From 42afa2a56c0b53e361ff7efce0b817f5a46681fc Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sun, 25 Oct 2026 01:57:54 -0400 Subject: [PATCH] Reset master to testing content --- .gitignore | 122 +- AGENTS.md | 155 +- AUTHORS | 5 + CONTRIBUTING.md | 222 + COPYING | 502 - HACKING | 46 - LIBREOFFICE_SUPPORT.md | 330 + LICENSE | 232 + PROGRESS_BARS.md | 44 + README-DEVELOPMENT.md | 122 - README-REMOTE-CONTROLLER.md | 345 - README.md | 697 +- RELEASE-HOWTO | 55 - REMOTE-CONTROLLER-COMMANDS.md | 133 - STEAM_FOCUS.md | 67 + TODO | 3 - assets/sounds/default/autocomplete.wav | Bin 0 -> 9644 bytes .../sounds}/default/browse_mode.wav | Bin {sounds => assets/sounds}/default/button.wav | Bin .../sounds}/default/checkbox_checked.wav | Bin .../sounds}/default/checkbox_mixed.wav | Bin .../sounds}/default/checkbox_unchecked.wav | Bin .../sounds}/default/combobox.wav | Bin .../sounds}/default/focus_mode.wav | Bin {sounds => assets/sounds}/default/link.wav | Bin .../sounds}/default/link_visited.wav | Bin .../sounds}/default/radiobutton_checked.wav | Bin .../sounds}/default/radiobutton_unchecked.wav | Bin {sounds => assets/sounds}/default/start.wav | Bin {sounds => assets/sounds}/default/stop.wav | Bin .../sounds}/default/switch_off.wav | Bin .../sounds}/default/switch_on.wav | Bin .../sounds}/default/togglebutton_checked.wav | Bin .../default/togglebutton_unchecked.wav | Bin assets/sounds/embed.go | 8 + build-local.sh | 109 - clean-local.sh | 97 - cmd/cthulhu-braille/main.go | 33 + cmd/cthulhu/greeter.go | 75 + cmd/cthulhu/greeter_test.go | 92 + cmd/cthulhu/main.go | 261 + cmd/cthulhu/main_test.go | 275 + cmd/cthulhu/replace.go | 152 + cmd/cthulhu/replace_test.go | 99 + cmd/parityledger/main.go | 65 + cmd/parityledger/main_test.go | 47 + cmd/tentacle-host/main.go | 85 + contrib/cthulhu-autostart.desktop | 59 - contrib/toggle.screenreader.gschema.xml | 20 - cthulhu.doap | 22 - .../Arch-Linux/cthulhu-git/.SRCINFO | 43 + .../Arch-Linux/cthulhu-git/PKGBUILD | 108 +- .../cthulhu-wine-access-git/PKGBUILD | 57 - .../Arch-Linux/cthulhu-wine-access/PKGBUILD | 40 - distro-packages/Arch-Linux/cthulhu/PKGBUILD | 93 - distro-packages/Slackware/cthulhu.SlackBuild | 90 - distro-packages/Slackware/doinst.sh | 11 - distro-packages/Slackware/slack-desc | 19 - distro-packages/Slint/README | 37 - distro-packages/Slint/cthulhu-info | 10 - distro-packages/Slint/cthulhu.SlackBuild | 90 - distro-packages/Slint/doinst.sh | 11 - distro-packages/Slint/slack-desc | 19 - docs/LOGGING.md | 46 - docs/atspi-document-selection-handoff.md | 51 - docs/man/cthulhu.1 | 336 - docs/man/meson.build | 1 - docs/meson.build | 1 - .../specs/2026-04-05-sounds-tab-design.md | 171 - .../2026-04-07-mouse-review-wayland-design.md | 117 - ...yland-compositor-event-interface-design.md | 355 - .../2026-04-10-tolk-nvda-presence-design.md | 198 - docs/testing/atspi-lifecycle.md | 61 + docs/testing/background-events.md | 77 + docs/testing/benchmarks.md | 103 + docs/testing/browser-audit-fixes.md | 140 + docs/testing/browser-editor.md | 49 + docs/testing/browser-lists.md | 87 + .../testing/browser-navigation-performance.md | 114 + docs/testing/browser-release-review.md | 140 + docs/testing/current-line.md | 44 + docs/testing/flat-review-robustness.md | 313 + docs/testing/flat-review-tables.md | 109 + docs/testing/flatpak-foreground.md | 80 + docs/testing/gui-list-tables.md | 44 + docs/testing/mozilla-reading.md | 86 + docs/testing/phonetic-review.md | 51 + docs/testing/qt-control-states.md | 109 + docs/testing/reading-settings.md | 51 + docs/testing/speech-preferences.md | 43 + docs/testing/speech-queue.md | 112 + docs/testing/terminal-scrollback.md | 38 + docs/testing/text-control-labels.md | 32 + docs/testing/thunderbird-workflows.md | 168 + docs/wine-accessibility.md | 53 - go.mod | 9 + go.sum | 6 + hooks/pre-push | 5 + icons/AUTHORS | 9 - icons/COPYING | 504 - icons/cthulhu-16x16.png | Bin 685 -> 0 bytes icons/cthulhu-22x22.png | Bin 1082 -> 0 bytes icons/cthulhu-24x24.png | Bin 1095 -> 0 bytes icons/cthulhu-256x256.png | Bin 30247 -> 0 bytes icons/cthulhu-32x32.png | Bin 2265 -> 0 bytes icons/cthulhu-48x48.png | Bin 3781 -> 0 bytes icons/cthulhu-scalable.svg | 1025 -- icons/cthulhu-splash.svg | 64 - icons/cthulhu-symbolic.svg | 27 - icons/meson.build | 53 - internal/app/app.go | 400 + internal/app/app_test.go | 117 + internal/app/application_behavior.go | 60 + internal/app/application_focus_test.go | 61 + internal/app/autocomplete.go | 94 + internal/app/braille_context.go | 76 + internal/app/braille_context_test.go | 99 + internal/app/braille_frames.go | 299 + internal/app/braille_helper_test.go | 104 + internal/app/braille_presentation.go | 438 + internal/app/braille_presentation_test.go | 425 + internal/app/braille_routing.go | 79 + internal/app/braille_session.go | 161 + internal/app/braille_text_attributes.go | 64 + internal/app/braille_text_attributes_test.go | 114 + internal/app/braille_worker.go | 125 + internal/app/braille_worker_test.go | 173 + internal/app/browser_activation_test.go | 43 + internal/app/browser_button_names.go | 69 + internal/app/browser_button_names_test.go | 180 + internal/app/browser_dynamic_test.go | 208 + internal/app/browser_editor_native_test.go | 148 + internal/app/browser_events_test.go | 1049 ++ internal/app/browser_lists.go | 98 + internal/app/browser_lists_native_test.go | 135 + internal/app/browser_lists_test.go | 97 + internal/app/browser_menu_native_test.go | 200 + internal/app/browser_mode.go | 467 + internal/app/browser_mode_test.go | 755 ++ .../browser_nested_document_native_test.go | 130 + .../app/browser_replacement_native_test.go | 188 + internal/app/browser_reveal_native_test.go | 155 + internal/app/browser_tabs_native_test.go | 125 + internal/app/browser_tooltip_native_test.go | 117 + internal/app/capitalization.go | 52 + internal/app/capitalization_test.go | 37 + internal/app/character_attributes.go | 261 + internal/app/character_attributes_test.go | 81 + internal/app/character_color_names.go | 147 + internal/app/clipboard.go | 64 + internal/app/clipboard_copy.go | 45 + internal/app/clipboard_copy_test.go | 110 + internal/app/clipboard_test.go | 52 + internal/app/clipboard_watch.go | 179 + internal/app/clipboard_watch_test.go | 99 + internal/app/combo_presentation.go | 39 + internal/app/combo_presentation_test.go | 60 + internal/app/command_input_test.go | 109 + internal/app/configured_speaker.go | 301 + .../app/configured_speaker_native_test.go | 90 + internal/app/control_events_test.go | 327 + internal/app/current_line.go | 51 + internal/app/current_line_test.go | 100 + internal/app/date_time.go | 25 + internal/app/date_time_test.go | 155 + internal/app/document_diagnostics_test.go | 54 + internal/app/document_line_test.go | 313 + internal/app/document_native_test.go | 1050 ++ internal/app/document_review.go | 464 + internal/app/document_review_test.go | 422 + internal/app/echo_preferences_test.go | 258 + internal/app/echo_speaker.go | 250 + internal/app/echo_speaker_test.go | 601 + internal/app/editable_document_test.go | 137 + internal/app/event_accessibility.go | 312 + internal/app/event_autocomplete.go | 93 + internal/app/event_browser_tabs.go | 74 + internal/app/event_caret.go | 98 + internal/app/event_caret_test.go | 226 + internal/app/event_filters.go | 79 + internal/app/event_focus.go | 169 + internal/app/event_focus_ownership.go | 129 + internal/app/event_focus_test.go | 414 + internal/app/event_gui_table_test.go | 420 + internal/app/event_lifecycle.go | 161 + internal/app/event_loop.go | 354 + internal/app/event_navigation_filters.go | 90 + internal/app/event_notification.go | 126 + internal/app/event_presentation.go | 262 + internal/app/event_presentation_test.go | 181 + internal/app/event_review_results.go | 284 + internal/app/event_state.go | 201 + internal/app/event_text_selection.go | 80 + internal/app/event_tooltip.go | 29 + internal/app/event_tooltip_test.go | 89 + internal/app/flat_review.go | 119 + internal/app/flat_review_test.go | 269 + internal/app/focus_gate.go | 157 + internal/app/foreground_test.go | 203 + internal/app/gui_table_presentation.go | 100 + internal/app/gui_table_test.go | 103 + internal/app/i38lock_feedback_native_test.go | 192 + internal/app/indentation.go | 89 + internal/app/input_events.go | 128 + internal/app/input_events_test.go | 168 + internal/app/internal_ui.go | 419 + internal/app/internal_ui_native_test.go | 218 + internal/app/internal_ui_output_test.go | 44 + internal/app/internal_ui_test.go | 131 + internal/app/interruption_test.go | 89 + internal/app/key_bindings_test.go | 132 + internal/app/learn_mode.go | 264 + internal/app/learn_mode_test.go | 81 + internal/app/libreoffice.go | 104 + internal/app/libreoffice_headers.go | 90 + internal/app/libreoffice_headers_test.go | 119 + internal/app/libreoffice_native_test.go | 395 + internal/app/libreoffice_selection.go | 117 + internal/app/libreoffice_selection_test.go | 156 + internal/app/libreoffice_test.go | 202 + internal/app/linked_headings_native_test.go | 244 + internal/app/live_region_test.go | 83 + internal/app/live_settings.go | 37 + internal/app/mouse_review.go | 176 + internal/app/mouse_review_test.go | 47 + internal/app/named_links_native_test.go | 168 + internal/app/notification_list_test.go | 141 + internal/app/notification_test.go | 138 + internal/app/notifications.go | 276 + internal/app/object_review_events_test.go | 224 + internal/app/ocr_activate.go | 242 + internal/app/ocr_commands.go | 227 + internal/app/ocr_copy.go | 86 + internal/app/ocr_copy_test.go | 28 + internal/app/ocr_native_test.go | 276 + internal/app/ocr_read_all.go | 48 + internal/app/ocr_reading_test.go | 162 + internal/app/ocr_refresh.go | 89 + internal/app/ocr_refresh_activation_test.go | 193 + internal/app/ocr_selection.go | 55 + internal/app/ocr_session.go | 690 ++ internal/app/ocr_session_test.go | 721 ++ internal/app/output_queue.go | 71 + internal/app/output_queue_test.go | 54 + internal/app/pause_chunks_test.go | 218 + internal/app/pending_presentation.go | 61 + internal/app/phonetic_hints.go | 67 + internal/app/phonetic_hints_test.go | 132 + internal/app/preferences.go | 186 + internal/app/preferences_application.go | 87 + internal/app/preferences_application_test.go | 87 + internal/app/preferences_apply.go | 263 + internal/app/preferences_echo_preview_test.go | 276 + internal/app/preferences_feedback_test.go | 194 + internal/app/preferences_preview.go | 158 + internal/app/preferences_preview_events.go | 47 + internal/app/preferences_session.go | 275 + internal/app/preferences_session_test.go | 161 + internal/app/preferences_tentacles.go | 73 + internal/app/preferences_test.go | 363 + internal/app/progress_bars.go | 123 + internal/app/progress_bars_test.go | 249 + internal/app/progress_browser_native_test.go | 79 + internal/app/progress_native_test.go | 128 + internal/app/progress_settings.go | 35 + internal/app/prompt_presentation.go | 56 + internal/app/prompt_presentation_test.go | 450 + internal/app/qt_controls_native_test.go | 220 + internal/app/radio_sound.go | 85 + internal/app/radio_sound_test.go | 146 + internal/app/read_all.go | 96 + internal/app/read_all_test.go | 193 + internal/app/reading_context.go | 131 + internal/app/reading_context_test.go | 96 + internal/app/reading_preferences_test.go | 307 + internal/app/reading_speech.go | 99 + internal/app/reading_speech_test.go | 95 + internal/app/remote.go | 166 + internal/app/remote_control.go | 353 + internal/app/remote_control_test.go | 94 + internal/app/remote_test.go | 140 + internal/app/review_spelling.go | 60 + internal/app/review_spelling_test.go | 100 + internal/app/runtime_backends.go | 134 + internal/app/runtime_commands.go | 291 + internal/app/runtime_commands_test.go | 349 + internal/app/runtime_notifications.go | 57 + internal/app/runtime_platform.go | 67 + internal/app/runtime_platform_test.go | 104 + internal/app/runtime_remote.go | 138 + internal/app/runtime_review.go | 67 + internal/app/runtime_settings.go | 118 + internal/app/runtime_settings_test.go | 117 + internal/app/runtime_shutdown.go | 106 + internal/app/runtime_test.go | 261 + internal/app/runtime_workers.go | 96 + internal/app/screen_lock.go | 209 + internal/app/screen_lock_test.go | 204 + internal/app/selection_native_test.go | 110 + internal/app/speech_delivery.go | 261 + internal/app/speech_enable_test.go | 62 + internal/app/speech_history.go | 105 + internal/app/speech_history_test.go | 230 + internal/app/speech_history_window.go | 261 + internal/app/speech_interrupt.go | 207 + internal/app/speech_key_echo_test.go | 84 + internal/app/speech_mode.go | 89 + internal/app/speech_mode_test.go | 182 + internal/app/speech_settings.go | 247 + internal/app/speech_settings_test.go | 209 + internal/app/speech_title_input.go | 23 + internal/app/speech_title_input_test.go | 79 + internal/app/speech_uninterruptible.go | 55 + internal/app/speech_worker.go | 419 + internal/app/speech_worker_test.go | 410 + internal/app/startup_sound_test.go | 104 + internal/app/steam_activation_test.go | 274 + internal/app/table_native_test.go | 166 + internal/app/tentacle_clipboard.go | 137 + internal/app/tentacle_clipboard_test.go | 93 + internal/app/tentacle_install_test.go | 280 + internal/app/tentacle_interaction.go | 253 + internal/app/tentacle_interaction_test.go | 204 + internal/app/tentacle_management.go | 673 + internal/app/tentacle_management_test.go | 406 + internal/app/tentacle_output.go | 141 + internal/app/tentacle_output_test.go | 197 + internal/app/tentacle_reader.go | 643 + internal/app/tentacle_reader_test.go | 665 + internal/app/tentacle_repositories.go | 52 + internal/app/tentacle_repositories_test.go | 109 + internal/app/tentacle_settings_test.go | 84 + internal/app/tentacle_uninterruptible_test.go | 222 + internal/app/tentacles.go | 436 + internal/app/tentacles_test.go | 473 + internal/app/terminal_events.go | 19 + internal/app/terminal_events_test.go | 320 + internal/app/test_helpers_test.go | 247 + internal/app/text_selection.go | 91 + internal/app/text_selection_test.go | 213 + internal/app/version.go | 18 + internal/app/version_test.go | 31 + internal/app/wayland_native_test.go | 101 + internal/app/webscripts.go | 97 + internal/app/webscripts_test.go | 114 + internal/app/window_owner.go | 154 + internal/app/window_owner_test.go | 106 + internal/app/window_speech_test.go | 97 + internal/app/window_title_command_test.go | 164 + internal/app/window_titles.go | 337 + internal/app/window_titles_native_test.go | 157 + internal/app/window_titles_test.go | 660 + internal/app/wine_echo_focus.go | 34 + internal/app/wine_echo_focus_test.go | 98 + internal/app/wine_events.go | 259 + internal/app/wine_events_native_test.go | 132 + internal/app/wine_events_test.go | 287 + internal/app/wine_review_capture.go | 59 + internal/app/wine_review_capture_test.go | 85 + internal/app/wine_review_focus.go | 125 + internal/app/wine_review_focus_test.go | 213 + internal/app/wine_review_native_test.go | 369 + .../app/wine_typing_echo_settings_test.go | 117 + internal/app/wine_window_titles.go | 62 + .../app/wine_window_titles_native_test.go | 213 + internal/app/xterm_handoff_test.go | 262 + internal/atspi/adapter.go | 443 + internal/atspi/adapter_actions_native.go | 161 + internal/atspi/adapter_capture.c | 980 ++ internal/atspi/adapter_document_native.go | 662 + .../atspi/adapter_event_callback_native.go | 608 + internal/atspi/adapter_event_filter_native.go | 71 + internal/atspi/adapter_events.c | 782 ++ internal/atspi/adapter_foreground_native.go | 338 + internal/atspi/adapter_lifecycle_native.go | 252 + internal/atspi/adapter_menu_states.c | 48 + internal/atspi/adapter_native.h | 150 + internal/atspi/adapter_native_test.go | 854 ++ internal/atspi/adapter_ocr_native.go | 147 + internal/atspi/adapter_position.c | 127 + internal/atspi/adapter_references_native.go | 416 + internal/atspi/adapter_secure_native.go | 100 + internal/atspi/adapter_snapshot_native.go | 190 + internal/atspi/adapter_text_boundary.c | 57 + internal/atspi/adapter_tree_native.go | 670 + internal/atspi/adapter_tree_test.go | 515 + internal/atspi/adapter_window_title.go | 36 + internal/atspi/alert_native_test.go | 313 + .../atspi/background_events_native_test.go | 208 + internal/atspi/braille_native.go | 142 + internal/atspi/braille_test.go | 119 + internal/atspi/browser_live_native_test.go | 118 + internal/atspi/browser_native_test.go | 483 + internal/atspi/capture_diagnostics.go | 153 + internal/atspi/capture_diagnostics_test.go | 90 + internal/atspi/catalog_native_test.go | 99 + internal/atspi/character_attributes_native.go | 102 + internal/atspi/current_line_native.go | 86 + internal/atspi/current_line_native_test.go | 99 + internal/atspi/document.go | 195 + internal/atspi/document_caret.go | 43 + internal/atspi/document_caret_echo.go | 59 + internal/atspi/document_caret_echo_test.go | 26 + internal/atspi/document_caret_test.go | 15 + internal/atspi/document_error.go | 61 + internal/atspi/document_error_test.go | 120 + internal/atspi/document_hypertext_native.go | 76 + internal/atspi/document_line.go | 131 + internal/atspi/document_lines_native.go | 118 + internal/atspi/document_lines_native_test.go | 94 + internal/atspi/document_rows.go | 94 + internal/atspi/document_rows_test.go | 54 + internal/atspi/document_sound.go | 40 + internal/atspi/document_sound_test.go | 77 + internal/atspi/document_test.go | 369 + internal/atspi/document_text_lines.go | 47 + internal/atspi/document_text_lines_test.go | 46 + internal/atspi/document_view.go | 172 + internal/atspi/document_view_test.go | 163 + internal/atspi/echo_focus.go | 69 + internal/atspi/echo_focus_native_test.go | 72 + internal/atspi/echo_focus_test.go | 106 + internal/atspi/edit_labels_native_test.go | 91 + internal/atspi/firefox_native_test.go | 202 + internal/atspi/flatpak_process.go | 100 + internal/atspi/flatpak_process_test.go | 54 + internal/atspi/foreground.go | 64 + internal/atspi/foreground_native_test.go | 60 + internal/atspi/foreground_test.go | 100 + internal/atspi/geometry.go | 69 + internal/atspi/geometry_test.go | 136 + internal/atspi/libreoffice.go | 65 + internal/atspi/libreoffice_headers.go | 109 + internal/atspi/libreoffice_headers_native.go | 103 + internal/atspi/libreoffice_headers_test.go | 161 + internal/atspi/libreoffice_native.go | 211 + .../atspi/libreoffice_selection_native.go | 135 + internal/atspi/libreoffice_test.go | 23 + internal/atspi/lifecycle_native_test.go | 216 + internal/atspi/live_regions.go | 46 + internal/atspi/live_regions_native.go | 66 + internal/atspi/live_regions_test.go | 39 + internal/atspi/model.go | 463 + internal/atspi/model_test.go | 243 + internal/atspi/mouse_review_native.go | 238 + internal/atspi/mouse_review_native_test.go | 81 + internal/atspi/ocr_geometry.go | 97 + internal/atspi/ocr_geometry_test.go | 48 + internal/atspi/ocr_native_test.go | 141 + internal/atspi/pointer_native_test.go | 42 + internal/atspi/position_native_test.go | 65 + internal/atspi/preferences_native_test.go | 245 + internal/atspi/read_all_native.go | 130 + internal/atspi/replaced_feed_native_test.go | 137 + internal/atspi/review.go | 95 + internal/atspi/review_cache_native_test.go | 253 + internal/atspi/review_table_native.go | 237 + internal/atspi/review_table_native_test.go | 217 + internal/atspi/review_test.go | 99 + internal/atspi/session_native_test.go | 47 + internal/atspi/speech_metadata_native.go | 151 + internal/atspi/speech_metadata_native_test.go | 125 + internal/atspi/tentacle_item_native.go | 82 + internal/atspi/testdata/text_boundary.c | 98 + internal/atspi/text.go | 552 + internal/atspi/text_attributes.go | 18 + internal/atspi/text_boundary_test.go | 29 + internal/atspi/text_bounds_test.go | 119 + internal/atspi/text_component_test.go | 54 + internal/atspi/text_native.go | 326 + internal/atspi/text_test.go | 473 + internal/atspi/text_viewport.go | 282 + internal/atspi/text_viewport_test.go | 228 + internal/atspi/tree.go | 586 + internal/atspi/tree_test.go | 408 + internal/atspi/version.go | 32 + internal/atspi/version_test.go | 36 + internal/atspi/webscripts_native.go | 218 + internal/atspi/webscripts_native_test.go | 145 + internal/atspi/window_title_native_test.go | 100 + internal/braille/braille.go | 276 + internal/braille/braille_test.go | 222 + internal/braille/client.go | 120 + internal/braille/client_test.go | 111 + internal/braille/native.go | 225 + internal/braille/native_test.go | 20 + internal/braille/regions.go | 42 + internal/braille/regions_test.go | 35 + internal/braille/tables.go | 56 + internal/braille/tables_test.go | 23 + internal/braille/translate_native.go | 117 + internal/braille/translate_native_test.go | 73 + internal/braille/translate_unavailable.go | 9 + internal/braille/unavailable.go | 12 + internal/braille/unavailable_test.go | 21 + internal/clipboard/clipboard.go | 109 + internal/clipboard/clipboard_test.go | 56 + internal/clipboard/native.go | 68 + internal/clipboard/watch.c | 70 + internal/clipboard/watch.go | 100 + internal/clipboard/watch.h | 17 + internal/config/application_store_test.go | 53 + internal/config/bindings_test.go | 42 + internal/config/capitalization.go | 13 + internal/config/capitalization_test.go | 104 + internal/config/clipboard_test.go | 16 + internal/config/codec.go | 145 + internal/config/config.go | 109 + internal/config/config_test.go | 284 + internal/config/defaults.go | 93 + internal/config/greeter.go | 86 + internal/config/greeter_test.go | 110 + internal/config/hardware_test.go | 61 + internal/config/interruption_test.go | 46 + internal/config/legacy.go | 140 + internal/config/legacy_mapping.go | 335 + internal/config/ocr_test.go | 48 + internal/config/patch_contract_test.go | 69 + internal/config/phonetic_hints_test.go | 45 + internal/config/profile_mapping.go | 605 + internal/config/progress_test.go | 90 + internal/config/schema.go | 202 + internal/config/settings.go | 218 + internal/config/settings_copy.go | 57 + internal/config/store.go | 285 + internal/config/store_test.go | 387 + internal/config/testdata/settings-v1.toml | 34 + internal/config/testdata/settings-v2.toml | 17 + internal/config/testdata/settings-v3.toml | 4 + internal/config/text_preferences_test.go | 37 + internal/config/validation.go | 262 + internal/config/voices.go | 32 + internal/config/voices_test.go | 86 + internal/config/window_titles_test.go | 58 + internal/datetime/datetime.go | 154 + internal/input/bindings.go | 316 + internal/input/bindings_test.go | 122 + internal/input/clipboard_test.go | 43 + internal/input/commands.go | 479 + internal/input/commands_test.go | 344 + internal/input/current_line_test.go | 35 + internal/input/date_time_test.go | 47 + internal/input/document_lists.go | 88 + internal/input/document_lists_test.go | 46 + internal/input/document_test.go | 50 + internal/input/flat_review_test.go | 191 + internal/input/input.go | 127 + internal/input/input_test.go | 89 + internal/input/intent.go | 154 + internal/input/intent_test.go | 148 + internal/input/interruption.go | 72 + internal/input/interruption_test.go | 47 + internal/input/notification_commands_test.go | 30 + internal/input/ocr.go | 75 + internal/input/ocr_test.go | 84 + internal/input/read_all_test.go | 29 + internal/input/repeat.go | 31 + internal/input/repeat_test.go | 39 + internal/input/review_presses.go | 57 + internal/input/speech_history_test.go | 20 + internal/input/speech_mode_test.go | 36 + internal/input/sticky_test.go | 55 + internal/input/tentacle_bindings.go | 46 + internal/input/tentacle_bindings_test.go | 62 + internal/input/version_test.go | 17 + internal/input/window_title_test.go | 42 + internal/interaction/session.go | 488 + internal/interaction/session_test.go | 191 + internal/lifecycle/lifecycle.go | 154 + internal/lifecycle/lifecycle_test.go | 176 + internal/logging/async.go | 405 + internal/logging/async_test.go | 388 + internal/logging/logging.go | 231 + internal/logging/logging_test.go | 158 + internal/notification/mako.go | 395 + internal/notification/mako_test.go | 228 + internal/notification/presenter.go | 442 + internal/notification/presenter_test.go | 123 + internal/notificationui/native.c | 263 + internal/notificationui/native.h | 21 + internal/notificationui/protocol.go | 35 + internal/notificationui/ui.go | 200 + internal/nvda2cthulhu/messagepack.go | 210 + internal/nvda2cthulhu/messagepack_test.go | 44 + internal/nvda2cthulhu/protocol.go | 154 + internal/nvda2cthulhu/protocol_test.go | 40 + internal/nvda2cthulhu/server.go | 196 + internal/nvda2cthulhu/server_test.go | 171 + internal/ocr/capture.go | 247 + internal/ocr/capture_native_test.go | 231 + internal/ocr/capture_test.go | 232 + internal/ocr/cursor.go | 169 + internal/ocr/cursor_continuous_test.go | 23 + internal/ocr/cursor_test.go | 59 + internal/ocr/engine.go | 252 + internal/ocr/engine_test.go | 431 + internal/ocr/model.go | 157 + internal/ocr/model_test.go | 90 + internal/ocr/native_test.go | 74 + internal/ocr/page_test.go | 30 + internal/ocr/preprocess.go | 57 + internal/ocr/preprocess_test.go | 47 + internal/ocr/process.go | 107 + internal/ocr/testdata/painted-text.png | Bin 0 -> 11544 bytes internal/ocr/tsv.go | 138 + internal/ocr/tsv_test.go | 135 + internal/ocrcapture/capture.go | 89 + internal/ocrcapture/native.c | 154 + internal/ocrcapture/native.h | 20 + internal/ocrconfirm/confirm.c | 24 + internal/ocrconfirm/confirm.go | 35 + internal/parity/parity.go | 177 + internal/parity/parity_test.go | 88 + internal/platform/session/session.go | 31 + internal/platform/session/session_test.go | 44 + internal/platform/wayland/keyboard.go | 243 + internal/platform/wayland/protocol.go | 299 + internal/platform/wayland/protocol_test.go | 408 + internal/platform/wayland/routing.go | 195 + internal/platform/wayland/routing_test.go | 214 + internal/platform/xorg/applications.go | 33 + internal/platform/xorg/clipboard.go | 124 + .../platform/xorg/clipboard_native_test.go | 41 + internal/platform/xorg/commands.go | 114 + internal/platform/xorg/commands_bindings.go | 220 + internal/platform/xorg/commands_chord.go | 178 + internal/platform/xorg/commands_foreground.go | 70 + internal/platform/xorg/commands_native.c | 651 + internal/platform/xorg/commands_native.h | 63 + internal/platform/xorg/commands_ocr.go | 117 + internal/platform/xorg/commands_owner.go | 113 + internal/platform/xorg/commands_owner_loop.go | 282 + internal/platform/xorg/commands_security.go | 54 + internal/platform/xorg/commands_ui.go | 175 + internal/platform/xorg/foreground_pid.c | 40 + .../xorg/grab_foreground_native_test.go | 82 + internal/platform/xorg/listener.go | 399 + .../platform/xorg/listener_native_test.go | 1141 ++ internal/platform/xorg/locks_native_test.go | 128 + internal/platform/xorg/ocr_click.c | 50 + internal/platform/xorg/ocr_click.go | 36 + .../platform/xorg/ocr_click_native_test.go | 83 + internal/platform/xorg/ocr_native_test.go | 348 + internal/platform/xorg/pointer.go | 44 + .../platform/xorg/scroll_lock_native_test.go | 178 + internal/platform/xorg/steam_focus.c | 106 + internal/platform/xorg/steam_focus.go | 87 + .../platform/xorg/steam_focus_native_test.go | 179 + internal/platform/xorg/steam_focus_test.go | 70 + .../platform/xorg/tentacle_native_test.go | 197 + internal/platform/xorg/ui_native_test.go | 206 + internal/platform/xorg/window_title.c | 273 + internal/platform/xorg/window_title.go | 42 + internal/platform/xorg/window_title.h | 21 + .../platform/xorg/window_title_native_test.go | 142 + .../xorg/xterm_handoff_native_test.go | 191 + internal/preferences/applications.go | 135 + internal/preferences/applications_test.go | 23 + internal/preferences/bindings.go | 147 + internal/preferences/braille.go | 111 + internal/preferences/catalog_protocol.go | 124 + internal/preferences/catalog_protocol_test.go | 113 + internal/preferences/catalog_voices.go | 32 + internal/preferences/echo.go | 171 + internal/preferences/extensions.go | 117 + internal/preferences/general.go | 79 + internal/preferences/interruption_test.go | 27 + internal/preferences/native.c | 317 + internal/preferences/native.h | 83 + internal/preferences/native_applications.c | 136 + internal/preferences/native_applications.h | 14 + internal/preferences/native_bindings.c | 155 + internal/preferences/native_extensions.c | 138 + internal/preferences/native_internal.h | 20 + internal/preferences/native_interruption.c | 188 + internal/preferences/native_reading.c | 204 + internal/preferences/native_tentacles.c | 163 + internal/preferences/native_text_attributes.c | 200 + internal/preferences/native_widgets.c | 69 + internal/preferences/ocr.go | 53 + internal/preferences/preferences.ui | 331 + internal/preferences/protocol.go | 138 + internal/preferences/protocol_test.go | 160 + internal/preferences/reading.go | 75 + internal/preferences/session.go | 39 + internal/preferences/sound.go | 78 + internal/preferences/speech.go | 436 + internal/preferences/tentacles.go | 285 + internal/preferences/tentacles_test.go | 40 + internal/preferences/text_attributes.go | 97 + internal/preferences/ui.go | 237 + internal/preferences/ui_values.go | 47 + internal/preferences/values.go | 143 + internal/preferences/widgets.go | 100 + internal/presentation/control_values.go | 203 + internal/presentation/control_values_test.go | 211 + internal/presentation/document_line.go | 127 + internal/presentation/document_line_test.go | 88 + internal/presentation/flat_review.go | 42 + internal/presentation/flat_review_test.go | 37 + internal/presentation/libreoffice.go | 78 + .../presentation/libreoffice_selection.go | 102 + .../libreoffice_selection_test.go | 45 + internal/presentation/libreoffice_test.go | 92 + internal/presentation/position_sound_test.go | 80 + internal/presentation/presentation.go | 318 + internal/presentation/presentation_test.go | 294 + internal/presentation/reading.go | 191 + internal/presentation/reading_test.go | 125 + internal/presentation/sound_cues.go | 209 + internal/presentation/sound_cues_test.go | 280 + internal/presentation/speech.go | 65 + .../presentation/text_label_native_test.go | 98 + internal/presentation/typing_echo.go | 152 + internal/presentation/typing_echo_test.go | 166 + internal/remote/endpoint.go | 273 + internal/remote/endpoint_test.go | 207 + internal/remote/introspection.go | 59 + internal/remote/modules.go | 386 + internal/remote/modules_test.go | 239 + internal/remote/registrations.go | 85 + internal/remote/service.go | 322 + internal/remote/service_test.go | 324 + internal/remote/wine_review.go | 37 + internal/remote/wine_review_test.go | 121 + internal/review/current_line.go | 80 + internal/review/current_line_test.go | 109 + internal/review/cursor.go | 198 + internal/review/cursor_test.go | 193 + internal/review/document.go | 641 + internal/review/document_activation_test.go | 151 + internal/review/document_benchmark_test.go | 224 + internal/review/document_braille.go | 75 + internal/review/document_braille_routing.go | 134 + .../review/document_braille_routing_test.go | 91 + internal/review/document_braille_test.go | 81 + internal/review/document_caret.go | 170 + .../review/document_caret_editable_test.go | 109 + internal/review/document_caret_glyph_test.go | 137 + internal/review/document_caret_line.go | 177 + internal/review/document_caret_nodes.go | 121 + internal/review/document_caret_ranges.go | 186 + internal/review/document_caret_test.go | 562 + internal/review/document_caret_text.go | 139 + internal/review/document_diagnostics.go | 66 + internal/review/document_hypertext_test.go | 280 + .../document_inline_replacement_test.go | 269 + internal/review/document_line_worker.go | 86 + internal/review/document_lists.go | 251 + internal/review/document_lists_test.go | 143 + internal/review/document_mode.go | 185 + internal/review/document_mode_test.go | 219 + internal/review/document_named_link.go | 60 + internal/review/document_native_caret.go | 137 + internal/review/document_native_caret_test.go | 115 + internal/review/document_navigation_reader.go | 64 + internal/review/document_navigation_test.go | 83 + internal/review/document_replacement.go | 134 + internal/review/document_replacement_test.go | 155 + internal/review/document_requests.go | 69 + internal/review/document_sound_test.go | 103 + internal/review/document_table.go | 243 + internal/review/document_table_test.go | 179 + internal/review/document_test.go | 514 + internal/review/document_tooltip_test.go | 101 + internal/review/document_visual_line.go | 284 + .../document_visual_line_native_test.go | 214 + internal/review/document_visual_line_test.go | 260 + internal/review/document_word_spaces_test.go | 78 + internal/review/document_worker.go | 608 + internal/review/document_worker_test.go | 1086 ++ internal/review/flat.go | 410 + internal/review/flat_browser_native_test.go | 147 + internal/review/flat_layout.go | 337 + internal/review/flat_native_test.go | 312 + internal/review/flat_pluma_native_test.go | 81 + internal/review/flat_robustness_test.go | 170 + internal/review/flat_test.go | 546 + internal/review/flat_worker.go | 139 + internal/review/flat_worker_test.go | 265 + internal/review/interest.go | 111 + internal/review/interest_test.go | 132 + internal/review/object_worker.go | 112 + internal/review/read_all.go | 227 + internal/review/read_all_test.go | 218 + internal/review/worker.go | 401 + internal/review/worker_contract.go | 144 + internal/review/worker_test.go | 405 + internal/sessionbus/sessionbus.go | 61 + internal/sessionbus/sessionbus_test.go | 107 + internal/shortcutui/native.c | 51 + internal/shortcutui/ui.go | 55 + internal/shortcutui/ui_native_test.go | 39 + internal/sound/indentation.go | 25 + internal/sound/indentation_test.go | 36 + internal/sound/player.go | 110 + internal/sound/position.go | 33 + internal/sound/position_test.go | 98 + internal/sound/progress.go | 69 + internal/sound/progress_test.go | 185 + internal/sound/service.go | 436 + internal/sound/service_test.go | 628 + internal/sound/speech_beep.go | 35 + internal/sound/speech_beep_test.go | 51 + internal/sound/tone.go | 45 + internal/sound/tone_test.go | 19 + internal/speech/address.go | 84 + internal/speech/address_test.go | 100 + internal/speech/autospawn.go | 95 + internal/speech/autospawn_test.go | 183 + internal/speech/catalog.go | 84 + internal/speech/catalog_test.go | 43 + internal/speech/defaults.go | 57 + internal/speech/defaults_test.go | 66 + internal/speech/hardware.go | 163 + internal/speech/hardware_test.go | 29 + internal/speech/locale_voices.go | 49 + internal/speech/read_all.go | 79 + internal/speech/read_all_test.go | 84 + internal/speech/serial_native.go | 65 + internal/speech/serial_native_test.go | 120 + internal/speech/serial_unavailable.go | 14 + internal/speech/settings_test.go | 258 + internal/speech/speech.go | 471 + internal/speech/speech_test.go | 471 + internal/speechhistoryui/native.c | 221 + internal/speechhistoryui/native.h | 14 + internal/speechhistoryui/ui.go | 151 + internal/tentacle/bindings.go | 88 + internal/tentacle/containment.go | 198 + internal/tentacle/containment_test.go | 386 + internal/tentacle/install.go | 431 + internal/tentacle/install_test.go | 442 + internal/tentacle/load_test.go | 114 + internal/tentacle/local.go | 68 + internal/tentacle/local_test.go | 45 + internal/tentacle/management.go | 27 + internal/tentacle/manager.go | 209 + internal/tentacle/page_store.go | 105 + internal/tentacle/page_store_test.go | 73 + internal/tentacle/process.go | 344 + internal/tentacle/protocol.go | 203 + internal/tentacle/protocol_test.go | 95 + internal/tentacle/reader_test.go | 111 + internal/tentacle/registry.go | 246 + internal/tentacle/registry_test.go | 105 + internal/tentacle/repository.go | 285 + internal/tentacle/repository_test.go | 177 + internal/tentacle/sdk_test.go | 252 + internal/tentacle/session.go | 314 + internal/tentacle/session_test.go | 599 + internal/tentacle/supervisor.go | 203 + internal/tentacle/supervisor_test.go | 226 + internal/tentacle/testdata/peer.py | 26 + internal/tentacle/testdata/resource_peer.py | 63 + internal/tentacle/testdata/sdk_peer.py | 41 + internal/tentacle/testdata/sdk_reader_peer.py | 20 + internal/tentaclewire/interaction.go | 114 + internal/tentaclewire/interaction_test.go | 57 + internal/tentaclewire/presentation.go | 73 + internal/tentaclewire/presentation_test.go | 37 + internal/tentaclewire/reader.go | 247 + internal/tentaclewire/reader_test.go | 134 + internal/tentaclewire/wire.go | 106 + internal/version/build.go | 43 + internal/version/build_test.go | 28 + internal/version/version.go | 43 + internal/version/version_test.go | 63 + internal/webscripts/registry.go | 72 + internal/webscripts/steam.go | 200 + internal/webscripts/steam_test.go | 147 + internal/wine/diagnostics.go | 160 + internal/wine/diagnostics_test.go | 167 + internal/wine/manager.go | 355 + internal/wine/manager_test.go | 354 + internal/wine/review_client.go | 91 + internal/wine/review_protocol.go | 82 + internal/wine/review_registry.go | 228 + internal/wine/review_registry_test.go | 174 + internal/wine/review_snapshot.go | 331 + internal/wine/review_snapshot_test.go | 352 + internal/wine/version.go | 40 + internal/wine/version_test.go | 65 + meson.build | 156 - meson_options.txt | 9 - po/.gitignore | 25 - po/ChangeLog | 2405 ---- po/LINGUAS | 84 - po/Makevars | 78 - po/POTFILES.in | 18 - po/POTFILES.skip | 3 - po/ab.po | 9207 -------------- po/an.po | 9770 --------------- po/ar.po | 10096 ---------------- po/ast.po | 9885 --------------- po/be.po | 9671 --------------- po/bg.po | 9234 -------------- po/bn.po | 9859 --------------- po/bn_IN.po | 9379 -------------- po/bs.po | 9527 --------------- po/ca.po | 9245 -------------- po/ca@valencia.po | 9254 -------------- po/ckb.po | 9292 -------------- po/cs.po | 9277 -------------- po/cy.po | 9736 --------------- po/da.po | 9275 -------------- po/de.po | 9292 -------------- po/dz.po | 9824 --------------- po/el.po | 9374 -------------- po/en_CA.po | 9578 --------------- po/en_GB.po | 9203 -------------- po/eo.po | 9922 --------------- po/es.po | 9254 -------------- po/et.po | 9658 --------------- po/eu.po | 9216 -------------- po/fa.po | 9139 -------------- po/fi.po | 9489 --------------- po/fr.po | 9264 -------------- po/fur.po | 9194 -------------- po/ga.po | 9279 -------------- po/gl.po | 9239 -------------- po/gu.po | 9892 --------------- po/he.po | 9324 -------------- po/hi.po | 9834 --------------- po/hr.po | 9279 -------------- po/hu.po | 9348 -------------- po/id.po | 9165 -------------- po/is.po | 9555 --------------- po/it.po | 9392 -------------- po/ja.po | 9827 --------------- po/ka.po | 9172 -------------- po/kab.po | 9179 -------------- po/kk.po | 9131 -------------- po/kn.po | 9905 --------------- po/ko.po | 9893 --------------- po/lt.po | 9260 -------------- po/lv.po | 9260 -------------- po/mai.po | 9576 --------------- po/meson.build | 6 - po/mk.po | 9888 --------------- po/ml.po | 9796 --------------- po/mr.po | 9586 --------------- po/ms.po | 9160 -------------- po/nb.po | 9256 -------------- po/ne.po | 9312 -------------- po/nl.po | 9355 -------------- po/nn.po | 9932 --------------- po/oc.po | 9312 -------------- po/or.po | 9814 --------------- po/pa.po | 9748 --------------- po/pl.po | 9306 -------------- po/pt.po | 9251 -------------- po/pt_BR.po | 9319 -------------- po/ro.po | 9283 -------------- po/ru.po | 9278 -------------- po/rw.po | 9995 --------------- po/si.po | 9326 -------------- po/sk.po | 9479 --------------- po/sl.po | 9312 -------------- po/sq.po | 10007 --------------- po/sr.po | 9312 -------------- po/sr@latin.po | 9325 -------------- po/sv.po | 9245 -------------- po/ta.po | 9841 --------------- po/te.po | 9849 --------------- po/tg.po | 9591 --------------- po/th.po | 9836 --------------- po/tr.po | 9181 -------------- po/ug.po | 9801 --------------- po/uk.po | 9329 -------------- po/vi.po | 9805 --------------- po/zh_CN.po | 9161 -------------- po/zh_HK.po | 9695 --------------- po/zh_TW.po | 9526 --------------- pyproject.toml | 35 - scripts/build-wine-access.sh | 17 - sdk/go/tentacle/tentacle.go | 277 + sdk/python/cthulhu_tentacle/__init__.py | 234 + set-version.sh | 133 - sounds/meson.build | 28 - src/cthulhu.py | 422 - src/cthulhu/.gitignore | 9 - src/cthulhu/__init__.py | 29 - src/cthulhu/acss.py | 137 - src/cthulhu/action_presenter.py | 384 - src/cthulhu/ax_collection.py | 167 - src/cthulhu/ax_component.py | 416 - src/cthulhu/ax_document.py | 280 - src/cthulhu/ax_document_selection.py | 571 - src/cthulhu/ax_event_synthesizer.py | 362 - src/cthulhu/ax_hypertext.py | 304 - src/cthulhu/ax_object.py | 1581 --- src/cthulhu/ax_selection.py | 128 - src/cthulhu/ax_table.py | 1373 --- src/cthulhu/ax_text.py | 1611 --- src/cthulhu/ax_utilities.py | 999 -- src/cthulhu/ax_utilities.pyi | 1288 -- src/cthulhu/ax_utilities_application.py | 209 - src/cthulhu/ax_utilities_collection.py | 2462 ---- src/cthulhu/ax_utilities_debugging.py | 285 - src/cthulhu/ax_utilities_event.py | 838 -- src/cthulhu/ax_utilities_relation.py | 389 - src/cthulhu/ax_utilities_role.py | 2533 ---- src/cthulhu/ax_utilities_state.py | 392 - src/cthulhu/ax_value.py | 211 - src/cthulhu/backends/__init__.py | 25 - src/cthulhu/backends/meson.build | 9 - src/cthulhu/backends/toml_backend.py | 474 - src/cthulhu/bookmarks.py | 330 - src/cthulhu/braille.py | 2112 ---- src/cthulhu/braille_generator.py | 531 - src/cthulhu/braille_rolenames.py | 296 - src/cthulhu/brlmon.py | 216 - src/cthulhu/brltablenames.py | 165 - src/cthulhu/caret_navigation.py | 463 - src/cthulhu/chat.py | 970 -- src/cthulhu/chnames.py | 822 -- src/cthulhu/cmdnames.py | 1182 -- src/cthulhu/colornames.py | 758 -- src/cthulhu/common_keyboardmap.py | 85 - src/cthulhu/compositor_state_adapter.py | 304 - src/cthulhu/compositor_state_i3.py | 264 - src/cthulhu/compositor_state_types.py | 53 - src/cthulhu/compositor_state_wayland.py | 365 - src/cthulhu/cthulhu-find.ui | 359 - src/cthulhu/cthulhu-setup.ui | 4747 -------- src/cthulhu/cthulhu.py | 1138 -- src/cthulhu/cthulhuVersion.py | 27 - src/cthulhu/cthulhu_bin.py.in | 380 - src/cthulhu/cthulhu_gtkbuilder.py | 182 - src/cthulhu/cthulhu_gui_find.py | 258 - src/cthulhu/cthulhu_gui_navlist.py | 196 - src/cthulhu/cthulhu_gui_prefs.py | 5416 --------- src/cthulhu/cthulhu_gui_profile.py | 148 - src/cthulhu/cthulhu_i18n.py.in | 91 - src/cthulhu/cthulhu_modifier_manager.py | 229 - src/cthulhu/cthulhu_platform.py.in | 54 - src/cthulhu/cthulhu_state.py | 116 - src/cthulhu/date_and_time_presenter.py | 124 - src/cthulhu/dbus_service.py | 1173 -- src/cthulhu/debug-2025-06-25-23:07:09.out | 1736 --- src/cthulhu/debug.py | 701 -- src/cthulhu/desktop_keyboardmap.py | 72 - src/cthulhu/dynamic_api_manager.py | 87 - src/cthulhu/event_manager.py | 1994 --- src/cthulhu/find.py | 267 - src/cthulhu/flat_review.py | 1483 --- src/cthulhu/flat_review_presenter.py | 1194 -- src/cthulhu/focus_manager.py | 489 - src/cthulhu/formatting.py | 1120 -- src/cthulhu/generator.py | 1587 --- src/cthulhu/gstreamer_support.py | 29 - src/cthulhu/guilabels.py | 1003 -- src/cthulhu/hardwarefactory.py | 571 - src/cthulhu/highlighter.py | 219 - src/cthulhu/input_event.py | 1234 -- src/cthulhu/input_event_manager.py | 2230 ---- src/cthulhu/keybindings.py | 599 - src/cthulhu/keynames.py | 340 - src/cthulhu/label_inference.py | 591 - src/cthulhu/laptop_keyboardmap.py | 75 - src/cthulhu/learn_mode_presenter.py | 407 - src/cthulhu/liveregions.py | 611 - src/cthulhu/logger.py | 73 - src/cthulhu/mako_notification_monitor.py | 419 - src/cthulhu/mathsymbols.py | 2332 ---- src/cthulhu/meson.build | 189 - src/cthulhu/messages.py | 2937 ----- src/cthulhu/mouse_review.py | 833 -- src/cthulhu/notification_presenter.py | 767 -- src/cthulhu/object_navigator.py | 331 - src/cthulhu/object_properties.py | 672 - src/cthulhu/phonnames.py | 85 - src/cthulhu/piper_audio_player.py | 307 - src/cthulhu/piper_voice_manager.py | 347 - src/cthulhu/piperfactory.py | 752 -- src/cthulhu/plugin.py | 105 - src/cthulhu/plugin_system_manager.py | 1126 -- src/cthulhu/plugins/AIAssistant/__init__.py | 22 - .../plugins/AIAssistant/ai_providers.py | 740 -- src/cthulhu/plugins/AIAssistant/meson.build | 15 - src/cthulhu/plugins/AIAssistant/plugin.info | 7 - src/cthulhu/plugins/AIAssistant/plugin.py | 2331 ---- src/cthulhu/plugins/ByeCthulhu/__init__.py | 25 - src/cthulhu/plugins/ByeCthulhu/meson.build | 14 - src/cthulhu/plugins/ByeCthulhu/plugin.info | 8 - src/cthulhu/plugins/ByeCthulhu/plugin.py | 77 - src/cthulhu/plugins/Clipboard/__init__.py | 30 - src/cthulhu/plugins/Clipboard/meson.build | 14 - src/cthulhu/plugins/Clipboard/plugin.info | 7 - src/cthulhu/plugins/Clipboard/plugin.py | 158 - src/cthulhu/plugins/CthulhuRemote/README.md | 206 - src/cthulhu/plugins/CthulhuRemote/__init__.py | 1 - .../plugins/CthulhuRemote/connection_info.py | 78 - .../plugins/CthulhuRemote/local_machine.py | 157 - src/cthulhu/plugins/CthulhuRemote/meson.build | 20 - src/cthulhu/plugins/CthulhuRemote/plugin.info | 7 - src/cthulhu/plugins/CthulhuRemote/plugin.py | 327 - src/cthulhu/plugins/CthulhuRemote/protocol.py | 41 - .../plugins/CthulhuRemote/serializer.py | 20 - .../plugins/CthulhuRemote/socket_utils.py | 23 - .../plugins/CthulhuRemote/transport.py | 269 - .../plugins/DisplayVersion/__init__.py | 25 - .../plugins/DisplayVersion/meson.build | 14 - .../plugins/DisplayVersion/plugin.info | 8 - src/cthulhu/plugins/DisplayVersion/plugin.py | 124 - src/cthulhu/plugins/GameMode/__init__.py | 14 - src/cthulhu/plugins/GameMode/meson.build | 14 - src/cthulhu/plugins/GameMode/plugin.info | 8 - src/cthulhu/plugins/GameMode/plugin.py | 98 - src/cthulhu/plugins/HelloCthulhu/__init__.py | 25 - src/cthulhu/plugins/HelloCthulhu/meson.build | 14 - src/cthulhu/plugins/HelloCthulhu/plugin.info | 7 - src/cthulhu/plugins/HelloCthulhu/plugin.py | 113 - src/cthulhu/plugins/OCR/README.md | 319 - src/cthulhu/plugins/OCR/__init__.py | 23 - src/cthulhu/plugins/OCR/meson.build | 14 - src/cthulhu/plugins/OCR/plugin.info | 8 - src/cthulhu/plugins/OCR/plugin.py | 854 -- src/cthulhu/plugins/SSIPProxy/__init__.py | 2 - src/cthulhu/plugins/SSIPProxy/meson.build | 14 - src/cthulhu/plugins/SSIPProxy/plugin.info | 11 - src/cthulhu/plugins/SSIPProxy/plugin.py | 587 - .../plugins/SimplePluginSystem/__init__.py | 25 - .../plugins/SimplePluginSystem/meson.build | 14 - .../plugins/SimplePluginSystem/plugin.info | 9 - .../plugins/SimplePluginSystem/plugin.py | 408 - src/cthulhu/plugins/SpeechHistory/__init__.py | 2 - src/cthulhu/plugins/SpeechHistory/meson.build | 15 - src/cthulhu/plugins/SpeechHistory/plugin.info | 8 - src/cthulhu/plugins/SpeechHistory/plugin.py | 541 - .../plugins/WindowTitleReader/__init__.py | 0 .../plugins/WindowTitleReader/meson.build | 14 - .../plugins/WindowTitleReader/plugin.info | 8 - .../plugins/WindowTitleReader/plugin.py | 619 - .../plugins/WineAccessibility/__init__.py | 5 - .../plugins/WineAccessibility/meson.build | 9 - .../plugins/WineAccessibility/plugin.info | 8 - .../plugins/WineAccessibility/plugin.py | 104 - src/cthulhu/plugins/hello_world/README.md | 42 - src/cthulhu/plugins/hello_world/__init__.py | 25 - src/cthulhu/plugins/hello_world/meson.build | 14 - src/cthulhu/plugins/hello_world/plugin.info | 8 - src/cthulhu/plugins/hello_world/plugin.py | 70 - src/cthulhu/plugins/meson.build | 17 - src/cthulhu/plugins/nvda2cthulhu/README.md | 24 - src/cthulhu/plugins/nvda2cthulhu/__init__.py | 5 - src/cthulhu/plugins/nvda2cthulhu/meson.build | 14 - src/cthulhu/plugins/nvda2cthulhu/plugin.info | 8 - src/cthulhu/plugins/nvda2cthulhu/plugin.py | 494 - src/cthulhu/plugins/self_voice/__init__.py | 25 - src/cthulhu/plugins/self_voice/meson.build | 14 - src/cthulhu/plugins/self_voice/plugin.info | 12 - src/cthulhu/plugins/self_voice/plugin.py | 198 - src/cthulhu/pronunciation_dict.py | 79 - src/cthulhu/punctuation_settings.py | 308 - src/cthulhu/resource_manager.py | 374 - src/cthulhu/role_keys.py | 57 - src/cthulhu/screen_lock_monitor.py | 155 - src/cthulhu/script.py | 637 - src/cthulhu/script_manager.py | 502 - src/cthulhu/script_utilities.py | 5801 --------- src/cthulhu/scripts/__init__.py | 25 - src/cthulhu/scripts/apps/Banshee/__init__.py | 26 - src/cthulhu/scripts/apps/Banshee/meson.build | 10 - src/cthulhu/scripts/apps/Banshee/script.py | 59 - .../scripts/apps/Banshee/script_utilities.py | 63 - src/cthulhu/scripts/apps/Eclipse/__init__.py | 26 - src/cthulhu/scripts/apps/Eclipse/meson.build | 9 - src/cthulhu/scripts/apps/Eclipse/script.py | 151 - src/cthulhu/scripts/apps/Mumble/__init__.py | 26 - src/cthulhu/scripts/apps/Mumble/chat.py | 150 - src/cthulhu/scripts/apps/Mumble/meson.build | 11 - src/cthulhu/scripts/apps/Mumble/script.py | 146 - .../scripts/apps/Mumble/script_utilities.py | 60 - .../scripts/apps/SeaMonkey/__init__.py | 31 - .../scripts/apps/SeaMonkey/meson.build | 9 - src/cthulhu/scripts/apps/SeaMonkey/script.py | 141 - .../scripts/apps/Thunderbird/__init__.py | 37 - .../scripts/apps/Thunderbird/meson.build | 11 - .../scripts/apps/Thunderbird/script.py | 404 - .../apps/Thunderbird/script_utilities.py | 97 - .../scripts/apps/Thunderbird/spellcheck.py | 106 - src/cthulhu/scripts/apps/__init__.py | 46 - src/cthulhu/scripts/apps/epiphany/__init__.py | 32 - src/cthulhu/scripts/apps/epiphany/meson.build | 9 - src/cthulhu/scripts/apps/epiphany/script.py | 56 - src/cthulhu/scripts/apps/evince/__init__.py | 30 - src/cthulhu/scripts/apps/evince/meson.build | 9 - src/cthulhu/scripts/apps/evince/script.py | 123 - .../scripts/apps/evolution/__init__.py | 30 - .../apps/evolution/braille_generator.py | 76 - .../scripts/apps/evolution/meson.build | 12 - src/cthulhu/scripts/apps/evolution/script.py | 190 - .../apps/evolution/script_utilities.py | 130 - .../apps/evolution/speech_generator.py | 163 - src/cthulhu/scripts/apps/gajim/__init__.py | 26 - src/cthulhu/scripts/apps/gajim/meson.build | 9 - src/cthulhu/scripts/apps/gajim/script.py | 110 - .../scripts/apps/gcalctool/__init__.py | 30 - .../scripts/apps/gcalctool/meson.build | 9 - src/cthulhu/scripts/apps/gcalctool/script.py | 101 - src/cthulhu/scripts/apps/gedit/__init__.py | 36 - src/cthulhu/scripts/apps/gedit/meson.build | 10 - src/cthulhu/scripts/apps/gedit/script.py | 177 - src/cthulhu/scripts/apps/gedit/spellcheck.py | 90 - .../scripts/apps/gnome-documents/__init__.py | 31 - .../scripts/apps/gnome-documents/meson.build | 11 - .../scripts/apps/gnome-documents/script.py | 78 - .../apps/gnome-documents/script_utilities.py | 49 - .../apps/gnome-documents/speech_generator.py | 46 - .../scripts/apps/gnome-shell/__init__.py | 26 - .../scripts/apps/gnome-shell/formatting.py | 73 - .../scripts/apps/gnome-shell/meson.build | 11 - .../scripts/apps/gnome-shell/script.py | 158 - .../apps/gnome-shell/script_utilities.py | 140 - src/cthulhu/scripts/apps/kwin/__init__.py | 31 - src/cthulhu/scripts/apps/kwin/meson.build | 10 - src/cthulhu/scripts/apps/kwin/script.py | 50 - .../scripts/apps/kwin/script_utilities.py | 61 - src/cthulhu/scripts/apps/meson.build | 30 - .../apps/notification-daemon/__init__.py | 31 - .../apps/notification-daemon/meson.build | 9 - .../apps/notification-daemon/script.py | 66 - .../scripts/apps/notify-osd/__init__.py | 31 - .../scripts/apps/notify-osd/meson.build | 9 - src/cthulhu/scripts/apps/notify-osd/script.py | 86 - src/cthulhu/scripts/apps/pidgin/__init__.py | 26 - src/cthulhu/scripts/apps/pidgin/chat.py | 70 - src/cthulhu/scripts/apps/pidgin/meson.build | 12 - src/cthulhu/scripts/apps/pidgin/script.py | 231 - .../scripts/apps/pidgin/script_utilities.py | 188 - .../scripts/apps/pidgin/speech_generator.py | 97 - .../apps/smuxi-frontend-gnome/__init__.py | 26 - .../scripts/apps/smuxi-frontend-gnome/chat.py | 52 - .../apps/smuxi-frontend-gnome/meson.build | 10 - .../apps/smuxi-frontend-gnome/script.py | 88 - src/cthulhu/scripts/apps/soffice/__init__.py | 26 - .../scripts/apps/soffice/braille_generator.py | 186 - .../scripts/apps/soffice/formatting.py | 91 - src/cthulhu/scripts/apps/soffice/meson.build | 14 - src/cthulhu/scripts/apps/soffice/script.py | 992 -- .../scripts/apps/soffice/script_utilities.py | 802 -- .../scripts/apps/soffice/speech_generator.py | 524 - .../scripts/apps/soffice/spellcheck.py | 146 - .../scripts/apps/steamwebhelper/__init__.py | 1 - .../scripts/apps/steamwebhelper/meson.build | 10 - .../scripts/apps/steamwebhelper/script.py | 1178 -- .../apps/steamwebhelper/script_utilities.py | 240 - src/cthulhu/scripts/apps/xfwm4/__init__.py | 31 - src/cthulhu/scripts/apps/xfwm4/meson.build | 9 - src/cthulhu/scripts/apps/xfwm4/script.py | 80 - src/cthulhu/scripts/default.py | 4050 ------- src/cthulhu/scripts/meson.build | 17 - src/cthulhu/scripts/self_voicing.py | 76 - src/cthulhu/scripts/sleepmode/__init__.py | 31 - .../scripts/sleepmode/braille_generator.py | 43 - src/cthulhu/scripts/sleepmode/meson.build | 12 - src/cthulhu/scripts/sleepmode/script.py | 140 - .../scripts/sleepmode/script_utilities.py | 59 - .../scripts/sleepmode/speech_generator.py | 62 - src/cthulhu/scripts/switcher/__init__.py | 31 - src/cthulhu/scripts/switcher/meson.build | 10 - src/cthulhu/scripts/switcher/script.py | 146 - .../scripts/switcher/script_utilities.py | 86 - src/cthulhu/scripts/terminal/__init__.py | 30 - .../scripts/terminal/braille_generator.py | 43 - src/cthulhu/scripts/terminal/meson.build | 12 - src/cthulhu/scripts/terminal/script.py | 166 - .../scripts/terminal/script_utilities.py | 227 - .../scripts/terminal/speech_generator.py | 43 - .../scripts/toolkits/Chromium/__init__.py | 30 - .../toolkits/Chromium/braille_generator.py | 71 - .../scripts/toolkits/Chromium/meson.build | 12 - .../scripts/toolkits/Chromium/script.py | 545 - .../toolkits/Chromium/script_utilities.py | 453 - .../toolkits/Chromium/speech_generator.py | 103 - src/cthulhu/scripts/toolkits/GAIL/__init__.py | 26 - src/cthulhu/scripts/toolkits/GAIL/meson.build | 10 - src/cthulhu/scripts/toolkits/GAIL/script.py | 126 - .../scripts/toolkits/GAIL/script_utilities.py | 84 - .../scripts/toolkits/Gecko/__init__.py | 27 - .../scripts/toolkits/Gecko/meson.build | 10 - src/cthulhu/scripts/toolkits/Gecko/script.py | 418 - .../toolkits/Gecko/script_utilities.py | 331 - .../toolkits/J2SE-access-bridge/__init__.py | 27 - .../toolkits/J2SE-access-bridge/formatting.py | 69 - .../toolkits/J2SE-access-bridge/meson.build | 12 - .../toolkits/J2SE-access-bridge/script.py | 200 - .../J2SE-access-bridge/script_utilities.py | 139 - .../J2SE-access-bridge/speech_generator.py | 170 - src/cthulhu/scripts/toolkits/Qt/__init__.py | 26 - src/cthulhu/scripts/toolkits/Qt/meson.build | 10 - src/cthulhu/scripts/toolkits/Qt/script.py | 91 - .../scripts/toolkits/Qt/script_utilities.py | 83 - src/cthulhu/scripts/toolkits/VCL.py | 37 - .../scripts/toolkits/WebKitGtk/__init__.py | 29 - .../toolkits/WebKitGtk/braille_generator.py | 110 - .../scripts/toolkits/WebKitGtk/meson.build | 12 - .../scripts/toolkits/WebKitGtk/script.py | 681 -- .../toolkits/WebKitGtk/script_utilities.py | 303 - .../toolkits/WebKitGtk/speech_generator.py | 203 - src/cthulhu/scripts/toolkits/__init__.py | 34 - .../scripts/toolkits/clutter/__init__.py | 26 - .../scripts/toolkits/clutter/meson.build | 10 - .../scripts/toolkits/clutter/script.py | 42 - .../toolkits/clutter/script_utilities.py | 46 - src/cthulhu/scripts/toolkits/gtk/__init__.py | 27 - src/cthulhu/scripts/toolkits/gtk/meson.build | 10 - src/cthulhu/scripts/toolkits/gtk/script.py | 245 - .../scripts/toolkits/gtk/script_utilities.py | 249 - src/cthulhu/scripts/toolkits/meson.build | 18 - src/cthulhu/scripts/web/__init__.py | 30 - src/cthulhu/scripts/web/bookmarks.py | 143 - src/cthulhu/scripts/web/braille_generator.py | 308 - src/cthulhu/scripts/web/event_router.py | 121 - src/cthulhu/scripts/web/meson.build | 16 - src/cthulhu/scripts/web/script.py | 3304 ----- src/cthulhu/scripts/web/script_utilities.py | 5698 --------- src/cthulhu/scripts/web/sound_generator.py | 129 - src/cthulhu/scripts/web/speech_generator.py | 898 -- src/cthulhu/scripts/web/tutorial_generator.py | 52 - src/cthulhu/settings.py | 542 - src/cthulhu/settings_manager.py | 918 -- src/cthulhu/signal_manager.py | 101 - src/cthulhu/sleep_mode_manager.py | 303 - src/cthulhu/sound.py | 628 - src/cthulhu/sound_generator.py | 405 - src/cthulhu/sound_helper.py | 466 - src/cthulhu/sound_sink.py | 115 - src/cthulhu/sound_theme_manager.py | 448 - src/cthulhu/speech.py | 747 -- src/cthulhu/speech_and_verbosity_manager.py | 1948 --- src/cthulhu/speech_generator.py | 3118 ----- src/cthulhu/speech_history.py | 176 - src/cthulhu/speechdispatcherfactory.py | 855 -- src/cthulhu/speechserver.py | 246 - src/cthulhu/spellcheck.py | 339 - src/cthulhu/structural_navigation.py | 2441 ---- src/cthulhu/text_attribute_names.py | 784 -- src/cthulhu/translation_context.py | 118 - src/cthulhu/translation_manager.py | 77 - src/cthulhu/tutorialgenerator.py | 797 -- src/cthulhu/typing_echo_presenter.py | 332 - src/cthulhu/wayland_protocols/__init__.py | 14 - .../wayland_protocols/ext_workspace_v1.py | 130 - src/cthulhu/wayland_protocols/meson.build | 9 - src/cthulhu/where_am_i_presenter.py | 520 - src/cthulhu/wine_access_manager.py | 223 - src/cthulhu/wnck_support.py | 40 - src/louis/.gitignore | 4 - src/meson.build | 9 - test-local.sh | 63 - testdata/parity-ledger.csv | 69 + tests/browser-catalog.html | 26 + tests/browser-changing.html | 32 + tests/browser-editor.html | 7 + tests/browser-fragments.html | 31 + tests/browser-lines.html | 17 + tests/browser-linked-headings.html | 18 + tests/browser-lists.html | 20 + tests/browser-live.html | 31 + tests/browser-named-links.html | 13 + tests/browser-next.html | 7 + tests/browser-positions.html | 28 + tests/browser-progress.html | 19 + tests/browser-replaced-feed.html | 12 + tests/browser.html | 45 + tests/check_speech.py | 97 + tests/conftest.py | 65 - tests/current_line_fixture.py | 69 + tests/firefox-baseline.html | 11 + tests/gtk_alert.py | 33 + tests/gtk_background_events.py | 82 + tests/gtk_edit_labels.py | 35 + tests/gtk_progress.py | 46 + tests/gtk_radio_group.py | 19 + tests/gtk_selection.py | 35 + tests/gtk_table.py | 65 + tests/gtk_tree.py | 162 + tests/gtk_web_notification.py | 76 + tests/libreoffice.fods | 31 + tests/native_alert.py | 83 + tests/native_atspi.py | 308 + tests/native_browser.py | 150 + tests/native_browser_navigation.py | 187 + tests/native_clipboard_preferences.py | 222 + tests/native_echo_preview.py | 368 + tests/native_firefox.py | 112 + tests/native_internal_ui.py | 119 + tests/native_libreoffice.py | 179 + tests/native_mozilla.py | 207 + tests/native_notifications.py | 175 + tests/native_ownership.py | 356 + tests/native_preferences.py | 1564 +++ tests/native_progress.py | 42 + tests/native_qt_controls.py | 112 + tests/native_speech_defaults.py | 114 + tests/native_speech_history.py | 147 + tests/native_tentacle_extensions.py | 100 + tests/native_tentacle_settings.py | 47 + tests/native_terminal.py | 199 + tests/native_test_session.py | 40 + tests/native_thunderbird.py | 382 + tests/native_webscripts.py | 45 + tests/native_x11.py | 746 ++ tests/ocr_capture_fixture.py | 135 + tests/ocr_click_fixture.py | 34 + tests/ocr_geometry_fixture.py | 89 + tests/ocr_review_fixture.py | 101 + tests/ocr_session_fixture.py | 125 + tests/review_cache_fixture.c | 162 + tests/run-delegated-reader.sh | 18 + tests/steam_big_picture_log.py | 94 + tests/steam_focus_fixture.py | 79 + tests/test_arch_pkgbuild_optional_wine.py | 147 - tests/test_bye_cthulhu_regressions.py | 30 - tests/test_chromium_omnibox_regressions.py | 251 - ...st_compositor_state_adapter_regressions.py | 444 - tests/test_compositor_state_i3_regressions.py | 201 - tests/test_cthulhu_remote_plugin.py | 173 - tests/test_dbus_service_native_interfaces.py | 361 - tests/test_debug_startup_timing.py | 79 - ...st_default_script_clipboard_regressions.py | 472 - ...est_default_script_shutdown_regressions.py | 32 - tests/test_document_selection_regressions.py | 229 - ..._manager_compositor_context_regressions.py | 383 - ...vent_manager_relevance_gate_regressions.py | 194 - ...event_manager_xterm_handoff_regressions.py | 129 - tests/test_hardwarefactory_regressions.py | 100 - ...t_event_manager_key_watcher_regressions.py | 409 - ...put_event_manager_x11_focus_regressions.py | 1090 -- tests/test_input_event_regressions.py | 65 - tests/test_learn_mode_regressions.py | 44 - tests/test_link_sound_regressions.py | 220 - tests/test_mako_notification_monitor.py | 160 - ...ouse_review_pointer_monitor_regressions.py | 232 - tests/test_native_test_session.py | 117 + tests/test_notification_daemon_regressions.py | 58 - ...notification_presenter_mako_regressions.py | 409 - tests/test_nvda2cthulhu_regressions.py | 47 - tests/test_piperfactory_rate_mapping.py | 78 - tests/test_plugin_preferences_regressions.py | 82 - .../test_plugin_system_manager_regressions.py | 201 - tests/test_preferences_responses.py | 59 + ...resentation_interrupt_sound_regressions.py | 46 - tests/test_runtime_state_snapshot.py | 174 - tests/test_screen_lock_monitor.py | 211 - tests/test_script_utilities_regressions.py | 28 - tests/test_self_voice_plugin_regressions.py | 19 - tests/test_sound_helper_backend.py | 93 - tests/test_sound_preferences_regressions.py | 179 - tests/test_sound_recovery.py | 170 - .../test_speech_default_policy_regressions.py | 91 - ..._speechdispatcher_interrupt_regressions.py | 154 - ...hdispatcher_voice_selection_regressions.py | 212 - tests/test_steam_notification_regressions.py | 223 - tests/test_steam_selection_regressions.py | 1105 -- ...structural_navigation_table_regressions.py | 105 - ..._toml_backend_legacy_schema_regressions.py | 139 - tests/test_web_event_router_contract.py | 313 - tests/test_web_event_sequences.py | 1216 -- tests/test_web_input_regressions.py | 2610 ---- tests/test_web_layout_mode_regressions.py | 164 - tests/test_web_router_regressions.py | 153 - .../test_window_title_fallback_regressions.py | 263 - tests/test_wine_access_controller_contract.py | 46 - tests/test_wine_access_manager.py | 146 - tests/test_wnck_session_regressions.py | 66 - tests/text-preferences.html | 9 + tests/text_label_fixture.py | 77 + tests/vte_terminal.py | 26 + tests/window_title_fixture.py | 75 + tests/window_titles.md | 86 + tests/wine_review_x11.py | 153 + tests/x11_focus_child.py | 45 + tests/x11_grab_fixture.py | 75 + tests/xorg_suspension_probe.c | 66 + tools/generate_dbus_documentation.py | 477 - wine-access/CMakeLists.txt | 30 - wine-access/main.cpp | 555 - wine-access/nvdaController.idl | 51 - wine-access/winelib-toolchain.cmake | 14 - 1483 files changed, 145308 insertions(+), 938069 deletions(-) create mode 100644 AUTHORS create mode 100644 CONTRIBUTING.md delete mode 100644 COPYING delete mode 100644 HACKING create mode 100644 LIBREOFFICE_SUPPORT.md create mode 100644 LICENSE create mode 100644 PROGRESS_BARS.md delete mode 100644 README-DEVELOPMENT.md delete mode 100644 README-REMOTE-CONTROLLER.md delete mode 100644 RELEASE-HOWTO delete mode 100644 REMOTE-CONTROLLER-COMMANDS.md create mode 100644 STEAM_FOCUS.md delete mode 100644 TODO create mode 100644 assets/sounds/default/autocomplete.wav rename {sounds => assets/sounds}/default/browse_mode.wav (100%) rename {sounds => assets/sounds}/default/button.wav (100%) rename {sounds => assets/sounds}/default/checkbox_checked.wav (100%) rename {sounds => assets/sounds}/default/checkbox_mixed.wav (100%) rename {sounds => assets/sounds}/default/checkbox_unchecked.wav (100%) rename {sounds => assets/sounds}/default/combobox.wav (100%) rename {sounds => assets/sounds}/default/focus_mode.wav (100%) rename {sounds => assets/sounds}/default/link.wav (100%) rename {sounds => assets/sounds}/default/link_visited.wav (100%) rename {sounds => assets/sounds}/default/radiobutton_checked.wav (100%) rename {sounds => assets/sounds}/default/radiobutton_unchecked.wav (100%) rename {sounds => assets/sounds}/default/start.wav (100%) rename {sounds => assets/sounds}/default/stop.wav (100%) rename {sounds => assets/sounds}/default/switch_off.wav (100%) rename {sounds => assets/sounds}/default/switch_on.wav (100%) rename {sounds => assets/sounds}/default/togglebutton_checked.wav (100%) rename {sounds => assets/sounds}/default/togglebutton_unchecked.wav (100%) create mode 100644 assets/sounds/embed.go delete mode 100755 build-local.sh delete mode 100755 clean-local.sh create mode 100644 cmd/cthulhu-braille/main.go create mode 100644 cmd/cthulhu/greeter.go create mode 100644 cmd/cthulhu/greeter_test.go create mode 100644 cmd/cthulhu/main.go create mode 100644 cmd/cthulhu/main_test.go create mode 100644 cmd/cthulhu/replace.go create mode 100644 cmd/cthulhu/replace_test.go create mode 100644 cmd/parityledger/main.go create mode 100644 cmd/parityledger/main_test.go create mode 100644 cmd/tentacle-host/main.go delete mode 100644 contrib/cthulhu-autostart.desktop delete mode 100644 contrib/toggle.screenreader.gschema.xml delete mode 100644 cthulhu.doap create mode 100644 distro-packages/Arch-Linux/cthulhu-git/.SRCINFO delete mode 100644 distro-packages/Arch-Linux/cthulhu-wine-access-git/PKGBUILD delete mode 100644 distro-packages/Arch-Linux/cthulhu-wine-access/PKGBUILD delete mode 100644 distro-packages/Arch-Linux/cthulhu/PKGBUILD delete mode 100755 distro-packages/Slackware/cthulhu.SlackBuild delete mode 100644 distro-packages/Slackware/doinst.sh delete mode 100644 distro-packages/Slackware/slack-desc delete mode 100644 distro-packages/Slint/README delete mode 100644 distro-packages/Slint/cthulhu-info delete mode 100755 distro-packages/Slint/cthulhu.SlackBuild delete mode 100644 distro-packages/Slint/doinst.sh delete mode 100644 distro-packages/Slint/slack-desc delete mode 100644 docs/LOGGING.md delete mode 100644 docs/atspi-document-selection-handoff.md delete mode 100644 docs/man/cthulhu.1 delete mode 100644 docs/man/meson.build delete mode 100644 docs/meson.build delete mode 100644 docs/superpowers/specs/2026-04-05-sounds-tab-design.md delete mode 100644 docs/superpowers/specs/2026-04-07-mouse-review-wayland-design.md delete mode 100644 docs/superpowers/specs/2026-04-09-wayland-compositor-event-interface-design.md delete mode 100644 docs/superpowers/specs/2026-04-10-tolk-nvda-presence-design.md create mode 100644 docs/testing/atspi-lifecycle.md create mode 100644 docs/testing/background-events.md create mode 100644 docs/testing/benchmarks.md create mode 100644 docs/testing/browser-audit-fixes.md create mode 100644 docs/testing/browser-editor.md create mode 100644 docs/testing/browser-lists.md create mode 100644 docs/testing/browser-navigation-performance.md create mode 100644 docs/testing/browser-release-review.md create mode 100644 docs/testing/current-line.md create mode 100644 docs/testing/flat-review-robustness.md create mode 100644 docs/testing/flat-review-tables.md create mode 100644 docs/testing/flatpak-foreground.md create mode 100644 docs/testing/gui-list-tables.md create mode 100644 docs/testing/mozilla-reading.md create mode 100644 docs/testing/phonetic-review.md create mode 100644 docs/testing/qt-control-states.md create mode 100644 docs/testing/reading-settings.md create mode 100644 docs/testing/speech-preferences.md create mode 100644 docs/testing/speech-queue.md create mode 100644 docs/testing/terminal-scrollback.md create mode 100644 docs/testing/text-control-labels.md create mode 100644 docs/testing/thunderbird-workflows.md delete mode 100644 docs/wine-accessibility.md create mode 100644 go.mod create mode 100644 go.sum create mode 100755 hooks/pre-push delete mode 100644 icons/AUTHORS delete mode 100644 icons/COPYING delete mode 100644 icons/cthulhu-16x16.png delete mode 100644 icons/cthulhu-22x22.png delete mode 100644 icons/cthulhu-24x24.png delete mode 100644 icons/cthulhu-256x256.png delete mode 100644 icons/cthulhu-32x32.png delete mode 100644 icons/cthulhu-48x48.png delete mode 100644 icons/cthulhu-scalable.svg delete mode 100644 icons/cthulhu-splash.svg delete mode 100644 icons/cthulhu-symbolic.svg delete mode 100644 icons/meson.build create mode 100644 internal/app/app.go create mode 100644 internal/app/app_test.go create mode 100644 internal/app/application_behavior.go create mode 100644 internal/app/application_focus_test.go create mode 100644 internal/app/autocomplete.go create mode 100644 internal/app/braille_context.go create mode 100644 internal/app/braille_context_test.go create mode 100644 internal/app/braille_frames.go create mode 100644 internal/app/braille_helper_test.go create mode 100644 internal/app/braille_presentation.go create mode 100644 internal/app/braille_presentation_test.go create mode 100644 internal/app/braille_routing.go create mode 100644 internal/app/braille_session.go create mode 100644 internal/app/braille_text_attributes.go create mode 100644 internal/app/braille_text_attributes_test.go create mode 100644 internal/app/braille_worker.go create mode 100644 internal/app/braille_worker_test.go create mode 100644 internal/app/browser_activation_test.go create mode 100644 internal/app/browser_button_names.go create mode 100644 internal/app/browser_button_names_test.go create mode 100644 internal/app/browser_dynamic_test.go create mode 100644 internal/app/browser_editor_native_test.go create mode 100644 internal/app/browser_events_test.go create mode 100644 internal/app/browser_lists.go create mode 100644 internal/app/browser_lists_native_test.go create mode 100644 internal/app/browser_lists_test.go create mode 100644 internal/app/browser_menu_native_test.go create mode 100644 internal/app/browser_mode.go create mode 100644 internal/app/browser_mode_test.go create mode 100644 internal/app/browser_nested_document_native_test.go create mode 100644 internal/app/browser_replacement_native_test.go create mode 100644 internal/app/browser_reveal_native_test.go create mode 100644 internal/app/browser_tabs_native_test.go create mode 100644 internal/app/browser_tooltip_native_test.go create mode 100644 internal/app/capitalization.go create mode 100644 internal/app/capitalization_test.go create mode 100644 internal/app/character_attributes.go create mode 100644 internal/app/character_attributes_test.go create mode 100644 internal/app/character_color_names.go create mode 100644 internal/app/clipboard.go create mode 100644 internal/app/clipboard_copy.go create mode 100644 internal/app/clipboard_copy_test.go create mode 100644 internal/app/clipboard_test.go create mode 100644 internal/app/clipboard_watch.go create mode 100644 internal/app/clipboard_watch_test.go create mode 100644 internal/app/combo_presentation.go create mode 100644 internal/app/combo_presentation_test.go create mode 100644 internal/app/command_input_test.go create mode 100644 internal/app/configured_speaker.go create mode 100644 internal/app/configured_speaker_native_test.go create mode 100644 internal/app/control_events_test.go create mode 100644 internal/app/current_line.go create mode 100644 internal/app/current_line_test.go create mode 100644 internal/app/date_time.go create mode 100644 internal/app/date_time_test.go create mode 100644 internal/app/document_diagnostics_test.go create mode 100644 internal/app/document_line_test.go create mode 100644 internal/app/document_native_test.go create mode 100644 internal/app/document_review.go create mode 100644 internal/app/document_review_test.go create mode 100644 internal/app/echo_preferences_test.go create mode 100644 internal/app/echo_speaker.go create mode 100644 internal/app/echo_speaker_test.go create mode 100644 internal/app/editable_document_test.go create mode 100644 internal/app/event_accessibility.go create mode 100644 internal/app/event_autocomplete.go create mode 100644 internal/app/event_browser_tabs.go create mode 100644 internal/app/event_caret.go create mode 100644 internal/app/event_caret_test.go create mode 100644 internal/app/event_filters.go create mode 100644 internal/app/event_focus.go create mode 100644 internal/app/event_focus_ownership.go create mode 100644 internal/app/event_focus_test.go create mode 100644 internal/app/event_gui_table_test.go create mode 100644 internal/app/event_lifecycle.go create mode 100644 internal/app/event_loop.go create mode 100644 internal/app/event_navigation_filters.go create mode 100644 internal/app/event_notification.go create mode 100644 internal/app/event_presentation.go create mode 100644 internal/app/event_presentation_test.go create mode 100644 internal/app/event_review_results.go create mode 100644 internal/app/event_state.go create mode 100644 internal/app/event_text_selection.go create mode 100644 internal/app/event_tooltip.go create mode 100644 internal/app/event_tooltip_test.go create mode 100644 internal/app/flat_review.go create mode 100644 internal/app/flat_review_test.go create mode 100644 internal/app/focus_gate.go create mode 100644 internal/app/foreground_test.go create mode 100644 internal/app/gui_table_presentation.go create mode 100644 internal/app/gui_table_test.go create mode 100644 internal/app/i38lock_feedback_native_test.go create mode 100644 internal/app/indentation.go create mode 100644 internal/app/input_events.go create mode 100644 internal/app/input_events_test.go create mode 100644 internal/app/internal_ui.go create mode 100644 internal/app/internal_ui_native_test.go create mode 100644 internal/app/internal_ui_output_test.go create mode 100644 internal/app/internal_ui_test.go create mode 100644 internal/app/interruption_test.go create mode 100644 internal/app/key_bindings_test.go create mode 100644 internal/app/learn_mode.go create mode 100644 internal/app/learn_mode_test.go create mode 100644 internal/app/libreoffice.go create mode 100644 internal/app/libreoffice_headers.go create mode 100644 internal/app/libreoffice_headers_test.go create mode 100644 internal/app/libreoffice_native_test.go create mode 100644 internal/app/libreoffice_selection.go create mode 100644 internal/app/libreoffice_selection_test.go create mode 100644 internal/app/libreoffice_test.go create mode 100644 internal/app/linked_headings_native_test.go create mode 100644 internal/app/live_region_test.go create mode 100644 internal/app/live_settings.go create mode 100644 internal/app/mouse_review.go create mode 100644 internal/app/mouse_review_test.go create mode 100644 internal/app/named_links_native_test.go create mode 100644 internal/app/notification_list_test.go create mode 100644 internal/app/notification_test.go create mode 100644 internal/app/notifications.go create mode 100644 internal/app/object_review_events_test.go create mode 100644 internal/app/ocr_activate.go create mode 100644 internal/app/ocr_commands.go create mode 100644 internal/app/ocr_copy.go create mode 100644 internal/app/ocr_copy_test.go create mode 100644 internal/app/ocr_native_test.go create mode 100644 internal/app/ocr_read_all.go create mode 100644 internal/app/ocr_reading_test.go create mode 100644 internal/app/ocr_refresh.go create mode 100644 internal/app/ocr_refresh_activation_test.go create mode 100644 internal/app/ocr_selection.go create mode 100644 internal/app/ocr_session.go create mode 100644 internal/app/ocr_session_test.go create mode 100644 internal/app/output_queue.go create mode 100644 internal/app/output_queue_test.go create mode 100644 internal/app/pause_chunks_test.go create mode 100644 internal/app/pending_presentation.go create mode 100644 internal/app/phonetic_hints.go create mode 100644 internal/app/phonetic_hints_test.go create mode 100644 internal/app/preferences.go create mode 100644 internal/app/preferences_application.go create mode 100644 internal/app/preferences_application_test.go create mode 100644 internal/app/preferences_apply.go create mode 100644 internal/app/preferences_echo_preview_test.go create mode 100644 internal/app/preferences_feedback_test.go create mode 100644 internal/app/preferences_preview.go create mode 100644 internal/app/preferences_preview_events.go create mode 100644 internal/app/preferences_session.go create mode 100644 internal/app/preferences_session_test.go create mode 100644 internal/app/preferences_tentacles.go create mode 100644 internal/app/preferences_test.go create mode 100644 internal/app/progress_bars.go create mode 100644 internal/app/progress_bars_test.go create mode 100644 internal/app/progress_browser_native_test.go create mode 100644 internal/app/progress_native_test.go create mode 100644 internal/app/progress_settings.go create mode 100644 internal/app/prompt_presentation.go create mode 100644 internal/app/prompt_presentation_test.go create mode 100644 internal/app/qt_controls_native_test.go create mode 100644 internal/app/radio_sound.go create mode 100644 internal/app/radio_sound_test.go create mode 100644 internal/app/read_all.go create mode 100644 internal/app/read_all_test.go create mode 100644 internal/app/reading_context.go create mode 100644 internal/app/reading_context_test.go create mode 100644 internal/app/reading_preferences_test.go create mode 100644 internal/app/reading_speech.go create mode 100644 internal/app/reading_speech_test.go create mode 100644 internal/app/remote.go create mode 100644 internal/app/remote_control.go create mode 100644 internal/app/remote_control_test.go create mode 100644 internal/app/remote_test.go create mode 100644 internal/app/review_spelling.go create mode 100644 internal/app/review_spelling_test.go create mode 100644 internal/app/runtime_backends.go create mode 100644 internal/app/runtime_commands.go create mode 100644 internal/app/runtime_commands_test.go create mode 100644 internal/app/runtime_notifications.go create mode 100644 internal/app/runtime_platform.go create mode 100644 internal/app/runtime_platform_test.go create mode 100644 internal/app/runtime_remote.go create mode 100644 internal/app/runtime_review.go create mode 100644 internal/app/runtime_settings.go create mode 100644 internal/app/runtime_settings_test.go create mode 100644 internal/app/runtime_shutdown.go create mode 100644 internal/app/runtime_test.go create mode 100644 internal/app/runtime_workers.go create mode 100644 internal/app/screen_lock.go create mode 100644 internal/app/screen_lock_test.go create mode 100644 internal/app/selection_native_test.go create mode 100644 internal/app/speech_delivery.go create mode 100644 internal/app/speech_enable_test.go create mode 100644 internal/app/speech_history.go create mode 100644 internal/app/speech_history_test.go create mode 100644 internal/app/speech_history_window.go create mode 100644 internal/app/speech_interrupt.go create mode 100644 internal/app/speech_key_echo_test.go create mode 100644 internal/app/speech_mode.go create mode 100644 internal/app/speech_mode_test.go create mode 100644 internal/app/speech_settings.go create mode 100644 internal/app/speech_settings_test.go create mode 100644 internal/app/speech_title_input.go create mode 100644 internal/app/speech_title_input_test.go create mode 100644 internal/app/speech_uninterruptible.go create mode 100644 internal/app/speech_worker.go create mode 100644 internal/app/speech_worker_test.go create mode 100644 internal/app/startup_sound_test.go create mode 100644 internal/app/steam_activation_test.go create mode 100644 internal/app/table_native_test.go create mode 100644 internal/app/tentacle_clipboard.go create mode 100644 internal/app/tentacle_clipboard_test.go create mode 100644 internal/app/tentacle_install_test.go create mode 100644 internal/app/tentacle_interaction.go create mode 100644 internal/app/tentacle_interaction_test.go create mode 100644 internal/app/tentacle_management.go create mode 100644 internal/app/tentacle_management_test.go create mode 100644 internal/app/tentacle_output.go create mode 100644 internal/app/tentacle_output_test.go create mode 100644 internal/app/tentacle_reader.go create mode 100644 internal/app/tentacle_reader_test.go create mode 100644 internal/app/tentacle_repositories.go create mode 100644 internal/app/tentacle_repositories_test.go create mode 100644 internal/app/tentacle_settings_test.go create mode 100644 internal/app/tentacle_uninterruptible_test.go create mode 100644 internal/app/tentacles.go create mode 100644 internal/app/tentacles_test.go create mode 100644 internal/app/terminal_events.go create mode 100644 internal/app/terminal_events_test.go create mode 100644 internal/app/test_helpers_test.go create mode 100644 internal/app/text_selection.go create mode 100644 internal/app/text_selection_test.go create mode 100644 internal/app/version.go create mode 100644 internal/app/version_test.go create mode 100644 internal/app/wayland_native_test.go create mode 100644 internal/app/webscripts.go create mode 100644 internal/app/webscripts_test.go create mode 100644 internal/app/window_owner.go create mode 100644 internal/app/window_owner_test.go create mode 100644 internal/app/window_speech_test.go create mode 100644 internal/app/window_title_command_test.go create mode 100644 internal/app/window_titles.go create mode 100644 internal/app/window_titles_native_test.go create mode 100644 internal/app/window_titles_test.go create mode 100644 internal/app/wine_echo_focus.go create mode 100644 internal/app/wine_echo_focus_test.go create mode 100644 internal/app/wine_events.go create mode 100644 internal/app/wine_events_native_test.go create mode 100644 internal/app/wine_events_test.go create mode 100644 internal/app/wine_review_capture.go create mode 100644 internal/app/wine_review_capture_test.go create mode 100644 internal/app/wine_review_focus.go create mode 100644 internal/app/wine_review_focus_test.go create mode 100644 internal/app/wine_review_native_test.go create mode 100644 internal/app/wine_typing_echo_settings_test.go create mode 100644 internal/app/wine_window_titles.go create mode 100644 internal/app/wine_window_titles_native_test.go create mode 100644 internal/app/xterm_handoff_test.go create mode 100644 internal/atspi/adapter.go create mode 100644 internal/atspi/adapter_actions_native.go create mode 100644 internal/atspi/adapter_capture.c create mode 100644 internal/atspi/adapter_document_native.go create mode 100644 internal/atspi/adapter_event_callback_native.go create mode 100644 internal/atspi/adapter_event_filter_native.go create mode 100644 internal/atspi/adapter_events.c create mode 100644 internal/atspi/adapter_foreground_native.go create mode 100644 internal/atspi/adapter_lifecycle_native.go create mode 100644 internal/atspi/adapter_menu_states.c create mode 100644 internal/atspi/adapter_native.h create mode 100644 internal/atspi/adapter_native_test.go create mode 100644 internal/atspi/adapter_ocr_native.go create mode 100644 internal/atspi/adapter_position.c create mode 100644 internal/atspi/adapter_references_native.go create mode 100644 internal/atspi/adapter_secure_native.go create mode 100644 internal/atspi/adapter_snapshot_native.go create mode 100644 internal/atspi/adapter_text_boundary.c create mode 100644 internal/atspi/adapter_tree_native.go create mode 100644 internal/atspi/adapter_tree_test.go create mode 100644 internal/atspi/adapter_window_title.go create mode 100644 internal/atspi/alert_native_test.go create mode 100644 internal/atspi/background_events_native_test.go create mode 100644 internal/atspi/braille_native.go create mode 100644 internal/atspi/braille_test.go create mode 100644 internal/atspi/browser_live_native_test.go create mode 100644 internal/atspi/browser_native_test.go create mode 100644 internal/atspi/capture_diagnostics.go create mode 100644 internal/atspi/capture_diagnostics_test.go create mode 100644 internal/atspi/catalog_native_test.go create mode 100644 internal/atspi/character_attributes_native.go create mode 100644 internal/atspi/current_line_native.go create mode 100644 internal/atspi/current_line_native_test.go create mode 100644 internal/atspi/document.go create mode 100644 internal/atspi/document_caret.go create mode 100644 internal/atspi/document_caret_echo.go create mode 100644 internal/atspi/document_caret_echo_test.go create mode 100644 internal/atspi/document_caret_test.go create mode 100644 internal/atspi/document_error.go create mode 100644 internal/atspi/document_error_test.go create mode 100644 internal/atspi/document_hypertext_native.go create mode 100644 internal/atspi/document_line.go create mode 100644 internal/atspi/document_lines_native.go create mode 100644 internal/atspi/document_lines_native_test.go create mode 100644 internal/atspi/document_rows.go create mode 100644 internal/atspi/document_rows_test.go create mode 100644 internal/atspi/document_sound.go create mode 100644 internal/atspi/document_sound_test.go create mode 100644 internal/atspi/document_test.go create mode 100644 internal/atspi/document_text_lines.go create mode 100644 internal/atspi/document_text_lines_test.go create mode 100644 internal/atspi/document_view.go create mode 100644 internal/atspi/document_view_test.go create mode 100644 internal/atspi/echo_focus.go create mode 100644 internal/atspi/echo_focus_native_test.go create mode 100644 internal/atspi/echo_focus_test.go create mode 100644 internal/atspi/edit_labels_native_test.go create mode 100644 internal/atspi/firefox_native_test.go create mode 100644 internal/atspi/flatpak_process.go create mode 100644 internal/atspi/flatpak_process_test.go create mode 100644 internal/atspi/foreground.go create mode 100644 internal/atspi/foreground_native_test.go create mode 100644 internal/atspi/foreground_test.go create mode 100644 internal/atspi/geometry.go create mode 100644 internal/atspi/geometry_test.go create mode 100644 internal/atspi/libreoffice.go create mode 100644 internal/atspi/libreoffice_headers.go create mode 100644 internal/atspi/libreoffice_headers_native.go create mode 100644 internal/atspi/libreoffice_headers_test.go create mode 100644 internal/atspi/libreoffice_native.go create mode 100644 internal/atspi/libreoffice_selection_native.go create mode 100644 internal/atspi/libreoffice_test.go create mode 100644 internal/atspi/lifecycle_native_test.go create mode 100644 internal/atspi/live_regions.go create mode 100644 internal/atspi/live_regions_native.go create mode 100644 internal/atspi/live_regions_test.go create mode 100644 internal/atspi/model.go create mode 100644 internal/atspi/model_test.go create mode 100644 internal/atspi/mouse_review_native.go create mode 100644 internal/atspi/mouse_review_native_test.go create mode 100644 internal/atspi/ocr_geometry.go create mode 100644 internal/atspi/ocr_geometry_test.go create mode 100644 internal/atspi/ocr_native_test.go create mode 100644 internal/atspi/pointer_native_test.go create mode 100644 internal/atspi/position_native_test.go create mode 100644 internal/atspi/preferences_native_test.go create mode 100644 internal/atspi/read_all_native.go create mode 100644 internal/atspi/replaced_feed_native_test.go create mode 100644 internal/atspi/review.go create mode 100644 internal/atspi/review_cache_native_test.go create mode 100644 internal/atspi/review_table_native.go create mode 100644 internal/atspi/review_table_native_test.go create mode 100644 internal/atspi/review_test.go create mode 100644 internal/atspi/session_native_test.go create mode 100644 internal/atspi/speech_metadata_native.go create mode 100644 internal/atspi/speech_metadata_native_test.go create mode 100644 internal/atspi/tentacle_item_native.go create mode 100644 internal/atspi/testdata/text_boundary.c create mode 100644 internal/atspi/text.go create mode 100644 internal/atspi/text_attributes.go create mode 100644 internal/atspi/text_boundary_test.go create mode 100644 internal/atspi/text_bounds_test.go create mode 100644 internal/atspi/text_component_test.go create mode 100644 internal/atspi/text_native.go create mode 100644 internal/atspi/text_test.go create mode 100644 internal/atspi/text_viewport.go create mode 100644 internal/atspi/text_viewport_test.go create mode 100644 internal/atspi/tree.go create mode 100644 internal/atspi/tree_test.go create mode 100644 internal/atspi/version.go create mode 100644 internal/atspi/version_test.go create mode 100644 internal/atspi/webscripts_native.go create mode 100644 internal/atspi/webscripts_native_test.go create mode 100644 internal/atspi/window_title_native_test.go create mode 100644 internal/braille/braille.go create mode 100644 internal/braille/braille_test.go create mode 100644 internal/braille/client.go create mode 100644 internal/braille/client_test.go create mode 100644 internal/braille/native.go create mode 100644 internal/braille/native_test.go create mode 100644 internal/braille/regions.go create mode 100644 internal/braille/regions_test.go create mode 100644 internal/braille/tables.go create mode 100644 internal/braille/tables_test.go create mode 100644 internal/braille/translate_native.go create mode 100644 internal/braille/translate_native_test.go create mode 100644 internal/braille/translate_unavailable.go create mode 100644 internal/braille/unavailable.go create mode 100644 internal/braille/unavailable_test.go create mode 100644 internal/clipboard/clipboard.go create mode 100644 internal/clipboard/clipboard_test.go create mode 100644 internal/clipboard/native.go create mode 100644 internal/clipboard/watch.c create mode 100644 internal/clipboard/watch.go create mode 100644 internal/clipboard/watch.h create mode 100644 internal/config/application_store_test.go create mode 100644 internal/config/bindings_test.go create mode 100644 internal/config/capitalization.go create mode 100644 internal/config/capitalization_test.go create mode 100644 internal/config/clipboard_test.go create mode 100644 internal/config/codec.go create mode 100644 internal/config/config.go create mode 100644 internal/config/config_test.go create mode 100644 internal/config/defaults.go create mode 100644 internal/config/greeter.go create mode 100644 internal/config/greeter_test.go create mode 100644 internal/config/hardware_test.go create mode 100644 internal/config/interruption_test.go create mode 100644 internal/config/legacy.go create mode 100644 internal/config/legacy_mapping.go create mode 100644 internal/config/ocr_test.go create mode 100644 internal/config/patch_contract_test.go create mode 100644 internal/config/phonetic_hints_test.go create mode 100644 internal/config/profile_mapping.go create mode 100644 internal/config/progress_test.go create mode 100644 internal/config/schema.go create mode 100644 internal/config/settings.go create mode 100644 internal/config/settings_copy.go create mode 100644 internal/config/store.go create mode 100644 internal/config/store_test.go create mode 100644 internal/config/testdata/settings-v1.toml create mode 100644 internal/config/testdata/settings-v2.toml create mode 100644 internal/config/testdata/settings-v3.toml create mode 100644 internal/config/text_preferences_test.go create mode 100644 internal/config/validation.go create mode 100644 internal/config/voices.go create mode 100644 internal/config/voices_test.go create mode 100644 internal/config/window_titles_test.go create mode 100644 internal/datetime/datetime.go create mode 100644 internal/input/bindings.go create mode 100644 internal/input/bindings_test.go create mode 100644 internal/input/clipboard_test.go create mode 100644 internal/input/commands.go create mode 100644 internal/input/commands_test.go create mode 100644 internal/input/current_line_test.go create mode 100644 internal/input/date_time_test.go create mode 100644 internal/input/document_lists.go create mode 100644 internal/input/document_lists_test.go create mode 100644 internal/input/document_test.go create mode 100644 internal/input/flat_review_test.go create mode 100644 internal/input/input.go create mode 100644 internal/input/input_test.go create mode 100644 internal/input/intent.go create mode 100644 internal/input/intent_test.go create mode 100644 internal/input/interruption.go create mode 100644 internal/input/interruption_test.go create mode 100644 internal/input/notification_commands_test.go create mode 100644 internal/input/ocr.go create mode 100644 internal/input/ocr_test.go create mode 100644 internal/input/read_all_test.go create mode 100644 internal/input/repeat.go create mode 100644 internal/input/repeat_test.go create mode 100644 internal/input/review_presses.go create mode 100644 internal/input/speech_history_test.go create mode 100644 internal/input/speech_mode_test.go create mode 100644 internal/input/sticky_test.go create mode 100644 internal/input/tentacle_bindings.go create mode 100644 internal/input/tentacle_bindings_test.go create mode 100644 internal/input/version_test.go create mode 100644 internal/input/window_title_test.go create mode 100644 internal/interaction/session.go create mode 100644 internal/interaction/session_test.go create mode 100644 internal/lifecycle/lifecycle.go create mode 100644 internal/lifecycle/lifecycle_test.go create mode 100644 internal/logging/async.go create mode 100644 internal/logging/async_test.go create mode 100644 internal/logging/logging.go create mode 100644 internal/logging/logging_test.go create mode 100644 internal/notification/mako.go create mode 100644 internal/notification/mako_test.go create mode 100644 internal/notification/presenter.go create mode 100644 internal/notification/presenter_test.go create mode 100644 internal/notificationui/native.c create mode 100644 internal/notificationui/native.h create mode 100644 internal/notificationui/protocol.go create mode 100644 internal/notificationui/ui.go create mode 100644 internal/nvda2cthulhu/messagepack.go create mode 100644 internal/nvda2cthulhu/messagepack_test.go create mode 100644 internal/nvda2cthulhu/protocol.go create mode 100644 internal/nvda2cthulhu/protocol_test.go create mode 100644 internal/nvda2cthulhu/server.go create mode 100644 internal/nvda2cthulhu/server_test.go create mode 100644 internal/ocr/capture.go create mode 100644 internal/ocr/capture_native_test.go create mode 100644 internal/ocr/capture_test.go create mode 100644 internal/ocr/cursor.go create mode 100644 internal/ocr/cursor_continuous_test.go create mode 100644 internal/ocr/cursor_test.go create mode 100644 internal/ocr/engine.go create mode 100644 internal/ocr/engine_test.go create mode 100644 internal/ocr/model.go create mode 100644 internal/ocr/model_test.go create mode 100644 internal/ocr/native_test.go create mode 100644 internal/ocr/page_test.go create mode 100644 internal/ocr/preprocess.go create mode 100644 internal/ocr/preprocess_test.go create mode 100644 internal/ocr/process.go create mode 100644 internal/ocr/testdata/painted-text.png create mode 100644 internal/ocr/tsv.go create mode 100644 internal/ocr/tsv_test.go create mode 100644 internal/ocrcapture/capture.go create mode 100644 internal/ocrcapture/native.c create mode 100644 internal/ocrcapture/native.h create mode 100644 internal/ocrconfirm/confirm.c create mode 100644 internal/ocrconfirm/confirm.go create mode 100644 internal/parity/parity.go create mode 100644 internal/parity/parity_test.go create mode 100644 internal/platform/session/session.go create mode 100644 internal/platform/session/session_test.go create mode 100644 internal/platform/wayland/keyboard.go create mode 100644 internal/platform/wayland/protocol.go create mode 100644 internal/platform/wayland/protocol_test.go create mode 100644 internal/platform/wayland/routing.go create mode 100644 internal/platform/wayland/routing_test.go create mode 100644 internal/platform/xorg/applications.go create mode 100644 internal/platform/xorg/clipboard.go create mode 100644 internal/platform/xorg/clipboard_native_test.go create mode 100644 internal/platform/xorg/commands.go create mode 100644 internal/platform/xorg/commands_bindings.go create mode 100644 internal/platform/xorg/commands_chord.go create mode 100644 internal/platform/xorg/commands_foreground.go create mode 100644 internal/platform/xorg/commands_native.c create mode 100644 internal/platform/xorg/commands_native.h create mode 100644 internal/platform/xorg/commands_ocr.go create mode 100644 internal/platform/xorg/commands_owner.go create mode 100644 internal/platform/xorg/commands_owner_loop.go create mode 100644 internal/platform/xorg/commands_security.go create mode 100644 internal/platform/xorg/commands_ui.go create mode 100644 internal/platform/xorg/foreground_pid.c create mode 100644 internal/platform/xorg/grab_foreground_native_test.go create mode 100644 internal/platform/xorg/listener.go create mode 100644 internal/platform/xorg/listener_native_test.go create mode 100644 internal/platform/xorg/locks_native_test.go create mode 100644 internal/platform/xorg/ocr_click.c create mode 100644 internal/platform/xorg/ocr_click.go create mode 100644 internal/platform/xorg/ocr_click_native_test.go create mode 100644 internal/platform/xorg/ocr_native_test.go create mode 100644 internal/platform/xorg/pointer.go create mode 100644 internal/platform/xorg/scroll_lock_native_test.go create mode 100644 internal/platform/xorg/steam_focus.c create mode 100644 internal/platform/xorg/steam_focus.go create mode 100644 internal/platform/xorg/steam_focus_native_test.go create mode 100644 internal/platform/xorg/steam_focus_test.go create mode 100644 internal/platform/xorg/tentacle_native_test.go create mode 100644 internal/platform/xorg/ui_native_test.go create mode 100644 internal/platform/xorg/window_title.c create mode 100644 internal/platform/xorg/window_title.go create mode 100644 internal/platform/xorg/window_title.h create mode 100644 internal/platform/xorg/window_title_native_test.go create mode 100644 internal/platform/xorg/xterm_handoff_native_test.go create mode 100644 internal/preferences/applications.go create mode 100644 internal/preferences/applications_test.go create mode 100644 internal/preferences/bindings.go create mode 100644 internal/preferences/braille.go create mode 100644 internal/preferences/catalog_protocol.go create mode 100644 internal/preferences/catalog_protocol_test.go create mode 100644 internal/preferences/catalog_voices.go create mode 100644 internal/preferences/echo.go create mode 100644 internal/preferences/extensions.go create mode 100644 internal/preferences/general.go create mode 100644 internal/preferences/interruption_test.go create mode 100644 internal/preferences/native.c create mode 100644 internal/preferences/native.h create mode 100644 internal/preferences/native_applications.c create mode 100644 internal/preferences/native_applications.h create mode 100644 internal/preferences/native_bindings.c create mode 100644 internal/preferences/native_extensions.c create mode 100644 internal/preferences/native_internal.h create mode 100644 internal/preferences/native_interruption.c create mode 100644 internal/preferences/native_reading.c create mode 100644 internal/preferences/native_tentacles.c create mode 100644 internal/preferences/native_text_attributes.c create mode 100644 internal/preferences/native_widgets.c create mode 100644 internal/preferences/ocr.go create mode 100644 internal/preferences/preferences.ui create mode 100644 internal/preferences/protocol.go create mode 100644 internal/preferences/protocol_test.go create mode 100644 internal/preferences/reading.go create mode 100644 internal/preferences/session.go create mode 100644 internal/preferences/sound.go create mode 100644 internal/preferences/speech.go create mode 100644 internal/preferences/tentacles.go create mode 100644 internal/preferences/tentacles_test.go create mode 100644 internal/preferences/text_attributes.go create mode 100644 internal/preferences/ui.go create mode 100644 internal/preferences/ui_values.go create mode 100644 internal/preferences/values.go create mode 100644 internal/preferences/widgets.go create mode 100644 internal/presentation/control_values.go create mode 100644 internal/presentation/control_values_test.go create mode 100644 internal/presentation/document_line.go create mode 100644 internal/presentation/document_line_test.go create mode 100644 internal/presentation/flat_review.go create mode 100644 internal/presentation/flat_review_test.go create mode 100644 internal/presentation/libreoffice.go create mode 100644 internal/presentation/libreoffice_selection.go create mode 100644 internal/presentation/libreoffice_selection_test.go create mode 100644 internal/presentation/libreoffice_test.go create mode 100644 internal/presentation/position_sound_test.go create mode 100644 internal/presentation/presentation.go create mode 100644 internal/presentation/presentation_test.go create mode 100644 internal/presentation/reading.go create mode 100644 internal/presentation/reading_test.go create mode 100644 internal/presentation/sound_cues.go create mode 100644 internal/presentation/sound_cues_test.go create mode 100644 internal/presentation/speech.go create mode 100644 internal/presentation/text_label_native_test.go create mode 100644 internal/presentation/typing_echo.go create mode 100644 internal/presentation/typing_echo_test.go create mode 100644 internal/remote/endpoint.go create mode 100644 internal/remote/endpoint_test.go create mode 100644 internal/remote/introspection.go create mode 100644 internal/remote/modules.go create mode 100644 internal/remote/modules_test.go create mode 100644 internal/remote/registrations.go create mode 100644 internal/remote/service.go create mode 100644 internal/remote/service_test.go create mode 100644 internal/remote/wine_review.go create mode 100644 internal/remote/wine_review_test.go create mode 100644 internal/review/current_line.go create mode 100644 internal/review/current_line_test.go create mode 100644 internal/review/cursor.go create mode 100644 internal/review/cursor_test.go create mode 100644 internal/review/document.go create mode 100644 internal/review/document_activation_test.go create mode 100644 internal/review/document_benchmark_test.go create mode 100644 internal/review/document_braille.go create mode 100644 internal/review/document_braille_routing.go create mode 100644 internal/review/document_braille_routing_test.go create mode 100644 internal/review/document_braille_test.go create mode 100644 internal/review/document_caret.go create mode 100644 internal/review/document_caret_editable_test.go create mode 100644 internal/review/document_caret_glyph_test.go create mode 100644 internal/review/document_caret_line.go create mode 100644 internal/review/document_caret_nodes.go create mode 100644 internal/review/document_caret_ranges.go create mode 100644 internal/review/document_caret_test.go create mode 100644 internal/review/document_caret_text.go create mode 100644 internal/review/document_diagnostics.go create mode 100644 internal/review/document_hypertext_test.go create mode 100644 internal/review/document_inline_replacement_test.go create mode 100644 internal/review/document_line_worker.go create mode 100644 internal/review/document_lists.go create mode 100644 internal/review/document_lists_test.go create mode 100644 internal/review/document_mode.go create mode 100644 internal/review/document_mode_test.go create mode 100644 internal/review/document_named_link.go create mode 100644 internal/review/document_native_caret.go create mode 100644 internal/review/document_native_caret_test.go create mode 100644 internal/review/document_navigation_reader.go create mode 100644 internal/review/document_navigation_test.go create mode 100644 internal/review/document_replacement.go create mode 100644 internal/review/document_replacement_test.go create mode 100644 internal/review/document_requests.go create mode 100644 internal/review/document_sound_test.go create mode 100644 internal/review/document_table.go create mode 100644 internal/review/document_table_test.go create mode 100644 internal/review/document_test.go create mode 100644 internal/review/document_tooltip_test.go create mode 100644 internal/review/document_visual_line.go create mode 100644 internal/review/document_visual_line_native_test.go create mode 100644 internal/review/document_visual_line_test.go create mode 100644 internal/review/document_word_spaces_test.go create mode 100644 internal/review/document_worker.go create mode 100644 internal/review/document_worker_test.go create mode 100644 internal/review/flat.go create mode 100644 internal/review/flat_browser_native_test.go create mode 100644 internal/review/flat_layout.go create mode 100644 internal/review/flat_native_test.go create mode 100644 internal/review/flat_pluma_native_test.go create mode 100644 internal/review/flat_robustness_test.go create mode 100644 internal/review/flat_test.go create mode 100644 internal/review/flat_worker.go create mode 100644 internal/review/flat_worker_test.go create mode 100644 internal/review/interest.go create mode 100644 internal/review/interest_test.go create mode 100644 internal/review/object_worker.go create mode 100644 internal/review/read_all.go create mode 100644 internal/review/read_all_test.go create mode 100644 internal/review/worker.go create mode 100644 internal/review/worker_contract.go create mode 100644 internal/review/worker_test.go create mode 100644 internal/sessionbus/sessionbus.go create mode 100644 internal/sessionbus/sessionbus_test.go create mode 100644 internal/shortcutui/native.c create mode 100644 internal/shortcutui/ui.go create mode 100644 internal/shortcutui/ui_native_test.go create mode 100644 internal/sound/indentation.go create mode 100644 internal/sound/indentation_test.go create mode 100644 internal/sound/player.go create mode 100644 internal/sound/position.go create mode 100644 internal/sound/position_test.go create mode 100644 internal/sound/progress.go create mode 100644 internal/sound/progress_test.go create mode 100644 internal/sound/service.go create mode 100644 internal/sound/service_test.go create mode 100644 internal/sound/speech_beep.go create mode 100644 internal/sound/speech_beep_test.go create mode 100644 internal/sound/tone.go create mode 100644 internal/sound/tone_test.go create mode 100644 internal/speech/address.go create mode 100644 internal/speech/address_test.go create mode 100644 internal/speech/autospawn.go create mode 100644 internal/speech/autospawn_test.go create mode 100644 internal/speech/catalog.go create mode 100644 internal/speech/catalog_test.go create mode 100644 internal/speech/defaults.go create mode 100644 internal/speech/defaults_test.go create mode 100644 internal/speech/hardware.go create mode 100644 internal/speech/hardware_test.go create mode 100644 internal/speech/locale_voices.go create mode 100644 internal/speech/read_all.go create mode 100644 internal/speech/read_all_test.go create mode 100644 internal/speech/serial_native.go create mode 100644 internal/speech/serial_native_test.go create mode 100644 internal/speech/serial_unavailable.go create mode 100644 internal/speech/settings_test.go create mode 100644 internal/speech/speech.go create mode 100644 internal/speech/speech_test.go create mode 100644 internal/speechhistoryui/native.c create mode 100644 internal/speechhistoryui/native.h create mode 100644 internal/speechhistoryui/ui.go create mode 100644 internal/tentacle/bindings.go create mode 100644 internal/tentacle/containment.go create mode 100644 internal/tentacle/containment_test.go create mode 100644 internal/tentacle/install.go create mode 100644 internal/tentacle/install_test.go create mode 100644 internal/tentacle/load_test.go create mode 100644 internal/tentacle/local.go create mode 100644 internal/tentacle/local_test.go create mode 100644 internal/tentacle/management.go create mode 100644 internal/tentacle/manager.go create mode 100644 internal/tentacle/page_store.go create mode 100644 internal/tentacle/page_store_test.go create mode 100644 internal/tentacle/process.go create mode 100644 internal/tentacle/protocol.go create mode 100644 internal/tentacle/protocol_test.go create mode 100644 internal/tentacle/reader_test.go create mode 100644 internal/tentacle/registry.go create mode 100644 internal/tentacle/registry_test.go create mode 100644 internal/tentacle/repository.go create mode 100644 internal/tentacle/repository_test.go create mode 100644 internal/tentacle/sdk_test.go create mode 100644 internal/tentacle/session.go create mode 100644 internal/tentacle/session_test.go create mode 100644 internal/tentacle/supervisor.go create mode 100644 internal/tentacle/supervisor_test.go create mode 100644 internal/tentacle/testdata/peer.py create mode 100644 internal/tentacle/testdata/resource_peer.py create mode 100644 internal/tentacle/testdata/sdk_peer.py create mode 100644 internal/tentacle/testdata/sdk_reader_peer.py create mode 100644 internal/tentaclewire/interaction.go create mode 100644 internal/tentaclewire/interaction_test.go create mode 100644 internal/tentaclewire/presentation.go create mode 100644 internal/tentaclewire/presentation_test.go create mode 100644 internal/tentaclewire/reader.go create mode 100644 internal/tentaclewire/reader_test.go create mode 100644 internal/tentaclewire/wire.go create mode 100644 internal/version/build.go create mode 100644 internal/version/build_test.go create mode 100644 internal/version/version.go create mode 100644 internal/version/version_test.go create mode 100644 internal/webscripts/registry.go create mode 100644 internal/webscripts/steam.go create mode 100644 internal/webscripts/steam_test.go create mode 100644 internal/wine/diagnostics.go create mode 100644 internal/wine/diagnostics_test.go create mode 100644 internal/wine/manager.go create mode 100644 internal/wine/manager_test.go create mode 100644 internal/wine/review_client.go create mode 100644 internal/wine/review_protocol.go create mode 100644 internal/wine/review_registry.go create mode 100644 internal/wine/review_registry_test.go create mode 100644 internal/wine/review_snapshot.go create mode 100644 internal/wine/review_snapshot_test.go create mode 100644 internal/wine/version.go create mode 100644 internal/wine/version_test.go delete mode 100644 meson.build delete mode 100644 meson_options.txt delete mode 100644 po/.gitignore delete mode 100644 po/ChangeLog delete mode 100644 po/LINGUAS delete mode 100644 po/Makevars delete mode 100644 po/POTFILES.in delete mode 100644 po/POTFILES.skip delete mode 100644 po/ab.po delete mode 100644 po/an.po delete mode 100644 po/ar.po delete mode 100644 po/ast.po delete mode 100644 po/be.po delete mode 100644 po/bg.po delete mode 100644 po/bn.po delete mode 100644 po/bn_IN.po delete mode 100644 po/bs.po delete mode 100644 po/ca.po delete mode 100644 po/ca@valencia.po delete mode 100644 po/ckb.po delete mode 100644 po/cs.po delete mode 100644 po/cy.po delete mode 100644 po/da.po delete mode 100644 po/de.po delete mode 100644 po/dz.po delete mode 100644 po/el.po delete mode 100644 po/en_CA.po delete mode 100644 po/en_GB.po delete mode 100644 po/eo.po delete mode 100644 po/es.po delete mode 100644 po/et.po delete mode 100644 po/eu.po delete mode 100644 po/fa.po delete mode 100644 po/fi.po delete mode 100644 po/fr.po delete mode 100644 po/fur.po delete mode 100644 po/ga.po delete mode 100644 po/gl.po delete mode 100644 po/gu.po delete mode 100644 po/he.po delete mode 100644 po/hi.po delete mode 100644 po/hr.po delete mode 100644 po/hu.po delete mode 100644 po/id.po delete mode 100644 po/is.po delete mode 100644 po/it.po delete mode 100644 po/ja.po delete mode 100644 po/ka.po delete mode 100644 po/kab.po delete mode 100644 po/kk.po delete mode 100644 po/kn.po delete mode 100644 po/ko.po delete mode 100644 po/lt.po delete mode 100644 po/lv.po delete mode 100644 po/mai.po delete mode 100644 po/meson.build delete mode 100644 po/mk.po delete mode 100644 po/ml.po delete mode 100644 po/mr.po delete mode 100644 po/ms.po delete mode 100644 po/nb.po delete mode 100644 po/ne.po delete mode 100644 po/nl.po delete mode 100644 po/nn.po delete mode 100644 po/oc.po delete mode 100644 po/or.po delete mode 100644 po/pa.po delete mode 100644 po/pl.po delete mode 100644 po/pt.po delete mode 100644 po/pt_BR.po delete mode 100644 po/ro.po delete mode 100644 po/ru.po delete mode 100644 po/rw.po delete mode 100644 po/si.po delete mode 100644 po/sk.po delete mode 100644 po/sl.po delete mode 100644 po/sq.po delete mode 100644 po/sr.po delete mode 100644 po/sr@latin.po delete mode 100644 po/sv.po delete mode 100644 po/ta.po delete mode 100644 po/te.po delete mode 100644 po/tg.po delete mode 100644 po/th.po delete mode 100644 po/tr.po delete mode 100644 po/ug.po delete mode 100644 po/uk.po delete mode 100644 po/vi.po delete mode 100644 po/zh_CN.po delete mode 100644 po/zh_HK.po delete mode 100644 po/zh_TW.po delete mode 100644 pyproject.toml delete mode 100644 scripts/build-wine-access.sh create mode 100644 sdk/go/tentacle/tentacle.go create mode 100644 sdk/python/cthulhu_tentacle/__init__.py delete mode 100755 set-version.sh delete mode 100644 sounds/meson.build delete mode 100644 src/cthulhu.py delete mode 100644 src/cthulhu/.gitignore delete mode 100644 src/cthulhu/__init__.py delete mode 100644 src/cthulhu/acss.py delete mode 100644 src/cthulhu/action_presenter.py delete mode 100644 src/cthulhu/ax_collection.py delete mode 100644 src/cthulhu/ax_component.py delete mode 100644 src/cthulhu/ax_document.py delete mode 100644 src/cthulhu/ax_document_selection.py delete mode 100644 src/cthulhu/ax_event_synthesizer.py delete mode 100644 src/cthulhu/ax_hypertext.py delete mode 100644 src/cthulhu/ax_object.py delete mode 100644 src/cthulhu/ax_selection.py delete mode 100644 src/cthulhu/ax_table.py delete mode 100644 src/cthulhu/ax_text.py delete mode 100644 src/cthulhu/ax_utilities.py delete mode 100644 src/cthulhu/ax_utilities.pyi delete mode 100644 src/cthulhu/ax_utilities_application.py delete mode 100644 src/cthulhu/ax_utilities_collection.py delete mode 100644 src/cthulhu/ax_utilities_debugging.py delete mode 100644 src/cthulhu/ax_utilities_event.py delete mode 100644 src/cthulhu/ax_utilities_relation.py delete mode 100644 src/cthulhu/ax_utilities_role.py delete mode 100644 src/cthulhu/ax_utilities_state.py delete mode 100644 src/cthulhu/ax_value.py delete mode 100644 src/cthulhu/backends/__init__.py delete mode 100644 src/cthulhu/backends/meson.build delete mode 100644 src/cthulhu/backends/toml_backend.py delete mode 100644 src/cthulhu/bookmarks.py delete mode 100644 src/cthulhu/braille.py delete mode 100644 src/cthulhu/braille_generator.py delete mode 100644 src/cthulhu/braille_rolenames.py delete mode 100644 src/cthulhu/brlmon.py delete mode 100644 src/cthulhu/brltablenames.py delete mode 100644 src/cthulhu/caret_navigation.py delete mode 100644 src/cthulhu/chat.py delete mode 100644 src/cthulhu/chnames.py delete mode 100644 src/cthulhu/cmdnames.py delete mode 100644 src/cthulhu/colornames.py delete mode 100644 src/cthulhu/common_keyboardmap.py delete mode 100644 src/cthulhu/compositor_state_adapter.py delete mode 100644 src/cthulhu/compositor_state_i3.py delete mode 100644 src/cthulhu/compositor_state_types.py delete mode 100644 src/cthulhu/compositor_state_wayland.py delete mode 100644 src/cthulhu/cthulhu-find.ui delete mode 100644 src/cthulhu/cthulhu-setup.ui delete mode 100644 src/cthulhu/cthulhu.py delete mode 100644 src/cthulhu/cthulhuVersion.py delete mode 100644 src/cthulhu/cthulhu_bin.py.in delete mode 100644 src/cthulhu/cthulhu_gtkbuilder.py delete mode 100644 src/cthulhu/cthulhu_gui_find.py delete mode 100644 src/cthulhu/cthulhu_gui_navlist.py delete mode 100644 src/cthulhu/cthulhu_gui_prefs.py delete mode 100644 src/cthulhu/cthulhu_gui_profile.py delete mode 100644 src/cthulhu/cthulhu_i18n.py.in delete mode 100644 src/cthulhu/cthulhu_modifier_manager.py delete mode 100644 src/cthulhu/cthulhu_platform.py.in delete mode 100644 src/cthulhu/cthulhu_state.py delete mode 100644 src/cthulhu/date_and_time_presenter.py delete mode 100644 src/cthulhu/dbus_service.py delete mode 100644 src/cthulhu/debug-2025-06-25-23:07:09.out delete mode 100644 src/cthulhu/debug.py delete mode 100644 src/cthulhu/desktop_keyboardmap.py delete mode 100644 src/cthulhu/dynamic_api_manager.py delete mode 100644 src/cthulhu/event_manager.py delete mode 100644 src/cthulhu/find.py delete mode 100644 src/cthulhu/flat_review.py delete mode 100644 src/cthulhu/flat_review_presenter.py delete mode 100644 src/cthulhu/focus_manager.py delete mode 100644 src/cthulhu/formatting.py delete mode 100644 src/cthulhu/generator.py delete mode 100644 src/cthulhu/gstreamer_support.py delete mode 100644 src/cthulhu/guilabels.py delete mode 100644 src/cthulhu/hardwarefactory.py delete mode 100644 src/cthulhu/highlighter.py delete mode 100644 src/cthulhu/input_event.py delete mode 100644 src/cthulhu/input_event_manager.py delete mode 100644 src/cthulhu/keybindings.py delete mode 100644 src/cthulhu/keynames.py delete mode 100644 src/cthulhu/label_inference.py delete mode 100644 src/cthulhu/laptop_keyboardmap.py delete mode 100644 src/cthulhu/learn_mode_presenter.py delete mode 100644 src/cthulhu/liveregions.py delete mode 100644 src/cthulhu/logger.py delete mode 100644 src/cthulhu/mako_notification_monitor.py delete mode 100644 src/cthulhu/mathsymbols.py delete mode 100644 src/cthulhu/meson.build delete mode 100644 src/cthulhu/messages.py delete mode 100644 src/cthulhu/mouse_review.py delete mode 100644 src/cthulhu/notification_presenter.py delete mode 100644 src/cthulhu/object_navigator.py delete mode 100644 src/cthulhu/object_properties.py delete mode 100644 src/cthulhu/phonnames.py delete mode 100644 src/cthulhu/piper_audio_player.py delete mode 100644 src/cthulhu/piper_voice_manager.py delete mode 100644 src/cthulhu/piperfactory.py delete mode 100644 src/cthulhu/plugin.py delete mode 100644 src/cthulhu/plugin_system_manager.py delete mode 100644 src/cthulhu/plugins/AIAssistant/__init__.py delete mode 100644 src/cthulhu/plugins/AIAssistant/ai_providers.py delete mode 100644 src/cthulhu/plugins/AIAssistant/meson.build delete mode 100644 src/cthulhu/plugins/AIAssistant/plugin.info delete mode 100644 src/cthulhu/plugins/AIAssistant/plugin.py delete mode 100644 src/cthulhu/plugins/ByeCthulhu/__init__.py delete mode 100644 src/cthulhu/plugins/ByeCthulhu/meson.build delete mode 100644 src/cthulhu/plugins/ByeCthulhu/plugin.info delete mode 100644 src/cthulhu/plugins/ByeCthulhu/plugin.py delete mode 100644 src/cthulhu/plugins/Clipboard/__init__.py delete mode 100644 src/cthulhu/plugins/Clipboard/meson.build delete mode 100644 src/cthulhu/plugins/Clipboard/plugin.info delete mode 100644 src/cthulhu/plugins/Clipboard/plugin.py delete mode 100644 src/cthulhu/plugins/CthulhuRemote/README.md delete mode 100644 src/cthulhu/plugins/CthulhuRemote/__init__.py delete mode 100644 src/cthulhu/plugins/CthulhuRemote/connection_info.py delete mode 100644 src/cthulhu/plugins/CthulhuRemote/local_machine.py delete mode 100644 src/cthulhu/plugins/CthulhuRemote/meson.build delete mode 100644 src/cthulhu/plugins/CthulhuRemote/plugin.info delete mode 100644 src/cthulhu/plugins/CthulhuRemote/plugin.py delete mode 100644 src/cthulhu/plugins/CthulhuRemote/protocol.py delete mode 100644 src/cthulhu/plugins/CthulhuRemote/serializer.py delete mode 100644 src/cthulhu/plugins/CthulhuRemote/socket_utils.py delete mode 100644 src/cthulhu/plugins/CthulhuRemote/transport.py delete mode 100644 src/cthulhu/plugins/DisplayVersion/__init__.py delete mode 100644 src/cthulhu/plugins/DisplayVersion/meson.build delete mode 100644 src/cthulhu/plugins/DisplayVersion/plugin.info delete mode 100644 src/cthulhu/plugins/DisplayVersion/plugin.py delete mode 100644 src/cthulhu/plugins/GameMode/__init__.py delete mode 100644 src/cthulhu/plugins/GameMode/meson.build delete mode 100644 src/cthulhu/plugins/GameMode/plugin.info delete mode 100644 src/cthulhu/plugins/GameMode/plugin.py delete mode 100644 src/cthulhu/plugins/HelloCthulhu/__init__.py delete mode 100644 src/cthulhu/plugins/HelloCthulhu/meson.build delete mode 100644 src/cthulhu/plugins/HelloCthulhu/plugin.info delete mode 100644 src/cthulhu/plugins/HelloCthulhu/plugin.py delete mode 100644 src/cthulhu/plugins/OCR/README.md delete mode 100644 src/cthulhu/plugins/OCR/__init__.py delete mode 100644 src/cthulhu/plugins/OCR/meson.build delete mode 100644 src/cthulhu/plugins/OCR/plugin.info delete mode 100644 src/cthulhu/plugins/OCR/plugin.py delete mode 100644 src/cthulhu/plugins/SSIPProxy/__init__.py delete mode 100644 src/cthulhu/plugins/SSIPProxy/meson.build delete mode 100644 src/cthulhu/plugins/SSIPProxy/plugin.info delete mode 100644 src/cthulhu/plugins/SSIPProxy/plugin.py delete mode 100644 src/cthulhu/plugins/SimplePluginSystem/__init__.py delete mode 100644 src/cthulhu/plugins/SimplePluginSystem/meson.build delete mode 100644 src/cthulhu/plugins/SimplePluginSystem/plugin.info delete mode 100644 src/cthulhu/plugins/SimplePluginSystem/plugin.py delete mode 100644 src/cthulhu/plugins/SpeechHistory/__init__.py delete mode 100644 src/cthulhu/plugins/SpeechHistory/meson.build delete mode 100644 src/cthulhu/plugins/SpeechHistory/plugin.info delete mode 100644 src/cthulhu/plugins/SpeechHistory/plugin.py delete mode 100644 src/cthulhu/plugins/WindowTitleReader/__init__.py delete mode 100644 src/cthulhu/plugins/WindowTitleReader/meson.build delete mode 100644 src/cthulhu/plugins/WindowTitleReader/plugin.info delete mode 100644 src/cthulhu/plugins/WindowTitleReader/plugin.py delete mode 100644 src/cthulhu/plugins/WineAccessibility/__init__.py delete mode 100644 src/cthulhu/plugins/WineAccessibility/meson.build delete mode 100644 src/cthulhu/plugins/WineAccessibility/plugin.info delete mode 100644 src/cthulhu/plugins/WineAccessibility/plugin.py delete mode 100644 src/cthulhu/plugins/hello_world/README.md delete mode 100644 src/cthulhu/plugins/hello_world/__init__.py delete mode 100644 src/cthulhu/plugins/hello_world/meson.build delete mode 100644 src/cthulhu/plugins/hello_world/plugin.info delete mode 100644 src/cthulhu/plugins/hello_world/plugin.py delete mode 100644 src/cthulhu/plugins/meson.build delete mode 100644 src/cthulhu/plugins/nvda2cthulhu/README.md delete mode 100644 src/cthulhu/plugins/nvda2cthulhu/__init__.py delete mode 100644 src/cthulhu/plugins/nvda2cthulhu/meson.build delete mode 100644 src/cthulhu/plugins/nvda2cthulhu/plugin.info delete mode 100644 src/cthulhu/plugins/nvda2cthulhu/plugin.py delete mode 100644 src/cthulhu/plugins/self_voice/__init__.py delete mode 100644 src/cthulhu/plugins/self_voice/meson.build delete mode 100644 src/cthulhu/plugins/self_voice/plugin.info delete mode 100644 src/cthulhu/plugins/self_voice/plugin.py delete mode 100644 src/cthulhu/pronunciation_dict.py delete mode 100644 src/cthulhu/punctuation_settings.py delete mode 100644 src/cthulhu/resource_manager.py delete mode 100644 src/cthulhu/role_keys.py delete mode 100644 src/cthulhu/screen_lock_monitor.py delete mode 100644 src/cthulhu/script.py delete mode 100644 src/cthulhu/script_manager.py delete mode 100644 src/cthulhu/script_utilities.py delete mode 100644 src/cthulhu/scripts/__init__.py delete mode 100644 src/cthulhu/scripts/apps/Banshee/__init__.py delete mode 100644 src/cthulhu/scripts/apps/Banshee/meson.build delete mode 100644 src/cthulhu/scripts/apps/Banshee/script.py delete mode 100644 src/cthulhu/scripts/apps/Banshee/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/Eclipse/__init__.py delete mode 100644 src/cthulhu/scripts/apps/Eclipse/meson.build delete mode 100644 src/cthulhu/scripts/apps/Eclipse/script.py delete mode 100644 src/cthulhu/scripts/apps/Mumble/__init__.py delete mode 100644 src/cthulhu/scripts/apps/Mumble/chat.py delete mode 100644 src/cthulhu/scripts/apps/Mumble/meson.build delete mode 100644 src/cthulhu/scripts/apps/Mumble/script.py delete mode 100644 src/cthulhu/scripts/apps/Mumble/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/SeaMonkey/__init__.py delete mode 100644 src/cthulhu/scripts/apps/SeaMonkey/meson.build delete mode 100644 src/cthulhu/scripts/apps/SeaMonkey/script.py delete mode 100644 src/cthulhu/scripts/apps/Thunderbird/__init__.py delete mode 100644 src/cthulhu/scripts/apps/Thunderbird/meson.build delete mode 100644 src/cthulhu/scripts/apps/Thunderbird/script.py delete mode 100644 src/cthulhu/scripts/apps/Thunderbird/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/Thunderbird/spellcheck.py delete mode 100644 src/cthulhu/scripts/apps/__init__.py delete mode 100644 src/cthulhu/scripts/apps/epiphany/__init__.py delete mode 100644 src/cthulhu/scripts/apps/epiphany/meson.build delete mode 100644 src/cthulhu/scripts/apps/epiphany/script.py delete mode 100644 src/cthulhu/scripts/apps/evince/__init__.py delete mode 100644 src/cthulhu/scripts/apps/evince/meson.build delete mode 100644 src/cthulhu/scripts/apps/evince/script.py delete mode 100644 src/cthulhu/scripts/apps/evolution/__init__.py delete mode 100644 src/cthulhu/scripts/apps/evolution/braille_generator.py delete mode 100644 src/cthulhu/scripts/apps/evolution/meson.build delete mode 100644 src/cthulhu/scripts/apps/evolution/script.py delete mode 100644 src/cthulhu/scripts/apps/evolution/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/evolution/speech_generator.py delete mode 100644 src/cthulhu/scripts/apps/gajim/__init__.py delete mode 100644 src/cthulhu/scripts/apps/gajim/meson.build delete mode 100644 src/cthulhu/scripts/apps/gajim/script.py delete mode 100644 src/cthulhu/scripts/apps/gcalctool/__init__.py delete mode 100644 src/cthulhu/scripts/apps/gcalctool/meson.build delete mode 100644 src/cthulhu/scripts/apps/gcalctool/script.py delete mode 100644 src/cthulhu/scripts/apps/gedit/__init__.py delete mode 100644 src/cthulhu/scripts/apps/gedit/meson.build delete mode 100644 src/cthulhu/scripts/apps/gedit/script.py delete mode 100644 src/cthulhu/scripts/apps/gedit/spellcheck.py delete mode 100644 src/cthulhu/scripts/apps/gnome-documents/__init__.py delete mode 100644 src/cthulhu/scripts/apps/gnome-documents/meson.build delete mode 100644 src/cthulhu/scripts/apps/gnome-documents/script.py delete mode 100644 src/cthulhu/scripts/apps/gnome-documents/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/gnome-documents/speech_generator.py delete mode 100644 src/cthulhu/scripts/apps/gnome-shell/__init__.py delete mode 100644 src/cthulhu/scripts/apps/gnome-shell/formatting.py delete mode 100644 src/cthulhu/scripts/apps/gnome-shell/meson.build delete mode 100644 src/cthulhu/scripts/apps/gnome-shell/script.py delete mode 100644 src/cthulhu/scripts/apps/gnome-shell/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/kwin/__init__.py delete mode 100644 src/cthulhu/scripts/apps/kwin/meson.build delete mode 100644 src/cthulhu/scripts/apps/kwin/script.py delete mode 100644 src/cthulhu/scripts/apps/kwin/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/meson.build delete mode 100644 src/cthulhu/scripts/apps/notification-daemon/__init__.py delete mode 100644 src/cthulhu/scripts/apps/notification-daemon/meson.build delete mode 100644 src/cthulhu/scripts/apps/notification-daemon/script.py delete mode 100644 src/cthulhu/scripts/apps/notify-osd/__init__.py delete mode 100644 src/cthulhu/scripts/apps/notify-osd/meson.build delete mode 100644 src/cthulhu/scripts/apps/notify-osd/script.py delete mode 100644 src/cthulhu/scripts/apps/pidgin/__init__.py delete mode 100644 src/cthulhu/scripts/apps/pidgin/chat.py delete mode 100644 src/cthulhu/scripts/apps/pidgin/meson.build delete mode 100644 src/cthulhu/scripts/apps/pidgin/script.py delete mode 100644 src/cthulhu/scripts/apps/pidgin/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/pidgin/speech_generator.py delete mode 100644 src/cthulhu/scripts/apps/smuxi-frontend-gnome/__init__.py delete mode 100644 src/cthulhu/scripts/apps/smuxi-frontend-gnome/chat.py delete mode 100644 src/cthulhu/scripts/apps/smuxi-frontend-gnome/meson.build delete mode 100644 src/cthulhu/scripts/apps/smuxi-frontend-gnome/script.py delete mode 100644 src/cthulhu/scripts/apps/soffice/__init__.py delete mode 100644 src/cthulhu/scripts/apps/soffice/braille_generator.py delete mode 100644 src/cthulhu/scripts/apps/soffice/formatting.py delete mode 100644 src/cthulhu/scripts/apps/soffice/meson.build delete mode 100644 src/cthulhu/scripts/apps/soffice/script.py delete mode 100644 src/cthulhu/scripts/apps/soffice/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/soffice/speech_generator.py delete mode 100644 src/cthulhu/scripts/apps/soffice/spellcheck.py delete mode 100644 src/cthulhu/scripts/apps/steamwebhelper/__init__.py delete mode 100644 src/cthulhu/scripts/apps/steamwebhelper/meson.build delete mode 100644 src/cthulhu/scripts/apps/steamwebhelper/script.py delete mode 100644 src/cthulhu/scripts/apps/steamwebhelper/script_utilities.py delete mode 100644 src/cthulhu/scripts/apps/xfwm4/__init__.py delete mode 100644 src/cthulhu/scripts/apps/xfwm4/meson.build delete mode 100644 src/cthulhu/scripts/apps/xfwm4/script.py delete mode 100644 src/cthulhu/scripts/default.py delete mode 100644 src/cthulhu/scripts/meson.build delete mode 100644 src/cthulhu/scripts/self_voicing.py delete mode 100644 src/cthulhu/scripts/sleepmode/__init__.py delete mode 100644 src/cthulhu/scripts/sleepmode/braille_generator.py delete mode 100644 src/cthulhu/scripts/sleepmode/meson.build delete mode 100644 src/cthulhu/scripts/sleepmode/script.py delete mode 100644 src/cthulhu/scripts/sleepmode/script_utilities.py delete mode 100644 src/cthulhu/scripts/sleepmode/speech_generator.py delete mode 100644 src/cthulhu/scripts/switcher/__init__.py delete mode 100644 src/cthulhu/scripts/switcher/meson.build delete mode 100644 src/cthulhu/scripts/switcher/script.py delete mode 100644 src/cthulhu/scripts/switcher/script_utilities.py delete mode 100644 src/cthulhu/scripts/terminal/__init__.py delete mode 100644 src/cthulhu/scripts/terminal/braille_generator.py delete mode 100644 src/cthulhu/scripts/terminal/meson.build delete mode 100644 src/cthulhu/scripts/terminal/script.py delete mode 100644 src/cthulhu/scripts/terminal/script_utilities.py delete mode 100644 src/cthulhu/scripts/terminal/speech_generator.py delete mode 100644 src/cthulhu/scripts/toolkits/Chromium/__init__.py delete mode 100644 src/cthulhu/scripts/toolkits/Chromium/braille_generator.py delete mode 100644 src/cthulhu/scripts/toolkits/Chromium/meson.build delete mode 100644 src/cthulhu/scripts/toolkits/Chromium/script.py delete mode 100644 src/cthulhu/scripts/toolkits/Chromium/script_utilities.py delete mode 100644 src/cthulhu/scripts/toolkits/Chromium/speech_generator.py delete mode 100644 src/cthulhu/scripts/toolkits/GAIL/__init__.py delete mode 100644 src/cthulhu/scripts/toolkits/GAIL/meson.build delete mode 100644 src/cthulhu/scripts/toolkits/GAIL/script.py delete mode 100644 src/cthulhu/scripts/toolkits/GAIL/script_utilities.py delete mode 100644 src/cthulhu/scripts/toolkits/Gecko/__init__.py delete mode 100644 src/cthulhu/scripts/toolkits/Gecko/meson.build delete mode 100644 src/cthulhu/scripts/toolkits/Gecko/script.py delete mode 100644 src/cthulhu/scripts/toolkits/Gecko/script_utilities.py delete mode 100644 src/cthulhu/scripts/toolkits/J2SE-access-bridge/__init__.py delete mode 100644 src/cthulhu/scripts/toolkits/J2SE-access-bridge/formatting.py delete mode 100644 src/cthulhu/scripts/toolkits/J2SE-access-bridge/meson.build delete mode 100644 src/cthulhu/scripts/toolkits/J2SE-access-bridge/script.py delete mode 100644 src/cthulhu/scripts/toolkits/J2SE-access-bridge/script_utilities.py delete mode 100644 src/cthulhu/scripts/toolkits/J2SE-access-bridge/speech_generator.py delete mode 100644 src/cthulhu/scripts/toolkits/Qt/__init__.py delete mode 100644 src/cthulhu/scripts/toolkits/Qt/meson.build delete mode 100644 src/cthulhu/scripts/toolkits/Qt/script.py delete mode 100644 src/cthulhu/scripts/toolkits/Qt/script_utilities.py delete mode 100644 src/cthulhu/scripts/toolkits/VCL.py delete mode 100644 src/cthulhu/scripts/toolkits/WebKitGtk/__init__.py delete mode 100644 src/cthulhu/scripts/toolkits/WebKitGtk/braille_generator.py delete mode 100644 src/cthulhu/scripts/toolkits/WebKitGtk/meson.build delete mode 100644 src/cthulhu/scripts/toolkits/WebKitGtk/script.py delete mode 100644 src/cthulhu/scripts/toolkits/WebKitGtk/script_utilities.py delete mode 100644 src/cthulhu/scripts/toolkits/WebKitGtk/speech_generator.py delete mode 100644 src/cthulhu/scripts/toolkits/__init__.py delete mode 100644 src/cthulhu/scripts/toolkits/clutter/__init__.py delete mode 100644 src/cthulhu/scripts/toolkits/clutter/meson.build delete mode 100644 src/cthulhu/scripts/toolkits/clutter/script.py delete mode 100644 src/cthulhu/scripts/toolkits/clutter/script_utilities.py delete mode 100644 src/cthulhu/scripts/toolkits/gtk/__init__.py delete mode 100644 src/cthulhu/scripts/toolkits/gtk/meson.build delete mode 100644 src/cthulhu/scripts/toolkits/gtk/script.py delete mode 100644 src/cthulhu/scripts/toolkits/gtk/script_utilities.py delete mode 100644 src/cthulhu/scripts/toolkits/meson.build delete mode 100644 src/cthulhu/scripts/web/__init__.py delete mode 100644 src/cthulhu/scripts/web/bookmarks.py delete mode 100644 src/cthulhu/scripts/web/braille_generator.py delete mode 100644 src/cthulhu/scripts/web/event_router.py delete mode 100644 src/cthulhu/scripts/web/meson.build delete mode 100644 src/cthulhu/scripts/web/script.py delete mode 100644 src/cthulhu/scripts/web/script_utilities.py delete mode 100644 src/cthulhu/scripts/web/sound_generator.py delete mode 100644 src/cthulhu/scripts/web/speech_generator.py delete mode 100644 src/cthulhu/scripts/web/tutorial_generator.py delete mode 100644 src/cthulhu/settings.py delete mode 100644 src/cthulhu/settings_manager.py delete mode 100644 src/cthulhu/signal_manager.py delete mode 100644 src/cthulhu/sleep_mode_manager.py delete mode 100644 src/cthulhu/sound.py delete mode 100644 src/cthulhu/sound_generator.py delete mode 100644 src/cthulhu/sound_helper.py delete mode 100644 src/cthulhu/sound_sink.py delete mode 100644 src/cthulhu/sound_theme_manager.py delete mode 100644 src/cthulhu/speech.py delete mode 100644 src/cthulhu/speech_and_verbosity_manager.py delete mode 100644 src/cthulhu/speech_generator.py delete mode 100644 src/cthulhu/speech_history.py delete mode 100644 src/cthulhu/speechdispatcherfactory.py delete mode 100644 src/cthulhu/speechserver.py delete mode 100644 src/cthulhu/spellcheck.py delete mode 100644 src/cthulhu/structural_navigation.py delete mode 100644 src/cthulhu/text_attribute_names.py delete mode 100644 src/cthulhu/translation_context.py delete mode 100644 src/cthulhu/translation_manager.py delete mode 100644 src/cthulhu/tutorialgenerator.py delete mode 100644 src/cthulhu/typing_echo_presenter.py delete mode 100644 src/cthulhu/wayland_protocols/__init__.py delete mode 100644 src/cthulhu/wayland_protocols/ext_workspace_v1.py delete mode 100644 src/cthulhu/wayland_protocols/meson.build delete mode 100644 src/cthulhu/where_am_i_presenter.py delete mode 100644 src/cthulhu/wine_access_manager.py delete mode 100644 src/cthulhu/wnck_support.py delete mode 100644 src/louis/.gitignore delete mode 100644 src/meson.build delete mode 100755 test-local.sh create mode 100644 testdata/parity-ledger.csv create mode 100644 tests/browser-catalog.html create mode 100644 tests/browser-changing.html create mode 100644 tests/browser-editor.html create mode 100644 tests/browser-fragments.html create mode 100644 tests/browser-lines.html create mode 100644 tests/browser-linked-headings.html create mode 100644 tests/browser-lists.html create mode 100644 tests/browser-live.html create mode 100644 tests/browser-named-links.html create mode 100644 tests/browser-next.html create mode 100644 tests/browser-positions.html create mode 100644 tests/browser-progress.html create mode 100644 tests/browser-replaced-feed.html create mode 100644 tests/browser.html create mode 100755 tests/check_speech.py delete mode 100644 tests/conftest.py create mode 100644 tests/current_line_fixture.py create mode 100644 tests/firefox-baseline.html create mode 100644 tests/gtk_alert.py create mode 100644 tests/gtk_background_events.py create mode 100644 tests/gtk_edit_labels.py create mode 100644 tests/gtk_progress.py create mode 100644 tests/gtk_radio_group.py create mode 100644 tests/gtk_selection.py create mode 100644 tests/gtk_table.py create mode 100644 tests/gtk_tree.py create mode 100644 tests/gtk_web_notification.py create mode 100644 tests/libreoffice.fods create mode 100644 tests/native_alert.py create mode 100644 tests/native_atspi.py create mode 100644 tests/native_browser.py create mode 100644 tests/native_browser_navigation.py create mode 100644 tests/native_clipboard_preferences.py create mode 100644 tests/native_echo_preview.py create mode 100644 tests/native_firefox.py create mode 100644 tests/native_internal_ui.py create mode 100644 tests/native_libreoffice.py create mode 100644 tests/native_mozilla.py create mode 100755 tests/native_notifications.py create mode 100644 tests/native_ownership.py create mode 100644 tests/native_preferences.py create mode 100644 tests/native_progress.py create mode 100644 tests/native_qt_controls.py create mode 100644 tests/native_speech_defaults.py create mode 100644 tests/native_speech_history.py create mode 100644 tests/native_tentacle_extensions.py create mode 100644 tests/native_tentacle_settings.py create mode 100644 tests/native_terminal.py create mode 100644 tests/native_test_session.py create mode 100644 tests/native_thunderbird.py create mode 100644 tests/native_webscripts.py create mode 100644 tests/native_x11.py create mode 100644 tests/ocr_capture_fixture.py create mode 100644 tests/ocr_click_fixture.py create mode 100644 tests/ocr_geometry_fixture.py create mode 100644 tests/ocr_review_fixture.py create mode 100644 tests/ocr_session_fixture.py create mode 100644 tests/review_cache_fixture.c create mode 100644 tests/run-delegated-reader.sh create mode 100644 tests/steam_big_picture_log.py create mode 100644 tests/steam_focus_fixture.py delete mode 100644 tests/test_arch_pkgbuild_optional_wine.py delete mode 100644 tests/test_bye_cthulhu_regressions.py delete mode 100644 tests/test_chromium_omnibox_regressions.py delete mode 100644 tests/test_compositor_state_adapter_regressions.py delete mode 100644 tests/test_compositor_state_i3_regressions.py delete mode 100644 tests/test_cthulhu_remote_plugin.py delete mode 100644 tests/test_dbus_service_native_interfaces.py delete mode 100644 tests/test_debug_startup_timing.py delete mode 100644 tests/test_default_script_clipboard_regressions.py delete mode 100644 tests/test_default_script_shutdown_regressions.py delete mode 100644 tests/test_document_selection_regressions.py delete mode 100644 tests/test_event_manager_compositor_context_regressions.py delete mode 100644 tests/test_event_manager_relevance_gate_regressions.py delete mode 100644 tests/test_event_manager_xterm_handoff_regressions.py delete mode 100644 tests/test_hardwarefactory_regressions.py delete mode 100644 tests/test_input_event_manager_key_watcher_regressions.py delete mode 100644 tests/test_input_event_manager_x11_focus_regressions.py delete mode 100644 tests/test_input_event_regressions.py delete mode 100644 tests/test_learn_mode_regressions.py delete mode 100644 tests/test_link_sound_regressions.py delete mode 100644 tests/test_mako_notification_monitor.py delete mode 100644 tests/test_mouse_review_pointer_monitor_regressions.py create mode 100644 tests/test_native_test_session.py delete mode 100644 tests/test_notification_daemon_regressions.py delete mode 100644 tests/test_notification_presenter_mako_regressions.py delete mode 100644 tests/test_nvda2cthulhu_regressions.py delete mode 100644 tests/test_piperfactory_rate_mapping.py delete mode 100644 tests/test_plugin_preferences_regressions.py delete mode 100644 tests/test_plugin_system_manager_regressions.py create mode 100644 tests/test_preferences_responses.py delete mode 100644 tests/test_presentation_interrupt_sound_regressions.py delete mode 100644 tests/test_runtime_state_snapshot.py delete mode 100644 tests/test_screen_lock_monitor.py delete mode 100644 tests/test_script_utilities_regressions.py delete mode 100644 tests/test_self_voice_plugin_regressions.py delete mode 100644 tests/test_sound_helper_backend.py delete mode 100644 tests/test_sound_preferences_regressions.py delete mode 100644 tests/test_sound_recovery.py delete mode 100644 tests/test_speech_default_policy_regressions.py delete mode 100644 tests/test_speechdispatcher_interrupt_regressions.py delete mode 100644 tests/test_speechdispatcher_voice_selection_regressions.py delete mode 100644 tests/test_steam_notification_regressions.py delete mode 100644 tests/test_steam_selection_regressions.py delete mode 100644 tests/test_structural_navigation_table_regressions.py delete mode 100644 tests/test_toml_backend_legacy_schema_regressions.py delete mode 100644 tests/test_web_event_router_contract.py delete mode 100644 tests/test_web_event_sequences.py delete mode 100644 tests/test_web_input_regressions.py delete mode 100644 tests/test_web_layout_mode_regressions.py delete mode 100644 tests/test_web_router_regressions.py delete mode 100644 tests/test_window_title_fallback_regressions.py delete mode 100644 tests/test_wine_access_controller_contract.py delete mode 100644 tests/test_wine_access_manager.py delete mode 100644 tests/test_wnck_session_regressions.py create mode 100644 tests/text-preferences.html create mode 100644 tests/text_label_fixture.py create mode 100644 tests/vte_terminal.py create mode 100644 tests/window_title_fixture.py create mode 100644 tests/window_titles.md create mode 100644 tests/wine_review_x11.py create mode 100644 tests/x11_focus_child.py create mode 100644 tests/x11_grab_fixture.py create mode 100644 tests/xorg_suspension_probe.c delete mode 100755 tools/generate_dbus_documentation.py delete mode 100644 wine-access/CMakeLists.txt delete mode 100644 wine-access/main.cpp delete mode 100644 wine-access/nvdaController.idl delete mode 100644 wine-access/winelib-toolchain.cmake diff --git a/.gitignore b/.gitignore index 0bbd067..ba3f744 100644 --- a/.gitignore +++ b/.gitignore @@ -1,110 +1,16 @@ -# Meson build artifacts -_build/ -builddir/ +.cache/ build/ - -# Legacy autotools artifacts (if any remain) -ABOUT-NLS -INSTALL -aclocal.m4 -autom4te.cache -compile -config.h -config.h.in -config.guess -config.log -config.rpath -config.status -config.sub -configure -debug.out -depcomp -install-sh -intltool-extract.in -intltool-extract -intltool-merge.in -intltool-merge -intltool-update.in -intltool-update -libtool -ltmain.sh -missing -mkinstalldirs -omf.make -orca-autostart.desktop -orca.desktop -orca.spec -py-compile -stamp-h1 -xmldocs.make -core -bld -*~ -patch.* -[0-9][0-9][0-9][0-9][-]* - -# Generated Python files -src/cthulhu/cthulhu_bin.py -src/cthulhu/cthulhu_i18n.py -src/cthulhu/cthulhu_platform.py - -# Python bytecode -*.pyc -*.pyo +dist/ +coverage.out +/cthulhu +/cthulhu-braille +/parityledger __pycache__/ - -# Editor backup files -*~ -*.bak -*.swp -*.tmp -*.orig -*.rej - -# AT-SPI test/debug files -debug*.log -debug*.out - -# Local build directory and artifacts -local-build/ -debug-*.out -debug.log -*.gmo -*.pot - -# Package artifacts -*.pkg.tar.* -distro-packages/**/.SRCINFO -distro-packages/**/*.log -distro-packages/*/*/cthulhu/ -distro-packages/*/*/cthulhu-git/ -distro-packages/*/*/pkg/ -distro-packages/*/*/src/ - -# Generated makefiles (should not be committed) -Makefile -Makefile.in - -# Sound files (if binary) -sounds/ - -# Test files that might be temporary -test-dbus.sh -test-local-meson.sh -test_displayversion.py -PORTING-NOTES.md - -# Translation files -po/stamp-po -po/insert-header.sed - -# /help -/help/*.omf -/help/*/*.page -!/help/C/*.page -/help/*/*.xml -!/help/C/*.xml -/help/*/*.mo -/help/*/*.stamp -.aider* -.worktrees/ +*.py[cod] +.aider.tags.cache.*/ +.pytest_cache/ +/.codex +/distro-packages/**/*.log +/distro-packages/**/*.pkg.tar.zst +/distro-packages/**/*.pkg.tar.xz +/distro-packages/Arch-Linux/cthulhu-git/*/ diff --git a/AGENTS.md b/AGENTS.md index 54c782e..b19401e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,136 +1,57 @@ -# AGENTS.md (Codex CLI guidance) +# Repository Guidelines -This repository is a screen reader. Prioritize accessibility, correctness, and stability over “clever” changes. +## CRITICAL: Init-System Independence -## System interactions -- If a command requires `sudo`, stop and ask the user to run it (no password entry is possible from here). +Cthulhu must never depend on a specific Linux init system or service manager. This applies to the reader, Tentacles, process supervision, installation, packaging, and required tests. Do not require systemd, `systemd-run`, `systemctl`, or a systemd user manager. Use init-independent Linux interfaces and detect the capabilities actually available. Cthulhu and its Tentacles must work on non-systemd distributions, including Artix. -## Build / run quick refs -- Local dev build + install: `./build-local.sh` -- Quick local sanity checks: `./test-local.sh` -- Clean local artifacts/install: `./clean-local.sh` -- Meson (manual): - - `meson setup _build --prefix=$HOME/.local` - - `meson compile -C _build` - - `meson install -C _build` +## Before Starting a Fix or Feature -## Runtime target and testing rules -- Make source changes in this repo, not in `~/.local/lib/python*/site-packages/cthulhu/`, unless the user explicitly asks for an installed-package hotfix. -- If you confirm the active import comes from `~/.local/...`, that does **not** mean you should edit there. It means you should update the repo and then run `./build-local.sh` to replace the installed copy for testing. -- Default test/apply workflow for local Cthulhu fixes: - - edit repo files - - run `./build-local.sh` - - reproduce/test against the refreshed `~/.local` install -- If repo and installed behavior differ, prefer rebuilding with `./build-local.sh` over patching the installed package directly. -- Treat direct edits under `~/.local/.../cthulhu/` as an exception path that requires explicit user approval. +Inspect `git status --short --branch`, confirm the intended branch and upstream, and complete `git pull --ff-only` before starting implementation. If local and upstream commits have diverged, resolve that divergence with a normal merge before proceeding; never discard local work to make the pull succeed. If a merge or rebase is already in progress, finish it first. Preserve uncommitted changes and diagnostic files; do not automatically stash, reset, or clean them. -## Bug intake -- Assume reporters may have little or no development experience. Ask for user-visible steps and guide them through logs or diagnostic commands without expecting them to identify the subsystem or use technical terminology. -- Capture the application or browser, page URL when relevant, desktop/session type, exact steps, expected result, actual result, and whether the problem is reproducible elsewhere. -- Separate keyboard focus from speech output: ask whether focus fails to move, moves but is not announced, or is reachable through another navigation method. -- For web issues, determine whether the behavior is site-specific, browser-specific, or reproducible across similar controls before changing code. -- When a log is needed, guide the reporter through launching the locally installed build with `~/.local/bin/cthulhu --debug-file /tmp/cthulhu.log --debug`, reproducing the problem once, exiting Cthulhu, and providing `/tmp/cthulhu.log` for review. -- If a reporter still sees the same problem after a fix, verify that the refreshed build is actually installed and running before assuming the patch failed. Guide the reporter through the check rather than assuming they know how the local install works. +On every branch other than `testing` or `master`, also fetch the maintained repository's latest `testing` branch and merge it into the working branch. With the maintained repository configured as `origin`, use `git fetch origin` followed by `git merge origin/testing`. Resolve conflicts, run the relevant checks, and finish any merge commit before starting the new work. An unresolved or failed synchronization blocks implementation. Do not merge `testing` into `master` as part of this preparation; release integration is separate. -## Contribution workflow (including generated patches) -- Assume contributors may use code-generation tools without understanding every changed line. Review the resulting code, not the contributor's confidence in it. -- Start from a reproducible user-visible problem. Complete the relevant bug-intake steps before changing code. -- Investigate the full confirmed behavior class before implementing a fix. For example, a stale-focus bug seen in one browser may also affect other applications or empty workspaces. -- Prefer the smallest root-cause fix that covers the full confirmed behavior class. Do not add app-specific exceptions, desktop-specific branches, compatibility fallbacks, or broad refactors unless the evidence requires them. -- Add or update automated regression tests for the general behavior and the originally reported workflow whenever practical. -- Read every generated diff before committing. Remove unrelated rewrites, speculative cleanup, dead code, debug leftovers, and generated files that are not required by the fix. -- Never commit a behavior change solely because it compiles or because an automated tool says it works. Verify the real user-facing workflow after rebuilding the installed copy. +After synchronization, check whether the reported issue still exists and inspect recent changes before implementing a fix. Another contributor may already have fixed it. See [the contributor synchronization procedure](CONTRIBUTING.md#update-your-branch-before-starting-work), including instructions for a new branch without an upstream. -## Verification checklist before commit -Run the narrowest relevant checks first, then broaden testing based on the affected behavior: -- For documentation-only changes, diff inspection is sufficient unless the edited documentation includes commands or generated content that need validation. +## Project Structure & Module Organization -1. Inspect the diff: - - `git diff --check` - - `git status --short` - - `git diff --stat` - - `git diff -- ` -2. Run syntax checks for each changed Python file: - - `python -m py_compile ` -3. Run focused automated regression tests: - - `python -m unittest ` - - For shared input, focus, script lifecycle, settings, plugin loading, or installation changes, run `./test-local.sh` after the focused tests pass. -4. For code or behavior changes, rebuild the local installed copy: - - `./build-local.sh` -5. For code or behavior changes, confirm the runtime import resolves to the refreshed local install: - - `python - <<'PY'` - - `import importlib.util` - - `print(importlib.util.find_spec("cthulhu").origin)` - - `PY` -6. For code or behavior changes, reproduce the original user-visible workflow against the rebuilt copy. -7. For focus, keyboard, or window-tracking changes, manually test closely related regressions: - - Xorg and the user's active window manager or desktop. - - Switching among browser content, terminal windows, GTK applications, dialogs, and empty workspaces. - - Returning to the original application after each switch. - - Cthulhu shortcuts, structural navigation, flat review, and any delegated key handling such as Fenrir in XTerm. - - Both key press and key release behavior for modifiers, NumLock, and keypad keys when relevant. - - Clean shutdown without crashing the browser or leaving grabs behind. -8. Record what was tested, what could not be tested locally, and any remaining uncertainty in the commit message or review notes. +Cthulhu is a Go Linux screen reader. `cmd/` contains executables; `internal/` owns reader subsystems. Embedded audio lives in `assets/sounds/`, Tentacle libraries in `sdk/`, native harnesses in `tests/`, and parity records in `testdata/`. Go tests sit beside implementation files. Arch packaging lives in `distro-packages/Arch-Linux/cthulhu-git/`. -## Platform support stance -- **critical** Robust Xorg support is required and is a merge gate for Cthulhu. -- Wayland support is desirable, but it is secondary to keeping Xorg stable and usable. -- If a change that improves Wayland would break, weaken, or regress Xorg support, the answer is a hard no by default. -- If the user explicitly insists on such a change anyway, warn them plainly that the change is expected to be rejected without further consideration as long as Xorg is adversely affected. -- Prefer desktop-agnostic fixes first. If a tradeoff is unavoidable, choose the path that preserves Xorg correctness and defer the Wayland-specific improvement. +## Build, Test, and Development Commands -## Coding guidelines -- **When modifying existing code:** follow the surrounding code’s conventions. -- **When writing new code from scratch:** prefer - - variables: `camelCase` - - functions/methods: `snake_case` - - classes: `PascalCase` -- Keep changes clean and well-structured; avoid layering short-term workarounds when a focused fix is possible. -- Add debug logs where helpful for troubleshooting. When adding timestamps to logs, use: `"Message [timestamp]"` (message first). +Use Go 1.24+ with CGO and development libraries listed by the Arch `PKGBUILD`. -## Accessibility requirements (high priority) -### General -- Screen-reader-first UX: assume non-visual navigation. -- No keyboard traps; Tab/Shift+Tab must move through all controls. -- Use clear, complete labels (e.g., “Confirm Password”, not “Confirm”). -- Do not invoke `spd-say` or add direct speech output to GUI dialogs. Expose accessible UI state and let the active screen reader announce it. +- `go build -o build/cthulhu ./cmd/cthulhu`: build the reader. +- `go build -tags brlapi -o build/cthulhu-braille ./cmd/cthulhu-braille`: build the Braille helper. +- `go test ./... -count=1`: run default tests; native cases may skip. +- `go test -tags brlapi ./... -count=1`: run packaging checks. +- `go vet ./...`: check common Go errors. +- `go run ./cmd/parityledger validate testdata/parity-ledger.csv`: validate parity records. +- `./build/cthulhu --check-config`: validate settings; `./build/cthulhu` starts the reader. -### Python GTK (Gtk 3) -- Associate labels with controls (mnemonics + buddy widget): - - `label.set_use_underline(True)` - - `label.set_mnemonic_widget(entry)` -- For `Gtk.TextView`, call `set_accepts_tab(False)` so Tab moves focus. -- For custom widgets, set accessible name/role via ATK where applicable. +## Coding Style & Naming Conventions -## Shell script rules -- **Bash variables must be `camelCase`** (except system env vars like `ACCESSIBILITY_ENABLED`). -- If you edit a `#!/usr/bin/env bash`, `#!/bin/bash`, or POSIX `sh` script, run `shellcheck` and fix issues. -- Avoid colorized output unless explicitly requested (accessibility-first; keep scripts simple). +Use `gofmt`, exported PascalCase identifiers, private camelCase identifiers, and lowercase packages. Preserve license headers. Follow existing Python conventions; run `shellcheck` for edited shell scripts. Keep complete user-facing messages separate from internal identifiers and preserve deliberate speech/Braille segmentation. -## Plugins (Cthulhu) -- System plugins live in `src/cthulhu/plugins/`. -- Follow existing plugin patterns (keybinding registration, GTK dialog/window patterns, debug logging). +## Behavior & Accessibility Safeguards -## Meson install reminder (important) -- If you add new Python modules under `src/cthulhu/`, update `src/cthulhu/meson.build` so they get installed (otherwise imports can fail after install). -- If you add a new plugin directory, update `src/cthulhu/plugins/meson.build` and add a `meson.build` in the plugin directory. +Read [CONTRIBUTING.md](CONTRIBUTING.md) for detailed safeguards. Compare accepted behavior with Python on `legacy`; use current Orca as the primary reference for Mozilla and LibreOffice support. Follow [LIBREOFFICE_SUPPORT.md](LIBREOFFICE_SUPPORT.md) for Office integration boundaries. Preserve unrelated work and active diagnostic logs; obtain authorization before replacing a running reader. -## Settings policy (important) -- Keep persistent settings in Cthulhu TOML files through the existing settings manager and TOML backend. -- Do not add `gsettings`, `dconf`, or `Gio.Settings` dependencies or fallback paths. +Fix regressions in the shared subsystem when appropriate. Identify state ownership, lifetime, reset, and cancellation; keep native callbacks and input/focus handling bounded. Preserve Xorg correctness while allowing capability-based Wayland degradation. Keep Tentacles external and responsive. -## Dependency synchronization (important) -- This repository does not use `requirements.txt`. When adding, removing, or changing a runtime, optional, or build dependency, keep the relevant dependency declarations and documentation synchronized. -- Check `pyproject.toml`, `meson.build`, the dependency sections in `README.md` and `README-DEVELOPMENT.md`, and each applicable distro package recipe under `distro-packages/`. -- In particular, update both Arch Linux `PKGBUILD` files and, when relevant, Slint's `cthulhu-info` and `README`. Review the Slackware and Slint build files for any corresponding build-dependency changes. -- Preserve the distinction between required, optional, and build-only dependencies so package builds install what Cthulhu actually needs without forcing optional features on every user. +Prefer core Go implementations for features users expect from the reader itself; use Tentacles for extensions. -## Arch package verification -- After changing an Arch Linux `PKGBUILD`, build every affected recipe in a clean chroot before considering the packaging work complete. Use `pkgctl build --clean` from the `devtools` package; a normal `makepkg` or `yay` build is not a substitute for this check. -- Validate both stable and `-git` recipes when a shared packaging change affects both. -- Build dependency packages first. When a split helper depends on a locally built package that is unavailable in the configured repositories, pass that package artifact to the helper build with `pkgctl build --clean -I /path/to/package.pkg.tar.zst`. -- Run `bash -n`, `shellcheck`, and `makepkg --printsrcinfo` on each changed recipe before the clean-chroot build. -- Report which recipes completed clean-chroot builds. If sudo access, network access, or an unavailable dependency prevents a build, state that explicitly instead of describing the package as verified. +Expose GUI controls through accessibility APIs. Keep outer preferences combo widgets `can-focus=False`; verify Tab/Shift+Tab, popup selection, and Apply/reload. Validate versioned TOML settings through persistence and runtime consumption. Protect passwords; redact private debug output before sharing. -## Common Cthulhu agent mistakes -- Do not edit or diagnose a stale installed copy under `~/.local/...`; update the repo and rebuild with `./build-local.sh`. +## Testing Guidelines + +Use Go's `testing` package, `*_test.go`, and `TestBehavior` functions. Start with the affected package. Use deterministic synchronization and generic fixtures. Native checks need their relevant harness, such as `python3 tests/native_atspi.py`. No numeric coverage target is configured. Report automated, installed-binary, physical-input, audible-speech, and Braille-display checks separately. + +For performance work, run the relevant `BenchmarkBehavior` functions before and after changes using repeated runs and allocation reporting. Add or expand representative benchmarks when investigating a new bottleneck; keep fixture construction outside timed loops and check that the intended work actually happens. Preserve announcement content, ordering, interruption, focus, and Braille behavior. Benchmark timing alone does not establish a bug or live responsiveness, and noisy timing changes must not become automatic pass/fail thresholds. See [benchmark procedures](docs/testing/benchmarks.md) for commands and measurement limits. Plain `go test` does not run benchmarks. + +## Commit & Pull Request Guidelines + +Use short descriptive subjects consistent with history. Confirm the intended target branch; `legacy` preserves Python. Describe behavior, issues, regressions checked, skipped checks, and remaining live acceptance. Human diff review and testing precede submission under the policy in `CONTRIBUTING.md`. + +## Guide Maintenance + +Update this guide when working rules, repository layout, commands, or verification requirements change. Replace stale guidance instead of appending progress reports; keep detailed procedures in `CONTRIBUTING.md`. diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..8b41010 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,5 @@ +Cthulhu authors: + +Storm Dragon +Angus Kola +Deedra Waters diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..068d13d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,222 @@ +# Contributing to Cthulhu + +Read [README.md](README.md) and [AGENTS.md](AGENTS.md) first. Start with a user-visible behavior and reproduce the issue in the current code. The maintained repository is `git.stormux.org/storm/cthulhu`; confirm the intended target branch with the maintainer. The `legacy` branch preserves Python Cthulhu; the current checkout is the Go implementation. + +## Update Your Branch Before Starting Work + +Update your checkout before starting each fix or feature. This helps avoid fixing an issue that another contributor has already resolved. + +1. Run `git status --short --branch` and confirm you are on the intended branch. If a merge or rebase is in progress, finish it first. Preserve any uncommitted work and diagnostic files before updating; do not discard them or automatically stash them. +2. Run `git pull --ff-only` to update the current branch from its configured upstream. A successful pull saying the branch is already up to date also satisfies this step. If Git reports divergent branches, merge the intended upstream into your branch and resolve the conflicts before continuing. Ask for help if you are unsure; do not use a reset or force push to make the error disappear. +3. If your branch is neither `testing` nor `master`, also run: + + ```sh + git fetch origin + git merge origin/testing + ``` + + These commands bring the latest shared development changes into your contributor branch. They assume `origin` points to the maintained repository. If `origin` is your fork, use the remote for the maintained repository in both commands instead. If you are unsure which remote that is, ask before merging. +4. Resolve any conflicts, run the relevant checks, and complete any merge commit before starting implementation. A failed pull or an unfinished merge means the update is not complete. +5. Reproduce the reported issue again and review recent changes. If it is already fixed, verify the existing fix rather than writing a second implementation. + +For a new local branch without an upstream, first update `testing` with `git pull --ff-only`, then create your contributor branch from that updated `testing`. Do this before making changes. Existing contributor branches still need the merge from the maintained repository's latest `testing` described above. + +Do not merge `testing` into `master` during this preparation. Updating `master` from its own upstream and integrating a release are separate operations. The historical Python `legacy` branch is not a target for Go changes. + +## Proposing a Change + +Keep each change to one complete behavior. Describe the reproduction, expected result, affected subsystem, and plausible regressions. A reported application or page is a reproduction case: fix the shared layer when it explains the defect. Use an application-specific script only when a shared fix would be wrong; document and test the exception. + +State the Xorg impact. Regressions in Xorg input, focus, event ordering, browser handling, or lifecycle block the change. Wayland support is welcome: use capability checks and graceful degradation, and restrict only features that cannot work correctly. Missing Wayland support alone should not block startup or a contribution preserving Xorg behavior. + +Record changed behavior and remaining acceptance gaps in the contribution description; update `testdata/parity-ledger.csv` when relevant. The old Cthulhu-Go migration plan and documentation index are absent here; avoid references to those missing files. Keep durable guidance focused on working rules rather than dated progress reports. + +## Development and Architecture + +Use Go 1.24 or newer, CGO, `pkg-config`, and development libraries for GTK3, AT-SPI, GStreamer, and X11. Braille builds also require BRLTTY/BrlAPI and liblouis. The Arch `PKGBUILD` lists runtime and build dependencies. + +```sh +go build -o build/cthulhu ./cmd/cthulhu +go build -tags brlapi -o build/cthulhu-braille ./cmd/cthulhu-braille +go test ./... -count=1 +go test -race ./... -count=1 +go test -tags brlapi ./... -count=1 +go vet ./... +go build ./cmd/... +go run ./cmd/parityledger validate testdata/parity-ledger.csv +``` + +Start verification with the affected packages; run broader checks when the change affects shared behavior or before submission where practical. Format edited Go files with `gofmt`; run `shellcheck` for edited shell scripts. Use deterministic tests and synchronization instead of timing sleeps. Keep fixtures generic, without real usernames or personal identifiers. + +### Speech regression push check + +Run `python3 tests/check_speech.py` for speech queue, title, Wine review metadata, +held-key repeat and fresh-key interruption regressions. This uses a private +D-Bus session, the race detector and the native build dependencies above; +it requires Python 3 and `dbus-run-session`. Required tests must pass: deleting +or skipping a required test fails the check. It does not use the active reader, +the desktop display, or audible speech. + +To enable this check for local pushes in a clone with no existing pre-push hook: + +```sh +ln -s ../../hooks/pre-push .git/hooks/pre-push +``` + +Preserve and integrate any existing pre-push hook rather than overwriting it. +The hook tests each distinct pushed commit tip in a temporary snapshot, so +uncommitted fixes cannot mask a broken commit and pushing another branch tests +that branch. Failed checks stop a normal local push. Git hooks are local and +can be bypassed with `--no-verify`; they do not enforce policy for other clones. +Server enforcement needs a required CI check on protected branches. Neither +hook results nor CI replace human review, real application listening, physical +keyboard checks or Braille acceptance. + +Before extending application orchestration, an event loop, native callback, or settings mapper, identify the subsystem responsible for the policy. Keep ordering and routing in coordinators and feature policy with its existing owner. Specify the owner, lifetime, reset conditions, and cancellation of new mutable state. Prefer cohesive files in existing packages; avoid unnecessary interfaces or packages. If responsibilities need separating, use a behavior-preserving change. Record any urgent-fix follow-up in the contribution description. + +Preserve event order, GLib/cgo ownership, and native lifetimes. Balance key grabs and releases, recover from dead AT-SPI objects, and clean up on shutdown. Keep core input and focus handling bounded and responsive. + +Tentacles already use an external process protocol: preserve existing host safeguards and author APIs. Keep runnable implementations in external repositories and leave a new installation's catalog empty until repositories are added. Tentacles must not block input, focus, or speech. Use init-independent process supervision for Tentacles by default, with optional explicitly configured cgroup-v2 resource limits. Do not require a particular init system, a service manager, or administrator setup for normal Tentacle use. Preserve descendant cleanup on disable and reader exit. Treat cgroup-v2 containment as resource control, not a same-user security sandbox. Preserve HTTPS artifact and SHA-256 verification before atomic package installation. + +### Local installation and reload + +After building, install both Go binaries beside one another so the reader can +find its Braille helper: + +```sh +install -Dm755 build/cthulhu "$HOME/.local/bin/cthulhu" +install -Dm755 build/cthulhu-braille "$HOME/.local/bin/cthulhu-braille" +"$HOME/.local/bin/cthulhu" --check-config +``` + +When replacement of the running reader is authorized, reload it from a terminal +in the same desktop session: + +```sh +"$HOME/.local/bin/cthulhu" --replace +``` + +The replacement command uses the same session-bus discovery as the reader's +D-Bus service, including when `DBUS_SESSION_BUS_ADDRESS` is unset. It waits +for the identified reader process to exit before starting the replacement. +A terminal using a different session bus can start another reader +instead of replacing the intended one. Preserve the original reader's desktop +session environment when restarting it from automation. + +Check replacement and session-bus discovery without touching the desktop reader: + +```sh +python3 tests/native_test_session.py env CTHULHU_NATIVE_REPLACE=1 CTHULHU_NATIVE_DBUS_TEST=1 go test ./cmd/cthulhu ./internal/sessionbus -run 'TestReplace|TestNativeDesktopSessionBusDiscovery' -count=1 -v +``` + +Wine accessibility also needs the separate standalone `wine-access` +installation described in the [README](README.md#wine-access). Building the Go +reader does not build or refresh that helper. After restoring an overwritten +helper, check MUSHclient menus, command typing, and incoming plugin speech; +automated event recordings alone do not establish audible speech acceptance. + +## Behavioral References and User-Facing Messages + +Inspect relevant settings, bindings, speech, Braille, and toolkit behavior before changing user-visible behavior. Read Python reference files without changing branches, for example: + +```sh +git show legacy:src/cthulhu/settings.py +``` + +Use the newer Orca implementation as the first reference for Firefox, Thunderbird, and LibreOffice when available. [LibreOffice support](LIBREOFFICE_SUPPORT.md) describes its integration boundaries and remaining acceptance checks. Reference implementations guide behavior; do not mechanically copy Python class or plugin boundaries. Preserve accepted behavior unless the user chooses a deliberate difference, and describe that difference. Do not modify reference checkouts or installed readers without authorization. + +Use complete messages and self-contained labels with placeholders for variable content. Keep internal states, commands, and settings identifiers independent of user-facing wording. Preserve deliberate speech/Braille segmentation, verbosity, and separate role/state announcements. Apply these rules within the change; adding translation infrastructure or sweeping existing strings requires separate scope. + +## Accessibility and Settings Verification + +Keep GUI controls keyboard reachable and exposed through accessibility APIs. GUI applications must let screen readers announce controls rather than calling Speech Dispatcher themselves. Associate labels with controls and provide accessible names for custom widgets. + +For preferences `GtkComboBox` and `GtkComboBoxText`, keep the outer widget's `can-focus` property false so GTK focuses its internal button. Setting it true can trap Tab and Shift+Tab. Fix the property instead of adding key handlers or changing reader grabs. Preserve semantic labels and selected-value presentation; the internal button's AT-SPI `STATE_FOCUSED` alone is insufficient evidence. + +For changed preferences, verify: + +1. Tab and Shift+Tab through the preceding control, changed control, and following control. +2. Open the popup and change the selection using the keyboard. +3. Apply, close, reopen, and confirm the value persists. +4. Exercise the affected reader behavior and confirm that the saved setting changes runtime output. + +Preserve versioned TOML settings. The default file is `$XDG_DATA_HOME/cthulhu/user-settings-go.toml`, with `~/.local/share` used when the variable is unset. Use a separate test configuration when appropriate: + +```sh +./build/cthulhu --config /tmp/cthulhu-test-settings.toml --check-config +``` + +Native `*_native_test.go` checks require fixtures and environment flags. Use the relevant isolated harness in `tests/`, such as `python3 tests/native_atspi.py` or `python3 tests/native_preferences.py`. Shared browser changes also need the relevant browser harness and real-browser regression checks. + +Native harnesses must launch their private D-Bus session through +`tests/native_test_session.py:run_private_session`. It gives activated services +a disposable mode-0700 `XDG_RUNTIME_DIR` and removes inherited desktop bus +addresses. Start Xvfb before D-Bus: service activation inherits the bus daemon's +display, even when the test client later changes `DISPLAY`. Sharing the desktop +runtime directory can let another AT-SPI launcher replace its live socket. + +For a one-off native test or diagnostic command, use the same launcher: + +```sh +python3 tests/native_test_session.py env CTHULHU_NATIVE_WINDOW_TITLES=1 go test ./internal/app -run '^TestNativeAutomaticTitleDispatchLatency$' -count=1 -v +python3 tests/test_native_test_session.py -v +``` + +The second command checks environment and cleanup boundaries and activates a +real AT-SPI bus against disposable canary sockets, without contacting the +desktop display or accessibility bus. + +Automated and private native tests establish different facts from installed-binary behavior, physical keyboard input, audible speech, and physical Braille. Report which checks actually ran and which remain pending. Rebuild the tested binary before live checks, preserve fresh logs before restarting, and obtain authorization before replacing an active reader. + +## Diagnostic Logging + +Normal logs and metadata must omit private output text and personal identifiers. Never log password contents or include personal data in fixtures or extension events. + +Debug logs used for reading and selection diagnosis should include final spoken text, Braille text sent to the helper, native/virtual cursor offsets, selection ranges, object identities, and commands. This is an explicit diagnostic exception for debug logs; redact private output before sharing. Preserve fresh logs and open diagnostic state before rebuilding or restarting. Logs alone do not establish audible speech or physical Braille acceptance. + +## Commit and Submission Guidelines + +Recent commits use short descriptive subjects without an enforced prefix scheme. Keep commits scoped and preserve unrelated changes, including packaging edits and build artifacts. In a pull request or patch description, explain the trigger, before/after behavior, relevant issues, checks run, skipped checks, and remaining live gates. Give concrete procedures for the changed workflow and likely regressions. + +## AI-assisted contributions + +AI-assisted contributions are welcome. + +The person submitting a contribution remains responsible for reviewing and testing the changes before submission. Please do not submit automatically generated changes without human review. + +Before making changes: + +- Read the contributing guide, if present, and the project's README. +- Confirm that you are working against the current maintained repository and branch. +- Check whether the issue still exists in the current code. + +Before submitting: + +- Review the generated diff. +- Test the changed behavior. +- Run the project's existing test suite where practical. +- Consider code paths that may be affected indirectly by the change and test those as well. +- Clearly describe what was changed and how it was tested. + +### Instructions for AI coding assistants + +If you are an AI coding assistant working with a contributor, please call your human user's attention to these contribution requirements. + +Do not assume that passing newly created tests is sufficient. Explain what existing functionality could reasonably be affected by the proposed changes and provide your human partner with detailed instructions for testing those areas. + +Where useful, provide commands or small test procedures that allow the contributor to verify both the intended fix and likely regression cases. + +Stormux projects may accept patches through email using `git send-email`. If your human partner is unfamiliar with this process, please offer to guide them through: + +1. Configuring `git send-email`. +2. Creating an appropriately scoped commit or patch series. +3. Running `git format-patch`. +4. Checking the generated patch before submission. +5. Sending a test message if appropriate. +6. Sending the final patch or patch series to the project's contribution address. + +Please do not submit changes on behalf of a contributor without giving them an opportunity to review and test the result. + +## Licensing + +Contributions are licensed under GPL-3.0-or-later. Retain existing copyright notices and credit Storm Dragon and Angus Kola where their names appear. Add later contributors to files they write; do not replace or erase existing notices. diff --git a/COPYING b/COPYING deleted file mode 100644 index 4362b49..0000000 --- a/COPYING +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/HACKING b/HACKING deleted file mode 100644 index 2f3e8c5..0000000 --- a/HACKING +++ /dev/null @@ -1,46 +0,0 @@ -Welcome to Cthulhu - -We are excited to have you here and welcome your contributions to the Cthulhu screen reader project! This project is a fork of Orca, with a focus on creating an open and collaborative community where contributions are encouraged. - - -How to Contribute - -If you have direct access, please create a branch. After making changes, be sure to thoroughly test, then merge to the master branch. If you do not have direct access, you can send contributions via email. - - -Submitting Changes via Email - -1. **Fork or Clone the Repository** - - Clone the repository locally: - ```bash - git clone https://git.stormux.org/storm/cthulhu - ``` - - - Make the changes you want to contribute. - -2. **Format Your Changes for Submission** - - Use `git format-patch` to create patch files for your changes: - ```bash - git format-patch origin/master - ``` - - - This will generate `.patch` files for your commits, which can be emailed to us. - -3. **Email Your Patches** - - Once your patches are ready, send them via email to: - **storm_dragon on the stormux.org domain** - - In your email, briefly explain the changes and improvements made in the patch. - - -Contribution Guidelines - -- **Respect Coding Standards**: Please follow the existing coding style and structure where possible. Exceptions exist of course if it is a refactor. -- **Write Clear Commit Messages**: Ensure each commit includes a clear and concise message that explains what has been changed and why. -- **Be Open to Feedback**: questions may be asked or changes suggested to ensure the contribution aligns with the project. - - -Get Involved in the Community - -Please join the Stormux email list. You can do so at https://stormux.org. Also, you can talk to us on irc at irc.stormux.org #stormux. - -Thank you for your interest in contributing to Cthulhu! Together we can make an awesome screen reader. diff --git a/LIBREOFFICE_SUPPORT.md b/LIBREOFFICE_SUPPORT.md new file mode 100644 index 0000000..a65aef4 --- /dev/null +++ b/LIBREOFFICE_SUPPORT.md @@ -0,0 +1,330 @@ +# LibreOffice integration + +Current Orca is the primary behavioral reference for LibreOffice. Python +Cthulhu remains available on the `legacy` branch for historical comparisons: +`git show legacy:src/cthulhu/scripts/apps/soffice/script.py`. +Do not switch the active Go checkout to inspect that reference. + +## Architecture + +Application handling runs after screen-lock and foreground validation, before +generic focus and text filtering. `internal/app/application_behavior.go` +routes copied accessibility events by verified provider process identity. +The LibreOffice handler lives in `internal/app/libreoffice.go`. +It can normalize an event, request focus adoption, or suppress presentation. +The reader retains window ownership, input policy, pending-output cancellation, +review, and speech/Braille delivery. Ordinary applications keep their existing +event path. Steam's existing integration remains in place. + +`internal/atspi/libreoffice_native.go` captures bounded Calc metadata on the +native owner thread. It does not enumerate a sheet. The controller and +presentation code never retain native objects or perform provider queries. +`internal/presentation/libreoffice.go` owns the corresponding speech +formatting; LibreOffice Braille formatting stays beside its controller. + +Logical focus belongs to the existing event loop. Selection comparison keeps +one bounded snapshot for the focused sheet, keyed by its application bus and +accessible sheet path and admitted only within the owned document window. +It is retired on sheet/application focus changes and ordinary owned-focus +reset, including destruction, foreground loss, and screen lock. There are no +selection workers, timers, or retained native references. Dynamic header +choices live in the adapter's bounded, synchronized store of copied identities +and coordinates. Commands update that store without provider queries; the +native owner captures header text. Choices use application bus, document/view, +window and the provider's sheet name. Calc recreates table objects on tab +switches, so a table path cannot identify a sheet across those switches. +Focus loss cancels output while preserving document header choices. +Use the existing input machinery for additional Office commands. +Application code must not bypass security/foreground gates or manage its own +speech connection, key grabs, or background event loop. + +Keep generic table operations and genuinely shared fixes in their existing +subsystems. Keep verified LibreOffice exceptions in the dedicated files. +Adding later Office features should extend these boundaries, without +reorganizing unrelated reader code or building a speculative plugin framework. + +## First slice + +- Calc active-cell events establish logical focus, including after editing + and when the sheet changes. +- LibreOffice frame activation and X11 foreground recovery establish window + ownership without the generic focused-descendant search. Calc's following + cell/editor events establish document focus. Searching the previous view + during workbook activation caused stale-object queries and timeouts on return; + leaving activation on the frame avoids that work. Dialogs retain normal + focused-control resolution. +- Cell contents and addresses are separate. Normal speech gives the value, + then the address; an empty value gives “blank.” Only-displayed-text mode + omits the address and the synthetic blank label. +- Recorded Braille preserves value spacing followed by the address. A cell + component is not an editable text route. +- F2 resolves a temporary editor's focused paragraph when available. + If the paragraph appears later, its first owned text/caret event establishes + editor focus before generic filtering. +- Post-editing sheet focus is adopted silently. Spreadsheet capacity and + cell/container state chatter are omitted as in Orca. +- Ancestor focus claims are suppressed when captured ancestry identifies the + existing focused spreadsheet object. +- Non-editor caret events do not displace a focused cell. Selection events do + not promote the first selected cell of a range into logical focus. + +References inspected: Orca commit `cd58a88ed` (2026-10-14), +`scripts/apps/soffice/script.py`, `script_utilities.py`, +`speech_generator.py`, `braille_generator.py`, and shared +`speech_generator.py` / `ax_utilities_table.py`. + +## Formula slice + +- Normal cell speech appends “has formula” after the value and address. + Only-displayed-text mode continues to omit synthetic metadata. +- Basic Where Am I includes the formula after the cell information. +- **Cthulhu+=** presents the current cell's formula in the desktop layout, + following Orca's `where_am_i_presenter.py:present_cell_formula`. The semantic + command is `present-cell-formula`; it is listed in preferences and Learn Mode. + As in current Orca, the laptop layout leaves it unbound; assign a shortcut + in Key Bindings if desired. +- A cell without a formula gives its value, or “empty” for an empty cell. + The command currently applies to Calc cells; other focus reports “Not in a + table.” Temporary F2 editors are separate objects, so leave editing before + requesting the cell's formula. +- Native capture reads the uncached `formula` attribute (or `Formula`, as + accepted by Orca) alongside the existing bounded cell metadata. Formula + string-literal spacing is preserved. Expressions are bounded to the native + snapshot field limit, retaining the beginning of long expressions. + Commands consume the latest accepted focus snapshot; they never scan a sheet + or query a provider from the event loop. A provider change without an event + requires revisiting the cell to refresh its snapshot. +- Formula speech uses the existing command and speech queues, foreground and + screen-lock gates. Normal Braille retains the value and address, with no new + routes or formula suffix. The explicit formula command uses the existing + system-message flash path and its Braille preferences, as in Orca. + +## Selection slice + +- Shift+Arrow selection growth and shrinkage announce selected/unselected + coordinates. Adjacent cells form compact rectangles; disjoint cells retain + their gaps. The active anchor is left to ordinary cell presentation. +- Full rows and columns use row/column labels. Select All says “All cells + selected”; leaving a selection says “Selection cleared.” Ctrl+A can first + select the used area; press it again to select the entire sheet. + These announcements require a provider event. An independent AT-SPI observer + on LibreOffice 26.2.6.3 confirmed that Shift+Up after extending whole rows, + and Shift+Left after extending whole columns, change the selection without + emitting a selection event. Ctrl+Home can also clear those selections without + an event. Immediate announcements for those cases remain unsupported; the + next selection event refreshes the snapshot. The reader does not poll or + infer selection changes from keystrokes. +- Small selections capture at most 64 cells, rows, or columns. Messages with + more than eight rectangles use a count. Larger selections use a count and + two boundary samples for duplicate suppression, without treating endpoints + as proof of a filled rectangle. Overlapping count-only selections report + the new total rather than falsely announcing the entire old range unselected. +- The GTK bridge caps cell counts at 2147483647; partial-sheet selections at + that limit say “At least … cells selected.” Whole-sheet selection is checked + separately. Large selections with identical counts and boundary samples + cannot be distinguished by this bounded snapshot; interior-only changes may + therefore be suppressed. Full topology/delta reporting remains future work. +- Native capture uses a fixed number of count queries and at most 64 selected + positions. It requests no selected-row/column arrays. Ordinary small cell + selections skip full-row/column counts; LibreOffice itself scans its row + marks when larger selections need a selected-row count. Fixed RPC counts + do not guarantee a provider's response time. +- Selection events keep both logical and retained native focus on the active + cell. Formula commands, object review, cell Braille frames, and routing + continue to use that cell. Selection messages use the existing system-message + Braille flash path and preferences. Only-displayed-text mode suppresses them. +- Current Orca's selection callbacks and utilities guide the behavior. The + [LibreOffice spreadsheet provider](https://github.com/LibreOffice/core/blob/libreoffice-26-2/sc/source/ui/Accessibility/AccessibleSpreadsheet.cxx) + and [GTK selection bridge](https://github.com/LibreOffice/core/blob/libreoffice-26-2/vcl/unx/gtk3/a11y/atkselection.cxx) + were also inspected for selection ordering, row-count cost, and count limits. + +## Dynamic headers slice + +- In **Preferences → Key Bindings**, assign shortcuts to “Use the current row + as Calc column headers,” “Use the current column as Calc row headers,” and + the corresponding clear commands. All four are available in both layouts + and Learn Mode, and are unbound by default. Orca's Cthulhu+Shift+C equivalent + conflicts with Cthulhu's existing clipboard command; it is preserved. + Semantic commands are `set-column-headers-row`, `set-row-headers-column`, + `clear-column-headers-row` and `clear-row-headers-column`. +- Set column headers from any cell in the heading row, and row headers from + any cell in the label column. Each axis can be changed or cleared separately. + This follows Orca's shared `table_navigator.py` and `ax_utilities_table.py`, + rather than just its soffice script. +- Automatic speech prefixes the row heading when the row changes and the + column heading when the column changes. A cell does not repeat itself as + its own heading. Blank headings add no label. Basic Where Am I includes both + headings; normal Braille includes both through its existing context path. + Only-displayed-text suppresses automatic speech metadata. Formula commands, + active-cell focus, selections and editor routing retain their existing paths. +- Header text is read afresh with at most two direct cell lookups per snapshot, + bounded to the normal field limit. There is no row/sheet enumeration, polling, + worker or native reference retained by the header feature. Provider response + times still apply. Commands consume the accepted cell snapshot; a provider + mutation without a new event requires revisiting the cell. +- Choices survive sheet/workbook switches and lock/unlock for this reader + session. They are separate per document/view and sheet; they are not saved to + the workbook or settings. A reader restart or document/window destruction + clears them. The store accepts up to 64 sheets; clearing both axes frees a slot. +- Sheet names come from the verified provider's uncached `page-name` attribute, + preserving exact whitespace. Missing or oversized identity metadata disables + these commands. This metadata is exposed by LibreOffice's + [spreadsheet document provider](https://github.com/LibreOffice/core/blob/libreoffice-26-2/sc/source/ui/Accessibility/AccessibleDocument.cxx). + Tab-list child changes and tab-name events conservatively clear choices for + that document window. Reassign headers + after adding, removing or renaming sheets. This depends on provider events; + silent structural mutations cannot be detected. Tab selection alone preserves + choices. Merged headings and structural row/column edits remain unverified; + header choices are coordinates, not references that follow moved content. + +## Next slices + +1. Spreadsheet full-row reading needs a bounded, + explicitly defined extent; the generic setting is not full Calc support. +2. Writer paragraph navigation, selection, Say All, spell-check presentation, + and Braille panning. Compare each actual workflow with current Orca. + +Merged cells, overflow announcements, large-sheet responsiveness, other +LibreOffice backends, and independent-workbook acceptance remain separate +checks. These slices do not establish complete Office support. + +## Verification + +```sh +dbus-run-session -- env GOCACHE=/tmp/cthulhu-go-cache go test -race ./... -count=1 +dbus-run-session -- env GOCACHE=/tmp/cthulhu-go-cache go test -tags brlapi ./... -count=1 +python3 tests/check_speech.py +/usr/bin/python3 tests/native_libreoffice.py +python3 tests/native_atspi.py --table-only +GOCACHE=/tmp/cthulhu-go-cache go build -o /tmp/cthulhu-libreoffice ./cmd/cthulhu +GOCACHE=/tmp/cthulhu-go-cache go test -c -o /tmp/cthulhu-libreoffice-xorg.test ./internal/platform/xorg +CTHULHU_BINARY=/tmp/cthulhu-libreoffice CTHULHU_XRECORD_TEST=/tmp/cthulhu-libreoffice-xorg.test python3 tests/native_x11.py +xvfb-run -a env CTHULHU_NATIVE_X11=1 /tmp/cthulhu-libreoffice-xorg.test -test.run '^TestNativeDispatchBeforeRelease$' -test.v +``` + +The Calc harness requires i3 as well as LibreOffice, Xvfb, xdotool, xprop, +the Python AT-SPI bindings and the normal native build dependencies. It launches +installed LibreOffice with a disposable profile, document, private i3 window +manager, virtual X11 display, and private session/accessibility buses. +It exercises the production native adapter and event loop; recorded speech +and Braille are asserted for cell movement and blanks, F2 typing, Escape +cancellation, Enter commit, caret movement inside an existing numeric cell, +and switching between two sheets. Formula assertions cover a numeric result, +an empty string result, literal spaces, replacement with a number, formula +and basic Where Am I requests, and non-formula cells on a second sheet. +Selection checks cover cell-range growth/shrinkage, clearing, row/column extension, +Select All, disjoint cells made through the provider selection +API, a 2097150-cell selection, and a partial-sheet selection above GTK's count +limit. Formula commands during selection verify preservation of the active cell. +The native listener tests check the desktop formula shortcut before key release; +the Calc harness sends semantic requests through the production event loop. +Dynamic-header checks exercise both axes, automatic axis-change speech, +Where Am I, complete Braille context, heading edits, independent clearing, +sheet round trips, and both return directions between workbooks with matching +sheet names and different headings, using normal navigation without Ctrl+F6 +recovery. Recorded speech, Where Am I and Braille must retain each workbook's +own headings. Find and Replace typing and +cancellation check the ordinary focused-control path and return to the sheet. +Header command bindings are checked through +the shared binding resolver in both layouts. +No active reader is replaced and no normal Office profile is changed. + +These automated checks do not establish audible speech, physical input, or +physical Braille. Before submission, review the diff and test a rebuilt binary: + +1. In a disposable Calc workbook, populate text, numbers, formulas and blanks. + Arrow between them and listen for the value followed by its address. +2. Visit a formula cell: listen for “has formula,” then use **Cthulhu+=** + and basic Where Am I. With Braille flash messages enabled, verify that the + formula command flashes its result and restores the cell display. Try a formula returning an empty string, a formula + containing a string literal with repeated spaces, a number, and a blank. + Replace a formula with a number and revisit it; the formula cue must clear. + With only-displayed-text enabled, automatic speech should omit the cue. +3. Press F2, edit, cancel with Escape, then edit and commit with Enter. Check + character/word navigation in an existing cell editor and continued arrows. +4. Switch sheets and switch between two workbooks. Return from menus, dialogs, + the formula bar, and another application; check logical focus recovery. +5. Check the cell value/address, spacing, editor cursor and return to cell + display on physical Braille. Text routing applies inside the editor. +6. Use Shift+Arrows to grow and shrink a range; check selected/unselected + addresses and continued active-cell/formula output. Try Ctrl+Space, + Shift+Space, their Shift+Arrow extensions, and Ctrl+A twice. Clear each + selection with an arrow. Select disjoint areas with Ctrl+click and a large + area with Ctrl+Shift+Arrows; check gaps in small selections and count summaries + for large ones. Enable Braille flash messages and verify selection messages + restore the cell display. Enable only-displayed-text and verify selection + chatter is omitted. Repeat on another sheet and in a second workbook. +7. Assign the four header commands in Key Bindings. In a workbook with headings + across row 1 and labels down column A, set both axes. Move horizontally and + vertically; listen for the changed axis's heading, value and coordinate. + Use Where Am I to hear both headings. Try a blank heading and a formula + heading, edit a heading and revisit a data cell, then clear each axis + separately. Check complete Braille context and that command flashes restore + the updated cell frame. Verify assignment/persistence of shortcuts after + reopening preferences; header choices themselves last only for this session. + Switch sheets, switch to a second workbook with the same sheet names, leave + Calc and return, and lock/unlock. Check independent choices and resumed + headings. Add, remove and rename a disposable sheet; reassign headers after + the conservative reset. Test structural row/column edits and merged headings + separately; these cases have no acceptance claim yet. +8. Repeat ordinary GTK table movement/multiselection, browser typing and table + reading, and Steam navigation. Check lock/unlock and stale/background events. + +Human review and testing remain required by `CONTRIBUTING.md`. Passing this +fixture alone is not sufficient for submission or live accessibility acceptance. + +The tightening pass against LibreOffice 26.2.6.3 verifies the existing cell, +editor, formula, selection and dynamic-header slices and adds workbook return +coverage. Returning to the original workbook previously reproduced stale-object +timeouts through the production adapter. Keeping LibreOffice frame activation +out of the generic descendant search makes the recorded return checks pass; +header choices remain independent in both workbooks. Foreground recovery uses +the same policy, preventing raw sheet-state chatter before the first cell event. +The virtual-display driver uses window-manager activation and waits for the +heading cell before editing it. + +Full default, race and BrlAPI-tagged Go suites, the speech regression gate, +vet/build, parity-ledger validation, ordinary GTK table/multiselection checks, +and the isolated X11 reader/listener harness pass. The former shutdown test +failure is fixed by waiting for completed runtime startup before cancellation. +A process-cleanup assertion also now accepts ESRCH when a killed task disappears +during a procfs read. Neither correction skips the underlying shutdown checks. +The earlier native probe linker failure no longer reproduces with the current +listener harness. + +These results establish recorded private-session behavior. Audible output, +physical input/Braille, normal-profile workbook return, tab rename/add/remove +event delivery, merged/structurally edited headings, large-sheet responsiveness +and independent real-workbook acceptance still need their own checks. Earlier +browser checks recorded an editing-title failure and one non-reproducible mode +failure; this pass does not establish current live browser acceptance. + +## Calc startup focus diagnosis + +A normal-profile startup under i3 can leave Calc accepting arrow keys while +omitting active-cell accessibility events. In the observed case, cell events +were followed by focus claims from the floating Form Design and Form Controls +toolbars; subsequent arrows produced formula-bar text updates but no new cell +events. A separate AT-SPI observer reproduced the missing events without +Cthulhu. The affected workbook worked with a fresh profile, and a generic +workbook reproduced the failure with a disposable copy of the normal profile. +This establishes a profile-dependent LibreOffice focus/event problem; the +precise profile setting responsible has not been isolated. + +Press **Ctrl+F6** to return focus to the document, then retry the arrows. +This directly restored active-cell events in the isolated reproduction. +LibreOffice documents this shortcut in its +[Calc accessibility keyboard guide](https://help.libreoffice.org/latest/en-GB/text/scalc/guide/keyboard.html). +Automatic focus stealing would interfere with intentional toolbar use and +is not part of the reader's handling. + +The native Calc test activates its initial window, establishes document focus +with F6 followed by Ctrl+F6, and uses ordinary key sequences within each document. +Explicit window-manager activation switches workbooks and focuses the dialog. +It also checks later F6/Ctrl+F6 recovery and resumed cell speech/Braille. +Its fresh-profile private i3 display does not cover this normal-profile startup +failure. The same production test also passed under private i3 with the copied +normal profile after Ctrl+F6 recovery, asserting recorded cell speech and +Braille along with editing and sheet switching. Verify startup and recovery +under the actual window manager, plus audible speech and physical Braille, +separately. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f6cdd22 --- /dev/null +++ b/LICENSE @@ -0,0 +1,232 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . + +The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . diff --git a/PROGRESS_BARS.md b/PROGRESS_BARS.md new file mode 100644 index 0000000..855bbc3 --- /dev/null +++ b/PROGRESS_BARS.md @@ -0,0 +1,44 @@ +# Progress reporting + +Progress bars use the configured Off, Beep, Speak, or Both output mode and +percentage thresholds. Background reporting is optional. Updates do not take +focus or replace Braille for an unrelated object. + +Native HTML `` and ARIA `progressbar` controls use their AT-SPI +progress role and value events. Steam's shader dialog instead exposes changing +static text such as `Processing Vulkan shaders (37%)`. The Steam webscript +recognizes that English status under the verified `steamwebhelper` process and +passes its percentage to the shared progress handler. Other text, containing +sections, and ordinary browser processes do not use this exception. Translated +Steam shader messages and other custom text-only progress widgets are not +covered by this recognition. + +## Automated checks + +```sh +GOCACHE=/tmp/cthulhu-go-cache go test ./internal/app ./internal/webscripts ./internal/presentation ./internal/sound -count=1 +python3 tests/native_progress.py +CTHULHU_NATIVE_BROWSER_TESTS=progress python3 tests/native_browser.py +``` + +The isolated GTK test checks foreground, background, and hidden progress. The +isolated browser test drives real HTML and ARIA controls in a Chromium-family +browser and verifies the resulting tone requests. Unit tests cover Steam text +recognition, output modes, duplicate suppression, percentage thresholds, +security, stale events, background settings, and unrelated Braille ownership. +These checks do not establish audible output from the running reader. + +## Live review before submission + +Rebuild and restart the reader, then launch a Steam game that needs shader +processing. With Beep selected and Steam in the foreground, confirm that pitch +rises as the percentage increases without navigating onto the status text. +With Speak or Both selected, verify the configured speech threshold. With Off +selected, verify that automatic progress output stops. + +Switch to another application during processing: reporting should follow the +background-progress setting without moving focus or replacing that application's +Braille. Check ordinary Steam navigation and notifications afterward. Open +`tests/browser-progress.html` in a browser and activate Update progress to check +native and ARIA bars. Physical keyboard, listening, and Braille checks remain +separate acceptance gates. diff --git a/README-DEVELOPMENT.md b/README-DEVELOPMENT.md deleted file mode 100644 index 930540d..0000000 --- a/README-DEVELOPMENT.md +++ /dev/null @@ -1,122 +0,0 @@ -# Cthulhu Development Guide - -This document applies to the Cthulhu fork maintained by Storm Dragon. -Cthulhu is forked from Orca; prior Orca maintainers and contributors are part -of the upstream history, but they are not current maintainers of this fork. - -## Local Development Build - -To develop Cthulhu without overwriting your system installation, use the provided build scripts: - -### Building Locally - -```bash -# Build and install to ~/.local -./build-local.sh - -# Clean build and rebuild everything -./clean-local.sh --build-only -./build-local.sh -``` - -This installs Cthulhu to `~/.local/bin/cthulhu` without touching your system installation. - -### Testing the Local Build - -```bash -# Test the local installation -./test-local.sh - -# Run the local version directly -~/.local/bin/cthulhu --version -``` - -### Running Local Cthulhu - -```bash -# Method 1: Direct path -~/.local/bin/cthulhu - -# Method 2: Add to PATH (add to ~/.bashrc) -export PATH="$HOME/.local/bin:$PATH" -cthulhu -``` - -### Cleaning Up - -```bash -# Clean build artifacts only -./clean-local.sh --build-only - -# Remove local installation only -./clean-local.sh --install-only - -# Clean everything (build artifacts + local installation) -./clean-local.sh -``` - -## D-Bus Remote Controller - -Cthulhu now includes a D-Bus service for remote control: - -- **Service**: `org.stormux.Cthulhu1.Service` -- **Path**: `/org/stormux/Cthulhu1/Service` -- **Requires**: `dasbus` library (should be installed) - -### Testing D-Bus Service - -```bash -# Start Cthulhu with D-Bus service -~/.local/bin/cthulhu - -# In another terminal, test the service -busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service org.stormux.Cthulhu1.Service GetVersion - -# Present a message via D-Bus -busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service org.stormux.Cthulhu1.Service PresentMessage s "Hello from D-Bus" -``` - -## Wine Accessibility Helper - -On x86_64, Meson's default `-Dwine-access=auto` builds the helper when `cmake`, `winegcc`, -`wineg++`, and `widl` are available. Use `-Dwine-access=enabled` to require it or -`-Dwine-access=disabled` for an architecture-independent Cthulhu-only build. - -The helper implements the NVDA Controller 1, 2, and 3 RPC interfaces and forwards standard MSAA -events to Cthulhu's D-Bus service. SSML currently returns `ERROR_NOT_SUPPORTED` because Cthulhu -cannot preserve backend-independent mark callbacks and synchronous completion semantics. - -## Development Workflow - -1. **Make changes** to the code -2. **Build locally**: `./build-local.sh` -3. **Test**: `./test-local.sh` -4. **Run**: `~/.local/bin/cthulhu` -5. **Clean when done**: `./clean-local.sh --build-only` - -## Git Repository Management - -The `.gitignore` file is configured to exclude: -- Build artifacts (`_build`, `_build_releasecheck`, `meson-private`, etc.) -- Generated Python files (`cthulhu_bin.py`, `cthulhu_i18n.py`, etc.) -- Python bytecode (`*.pyc`, `__pycache__/`) - -Before committing: -```bash -# Clean build artifacts to avoid committing them -./clean-local.sh --build-only - -# Check what will be committed -git status -``` - -## Dependencies - -- **Runtime**: python3, pygobject-3.0, pluggy, tomlkit, AT-SPI2 -- **Build**: meson, ninja, gettext -- **Optional**: dasbus (for D-Bus service), BrlTTY, speech-dispatcher, piper-tts - -Install build dependencies on Arch Linux: -```bash -sudo pacman -S meson ninja gettext python-dasbus python-tomlkit -``` diff --git a/README-REMOTE-CONTROLLER.md b/README-REMOTE-CONTROLLER.md deleted file mode 100644 index bc7d403..0000000 --- a/README-REMOTE-CONTROLLER.md +++ /dev/null @@ -1,345 +0,0 @@ -# Cthulhu Remote Controller (D-Bus Interface) - -This documentation covers the Cthulhu fork maintained by Storm Dragon. -Cthulhu is forked from Orca; former Orca maintainers and contributors are part -of the project's upstream history, but they are not current maintainers of -this fork. - -> **⚠️⚠️ WORK IN PROGRESS**: This D-Bus interface is brand new and not yet feature complete. -Low-risk feature additions will continue to be made. The API may be -modified beyond bug fixes in future versions based on feedback from consumers of this support. -Such changes will be documented here. - -> **💡 Desktop-Agnostic Design**: Cthulhu's D-Bus Remote Controller is built on standard D-Bus -session bus infrastructure and works across all desktop environments (GNOME, KDE Plasma, XFCE, -i3, Sway, etc.). The D-Bus service uses no desktop-specific dependencies and follows universal -D-Bus conventions, making it suitable for integration with any application or automation tool -on any Linux desktop environment or window manager. - -[TOC] - -## Overview - -Cthulhu exposes a D-Bus service at: - -- **Service Name**: `org.stormux.Cthulhu1.Service` -- **Main Object Path**: `/org/stormux/Cthulhu1/Service` -- **Module Object Paths**: `/org/stormux/Cthulhu1/Service/ModuleName` - (e.g., `/org/stormux/Cthulhu1/Service/SpeechManager`) -- **Module Interfaces**: `org.stormux.Cthulhu1.ModuleName` - -See [REMOTE-CONTROLLER-COMMANDS.md](REMOTE-CONTROLLER-COMMANDS.md) for a complete -list of available commands. - -## Dependencies - -The D-Bus interface requires: - -- **dasbus** - Python D-Bus library used by Cthulhu for the remote controller implementation. - ([Installation instructions](https://dasbus.readthedocs.io/en/latest/index.html)) - -## Alternative Tools for D-Bus Interaction - -While this documentation primarily uses `gdbus` for examples, you can use any D-Bus tool or library: - -### Using `busctl` (systemd D-Bus tool) -```bash -busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \ - org.stormux.Cthulhu1.Service GetVersion -``` - -### Using Python with `dasbus` -```python -from dasbus.connection import SessionMessageBus -bus = SessionMessageBus() -proxy = bus.get_proxy("org.stormux.Cthulhu1.Service", "/org/stormux/Cthulhu1/Service") -version = proxy.GetVersion() -``` - -### Using `qdbus` (Qt D-Bus tool - available on KDE) -```bash -qdbus org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \ - org.stormux.Cthulhu1.Service.GetVersion -``` - -## Service-Level Commands - -Commands available directly on the main service (`/org/stormux/Cthulhu1/Service`): - -### Get Cthulhu's Version - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service \ - --method org.stormux.Cthulhu1.Service.GetVersion -``` - -**Returns:** String containing the version (and revision if available) - -### Present a Custom Message in Speech and/or Braille - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service \ - --method org.stormux.Cthulhu1.Service.PresentMessage "Your message here" -``` - -**Parameters:** - -- `message` (string): The message to present to the user - -**Returns:** Boolean indicating success - -### Show Cthulhu's Preferences GUI - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service \ - --method org.stormux.Cthulhu1.Service.ShowPreferences -``` - -**Returns:** Boolean indicating success - -### Quit Cthulhu - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service \ - --method org.stormux.Cthulhu1.Service.Quit -``` - -**Returns:** Boolean indicating if the quit request was accepted - -## Discovering Modules and Their Capabilities - -Use the standard DBus introspection interface to discover registered modules: - -```bash -gdbus introspect --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service --recurse -``` - -The child `` entries beneath `/org/stormux/Cthulhu1/Service` are the -registered modules. To inspect the methods and properties for one module: - -```bash -gdbus introspect --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/SpeechManager -``` - -## Interacting with Modules - -Each registered module exposes its own native DBus interface. Based on the underlying Cthulhu code, -these are categorized as **Commands** and **Properties**: - -- **Commands**: Actions that perform a task. These typically correspond to Cthulhu commands bound - to a keystroke (e.g., `IncreaseRate`). -- **Properties**: Runtime values, often settings (e.g., `Rate`). Setting a property does not cause - it to become permanently saved. - -You can discover and execute these for each module. - -### Plugin Modules - -Plugins that expose D-Bus decorators are automatically registered as modules using the naming -convention `Plugin_` (e.g., `Plugin_GameMode`, `Plugin_WindowTitleReader`). Use -standard DBus introspection to discover available plugin modules at runtime. - -#### Plugin_WindowTitleReader - -Controls for the Window Title Reader plugin: - -- Method: `SetEnabled` (`enabled`: bool, `notify_user`: bool) -- Property: `Enabled` - -Example: - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \ - --method org.stormux.Cthulhu1.Plugin_WindowTitleReader.SetEnabled true false - -# Check current state -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \ - --method org.freedesktop.DBus.Properties.Get \ - org.stormux.Cthulhu1.Plugin_WindowTitleReader Enabled -``` - -Busctl example: - -```bash -busctl --user call org.stormux.Cthulhu1.Service \ - /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \ - org.stormux.Cthulhu1.Plugin_WindowTitleReader SetEnabled bb true false - -# Check current state -busctl --user call org.stormux.Cthulhu1.Service \ - /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \ - org.freedesktop.DBus.Properties Get ss \ - org.stormux.Cthulhu1.Plugin_WindowTitleReader Enabled -``` - -### PluginSystemManager Module - -The `PluginSystemManager` module provides session-only plugin control: - -- `ListPlugins` -- `ListActivePlugins` -- `IsPluginActive` -- `SetPluginActive` -- `RescanPlugins` - -These calls do **not** persist changes to user preferences. - -### Executing Module Operations - -#### Get a Property - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/ModuleName \ - --method org.freedesktop.DBus.Properties.Get \ - org.stormux.Cthulhu1.ModuleName PropertyName -``` - -##### Example: Get the current speech rate - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/SpeechManager \ - --method org.freedesktop.DBus.Properties.Get \ - org.stormux.Cthulhu1.SpeechManager Rate -``` - -#### Set a Property - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/ModuleName \ - --method org.freedesktop.DBus.Properties.Set \ - org.stormux.Cthulhu1.ModuleName PropertyName '' -``` - -##### Example: Set the current speech rate - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/SpeechManager \ - --method org.freedesktop.DBus.Properties.Set \ - org.stormux.Cthulhu1.SpeechManager Rate '<90>' -``` - -#### Execute a Module Command - -```bash -# With user notification -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/ModuleName \ - --method org.stormux.Cthulhu1.ModuleName.CommandName true - -# Without user notification (silent) -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/ModuleName \ - --method org.stormux.Cthulhu1.ModuleName.CommandName false -``` - -- `notify_user` (boolean): Whether to notify the user of the action (see section below) - -#### Execute a Parameterized Command - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/ModuleName \ - --method org.stormux.Cthulhu1.ModuleName.CommandName \ - "value1" "value2" false -``` - -**Parameters:** - -- `notify_user` (boolean): Whether to notify the user of the action - -##### Example: Get voices for a specific language - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/SpeechManager \ - --method org.stormux.Cthulhu1.SpeechManager.GetVoicesForLanguage "en-us" "" false -``` - -This will return a list of available voices for US English. - -### User Notification Applicability - -**Setting `notify_user=true` is not a guarantee that feedback will be presented.** - -Some commands inherently don't make sense to announce. For example: - -```bash -# This command should simply stop speech, not announce that it is stopping speech. -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/SpeechManager \ - --method org.stormux.Cthulhu1.SpeechManager.InterruptSpeech true -``` - -In those cases Cthulhu will ignore the value of `notify_user`. - -**Setting `notify_user=false` is not a guarantee that Cthulhu will remain silent**, though for the -most part Cthulhu will try to respect this value. The exceptions are: - -1. If executing the command has resulted in UI being shown, such as a dialog or menu, the - newly-shown UI will be presented in speech and/or braille based on the user's settings. - Failure to announce that the user has been removed from one window and placed in another - could be extremely confusing. -2. If the *sole* purpose of the command is to announce something without making any other - changes, e.g. `PresentTime`, executing it with `notify_user=false` makes no sense. Adding - checks and early returns to handle this possibility does not seem worth doing. If you - don't want Cthulhu to present the time, don't ask Cthulhu to present the time. 😃 - -### Navigator Module "Enabled" State Applicability - -**In the Remote Controller, Navigator commands are expected to work even when not "enabled."** - -Some of Cthulhu's Navigator modules, namely Table Navigator, Caret Navigator, and Structural Navigator, -have an "enabled" state. The reason for this is very much tied to the keyboard-centric nature of -Cthulhu's commands. For instance, if Cthulhu always grabbed "H" (for heading navigation) and the arrow -keys (for caret navigation), normal interaction with applications would be completely broken. For -this reason, Navigator modules whose commands will prevent normal, native interaction with -applications are typically not enabled by default and can be easily disabled. - -In contrast, performing Navigator commands via D-Bus does not prevent native interaction with -applications. For instance, one could use the Remote Controller to move to the next heading without -causing H to stop functioning in editable fields. For this reason, and to avoid a performance hit, -the decision was made to not check if (keyboard-centric) navigation commands were enabled. As a -result, it should be possible to use Remote Controller navigation even in "focus mode" or other -cases where Cthulhu is not controlling the caret. This is by design. - -Given the keyboard-centric nature of Cthulhu's commands, there may be instances in which one uses the -Remote Controller for navigation and Cthulhu fails to correctly update its location in response. If -Cthulhu correctly updates its location when the same navigation command is executed via keyboard, -please report the Remote Controller failure as a new bug in Cthulhu's issue tracker. - -### The "Stickiness" (or Lack Thereof) of On-The-Fly Settings Changes - -Cthulhu has a number of keyboard commands to temporarily change settings such as speech rate, pitch, -volume; capitalization style; punctuation level; etc., etc. The question is: how long should -on-the-fly modifications to settings persist? - -Early on in Cthulhu's development, the conclusion was that on-the-fly settings changes should be -seen as quite temporary, presumed to be used to address a specific one-time need. For instance, -if reading some difficult-to-understand text, one might want to reduce the speed just for that text. -If one were doing a final proofread of some content, one might want to briefly set the punctuation -level to all. If one needs slow speed and/or verbose punctuation all the time, those should be set -in Cthulhu's Preferences dialogs -- either globally or on a per-app basis. Cthulhu also has a profile -feature through which the user can save settings and quickly load/unload them by switching profiles*. - -Whether or not that historical decision was the right decision goes beyond the scope of the -Remote Controller. The primary purpose of the Remote Controller is to provide D-Bus access to -commands and runtime settings as if they were performed by the user via keyboard command. Thus if -a setting changed via Remote Controller persists (or fails to persist) in the same way as when -changed via keyboard command, it is not a Remote Controller bug. (It may be a general Cthulhu -bug or feature request, and you are encouraged to file it as such.) On the other hand, if the -behavior of the Remote Controller differs from that of the corresponding or related keyboard -command, please report that Remote Controller failure as a new bug in Cthulhu's issue tracker. - -\* *Note: Remote Controller support for profile management is still pending.* diff --git a/README.md b/README.md index e0ed570..6cdfa6f 100644 --- a/README.md +++ b/README.md @@ -1,294 +1,445 @@ -# Cthulhu +# Cthulhu -## Note +Cthulhu is a Linux screen reader written in Go. -Cthulhu is a fork of the Orca screen reader. Project home: https://git.stormux.org/storm/cthulhu. Cthulhu is currently a supplemental screen reader that fills a niche for some advanced users. For example, some older Qt-based programs may work with Cthulhu, and if you use certain window managers like i3, Mozilla applications like Firefox and Thunderbird may work better. +- [Repository Guidelines](AGENTS.md): layout, commands, and working safeguards. +- [Contributing](CONTRIBUTING.md): development, accessibility verification, licensing, and the AI-assisted contribution policy. +- [LibreOffice support](LIBREOFFICE_SUPPORT.md): integration boundaries, initial Calc behavior, remaining work, and verification. +- [Progress reporting](PROGRESS_BARS.md): web progress bars, Steam shader processing, and verification. +- [Steam keyboard focus](STEAM_FOCUS.md): Xorg workspace focus recovery and verification. +- [Flatpak foreground accessibility](docs/testing/flatpak-foreground.md): process identity and proxy matching, tests, and live acceptance. +- [Background event filtering](docs/testing/background-events.md): early foreground checks, notification exceptions, and performance verification. +- [Qt control states](docs/testing/qt-control-states.md): menu checkability, native regressions, and the Qt 5 provider limitation. +- [Tentacle reader settings API](docs/tentacle-reader-settings.md): contributed preferences pages, quick settings, speech overrides, and verification. -## Current Maintenance +AI-assisted contributions are welcome. Contributors remain responsible for human review and testing before submission; see the [full policy](CONTRIBUTING.md#ai-assisted-contributions). -Cthulhu is currently maintained by Storm Dragon. +## Login greeter settings -Current contributors called out in this fork's documentation: - -- Hunter Joziak -- Harley Richardson (`destructatron`) - -## Project History - -Cthulhu is forked from Orca and builds on many years of upstream work by the Orca community, including former maintainers and contributors such as Joanmarie Diggs and others. - -Those upstream maintainers and contributors are part of the project's history, but they are not current maintainers of this fork unless explicitly noted elsewhere. - - -## Introduction - -Cthulhu is a free, open source, flexible, and extensible screen reader -that provides access to the graphical desktop via user-customizable -combinations of speech and/or braille. - -Cthulhu works with applications and toolkits that support the assistive -technology service provider interface (AT-SPI), which is the primary -assistive technology infrastructure for the Solaris and Linux -operating environments. Applications and toolkits supporting the -AT-SPI include the GNOME GTK+ toolkit, the Java platform's Swing -toolkit, OpenOffice/LibreOffice, Gecko, WebKitGtk, and KDE Qt toolkit. - -## Key Features - -### Desktop-Agnostic Design -- **Universal compatibility**: Works on KDE, XFCE, i3, Sway, and other desktop environments -- **Minimal GNOME dependencies**: Reduced reliance on GNOME-specific libraries -- **Tiling window manager optimized**: Enhanced support for i3, Sway, and similar WMs - -### Plugin System -- **Extensible architecture**: Plugin system using pluggy framework -- **Hot-reloadable plugins**: Add functionality without restarting -- **Community plugins**: User and system plugin directories -- **Plugin preferences**: Plugins can provide preferences pages that appear only when the plugin is active - -### Remote Control -- **D-Bus interface**: External control via D-Bus service -- **API access**: Remote access to Cthulhu functions and settings -- **Automation support**: Script-friendly remote control - -### Sleep Mode -- **Application-specific**: Disable speech/events per application -- **Toggle keybinding**: `Cthulhu+Ctrl+Alt+Shift+Q` -- **Preserves exit key**: Only sleep toggle remains active - -### Self-Voicing -- **Unix socket interface**: Direct speech output via `${XDG_RUNTIME_DIR}/cthulhu.sock` -- **External integration**: Other applications can speak through Cthulhu -- **Simple protocol**: `echo "text" | socat - UNIX-CLIENT:"${XDG_RUNTIME_DIR}/cthulhu.sock"` - -### Wine And Proton -- **Standard controls**: MSAA events with Win32 class/message fallbacks for controls Wine leaves empty -- **Unmodified clients**: Implements the NVDA Controller RPC endpoint used by the official controller DLLs -- **Tolk compatibility**: Provides the NVDA detection window expected by the official `Tolk.dll` -- **Prefix management**: Runs one helper per active same-user Wine or Proton prefix and preserves Proton's loader - -The built-in Wine Accessibility plugin is enabled by default when the helper is installed. Its -preferences page controls automatic prefix management, standard-control reading, and controller -compatibility independently. Custom-drawn game interfaces are not made accessible by this bridge. -See [Wine accessibility](docs/wine-accessibility.md) for build and protocol details. - -## D-Bus Remote Controller - -Cthulhu exposes a D-Bus service for external automation and integrations. - -### Service Details -- **Service Name**: `org.stormux.Cthulhu1.Service` -- **Main Object Path**: `/org/stormux/Cthulhu1/Service` -- **Module Object Paths**: `/org/stormux/Cthulhu1/Service/` -- **Module Interfaces**: `org.stormux.Cthulhu1.` - -### Discovering Capabilities - -```bash -# List registered module object paths and introspect their methods/properties -gdbus introspect --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service --recurse - -# Inspect one module -gdbus introspect --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/ModuleName -``` - -### Plugin Modules - -Plugins that expose D-Bus decorators are automatically registered as modules using the naming -convention `Plugin_` (for example, `Plugin_GameMode`, `Plugin_WindowTitleReader`). - -### PluginSystemManager Module - -The `PluginSystemManager` module provides **session-only** plugin control (no preference changes): - -- `ListPlugins` -- `ListActivePlugins` -- `IsPluginActive` -- `SetPluginActive` -- `RescanPlugins` - -### Plugin Preferences Pages - -Plugins can add their own Preferences tab without modifying Cthulhu core code. -Implement `getPreferencesGUI()` to return a Gtk widget (or `(widget, label)`), -and `getPreferencesFromGUI()` to return a settings dict. The tab appears only -when the plugin is active. - -### More Documentation - -See `README-REMOTE-CONTROLLER.md` and `REMOTE-CONTROLLER-COMMANDS.md` for the full D-Bus API -and usage examples. - -## Dependencies - -### Core Requirements - -* **Python 3.9+** - Python platform -* **pygobject-3.0** - Python bindings for the GObject library -* **gtk+-3.0** - GTK+ toolkit (minimal usage for AT-SPI integration) -* **AT-SPI2** - Assistive Technology Service Provider Interface -* **ATK** - Accessibility Toolkit - -### Desktop-Neutral Features - -* **pluggy** - Plugin and hook calling mechanisms for Python -* **python-dasbus** - D-Bus remote control interface (optional) - -### Audio and Speech - -* **python-speechd** - Python bindings for Speech Dispatcher (recommended) -* **gstreamer-1.0** - GStreamer streaming media framework (for sounds) -* **piper-tts** - Piper neural text-to-speech engine (optional) - -Piper voice models are typically stored under `~/.local/share/piper/voices` or -`/usr/share/piper-voices`. - -### Braille Support (Optional) - -* **BrlTTY** - BrlTTY () braille terminal support -* **BrlAPI** - BrlAPI Python bindings for braille -* **liblouis** - Liblouis () contracted braille translation - -### System Integration - -* **py-setproctitle** - Python library to set the process title (optional) -* **socat** - Used for self-voicing functionality -* **xorg-xkbcomp** - X keyboard compiler (for key remapping) -* **xorg-xmodmap** - X modifier map utility - -You are strongly encouraged to also have the latest stable versions -of AT-SPI2 and ATK. - - -## Braille - -Cthulhu depends upon the Python bindings for BrlAPI available in BrlTTY v4.5 -or better. You can determine if the Python bindings for BrlAPI are -installed by running the following command: +Copy your saved active profile into the LightDM account's default Cthulhu +settings location, without starting or replacing a reader: ```sh -python -c "import brlapi" +cthulhu --greeter lightdm ``` -If you get an error, the Python bindings for BrlAPI are not installed. +Run this as your normal user. Cthulhu requests sudo authentication to run the +copy as the `lightdm` account. It discovers that account's home directory and +writes `.local/share/cthulhu/user-settings-go.toml` there, creating directories +as needed. The destination belongs to that account and has mode `0600`. +Cthulhu must be installed where the greeter account can execute it. +LightDM's default greeter account is `lightdm`; custom greeter accounts are +not currently supported. -## Running Cthulhu +Use `cthulhu --greeter lightdm --config FILE` to copy from an alternative +configuration. Your normal configuration remains unchanged. The copy contains +one complete active profile, including speech, Braille and keyboard preferences; +application profiles and Tentacles are not copied. Save preferences first: +unsaved changes are not included. Repeating the command updates the installed +settings. A missing source file selects built-in defaults, as at normal startup. -If you wish to modify your Cthulhu preferences, you can press "Insert+space" -while Cthulhu is running. +Configure the LightDM GTK greeter's reader command as +`cthulhu --no-tentacles` so it uses that account's default settings. Remove any +explicit `--config` path from an existing reader command to use the new location. +Changes take effect when the greeter reader next starts. -To get help while running Cthulhu, press "Insert+H". This will enable -"learn mode", which provides a spoken and brailled description of what -various keyboard and braille input device actions will do. To exit -learn mode, press "Escape." Finally, the preferences dialog contains -a "Key Bindings" tab that lists the keyboard binding for Cthulhu. +The greeter account needs its own accessibility bus and working audio setup. +Selected voices, Braille tables and custom sound assets must also be installed +and readable by that account. The command copies settings; it does not configure +LightDM or audio, restart a reader, or create a restricted login mode. -For more information, see the Cthulhu documentation which is available -within Cthulhu. +Native X11 grab-window regression: +`python3 tests/native_test_session.py env CTHULHU_NATIVE_GRAB_FOREGROUND=1 go test ./internal/platform/xorg -run '^TestNativeInputOnlyGrabForeground$' -count=1`. -## Scripting Cthulhu +## Speech preferences -So, you want to write a script for Cthulhu? The best thing to do is -start by looking at other scripts under the src/cthulhu/scripts/ hierarchy -of the source tree. Cthulhu also has an excellent plugin system, more documentation and examples coming soon. +Speech preferences let you adjust rate, pitch and volume directly, without +first disabling a default checkbox. Unconfigured values display Speech +Dispatcher's defaults when available, or rate 50, pitch 5 and volume 5. +Adjusting a slider creates an explicit setting; untouched values retain their +inheritance, including automatic Uppercase pitch. Apply saves the changes; +Cancel restores the last applied voice. See +[speech preferences verification](docs/testing/speech-preferences.md). -## Building and Installation +## Speech interruption -### Prerequisites +Incoming announcements queue in order. Focus, selection, state changes, +notifications, tooltips and terminal output let earlier speech finish. +Passive announcements also queue behind Say All. By default, a new key press +or reader command stops earlier speech and clears its pending announcements. +Delayed copies of the key that started a command preserve that command's response. -Ensure you have the development dependencies installed: +The Speech tab in Preferences offers **All keys interrupt**, **Control, Enter, +Space, and Escape**, and **Define interruption keys**. The second choice includes +both Control keys and the keypad Enter key. These choices apply immediately +after Apply and are saved with the profile. Key echo remains independent; +reader commands and explicit stop requests still interrupt speech in every mode. -**Arch Linux:** -```bash -sudo pacman -S python python-gobject gtk3 at-spi2-core at-spi2-atk \ - python-speechd gstreamer python-pluggy python-dasbus \ - python-tomlkit \ - meson ninja pkgconf intltool gettext +For custom keys, select **Define interruption keys**, then activate **Record +interruption keys**. Press the individual keys to record, including Tab, Enter, +Space or Escape. Press and release a modifier separately to record it; left and +right modifiers can be selected independently. **Control+Enter** finishes and +**Control+Escape** cancels. Neither finishing nor cancelling adds its Control +key to the list. There is no timer. Recording replaces the previous list when +finished and requires at least one key. Duplicate keys are ignored. Focus +returns to the recording button, and the read-only **Defined interruption keys** +field displays the result. Tab and Shift+Tab work normally outside recording. + +Screen lock, shutdown, speech configuration changes and explicit stop requests +retain their lifecycle behavior. Existing Tentacle requests marked +uninterruptible retain their bounded protection. The speech queue remains +bounded against excessive output. +See [speech queue verification](docs/testing/speech-queue.md) for automated +checks and the listening procedure. + +## Key echo + +The Key Echo preferences page offers three radio choices: Disable key echo, +Enable key echo, and Key echo in edit fields. The last choice limits typing +and key-name echo to writable edit controls. It uses the existing key categories +and custom echo voice settings, and Apply takes effect immediately. Existing +configurations keep their previous enabled or disabled behavior. The new setting +is `edit-fields-only` in the profile's `key-echo` table. + +Enable **Use custom echo voice** to choose the echo synthesizer, voice, rate, +pitch and volume. The synthesizer starts with the main speech synthesizer unless +a separate echo synthesizer was previously configured. No additional synthesizer +checkbox is needed. Under **Use the custom voice for:**, choose **Key names** +(such as Enter, Shift and arrows), **Typed characters**, **Words** or **Sentences**. +These choices select the voice; the corresponding echo settings still control +what is spoken. Turn off custom echo voice to use the main speech settings. + +Key names finish before the resulting navigation or focus announcement starts. +For example, Right speaks "right" in the selected key echo voice, followed by +the character at the caret in the normal reading voice. A configured interruption +key still interrupts the previous key's speech and discards its pending feedback. + +Changing the custom echo synthesizer, person, rate, pitch or volume speaks the +selected value using the echo voice and its draft settings, before Apply. +Tab and Shift+Tab announce the field label in the main voice, followed by its +current value in the echo voice. Other controls use the main voice. +Apply saves the changes; Cancel restores the previous settings. + +For the combined reader, GTK and recorded-speech regression check, build a test +binary and run `CTHULHU_BINARY=/path/to/test-binary CTHULHU_PREFS_ECHO_RUNTIME_ONLY=1 /usr/bin/python3 tests/native_preferences.py`. +This uses private Xvfb, D-Bus and SSIP services. Live listening still needs a +separate check: Tab and Shift+Tab across all five fields, change synthesizer +and person with arrows and their popups, and confirm labels use the main voice +while values finish in the selected echo voice. + +Native controls must expose editable accessibility metadata. This includes +standard entries, text editors and editable browser controls. Read-only fields, +password contents, buttons, menus and terminals do not enable this mode. Controls +that omit editable metadata stay quiet. Pasted text, terminal output containing +multiple characters, live regions, navigation and deletion feedback retain their +existing presentation rules; those announcements are distinct from key echo. + +Wine Access supplies edit-control focus and typing feedback, including standard +Edit controls and its supported Scintilla editors. Key-name echo also requires +matching current X11 foreground metadata; without that evidence it stays quiet. +Wine insertion feedback uses the custom key voice when character echo is off, +and the custom character voice when character echo is on. + +## Capital letters + +Speech preferences group three independent checkboxes under Capital letters: +Raise pitch for capital letters (on by default), Beep for capital letters, +and Say “cap” before capital letters (both off by default). Any combination, +including all off, is supported. These settings apply to character navigation, +spelling, and typing feedback, including a custom key echo voice. Word and line +reading keep their normal presentation. + +The beep matches NVDA's generated 2000 Hz, 50 ms capital-letter tone. It uses +the Sounds volume and audio backend, independently of role sounds and themes. +The pitch checkbox enables the existing Uppercase voice pitch. That voice +uses automatic adjustment until an explicit pitch is set with its slider. Apply +changes the running reader, and saved choices survive restart and can be set +per application. Older capitalization styles are imported into the corresponding +beep or “cap” checkbox. + +## Reading settings descriptions + +Under Speech, the Reading settings table has three columns: Enabled, Setting +and Description. Each description explains what the checkbox changes, with +examples where useful. Use Left and Right to read individual cells and Space +to toggle the selected setting from any column. With full-row reading enabled, +moving between rows reads the state, title and description together. Further +input interrupts speech as usual. + +See [reading settings verification](docs/testing/reading-settings.md) for +automated checks and live listening steps. + +## Flat review spelling and phonetic hints + +Press Numpad 2 twice to hear the current character phonetically. Press Numpad 5 +once to read the current word, twice to spell it, or three times to spell it +phonetically. Numpad 8 provides the same three choices for the current line. +Successive presses must be within 500 milliseconds. Single presses speak +immediately. Laptop equivalents are Cthulhu+Comma, Cthulhu+K and Cthulhu+I. + +Under Speech → Reading settings, **Phonetic character hints** is off by default. +Enable it to hear a phonetic letter about 300 milliseconds after a character +spoken by plain Left or Right, for example “a … alpha”. Further input cancels +the pending hint. Selection, word navigation, Home/End and typing echo do not +add hints. Spaces, punctuation and letters without a phonetic name keep their +normal announcements. This applies to native text controls, browser character +navigation and supported Wine editor character navigation. +The delayed hint uses the normal voice without repeating capital beeps, pitch +changes or “cap”. Explicit phonetic review commands retain capital indicators. + +See [phonetic review verification](docs/testing/phonetic-review.md) for checks +and live listening steps. + +## Read the current line + +Press **Cthulhu+Shift+Up** in either keyboard layout to read the line at the +application caret in native AT-SPI controls, or at the browse cursor on a webpage +in browse mode. +Press twice within 500 milliseconds to spell the line, or three times for +phonetics. The command leaves the caret and flat-review position in place. +Empty lines say “blank”; password contents are never read. Controls without +a text interface read their accessible name. Cthulhu+Up still increases the +selected speech setting. + +This follows NVDA's desktop NVDA+Up current-line command, rather than replaying +the last spoken message. Numpad 8 (laptop: Cthulhu+I) continues to read the +independent flat-review line. +See [current-line verification](docs/testing/current-line.md) for checks. + +## Read the current window title + +Press **Cthulhu+Numpad Enter** in the desktop keyboard layout, or +**Cthulhu+Slash** in the laptop layout, to read the current window title. +In a browser this normally includes the active page title. The command also +flashes the title on Braille when flash messages are enabled. It works with +automatic title announcements disabled and can repeat the same title without +moving focus or the browser reading position. + +These bindings match Orca's title command. Plain **Numpad Enter** on desktop +and **Cthulhu+Enter** on laptop retain their Where Am I behavior. Repeated title +commands read the title again; a double press does not read the status bar. +See [window title checks](tests/window_titles.md) for verification. + +## Browser button updates + +Web buttons announce their current label when focused. Automatic label changes +wait for 350 milliseconds without another change before speaking, so a rapidly +updating counter does not continually interrupt reading. Braille receives each +update immediately. Moving focus, navigating, changing tabs or windows, and +locking the session discard pending announcements. Live regions retain their +existing announcement behavior. + +Debug logging with `--debug-file PATH` replaces any existing log at that path. +Add `--append` to preserve earlier sessions, for example +`cthulhu --debug-file /tmp/cthulhu.log --append`. +`--append` requires `--debug-file`. A log can still grow during a long session. + +For browser bug reports, start Cthulhu with `--debug-file /tmp/cthulhu-browser.log` +and reproduce the affected navigation. The startup record includes the release +version, embedded Git revision and modified-build status, Go and AT-SPI versions, +and session information. Builds without Go VCS stamps report `unknown`; a +modified build identifies its base commit, not the exact uncommitted changes. +Display availability does not establish whether the browser uses native Wayland +or XWayland. Include the browser version and its actual display backend separately. + +Navigation records include focus and document identities, the cursor before and +after focus synchronization and movement, recovery decisions, capture attempts, +errors and structural-navigation wrapping. For example, `preserved` retains the +saved position, `replaced-text-child` recovers a replacement under its surviving +parent, and `saved-object-missing` falls back to native focus. These records help +distinguish a cursor reset from an intentional wrap without extra native queries. +Review debug logs before sharing: they also contain spoken page text. + +When the browser confirms that a navigation target no longer exists, Cthulhu +retires the cached object and refreshes its parent's child list. It retries +caret placement only if the same target survives the refresh. Otherwise the +move reports a location failure; repeat the navigation command to find a live +target from the retained browser focus. An ordinary native caret refusal still +allows a successful virtual reading move. + +## Wine Access + +Install the separate `wine-access` helper for Wine application accessibility. +Cthulhu checks `CTHULHU_WINE_ACCESS_HELPER`, then +`~/.local/libexec/wine-access/wine-access.exe`, +`/usr/local/libexec/wine-access/wine-access.exe`, +`/usr/libexec/wine-access/wine-access.exe`, and `wine-access.exe` on `PATH`. +The existing `cthulhu-wine-access.exe` lookup remains supported: the old user +location follows the new user location, the old `/usr` location follows the new +system locations, and the old name on `PATH` follows the new name. +Restart Cthulhu after changing the selected helper. Keep the launcher, its +`.exe.so` sidecar, and the native hooks together in the installed directory. + +With an updated Wine Access helper, the log records the running helper's +embedded release version, Git revision and modified-build flag, followed by +initialization status for its workers, hooks, controller and control poll. +The process-start message alone does not establish successful initialization. +Debug logs also identify the selected executable, Wine loader and prefix; +check those paths for an older local copy when machines behave differently. +Helpers built before identity reporting do not provide these identity/status +records. The installed helper's `--version` option can be used for a manual +check; it does not require a running reader. + +`cthulhu -v`, `cthulhu --version`, and **Cthulhu+Shift+V** append +`wine-access YYYY.MM.DD` when the selected installed helper contains release +metadata. This reads its `.exe.so` sidecar directly without starting Wine. +Rebuild Wine Access to supply the metadata; older helpers are omitted. +The reported release describes the installed files, which can differ from a +helper still running after an upgrade. + +Helper-prefixed stderr diagnostics are captured with a 4096-byte line limit, +a 64-record queue and up to 32 distinct records per ten-second window. Repeated, +oversized and excess records are counted in a suppression notice. Unrelated +Wine/application stderr is ignored. Capture does not log accessible control +contents or change speech delivery; output already present in debug speech +logs can still contain private text. Review debug logs before sharing them. + +The standalone helper currently installs under the compatible name +`~/.local/libexec/cthulhu/wine/cthulhu-wine-access.exe`. Its complete installation +contains the launcher, `cthulhu-wine-access.exe.so`, `wine-access-menu.dll`, +`wine-access-menu32.dll`, and `wine-access-menu-host32.exe`. The 32-bit host +supplies native menu and editor feedback for applications such as MUSHclient. + +Older Python Cthulhu builds can overwrite the helper launcher and sidecar in +that same directory while leaving the standalone hook files behind. The old +helper can still run and connect to Cthulhu without providing the standalone +menu and editor hooks. If Wine reading disappears after installing an older +Cthulhu build, rebuild and reinstall the separate `wine-access` project, then +reload Cthulhu from the same desktop session. If a Wine application already +loaded a previous hook DLL, save its work and restart it to load the replacement. +See [local installation and reload](CONTRIBUTING.md#local-installation-and-reload) +for the Go reader commands. + +Wine typing feedback in standard Edit controls follows the current key echo +settings, including the master switch, character echo, and alphabetic, numeric, +punctuation, space and diacritical categories. Tabs and line breaks follow +key echo's action-key setting. Applying preferences takes effect without +restarting the helper. Navigation, selection and deletion feedback remain +available when typing echo is disabled. Word and sentence typing echo are not +currently supplied by the Wine helper. + +For a live check, type repeated letters, numbers, punctuation and spaces in +Wine Notepad, change the corresponding echo settings and apply them, then +continue typing. Disable key echo and verify that typing stays quiet while +arrows, selection and Backspace still report editing feedback. Re-enable it +and check capital/lowercase voices and password exclusion. Automated tests +cover queued speech and Braille; audible speech and a physical Braille display +still require live verification. + +## Tentacle process supervision + +Installed Tentacles run as the current user and require no administrator setup or +particular init system. Each session has a private Linux subreaper helper. The +helper watches a reader-owned lifetime pipe and terminates and reaps its child +and detached descendants when the session ends, including abrupt reader exit. +Exited orphaned descendants are also reaped while the Tentacle remains active. +Installation and enabling report success only after registration, keyboard +shortcut setup and activation succeed. A failed start leaves the installed +package disabled, with an error in Preferences; enabling it again retries. +Enabling an already enabled Tentacle restarts it if its session has failed. +Cancelling startup during shortcut setup restores the other Tentacles' shortcuts. + +Only install Tentacles from publishers you trust. They inherit your account's +file and network access. Protocol sizes, request deadlines and host admission +limits always apply. CPU, memory and task limits require an explicitly configured, +writable cgroup v2 parent with the `cpu`, `memory` and `pids` controllers enabled. +Set `CTHULHU_TENTACLE_CGROUP_PARENT` or pass +`--tentacle-cgroup-parent /absolute/delegated/parent` to opt in. Provisioning that +parent is an administrator or session-launcher responsibility, independent of +any init system. An invalid explicit parent fails startup rather than silently +ignoring the requested limits. Without that configuration, supervision works +without kernel resource quotas; it does not provide a security sandbox. + +## Browser navigation + +Browser element lists use **Alt+Shift** plus the structural navigation +key: **K** for links, **A** for clickables, **H** for headings, and **1–6** for +headings at a specific level. Use arrows or type a name to select an item, +Enter to move to it, and Escape to cancel. See [browser element lists](docs/testing/browser-lists.md) +for every list shortcut and verification steps. + +Heading and browse-caret commands retain the virtual reading position while +the browser reports delayed native caret events. Each reader command takes +ownership before its result arrives. Native keyboard input, text selection, +pointer presses, document loads and leaving the document release that ownership. +An unsuccessful native caret placement does not undo a successful virtual move. + +When a page replaces a plain text child in a paragraph, heading, section or +ordinary link, navigation can retain its offset through the same surviving +parent and document generation. With multiple children, the replacement must +remain between the same generation-checked adjacent siblings (or the same +start/end boundary). +This prevents repeatedly restarting a paragraph when an inline text object is +recreated. No text-label matching is used to guess a replacement. +This includes CSS-generated link prefixes such as `::before`, which browsers +can recreate when placing the native caret. Explicitly named links retain their +separate label-navigation behavior. Recovery never transfers an activation to +a replacement link. +Read All uses navigation recovery too, and stops if the document generation +changes. Text that disappears during a native read requires a refresh rather +than silently losing that part of the line. +When a larger subtree disappears, navigation can restart within its nearest +surviving noninteractive container. Ambiguous children, editable controls and +replaced parents do not inherit the old offset. Removing a native focus anchor +does not reset a still-valid virtual reading position elsewhere in that document. +Verify repeated native replacements, forward/reverse lines and subsequent +Read All with +`CTHULHU_NATIVE_BROWSER_TESTS=replacement,generatedlinks python3 tests/native_browser.py`. + +Explicitly named links retain their complete accessible label when reading by +line. Left/Right, Ctrl+Left/Right, and Home/End review that label by character, +word, or boundary, including links with no native text or only a numeric badge. +The label's review position remains separate from the browser's text caret. + +Browse arrows, word navigation and Read All skip non-focusable, non-editable +tooltips and their contents. This avoids repeatedly entering a tooltip that +disappears when native caret placement moves focus away from its owner. +Focusable or editable tooltip contents remain navigable. Verify the native +focus-triggered case with +`CTHULHU_NATIVE_BROWSER_TESTS=tooltips python3 tests/native_browser.py`. + +Enter activates the current link or clickable, including explicitly named custom +controls and clickable ancestors of ordinary text. Activation itself is silent +whether it succeeds or fails; the page's own focus changes and live regions still +speak. Ordinary text does not cause an unnecessary document recapture. A removed +target or replaced document cannot silently substitute a different action. + +Successful virtual navigation presents the requested content even if the browser +refuses native caret placement; synchronization failures remain in diagnostic logs. +Stale native placement gets one refresh and retry at the same target and offset. +Braille routing also recognizes the temporary caret produced by clearing a +selection, so it cannot reset the routed reading position. + +Reading a final ellipsis avoids the provider's native line-boundary request: +Chromium can calculate a boundary past truncated text and abort the browser. +At that character, Cthulhu reads a bounded logical line using explicit line +breaks; visual wrapping may be combined. Ordinary line, character and word +navigation retain their existing boundaries. The regression checks are +`go test ./internal/atspi -run TestTextBoundaryAvoidsProviderEllipsisAbort` +and `CTHULHU_NATIVE_BROWSER_TESTS=lines python3 tests/native_browser.py`. + +Browse-mode arrows and Read All include text inside embedded editors. Reading +continues through the editor's paragraphs before reaching the following page +content. + +Native menu rows can contain several controls. Up and Down announce those +controls individually, including Brave's Sidebar choices and Zoom controls. +Check this workflow with `CTHULHU_NATIVE_BROWSER_TESTS=menu python3 tests/native_browser.py`. + +See [browser release review](docs/testing/browser-release-review.md) for findings, +automated checks and remaining live acceptance. + +The generic changing-document regression starts a private reader, browser +profile, X display, accessibility bus and speech protocol recorder: + +```sh +go build -o /tmp/cthulhu-browser-review ./cmd/cthulhu +CTHULHU_BINARY=/tmp/cthulhu-browser-review python3 tests/native_browser_navigation.py +CTHULHU_NATIVE_BROWSER_TESTS=pointer,positions,dynamic,linkedheadings,document,editing,selection,tabs,modes python3 tests/native_browser.py ``` -**Debian/Ubuntu:** -```bash -sudo apt install python3 python3-gi python3-gi-cairo gir1.2-gtk-3.0 \ - at-spi2-core libatk-adaptor python3-speechd \ - gstreamer1.0-plugins-base python3-pluggy python3-dasbus \ - python3-tomlkit \ - meson ninja-build pkg-config intltool gettext -``` - -### Local Development Build (Recommended) - -For active development, build and install to your user directory: - -```bash -# Build and install to ~/.local -./build-local.sh - -# Test the local installation -./test-local.sh - -# Run your local version -~/.local/bin/cthulhu - -# Clean build artifacts and local installation -./clean-local.sh -``` - -This approach: -- Installs to `~/.local/bin/cthulhu` (won't conflict with system installation) -- Loads modules from `~/.local/lib/python*/site-packages/cthulhu/` -- Preserves any system-wide Cthulhu installation at `/usr/bin/cthulhu` - -### System Installation - -For system-wide installation: - -```bash -# Configure the build -meson setup _build --prefix=/usr - -# Compile -meson compile -C _build - -# Install (requires sudo) -sudo meson install -C _build -``` - -### Manual Meson Build - -If you prefer to use Meson commands directly instead of the convenience scripts: - -```bash -# Configure for local installation -meson setup _build --prefix=$HOME/.local - -# Or configure for system installation -meson setup _build --prefix=/usr - -# Compile -meson compile -C _build - -# Install -meson install -C _build - -# Clean -rm -rf _build -``` - -### Testing - -Manual testing is recommended. The legacy keystroke-driven test harness has been removed. - -## Self-voicing - -Cthulhu offers a mechanism through which messages may be spoken directly by the screen reader. Usage is as follows: - -```bash -# Speak hello world. -echo "Hello world." | socat - UNIX-CLIENT:"${XDG_RUNTIME_DIR}/cthulhu.sock" -# Speak Hello world without interrupting the previous speech. -echo "<#APPEND#>Hello world." | socat - UNIX-CLIENT:"${XDG_RUNTIME_DIR}/cthulhu.sock" -# Make hello world persistent in Braille. -echo "Hello world.<#PERSISTENT#>" | socat - UNIX-CLIENT:"${XDG_RUNTIME_DIR}/cthulhu.sock" -``` +These checks leave the desktop reader unchanged. They verify synthetic X11 +input and recorded speech requests; real-page listening, physical keyboard +and Braille checks remain necessary. On an updating page, traverse headings in +both directions, pause and continue, read changing lines with arrows and word +commands, then verify Tab, selection, editable fields and browser chrome. diff --git a/RELEASE-HOWTO b/RELEASE-HOWTO deleted file mode 100644 index f12a39f..0000000 --- a/RELEASE-HOWTO +++ /dev/null @@ -1,55 +0,0 @@ -This document provides a step-by-step reminder for making a Cthulhu release. - -PREPARE SOURCES: ----------------- - -Make sure you are up to date and clean: - - git pull - git status - -Decide the release version: - - - Update the version in `meson.build` - - Update the version in `src/cthulhu/cthulhuVersion.py` - -Update release notes: - - - Update `NEWS` (or your preferred changelog location) with user-visible changes. - - -BUILD + SANITY CHECK: ---------------------- - -Build with Meson: - - meson setup _build_release --prefix=/usr --buildtype=release - meson compile -C _build_release - -Optional sanity checks: - - python3 -m compileall -q src/cthulhu - meson test -C _build_release # may be empty - -Create a source tarball: - - meson dist -C _build_release - - -TAG + PUSH: ------------ - -Commit release changes, tag, and push: - - git commit -a - git push - git tag -a v - git push origin v - - -PACKAGING NOTES: ----------------- - -Arch packaging lives in `distro-packages/Arch-Linux/PKGBUILD`. -If the package version is derived from `src/cthulhu/cthulhuVersion.py`, -ensure that file matches the release version. diff --git a/REMOTE-CONTROLLER-COMMANDS.md b/REMOTE-CONTROLLER-COMMANDS.md deleted file mode 100644 index 79cb094..0000000 --- a/REMOTE-CONTROLLER-COMMANDS.md +++ /dev/null @@ -1,133 +0,0 @@ -# Cthulhu Remote Controller - Available Commands - -This documentation covers the Cthulhu fork maintained by Storm Dragon. -Cthulhu is forked from Orca; former Orca maintainers and contributors are part -of the project's upstream history, but they are not current maintainers of -this fork. - -This document lists the currently available D-Bus commands in Cthulhu's Remote Controller interface. - -> **Note**: This is a work-in-progress. As more modules are exposed via D-Bus, this document will be expanded. Eventually this will be auto-generated using `tools/generate_dbus_documentation.py`. - -## Service-Level Commands - -Available on the main service object `/org/stormux/Cthulhu1/Service`: - -### Service Commands - -| Command | Description | Parameters | Returns | -|---------|-------------|------------|---------| -| `GetVersion` | Returns Cthulhu's version string | None | String (version + revision) | -| `PresentMessage` | Present a message via speech/braille | `message` (string) | Boolean (success) | -| `ShowPreferences` | Opens Cthulhu's preferences GUI | None | Boolean (success) | -| `Quit` | Exits Cthulhu | None | Boolean (accepted) | - -### Example Usage - -```bash -# Get Cthulhu version -busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \ - org.stormux.Cthulhu1.Service GetVersion - -# Present a custom message -busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \ - org.stormux.Cthulhu1.Service PresentMessage s "Hello from D-Bus" - -# Open preferences -busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \ - org.stormux.Cthulhu1.Service ShowPreferences - -# Quit Cthulhu -busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \ - org.stormux.Cthulhu1.Service Quit -``` - -## Module-Level Commands - -Module-level commands and properties are discovered with standard DBus introspection: - -```bash -gdbus introspect --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service --recurse -``` - -Two key additions are: - -### PluginSystemManager - -Session-only plugin control (does not persist preferences): - -- `ListPlugins` -- `ListActivePlugins` -- `IsPluginActive` -- `SetPluginActive` -- `RescanPlugins` - -### Plugin Modules - -Plugins that expose D-Bus decorators are automatically registered as modules using the naming -convention `Plugin_` (e.g., `Plugin_GameMode`, `Plugin_WindowTitleReader`). - -#### WindowTitleReader (Plugin_WindowTitleReader) - -- `SetEnabled` -> enabled (bool), notify_user (bool) -- `Enabled` (property) - -Example: - -```bash -gdbus call --session --dest org.stormux.Cthulhu1.Service \ - --object-path /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \ - --method org.stormux.Cthulhu1.Plugin_WindowTitleReader.SetEnabled true false -``` - -Busctl example: - -```bash -busctl --user call org.stormux.Cthulhu1.Service \ - /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \ - org.stormux.Cthulhu1.Plugin_WindowTitleReader SetEnabled bb true false -``` - -# Check current state -busctl --user call org.stormux.Cthulhu1.Service \ - /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \ - org.freedesktop.DBus.Properties Get ss \ - org.stormux.Cthulhu1.Plugin_WindowTitleReader Enabled - -See [README-REMOTE-CONTROLLER.md](README-REMOTE-CONTROLLER.md) for comprehensive D-Bus API documentation and usage examples. - -## Verifying D-Bus Service Status - -```bash -# Check if Cthulhu's D-Bus service is running -busctl --user list | grep Cthulhu - -# Introspect the service to see available module nodes -busctl --user introspect org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service - -# Introspect a module to see its methods and properties -busctl --user introspect org.stormux.Cthulhu1.Service \ - /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader - -# Get detailed service information -busctl --user status org.stormux.Cthulhu1.Service -``` - -## Contributing - -To add new D-Bus-accessible functionality: - -1. Add `@dbus_service.command`, `@dbus_service.getter`, or `@dbus_service.setter` decorators to methods -2. Register the module with the D-Bus service in `src/cthulhu/cthulhu.py` -3. Rebuild and test with busctl -4. Update this documentation (or regenerate using `tools/generate_dbus_documentation.py` when available) - -## Desktop Environment Compatibility - -Cthulhu's D-Bus Remote Controller is desktop-agnostic and works across all Linux desktop environments: -- GNOME, KDE Plasma, XFCE, LXDE -- Tiling window managers (i3, Sway, bspwm, etc.) -- Any environment with D-Bus session bus support - -The service uses only standard D-Bus infrastructure with no desktop-specific dependencies. diff --git a/STEAM_FOCUS.md b/STEAM_FOCUS.md new file mode 100644 index 0000000..37e0562 --- /dev/null +++ b/STEAM_FOCUS.md @@ -0,0 +1,67 @@ +# Steam keyboard focus on Xorg + +Steam Big Picture can retain its accessible focus while physical keyboard +events reach the outer Steam window instead of its embedded Chromium window. +In the reported game/workspace round trip, Escape stopped opening or closing +the menu, and switching browse/focus mode did not help. A delivery trace showed +both Escape edges reaching the outer window with no held modifiers. Restoring +native focus to the browser child recovered the open menu without restarting +Steam or Cthulhu. The original trigger remains unverified. + +Cthulhu's Xorg command owner remembers the most recently focused, mapped +browser child of a Steam webhelper window. During the first second after that +window becomes foreground again, it allows Steam to restore its own focus. +Only if two consecutive focus samples still identify the outer window does it +attempt to restore the remembered child. A successful repair ends the attempt +for that activation. + +The repair verifies the foreground window, Steam window class, process IDs, +child ancestry, and mapping state immediately before changing focus. It leaves +valid inner focus alone, including menus, search fields, and dialogs. It does +not run with keys held, reader modal input active, OCR active or pending, or +secure input active. Hidden, destroyed, unrelated, or unverified targets cause +it to leave focus unchanged. It does not guess another child or retain a +hard-coded window ID. The cache holds one Steam window and expires with the +command listener; restarting Cthulhu in an already broken session may require +fresh Steam focus before a valid child can be remembered. + +This is an Xorg Steam workaround. Other applications and native Wayland focus +handling do not receive automatic keyboard-focus changes. + +## Verification + +The policy tests cover activation grace, remembered popup focus, bounded +attempts, process/window boundaries, and preservation of valid browser focus. +The native fixture verifies real Escape press/release delivery after repair and +rejects hidden or destroyed popups, unrelated children, changed process IDs, +held modifiers, other applications, and ordinary window classes. + +```sh +GOCACHE=/tmp/cthulhu-go-cache GOPROXY=off go test -race ./internal/platform/xorg ./internal/app -count=1 +xvfb-run -a env CTHULHU_NATIVE_STEAM_FOCUS=1 GOCACHE=/tmp/cthulhu-go-cache GOPROXY=off go test ./internal/platform/xorg -run '^TestNativeSteamFocusRepair$' -count=1 -v +CTHULHU_NATIVE_BROWSER_TESTS=keys,modes python3 tests/native_browser.py +python3 tests/native_x11.py +``` + +These checks passed for the initial patch. The existing native browser editing +check failed on both the patch and unchanged commit `9205e72`: its first typed +`c` was accompanied by `Cthulhu Browser Probe - Brave`. That separate title +announcement failure was not changed here. + +Human review and live Steam acceptance remain required before submission: + +1. Restart Cthulhu using the normal `cthulhu-go.sh -r` launcher, then start fresh + Steam Big Picture so the reader can observe a valid browser focus. +2. Verify Escape and game activation initially work. Launch a game, switch to + another workspace and back, and verify Escape and game activation again. +3. Repeat with the Steam menu open before switching away. Check Escape closes + it and arrows/Enter still select commands. +4. Type in Steam search, use Tab and Shift+Tab, and move away/back while search + or a dialog has focus. Check text entry, selection, and dialog buttons retain + their intended focus. +5. Switch to a normal browser and a GTK application. Check native typing, + browser structural navigation, and Cthulhu's XTerm/Fenrir handoff. Quit + Cthulhu and confirm normal application keys remain available. + +Do not count a native fixture pass as audible speech, physical Braille, or +successful operation of Steam's actual Chromium/controller navigation. diff --git a/TODO b/TODO deleted file mode 100644 index a2a2fab..0000000 --- a/TODO +++ /dev/null @@ -1,3 +0,0 @@ -- Merge in sleep mode. -- Add in ocrdesktop code so that Cthulhu has native ocr support. -- Get rid of build systems. My hope is git clone and run so long as requirements are satisfied. diff --git a/assets/sounds/default/autocomplete.wav b/assets/sounds/default/autocomplete.wav new file mode 100644 index 0000000000000000000000000000000000000000..61d70df09406bc29cf68f3e32ca57ba3a7af77d7 GIT binary patch literal 9644 zcmWIYbaPvx%D@or80MOmTcRMqz`(%Bz{Jq7n}LDh9TNi!g8)NHVo73yDg#5>v$SVB zpY3?Y^_=^8?DN>?>z}WG&iI1qMaYYg7t3BOd-3zduNOWqyW&hg#_2k!+UO#*N?6u_^t2e!Gdfz;H^YD$yTeG*FZ@b>!dwcJ#;X9*u z?eALO-FkQXoxywk_bu;R-rszG^S#~&y${VFnm^q9aN~pCN4<~DADchk{CM-D?kBxZ zEuWe{-TZX(lm2J@&#j-^KHvU)`?Jv(!!I3Q+P~cUa_@`DSJSWEUwghj{QBst#W#y@ z{of{hd;aa&H@ok)-=}<^^8L;CH{V@;IRBXaWA=|vKR*5N`swv^(a%LcfBpRRGw4^) zuT{TR{bKsf^gHTz)bGu|H~;4O!}BNQPs*RYfA;@5}gC@vjcPI`~TYwesuM z*R8K#yng=L>y6i&HE-6w;eX5jw&-oq+pBM{zO{H~@ox6JIq&|x`}Z#Ked7Bg?~lIM z_@Mcr=R?nj_a8od2>uxIamUB)AEiG@eQNmB@agfVC!gFuyMJE&dG%+(FM?l6zm$Ht z_2uRl`>%Fi7k^#ymE#-7x4dt8-!6T-{LSLK<@dSY=Y41X!TclhN9K=nKhFO!`DyZV z_RrZr8GkYSO8b@e>+G*Hzl?vI{GR!H=5K~SjDOPqr2jel=iDFDzovg@|DFAp`5)82 z%zv5xF8;gt&*Hzu{{{aS{AXw2V9004XSmLAoxz^bo^d(jaz;KTKBjV}a;67N_nADH z-I+HqZ)BEakz{FNX=HiL@`@#dHJEh|>mF7$HZ`_>wtluBY(LnN*b~`Lv!7x&HtIm&aCN1xY#cQ)^A zUN$~9zCyl2zPo&P_}uwD_&4)!=9d$Y7w8h`68I+YT_8y?S@4|TIYBESE1_jV%Y}r5 zg@o&c>xJJ4zZQ-Vi4Zv|a#X}f)DRs1++y5f6=IcQ&%~aI1&arZ9}qt%t|y@!y6@XdiY2j1wt)qgwh?fkd=@A%%;y{mf%0tp6bQQT}89$NrE1KQeqO{8aeq;ipHRf<6a-KK%LcXOl0cUzUDZ_C@@w_}7lF z9bbQa{rNTLTlTlR-|l`3`0oGx;P->yjei*bSo&kx5AmPkKRbVR{rvm$&(Hi{dA}b1 zdiX2kcku6HzmNU4`eXTL?Vq)O6#gpwo$`0`U-o}&|Em5~{(JZD?Z2e|N&m0?zxv;k z!INPR!(IkMMkB_hj7u4%m?W8cnR=O+nVFc&nai19GrwU@WJzGT%5sgxi`A2LKkI&0 zQ#Mn!RctHSCG<#y%X&Apr3 zkjIc`1E{jJB_!*370wR>mxZs)sQ?@ZsDzTfbE!+V_% zIvdjALo6P{v`cr`lsoigg*;??*H8XnfnX(myR!;Us%4fer@{N`1Rk{ ze_yM=Re$^O?dP|$@1@^AegE`5|3|@(w?E$g$oiQDa>~!tUunM{|9bo@@pt0yd%y4h zj{Ot+=gyzof1>_I{k{43#^3ON;s37vyY?^Sf9U^9|1bX!VhCcm$Z&xnfH8paJmYyr zedE#fR0G^$hD7Rv$KBwzF(!+5Fi3*w3+_WB2Fq z<2cW8o+E%Wkn9b1e4zrNPePxBN`*^>e+d5&t`eyd`6u#E zq*1g{ltqk1tX-@_j9Z*XykERuTu4G#Vw%J>2`Ncw$?Rv@&)z@#@T~ZG>GPk@e>|^w zQTu}NCF9Gsmu)Y(Uva;h@M^*0nynZDco zZr3}9_YUumy+8Ke=Y!9O%O5U%i1--s@&3pAA5%Z2e0uZg&8MQzMW26u{_(l~OZ^wN zuWVm?zxI9=`6l{p_P06Tl)fu}U-f;}ccUMMKX(1t`NQ$2^{44?(_ij?JpZQroBB`ozwG~I|CjyOXV7QZ$*_~bk%dHf@q@XJJENdp!~rh z&LKWce44njgtEj&i479=lJ=4_pUrxv{#^a}*5_NFJHK#wap}dS7YQ#DUcP_%{$<^( z+E?7Kd0x+cJ?FL78|^nc-|T$j`PSp@wYN9kroT&n_wC)ccdhSR--~?^{jl`I(hsH| zO+Oy_c;sWqr;txiKRx|a^11Xg>lfB9Q@>38qWV?s>$b1kzPf+&_;%yl&2L%Xv%dfS z{`-6PkM19`KV^Qd`?>C?{V)4p7k^#)mHa#T_m|&aez*T=|0D5N;_vFetNz;lv-x-a z-}!%u{}caz`TymA8$%m|B%>tb8phR(_Dpt6mzXXxr81|2sy*gzmTne#Ryo#9teaR} z*<9IfvE5?JWzS=0YlT(v(ALl;KAg&;;XI#&?YPhSp1$g**mhvp&vE;Sn zJSq?+4#czCQk5eq{j_ft><71bhYk1fK{#7OWDg6cP~T7hWp7RMn*B0}Q5#CwT0$u`MX&t5%ieBSh2@`c2UjW0I5 z@ObI|^8U;FFUwz*zv6$*|9biBWv}hu*uS~<=K7obxA|{5-m$-1@NWJ)i}x1qFTTI{ zKJ!EN2j-8=A7_7@{n7N3>8G=w&V5S%oc@{d3&WS0UuJzV{%ZX7?ANnj)4rvDWBAVS zeb)Ec-%Wm)fb0LvpP4_If3f_U_iNrSi{BQ%Fa5ssJMT~4AI`rVf0z7S^4I>K{l8oP zZv89!U;1B=L6Bh$!x{#6Mt8=?j87Qrnd+IOnWdSxGjC@OW(i?=&+?w7hqaqkgH4_7 z2-{J%MD|4Xf9(I*XLHQvu;8@dyvli%vxuvhOMsi7doA}`Zf_nho)2^9G#@=;`h=mb%H zF@3RfV&}l+I*$ae#2Se;65f(NlAyMI#Pf*fKc4@1KI6rV7ZxuqU*33m^JV3$idT}a zC13A)z4LYSo2WOx-~4$q`|X^!w(o4;-Fs#>SUxTP zwCt0|XOGXXKEM3j{iWxN-dEkP7rvhVTJ){xo5**O@7urc_#XKq>c^iSe}2sSIsd2A zFQ;Eme?9rt@w?-<)*tOZXaAi4Q~0;=FDL=*{I}y@%>S7G3=IGOFJ@Q*Zb!dme8V__ zX(E#;vnlgU=9|oQEVV33tV*oMSdX!0vt_dhvJ0|rW#7gg#SzWHz{$wDlyeEEHq26B?(U&OzNgW5JOk}i@vp6z&+@I2u;#|w@Z z8(wUD5%DteCF3i`SF2vFdKLUS`1SACzh5tTv*eBMTi>@|-+p^L|K0p|9`D`Xe|-P( z{p=63Ke&E${rK+VyN}a9&G_W_+3E9}&u>11^11z2`>(IQzWO@#+thD%-|fG@{Qm0u zlpj-m*#ETu`ReDZpHqHK{pIl69%TIQseh*Zas2D}_wC=ee`o%i`OoFQ>;L!vKmMP? zFc+NuzA%1fT*x$^$%om8`6u&F<|Qo4Sb|uCSpT#BV_nU*nk|w&f}NFvm18r z;X1-q$z92<$D_ydnCA)4Ox~Hietdp>Ec`6|yZCqU=L-}Fs0ykI-WI$qI8kV#kh`#l z@IT>y!dpbPh-8aqizJ+WA0~Y8{OIwK z@e|{xU7vP+D*0UeS?7!HmuFv|ewqJu{?~|a5#NNq3w}TI{q*_hEN1?O-ZlE@swa z(PMeV@``0C>r&Q4wnR1=c3Jit>^In_a7^V0KW!!F38;|2pzG@%-cY&$F9% zH*Yy#IiD%N3I9j_kNoQe)(d0{<_KyDX$n0TdM30)c&TubNRo)WsDkJn(YvCv#pZ}b ziARcyONdKclej7|S#pY`{B!x|_nzN<=xbGA@76Vi+m9NaQVaK50gJm{uulz_>=Hw;m?;pU;aGh%akv{Uqil% zeiQw6_1o2N)4osp9`+*)-2T7$^TyAazh?f5`W^jS=8w#uyMONfng4hG-^723|CIhK z{(t=c$^T^x%NWubGZ?j)w3yy7y=7X*ypFkmrGUkl)tL1g>sQttY&+Ph*{j*@IP5tX zIT<;Ra30}o=W6Hj=Jw|1e!lYg%IDc%W_?Ngn)Frko7T5a-#&iZ@qNel#vcto+<$uf6!<0Z>-w)7zZU#n z@H^vA#vjAK27iD2{qgtUzk~le|967h&(e(2j87OJGp=P?!&Jsx#%#}G&%(jV!Fq}H zA}eSNBZWPcU5`VL<2%Q9jzgS>IJ>!exWc%@xD|L5cwX_m;@QHxmA8SffzONIi(f=Q zRN%hA1A$e7s{~7hN`)MS9fWyAxJ9muTo+j+x=1uvEKkfz+)|uXf>q+8#6^j$XIan8 zo|`>qdcpYO+>3KBX1$#KGVN8`E92KDuNmI_e|`4NnK!fE&IIQZllR8&89y+7IQQY) z2T=W=@hS6@`De4wtY28ZT>NtB%lxkkzJmJyHs5W&bN%4_apT90AIp9&|5^I0^q0$T zm*2vFg#JAG^XSipzw7@t{Hy!t|KIPwEQ1`w8-_Owdl`2#b~E)bMKeb;YqMyx{AT&h za*Fjd>nyg}Y}xGD?A9DM9Ne5d;Qskqt~Fe>+%?>OJbpa#ymGuBct7xh>hnqbllhYc zk_AizO$FJ6*o3YNT^CvwC!$k{{lFc>Cet z#{(ayewz9z^K<5B+b=d>1iuP=efIU)*InOsee3()_dWSX(hrND=0ACU@&0=F>(Q@m zzqkMH`P2O;@o&Okvw!BGto;As|A+r~Fl=Y&VeDm0W=dkRV76ce6?#utp0Mm@-NibQ zZ6aF+dpbD%i*kx`zTtesd6?@k*DUUt+=V=aJRZF6ymEZ>ic9W$w(r^0=To2OzsLuV zA1J<3eD(X)uUD5}Uw*yr&DuBZZ`@ZyaN^^MkBdGn`c(b7 z=5zR$urCH*jlS}HHOCH&H0Dp&yzn-{_Ov||L^R7 zbN-e6FZ&bP?1o8aDcGBh@J?q zD6i-%(bu9U#ZHK=5MLqQCebF5Dw!rJ_*~%mhv)B~pMP=w#k!a4UiQA~eU8y4<9YY`-RpO!-=BWJ`oroE-5KU&#NE|27QP49bkkj66)-OrM!PGu>vs&3uIAFw0ujHLO$Ern1$t z*RiK@q;dFh`g59dnR6*{%Y(8o&nKSGJa>3+^B(0p$_E-hoh~p#pi!_%Fk2{FC`33! z*iOV=L`zgtR7gx%?625gu@~ac#V<)*lIVQa^{n)H@$>i>@h`kydc8DxW%^3twft-D zH(YPNz4`v;;oC=V&%QhNZs+?Q@0Wa7@}d9ZgpW0!YCdIrPX8S8CHRZuSBI}U-*mo7 ze3$sn`hyibc75;Xy`QIlo&L4s_s-wT{w)17`R}B^_5bSs<^Iq4AI%WO;KAt5XvSp9 zq|B_sEXX3j@}K2D%UjmBtasRMvz=r=!M=lIJI6B4Wt>yFrf{`zH***96!9eTCh!LE z1@PJP+wtoO=n2RO$_erc@e2JB`Xls4__gqDk=r7tM9+xs65AuTMtrsSEQ#3?-I86B z9?w0WTfVS-q484drQ|EAS6r{T!R_BSZ{EDQ`}WS;v+vHoJMe!0`;8wqepvKz(Z|W3 zrhIDs-1@ovOU0MWuNhyXzeRuZ`R@DO{)hb!!=HvfRemY`68kOoo8u41pWlCe{{gjc zAO3sr@ACi4|Bo>oW7x^KlW`r>TBe1}3z(;{OkwF@ZD*}!t76M%&u35KNa6_N4CnOX z^5U}Rw&ynCF#-4gW%#7|1o#E{Sp`@HehK^%crW-~@QKi4p_{@th0lqc6FDq;M0BUv z4zac3>%^BxERg`sf5beGc^>p47~I#ie`Wv5G~zPi(&pCYR^?Fv*B_F65`4n^!u&h}yaMck?1D@}OyIcsF8odSqsRx5*P?Gk zpNTyednEo){Eoz3i6zgLJe&V~{`1){X1|#Ba@xyDuO`0gd)@oG^G(;A*0-&18{aj) zt9@VhzVbumhtiK_AB#Q}eaics_c`ZF_Luap>0eX6rG88Np7=fPN9>R2pV2=fe?|TZ z`yKW>_)qYkz`p^1{r~y@^ZD=d-;==$+;4Mda$|C4c42mAabj^~b!4?;vuCqow_&&8 zu;H-cwBoelvf?u5w&1qlG3PPoHRmM93Kj~M36%>~3s(z+=1^KiTSdFYy2K`kPXO2F z8P77F_w(O_#)wvbT=Q|$ zr_G;se%|@{z?TDGPJBJ__58Q<->!YX_WjhlS6IoE5n)dR_F9*h8^5;%~&i zNqmzy|Lokeo6m1PfAZqV3()x2&sV=*f#O5(t-xE^cQWtP->bhj{$TvU{-gazuTS2e z!aj$6PX3boCI4&w*P3tD-`c;of1mPW@{ff-7yexLYu&G1zjysU{^!`A%YU!@efaO; zzqkM2{{PMJn}LIglS!0Wj9HmQg~gE7fYqMOj?I_dmpz&znj@1lle3(w99;iS;hD^{ zh<6e1M!t=F`}z0tpA$GIa98lI;2WVgLcfLo2y=;Yib{z|iD`;!iCaimN_a?mN~%6r zeQx@~0LSLo6PI+DWrWBk%roEf?Zu$G=@3(*04sKW6{B+~f%g--A|N8Rl z3#d&Y`(5_C-VZ%+UmZ052^xnh{Zsm!M1Q~@H zg+)cgL^MUUL~X_F#Dc_w#M30wB&sB&scMX206-dc*5uZ;rmX z_4f8#P=g3mUP*tH{%H8g;FH^D_s=n3V!jl8E&AH=t>fFg@AJQJ`LX54sh_8Qg4%yS ze*gH*_m}Ul+CQ~_*8gq(2QvgSWHV+lHZe6a&19a*ypd%C%W>8dtoPX-uzhF$&d$%t z&#BI(&SlSS#~r~F&Qrjf&)d$|!MA{a0sjtx9RimGFABaAdL_gp!XzRiDkEwlW+LV* z?kAoukuK37*&vzrJpFmYi~1KcU(S5F`PJrEXJ4Ov{rt^~H;nHX-bufgesB80>_foE zfR9<9vcdJo!Y>QHfcpQ}zFqzH@%zW`+&{U0s{c~^<@DR>cif-YKb3zg|ANMuH~io5 z{|v)vh8K)47+IKEm=##$S!`HsStHpZ*-F_<*(Y&KLR*Bl3SSbrB=SM@gD9UkpSX^MwuGmom!!#a)91l2f?pK8 zEPUDjYQn2^uh+dk`{wMMH*ep(<$BNkUh{+I2ak`QA2U8>d}{yP{(1SAfR z!k@Okt$$bkTlMe!{|o=WFnnPE&41Z5+cT%Iq_A|ccCoH!ThDft{VMx!j$a&#Tnb!n z-0s}DJh?oRc_;Jkc4(zweaTNwN3hAH*dj#U;6)^E@|x zVe}&EWz@^&S52>0yL-;aKC|K$*+=M-M+bfEBRjhec_JOKxh%6;XR)4SJIVHg{X4rlr#fdCS17pr+rqPz=Lzp)USWPA zekTEEfg-^o!G%H#g)RzT5@r--6g3nx6iX6M5}zb7Ndh!SzyJCE=O13Yf1&V7;Z@-4 zfY(iL8sBVsyXo!YcaPtReh~TK_R;NQ`KO9cD?hLJ44OX&m3g4G75P8%!DaU4UzdNe z{9*lL{@46(=D)0ebNR9=#ENC;raoz3=;`4~-wTf874@?Web&l)or{iToP* zweMU1wE`0ntD3Wx~!2>J@P3bhLD72YQd z8tm2=(-+GS&k$cIu~1^!vt`fjKfnK6;-%!vpjUyfx?gv{KKkb9oBwbBy|s96@xJIo z(T6o3*L(!c^(cN(_!9Ls8a(cM{`>jwTtB&fy8LqeRsXyG_pU!X|9tuT^{>Hyga26! z*$hh=moYwMdc-8dBFhrN8o@e+Z3^23_VesKoZOu5Tpr-|`~jW=Jb!rq@LKR&@|Oyf z3TzbIDELn3osgD@Hh8WDG^Pz|7s^Y@OKLpVe4h3q?ZuLpOI|*F_2`xS8~Hb}Z{yz1 zemDEwt@k(Ii+_~(82Tyn)8x-nK41QF>5Jeu!EgTG{lEA9=>2i_=h>g!zj=Op|MC9Q z`M2xuiGL^maWHU#$DiAo+L?|s9|zZQZfx#s?d)yr$2g90uyL_-xpTX7xAC;|oZvmd z%gN8l?V*L>gqWB(7vUyQ$8 zf4lx}|I_j3)Zf#8`Tp~R$FHU_PGh{mbc;!rMV2LzHIa2G+Y+{y?627MICVLTxC*(p zb8iEAjmMtPfv=Ung&(v|hEIr3C|EdHc&5lqk$a-|M3u#r#WN)`B&wfPKRfXJ;B&T@ z>@R&^`MjF+deUpqIGo%&`FE-BQ^Ec7Pai*hwD@cRo<{|h|GeLMzK8q>`2kv6^61yY QUs`{(!1EwG{_Xe&09LoQTL1t6 literal 0 HcmV?d00001 diff --git a/sounds/default/browse_mode.wav b/assets/sounds/default/browse_mode.wav similarity index 100% rename from sounds/default/browse_mode.wav rename to assets/sounds/default/browse_mode.wav diff --git a/sounds/default/button.wav b/assets/sounds/default/button.wav similarity index 100% rename from sounds/default/button.wav rename to assets/sounds/default/button.wav diff --git a/sounds/default/checkbox_checked.wav b/assets/sounds/default/checkbox_checked.wav similarity index 100% rename from sounds/default/checkbox_checked.wav rename to assets/sounds/default/checkbox_checked.wav diff --git a/sounds/default/checkbox_mixed.wav b/assets/sounds/default/checkbox_mixed.wav similarity index 100% rename from sounds/default/checkbox_mixed.wav rename to assets/sounds/default/checkbox_mixed.wav diff --git a/sounds/default/checkbox_unchecked.wav b/assets/sounds/default/checkbox_unchecked.wav similarity index 100% rename from sounds/default/checkbox_unchecked.wav rename to assets/sounds/default/checkbox_unchecked.wav diff --git a/sounds/default/combobox.wav b/assets/sounds/default/combobox.wav similarity index 100% rename from sounds/default/combobox.wav rename to assets/sounds/default/combobox.wav diff --git a/sounds/default/focus_mode.wav b/assets/sounds/default/focus_mode.wav similarity index 100% rename from sounds/default/focus_mode.wav rename to assets/sounds/default/focus_mode.wav diff --git a/sounds/default/link.wav b/assets/sounds/default/link.wav similarity index 100% rename from sounds/default/link.wav rename to assets/sounds/default/link.wav diff --git a/sounds/default/link_visited.wav b/assets/sounds/default/link_visited.wav similarity index 100% rename from sounds/default/link_visited.wav rename to assets/sounds/default/link_visited.wav diff --git a/sounds/default/radiobutton_checked.wav b/assets/sounds/default/radiobutton_checked.wav similarity index 100% rename from sounds/default/radiobutton_checked.wav rename to assets/sounds/default/radiobutton_checked.wav diff --git a/sounds/default/radiobutton_unchecked.wav b/assets/sounds/default/radiobutton_unchecked.wav similarity index 100% rename from sounds/default/radiobutton_unchecked.wav rename to assets/sounds/default/radiobutton_unchecked.wav diff --git a/sounds/default/start.wav b/assets/sounds/default/start.wav similarity index 100% rename from sounds/default/start.wav rename to assets/sounds/default/start.wav diff --git a/sounds/default/stop.wav b/assets/sounds/default/stop.wav similarity index 100% rename from sounds/default/stop.wav rename to assets/sounds/default/stop.wav diff --git a/sounds/default/switch_off.wav b/assets/sounds/default/switch_off.wav similarity index 100% rename from sounds/default/switch_off.wav rename to assets/sounds/default/switch_off.wav diff --git a/sounds/default/switch_on.wav b/assets/sounds/default/switch_on.wav similarity index 100% rename from sounds/default/switch_on.wav rename to assets/sounds/default/switch_on.wav diff --git a/sounds/default/togglebutton_checked.wav b/assets/sounds/default/togglebutton_checked.wav similarity index 100% rename from sounds/default/togglebutton_checked.wav rename to assets/sounds/default/togglebutton_checked.wav diff --git a/sounds/default/togglebutton_unchecked.wav b/assets/sounds/default/togglebutton_unchecked.wav similarity index 100% rename from sounds/default/togglebutton_unchecked.wav rename to assets/sounds/default/togglebutton_unchecked.wav diff --git a/assets/sounds/embed.go b/assets/sounds/embed.go new file mode 100644 index 0000000..faa5fcf --- /dev/null +++ b/assets/sounds/embed.go @@ -0,0 +1,8 @@ +package sounds + +import "embed" + +// Default contains the bundled theme, independent of the working directory. +// +//go:embed default/*.wav +var Default embed.FS diff --git a/build-local.sh b/build-local.sh deleted file mode 100755 index 02a1b30..0000000 --- a/build-local.sh +++ /dev/null @@ -1,109 +0,0 @@ -#!/bin/bash -# -# Build script for Cthulhu screen reader using Meson build system -# This script builds and installs Cthulhu locally to ~/.local -# - -set -e # Exit on error - -echo "Cthulhu Meson Local Build Script" -echo "Building and installing Cthulhu to ~/.local" -echo "================================================" - -# Check if we're in the right directory -if [[ ! -f "meson.build" ]] || [[ ! -f "src/cthulhu/cthulhu.py" ]]; then - echo "Error: This script must be run from the Cthulhu source directory" - exit 1 -fi - -# Check for required dependencies -echo "Checking dependencies..." -for cmd in meson ninja python3; do - if ! command -v "$cmd" &> /dev/null; then - echo "Error: $cmd is not installed" - echo "Please install: meson ninja python" - exit 1 - fi -done - -if ! python3 -c "import tomlkit" 2>/dev/null; then - echo "Error: Python module tomlkit is not installed" - echo "Please install: python-tomlkit" - exit 1 -fi - -getPythonSiteDir() { - python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' -} - -removeExistingLocalInstall() { - local pythonSite packageDir binPath desktopFile manPage - pythonSite="$HOME/.local/lib/python$(getPythonSiteDir)/site-packages" - packageDir="$pythonSite/cthulhu" - binPath="$HOME/.local/bin/cthulhu" - desktopFile="$HOME/.local/share/applications/cthulhu.desktop" - manPage="$HOME/.local/share/man/man1/cthulhu.1" - - echo "Removing existing local installation targets..." - rm -f "$binPath" - rm -rf "$packageDir" - rm -f "$desktopFile" - rm -f "$manPage" -} - -# Check for optional dependencies -missingOptional=() -if ! python3 -c "import gi" 2>/dev/null; then - missingOptional+=("python-gi") -fi - -if [[ ${#missingOptional[@]} -gt 0 ]]; then - echo "Warning: Optional dependencies missing: ${missingOptional[*]}" - echo "Cthulhu may not function properly without these." -fi - -# Clean any cached bytecode -echo "Removing __pycache__ directories..." -find . -type d -name "__pycache__" -prune -exec rm -rf {} + - -# Clean any existing build directory -if [[ -d "_build" ]]; then - echo "Removing existing build directory..." - rm -rf _build -fi - -# Setup Meson build -echo "Setting up Meson build..." -meson setup _build --prefix="$HOME/.local" --buildtype=debugoptimized - -# Build -echo "Building Cthulhu..." -meson compile -C _build - -# Install -echo "Installing Cthulhu to ~/.local..." -removeExistingLocalInstall -meson install -C _build - -# Update desktop database and icon cache -if command -v update-desktop-database &> /dev/null; then - echo "Updating desktop database..." - update-desktop-database "$HOME/.local/share/applications" 2>/dev/null || true -fi - -if command -v gtk-update-icon-cache &> /dev/null; then - echo "Updating icon cache..." - gtk-update-icon-cache -f -t "$HOME/.local/share/icons/hicolor" 2>/dev/null || true -fi - -echo -echo "Build completed successfully!" -echo -echo "To run Cthulhu:" -echo " ~/.local/bin/cthulhu" -echo -echo "To run Cthulhu setup:" -echo " ~/.local/bin/cthulhu -s" -echo -echo "Build artifacts are in: _build/" -echo "To clean build artifacts, run: rm -rf _build" diff --git a/clean-local.sh b/clean-local.sh deleted file mode 100755 index 90fdd3a..0000000 --- a/clean-local.sh +++ /dev/null @@ -1,97 +0,0 @@ -#!/bin/bash -# -# Clean script for Cthulhu screen reader Meson build -# This script removes build artifacts and optionally the local installation -# - -set -e # Exit on error - -# Colors for output (only if stdout is a terminal) -if [[ -t 1 ]]; then - GREEN='\033[0;32m' - YELLOW='\033[1;33m' - BLUE='\033[0;34m' - NC='\033[0m' # No Color -else - GREEN='' - YELLOW='' - BLUE='' - NC='' -fi - -echo -e "${BLUE}Cthulhu Meson Clean Script${NC}" -echo "Cleaning build artifacts and local installation" -echo "==============================================" - -# Clean build directory -if [[ -d "_build" ]]; then - echo -e "${YELLOW}Removing build directory...${NC}" - rm -rf _build - echo -e "${GREEN}Build directory cleaned${NC}" -else - echo "No build directory found" -fi - -# Ask about local installation cleanup -echo -read -p "Remove local installation from ~/.local? (y/N): " -n 1 -r -echo -if [[ $REPLY =~ ^[Yy]$ ]]; then - echo -e "${YELLOW}Removing local installation...${NC}" - - # Remove binary - if [[ -f "$HOME/.local/bin/cthulhu" ]]; then - rm -f "$HOME/.local/bin/cthulhu" - echo " Removed: ~/.local/bin/cthulhu" - fi - - # Remove Python modules - PYTHON_SITE="$HOME/.local/lib/python$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')/site-packages" - if [[ -d "$PYTHON_SITE/cthulhu" ]]; then - rm -rf "$PYTHON_SITE/cthulhu" - echo " Removed: $PYTHON_SITE/cthulhu/" - fi - - # Remove data files - - # Remove icons - for size in 16x16 22x22 24x24 32x32 48x48 256x256 scalable symbolic; do - icon_path="$HOME/.local/share/icons/hicolor/$size/apps" - if [[ -f "$icon_path/cthulhu.png" ]]; then - rm -f "$icon_path/cthulhu.png" - echo " Removed: $icon_path/cthulhu.png" - fi - if [[ -f "$icon_path/cthulhu.svg" ]]; then - rm -f "$icon_path/cthulhu.svg" - echo " Removed: $icon_path/cthulhu.svg" - fi - if [[ -f "$icon_path/cthulhu-symbolic.svg" ]]; then - rm -f "$icon_path/cthulhu-symbolic.svg" - echo " Removed: $icon_path/cthulhu-symbolic.svg" - fi - done - - # Remove man page - if [[ -f "$HOME/.local/share/man/man1/cthulhu.1" ]]; then - rm -f "$HOME/.local/share/man/man1/cthulhu.1" - echo " Removed: ~/.local/share/man/man1/cthulhu.1" - fi - - # Update caches - if command -v update-desktop-database &> /dev/null; then - echo -e "${YELLOW}Updating desktop database...${NC}" - update-desktop-database "$HOME/.local/share/applications" 2>/dev/null || true - fi - - if command -v gtk-update-icon-cache &> /dev/null; then - echo -e "${YELLOW}Updating icon cache...${NC}" - gtk-update-icon-cache -f -t "$HOME/.local/share/icons/hicolor" 2>/dev/null || true - fi - - echo -e "${GREEN}Local installation cleaned${NC}" -else - echo "Local installation preserved" -fi - -echo -echo -e "${GREEN}Cleanup completed!${NC}" diff --git a/cmd/cthulhu-braille/main.go b/cmd/cthulhu-braille/main.go new file mode 100644 index 0000000..52fefa9 --- /dev/null +++ b/cmd/cthulhu-braille/main.go @@ -0,0 +1,33 @@ +// cthulhu-braille is the isolated BrlAPI helper and standalone diagnostic. +// The main executable starts it only when braille is enabled. +package main + +import ( + "context" + "fmt" + "os" + "os/signal" + "syscall" + + "git.stormux.org/storm/cthulhu/internal/braille" +) + +func main() { + if len(os.Args) > 2 || len(os.Args) == 2 && os.Args[1] != "--client" { + fmt.Fprintln(os.Stderr, "Usage: cthulhu-braille [--client]") + os.Exit(2) + } + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) + defer cancel() + if len(os.Args) == 2 { + if err := braille.RunClient(ctx, braille.NewRouting(), os.Stdin, os.Stdout); err != nil { + fmt.Fprintf(os.Stderr, "cthulhu-braille: %v\n", err) + os.Exit(1) + } + return + } + if err := braille.Diagnostic(ctx, braille.New(), os.Stdout); err != nil { + fmt.Fprintf(os.Stderr, "cthulhu-braille: %v\n", err) + os.Exit(1) + } +} diff --git a/cmd/cthulhu/greeter.go b/cmd/cthulhu/greeter.go new file mode 100644 index 0000000..8db837b --- /dev/null +++ b/cmd/cthulhu/greeter.go @@ -0,0 +1,75 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package main + +import ( + "bytes" + "context" + "fmt" + "io" + "os" + "os/exec" + "os/user" + "path/filepath" + "strconv" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +func greeter_account(name string) (*user.User, error) { + if name != "lightdm" { + return nil, fmt.Errorf("unsupported greeter %q; supported: lightdm", name) + } + account, err := user.Lookup(name) + if err != nil { + return nil, fmt.Errorf("find %s greeter account: %w", name, err) + } + if account.Uid == "0" || !filepath.IsAbs(account.HomeDir) || account.HomeDir == "/" { + return nil, fmt.Errorf("%s greeter account needs a non-root UID and an absolute home directory other than /", name) + } + return account, nil +} + +func copy_greeter_settings(ctx context.Context, settings config.Settings, account *user.User, stdout, stderr io.Writer) error { + if account.Uid != strconv.Itoa(os.Geteuid()) { + executable, err := os.Executable() + if err != nil { + return fmt.Errorf("find Cthulhu executable: %w", err) + } + command, err := greeter_copy_command(ctx, executable, settings, account) + if err != nil { + return err + } + // sudo reads authentication from the terminal, leaving stdin available + // for the validated settings. Only the greeter account writes its files. + fmt.Fprintf(stdout, "Copying settings for %s; sudo authentication may be required.\n", account.Username) + command.Stdout, command.Stderr = stdout, stderr + if err := command.Run(); err != nil { + return fmt.Errorf("copy greeter settings as %s: %w", account.Username, err) + } + return nil + } + // Deliberately ignore the invoking user's XDG_DATA_HOME. This is the + // destination account's default, matching an ordinary Cthulhu startup. + path := filepath.Join(account.HomeDir, ".local", "share", "cthulhu", "user-settings-go.toml") + if err := config.WriteGreeterSettings(path, settings); err != nil { + return fmt.Errorf("copy greeter settings: %w", err) + } + fmt.Fprintf(stdout, "Copied greeter settings to %s. They take effect when the greeter reader next starts.\n", path) + return nil +} + +func greeter_copy_command(ctx context.Context, executable string, settings config.Settings, account *user.User) (*exec.Cmd, error) { + contents, err := config.GreeterSettings(settings) + if err != nil { + return nil, err + } + // Re-enter only the copy path, never the screen reader. Sending the + // snapshot over stdin avoids exposing the source file to another user. + command := exec.CommandContext(ctx, "sudo", "--user", account.Username, "--", + executable, "--greeter", "lightdm", "--greeter-settings-stdin") + command.Stdin = bytes.NewReader(contents) + return command, nil +} diff --git a/cmd/cthulhu/greeter_test.go b/cmd/cthulhu/greeter_test.go new file mode 100644 index 0000000..350cfa0 --- /dev/null +++ b/cmd/cthulhu/greeter_test.go @@ -0,0 +1,92 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package main + +import ( + "bytes" + "context" + "io" + "os" + "os/user" + "path/filepath" + "reflect" + "strconv" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestGreeterCopyUsesDestinationHomeAndPreservesSource(t *testing.T) { + t.Setenv("DBUS_SESSION_BUS_ADDRESS", "unix:path=/nonexistent/session-bus") + directory := t.TempDir() + source := filepath.Join(directory, "source.toml") + contents := []byte("[general]\nenableEchoByWord = true\n") + if err := os.WriteFile(source, contents, 0o600); err != nil { + t.Fatal(err) + } + settings, err := config.Load(source) + if err != nil { + t.Fatal(err) + } + account := &user.User{Username: "Username", Uid: strconv.Itoa(os.Geteuid()), HomeDir: filepath.Join(directory, "greeter-home")} + t.Setenv("XDG_DATA_HOME", filepath.Join(directory, "source-data")) + var output bytes.Buffer + if err := copy_greeter_settings(context.Background(), settings, account, &output, &output); err != nil { + t.Fatal(err) + } + target := filepath.Join(account.HomeDir, ".local", "share", "cthulhu", "user-settings-go.toml") + copied, err := config.Load(target) + if err != nil || !copied.Loaded || copied.ActiveProfile != "greeter" || !copied.EnableEchoByWord { + t.Fatalf("copied settings = %#v, error %v", copied, err) + } + info, err := os.Stat(target) + if err != nil || info.Mode().Perm() != 0o600 { + t.Fatalf("destination mode = %v, error %v", info, err) + } + unchanged, err := os.ReadFile(source) + if err != nil || !bytes.Equal(contents, unchanged) { + t.Fatalf("source changed: %q, error %v", unchanged, err) + } + if !strings.Contains(output.String(), target) { + t.Fatalf("missing destination confirmation: %q", output.String()) + } + // A second copy must replace settings without leaving a stale value. + settings.EnableEchoByWord = false + if err := copy_greeter_settings(context.Background(), settings, account, &output, &output); err != nil { + t.Fatal(err) + } + copied, err = config.Load(target) + if err != nil || copied.EnableEchoByWord { + t.Fatalf("repeated copy retained old settings: %#v, %v", copied, err) + } +} + +func TestGreeterCopyRequestsOnlyDestinationAccountPrivileges(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = "/private/source/settings.toml" + settings.EnableEchoByWord = true + account := &user.User{Username: "Username"} + command, err := greeter_copy_command(context.Background(), "/usr/bin/cthulhu", settings, account) + if err != nil { + t.Fatal(err) + } + want := []string{"sudo", "--user", "Username", "--", "/usr/bin/cthulhu", "--greeter", "lightdm", "--greeter-settings-stdin"} + if !reflect.DeepEqual(command.Args, want) { + t.Fatalf("copy arguments = %q, want %q", command.Args, want) + } + contents, err := io.ReadAll(command.Stdin) + if err != nil { + t.Fatal(err) + } + snapshot := filepath.Join(t.TempDir(), "snapshot.toml") + if err := os.WriteFile(snapshot, contents, 0o600); err != nil { + t.Fatal(err) + } + copied, err := config.Load(snapshot) + if err != nil || copied.ActiveProfile != "greeter" || !copied.EnableEchoByWord { + t.Fatalf("sudo stdin snapshot = %#v, error %v", copied, err) + } +} diff --git a/cmd/cthulhu/main.go b/cmd/cthulhu/main.go new file mode 100644 index 0000000..2671602 --- /dev/null +++ b/cmd/cthulhu/main.go @@ -0,0 +1,261 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package main + +import ( + "context" + "errors" + "flag" + "fmt" + "io" + "log/slog" + "os" + "os/signal" + "os/user" + "syscall" + "time" + + "git.stormux.org/storm/cthulhu/internal/app" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/clipboard" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/logging" + "git.stormux.org/storm/cthulhu/internal/notificationui" + "git.stormux.org/storm/cthulhu/internal/ocrcapture" + "git.stormux.org/storm/cthulhu/internal/ocrconfirm" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/shortcutui" + "git.stormux.org/storm/cthulhu/internal/speechhistoryui" + "git.stormux.org/storm/cthulhu/internal/tentacle" + "git.stormux.org/storm/cthulhu/internal/version" + "git.stormux.org/storm/cthulhu/internal/wine" +) + +func main() { + ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) + defer stop() + if err := run(ctx, os.Args[1:], os.Stdout, os.Stderr); err != nil { + fmt.Fprintf(os.Stderr, "cthulhu: %v\n", err) + os.Exit(1) + } +} + +func run(ctx context.Context, arguments []string, stdout, stderr io.Writer) (result error) { + options := flag.NewFlagSet("cthulhu", flag.ContinueOnError) + options.SetOutput(stderr) + tentacleFile := options.String("tentacles", "", "explicit local tentacle launch list (experimental JSON)") + tentacleParent := options.String("tentacle-cgroup-parent", "auto", "optional delegated cgroup v2 parent; auto uses CTHULHU_TENTACLE_CGROUP_PARENT or process supervision") + noTentacles := options.Bool("no-tentacles", false, "start without tentacles, ignoring saved tentacles and the local launch list") + tentacleGuardian := options.Bool("tentacle-guardian", false, "run the internal tentacle lifetime helper") + showVersion := options.Bool("version", false, "print version and exit") + shortVersion := options.Bool("v", false, "print version and exit") + replace := options.Bool("replace", false, "stop the running Cthulhu instance before starting") + shortReplace := options.Bool("r", false, "stop the running Cthulhu instance before starting") + checkConfig := options.Bool("check-config", false, "validate configuration and exit") + greeterStdin := options.Bool("greeter-settings-stdin", false, "receive an internal greeter settings snapshot") + greeter := options.String("greeter", "", "copy the saved active profile to a greeter account and exit (supported: lightdm)") + shortSettings := options.Bool("s", false, "open the preferences window at startup") + settingsFlag := options.Bool("settings", false, "open the preferences window at startup") + preferencesUI := options.Bool("preferences-ui", false, "run the internal preferences helper (private pipe protocol)") + notificationListUI := options.Bool("notification-list-ui", false, "run the internal notification list helper (private pipe protocol)") + speechHistoryUI := options.Bool("speech-history-ui", false, "run the internal speech history helper (private pipe protocol)") + shortcutListUI := options.Bool("shortcut-list-ui", false, "run the internal shortcut list helper (private pipe protocol)") + clipboardRead := options.Bool("clipboard-read", false, "run the internal clipboard reader (private pipe protocol)") + clipboardWatch := options.Bool("clipboard-watch", false, "run the internal clipboard change helper (private pipe protocol)") + ocrCapture := options.Bool("ocr-capture", false, "run the internal OCR capture helper (private pipe protocol)") + ocrConfirm := options.Bool("ocr-confirm", false, "run the internal OCR click confirmation helper") + appendLog := options.Bool("append", false, "preserve existing debug log contents (requires --debug-file)") + debugFile := options.String("debug-file", "", "enable debug logging only to this file, replacing existing contents") + speechSocket := options.String( + "speech-socket", + "", + "Speech Dispatcher SSIP socket (overrides SPEECHD_ADDRESS and SPEECHD_SOCKET)", + ) + configPath := options.String( + "config", + "", + "TOML configuration file (default: $XDG_DATA_HOME/cthulhu/user-settings-go.toml)", + ) + options.Usage = func() { + fmt.Fprintln(stdout, version.Details( + atspi.Version(), + os.Getenv("XDG_SESSION_TYPE"), + os.Getenv("XDG_SESSION_DESKTOP"), + wine.InstalledVersion(), + )) + fmt.Fprintln(stdout) + fmt.Fprintln(stdout, "Usage: cthulhu [options]") + fmt.Fprintln(stdout) + fmt.Fprintln(stdout, "Options:") + // Helpers remain parseable but are not part of the public help. + visibleOptions := flag.NewFlagSet("cthulhu", flag.ContinueOnError) + visibleOptions.SetOutput(stderr) + options.VisitAll(func(option *flag.Flag) { + switch option.Name { + case "preferences-ui", "notification-list-ui", "speech-history-ui", "shortcut-list-ui", + "clipboard-read", "clipboard-watch", "ocr-capture", "ocr-confirm", "tentacle-guardian", "greeter-settings-stdin": + return + } + visibleOptions.Var(option.Value, option.Name, option.Usage) + visibleOptions.Lookup(option.Name).DefValue = option.DefValue + }) + visibleOptions.PrintDefaults() + } + + if err := options.Parse(arguments); err != nil { + if errors.Is(err, flag.ErrHelp) { + return nil + } + return fmt.Errorf("parse command line: %w", err) + } + if options.NArg() != 0 { + return fmt.Errorf("unexpected argument %q", options.Arg(0)) + } + if *appendLog && *debugFile == "" { + return errors.New("--append requires --debug-file") + } + if *showVersion || *shortVersion { + fmt.Fprintln(stdout, version.Details( + atspi.Version(), + os.Getenv("XDG_SESSION_TYPE"), + os.Getenv("XDG_SESSION_DESKTOP"), + wine.InstalledVersion(), + )) + return nil + } + if *preferencesUI { + return preferences.Run(ctx, os.Stdin, stdout) + } + if *tentacleGuardian { + return tentacle.RunSupervisor(ctx) + } + if *ocrConfirm { + return ocrconfirm.Run(os.Stdin, stdout) + } + if *notificationListUI { + return notificationui.Run(ctx, os.Stdin, stdout) + } + if *shortcutListUI { + return shortcutui.Run(os.Stdin) + } + if *speechHistoryUI { + return speechhistoryui.Run(ctx, os.Stdin, stdout) + } + if *clipboardRead { + return clipboard.WriteMessage(stdout) + } + if *clipboardWatch { + return clipboard.WatchText(ctx, os.Stdin, stdout) + } + if *ocrCapture { + return ocrcapture.Run(ctx, os.Stdin, stdout) + } + var greeterAccount *user.User + if *greeterStdin && (*greeter == "" || *configPath != "") { + return errors.New("--greeter-settings-stdin requires --greeter and cannot be combined with --config") + } + if *greeter != "" { + var err error + greeterAccount, err = greeter_account(*greeter) + if err != nil { + return err + } + if os.Geteuid() == 0 && *configPath == "" { + return errors.New("run --greeter as your normal user; it requests sudo authentication when needed (root must supply --config FILE)") + } + } + logger := slog.New(slog.DiscardHandler) + if *debugFile != "" { + fileWriter, err := logging.OpenFile(*debugFile, nil, *appendLog) + if err != nil { + return fmt.Errorf("open debug log: %w", err) + } + diagnostics := logging.NewAsync(fileWriter, logging.AsyncOptions{ + Options: logging.Options{Level: slog.LevelDebug, AddSource: true}, + }) + defer func() { + stopContext, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + if err := diagnostics.Stop(stopContext); err != nil { + result = errors.Join(result, fmt.Errorf("stop diagnostics: %w", err)) + } + }() + logger = diagnostics.Logger() + } + logger.Info("starting Cthulhu", "version", version.String(), "pid", os.Getpid(), + "build", version.RuntimeIdentity(), "atspi_version", atspi.Version(), + "session_type", os.Getenv("XDG_SESSION_TYPE"), "session_desktop", os.Getenv("XDG_SESSION_DESKTOP"), + "x11_display_available", os.Getenv("DISPLAY") != "", "wayland_display_available", os.Getenv("WAYLAND_DISPLAY") != "") + var settings config.Settings + var err error + if *greeterStdin { + settings, err = config.ReadGreeterSettings(os.Stdin) + } else { + settings, err = config.Load(*configPath) + } + if err != nil { + logger.Error("load configuration", "error", err) + return err + } + if *checkConfig { + if settings.Loaded && settings.ActiveProfile != "" { + fmt.Fprintf(stdout, "Configuration is valid; active profile: %s.\n", settings.ActiveProfile) + } else if settings.Loaded { + fmt.Fprintln(stdout, "Configuration is valid.") + } else { + fmt.Fprintln(stdout, "Configuration file not found; built-in defaults are valid.") + } + return nil + } + if greeterAccount != nil { + return copy_greeter_settings(ctx, settings, greeterAccount, stdout, stderr) + } + if *replace || *shortReplace { + if err := replaceRunning(ctx); err != nil { + return fmt.Errorf("replace running Cthulhu: %w", err) + } + } + + if settings.Loaded { + logger.Info("loaded configuration", "profile", settings.ActiveProfile, + "keyboard_layout", settings.KeyboardLayout, "cthulhu_modifier_keys", settings.CthulhuModifierKeys) + } else { + logger.Info("configuration not found; using defaults") + } + registryPath := tentacle.RegistryPath(settings.Path) + if *noTentacles { + *tentacleFile = "" + registryPath = "" + } + err = app.Run(ctx, app.Options{ + TentacleFile: *tentacleFile, + TentacleRegistry: registryPath, + TentacleCgroupParent: *tentacleParent, + EnableRemote: true, + OpenPreferences: *shortSettings || *settingsFlag, + Logger: logger, + SpeechSocket: *speechSocket, + Settings: &settings, + }) + if err != nil { + logger.Error("Cthulhu stopped with an error", "error", err) + } else { + logger.Info("Cthulhu stopped") + } + return err +} diff --git a/cmd/cthulhu/main_test.go b/cmd/cthulhu/main_test.go new file mode 100644 index 0000000..0d6060d --- /dev/null +++ b/cmd/cthulhu/main_test.go @@ -0,0 +1,275 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package main + +import ( + "bytes" + "context" + "encoding/json" + "os" + "path/filepath" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/version" + "git.stormux.org/storm/cthulhu/internal/wine" +) + +func TestVersion(t *testing.T) { + t.Setenv("XDG_SESSION_TYPE", "x11") + t.Setenv("XDG_SESSION_DESKTOP", "GNOME") + want := version.Details(atspi.Version(), "x11", "GNOME", wine.InstalledVersion()) + for _, argument := range []string{"--version", "-v"} { + var stdout bytes.Buffer + if err := run(context.Background(), []string{argument}, &stdout, &stdout); err != nil { + t.Fatalf("run %s: %v", argument, err) + } + if got := strings.TrimSpace(stdout.String()); got != want { + t.Fatalf("version output = %q, want %q", got, want) + } + } +} + +func TestHelp(t *testing.T) { + var versionOutput bytes.Buffer + if err := run(context.Background(), []string{"-v"}, &versionOutput, &versionOutput); err != nil { + t.Fatalf("run -v: %v", err) + } + for _, argument := range []string{"-h", "--help"} { + var stdout bytes.Buffer + if err := run(context.Background(), []string{argument}, &stdout, &stdout); err != nil { + t.Fatalf("run %s: %v", argument, err) + } + help := stdout.String() + if strings.Contains(help, "tentacle-guardian") { + t.Fatal("private guardian exposed in help") + } + if !strings.HasPrefix(help, versionOutput.String()+"\nUsage: cthulhu [options]\n\nOptions:\n") || + !strings.Contains(help, "-s") || !strings.Contains(help, "-settings") || + !strings.Contains(help, "-r") || !strings.Contains(help, "-replace") { + t.Fatalf("help output does not contain expected version, usage, and flags: %q", help) + } + } +} + +func TestCheckConfig(t *testing.T) { + path := filepath.Join(t.TempDir(), "user-settings.toml") + contents := []byte("[general]\nstartingProfile = [\"Default\", \"default\"]\n[profiles.default]\nspeakDescription = false\n") + if err := os.WriteFile(path, contents, 0o600); err != nil { + t.Fatalf("write config: %v", err) + } + var stdout, stderr bytes.Buffer + if err := run( + context.Background(), + []string{"--check-config", "--config", path}, + &stdout, + &stderr, + ); err != nil { + t.Fatalf("run --check-config: %v", err) + } + if got := stdout.String(); !strings.Contains(got, "active profile: default") { + t.Fatalf("check-config output = %q", got) + } + if stderr.Len() != 0 { + t.Fatalf("logging enabled without --debug-file: %q", stderr.String()) + } +} + +func TestUnsupportedGreeterDoesNotStartOrReplaceReader(t *testing.T) { + t.Setenv("DBUS_SESSION_BUS_ADDRESS", "unix:path=/nonexistent/session-bus") + var output bytes.Buffer + err := run(context.Background(), []string{"--greeter", "unsupported", "--replace"}, &output, &output) + if err == nil || !strings.Contains(err.Error(), "unsupported greeter") { + t.Fatalf("unsupported greeter error = %v", err) + } + if output.Len() != 0 { + t.Fatalf("unexpected output: %q", output.String()) + } +} + +func TestCheckVersionedConfig(t *testing.T) { + for _, test := range []struct { + name string + contents string + wantError bool + }{ + {"current", "schema-version = 2\nactive-profile = 'default'\n[profiles.default.speech]\nenabled = false\n", false}, + {"future", "schema-version = 3\nactive-profile = 'default'\n[profiles.default]\n", true}, + {"invalid", "schema-version = 2\nactive-profile = 'default'\n[profiles.default.sound]\nvolume = 2.0\n", true}, + } { + t.Run(test.name, func(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + if err := os.WriteFile(path, []byte(test.contents), 0o600); err != nil { + t.Fatal(err) + } + var stdout, stderr bytes.Buffer + err := run(context.Background(), []string{"--check-config", "--config", path}, &stdout, &stderr) + if (err != nil) != test.wantError { + t.Fatalf("check-config error = %v, want error %v", err, test.wantError) + } + if !test.wantError && stdout.String() != "Configuration is valid; active profile: default.\n" { + t.Fatalf("check-config output = %q", stdout.String()) + } + if test.wantError && stdout.Len() != 0 { + t.Fatalf("invalid configuration reported success: %q", stdout.String()) + } + if stderr.Len() != 0 { + t.Fatalf("logging enabled without --debug-file: %q", stderr.String()) + } + }) + } +} + +func TestDebugFileCapturesStartupFailureAndAppends(t *testing.T) { + directory := t.TempDir() + logPath := filepath.Join(directory, "debug.log") + configPath := filepath.Join(directory, "settings.toml") + configContents := []byte("[profiles.default]\nenableSound = false\n") + if err := os.WriteFile(configPath, configContents, 0o600); err != nil { + t.Fatalf("write config: %v", err) + } + for range 2 { + var stdout, stderr bytes.Buffer + err := run(context.Background(), []string{ + "--debug-file", logPath, "--append", + "--config", configPath, + "--speech-socket", filepath.Join(directory, "absent.sock"), + }, &stdout, &stderr) + if err == nil { + t.Fatal("startup unexpectedly succeeded") + } + if !strings.Contains(err.Error(), "connect to Speech Dispatcher") { + t.Fatalf("startup error = %v", err) + } + if stdout.Len() != 0 || stderr.Len() != 0 { + t.Fatalf("debug-file wrote to terminal: stdout %q, stderr %q", stdout.String(), stderr.String()) + } + } + data, err := os.ReadFile(logPath) + if err != nil { + t.Fatal(err) + } + if strings.Count(string(data), `"message":"starting Cthulhu"`) != 2 { + t.Fatalf("previous session was not retained: %s", data) + } + if strings.Count(string(data), `"message":"Cthulhu stopped with an error"`) != 2 { + t.Fatalf("startup failures were not logged: %s", data) + } + for _, line := range strings.Split(strings.TrimSpace(string(data)), "\n") { + var record map[string]any + if err := json.Unmarshal([]byte(line), &record); err != nil { + t.Fatal(err) + } + if record["source"] == nil { + t.Fatalf("debug-file did not enable sources: %s", line) + } + if record["message"] == "starting Cthulhu" { + build, ok := record["build"].(map[string]any) + if !ok || build["go_version"] == "" || build["vcs_revision"] == nil || build["vcs_modified"] == nil || + record["version"] != version.String() || record["atspi_version"] == nil || record["session_type"] == nil { + t.Fatalf("startup identity missing: %s", line) + } + } + if record["level"] == "ERROR" { + message, ok := record["error"].(string) + if !ok || !strings.Contains(message, "connect to Speech Dispatcher") { + t.Fatalf("missing actual error: %s", line) + } + } + } + info, err := os.Stat(logPath) + if err != nil { + t.Fatal(err) + } + if info.Mode().Perm() != 0o600 { + t.Fatalf("log permissions = %o", info.Mode().Perm()) + } +} + +func TestDebugFileOpenFailure(t *testing.T) { + var output bytes.Buffer + err := run(context.Background(), []string{"--debug-file", t.TempDir()}, &output, &output) + if err == nil || !strings.Contains(err.Error(), "open debug log") { + t.Fatalf("error = %v", err) + } +} + +func TestDebugFileCheckConfig(t *testing.T) { + logPath := filepath.Join(t.TempDir(), "debug.log") + configPath := filepath.Join(t.TempDir(), "absent.toml") + var stdout, stderr bytes.Buffer + if err := run(context.Background(), []string{ + "--check-config", "--config", configPath, "--debug-file", logPath, + }, &stdout, &stderr); err != nil { + t.Fatal(err) + } + if stdout.String() != "Configuration file not found; built-in defaults are valid.\n" { + t.Fatalf("check-config output = %q", stdout.String()) + } + if stderr.Len() != 0 { + t.Fatalf("debug-file wrote to terminal: %q", stderr.String()) + } + data, err := os.ReadFile(logPath) + if err != nil { + t.Fatal(err) + } + var record map[string]any + if err := json.Unmarshal(bytes.TrimSpace(data), &record); err != nil { + t.Fatal(err) + } + if record["message"] != "starting Cthulhu" || record["source"] == nil { + t.Fatalf("missing startup diagnostic or source: %s", data) + } +} + +func TestStandaloneDebugFlagRejected(t *testing.T) { + var stdout, stderr bytes.Buffer + err := run(context.Background(), []string{"--debug"}, &stdout, &stderr) + if err == nil || !strings.Contains(err.Error(), "flag provided but not defined: -debug") { + t.Fatalf("standalone --debug error = %v", err) + } +} + +func TestAppendRequiresDebugFile(t *testing.T) { + var output bytes.Buffer + err := run(context.Background(), []string{"--append"}, &output, &output) + if err == nil || err.Error() != "--append requires --debug-file" { + t.Fatalf("error = %v", err) + } +} + +func TestDebugFileStartsFresh(t *testing.T) { + logPath := filepath.Join(t.TempDir(), "debug.log") + configPath := filepath.Join(t.TempDir(), "absent.toml") + for range 2 { + var output bytes.Buffer + if err := run(context.Background(), []string{ + "--check-config", "--config", configPath, "--debug-file", logPath, + }, &output, &output); err != nil { + t.Fatal(err) + } + data, err := os.ReadFile(logPath) + if err != nil { + t.Fatal(err) + } + if strings.Count(string(data), `"message":"starting Cthulhu"`) != 1 { + t.Fatalf("expected only the current session: %s", data) + } + } +} diff --git a/cmd/cthulhu/replace.go b/cmd/cthulhu/replace.go new file mode 100644 index 0000000..3ce8e9a --- /dev/null +++ b/cmd/cthulhu/replace.go @@ -0,0 +1,152 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package main + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + "strings" + "syscall" + "time" + + "git.stormux.org/storm/cthulhu/internal/remote" + "git.stormux.org/storm/cthulhu/internal/sessionbus" + "github.com/godbus/dbus/v5" +) + +const replaceWait = 8 * time.Second + +// replaceRunning identifies the active Go reader through its private session +// bus name. It never signals a process merely because its name matches. +func replaceRunning(ctx context.Context) error { + // Match the reader's service discovery without rewriting the environment. + // Other discovery paths can select another bus when the address is unset. + connection, err := sessionbus.Connect(nil, "replacement") + if err != nil { + return fmt.Errorf("connect to session bus: %w", err) + } + defer connection.Close() + owner, err := busNameOwner(ctx, connection) + if err != nil || owner == "" { + return err + } + var pid uint32 + if err := connection.BusObject().CallWithContext(ctx, "org.freedesktop.DBus.GetConnectionUnixProcessID", 0, owner).Store(&pid); err != nil { + return fmt.Errorf("get running reader PID: %w", err) + } + var uid uint32 + if err := connection.BusObject().CallWithContext(ctx, "org.freedesktop.DBus.GetConnectionUnixUser", 0, owner).Store(&uid); err != nil { + return fmt.Errorf("get running reader UID: %w", err) + } + if uid != uint32(os.Getuid()) || pid == 0 || int(pid) == os.Getpid() { + return errors.New("running reader has an unexpected owner or PID") + } + if err := verifyReaderExecutable(int(pid)); err != nil { + return err + } + _, started, err := processIdentity(int(pid)) + if err != nil { + return fmt.Errorf("inspect running reader identity: %w", err) + } + if current, err := busNameOwner(ctx, connection); err != nil || current != owner { + return fmt.Errorf("running reader changed before replacement: %w", err) + } + if err := syscall.Kill(int(pid), syscall.SIGTERM); err != nil { + return fmt.Errorf("stop running reader: %w", err) + } + if err := waitForProcessExit(ctx, int(pid), started, replaceWait); err == nil { + return nil + } else if !errors.Is(err, context.DeadlineExceeded) { + return err + } + // The old reader did not finish shutdown. Verify the PID still belongs to + // a reader before forcing it down. + if _, currentStart, err := processIdentity(int(pid)); errors.Is(err, os.ErrNotExist) || err == nil && currentStart != started { + return nil + } else if err != nil { + return err + } + if err := verifyReaderExecutable(int(pid)); err != nil { + return err + } + if err := syscall.Kill(int(pid), syscall.SIGKILL); err != nil && !errors.Is(err, syscall.ESRCH) { + return fmt.Errorf("force stop running reader: %w", err) + } + return waitForProcessExit(ctx, int(pid), started, 2*time.Second) +} + +func waitForProcessExit(ctx context.Context, pid int, started string, timeout time.Duration) error { + deadline := time.NewTimer(timeout) + defer deadline.Stop() + ticker := time.NewTicker(50 * time.Millisecond) + defer ticker.Stop() + for { + state, currentStart, err := processIdentity(pid) + if errors.Is(err, os.ErrNotExist) { + return nil + } + if err != nil { + return fmt.Errorf("inspect running reader state: %w", err) + } + if state == "Z" || currentStart != started { + return nil + } + select { + case <-ctx.Done(): + return ctx.Err() + case <-deadline.C: + return context.DeadlineExceeded + case <-ticker.C: + } + } +} + +func processIdentity(pid int) (state, started string, err error) { + data, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid)) + if err != nil { + return "", "", err + } + closing := strings.LastIndexByte(string(data), ')') + if closing < 0 { + return "", "", errors.New("invalid process status") + } + fields := strings.Fields(string(data[closing+1:])) + if len(fields) <= 19 { + return "", "", errors.New("incomplete process status") + } + return fields[0], fields[19], nil +} + +func busNameOwner(ctx context.Context, connection *dbus.Conn) (string, error) { + var owner string + err := connection.BusObject().CallWithContext(ctx, "org.freedesktop.DBus.GetNameOwner", 0, remote.BusName).Store(&owner) + if err == nil { + return owner, nil + } + var busError dbus.Error + if errors.As(err, &busError) && busError.Name == "org.freedesktop.DBus.Error.NameHasNoOwner" { + return "", nil + } + return "", fmt.Errorf("query running reader: %w", err) +} + +func verifyReaderExecutable(pid int) error { + running, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pid)) + if err != nil { + return fmt.Errorf("inspect running reader: %w", err) + } + current, err := os.Executable() + if err != nil { + return fmt.Errorf("inspect current reader: %w", err) + } + running = strings.TrimSuffix(running, " (deleted)") + if filepath.Base(running) != filepath.Base(current) { + return fmt.Errorf("D-Bus owner is %q, not %q", running, filepath.Base(current)) + } + return nil +} diff --git a/cmd/cthulhu/replace_test.go b/cmd/cthulhu/replace_test.go new file mode 100644 index 0000000..2824c28 --- /dev/null +++ b/cmd/cthulhu/replace_test.go @@ -0,0 +1,99 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package main + +import ( + "bufio" + "context" + "fmt" + "os" + "os/exec" + "os/signal" + "syscall" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/remote" + "git.stormux.org/storm/cthulhu/internal/sessionbus" + "github.com/godbus/dbus/v5" +) + +func TestReplaceHelper(t *testing.T) { + if os.Getenv("CTHULHU_REPLACE_HELPER") != "1" { + return + } + connection, err := sessionbus.Connect(nil, "replacement-test-reader") + if err != nil { + t.Fatal(err) + } + defer connection.Close() + reply, err := connection.RequestName(remote.BusName, dbus.NameFlagDoNotQueue) + if err != nil || reply != dbus.RequestNameReplyPrimaryOwner { + t.Fatalf("own reader bus name: %v, %v", reply, err) + } + signals := make(chan os.Signal, 1) + signal.Notify(signals, syscall.SIGTERM) + defer signal.Stop(signals) + fmt.Println("READY") + <-signals +} + +func TestReplaceRunningNative(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_REPLACE") != "1" { + t.Skip("requires isolated session bus") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := replaceRunning(ctx); err != nil { + t.Fatalf("replace with no reader: %v", err) + } + command := exec.CommandContext(ctx, os.Args[0], "-test.run=^TestReplaceHelper$") + command.Env = append(os.Environ(), "CTHULHU_REPLACE_HELPER=1") + output, err := command.StdoutPipe() + if err != nil { + t.Fatal(err) + } + command.Stderr = os.Stderr + if err := command.Start(); err != nil { + t.Fatal(err) + } + defer func() { + if command.ProcessState == nil { + command.Process.Kill() + command.Wait() + } + }() + ready := make(chan bool, 1) + go func() { + scanner := bufio.NewScanner(output) + for scanner.Scan() { + if scanner.Text() == "READY" { + ready <- true + return + } + } + ready <- false + }() + select { + case started := <-ready: + if !started { + t.Fatal("helper did not claim bus name") + } + case <-ctx.Done(): + t.Fatal("helper did not claim bus name") + } + if err := replaceRunning(ctx); err != nil { + t.Fatal(err) + } + if state, _, err := processIdentity(command.Process.Pid); !os.IsNotExist(err) && (err != nil || state != "Z") { + t.Fatalf("replacement returned before reader exit: state=%q, error=%v", state, err) + } + if err := command.Wait(); err != nil { + t.Fatalf("running reader did not exit cleanly: %v", err) + } + if err := replaceRunning(ctx); err != nil { + t.Fatalf("replace after reader exit: %v", err) + } +} diff --git a/cmd/parityledger/main.go b/cmd/parityledger/main.go new file mode 100644 index 0000000..2ac1a37 --- /dev/null +++ b/cmd/parityledger/main.go @@ -0,0 +1,65 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package main + +import ( + "fmt" + "io" + "os" + + "git.stormux.org/storm/cthulhu/internal/parity" +) + +func main() { + if err := run(os.Args[1:], os.Stdout, os.Stderr); err != nil { + fmt.Fprintf(os.Stderr, "parityledger: %v\n", err) + os.Exit(1) + } +} + +func run(arguments []string, stdout, stderr io.Writer) error { + if len(arguments) == 1 && (arguments[0] == "-h" || arguments[0] == "--help") { + writeUsage(stdout) + return nil + } + if len(arguments) != 2 || arguments[0] != "validate" { + writeUsage(stderr) + return fmt.Errorf("expected validate LEDGER") + } + + file, err := os.Open(arguments[1]) + if err != nil { + return fmt.Errorf("open parity ledger: %w", err) + } + defer file.Close() + + records, err := parity.Load(file) + if err != nil { + return fmt.Errorf("validate parity ledger: %w", err) + } + fmt.Fprintf(stdout, "Validated %d parity ledger rows.\n", len(records)) + return nil +} + +func writeUsage(writer io.Writer) { + fmt.Fprintln(writer, "Usage: parityledger validate LEDGER") + fmt.Fprintln(writer) + fmt.Fprintln(writer, "Validates the schema, required fields, statuses, and duplicate row IDs.") + fmt.Fprintln(writer) + fmt.Fprintf(writer, "Allowed statuses: %s.\n", parity.FormatStatuses()) +} diff --git a/cmd/parityledger/main_test.go b/cmd/parityledger/main_test.go new file mode 100644 index 0000000..f07f690 --- /dev/null +++ b/cmd/parityledger/main_test.go @@ -0,0 +1,47 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package main + +import ( + "bytes" + "path/filepath" + "strings" + "testing" +) + +func TestValidateFixture(t *testing.T) { + var stdout bytes.Buffer + ledgerPath := filepath.Join("..", "..", "testdata", "parity-ledger.csv") + if err := run([]string{"validate", ledgerPath}, &stdout, &stdout); err != nil { + t.Fatalf("validate fixture: %v", err) + } + if !strings.HasPrefix(stdout.String(), "Validated ") || + !strings.Contains(stdout.String(), " parity ledger rows.") { + t.Fatalf("unexpected validation output: %q", stdout.String()) + } +} + +func TestUsage(t *testing.T) { + var stdout bytes.Buffer + if err := run([]string{"--help"}, &stdout, &stdout); err != nil { + t.Fatalf("run --help: %v", err) + } + if !strings.Contains(stdout.String(), "Usage: parityledger validate LEDGER") { + t.Fatalf("unexpected usage output: %q", stdout.String()) + } +} diff --git a/cmd/tentacle-host/main.go b/cmd/tentacle-host/main.go new file mode 100644 index 0000000..4a50a6c --- /dev/null +++ b/cmd/tentacle-host/main.go @@ -0,0 +1,85 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +// A host diagnostic tool for external Tentacles, independent of the running reader. +package main + +import ( + "context" + "encoding/json" + "errors" + "flag" + "fmt" + "os" + "time" + + "git.stormux.org/storm/cthulhu/internal/tentacle" +) + +func main() { + if err := run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func run() (runError error) { + options := flag.NewFlagSet("host", flag.ContinueOnError) + cgroupParent := options.String("cgroup-parent", "", "delegated cgroup v2 parent for resource containment") + presentation := options.Bool("presentation", false, "grant command speech/braille result capability (prints JSON only)") + interactive := options.Bool("interaction", false, "grant internal form/clipboard/focused-item capability (prints initial JSON only)") + readerSettings := options.Bool("reader-settings", false, "grant declarative reader settings capability (prints initial JSON only; does not modify a reader)") + command := options.String("command", "echo", "registered command to invoke") + if err := options.Parse(os.Args[1:]); err != nil { + return err + } + if options.NArg() < 1 { + return fmt.Errorf("usage: host [-cgroup-parent /delegated/parent] /absolute/program [arguments...]") + } + var manager *tentacle.Manager + var err error + if *cgroupParent == "" { + manager, err = tentacle.NewManager(tentacle.DefaultLimits(), nil) + } else { + manager, err = tentacle.NewContainedManager(tentacle.DefaultLimits(), nil, *cgroupParent, tentacle.DefaultResourceLimits()) + } + if err != nil { + return err + } + defer func() { + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + runError = errors.Join(runError, manager.Shutdown(ctx)) + }() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + session, err := manager.Start(ctx, tentacle.Spec{ID: "local-example", Program: options.Args(), Presentation: *presentation, Interaction: *interactive, ReaderSettings: *readerSettings}) + if err != nil { + return err + } + select { + case <-session.Ready(): + case <-ctx.Done(): + return ctx.Err() + } + if state, err := session.Status(); state != tentacle.Ready { + return fmt.Errorf("startup %s: %v", state, err) + } + if err := session.Activate(); err != nil { + return err + } + pending, err := session.Invoke(ctx, *command, json.RawMessage(`{"text":"Hello, é猫😀é"}`)) + if err != nil { + return err + } + select { + case result := <-pending: + if result.Err != nil { + return result.Err + } + fmt.Println(string(result.Value)) + return nil + case <-ctx.Done(): + return ctx.Err() + } +} diff --git a/contrib/cthulhu-autostart.desktop b/contrib/cthulhu-autostart.desktop deleted file mode 100644 index bd0dc0c..0000000 --- a/contrib/cthulhu-autostart.desktop +++ /dev/null @@ -1,59 +0,0 @@ -[Desktop Entry] -Type=Application -Name[an]=Lector de pantalla Cthulhu -Name[ast]=Llector de pantalla d'Cthulhu -Name[be]=Чытач з экрана Cthulhu -Name[bg]=Cthulhu — екранен четец -Name[bs]=Cthulhu čitač ekrana -Name[ca]=Lector de pantalla Cthulhu -Name[cs]=Čtečka obrazovky Cthulhu -Name[da]=Skærmlæseren Cthulhu -Name[de]=Cthulhu-Bildschirmleser -Name[el]=Αναγνώστης οθόνης Cthulhu -Name[en_GB]=Cthulhu Screen Reader -Name[eo]=Ekranlegilo Orko -Name[es]=Lector de pantalla Cthulhu -Name[eu]=Cthulhu pantaila-irakurlea -Name[fa]=صفحه‌خوان اورکا -Name[fi]=Cthulhu-näytönlukija -Name[fr]=Lecteur d’écran Cthulhu -Name[gl]=Lector da pantalla Cthulhu -Name[he]=מקריא המסך Cthulhu -Name[hi]=Cthulhu स्क्रीन वाचक -Name[hu]=Orka képernyőolvasó -Name[id]=Pembaca Layar Cthulhu -Name[is]=Cthulhu skjálestur -Name[it]=Lettore schermo Cthulhu -Name[ka]=Cthulhu - ეკრანის მკითხველი -Name[kk]=Cthulhu экраннан оқитын қолданбасы -Name[lt]=Cthulhu ekrano skaityklė -Name[lv]=Cthulhu ekrāna lasītājs -Name[mk]=Cthulhu читач на екранот -Name[nb]=Cthulhu skjermleser -Name[ne]=ओर्का दृष्टि वाचक -Name[nl]=Cthulhu schermlezer -Name[oc]=Lector d'ecran Cthulhu -Name[pa]=ਓਰਕਾ ਸਕਰੀਨ ਰੀਡਰ -Name[pl]=Czytnik ekranowy Cthulhu -Name[pt]=Leitor de ecrã Cthulhu -Name[pt_BR]=Leitor de tela Cthulhu -Name[ro]=Cititorul de ecran Cthulhu -Name[ru]=Экранный диктор Cthulhu -Name[sl]=Zaslonski bralnik Orka -Name[sr]=Читач екрана Орка -Name[sv]=Cthulhu skärmläsare -Name[ta]=ஆர்கா திரை படிப்பி -Name[te]=ఓర్కా తెరచదువరి -Name[tg]=Хонандаи экрани Cthulhu -Name[tr]=Cthulhu Ekran Okuyucu -Name[ug]=Cthulhu ئېكران ئوقۇغۇ -Name[uk]=Інструмент читання з екрана «Cthulhu» -Name[zh_CN]=Cthulhu 屏幕阅读器 -Name[zh_HK]=Cthulhu 螢幕閱讀器 -Name=Cthulhu Screen Reader -Exec=cthulhu -NoDisplay=true -AutostartCondition=GSettings org.gnome.desktop.a11y.applications screen-reader-enabled -X-GNOME-AutoRestart=true -#X-GNOME-Autostart-Phase=Initialization -OnlyShowIn=GNOME;MATE;Unity;Cinnamon; diff --git a/contrib/toggle.screenreader.gschema.xml b/contrib/toggle.screenreader.gschema.xml deleted file mode 100644 index 7aa86ec..0000000 --- a/contrib/toggle.screenreader.gschema.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - '<Shift><Alt>v' - Keybinding - Keybinding associated to toggle screen reader. - - - '/opt/I38/scripts/toggle_screenreader.sh 1>/dev/null' - Command - Command to toggle the screen reader between orca and cthulhu. - - - 'Toggle screenreader' - Name - Description associated to toggle screen reader. - - - diff --git a/cthulhu.doap b/cthulhu.doap deleted file mode 100644 index 8e9c05d..0000000 --- a/cthulhu.doap +++ /dev/null @@ -1,22 +0,0 @@ - - - cthulhu - Screen reader for individuals who are blind or visually impaired - Screen reader for individuals who are blind or visually impaired - - - - - - Python - - - Storm Dragon - - - - diff --git a/distro-packages/Arch-Linux/cthulhu-git/.SRCINFO b/distro-packages/Arch-Linux/cthulhu-git/.SRCINFO new file mode 100644 index 0000000..efafa99 --- /dev/null +++ b/distro-packages/Arch-Linux/cthulhu-git/.SRCINFO @@ -0,0 +1,43 @@ +pkgbase = cthulhu-git + pkgdesc = Desktop-agnostic screen reader with speech, Braille, and Tentacle support + pkgver = 2026.10.14.r3.ge5049b9 + pkgrel = 1 + url = https://git.stormux.org/storm/cthulhu + arch = x86_64 + arch = aarch64 + arch = armv7h + license = GPL-3.0-or-later + makedepends = git + makedepends = go + makedepends = pkgconf + depends = glibc + depends = at-spi2-core + depends = glib2 + depends = gdk-pixbuf2 + depends = gtk3 + depends = speech-dispatcher + depends = gstreamer + depends = gst-plugins-base + depends = gst-plugins-good + depends = brltty + depends = liblouis + depends = libx11 + depends = libxres + depends = libxtst + depends = libxfixes + depends = libxkbcommon + depends = xclip + depends = dbus + depends = systemd + optdepends = git: Discover and update Tentacle repositories + optdepends = tesseract: OCR engine for text recognition + optdepends = tesseract-data-eng: English OCR language data + provides = cthulhu=2026.10.14.r3.ge5049b9 + conflicts = cthulhu + options = !debug + options = !lto + source = cthulhu::git+https://git.stormux.org/storm/cthulhu.git#branch=master + sha512sums = SKIP + optdepends_x86_64 = wine-access: Wine, Proton, NVDA Controller, and Tolk integration + +pkgname = cthulhu-git diff --git a/distro-packages/Arch-Linux/cthulhu-git/PKGBUILD b/distro-packages/Arch-Linux/cthulhu-git/PKGBUILD index d68d34f..7628fc8 100644 --- a/distro-packages/Arch-Linux/cthulhu-git/PKGBUILD +++ b/distro-packages/Arch-Linux/cthulhu-git/PKGBUILD @@ -4,21 +4,20 @@ pkgbase=cthulhu-git pkgname=cthulhu-git _pkgname=cthulhu -pkgver=2026.09.03.r475.gd4bec38 +pkgver=2026.10.24.r77.g133953e pkgrel=1 -pkgdesc="Desktop-agnostic screen reader with plugin system, forked from Orca" +pkgdesc="Desktop-agnostic screen reader with speech, Braille, and Tentacle support" url="https://git.stormux.org/storm/cthulhu" arch=(x86_64 aarch64 armv7h) -license=(LGPL-2.1-or-later) +license=(GPL-3.0-or-later) provides=("${_pkgname}=${pkgver}") conflicts=("${_pkgname}") depends=( - # Core AT-SPI accessibility + # Native accessibility and user interface + glibc at-spi2-core glib2 - gobject-introspection-runtime - python-gobject - python-cairo + gdk-pixbuf2 gtk3 # Audio and speech speech-dispatcher @@ -27,85 +26,84 @@ depends=( gst-plugins-good # pulsesink, more decoders # Braille support - python-brltty + brltty liblouis - # Plugin system and D-Bus remote control - python-pluggy - python-tomlkit - python-dasbus - python-msgpack - python-tornado - python-xlib + # Xorg input, window capture, and clipboard operations + libx11 + libxres + libxtst + libxfixes + libxkbcommon + xclip - # Desktop integration - hicolor-icon-theme - libwnck3 - pango - - # System utilities - python-setproctitle - xorg-xkbcomp + # Private D-Bus services + dbus ) optdepends=( - 'git: Install and update third-party plugin sources' - 'python-pywayland: Wayland shared workspace backend' - 'piper-tts: Piper speech backend' - 'socat: Send text to the Self Voice socket from the command line' - - # AI Assistant providers (optional) - 'python-requests: AI Assistant plugin and HTTP provider support' - 'python-pyautogui: AI Assistant mouse and keyboard actions' - 'claude-code: Claude AI provider support' - 'openai-codex: OpenAI Codex provider support' - 'gemini-cli: Gemini AI provider support' - 'ollama: Local AI model support' - - # OCR plugin dependencies (optional) - 'python-pillow: Image processing for OCR' - 'python-pytesseract: Python wrapper for Tesseract OCR engine' + 'git: Discover and update Tentacle repositories' 'tesseract: OCR engine for text recognition' + 'tesseract-data-eng: English OCR language data' ) optdepends_x86_64=( - # The helper is x86_64-only, but this package is architecture-independent. - 'cthulhu-wine-access: Wine, Proton, NVDA Controller, and Tolk integration' + # Wine accessibility helpers are supported on x86_64. + 'wine-access: Wine, Proton, NVDA Controller, and Tolk integration' ) makedepends=( git - meson + go + pkgconf ) +options=(!debug !lto) source=("${_pkgname}::git+https://git.stormux.org/storm/${_pkgname}.git#branch=master") sha512sums=('SKIP') +prepare() { + cd "${_pkgname}" + git checkout -B testing origin/testing +} + pkgver() { cd "${_pkgname}" local projectVersion revisionCount commitHash - projectVersion=$(sed -n "s/^[[:space:]]*version: '\([^']*\)'.*/\1/p" meson.build) - projectVersion=${projectVersion%-master} - projectVersion=${projectVersion//-/.} + projectVersion=$(sed -n 's/^const Version = "\([^"]*\)"/\1/p' internal/version/version.go) [[ -n "${projectVersion}" ]] || return 1 revisionCount=$(git rev-list --count HEAD) commitHash=$(git rev-parse --short=7 HEAD) - printf "%s.r%s.g%s\n" "${projectVersion}" "${revisionCount}" "${commitHash}" + echo "${projectVersion}.r${revisionCount}.g${commitHash}" } build() { cd "${_pkgname}" - arch-meson _build -Dwine-access=disabled - meson compile -C _build + export CGO_ENABLED=1 + export CGO_CPPFLAGS="${CPPFLAGS}" + export CGO_CFLAGS="${CFLAGS}" + export CGO_CXXFLAGS="${CXXFLAGS}" + export CGO_LDFLAGS="${LDFLAGS}" + export GOPATH="${srcdir}/go" + export GOCACHE="${GOCACHE:-${srcdir}/go-build}" + export GOFLAGS="-buildmode=pie -trimpath -ldflags=-linkmode=external -mod=readonly -modcacherw" + + go build -o build/cthulhu ./cmd/cthulhu + go build -tags brlapi -o build/cthulhu-braille ./cmd/cthulhu-braille +} + +check() { + cd "${_pkgname}" + export CGO_ENABLED=1 + export GOPATH="${srcdir}/go" + export GOCACHE="${GOCACHE:-${srcdir}/go-build}" + go test -tags brlapi ./... -count=1 } package() { - arch=(any) - provides=("cthulhu=${pkgver}") - conflicts=(cthulhu) cd "${_pkgname}" - meson install -C _build --destdir "$pkgdir" - - # Remove icon cache - it will be generated by post-install hooks - rm -f "$pkgdir/usr/share/icons/hicolor/icon-theme.cache" + install -Dm755 build/cthulhu "${pkgdir}/usr/bin/cthulhu" + install -Dm755 build/cthulhu-braille "${pkgdir}/usr/bin/cthulhu-braille" + install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" + install -Dm644 AUTHORS "${pkgdir}/usr/share/doc/${pkgname}/AUTHORS" } # vim:set sw=2 sts=-1 et: diff --git a/distro-packages/Arch-Linux/cthulhu-wine-access-git/PKGBUILD b/distro-packages/Arch-Linux/cthulhu-wine-access-git/PKGBUILD deleted file mode 100644 index a01c80d..0000000 --- a/distro-packages/Arch-Linux/cthulhu-wine-access-git/PKGBUILD +++ /dev/null @@ -1,57 +0,0 @@ -# Maintainer: Storm Dragon -# shellcheck shell=bash disable=SC2034,SC2154,SC2164 - -pkgname=cthulhu-wine-access-git -_pkgname=cthulhu -pkgver=2026.09.03.r475.gd4bec38 -pkgrel=1 -pkgdesc="Optional Wine and Proton accessibility bridge for Cthulhu" -url="https://git.stormux.org/storm/cthulhu" -arch=(x86_64) -license=(LGPL-2.1-or-later) -depends=( - glib2 - wine -) -makedepends=( - cmake - git -) -provides=(cthulhu-wine-access) -conflicts=(cthulhu-wine-access) -source=("${_pkgname}::git+https://git.stormux.org/storm/${_pkgname}.git#branch=master") -sha512sums=('SKIP') -options=(!lto) - -pkgver() { - cd "${_pkgname}" - local projectVersion revisionCount commitHash - - projectVersion=$(sed -n "s/^[[:space:]]*version: '\([^']*\)'.*/\1/p" meson.build) - projectVersion=${projectVersion%-master} - projectVersion=${projectVersion//-/.} - [[ -n "${projectVersion}" ]] || return 1 - - revisionCount=$(git rev-list --count HEAD) - commitHash=$(git rev-parse --short=7 HEAD) - printf "%s.r%s.g%s\n" "${projectVersion}" "${revisionCount}" "${commitHash}" -} - -build() { - local sourceDir="${srcdir}/${_pkgname}" - bash "${sourceDir}/scripts/build-wine-access.sh" \ - "${sourceDir}/wine-access" \ - "${sourceDir}/_build/wine-access-build" \ - "${sourceDir}/_build/cthulhu-wine-access.exe" \ - "${sourceDir}/_build/cthulhu-wine-access.exe.so" -} - -package() { - cd "${_pkgname}" - install -Dm755 _build/cthulhu-wine-access.exe \ - "$pkgdir/usr/libexec/cthulhu/wine/cthulhu-wine-access.exe" - install -Dm755 _build/cthulhu-wine-access.exe.so \ - "$pkgdir/usr/libexec/cthulhu/wine/cthulhu-wine-access.exe.so" -} - -# vim:set sw=2 sts=-1 et: diff --git a/distro-packages/Arch-Linux/cthulhu-wine-access/PKGBUILD b/distro-packages/Arch-Linux/cthulhu-wine-access/PKGBUILD deleted file mode 100644 index 8490255..0000000 --- a/distro-packages/Arch-Linux/cthulhu-wine-access/PKGBUILD +++ /dev/null @@ -1,40 +0,0 @@ -# Maintainer: Storm Dragon -# shellcheck shell=bash disable=SC2034,SC2154,SC2164 - -pkgname=cthulhu-wine-access -pkgver=2026.09.09 -pkgrel=1 -pkgdesc="Optional Wine and Proton accessibility bridge for Cthulhu" -url="https://git.stormux.org/storm/cthulhu" -arch=(x86_64) -license=(LGPL-2.1-or-later) -depends=( - glib2 - wine -) -makedepends=( - cmake - git -) -source=("git+https://git.stormux.org/storm/cthulhu.git#tag=${pkgver}") -sha512sums=('SKIP') -options=(!lto !debug) - -build() { - local sourceDir="${srcdir}/cthulhu" - bash "${sourceDir}/scripts/build-wine-access.sh" \ - "${sourceDir}/wine-access" \ - "${sourceDir}/_build/wine-access-build" \ - "${sourceDir}/_build/cthulhu-wine-access.exe" \ - "${sourceDir}/_build/cthulhu-wine-access.exe.so" -} - -package() { - cd cthulhu - install -Dm755 _build/cthulhu-wine-access.exe \ - "$pkgdir/usr/libexec/cthulhu/wine/cthulhu-wine-access.exe" - install -Dm755 _build/cthulhu-wine-access.exe.so \ - "$pkgdir/usr/libexec/cthulhu/wine/cthulhu-wine-access.exe.so" -} - -# vim:set sw=2 sts=-1 et: diff --git a/distro-packages/Arch-Linux/cthulhu/PKGBUILD b/distro-packages/Arch-Linux/cthulhu/PKGBUILD deleted file mode 100644 index 024f61f..0000000 --- a/distro-packages/Arch-Linux/cthulhu/PKGBUILD +++ /dev/null @@ -1,93 +0,0 @@ -# Maintainer: Storm Dragon -# shellcheck shell=bash disable=SC2034,SC2154,SC2164 - -pkgbase=cthulhu -pkgname=cthulhu -pkgver=2026.09.09 -pkgrel=1 -pkgdesc="Desktop-agnostic screen reader with plugin system, forked from Orca" -url="https://git.stormux.org/storm/cthulhu" -arch=(x86_64 aarch64 armv7h) -license=(LGPL-2.1-or-later) -depends=( - # Core AT-SPI accessibility - at-spi2-core - glib2 - gobject-introspection-runtime - python-gobject - python-cairo - gtk3 - # Audio and speech - speech-dispatcher - gstreamer - gst-plugins-base # playbin, audiotestsrc, basic decoders - gst-plugins-good # pulsesink, more decoders - - # Braille support - python-brltty - liblouis - - # Plugin system and D-Bus remote control - python-pluggy - python-tomlkit - python-dasbus - python-msgpack - python-tornado - python-xlib - - # Desktop integration - hicolor-icon-theme - libwnck3 - pango - - # System utilities - python-setproctitle - xorg-xkbcomp -) -optdepends=( - 'git: Install and update third-party plugin sources' - 'python-pywayland: Wayland shared workspace backend' - 'piper-tts: Piper speech backend' - 'socat: Send text to the Self Voice socket from the command line' - - # AI Assistant providers (optional) - 'python-requests: AI Assistant plugin and HTTP provider support' - 'python-pyautogui: AI Assistant mouse and keyboard actions' - 'claude-code: Claude AI provider support' - 'openai-codex: OpenAI Codex provider support' - 'gemini-cli: Gemini AI provider support' - 'ollama: Local AI model support' - - # OCR plugin dependencies (optional) - 'python-pillow: Image processing for OCR' - 'python-pytesseract: Python wrapper for Tesseract OCR engine' - 'tesseract: OCR engine for text recognition' -) -optdepends_x86_64=( - 'cthulhu-wine-access: Wine, Proton, NVDA Controller, and Tolk integration' -) -makedepends=( - git - meson -) -source=("git+https://git.stormux.org/storm/cthulhu.git#tag=${pkgver}") -sha512sums=('SKIP') - -build() { - cd cthulhu - arch-meson _build -Dwine-access=disabled - meson compile -C _build -} - -package() { - arch=(any) - provides=("cthulhu=${pkgver}") - conflicts=(cthulhu) - cd cthulhu - meson install -C _build --destdir "$pkgdir" - - # Remove icon cache - it will be generated by post-install hooks - rm -f "$pkgdir/usr/share/icons/hicolor/icon-theme.cache" -} - -# vim:set sw=2 sts=-1 et: diff --git a/distro-packages/Slackware/cthulhu.SlackBuild b/distro-packages/Slackware/cthulhu.SlackBuild deleted file mode 100755 index 1d46689..0000000 --- a/distro-packages/Slackware/cthulhu.SlackBuild +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash - -# Slackware build script for cthulhu -# Created based on PKGBUILD from Storm Dragon - -cd "$(dirname "$0")" ; CWD=$(pwd) - -PRGNAM=cthulhu -VERSION=${VERSION:-2026.09.09} -BUILD=${BUILD:-1} -TAG=storm -PKGTYPE=txz - -if [ -z "${ARCH:-}" ]; then - case "$( uname -m )" in - i?86) ARCH=i586 ;; - arm*) ARCH=arm ;; - *) ARCH=$( uname -m ) ;; - esac -fi - -# If the variable PRINT_PACKAGE_NAME is set, then this script will report what -# the name of the created package would be, and then exit. This information -# could be useful to other scripts. -if [ -n "${PRINT_PACKAGE_NAME:-}" ]; then - echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE" - exit 0 -fi - -TMP=$CWD -PKG=$TMP/package-$PRGNAM -OUTPUT=$CWD - -if [ "$ARCH" = "i586" ]; then - SLKCFLAGS="-O2 -march=i586 -mtune=i686" - LIBDIRSUFFIX="" -elif [ "$ARCH" = "i686" ]; then - SLKCFLAGS="-O2 -march=i686 -mtune=i686" - LIBDIRSUFFIX="" -elif [ "$ARCH" = "x86_64" ]; then - SLKCFLAGS="-O2 -fPIC" - LIBDIRSUFFIX="64" -else - SLKCFLAGS="-O2" - LIBDIRSUFFIX="" -fi - -set -e - -rm -rf "$PKG" -mkdir -p "$TMP" "$PKG" "$OUTPUT" -cd "$TMP" -rm -rf "$PRGNAM-$VERSION" -git clone --branch "$VERSION" --depth 1 https://git.stormux.org/storm/cthulhu.git "$PRGNAM-$VERSION" -cd "$PRGNAM-$VERSION" -chown -R root:root . -find -L . \ - \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \ - -o -perm 511 \) -exec chmod 755 {} \; -o \ - \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \ - -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \; - -CFLAGS="$SLKCFLAGS" \ -CXXFLAGS="$SLKCFLAGS" \ -meson setup _build \ - --prefix=/usr \ - --libdir="/usr/lib${LIBDIRSUFFIX}" \ - --sysconfdir=/etc \ - --localstatedir=/var \ - --mandir=/usr/man \ - --buildtype=release -meson compile -C _build -DESTDIR="$PKG" meson install -C _build - -find "$PKG" -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \ - | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true - -rm -f "$PKG/usr/share/icons/hicolor/icon-theme.cache" - -mkdir -p "$PKG/usr/doc/$PRGNAM-$VERSION" -cp -a COPYING HACKING README.md README-DEVELOPMENT.md RELEASE-HOWTO \ - "$PKG/usr/doc/$PRGNAM-$VERSION" -cat "$CWD/$PRGNAM.SlackBuild" > "$PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild" - -mkdir -p "$PKG/install" -cat "$CWD/slack-desc" > "$PKG/install/slack-desc" -cat "$CWD/doinst.sh" > "$PKG/install/doinst.sh" - -cd "$PKG" -/sbin/makepkg -l y -c n "$OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE" diff --git a/distro-packages/Slackware/doinst.sh b/distro-packages/Slackware/doinst.sh deleted file mode 100644 index 00d4b61..0000000 --- a/distro-packages/Slackware/doinst.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -if [ -x /usr/bin/update-desktop-database ]; then - /usr/bin/update-desktop-database -q usr/share/applications >/dev/null 2>&1 -fi - -if [ -e usr/share/icons/hicolor/icon-theme.cache ]; then - if [ -x /usr/bin/gtk-update-icon-cache ]; then - /usr/bin/gtk-update-icon-cache usr/share/icons/hicolor >/dev/null 2>&1 - fi -fi diff --git a/distro-packages/Slackware/slack-desc b/distro-packages/Slackware/slack-desc deleted file mode 100644 index d420716..0000000 --- a/distro-packages/Slackware/slack-desc +++ /dev/null @@ -1,19 +0,0 @@ -# HOW TO EDIT THIS FILE: -# The "handy ruler" below makes it easier to edit a package description. -# Line up the first '|' above the ':' following the base package name, and -# the '|' on the right side marks the last column you can put a character in. -# You must make exactly 11 lines for the formatting to be correct. It's also -# customary to leave one space after the ':' except on otherwise blank lines. - - |-----handy-ruler------------------------------------------------------| -cthulhu: cthulhu (Screen reader for blind or visually impaired users) -cthulhu: -cthulhu: Cthulhu is a screen reader for individuals who are blind or visually -cthulhu: impaired, forked from Orca. It provides a way to access applications -cthulhu: and toolkits that support the AT-SPI accessibility infrastructure. -cthulhu: -cthulhu: Homepage: https://git.stormux.org/storm/cthulhu -cthulhu: -cthulhu: -cthulhu: -cthulhu: diff --git a/distro-packages/Slint/README b/distro-packages/Slint/README deleted file mode 100644 index 241befc..0000000 --- a/distro-packages/Slint/README +++ /dev/null @@ -1,37 +0,0 @@ -Cthulhu is a screen reader for individuals who are blind or visually impaired, -forked from Orca. It provides access to applications and toolkits that support -the AT-SPI (e.g., GNOME and other Linux desktop environments). - -This fork is currently maintained by Storm Dragon. It builds on upstream Orca -work, but former Orca maintainers and contributors are not current maintainers -of this fork. - -This screen reader helps users navigate their desktop environment and applications -through speech synthesis and braille output. - -After installation, you can start Cthulhu through your desktop environment -or by running 'cthulhu' from the command line. - -DEPENDENCIES: -This package requires the following packages, all available from SlackBuilds.org: -- at-spi2-core -- brltty -- gobject-introspection -- gstreamer -- gst-plugins-base -- gst-plugins-good -- gtk3 -- liblouis -- libwnck3 -- python3-cairo -- python3-dasbus -- python3-gobject -- python3-pluggy -- python3-pywayland -- python3-setproctitle -- python3-tomlkit -- speech-dispatcher - -BUILD DEPENDENCIES: -- meson -- ninja diff --git a/distro-packages/Slint/cthulhu-info b/distro-packages/Slint/cthulhu-info deleted file mode 100644 index f61157a..0000000 --- a/distro-packages/Slint/cthulhu-info +++ /dev/null @@ -1,10 +0,0 @@ -PRGNAM="cthulhu" -VERSION="2026.09.09" -HOMEPAGE="https://git.stormux.org/storm/cthulhu" -DOWNLOAD="https://git.stormux.org/storm/cthulhu.git" -MD5SUM="SKIP" -DOWNLOAD_x86_64="" -MD5SUM_x86_64="" -REQUIRES="at-spi2-core brltty gobject-introspection gstreamer gst-plugins-base gst-plugins-good gtk3 liblouis libwnck3 python3-cairo python3-dasbus python3-gobject python3-pluggy python3-pywayland python3-setproctitle python3-tomlkit speech-dispatcher" -MAINTAINER="Storm Dragon" -EMAIL="storm_dragon@stormux.org" diff --git a/distro-packages/Slint/cthulhu.SlackBuild b/distro-packages/Slint/cthulhu.SlackBuild deleted file mode 100755 index 1d46689..0000000 --- a/distro-packages/Slint/cthulhu.SlackBuild +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash - -# Slackware build script for cthulhu -# Created based on PKGBUILD from Storm Dragon - -cd "$(dirname "$0")" ; CWD=$(pwd) - -PRGNAM=cthulhu -VERSION=${VERSION:-2026.09.09} -BUILD=${BUILD:-1} -TAG=storm -PKGTYPE=txz - -if [ -z "${ARCH:-}" ]; then - case "$( uname -m )" in - i?86) ARCH=i586 ;; - arm*) ARCH=arm ;; - *) ARCH=$( uname -m ) ;; - esac -fi - -# If the variable PRINT_PACKAGE_NAME is set, then this script will report what -# the name of the created package would be, and then exit. This information -# could be useful to other scripts. -if [ -n "${PRINT_PACKAGE_NAME:-}" ]; then - echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE" - exit 0 -fi - -TMP=$CWD -PKG=$TMP/package-$PRGNAM -OUTPUT=$CWD - -if [ "$ARCH" = "i586" ]; then - SLKCFLAGS="-O2 -march=i586 -mtune=i686" - LIBDIRSUFFIX="" -elif [ "$ARCH" = "i686" ]; then - SLKCFLAGS="-O2 -march=i686 -mtune=i686" - LIBDIRSUFFIX="" -elif [ "$ARCH" = "x86_64" ]; then - SLKCFLAGS="-O2 -fPIC" - LIBDIRSUFFIX="64" -else - SLKCFLAGS="-O2" - LIBDIRSUFFIX="" -fi - -set -e - -rm -rf "$PKG" -mkdir -p "$TMP" "$PKG" "$OUTPUT" -cd "$TMP" -rm -rf "$PRGNAM-$VERSION" -git clone --branch "$VERSION" --depth 1 https://git.stormux.org/storm/cthulhu.git "$PRGNAM-$VERSION" -cd "$PRGNAM-$VERSION" -chown -R root:root . -find -L . \ - \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \ - -o -perm 511 \) -exec chmod 755 {} \; -o \ - \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \ - -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \; - -CFLAGS="$SLKCFLAGS" \ -CXXFLAGS="$SLKCFLAGS" \ -meson setup _build \ - --prefix=/usr \ - --libdir="/usr/lib${LIBDIRSUFFIX}" \ - --sysconfdir=/etc \ - --localstatedir=/var \ - --mandir=/usr/man \ - --buildtype=release -meson compile -C _build -DESTDIR="$PKG" meson install -C _build - -find "$PKG" -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \ - | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true - -rm -f "$PKG/usr/share/icons/hicolor/icon-theme.cache" - -mkdir -p "$PKG/usr/doc/$PRGNAM-$VERSION" -cp -a COPYING HACKING README.md README-DEVELOPMENT.md RELEASE-HOWTO \ - "$PKG/usr/doc/$PRGNAM-$VERSION" -cat "$CWD/$PRGNAM.SlackBuild" > "$PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild" - -mkdir -p "$PKG/install" -cat "$CWD/slack-desc" > "$PKG/install/slack-desc" -cat "$CWD/doinst.sh" > "$PKG/install/doinst.sh" - -cd "$PKG" -/sbin/makepkg -l y -c n "$OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE" diff --git a/distro-packages/Slint/doinst.sh b/distro-packages/Slint/doinst.sh deleted file mode 100644 index 00d4b61..0000000 --- a/distro-packages/Slint/doinst.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -if [ -x /usr/bin/update-desktop-database ]; then - /usr/bin/update-desktop-database -q usr/share/applications >/dev/null 2>&1 -fi - -if [ -e usr/share/icons/hicolor/icon-theme.cache ]; then - if [ -x /usr/bin/gtk-update-icon-cache ]; then - /usr/bin/gtk-update-icon-cache usr/share/icons/hicolor >/dev/null 2>&1 - fi -fi diff --git a/distro-packages/Slint/slack-desc b/distro-packages/Slint/slack-desc deleted file mode 100644 index 3f09536..0000000 --- a/distro-packages/Slint/slack-desc +++ /dev/null @@ -1,19 +0,0 @@ -# HOW TO EDIT THIS FILE: -# The "handy ruler" below makes it easier to edit a package description. -# Line up the first '|' above the ':' following the base package name, and -# the '|' on the right side marks the last column you can put a character in. -# You must make exactly 11 lines for the formatting to be correct. It's also -# customary to leave one space after the ':' except on otherwise blank lines. - - |-----handy-ruler------------------------------------------------------| -cthulhu: cthulhu (Screen reader for blind or visually impaired users) -cthulhu: -cthulhu: Cthulhu is a screen reader for individuals who are blind or visually -cthulhu: impaired, forked from Orca. It provides a way to access applications -cthulhu: and toolkits that support the AT-SPI (e.g., the GNOME desktop). -cthulhu: -cthulhu: Homepage: https://git.stormux.org/storm/cthulhu -cthulhu: -cthulhu: -cthulhu: -cthulhu: diff --git a/docs/LOGGING.md b/docs/LOGGING.md deleted file mode 100644 index be8db6a..0000000 --- a/docs/LOGGING.md +++ /dev/null @@ -1,46 +0,0 @@ -# Cthulhu Logging Guidelines - -This document defines the preferred format for debug logging in Cthulhu. -The goal is to keep logs consistent, searchable, and easy to scan. - -## Helpers - -Use the helpers in `cthulhu.debug` for new logs: - -- `debug.print_log(level, prefix, message, reason=None, timestamp=False, stack=False)` -- `debug.print_log_tokens(level, prefix, tokens, reason=None, timestamp=False, stack=False)` - -These helpers ensure the prefix and optional reason tag are formatted consistently. -Timestamps are appended at the end of the message when enabled. - -## Prefixes - -Use short, uppercase prefixes that identify the subsystem: - -- `EVENT MANAGER` -- `FOCUS MANAGER` -- `INPUT EVENT` -- `SCRIPT MANAGER` -- `WEB` - -## Messages - -- Keep messages short and action-focused. -- Do not include the prefix in the message. -- Prefer consistent verbs (e.g., "Not using …", "Setting …", "Ignoring …"). - -## Reason Tags - -Use reason tags to explain decisions or early exits. - -- Lowercase with hyphens (e.g., `focus-mode`, `no-active-script`). -- Use a short phrase rather than a full sentence. -- If a human-readable reason is already available, it can be used directly. - -## Examples - -```text -WEB: Not using caret navigation (reason=disabled) -FOCUS MANAGER: Setting locus of focus to existing locus of focus (reason=no-change) -SCRIPT MANAGER: Setting active script to [script] (reason=focus: active-window) -``` diff --git a/docs/atspi-document-selection-handoff.md b/docs/atspi-document-selection-handoff.md deleted file mode 100644 index d615eb6..0000000 --- a/docs/atspi-document-selection-handoff.md +++ /dev/null @@ -1,51 +0,0 @@ -# AT-SPI Document Selection Branch Handoff - -Branch: `atspi-document-selection` - -## Implemented - -- Added document-wide AT-SPI selection normalization in - `src/cthulhu/ax_document_selection.py`. -- Reworked text-selection handling in `src/cthulhu/script_utilities.py` to use - the shared adapter where possible and fall back cleanly where not. -- Updated primary callers in the default and web scripts so copy/cut, - selection announcements, and selected-text queries use the shared selection - path. -- Added keyboard-driven clipboard announcement fallback in - `src/cthulhu/scripts/default.py`, including Wayland-specific policy changes. -- Fixed `build-local.sh` so rebuilding refreshes modified installed modules - under `~/.local`. - -## Verified - -- `python3 -m pytest -q tests/test_document_selection_regressions.py` -- `python3 -m pytest -q tests/test_default_script_clipboard_regressions.py` -- `python3 -m pytest -q tests/test_web_input_regressions.py` -- `HOME=/tmp/cthulhu-test-home python3 -m pytest -q tests` -- `./build-local.sh` - -Latest full-suite result before handoff: `95 passed, 1 warning`. - -## Still Open - -- Browser link-text selection is still not reliable in Chromium/Edge and in - web-backed content like Steam. -- The current branch includes extra diagnostics around clipboard and selection - paths because they were useful during manual debugging. -- The newest attempted web fix is in `src/cthulhu/scripts/web/script.py`, but - the manual repro still fails: - - selecting link text with `Shift+Left` / `Shift+Right` - - hearing no selection announcement - - then having copy behavior depend on fallback logic instead of real - selection state - -## Useful Files For Follow-Up - -- `src/cthulhu/ax_document_selection.py` -- `src/cthulhu/script_utilities.py` -- `src/cthulhu/scripts/default.py` -- `src/cthulhu/scripts/web/script.py` -- `src/cthulhu/scripts/web/script_utilities.py` -- `tests/test_document_selection_regressions.py` -- `tests/test_default_script_clipboard_regressions.py` -- `tests/test_web_input_regressions.py` diff --git a/docs/man/cthulhu.1 b/docs/man/cthulhu.1 deleted file mode 100644 index 1d9bfa5..0000000 --- a/docs/man/cthulhu.1 +++ /dev/null @@ -1,336 +0,0 @@ -.\" Copyright (C) 2005-2009 Sun Microsystems Inc. -.\" -.\" This is free software; you may redistribute it and/or modify -.\" it under the terms of the GNU General Public License as -.\" published by the Free Software Foundation; either version 2, -.\" or (at your option) any later version. -.\" -.\" This is distributed in the hope that it will be useful, but -.\" WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this; if not write to the Free Software Foundation, Inc. -.\" 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA -'\" -.TH cthulhu 1 "10 April 2026" "Stormux" -.SH NAME -cthulhu \- a scriptable screen reader -.SH SYNOPSIS -.B cthulhu -.RI [ option... ] -.SH DESCRIPTION -.B cthulhu -is a screen reader for people with visual impairments, -it provides alternative access to the desktop by using speech synthesis and braille. -.P -.B cthulhu -is maintained in this fork by Storm Dragon. It is forked from Orca and builds -on upstream work by former Orca maintainers and contributors, who are part of -the project's history but are not current maintainers of this fork. -.P -.B cthulhu -works with applications and toolkits that support -the Assistive Technology Service Provider Interface (AT-SPI), which -is the primary assistive technology infrastructure for Linux and -Solaris. Applications and toolkits supporting the AT-SPI include the -GNOME Gtk+ toolkit, the Java platform's Swing toolkit, LibreOffice, -Gecko, WebKitGtk, and the KDE Qt toolkit. -.SH OPTIONS -.TP -.B \-s, --setup -When starting -.BR cthulhu , -initiate the GUI-based configuration. -.TP -.BI "\-u, --user-prefs-dir=" dirname -When starting -.BR cthulhu , -use -.I dirname -as an alternate directory for the user preferences. -.TP -.BI "\-e, \-\-enable=" speech|braille|braille\-monitor -When starting -.BR cthulhu , -force the enabling of the supplied options. -.TP -.BI "\-d, \-\-disable=" speech|braille|braille\-monitor -When starting -.BR cthulhu , -force the disabling of the supplied options. -.TP -.B \-l, --list-apps -Prints the names of all the currently running applications. This -is used primarily for debugging purposes to see if -.B cthulhu -can talk to the accessibility infrastructure. Note that if -.B cthulhu -is already running, this will not kill the other -.B cthulhu -process. It will just list the currently running applications, -and you will see -.B cthulhu -listed twice: once for the existing -.B cthulhu -and once for this instance. -.TP -.B \--debug -Enables debug output for -.B cthulhu -and sends all debug output to a file with a name of the -form 'debug-YYYY-MM-DD-HH:MM:SS.out' in the current directory. -The YYYY-MM-DD-HH:MM:SS portion will be replaced with the current -date and time. -.TP -.BI "\--debug-file=" filename -Enables debug output for -.B cthulhu -and sends all debug output to the given filename. -.TP -.B \-v, --version -outputs -.B cthulhu -version number and exits. -.TP -.B \-h, \--help -displays -.B cthulhu -help and exits. -.TP -.B \--replace -Replace a currently running -.BR cthulhu -process. By default, if -.BR cthulhu -detects an existing -.BR cthulhu -process for the same session, it will not start a new -.BR cthulhu -process. This option will kill and cleanup after any existing -.BR cthulhu -process and then start a new -.BR cthulhu -in its place. -.TP - -.SH KEYBOARD SETTINGS -Cthulhu provides two keyboard modes, Desktop and Laptop keyboard layout. The -.B Cthulhu_Modifier -key is -.B Insert -in desktop keyboard layout and -.B Caps_Lock -in laptop keyboard layout. - -.B Cthulhu -uses its configured keyboard shortcuts to navigate the desktop and interact with various applications. The flat review commands provide an alternative method of interaction in certain inaccessible applications. It should not be confused with flat review functionality provided by other screen readers. - -.SH Desktop Mode - -.B Flat review commands - -.B "Numpad-7" -move the flat review cursor to the previous line and read it. - -.B "Numpad-8" -read the current line. - -.B "Numpad-9" -move the flat review cursor to the next line and read it. - -.B "Numpad-4" -move the flat review cursor to the previous word and read it. - -.B "Numpad-5" -read the current word. - -.B "Numpad-6" -move the flat review cursor to the next word and read it. - -.B "Numpad-1" -move the flat review cursor to the previous character and read it. - -.B "Numpad-2" -read the current character. - -.B "Numpad-3" -move the flat review cursor to the next character and read it. - -.B "Numpad-slash" -perform a left mouse click at the location of the flat review cursor. - -.B "Numpad-star" -perform a right mouse click at the location of the flat review cursor. - -.B Bookmark commands - -.B "Alt+Insert+[1-6]" -assign a bookmark to a numbered slot. If a bookmark already exists in the slot it will be replaced with the new one. - -.B "Insert+[1-6]" -go to the position pointed to by the bookmark bound to this numbered slot. - -.B "Insert+B and Insert+Shift+B" -move between the given bookmarks for the given application or page. - -.B "Alt+Insert+B" -save the defined bookmarks for the current application or page. - - -.B Miscellaneous functions - -.B "Numpad+Plus" - 'say all' command; reads from the current position of the caret to the end of the document. - -.B "Numpad+Enter" - 'Where am I' command; speaks information such as the title of the current application window, as well as the name of the control that currently has focus. - -.B "Insert+H" -enter into cthulhu's 'learn mode'; press Escape to exit. - -.B "Insert+Shift+Backslash" -toggle live regions monitoring on and off. - -.B "Insert+F" -speak font and attribute information for the current character. - -.B "Insert+Space" -Launch the cthulhu Configuration dialog. - -.B "Insert+Ctrl+Space" -reload user settings and reinitialize services as necessary. Also launches the cthulhu Configuration dialog for the current application. - -.B "Insert+S" -toggle speech on and off. - -.B "Insert+F11" -toggle the reading of tables, either by single cell or whole row. - -.SH Laptop Mode - -.B Flat review commands - -.B "Caps_Lock+U" -move the flat review cursor to the previous line and read it. Double-click to move flat review to the top of the current window. - -.B "Caps_Lock+I" -read the current line. Double-click to read the current line along with formatting and capitalization details. - -.B "Caps_Lock+O" -move the flat review cursor to the next line and read it. Double- click to move flat review to the bottom of the current window. - -.B "Caps_Lock+J" -move the flat review cursor to the previous word and read it. Double-click to move flat review to the word above the current word. - -.B "Caps_Lock+K" -read the current word. Double-click to spell the word. Triple-click to hear the word spelled phonetically. - -.B "Caps_Lock+L" -move the flat review cursor to the next word and read it. Double- click to move flat review to the word below the current word. - -.B "Caps_Lock+M" -move the flat review cursor to the previous character and read it. Double-click to move flat review to the end of the current line. - -.B "Caps_Lock+Comma" -read the current character. Double-click to pronounce the character phonetically if it is a letter. - -.B "Caps_Lock+Period" -move the flat review cursor to the next character and read it. - -.B "Caps_Lock+7" -perform a left mouse click at the location of the flat review cursor. - -.B "Caps_Lock+8" -perform a right mouse click at the location of the flat review cursor. - -.B Bookmark commands - -.B "Alt+Caps_Lock+[1-6]" - -add a bookmark to the numbered slot. If a bookmark already exists for the slot it will be replaced with the new one. - -.B "Caps_Lock+[1-6]" -go to the position pointed to by the bookmark bound to this numbered slot. - -.B "Caps_Lock+Band Caps_Lock+Shift+B" -move between the given bookmarks for the given application or page. - -.B "Alt+Caps_Lock+B" -save the defined bookmarks for the current application or page. - -.B Miscellaneous functions - -.B "Caps_Lock+Semicolon" - 'Say all' command; reads from the current position of the caret to the end of the document. -.B "Caps_Lock+Enter" - 'Where am I' command; speaks information such as the title of the current application window, as well as the name of the control that currently has focus. - -.B "Caps_Lock+H" -enter learn mode (press Escape to exit). - -.B "Caps_Lock+Shift+Backslash" -toggle live regions monitoring on and off. - -.B "Caps_Lock+F" -speak font and attribute information for the current character. - -.B "Caps_Lock+Space" -launch the cthulhu Configuration dialog. - -.B "Caps_Lock+Ctrl+Space" -reload user settings and reinitialize services as necessary; also launches the cthulhu Configuration dialog for the current application. - -.B "Caps_Lock+S" -toggle speech on and off. - -.B "Caps_Lock+F11" -toggle the reading of tables, either by single cell or whole row. - -.SH FILES -.TP -.BI ~/.local/share/cthulhu -.B Cthulhu -user preferences directory -.TP -.BI ~/.local/share/cthulhu/user-settings.toml -.B Cthulhu -user preferences configuration file. -.TP -.BI ~/.local/share/cthulhu/cthulhu-customizations.py -.B Cthulhu -user customizations configuration file - -.TP -.BI ~/.local/share/cthulhu/cthulhu-scripts -.B Cthulhu -user cthulhu scripts directory -.TP -.BI ~/.local/share/cthulhu/bookmarks -.B Cthulhu -user bookmarks directory -.TP -.BI ~/.local/share/cthulhu/app-settings -.B Cthulhu -user application specific settings directory - - -.SH AUTHOR -.B Cthulhu -originated as a community effort led by the Sun Microsystems Inc. -Accessibility Program Office and with contributions from many community members. -.SH SEE ALSO -For more information please visit -.B Cthulhu -at -.UR https://git.stormux.org/storm/cthulhu - -.UE -.P -The -.B Stormux -community list is available at -.UR https://groups.io/g/stormux - -.UE diff --git a/docs/man/meson.build b/docs/man/meson.build deleted file mode 100644 index 6e4d1d3..0000000 --- a/docs/man/meson.build +++ /dev/null @@ -1 +0,0 @@ -install_man('cthulhu.1') \ No newline at end of file diff --git a/docs/meson.build b/docs/meson.build deleted file mode 100644 index 223b302..0000000 --- a/docs/meson.build +++ /dev/null @@ -1 +0,0 @@ -subdir('man') \ No newline at end of file diff --git a/docs/superpowers/specs/2026-04-05-sounds-tab-design.md b/docs/superpowers/specs/2026-04-05-sounds-tab-design.md deleted file mode 100644 index f30dac1..0000000 --- a/docs/superpowers/specs/2026-04-05-sounds-tab-design.md +++ /dev/null @@ -1,171 +0,0 @@ -# Sounds Tab Design - -Date: 2026-04-05 - -## Context - -Cthulhu currently stores several non-speech sound settings in the general settings file, but the preferences dialog does not present them coherently: - -- The General tab contains an inline Sound section for backend, theme, and role-sound presentation. -- The progress-bar beep checkbox lives in the General tab's progress-bar section. -- `soundVolume` exists in settings and the user's active profile, but there is no UI control for it. -- `enableSound`, `playSoundForRole`, `playSoundForState`, `playSoundForPositionInSet`, and `playSoundForValue` exist as persisted settings but are not currently exposed in the dialog. -- `progressBarBeepInterval` exists in runtime defaults but is not part of the normal persisted general-settings key list. - -The result is that sound-related behavior is split across the dialog and some active settings cannot be inspected or changed from the UI. - -## Goals - -- Add a dedicated `Sounds` preferences tab. -- Move currently exposed sound-related controls out of `General` and into `Sounds`. -- Move the progress-bar beep option into `Sounds` while leaving the rest of the progress-bar section in `General`. -- Expose currently hidden sound-related settings in the UI. -- Add a UI control for `soundVolume`. -- Expose and persist `progressBarBeepInterval`. -- Preserve the existing settings model and save format. -- Avoid clobbering unrelated settings when saving preferences. - -## Non-Goals - -- No refactor of the broader preferences architecture. -- No changes to sound playback implementation outside what is needed to load and save settings correctly. -- No new settings schema beyond persisting the existing hidden `progressBarBeepInterval`. -- No dynamic enable/disable logic for sound controls in this pass. - -## Design Summary - -Add a new notebook page labeled `Sounds` and make it the single home for non-speech sound configuration. Remove the inline Sound frame from `General`. Keep the existing progress-bar speech/braille controls and shared progress-bar behavior controls in `General`, but move beep-specific controls into `Sounds`. - -The new tab will use existing settings keys wherever possible and will save through the existing `prefsDict` and settings-manager flow. - -## Sounds Tab Layout - -The `Sounds` tab will contain three sections. - -### Output - -- `enableSound` checkbox -- `soundVolume` slider -- `soundSink` combo box - -`soundVolume` should be represented by a native `GtkScale` and persisted back to the existing floating-point `soundVolume` setting. The control should initialize from `prefsDict.get("soundVolume", settings.soundVolume)`. - -For this implementation, the slider should match the stored setting directly rather than introducing a new percentage representation. That keeps the implementation small and avoids conversion-only complexity in a settings path that already exists. - -### Presentation - -- `soundTheme` combo box -- `roleSoundPresentation` combo box -- `playSoundForRole` checkbox -- `playSoundForState` checkbox -- `playSoundForPositionInSet` checkbox -- `playSoundForValue` checkbox - -These controls will expose already-existing settings and use the same `prefsDict` update pattern already used by the current dialog. - -### Alerts - -- `beepProgressBarUpdates` checkbox -- `progressBarBeepInterval` spin button - -This section controls only beep-based progress-bar alerts. The label should make it clear that the interval is beep-specific, not the general progress-bar announcement interval. - -## General Tab Changes - -Keep these controls in `General`: - -- `speakProgressBarUpdates` -- `brailleProgressBarUpdates` -- `progressBarUpdateInterval` -- `progressBarVerbosity` -- `ignoreStatusBarProgressBars` - -Remove these from `General`: - -- the inline Sound frame -- `beepProgressBarUpdates` - -This preserves the current organization for general progress-bar announcement behavior while moving sound-only concerns into the new tab. - -## Settings and Persistence - -### Existing Keys Reused - -The new UI will continue to use the existing settings keys: - -- `enableSound` -- `soundVolume` -- `soundSink` -- `soundTheme` -- `roleSoundPresentation` -- `playSoundForRole` -- `playSoundForState` -- `playSoundForPositionInSet` -- `playSoundForValue` -- `beepProgressBarUpdates` - -### Persisted Hidden Key - -Add `progressBarBeepInterval` to the persisted general-settings key list so it round-trips through: - -- defaults in `settings.py` -- settings-manager general settings -- TOML backend save/load -- `prefsDict` in the preferences dialog - -This avoids the current mismatch where beep interval exists as a runtime default but is not part of the normal persisted general-settings path. - -### Save Behavior - -The implementation should continue to update individual keys in `prefsDict` and then rely on the existing general-settings save flow. No bulk replacement of the whole settings structure should be introduced. - -This is specifically intended to avoid accidental overwrites of unrelated settings already present in `user-settings.toml`. - -## Default Values - -- Keep `progressBarUpdateInterval = 10` as the default for speech and braille progress-bar updates. -- Keep `progressBarBeepInterval = 0` as the default for beep-based progress-bar updates. -- Keep `soundVolume = 0.5` as the existing default unless the user explicitly changes it. - -The new UI should reflect these values accurately on load. - -## Accessibility - -Use native GTK controls and follow the existing preferences-dialog patterns: - -- every label must be associated with its control via `mnemonic_widget` -- checkboxes should use the existing `checkButtonToggled` convention when possible -- combo boxes should keep proper `label-for` / `labelled-by` relationships -- no custom-drawn controls -- no keyboard traps - -The new tab should be fully reachable with standard tab navigation. - -## Implementation Notes - -Expected files to change: - -- `src/cthulhu/cthulhu-setup.ui` -- `src/cthulhu/cthulhu_gui_prefs.py` -- `src/cthulhu/settings.py` - -Implementation should: - -- add the new notebook page and move or recreate the relevant widgets there -- initialize and save the new sound controls using existing dialog patterns -- add explicit handling for `soundVolume` -- add explicit handling for `progressBarBeepInterval` -- keep all unrelated preference behavior unchanged - -## Verification - -The implementation should be considered complete only after all of the following are checked: - -1. The preferences dialog opens and the new `Sounds` tab is present. -2. Existing sound settings load into the correct controls. -3. Changing sound settings updates `prefsDict` without breaking unrelated settings. -4. Saving preferences preserves unrelated keys in `user-settings.toml`. -5. `progressBarBeepInterval` is written and reloaded correctly. -6. The General tab still handles speech/braille progress-bar settings correctly. -7. Touched Python files pass compile checks. -8. Manual verification confirms keyboard navigation and label association remain intact. diff --git a/docs/superpowers/specs/2026-04-07-mouse-review-wayland-design.md b/docs/superpowers/specs/2026-04-07-mouse-review-wayland-design.md deleted file mode 100644 index bd4f04a..0000000 --- a/docs/superpowers/specs/2026-04-07-mouse-review-wayland-design.md +++ /dev/null @@ -1,117 +0,0 @@ -# Guarded Mouse Review Wayland Backport - -## Summary - -Backport Orca's modern mouse review split into Cthulhu in a conservative way. Keep the current X11 `Wnck` plus `mouse:abs` implementation as the existing path. Add a second path that uses `Atspi.Device` pointer monitoring only when the local AT-SPI version is new enough and the compositor/device actually grants `POINTER_MONITOR`. If either condition fails, Cthulhu stays on the current behavior. - -This is explicitly an X-safe design. The X11 path remains first-class and unchanged in behavior. Wayland support is opportunistic and must fail closed. - -## Current State - -- Cthulhu mouse review currently depends on `Wnck` window lookup and `mouse:abs` events in [mouse_review.py](/home/storm/devel/cthulhu/src/cthulhu/mouse_review.py). -- Recent local changes already avoid importing `Wnck` on Wayland to suppress the terminal warning, but they do not add functional Wayland mouse review. -- Cthulhu already has an `Atspi.Device` for keyboard handling in [input_event_manager.py](/home/storm/devel/cthulhu/src/cthulhu/input_event_manager.py), which is the required foundation for an Orca-style pointer-monitor path. - -## Goals - -- Preserve existing X11 mouse review behavior. -- Add a guarded Wayland-capable path modeled on Orca's `Atspi.Device` pointer monitoring. -- Avoid startup warnings from `Wnck` on Wayland. -- Avoid enabling any new path unless support is positively confirmed at runtime. - -## Non-Goals - -- No full Orca mouse review rewrite beyond the pointer-monitor split. -- No removal or semantic change of the current X11 `Wnck` path. -- No OCR refactor beyond existing `Wnck` gating already added. -- No assumption that Wayland mouse review will work everywhere; unsupported compositors must remain a no-op. - -## Design - -### Capability Detection - -Mouse review will select its backend at runtime: - -1. If AT-SPI version is at least `2.60`, or the pre-release threshold Orca used (`2.59.90`), Cthulhu may try the new backend. -2. The new backend must call `set_capabilities(... | POINTER_MONITOR)` on the existing `Atspi.Device`. -3. The new backend is considered available only if `POINTER_MONITOR` is present in the returned capability set. -4. If any of those checks fail, Cthulhu uses the existing X11 path. - -This means X11 systems on older stacks continue to use the current implementation. Wayland systems with insufficient AT-SPI support do not partially enable mouse review. - -### InputEventManager Extension - -Extend [input_event_manager.py](/home/storm/devel/cthulhu/src/cthulhu/input_event_manager.py) with narrow pointer-monitor wrappers: - -- `enable_pointer_monitoring() -> bool` -- `start_pointer_watcher(callback) -> None` -- `stop_pointer_watcher() -> None` - -These wrappers should mirror Orca's error handling: - -- return `False` on missing device or `GLib.GError` -- never raise into callers -- leave existing keyboard handling unchanged - -No unrelated device-manager refactor is included in this pass. - -### Mouse Review Backend Split - -Update [mouse_review.py](/home/storm/devel/cthulhu/src/cthulhu/mouse_review.py) to maintain two internal paths: - -- Legacy path: - - existing `Wnck` window tracking - - existing `mouse:abs` listener - - existing absolute-coordinate flow -- New path: - - register a `pointer-moved` watcher on the `Atspi.Device` - - use the accessible object and local coordinates delivered by AT-SPI - - if the event source is an application, resolve the containing window from the app's accessible children - - otherwise use the event object directly - -The common object-presentation logic should stay shared as much as possible. Only the event source and coordinate acquisition differ. - -### Safety Rules - -- Do not change the old X11 path except for harmless factoring needed to share code. -- Do not force the new path on X11 systems that are currently using the legacy path successfully. -- If pointer monitoring disconnects, errors, or cannot be enabled, mouse review must behave as unavailable rather than falling into a broken mixed state. -- Existing `Wnck` suppression on Wayland remains in place. - -## Testing - -### Automated - -Add focused regressions for: - -- version/capability gating chooses the new backend only when allowed -- `enable_pointer_monitoring()` returns `False` on capability failure -- pointer watcher start/stop are no-ops when there is no device -- mouse review activation chooses the legacy backend when AT-SPI support is not available -- mouse review activation chooses the pointer-monitor backend when support is available - -Tests should mock AT-SPI rather than requiring a compositor. - -### Manual - -X11: - -- mouse review still enables and behaves as before -- no regressions in pointer routing or reviewed object presentation - -Wayland: - -- no `Wnck` warning on startup -- mouse review only enables when AT-SPI pointer monitoring is actually available -- if supported, pointer hover review works without breaking keyboard handling -- if unsupported, failure is clean and explicit rather than noisy or partially broken - -## Risks - -- The local environment here is still on AT-SPI `2.58.4`, so the new backend cannot be exercised live in this workspace. -- The guarded design limits that risk by preserving the existing path and enabling the new path only under the same runtime conditions Orca used. -- The main regression risk is accidental interaction with Cthulhu's existing keyboard `Atspi.Device`; that is why the change is limited to small wrappers plus mouse-review-specific watcher usage. - -## Recommendation - -Implement the guarded dual-path backport and stop there. Do not port broader Orca mouse review refactors in the same pass. diff --git a/docs/superpowers/specs/2026-04-09-wayland-compositor-event-interface-design.md b/docs/superpowers/specs/2026-04-09-wayland-compositor-event-interface-design.md deleted file mode 100644 index ab02403..0000000 --- a/docs/superpowers/specs/2026-04-09-wayland-compositor-event-interface-design.md +++ /dev/null @@ -1,355 +0,0 @@ -# Wayland Compositor Event Interface For Churn Reduction - -## Summary - -Revise Cthulhu's event interface so Wayland session state can reduce AT-SPI churn before it reaches the current object-event pipeline. Keep `AT-SPI` authoritative for object semantics, text, selection, and actions. Add a small compositor-state normalization layer that is authoritative for desktop context such as active workspace, active top-level window, and focus routing during transitions. - -This is not a Newton-style redesign. It is a conservative performance-oriented split intended to reduce queue growth, redundant script activation, and processing of stale events on Wayland systems while preserving existing accessibility semantics. - -## Current State - -- Cthulhu's main event flow is still centered on `Atspi.EventListener` and a single `event_manager` queue in `src/cthulhu/event_manager.py`. -- The current design already spends significant effort filtering spam, handling floods and deluges, recovering focus context, and pruning duplicate events. -- `src/cthulhu/input_event_manager.py` already uses `Atspi.Device` for keyboard handling and pointer monitoring wrappers, so Cthulhu already has one narrow example of a side-channel interface on Wayland. -- `src/cthulhu/focus_manager.py` and `src/cthulhu/cthulhu_state.py` still derive active-window and focus truth primarily from AT-SPI objects and events. -- `src/cthulhu/wnck_support.py` correctly gates `Wnck` to X11-only use, which is a useful precedent for runtime capability-based backend selection. -- Recent work in this repository has improved individual Wayland features, but there is not yet a compositor-agnostic interface for desktop state that can suppress irrelevant object churn before it enters the hot path. - -## Goals - -- Reduce AT-SPI event churn on Wayland systems before it reaches the main queue. -- Keep the design generic and compositor-agnostic at the Cthulhu interface level. -- Preserve current `AT-SPI` object semantics and script behavior as much as possible. -- Improve prioritization of focus and active-window related work during workspace and window transitions. -- Provide a single internal contract that can support Mutter, KWin, and wlroots-based compositors without teaching the rest of Cthulhu about compositor brands. -- Fail safe to current behavior when compositor state is missing, incomplete, or inconsistent. - -## Non-Goals - -- No Newton-style compositor-authoritative accessibility tree transport. -- No replacement of AT-SPI for object semantics, text, selection, caret movement, or actions. -- No dependency on `niri` IPC, GNOME Shell extensions, or KWin scripts in the core architecture for phase one. -- No requirement that every supported compositor expose the same amount of state. -- No broad rewrite of script listeners or script modules in this pass. - -## Approaches Considered - -### 1. Direct Wayland Integration Inside `event_manager` - -Teach `event_manager` to consume shared Wayland state directly and add compositor-specific checks inside its current logic. - -Pros: - -- smallest code footprint up front -- no new internal abstraction layer - -Cons: - -- quickly leaks compositor-specific capability checks into the hottest code path -- makes Mutter, KWin, and wlroots differences part of `event_manager` logic -- harder to test in isolation - -### 2. Thin Compositor-State Adapter Layer - -Introduce a small internal normalization layer that consumes shared compositor-facing signals and emits a compact generic event vocabulary to `event_manager`. - -Pros: - -- keeps compositor-specific capability detection out of the hot path -- gives `event_manager` one stable interface to consume -- matches the long-term direction of consuming normalized state below the main screen reader logic -- easy to test with mocked backends - -Cons: - -- adds one more internal subsystem -- requires careful definition of authority boundaries to avoid duplication with AT-SPI - -### 3. Full Compositor-Authoritative Routing - -Make compositor state the primary truth for most event routing and use AT-SPI only for fine-grained object semantics. - -Pros: - -- highest potential performance ceiling -- most direct path toward a future compositor-led architecture - -Cons: - -- much higher correctness risk -- too large a shift for a churn-focused first pass -- would require significantly more backend-specific coverage and recovery logic - -## Recommendation - -Implement approach 2. - -For phase one, Cthulhu should add a thin compositor-state adapter layer. It should be authoritative for desktop context and transition hints, but not for accessible object semantics. This gives Cthulhu a generic way to suppress or reprioritize AT-SPI noise without requiring a full architecture rewrite. - -## Design - -### Authority Split - -The revised interface should split responsibility cleanly: - -- compositor-state adapter is authoritative for: - - active desktop context - - active workspace set - - active top-level window identity when available - - desktop transition start and end - - focus-routing hints during compositor-driven changes -- AT-SPI remains authoritative for: - - focused accessible object - - accessible roles, names, and states - - text, caret, and selection semantics - - actionable objects and accessibility events consumed by scripts - -Inference from upstream: current Orca remains AT-SPI-authoritative in its main pipeline, while newer GNOME accessibility work moves normalization below Orca rather than throughout it. This design follows that same direction without depending on Newton itself. - -### New Internal Boundary - -Add a new internal interface named `CompositorStateAdapter`. - -Responsibilities: - -- detect and activate the best available compositor-state backend at runtime -- normalize raw backend signals into a small generic event vocabulary -- maintain a current desktop-context snapshot -- emit state deltas and control hints to `event_manager` -- degrade to no-op behavior when capabilities are absent or unclear - -This adapter should not expose compositor-specific event names or objects outside its own implementation. - -### Normalized Event Vocabulary - -The adapter should emit two families of signals. - -State deltas: - -- `workspace_state_changed` -- `desktop_focus_context_changed` -- `desktop_transition_started` -- `desktop_transition_finished` - -Control hints: - -- `pause_atspi_churn` -- `resume_atspi_churn` -- `prioritize_focus` -- `deprioritize_context` -- `flush_stale_atspi_events` - -This vocabulary is intentionally small. It exists to shape queueing and prioritization, not to mirror every compositor event. - -### Desktop Context Snapshot - -The adapter should maintain a compact snapshot object with fields along these lines: - -- `session_type` -- `backend_name` -- `active_workspace_ids` -- `active_window_token` -- `focus_route_token` -- `transition_active` -- `timestamp` - -`active_window_token` and `focus_route_token` are intentionally generic. They should be comparable identifiers, not compositor-native objects leaking into the rest of Cthulhu. - -### Backend Selection - -Phase one should use capability-driven backend selection with generic shared interfaces first. - -Preferred order: - -1. `WaylandSharedProtocolsBackend` -2. `AtspiContextBackend` -3. `NullBackend` - -#### `WaylandSharedProtocolsBackend` - -This backend should consume shared Wayland-facing protocols where available and normalize them for Cthulhu. The first protocol target should be `ext_workspace_v1`. - -Reasoning: - -- `ext_workspace_v1` provides workspace groups, workspaces, active state, and atomic `done` notifications, which is exactly the sort of low-volume desktop-state signal Cthulhu needs to reason about transitions. -- As of April 9, 2026, Wayland Explorer lists `ext_workspace_v1` support for Mutter `49.2`, KWin `6.6`, and niri `25.11`, making it a good cross-family starting point. - -This backend should only expose normalized state to the rest of Cthulhu. It should not expose protocol objects or protocol-specific state transitions outside the backend. - -#### `AtspiContextBackend` - -This backend should use current AT-SPI-based context recovery when shared Wayland state is missing or insufficient. It does not improve churn by itself, but it preserves current behavior and keeps the adapter contract usable everywhere. - -#### `NullBackend` - -This backend should emit no compositor hints and leave the rest of Cthulhu in its current behavior. It is the fail-safe path. - -### Explicit Exclusions For Phase One - -The following are not part of the core architecture in phase one: - -- `niri` IPC as a first-class public interface -- compositor-specific `D-Bus` integrations -- GNOME Shell extension event streams -- KWin scripting APIs - -These may become optional backend implementations in the future if a shared protocol proves insufficient, but they must remain behind the same generic adapter contract. - -### Event Flow - -The adapter should sit ahead of the current `event_manager`, not replace it. - -Proposed flow: - -1. backend receives shared compositor-facing state changes -2. adapter updates its desktop-context snapshot -3. adapter emits normalized state deltas and control hints -4. `event_manager` updates queueing, prioritization, and obsolescence decisions -5. AT-SPI object events continue to provide object-level truth within the selected desktop context - -This allows Cthulhu to reduce irrelevant work before scripts interpret it, while keeping existing AT-SPI semantics intact. - -### `event_manager` Integration - -`event_manager` should gain a separate notion of desktop-context state in addition to its existing AT-SPI queue. - -New responsibilities: - -- track whether churn suppression is active -- track the currently prioritized desktop context -- reject queued AT-SPI work that became stale because the compositor already moved to a new context -- prefer script activation and focus recovery work that matches the current desktop context - -The existing queue does not need to be replaced, but it does need one new concept: context obsolescence. - -### Context Obsolescence - -Add a new pruning rule: an event can be obsolete not only because a newer event of the same type exists, but because the desktop context that made the event relevant no longer exists. - -Examples: - -- a large `children-changed` burst from a window on a workspace that is no longer active -- queued `showing` or `name-change` events from a window that just lost compositor priority -- stale background application updates that were queued before a workspace switch finished - -This is the primary performance win of the new interface. It lets Cthulhu discard irrelevant work based on context freshness, not only on event-type heuristics. - -### Churn Suppression Mode - -When the adapter emits `pause_atspi_churn`, `event_manager` should enter a guarded suppression mode. - -This is not a full stop. It is a mode where: - -- high-value focus and activation events are always preserved -- low-value background churn is collapsed, deprioritized, or dropped -- stale work from the prior desktop context is pruned aggressively - -Events that should still be preserved during suppression: - -- `window:*` -- `object:state-changed:focused` with `detail1=true` -- `object:state-changed:active` on frames and windows -- `object:text-selection-changed` -- `object:selection-changed` for the prioritized context -- user-trigger-correlated events associated with the last input event - -Events that should usually be suppressed, collapsed, or deprioritized: - -- `object:children-changed:*` -- `object:state-changed:showing` -- `object:state-changed:sensitive` -- background `object:property-change:accessible-name` -- bulk `object:text-changed:*` -- repeated `object:text-caret-moved` from non-priority contexts - -### Transition Handling - -When the adapter indicates a desktop transition: - -- `desktop_transition_started` - - adapter marks `transition_active=True` - - adapter emits `pause_atspi_churn` -- `desktop_focus_context_changed` - - `event_manager` updates the preferred app/window context before AT-SPI focus settles - - focus-related events for the new context get priority -- `desktop_transition_finished` - - adapter emits `resume_atspi_churn` - - adapter emits `flush_stale_atspi_events` - - `event_manager` drops queued events that belong to the old context and resumes normal flow - -This allows Cthulhu to be more decisive during workspace switches, app switches, and transient window transitions without needing compositor-authoritative object trees. - -### Script Activation - -`event_manager` should use the adapter's prioritized desktop context as an additional input when deciding whether to activate a script. - -It should not activate a script purely because the compositor hinted at it, but it should: - -- prioritize AT-SPI events from the compositor-indicated context -- deprioritize or skip activation from obviously stale background contexts -- improve focus recovery when AT-SPI active-window truth is noisy or delayed - -This should reduce cases where script activation thrashes between background and foreground apps during Wayland transitions. - -### Debugging And Observability - -Add explicit logs around the new boundary: - -- backend chosen and why -- normalized adapter signal emitted -- transition suppression entered and left -- events dropped due to context obsolescence -- events preserved during suppression and why - -These logs should make it possible to explain every major pruning decision in the same way current flood and ignore logic can be debugged. - -## Testing - -### Automated - -Add targeted tests for: - -- backend capability detection and fallback order -- normalization of backend signals into adapter events -- transition start and finish behavior -- churn suppression activation and release -- context-obsolescence pruning of queued AT-SPI events -- preservation of focus and selection events during suppression -- script activation preferring compositor-indicated context when AT-SPI is noisy -- fail-safe fallback to current behavior when the adapter is uncertain - -These tests should be written with mocks and fake backend signals. No real compositor should be required for unit coverage. - -### Manual - -Manual validation should focus on: - -- workspace switches on Mutter, KWin, and niri -- fast application switching -- opening and dismissing transient dialogs and menus -- noisy web or Steam-like scenarios where background AT-SPI churn is high -- confirmation that speech follows real focused objects once AT-SPI settles -- confirmation that no important notifications or menu interactions are lost during suppression - -## Risks - -- Shared Wayland protocols may provide enough workspace truth but not enough top-level detail on every compositor. -- Compositor state may lead AT-SPI focus briefly, which could cause over-eager prioritization if the suppression policy is too aggressive. -- Some legitimate background AT-SPI events may look like churn if the rules are too broad. -- Adding a new boundary introduces state-synchronization bugs if adapter and event queue state diverge. - -## Risk Management - -- keep suppression guarded rather than absolute -- keep AT-SPI authoritative for object semantics -- make context obsolescence explicit and debuggable -- fail back to current behavior whenever backend certainty is too low -- avoid compositor-specific backends in phase one unless a shared protocol is clearly insufficient - -## Recommendation - -Implement a small generic `CompositorStateAdapter` and teach `event_manager` to consume its normalized desktop-state signals and churn-control hints. - -Do not make `niri` IPC part of the core contract. -Do not attempt a compositor-authoritative accessibility architecture in this pass. -Do not broaden the first implementation beyond shared protocol detection, AT-SPI fallback, context-based pruning, and guarded churn suppression. diff --git a/docs/superpowers/specs/2026-04-10-tolk-nvda-presence-design.md b/docs/superpowers/specs/2026-04-10-tolk-nvda-presence-design.md deleted file mode 100644 index 78da441..0000000 --- a/docs/superpowers/specs/2026-04-10-tolk-nvda-presence-design.md +++ /dev/null @@ -1,198 +0,0 @@ -# Tolk NVDA Presence Compatibility Design - -> Superseded by `docs/wine-accessibility.md`, which uses the original NVDA Controller clients and -> a native RPC server instead of replacement controller DLLs. - -## Goal - -Allow applications running under Wine or Proton to use the official upstream `Tolk.dll` unchanged while routing Tolk speech through the existing Linux NVDA-to-Cthulhu path. - -The compatibility layer must satisfy only the checks that Tolk performs when selecting its NVDA driver. It must not require replacing `Tolk.dll`, patching Tolk, or using a Tolk-specific DLL override. - -## Confirmed Constraints - -- The shipped `Tolk.dll` must remain the official upstream binary. -- The existing `wine2speechd` package already provides replacement `nvdaControllerClient32.dll` and `nvdaControllerClient64.dll` implementations for Linux. -- The current blocker is Tolk detection, not the downstream speech transport. -- Scope is limited to making Tolk believe NVDA is present; broader NVDA emulation is out of scope. - -## Current Tolk Behavior - -From `tolk/src/ScreenReaderDriverNVDA.cpp`, Tolk considers NVDA active only when both of the following succeed: - -1. `nvdaController_testIfRunning() == 0` -2. `FindWindow(L"wxWindowClassNR", L"NVDA")` returns a window handle - -If either check fails, Tolk will not select the NVDA driver and speech output through Tolk will fail. - -## Recommended Approach - -Extend the existing Wine NVDA compatibility stack with a minimal NVDA presence helper. The solution has two parts: - -1. The existing custom NVDA controller DLLs continue handling `nvdaController_*` API calls and forwarding them into the Linux bridge. -2. A lightweight Windows helper process running inside Wine creates the exact window Tolk expects for NVDA detection. - -This keeps the official `Tolk.dll` untouched and confines the compatibility contract to Tolk's actual checks. - -## Architecture - -### 1. NVDA controller DLLs - -The custom `nvdaControllerClient32.dll` and `nvdaControllerClient64.dll` remain the Wine-visible implementation that applications and Tolk load. - -Required behavior: - -- `nvdaController_speakText` forwards speech to the existing Linux bridge. -- `nvdaController_brailleMessage` continues current behavior. -- `nvdaController_cancelSpeech` continues current behavior. -- `nvdaController_testIfRunning` returns success only when the Linux bridge is reachable and the compatibility environment is operational. - -`nvdaController_testIfRunning` must not return success solely because the DLL loaded. It is the main guard against false positive Tolk detection. - -### 2. NVDA presence helper - -A small Windows executable is added to the Wine-side compatibility package. Its only job is to create and maintain a top-level window with: - -- class name: `wxWindowClassNR` -- window title: `NVDA` - -Required behavior: - -- starts quickly and remains idle -- single-instance per Wine prefix or session -- exits cleanly without user interaction -- does not present visible UI unless Wine forces a window surface -- can be launched independently or on demand by the controller DLL - -### 3. Startup coordination - -The presence helper must be running before Tolk calls `FindWindow`, or Tolk detection will fail. - -Acceptable coordination strategies: - -- preferred: launch the helper as part of the existing Wine accessibility startup path -- acceptable: lazily launch the helper the first time the custom NVDA DLL is loaded, then wait briefly for the window to appear - -The preferred strategy is external startup rather than in-DLL process creation because it separates concerns and avoids loader-time side effects. - -## Detection Contract - -Tolk compatibility is considered successful only when all of the following are true: - -- official `Tolk.dll` loads normally -- Tolk loads the custom NVDA controller DLL -- `nvdaController_testIfRunning()` returns `0` -- `FindWindow(L"wxWindowClassNR", L"NVDA")` succeeds -- `Tolk_DetectScreenReader()` returns `NVDA` -- `Tolk_Output()` delivers speech through the existing Linux bridge - -If the Linux bridge is unavailable, the compatibility layer must fail closed: - -- `nvdaController_testIfRunning()` returns failure -- Tolk does not report NVDA as active - -The dummy NVDA window alone must never make Tolk think speech is available. - -## Packaging - -The compatibility feature belongs with the Wine NVDA compatibility stack, not in Tolk itself. - -Expected package contents: - -- `nvdaControllerClient32.dll` -- `nvdaControllerClient64.dll` -- `nvda-presence-helper.exe` or similarly named helper -- startup integration so the helper is available in Wine and Proton environments where Tolk-based games run - -No `Tolk.dll` replacement or override is added. - -## Error Handling - -### Bridge unavailable - -- `nvdaController_testIfRunning` returns failure -- speech-related entry points return the existing failure behavior -- Tolk should not detect NVDA - -### Helper missing or failed to start - -- `FindWindow` fails -- Tolk should not detect NVDA -- logging should identify missing helper startup distinctly from bridge connectivity failures - -### Duplicate helper instances - -- duplicates must resolve harmlessly, preferably by allowing one owner and exiting the rest - -## Logging - -Add targeted logging in the compatibility layer only. Logging should make these states distinguishable: - -- controller DLL loaded -- bridge connectivity check succeeded or failed -- presence helper started -- presence window created -- Tolk compatibility ready - -No Tolk-side logging changes are needed because Tolk is not being modified. - -## Testing - -### Functional test - -Create or reuse a small Wine test application that: - -1. calls `Tolk_Load()` -2. calls `Tolk_DetectScreenReader()` -3. calls `Tolk_Output(L\"test\", false)` - -Expected result with bridge and helper active: - -- `Tolk_DetectScreenReader()` returns `NVDA` -- speech reaches Cthulhu through the existing NVDA path - -### Negative tests - -1. Bridge down, helper up: - `Tolk_DetectScreenReader()` must not return `NVDA` -2. Bridge up, helper down: - `Tolk_DetectScreenReader()` must not return `NVDA` -3. Both down: - `Tolk_DetectScreenReader()` must not return `NVDA` - -### Regression check - -Verify that existing non-Tolk NVDA speech consumers continue using the current `wine2speechd` path without requiring Tolk-specific configuration. - -## Out of Scope - -- adding a plugin mechanism to Tolk -- maintaining a Tolk fork -- broader NVDA desktop emulation beyond what Tolk checks -- compatibility with applications that perform additional NVDA-specific probing outside the current `wine2speechd` contract -- anti-cheat or anti-tamper guarantees beyond avoiding Tolk replacement - -## Risks - -### Wine window behavior - -The helper must create a window that `FindWindow` can discover reliably under Wine and Proton. If Wine normalizes or alters class registration behavior, the helper may need adjustment. - -### Timing - -If a game calls Tolk very early, helper startup races could cause intermittent detection failure. This is why pre-starting the helper is preferred. - -### Split responsibility - -The controller DLL and helper must agree on readiness. If they drift apart, Tolk may see the window but still fail to speak. The fail-closed `testIfRunning` check is the protection against this. - -## Recommendation - -Implement the feature in the existing Wine NVDA compatibility stack, not in Tolk and not in Cthulhu core. - -The smallest correct implementation is: - -1. fix or confirm `nvdaController_testIfRunning()` behavior in the custom DLL -2. add a minimal Wine helper that exposes the NVDA window Tolk checks for -3. wire startup so the helper is available before Tolk detection occurs -4. verify with a small Tolk test program under Wine diff --git a/docs/testing/atspi-lifecycle.md b/docs/testing/atspi-lifecycle.md new file mode 100644 index 0000000..2ddc4c2 --- /dev/null +++ b/docs/testing/atspi-lifecycle.md @@ -0,0 +1,61 @@ +# AT-SPI lifecycle and notebook flat review + +Adapter shutdown removes event subscriptions, the foreground timer and pending +capture sources on the GLib owner thread before releasing callback data and its +Go handle. Incoming owned event copies are freed after the Go callback returns. +Only one adapter may own the process-global AT-SPI loop at a time. +Sequential adapters reuse the library connection: upstream documents +[`atspi_exit()`](https://gnome.pages.gitlab.gnome.org/at-spi2-core/libatspi/func.exit.html) +as a process-exit operation. Process termination releases that connection. + +GTK notebook focus is resolved to the selected tab. This lets ordinary duplicate +focus suppression handle the notebook/tab focus replay after an X11 reader-key +grab, without suppressing real tab changes or returning from a page control. + +Run the lifecycle regressions on a disposable display and accessibility bus: + +```sh +python3 tests/native_test_session.py env CTHULHU_NATIVE_LIFECYCLE=1 go test -race ./internal/atspi -run '^TestNative(SequentialAdapterLifecycle|AdapterPendingCaptureShutdown|CanceledAdapterStart|AdapterStopRetry)$' -count=1 -v +``` + +These cover a live GTK provider across adapter replacement and restart, concurrent +adapter rejection, canceled startup, a canceled capture left pending at shutdown, +and a Stop retry after its caller times out. The original sequential test crashed +with `runtime/cgo: misuse of an invalid Handle` before the fix. + +AddressSanitizer also runs these cases with `-asan` in place of `-race`. +The sequential GTK case previously reported 360 bytes in eight allocations +after three repeated fixture runs. Focused-descendant lookup freed the Collection +result array without releasing its owned accessible references. It now releases +every result while preserving a separate reference for the returned target. +The array does not have an element cleanup function in +[libatspi's Collection implementation](https://github.com/GNOME/at-spi2-core/blob/2.62.1/atspi/atspi-collection.c#L84-L102). +The earlier incoming-event-copy leaks were fixed in the callback wrapper. + +To check the original reproduction, use the lifecycle command above with +`-asan`, `-run '^TestNativeSequentialAdapterLifecycle$'` and `-count=3`; +keep leak detection enabled. A passing Go test followed by a LeakSanitizer +failure is a failed check. This focused check does not establish leak freedom +for the whole reader or its native dependencies. + +Build a separate binary and run the full reader/preferences regression: + +```sh +go build -o /tmp/cthulhu-lifecycle-review ./cmd/cthulhu +CTHULHU_BINARY=/tmp/cthulhu-lifecycle-review CTHULHU_PREFS_FLAT_REVIEW_ONLY=1 /usr/bin/python3 tests/native_preferences.py +``` + +This uses private Xvfb, D-Bus and recorded SSIP speech. It checks line, word and +character review on the General tab, absence of following tab announcements, +real tab changes, Tab into the page and Shift+Tab back to the tab strip. Evidence +is retained in the printed temporary directory. It does not replace listening +or physical keyboard/Braille checks. + +For live acceptance with a user-started updated build, focus the General tab +header and review several lines, words and characters in both directions. Each +review response should finish without “page tab list / General / page tab”. +Use Left/Right to change tabs, Tab into a page and Shift+Tab back: those genuine +focus changes should still speak. Check another application's notebook and a +browser tab strip, plus ordinary menus and single/multiple table selections, +because they share focus-target selection. Confirm Braille review stays at the +review position until genuine navigation changes focus. diff --git a/docs/testing/background-events.md b/docs/testing/background-events.md new file mode 100644 index 0000000..bbc80b6 --- /dev/null +++ b/docs/testing/background-events.md @@ -0,0 +1,77 @@ +# Background accessibility events + +On Xorg, Cthulhu rejects known background control updates before resolving +selected descendants or capturing their text, values, attributes and geometry. +The native adapter owns this decision on the GLib thread. It uses the existing +foreground window and epoch; there is no additional window ownership cache. + +Events from another provider can be rejected using copied bus identities and +libatspi's cached role and application name, without querying that provider. +Events from another window on the same provider undergo the existing window +correlation before content capture. Lifecycle invalidation still runs, but a +background provider no longer clears another provider's cached document lines. + +Window creation, activation, deactivation, destruction and defunct events keep +their existing handling. Native alerts, notification daemons and supported +Steam toasts retain their notification paths. Menu popups retain existing +foreground checks. Same-provider autocomplete relations and tooltip candidates +continue through the existing event-loop ownership checks; they do not acquire +focus merely by passing the early filter. + +When notification metadata or a detached document's containing window is +unknown, the adapter retains the existing validation path. The optimization +does not introduce an X11 ownership requirement for native Wayland sessions. + +Orca's `src/orca/event_manager.py` was used as a reference for keeping global +window monitoring and filtering noisy content events before presentation. + +## Automated checks + +Run from the repository root with the normal native build dependencies: + +```sh +go test ./... -count=1 +go test -race ./internal/atspi ./internal/app ./internal/review -count=1 +python3 tests/native_test_session.py env CTHULHU_NATIVE_BACKGROUND_EVENTS=1 CTHULHU_NATIVE_WAYLAND_POLICY=1 go test -race ./internal/atspi -run '^TestNative(BackgroundEventFiltering|WaylandForegroundPolicy)$' -count=1 -v -timeout=40s +python3 tests/native_webscripts.py +CTHULHU_NATIVE_BROWSER_TESTS=browser,tabs,live,tooltips python3 tests/native_browser.py +go build -o /tmp/cthulhu-background-events ./cmd/cthulhu +CTHULHU_BINARY=/tmp/cthulhu-background-events python3 tests/native_ownership.py +``` + +The flood regression uses two real GTK providers, then two windows on one +provider. Each burst changes the table selection 300 times. A private D-Bus +monitor asserts that the rejected updates cause no Selection, Table, Text or +Value interface calls. The explicit alert used as a completion marker is +excluded from this content-query assertion. Returning to the noisy window must +deliver its current table selection. The separate cache regression verifies +that invalidation preserves other providers' document lines. + +All native checks use disposable X servers and private D-Bus/runtime sockets. +They do not replace the active desktop reader. Browser checks cover address +suggestions, page controls, tabs, live regions and tooltips. Ownership checks +cover GTK/Qt menus, a GTK menu popup, dialogs, same-process windows, empty +workspaces and Brave window recovery. Notification checks preserve Steam toast +capture while rejecting ordinary background Chromium text changes. + +## Live acceptance + +Private fixtures do not establish audible speech, physical Braille or actual +FastSMRW update latency. After reviewing the diff, preserve the current debug +log and rebuild/start the candidate through the normal local launcher when +ready to replace the reader. + +1. Read headings and lines in Brave while FastSMRW receives new items. Compare + responsiveness with quiet periods. Background selection changes should not + delay reading or take speech/focus ownership. +2. Switch to FastSMRW and move through results. Confirm the current selection + is spoken; open its Open Links popup, move between links, and close it. +3. Switch between two windows from the same application. Open and close a + dialog and a menu; confirm speech follows the active control. +4. In Brave, type into the address bar and move through suggestions. Return to + the page, switch tabs, and verify normal editing and reading still work. +5. Check supported background notifications. If using Braille, confirm it + follows the foreground control and still displays supported notifications. + +Preserve a fresh log if lag or a missing announcement remains, with the time +and the key or update that triggered it. Debug logs can contain private text. diff --git a/docs/testing/benchmarks.md b/docs/testing/benchmarks.md new file mode 100644 index 0000000..ccc53a3 --- /dev/null +++ b/docs/testing/benchmarks.md @@ -0,0 +1,103 @@ +# Performance benchmarks + +Benchmarks measure time and Go allocations for repeatable operations. Run the +relevant cases before and after performance changes, alongside correctness tests. +Normal `go test` runs do not execute benchmarks; add `-bench` explicitly. + +## Browser document benchmarks + +Run from the repository root: + +```sh +go test ./internal/review -run '^$' -bench '^BenchmarkDocument(Snapshot|HeadingNavigation|LineAssembly)$' -benchmem -count=10 > /tmp/cthulhu-bench-before.txt +``` + +Repeat after the change with the same command and +`/tmp/cthulhu-bench-after.txt` as the output file. Choose distinct filenames when +retaining earlier measurements. To check that the benchmarks execute quickly, +use `-benchtime=1x -count=1`; that is a smoke check, not a useful timing baseline. + +The initial cases use 100, 1,000 and 10,000 content objects, plus one section per +twenty objects and a document root. Fixtures contain headings, links and Unicode +text, with two objects on each visual row. Each benchmark iteration performs: + +- `BenchmarkDocumentSnapshot`: one document snapshot from an existing tree, + including traversal and derived metadata. +- `BenchmarkDocumentHeadingNavigation`: a forward/backward heading round trip + on an existing tree. The `adjacent` case visits two headings near the middle; + `wrap` moves between the last and first headings. Each iteration returns to + the same position, keeping the workload independent of the loop count. + Time and allocations are per round trip (two moves), including snapshot + construction and navigation bookkeeping. +- `BenchmarkDocumentLineAssembly`: one line lookup in the middle of a document, + combining the two text objects on that row. This includes snapshot construction. +- `BenchmarkDocumentCaretNavigation`: a character forward/backward round trip + within the same text object. Reusable caret ranges are warmed before timing. +- `BenchmarkDocumentWorkerHeadingNavigation`: a heading forward/backward round + trip through the review worker, including focus synchronization, diagnostics + and placement dispatch, with an in-memory provider. It performs no browser IPC. + +Include the additional cases with +`-bench '^BenchmarkDocument(Snapshot|HeadingNavigation|LineAssembly|CaretNavigation|WorkerHeadingNavigation)$'`. +Navigation shares an immutable indexed view; `BenchmarkDocumentSnapshot` +continues to measure the independently owned node copy returned by `Document`. +The first view construction is included in snapshot and line measurements and +amortized over subsequent iterations. A short run can therefore overstate the +steady allocation rate. See [document navigation validation](browser-navigation-performance.md) +for cache ownership, invalidation and real-browser checks. + +Fixture construction and initial focus synchronization are outside the timed +loops. The benchmarks fail on errors, missing work or invalid result shapes. +They use owned tree data and do not start a browser, access the desktop reader, +query native AT-SPI objects, or produce speech or Braille output. They do not +measure browser capture, native caret placement, input queues or audible latency. +Expand the suite when a reproduced bottleneck needs a different workload, such +as nested documents, tables, long text or event bursts. + +Existing benchmarks also cover speech text preparation and Tentacle commands: + +```sh +go test ./internal/speech -run '^$' -bench '^BenchmarkNormalizeSpeakText$' -benchmem -count=10 +go test ./internal/tentacle -run '^$' -bench '^BenchmarkCommandRoundTrip$' -benchmem -count=10 +``` + +The Tentacle benchmark starts disposable test peers and measures one completed +command at a time across 1, 8 or 16 processes; it does not measure concurrent +command saturation. + +## Comparing changes + +Record the revision, uncommitted changes, Go version, machine and benchmark +command with results. Compare repeated measurements on the same machine and +toolchain, under similar load and power settings. Do not run performance +comparisons with the race detector or coverage instrumentation enabled. Use +`benchstat` from `golang.org/x/perf/cmd/benchstat`, if installed, to compare files: + +```sh +benchstat /tmp/cthulhu-bench-before.txt /tmp/cthulhu-bench-after.txt +``` + +`ns/op` is elapsed time per operation, `B/op` is Go bytes allocated per operation, +and `allocs/op` counts Go allocations. These are not total process memory or +native C allocation measurements. A benchmark's `PASS` means it executed without +failure; it does not mean its performance is acceptable or improved. + +Investigate substantial, repeatable regressions before changing code. Profile +the affected operation when the cause is unclear. Preserve the full workload +and result checks when optimizing; do not improve scores by dropping required +content or bypassing validation. Initially keep timings informational rather +than adding timing gates to tests or push hooks. These commands can be run by +automation later; no scheduled job or CI timing gate is configured here. + +For this benchmark-only change, run the existing affected correctness tests: + +```sh +go test ./internal/review ./internal/atspi -count=1 +``` + +Future browser performance fixes also need the relevant native browser harness +and human checks: navigate headings forward and backward through wrapping, read +lines with arrows, move through links and editable fields, return from browser +chrome, and verify fresh input interrupts old output. Check speech and physical +Braille where available. Automated timing does not replace those checks or the +human review required by `CONTRIBUTING.md`. diff --git a/docs/testing/browser-audit-fixes.md b/docs/testing/browser-audit-fixes.md new file mode 100644 index 0000000..a697a74 --- /dev/null +++ b/docs/testing/browser-audit-fixes.md @@ -0,0 +1,140 @@ +# Browser audit fixes + +This work addresses the browser review of `bf4b9d7` against local Orca. The first +implementation batch fixes the four reproduced defects and two navigation costs. +It also adds busy live-region deferral. It does not establish complete Orca parity. + +## Implemented behavior + +- Crossing objects validates dirty hypertext ancestors, because parent-owned text + can change embedded offsets without changing accessible child identities. + A failed move preserves the position; the refreshed retry reads the insertion. + A local character move within an unchanged child still avoids recapture. +- Atomic updates read the enclosing atomic region for both text changes and child + additions. The source's effective `container-atomic` metadata gates this path. + Chromium exposes `atomic=false` on ordinary descendants, so those default values + do not terminate the ancestor walk. +- Table movement crosses missing cells, including neighbors in lower rows of a + spanning cell. It uses captured cells rather than iterating huge sparse row or + column dimensions. Real blank cells remain stops. Table validation and lookup + operate on the table subtree and its ancestors, preserving refreshes for changed + coordinates, headers and cell data while allowing unrelated page updates. +- Word movement skips whitespace using blocks of at most 128 native Unicode + characters. Only observed whitespace triggers this path, so ordinary word and + character movement do not gain an extra block request. Native word boundaries, + spelling metadata and embedded-object limits retain their existing handling. +- The cursor indexes object-to-range positions once per immutable document view. + A hypertext object can have multiple ranges, and lookup preserves their actual + traversal order. Retired views rebuild both the ranges and their index. +- Busy live regions defer updates until their busy flag clears. The GLib owner + keeps at most 32 region/document identities, without retained native references + or intermediate text. Completion rereads the active region and enters the live + insertion path, without acquiring focus or producing document-loading speech. + Secure input, tab selection, object destruction, document lifecycle and shutdown + retire the relevant deferred state. Live attributes are fetched together once + per candidate event, after foreground filtering. + +The browser must expose accurate live attributes. A diagnostic Chromium fixture +which set `aria-busy=true` and replaced descendant text in the same JavaScript +turn reported `container-busy=false` on the initial descendant event. Cthulhu +cannot reliably defer an update which the provider reports as not busy. The +retained regression establishes busy state before the initial accessibility +capture and proves that clearing the flag alone releases the deferred content. +Nested explicit atomic=false boundaries likewise depend on correct effective +`container-atomic` metadata from the provider. + +## Automated evidence + +The AT-SPI, review and app packages passed with the race detector. The full race +run failed in `internal/sound` at +`TestNewPresentationInterruptsOldCueAndDiscardsPendingCues` with “stale link cues +remained queued.” Ten isolated repetitions also reproduced that failure in an +untouched snapshot of `bf4b9d7`; the sound files were not changed. This remains an +existing gate, so the full suite is not described as passing. + +Thirteen selected Chromium fixtures passed in a private X11/D-Bus session: +`generatedlinks,replacement,fragments,namedlinks,linkedheadings,tables,selection,modes,document,editing,tabs,live,live-atomic`. +The final `live-atomic` run also verifies that busy completion requires no new text +insertion. It covers atomic text updates, atomic child additions, non-atomic +updates, suppression while busy, and release after busy becomes false. + +Firefox baseline reading passed. Its tab regression timed out on the second +“New Tab” announcement in both the modified checkout and an untouched `bf4b9d7` +snapshot. The recorded events include a selected-state event for the previous +unselected tab. This is an unresolved existing/provider case, not a verified +regression introduced by these changes. + +The affected `go vet` checks, normal reader build, BrlAPI helper build, Python +syntax check, parity-ledger validation and whitespace check passed. No installed +reader was replaced. The native fixtures record protocol/snapshot behavior; +they do not prove audible output or physical keyboard/Braille acceptance. + +A counting reader crossed 1,000 whitespace characters with three word commands +using 39 reads, including 16 character-block reads. The old implementation used +1,003 reads for a single forward word command. This is an API-call count, not a +measurement of audible latency. + +Three 100 ms synthetic benchmark repetitions still show character round trips +near 12 microseconds at 10,000 content nodes. Allocation traffic remains about +16 KB per character round trip and 52 KB per worker heading round trip. These +runs overlapped other checks and are informational, not a controlled timing +comparison. They exclude native IPC, initial capture, speech and physical input. + +Run the relevant checks: + +```sh +python3 tests/native_test_session.py env GOCACHE=/tmp/cthulhu-cache go test -race ./internal/atspi ./internal/review ./internal/app -count=1 +CTHULHU_NATIVE_BROWSER_TESTS=live-atomic,generatedlinks,replacement,fragments,namedlinks,linkedheadings,tables,selection,modes,document,editing,tabs,live python3 tests/native_browser.py +python3 tests/native_firefox.py +go vet ./internal/atspi ./internal/review ./internal/app +go run ./cmd/parityledger validate testdata/parity-ledger.csv +``` + +## Human acceptance before submission + +Review the generated diff under the project's AI-assisted contribution policy. +With an explicitly rebuilt reader, test these workflows in Chromium and Firefox: + +1. Read forward and backward through links and changing text between them. Read + All must include inserted text once and continue through generated links. +2. Check atomic status updates retain their surrounding label, non-atomic updates + announce the change, and busy updates wait for the completed region. +3. Navigate ragged and merged-cell tables in all directions. Verify headers, + blank cells, logical row/column retention, nested tables and boundary messages. + Repeat with an unrelated page ticker and then a changed cell/header. +4. Move by word through long indentation, tabs, newlines and Unicode whitespace. + Check reverse movement, emoji, named links, and character-by-character spacing. +5. Type/select in an editor; return from the address bar and another tab; check + Steam browsing/search; verify stale targets never activate replacement controls. + Compare speech and physical Braille where available. + +Do not submit or replace the active reader automatically. Preserve logs if a +workflow fails and distinguish provider metadata from reader-owned state. + +## Remaining review work + +The user authorized addressing the whole review, in priority order. On October +24, the maintainer prioritized stabilizing the current release before adding +new functionality. MathCAT was left to implementation judgment and is deferred +with the other feature additions below. Release work should concentrate on the +existing fixes, the recorded test failures, and live acceptance. These items +remain open and must not be reported as implemented: + +- Automatic language switching, including language runs within a line, native + focus, structural navigation, character reading and Read All. The current + speech queue and client selection do not carry per-content language metadata. +- Structured math speech, Braille and exploration. MathCAT's maintained C + interface provides a shared engine, but adds a Rust-built library and its rule + data to packaging. No MathCAT dependency has been added in this batch. +- Constrained label inference for controls without an accessible name or explicit + label relationship. Keep explicit labels authoritative and reject ambiguous + neighboring text. This is a deliberate presentation-policy addition. +- Demand-driven capture for pages exceeding the 30,000-object safety bound. + The bound and whole-document initial capture remain unchanged. A partial tree + must represent unloaded branches explicitly so it cannot silently report false + end-of-document or incomplete element lists as complete results. + +MathCAT integration should keep Go as the policy owner, use the upstream C ABI, +serialize engine state on a dedicated worker, and preserve browser responsiveness +when the engine or rules are unavailable. Revisit dependency and packaging choices +after the current release is stable; no MathCAT dependency is being added now. diff --git a/docs/testing/browser-editor.md b/docs/testing/browser-editor.md new file mode 100644 index 0000000..9a41845 --- /dev/null +++ b/docs/testing/browser-editor.md @@ -0,0 +1,49 @@ +# Browser editor typing + +Chromium contenteditable textboxes can keep native focus on an `entry` while +editable child paragraphs emit insertion, deletion, caret and selection events. +The native adapter records the nearest focusable writable editor as +`EditableRoot`, just as it records an editable document for document editors. +The event loop accepts that relationship only while that exact editor owns focus. +Lookup stops at document, window, password and read-only boundaries. + +The reported ChatGPT failure was captured in the debug log on 2026-10-23: +paragraph text changes were rejected as outside the focused editor because +`editable_root` was empty. Following caret events then spoke the growing line. +Recognizing the parent editor restores configured typing echo and the existing +suppression of caret speech following a text change. This uses accessibility +identity and states; it does not depend on a website, label or DOM class. + +## Automated checks + +```sh +env CTHULHU_NATIVE_BROWSER_TESTS=editor python3 tests/native_browser.py +env CTHULHU_NATIVE_BROWSER_TESTS=editing,selection,live python3 tests/native_browser.py +python3 tests/native_test_session.py go test ./internal/app ./internal/atspi ./internal/presentation -count=1 +``` + +The editor proof uses real Chromium paragraph events and the reader's event +pipeline on a private Xvfb display and D-Bus session. It checks quiet typing with +echo disabled, parent identity, character and line reading, deletion feedback, +and movement into another editor. Unit coverage checks disabled, character, +word and sentence echo, delayed events after focus leaves, existing editable +document handling, and Braille ownership. + +## Live acceptance + +After rebuilding and restarting the logging reader through its usual launcher: + +1. In ChatGPT, compose several words, pause, and continue typing. With typing + echo disabled, each key must not reread the draft. With character or word + echo enabled, hear only the configured echo. +2. Use Left/Right, Control+Left/Right and Up/Down in a multiline draft. Confirm + character, word and line reading, Backspace/Delete feedback, and Shift-arrow + selection. Check Braille text and cursor placement if available. +3. Tab and Shift+Tab out of and back into the composer. Confirm focus labels + and that typing in another field cannot announce the old draft. +4. Check browser address-bar typing and suggestions, ordinary form fields, + password fields, and live status/response announcements. Check an editable + document body as well as its separate header fields when available. + +Private test results do not establish audible speech or physical Braille +acceptance on the original ChatGPT page. That acceptance remains pending. diff --git a/docs/testing/browser-lists.md b/docs/testing/browser-lists.md new file mode 100644 index 0000000..b21fdc9 --- /dev/null +++ b/docs/testing/browser-lists.md @@ -0,0 +1,87 @@ +# Browser element lists + +In browse mode, hold **Alt+Shift** and press the key below. These +shortcuts work in both desktop and laptop layouts and can be changed in +Preferences under browser shortcuts. + +| Key | List | +| --- | --- | +| A | Clickables | +| B | Buttons | +| C | Combo boxes | +| E | Text entries | +| F | Form fields | +| G | Images | +| H | Headings | +| I | List items | +| K | Links | +| L | Lists | +| M | Landmarks | +| O | Large objects | +| P | Paragraphs | +| Q | Block quotes | +| R | Radio buttons | +| T | Tables | +| U | Unvisited links | +| V | Visited links | +| X | Check boxes | +| 1–6 | Headings at that level | + +Annotation, internal frame and math lists have no default shortcut, matching +Orca. Assign them a browser shortcut in Preferences. Annotation lists include +content insertions, content deletions and marks. Separators and live regions +have no list command in Orca. + +The list opens with the current item selected when it matches the filter. +Use arrows, Home, End, Page Up and Page Down to select an item, or type the +beginning of its name. Enter closes the list and moves the reading position +to the selected item. It does not activate a link or press a button. Escape +closes the list without moving. An empty list reports zero items and releases +the keyboard. Speech presents rows and Braille shows the selection and count. +The browser retains native keyboard focus while the list is open. + +Lists use the same semantic filters as structural navigation, exclude hidden +content, and stay within the current document, including embedded content. +The native document capture limit also bounds lists. Core navigation lists can +contain more than 256 items; external Tentacle forms retain their existing +256-item limit. List selections retain exact accessible references and page +ownership, so removed targets, replaced documents and changed focus cannot +select a different item. A changed page can require reopening the list. + +Automated checks: + +```sh +go test ./internal/input ./internal/review ./internal/interaction ./internal/app -count=1 +CTHULHU_NATIVE_BROWSER_TESTS=lists,keys,document,modes,editing python3 tests/native_browser.py +python3 tests/native_internal_ui.py +``` + +The private browser list fixture checks 302 links, hidden-link exclusion, +current-row restoration, selection, Escape, clickables, a heading level and an +empty image list with actual X11 grabs and AT-SPI data. These checks inspect +speech requests and synthetic input. They do not establish audible speech or +physical keyboard/Braille behavior. + +Before submission, review the diff and test the rebuilt reader on a real page: + +1. Open links with Alt+Shift+K. Move with arrows, type a name, select + with Enter, and confirm subsequent browse arrows start at that item. Press + Enter again to verify that ordinary link activation still works. +2. Open clickables with Alt+Shift+A and headings with H and 1–6. Check + spoken labels and Braille rows, then cancel and confirm the old reading + position remains. Check lists with several hundred entries. +3. Open a list, change tabs or windows, and confirm capture is dismissed and + typing works normally. Reload or remove a selected page item and confirm + the old list cannot move to a different target. +4. Check ordinary H/Shift+H and K/Shift+K, browse arrows, Tab/Shift+Tab, + editable-field typing, browser chrome, and the existing Cthulhu+Shift+A + actions menu. Verify the new list keys pass through outside browse mode. + +Human review and these live checks remain necessary under the project's +AI-assisted contribution policy. + +The full Go race suite, private browser lists, document navigation, editing, +keyboard transitions and existing internal UI checks passed. The browser mode +check missed a dynamic-text announcement during the combined run, then passed +in isolation. The cause of that initial failure is unverified; its diagnostic +log was retained at `/tmp/cthulhu-browser-modes-2991369198.log`. diff --git a/docs/testing/browser-navigation-performance.md b/docs/testing/browser-navigation-performance.md new file mode 100644 index 0000000..38520fb --- /dev/null +++ b/docs/testing/browser-navigation-performance.md @@ -0,0 +1,114 @@ +# Document navigation performance and validation + +Browse navigation reuses an immutable document view and an object-to-index +lookup owned by `AccessibleTree`. `DocumentCursor` reuses the view's caret ranges +and visual-line ownership map. Focus synchronization, heading/link searches, +position lookup, linked-heading lookup and replacement-parent bookkeeping use +that index instead of rebuilding maps or scanning the entire document per key. + +`Replace`, object removal and destructive child invalidation retire the cached +view. Pending semantic, text, geometry and child-order changes keep the view's +immutable data but mark the live tree entries dirty. Before navigation reads or +selects content, it validates the objects it traverses and their relevant +ancestors. Dirty skipped candidates are validated too, so navigation cannot +silently omit newly readable content. A local move within one live text object +can proceed through a parent's unrelated insertion; crossing objects requires +fresh child order. Table-row summaries also validate their contributing sibling +cells using the same bounded dependency list used to derive the row text. + +Failed validation preserves the reading position and uses the existing bounded +recapture/retry path. Successful native text remains valid for the requested +announcement if the provider removes its object immediately afterwards; retrying +that completed move would skip text. Activation, element lists, native selection +resolution and captured-line assembly retain complete-document validation. +`Document` still returns an independently owned node slice; callers of +`DocumentView` and `NavigationDocument` must treat the shared data as read-only. +Tree access and cache publication use the tree mutex, and native object lifetime +and GLib ownership stay with the adapter. + +On 2026-10-24, three sequential 200 ms runs on an AMD Ryzen 9 PRO 5945 with +Go 1.27.3 compared the unchanged `133953e` source through a Go overlay with +these changes. The same benchmark source ran against both versions. Median +results for the 10,000-content-object fixture were: + +| Operation | Before | After | Bytes allocated before | Bytes allocated after | +| --- | ---: | ---: | ---: | ---: | +| Worker heading forward/back pair | 87.476 ms | 0.053 ms | 276,775,952 | 51,650 | +| Character forward/back pair | 53.536 ms | 0.014 ms | 124,261,980 | 16,072 | +| Heading forward/back pair | 43.129 ms | 0.035 ms | 142,691,897 | 18,080 | +| Heading wrapping pair | 44.895 ms | 0.032 ms | 142,687,798 | 18,080 | +| Owned document snapshot | 14.747 ms | 5.421 ms | 54,801,125 | 11,723,115 | +| Captured line assembly | 15.297 ms | 3.095 ms | 54,810,445 | 182,019 | + +These measure owned Go data and fake-provider calls, excluding native browser +IPC, initial capture, speech delivery and audible latency. Allocation figures +are traffic per operation, not retained process memory. Snapshot/line results +include an amortized first index build; navigation setup precedes timing. +Raw outputs are `/tmp/cthulhu-web-performance-before.txt` and +`/tmp/cthulhu-web-performance-after.txt`; medians are retained in +`/tmp/cthulhu-web-performance-medians.json`. Performance remains informational, +with no timing gate added to tests. + +Run the affected correctness and race checks in a private session: + +```sh +python3 tests/native_test_session.py env GOCACHE=/tmp/cthulhu-cache go test ./internal/atspi ./internal/review ./internal/app -count=1 +python3 tests/native_test_session.py env GOCACHE=/tmp/cthulhu-cache go test -race ./internal/atspi ./internal/review ./internal/app -count=1 +go vet ./internal/atspi ./internal/review ./internal/app +``` + +The tests cover cached-view ownership, concurrent replacement, retired views, +cancellation, unrelated dirty branches, stale traversal and unchanged reading +positions after failures. Existing regressions also cover replacement recovery, +generation-checked activation, table navigation, native selections, passwords, +inline text, named links and browser-chrome round trips. Two existing recapture +tests now distinguish continued reading within a live leaf from crossing dirty +child order, rather than requiring a recapture for every document mutation. + +Run the existing browser fixtures and actual-reader navigation fixture: + +```sh +CTHULHU_NATIVE_BROWSER_TESTS=replaced-feed,generatedlinks,replacement,fragments,tabs,namedlinks,linkedheadings,tables,dynamic,document,editing,selection,modes python3 tests/native_browser.py +go build -o /tmp/cthulhu-browser-performance ./cmd/cthulhu +CTHULHU_BINARY=/tmp/cthulhu-browser-performance python3 tests/native_browser_navigation.py +``` + +The actual-reader fixture checks 76 navigation commands while page text changes, +including forward/reverse headings, line/character/word movement and custom +activation. It records speech protocol requests in a private X11/browser session. +It does not establish audible output or physical keyboard/Braille behavior. +An initial optimized run passed the entire fixture. A final-binary run completed +all 76 navigation commands and both custom activations, then failed its final +pointer-handoff assertion: the click at screen coordinates 0,0 produced no +observed shared AT-SPI pointer press. The focused native pointer test passed. +Keep this separate from the verified navigation sequence; it remains an open +harness/delivery check. The unchanged original binary reproduced the same final +pointer failure after completing its navigation sequence, so this failure +predates the performance changes. Evidence is retained in +`/tmp/cthulhu-browser-navigation-56h2cw3n` (final binary), +`/tmp/cthulhu-browser-navigation-i2jxxobv` (original binary), and +`/tmp/cthulhu-browser-navigation-mduikajr` (initial complete optimized pass). + +The browser `modes` fixture remains an intermittent gate. During this change it +passed in an isolated optimized run, but mixed runs failed once on page return +and once while expecting typed chrome text. The original source passed isolated +and tables/selection/modes comparison runs; these comparisons do not conclusively +attribute the intermittent failures. Preserve their logs and report the open +gate rather than describing the whole browser suite as consistently passing. + +For human acceptance, use the actual reported Reddit view and a long updating +page. Navigate headings in both directions through wrapping, read post/comment +text with arrows and word/character commands, expand/collapse comments, load +more content, type and select in an editor, activate links, and return from the +address bar and another tab. Check that stale/replaced targets never activate a +different control. On a table, change a sibling cell and verify full-row speech +and Braille refresh. Check Steam browse navigation and search/Tab behavior after +an application/workspace round trip. Listen for skipped/repeated text and verify +physical Braille where available. Preserve the current log and obtain approval +before replacing the active reader. + +The first native document capture still enumerates the captured tree, the +30,000-object safety limit still applies, and generic named-clickable filtering +is unchanged. These performance changes do not establish a fix for Reddit's +specific reported content problem. Review the diff and complete the live checks +before submitting under the project's AI-assisted contribution policy. diff --git a/docs/testing/browser-release-review.md b/docs/testing/browser-release-review.md new file mode 100644 index 0000000..286da1b --- /dev/null +++ b/docs/testing/browser-release-review.md @@ -0,0 +1,140 @@ +# Browser release review + +Reviewed `423590e` (Browser updates) and `ebb9ad4` (Better logging for browser) +on the Go `testing` branch, including the surrounding navigation and activation +paths. References were the local Orca web caret-context and removed-child recovery +code and Python Cthulhu's `master:src/cthulhu/scripts/web/script.py` clickable +activation. Reference checkouts were not changed. + +## Findings and changes + +- Native selection clearing could emit a temporary caret at the selection start + before Braille routing finished. A private Chromium mode test reproduced a + routed offset of one being reset to zero, so Right read “e” instead of “x”. + Native echo tracking now recognizes selection-collapse endpoints separately + from the requested caret. A new nonempty selection remains native input. +- Recovering a removed native focus anchor reset an otherwise valid virtual + position. Recovery now rebinds the anchor within the same document generation, + retaining the virtual object and offset. +- The recent single-text-child recovery did not cover replacement of several + children or a containing paragraph. Navigation now retains at most 32 ancestor + references per saved position and can restart inside a surviving noninteractive + container. This fallback transfers no offset and is excluded from activation. + Document changes, hidden content and editable contexts remain boundaries. +- Native caret placement failure was spoken after successful structural reading. + The content now speaks without that misleading failure announcement; diagnostic + errors remain available. Arrow navigation now uses the same bounded stale + placement retry as structural navigation, without advancing twice. +- Name-event echo suppression could bypass both live-region presentation and the + new focused-button coalescer. Live regions and buttons now reach those existing + handlers; button updates still refresh Braille immediately and debounce speech. +- Enter failures announced “Could not activate current item.” All activation + results now remain silent, without interrupting page-generated feedback. +- Snapshot capture recognized only `click`, although activation supported + `click-ancestor`, `press`, `jump`, `open` and `activate`. Capture now recognizes + the same names. Explicitly named custom clickables are whole browse stops; + ordinary clickable text remains readable and activates its clickable ancestor. +- Enter on ordinary text needlessly recaptured the document. A distinct + nonactivatable result avoids that work. Native action names are fetched once + rather than repeatedly for each preferred action spelling, and metadata capture + stops after finding an activation action. +- Action refresh could accept a replaced document generation with reused object + paths. It now rejects that case when the retained tree establishes replacement. + +No additional confirmed defect was found in the build-identity logging changes. +These changes do not establish complete Orca browsing parity or a failure rate on +arbitrary real pages. Browser/provider timeouts and genuinely missing document +context can still produce a location error. Virtual movement cannot guarantee +native Tab/selection placement when a provider refuses to move its caret. + +## Automated checks + +The review uses existing package tests plus focused regressions for silent +activation, removed focus anchors, surviving-container recovery, custom clickable +stops, document-generation rejection, live names, button coalescing and native +placement retries. The private Chromium fixtures cover pointer input, list +positions, tabs, linked headings, dynamic pages, live regions, structural commands, +editing, selection and browse/focus modes. Firefox has baseline and tab checks. + +The expanded real-reader changing-page test uses private i3, Xvfb, D-Bus, a browser +profile and recorded SSIP output. It executes 76 navigation commands, checks silent +Enter on ordinary text, and activates a custom clickable twice, requiring exactly +the page's “Action count 1” and “Action count 2” messages. It does not use the +desktop reader or audible speech. + +Relevant commands: + +```sh +GOCACHE=/tmp/cthulhu-go-cache GOPROXY=off go test -race ./... -count=1 -timeout=120s +go vet ./... +go build -o /tmp/cthulhu-browser-review ./cmd/cthulhu +go build -tags brlapi -o /tmp/cthulhu-browser-review-braille ./cmd/cthulhu-braille +CTHULHU_BINARY=/tmp/cthulhu-browser-review python3 tests/native_browser_navigation.py +CTHULHU_NATIVE_BROWSER_TESTS=pointer,positions,dynamic,linkedheadings,document,editing,selection,tabs,modes,live python3 tests/native_browser.py +python3 tests/native_firefox.py +``` + +## Generated-link recovery acceptance (2026-10-22) + +The original reproduction was the attribution link on +[the Techrights article](https://techrights.org/n/2026/10/22/Linux_Kernel_Needs_Diversity_and_Diversity_of_Good_Code_Not_LLM.shtml). +Brave recreated its CSS-generated `::before` text during native caret placement. +Navigation repeatedly fell back to the containing paragraph instead of advancing. +The first paragraph-only replacement fixture did not cover that link structure. + +Recovery now recognizes a replaced plain text child within the same surviving +ordinary link and adjacent sibling identities. Navigation-triggered defunct +events refresh the affected parent's children while preserving live siblings. +Native text disappearing during text/geometry queries requests a refresh instead +of silently dropping the fragment. Read All uses navigation recovery and rejects +document-generation changes; activation retains its stricter target checks. + +The `generatedlinks` browser fixture uses the page's CSS and reproduces the loop +without a script forcing replacements. It fails with the first recovery fix and +passes with the completed fix, including exact prefix/body text, both navigation +directions and Read All. Three consecutive generated-link runs passed, followed +by a passing combined run of `generatedlinks,replacement,tooltips,fragments,namedlinks,linkedheadings`. +The AT-SPI, review and app race suites, reader build and diff checks passed. + +On 2026-10-22 the maintainer confirmed that the updated reader could read the +entire original article without looping. This accepts full-article reading and +navigation recovery for that live Brave page. The input method was not specified; +separate manual reverse-navigation, Read All, activation and physical Braille +acceptance were not reported. This result does not close the other workflows +below or the separate dynamic-page flat-review failure reproduced before this fix. + +## Other live acceptance checks + +The contribution policy requires human review and live testing before submission. +Automated speech requests and Braille frames do not verify audible output, physical +keys or a physical Braille display. Those automated checks use private sessions +rather than the desktop reader; the live reading result above was reported by +the maintainer separately. + +1. Quit the current Cthulhu with Cthulhu+Q. Press Ctrl+Escape to enter i3 personal + mode, then separately press Shift+G. These are separate key presses. Shift+G + runs `~/devel/cthulhu-go.sh` and rebuilds the reader and Braille helper. +2. Open `file:///home/angus/devel/cthulhu/tests/browser-changing.html` in Brave. + Tab to “Changing document”. Use H through Sections 1–10 and Statistics, then + Shift+H backwards. Pause for several seconds partway through each direction. + Expect the next heading in order, with matching Braille and no unexpected jump + to an earlier heading or location/caret error. +3. At Statistics, press Down to the changing counter. Try Right, Home, + Ctrl+Right, Down and Up. Expect the requested character/word/line and matching + Braille despite the counter updating. Down from the counter should reach + “Following stable line”. +4. On “Following stable line”, press Enter: expect no action feedback. Press + Down to “Custom action”, then Enter twice. Expect only the page's “Action count + 1” and “Action count 2” messages, one per press. No “activated”, “activating” or + activation error should be added. +5. On a stable text line, press Home, Shift+Right twice and Shift+Left once. + Expect selection feedback for the first two characters and removal of the + second. If using Braille, route to the second character to clear selection; + Right must then read the third character, with the Braille cursor there. +6. Check Tab and Shift+Tab into the editable field, type, and use its arrows. + Check Ctrl+L and browser tab switching. Expect native editing/chrome keys to + work and browsing to resume at the correct page after returning. +7. Repeat heading traversal and Enter on the real updating pages that previously + failed. Report the exact key sequence, spoken text, focused control, Braille + text/cursor and any unexpected keyboard behavior. Unexpected results should + be diagnosed from `~/devel/cthulhu-go.log` before another restart. diff --git a/docs/testing/current-line.md b/docs/testing/current-line.md new file mode 100644 index 0000000..a2743f4 --- /dev/null +++ b/docs/testing/current-line.md @@ -0,0 +1,44 @@ +# Current-line command + +Cthulhu+Shift+Up reads the entire current line. Two presses within 500 ms spell +it; three use phonetics. Both desktop and laptop layouts use the same binding. +It follows NVDA's `script_reportCurrentLine` in `source/globalCommands.py`: +native caret outside browse mode, browse cursor inside it. It does not replay +the previous utterance or use the flat-review position. + +Automated checks: + +```sh +go test ./internal/input ./internal/review ./internal/app -run 'Test(CurrentLine|CommandRuntimeRoutesFocusPresentationRequests|ReviewMultiPressSequences)' -count=1 +python3 tests/native_test_session.py env CTHULHU_NATIVE_CURRENT_LINE=1 go test ./internal/atspi -run '^TestNativeCurrentLine$' -count=1 -v +``` + +The private GTK fixture checks Unicode, a caret in the middle of a line, the +end of text, empty controls, blank lines, a trailing newline, password exclusion, +non-text control labels and rejection of stale focus. It verifies native caret +offsets after reading. Worker tests check whole browse lines and multiple inline +fragments, preserving the browse position. Existing flat-review and Say All tests +cover the shared line-reading and multi-press helpers. + +Live acceptance after a normal rebuild and reload: + +1. In a native multiline editor, enter `First line`, `Second café`, an empty line + and `Last line`. Put the caret in the middle of the second line. Press + Cthulhu+Shift+Up: expect the whole second line. Press Left afterward to verify + that the caret did not move. Check the blank line and the end of the last line. +2. Double and triple press to check spelling and phonetics. Pause longer than + 500 ms and verify the next press reads normally. Check both keyboard layouts. +3. Move flat review to a different line. The new command should still read the + application caret line; Numpad 8 or Cthulhu+I should retain the review position. +4. In a browser, move into the middle of a line using browse arrows. Check the + whole line, including inline text fragments, and verify the next arrow + continues from the previous position. In a focused editable field, check the + native caret instead. Try another tab or window while a report is pending. +5. Check a FastSMRW table cell and a button. Check that password contents remain + silent and unavailable text gives explicit failure feedback. Cthulhu+Up must + still increase the selected speech setting. Check Say All and Numpad 8's + spelling behavior for regressions. + +These automated checks do not establish audible output, physical key routing or +Braille behavior. The native implementation uses AT-SPI; Wine Access does not +currently expose this focused-line operation. diff --git a/docs/testing/flat-review-robustness.md b/docs/testing/flat-review-robustness.md new file mode 100644 index 0000000..6a90648 --- /dev/null +++ b/docs/testing/flat-review-robustness.md @@ -0,0 +1,313 @@ +# Flat-review robustness comparison + +Review date: 2026-10-21. Cthulhu baseline: `testing` at `50e32f2`. +Orca reference: upstream `main` at +`828eaf2e70d7b88124b10b3a6b2daa792ab266c7`. The local Orca checkout was +older; fetching the current reference confirmed that the three source files +below have no changes between those revisions. + +This is a source comparison and a set of verified capture and recovery repairs. +It does not establish complete Orca parity or resolve every user report. +At the initial comparison, the available local log contained one +`accessible object not found` flat-review failure without enough evidence to +identify its cause, and no instance of the reported text-limit failure. Older diagnostic logs describe +provider timeouts already addressed by earlier capture work; they are not proof +of a remaining timeout in the current build. + +## What Orca does + +Orca's [Flat Review documentation](https://help.gnome.org/orca/howto_flat_review.html) +describes a spatial representation of the active window's visible contents. +The implementation separates finding on-screen objects, finding visible lines, +and building review zones: + +- [`flat_review.py`](https://gitlab.gnome.org/GNOME/orca/-/blob/828eaf2e70d7b88124b10b3a6b2daa792ab266c7/src/orca/flat_review.py): + `Context` chooses a dialog/frame or an explicit root and restricts to an active + menu when appropriate. `_get_zones_from_text` clips to a scroll pane/document, + gets visible lines, removes embedded-object characters, and builds text zones. + Word and character objects are created on demand. `_find_zone_with_object` + can use a parent or child when the exact focused object was pruned. +- [`ax_utilities.py`](https://gitlab.gnome.org/GNOME/orca/-/blob/828eaf2e70d7b88124b10b3a6b2daa792ab266c7/src/orca/ax_utilities.py): + `_get_on_screen_objects` checks showing/visible state and window intersection, + treats suitable controls as leaves, enumerates visible table cells, and + suppresses some duplicate container text. Invalid component geometry is not + invariably treated as off-screen. +- [`ax_utilities_text.py`](https://gitlab.gnome.org/GNOME/orca/-/blob/828eaf2e70d7b88124b10b3a6b2daa792ab266c7/src/orca/ax_utilities_text.py): + `find_first_visible_line` searches by line rectangles, then `get_visible_lines` + walks forward until below the viewport. Invalid line offsets have explicit + handling. This differs from requiring usable character geometry to find a + large object's viewport. + +These paths do not impose Cthulhu's 256-range/65,536-character object budgets. +That is not evidence that unlimited capture is safe: Cthulhu still needs bounded +native calls, memory use, cancellation, and protection from defective providers. +Orca also has its own tradeoffs: the single-line editable-text path requests all +text, and `Context.is_stale` itself only checks top-level size changes. Presenter +event handling supplies additional context management. Copying one function +alone would not reproduce that behavior. + +## Comparison and priorities + +| Area | Current Cthulhu behavior | Assessment | +| --- | --- | --- | +| Scope | Captures the focused window/menu/dialog and skips hidden descendants during review-only traversal. | Already aligned in principle. Preserve foreground ownership and popup handling. | +| Large GTK tables | Captures visible selectable-table cells and headers; keeps a selected-cell identity anchor. | Already follows Orca's viewport approach. Existing table checks remain relevant. | +| Clipped text ranges | Previously emitted one range per clipped visible character. | Confirmed defect; repaired here. Count contiguous visible spans against the range budget. | +| Viewport discovery | Uses character rectangles first; large objects can use a bounded binary search over line rectangles. | Private GTK coverage seeks into a 101000-character scrolled object with unavailable character rectangles. Small objects keep their existing bounded path. | +| Long horizontal lines | Oversized viewport intervals use glyph locations and bounded text retrieval; oversized native line responses also enter that path. | A real GTK 100000-character line is captured without increasing the character budget. New text requests contain at most 128 characters. Sparse or defective point providers remain bounded and explicitly limited. | +| Failure scope | Known unavailable text objects and failed child enumeration retain healthy content with explicit completeness counts. | Partial-result counts remain diagnostic log data. Line boundaries always use "Top of screen." and "Bottom of screen."; no extra partial-content speech or Braille message is emitted. Root failure, cancellation, stale snapshots, invalid trees, and aggregate layout limits still fail the operation. | +| Focus anchoring | Tries exact focus, displayed descendants, then the nearest displayed ancestor within the review root. | A targeted fixture proves pruned focus stays on its parent text rather than an unrelated first line. Preserved position still uses object generations and native offsets. | +| Updates and cancellation | Cthulhu refreshes owned layout per command and rejects stale results; native capture and queues are bounded. | Preserve these safeguards. Snapshot refresh, provider timeout, and audible responsiveness are separate concerns. | +| Diagnostics | Capture timings include `text_issues` counts for viewport, character, range, tree-byte, query-budget, and provider failures. Partial presentation logs omission counts. | These fields contain no accessible text or names. A wholly limited window retains its existing spoken text-limit message. | + +The line-based discovery, long-line retrieval, explicit partial recovery, and +parent anchoring above are implemented in the current working tree. Capture +budgets, provider-call chunking, cancellation, foreground ownership, and stale +result rejection remain in force. Remaining failures need an application, +triggering command, build revision, and fresh failure/timing record before +assigning a cause. Cold-capture latency remains separate from cached navigation. + +## Repair and evidence + +`internal/atspi/text.go` now accumulates adjacent visible characters with the +same row geometry into one range. It preserves exact Unicode offsets and unions +only their clipped rectangles. A hidden offset, embedded object, or row change +prevents merging across that boundary. The 128-character geometry blocks and +all existing capture budgets remain in force. No new mutable cross-command state +is introduced; span accumulation belongs to one synchronous capture. + +Before the change, a real GTK label with 20 horizontally clipped lines produced +`VisibleText{Limited: true}`. After the change, the same fixture captures more +than 256 characters in at most 21 spans. A deterministic fixture verifies 800 +Unicode characters in 20 spans, exact offsets, and clipping at both edges. Other +regressions cover a span crossing geometry blocks, disjoint bidirectional runs, +and a genuinely excessive number of separate visible spans. Existing tests +cover blank rows, embedded objects, large terminals, cancellation and malformed +provider data. + +The successful four-row capture benchmark, three runs per version, measured +14.6–15.1 microseconds and 180 allocations before, versus 10.4–10.7 microseconds +and 19 allocations after. Allocated bytes fell from 19,664 to 4,048 per capture. +This measures local layout preparation with a synthetic provider; it does not +measure AT-SPI round trips or prove live speech latency. + +## Automated checks + +```sh +go test ./... -count=1 +go test -race ./internal/atspi ./internal/review ./internal/app ./internal/presentation -count=1 +go vet ./internal/atspi ./internal/review ./internal/app ./internal/presentation +python3 tests/native_atspi.py +python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_CLIPPED=1 CTHULHU_NATIVE_REVIEW_CACHE=1 CTHULHU_NATIVE_REVIEW_BOUNDS=1 go test ./internal/atspi -run '^TestNativeFlatReview(ClippedViewport|PreservesProviderCache|BoundsSlowLongRanges)$' -count=1 -v +go test ./internal/atspi -run '^$' -bench '^BenchmarkCaptureVisibleTextClipped$' -benchmem -count=3 +``` + +Use a writable `GOCACHE` if required by the environment. Native harnesses create +private Xvfb/D-Bus/AT-SPI sessions and do not replace the running reader. +All checks above passed for this change. The existing table harness emitted +GTK `Atk-CRITICAL` object-role warnings while its assertions passed; the cause +of those warnings was not investigated here. + +## Follow-up implementation and evidence + +Large-object line discovery moves by validated complete line boundaries during +binary search; it never scans terminal scrollback. Oversized horizontal text +uses native offset-at-point and glyph rectangles to discover visible offsets, +then reads text in spans of at most 128 characters. Offsets are sorted before +capture so bidirectional runs retain exact logical identities. Point traversal +has a 4096-query budget; it checks gaps before skipping vertically so an inset +or shorter glyph is not missed. Ordinary clipped capture continues to use bounded +geometry blocks. Unsupported or excessive work yields an explicit limitation, +not guessed text. No global capture limit was increased. + +A native provider may return a zero-area rectangle for a nonvisible glyph. +That is distinct from a failed native request. Such glyphs now break visible +spans instead of discarding the entire object's usable text. Unavailable whole +line geometry remains an unavailable capture. A private GTK fixture injects a +zero-area glyph and verifies that the surrounding visible text survives and +the missing offset is excluded. Combining marks and joiners attached to a +visible base retain their Unicode offsets even without independent rectangles. +Bounded endpoint lookup also handles a huge line ending in a zero-area newline. + +`ChildrenUnavailable` is capture-owned state copied into the owned tree and +atomic review snapshot. Recovery is restricted to review-only child enumeration; +root enumeration failure and cancellation remain fatal. `FlatCompleteness` +travels with each worker result. No partial object's accessible name is silently +substituted for its missing text. Incomplete-capture diagnostics are logged on +entry or when omission counts change; returning to a complete layout clears +that diagnostic state. Ordinary invalidation triggers recapture as before; there +is no broad automatic retry loop. Partial layouts add no speech or Braille +warning, and boundaries retain the standard top/bottom-of-screen messages. +Spelling retains its own request. + +Seven private native cases cover cache reuse, bounded geometry, clipped spans, +a 100000-character horizontal line, scrolled line-only geometry, unavailable +child enumeration, and zero-area glyphs. Additional worker and presentation +fixtures cover healthy-content recovery, omission counts, recovery to a complete +layout, ancestor anchoring, spelling without extra speech/Braille messages, +and standard boundary feedback on incomplete layouts. Run native modes in separate processes: + +```sh +python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_VIEWPORT=1 CTHULHU_NATIVE_REVIEW_VIEWPORT_MODE=long go test ./internal/atspi -run '^TestNativeFlatReviewLargeTextViewport$' -count=1 -v +python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_VIEWPORT=1 CTHULHU_NATIVE_REVIEW_VIEWPORT_MODE=lines go test ./internal/atspi -run '^TestNativeFlatReviewLargeTextViewport$' -count=1 -v +python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_SUBTREE=1 go test ./internal/atspi -run '^TestNativeFlatReviewUnavailableSubtree$' -count=1 -v +python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_GLYPHS=1 go test ./internal/atspi -run '^TestNativeFlatReviewZeroAreaGlyph$' -count=1 -v +``` + +A read-only probe of the open FastSMRW instance exposed zero-area glyph failures +that previously left visible table-cell text unavailable. After the repair, +27 worker commands across line, word, character, window-start, and window-end +review passed with zero reported omissions. Cached commands took about 0.3-0.7 +milliseconds. Initial capture still took about eight seconds, mostly in visible +text. The standalone probe had no retained native focus event and reported +`root_scope=desktop` while filtering capture to FastSMRW's provider; this timing +does not establish normal foreground reader latency. No application keys were +injected and the running reader was not replaced. These results do not establish +audible speech or physical Braille acceptance. + +### Follow-up check results + +The full Go suite, affected-package race tests, vet, command builds, parity +ledger validation, recorded-speech checks, and all seven targeted native GTK +cases passed. The broad `tests/native_atspi.py` harness initially failed +`TestNativeGUIListTableSpeech` because the launcher description was repeated. +The isolated table checks passed on both an untouched `50e32f2` snapshot and the +changed tree, and a subsequent complete harness run passed. The initial failure +was not explained; passing reruns do not establish that this startup/event-order +behavior is stable. Existing GTK `Atk-CRITICAL` role warnings also remain. + +## Dynamic-page visibility cache regression + +On 2026-10-22, `TestNativeBrowserDynamicNavigation` reproduced a separate +flat-review failure after browse navigation scrolled a 1000-paragraph page to +newly inserted content. Window-end review returned "New content", but previous +line returned the same text with `Moved=false`, including after a text-triggered +recapture. + +Temporary capture diagnostics showed one review line: cached AT-SPI `SHOWING` +states still described the original viewport. Paragraphs now on screen were +treated as hidden, while the originally showing paragraphs had current bounds +far above the window. Cursor restoration was not the cause. The 40 omitted +objects were browser-chrome text-provider failures and remained after the fix; +they did not account for the missing page paragraphs. + +For a node entering a review-only native capture, refresh the cached state bits +before reading its snapshot and geometry. Preserve cached children, interfaces, +and the existing dirty-node refresh policy. This recovers the current viewport +without adding retries or changing any text, range, tree, or deadline limits. +The diagnostic capture then contained 26 review lines. Temporary text-bearing +diagnostics were removed from the code. + +```sh +CTHULHU_NATIVE_BROWSER_TESTS=dynamic python3 tests/native_browser.py +``` + +The strengthened regression keeps the original window-end/previous-line +sequence and requires "New content", "End of page", and "Unrelated paragraph +999" in order. It also checks forward lines, words, characters, the last +character at window end, and backward recovery after the bottom boundary. +Private GTK provider-cache and clipped-text regressions and the native AT-SPI +harness passed, including terminal and table workflows. The table harness still +emitted GTK `Atk-CRITICAL` role warnings while its assertions passed. +Race tests and vet for `internal/atspi`, `internal/review`, and `internal/app`, +plus `go build ./cmd/...`, also passed. The initial ordinary app-package run +could not create private Unix speech sockets inside the sandbox; the approved +race run outside that restriction passed all three packages. + +For live acceptance after an authorized build/restart, browse to the bottom of +a long dynamically updated page. Press Cthulhu+Numpad 9, then Numpad 7: speech +and Braille should move from the final visible line to its predecessor. Check +forward movement back to the final line, bottom feedback, and backward movement +again. Repeat after scrolling back up and check word/character review and a +native terminal. These automated checks do not establish physical-key, audible +speech, or Braille acceptance. + +## Browser chrome omissions and standard messages + +A private Chromium-family browser probe reproduced 40 omitted objects. Native +text queries exposed three distinct provider patterns: containers containing +only embedded-child placeholders, named controls returning their accessible +labels through Text but invalid line offsets, and real text with unavailable +geometry. Both character and range geometry were zero for the failing chrome +objects. The address entry's native Text contained its URL, not its label. + +After a provider failure, bounded verification now allows embedded-only +containers to use child-provided content. A noneditable named control or static +label can use the existing synthetic-name path only when its native text +exactly equals its accessible name and its component is fully inside the clip. +Editable text, passwords, differing names/text, mixed container content, capture +limits, and clipped labels do not qualify. Recovered names have no native text +offsets. This is a generic provider-content rule, not a browser-name exception. + +Tabs and compound menu rows also retain their own label beside independently +named child actions such as Close. Text/label descendants still suppress duplicate +parent labels. Ordinary nested-button suppression is preserved. + +The new browser proof fails with the fixes disabled: Back, Forward, Reload, +New Tab, and the tab label are absent, with 40 omissions. With the fixes enabled, +these controls and popup entries are reviewable. The window fixture reports +two omissions (the address entry and a mixed-text panel); its popup reports +none. These counts describe this fixture, not every browser or screen. +The mixed-text panel remains conservatively unresolved even though a static +child supplies its displayed label. The address URL remains unavailable in flat review because +its visible character span cannot be established from zero geometry. Neither +its label nor its entire potentially clipped value is substituted. Ordinary +address-bar focus and editing remain separate from geometric flat review. + +The partial-content speech/Braille warning is removed. Both complete and partial +layouts use "Top of screen." and "Bottom of screen." Omission counts remain in +diagnostics; fatal capture errors keep their existing messages. Ask before +adding or replacing established user-facing messages. + +```sh +CTHULHU_NATIVE_BROWSER_TESTS=flat-chrome,dynamic,menu python3 tests/native_browser.py +``` + +The new proof checks actual tab-label zones, toolbar controls, focused/unfocused +address handling, and popup review. The dynamic-page proof retains its stale +state-cache fix and backward/forward line, word, and character navigation. +Focused unit cases reject unsafe component recovery and verify tab/menu labels +with child actions and text-label deduplication. Existing cache, clipping, and +zero-area-glyph native checks also remain relevant. + +After an authorized build/restart, check speech and physical Braille separately: +review the tab strip and toolbar, including a tab's title and Close control; +open the browser menu and review its rows and inline controls; return to the +page and exercise dynamic-page backward review. At the first/last review line, +Numpad 7/9 must announce only the standard screen boundary. No partial-content +message should interrupt review or flash Braille. Check normal address-bar +focus/typing, a narrow/scrolled field, passwords, a native terminal, and native +text clipping. Address-value flat review remains a known limitation in the +observed provider. Private tests do not establish audible speech, physical +keys, or Braille acceptance, and the running reader was not replaced. + +## Human review and live acceptance + +Review the generated diff before submission. With an authorized build/restart: + +1. In a native editor or a window containing a wide multiline text control, + horizontally scroll so multiple lines are clipped. Review lines, words, and + characters forward and backward; visible text must remain available when + the total exceeds 256 characters. Repeat after resizing and scrolling. Check + the first and last partially visible characters and Unicode offsets. +2. Review ordinary and large terminal screens, blank rows, and a large file in + a terminal editor. Check Numpad 7/8/9, 4/5/6 and 1/2/3, window start/end, + explicit top/bottom feedback, and multi-press spelling. +3. Check a browser with horizontally clipped text and embedded links, a GTK + table such as a timeline, a preferences notebook, and a popup menu. Hidden + letters and embedded-object placeholders must not be spoken as ordinary text. + Password contents must stay excluded. Review must stay in the foreground + window and ordinary focus/caret navigation must still work afterward. +4. Exercise a window with one unavailable text object or child subtree. Healthy + content must remain reviewable without an additional partial-content + announcement. Verify omission diagnostics in the log, then refresh after the + provider recovers. Top/bottom feedback must use the same standard messages + before and after recovery. +5. Confirm audible speech and physical Braille separately, including routing + within a merged span. Native capture and Go test success do not establish + these outcomes. Preserve fresh logs for any remaining failure. + +The code change affects shared visible-text capture used in owned trees; +terminal, browser, mouse-review, and Braille consumers can therefore be affected +indirectly. It changes neither X11 key grabs nor foreground ownership. Wayland +live acceptance remains separate. diff --git a/docs/testing/flat-review-tables.md b/docs/testing/flat-review-tables.md new file mode 100644 index 0000000..119c0ed --- /dev/null +++ b/docs/testing/flat-review-tables.md @@ -0,0 +1,109 @@ +# Flat review in scrolling tables + +Flat review captures the visible cells of selectable tables through AT-SPI +table coordinates and component hit testing. It does not enumerate the model's +offscreen rows. Visible column headers and compound cells remain available. +The first selected cell is retained as a focus anchor if horizontal scrolling +hides its column; its offscreen text does not enter review output. + +New flat-review objects retain libatspi's event-maintained provider cache. +Clearing that cache forced redundant child-count requests even for known leaves, +which could abort capture when a provider was briefly unresponsive. Objects +already marked dirty in the owned tree still refresh their native snapshot. + +Long text geometry queries are bounded to 128 characters per provider call. +Their rectangles are combined across every chunk, including interior bidi runs. +For partially clipped lines, offscreen chunks are rejected before querying +individual character rectangles. This preserves native offsets and visible text +without measuring thousands of characters in one synchronous request. +Exact range rectangles are reused only within one object's synchronous text +capture, including zero-area rectangles. This avoids querying the same 128-character +blocks once to combine line bounds and again to clip the line. The map is discarded +when that object's text capture returns; a changed viewport or later command does +not reuse it. Failed requests are not stored, and cancellation is checked before +using a saved rectangle. Individual glyph checks for clipped text remain intact. + +In the live FastSMRW investigation, measuring an entire 3,424-character line took +about 0.9 seconds, exceeding the adapter's 0.8-second provider timeout. A later +child-count query then reported that the process appeared hung, masking the +earlier text-geometry timeout. The same read-only capture probe failed before +bounded measurement and completed after it. That is provider-capture evidence; +speech, keyboard response and physical Braille still require live acceptance. +Three subsequent read-only review-worker runs completed line, word, character, +window-start and window-end commands. Initial capture took roughly 4–6 seconds; +cached commands took about one millisecond. One earlier worker probe returned a +negative child count, which did not recur in those three runs. Negative-count +errors now include the same object metadata as provider-error responses so a +recurrence can be located. Initial-capture latency remains a live acceptance +concern. + +Debug logs include one `flat review capture timing` record for each capture +attempt, including a timed-out attempt while a native call is still running. +It reports request-lock and GLib queue wait, root selection, cache preparation, +snapshot, geometry, visible-text, table-viewport, child-count, child-enumeration, +installation and reference-cleanup timings. Each stage has a total, invocation +count, and longest invocation with its bus/path/role. These are helper-stage +timings: a visible-text invocation can contain several native range queries. +`last_stage`, `stage_duration` and the object identity describe the stage at +completion or timeout; on timeout its elapsed portion is included in totals. +`root_scope` distinguishes a focused-window root from the desktop fallback. +Captured/pending object counts and text byte counts show traversal progress. +No names or text contents are added. Diagnostics allocate no per-capture trace +unless debug logging is enabled, and do not issue additional provider queries. +Late native completion cannot overwrite the timeout record. + +A descendant which becomes defunct during capture is removed from its parent's +child list. A defunct root still fails capture. Other provider failures still +fail capture rather than presenting an old snapshot. Child-count errors include +the object's bus, path, role and the number of objects already captured, without +logging its name or text. + +Run the native viewport regression on a private display and accessibility bus: + +```sh +python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_TABLE=1 go test ./internal/atspi -run '^TestNativeFlatReviewLargeGTKTable$' -count=1 -timeout=150s -v +python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_CACHE=1 go test -race ./internal/atspi -run '^TestNativeFlatReviewPreservesProviderCache$' -count=1 -timeout=30s -v +python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_BOUNDS=1 go test -race ./internal/atspi -run '^TestNativeFlatReviewBoundsSlowLongRanges$' -count=1 -timeout=30s -v +python3 tests/native_atspi.py +``` + +The viewport test covers a 6,000-row GTK table scrolled to its middle, a changed +viewport and updated row text, a small table, an empty table with headers, +horizontal scrolling, and cells with multiple renderers. It checks that a small +viewport captures fewer than 100 objects. Before the change, the large case +captured 6,006 objects. The existing suite covers flat-review cursor movement, +text changes, terminal viewport capture, password exclusion, and ordinary +single/multiple GTK table selections. + +The cache regression uses a GTK label whose initial cache reports zero children, +then arms a deliberately slow child-count getter. Before cache preservation, +capture failed on that redundant query. The test requires capture to succeed +without invoking the getter, then changes the label and checks that dirty text +is refreshed. The C fixture is compiled with the existing GTK development +dependencies during the test. + +The long-range regression uses a horizontally clipped 3,424-character GTK label. +Its provider deliberately stalls when a range query exceeds 128 characters. +Capture must retain visible text and never trigger that large request. The fixture +also counts repeated native range requests: the original implementation repeats +36 requests, while capture-local reuse makes none. Unit +tests also cover Unicode offsets, offscreen query counts, interior bidi bounds, +zero-size chunks, cancellation and provider errors. + +For live acceptance, use a user-started updated reader and: + +1. In FastSMRW, review lines, words and characters in both directions, including + window start/end. Repeat after changing the selected post and after a timeline + update. Responses should complete without a long pause or a location error. +2. Scroll the table away from its original viewport. Review should contain the + currently visible rows. Check another GTK table, its column headers, and a + horizontally scrolled table. +3. Check ordinary Up/Down selection speech, menus, preferences notebooks and + terminal flat review. Semantic browser navigation and table speech should + continue to work because their captures retain the complete semantic tree. +4. Confirm audible output and physical Braille separately. Private native tests + do not establish these outcomes or prove that the live FastSMRW timeout is + resolved. Preserve fresh logs if a failure remains; the object metadata will + identify where capture stopped. Inspect `flat review capture timing` to + compare the failed initial capture with a successful retry, including root + scope, queue wait, stage totals and the slowest object in each stage. diff --git a/docs/testing/flatpak-foreground.md b/docs/testing/flatpak-foreground.md new file mode 100644 index 0000000..97d631d --- /dev/null +++ b/docs/testing/flatpak-foreground.md @@ -0,0 +1,80 @@ +# Flatpak foreground accessibility + +The Python `master` reference's `script_utilities.py:canBeActiveWindow` +requires active, showing, non-iconified state. It does not require X11 and +AT-SPI process IDs or window rectangles to agree. Go's additional correlation +checks exposed two Flatpak cases: + +- `_NET_WM_PID` can be relative to the application's PID namespace. The Xorg + foreground reader now prefers XRes 1.2's local connection PID. It retains + the property as a fallback when server-side lookup is unavailable. +- AT-SPI's process query returns the D-Bus connection owner, which can be a + proxy. The adapter accepts different processes only when their + `/proc/PID/root/.flatpak-info` files identify the same application and running + instance. Active state, geometry and existing window ownership still apply. + +This is shared foreground handling, with no Steam name or window-title match. +It covers direct events, foreground recovery, menu correlation and OCR's +process check. It does not establish compatibility with every Flatpak, native +Wayland focus, or application-specific scripts behind a proxy. Missing or +unreadable instance metadata does not relax matching. The reported Steam 2x2 +auxiliary frames remain subject to the ordinary geometry checks. + +XRes adds the `libxres` Arch dependency (`xres` pkg-config module). Debug logs +record both the resolved X11 PID and original property PID. + +The Xorg owner caches one client's lookup until the window or property changes. +The AT-SPI GLib owner bounds provider comparisons to 128 entries and clears them +when the foreground window, process or known state changes. Metadata reads are +limited to regular files of at most 64 KiB. No process scan or service manager +is used. + +References: [AT-SPI process query](https://gnome.pages.gitlab.gnome.org/gtk/atspi2/method.Accessible.get_process_id.html), +[proxy credentials](https://github.com/flatpak/xdg-dbus-proxy/blob/main/xdg-dbus-proxy.xml), +[Flatpak instance metadata](https://github.com/flatpak/flatpak/blob/main/doc/flatpak-metadata.xml), +[libwnck's XRes namespace correction](https://lists.gnome.org/archives/commits-list/2022-March/msg10404.html). + +## Automated checks + +Run the private fixtures sequentially. The GTK mismatch test fails before the +XRes change. The proxy fixture uses real bubblewrap mount namespaces and +xdg-dbus-proxy, with synthetic instance metadata; it needs neither an installed +Flatpak nor a running desktop reader. + +```sh +CTHULHU_FOREGROUND_PID=1 python3 tests/native_atspi.py +CTHULHU_FOREGROUND_PID=1 CTHULHU_FOREGROUND_PROXY=1 python3 tests/native_atspi.py +CTHULHU_FOREGROUND_PID=1 CTHULHU_FOREGROUND_PROXY=1 CTHULHU_FOREGROUND_PROXY_OTHER=1 python3 tests/native_atspi.py +xvfb-run -a env CTHULHU_NATIVE_WINDOW_TITLES=1 go test ./internal/platform/xorg -run '^TestNativeWindowTitleDiscovery$' -count=1 +xvfb-run -a -s '-screen 0 1280x1024x24 -extension X-Resource' env CTHULHU_NATIVE_WINDOW_TITLES=1 CTHULHU_XRES_DISABLED=1 go test ./internal/platform/xorg -run '^TestNativeWindowTitleDiscovery$' -count=1 +``` + +The final proxy case must reject the control from a different instance of the +same application. Xorg tests cover cached reads, property changes, empty +workspaces, destroyed windows and fallback without XRes. Also run the affected +Go packages and `tests/native_ownership.py` with `CTHULHU_BINARY` pointing to a +fresh isolated build; that checks GTK, Qt and Brave foreground boundaries. + +## Live acceptance + +Actual Flatpak Steam, audible speech and physical Braille remain unverified. +On the maintainer's i3 setup: + +1. Quit Cthulhu with Cthulhu+Q. Press Ctrl+Escape, then Shift+G as separate key + presses. Shift+G runs `~/devel/cthulhu-go.sh` and rebuilds both binaries. +2. Launch `flatpak --user run com.valvesoftware.Steam -tenfoot`. Press Tab and + Shift+Tab through controls. Each focus move should announce the control + label and role; a working Braille display should follow that same control. +3. Open and close a Steam menu with Escape, navigate with arrows and Enter, + then type in search. Keys should reach Steam and speech should track the + selected control or edited text. +4. Switch to another application's window and back. Steam's ordinary control + events should not interrupt the other application; returning should restore + announcements. Repeat with another available Flatpak and a native browser. +5. Report the exact spoken text, Braille text if connected, focused control and + key that differed from expectation. Preserve `~/devel/cthulhu-go.log` after + an unexpected result. A remote tester should use their own equivalent rebuild + and debug-log launcher; the i3 bindings above are local customizations. + +The original report also contains independent Braille geometry errors. This +foreground change does not repair the Braille helper's connection failure. diff --git a/docs/testing/gui-list-tables.md b/docs/testing/gui-list-tables.md new file mode 100644 index 0000000..e7e7e33 --- /dev/null +++ b/docs/testing/gui-list-tables.md @@ -0,0 +1,44 @@ +# GTK tables exposed as lists + +I38's run dialog uses a GTK TreeView whose accessible role is overridden to +`list`. It still exposes table selection and table cells. On the first Down, +GTK can send container focus, row selection and container focus again. + +Cthulhu resolves this control's focus to its selected cell using the existing +table selection rules. Recognition requires the GTK toolkit, list role and +AT-SPI Table interface. Multiple selected rows retain container focus. Cell +capture preserves the table owner so subsequent arrows remain readable. +Ordinary lists and browser lists do not use this added normalization. + +Window descriptions spoken during entry activation are remembered before the +first row selection. Changed or newly available help remains eligible for +speech. A list's name is supplied by list context when enabled, or by the +existing table-name presentation when list context is disabled. + +Run the affected packages and isolated GTK checks: + +```sh +go test -race ./internal/app ./internal/atspi ./internal/presentation -count=1 +python3 tests/native_atspi.py --table-only +``` + +The native checks cover ordinary single- and multiple-selection tables, tables +with list roles, and combined focus/context/speech delivery. The speech check +uses Down twice and Shift+Tab: each row and the opening description occur once, +and the only list-exit announcement occurs on returning to the entry. The +fixture counts accessible children according to existing list-count behavior; +that count can include headers and individual cells. + +Before submission, review the diff and test with the rebuilt reader: + +1. Open I38 Run, wait for its instructions, and press Down several times, then + Up. Confirm the first result is readable without repeated help or a false + list-exit announcement. Return to the entry with Shift+Tab, type a filter, + re-enter the results, and close and reopen the dialog. +2. In a file manager and Cthulhu's preference tables, check Up/Down, Left/Right, + multiple selection and the full-row reading preference. +3. Check an ordinary GTK list, a menu and a browser list. Genuine container + exits must still be announced when enabled. Toggle list-context speech and + description speech, checking that enabled labels/help remain available. +4. Repeat the affected navigation with a physical Braille display when + available. Automated checks do not establish audible or physical acceptance. diff --git a/docs/testing/mozilla-reading.md b/docs/testing/mozilla-reading.md new file mode 100644 index 0000000..ce095c9 --- /dev/null +++ b/docs/testing/mozilla-reading.md @@ -0,0 +1,86 @@ +# Firefox and Thunderbird reading baseline + +The first Mozilla release-readiness slice covers reading an ordinary Firefox +page and a saved HTML message in Thunderbird. Both applications can expose a +heading or link as a text-bearing leaf without a static text child. Document +capture previously recorded zero characters for these roles. Structural heading +navigation still worked, but arrow reading and Read All skipped their content. +Capturing their native text counts fixes this at the shared AT-SPI boundary. +It does not add browser- or application-specific navigation rules. + +## Automated verification + +Build a separate reader and run: + +```sh +go build -o /tmp/cthulhu-mozilla-review ./cmd/cthulhu +python3 tests/native_firefox.py +CTHULHU_BINARY=/tmp/cthulhu-mozilla-review /usr/bin/python3 tests/native_mozilla.py +``` + +The last command requires Firefox, Thunderbird, i3, Xvfb, xdotool, D-Bus and +Python with pyatspi. Pass `firefox` or `thunderbird` to run just one application. +It creates a separate X display, accessibility/session buses, application +profile, reader configuration and speech protocol recorder for each run. +Thunderbird uses a synthetic local identity and a saved message; no mail account +credentials or SMTP server are configured. Existing profiles and the active +desktop reader are not used. + +The evidence directory printed for each application retains the profile, +fixture, reader/application/session logs, `speech.json` and `report.json`. +The test checks: + +- Ctrl+Home reads the initial heading. +- Down and Up traverse all six content items in order, including headings and + the link. +- Heading jumps followed by Down reach the following paragraph. +- Link navigation reaches the expected link. +- Read All emits every content item in order, with heading/link roles. + +The original Firefox metadata test now asserts heading and link character counts +in the captured document. This assertion fails on the original implementation. +It also retains the existing address-bar/page handoff and browser-tab checks. +The reader-level checks passed with Firefox 158.0 and Thunderbird 158.0. Each +run completed 17 navigation commands and Read All; the recorded navigation +results contained no native caret synchronization errors. + +Shared capture changes also need Chromium checks: + +```sh +go test -race ./internal/atspi ./internal/review ./internal/presentation ./internal/app -count=1 -timeout=120s +CTHULHU_NATIVE_BROWSER_TESTS=fragments,linkedheadings,document,editing,selection,modes python3 tests/native_browser.py +``` + +These cover plausible regressions in child-text traversal, linked headings, +structural movement, native editing, selection, Braille routing and focus modes. + +## Human review and live acceptance + +Review the diff and test through the normal rebuilt reader before submission, +as required by the contribution policy. Protocol recordings prove requested +speech, not audible output, physical keyboard behavior or physical Braille. +The Mozilla reader-level harness disables Braille. + +1. Open the retained `reading.html` in Firefox and `message.eml` in Thunderbird. + Move focus into their content. +2. Press Ctrl+Home. Expect "Reading start", heading level 1. Down must read + "First readable paragraph.", "Reading section", "Second readable paragraph.", + "Local destination link" and "Final readable paragraph." in that order. + Up must reverse that order. Check spoken roles and matching Braille. +3. From the first heading, press H and then Down. Expect "Reading section" + followed by "Second readable paragraph.". Check ordinary character and word + movement within a heading and link as well. +4. Return to the start and invoke Read All. Expect every content item, including + both headings and the link. Interrupt it and verify the next navigation + command reads from the expected position. +5. In Firefox, use Ctrl+L and browser-tab switching, then return to the page. + In Thunderbird, move between message headers and body. Verify native controls + retain their keyboard behavior and reading resumes in the correct document. +6. Repeat with representative plain-text and HTML email and ordinary websites. + Check existing Chromium reading, linked headings, editing and selection too. + +This is a reading baseline, not complete Thunderbird acceptance. Folder and +message-list navigation and unsent composition now have their own +[local-mail workflow checks](thunderbird-workflows.md). Settings and real mailbox +workflows still need dedicated acceptance checks. +Page summaries, automatic Read All on load and math support remain separate work. diff --git a/docs/testing/phonetic-review.md b/docs/testing/phonetic-review.md new file mode 100644 index 0000000..1afa1dc --- /dev/null +++ b/docs/testing/phonetic-review.md @@ -0,0 +1,51 @@ +# Flat review spelling and phonetic hints + +Build a separate binary, preserving the running reader: + +```sh +go build -o /tmp/cthulhu-phonetic-review ./cmd/cthulhu +python3 tests/native_test_session.py go test -race ./internal/input ./internal/config ./internal/preferences ./internal/app ./internal/review ./internal/presentation -count=1 +CTHULHU_BINARY=/tmp/cthulhu-phonetic-review CTHULHU_PREFS_READING_ONLY=1 /usr/bin/python3 tests/native_preferences.py +CTHULHU_BINARY=/tmp/cthulhu-phonetic-review /usr/bin/python3 tests/native_x11.py +python3 tests/check_speech.py +``` + +The native fixtures use private Xvfb, D-Bus and AT-SPI sessions. Run them +sequentially. They verify command consumption and releases, repeat routing, +accessible checkbox state, Space/arrows/Tab/Shift+Tab, Apply and reload. Go tests +verify line spelling including spaces and repeated letters, OCR cursor/Braille +stability, the hint delay and cancellation, silent modes, defaults, persistence +and application overrides. These checks do not establish audible speech or +physical keyboard/Braille behavior. + +After reviewing the diff and installing/restarting through the normal process: + +1. In a text editor, use a line such as `A book!`. Check single/double Numpad 2, + single/double/triple Numpad 5 and single/double/triple Numpad 8. Presses within + each sequence must be no more than 500 ms apart. Confirm immediate ordinary + speech on the first press, repeated letters, capitals, spaces and punctuation. + Pause longer than 500 ms and confirm the next press starts ordinary reading. +2. Check the same actions in a terminal and a browser. If using laptop layout, + use Cthulhu+Comma, Cthulhu+K and Cthulhu+I. Confirm other review movement and + window start/end still work, with no leaked or stuck keys. If using OCR or + Wine flat review, confirm the line sequence and retained Braille cursor there. +3. In Speech → Reading settings, confirm Phonetic character hints starts + unchecked. Toggle with Space, Apply, and use plain Left/Right through text: + `a` should be followed about 300 ms later by `alpha`. Try capitals and repeated + letters. Move or type before the delay expires: the previous hint must not + follow the new character. Hold an arrow and confirm navigation stays responsive. + With capital beep, raised pitch and “cap” enabled, arrow to `T`: those cues + should occur only with the character, followed by plain `tango` in the normal + voice. Double Numpad 2 and triple Numpad 5/8 should retain capital cues in their + explicitly requested phonetic output. +4. Confirm Ctrl+Left/Right, Shift+Left/Right, Home/End, typing, punctuation and + spaces retain their usual behavior. Repeat in browser browse and editable + text modes and a supported Wine editor when available. Turn speech off and + on; hints suppressed while off must never replay. Confirm capital pitch/beep/ + “cap” choices and ordinary speech queues still behave as configured. +5. Uncheck and Apply: arrows should speak characters alone again. Check saved + state after restart and application-specific settings if used. Cancel a draft + toggle and confirm it does not change the saved choice. With Braille enabled, + confirm hints do not move the review or Braille cursor or replace its text. + +Human review and these listening checks remain required before submission. diff --git a/docs/testing/qt-control-states.md b/docs/testing/qt-control-states.md new file mode 100644 index 0000000..a0a8a25 --- /dev/null +++ b/docs/testing/qt-control-states.md @@ -0,0 +1,109 @@ +# Qt control state reporting + +Cthulhu preserves AT-SPI checkability independently of the native role. +An ordinary menu-item role with CHECKABLE, CHECKED or INDETERMINATE is +presented as a check menu item for speech, state sounds and Braille. A checked +state-change event also establishes checkability when its new value is false. +When a provider omits CHECKABLE, Cthulhu remembers that evidence on the native +accessible object, so a subsequent unchecked value still has check-menu +semantics. This applies to all applications without matching names or labels. +An ordinary menu command without that evidence keeps its existing presentation. + +Qt menu actions can change state without sending a checked-state event. +Cthulhu refreshes their native cache on focus so reopening a menu reads the +current state instead of a previously cached value. + +Actions shared between a menu bar and a context menu can keep their original +AT-SPI parent. Qt can emit focus-gained for the shared accessible while a state +query reports it unfocused because its original menu is hidden. Cthulhu uses +that explicit focus event for menu items, including check and radio menu +items, before applying the existing foreground checks. The event must name +the captured accessible itself; redirected descendants and defunct items do +not inherit this evidence. No focus evidence is retained beyond the event. + +Checkability evidence belongs to the AT-SPI accessible on the GLib owner +thread. No extra accessible references are retained. It ends with that object's +native lifetime, is cleared on defunct/name-change events or a changed role, +and respects withdrawal of an explicitly exported CHECKABLE state. Replacement +actions, including ones with the same label, do not inherit the evidence. + +## Automated checks + +Run the generic Qt 5 (PyQt5) and Qt 6 (PySide6) fixture with: + +```sh +/usr/bin/python3 tests/native_qt_controls.py +``` + +This uses private Xvfb, D-Bus and temporary configuration directories. It checks +queued speech and Braille frames through Cthulhu's event loop for menu-bar and +context-menu actions, checking and unchecking ordinary checkboxes and checkable +buttons, an ordinary menu command, same-label action replacement, and explicit +capability removal. It also traverses shared and context-only actions in both +directions and after reopening the context menu. It requires both Python Qt bindings, +xdotool and the native build dependencies. It does not replace the active +reader or establish audible speech or physical Braille acceptance. + +Existing package checks cover mixed states, state sounds, speech-only and +sound-only modes, and repeated focus after checking and unchecking. The +existing browser menu test checks ordinary and compound menu navigation: + +```sh +go test ./internal/atspi ./internal/presentation ./internal/app -count=1 +CTHULHU_NATIVE_BROWSER_TESTS=menu /usr/bin/python3 tests/native_browser.py +``` + +## Providers which omit checkability + +The tested Mumble 1.5.939 / Qt 5 installation exports Mute Self and Deafen Self +as ordinary menu items, with CHECKED only while checked and no CHECKABLE state. +Its toolbar equivalents use the check-box role. Qt 5's upstream +[AT-SPI state mapping](https://github.com/qt/qtbase/blob/5.15/src/platformsupport/linuxaccessibility/constant_mappings.cpp) +omits `state.checkable`, although +[menu accessibility](https://github.com/qt/qtbase/blob/5.15/src/widgets/accessible/qaccessiblemenu.cpp) +sets that field internally. Qt 6's +[mapping](https://github.com/qt/qtbase/blob/6.12/src/gui/accessible/linux/qspi_constant_mappings.cpp) +exports it. + +No toolkit patch is required for Cthulhu to retain observed checkability. +The Qt 5 native fixture verifies the sequence unchecked, checked, unchecked +for both menu-bar and context-menu actions. After checking establishes the +capability, unchecking and reopening announces `not checked`, with the +corresponding Braille indicator. Native checked-state events establish the same +capability even when the first observed transition is to false. + +The Python reference's `generator._generateCheckedStateIfCheckable` and Orca's +`generator._generate_state_checked_if_checkable` also treat CHECKED as sufficient +evidence even without CHECKABLE. Their menu generators do not assign an +unchecked state to an ordinary menu action without evidence. + +On first encountering an unchecked menu action with neither the correct role +nor CHECKABLE nor a checked-state event, its semantics are unknown. Cthulhu +keeps ordinary menu presentation until evidence arrives, rather than +announcing every menu command as unchecked. Retained evidence cannot detect +an unreported capability removal by a provider that never exports CHECKABLE; +object destruction, role changes and name changes still retire it. + +## Live acceptance + +After reviewing the diff, rebuild and restart the intended Cthulhu binary: + +1. In Mumble's Self menu, navigate to Mute Self and Deafen Self. Toggle each, + reopen the menu, and confirm both checked and not-checked states once the + capability is established. Restore the original settings. +2. On a server authorized for testing, open another user's context menu and + exercise Local Mute in both states. Reopen the menu after each change. + Restore the original local mute setting; do not change server mute. +3. Test the toolbar mute/deafen controls and ordinary settings checkboxes in + both states. Confirm Tab and Shift+Tab still reach adjacent controls. +4. Navigate ordinary Mumble and browser menu commands. Confirm no invented + checked state, duplicate announcements, or lost keyboard focus. +5. Listen to actual speech and check a physical Braille display when available. +6. Open your own user context menu. Arrow through every enabled item in both + directions, including ordinary commands and checkable items, then close and + reopen it and repeat. Confirm every stop reads once. Also test the menu-bar + equivalents, Escape back to the user list, and switching away from Mumble + while the popup is open; background menu events must remain silent. + +Do not submit before human review and live testing, as required by +[the contribution policy](../../CONTRIBUTING.md#ai-assisted-contributions). diff --git a/docs/testing/reading-settings.md b/docs/testing/reading-settings.md new file mode 100644 index 0000000..a0407b6 --- /dev/null +++ b/docs/testing/reading-settings.md @@ -0,0 +1,51 @@ +# Reading settings descriptions + +Build a separate test binary and run the focused checks: + +```sh +go build -o /tmp/cthulhu-reading-descriptions ./cmd/cthulhu +go test ./internal/preferences ./internal/presentation -count=1 +go test ./internal/app -run 'GUITable|GUIListTable|Context|PauseChunks' -count=1 +CTHULHU_BINARY=/tmp/cthulhu-reading-descriptions CTHULHU_PREFS_READING_ONLY=1 /usr/bin/python3 tests/native_preferences.py +``` + +The native check uses private Xvfb, D-Bus and AT-SPI services. It checks all +three column headers, a description for every setting, checkbox states, +Left/Right and Up/Down navigation, Space from the description column, +Tab/Shift+Tab, Apply/reload and Cancel. The reader tests check full-row speech +including a third cell, individual-cell speech and interruption. + +Before submission, review the diff and check the rebuilt reader in a live +session: + +1. Open Preferences, select Speech and enter Reading settings. With Speak full + row in GUI tables enabled, use Up and Down and confirm the state, setting + name and explanation are spoken in that order. +2. Press another navigation key before an explanation finishes. Confirm the + earlier speech stops and the new row is announced promptly. +3. Use Left and Right to reach all three cells. Confirm the description is + read in full, without repeating the setting title or checkbox state. +4. Press Space from each column and confirm it toggles only the selected + setting. Apply, close and reopen preferences to check saved state. Change a + checkbox again and Cancel to confirm the change is discarded. +5. Check Tab and Shift+Tab into and out of the table. Disable full-row reading + and confirm arrows read individual cells. Restore the preferred setting. +6. Check the modifier-key table and an application table to confirm their + existing row and cell reading still works. Check the new descriptions on a + physical Braille display when available. +7. In FastSMRW, move through the timeline and switch workspaces to a terminal. + Confirm no enter/leave container announcements occur. Also Tab into and out + of Preferences tables and a native application's list: names, rows and cells + should still be spoken, without a separate container exit announcement. +8. In browser browse mode, navigate into and out of a list and data table. + Confirm enabled context announcements still work, including during Say All. + Switch to focus mode, browser chrome or another workspace and confirm there + is no container exit announcement. Return to browse mode and check context + is announced again when entering a container. +9. Focus a button with a mnemonic, such as Preferences' Apply button. With + pause breaks enabled, confirm the mnemonic follows as a separate chunk. + Disable pause breaks and confirm the announcement is combined. Restore the + preferred setting. + +Automated checks do not establish audible speech, physical keyboard or Braille +acceptance, or behavior of the installed reader. diff --git a/docs/testing/speech-preferences.md b/docs/testing/speech-preferences.md new file mode 100644 index 0000000..0d5abaf --- /dev/null +++ b/docs/testing/speech-preferences.md @@ -0,0 +1,43 @@ +# Direct speech preferences controls + +Rate, pitch and volume are always editable. There are no separate server-default +or inherited-voice checkboxes and no restore button. An untouched field preserves +its existing explicit value or inheritance. Changing a field makes it explicit, +even if it is subsequently moved back to its initial value. Uppercase retains +automatic pitch until its pitch slider is changed. + +The preferences worker queries Speech Dispatcher over a separate connection, +with a 500 ms overall deadline. Unsupported, invalid or unavailable values use +display defaults of rate 50, pitch 5 and volume 5. Server values are converted +to the reader's existing scales, rounded to one decimal place and constrained +by the sliders' existing ranges. Hardware speech uses the display defaults. +Merely opening preferences or applying unrelated changes does not save these +display values as speech overrides. + +Build an isolated binary and run the focused checks: + +```sh +go build -o /tmp/cthulhu-speech-preferences ./cmd/cthulhu +go test ./internal/preferences ./internal/speech ./internal/config ./internal/app -count=1 +CTHULHU_BINARY=/tmp/cthulhu-speech-preferences CTHULHU_PREFS_NO_CONFIG_ONLY=1 /usr/bin/python3 tests/native_preferences.py +CTHULHU_BINARY=/tmp/cthulhu-speech-preferences CTHULHU_PREFS_NO_CONFIG_ONLY=1 CTHULHU_PREFS_DEFAULTS_UNSUPPORTED=1 /usr/bin/python3 tests/native_preferences.py +CTHULHU_BINARY=/tmp/cthulhu-speech-preferences CTHULHU_PREFS_VOICE_TYPES_ONLY=1 /usr/bin/python3 tests/native_preferences.py +CTHULHU_BINARY=/tmp/cthulhu-speech-preferences CTHULHU_PREFS_NUMBERS_ONLY=1 /usr/bin/python3 tests/native_preferences.py +CTHULHU_BINARY=/tmp/cthulhu-speech-preferences /usr/bin/python3 tests/native_preferences.py +``` + +The missing-file checks use the real reader, GTK preferences and a private SSIP +server, isolated under Xvfb and D-Bus. They verify initial values with no settings +file, direct keyboard edits, Tab and Shift+Tab, untouched inheritance, automatic +Uppercase pitch, preview settings reaching SSIP, Apply creating the file, +saved values after reopening, and Cancel discarding unsaved changes. Test logs, +configuration and speech recordings remain in the reported temporary directory. + +Human acceptance remains separate: with the rebuilt reader, use a temporary +configuration and physically adjust all three sliders, listen to their previews, +Apply and reopen, then change a value and Cancel. Check the Default, Uppercase, +Hyperlink and System voices independently; confirm capital pitch still works, +ordinary speech returns to its normal pitch, and Tab/Shift+Tab retain sensible +labels and values. Check Braille if used. These checks also cover existing +profiles with explicit values; the automated harness does not establish audible +speech, physical input or physical Braille acceptance. diff --git a/docs/testing/speech-queue.md b/docs/testing/speech-queue.md new file mode 100644 index 0000000..47db8bc --- /dev/null +++ b/docs/testing/speech-queue.md @@ -0,0 +1,112 @@ +# Speech queue verification + +Ordinary output always appends. Cancellation belongs to configured interruption keys, +reader command dispatch and explicit stop requests. An announcement arriving +later from the same action must let earlier speech finish. This includes focus, +selection, state, notification and delayed review output. Accepted Tentacle +speech follows the same rule when its originating focus/session retires; +admission still rejects stale replies and Braille retains its own ownership. +External `SpeakText` announcements also queue regardless of their interrupt +flag; `CancelSpeech` remains an explicit stop request. + +Run: + +```sh +go test ./internal/app ./internal/input ./internal/speech -count=1 +python3 tests/check_speech.py +go build -o /tmp/cthulhu-radio-sound ./cmd/cthulhu +CTHULHU_BINARY=/tmp/cthulhu-radio-sound CTHULHU_PREFS_RADIO_RUNTIME_ONLY=1 /usr/bin/python3 tests/native_preferences.py +``` + +The required radio-selection test sends Laptop focus and checked-state events +through the event loop and speech worker, with a controlled backend that fails +on an unexpected cancellation. Existing tests cover the cancellation barrier, +Say All, key echo voice ordering, initiating-key timestamps, title repeats, +screen lock, internal UI and Tentacle output. These checks establish software +ordering, without proving audible completion or physical input on a Pi. + +The private GTK radio test drives Right/Left between Desktop and Laptop. It +requires one selected sound per move, with the label retained. It uses private +Xvfb, D-Bus and a fake speech server; GStreamer auto audio is restricted to the +fake audio sink in the child reader. It never uses the desktop speech server or +audio devices. Debug sound records identify playback attempts, not audible +output. GStreamer's Python bindings and `fakeaudiosink` are required. + +Unchecked radio focus sounds wait up to 250 milliseconds for a following +checked event. That event replaces the pending sound immediately. Speech and +Braille remain immediate, and a radio that stays unchecked gets its original +unchecked cue. Fresh input, changed focus/window, lock and handoff retire the +pending cue. Native state-only snapshots retain the owned mnemonic so a +repeated focus event does not replay the selected sound and label. + +Before submission, review the diff and rebuild the reader. Restart the active +reader only with the user's authorization. Then listen on the target desktop +and Pi: + +1. In keyboard preferences, change Desktop to Laptop, release the key and wait. + Laptop should finish, followed by the role/state announcements. Repeat in + the other direction and test radio buttons, checkboxes and combo boxes. +2. With All keys interrupt selected, during a long announcement, press Control. + Repeat with typing, an arrow, + Tab and a reader command. Old speech and its queued feedback should stop; + the new action should speak normally. Releasing keys should leave speech + alone. Test rapid presses and held arrows, including automatic titles. +3. Leave a long announcement playing while a notification or terminal output + arrives. Both should finish in order. Repeat during Say All, then stop it + with a fresh key and check that the reading position has stopped advancing. +4. With a custom echo voice, press Right in an entry. The key name should finish + before the caret character. A new key should still stop stale feedback. +5. Exercise browser navigation, Where Am I, action/list dialogs and preferences + Apply. Check that each fresh command responds promptly and delayed results + preserve announcements from the same action. Check Braille focus/state and + confirmation restoration separately. + +Screen lock still clears speech for privacy. Disabling speech, replacing its +configuration/backend and shutdown retain their existing behavior. Protected +Tentacle messages retain their explicit timeout and cancellation rules. The +bounded queue can discard pending requests on overflow and logs that loss. + +## Interruption preferences + +Build a separate binary and exercise the recorder on a private display: + +```sh +go build -o /tmp/cthulhu-interruption-test ./cmd/cthulhu +CTHULHU_BINARY=/tmp/cthulhu-interruption-test CTHULHU_PREFS_INTERRUPTION_ONLY=1 /usr/bin/python3 tests/native_preferences.py +CTHULHU_BINARY=/tmp/cthulhu-interruption-test CTHULHU_PREFS_INTERRUPTION_RUNTIME_ONLY=1 /usr/bin/python3 tests/native_preferences.py +``` + +This checks all three choices, Tab and Shift+Tab around the new controls, +recording Tab/Enter/Space/Escape and separate modifiers, duplicate suppression, +Control+Enter finish, Control+Escape cancellation, replacement, empty-recording +rejection, Apply and reloading the accepted draft. Direct XTest modifier input +avoids extra Control presses synthesized by xdotool. Config tests separately +check disk persistence and application profiles. Application tests apply the +preference to the live settings and check that unselected keys preserve both +queued speech and Say All, while selected keys and reader commands cancel them. +The runtime check starts a private reader and fake speech server. It verifies +that the read-only summary's contents are spoken on focus and characters are +spoken while moving with Left and Right. The generic native text-label test +also covers read-only entries and keeps password contents excluded. + +After reviewing the diff and authorizing a reader replacement, verify audibly: + +1. Select All keys interrupt and Apply. During long speech, press a letter, + Tab, an arrow, Shift and Control separately; each should stop old speech. +2. Select Control, Enter, Space, and Escape and Apply. Letters, arrows, Tab and + Shift should let speech continue. Both Control keys, both Enter keys, Space + and Escape should stop it. Repeat during Say All. +3. Select Define interruption keys. Record Tab, Enter, Escape and Right Control, + finishing with Control+Enter. Confirm Left Control was not added. Check the + result field, Apply, close, reopen and confirm the list persists. Test each + chosen key during long speech and confirm unchosen keys let it continue. +4. Record a different list and cancel with Control+Escape; the previous list + should remain. Cancel the whole Preferences window and confirm unapplied + changes do not alter runtime behavior. +5. Tab and Shift+Tab through the interruption group, recorder button, defined + keys and speech history. Check spoken instructions and Braille in recording, + normal typing/key echo, browser navigation, reader commands, automatic title + repeats, and selected/unselected held keys after applying each mode. + +The private checks do not establish live speech, physical keyboard, physical +Braille or Wayland compositor acceptance. diff --git a/docs/testing/terminal-scrollback.md b/docs/testing/terminal-scrollback.md new file mode 100644 index 0000000..0e7b18b --- /dev/null +++ b/docs/testing/terminal-scrollback.md @@ -0,0 +1,38 @@ +# Terminal scrollback deletion feedback + +VTE reports old lines leaving its accessible text as deletions at offset zero. +Speaking those deletions replays previous prompts and command output while new +output arrives. This was reproduced with a real shell and reader on private X11; +the same event pattern appeared in the reported Wayland log. + +The shared event policy suppresses only terminal deletions at offset zero when +the native caret is known, the original removed text ends with a newline, and +its positive code-point length does not extend past the current line start. +Other deletions retain the existing redraw coalescing and editing feedback. +Speech normalization stays unchanged; numeric length and line-ending metadata +are retained separately because normalized payloads lose that information. + +Build and run the focused native regression: + +```sh +go build -o /tmp/cthulhu-terminal-check ./cmd/cthulhu +CTHULHU_BINARY=/tmp/cthulhu-terminal-check /usr/bin/python3 tests/native_terminal.py +``` + +It requires GTK3, VTE 2.91, Python GI/pyatspi, Xvfb, i3 and xdotool. It uses a +private display, D-Bus session, configuration, shell home and recorded SSIP +server; it does not replace the running reader. A small terminal with zero +scrollback reaches the scrolling condition quickly. The test checks that 16 +command outputs reach SSIP without old prompt deletions, then exercises +Backspace, Delete, Ctrl+W, character navigation, history and current-line flat +review. It prints the evidence directory containing reader logs and speech +records. Run private X11 display tests sequentially to avoid xvfb-run display +allocation collisions. + +Human acceptance still requires listening in LXTerminal on both X11 and +Wayland. Fill the terminal until output scrolls, run short and multiline +commands, and confirm previous prompts and output are not replayed. Edit at +the beginning, middle and end of a command with Backspace, Delete and Ctrl+W; +use arrows, history and flat review. Check fresh-terminal and cleared-screen +behavior as well. Physical keyboard, audible speech and Braille acceptance +are separate from recorded SSIP and synthetic input. diff --git a/docs/testing/text-control-labels.md b/docs/testing/text-control-labels.md new file mode 100644 index 0000000..501c0c3 --- /dev/null +++ b/docs/testing/text-control-labels.md @@ -0,0 +1,32 @@ +# Native text-control labels + +Unnamed text controls can expose their labels through AT-SPI `LABELLED_BY` +relationships. Cthulhu uses those labels for text, entry and password-text +snapshots when the control has no accessible name. An existing name takes +precedence. The lookup follows only explicit targets, with a maximum of 16 +targets and 4096 bytes; it does not guess from neighboring widgets or use +the field's value as its label. + +Run the native GTK and presentation regression in a private display and bus: + +```sh +python3 tests/native_test_session.py env CTHULHU_NATIVE_TEXT_LABELS=1 go test ./internal/presentation -run '^TestNativeTextLabelRelations$' -count=1 -timeout=40s -v +go test ./internal/atspi ./internal/presentation ./internal/braille +env CTHULHU_SPEECH_METADATA=1 python3 tests/native_atspi.py +``` + +The native regression covers empty and populated entries with mnemonic labels, +an explicit accessible name differing from its visible label, a password field, +an unlabeled entry beside unrelated labels, and multiple relationship targets. +It checks the captured names and resulting focus speech text. It does not +establish audible speech or physical Braille acceptance. + +For live verification with a rebuilt reader, open I38's Create Desktop Shortcut +dialog. Tab and Shift+Tab through Target and Shortcut name while empty, then +populate both fields and repeat. Each focus announcement should include its +label and current value. Confirm editing and caret navigation still read field +contents normally. Check an explicitly named search field in the application +picker, plus ordinary labeled entries and password fields in another GTK +application. Password contents must remain private. If using Braille, confirm +labels appear and routing still reaches the editable text. Review and test +these changes before submission. diff --git a/docs/testing/thunderbird-workflows.md b/docs/testing/thunderbird-workflows.md new file mode 100644 index 0000000..e0c7e77 --- /dev/null +++ b/docs/testing/thunderbird-workflows.md @@ -0,0 +1,168 @@ +# Thunderbird local mail and composition + +This slice covers a synthetic local mailbox, folder/message-list navigation, +opening and returning from a message tab, unsent HTML and plain-text +composition, replies/reply-all, inline forwarding, attachment saving/adding, +and multiple message selection. The separate +[Mozilla reading baseline](mozilla-reading.md) covers Firefox pages and saved +Thunderbird messages. Page-load summaries and automatic Read All remain +separate feature work. + +## Changes and boundaries + +Thunderbird can register a GTK accessibility application before replacing it +with its Gecko application while keeping the same X11 client. Previously the +reader could retain the GTK frame and reject real folder/message focus events. +Foreground ownership now accepts a replacement only after fresh active/showing +state, process and geometry checks, and bounded window enumeration. The +candidate's parent application must still be registered on the accessibility +desktop; its current window list must include the candidate and exclude the old +owner. Existing same-process siblings cannot take ownership. Retained focus and +document references belonging to the retired frame are released on the native +owner thread. Unknown or incomplete queries reject replacement. + +The composer keeps native focus on its editable web document while paragraphs +emit text, caret and selection events. Previously those insertions were rejected +as outside the focused editor; subsequent caret events spoke the growing line, +and selection feedback was missing. Native capture now copies the nearest +editable-document identity. Paragraph events belong to that document only while +it owns focus. They use ordinary typing, deletion, selection, clipboard and +Braille presentation. Focus stays on the editor, while the current paragraph +provides text and cursor/routing metadata. Moving to Subject or another editor +revokes the relationship immediately. A nested read-only document is a boundary. + +These are shared AT-SPI and event ownership changes. No Thunderbird-specific +application-name, window-title or widget-label matching selects production +behavior. Orca's Thunderbird editable-message handling and shared web/focus +utilities were used as behavioral references. + +Automatic title changes no longer repeat the focused editor's text during +typing, deletion or clipboard edits when the rest of the title stays the same. +This uses owned editable focus and recent input, with matching title prefix and +suffix. Both AT-SPI and X11 title sources use the same check. Window introductions, +unrelated status changes, empty values and ambiguous matches keep their existing +behavior. There is no application-name or Subject-label exception. The new +recorded-speech assertion reproduced the title echo on the pre-fix reader. + +## Automated checks + +```sh +go build -o /tmp/cthulhu-mozilla-review ./cmd/cthulhu +CTHULHU_BINARY=/tmp/cthulhu-mozilla-review /usr/bin/python3 tests/native_thunderbird.py +``` + +The harness requires Thunderbird, i3, Xvfb, xdotool, D-Bus and Python with +pyatspi. It starts a private reader before Thunderbird, with its own display, +session/accessibility buses, SSIP recorder, profile and configuration. It seeds +Inbox and Archive mbox files, a synthetic local identity, a Cc recipient and a +plain-text MIME attachment. No mail credentials or SMTP server are configured +and no send command is used. Pass `--format html` +or `--format plain` to select one run. + +Each run checks native focus and recorded speech for: + +- Folder Home/End and Down navigation, including returning to Inbox. +- F6/Shift+F6 between the folder tree and message list, retaining the row. +- Up/Down through messages, with native selection and spoken row roles. +- Shift+Down/Shift+Up to extend/shrink message selection; Ctrl+Down to move + without extending it; Ctrl+Space to add/remove the focused message. Native + selected rows must match at each step, and state changes must speak. +- Enter to open the selected message in a tab, Ctrl+Home to read its body, + Ctrl+W to return to the selected row, and Down to the following message. +- Tab from the message body to its attachment bar, Enter to expand the list, + and Shift+F10/Down through Open and Save As. Save the received attachment + into the evidence directory and verify its contents, then return to the + selected message row. +- Ctrl+R/Ctrl+Shift+R/Ctrl+L for reply, reply-all and inline forward, with + expected Subject and quoted body. Replies retain the sender address chip; + reply-all also retains Cc. Forwarding includes recipient entry and Tab to + the body. Type into each body, close it, focus Discard changes and confirm + return to the selected message. These messages are never sent. +- Ctrl+M, recipient typing and committing its address chip, then Subject. +- Subject character echo and Backspace without repeated composer titles. +- Tab from Subject to the editable body; H reaches the editor as typed text. +- Character echo and Backspace, two-line body input, Ctrl+Home/Down reading, + selected-word speech and native text selection, and deletion of that word. +- Shift+Tab/Tab between the body and Subject. +- Ctrl+Shift+A to open the file picker, attach a generated local file, check + the selected attachment row and its speech, Escape to clear selection, and + a second Escape back to the body. + +Initial message-list focus need not select the first row: Thunderbird can expose +a focused but unselected row until a navigation key selects it. The harness +requires selection after Up/Down, rather than treating initial focus as selection. +The parent document can expose a selection as embedded-object placeholders; the +native selection assertion checks the selected paragraph text instead. +The harness ignores hidden duplicate controls in retained tabs and inspects +both Thunderbird accessibility applications and the GTK desktop portal's file +dialogs. Attachment row names can separate the filename and extension with a +space; their descriptions retain the complete filename. File-picker paths and +saved content are checked separately from recorded speech. + +Printed evidence directories retain the profile, mailbox fixtures, settings, +reader/application/session logs, `tree.json`, `speech.json` and `report.json`. +Successful HTML and plain-text runs were verified with Thunderbird 158.0, +with 60 workflow checks in each format. +The tests disable Braille; the event-loop tests separately check paragraph +Braille cursor and routing metadata. + +Run the shared regression checks as well: + +```sh +go test -race ./internal/atspi ./internal/app ./internal/review ./internal/presentation -count=1 -timeout=120s +go vet ./internal/atspi ./internal/app ./internal/review ./internal/presentation +python3 tests/native_firefox.py +python3 tests/check_speech.py +CTHULHU_BINARY=/tmp/cthulhu-mozilla-review /usr/bin/python3 tests/native_mozilla.py +CTHULHU_BINARY=/tmp/cthulhu-mozilla-review /usr/bin/python3 tests/native_ownership.py +CTHULHU_NATIVE_BROWSER_TESTS=editing,selection,modes python3 tests/native_browser.py +``` + +These cover Firefox tabs/address focus and native metadata, Firefox/Thunderbird +reading and Read All, GTK/Qt controls and dialogs, same-process overlapping window +ownership, workspace return, and Chromium editing/selection/focus modes. Passing +the new tests alone does not establish that these existing behaviors still work. + +## Human review and live acceptance + +Review the diff and test the rebuilt reader before submission, under the +[contribution policy](../../CONTRIBUTING.md#ai-assisted-contributions). Recorded +SSIP and synthetic X11 input establish requested behavior, not audible speech, +physical input, a physical Braille display or native Wayland acceptance. + +1. Start Thunderbird with the rebuilt reader already running. In a test mailbox, + use arrows, Home/End, expansion/collapse, F6 and Shift+F6 across folders and + message rows. Check sender, subject, unread/read state and selected rows. +2. Open a message, read its headers and body, return to the list and switch + folders. Check that focus and reading position belong to the current message. +3. Create an unsent HTML message. Type and commit a recipient, Tab to Subject, + and type slowly, pause, then use Backspace and paste text. Confirm ordinary + echo without repeated composer titles. Clear Subject completely; the empty + subject title can still announce. Tab to the body and confirm line/word + movement, selection, Backspace/Delete, cut/paste, and header/body return with + Tab/Shift+Tab. Repeat in plain text. Check speech and Braille text, selection, + cursor and routing. +4. Select several messages with Shift+arrows, move without changing selection + with Ctrl+arrows, and toggle rows with Ctrl+Space. Check announced selection + state and matching Braille, then return to single selection and open a + message. Try a larger folder and nonadjacent selections in a test mailbox. +5. Reply, reply-all and forward a test message without sending it. Verify + recipients, Cc, Subject, quoted content and ordinary body editing. Close the + composer, inspect the save/discard/cancel prompt, cancel once to return to + editing, then discard and verify the original selected message. +6. Tab to a received attachment, expand its list, inspect the context menu, + and save a harmless test file to a chosen directory. Verify the saved file. + Add a local file to an unsent message with Ctrl+Shift+A, check its filename + and selection, then Escape to clear selection and Escape again to return + to editing. Also check removal, multiple + attachments and other file types; those exceed the automated fixture. +7. Move from the body to Subject, another window or another message. Old + body activity must not interrupt the newly focused control. Switch between + multiple Thunderbird windows and ordinary Firefox and Chromium windows. +8. Recheck Firefox tab creation/switch/close and address editing; Chromium + editing and selection; GTK/Qt menus and dialogs; and empty-workspace return. + +Remote accounts, sending, forwarding as an attached message, external attachment +opening, attachment removal, larger/nonadjacent selections, real mailbox +performance and physical speech/Braille remain outside this automated local +baseline. Page-load summaries and automatic Read All remain separate features. diff --git a/docs/wine-accessibility.md b/docs/wine-accessibility.md deleted file mode 100644 index 0cd2808..0000000 --- a/docs/wine-accessibility.md +++ /dev/null @@ -1,53 +0,0 @@ -# Wine Accessibility - -Cthulhu's Wine integration has three components: - -1. `WineAccessibility`, a built-in plugin which discovers same-user Wine and Proton prefixes. -2. `cthulhu-wine-access.exe`, a Wine-hosted helper built with Winegcc. -3. The `org.stormux.Cthulhu1.Service` D-Bus interface used by the helper and Prism. - -The manager starts one helper per prefix, uses `WINEPREFIX` or -`STEAM_COMPAT_DATA_PATH/pfx`, and passes the prefix's own loader through `WINELOADER`. Discovery -requires an actual Wine loader process, so exported prefix variables and idle `wineserver` -processes do not keep helpers alive. A helper is stopped after its prefix has been idle for ten seconds. Repeated early exits use exponential -restart backoff. If an actual NVDA window already exists in the prefix, the helper yields the -controller endpoint to it while continuing to provide standard-dialog reading. - -## Controller Compatibility - -The helper registers the current `NvdaCtlr..` local RPC endpoint, the legacy -`NvdaCtlr` endpoint used by older official controller clients, and the Controller 1, 2, and 3 -interface UUIDs. It also creates the `wxWindowClassNR` / `NVDA` window used -by official Tolk releases for detection. The compatibility window is explicitly hidden, -nonactivating, and excluded from ordinary window switching. Therefore applications can keep the original -`nvdaControllerClient32.dll`, `nvdaControllerClient64.dll`, and `Tolk.dll`; no DLL override is -required. - -Plain speech queues like NVDA Controller output; Tolk's interrupt flag uses the separate cancel call -before speaking. Braille, cancel, and process ID calls are also implemented. Speaking-state queries return -`ERROR_CALL_NOT_IMPLEMENTED`, because Cthulhu's current speech backend does not expose an accurate -answer. SSML is validated by Cthulhu and currently fails with `ERROR_NOT_SUPPORTED`. This is -intentional: accepting SSML while dropping mark callbacks or reporting completion too early would -violate the Controller 2 contract. - -The current Meson target builds the 64-bit helper. A 32-bit helper requires a 32-bit Winegcc and -32-bit GLib/GIO development environment and should be shipped by multilib packaging. - -## Standard Dialog Reading - -The first reader stage listens for MSAA focus, name, value, state, and selection events. When Wine's -MSAA proxy has no useful data for a standard control, the helper falls back to the control's Win32 -class and message protocol. Combo boxes, list boxes, edits, buttons, sliders, and static controls can -therefore expose useful names, roles, values, and states without replacing the MSAA path for controls -which already read correctly. - -This class-based fallback is adapted from the LGPL `wine-a11y` reader published by Mudb0y. - -The reader does not expose custom-drawn, DirectX, or game-specific interfaces. UI Automation coverage -and an AT-SPI object broker remain separate later stages. - -## Prism - -Prism has a distinct `Cthulhu` backend ID. Native applications call Cthulhu's D-Bus service -directly. Wine builds use Prism's Winelib D-Bus bridge. This backend supports speech, braille, -combined output, and cancellation without claiming to be Orca. diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..45dad23 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module git.stormux.org/storm/cthulhu + +go 1.24.0 + +require github.com/pelletier/go-toml/v2 v2.4.3 + +require github.com/godbus/dbus/v5 v5.1.0 + +require github.com/gorilla/websocket v1.5.3 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6bfd03e --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY= +github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= diff --git a/hooks/pre-push b/hooks/pre-push new file mode 100755 index 0000000..18e533a --- /dev/null +++ b/hooks/pre-push @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +set -euo pipefail + +repoRoot=$(git rev-parse --show-toplevel) +exec python3 "$repoRoot/tests/check_speech.py" --pre-push "$@" diff --git a/icons/AUTHORS b/icons/AUTHORS deleted file mode 100644 index 6412486..0000000 --- a/icons/AUTHORS +++ /dev/null @@ -1,9 +0,0 @@ -Cthulhu icon created by Stephen Brandt. -stephen@stephenbrandt.com -http://www.stephenbrandt.com/ - -This artwork is available under the terms of the GNU Lesser General Public License. -http://www.gnu.org/licenses/lgpl.html - -This icon follows the Tango visual guidelines. -http://tango-project.org/ \ No newline at end of file diff --git a/icons/COPYING b/icons/COPYING deleted file mode 100644 index 5faba9d..0000000 --- a/icons/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/icons/cthulhu-16x16.png b/icons/cthulhu-16x16.png deleted file mode 100644 index 8bc4aba60abce5bad27bb7835e81253b1c8d486c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 685 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7*pj^6T^Rm@;DWu&Co?cG za29w(7BevLUI$@DCym(^3=9nHC7!;n?AO^PIi;lwVyaIwFfdtpx;TbdoSr+$(IdD} z=D2&-MiXE8+ z1p!}w|J||9duPls6W_A3GO33AquS!Wv7aJQJ`>tBGY2QA-r9lhBR&U(B+uPfl zd)Bh6lTW6cE1aW!;Gd!cgPd#NJ$0c@GtH&ybNzzXh8g-!F0txOlz8&F(!@8o>EMF> z0U9+7UF{6~0=+Iu(+@w~aN~}Sp^3?nZ{N&j`m`18?8&{IlbbuyYbgg?vsS_L7hG}) z4%bWPCrW&Id41;G*~yuioVT}0%F3!vKRxkW%8NH|R0KFG`s6PyUiHc&JA3tsw9PhE z63aJiY+U#HNRr{TYuA44_`~`3PGwcq?+HOn8T%P$&7OVRYpIYP*XQ+dn?F30t*-v9 zqo?=Cg75qLyQxpUt-W=1UR;X+LpuMbkK757VOL!rp1iEGEOXPYT}}!Tn|Kf3&=Bj^ zfA#g(80 pPuXQOpB5{esekq8KASzG%ZzigGTv=`z`(%3;OXk;vd$@?2>?JoI2Zr` diff --git a/icons/cthulhu-22x22.png b/icons/cthulhu-22x22.png deleted file mode 100644 index bb5dc5252b5d7d9ff5862d363abcdb59f3df7a63..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1082 zcmeAS@N?(olHy`uVBq!ia0y~yU=Rag4mJh`h9g^YtQi;>*pj^6T^Rm@;DWu&Co?cG za29w(7BevLUI$@DCym(^3=9nHC7!;n?AO^PIVH{5x4POeFfbqYba4!^IK6agU`}wT z#PRy&-?weoovod#zAai?m}N8Pwk5XZ+v#Ywgk9w;R11j#MA;G}zbYo2y%T4sKEb$)cb)-}h#JYX2j9 z!R-w9OG--iNN}*^WM5y$>cHV>HaoSbXwt1)QP#fb_xYxT33-c_?mqwA+RVl#$6H0{ z(XFl7OM)~*LRDv4&FJNKvo&!?X@KWpY$m%lSGHFaGWu!Da~)Y><~<%%G>9f%ou%yzRj{Vy;?Kt$3G&eOr3-VL?gm%}uU+ ztxhXeRmDfDO;(iPS@inX{b&)U?YDUk+_@tYw?3R{m)x}vZ{NOsd$hvl+@(uGb^ojQ zQfhY#O++dFNVShk9g zV`%8S?7YN`7Y3g{f9B!gdGN8qqWqoA#TV;MeqCQI&NauTvdg)hFKP4501?&)FWE&- zZ`zZ6cUS4M1cMVxy{B{hvpM|mq4J!cg-shb=I^ZfswLOo?mK(l((L1}=UCJ+P2WB5 z;>PzMe*di(tdqQnlHsoMy{`WcD9lRRuu%aUm^ zdgAi+TmIWD$jz;Nc(reOd?1gl{+YDTY_Zqp9=O}JTfn^R{k^@FhmZBXc~LdF=>W1 z6bMv^XE3Zu<^IEL!7RgGxAIfg{Gy#P7j3J*-4JzM7@{TE>Cz=EEPS%W>hGmje=n!} zQWW5L!Okb6VJXvBQ(XLc($%c9r#H=E*%zVvURbQ#Ra!CvB?VQ3e1_lNOPgg&ebxsLQ05(hfQ~&?~ diff --git a/icons/cthulhu-24x24.png b/icons/cthulhu-24x24.png deleted file mode 100644 index a015b1d00a95ea82d26b58dbdb0efd1cdfacb989..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1095 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuJo*pj^6T^Rm@;DWu&Co?cG za29w(7BevLUI$@DCym(^3=9nHC7!;n?AO^PIoWwce=H7UU|_!D>EamTas2GGc%SG{ zndA1$zh8>x^2qGI;Ut)n$989eivVw@Vcx+bJw8G`{ExUf4>F{!*mL69?S_T=Qj6EK z+>MD4lRxq3(BVlZ#s0aTYX0-up)H8TYkS*;=)Cv2uf5F+`xf@O_9B;D1Fb!+Xz3Uzk5=7qC|p+sn*u@Sp3KzGK-kwM#c{NSMz)tGJ-Xe$H~H@KdKx zAJ)~??Rq&T&wi5FHvib>8gR*_`c%d;0s^O?|7?f4cnF zaNzt9nwt9b^VY3fS4KugGH@tzv>)c-<()WjqGMFlEQUN=9p{e?yQdvGbjUv{I(q7x zH#r-3>^O1jmej6w$r5aQ>VCug@wT-fxw{+kJoZ1fpxRV5V~`aX5n)~&7AU%OuaYM;Q}c=;tuLS?1o_S?FQS9hE8I=H&Jy54#Jee=$p zo^^GM%l+!l+_)jZ&CSiBI6h~6GT`TKrtf5iUb$679`{9G_@^kjEWw?9Iuip9T=yVb1{;nxgrYOZ;e|zBV{wXU3lD4f|_b%XKBeTrv zy14-_%wE4{eD*Bu@pQd!`TsYSyyh!l-NCtpIlUqGK|od2uijt3s*ayIYXMgSM>uWii)-5J3o*$(%ZH3Nh#s{0-m%clGCT;Vzd-vvP=<4=* zOe*24VBPTcx=VG~v{c_oOFC3M=QjMj@278>x#o^~+T@d4R9Y%tzrVEA!^-=n;wL`O zn-^!e1@$p3KDn3AWwKS-^nFL=IF9I9ZEXH8{Qu?k$K`>)$}^qSZr@~JU|{fc^>bP0 Hl+XkK|2hSa diff --git a/icons/cthulhu-256x256.png b/icons/cthulhu-256x256.png deleted file mode 100644 index c736f1158cc15de501a3b9c5333b0af0a34a6974..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30247 zcmeAS@N?(olHy`uVBq!ia0y~yU}OMc4mJh`hM1xiX$%YuY)RhkE)4%caKYZ?lNlHo zI14-?iy0VruY)k7lg8`{1_lQ95>H=O_B(9C3{r|S8YV7aU{GN2ba4!+xb`z`k-IqgvV}ipbo!vU|5mu)UN$_{grJa9Mxlf#d_X8%m`Z-|w^$tl(wjJn`kE z)`QIlT2C@;a9b=WEF^T~%o(4;=jY}o6%>4kIQL(!_)eeL21b^Ybzi>lGi+y+e7v{A zZ@IFa-Mk$;ERvFwJ9~Rom6Vtq3le^Od3l+Km$&y@(fz`pdcy?_OhOY*PEU9s_JG+U zCOdi4mDN|X%x^q?{J68fU){(k=;M#?_p19hZQ67(<`&x@;}82kKU8EFad1eR{lwC- zUR=OX?0~wO+N3#ie7wB4Iy*a8TzwTdH##cn)XmN5?!_wv+qeF|Qd4;Y6g)Q-tkgHy zwH~&&*Xr!(NO*Z^>5`>OC(fDE<7HY_UKboJyngSuTN!-1Y<^5jKfgQ(wk2p%<9UYf zj|(36YIu5ju8G*#v}KEllCrYk(U1HGtE;OmOJ9kY&CXroT+d{~#B+YTxIh2{<4n%T zcW>UxGdQ_fS!ii>U0of%x$0|{m~PaQdv<~!zJLGz`I5K3p@qeZ_Xgd;j(^YB)Cz*! z_i{?k1MUNbZU(PbUd;+y6X6&ZCg$nsIq9!3^=e3X z_~k2Cj@;UseRFeq|C^o8&d!S&|Ccu&pZlf$o_7NyONv&?%E_?&iBs`V(0Dqy& z2TiYt2#M%zIf-XynZCPGt-3L4?UX4~0s;aal(4I_IZW-gUWiX}U}Q&1_ba3&=uryh(C2|05A-#2sB>4~xh zEE+s}jx{iGoVam>;g9$S!=>96U(C3%A(7eA((=XEUxJPQ?^VAKjEU*FYiA`UCnR*} zcp?ioJI0`E8YEr0yuwK4gdt2|<*Vlh#v_? zx}Uc_I3(nV_4_@CKYVy1at>7dYHNEl{ad$A@7x^A#U)YP1rqKX&hMF6I@|0hw^+~{ zsf(u$9Ju=EQBtu3>$cv`2`6>4X1)?F|vC zr$D*2sJK|P`tQ4Ud2zL0LubuaH?OVx{q60f#J0P6&-Lqna)+%BeJ3JVF`@F&^Ygd1 zXtK`!p;5qYR>-LpaJ%urgokVH{3&M@y{~Ce{_bffPcai$!ZR1vB@aF3#x^eYx#pE1 zDe#hIZyD2dd4^YoB3oCmbv3NE=!&}bXvMkD_q~#98JZ6sn5gW2=i#=Z2l^Ts57utK z7sT{rN9xH*sycCdB0kLyUl;Q+J>ZXBL6zN>-ZOXp_$LYPe--j$-y-(1?y|DkIdb!hejL@oq1gRPi}7R9IMi-J9d93 zswgTtGSxMFet!PM=LsD># z?FCPnkIz;=za@X+_18Nkmwn@2ZrukC68Zl>j%Rpf_D4VAs+Q<=>+0^F>Q~9>F1vr{ z&DZH~xI(4b_G@?Dv7ZzlEQ9Ju0T)i>+gckAQdCOa##G;Y{n@I9t% z-AV1khYoRYb2~4;oM<3%A;V(`GTIKbex_+qzPwuw~Pn;VX0W!rK#@H(WYt1tJPyJ+?5>{IeBYiV^|xDar2R&{pa?a&Y9U5d_VG8r<6J&oXycVm(vRJBMJ|A0va+GYr~CGOht=)V0#}ACS-Ny%-QTKfYa$O{ zTI$`|-R->i;t$pj6^;7eZ8bDH7A#OWboj8RheyKOTU+bar*FTlsj2BGz+z-%l#!Xa zaPQt)ujBs?9z3X`;*q;Fe0^M~)zkM5H)FDVBBjl9k0n*#lP~V+;Yjz6(-VC7kcE|X z;ngfbmV;}j_^Ju3O+Fcz=(%c!Y1q_f!WKpr%v=dfn|LbD+V+c)Lh zG%Dw}7h~ub|DnuSV{(9f#rpNjw`{rcdV9=qjwXkk934YL!<5w2L=&l%Yu7H_wQJV9 zcb(!_zpj1H9uOV9dP>0+);$*DQXy&2zIiyN|J(T@Jx6ZM^~t*vZ8beR-^Il*zF5(C z?{jr&tgYD72djU4__uI(;Swiykpmj3hJCZX$xECr=H%v1KHew$=HA}fp{v6xukM%D zZ-~{e%*f!FeDaCehe#cqfb_xv@z~N`CqFEhswLJ2!Xj^%U7;LCat7mw&hCosm|( z_|&aL}hnSQ}W}-k6l;piu0&V z?tJ$y&&t~R<;$0a-`oB**of}kXW!tj_MvvYxQNJ+Q&Y7gcNVFxUAs0UB;>-CD=OB@ z`1$##-|4=X5wc3`4s*!av{U-O7XR6}G3V@gRTY&ZymhnBs(JtPRTD1l^)=bLt#@wI zfqiT4+zI_x#3D9}$>YF7^L@>MKRzleEARaK?e@*x<@ygFJ``F!Q%2%Un(^DWZ?|mQ zW@KPskhb6)`-9Ve{bFKd3JVLreE%LC80Z)pI(54D#Zad^pR4}<{p+=US=-I7Uj|o!qrGdryv0k(=G*lP>Y`_ESqszkKEI`906!tK$P>MplOJO#iuE zdP@>AGBniv=RG+wQMqg3#(A&Bx?8_}E4y|3_RF_#zXpkL%l_E+J>5X!#HmwBFE1?> z5f$CpTT|5P_Gb!D{w!bK?7zRh3YwK(I4^KCdP?8L*Cjb8PpfJg9^|c=F6-gPSW;3J z7#iPy)#~An?%zd4MRw&MAGw}(3T5y-5d5QaS5fD|ga;QEI?LGC-LZY$WB;JMwDjVI z3l91D?`JgbxzM1$oa58y&o5uRSg>M+$F@})<}X;h@aCl**PcFqe(UX@u!5F$?Vx|U zm6k27tvfaMA5EJ0<;S|Ox7ysIZdw2NyXIyli>&X7{HDkYGEDzA2#6l2Jr`$Rq{3ZN zS7-PAZn^yFX}Xhj%U(upznKH7(ym-_sjvUPqj6V2gZ-uYj=sLM<9)I(N~}V(re6Q* zHp`{t*zw<%Kl?k%_O;HB_}6oF^@&pvub2JF+B)mu!^FrB-}!k0BBR~^H_Ts?Hc@J- z*Pgp+;&$4fE4m6;Hn3LrGr!^2Ght0Q5Gb2=%xcZg1q~vGs5*Y@&vZse`rZa5%^!f5e@6SOjqVI1BTC=d+ z@AF^lRI2}>_vbo>cZGf5o&U;CnKtd%al3DZM#jdfCHFT6ZripkC^*i1wn4-HSgwI+`tazIL_3^COos&WY{&ofjOIS0~yR zHF=(Md;P5QTn?{gUfaKUudp@h>_X@E9pCR&@BMRbU+=!%yJxRjwaRekM>VcLKT{q^ zpHGjEpD+F4L5Gfyudk||U7Vg&0P7pZxOsiYo_gK?n(o18C~;%feD9i=IlHfytA0Gu zxPR;3xx1E${oky_eQ5Hr2@mSO`o0Rh+1k8F+~sSh%$XzOd1R)ykD9QksAx%9ncs@`xE0g>cGh$) z>bRKk<Aj_`)_v(Z|81b>AgBTf6@!Cz>33fZ391U@p{tz zL!@?V_p9HG`m77)J$?|+{YUgqc);B~mB#=7z5jo1Rp{!J)%Q9Uc_b$*hp&&DdoAw% z{jX1E9Q3&Tl)-M=Tjjs!LTY!ptiLWSEc|#YXb_}ZT>q4>*(RCk(D zj_^f)vcuP=WY^8JUe8nz{jqPBP>v}btOMlMPv!wy;ZFyoY zaucoCe^f;mCv!SP2TwM%v#iwa3;I0oUBeYq?QomG;Nax>{5%QzeI*xM|MAq8->)@S z_nY%!lg4ki*;A)ZWsRx2eCP4$zkc4{-Mf`0WJh~=aJ2KwKf7Cgf9a}Kr#{E@7T?&; z{X^k`Z6t5@)or+}{bT=-5!F8=<$*S{Y; z5V-pF>lcZ?YR+FdntmK?`uyB|O};{x5vLnde(auti>uvsJ1+gTUvYNEA#*oJk-V=V z48?^U9~3_5oH!oMtP{PhN5AGF_dBQQ`+D;-GCC$r5{in7IwrHtdfMaX+*jwHii>|Y z^T##T3olDDOr+S@*f{w4m#hG=AC6PrGAk z7HL#ntnvSK|MG3`N?+c;&2`M;-B+?6K6qOE{GZ{azp2l1PKvO6v|sYLe&6j|cYdsU zzU|mCx8RzfqJ70Ho@jRG-`MuGbJ8TCLOr8~^9=tx=ex}N^QT6x{!ih}%GYnptmn?1 zJ7wzB#H~@xjyA>~->2HWe)TG1TaIL6Vq)Cw%a<<)t_+FURnpljZC>>AQ|f)ErJNR7 zEON~EWV{z!ReX4$G}*Ui_qu(S!7nAk6V5-HlH%FuXL;)Wm0MoH*}pl$>gt3R1=|05 zxBGpc)|NnWn~mZaSp7fBMImBh$mf^UEZepLa0{6!;|kJpYf+s^9^G{I3h` z9GsjJeK)RMxpLvYeRcvzjJX@%SJosZDn@V1nfNAtQwpcm+`iAx&rhB?Q`0=$LE;0~ z27U|cS#71C->UO(-CDB8z`$aO#T=iG?&ROkYMh*%@9wKTeH+!u z_4e~)s~+3lE8U-)n=8S?cC%sag9izV7B7DJ=8enZix+O*e0f`^Y3{Lu_mzZof84(R zFKn-2`QPa*E%LfiB4TSUvtGP%N9*>!MM}yM+f44to?FfGZ`ri4EUDRlrum9L*xhV< zw|t6-Sl`ZF?lnc9o)`GoKG!r0)UDaDc4MK#&plHr687t_?CkffUA1*MSitmm*LmnR-tZ~JlUk$daj*>f;`-<{)mF>qqUnlLM?rSp!QdzZH* zO1Im|S#^QDoLpK#!Gu-2s&4%~`iZ-QTkD;sMg6<|yLat6Hs`_oZQ0Y~(zn^Xef?GF z;nziI$sr~)!WYn+OvuA7S z>dIa`D$em}rtE=mt7VH9H!obMC?q7L;uv%A;6WD`mkamr_g~DI!Y$@?$T0r#X@>iM zo?ZXOS@tkgK(#Z8^W(-Z-=qw`dB%S5J*z9x^fhCyV4dEF?_a(J1qL5)u-D#ypjvBd zR{g=7n;)-B+@YfOFHD9tx8~=6@msT`x&O|+eeKQ#x%o5xD6-72kaT>JotsrtxlOBq zy>QCANn5|Y{#pgf?qzRpsb)W2w{m46doN2&)n)EK8=LA)uD^NtGBF|Hz+1U5Hg+m1 zEPLb5U$`*g(izvAR&&?=ULF7c)Lo7m_EwjT3l=EI{aDVvV#S(8d!3_t7Vlg-^@0HN zqPyoVToCBhU3#*t&H)JQ|J9U5FcM#>g4G4@#M+-$IMspS2;Cbkkl6U9 z$SKH6jp=o*$>e=oSAMMCyz$YY#O24XX?*?DZ~xEY_O{&5S`rVLj&IGrzK6%TQDNRo z&POx39{kSp_wrJ*w~xOzBPuHD)J)@amB}4$uC7Jr_mzp$*R zZ*Z{iciSI|yHZvOvS)79@s9N=j{fb@XuDSFP;;yJxqq395>9}}{~{h|uNQvU-YR~s zH%sfonLT^>xfgv<_KeTu>YA6!lfeF=UW4W5imO?6zb^J~NfVVc`S<4ONd}jiq)+M% z(yGebyFYkj7bhRiSSL7r!woHtNj{N|OE>+^HPdXEdSJE2k#F2h2blS7K;w=n#Xr`^ z?R_PxXm-EBUUu)l9M*l$muJso2tVs~{_n?+A0>L-Zr#3pbL(%mzPmL?Vrwpkn@I6i ze}9wwdzuqwTHIhu+YaEBW{Re6_lEato)To#sz*5AR#CJBvQv z`7iy}_0}xu+m9zrk{7Ny+{CJt-pv%zqTEy5d5LlR-7@LzcgtqKNs-a}aGv#n|CD#< zk67GK+icks!^UPH)hp5Kw*F>M%x789P})ZlAP{+?KObrRn@u7gskSktIu4Jb9IID}TDzlW$Gk&*v4j-tcQn zd7g8tPocE2`@{WQ-`@0Ni{=PTn)Ll~w5R8SdNUU$t^>v%$%fs8dj$^$72Ma5!pqSXRtvenW zt4)rK*-^ka*UvpB=FZpWDz^+i5J=m6bMDdSziYkg za zxVx*==F0`=Np36wv9Z3v!IxVa_6zXV6#d`4cyaTzX<|{)(RT}llk+y5yH%$)xs#9I zyDB3?BQP+~#m!AfPEId-zvSr&hmLxkn`?di-rnkqufN`Kl~y{XSJvxx_+4!E%?)+R zX`65I*7-lEURPdP8WdL8+heM2@a=10@NI>_veTEu!k4D$?0ea%Z+Fr3=7JNaPH{2j zO@I0Kf6>QBN1tuf7GCHyVMCx{?K05=iVwWKtS3*JRPkoxag~jKAIvzmYuh%nfX;NL z`OVGESFT^beBpw^bLaUcg}magUcCxfebvR?U07cJedynGn|H?^K1}4|;yQ8mHb;}u z=f0kvM>i%uK63P^p^c3Wcg6YlUwOA)xoW*kRh*^q&zzi|+P@{GUoEC~&YF69`oFTT zpG3=RKX%7&@jq%TTzYUj_acdByJMF=TK;(P&2L_k>v!d;i5@6=F#X3A-6GG32#NXs zzAR6D{wO;$bK#~027hf^y8Hb8~aIY~8x>^2?6?esw#$ zxM>f2mk3M>o^;~ghI9Hq%-5VxyngQPyH4}Jjr9o$4VN~pmiS$@^iAS%vAEjD@*G+R z_t?~)l=c7r<)x;syP86sLt63fV`;x1SFBqev|9UZ*vfUYG+7rMp14ZGI7$43 z@@YrAM1@w}yM6og*6izQrZwdY8SbYT1;)ks#m3&y`_LBWJWhYlHre~4Uh;QODr=xC6W?}+`rsWx}++>){~ zAu%zxqM}XLKOFd6FTun1$^5yH!LrF zmeLn8OcyWuY6ZUr| zXiT%KyE}4AhG1r9=9BzW(&kU6zy5jq_HB*zI)}5q9$w*EXDyTS^Mknj-$z?~9X46n z+e=xSpNRMvKWjs*W6F(kyT+Fx3``$PJeHdhd3SG{JZaLJ3ZI-D9ru2Vq@S@{>K09jZ*jN#y?*}hizWZ# z*Y?_S1jVd!x!oe#pwXdqe_y$k=mF*fzFyY+@^)w1c%@Y)Chy(5HzXvaM|)NNLe`Hv z*1VanAHQtt)~P%7W=6i=@%5VUi!Zx4qko=FGp_wxJ7rqz()H&pR%`6{H{ThV79D-? zC--yphmY7go94Q``k%XW?#h)b@04DTog`7e`KC``;Kh!2`&u&|1b^y|-%;SW&f?e{ zp{-G8&mQlev|rQzqr_aleBQ{sPowMxEqiO=BC61NZLdf=(xmHFn| z3FZEZtDlNZ-%Oe$RNmlqVAFg1fMXdZMgRU(`utO$HRr34tnAUd-|u*Sve4YG{v&q& zRnyQq&HY!io_>1T6#w_%cKv(ShwI~254mant4v=ces4pf^BUh}VuwmJ8Xh0W^|H?2 z`!#Hue!L!|Pi^hr8P8rspV<8B%h#`Gxj&?*rWbvBqPuw6pLH(tIs^WlJEvFo_w@6O zoSa(^wgjJ@aWUoZudm&2Hch^JgIm2SclUz38rjJ+AN?2MtMSi#-X*GSQTArWl0<$U zo}Q{Z`!6iN{Oa}V$9HxX7hk$$A3EiJj@ji~*SwB$O!@ESsHnf^gV3@>VT&~JTZdG> zY_d|GMpeV9p<%nUgW;cCGaX%?0&p^V-!s3~sG8`l`HU34`k6 zy?GJ;A1pp`rgVil=^%nESgRo``4nyiz_}j^KVEyn`J-6 zzAxJU-nmCdy$xocowUk!-)qsSsUg=xw9Xw)-+p^zluY++3sE`0z`%(z%|;JqcqiOi zx@_4ox%pG}$j;|Fz?7n@qADFEBz!M3FHf%2C?L)6-(9Vi=X3va&d;{1{Q0QW-j9`; zgXv%N#BZso6KBuX&V1tQ>swM4`b^}3lAZcPgRVnkY*jcmWA>oooPw`R{D zaluye17Tg3E8d=(T7JhI7>aGjg~zcwuIUu44MGw&)~$z|J^i~ z5WdodbDpPfSGK8m`swMsl>rQF5AIJXdv|yD^emScCV{dr>{BkHus$bO4 z_j|jaJW<&{<^PR|vpc0)r{2#o3yutZcl}iU#)yiSN9{lSJL>%|H~rikMJuaW8#Wk( zXo)V;5E2)6_wwqxQ*3J(%*C)_waF^$w_(3670M>9&lP6<=Q-e$?6h{{4Gr)z?>ZnEz*J{(l$SS1ISV=+EE3e`9oYm+gc)_u!m{$1#D_H2jwgHP4( zujbs?k~#gX+CRAnW6$YtSsymHK0m+r!O>IdANMI2hWwm3H~sIn+j+|B>h6~gaC393 zKHSG$D`$KDecI;Ab3cEXO7R}gw>;L^Y+e~!^lj;%c7D0U;D2f5Hw*6{y?o>PrCUxX zuR86|JKuCV{KwJr^Or8)?S9QqL`cXfCr9V-;lmkQqe8Sq6%`dl#KnK}F`GC{ES@Qt znVFN*@8MtVmMxyEv}XF1FY?Tb89usRS(O}qZoaK{W%%TZ^Yd9!PH%B>aVfa$Ywjsk z6&)>o_wL=#+m6roSg*fa;W^vW{%7y1-^&O;4cEH-^jBP5pj&qI=NTIN=S-P4ZPL`K zt#|X5FJIoiVS@n=8}rMTFJt!AMCM6+xZ`7Y`jT<_uZHvax3;{DZZ7lVQgU}WqPs7& z_Q?vnfDVm$Zn}SdoZ9*MYS*bMq3ZwsT5tD!y%w!HwKmrB^&*XPRiGO9yUo5`yJoFh zx6YFJ-^vAlu6ud^iTZgv>h_PP`tujBEq&7E4r-N@ln4k5H{Z=Wo?#*+C3Wi3Qg2N? zy>DyTD-N7YOON?I&$jwnhqBqj=M1yWa-**3cfE{~)->}MpRd5PV&hl7mnGqIP9>*o zGrPLCJ|#uPy8PXghLsB!HvaqfPm=Lpj?DAla`!J@bPNr>I)`Cj*y^X#CYx_Ae9ZPg z?B8GZh`py0pUSU%o}Zn+c+aC-E7tr;_H0_UZk?Ky)vdp4e*gN_(b1uxqjM(wW*d{a z!8wLGnE@QE=TegnZ}r?UKjA^Lm$m;qo6flP-?Q$7t)AM|)y2tNZzu8N$-C=G8wZbK2`^$FEU9@PC<-}XF_u6#}tM~PHe)|3TtGn>& z`?qc#Tkq!i^XZc1%iHJ8lk>d#aLE#tS+iBW()mBfsI6kSav*(5nVfamnYEF&(z~?p z*)!C<{J(Pb>f-YayEkamYd;nJcez|YUhBb9@&5*iPa}eZ5C8i5dhfQS%a#>=T(pEM zqVMv)tFi$MpNhEm8TVPK>gf0weJeNp@bKY7h7YO#{Qdp;uU@^ndETe{#qZ~;^g8_P zm)kk>!v~K27i;vy?}r5ayQtN0<3_}xLx*0xe*O9FgFJ?R0s#!4KCQUa_xJbr-N*mU zQ&_iZ)ubQy#jQTXmQB2A_wIb${G*+dk54^zx@$`O%IEX>PU+X54P#?tyR%uKa#O=1 zrOwy&;SP)^ywx^1e_I6V6u+Cwuwdm%&qtT%dhepHeB!(326W-bmoBOF)~!kYzfK! zwt42K*I%phZk106T^&{(Sf_f+Ug}i+zdNjPKM%``roWi$V>tWlyA=-lW|L>USk1st z#LRUdT7JSuIcd?(-}3}D>XU@r`Q??B zl!}5h_TS8T_H=sO%%D^H>b}0dLaYlC*l&nzV65oxOwqP(X>HwD_}InIM;A<3B$YKTZM;t z&3B}K`)cyS#MG3v;r+&YSFf6`KK3`*`DgT;De;!m{@=Oz`Okgr<;z+>o%Zzh?!L|U zVA6sG3ZT)>7aunLbY(i-(ABz*f#vy+_-jA5*ZwZ+{J3`M(xZQyKxyacp3|pJJ=1+E zFDJKb(WaWPpt_yEU%YuUg@;*4NT^1X!SCAc2ciec6hiadtE#LtH8taU<3wDuva_Gt zesKRCE!N$t9lq|&tVeRm3;*of{9Y^QU-nTR9=;zhOJ%3*uVvHNKgYz}+*`yUXH8C) zx1Di}e1e%qgZ1Bw_2C=+!xx)N^~M#xE$00(`ReQD65o@ zGm{JxQ7+H8=VZ>bsxZWJ;=6#=Cr_T7*sx^ZzPd1m`eiTnJx{N!+?hY;XOBlsjm-Bu z)#8O83zL`qDSG^Or_0Z$E^V)b<>dO@7Jm#)dp%cTgKh}x2JY6T`PtXksVXTs8Fl+P zJ2&6&vM;vnNH^L4_*DIb;^uR1r{>S!-YI*#yzkyA`{Nq>*MIr;Ey-*)Cl}YJP3f+# zu0J<53n=ieh*`n)pyg8E+UV_G+qQ1se)`vr=bIbPf4`i!Jvc5-@Am04UZ?i|S6Cfp zrLlkiraNkrJD)vM(^`G{?&KZkL{I6f&z(D0MNO@0@BSGxBz8VLc&l{{1K;V~D=$lg z;A53ozf$vwNZHJgWr=ZxSf{k1og+5atExX{w~ z=U+{R^W|?&rA`cF_`h91)Ip5v+JDpRYa22yD(NTO$T5qGj!x(Ouz2xe%c?IL*5&U? zqAOejpY+%NQNI8C-gh<8AB!}SOr$jR_2+-o*#A{})6S`m!9EK z{^Wm?nV0wQ`u?hU-?o*RNb!1ldg?@OYWeV?KuKA-v!_QzN$JpD&=8G`%$f?@?xRkS zF(wmJ)4y3tOaFweEZ5*T&)D+n{)q(z2YdSXgv=3l@Vj&V(=WF5@8|v2N#kZ^W!>}h+5L)VGt>8E z`S`Ud8fa;8P4#-3y`M{iVf|!NDI+5z6*p^thBG2p&!0T`aH6{$c;*Z<`1|Nr^%m8;kKe$Ff{ zFHhcn`|f7e#>1OM#l)Uj3%-_m7U}UJL&U*kLulUdOG~{u`T4(BZPfc^AABHuWyqc4 z_q8&XMJ!vRdSkaN77Cpt&XZs?Q$j{&PQdznqnRt#ub=)^{XEN4`@&BhC)8oHi<66`{?Z)FJ8Mg_t@!*l~=R)WbIB|%bmUV(XHB>=X$HZ zZ`M;5UVT+-X3OR8zcbSA$L`Gn4caPeXmIS-=v!?b&bCYB$-UPew>&*OIQ;*9XkT+W z!a7au+U?ugs~MjB`{oqPu=|M_SCd0p+Oj1dcXR3blneO#`0)JymH*!_C}@)OkG_wy zxk8jW78Lbq#wu7AKRYucneR=RwXUwNiHXS%*5f&wKB=p!?R@>|xAtYzDDC=y0D*N+#o7HVB`Xi@tIKn7VR`uQ;o~5NeUCEle4Fs4HH~?~+TY^h;?G5m z-&Ser{j#5!FmK~LadGkU`|G~lmkqYF+*KnGx;FH(!f3 z2-E8)WosfgAIps_-@D@8y|}ivwq>Rr>UN5a^}n~D7kt;_BJ#G(B_?6Ja+j8j%Y$7> z4kDFrw_d;VxU7D^v4sU_7GG9YR(RR3CItaGIlrJFp_3<1z6-jtPNr+$KD(%>s1++# zNEpUi7;880ezz|;>H3bmr~JjYva_;eE}oh{cWdL?XwX{t4c%q@ zi|_oXF3x;!cWA3fn{fT_*Y|&{&#!Cd7T4=}efNZB!-fqTSl2Ubvs^n*XyWF7yFaa7 zu3e>XVlu^DuD0jG1_O6}{Z#^UkIKmSFl^{v5pwSvL-*A)`E{SA_dncy_wL;-+qU^t zOzQjap};Kfjz?LUS+}^pnu$pWQ`FA?*YDjsr@em9p`FFgQ`SdUES>T1-~6KQcguyg zX`Io2`rZAvyYtVjw-n0W-Z^|~>T22Z?pyjfzI^=p?2|)ylH}dkyL&zydjIpPe!XYm z$0KQV| zRlTS6bUxd)GCW6z-{u2D_O&$+cRrstdGGvJtEA@De5$@v{62Qc(xrVjPvx6@>x^*4G0E7{XSIZjE|-^aiMX z`SK;F2E%$eHOLF7> zm1b1Mzn{4qvc{}qxmja7B*ODvzo2s@} z-+5J45gQx(?wHBdPOF`jKXdMGW8R(NULg6s;LEo>wFN~cN>eo~?lzR^h*`(~esx_! zN-8NKp<&uIvF*2u_AI*oI&y!VZT0tes=B&o?>7JVoTg#wkm_A;^Z%3n|3lvTdym}z z|F8UH-R!f+y7l+8#EG9N-}hN|OVnDWAMNe!?mCxNUd_6>vDREWY|WQ#pZu9}zq6NI z-=)zt$G(2v|LUjwbL{@AOG!yBW94CHX5Pf*;C89u^ygT{6y_*Z)(6=yzx%A2d5UN6 zh7GQBcD&_l_rLG?(zdsn?~e6b#yB5_y8pZH7d|_4d&{S?AO=# z|1+JgAOCE*{a;N@P0dMh_cPwe8rGU?Y0avw<`<9?e3=%K{O+u1gI!R-g$EY|^!I;J zI&b%xXS%+Bz0$;(yn{|*4AN7o+K+aNd-F6DaV6|I5YA+O;NoL-4n8xB*noA0`!-KM z&R7;GvhKQKK?K9k&nts%KAlikJ6gUzZ1v4;xzfk`<<*Uhid?$#x8DXW?_0XGb=x+x z{h^I4jtNJ*M0H|!U6Eaqviatn`I3^7HJ>KWe=;+DUZHsO*C~@G34MEi|NQoSUv;;kd$=p0B^6C6f=_x6jHS0H9HwAItNPcg)I+2!Tt_BF5A|2%rR+)%1IorkAr z=4`fR$9ET=v?eg$SmELx8+GyOhqYnav9Yniah>XRc8$H3m3#%od#}51QGW2^Y3%D8 zp({f8TmuSz3dz_1c<9M}=j7?r$*-@ib#Zh1_4aFZbv0-;^2(K&S1dm+(g=!*@~W=3 zo;h>oyM@!vrWI?08b)$eFBIb{pNihA|6jW@cES4ocKNy){WVXN?-ZZ6RgU^;D#d$y z``e_OpG424>-Wvvw)=Xj!@4i?){1fa+x^`C=S92!#ryZ|A16pKGkZjFa5+q4T(WGL zkch~WuTHyn?NST*ny&I-_qFYJH=Mq?xjV05_n&`dQ(u&Ptu|t|c6C*~Q}{b~^0eve zuV!_2cTesSwLO}&vEbdEorPz=r*FQw;bxABsp-Xg_x#Gr%mM=gZ@evgQ?`3H?~1Eg zeX`bWK|w;x{pU~n@@A37rz^q!g)cAtma(pLDeMrE6g~Uy?(Ytceupi;89!-MeV(|7 zY2M+^zCJ#?AC2r4|NnMxX5%UH@^EBSIVaA#Anb-5i;d#;`s?drmn>UWwf8|=8(X>8 zQF-NFXU&p2 zbm&mTww#$cZ}xgEby^zKtEuEG;<_embu{CR95Wv^&^q-SIc7@A%6GXA1WT%@s7#nQ z&o4A|YR=!rW5?XGva=#*Z*-d^v^VQ&)VDYH{5RN1gx_d+@nu!VysiVqcPo2R?wG|v)^lo+d`e{5TxwyG&`E!};Ea!_lsC_8hDSNz6cJh_~ zt5>Wj5Z^N==fQ66pGS^tD*oP^S706AFZ{bH*|^D>ljFnl%k_^I^4nXewp!$xNiSWx zbVZ1kkg)JxuDl)Z$}cW*T@kV>a4PfWn>l$OqSuCfPuhHQLxj$jZQCy0y9ZkJ+oZ5V zw85KGf`=_^eVlJ_@Z>lD-@beIEbC-w*xESHf&v4n-nO;T`3libme%>XaJ7%+c zr^i)w=GXte4I1z&j~#RS_vg9&?qb21?$?&D zO04|mSSZf?eD7}R)~%oazPEENFV}DHzjNr)Qtfs7xt~A!85i^ZSYEkq(d%`|uKnM& zc3pqF=B^+ zzxCd|YhKye-N`-q-}g*geDLO*vbg%Up?)&fhc=(LvCY-o#mmcE^Z)n#=Wn;)pZ53c znl(C+-kb9C-v_bm>wa$Nws_+8xa!_ZmxA6vqqAsMr1;X zDrm!nwe{`nPe-m@3zL$TR_}dvI#*soV!@ghXx6DM2g(QW+x+gHfBEudTV>wor>1JFfVbM}Y-D$Fb=~>gW5eyYljhwk=6JCC#KxvyzpARL zsyh1n%i}K>dk6>%JJ;0MeEs@W=zROttfyC2+6xH@9ct^fT)gP*b>H$uDp~#|Qv51r zEZ09Av}`L_tL&7OC8fXr%b_(h)DMP-t&h`v`Em8CRW-dQm_8^Uu!!Hwp#9Wr*Rp?~ zSXSr%cptImSJ7?T?Yz9afw8e~P5b^myT1R7Ib*Y8%fp8YH95Iu*9-l)dA`og$A>4= z&Nil^!a_T2&4MLMj__WZC^mgjfYrUwygzNyc?H#}HhWnKY~q7SE6|TfBpZLpZ`wz_cbe4KCtEiO?}>477${} zmNDZsmqQ;T$ARs0=P~G8R(x1+`}_oDs)@U%|})z$s-{rhPnhMn```xqGJ>KD+n&QK{L3ZQtYV&-Hyb?DXthvRwb^ z*Xwa}L*EiPz8ELpkIGf(Tgc*ClnD;Op<)PKG!AtQ6<-{0Sc5uz*lJfG&lP4=1u5xvA3yO{HJ(~2<`}1E-w)>CU+uAgA zbyY1aZg^W(^EqC+bV))=YEt%*m|b7&czJo>+}zC0;y7{JZY73T+dbB|Z!tf)e%*FT z;|s%_4}m(Tr>##odyD7a$M5^k&f*Lf*N^iFnNnVR_}aCwowNFvH!k|Qg29Z5-(!nY zkWlotoR6PWcdPB6!SjHhk1r@F$f>ya^OnoMHf%5unmj3DPle&il`ElJvxS5wbMSII zufAF(+2J0Mi#;c| zAV=PzWy_Y5viEx@e%Fti5E^h<7i8eg#@n}UW#mnB3EIawXMVp~!_!U7^JYkR_Lhh1 z+fIxueN$$=b?er+wj(R2^_0H8u|3~D+AKfu>8enbGti@*S*WD z+O>PdniWrG-~ZEgr1i_2&F3f0n&p*|v0}QAhp+F_ZQG``wY3%Y|F;$Q*VNHjvU~UJ zxz^=gZ3+xGZ{B2KXa9V!`n~78ukrtCW*xWts^M?*Q^oO?!j*FgYL2Q4gk%!0dK~+G zPdbLpb-UxGyyIzGlega7aC6Nh8HVYgBouyr|AFB9|M~p?zfm`iD)RL^`I{}kQnhMd z6=R=bFh|MVU8QSccZ*H+dRkZ6+uIwbdf+%yjd-k{p5DA^J3lX4w7Bwxviw7K`-(1i z`M)aGWp^B+s;m;b#d;0i?Y)=1G9-(Kjd@~Vpo*H>rjnONMMcG({r%6c?*DW2_4hMr z#r)%i>ofa-14H-s;OxU zpR3X%LHmZ!H&>lFegDk8+TSZzuU)t?G3`xuVPRpM4wp=0NNH*5zIHLD`g#3a5A+nS zmp^`XcJ^Jx19}YMp`n$c-V)ws3Bkd_*Vo0){`7LQle6>B`uYEv?0+2Ozqz-XKe1a( zbI0nM7b}nN?HBp9%S^eM`}z6c@aM6*yOu6(y>TPr(W6IuA{xAwDj69~`t+%&bA7#u zbJN5blTM~A+O=!eks~fQC0anqTv#|&TRMJs+0BSs__%GZoyWes``@En z(>xTyt$e=7*{uj+idxIIH?BQwvE!4fSDzScRC(Ey8nB1v&+&k&aibs!N{QCY6fA@m{Gwz3$2uo(pS-EUaH^zD=j6p zXwRNI-!G^=nE5k(|z{uL) za-~3Zzn*E>&!9V(Hmw$k+xg<%*X?1 zJ8rCgGkb|*rpb%1RbQ%X*_sQ^-^zMdV0ia zv81hXSBaIb)m*XFSKa;}P*B@Fb2gvMvtzaFKQ6BfuXt5`f8p-k*N3@pqf)u*w)78&D1M~mr8EBy1E9xd(F$m^=M{#{n2%Ice^in>oqg0 z;O_mmmiydfto~9eQ)I8X6i4cI}!qZ=Rfwn($#~XOk<}KmPkIzN6@;kZtVUmbO+w zA*n~ERRJqmzU)%i5~UmV{BzXKEK_q?3!l(b*52O9`5K_jGDo{a<8p7L7!|&~WqRNF zcff_PsqZ>%NP~$oM!pHLVev!6PXpwP@|y-czT%xVX79b8?QP7%jY- z_3}l=^Gmgl`kdH19H%cJ&vkdJ@VXZ>EP zH2)oUiRVM^nG>#m`m}nE^>4Gohd&*ba1^+)CsSMg{|$8w4UGv)_TGA1cIxzL&=xhR zUN<8d4}bsT2?iIgTro*Kzh?F7?t=#%CrzHb*FmjI>EOYGM~)t?+i-|sKpv&KbGf~~nR*}Z?W-R(fnx5uRO zpIliPJV}Cm^G%=JT;0>tbc;pqf9agp)7hE$^V3s_-eaCCW7aHTX=`g!nc1z!pcA#_ z#N53Wvl5LjaF;O5wJ>_(BJ*<7s*5oPGE9O(LyvCFzAhmrcPzmmAUxW+Fj4U!8}miG ziIrKsQqCLrcAxe8wMn$a-KF5$-EuWw#vfs^ z#=U!a=jK~G*Y7WSmL3#jFN6F_V)Krt3CLoqp7)Yfy1=8dUgxekjFFBZpSOQYxJE7x<092 z`IySR{Pj!1K+&;j^JY#?&cu(CLh|m^H>`M(aq_p(Y~3$kq<+4e?Em5S{XbQQ&Z`(1 zO^VLjc{Ka>hYtq(|80GmUzIgN_EyH>E9$en_x2AGDS3 z&%XHjYf5VB$LIF{BZZQzY;1f&Lq%7vTsf&E_`0#F1P^G>(v~eIAzGrfwY8IH+1J?dg*ZT*xh^%%o^)~JSwFXl>S9GhtJx%|O(3nSn7BNIKhbF`n1{P6ex z+qZAul`RQey)!DPMWah)sgB!+3$L@bay7@fr(I*aSNHmTNvZFdqcS2Qprdl%1CPwahPX+yW}Vtq`g)I4dV2cu@Yt&B-#&f%q`7$AJRwohv&H*=${HGO zoaAHb>Gg_ZX4bw_2eUQ?6ugvKy41BRxv=@*fwS)Uit6guc{BV!?7p^m(V`P)&OGTg zzc-=bdX8CeSXkS^1O+uUw~za!c-Vr1f+Du($zHs8@kWjr8ylP2QNIgUueL_5RWmaS zTXaTPNC>omNA{TOLl4pVTqgV5Y@{)=QAU+dLV4fV6si1_{cch4N_@8!2{M~l|mE7~hwL5wmC33*xB2=JE<}7{F;3qJ`_yTiv@+BhmVhng@r`- zQKN;w+SjgKo40@O^Y@u1Qvd#cJ7;av_uA_B{+qE3+&WeIDjZEr2ei6atbI40Qqt_) z)-hB^my27263(P#fxK& zHf-7?v}$#B=>NL-c=_r2@yFhlO`bPTE~rvcMtOqu^=HqY8<)R}d3J8DcV3>Jr>Cbx zuiG5I=N(KN)~;PEA|}=rBDieXvP(B^NX$`5`LgrvMV+?7UwfM5e|sc~3Md?VUShR! z<;sP-chBB;FK(9@#U2V24{=-qn zWuZI?*8^A-x{^2;L8mgsG}X=j_vZPJ%j^GCcKkZiF(v1ZUHg>!cgsHgkz93X$DfTG z3-4_HYZs;yFL~|h^!~oSGQE&_htu|3a!j5yIU;J`ly9I->(1H=d*k$Vb#+6+!n97a z_Xb@N0JSA1Pd<6}Z0fl=mO4>eIuecd{}uI_GUw*3km zSzkYJPh7HbvF_eCtbPpk%t1AiCn;9k42q8K&c4ui`)N|y$Fu)<)FyN8zUx*Lr1bai zU*&h4i3So8dnyV!KF+hRkIT(@!<@BDm{Ejz{#7N0dbT(3--mDOii(OlwscAP-!@;H zuYct57xGe^zV zcJ7})HP6n>JpAY9XH88_MScDLEn7?`O`beewf*$dLus2=UgJG-?AWTOhmJE{ZwyZU zQhK}L{*NTy*%NLRX&3B_xpM8=rJFYoF1YOYF;{g)l8=H@O%2m@{kR1yR&Z>;y>{6% zVX^W%h3*~KpRTWY+8*BE9Xykv>90?y+4R)?&CRNdG#(XL99vrZ`OTxGd4K+0o|F?> z@ZPFJ3ZRpuCJG6@%8aa z`ugf?O;)%Sf8DFgHQ%l8Ke}=8yJ`B6-T`wai<8=mg6glyk8A;C@hi>C&YeOI}`T zkbYdY8O=ArDkKNZIp5S-K$aS%(GuhOYpG0i`dlk=#kLV+TZcJ zGC#+ziQ7DF`TSpUzrVjfYU$!~|7j7ZO|9yvVQD$@&6^w}W8;&jPAQq1hHgzyT%w|= z&mS_u_}t^KtPi@*f7RpQTlDWu`u~#+xefOJCbxTd`EdQPdHVEeg^k?S9=p&@Q;&M3 zC|y{=vBjs9KOureA-st-d_wP%pQ$PyUS7|R|Nka0a!$)dWN%}uO=6GCmD0br`u3ln z`p)c5Vo&|cNk!N0?-ZPTQsmJmcIo|B)0VD!WfXh&R`kJ-A34{=?Ck3~lM~;gv|-PV zWy_|S^X)k|&sP7!#d~rWYhS&7y?Fil{#mo6R0XEZo991fhJb^E{mUS6lC)O~f9+?A%aA^gcJ?dp~O zehj_eWyHmgU)#MsI4Y>^`s>h`8q>q_GBQh6ub!-Zb^4)q`_rF4*_iY*D(Uf=Q=3>+ zbdQ$btLv_<{vKe@t5&8KMOYiNp_=FFk z_s=(&{#hSa)!8d;-lp-Jqv^n}udgi&9yoMp_-;7(`@h^V<{wHQSQ6&zu`G}}Rc;~k z<=eMO)21zxNXXCEpE+}8ve4iD-tNaY>;DOUex}dS^P+!=b?^J~jf-V3KfbT<+fDoW zzE7!pw3=--4Lkk+A58c3_Ljf&R9;5rNmMd3@AY+Ad6HaB2kumMYiLKWIHPg*Zmi6& zyYDN$PK_`AbmU{<`$~l_P{I4<`}g)MVn>c2XBTivN&>Aj+_Gg$hU@;+JtmFG)RZ*9%CEO{{@>B~Qs3zsi1exY&dxtM<3 z8rQaZ<~^+;uMM6qcy|4d{F0jY3{Rdt)6xsg&)3(R-o0dr%37Y4C({1iu$Wi(ZGPnb z!pUWY{vJ{5qrS}-fBbpB!n5~s?f+(n)|~XczA-h`aDued?p3>^j;}eS#Wh_&w#y`cKfC7BZ|58C?(5hr zy5g(rg8DbseT=ytN6j@^QZMu}?wauA@oV*i65kZIzKmi#!}+ZWbZTW_V4%mr(5x&i zv)R4#=E)uX!MiVxgRi~$cHVB?28lI!jo6r70y!e9*p{oy!)s-~KgupABR3 zQOzFz8sS}ASd}Mxd2hT^F8|voSR#b;%^5wdw7i=&uJ_*+T|K&iX^PqExzFcUH}2ZC zdht)WJqLc<_N#ylgxj7XO~I^Za`eFR*pfFCMlcvs|UzpG5|N)M`hMPIhE<@q4RLUm9wv|L&%I;Kk1O%=5nOTwgtr#Y|25jNPRIBg5#r zi3*&WwH2u!gumY@=C`!8^m4hMVDO-5XT{&I*EimNs~C4+SLy313XAF;K3rPrz31z- z=!f^3&x*_cWSqRGd4m+Aj=E3X_cmT>r&UYajOuikEL&E1U)|2Ls%lwR?vMYzxzeAu zlqdXuz5meX#%+2rK3-g`)@1_r*?P+w;R`Z8^mj8yoBE>gw7dK4HRy z1GeAqIOpW#oDh51$}L{;d~SK0)O)%3HP2Y*r(ZI@nKva$;6t1KizTz3Ub%3g;b4M- zzP`RoNRi5nP?OpIb{`ZxJx@AI?26LcUs9nr=lH*+`j6ILIrnbUnOUw6*To)r_FP#- z#leYbM@&bVweecBSG-JSlMRm?*lO2*H!uA>clFN)&BBNOp4q!^>&wmimR{wbuGMjSmAn%#6M^lEom(_E&d!S6rsKk)HMxnr`W5(krH_O%J6&*uur z>!1DOrfeb8v5$H8T)Y0+dyPLAw0X8oym;lt5$^N*E#?Sa=C(Ul&+M6eaqaCVEe9I5 zxb8Syf9Ktuos)n3_|c%VfBXHq*?oO{S91@#c8hIHILLI>W#PYnb$oI*5}kRAPj6?j zdDZ>Drom0_oQr_Njnsx|iRmdR8Z8s%%vqx{?ZlA)gJiYW<~d5n+S&^m+)tnQ>(p>c z_|XA|bI130{(iuC_IuK%h!gwY+v%vPn#b1lyBk&A{2|NdvRn4z!v{(6`t9#y9$#lQ z7dhT1_xwSl`IZ~|_%h{xYnaun4yLD1 zpPst5z@GDjeRfusMbQ(Ew}Q)xe;3?zXK`;VKb|bp>a9@8_v6os|BVU>8zV%F3}&BA zNlEe2T>0|llBHfNSDw_=l;~C4%4*)+-25eat;)5K&2PegZ~T(|+Cc5xJl}t{-xGbj zojdy5ckFOj{9V$HkA2=gyD0xT2@AGPos}!UyzcR@3#O9}pZxv1{%rPh{TFQZrW;SD z`*2-b7km2A(QZ*?_Lb*TQ&UqLF8-d}a4;d^HLG6>pr|sKR@qi)>f@2f<6pv&5f5X1)Vx|YQxPO z(3vo&PI;}1-!I20$#Ed){zqMvhZFC5RI&x$Zj;q&z0xryX=m%~%;k^e&fVp`Bl&FB zj3+6d%HJp?etR=pZ~txCSD${T{hxQr>z1~*^OcG@Cq3uXJkgi%@o707T54bM_JI7B zl9HMu7d~CLQq#Z3^zM`W#@yRxUS3{IlbZbI+nv3-I^4Ob_MnOa2h+=!FLk1~`3MGn zRcEdbnlOL!ZO~%q;NW0qU*EGCp_|VuZGB&zZNs4;vAL#Y!=dss$usW8D=mHZo^fa5 zI!_%frT_nat4_b4({|%Vz~b+=-@bgmT=mC-Iq}pC>(gG=(q`-G|M~xWYcF>(H~my{ zTmDY5$L}@kUV6s|^@N*+RQ|OSVLWk6PFUEvu+T6yHMOhEVMmtJ|No$Edt0-wuUNhM z@uj8S6E&>5Jv<}hQ>X0qJfx9dpta$~bICKGWs4_nvvO-a&rmOU?y0%NiMajqzL;j` zo%o+ zr6Ke7LgT9@7I#f9Kll9+F1w7OP36J+08O_K{4o(aB5!UuHq}qL|CFoq-D#EuPe1)W z$ZQkG=g&Ra{A}p)6BC+5=J>L#}E9-!v3@3}exZhl> zqrczpx1W;!q4t5{lAOzlhbu51=y5tNGn@JANacwUFs+=yBM3*nV<=-IM!!F`T1FprSaXncMQzejlM19)6{voVD;+mWy{o} zqM}54&$hI*H0&4Ov*yEhwxr}_O>OPucXxKi>@MrA`x-MN)kE`7zCS0^iUuRbdjf}a zem?&EN#oC%bOUiw&tvk!!d9<;_uMx&IM6#;{pG54eB1M0i9EP``oZ)2mv~dH9x=vC zXo6Pl2JX`NEgj?P+A8$N+tX7~Tf6(r86Veo=U#txd%~JA_jA==9v+?x_wJqh`ue)) z*3_N+$r~QBS07xta-~k(9*Y>`d8QuL%<5{Uj6Y)jO}`KnCdy)TeT`!Mb3dP#FDHHM zPCBsWy+6yjYhmm5f0x_#L8>+X_s-Ycw?6!<)r79oR#sL!>i$~k z>gs;^`t{+*ijLmit0LLGot=pn7rC04n`bYT%XjorUpK#mrGVp1y{f3R?ZT&@q#r%f z*zv#aQrP-q6DBA~?!PRV^yNp)|9`WjX8F%M^7e|zdBMhdmVX&9MczMOr>s-Qki#S4 z&BlCtTduOUwzf*{_bV%dD{SU9%xI8N7GP<-aU&w_+#JuE8k<vl89d+oIS%`rJpB0k_i54+rfDN|LKe&K3*c5h$C)=Oc5j`2UPrL1MD zStnDs{PyuJ$Bs`ZD`FD5ET$K8;%@nUS%J>!rVLF}8+h25LG87kD6@*nWp?H7WbWR* z%gFY+Y`5X;v!}8Ty_Gugk-@Uwq3ma~;`Y4LXU~S3*40O>4g2?U{y$IOjS}%X3EGKe zY{$+r|2Vpiz3xVI#E;8gW<{MnvTw_$BCbE6M#AN%<>h5XfB$~p*tT+?(1Jr8(bHe) z{V#E!bN(y;4M#5@pC|XK--mkDr!FqBkg56cu$|F(*Pj|k$3`KIFZS}%(%y-QiYHH= z{PO+#ZlD*|rI&S(~S@-N{K$AjzIVJSH~t3U6Q-mZV^nsN2ClXvcV2Nfsi z_G&6NN?Mms+E=E_*3J6pasIA9bVFix1=%o6@}u4QpsV!YHb09QzwF$u z-E{Yne$7K}#YX%7iPcX=jSWeueVQd^6}|0dYzV1nWH_?gdM&9z8FYd1Gn@XsQ)L#4Uj;tyNP@M&pluUxTW!Mb&MTOKL> zNMh{f2%6vbO6bAK^!Ylb6?=aRv>tViy*)SMVMjs&cbmgSzWERZePpbXnUC#M7Z zxrduP9m*d6txi1QwE5qA?F6RJy1KJw&9W$b#3Cvx>h=DR#=%F?Tsa5VKhVu$`EccO z{eJ_wkD3B)cc;Bt^g=cF!nvT;x&>$Rw?BUQdhyalNh^-b<36x_nrBp&Rh}%zfqI3n zIy)?9|CFjf_4C`m&3|?lKMyH>e|6j2rr1Ku2j9Q#q!{;_5H6S!05`<5^JZ-p|wRH35$=c!T3ckIGj5<7hW%k;~{><`B``v|DGCxXg zj=3Vn{^WNblgiy*q5FZatpC6Nu}jn4hr!?e?~^M1N7*c#dOsfbSx?)Pc{q*5F`=Mf zg0J+p53A$fAI{>|IZ!OsyC-tS`CIe<^F>$Ge$^5z)0-SqFS}iBo>R~wt^?1`&fXZI z!n3?3+t~fQD;?uolub5FxxHh5Br4|aw6j5$B%E%Nxiq{ z=Z+Y?IeyD8`4_yMRl28IW6RR8 zlW2D7{WVLLr%sq}-u!IZ1*Lhrc5k0><&x90rP>T{*?ye4wBQ(@Ri5V?rc=%_O`)q# zoH)Tzcw0Yy-*{WTC4(|W{ z?Q7A~Q?7HGr5Z&8RsI%Tb-&lrqU-&2jh(E}z9+_07;h{~tJ@;Rh6m8u%ZJYG1 z-}64+y}ND=_tf2Xzkf-ue~}#5E-&Y@^x~OkXJ)6+>u{{5><-S)lwXLj~#r*Hq5 zuNC=TpKYvvy(Z^+bbjpB5zbv#e|zmYV{&nt%s(N9hglzl5)N1$*vQ`(6c*K{(RBIclHJQ^Z`&4j zD{qUDg@jr2D(*)8y3hIZEEe<^%Sv%*YMwuPHuc+^n~K^0Z{3PY-4@RMg;m(u(UGzE z*_lA!&!tv#Wh{$Yyr=7B`b7OXT(a}vVKs(+&zjp$#P+b{%7%r;FI)9%Q`Xa9iI5pQ zkCyNI_f=i$i{U!w?2DW=NJh zQ&X$n@BJ><&M$v$)xr9{%q51FZ)_UW_x(Cj%9yzR+UHFMj|@Jn=X|!Lbl1n%5=_|> zXPwsa@bE~ux2ICkxHdTW@&sN>Az|Uj4GE0eVQUm@ZDSQDJWzeRulBb^!GnfrALE^~ zqHJ>w7TGW`UJiGSc|GCRx_%xdU8Y0x>mN(^zYMICJ$$hCpgO2a5fl{U&~X0oN0u}H z4m$38@+8H}%WF!TeAJ6~@19NH|0i`vRSkd8$?E&M-VFVAzcOA={{P|0UADj)(TTU) zej15?h{@@Boxktb)w{c#*7rS3a{bV`Y11Zwv;U?|o5rwIw!ZVNq;ZH#b{=kioqfPrA#L@!?@bkc4mb2W z4F7+9vABQRtH+VYIW}tiZ~;w|G^}5}TKm9{&!0ZcFwGY0?CeaOzQk`i=+upSb-#00 ztzLb2FTeSR)Ccv;9{b8o)p)V5_IJwFJS&%kf5|1RC3 zE5`l#*;#G{w)&rW|0VZt+&EEK-7g?Aa%IWWs|_4`6e@RI&OR$2%5-62a?b>z8YM+V zMThnzGba zEx2RhX(fd$M!WUby<=l#-|zda7aAIR_~O<59U&!OjJ8ks(BsEorKW81x7bwnUxJCb z`R7-w*B3oKHTB__YpY$fp4SRyu6{qQ39QKJRsLK*^}OxY4xjBM%688+zh5)?`@QOX zi?;uQAHMICykEWgUdCL85+AoKZ1W`~Bo4eR(OSE^`QnWmC%X0btyp?bc+au_dO_A7 zqvMi;)EQ(a3+j4Ueee2^6CN(k*WP^Pii2xGpvcNKYf|p-tNrq=O|&PELC$s3jcZ3! zYYkp(cQ~%n;t|lEzWuguZEfv|*6I53Y3JwJKJ2;ATf;ts{mtdxcy$KZU}nXgs>}W7 z^OXokMOD09I$c6S;=(WKP!Ctv|MH$koZCTx!_n6oQ5-r|=|bk_n>Tis>&xCcn|$A8 zlA!(4`(ASy)R+z#@E_LTdu$=MxN`pCz2g5YR+R<&&$sK<=-Tt~m~_nERVx*~b0@F| ziOa|)E?{T8%3H4TT)Ea)<+|(Z(uwO%AOBQ(@cLDytM|p(gdOto^yF(6%v`Zu+|w;4 z{R>96*DcU%+fISXg}_rJoK@M>Sa zVpF!7v>?ZJ1;!5NIq|GAQqTTpu}>@5{P0*oPfSmP#4^#q8Ov5QaxXS`hHTBeaO>Q<|{O^8x!6HY7Mx4pn5Sh*yh$;ME8H}(QPb)0e2>NZLpzj(lmw2Q{Gn|6$AdS7;U4q9 z)&qMQ;){*D3wFG#Fp=+1d(>MJ9onHL=rU=gT2JG}dtE9IS>A#136Hew; zJkD*IY-?dL%fi9r+q>h&ZU%CW`%k*?1@g1>rHL!tax=WwW*)hnz1@0p|JAYw8QcFK z)B2sas3Um~Z*@%CKM(d(DTaG4rm**gR(;Cov6*H3J0g$S?Q*b0=SBAmdKI;Vst0B(Ka9{>OV diff --git a/icons/cthulhu-32x32.png b/icons/cthulhu-32x32.png deleted file mode 100644 index 0f0d058cab854137a8bced6a3613549b067e798c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2265 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANL}Y)RhkE)4%caKYZ?lNlHo zI14-?iy0VruY)k7lg8`{1_lQ95>H=O_Ur7DoU+0icSGtK7&y{AT^vIq4sV@aUl4Lt z^tk=|)bhvgW1_0!gtPuf)DAQ#Y%y`=+|TnPIYFX6AY{X~%jZIFJBTis zyYceITL-gxd$t^4@hs@@O9@dCdg4Cm?jHrW&)qCaog3`$y}SMW-oAg6FQ~Gx9G^GS z`1_y2cYo{7@BBWmTJO&fC5F$9Zyii8Fjh3G|Fl0{kE+ooXTIn~ZPA!BZ=M|6 zALkY~(Zl^BA0MY}{yDX&sY#>#aH1FsqwnP_lhysdF&8&(llI*wYRJf^z_x>7~EE=Qax7m^Wd< zhYC;6&V?&hoXFT1!O`mE<{HS+>eS+-Xk}%Uk(+z;VZntvcg`H?6kfS*-8)%c8(m#p zt7}sKMVcNIJUf4<^4XD(+g=OKQ0jVg@Y1DA*3t@b6 zZEbDuGOM|5$Bw!E`t@sq%1f^+U5gY>8+9#;S-NZ8Wz()17}yzBJ~}s%MNN{YP5;!XQ;!}!den04m>W|g!(mN%&J`M5 z&CSg`e0)M2ECMWz-QxN|5fK?LUc5MQX~F54@gLk7=gqWFFI#i|{pEgH`-j&r-gVIW z5cxz=gzwJGx)RnJmltY7jJyDVOc%X9_Az6f-H5F=WV~=*t~f&>-5vDI;UBh z9aAFrc{wi>Xl`znv90=|RlpEA?d7Xii*_&XzAc=)CVso0&WY0(zsp&yi2qc@7qjVz z4}bPAkp-+3%ri`DID}aoZ+!c3nE&{d>(`Y%FPRGR-v;Vny zwzo^Zy@^bT+{a~7RI>Z7$D|V8in6}RPft%bEPrS7Xiedt&ue2%Oihg~3OEH8F{l@$ zov2m+aOT3}FFlMWw%yFxwq%Kll(cl92y1BQ%=-JaXXYBW>qc*T@UbEzGxOm4@A0uK zd)&OPuQ@jJZHntjFDWVMAAfG7Yjhp^&91fa_FENo^~;wpKbBCt@FDds;{%5$$tLRN z=GRO9{i$p^s4#0;;d}qCh@Gz#wZ6SS`n2fb$BGjtP9z*^;rvl!mzABpQT4`+JwG#p z-tXzIEPh`6qFL+Dr2aLMl_7FA9rxcKfB!vsYgF%n7U{ihJIi+8y>a`tw}yyQXy}`A zzh}MXanG0LMhA+puD*Ke*4AuJ7N#G6>(qQ_xrBy_ik+5N=0E%3y!!WQii#68oO!a&A`&^=%Y4S&|{xmqs9aNqeqW+u3fv9hll4u+3w2xa?AKD*FK$4?*EkF$+=5z z*|KNJmo6{glz-n&#ZyUJyZh6p@}J8V&s9C@ee%>PRZUCI*}9GTS=oW1tdmc++|3ie zb?eqS#@}vd8x%Ooj~qL8>E_MO(@<_=;zrJ$C#36yw}mC5IjwXosy!yL?Q2#hNus z7A$D^^{eXKT3X{jq zJT@P-%lX{g+>5`zyW71ivq#o?n)!XL=j*oY<~*g?RMe4gb*oc4{a{Mhvw*9LLc+qG z{r%~8b`(nRu-&?KtIAgHd~N*p?ef209DX(9+qd=ae;mEU-Xp&Mt-7V9AE)CBeSF<7A6l`>E4$eCew@YeuBWSaoGp`1K6a$w)s>g;9v^>g zmz|k8vH9SGh{$Q#C9(Cq19eEdE56^gmA~(z z{Q1+G$jxYv<-o;MxS7|t_aW<1=iV4rQ)pa0{l z*vEB|-(Q{8Jv(XH%J#qa9xT@1_hZp}wF8S;9Dl6Zvc=?T)>fs{MroU8E?J`T>-X=K zD^_rP`S$HySZL|v0@XE4tM;*UYjowiN%DBVi`eQV6JH**-pqwFu<-%+?EhOHpEtj| zl+AKY zI=;fuK6|_Oa+i&dFF$!QCpsra*hg)0`sZh7fBpLU`YW%r*^5OQRW5-%61~UN67B}< z{=R=(&GB>7ua&fa-EMo?_-N|Ah7VuAz1>%!@x{?XrY@%}e|jFgFVFE7bp0s5G+Vy+Qc%zeyX#9=9(=IuO+iJf+#M|o zx5b4EFTXUIZ&z!zr}TB$%H6wvm&RU?-y5jO_iER<-|xeJ{9*KzQtpy2PJGY*cWK1h zYwP*s?bei*m6fepwTmU=-@W>Sr>(c8G6gsG*M0u;UeA3?#-j=6PZVykZ?#(z%;IRV z>~$661+JF%ko^~ryGT@tFKTmGH=O_Ur7DoN~NB|6AQ>VBib#ba4#HxOa9|b;Xpc zbC27I`vW8Ue&lx8G(XcmK~fkKOlOTaouy`wD5N(on%HpO0Fl$$HRd+o0Ci^6u> zT|2$)?$=GHneG)hE?~?J(NJ?z5cen$Dw5{dDSX1<O zxBWct^WS-&ZMWZ-tznUS-B{{zog<&V}3CL9rbHf(!r%ii1wUZhdRzdx)UwUu_V_lYkgp8%7<)>x7v#%UE;vyR0?BsNXUA`t@u2tzO zX$zi~o@EEFY$^GeZ_9R!`EsL({e!#*TniZV)m2n{qBbNn?pw5|>C>m8kWf|yW8=xM zUS*w|YyF(%9pfG6P=o4kIdj8BNG1Hf10C zGUdV&&CXfQt@BT9TV2L$uzAy$Co}giVOL|6pXsw~<@fvb`|GZ)i7Y8EzkKPEldmuD zBo)QeMqP_ygul0L*kCYe(j*TbpCv0-c21ZekYgt8a5Z4kMAKd2TdZ>b&FvPGiqRAQ z%_nAYH!fdXfZ2w@#_pEf4URu{=H})lkB{{xWoK)zUAy*2jh%|8Q)sA)=Ptey1*5J- z3pBV44Gp(!+g9}9!9lKsYX?rHrKKI?=3)(eeEg_>^d5~bKB=OiS55s`>$+F5{hm63 zeTKnc*s|`uTBmNE3RbT-zbNtB zY4x5^oOtY25p`Z1+T!PV09&oWp~I zH#nndPVL3FFH}Ub@_6swP|swo}R8*QNKhUwExR(XL!P= zzR>+k)!%OYJs+Gj8m?yXYV8NM#YagvHlpv&s3i!Q(XwbUf_l*ppRiycCy zUbzzTUiPziTh8y3{!@OjtzNL|l=kCe67wvozN~mM|NnO8U8gQhw)gh+p3l3-@QOm5 zX4j)`f7`DiD^{&CF)`uctWx;U_;Zp8)i2+^%oJn2 z+jQ5ue4hN4Uu?{34^}g>9Aj1bFz05DSxS0(a8OXw_1C-{RssdCfiK>^eR`x*xMJ@; z#jTQ(k|&*`|4p1S<)u#Srk+<>+^M2Vw`||~`PSo~5Nu*q$a^R?T1iz1G9qn>&B+PqXlKCCPoWkF;z*=bA}B zKR1_KW9A*x@`;w_led{(>43dy4c;FJv~PrmRu@b*?m2(zW320B@x$!YuEBFzW8Em)Y|_H zb0l>et%Zezn)b%&`z`-0^iRdkA_2T$Jz4 z{qyf)cWdbBIZawp=fKy_yf;q%jk>`r!-DRcIm;F=W}bh({OmOattzFdQ$uY&K0dx; z{rcaV%^d`0SQIL4-MZDp)bwH5?vFof&dfA!pEXM=tTtctyxn)1)6>_x2)M-L@vmC7 zV1-sYzw9ISXn8J<6Hki-B_$=FlxOv3EUM4XHJa&DQc|MeDP%XFfBI=xUteDSJLUR2 z%hxX1w~sGS#89et$+;Pg#~-Ku{`Pjp*|aTDy0WseCT3=z-tB(BNP}y0-rS@6ZGIMe z`OQ1@_S>Vcl^-i=cifFLGI};?qNTZl!t%?W85tS}wpL+ zthBs(^{PgfQ)sBD-t_J-UrNmG?vDFfVI$6&_~o;Ti>MMXz@dV5c9FiH@dkhA&b zA#SdJ8|n`K+NxXqeUJLzZ{PC;WMz39bWV3H;t;Tk(m#Cm;K75hFI~FS#LdMOAhOiH z`1WJ_w8O`0Y9_T@e|qRs{rgLAUa6X!^Sg#={Q1*gVJjE5=G4)L1qBKJ-Mxy7H!slW z5)l(qJ9hlIu&{8mil@}-t5WPX@Aab?vs68Qo!_+SQl_r1?qp+Q`(6!57+WP`1b2UN!fy%-#A{qjXa{_yLjQg zd6&~q6;{{m`F~ID`pd4OkkDM_y1RGp)^6Fo+nPCo!H2CUYONVlg_*-&zJ#|Q^}Flp zR&M?)?mbQCqPUpYqE%X)oSaV1&WEE{t+M0!()UC<*Kqb(!O3dAT%5eTqUrany5Crb zD{wJoT@-Jz{jU?4S=_PbaaoyHo(voF`qyr z@G=d4b-v={qGmHy6_qDno}HcjRaI40f`_fDx|)-VE9uRRjS{_XJ#Na0iHS9TJ|17U zXwjnXNh+xf+g{(%+I{WGAD+NJ7i?0!))=a*@7TS-A=kF-%u0_-(@a9|{=3D|{L0No zHQ)ePR_(LGYn^(O`Cf+kN@?XH$H(PPxt(Rym`|mlZOu1%)Twn$zklB< zyHcLAY86+L!ixLX?oJL{o%`>pe!Zl$jEs-3Z*SFu1B~16=H1u!ytJYF`h@Fi?yFVQ z*V^*6H#@iURh~L^>XnM;tvk<`{;Qs4;3T23P<-*CMIvj%ZgchQym-ouNr`Ww9ACnM zqN@yrixfEGSFM`GJLl8>V78;RF9kVySR^$#4%@IRS#0>zxPYD6o9W!I%ghJ)`I_&u zt1OUgJQDBZBk`a^m7!x{1K)Ige)j~6pFC` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/icons/cthulhu-splash.svg b/icons/cthulhu-splash.svg deleted file mode 100644 index 25dbb32..0000000 --- a/icons/cthulhu-splash.svg +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/icons/cthulhu-symbolic.svg b/icons/cthulhu-symbolic.svg deleted file mode 100644 index 29ce2d8..0000000 --- a/icons/cthulhu-symbolic.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - image/svg+xml - - Gnome Symbolic Icon Theme - - - - - - - Gnome Symbolic Icon Theme - - - - - - - - - - diff --git a/icons/meson.build b/icons/meson.build deleted file mode 100644 index 086876f..0000000 --- a/icons/meson.build +++ /dev/null @@ -1,53 +0,0 @@ -# Install icons in hicolor icon theme locations -install_data( - 'cthulhu-16x16.png', - rename: 'cthulhu.png', - install_dir: get_option('datadir') / 'icons' / 'hicolor' / '16x16' / 'apps' -) - -install_data( - 'cthulhu-22x22.png', - rename: 'cthulhu.png', - install_dir: get_option('datadir') / 'icons' / 'hicolor' / '22x22' / 'apps' -) - -install_data( - 'cthulhu-24x24.png', - rename: 'cthulhu.png', - install_dir: get_option('datadir') / 'icons' / 'hicolor' / '24x24' / 'apps' -) - -install_data( - 'cthulhu-32x32.png', - rename: 'cthulhu.png', - install_dir: get_option('datadir') / 'icons' / 'hicolor' / '32x32' / 'apps' -) - -install_data( - 'cthulhu-48x48.png', - rename: 'cthulhu.png', - install_dir: get_option('datadir') / 'icons' / 'hicolor' / '48x48' / 'apps' -) - -install_data( - 'cthulhu-256x256.png', - rename: 'cthulhu.png', - install_dir: get_option('datadir') / 'icons' / 'hicolor' / '256x256' / 'apps' -) - -install_data( - 'cthulhu-scalable.svg', - rename: 'cthulhu.svg', - install_dir: get_option('datadir') / 'icons' / 'hicolor' / 'scalable' / 'apps' -) - -install_data( - 'cthulhu-symbolic.svg', - install_dir: get_option('datadir') / 'icons' / 'hicolor' / 'symbolic' / 'apps' -) - -# Additional icons -install_data( - 'cthulhu-splash.svg', - install_dir: get_option('datadir') / 'cthulhu' / 'icons' -) \ No newline at end of file diff --git a/internal/app/app.go b/internal/app/app.go new file mode 100644 index 0000000..3a42dc9 --- /dev/null +++ b/internal/app/app.go @@ -0,0 +1,400 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "errors" + "log/slog" + "math/rand/v2" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/lifecycle" + "git.stormux.org/storm/cthulhu/internal/logging" + "git.stormux.org/storm/cthulhu/internal/platform/session" + "git.stormux.org/storm/cthulhu/internal/platform/wayland" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/sound" + "git.stormux.org/storm/cthulhu/internal/tentacle" + "git.stormux.org/storm/cthulhu/internal/wine" +) + +type Speaker interface { + Connect(context.Context) error + Speak(context.Context, string) error + Cancel(context.Context) error + Close(context.Context) error +} + +type Adapter interface { + Events() <-chan atspi.Event + Overflow() uint64 + CaptureDesktop(context.Context) (*atspi.AccessibleTree, error) + CaptureReviewWindow(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) + CaptureDocument(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) + CaptureDocumentText(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) + Start(context.Context) error + Stop(context.Context) error +} + +type speechEnqueuer interface { + Enqueue(speechRequest) + Interrupt() +} + +type soundService interface { + Start(context.Context) error + Stop(context.Context) error + Enqueue(sound.Cue) bool + EnqueueBatch([]sound.Cue) bool + Available(string) bool +} + +type soundSettingsUpdater interface { + Configure(sound.Configuration) +} + +type soundGeometryCaptureConfigurer interface { + SetCaptureSoundGeometry(bool) +} + +type textAttributeCaptureConfigurer interface { + SetCaptureTextAttributes(bool) +} + +func random_string(messages []string) string { + if len(messages) == 0 { + return "" + } + return messages[rand.IntN(len(messages))] +} + +type commandListener interface { + Commands() <-chan input.CommandEvent + LockStates() <-chan input.LockState + Failures() <-chan error + Start(context.Context) error + Stop(context.Context) error +} + +type foregroundMonitor interface { + Foreground() atspi.ForegroundState + ForegroundChanges() <-chan struct{} +} + +type xtermFocusMonitor interface { + FocusChanges() <-chan xorg.FocusState +} + +type Options struct { + TentacleFile string + TentacleRegistry string + TentacleCgroupParent string + EnableRemote bool + OpenPreferences bool + newCommands func() commandListener + onPreferences func() + newSound func() soundService + Logger *slog.Logger + SpeechSocket string + Settings *config.Settings + newSpeaker func() Speaker + newAdapter func() Adapter + newInput func() InputListener + onNotificationList func() + onSpeechHistory func() + onSpeechMonitor func() +} + +type InputListener interface { + Events() <-chan input.Event + ModifierKeycodes() input.ModifierKeycodes + Overflow() uint64 + Start(context.Context) error + Stop(context.Context) error +} + +const ( + caretDebounce = 150 * time.Millisecond + terminalMutationDebounce = 50 * time.Millisecond + objectReviewCaptureTimeout = 2 * time.Second + flatReviewCaptureTimeout = 10 * time.Second + documentCaptureTimeout = 15 * time.Second +) + +var startupMessages = []string{ + "Cthulhu welcomes you!", + "Face the thing that should not be!", + "The stars came right again.", +} + +var shutdownMessages = []string{ + "Cthulhu lurks beneath the waves!", + "He watches, lurking beneath the sea.", + "In his house at R’lyeh dead Cthulhu waits dreaming.", +} + +const ( + farewellTimeout = 2 * time.Second + shutdownTimeout = 3 * time.Second + soundStopTimeout = 3 * time.Second +) + +func Run(ctx context.Context, options Options) error { + ctx, stopRun := context.WithCancel(ctx) + defer stopRun() + logger := options.Logger + if logger == nil { + logger = logging.New(nil, logging.Options{}) + } + settings := config.DefaultSettings() + if options.Settings != nil { + settings = *options.Settings + } + if options.newAdapter == nil { + options.newAdapter = func() Adapter { + adapter := atspi.New() + adapter.SetCaptureLogger(logger) + return adapter + } + } + + if options.newCommands == nil { + if session.Wayland() { + keyboard := wayland.New(settings.CthulhuModifierKeys, input.KeyboardLayout(settings.KeyboardLayout), logger) + options.newCommands = func() commandListener { return keyboard } + if options.newInput == nil { + options.newInput = func() InputListener { return keyboard.Monitor() } + } + } else { + options.newCommands = func() commandListener { + return xorg.NewCommands(settings.CthulhuModifierKeys, input.KeyboardLayout(settings.KeyboardLayout)) + } + } + } + commands := options.newCommands() + if updater, ok := commands.(interface { + SetKeyBindings(context.Context, []input.BindingOverride) error + }); ok { + if err := updater.SetKeyBindings(ctx, settings.KeyBindings); err != nil { + return err + } + } + focusGate := newFocusGate(commands) + var focusChanges <-chan xorg.FocusState + if monitor, ok := commands.(xtermFocusMonitor); ok { + focusChanges = monitor.FocusChanges() + } + adapter := options.newAdapter() + if configurer, ok := adapter.(soundGeometryCaptureConfigurer); ok { + configurer.SetCaptureSoundGeometry(captureSoundGeometry(settings)) + } + if configurer, ok := adapter.(textAttributeCaptureConfigurer); ok { + configurer.SetCaptureTextAttributes(captureTextAttributes(settings)) + } + backends, err := newRuntimeBackends(&options, settings, logger, adapter) + if err != nil { + return err + } + speechOutput := backends.speechOutput + brailleOutput := backends.brailleOutput + focusGate.braille = brailleOutput + speechMessages := backends.speechMessages + history := backends.history + settingsUpdater := backends.settingsUpdater + inputListener := backends.inputListener + sounds := backends.sounds + services := backends.services + services = append(services, desktopInputService("commands", commands, logger)) + services = append(services, lifecycle.Service{Name: "atspi", Start: adapter.Start, Stop: adapter.Stop}) + var wineReview *wine.ReviewRegistry + if options.EnableRemote { + wineReview = wine.NewReviewRegistry(logger) + } + var wineCapture wineReviewCapturer + if wineReview != nil { + wineCapture = wineReview + } + objectReview, browser, reviewServices, err := newRuntimeReviewServices(logger, commands, adapter, inputListener, focusGate, speechOutput, speechMessages, brailleOutput, wineCapture) + if err != nil { + return err + } + services = append(services, reviewServices...) + live := &liveSettings{clipboardChanges: make(chan struct{}, 1), wineReview: wineReview} + if source, ok := adapter.(interface{ EditFieldFocused() bool }); ok { + live.editFieldFocused = source.EditFieldFocused + } + live.Store(settings) + if pointAdapter, ok := adapter.(pointReviewAdapter); ok { + services = append(services, mouseReviewService(logger, pointAdapter, + gatedSpeech{speech: speechOutput, gate: focusGate}, brailleOutput, live, focusGate)) + } + if speechMessages != nil { + speechMessages.capitalization = func() (bool, bool) { + settings := live.Load() + return settings.BeepForCapitals, settings.SayCapForCapitals + } + speechMessages.inputActivity = func() input.Activity { return recentInput(inputListener) } + speechMessages.reading = func() config.ReadingSettings { return live.Load().Reading } + speechMessages.verbosity = func() int { return live.Load().SpeechVerbosityLevel } + speechMessages.indentationCue = func(cue sound.Cue) { + if sounds != nil { + sounds.EnqueueBatch([]sound.Cue{cue}) + } + } + speechMessages.textTransform = func(text string) string { + settings := live.Load() + return pronunciationSpeechText(readingSpeechText(text, settings.Reading), settings.Pronunciations) + } + } + ocrSession := new_ocr_session(logger, commands, adapter, objectReview, speechOutput, speechMessages, brailleOutput, focusGate, live) + brailleOutput.ocr = ocrSession + brailleOutput.document = objectReview + focusGate.ocr = ocrSession + services = append(services, lifecycle.Service{Name: "OCR", Start: ocrSession.Start, Stop: ocrSession.Stop}) + var tentacles *tentacleRuntime + if options.TentacleFile != "" || options.TentacleRegistry != "" { + tentacles = newTentacleRuntime(logger, commands, options.TentacleFile, options.TentacleCgroupParent) + if options.TentacleFile == "" { + tentacles.registry = &tentacle.Registry{Path: options.TentacleRegistry} + tentacles.requests = make(chan tentacleManagementCall, 16) + tentacles.snapshot.Message = "Loading tentacle configuration." + } + tentacles.output = &tentacleOutput{speech: speechMessages, braille: brailleOutput, gate: focusGate, live: live} + focusGate.tentacleOutput = tentacles.output + services = append(services, lifecycle.Service{Name: "tentacles", Start: tentacles.Start, Stop: tentacles.Stop}) + } + preferences := newPreferencesWorker(logger, settings, settingsUpdater) + preferences.tentacles = tentacles + if tentacles != nil { + tentacles.readerSettings = preferences + } + preferences.live = live + live.onApplication = preferences.SetApplication + preferences.bindings, _ = commands.(interface { + SetKeyBindings(context.Context, []input.BindingOverride) error + }) + preferences.history = history + preferences.speechWorker = speechMessages + preferences.braille = brailleOutput + preferences.documentReview = objectReview + objectReview.SetDocumentBrailleEnabled(settings.EnableBraille) + if updater, ok := sounds.(soundSettingsUpdater); ok { + preferences.sound = updater + } + if configurer, ok := adapter.(soundGeometryCaptureConfigurer); ok { + preferences.geometry = configurer + } + if configurer, ok := adapter.(textAttributeCaptureConfigurer); ok { + preferences.textAttributes = configurer + } + preferences.socket = options.SpeechSocket + if options.onPreferences == nil { + options.onPreferences = preferences.Open + } + openPreferences := options.onPreferences + options.onPreferences = func() { + ocrSession.Retire() + openPreferences() + } + preferences.announce = func(message string) { + speechOutput.Enqueue(speechRequest{Text: message, Role: "system", Cause: "speech-setting"}) + brailleOutput.EnqueueMessage(message) + } + preferences.announceApply = func(message string) { + speechOutput.Enqueue(speechRequest{Text: message, Role: "system", Cause: "preferences-applied", Confirmation: true}) + brailleOutput.FlashConfirmation(message, live.Load().Braille) + } + preferences.announceEchoPreview = func(label, value string) { + speechOutput.Enqueue(echo_preview_speech(label, value)) + } + services = append(services, lifecycle.Service{Name: "preferences", Start: preferences.Start, Stop: preferences.Stop}) + + notifications, onNotificationList, notificationServices := newNotificationRuntime(logger, speechOutput, brailleOutput, live, options.onNotificationList) + options.onNotificationList = onNotificationList + services = append(services, notificationServices...) + if history != nil && (options.onSpeechHistory == nil || options.onSpeechMonitor == nil) { + windows := newSpeechHistoryWindows(logger, history, outputQueue{ + speech: gatedSpeech{speech: speechOutput, gate: focusGate}, + braille: brailleOutput, live: live, + }, focusGate) + if options.onSpeechHistory == nil { + options.onSpeechHistory = windows.Open + } + preferences.refreshHistory = windows.Refresh + if options.onSpeechMonitor == nil { + options.onSpeechMonitor = windows.ToggleMonitor + } + services = append(services, lifecycle.Service{Name: "speech history", Start: windows.Start, Stop: windows.Stop}) + } + if options.EnableRemote { + services = append(services, newRemoteRuntimeServices(remoteServiceDependencies{ + logger: logger, stopRun: stopRun, adapter: adapter, inputListener: inputListener, + speech: speechMessages, braille: brailleOutput, live: live, + preferences: preferences, onPreferences: options.onPreferences, + })...) + } + runner, err := lifecycle.NewWithLogger(logger, services...) + if err != nil { + return err + } + if err := runner.Start(ctx); err != nil { + return err + } + if settings.EnableBraille { + if err := brailleOutput.Start(); err != nil { + logger.Warn("start braille", "error", err) + } + } + if options.OpenPreferences && options.onPreferences != nil { + options.onPreferences() + } + + presentationOptions := presentationSettingsFromConfig(settings, true) + presentationOptions.SoundCueAvailable = sounds.Available + if soundConfiguration(settings).Enabled { + sounds.Enqueue(sound.Cue{Name: "start"}) + } + if speechMessages != nil && !focusGate.Locked() { + speechMessages.EnqueueStartup(speechRequest{Text: random_string(startupMessages), Role: "system", Cause: "startup"}) + } + commandWorker := commandRuntime{ + logger: logger, commands: commands, focusChanges: focusChanges, focusGate: focusGate, + speechMessages: speechMessages, speechOutput: speechOutput, + browser: browser, preferences: preferences, live: live, + onPreferences: options.onPreferences, onSpeechHistory: options.onSpeechHistory, + onSpeechMonitor: options.onSpeechMonitor, onNotificationList: options.onNotificationList, + tentacles: tentacles, ocr: ocrSession, objectReview: objectReview, notifications: notifications, stopRun: stopRun, + } + commandWorker.actionSource, _ = adapter.(accessibleActionSource) + workers := startRuntimeWorkers(ctx, commandWorker, inputListener, settings, backends.copyChanges, brailleOutput) + var eventInput any = inputListener + if browser != nil { + eventInput = browser + } + runError := processEventsWithAttributes(ctx, logger, outputQueue{speech: gatedSpeech{speech: speechOutput, gate: focusGate}, sounds: sounds, braille: brailleOutput, live: live}, adapter, workers.reviewRequests, workers.attributeRequests, objectReview, caretDebounce, live, eventInput, focusGate, notifications, ocrSession, presentationOptions) + stopError := stopRuntime(runtimeShutdown{ + logger: logger, cancel: stopRun, workers: workers, + tentacles: tentacles, ocr: ocrSession, preferences: preferences, braille: brailleOutput, speech: speechMessages, + focusGate: focusGate, services: runner, + }) + return errors.Join(runError, workers.commandError, stopError) +} diff --git a/internal/app/app_test.go b/internal/app/app_test.go new file mode 100644 index 0000000..3daef49 --- /dev/null +++ b/internal/app/app_test.go @@ -0,0 +1,117 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +func TestRunSpeaksFocusEventsAndStops(t *testing.T) { + speaker := &fakeSpeaker{spoken: make(chan string, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + inputListener := &fakeInputListener{ + events: make(chan input.Event, 1), + modifierKeycodes: input.NewModifierKeycodes(37), + } + ctx, cancel := context.WithCancel(context.Background()) + + completed := make(chan error, 1) + go func() { + completed <- Run(ctx, Options{ + Logger: slog.New(slog.DiscardHandler), + newSpeaker: func() Speaker { return speaker }, + newCommands: func() commandListener { return silentCommands{} }, + newSound: func() soundService { return silentSound{} }, + newAdapter: func() Adapter { return adapter }, + newInput: func() InputListener { return inputListener }, + }) + }() + + adapter.events <- atspi.NewEvent("focus:", atspi.NewSnapshot("/accessible/save", "Save", "push button", "", "")) + for index, expected := range []string{"", "Save", "push button"} { + select { + case text := <-speaker.spoken: + if index == 0 { + if !contains_string(startupMessages, text) { + t.Fatalf("startup speech = %q, want one of %q", text, startupMessages) + } + continue + } + if text != expected { + t.Fatalf("spoken text = %q, want %q", text, expected) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for %q", expected) + } + } + + cancel() + select { + case err := <-completed: + if err != nil { + t.Fatalf("Run: %v", err) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for Run to stop") + } + select { + case text := <-speaker.spoken: + if !contains_string(shutdownMessages, text) { + t.Fatalf("shutdown speech = %q, want one of %q", text, shutdownMessages) + } + default: + t.Fatal("shutdown message was not spoken") + } + if !adapter.stopped || !speaker.closed || !speaker.canceledOnClose { + t.Fatal("runtime did not stop both services") + } + if !inputListener.started || !inputListener.stopped { + t.Fatal("runtime did not run the X11 listener lifecycle") + } +} + +func (silentSound) Start(context.Context) error { return nil } + +func (silentSound) Stop(context.Context) error { return nil } + +func (silentSound) Enqueue(sound.Cue) bool { return true } + +func (silentSound) EnqueueBatch([]sound.Cue) bool { return true } + +func (silentSound) Available(string) bool { return true } + +func (rejectingSound) Enqueue(sound.Cue) bool { return false } + +func (rejectingSound) EnqueueBatch([]sound.Cue) bool { return false } + +func (silentCommands) Commands() <-chan input.CommandEvent { return nil } + +func (silentCommands) LockStates() <-chan input.LockState { return nil } + +func (silentCommands) Failures() <-chan error { return nil } + +func (silentCommands) Start(context.Context) error { return nil } + +func (silentCommands) Stop(context.Context) error { return nil } diff --git a/internal/app/application_behavior.go b/internal/app/application_behavior.go new file mode 100644 index 0000000..db52251 --- /dev/null +++ b/internal/app/application_behavior.go @@ -0,0 +1,60 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import "git.stormux.org/storm/cthulhu/internal/atspi" + +type applicationEventResult struct { + event atspi.Event + adoptFocus bool + suppress bool + resetPresentation bool +} + +// prepareApplicationEvent runs after security/foreground checks and before +// generic focus and text filters. Application policy receives copied semantics; +// the reader retains ownership, review, cancellation, and output services. +// Application-specific state stays on the event loop with an explicit focus +// lifetime, rather than hidden in native callbacks. +func (handler *accessibilityEventHandler) prepareApplicationEvent(event atspi.Event) (atspi.Event, bool) { + result := applicationEventResult{event: event} + if atspi.IsLibreOfficeProcess(event.Source.ApplicationProcess) { + result = prepareLibreOfficeEvent(event, handler.state.current, handler.state.owner) + } + if !result.suppress || event.Type == atspi.SelectionChangedEvent { + handler.handleLibreOfficeSelection(result.event) + } + if result.adoptFocus { + if handler.focusGate.Suspended() { + return event, false + } + state := handler.state + if !state.owner.follow(result.event) { + return event, true + } + state.pending.caret.clear() + state.focusedID = result.event.Source.ID() + state.current = result.event.Source + state.managedContainerID, state.managedDescendantID = atspi.ObjectID{}, atspi.ObjectID{} + if result.event.Source.Role != "table" && result.event.Source.Role != "table cell" { + // A late-created editor has no ordinary focus event to reset + // row history. Returning to its old cell is a fresh focus. + state.lastTable, state.lastTableCell = atspi.ObjectID{}, atspi.ObjectID{} + } + state.selection.reset(result.event.Source) + if handler.objectReview != nil { + handler.objectReview.SyncFocus(result.event.Source.ID()) + } + } + if result.resetPresentation { + handler.state.pending.caret.clear() + handler.state.lastSpokenPath, handler.state.lastSpokenText, handler.state.lastSound = "", "", "" + } + if result.suppress { + handler.logger.Debug("skipped application-specific accessibility event", "type", event.Type, + "application_process", event.Source.ApplicationProcess, "role", event.Source.Role) + } + return result.event, result.suppress +} diff --git a/internal/app/application_focus_test.go b/internal/app/application_focus_test.go new file mode 100644 index 0000000..57fddaf --- /dev/null +++ b/internal/app/application_focus_test.go @@ -0,0 +1,61 @@ +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestAcceptedApplicationFocusPublishesSettingsIdentity(t *testing.T) { + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + speech := &fakeSpeechQueue{spoken: make(chan string, 4)} + applications := make(chan string, 4) + live := &liveSettings{onApplication: func(name string) { applications <- name }} + live.Store(config.DefaultSettings()) + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + _ = processEventsWithInput(ctx, slog.New(slog.DiscardHandler), speech, adapter, nil, nil, 0, live, nil, nil, nil) + close(done) + }() + defer func() { cancel(); <-done }() + frame := atspi.NewSnapshot("/first/window", "First", "frame", "", "") + frame.BusName, frame.ApplicationName = ":1.41", "First Editor" + activated := atspi.NewEvent(atspi.WindowActivatedEvent, frame) + activated.Window = frame.ID() + adapter.events <- activated + select { + case name := <-applications: + if name != "First Editor" { + t.Fatalf("application = %q", name) + } + case <-time.After(time.Second): + t.Fatal("accepted window did not publish application") + } + background := atspi.NewSnapshot("/background/window", "Background", "frame", "", "") + background.BusName, background.ApplicationName = ":1.42", "Background Editor" + ignored := atspi.NewEvent(atspi.FocusedStateEvent, background) + ignored.Window, ignored.Detail1 = background.ID(), 1 + adapter.events <- ignored + select { + case name := <-applications: + t.Fatalf("background focus published %q", name) + case <-time.After(30 * time.Millisecond): + } + background.Focused = true + focused := atspi.NewEvent(atspi.FocusedStateEvent, background) + focused.Window, focused.Detail1 = background.ID(), 1 + adapter.events <- focused + select { + case name := <-applications: + if name != "Background Editor" { + t.Fatalf("foreground application = %q", name) + } + case <-time.After(time.Second): + t.Fatal("accepted focus did not publish new application") + } +} diff --git a/internal/app/autocomplete.go b/internal/app/autocomplete.go new file mode 100644 index 0000000..8aa50d6 --- /dev/null +++ b/internal/app/autocomplete.go @@ -0,0 +1,94 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" +) + +// Inline completions are selected by the browser. Echo the inserted portion +// outside that selection; it contains the user's edit, not the suggested suffix. +func autocompleteInsertion(event atspi.Event) string { + text := []rune(event.Payload) + start, end := event.Source.SelectionStart, event.Source.SelectionEnd + if end <= start || end <= event.Detail1 || start >= event.Detail1+len(text) { + return event.Payload + } + left := max(0, start-event.Detail1) + right := min(len(text), end-event.Detail1) + return string(text[:left]) + string(text[right:]) +} + +func recentInput(source any) input.Activity { + if provider, ok := source.(interface{ RecentInput() input.Activity }); ok { + return provider.RecentInput() + } + return input.Activity{} +} + +type autocompleteEcho struct { + sequence uint64 + source atspi.ObjectID +} + +// autocompleteAvailability presents the selected address when it changes. +// Chromium can send several insertion and popup events for the same suggestion. +type autocompleteAvailability struct { + entry atspi.ObjectID + lastAddress string +} + +func supportsAutocomplete(snapshot atspi.Snapshot) bool { + return snapshot.Autocomplete || snapshot.Role == "autocomplete" +} + +func (availability *autocompleteAvailability) focus(event atspi.Event) { + if !isFocusGainEvent(event) || event.Source.AutocompletePopup { + return + } + entry := atspi.ObjectID{} + if supportsAutocomplete(event.Source) { + entry = event.Source.ID() + } + if entry != availability.entry { + availability.entry = entry + availability.lastAddress = "" + } +} + +func (availability *autocompleteAvailability) offered(event atspi.Event, activity input.Activity) string { + if !availability.entry.Valid() || event.Type != atspi.TextInsertedEvent || + !supportsAutocomplete(event.Source) || event.Source.ID() != availability.entry || + (activity.Intent != input.TypingIntent && activity.Intent != input.DeleteIntent) { + return "" + } + address := strings.TrimSpace(event.Source.Text) + if event.Source.SelectionEnd <= event.Source.SelectionStart || + event.Source.SelectionEnd > len([]rune(address)) || address == "" || + address == availability.lastAddress { + return "" + } + availability.lastAddress = address + return address +} + +func (echo *autocompleteEcho) insertion(event atspi.Event, activity input.Activity) string { + text := autocompleteInsertion(event) + if text == "" && activity.Sequence != 0 && + (activity.Sequence != echo.sequence || event.Source.ID() != echo.source) && + event.Detail1 == event.Source.SelectionStart { + // Chromium can retain an unchanged typed prefix and emit only a replacement + // of the selected suffix. Recover that character from accessible text once + // for this key press; a normal insertion already covers the other case. + text = event.Source.CompletionPrefixCharacter + } + if text != "" { + echo.sequence, echo.source = activity.Sequence, event.Source.ID() + } + return text +} diff --git a/internal/app/braille_context.go b/internal/app/braille_context.go new file mode 100644 index 0000000..2c01cdf --- /dev/null +++ b/internal/app/braille_context.go @@ -0,0 +1,76 @@ +package app + +import ( + "strings" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" +) + +// Python includes context at the first line of text areas and omits desktop +// ancestry within web documents. Verbosity changes roles, not group labels. +func braille_context_frame(frame braille.Frame, snapshot atspi.Snapshot, options config.BrailleOptions) braille.Frame { + if snapshot.Role == "terminal" || snapshot.TextCaretKnown && snapshot.BrailleLineStart > 0 { + return frame + } + for _, ancestor := range snapshot.BrailleContext { + if atspi.IsWebDocumentRole(ancestor.Role) { + return frame + } + } + parts := []string{} + groupSkipped := false + ancestors := snapshot.BrailleContext + if len(ancestors) > 0 { + switch ancestors[0].Role { + case "menu", "menu bar", "page tab list", "redundant object", "unknown", "combo box": + ancestors = ancestors[1:] + } + } + for index := len(ancestors) - 1; index >= 0; index-- { + ancestor := ancestors[index] + if ancestor.ID().Valid() && ancestor.ID() == snapshot.ID() { + continue + } + switch ancestor.Role { + case "invalid", "unknown", "redundant object", "section", "split pane", "desktop frame", "scroll pane", "viewport": + continue + case "panel", "filler", "grouping": + if strings.TrimSpace(ancestor.Name) == "" { + continue + } + if snapshot.Role == "radio button" && ancestor.Name == snapshot.RadioGroupName && !groupSkipped { + groupSkipped = true + continue + } + } + if ancestor.Role == "table" && ancestor.LayoutTable { + continue + } + text := braille_object_frame(ancestor, options).Text + if text != "" { + parts = append(parts, text) + } + } + parts = append(parts, snapshot.TableRowHeaders, snapshot.TableColumnHeaders, snapshot.RadioGroupName) + prefix := brailleJoin(parts...) + if prefix == "" { + return frame + } + prefix += " " + shift := utf8.RuneCountInString(prefix) + frame.Text = prefix + frame.Text + if frame.Cursor >= 0 { + frame.Cursor += shift + } + if len(frame.Dots) != 0 { + frame.Dots = append(make([]byte, shift), frame.Dots...) + } + for index := range frame.Routes { + frame.Routes[index].Start += shift + frame.Routes[index].End += shift + } + return frame +} diff --git a/internal/app/braille_context_test.go b/internal/app/braille_context_test.go new file mode 100644 index 0000000..fab0c8c --- /dev/null +++ b/internal/app/braille_context_test.go @@ -0,0 +1,99 @@ +package app + +import ( + "reflect" + "testing" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestBrailleContextVerbosityAndRoutingOffsets(t *testing.T) { + options := config.DefaultSettings().Braille + source := atspi.Snapshot{BusName: ":1.42", Path: "/entry", Role: "entry", Name: "Title", TextCaretKnown: true, + BrailleLine: "é猫", BrailleCaret: 1, SelectionStart: 0, SelectionEnd: 1, + BrailleContext: []atspi.Snapshot{{Role: "panel", Name: "Details"}, {Role: "dialog", Name: "Properties"}, {Role: "application", Name: "Editor"}}} + for _, test := range []struct { + verbosity int + prefix string + }{ + {1, "Editor application Properties dialog Details panel "}, + {0, "Editor Properties Details "}, + } { + options.Verbosity = test.verbosity + frame := brailleFocusFrameWithOptions(source, options) + shift := utf8.RuneCountInString(test.prefix) + 6 + if frame.Text != test.prefix+"Title é猫 $l" || frame.Cursor != shift+1 || len(frame.Routes) != 1 || frame.Routes[0].Start != shift || frame.Dots[shift] != byte(options.SelectionIndicator) { + t.Fatalf("verbosity %d = %+v", test.verbosity, frame) + } + } + options.Verbosity, options.AbbreviateRoles = 1, true + if frame := brailleFocusFrameWithOptions(source, options); frame.Text != "Editor app Properties dlg Details pnl Title é猫 $l" { + t.Fatalf("abbreviated context = %q", frame.Text) + } + source.BrailleLineStart, source.BrailleCaret = 4, 5 + if frame := brailleFocusFrameWithOptions(source, options); frame.Text != "Title é猫 $l" { + t.Fatalf("later line repeats context: %+v", frame) + } + source.BrailleContext = append(source.BrailleContext, atspi.Snapshot{Role: "document web"}) + source.BrailleLineStart, source.BrailleCaret = 0, 1 + if frame := brailleFocusFrameWithOptions(source, options); frame.Text != "Title é猫 $l" { + t.Fatalf("web text includes desktop ancestry: %+v", frame) + } + options.SelectionIndicator, options.LinkIndicator = 0x40, 0x80 + source.Role, source.Name = "static", "é猫" + source.BrailleContext = []atspi.Snapshot{{Role: "link"}, {Role: "document web"}} + if frame := brailleFocusFrameWithOptions(source, options); frame.Text != "é猫 $l" || frame.Dots[0] != 0xc0 || frame.Dots[1] != 0x80 || frame.Dots[2] != 0 { + t.Fatalf("native browse link selection = %+v", frame) + } +} + +func TestBrailleContextHeadersGroupsAndBriefRoles(t *testing.T) { + options := config.DefaultSettings().Braille + options.Verbosity = 0 + radio := atspi.Snapshot{Role: "radio button", Name: "Brief", RadioGroupName: "Verbosity", BrailleContext: []atspi.Snapshot{{Role: "panel", Name: "Verbosity"}}} + if frame := brailleFocusFrameWithOptions(radio, options); frame.Text != "Verbosity & y Brief" { + t.Fatalf("radio group = %q", frame.Text) + } + cell := atspi.Snapshot{Role: "table cell", Name: "10", TableRowHeaders: "January", TableColumnHeaders: "Total"} + if frame := brailleFocusFrameWithOptions(cell, options); frame.Text != "January Total 10" { + t.Fatalf("table headers = %q", frame.Text) + } + if frame := brailleFocusFrameWithOptions(atspi.Snapshot{Role: "button"}, options); frame.Text != "" { + t.Fatalf("brief unnamed role = %q", frame.Text) + } + if frame := brailleFocusFrameWithOptions(atspi.Snapshot{Role: "heading", Name: "Title", HeadingLevel: 2}, options); frame.Text != "Title h2" { + t.Fatalf("brief heading = %q", frame.Text) + } +} + +func TestBrowseBrailleMapsInlineSelectionsAndLinkDots(t *testing.T) { + options := config.DefaultSettings().Braille + options.SelectionIndicator, options.LinkIndicator = 0x40, 0x80 + first := atspi.Snapshot{BusName: ":1.42", Path: "/first", Role: "static", SelectionStart: 1, SelectionEnd: 2} + second := atspi.Snapshot{BusName: ":1.42", Path: "/second", Role: "static", SelectionStart: 7, SelectionEnd: 10, BrailleContext: []atspi.Snapshot{{Role: "link"}}} + doc := atspi.Snapshot{BusName: first.BusName, Path: "/document", Role: "document web"} + tree, err := atspi.NewAccessibleTree(doc.ID(), []atspi.TreeNode{{Snapshot: doc, Children: []atspi.ObjectID{first.ID(), second.ID()}}, {Snapshot: first}, {Snapshot: second}}) + if err != nil { + t.Fatal(err) + } + docRef, _ := tree.Reference(doc.ID()) + result := review.Result{DocumentEpoch: 3, DocumentFocus: doc.ID(), DocumentPosition: review.DocumentPosition{Document: docRef, Snapshot: second, Offset: 8}, + DocumentCaretLine: &atspi.DocumentLine{Contents: []atspi.DocumentContent{{Snapshot: first, Start: 0, End: 2, RawText: "é猫"}, {Snapshot: second, Start: 7, End: 11, RawText: "word", Separator: " "}}}} + frame := brailleDocumentFrame(result, options) + if frame.Text != "é猫 word" || frame.Cursor != 4 || frame.Document == nil || frame.Document.Epoch != 3 || len(frame.Routes) != 2 || frame.Routes[1].SourceStart != 7 || frame.Routes[1].Start != 3 { + t.Fatalf("inline frame = %+v", frame) + } + if !reflect.DeepEqual(frame.Dots, []byte{0, 0x40, 0, 0xc0, 0xc0, 0xc0, 0x80}) { + t.Fatalf("inline dots = %v", frame.Dots) + } + result.DocumentCaretLine = nil + result.DocumentBrailleLine = &atspi.DocumentCaretText{Start: 7, Text: "word\n", SelectionStart: 8, SelectionEnd: 10} + result.DocumentPosition.Offset = 11 + frame = brailleDocumentFrame(result, options) + if frame.Text != "word " || frame.Cursor != 4 || frame.Routes[0].End != 5 || frame.Routes[0].TextLength != 4 { + t.Fatalf("end cursor route = %+v", frame) + } +} diff --git a/internal/app/braille_frames.go b/internal/app/braille_frames.go new file mode 100644 index 0000000..019f6dc --- /dev/null +++ b/internal/app/braille_frames.go @@ -0,0 +1,299 @@ +package app + +import ( + "context" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" +) + +func (worker *brailleWorker) Enqueue(text string) { + worker.EnqueueFrame(braille.Frame{Text: text, Cursor: -1}) +} + +func (worker *brailleWorker) EnqueueMessage(text string) bool { + if text == "" || len(text) > 10000 { + return false + } + worker.mu.Lock() + if !worker.connected { + worker.mu.Unlock() + return false + } + queued := worker.enqueueFrameLocked(braille.Frame{Text: text, Cursor: -1, WordWrap: worker.wordWrap}, true) + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } + return queued +} + +func (worker *brailleWorker) EnqueueFrame(frame braille.Frame) { + worker.enqueueFrame(frame, true) +} + +// SetInternalUIFrame temporarily owns presentation while normal focus frames +// continue updating the base. Closing restores the newest application frame. +func (worker *brailleWorker) SetInternalUIFrame(frame *braille.Frame) { + worker.mu.Lock() + if worker.flashTimer != nil { + worker.flashTimer.Stop() + worker.flashTimer = nil + } + worker.flashGeneration++ + worker.flashContext = nil + worker.protectedFlash = false + worker.internalUIFrame = nil + next := worker.baseFrame + if frame != nil { + next = *frame + next.WordWrap = worker.wordWrap + if len(next.Text) > 10000 { + next.Text = next.Text[:10000] + for !utf8.ValidString(next.Text) { + next.Text = next.Text[:len(next.Text)-1] + } + if next.Cursor >= utf8.RuneCountInString(next.Text) { + next.Cursor = -1 + } + } + } + queued := worker.enqueueFrameLocked(next, false) + if frame != nil { + copy := *frame + worker.internalUIFrame = © + } + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } +} + +func (worker *brailleWorker) enqueueFrame(frame braille.Frame, base bool) { + // JSON escaping can expand a frame; keep it below the helper's 64 KiB + // scanner limit even when every byte needs escaping. + if len(frame.Text) > 10000 { + frame.Text = frame.Text[:10000] + for !utf8.ValidString(frame.Text) { + frame.Text = frame.Text[:len(frame.Text)-1] + } + if frame.Cursor > utf8.RuneCountInString(frame.Text) { + frame.Cursor = -1 + } + if len(frame.Dots) > utf8.RuneCountInString(frame.Text) { + frame.Dots = frame.Dots[:utf8.RuneCountInString(frame.Text)] + } + } + worker.mu.Lock() + queued := worker.enqueueFrameLocked(frame, base) + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } +} + +// enqueueFrameLocked must run under mu so flash, focus and timer restoration +// cannot reorder their frames. +func (worker *brailleWorker) enqueueFrameLocked(frame braille.Frame, base bool) bool { + if worker.secure { + return false + } + return worker.enqueueSecureFrameLocked(frame, base) +} + +func (worker *brailleWorker) enqueueSecureFrameLocked(frame braille.Frame, base bool) bool { + if worker.internalUIFrame != nil { + if base { + worker.baseFrame = frame + } + return false + } + if worker.cancel == nil || worker.stopping { + return false + } + if base { + worker.flashContext = nil + if worker.protectedFlash { + worker.baseFrame = frame + return false + } + worker.flashGeneration++ + if worker.flashTimer != nil { + worker.flashTimer.Stop() + worker.flashTimer = nil + } + worker.baseFrame = frame + } + frame.Contract = worker.contracted + frame.Table = worker.table + frame.ExpandAtCursor = frame.Cursor >= 0 && len(frame.Routes) > 0 + worker.sequence++ + frame.ID = worker.sequence + frame.Routes = append([]braille.TextRoute(nil), frame.Routes...) + frame.Dots = append([]byte(nil), frame.Dots...) + if worker.routeCancel != nil { + worker.routeCancel() + } + worker.frame = frame + return true +} + +func (worker *brailleWorker) wakeDisplay() { + select { + case worker.wake <- struct{}{}: + default: + } +} + +func (worker *brailleWorker) Flash(text string, options config.BrailleOptions) bool { + return worker.flash_message(text, options, false) +} + +// Confirmation flashes survive the automatic focus change caused by Apply/OK. +// Normal flashes keep their existing focus-replacement behavior. +func (worker *brailleWorker) FlashConfirmation(text string, options config.BrailleOptions) bool { + return worker.flash_message(text, options, true) +} + +func (worker *brailleWorker) flash_message(text string, options config.BrailleOptions, confirmation bool) bool { + return worker.flash_message_guarded(text, options, confirmation, nil, 0) +} + +func (worker *brailleWorker) flash_message_guarded(text string, options config.BrailleOptions, confirmation bool, owner context.Context, sequence uint64) bool { + if text == "" || !options.FlashMessages { + return false + } + if len(text) > 10000 { + text = text[:10000] + for !utf8.ValidString(text) { + text = text[:len(text)-1] + } + } + worker.mu.Lock() + if worker.internalUIFrame != nil { + worker.mu.Unlock() + return false + } + if owner != nil && (owner.Err() != nil || worker.sequence != sequence) { + worker.mu.Unlock() + return false + } + if worker.cancel == nil || worker.stopping || !worker.connected || worker.secure { + worker.mu.Unlock() + return false + } + worker.flashGeneration++ + worker.flashContext = owner + worker.protectedFlash = confirmation + generation := worker.flashGeneration + if worker.flashTimer != nil { + worker.flashTimer.Stop() + } + queued := worker.enqueueFrameLocked(braille.Frame{Text: text, Cursor: -1, WordWrap: options.WordWrap}, false) + if !options.FlashPersistent && options.FlashTime > 0 { + worker.flashTimer = time.AfterFunc(time.Duration(options.FlashTime)*time.Millisecond, func() { + worker.mu.Lock() + if worker.flashGeneration != generation { + worker.mu.Unlock() + return + } + worker.flashTimer = nil + worker.flashContext = nil + worker.protectedFlash = false + queued := worker.enqueueFrameLocked(worker.baseFrame, false) + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } + }) + } + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } + return true +} + +func (worker *brailleWorker) DismissConfirmation() { + worker.mu.Lock() + if !worker.protectedFlash { + worker.mu.Unlock() + return + } + worker.protectedFlash = false + worker.flashGeneration++ + if worker.flashTimer != nil { + worker.flashTimer.Stop() + worker.flashTimer = nil + } + queued := worker.enqueueFrameLocked(worker.baseFrame, false) + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } +} + +func (worker *brailleWorker) SetContraction(enabled bool, table string) { + worker.mu.Lock() + worker.contracted, worker.table = enabled, table + frame := worker.frame + running := worker.cancel != nil && !worker.stopping + queued := false + if running { + queued = worker.enqueueFrameLocked(frame, false) + } + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } +} + +func (worker *brailleWorker) SetWordWrap(enabled bool) { + worker.mu.Lock() + if worker.wordWrap == enabled { + worker.mu.Unlock() + return + } + worker.wordWrap = enabled + worker.baseFrame.WordWrap = enabled + frame := worker.frame + frame.WordWrap = enabled + queued := worker.enqueueFrameLocked(frame, false) + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } +} + +func (worker *brailleWorker) current() braille.Frame { + worker.mu.Lock() + defer worker.mu.Unlock() + if worker.flashContext != nil && worker.flashContext.Err() != nil { + worker.retirePresentationLocked(worker.flashContext) + } + return worker.frame +} + +func (worker *brailleWorker) retirePresentationLocked(owner context.Context) bool { + if worker.flashContext != owner { + return false + } + worker.flashContext = nil + worker.flashGeneration++ + if worker.flashTimer != nil { + worker.flashTimer.Stop() + worker.flashTimer = nil + } + return worker.enqueueFrameLocked(worker.baseFrame, false) +} + +func (worker *brailleWorker) retirePresentation(owner context.Context) { + worker.mu.Lock() + queued := worker.retirePresentationLocked(owner) + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } +} diff --git a/internal/app/braille_helper_test.go b/internal/app/braille_helper_test.go new file mode 100644 index 0000000..2b0fbc7 --- /dev/null +++ b/internal/app/braille_helper_test.go @@ -0,0 +1,104 @@ +package app + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "os" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/logging" +) + +// The test executable doubles as a real pipe-protocol peer. Only the explicit +// child invocation takes this path; the parent runs the ordinary test suite. +func TestMain(m *testing.M) { + if os.Getenv("CTHULHU_BRAILLE_TEST_FAIL") == "1" && len(os.Args) == 2 && os.Args[1] == "--client" { + fmt.Fprintln(os.Stderr, "braille test startup failure") + os.Exit(1) + } + if os.Getenv("CTHULHU_BRAILLE_TEST_CLIENT") == "1" && len(os.Args) == 2 && os.Args[1] == "--client" { + fmt.Println("ready") + decoder, encoder := json.NewDecoder(os.Stdin), json.NewEncoder(os.Stdout) + for { + var frame braille.Frame + if err := decoder.Decode(&frame); err != nil { + os.Exit(0) + } + if frame.Text != "" { + if err := encoder.Encode(braille.RoutingEvent{ID: frame.ID, Offset: 1}); err != nil { + os.Exit(1) + } + } + } + } + os.Exit(m.Run()) +} + +func TestBrailleWorkerReportsHelperStartupFailure(t *testing.T) { + t.Setenv("CTHULHU_BRAILLE_TEST_FAIL", "1") + path, err := os.Executable() + if err != nil { + t.Fatal(err) + } + worker := &brailleWorker{path: path, logger: slog.New(slog.DiscardHandler)} + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := worker.session(ctx); err == nil || !strings.Contains(err.Error(), "braille test startup failure") { + t.Fatalf("helper startup error = %v", err) + } +} + +func TestBrailleWorkerHelperProtocolAndRestart(t *testing.T) { + t.Setenv("CTHULHU_BRAILLE_TEST_CLIENT", "1") + path, err := os.Executable() + if err != nil { + t.Fatal(err) + } + router := &recordingBrailleRouter{calls: make(chan atspi.BrailleRoute, 8)} + var output bytes.Buffer + worker := &brailleWorker{path: path, router: router, logger: logging.New(&output, logging.Options{Level: slog.LevelDebug}), wake: make(chan struct{}, 1)} + stop := func() { + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := worker.Stop(ctx); err != nil { + t.Errorf("stop helper: %v", err) + } + } + defer stop() + for attempt := 0; attempt < 2; attempt++ { + if err := worker.Start(); err != nil { + t.Fatal(err) + } + worker.EnqueueFrame(braille.Frame{Text: "é猫", Cursor: 0, Routes: []braille.TextRoute{{Start: 0, End: 2, TextLength: 2, SourceStart: 10, BusName: ":1.42", Path: "/entry", SourceText: "é猫"}}}) + select { + case route := <-router.calls: + if route.Offset != 11 || route.Focus.Path != "/entry" { + t.Fatalf("route %+v", route) + } + case <-time.After(3 * time.Second): + t.Fatal("helper route was not delivered") + } + stop() + // Stop joins the writer before inspecting its debug output. + for _, expected := range []string{`"message":"sent braille frame"`, `"braille_text":"é猫"`, `"cursor_offset":0`} { + if !strings.Contains(output.String(), expected) { + t.Fatalf("braille diagnostics missing %s: %s", expected, output.String()) + } + } + // A duplicate send can be coalesced by either side; discard already handled + // keys before checking that the restarted child returns a new event. + for len(router.calls) > 0 { + <-router.calls + } + if worker.current().Text != "" { + t.Fatal("stopped worker retained old content") + } + } +} diff --git a/internal/app/braille_presentation.go b/internal/app/braille_presentation.go new file mode 100644 index 0000000..e81d522 --- /dev/null +++ b/internal/app/braille_presentation.go @@ -0,0 +1,438 @@ +package app + +import ( + "fmt" + "math" + "strings" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/review" +) + +type brailleFrameEnqueuer interface{ EnqueueFrame(braille.Frame) } + +// Browse cells map to native object offsets under the page's review epoch. +func brailleDocumentFrame(result review.Result, options config.BrailleOptions, configured ...config.TextAttributeSettings) braille.Frame { + snapshot := result.DocumentPosition.Snapshot + line, assembled := result.DocumentBrailleLine, result.DocumentCaretLine + if line == nil && assembled == nil || snapshot.Role == "password text" { + frame := brailleFocusFrameWithOptions(snapshot, options, configured...) + frame.Routes = nil + if snapshot.Role == "link" && snapshot.ExplicitName && strings.TrimSpace(snapshot.Name) != "" && !snapshot.Editable { + // Accessible-label review has no native text route. + frame.Cursor = min(result.DocumentPosition.Offset, utf8.RuneCountInString(strings.TrimSpace(snapshot.Name))) + } + textLength := utf8.RuneCountInString(snapshot.Name) + if textLength == 0 { + textLength = utf8.RuneCountInString(snapshot.Text) + } + return linkedHeadingBraille(frame, result.DocumentPosition.LinkedHeading, options, textLength) + } + frame := braille.Frame{Cursor: -1, WordWrap: options.WordWrap} + appendContent := func(source atspi.Snapshot, raw, separator string, sourceStart int) { + frame.Text += separator + start := utf8.RuneCountInString(frame.Text) + frame.Text += raw + length := utf8.RuneCountInString(raw) + if source.ID() == snapshot.ID() && result.DocumentPosition.Offset >= sourceStart && result.DocumentPosition.Offset <= sourceStart+length { + frame.Cursor = start + result.DocumentPosition.Offset - sourceStart + } + if source.ID().Valid() && source.Role != "password text" && length > 0 { + frame.Routes = append(frame.Routes, braille.TextRoute{Start: start, End: start + length, + SourceStart: sourceStart, TextLength: length, BusName: source.BusName, Path: source.Path, SourceText: raw}) + } + if options.SelectionIndicator != 0 && source.SelectionEnd > source.SelectionStart { + frame.Dots = append(frame.Dots, make([]byte, utf8.RuneCountInString(frame.Text)-len(frame.Dots))...) + for offset := max(source.SelectionStart, sourceStart); offset < min(source.SelectionEnd, sourceStart+length); offset++ { + frame.Dots[start+offset-sourceStart] |= byte(options.SelectionIndicator) + } + } + isLink := source.Role == "link" + for _, ancestor := range source.BrailleContext { + isLink = isLink || ancestor.Role == "link" + } + if options.LinkIndicator != 0 && isLink { + frame.Dots = append(frame.Dots, make([]byte, utf8.RuneCountInString(frame.Text)-len(frame.Dots))...) + for offset := start; offset < start+length; offset++ { + frame.Dots[offset] |= byte(options.LinkIndicator) + } + } + if len(configured) != 0 { + if len(source.TextAttributeRuns) != 0 { + for _, run := range source.TextAttributeRuns { + markTextAttributeRun(&frame, run, sourceStart, start, length, configured[0]) + } + } else { + markTextAttributeRun(&frame, source.TextAttributeRun, sourceStart, start, length, configured[0]) + } + } + } + if assembled != nil { + for index, content := range assembled.Contents { + raw := content.RawText + if index == len(assembled.Contents)-1 { + raw = strings.TrimRight(raw, "\r\n") + } + if content.Snapshot.Role == "password text" { + continue + } + appendContent(content.Snapshot, raw, content.Separator, content.Start) + } + } else { + snapshot.SelectionStart, snapshot.SelectionEnd = line.SelectionStart, line.SelectionEnd + snapshot.TextAttributeRuns = line.TextAttributeRuns + appendContent(snapshot, strings.TrimRight(line.Text, "\r\n"), "", line.Start) + } + textLength := utf8.RuneCountInString(frame.Text) + if frame.Cursor < 0 || frame.Cursor > textLength { + frame.Cursor = -1 + } else if frame.Cursor == textLength { + frame.Text += " " + for index := range frame.Routes { + if frame.Routes[index].End == textLength { + frame.Routes[index].End++ + } + } + } + if result.DocumentFocus.Valid() && result.DocumentPosition.Document.Valid() { + doc := result.DocumentPosition.Document.ID() + frame.Document = &braille.DocumentRoute{Epoch: result.DocumentEpoch, FocusBus: result.DocumentFocus.BusName, + FocusPath: result.DocumentFocus.Path, DocumentBus: doc.BusName, DocumentPath: doc.Path} + } else { + frame.Routes = nil + } + ancestors := append([]atspi.Snapshot{snapshot}, result.DocumentCaretContext...) + for _, ancestor := range ancestors { + if ancestor.Role == "heading" { + frame.Text = brailleJoin(frame.Text, fmt.Sprintf("h%d", ancestor.HeadingLevel)) + break + } + } + if options.LinkIndicator != 0 && assembled == nil { + for _, ancestor := range ancestors { + if ancestor.Role == "link" { + frame.Dots = append(frame.Dots, make([]byte, utf8.RuneCountInString(frame.Text)-len(frame.Dots))...) + for index := 0; index < textLength; index++ { + frame.Dots[index] |= byte(options.LinkIndicator) + } + break + } + } + } + if len(frame.Dots) != 0 { + frame.Dots = append(frame.Dots, make([]byte, utf8.RuneCountInString(frame.Text)-len(frame.Dots))...) + } + return linkedHeadingBraille(frame, result.DocumentPosition.LinkedHeading, options, textLength) +} + +func linkedHeadingBraille(frame braille.Frame, link *atspi.Snapshot, options config.BrailleOptions, textLength int) braille.Frame { + if link == nil { + return frame + } + contentLength := utf8.RuneCountInString(frame.Text) + textLength = min(contentLength, max(0, textLength)) + if options.LinkIndicator != 0 { + if len(frame.Dots) < contentLength { + frame.Dots = append(frame.Dots, make([]byte, contentLength-len(frame.Dots))...) + } + for index := 0; index < textLength; index++ { + frame.Dots[index] |= byte(options.LinkIndicator) + } + } + role := "lnk" + if link.Visited { + role = "vlnk" + } + frame.Text = brailleJoin(frame.Text, role) + if len(frame.Dots) != 0 { + frame.Dots = append(frame.Dots, make([]byte, utf8.RuneCountInString(frame.Text)-contentLength)...) + } + return frame +} + +// Formats the captured object and bounded context using Python formatting.py's +// braille rules and object_properties.py's indicators. +func brailleFocusFrame(s atspi.Snapshot) braille.Frame { + return brailleFocusFrameWithOptions(s, config.DefaultSettings().Braille) +} + +func brailleFocusFrameWithOptions(s atspi.Snapshot, options config.BrailleOptions, configured ...config.TextAttributeSettings) braille.Frame { + return braille_context_frame(braille_object_frame(s, options, configured...), s, options) +} + +func braille_object_frame(s atspi.Snapshot, options config.BrailleOptions, configured ...config.TextAttributeSettings) braille.Frame { + if frame, handled := libreOfficeBrailleFrame(s, options); handled { + return frame + } + name, role := strings.TrimSpace(s.Name), s.ControlRole() + if role == "terminal" || brailleTextRole(role) && s.TextCaretKnown { + label := name + if role == "terminal" || role == "heading" || role == "static" { + label = "" + } + line := strings.TrimRight(s.BrailleLine, "\r\n") + if label == line { + label = "" + } + prefix := "" + if label != "" { + prefix = label + " " + } + text := prefix + line + end := utf8.RuneCountInString(text) + cursor := -1 + relative := s.BrailleCaret - s.BrailleLineStart + if s.TextCaretKnown && relative >= 0 && relative <= utf8.RuneCountInString(s.BrailleLine) { + cursor = utf8.RuneCountInString(prefix) + min(relative, utf8.RuneCountInString(line)) + } + if role != "terminal" && role != "heading" && !options.DisableEOL { + text += " $l" + } else if cursor == end { + text += " " + } + frame := braille.Frame{Text: text, Cursor: cursor, WordWrap: options.WordWrap} + if options.SelectionIndicator != 0 && s.SelectionEnd > s.SelectionStart { + frame.Dots = make([]byte, utf8.RuneCountInString(frame.Text)) + start := utf8.RuneCountInString(prefix) + for source := max(s.SelectionStart, s.BrailleLineStart); source < min(s.SelectionEnd, s.BrailleLineStart+utf8.RuneCountInString(line)); source++ { + frame.Dots[start+source-s.BrailleLineStart] = byte(options.SelectionIndicator) + } + } + if options.LinkIndicator != 0 { + for _, ancestor := range s.BrailleContext { + if ancestor.Role != "link" { + continue + } + if len(frame.Dots) == 0 { + frame.Dots = make([]byte, utf8.RuneCountInString(frame.Text)) + } + start := utf8.RuneCountInString(prefix) + for index := start; index < start+utf8.RuneCountInString(line); index++ { + frame.Dots[index] |= byte(options.LinkIndicator) + } + break + } + } + if len(configured) != 0 { + if len(s.TextAttributeRuns) != 0 { + for _, run := range s.TextAttributeRuns { + markTextAttributeRun(&frame, run, s.BrailleLineStart, utf8.RuneCountInString(prefix), utf8.RuneCountInString(line), configured[0]) + } + } else { + markTextAttributeRun(&frame, s.TextAttributeRun, s.BrailleLineStart, utf8.RuneCountInString(prefix), utf8.RuneCountInString(line), configured[0]) + } + } + // Only actual text and its EOL marker route; labels and state suffixes do not. + if s.TextCaretKnown && s.ID().Valid() { + frame.Routes = []braille.TextRoute{{Start: utf8.RuneCountInString(prefix), End: utf8.RuneCountInString(text), + SourceStart: s.BrailleLineStart, TextLength: utf8.RuneCountInString(line), + BusName: s.BusName, Path: s.Path, SourceText: s.BrailleLine}} + } + if role == "heading" { + frame.Text = brailleJoin(frame.Text, fmt.Sprintf("h%d", s.HeadingLevel)) + } else if role != "terminal" { + if s.Invalid && role != "spin button" && role != "document frame" && role != "document web" { + frame.Text += " invalid" + } + if s.Required { + frame.Text += " required" + } + if s.ReadOnly { + frame.Text += " rdonly" + } + } + if len(frame.Dots) != 0 && len(frame.Dots) < utf8.RuneCountInString(frame.Text) { + frame.Dots = append(frame.Dots, make([]byte, utf8.RuneCountInString(frame.Text)-len(frame.Dots))...) + } + return frame + } + // Protected text is never copied, even if a provider supplies it accidentally. + if role == "password text" { + return braille.Frame{Text: brailleJoin(name, role), Cursor: 0} + } + roleName := role + switch role { + case "invalid", "unknown", "redundant object", "filler", "extended", "link": + roleName = "" + case "heading": + roleName = fmt.Sprintf("h%d", s.HeadingLevel) + } + if options.Verbosity == 0 && role != "heading" { + roleName = "" + } + if options.AbbreviateRoles && roleName != "" && role != "heading" { + roleName = shortBrailleRole(roleName) + } + expanded := "" + if s.Expandable { + expanded = "collapsed" + if s.Expanded { + expanded = "expanded" + } + } + available := "" + if s.SensitiveKnown && !s.Sensitive { + available = "grayed" + } + indicator := "" + if s.Checked { + indicator = "" + } else if s.Indeterminate { + indicator = "<->" + } else { + indicator = "< >" + } + value := brailleValue(s) + text := "" + cursor := 0 + switch role { + case "check box": + text = brailleJoin(indicator, name, roleName) + case "check menu item": + text = brailleJoin(indicator, name, roleName, available) + case "radio button", "radio menu item", "toggle button": + indicator = "& y" + if s.Checked { + indicator = "&=y" + } + if name == "" { + name = s.Description + } + if role == "toggle button" { + text = brailleJoin(indicator, name, expanded, roleName) + } else { + text = brailleJoin(indicator, name, roleName) + if role == "radio menu item" { + text = brailleJoin(text, available) + } + } + case "push button", "button": + if name == "" { + name = s.Description + } + text = brailleJoin(name, expanded, roleName) + case "menu item": + text = brailleJoin(name, expanded, available) + case "tree item": + text = brailleJoin(name, expanded) + case "list item": + text = brailleJoin(name, expanded, roleName, available) + case "menu", "page tab": + text = brailleJoin(name, roleName, available) + case "combo box": + if value == "" { + value = s.Description + } + text = brailleJoin(name, value, roleName) + if name != "" && value != "" { + cursor = utf8.RuneCountInString(name) + 1 + } + case "dial", "scroll bar", "slider", "spin button": + text = brailleJoin(name, value, roleName) + if s.Required { + text = brailleJoin(text, "required") + } + if role == "slider" && s.Invalid { + text = brailleJoin(text, "invalid") + } + case "progress bar": + text = brailleJoin(name, value, roleName) + default: + displayed := s.Text + if displayed == name { + displayed = "" + } + text = brailleJoin(name, displayed, value, roleName) + if s.Required { + text = brailleJoin(text, "required") + } + if s.Invalid { + text = brailleJoin(text, "invalid") + } + } + if text == "" { + cursor = -1 + } + frame := braille.Frame{Text: text, Cursor: cursor, WordWrap: options.WordWrap} + if role == "link" && options.LinkIndicator != 0 { + frame.Dots = make([]byte, utf8.RuneCountInString(text)) + for index := range frame.Dots { + frame.Dots[index] |= byte(options.LinkIndicator) + } + } + return frame +} + +func shortBrailleRole(role string) string { + if short, ok := map[string]string{ + "check box": "chk", "check menu item": "chk", "radio button": "radio", + "push button": "btn", "button": "btn", "combo box": "cbo", + "list item": "lstitm", "page tab": "pgt", "text": "txt", + "link": "lnk", "slider": "sldr", "spin button": "spin", + "menu": "mnu", "menu item": "mnuitm", "progress bar": "pgbar", + "toggle button": "tglbtn", "password text": "pwd", "label": "lbl", + "application": "app", "frame": "frm", "dialog": "dlg", "panel": "pnl", + "list": "lst", "table": "tbl", "table cell": "cll", + "column header": "colhdr", "row header": "rwhdr", + }[role]; ok { + return short + } + return role +} + +func brailleTextRole(role string) bool { + switch role { + case "entry", "text", "static", "paragraph", "section", "label", "page", "document frame", "document web", "heading", "spin button": + return true + } + return false +} + +func brailleJoin(parts ...string) string { + out := make([]string, 0, len(parts)) + for _, part := range parts { + if part != "" { + out = append(out, part) + } + } + return strings.Join(out, " ") +} + +func brailleValue(s atspi.Snapshot) string { + if s.Role == "progress bar" { + if !s.ValueKnown || s.Indeterminate && s.CurrentValue <= 0 { + return "" + } + if s.MaximumValue == s.MinimumValue { + if s.CurrentValue == s.MaximumValue && s.CurrentValue >= 1 && s.CurrentValue <= 100 { + return fmt.Sprintf("%.0f%%", math.Trunc(s.CurrentValue)) + } + return "" + } + value := (s.CurrentValue - s.MinimumValue) / (s.MaximumValue - s.MinimumValue) * 100 + if math.IsNaN(value) || math.IsInf(value, 0) { + return "" + } + return fmt.Sprintf("%.0f%%", math.Trunc(value)) + } + if s.ValueText != "" { + return s.ValueText + } + if !s.ValueKnown || math.IsNaN(s.CurrentValue) || math.IsInf(s.CurrentValue, 0) { + return "" + } + increment := s.MinimumIncrement + if increment < 0 || math.IsNaN(increment) || math.IsInf(increment, 0) { + return "" + } + places := 0 + if increment > 0 { + places = int(math.Ceil(math.Max(0, -math.Log10(increment)))) + } else if math.Abs(s.CurrentValue) < 1 { + places = 1 + } + return fmt.Sprintf("%.*f", places, s.CurrentValue) +} diff --git a/internal/app/braille_presentation_test.go b/internal/app/braille_presentation_test.go new file mode 100644 index 0000000..ae93a45 --- /dev/null +++ b/internal/app/braille_presentation_test.go @@ -0,0 +1,425 @@ +package app + +import ( + "context" + "log/slog" + "reflect" + "strings" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/review" +) + +type frameRecorder struct{ frames chan braille.Frame } + +type flashRecorder struct{ messages []string } + +func (*flashRecorder) EnqueueFrame(braille.Frame) {} +func (recorder *flashRecorder) Flash(message string, _ config.BrailleOptions) bool { + recorder.messages = append(recorder.messages, message) + return true +} + +func TestSystemMessageFlashesOnBraille(t *testing.T) { + live := &liveSettings{} + live.Store(config.DefaultSettings()) + braille := &flashRecorder{} + queue := outputQueue{speech: &remoteSpeechQueue{}, braille: braille, live: live} + queue.Enqueue(speechRequest{Text: "Copied", Role: "system", Cause: "clipboard"}) + queue.Enqueue(speechRequest{Text: "Current line", Role: "system", Cause: "document-caret-line"}) + if len(braille.messages) != 1 || braille.messages[0] != "Copied" { + t.Fatalf("flash messages = %v", braille.messages) + } +} + +func TestBrailleOptionsChangePresentation(t *testing.T) { + options := config.DefaultSettings().Braille + options.DisableEOL = true + options.WordWrap = true + options.SelectionIndicator = 0x40 + entry := atspi.Snapshot{Role: "entry", Name: "Title", BrailleLine: "abcd", BrailleLineStart: 10, + BrailleCaret: 12, TextCaretKnown: true, SelectionStart: 11, SelectionEnd: 13} + frame := brailleFocusFrameWithOptions(entry, options) + if frame.Text != "Title abcd" || !frame.WordWrap || len(frame.Dots) != 10 || frame.Dots[7] != 0x40 || frame.Dots[8] != 0x40 { + t.Fatalf("entry frame = %+v", frame) + } + options.AbbreviateRoles = true + if got := brailleFocusFrameWithOptions(atspi.Snapshot{Role: "button", Name: "Save"}, options).Text; got != "Save btn" { + t.Fatalf("abbreviated button = %q", got) + } + options.Verbosity = 0 + if got := brailleFocusFrameWithOptions(atspi.Snapshot{Role: "button", Name: "Save"}, options).Text; got != "Save" { + t.Fatalf("brief button = %q", got) + } + options.LinkIndicator = 0x80 + link := brailleFocusFrameWithOptions(atspi.Snapshot{Role: "link", Name: "Help"}, options) + if len(link.Dots) != 4 || link.Dots[0] != 0x80 || link.Dots[3] != 0x80 { + t.Fatalf("link dots = %v", link.Dots) + } +} + +func (recorder frameRecorder) EnqueueFrame(frame braille.Frame) { recorder.frames <- frame } + +func TestBrailleFocusFrameTracksUnicodeCaret(t *testing.T) { + snapshot := atspi.NewSnapshot("/entry", "Message", "entry", "", "é猫x") + snapshot.TextCaretKnown = true + snapshot.BrailleLine = "é猫x" + snapshot.TextBeforeCaret = "é猫" + snapshot.BrailleCaret = 2 + if got := brailleFocusFrame(snapshot); !reflect.DeepEqual(got, braille.Frame{Text: "Message é猫x $l", Cursor: 10}) { + t.Fatalf("braille frame = %+v", got) + } + snapshot.BrailleLine = "a é" + snapshot.TextBeforeCaret = "a " + snapshot.BrailleCaret = 3 + if got := brailleFocusFrame(snapshot); !reflect.DeepEqual(got, braille.Frame{Text: "Message a é $l", Cursor: 11}) { + t.Fatalf("braille spacing/caret = %+v", got) + } + snapshot.BrailleLine = "é猫x" + snapshot.TextBeforeCaret = "other" + snapshot.BrailleCaret = 5 + if got := brailleFocusFrame(snapshot); got.Cursor != -1 { + t.Fatalf("invalid caret should be hidden: %+v", got) + } + snapshot.Role = "password text" + if got := brailleFocusFrame(snapshot); got.Cursor != 0 || got.Text != "Message password text" { + t.Fatalf("protected text leaked into braille: %+v", got) + } +} + +func TestBrailleFramesFollowAcceptedFocusAndCaretWithoutSpeech(t *testing.T) { + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + frames := make(chan braille.Frame, 8) + queue := outputQueue{speech: discardSpeech{}, braille: frameRecorder{frames: frames}} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + _ = processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + entry := atspi.NewSnapshot("/entry", "Message", "entry", "", "é猫") + entry.Editable = true + entry.TextCaretKnown = true + entry.BrailleLine = "é猫" + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + wantFrame(t, frames, braille.Frame{Text: "Message é猫 $l", Cursor: 8}) + entry.TextBeforeCaret = "é" + entry.BrailleCaret = 1 + adapter.events <- atspi.NewEvent(atspi.CaretEvent, entry) + wantFrame(t, frames, braille.Frame{Text: "Message é猫 $l", Cursor: 9}) + entry.Text = "é猫x" + entry.BrailleLine = "é猫x" + entry.TextBeforeCaret = "é猫x" + entry.BrailleCaret = 3 + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "x") + wantFrame(t, frames, braille.Frame{Text: "Message é猫x $l", Cursor: 11}) + // State snapshots may omit text capture. They must retain the displayed + // line while updating its state suffix. + entry.TextCaretKnown = false + entry.BrailleLine = "" + entry.Required = true + adapter.events <- atspi.NewEvent("object:state-changed:required", entry) + wantFrame(t, frames, braille.Frame{Text: "Message é猫x $l required", Cursor: 11}) + check := atspi.NewSnapshot("/check", "Save", "check box", "", "") + adapter.events <- atspi.NewEvent(atspi.FocusEvent, check) + wantFrame(t, frames, braille.Frame{Text: "< > Save check box", Cursor: 0}) + check.Checked = true + adapter.events <- atspi.NewEvent("object:state-changed:checked", check) + wantFrame(t, frames, braille.Frame{Text: " Save check box", Cursor: 0}) +} + +func wantFrame(t *testing.T, frames <-chan braille.Frame, want braille.Frame) { + t.Helper() + select { + case got := <-frames: + if !reflect.DeepEqual(got, want) { + t.Fatalf("braille frame = %+v, want %+v", got, want) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for braille frame %+v", want) + } +} + +func TestBraillePythonControlFormats(t *testing.T) { + for _, tc := range []struct { + name string + snapshot atspi.Snapshot + text string + cursor int + }{ + {"unchecked", atspi.Snapshot{Name: "Save", Role: "check box"}, "< > Save check box", 0}, + {"checked", atspi.Snapshot{Name: "Save", Role: "check box", Checked: true}, " Save check box", 0}, + {"mixed", atspi.Snapshot{Name: "Save", Role: "check box", Indeterminate: true}, "<-> Save check box", 0}, + {"radio", atspi.Snapshot{Name: "First", Role: "radio button", Checked: true}, "&=y First radio button", 0}, + {"toggle", atspi.Snapshot{Name: "Bold", Role: "toggle button", Checked: true}, "&=y Bold toggle button", 0}, + {"button", atspi.Snapshot{Name: "More", Role: "push button", Expandable: true}, "More collapsed push button", 0}, + {"menu", atspi.Snapshot{Name: "Save", Role: "menu item", SensitiveKnown: true}, "Save grayed", 0}, + {"unchecked generic menu", atspi.Snapshot{Name: "Updates", Role: "menu item", Checkable: true}, "< > Updates check menu item", 0}, + {"checked generic menu", atspi.Snapshot{Name: "Updates", Role: "menu item", Checked: true}, " Updates check menu item", 0}, + {"mixed generic menu", atspi.Snapshot{Name: "Updates", Role: "menu item", Indeterminate: true}, "<-> Updates check menu item", 0}, + {"combo", atspi.Snapshot{Name: "Color", Role: "combo box", ValueText: "Blue"}, "Color Blue combo box", 6}, + {"slider", atspi.Snapshot{Name: "Volume", Role: "slider", ValueKnown: true, CurrentValue: 1.25, MinimumIncrement: 0.01}, "Volume 1.25 slider", 0}, + {"progress", atspi.Snapshot{Name: "Copy", Role: "progress bar", ValueKnown: true, CurrentValue: 25, MaximumValue: 100}, "Copy 25% progress bar", 0}, + {"progress range", atspi.Snapshot{Name: "Copy", Role: "progress bar", ValueKnown: true, MinimumValue: 10, CurrentValue: 20, MaximumValue: 30}, "Copy 50% progress bar", 0}, + {"tree", atspi.Snapshot{Name: "Files", Role: "tree item", Expandable: true, Expanded: true}, "Files expanded", 0}, + } { + t.Run(tc.name, func(t *testing.T) { + frame := brailleFocusFrame(tc.snapshot) + if frame.Text != tc.text || frame.Cursor != tc.cursor { + t.Fatalf("got %+v, want %q cursor %d", frame, tc.text, tc.cursor) + } + }) + } +} + +func TestBrailleTextRoutesExcludeLabelsAndStates(t *testing.T) { + s := atspi.Snapshot{BusName: ":1.42", Path: "/entry", Name: "Message", Role: "entry", Editable: true, TextCaretKnown: true, + BrailleLine: "é猫\n", BrailleLineStart: 20, BrailleCaret: 22, Invalid: true, Required: true, ReadOnly: true} + f := brailleFocusFrame(s) + if f.Text != "Message é猫 $l invalid required rdonly" || f.Cursor != 10 || len(f.Routes) != 1 { + t.Fatalf("frame %+v", f) + } + r := f.Routes[0] + if r.Start != 8 || r.End != 13 || r.SourceStart != 20 || r.TextLength != 2 || r.SourceText != "é猫\n" { + t.Fatalf("route %+v", r) + } + s.Role = "terminal" + f = brailleFocusFrame(s) + if f.Text != "é猫 " || f.Cursor != 2 { + t.Fatalf("terminal frame %+v", f) + } + s.BrailleCaret = 19 + if f = brailleFocusFrame(s); f.Cursor != -1 { + t.Fatalf("caret outside captured suffix: %+v", f) + } +} + +type tableBrailleCapturer struct{ *documentLineCapturer } + +type browseBrailleCapturer struct { + *documentLineCapturer + text string +} + +func (capturer *browseBrailleCapturer) ReadDocumentCaret(_ context.Context, _ atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + characters := []rune(capturer.text) + if offset < 0 || offset >= len(characters) { + return atspi.DocumentCaretText{CharacterCount: len(characters)}, nil + } + start, end := offset, offset+1 + if unit != atspi.DocumentCaretCharacter { + for start > 0 && characters[start-1] != '\n' { + start-- + } + for end < len(characters) && characters[end-1] != '\n' { + end++ + } + } + return atspi.DocumentCaretText{Start: start, End: end, Text: string(characters[start:end]), CharacterCount: len(characters)}, nil +} + +func TestBrowseCaretUpdatesBrailleWithoutNativeCaretEvents(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + capturer := &browseBrailleCapturer{documentLineCapturer: &documentLineCapturer{calls: make(chan documentLineCaptureCall, 2)}, text: "é猫 word\nSecond line"} + worker, err := review.NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + settings := config.DefaultSettings() + settings.EnableBraille = false + prefsWorker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + prefsWorker.braille = &recordingBrailleSettings{} + prefsWorker.documentReview = worker + values := preferences.FromSettings(settings) + values.EnableBraille = true + if response := prefsWorker.apply(ctx, preferences.Request{Values: values}); !response.Accepted { + t.Fatalf("enabling braille for the running session failed: %+v", response) + } + if err = worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + frames := make(chan braille.Frame, 16) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), outputQueue{speech: discardSpeech{}, braille: frameRecorder{frames: frames}}, adapter, nil, worker, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + doc := atspi.Snapshot{BusName: ":1.42", Path: "/doc", Role: "document web", StatesKnown: true} + text := atspi.Snapshot{BusName: ":1.42", Path: "/text", Role: "static", StatesKnown: true, CharacterCount: utf8.RuneCountInString(capturer.text)} + tree, err := atspi.NewAccessibleTree(doc.ID(), []atspi.TreeNode{{Snapshot: doc, Children: []atspi.ObjectID{text.ID()}}, {Snapshot: text}}) + if err != nil { + t.Fatal(err) + } + adapter.events <- atspi.NewEvent(atspi.FocusEvent, doc) + wantFrame(t, frames, brailleFocusFrame(doc)) + for index, step := range []struct { + command review.DocumentCaretCommand + line string + cursor int + }{ + {review.CaretDocumentStart, "é猫 word", 0}, + {review.CaretNextCharacter, "é猫 word", 1}, + {review.CaretLineEnd, "é猫 word", 8}, + {review.CaretNextLine, "Second line", 0}, + {review.CaretPreviousLine, "é猫 word", 0}, + {review.CaretDocumentEnd, "Second line", 10}, + } { + if err = worker.MoveDocumentCaret(step.command); err != nil { + t.Fatal(err) + } + if index == 0 { + select { + case call := <-capturer.calls: + call.result <- tree + case <-time.After(time.Second): + t.Fatal("document capture missing") + } + } + select { + case frame := <-frames: + if strings.TrimRight(frame.Text, " ") != step.line || frame.Cursor != step.cursor || len(frame.Routes) != 1 || frame.Document == nil || frame.Routes[0].Path != text.Path { + t.Fatalf("command %v: frame %+v, want %q cursor %d with document routing", step.command, frame, step.line, step.cursor) + } + case <-time.After(time.Second): + t.Fatalf("command %v did not update braille", step.command) + } + } +} + +func TestBrowseBrailleUsesVirtualOffsetAndAncestorIndicators(t *testing.T) { + options := config.DefaultSettings().Braille + options.LinkIndicator = 0x80 + options.WordWrap = true + result := review.Result{DocumentPosition: review.DocumentPosition{Offset: 12, Snapshot: atspi.Snapshot{Role: "static"}}, + DocumentBrailleLine: &atspi.DocumentCaretText{Start: 10, Text: "é猫 word\n"}, + DocumentCaretContext: []atspi.Snapshot{{Role: "link"}, {Role: "heading", HeadingLevel: 2}}} + frame := brailleDocumentFrame(result, options) + if frame.Text != "é猫 word h2" || frame.Cursor != 2 || !frame.WordWrap || len(frame.Routes) != 0 || len(frame.Dots) != 11 || frame.Dots[0] != 0x80 || frame.Dots[8] != 0 { + t.Fatalf("browse frame = %+v", frame) + } + result.DocumentPosition.Snapshot = atspi.Snapshot{Role: "password text", Name: "Secret"} + frame = brailleDocumentFrame(result, options) + if frame.Text != "Secret password text" || len(frame.Routes) != 0 { + t.Fatalf("protected document text leaked: %+v", frame) + } +} + +func TestBrowseBrailleNamedLinkUsesLabelCursorWithoutNativeRoutes(t *testing.T) { + result := review.Result{DocumentPosition: review.DocumentPosition{Offset: 4, + Snapshot: atspi.Snapshot{Role: "link", ExplicitName: true, Name: "É猫 Info", CharacterCount: 1}}} + frame := brailleDocumentFrame(result, config.DefaultSettings().Braille) + if !strings.HasPrefix(frame.Text, "É猫 Info") || frame.Cursor != 4 || len(frame.Routes) != 0 { + t.Fatalf("named link lost label cursor or exposed synthetic native routes: %+v", frame) + } +} + +func TestBrowseBrailleFragmentLineKeepsNativeCursor(t *testing.T) { + first := atspi.NewSnapshot("/first", "", "static", "", "") + first.BusName = ":1.999" + second := atspi.NewSnapshot("/second", "", "static", "", "") + second.BusName = first.BusName + result := review.Result{ + DocumentPosition: review.DocumentPosition{Snapshot: second, Offset: 8}, + DocumentCaretLine: &atspi.DocumentLine{Contents: []atspi.DocumentContent{ + {Snapshot: first, Start: 0, End: 2, RawText: "é猫"}, + {Snapshot: second, Start: 7, End: 11, RawText: "word", Separator: " "}, + }}, + DocumentCaretContext: []atspi.Snapshot{{Role: "heading", HeadingLevel: 2}}, + } + frame := brailleDocumentFrame(result, config.DefaultSettings().Braille) + if frame.Text != "é猫 word h2" || frame.Cursor != 4 || len(frame.Routes) != 0 { + t.Fatalf("fragment frame = %+v", frame) + } +} + +func TestLinkedHeadingBrailleKeepsHeadingAndLinkIndicators(t *testing.T) { + options := config.DefaultSettings().Braille + options.LinkIndicator = 0x80 + heading := atspi.NewSnapshot("/heading", "Linked heading", "heading", "", "") + heading.HeadingLevel = 2 + link := atspi.NewSnapshot("/link", "Linked heading", "link", "", "") + link.Visited = true + result := review.Result{DocumentPosition: review.DocumentPosition{Snapshot: heading, LinkedHeading: &link}} + frame := brailleDocumentFrame(result, options) + if !strings.Contains(frame.Text, "h2") || !strings.Contains(frame.Text, "vlnk") || len(frame.Dots) != utf8.RuneCountInString(frame.Text) || frame.Dots[0] != 0x80 || frame.Dots[len([]rune(heading.Name))] != 0 { + t.Fatalf("linked heading frame = %+v", frame) + } + result.DocumentBrailleLine = &atspi.DocumentCaretText{Text: "Linked heading"} + frame = brailleDocumentFrame(result, options) + if frame.Text != "Linked heading h2 vlnk" || frame.Dots[0] != 0x80 || frame.Dots[len([]rune(heading.Name))] != 0 { + t.Fatalf("linked heading line frame = %+v", frame) + } +} + +func (*tableBrailleCapturer) ReadDocumentCaret(context.Context, atspi.ObjectReference, int, atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + return atspi.DocumentCaretText{}, nil +} + +func TestTableNavigationUpdatesBrailleWithoutNativeCaretEvent(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + capturer := &tableBrailleCapturer{&documentLineCapturer{calls: make(chan documentLineCaptureCall, 2)}} + worker, err := review.NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + if err = worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + frames := make(chan braille.Frame, 8) + queue := outputQueue{speech: discardSpeech{}, braille: frameRecorder{frames: frames}} + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, worker, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + doc := atspi.Snapshot{BusName: ":1.42", Path: "/doc", Role: "document web", StatesKnown: true} + table := atspi.Snapshot{BusName: ":1.42", Path: "/table", Role: "table", Name: "Probe", TableRowCount: 1, TableColumnCount: 1, StatesKnown: true} + cell := atspi.Snapshot{BusName: ":1.42", Path: "/cell", Role: "table cell", Name: "Cell contents", TablePositionKnown: true, TableRowSpan: 1, TableColumnSpan: 1, StatesKnown: true} + tree, err := atspi.NewAccessibleTree(doc.ID(), []atspi.TreeNode{{Snapshot: doc, Children: []atspi.ObjectID{table.ID()}}, {Snapshot: table, Children: []atspi.ObjectID{cell.ID()}}, {Snapshot: cell}}) + if err != nil { + t.Fatal(err) + } + adapter.events <- atspi.NewEvent(atspi.FocusEvent, table) + wantFrame(t, frames, brailleFocusFrame(table)) + if err = worker.MoveDocumentCaret(review.TableFirst); err != nil { + t.Fatal(err) + } + select { + case call := <-capturer.calls: + call.result <- tree + case <-time.After(time.Second): + t.Fatal("table capture missing") + } + wantFrame(t, frames, brailleFocusFrame(cell)) +} + +func TestBrowseBrailleRepeatedParentKeepsNativeCursor(t *testing.T) { + parent := atspi.NewSnapshot("/body", "", "paragraph", "", "") + parent.BusName = ":1.1" + child := atspi.NewSnapshot("/span", "", "section", "", "") + child.BusName = ":1.1" + result := review.Result{DocumentPosition: review.DocumentPosition{Snapshot: parent, Offset: 0}, DocumentCaretLine: &atspi.DocumentLine{Contents: []atspi.DocumentContent{ + {Snapshot: parent, Start: 0, End: 7, RawText: "Before "}, + {Snapshot: child, Start: 0, End: 9, RawText: "Read more"}, + {Snapshot: parent, Start: 8, End: 15, RawText: " after."}, + }}} + frame := brailleDocumentFrame(result, config.DefaultSettings().Braille) + if frame.Cursor != 0 { + t.Fatalf("text=%q cursor=%d; expected cursor=0", frame.Text, frame.Cursor) + } +} diff --git a/internal/app/braille_routing.go b/internal/app/braille_routing.go new file mode 100644 index 0000000..1e9fc64 --- /dev/null +++ b/internal/app/braille_routing.go @@ -0,0 +1,79 @@ +package app + +import ( + "context" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" +) + +type brailleRouter interface { + RouteBraille(context.Context, atspi.BrailleRoute) error +} + +func (worker *brailleWorker) route(ctx context.Context, event braille.RoutingEvent) { + worker.mu.Lock() + frame := worker.frame + length := utf8.RuneCountInString(frame.Text) + if worker.secure || worker.stopping || frame.ID == 0 || event.ID != frame.ID || event.Offset < 0 || + (frame.Virtual == nil && event.Offset >= length) || (frame.Virtual != nil && event.Offset > length) { + worker.mu.Unlock() + return + } + if route := frame.Virtual; route != nil { + if worker.ocr == nil || event.Offset < route.Start || event.Offset > route.End { + worker.mu.Unlock() + return + } + routeCtx, cancel := context.WithTimeout(ctx, time.Second) + worker.routeCancel = cancel + worker.mu.Unlock() + defer cancel() + worker.ocr.RouteBraille(routeCtx, route.Generation, route.SourceStart+event.Offset-route.Start) + return + } + if worker.router == nil && frame.Document == nil { + worker.mu.Unlock() + return + } + var target *braille.TextRoute + for _, route := range frame.Routes { + if event.Offset >= route.Start && event.Offset < route.End { + target = &route + break + } + } + if target == nil { + worker.mu.Unlock() + return + } + routeCtx, cancel := context.WithTimeout(ctx, time.Second) + worker.routeCancel = cancel + worker.mu.Unlock() + defer cancel() + if document := frame.Document; document != nil { + if worker.document == nil { + return + } + worker.logger.Debug("routing document braille", "frame_id", frame.ID, "document_epoch", document.Epoch, + "source_bus", target.BusName, "source_path", target.Path, "source_start", target.SourceStart, + "native_offset", target.SourceStart+min(event.Offset-target.Start, target.TextLength)) + err := worker.document.RouteDocumentBraille(routeCtx, document.Epoch, + atspi.NewObjectID(document.FocusBus, document.FocusPath), atspi.NewObjectID(document.DocumentBus, document.DocumentPath), + atspi.NewObjectID(target.BusName, target.Path), target.SourceText, target.SourceStart, + target.SourceStart+min(event.Offset-target.Start, target.TextLength)) + if err != nil && routeCtx.Err() == nil { + worker.logger.Debug("document braille routing rejected", "error", err) + } + return + } + err := worker.router.RouteBraille(routeCtx, atspi.BrailleRoute{ + Focus: atspi.NewObjectID(target.BusName, target.Path), Line: target.SourceText, Start: target.SourceStart, + Offset: target.SourceStart + min(event.Offset-target.Start, target.TextLength), + }) + if err != nil && routeCtx.Err() == nil { + worker.logger.Debug("braille routing rejected", "error", err) + } +} diff --git a/internal/app/braille_session.go b/internal/app/braille_session.go new file mode 100644 index 0000000..f43dee1 --- /dev/null +++ b/internal/app/braille_session.go @@ -0,0 +1,161 @@ +package app + +import ( + "bufio" + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "os/exec" + "strings" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/braille" +) + +func (worker *brailleWorker) run(ctx context.Context, done chan struct{}) { + defer close(done) + for ctx.Err() == nil { + if err := worker.session(ctx); err != nil && ctx.Err() == nil { + worker.logger.Warn("braille helper disconnected", "error", err) + } + select { + case <-ctx.Done(): + return + case <-time.After(time.Second): + } + } +} + +func (worker *brailleWorker) session(ctx context.Context) (result error) { + defer func() { worker.mu.Lock(); worker.connected = false; worker.mu.Unlock() }() + childCtx, cancel := context.WithCancel(ctx) + defer cancel() + command := exec.CommandContext(childCtx, worker.path, "--client") + stdin, err := command.StdinPipe() + if err != nil { + return err + } + stdout, err := command.StdoutPipe() + if err != nil { + return err + } + var stderr bytes.Buffer + command.Stderr = &stderr + if err := command.Start(); err != nil { + return err + } + waitDone := make(chan struct{}) + var waitErr error + go func() { defer close(waitDone); waitErr = command.Wait() }() + var ioWorkers sync.WaitGroup + // Kill the disposable native owner, close pipes to unblock I/O, then join + // every goroutine before permitting reconnect or a new configured session. + defer func() { + cancel() + _ = stdin.Close() + _ = stdout.Close() + <-waitDone + ioWorkers.Wait() + if result != nil { + if detail := strings.TrimSpace(stderr.String()); detail != "" { + result = fmt.Errorf("%w: %s", result, detail) + } else if waitErr != nil { + result = fmt.Errorf("%w: %v", result, waitErr) + } + } + }() + ready := make(chan error, 1) + readErrors := make(chan error, 1) + // Routing keys retain FIFO order. Backpressure stops this pipe reader at + // 16 pending keys; cancellation releases it and retires the session queue. + routes := make(chan braille.RoutingEvent, 16) + ioWorkers.Add(1) + go func() { + defer ioWorkers.Done() + scanner := bufio.NewScanner(stdout) + scanner.Buffer(make([]byte, 1024), 1024) + if !scanner.Scan() || scanner.Text() != "ready" { + ready <- errors.New("braille helper sent an invalid ready message") + return + } + ready <- nil + for scanner.Scan() { + var event braille.RoutingEvent + if err := json.Unmarshal(scanner.Bytes(), &event); err != nil { + readErrors <- errors.New("invalid braille routing event") + return + } + select { + case routes <- event: + case <-childCtx.Done(): + return + } + } + err := scanner.Err() + if err == nil { + err = io.EOF + } + readErrors <- err + }() + timer := time.NewTimer(2 * time.Second) + defer timer.Stop() + select { + case err := <-ready: + if err != nil { + return err + } + case <-timer.C: + return errors.New("braille helper connection timed out") + case <-ctx.Done(): + return nil + } + worker.logger.Info("braille helper connected") + worker.mu.Lock() + worker.connected = true + worker.mu.Unlock() + writeError := make(chan error, 1) + ioWorkers.Add(1) + go func() { + defer ioWorkers.Done() + encoder := json.NewEncoder(stdin) + for { + frame := worker.current() + if err := encoder.Encode(frame); err != nil { + writeError <- err + return + } + // This confirms the helper write, not the physical display. Text is + // the uncontracted line; cursor offsets count Unicode characters. + if worker.logger.Enabled(context.Background(), slog.LevelDebug) { + worker.logger.Debug("sent braille frame", "frame_id", frame.ID, + "braille_text", frame.Text, "cursor_offset", frame.Cursor, + "contracted", frame.Contract, "table", frame.Table, + "word_wrap", frame.WordWrap, "expand_at_cursor", frame.ExpandAtCursor) + } + select { + case <-childCtx.Done(): + return + case <-worker.wake: + } + } + }() + for { + select { + case <-waitDone: + return waitErr + case err := <-writeError: + return err + case err := <-readErrors: + return err + case event := <-routes: + worker.route(childCtx, event) + case <-ctx.Done(): + return nil + } + } +} diff --git a/internal/app/braille_text_attributes.go b/internal/app/braille_text_attributes.go new file mode 100644 index 0000000..6f7ff56 --- /dev/null +++ b/internal/app/braille_text_attributes.go @@ -0,0 +1,64 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" +) + +func markTextAttributeRun(frame *braille.Frame, run atspi.TextAttributeRun, sourceStart, frameStart, textLength int, settings config.TextAttributeSettings) { + if settings.Indicator == 0 || run.End <= run.Start || textLength <= 0 { + return + } + marked := false + for _, choice := range settings.Choices { + if !choice.Braille { + continue + } + if choice.Key == "text-spelling" { + if atspi.TextAttributesMisspelled(run.Values) { + marked = true + break + } + continue + } + value := strings.TrimSpace(run.Values[choice.Key]) + if value == "" { + continue + } + for _, known := range characterAttributeOrder { + if known.key != choice.Key { + continue + } + if value != known.ignore { + marked = true + } + break + } + if marked { + break + } + } + if !marked { + return + } + begin := max(run.Start, sourceStart) + end := min(run.End, sourceStart+textLength) + if begin >= end { + return + } + count := utf8.RuneCountInString(frame.Text) + if len(frame.Dots) < count { + frame.Dots = append(frame.Dots, make([]byte, count-len(frame.Dots))...) + } + for offset := begin; offset < end; offset++ { + frame.Dots[frameStart+offset-sourceStart] |= byte(settings.Indicator) + } +} diff --git a/internal/app/braille_text_attributes_test.go b/internal/app/braille_text_attributes_test.go new file mode 100644 index 0000000..926d110 --- /dev/null +++ b/internal/app/braille_text_attributes_test.go @@ -0,0 +1,114 @@ +package app + +import ( + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestSpellingAttributesAgreeInSpeechAndBraille(t *testing.T) { + settings := config.DefaultTextAttributes() + settings.Indicator = 0x40 + for index := range settings.Choices { + settings.Choices[index].Speak = settings.Choices[index].Key == "text-spelling" + settings.Choices[index].Braille = settings.Choices[index].Speak + } + for _, test := range []struct { + key, value string + misspelled bool + }{ + {"invalid", "spelling", true}, + {"invalid", "grammar", false}, + {"invalid-spelling", "true", true}, + {"invalid-spelling", "misspelled", true}, + {"spelling", "true", true}, + {"spelling", "misspelled", true}, + {"text-spelling", "misspelled", true}, + {"text-spelling", "true", true}, + {"text-spelling", "false", false}, + {"text-spelling", "none", false}, + {"underline", "error", true}, + {"underline", "spelling", true}, + {"underline", "single", false}, + } { + t.Run(test.key+"="+test.value, func(t *testing.T) { + values := map[string]string{test.key: test.value} + snapshot := atspi.Snapshot{Role: "entry", BrailleLine: "word", TextCaretKnown: true, + TextAttributeRun: atspi.TextAttributeRun{Start: 0, End: 4, Values: values}} + frame := brailleFocusFrameWithOptions(snapshot, config.DefaultSettings().Braille, settings) + marked := len(frame.Dots) >= 4 && frame.Dots[0] == 0x40 && frame.Dots[3] == 0x40 + if marked != test.misspelled { + t.Errorf("braille dots = %v, want misspelled %v", frame.Dots, test.misspelled) + } + want := "" + if test.misspelled { + want = "misspelled" + } + if got := strings.Join(spokenCharacterAttributes(values, true, settings), ", "); got != want { + t.Errorf("speech = %q, want %q", got, want) + } + }) + } +} + +func TestBrailleTextAttributeIndicatorMarksCurrentRun(t *testing.T) { + s := atspi.Snapshot{Role: "entry", BrailleLine: "abcde", BrailleLineStart: 10, + BrailleCaret: 12, TextCaretKnown: true, + TextAttributeRun: atspi.TextAttributeRun{Start: 11, End: 14, Values: map[string]string{"weight": "700"}}} + settings := config.DefaultTextAttributes() + settings.Indicator = 0x40 + for index := range settings.Choices { + settings.Choices[index].Braille = settings.Choices[index].Key == "weight" + } + frame := brailleFocusFrameWithOptions(s, config.DefaultSettings().Braille, settings) + if len(frame.Dots) < 5 || frame.Dots[0] != 0 || frame.Dots[1] != 0x40 || frame.Dots[2] != 0x40 || frame.Dots[3] != 0x40 || frame.Dots[4] != 0 { + t.Fatalf("attribute dots = %v", frame.Dots) + } + settings.Indicator = 0x80 + frame = brailleFocusFrameWithOptions(s, config.DefaultSettings().Braille, settings) + if frame.Dots[2] != 0x80 { + t.Fatalf("dot eight = %v", frame.Dots) + } + settings.Choices[2].Braille = false + frame = brailleFocusFrameWithOptions(s, config.DefaultSettings().Braille, settings) + if len(frame.Dots) != 0 { + t.Fatalf("disabled indicator = %v", frame.Dots) + } +} + +func TestBrailleTextAttributeIndicatorMarksSeparateRuns(t *testing.T) { + s := atspi.Snapshot{Role: "entry", BrailleLine: "abcd", BrailleLineStart: 4, + BrailleCaret: 5, TextCaretKnown: true, + TextAttributeRuns: []atspi.TextAttributeRun{ + {Start: 4, End: 6, Values: map[string]string{"weight": "700"}}, + {Start: 6, End: 8, Values: map[string]string{"underline": "single"}}, + }} + settings := config.DefaultTextAttributes() + settings.Indicator = 0xc0 + for index := range settings.Choices { + settings.Choices[index].Braille = settings.Choices[index].Key == "underline" + } + frame := brailleFocusFrameWithOptions(s, config.DefaultSettings().Braille, settings) + if len(frame.Dots) < 4 || frame.Dots[0] != 0 || frame.Dots[1] != 0 || frame.Dots[2] != 0xc0 || frame.Dots[3] != 0xc0 { + t.Fatalf("separate runs = %v", frame.Dots) + } +} + +func TestCaptureTextAttributesRequiresEnabledBrailleAndMarkedAttribute(t *testing.T) { + settings := config.DefaultSettings() + settings.TextAttributes.Indicator = 0x40 + settings.TextAttributes.Choices[0].Braille = true + if captureTextAttributes(settings) { + t.Fatal("captured attributes with braille disabled") + } + settings.EnableBraille = true + if !captureTextAttributes(settings) { + t.Fatal("did not capture enabled attribute runs") + } + settings.TextAttributes.Choices[0].Braille = false + if captureTextAttributes(settings) { + t.Fatal("captured without a marked attribute") + } +} diff --git a/internal/app/braille_worker.go b/internal/app/braille_worker.go new file mode 100644 index 0000000..5dd67f6 --- /dev/null +++ b/internal/app/braille_worker.go @@ -0,0 +1,125 @@ +package app + +import ( + "context" + "errors" + "fmt" + "log/slog" + "os" + "path/filepath" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// brailleWorker keeps all BrlAPI calls in a disposable child process. Only the +// newest frame is retained; focus and input callbacks never wait for the display. +// mu owns frames, flash generations, routing cancellation and session flags. +// The session joins its child and pipe workers before reconnecting; routing +// events retain their own bounded FIFO and validate the current frame identity. +type brailleWorker struct { + internalUIFrame *braille.Frame + router brailleRouter + document *review.Worker + ocr *ocrSession + sequence uint64 + routeCancel context.CancelFunc + secure bool + stopping bool + connected bool + logger *slog.Logger + path string + mu sync.Mutex + frame braille.Frame + baseFrame braille.Frame + flashTimer *time.Timer + flashGeneration uint64 + flashContext context.Context // A tentacle flash expires with its command/session. + protectedFlash bool // Focus updates retain baseFrame until expiry or user input. + contracted bool + wordWrap bool + table string + wake chan struct{} + cancel context.CancelFunc + done chan struct{} +} + +func newBrailleWorker(logger *slog.Logger) (*brailleWorker, error) { + executable, err := os.Executable() + if err != nil { + return nil, err + } + return &brailleWorker{logger: logger, path: filepath.Join(filepath.Dir(executable), "cthulhu-braille"), + frame: braille.Frame{Cursor: -1}, baseFrame: braille.Frame{Cursor: -1}, wake: make(chan struct{}, 1)}, nil +} + +func (worker *brailleWorker) Start() error { + worker.mu.Lock() + defer worker.mu.Unlock() + if worker.stopping { + return errors.New("braille helper shutdown is still pending") + } + if worker.cancel != nil { + return nil + } + info, err := os.Stat(worker.path) + if err != nil || info.IsDir() || info.Mode()&0111 == 0 { + return fmt.Errorf("braille helper %q is unavailable; build cthulhu-braille with -tags brlapi", worker.path) + } + ctx, cancel := context.WithCancel(context.Background()) + worker.cancel = cancel + worker.done = make(chan struct{}) + go worker.run(ctx, worker.done) + return nil +} + +func (worker *brailleWorker) Stop(ctx context.Context) error { + worker.mu.Lock() + cancel, done := worker.cancel, worker.done + if cancel == nil { + worker.mu.Unlock() + return nil + } + worker.stopping = true + if worker.routeCancel != nil { + worker.routeCancel() + } + worker.mu.Unlock() + cancel() + select { + case <-done: + worker.mu.Lock() + if worker.done == done { + worker.cancel, worker.done = nil, nil + worker.stopping = false + worker.connected = false + worker.protectedFlash = false + worker.flashContext = nil + worker.frame = braille.Frame{Cursor: -1} + worker.baseFrame = braille.Frame{Cursor: -1} + if worker.flashTimer != nil { + worker.flashTimer.Stop() + worker.flashTimer = nil + } + } + worker.mu.Unlock() + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (worker *brailleWorker) Configure(ctx context.Context, enabled bool) error { + if enabled { + return worker.Start() + } + return worker.Stop(ctx) +} + +func (worker *brailleWorker) Running() bool { + worker.mu.Lock() + defer worker.mu.Unlock() + return worker.cancel != nil && !worker.stopping && worker.connected +} diff --git a/internal/app/braille_worker_test.go b/internal/app/braille_worker_test.go new file mode 100644 index 0000000..80e03f1 --- /dev/null +++ b/internal/app/braille_worker_test.go @@ -0,0 +1,173 @@ +package app + +import ( + "context" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "log/slog" + "path/filepath" + "testing" + "time" +) + +func TestBrailleHelperStartsOnlyWhenEnabled(t *testing.T) { + worker := &brailleWorker{logger: slog.New(slog.DiscardHandler), + path: filepath.Join(t.TempDir(), "missing-helper"), wake: make(chan struct{}, 1)} + worker.Enqueue("focus") + if worker.frame.Text != "" { + t.Fatal("disabled braille retained a frame") + } + if err := worker.Configure(context.Background(), false); err != nil { + t.Fatal(err) + } + if err := worker.Configure(context.Background(), true); err == nil { + t.Fatal("enabled braille accepted a missing helper") + } +} + +func TestBrailleWordWrapUpdatesCurrentAndMessageFrames(t *testing.T) { + worker := &brailleWorker{wake: make(chan struct{}, 1), cancel: func() {}, connected: true} + worker.EnqueueFrame(braille.Frame{Text: "Focused long line", Cursor: 0}) + worker.SetWordWrap(true) + if !worker.current().WordWrap || !worker.baseFrame.WordWrap { + t.Fatal("word wrap did not update current and restoration frames") + } + if !worker.EnqueueMessage("Long external message") || !worker.current().WordWrap { + t.Fatal("external message lost word wrapping") + } + options := config.DefaultSettings().Braille + options.WordWrap, options.FlashPersistent = true, true + if !worker.Flash("Long flash message", options) || !worker.current().WordWrap { + t.Fatal("flash message lost word wrapping") + } + worker.SetWordWrap(false) + if worker.current().WordWrap || worker.baseFrame.WordWrap { + t.Fatal("disabled word wrap did not update current and restoration frames") + } +} + +func TestBrailleFlashRestoresFocusAndHonorsPreferences(t *testing.T) { + worker := &brailleWorker{wake: make(chan struct{}, 1), cancel: func() {}, connected: true} + worker.EnqueueFrame(braille.Frame{Text: "focus", Cursor: 0}) + options := config.DefaultSettings().Braille + options.FlashTime = 10 + if !worker.Flash("notice", options) || worker.current().Text != "notice" { + t.Fatalf("flash frame = %+v", worker.current()) + } + deadline := time.After(time.Second) + for worker.current().Text != "focus" { + select { + case <-deadline: + t.Fatal("flash did not restore focus") + case <-time.After(time.Millisecond): + } + } + options.FlashMessages = false + if worker.Flash("ignored", options) || worker.current().Text != "focus" { + t.Fatal("disabled flash changed the display") + } + options.FlashMessages = true + options.FlashPersistent = true + if !worker.Flash("persistent", options) { + t.Fatal("persistent flash rejected") + } + time.Sleep(20 * time.Millisecond) + if worker.current().Text != "persistent" { + t.Fatal("persistent flash expired") + } + worker.EnqueueFrame(braille.Frame{Text: "new focus", Cursor: -1}) + if worker.current().Text != "new focus" { + t.Fatal("focus did not replace persistent flash") + } +} + +type recordingBrailleRouter struct { + calls chan atspi.BrailleRoute + entered chan struct{} +} + +func (r *recordingBrailleRouter) RouteBraille(ctx context.Context, route atspi.BrailleRoute) error { + r.calls <- route + if r.entered != nil { + close(r.entered) + <-ctx.Done() + return ctx.Err() + } + return nil +} + +func TestBrailleWorkerRoutesOnlyCurrentTextCells(t *testing.T) { + router := &recordingBrailleRouter{calls: make(chan atspi.BrailleRoute, 8)} + worker := &brailleWorker{router: router, logger: slog.New(slog.DiscardHandler), wake: make(chan struct{}, 1), cancel: func() {}} + snapshot := atspi.Snapshot{BusName: ":1.42", Path: "/entry", Name: "Message", Role: "entry", Editable: true, + TextCaretKnown: true, BrailleLine: "é猫", BrailleLineStart: 20, BrailleCaret: 21, Required: true} + worker.EnqueueFrame(brailleFocusFrame(snapshot)) + id := worker.current().ID + for _, event := range []braille.RoutingEvent{{ID: id, Offset: 0}, {ID: id, Offset: 13}, {ID: id, Offset: -1}, {ID: id + 1, Offset: 8}} { + worker.route(context.Background(), event) + } + if len(router.calls) != 0 { + t.Fatal("routed label, suffix, invalid offset or stale frame") + } + for _, offset := range []int{8, 9, 10, 12} { + worker.route(context.Background(), braille.RoutingEvent{ID: id, Offset: offset}) + } + for _, want := range []int{20, 21, 22, 22} { + select { + case got := <-router.calls: + if got.Offset != want || got.Focus != snapshot.ID() || got.Line != "é猫" { + t.Fatalf("route %+v want offset %d", got, want) + } + default: + t.Fatal("routing missing") + } + } + worker.EnqueueFrame(braille.Frame{Cursor: -1}) + worker.route(context.Background(), braille.RoutingEvent{ID: id, Offset: 8}) + if len(router.calls) != 0 { + t.Fatal("routed cleared focus") + } +} + +func TestBrailleWorkerCancelsRoutingWhenFrameChanges(t *testing.T) { + router := &recordingBrailleRouter{calls: make(chan atspi.BrailleRoute, 1), entered: make(chan struct{})} + worker := &brailleWorker{router: router, logger: slog.New(slog.DiscardHandler), wake: make(chan struct{}, 1), cancel: func() {}} + worker.EnqueueFrame(braille.Frame{Text: "abc", Cursor: 0, Routes: []braille.TextRoute{{Start: 0, End: 3, TextLength: 3, BusName: ":1.42", Path: "/entry", SourceText: "abc"}}}) + done := make(chan struct{}) + go func() { + defer close(done) + worker.route(context.Background(), braille.RoutingEvent{ID: worker.current().ID, Offset: 1}) + }() + select { + case <-router.entered: + case <-time.After(time.Second): + t.Fatal("route did not start") + } + worker.EnqueueFrame(braille.Frame{Cursor: -1}) + select { + case <-done: + case <-time.After(time.Second): + t.Fatal("route was not canceled") + } +} + +func TestBrailleStopTimeoutRetainsJoinState(t *testing.T) { + done := make(chan struct{}) + worker := &brailleWorker{cancel: func() {}, done: done} + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if err := worker.Stop(ctx); err != context.Canceled { + t.Fatalf("stop error %v", err) + } + if worker.cancel == nil || worker.done == nil || !worker.stopping { + t.Fatal("lost timed-out worker") + } + close(done) + if err := worker.Stop(context.Background()); err != nil { + t.Fatal(err) + } + if worker.cancel != nil || worker.done != nil { + t.Fatal("completed stop retained session") + } +} diff --git a/internal/app/browser_activation_test.go b/internal/app/browser_activation_test.go new file mode 100644 index 0000000..bdbddb2 --- /dev/null +++ b/internal/app/browser_activation_test.go @@ -0,0 +1,43 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "errors" + "log/slog" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestBrowserActivationResultsStaySilent(t *testing.T) { + for _, activationErr := range []error{nil, review.ErrNoCurrent, atspi.ErrStaleObject, errors.New("action refused")} { + queue := &fakeSpeechQueue{spoken: make(chan string, 8), interrupt: make(chan struct{}, 8)} + focus := atspi.Snapshot{BusName: ":1.42", Path: "/clickable", Role: "section"} + browser := newBrowserModeController(nil, &modeKeys{}, nil) + browser.ready, browser.mode, browser.focus = true, review.BrowseMode, focus.ID() + state := &eventLoopState{} + state.current = focus + handler := eventReviewHandler{state: state, + logger: slog.New(slog.DiscardHandler), speech: queue, + objectReview: &review.Worker{}, browser: browser, focusGate: &focusGate{}, syncForeground: func() {}} + handler.handle(review.Result{DocumentActivate: true, DocumentFocus: focus.ID(), Err: activationErr}) + if len(queue.spoken) != 0 || len(queue.interrupt) != 0 { + t.Fatalf("activation %v produced feedback or interrupted page speech", activationErr) + } + } +} + +func TestBrowserNavigationDoesNotSuppressLiveNames(t *testing.T) { + browser := newBrowserModeController(nil, &modeKeys{}, nil) + browser.navigation = atspi.NewObjectID(":1.42", "/heading") + browser.navigationDocument = atspi.NewObjectID(":1.42", "/document") + event := atspi.NewEvent(atspi.AccessibleNameEvent, atspi.Snapshot{ + BusName: ":1.42", Path: "/status", Role: "status bar", Name: "Download complete", LiveRegion: true}) + if browser.suppressNavigationEcho(event) { + t.Fatal("reader navigation swallowed a live-region name update") + } +} diff --git a/internal/app/browser_button_names.go b/internal/app/browser_button_names.go new file mode 100644 index 0000000..7ee27b0 --- /dev/null +++ b/internal/app/browser_button_names.go @@ -0,0 +1,69 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" +) + +const browserButtonNameDelay = 350 * time.Millisecond + +// The event loop retains only the latest focused web button name. Focus and +// Braille update immediately; speech waits for the label to settle. Document +// generation and input identity prevent a delayed name from interrupting a +// later action, including leaving and returning to the same object. +type pendingBrowserButtonName struct { + pendingPresentation + document atspi.ObjectID + generation uint64 + inputSequence uint64 +} + +func (handler *accessibilityEventHandler) defer_browser_button_name(event atspi.Event, activity input.Activity) bool { + browser := handler.browser + if event.Type != atspi.AccessibleNameEvent || event.Source.LiveRegion || event.Source.Editable || + browser == nil || !browser.ready || !browser.document.Valid() || + event.Source.BusName != browser.document.BusName || event.Source.ID() != browser.focus || + event.Source.ID() != handler.state.focusedID { + return false + } + switch event.Source.Role { + case "button", "push button", "toggle button": + default: + return false + } + pending := &handler.state.pending.browserButtonName + // Duplicate notifications must not postpone an already settled label. + if pending.event.Source.ID() == event.Source.ID() && pending.event.Source.Name == event.Source.Name && + pending.document == browser.document && pending.generation == browser.generation && + pending.inputSequence == activity.TitleInterruptionSequence { + return true + } + pending.schedule(event, input.NoIntent, browserButtonNameDelay) + pending.document, pending.generation = browser.document, browser.generation + pending.inputSequence = activity.TitleInterruptionSequence + handler.logger.Debug("coalesced focused web button name", "bus", event.Source.BusName, "source_path", event.Source.Path) + return true +} + +func (handler *accessibilityEventHandler) flush_browser_button_name() { + pending := &handler.state.pending.browserButtonName + document, generation, inputSequence := pending.document, pending.generation, pending.inputSequence + event, _ := pending.take() + browser := handler.browser + if event.Type == "" || handler.focusGate.Locked() || handler.focusGate.Suspended() || + browser == nil || !browser.ready || browser.document != document || browser.generation != generation || + browser.RecentInput().TitleInterruptionSequence != inputSequence || browser.focus != event.Source.ID() || + handler.state.focusedID != event.Source.ID() || handler.state.current.ID() != event.Source.ID() || + handler.state.owner.window != eventWindow(event) { + return + } + // State events may have refreshed the same control during the quiet period. + event.Source = handler.state.current + handler.speak(event) +} diff --git a/internal/app/browser_button_names_test.go b/internal/app/browser_button_names_test.go new file mode 100644 index 0000000..67f45ee --- /dev/null +++ b/internal/app/browser_button_names_test.go @@ -0,0 +1,180 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestProcessEventsCoalescesWebButtonNames(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + speech := &fakeSpeechQueue{spoken: make(chan string, 32)} + frames := make(chan braille.Frame, 32) + adapter := &fakeAdapter{events: make(chan atspi.Event, 32)} + button := atspi.Snapshot{BusName: ":1.42", Path: "/counter", Name: "Counter value 0", Role: "button", Focused: true, Focusable: true} + browser := newBrowserModeController(nil, &modeKeys{}, nil) + browser.focus, browser.document = button.ID(), atspi.NewObjectID(button.BusName, "/document") + browser.ready, browser.mode = true, review.BrowseMode + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), outputQueue{speech: speech, braille: frameRecorder{frames}}, adapter, nil, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + event := atspi.NewEvent(atspi.FocusEvent, button) + event.Window = atspi.NewObjectID(button.BusName, "/window") + adapter.events <- event + expect := func(want string) { + t.Helper() + select { + case got := <-speech.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing speech %q", want) + } + } + expect("Counter value 0, button") + select { + case <-frames: + case <-time.After(time.Second): + t.Fatal("missing focus Braille") + } + // Structural navigation also owns this button. Updates must still reach + // Braille and the coalescer while delayed caret/focus echoes are suppressed. + browser.mutex.Lock() + browser.navigation, browser.navigationDocument = button.ID(), browser.document + browser.mutex.Unlock() + // Match the reported page's six updates per second for longer than the + // quiet window. Frame delivery acknowledges each event's processing. + ticker := time.NewTicker(150 * time.Millisecond) + defer ticker.Stop() + for i := 1; i <= 6; i++ { + <-ticker.C + event.Type = atspi.AccessibleNameEvent + event.Source.Name = fmt.Sprintf("Counter value %d", i) + adapter.events <- event + select { + case frame := <-frames: + if frame.Text != event.Source.Name+" button" { + t.Fatalf("current Braille = %q", frame.Text) + } + case <-time.After(time.Second): + t.Fatal("name change did not refresh Braille") + } + select { + case got := <-speech.spoken: + t.Fatalf("changing counter interrupted focus: %q", got) + default: + } + } + // Native input releases echo ownership before the next focus event. + browser.pointer_input() + // A redundant native focus notification must not discard the final name. + event.Type = atspi.FocusEvent + adapter.events <- event + <-frames + expect("Counter value 6, button") + + // A later action label still speaks once after settling. + event.Type = atspi.AccessibleNameEvent + event.Source.Name = "Update complete" + adapter.events <- event + <-frames + expect("Update complete, button") + + // Moving away cancels a pending name, and does not delay new focus. + event.Source.Name = "Pending counter" + adapter.events <- event + <-frames + event.Type, event.Source.Path, event.Source.Name = atspi.FocusEvent, "/next", "Next control" + adapter.events <- event + expect("Next control, button") + select { + case got := <-speech.spoken: + t.Fatalf("departed button spoke again: %q", got) + case <-time.After(2 * browserButtonNameDelay): + } +} + +func TestWebButtonNameScopeAndCancellation(t *testing.T) { + for _, kind := range []string{"settled", "live", "desktop", "entry", "other focus", "input", "document", "generation", "lock", "suspended", "window", "focus", "clear"} { + t.Run(kind, func(t *testing.T) { + button := atspi.Snapshot{BusName: ":1.42", Path: "/button", Name: "Play", Role: "button"} + event := atspi.NewEvent(atspi.AccessibleNameEvent, button) + event.Window = atspi.NewObjectID(button.BusName, "/window") + state := &eventLoopState{} + state.current, state.focusedID = button, button.ID() + state.owner.window = event.Window + source := fixedInputActivity{input.Activity{TitleInterruptionSequence: 1}} + browser := newBrowserModeController(source, &modeKeys{}, nil) + browser.ready, browser.focus, browser.document = true, button.ID(), atspi.NewObjectID(button.BusName, "/document") + spoken := 0 + handler := &accessibilityEventHandler{state: state, browser: browser, logger: slog.New(slog.DiscardHandler), focusGate: &focusGate{}, speak: func(atspi.Event, ...input.Intent) { spoken++ }} + defer state.pending.clear() + switch kind { + case "live": + event.Source.LiveRegion = true + case "desktop": + browser.ready = false + case "entry": + event.Source.Role = "entry" + case "other focus": + state.focusedID.Path = "/other" + } + deferred := handler.defer_browser_button_name(event, source.activity) + if kind == "live" || kind == "desktop" || kind == "entry" || kind == "other focus" { + if deferred { + t.Fatal("unrelated event was delayed") + } + return + } + if !deferred { + t.Fatal("web button name was not delayed") + } + timer := state.pending.browserButtonName.timer + handler.defer_browser_button_name(event, source.activity) + if state.pending.browserButtonName.timer != timer { + t.Fatal("duplicate name postponed presentation") + } + switch kind { + case "input": + browser.source = fixedInputActivity{input.Activity{TitleInterruptionSequence: 2}} + case "document": + browser.document.Path = "/newDocument" + case "generation": + browser.generation++ + case "lock": + handler.focusGate.secure.Store(true) + case "suspended": + handler.focusGate.suspended.Store(true) + case "window": + state.owner.window.Path = "/otherWindow" + case "focus": + state.focusedID.Path = "/other" + case "clear": + state.pending.clear() + } + handler.flush_browser_button_name() + want := 0 + if kind == "settled" { + want = 1 + } + if spoken != want { + t.Fatalf("presentations = %d, want %d", spoken, want) + } + }) + } +} diff --git a/internal/app/browser_dynamic_test.go b/internal/app/browser_dynamic_test.go new file mode 100644 index 0000000..238f7a1 --- /dev/null +++ b/internal/app/browser_dynamic_test.go @@ -0,0 +1,208 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "log/slog" + "net/http" + "net/http/httptest" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeBrowserDynamicNavigation(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + page := `Dynamic navigation regression +Start of page + +

After control

+ +` + // A large document must remain navigable without exhausting the live + // two-second first-capture budget before any browse position exists. + for i := 0; i < 1000; i++ { + page += fmt.Sprintf("

Unrelated paragraph %d

", i) + } + page += `

End of page

` + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, page) + })) + defer server.Close() + adapter := atspi.New() + adapter.SetCaptureSoundGeometry(true) + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + command := func(args ...string) { + t.Helper() + if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("xdotool: %v: %s", err, output) + } + } + command("key", "--clearmodifiers", "ctrl+l") + command("type", "--clearmodifiers", "--delay", "0", server.URL) + command("key", "Return") + var document atspi.ObjectID + var applicationName string + for !document.Valid() { + select { + case event := <-adapter.Events(): + if event.Type == atspi.DocumentLoadCompleteEvent && event.Source.Name == "Dynamic navigation regression" { + document = event.Source.ID() + applicationName = event.Source.ApplicationName + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + worker, err := review.NewWorker(adapter, 2*time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.SetFlatCaptureTimeout(10 * time.Second); err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(document) + move := func(command review.DocumentCaretCommand, want string) { + t.Helper() + if err := worker.MoveDocumentCaret(command); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + got := result.DocumentCaretText + if got == "" { + got = result.DocumentPosition.Snapshot.Name + } + if result.Err != nil || result.CaretErr != nil || !result.Moved || !strings.Contains(got, want) { + t.Fatalf("next line = %q, want %q: %+v", got, want, result) + } + if result.DocumentPosition.Snapshot.ApplicationName != applicationName { + t.Fatalf("document target application = %q, want %q", result.DocumentPosition.Snapshot.ApplicationName, applicationName) + } + attempts := result.DocumentDiagnostics.Attempts + if len(attempts) == 0 || attempts[len(attempts)-1].After.Object != result.DocumentPosition.Object.ID() { + t.Fatalf("navigation diagnostics do not match the browser position: %+v", result.DocumentDiagnostics) + } + t.Logf("line=%q elapsed=%s capture=%s reason=%v", got, result.Elapsed, result.CaptureDuration, result.CaptureReason) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + next := func(want string) { + t.Helper() + move(review.CaretNextLine, want) + } + next("Start of page") + next("Counter") + waitName := func(name string) atspi.Event { + t.Helper() + for { + select { + case event := <-adapter.Events(): + if event.Type == atspi.AccessibleNameEvent && event.Source.Name == name { + return event + } + case <-ctx.Done(): + t.Fatalf("name change to %q was not observed", name) + } + } + } + counter := waitName("Counter updated") + // Exercise actual browser name events at the reported update cadence. + // The separate event-loop regression covers routing and immediate Braille. + state := &eventLoopState{} + state.current, state.focusedID, state.owner.window = counter.Source, counter.Source.ID(), counter.Window + browser := newBrowserModeController(nil, &modeKeys{}, nil) + browser.ready, browser.focus, browser.document = true, counter.Source.ID(), document + namePresentations := 0 + handler := &accessibilityEventHandler{state: state, browser: browser, logger: slog.New(slog.DiscardHandler), speak: func(event atspi.Event, _ ...input.Intent) { + namePresentations++ + if event.Source.Name != "Counter 6" { + t.Fatalf("changing native counter spoke before settling: %q", event.Source.Name) + } + }} + defer state.pending.clear() + updates := 0 + for namePresentations == 0 { + select { + case event := <-adapter.Events(): + if event.Type == atspi.AccessibleNameEvent && event.Source.ID() == counter.Source.ID() { + updates++ + state.current = event.Source + if !handler.defer_browser_button_name(event, input.Activity{}) { + t.Fatal("native web button name was not coalesced") + } + } + case <-state.pending.browserButtonName.ready: + handler.flush_browser_button_name() + case <-ctx.Done(): + t.Fatal("native counter did not finish: ", ctx.Err()) + } + } + if updates < 2 { + t.Fatalf("observed only %d native counter updates", updates) + } + t.Logf("coalesced %d native counter updates into one settled announcement", updates) + next("After control") + next("Avatar") + next("Add content") + waitName("Add content done") + next("Unrelated paragraph 0") + next("Unrelated paragraph 1") + move(review.CaretDocumentEnd, "New content") + // Browsing to the end scrolls paragraphs which were previously not + // showing into view. Flat review must capture those paragraphs even if + // the provider's state cache still describes the initial viewport. + for index, tc := range []struct { + unit review.FlatUnit + step int + text string + moved bool + }{ + {review.WindowEnd, 0, "New content", true}, + {review.Line, -1, "End of page", true}, + {review.Line, -1, "Unrelated paragraph 999", true}, + {review.Line, 1, "End of page", true}, + {review.Word, 1, "of", true}, + {review.Character, 1, "f", true}, + {review.WindowEnd, 0, "New content", true}, + {review.Character, 0, "t", false}, + {review.Line, 1, "New content", false}, + {review.Line, -1, "End of page", true}, + } { + started := time.Now() + if err := worker.ReadFlat(tc.unit, tc.step); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + t.Logf("flat review unit %d step=%d text=%q moved=%v elapsed=%s capture=%s reason=%v", tc.unit, tc.step, result.FlatPosition.Text, result.Moved, time.Since(started), result.CaptureDuration, result.CaptureReason) + if result.Err != nil || strings.TrimSpace(result.FlatPosition.Text) != tc.text || index > 0 && result.Moved != tc.moved { + t.Fatalf("large-page flat review unit %d step=%d want=%q moved=%v: %+v", tc.unit, tc.step, tc.text, tc.moved, result) + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } +} diff --git a/internal/app/browser_editor_native_test.go b/internal/app/browser_editor_native_test.go new file mode 100644 index 0000000..79cc586 --- /dev/null +++ b/internal/app/browser_editor_native_test.go @@ -0,0 +1,148 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "os" + "os/exec" + "strings" + "sync/atomic" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +func TestNativeBrowserEditorTyping(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + listener := xorg.New() + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + var focus atomic.Pointer[atspi.Snapshot] + var insertion atomic.Pointer[atspi.Event] + observed := &browserEventProbe{Adapter: adapter, events: make(chan atspi.Event, 64)} + relayDone := make(chan struct{}) + go func() { + defer close(relayDone) + for { + select { + case event := <-adapter.Events(): + if isFocusGainEvent(event) { + focus.Store(&event.Source) + } + if event.Type == atspi.TextInsertedEvent && event.Source.Role == "paragraph" { + insertion.Store(&event) + } + select { + case observed.events <- event: + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } + }() + defer func() { cancel(); <-relayDone }() + queue := &fakeSpeechQueue{spoken: make(chan string, 128)} + done := make(chan struct{}) + go func() { + defer close(done) + options := presentation.DefaultOptions() + options.EnableKeyEcho = false + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, observed, nil, nil, + 20*time.Millisecond, nil, listener, nil, nil, options) + }() + defer func() { cancel(); <-done }() + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + collect := func() []string { + t.Helper() + timer := time.NewTimer(180 * time.Millisecond) + defer timer.Stop() + var texts []string + for { + select { + case text := <-queue.spoken: + texts = append(texts, text) + case <-timer.C: + return texts + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + for attempt := 0; attempt < 20; attempt++ { + keys("Tab") + collect() + if current := focus.Load(); current != nil && current.Name == "Message composer" { + break + } + } + editor := focus.Load() + if editor == nil || editor.Name != "Message composer" || !editor.Editable || editor.Role != "entry" { + t.Fatalf("composer focus = %+v", editor) + } + keys("End") + collect() + for _, letter := range []string{"h", "e", "l", "l", "o"} { + keys(letter) + if got := collect(); len(got) != 0 { + t.Fatalf("typing %q with echo disabled spoke %q", letter, got) + } + } + if event := insertion.Load(); event == nil || event.Source.EditableRoot != editor.ID() { + t.Fatalf("paragraph insertion lost editor ownership: %+v", event) + } + keys("Left") + if got := collect(); len(got) != 1 || got[0] != "o" { + t.Fatalf("character reading = %q", got) + } + keys("Down") + if got := collect(); len(got) != 1 || got[0] != "Following line" { + t.Fatalf("next line reading = %q", got) + } + keys("Up") + if got := collect(); len(got) != 1 || got[0] != "Draft:hello" { + t.Fatalf("line reading = %q", got) + } + keys("End") + collect() + keys("BackSpace") + if got := collect(); len(got) != 1 || got[0] != "o" { + t.Fatalf("deletion = %q", got) + } + keys("Tab") + if got := collect(); len(got) == 0 || !strings.Contains(strings.Join(got, " "), "Other editor") { + t.Fatalf("next editor focus = %q", got) + } + keys("x") + if got := collect(); len(got) != 0 { + t.Fatalf("typing in second editor spoke %q", got) + } + if current, event := focus.Load(), insertion.Load(); current == nil || current.Name != "Other editor" || + event == nil || event.Source.EditableRoot != current.ID() || event.Source.EditableRoot == editor.ID() { + t.Fatalf("second editor ownership: focus=%+v insertion=%+v", current, event) + } +} diff --git a/internal/app/browser_events_test.go b/internal/app/browser_events_test.go new file mode 100644 index 0000000..998d248 --- /dev/null +++ b/internal/app/browser_events_test.go @@ -0,0 +1,1049 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +type autocompleteRequestQueue struct{ requests chan speechRequest } + +func TestBrowserNewTabsKeepAddressFocusAndSuppressURLRewrites(t *testing.T) { + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 32)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 32)} + tracker := &input.IntentTracker{} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, tracker, nil, nil) + }() + defer func() { cancel(); <-done }() + expect := func(want string) speechRequest { + t.Helper() + select { + case request := <-queue.requests: + if request.Text != want { + t.Fatalf("speech = %q, want %q", request.Text, want) + } + return request + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + return speechRequest{} + } + } + page := ownerEvent(atspi.FocusEvent, ":1.7", "/window", "/page") + page.Source.Role, page.Source.Name = "document web", "Original page" + adapter.events <- page + expect("Original page, document web") + tracker.Observe(input.NewKeyEvent(0, true, "Control_L")) + tracker.Observe(input.NewKeyEvent(0, true, "t")) + tab := ownerEvent(atspi.SelectedStateEvent, ":1.7", "/window", "/tab1") + tab.Source.Role, tab.Source.Name, tab.Source.BrowserTab = "page tab", "New Tab", true + tab.Detail1 = 1 + adapter.events <- tab + expect("New Tab, page tab") + entry := ownerEvent(atspi.FocusEvent, ":1.7", "/window", "/address") + entry.Source.Role, entry.Source.Name = "entry", "Address" + entry.Source.Editable, entry.Source.Autocomplete, entry.Source.Focused = true, true, true + adapter.events <- entry + if request := expect("Address, autocomplete"); !request.Append { + t.Fatal("address focus would interrupt new-tab announcement") + } + deletion := atspi.NewEventWithPayload(atspi.TextDeletedEvent, entry.Source, "previous.example") + adapter.events <- deletion + tracker.Observe(input.NewKeyEvent(0, true, "t")) + tab.Source.Path = "/tab2" + adapter.events <- tab + expect("New Tab, page tab") // No address focus event for the second Ctrl+T. + adapter.events <- tab // Duplicate selected-state event. + selection := tab + selection.Type, selection.OriginPath = atspi.SelectionChangedEvent, "/tabs" + adapter.events <- selection + selection.Type, selection.Detail1 = atspi.SelectedStateEvent, 0 + adapter.events <- selection + background := tab + background.Window.Path, background.Source.Path = "/background", "/backgroundTab" + adapter.events <- background + tracker.Observe(input.NewKeyEvent(0, false, "Control_L")) + tracker.Observe(input.NewKeyEvent(0, true, "a")) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry.Source, "a") + expect("a") // The selected tab did not steal the owned address focus. + tracker.Observe(input.NewKeyEvent(0, true, "BackSpace")) + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, entry.Source, "a") + expect("a") + tracker.Observe(input.NewKeyEvent(0, true, "Control_L")) + tracker.Observe(input.NewKeyEvent(0, true, "x")) + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, entry.Source, "selected.example") + expect("selected.example") + tracker.Observe(input.NewKeyEvent(0, false, "Control_L")) + tab.Source.Path, tab.Source.Name = "/tab1", "First tab" + adapter.events <- tab + expect("First tab, page tab") + // Firefox may report only a tab-list selection, followed by a delayed + // selected-state gain from the previous tab. Fresh state rejects that gain. + selection = tab + selection.Type, selection.Source.Path, selection.Source.Name = atspi.SelectionChangedEvent, "/tab3", "Third tab" + selection.Source.StatesKnown, selection.Source.Selected = true, true + selection.Source.ToolkitName = "Gecko" + adapter.events <- selection + expect("Third tab, page tab") + adapter.events <- selection + tab.Source.StatesKnown, tab.Source.Selected = true, false + adapter.events <- tab + marker := entry + marker.Source.Path, marker.Source.Name = "/marker", "End" + marker.Source.Role, marker.Source.Autocomplete = "button", false + adapter.events <- marker + expect("End, button") // Marker also catches unexpected queued announcements. +} + +func (queue *autocompleteRequestQueue) Enqueue(request speechRequest) { queue.requests <- request } +func (queue *autocompleteRequestQueue) Interrupt() {} + +func TestAutocompleteAnnouncesSelectedAddressWhenItChanges(t *testing.T) { + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 16)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 16)} + tracker := &input.IntentTracker{} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + options := presentation.DefaultOptions() + options.EnableSound = true + options.PlaySoundForRole = true + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, tracker, nil, nil, options) + }() + defer func() { cancel(); <-done }() + + entry := atspi.Snapshot{BusName: ":1.7", Path: "/address", Role: "entry", Autocomplete: true, Editable: true, Focused: true} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + select { + case request := <-queue.requests: + if request.Text != "autocomplete" || len(request.Sound) != 0 { + t.Fatalf("focus request = %#v", request) + } + case <-time.After(time.Second): + t.Fatal("missing address-bar focus") + } + tracker.Observe(input.NewKeyEvent(0, true, "s")) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "s") + select { + case request := <-queue.requests: + if len(request.Sound) != 0 { + t.Fatalf("ordinary typing sounded like a completion: %#v", request) + } + case <-time.After(time.Second): + t.Fatal("missing typing presentation") + } + entry.Text = "https://stormux.org" + entry.SelectionStart, entry.SelectionEnd = 1, len([]rune(entry.Text)) + inserted := atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "suggestion") + inserted.Detail1 = 1 + adapter.events <- inserted + select { + case request := <-queue.requests: + if request.Text != entry.Text || len(request.Sound) != 1 || request.Sound[0].Name != "autocomplete" { + t.Fatalf("completion request = %#v", request) + } + case <-time.After(time.Second): + t.Fatal("missing autocomplete sound") + } + popup := atspi.NewEvent(atspi.SelectionChangedEvent, atspi.Snapshot{BusName: ":1.7", Path: "/suggestion", Role: "list item", Name: "Other result", AutocompletePopup: true}) + popup.PopupFor = entry.ID() + adapter.events <- popup + adapter.events <- inserted + select { + case request := <-queue.requests: + if request.Text == entry.Text || len(request.Sound) != 0 { + t.Fatalf("duplicate selected address announcement = %#v", request) + } + case <-time.After(40 * time.Millisecond): + } + tracker.Observe(input.NewKeyEvent(0, true, "t")) + entry.Text = "https://stormux.org/docs" + entry.SelectionStart, entry.SelectionEnd = 2, len([]rune(entry.Text)) + updated := atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "updated suggestion") + updated.Detail1 = 2 + adapter.events <- updated + select { + case request := <-queue.requests: + if request.Text != entry.Text || len(request.Sound) != 1 || request.Sound[0].Name != "autocomplete" { + t.Fatalf("updated address request = %#v", request) + } + case <-time.After(time.Second): + t.Fatal("missing updated address announcement") + } +} + +func TestAutocompleteAnnouncementRequiresSelectedAddress(t *testing.T) { + entry := atspi.Snapshot{BusName: ":1.7", Path: "/address", Role: "entry", Autocomplete: true} + var availability autocompleteAvailability + availability.focus(atspi.NewEvent(atspi.FocusEvent, entry)) + edit := atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "h") + activity := input.Activity{Intent: input.TypingIntent, Sequence: 1} + if got := availability.offered(edit, activity); got != "" { + t.Fatalf("unselected text sounded as completion: %q", got) + } + entry.Text = "https://stormux.org" + entry.SelectionStart, entry.SelectionEnd = 1, len([]rune(entry.Text)) + edit.Source = entry + if got := availability.offered(edit, input.Activity{}); got != "" { + t.Fatalf("completion without user edit sounded: %q", got) + } + if got := availability.offered(edit, activity); got != entry.Text { + t.Fatalf("selected address = %q, want %q", got, entry.Text) + } + if got := availability.offered(edit, input.Activity{Intent: input.TypingIntent, Sequence: 2}); got != "" { + t.Fatalf("unchanged address sounded again: %q", got) + } + other := edit + other.Source.Path = "/other" + other.Source.Text = "https://different.example" + if got := availability.offered(other, activity); got != "" { + t.Fatalf("other entry sounded as owned address: %q", got) + } +} + +func TestFirstBrowserLoadKeepsActivationSpeech(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 8), interrupt: make(chan struct{}, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + browser := newBrowserModeController(nil, &modeKeys{}, nil) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.42", "/window", "/document") + activation.Source.Role, activation.Source.Name = "document web", "First page" + adapter.events <- activation + expectActivationSpeech(t, queue.spoken, "First page, document web") + load := ownerEvent(atspi.DocumentLoadCompleteEvent, ":1.42", "/window", "/document") + load.Source.Role, load.Source.Name = "document web", "First page" + adapter.events <- load + expectActivationSpeech(t, queue.spoken, "Finished loading First page.") + button := ownerEvent(atspi.FocusedStateEvent, ":1.42", "/window", "/button") + button.Source.Role, button.Source.Name = "button", "Next" + button.Detail1 = 1 + adapter.events <- button + expectActivationSpeech(t, queue.spoken, "Next, button") + select { + case <-queue.interrupt: + t.Fatal("first load interrupted its own activation speech") + default: + } + load.Source.Path = "/second-document" + adapter.events <- load + adapter.events <- button + expectActivationSpeech(t, queue.spoken, "Finished loading First page.") + expectActivationSpeech(t, queue.spoken, "Next, button") + select { + case <-queue.interrupt: + t.Fatal("document completion interrupted earlier speech") + default: + } +} + +func TestBrowserTypingAndNavigation(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 32)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 32)} + tracker := &input.IntentTracker{} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, tracker, nil, nil) + }() + defer func() { cancel(); <-done }() + expect := func(want string) { + t.Helper() + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("speech %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } + quiet := func() { + t.Helper() + select { + case got := <-queue.spoken: + t.Fatalf("unexpected %q", got) + case <-time.After(30 * time.Millisecond): + } + } + key := func(name string) { tracker.Observe(input.NewKeyEvent(0, true, name)) } + entry := atspi.Snapshot{BusName: ":1.7", Path: "/entry", Role: "entry", Editable: true, Autocomplete: true, Focused: true} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + expect("autocomplete") + key("s") + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, entry, "previous.example") + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "s") + expect("s") + // Suggestions can clear the native focused bit without changing the owned entry. + entry.Focused = false + key("t") + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "t") + expect("t") + // Chromium inserts the selected completion and emits several popup events. + entry.SelectionStart, entry.SelectionEnd = 1, 11 + completion := atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "tormux.org") + completion.Detail1 = 1 + adapter.events <- completion + adapter.events <- atspi.NewEvent(atspi.CaretEvent, entry) + popup := atspi.Snapshot{BusName: ":1.7", Path: "/suggestion", Role: "list item", Name: "Suggested site", Selected: true, AutocompletePopup: true} + popupFocus := atspi.NewEvent(atspi.FocusedStateEvent, popup) + popupFocus.Detail1 = 1 + adapter.events <- popupFocus + adapter.events <- atspi.NewEvent("object:state-changed:selected", popup) + adapter.events <- atspi.NewEvent(atspi.SelectionChangedEvent, popup) + quiet() + // Explicit suggestion navigation still speaks the chosen item, once. + key("Down") + adapter.events <- popupFocus + expect("Suggested site, list item, selected") + adapter.events <- atspi.NewEvent("object:state-changed:selected", popup) + adapter.events <- atspi.NewEvent(atspi.SelectionChangedEvent, popup) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "suggested.example") + adapter.events <- atspi.NewEvent(atspi.CaretEvent, entry) + quiet() + page := atspi.Snapshot{BusName: ":1.7", Path: "/paragraph", Role: "paragraph", Text: "Plain document text", CaretWord: "document", CaretCharacter: "d"} + key("Down") + adapter.events <- atspi.NewEvent(atspi.CaretEvent, page) + expect("Plain document text") + blank := page + blank.Text, blank.CaretCharacter = "", "\n" + adapter.events <- atspi.NewEvent(atspi.CaretEvent, blank) + expect("blank") + key("Control_L") + key("Right") + adapter.events <- atspi.NewEvent(atspi.CaretEvent, page) + expect("document") + tracker.Observe(input.NewKeyEvent(0, false, "Control_L")) + key("Right") + adapter.events <- atspi.NewEvent(atspi.CaretEvent, page) + expect("d") +} + +func TestAutocompleteFocusCaretDoesNotInterruptAnnouncement(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + tracker := &input.IntentTracker{} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, tracker, nil, nil) + }() + defer func() { cancel(); <-done }() + entry := atspi.Snapshot{ + BusName: ":1.7", Path: "/address", Name: "Address and search bar", Role: "entry", + Editable: true, Autocomplete: true, Focused: true, Text: "https://example.test", + SelectionEnd: len("https://example.test"), CaretCharacter: "h", + } + tracker.Observe(input.NewKeyEvent(0, true, "Control_L")) + tracker.Observe(input.NewKeyEvent(0, true, "l")) + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + adapter.events <- atspi.NewEvent(atspi.CaretEvent, entry) + select { + case got := <-queue.spoken: + if want := "Address and search bar, autocomplete, https://example.test, selected"; got != want { + t.Fatalf("focus speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatal("missing address-bar focus speech") + } + select { + case got := <-queue.spoken: + t.Fatalf("focus caret interrupted announcement with %q", got) + case <-time.After(40 * time.Millisecond): + } + tracker.Observe(input.NewKeyEvent(0, false, "Control_L")) + tracker.Observe(input.NewKeyEvent(0, true, "Right")) + adapter.events <- atspi.NewEvent(atspi.CaretEvent, entry) + select { + case got := <-queue.spoken: + if got != "h" { + t.Fatalf("arrow caret speech = %q, want h", got) + } + case <-time.After(time.Second): + t.Fatal("missing arrow caret speech") + } +} + +func TestFocusedStateLossIsIgnored(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + keys := &modeKeys{enabled: true} + browser := newBrowserModeController(nil, keys, nil) + browser.ready = true + browser.mode = review.BrowseMode + browser.document = atspi.NewObjectID(":1.7", "/document") + + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + _ = processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, browser, nil, nil) + }() + lost := atspi.Snapshot{BusName: ":1.7", Path: "/button", Name: "Old", Role: "button", Focusable: true} + event := atspi.NewEvent(atspi.FocusedStateEvent, lost) + event.Detail1 = 0 + adapter.events <- event + time.Sleep(30 * time.Millisecond) + if !browser.ready || browser.mode != review.BrowseMode || !keys.enabled { + t.Fatal("focus loss changed browser mode or browse grabs") + } + select { + case got := <-queue.spoken: + t.Fatalf("focus loss spoke %q", got) + default: + } + cancel() + <-done +} + +func TestNewDocumentFocusIsNotRetainedOldCaret(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + browser := newBrowserModeController(nil, &modeKeys{}, nil) + browser.ready, browser.mode = true, review.BrowseMode + browser.document = atspi.NewObjectID(":1.7", "/old_document") + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + newDocument := atspi.Snapshot{BusName: ":1.7", Path: "/new_document", Role: "document web", Name: "New topic"} + focus := atspi.NewEvent(atspi.FocusedStateEvent, newDocument) + focus.Detail1 = 1 + adapter.events <- focus + select { + case spoken := <-queue.spoken: + if spoken != "New topic, document web" { + t.Fatalf("new document focus said %q", spoken) + } + case <-time.After(time.Second): + t.Fatal("new document focus was suppressed") + } + if browser.focus != newDocument.ID() { + t.Fatalf("browser retained old focus: %v", browser.focus) + } +} + +func TestDelayedDocumentCaretCannotOverrideEditableFocus(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + where := make(chan input.Command) + browser := newBrowserModeController(nil, &modeKeys{}, nil) + browser.ready, browser.mode = true, review.BrowseMode + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, where, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + entry := atspi.Snapshot{BusName: ":1.42", Path: "/address", Role: "entry", Editable: true, Name: "Address"} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + select { + case <-queue.spoken: + case <-time.After(time.Second): + t.Fatal("missing entry focus") + } + oldHeading := atspi.Snapshot{BusName: ":1.42", Path: "/old-heading", Role: "heading", Text: "Old page"} + adapter.events <- atspi.NewEvent(atspi.CaretEvent, oldHeading) + // The event loop must finish processing the caret before it can receive + // this command. Join before inspecting controller state. + where <- input.WhereAmI + cancel() + <-done + if browser.focus != entry.ID() || browser.generation != 1 { + t.Fatalf("old document caret replaced editable focus: %v generation %d", browser.focus, browser.generation) + } +} + +func TestBrowseSelectionCaretUpdatesReviewFocus(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + browser := newBrowserModeController(nil, &modeKeys{}, nil) + browser.ready = true + browser.mode = review.BrowseMode + browser.document = atspi.NewObjectID(":1.42", "/document") + browser.focus = browser.document + + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + + selection := atspi.Snapshot{ + BusName: ":1.42", Path: "/selection", Role: "paragraph", + Text: "Selected", CaretCharacter: "h", + SelectionStart: 0, SelectionEnd: 1, + } + adapter.events <- atspi.NewEvent(atspi.CaretEvent, selection) + + select { + case got := <-queue.spoken: + if got != "h" { + t.Fatalf("selected caret speech = %q, want h", got) + } + case <-time.After(time.Second): + t.Fatal("selected caret did not speak") + } + if browser.focus != selection.ID() { + t.Fatalf("selection caret did not update browse focus: %v", browser.focus) + } + if browser.generation != 1 { + t.Fatalf("selection caret generation = %d, want 1", browser.generation) + } +} + +func TestBackgroundDocumentLoadPreservesChromeFocus(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + where := make(chan input.Command) + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, where, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + expect := func(want string) { + t.Helper() + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } + entry := atspi.Snapshot{BusName: ":1.42", Path: "/address", Role: "entry", Editable: true, Autocomplete: true, Name: "Address"} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + expect("Address, autocomplete") + document := atspi.Snapshot{BusName: ":1.42", Path: "/document", Role: "document web", Name: "Loaded page"} + load := atspi.NewEvent(atspi.DocumentLoadCompleteEvent, document) + load.FocusOutsideDocument = entry.ID() + adapter.events <- load + where <- input.WhereAmI + expect("Address, autocomplete") + // A subsequent load with document focus must still announce and acquire + // the new document, even if the previous chrome snapshot was editable. + adapter.events <- atspi.NewEvent(atspi.DocumentLoadCompleteEvent, document) + expect("Finished loading Loaded page.") + cancel() + <-done + if browser.focus != document.ID() || browser.ready || keys.enabled { + t.Fatalf("load did not schedule new document resolution: %+v", browser.focus) + } +} + +func TestDocumentCompletionPreservesBackendSpeech(t *testing.T) { + for _, eventType := range []string{atspi.DocumentLoadCompleteEvent, atspi.BusyStateEvent} { + t.Run(eventType, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 8), requests: make(chan speechRequest, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + browser := newBrowserModeController(nil, &modeKeys{}, nil) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.42", "/window", "/document") + activation.Source.Role, activation.Source.Name = "document web", "First page" + adapter.events <- activation + expectActivationSpeech(t, queue.spoken, "First page, document web") + <-queue.requests + load := activation + load.Type = eventType + load.Detail1 = 0 + adapter.events <- load + expectActivationSpeech(t, queue.spoken, "Finished loading First page.") + request := <-queue.requests + // Exercise backend cancellation: checking queue.Interrupt alone + // misses the implicit cancellation of non-appended requests. + speaker := &fakeSpeaker{spoken: make(chan string, 1)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.deliver(ctx, request); err != nil { + t.Fatal(err) + } + if speaker.canceled { + t.Fatal("load completion canceled earlier speech at the backend") + } + }) + } +} + +func TestDocumentLifecycleRecoversBrowseFocusWithoutLoadComplete(t *testing.T) { + for _, tc := range []struct { + name string + start string + end string + }{ + {"reload stopped", atspi.DocumentReloadEvent, atspi.DocumentLoadStoppedEvent}, + {"busy completed", atspi.BusyStateEvent, atspi.BusyStateEvent}, + } { + t.Run(tc.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + where := make(chan input.Command) + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, where, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + focus := ownerEvent(atspi.FocusEvent, ":1.42", "/window", "/document") + focus.Source.Role, focus.Source.Name = "document web", "Example page" + adapter.events <- focus + expectActivationSpeech(t, queue.spoken, "Example page, document web") + start := ownerEvent(tc.start, ":1.42", "/window", "/document") + start.Source.Role = "document web" + start.Detail1 = 1 + adapter.events <- start + if tc.start == atspi.BusyStateEvent { + expectActivationSpeech(t, queue.spoken, "Loading. Please wait.") + } + where <- input.WhereAmI + expectActivationSpeech(t, queue.spoken, "Example page, document web") + if browser.focus.Valid() || browser.ready || keys.enabled { + t.Fatal("loading retained browse focus") + } + end := ownerEvent(tc.end, ":1.42", "/window", "/new_document") + end.Source.Role, end.Source.Name = "document web", "New page" + adapter.events <- end + if tc.end == atspi.BusyStateEvent { + expectActivationSpeech(t, queue.spoken, "Finished loading New page.") + } + where <- input.WhereAmI + expectActivationSpeech(t, queue.spoken, "New page, document web") + if browser.focus != end.Source.ID() || !browser.resolving { + t.Fatalf("load completion did not schedule document recovery: %+v", browser.focus) + } + // Retiring the old page must not clear the replacement's ownership. + dead := focus + dead.Type, dead.Detail1 = atspi.DefunctStateEvent, 1 + adapter.events <- dead + where <- input.WhereAmI + expectActivationSpeech(t, queue.spoken, "New page, document web") + }) + } +} + +func TestDocumentLifecycleKeepsChromeFocus(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + where := make(chan input.Command) + browser := newBrowserModeController(nil, &modeKeys{}, nil) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, where, nil, 0, nil, browser, nil, nil) + }() + entry := ownerEvent(atspi.FocusEvent, ":1.42", "/window", "/address") + entry.Source.Role, entry.Source.Name = "entry", "Address" + adapter.events <- entry + expectActivationSpeech(t, queue.spoken, "Address, entry") + for _, eventType := range []string{atspi.DocumentReloadEvent, atspi.BusyStateEvent, atspi.DocumentLoadStoppedEvent} { + event := ownerEvent(eventType, ":1.42", "/window", "/document") + event.Source.Role = "document web" + event.Detail1 = 1 + event.FocusOutsideDocument = entry.Source.ID() + adapter.events <- event + } + where <- input.WhereAmI + expectActivationSpeech(t, queue.spoken, "Address, entry") + cancel() + <-done + if browser.focus != entry.Source.ID() { + t.Fatalf("document lifecycle displaced chrome focus: %v", browser.focus) + } +} + +func TestDocumentBusyCompletionKeepsVerifiedMessageListFocus(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + where := make(chan input.Command) + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, where, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + + row := ownerEvent(atspi.FocusEvent, ":1.42", "/window", "/message_row") + row.Source.Role, row.Source.Name = "table row", "Message one" + adapter.events <- row + expectActivationSpeech(t, queue.spoken, "Message one, table row") + load := ownerEvent(atspi.DocumentLoadCompleteEvent, ":1.42", "/window", "/preview") + load.Source.Role = "document web" + load.FocusOutsideDocument = row.Source.ID() + adapter.events <- load + busy := load + busy.Type, busy.Detail1 = atspi.BusyStateEvent, 0 + busy.FocusOutsideDocument = atspi.ObjectID{} + adapter.events <- busy + where <- input.WhereAmI + expectActivationSpeech(t, queue.spoken, "Message one, table row") + if browser.focus != row.Source.ID() || browser.mode != review.InactiveMode || keys.enabled { + t.Fatalf("preview busy completion took message-list arrows: focus %v, mode %v, grabs %v", browser.focus, browser.mode, keys.enabled) + } + entered := ownerEvent(atspi.FocusEvent, ":1.42", "/window", "/preview") + entered.Source.Role, entered.Source.Name = "document web", "Message preview" + adapter.events <- entered + expectActivationSpeech(t, queue.spoken, "Message preview, document web") + busy.Source.Name = entered.Source.Name + adapter.events <- busy + expectActivationSpeech(t, queue.spoken, "Finished loading Message preview.") + // Speech is queued before the controller finishes adopting the document. + // Join the event loop before inspecting its state. + cancel() + <-done + if browser.focus != entered.Source.ID() { + t.Fatalf("document focus did not enter preview: %v", browser.focus) + } +} + +func TestDocumentLoadRespectsWindowAndFocusOwnership(t *testing.T) { + for _, test := range []struct { + name string + bus string + window string + deactivate bool + defunctBefore bool + defunct string + accepted bool + want string + }{ + {name: "other application", bus: ":1.43", window: "/window", want: "Address, entry"}, + {name: "other window", bus: ":1.42", window: "/other", want: "Address, entry"}, + {name: "owner ended", bus: ":1.42", window: "/window", deactivate: true, want: "Could not find current location."}, + {name: "loaded document dies", bus: ":1.42", window: "/window", defunct: "/document", accepted: true, want: "Could not find current location."}, + {name: "old focus dies", bus: ":1.42", window: "/window", defunct: "/address", accepted: true, want: "Loaded page, document web"}, + {name: "replacement after old focus dies", bus: ":1.42", window: "/window", defunctBefore: true, accepted: true, want: "Loaded page, document web"}, + } { + t.Run(test.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + where := make(chan input.Command) + browser := newBrowserModeController(nil, &modeKeys{}, nil) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, where, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + focus := ownerEvent(atspi.FocusEvent, ":1.42", "/window", "/address") + focus.Source.Role, focus.Source.Name, focus.Source.Editable = "entry", "Address", true + adapter.events <- focus + expectActivationSpeech(t, queue.spoken, "Address, entry") + if test.deactivate { + adapter.events <- ownerEvent(atspi.WindowDeactivatedEvent, ":1.42", "/window", "/window") + } + if test.defunctBefore { + dead := ownerEvent(atspi.DefunctStateEvent, test.bus, test.window, "/address") + dead.Detail1 = 1 + adapter.events <- dead + } + load := ownerEvent(atspi.DocumentLoadCompleteEvent, test.bus, test.window, "/document") + load.Source.Role, load.Source.Name = "document web", "Loaded page" + adapter.events <- load + if test.accepted { + expectActivationSpeech(t, queue.spoken, "Finished loading Loaded page.") + } + if test.defunct != "" { + dead := ownerEvent(atspi.DefunctStateEvent, test.bus, test.window, test.defunct) + dead.Detail1 = 1 + adapter.events <- dead + } + // The unbuffered command follows event processing, without a sleep. + where <- input.WhereAmI + expectActivationSpeech(t, queue.spoken, test.want) + cancel() + <-done + if test.want == "Could not find current location." && browser.focus.Valid() { + t.Fatalf("browser retained ended focus: %v", browser.focus) + } + if !test.accepted && !test.deactivate && browser.focus != focus.Source.ID() { + t.Fatalf("background load replaced browser focus: %v", browser.focus) + } + }) + } +} + +func TestBrowserAddressBarNameEventsAreIgnored(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 16)} + tracker := &input.IntentTracker{} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + options := presentation.DefaultOptions() + options.EnableKeyEcho = false + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, tracker, nil, nil, options) + }() + defer func() { cancel(); <-done }() + + entry := atspi.Snapshot{ + BusName: ":1.7", Path: "/address-bar", ApplicationName: "Chromium Variant", + Name: "Address and search bar", Role: "entry", Editable: true, Autocomplete: true, Focused: true, + } + focused := atspi.NewEvent(atspi.FocusedStateEvent, entry) + focused.Detail1 = 1 + adapter.events <- focused + select { + case got := <-queue.spoken: + if got != "Address and search bar, autocomplete" { + t.Fatalf("focus speech %q", got) + } + case <-time.After(time.Second): + t.Fatal("missing address bar focus speech") + } + + siteInformation := entry + siteInformation.Path = "/site-information" + siteInformation.Name = "View site information" + siteInformation.Role = "image map" + siteInformation.Editable = false + siteInformation.Autocomplete = false + adapter.events <- atspi.NewEvent(atspi.AccessibleNameEvent, siteInformation) + + typed := entry + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, typed, "c") + select { + case got := <-queue.spoken: + t.Fatalf("unexpected typing speech %q", got) + case <-time.After(30 * time.Millisecond): + } + + suggestion := atspi.Snapshot{ + BusName: ":1.7", Path: "/suggestions/first", ApplicationName: "Chromium Variant", + Name: "stormux.org", Role: "list item", Selected: true, AutocompletePopup: true, + } + selected := atspi.NewEvent("object:state-changed:selected", suggestion) + selected.Detail1 = 1 + tracker.Observe(input.NewKeyEvent(0, true, "Down")) + adapter.events <- selected + select { + case got := <-queue.spoken: + if got != "stormux.org, list item, selected" { + t.Fatalf("completion speech %q", got) + } + case <-time.After(time.Second): + t.Fatal("missing completion speech") + } + // A focus event for the same popup item is another route to the same + // presentation in Chromium and must not repeat it. + adapter.events <- atspi.NewEvent(atspi.FocusedStateEvent, suggestion) + + suggestionName := suggestion + suggestionName.Name = "stormux.org suggestion" + adapter.events <- atspi.NewEvent(atspi.AccessibleNameEvent, suggestionName) + adapter.events <- selected + select { + case got := <-queue.spoken: + t.Fatalf("unexpected duplicate completion or browser UI name speech %q", got) + case <-time.After(30 * time.Millisecond): + } + + select { + case got := <-queue.spoken: + t.Fatalf("unexpected browser UI name speech %q", got) + case <-time.After(30 * time.Millisecond): + } + + if !isBrowserUINameNoise(atspi.NewEvent(atspi.AccessibleNameEvent, suggestionName), suggestion) { + t.Fatal("focused autocomplete popup name event was not classified as noise") + } +} + +func TestBrowserNameChangesBeforeDocumentFocus(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + adapter := &fakeAdapter{events: make(chan atspi.Event)} + queue := &fakeSpeechQueue{spoken: make(chan string, 16)} + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + // A new browser can send these before its first focus event. The last + // focused application and address-bar state cannot identify their owner. + for _, role := range []string{"button", "page tab", "frame", "static", "heading"} { + adapter.events <- atspi.NewEvent(atspi.AccessibleNameEvent, atspi.Snapshot{ + BusName: ":1.7", Path: "/changed", ToolkitName: "Chromium", Role: role, Name: "Background update", + }) + } + // This focus announcement synchronizes the event loop and must be first. + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{ + BusName: ":1.7", Path: "/document", Role: "document web", Name: "Example page", + }) + select { + case got := <-queue.spoken: + if got != "Example page, document web" { + t.Fatalf("page focus was preceded by name noise: %q", got) + } + case <-time.After(time.Second): + t.Fatal("missing page focus") + } + // Preserve ordinary toolkit name changes and actual browser focus events. + for _, toolkit := range []string{"gtk", "Qt", ""} { + event := atspi.NewEvent(atspi.AccessibleNameEvent, atspi.Snapshot{ToolkitName: toolkit}) + if isBrowserUINameNoise(event, atspi.Snapshot{}) { + t.Fatalf("filtered non-web toolkit %q", toolkit) + } + } + if isBrowserUINameNoise(atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{ToolkitName: "Chromium"}), atspi.Snapshot{}) { + t.Fatal("filtered browser focus") + } +} + +func TestEditableEntryEchoExcludesPasswordAndReadOnlyContent(t *testing.T) { + for _, tc := range []struct { + snapshot atspi.Snapshot + want bool + }{ + {atspi.Snapshot{Role: "entry", Editable: true}, true}, + {atspi.Snapshot{Role: "text", Editable: true}, true}, + {atspi.Snapshot{Role: "password text", Editable: true}, false}, + {atspi.Snapshot{Role: "entry"}, false}, + {atspi.Snapshot{Role: "entry", Editable: true, ReadOnly: true}, false}, + {atspi.Snapshot{Role: "paragraph"}, false}, + } { + if got := speaksTextChanges(tc.snapshot); got != tc.want { + t.Fatalf("%+v: %v", tc.snapshot, got) + } + } +} + +func TestSystemTextMutationsDoNotSpeakWebContainers(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + page := atspi.Snapshot{BusName: ":1.7", Path: "/page", Role: "document web", Name: "Example page"} + section := atspi.Snapshot{BusName: ":1.7", Path: "/section", Role: "section"} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, page) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent+":system", section, "new page content") + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent+":system", section, "old page content") + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: ":1.7", Path: "/end", Role: "button", Name: "End"}) + for _, want := range []string{"Example page, document web", "End, button"} { + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } +} + +func TestAutocompleteRetainsTypedPrefix(t *testing.T) { + entry := atspi.Snapshot{BusName: ":1.7", Path: "/entry", Role: "entry", Editable: true, Autocomplete: true, SelectionStart: 1, SelectionEnd: 15, CompletionPrefixCharacter: "b"} + event := atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "rave://version") + event.Detail1 = 1 + echo := &autocompleteEcho{} + activity := input.Activity{Intent: input.TypingIntent, Sequence: 1} + if got := echo.insertion(event, activity); got != "b" { + t.Fatalf("retained prefix: %q", got) + } + if got := echo.insertion(event, activity); got != "" { + t.Fatalf("duplicate completion: %q", got) + } + activity.Sequence++ + entry.SelectionStart = 2 + entry.CompletionPrefixCharacter = "r" + event = atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "ave://version") + event.Detail1 = 2 + if got := echo.insertion(event, activity); got != "r" { + t.Fatalf("extended prefix: %q", got) + } + // A separately reported typed character already covers the completion. + activity.Sequence++ + typed := atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "r") + typed.Detail1 = 1 + if got := echo.insertion(typed, activity); got != "r" { + t.Fatalf("typed letter: %q", got) + } + if got := echo.insertion(event, activity); got != "" { + t.Fatalf("completion duplicated typed letter: %q", got) + } +} + +func TestBackgroundAddressChangesDoNotInterruptDocument(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + entry := atspi.Snapshot{BusName: ":1.7", Path: "/address", Role: "entry", Editable: true, Autocomplete: true, Focused: true} + page := atspi.Snapshot{BusName: ":1.7", Path: "/page", Role: "document web", Name: "Example page"} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + // Focus state can change before the page's focus event arrives. + entry.Focused = false + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "automatic redirect") + adapter.events <- atspi.NewEvent(atspi.FocusEvent, page) + // Even a stale focused bit must not override the owned document focus. + entry.Focused = true + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, entry, "previous address") + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "new address") + marker := atspi.Snapshot{Path: "/marker", Role: "button", Name: "End"} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, marker) + for _, want := range []string{"autocomplete", "Example page, document web", "End, button"} { + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } +} diff --git a/internal/app/browser_lists.go b/internal/app/browser_lists.go new file mode 100644 index 0000000..21fdd02 --- /dev/null +++ b/internal/app/browser_lists.go @@ -0,0 +1,98 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "strconv" + "strings" + "unicode" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/review" +) + +type documentListSource interface { + ListDocument(context.Context, review.DocumentTarget, int) (review.DocumentListSnapshot, error) + SelectDocumentList(review.DocumentListSnapshot, int) error +} + +func (ui *internalUI) browserListMessage(message string) { + if ui.gate.Locked() || ui.gate.Suspended() { + return + } + ui.speech.Enqueue(speechRequest{Text: message, Role: "system", Cause: "browser-list"}) + if ui.braille != nil { + ui.braille.EnqueueMessage(message) + } +} + +func documentListTarget(binding input.DocumentListBinding) review.DocumentTarget { + switch binding.Command { + case input.DocumentListAnnotations: + return review.DocumentAnnotation + case input.DocumentListInternalFrames: + return review.DocumentInternalFrame + case input.DocumentListMath: + return review.DocumentMath + } + target, _, _ := documentReviewCommand(binding.Next) + return target +} + +func (ui *internalUI) browserList(ctx context.Context, binding input.DocumentListBinding) (*interaction.Session, review.DocumentListSnapshot, error) { + if ui.documents == nil { + return nil, review.DocumentListSnapshot{}, review.ErrNoCurrent + } + list, err := ui.documents.ListDocument(ctx, documentListTarget(binding), binding.Level) + if err != nil { + return nil, list, err + } + if len(list.Entries) == 0 { + return nil, list, nil + } + items := make([]interaction.Item, 0, len(list.Entries)) + for index, position := range list.Entries { + snapshot := position.Snapshot + label := position.Label + if label == "" { + label = snapshot.Name + } + if label == "" && snapshot.Role != "password text" { + label = snapshot.Text + } + if label == "" { + label = snapshot.Role + } + label = strings.Join(strings.FieldsFunc(label, func(r rune) bool { return unicode.IsControl(r) || unicode.IsSpace(r) }), " ") + // Keep the existing form label bound without splitting UTF-8. + labelRunes := []rune(label) + if len(labelRunes) > 225 { + label = string(labelRunes[:225]) + } + if label == "" { + label = snapshot.Role + } + if snapshot.HeadingLevel > 0 { + label += fmt.Sprintf(", heading level %d", snapshot.HeadingLevel) + } + if snapshot.Role == "check box" || snapshot.Role == "radio button" || snapshot.Role == "toggle button" { + if snapshot.Checked { + label += ", checked" + } else { + label += ", not checked" + } + } + items = append(items, interaction.Item{ID: strconv.Itoa(index), Label: label}) + } + title := fmt.Sprintf("%s: %d items found", binding.Title, len(items)) + if len(items) == 1 { + title = binding.Title + ": 1 item found" + } + session, err := interaction.NewNavigationSession(title, items, list.Selected) + return session, list, err +} diff --git a/internal/app/browser_lists_native_test.go b/internal/app/browser_lists_native_test.go new file mode 100644 index 0000000..0ac44e2 --- /dev/null +++ b/internal/app/browser_lists_native_test.go @@ -0,0 +1,135 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeBrowserLists(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser list fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + key := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + var focus atspi.ObjectID + for attempt := 0; attempt < 25 && !focus.Valid(); attempt++ { + key("Tab") + timer := time.NewTimer(150 * time.Millisecond) + loop: + for { + select { + case event := <-adapter.Events(): + if isFocusEvent(event.Type) && event.Source.Name == "Browser foundation" { + focus = event.Source.ID() + break loop + } + case <-timer.C: + break loop + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + timer.Stop() + } + if !focus.Valid() { + t.Fatal("fixture heading focus missing") + } + worker, _ := review.NewWorker(adapter, 2*time.Second) + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(focus) + keys := xorg.NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + if err := keys.Start(ctx); err != nil { + t.Fatal(err) + } + defer keys.Stop(context.Background()) + keys.SetBrowseNavigation(true) + for !keys.BrowseNavigationEnabled() { + if ctx.Err() != nil { + t.Fatal(ctx.Err()) + } + time.Sleep(5 * time.Millisecond) + } + output := &ocrTestOutput{speech: make(chan speechRequest, 32)} + ui := &internalUI{keys: keys, documents: worker, speech: output, gate: newFocusGate(keys), events: make(chan input.CommandEvent, 32), done: make(chan struct{})} + go ui.run(ctx) + done := make(chan struct{}) + go func() { + defer close(done) + for { + select { + case <-ctx.Done(): + return + case event := <-keys.Commands(): + ui.Handle(event) + case <-adapter.Events(): // Keep the native event queue draining. + } + } + }() + defer func() { cancel(); <-ui.done; <-done }() + wait := func(want string) { + t.Helper() + select { + case message := <-output.speech: + if !strings.HasPrefix(message.Text, want) { + t.Fatalf("speech %q, want prefix %q", message.Text, want) + } + case <-ctx.Done(): + t.Fatalf("missing %q: %v", want, ctx.Err()) + } + } + key("alt+shift+k") + wait("Links: 302 items found. First link") + key("Down") + wait("Second link") + key("Return") + select { + case result := <-worker.Results(): + if result.Err != nil || !result.Moved || result.DocumentPosition.Snapshot.Name != "Second link" { + t.Fatalf("list selection: %+v", result) + } + case <-ctx.Done(): + t.Fatal("selection did not reach review worker") + } + key("alt+shift+k") + wait("Links: 302 items found. Second link") + key("Escape") + // The next shortcut follows Escape in the native input stream. + key("alt+shift+a") + wait("Clickables: 1 item found. Custom clickable") + key("Escape") + key("alt+shift+2") + wait("Headings at level 2: 1 item found. Second heading") + key("Escape") + key("alt+shift+g") + wait("Images: 0 items found") + if keys.InternalUISession() != 0 { + t.Fatal("empty list retained keyboard capture") + } +} diff --git a/internal/app/browser_lists_test.go b/internal/app/browser_lists_test.go new file mode 100644 index 0000000..c436b8c --- /dev/null +++ b/internal/app/browser_lists_test.go @@ -0,0 +1,97 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" +) + +type listTestSource struct { + keys *uiTestKeys + selected chan int + count int +} + +func (source *listTestSource) ListDocument(context.Context, review.DocumentTarget, int) (review.DocumentListSnapshot, error) { + list := review.DocumentListSnapshot{Selected: source.count - 1} + for index := 0; index < source.count; index++ { + list.Entries = append(list.Entries, review.DocumentListEntry{DocumentPosition: review.DocumentPosition{Snapshot: atspi.Snapshot{Name: fmt.Sprintf("Example %03d", index), Role: "link"}}}) + } + return list, nil +} +func (source *listTestSource) SelectDocumentList(_ review.DocumentListSnapshot, index int) error { + if source.keys.InternalUISession() != 0 { + index = -1 + } + source.selected <- index + return nil +} + +func TestBrowserListNavigationSelectionAndCancellation(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + keys := &uiTestKeys{} + source := &listTestSource{keys: keys, selected: make(chan int, 1), count: 300} + output := &ocrTestOutput{speech: make(chan speechRequest, 16)} + ui := &internalUI{keys: keys, documents: source, speech: output, gate: &focusGate{}, events: make(chan input.CommandEvent, 16), done: make(chan struct{})} + go ui.run(ctx) + defer func() { cancel(); <-ui.done }() + wait := func(want string) { + t.Helper() + select { + case message := <-output.speech: + if message.Text != want { + t.Fatalf("got %q want %q", message.Text, want) + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + send := func(symbol uint32) { + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Chord: input.CommandChord{Symbol: symbol}}) + } + ui.Handle(input.CommandEvent{Command: input.DocumentListLinks}) + wait("Links: 300 items found. Example 299") + send(0xff50) + wait("Example 000") + send(0xff54) + wait("Example 001") + send(0xff0d) + select { + case index := <-source.selected: + if index != 1 { + t.Fatalf("selected %d or keyboard capture retained", index) + } + case <-ctx.Done(): + t.Fatal("selection did not finish") + } + ui.Handle(input.CommandEvent{Command: input.DocumentListLinks}) + wait("Links: 300 items found. Example 299") + send(0xff1b) + // A second request is processed after Escape, establishing cancellation + // without a timing assumption or a selection callback. + ui.Handle(input.CommandEvent{Command: input.DocumentListLinks}) + wait("Links: 300 items found. Example 299") + select { + case <-source.selected: + t.Fatal("Escape selected an item") + default: + } + send(0xff1b) +} + +func TestBrowserListCatalogMapsAllOrcaListTypes(t *testing.T) { + for _, binding := range input.DocumentListBindings() { + if documentListTarget(binding) == 0 { + t.Fatalf("unhandled %s", binding.Command) + } + } +} diff --git a/internal/app/browser_menu_native_test.go b/internal/app/browser_menu_native_test.go new file mode 100644 index 0000000..063eef6 --- /dev/null +++ b/internal/app/browser_menu_native_test.go @@ -0,0 +1,200 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type menuRecordingAdapter struct { + *atspi.Adapter + events chan atspi.Event +} + +func (adapter *menuRecordingAdapter) Events() <-chan atspi.Event { return adapter.events } + +func TestNativeBrowserMenuControls(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires a private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + native := atspi.New() + if err := native.Start(ctx); err != nil { + t.Fatal(err) + } + defer native.Stop(context.Background()) + adapter := &menuRecordingAdapter{Adapter: native, events: make(chan atspi.Event, 256)} + observed := make(chan atspi.Event, 256) + pumpDone := make(chan struct{}) + go func() { + defer close(pumpDone) + for { + select { + case event := <-native.Events(): + select { + case observed <- event: + case <-ctx.Done(): + return + } + select { + case adapter.events <- event: + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } + }() + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 256)} + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done; <-pumpDone }() + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + waitEvent := func(match func(atspi.Event) bool) atspi.Event { + t.Helper() + for { + select { + case event := <-observed: + if match(event) { + t.Logf("event %s (native %s): %s %q, origin %s", event.Type, event.NativeType, event.Source.Role, event.Source.Name, event.OriginPath) + return event + } + case <-ctx.Done(): + t.Fatal("missing menu event: ", ctx.Err()) + return atspi.Event{} + } + } + } + waitSpeech := func(name string) { + t.Helper() + if name == "" { + t.Fatal("menu control has no accessible name") + } + timer := time.NewTimer(time.Second) + defer timer.Stop() + for { + select { + case request := <-queue.requests: + if strings.Contains(request.Text, name) { + t.Logf("speech: %q", request.Text) + return + } + case <-timer.C: + t.Fatalf("missing menu speech %q", name) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + settle := func() { + t.Helper() + timer := time.NewTimer(100 * time.Millisecond) + defer timer.Stop() + for { + select { + case <-observed: + timer.Reset(100 * time.Millisecond) + case request := <-queue.requests: + if request.Cause == atspi.SelectionChangedEvent || request.Cause == atspi.ActiveDescendantEvent { + t.Fatalf("duplicate menu speech without another key: %q", request.Text) + } + case <-timer.C: + return + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + keys("F10") + waitEvent(func(e atspi.Event) bool { return isFocusGainEvent(e) && strings.Contains(e.Source.Name, "Brave") }) + keys("Down") + waitEvent(func(e atspi.Event) bool { return e.Type == atspi.WindowActivatedEvent && e.Source.Role == "menu" }) + // The app menu wraps; find the row by its real selection rather than + // relying on a fixed number of entries or the current browser profile. + for steps := 0; ; steps++ { + if steps >= 40 { + t.Fatal("Sidebar row absent from app menu") + } + keys("Down") + event := waitEvent(func(e atspi.Event) bool { return e.Type == atspi.SelectionChangedEvent && e.Source.Role == "menu item" }) + waitSpeech(event.Source.Name) + if event.Source.Name == "Sidebar" { + break + } + settle() + } + inline := func(role, rowName string) atspi.Event { + return waitEvent(func(e atspi.Event) bool { + return (e.Type == atspi.SelectedStateEvent || e.NativeType == atspi.SelectedStateEvent) && + e.Detail1 == 1 && e.Source.Role == role && e.Source.Name != rowName + }) + } + first := inline("button", "Sidebar") + waitSpeech(first.Source.Name) + settle() + for _, chord := range []string{"Down", "Down", "Up", "Up", "Down", "Up"} { + keys(chord) + event := inline("button", "Sidebar") + if event.Type != atspi.ActiveDescendantEvent || event.OriginPath == event.Source.Path { + t.Fatalf("inline control lacks menu ownership: %+v", event) + } + waitSpeech(event.Source.Name) + settle() + } + for range 2 { + keys("Down") + event := inline("button", "Sidebar") + waitSpeech(event.Source.Name) + settle() + } + // Continue through the normal entries to the second compound row. + // Its inner controls use menu-item roles rather than button roles. + for steps := 0; ; steps++ { + if steps >= 25 { + t.Fatal("Zoom row absent from app menu") + } + keys("Down") + event := waitEvent(func(e atspi.Event) bool { return e.Type == atspi.SelectionChangedEvent && e.Source.Role == "menu item" }) + waitSpeech(event.Source.Name) + if event.Source.Name == "Zoom" { + break + } + settle() + } + zoom := inline("menu item", "Zoom") + waitSpeech(zoom.Source.Name) + settle() + for _, chord := range []string{"Down", "Down", "Up", "Up", "Down", "Up"} { + keys(chord) + event := inline("menu item", "Zoom") + if event.Type != atspi.ActiveDescendantEvent || event.OriginPath != zoom.OriginPath { + t.Fatalf("Zoom control lacks the same menu owner: %+v", event) + } + waitSpeech(event.Source.Name) + settle() + } + keys("Escape") + waitEvent(func(e atspi.Event) bool { return e.Type == atspi.WindowActivatedEvent && e.Source.Role != "menu" }) + keys("ctrl+l") + waitSpeech("Address and search bar") +} diff --git a/internal/app/browser_mode.go b/internal/app/browser_mode.go new file mode 100644 index 0000000..b87c106 --- /dev/null +++ b/internal/app/browser_mode.go @@ -0,0 +1,467 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +type documentContextCapturer interface { + CaptureDocumentContext(context.Context, atspi.ObjectID) (atspi.DocumentContext, error) +} +type browseKeyOwner interface{ SetBrowseNavigation(bool) } +type commandGrabState interface{ CommandGrabActive() bool } +type browserModeResult struct { + focus atspi.ObjectID + generation uint64 + owner atspi.DocumentContext + origin review.NavigationOrigin + err error +} + +// The event loop owns policy. One joined worker resolves only the latest focus; +// a generation check rejects results overtaken by another focus or caret event. +type browserModeController struct { + source any + keys browseKeyOwner + capturer documentContextCapturer + mutex sync.Mutex + focus atspi.ObjectID + origin review.NavigationOrigin + generation uint64 + captureParent context.Context + captureContext context.Context + captureCancel context.CancelFunc + captureTimeout time.Duration + wake chan struct{} + results chan browserModeResult + toggles chan input.Command + stickyModes map[string]review.DocumentMode + cancel context.CancelFunc + done chan struct{} + document atspi.ObjectID + navigation atspi.ObjectID + navigationDocument atspi.ObjectID + navigationFocus atspi.ObjectID + navigationInput input.Activity + commandAt time.Time + state review.DocumentModeState + mode review.DocumentMode + ready bool + resolving bool +} + +func newBrowserModeController(source any, keys browseKeyOwner, capturer documentContextCapturer) *browserModeController { + return &browserModeController{source: source, keys: keys, capturer: capturer, captureTimeout: 2 * time.Second, wake: make(chan struct{}, 1), results: make(chan browserModeResult, 1), toggles: make(chan input.Command, 8), stickyModes: make(map[string]review.DocumentMode)} +} + +func (browser *browserModeController) invalidateCaptureContextLocked() { + if browser.captureParent == nil { + return + } + if browser.captureCancel != nil { + browser.captureCancel() + browser.captureCancel = nil + } + browser.captureContext, browser.captureCancel = context.WithCancel(browser.captureParent) +} + +func (browser *browserModeController) RecentInput() input.Activity { + return recentInput(browser.source) +} +func (browser *browserModeController) Start(ctx context.Context) error { + ctx, browser.cancel = context.WithCancel(ctx) + browser.mutex.Lock() + browser.captureParent = ctx + browser.captureContext = ctx + browser.captureCancel = nil + browser.mutex.Unlock() + browser.done = make(chan struct{}) + go func() { + defer close(browser.done) + for { + select { + case <-ctx.Done(): + return + case <-browser.wake: + } + if ctx.Err() != nil { + return + } + browser.mutex.Lock() + focus, generation, origin, captureContext := browser.focus, browser.generation, browser.origin, browser.captureContext + browser.mutex.Unlock() + deadline, cancel := context.WithTimeout(captureContext, browser.captureTimeout) + owner, err := browser.capturer.CaptureDocumentContext(deadline, focus) + cancel() + browser.mutex.Lock() + current := focus == browser.focus && generation == browser.generation + browser.mutex.Unlock() + if !current { + continue + } + if errors.Is(err, context.DeadlineExceeded) && captureContext.Err() == nil { + // Retry a slow provider while this focus is still current. A focus + // or load change cancels the wait and leaves its own wake pending. + timer := time.NewTimer(200 * time.Millisecond) + select { + case <-timer.C: + case <-captureContext.Done(): + case <-ctx.Done(): + } + timer.Stop() + if captureContext.Err() == nil && ctx.Err() == nil { + select { + case browser.wake <- struct{}{}: + default: + } + } + continue + } + select { + case browser.results <- browserModeResult{focus: focus, generation: generation, owner: owner, origin: origin, err: err}: + case <-ctx.Done(): + return + } + } + }() + return nil +} +func (browser *browserModeController) Stop(ctx context.Context) error { + browser.keys.SetBrowseNavigation(false) + if browser.cancel == nil { + return nil + } + browser.cancel() + select { + case <-browser.done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} +func (browser *browserModeController) follow(focus atspi.ObjectID) { + browser.followWithOrigin(focus, review.NativeNavigation) +} + +func (browser *browserModeController) followCaret(focus atspi.ObjectID) { + browser.followWithOrigin(focus, review.CaretNavigation) +} + +func (browser *browserModeController) clear() { + browser.nativeButtonFocus(false) + browser.mutex.Lock() + browser.focus = atspi.ObjectID{} + browser.document = atspi.ObjectID{} + browser.navigation = atspi.ObjectID{} + browser.navigationDocument = atspi.ObjectID{} + browser.navigationFocus = atspi.ObjectID{} + browser.generation++ + browser.resolving = false + browser.ready = false + browser.mode = review.InactiveMode + browser.state = review.DocumentModeState{} + browser.invalidateCaptureContextLocked() + browser.mutex.Unlock() + browser.keys.SetBrowseNavigation(false) +} + +func (browser *browserModeController) nativeButtonFocus(focused bool) { + if keys, ok := browser.keys.(interface{ SetNativeButtonFocus(bool) }); ok { + keys.SetNativeButtonFocus(focused) + } +} + +func (browser *browserModeController) followWithOrigin(focus atspi.ObjectID, origin review.NavigationOrigin) { + browser.mutex.Lock() + if focus.Valid() && focus == browser.focus && (browser.ready || browser.resolving) && (origin == browser.origin || browser.ready && browser.mode == review.BrowseMode) { + browser.mutex.Unlock() + return + } + browser.focus = focus + browser.navigationFocus = atspi.ObjectID{} + browser.origin = origin + browser.generation++ + browser.resolving = true + browser.invalidateCaptureContextLocked() + browser.mutex.Unlock() + if origin != review.CaretNavigation { + browser.ready = false + browser.keys.SetBrowseNavigation(false) + } + select { + case browser.wake <- struct{}{}: + default: + } +} +func (browser *browserModeController) accept(result browserModeResult, speech speechEnqueuer) { + browser.mutex.Lock() + current := result.focus == browser.focus && result.generation == browser.generation + browser.mutex.Unlock() + if !current { + return + } + browser.resolving = false + if result.err != nil { + browser.ready = false + browser.mode = review.InactiveMode + browser.keys.SetBrowseNavigation(false) + return + } + if result.owner.TopLevel.ID() != browser.document { + browser.mutex.Lock() + browser.document = result.owner.TopLevel.ID() + browser.mutex.Unlock() + browser.state = review.DocumentModeState{} + browser.state.SetSticky(browser.stickyModes[browser.document.BusName]) + } + browser.ready = true + modeInput := runtimeModeInput(result.owner) + modeInput.Origin = result.origin + mode := browser.state.Update(modeInput, review.DefaultModeSettings()) + browser.set(mode, speech, false) +} +func (browser *browserModeController) set(mode review.DocumentMode, speech speechEnqueuer, manual bool) { + previous := browser.mode + browser.mode = mode + browser.keys.SetBrowseNavigation(mode == review.BrowseMode) + // Python starts web content in browse mode. Entering ordinary document + // content is therefore silent; only an actual automatic mode change (for + // example, browse to focus for an entry) is announced. + if mode == review.InactiveMode || (!manual && (mode == previous || previous == review.InactiveMode && mode == review.BrowseMode)) { + return + } + text := "Browse mode" + cue := "browse_mode" + if mode == review.FocusMode { + text = "Focus mode" + cue = "focus_mode" + } + // Append automatic changes so they do not replace the focused control. + speech.Enqueue(speechRequest{Text: text, Role: "system", Sound: []sound.Cue{{Name: cue}}, Cause: "document-mode", Append: !manual, ResetContext: mode != review.BrowseMode}) +} +func (browser *browserModeController) toggle(speech speechEnqueuer) { + if !browser.ready || browser.mode == review.InactiveMode { + speech.Enqueue(speechRequest{Text: "Not in web document content.", Role: "system", Cause: "document-mode"}) + return + } + delete(browser.stickyModes, browser.document.BusName) + browser.set(browser.state.Toggle(), speech, true) +} + +// Until table layout/PDF/action semantics are resolved, ambiguous widgets stay +// in focus mode. Editable and composite ancestors also keep letters available +// to the application. This is a deliberate conservative runtime subset of the +// more complete reference policy, not guessed false values for missing traits. +func runtimeModeInput(owner atspi.DocumentContext) review.ModeInput { + result := review.ModeInput{Context: owner} + for _, ancestor := range owner.Ancestors { + if ancestor.Editable { + result.Traits.ContentEditableWithEmbeddedObjects = true + } + switch ancestor.Role { + case "table", "table cell", "tree table": + result.Traits.GridDescendant = true + } + } + return result +} + +func (browser *browserModeController) navigated(position review.DocumentPosition, focus atspi.ObjectID) { + browser.mutex.Lock() + browser.focus = position.Snapshot.ID() + browser.origin = position.Origin + browser.generation++ + browser.navigationFocus = focus + browser.navigation = position.Snapshot.ID() + browser.navigationDocument = position.Document.ID() + browser.navigationInput = browser.RecentInput() + browser.document = position.Document.ID() + browser.invalidateCaptureContextLocked() + browser.mutex.Unlock() + browser.state = review.DocumentModeState{} + browser.state.SetSticky(browser.stickyModes[browser.document.BusName]) + browser.mode = browser.state.Current() + browser.ready = true + browser.keys.SetBrowseNavigation(browser.mode == review.BrowseMode) +} + +func (browser *browserModeController) acceptsDocumentResult(result review.Result) bool { + browser.mutex.Lock() + focus := browser.focus + anchor := browser.navigationFocus + browser.mutex.Unlock() + // A pending chrome/other-document focus must not be overwritten by an + // old structural result. Native focus on the target itself is its echo. + if !browser.ready && focus != result.DocumentFocus && focus != result.DocumentPosition.Snapshot.ID() { + return false + } + if browser.mode == review.InactiveMode { + return result.DocumentFragment && focus.Valid() && result.DocumentFocus == focus + } + if (result.DocumentCaretCommand != 0 || result.DocumentActivate) && browser.mode != review.BrowseMode { + return false + } + if result.Err != nil { + // Caret navigation retains the worker's native focus anchor while the + // browser cursor follows a text leaf. Failures have no target position; + // match that anchor so a timeout cannot turn into a silently dead key. + return result.DocumentFocus.Valid() && (result.DocumentFocus == focus || browser.ready && result.DocumentFocus == anchor) + } + if result.DocumentActivate { + return result.DocumentFocus.Valid() && (result.DocumentFocus == focus || browser.ready && result.DocumentFocus == anchor) + } + return result.DocumentPosition.Document.ID() == browser.document +} + +// A load can reuse both the document path and the last focused object path. +// Force context resolution and retire the previous document generation. +func (browser *browserModeController) loaded(focus atspi.ObjectID) { + browser.mutex.Lock() + browser.focus = atspi.ObjectID{} + browser.navigation = atspi.ObjectID{} + browser.navigationDocument = atspi.ObjectID{} + browser.navigationFocus = atspi.ObjectID{} + browser.document = atspi.ObjectID{} + browser.invalidateCaptureContextLocked() + browser.mutex.Unlock() + browser.mode = review.InactiveMode + browser.state = review.DocumentModeState{} + browser.follow(focus) +} + +// Loading retires the old document while keeping window ownership with the +// event loop. A later busy:false, load-stopped, or load-complete can resolve +// the current document again. +func (browser *browserModeController) loading() { + browser.mutex.Lock() + browser.generation++ + browser.resolving = false + browser.ready = false + browser.focus = atspi.ObjectID{} + browser.document = atspi.ObjectID{} + browser.navigation = atspi.ObjectID{} + browser.navigationDocument = atspi.ObjectID{} + browser.navigationFocus = atspi.ObjectID{} + browser.mode = review.InactiveMode + browser.state = review.DocumentModeState{} + browser.invalidateCaptureContextLocked() + browser.mutex.Unlock() + browser.keys.SetBrowseNavigation(false) +} + +func (browser *browserModeController) observeCommand(command input.Command) { + target, _, _ := documentReviewCommand(command) + browser.mutex.Lock() + browser.commandAt = time.Now() + if target != 0 || documentCaretCommand(command) != 0 { + // Reader commands continue virtual navigation. Native events from a + // previous placement remain echoes while the next request is pending. + // Activation or native input may have cleared the previous protection; + // arm it now, before the new worker result can arrive. + if browser.document.Valid() { + browser.navigation = browser.focus + browser.navigationDocument = browser.document + } + browser.navigationInput = browser.RecentInput() + } else { + browser.navigation = atspi.ObjectID{} + browser.navigationDocument = atspi.ObjectID{} + } + browser.mutex.Unlock() +} + +func (browser *browserModeController) pointer_input() { + browser.mutex.Lock() + defer browser.mutex.Unlock() + browser.navigation = atspi.ObjectID{} + browser.navigationDocument = atspi.ObjectID{} +} + +// recentConsumedCommand reports whether X11 just dispatched one of Cthulhu's +// passive command grabs. Some toolkits emit a transient window deactivation as +// a side effect of that grab. Python Cthulhu ignores the same event when its +// last keyboard event was consumed. +func (browser *browserModeController) recentConsumedCommand() bool { + if state, ok := browser.keys.(commandGrabState); ok && state.CommandGrabActive() { + return true + } + browser.mutex.Lock() + defer browser.mutex.Unlock() + return !browser.commandAt.IsZero() && time.Since(browser.commandAt) <= 100*time.Millisecond +} + +func (browser *browserModeController) suppressNavigationEcho(event atspi.Event) bool { + if event.Type == atspi.WindowActivatedEvent || isMenuRole(event.Source.Role) || + event.Source.Editable || event.FocusOutsideDocument.Valid() { + return false + } + browser.mutex.Lock() + activity := browser.RecentInput() + // Like Orca, preserve the virtual position while the last input was a + // reader navigation command. Intent expires; input identity does not. + // An active passive grab also covers the short interval before dispatch. + grabActive := false + if keys, ok := browser.keys.(commandGrabState); ok { + grabActive = keys.CommandGrabActive() + } + if activity.InputSequence != browser.navigationInput.InputSequence && !grabActive { + browser.navigation = atspi.ObjectID{} + browser.navigationDocument = atspi.ObjectID{} + } + target, document := browser.navigation, browser.navigationDocument + browser.mutex.Unlock() + if document.Valid() && event.Type == atspi.AccessibleNameEvent && !event.Source.LiveRegion && + event.Source.Role != "button" && event.Source.Role != "push button" && event.Source.Role != "toggle button" && + event.Source.ID().BusName == document.BusName { + return true + } + if event.Type != atspi.CaretEvent && !isFocusEvent(event.Type) { + return false + } + if atspi.IsWebDocumentRole(event.Source.Role) && event.Source.ID() != document { + return false + } + if target.Valid() && event.Source.ID() == target { + return true + } + // Chromium commonly reports the caret or focus on a newly-created child + // of the structural target rather than on the target itself. The child can + // have an identity which was not present in the captured tree, so ancestry + // cannot be resolved reliably here. Navigation suppression is already + // bounded by the next native input sequence; within that bound, treat + // focus/caret events from the target's browser application as echoes. This + // prevents a child static/link announcement from replacing the structural + // presentation and from moving the independent document cursor to an + // uncaptured identity. + return document.Valid() && event.Source.ID().BusName == document.BusName +} + +func (browser *browserModeController) sticky(mode review.DocumentMode, speech speechEnqueuer) { + if !browser.ready || browser.mode == review.InactiveMode { + speech.Enqueue(speechRequest{Text: "Not in web document content.", Role: "system", Cause: "document-mode"}) + return + } + if len(browser.stickyModes) >= 16 { + clear(browser.stickyModes) + } + browser.stickyModes[browser.document.BusName] = mode + browser.state.SetSticky(mode) + browser.mode = mode + browser.keys.SetBrowseNavigation(mode == review.BrowseMode) + text := "Browse mode is sticky." + if mode == review.FocusMode { + text = "Focus mode is sticky." + } + speech.Enqueue(speechRequest{Text: text, Role: "system", Cause: "document-mode"}) +} diff --git a/internal/app/browser_mode_test.go b/internal/app/browser_mode_test.go new file mode 100644 index 0000000..e5340ef --- /dev/null +++ b/internal/app/browser_mode_test.go @@ -0,0 +1,755 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +type modeKeys struct { + enabled bool + nativeButtonFocus bool +} + +func (keys *modeKeys) SetBrowseNavigation(enabled bool) { keys.enabled = enabled } +func (keys *modeKeys) SetNativeButtonFocus(focused bool) { + keys.nativeButtonFocus = focused +} + +func TestBrowserModeClearsNativeButtonFocus(t *testing.T) { + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + browser.nativeButtonFocus(true) + if !keys.nativeButtonFocus { + t.Fatal("focused button did not request native Return") + } + browser.clear() + if keys.nativeButtonFocus { + t.Fatal("departed button retained native Return policy") + } +} + +type modeSoundQueue struct { + speech *fakeSpeechQueue + sounds chan sound.Cue +} + +func (queue *modeSoundQueue) Enqueue(request speechRequest) { + queue.speech.Enqueue(request) + for _, cue := range request.Sound { + queue.sounds <- cue + } +} + +func (queue *modeSoundQueue) Interrupt() { + queue.speech.Interrupt() +} + +func modeContext(t *testing.T, role string, editableAncestor bool) atspi.DocumentContext { + t.Helper() + return modeContextInDocument(t, role, editableAncestor, "/document") +} +func modeContextInDocument(t *testing.T, role string, editableAncestor bool, documentPath string) atspi.DocumentContext { + t.Helper() + snapshot := atspi.Snapshot{BusName: ":1.42", Path: "/target", Role: role, StatesKnown: true} + doc := atspi.Snapshot{BusName: ":1.42", Path: documentPath, Role: "document web", StatesKnown: true, Editable: editableAncestor} + tree, err := atspi.NewAccessibleTree(doc.ID(), []atspi.TreeNode{{Snapshot: doc, Children: []atspi.ObjectID{snapshot.ID()}}, {Snapshot: snapshot}}) + if err != nil { + t.Fatal(err) + } + ref, _ := tree.Reference(snapshot.ID()) + owner, err := tree.DocumentContext(ref) + if err != nil { + t.Fatal(err) + } + return owner +} +func TestBrowserModeRejectsDepartedFocusAndPreservesTyping(t *testing.T) { + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + queue := &fakeSpeechQueue{spoken: make(chan string, 16)} + heading := modeContext(t, "heading", false) + focus := heading.Ancestors[0].ID() + browser.follow(focus) + browser.accept(browserModeResult{focus: focus, generation: 1, owner: heading}, queue) + if !keys.enabled { + t.Fatal("heading did not enable browse keys") + } + browser.toggle(queue) + if keys.enabled { + t.Fatal("manual focus mode retained letters") + } + browser.toggle(queue) + if !keys.enabled { + t.Fatal("manual browse mode did not restore letters") + } + chrome := atspi.NewObjectID(":1.42", "/chrome") + browser.follow(chrome) + if keys.enabled { + t.Fatal("leaving content did not immediately release letters") + } + browser.accept(browserModeResult{focus: focus, generation: 1, owner: heading}, queue) + if keys.enabled { + t.Fatal("late result re-enabled letters in chrome") + } + browser.accept(browserModeResult{focus: chrome, generation: 2, err: atspi.ErrNotInDocument}, queue) + browser.toggle(queue) + if keys.enabled { + t.Fatal("toggle in chrome enabled letters") + } + entry := modeContext(t, "entry", false) + entryFocus := atspi.NewObjectID(":1.42", "/entry") + browser.follow(entryFocus) + browser.accept(browserModeResult{focus: entryFocus, generation: 3, owner: entry}, queue) + if keys.enabled || browser.mode != review.FocusMode { + t.Fatal("entry did not preserve typing") + } + browser.follow(focus) + browser.accept(browserModeResult{focus: focus, generation: 4, owner: heading}, queue) + if !keys.enabled { + t.Fatal("return to content did not restore navigation") + } +} + +func TestBrowserModeDuplicateFocusKeepsBrowseRouting(t *testing.T) { + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + heading := modeContext(t, "heading", false) + focus := heading.Ancestors[0].ID() + browser.follow(focus) + browser.accept(browserModeResult{focus: focus, generation: 1, owner: heading}, &fakeSpeechQueue{spoken: make(chan string, 1)}) + if !browser.ready || !keys.enabled { + t.Fatal("initial browse routing was not ready") + } + browser.follow(focus) + if !browser.ready || !keys.enabled || browser.generation != 1 { + t.Fatal("duplicate focus restarted browser capture or released browse routing") + } +} + +func TestBrowserCaretLeavesFocusModeForDocumentText(t *testing.T) { + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + queue := &fakeSpeechQueue{spoken: make(chan string, 4)} + entry := modeContext(t, "entry", false) + entryFocus := atspi.NewObjectID(":1.42", "/entry") + browser.follow(entryFocus) + browser.accept(browserModeResult{focus: entryFocus, generation: 1, owner: entry}, queue) + if browser.mode != review.FocusMode || keys.enabled { + t.Fatal("entry did not enter focus mode") + } + + paragraph := modeContext(t, "paragraph", false) + caret := paragraph.Ancestors[0].ID() + browser.followCaret(caret) + if browser.focus != caret || browser.origin != review.CaretNavigation { + t.Fatal("document caret was not tracked") + } + browser.accept(browserModeResult{focus: caret, generation: 2, owner: paragraph, origin: review.CaretNavigation}, queue) + if browser.mode != review.BrowseMode || !keys.enabled { + t.Fatal("caret navigation did not restore browse keys") + } + browser.followCaret(caret) + if browser.generation != 2 || !keys.enabled { + t.Fatal("repeated caret movement restarted browse routing") + } +} + +func TestBrowserModePlaysModeChangeSounds(t *testing.T) { + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + speech := &fakeSpeechQueue{spoken: make(chan string, 16)} + queue := &modeSoundQueue{speech: speech, sounds: make(chan sound.Cue, 16)} + heading := modeContext(t, "heading", false) + entry := modeContext(t, "entry", false) + focus := heading.Ancestors[0].ID() + + browser.follow(focus) + browser.accept(browserModeResult{focus: focus, generation: 1, owner: heading}, queue) + if len(queue.sounds) != 0 || len(speech.spoken) != 0 { + t.Fatal("initial browse mode was announced") + } + + browser.toggle(queue) + assertModeSound(t, queue, speech, "focus_mode", "Focus mode") + + browser.follow(focus) + browser.accept(browserModeResult{focus: focus, generation: 2, owner: entry}, queue) + if len(queue.sounds) != 0 { + t.Fatalf("unchanged mode queued cue %#v", <-queue.sounds) + } + + browser.toggle(queue) + assertModeSound(t, queue, speech, "browse_mode", "Browse mode") +} + +func assertModeSound(t *testing.T, queue *modeSoundQueue, speech *fakeSpeechQueue, wantCue, wantText string) { + t.Helper() + select { + case cue := <-queue.sounds: + if cue.Name != wantCue || cue.Pan != 0 { + t.Fatalf("got mode cue %#v want centered %q", cue, wantCue) + } + case <-time.After(time.Second): + t.Fatalf("mode cue %q was not queued", wantCue) + } + select { + case text := <-speech.spoken: + if text != wantText { + t.Fatalf("got mode text %q want %q", text, wantText) + } + case <-time.After(time.Second): + t.Fatalf("mode text %q was not spoken", wantText) + } +} + +func TestBrowserModeAcceptsSameDocumentNavigationDuringRecapture(t *testing.T) { + browser := newBrowserModeController(nil, &modeKeys{}, nil) + heading := modeContext(t, "heading", false) + focus := heading.Ancestors[0].ID() + browser.follow(focus) + queue := &fakeSpeechQueue{spoken: make(chan string, 1)} + browser.accept(browserModeResult{focus: focus, generation: 1, owner: heading}, queue) + position := review.DocumentPosition{ + Document: heading.TopLevel, + Snapshot: heading.Ancestors[0], + } + if !browser.acceptsDocumentResult(review.Result{DocumentPosition: position}) { + t.Fatal("same-document navigation result rejected") + } + browser.follow(atspi.NewObjectID(":1.42", "/second")) + if browser.ready { + t.Fatal("new focus did not start recapture") + } + if browser.acceptsDocumentResult(review.Result{DocumentPosition: position}) { + t.Fatal("old result accepted while the new focus document is unknown") + } + browser.follow(position.Snapshot.ID()) + if !browser.acceptsDocumentResult(review.Result{DocumentPosition: position}) { + t.Fatal("native focus echo on the structural target rejected") + } + other := modeContextInDocument(t, "heading", false, "/other_document").TopLevel + if browser.acceptsDocumentResult(review.Result{DocumentPosition: review.DocumentPosition{Document: other}}) { + t.Fatal("other-document result accepted") + } + if browser.acceptsDocumentResult(review.Result{Err: errors.New("capture failed"), DocumentPosition: position}) { + t.Fatal("failed result accepted") + } + if !browser.acceptsDocumentResult(review.Result{Err: errors.New("capture failed"), DocumentFocus: position.Snapshot.ID()}) { + t.Fatal("current navigation failure would be silently discarded") + } +} +func TestBrowserRuntimeModeProtectsAmbiguousAndEditableContent(t *testing.T) { + for _, tc := range []struct { + role string + editable bool + want review.DocumentMode + }{ + {"heading", false, review.BrowseMode}, {"entry", false, review.FocusMode}, + {"paragraph", true, review.FocusMode}, {"table cell", false, review.FocusMode}, + {"embedded", false, review.FocusMode}, {"menu item", false, review.FocusMode}, + } { + t.Run(tc.role, func(t *testing.T) { + var state review.DocumentModeState + got := state.Update(runtimeModeInput(modeContext(t, tc.role, tc.editable)), review.DefaultModeSettings()) + if got != tc.want { + t.Fatalf("got %v want %v", got, tc.want) + } + }) + } +} + +type canceledModeCapture struct{ started chan struct{} } + +func (capture canceledModeCapture) CaptureDocumentContext(ctx context.Context, _ atspi.ObjectID) (atspi.DocumentContext, error) { + close(capture.started) + <-ctx.Done() + return atspi.DocumentContext{}, ctx.Err() +} +func TestBrowserModeShutdownCancelsNativeWait(t *testing.T) { + capture := canceledModeCapture{make(chan struct{})} + browser := newBrowserModeController(nil, &modeKeys{}, capture) + if err := browser.Start(context.Background()); err != nil { + t.Fatal(err) + } + browser.follow(atspi.NewObjectID(":1.42", "/target")) + select { + case <-capture.started: + case <-time.After(time.Second): + t.Fatal("capture did not start") + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := browser.Stop(ctx); err != nil && !errors.Is(err, context.Canceled) { + t.Fatal(err) + } +} + +type timeoutThenModeCapture struct { + calls chan struct{} + owner atspi.DocumentContext +} + +func (capture *timeoutThenModeCapture) CaptureDocumentContext(ctx context.Context, _ atspi.ObjectID) (atspi.DocumentContext, error) { + capture.calls <- struct{}{} + if len(capture.calls) == 1 { + <-ctx.Done() + return atspi.DocumentContext{}, ctx.Err() + } + return capture.owner, nil +} + +func TestBrowserModeRetriesTimedOutCurrentFocus(t *testing.T) { + owner := modeContext(t, "heading", false) + focus := owner.Ancestors[0].ID() + capture := &timeoutThenModeCapture{calls: make(chan struct{}, 2), owner: owner} + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, capture) + browser.captureTimeout = 20 * time.Millisecond + if err := browser.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer browser.Stop(context.Background()) + browser.follow(focus) + select { + case result := <-browser.results: + browser.accept(result, &fakeSpeechQueue{spoken: make(chan string, 1)}) + if result.err != nil || result.focus != focus || !keys.enabled || len(capture.calls) != 2 { + t.Fatalf("timed-out capture did not recover: %+v, calls %d", result, len(capture.calls)) + } + case <-time.After(time.Second): + t.Fatal("timed-out capture was not retried") + } +} + +type cancelableModeCapture struct { + started chan atspi.ObjectID + canceled chan atspi.ObjectID +} + +func (capture *cancelableModeCapture) CaptureDocumentContext(ctx context.Context, focus atspi.ObjectID) (atspi.DocumentContext, error) { + started := false + for !started { + select { + case capture.started <- focus: + started = true + case <-ctx.Done(): + return atspi.DocumentContext{}, ctx.Err() + } + } + <-ctx.Done() + select { + case capture.canceled <- focus: + case <-context.Background().Done(): + } + return atspi.DocumentContext{}, ctx.Err() +} + +func TestBrowserModeCancelsCaptureOnLoadLifecycle(t *testing.T) { + first := atspi.NewObjectID(":1.42", "/first") + second := atspi.NewObjectID(":1.42", "/second") + capture := &cancelableModeCapture{ + started: make(chan atspi.ObjectID, 1), + canceled: make(chan atspi.ObjectID, 1), + } + browser := newBrowserModeController(nil, &modeKeys{}, capture) + if err := browser.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer browser.Stop(context.Background()) + + browser.follow(first) + select { + case got := <-capture.started: + if got != first { + t.Fatalf("first capture focus = %v", got) + } + case <-time.After(time.Second): + t.Fatal("first capture did not start") + } + + browser.loading() + select { + case got := <-capture.canceled: + if got != first { + t.Fatalf("canceled capture focus = %v", got) + } + case <-time.After(time.Second): + t.Fatal("page loading did not cancel the old capture") + } + if len(capture.started) != 0 { + t.Fatal("page loading started a new capture before load completion") + } + browser.loaded(second) + select { + case got := <-capture.started: + if got != second { + t.Fatalf("second capture focus = %v", got) + } + case <-time.After(time.Second): + t.Fatal("load completion did not start the latest capture") + } +} + +func TestBrowserLoadingRejectsOldCaptureAndRecoversOnStop(t *testing.T) { + owner := modeContext(t, "heading", false) + focus := owner.Ancestors[0].ID() + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + browser.follow(focus) + browser.accept(browserModeResult{focus: focus, generation: 1, owner: owner}, speech) + if !keys.enabled { + t.Fatal("initial page did not enable browse mode") + } + browser.loading() + if browser.ready || keys.enabled { + t.Fatal("reloading page retained old browse keys") + } + browser.accept(browserModeResult{focus: focus, generation: 1, owner: owner}, speech) + if browser.ready || keys.enabled { + t.Fatal("late pre-reload capture restored the old page") + } + browser.loaded(focus) + browser.accept(browserModeResult{focus: focus, generation: browser.generation, owner: owner}, speech) + if !browser.ready || !keys.enabled { + t.Fatal("stopped page load did not restore browse mode") + } +} + +func TestBrowserModeSuppressesStructuralNavigationEcho(t *testing.T) { + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + target := atspi.NewSnapshot("/target", "Target", "heading", "", "") + target.BusName = ":1.42" + owner := modeContext(t, "heading", false) + browser.navigated(review.DocumentPosition{ + Document: owner.TopLevel, + Snapshot: target, + }, target.ID()) + + for _, eventType := range []string{atspi.CaretEvent, atspi.FocusEvent, atspi.FocusedStateEvent} { + if !browser.suppressNavigationEcho(atspi.NewEvent(eventType, target)) { + t.Fatalf("%s echo was not suppressed", eventType) + } + } + child := atspi.NewSnapshot("/new-child", "Child", "static", "", "") + child.BusName = ":1.42" + for _, eventType := range []string{atspi.CaretEvent, atspi.FocusEvent, atspi.FocusedStateEvent} { + if !browser.suppressNavigationEcho(atspi.NewEvent(eventType, child)) { + t.Fatalf("%s descendant echo was not suppressed", eventType) + } + } + + other := atspi.NewSnapshot("/other", "Other", "heading", "", "") + other.BusName = ":1.99" + if browser.suppressNavigationEcho(atspi.NewEvent(atspi.FocusEvent, other)) { + t.Fatal("unrelated focus echo was suppressed") + } + + browser.observeCommand(input.ToggleDocumentMode) + if browser.suppressNavigationEcho(atspi.NewEvent(atspi.FocusEvent, target)) { + t.Fatal("non-structural command retained navigation suppression") + } +} + +func TestBrowserNavigationEchoEndsOnNativeKey(t *testing.T) { + tracker := &input.IntentTracker{} + tracker.Observe(input.NewKeyEvent(0, true, "h")) + browser := newBrowserModeController(tracker, &modeKeys{}, nil) + target := atspi.Snapshot{BusName: ":1.42", Path: "/heading", Role: "heading"} + browser.navigated(review.DocumentPosition{Snapshot: target}, target.ID()) + if !browser.suppressNavigationEcho(atspi.NewEvent(atspi.CaretEvent, target)) { + t.Fatal("structural echo was not suppressed") + } + tracker.Observe(input.NewKeyEvent(0, true, "Up")) + if browser.suppressNavigationEcho(atspi.NewEvent(atspi.CaretEvent, target)) { + t.Fatal("native movement back into heading was suppressed") + } +} + +func TestBrowserTracksRecentlyConsumedCommand(t *testing.T) { + browser := newBrowserModeController(nil, &modeKeys{}, nil) + if browser.recentConsumedCommand() { + t.Fatal("new browser controller reported a consumed command") + } + browser.observeCommand(input.ReviewNextLine) + if !browser.recentConsumedCommand() { + t.Fatal("fresh command was not reported as consumed") + } + browser.mutex.Lock() + browser.commandAt = time.Now().Add(-time.Second) + browser.mutex.Unlock() + if browser.recentConsumedCommand() { + t.Fatal("stale command was reported as recently consumed") + } +} + +type activeCommandKeys struct { + modeKeys + active bool +} + +func (keys *activeCommandKeys) CommandGrabActive() bool { return keys.active } + +func TestBrowserRecognizesCommandGrabBeforeDispatch(t *testing.T) { + keys := &activeCommandKeys{active: true} + browser := newBrowserModeController(nil, keys, nil) + if !browser.recentConsumedCommand() { + t.Fatal("active command grab was not recognized before dispatch") + } + keys.active = false + if browser.recentConsumedCommand() { + t.Fatal("inactive command grab was reported without a dispatched command") + } +} + +func TestBrowserNavigationEchoSurvivesFastStructuralRepeat(t *testing.T) { + tracker := &input.IntentTracker{} + tracker.Observe(input.NewKeyEvent(0, true, "h")) + browser := newBrowserModeController(tracker, &modeKeys{}, nil) + owner := modeContext(t, "heading", false) + target := atspi.Snapshot{BusName: ":1.42", Path: "/heading", Role: "heading"} + browser.navigated(review.DocumentPosition{Document: owner.TopLevel, Snapshot: target}, target.ID()) + + tracker.Observe(input.NewKeyEvent(0, true, "h")) + browser.observeCommand(input.DocumentNextHeading) + child := atspi.Snapshot{BusName: ":1.42", Path: "/replacement", Role: "static"} + if !browser.suppressNavigationEcho(atspi.NewEvent(atspi.CaretEvent, child)) { + t.Fatal("fast repeated structural command exposed prior caret echo") + } +} + +func TestBrowserNavigationOwnershipSurvivesQueuedReaderCommands(t *testing.T) { + for _, test := range []struct { + name, key string + command input.Command + }{ + {"heading", "h", input.DocumentNextHeading}, + {"reverse heading", "h", input.DocumentPreviousHeading}, + {"line", "Down", input.DocumentCaretNextLine}, + {"character", "Right", input.DocumentCaretNextCharacter}, + } { + t.Run(test.name, func(t *testing.T) { + tracker := &input.IntentTracker{} + tracker.Observe(input.NewKeyEvent(0, true, "h")) + browser := newBrowserModeController(tracker, &modeKeys{}, nil) + owner := modeContext(t, "heading", false) + target := owner.Ancestors[0] + browser.navigated(review.DocumentPosition{Document: owner.TopLevel, Snapshot: target}, owner.TopLevel.ID()) + tracker.Observe(input.NewKeyEvent(0, true, test.key)) + browser.observeCommand(test.command) + child := atspi.Snapshot{BusName: target.BusName, Path: "/old-heading-child", Role: "static"} + if !browser.suppressNavigationEcho(atspi.NewEvent(atspi.CaretEvent, child)) { + t.Fatal("delayed caret reset the cursor while a reader command was pending") + } + tracker.Observe(input.NewKeyEvent(0, true, "Tab")) + if browser.suppressNavigationEcho(atspi.NewEvent(atspi.FocusEvent, child)) { + t.Fatal("native Tab did not release navigation ownership") + } + }) + } +} + +func TestBrowserNavigationOwnershipSurvivesIdleAndEndsOnPointer(t *testing.T) { + source := &fixedInputActivity{activity: input.Activity{InputSequence: 1, Sequence: 1, Intent: input.TypingIntent}} + browser := newBrowserModeController(source, &modeKeys{}, nil) + owner := modeContext(t, "heading", false) + target := owner.Ancestors[0] + browser.navigated(review.DocumentPosition{Document: owner.TopLevel, Snapshot: target}, owner.TopLevel.ID()) + source.activity = input.Activity{InputSequence: 1} + if !browser.suppressNavigationEcho(atspi.NewEvent(atspi.CaretEvent, target)) { + t.Fatal("expired speech intent released the virtual caret") + } + for _, snapshot := range []atspi.Snapshot{ + {BusName: target.BusName, Path: "/entry", Role: "entry", Editable: true}, + {BusName: target.BusName, Path: "/menu", Role: "menu"}, + {BusName: target.BusName, Path: "/other-document", Role: "document web"}, + } { + if browser.suppressNavigationEcho(atspi.NewEvent(atspi.FocusEvent, snapshot)) { + t.Fatalf("suppressed focus on %s", snapshot.Role) + } + } + chrome := atspi.NewEvent(atspi.FocusEvent, target) + chrome.FocusOutsideDocument = atspi.NewObjectID(target.BusName, "/chrome") + if browser.suppressNavigationEcho(chrome) { + t.Fatal("suppressed chrome focus") + } + handler := &accessibilityEventHandler{state: &eventLoopState{}, browser: browser, logger: slog.New(slog.DiscardHandler)} + handler.handle(atspi.Event{Type: atspi.MouseButtonEvent}) + if browser.suppressNavigationEcho(atspi.NewEvent(atspi.CaretEvent, target)) { + t.Fatal("pointer click did not release the virtual caret") + } +} + +func TestQueuedHeadingOwnsCaretAfterActivation(t *testing.T) { + tracker := &input.IntentTracker{} + browser := newBrowserModeController(tracker, &modeKeys{}, nil) + owner := modeContext(t, "link", false) + target := owner.Ancestors[0] + browser.navigated(review.DocumentPosition{Document: owner.TopLevel, Snapshot: target}, owner.TopLevel.ID()) + tracker.Observe(input.NewKeyEvent(0, true, "Return")) + browser.observeCommand(input.DocumentActivate) + tracker.Observe(input.NewKeyEvent(0, true, "h")) + browser.observeCommand(input.DocumentNextHeading) + // A fragment activation can emit multiple paragraph caret events. The + // second can arrive after the heading request but before its result. + paragraph := atspi.Snapshot{BusName: target.BusName, Path: "/fragment", Role: "paragraph"} + if !browser.suppressNavigationEcho(atspi.NewEvent(atspi.CaretEvent, paragraph)) { + t.Fatal("activation caret was allowed to queue behind the heading move") + } +} + +func TestBrowserVirtualPositionSurvivesNativePlacementFailure(t *testing.T) { + worker, err := review.NewWorker(&documentLineCapturer{}, time.Second) + if err != nil { + t.Fatal(err) + } + owner := modeContext(t, "heading", false) + anchor := owner.TopLevel.ID() + worker.SyncFocus(anchor) + browser := newBrowserModeController(nil, &modeKeys{}, nil) + initial := review.DocumentPosition{Document: owner.TopLevel, Snapshot: owner.Ancestors[0]} + browser.navigated(initial, anchor) + state := &eventLoopState{} + state.current, state.presentationOptions = initial.Snapshot, presentation.DefaultOptions() + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + handler := &eventReviewHandler{state: state, browser: browser, objectReview: worker, speech: queue, + logger: slog.New(slog.DiscardHandler), syncForeground: func() {}} + target := atspi.Snapshot{BusName: anchor.BusName, Path: "/replacement-text", Role: "static", Name: "Current total"} + result := review.Result{DocumentEpoch: worker.DocumentEpoch(), DocumentFocus: anchor, + DocumentCaretCommand: review.CaretNextLine, DocumentCaretText: target.Name, Moved: true, + DocumentPosition: review.DocumentPosition{Document: owner.TopLevel, Snapshot: target, Offset: 4}, + CaretErr: atspi.ErrStaleSnapshot} + handler.handle(result) + if state.current.ID() != target.ID() || browser.navigation != target.ID() || worker.Focus() != anchor { + t.Fatal("native placement failure displaced the virtual position or its native anchor") + } + // A late result still cannot overwrite a newly focused browser control. + browser.follow(atspi.NewObjectID(anchor.BusName, "/address")) + state.current = atspi.Snapshot{BusName: anchor.BusName, Path: "/address", Role: "entry", Editable: true} + handler.handle(result) + if state.current.Path != "/address" { + t.Fatal("late virtual move displaced browser chrome") + } +} + +func TestBrowserLoadRetiresPositionEvenWhenPathIsReused(t *testing.T) { + browser := newBrowserModeController(nil, &modeKeys{}, nil) + owner := modeContext(t, "heading", false) + position := review.DocumentPosition{Document: owner.TopLevel, Snapshot: owner.Ancestors[0]} + browser.navigated(position, position.Snapshot.ID()) + browser.loaded(position.Snapshot.ID()) + if browser.ready || browser.mode != review.InactiveMode || browser.acceptsDocumentResult(review.Result{DocumentPosition: position}) { + t.Fatal("load retained the old document position") + } + if browser.suppressNavigationEcho(atspi.NewEvent(atspi.FocusEvent, position.Snapshot)) { + t.Fatal("load retained old navigation echo suppression") + } + select { + case <-browser.wake: + default: + t.Fatal("same-path load did not schedule fresh context capture") + } +} + +func TestBrowserLoadAcceptsCurrentFragmentTarget(t *testing.T) { + browser := newBrowserModeController(nil, &modeKeys{}, nil) + document := atspi.NewObjectID(":1.42", "/document") + browser.loaded(document) + result := review.Result{DocumentFragment: true, DocumentFocus: document, Moved: true} + if !browser.acceptsDocumentResult(result) { + t.Fatal("current document fragment was rejected before context resolution") + } + result.DocumentFocus = atspi.NewObjectID(":1.42", "/old_document") + if browser.acceptsDocumentResult(result) { + t.Fatal("old document fragment crossed a page load") + } +} + +func TestBrowserModeRetriesSameFocusAfterCaptureFailure(t *testing.T) { + browser := newBrowserModeController(nil, &modeKeys{}, nil) + owner := modeContext(t, "heading", false) + focus := owner.Ancestors[0].ID() + browser.follow(focus) + browser.accept(browserModeResult{focus: focus, generation: 1, err: atspi.ErrStaleObject}, &fakeSpeechQueue{}) + browser.follow(focus) + if browser.generation != 2 { + t.Fatal("transient context failure permanently disabled same-object navigation") + } + browser.accept(browserModeResult{focus: focus, generation: 2, owner: owner}, &fakeSpeechQueue{}) + if !browser.ready || browser.mode != review.BrowseMode { + t.Fatal("same-object retry did not restore browse mode") + } +} + +func TestBrowserReportsNavigationFailureAfterCaretMovesFromNativeFocus(t *testing.T) { + browser := newBrowserModeController(nil, &modeKeys{}, nil) + owner := modeContext(t, "heading", false) + anchor := owner.TopLevel.ID() + position := review.DocumentPosition{Document: owner.TopLevel, Snapshot: owner.Ancestors[0], Origin: review.CaretNavigation} + browser.navigated(position, anchor) + for _, result := range []review.Result{ + {DocumentCaretCommand: review.CaretNextLine, DocumentFocus: anchor, Err: context.DeadlineExceeded}, + {DocumentTarget: review.DocumentHeading, DocumentFocus: anchor, Err: context.DeadlineExceeded}, + {DocumentActivate: true, DocumentFocus: anchor, Err: context.DeadlineExceeded}, + } { + if !browser.acceptsDocumentResult(result) { + t.Fatalf("current navigation error was silently discarded: %+v", result) + } + result.DocumentFocus = atspi.NewObjectID(anchor.BusName, "/another-document") + if browser.acceptsDocumentResult(result) { + t.Fatal("accepted an unrelated navigation error") + } + } + browser.follow(atspi.NewObjectID(anchor.BusName, "/address-bar")) + if browser.acceptsDocumentResult(review.Result{DocumentCaretCommand: review.CaretNextLine, DocumentFocus: anchor, Err: context.DeadlineExceeded}) { + t.Fatal("old document error interrupted chrome focus") + } +} + +func TestStickyBrowserModeSurvivesNavigationChromeAndWindowSuspension(t *testing.T) { + for _, mode := range []review.DocumentMode{review.BrowseMode, review.FocusMode} { + keys := &modeKeys{} + browser := newBrowserModeController(nil, keys, nil) + queue := &fakeSpeechQueue{spoken: make(chan string, 20)} + owner := modeContext(t, "paragraph", false) + focus := owner.Ancestors[0].ID() + accept := func(owner atspi.DocumentContext) { + browser.follow(focus) + browser.accept(browserModeResult{focus: focus, generation: browser.generation, owner: owner}, queue) + } + accept(owner) + browser.sticky(mode, queue) + browser.navigated(review.DocumentPosition{Document: owner.TopLevel, Snapshot: owner.Ancestors[0]}, focus) + if browser.mode != mode { + t.Fatal("navigation discarded sticky mode") + } + browser.clear() + accept(modeContext(t, "entry", false)) + if browser.mode != mode || keys.enabled != (mode == review.BrowseMode) { + t.Fatal("window return lost sticky mode") + } + browser.loaded(focus) + accept(modeContextInDocument(t, "entry", false, "/new_document")) + if browser.mode != mode { + t.Fatal("new document lost sticky mode") + } + browser.toggle(queue) + if browser.state.Sticky() != review.InactiveMode || len(browser.stickyModes) != 0 { + t.Fatal("single press failed to clear sticky mode") + } + } +} diff --git a/internal/app/browser_nested_document_native_test.go b/internal/app/browser_nested_document_native_test.go new file mode 100644 index 0000000..5d279d2 --- /dev/null +++ b/internal/app/browser_nested_document_native_test.go @@ -0,0 +1,130 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeBrowserNestedDocumentHeadings(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, `Nested document headings

First heading

`) + for i := 0; i < 200; i++ { + fmt.Fprint(w, `
`) + for depth := 0; depth < 15; depth++ { + fmt.Fprint(w, `
`) + } + fmt.Fprintf(w, `

Post %d

Post body %d

`, i, i) + for depth := 0; depth < 15; depth++ { + fmt.Fprint(w, `
`) + } + fmt.Fprint(w, `
`) + } + fmt.Fprint(w, `

Last heading

`) + })) + defer server.Close() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + command := func(args ...string) { + t.Helper() + if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("xdotool: %v: %s", err, output) + } + } + window, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "Cthulhu Browser Probe").Output() + if err != nil || len(strings.Fields(string(window))) == 0 { + t.Fatalf("browser window: %s: %v", window, err) + } + command("windowfocus", "--sync", strings.Fields(string(window))[0]) + command("key", "--clearmodifiers", "ctrl+l") + // The X window can appear before browser startup finishes. Wait for + // native address-bar focus so startup cannot swallow the URL keystrokes. + addressFocused := false + retryFocus := time.NewTicker(time.Second) + defer retryFocus.Stop() + for !addressFocused { + select { + case event := <-adapter.Events(): + addressFocused = event.Type == atspi.FocusedStateEvent && event.Detail1 == 1 && event.Source.Editable + case <-retryFocus.C: + command("key", "--clearmodifiers", "ctrl+l") + case <-ctx.Done(): + t.Fatal("browser address-bar focus: ", ctx.Err()) + } + } + command("key", "--clearmodifiers", "ctrl+a") + command("type", "--clearmodifiers", "--delay", "1", server.URL) + command("key", "Return") + var document atspi.ObjectID + for !document.Valid() { + select { + case event := <-adapter.Events(): + if event.Type == atspi.DocumentLoadCompleteEvent && event.Source.Name == "Nested document headings" { + document = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + worker, err := review.NewWorker(adapter, 2*time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.SetDocumentCaptureTimeout(documentCaptureTimeout); err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(document) + result := func(want string) { + t.Helper() + select { + case result := <-worker.Results(): + if result.CaptureDuration > 0 { + t.Logf("whole-document capture: %v", result.CaptureDuration) + } + if result.Err != nil || result.DocumentPosition.Snapshot.Name != want { + t.Fatalf("navigation = %q, want %q: err=%v capture=%v diagnostics=%+v", result.DocumentPosition.Snapshot.Name, want, result.Err, result.CaptureReason, result.DocumentDiagnostics) + } + if result.DocumentSoundErr != nil || !result.DocumentPosition.Snapshot.SoundGeometry.ObjectKnown || !result.DocumentPosition.Snapshot.SoundGeometry.ReferenceKnown { + t.Fatalf("heading sound geometry unavailable: %+v, %v", result.DocumentPosition.Snapshot.SoundGeometry, result.DocumentSoundErr) + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + for _, step := range []struct { + backwards bool + want string + }{ + {false, "First heading"}, {true, "Last heading"}, {true, "Post 199"}, {false, "Last heading"}, {false, "First heading"}, + } { + if err := worker.MoveDocument(review.DocumentHeading, 0, step.backwards); err != nil { + t.Fatal(err) + } + result(step.want) + } +} diff --git a/internal/app/browser_replacement_native_test.go b/internal/app/browser_replacement_native_test.go new file mode 100644 index 0000000..5e9cd10 --- /dev/null +++ b/internal/app/browser_replacement_native_test.go @@ -0,0 +1,188 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "os" + "os/exec" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeBrowserInlineReplacementNavigation(t *testing.T) { + run_native_replacement_navigation(t, false) +} + +func TestNativeBrowserGeneratedLinkNavigation(t *testing.T) { + run_native_replacement_navigation(t, true) +} + +func run_native_replacement_navigation(t *testing.T, generated bool) { + t.Helper() + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if generated { + fmt.Fprint(w, `Inline replacement regression + +

Published by Publisher some hours ago. Article continues

`) + return + } + fmt.Fprint(w, `Inline replacement regression +

Published↺ by PublisherArticle continues

+`) + })) + defer server.Close() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + command := func(args ...string) { + t.Helper() + if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("xdotool: %v: %s", err, output) + } + } + command("key", "--clearmodifiers", "ctrl+l") + command("type", "--clearmodifiers", "--delay", "0", server.URL) + command("key", "Return") + var document atspi.ObjectID + for !document.Valid() { + select { + case event := <-adapter.Events(): + if event.Type == atspi.DocumentLoadCompleteEvent && event.Source.Name == "Inline replacement regression" { + document = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + worker, err := review.NewWorker(adapter, 2*time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(document) + dump_generated_tree := func() { + if !generated { + return + } + tree, captureErr := adapter.CaptureDocument(ctx, document) + if captureErr != nil { + return + } + ref, _ := tree.Reference(document) + doc, _ := tree.Document(ctx, ref) + for _, node := range doc.Nodes { + if node.Snapshot.Role == "static" { + text, err := adapter.ReadDocumentCaret(ctx, node.Reference, 0, atspi.DocumentCaretLine) + t.Logf("native node %s parent=%s name=%q count=%d text=%+v err=%v", node.Snapshot.Path, node.Parent.Path, node.Snapshot.Name, node.Snapshot.CharacterCount, text, err) + } + } + } + move := func(command review.DocumentCaretCommand, want string) review.Result { + t.Helper() + if err := worker.MoveDocumentCaret(command); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + // Generated text can disappear between a successful virtual move + // and native placement. A caret error must not undo that move; + // require the exact text and subsequent navigation/replacement + // checks rather than requiring the transient native caret to stick. + if result.Err != nil || result.CaretErr != nil && !generated || !result.Moved || result.DocumentCaretText != want { + dump_generated_tree() + t.Fatalf("%s: text=%q want=%q err=%v caret=%v diagnostics=%+v", command, + result.DocumentCaretText, want, result.Err, result.CaretErr, result.DocumentDiagnostics) + } + if generated && result.CaretErr != nil { + t.Logf("generated native caret: %v; virtual movement succeeded", result.CaretErr) + } + return result + case <-ctx.Done(): + t.Fatal(ctx.Err()) + return review.Result{} + } + } + move(review.CaretNextLine, "Published") + attribution, after := "↺ by Publisher", "Article continues" + if generated { + attribution, after = "↺ by Publisher some hours ago", ". Article continues" + } + current := move(review.CaretNextLine, attribution) + for generation := 0; generation < 4; generation++ { + old := current.DocumentPosition.Object + if !generated { + command("key", "--clearmodifiers", "F8") + } + // Require a genuinely replaced native static-text object. Merely + // changing a label would not exercise recovery of a missing cursor. + for { + tree, err := adapter.CaptureDocument(ctx, document) + if err != nil { + t.Fatal(err) + } + if _, err := tree.Resolve(old); err != nil { + break + } + select { + case <-adapter.Events(): + case <-ctx.Done(): + t.Fatal("native attribution object was not replaced: ", ctx.Err()) + } + } + if generation%2 == 0 { + move(review.CaretNextLine, after) + current = move(review.CaretPreviousLine, attribution) + } else { + move(review.CaretPreviousLine, "Published") + current = move(review.CaretNextLine, attribution) + } + } + if err := worker.ReadAll(ctx); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + if result.Err != nil || len(result.ReadAllLines) != 2 { + t.Fatalf("Read All after replacement: err=%v lines=%d", result.Err, len(result.ReadAllLines)) + } + for index, want := range []string{attribution, after} { + if got := result.ReadAllLines[index].Contents[0].Text; got != want { + dump_generated_tree() + t.Fatalf("Read All line %d: %q, want %q", index, got, want) + } + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } +} diff --git a/internal/app/browser_reveal_native_test.go b/internal/app/browser_reveal_native_test.go new file mode 100644 index 0000000..b678369 --- /dev/null +++ b/internal/app/browser_reveal_native_test.go @@ -0,0 +1,155 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeBrowserRevealedHeadings(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, `Revealed headings regression + +

Across

`) + for i := 1; i <= 12; i++ { + class := "" + if i > 5 { + class = "hidden" + } + fmt.Fprintf(w, `
%d

Clue %d

`, class, i, i, i) + } + fmt.Fprint(w, `
+

Following section

`) + })) + defer server.Close() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + command := func(args ...string) { + t.Helper() + if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("xdotool: %v: %s", err, output) + } + } + window, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "Cthulhu Browser Probe").Output() + if err != nil || len(strings.Fields(string(window))) == 0 { + t.Fatalf("browser window: %s: %v", window, err) + } + command("windowfocus", strings.Fields(string(window))[0]) + command("key", "--clearmodifiers", "ctrl+l") + command("type", "--clearmodifiers", "--delay", "1", server.URL) + command("key", "Return") + var document atspi.ObjectID + for !document.Valid() { + select { + case event := <-adapter.Events(): + if event.Type == atspi.DocumentLoadCompleteEvent && event.Source.Name == "Revealed headings regression" { + document = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + worker, err := review.NewWorker(adapter, 2*time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(document) + result := func(want string) { + t.Helper() + select { + case result := <-worker.Results(): + if result.Err != nil || result.DocumentPosition.Snapshot.Name != want { + t.Fatalf("navigation = %q, want %q: err=%v capture=%v diagnostics=%+v", result.DocumentPosition.Snapshot.Name, want, result.Err, result.CaptureReason, result.DocumentDiagnostics) + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + if err := worker.MoveDocument(review.DocumentHeading, 0, false); err != nil { + t.Fatal(err) + } + result("Across") + if err := worker.MoveDocument(review.DocumentHeading, 0, true); err != nil { + t.Fatal(err) + } + result("Following section") + if err := worker.MoveDocumentCaret(review.CaretPreviousLine); err != nil { + t.Fatal(err) + } + result("More clues") + activate := func(want string) { + t.Helper() + if err := worker.ActivateDocumentCaret(); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + if result.Err != nil { + t.Fatal(result.Err) + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + for { + select { + case event := <-adapter.Events(): + if event.Type == atspi.AccessibleNameEvent && event.Source.Name == want && event.Source.Role == "button" { + return + } + case <-ctx.Done(): + t.Fatal("clue toggle was not observed: ", ctx.Err()) + } + } + } + activate("Fewer clues") + // The added headings precede the button. Browse in both directions + // without ever tabbing into the new content. + for _, step := range []struct { + backwards bool + want string + }{ + {true, "Clue 12"}, + {true, "Clue 11"}, + {false, "Clue 12"}, + {false, "Following section"}, + } { + if err := worker.MoveDocument(review.DocumentHeading, 0, step.backwards); err != nil { + t.Fatal(err) + } + result(step.want) + } + if err := worker.MoveDocumentCaret(review.CaretPreviousLine); err != nil { + t.Fatal(err) + } + result("Fewer clues") + activate("More clues") + if err := worker.MoveDocument(review.DocumentHeading, 0, true); err != nil { + t.Fatal(err) + } + result("Clue 5") +} diff --git a/internal/app/browser_tabs_native_test.go b/internal/app/browser_tabs_native_test.go new file mode 100644 index 0000000..9ac5ef5 --- /dev/null +++ b/internal/app/browser_tabs_native_test.go @@ -0,0 +1,125 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +func TestNativeBrowserTabs(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" && os.Getenv("CTHULHU_NATIVE_FIREFOX") != "1" { + t.Skip("requires a private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + listener := xorg.New() + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 128)} + logFile, err := os.CreateTemp("/tmp", "cthulhu-tabs-events-*.log") + if err != nil { + t.Fatal(err) + } + defer logFile.Close() + t.Logf("event diagnostics: %s", logFile.Name()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.NewTextHandler(logFile, &slog.HandlerOptions{Level: slog.LevelDebug})), queue, adapter, nil, nil, 0, nil, listener, nil, nil) + }() + defer func() { cancel(); <-done }() + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + wait := func(role, text string) speechRequest { + t.Helper() + for { + select { + case request := <-queue.requests: + t.Logf("speech: %s %q (%s, append=%v)", request.Role, request.Text, request.Cause, request.Append) + if request.Role == role && (text == "" || request.Text == text || + role == "page tab" && strings.Contains(request.Text, text)) { + return request + } + case <-ctx.Done(): + t.Fatalf("missing %s %q: %v", role, text, ctx.Err()) + return speechRequest{} + } + } + } + settle := func(checkTab bool) { + t.Helper() + // Drain the asynchronous event burst before the next chord so a + // duplicate from one operation cannot satisfy the next assertion. + timer := time.NewTimer(150 * time.Millisecond) + defer timer.Stop() + for { + select { + case request := <-queue.requests: + if checkTab && request.Role == "page tab" { + t.Fatalf("extra tab announcement without another chord: %#v", request) + } + if checkTab && (request.Cause == atspi.TextDeletedEvent || request.Cause == atspi.TextInsertedEvent) { + t.Fatalf("automatic address rewrite spoken: %#v", request) + } + timer.Reset(150 * time.Millisecond) + case <-timer.C: + return + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + keys("ctrl+l") + // Firefox's address control is exposed as a combo box. + role := "entry" + if os.Getenv("CTHULHU_NATIVE_FIREFOX") == "1" { + role = "combo box" + } + wait(role, "") + settle(false) + for i := 0; i < 2; i++ { + keys("ctrl+t") + request := wait("page tab", "New Tab") + if request.Cause != atspi.SelectedStateEvent && request.Cause != atspi.SelectionChangedEvent { + t.Fatalf("new tab did not use selected state: %#v", request) + } + settle(true) + } + keys("ctrl+shift+Tab") + wait("page tab", "New Tab") + settle(true) + keys("ctrl+w") + wait("page tab", "New Tab") + settle(true) + keys("ctrl+w") + wait("page tab", "Cthulhu") + settle(true) + keys("ctrl+l") + keys("x") + wait(role, "x") + settle(false) + keys("BackSpace") + wait(role, "x") +} diff --git a/internal/app/browser_tooltip_native_test.go b/internal/app/browser_tooltip_native_test.go new file mode 100644 index 0000000..0dc8547 --- /dev/null +++ b/internal/app/browser_tooltip_native_test.go @@ -0,0 +1,117 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "os" + "os/exec" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeBrowserTooltipNavigation(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprint(w, `Tooltip navigation regression +`) + })) + defer server.Close() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + command := func(args ...string) { + t.Helper() + if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("xdotool: %v: %s", err, output) + } + } + command("key", "--clearmodifiers", "ctrl+l") + command("type", "--clearmodifiers", "--delay", "0", server.URL) + command("key", "Return") + var document atspi.ObjectID + for !document.Valid() { + select { + case event := <-adapter.Events(): + if event.Type == atspi.DocumentLoadCompleteEvent && event.Source.Name == "Tooltip navigation regression" { + document = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + worker, err := review.NewWorker(adapter, 2*time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(document) + move := func(command review.DocumentCaretCommand, want string) { + t.Helper() + if err := worker.MoveDocumentCaret(command); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + if result.Err != nil || result.CaretErr != nil || !result.Moved || result.DocumentCaretText != want { + t.Fatalf("%s: text=%q want=%q err=%v caret=%v diagnostics=%+v", command, + result.DocumentCaretText, want, result.Err, result.CaretErr, result.DocumentDiagnostics) + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + move(review.CaretNextLine, "Example project") + // Capture after focus has exposed the tooltip. This proves the fixture + // supplies a real native tooltip subtree, rather than merely hidden text. + for { + tree, err := adapter.CaptureDocument(ctx, document) + if err != nil { + t.Fatal(err) + } + ref, _ := tree.Reference(document) + doc, err := tree.Document(ctx, ref) + found := false + if err == nil { + for _, node := range doc.Nodes { + if node.Snapshot.Role == "tool tip" && !node.Hidden && len(node.Children) > 0 { + found = true + } + } + } + if found { + break + } + select { + case <-adapter.Events(): + case <-ctx.Done(): + t.Fatal("visible native tooltip missing: ", ctx.Err()) + } + } + move(review.CaretNextLine, "After project") + move(review.CaretPreviousLine, "Example project") + move(review.CaretLineEnd, "t") + move(review.CaretNextCharacter, "A") + move(review.CaretPreviousCharacter, "t") +} diff --git a/internal/app/capitalization.go b/internal/app/capitalization.go new file mode 100644 index 0000000..1d2a951 --- /dev/null +++ b/internal/app/capitalization.go @@ -0,0 +1,52 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "unicode" + "unicode/utf8" +) + +func capitalCharacter(text string) bool { + letter, size := utf8.DecodeRuneInString(text) + return size == len(text) && unicode.IsUpper(letter) +} + +func capitalVoice(customEcho bool) string { + if customEcho { + return "uppercase-echo" + } + return "uppercase" +} + +// Called only by serialized speech delivery, after mode and context handling. +// No cue outlives its owning request's cancellation context. +func (worker *speechWorker) present_capital(ctx context.Context, request speechRequest) error { + if worker.capitalization == nil { + return nil + } + beep, sayCap := worker.capitalization() + if beep && worker.capitalBeep != nil { + if err := worker.capitalBeep(ctx); err != nil { + if ctx.Err() != nil { + return ctx.Err() + } + worker.logger.Warn("capital letter beep", "error", err) + } + } + if err := ctx.Err(); err != nil { + return err + } + if sayCap { + if voice, ok := worker.speaker.(interface { + SpeakVoiceAndWait(context.Context, string, string, func()) error + }); ok { + return voice.SpeakVoiceAndWait(ctx, "cap", capitalVoice(request.CustomEcho), nil) + } + return worker.speaker.Speak(ctx, "cap") + } + return nil +} diff --git a/internal/app/capitalization_test.go b/internal/app/capitalization_test.go new file mode 100644 index 0000000..ce3d263 --- /dev/null +++ b/internal/app/capitalization_test.go @@ -0,0 +1,37 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + "testing" +) + +func TestCapitalBeepCancellationAndFailure(t *testing.T) { + for _, interrupt := range []bool{false, true} { + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.capitalization = func() (bool, bool) { return true, true } + ctx, cancel := context.WithCancel(context.Background()) + worker.capitalBeep = func(beepContext context.Context) error { + if interrupt { + cancel() + return beepContext.Err() + } + return errors.New("audio unavailable") + } + err := worker.deliver(ctx, speechRequest{Text: "A", Character: true}) + cancel() + if interrupt { + if !errors.Is(err, context.Canceled) || len(speaker.parts) != 0 { + t.Fatalf("canceled capital: %v %v", err, speaker.parts) + } + } else if err != nil || len(speaker.parts) != 2 || speaker.parts[0] != "cap" || speaker.parts[1] != "A" { + t.Fatalf("failed beep suppressed speech: %v %v", err, speaker.parts) + } + } +} diff --git a/internal/app/character_attributes.go b/internal/app/character_attributes.go new file mode 100644 index 0000000..dcc7703 --- /dev/null +++ b/internal/app/character_attributes.go @@ -0,0 +1,261 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "fmt" + "strconv" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" +) + +type characterAttributeSource interface { + ReadCharacterAttributes(context.Context, atspi.ObjectID) (atspi.CharacterAttributes, error) +} + +type characterAttributeResult struct { + object atspi.ObjectID + sequence uint64 + values map[string]string + err error +} + +type characterAttributeRequest struct { + object atspi.ObjectID + sequence uint64 +} + +type characterAttributeReader struct { + requests chan characterAttributeRequest + results chan characterAttributeResult + cancel context.CancelFunc + done chan struct{} +} + +// This reader owns one native query at a time and one waiting request. Native +// work stays on AT-SPI's GLib owner; the event loop remains responsive. +func startCharacterAttributeReader(parent context.Context, adapter Adapter) *characterAttributeReader { + ctx, cancel := context.WithCancel(parent) + reader := &characterAttributeReader{ + requests: make(chan characterAttributeRequest, 1), + results: make(chan characterAttributeResult, 1), + cancel: cancel, + done: make(chan struct{}), + } + source, supported := adapter.(characterAttributeSource) + go func() { + defer close(reader.done) + for { + select { + case <-ctx.Done(): + return + case request := <-reader.requests: + result := characterAttributeResult{object: request.object, sequence: request.sequence} + if supported && request.object.Valid() { + deadline, cancel := context.WithTimeout(ctx, 1200*time.Millisecond) + attributes, err := source.ReadCharacterAttributes(deadline, request.object) + cancel() + result.values, result.err = attributes.Values, err + } else { + result.err = atspi.ErrStaleObject + } + select { + case reader.results <- result: + case <-ctx.Done(): + return + } + } + } + }() + return reader +} + +func (reader *characterAttributeReader) request(object atspi.ObjectID, sequence uint64) { + if !object.Valid() { + return + } + request := characterAttributeRequest{object: object, sequence: sequence} + select { + case reader.requests <- request: + default: + select { + case <-reader.requests: + default: + } + select { + case reader.requests <- request: + default: + } + } +} + +func (reader *characterAttributeReader) stop() { + reader.cancel() + <-reader.done +} + +func presentCharacterAttributes(speech speechEnqueuer, result characterAttributeResult, useColorNames bool, configured ...config.TextAttributeSettings) { + if errors.Is(result.err, atspi.ErrStaleObject) || errors.Is(result.err, context.Canceled) { + return + } + message := "Text attributes are unavailable." + if result.err == nil { + if parts := spokenCharacterAttributes(result.values, useColorNames, configured...); len(parts) != 0 { + message = strings.Join(parts, ", ") + } else { + message = "No text attributes to speak." + } + } + speech.Enqueue(speechRequest{Text: message, Role: "system", Cause: "character-attributes"}) +} + +var characterAttributeOrder = [...]struct { + key, label, ignore string +}{ + {"size", "font size", ""}, + {"family-name", "font family", ""}, + {"weight", "weight", "400"}, + {"indent", "indent", "0"}, + {"underline", "underline", "none"}, + {"strikethrough", "strikethrough", "false"}, + {"justification", "justification", "left"}, + {"style", "style", "normal"}, + {"paragraph-style", "paragraph style", ""}, + {"text-spelling", "spelling", "none"}, + {"fg-color", "foreground color", ""}, + {"bg-color", "background color", ""}, +} + +func spokenCharacterAttributes(values map[string]string, useColorNames bool, configured ...config.TextAttributeSettings) []string { + parts := make([]string, 0, len(characterAttributeOrder)) + order := make([]struct{ key, label, ignore string }, 0, len(characterAttributeOrder)) + if len(configured) == 0 { + order = append(order, characterAttributeOrder[:]...) + } else { + for _, choice := range configured[0].Choices { + if !choice.Speak { + continue + } + for _, known := range characterAttributeOrder { + if choice.Key == known.key { + order = append(order, known) + break + } + } + } + } + for _, attribute := range order { + if attribute.key == "text-spelling" { + if atspi.TextAttributesMisspelled(values) { + parts = append(parts, "misspelled") + } + continue + } + value := strings.TrimSpace(values[attribute.key]) + if value == "" || value == attribute.ignore || value == "0" && attribute.ignore == "0" { + continue + } + switch attribute.key { + case "weight": + if number, ok := parseAttributeInteger(value); value == "bold" || ok && number > 400 { + parts = append(parts, "bold") + continue + } + case "family-name": + value = strings.Trim(strings.TrimSpace(strings.Split(value, ",")[0]), "\"") + case "fg-color", "bg-color": + if color, ok := describeAttributeColor(value, useColorNames); ok { + value = color + } + } + parts = append(parts, attribute.label+": "+value) + } + return parts +} + +func parseAttributeInteger(value string) (int, bool) { + number, err := strconv.Atoi(value) + return number, err == nil +} + +func describeAttributeColor(value string, useColorNames bool) (string, bool) { + red, green, blue, ok := parseAttributeColor(value) + if !ok { + return "", false + } + if useColorNames { + return nearestCSSColor(red, green, blue), true + } + return fmt.Sprintf("%d %d %d", red, green, blue), true +} + +func parseAttributeColor(value string) (int, int, int, bool) { + value = strings.ToLower(strings.TrimSpace(value)) + if strings.HasPrefix(value, "#") { + if len(value) == 4 { + value = "#" + strings.Repeat(value[1:2], 2) + strings.Repeat(value[2:3], 2) + strings.Repeat(value[3:4], 2) + } + if len(value) != 7 { + return 0, 0, 0, false + } + var channels [3]int + for index := range channels { + number, err := strconv.ParseUint(value[1+index*2:3+index*2], 16, 8) + if err != nil { + return 0, 0, 0, false + } + channels[index] = int(number) + } + return channels[0], channels[1], channels[2], true + } + value = strings.TrimPrefix(value, "rgb(") + value = strings.TrimSuffix(value, ")") + fields := strings.Split(value, ",") + if len(fields) != 3 { + return 0, 0, 0, false + } + var channels [3]int + for index, field := range fields { + number, err := strconv.Atoi(strings.TrimSpace(field)) + if err != nil || number < 0 || number > 65535 { + return 0, 0, 0, false + } + channels[index] = number + } + if channels[0] > 255 || channels[1] > 255 || channels[2] > 255 { + for index, number := range channels { + channels[index] = (number*255 + 32767) / 65535 + } + } + return channels[0], channels[1], channels[2], true +} + +func nearestCSSColor(red, green, blue int) string { + hex := fmt.Sprintf("#%02x%02x%02x", red, green, blue) + if name := cssColorNames[hex]; name != "" { + return name + } + bestDistance, secondDistance := int(^uint(0)>>1), int(^uint(0)>>1) + bestHex, secondHex := "", "" + for candidate := range cssColorNames { + r, g, b, _ := parseAttributeColor(candidate) + distance := (r-red)*(r-red) + (g-green)*(g-green) + (b-blue)*(b-blue) + if distance < bestDistance || distance == bestDistance && candidate < bestHex { + secondDistance, secondHex = bestDistance, bestHex + bestDistance, bestHex = distance, candidate + } else if distance < secondDistance || distance == secondDistance && candidate < secondHex { + secondDistance, secondHex = distance, candidate + } + } + if (bestHex == "#000000" || bestHex == "#ffffff") && secondHex != "" && secondDistance-bestDistance < bestDistance { + bestHex = secondHex + } + return cssColorNames[bestHex] +} diff --git a/internal/app/character_attributes_test.go b/internal/app/character_attributes_test.go new file mode 100644 index 0000000..7ff9e4b --- /dev/null +++ b/internal/app/character_attributes_test.go @@ -0,0 +1,81 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestCharacterAttributeColorSettingChangesSpokenValues(t *testing.T) { + attributes := map[string]string{ + "family-name": "Liberation Sans, Sans", + "weight": "700", + "underline": "none", + "fg-color": "rgb(65535, 0, 0)", + "bg-color": "#0000ff", + "text-spelling": "spelling", + } + named := strings.Join(spokenCharacterAttributes(attributes, true), ", ") + for _, want := range []string{"font family: Liberation Sans", "bold", "misspelled", "foreground color: red", "background color: blue"} { + if !strings.Contains(named, want) { + t.Errorf("named attributes %q missing %q", named, want) + } + } + if strings.Contains(named, "underline") { + t.Errorf("default underline was spoken: %q", named) + } + numeric := strings.Join(spokenCharacterAttributes(attributes, false), ", ") + for _, want := range []string{"foreground color: 255 0 0", "background color: 0 0 255"} { + if !strings.Contains(numeric, want) { + t.Errorf("numeric attributes %q missing %q", numeric, want) + } + } +} + +func TestConfiguredCharacterAttributesRespectSelectionAndOrder(t *testing.T) { + settings := config.DefaultTextAttributes() + for index := range settings.Choices { + settings.Choices[index].Speak = false + } + settings.Choices[0], settings.Choices[2] = settings.Choices[2], settings.Choices[0] + settings.Choices[0].Speak, settings.Choices[2].Speak = true, true + got := strings.Join(spokenCharacterAttributes(map[string]string{"size": "14", "weight": "700", "underline": "single"}, true, settings), ", ") + if got != "bold, font size: 14" { + t.Fatalf("attributes = %q", got) + } +} + +func TestSpellingAttributeUsesProviderInvalidValue(t *testing.T) { + settings := config.DefaultTextAttributes() + for index := range settings.Choices { + settings.Choices[index].Speak = settings.Choices[index].Key == "text-spelling" + } + got := strings.Join(spokenCharacterAttributes(map[string]string{"invalid": "spelling"}, true, settings), ", ") + if got != "misspelled" { + t.Fatalf("spelling attribute = %q", got) + } +} + +func TestCharacterAttributeColorParsingAndFallback(t *testing.T) { + for _, probe := range []struct { + input, want string + }{ + {"#f00", "red"}, + {"rgb(255, 0, 0)", "red"}, + {"rgb(65535, 0, 0)", "red"}, + {"#fefefe", "white"}, + } { + got, ok := describeAttributeColor(probe.input, true) + if !ok || got != probe.want { + t.Errorf("%q: %q, %v; want %q", probe.input, got, ok, probe.want) + } + } + if got := strings.Join(spokenCharacterAttributes(map[string]string{"fg-color": "transparent"}, true), ", "); got != "foreground color: transparent" { + t.Errorf("unsupported provider color changed: %q", got) + } +} diff --git a/internal/app/character_color_names.go b/internal/app/character_color_names.go new file mode 100644 index 0000000..6f268a5 --- /dev/null +++ b/internal/app/character_color_names.go @@ -0,0 +1,147 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// CSS color coordinates and names from the Python Cthulhu reference. +package app + +var cssColorNames = map[string]string{ + "#f0f8ff": "alice blue", + "#faebd7": "antique white", + "#7fffd4": "aquamarine", + "#f0ffff": "azure", + "#f5f5dc": "beige", + "#ffe4c4": "bisque", + "#000000": "black", + "#ffebcd": "blanched almond", + "#0000ff": "blue", + "#8a2be2": "blue violet", + "#a52a2a": "brown", + "#deb887": "burlywood", + "#5f9ea0": "cadet blue", + "#7fff00": "chartreuse", + "#d2691e": "chocolate", + "#ff7f50": "coral", + "#6495ed": "cornflower blue", + "#fff8dc": "cornsilk", + "#dc143c": "crimson", + "#00ffff": "cyan", + "#00008b": "dark blue", + "#008b8b": "dark cyan", + "#b8860b": "dark goldenrod", + "#a9a9a9": "dark gray", + "#006400": "dark green", + "#bdb76b": "dark khaki", + "#8b008b": "dark magenta", + "#556b2f": "dark olive green", + "#ff8c00": "dark orange", + "#9932cc": "dark orchid", + "#8b0000": "dark red", + "#e9967a": "dark salmon", + "#8fbc8f": "dark sea green", + "#483d8b": "dark slate blue", + "#2f4f4f": "dark slate gray", + "#00ced1": "dark turquoise", + "#9400d3": "dark violet", + "#ff1493": "deep pink", + "#00bfff": "deep sky blue", + "#696969": "dim gray", + "#1e90ff": "dodger blue", + "#b22222": "fire brick", + "#fffaf0": "floral white", + "#228b22": "forest green", + "#ff00ff": "magenta", + "#dcdcdc": "gainsboro", + "#f8f8ff": "ghost white", + "#ffd700": "gold", + "#daa520": "goldenrod", + "#808080": "gray", + "#008000": "green", + "#adff2f": "green yellow", + "#f0fff0": "honeydew", + "#ff69b4": "hot pink", + "#cd5c5c": "indian red", + "#4b0082": "indigo", + "#fffff0": "ivory", + "#f0e68c": "khaki", + "#e6e6fa": "lavender", + "#fff0f5": "lavender blush", + "#7cfc00": "lawn green", + "#fffacd": "lemon chiffon", + "#add8e6": "light blue", + "#f08080": "light coral", + "#e0ffff": "light cyan", + "#fafad2": "light goldenrod yellow", + "#d3d3d3": "light gray", + "#90ee90": "light green", + "#ffb6c1": "light pink", + "#ffa07a": "light salmon", + "#20b2aa": "light sea green", + "#87cefa": "light sky blue", + "#778899": "light slate gray", + "#b0c4de": "light steel blue", + "#ffffe0": "light yellow", + "#00ff00": "lime", + "#32cd32": "lime green", + "#faf0e6": "linen", + "#800000": "maroon", + "#66cdaa": "medium aquamarine", + "#0000cd": "medium blue", + "#ba55d3": "medium orchid", + "#9370d8": "medium purple", + "#3cb371": "medium sea green", + "#7b68ee": "medium slate blue", + "#00fa9a": "medium spring green", + "#48d1cc": "medium turquoise", + "#c71585": "medium violet red", + "#191970": "midnight blue", + "#f5fffa": "mint cream", + "#ffe4e1": "misty rose", + "#ffe4b5": "moccasin", + "#ffdead": "navajo white", + "#000080": "navy", + "#fdf5e6": "old lace", + "#808000": "olive", + "#6b8e23": "olive drab", + "#ffa500": "orange", + "#ff4500": "orange red", + "#da70d6": "orchid", + "#eee8aa": "pale goldenrod", + "#98fb98": "pale green", + "#afeeee": "pale turquoise", + "#d87093": "pale violet red", + "#ffefd5": "papaya whip", + "#ffdab9": "peach puff", + "#cd853f": "peru", + "#ffc0cb": "pink", + "#dda0dd": "plum", + "#b0e0e6": "powder blue", + "#800080": "purple", + "#ff0000": "red", + "#bc8f8f": "rosy brown", + "#4169e1": "royal blue", + "#8b4513": "saddle brown", + "#fa8072": "salmon", + "#f4a460": "sandy brown", + "#2e8b57": "sea green", + "#fff5ee": "seashell", + "#a0522d": "sienna", + "#c0c0c0": "silver", + "#87ceeb": "sky blue", + "#6a5acd": "slate blue", + "#708090": "slate gray", + "#fffafa": "snow", + "#00ff7f": "spring green", + "#4682b4": "steel blue", + "#d2b48c": "tan", + "#008080": "teal", + "#d8bfd8": "thistle", + "#ff6347": "tomato", + "#40e0d0": "turquoise", + "#ee82ee": "violet", + "#f5deb3": "wheat", + "#ffffff": "white", + "#f5f5f5": "white smoke", + "#ffff00": "yellow", + "#9acd32": "yellow green", +} diff --git a/internal/app/clipboard.go b/internal/app/clipboard.go new file mode 100644 index 0000000..c4be918 --- /dev/null +++ b/internal/app/clipboard.go @@ -0,0 +1,64 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "encoding/json" + "errors" + "git.stormux.org/storm/cthulhu/internal/platform/session" + "os" + "os/exec" + "time" +) + +const clipboardReadTimeout = 3 * time.Second + +func runClipboardWorker(ctx context.Context, requests <-chan struct{}, speech speechEnqueuer, read func(context.Context) (string, error)) <-chan struct{} { + done := make(chan struct{}) + go func() { + defer close(done) + for { + select { + case <-ctx.Done(): + return + case <-requests: + requestCtx, cancel := context.WithTimeout(ctx, clipboardReadTimeout) + result, err := read(requestCtx) + cancel() + if ctx.Err() != nil { + return + } + message := "Error accessing clipboard" + if err == nil { + message = result + } + speech.Enqueue(speechRequest{Text: message, Role: "system", Cause: "clipboard"}) + } + } + }() + return done +} + +func readClipboardMessage(ctx context.Context) (string, error) { + executable, err := os.Executable() + if err != nil { + return "", err + } + command := exec.CommandContext(ctx, executable, "--clipboard-read") + command.Env = session.GTKEnvironment() + command.WaitDelay = time.Second + output, err := command.Output() + if err != nil { + return "", err + } + var result struct { + Message string `json:"message"` + } + if err := json.Unmarshal(output, &result); err != nil || result.Message == "" { + return "", errors.New("invalid clipboard helper response") + } + return result.Message, nil +} diff --git a/internal/app/clipboard_copy.go b/internal/app/clipboard_copy.go new file mode 100644 index 0000000..d1a5847 --- /dev/null +++ b/internal/app/clipboard_copy.go @@ -0,0 +1,45 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func runCopyFeedback(ctx context.Context, changes <-chan struct{}, source any, speech speechEnqueuer, live *liveSettings, ocr *ocrSession) <-chan struct{} { + done := make(chan struct{}) + go func() { + defer close(done) + var announced uint64 + for { + select { + case <-ctx.Done(): + return + case _, ok := <-changes: + if !ok { + return + } + activity := recentInput(source) + if ocr != nil && ocr.Reviewing() { + if activity.Clipboard == input.CopyAction { + announced = activity.Sequence + } + continue + } + if live != nil && live.Load().Reading.AutomaticallyReadClipboardChanges { + continue + } + if activity.Clipboard != input.CopyAction || activity.Sequence == 0 || activity.Sequence == announced { + continue + } + announced = activity.Sequence + speech.Enqueue(speechRequest{Text: "copied to clipboard", Role: "system", Cause: "clipboard"}) + } + } + }() + return done +} diff --git a/internal/app/clipboard_copy_test.go b/internal/app/clipboard_copy_test.go new file mode 100644 index 0000000..475f7b4 --- /dev/null +++ b/internal/app/clipboard_copy_test.go @@ -0,0 +1,110 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/ocr" +) + +func TestCopyFeedbackRequiresClipboardChangeAndNewCopyKey(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + changes := make(chan struct{}) + tracker := &input.IntentTracker{} + speech := &fakeSpeechQueue{spoken: make(chan string, 4), interrupt: make(chan struct{}, 4)} + done := runCopyFeedback(ctx, changes, tracker, speech, nil, nil) + checkSilent := func() { + t.Helper() + select { + case got := <-speech.spoken: + t.Fatalf("unexpected speech %q", got) + case <-time.After(30 * time.Millisecond): + } + } + change := func() { changes <- struct{}{} } + change() + checkSilent() + tracker.Observe(input.NewKeyEvent(0, true, "Control_L")) + tracker.Observe(input.NewKeyEvent(0, true, "c")) + checkSilent() + change() + select { + case got := <-speech.spoken: + if got != "copied to clipboard" { + t.Fatalf("copy speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("copy was not announced") + } + change() + checkSilent() + tracker.Observe(input.NewKeyEvent(0, true, "c")) + change() + select { + case got := <-speech.spoken: + if got != "copied to clipboard" { + t.Fatalf("second copy speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("second copy was not announced") + } + tracker.Observe(input.NewKeyEvent(0, true, "v")) + change() + checkSilent() + cancel() + select { + case <-done: + case <-time.After(time.Second): + t.Fatal("copy worker did not stop") + } +} + +func TestCopyFeedbackDoesNotRepeatOCRCopy(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + changes := make(chan struct{}) + tracker := &input.IntentTracker{} + speech := &fakeSpeechQueue{spoken: make(chan string, 2), interrupt: make(chan struct{}, 2)} + session := &ocrSession{cursor: ocr.NewCursor(ocr.Result{Text: "OCR"}), cancel: func() {}} + done := runCopyFeedback(ctx, changes, tracker, speech, nil, session) + tracker.Observe(input.NewKeyEvent(0, true, "Control_L")) + tracker.Observe(input.NewKeyEvent(0, true, "c")) + changes <- struct{}{} + select { + case got := <-speech.spoken: + t.Fatalf("duplicate OCR copy feedback %q", got) + case <-time.After(30 * time.Millisecond): + } + session.mu.Lock() + session.cursor, session.cancel = nil, nil + session.mu.Unlock() + changes <- struct{}{} + select { + case got := <-speech.spoken: + t.Fatalf("late duplicate OCR copy feedback %q", got) + case <-time.After(30 * time.Millisecond): + } + tracker.Observe(input.NewKeyEvent(0, true, "c")) + changes <- struct{}{} + select { + case got := <-speech.spoken: + if got != "copied to clipboard" { + t.Fatal(got) + } + case <-time.After(time.Second): + t.Fatal("ordinary copy feedback was suppressed") + } + cancel() + select { + case <-done: + case <-time.After(time.Second): + t.Fatal("copy worker did not stop") + } +} diff --git a/internal/app/clipboard_test.go b/internal/app/clipboard_test.go new file mode 100644 index 0000000..2129cca --- /dev/null +++ b/internal/app/clipboard_test.go @@ -0,0 +1,52 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "testing" + "time" +) + +func TestClipboardWorkerAnnouncesContentAndAccessError(t *testing.T) { + for _, test := range []struct { + name string + read func(context.Context) (string, error) + wantText string + }{ + {"text", func(context.Context) (string, error) { + return "Text in clipboard sample", nil + }, "Text in clipboard sample"}, + {"error", func(context.Context) (string, error) { + return "", errors.New("unavailable") + }, "Error accessing clipboard"}, + } { + t.Run(test.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + requests := make(chan struct{}, 1) + speech := &fakeSpeechQueue{spoken: make(chan string, 1), interrupt: make(chan struct{}, 1)} + done := runClipboardWorker(ctx, requests, speech, test.read) + requests <- struct{}{} + select { + case got := <-speech.spoken: + if got != test.wantText { + t.Fatalf("speech = %q, want %q", got, test.wantText) + } + case <-time.After(time.Second): + t.Fatal("clipboard announcement missing") + } + if len(speech.interrupt) != 0 { + t.Fatal("clipboard result interrupted earlier speech") + } + cancel() + select { + case <-done: + case <-time.After(time.Second): + t.Fatal("clipboard worker did not stop") + } + }) + } +} diff --git a/internal/app/clipboard_watch.go b/internal/app/clipboard_watch.go new file mode 100644 index 0000000..06b20a1 --- /dev/null +++ b/internal/app/clipboard_watch.go @@ -0,0 +1,179 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "io" + "log/slog" + "os" + "os/exec" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/clipboard" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/platform/session" +) + +type clipboardScope struct { + settings *config.Settings + application, requested string + enabled bool +} + +func clipboard_scope(live *liveSettings, gate *focusGate) clipboardScope { + scope := clipboardScope{settings: live.current.Load()} + if name := live.application.Load(); name != nil { + scope.application = *name + } + if name := live.requestedApplication.Load(); name != nil { + scope.requested = *name + } + scope.enabled = scope.settings.Reading.AutomaticallyReadClipboardChanges && !gate.Locked() && !gate.Suspended() && + (scope.requested == "" || scope.requested == scope.application) + return scope +} + +func run_automatic_clipboard(ctx context.Context, logger *slog.Logger, live *liveSettings, gate *focusGate, speech speechEnqueuer) <-chan struct{} { + done := make(chan struct{}) + go func() { + defer close(done) + if live == nil { + return + } + // No helper or clipboard reads until an application enables the feature. + ticker := time.NewTicker(20 * time.Millisecond) + defer ticker.Stop() + for !clipboard_scope(live, gate).enabled { + select { + case <-ctx.Done(): + return + case <-live.clipboardChanges: + case <-ticker.C: + } + } + ticker.Stop() + if err := watch_clipboard(ctx, live, gate, speech); err != nil && ctx.Err() == nil { + logger.Warn("automatic clipboard reading unavailable", "error", err) + } + }() + return done +} + +func watch_clipboard(ctx context.Context, live *liveSettings, gate *focusGate, speech speechEnqueuer) error { + executable, err := os.Executable() + if err != nil { + return err + } + childCtx, cancel := context.WithCancel(ctx) + defer cancel() + command := exec.CommandContext(childCtx, executable, "--clipboard-watch") + command.Env = session.GTKEnvironment() + command.WaitDelay = time.Second + in, err := command.StdinPipe() + if err != nil { + return err + } + defer in.Close() + out, err := command.StdoutPipe() + if err != nil { + return err + } + defer out.Close() + var diagnostic preferencesStderr + command.Stderr = &diagnostic + if err := command.Start(); err != nil { + return err + } + defer func() { cancel(); in.Close(); out.Close(); command.Wait() }() + changes := make(chan clipboard.TextChange, 128) + failures := make(chan error, 1) + readerDone := make(chan struct{}) + go func() { + defer close(readerDone) + scanner := bufio.NewScanner(out) + scanner.Buffer(make([]byte, 4096), 1024*1024) + for scanner.Scan() { + var change clipboard.TextChange + if err := json.Unmarshal(scanner.Bytes(), &change); err != nil { + failures <- err + return + } + select { + case changes <- change: + case <-childCtx.Done(): + return + } + } + err := scanner.Err() + if err == nil { + err = io.EOF + } + failures <- err + }() + defer func() { cancel(); out.Close(); <-readerDone }() + return serve_clipboard_changes(ctx, live, gate, speech, json.NewEncoder(in), changes, failures) +} + +func serve_clipboard_changes(ctx context.Context, live *liveSettings, gate *focusGate, speech speechEnqueuer, encoder *json.Encoder, changes <-chan clipboard.TextChange, failures <-chan error) error { + ticker := time.NewTicker(20 * time.Millisecond) + defer ticker.Stop() + var previous clipboardScope + var epoch uint64 + var lastText string + update := func() error { + scope := clipboard_scope(live, gate) + if scope == previous { + return nil + } + previous = scope + epoch++ + lastText = "" + return encoder.Encode(clipboard.WatchSettings{Enabled: scope.enabled, Epoch: epoch}) + } + if err := update(); err != nil { + return err + } + for { + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-failures: + return err + case <-live.clipboardChanges: + if err := update(); err != nil { + return err + } + case <-ticker.C: + // Check the screen-lock gate without polling clipboard contents. + if err := update(); err != nil { + return err + } + case change, ok := <-changes: + if !ok { + return errors.New("clipboard helper closed") + } + if change.Ready { + continue + } + if clipboard_scope(live, gate) != previous { + if err := update(); err != nil { + return err + } + } + if !previous.enabled || change.Epoch != epoch { + continue + } + if strings.TrimSpace(change.Text) != "" && change.Text != lastText { + speech.Enqueue(speechRequest{Text: change.Text, Role: "system", Cause: "clipboard", Append: true, ClipboardTimestamp: change.Timestamp}) + } + lastText = change.Text + } + } +} diff --git a/internal/app/clipboard_watch_test.go b/internal/app/clipboard_watch_test.go new file mode 100644 index 0000000..4fda302 --- /dev/null +++ b/internal/app/clipboard_watch_test.go @@ -0,0 +1,99 @@ +package app + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/clipboard" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestAutomaticClipboardQueuesTextAndNormalInputCancels(t *testing.T) { + live := &liveSettings{} + settings := config.DefaultSettings() + if settings.Reading.AutomaticallyReadClipboardChanges { + t.Fatal("clipboard reading defaults on") + } + settings.Reading.AutomaticallyReadClipboardChanges = true + live.Store(settings) + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.running = true // Inspect the real FIFO without a delivery goroutine. + changes := make(chan clipboard.TextChange, 6) + changes <- clipboard.TextChange{Text: "First", Epoch: 1, Timestamp: 10} + changes <- clipboard.TextChange{Text: "Second", Epoch: 1, Timestamp: 20} + changes <- clipboard.TextChange{Text: "", Epoch: 1, Timestamp: 30} + changes <- clipboard.TextChange{Text: "Third", Epoch: 1, Timestamp: 40} + close(changes) + var output bytes.Buffer + serve_clipboard_changes(context.Background(), live, nil, worker, json.NewEncoder(&output), changes, nil) + if len(worker.pending) != 3 { + t.Fatalf("clipboard queue = %+v", worker.pending) + } + for i, want := range []string{"First", "Second", "Third"} { + if worker.pending[i].Text != want || !worker.pending[i].Append { + t.Fatalf("clipboard request %d = %+v", i, worker.pending[i]) + } + } + if !worker.InterruptForInput(input.Event{Pressed: true, Name: "Control_L", Timestamp: 50}) || len(worker.pending) != 0 { + t.Fatal("normal input did not clear clipboard queue") + } + worker.Enqueue(speechRequest{Text: "Late old clipboard", Cause: "clipboard", Append: true, ClipboardTimestamp: 40}) + if len(worker.pending) != 0 { + t.Fatal("old asynchronous clipboard reply replayed after interruption") + } + worker.Enqueue(speechRequest{Text: "New clipboard", Cause: "clipboard", Append: true, ClipboardTimestamp: 60}) + if len(worker.pending) != 1 { + t.Fatal("new clipboard change suppressed after interruption") + } + worker.Enqueue(speechRequest{Text: "Same millisecond copy", Cause: "clipboard", Append: true, ClipboardTimestamp: 50}) + if len(worker.pending) != 2 { + t.Fatal("copy result in same server millisecond as input was suppressed") + } +} + +func TestAutomaticClipboardRejectsDisabledAndStaleApplications(t *testing.T) { + for _, tc := range []struct { + name string + enabled, pending bool + }{ + {"disabled", false, false}, {"switching", true, true}, {"stale epoch", true, false}, + } { + t.Run(tc.name, func(t *testing.T) { + live := &liveSettings{} + settings := config.DefaultSettings() + settings.Reading.AutomaticallyReadClipboardChanges = tc.enabled + live.Store(settings) + if tc.pending { + name := "Other Application" + live.requestedApplication.Store(&name) + } + changes := make(chan clipboard.TextChange, 1) + changes <- clipboard.TextChange{Text: "Do not speak", Epoch: 0} + close(changes) + speech := &fakeSpeechQueue{spoken: make(chan string, 1), interrupt: make(chan struct{}, 1)} + var output bytes.Buffer + serve_clipboard_changes(context.Background(), live, nil, speech, json.NewEncoder(&output), changes, nil) + if len(speech.spoken) != 0 || len(speech.interrupt) != 0 { + t.Fatal("disabled/stale clipboard was spoken") + } + }) + } +} + +func TestAutomaticClipboardDisabledStartsNoHelperAndStops(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + live := &liveSettings{clipboardChanges: make(chan struct{}, 1)} + live.Store(config.DefaultSettings()) + done := run_automatic_clipboard(ctx, slog.New(slog.DiscardHandler), live, nil, discardSpeech{}) + cancel() + select { + case <-done: + case <-time.After(time.Second): + t.Fatal("disabled clipboard worker did not stop") + } +} diff --git a/internal/app/combo_presentation.go b/internal/app/combo_presentation.go new file mode 100644 index 0000000..5c86732 --- /dev/null +++ b/internal/app/combo_presentation.go @@ -0,0 +1,39 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +// The event loop owns this history. Some toolkits repeat focus on the semantic +// combo when its internal selection changes; that is not entry into a control. +type comboPresentation struct { + focus atspi.ObjectID + value string +} + +func (history *comboPresentation) observe(event atspi.Event) (text string, update, duplicate bool) { + focusGain := isFocusGainEvent(event) + if event.Source.Role != "combo box" { + if focusGain { + history.focus, history.value = event.Source.ID(), "" + } + return "", false, false + } + if !focusGain && !isValueChangeEvent(event.Type) && + event.Type != atspi.AccessibleNameEvent && !isManagedDescendantEvent(event.Type) { + return "", false, false + } + text = presentation.ComboBoxSelectionText(event.Source) + update = !focusGain || event.Source.ID() == history.focus + duplicate = update && event.Source.ID() == history.focus && text == history.value + history.value = text + if focusGain { + history.focus = event.Source.ID() + } + return text, update, duplicate +} diff --git a/internal/app/combo_presentation_test.go b/internal/app/combo_presentation_test.go new file mode 100644 index 0000000..9fc8896 --- /dev/null +++ b/internal/app/combo_presentation_test.go @@ -0,0 +1,60 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +func TestComboSelectionSpeaksValueWithoutRepeatingRoleSound(t *testing.T) { + for _, kind := range []string{atspi.FocusEvent, atspi.FocusedStateEvent, atspi.AccessibleNameEvent, atspi.AccessibleValueEvent, atspi.ValueChangedEvent} { + t.Run(kind, func(t *testing.T) { + queue := &modeSoundQueue{speech: &fakeSpeechQueue{spoken: make(chan string, 16)}, sounds: make(chan sound.Cue, 16)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 16)} + combo := atspi.Snapshot{BusName: ":1.70", Path: "/combo", Role: "combo box", Focused: true, ValueText: "bacon"} + focus := atspi.NewEvent(atspi.FocusEvent, combo) + adapter.events <- focus + adapter.events <- focus // Providers can repeat focus while the combo stays active. + for _, value := range []string{"hamburger", "steak", "hamburger", "bacon"} { + combo.ValueText = value + changed := atspi.NewEvent(kind, combo) + changed.Detail1 = 1 + changed.OriginPath = combo.Path + adapter.events <- changed + } + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: combo.BusName, Path: "/other", Role: "entry", Name: "Other", Focused: true}) + adapter.events <- focus + close(adapter.events) + options := presentation.DefaultOptions() + options.EnableSound, options.PlaySoundForRole = true, true + options.RoleSoundPresentation = "sound_only" + processEventsWithInput(context.Background(), slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil, options) + close(queue.speech.spoken) + var got []string + for text := range queue.speech.spoken { + got = append(got, text) + } + want := []string{"bacon", "hamburger", "steak", "hamburger", "bacon", "Other, entry", "bacon"} + if !reflect.DeepEqual(got, want) { + t.Fatalf("speech = %q, want %q", got, want) + } + if len(queue.sounds) != 2 { + t.Fatalf("got %d sounds, want only initial and returning focus", len(queue.sounds)) + } + for range 2 { + if cue := <-queue.sounds; cue.Name != "combobox" { + t.Fatalf("cue = %+v", cue) + } + } + }) + } +} diff --git a/internal/app/command_input_test.go b/internal/app/command_input_test.go new file mode 100644 index 0000000..65c05b0 --- /dev/null +++ b/internal/app/command_input_test.go @@ -0,0 +1,109 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestRunPresentsLockStatesWithKeyEchoDisabled(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSound = false + settings.EnableBraille = false + settings.EnableKeyEcho = false + speaker := &fakeSpeaker{spoken: make(chan string, 4)} + commands := &fakeCommands{commands: make(chan input.CommandEvent), lockStates: make(chan input.LockState)} + ctx, cancel := context.WithCancel(context.Background()) + completed := make(chan error, 1) + go func() { + completed <- Run(ctx, Options{ + Logger: slog.New(slog.DiscardHandler), Settings: &settings, + newCommands: func() commandListener { return commands }, + newSpeaker: func() Speaker { return speaker }, + newAdapter: func() Adapter { return &fakeAdapter{events: make(chan atspi.Event)} }, + newInput: func() InputListener { return &fakeInputListener{events: make(chan input.Event)} }, + }) + }() + defer func() { + cancel() + select { + case err := <-completed: + if err != nil { + t.Error(err) + } + case <-time.After(time.Second): + t.Error("reader did not stop") + } + }() + select { + case <-speaker.spoken: + case <-time.After(time.Second): + t.Fatal("missing startup speech") + } + for _, name := range []string{"Caps Lock", "Num Lock", "Scroll Lock"} { + for _, locked := range []bool{true, false} { + state := input.LockState{Name: name, Locked: locked, Timestamp: 100} + select { + case commands.lockStates <- state: + case <-time.After(time.Second): + t.Fatal("lock event was not received") + } + select { + case text := <-speaker.spoken: + if text != state.Text() { + t.Fatalf("speech = %q, want %q", text, state.Text()) + } + case <-time.After(time.Second): + t.Fatal("lock state did not reach speech") + } + } + } +} + +func TestCommandSpeechSurvivesDelayedInitiatingInput(t *testing.T) { + for _, cause := range []string{"current-time", "current-date", "version"} { + t.Run(cause, func(t *testing.T) { + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.running = true + worker.ProtectCommand(100) + worker.Enqueue(speechRequest{Text: "Command result", Role: "system", Cause: cause}) + for _, timestamp := range []uint32{80, 99, 100} { + if worker.InterruptForInput(input.Event{Pressed: true, Timestamp: timestamp}) { + t.Fatalf("command interrupted by initiating input at %d", timestamp) + } + } + if len(worker.pending) != 1 || worker.generation != 1 { + t.Fatal("command speech was discarded") + } + if !worker.InterruptForInput(input.Event{Pressed: true, Timestamp: 101}) || len(worker.pending) != 0 { + t.Fatal("later input did not interrupt command speech") + } + }) + } +} + +func TestCommandInputProtectionOrdersTimestampsAcrossWrap(t *testing.T) { + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.ProtectCommand(^uint32(0) - 1) + worker.ProtectCommand(3) + worker.ProtectCommand(^uint32(0)) // An older queued notification cannot move the cutoff back. + for _, timestamp := range []uint32{^uint32(0), 2, 3} { + if worker.InterruptForInput(input.Event{Pressed: true, Timestamp: timestamp}) { + t.Fatalf("old input at %d interrupted", timestamp) + } + } + for _, timestamp := range []uint32{4, 0} { + if !worker.InterruptForInput(input.Event{Pressed: true, Timestamp: timestamp}) { + t.Fatalf("new or untimed input at %d ignored", timestamp) + } + } +} diff --git a/internal/app/configured_speaker.go b/internal/app/configured_speaker.go new file mode 100644 index 0000000..fbbc9a1 --- /dev/null +++ b/internal/app/configured_speaker.go @@ -0,0 +1,301 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "sync" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +type configuredVoice interface { + Speaker + SpeakCharacter(context.Context, string) error + SpeakEcho(context.Context, string) error + SpeakAndWait(context.Context, string, func()) error + SpeakVoice(context.Context, string, string) error + SpeakVoiceAndWait(context.Context, string, string, func()) error + SpeakEchoCharacter(context.Context, string) error +} + +// Keep backend replacement on the preferences worker. Input cancellation can +// still reach the active backend while its replacement connects. +type configuredSpeaker struct { + mu sync.RWMutex + update sync.Mutex + active configuredVoice + socket string + settings config.Settings + closed bool +} + +func newConfiguredSpeaker(socket string, settings config.Settings) *configuredSpeaker { + return &configuredSpeaker{socket: socket, settings: settings} +} +func (speaker *configuredSpeaker) Connect(ctx context.Context) error { + return speaker.UpdateConfiguration(ctx, speaker.settings) +} +func (speaker *configuredSpeaker) UpdateConfiguration(ctx context.Context, settings config.Settings) error { + if !speaker.update.TryLock() { + return errors.New("speech settings update already in progress") + } + defer speaker.update.Unlock() + if err := config.Validate(settings); err != nil { + return err + } + speaker.mu.RLock() + current, closed := speaker.active, speaker.closed + speaker.mu.RUnlock() + if closed { + return errors.New("speech is closed") + } + // Reuse the existing descriptor when only serial voice parameters change. + if hardware, ok := current.(*hardwareSpeaker); ok && settings.SpeechServerFactory == "hardwarefactory" && + hardware.device == settings.HardwareSpeechDevice && hardware.baud == settings.HardwareSpeechBaudRate && + hardware.synth == settings.SpeechOutputModule { + if err := hardware.Cancel(ctx); err != nil { + return err + } + hardware.mu.Lock() + if err := ctx.Err(); err != nil { + hardware.mu.Unlock() + return err + } + hardware.settings = settings + hardware.mu.Unlock() + return nil + } + if software, ok := current.(*echoSpeaker); ok && settings.SpeechServerFactory != "hardwarefactory" { + return software.UpdateConfiguration(ctx, settings) + } + var candidate configuredVoice + if settings.SpeechServerFactory == "hardwarefactory" { + candidate = &hardwareSpeaker{device: settings.HardwareSpeechDevice, baud: settings.HardwareSpeechBaudRate, + synth: settings.SpeechOutputModule, settings: settings} + } else { + candidate = newEchoSpeaker(speaker.socket, settings) + } + if err := candidate.Connect(ctx); err != nil { + return err + } + speaker.mu.Lock() + if speaker.closed || ctx.Err() != nil { + speaker.mu.Unlock() + candidate.Close(context.Background()) + return errors.New("speech configuration was canceled") + } + if current != nil { + if err := current.Cancel(ctx); err != nil { + speaker.mu.Unlock() + candidate.Close(context.Background()) + return err + } + } + speaker.active = candidate + speaker.settings = settings + speaker.mu.Unlock() + // The new backend is committed. A retired connection's cleanup error must + // not report this successful swap as a rejected preferences transaction. + if current != nil { + _ = current.Close(context.Background()) + } + return nil +} +func (speaker *configuredSpeaker) voice() (configuredVoice, error) { + speaker.mu.RLock() + defer speaker.mu.RUnlock() + if speaker.active == nil || speaker.closed { + return nil, errors.New("speech is not connected") + } + return speaker.active, nil +} +func (speaker *configuredSpeaker) Speak(ctx context.Context, text string) error { + voice, err := speaker.voice() + if err != nil { + return err + } + return voice.Speak(ctx, text) +} +func (speaker *configuredSpeaker) SpeakEcho(ctx context.Context, text string) error { + voice, err := speaker.voice() + if err != nil { + return err + } + return voice.SpeakEcho(ctx, text) +} +func (speaker *configuredSpeaker) SpeakVoice(ctx context.Context, text, kind string) error { + voice, err := speaker.voice() + if err != nil { + return err + } + return voice.SpeakVoice(ctx, text, kind) +} +func (speaker *configuredSpeaker) SpeakVoiceAndWait(ctx context.Context, text, kind string, began func()) error { + voice, err := speaker.voice() + if err != nil { + return err + } + return voice.SpeakVoiceAndWait(ctx, text, kind, began) +} +func (speaker *configuredSpeaker) SpeakEchoCharacter(ctx context.Context, text string) error { + voice, err := speaker.voice() + if err != nil { + return err + } + return voice.SpeakEchoCharacter(ctx, text) +} +func (speaker *configuredSpeaker) SpeakCharacter(ctx context.Context, text string) error { + voice, err := speaker.voice() + if err != nil { + return err + } + return voice.SpeakCharacter(ctx, text) +} +func (speaker *configuredSpeaker) SpeakAndWait(ctx context.Context, text string, began func()) error { + voice, err := speaker.voice() + if err != nil { + return err + } + return voice.SpeakAndWait(ctx, text, began) +} + +func (speaker *configuredSpeaker) speak_uninterruptible(ctx context.Context, text string) error { + voice, err := speaker.voice() + if err != nil { + return err + } + reader, ok := voice.(interface { + speak_uninterruptible(context.Context, string) error + }) + if !ok { + return errors.New("speech backend does not report utterance completion") + } + return reader.speak_uninterruptible(ctx, text) +} +func (speaker *configuredSpeaker) Cancel(ctx context.Context) error { + speaker.mu.RLock() + voice := speaker.active + speaker.mu.RUnlock() + if voice == nil { + return nil + } + return voice.Cancel(ctx) +} +func (speaker *configuredSpeaker) Close(ctx context.Context) error { + speaker.update.Lock() + defer speaker.update.Unlock() + speaker.mu.Lock() + voice := speaker.active + speaker.active, speaker.closed = nil, true + speaker.mu.Unlock() + if voice == nil { + return nil + } + return voice.Close(ctx) +} + +type hardwareSpeaker struct { + mu sync.RWMutex + device, synth string + baud int + client *speech.Hardware + settings config.Settings +} + +func (speaker *hardwareSpeaker) Connect(ctx context.Context) error { + if err := ctx.Err(); err != nil { + return err + } + client, err := speech.NewHardware(speaker.device, speaker.synth, speaker.baud) + if err != nil { + return err + } + speaker.client = client + return nil +} +func (speaker *hardwareSpeaker) Speak(ctx context.Context, text string) error { + return speaker.speak(ctx, text, false, "default") +} +func (speaker *hardwareSpeaker) SpeakEcho(ctx context.Context, text string) error { + return speaker.speak(ctx, text, true, "default") +} +func (speaker *hardwareSpeaker) SpeakCharacter(ctx context.Context, text string) error { + return speaker.speak_character(ctx, text, false) +} +func (speaker *hardwareSpeaker) SpeakEchoCharacter(ctx context.Context, text string) error { + return speaker.speak_character(ctx, text, true) +} +func (speaker *hardwareSpeaker) speak_character(ctx context.Context, text string, echo bool) error { + r, size := utf8.DecodeRuneInString(text) + kind := "default" + if size == len(text) && unicode.IsUpper(r) { + kind = "uppercase" + } + return speaker.speak(ctx, text, echo, kind) +} +func (speaker *hardwareSpeaker) SpeakVoice(ctx context.Context, text, kind string) error { + if kind == "echo" { + return speaker.SpeakEcho(ctx, text) + } + if kind == "uppercase-echo" { + return speaker.speak(ctx, text, true, "uppercase") + } + return speaker.speak(ctx, text, false, kind) +} +func (speaker *hardwareSpeaker) speak(ctx context.Context, text string, echo bool, kind string) error { + speaker.mu.RLock() + defer speaker.mu.RUnlock() + settings := speaker.settings + voice := config.EffectiveVoice(settings, "default") + if echo && settings.UseCustomEchoVoice { + if value := settings.EchoVoice.Rate; value != nil { + voice.Rate = value + } + if value := settings.EchoVoice.AveragePitch; value != nil { + voice.AveragePitch = value + } + if value := settings.EchoVoice.Gain; value != nil { + voice.Gain = value + } + } + settings.DefaultVoice = voice + voice = config.EffectiveVoice(settings, kind) + // Hardware has a single serial engine; echo uses that same synth with its + // custom numeric voice settings. Restore the default values each utterance. + if voice.Rate == nil { + value := 50.0 + voice.Rate = &value + } + if voice.AveragePitch == nil { + value := 5.0 + voice.AveragePitch = &value + } + if voice.Gain == nil { + value := 5.0 + voice.Gain = &value + } + return speaker.client.Speak(ctx, text, speech.HardwareVoice{Rate: voice.Rate, Pitch: voice.AveragePitch, Volume: voice.Gain}) +} +func (speaker *hardwareSpeaker) SpeakAndWait(ctx context.Context, text string, began func()) error { + return speaker.SpeakVoiceAndWait(ctx, text, "default", began) +} +func (speaker *hardwareSpeaker) SpeakVoiceAndWait(ctx context.Context, text, kind string, began func()) error { + // These protocols provide no utterance-completion event. Match Python's + // queued Say All behavior; progress denotes transmission, not audible end. + if err := speaker.SpeakVoice(ctx, text, kind); err != nil { + return err + } + if began != nil { + began() + } + return nil +} +func (speaker *hardwareSpeaker) Cancel(ctx context.Context) error { return speaker.client.Cancel(ctx) } +func (speaker *hardwareSpeaker) Close(ctx context.Context) error { return speaker.client.Close(ctx) } diff --git a/internal/app/configured_speaker_native_test.go b/internal/app/configured_speaker_native_test.go new file mode 100644 index 0000000..ecfca04 --- /dev/null +++ b/internal/app/configured_speaker_native_test.go @@ -0,0 +1,90 @@ +//go:build linux && cgo + +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "io" + "log/slog" + "os" + "strings" + "syscall" + "testing" + "time" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/preferences" +) + +func test_hardware_switch(t *testing.T, speaker *configuredSpeaker, software config.Settings) { + t.Helper() + fd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0600) + if err != nil { + t.Fatal(err) + } + master := os.NewFile(uintptr(fd), "hardware-speech-fixture") + defer master.Close() + var unlocked int32 + var number uint32 + if _, _, code := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&unlocked))); code != 0 { + t.Fatal(code) + } + if _, _, code := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&number))); code != 0 { + t.Fatal(code) + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + hardware := software + hardware.SpeechServerFactory = "hardwarefactory" + hardware.SpeechOutputModule = "litetalk" + hardware.HardwareSpeechDevice = fmt.Sprintf("/dev/pts/%d", number) + hardware.HardwareSpeechBaudRate = 9600 + rate, pitch, volume := 99.0, 9.0, 9.0 + hardware.DefaultVoice = config.Voice{Rate: &rate, AveragePitch: &pitch, Gain: &volume} + if err := speaker.UpdateConfiguration(ctx, hardware); err != nil { + t.Fatal(err) + } + check := func(speak func(context.Context, string) error, text, want string) { + t.Helper() + if err := speak(ctx, text); err != nil { + t.Fatal(err) + } + master.SetReadDeadline(time.Now().Add(time.Second)) + buffer := make([]byte, len(want)) + if _, err := io.ReadFull(master, buffer); err != nil || string(buffer) != want { + t.Fatalf("serial=%q want=%q error=%v", buffer, want, err) + } + } + check(speaker.Speak, "Default", "\x019S\x0199P\x019VDefault\r") + check(speaker.SpeakCharacter, "A", "\x019S\x0199P\x019VA\r") + check(speaker.SpeakCharacter, "a", "\x019S\x0199P\x019Va\r") + + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), hardware, speaker) + values := preferences.FromSettings(hardware) + rateLow := 0.0 + values.Rate = &rateLow + if response := worker.apply(ctx, preferences.Request{Values: values}); !response.Accepted { + t.Fatal(response.Message) + } + check(speaker.Speak, "Applied", "\x18\x010S\x0199P\x019VApplied\r") + values.HardwareSpeechDevice = "/dev/cthulhu-missing-serial-fixture" + if response := worker.apply(ctx, preferences.Request{Values: values}); response.Accepted { + t.Fatal("unavailable serial device accepted") + } + if worker.settings.HardwareSpeechDevice != hardware.HardwareSpeechDevice { + t.Fatal("failed Apply committed a missing device") + } + check(speaker.Speak, "Retained", "\x010S\x0199P\x019VRetained\r") + if err := speaker.UpdateConfiguration(ctx, software); err != nil { + t.Fatal(err) + } + if !strings.HasPrefix(worker.settings.HardwareSpeechDevice, "/dev/pts/") { + t.Fatal("unexpected fixture device") + } +} diff --git a/internal/app/control_events_test.go b/internal/app/control_events_test.go new file mode 100644 index 0000000..4cb016b --- /dev/null +++ b/internal/app/control_events_test.go @@ -0,0 +1,327 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestRepeatedControlFocusAfterStateChange(t *testing.T) { + for _, role := range []string{"radio button", "check box", "toggle button", "check menu item", "menu item"} { + for _, mode := range []string{"speech_only", "sound_and_speech", "sound_only"} { + t.Run(role+"/"+mode, func(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 16), requests: make(chan speechRequest, 16)} + frames := make(chan braille.Frame, 16) + state := &eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + state.presentationOptions.EnableSound = true + state.presentationOptions.PlaySoundForState = true + state.presentationOptions.RoleSoundPresentation = mode + logger := slog.New(slog.DiscardHandler) + handler := accessibilityEventHandler{state: state, logger: logger, brailleOutput: frameRecorder{frames: frames}} + presenter := eventPresenter{state: state, logger: logger, speech: queue} + present := func(event atspi.Event) bool { + if handler.acceptFocusedEvent(event, input.Activity{}) { + return false + } + presenter.speak(event) + return true + } + control := atspi.Snapshot{BusName: ":1.7", Path: "/option", Role: role, Name: "Some", RadioGroupName: "Punctuation Level"} + control.Checkable = role == "menu item" + focus := atspi.NewEvent(atspi.FocusedStateEvent, control) + focus.Detail1 = 1 + present(focus) + <-queue.requests + <-frames + control.Checked = true + checked := atspi.NewEvent("object:state-changed:checked", control) + checked.Detail1 = 1 + present(checked) + changed := <-queue.requests + if mode == "sound_only" { + if changed.Text != "" || len(changed.Sound) != 1 { + t.Fatalf("state sound = %+v", changed) + } + } else { + want := map[string]string{"radio button": "selected", "check box": "checked", "toggle button": "pressed", "check menu item": "checked", "menu item": "checked"}[role] + if changed.Text != want { + t.Fatalf("state speech = %q, want %q", changed.Text, want) + } + } + checkedFrame := <-frames + focus.Source = control + if present(focus) || len(queue.requests) != 0 { + t.Fatal("repeated focus after state change restarted the control announcement") + } + if frame := <-frames; frame.Text != checkedFrame.Text || !state.current.Checked || !state.brailleSnapshot.Checked { + t.Fatalf("repeated focus lost the checked state: %+v", frame) + } + control.Checked = false + present(atspi.NewEvent("object:state-changed:checked", control)) + changed = <-queue.requests + if mode == "sound_only" { + if changed.Text != "" || len(changed.Sound) != 1 { + t.Fatalf("unchecked state sound = %+v", changed) + } + } else { + want := map[string]string{"radio button": "not selected", "check box": "not checked", "toggle button": "not pressed", "check menu item": "not checked", "menu item": "not checked"}[role] + if changed.Text != want { + t.Fatalf("unchecked state speech = %q, want %q", changed.Text, want) + } + } + <-frames + focus.Source = control + // New semantics at the same identity still need an announcement. + focus.Source.Name = "Most" + if !present(focus) || len(queue.requests) != 1 { + t.Fatal("changed control name was suppressed") + } + <-queue.requests + other := atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: ":1.7", Path: "/apply", Role: "button", Name: "Apply"}) + present(other) + <-queue.requests + if !present(focus) || len(queue.requests) != 1 { + t.Fatal("returning to the control was suppressed") + } + }) + } + } +} + +func TestRepeatedTerminalFocusRetainsPendingPresentation(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 10*time.Millisecond, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + terminal := atspi.Snapshot{BusName: ":1.7", Path: "/terminal", ApplicationName: "Fixture", Role: "terminal", Text: "Ready"} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, terminal) + focused := atspi.NewEvent(atspi.FocusedStateEvent, terminal) + focused.Detail1 = 1 + adapter.events <- focused + select { + case got := <-queue.spoken: + if got != "terminal, Ready" { + t.Fatalf("terminal focus speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("repeated focus discarded pending terminal speech") + } +} + +func TestSettingsTreeSelectionSpeaksOnceAndIgnoresUnfocusedEdits(t *testing.T) { + for _, toolkit := range []string{"Gecko", "Chromium", "gtk"} { + t.Run(toolkit, func(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 32)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 32)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + item := atspi.Snapshot{BusName: ":1.7", Path: "/server", Name: "Server Settings", Role: "tree item", ToolkitName: toolkit, Selected: true} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, item) + selected := atspi.NewEvent(atspi.SelectedStateEvent, item) + selected.Detail1 = 1 + adapter.events <- selected + selection := atspi.NewEvent(atspi.SelectionChangedEvent, item) + selection.OriginPath = "/tree" + adapter.events <- selection + port := atspi.Snapshot{BusName: ":1.7", Path: "/port", Name: "Port", Role: "spin button", Editable: true, Text: "993"} + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, port, "993") + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, port, "993") + // An active-page live region must still announce its update. + live := atspi.Snapshot{BusName: ":1.7", Path: "/live", Role: "entry", Editable: true, LiveRegion: true} + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, live, "Connection status updated") + // Actual focus and subsequent edits to the port must still speak. + adapter.events <- atspi.NewEvent(atspi.FocusEvent, port) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, port, "4") + // Selection changes within the focused tree must remain usable. + adapter.events <- atspi.NewEvent(atspi.FocusEvent, item) + adapter.events <- selection + next := item + next.Path, next.Name = "/folders", "Copies & Folders" + selection.Source = next + adapter.events <- selection + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: ":1.7", Path: "/end", Role: "button", Name: "End"}) + for _, want := range []string{ + "Server Settings, tree item, selected", "Connection status updated", "Port, spin button, 993", "4", + "Server Settings, tree item, selected", "Copies & Folders, tree item, selected", "End, button", + } { + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } + }) + } +} + +func TestControlFocusCaretDoesNotInterruptButArrowCaretSpeaks(t *testing.T) { + for _, role := range []string{"spin button", "button", "link"} { + t.Run(role, func(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + tracker := &input.IntentTracker{} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, tracker, nil, nil) + }() + defer func() { cancel(); <-done }() + control := atspi.Snapshot{BusName: ":1.7", Path: "/control", Name: "Port", Role: role, Editable: role == "spin button", Text: "993"} + tracker.Observe(input.NewKeyEvent(0, true, "Tab")) + adapter.events <- atspi.NewEvent(atspi.FocusEvent, control) + select { + case <-queue.spoken: + case <-time.After(time.Second): + t.Fatal("missing control focus speech") + } + adapter.events <- atspi.NewEvent(atspi.CaretEvent, control) + select { + case got := <-queue.spoken: + t.Fatalf("automatic caret interrupted control speech with %q", got) + case <-time.After(50 * time.Millisecond): + } + tracker.Observe(input.NewKeyEvent(0, true, "Right")) + control.CaretCharacter = "9" + adapter.events <- atspi.NewEvent(atspi.CaretEvent, control) + select { + case got := <-queue.spoken: + if got != "9" { + t.Fatalf("arrow caret speech = %q, want 9", got) + } + case <-time.After(time.Second): + t.Fatal("missing arrow caret speech") + } + }) + } +} + +func TestEmbeddedObjectCaretDoesNotReplaceControlFocus(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + tracker := &input.IntentTracker{} + browser := newBrowserModeController(tracker, &modeKeys{}, nil) + browser.ready, browser.mode = true, review.BrowseMode + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, browser, nil, nil) + }() + defer func() { cancel(); <-done }() + tracker.Observe(input.NewKeyEvent(0, true, "Tab")) + checkbox := atspi.Snapshot{BusName: ":1.7", Path: "/checkbox", Role: "check box", Name: "Use HTML", StatesKnown: true, Sensitive: true, Focusable: true} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, checkbox) + select { + case got := <-queue.spoken: + if got != "Use HTML, check box, not checked" { + t.Fatalf("checkbox focus speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("missing checkbox focus speech") + } + container := atspi.Snapshot{BusName: ":1.7", Path: "/panel", Role: "panel", Text: "\ufffc"} + adapter.events <- atspi.NewEvent(atspi.CaretEvent, container) + select { + case got := <-queue.spoken: + t.Fatalf("embedded-object caret interrupted checkbox with %q", got) + case <-time.After(50 * time.Millisecond): + } + checkbox.Checked = true + adapter.events <- atspi.NewEvent("object:state-changed:checked", checkbox) + select { + case got := <-queue.spoken: + if got != "checked" { + t.Fatalf("checkbox toggle speech = %q, want checked", got) + } + case <-time.After(time.Second): + t.Fatal("checkbox focus was lost after container caret") + } + cancel() + <-done + if browser.focus != checkbox.ID() { + t.Fatalf("container caret replaced browser focus: %v", browser.focus) + } +} + +func TestFocusedTreeSelectionStateChangesRemainAudible(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + item := atspi.Snapshot{BusName: ":1.7", Path: "/item", Role: "list item", Name: "Important", Selected: true} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, item) + item.Selected = false + adapter.events <- atspi.NewEvent(atspi.SelectedStateEvent, item) + item.Selected = true + selected := atspi.NewEvent(atspi.SelectedStateEvent, item) + selected.Detail1 = 1 + adapter.events <- selected + for _, want := range []string{"Important, list item, selected", "not selected", "selected"} { + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("selection state speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing selection state %q", want) + } + } +} + +// Drive focus and checked-state events through the real event loop and speech +// worker. The backend call stays in flight while the selection arrives, so any +// automatic CANCEL (including one after SPEAK returns) fails the expected order. +func TestSpeechWorkerRadioSelectionDoesNotCancelLabel(t *testing.T) { + logger := slog.New(slog.DiscardHandler) + speaker := &controlledSpeaker{calls: make(chan speechCall, 8)} + worker := newSpeechWorker(logger, speaker) + if err := worker.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + option := atspi.Snapshot{BusName: ":1.7", Path: "/option", Name: "Laptop", Role: "radio button"} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, option) + option.Checked = true + selected := atspi.NewEvent("object:state-changed:checked", option) + selected.Detail1 = 1 + adapter.events <- selected + close(adapter.events) + if err := processEvents(t.Context(), logger, worker, adapter, 0); err != nil { + t.Fatal(err) + } + for _, want := range []string{"Laptop", "radio button", "not selected", "selected"} { + close(expectSpeechCall(t, speaker, want).done) + } +} diff --git a/internal/app/current_line.go b/internal/app/current_line.go new file mode 100644 index 0000000..335e5af --- /dev/null +++ b/internal/app/current_line.go @@ -0,0 +1,51 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func (handler *eventReviewHandler) current_line(command input.Command) { + if handler.focusGate.Locked() || handler.focusGate.Suspended() { + return + } + handler.syncForeground() + if handler.objectReview == nil || !handler.state.current.ID().Valid() { + return + } + handler.state.pending.terminalFocus.clear() + handler.state.pending.terminalDeletion.clear() + style := review.FlatSpeak + if command == input.SpellCurrentLine { + style = review.FlatSpell + } else if command == input.PhoneticCurrentLine { + style = review.FlatPhonetic + } + browse := handler.browser != nil && handler.browser.ready && handler.browser.mode == review.BrowseMode + if err := handler.objectReview.ReadCurrentLine(browse, style); err != nil { + handler.logger.Warn("queue current line", "error", err) + } +} + +func (handler *eventReviewHandler) present_current_line(result review.Result) { + if !handler.objectReview.CurrentDocumentResult(result) || result.DocumentFocus != handler.objectReview.Focus() || handler.focusGate.Suspended() { + return + } + if result.CurrentLineBrowse && (handler.browser == nil || !handler.browser.acceptsDocumentResult(review.Result{ + DocumentFocus: result.DocumentFocus, DocumentPosition: result.DocumentPosition, DocumentCaretCommand: review.CaretReadLine, Err: result.Err, + })) { + return + } + request := speechRequest{Text: "Could not read current line.", Role: "system", Cause: "current-line"} + if result.Err == nil { + text := result.DocumentCaretText + request.Text = presentation.FlatReviewText(text, false) + request.Role = result.DocumentPosition.Snapshot.Role + set_review_spelling(&request, text, result.FlatSpeech) + } + handler.speech.Enqueue(request) +} diff --git a/internal/app/current_line_test.go b/internal/app/current_line_test.go new file mode 100644 index 0000000..816b1fa --- /dev/null +++ b/internal/app/current_line_test.go @@ -0,0 +1,100 @@ +package app + +import ( + "context" + "errors" + "log/slog" + "reflect" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" +) + +type currentLineAdapter struct{ *fakeAdapter } + +func (*currentLineAdapter) ReadFocusedLine(_ context.Context, focus atspi.ObjectID) (atspi.DocumentContent, error) { + return atspi.DocumentContent{Text: "Complete caret line", Snapshot: atspi.Snapshot{BusName: focus.BusName, Path: focus.Path, Role: "entry"}}, nil +} + +func TestCurrentLineEventLoopPreservesFocusedItem(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + adapter := ¤tLineAdapter{&fakeAdapter{events: make(chan atspi.Event)}} + worker, _ := review.NewWorker(adapter, time.Second) + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + requests := make(chan input.Command) + done := make(chan error, 1) + go func() { + done <- processEventsWithSettings(ctx, slog.New(slog.DiscardHandler), queue, adapter, requests, worker, 0, nil) + }() + t.Cleanup(func() { + cancel() + if err := worker.Stop(context.Background()); err != nil { + t.Error(err) + } + <-done + }) + waitSpeech := func(want string) { + t.Helper() + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("speech %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing speech %q", want) + } + } + focus := atspi.NewSnapshot("/entry", "Original item", "entry", "", "") + focus.BusName = ":1.42" + adapter.events <- atspi.NewEvent(atspi.FocusEvent, focus) + waitSpeech("Original item, entry") + requests <- input.PresentCurrentLine + waitSpeech("Complete caret line") + requests <- input.WhereAmI + waitSpeech("Original item, entry") +} + +func TestCurrentLinePresentationAndStaleResults(t *testing.T) { + focus := atspi.ObjectID{BusName: ":1.42", Path: "/entry"} + worker, _ := review.NewWorker(&fakeAdapter{}, time.Second) + worker.SyncFocus(focus) + queue := &fakeSpeechQueue{requests: make(chan speechRequest, 8), spoken: make(chan string, 8)} + handler := eventReviewHandler{objectReview: worker, speech: queue, focusGate: &focusGate{}} + for _, probe := range []struct { + text string + style review.FlatSpeech + err error + want string + spelling []string + }{ + {"A book", review.FlatSpeak, nil, "A book", nil}, + {"A", review.FlatSpell, nil, "A", []string{"A"}}, + {"A", review.FlatPhonetic, nil, "A", []string{"alpha"}}, + {"\n", review.FlatSpeak, nil, "blank", nil}, + {"", review.FlatSpeak, nil, "blank", nil}, + {"", review.FlatSpeak, errors.New("unavailable"), "Could not read current line.", nil}, + } { + result := review.Result{CurrentLine: true, DocumentFocus: focus, DocumentCaretText: probe.text, FlatSpeech: probe.style, Err: probe.err} + handler.present_current_line(result) + got := <-queue.requests + if got.Text != probe.want || !reflect.DeepEqual(got.Spelling, probe.spelling) { + t.Fatalf("current line: %+v, want %q %v", got, probe.want, probe.spelling) + } + } + worker.ResetDocument(focus) + handler.present_current_line(review.Result{CurrentLine: true, DocumentFocus: focus}) + if len(queue.requests) != 0 { + t.Fatal("stale report was spoken") + } + worker.SyncFocus(atspi.ObjectID{BusName: ":1.42", Path: "/other"}) + handler.present_current_line(review.Result{CurrentLine: true, DocumentFocus: focus, DocumentEpoch: worker.DocumentEpoch()}) + if len(queue.requests) != 0 { + t.Fatal("report from previous focus was spoken") + } +} diff --git a/internal/app/date_time.go b/internal/app/date_time.go new file mode 100644 index 0000000..ff9ebaa --- /dev/null +++ b/internal/app/date_time.go @@ -0,0 +1,25 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/datetime" + "git.stormux.org/storm/cthulhu/internal/input" +) + +// The command worker supplies local wall time and one immutable settings snapshot. +func presentDateTime(speech speechEnqueuer, settings config.Settings, command input.Command, now time.Time) { + text, cause := "", "current-time" + if command == input.PresentDate { + cause = "current-date" + text, _ = datetime.FormatDate(settings.DateFormat, now) + } else { + text, _ = datetime.FormatTime(settings.TimeFormat, now) + } + speech.Enqueue(speechRequest{Text: text, Role: "system", Cause: cause}) +} diff --git a/internal/app/date_time_test.go b/internal/app/date_time_test.go new file mode 100644 index 0000000..2a40402 --- /dev/null +++ b/internal/app/date_time_test.go @@ -0,0 +1,155 @@ +package app + +import ( + "context" + "log/slog" + "os" + "os/exec" + "path/filepath" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/datetime" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" +) + +func TestDateTimeFormats(t *testing.T) { + // datetime initializes libc's locale before tests run. Use a child process + // so these fixed English expectations do not depend on the build locale. + if os.Getenv("CTHULHU_DATE_TIME_TEST_CHILD") != "1" { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + command := exec.CommandContext(ctx, os.Args[0], "-test.run=^TestDateTimeFormats$", "-test.count=1") + command.Env = append(os.Environ(), "LC_ALL=C", "CTHULHU_DATE_TIME_TEST_CHILD=1") + if output, err := command.CombinedOutput(); err != nil { + t.Fatalf("C-locale date/time test: %v\n%s", err, output) + } + return + } + now := time.Date(2026, 9, 17, 19, 5, 0, 0, time.UTC) + for _, tc := range []struct { + command input.Command + format, want string + }{ + {input.PresentTime, "locale", "19:05:00"}, + {input.PresentTime, "12-hour", "07:05 PM"}, + {input.PresentTime, "12-hour-seconds", "07:05:00 PM"}, + {input.PresentTime, "24-hour-seconds", "19:05:00"}, + {input.PresentTime, "24-hour-seconds-words", "19 hours, 05 minutes and 00 seconds"}, + {input.PresentTime, "24-hour", "19:05"}, + {input.PresentTime, "24-hour-words", "19 hours and 05 minutes"}, + {input.PresentDate, "locale", "09/17/26"}, + {input.PresentDate, "numbers-dm", "17/09"}, + {input.PresentDate, "numbers-md", "09/17"}, + {input.PresentDate, "numbers-dmy", "17/09/2026"}, + {input.PresentDate, "numbers-mdy", "09/17/2026"}, + {input.PresentDate, "numbers-ymd", "2026/09/17"}, + {input.PresentDate, "full-dm", "Thursday, 17 September"}, + {input.PresentDate, "full-md", "Thursday, September 17"}, + {input.PresentDate, "full-dmy", "Thursday, 17 September, 2026"}, + {input.PresentDate, "full-mdy", "Thursday, September 17, 2026"}, + {input.PresentDate, "full-ymd", "2026. September 17, Thursday"}, + {input.PresentDate, "abbreviated-dm", "Thu, 17 Sep"}, + {input.PresentDate, "abbreviated-md", "Thu, Sep 17"}, + {input.PresentDate, "abbreviated-dmy", "Thu, 17 Sep, 2026"}, + {input.PresentDate, "abbreviated-mdy", "Thu, Sep 17, 2026"}, + {input.PresentDate, "abbreviated-ymd", "2026. Sep 17, Thu"}, + } { + settings := config.DefaultSettings() + if tc.command == input.PresentTime { + settings.TimeFormat = tc.format + } else { + settings.DateFormat = tc.format + } + queue := &fakeSpeechQueue{spoken: make(chan string, 1), interrupt: make(chan struct{}, 1)} + presentDateTime(queue, settings, tc.command, now) + if got := <-queue.spoken; got != tc.want { + t.Errorf("%s: %q want %q", tc.format, got, tc.want) + } + if len(queue.interrupt) != 0 { + t.Fatal("delayed command result interrupted speech again") + } + } +} + +func TestDateTimeOptionCounts(t *testing.T) { + now := time.Date(2026, 9, 17, 19, 5, 0, 0, time.UTC) + timeOptions := datetime.TimeOptions(now) + dateOptions := datetime.DateOptions(now) + wantTime := []string{ + "locale", "12-hour", "12-hour-seconds", "24-hour-seconds", + "24-hour-seconds-words", "24-hour", "24-hour-words", + } + wantDate := []string{ + "locale", "numbers-dm", "numbers-md", "numbers-dmy", "numbers-mdy", + "numbers-ymd", "full-dm", "full-md", "full-dmy", "full-mdy", + "full-ymd", "abbreviated-dm", "abbreviated-md", "abbreviated-dmy", + "abbreviated-mdy", "abbreviated-ymd", + } + if len(timeOptions) != len(wantTime) { + t.Fatalf("time options: got %d, want %d", len(timeOptions), len(wantTime)) + } + if len(dateOptions) != len(wantDate) { + t.Fatalf("date options: got %d, want %d", len(dateOptions), len(wantDate)) + } + for _, test := range []struct { + name string + options []datetime.Option + expected []string + }{ + {"time", timeOptions, wantTime}, + {"date", dateOptions, wantDate}, + } { + for index, option := range test.options { + if option.Value != test.expected[index] { + t.Fatalf("%s option %d = %q, want %q", test.name, index, + option.Value, test.expected[index]) + } + } + } + for _, option := range append(timeOptions, dateOptions...) { + if option.Value == "" || option.Label == "" { + t.Fatalf("empty option: %+v", option) + } + } +} + +func TestDateTimePreferencesLiveAndSaved(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + live := &liveSettings{} + live.Store(settings) + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + worker.live = live + values := preferences.FromSettings(settings) + values.TimeFormat, values.DateFormat = "24-hour-words", "abbreviated-mdy" + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true, Close: true}) + if !response.Accepted || !response.Close { + t.Fatalf("apply: %+v", response) + } + loaded, err := config.Load(settings.Path) + if err != nil || loaded.TimeFormat != "24-hour-words" || loaded.DateFormat != "abbreviated-mdy" { + t.Fatalf("saved formats: %+v %v", loaded, err) + } + queue := &fakeSpeechQueue{spoken: make(chan string, 1)} + presentDateTime(queue, live.Load(), input.PresentTime, time.Date(2026, 9, 17, 0, 1, 0, 0, time.Local)) + if got := <-queue.spoken; got != "00 hours and 01 minutes" { + t.Fatalf("live time: %s", got) + } + for _, field := range []string{"time", "date"} { + bad := values + if field == "time" { + bad.TimeFormat = "invalid" + } else { + bad.DateFormat = "invalid" + } + if worker.apply(context.Background(), preferences.Request{Values: bad, Save: true}).Accepted { + t.Fatal("invalid format accepted") + } + } + if live.Load().TimeFormat != "24-hour-words" || live.Load().DateFormat != "abbreviated-mdy" { + t.Fatal("invalid draft changed live settings") + } +} diff --git a/internal/app/document_diagnostics_test.go b/internal/app/document_diagnostics_test.go new file mode 100644 index 0000000..823bb85 --- /dev/null +++ b/internal/app/document_diagnostics_test.go @@ -0,0 +1,54 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bytes" + "encoding/json" + "errors" + "log/slog" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestDocumentDiagnosticsSeparateFailureFromWrapping(t *testing.T) { + for _, caret := range []bool{true, false} { + var output bytes.Buffer + logger := slog.New(slog.NewJSONHandler(&output, &slog.HandlerOptions{Level: slog.LevelDebug})) + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 4)} + result := review.Result{DocumentEpoch: 7, DocumentFocus: atspi.NewObjectID(":1.42", "/doc"), + DocumentWrapped: !caret, Moved: !caret, DocumentTarget: review.DocumentHeading, + DocumentDiagnostics: review.DocumentDiagnostics{CaptureAttempts: 2, + Attempts: []review.DocumentAttempt{{Recovery: "saved-object-missing", Stage: "move"}}}} + if caret { + result.Err = errors.New("accessible children require recapture") + presentDocumentCaretResult(logger, queue, result, presentation.DefaultOptions()) + } else { + result.DocumentPosition.Snapshot = atspi.NewSnapshot("/heading", "Example", "heading", "", "") + presentDocumentResult(logger, queue, result, presentation.DefaultOptions()) + } + var record struct { + Epoch uint64 `json:"document_epoch"` + Focus atspi.ObjectID `json:"focus"` + Error string `json:"error"` + Wrapped bool `json:"wrapped"` + Navigation review.DocumentDiagnostics `json:"navigation"` + } + if err := json.NewDecoder(&output).Decode(&record); err != nil { + t.Fatal(err) + } + if record.Epoch != 7 || record.Focus != result.DocumentFocus || record.Wrapped != !caret || + record.Navigation.CaptureAttempts != 2 || len(record.Navigation.Attempts) != 1 || + record.Navigation.Attempts[0].Recovery != "saved-object-missing" { + t.Fatalf("missing navigation diagnostics: %+v", record) + } + if caret && record.Error != result.Err.Error() { + t.Fatalf("failed command lost its error: %+v", record) + } + } +} diff --git a/internal/app/document_line_test.go b/internal/app/document_line_test.go new file mode 100644 index 0000000..b9c5de5 --- /dev/null +++ b/internal/app/document_line_test.go @@ -0,0 +1,313 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +type documentLineCaptureCall struct { + focus atspi.ObjectID + result chan *atspi.AccessibleTree +} + +type documentLineCapturer struct { + calls chan documentLineCaptureCall +} + +func (capturer *documentLineCapturer) capture(ctx context.Context, focus atspi.ObjectID) (*atspi.AccessibleTree, error) { + call := documentLineCaptureCall{focus: focus, result: make(chan *atspi.AccessibleTree, 1)} + capturer.calls <- call + select { + case tree := <-call.result: + return tree, nil + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +func (capturer *documentLineCapturer) CaptureDesktop(ctx context.Context) (*atspi.AccessibleTree, error) { + return capturer.capture(ctx, atspi.ObjectID{}) +} + +func (capturer *documentLineCapturer) CaptureReviewWindow(ctx context.Context, focus atspi.ObjectID) (*atspi.AccessibleTree, error) { + return capturer.capture(ctx, focus) +} + +func (capturer *documentLineCapturer) CaptureDocument(ctx context.Context, focus atspi.ObjectID) (*atspi.AccessibleTree, error) { + return capturer.capture(ctx, focus) +} + +func (capturer *documentLineCapturer) CaptureDocumentText(ctx context.Context, focus atspi.ObjectID) (*atspi.AccessibleTree, error) { + return capturer.capture(ctx, focus) +} + +type documentLineKeys struct{} + +func (keys *documentLineKeys) SetBrowseNavigation(bool) {} + +func documentLineTree(t *testing.T, staticText string) *atspi.AccessibleTree { + t.Helper() + baseNode := func(path, role string, children ...atspi.ObjectID) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, path, role, "", "") + snapshot.BusName = ":1.42" + return atspi.TreeNode{Snapshot: snapshot, Children: children} + } + lineNode := func(path, role, text string, bounds atspi.Rectangle, caret bool) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, path, role, "", text) + snapshot.BusName = ":1.42" + geometry := atspi.Geometry{Bounds: bounds, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + visible := atspi.VisibleText{Known: true, Ranges: []atspi.TextRange{{ + Start: 0, End: utf8.RuneCountInString(text), Text: text, Bounds: bounds, + }}} + if caret { + visible.CaretKnown, visible.CaretOffset = true, 1 + } + return atspi.TreeNode{Snapshot: snapshot, Geometry: geometry, Text: visible} + } + tree, err := atspi.NewAccessibleTree(atspi.NewObjectID(":1.42", "/root"), []atspi.TreeNode{ + baseNode("/root", "frame", atspi.NewObjectID(":1.42", "/document")), + baseNode("/document", "document web", atspi.NewObjectID(":1.42", "/static"), atspi.NewObjectID(":1.42", "/link")), + lineNode("/static", "static", staticText, atspi.Rectangle{X: 0, Y: 100, Width: 60, Height: 20}, false), + lineNode("/link", "link", "the link", atspi.Rectangle{X: 100, Y: 100, Width: 80, Height: 20}, false), + }) + if err != nil { + t.Fatal(err) + } + return tree +} + +func TestProcessEventsSpeaksNewestDocumentCaretLine(t *testing.T) { + capturer := &documentLineCapturer{calls: make(chan documentLineCaptureCall, 2)} + worker, err := review.NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopContext, stopCancel := context.WithTimeout(context.Background(), time.Second) + defer stopCancel() + if err := worker.Stop(stopContext); err != nil { + t.Fatal(err) + } + }() + + tracker := &input.IntentTracker{} + tracker.Observe(input.NewKeyEvent(0, true, "Down")) + browser := newBrowserModeController(tracker, &documentLineKeys{}, nil) + browser.mode = review.FocusMode + browser.ready = true + adapter := &fakeAdapter{events: make(chan atspi.Event)} + speech := &fakeSpeechQueue{spoken: make(chan string, 2)} + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), speech, adapter, nil, worker, 0, nil, browser, nil, nil) + }() + + static := atspi.NewSnapshot("/static", "/static", "static", "", "First ") + static.BusName = ":1.42" + staticEvent := atspi.NewEvent(atspi.CaretEvent, static) + staticEvent.Detail1 = 1 + adapter.events <- staticEvent + firstCapture := <-capturer.calls + + link := atspi.NewSnapshot("/link", "/link", "link", "", "the link") + link.BusName = ":1.42" + linkEvent := atspi.NewEvent(atspi.CaretEvent, link) + linkEvent.Detail1 = 1 + adapter.events <- linkEvent + // Native capture observes the current document when it completes, not the + // event which originally caused the capture. + firstCapture.result <- documentLineTree(t, "Second ") + + select { + case got := <-speech.spoken: + if got != "Second, the link, link" { + t.Fatalf("document line speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for document line speech") + } + cancel() + select { + case <-done: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } + select { + case got := <-speech.spoken: + t.Fatalf("unexpected stale document line speech = %q", got) + default: + } +} + +func TestProcessEventsUsesCapturedLineInBrowseModeWithoutReviewWorker(t *testing.T) { + tracker := &input.IntentTracker{} + tracker.Observe(input.NewKeyEvent(0, true, "Down")) + browser := newBrowserModeController(tracker, &documentLineKeys{}, nil) + browser.mode = review.BrowseMode + browser.ready = true + adapter := &fakeAdapter{events: make(chan atspi.Event)} + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + _ = processEventsWithInput(ctx, slog.New(slog.DiscardHandler), speech, adapter, nil, nil, 0, nil, browser, nil, nil) + }() + + retainedFocus := atspi.NewSnapshot("/old-heading", "Retained heading", "heading", "", "") + retainedFocus.BusName = ":1.42" + retainedFocus.Focusable = true + adapter.events <- atspi.NewEvent(atspi.FocusEvent, retainedFocus) + + snapshot := atspi.NewSnapshot("/paragraph", "", "paragraph", "", "Current browser line") + snapshot.BusName = ":1.42" + event := atspi.NewEvent(atspi.CaretEvent, snapshot) + event.Detail1 = 4 + adapter.events <- event + select { + case got := <-speech.spoken: + if got != "Current browser line" { + t.Fatalf("browse line speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for browse line speech") + } + if !browser.ready || browser.mode != review.BrowseMode { + t.Fatalf("retained DOM focus changed browse state: ready=%v mode=%v", browser.ready, browser.mode) + } + cancel() + select { + case <-done: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestBlankBrowseCaretDoesNotCaptureWholeDocument(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + capturer := &documentLineCapturer{calls: make(chan documentLineCaptureCall, 1)} + worker, err := review.NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + tracker := &input.IntentTracker{} + tracker.Observe(input.NewKeyEvent(0, true, "Down")) + browser := newBrowserModeController(tracker, &documentLineKeys{}, nil) + browser.mode, browser.ready = review.BrowseMode, true + adapter := &fakeAdapter{events: make(chan atspi.Event)} + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + done := make(chan error, 1) + go func() { + done <- processEventsWithInput(ctx, slog.New(slog.DiscardHandler), speech, adapter, nil, worker, 0, nil, browser, nil, nil) + }() + blank := atspi.NewSnapshot("/link", "", "link", "", "") + blank.BusName = ":1.42" + adapter.events <- atspi.NewEvent(atspi.CaretEvent, blank) + select { + case <-capturer.calls: + t.Fatal("blank browse caret started full document text capture") + case <-time.After(50 * time.Millisecond): + } + cancel() + select { + case err := <-done: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestBrowserCaretUpdatesStructuralPositionAndSounds(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + capturer := &documentLineCapturer{calls: make(chan documentLineCaptureCall, 2)} + worker, err := review.NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + tracker := &input.IntentTracker{} + tracker.Observe(input.NewKeyEvent(0, true, "Down")) + browser := newBrowserModeController(tracker, &documentLineKeys{}, nil) + browser.ready, browser.mode = true, review.BrowseMode + adapter := &fakeAdapter{events: make(chan atspi.Event)} + queue := &modeSoundQueue{speech: &fakeSpeechQueue{spoken: make(chan string, 4)}, sounds: make(chan sound.Cue, 4)} + options := presentation.DefaultOptions() + options.EnableSound, options.PlaySoundForRole = true, true + options.RoleSoundPresentation = "sound_only" + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, worker, 0, nil, browser, nil, nil, options) + }() + defer func() { cancel(); <-done }() + snapshot := atspi.Snapshot{BusName: ":1.42", Path: "/link", Role: "link", Text: "the link", Visited: true} + adapter.events <- atspi.NewEvent(atspi.CaretEvent, snapshot) + select { + case text := <-queue.speech.spoken: + if text != "the link" { + t.Fatalf("caret speech = %q", text) + } + case <-time.After(time.Second): + t.Fatal("missing caret speech") + } + select { + case cue := <-queue.sounds: + if cue.Name != "link_visited" { + t.Fatalf("caret cue = %#v", cue) + } + case <-time.After(time.Second): + t.Fatal("missing caret sound") + } + worker.MoveDocument(review.DocumentHeading, 0, false) + select { + case call := <-capturer.calls: + if call.focus != snapshot.ID() { + t.Fatalf("structural navigation anchored at %v, want caret %v", call.focus, snapshot.ID()) + } + case <-time.After(time.Second): + t.Fatal("structural navigation did not follow the caret") + } +} diff --git a/internal/app/document_native_test.go b/internal/app/document_native_test.go new file mode 100644 index 0000000..73bf1fd --- /dev/null +++ b/internal/app/document_native_test.go @@ -0,0 +1,1050 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "os" + "os/exec" + "path/filepath" + "strings" + "sync/atomic" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeBrowserDocumentCommands(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + var focus atspi.Snapshot + for attempt := 0; attempt < 25 && focus.Name != "Browser foundation"; attempt++ { + keys("Tab") + timer := time.NewTimer(250 * time.Millisecond) + drain: + for { + select { + case event := <-adapter.Events(): + if isFocusEvent(event.Type) { + focus = event.Source + } + if focus.Name == "Browser foundation" { + break drain + } + case <-timer.C: + break drain + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + timer.Stop() + } + if focus.Name != "Browser foundation" { + t.Fatalf("fixture heading focus missing, last %q", focus.Name) + } + // Feed real owned native states into the policy without installing web-key + // grabs. These simple roles do not need the remaining derived traits. + tree, err := adapter.CaptureDocument(ctx, focus.ID()) + if err != nil { + t.Fatal(err) + } + ref, err := tree.Reference(focus.ID()) + if err != nil { + t.Fatal(err) + } + document, err := tree.Document(ctx, ref) + if err != nil { + t.Fatal(err) + } + type modeTarget struct{ name, role string } + modeCases := map[modeTarget]review.DocumentMode{ + {"Reading section", "heading"}: review.BrowseMode, + {"Ordinary unfocusable heading", "heading"}: review.BrowseMode, + {"Display name", "entry"}: review.FocusMode, + {"Details", "button"}: review.FocusMode, + {"Popup actions", "button"}: review.FocusMode, + {"Popup toggle", "toggle button"}: review.FocusMode, + {"Ordinary action", "button"}: review.BrowseMode, + } + for _, node := range document.Nodes { + target := modeTarget{node.Snapshot.Name, node.Snapshot.Role} + want, ok := modeCases[target] + if !ok { + continue + } + owner, err := tree.DocumentContext(node.Reference) + if err != nil { + t.Fatal(err) + } + var mode review.DocumentModeState + if got := mode.Update(review.ModeInput{Context: owner}, review.DefaultModeSettings()); got != want { + t.Fatalf("native mode for %s (%s): got %v want %v", node.Snapshot.Name, node.Snapshot.Role, got, want) + } + delete(modeCases, target) + } + if len(modeCases) != 0 { + t.Fatalf("missing native mode fixtures: %v", modeCases) + } + worker, err := review.NewWorker(adapter, 2*time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(focus.ID()) + commands := xorg.NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := commands.Start(ctx); err != nil { + t.Fatal(err) + } + defer commands.Stop(context.Background()) + // This fixture drives the Xorg listener directly. Install the same browse + // bindings the application requests for an owned web document. + commands.SetBrowseNavigation(true) + browseDeadline := time.NewTimer(time.Second) + defer browseDeadline.Stop() + browseApplied := time.NewTicker(10 * time.Millisecond) + defer browseApplied.Stop() + for !commands.BrowseNavigationEnabled() { + select { + case <-browseDeadline.C: + t.Fatal("browse bindings were not applied") + case <-browseApplied.C: + } + } + queue := &fakeSpeechQueue{spoken: make(chan string, 1)} + reuseDocument := false + checkCommand := func(chord, want string) { + t.Helper() + keys(chord) + var command input.Command + select { + case event := <-commands.Commands(): + command = event.Command + case err := <-commands.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + target, level, backwards := documentReviewCommand(command) + if target == 0 { + t.Fatalf("unexpected command %s", command) + } + if err := worker.MoveDocument(target, level, backwards); err != nil { + t.Fatal(err) + } + var result review.Result + select { + case result = <-worker.Results(): + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + if result.Err != nil { + t.Fatal(result.Err) + } + if result.CaretErr != nil { + t.Fatal(result.CaretErr) + } + if reuseDocument && result.CaptureReason != nil { + t.Fatalf("unchanged page recaptured for %s: %v (%s)", chord, result.CaptureReason, result.CaptureDuration) + } + if result.Moved { + worker.SyncFocus(result.DocumentPosition.Snapshot.ID()) + } + presentDocumentResult(slog.New(slog.DiscardHandler), queue, result, presentation.Options{}) + got := <-queue.spoken + if !strings.HasPrefix(got, want) { + t.Fatalf("%s: speech %q want %q", chord, got, want) + } + t.Logf("%s: %s (elapsed %s, capture %s)", chord, got, result.Elapsed, result.CaptureDuration) + } + for index, tc := range []struct{ chord, want string }{ + {"h", "Reading section, heading level 2"}, + {"h", "Ordinary unfocusable heading, heading level 2"}, + {"h", "Embedded heading, heading level 3"}, + {"h", "Browser foundation, heading level 1. Wrapping to top."}, + {"shift+h", "Embedded heading, heading level 3. Wrapping to bottom."}, + {"ctrl+shift+Insert+k", "Example link"}, + {"ctrl+Insert+k", "Example link, link. Wrapping to top."}, + } { + checkCommand(tc.chord, tc.want) + // Brave can retire the embedded srcdoc object during frame load. + // Cache reuse is deterministic only across the parent headings. + reuseDocument = index < 1 + } + reuseDocument = false + keys("ctrl+r") + for attempt := 0; attempt < 25; attempt++ { + keys("Tab") + timer := time.NewTimer(250 * time.Millisecond) + waitFocus: + for { + select { + case event := <-adapter.Events(): + if isFocusEvent(event.Type) && event.Source.Name == "Browser foundation" && event.Source.ID() != focus.ID() { + timer.Stop() + worker.SyncFocus(event.Source.ID()) + checkCommand("h", "Reading section, heading level 2") + checkCommand("shift+h", "Browser foundation, heading level 1") + return + } + case <-timer.C: + break waitFocus + case <-ctx.Done(): + timer.Stop() + t.Fatal(ctx.Err()) + } + } + } + t.Fatal("reloaded heading focus missing") +} + +func TestNativeBrowserEditing(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + listener := xorg.New() + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + var selectedCompletion atomic.Bool + var browserNameChanged atomic.Bool + var latestCaret atomic.Pointer[atspi.Event] + observed := &browserEventProbe{Adapter: adapter, events: make(chan atspi.Event, 64)} + relayDone := make(chan struct{}) + go func() { + defer close(relayDone) + for { + select { + case event := <-adapter.Events(): + if event.Type == atspi.AccessibleNameEvent && event.Source.Name == "Cthulhu Browser Probe updated" && event.Source.ToolkitName == "Chromium" { + browserNameChanged.Store(true) + } + if event.Type == atspi.CaretEvent { + latestCaret.Store(&event) + } + if event.Type == atspi.TextInsertedEvent && event.Source.Autocomplete && event.Source.SelectionEnd > event.Source.SelectionStart { + selectedCompletion.Store(true) + } + select { + case observed.events <- event: + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } + }() + defer func() { cancel(); <-relayDone }() + queue := &fakeSpeechQueue{spoken: make(chan string, 128), interrupt: make(chan struct{}, 128)} + logger := slog.New(slog.DiscardHandler) + inputDone := make(chan struct{}) + go func() { + defer close(inputDone) + processInputEvents(ctx, logger, queue, listener, input.EchoSettings{}, nil, nil) + }() + defer func() { cancel(); <-inputDone }() + done := make(chan struct{}) + go func() { + defer close(done) + options := presentation.DefaultOptions() + options.KeyEchoInEditFieldsOnly = true + processEventsWithInput(ctx, logger, queue, observed, nil, nil, 20*time.Millisecond, nil, listener, nil, nil, options) + }() + defer func() { cancel(); <-done }() + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + collect := func() []string { + t.Helper() + timer := time.NewTimer(180 * time.Millisecond) + defer timer.Stop() + var result []string + for { + select { + case text := <-queue.spoken: + result = append(result, text) + case <-timer.C: + return result + case <-ctx.Done(): + t.Fatal(ctx.Err()) + return nil + } + } + } + keys("ctrl+l") + collect() + if !adapter.EditFieldFocused() { + t.Fatal("browser address bar did not enable edit-field key echo") + } + for _, letter := range []string{"c", "t", "h"} { + for len(queue.interrupt) > 0 { + <-queue.interrupt + } + keys(letter) + got := collect() + if len(got) != 1 || got[0] != letter { + t.Fatalf("typing %q: %q", letter, got) + } + if len(queue.interrupt) == 0 { + t.Fatalf("typing %q did not interrupt speech", letter) + } + } + keys("Down") + got := collect() + if len(got) != 1 || !strings.Contains(got[0], "list item") { + t.Fatalf("explicit suggestion navigation: %q", got) + } + keys("Escape") + keys("Escape") + keys("Escape") + collect() + // Exercise the browser's native caret against non-editable page text. + keys("F7") + collect() + keys("Return") + collect() + foundPage := false + for attempt := 0; attempt < 30 && !foundPage; attempt++ { + keys("Tab") + for _, text := range collect() { + if strings.Contains(text, "Browser foundation, heading") { + foundPage = true + } + } + } + if !foundPage { + t.Fatal("could not focus the page heading") + } + keys("ctrl+Home") + collect() + keys("Down") + collect() // The focusable second heading may announce its role as well. + keys("Down") + got = collect() + if len(got) == 0 || got[len(got)-1] != "Plain document text with Café and 猫." { + t.Fatalf("native page line navigation: %q", got) + } + keys("ctrl+Right") + got = collect() + if len(got) != 1 || got[0] != "Plain" { + t.Fatalf("native word navigation: %q", got) + } + keys("Right") + got = collect() + if len(got) != 1 || got[0] != "d" { + t.Fatalf("native character navigation: %q", got) + } + keys("End") + collect() + if event := latestCaret.Load(); event == nil || event.Source.Text != "Plain document text with Café and 猫." { + t.Fatalf("line snapshot at end of browser text: %+v", event) + } + keys("Home") + collect() + keys("Down") + collect() + keys("Down") + got = collect() + if len(got) != 1 || got[0] != "• Registered: September 2026" { + t.Fatalf("embedded browser line text: %q", got) + } + // Preserve the browser-specific suffix. AT-SPI can report this change + // before the native X11 title cache catches up. + wantTitle := strings.Replace(adapter.ForegroundTitle().Title.Title, "Cthulhu Browser Probe", "Cthulhu Browser Probe updated", 1) + keys("F8") + got = collect() + if len(got) != 1 || got[0] != wantTitle || !strings.Contains(wantTitle, "Cthulhu Browser Probe updated") || !browserNameChanged.Load() { + t.Fatalf("browser title update: speech=%q, expected=%q, native event=%v", got, wantTitle, browserNameChanged.Load()) + } + + // Seed a typed browser URL locally, then replace it with a prefix. This + // exercises real selected inline completion without external networking. + keys("ctrl+l") + collect() + if !adapter.EditFieldFocused() { + t.Fatal("browser address bar did not enable edit-field key echo") + } + if out, err := exec.CommandContext(ctx, "xdotool", "type", "--clearmodifiers", "--delay", "20", "brave://version").CombinedOutput(); err != nil { + t.Fatalf("type URL: %v %s", err, out) + } + collect() + keys("Return") + collect() + keys("ctrl+l") + collect() + if !adapter.EditFieldFocused() { + t.Fatal("browser address bar did not enable edit-field key echo") + } + selectedCompletion.Store(false) + for _, letter := range []string{"b", "r", "a"} { + keys(letter) + got = collect() + want := letter + if letter == "b" { + want = "brave://version" + } + if len(got) != 1 || got[0] != want { + t.Fatalf("inline completion typing %q: %q, want %q", letter, got, want) + } + } + if !selectedCompletion.Load() { + t.Fatal("inline completion fixture did not produce a selected completion") + } +} + +type browserEventProbe struct { + *atspi.Adapter + events chan atspi.Event +} + +func (probe *browserEventProbe) Events() <-chan atspi.Event { return probe.events } + +type readAllProbeQueue struct { + *fakeSpeechQueue + reading chan speechRequest +} + +type browserBrailleProbe struct{ frames chan braille.Frame } + +func (probe browserBrailleProbe) EnqueueFrame(frame braille.Frame) { + select { + case probe.frames <- frame: + default: + // Like the real helper, retain recent output without blocking input + // while browser chrome produces many updates before an assertion. + select { + case <-probe.frames: + default: + } + select { + case probe.frames <- frame: + default: + } + } +} + +func (queue *readAllProbeQueue) Enqueue(request speechRequest) { + if request.Cause == "read-all" { + queue.reading <- request + return + } + queue.fakeSpeechQueue.Enqueue(request) +} + +func TestNativeBrowserModes(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second) + defer cancel() + diagnostics, err := os.CreateTemp("", "cthulhu-browser-modes-*.log") + if err != nil { + t.Fatal(err) + } + defer diagnostics.Close() + t.Logf("event diagnostics: %s", diagnostics.Name()) + logger := slog.New(slog.NewJSONHandler(diagnostics, &slog.HandlerOptions{Level: slog.LevelDebug})) + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + listener := xorg.New() + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + commands := xorg.NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := commands.Start(ctx); err != nil { + t.Fatal(err) + } + defer commands.Stop(context.Background()) + worker, err := review.NewWorker(adapter, 2*time.Second) + if err != nil { + t.Fatal(err) + } + worker.SetDocumentBrailleEnabled(true) + if err = worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + browser := newBrowserModeController(listener, commands, adapter) + if err = browser.Start(ctx); err != nil { + t.Fatal(err) + } + defer browser.Stop(context.Background()) + queue := &readAllProbeQueue{fakeSpeechQueue: &fakeSpeechQueue{spoken: make(chan string, 256)}, reading: make(chan speechRequest, 1)} + brailleFrames := make(chan braille.Frame, 256) + // Shift+Down preserves a visual x position, so its character endpoint + // depends on fonts and browser layout. Compare speech with the actual + // native range rather than a hard-coded paragraph prefix. + nativeSelections := make(chan atspi.Snapshot, 16) + nativeLoads := make(chan atspi.Event, 16) + events := make(chan atspi.Event, 64) + probe := &browserEventProbe{Adapter: adapter, events: events} + probeDone := make(chan struct{}) + go func() { + defer close(probeDone) + for { + select { + case <-ctx.Done(): + return + case event := <-adapter.Events(): + if event.Type == atspi.CaretEvent && event.Source.Role == "paragraph" && + event.Source.TextCaretKnown && event.Source.SelectionEnd > event.Source.SelectionStart { + select { + case nativeSelections <- event.Source: + default: + } + } + select { + case events <- event: + case <-ctx.Done(): + return + } + if event.Type == atspi.DocumentLoadCompleteEvent { + select { + case nativeLoads <- event: + case <-ctx.Done(): + return + } + } + } + } + }() + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, logger, outputQueue{speech: queue, braille: browserBrailleProbe{frames: brailleFrames}}, probe, nil, worker, 20*time.Millisecond, nil, browser, nil, nil) + }() + commandDone := make(chan struct{}) + go func() { + defer close(commandDone) + for { + select { + case <-ctx.Done(): + return + case event := <-commands.Commands(): + command := event.Command + logger.Debug("native probe command", "command", command, "input_timestamp", event.Timestamp, "activity", listener.RecentInput()) + browser.observeCommand(command) + if command == input.ToggleDocumentMode || command == input.StickyFocusMode || command == input.StickyBrowseMode { + browser.toggles <- command + } else if target, level, backwards := documentReviewCommand(command); target != 0 { + worker.MoveDocument(target, level, backwards) + } else if caretCommand := documentCaretCommand(command); caretCommand != 0 { + worker.MoveDocumentCaret(caretCommand) + } else if unit, step := flatReviewCommand(command); unit != 0 { + worker.ReadFlat(unit, step) + } else if command == input.ReadAll { + worker.ReadAll(ctx) + } else if command == input.DocumentActivate { + worker.ActivateDocumentCaret() + } + } + } + }() + defer func() { cancel(); <-done; <-commandDone; <-probeDone }() + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + wait := func(want string) { + t.Helper() + timer := time.NewTimer(3 * time.Second) + defer timer.Stop() + var heard []string + for { + select { + case text := <-queue.spoken: + heard = append(heard, text) + if strings.Contains(text, "Could not") { + t.Fatalf("navigation failure: %s", text) + } + if text == want { + t.Logf("heard %s", text) + return + } + case err := <-commands.Failures(): + t.Fatal(err) + case <-timer.C: + t.Fatalf("missing %q; heard %q", want, heard) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + waitPrefix := func(want string) { + t.Helper() + timer := time.NewTimer(3 * time.Second) + defer timer.Stop() + var heard []string + for { + select { + case text := <-queue.spoken: + heard = append(heard, text) + if strings.HasPrefix(text, want) { + t.Logf("heard %s", text) + return + } + case err := <-commands.Failures(): + t.Fatal(err) + case <-timer.C: + t.Fatalf("missing %q; heard %q", want, heard) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + browseReady := func() { + t.Helper() + timer := time.NewTimer(3 * time.Second) + defer timer.Stop() + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + for !commands.BrowseNavigationEnabled() { + select { + case <-ticker.C: + case <-timer.C: + t.Fatal("browse grabs did not become ready") + } + } + } + waitLoaded := func(name string) { + t.Helper() + // A title can arrive before busy/load events retire the old browse + // grabs. Wait for the actual document completion and its new anchor. + for { + select { + case event := <-nativeLoads: + if event.Source.Name != name { + continue + } + for worker.Focus() != event.Source.ID() || !commands.BrowseNavigationEnabled() { + select { + case <-time.After(time.Millisecond): + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + return + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + waitBraille := func(text string, cursor int) braille.Frame { + t.Helper() + timer := time.NewTimer(3 * time.Second) + defer timer.Stop() + var last braille.Frame + for { + select { + case frame := <-brailleFrames: + last = frame + if frame.Text == text && frame.Cursor == cursor { + // A frame can arrive before the mode controller restores + // native browse grabs after the preceding caret placement. + browseReady() + return frame + } + case <-timer.C: + t.Fatalf("missing braille %q cursor %d; last frame %+v", text, cursor, last) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + // This proof also runs by itself. Enable native caret browsing so Down + // moves in document content after structural navigation. + keys("F7") + keys("Return") + // Reload resets focus; Tab reaches the fixture's first focusable heading. + keys("ctrl+l") + waitPrefix("Address and search bar") + fixture, err := filepath.Abs("../../tests/browser.html") + if err != nil { + t.Fatal(err) + } + if out, err := exec.CommandContext(ctx, "xdotool", "type", "--clearmodifiers", "file://"+fixture).CombinedOutput(); err != nil { + t.Fatalf("load fixture: %v %s", err, out) + } + keys("Return") + waitPrefix("Cthulhu Browser Probe") + waitLoaded("Cthulhu Browser Probe") + // Browser chrome can insert a tab-strip stop after a reload. Follow the + // actual focus announcements until the first document heading is reached. + foundHeading := false + for attempt := 0; attempt < 20 && !foundHeading; attempt++ { + keys("Tab") + timer := time.NewTimer(400 * time.Millisecond) + searchHeading: + for { + select { + case text := <-queue.spoken: + if text == "Browser foundation, heading level 1" { + foundHeading = true + break searchHeading + } + case <-timer.C: + break searchHeading + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + timer.Stop() + } + if !foundHeading { + t.Fatal("could not focus first document heading after reload") + } + browseReady() + keys("h") + wait("Reading section, heading level 2") + if err := worker.ReadFlat(review.Line, 0); err != nil { + t.Fatal(err) + } + wait("Reading section") + // Closing a second tab must restore browse keys for the original page. + keys("ctrl+t") + keys("ctrl+l") + waitPrefix("Address and search bar") + tabFixture, err := filepath.Abs("../../tests/browser-next.html") + if err != nil { + t.Fatal(err) + } + if out, err := exec.CommandContext(ctx, "xdotool", "type", "--clearmodifiers", "file://"+tabFixture).CombinedOutput(); err != nil { + t.Fatalf("load second tab: %v %s", err, out) + } + keys("Return") + waitPrefix("Cthulhu Second Page") + waitLoaded("Cthulhu Second Page") + keys("ctrl+w") + wait("Reading section, heading level 2") + browseReady() + // Page changes must reset the virtual position without a Tab/arrow nudge. + // Exercise both an address-bar load and activation of a real page link. + keys("ctrl+l") + waitPrefix("Address and search bar") + nextFixture, err := filepath.Abs("../../tests/browser-next.html") + if err != nil { + t.Fatal(err) + } + if out, err := exec.CommandContext(ctx, "xdotool", "type", "--clearmodifiers", "file://"+nextFixture).CombinedOutput(); err != nil { + t.Fatalf("load second fixture: %v %s", err, out) + } + keys("Return") + waitPrefix("Cthulhu Second Page") + waitLoaded("Cthulhu Second Page") + browseReady() + keys("KP_Add") + select { + case request := <-queue.reading: + var text []string + for _, part := range request.ReadAll { + text = append(text, part.Text) + } + if got := strings.Join(text, "|"); got != "Fresh page heading|heading level 1|Fresh page content.|Return to browser probe|link" { + t.Fatalf("read all = %q, error speech = %q", got, request.Text) + } + case <-time.After(3 * time.Second): + t.Fatal("keypad Plus did not produce read all") + } + // Native Tab may select a link before any command captures a browse cursor. + keys("Tab") + wait("Return to browser probe, link") + browseReady() + keys("Return") + waitPrefix("Cthulhu Browser Probe") + waitLoaded("Cthulhu Browser Probe") + browseReady() + keys("h") + wait("Browser foundation, heading level 1") + keys("h") + wait("Reading section, heading level 2") + browseReady() + keys("Home") + wait("R") + keys("shift+End") + wait("Reading section selected") + keys("shift+Down") + select { + case snapshot := <-nativeSelections: + paragraph := []rune("Plain document text with Café and 猫.") + if snapshot.SelectionStart != 0 || snapshot.SelectionEnd > len(paragraph) || + snapshot.BrailleCaret != snapshot.SelectionEnd { + t.Fatalf("heading-to-paragraph selection endpoints: %+v", snapshot) + } + selected := string(paragraph[:snapshot.SelectionEnd]) + if snapshot.SelectionText != selected { + t.Fatalf("native selected text = %q; range 0:%d = %q", snapshot.SelectionText, snapshot.SelectionEnd, selected) + } + t.Logf("native paragraph selection 0:%d, caret %d: %q", snapshot.SelectionEnd, snapshot.BrailleCaret, selected) + wait(strings.Join(strings.Fields(selected), " ") + " selected") + case <-time.After(3 * time.Second): + t.Fatal("Shift+Down did not select text in the paragraph") + } + keys("Home") + wait("P") + keys("Up") + wait("Reading section, heading level 2") + keys("Down") + wait("Plain document text with Café and 猫.") + waitBraille("Plain document text with Café and 猫.", 0) + browseReady() + keys("k") + wait("Example link, link") + keys("shift+F10") + wait("menu") + keys("Down") + waitPrefix("Open link in new tab") + keys("Down") + waitPrefix("Open link in new window") + keys("Escape") + browseReady() + keys("Home") + wait("E") + keys("ctrl+Right") + wait("Example, link") + keys("Return") + keys("h") + wait("Ordinary unfocusable heading, heading level 2") + browseReady() + keys("Down") + wait("Text refreshed after the ordinary heading.") + waitBraille("Text refreshed after the ordinary heading.", 0) + keys("Right") + wait("e") + waitBraille("Text refreshed after the ordinary heading.", 1) + keys("Home") + wait("T") + waitBraille("Text refreshed after the ordinary heading.", 0) + keys("ctrl+Right") + wait("Text") + waitBraille("Text refreshed after the ordinary heading.", 4) + keys("ctrl+Right") + wait("refreshed") + keys("ctrl+Left") + wait("refreshed") + keys("Home") + wait("T") + routeDisplay := &brailleWorker{document: worker, logger: slog.New(slog.DiscardHandler), wake: make(chan struct{}, 1), cancel: func() {}} + routeBrowse := func(frame braille.Frame, offset int) { + t.Helper() + if frame.Document == nil || len(frame.Routes) == 0 { + t.Fatalf("browse frame has no document routes: %+v", frame) + } + routeDisplay.EnqueueFrame(frame) + routeDisplay.route(ctx, braille.RoutingEvent{ID: routeDisplay.current().ID, Offset: offset}) + } + routeBrowse(waitBraille("Text refreshed after the ordinary heading.", 0), 1) + waitBraille("Text refreshed after the ordinary heading.", 1) + keys("Right") + wait("x") + waitBraille("Text refreshed after the ordinary heading.", 2) + keys("Home") + wait("T") + checkSelectionBraille := func(cursor, selected int) braille.Frame { + t.Helper() + frame := waitBraille("Text refreshed after the ordinary heading. $l", cursor) + for index := 0; index < 3; index++ { + want := byte(0) + if index < selected { + want = 0xc0 + } + if len(frame.Dots) <= index || frame.Dots[index] != want { + t.Fatalf("selection braille dots = %v; selected characters = %d", frame.Dots, selected) + } + } + return frame + } + keys("shift+Right") + wait("T selected") + checkSelectionBraille(1, 1) + keys("shift+Right") + wait("e selected") + checkSelectionBraille(2, 2) + keys("shift+Left") + wait("e unselected") + selectionFrame := checkSelectionBraille(1, 1) + // Routing a native selection frame clears selection and updates Go's cursor. + routeBrowse(selectionFrame, 1) + waitBraille("Text refreshed after the ordinary heading.", 1) + // Resume Go navigation from the native endpoint, then reverse it. + keys("Right") + wait("x") + waitBraille("Text refreshed after the ordinary heading.", 2) + keys("Left") + wait("e") + waitBraille("Text refreshed after the ordinary heading.", 1) + keys("Home") + wait("T") + for _, text := range []string{"e", "x", "t", "space"} { + keys("Right") + wait(text) + } + keys("End") + wait(".") + keys("ctrl+Left") + wait("heading") + keys("shift+h") + wait("Ordinary unfocusable heading, heading level 2") + keys("shift+h") + wait("Reading section, heading level 2") + keys("ctrl+Home") + wait("Browser foundation, heading level 1") + // The next native Tab must follow the new caret position, not the old link. + keys("Tab") + wait("Reading section, heading level 2") + browseReady() + keys("b") + waitPrefix("Details, button") + keys("shift+x") + waitPrefix("Remember choice, check box") + keys("shift+l") + wait("Example list, 2 items") + // The separator follows the list in document order, so this is forward + // navigation. Shift+S correctly reports the previous-separator boundary. + keys("s") + waitPrefix("Section separator, separator") + keys("k") + wait("Example link, link") + keys("Tab") + wait("Focus mode") + keys("h") + wait("h") + keys("k") + wait("k") + keys("Insert+a") + wait("Browse mode") + browseReady() + keys("h") + wait("Ordinary unfocusable heading, heading level 2") + keys("Insert+a") + wait("Focus mode") + keys("Insert+a") + wait("Focus mode is sticky.") + keys("Insert+a") + wait("Browse mode is sticky.") + // Separate ordinary toggles from the 500 ms multi-press sequence. + time.Sleep(550 * time.Millisecond) + keys("Insert+a") + wait("Focus mode") + time.Sleep(550 * time.Millisecond) + keys("Insert+a") + wait("Browse mode") + keys("ctrl+l") + // The chrome focus presentation is not stable across browser releases; + // Where Am I isn't needed to establish pass-through: typing must be heard. + keys("h") + wait("h") + keys("Escape") + keys("Escape") + found := false + for attempt := 0; attempt < 25 && !found; attempt++ { + keys("Tab") + timer := time.NewTimer(200 * time.Millisecond) + nextFocus: + for { + select { + case text := <-queue.spoken: + if text == "Browser foundation, heading level 1" { + found = true + break nextFocus + } + case <-timer.C: + break nextFocus + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + timer.Stop() + } + if !found { + t.Fatal("could not return to page heading from chrome") + } + browseReady() + keys("h") + wait("Reading section, heading level 2") + readAll := func() speechRequest { + t.Helper() + keys("KP_Add") + select { + case request := <-queue.reading: + if len(request.ReadAll) == 0 { + t.Fatalf("read all failed: %q", request.Text) + } + for _, part := range request.ReadAll { + if strings.Contains(part.Text, "private-probe-value") { + t.Fatal("read all exposed password text") + } + } + return request + case <-time.After(3 * time.Second): + t.Fatal("read all did not complete") + return speechRequest{} + } + } + reading := readAll() + if len(reading.ReadAll) < 3 || reading.ReadAll[2].Text != "Plain document text with Café and 猫." { + t.Fatal("reading sequence did not continue after the heading text and role") + } + // A real backend invokes this only upon SSIP BEGIN. Resume should use + // the spoken line rather than the original heading or end of the page. + reading.ReadAll[2].Began() + resumed := readAll() + if resumed.ReadAll[0].Text != "Plain document text with Café and 猫." { + t.Fatalf("resumed from %q", resumed.ReadAll[0].Text) + } +} diff --git a/internal/app/document_review.go b/internal/app/document_review.go new file mode 100644 index 0000000..8bce04d --- /dev/null +++ b/internal/app/document_review.go @@ -0,0 +1,464 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "errors" + "fmt" + "log/slog" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +func documentReviewCommand(command input.Command) (review.DocumentTarget, int, bool) { + switch command { + case input.DocumentNextHeading: + return review.DocumentHeading, 0, false + case input.DocumentPreviousHeading: + return review.DocumentHeading, 0, true + case input.DocumentNextHeadingAtLevel1: + return review.DocumentHeading, 1, false + case input.DocumentPreviousHeadingAtLevel1: + return review.DocumentHeading, 1, true + case input.DocumentNextHeadingAtLevel2: + return review.DocumentHeading, 2, false + case input.DocumentPreviousHeadingAtLevel2: + return review.DocumentHeading, 2, true + case input.DocumentNextHeadingAtLevel3: + return review.DocumentHeading, 3, false + case input.DocumentPreviousHeadingAtLevel3: + return review.DocumentHeading, 3, true + case input.DocumentNextHeadingAtLevel4: + return review.DocumentHeading, 4, false + case input.DocumentPreviousHeadingAtLevel4: + return review.DocumentHeading, 4, true + case input.DocumentNextHeadingAtLevel5: + return review.DocumentHeading, 5, false + case input.DocumentPreviousHeadingAtLevel5: + return review.DocumentHeading, 5, true + case input.DocumentNextHeadingAtLevel6: + return review.DocumentHeading, 6, false + case input.DocumentPreviousHeadingAtLevel6: + return review.DocumentHeading, 6, true + case input.DocumentNextLink: + return review.DocumentLink, 0, false + case input.DocumentPreviousLink: + return review.DocumentLink, 0, true + case input.DocumentNextButton: + return review.DocumentButton, 0, false + case input.DocumentPreviousButton: + return review.DocumentButton, 0, true + case input.DocumentNextCheckBox: + return review.DocumentCheckBox, 0, false + case input.DocumentPreviousCheckBox: + return review.DocumentCheckBox, 0, true + case input.DocumentNextList: + return review.DocumentList, 0, false + case input.DocumentPreviousList: + return review.DocumentList, 0, true + case input.DocumentNextSeparator: + return review.DocumentSeparator, 0, false + case input.DocumentPreviousSeparator: + return review.DocumentSeparator, 0, true + case input.DocumentNextBlockQuote: + return review.DocumentBlockQuote, 0, false + case input.DocumentPreviousBlockQuote: + return review.DocumentBlockQuote, 0, true + case input.DocumentNextComboBox: + return review.DocumentComboBox, 0, false + case input.DocumentPreviousComboBox: + return review.DocumentComboBox, 0, true + case input.DocumentNextEntry: + return review.DocumentEntry, 0, false + case input.DocumentPreviousEntry: + return review.DocumentEntry, 0, true + case input.DocumentNextFormField: + return review.DocumentFormField, 0, false + case input.DocumentPreviousFormField: + return review.DocumentFormField, 0, true + case input.DocumentNextImage: + return review.DocumentImage, 0, false + case input.DocumentPreviousImage: + return review.DocumentImage, 0, true + case input.DocumentNextLandmark: + return review.DocumentLandmark, 0, false + case input.DocumentPreviousLandmark: + return review.DocumentLandmark, 0, true + case input.DocumentNextListItem: + return review.DocumentListItem, 0, false + case input.DocumentPreviousListItem: + return review.DocumentListItem, 0, true + case input.DocumentNextLiveRegion: + return review.DocumentLiveRegion, 0, false + case input.DocumentPreviousLiveRegion: + return review.DocumentLiveRegion, 0, true + case input.DocumentNextParagraph: + return review.DocumentParagraph, 0, false + case input.DocumentPreviousParagraph: + return review.DocumentParagraph, 0, true + case input.DocumentNextRadioButton: + return review.DocumentRadioButton, 0, false + case input.DocumentPreviousRadioButton: + return review.DocumentRadioButton, 0, true + case input.DocumentNextTable: + return review.DocumentTable, 0, false + case input.DocumentPreviousTable: + return review.DocumentTable, 0, true + case input.DocumentNextUnvisitedLink: + return review.DocumentUnvisitedLink, 0, false + case input.DocumentPreviousUnvisitedLink: + return review.DocumentUnvisitedLink, 0, true + case input.DocumentNextVisitedLink: + return review.DocumentVisitedLink, 0, false + case input.DocumentPreviousVisitedLink: + return review.DocumentVisitedLink, 0, true + case input.DocumentNextClickable: + return review.DocumentClickable, 0, false + case input.DocumentPreviousClickable: + return review.DocumentClickable, 0, true + case input.DocumentNextChunk: + return review.DocumentChunk, 0, false + case input.DocumentPreviousChunk: + return review.DocumentChunk, 0, true + } + return 0, 0, false +} + +func documentCaretCommand(command input.Command) review.DocumentCaretCommand { + switch command { + case input.DocumentTableLeft: + return review.TableLeft + case input.DocumentTableRight: + return review.TableRight + case input.DocumentTableUp: + return review.TableUp + case input.DocumentTableDown: + return review.TableDown + case input.DocumentTableFirst: + return review.TableFirst + case input.DocumentTableLast: + return review.TableLast + + case input.DocumentCaretNextCharacter: + return review.CaretNextCharacter + case input.DocumentCaretPreviousCharacter: + return review.CaretPreviousCharacter + case input.DocumentCaretNextWord: + return review.CaretNextWord + case input.DocumentCaretPreviousWord: + return review.CaretPreviousWord + case input.DocumentCaretNextLine: + return review.CaretNextLine + case input.DocumentCaretPreviousLine: + return review.CaretPreviousLine + case input.DocumentCaretLineStart: + return review.CaretLineStart + case input.DocumentCaretLineEnd: + return review.CaretLineEnd + case input.DocumentCaretDocumentStart: + return review.CaretDocumentStart + case input.DocumentCaretDocumentEnd: + return review.CaretDocumentEnd + } + return 0 +} + +func presentDocumentCaretResult(logger *slog.Logger, speech speechEnqueuer, result review.Result, options presentation.Options) { + if logger.Enabled(context.Background(), slog.LevelDebug) { + logger.Debug("document caret navigation completed", "elapsed", result.Elapsed, + "error", result.Err, "document_epoch", result.DocumentEpoch, + "focus", result.DocumentFocus, "document", result.DocumentPosition.Document.ID(), + "application", result.DocumentPosition.Snapshot.ApplicationName, "role", result.DocumentPosition.Snapshot.Role, + "navigation", result.DocumentDiagnostics, + "capture_duration", result.CaptureDuration, "capture_reason", result.CaptureReason, + "moved", result.Moved, "command", result.DocumentCaretCommand.String(), + "bus", result.DocumentPosition.Object.ID().BusName, + "source_path", result.DocumentPosition.Object.ID().Path, + "virtual_caret_offset", result.DocumentPosition.Offset, + "native_text_start", result.DocumentCaretStart, "native_text_end", result.DocumentCaretEnd, + "line_fragments", document_line_ranges(result.DocumentCaretLine), + "caret_sync_error", result.CaretErr, + "braille_line_available", result.DocumentBrailleLine != nil || result.DocumentCaretLine != nil, + "braille_read_error", result.DocumentBrailleErr) + } + if result.Err != nil { + logger.Warn("document caret navigation failed", "error", result.Err) + speech.Enqueue(speechRequest{Text: "Could not find current location.", Role: "system", Cause: "document-caret"}) + return + } + if !result.Moved && result.DocumentCaretText == "" { + return + } + text := result.DocumentCaretText + if text == " " { + text = "space" + } + if text == "\n" { + if !options.SpeakBlankLines { + return + } + text = "blank" + } + request := speechRequest{Text: text, Role: result.DocumentPosition.Snapshot.Role, Cause: "document-caret"} + request.PhoneticHint = result.DocumentCaretCommand == review.CaretNextCharacter || result.DocumentCaretCommand == review.CaretPreviousCharacter + request.Context = result.DocumentCaretContext + if len(request.Context) > 0 && request.Context[0].ID() == result.DocumentPosition.Snapshot.ID() { + request.Context = request.Context[1:] + } + if result.DocumentCaretCommand >= review.TableLeft && result.DocumentCaretCommand <= review.TableLast { + snapshot := result.DocumentPosition.Snapshot + prefix := result.DocumentTablePrefix + if result.Moved && options.SpeechVerbosityLevel != 0 && prefix != "" && + (result.DocumentTableRowHeader != "" || result.DocumentTableColumnHeader != "") { + parts := []string{ + presentation.TableHeaderText(result.DocumentTableRowHeader, "row header", options.SpeechVerbosityLevel), + presentation.TableHeaderText(result.DocumentTableColumnHeader, "column header", options.SpeechVerbosityLevel), + } + prefix = strings.TrimSpace(strings.Join(parts, " ")) + if strings.HasPrefix(request.Text, result.DocumentTablePrefix+" ") { + request.Text = prefix + strings.TrimPrefix(request.Text, result.DocumentTablePrefix) + } + } + if result.Moved && options.Reading != nil && options.Reading.OnlySpeakDisplayedText { + request.Text = snapshot.Name + } + vertical := result.DocumentCaretCommand != review.TableLeft && result.DocumentCaretCommand != review.TableRight + if result.Moved && vertical && snapshot.TableRowText != "" && presentation.FullRowEnabled(snapshot, options) { + if options.Reading != nil && options.Reading.OnlySpeakDisplayedText { + request.Text = snapshot.TableRowText + } else { + request.Text = strings.TrimSpace(strings.Join([]string{prefix, snapshot.TableRowText, result.DocumentTableSuffix}, " ")) + } + } + } + for _, ancestor := range result.DocumentCaretContext { + if ancestor.Role == "link" { + request.VoiceType = "hyperlink" + break + } + } + switch result.DocumentCaretCommand { + case review.CaretNextCharacter, review.CaretPreviousCharacter, review.CaretLineStart, review.CaretLineEnd: + request.Character = true + case review.CaretNextLine, review.CaretPreviousLine, review.CaretDocumentStart, review.CaretDocumentEnd, + review.CaretNextWord, review.CaretPreviousWord: + line := atspi.DocumentLine{Contents: []atspi.DocumentContent{{Snapshot: result.DocumentPosition.Snapshot, Text: text, RawText: result.DocumentCaretRawText}}} + if result.DocumentCaretCommand != review.CaretNextWord && result.DocumentCaretCommand != review.CaretPreviousWord { + request.Line = document_speech_line(line) + } + roles := map[string]bool{result.DocumentPosition.Snapshot.Role: true} + // Chromium commonly exposes link/heading text in static descendants. + // Python's web _generateRoleName includes those ancestor roles. Keep + // their identity separate from the leaf which owns the caret offset. + for _, ancestor := range result.DocumentCaretContext { + if (ancestor.Role != "link" && ancestor.Role != "heading") || roles[ancestor.Role] { + continue + } + roles[ancestor.Role] = true + ancestor.Name = "" + line.Contents = append(line.Contents, atspi.DocumentContent{Snapshot: ancestor}) + } + spoken := presentation.DocumentLineSpeechWithOptions(line, options) + request.Text, request.Chunks = spoken.Text, spoken.Chunks + request.Sound = presentation.DocumentLineSoundCues(line, options) + fallback := options + fallback.RoleSoundPresentation = "sound_and_speech" + fallbackSpeech := presentation.DocumentLineSpeechWithOptions(line, fallback) + request.FallbackText, request.FallbackChunks = fallbackSpeech.Text, fallbackSpeech.Chunks + } + if request.Text == "" && len(request.Sound) == 0 { + return + } + speech.Enqueue(request) +} + +func document_line_ranges(line *atspi.DocumentLine) []map[string]any { + if line == nil { + return nil + } + ranges := make([]map[string]any, 0, len(line.Contents)) + for _, content := range line.Contents { + ranges = append(ranges, map[string]any{"bus": content.Snapshot.BusName, + "source_path": content.Snapshot.Path, "native_text_start": content.Start, + "native_text_end": content.End, "bounds": content.Bounds}) + } + return ranges +} + +func documentResultMatchesCurrent(result review.Result, current atspi.Snapshot) bool { + if result.DocumentFocus == current.ID() { + return true + } + return result.Moved && result.Err == nil && + result.DocumentPosition.Snapshot.ID() == current.ID() +} + +func presentDocumentResult(logger *slog.Logger, speech speechEnqueuer, result review.Result, options presentation.Options) { + if logger.Enabled(context.Background(), slog.LevelDebug) { + logger.Debug("document navigation completed", "elapsed", result.Elapsed, + "error", result.Err, "document_epoch", result.DocumentEpoch, + "focus", result.DocumentFocus, "document", result.DocumentPosition.Document.ID(), + "application", result.DocumentPosition.Snapshot.ApplicationName, "role", result.DocumentPosition.Snapshot.Role, + "wrapped", result.DocumentWrapped, "navigation", result.DocumentDiagnostics, + "capture_duration", result.CaptureDuration, "capture_reason", result.CaptureReason, + "moved", result.Moved, "target", result.DocumentTarget, + "level", result.DocumentLevel, "backwards", result.DocumentBackwards, + "bus", result.DocumentPosition.Object.ID().BusName, + "source_path", result.DocumentPosition.Object.ID().Path, + "virtual_caret_offset", result.DocumentPosition.Offset, + "caret_sync_error", result.CaretErr, + "sound_geometry_error", result.DocumentSoundErr, + "braille_line_available", result.DocumentBrailleLine != nil, + "braille_read_error", result.DocumentBrailleErr) + } + text, fallbackText, role := "", "", "system" + var spoken, fallbackSpeech presentation.Speech + var cues []sound.Cue + switch { + case errors.Is(result.Err, atspi.ErrNotInDocument): + text = "Not in web document content." + case result.Err != nil: + logger.Warn("document navigation failed", "error", result.Err) + text = "Could not find current location." + case !result.Moved: + switch result.DocumentTarget { + case review.DocumentHeading: + if result.DocumentLevel == 0 { + text = "No more headings." + } else { + text = fmt.Sprintf("No more headings at level %d.", result.DocumentLevel) + } + case review.DocumentLink: + text = "No more links." + case review.DocumentButton: + text = "No more buttons." + case review.DocumentCheckBox: + text = "No more check boxes." + case review.DocumentList: + text = "No more lists." + case review.DocumentSeparator: + text = "No more separators." + case review.DocumentBlockQuote: + text = "No more blockquotes." + case review.DocumentComboBox: + text = "No more combo boxes." + case review.DocumentEntry: + text = "No more entries." + case review.DocumentFormField: + text = "No more form fields." + case review.DocumentImage: + text = "No more images." + case review.DocumentLandmark: + text = "No landmark found." + case review.DocumentListItem: + text = "No more list items." + case review.DocumentLiveRegion: + text = "No more live regions." + case review.DocumentParagraph: + text = "No more paragraphs." + case review.DocumentRadioButton: + text = "No more radio buttons." + case review.DocumentTable: + text = "No more tables." + case review.DocumentUnvisitedLink: + text = "No more unvisited links." + case review.DocumentVisitedLink: + text = "No more visited links." + case review.DocumentClickable: + text = "No more clickables." + case review.DocumentChunk: + text = "No more large objects." + } + default: + if link := result.DocumentPosition.LinkedHeading; link != nil { + roleOnly := *link + roleOnly.Name, roleOnly.Text = "", "" + line := atspi.DocumentLine{Contents: []atspi.DocumentContent{ + {Snapshot: result.DocumentPosition.Snapshot}, {Snapshot: roleOnly}, + }} + spoken = presentation.DocumentLineSpeechWithOptions(line, options) + text = spoken.Text + cues = presentation.DocumentLineSoundCues(line, options) + fallbackOptions := options + fallbackOptions.RoleSoundPresentation = "sound_and_speech" + fallbackSpeech = presentation.DocumentLineSpeechWithOptions(line, fallbackOptions) + fallbackText = fallbackSpeech.Text + } else { + spoken = presentation.FocusSpeechWithOptions(result.DocumentPosition.Snapshot, options) + text = spoken.Text + cues = presentation.SoundCues(result.DocumentPosition.Snapshot, options) + if options.RoleSoundPresentation == "sound_only" { + fallbackOptions := options + fallbackOptions.RoleSoundPresentation = "sound_and_speech" + fallbackSpeech = presentation.FocusSpeechWithOptions(result.DocumentPosition.Snapshot, fallbackOptions) + fallbackText = fallbackSpeech.Text + } + } + if len(cues) > 0 && logger.Enabled(context.Background(), slog.LevelDebug) { + // Record the captured geometry actually used for cue generation. + // Linked headings use the link's geometry independently of the heading. + attributes := []any{ + "bus", result.DocumentPosition.Snapshot.BusName, + "source_path", result.DocumentPosition.Snapshot.Path, + "role", result.DocumentPosition.Snapshot.Role, + "spatialize_object_sounds", options.SpatializeObjectSounds, + "sound_geometry", result.DocumentPosition.Snapshot.SoundGeometry, + "cues", cues, + } + if link := result.DocumentPosition.LinkedHeading; link != nil { + attributes = append(attributes, + "linked_heading_bus", link.BusName, + "linked_heading_path", link.Path, + "linked_heading_sound_geometry", link.SoundGeometry) + } + logger.Debug("document navigation sound positioning", attributes...) + } + role = result.DocumentPosition.Snapshot.Role + if result.DocumentWrapped { + if result.DocumentBackwards { + spoken = spoken.Append("Wrapping to bottom.", ". ") + text = spoken.Text + fallbackSpeech = fallbackSpeech.Append("Wrapping to bottom.", ". ") + fallbackText = fallbackSpeech.Text + } else { + spoken = spoken.Append("Wrapping to top.", ". ") + text = spoken.Text + fallbackSpeech = fallbackSpeech.Append("Wrapping to top.", ". ") + fallbackText = fallbackSpeech.Text + } + } + if result.CaretErr != nil { + logger.Warn("document caret synchronization failed", "error", result.CaretErr) + } + } + voiceType := ancestor_voice(result.DocumentCaretContext) + if result.DocumentPosition.LinkedHeading != nil { + voiceType = "hyperlink" + } + ancestors := result.DocumentCaretContext + if len(ancestors) > 0 && ancestors[0].ID() == result.DocumentPosition.Snapshot.ID() { + ancestors = ancestors[1:] + } + speech.Enqueue(speechRequest{Text: text, Chunks: spoken.WithText(text).Chunks, FallbackText: fallbackText, FallbackChunks: fallbackSpeech.WithText(fallbackText).Chunks, Role: role, Sound: cues, Cause: "document-navigation", Context: ancestors, VoiceType: voiceType}) +} diff --git a/internal/app/document_review_test.go b/internal/app/document_review_test.go new file mode 100644 index 0000000..0f6c4d4 --- /dev/null +++ b/internal/app/document_review_test.go @@ -0,0 +1,422 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/sound" + "log/slog" + "testing" + "time" +) + +func TestDocumentPresentation(t *testing.T) { + heading := atspi.NewSnapshot("/h", "Reading section", "heading", "", "") + heading.HeadingLevel = 2 + link := atspi.NewSnapshot("/l", "Example", "link", "", "") + link.Visited = true + for _, tc := range []struct { + result review.Result + want string + }{ + {review.Result{Moved: true, DocumentPosition: review.DocumentPosition{Snapshot: heading}}, "Reading section, heading level 2"}, + {review.Result{Moved: true, DocumentPosition: review.DocumentPosition{Snapshot: link}}, "Example, visited link"}, + {review.Result{Moved: true, DocumentWrapped: true, DocumentPosition: review.DocumentPosition{Snapshot: heading}}, "Reading section, heading level 2. Wrapping to top."}, + {review.Result{Moved: true, DocumentBackwards: true, DocumentWrapped: true, DocumentPosition: review.DocumentPosition{Snapshot: heading}}, "Reading section, heading level 2. Wrapping to bottom."}, + {review.Result{DocumentTarget: review.DocumentHeading}, "No more headings."}, + {review.Result{DocumentTarget: review.DocumentLink}, "No more links."}, + {review.Result{DocumentTarget: review.DocumentButton}, "No more buttons."}, + {review.Result{DocumentTarget: review.DocumentCheckBox}, "No more check boxes."}, + {review.Result{DocumentTarget: review.DocumentList}, "No more lists."}, + {review.Result{DocumentTarget: review.DocumentSeparator}, "No more separators."}, + {review.Result{DocumentTarget: review.DocumentHeading, DocumentLevel: 3}, "No more headings at level 3."}, + {review.Result{DocumentTarget: review.DocumentBlockQuote}, "No more blockquotes."}, + {review.Result{DocumentTarget: review.DocumentComboBox}, "No more combo boxes."}, + {review.Result{DocumentTarget: review.DocumentEntry}, "No more entries."}, + {review.Result{DocumentTarget: review.DocumentFormField}, "No more form fields."}, + {review.Result{DocumentTarget: review.DocumentImage}, "No more images."}, + {review.Result{DocumentTarget: review.DocumentLandmark}, "No landmark found."}, + {review.Result{DocumentTarget: review.DocumentListItem}, "No more list items."}, + {review.Result{DocumentTarget: review.DocumentLiveRegion}, "No more live regions."}, + {review.Result{DocumentTarget: review.DocumentParagraph}, "No more paragraphs."}, + {review.Result{DocumentTarget: review.DocumentRadioButton}, "No more radio buttons."}, + {review.Result{DocumentTarget: review.DocumentTable}, "No more tables."}, + {review.Result{DocumentTarget: review.DocumentUnvisitedLink}, "No more unvisited links."}, + {review.Result{DocumentTarget: review.DocumentVisitedLink}, "No more visited links."}, + {review.Result{DocumentTarget: review.DocumentClickable}, "No more clickables."}, + {review.Result{DocumentTarget: review.DocumentChunk}, "No more large objects."}, + {review.Result{Err: atspi.ErrNotInDocument}, "Not in web document content."}, + {review.Result{Err: atspi.ErrStaleObject}, "Could not find current location."}, + } { + queue := &fakeSpeechQueue{spoken: make(chan string, 1), interrupt: make(chan struct{}, 1)} + presentDocumentResult(slog.New(slog.DiscardHandler), queue, tc.result, presentation.Options{}) + if got := <-queue.spoken; got != tc.want { + t.Fatalf("got %q want %q", got, tc.want) + } + if len(queue.interrupt) != 0 { + t.Fatal("delayed document result interrupted speech again") + } + } +} + +func TestLinkedHeadingPresentation(t *testing.T) { + heading := atspi.NewSnapshot("/heading", "Linked heading", "heading", "", "") + heading.HeadingLevel = 2 + link := atspi.NewSnapshot("/link", "Linked heading", "link", "", "") + link.Visited = true + for _, mode := range []struct{ name, want string }{ + {"sound_and_speech", "Linked heading, heading level 2, visited link"}, + {"sound_only", "Linked heading, heading level 2"}, + {"speech_only", "Linked heading, heading level 2, visited link"}, + } { + t.Run(mode.name, func(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + queue := &modeSoundQueue{speech: speech, sounds: make(chan sound.Cue, 2)} + presentDocumentResult(slog.New(slog.DiscardHandler), queue, review.Result{ + Moved: true, DocumentPosition: review.DocumentPosition{Snapshot: heading, LinkedHeading: &link}, + }, presentation.Options{EnableSound: true, PlaySoundForRole: true, RoleSoundPresentation: mode.name}) + if got := <-speech.spoken; got != mode.want { + t.Fatalf("speech = %q, want %q", got, mode.want) + } + if mode.name != "speech_only" { + if cue := <-queue.sounds; cue.Name != "link_visited" { + t.Fatalf("cue = %+v", cue) + } + } + }) + } +} + +func TestDocumentPresentationUsesObjectSoundPolicy(t *testing.T) { + toggle := atspi.NewSnapshot("/toggle", "Power", "toggle button", "", "") + toggle.Checked = true + toggle.SoundGeometry = atspi.SoundGeometry{ + ObjectKnown: true, ReferenceKnown: true, + Object: atspi.Rectangle{X: 100, Y: 10, Width: 10, Height: 10}, + Reference: atspi.Rectangle{X: 100, Y: 0, Width: 1000, Height: 600}, + } + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + queue := &modeSoundQueue{speech: speech, sounds: make(chan sound.Cue, 2)} + options := presentation.Options{ + EnableSound: true, PlaySoundForRole: true, PlaySoundForState: true, + RoleSoundPresentation: "sound_only", SpatializeObjectSounds: true, + } + presentDocumentResult(slog.New(slog.DiscardHandler), queue, review.Result{ + Moved: true, DocumentPosition: review.DocumentPosition{Snapshot: toggle}, + }, options) + if got := <-speech.spoken; got != "Power" { + t.Fatalf("sound-only structural speech = %q", got) + } + if len(queue.sounds) != 1 { + t.Fatalf("structural cues = %d, want one toggle state cue", len(queue.sounds)) + } + if cue := <-queue.sounds; cue.Name != "togglebutton_checked" || cue.Pan != -1 { + t.Fatalf("structural cue = %#v, want togglebutton_checked panned left", cue) + } +} + +func TestDocumentReviewCommandMapping(t *testing.T) { + cases := []struct { + command input.Command + target review.DocumentTarget + level int + back bool + }{ + {input.DocumentNextHeadingAtLevel3, review.DocumentHeading, 3, false}, + {input.DocumentPreviousHeadingAtLevel3, review.DocumentHeading, 3, true}, + {input.DocumentNextComboBox, review.DocumentComboBox, 0, false}, + {input.DocumentPreviousComboBox, review.DocumentComboBox, 0, true}, + {input.DocumentNextChunk, review.DocumentChunk, 0, false}, + {input.DocumentPreviousClickable, review.DocumentClickable, 0, true}, + } + for _, tc := range cases { + target, level, back := documentReviewCommand(tc.command) + if target != tc.target || level != tc.level || back != tc.back { + t.Fatalf("%s: target=%v level=%d back=%v", tc.command, target, level, back) + } + } +} + +func TestDocumentNavigationReachesEventLoopSpeech(t *testing.T) { + id := func(path string) atspi.ObjectID { return atspi.NewObjectID(":1.42", path) } + doc := atspi.NewSnapshot("/doc", "Page", "document web", "", "") + doc.BusName = ":1.42" + heading := atspi.NewSnapshot("/heading", "Section", "heading", "", "") + heading.BusName = ":1.42" + heading.HeadingLevel = 2 + tree, err := atspi.NewAccessibleTree(id("/doc"), []atspi.TreeNode{ + {Snapshot: doc, Children: []atspi.ObjectID{id("/heading")}}, {Snapshot: heading}, + }) + if err != nil { + t.Fatal(err) + } + adapter := &fakeAdapter{events: make(chan atspi.Event, 1), tree: tree} + worker, err := review.NewWorker(adapter, time.Second) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithCancel(context.Background()) + if err := worker.Start(ctx); err != nil { + cancel() + t.Fatal(err) + } + defer worker.Stop(context.Background()) + defer cancel() + queue := &fakeSpeechQueue{spoken: make(chan string, 4), interrupt: make(chan struct{}, 4)} + done := make(chan error, 1) + go func() { + done <- processEventsWithObjectReview(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, worker, 0) + }() + expect := func(want string) { + t.Helper() + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("got %q want %q", got, want) + } + case <-time.After(time.Second): + t.Fatal("speech missing") + } + } + adapter.events <- atspi.NewEvent(atspi.FocusEvent, doc) + expect("Page, document web") + worker.MoveDocument(review.DocumentHeading, 0, false) + expect("Section, heading level 2") + worker.MoveDocument(review.DocumentHeading, 0, false) + expect("Section, heading level 2. Wrapping to top.") + cancel() + select { + case err := <-done: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestDocumentNavigationDiscardsPendingOldCaret(t *testing.T) { + id := func(path string) atspi.ObjectID { return atspi.NewObjectID(":1.42", path) } + doc := atspi.NewSnapshot("/doc", "Page", "document web", "", "") + doc.BusName = ":1.42" + link := atspi.NewSnapshot("/link", "Old link", "link", "", "") + link.BusName = ":1.42" + heading := atspi.NewSnapshot("/heading", "Next section", "heading", "", "") + heading.BusName = ":1.42" + tree, err := atspi.NewAccessibleTree(id("/doc"), []atspi.TreeNode{ + {Snapshot: doc, Children: []atspi.ObjectID{id("/link"), id("/heading")}}, + {Snapshot: link}, {Snapshot: heading}, + }) + if err != nil { + t.Fatal(err) + } + captureStarted := make(chan struct{}, 1) + releaseCapture := make(chan struct{}) + adapter := &fakeAdapter{events: make(chan atspi.Event)} + adapter.capture = func(ctx context.Context) (*atspi.AccessibleTree, error) { + captureStarted <- struct{}{} + select { + case <-releaseCapture: + return tree, nil + case <-ctx.Done(): + return nil, ctx.Err() + } + } + worker, err := review.NewWorker(adapter, time.Second) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 4)} + done := make(chan error, 1) + go func() { + done <- processEventsWithObjectReview(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, worker, 100*time.Millisecond) + }() + adapter.events <- atspi.NewEvent(atspi.FocusEvent, link) + if got := <-queue.spoken; got != "Old link, link" { + t.Fatalf("focus speech = %q", got) + } + if err := worker.MoveDocument(review.DocumentHeading, 0, false); err != nil { + t.Fatal(err) + } + select { + case <-captureStarted: + case <-time.After(time.Second): + t.Fatal("document capture did not start") + } + oldCaret := link + oldCaret.Text = "Old line" + adapter.events <- atspi.NewEvent(atspi.CaretEvent, oldCaret) + // Receiving the unrelated event means the old caret reached its timer + // before the structural capture is allowed to finish. + unrelated := atspi.NewSnapshot("/unrelated", "", "static", "", "") + unrelated.BusName = ":1.99" + adapter.events <- atspi.NewEvent(atspi.DefunctStateEvent, unrelated) + close(releaseCapture) + select { + case got := <-queue.spoken: + if got != "Next section, heading" { + t.Fatalf("navigation speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("navigation speech missing") + } + select { + case got := <-queue.spoken: + t.Fatalf("old caret replaced navigation speech: %q", got) + case <-time.After(50 * time.Millisecond): + } + cancel() + select { + case err := <-done: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestDocumentResultAcceptsSelfNavigationFocusTransition(t *testing.T) { + previous := atspi.NewSnapshot("/previous", "Previous", "heading", "", "") + target := atspi.NewSnapshot("/target", "Target", "heading", "", "") + moved := review.Result{ + Moved: true, + DocumentFocus: previous.ID(), + DocumentPosition: review.DocumentPosition{Snapshot: target}, + } + if !documentResultMatchesCurrent(moved, previous) { + t.Fatal("result for unchanged focus was rejected") + } + if !documentResultMatchesCurrent(moved, target) { + t.Fatal("result for navigation target was rejected") + } + other := atspi.NewSnapshot("/other", "Other", "heading", "", "") + if documentResultMatchesCurrent(moved, other) { + t.Fatal("result for unrelated focus was accepted") + } + boundary := moved + boundary.Moved = false + if documentResultMatchesCurrent(boundary, target) { + t.Fatal("unmoved result was accepted as a navigation transition") + } +} + +func TestCaretPresentationRetainsAncestorSemantics(t *testing.T) { + leaf := atspi.NewSnapshot("/text", "Entire longer label", "static", "", "") + link := atspi.NewSnapshot("/link", "Entire longer label", "link", "", "") + link.Visited = true + heading := atspi.NewSnapshot("/heading", "Entire heading", "heading", "", "") + heading.HeadingLevel = 3 + for _, tc := range []struct { + command review.DocumentCaretCommand + text, want string + }{ + {review.CaretNextLine, "Example", "Example, visited link, heading level 3"}, + {review.CaretPreviousWord, "Example", "Example, visited link, heading level 3"}, + {review.CaretNextCharacter, "E", "E"}, + {review.CaretLineStart, "E", "E"}, + } { + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 1)} + presentDocumentCaretResult(slog.New(slog.DiscardHandler), queue, review.Result{ + Moved: true, DocumentCaretCommand: tc.command, DocumentCaretText: tc.text, + DocumentPosition: review.DocumentPosition{Snapshot: leaf}, DocumentCaretContext: []atspi.Snapshot{leaf, link, heading}, + }, presentation.DefaultOptions()) + request := <-queue.requests + if request.Text != tc.want { + t.Fatalf("speech = %q, want %q", request.Text, tc.want) + } + wantCharacter := tc.command == review.CaretNextCharacter || tc.command == review.CaretLineStart + if request.Character != wantCharacter { + t.Fatalf("character voice = %v for command %v", request.Character, tc.command) + } + } +} + +func TestTableCaretHeadersFollowSpeechVerbosity(t *testing.T) { + cell := atspi.NewSnapshot("/cell", "42", "table cell", "", "") + cell.TableRowText = "42, 18" + result := review.Result{ + Moved: true, DocumentCaretCommand: review.TableRight, + DocumentCaretText: "Monday Total 42 Row 2, column 3.", + DocumentTablePrefix: "Monday Total", DocumentTableRowHeader: "Monday", DocumentTableColumnHeader: "Total", + DocumentPosition: review.DocumentPosition{Snapshot: cell}, + } + for _, tc := range []struct { + verbosity int + want string + }{{0, result.DocumentCaretText}, {1, "Monday row header Total column header 42 Row 2, column 3."}} { + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 1)} + options := presentation.DefaultOptions() + options.SpeechVerbosityLevel = tc.verbosity + presentDocumentCaretResult(slog.New(slog.DiscardHandler), queue, result, options) + if got := (<-queue.requests).Text; got != tc.want { + t.Fatalf("verbosity %d: %q, want %q", tc.verbosity, got, tc.want) + } + } + result.DocumentCaretCommand = review.TableDown + result.DocumentTableSuffix = "Row 2, column 3." + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 1)} + options := presentation.DefaultOptions() + options.SpeechVerbosityLevel = 1 + reading := config.DefaultSettings().Reading + reading.ReadFullRowInDocumentTable = true + options.Reading = &reading + presentDocumentCaretResult(slog.New(slog.DiscardHandler), queue, result, options) + if got := (<-queue.requests).Text; got != "Monday row header Total column header 42, 18 Row 2, column 3." { + t.Fatalf("verbose full row = %q", got) + } + reading.OnlySpeakDisplayedText = true + queue = &autocompleteRequestQueue{requests: make(chan speechRequest, 1)} + presentDocumentCaretResult(slog.New(slog.DiscardHandler), queue, result, options) + if got := (<-queue.requests).Text; got != "42, 18" { + t.Fatalf("displayed-only full row = %q", got) + } +} + +func TestCaretPresentationUsesAncestorRoleSound(t *testing.T) { + leaf := atspi.NewSnapshot("/text", "", "static", "", "") + link := atspi.NewSnapshot("/link", "Example", "link", "", "") + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + queue := &modeSoundQueue{speech: speech, sounds: make(chan sound.Cue, 2)} + presentDocumentCaretResult(slog.New(slog.DiscardHandler), queue, review.Result{ + Moved: true, DocumentCaretCommand: review.CaretNextLine, DocumentCaretText: "Example", + DocumentPosition: review.DocumentPosition{Snapshot: leaf}, DocumentCaretContext: []atspi.Snapshot{leaf, link}, + }, presentation.Options{EnableSound: true, PlaySoundForRole: true, RoleSoundPresentation: "sound_only"}) + if got := <-speech.spoken; got != "Example" { + t.Fatalf("sound-only speech = %q", got) + } + select { + case cue := <-queue.sounds: + if cue.Name != "link" { + t.Fatalf("cue = %+v", cue) + } + default: + t.Fatal("missing link sound") + } +} diff --git a/internal/app/echo_preferences_test.go b/internal/app/echo_preferences_test.go new file mode 100644 index 0000000..29ed2d1 --- /dev/null +++ b/internal/app/echo_preferences_test.go @@ -0,0 +1,258 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "path/filepath" + "reflect" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" +) + +func TestEveryEchoPreferenceRoundTrips(t *testing.T) { + settings := config.DefaultSettings() + if !settings.EnableKeyEcho { + t.Fatal("key echo must default on") + } + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + values := preferences.FromSettings(settings) + // Flip each echo switch, including false defaults, to exercise both directions. + value := reflect.ValueOf(&values).Elem() + for i := 0; i < value.NumField(); i++ { + if value.Field(i).Kind() == reflect.Bool { + value.Field(i).SetBool(!value.Field(i).Bool()) + } + } + rate, pitch, volume := 100.0, 10.0, 10.0 + values.EchoVoice = config.Voice{Rate: &rate, AveragePitch: &pitch, Gain: &volume, Family: &config.VoiceFamily{Name: "Test Voice", Lang: "en", Variant: "test"}} + values.EchoSpeechServer = "test-module" + next, err := values.Merge(settings) + if err != nil { + t.Fatal(err) + } + store, err := config.NewStore(settings.Path) + if err != nil { + t.Fatal(err) + } + if _, err = store.Load(); err != nil { + t.Fatal(err) + } + if err = store.Save(next); err != nil { + t.Fatal(err) + } + loaded, err := config.Load(settings.Path) + if err != nil { + t.Fatal(err) + } + if got := preferences.FromSettings(loaded); !reflect.DeepEqual(got, values) { + t.Fatalf("round trip = %+v; want %+v", got, values) + } +} + +func TestApplyUpdatesRunningTextAndKeyboardEcho(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableModifierKeys = false + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + live := &liveSettings{} + live.Store(settings) + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + worker.live = live + queue := &fakeSpeechQueue{spoken: make(chan string, 10), interrupt: make(chan struct{}, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 10)} + listener := &fakeInputListener{events: make(chan input.Event, 10), modifierKeycodes: input.NewModifierKeycodes(37)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}, 2) + go func() { + processEventsWithSettings(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, live) + done <- struct{}{} + }() + go func() { + processInputEvents(ctx, slog.New(slog.DiscardHandler), queue, listener, inputEchoSettingsFromConfig(settings), live, nil) + done <- struct{}{} + }() + defer func() { cancel(); <-done; <-done }() + expect := func(want string) { + t.Helper() + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("speech %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } + snapshot := atspi.NewSnapshot("/editor", "", "text", "", "") + snapshot.Editable = true + insert := func(text string) { + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, text) + } + insert("a") + expect("a") + listener.events <- input.NewKeyEvent(67, true, "F1") + expect("f1") + <-queue.interrupt + values := preferences.FromSettings(settings) + values.EnableKeyEcho = false + // Echo-only changes must work without a speech settings updater. + if r := worker.apply(ctx, preferences.Request{Values: values, Save: true}); !r.Accepted || r.Close { + t.Fatalf("Apply = %+v", r) + } + insert("b") + insert("barrier") + expect("barrier") + listener.events <- input.NewKeyEvent(68, true, "F2") + listener.events <- input.NewKeyEvent(37, true, "Control_L") + for range 2 { + select { + case <-queue.interrupt: + case <-time.After(time.Second): + t.Fatal("keyboard barrier missing") + } + } + values.EnableKeyEcho = true + if r := worker.apply(ctx, preferences.Request{Values: values, Save: true, Close: true}); !r.Accepted || !r.Close { + t.Fatalf("OK = %+v", r) + } + insert("c") + expect("c") + listener.events <- input.NewKeyEvent(69, true, "F3") + expect("f3") + loaded, err := config.Load(settings.Path) + if err != nil || !loaded.EnableKeyEcho { + t.Fatalf("saved state: %+v, %v", loaded, err) + } +} + +func TestCustomEchoVoiceInheritanceAndRouting(t *testing.T) { + settings := config.DefaultSettings() + settings.UseCustomEchoVoice = true + rate, pitch, volume := 65.0, 10.0, 10.0 + settings.DefaultVoice = config.Voice{Rate: &rate, Family: &config.VoiceFamily{Name: "base", Lang: "en"}} + settings.EchoVoice = config.Voice{AveragePitch: &pitch, Gain: &volume} + settings.UseCustomEchoSpeechServer = true + settings.EchoSpeechServer = "echo-module" + got := echoSpeechSettings(settings) + if *got.Rate != 32 || *got.Pitch != 90 || *got.Volume != 100 || got.OutputModule != "echo-module" || got.SynthesisVoice != "base" { + t.Fatalf("echo settings = %+v", got) + } + if !customEcho(settings, "key") || !customEcho(settings, "character") || customEcho(settings, "word") || customEcho(settings, "sentence") || customEcho(settings, "") { + t.Fatal("wrong default custom voice routing") + } + settings.UseCustomEchoForWord = true + settings.UseCustomEchoForSentence = true + if !customEcho(settings, "word") || !customEcho(settings, "sentence") { + t.Fatal("custom routing flags ignored") + } + settings.EnableKeyEcho = false + if customEcho(settings, "key") { + t.Fatal("custom echo survived master disable") + } +} + +func TestEditFieldsOnlyKeyNamesAndVoice(t *testing.T) { + for _, tc := range []struct { + name string + only, enabled, focused, known bool + want bool + }{ + {"all fields", false, true, false, false, true}, + {"disabled", true, false, true, true, false}, + {"editor", true, true, true, true, true}, + {"button", true, true, false, true, false}, + {"unknown", true, true, false, false, false}, + } { + t.Run(tc.name, func(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableKeyEcho = tc.enabled + settings.KeyEchoInEditFieldsOnly = tc.only + settings.UseCustomEchoVoice = true + settings.UseCustomEchoForKey = true + settings.UseCustomEchoForCharacter = false + live := &liveSettings{} + live.Store(settings) + if tc.known { + live.editFieldFocused = func() bool { return tc.focused } + } + listener := &fakeInputListener{events: make(chan input.Event, 1)} + listener.events <- input.NewKeyEvent(67, true, "F1") + close(listener.events) + speech := &remoteSpeechQueue{} + processInputEvents(context.Background(), slog.New(slog.DiscardHandler), speech, listener, inputEchoSettingsFromConfig(settings), live, nil) + if (len(speech.requests) != 0) != tc.want { + t.Fatalf("requests=%+v", speech.requests) + } + if tc.want && (speech.requests[0].Text != "f1" || !speech.requests[0].CustomEcho) { + t.Fatalf("key voice lost: %+v", speech.requests[0]) + } + }) + } +} + +func TestEditFieldsOnlyPreferencesApplyAndReload(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + live := &liveSettings{} + live.Store(settings) + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + worker.live = live + values := preferences.FromSettings(settings) + values.KeyEchoInEditFieldsOnly = true + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted { + t.Fatalf("Apply: %+v", response) + } + loaded, err := config.Load(settings.Path) + if err != nil || !loaded.EnableKeyEcho || !loaded.KeyEchoInEditFieldsOnly { + t.Fatalf("reload: %+v, %v", loaded, err) + } + if !live.Load().KeyEchoInEditFieldsOnly || !presentationSettingsFromConfig(live.Load(), false).KeyEchoInEditFieldsOnly { + t.Fatal("Apply did not reach typing policy") + } + values.KeyEchoInEditFieldsOnly = false + response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || live.Load().KeyEchoInEditFieldsOnly { + t.Fatal("could not return to unrestricted echo") + } +} + +func TestEditFieldsOnlyNativeTypingVoice(t *testing.T) { + settings := config.DefaultSettings() + settings.KeyEchoInEditFieldsOnly = true + settings.UseCustomEchoVoice = true + settings.UseCustomEchoForKey = true + settings.UseCustomEchoForCharacter = false + live := &liveSettings{} + live.Store(settings) + queue := &remoteSpeechQueue{} + state := &eventLoopState{} + state.presentationOptions = presentationSettingsFromConfig(settings, false) + presenter := eventPresenter{state: state, live: live, speech: queue, logger: slog.New(slog.DiscardHandler)} + source := atspi.Snapshot{Role: "text", Editable: true, Focused: true} + presenter.speak(atspi.Event{Type: atspi.TextInsertedEvent, Source: source, Payload: "A"}) + if len(queue.requests) != 1 || !queue.requests[0].CustomEcho || !queue.requests[0].Character { + t.Fatalf("typed key voice: %+v", queue.requests) + } + source.Role = "terminal" + source.Editable = false + presenter.speak(atspi.Event{Type: atspi.TextInsertedEvent, Source: source, Payload: "b"}) + if len(queue.requests) != 1 { + t.Fatal("terminal echoed typed key") + } + source.Role = "section" + source.LiveRegion = true + source.LivePoliteness = "polite" + presenter.speak(atspi.Event{Type: atspi.TextInsertedEvent, Source: source, Payload: "c"}) + if len(queue.requests) != 2 || queue.requests[1].Text != "c" || queue.requests[1].CustomEcho { + t.Fatalf("live region changed: %+v", queue.requests) + } +} diff --git a/internal/app/echo_speaker.go b/internal/app/echo_speaker.go new file mode 100644 index 0000000..0cf8b7d --- /dev/null +++ b/internal/app/echo_speaker.go @@ -0,0 +1,250 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "reflect" + "sync" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +// echoSpeaker prepares all voices before publishing any. Speech and +// cancellation remain available while a preferences change is prepared. +type echoSpeaker struct { + socket string + initial config.Settings + mu sync.RWMutex + update sync.Mutex + voices map[string]*speech.Client + closed bool +} + +func newEchoSpeaker(socket string, settings config.Settings) *echoSpeaker { + return &echoSpeaker{socket: socket, initial: settings} +} +func (speaker *echoSpeaker) Connect(ctx context.Context) error { + return speaker.UpdateConfiguration(ctx, speaker.initial) +} +func (speaker *echoSpeaker) UpdateConfiguration(ctx context.Context, settings config.Settings) error { + if !speaker.update.TryLock() { + return errors.New("speech settings update already in progress") + } + defer speaker.update.Unlock() + candidates := make(map[string]*speech.Client) + closeClients := func(clients map[string]*speech.Client) error { + var result error + for _, client := range clients { + result = errors.Join(result, client.Close(context.Background())) + } + return result + } + voiceSettings := map[string]speech.Settings{"default": speechSettingsFromConfig(settings)} + for _, kind := range []string{"uppercase", "hyperlink", "system"} { + if kind == "hyperlink" && reflect.DeepEqual(settings.HyperlinkVoice, config.Voice{}) || kind == "system" && reflect.DeepEqual(settings.SystemVoice, config.Voice{}) { + continue + } + candidate := settings + candidate.DefaultVoice = config.EffectiveVoice(settings, kind) + voiceSettings[kind] = speechSettingsFromConfig(candidate) + } + if settings.UseCustomEchoVoice { + voiceSettings["echo"] = echoSpeechSettings(settings) + echoSettings := settings + echoSettings.DefaultVoice = config.EffectiveVoice(settings, "default") + merge_echo_voice(&echoSettings.DefaultVoice, settings.EchoVoice) + echoSettings.DefaultVoice = config.EffectiveVoice(echoSettings, "uppercase") + if settings.UseCustomEchoSpeechServer { + echoSettings.SpeechOutputModule = settings.EchoSpeechServer + } + // Echo endpoints allow 100/10/10; use the existing clamping mapper. + echoSettings.EchoVoice = echoSettings.DefaultVoice + voiceSettings["uppercase-echo"] = echoSpeechSettings(echoSettings) + } + for _, kind := range []string{"default", "echo", "uppercase", "uppercase-echo", "hyperlink", "system"} { + values, exists := voiceSettings[kind] + if !exists { + continue + } + client := speech.NewWithSettings(speaker.socket, values) + candidates[kind] = client + if err := client.Connect(ctx); err != nil { + closeClients(candidates) + return err + } + } + speaker.mu.Lock() + defer speaker.mu.Unlock() + if speaker.closed { + closeClients(candidates) + return errors.New("speech is closed") + } + if err := ctx.Err(); err != nil { + closeClients(candidates) + return err + } + for _, client := range speaker.voices { + if err := client.Cancel(ctx); err != nil { + closeClients(candidates) + return err + } + } + retired := speaker.voices + speaker.voices = candidates + _ = closeClients(retired) + return nil +} +func (speaker *echoSpeaker) client(kind string) *speech.Client { + if client := speaker.voices[kind]; client != nil { + return client + } + return speaker.voices["default"] +} +func (speaker *echoSpeaker) Speak(ctx context.Context, text string) error { + return speaker.SpeakVoice(ctx, text, "default") +} +func (speaker *echoSpeaker) SpeakVoice(ctx context.Context, text, kind string) error { + speaker.mu.RLock() + defer speaker.mu.RUnlock() + client := speaker.client(kind) + if client == nil { + return errors.New("speech is not connected") + } + return client.Speak(ctx, text) +} +func (speaker *echoSpeaker) SpeakCharacter(ctx context.Context, text string) error { + return speaker.speak_character(ctx, text, false) +} +func (speaker *echoSpeaker) SpeakEchoCharacter(ctx context.Context, text string) error { + return speaker.speak_character(ctx, text, true) +} +func (speaker *echoSpeaker) speak_character(ctx context.Context, text string, custom bool) error { + speaker.mu.RLock() + defer speaker.mu.RUnlock() + kind := "default" + if custom { + kind = "echo" + } + r, size := utf8.DecodeRuneInString(text) + if size == len(text) && unicode.IsUpper(r) { + kind = "uppercase" + if custom && speaker.voices["uppercase-echo"] != nil { + kind = "uppercase-echo" + } + } + client := speaker.client(kind) + if client == nil { + return errors.New("speech is not connected") + } + return client.SpeakCharacter(ctx, text) +} +func (speaker *echoSpeaker) SpeakEcho(ctx context.Context, text string) error { + return speaker.SpeakVoice(ctx, text, "echo") +} +func (speaker *echoSpeaker) SpeakAndWait(ctx context.Context, text string, began func()) error { + return speaker.SpeakVoiceAndWait(ctx, text, "default", began) +} + +func (speaker *echoSpeaker) speak_uninterruptible(ctx context.Context, text string) error { + return speaker.SpeakVoiceAndWait(ctx, text, "system", nil) +} + +func (speaker *echoSpeaker) SpeakVoiceAndWait(ctx context.Context, text, kind string, began func()) error { + speaker.mu.RLock() + client := speaker.client(kind) + speaker.mu.RUnlock() + if client == nil { + return errors.New("speech is not connected") + } + return client.SpeakAndWait(ctx, text, began) +} +func (speaker *echoSpeaker) Cancel(ctx context.Context) error { + speaker.mu.RLock() + defer speaker.mu.RUnlock() + var result error + for _, client := range speaker.voices { + result = errors.Join(result, client.Cancel(ctx)) + } + return result +} +func (speaker *echoSpeaker) Close(ctx context.Context) error { + speaker.update.Lock() + defer speaker.update.Unlock() + speaker.mu.Lock() + defer speaker.mu.Unlock() + speaker.closed = true + var result error + for _, client := range speaker.voices { + result = errors.Join(result, client.Close(ctx)) + } + speaker.voices = nil + return result +} +func merge_echo_voice(voice *config.Voice, echo config.Voice) { + if echo.Rate != nil { + voice.Rate = echo.Rate + } + if echo.AveragePitch != nil { + voice.AveragePitch = echo.AveragePitch + } + if echo.Gain != nil { + voice.Gain = echo.Gain + } + if echo.Family != nil { + voice.Family = echo.Family + } +} +func echoSpeechSettings(settings config.Settings) speech.Settings { + voice := settings.DefaultVoice + if v := settings.EchoVoice.Rate; v != nil { + voice.Rate = v + } + if v := settings.EchoVoice.AveragePitch; v != nil { + voice.AveragePitch = v + } + if v := settings.EchoVoice.Gain; v != nil { + voice.Gain = v + } + if v := settings.EchoVoice.Family; v != nil { + voice.Family = v + } + // Cthulhu accepts UI endpoints 100/10/10 and clamps for SSIP. + for _, field := range []struct { + value **float64 + max float64 + }{{&voice.Rate, 99}, {&voice.AveragePitch, 9}, {&voice.Gain, 9}} { + if *field.value != nil { + value := min(**field.value, field.max) + *field.value = &value + } + } + settings.DefaultVoice = voice + result := speechSettingsFromConfig(settings) + if settings.UseCustomEchoSpeechServer { + result.OutputModule = settings.EchoSpeechServer + } + return result +} +func customEcho(settings config.Settings, kind string) bool { + if !settings.EnableKeyEcho || !settings.UseCustomEchoVoice { + return false + } + switch kind { + case "key": + return settings.UseCustomEchoForKey + case "character": + return settings.UseCustomEchoForCharacter + case "word": + return settings.UseCustomEchoForWord + case "sentence": + return settings.UseCustomEchoForSentence + } + return false +} diff --git a/internal/app/echo_speaker_test.go b/internal/app/echo_speaker_test.go new file mode 100644 index 0000000..1dbf3ad --- /dev/null +++ b/internal/app/echo_speaker_test.go @@ -0,0 +1,601 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "context" + "fmt" + "log/slog" + "net" + "path/filepath" + "strings" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/remote" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +func TestEchoSpeakerSwitchesBothVoicesTransactionally(t *testing.T) { + for _, wrapped := range []bool{false, true} { + t.Run(fmt.Sprintf("configured=%v", wrapped), func(t *testing.T) { test_echo_speaker(t, wrapped) }) + } +} + +func test_echo_speaker(t *testing.T, wrapped bool) { + path := filepath.Join(t.TempDir(), "speech.sock") + listener, err := net.Listen("unix", path) + if err != nil { + t.Fatal(err) + } + type utterance struct { + module, text string + rate, pitch string + volume, voice string + } + spoken := make(chan utterance, 10) + var handlers sync.WaitGroup + acceptDone := make(chan struct{}) + go func() { + defer close(acceptDone) + for id := 1; ; id++ { + conn, err := listener.Accept() + if err != nil { + return + } + handlers.Add(1) + go func(id int) { + defer handlers.Done() + defer conn.Close() + reader := bufio.NewReader(conn) + module, rate, pitch := "", "", "" + volume, voice := "", "" + notifications := false + for { + line, err := reader.ReadString('\n') + if err != nil { + return + } + command := strings.TrimSpace(line) + response := "200 OK\r\n" + if command == "SET SELF NOTIFICATION ALL on" { + notifications = true + } else if command == "SET SELF NOTIFICATION ALL off" { + notifications = false + } + if strings.HasPrefix(command, "SET SELF OUTPUT_MODULE ") { + module = strings.TrimPrefix(command, "SET SELF OUTPUT_MODULE ") + } + if strings.HasPrefix(command, "SET SELF RATE ") { + rate = strings.TrimPrefix(command, "SET SELF RATE ") + } + if strings.HasPrefix(command, "SET SELF PITCH ") { + pitch = strings.TrimPrefix(command, "SET SELF PITCH ") + } + if strings.HasPrefix(command, "SET SELF VOLUME ") { + volume = strings.TrimPrefix(command, "SET SELF VOLUME ") + } + if strings.HasPrefix(command, "SET SELF SYNTHESIS_VOICE ") { + voice = strings.TrimPrefix(command, "SET SELF SYNTHESIS_VOICE ") + } + if command == "SET SELF OUTPUT_MODULE rejected" { + response = "400 Module unavailable\r\n" + } + if command == "HISTORY GET CLIENT_ID" { + response = fmt.Sprintf("245-%d\r\n245 OK\r\n", id) + } + if strings.HasPrefix(command, "CHAR ") { + spoken <- utterance{module, strings.TrimPrefix(command, "CHAR "), rate, pitch, volume, voice} + } + if command == "SPEAK" { + var text strings.Builder + for { + part, err := reader.ReadString('\n') + if err != nil { + return + } + if part == ".\r\n" { + break + } + text.WriteString(strings.TrimSuffix(part, "\r\n")) + } + spoken <- utterance{module, text.String(), rate, pitch, volume, voice} + response = "230 OK\r\n200 QUEUED\r\n" + if notifications { + response += fmt.Sprintf("701-1\r\n701-%d\r\n701 BEGIN\r\n702-1\r\n702-%d\r\n702 END\r\n", id, id) + } + } + if _, err := conn.Write([]byte(response)); err != nil { + return + } + } + }(id) + } + }() + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + settings := config.DefaultSettings() + settings.UseCustomEchoVoice = true + settings.UseCustomEchoSpeechServer = true + settings.EchoSpeechServer = "echo-module" + rate := 80.0 + settings.EchoVoice.Rate = &rate + var speaker interface { + configuredVoice + UpdateConfiguration(context.Context, config.Settings) error + } = newEchoSpeaker(path, settings) + if wrapped { + speaker = newConfiguredSpeaker(path, settings) + } + defer func() { speaker.Close(ctx); listener.Close(); <-acceptDone; handlers.Wait() }() + if err := speaker.Connect(ctx); err != nil { + t.Fatal(err) + } + check := func(custom bool, wantModule, wantRate string) { + t.Helper() + var err error + if custom { + err = speaker.SpeakEcho(ctx, "test") + } else { + err = speaker.Speak(ctx, "test") + } + if err != nil { + t.Fatal(err) + } + select { + case got := <-spoken: + if got.module != wantModule || got.rate != wantRate { + t.Fatalf("utterance=%+v, want module %q rate %q", got, wantModule, wantRate) + } + case <-ctx.Done(): + t.Fatal("speech missing") + } + } + check(false, "", "") + check(true, "echo-module", "62") + if wrapped { + // Exercise the new request path through the actual configured backend + // and private SSIP connections, including a failure in the echo client + // after preparation of the new main client has already succeeded. + readerWorker, session, _ := reader_extension_fixture(t, "normal") + base := settings + base.Path = readerWorker.settings.Path + readerWorker.settings, readerWorker.globalSettings = base, base + readerWorker.updater = speaker + readerWorker.live.Store(base) + configuration := tentaclewire.SpeechFromSettings(base) + configuration.Module = "tentacle-module" + profileRate := 65.0 + configuration.DefaultVoice.Rate = &profileRate + if _, err := readerWorker.apply_reader_request(ctx, session, tentaclewire.ReaderRequest{Speech: &configuration}, false); err != nil { + t.Fatal(err) + } + check(false, "tentacle-module", "32") + check(true, "echo-module", "62") + configuration.Module, configuration.EchoServer = "candidate-module", "rejected" + if _, err := readerWorker.apply_reader_request(ctx, session, tentaclewire.ReaderRequest{Speech: &configuration}, false); err == nil { + t.Fatal("failed echo client accepted through reader API") + } + check(false, "tentacle-module", "32") + check(true, "echo-module", "62") + if _, err := readerWorker.apply_reader_request(ctx, session, tentaclewire.ReaderRequest{RestoreSpeech: true}, false); err != nil { + t.Fatal(err) + } + check(false, "", "") + check(true, "echo-module", "62") + } + // Key names use completion notifications on the selected voice's real + // SSIP connection, so following navigation cannot cancel an active echo. + keySpeech := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + for _, custom := range []bool{false, true} { + if err := keySpeech.deliver(ctx, speechRequest{Text: "right", Role: "key", Cause: "key-echo", CustomEcho: custom}); err != nil { + t.Fatal(err) + } + got := <-spoken + wantModule, wantRate := "", "" + if custom { + wantModule, wantRate = "echo-module", "62" + } + if got.text != "right" || got.module != wantModule || got.rate != wantRate { + t.Fatalf("key echo custom=%v: %+v", custom, got) + } + } + // Preview unsaved echo selections through the real SSIP clients. Only the + // numeric request uses that endpoint; subsequent dialog speech stays main. + previewWorker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, speaker) + previewValues := preferences.FromSettings(settings) + previewRate, previewPitch, previewVolume := 70.0, 6.0, 10.0 + previewValues.EchoSpeechServer = "preview-module" + previewValues.EchoVoice = config.Voice{Rate: &previewRate, AveragePitch: &previewPitch, Gain: &previewVolume, + Family: &config.VoiceFamily{Name: "Preview voice", Lang: "en"}} + previewSpeech := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + previewWorker.announceEchoPreview = func(label, value string) { + if err := previewSpeech.deliver(ctx, echo_preview_speech(label, value)); err != nil { + t.Fatal(err) + } + } + for _, test := range []struct{ slider, text string }{{"rate", "70.0"}, {"pitch", "6.0"}, {"volume", "10.0"}, {"synthesizer", "preview-module"}, {"person", "Preview voice (en)"}} { + if response := previewWorker.preview(ctx, preferences.Request{Values: previewValues, Preview: true, EchoPreview: test.slider, EchoPreviewFocus: true}); !response.Accepted { + t.Fatalf("echo preview rejected: %+v", response) + } + select { + case got := <-spoken: + if !strings.HasPrefix(got.text, "Key echo ") || got.module != "" || got.voice != "" { + t.Fatalf("echo focus label did not use the normal voice: %+v", got) + } + case <-ctx.Done(): + t.Fatal("echo focus label missing") + } + select { + case got := <-spoken: + if got.text != test.text || got.module != "preview-module" || got.voice != "Preview voice" || + got.rate != "42" || got.pitch != "30" || got.volume != "100" { + t.Fatalf("echo slider SSIP request = %+v", got) + } + case <-ctx.Done(): + t.Fatal("echo slider SSIP request missing") + } + check(false, "", "") + } + if response := previewWorker.restorePreview(ctx); !response.Accepted { + t.Fatalf("restore echo preview: %+v", response) + } + check(true, "echo-module", "62") + checkCharacters := func(wantNormal string) { + t.Helper() + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + for _, tc := range []struct { + text string + character bool + pitch string + }{ + {"A", true, "50"}, {"a", true, wantNormal}, {"É", true, "50"}, + {"o", true, wantNormal}, {"o", true, wantNormal}, + {"猫", true, wantNormal}, {"7", true, wantNormal}, {"space", true, wantNormal}, + {"ABC", false, wantNormal}, {"A", false, wantNormal}, + } { + if err := worker.deliver(ctx, speechRequest{Text: tc.text, Character: tc.character}); err != nil { + t.Fatal(err) + } + select { + case got := <-spoken: + if got.pitch != tc.pitch || got.text != tc.text || got.module != "" { + t.Fatalf("character %v: got %+v, want text %q pitch %q", tc.character, got, tc.text, tc.pitch) + } + case <-ctx.Done(): + t.Fatal("character speech missing") + } + } + } + checkCharacters("") + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + // Exercise deletion from event presentation through the real SSIP client, + // checking both uppercase pitch and restoration on the following letter. + for _, custom := range []bool{false, true} { + deletionSettings := settings + deletionSettings.UseCustomEchoVoice = custom + live := &liveSettings{} + live.Store(deletionSettings) + queue := &fakeSpeechQueue{spoken: make(chan string, 1), requests: make(chan speechRequest, 1)} + presenter := eventPresenter{state: &eventLoopState{}, logger: slog.New(slog.DiscardHandler), speech: queue, live: live} + for _, text := range []string{"A", "a", "É", "é"} { + snapshot := atspi.Snapshot{BusName: ":1.42", Path: "/editor", Role: "entry", Editable: true} + presenter.speak(atspi.NewEventWithPayload(atspi.TextDeletedEvent, snapshot, text)) + request := <-queue.requests + <-queue.spoken + if err := worker.deliver(ctx, request); err != nil { + t.Fatal(err) + } + got := <-spoken + wantPitch, wantModule, wantRate := "", "", "" + if text == "A" || text == "É" { + wantPitch = "50" + } + if custom { + wantModule, wantRate = "echo-module", "62" + } + if got.text != text || got.pitch != wantPitch || got.module != wantModule || got.rate != wantRate { + t.Fatalf("deleted %q, custom=%v: %+v", text, custom, got) + } + } + } + // Wine insertion must use the same character voice as native typing. + for _, custom := range []bool{false, true} { + wineSettings := settings + wineSettings.UseCustomEchoVoice = custom + live := &liveSettings{} + live.Store(wineSettings) + queue := &remoteSpeechQueue{} + braille := &remoteBrailleQueue{running: true} + presenter := remoteSpeech{speech: queue, braille: braille, live: live} + owner := newWineEventPresenter(func(message string) bool { + return presenter.presentMessage(message, "wine-accessible-event") + }) + presenter.wine = owner + presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "42:text", EventType: "focus", Role: "edit"}) + owner.flush() + queue.requests, braille.text = nil, nil + for _, text := range []string{"A", "a", "É", "é", "é", "𐐀", "𐐨", "😀", "space", "new line"} { + if !presenter.PresentAccessibleEvent(remote.AccessibleEvent{ + SourceID: "42:text", EventType: "text", Name: text, States: "start=1 end=1 kind=8", + }) { + t.Fatalf("Wine insertion %q rejected", text) + } + request := queue.requests[len(queue.requests)-1] + if err := worker.deliver(ctx, request); err != nil { + t.Fatal(err) + } + got := <-spoken + wantPitch, wantModule, wantRate := "", "", "" + if text == "A" || text == "É" || text == "𐐀" { + wantPitch = "50" + } + if custom { + wantModule, wantRate = "echo-module", "62" + } + if got.text != text || got.pitch != wantPitch || got.module != wantModule || got.rate != wantRate { + t.Fatalf("Wine insertion %q, custom=%v: %+v; want pitch %q module %q rate %q", text, custom, got, wantPitch, wantModule, wantRate) + } + if braille.text[len(braille.text)-1] != text { + t.Fatalf("Wine braille changed character case: %v", braille.text) + } + } + owner.Close() + } + for _, text := range []string{"A", "a", "É"} { + if err := worker.deliver(ctx, speechRequest{Text: text, Character: true, CustomEcho: true}); err != nil { + t.Fatal(err) + } + got := <-spoken + wantPitch := "50" + if text == "a" { + wantPitch = "" + } + if got.module != "echo-module" || got.rate != "62" || got.pitch != wantPitch { + t.Fatalf("custom character echo = %+v; want pitch %s", got, wantPitch) + } + } + + capitalPreferences := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, speaker) + capitalLive := &liveSettings{} + capitalLive.Store(settings) + capitalPreferences.live = capitalLive + for mask := 0; mask < 8; mask++ { + choices := settings + echoPitch := 6.0 + choices.EchoVoice.AveragePitch = &echoPitch + choices.RaisePitchForCapitals = mask&1 != 0 + choices.BeepForCapitals = mask&2 != 0 + choices.SayCapForCapitals = mask&4 != 0 + if response := capitalPreferences.apply(ctx, preferences.Request{Values: preferences.FromSettings(choices)}); !response.Accepted { + t.Fatalf("capital choices Apply failed: %+v", response) + } + capitals := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + capitals.capitalization = func() (bool, bool) { + current := capitalLive.Load() + return current.BeepForCapitals, current.SayCapForCapitals + } + beeps := 0 + capitals.capitalBeep = func(context.Context) error { beeps++; return nil } + for _, custom := range []bool{false, true} { + for _, tc := range []struct { + text, cause, voice string + character, capital bool + }{ + {"A", "character-echo", "", true, true}, + {"É", "document-caret-character", "", true, true}, + {"𐐀", "flat-review", "", true, true}, + {"A", "key-echo", "", true, true}, + {"a", "character-echo", "", true, false}, + {"ABC", "word-echo", "", false, false}, + {"A", "focus", "", false, false}, + } { + before := beeps + request := speechRequest{Text: tc.text, Cause: tc.cause, VoiceType: tc.voice, Character: tc.character, CustomEcho: custom} + if err := capitals.deliver(ctx, request); err != nil { + t.Fatal(err) + } + wantPitch, wantModule := "", "" + if custom { + wantPitch, wantModule = "30", "echo-module" + } + if tc.capital && choices.RaisePitchForCapitals { + wantPitch = "50" + if custom { + wantPitch = "70" + } + } + if tc.capital && choices.SayCapForCapitals { + got := <-spoken + if got.text != "cap" || got.pitch != wantPitch || got.module != wantModule { + t.Fatalf("mask %d cap prefix: %+v", mask, got) + } + } + got := <-spoken + if got.text != tc.text || got.pitch != wantPitch || got.module != wantModule { + t.Fatalf("mask %d custom=%v request=%+v: %+v", mask, custom, request, got) + } + wantBeeps := 0 + if tc.capital && choices.BeepForCapitals { + wantBeeps = 1 + } + if beeps-before != wantBeeps { + t.Fatalf("mask %d beeps=%d", mask, beeps-before) + } + } + } + // Phonetic spelling carries uppercase metadata despite lowercase words. + for _, character := range []bool{false, true} { + text := "alpha" + if character { + text = "A" + } + request := speechRequest{Spelling: []string{text, "b"}, SpellingVoices: []string{"uppercase", ""}, Character: character} + before := beeps + if err := capitals.deliver(ctx, request); err != nil { + t.Fatal(err) + } + if choices.SayCapForCapitals { + if got := <-spoken; got.text != "cap" { + t.Fatalf("spelled prefix: %+v", got) + } + } + if got := <-spoken; got.text != text { + t.Fatalf("spelled capital: %+v", got) + } + if got := <-spoken; got.text != "b" || got.pitch != "" { + t.Fatalf("spelled lowercase: %+v", got) + } + wantBeeps := 0 + if choices.BeepForCapitals { + wantBeeps = 1 + } + if beeps-before != wantBeeps { + t.Fatal("spelling beep count") + } + } + // Delayed arrow hints must not repeat any capital cues. Exercise all + // capital combinations through SSIP, including a specialized source role. + capitals.reading = func() config.ReadingSettings { + return config.ReadingSettings{PhoneticCharacterHints: true} + } + capitals.inputActivity = func() input.Activity { + return input.Activity{PlainCharacterArrow: true, InputSequence: 1} + } + before := beeps + if err := capitals.deliver(ctx, speechRequest{Text: "T", Role: "system", Character: true, PhoneticHint: true}); err != nil { + t.Fatal(err) + } + wantPitch := "" + if choices.RaisePitchForCapitals { + wantPitch = "50" + } + if choices.SayCapForCapitals { + if got := <-spoken; got.text != "cap" || got.pitch != wantPitch { + t.Fatalf("mask %d initial character cap prefix: %+v", mask, got) + } + } + if got := <-spoken; got.text != "T" || got.pitch != wantPitch { + t.Fatalf("mask %d initial character: %+v", mask, got) + } + if got := <-spoken; got.text != "tango" || got.pitch != "" || got.module != "" { + t.Fatalf("mask %d delayed hint repeated capital or specialized voice: %+v", mask, got) + } + wantBeeps := 0 + if choices.BeepForCapitals { + wantBeeps = 1 + } + if beeps-before != wantBeeps { + t.Fatalf("mask %d delayed hint repeated capital beep: %d", mask, beeps-before) + } + } + if err := speaker.UpdateConfiguration(ctx, settings); err != nil { + t.Fatal(err) + } + upperPitch, linkPitch, systemPitch := 8.0, 1.0, 2.0 + settings.UppercaseVoice.AveragePitch = &upperPitch + settings.HyperlinkVoice.AveragePitch = &linkPitch + settings.SystemVoice.AveragePitch = &systemPitch + if err := speaker.UpdateConfiguration(ctx, settings); err != nil { + t.Fatal(err) + } + for _, tc := range []struct { + request speechRequest + pitch string + }{ + {speechRequest{Text: "A", Character: true}, "70"}, + {speechRequest{Text: "A", Character: true, CustomEcho: true}, "70"}, + {speechRequest{Text: "link text", Role: "link"}, "-70"}, + {speechRequest{Text: "status text", Role: "system"}, "-50"}, + {speechRequest{Text: "ordinary text"}, ""}, + {speechRequest{Spelling: []string{"alpha", "bravo"}, SpellingVoices: []string{"uppercase", ""}}, "70"}, + } { + if err := worker.deliver(ctx, tc.request); err != nil { + t.Fatal(err) + } + got := <-spoken + if got.pitch != tc.pitch { + t.Fatalf("voice selection for %+v = %+v", tc.request, got) + } + if len(tc.request.Spelling) != 0 { + if got := <-spoken; got.pitch != "" { + t.Fatalf("uppercase spelling pitch leaked: %+v", got) + } + } + } + // Verify real SSIP SPEAK requests from focus presentation, including source + // punctuation, the selected special voice, and disabling pause chunks. + for _, enabled := range []bool{true, false} { + pauseSettings := settings + pauseSettings.Reading.EnablePauseBreaks = enabled + pauseSettings.EnableSound = false + live := &liveSettings{} + live.Store(pauseSettings) + queue := &fakeSpeechQueue{spoken: make(chan string, 1), requests: make(chan speechRequest, 1)} + presenter := eventPresenter{state: &eventLoopState{}, logger: slog.New(slog.DiscardHandler), speech: queue, live: live} + presenter.speak(atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{Name: "Read, draft. Next!", Role: "link", Description: "Open document"})) + if err := worker.deliver(ctx, <-queue.requests); err != nil { + t.Fatal(err) + } + want := []string{"Read, draft. Next!", "link", "Open document"} + if !enabled { + want = []string{"Read, draft. Next! link Open document"} + } + for _, text := range want { + select { + case got := <-spoken: + if got.text != text || got.pitch != "-70" || got.module != "" { + t.Fatalf("pause chunks enabled=%v: SSIP utterance=%+v, want text %q with hyperlink pitch", enabled, got, text) + } + case <-ctx.Done(): + t.Fatal("pause chunk SSIP request missing") + } + } + if len(spoken) != 0 { + t.Fatal("unexpected extra SSIP request") + } + } + settings.UppercaseVoice, settings.HyperlinkVoice, settings.SystemVoice = config.Voice{}, config.Voice{}, config.Voice{} + if err := speaker.UpdateConfiguration(ctx, settings); err != nil { + t.Fatal(err) + } + settings.EchoSpeechServer = "rejected" + if err := speaker.UpdateConfiguration(ctx, settings); err == nil { + t.Fatal("invalid module accepted") + } + check(false, "", "") + check(true, "echo-module", "62") + settings.UseCustomEchoVoice = false + if err := speaker.UpdateConfiguration(ctx, settings); err != nil { + t.Fatal(err) + } + check(true, "", "") + pitch := 3.0 + settings.DefaultVoice.AveragePitch = &pitch + if err := speaker.UpdateConfiguration(ctx, settings); err != nil { + t.Fatal(err) + } + checkCharacters("-30") + if wrapped { + test_hardware_switch(t, speaker.(*configuredSpeaker), settings) + check(false, "", "") + checkCharacters("-30") + } + if err := speaker.Cancel(ctx); err != nil { + t.Fatal(err) + } + if err := speaker.Close(ctx); err != nil { + t.Fatal(err) + } + if err := speaker.UpdateConfiguration(ctx, settings); err == nil { + t.Fatal("closed speaker revived") + } +} diff --git a/internal/app/editable_document_test.go b/internal/app/editable_document_test.go new file mode 100644 index 0000000..dc9309d --- /dev/null +++ b/internal/app/editable_document_test.go @@ -0,0 +1,137 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +func TestEditorParagraphUsesConfiguredEcho(t *testing.T) { + for _, echo := range []string{"disabled", "character", "word", "sentence"} { + t.Run(echo, func(t *testing.T) { + options := presentation.DefaultOptions() + payload, contextText, want := "o", "Hello", "o" + switch echo { + case "disabled": + options.EnableKeyEcho, want = false, "" + case "character": + options.EnableEchoByCharacter = true + case "word": + options.EnableEchoByWord = true + payload, contextText, want = " ", "Hello ", "Hello" + case "sentence": + options.EnableEchoBySentence = true + payload, contextText, want = " ", "Hello. ", "Hello." + } + queue := &fakeSpeechQueue{spoken: make(chan string, 16)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 16)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEvents(ctx, slog.New(slog.DiscardHandler), queue, adapter, 0, options) + }() + defer func() { cancel(); <-done }() + editor := atspi.Snapshot{BusName: ":1.7", Path: "/editor", Name: "Composer", Role: "entry", Editable: true} + paragraph := atspi.Snapshot{BusName: editor.BusName, Path: "/paragraph", Role: "paragraph", Editable: true, + EditableRoot: editor.ID(), Text: contextText, TextBeforeCaret: contextText} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, editor) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, paragraph, payload) + adapter.events <- atspi.NewEvent(atspi.CaretEvent, paragraph) + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: editor.BusName, Path: "/next", Role: "button", Name: "Next"}) + // Once focus leaves, delayed events from that editor stay quiet. + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, paragraph, "delayed edit") + adapter.events <- atspi.NewEvent(atspi.CaretEvent, paragraph) + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: editor.BusName, Path: "/end", Role: "button", Name: "End"}) + wants := []string{"Composer, entry"} + if want != "" { + wants = append(wants, want) + } + wants = append(wants, "Next, button", "End, button") + for _, want := range wants { + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } + }) + } +} + +func TestEditableDocumentParagraphEvents(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 16)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 16)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + editor := atspi.Snapshot{BusName: ":1.7", Path: "/editor", Name: "Message body", Role: "document web", Editable: true} + paragraph := atspi.Snapshot{BusName: editor.BusName, Path: "/paragraph", Role: "paragraph", Editable: true, + EditableRoot: editor.ID(), Text: "a", TextCaretKnown: true, BrailleLine: "a", BrailleCaret: 1} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, editor) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, paragraph, "a") + // This caret must not reread the growing line after accepted typing. + adapter.events <- atspi.NewEvent(atspi.CaretEvent, paragraph) + paragraph.SelectionStart, paragraph.SelectionEnd, paragraph.SelectionText = 0, 1, "a" + adapter.events <- atspi.NewEvent(atspi.TextSelectionChangedEvent, paragraph) + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, paragraph, "a") + subject := atspi.Snapshot{BusName: editor.BusName, Path: "/subject", Name: "Subject", Role: "entry", Editable: true} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, subject) + // A delayed mutation from the old body cannot interrupt a header field. + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, paragraph, "unfocused text") + other := paragraph + other.Path, other.EditableRoot = "/other_paragraph", atspi.NewObjectID(editor.BusName, "/other_editor") + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, other, "other editor") + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: editor.BusName, Path: "/end", Role: "button", Name: "End"}) + for _, want := range []string{"Message body, document web", "a", "a selected", "a", "Subject, entry", "End, button"} { + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } +} + +func TestEditableDocumentCaretAndSelectionBraille(t *testing.T) { + root := atspi.NewObjectID(":1.7", "/editor") + frames := make(chan braille.Frame, 2) + state := &eventLoopState{} + state.focusedID = root + handler := accessibilityEventHandler{state: state, logger: slog.New(slog.DiscardHandler), brailleOutput: frameRecorder{frames: frames}} + source := atspi.Snapshot{BusName: root.BusName, Path: "/paragraph", Role: "paragraph", Editable: true, + EditableRoot: root, Text: "body", TextCaretKnown: true, BrailleLine: "body", BrailleCaret: 2} + for _, eventType := range []string{atspi.CaretEvent, atspi.TextSelectionChangedEvent} { + handler.acceptFocusedEvent(atspi.NewEvent(eventType, source), recentInput(nil)) + if state.focusedID != root || state.current.ID() != source.ID() || state.brailleSnapshot.ID() != source.ID() { + t.Fatal("paragraph presentation lost native editor focus or Braille ownership") + } + select { + case frame := <-frames: + if !strings.HasPrefix(frame.Text, "body") || frame.Cursor != 2 || len(frame.Routes) == 0 || frame.Routes[0].Path != source.Path { + t.Fatalf("paragraph Braille frame = %+v", frame) + } + default: + t.Fatal("missing paragraph Braille frame") + } + } +} diff --git a/internal/app/event_accessibility.go b/internal/app/event_accessibility.go new file mode 100644 index 0000000..ee5811e --- /dev/null +++ b/internal/app/event_accessibility.go @@ -0,0 +1,312 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/notification" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// accessibilityEventHandler handles native events on the event-loop goroutine. +// A return drops or consumes this event; the select loop then receives the next. +type accessibilityEventHandler struct { + state *eventLoopState + titles *windowTitleController + logger *slog.Logger + speech speechEnqueuer + adapter Adapter + objectReview *review.Worker + browser *browserModeController + inputSource any + focusGate *focusGate + notifications *notification.Presenter + live *liveSettings + brailleOutput brailleFrameEnqueuer + foreground foregroundMonitor + debounce time.Duration + clearOwnedFocus func() + syncForeground func() + flushTerminalDeletion func() + speak func(atspi.Event, ...input.Intent) + webScripts *webScriptController + wineReview *wineReviewFocusController +} + +func (handler *accessibilityEventHandler) handle(event atspi.Event) { + state := handler.state + logger := handler.logger + speech := handler.speech + adapter := handler.adapter + browser := handler.browser + inputSource := handler.inputSource + focusGate := handler.focusGate + notifications := handler.notifications + live := handler.live + brailleOutput := handler.brailleOutput + foreground := handler.foreground + debounce := handler.debounce + syncForeground := handler.syncForeground + flushTerminalDeletion := handler.flushTerminalDeletion + speak := handler.speak + webScripts := handler.webScripts + ownedAutocompletePopup := state.ownedAutocompletePopup + if focusGate.Locked() { + return + } + if event.Type == atspi.MouseButtonEvent { + state.pending.clear() + if browser != nil { + browser.pointer_input() + } + logger.Debug("released virtual caret for pointer input") + return + } + if overflow := adapter.Overflow(); overflow > state.lastOverflow { + logger.Warn("AT-SPI event queue overflow", "dropped_events", overflow-state.lastOverflow) + state.lastOverflow = overflow + } + if logger.Enabled(context.Background(), slog.LevelDebug) { + logger.Debug("received accessibility event", + "type", event.Type, + "native_type", event.NativeType, + "application", event.Source.ApplicationName, + "bus", event.Source.BusName, + "source_path", event.Source.Path, + "origin_path", event.OriginPath, + "window_bus", event.Window.BusName, + "window_path", event.Window.Path, + "window_recovered", event.WindowRecovered, + "focus_outside_document", event.FocusOutsideDocument.Path, + "role", event.Source.Role, + "focused", event.Source.Focused, + "browser_tab", event.Source.BrowserTab, + "selected", event.Source.Selected, + "checked", event.Source.Checked, + "radio_group_name", event.Source.RadioGroupName, + "prompt_message_present", event.Source.Text != "" && (event.Source.Role == "frame" || event.Source.Role == "alert") || event.WindowMessage != "", + "snapshot_duration", event.SnapshotDuration, + "editable", event.Source.Editable, + "editable_root", event.Source.EditableRoot.Path, + "autocomplete", event.Source.Autocomplete, + "autocomplete_popup", event.Source.AutocompletePopup, + "event_detail1", event.Detail1, + "native_caret_known", event.Source.TextCaretKnown, + "native_caret_offset", event.Source.BrailleCaret, + "native_line_start", event.Source.BrailleLineStart, + "character_count", event.Source.CharacterCount, + "selection_start", event.Source.SelectionStart, + "selection_end", event.Source.SelectionEnd) + } + syncForeground() + notification := eventBypassesXTermHandoff(event) + if handler.wineReview != nil && handler.wineReview.owns(state.current.ID()) && !notification { + return + } + ownedTooltip := event.Type == atspi.ShowingStateEvent && event.Source.Role == "tool tip" && + state.owner.applicationBus != "" && state.owner.applicationBus == event.Source.BusName && + event.Foreground.Epoch == state.foregroundState.Epoch + if webScripts.handle(event) { + return + } + if handler.handle_progress_bar(event) { + return + } + ending := event.Type == atspi.DefunctStateEvent || event.Type == atspi.WindowDestroyedEvent || event.Type == atspi.WindowDeactivatedEvent + if foreground != nil && !notification && + (event.Foreground.Epoch != state.foregroundState.Epoch || + event.ForegroundMismatch && !ending && !ownedAutocompletePopup(event) && !ownedTooltip) { + if event.Type == atspi.WindowActivatedEvent { + check := event.ForegroundCheck + client := event.Foreground.Client + logger.Debug("ignored accessibility event outside X11 foreground", "type", event.Type, + "bus", event.Window.BusName, "window_path", event.Window.Path, + "x_window", client.Window, "epoch", event.Foreground.Epoch, + "current_epoch", state.foregroundState.Epoch, "reason", check.Reason, + "x_pid", client.PID, "x_property_pid", client.PropertyPID, "accessible_pid", check.AccessiblePID, + "active", check.Active, "showing", check.Showing, "iconified", check.Iconified, + "accessible_bounds", check.Bounds, + "x_bounds", [4]int{client.X, client.Y, client.Width, client.Height}, + "x_outer_bounds", [4]int{client.OuterX, client.OuterY, client.OuterWidth, client.OuterHeight}) + } else { + logger.Debug("ignored accessibility event outside X11 foreground", "type", event.Type, + "bus", event.Window.BusName, "window_path", event.Window.Path, + "x_window", state.foregroundState.Client.Window, "epoch", event.Foreground.Epoch) + } + return + } + var applicationSuppressed bool + event, applicationSuppressed = handler.prepareApplicationEvent(event) + if applicationSuppressed { + return + } + if handler.handleLifecycle(event) { + return + } + consumed := handler.acceptFocusOwnership(event, notification) + if isFocusGainEvent(event) && !notification && live != nil && live.onApplication != nil && + state.owner.applicationBus == event.Source.BusName && state.owner.window == eventWindow(event) { + application := handler.titles.applicationForEvent(event) + live.onApplication(application) + } + if event.Type == atspi.WindowActivatedEvent && state.owner.window == eventWindow(event) { + handler.titles.activated(event) + } + if consumed { + return + } + if notifications != nil { + message, speechMessages, handled, save := notificationEvent(event) + if save { + notifications.Save(message) + } + if handled { + presentNotifications(speech, speechMessages) + return + } + if save { + speak(event) + return + } + } + if handler.handleTooltip(event) { + return + } + activity := recentInput(inputSource) + if inputSource == nil && browser != nil { + activity = browser.RecentInput() + } + intent := activity.Intent + if event.Type == atspi.CaretEvent && event.Source.EditableRoot.Valid() && state.focusedID.Valid() && + !belongsToFocusedEditor(event.Source, state.focusedID) { + logger.Debug("skipped caret outside focused editor", "role", event.Source.Role) + return + } + if isTextChangeEvent(event.Type) && event.Source.Editable && + event.Source.Role != "terminal" && !event.Source.LiveRegion && state.focusedID.Path != "" && + !belongsToFocusedEditor(event.Source, state.focusedID) && event.Source.ID() != state.managedDescendantID { + // Settings pages initialize editable number fields while focus + // remains in their navigation tree. These are not user edits. + logger.Debug("skipped text change outside focused editor", "type", event.Type, "role", event.Source.Role) + return + } + if event.Type == atspi.CaretEvent && !event.Source.Editable && !activity.Selecting && + state.focusedID.Path != "" && isFocusCaretControl(state.current.Role) && + (intent == input.NoIntent || intent == input.OtherIntent) && + presentation.EventText(event) == "\ufffc" { + // Gecko can move a containing panel's caret to an embedded + // control just after Tab. Preserve the control's focus, speech, + // and braille rather than adopting that object's placeholder. + logger.Debug("skipped embedded-object caret after control focus", "role", event.Source.Role) + return + } + if handler.handleBrowserTab(event, activity) { + return + } + if shouldPresentFileManagerStatus(event, state.current, state.owner, intent) { + status := strings.TrimSpace(event.Source.Name) + if state.lastFileManagerStatusWindow != state.owner.window || status != state.lastFileManagerStatus { + state.lastFileManagerStatusWindow, state.lastFileManagerStatus = state.owner.window, status + speech.Enqueue(speechRequest{Text: status, Role: "status bar", Cause: event.Type}) + if brailleOutput != nil { + brailleOptions := config.DefaultSettings().Braille + textAttributes := config.DefaultTextAttributes() + if live != nil { + settings := live.Load() + brailleOptions, textAttributes = settings.Braille, settings.TextAttributes + } + brailleOutput.EnqueueFrame(brailleFocusFrameWithOptions(event.Source, brailleOptions, textAttributes)) + } + } + return + } + if handler.filterNavigationAndNames(event, activity, intent) { + return + } + event, autocompleteRequest, autocompleteConsumed := handler.handleAutocomplete(event, activity, intent) + if autocompleteConsumed { + return + } + if state.pending.terminalDeletion.event.Type != "" && event.Type != atspi.CaretEvent { + isReplacement := event.Type == atspi.TextInsertedEvent && + event.Source.Path != "" && + event.Source.Path == state.pending.terminalDeletion.event.Source.Path && + event.Detail1 == state.pending.terminalDeletion.event.Detail1 + if isReplacement { + state.pending.terminalDeletion.clear() + logger.Debug("coalesced terminal deletion with following insertion", "role", event.Source.Role) + } else { + flushTerminalDeletion() + } + } + if state.pending.terminalFocus.event.Type != "" { + if event.Type == atspi.TextInsertedEvent && + event.Source.Path != "" && + event.Source.Path == state.pending.terminalFocus.event.Source.Path { + state.pending.terminalFocus.clear() + logger.Debug("coalesced terminal focus with following insertion", "role", event.Source.Role) + } else if isFocusEvent(event.Type) { + state.pending.terminalFocus.clear() + } + } + if handler.acceptFocusedEvent(event, activity) { + return + } + if handler.defer_browser_button_name(event, activity) { + return + } + if handler.handleSelectionAndClipboard(event, activity, intent) { + return + } + if handler.handleCaret(event, activity, intent) { + return + } + state.pending.caret.clear() + if isFocusEvent(event.Type) && event.Source.Role == "terminal" { + state.pending.terminalFocus.schedule(event, input.NoIntent, debounce) + return + } + if event.Type == atspi.TextDeletedEvent && event.Source.Role == "terminal" { + if should_ignore_terminal_scrollback(event) { + logger.Debug("skipped terminal scrollback deletion", "role", event.Source.Role) + return + } + state.pending.terminalDeletion.schedule(event, input.NoIntent, terminalMutationDebounce) + return + } + speak(event) + if autocompleteRequest.Text != "" { + speech.Enqueue(autocompleteRequest) + } +} + +// Thunar and PCManFM can leave AT-SPI focus on a file-view panel while arrowing +// through icons. The status-bar name is then the only changing accessible text +// for the selection. A normally focused file item keeps its own presentation. +func shouldPresentFileManagerStatus(event atspi.Event, current atspi.Snapshot, owner windowOwner, intent input.Intent) bool { + if event.Type != atspi.AccessibleNameEvent || event.Source.Role != "status bar" || + !strings.EqualFold(event.Source.ApplicationName, "thunar") && + !strings.EqualFold(event.Source.ApplicationName, "pcmanfm") || + strings.TrimSpace(event.Source.Name) == "" || + !owner.window.Valid() || event.Window != owner.window || + event.Source.BusName != owner.applicationBus { + return false + } + if intent != input.LineIntent && intent != input.CharacterIntent && intent != input.WordIntent { + return false + } + return current.Role == "panel" || current.Role == "directory pane" || + current.Role == "tree table" && current.Name == "" || + current.Role == "table cell" && current.Name == "" +} diff --git a/internal/app/event_autocomplete.go b/internal/app/event_autocomplete.go new file mode 100644 index 0000000..152c7ee --- /dev/null +++ b/internal/app/event_autocomplete.go @@ -0,0 +1,93 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +// handleAutocomplete may rewrite insertion payload before normal presentation. +// A true consumed result discards popup and address-bar echo events in place. +func (handler *accessibilityEventHandler) handleAutocomplete(event atspi.Event, activity input.Activity, intent input.Intent) (atspi.Event, speechRequest, bool) { + state := handler.state + live := handler.live + logger := handler.logger + speak := handler.speak + var autocompleteRequest speechRequest + state.autocompleteAvailable.focus(event) + if event.Type == atspi.TextInsertedEvent && supportsAutocomplete(event.Source) { + if live != nil { + available := state.presentationOptions.SoundCueAvailable + state.presentationOptions = presentationSettingsFromConfig(live.Load(), true) + state.presentationOptions.SoundCueAvailable = available + } + if address := state.autocompleteAvailable.offered(event, activity); address != "" { + autocompleteRequest = speechRequest{Text: address, Role: "autocomplete", Cause: "autocomplete-available"} + if state.presentationOptions.EnableSound && state.presentationOptions.RoleSoundPresentation != "speech_only" && + (state.presentationOptions.SoundCueAvailable == nil || state.presentationOptions.SoundCueAvailable("autocomplete")) { + autocompleteRequest.Sound = []sound.Cue{{Name: "autocomplete"}} + } + } + } + if event.Source.AutocompletePopup { + explicitItem := isAutocompletePopupItem(event.Source.Role) && + ((isFocusGainEvent(event) && intent == input.LineIntent) || + (event.Type == "object:state-changed:selected" && event.Detail1 != 0 && intent == input.LineIntent)) + if explicitItem && event.Source.ID() != state.lastAutocompletePopupItem { + state.lastAutocompletePopupItem = event.Source.ID() + presentationEvent := event + presentationEvent.Type = atspi.FocusEvent + speak(presentationEvent) + } + logger.Debug("skipped autocomplete popup noise", "type", event.Type, "role", event.Source.Role) + return event, autocompleteRequest, true + } + if event.Source.Autocomplete { + if isFocusGainEvent(event) { + state.lastAutocompletePopupItem = atspi.ObjectID{} + } + if (isTextChangeEvent(event.Type) || event.Type == atspi.CaretEvent) && intent == input.LineIntent { + return event, autocompleteRequest, true // Up/Down presents the popup item, not the entry's replacement text. + } + if event.Type == atspi.TextDeletedEvent && intent == input.TypingIntent { + return event, autocompleteRequest, true // Replacing the selected URL or completion is not a user deletion. + } + if event.Type == atspi.TextInsertedEvent && intent == input.TypingIntent { + event.Payload = state.autocompleteTyping.insertion(event, activity) + if autocompleteRequest.Text != "" { + event.Payload = "" // The selected address replaces this insertion's character echo. + } + } + } + return event, autocompleteRequest, false +} + +func isBrowserUINameNoise(event atspi.Event, focus atspi.Snapshot) bool { + if event.Type != atspi.AccessibleNameEvent { + return false + } + // Browser chrome labels, status bars, and frames can change independently + // of focus. Current controls and rows still need their new names presented. + // Orca's web UI noise filter likewise limits these ignored roles. + switch strings.ToLower(event.Source.ToolkitName) { + case "chromium", "gecko", "webkit", "webkitgtk": + return event.Source.Role == "status bar" || event.Source.Role == "label" || + event.Source.Role == "frame" + } + if event.Source.AutocompletePopup { + return true + } + return focus.Autocomplete && event.Source.ID().BusName != "" && + event.Source.ID().BusName == focus.ID().BusName +} + +func isAutocompletePopupItem(role string) bool { + return role == "list item" || role == "menu item" +} diff --git a/internal/app/event_browser_tabs.go b/internal/app/event_browser_tabs.go new file mode 100644 index 0000000..7b91061 --- /dev/null +++ b/internal/app/event_browser_tabs.go @@ -0,0 +1,74 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +// handleBrowserTab presents a selected tab while leaving native focus in chrome. +func (handler *accessibilityEventHandler) handleBrowserTab(event atspi.Event, activity input.Activity) bool { + state := handler.state + browser := handler.browser + objectReview := handler.objectReview + speech := handler.speech + brailleOutput := handler.brailleOutput + live := handler.live + if event.Source.BrowserTab && (event.Type == atspi.SelectedStateEvent || event.Type == atspi.SelectionChangedEvent) { + // Python's web page-switch handler presents the tab without moving + // the locus of focus. Repeated Ctrl+T can keep the same address + // control focused and produce no further focus events at all. + selected := event.Type == atspi.SelectedStateEvent && event.Detail1 != 0 || + event.Type == atspi.SelectionChangedEvent && event.Source.Selected && + strings.EqualFold(event.Source.ToolkitName, "Gecko") + if !selected || event.Source.StatesKnown && !event.Source.Selected || + event.Source.Defunct || !state.owner.containsLoad(event) || event.Source.ID() == state.selectedBrowserTab { + return true + } + state.selectedBrowserTab = event.Source.ID() + state.tabFocusWindow, state.tabFocusSequence = eventWindow(event), activity.Sequence + state.pending.caret.clear() + state.documentLineFocus, state.documentLineRequest, state.documentLineEvent = atspi.ObjectID{}, 0, atspi.Event{} + state.loadingDocument, state.loadedDocument = atspi.ObjectID{}, atspi.ObjectID{} + state.chromeLoadedDocument, state.chromeLoadedWindow = atspi.ObjectID{}, atspi.ObjectID{} + if browser != nil { + browser.clear() + } + if objectReview != nil { + focus := atspi.ObjectID{} + if state.current.Autocomplete { + focus = state.current.ID() + } + objectReview.ResetDocument(focus) + } + spoken := presentation.FocusSpeechWithOptions(event.Source, state.presentationOptions) + text := spoken.Text + if text != "" { + speech.Enqueue(speechRequest{Text: text, Chunks: spoken.Chunks, Role: event.Source.Role, Cause: event.Type}) + } + if brailleOutput != nil { + brailleOptions := config.DefaultSettings().Braille + textAttributes := config.DefaultTextAttributes() + if live != nil { + settings := live.Load() + brailleOptions, textAttributes = settings.Braille, settings.TextAttributes + } + brailleOutput.EnqueueFrame(brailleFocusFrameWithOptions(event.Source, brailleOptions, textAttributes)) + } + return true + } + if event.Source.Autocomplete && eventWindow(event) == state.tabFocusWindow && + activity.Sequence != 0 && activity.Sequence == state.tabFocusSequence && + (event.Type == atspi.CaretEvent || event.Type == "object:state-changed:expanded") { + return true // Automatic address reset must not cut off the selected tab. + } + return false +} diff --git a/internal/app/event_caret.go b/internal/app/event_caret.go new file mode 100644 index 0000000..85e0c41 --- /dev/null +++ b/internal/app/event_caret.go @@ -0,0 +1,98 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func (handler *accessibilityEventHandler) handleCaret(event atspi.Event, activity input.Activity, intent input.Intent) bool { + state := handler.state + logger := handler.logger + speech := handler.speech + browser := handler.browser + objectReview := handler.objectReview + debounce := handler.debounce + if event.Type == atspi.CaretEvent { + if event.Source.ID() == state.selectionCaretID { + state.selectionCaretID = atspi.ObjectID{} + if activity.Sequence == state.selectionCaretSequence && time.Since(state.selectionCaretAt) < 150*time.Millisecond { + logger.Debug("skipped caret covered by text selection") + return true + } + } + if (event.Source.Autocomplete || activity.Sequence != 0 && + (event.Source.Role == "spin button" || event.Source.Role == "button" || event.Source.Role == "link")) && + event.Source.ID() == state.focusCaretID && activity.Sequence == state.focusCaretSequence && + !activity.Selecting && + (intent == input.NoIntent || intent == input.OtherIntent) { + // Address bars, spin buttons, and Gecko buttons/links move their + // text caret on focus. With the same input sequence and no + // caret-navigation intent, this must not interrupt the label. + logger.Debug("skipped control caret caused by focus", "role", event.Source.Role) + return true + } + if browser != nil && browser.ready && !event.Source.Editable { + state.current = event.Source + if objectReview != nil { + objectReview.SyncFocus(event.Source.ID()) + if err := objectReview.SyncDocumentCaret(event.Source.ID(), event.Detail1); err != nil { + logger.Debug("could not queue native document caret", "error", err) + } + } + } + if browser != nil && browser.ready && !event.Source.Editable && event.Source.TextCaretKnown && event.Source.Role != "password text" { + if state.documentSelection.id != event.Source.ID() { + state.documentSelection.reset(atspi.Snapshot{BusName: event.Source.BusName, Path: event.Source.Path}) + } + fragmentLimit := selectionFragmentLimit + if activity.Selecting && intent == input.LineIntent { + fragmentLimit = lineSelectionFragmentLimit + } + if message := state.documentSelection.changedWithLimit(event.Source, fragmentLimit); message != "" { + state.pending.caret.clear() + speech.Enqueue(speechRequest{Text: message, Role: "system", Cause: event.Type}) + return true + } + } + + // Any newer caret event supersedes an outstanding visual-line + // assembly, even when the new event can use its already-captured + // current-object line. + state.documentLineFocus = atspi.ObjectID{} + state.documentLineRequest = 0 + state.documentLineEvent = atspi.Event{} + // Python's default non-layout web mode reads the current object's + // line. A blank browse caret is not a reason to scan the whole + // document; focus mode still assembles visual lines across objects. + if browser != nil && browser.ready && browser.mode == review.FocusMode && + intent == input.LineIntent && !event.Source.Editable && objectReview != nil { + state.current = event.Source + objectReview.SyncFocus(event.Source.ID()) + if request, err := objectReview.ReadDocumentLine(event.Source.ID(), event.Detail1); err == nil { + state.documentLineFocus = event.Source.ID() + state.documentLineRequest = request + state.documentLineEvent = event + logger.Debug("queued document caret line", "role", event.Source.Role) + return true + } + } + if event.Source.Path != "" && event.Source.Path == state.suppressNextCaretPath { + state.suppressNextCaretPath = "" + logger.Debug("skipped caret event already covered by text change", "type", event.Type, "role", event.Source.Role) + return true + } + // Keep a short coalescing window for selection/focus events without + // adding the terminal focus delay to every caret movement. + state.pending.caret.schedule(event, intent, min(debounce, 20*time.Millisecond)) + return true + } + return false +} diff --git a/internal/app/event_caret_test.go b/internal/app/event_caret_test.go new file mode 100644 index 0000000..4a9c35e --- /dev/null +++ b/internal/app/event_caret_test.go @@ -0,0 +1,226 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestProcessEventsSpeaksChangedCaretLines(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + adapter.events <- atspi.NewEvent(atspi.CaretEvent, atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "First line")) + select { + case text := <-speech.spoken: + if text != "First line" { + t.Fatalf("spoken text = %q, want %q", text, "First line") + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for first caret speech") + } + + adapter.events <- atspi.NewEvent(atspi.CaretEvent, atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "First line")) + adapter.events <- atspi.NewEvent(atspi.CaretEvent, atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "Second line")) + select { + case text := <-speech.spoken: + if text != "Second line" { + t.Fatalf("spoken text = %q, want %q", text, "Second line") + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for second caret speech") + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestProcessEventsSuppressesCaretAfterEditableTextChange(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + paragraph := atspi.Snapshot{Path: "/writer/paragraph", Role: "paragraph", Editable: true, + Text: "Hello", CaretCharacter: "o"} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, paragraph) + <-speech.spoken + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, paragraph, "o") + if got := <-speech.spoken; got != "o" { + t.Fatalf("insert speech = %q", got) + } + adapter.events <- atspi.NewEvent(atspi.CaretEvent, paragraph) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, + atspi.Snapshot{Path: "/status", Role: "label"}, "status update") + + select { + case got := <-speech.spoken: + t.Fatalf("unexpected duplicate or status speech: %q", got) + case <-time.After(30 * time.Millisecond): + } + + cancel() + <-completed +} + +func TestProcessEventsSpeaksCaretCharacters(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + adapter.events <- atspi.NewEvent(atspi.CaretEvent, atspi.NewSnapshotWithCaretCharacter( + "/accessible/terminal", "", "terminal", "", "prompt ls", "l", + )) + select { + case text := <-speech.spoken: + if text != "l" { + t.Fatalf("spoken text = %q, want %q", text, "l") + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for first caret character speech") + } + adapter.events <- atspi.NewEvent(atspi.CaretEvent, atspi.NewSnapshotWithCaretCharacter( + "/accessible/terminal", "", "terminal", "", "prompt ll", "l", + )) + select { + case text := <-speech.spoken: + if text != "l" { + t.Fatalf("repeated caret character = %q, want l", text) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for repeated caret character speech") + } + + adapter.events <- atspi.NewEvent(atspi.CaretEvent, atspi.NewSnapshotWithCaretCharacter( + "/accessible/terminal", "", "terminal", "", "prompt ls", "s", + )) + select { + case text := <-speech.spoken: + if text != "s" { + t.Fatalf("spoken text = %q, want %q", text, "s") + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for second caret character speech") + } + + adapter.events <- atspi.NewEvent(atspi.CaretEvent, atspi.NewSnapshotWithCaretCharacter( + "/accessible/terminal", "", "terminal", "", "prompt ls", " ", + )) + select { + case text := <-speech.spoken: + if text != "space" { + t.Fatalf("spoken caret space = %q, want %q", text, "space") + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for caret space speech") + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestProcessEventsTextChangeCancelsPendingCaretLine(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, time.Hour) + close(completed) + }() + + terminal := atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "prompt l") + adapter.events <- atspi.NewEvent(atspi.CaretEvent, terminal) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, terminal, "l") + + select { + case text := <-speech.spoken: + if text != "l" { + t.Fatalf("spoken text = %q, want %q", text, "l") + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for inserted text speech") + } + + select { + case text := <-speech.spoken: + t.Fatalf("unexpected additional speech: %q", text) + default: + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestCaretEventRequestsCharacterVoice(t *testing.T) { + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { defer close(done); processEvents(ctx, slog.New(slog.DiscardHandler), queue, adapter, 0) }() + defer func() { cancel(); <-done }() + adapter.events <- atspi.NewEvent(atspi.CaretEvent, atspi.NewSnapshotWithCaretCharacter("/terminal", "", "terminal", "", "Ab", "A")) + select { + case request := <-queue.requests: + if request.Text != "A" || !request.Character { + t.Fatalf("caret request = %+v", request) + } + case <-time.After(time.Second): + t.Fatal("caret speech missing") + } +} diff --git a/internal/app/event_filters.go b/internal/app/event_filters.go new file mode 100644 index 0000000..cb8433f --- /dev/null +++ b/internal/app/event_filters.go @@ -0,0 +1,79 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func isFocusEvent(eventType string) bool { + return eventType == atspi.FocusEvent || eventType == atspi.FocusedStateEvent || eventType == atspi.WindowActivatedEvent +} + +func isMenuRole(role string) bool { + return role == "menu" || role == "menu item" || role == "check menu item" || role == "radio menu item" +} + +func isFocusGainEvent(event atspi.Event) bool { + return event.Type == atspi.FocusEvent || + event.Type == atspi.WindowActivatedEvent || + (event.Type == atspi.FocusedStateEvent && event.Detail1 != 0) +} + +func isStateChangeEvent(eventType string) bool { + return strings.HasPrefix(eventType, "object:state-changed:") && eventType != atspi.FocusedStateEvent +} + +func isValueChangeEvent(eventType string) bool { + return eventType == atspi.ValueChangedEvent || eventType == atspi.AccessibleValueEvent +} + +func isManagedDescendantEvent(eventType string) bool { + return eventType == atspi.ActiveDescendantEvent || eventType == atspi.SelectionChangedEvent +} + +func sameSelectionItem(source, current atspi.Snapshot) bool { + return (source.Role == "tree item" || source.Role == "list item") && + source.ID() == current.ID() && source.Role == current.Role && source.Name == current.Name && + source.Selected == current.Selected && source.Expandable == current.Expandable && source.Expanded == current.Expanded +} + +func sameManagedDescendant(source, current atspi.Snapshot) bool { + return source.ID() == current.ID() && source.Role == current.Role && + source.Name == current.Name && source.TableRowText == current.TableRowText && + source.Selected == current.Selected && source.Expanded == current.Expanded && + source.Checked == current.Checked +} + +func presentsReusedRow(source atspi.Snapshot) bool { + return source.Role == "table row" || source.Role == "table cell" && source.GUITable +} + +func isFocusCaretControl(role string) bool { + switch role { + case "button", "toggle button", "check box", "radio button", "combo box", "spin button", "tree item", "list item": + return true + default: + return false + } +} + +func speaksTextChanges(snapshot atspi.Snapshot) bool { + return snapshot.Role == "terminal" || + (snapshot.Editable && !snapshot.ReadOnly && snapshot.Role != "password text") +} + +func belongsToFocusedEditor(source atspi.Snapshot, focus atspi.ObjectID) bool { + return focus.Path != "" && (source.ID() == focus || focus.Valid() && source.Editable && !source.ReadOnly && + source.Role != "password text" && source.EditableRoot.Valid() && source.EditableRoot == focus && + source.BusName == focus.BusName) +} + +func isTextChangeEvent(eventType string) bool { + return eventType == atspi.TextInsertedEvent || eventType == atspi.TextDeletedEvent +} diff --git a/internal/app/event_focus.go b/internal/app/event_focus.go new file mode 100644 index 0000000..4adb7aa --- /dev/null +++ b/internal/app/event_focus.go @@ -0,0 +1,169 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "slices" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func (handler *accessibilityEventHandler) acceptFocusedEvent(event atspi.Event, activity input.Activity) bool { + state := handler.state + logger := handler.logger + objectReview := handler.objectReview + browser := handler.browser + brailleOutput := handler.brailleOutput + live := handler.live + // Native state-only captures omit mnemonic lookup. Preserve the owned + // value so GTK's following focus event compares against the same metadata + // and does not replay the just-announced state sound and label. + if isStateChangeEvent(event.Type) && event.Source.ID() == state.current.ID() && + event.Source.Role == state.current.Role && event.Source.Mnemonic == "" { + event.Source.Mnemonic = state.current.Mnemonic + } + // Compare with the owned focus snapshot, not the last speech request: + // a state/value update can intervene between two toolkit focus events. + // Still refresh review and braille below before suppressing presentation. + duplicateFocus := (event.Type == atspi.FocusEvent || event.Type == atspi.FocusedStateEvent && event.Detail1 != 0) && + event.Source.Role != "terminal" && !presentsReusedRow(event.Source) && + !(state.pendingPromptWindow.Valid() && event.Window == state.pendingPromptWindow) && + state.focusedID.Valid() && event.Source.ID() == state.focusedID && + event.Source.ID() == state.current.ID() && + presentation.FocusTextWithOptions(event.Source, state.presentationOptions) == presentation.FocusTextWithOptions(state.current, state.presentationOptions) && + slices.Equal(presentation.SoundCues(event.Source, state.presentationOptions), presentation.SoundCues(state.current, state.presentationOptions)) + if isFocusEvent(event.Type) { + if !duplicateFocus { + state.pending.browserButtonName.clear() + } + focusID := event.Source.ID() + if isFocusGainEvent(event) { + state.focusCaretID = focusID + state.focusCaretSequence = activity.Sequence + } else { + state.focusCaretID = atspi.ObjectID{} + } + if focusID != state.managedContainerID && focusID != state.managedDescendantID { + state.managedContainerID = atspi.ObjectID{} + state.managedDescendantID = atspi.ObjectID{} + } + // GTK table focus is normalized to its selected cell by the native + // adapter. Retain the captured table owner before the first arrow + // move, even when no container focus event reached this loop. + if event.Source.Role == "table cell" && event.Source.GUITable { + tableID := atspi.NewObjectID(event.Source.BusName, event.Source.TablePath) + if tableID.Valid() { + state.managedContainerID = tableID + state.managedDescendantID = focusID + } + } + state.focusedID = focusID + state.selection.reset(event.Source) + if objectReview != nil { + objectReview.SyncFocus(event.Source.ID()) + } + } else if isManagedDescendantEvent(event.Type) { + containerID := atspi.NewObjectID(event.Source.BusName, event.OriginPath) + descendantID := event.Source.ID() + if event.Source.Defunct || event.Source.Role == "invalid" || descendantID.Path == "" { + logger.Debug("skipped invalid managed descendant", "type", event.Type) + return true + } + if state.focusedID.Path == "" || + (containerID != state.focusedID && descendantID != state.focusedID && containerID != state.managedContainerID) { + logger.Debug("skipped managed descendant outside focused object", "type", event.Type, "role", event.Source.Role) + return true + } + if containerID == state.managedContainerID && descendantID == state.managedDescendantID && + (!presentsReusedRow(event.Source) || sameManagedDescendant(event.Source, state.current)) { + logger.Debug("skipped unchanged managed descendant", "type", event.Type, "role", event.Source.Role) + return true + } + state.managedContainerID = containerID + state.managedDescendantID = descendantID + if event.Type == atspi.SelectionChangedEvent && sameSelectionItem(event.Source, state.current) { + logger.Debug("skipped selection already presented by focus", "role", event.Source.Role) + return true + } + } else if (isStateChangeEvent(event.Type) || isValueChangeEvent(event.Type)) && + (state.focusedID.Path == "" || event.Source.ID() != state.focusedID) { + logger.Debug("skipped event outside focused object", "type", event.Type, "role", event.Source.Role) + return true + } + if event.Type == atspi.SelectedStateEvent && sameSelectionItem(event.Source, state.current) { + logger.Debug("skipped selected state already presented by focus", "role", event.Source.Role) + return true + } + // Keep native focus on the editor, but present the paragraph which owns + // its current caret/selection. Leaving that editor immediately revokes + // this relationship; no extra mutable ownership state is retained. + if belongsToFocusedEditor(event.Source, state.focusedID) && + (isTextChangeEvent(event.Type) || event.Type == atspi.CaretEvent || event.Type == atspi.TextSelectionChangedEvent) { + state.current = event.Source + } + if isFocusEvent(event.Type) || isManagedDescendantEvent(event.Type) || + event.Type == atspi.AccessibleNameEvent && presentsReusedRow(event.Source) && + event.Source.ID() == state.managedDescendantID || + (event.Source.Path != "" && event.Source.ID() == state.focusedID) { + state.current = event.Source + } + if isTextChangeEvent(event.Type) { + if !speaksTextChanges(event.Source) && !event.Source.LiveRegion { + logger.Debug("skipped text change outside editable content", "type", event.Type, "role", event.Source.Role) + return true + } + if !event.Source.LiveRegion { + state.suppressNextCaretPath = event.Source.Path + } + } + if event.Type == atspi.CaretEvent && browser != nil && browser.ready && !event.Source.Editable { + state.current = event.Source + } + if brailleOutput != nil && (isFocusGainEvent(event) || + isManagedDescendantEvent(event.Type) || event.Type == atspi.CaretEvent || + event.Type == atspi.AccessibleNameEvent && + (event.Source.ID() == state.focusedID || presentsReusedRow(event.Source)) || + event.Type == atspi.TextSelectionChangedEvent && event.Source.TextCaretKnown || + isStateChangeEvent(event.Type) || isValueChangeEvent(event.Type) || + isTextChangeEvent(event.Type) && speaksTextChanges(event.Source)) && + event.Source.ID() == state.current.ID() { + source := event.Source + if (isStateChangeEvent(event.Type) || isValueChangeEvent(event.Type)) && + !source.TextCaretKnown && source.ID() == state.brailleSnapshot.ID() { + source.TextCaretKnown = state.brailleSnapshot.TextCaretKnown + source.BrailleLine = state.brailleSnapshot.BrailleLine + source.BrailleLineStart = state.brailleSnapshot.BrailleLineStart + source.BrailleCaret = state.brailleSnapshot.BrailleCaret + } + if len(source.BrailleContext) == 0 && source.ID() == state.brailleSnapshot.ID() { + source.BrailleContext = state.brailleSnapshot.BrailleContext + } + state.brailleSnapshot = source + brailleOptions := config.DefaultSettings().Braille + textAttributes := config.DefaultTextAttributes() + if live != nil { + settings := live.Load() + brailleOptions, textAttributes = settings.Braille, settings.TextAttributes + } + frame := brailleFocusFrameWithOptions(source, brailleOptions, textAttributes) + if browser != nil && browser.ready && browser.mode == review.BrowseMode && !source.Editable && + objectReview != nil && browser.document.Valid() && source.Role != "password text" { + focus := objectReview.Focus() + frame.Document = &braille.DocumentRoute{Epoch: objectReview.DocumentEpoch(), FocusBus: focus.BusName, FocusPath: focus.Path, + DocumentBus: browser.document.BusName, DocumentPath: browser.document.Path} + } + brailleOutput.EnqueueFrame(frame) + } + if duplicateFocus { + logger.Debug("skipped unchanged accessible focus", "type", event.Type, "role", event.Source.Role) + } + return duplicateFocus +} diff --git a/internal/app/event_focus_ownership.go b/internal/app/event_focus_ownership.go new file mode 100644 index 0000000..e0e111e --- /dev/null +++ b/internal/app/event_focus_ownership.go @@ -0,0 +1,129 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/webscripts" +) + +// acceptFocusOwnership keeps native window focus, XTerm handoff, and navigation +// echoes ahead of input intent and normal presentation. +func (handler *accessibilityEventHandler) acceptFocusOwnership(event atspi.Event, notification bool) bool { + state := handler.state + logger := handler.logger + speech := handler.speech + focusGate := handler.focusGate + objectReview := handler.objectReview + brailleOutput := handler.brailleOutput + ownedAutocompletePopup := state.ownedAutocompletePopup + if isFocusGainEvent(event) { + if event.Type == atspi.WindowActivatedEvent { + focusBeforeActivation := state.owner.window.Valid() && state.owner.window == eventWindow(event) && + state.owner.focus.Valid() && !state.owner.activated + // Window ownership and object focus are independent. Providers can + // repeat activation for the same top-level around an X11 key grab, + // and the activation snapshot can be the frame while the focused + // object is one of its descendants. Treating that source mismatch as + // a new activation interrupts review speech and resets its cursor. + if state.owner.activate(event) { + logger.Debug("skipped duplicate accessible window activation", "application", event.Source.ApplicationName, "bus", state.owner.window.BusName, "window_path", state.owner.window.Path, "focus_path", event.Source.Path) + return true + } + state.lastFileManagerStatus, state.lastFileManagerStatusWindow = "", atspi.ObjectID{} + logger.Debug("activated accessible window", "application", event.Source.ApplicationName, "bus", state.owner.window.BusName, "window_path", state.owner.window.Path, "focus_path", event.Source.Path) + if (event.Source.Role == "alert" || event.Source.Role == "frame") && + state.pendingPromptTextAnnounced && state.pendingPromptWindow.Valid() && event.Window == state.pendingPromptWindow { + // The prompt's window:create already queued its title and + // message. Activation must not cut that announcement short. + return true + } + if focusBeforeActivation { + text := strings.TrimSpace(event.WindowTitle) + if (event.Source.Role == "button" || event.Source.Role == "tree table" || event.Source.Role == "table cell") && event.WindowMessage != "" { + if text != "" { + text += ", " + } + text += event.WindowMessage + } + if text != "" { + speech.Enqueue(speechRequest{Text: text, Role: "frame", Cause: event.Type, + Window: eventWindow(event), IntroducesWindow: true, + ExcludeFromHistory: state.historyWindow.Valid() && eventWindow(event) == state.historyWindow}) + } + return true + } + } else if !ownedAutocompletePopup(event) && !state.owner.follow(event) { + logger.Debug("skipped focus outside active window", "type", event.Type, "application", event.Source.ApplicationName, "bus", event.Window.BusName, "window_path", event.Window.Path, "focus_path", event.Source.Path) + return true + } + if isXTermFocus(event) { + state.brailleSnapshot = atspi.Snapshot{} + if brailleOutput != nil { + brailleOutput.EnqueueFrame(braille.Frame{Cursor: -1}) + } + state.pending.clear() + focusGate.SetSuspended(true) + state.focusedID = event.Source.ID() + state.current = event.Source + if objectReview != nil { + objectReview.SyncFocus(event.Source.ID()) + } + logger.Info("suspended for XTerm focus handoff") + return true + } + if !notification { + focusGate.SetSuspended(false) + } + } + if focusGate.Suspended() && !notification { + logger.Debug("skipped event during XTerm focus handoff", "type", event.Type, "role", event.Source.Role) + return true + } + if event.NavigationEcho { + return true + } + // The native adapter already filters focused-state losses. Keep the + // event loop defensive for alternate adapters and tests: Python does + // not present or follow the object which just lost focus. + if event.Type == atspi.FocusedStateEvent && event.Detail1 == 0 { + return true + } + return false +} + +func isXTermSnapshot(snapshot atspi.Snapshot) bool { + return strings.EqualFold(snapshot.ApplicationName, "xterm") +} + +func isXTermFocus(event atspi.Event) bool { + if isXTermSnapshot(event.Source) { + return true + } + return event.Source.Role == "terminal" && event.Source.ApplicationName == "" && xorg.ActiveWindowIsXTerm() +} + +func eventBypassesXTermHandoff(event atspi.Event) bool { + if webscripts.HandlesNotification(event.Source.ApplicationProcess, event.Type, event.Detail1, event.WebNotification) { + return true + } + role := strings.ToLower(event.Source.Role) + if role == "notification" || role == "alert" { + return true + } + switch event.Type { + case "window:create", "object:property-change:accessible-name", atspi.AccessibleValueEvent: + switch strings.ToLower(event.Source.ApplicationName) { + case "notification-daemon", "notify-osd", "xfce4-notifyd", "mate-notification-daemon": + return true + } + } + return false +} diff --git a/internal/app/event_focus_test.go b/internal/app/event_focus_test.go new file mode 100644 index 0000000..1d17443 --- /dev/null +++ b/internal/app/event_focus_test.go @@ -0,0 +1,414 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestProcessEventsSuppressesDuplicateFocusObjects(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + adapter.events <- atspi.NewEvent("focus:", atspi.NewSnapshot("/accessible/save", "Save", "push button", "", "")) + saveFocused := atspi.NewEvent("object:state-changed:focused", atspi.NewSnapshot("/accessible/save", "Save", "push button", "", "")) + saveFocused.Detail1 = 1 + adapter.events <- saveFocused + cancelFocused := atspi.NewEvent("object:state-changed:focused", atspi.NewSnapshot("/accessible/cancel", "Cancel", "push button", "", "")) + cancelFocused.Detail1 = 1 + adapter.events <- cancelFocused + + for _, expected := range []string{"Save, push button", "Cancel, push button"} { + select { + case text := <-speech.spoken: + if text != expected { + t.Fatalf("spoken text = %q, want %q", text, expected) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for speech %q", expected) + } + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestProcessEventsSuppressesUnfocusedNameChangesDuringFileNavigation(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + ctx, cancel := context.WithCancel(context.Background()) + completed := make(chan struct{}) + go func() { + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), speech, adapter, nil, nil, 0, nil, + fixedInputActivity{input.Activity{Intent: input.LineIntent}}, nil, nil) + close(completed) + }() + defer func() { cancel(); <-completed }() + + frame := atspi.NewSnapshot("/thunar/window", "Thunar", "frame", "", "") + frame.BusName, frame.ApplicationName = ":1.45", "thunar" + activated := atspi.NewEvent(atspi.WindowActivatedEvent, frame) + activated.Window = frame.ID() + adapter.events <- activated + <-speech.spoken + + file := atspi.NewSnapshot("/thunar/file", "Audio", "table cell", "", "") + file.BusName, file.ApplicationName = frame.BusName, "thunar" + focused := atspi.NewEvent(atspi.FocusedStateEvent, file) + focused.Detail1, focused.Window = 1, frame.ID() + adapter.events <- focused + if got := <-speech.spoken; got != "Audio" { + t.Fatalf("file speech = %q", got) + } + + for _, role := range []string{"directory pane", "status bar"} { + changed := atspi.NewSnapshot("/thunar/"+role, "Updated "+role, role, "", "") + changed.BusName, changed.ApplicationName = frame.BusName, "thunar" + event := atspi.NewEvent(atspi.AccessibleNameEvent, changed) + event.Window = frame.ID() + adapter.events <- event + } + select { + case got := <-speech.spoken: + t.Fatalf("unfocused name change interrupted file: %q", got) + case <-time.After(30 * time.Millisecond): + } + + status := atspi.NewSnapshot("/thunar/status bar", "Selected file", "status bar", "", "") + status.BusName, status.ApplicationName = frame.BusName, "thunar" + statusFocus := atspi.NewEvent(atspi.FocusedStateEvent, status) + statusFocus.Detail1, statusFocus.Window = 1, frame.ID() + adapter.events <- statusFocus + if got := <-speech.spoken; got != "Selected file, status bar" { + t.Fatalf("focused status bar speech = %q", got) + } + status.Name = "Updated status" + statusChanged := atspi.NewEvent(atspi.AccessibleNameEvent, status) + statusChanged.Window = frame.ID() + adapter.events <- statusChanged + if got := <-speech.spoken; got != "Updated status, status bar" { + t.Fatalf("focused status bar update = %q", got) + } +} + +func TestProcessEventsFiltersUnfocusedStateAndValueChanges(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + focused := atspi.Snapshot{Path: "/volume", Name: "Volume", Role: "slider", ValueKnown: true, + CurrentValue: 20, MinimumValue: 0, MaximumValue: 100} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, focused) + if got := <-speech.spoken; got != "Volume, slider, 20" { + t.Fatalf("focus speech = %q", got) + } + + unfocused := atspi.Snapshot{Path: "/other", Name: "Other", Role: "slider", ValueKnown: true, + CurrentValue: 90, MinimumValue: 0, MaximumValue: 100} + adapter.events <- atspi.NewEvent(atspi.ValueChangedEvent, unfocused) + adapter.events <- atspi.NewEvent("object:state-changed:sensitive", atspi.Snapshot{ + Path: "/other", Name: "Other", Role: "push button", SensitiveKnown: true, + }) + focused.CurrentValue = 30 + adapter.events <- atspi.NewEvent(atspi.ValueChangedEvent, focused) + + select { + case got := <-speech.spoken: + if got != "30" { + t.Fatalf("value-change speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for focused value change") + } + select { + case got := <-speech.spoken: + t.Fatalf("unexpected unfocused event speech: %q", got) + default: + } + + cancel() + <-completed +} + +func TestProcessEventsPresentsFocusedManagedDescendant(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + list := atspi.NewSnapshot("/run-dialog/results", "Run dialog suggestions", "list", "", "") + adapter.events <- atspi.NewEvent(atspi.FocusEvent, list) + if got := <-speech.spoken; got != "Run dialog suggestions, list" { + t.Fatalf("list focus speech = %q", got) + } + + result := atspi.NewSnapshot("/run-dialog/results/1", "LibreOffice Writer", "table cell", "", "") + adapter.events <- atspi.NewManagedDescendantEvent(atspi.SelectionChangedEvent, list.Path, result) + if got := <-speech.spoken; got != "LibreOffice Writer" { + t.Fatalf("selected result speech = %q", got) + } + + // GTK can emit both selection and active-descendant events for the same row. + adapter.events <- atspi.NewManagedDescendantEvent(atspi.ActiveDescendantEvent, list.Path, result) + select { + case got := <-speech.spoken: + t.Fatalf("duplicate managed-descendant speech = %q", got) + case <-time.After(30 * time.Millisecond): + } + // A feed refresh can briefly expose defunct descendants and repeatedly + // select the same row while updating its relative timestamp. None of + // these events represents navigation or a new post. + invalid := atspi.NewSnapshot("/run-dialog/results/defunct", "", "invalid", "", "") + adapter.events <- atspi.NewManagedDescendantEvent(atspi.ActiveDescendantEvent, list.Path, invalid) + adapter.events <- atspi.NewManagedDescendantEvent(atspi.SelectionChangedEvent, list.Path, result) + updated := result + updated.Name = "LibreOffice Writer, 2 minutes ago" + adapter.events <- atspi.NewEvent(atspi.AccessibleNameEvent, updated) + + // GTK can move explicit focus to the current child before reporting a + // sibling as the container's new selected descendant. The focused child + // remains owned by the same managed container, so the sibling change is + // still relevant. + focusEvent := atspi.NewEvent(atspi.FocusedStateEvent, result) + focusEvent.Detail1 = 1 + adapter.events <- focusEvent + sibling := atspi.NewSnapshot("/run-dialog/results/2", "Calculator", "table cell", "", "") + adapter.events <- atspi.NewManagedDescendantEvent(atspi.SelectionChangedEvent, list.Path, sibling) + if got := <-speech.spoken; got != "Calculator" { + t.Fatalf("sibling result speech = %q", got) + } + + other := atspi.NewSnapshot("/other/results/1", "Unrelated", "table cell", "", "") + adapter.events <- atspi.NewManagedDescendantEvent(atspi.SelectionChangedEvent, "/other/results", other) + select { + case got := <-speech.spoken: + t.Fatalf("unfocused selection speech = %q", got) + case <-time.After(30 * time.Millisecond): + } + + cancel() + <-completed +} + +func TestGeckoCurrentButtonNameArrivesAfterFocus(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3)} + frames := make(chan braille.Frame, 3) + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), outputQueue{speech: speech, braille: frameRecorder{frames}}, adapter, 0) + close(done) + }() + defer func() { cancel(); <-done }() + + button := atspi.NewSnapshot("/mail/toolbar/button", "", "button", "", "") + button.ToolkitName = "Gecko" + adapter.events <- atspi.NewEvent(atspi.FocusEvent, button) + if got := <-speech.spoken; got != "button" { + t.Fatalf("initial unnamed button = %q", got) + } + <-frames + button.Name = "Open calendar" + adapter.events <- atspi.NewEvent(atspi.AccessibleNameEvent, button) + select { + case got := <-speech.spoken: + if got != "Open calendar, button" { + t.Fatalf("updated button name = %q", got) + } + case <-time.After(time.Second): + t.Fatal("updated Gecko button name was not spoken") + } + select { + case frame := <-frames: + if frame.Text != "Open calendar button" { + t.Fatalf("updated button braille = %q", frame.Text) + } + case <-time.After(time.Second): + t.Fatal("updated Gecko button name did not refresh braille") + } +} + +func TestReusedTableRowSelectionReadsChangedMessage(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(done) + }() + defer func() { cancel(); <-done }() + + row := atspi.NewSnapshot("/mail/list/row", "First message", "table row", "", "") + row.ToolkitName = "Gecko" + adapter.events <- atspi.NewEvent(atspi.FocusEvent, row) + if got := <-speech.spoken; got != "First message, table row" { + t.Fatalf("first message = %q", got) + } + selected := atspi.NewManagedDescendantEvent(atspi.SelectionChangedEvent, "/mail/list", row) + adapter.events <- selected + + replacement := row + replacement.Name = "Next message" + adapter.events <- atspi.NewManagedDescendantEvent(atspi.SelectionChangedEvent, "/mail/list", replacement) + select { + case got := <-speech.spoken: + if got != "Next message, table row" { + t.Fatalf("replacement message = %q", got) + } + case <-time.After(time.Second): + t.Fatal("replacement table row was not spoken") + } + + third := replacement + third.Name = "Third message" + adapter.events <- atspi.NewEvent(atspi.AccessibleNameEvent, third) + select { + case got := <-speech.spoken: + if got != "Third message, table row" { + t.Fatalf("renamed message = %q", got) + } + case <-time.After(time.Second): + t.Fatal("renamed table row was not spoken") + } +} + +func TestFileManagerStatusFallbackRequiresOwnedUnnamedNavigationFocus(t *testing.T) { + window := atspi.NewObjectID(":1.45", "/thunar/window") + owner := windowOwner{applicationBus: window.BusName, window: window} + status := atspi.NewSnapshot("/thunar/status", `"Beta" | 0 bytes`, "status bar", "", "") + status.BusName = window.BusName + status.ApplicationName = "thunar" + event := atspi.NewEvent(atspi.AccessibleNameEvent, status) + event.Window = window + panel := atspi.NewSnapshot("/thunar/file-view", "", "panel", "", "") + if !shouldPresentFileManagerStatus(event, panel, owner, input.LineIntent) { + t.Fatal("selected-file status was lost while focus remained on the file-view panel") + } + event.Source.ApplicationName = "pcmanfm" + if !shouldPresentFileManagerStatus(event, panel, owner, input.LineIntent) { + t.Fatal("PCManFM icon selection status was lost while focus remained on its panel") + } + event.Source.ApplicationName = "thunar" + for _, test := range []struct { + name string + modify func(*atspi.Event, *atspi.Snapshot, *windowOwner) + intent input.Intent + }{ + {"no navigation key", nil, input.NoIntent}, + {"named file focus", func(_ *atspi.Event, focus *atspi.Snapshot, _ *windowOwner) { + focus.Role, focus.Name = "table cell", "Beta" + }, input.LineIntent}, + {"other window", func(event *atspi.Event, _ *atspi.Snapshot, _ *windowOwner) { + event.Window = atspi.NewObjectID(":1.45", "/other/window") + }, input.LineIntent}, + {"other application", func(event *atspi.Event, _ *atspi.Snapshot, _ *windowOwner) { event.Source.ApplicationName = "editor" }, input.LineIntent}, + {"empty status", func(event *atspi.Event, _ *atspi.Snapshot, _ *windowOwner) { event.Source.Name = "" }, input.LineIntent}, + } { + t.Run(test.name, func(t *testing.T) { + candidate, focus, active := event, panel, owner + if test.modify != nil { + test.modify(&candidate, &focus, &active) + } + if shouldPresentFileManagerStatus(candidate, focus, active, test.intent) { + t.Fatal("unrelated status change took over file navigation") + } + }) + } +} + +func TestProcessEventsSpeaksFileManagerSelectionStatusAfterPanelFocus(t *testing.T) { + for _, applicationName := range []string{"thunar", "pcmanfm"} { + t.Run(applicationName, func(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + ctx, cancel := context.WithCancel(context.Background()) + completed := make(chan struct{}) + go func() { + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), speech, adapter, nil, nil, 0, nil, + fixedInputActivity{input.Activity{Intent: input.LineIntent}}, nil, nil) + close(completed) + }() + defer func() { cancel(); <-completed }() + + frame := atspi.NewSnapshot("/thunar/window", "Thunar", "frame", "", "") + frame.BusName, frame.ApplicationName = ":1.45", applicationName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, frame) + activated.Window = frame.ID() + adapter.events <- activated + if got := <-speech.spoken; got != "Thunar, frame" { + t.Fatalf("window speech = %q", got) + } + panel := atspi.NewSnapshot("/thunar/file-view", "", "panel", "", "") + panel.BusName, panel.ApplicationName = frame.BusName, applicationName + focused := atspi.NewEvent(atspi.FocusedStateEvent, panel) + focused.Detail1, focused.Window = 1, frame.ID() + adapter.events <- focused + if got := <-speech.spoken; got != "panel" { + t.Fatalf("panel speech = %q", got) + } + status := atspi.NewSnapshot("/thunar/status", `"Beta" | 0 bytes`, "status bar", "", "") + status.BusName, status.ApplicationName = frame.BusName, applicationName + changed := atspi.NewEvent(atspi.AccessibleNameEvent, status) + changed.Window = frame.ID() + adapter.events <- changed + if got := <-speech.spoken; got != status.Name { + t.Fatalf("selected file speech = %q, want %q", got, status.Name) + } + adapter.events <- changed + select { + case got := <-speech.spoken: + t.Fatalf("duplicate status speech = %q", got) + case <-time.After(30 * time.Millisecond): + } + }) + } +} diff --git a/internal/app/event_gui_table_test.go b/internal/app/event_gui_table_test.go new file mode 100644 index 0000000..2c6a803 --- /dev/null +++ b/internal/app/event_gui_table_test.go @@ -0,0 +1,420 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +func TestNativeGUIListTableSpeech(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_GUI_LIST_TABLE") != "1" { + t.Skip("requires isolated GTK table with list role") + } + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + var entry atspi.Snapshot + var window atspi.ObjectID + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + pending := []atspi.ObjectReference{root} + for len(pending) > 0 { + reference := pending[len(pending)-1] + pending = pending[:len(pending)-1] + snapshot, err := tree.Resolve(reference) + if err != nil { + t.Fatal(err) + } + if snapshot.Name == "Command" { + entry = snapshot + } + if snapshot.Name == "Table presentation probe" { + window = snapshot.ID() + } + for child, ok, err := tree.FirstChild(reference); ; child, ok, err = tree.NextSibling(child) { + if err != nil { + t.Fatal(err) + } + if !ok { + break + } + pending = append(pending, child) + } + } + if !entry.ID().Valid() || !window.Valid() { + t.Fatal("launcher entry or window missing") + } + queue := &fakeSpeechQueue{spoken: make(chan string, 32), requests: make(chan speechRequest, 32)} + logger := slog.New(slog.DiscardHandler) + state := &eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + state.focusedID, state.current = entry.ID(), entry + presenter := eventPresenter{state: state, logger: logger, speech: queue} + handler := accessibilityEventHandler{state: state, logger: logger} + speaker := &fakeSpeaker{spoken: make(chan string, 64)} + worker := newSpeechWorker(logger, speaker) + worker.reading = func() config.ReadingSettings { return config.DefaultSettings().Reading } + worker.verbosity = func() int { return 1 } + activation := atspi.NewEvent(atspi.WindowActivatedEvent, entry) + activation.Window, activation.WindowTitle = window, "Table presentation probe" + activation.WindowDescription = "Select an item and press Enter to open it." + presenter.speak(activation) + deliver := func() { + t.Helper() + for len(queue.requests) > 0 { + if err := worker.deliver(ctx, <-queue.requests); err != nil { + t.Fatal(err) + } + } + } + deliver() + for index, step := range []struct{ key, name string }{{"Down", "Alpha"}, {"Down", "Beta"}, {"shift+Tab", "Command"}} { + if err := exec.Command("xdotool", "key", step.key).Run(); err != nil { + t.Fatal(err) + } + matched: + for { + select { + case <-ctx.Done(): + t.Fatalf("no focus/selection for %s", step.name) + case event := <-adapter.Events(): + if !isFocusGainEvent(event) && !isManagedDescendantEvent(event.Type) { + continue + } + if !handler.acceptFocusedEvent(event, input.Activity{Sequence: uint64(index + 1)}) { + presenter.speak(event) + } + deliver() + if event.Source.Name == step.name { + break matched + } + } + } + } + var parts []string + for len(speaker.spoken) > 0 { + parts = append(parts, <-speaker.spoken) + } + text := strings.Join(parts, " | ") + t.Log(text) + if strings.Count(text, activation.WindowDescription) != 1 || strings.Contains(text, "Leaving ") || + strings.Count(text, "Alpha") != 1 || strings.Count(text, "Beta") != 1 || strings.Count(text, "Probe items") != 1 { + t.Fatalf("unexpected launcher speech: %s", text) + } +} + +func TestGUIListTableNameWithoutBrowseContext(t *testing.T) { + for _, contextEnabled := range []bool{true, false} { + state := &eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + reading := config.DefaultSettings().Reading + reading.SpeakContextList = contextEnabled + state.presentationOptions.Reading = &reading + list := atspi.Snapshot{BusName: ":1.24", Path: "/results", Role: "list", Name: "Results"} + cell := atspi.Snapshot{BusName: list.BusName, Path: "/results/alpha", Name: "Alpha", Role: "table cell", + GUITable: true, TablePath: list.Path, TableName: list.Name, SpeechContext: []atspi.Snapshot{list}} + event := atspi.NewManagedDescendantEvent(atspi.SelectionChangedEvent, list.Path, cell) + result := state.prepareGUITable(event, 1) + spoken, _ := state.decorateGUITable(event, presentation.Speech{Text: "Alpha"}, result) + want := "Results, Alpha" + if spoken.Text != want { + t.Fatalf("list context enabled=%t: got %q, want %q", contextEnabled, spoken.Text, want) + } + } +} + +func TestTableDescriptionAlreadyReadWithEntryActivation(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 8), requests: make(chan speechRequest, 8)} + state := &eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + presenter := eventPresenter{state: state, logger: slog.New(slog.DiscardHandler), speech: queue} + window := atspi.NewObjectID(":1.24", "/launcher") + entry := atspi.NewSnapshot("/launcher/entry", "Command", "text", "", "") + entry.BusName = window.BusName + event := atspi.NewEvent(atspi.WindowActivatedEvent, entry) + event.Window, event.WindowTitle = window, "Launcher" + event.WindowDescription = "Choose a result and press Enter." + presenter.speak(event) + if got := (<-queue.requests).Text; got != "Launcher, Command, text, Choose a result and press Enter." { + t.Fatalf("entry activation = %q", got) + } + cell := atspi.NewSnapshot("/launcher/results/alpha", "Alpha", "table cell", "", "") + cell.BusName = window.BusName + event.Type, event.Source = atspi.SelectionChangedEvent, cell + presenter.speak(event) + if got := (<-queue.requests).Text; got != "Alpha" { + t.Fatalf("first result repeated window description: %q", got) + } + // Changed help and help in another window must still be presented. + event.WindowDescription = "Updated result help." + presenter.speak(event) + if got := (<-queue.requests).Text; got != "Alpha, Updated result help." { + t.Fatalf("changed description = %q", got) + } + event.Window = atspi.NewObjectID(window.BusName, "/other") + event.Source.Path = "/other/results/alpha" + presenter.speak(event) + if got := (<-queue.requests).Text; got != "Alpha, Updated result help." { + t.Fatalf("other window description = %q", got) + } + // Opening with descriptions disabled must not consume help which becomes + // enabled before the user enters the results. + state.presentationOptions.SpeakDescription = false + event.Type, event.Source, event.Window = atspi.WindowActivatedEvent, entry, window + presenter.speak(event) + <-queue.requests + state.presentationOptions.SpeakDescription = true + event.Type, event.Source = atspi.SelectionChangedEvent, cell + presenter.speak(event) + if got := (<-queue.requests).Text; got != "Alpha, Updated result help." { + t.Fatalf("newly enabled description = %q", got) + } +} + +func TestTableWindowDescriptionSurvivesImmediateTableFocus(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3), requests: make(chan speechRequest, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + window := atspi.NewObjectID(":1.20", "/desktop") + cell := atspi.NewSnapshot("/desktop/table/item", "Alpha", "table cell", "", "") + cell.BusName = window.BusName + cell.TableName = "Desktop items" + cell.TableRowCount, cell.TableColumnCount = 2, 2 + cell.TableRowText, cell.GUITable = "Alpha, Document", true + activated := atspi.NewEvent(atspi.WindowActivatedEvent, cell) + activated.Window = window + activated.WindowTitle = "Desktop" + activated.WindowDescription = "Select an item and press Enter to open it." + adapter.events <- activated + table := atspi.NewSnapshot("/desktop/table", "Desktop items", "table", "", "") + table.BusName = window.BusName + table.TableRowCount, table.TableColumnCount = 2, 2 + focused := atspi.NewEvent(atspi.FocusedStateEvent, table) + focused.Window = window + focused.Detail1 = 1 + adapter.events <- focused + for index, expected := range []struct { + text string + append bool + }{ + {"Desktop, Desktop items, table with 2 rows 2 columns, Alpha, Document, Select an item and press Enter to open it.", false}, + {"Desktop items, table with 2 rows 2 columns", true}, + } { + select { + case request := <-speech.requests: + if request.Text != expected.text || request.Append != expected.append { + t.Fatalf("request %d = %q append %t, want %q append %t", index, request.Text, request.Append, expected.text, expected.append) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for request %d", index) + } + } + cancel() + <-completed +} + +func TestTableDescriptionArrivingAfterActivation(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3), requests: make(chan speechRequest, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + window := atspi.NewObjectID(":1.21", "/desktop") + table := atspi.NewSnapshot("/desktop/table", "Desktop items", "table", "", "") + table.BusName = window.BusName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, table) + activated.Window = window + activated.WindowTitle = "Desktop" + adapter.events <- activated + first := <-speech.requests + if first.Text != "Desktop, Desktop items, table" { + t.Fatalf("activation = %q", first.Text) + } + table.TableRowCount, table.TableColumnCount = 2, 2 + focused := atspi.NewEvent(atspi.FocusedStateEvent, table) + focused.Window = window + focused.WindowDescription = "Select an item and press Enter to open it." + focused.Detail1 = 1 + adapter.events <- focused + second := <-speech.requests + if second.Text != "Desktop items, table with 2 rows 2 columns, Select an item and press Enter to open it." { + t.Fatalf("focused table = %q", second.Text) + } + cell := atspi.NewSnapshot("/desktop/table/first", "Alpha", "table cell", "", "") + cell.BusName = window.BusName + cell.TablePath = table.Path + cell.TableRowText, cell.GUITable = "Alpha, Document", true + cell.TablePositionKnown = true + third := atspi.NewEvent(atspi.FocusedStateEvent, cell) + third.Window = window + third.Detail1 = 1 + adapter.events <- third + request := <-speech.requests + if request.Text != "Alpha, Document" || !request.Append { + t.Fatalf("following cell = %q append %t", request.Text, request.Append) + } + cancel() + <-completed +} + +func TestGUITableHorizontalMovementReadsOneCell(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 8), requests: make(chan speechRequest, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + inputs := &sequencedInputActivity{} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), speech, adapter, + nil, nil, 0, nil, inputs, nil, nil) + close(completed) + }() + window := atspi.NewObjectID(":1.22", "/desktop") + table := atspi.NewSnapshot("/desktop/table", "Desktop items", "table", "", "") + table.BusName = window.BusName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, table) + activated.Window = window + adapter.events <- activated + <-speech.requests + cellEvent := func(path, name, rowText string, row, column int, eventType string) atspi.Event { + cell := atspi.NewSnapshot(path, name, "table cell", "", "") + cell.BusName = window.BusName + cell.TablePath = table.Path + cell.TableRowIndex, cell.TableColumnIndex = row, column + cell.TablePositionKnown, cell.GUITable = true, true + cell.TableRowText = rowText + event := atspi.NewManagedDescendantEvent(eventType, table.Path, cell) + event.Window = window + return event + } + for _, step := range []struct { + sequence uint64 + event atspi.Event + want string + }{ + {1, cellEvent("/desktop/table/alpha", "Alpha", "Alpha, Document", 0, 0, atspi.SelectionChangedEvent), "Alpha, Document"}, + {2, cellEvent("/desktop/table/document", "Document", "Alpha, Document", 0, 1, atspi.ActiveDescendantEvent), "Document"}, + {3, cellEvent("/desktop/table/alpha", "Alpha", "Alpha, Document", 0, 0, atspi.ActiveDescendantEvent), "Alpha"}, + {4, cellEvent("/desktop/table/beta", "Beta", "Beta, Shortcut", 1, 0, atspi.SelectionChangedEvent), "Beta, Shortcut"}, + {4, cellEvent("/desktop/table/replacement", "Renamed", "Renamed, Shortcut", 1, 0, atspi.ActiveDescendantEvent), "Renamed"}, + } { + inputs.set(step.sequence) + adapter.events <- step.event + select { + case request := <-speech.requests: + if request.Text != step.want { + t.Fatalf("sequence %d = %q, want %q", step.sequence, request.Text, step.want) + } + case <-time.After(time.Second): + t.Fatalf("sequence %d produced no speech", step.sequence) + } + } + cancel() + <-completed +} + +func TestGUITableReusedCurrentCellReadsReplacementRow(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 4), requests: make(chan speechRequest, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + defer func() { cancel(); <-completed }() + + cell := atspi.NewSnapshot("/mail/messages/row", "First subject", "table cell", "", "") + cell.BusName = ":1.23" + cell.TablePath = "/mail/messages" + cell.TableRowIndex, cell.TableColumnIndex = 0, 0 + cell.TablePositionKnown, cell.GUITable = true, true + cell.TableRowText = "First subject, First sender" + focus := atspi.NewEvent(atspi.FocusedStateEvent, cell) + focus.Detail1 = 1 + adapter.events <- focus + if got := (<-speech.requests).Text; got != cell.TableRowText { + t.Fatalf("initial row = %q", got) + } + + replacement := cell + replacement.Name = "Next subject" + replacement.TableRowText = "Next subject, Next sender" + selected := atspi.NewManagedDescendantEvent(atspi.SelectionChangedEvent, cell.TablePath, replacement) + adapter.events <- selected + select { + case request := <-speech.requests: + if request.Text != replacement.TableRowText { + t.Fatalf("replacement row = %q, want %q", request.Text, replacement.TableRowText) + } + case <-time.After(time.Second): + t.Fatal("replacement row was not spoken") + } + + // A name event is another way a provider can expose a reused row. + third := replacement + third.Name = "Third subject" + third.TableRowText = "Third subject, Third sender" + nameChanged := atspi.NewEvent(atspi.AccessibleNameEvent, third) + adapter.events <- nameChanged + select { + case request := <-speech.requests: + if request.Text != third.TableRowText { + t.Fatalf("renamed row = %q, want %q", request.Text, third.TableRowText) + } + case <-time.After(time.Second): + t.Fatal("renamed current row was not spoken") + } +} diff --git a/internal/app/event_lifecycle.go b/internal/app/event_lifecycle.go new file mode 100644 index 0000000..7bb5c62 --- /dev/null +++ b/internal/app/event_lifecycle.go @@ -0,0 +1,161 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// handleLifecycle returns true when window or document lifecycle consumes an event. +func (handler *accessibilityEventHandler) handleLifecycle(event atspi.Event) bool { + state := handler.state + logger := handler.logger + speech := handler.speech + browser := handler.browser + objectReview := handler.objectReview + focusGate := handler.focusGate + clearOwnedFocus := handler.clearOwnedFocus + if event.Type == atspi.WindowActivatedEvent && strings.TrimSpace(event.WindowTitle) == speechHistoryWindowTitle { + state.historyWindow = eventWindow(event) + } + if event.Type == atspi.WindowDeactivatedEvent || event.Type == atspi.WindowDestroyedEvent { + recentCommand := browser != nil && browser.recentConsumedCommand() + if transientForegroundDeactivation(event, state.foregroundState) { + // Native correlation, not a time heuristic, confirms that + // this is still the actual foreground client. + recentCommand = true + } + if state.owner.end(event, recentCommand) { + clearOwnedFocus() + logger.Debug("cleared accessible window ownership", "type", event.Type, "application", event.Source.ApplicationName, "bus", event.Window.BusName, "window_path", event.Window.Path) + } else { + logger.Debug("ignored unrelated or transient window lifecycle", "type", event.Type, "application", event.Source.ApplicationName, "bus", event.Window.BusName, "window_path", event.Window.Path) + } + return true + } + if event.Type == atspi.DefunctStateEvent { + windowEnded, focusEnded := state.owner.defunct(event) + if focusEnded { + clearOwnedFocus() + logger.Debug("cleared defunct accessibility ownership", "window_ended", windowEnded, "application", event.Source.ApplicationName, "bus", event.Source.BusName, "source_path", event.Source.Path) + } + return true + } + if browser != nil && !focusGate.Suspended() && + (event.Type == atspi.DocumentReloadEvent || event.Type == atspi.DocumentLoadStoppedEvent || event.Type == atspi.BusyStateEvent) { + if !state.owner.containsLoad(event) { + logger.Debug("ignored document lifecycle outside owned focus", "type", event.Type, + "bus", event.Source.BusName, "window_path", event.Window.Path) + return true + } + if event.FocusOutsideDocument.Valid() { + logger.Debug("kept browser chrome focus during document lifecycle", "type", event.Type) + return true + } + if event.Type == atspi.BusyStateEvent && event.Detail1 == 0 && + state.chromeLoadedDocument == event.Source.ID() && state.chromeLoadedWindow == eventWindow(event) && + state.owner.focus.Valid() && state.owner.focus != event.Source.ID() && + !(browser.ready && browser.document == event.Source.ID()) { + logger.Debug("kept verified chrome focus during document completion") + return true + } + if event.Type == atspi.DocumentReloadEvent || event.Type == atspi.BusyStateEvent && event.Detail1 != 0 { + if state.loadingDocument != event.Source.ID() { + state.loadingDocument = event.Source.ID() + state.loadedDocument = atspi.ObjectID{} + if event.Type == atspi.BusyStateEvent { + speech.Enqueue(speechRequest{Text: "Loading. Please wait.", Role: "system", Cause: "document-loading"}) + } + } + browser.loading() + if objectReview != nil { + objectReview.ResetDocument(event.Source.ID()) + } + } else { + state.pending.caret.clear() + state.documentLineFocus = atspi.ObjectID{} + state.documentLineRequest = 0 + state.documentLineEvent = atspi.Event{} + if state.loadedDocument != event.Source.ID() { + state.lastSpokenPath, state.lastSpokenText, state.lastSound = "", "", "" + } + state.owner.follow(event) + state.current = event.Source + state.focusedID = event.Source.ID() + if event.Type == atspi.BusyStateEvent && state.loadedDocument != event.Source.ID() { + speech.Enqueue(speechRequest{Text: finishedLoadingText(event.Source.Name), Role: "system", Cause: "document-loaded", Append: true}) + state.loadedDocument = event.Source.ID() + } + state.loadingDocument = atspi.ObjectID{} + browser.loaded(event.Source.ID()) + if objectReview != nil { + objectReview.ResetDocument(event.Source.ID()) + } + } + return true + } + if event.Type == atspi.DocumentLoadCompleteEvent && browser != nil && !focusGate.Suspended() { + if !state.owner.containsLoad(event) { + logger.Debug("ignored document load outside owned focus", "bus", event.Source.BusName, "window_path", event.Window.Path) + return true + } + alreadyAnnounced := state.loadedDocument == event.Source.ID() && state.loadingDocument != event.Source.ID() + state.pending.caret.clear() + state.documentLineFocus = atspi.ObjectID{} + state.documentLineRequest = 0 + state.documentLineEvent = atspi.Event{} + if !alreadyAnnounced { + state.lastSpokenPath, state.lastSpokenText, state.lastSound = "", "", "" + } + if event.FocusOutsideDocument.Valid() { + state.chromeLoadedDocument = event.Source.ID() + state.chromeLoadedWindow = eventWindow(event) + browser.loaded(event.FocusOutsideDocument) + if objectReview != nil { + objectReview.ResetDocument(event.FocusOutsideDocument) + } + logger.Debug("kept browser chrome focus during document load") + return true + } + state.chromeLoadedDocument = atspi.ObjectID{} + state.chromeLoadedWindow = atspi.ObjectID{} + state.owner.follow(event) + state.current = event.Source + state.focusedID = event.Source.ID() + browser.loaded(event.Source.ID()) + if objectReview != nil { + objectReview.ResetDocument(event.Source.ID()) + if event.DocumentFragment != "" { + if err := objectReview.JumpToDocumentFragment(event.DocumentFragment); err != nil { + logger.Warn("queue document fragment navigation", "error", err) + } + } + } + if !alreadyAnnounced { + speech.Enqueue(speechRequest{Text: finishedLoadingText(event.Source.Name), Role: "system", Cause: "document-loaded", Append: true}) + } + state.loadingDocument = atspi.ObjectID{} + state.loadedDocument = event.Source.ID() + return true + } + return false +} + +// Keyboard grabs can make GTK emit deactivate/activate while X11 still owns +// the same foreground client. Native correlation is stronger than a timer. +func transientForegroundDeactivation(event atspi.Event, foreground atspi.ForegroundState) bool { + return event.Type == atspi.WindowDeactivatedEvent && !event.ForegroundMismatch && foreground.Client.Known && foreground.Client.Window != 0 +} + +func finishedLoadingText(name string) string { + name = strings.TrimSpace(name) + if name == "" { + return "Finished loading." + } + return "Finished loading " + name + "." +} diff --git a/internal/app/event_loop.go b/internal/app/event_loop.go new file mode 100644 index 0000000..36e97e0 --- /dev/null +++ b/internal/app/event_loop.go @@ -0,0 +1,354 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/notification" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func processEvents( + ctx context.Context, + logger *slog.Logger, + speech speechEnqueuer, + adapter Adapter, + debounce time.Duration, + configuredPresentation ...presentation.Options, +) error { + return processEventsWithReview(ctx, logger, speech, adapter, nil, debounce, configuredPresentation...) +} + +func processEventsWithReview( + ctx context.Context, + logger *slog.Logger, + speech speechEnqueuer, + adapter Adapter, + reviewRequests <-chan input.Command, + debounce time.Duration, + configuredPresentation ...presentation.Options, +) error { + return processEventsWithObjectReview(ctx, logger, speech, adapter, reviewRequests, nil, debounce, configuredPresentation...) +} + +func processEventsWithObjectReview( + ctx context.Context, + logger *slog.Logger, + speech speechEnqueuer, + adapter Adapter, + reviewRequests <-chan input.Command, + objectReview *review.Worker, + debounce time.Duration, + configuredPresentation ...presentation.Options, +) error { + return processEventsWithSettings(ctx, logger, speech, adapter, reviewRequests, objectReview, debounce, nil, configuredPresentation...) +} + +func processEventsWithSettings( + ctx context.Context, + logger *slog.Logger, + speech speechEnqueuer, + adapter Adapter, + reviewRequests <-chan input.Command, + objectReview *review.Worker, + debounce time.Duration, + live *liveSettings, + configuredPresentation ...presentation.Options, +) error { + return processEventsWithInput(ctx, logger, speech, adapter, reviewRequests, objectReview, debounce, live, nil, nil, nil, configuredPresentation...) +} + +func processEventsWithInput( + ctx context.Context, + logger *slog.Logger, + speech speechEnqueuer, + adapter Adapter, + reviewRequests <-chan input.Command, + objectReview *review.Worker, + debounce time.Duration, + live *liveSettings, + inputSource any, + focusGate *focusGate, + notifications *notification.Presenter, + configuredPresentation ...presentation.Options, +) error { + return processEventsWithOCR(ctx, logger, speech, adapter, reviewRequests, objectReview, debounce, live, inputSource, focusGate, notifications, nil, configuredPresentation...) +} + +func processEventsWithOCR( + ctx context.Context, + logger *slog.Logger, + speech speechEnqueuer, + adapter Adapter, + reviewRequests <-chan input.Command, + objectReview *review.Worker, + debounce time.Duration, + live *liveSettings, + inputSource any, + focusGate *focusGate, + notifications *notification.Presenter, + ocrSession *ocrSession, + configuredPresentation ...presentation.Options, +) error { + return processEventsWithAttributes(ctx, logger, speech, adapter, reviewRequests, nil, objectReview, debounce, live, inputSource, focusGate, notifications, ocrSession, configuredPresentation...) +} + +func processEventsWithAttributes( + ctx context.Context, + logger *slog.Logger, + speech speechEnqueuer, + adapter Adapter, + reviewRequests <-chan input.Command, + attributeRequests <-chan struct{}, + objectReview *review.Worker, + debounce time.Duration, + live *liveSettings, + inputSource any, + focusGate *focusGate, + notifications *notification.Presenter, + ocrSession *ocrSession, + configuredPresentation ...presentation.Options, +) error { + attributes := startCharacterAttributeReader(ctx, adapter) + defer attributes.stop() + if notifications == nil { + notifications = notification.NewPresenter() + } + state := eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + if len(configuredPresentation) != 0 { + state.presentationOptions = configuredPresentation[0] + } + var brailleOutput brailleFrameEnqueuer + if queue, ok := speech.(outputQueue); ok { + brailleOutput = queue.braille + } + webScripts := &webScriptController{speech: speech, notifications: notifications, live: live, gate: focusGate} + webScripts.braille, _ = brailleOutput.(interface { + Flash(string, config.BrailleOptions) bool + }) + defer webScripts.reset() + logger.Info("listening for focus events") + browser, _ := inputSource.(*browserModeController) + var modeResults <-chan browserModeResult + var modeToggles <-chan input.Command + if browser != nil { + modeResults = browser.results + modeToggles = browser.toggles + } + foreground, _ := adapter.(foregroundMonitor) + var foregroundChanges <-chan struct{} + if foreground != nil { + foregroundChanges = foreground.ForegroundChanges() + state.foregroundState = foreground.Foreground() + } + titles := &windowTitleController{state: &state, live: live, gate: focusGate, speech: speech, logger: logger, foreground: foreground, inputSource: inputSource} + titles.source, _ = adapter.(windowTitleSource) + var titleChanges <-chan struct{} + if titles.source != nil { + titleChanges = titles.source.TitleChanges() + titles.nativeChanged() + } + var wineTitles <-chan wineWindowTitle + if live != nil { + wineTitles = live.wineTitles + } + defer titles.reset() + defer state.pending.clear() + var objectReviewResults <-chan review.Result + if objectReview != nil { + objectReviewResults = objectReview.Results() + } + + presenter := eventPresenter{ + state: &state, logger: logger, speech: speech, foreground: foreground, + inputSource: inputSource, live: live, browser: browser, + } + speak := presenter.speak + flushTerminalDeletion := func() { + if state.pending.terminalDeletion.event.Type == "" { + return + } + event, _ := state.pending.terminalDeletion.take() + speak(event) + } + clearObjectFocus := func() { + ocrSession.Retire() + state.clearOwnedFocus(brailleOutput, browser, objectReview, speech) + } + clearOwnedFocus := func() { + titles.reset() + clearObjectFocus() + } + var wineReview *wineReviewFocusController + var wineReviewChanges <-chan struct{} + if live != nil && live.wineReview != nil { + // Wine control revisions reset object review, but a pending title and + // its duplicate history belong to the foreground window's lifetime. + // These notices carry metadata, not an instruction to stop speech. + // User input owns speech cancellation; metadata changes preserve it. + clearWineReviewFocus := func() { + ocrSession.Retire() + state.clearObjectFocus(brailleOutput, browser, objectReview) + } + wineReview = &wineReviewFocusController{registry: live.wineReview, logger: logger, state: &state, foreground: foreground, titles: titles.source, gate: focusGate, worker: objectReview, clear: clearWineReviewFocus} + wineReviewChanges = live.wineReview.Changes() + wineReview.changed() + defer wineReview.retire() + } + syncForeground := func() { + state.syncForeground(foreground, logger, clearOwnedFocus) + if wineReview != nil { + wineReview.foregroundChanged() + } + } + reviewHandler := eventReviewHandler{ + state: &state, logger: logger, speech: speech, objectReview: objectReview, + browser: browser, brailleOutput: brailleOutput, live: live, + focusGate: focusGate, syncForeground: syncForeground, speak: speak, + wineReview: wineReview, + } + reviewHandler.calcHeaders, _ = adapter.(libreOfficeHeaderConfigurer) + eventHandler := accessibilityEventHandler{ + state: &state, titles: titles, logger: logger, speech: speech, adapter: adapter, + objectReview: objectReview, browser: browser, inputSource: inputSource, + focusGate: focusGate, notifications: notifications, live: live, + brailleOutput: brailleOutput, foreground: foreground, debounce: debounce, + clearOwnedFocus: clearOwnedFocus, syncForeground: syncForeground, + flushTerminalDeletion: flushTerminalDeletion, speak: speak, webScripts: webScripts, + wineReview: wineReview, + } + + var lockChanges <-chan struct{} + if focusGate != nil { + lockChanges = focusGate.lockChanges + } + for { + select { + case <-ctx.Done(): + return nil + case <-lockChanges: + if wineReview != nil { + wineReview.retire() + } + webScripts.reset() + state.owner.clear() + clearOwnedFocus() + case <-wineReviewChanges: + syncForeground() + case <-webScripts.due: + webScripts.flush() + case <-foregroundChanges: + focusGate.retireTentacleOutput() + ocrSession.ForegroundChanged() + syncForeground() + if titles.source != nil { + titles.nativeChanged() + } + case <-titleChanges: + focusGate.retireTentacleOutput() + syncForeground() + titles.nativeChanged() + case update := <-wineTitles: + syncForeground() + titles.wineChanged(update) + case <-titles.due: + syncForeground() + titles.flush() + case result := <-modeResults: + focusGate.retireTentacleOutput() + if focusGate.Locked() { + continue + } + syncForeground() + if result.err != nil { + logger.Debug("browser mode outside web document", "reason", result.err) + } + browser.accept(result, speech) + case command := <-modeToggles: + focusGate.retireTentacleOutput() + if focusGate.Locked() { + continue + } + syncForeground() + switch command { + case input.StickyFocusMode: + browser.sticky(review.FocusMode, speech) + case input.StickyBrowseMode: + browser.sticky(review.BrowseMode, speech) + default: + browser.toggle(speech) + } + case event, ok := <-adapter.Events(): + focusGate.retireTentacleOutput() + if !ok { + return nil + } + if !ocrSession.Observe(event) { + eventHandler.handle(event) + } + case <-state.pending.browserButtonName.ready: + syncForeground() + eventHandler.flush_browser_button_name() + case <-state.pending.radioSound.ready: + syncForeground() + presenter.flush_radio_sound(focusGate) + case <-state.pending.caret.ready: + if focusGate.Locked() { + state.pending.clear() + continue + } + event, intent := state.pending.caret.take() + speak(event, intent) + case <-state.pending.terminalFocus.ready: + if focusGate.Locked() { + state.pending.clear() + continue + } + event, _ := state.pending.terminalFocus.take() + speak(event) + case <-state.pending.terminalDeletion.ready: + if focusGate.Locked() { + state.pending.clear() + continue + } + event, _ := state.pending.terminalDeletion.take() + speak(event) + case command := <-reviewRequests: + switch command { + case input.PresentCurrentLine, input.SpellCurrentLine, input.PhoneticCurrentLine: + reviewHandler.current_line(command) + case input.PresentWindowTitle: + syncForeground() + titles.present() + case input.PresentCellFormula: + reviewHandler.presentCellFormula() + case input.SetColumnHeadersRow, input.ClearColumnHeadersRow, input.SetRowHeadersColumn, input.ClearRowHeadersColumn: + reviewHandler.configureCalcHeader(command) + default: + reviewHandler.whereAmI() + } + case <-attributeRequests: + if !focusGate.Locked() { + syncForeground() + attributes.request(state.current.ID(), recentInput(inputSource).Sequence) + } + case result := <-attributes.results: + if !focusGate.Locked() && result.object == state.current.ID() && result.object.Valid() && result.sequence == recentInput(inputSource).Sequence { + settings := live.Load() + presentCharacterAttributes(speech, result, settings.Reading.UseColorNames, settings.TextAttributes) + } + case result := <-objectReviewResults: + reviewHandler.handle(result) + } + } +} diff --git a/internal/app/event_navigation_filters.go b/internal/app/event_navigation_filters.go new file mode 100644 index 0000000..26aa87d --- /dev/null +++ b/internal/app/event_navigation_filters.go @@ -0,0 +1,90 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// filterNavigationAndNames runs after selected-tab presentation and before +// autocomplete, terminal coalescing, or focus/text presentation. +func (handler *accessibilityEventHandler) filterNavigationAndNames(event atspi.Event, activity input.Activity, intent input.Intent) bool { + state := handler.state + logger := handler.logger + browser := handler.browser + ownedAutocompletePopup := state.ownedAutocompletePopup + // A suggestion popup may clear the entry's native focused bit. + // Preserve user edits in the owned entry, but reject background + // URL rewrites unless input confirms an edit in the owned entry. + if isTextChangeEvent(event.Type) && event.Source.Autocomplete && + (event.Source.ID() != state.focusedID || + intent != input.TypingIntent && intent != input.DeleteIntent && + activity.Clipboard != input.PasteAction && activity.Clipboard != input.CutAction) { + logger.Debug("skipped autocomplete text change without owned edit", "type", event.Type) + return true + } + if browser != nil && event.Type == atspi.CaretEvent && !event.Source.Editable && + state.current.Editable && event.Source.ID() != state.current.ID() && + !(browser.ready && browser.mode == review.BrowseMode) { + // Chromium can deliver a queued document caret after focus has + // moved to the address bar or an entry. It must not reacquire + // browse grabs while the user is typing in that control. + logger.Debug("skipped document caret after editable focus", "role", event.Source.Role) + return true + } + if handler.titles.accessible(event) { + return true + } + if isBrowserUINameNoise(event, state.current) { + logger.Debug("skipped browser UI name event", "type", event.Type, "role", event.Source.Role) + return true + } + if event.Type == atspi.AccessibleNameEvent && event.Source.Role == "table cell" && + (!event.Source.GUITable || event.Source.ID() != state.focusedID && event.Source.ID() != state.managedDescendantID || + sameManagedDescendant(event.Source, state.current)) { + // Ignore unchanged or background cells, including relative timestamps + // in old feed rows. A reused current row needs its new content read. + logger.Debug("skipped table cell name event") + return true + } + // Python presents ordinary name changes only for the locus of focus. + // Containers and status bars can rename on every file selection; + // presenting those updates would interrupt the focused file name. + // Thunar's unnamed-panel selection fallback is handled above. + if event.Type == atspi.AccessibleNameEvent && + !event.Source.LiveRegion && event.Source.ID() != state.focusedID && + !(presentsReusedRow(event.Source) && event.Source.ID() == state.managedDescendantID) { + logger.Debug("skipped name change outside focused object", "role", event.Source.Role) + return true + } + if browser != nil && browser.suppressNavigationEcho(event) { + logger.Debug("skipped structural navigation echo", "type", event.Type, "role", event.Source.Role) + return true + } + retainBrowseCaret := browser != nil && browser.ready && browser.mode == review.BrowseMode && + event.Type != atspi.WindowActivatedEvent && !isMenuRole(event.Source.Role) && + isFocusEvent(event.Type) && !event.Source.Editable && + (!atspi.IsWebDocumentRole(event.Source.Role) || event.Source.ID() == browser.document) && + (atspi.IsWebDocumentRole(event.Source.Role) || !event.Source.Focusable || + intent == input.LineIntent || intent == input.WordIntent || intent == input.CharacterIntent) + if retainBrowseCaret { + // Chromium can re-emit its retained DOM focus after native caret + // movement. Python keeps the independent browse caret in this case; + // following the delayed focus would briefly release the browse grabs + // and reset structural navigation to the old focused object. + logger.Debug("skipped retained browser focus during caret navigation", "role", event.Source.Role) + return true + } + if browser != nil && isFocusEvent(event.Type) && !ownedAutocompletePopup(event) { + browser.nativeButtonFocus(isFocusGainEvent(event) && (event.Source.Role == "button" || event.Source.Role == "push button" || event.Source.Role == "toggle button")) + browser.follow(event.Source.ID()) + } else if browser != nil && event.Type == atspi.CaretEvent && !event.Source.Editable { + browser.followCaret(event.Source.ID()) + } + return false +} diff --git a/internal/app/event_notification.go b/internal/app/event_notification.go new file mode 100644 index 0000000..246188b --- /dev/null +++ b/internal/app/event_notification.go @@ -0,0 +1,126 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strconv" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/notification" +) + +func presentNotifications(speech speechEnqueuer, messages []string) { + for _, message := range messages { + // Notifications remain audible while XTerm owns keyboard handling. + // The output gate still rejects these requests during screen lock. + speech.Enqueue(speechRequest{Text: message, Role: "system", Cause: "notifications", BypassFocusGate: true}) + } +} + +type notificationAnnouncer struct { + presenter *notification.Presenter + speech speechEnqueuer + braille interface { + Flash(string, config.BrailleOptions) bool + } + live *liveSettings +} + +func (announcer *notificationAnnouncer) Announce(entry notification.Entry) { + if announcer.braille != nil && announcer.live != nil { + options := announcer.live.Load().Braille + message := entry.Message + if !options.FlashDetailed && entry.Summary != "" { + message = entry.Summary + } + announcer.braille.Flash(message, options) + } + announcer.presenter.Save(entry.Message, notification.SaveOptions{ + Source: entry.Source, + SourceGeneration: entry.SourceGeneration, + NotificationID: entry.NotificationID, + Live: entry.Live, + Actions: entry.Actions, + AppName: entry.AppName, + Summary: entry.Summary, + Body: entry.Body, + Urgency: entry.Urgency, + DesktopEntry: entry.DesktopEntry, + }) + message := entry.Message + if announcer.live != nil && !announcer.live.Load().Reading.MessagesAreDetailed && entry.Summary != "" { + message = entry.Summary + } + announcer.speech.Enqueue(speechRequest{ + Text: message, Role: "system", Cause: "mako-notification", + }) +} + +func notificationEvent(event atspi.Event) (string, []string, bool, bool) { + applicationName := strings.ToLower(event.Source.ApplicationName) + if event.Type == atspi.WindowCreateEvent { + switch applicationName { + case "notification-daemon", "mate-notification-daemon", "xfce4-notifyd": + message := notification.MessageNotification + if event.Source.Text != "" { + message += " " + event.Source.Text + } + return message, []string{message}, true, true + } + } + + if applicationName == "notify-osd" { + if event.Type == atspi.AccessibleNameEvent { + message := event.Source.Name + " " + event.Source.Description + if !event.Source.ValueKnown || event.Source.CurrentValue < 0 { + return message, []string{notification.MessageNotification, message}, true, true + } + message = event.Source.Name + " " + strconv.Itoa(int(event.Source.CurrentValue)) + return message, []string{message, message}, true, true + } + if event.Type == atspi.ValueChangedEvent || event.Type == atspi.AccessibleValueEvent { + if !event.Source.ValueKnown || event.Source.CurrentValue < 0 { + return "", nil, false, false + } + value := strconv.Itoa(int(event.Source.CurrentValue)) + return value, []string{value}, true, false + } + } + + if event.Type == atspi.ShowingStateEvent && + strings.EqualFold(event.Source.Role, "notification") && event.Detail1 != 0 { + return notificationContent(event.Source), nil, false, true + } + return "", nil, false, false +} + +func notificationContent(snapshot atspi.Snapshot) string { + parts := []string{snapshot.Name} + if snapshot.Text != "" && snapshot.Text != snapshot.Name { + parts = append(parts, snapshot.Text) + } + if len(parts) == 1 && parts[0] == "" && snapshot.Description != "" { + parts = []string{snapshot.Description} + } + var content []string + for _, part := range parts { + if part != "" && !containsString(content, part) { + content = append(content, part) + } + } + return strings.Join(content, " ") +} + +func containsString(values []string, candidate string) bool { + for _, value := range values { + if value == candidate { + return true + } + } + return false +} diff --git a/internal/app/event_presentation.go b/internal/app/event_presentation.go new file mode 100644 index 0000000..31b82d5 --- /dev/null +++ b/internal/app/event_presentation.go @@ -0,0 +1,262 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "log/slog" + "strconv" + "strings" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +// eventPresenter owns presentation policy but mutates only its event-loop state. +type eventPresenter struct { + state *eventLoopState + logger *slog.Logger + speech speechEnqueuer + foreground foregroundMonitor + inputSource any + live *liveSettings + browser *browserModeController +} + +func (presenter *eventPresenter) speak(event atspi.Event, capturedIntent ...input.Intent) { + state := presenter.state + logger := presenter.logger + speech := presenter.speech + foreground := presenter.foreground + inputSource := presenter.inputSource + live := presenter.live + if live != nil && state.echoPreview.owns(event, live.preferencesPID.Load()) { + state.comboHistory.observe(event) + // Focus labels and values are serialized by the private preview path. + // GTK selection descendants belong to that same presentation. + return + } + browser := presenter.browser + ownedAutocompletePopup := state.ownedAutocompletePopup + if foreground != nil && !eventBypassesXTermHandoff(event) && + (event.Foreground.Epoch != foreground.Foreground().Epoch || + event.ForegroundMismatch && !ownedAutocompletePopup(event)) { + return + } + var settings config.Settings + if live != nil { + settings = live.Load() + available := state.presentationOptions.SoundCueAvailable + state.presentationOptions = presentationSettingsFromConfig(settings, true) + state.presentationOptions.SoundCueAvailable = available + } + echoKind := "" + comboValue, comboUpdate, comboDuplicate := state.comboHistory.observe(event) + if comboDuplicate { + return + } + sequence := recentInput(inputSource).Sequence + intent := recentInput(inputSource).Intent + if len(capturedIntent) != 0 { + intent = capturedIntent[0] + } + table := state.prepareGUITable(event, sequence) + if table.skip { + return + } + spoken := presentation.EventSpeechWithOptions(state.calcHeaderSpeechEvent(event), table.options) + spoken, appendTableFocus := state.decorateGUITable(event, spoken, table) + text := spoken.Text + prompt := newPromptPresentation(state, event) + if prompt.activation { + spoken = presentation.SpeechWithOptions([]string{strings.TrimSpace(event.WindowTitle), event.WindowMessage}, table.options) + text = spoken.Text + } + if comboUpdate { + text = comboValue + } + if event.Type == atspi.CaretEvent { + intent := recentInput(inputSource).Intent + if len(capturedIntent) != 0 { + intent = capturedIntent[0] + } + switch intent { + case input.LineIntent: + text = event.Source.Text + if text == "" && event.Source.CaretCharacter != "" && strings.TrimSpace(event.Source.CaretCharacter) == "" { + text = "blank" + } + case input.WordIntent: + text = event.Source.CaretWord + } + } + if event.Type == atspi.TextInsertedEvent { + if event.Source.LiveRegion { + text = strings.TrimSpace(event.Payload) + if event.Source.LiveAtomic && event.Source.Text != "" { + text = strings.TrimSpace(event.Source.Text) + } + } else { + previousText := "" + if event.Source.Path == state.typingPath { + previousText = state.typingText + } + text, echoKind = presentation.TypingEcho(event, previousText, state.presentationOptions) + } + } + if event.Type == atspi.TextDeletedEvent && utf8.RuneCountInString(event.Payload) == 1 && text == event.Payload { + // Deleting one letter needs the same uppercase voice as character + // review. Keep whitespace labels and multi-character deletions as text. + echoKind = "character" + } + if event.Type == atspi.ChildrenAddedEvent && event.Source.LiveRegion { + text = strings.TrimSpace(event.Source.Text) + } + if event.Source.LiveRegion { + text = strings.TrimSpace(strings.ReplaceAll(text, "\ufffc", "")) + } + if speaksTextChanges(event.Source) && event.Source.Path != "" && !event.Source.LiveRegion { + state.typingPath = event.Source.Path + state.typingText = event.Source.TextBeforeCaret + if state.typingText == "" && event.Payload != "\n" && event.Payload != "\t" { + state.typingText = event.Source.Text + } + } + if event.Type == atspi.CaretEvent && (intent == input.WordIntent || intent == input.LineIntent) && event.Source.Misspelled && + settings.Reading.SpeakMisspelledIndicator && !settings.Reading.OnlySpeakDisplayedText { + spoken = presentation.SpeechWithOptions([]string{strings.TrimSuffix(text, ", misspelled"), "misspelled"}, table.options) + text = spoken.Text + } + cues := []sound.Cue(nil) + fallbackSpeech := presentationFallbackSpeech(event, state.presentationOptions) + fallbackText := fallbackSpeech.Text + if prompt.activation { + fallbackText = text + fallbackSpeech = spoken.WithText(text) + } + if comboUpdate { + fallbackText = text + fallbackSpeech = spoken.WithText(text) + } + if event.Type == atspi.CaretEvent && browser != nil && browser.ready && !event.Source.Editable { + intent := recentInput(inputSource).Intent + if len(capturedIntent) != 0 { + intent = capturedIntent[0] + } + if intent == input.LineIntent && event.Source.Text != "" { + line := atspi.DocumentLine{Contents: []atspi.DocumentContent{{Snapshot: event.Source, Text: event.Source.Text}}} + spoken = presentation.DocumentLineSpeechWithOptions(line, state.presentationOptions) + text = spoken.Text + cues = presentation.DocumentLineSoundCues(line, state.presentationOptions) + fallbackOptions := state.presentationOptions + fallbackOptions.RoleSoundPresentation = "sound_and_speech" + fallbackSpeech = presentation.DocumentLineSpeechWithOptions(line, fallbackOptions) + fallbackText = fallbackSpeech.Text + } + } + if event.Type != atspi.CaretEvent && !isTextChangeEvent(event.Type) { + cues = presentation.EventSoundCues(event, state.presentationOptions) + if event.Source.Role == "combo box" && (comboUpdate || !isFocusGainEvent(event)) { + cues = nil + } + + } + if prompt.activation { + // The control's own focus event will present its role and cue. + cues = nil + } + cues = presenter.coalesce_radio_sound(event, cues) + cueParts := make([]string, 0, len(cues)) + for _, cue := range cues { + cueParts = append(cueParts, cue.Name+":"+strconv.FormatFloat(cue.Pan, 'g', -1, 64)) + } + spoken, fallbackSpeech = prompt.focusSpeech(spoken.WithText(text), fallbackSpeech.WithText(fallbackText)) + text, fallbackText = spoken.Text, fallbackSpeech.Text + cueKey := strings.Join(cueParts, "\x00") + // Adjacent characters can have the same text while the caret moves. + // Treat each character caret event as a new review position. + characterCaret := event.Type == atspi.CaretEvent && text != "" && text == event.Source.CaretCharacter + if !characterCaret && !isTextChangeEvent(event.Type) && + event.Source.Path != "" && event.Source.Path == state.lastSpokenPath && text == state.lastSpokenText && cueKey == state.lastSound { + return + } + if event.Source.LiveRegion && event.Source.LivePoliteness == "off" { + return + } + if event.Source.LiveRegion && text != "" && text == state.lastLiveText && time.Since(state.lastLiveAt) < 300*time.Millisecond { + return + } + if text == "" && len(cues) == 0 { + logger.Debug("accessibility event has no speech text", "type", event.Type, "role", event.Source.Role) + return + } + appendPromptFocus := prompt.appendFocus() + prompt.finishFocus() + custom := false + if live != nil { + custom = customEcho(settings, echoKind) + } + appendTabFocus := isFocusGainEvent(event) && eventWindow(event) == state.tabFocusWindow && + state.tabFocusSequence != 0 && sequence == state.tabFocusSequence + if isFocusGainEvent(event) { + state.tabFocusWindow, state.tabFocusSequence = atspi.ObjectID{}, 0 + } + var line *speechLine + if event.Source.Role != "password text" && event.Source.TextCaretKnown && + (event.Type == atspi.CaretEvent && intent == input.LineIntent || isFocusGainEvent(event)) { + line = &speechLine{Object: event.Source.ID(), Raw: event.Source.BrailleLine} + } + browseContext := browser.speech_context_enabled() && event.Source.BusName == browser.document.BusName + speech.Enqueue(speechRequest{ + Context: event.Source.SpeechContext, ResetContext: !browseContext, VoiceType: ancestor_voice(event.Source.SpeechContext), + Window: eventWindow(event), + IntroducesWindow: (event.Type == atspi.WindowActivatedEvent || event.Type == atspi.WindowCreateEvent) && + activationTitle(event) != "", + Text: text, Chunks: spoken.WithText(text).Chunks, FallbackText: fallbackText, FallbackChunks: fallbackSpeech.WithText(fallbackText).Chunks, Role: event.Source.Role, Sound: cues, Cause: event.Type, CustomEcho: custom, + Line: line, + ExcludeFromHistory: state.historyWindow.Valid() && eventWindow(event) == state.historyWindow, + PhoneticHint: characterCaret, + Character: event.Type == atspi.CaretEvent && text == event.Source.CaretCharacter || echoKind == "character" || echoKind == "key", + Append: appendTabFocus || appendTableFocus || appendPromptFocus || event.Source.LiveRegion && event.Source.LivePoliteness == "polite" || + event.Source.Role == "terminal" && event.Type == atspi.TextInsertedEvent, + BypassFocusGate: eventBypassesXTermHandoff(event), + }) + // Activation can describe the window while focus is still in its entry. + // Remember that help before the first table row is selected. Keep the + // immediate table-focus append timing owned by decorateGUITable. + if event.Type == atspi.WindowActivatedEvent && !prompt.activation && + state.presentationOptions.SpeakDescription && event.Window.Valid() && event.WindowDescription != "" { + state.tableDescriptionWindow = event.Window + state.tableDescriptionText = event.WindowDescription + } + state.rememberGUITable(event, table) + if event.Source.LiveRegion { + state.lastLiveText, state.lastLiveAt = text, time.Now() + } + logger.Debug("queued accessible presentation", "type", event.Type, "role", event.Source.Role) + prompt.rememberWindow() + if !isTextChangeEvent(event.Type) { + state.lastSpokenPath = event.Source.Path + state.lastSpokenText = text + state.lastSound = cueKey + } +} + +func presentationFallbackText(event atspi.Event, options presentation.Options) string { + return presentationFallbackSpeech(event, options).Text +} + +func presentationFallbackSpeech(event atspi.Event, options presentation.Options) presentation.Speech { + if options.RoleSoundPresentation != "sound_only" { + return presentation.Speech{} + } + options.RoleSoundPresentation = "sound_and_speech" + return presentation.EventSpeechWithOptions(event, options) +} diff --git a/internal/app/event_presentation_test.go b/internal/app/event_presentation_test.go new file mode 100644 index 0000000..5090a9a --- /dev/null +++ b/internal/app/event_presentation_test.go @@ -0,0 +1,181 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/logging" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestProcessEventsDoesNotBlockOnDiagnosticsWriter(t *testing.T) { + writer := &eventDiagnosticsWriter{ + started: make(chan struct{}), + canceled: make(chan struct{}), + } + diagnostics := logging.NewAsync(writer, logging.AsyncOptions{ + Options: logging.Options{Level: slog.LevelDebug}, + Capacity: 2, + StopTimeout: 100 * time.Millisecond, + CancelGrace: 10 * time.Millisecond, + }) + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, diagnostics.Logger(), speech, adapter, 0) + close(completed) + }() + + adapter.events <- atspi.NewEvent("focus:", atspi.NewSnapshot("/accessible/test", "Test", "label", "", "")) + select { + case <-writer.started: + case <-time.After(time.Second): + t.Fatal("diagnostics worker did not start") + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("event consumer blocked on diagnostics writer") + } + + writer.Cancel() + if err := diagnostics.Stop(context.Background()); err != nil { + t.Fatalf("diagnostics stop: %v", err) + } +} + +func TestProcessEventsSuppressesBrowserAccessibleNameEvents(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + browser := newBrowserModeController(nil, &modeKeys{}, nil) + documentContext := modeContext(t, "heading", false) + browser.navigated(review.DocumentPosition{ + Document: documentContext.TopLevel, + Snapshot: documentContext.Ancestors[0], + }, documentContext.Ancestors[0].ID()) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), speech, adapter, nil, nil, 0, nil, browser, nil, nil) + close(completed) + }() + + browserName := atspi.NewSnapshot("/browser/static", "https://example.com/", "static", "", "") + browserName.BusName = documentContext.TopLevel.ID().BusName + adapter.events <- atspi.NewEvent(atspi.AccessibleNameEvent, browserName) + select { + case text := <-speech.spoken: + t.Fatalf("browser name event spoke %q", text) + case <-time.After(50 * time.Millisecond): + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestProcessEventsAppliesDescriptionSetting(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEvents( + ctx, + slog.New(slog.DiscardHandler), + speech, + adapter, + 0, + presentation.Options{SpeakDescription: false}, + ) + close(completed) + }() + + adapter.events <- atspi.NewEvent( + "focus:", + atspi.NewSnapshot("/accessible/save", "Save", "push button", "Saves the document", ""), + ) + select { + case text := <-speech.spoken: + if text != "Save, push button" { + t.Fatalf("spoken text = %q, want %q", text, "Save, push button") + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for configured focus speech") + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestProcessEventsSpeaksChangedTextImmediately(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + snapshot := atspi.NewSnapshot("/accessible/editor", "", "text", "", "prompt ls") + snapshot.Editable = true + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, "s") + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, snapshot, "s") + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, snapshot, " ") + + for _, expected := range []string{"s", "s", "space"} { + select { + case text := <-speech.spoken: + if text != expected { + t.Fatalf("spoken text = %q, want %q", text, expected) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for changed text speech %q", expected) + } + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} diff --git a/internal/app/event_review_results.go b/internal/app/event_review_results.go new file mode 100644 index 0000000..d80e0dd --- /dev/null +++ b/internal/app/event_review_results.go @@ -0,0 +1,284 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "log/slog" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// eventReviewHandler consumes review results on the event-loop goroutine. +type eventReviewHandler struct { + state *eventLoopState + logger *slog.Logger + speech speechEnqueuer + objectReview *review.Worker + browser *browserModeController + brailleOutput brailleFrameEnqueuer + live *liveSettings + focusGate *focusGate + syncForeground func() + speak func(atspi.Event, ...input.Intent) + wineReview *wineReviewFocusController + calcHeaders libreOfficeHeaderConfigurer +} + +func (handler *eventReviewHandler) whereAmI() { + if handler.focusGate.Locked() { + return + } + handler.syncForeground() + handler.refreshPresentation() + state := handler.state + state.pending.terminalFocus.clear() + state.pending.terminalDeletion.clear() + // Python's Where Am I is speech-only. Do not suppress the role merely + // because ordinary focus presentation replaces it with a sound cue. + reviewOptions := state.presentationOptions + reviewOptions.EnableSound = false + spoken := presentation.FocusSpeechWithOptions(state.current, reviewOptions) + if formula := presentation.LibreOfficeCellFormula(state.current); formula != "" { + spoken = spoken.Append(formula, ", ") + } + text := spoken.Text + role := state.current.Role + if text == "" { + text = "Could not find current location." + role = "system" + } + handler.speech.Enqueue(speechRequest{Text: text, Chunks: spoken.WithText(text).Chunks, Role: role, Cause: "where-am-i"}) + handler.logger.Debug("queued where am I presentation", "role", role) +} + +func (handler *eventReviewHandler) handle(result review.Result) { + handler.refreshPresentation() + state := handler.state + logger := handler.logger + speech := contextSpeechQueue{speechEnqueuer: handler.speech, enabled: handler.browser.speech_context_enabled()} + objectReview := handler.objectReview + browser := handler.browser + brailleOutput := handler.brailleOutput + live := handler.live + focusGate := handler.focusGate + syncForeground := handler.syncForeground + speak := handler.speak + if focusGate.Locked() { + return + } + if result.DocumentNativeCaret { + logger.Debug("native document caret synchronized", "source_bus", result.DocumentFocus.BusName, "source_path", result.DocumentFocus.Path, + "target_path", result.DocumentPosition.Object.ID().Path, "virtual_caret_offset", result.DocumentPosition.Offset, "error", result.Err) + return + } + syncForeground() + if !state.current.ID().Valid() { + return + } + if result.CurrentLine { + handler.present_current_line(result) + return + } + if result.ReadAllPosition { + if objectReview.CurrentDocumentResult(result) && result.DocumentFocus == objectReview.Focus() { + state.current = result.DocumentPosition.Snapshot + state.focusedID = state.current.ID() + } + return + } + if result.ReadAllContext != nil { + if objectReview.CurrentDocumentResult(result) && result.ReadAllContext.Err() == nil && result.DocumentFocus == objectReview.Focus() { + presentReadAllResult(logger, speech, result, state.presentationOptions) + } + return + } + if (result.DocumentLine || result.DocumentTarget != 0 || result.DocumentCaretCommand != 0 || result.DocumentActivate || result.DocumentFragment) && !objectReview.CurrentDocumentResult(result) { + return + } + if result.DocumentFragment && (!result.Moved || result.Err != nil) { + if result.Err != nil { + logger.Warn("document fragment navigation failed", "error", result.Err) + } + return + } + if result.DocumentActivate { + if browser == nil || !browser.acceptsDocumentResult(result) { + return + } + if result.Err != nil { + logger.Debug("document activation failed", "error", result.Err) + } else { + logger.Debug("document activation completed", "elapsed", result.Elapsed) + } + return + } + if result.DocumentLine { + if result.DocumentLineRequest == 0 || result.DocumentLineRequest != state.documentLineRequest || + !result.DocumentLineFocus.Valid() || result.DocumentLineFocus != state.documentLineFocus { + return + } + event := state.documentLineEvent + state.documentLineFocus = atspi.ObjectID{} + state.documentLineRequest = 0 + state.documentLineEvent = atspi.Event{} + if result.Err != nil { + logger.Debug("document caret line assembly failed", "error", result.Err) + speak(event, input.LineIntent) + return + } + spoken := presentation.DocumentLineSpeechWithOptions(result.DocumentLineData, state.presentationOptions) + text := spoken.Text + cues := presentation.DocumentLineSoundCues(result.DocumentLineData, state.presentationOptions) + fallbackOptions := state.presentationOptions + fallbackOptions.RoleSoundPresentation = "sound_and_speech" + fallback := presentation.DocumentLineSpeechWithOptions(result.DocumentLineData, fallbackOptions) + if text == "" && len(cues) == 0 { + return + } + speech.Enqueue(speechRequest{Text: text, Chunks: spoken.Chunks, FallbackText: fallback.Text, FallbackChunks: fallback.Chunks, Sound: cues, Role: "text", Cause: "document-caret-line", Line: document_speech_line(result.DocumentLineData), Context: result.DocumentLineData.Context, VoiceType: document_line_voice(result.DocumentLineData)}) + return + } + if result.DocumentTarget != 0 || result.DocumentCaretCommand != 0 || result.DocumentFragment { + if browser != nil { + if !browser.acceptsDocumentResult(result) { + return + } + } else if !documentResultMatchesCurrent(result, state.current) { + return + } + // The native caret event which preceded this result can still be + // waiting in the coalescing timer. Its old text must not replace + // the structural result after the jump completes. + state.pending.clear() + if result.DocumentCaretCommand != 0 { + if !result.DocumentBrailleRoute { + presentDocumentCaretResult(logger, speech, result, state.presentationOptions) + } + } else { + presentDocumentResult(logger, speech, result, state.presentationOptions) + } + // The virtual move is authoritative. Native placement can fail when + // a page replaces its text after we read it; that must not leave the + // browser controller or Braille at the previous virtual position. + if result.Moved && result.Err == nil { + if result.DocumentCaretCommand != review.CaretReadLine || result.DocumentBrailleRoute { + state.documentSelection = textSelection{} + } + state.current = result.DocumentPosition.Snapshot + if brailleOutput != nil { + state.brailleSnapshot = state.current + brailleOptions := config.DefaultSettings().Braille + textAttributes := config.DefaultTextAttributes() + if live != nil { + settings := live.Load() + brailleOptions, textAttributes = settings.Braille, settings.TextAttributes + } + brailleOutput.EnqueueFrame(brailleDocumentFrame(result, brailleOptions, textAttributes)) + } + state.focusedID = state.current.ID() + // Browse navigation does not change native focus. Keep the + // worker on its document anchor; dynamic pages can remove the + // spoken leaf before the next review command. + if result.DocumentCaretCommand == 0 && browser == nil { + objectReview.SyncFocus(state.current.ID()) + } + if browser != nil { + objectReview.SetFlatOrigin(state.current.ID(), result.DocumentPosition.Offset) + browser.navigated(result.DocumentPosition, objectReview.Focus()) + } + } + } else if result.FlatUnit != 0 { + if reservedWineID(result.FlatFocus) && (handler.wineReview == nil || !handler.wineReview.resultCurrent(result)) { + return + } + // The browse caret can be a leaf while native focus remains on + // the document. Flat review belongs to that native review focus. + if !flatReviewResultCurrent(objectReview, result) { + logger.Debug("discarded stale flat review result", "result_focus", result.FlatFocus.Path, + "current_focus", objectReview.Focus().Path, "document_epoch", result.DocumentEpoch) + return + } + state.pending.terminalFocus.clear() + state.pending.terminalDeletion.clear() + presentFlatReviewResult(logger, speech, result) + if reservedWineID(result.FlatFocus) && brailleOutput != nil && result.Err == nil && + (result.Moved || result.FlatStep == 0 && result.FlatUnit != review.WordAbove && result.FlatUnit != review.WordBelow) { + options := config.DefaultSettings().Braille + if live != nil { + options = live.Load().Braille + } + // Review is independent of the native caret. Display through the + // existing queue with no native text routes or document navigation. + brailleOutput.EnqueueFrame(braille.Frame{Text: result.FlatPosition.Text, Cursor: 0, WordWrap: options.WordWrap}) + } + } else { + presentObjectReviewResult(logger, speech, result, state.presentationOptions) + } +} + +func (handler *eventReviewHandler) refreshPresentation() { + if handler.live == nil { + return + } + available := handler.state.presentationOptions.SoundCueAvailable + handler.state.presentationOptions = presentationSettingsFromConfig(handler.live.Load(), true) + handler.state.presentationOptions.SoundCueAvailable = available +} + +func flatReviewResultCurrent(worker *review.Worker, result review.Result) bool { + return worker != nil && result.FlatFocus.Valid() && + worker.CurrentDocumentResult(result) && result.FlatFocus == worker.Focus() +} + +func queueObjectReviewMove(logger *slog.Logger, worker *review.Worker, direction review.Direction) { + logger.Info("object review command received", "direction", direction.String()) + if err := worker.Move(direction); err != nil { + logger.Warn("queue object review movement", "direction", direction.String(), "error", err) + } +} + +func presentObjectReviewResult(logger *slog.Logger, speech speechEnqueuer, result review.Result, options presentation.Options) { + text := "" + var spoken presentation.Speech + role := "system" + if result.Err != nil { + logger.Warn("object review movement failed", "direction", result.Direction.String(), "error", result.Err) + text = "Could not find current location." + } else if !result.Moved { + text = objectReviewBoundaryMessage(result.Direction) + } else { + options.EnableSound = false + spoken = presentation.FocusSpeechWithOptions(result.Position.Current, options) + text = spoken.Text + role = result.Position.Current.Role + if text == "" { + text = "Could not find current location." + role = "system" + } + } + speech.Enqueue(speechRequest{Text: text, Chunks: spoken.WithText(text).Chunks, Role: role, Cause: "object-review"}) + logger.Debug("queued object review presentation", "direction", result.Direction.String(), "moved", result.Moved, "role", role) +} + +func objectReviewBoundaryMessage(direction review.Direction) string { + switch direction { + case review.Parent: + return "No parent." + case review.FirstChild: + return "No children." + case review.PreviousSibling: + return "No previous." + case review.NextSibling: + return "No next." + default: + return "Could not find current location." + } +} diff --git a/internal/app/event_state.go b/internal/app/event_state.go new file mode 100644 index 0000000..39ae0c5 --- /dev/null +++ b/internal/app/event_state.go @@ -0,0 +1,201 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "log/slog" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// eventLoopState is owned only by processEventsWithInput's goroutine. Embedded +// groups keep each lifetime visible while retaining the existing individual +// reset transitions. Workers observe state only through their existing APIs. +type eventLoopState struct { + eventForegroundState + eventFocusState + eventDocumentState + eventInputState + eventPresentationState +} + +type eventForegroundState struct { + owner windowOwner + foregroundState atspi.ForegroundState + lastOverflow uint64 +} + +type eventFocusState struct { + libreOfficeSelection libreOfficeSelectionState + current atspi.Snapshot + brailleSnapshot atspi.Snapshot + focusedID atspi.ObjectID + managedContainerID atspi.ObjectID + managedDescendantID atspi.ObjectID +} + +type eventDocumentState struct { + selectedBrowserTab atspi.ObjectID + tabFocusWindow atspi.ObjectID + tabFocusSequence uint64 + documentLineFocus atspi.ObjectID + documentLineRequest uint64 + documentLineEvent atspi.Event + loadedDocument atspi.ObjectID + loadingDocument atspi.ObjectID + // A load-complete can verify chrome focus just before a busy:false event + // temporarily loses its native focused state. Keep that document from + // taking browse keys until focus actually enters it. + chromeLoadedDocument atspi.ObjectID + chromeLoadedWindow atspi.ObjectID +} + +type eventInputState struct { + lastAutocompletePopupItem atspi.ObjectID + focusCaretID atspi.ObjectID + focusCaretSequence uint64 + suppressNextCaretPath string + selectionCaretID atspi.ObjectID + selectionCaretSequence uint64 + selectionCaretAt time.Time + autocompleteTyping autocompleteEcho + autocompleteAvailable autocompleteAvailability + typingPath string + typingText string + selection textSelection + documentSelection textSelection + lastClipboardSequence uint64 + lastPasteSequence uint64 + lastPasteID atspi.ObjectID + lastPasteAt time.Time +} + +type eventPresentationState struct { + presentationOptions presentation.Options + pending pendingPresentations + lastSpokenPath string + lastSpokenText string + lastSound string + lastLiveText string + lastLiveAt time.Time + comboHistory comboPresentation + echoPreview echoPreviewPresentation + // Retain this identity after the history window closes so delayed GTK + // events cannot enter speech history. + historyWindow atspi.ObjectID + lastFileManagerStatus string + lastFileManagerStatusWindow atspi.ObjectID + pendingPromptWindow atspi.ObjectID + pendingPromptTextAnnounced bool + tableDescriptionWindow atspi.ObjectID + tableDescriptionText string + tableDescriptionAt time.Time + lastTable atspi.ObjectID + lastTableCell atspi.ObjectID + lastTableRow int + lastTableColumn int + lastTableSequence uint64 + lastTableAt time.Time + lastTableFullRow bool + lastTableText string + progressBars ProgressBarHistory +} + +func (state *eventLoopState) ownedAutocompletePopup(event atspi.Event) bool { + return event.Source.AutocompletePopup && event.PopupFor.Valid() && + state.current.Autocomplete && state.current.ID() == event.PopupFor && + state.owner.focus == event.PopupFor && state.owner.window.Valid() && + event.Window.Valid() && event.Window != state.owner.window && + event.Window.BusName == state.owner.applicationBus && + event.Source.BusName == state.owner.applicationBus +} + +// clearOwnedFocus retires only the state cleared by the former event-loop +// closure. Session presentation history and chrome load verification survive. +func (state *eventLoopState) clearOwnedFocus(brailleOutput brailleFrameEnqueuer, browser *browserModeController, objectReview *review.Worker, speech speechEnqueuer) { + state.clearObjectFocus(brailleOutput, browser, objectReview) +} + +// Review metadata can change without new input or a foreground switch. Reset +// its navigation state independently so title announcements keep playing. +func (state *eventLoopState) clearObjectFocus(brailleOutput brailleFrameEnqueuer, browser *browserModeController, objectReview *review.Worker) { + state.libreOfficeSelection = libreOfficeSelectionState{} + if calcSheet(state.current).Valid() { + state.lastTable = atspi.ObjectID{} + state.lastTableCell = atspi.ObjectID{} + } + state.selection = textSelection{} + state.documentSelection = textSelection{} + state.lastClipboardSequence = 0 + state.lastPasteSequence = 0 + state.lastPasteID = atspi.ObjectID{} + state.lastPasteAt = time.Time{} + state.selectionCaretID = atspi.ObjectID{} + state.brailleSnapshot = atspi.Snapshot{} + if brailleOutput != nil { + brailleOutput.EnqueueFrame(braille.Frame{Cursor: -1}) + } + state.pending.clear() + state.pendingPromptWindow = atspi.ObjectID{} + state.pendingPromptTextAnnounced = false + state.focusedID = atspi.ObjectID{} + state.selectedBrowserTab = atspi.ObjectID{} + state.tabFocusWindow, state.tabFocusSequence = atspi.ObjectID{}, 0 + state.managedContainerID = atspi.ObjectID{} + state.managedDescendantID = atspi.ObjectID{} + state.current = atspi.Snapshot{} + state.focusCaretID, state.focusCaretSequence = atspi.ObjectID{}, 0 + state.lastSpokenPath, state.lastSpokenText, state.lastSound = "", "", "" + state.lastLiveText, state.lastLiveAt = "", time.Time{} + state.comboHistory = comboPresentation{} + state.echoPreview = echoPreviewPresentation{} + state.typingPath, state.typingText, state.suppressNextCaretPath = "", "", "" + state.lastAutocompletePopupItem = atspi.ObjectID{} + state.autocompleteTyping = autocompleteEcho{} + state.autocompleteAvailable = autocompleteAvailability{} + state.documentLineFocus = atspi.ObjectID{} + state.documentLineRequest = 0 + state.documentLineEvent = atspi.Event{} + state.loadedDocument = atspi.ObjectID{} + state.loadingDocument = atspi.ObjectID{} + if browser != nil { + browser.clear() + } + if objectReview != nil { + objectReview.ClearFocus() + } +} + +func (state *eventLoopState) syncForeground(foreground foregroundMonitor, logger *slog.Logger, clearOwnedFocus func()) { + if foreground == nil { + return + } + latest := foreground.Foreground() + if latest.Epoch != state.foregroundState.Epoch { + state.owner.clear() + clearOwnedFocus() + logger.Debug("X11 foreground ownership changed", "x_window", latest.Client.Window, + "pid", latest.Client.PID, "property_pid", latest.Client.PropertyPID, + "known", latest.Client.Known, "epoch", latest.Epoch) + } + state.foregroundState = latest +} diff --git a/internal/app/event_text_selection.go b/internal/app/event_text_selection.go new file mode 100644 index 0000000..432db3e --- /dev/null +++ b/internal/app/event_text_selection.go @@ -0,0 +1,80 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func (handler *accessibilityEventHandler) handleSelectionAndClipboard(event atspi.Event, activity input.Activity, intent input.Intent) bool { + state := handler.state + logger := handler.logger + speech := handler.speech + if activity.Clipboard == input.PasteAction && activity.Sequence == state.lastPasteSequence && + event.Source.ID() == state.lastPasteID && time.Since(state.lastPasteAt) < time.Second && + (event.Type == atspi.TextInsertedEvent || event.Type == atspi.TextDeletedEvent || + event.Type == atspi.TextSelectionChangedEvent || event.Type == atspi.CaretEvent) { + if event.Type == atspi.CaretEvent { + state.suppressNextCaretPath = "" + } else if event.Type == atspi.TextSelectionChangedEvent { + state.selection.changed(event.Source) + } + logger.Debug("skipped text event following paste confirmation", "type", event.Type) + return true + } + if event.Type == atspi.TextSelectionChangedEvent { + if !belongsToFocusedEditor(event.Source, state.focusedID) || !event.Source.Editable || event.Source.ReadOnly || + event.Source.Role == "password text" || event.Source.Autocomplete { + return true + } + fragmentLimit := selectionFragmentLimit + if activity.Selecting && intent == input.LineIntent { + fragmentLimit = lineSelectionFragmentLimit + } + if event.Source.EditableRoot == state.focusedID && event.Source.ID() != state.focusedID && + state.selection.id != event.Source.ID() { + // Native focus stays on the document. The first selection in a + // newly visited paragraph still needs its selected text spoken. + state.selection.reset(atspi.Snapshot{BusName: event.Source.BusName, Path: event.Source.Path}) + } + message := state.selection.changedWithLimit(event.Source, fragmentLimit) + if message != "" { + state.pending.caret.clear() + state.selectionCaretID = event.Source.ID() + state.selectionCaretSequence = activity.Sequence + state.selectionCaretAt = time.Now() + if activity.Clipboard != input.CutAction && activity.Clipboard != input.PasteAction { + speech.Enqueue(speechRequest{Text: message, Role: "system", Cause: event.Type}) + } + } + return true + } + if activity.Sequence != 0 && activity.Sequence != state.lastClipboardSequence && + belongsToFocusedEditor(event.Source, state.focusedID) && event.Source.Editable && !event.Source.ReadOnly && + !event.Source.Autocomplete && event.Source.Role != "password text" { + message := "" + if event.Type == atspi.TextDeletedEvent && activity.Clipboard == input.CutAction { + message = "cut" + } else if event.Type == atspi.TextInsertedEvent && activity.Clipboard == input.PasteAction { + message = "pasted from clipboard" + } + if message != "" { + state.lastClipboardSequence = activity.Sequence + if activity.Clipboard == input.PasteAction { + state.lastPasteSequence = activity.Sequence + state.lastPasteID = event.Source.ID() + state.lastPasteAt = time.Now() + state.pending.caret.clear() + } + speech.Enqueue(speechRequest{Text: message, Role: "system", Cause: "clipboard"}) + return true + } + } + return false +} diff --git a/internal/app/event_tooltip.go b/internal/app/event_tooltip.go new file mode 100644 index 0000000..d9cb1d7 --- /dev/null +++ b/internal/app/event_tooltip.go @@ -0,0 +1,29 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +// A tooltip is transient output. It must not take keyboard focus or replace +// the current review position when the provider shows its popup window. +func (handler *accessibilityEventHandler) handleTooltip(event atspi.Event) bool { + if event.Type != atspi.ShowingStateEvent || event.Source.Role != "tool tip" { + return false + } + if event.Detail1 == 0 || handler.live == nil || !handler.live.Load().Reading.PresentTooltips { + return true + } + options := presentationSettingsFromConfig(handler.live.Load(), true) + spoken := presentation.FocusSpeechWithOptions(event.Source, options) + if text := strings.TrimSpace(spoken.Text); text != "" && text != "tool tip" { + handler.speech.Enqueue(speechRequest{Text: text, Chunks: spoken.WithText(text).Chunks, Role: "system", Cause: "tooltip"}) + } + return true +} diff --git a/internal/app/event_tooltip_test.go b/internal/app/event_tooltip_test.go new file mode 100644 index 0000000..a11701c --- /dev/null +++ b/internal/app/event_tooltip_test.go @@ -0,0 +1,89 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +func TestTooltipPreferenceGatesTransientSpeechWithoutMovingFocus(t *testing.T) { + settings := config.DefaultSettings() + live := &liveSettings{} + live.Store(settings) + queue := &fakeSpeechQueue{spoken: make(chan string, 2), requests: make(chan speechRequest, 2), interrupt: make(chan struct{}, 2)} + state := &eventLoopState{} + state.focusedID = atspi.ObjectID{BusName: ":1.42", Path: "/button"} + handler := accessibilityEventHandler{state: state, live: live, speech: queue} + event := atspi.NewEvent(atspi.ShowingStateEvent, atspi.Snapshot{Role: "tool tip", Name: "Save document"}) + event.Detail1 = 1 + if !handler.handleTooltip(event) || len(queue.requests) != 0 { + t.Fatal("disabled tooltip was presented") + } + settings.Reading.PresentTooltips = true + live.Store(settings) + if !handler.handleTooltip(event) { + t.Fatal("showing tooltip was not handled") + } + request := <-queue.requests + if request.Text != "Save document, tool tip" || request.Cause != "tooltip" || state.focusedID.Path != "/button" { + t.Fatalf("tooltip presentation = %+v; focus = %+v", request, state.focusedID) + } + event.Detail1 = 0 + if !handler.handleTooltip(event) || len(queue.requests) != 0 { + t.Fatal("hidden tooltip was presented") + } +} + +func TestOwnedTooltipPopupReachesSpeechAndUnownedPopupDoesNot(t *testing.T) { + adapter := &foregroundAdapter{fakeAdapter: fakeAdapter{events: make(chan atspi.Event, 8)}, changes: make(chan struct{}, 1)} + foreground := atspi.ForegroundState{Client: xorg.Foreground{Known: true, Window: 101}, Epoch: 1} + adapter.state.Store(&foreground) + settings := config.DefaultSettings() + settings.Reading.PresentTooltips = true + live := &liveSettings{} + live.Store(settings) + queue := &fakeSpeechQueue{spoken: make(chan string, 8), requests: make(chan speechRequest, 8), interrupt: make(chan struct{}, 8)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + _ = processEventsWithSettings(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, live) + }() + defer func() { cancel(); <-done }() + focus := ownerEvent(atspi.FocusedStateEvent, ":1.42", "/window", "/button") + focus.Source.Role, focus.Source.Name, focus.Source.Focused = "push button", "Save", true + focus.Detail1, focus.Foreground = 1, foreground + adapter.events <- focus + expectActivationSpeech(t, queue.spoken, "Save, push button") + tooltip := ownerEvent(atspi.ShowingStateEvent, ":1.42", "/popup", "/tooltip") + tooltip.Source.Role, tooltip.Source.Name = "tool tip", "Save document" + tooltip.Detail1, tooltip.Foreground, tooltip.ForegroundMismatch = 1, foreground, true + adapter.events <- tooltip + expectActivationSpeech(t, queue.spoken, "Save document, tool tip") + settings.Reading.PresentTooltips = false + live.Store(settings) + adapter.events <- tooltip + select { + case got := <-queue.spoken: + t.Fatalf("disabled tooltip spoke %q", got) + case <-time.After(100 * time.Millisecond): + } + settings.Reading.PresentTooltips = true + live.Store(settings) + tooltip.Source.BusName = ":1.43" + adapter.events <- tooltip + select { + case got := <-queue.spoken: + t.Fatalf("unowned tooltip spoke %q", got) + case <-time.After(100 * time.Millisecond): + } +} diff --git a/internal/app/flat_review.go b/internal/app/flat_review.go new file mode 100644 index 0000000..1e9ce72 --- /dev/null +++ b/internal/app/flat_review.go @@ -0,0 +1,119 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "errors" + "log/slog" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func flatReviewCommand(command input.Command) (review.FlatUnit, int) { + switch command { + case input.ReviewWindowStart: + return review.WindowStart, 0 + case input.ReviewWindowEnd: + return review.WindowEnd, 0 + case input.ReviewPreviousLine: + return review.Line, -1 + case input.ReviewCurrentLine, input.ReviewSpellLine, input.ReviewPhoneticLine: + return review.Line, 0 + case input.ReviewNextLine: + return review.Line, 1 + case input.ReviewPreviousWord: + return review.Word, -1 + case input.ReviewCurrentWord, input.ReviewSpellWord, input.ReviewPhoneticWord: + return review.Word, 0 + case input.ReviewNextWord: + return review.Word, 1 + case input.ReviewPreviousCharacter: + return review.Character, -1 + case input.ReviewCurrentCharacter, input.ReviewPhoneticCharacter: + return review.Character, 0 + case input.ReviewNextCharacter: + return review.Character, 1 + case input.ReviewWordAbove: + return review.WordAbove, 0 + case input.ReviewWordBelow: + return review.WordBelow, 0 + case input.ReviewLineEnd: + return review.LineEnd, 0 + default: + return 0, 0 + } +} + +func presentFlatReviewResult(logger *slog.Logger, speech speechEnqueuer, result review.Result) { + text := "" + boundary := false + if result.Err != nil { + logger.Warn("flat review failed", "error", result.Err) + switch { + case errors.Is(result.Err, review.ErrLimitedReview): + text = "This window exceeds the current flat review text limit." + case errors.Is(result.Err, review.ErrNoReviewContent): + text = "No visible content." + case errors.Is(result.Err, review.ErrUnavailableReview): + text = "Visible content is unavailable for flat review." + default: + text = "Could not find current location." + } + } else if !result.Moved && (result.FlatStep != 0 || result.FlatUnit == review.WordAbove || result.FlatUnit == review.WordBelow) { + if result.FlatUnit != review.Line { + return + } + boundary = true + if result.FlatStep < 0 { + text = "Top of screen." + } else { + text = "Bottom of screen." + } + } else { + text = presentation.FlatReviewText(result.FlatPosition.Text, result.FlatUnit == review.Character || result.FlatUnit == review.LineEnd) + } + hasContent := result.Err == nil && !boundary + request := speechRequest{Text: text, Role: "text", Cause: "flat-review", Character: hasContent && (result.FlatUnit == review.Character || result.FlatUnit == review.LineEnd)} + if hasContent && result.FlatUnit == review.Line { + request.Line = &speechLine{Object: result.FlatPosition.Object, Raw: result.FlatPosition.Text} + } + if hasContent { + set_review_spelling(&request, result.FlatPosition.Text, result.FlatSpeech) + } + if result.FlatWarning { + logger.Warn("flat review content incomplete", "omitted_text_objects", result.FlatCompleteness.OmittedObjects, + "unavailable_subtrees", result.FlatCompleteness.UnavailableSubtrees) + } + speech.Enqueue(request) + if logger.Enabled(context.Background(), slog.LevelDebug) { + logger.Debug("queued flat review presentation", + "speech_text", request.Text, "spelling", request.Spelling, "speech_style", result.FlatSpeech, + "unit", result.FlatUnit, + "moved", result.Moved, + "bus", result.FlatPosition.Object.BusName, + "object_path", result.FlatPosition.Object.Path, + "offset", result.FlatPosition.Offset, + "has_offset", result.FlatPosition.HasOffset, + "capture_duration", result.CaptureDuration, + "capture_reason", result.CaptureReason, + ) + } +} diff --git a/internal/app/flat_review_test.go b/internal/app/flat_review_test.go new file mode 100644 index 0000000..8f1cb67 --- /dev/null +++ b/internal/app/flat_review_test.go @@ -0,0 +1,269 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestFlatReviewPartialDiagnosticsPreserveSpellingWithoutExtraMessages(t *testing.T) { + live := &liveSettings{} + live.Store(config.DefaultSettings()) + braille := &flashRecorder{} + queue := &fakeSpeechQueue{spoken: make(chan string, 4), requests: make(chan speechRequest, 4)} + output := outputQueue{speech: queue, braille: braille, live: live} + result := review.Result{FlatUnit: review.Word, FlatSpeech: review.FlatSpell, FlatWarning: true, + FlatCompleteness: review.FlatCompleteness{OmittedObjects: 1}, FlatPosition: review.FlatPosition{Text: "cat"}} + presentFlatReviewResult(slog.New(slog.DiscardHandler), output, result) + content := <-queue.requests + if len(content.Spelling) != 3 || content.Text != "cat" || len(queue.requests) != 0 { + t.Fatalf("content metadata or extra message: %+v, queued=%d", content, len(queue.requests)) + } + if len(braille.messages) != 0 { + t.Fatalf("unexpected Braille warning: %v", braille.messages) + } + result.FlatUnit, result.FlatStep, result.Moved = review.Line, -1, false + presentFlatReviewResult(slog.New(slog.DiscardHandler), output, result) + if boundary := <-queue.requests; boundary.Text != "Top of screen." { + t.Fatalf("partial top boundary: %+v", boundary) + } + result.FlatStep = 1 + presentFlatReviewResult(slog.New(slog.DiscardHandler), output, result) + if boundary := <-queue.requests; boundary.Text != "Bottom of screen." || len(queue.requests) != 0 { + t.Fatalf("partial bottom boundary or extra message: %+v", boundary) + } +} + +func TestProcessEventsPresentsFlatReviewThroughSpeechQueue(t *testing.T) { + id := func(path string) atspi.ObjectID { return atspi.NewObjectID(":1.42", path) } + snapshot := func(path, name, role string) atspi.Snapshot { + s := atspi.NewSnapshot(path, name, role, "", "") + s.BusName = ":1.42" + return s + } + root := snapshot("/window", "Window", "frame") + field := snapshot("/field", "Review field", "text") + geometry := atspi.Geometry{Bounds: atspi.Rectangle{Width: 200, Height: 50}, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + tree, err := atspi.NewAccessibleTree(id("/window"), []atspi.TreeNode{ + {Snapshot: root, Geometry: geometry, Children: []atspi.ObjectID{id("/field")}}, + {Snapshot: field, Geometry: geometry, Text: atspi.VisibleText{Known: true, Ranges: []atspi.TextRange{{Start: 0, End: 6, Text: "a 猫!oo", Bounds: geometry.Bounds}}}}, + }) + if err != nil { + t.Fatal(err) + } + adapter := &fakeAdapter{events: make(chan atspi.Event, 1), tree: tree} + worker, err := review.NewWorker(adapter, time.Second) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + speech := &fakeSpeechQueue{spoken: make(chan string, 8), interrupt: make(chan struct{}, 8)} + completed := make(chan error, 1) + go func() { + completed <- processEventsWithObjectReview(ctx, slog.New(slog.DiscardHandler), speech, adapter, nil, worker, 0) + }() + expect := func(want string) { + t.Helper() + select { + case got := <-speech.spoken: + if got != want { + t.Fatalf("speech=%q want=%q", got, want) + } + case <-time.After(time.Second): + t.Fatal("speech missing") + } + } + adapter.events <- atspi.NewEvent(atspi.FocusEvent, field) + expect("Review field, text") + worker.ReadFlat(review.Line, 0) + expect("a 猫!oo") + worker.ReadFlat(review.Line, -1) + expect("Top of screen.") + worker.ReadFlat(review.Line, 0) + expect("a 猫!oo") + worker.ReadFlat(review.Line, 1) + expect("Bottom of screen.") + worker.ReadFlat(review.Line, 0) + expect("a 猫!oo") + worker.ReadFlat(review.Character, 1) + expect("space") + worker.ReadFlat(review.Character, 1) + expect("猫") + worker.ReadFlat(review.Word, 0) + expect("猫!oo") + worker.ReadFlat(review.Character, 1) + expect("!") + worker.ReadFlat(review.Character, 1) + expect("o") + worker.ReadFlat(review.Character, 1) + expect("o") + cancel() + select { + case err := <-completed: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestFlatReviewResultUsesNativeFocusAndRejectsOldPage(t *testing.T) { + worker, err := review.NewWorker(&fakeAdapter{}, time.Second) + if err != nil { + t.Fatal(err) + } + document := atspi.NewObjectID(":1.42", "/document") + worker.SyncFocus(document) + result := review.Result{FlatUnit: review.Line, FlatFocus: document} + // A browse caret can be on a child while native focus remains here. + if !flatReviewResultCurrent(worker, result) { + t.Fatal("flat result from native document focus was discarded") + } + worker.ResetDocument(document) + if flatReviewResultCurrent(worker, result) { + t.Fatal("flat result from the previous page was accepted") + } + result.DocumentEpoch = 1 + worker.SyncFocus(atspi.NewObjectID(":1.42", "/address")) + if flatReviewResultCurrent(worker, result) { + t.Fatal("flat result after focus left the document was accepted") + } +} + +func TestFlatReviewLineBoundaryFeedback(t *testing.T) { + for _, tc := range []struct { + name string + step int + want string + }{ + {"top", -1, "Top of screen."}, + {"bottom", 1, "Bottom of screen."}, + } { + t.Run(tc.name, func(t *testing.T) { + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 1)} + result := review.Result{ + FlatUnit: review.Line, FlatStep: tc.step, FlatSpeech: review.FlatSpell, + FlatPosition: review.FlatPosition{Text: " Edge line"}, + } + for range 2 { + presentFlatReviewResult(slog.New(slog.DiscardHandler), queue, result) + select { + case request := <-queue.requests: + if request.Text != tc.want || request.Cause != "flat-review" { + t.Fatalf("boundary request = %+v", request) + } + if request.Line != nil || request.Character || len(request.Spelling) != 0 { + t.Fatalf("boundary retained content speech metadata: %+v", request) + } + default: + t.Fatal("boundary was silent") + } + } + }) + } +} + +func TestFlatReviewErrorsAndSilentBoundary(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 2)} + logger := slog.New(slog.DiscardHandler) + for _, result := range []review.Result{ + {FlatUnit: review.Word, FlatStep: -1}, + {FlatUnit: review.Word, FlatStep: 1}, + {FlatUnit: review.Character, FlatStep: -1}, + {FlatUnit: review.Character, FlatStep: 1}, + {FlatUnit: review.WordAbove}, + {FlatUnit: review.WordBelow}, + } { + presentFlatReviewResult(logger, queue, result) + select { + case <-queue.spoken: + t.Fatalf("boundary spoke for unit %d", result.FlatUnit) + default: + } + } + presentFlatReviewResult(logger, queue, review.Result{FlatUnit: review.Line, Err: review.ErrLimitedReview}) + if got := <-queue.spoken; got != "This window exceeds the current flat review text limit." { + t.Fatal(got) + } +} + +func TestFlatReviewWindowCommands(t *testing.T) { + if unit, step := flatReviewCommand(input.ReviewWindowStart); unit != review.WindowStart || step != 0 { + t.Fatalf("start = %d, %d", unit, step) + } + if unit, step := flatReviewCommand(input.ReviewWindowEnd); unit != review.WindowEnd || step != 0 { + t.Fatalf("end = %d, %d", unit, step) + } + if unit, step := flatReviewCommand(input.ReviewWordAbove); unit != review.WordAbove || step != 0 { + t.Fatalf("above = %d, %d", unit, step) + } + if unit, step := flatReviewCommand(input.ReviewWordBelow); unit != review.WordBelow || step != 0 { + t.Fatalf("below = %d, %d", unit, step) + } + if unit, step := flatReviewCommand(input.ReviewLineEnd); unit != review.LineEnd || step != 0 { + t.Fatalf("line end = %d, %d", unit, step) + } +} + +func TestFlatReviewBlankAndWhitespaceSpeech(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 1)} + logger := slog.New(slog.DiscardHandler) + for _, tc := range []struct { + unit review.FlatUnit + text, want string + }{ + {review.Line, "\n", "blank"}, + {review.Character, "\n", "blank"}, + {review.WindowEnd, "\n", "blank"}, + {review.Line, " ", "white space"}, + {review.Word, "\t", "white space"}, + {review.Character, " ", "space"}, + {review.LineEnd, "\n", "blank"}, + } { + presentFlatReviewResult(logger, queue, review.Result{FlatUnit: tc.unit, Moved: true, FlatPosition: review.FlatPosition{Text: tc.text}}) + if got := <-queue.spoken; got != tc.want { + t.Fatalf("unit=%v text=%q: got=%q want=%q", tc.unit, tc.text, got, tc.want) + } + } +} + +func TestFlatReviewCharacterVoice(t *testing.T) { + for _, unit := range []review.FlatUnit{review.Character, review.LineEnd, review.Word, review.Line} { + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 1)} + presentFlatReviewResult(slog.New(slog.DiscardHandler), queue, review.Result{Moved: true, FlatUnit: unit}) + request := <-queue.requests + want := unit == review.Character || unit == review.LineEnd + if request.Character != want { + t.Fatalf("unit %v: character = %v", unit, request.Character) + } + } +} diff --git a/internal/app/focus_gate.go b/internal/app/focus_gate.go new file mode 100644 index 0000000..d6a6f7c --- /dev/null +++ b/internal/app/focus_gate.go @@ -0,0 +1,157 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "sync" + "sync/atomic" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +type commandGrabController interface { + SetCommandGrabs(bool) +} + +type focusGate struct { + tentacleOutput *tentacleOutput + + ocr *ocrSession + mutex sync.Mutex + speech speechEnqueuer + suspended atomic.Bool + secure atomic.Bool + lockChanges chan struct{} + commands commandGrabController + internalUI interface{ InternalUIActive() bool } + braille *brailleWorker +} + +func newFocusGate(commands commandListener) *focusGate { + gate := &focusGate{lockChanges: make(chan struct{}, 1)} + if controller, ok := commands.(commandGrabController); ok { + gate.commands = controller + } + gate.internalUI, _ = commands.(interface{ InternalUIActive() bool }) + return gate +} + +func (gate *focusGate) SetSuspended(suspended bool) bool { + if gate == nil { + return false + } + if suspended { + gate.ocr.Retire() + } + gate.mutex.Lock() + defer gate.mutex.Unlock() + if !gate.suspended.CompareAndSwap(!suspended, suspended) { + return false + } + gate.retireTentacleOutput() + if gate.commands != nil { + gate.commands.SetCommandGrabs(!suspended && !gate.secure.Load()) + } + return true +} + +func (gate *focusGate) InternalUIActive() bool { + return gate != nil && gate.internalUI != nil && gate.internalUI.InternalUIActive() +} + +func (gate *focusGate) Suspended() bool { + return gate != nil && gate.suspended.Load() +} + +func (gate *focusGate) retireTentacleOutput() { + if gate != nil { + gate.tentacleOutput.Retire() + } +} + +func (gate *focusGate) dismiss_confirmation() { + if gate != nil && gate.braille != nil { + gate.braille.DismissConfirmation() + } +} + +type gatedSpeech struct { + speech speechEnqueuer + gate *focusGate +} + +func (speaker gatedSpeech) Enqueue(request speechRequest) { + if speaker.gate != nil { + speaker.gate.mutex.Lock() + defer speaker.gate.mutex.Unlock() + } + if speaker.gate.InternalUIActive() && request.Cause != "internal-ui" { + return + } + if speaker.gate.Locked() || speaker.gate.Suspended() && !request.BypassFocusGate { + return + } + speaker.speech.Enqueue(request) +} + +func (speaker gatedSpeech) Interrupt() { + if speaker.gate.InternalUIActive() { + return + } + speaker.InterruptInternalUI() +} + +func (speaker gatedSpeech) InterruptInternalUI() { + if speaker.gate != nil { + speaker.gate.mutex.Lock() + defer speaker.gate.mutex.Unlock() + } + if !speaker.gate.Locked() && !speaker.gate.Suspended() { + speaker.speech.Interrupt() + } +} + +func (speaker gatedSpeech) InterruptForUser() { + if speaker.gate.Locked() { + return + } + speaker.gate.dismiss_confirmation() + if interrupt, ok := speaker.speech.(interface{ InterruptForUser() }); ok { + interrupt.InterruptForUser() + } else { + speaker.Interrupt() + } +} + +func (speaker gatedSpeech) InterruptForInput(event input.Event) bool { + if speaker.gate.InternalUIActive() { + return false + } + if speaker.gate.Locked() { + return false + } + if speech, ok := speaker.speech.(interface{ InterruptForInput(input.Event) bool }); ok { + interrupted := speech.InterruptForInput(event) + if interrupted { + speaker.gate.dismiss_confirmation() + } + return interrupted + } + speaker.InterruptForUser() + return true +} diff --git a/internal/app/foreground_test.go b/internal/app/foreground_test.go new file mode 100644 index 0000000..8866a46 --- /dev/null +++ b/internal/app/foreground_test.go @@ -0,0 +1,203 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "log/slog" + "sync/atomic" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +type foregroundAdapter struct { + fakeAdapter + state atomic.Pointer[atspi.ForegroundState] + changes chan struct{} +} + +func TestForegroundAutocompletePopupRequiresOwnedEntry(t *testing.T) { + a := &foregroundAdapter{fakeAdapter: fakeAdapter{events: make(chan atspi.Event, 16)}, changes: make(chan struct{}, 1)} + state := atspi.ForegroundState{Client: xorg.Foreground{Known: true, Window: 101}, Epoch: 1} + a.state.Store(&state) + queue := &fakeSpeechQueue{spoken: make(chan string, 16)} + keys := &input.IntentTracker{} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, a, nil, nil, 0, nil, keys, nil, nil) + }() + defer func() { cancel(); <-done }() + + entry := ownerEvent(atspi.FocusedStateEvent, ":1.40", "/browser", "/address") + entry.Source.Role = "entry" + entry.Source.Autocomplete = true + entry.Source.Editable = true + entry.Source.Focused = true + entry.Detail1 = 1 + entry.Foreground = state + a.events <- entry + expectActivationSpeech(t, queue.spoken, "autocomplete") + + keys.Observe(input.NewKeyEvent(0, true, "Down")) + popup := ownerEvent(atspi.FocusedStateEvent, ":1.40", "/popup", "/item") + popup.Source.Role = "list item" + popup.Source.Name = "Suggestion" + popup.Source.Selected = true + popup.Source.AutocompletePopup = true + popup.Source.Focused = true + popup.Detail1 = 1 + popup.PopupFor = entry.Source.ID() + popup.Foreground = state + popup.ForegroundMismatch = true + a.events <- popup + expectActivationSpeech(t, queue.spoken, "Suggestion, list item, selected") + + // A different relation target or bus cannot borrow the browser's window. + for _, bad := range []atspi.Event{ + func() atspi.Event { e := popup; e.PopupFor = atspi.NewObjectID(":1.40", "/other-entry"); return e }(), + func() atspi.Event { e := popup; e.Source.BusName = ":1.41"; return e }(), + } { + bad.Source.Name = "Background suggestion" + a.events <- bad + } + // The popup must not replace the owned address entry or prevent typing. + insertion := atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry.Source, "z") + insertion.Window = entry.Window + insertion.Foreground = state + keys.Observe(input.NewKeyEvent(0, true, "z")) + a.events <- insertion + expectActivationSpeech(t, queue.spoken, "z") + + other := ownerEvent(atspi.FocusedStateEvent, ":1.41", "/other-window", "/button") + other.Source.Role = "push button" + other.Source.Name = "Other window" + other.Source.Focused = true + other.Detail1 = 1 + other.Foreground = state + a.events <- other + expectActivationSpeech(t, queue.spoken, "Other window, push button") + popup.Source.Name = "Inactive suggestion" + a.events <- popup + other.Source.Name = "Still foreground" + a.events <- other + expectActivationSpeech(t, queue.spoken, "Still foreground, push button") +} + +func TestAutocompletePopupNameChangesDoNotCue(t *testing.T) { + adapter := &foregroundAdapter{fakeAdapter: fakeAdapter{events: make(chan atspi.Event, 16)}, changes: make(chan struct{}, 1)} + state := atspi.ForegroundState{Client: xorg.Foreground{Known: true, Window: 101}, Epoch: 1} + adapter.state.Store(&state) + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 16)} + keys := &input.IntentTracker{} + options := presentation.DefaultOptions() + options.EnableSound = true + options.PlaySoundForRole = true + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, keys, nil, nil, options) + }() + defer func() { cancel(); <-done }() + + entry := ownerEvent(atspi.FocusedStateEvent, ":1.40", "/browser", "/address") + entry.Source.Role, entry.Source.Autocomplete, entry.Source.Editable, entry.Source.Focused = "entry", true, true, true + entry.Detail1, entry.Foreground = 1, state + adapter.events <- entry + if got := <-queue.requests; got.Text != "autocomplete" { + t.Fatalf("focus request = %#v", got) + } + keys.Observe(input.NewKeyEvent(0, true, "g")) + insertion := atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry.Source, "g") + insertion.Window, insertion.Foreground = entry.Window, state + adapter.events <- insertion + if got := <-queue.requests; got.Text != "g" || len(got.Sound) != 0 { + t.Fatalf("typing request = %#v", got) + } + popup := ownerEvent(atspi.AccessibleNameEvent, ":1.40", "/popup", "/item") + popup.Source.Role, popup.Source.AutocompletePopup = "list item", true + popup.PopupFor, popup.Foreground, popup.ForegroundMismatch = entry.Source.ID(), state, true + for _, name := range []string{"First suggestion", "Second suggestion", "Third suggestion"} { + popup.Source.Name = name + adapter.events <- popup + } + select { + case got := <-queue.requests: + t.Fatalf("popup name update produced output: %#v", got) + case <-time.After(300 * time.Millisecond): + } + keys.Observe(input.NewKeyEvent(0, true, "Down")) + selected := popup + selected.Type = atspi.FocusedStateEvent + selected.Detail1 = 1 + selected.Source.Selected = true + adapter.events <- selected + select { + case got := <-queue.requests: + if got.Text != "Third suggestion, list item, selected" { + t.Fatalf("selected popup item = %#v", got) + } + case <-time.After(time.Second): + t.Fatal("missing selected popup item") + } +} + +func (a *foregroundAdapter) Foreground() atspi.ForegroundState { return *a.state.Load() } +func (a *foregroundAdapter) ForegroundChanges() <-chan struct{} { return a.changes } + +func TestForegroundRetiresQueuedEventsAndClearsLocation(t *testing.T) { + for _, window := range []uint64{0, 202} { + t.Run(map[uint64]string{0: "empty workspace", 202: "other window"}[window], func(t *testing.T) { + a := &foregroundAdapter{fakeAdapter: fakeAdapter{events: make(chan atspi.Event, 16)}, changes: make(chan struct{}, 1)} + state := atspi.ForegroundState{Client: xorg.Foreground{Known: true, Window: 101}, Epoch: 1} + a.state.Store(&state) + queue := &fakeSpeechQueue{spoken: make(chan string, 16)} + where := make(chan input.Command) + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, a, where, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + event := ownerEvent(atspi.WindowActivatedEvent, ":1.5", "/window", "/button") + event.Source.Name = "Current" + event.Source.Role = "push button" + event.Foreground = state + a.events <- event + expectActivationSpeech(t, queue.spoken, "Current, push button") + next := atspi.ForegroundState{Client: xorg.Foreground{Known: true, Window: window}, Epoch: 2} + a.state.Store(&next) + // No wakeup is required: event/result consumers must check the latest + // atomic epoch even if the channel notification has not been selected. + event.Source.Name = "Stale" + a.events <- event + where <- input.WhereAmI + expectActivationSpeech(t, queue.spoken, "Could not find current location.") + event.Foreground = next + event.ForegroundMismatch = true + a.events <- event + where <- input.WhereAmI + expectActivationSpeech(t, queue.spoken, "Could not find current location.") + if window != 0 { + event.ForegroundMismatch = false + event.Source.Name = "New" + a.events <- event + expectActivationSpeech(t, queue.spoken, "New, push button") + deactivated := event + deactivated.Type = atspi.WindowDeactivatedEvent + a.events <- deactivated + where <- input.WhereAmI + expectActivationSpeech(t, queue.spoken, "New, push button") + } + }) + } +} diff --git a/internal/app/gui_table_presentation.go b/internal/app/gui_table_presentation.go new file mode 100644 index 0000000..feebcfa --- /dev/null +++ b/internal/app/gui_table_presentation.go @@ -0,0 +1,100 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +type guiTablePresentation struct { + options presentation.Options + table atspi.ObjectID + sequence uint64 + newDescription bool + skip bool +} + +func (state *eventLoopState) prepareGUITable(event atspi.Event, sequence uint64) guiTablePresentation { + if event.Type == atspi.WindowActivatedEvent { + state.tableDescriptionWindow = atspi.ObjectID{} + state.tableDescriptionText = "" + state.tableDescriptionAt = time.Time{} + state.lastTable = atspi.ObjectID{} + state.lastTableCell = atspi.ObjectID{} + } else if isFocusGainEvent(event) && event.Source.Role != "table" && event.Source.Role != "table cell" { + state.lastTable = atspi.ObjectID{} + state.lastTableCell = atspi.ObjectID{} + } + result := guiTablePresentation{ + options: state.presentationOptions, + table: atspi.NewObjectID(event.Source.BusName, event.Source.TablePath), + sequence: sequence, + } + result.newDescription = state.presentationOptions.SpeakDescription && event.Window.Valid() && + (event.Source.Role == "table" || event.Source.Role == "table cell") && + event.WindowDescription != "" && event.WindowDescription != event.Source.Description && + (state.tableDescriptionWindow != event.Window || state.tableDescriptionText != event.WindowDescription) + sameRow := event.Source.Role == "table cell" && + event.Source.TablePositionKnown && result.table.Valid() && result.table == state.lastTable && + event.Source.TableRowIndex == state.lastTableRow + if sameRow { + unchangedRow := presentation.FocusTextWithOptions(event.Source, state.presentationOptions) == state.lastTableText + if unchangedRow || event.Source.ID() != state.lastTableCell { + result.options.ReadFullRowInGUITable = false + if result.options.Reading != nil { + reading := *result.options.Reading + reading.ReadFullRowInDocumentTable, reading.ReadFullRowInSpreadSheet = false, false + result.options.Reading = &reading + } + } + sameAction := sequence != 0 && sequence == state.lastTableSequence || + sequence == 0 && time.Since(state.lastTableAt) < 75*time.Millisecond + result.skip = sameAction && !result.newDescription && unchangedRow && + (state.lastTableFullRow || event.Source.TableColumnIndex == state.lastTableColumn) + } + return result +} + +func (state *eventLoopState) decorateGUITable(event atspi.Event, spoken presentation.Speech, result guiTablePresentation) (presentation.Speech, bool) { + if event.Source.Role == "table cell" && event.Source.GUITable && result.table.Valid() && + result.table != state.lastTable && event.Source.TableName != "" && + (isFocusGainEvent(event) || isManagedDescendantEvent(event.Type)) && + event.Type != atspi.WindowActivatedEvent { + spoken = spoken.Prepend(event.Source.TableName, ", ") + } + appendFocus := isFocusGainEvent(event) && event.Type != atspi.WindowActivatedEvent && + state.tableDescriptionWindow.Valid() && event.Window == state.tableDescriptionWindow && + time.Since(state.tableDescriptionAt) < 300*time.Millisecond + if result.newDescription { + if event.Type != atspi.WindowActivatedEvent { + spoken = spoken.Append(event.WindowDescription, ", ") + } + state.tableDescriptionWindow = event.Window + state.tableDescriptionText = event.WindowDescription + state.tableDescriptionAt = time.Now() + } + return spoken, appendFocus +} + +func (state *eventLoopState) rememberGUITable(event atspi.Event, result guiTablePresentation) { + if event.Source.Role == "table cell" && event.Source.TablePositionKnown && result.table.Valid() { + state.lastTable = result.table + state.lastTableCell = event.Source.ID() + state.lastTableText = presentation.FocusTextWithOptions(event.Source, state.presentationOptions) + state.lastTableRow = event.Source.TableRowIndex + state.lastTableColumn = event.Source.TableColumnIndex + state.lastTableSequence = result.sequence + state.lastTableAt = time.Now() + state.lastTableFullRow = presentation.FullRowEnabled(event.Source, result.options) && event.Source.TableRowText != "" + } else if event.Source.Role == "table" && isFocusGainEvent(event) { + state.lastTable = event.Source.ID() + state.lastTableCell = atspi.ObjectID{} + state.lastTableRow = -1 + } +} diff --git a/internal/app/gui_table_test.go b/internal/app/gui_table_test.go new file mode 100644 index 0000000..6f5fde7 --- /dev/null +++ b/internal/app/gui_table_test.go @@ -0,0 +1,103 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestGUITableNormalizedFocusRetainsOwnerAndTitle(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 16), requests: make(chan speechRequest, 16)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 16)} + inputs := &sequencedInputActivity{} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), speech, adapter, + nil, nil, 0, nil, inputs, nil, nil) + close(completed) + }() + window := atspi.NewObjectID(":1.22", "/preferences") + cell_event := func(path, name, rowText string, row, column int, eventType string) atspi.Event { + cell := atspi.NewSnapshot(path, name, "table cell", "", "") + cell.BusName = window.BusName + cell.TablePath, cell.TableName = "/preferences/reading", "Reading settings" + cell.TableRowIndex, cell.TableColumnIndex = row, column + cell.TablePositionKnown, cell.GUITable = true, true + cell.TableRowText = rowText + event := atspi.NewManagedDescendantEvent(eventType, cell.TablePath, cell) + event.Window = window + if eventType == atspi.FocusedStateEvent { + event.Detail1 = 1 + } + return event + } + expect_speech := func(event atspi.Event, sequence uint64, want string) { + t.Helper() + inputs.set(sequence) + adapter.events <- event + select { + case request := <-speech.requests: + if request.Text != want { + t.Fatalf("%s: got %q, want %q", event.Type, request.Text, want) + } + case <-time.After(time.Second): + t.Fatalf("%s produced no speech", event.Type) + } + } + // The adapter resolves the table's initial focus to a selected cell. GTK + // need not send another focused-state event as Up/Down changes rows. + first := cell_event("/reading/0/state", "unchecked", "unchecked, Only speak displayed text", 0, 0, atspi.FocusedStateEvent) + expect_speech(first, 1, "Reading settings, unchecked, Only speak displayed text") + second := cell_event("/reading/1/state", "checked", "checked, Break speech into chunks between pauses", 1, 0, atspi.SelectionChangedEvent) + expect_speech(second, 2, "checked, Break speech into chunks between pauses") + duplicate := second + duplicate.Type = atspi.ActiveDescendantEvent + adapter.events <- duplicate + right := cell_event("/reading/1/label", "Break speech into chunks between pauses", second.Source.TableRowText, 1, 1, atspi.ActiveDescendantEvent) + expect_speech(right, 3, "Break speech into chunks between pauses") + left := second + left.Type = atspi.ActiveDescendantEvent + expect_speech(left, 4, "checked") + up := first + up.Type = atspi.SelectionChangedEvent + expect_speech(up, 5, "unchecked, Only speak displayed text") + // Background tables and another bus cannot inherit the focused table. + other := second + other.OriginPath, other.Source.TablePath = "/unrelated", "/unrelated" + other.Source.Path = "/unrelated/cell" + adapter.events <- other + other.OriginPath, other.Source.TablePath = first.OriginPath, first.Source.TablePath + other.Source.BusName = ":1.99" + adapter.events <- other + expect_speech(second, 6, "checked, Break speech into chunks between pauses") + // A third description cell participates in full-row speech, while + // horizontal movement reads just that cell. + description := "Reads numbers one digit at a time." + rowText := "unchecked, Speak numbers as digits, " + description + third := cell_event("/reading/2/state", "unchecked", rowText, 2, 0, atspi.SelectionChangedEvent) + expect_speech(third, 7, rowText) + descriptionCell := cell_event("/reading/2/description", description, rowText, 2, 2, atspi.ActiveDescendantEvent) + expect_speech(descriptionCell, 8, description) + button := atspi.NewSnapshot("/preferences/apply", "Apply", "button", "", "") + button.BusName = window.BusName + focus := atspi.NewEvent(atspi.FocusEvent, button) + focus.Window = window + expect_speech(focus, 9, "Apply, button") + adapter.events <- up // A table selection after leaving the table is noise. + // Returning through a cell focus event establishes ownership and speaks + // the table name again, without changing the user's row-reading option. + first.OriginPath = first.Source.Path + expect_speech(first, 10, "Reading settings, unchecked, Only speak displayed text") + expect_speech(second, 11, "checked, Break speech into chunks between pauses") + cancel() + <-completed +} diff --git a/internal/app/i38lock_feedback_native_test.go b/internal/app/i38lock_feedback_native_test.go new file mode 100644 index 0000000..ed52e8e --- /dev/null +++ b/internal/app/i38lock_feedback_native_test.go @@ -0,0 +1,192 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "context" + "fmt" + "log/slog" + "os" + "os/exec" + "path/filepath" + "strings" + "sync/atomic" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/remote" +) + +type lockerFeedbackSpeaker struct{ spoken chan string } + +func (speaker *lockerFeedbackSpeaker) Connect(context.Context) error { return nil } +func (speaker *lockerFeedbackSpeaker) Close(context.Context) error { return nil } +func (speaker *lockerFeedbackSpeaker) Cancel(context.Context) error { return nil } +func (speaker *lockerFeedbackSpeaker) Speak(_ context.Context, text string) error { + speaker.spoken <- text + return nil +} + +type lockerFeedbackPresenter struct { + remoteSpeech + interrupts atomic.Int32 + presented chan struct{} +} + +func (presenter *lockerFeedbackPresenter) PresentMessage(message string) bool { + accepted := presenter.remoteSpeech.PresentMessage(message) + presenter.presented <- struct{}{} + return accepted +} + +func (presenter *lockerFeedbackPresenter) CancelSpeech() bool { + presenter.interrupts.Add(1) + return presenter.remoteSpeech.CancelSpeech() +} + +// Compile the actual locker feedback implementation without X grabs or PAM. +// This catches mismatches in its bus discovery and complete D-Bus call sequence. +func TestNativeI38lockFeedback(t *testing.T) { + sourceDirectory := os.Getenv("CTHULHU_I38LOCK_SOURCE") + if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" || sourceDirectory == "" { + t.Skip("requires private session bus and CTHULHU_I38LOCK_SOURCE checkout") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + directory := t.TempDir() + harness := filepath.Join(directory, "feedback.c") + source := `#include +#include "accessibility_feedback.h" +int main(void) { + if (!accessibility_feedback_start(-1)) return 1; + accessibility_feedback_notify(ACCESSIBILITY_SCREEN_LOCKED); + puts("ready"); + fflush(stdout); + int event; + while (scanf("%d", &event) == 1) { + accessibility_feedback_notify((accessibility_feedback_t)event); + } + return 0; +} +` + if err := os.WriteFile(harness, []byte(source), 0600); err != nil { + t.Fatal(err) + } + flags, err := exec.CommandContext(ctx, "pkg-config", "--cflags", "--libs", "gio-2.0").Output() + if err != nil { + t.Fatal(err) + } + executable := filepath.Join(directory, "i38lock") + arguments := []string{"-o", executable, harness, filepath.Join(sourceDirectory, "accessibility_feedback.c"), "-I" + filepath.Join(sourceDirectory, "include")} + arguments = append(arguments, strings.Fields(string(flags))...) + if output, err := exec.CommandContext(ctx, "cc", arguments...).CombinedOutput(); err != nil { + t.Fatalf("compile actual feedback: %v\n%s", err, output) + } + logger := slog.New(slog.DiscardHandler) + speaker := &lockerFeedbackSpeaker{spoken: make(chan string, 32)} + worker := newSpeechWorker(logger, speaker) + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + display := &brailleWorker{cancel: func() {}, connected: true, wake: make(chan struct{}, 1)} + gate := newFocusGate(nil) + states := make(chan bool, 8) + monitor := &screenLockMonitor{logger: logger, setActive: func(active bool) { + gate.SetLocked(active, nil, nil, nil, worker, display) + states <- active + }} + if err := monitor.Start(ctx); err != nil { + t.Fatal(err) + } + defer monitor.Stop(context.Background()) + presenter := &lockerFeedbackPresenter{remoteSpeech: remoteSpeech{speech: worker, braille: lockFeedbackBraille{display}}, presented: make(chan struct{}, 32)} + service := remote.New(logger, presenter) + if err := service.Start(ctx); err != nil { + t.Fatal(err) + } + defer service.Stop(context.Background()) + process := exec.CommandContext(ctx, executable) + stdin, err := process.StdinPipe() + if err != nil { + t.Fatal(err) + } + defer stdin.Close() + stdout, err := process.StdoutPipe() + if err != nil { + t.Fatal(err) + } + process.Stderr = os.Stderr + if err := process.Start(); err != nil { + t.Fatal(err) + } + defer process.Process.Kill() + ready := make(chan string, 1) + go func() { line, _ := bufio.NewReader(stdout).ReadString('\n'); ready <- line }() + select { + case line := <-ready: + if line != "ready\n" { + t.Fatalf("locker ready: %q", line) + } + case <-ctx.Done(): + t.Fatal("locker startup timed out") + } + expectState := func(want bool) { + t.Helper() + select { + case got := <-states: + if got != want { + t.Fatalf("secure state=%v want=%v", got, want) + } + case <-ctx.Done(): + t.Fatal("missing lock transition") + } + } + expectState(true) + // Local output is blocked. Locker feedback travels through self-voice and + // does not depend on enabling a local key-echo presenter. + worker.Enqueue(speechRequest{Text: "Desktop notification", Cause: "notification"}) + for index, message := range []string{"Screen locked. Enter password.", "Enter password.", "star", "backspace star", "backspace blank", "Password cleared.", "Verifying.", "Authenticated.", "Incorrect password. Enter password."} { + if index > 0 { + if _, err := fmt.Fprintln(stdin, index); err != nil { + t.Fatal(err) + } + } + select { + case spoken := <-speaker.spoken: + if spoken != message { + t.Fatalf("feedback %d = %q want=%q", index, spoken, message) + } + case <-ctx.Done(): + t.Fatalf("missing feedback %d: %q", index, message) + } + select { + case <-presenter.presented: + case <-ctx.Done(): + t.Fatal("presentation did not complete") + } + if got := presenter.interrupts.Load(); got != 0 { + t.Fatalf("feedback %d interrupts=%d", index, got) + } + if got := display.current().Text; got != message { + t.Fatalf("braille feedback=%q want=%q", got, message) + } + } + stdin.Close() + if err := process.Wait(); err != nil { + t.Fatal(err) + } + expectState(false) + worker.Enqueue(speechRequest{Text: "Desktop resumed", Cause: "focus"}) + select { + case spoken := <-speaker.spoken: + if spoken != "Desktop resumed" { + t.Fatalf("unlock speech=%q", spoken) + } + case <-ctx.Done(): + t.Fatal("desktop speech did not resume") + } +} diff --git a/internal/app/indentation.go b/internal/app/indentation.go new file mode 100644 index 0000000..dcdd92b --- /dev/null +++ b/internal/app/indentation.go @@ -0,0 +1,89 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "fmt" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +type speechLine struct { + Object atspi.ObjectID + Raw string +} +type indentationData struct { + signature string + columns int +} +type indentationHistory map[atspi.ObjectID]indentationData + +func indentation_data(line string) indentationData { + var data indentationData + for _, value := range line { + switch value { + case ' ', '\u00a0': + data.columns++ + value = ' ' + case '\t': + data.columns += 4 - data.columns%4 + default: + return data + } + data.signature += string(value) + } + return data +} + +func (worker *speechWorker) line_text(text string, line *speechLine) string { + if line == nil || worker.reading == nil { + return text + } + data := indentation_data(line.Raw) + previous, known := worker.indentation[line.Object] + if worker.indentation == nil || len(worker.indentation) >= 128 && !known { + worker.indentation = make(indentationHistory) + } + worker.indentation[line.Object] = data + settings := worker.reading() + if !settings.EnableIndentation || settings.OnlySpeakDisplayedText || known && previous.signature == data.signature { + return text + } + mode := settings.IndentationPresentationMode + if (mode == "beeps" || mode == "both") && worker.indentationCue != nil { + frequency := min(2700, 200+data.columns*30) + if data.columns > previous.columns { + frequency += 50 + } else if data.columns < previous.columns { + frequency = max(100, frequency-50) + } + worker.indentationCue(sound.Cue{Name: sound.IndentationCueName(frequency)}) + } + if mode == "beeps" { + return text + } + word := "columns" + if data.columns == 1 { + word = "column" + } + return strings.TrimSuffix(fmt.Sprintf("indentation %d %s, %s", data.columns, word, text), ", ") +} + +func document_speech_line(line atspi.DocumentLine) *speechLine { + if len(line.Contents) == 0 { + return nil + } + content := line.Contents[0] + if content.Snapshot.Role == "password text" { + return nil + } + raw := content.RawText + if raw == "" { + raw = content.Text + } + return &speechLine{Object: content.Snapshot.ID(), Raw: raw} +} diff --git a/internal/app/input_events.go b/internal/app/input_events.go new file mode 100644 index 0000000..eb16a46 --- /dev/null +++ b/internal/app/input_events.go @@ -0,0 +1,128 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func processInputEvents( + ctx context.Context, + logger *slog.Logger, + speech speechEnqueuer, + listener InputListener, + echoSettings input.EchoSettings, + live *liveSettings, + commands commandListener, + ocrSessions ...*ocrSession, +) { + echo := newKeyEchoPolicy(echoSettings) + var lastOverflow uint64 + for { + select { + case <-ctx.Done(): + return + case event, ok := <-listener.Events(): + if !ok { + return + } + if guarded, ok := speech.(gatedSpeech); ok && guarded.gate.Locked() { + echo.Reset() + continue + } + if modal, ok := commands.(interface{ InternalUIEchoActive() bool }); ok && modal.InternalUIEchoActive() { + echo.Reset() + continue + } + if learner, ok := commands.(interface{ LearnModeEchoActive() bool }); ok && learner.LearnModeEchoActive() { + echo.Reset() + continue + } + if overflow := listener.Overflow(); overflow > lastOverflow { + logger.Warn("X11 event queue overflow", "dropped_events", overflow-lastOverflow) + lastOverflow = overflow + echo.Reset() + } + if len(ocrSessions) > 0 { + ocrSessions[0].Input(event) + } + interruption := input.InterruptionSettings{Mode: input.InterruptAllKeys} + custom := false + if live != nil { + settings := live.Load() + interruption = settings.SpeechInterruption + echo.settings = inputEchoSettingsFromConfig(settings) + custom = customEcho(settings, "key") + if settings.KeyEchoInEditFieldsOnly && (live.editFieldFocused == nil || !live.editFieldFocused()) { + echo.settings.EnableKeyEcho = false + } + } + if interruption.ShouldInterrupt(event) { + if interrupt, ok := speech.(interface{ InterruptForInput(input.Event) bool }); ok { + if !interrupt.InterruptForInput(event) { + continue + } + } else if interrupt, ok := speech.(interface{ InterruptForUser() }); ok { + interrupt.InterruptForUser() + } else { + speech.Interrupt() + } + logger.Debug("queued speech interrupted by key press", "input_timestamp", event.Timestamp, + "input_keycode", event.Keycode, "input_repeat", event.Repeat) + } + if text := echo.Text(event); text != "" { + speech.Enqueue(speechRequest{Text: text, Role: "key", Cause: "key-echo", CustomEcho: custom}) + logger.Debug("queued non-printable key echo", "kind", event.Kind) + } + } + } +} + +type keyEchoPolicy struct { + settings input.EchoSettings + cthulhuModifiers map[string]struct{} + heldCthulhuKeys [256]bool +} + +func newKeyEchoPolicy(settings input.EchoSettings) *keyEchoPolicy { + modifiers := make(map[string]struct{}, len(settings.CthulhuModifierKeys)) + for _, name := range settings.CthulhuModifierKeys { + modifiers[name] = struct{}{} + } + return &keyEchoPolicy{settings: settings, cthulhuModifiers: modifiers} +} + +func (policy *keyEchoPolicy) Text(event input.Event) string { + if _, isCthulhuModifier := policy.cthulhuModifiers[event.Name]; isCthulhuModifier { + policy.heldCthulhuKeys[event.Keycode] = event.Pressed + return "" + } + for _, held := range policy.heldCthulhuKeys { + if held { + return "" + } + } + return input.EchoText(event, policy.settings) +} + +func (policy *keyEchoPolicy) Reset() { + clear(policy.heldCthulhuKeys[:]) +} diff --git a/internal/app/input_events_test.go b/internal/app/input_events_test.go new file mode 100644 index 0000000..0b58073 --- /dev/null +++ b/internal/app/input_events_test.go @@ -0,0 +1,168 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +func TestProcessInputEventsInterruptsSpeechOnKeyPress(t *testing.T) { + speech := &fakeSpeechQueue{ + spoken: make(chan string, 1), + interrupt: make(chan struct{}, 3), + } + listener := &fakeInputListener{ + events: make(chan input.Event, 4), + modifierKeycodes: input.NewModifierKeycodes(37), + } + listener.events <- input.Event{Keycode: 37, Pressed: false} + listener.events <- input.NewKeyEvent(111, true, "Up") + listener.events <- input.NewKeyEvent(111, false, "Up") + listener.events <- input.Event{Keycode: 37, Pressed: true} + close(listener.events) + processInputEvents(context.Background(), slog.New(slog.DiscardHandler), speech, listener, input.EchoSettings{}, nil, nil) + if got := len(speech.interrupt); got != 2 { + t.Fatalf("interrupts = %d, want 2 for Up and Control presses", got) + } +} + +func TestProcessInputEventsEchoesConfiguredNonPrintableKeys(t *testing.T) { + speech := &fakeSpeechQueue{ + spoken: make(chan string, 3), + interrupt: make(chan struct{}, 4), + } + listener := &fakeInputListener{ + events: make(chan input.Event, 5), + modifierKeycodes: input.NewModifierKeycodes(37), + } + ctx, cancel := context.WithCancel(context.Background()) + completed := make(chan struct{}) + go func() { + processInputEvents(ctx, slog.New(slog.DiscardHandler), speech, listener, input.EchoSettings{ + EnableKeyEcho: true, EnableModifierKeys: true, EnableFunctionKeys: true, + CthulhuModifierKeys: []string{"Insert", "KP_Insert"}, + }, nil, nil) + close(completed) + }() + + listener.events <- input.NewKeyEvent(37, true, "Control_L") + listener.events <- input.NewKeyEvent(118, true, "Insert") + listener.events <- input.NewKeyEvent(67, true, "F1") + listener.events <- input.NewKeyEvent(118, false, "Insert") + listener.events <- input.NewKeyEvent(68, true, "F2") + + select { + case text := <-speech.spoken: + if text != "left control" { + t.Fatalf("modifier echo = %q", text) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for modifier echo") + } + select { + case text := <-speech.spoken: + if text != "f2" { + t.Fatalf("Cthulhu chord key echo leaked as %q before f2", text) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for key echo after Cthulhu modifier release") + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for input event loop to stop") + } +} + +func TestProcessEventsAppliesPrintableKeyEchoSettings(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + ctx, cancel := context.WithCancel(context.Background()) + completed := make(chan struct{}) + options := presentation.DefaultOptions() + options.EnableAlphabeticKeys = false + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0, options) + close(completed) + }() + + snapshot := atspi.NewSnapshot("/accessible/editor", "", "text", "", "") + snapshot.Editable = true + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, "a") + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, "pasted text") + select { + case text := <-speech.spoken: + if text != "pasted text" { + t.Fatalf("disabled alphabetic key echo spoke %q before multi-character insertion", text) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for multi-character insertion") + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestProcessEventsRetainsPriorLineForSentenceEchoOnNewline(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + ctx, cancel := context.WithCancel(context.Background()) + completed := make(chan struct{}) + options := presentation.DefaultOptions() + options.EnableEchoBySentence = true + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0, options) + close(completed) + }() + + snapshot := atspi.NewSnapshot("/accessible/editor", "", "text", "", "Line without punctuation") + snapshot.Editable = true + snapshot.TextBeforeCaret = "Line without punctuation" + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, "n") + blankLine := atspi.NewSnapshot("/accessible/editor", "", "text", "", "") + blankLine.Editable = true + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, blankLine, "\n") + + for _, want := range []string{"n", "Line without punctuation"} { + select { + case text := <-speech.spoken: + if text != want { + t.Fatalf("typing echo = %q, want %q", text, want) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for typing echo %q", want) + } + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} diff --git a/internal/app/internal_ui.go b/internal/app/internal_ui.go new file mode 100644 index 0000000..7a64559 --- /dev/null +++ b/internal/app/internal_ui.go @@ -0,0 +1,419 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "io" + "os/exec" + "strconv" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type internalUIKeys interface { + InternalUISession() uint64 + BeginInternalUI(context.Context) (uint64, error) + EndInternalUI(context.Context, uint64) error +} +type accessibleActionSource interface { + AccessibleActions(context.Context, atspi.ObjectID) (atspi.ActionSet, error) + PerformAccessibleAction(context.Context, atspi.ActionTarget, string) error +} +type internalUIResult struct { + Activated string + Values map[string]interaction.Value + Cancelled bool + Err error +} +type internalUINotice struct { + ctx context.Context + value interaction.Presentation +} +type internalUIRequest struct { + ctx context.Context + session *interaction.Session + result chan internalUIResult + ready chan error +} + +// internalUI owns one modal session on its worker. The bounded event channel +// keeps AT-SPI/clipboard latency off the native input and command consumers. +// Core clients can Open a form and receive its submitted values/cancellation. +type internalUI struct { + documents documentListSource + keys internalUIKeys + actions accessibleActionSource + interest interface { + ObjectOfInterest(context.Context) (review.Interest, error) + } + speech speechEnqueuer + braille *brailleWorker + gate *focusGate + notices chan internalUINotice + events chan input.CommandEvent + requests chan internalUIRequest + done chan struct{} +} + +func (ui *internalUI) Open(ctx context.Context, form interaction.Form) (<-chan internalUIResult, error) { + session, err := interaction.NewSession(form) + if err != nil { + return nil, err + } + request := internalUIRequest{ctx: ctx, session: session, result: make(chan internalUIResult, 1), ready: make(chan error, 1)} + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-ui.done: + return nil, errors.New("internal UI stopped") + default: + } + select { + case ui.requests <- request: + default: + return nil, errors.New("internal UI busy") + } + select { + case err := <-request.ready: + if err != nil { + return nil, err + } + return request.result, nil + case <-ctx.Done(): + return nil, ctx.Err() + case <-ui.done: + return nil, errors.New("internal UI stopped") + } +} +func (ui *internalUI) Notice(ctx context.Context, value tentaclewire.Presentation) { + if value.Speech == "" && value.Braille == "" { + return + } + select { + case ui.notices <- internalUINotice{ctx, interaction.Presentation{Speech: value.Speech, Braille: value.Braille, Cursor: -1}}: + default: + } +} +func (ui *internalUI) Handle(event input.CommandEvent) bool { + _, browserList := input.LookupDocumentList(event.Command) + if ui == nil || !browserList && event.Command != input.ShowActions && event.Command != input.InternalUIKey && event.Command != input.InternalUIDismiss { + return false + } + select { + case ui.events <- event: + default: + return false + } + return true +} + +func (ui *internalUI) present(output interaction.Presentation) { + if ui.gate.Locked() || ui.gate.Suspended() { + return + } + if output.Speech != "" { + ui.speech.Enqueue(speechRequest{Text: output.Speech, Role: "system", Cause: "internal-ui"}) + } + if ui.braille != nil && output.Braille != "" { + ui.braille.SetInternalUIFrame(&braille.Frame{Text: output.Braille, Cursor: output.Cursor}) + } +} + +func (ui *internalUI) run(ctx context.Context) { + defer close(ui.done) + var session *interaction.Session + var sessionID uint64 + var target atspi.ActionTarget + var documentList review.DocumentListSnapshot + var result chan internalUIResult + var requestDone <-chan struct{} + finish := func(reply internalUIResult) error { + var closeErr error + if sessionID != 0 { + closeCtx, cancel := context.WithTimeout(ctx, time.Second) + closeErr = ui.keys.EndInternalUI(closeCtx, sessionID) + cancel() + } + if ui.braille != nil { + ui.braille.SetInternalUIFrame(nil) + } + if result != nil { + if reply.Err == nil { + reply.Err = closeErr + } + result <- reply + close(result) + } + session, sessionID, result, requestDone = nil, 0, nil, nil + target = atspi.ActionTarget{} + documentList = review.DocumentListSnapshot{} + return closeErr + } + defer func() { finish(internalUIResult{Cancelled: true}) }() + // Native capture can be revoked by lock, focus change or handoff without a + // command being delivered (secure input deliberately drains command queues). + ticker := time.NewTicker(50 * time.Millisecond) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-requestDone: + finish(internalUIResult{Cancelled: true}) + case <-ticker.C: + if sessionID != 0 && ui.keys.InternalUISession() != sessionID { + finish(internalUIResult{Cancelled: true}) + } + case notice := <-ui.notices: + if sessionID != 0 && requestDone == notice.ctx.Done() && ui.keys.InternalUISession() == sessionID { + ui.present(notice.value) + } + case request := <-ui.requests: + if sessionID != 0 { + request.ready <- errors.New("internal UI busy") + close(request.result) + continue + } + var err error + sessionID, err = ui.keys.BeginInternalUI(request.ctx) + if err != nil { + request.ready <- err + close(request.result) + continue + } + session, result, requestDone = request.session, request.result, request.ctx.Done() + ui.present(session.Opening()) + request.ready <- nil + case event := <-ui.events: + if binding, ok := input.LookupDocumentList(event.Command); ok { + if sessionID != 0 { + continue + } + lookupCtx, cancel := context.WithTimeout(ctx, 3*time.Second) + var err error + sessionID, err = ui.keys.BeginInternalUI(lookupCtx) + if err == nil { + session, documentList, err = ui.browserList(lookupCtx, binding) + } + cancel() + if sessionID == 0 || ui.keys.InternalUISession() != sessionID { + finish(internalUIResult{Cancelled: true}) + continue + } + if err != nil || session == nil { + message := binding.Title + ": 0 items found" + if err != nil { + message = "Browser list unavailable" + } + finish(internalUIResult{Err: err}) + ui.browserListMessage(message) + continue + } + ui.present(session.Opening()) + continue + } + if event.Command == input.ShowActions { + if sessionID != 0 { + finish(internalUIResult{Cancelled: true}) + } + sessionID = event.UISession + if sessionID == 0 || ui.actions == nil || ui.interest == nil { + finish(internalUIResult{Err: errors.New("actions unavailable")}) + ui.speech.Enqueue(speechRequest{Text: "Actions unavailable", Role: "system", Cause: "internal-ui"}) + if ui.braille != nil { + ui.braille.EnqueueMessage("Actions unavailable") + } + continue + } + lookupCtx, cancel := context.WithTimeout(ctx, 2*time.Second) + interest, err := ui.interest.ObjectOfInterest(lookupCtx) + var actions atspi.ActionSet + if err == nil { + actions, err = ui.actions.AccessibleActions(lookupCtx, interest.Object) + } + cancel() + if ui.keys.InternalUISession() != sessionID { + finish(internalUIResult{Cancelled: true}) + continue + } + if err != nil || len(actions.Actions) == 0 { + finish(internalUIResult{Err: err}) + message := "No actions found" + if err != nil { + message = "Actions unavailable" + } + ui.speech.Enqueue(speechRequest{Text: message, Role: "system", Cause: "internal-ui"}) + if ui.braille != nil { + ui.braille.EnqueueMessage(message) + } + continue + } + items := make([]interaction.Item, 0, len(actions.Actions)) + for _, action := range actions.Actions { + items = append(items, interaction.Item{ID: action.Name, Label: action.Label}) + } + session, err = interaction.NewSession(interaction.Form{Title: "Actions", Elements: []interaction.Element{{ID: "actions", Label: "Actions", Kind: interaction.List, Items: items}}}) + if err != nil { + finish(internalUIResult{Err: err}) + continue + } + target = actions.Target + ui.present(session.Opening()) + continue + } + if session == nil || event.UISession != sessionID { + continue + } + if event.Command == input.InternalUIDismiss { + finish(internalUIResult{Cancelled: true}) + continue + } + key := internal_ui_event(event) + effect := session.Handle(key) + if effect.Cancelled { + finish(internalUIResult{Cancelled: true}) + continue + } + if ui.keys.InternalUISession() != sessionID { + finish(internalUIResult{Cancelled: true}) + continue + } + if effect.Paste { + clipboardCtx, cancel := context.WithTimeout(ctx, time.Second) + text, err := read_internal_clipboard(clipboardCtx) + cancel() + if ui.keys.InternalUISession() != sessionID { + finish(internalUIResult{Cancelled: true}) + continue + } + if err == nil { + effect = session.Insert(text) + } else { + effect.Presentation = interaction.Presentation{Speech: "Clipboard text unavailable", Braille: "Clipboard text unavailable", Cursor: -1} + } + } + if effect.Copy != nil { + copyCtx, cancel := context.WithTimeout(ctx, time.Second) + err := (xclipOCRCopier{}).Copy(copyCtx, *effect.Copy) + cancel() + if ui.keys.InternalUISession() != sessionID { + finish(internalUIResult{Cancelled: true}) + continue + } + message := "Copied" + if err != nil { + message = "Copy failed" + } else if strings.EqualFold(key.Text, "x") { + effect = session.Handle(interaction.Event{Key: interaction.Delete}) + message = "Cut" + } + effect.Presentation = session.Presentation() + effect.Speech = message + } + if effect.Activated != "" { + values := session.Values() + actionTarget := target + selectedList := documentList + closeErr := finish(internalUIResult{Activated: effect.Activated, Values: values}) + if len(selectedList.Entries) > 0 && closeErr == nil && !ui.gate.Locked() && !ui.gate.Suspended() { + index, err := strconv.Atoi(effect.Activated) + if err == nil { + err = ui.documents.SelectDocumentList(selectedList, index) + } + if err != nil { + ui.browserListMessage("Browser item unavailable") + } + } + if actionTarget.Object.Valid() && closeErr == nil { + actionCtx, cancel := context.WithTimeout(ctx, 2*time.Second) + err := ui.actions.PerformAccessibleAction(actionCtx, actionTarget, effect.Activated) + cancel() + if err != nil && !ui.gate.Locked() && !ui.gate.Suspended() { + ui.speech.Enqueue(speechRequest{Text: "Action unavailable", Role: "system", Cause: "internal-ui"}) + if ui.braille != nil { + ui.braille.EnqueueMessage("Action unavailable") + } + } + } else if actionTarget.Object.Valid() && !ui.gate.Locked() && !ui.gate.Suspended() { + ui.speech.Enqueue(speechRequest{Text: "Action unavailable", Role: "system", Cause: "internal-ui"}) + if ui.braille != nil { + ui.braille.EnqueueMessage("Action unavailable") + } + } + continue + } + if effect.Speech != "" || effect.Braille != "" { + ui.present(effect.Presentation) + } + } + } +} + +func internal_ui_event(event input.CommandEvent) interaction.Event { + key := interaction.Text + switch event.Chord.Symbol { + case 0xff52, 0xff97: + key = interaction.Up + case 0xff54, 0xff99: + key = interaction.Down + case 0xff51, 0xff96: + key = interaction.Left + case 0xff53, 0xff98: + key = interaction.Right + case 0xff50, 0xff95: + key = interaction.Home + case 0xff57, 0xff9c: + key = interaction.End + case 0xff55, 0xff9a: + key = interaction.PageUp + case 0xff56, 0xff9b: + key = interaction.PageDown + case 0xff09, 0xfe20: + key = interaction.Tab + case 0xff0d, 0xff8d: + key = interaction.Enter + case 0xff1b: + key = interaction.Escape + case 0xff08: + key = interaction.Backspace + case 0xffff, 0xff9f: + key = interaction.Delete + } + text := event.Text + if event.Chord.CthulhuModifier { + text = "" + } + return interaction.Event{Key: key, Text: text, Shift: event.Chord.Modifiers&1 != 0, Control: event.Chord.Modifiers&4 != 0, Alt: event.Chord.Modifiers&(8|64) != 0} +} + +func read_internal_clipboard(ctx context.Context) (string, error) { + command := exec.CommandContext(ctx, "xclip", "-selection", "clipboard", "-out") + output, err := command.StdoutPipe() + if err != nil { + return "", err + } + if err = command.Start(); err != nil { + return "", err + } + data, readErr := io.ReadAll(io.LimitReader(output, 32769)) + if len(data) > 32768 || readErr != nil { + _ = command.Process.Kill() + _ = command.Wait() + return "", errors.New("clipboard text too large") + } + if err = command.Wait(); err != nil { + return "", err + } + return string(data), nil +} diff --git a/internal/app/internal_ui_native_test.go b/internal/app/internal_ui_native_test.go new file mode 100644 index 0000000..90883da --- /dev/null +++ b/internal/app/internal_ui_native_test.go @@ -0,0 +1,218 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "encoding/json" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeInternalUIActionsAndEntry(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_INTERNAL_UI") != "1" { + t.Skip("requires private GTK/AT-SPI fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + adapter := atspi.New() + keys := xorg.NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + worker, err := review.NewWorker(adapter, time.Second) + if err != nil { + t.Fatal(err) + } + for _, service := range []interface { + Start(context.Context) error + Stop(context.Context) error + }{adapter, worker, keys} { + if err := service.Start(ctx); err != nil { + t.Fatal(err) + } + defer service.Stop(context.Background()) + } + output := &ocrTestOutput{speech: make(chan speechRequest, 256)} + ui := &internalUI{keys: keys, actions: adapter, interest: worker, speech: output, gate: newFocusGate(keys), events: make(chan input.CommandEvent, 32), requests: make(chan internalUIRequest, 1), done: make(chan struct{})} + go ui.run(ctx) + focused := make(chan struct{}, 1) + done := make(chan struct{}) + go func() { + defer close(done) + for { + select { + case <-ctx.Done(): + return + case event := <-keys.Commands(): + ui.Handle(event) + case event := <-adapter.Events(): + if event.Type == atspi.FocusEvent || event.Type == atspi.FocusedStateEvent && event.Detail1 != 0 { + worker.SyncFocus(event.Source.ID()) + if event.Source.Name == "Run action" { + select { + case focused <- struct{}{}: + default: + } + } + } + } + } + }() + defer func() { cancel(); <-ui.done; <-done }() + key := func(names ...string) { + t.Helper() + if data, err := exec.CommandContext(ctx, "xdotool", append([]string{"key"}, names...)...).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, data) + } + } + key("Tab", "shift+Tab") + select { + case <-focused: + case <-ctx.Done(): + t.Fatal("button did not gain accessible focus") + } + original, err := exec.CommandContext(ctx, "xdotool", "getwindowfocus").Output() + if err != nil { + t.Fatal(err) + } + key("Insert+shift+a") + select { + case message := <-output.speech: + if !strings.Contains(strings.ToLower(message.Text), "click") { + t.Fatalf("accessible actions=%q", message.Text) + } + case <-ctx.Done(): + t.Fatal("actions menu did not open") + } + key("Return") + read := func() (int, string) { + data, err := os.ReadFile(os.Getenv("CTHULHU_UI_MARKER")) + if err != nil { + return 0, "" + } + var value struct { + Clicks int `json:"clicks"` + Text string `json:"text"` + } + if json.Unmarshal(data, &value) != nil { + return 0, "" + } + return value.Clicks, value.Text + } + for { + clicks, _ := read() + if clicks == 1 { + break + } + if ctx.Err() != nil { + t.Fatal("accessible click not performed") + } + time.Sleep(10 * time.Millisecond) + } + originalActions, err := adapter.AccessibleActions(ctx, worker.Focus()) + if err != nil { + t.Fatal(err) + } + result, err := ui.Open(ctx, interaction.Form{Title: "Example", Elements: []interaction.Element{{ID: "code", Label: "Code", Kind: interaction.Entry}}}) + if err != nil { + t.Fatal(err) + } + for keys.InternalUISession() == 0 { + if ctx.Err() != nil { + t.Fatal("entry did not open") + } + time.Sleep(time.Millisecond) + } + key("a", "shift+b", "c", "BackSpace", "exclam", "shift+Home", "ctrl+c") +copied: + for { + select { + case message := <-output.speech: + if message.Text == "Copied" { + break copied + } + case <-ctx.Done(): + t.Fatal("entry copy did not complete") + } + } + clipboardText, err := read_internal_clipboard(ctx) + if err != nil || clipboardText != "aB!" { + t.Fatalf("copied text = %q, %v", clipboardText, err) + } + key("BackSpace", "ctrl+v", "d", "Return") + select { + case submitted := <-result: + if submitted.Err != nil || submitted.Values["code"].Text != "aB!d" { + t.Fatalf("entry result=%+v", submitted) + } + case <-ctx.Done(): + t.Fatal("entry did not submit") + } + current, _ := exec.CommandContext(ctx, "xdotool", "getwindowfocus").Output() + if string(current) != string(original) { + t.Fatal("internal UI moved application focus") + } + clicks, text := read() + if clicks != 1 || text != "" { + t.Fatalf("UI keys reached GTK: clicks=%d text=%q", clicks, text) + } + key("Tab", "q") + for { + _, text = read() + if text == "q" { + break + } + if ctx.Err() != nil { + t.Fatalf("ordinary typing did not resume: %q", text) + } + time.Sleep(10 * time.Millisecond) + } + if err := adapter.PerformAccessibleAction(ctx, originalActions.Target, "click"); err == nil { + t.Fatal("stale focus action was performed") + } + clicks, _ = read() + if clicks != 1 { + t.Fatal("stale action clicked old target") + } + // Fresh one-line transfer reads share native foreground/password safeguards. + item, err := adapter.ReadTransferItem(ctx, worker.Focus(), -1) + if err != nil || item.Text != "q" { + t.Fatalf("focused entry transfer=%+v %v", item, err) + } + key("Tab") + for { + item, err = adapter.ReadTransferItem(ctx, worker.Focus(), -1) + if err == nil && item.Text == "First line" { + break + } + if ctx.Err() != nil { + t.Fatalf("multiline transfer=%+v %v", item, err) + } + time.Sleep(10 * time.Millisecond) + } + // A browser's virtual caret can request another line without moving native focus. + item, err = adapter.ReadTransferItem(ctx, worker.Focus(), 12) + if err != nil || item.Text != "Second line" { + t.Fatalf("virtual transfer=%+v %v", item, err) + } + key("ctrl+Tab") + for { + if _, err = adapter.ReadTransferItem(ctx, worker.Focus(), -1); err != nil { + break + } + if ctx.Err() != nil { + t.Fatal("protected item was exported") + } + time.Sleep(10 * time.Millisecond) + } + +} diff --git a/internal/app/internal_ui_output_test.go b/internal/app/internal_ui_output_test.go new file mode 100644 index 0000000..fdf83dd --- /dev/null +++ b/internal/app/internal_ui_output_test.go @@ -0,0 +1,44 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "sync/atomic" + "testing" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +type uiOutputRecorder struct { + messages []speechRequest + interrupts atomic.Int32 +} + +func (output *uiOutputRecorder) Enqueue(request speechRequest) { + output.messages = append(output.messages, request) +} +func (output *uiOutputRecorder) Interrupt() { output.interrupts.Add(1) } + +func TestInternalUISuppressesApplicationOutputAndInputInterruption(t *testing.T) { + keys := &uiTestKeys{} + keys.session.Store(1) + output := &uiOutputRecorder{} + speaker := gatedSpeech{speech: output, gate: &focusGate{internalUI: keys}} + speaker.Enqueue(speechRequest{Text: "Application event", Cause: "focus"}) + speaker.Interrupt() + if speaker.InterruptForInput(input.Event{}) || len(output.messages) != 0 || output.interrupts.Load() != 0 { + t.Fatal("application output interrupted internal UI") + } + speaker.InterruptInternalUI() + speaker.Enqueue(speechRequest{Text: "Choice", Cause: "internal-ui"}) + if len(output.messages) != 1 || output.interrupts.Load() != 1 { + t.Fatal("internal UI output was suppressed") + } + keys.session.Store(0) + speaker.Enqueue(speechRequest{Text: "Application event", Cause: "focus"}) + if len(output.messages) != 2 { + t.Fatal("normal presentation did not resume") + } +} diff --git a/internal/app/internal_ui_test.go b/internal/app/internal_ui_test.go new file mode 100644 index 0000000..f85d81f --- /dev/null +++ b/internal/app/internal_ui_test.go @@ -0,0 +1,131 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "sync/atomic" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/review" +) + +type uiTestKeys struct{ session atomic.Uint64 } + +func (keys *uiTestKeys) InternalUISession() uint64 { return keys.session.Load() } +func (keys *uiTestKeys) InternalUIActive() bool { return keys.session.Load() != 0 } +func (keys *uiTestKeys) BeginInternalUI(context.Context) (uint64, error) { + keys.session.Store(1) + return 1, nil +} +func (keys *uiTestKeys) EndInternalUI(_ context.Context, id uint64) error { + keys.session.CompareAndSwap(id, 0) + return nil +} + +type uiTestActions struct { + keys *uiTestKeys + invoked chan string + object atspi.ObjectID +} + +func (source *uiTestActions) ObjectOfInterest(context.Context) (review.Interest, error) { + return review.Interest{Object: source.object}, nil +} +func (source *uiTestActions) AccessibleActions(_ context.Context, object atspi.ObjectID) (atspi.ActionSet, error) { + return atspi.ActionSet{Target: atspi.ActionTarget{Object: object}, Actions: []atspi.AccessibleAction{{Name: "click", Label: "Click"}, {Name: "press", Label: "Press"}}}, nil +} +func (source *uiTestActions) PerformAccessibleAction(_ context.Context, target atspi.ActionTarget, name string) error { + if source.keys.InternalUISession() != 0 || target.Object != source.object { + source.invoked <- "wrong target or capture retained" + } else { + source.invoked <- name + } + return nil +} + +func TestInternalUIActionsAndFormUseSameHost(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + keys := &uiTestKeys{} + keys.session.Store(1) + source := &uiTestActions{keys: keys, object: atspi.NewObjectID(":1.42", "/button"), invoked: make(chan string, 1)} + output := &ocrTestOutput{speech: make(chan speechRequest, 16)} + ui := &internalUI{keys: keys, actions: source, interest: source, speech: output, gate: &focusGate{}, events: make(chan input.CommandEvent, 16), requests: make(chan internalUIRequest, 1), done: make(chan struct{})} + go ui.run(ctx) + defer func() { cancel(); <-ui.done }() + ui.Handle(input.CommandEvent{Command: input.ShowActions, UISession: 1}) + select { + case message := <-output.speech: + if message.Cause != "internal-ui" || message.Text != "Actions. Click" { + t.Fatal(message) + } + case <-ctx.Done(): + t.Fatal("menu did not open") + } + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Chord: input.CommandChord{Symbol: 0xff54}}) + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Chord: input.CommandChord{Symbol: 0xff0d}}) + select { + case action := <-source.invoked: + if action != "press" { + t.Fatal(action) + } + case <-ctx.Done(): + t.Fatal("action did not run") + } + select { + case message := <-output.speech: + if message.Text != "Press" { + t.Fatalf("navigation repeated title: %q", message.Text) + } + case <-ctx.Done(): + t.Fatal("selection was not announced") + } + result, err := ui.Open(ctx, interaction.Form{Title: "Example", Elements: []interaction.Element{{ID: "entry", Label: "Code", Kind: interaction.Entry}}}) + if err != nil { + t.Fatal(err) + } + for keys.InternalUISession() == 0 { + if ctx.Err() != nil { + t.Fatal("form did not open") + } + time.Sleep(time.Millisecond) + } + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Text: "é", Chord: input.CommandChord{Symbol: 0xe9}}) + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Chord: input.CommandChord{Symbol: 0xff0d}}) + select { + case submitted := <-result: + if submitted.Activated != "entry" || submitted.Values["entry"].Text != "é" { + t.Fatalf("form=%+v", submitted) + } + case <-ctx.Done(): + t.Fatal("form did not submit") + } +} + +func TestInternalUIBrailleRestoresNewestApplicationFrame(t *testing.T) { + worker := &brailleWorker{wake: make(chan struct{}, 1), cancel: func() {}, connected: true} + worker.EnqueueFrame(braille.Frame{Text: "Application", Cursor: 2}) + worker.SetInternalUIFrame(&braille.Frame{Text: "Code, edit: abc", Cursor: 14}) + worker.EnqueueFrame(braille.Frame{Text: "Newest application", Cursor: 4}) + if worker.current().Text != "Code, edit: abc" { + t.Fatal("application overwrote UI") + } + options := config.DefaultSettings().Braille + options.FlashMessages = true + if worker.Flash("Background", options) { + t.Fatal("background flash overwrote UI") + } + worker.SetInternalUIFrame(nil) + if worker.current().Text != "Newest application" || worker.current().Cursor != 4 { + t.Fatal("latest application frame not restored") + } +} diff --git a/internal/app/interruption_test.go b/internal/app/interruption_test.go new file mode 100644 index 0000000..aade9fb --- /dev/null +++ b/internal/app/interruption_test.go @@ -0,0 +1,89 @@ +package app + +import ( + "context" + "log/slog" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestProcessInputEventsUsesLiveInterruptionSettings(t *testing.T) { + live := &liveSettings{} + settings := config.DefaultSettings() + settings.EnableKeyEcho = true + settings.EnableActionKeys = true + for _, mode := range []string{input.InterruptAllKeys, input.InterruptCommonKeys, input.InterruptCustomKeys} { + settings.SpeechInterruption = input.InterruptionSettings{Mode: mode, Keys: []string{"Tab"}} + live.Store(settings) + speech := &fakeSpeechQueue{spoken: make(chan string, 10), interrupt: make(chan struct{}, 10)} + listener := &fakeInputListener{events: make(chan input.Event, 8)} + for _, name := range []string{"a", "Tab", "Control_L", "Return"} { + listener.events <- input.NewKeyEvent(42, true, name) + listener.events <- input.NewKeyEvent(42, false, name) + } + close(listener.events) + processInputEvents(context.Background(), slog.New(slog.DiscardHandler), speech, listener, input.EchoSettings{}, live, nil) + want := map[string]int{input.InterruptAllKeys: 4, input.InterruptCommonKeys: 2, input.InterruptCustomKeys: 1}[mode] + if len(speech.interrupt) != want { + t.Fatalf("mode %s interrupted %d times, want %d", mode, len(speech.interrupt), want) + } + // Selecting interruption keys must not suppress ordinary key echo. + if len(speech.spoken) < 2 { + t.Fatalf("mode %s suppressed Tab/Enter echo", mode) + } + } +} + +func TestAppliedInterruptionKeysPreserveQueuedSpeechAndSayAll(t *testing.T) { + logger := slog.New(slog.DiscardHandler) + speech := newSpeechWorker(logger, nil) + speech.running = true + live := &liveSettings{} + settings := config.DefaultSettings() + settings.EnableKeyEcho = false + live.Store(settings) + preferences := &preferencesWorker{settings: settings, live: live, speechWorker: speech} + settings.SpeechInterruption.Mode = input.InterruptCommonKeys + if err := preferences.applyRuntime(context.Background(), settings); err != nil { + t.Fatal(err) + } + deliver := func(name string) { + listener := &fakeInputListener{events: make(chan input.Event, 1)} + listener.events <- input.NewKeyEvent(42, true, name) + close(listener.events) + processInputEvents(context.Background(), logger, speech, listener, input.EchoSettings{}, live, nil) + } + readContext := speech.BeginReadAll(context.Background(), 0) + speech.Enqueue(speechRequest{Text: "First announcement"}) + speech.Enqueue(speechRequest{Text: "Second announcement"}) + generation := speech.generation + deliver("Up") + deliver("a") + if readContext.Err() != nil || len(speech.pending) != 2 || speech.generation != generation { + t.Fatal("unselected keys cancelled Say All or dropped queued speech") + } + deliver("Control_R") + if readContext.Err() != context.Canceled || len(speech.pending) != 0 { + t.Fatal("common interruption key did not cancel Say All and pending output") + } + settings.SpeechInterruption = input.InterruptionSettings{Mode: input.InterruptCustomKeys, Keys: []string{"F8"}} + if err := preferences.applyRuntime(context.Background(), settings); err != nil { + t.Fatal(err) + } + speech.Enqueue(speechRequest{Text: "Custom mode announcement"}) + deliver("Control_R") + if len(speech.pending) != 1 { + t.Fatal("previous interruption mode remained active after Apply") + } + deliver("F8") + if len(speech.pending) != 0 { + t.Fatal("custom interruption key did not cancel queued output") + } + speech.Enqueue(speechRequest{Text: "Old output"}) + speech.ProtectCommand(100) + if len(speech.pending) != 0 { + t.Fatal("reader command failed to cancel old output in custom mode") + } +} diff --git a/internal/app/key_bindings_test.go b/internal/app/key_bindings_test.go new file mode 100644 index 0000000..94f0ccd --- /dev/null +++ b/internal/app/key_bindings_test.go @@ -0,0 +1,132 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "errors" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" + "log/slog" + "path/filepath" + "reflect" + "testing" +) + +type bindingRecorder struct { + values []input.BindingOverride + calls int + err error +} + +func (recorder *bindingRecorder) SetKeyBindings(_ context.Context, values []input.BindingOverride) error { + recorder.calls++ + if recorder.err != nil { + return recorder.err + } + recorder.values = input.CloneBindingOverrides(values) + return nil +} + +func TestPreferencesKeyBindingsApplySaveResetAndFailure(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + recorder := &bindingRecorder{} + worker.bindings = recorder + values := preferences.FromSettings(settings) + values.KeyBindings = []input.BindingOverride{{Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Preferences, Keys: []string{"Cthulhu+F8"}}} + recorder.err = errors.New("grab conflict") + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if response.Accepted || len(worker.settings.KeyBindings) != 0 { + t.Fatal("failed update committed") + } + recorder.err = nil + response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || !reflect.DeepEqual(values.KeyBindings, recorder.values) { + t.Fatalf("apply: %+v", response) + } + loaded, err := config.Load(settings.Path) + if err != nil || !reflect.DeepEqual(values.KeyBindings, loaded.KeyBindings) { + t.Fatalf("save: %v", err) + } + calls := recorder.calls + values.KeyBindings[0].Keys = []string{"Cthulhu+q"} + response = worker.apply(context.Background(), preferences.Request{Values: values}) + if response.Accepted || recorder.calls != calls { + t.Fatal("invalid bindings reached backend") + } + values.KeyBindings[0].Keys = []string{"Cthulhu+F9"} + rate := 70.0 + values.Rate = &rate + response = worker.apply(context.Background(), preferences.Request{Values: values}) + if response.Accepted || recorder.values[0].Keys[0] != "Cthulhu+F8" { + t.Fatal("later backend failure did not restore keys") + } + values.Rate = nil + values.KeyBindings = nil + response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || len(recorder.values) != 0 { + t.Fatal("reset was not applied") + } +} + +type keyboardRecorder struct { + bindingRecorder + layout input.KeyboardLayout + modifiers []string +} + +func (recorder *keyboardRecorder) SetKeyboardConfiguration(ctx context.Context, layout input.KeyboardLayout, modifiers []string, overrides []input.BindingOverride) error { + if err := recorder.SetKeyBindings(ctx, overrides); err != nil { + return err + } + recorder.layout = layout + recorder.modifiers = append([]string(nil), modifiers...) + return nil +} + +func TestPreferencesKeyboardConfigurationApplySaveRollback(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + recorder := &keyboardRecorder{} + worker.bindings = recorder + values := preferences.FromSettings(settings) + values.KeyboardLayout = 2 + values.CthulhuModifierKeys = []string{"Caps_Lock"} + recorder.err = errors.New("modifier grab conflict") + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if response.Accepted || worker.settings.KeyboardLayout != 1 { + t.Fatal("failed modifier update committed") + } + recorder.err = nil + response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || recorder.layout != input.LaptopKeyboardLayout || !reflect.DeepEqual(recorder.modifiers, values.CthulhuModifierKeys) { + t.Fatalf("apply: %+v", response) + } + loaded, err := config.Load(settings.Path) + if err != nil || loaded.KeyboardLayout != 2 || !reflect.DeepEqual(loaded.CthulhuModifierKeys, values.CthulhuModifierKeys) { + t.Fatalf("save keyboard: %v", err) + } + values.KeyboardLayout = 1 + values.CthulhuModifierKeys = []string{"KP_Insert"} + rate := 70.0 + values.Rate = &rate + response = worker.apply(context.Background(), preferences.Request{Values: values}) + if response.Accepted || recorder.layout != input.LaptopKeyboardLayout || !reflect.DeepEqual(recorder.modifiers, []string{"Caps_Lock"}) { + t.Fatal("later backend failure did not restore keyboard configuration") + } + values.Rate = nil + values.CthulhuModifierKeys = []string{} + response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || len(recorder.modifiers) != 0 { + t.Fatalf("all unchecked: %+v", response) + } + loaded, err = config.Load(settings.Path) + if err != nil || len(loaded.CthulhuModifierKeys) != 0 { + t.Fatalf("reload all unchecked: %v", err) + } +} diff --git a/internal/app/learn_mode.go b/internal/app/learn_mode.go new file mode 100644 index 0000000..69e73f6 --- /dev/null +++ b/internal/app/learn_mode.go @@ -0,0 +1,264 @@ +package app + +import ( + "context" + "encoding/json" + "fmt" + "log/slog" + "os" + "os/exec" + "strings" + "time" + "unicode" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/shortcutui" + "git.stormux.org/storm/cthulhu/internal/version" +) + +const learnModeInstructions = "Entering learn mode. Press any key to hear its function. Press F1 for Cthulhu documentation, F2 for default shortcuts, or F3 for application shortcuts. Press Escape, Cthulhu H, or Cthulhu F1 to exit." + +type learnModePresenter struct { + tentacles *tentacleRuntime + ctx context.Context + logger *slog.Logger + speech speechEnqueuer + braille interface{ EnqueueMessage(string) bool } + live *liveSettings + browse interface{ BrowseNavigationEnabled() bool } + active bool + lastChord input.CommandChord + lastTime uint32 +} + +func (presenter *learnModePresenter) present(text, cause string) { + presenter.speech.Enqueue(speechRequest{Text: text, Role: "system", Cause: cause}) + presenter.braille.EnqueueMessage(text) +} + +func (presenter *learnModePresenter) handle(event input.CommandEvent) { + switch event.Command { + case input.ToggleLearnMode: + entering := event.LearnModeStarted + if entering { + presenter.active = true + presenter.lastTime = 0 + presenter.speech.Enqueue(speechRequest{Text: version.String(), Role: "system", Cause: "learn-mode"}) + presenter.speech.Enqueue(speechRequest{Text: learnModeInstructions, Role: "system", Cause: "learn-mode"}) + presenter.braille.EnqueueMessage("Learn mode. Press Escape, Cthulhu H, or Cthulhu F1 to exit.") + return + } + presenter.key(event) + presenter.stop() + case input.LearnKey: + presenter.key(event) + case input.LearnDocumentation: + presenter.key(event) + presenter.stop() + go presenter.openDocumentation() + case input.LearnDefaultShortcuts: + presenter.key(event) + presenter.stop() + presenter.openShortcutList() + case input.LearnApplicationShortcuts: + presenter.key(event) + presenter.stop() + presenter.present("No application-specific screen reader shortcuts are available.", "learn-mode") + } +} + +func (presenter *learnModePresenter) stop() { + presenter.active = false + presenter.lastTime = 0 + presenter.present("Exiting learn mode.", "learn-mode") +} + +func (presenter *learnModePresenter) key(event input.CommandEvent) { + if !presenter.active { + return + } + name := spokenLearnKey(event) + presenter.present(name, "learn-key") + settings := presenter.live.Load() + browse := presenter.browse != nil && presenter.browse.BrowseNavigationEnabled() + bindings, err := input.ResolveCommandBindings(input.KeyboardLayout(settings.KeyboardLayout), browse, settings.KeyBindings) + if err == nil { + if command := bindings[event.Chord]; command != "" { + presenter.present(learnCommandDescription(command), "learn-command") + presenter.lastTime = 0 + return + } + } + if description := presenter.tentacles.Describe(event.Chord, input.KeyboardLayout(settings.KeyboardLayout), browse); description != "" { + presenter.present(description, "learn-command") + presenter.lastTime = 0 + return + } + if event.Command == input.LearnKey && len(event.KeyName) == 1 && unicode.IsLetter(rune(event.KeyName[0])) && + presenter.lastChord == event.Chord && event.Timestamp >= presenter.lastTime && event.Timestamp-presenter.lastTime <= 500 { + if word := phoneticLetter(rune(event.KeyName[0])); word != "" { + presenter.present(word, "learn-phonetic") + } + presenter.lastTime = 0 + return + } + presenter.lastChord, presenter.lastTime = event.Chord, event.Timestamp +} + +func spokenLearnKey(event input.CommandEvent) string { + name := event.KeyName + if name == "" { + name = input.FormatCommandChord(input.CommandChord{Symbol: event.Chord.Symbol}) + } + switch name { + case "space": + name = "space" + case "Return": + name = "enter" + case "Escape": + name = "escape" + case "BackSpace": + name = "backspace" + case "Prior": + name = "page up" + case "Next": + name = "page down" + case "Caps_Lock": + name = "caps lock" + } + name = strings.ReplaceAll(name, "_", " ") + var parts []string + if event.Chord.CthulhuModifier { + parts = append(parts, "Cthulhu") + } + if event.Chord.Modifiers&4 != 0 { + parts = append(parts, "control") + } + if event.Chord.Modifiers&8 != 0 { + parts = append(parts, "alt") + } + if event.Chord.Modifiers&64 != 0 { + parts = append(parts, "super") + } + if event.Chord.Modifiers&1 != 0 { + parts = append(parts, "shift") + } + return strings.Join(append(parts, name), " ") +} + +func learnCommandDescription(command input.Command) string { + if _, ok := input.LookupDocumentList(command); ok { + return input.CommandLabel(command) + } + switch command { + case input.ShowActions: + return "Show the actions available for the current object" + case input.ToggleLearnMode: + return "Enter or exit learn mode." + case input.DisableTentacles: + return "Disable all tentacles until Cthulhu restarts." + case input.Quit: + return "Quit Cthulhu." + case input.CycleProgressBarOutput: + return "Cycle progress bar speech, beeps, speech and beeps, and off." + case input.CycleSpeechMode: + return "Cycle speech, beeps, and off." + case input.Preferences: + return "Open Cthulhu preferences." + case input.ApplicationPreferences: + return "Open preferences for the current application." + case input.ChooseApplicationPreferences: + return "Choose an application and open its preferences." + case input.WhereAmI: + return "Speak details of the current item." + case input.PresentCurrentLine: + return "Read the current line. Press twice to spell it, or three times for phonetics." + case input.PresentWindowTitle: + return "Read the current window title." + case input.PresentCellFormula: + return "Present the formula for the current cell." + case input.PresentCharacterAttributes: + return "Read the current character's font and formatting attributes." + case input.ReadAll: + return "Read all from the current position." + } + return input.CommandLabel(command) + "." +} + +func (presenter *learnModePresenter) openDocumentation() { + ctx, cancel := context.WithTimeout(presenter.ctx, 8*time.Second) + defer cancel() + for _, tool := range []string{"gio", "xdg-open"} { + arguments := []string{"help:cthulhu"} + if tool == "gio" { + arguments = append([]string{"open"}, arguments...) + } + if err := exec.CommandContext(ctx, tool, arguments...).Run(); err == nil { + return + } + } + presenter.logger.Warn("could not open Cthulhu documentation") + presenter.present("Help is not available.", "learn-mode") +} + +func (presenter *learnModePresenter) openShortcutList() { + settings := presenter.live.Load() + list := makeShortcutList(settings) + if rows := presenter.tentacles.ShortcutRows(input.KeyboardLayout(settings.KeyboardLayout)); len(rows) > 0 { + list.Rows = append(list.Rows, rows...) + list.Title = "Screen reader shortcuts, including tentacles" + } + if len(list.Rows) == 0 { + presenter.present(list.Title, "learn-mode") + return + } + executable, err := os.Executable() + if err != nil { + presenter.present("Shortcut list is not available.", "learn-mode") + return + } + cmd := exec.CommandContext(presenter.ctx, executable, "--shortcut-list-ui") + stdin, err := cmd.StdinPipe() + if err != nil { + presenter.present("Shortcut list is not available.", "learn-mode") + return + } + if err := cmd.Start(); err != nil { + presenter.logger.Warn("start shortcut list", "error", err) + presenter.present("Shortcut list is not available.", "learn-mode") + return + } + go func() { + encoder := json.NewEncoder(stdin) + encodeError := encoder.Encode(list) + stdin.Close() + waitError := cmd.Wait() + if encodeError != nil { + presenter.logger.Warn("send shortcut list", "error", encodeError) + } + if waitError != nil && presenter.ctx.Err() == nil { + presenter.logger.Warn("shortcut list window", "error", waitError) + presenter.present("Shortcut list is not available.", "learn-mode") + } + }() +} + +func makeShortcutList(settings config.Settings) shortcutui.List { + rows := input.BindingRows(input.KeyboardLayout(settings.KeyboardLayout), settings.KeyBindings) + list := shortcutui.List{} + shortcuts := 0 + for _, row := range rows { + if row.Keys == "" { + continue + } + group := "Default" + if row.Scope == "browse" { + group = "Browse mode" + } + list.Rows = append(list.Rows, shortcutui.Row{Group: group, Label: learnCommandDescription(row.Command), Keys: row.Keys}) + shortcuts += len(strings.Split(row.Keys, ";")) + } + list.Title = fmt.Sprintf("%d screen reader default shortcuts found", shortcuts) + return list +} diff --git a/internal/app/learn_mode_test.go b/internal/app/learn_mode_test.go new file mode 100644 index 0000000..1bc11d9 --- /dev/null +++ b/internal/app/learn_mode_test.go @@ -0,0 +1,81 @@ +package app + +import ( + "context" + "log/slog" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +type learnSpeechRecorder struct { + texts []string + interrupts int +} + +func (recorder *learnSpeechRecorder) Enqueue(request speechRequest) { + recorder.texts = append(recorder.texts, request.Text) +} +func (recorder *learnSpeechRecorder) Interrupt() { recorder.interrupts++ } + +type learnBrailleRecorder struct{ texts []string } + +func (recorder *learnBrailleRecorder) EnqueueMessage(text string) bool { + recorder.texts = append(recorder.texts, text) + return true +} + +func TestLearnModePresentsKeyCommandsWithoutExecutingThem(t *testing.T) { + live := &liveSettings{} + live.Store(config.DefaultSettings()) + speech := &learnSpeechRecorder{} + braille := &learnBrailleRecorder{} + presenter := &learnModePresenter{ctx: context.Background(), logger: slog.New(slog.DiscardHandler), speech: speech, braille: braille, live: live} + presenter.handle(input.CommandEvent{Command: input.ToggleLearnMode, LearnModeStarted: true}) + if !presenter.active || len(speech.texts) != 2 || !strings.Contains(speech.texts[1], "Cthulhu F1") || len(braille.texts) != 1 { + t.Fatalf("start speech=%q braille=%q", speech.texts, braille.texts) + } + presenter.handle(input.CommandEvent{Command: input.LearnKey, Chord: input.CommandChord{Symbol: 'q', CthulhuModifier: true}, KeyName: "q", Timestamp: 100}) + if got := speech.texts[len(speech.texts)-1]; got != "Quit Cthulhu." { + t.Fatalf("command description = %q", got) + } + if got := braille.texts[len(braille.texts)-1]; got != "Quit Cthulhu." { + t.Fatalf("braille description = %q", got) + } + presenter.handle(input.CommandEvent{Command: input.LearnKey, Chord: input.CommandChord{Symbol: 'z'}, KeyName: "z", Timestamp: 1000}) + presenter.handle(input.CommandEvent{Command: input.LearnKey, Chord: input.CommandChord{Symbol: 'z'}, KeyName: "z", Timestamp: 1200}) + if got := speech.texts[len(speech.texts)-1]; got != "zulu" { + t.Fatalf("phonetic double press = %q", got) + } + presenter.handle(input.CommandEvent{Command: input.ToggleLearnMode, Chord: input.CommandChord{Symbol: 'h', CthulhuModifier: true}, KeyName: "h"}) + if presenter.active || speech.texts[len(speech.texts)-1] != "Exiting learn mode." || speech.interrupts != 0 { + t.Fatalf("exit speech=%q interrupts=%d", speech.texts, speech.interrupts) + } +} + +func TestLearnShortcutListUsesActiveBindings(t *testing.T) { + settings := config.DefaultSettings() + settings.KeyBindings = []input.BindingOverride{{Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Preferences, Keys: []string{"Cthulhu+Ctrl+F8"}}} + list := makeShortcutList(settings) + if len(list.Rows) == 0 || !strings.Contains(list.Title, "shortcuts found") { + t.Fatalf("empty shortcut list: %+v", list) + } + foundLearn := false + foundPreferences := false + for _, row := range list.Rows { + if row.Label == "Enter or exit learn mode." { + foundLearn = strings.Contains(row.Keys, "Cthulhu+h") && strings.Contains(row.Keys, "Cthulhu+F1") + } + if row.Label == "Open Cthulhu preferences." { + foundPreferences = true + if row.Keys != "Cthulhu+Ctrl+F8" { + t.Fatalf("preferences keys = %q", row.Keys) + } + } + } + if !foundLearn || !foundPreferences { + t.Fatalf("learn and preferences shortcuts missing from list: learn=%t preferences=%t", foundLearn, foundPreferences) + } +} diff --git a/internal/app/libreoffice.go b/internal/app/libreoffice.go new file mode 100644 index 0000000..26f7751 --- /dev/null +++ b/internal/app/libreoffice.go @@ -0,0 +1,104 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +// prepareLibreOfficeEvent follows current Orca's soffice focus/caret policy. +// A Calc active cell is the logical focus even when editing destroyed the old +// focus or a sheet switch changed its managed container (LO bug 161444). +func prepareLibreOfficeEvent(event atspi.Event, current atspi.Snapshot, owner windowOwner) applicationEventResult { + result := applicationEventResult{event: event} + context := event.Source.LibreOffice + if !atspi.IsLibreOfficeProcess(event.Source.ApplicationProcess) || + event.Source.Defunct || !event.Source.ID().Valid() || + owner.window.Valid() && (eventWindow(event) != owner.window || event.Source.BusName != owner.applicationBus) { + return result + } + if isFocusGainEvent(event) && event.Type != atspi.WindowActivatedEvent && + current.LibreOffice != nil && current.LibreOffice.InSpreadsheet { + // LibreOffice also claims focus for ancestors of the real focused + // object. Orca ignores these; copied ancestry is enough to identify + // them without another native tree query. + for _, ancestor := range current.BrailleContext { + if ancestor.ID().Valid() && ancestor.ID() == event.Source.ID() { + result.suppress = true + return result + } + } + } + if context != nil && context.InSpreadsheet && context.Cell && event.Source.Role == "table cell" && + event.Type == atspi.ActiveDescendantEvent && + (event.Source.Focused || context.ContainerFocused) { + // Preserve NativeType/OriginPath for diagnostics. Ordinary focus + // handling now owns review, duplicate suppression, and Braille. + if result.event.NativeType == "" { + result.event.NativeType = event.Type + } + result.event.Type = atspi.FocusEvent + } + if context != nil && context.InSpreadsheet && event.Type == atspi.SelectionChangedEvent { + // Selection can name the first cell of a range rather than the + // active cell. Dedicated selection presentation consumes copied + // sheet metadata without changing logical focus or review. + result.suppress = true + } + if context != nil && context.InSpreadsheet && event.Source.Role == "table" && + isFocusGainEvent(event) && event.Type != atspi.WindowActivatedEvent && + current.LibreOffice != nil && + (current.LibreOffice.CellEditor || current.LibreOffice.Cell && current.TablePath == event.Source.Path) { + // Orca treats this as the sheet reclaiming focus after editing. + // Own it silently; the following active cell supplies presentation. + result.adoptFocus, result.suppress = true, true + } + if context != nil && context.Cell && isFocusGainEvent(result.event) && current.ID() != event.Source.ID() { + // Returning to the cell after typing must speak it even if its + // value is unchanged; typing uses a separate presentation history. + result.resetPresentation = true + } + if context != nil && context.CellEditor && event.Source.Role == "paragraph" && + (isTextChangeEvent(event.Type) || event.Type == atspi.CaretEvent) && + owner.window.Valid() && event.Source.ID() != current.ID() && + (event.Source.Focused || context.EditorParent == current.ID() && current.LibreOffice != nil && current.LibreOffice.CellEditor) { + // Empty-cell F2 can focus a panel before its paragraph exists. + // Admit that editor's first mutation before generic text filtering. + result.adoptFocus = true + } + if event.Type == atspi.CaretEvent && current.LibreOffice != nil && current.LibreOffice.Cell && + (context == nil || !context.CellEditor) { + // Formula-bar/background caret events must not displace the cell. + result.suppress = true + } + return result +} + +func libreOfficeBrailleFrame(snapshot atspi.Snapshot, options config.BrailleOptions) (braille.Frame, bool) { + context := snapshot.LibreOffice + if !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) || snapshot.Role != "table cell" || + context == nil || !context.InSpreadsheet || !context.Cell { + return braille.Frame{}, false + } + // Orca presents the value followed by its cell address. This is a + // component, not an editable-text route; cell focus has no text caret. + return braille.Frame{Text: brailleJoin(context.CellText, context.Coordinates), Cursor: 0, + WordWrap: options.WordWrap}, true +} + +// The event loop owns the accepted focus snapshot. Formula commands share its +// foreground/lock gates and output queue, with no separate application state. +func (handler *eventReviewHandler) presentCellFormula() { + if handler.focusGate.Locked() || handler.focusGate.Suspended() { + return + } + handler.syncForeground() + handler.state.pending.clear() + text := presentation.LibreOfficeFormulaText(handler.state.current) + handler.speech.Enqueue(speechRequest{Text: text, Role: "system", Cause: "cell-formula"}) +} diff --git a/internal/app/libreoffice_headers.go b/internal/app/libreoffice_headers.go new file mode 100644 index 0000000..433fb26 --- /dev/null +++ b/internal/app/libreoffice_headers.go @@ -0,0 +1,90 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "fmt" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +type libreOfficeHeaderConfigurer interface { + ConfigureLibreOfficeHeader(atspi.Snapshot, atspi.ObjectID, bool, bool) error +} + +func (handler *eventReviewHandler) configureCalcHeader(command input.Command) { + if handler.focusGate.Locked() || handler.focusGate.Suspended() { + return + } + handler.syncForeground() + state := handler.state + snapshot := state.current + context := snapshot.LibreOffice + text := "Not in a Calc cell." + if handler.calcHeaders != nil && context != nil && context.Cell && context.InSpreadsheet && + !snapshot.Defunct && atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) && + state.owner.window.Valid() && state.owner.applicationBus == snapshot.BusName && + state.owner.focus == snapshot.ID() && snapshot.TablePositionKnown { + columnHeaders := command == input.SetColumnHeadersRow || command == input.ClearColumnHeadersRow + clear := command == input.ClearColumnHeadersRow || command == input.ClearRowHeadersColumn + if err := handler.calcHeaders.ConfigureLibreOfficeHeader(snapshot, state.owner.window, columnHeaders, clear); err != nil { + text = err.Error() + } else if columnHeaders { + // The command changes this axis immediately. Its text is captured + // again on the next cell event, never queried by the event loop. + state.current.TableColumnHeaders = "" + text = fmt.Sprintf("Row %d set as column headers.", snapshot.TableRowIndex+1) + if clear { + text = "Column headers cleared." + } + } else { + state.current.TableRowHeaders = "" + text = fmt.Sprintf("Column %s set as row headers.", calcColumnLabel(snapshot.TableColumnIndex)) + if clear { + text = "Row headers cleared." + } + } + if handler.brailleOutput != nil { + options := config.DefaultSettings().Braille + if handler.live != nil { + options = handler.live.Load().Braille + } + state.brailleSnapshot = state.current + handler.brailleOutput.EnqueueFrame(brailleFocusFrameWithOptions(state.current, options)) + } + } + state.pending.clear() + handler.speech.Enqueue(speechRequest{Text: text, Role: "system", Cause: "calc-headers"}) +} + +func calcColumnLabel(column int) string { + label := "" + for column >= 0 { + label = string(rune('A'+column%26)) + label + column = column/26 - 1 + } + return label +} + +// Use existing table presentation history, which belongs to the event loop. +// Keep the full snapshot for Where Am I and Braille; only automatic speech +// omits headings for an unchanged axis, following current Orca. +func (state *eventLoopState) calcHeaderSpeechEvent(event atspi.Event) atspi.Event { + snapshot := event.Source + if snapshot.LibreOffice == nil || !snapshot.LibreOffice.Cell || + !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) || !snapshot.TablePositionKnown || + !state.lastTableCell.Valid() || state.lastTable != calcSheet(snapshot) { + return event + } + if snapshot.TableRowIndex == state.lastTableRow { + event.Source.TableRowHeaders = "" + } + if snapshot.TableColumnIndex == state.lastTableColumn { + event.Source.TableColumnHeaders = "" + } + return event +} diff --git a/internal/app/libreoffice_headers_test.go b/internal/app/libreoffice_headers_test.go new file mode 100644 index 0000000..70ddbe1 --- /dev/null +++ b/internal/app/libreoffice_headers_test.go @@ -0,0 +1,119 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +func TestLibreOfficeHeaderCommandsRespectOwnershipAndGates(t *testing.T) { + event := calcTestEvent(atspi.FocusEvent, "/cell", "10", "B3") + event.Source.TableRowIndex, event.Source.TableColumnIndex = 2, 1 + event.Source.LibreOffice.Document = atspi.NewObjectID(event.Source.BusName, "/document") + event.Source.LibreOffice.SheetName = "Example" + state := eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + state.current = event.Source + state.owner.follow(event) + speech := &fakeSpeechQueue{spoken: make(chan string, 8)} + gate := &focusGate{} + frames := make(chan braille.Frame, 8) + handler := eventReviewHandler{state: &state, speech: speech, focusGate: gate, + calcHeaders: atspi.New(), syncForeground: func() {}, brailleOutput: calcFrameQueue{frames}} + for _, test := range []struct { + command input.Command + want string + }{ + {input.SetColumnHeadersRow, "Row 3 set as column headers."}, + {input.SetRowHeadersColumn, "Column B set as row headers."}, + {input.ClearColumnHeadersRow, "Column headers cleared."}, + {input.ClearRowHeadersColumn, "Row headers cleared."}, + } { + handler.configureCalcHeader(test.command) + if got := <-speech.spoken; got != test.want { + t.Fatalf("header command = %q", got) + } + <-frames + } + // Clearing immediately refreshes the Braille base frame as well as the + // copied Where Am I snapshot, without waiting for another cell event. + state.current.TableColumnHeaders, state.current.TableRowHeaders = "Total", "Monday" + handler.configureCalcHeader(input.ClearColumnHeadersRow) + <-speech.spoken + if frame := <-frames; frame.Text != "Monday 10 B3" { + t.Fatalf("cleared frame = %+v", frame) + } + if state.current.TableColumnHeaders != "" || state.brailleSnapshot.TableColumnHeaders != "" { + t.Fatal("clear retained column heading") + } + gate.secure.Store(true) + handler.configureCalcHeader(input.SetColumnHeadersRow) + gate.secure.Store(false) + gate.suspended.Store(true) + handler.configureCalcHeader(input.SetColumnHeadersRow) + gate.suspended.Store(false) + if len(speech.spoken) != 0 || len(frames) != 0 { + t.Fatal("header command bypassed lock/suspension") + } + state.owner.focus = atspi.NewObjectID(event.Source.BusName, "/other") + handler.configureCalcHeader(input.SetColumnHeadersRow) + if got := <-speech.spoken; got != "Not in a Calc cell." { + t.Fatal(got) + } + handler.syncForeground = func() { state.current = atspi.Snapshot{} } + handler.configureCalcHeader(input.SetColumnHeadersRow) + if got := <-speech.spoken; got != "Not in a Calc cell." { + t.Fatal(got) + } +} + +func TestLibreOfficeHeaderSpeechHistoryAndBraille(t *testing.T) { + event := calcTestEvent(atspi.FocusEvent, "/cell", "10", "B3") + event.Source.TableRowIndex, event.Source.TableColumnIndex = 2, 1 + event.Source.TableRowHeaders, event.Source.TableColumnHeaders = "Monday", "Total" + state := eventLoopState{} + state.lastTable, state.lastTableCell = calcSheet(event.Source), event.Source.ID() + state.lastTableRow, state.lastTableColumn = 2, 0 + filtered := state.calcHeaderSpeechEvent(event) + if filtered.Source.TableRowHeaders != "" || filtered.Source.TableColumnHeaders != "Total" { + t.Fatalf("horizontal: %+v", filtered.Source) + } + state.lastTableRow, state.lastTableColumn = 1, 1 + filtered = state.calcHeaderSpeechEvent(event) + if filtered.Source.TableRowHeaders != "Monday" || filtered.Source.TableColumnHeaders != "" { + t.Fatalf("vertical: %+v", filtered.Source) + } + // The accepted snapshot retains both for Where Am I and Braille. + if got := presentation.FocusText(event.Source); got != "Monday row header, Total column header, 10, B3" { + t.Fatal(got) + } + if frame := brailleFocusFrame(event.Source); frame.Text != "Monday Total 10 B3" { + t.Fatalf("frame = %+v", frame) + } + reading := config.DefaultSettings().Reading + reading.OnlySpeakDisplayedText = true + options := presentation.DefaultOptions() + options.Reading = &reading + if got := presentation.FocusTextWithOptions(event.Source, options); got != "10" { + t.Fatal(got) + } + state.current = event.Source + state.clearObjectFocus(nil, nil, nil) + filtered = state.calcHeaderSpeechEvent(event) + if filtered.Source.TableRowHeaders == "" || filtered.Source.TableColumnHeaders == "" { + t.Fatal("focus return suppressed headers") + } + state.lastTable = atspi.NewObjectID(event.Source.BusName, "/other-sheet") + filtered = state.calcHeaderSpeechEvent(event) + if filtered.Source.TableRowHeaders == "" || filtered.Source.TableColumnHeaders == "" { + t.Fatal("sheet return suppressed headers") + } +} diff --git a/internal/app/libreoffice_native_test.go b/internal/app/libreoffice_native_test.go new file mode 100644 index 0000000..285cf46 --- /dev/null +++ b/internal/app/libreoffice_native_test.go @@ -0,0 +1,395 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bytes" + "context" + "log/slog" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +type calcFrameQueue struct{ frames chan braille.Frame } + +func (queue calcFrameQueue) EnqueueFrame(frame braille.Frame) { queue.frames <- frame } + +// This runs the production native adapter and event loop against real Calc. +// Speech/Braille are recorded queues, not audible or physical display proof. +func TestNativeLibreOfficeCalc(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_LIBREOFFICE") != "1" { + t.Skip("requires tests/native_libreoffice.py") + } + window := os.Getenv("CTHULHU_CALC_WINDOW") + if window == "" { + t.Fatal("Calc window missing") + } + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + speech := &fakeSpeechQueue{spoken: make(chan string, 256)} + frames := make(chan braille.Frame, 256) + done := make(chan error, 1) + commands := make(chan input.Command, 1) + var logBuffer bytes.Buffer + logger := slog.New(slog.NewTextHandler(&logBuffer, &slog.HandlerOptions{Level: slog.LevelDebug})) + options := presentation.DefaultOptions() + options.EnableEchoByCharacter = true + go func() { + done <- processEventsWithReview(ctx, logger, outputQueue{speech: speech, braille: calcFrameQueue{frames}}, adapter, commands, 0, options) + }() + defer func() { + cancel() + <-done + if t.Failed() { + t.Log(logBuffer.String()) + } + }() + press := func(keys ...string) { + t.Helper() + args := append([]string{"key", "--clearmodifiers"}, keys...) + if err := exec.CommandContext(ctx, "xdotool", args...).Run(); err != nil { + t.Fatal(err) + } + } + waitSpeech := func(want string) { + t.Helper() + timeout := time.NewTimer(5 * time.Second) + defer timeout.Stop() + for { + select { + case got := <-speech.spoken: + t.Logf("Calc speech: %q", got) + if strings.Contains(got, "1048576") || strings.Contains(got, "grayed") { + t.Fatalf("Calc capacity/state chatter: %q", got) + } + if got == want || strings.HasSuffix(got, ". "+want) { + return + } + case <-timeout.C: + t.Fatalf("missing Calc speech %q", want) + } + } + } + waitFrame := func(suffix string) { + t.Helper() + timeout := time.NewTimer(5 * time.Second) + defer timeout.Stop() + for { + select { + case frame := <-frames: + if strings.HasSuffix(frame.Text, suffix) { + return + } + case <-timeout.C: + t.Fatalf("missing Calc Braille ending %q", suffix) + } + } + } + enterEditor := func(coordinate string) { + t.Helper() + drain: + for { + select { + case <-frames: + default: + break drain + } + } + press("F2") + timeout := time.NewTimer(5 * time.Second) + defer timeout.Stop() + for { + select { + case frame := <-frames: + if strings.Contains(frame.Text, "Cell "+coordinate) { + return + } + case <-timeout.C: + t.Fatal("Calc did not expose its temporary cell editor") + } + } + } + activate := func(window string) { + t.Helper() + if err := exec.CommandContext(ctx, "xdotool", "windowactivate", "--sync", window).Run(); err != nil { + t.Fatal(err) + } + } + // Focus once. Refocusing before every key sequence can hide failures + // to retain or recover Calc's document focus during normal keyboard use. + activate(window) + press("Escape", "F6", "ctrl+F6", "ctrl+Home", "Right") + waitSpeech("42, B1") + waitFrame("42 B1") + press("Down") + waitSpeech("Beta, B2") + press("Left") + waitSpeech("blank, A2") + waitFrame("A2") + enterEditor("A2") + press("x") + waitSpeech("x") + press("Escape") + waitSpeech("blank, A2") + enterEditor("A2") + press("y") + waitSpeech("y") + press("Return") + waitSpeech("blank, A3") + press("Up") + waitSpeech("y, A2") + press("ctrl+Page_Down", "ctrl+Home") + waitSpeech("Gamma, A1") + press("ctrl+Page_Up", "ctrl+Home") + waitSpeech("Alpha, A1") + press("Right") + waitSpeech("42, B1") + enterEditor("B1") + press("Left") + waitSpeech("2") + press("Escape") + waitSpeech("42, B1") + press("F6") + press("ctrl+F6", "Down") + waitSpeech("Beta, B2") + waitFrame("Beta B2") + press("ctrl+Home", "Right", "Right") + waitSpeech("43, C1, has formula") + waitFrame("43 C1") + commands <- input.PresentCellFormula + waitSpeech("B1+1") + commands <- input.WhereAmI + waitSpeech("43, C1, has formula, B1+1") + press("Right") + waitSpeech("blank, D1, has formula") + commands <- input.PresentCellFormula + waitSpeech(`""`) + // Replacing a formula must refresh metadata for the same cell identity. + press("7", "Return", "Up") + waitSpeech("7, D1") + commands <- input.PresentCellFormula + waitSpeech("7") + press("Right") + waitSpeech("two spaces, E1, has formula") + commands <- input.PresentCellFormula + waitSpeech(`"two spaces"`) + press("Right") + waitSpeech("blank, F1") + commands <- input.PresentCellFormula + waitSpeech("empty") + press("ctrl+Page_Down", "ctrl+Home", "Right", "Right") + waitSpeech("blank, C1") + commands <- input.PresentCellFormula + waitSpeech("empty") + press("ctrl+Home") + waitSpeech("Gamma, A1") + press("shift+Right") + waitSpeech("Cell B1 selected.") + press("shift+Down") + waitSpeech("Cells A2 to B2 selected.") + press("shift+Up") + waitSpeech("Cells A2 to B2 unselected.") + // Formula commands must still use the active cell, not the range's + // first selected child or the sheet that emitted the selection event. + commands <- input.PresentCellFormula + waitSpeech("Gamma") + press("Right") + waitSpeech("Selection cleared.") + press("ctrl+Home", "shift+space") + waitSpeech("Row 1 selected.") + press("shift+Down") + waitSpeech("Row 2 selected.") + press("ctrl+Home", "ctrl+space") + waitSpeech("Column A selected.") + press("shift+Right") + waitSpeech("Column B selected.") + press("ctrl+Home", "ctrl+a", "ctrl+a") + waitSpeech("All cells selected.") + // Calc omits events while shrinking full-column ranges. Growing the + // shrunken selection again supplies an event for a capped partial sheet. + press("shift+Left", "shift+Left", "shift+Right") + waitSpeech("At least 2147483647 cells selected.") + press("Right") + waitSpeech("Selection cleared.") + press("Down") + waitSpeech("blank, B2") + // Use the provider's selection API to make actual disjoint selections; + // these are distinct from the synthetic event/presentation unit checks. + if output, err := exec.CommandContext(ctx, "/usr/bin/python3", "../../tests/native_libreoffice.py", "--select-disjoint").CombinedOutput(); err != nil { + t.Fatalf("disjoint Calc selection: %v: %s", err, output) + } + waitSpeech("Cell C1 selected.") + commands <- input.PresentCellFormula + waitSpeech("empty") + press("Right") + waitSpeech("Selection cleared.") + // A large non-column selection has an exact count, without enumerating + // its cells or inferring a rectangle from boundary samples. + press("ctrl+Home", "shift+Right", "ctrl+shift+Down", "shift+Up") + waitSpeech("2097150 cells selected.") + press("Right") + waitSpeech("Selection cleared.") + // Dynamic headers are real provider cell reads, isolated per sheet. + press("ctrl+Page_Up", "ctrl+Home") + waitSpeech("Alpha, A1") + commands <- input.SetColumnHeadersRow + waitSpeech("Row 1 set as column headers.") + commands <- input.SetRowHeadersColumn + waitSpeech("Column A set as row headers.") + press("Right") + waitSpeech("42, B1") + press("Down") + waitSpeech("y row header, Beta, B2") + waitFrame("y 42 Beta B2") + commands <- input.WhereAmI + waitSpeech("y row header, 42 column header, Beta, B2") + press("Right") + waitSpeech("43 column header, blank, C2") + press("Down") + waitSpeech("blank, C3") + press("Up") + waitSpeech("y row header, blank, C2") + press("ctrl+Page_Down", "ctrl+Home") + waitSpeech("Gamma, A1") + commands <- input.SetColumnHeadersRow + waitSpeech("Row 1 set as column headers.") + press("Down") + waitSpeech("blank, A2") // Same column: only Where Am I repeats its header. + commands <- input.WhereAmI + waitSpeech("Gamma column header, blank, A2") + press("ctrl+Page_Up", "ctrl+Home", "Right", "Down") + waitSpeech("y row header, Beta, B2") + // A heading edit is visible on the next cell snapshot, without a cache. + press("Up") + waitSpeech("Alpha row header, 42, B1") + press("8", "Return") + waitSpeech("y row header, Beta, B2") + waitFrame("y 8 Beta B2") + commands <- input.WhereAmI + waitSpeech("y row header, 8 column header, Beta, B2") + commands <- input.ClearColumnHeadersRow + waitSpeech("Column headers cleared.") + commands <- input.WhereAmI + waitSpeech("y row header, Beta, B2") + commands <- input.ClearRowHeadersColumn + waitSpeech("Row headers cleared.") + commands <- input.WhereAmI + waitSpeech("Beta, B2") + press("Up", "Down") + waitSpeech("Beta, B2") + press("ctrl+Page_Down", "ctrl+Home", "Down") + waitSpeech("blank, A2") + commands <- input.WhereAmI + waitSpeech("Gamma column header, blank, A2") + // A second workbook in the same provider bus must not inherit choices. + profile, document := os.Getenv("CTHULHU_CALC_PROFILE"), os.Getenv("CTHULHU_CALC_SECOND_DOCUMENT") + if profile == "" || document == "" { + t.Fatal("private second-workbook fixture missing") + } + if output, err := exec.CommandContext(ctx, "libreoffice", "-env:UserInstallation="+profile, "--calc", document).CombinedOutput(); err != nil { + t.Fatalf("open second private workbook: %v: %s", err, output) + } + secondWindow := "" + deadline := time.Now().Add(5 * time.Second) + for secondWindow == "" && time.Now().Before(deadline) { + output, _ := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--class", "libreoffice-calc").Output() + for _, candidate := range strings.Fields(string(output)) { + if candidate != window { + secondWindow = candidate + } + } + if secondWindow == "" { + time.Sleep(20 * time.Millisecond) + } + } + if secondWindow == "" { + t.Fatal("second private workbook window missing") + } + activate(secondWindow) + press("ctrl+F6", "ctrl+Page_Down", "ctrl+Home", "Down") + waitSpeech("blank, A2") + commands <- input.WhereAmI + waitSpeech("blank, A2") + press("Up", "d", "Return") + waitSpeech("blank, A2") + press("Up") + waitSpeech("d, A1") + commands <- input.SetColumnHeadersRow + waitSpeech("Row 1 set as column headers.") + press("Down") + waitSpeech("blank, A2") + commands <- input.WhereAmI + waitSpeech("d column header, blank, A2") + // Return to the first workbook, then back again: identical sheet names + // must retain independent choices and fresh cells in both directions. + // Use normal navigation here, without the Ctrl+F6 recovery shortcut. + activate(window) + press("ctrl+Home", "Down") + waitSpeech("blank, A2") + commands <- input.WhereAmI + waitSpeech("Gamma column header, blank, A2") + waitFrame("Gamma A2") + activate(secondWindow) + press("ctrl+Home", "Down") + waitSpeech("blank, A2") + commands <- input.WhereAmI + waitSpeech("d column header, blank, A2") + waitFrame("d A2") + // Dialog activation still resolves its focused control. Cancelling it + // must leave the document navigable with the same header choices. + press("ctrl+h") + dialogWindow := "" + deadline = time.Now().Add(5 * time.Second) + for dialogWindow == "" && time.Now().Before(deadline) { + output, _ := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Find and Replace$").Output() + if candidates := strings.Fields(string(output)); len(candidates) == 1 { + dialogWindow = candidates[0] + } else { + time.Sleep(20 * time.Millisecond) + } + } + if dialogWindow == "" { + t.Fatal("private Find and Replace dialog window missing") + } + activate(dialogWindow) + press("x") + waitSpeech("x") + press("Escape") + deadline = time.Now().Add(5 * time.Second) + for { + output, _ := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Find and Replace$").Output() + if len(strings.Fields(string(output))) == 0 { + break + } + if time.Now().After(deadline) { + t.Fatal("private Find and Replace dialog did not close") + } + time.Sleep(20 * time.Millisecond) + } + activate(secondWindow) + press("ctrl+F6", "ctrl+Home", "Down") + waitSpeech("blank, A2") + commands <- input.WhereAmI + waitSpeech("d column header, blank, A2") +} diff --git a/internal/app/libreoffice_selection.go b/internal/app/libreoffice_selection.go new file mode 100644 index 0000000..f0a5ab9 --- /dev/null +++ b/internal/app/libreoffice_selection.go @@ -0,0 +1,117 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "slices" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +// Owned by the event loop, with one bounded snapshot for the focused sheet. +// Retired on sheet/application focus changes and the ordinary focus reset +// (including lock, destruction, foreground loss, and shutdown). No timers or +// provider references survive a selection event. +type libreOfficeSelectionState struct { + sheet atspi.ObjectID + previous *atspi.LibreOfficeSelection +} + +func calcSheet(snapshot atspi.Snapshot) atspi.ObjectID { + if !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) || snapshot.LibreOffice == nil || !snapshot.LibreOffice.InSpreadsheet { + return atspi.ObjectID{} + } + if snapshot.Role == "table" { + return snapshot.ID() + } + if snapshot.LibreOffice.Cell { + return atspi.NewObjectID(snapshot.BusName, snapshot.TablePath) + } + return atspi.ObjectID{} +} + +func (handler *accessibilityEventHandler) handleLibreOfficeSelection(event atspi.Event) { + state := handler.state + if isFocusGainEvent(event) && state.libreOfficeSelection.sheet != calcSheet(event.Source) { + state.libreOfficeSelection = libreOfficeSelectionState{} + } + context := event.Source.LibreOffice + if event.Type != atspi.SelectionChangedEvent || context == nil || context.Selection == nil || + event.Source.Role != "table" || event.Source.Defunct || !context.InSpreadsheet || + !atspi.IsLibreOfficeProcess(event.Source.ApplicationProcess) || + handler.focusGate.Suspended() || !state.owner.window.Valid() || + state.owner.window != eventWindow(event) || state.owner.applicationBus != event.Source.BusName || + calcSheet(state.current) != event.Source.ID() { + return + } + history := &state.libreOfficeSelection + if history.sheet != event.Source.ID() { + *history = libreOfficeSelectionState{sheet: event.Source.ID()} + } + selection := context.Selection + handler.logger.Debug("received Calc selection snapshot", "kind", selection.Kind, + "count", selection.Count, "count_limited", selection.CountLimited, + "complete", selection.Complete, "cells", selection.Cells, + "first", selection.First, "last", selection.Last) + previous := history.previous + history.previous = selection + if previous != nil && previous.Kind == selection.Kind && previous.Count == selection.Count && + previous.CountLimited == selection.CountLimited && previous.Complete == selection.Complete && + previous.First == selection.First && previous.Last == selection.Last && slices.Equal(previous.Cells, selection.Cells) { + return + } + reading := state.presentationOptions.Reading + if handler.live != nil { + settings := handler.live.Load() + reading = &settings.Reading + } + if reading != nil && reading.OnlySpeakDisplayedText { + return + } + var messages []string + if previous != nil && (previous.Count != 0 || previous.Kind == "all") { + if selection.Count == 0 && selection.Kind != "all" { + messages = append(messages, "Selection cleared.") + } else if previous.Kind == selection.Kind && previous.Kind != "all" && previous.Complete && selection.Complete { + removed := *previous + removed.Cells = calcSelectionDifference(previous.Cells, selection.Cells) + removed.Count = len(removed.Cells) + if text := presentation.LibreOfficeSelectionText(removed, "unselected"); text != "" { + messages = append(messages, text) + } + } + } + added := *selection + if selection.Complete && (selection.Kind == "cells" || previous != nil && previous.Kind == selection.Kind) { + if previous != nil && previous.Complete && previous.Kind == selection.Kind { + added.Cells = calcSelectionDifference(selection.Cells, previous.Cells) + } + if selection.Kind == "cells" && state.current.TablePositionKnown { + // Orca leaves the anchor to ordinary active-cell presentation. + anchor := atspi.LibreOfficeCell{Row: state.current.TableRowIndex, Column: state.current.TableColumnIndex} + added.Cells = calcSelectionDifference(added.Cells, []atspi.LibreOfficeCell{anchor}) + } + added.Count = len(added.Cells) + } + if text := presentation.LibreOfficeSelectionText(added, "selected"); text != "" { + messages = append(messages, text) + } + if text := strings.Join(messages, " "); text != "" { + state.pending.clear() + handler.speech.Enqueue(speechRequest{Text: text, Role: "system", Cause: "calc-selection"}) + } +} + +func calcSelectionDifference(first, second []atspi.LibreOfficeCell) []atspi.LibreOfficeCell { + var result []atspi.LibreOfficeCell + for _, cell := range first { + if !slices.Contains(second, cell) { + result = append(result, cell) + } + } + return result +} diff --git a/internal/app/libreoffice_selection_test.go b/internal/app/libreoffice_selection_test.go new file mode 100644 index 0000000..3b66fd7 --- /dev/null +++ b/internal/app/libreoffice_selection_test.go @@ -0,0 +1,156 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "log/slog" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +func TestLibreOfficeSelectionChangesKeepActiveCellAndBraille(t *testing.T) { + current := calcTestEvent(atspi.FocusEvent, "/cell", "43", "C1") + current.Source.TableColumnIndex = 2 + current.Source.LibreOffice.Formula = "B1+1" + state := eventLoopState{} + state.current, state.focusedID = current.Source, current.Source.ID() + state.owner = windowOwner{window: current.Window, applicationBus: current.Source.BusName} + state.presentationOptions = presentation.DefaultOptions() + speech := &fakeSpeechQueue{spoken: make(chan string, 16)} + display := &flashRecorder{} + live := &liveSettings{} + live.Store(config.DefaultSettings()) + handler := accessibilityEventHandler{state: &state, logger: slog.New(slog.DiscardHandler), + adapter: &fakeAdapter{}, speech: outputQueue{speech: speech, braille: display, live: live}, syncForeground: func() {}, webScripts: &webScriptController{}} + event := current + event.Type = atspi.SelectionChangedEvent + event.Source.Path, event.Source.Role = "/sheet", "table" + selection := func(cells ...atspi.LibreOfficeCell) { + event.Source.LibreOffice = &atspi.LibreOfficeContext{InSpreadsheet: true, + Selection: &atspi.LibreOfficeSelection{Kind: "cells", Count: len(cells), Complete: true, Cells: cells}} + handler.handle(event) + } + expect := func(want string) { + t.Helper() + select { + case got := <-speech.spoken: + if got != want { + t.Fatalf("got %q, want %q", got, want) + } + default: + t.Fatalf("missing %q", want) + } + if state.current.ID() != current.Source.ID() || state.focusedID != current.Source.ID() || presentation.LibreOfficeCellFormula(state.current) != "B1+1" { + t.Fatal("selection displaced active cell/formula") + } + if display.messages[len(display.messages)-1] != want { + t.Fatal("selection did not use system Braille flash") + } + } + selection(atspi.LibreOfficeCell{Row: 0, Column: 0}, atspi.LibreOfficeCell{Row: 0, Column: 2}) + expect("Cell A1 selected.") + handler.handle(event) + if len(speech.spoken) != 0 { + t.Fatal("duplicate selection repeated") + } + selection(atspi.LibreOfficeCell{Row: 0, Column: 0}, atspi.LibreOfficeCell{Row: 0, Column: 2}, atspi.LibreOfficeCell{Row: 0, Column: 4}) + expect("Cell E1 selected.") + selection(atspi.LibreOfficeCell{Row: 0, Column: 2}, atspi.LibreOfficeCell{Row: 0, Column: 4}) + expect("Cell A1 unselected.") + selection() + expect("Selection cleared.") + // A count-only change reports the new total, never a fabricated + // unselection of the whole old range when selections overlap. + event.Source.LibreOffice.Selection = &atspi.LibreOfficeSelection{Kind: "cells", Count: 1000000} + handler.handle(event) + expect("1000000 cells selected.") + event.Source.LibreOffice.Selection = &atspi.LibreOfficeSelection{Kind: "cells", Count: 1000001} + handler.handle(event) + expect("1000001 cells selected.") + // The same total with different boundary samples is a changed selection. + event.Source.LibreOffice.Selection = &atspi.LibreOfficeSelection{Kind: "cells", Count: 1000001, First: atspi.LibreOfficeCell{Row: 2, Column: 2}} + handler.handle(event) + expect("1000001 cells selected.") + // Whole-row/column shrinkage has the same delta policy when the + // provider supplies an event (the real Calc harness documents gaps). + for _, kind := range []string{"rows", "columns"} { + state.libreOfficeSelection = libreOfficeSelectionState{} + positions := []atspi.LibreOfficeCell{{Row: 0, Column: 0}, {Row: 1, Column: 0}} + label := "Row 2 unselected." + selectedLabel := "Rows 1 to 2 selected." + if kind == "columns" { + positions[1] = atspi.LibreOfficeCell{Row: 0, Column: 1} + label = "Column B unselected." + selectedLabel = "Columns A to B selected." + } + event.Source.LibreOffice.Selection = &atspi.LibreOfficeSelection{Kind: kind, Count: 2, Complete: true, Cells: positions} + handler.handle(event) + expect(selectedLabel) + event.Source.LibreOffice.Selection = &atspi.LibreOfficeSelection{Kind: kind, Count: 1, Complete: true, Cells: positions[:1]} + handler.handle(event) + expect(label) + } + state.clearObjectFocus(nil, nil, nil) + if state.libreOfficeSelection.previous != nil { + t.Fatal("selection survived owned-focus reset") + } +} + +func TestLibreOfficeSelectionRejectsUnownedAndSuppressedOutput(t *testing.T) { + for _, name := range []string{"other sheet", "other bus", "other window", "wrong process", "defunct", "locked", "suspended", "stale foreground", "displayed text"} { + t.Run(name, func(t *testing.T) { + current := calcTestEvent(atspi.FocusEvent, "/cell", "42", "B1") + state := eventLoopState{} + state.current, state.focusedID = current.Source, current.Source.ID() + state.owner = windowOwner{window: current.Window, applicationBus: current.Source.BusName} + state.foregroundState = atspi.ForegroundState{Epoch: 2} + state.presentationOptions = presentation.DefaultOptions() + speech := &fakeSpeechQueue{spoken: make(chan string, 4)} + gate := newFocusGate(nil) + handler := accessibilityEventHandler{state: &state, logger: slog.New(slog.DiscardHandler), adapter: &fakeAdapter{}, speech: speech, focusGate: gate, + foreground: &ocrTestForeground{state: state.foregroundState}, syncForeground: func() {}, webScripts: &webScriptController{}} + event := current + event.Type = atspi.SelectionChangedEvent + event.Foreground.Epoch = 2 + event.Source.Path, event.Source.Role = "/sheet", "table" + event.Source.LibreOffice = &atspi.LibreOfficeContext{InSpreadsheet: true, Selection: &atspi.LibreOfficeSelection{Kind: "all", Complete: true}} + switch name { + case "other sheet": + event.Source.Path = "/other_sheet" + case "other bus": + event.Source.BusName = ":1.99" + case "other window": + event.Window.Path = "/other_window" + case "wrong process": + event.Source.ApplicationProcess = "example" + case "defunct": + event.Source.Defunct = true + case "locked": + gate.secure.Store(true) + case "suspended": + gate.suspended.Store(true) + case "stale foreground": + event.Foreground.Epoch = 1 + case "displayed text": + reading := config.DefaultSettings().Reading + reading.OnlySpeakDisplayedText = true + state.presentationOptions.Reading = &reading + } + // Test the application hook after the ordinary foreground/security + // gates; wrong-process events belong to the generic application path. + if name == "wrong process" { + handler.handleLibreOfficeSelection(event) + } else { + handler.handle(event) + } + if len(speech.spoken) != 0 || state.current.ID() != current.Source.ID() { + t.Fatal("unowned/suppressed selection changed output or focus") + } + }) + } +} diff --git a/internal/app/libreoffice_test.go b/internal/app/libreoffice_test.go new file mode 100644 index 0000000..4a42bbe --- /dev/null +++ b/internal/app/libreoffice_test.go @@ -0,0 +1,202 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +func calcTestEvent(eventType, path, value, coordinate string) atspi.Event { + source := atspi.Snapshot{BusName: ":1.42", Path: path, Role: "table cell", Name: coordinate, + Text: value, ApplicationProcess: "soffice.bin", Focused: true, + TablePath: "/sheet", TablePositionKnown: true, + LibreOffice: &atspi.LibreOfficeContext{InSpreadsheet: true, Cell: true, CellText: value, Coordinates: coordinate}} + event := atspi.NewEvent(eventType, source) + event.NativeType = eventType + event.Window = atspi.NewObjectID(source.BusName, "/window") + event.OriginPath = "/sheet" + return event +} + +func TestLibreOfficeFormulaCommandUsesOwnedFocusAndSecurityGates(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 4)} + state := eventLoopState{} + state.current = calcTestEvent(atspi.FocusEvent, "/cell", "43", "C1").Source + state.current.LibreOffice.Formula = "B1+1" + gate := &focusGate{} + display := &flashRecorder{} + live := &liveSettings{} + live.Store(config.DefaultSettings()) + queue := outputQueue{speech: speech, braille: display, live: live} + handler := eventReviewHandler{state: &state, speech: queue, focusGate: gate, + syncForeground: func() {}} + handler.presentCellFormula() + if got := <-speech.spoken; got != "B1+1" { + t.Fatalf("formula = %q", got) + } + if len(display.messages) != 1 || display.messages[0] != "B1+1" { + t.Fatalf("formula Braille flash = %v", display.messages) + } + gate.secure.Store(true) + handler.presentCellFormula() + gate.secure.Store(false) + gate.suspended.Store(true) + handler.presentCellFormula() + gate.suspended.Store(false) + if len(speech.spoken) != 0 || len(display.messages) != 1 { + t.Fatal("formula command bypassed lock or suspension") + } + // Synchronizing foreground ownership can retire the old Calc focus. + handler.syncForeground = func() { state.current = atspi.Snapshot{} } + handler.presentCellFormula() + if got := <-speech.spoken; got != "Not in a table." { + t.Fatalf("stale foreground formula = %q", got) + } +} + +func TestLibreOfficeMovementEditingAndFocusReturn(t *testing.T) { + state := eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + state.presentationOptions.EnableEchoByCharacter = true + speech := &fakeSpeechQueue{spoken: make(chan string, 32)} + handler := accessibilityEventHandler{state: &state, logger: slog.New(slog.DiscardHandler), + speech: speech, adapter: &fakeAdapter{}, clearOwnedFocus: func() {}, syncForeground: func() {}} + presenter := eventPresenter{state: &state, logger: handler.logger, speech: speech} + handler.speak = presenter.speak + handler.titles = &windowTitleController{state: &state, speech: speech, logger: handler.logger} + handler.webScripts = &webScriptController{speech: speech} + expectSpeech := func(want string) { + t.Helper() + select { + case got := <-speech.spoken: + if got != want { + t.Fatalf("Calc speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing Calc speech %q", want) + } + } + first := calcTestEvent(atspi.ActiveDescendantEvent, "/cell1", "42", "B1") + first.Source.TableColumnIndex = 1 + handler.handle(first) + expectSpeech("42, B1") + ancestor := first + ancestor.Type = atspi.FocusEvent + ancestor.Source.Path, ancestor.Source.Role, ancestor.Source.Name = "/root_pane", "root pane", "Example" + ancestor.Source.LibreOffice = nil + state.current.BrailleContext = []atspi.Snapshot{ancestor.Source} + handler.handle(ancestor) + if state.current.ID() != first.Source.ID() || len(speech.spoken) != 0 { + t.Fatal("ancestor focus displaced the active cell") + } + handler.handle(first) + if len(speech.spoken) != 0 { + t.Fatal("repeated cell descendant was spoken") + } + blank := calcTestEvent(atspi.ActiveDescendantEvent, "/cell2", "", "A2") + blank.Source.TableRowIndex = 1 + handler.handle(blank) + expectSpeech("blank, A2") + backgroundCaret := blank + backgroundCaret.Type = atspi.CaretEvent + backgroundCaret.Source.Path = "/input_line" + backgroundCaret.Source.Role = "paragraph" + backgroundCaret.Source.Text = "unrelated" + backgroundCaret.Source.LibreOffice = nil + handler.handle(backgroundCaret) + if state.current.ID() != blank.Source.ID() || len(speech.spoken) != 0 { + t.Fatal("formula-bar caret displaced cell focus") + } + editor := blank + editor.Type = atspi.TextInsertedEvent + editor.Source.Path, editor.Source.Role, editor.Source.Name = "/editor", "paragraph", "" + editor.Source.Editable = true + editor.Source.Text, editor.Payload = "x", "x" + editor.Source.LibreOffice = &atspi.LibreOfficeContext{InSpreadsheet: true, CellEditor: true} + handler.handle(editor) + if state.current.ID() != editor.Source.ID() || state.focusedID != editor.Source.ID() { + t.Fatal("first editor mutation was filtered before focus adoption") + } + expectSpeech("x") + table := editor + table.Type = atspi.FocusEvent + table.Source.Path, table.Source.Role, table.Source.Name = "/sheet", "table", "Sheet Example" + table.Source.LibreOffice = &atspi.LibreOfficeContext{InSpreadsheet: true} + handler.handle(table) + if state.current.ID() != table.Source.ID() || len(speech.spoken) != 0 { + t.Fatal("post-edit table focus was not owned silently") + } + handler.handle(blank) + expectSpeech("blank, A2") + otherSheet := calcTestEvent(atspi.ActiveDescendantEvent, "/other_cell", "Gamma", "A1") + otherSheet.OriginPath = "/other_sheet" + otherSheet.Source.TablePath = "/other_sheet" + handler.handle(otherSheet) + expectSpeech("Gamma, A1") + selection := blank + selection.Type = atspi.SelectionChangedEvent + handler.handle(selection) + if state.current.ID() != otherSheet.Source.ID() || len(speech.spoken) != 0 { + t.Fatal("range selection displaced the active cell") + } +} + +func TestLibreOfficePolicyCannotAdoptAnotherWindowOrProcess(t *testing.T) { + current := calcTestEvent(atspi.FocusEvent, "/cell", "42", "B1") + owner := windowOwner{window: current.Window, applicationBus: current.Source.BusName} + for _, change := range []func(*atspi.Event){ + func(event *atspi.Event) { event.Window.Path = "/other_window" }, + func(event *atspi.Event) { event.Source.ApplicationProcess = "chromium" }, + func(event *atspi.Event) { event.Source.Focused = false }, + func(event *atspi.Event) { event.Source.Defunct = true }, + } { + event := calcTestEvent(atspi.ActiveDescendantEvent, "/other_cell", "wrong", "C1") + change(&event) + result := prepareLibreOfficeEvent(event, current.Source, owner) + if result.event.Type != atspi.ActiveDescendantEvent || result.adoptFocus { + t.Fatalf("unowned cell became focus: %+v", result) + } + } +} + +func TestLibreOfficeBraillePreservesSpacingAndHasNoEditorRoute(t *testing.T) { + event := calcTestEvent(atspi.FocusEvent, "/cell", "é 猫", "B3") + frame := brailleFocusFrameWithOptions(event.Source, config.DefaultSettings().Braille) + if frame.Text != "é 猫 B3" || frame.Cursor != 0 || len(frame.Routes) != 0 { + t.Fatalf("Calc Braille = %+v", frame) + } +} + +func TestLibreOfficeRoutingHonorsLockAndForegroundBeforePolicy(t *testing.T) { + for _, locked := range []bool{true, false} { + t.Run(map[bool]string{true: "locked", false: "stale foreground"}[locked], func(t *testing.T) { + current := calcTestEvent(atspi.FocusEvent, "/current", "42", "B1") + state := eventLoopState{} + state.current, state.focusedID = current.Source, current.Source.ID() + state.owner = windowOwner{window: current.Window, applicationBus: current.Source.BusName} + state.foregroundState = atspi.ForegroundState{Epoch: 2} + state.lastSpokenText = "unchanged" + gate := newFocusGate(nil) + gate.secure.Store(locked) + speech := &fakeSpeechQueue{spoken: make(chan string, 4)} + handler := accessibilityEventHandler{state: &state, focusGate: gate, speech: speech, + logger: slog.New(slog.DiscardHandler), adapter: &fakeAdapter{}, + foreground: &ocrTestForeground{state: state.foregroundState}, + syncForeground: func() {}, webScripts: &webScriptController{}} + event := calcTestEvent(atspi.ActiveDescendantEvent, "/new_cell", "wrong", "C1") + event.Foreground.Epoch = 1 + handler.handle(event) + if state.current.ID() != current.Source.ID() || state.lastSpokenText != "unchanged" || len(speech.spoken) != 0 { + t.Fatal("LibreOffice policy ran before security/foreground rejection") + } + }) + } +} diff --git a/internal/app/linked_headings_native_test.go b/internal/app/linked_headings_native_test.go new file mode 100644 index 0000000..51dfef9 --- /dev/null +++ b/internal/app/linked_headings_native_test.go @@ -0,0 +1,244 @@ +package app + +import ( + "context" + "errors" + "fmt" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeLinkedHeadings(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_LINKED_HEADINGS") != "1" { + t.Skip("requires private linked heading browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 40*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + if output, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "Tab", "shift+Tab").CombinedOutput(); err != nil { + t.Fatalf("fixture focus: %s, %v", output, err) + } + var focus atspi.ObjectID + var bounds atspi.Rectangle + for !focus.Valid() && ctx.Err() == nil { + tree, err := adapter.CaptureDesktop(ctx) + if err == nil { + focus = linkedHeadingFixtureFocus(tree) + if focus.Valid() { + ref, _ := tree.Reference(focus) + geometry, _ := tree.Geometry(ref) + if geometry.BoundsKnown { + bounds = geometry.Bounds + } + } + } + if !focus.Valid() { + time.Sleep(100 * time.Millisecond) + } + } + if !focus.Valid() { + t.Fatal("linked heading fixture input absent from accessible desktop") + } + if !bounds.Valid() { + t.Fatal("linked heading fixture input has no screen bounds") + } + keys := []string{"key", "--clearmodifiers", "ctrl+l"} + if output, err := exec.CommandContext(ctx, "xdotool", keys...).CombinedOutput(); err != nil { + t.Fatalf("focus browser chrome: %s, %v", output, err) + } + pointX, pointY := bounds.X+bounds.Width/2, bounds.Y+bounds.Height/2 + if output, err := exec.CommandContext(ctx, "xdotool", "mousemove", "--sync", fmt.Sprint(pointX), fmt.Sprint(pointY), "click", "1").CombinedOutput(); err != nil { + t.Fatalf("focus fixture input: %s, %v", output, err) + } + focused := false + deadline := time.NewTimer(5 * time.Second) + defer deadline.Stop() + for !focused { + select { + case event := <-adapter.Events(): + focused = event.Type == atspi.FocusedStateEvent && event.Detail1 == 1 && event.Source.ID() == focus + case <-deadline.C: + t.Fatal("fixture input did not emit native focus") + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + t.Run("sound geometry after scrolling", func(t *testing.T) { + testLinkedHeadingSoundGeometry(t, ctx, adapter, focus) + }) + for _, tc := range []struct { + level int + name, title string + moves int + }{ + {2, "Inside heading link", "Cthulhu Linked Heading Inside", 1}, + {3, "Outside heading link", "Cthulhu Linked Heading Outside", 1}, + {3, "#1 Username Example date", "Cthulhu Linked Heading Post", 2}, + } { + tree, err := adapter.CaptureDocument(ctx, focus) + if err != nil { + t.Fatal(err) + } + cursor, err := review.NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, focus); err != nil { + t.Fatal(err) + } + move, err := cursor.Move(ctx, review.DocumentHeading, tc.level, false) + for step := 1; step < tc.moves && err == nil; step++ { + move, err = cursor.Move(ctx, review.DocumentHeading, tc.level, false) + } + if err != nil || !move.Moved || move.Position.Snapshot.Name != tc.name || move.Position.LinkedHeading == nil { + t.Fatalf("heading level %d: %+v, %v", tc.level, move, err) + } + target, err := cursor.ActivationTarget() + if err != nil { + t.Fatal(err) + } + link, err := tree.Resolve(target) + if err != nil || link.Role != "link" { + t.Fatalf("activation target = %+v, %v", link, err) + } + if err := adapter.ActivateDocumentObject(ctx, target, focus); err != nil { + t.Fatalf("activate %s: %v", tc.name, err) + } + for { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", tc.title).Output() + if err == nil && strings.TrimSpace(string(output)) != "" { + break + } + if ctx.Err() != nil { + t.Fatalf("activation did not open %s: %s", tc.title, output) + } + time.Sleep(50 * time.Millisecond) + } + } + tree, err := adapter.CaptureDocument(ctx, focus) + if err != nil { + t.Fatal(err) + } + cursor, err := review.NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, focus); err != nil { + t.Fatal(err) + } + move, err := cursor.Move(ctx, review.DocumentHeading, 5, false) + if err != nil || !move.Moved || move.Position.LinkedHeading != nil { + t.Fatalf("plain-text heading with multiple links: %+v, %v", move, err) + } + if target, err := cursor.ActivationTarget(); target.Valid() || !errors.Is(err, review.ErrNoDocumentAction) { + t.Fatalf("ambiguous activation target = %v, %v", target, err) + } +} + +func testLinkedHeadingSoundGeometry(t *testing.T, ctx context.Context, adapter *atspi.Adapter, focus atspi.ObjectID) { + t.Helper() + tree, err := adapter.CaptureDocument(ctx, focus) + if err != nil { + t.Fatal(err) + } + cursor, err := review.NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, focus); err != nil { + t.Fatal(err) + } + cold, err := cursor.Move(ctx, review.DocumentHeading, 6, false) + if err != nil || !cold.Moved || cold.Position.LinkedHeading == nil { + t.Fatalf("cold offscreen heading = %+v, %v", cold, err) + } + if cold.Position.LinkedHeading.SoundGeometry.ObjectKnown { + t.Fatal("fixture heading must start offscreen without captured sound geometry") + } + worker, err := review.NewWorker(adapter, 2*time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(focus) + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + for _, step := range []struct { + target review.DocumentTarget + level int + backwards bool + name string + }{ + {review.DocumentHeading, 6, false, "Offscreen first topic"}, + {review.DocumentHeading, 6, false, "Offscreen second topic"}, + {review.DocumentHeading, 6, true, "Offscreen first topic"}, + {review.DocumentLink, 0, false, "Offscreen first topic"}, + {review.DocumentLink, 0, false, "Offscreen second topic"}, + {review.DocumentLink, 0, true, "Offscreen first topic"}, + } { + if err := worker.MoveDocument(step.target, step.level, step.backwards); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + if result.Err != nil || result.CaretErr != nil || result.DocumentSoundErr != nil || + !result.Moved || result.DocumentPosition.Snapshot.Name != step.name { + t.Fatalf("scrolled heading result = %+v", result) + } + link := result.DocumentPosition.LinkedHeading + if step.target == review.DocumentLink { + link = &result.DocumentPosition.Snapshot + } + if link == nil || !link.SoundGeometry.ObjectKnown || !link.SoundGeometry.ReferenceKnown { + t.Fatalf("scrolled link lacks fresh geometry: %+v", link) + } + if !result.DocumentPosition.Snapshot.SoundGeometry.ObjectKnown { + t.Fatal("scrolled heading lacks fresh geometry") + } + cues := presentation.SoundCues(*link, presentation.Options{ + EnableSound: true, PlaySoundForRole: true, SpatializeObjectSounds: true, + }) + if len(cues) != 1 || cues[0].Pan >= -0.3 { + t.Fatalf("left-column link lost leftward sound: %+v", cues) + } + t.Logf("%s after scroll: bounds=%+v pan=%g", step.name, link.SoundGeometry.Object, cues[0].Pan) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } +} + +func linkedHeadingFixtureFocus(tree *atspi.AccessibleTree) atspi.ObjectID { + root, err := tree.Root() + if err != nil { + return atspi.ObjectID{} + } + pending := []atspi.ObjectReference{root} + for len(pending) != 0 { + current := pending[len(pending)-1] + pending = pending[:len(pending)-1] + snapshot, err := tree.Resolve(current) + if err != nil { + continue + } + if snapshot.Name == "Probe start" && snapshot.Role == "entry" { + return current.ID() + } + for child, ok, err := tree.FirstChild(current); err == nil && ok; child, ok, err = tree.NextSibling(child) { + pending = append(pending, child) + } + } + return atspi.ObjectID{} +} diff --git a/internal/app/live_region_test.go b/internal/app/live_region_test.go new file mode 100644 index 0000000..3ed087b --- /dev/null +++ b/internal/app/live_region_test.go @@ -0,0 +1,83 @@ +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestLiveRegionSpeaksInsertedChatWithoutEditableFocus(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + }() + defer func() { cancel(); <-done }() + + region := atspi.Snapshot{ + BusName: ":1.7", Path: "/chat/status", Role: "status", + LiveRegion: true, LivePoliteness: "polite", LiveAtomic: true, + Text: "Username: Test message", + } + placeholder := region + placeholder.Text = "\ufffc" + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, placeholder, "\ufffc") + select { + case got := <-speech.spoken: + t.Fatalf("placeholder spoken as %q", got) + case <-time.After(30 * time.Millisecond): + } + adapter.events <- atspi.NewEvent(atspi.ChildrenAddedEvent, region) + select { + case got := <-speech.spoken: + if got != "Username: Test message" { + t.Fatalf("speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("live region was not spoken") + } + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, region, "Username: Test message") + select { + case got := <-speech.spoken: + t.Fatalf("duplicate live region speech %q", got) + case <-time.After(30 * time.Millisecond): + } + region.Text = "Username: Next message" + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, region, "Next message") + select { + case got := <-speech.spoken: + if got != "Username: Next message" { + // Atomic regions speak their current full content, supplied by the + // adapter, rather than only the insertion payload. + t.Fatalf("atomic speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("atomic live region insertion was not spoken") + } +} + +func TestLiveRegionOffDoesNotSpeak(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + }() + defer func() { cancel(); <-done }() + + region := atspi.Snapshot{BusName: ":1.7", Path: "/chat/status", Role: "status", LiveRegion: true, LivePoliteness: "off", Text: "Silence"} + adapter.events <- atspi.NewEvent(atspi.ChildrenAddedEvent, region) + select { + case got := <-speech.spoken: + t.Fatalf("unexpected speech %q", got) + case <-time.After(30 * time.Millisecond): + } +} diff --git a/internal/app/live_settings.go b/internal/app/live_settings.go new file mode 100644 index 0000000..985e902 --- /dev/null +++ b/internal/app/live_settings.go @@ -0,0 +1,37 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/wine" + "sync/atomic" +) + +// Published settings are immutable snapshots shared by the preferences, input, +// and accessibility workers. Each event uses one complete snapshot. +type liveSettings struct { + editFieldFocused func() bool // Installed before workers start; reads cached focus only. + current atomic.Pointer[config.Settings] + preferencesPID atomic.Int64 // Owned by the preferences window lifetime; zero when closed. + application atomic.Pointer[string] + requestedApplication atomic.Pointer[string] + clipboardChanges chan struct{} + onApplication func(string) + wineTitles chan wineWindowTitle + wineReview *wine.ReviewRegistry +} + +func (live *liveSettings) Store(settings config.Settings) { + live.current.Store(&settings) + live.notify_clipboard() +} +func (live *liveSettings) notify_clipboard() { + select { + case live.clipboardChanges <- struct{}{}: + default: + } +} +func (live *liveSettings) Load() config.Settings { return *live.current.Load() } diff --git a/internal/app/mouse_review.go b/internal/app/mouse_review.go new file mode 100644 index 0000000..1482626 --- /dev/null +++ b/internal/app/mouse_review.go @@ -0,0 +1,176 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "log/slog" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/lifecycle" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +type pointReviewAdapter interface { + ReviewAtPoint(context.Context, int, int, int) (atspi.PointReview, error) +} + +type mouseReviewState struct { + ready bool + last atspi.PointReview + spoken string + position xorg.PointerPosition +} + +func (state *mouseReviewState) reset() { *state = mouseReviewState{} } + +func (state *mouseReviewState) clearItem(position xorg.PointerPosition) { + state.ready = true + state.last = atspi.PointReview{} + state.spoken = "" + state.position = position +} + +func (state *mouseReviewState) text(point atspi.PointReview, settings config.Settings) string { + return state.presentation(point, settings).Text +} + +func (state *mouseReviewState) presentation(point atspi.PointReview, settings config.Settings) presentation.Speech { + if !point.Snapshot.ID().Valid() || point.Snapshot.Defunct { + return presentation.Speech{} + } + if !state.ready { + state.ready = true + state.last = point + return presentation.Speech{} + } + changedObject := point.Snapshot.ID() != state.last.Snapshot.ID() || point.Window != state.last.Window + var value string + var spoken presentation.Speech + if changedObject { + snapshot := point.Snapshot + if snapshot.Role != "password text" && point.Line != snapshot.Name { + snapshot.Text = point.Line + } + spoken = presentation.FocusSpeechWithOptions(snapshot, presentationSettingsFromConfig(settings, true)) + value = spoken.Text + } else if point.LineStart != state.last.LineStart && point.Line != "" { + value = point.Line + } else if point.Word != "" && point.Word != state.last.Word { + value = point.Word + } + state.last = point + value = strings.TrimSpace(value) + if value == state.spoken && !changedObject { + return presentation.Speech{} + } + if value != "" { + state.spoken = value + } + spoken.Text = value + return spoken +} + +// Mouse review owns its pointer connection and last spoken item for one +// enabled session. Only copied snapshots leave the AT-SPI owner thread. +func mouseReviewService(logger *slog.Logger, adapter pointReviewAdapter, speech speechEnqueuer, + braille interface{ EnqueueMessage(string) bool }, live *liveSettings, gate *focusGate) lifecycle.Service { + var cancel context.CancelFunc + var done chan struct{} + return lifecycle.Service{Name: "mouse review", Start: func(ctx context.Context) error { + ctx, cancel = context.WithCancel(ctx) + done = make(chan struct{}) + go func() { + defer close(done) + pointer := xorg.OpenPointerReader() + if pointer == nil { + logger.Warn("mouse review pointer unavailable") + return + } + defer pointer.Close() + ticker := time.NewTicker(100 * time.Millisecond) + defer ticker.Stop() + var state mouseReviewState + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + } + settings := live.Load() + if !settings.Reading.EnableMouseReview || gate.Locked() { + state.reset() + continue + } + position := pointer.Read() + if !position.Known { + state.reset() + continue + } + if position.PID <= 0 { + state.clearItem(position) + continue + } + if state.ready && position == state.position { + continue + } + queryCtx, stop := context.WithTimeout(ctx, 2*time.Second) + point, err := adapter.ReviewAtPoint(queryCtx, position.X, position.Y, position.PID) + stop() + if err != nil { + if ctx.Err() == nil { + logger.Debug("mouse review hit test", "error", err) + } + continue + } + if pointer.Read() != position { + continue + } + settings = live.Load() + if !settings.Reading.EnableMouseReview || gate.Locked() { + state.reset() + continue + } + if !point.Snapshot.ID().Valid() { + state.clearItem(position) + continue + } + if point.Snapshot.Role == "tool tip" && !settings.Reading.PresentTooltips { + state.position = position + continue + } + spoken := state.presentation(point, settings) + message := spoken.Text + state.position = position + if message == "" { + continue + } + speech.Enqueue(speechRequest{Text: message, Chunks: spoken.Chunks, Role: point.Snapshot.Role, Cause: "mouse-review"}) + braille.EnqueueMessage(message) + logger.Debug("mouse review presentation", "bus", point.Snapshot.BusName, + "path", point.Snapshot.Path, "window", point.Window.Path, "command", "mouse-review", + "x", position.X, "y", position.Y, "native_offset", point.Offset, + "virtual_offset", -1, "selection_start", -1, "selection_end", -1, + "speech", message, "braille", message) + } + }() + return nil + }, Stop: func(ctx context.Context) error { + if cancel != nil { + cancel() + } + if done != nil { + select { + case <-done: + case <-ctx.Done(): + return ctx.Err() + } + } + return nil + }} +} diff --git a/internal/app/mouse_review_test.go b/internal/app/mouse_review_test.go new file mode 100644 index 0000000..0dcd0e2 --- /dev/null +++ b/internal/app/mouse_review_test.go @@ -0,0 +1,47 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestMouseReviewChangesObjectLineAndWordWithoutMovingFocus(t *testing.T) { + settings := config.DefaultSettings() + point := atspi.PointReview{Snapshot: atspi.Snapshot{BusName: ":1.9", Path: "/entry", Name: "Search", Role: "entry"}, + Window: atspi.ObjectID{BusName: ":1.9", Path: "/window"}, Word: "first", Line: "first second", LineStart: 0} + var state mouseReviewState + if got := state.text(point, settings); got != "" { + t.Fatalf("initial pointer spoke %q", got) + } + point.Word = "second" + if got := state.text(point, settings); got != "second" { + t.Fatalf("new word = %q", got) + } + if got := state.text(point, settings); got != "" { + t.Fatalf("duplicate word = %q", got) + } + point.Line, point.LineStart, point.Word = "next line", 12, "next" + if got := state.text(point, settings); got != "next line" { + t.Fatalf("new line = %q", got) + } + point.Snapshot.Path, point.Snapshot.Name, point.Snapshot.Role = "/button", "Save", "push button" + point.Word, point.Line = "", "" + if got := state.text(point, settings); !strings.Contains(got, "Save") || !strings.Contains(got, "button") { + t.Fatalf("new object = %q", got) + } + point.Snapshot.Path, point.Snapshot.Name, point.Snapshot.Role = "/password", "Password", "password text" + point.Word, point.Line = "secret", "secret" + if got := state.text(point, settings); strings.Contains(got, "secret") { + t.Fatalf("password leaked: %q", got) + } + state.clearItem(state.position) + if got := state.text(point, settings); !strings.Contains(got, "Password") { + t.Fatalf("object re-entry = %q", got) + } +} diff --git a/internal/app/named_links_native_test.go b/internal/app/named_links_native_test.go new file mode 100644 index 0000000..74ad297 --- /dev/null +++ b/internal/app/named_links_native_test.go @@ -0,0 +1,168 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeBrowserNamedLinks(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + if output, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "Tab", "shift+Tab").CombinedOutput(); err != nil { + t.Fatalf("fixture focus: %s, %v", output, err) + } + var focus atspi.ObjectID + for !focus.Valid() { + select { + case event := <-adapter.Events(): + if event.Type == atspi.FocusedStateEvent && event.Detail1 == 1 && event.Source.Name == "Probe start" { + focus = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + tree, err := adapter.CaptureDocument(ctx, focus) + if err != nil { + t.Fatal(err) + } + cursor, err := review.NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, focus); err != nil { + t.Fatal(err) + } + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + for _, step := range []struct { + command review.DocumentCaretCommand + text string + }{ + {review.CaretNextLine, "Example Game 2 copies"}, + {review.CaretNextCharacter, "x"}, + {review.CaretPreviousCharacter, "E"}, + {review.CaretNextWord, "Example"}, + {review.CaretNextWord, "Game"}, + {review.CaretLineEnd, "s"}, + {review.CaretLineStart, "E"}, + {review.CaretNextLine, "Ordinary multiline link"}, + {review.CaretNextCharacter, "r"}, + {review.CaretNextWord, "Ordinary"}, + {review.CaretNextWord, "multiline"}, + {review.CaretNextLine, "Useful image label"}, + {review.CaretPreviousLine, "Ordinary multiline link"}, + {review.CaretPreviousLine, "Example Game 2 copies"}, + } { + move, err := cursor.MoveCaret(ctx, adapter, step.command) + t.Logf("%v: path=%s role=%s text=%q offset=%d range=%d:%d count=%d", step.command, move.Position.Object.ID().Path, move.Position.Snapshot.Role, move.Text, move.Position.Offset, move.Start, move.End, move.Position.Snapshot.CharacterCount) + if err != nil || !move.Moved { + t.Fatalf("%v: %+v, %v", step.command, move, err) + } + if step.text == "Example Game 2 copies" && !move.Position.Snapshot.ExplicitName { + t.Fatal("native explicit-name attribute was not captured") + } + context, err := tree.DocumentContext(move.Position.Object) + if err != nil { + t.Fatal(err) + } + result := review.Result{DocumentCaretCommand: step.command, DocumentPosition: move.Position, + DocumentCaretText: move.Text, DocumentCaretContext: context.Ancestors, Moved: move.Moved} + presentDocumentCaretResult(slog.New(slog.DiscardHandler), queue, result, presentation.DefaultOptions()) + select { + case spoken := <-queue.spoken: + if !strings.Contains(spoken, step.text) { + t.Fatalf("%v spoke %q, want %q", step.command, spoken, step.text) + } + default: + t.Fatal("native browse result was silent") + } + } + reference, err := tree.Reference(focus) + if err != nil { + t.Fatal(err) + } + document, err := tree.Document(ctx, reference) + if err != nil { + t.Fatal(err) + } + var username, emoji atspi.ObjectReference + var labelOnly atspi.ObjectReference + for _, node := range document.Nodes { + if node.Snapshot.Role == "link" && node.Snapshot.Name == "Example Info Page" { + labelOnly = node.Reference + t.Logf("label-only native link: explicit=%t count=%d children=%d", node.Snapshot.ExplicitName, node.Snapshot.CharacterCount, len(node.Children)) + } + if node.Snapshot.Role != "static" { + continue + } + switch strings.TrimSpace(node.Snapshot.Name) { + case "Username": + username = node.Reference + case "🧻": + emoji = node.Reference + } + } + if !labelOnly.Valid() { + t.Fatal("label-only link missing") + } + if _, err := cursor.SyncFocus(ctx, labelOnly.ID()); err != nil { + t.Fatal(err) + } + for _, want := range []rune("xample Info Page.") { + move, err := cursor.MoveCaret(ctx, adapter, review.CaretNextCharacter) + if err != nil || !move.Moved || move.Text != string(want) { + t.Fatalf("label-only character: %+v, %v; want %q", move, err, want) + } + } + for _, want := range []rune("egaP ofnI elpmaxE") { + move, err := cursor.MoveCaret(ctx, adapter, review.CaretPreviousCharacter) + if err != nil || !move.Moved || move.Text != string(want) { + t.Fatalf("reverse label-only character: %+v, %v; want %q", move, err, want) + } + } + if !username.Valid() || !emoji.Valid() { + t.Fatal("separate display-name and emoji text objects missing") + } + word, err := adapter.ReadDocumentCaret(ctx, emoji, 0, atspi.DocumentCaretWord) + t.Logf("native emoji word: %+v, %v", word, err) + if _, err := cursor.SyncFocus(ctx, username.ID()); err != nil { + t.Fatal(err) + } + for _, step := range []struct { + command review.DocumentCaretCommand + text string + }{ + {review.CaretNextWord, "Username"}, + {review.CaretNextWord, "🧻"}, + {review.CaretNextWord, "After"}, + {review.CaretPreviousWord, "After"}, + {review.CaretPreviousWord, "🧻"}, + {review.CaretPreviousWord, "Username"}, + } { + move, err := cursor.MoveCaret(ctx, adapter, step.command) + if err != nil || !move.Moved || strings.TrimSpace(move.Text) != step.text { + t.Fatalf("word navigation across emoji, %v: %+v, %v; want %q", step.command, move, err, step.text) + } + } +} diff --git a/internal/app/notification_list_test.go b/internal/app/notification_list_test.go new file mode 100644 index 0000000..7e97dc6 --- /dev/null +++ b/internal/app/notification_list_test.go @@ -0,0 +1,141 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/notification" + "git.stormux.org/storm/cthulhu/internal/notificationui" +) + +func TestNotificationListSnapshotMatchesReferenceLayout(t *testing.T) { + presenter, controller, speech := notificationListFixture(t) + worker := newNotificationListWorker(nil, presenter, speech) + response := worker.snapshot("") + + if response.Title != "2 notifications" { + t.Fatalf("title = %q, want %q", response.Title, "2 notifications") + } + if response.Selected != "1" { + t.Fatalf("selected = %q, want %q", response.Selected, "1") + } + if len(response.Entries) != 2 { + t.Fatalf("entry count = %d, want 2", len(response.Entries)) + } + latest := response.Entries[0] + if latest.Message != "Live message" || latest.Received != "0 seconds ago" || !latest.CanControl { + t.Fatalf("latest entry = %+v", latest) + } + if len(latest.Actions) != 2 || latest.Actions[0].Key != "default" || latest.Actions[1].Key != "reply" { + t.Fatalf("actions = %+v, want sorted default and reply", latest.Actions) + } + if response.Entries[1].CanControl { + t.Fatalf("older generic entry unexpectedly controllable: %+v", response.Entries[1]) + } + if len(controller.dismissed) != 0 || len(controller.invoked) != 0 { + t.Fatalf("snapshot unexpectedly changed controller state: %+v", controller) + } +} + +func TestNotificationListActionsMatchReferenceBehavior(t *testing.T) { + tests := []struct { + name string + request notificationui.Request + wantClose bool + wantSpeech string + }{ + { + name: "copy", + request: notificationui.Request{Copy: true}, + wantSpeech: messageClipboardCopiedFull, + }, + { + name: "dismiss", + request: notificationui.Request{Dismiss: true, Selection: "1", Row: intPointer(0)}, + wantSpeech: notification.MessageDismissed, + }, + { + name: "invoke action", + request: notificationui.Request{Action: "reply", Selection: "1", Row: intPointer(0)}, + wantSpeech: notification.MessageActionInvoked, + }, + { + name: "clear", + request: notificationui.Request{Clear: true}, + wantClose: true, + wantSpeech: notification.MessageNoMessages, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + presenter, controller, speech := notificationListFixture(t) + worker := newNotificationListWorker(nil, presenter, speech) + response, close := worker.handle(test.request) + if close != test.wantClose { + t.Fatalf("close = %v, want %v", close, test.wantClose) + } + select { + case message := <-speech.spoken: + if message != test.wantSpeech { + t.Fatalf("speech = %q, want %q", message, test.wantSpeech) + } + default: + t.Fatal("no speech was presented") + } + if test.request.Clear && len(presenter.Entries()) != 0 { + t.Fatalf("history length after clear = %d, want 0", len(presenter.Entries())) + } + if test.request.Dismiss && len(presenter.Entries()) != 1 { + t.Fatalf("history length after dismiss = %d, want 1", len(presenter.Entries())) + } + if test.request.Action != "" && controller.invoked[0].key != "reply" { + t.Fatalf("invoked = %+v, want reply", controller.invoked) + } + if response.Selected == "" && !test.wantClose { + t.Fatalf("selected = %q, want a live selection", response.Selected) + } + }) + } +} + +func notificationListFixture(t *testing.T) (*notification.Presenter, *notificationListController, *fakeSpeechQueue) { + t.Helper() + now := time.Unix(1_800_000_000, 0) + presenter := notification.NewPresenterAt(func() time.Time { return now }) + controller := ¬ificationListController{} + presenter.SetMakoController(controller) + presenter.Save("Older message") + identifier := 42 + presenter.Save("Live message", notification.SaveOptions{ + Source: notification.MakoSource, NotificationID: &identifier, Live: true, + Actions: map[string]string{"reply": "Reply", "default": "View"}, + }) + speech := &fakeSpeechQueue{spoken: make(chan string, 4)} + return presenter, controller, speech +} + +func intPointer(value int) *int { return &value } + +type notificationListAction struct { + id int + key string +} + +type notificationListController struct { + dismissed []int + invoked []notificationListAction +} + +func (controller *notificationListController) IsCurrent(notification.Entry) bool { return true } +func (controller *notificationListController) Dismiss(id int) bool { + controller.dismissed = append(controller.dismissed, id) + return true +} +func (controller *notificationListController) InvokeAction(id int, key string) bool { + controller.invoked = append(controller.invoked, notificationListAction{id: id, key: key}) + return true +} diff --git a/internal/app/notification_test.go b/internal/app/notification_test.go new file mode 100644 index 0000000..1e37a78 --- /dev/null +++ b/internal/app/notification_test.go @@ -0,0 +1,138 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/notification" +) + +func TestNotificationProvidersAndHistoryMatchReferenceBehavior(t *testing.T) { + tests := []struct { + name string + event atspi.Event + expectedSpeech []string + expectedHistory string + }{ + { + name: "xfce notification daemon labels", + event: notificationSnapshot("xfce4-notifyd", atspi.WindowCreateEvent, atspi.NewSnapshot( + "/notification", "", "frame", "", "Mail arrived New message", + )), + expectedSpeech: []string{"Notification Mail arrived New message"}, + expectedHistory: "Notification Mail arrived New message", + }, + { + name: "notify-osd name without value announces prefix and message", + event: notificationSnapshot("notify-osd", atspi.AccessibleNameEvent, atspi.NewSnapshot( + "/notification", "Volume", "notification", "at maximum", "", + )), + expectedSpeech: []string{"Notification", "Volume at maximum"}, + expectedHistory: "Volume at maximum", + }, + { + name: "notify-osd gauge value is not saved", + event: gaugeSnapshot(), + expectedSpeech: []string{"55"}, + expectedHistory: "", + }, + { + name: "generic accessible notification is saved", + event: showingNotification("Mail", "You have one unread message", true), + expectedSpeech: []string{"Mail, notification, You have one unread message"}, + expectedHistory: "Mail You have one unread message", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + presenter := notification.NewPresenter() + speech, entries := processNotificationEvent(t, test.event, presenter) + if len(speech) != len(test.expectedSpeech) { + t.Fatalf("speech count = %d, want %d: %q", len(speech), len(test.expectedSpeech), speech) + } + for index, expected := range test.expectedSpeech { + if speech[index] != expected { + t.Fatalf("speech %d = %q, want %q", index, speech[index], expected) + } + } + if test.expectedHistory == "" { + if len(entries) != 0 { + t.Fatalf("history length = %d, want 0", len(entries)) + } + return + } + if len(entries) != 1 { + t.Fatalf("history length = %d, want 1", len(entries)) + } + if entries[0].Message != test.expectedHistory { + t.Fatalf("history = %q, want %q", entries[0].Message, test.expectedHistory) + } + }) + } +} + +func TestHiddenGenericNotificationIsNotSaved(t *testing.T) { + event := showingNotification("Mail", "You have one unread message", false) + presenter := notification.NewPresenter() + _, entries := processNotificationEvent(t, event, presenter) + if len(entries) != 0 { + t.Fatalf("history length = %d, want 0", len(entries)) + } +} + +func showingNotification(name, text string, showing bool) atspi.Event { + event := notificationSnapshot("Application", atspi.ShowingStateEvent, + atspi.NewSnapshot("/notification", name, "notification", "", text)) + if showing { + event.Detail1 = 1 + } + return event +} + +func notificationSnapshot(application, eventType string, snapshot atspi.Snapshot) atspi.Event { + snapshot.ApplicationName = application + return atspi.NewEvent(eventType, snapshot) +} + +func gaugeSnapshot() atspi.Event { + snapshot := atspi.NewSnapshot("/notification", "Volume", "notification", "", "") + snapshot.ValueKnown = true + snapshot.CurrentValue = 55 + return notificationSnapshot("notify-osd", atspi.ValueChangedEvent, snapshot) +} + +func processNotificationEvent(t *testing.T, event atspi.Event, presenter *notification.Presenter) ([]string, []notification.Entry) { + t.Helper() + speech := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + adapter.events <- event + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan error, 1) + go func() { + completed <- processEventsWithInput( + ctx, slog.New(slog.DiscardHandler), speech, adapter, + nil, nil, 0, nil, nil, nil, presenter, + ) + }() + var messages []string + for { + select { + case message := <-speech.spoken: + messages = append(messages, message) + case <-time.After(50 * time.Millisecond): + cancel() + if err := <-completed; err != nil { + t.Fatalf("process events: %v", err) + } + return messages, presenter.Entries() + } + } +} diff --git a/internal/app/notifications.go b/internal/app/notifications.go new file mode 100644 index 0000000..0aed711 --- /dev/null +++ b/internal/app/notifications.go @@ -0,0 +1,276 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "io" + "log/slog" + "os" + "os/exec" + "sort" + "strconv" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/notification" + "git.stormux.org/storm/cthulhu/internal/notificationui" + "git.stormux.org/storm/cthulhu/internal/platform/session" +) + +const messageClipboardCopiedFull = "Copied selection to clipboard." + +type notificationListWorker struct { + logger *slog.Logger + presenter *notification.Presenter + speech speechEnqueuer + open chan struct{} + done chan struct{} + cancel context.CancelFunc + once sync.Once +} + +func newNotificationListWorker(logger *slog.Logger, presenter *notification.Presenter, speech speechEnqueuer) *notificationListWorker { + return ¬ificationListWorker{ + logger: logger, presenter: presenter, speech: speech, + open: make(chan struct{}, 1), done: make(chan struct{}), + } +} + +func (worker *notificationListWorker) Start(ctx context.Context) error { + ctx, worker.cancel = context.WithCancel(ctx) + go func() { + defer close(worker.done) + for { + select { + case <-ctx.Done(): + return + case <-worker.open: + if err := worker.window(ctx); err != nil && ctx.Err() == nil { + worker.logger.Error("notification list window", "error", err) + } + } + } + }() + return nil +} + +func (worker *notificationListWorker) Open() { + worker.presenter.RefreshLive() + if len(worker.presenter.Entries()) == 0 { + presentNotifications(worker.speech, []string{notification.MessageNoMessages}) + return + } + select { + case worker.open <- struct{}{}: + default: + } +} + +func (worker *notificationListWorker) Stop(ctx context.Context) error { + worker.once.Do(func() { + if worker.cancel != nil { + worker.cancel() + } + }) + select { + case <-worker.done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (worker *notificationListWorker) window(ctx context.Context) error { + executable, err := os.Executable() + if err != nil { + return err + } + childCtx, stop := context.WithCancel(ctx) + defer stop() + command := exec.CommandContext(childCtx, executable, "--notification-list-ui") + command.Env = session.GTKEnvironment() + command.WaitDelay = time.Second + in, err := command.StdinPipe() + if err != nil { + return err + } + out, err := command.StdoutPipe() + if err != nil { + in.Close() + return err + } + command.Stderr = os.Stderr + if err := command.Start(); err != nil { + in.Close() + out.Close() + return err + } + defer func() { stop(); in.Close(); out.Close(); _ = command.Wait() }() + + encoder := json.NewEncoder(in) + if err := encoder.Encode(worker.snapshot("")); err != nil { + return err + } + requests := make(chan notificationui.Request, 1) + readDone := make(chan error, 1) + readerStopped := make(chan struct{}) + go func() { + defer close(readerStopped) + defer stop() + scanner := bufio.NewScanner(out) + scanner.Buffer(make([]byte, 4096), 16*1024) + for scanner.Scan() { + var request notificationui.Request + if err := json.Unmarshal(scanner.Bytes(), &request); err != nil { + readDone <- err + return + } + select { + case requests <- request: + case <-childCtx.Done(): + readDone <- childCtx.Err() + return + } + } + readDone <- scanner.Err() + }() + defer func() { + stop() + out.Close() + <-readerStopped + }() + + for { + select { + case <-ctx.Done(): + return ctx.Err() + case <-worker.open: + if err := encoder.Encode(notificationui.Response{Present: true}); err != nil { + return err + } + case err := <-readDone: + if errors.Is(err, io.EOF) { + return nil + } + return err + case request := <-requests: + response, close := worker.handle(request) + if close { + response.Close = true + } + if err := encoder.Encode(response); err != nil { + return err + } + if close { + return nil + } + } + } +} + +func (worker *notificationListWorker) handle(request notificationui.Request) (notificationui.Response, bool) { + worker.presenter.RefreshLive() + entries := worker.listEntries() + selected := notification.Entry{} + for _, entry := range entries { + if entry.ID == request.Selection { + selected = entry + break + } + } + switch { + case request.Copy: + presentNotifications(worker.speech, []string{messageClipboardCopiedFull}) + case request.Dismiss: + if selected.ID == "" { + presentNotifications(worker.speech, []string{notification.MessageUnavailable}) + } else { + messages, _ := worker.presenter.DismissEntry(selected) + presentNotifications(worker.speech, messages) + } + case request.Clear: + worker.presenter.Clear() + presentNotifications(worker.speech, []string{notification.MessageNoMessages}) + return notificationui.Response{}, true + case request.Action != "": + if selected.ID == "" { + presentNotifications(worker.speech, []string{notification.MessageUnavailable}) + } else { + messages, _ := worker.presenter.InvokeActionEntry(selected, request.Action) + presentNotifications(worker.speech, messages) + } + } + if request.Dismiss { + return worker.snapshot(worker.selectionAfterRemoval(request)), false + } + return worker.snapshot(request.Selection), false +} + +func (worker *notificationListWorker) snapshot(selected string) notificationui.Response { + entries := worker.listEntries() + response := notificationui.Response{ + Title: worker.presenter.ListTitle(), Entries: make([]notificationui.Entry, len(entries)), + } + for index, entry := range entries { + response.Entries[index] = notificationui.Entry{ + ID: entry.ID, Message: entry.Message, Received: worker.presenter.ReceivedTime(entry.Timestamp), + CanControl: worker.presenter.CanControlEntry(entry), Actions: worker.actions(entry), + } + } + if len(response.Entries) != 0 { + response.Selected = response.Entries[0].ID + for _, entry := range response.Entries { + if entry.ID == selected { + response.Selected = selected + break + } + } + } + return response +} + +func (worker *notificationListWorker) listEntries() []notification.Entry { + history := worker.presenter.Entries() + entries := make([]notification.Entry, 0, len(history)) + for index := len(history) - 1; index >= 0; index-- { + entry := history[index] + entry.ID = strconv.Itoa(index) + entries = append(entries, entry) + } + return entries +} + +func (worker *notificationListWorker) selectionAfterRemoval(request notificationui.Request) string { + row := 0 + if request.Row != nil { + row = *request.Row + } + entries := worker.listEntries() + if len(entries) == 0 || row < 0 { + return "" + } + if row >= len(entries) { + row = len(entries) - 1 + } + return entries[row].ID +} + +func (worker *notificationListWorker) actions(entry notification.Entry) []notificationui.Action { + actions := worker.presenter.ActionsForEntry(entry) + keys := make([]string, 0, len(actions)) + for key := range actions { + keys = append(keys, key) + } + sort.Strings(keys) + result := make([]notificationui.Action, 0, len(keys)) + for _, key := range keys { + result = append(result, notificationui.Action{Key: key, Label: actions[key]}) + } + return result +} diff --git a/internal/app/object_review_events_test.go b/internal/app/object_review_events_test.go new file mode 100644 index 0000000..d063f71 --- /dev/null +++ b/internal/app/object_review_events_test.go @@ -0,0 +1,224 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestProcessEventsWhereAmIRepeatsCurrentFocus(t *testing.T) { + speech := &fakeSpeechQueue{ + spoken: make(chan string, 2), + interrupt: make(chan struct{}, 1), + } + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + reviewRequests := make(chan input.Command, 1) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan error, 1) + options := presentation.DefaultOptions() + options.EnableSound = true + options.PlaySoundForRole = true + options.RoleSoundPresentation = "sound_only" + go func() { + completed <- processEventsWithReview( + ctx, + slog.New(slog.DiscardHandler), + speech, + adapter, + reviewRequests, + 0, + options, + ) + }() + + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.NewSnapshot( + "/accessible/example", "Example", "button", "Runs the example", "", + )) + select { + case text := <-speech.spoken: + if text != "Example, Runs the example" { + t.Fatalf("focus speech = %q", text) + } + case <-time.After(time.Second): + t.Fatal("focus was not presented") + } + reviewRequests <- input.WhereAmI + select { + case text := <-speech.spoken: + if text != "Example, button, Runs the example" { + t.Fatalf("where am I speech = %q", text) + } + case <-time.After(time.Second): + t.Fatal("where am I was not presented") + } + cancel() + select { + case err := <-completed: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestProcessEventsWhereAmIWithoutFocus(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + reviewRequests := make(chan input.Command, 1) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan error, 1) + go func() { + completed <- processEventsWithReview( + ctx, + slog.New(slog.DiscardHandler), + speech, + adapter, + reviewRequests, + 0, + ) + }() + reviewRequests <- input.WhereAmI + select { + case text := <-speech.spoken: + if text != "Could not find current location." { + t.Fatalf("where am I without focus = %q", text) + } + case <-time.After(time.Second): + t.Fatal("missing-focus message was not presented") + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestProcessEventsSynchronizesAndPresentsObjectReview(t *testing.T) { + rootID := atspi.NewObjectID(":1.42", "/root") + firstID := atspi.NewObjectID(":1.42", "/first") + secondID := atspi.NewObjectID(":1.42", "/second") + root := atspi.NewSnapshot("/root", "Window", "frame", "", "") + root.BusName = ":1.42" + first := atspi.NewSnapshot("/first", "First", "push button", "", "") + first.BusName = ":1.42" + second := atspi.NewSnapshot("/second", "Second", "check box", "", "") + second.BusName = ":1.42" + second.Checked = true + tree, err := atspi.NewAccessibleTree(rootID, []atspi.TreeNode{ + {Snapshot: root, Children: []atspi.ObjectID{firstID, secondID}}, + {Snapshot: first}, + {Snapshot: second}, + }) + if err != nil { + t.Fatal(err) + } + adapter := &fakeAdapter{events: make(chan atspi.Event, 1), tree: tree} + objectReview, err := review.NewWorker(adapter, time.Second) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if err := objectReview.Start(ctx); err != nil { + t.Fatal(err) + } + speech := &fakeSpeechQueue{spoken: make(chan string, 3), interrupt: make(chan struct{}, 2)} + completed := make(chan error, 1) + go func() { + completed <- processEventsWithObjectReview( + ctx, + slog.New(slog.DiscardHandler), + speech, + adapter, + nil, + objectReview, + 0, + ) + }() + + adapter.events <- atspi.NewEvent(atspi.FocusEvent, first) + select { + case text := <-speech.spoken: + if text != "First, push button" { + t.Fatalf("focus speech = %q", text) + } + case <-time.After(time.Second): + t.Fatal("focus was not presented") + } + if err := objectReview.Move(review.NextSibling); err != nil { + t.Fatal(err) + } + select { + case text := <-speech.spoken: + if text != "Second, check box, checked" { + t.Fatalf("object review speech = %q", text) + } + case <-time.After(time.Second): + t.Fatal("object review movement was not presented") + } + if err := objectReview.Move(review.FirstChild); err != nil { + t.Fatal(err) + } + select { + case text := <-speech.spoken: + if text != "No children." { + t.Fatalf("object review boundary = %q", text) + } + case <-time.After(time.Second): + t.Fatal("object review boundary was not presented") + } + + cancel() + select { + case err := <-completed: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } + if err := objectReview.Stop(context.Background()); err != nil { + t.Fatal(err) + } +} + +func TestObjectReviewBoundaryMessagesMatchPython(t *testing.T) { + tests := map[review.Direction]string{ + review.Parent: "No parent.", + review.FirstChild: "No children.", + review.PreviousSibling: "No previous.", + review.NextSibling: "No next.", + } + for direction, expected := range tests { + if got := objectReviewBoundaryMessage(direction); got != expected { + t.Fatalf("direction %d = %q, want %q", direction, got, expected) + } + } +} diff --git a/internal/app/ocr_activate.go b/internal/app/ocr_activate.go new file mode 100644 index 0000000..d43e224 --- /dev/null +++ b/internal/app/ocr_activate.go @@ -0,0 +1,242 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bytes" + "context" + "errors" + "image" + "os/exec" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/ocr" +) + +type ocrActivateRequest struct { + job ocrJob + word ocr.Word + capture ocr.Capture +} + +type ocrDialogConfirmer struct{ executable string } + +func (helper ocrDialogConfirmer) Confirm(ctx context.Context, word string) (bool, error) { + if len(word) == 0 || len(word) > 4096 || strings.ContainsRune(word, 0) { + return false, errors.New("invalid OCR word") + } + ctx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + command := exec.CommandContext(ctx, helper.executable, "--ocr-confirm") + command.Stdin = strings.NewReader(word) + var output bytes.Buffer + command.Stdout = &output + if err := command.Run(); err != nil { + return false, err + } + if output.String() != "yes\n" && output.String() != "cancel\n" { + return false, errors.New("invalid OCR confirmation") + } + return output.String() == "yes\n", nil +} + +func (session *ocrSession) activate_locked() { + if session.cursor == nil || session.refreshing || session.refreshFailed || session.activating || session.clicker == nil || session.activateRequests == nil || + !session.current_locked(session.job) || session.job.kind == ocr.ClipboardSource { + session.status_locked("OCR activation unavailable; refresh the screen result") + return + } + word, ok := session.cursor.CurrentWord() + if !ok { + session.status_locked("Move to a recognized word to activate it") + return + } + if _, ok = session.pixels.Transform.ScreenRectangle(word.Bounds); !ok { + session.status_locked("OCR word has no screen position") + return + } + if session.autoTimer != nil { + session.autoTimer.Stop() + session.autoTimer = nil + } + session.activating = true + session.activationInterrupted = false + job := session.job + job.source = session.source + session.activateRequests <- ocrActivateRequest{job: job, word: word, capture: session.pixels} +} + +func (session *ocrSession) activation_current(request ocrActivateRequest) bool { + session.mu.Lock() + defer session.mu.Unlock() + return session.activating && !session.activationInterrupted && session.current_locked(request.job) +} + +func (session *ocrSession) activate(request ocrActivateRequest) { + if !session.activation_current(request) { + session.finish_activation(request, true, "OCR source changed") + return + } + ctx, cancel := context.WithTimeout(request.job.ctx, 35*time.Second) + defer cancel() + if err := session.keys.SetOCRReview(ctx, false); err != nil { + session.mu.Lock() + current := session.activating && session.generation == request.job.generation && session.cancel != nil + if current { + session.retire_locked() + } + session.mu.Unlock() + if current && !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, context.Canceled) { + select { + case session.failures <- err: + default: + } + } + if current { + session.release_input() + } + return + } + if session.settings().OCR.ConfirmClick { + if session.confirmer == nil { + session.finish_activation(request, false, "OCR confirmation unavailable") + return + } + confirmed, err := session.confirmer.Confirm(ctx, request.word.Text) + session.wait_activation_source(ctx, request) + if err != nil || !confirmed { + session.finish_activation(request, false, "OCR activation cancelled") + return + } + } + if !session.activation_current(request) { + session.finish_activation(request, true, "OCR source changed") + return + } + if err := session.validate_activation(ctx, request); err != nil { + session.finish_activation(request, true, "OCR source changed; refresh before activation") + return + } + rectangle, ok := request.capture.Transform.ScreenRectangle(request.word.Bounds) + if !ok { + session.finish_activation(request, true, "OCR word has no screen position") + return + } + point := image.Pt(rectangle.Min.X+(rectangle.Dx()-1)/2, rectangle.Min.Y+(rectangle.Dy()-1)/2) + session.mu.Lock() + if !session.activating || session.activationInterrupted || !session.current_locked(request.job) { + session.mu.Unlock() + session.finish_activation(request, true, "OCR source changed") + return + } + session.retire_locked() + session.mu.Unlock() + clickCtx, clickCancel := context.WithTimeout(context.Background(), time.Second) + defer clickCancel() + if err := session.clicker.ClickOCR(clickCtx, request.job.foreground.Client.Window, request.capture.RootBounds, point); err != nil { + session.mu.Lock() + session.status_locked("OCR click unavailable") + session.mu.Unlock() + } +} + +func (session *ocrSession) wait_activation_source(ctx context.Context, request ocrActivateRequest) { + deadline := time.NewTimer(time.Second) + defer deadline.Stop() + ticker := time.NewTicker(20 * time.Millisecond) + defer ticker.Stop() + for !session.activation_current(request) { + select { + case <-ctx.Done(): + return + case <-deadline.C: + return + case <-ticker.C: + } + } +} + +func (session *ocrSession) finish_activation(request ocrActivateRequest, stale bool, message string) { + session.mu.Lock() + if !session.activating || session.generation != request.job.generation || request.job.ctx.Err() != nil { + session.mu.Unlock() + return + } + if session.activationInterrupted || !session.current_locked(request.job) { + session.retire_locked() + session.status_locked("OCR source changed") + session.mu.Unlock() + return + } + session.mu.Unlock() + // Re-enter only in the original client. Native entry waits for complete + // dialog chord release and refuses changed foreground ownership. + ctx, cancel := context.WithTimeout(request.job.ctx, 2*time.Second) + err := session.keys.SetOCRContext(ctx, request.job.foreground.Client.Window, false) + cancel() + session.mu.Lock() + defer session.mu.Unlock() + if !session.activating || session.activationInterrupted || !session.current_locked(request.job) { + session.retire_locked() + return + } + if err != nil { + session.retire_locked() + session.status_locked("OCR review unavailable") + return + } + session.activating = false + if stale { + session.refreshFailed = true + } else { + session.schedule_refresh_locked() + } + session.status_locked(message) +} + +func (session *ocrSession) validate_activation(ctx context.Context, request ocrActivateRequest) error { + if request.capture.Pixels == nil { + return ocr.ErrSourceChanged + } + if request.job.kind == ocr.ObjectSource { + var zone *atspi.Rectangle + if request.job.source.HasZone { + zone = &request.job.source.Zone + } + geometry, err := session.geometry.CaptureOCRGeometry(ctx, request.job.source.Object, zone) + if err != nil || geometry.Foreground != request.job.foreground || geometry.ScreenBounds != request.capture.Request.Bounds { + return ocr.ErrSourceChanged + } + } + fresh, err := session.capture.Capture(ctx, request.capture.Request) + if err != nil || fresh.SourceWindow != request.capture.SourceWindow || fresh.RootBounds != request.capture.RootBounds || + fresh.SourceBounds != request.capture.SourceBounds || fresh.ScreenBounds != request.capture.ScreenBounds || + !equalOCRPixels(ctx, fresh.Pixels, request.capture.Pixels) { + return ocr.ErrSourceChanged + } + return nil +} + +func equalOCRPixels(ctx context.Context, first, second image.Image) bool { + if first == nil || second == nil || first.Bounds() != second.Bounds() { + return false + } + bounds := first.Bounds() + for y := bounds.Min.Y; y < bounds.Max.Y; y++ { + if y%32 == 0 && ctx.Err() != nil { + return false + } + for x := bounds.Min.X; x < bounds.Max.X; x++ { + r1, g1, b1, a1 := first.At(x, y).RGBA() + r2, g2, b2, a2 := second.At(x, y).RGBA() + if r1 != r2 || g1 != g2 || b1 != b2 || a1 != a2 { + return false + } + } + } + return ctx.Err() == nil +} diff --git a/internal/app/ocr_commands.go b/internal/app/ocr_commands.go new file mode 100644 index 0000000..d554cf6 --- /dev/null +++ b/internal/app/ocr_commands.go @@ -0,0 +1,227 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/ocr" +) + +func ocr_cursor_command(command input.Command) (ocr.Unit, int) { + switch command { + case input.OCRPreviousCharacter, input.ReviewPreviousCharacter: + return ocr.Character, -1 + case input.OCRNextCharacter, input.ReviewNextCharacter: + return ocr.Character, 1 + case input.ReviewCurrentCharacter, input.ReviewPhoneticCharacter: + return ocr.Character, 0 + case input.OCRPreviousWord, input.ReviewPreviousWord: + return ocr.WordUnit, -1 + case input.OCRNextWord, input.ReviewNextWord: + return ocr.WordUnit, 1 + case input.ReviewCurrentWord, input.ReviewSpellWord, input.ReviewPhoneticWord: + return ocr.WordUnit, 0 + case input.OCRPreviousLine, input.ReviewPreviousLine: + return ocr.LineUnit, -1 + case input.OCRNextLine, input.ReviewNextLine: + return ocr.LineUnit, 1 + case input.OCRPreviousPage: + return ocr.PageUnit, -1 + case input.OCRNextPage: + return ocr.PageUnit, 1 + case input.ReviewCurrentLine, input.ReviewSpellLine, input.ReviewPhoneticLine, input.WhereAmI: + return ocr.LineUnit, 0 + case input.OCRLineStart: + return ocr.LineStart, 0 + case input.OCRLineEnd, input.ReviewLineEnd: + return ocr.LineEnd, 0 + case input.OCRDocumentStart, input.ReviewWindowStart: + return ocr.DocumentStart, 0 + case input.OCRDocumentEnd, input.ReviewWindowEnd: + return ocr.DocumentEnd, 0 + } + return 0, 0 +} + +// Handle runs on the command consumer and never waits for native input changes. +func (session *ocrSession) Handle(event input.CommandEvent) bool { + if session == nil { + return false + } + session.mu.Lock() + defer session.mu.Unlock() + if kind, ok := ocr_source_command(event.Command); ok { + session.request_locked(kind, event.Timestamp) + return true + } + if session.activating { + return strings.HasPrefix(string(event.Command), "ocr-") + } + if session.cancel == nil { + return strings.HasPrefix(string(event.Command), "ocr-") + } + if !session.current_locked(session.job) { + session.retire_locked() + return strings.HasPrefix(string(event.Command), "ocr-") + } + if event.Timestamp != 0 && (session.cutoff == 0 || int32(event.Timestamp-session.cutoff) > 0) { + session.cutoff = event.Timestamp + } + if session.cursor != nil { + from, to := session.selection_locked() + session.logger.Debug("OCR review command", "command", event.Command, "generation", session.generation, + "focus_path", session.focus.Path, "source_path", session.source.Object.Path, + "offset", session.cursor.Offset(), "selection_start", from, "selection_end", to) + } + switch event.Command { + case input.OCRDismiss, input.OCRDismissAndPass: + session.retire_locked() + if event.Command == input.OCRDismiss { + session.status_locked("OCR dismissed") + } + return true + case input.OCRSelectAll: + if session.cursor == nil { + return true + } + session.selectionAnchor = 0 + position, _ := session.cursor.Set(session.cursor.Length()) + session.speech.Enqueue(speechRequest{Text: "OCR text selected", Role: "system", Cause: "ocr-selection", context: session.job.ctx}) + frame := session.frame_locked(position) + if session.display != nil { + session.display.EnqueueFrame(frame) + } + session.logger.Debug("OCR selection presentation", "command", event.Command, "offset", position.Offset, + "selection_start", 0, "selection_end", position.Offset, "speech_text", "OCR text selected", + "braille_text", frame.Text, "braille_cursor", frame.Cursor) + return true + case input.OCRCopySelection: + session.copy_selection_locked() + return true + case input.OCRActivate: + session.activate_locked() + return true + case input.OCRRefresh: + session.refresh_locked(false) + return true + case input.ReadAll: + session.read_all_locked(event.Timestamp) + return true + } + if unit, step := ocr_cursor_command(event.Command); unit != 0 { + if session.cursor == nil { + return true + } + moves := step != 0 || unit >= ocr.LineStart + oldStart, oldEnd := session.selection_locked() + if moves { + previous := session.cursor.Offset() + if event.Chord.Modifiers&1 != 0 { + if session.selectionAnchor < 0 { + session.selectionAnchor = previous + } + } else { + session.selectionAnchor = -1 + } + } + position := session.cursor.Move(unit, step) + if moves && event.Chord.Modifiers&1 != 0 { + if message := session.selection_change_locked(oldStart, oldEnd); message != "" { + session.present_request_locked(position, unit, speechRequest{Text: message, Role: "text", Cause: "ocr-selection", context: session.job.ctx}) + return true + } + } + if step != 0 && !position.Moved { + session.present_request_locked(position, unit, speechRequest{Text: "OCR text boundary", Role: "system", Cause: "ocr-status", context: session.job.ctx}) + return true + } + session.present_spelling_locked(position, unit, flat_review_speech(event.Command)) + return true + } + // Ordinary reader commands restore their existing source/routing first. + session.retire_locked() + return false +} + +// Input sees XRecord observations independently of grabbed command dispatch. +// Match complete chords, and protect delayed initiating observations by X time. +// Every unclaimed press retires the session immediately, including Alt+Tab. +func (session *ocrSession) Input(event input.Event) { + if session == nil { + return + } + session.mu.Lock() + defer session.mu.Unlock() + if session.activating { + return + } + if event.Pressed { + session.held[event.Name] = true + } else { + delete(session.held, event.Name) + return + } + if session.cancel == nil { + return + } + session.logger.Debug("OCR observed input", "key", event.Name, "timestamp", event.Timestamp, "cutoff", session.cutoff) + if event.Timestamp != 0 && session.cutoff != 0 && int32(event.Timestamp-session.cutoff) <= 0 { + return + } + settings := session.settings() + symbolName := event.Name + // XRecord uses Xlib's keypad names; shortcut labels use the page names. + switch symbolName { + case "KP_Next": + symbolName = "KP_Page_Down" + case "KP_Prior": + symbolName = "KP_Page_Up" + } + chord, err := input.ParseCommandChord(symbolName) + for name := range session.held { + switch name { + case "Shift_L", "Shift_R": + chord.Modifiers |= 1 + case "Control_L", "Control_R": + chord.Modifiers |= 4 + case "Alt_L", "Alt_R", "Meta_L", "Meta_R", "Super_L", "Super_R": + session.retire_locked() + return + } + for _, modifier := range settings.CthulhuModifierKeys { + if modifier == name { + chord.CthulhuModifier = true + } + } + } + if event.Kind == input.KeyModifier { + return + } + for _, modifier := range settings.CthulhuModifierKeys { + if modifier == event.Name { + return + } + } + if err != nil { + session.retire_locked() + return + } + bindings, err := input.ResolveCommandBindings(input.KeyboardLayout(settings.KeyboardLayout), false, settings.KeyBindings) + if err != nil { + session.retire_locked() + return + } + if session.cursor == nil { + bindings = input.OCRPendingBindings(bindings) + } else { + bindings = input.OCRCommandBindings(bindings) + } + if bindings[chord] == "" { + session.logger.Debug("OCR dismissed by unclaimed input", "chord", input.FormatCommandChord(chord)) + session.retire_locked() + } +} diff --git a/internal/app/ocr_copy.go b/internal/app/ocr_copy.go new file mode 100644 index 0000000..321d30d --- /dev/null +++ b/internal/app/ocr_copy.go @@ -0,0 +1,86 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "os/exec" + "strings" + "time" +) + +type ocrTextCopier interface { + Copy(context.Context, string) error +} + +// xclip becomes the X11 selection owner after its short-lived parent exits. +// It releases ownership when another application replaces the clipboard. +type xclipOCRCopier struct{} + +func (xclipOCRCopier) Copy(ctx context.Context, value string) error { + if value == "" { + return errors.New("empty OCR selection") + } + ctx, cancel := context.WithTimeout(ctx, 2*time.Second) + defer cancel() + command := exec.CommandContext(ctx, "xclip", "-selection", "clipboard", "-in") + command.Stdin = strings.NewReader(value) + return command.Run() +} + +type ocrCopyRequest struct { + ctx context.Context + generation uint64 + text string + automatic bool +} + +func (session *ocrSession) copy_selection_locked() { + if session.cursor == nil || session.selectionAnchor < 0 || session.selectionAnchor == session.cursor.Offset() { + session.status_locked("No OCR text selected") + return + } + start, end := min(session.selectionAnchor, session.cursor.Offset()), max(session.selectionAnchor, session.cursor.Offset()) + value, ok := session.cursor.Slice(start, end) + if !ok || value == "" || session.copier == nil || session.copyRequests == nil { + session.status_locked("OCR copy unavailable") + return + } + request := ocrCopyRequest{ctx: session.job.ctx, generation: session.generation, text: value} + select { + case session.copyRequests <- request: + default: + // Keep the newest explicit copy request without blocking the input loop. + select { + case <-session.copyRequests: + default: + } + session.copyRequests <- request + } +} + +func (session *ocrSession) copy(request ocrCopyRequest) { + if request.ctx.Err() != nil { + return + } + err := session.copier.Copy(request.ctx, request.text) + session.mu.Lock() + defer session.mu.Unlock() + if request.ctx.Err() != nil || request.generation != session.generation || !session.current_locked(session.job) { + return + } + // A successful optional copy must not cancel initial Say All or replace its + // routable braille frame. Explicit copies retain their normal confirmation. + if request.automatic && err == nil && session.job.autoReadAll { + return + } + message := "OCR text copied to clipboard" + if err != nil { + message = "OCR copy unavailable" + session.logger.Debug("OCR copy failed", "error", err) + } + session.status_locked(message) +} diff --git a/internal/app/ocr_copy_test.go b/internal/app/ocr_copy_test.go new file mode 100644 index 0000000..a307304 --- /dev/null +++ b/internal/app/ocr_copy_test.go @@ -0,0 +1,28 @@ +package app + +import ( + "context" + "os" + "os/exec" + "testing" + "time" +) + +func TestNativeOCRClipboardCopy(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_OCR_COPY") != "1" { + t.Skip("requires a private X11 display and xclip") + } + ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second) + defer cancel() + want := "é猫 OCR\nsecond line" + if err := (xclipOCRCopier{}).Copy(ctx, want); err != nil { + t.Fatal(err) + } + got, err := exec.CommandContext(ctx, "xclip", "-selection", "clipboard", "-out").Output() + if err != nil { + t.Fatal(err) + } + if string(got) != want { + t.Fatalf("clipboard = %q, want %q", got, want) + } +} diff --git a/internal/app/ocr_native_test.go b/internal/app/ocr_native_test.go new file mode 100644 index 0000000..f2cae35 --- /dev/null +++ b/internal/app/ocr_native_test.go @@ -0,0 +1,276 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "context" + "encoding/json" + "log/slog" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/ocr" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// This joins the actual reader loops, AT-SPI/review, XRecord, native grabs, +// capture helper and installed engine, with recording output sinks. It does +// not run an installed reader or establish audible/physical braille acceptance. +func TestNativeOCRSession(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_OCR_SESSION") != "1" { + t.Skip("requires private Xorg/AT-SPI session and installed Tesseract") + } + executable := os.Getenv("CTHULHU_OCR_CAPTURE_BINARY") + if executable == "" { + t.Fatal("set CTHULHU_OCR_CAPTURE_BINARY to the temporary reader binary") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + logger := slog.New(slog.DiscardHandler) + adapter := atspi.New() + keys := xorg.NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + settings := config.DefaultSettings() + settings.EnableKeyEcho = false + settings.KeyBindings = []input.BindingOverride{{Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.OCRClipboard, Keys: []string{"Cthulhu+F8"}}} + if err := keys.SetKeyBindings(ctx, settings.KeyBindings); err != nil { + t.Fatal(err) + } + listener := xorg.New() + objectReview, err := review.NewWorker(adapter, time.Second) + if err != nil { + t.Fatal(err) + } + output := &ocrTestOutput{speech: make(chan speechRequest, 256), frames: make(chan braille.Frame, 256)} + gate := newFocusGate(keys) + live := &liveSettings{} + live.Store(settings) + session := new_ocr_session(logger, keys, adapter, objectReview, output, nil, output, gate, live) + session.capture = ocr.NewCapturer(executable) + gate.ocr = session + for _, service := range []interface { + Start(context.Context) error + Stop(context.Context) error + }{keys, adapter, objectReview, listener, session} { + if err := service.Start(ctx); err != nil { + t.Fatal(err) + } + defer service.Stop(context.Background()) + } + commandDone := make(chan error, 1) + eventDone := make(chan error, 1) + inputDone := make(chan struct{}) + go func() { + commandDone <- (commandRuntime{logger: logger, commands: keys, focusGate: gate, speechOutput: output, objectReview: objectReview, ocr: session, stopRun: cancel}).run(ctx) + }() + go func() { + eventDone <- processEventsWithOCR(ctx, logger, outputQueue{speech: output, braille: output, live: live}, adapter, nil, objectReview, time.Millisecond, live, listener, gate, nil, session) + }() + go func() { + defer close(inputDone) + processInputEvents(ctx, logger, output, listener, inputEchoSettingsFromConfig(settings), live, keys, session) + }() + defer func() { + cancel() + if err := <-commandDone; err != nil { + t.Error(err) + } + if err := <-eventDone; err != nil { + t.Error(err) + } + <-inputDone + }() + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-u", "../../tests/ocr_session_fixture.py") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err = fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + read := func() map[string]uint64 { + t.Helper() + if !scanner.Scan() { + t.Fatal("OCR fixture did not respond") + } + var state map[string]uint64 + if err := json.Unmarshal(scanner.Bytes(), &state); err != nil { + t.Fatal(err) + } + return state + } + read() + action := func(name string) map[string]uint64 { + t.Helper() + data, _ := json.Marshal(map[string]string{"action": name}) + if _, err := stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + state := read() + if state["focus"] != state["window"] { + t.Fatalf("OCR changed native window focus: %+v", state) + } + return state + } + key := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("key: %v %s", err, out) + } + } + defer exec.Command("xdotool", "keyup", "Insert", "Control_L", "Shift_L", "o", "Escape").Run() + wait := func(predicate func() bool) { + t.Helper() + for !predicate() { + select { + case err := <-session.failures: + t.Fatal(err) + case err := <-keys.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + } + focus := func(actionName string) { + session.mu.Lock() + previous := session.focus + session.mu.Unlock() + action(actionName) + wait(func() bool { + session.mu.Lock() + defer session.mu.Unlock() + return session.focus.Valid() && session.focus != previous + }) + } + // Observe actual focused-widget speech, not merely a valid frame identity. + for { + got := ocr_test_receive(t, output.speech) + if strings.Contains(got.Text, "Painted OCR target") { + break + } + } + wait(func() bool { + session.mu.Lock() + defer session.mu.Unlock() + return session.focus.Valid() + }) + expect := func(want string) { + t.Helper() + for { + select { + case got := <-output.speech: + t.Logf("output %s: %q", got.Cause, got.Text) + if got.Cause == "ocr-status" || got.Cause == "ocr-cursor" || got.Cause == "ocr-selection" { + if got.Text != want { + t.Fatalf("OCR speech: %+v want %q", got, want) + } + return + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + frame := func(text string, cursor int) { + t.Helper() + for { + select { + case got := <-output.frames: + if got.Text == text { + if got.Cursor != cursor || len(got.Routes) != 0 { + t.Fatalf("OCR braille: %+v", got) + } + return + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + key("Insert+o") + expect("OCR test window") + frame("OCR test window", 0) + wait(keys.OCRReviewEnabled) + key("shift+Right") + expect("O selected") + frame("OCR test window", 1) + key("shift+Left") + expect("O unselected") + frame("OCR test window", 0) + key("ctrl+Right") + expect("test") + frame("OCR test window", 4) + key("Down") + expect("Open Settings") + frame("Open Settings", 4) + action("state") + key("Escape") + expect("OCR dismissed") + wait(func() bool { return !keys.OCRReviewEnabled() }) + key("Insert+F8") + expect("OCR test window") + frame("OCR test window", 0) + action("clipboard-text") + key("Down") + expect("Open Settings") + key("ctrl+a") + expect("OCR text selected") + key("ctrl+c") + expect("OCR text copied to clipboard") + session.mu.Lock() + wantCopy, _ := session.cursor.Slice(0, session.cursor.Length()) + session.mu.Unlock() + copyResult, err := exec.CommandContext(ctx, "xclip", "-selection", "clipboard", "-out").Output() + if err != nil || string(copyResult) != wantCopy { + t.Fatalf("OCR clipboard copy = %q, want %q: %v", copyResult, wantCopy, err) + } + // Native focus changes within the same X11 window dismiss a ready result. + action("other") + wait(func() bool { return !keys.OCRReviewEnabled() }) + focus("password") + key("Insert+o") + expect("OCR test window") + key("Escape") + expect("OCR dismissed") + focus("painted") + key("Insert+o") + expect("OCR test window") + key("h") + wait(func() bool { return !keys.OCRReviewEnabled() }) + // No accessibility provider exists for this client. The default command, + // review, refresh and dismissal must work using only X11 ownership/pixels. + inaccessible := action("inaccessible") + wait(func() bool { return adapter.Foreground().Client.Window == inaccessible["window"] }) + key("Insert+o") + expect("OCR test window") + frame("OCR test window", 0) + wait(keys.OCRReviewEnabled) + key("Down") + expect("Open Settings") + frame("Open Settings", 0) + key("Insert+F5") + expect("OCR text unchanged") + action("state") + key("Escape") + expect("OCR dismissed") + wait(func() bool { return !keys.OCRReviewEnabled() }) +} diff --git a/internal/app/ocr_read_all.go b/internal/app/ocr_read_all.go new file mode 100644 index 0000000..676c433 --- /dev/null +++ b/internal/app/ocr_read_all.go @@ -0,0 +1,48 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +// read_all_locked starts ordinary paced speech from the current virtual +// offset. Progress moves only OCR's cursor and braille; native focus is intact. +func (session *ocrSession) read_all_locked(timestamp uint32) { + if session.cursor == nil || session.readAll == nil { + session.status_locked("OCR Say All is unavailable") + return + } + lines := session.cursor.LinesFrom() + if len(lines) == 0 { + session.status_locked("OCR text boundary") + return + } + job := session.job + session.selectionAnchor = -1 + ctx := session.readAll.BeginReadAll(job.ctx, timestamp) + session.readAllContext = ctx + session.readAllDone = make(chan error, 1) + parts := make([]readAllPart, 0, len(lines)) + for _, line := range lines { + offset := line.Offset + parts = append(parts, readAllPart{Text: line.Text, Began: func() { + session.mu.Lock() + defer session.mu.Unlock() + if ctx.Err() != nil || !session.current_locked(job) || session.cursor == nil { + return + } + position, ok := session.cursor.Set(offset) + if !ok { + return + } + frame := session.frame_locked(position) + if session.display != nil { + session.display.EnqueueFrame(frame) + } + session.logger.Debug("OCR Say All progress", "command", "read-all", "generation", job.generation, + "focus_path", session.focus.Path, "source_path", session.source.Object.Path, "offset", position.Offset, + "selection_start", -1, "selection_end", -1, "speech_text", line.Text, + "braille_text", frame.Text, "braille_cursor", frame.Cursor) + }}) + } + session.speech.Enqueue(speechRequest{ReadAll: parts, Role: "text", Cause: "read-all", context: ctx, result: session.readAllDone}) +} diff --git a/internal/app/ocr_reading_test.go b/internal/app/ocr_reading_test.go new file mode 100644 index 0000000..1e6963c --- /dev/null +++ b/internal/app/ocr_reading_test.go @@ -0,0 +1,162 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "testing" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/ocr" +) + +func TestOCRAutomaticReadAllOnceWithCopyAndRefresh(t *testing.T) { + session, _, _, engine, output := ocr_test_session(t) + reader := &ocrTestReadAll{} + copier := &ocrTestCopier{copied: make(chan string, 1)} + session.readAll, session.copier = reader, copier + settings := session.settings() + settings.OCR.AutoReadAll, settings.OCR.CopyFirstResult = true, true + session.live = &liveSettings{} + session.live.Store(settings) + session.Handle(input.CommandEvent{Command: input.OCRWindow, Timestamp: 100}) + ocr_test_receive(t, engine.calls) + // A pending job must keep the initiating preferences. + settings.OCR.AutoReadAll, settings.OCR.CopyFirstResult = false, false + session.live.Store(settings) + engine.results <- ocr.Result{Text: "é one\n猫 two"} + request := ocr_test_receive(t, output.speech) + if request.Cause != "read-all" || len(request.ReadAll) != 2 || request.ReadAll[0].Text != "é one" || reader.timestamp != 100 { + t.Fatalf("initial reading: %+v", request) + } + frame := ocr_test_receive(t, output.frames) + if frame.Text != "é one" || frame.Cursor != 0 || frame.Virtual == nil { + t.Fatalf("initial braille: %+v", frame) + } + if text := ocr_test_receive(t, copier.copied); text != "é one\n猫 two" { + t.Fatal(text) + } + request.ReadAll[1].Began() + frame = ocr_test_receive(t, output.frames) + if frame.Text != "猫 two" || frame.Virtual.SourceStart != 6 { + t.Fatalf("paced braille: %+v", frame) + } + session.Handle(input.CommandEvent{Command: input.OCRRefresh, Timestamp: 101}) + ocr_test_receive(t, engine.calls) // Worker has also finished the optional copy. + if request.context.Err() != context.Canceled { + t.Fatal("manual refresh did not cancel old reading") + } + engine.results <- ocr.Result{Text: "é one\n猫 two"} + if got := ocr_test_receive(t, output.speech); got.Text != "OCR text unchanged" || len(got.ReadAll) != 0 { + t.Fatalf("copy interrupted reading or refresh restarted it: %+v", got) + } + ocr_test_receive(t, output.frames) // Status, then current review frame. + ocr_test_receive(t, output.frames) + request.ReadAll[0].Began() + select { + case got := <-output.frames: + t.Fatalf("stale reading moved refreshed braille: %+v", got) + default: + } +} + +func TestOCRPeriodicRefreshWaitsForSayAll(t *testing.T) { + for _, interrupted := range []bool{false, true} { + t.Run(map[bool]string{false: "completed", true: "interrupted"}[interrupted], func(t *testing.T) { + session, _, _, engine, output := ocr_test_session(t) + session.readAll = &ocrTestReadAll{} + settings := session.settings() + settings.OCR.AutoReadAll = true + session.live = &liveSettings{} + session.live.Store(settings) + session.Handle(input.CommandEvent{Command: input.OCRWindow}) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "first\nsecond"} + request := ocr_test_receive(t, output.speech) + ocr_test_receive(t, output.frames) + settings.OCR.AutoRefresh = true + session.live.Store(settings) + session.mu.Lock() + session.refresh_locked(true) + if session.refreshing || request.context.Err() != nil { + session.mu.Unlock() + t.Fatal("periodic refresh truncated Say All") + } + if interrupted { + ctx, cancel := context.WithCancel(session.job.ctx) + session.readAllContext = ctx + cancel() + } else { + completeSpeechRequest(request, nil) + } + session.refresh_locked(true) + if !session.refreshing { + session.mu.Unlock() + t.Fatal("periodic refresh did not resume after reading") + } + session.mu.Unlock() + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "changed"} + if got := ocr_test_receive(t, output.speech); got.Text != "changed" || len(got.ReadAll) != 0 { + t.Fatalf("automatic refresh restarted Say All: %+v", got) + } + }) + } +} + +func TestOCRShiftSelectionAnnouncesChangedRanges(t *testing.T) { + session, _, _, engine, output := ocr_test_session(t) + session.Handle(input.CommandEvent{Command: input.OCRWindow}) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "é猫abc\nnext"} + ocr_test_receive(t, output.speech) + ocr_test_receive(t, output.frames) + steps := []struct { + command input.Command + shift bool + speech string + offset, start, end int + }{ + {input.OCRNextCharacter, true, "é selected", 1, 0, 1}, + {input.OCRNextCharacter, true, "猫 selected", 2, 0, 2}, + {input.OCRPreviousCharacter, true, "猫 unselected", 1, 0, 1}, + {input.OCRPreviousCharacter, true, "é unselected", 0, 0, 0}, + {input.OCRPreviousCharacter, true, "OCR text boundary", 0, 0, 0}, + {input.OCRNextCharacter, false, "猫", 1, -1, -1}, + {input.OCRNextCharacter, true, "猫 selected", 2, 1, 2}, + {input.OCRLineStart, true, "猫 unselected, é selected", 0, 0, 1}, + {input.OCRLineEnd, true, "é unselected, 猫abc selected", 5, 1, 5}, + {input.OCRNextCharacter, true, "selected", 6, 1, 6}, + {input.OCRDocumentEnd, true, "next selected", 10, 1, 10}, + {input.OCRNextCharacter, false, "OCR text boundary", 10, -1, -1}, + } + for _, step := range steps { + modifiers := uint16(0) + if step.shift { + modifiers = 1 + } + session.Handle(input.CommandEvent{Command: step.command, Chord: input.CommandChord{Modifiers: modifiers}}) + if got := ocr_test_receive(t, output.speech); got.Text != step.speech { + t.Fatalf("%s shift=%v: %q, want %q", step.command, step.shift, got.Text, step.speech) + } + frame := ocr_test_receive(t, output.frames) + session.mu.Lock() + start, end := session.selection_locked() + offset := session.cursor.Offset() + session.mu.Unlock() + if offset != step.offset || start != step.start || end != step.end || frame.Virtual == nil { + t.Fatalf("%s: offset=%d selection=%d:%d frame=%+v", step.command, offset, start, end, frame) + } + for index, dots := range frame.Dots { + source := frame.Virtual.SourceStart + index + if (dots != 0) != (source >= start && source < end) { + t.Fatalf("wrong selection dots: %+v", frame) + } + } + if start == end && len(frame.Dots) != 0 { + t.Fatalf("cleared selection retained dots: %+v", frame) + } + } +} diff --git a/internal/app/ocr_refresh.go b/internal/app/ocr_refresh.go new file mode 100644 index 0000000..ab29e2f --- /dev/null +++ b/internal/app/ocr_refresh.go @@ -0,0 +1,89 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/ocr" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// Retain an unchanged prefix or suffix exactly. A changed middle keeps the +// nearest legal offset; identical repeated text is deliberately not guessed. +func remapOCROffset(oldText, newText string, offset int) int { + oldRunes, newRunes := []rune(oldText), []rune(newText) + offset = max(0, min(offset, len(oldRunes))) + prefix := 0 + for prefix < len(oldRunes) && prefix < len(newRunes) && oldRunes[prefix] == newRunes[prefix] { + prefix++ + } + if offset < prefix { + return offset + } + suffix := 0 + for suffix < len(oldRunes)-prefix && suffix < len(newRunes)-prefix && + oldRunes[len(oldRunes)-1-suffix] == newRunes[len(newRunes)-1-suffix] { + suffix++ + } + if offset >= len(oldRunes)-suffix { + return len(newRunes) - (len(oldRunes) - offset) + } + return min(offset, len(newRunes)) +} + +func (session *ocrSession) finish_refresh_locked(job ocrJob, interest review.Interest, capture ocr.Capture, result ocr.Result, err error) { + session.refreshing = false + if err != nil { + session.refreshFailed = true + session.status_locked("OCR refresh failed; activate after a successful refresh") + return + } + previous := session.cursor.Text() + offset := remapOCROffset(previous, result.Text, session.cursor.Offset()) + anchor := -1 + if session.selectionAnchor >= 0 { + anchor = remapOCROffset(previous, result.Text, session.selectionAnchor) + } + session.source, session.pixels = interest, capture + session.cursor = ocr.NewCursor(result) + position, _ := session.cursor.Set(offset) + session.selectionAnchor = anchor + session.refreshFailed = result.Text == "" + if result.Text == "" { + session.status_locked("No text recognized") + } else if result.Text != previous { + session.status_locked(ocrChangedAnnouncement(previous, result.Text)) + } else if !job.automatic { + session.status_locked("OCR text unchanged") + } + if session.display != nil { + session.display.EnqueueFrame(session.frame_locked(position)) + } + session.schedule_refresh_locked() +} + +func ocrChangedAnnouncement(previous, current string) string { + oldRunes, newRunes := []rune(previous), []rune(current) + index := 0 + for index < len(oldRunes) && index < len(newRunes) && oldRunes[index] == newRunes[index] { + index++ + } + if index == len(newRunes) && index < len(oldRunes) { + return "OCR text removed" + } + start, end := index, index + for start > 0 && newRunes[start-1] != '\n' { + start-- + } + for end < len(newRunes) && newRunes[end] != '\n' && end-start < 100 { + end++ + } + line := strings.TrimSpace(string(newRunes[start:end])) + if line == "" { + return "OCR text changed" + } + return line +} diff --git a/internal/app/ocr_refresh_activation_test.go b/internal/app/ocr_refresh_activation_test.go new file mode 100644 index 0000000..6299e7e --- /dev/null +++ b/internal/app/ocr_refresh_activation_test.go @@ -0,0 +1,193 @@ +package app + +import ( + "context" + "image" + "image/color" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/ocr" +) + +func TestOCRClipboardRefreshKeepsSnapshotAndCursor(t *testing.T) { + session, keys, capture, engine, output := ocr_test_session(t) + session.Handle(input.CommandEvent{Command: input.OCRClipboard, Timestamp: 100}) + ocr_test_receive(t, keys.calls) + ocr_test_receive(t, capture.calls) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "one two", Words: []ocr.Word{{Text: "one", Span: ocr.Span{Start: 0, End: 3}}, {Text: "two", Span: ocr.Span{Start: 4, End: 7}}}} + ocr_test_receive(t, keys.calls) + ocr_test_receive(t, output.speech) + ocr_test_receive(t, output.frames) + session.Handle(input.CommandEvent{Command: input.OCRNextWord, Timestamp: 101}) + ocr_test_receive(t, output.speech) + ocr_test_receive(t, output.frames) + session.Handle(input.CommandEvent{Command: input.OCRRefresh, Timestamp: 102}) + ocr_test_receive(t, engine.calls) + select { + case <-capture.calls: + t.Fatal("clipboard refresh fetched a changed clipboard") + default: + } + engine.results <- ocr.Result{Text: "one three", Words: []ocr.Word{{Text: "one", Span: ocr.Span{Start: 0, End: 3}}, {Text: "three", Span: ocr.Span{Start: 4, End: 9}}}} + if got := ocr_test_receive(t, output.speech); got.Text != "one three" { + t.Fatal(got) + } + session.mu.Lock() + defer session.mu.Unlock() + if session.cursor == nil || session.cursor.Offset() != 4 || session.cursor.Text() != "one three" || session.refreshFailed { + t.Fatal("refresh lost cursor or snapshot") + } +} + +func TestOCRRefreshRetainsUnchangedSuffixAcrossInsertion(t *testing.T) { + if got := remapOCROffset("é one", "new é one", 2); got != 6 { + t.Fatalf("cursor moved to inserted text: %d", got) + } + if got := remapOCROffset("é one", "é new one", 2); got != 6 { + t.Fatalf("cursor missed original suffix: %d", got) + } + if got := remapOCROffset("old text", "old", 8); got != 3 { + t.Fatalf("deleted suffix was not clamped: %d", got) + } +} + +func TestOCRStaleActivationCannotRetireReplacement(t *testing.T) { + session, keys, _, engine, _ := ocr_test_session(t) + defer func() { engine.results <- ocr.Result{}; engine.results <- ocr.Result{} }() + session.Handle(input.CommandEvent{Command: input.OCRWindow, Timestamp: 100}) + ocr_test_receive(t, keys.calls) + session.mu.Lock() + old := session.job + session.mu.Unlock() + session.Handle(input.CommandEvent{Command: input.OCRDesktop, Timestamp: 101}) + session.mu.Lock() + current := session.job.generation + session.mu.Unlock() + session.activate(ocrActivateRequest{job: old}) + session.mu.Lock() + defer session.mu.Unlock() + if session.cancel == nil || session.job.generation != current { + t.Fatal("late activation retired replacement job") + } +} + +func TestOCRAutoRefreshWaitsForEachJob(t *testing.T) { + session, keys, capture, engine, output := ocr_test_session(t) + live := &liveSettings{} + settings := config.DefaultSettings() + settings.OCR.AutoRefresh = true + settings.OCR.RefreshInterval = 500 + live.Store(settings) + session.live = live + session.Handle(input.CommandEvent{Command: input.OCRWindow, Timestamp: 100}) + ocr_test_receive(t, keys.calls) + ocr_test_receive(t, capture.calls) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "ready"} + ocr_test_receive(t, keys.calls) + ocr_test_receive(t, output.speech) + ocr_test_receive(t, output.frames) + ocr_test_receive(t, capture.calls) + ocr_test_receive(t, engine.calls) + select { + case <-capture.calls: + t.Fatal("automatic OCR jobs overlapped") + case <-time.After(600 * time.Millisecond): + } + engine.results <- ocr.Result{Text: "ready"} + ocr_test_receive(t, output.frames) + ocr_test_receive(t, capture.calls) + ocr_test_receive(t, engine.calls) +} + +type ocrTestClicker struct{ points chan image.Point } + +func (clicker *ocrTestClicker) ClickOCR(ctx context.Context, _ uint64, _ image.Rectangle, point image.Point) error { + clicker.points <- point + return ctx.Err() +} + +type ocrTestConfirmer struct { + answer bool + called chan string +} + +func (confirm *ocrTestConfirmer) Confirm(_ context.Context, word string) (bool, error) { + confirm.called <- word + return confirm.answer, nil +} + +func TestOCRActivationChecksFreshPixelsBeforeClick(t *testing.T) { + for _, test := range []struct { + name string + command input.Command + changed bool + }{ + {"object/unchanged", input.OCRObject, false}, + {"object/changed", input.OCRObject, true}, + {"inaccessible-window/unchanged", input.OCRWindow, false}, + {"inaccessible-window/changed", input.OCRWindow, true}, + } { + t.Run(test.name, func(t *testing.T) { + session, keys, capture, engine, output := ocr_test_session(t) + if test.command == input.OCRWindow { + session.focus, session.window = atspi.ObjectID{}, atspi.ObjectID{} + session.geometry, session.interest = nil, nil + } + clicker := &ocrTestClicker{points: make(chan image.Point, 1)} + confirmer := &ocrTestConfirmer{answer: true, called: make(chan string, 1)} + session.clicker, session.confirmer = clicker, confirmer + paint := color.RGBA{R: 20, A: 255} + capture.produce = func(ctx context.Context, request ocr.CaptureRequest) (ocr.Capture, error) { + pixels := image.NewRGBA(image.Rect(0, 0, 100, 50)) + for index := range pixels.Pix { + pixels.Pix[index] = 20 + } + pixels.SetRGBA(0, 0, paint) + bounds := image.Rect(10, 20, 110, 70) + return ocr.Capture{CaptureHeader: ocr.CaptureHeader{Request: request, RootBounds: image.Rect(0, 0, 200, 200), SourceBounds: bounds, ScreenBounds: bounds, SourceWindow: request.Foreground}, Pixels: pixels, + Transform: ocr.Transform{ImageContent: image.Rect(0, 0, 100, 50), ScreenBounds: bounds, HasScreenMapping: true}}, ctx.Err() + } + session.Handle(input.CommandEvent{Command: test.command, Timestamp: 100}) + ocr_test_receive(t, keys.calls) + ocr_test_receive(t, capture.calls) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "go", Width: 100, Height: 50, Words: []ocr.Word{{Text: "go", Bounds: image.Rect(10, 10, 30, 20), Span: ocr.Span{Start: 0, End: 2}}}} + ocr_test_receive(t, keys.calls) + ocr_test_receive(t, output.speech) + ocr_test_receive(t, output.frames) + if test.changed { + paint = color.RGBA{R: 30, A: 255} + } + session.Handle(input.CommandEvent{Command: input.OCRActivate, Timestamp: 101}) + if got := ocr_test_receive(t, confirmer.called); got != "go" { + t.Fatal(got) + } + ocr_test_receive(t, capture.calls) + if test.changed { + if got := ocr_test_receive(t, output.speech); got.Text != "OCR source changed; refresh before activation" { + t.Fatal(got) + } + select { + case <-clicker.points: + t.Fatal("clicked changed image") + default: + } + } else { + select { + case point := <-clicker.points: + if point != image.Pt(29, 34) { + t.Fatal(point) + } + case <-time.After(3 * time.Second): + t.Fatal("valid word was not clicked") + } + } + }) + } +} diff --git a/internal/app/ocr_selection.go b/internal/app/ocr_selection.go new file mode 100644 index 0000000..ce4d709 --- /dev/null +++ b/internal/app/ocr_selection.go @@ -0,0 +1,55 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "fmt" + "strings" +) + +// Selection is owned by the session's anchor and cursor. Compare ranges in the +// current document without retaining text or inventing a native object identity. +func (session *ocrSession) selection_change_locked(oldStart, oldEnd int) string { + start, end := session.selection_locked() + var changes []string + fragment := func(from, to int, selected bool) { + if from < 0 || to <= from { + return + } + message := "unselected" + if selected { + message = "selected" + } + if to-from <= lineSelectionFragmentLimit { + value, _ := session.cursor.Slice(from, to) + value = strings.Join(strings.Fields(value), " ") + if value != "" { + if selected { + message = fmt.Sprintf("%s selected", value) + } else { + message = fmt.Sprintf("%s unselected", value) + } + } + } + changes = append(changes, message) + } + if oldEnd > oldStart { + if end <= start { + fragment(oldStart, oldEnd, false) + } else { + fragment(oldStart, min(oldEnd, start), false) + fragment(max(oldStart, end), oldEnd, false) + } + } + if end > start { + if oldEnd <= oldStart { + fragment(start, end, true) + } else { + fragment(start, min(end, oldStart), true) + fragment(max(start, oldEnd), end, true) + } + } + return strings.Join(changes, ", ") +} diff --git a/internal/app/ocr_session.go b/internal/app/ocr_session.go new file mode 100644 index 0000000..eb577ec --- /dev/null +++ b/internal/app/ocr_session.go @@ -0,0 +1,690 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "image" + "log/slog" + "os" + "sync" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/ocr" + "git.stormux.org/storm/cthulhu/internal/review" +) + +type ocrKeyOwner interface { + SetOCRReview(context.Context, bool) error + SetOCRContext(context.Context, uint64, bool) error +} +type ocrClicker interface { + ClickOCR(context.Context, uint64, image.Rectangle, image.Point) error +} +type ocrConfirmer interface { + Confirm(context.Context, string) (bool, error) +} +type ocrGeometrySource interface { + CaptureOCRGeometry(context.Context, atspi.ObjectID, *atspi.Rectangle) (atspi.OCRGeometry, error) +} +type ocrInterestSource interface { + ObjectOfInterest(context.Context) (review.Interest, error) +} +type ocrCaptureSource interface { + Capture(context.Context, ocr.CaptureRequest) (ocr.Capture, error) +} +type ocrRecognizer interface { + Recognize(context.Context, image.Image, ocr.Options) (ocr.Result, error) +} +type ocrReadAllStarter interface { + BeginReadAll(context.Context, uint32) context.Context +} + +type ocrJob struct { + window atspi.ObjectID + ctx context.Context + generation uint64 + focus atspi.ObjectID + foreground atspi.ForegroundState + kind ocr.SourceKind + options ocr.Options + source review.Interest + snapshot ocr.Capture + refresh bool + automatic bool + autoReadAll bool + copyFirstResult bool + timestamp uint32 +} + +// ocrSession owns source/job/result generations and the virtual cursor under mu. +// A single worker serializes capture, recognition and acknowledged input changes. +// Retirement cancels synchronously; the worker joins children and releases native +// input before admitting the next job. No native work runs on an input/event loop. +type ocrSession struct { + window atspi.ObjectID + mu sync.Mutex + logger *slog.Logger + keys ocrKeyOwner + geometry ocrGeometrySource + interest ocrInterestSource + foreground foregroundMonitor + capture ocrCaptureSource + engine ocrRecognizer + copier ocrTextCopier + copyRequests chan ocrCopyRequest + activateRequests chan ocrActivateRequest + clicker ocrClicker + confirmer ocrConfirmer + speech speechEnqueuer + readAll ocrReadAllStarter + readAllContext context.Context // Current speech request; cleared on retirement/refresh. + readAllDone chan error + display brailleFrameEnqueuer + gate *focusGate + live *liveSettings + ctx context.Context + stop context.CancelFunc + done chan struct{} + wake chan struct{} + failures chan error + focus atspi.ObjectID + focusForeground uint64 + job ocrJob + cancel context.CancelFunc + generation uint64 + cursor *ocr.Cursor + selectionAnchor int // -1 means no active virtual selection. + source review.Interest + pixels ocr.Capture + held map[string]bool + cutoff uint32 + refreshing bool + refreshFailed bool + autoTimer *time.Timer + activating bool + activationInterrupted bool +} + +func new_ocr_session(logger *slog.Logger, commands commandListener, adapter Adapter, interest *review.Worker, speech speechEnqueuer, readAll ocrReadAllStarter, display brailleFrameEnqueuer, gate *focusGate, live *liveSettings) *ocrSession { + executable, _ := os.Executable() + session := &ocrSession{logger: logger, interest: interest, speech: gatedSpeech{speech: speech, gate: gate}, readAll: readAll, display: display, gate: gate, live: live, + capture: ocr.NewCapturer(executable), engine: ocr.NewEngine(), copier: xclipOCRCopier{}, copyRequests: make(chan ocrCopyRequest, 1), + activateRequests: make(chan ocrActivateRequest, 1), confirmer: ocrDialogConfirmer{executable: executable}, + wake: make(chan struct{}, 1), failures: make(chan error, 1), held: make(map[string]bool), selectionAnchor: -1} + session.keys, _ = commands.(ocrKeyOwner) + session.clicker, _ = commands.(ocrClicker) + session.geometry, _ = adapter.(ocrGeometrySource) + session.foreground, _ = adapter.(foregroundMonitor) + return session +} + +func (session *ocrSession) Start(ctx context.Context) error { + session.mu.Lock() + session.ctx, session.stop = context.WithCancel(ctx) + session.done = make(chan struct{}) + session.mu.Unlock() + go session.run() + return nil +} + +func (session *ocrSession) Stop(ctx context.Context) error { + session.Retire() + session.mu.Lock() + stop, done := session.stop, session.done + session.mu.Unlock() + if stop == nil { + return nil + } + stop() + select { + case <-done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (session *ocrSession) signal() { + select { + case session.wake <- struct{}{}: + default: + } +} + +func (session *ocrSession) retire_locked() { + if session.autoTimer != nil { + session.autoTimer.Stop() + session.autoTimer = nil + } + if session.cancel == nil { + return + } + session.logger.Debug("OCR session retired", "generation", session.generation) + session.cancel() + session.cancel = nil + session.generation++ + session.cursor = nil + session.selectionAnchor = -1 + session.source = review.Interest{} + session.pixels = ocr.Capture{} + session.refreshing = false + session.refreshFailed = false + session.readAllContext, session.readAllDone = nil, nil + session.activating = false + session.activationInterrupted = false + if session.display != nil { + session.display.EnqueueFrame(braille.Frame{Cursor: -1}) + } + session.signal() +} + +func (session *ocrSession) Retire() { + if session == nil { + return + } + session.mu.Lock() + defer session.mu.Unlock() + session.retire_locked() +} + +func (session *ocrSession) Secure() { + if session == nil { + return + } + session.mu.Lock() + defer session.mu.Unlock() + session.retire_locked() + session.focus, session.window = atspi.ObjectID{}, atspi.ObjectID{} + session.focusForeground = 0 + clear(session.held) +} + +func ocr_source_command(command input.Command) (ocr.SourceKind, bool) { + switch command { + case input.OCRObject: + return ocr.ObjectSource, true + case input.OCRWindow: + return ocr.WindowSource, true + case input.OCRDesktop: + return ocr.DesktopSource, true + case input.OCRClipboard: + return ocr.ClipboardSource, true + } + return "", false +} + +func (session *ocrSession) request_locked(kind ocr.SourceKind, timestamp uint32) { + session.retire_locked() + session.cutoff = timestamp + if session.ctx == nil || session.ctx.Err() != nil { + return + } + if session.gate.Locked() || session.gate.Suspended() { + return + } + if session.keys == nil || session.foreground == nil { + session.status_locked("OCR source unavailable") + return + } + foreground := session.foreground.Foreground() + if !foreground.Client.Known || foreground.Client.Window == 0 { + session.status_locked("OCR source unavailable") + return + } + // An inaccessible client may leave the previous application's AT-SPI focus + // behind. It must not supply object geometry or invalidate this client's job. + if session.focusForeground != foreground.Client.Window { + session.focus, session.window = atspi.ObjectID{}, atspi.ObjectID{} + } + if kind == ocr.ObjectSource && (session.geometry == nil || session.interest == nil || !session.focus.Valid()) { + session.status_locked("OCR source unavailable") + return + } + session.generation++ + ctx, cancel := context.WithCancel(session.ctx) + session.cancel = cancel + settings := session.settings().OCR + session.job = ocrJob{ctx: ctx, generation: session.generation, window: session.window, focus: session.focus, foreground: foreground, kind: kind, + autoReadAll: settings.AutoReadAll, copyFirstResult: settings.CopyFirstResult, timestamp: timestamp, + options: ocr.Options{Language: settings.Language, Layout: ocr.Layout(settings.Layout), Scale: settings.Scale, Grayscale: settings.Grayscale, Invert: settings.Invert, BlackWhite: settings.BlackWhite, Threshold: settings.Threshold}} + session.signal() +} + +func (session *ocrSession) refresh_locked(automatic bool) { + if session.cancel == nil || session.cursor == nil || session.refreshing || !session.current_locked(session.job) { + return + } + if automatic && (session.job.kind == ocr.ClipboardSource || !session.settings().OCR.AutoRefresh) { + return + } + // Keep a periodic capture from truncating paced reading. Completion and + // interruption are observed without waiting on the speech worker. + if automatic && session.readAllContext != nil && session.readAllContext.Err() == nil { + select { + case <-session.readAllDone: + default: + session.schedule_refresh_locked() + return + } + } + session.readAllContext, session.readAllDone = nil, nil + if session.autoTimer != nil { + session.autoTimer.Stop() + session.autoTimer = nil + } + session.cancel() + session.generation++ + ctx, cancel := context.WithCancel(session.ctx) + session.cancel = cancel + old := session.job + settings := session.settings().OCR + session.job = ocrJob{ctx: ctx, generation: session.generation, window: old.window, focus: old.focus, + foreground: old.foreground, kind: old.kind, source: session.source, snapshot: session.pixels, + refresh: true, automatic: automatic, + options: ocr.Options{Language: settings.Language, Layout: ocr.Layout(settings.Layout), Scale: settings.Scale, Grayscale: settings.Grayscale, Invert: settings.Invert, BlackWhite: settings.BlackWhite, Threshold: settings.Threshold}} + session.refreshing = true + session.refreshFailed = true + session.signal() +} + +func (session *ocrSession) schedule_refresh_locked() { + if session.autoTimer != nil { + session.autoTimer.Stop() + session.autoTimer = nil + } + settings := session.settings().OCR + if settings.AutoRefresh && session.cursor != nil && session.job.kind != ocr.ClipboardSource && !session.refreshFailed { + session.autoTimer = time.NewTimer(time.Duration(settings.RefreshInterval) * time.Millisecond) + } +} + +func (session *ocrSession) timer_channel() <-chan time.Time { + session.mu.Lock() + defer session.mu.Unlock() + if session.autoTimer != nil { + return session.autoTimer.C + } + return nil +} + +func (session *ocrSession) run() { + defer close(session.done) + for { + select { + case <-session.ctx.Done(): + session.Retire() + session.release_input() + return + case <-session.wake: + session.mu.Lock() + job, active, ready := session.job, session.cancel != nil, session.cursor != nil && !session.refreshing + session.mu.Unlock() + if !active { + session.release_input() + continue + } + if !ready { + session.recognize(job) + } + case request := <-session.copyRequests: + session.copy(request) + case request := <-session.activateRequests: + session.activate(request) + case <-session.timer_channel(): + session.mu.Lock() + session.autoTimer = nil + session.refresh_locked(true) + session.mu.Unlock() + } + } +} + +func (session *ocrSession) release_input() { + if session.keys == nil { + return + } + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + defer cancel() + if err := session.keys.SetOCRReview(ctx, false); err != nil && session.ctx.Err() == nil { + if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) { + // A physical key may still be held. Retry after the chord releases; + // waiting for that release is not a failed native grab transaction. + session.signal() + return + } + // Failed release must stop the reader rather than leave swallowed keys. + select { + case session.failures <- err: + default: + } + } +} + +func (session *ocrSession) current_locked(job ocrJob) bool { + return session.cancel != nil && session.generation == job.generation && job.ctx.Err() == nil && + !session.gate.Locked() && !session.gate.Suspended() && session.focus == job.focus && + session.foreground.Foreground() == job.foreground +} + +func (session *ocrSession) recognize(job ocrJob) { + var err error + if !job.refresh { + err = session.keys.SetOCRContext(job.ctx, job.foreground.Client.Window, true) + } + interest := job.source + var capture ocr.Capture + var result ocr.Result + // Only object capture needs AT-SPI geometry. Window, desktop and clipboard + // jobs belong to the X11 foreground even when it has no accessible objects. + request := ocr.CaptureRequest{Kind: job.kind, Foreground: job.foreground.Client.Window, Generation: job.generation} + if err == nil && job.kind == ocr.ObjectSource { + if !job.refresh { + interest, err = session.interest.ObjectOfInterest(job.ctx) + } + if err == nil { + var zone *atspi.Rectangle + if interest.HasZone { + zone = &interest.Zone + } + var geometry atspi.OCRGeometry + geometry, err = session.geometry.CaptureOCRGeometry(job.ctx, interest.Object, zone) + if err == nil && geometry.Foreground != job.foreground { + err = ocr.ErrSourceChanged + } + request.Bounds = geometry.ScreenBounds + if err == nil { + session.mu.Lock() + if session.current_locked(job) { + session.source = interest + } else { + err = context.Canceled + } + session.mu.Unlock() + } + } + } + if err == nil { + if job.refresh && job.kind == ocr.ClipboardSource { + capture = job.snapshot + } else { + capture, err = session.capture.Capture(job.ctx, request) + } + } + if err == nil { + result, err = session.engine.Recognize(job.ctx, capture.Pixels, job.options) + if err == nil && result.Width > 0 && result.Height > 0 { + capture.Transform.ImageContent = image.Rect(0, 0, result.Width, result.Height) + } + } + if err == nil { + var fresh atspi.OCRGeometry + if err == nil && job.kind == ocr.ObjectSource { + var zone *atspi.Rectangle + if interest.HasZone { + zone = &interest.Zone + } + fresh, err = session.geometry.CaptureOCRGeometry(job.ctx, interest.Object, zone) + if err == nil && (fresh.Foreground != job.foreground || fresh.ScreenBounds != request.Bounds) { + err = ocr.ErrSourceChanged + } + } + if err == nil && result.Text != "" && !job.refresh { + err = session.keys.SetOCRContext(job.ctx, job.foreground.Client.Window, false) + } + } + session.mu.Lock() + current := session.current_locked(job) + if current { + if job.refresh { + session.finish_refresh_locked(job, interest, capture, result, err) + } else if err != nil || result.Text == "" { + session.retire_locked() + message := "OCR recognition failed" + switch { + case errors.Is(err, ocr.ErrUnavailable): + message = "OCR not available" + case err == nil: + message = "No text recognized" + case errors.Is(err, ocr.ErrSourceChanged): + message = "OCR source changed" + case errors.Is(err, atspi.ErrOCRGeometry), errors.Is(err, atspi.ErrObjectNotFound), errors.Is(err, review.ErrNoCurrent), errors.Is(err, ocr.ErrSource), errors.Is(err, ocr.ErrCapture): + message = "OCR source unavailable" + } + session.status_locked(message) + } else { + session.source, session.pixels = interest, capture + session.cursor = ocr.NewCursor(result) + session.selectionAnchor = -1 + if job.autoReadAll && session.readAll != nil { + if session.display != nil { + session.display.EnqueueFrame(session.frame_locked(session.cursor.Current(ocr.LineUnit))) + } + session.read_all_locked(job.timestamp) + } else { + session.present_locked(session.cursor.Current(ocr.LineUnit), ocr.LineUnit) + } + session.schedule_refresh_locked() + if job.copyFirstResult && session.copier != nil && session.copyRequests != nil { + select { + case session.copyRequests <- ocrCopyRequest{ctx: job.ctx, generation: job.generation, text: result.Text, automatic: true}: + default: + } + } + } + } else if session.generation == job.generation { + session.retire_locked() + } + session.mu.Unlock() + if !job.refresh && (!current || err != nil || result.Text == "") { + session.release_input() + } +} + +func (session *ocrSession) status_locked(message string) { + if session.gate.Locked() || session.gate.Suspended() { + return + } + session.speech.Enqueue(speechRequest{Text: message, Role: "system", Cause: "ocr-status"}) + if session.display != nil { + session.display.EnqueueFrame(braille.Frame{Text: message, Cursor: -1}) + } + session.logger.Debug("OCR status", "text", message) +} + +func (session *ocrSession) present_locked(position ocr.Position, unit ocr.Unit) { + session.present_spelling_locked(position, unit, review.FlatSpeak) +} + +func (session *ocrSession) present_spelling_locked(position ocr.Position, unit ocr.Unit, style review.FlatSpeech) { + text := presentationOCRText(position.Text, unit) + request := speechRequest{Text: text, Role: "text", Cause: "ocr-cursor", context: session.job.ctx, Character: unit == ocr.Character || unit == ocr.LineStart || unit == ocr.LineEnd} + set_review_spelling(&request, position.Text, style) + session.present_request_locked(position, unit, request) +} + +func (session *ocrSession) present_request_locked(position ocr.Position, unit ocr.Unit, request speechRequest) { + session.speech.Enqueue(request) + frame := session.frame_locked(position) + if session.display != nil { + session.display.EnqueueFrame(frame) + } + from, to := session.selection_locked() + session.logger.Debug("OCR cursor presentation", "generation", session.generation, "source_path", session.source.Object.Path, + "focus_path", session.focus.Path, "unit", unit, "offset", position.Offset, "line_start", position.LineStart, + "selection_start", from, "selection_end", to, + "speech_text", request.Text, "spelling", request.Spelling, "braille_text", frame.Text, "braille_cursor", frame.Cursor) +} + +func (session *ocrSession) selection_locked() (int, int) { + if session.cursor == nil || session.selectionAnchor < 0 { + return -1, -1 + } + return min(session.selectionAnchor, session.cursor.Offset()), max(session.selectionAnchor, session.cursor.Offset()) +} + +func (session *ocrSession) frame_locked(position ocr.Position) braille.Frame { + frame := ocr_braille_frame(position) + start := position.LineStart + position.Cursor - frame.Cursor + length := utf8.RuneCountInString(frame.Text) + frame.Virtual = &braille.VirtualRoute{Generation: session.generation, Start: 0, End: length, SourceStart: start} + if from, to := session.selection_locked(); from >= 0 && from != to { + indicator := byte(session.settings().Braille.SelectionIndicator) + if indicator != 0 { + frame.Dots = make([]byte, length) + for offset := max(from, start); offset < min(to, start+length); offset++ { + frame.Dots[offset-start] = indicator + } + } + } + return frame +} + +// Keep long Unicode lines inside the helper frame limit without losing the +// cursor. This is a presentation window; the document keeps the full line. +func ocr_braille_frame(position ocr.Position) braille.Frame { + if len(position.Line) <= 10000 { + return braille.Frame{Text: position.Line, Cursor: position.Cursor} + } + const windowRunes = 2000 // At most 8000 UTF-8 bytes, below the helper limit. + length := utf8.RuneCountInString(position.Line) + start := max(0, min(position.Cursor-windowRunes/2, length-windowRunes)) + end := min(length, start+windowRunes) + startByte, endByte, offset := 0, len(position.Line), 0 + for index := range position.Line { + if offset == start { + startByte = index + } + if offset == end { + endByte = index + break + } + offset++ + } + return braille.Frame{Text: position.Line[startByte:endByte], Cursor: position.Cursor - start} +} + +func presentationOCRText(text string, unit ocr.Unit) string { + if text == "" { + return "blank" + } + if unit == ocr.Character || unit == ocr.LineStart || unit == ocr.LineEnd { + switch text { + case " ": + return "space" + case "\n": + return "new line" + case "\t": + return "tab" + } + } + return text +} + +// Observe runs before native event presentation. Focus/owner changes retire +// synchronously, including changes within one X11 client. OCR never invents an +// AT-SPI object; duplicate source updates cannot overwrite its virtual cursor. +func (session *ocrSession) Observe(event atspi.Event) bool { + if session == nil { + return false + } + session.mu.Lock() + defer session.mu.Unlock() + if session.activating { + if (isFocusGainEvent(event) && event.Source.ID().BusName == session.job.focus.BusName && event.Source.ID() != session.job.focus) || + (event.Type == atspi.DefunctStateEvent && (event.Source.ID() == session.job.focus || event.Source.ID() == session.source.Object)) { + session.activationInterrupted = true + } + return false + } + if session.cancel != nil && session.foreground.Foreground() != session.job.foreground { + session.retire_locked() + } + if isFocusGainEvent(event) && !event.ForegroundMismatch && !eventBypassesXTermHandoff(event) && + (session.foreground == nil || event.Foreground.Epoch == 0 || event.Foreground.Epoch == session.foreground.Foreground().Epoch) { + if event.Type == atspi.WindowActivatedEvent && session.window.Valid() && eventWindow(event) == session.window { + return session.cursor != nil + } + session.window = eventWindow(event) + if session.focus != event.Source.ID() { + session.retire_locked() + } + session.focus = event.Source.ID() + if session.foreground != nil { + session.focusForeground = session.foreground.Foreground().Client.Window + } + } + if event.Type == atspi.WindowDeactivatedEvent || event.Type == atspi.WindowDestroyedEvent || event.Type == atspi.DefunctStateEvent { + if session.foreground != nil && transientForegroundDeactivation(event, session.foreground.Foreground()) { + return false + } + sourceLost := event.Source.ID() == session.focus || session.cancel != nil && + (event.Source.ID() == session.source.Object || event.Source.ID() == session.job.window) + windowLost := event.Type != atspi.DefunctStateEvent && session.cancel != nil && eventWindow(event) == session.job.window + if sourceLost || windowLost { + session.retire_locked() + session.focus = atspi.ObjectID{} + } + } + return session.cursor != nil && !eventBypassesXTermHandoff(event) && + (isFocusGainEvent(event) || event.Type == atspi.CaretEvent || isTextChangeEvent(event.Type) || event.Type == atspi.AccessibleNameEvent || event.Type == atspi.TextSelectionChangedEvent) +} + +func (session *ocrSession) ForegroundChanged() { + if session == nil { + return + } + session.mu.Lock() + defer session.mu.Unlock() + if session.activating { + return + } + if session.cancel != nil && session.foreground.Foreground() != session.job.foreground { + session.retire_locked() + } +} + +func (session *ocrSession) settings() config.Settings { + if session.live != nil { + return session.live.Load() + } + return config.DefaultSettings() +} + +func (session *ocrSession) Reviewing() bool { + if session == nil { + return false + } + session.mu.Lock() + defer session.mu.Unlock() + return session.cancel != nil && session.cursor != nil +} + +// RouteBraille accepts only a current OCR frame's generation and moves the +// virtual cursor. It never forwards a route to AT-SPI or application focus. +func (session *ocrSession) RouteBraille(ctx context.Context, generation uint64, offset int) { + if session == nil || ctx.Err() != nil { + return + } + session.mu.Lock() + defer session.mu.Unlock() + if generation != session.generation || session.cursor == nil || !session.current_locked(session.job) || ctx.Err() != nil { + return + } + position, ok := session.cursor.Set(offset) + if !ok { + return + } + session.selectionAnchor = -1 + session.logger.Debug("OCR braille route", "command", "braille-route", "generation", generation, + "focus_path", session.focus.Path, "source_path", session.source.Object.Path, "offset", offset) + session.present_locked(position, ocr.Character) +} diff --git a/internal/app/ocr_session_test.go b/internal/app/ocr_session_test.go new file mode 100644 index 0000000..3e344ca --- /dev/null +++ b/internal/app/ocr_session_test.go @@ -0,0 +1,721 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "fmt" + "image" + "log/slog" + "reflect" + "strings" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/ocr" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/review" +) + +type ocrTestKeys struct { + calls chan string + enter func(context.Context) error + releaseErr error + release func() error +} + +func (keys *ocrTestKeys) SetOCRReview(ctx context.Context, enabled bool) error { + if enabled { + panic("entry must supply foreground") + } + keys.calls <- "released" + if keys.release != nil { + return keys.release() + } + return keys.releaseErr +} +func (keys *ocrTestKeys) SetOCRContext(ctx context.Context, foreground uint64, pending bool) error { + if foreground != 42 { + return ocr.ErrSourceChanged + } + if pending { + keys.calls <- "pending" + return ctx.Err() + } + keys.calls <- "review" + if keys.enter != nil { + return keys.enter(ctx) + } + return ctx.Err() +} + +type ocrTestForeground struct { + mu sync.Mutex + state atspi.ForegroundState +} + +func (monitor *ocrTestForeground) Foreground() atspi.ForegroundState { + monitor.mu.Lock() + defer monitor.mu.Unlock() + return monitor.state +} +func (*ocrTestForeground) ForegroundChanges() <-chan struct{} { return nil } + +type ocrTestGeometry struct { + monitor *ocrTestForeground + calls chan atspi.ObjectID + err error +} + +func (source *ocrTestGeometry) CaptureOCRGeometry(ctx context.Context, id atspi.ObjectID, zone *atspi.Rectangle) (atspi.OCRGeometry, error) { + source.calls <- id + if ctx.Err() != nil { + return atspi.OCRGeometry{}, ctx.Err() + } + return atspi.OCRGeometry{Object: id, Foreground: source.monitor.Foreground(), ScreenBounds: image.Rect(10, 20, 110, 70)}, source.err +} + +type ocrTestInterest struct{ interest review.Interest } + +func (source ocrTestInterest) ObjectOfInterest(context.Context) (review.Interest, error) { + return source.interest, nil +} + +type ocrTestCapture struct { + calls chan ocr.CaptureRequest + run func(context.Context) error + produce func(context.Context, ocr.CaptureRequest) (ocr.Capture, error) +} + +func (source *ocrTestCapture) Capture(ctx context.Context, request ocr.CaptureRequest) (ocr.Capture, error) { + source.calls <- request + if source.produce != nil { + return source.produce(ctx, request) + } + if source.run != nil { + if err := source.run(ctx); err != nil { + return ocr.Capture{}, err + } + } + return ocr.Capture{CaptureHeader: ocr.CaptureHeader{Request: request}, Pixels: image.NewRGBA(image.Rect(0, 0, 100, 50))}, ctx.Err() +} + +type ocrTestEngine struct { + calls chan context.Context + results chan ocr.Result + err error +} + +func (engine *ocrTestEngine) Recognize(ctx context.Context, _ image.Image, _ ocr.Options) (ocr.Result, error) { + engine.calls <- ctx + // Deliberately finish after cancellation to verify the publication guard. + return <-engine.results, engine.err +} + +type ocrTestOutput struct { + speech chan speechRequest + frames chan braille.Frame +} + +type ocrTestCopier struct{ copied chan string } + +func (copier *ocrTestCopier) Copy(ctx context.Context, value string) error { + copier.copied <- value + return ctx.Err() +} + +type ocrTestReadAll struct{ timestamp uint32 } + +func (reader *ocrTestReadAll) BeginReadAll(ctx context.Context, timestamp uint32) context.Context { + reader.timestamp = timestamp + return ctx +} + +func (output *ocrTestOutput) Enqueue(request speechRequest) { output.speech <- request } +func (*ocrTestOutput) Interrupt() {} +func (output *ocrTestOutput) EnqueueFrame(frame braille.Frame) { output.frames <- frame } + +func ocr_test_receive[T any](t *testing.T, channel <-chan T) T { + t.Helper() + select { + case result := <-channel: + return result + case <-time.After(3 * time.Second): + t.Fatal("OCR worker did not respond") + } + var empty T + return empty +} +func ocr_test_focus(path, role string) atspi.Event { + return atspi.Event{Type: atspi.FocusEvent, Source: atspi.Snapshot{BusName: ":1.42", Path: path, Role: role}, Window: atspi.NewObjectID(":1.42", "/window")} +} +func ocr_test_session(t *testing.T) (*ocrSession, *ocrTestKeys, *ocrTestCapture, *ocrTestEngine, *ocrTestOutput) { + t.Helper() + keys := &ocrTestKeys{calls: make(chan string, 32)} + monitor := &ocrTestForeground{state: atspi.ForegroundState{Epoch: 1, Client: xorg.Foreground{Known: true, Window: 42, PID: 123, Width: 100, Height: 50}}} + capture := &ocrTestCapture{calls: make(chan ocr.CaptureRequest, 16)} + engine := &ocrTestEngine{calls: make(chan context.Context, 16), results: make(chan ocr.Result, 16)} + output := &ocrTestOutput{speech: make(chan speechRequest, 32), frames: make(chan braille.Frame, 32)} + session := &ocrSession{logger: slog.New(slog.DiscardHandler), keys: keys, geometry: &ocrTestGeometry{monitor: monitor, calls: make(chan atspi.ObjectID, 32)}, + interest: ocrTestInterest{review.Interest{Object: atspi.NewObjectID(":1.42", "/image")}}, foreground: monitor, capture: capture, engine: engine, + speech: output, display: output, gate: newFocusGate(nil), wake: make(chan struct{}, 1), failures: make(chan error, 1), + copyRequests: make(chan ocrCopyRequest, 1), activateRequests: make(chan ocrActivateRequest, 1), held: make(map[string]bool), selectionAnchor: -1} + if err := session.Start(context.Background()); err != nil { + t.Fatal(err) + } + session.Observe(ocr_test_focus("/focus", "image")) + t.Cleanup(func() { + engine.results <- ocr.Result{} + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := session.Stop(ctx); err != nil { + t.Error(err) + } + }) + return session, keys, capture, engine, output +} + +func TestOCRSessionCommandsOwnSourceAndRunePresentation(t *testing.T) { + session, keys, capture, engine, output := ocr_test_session(t) + if !session.Handle(input.CommandEvent{Command: input.OCRObject, Timestamp: 100}) { + t.Fatal("OCR command not claimed") + } + if got := ocr_test_receive(t, keys.calls); got != "pending" { + t.Fatal(got) + } + request := ocr_test_receive(t, capture.calls) + if request.Kind != ocr.ObjectSource || request.Foreground != 42 || request.Bounds != image.Rect(10, 20, 110, 70) || request.Generation == 0 { + t.Fatalf("capture: %+v", request) + } + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "é one\ntwo", Words: []ocr.Word{{Text: "é", Span: ocr.Span{Start: 0, End: 1}}, {Text: "one", Span: ocr.Span{Start: 2, End: 5}}, {Text: "two", Span: ocr.Span{Start: 6, End: 9}}}} + if got := ocr_test_receive(t, keys.calls); got != "review" { + t.Fatal(got) + } + if got := ocr_test_receive(t, output.speech); got.Text != "é one" { + t.Fatal(got) + } + if got := ocr_test_receive(t, output.frames); got.Text != "é one" || got.Cursor != 0 || len(got.Routes) != 0 { + t.Fatalf("braille: %+v", got) + } + session.Input(input.NewKeyEvent(1, true, "Right")) + session.Handle(input.CommandEvent{Command: input.OCRNextCharacter, Timestamp: 101}) + if got := ocr_test_receive(t, output.speech); got.Text != "space" || !got.Character { + t.Fatal(got) + } + if got := ocr_test_receive(t, output.frames); got.Cursor != 1 { + t.Fatal(got) + } + session.Handle(input.CommandEvent{Command: input.OCRNextWord, Timestamp: 102}) + if got := ocr_test_receive(t, output.speech); got.Text != "one" { + t.Fatal(got) + } + if got := ocr_test_receive(t, output.frames); got.Cursor != 2 { + t.Fatal(got) + } + // A repeated activation of the same top-level is not a focus change. + for _, tc := range []struct { + command input.Command + parts []string + }{ + {input.ReviewSpellWord, []string{"o", "n", "e"}}, + {input.ReviewSpellLine, []string{"é", "space", "o", "n", "e"}}, + {input.ReviewPhoneticLine, []string{"é", "space", "oscar", "november", "echo"}}, + {input.ReviewPhoneticWord, []string{"oscar", "november", "echo"}}, + {input.ReviewPhoneticCharacter, []string{"oscar"}}, + } { + if !session.Handle(input.CommandEvent{Command: tc.command}) { + t.Fatal("OCR did not claim spelling") + } + if got := ocr_test_receive(t, output.speech); !reflect.DeepEqual(got.Spelling, tc.parts) { + t.Fatalf("OCR spelling: %+v", got) + } + if got := ocr_test_receive(t, output.frames); got.Text != "é one" || got.Cursor != 2 { + t.Fatalf("spelling moved OCR braille cursor: %+v", got) + } + } + event := ocr_test_focus("/window", "frame") + event.Type = atspi.WindowActivatedEvent + if !session.Observe(event) { + t.Fatal("duplicate activation discarded OCR") + } + event.Type = atspi.WindowDeactivatedEvent + session.Observe(event) + session.Handle(input.CommandEvent{Command: input.OCRNextLine, Timestamp: 103}) + if got := ocr_test_receive(t, output.speech); got.Text != "two" { + t.Fatal(got) + } + if got := ocr_test_receive(t, output.frames); got.Text != "two" || got.Cursor != 2 { + t.Fatal(got) + } + session.Handle(input.CommandEvent{Command: input.OCRDismiss, Timestamp: 104}) + if got := ocr_test_receive(t, output.speech); got.Text != "OCR dismissed" { + t.Fatal(got) + } + if got := ocr_test_receive(t, keys.calls); got != "released" { + t.Fatal(got) + } +} + +func TestOCRSessionSupersedesAndJoinsBeforeNewJob(t *testing.T) { + session, keys, capture, engine, output := ocr_test_session(t) + session.Handle(input.CommandEvent{Command: input.OCRWindow, Timestamp: 100}) + first := ocr_test_receive(t, capture.calls) + firstContext := ocr_test_receive(t, engine.calls) + session.Handle(input.CommandEvent{Command: input.OCRClipboard, Timestamp: 101}) + if firstContext.Err() != context.Canceled { + t.Fatal("replacement did not cancel old job") + } + select { + case <-capture.calls: + t.Fatal("new capture overlapped old recognition") + default: + } + engine.results <- ocr.Result{Text: "stale result"} + second := ocr_test_receive(t, capture.calls) + if first.Kind != ocr.WindowSource || second.Kind != ocr.ClipboardSource || second.Generation <= first.Generation { + t.Fatalf("generations: %+v %+v", first, second) + } + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "current result"} + if got := ocr_test_receive(t, output.speech); got.Text != "current result" { + t.Fatal(got) + } + // Source options/pixels are owned until dismissal, even for clipboard OCR. + session.mu.Lock() + kind := session.pixels.Request.Kind + session.mu.Unlock() + if kind != ocr.ClipboardSource { + t.Fatal(kind) + } + _ = keys +} + +func TestOCRSessionRetiresEveryJobBoundary(t *testing.T) { + for _, boundary := range []string{"input", "same-client-focus", "password", "source-destroyed", "foreground", "lock", "terminal", "dialog", "shutdown"} { + t.Run(boundary, func(t *testing.T) { + session, keys, _, engine, output := ocr_test_session(t) + session.Handle(input.CommandEvent{Command: input.OCRObject, Timestamp: 100}) + jobContext := ocr_test_receive(t, engine.calls) + switch boundary { + case "input": + event := input.NewKeyEvent(1, true, "a") + event.Timestamp = 101 + session.Input(event) + case "same-client-focus": + session.Observe(ocr_test_focus("/other", "image")) + case "password": + session.Observe(ocr_test_focus("/password", "password text")) + case "source-destroyed": + event := ocr_test_focus("/image", "image") + event.Type = atspi.DefunctStateEvent + session.Observe(event) + case "foreground": + monitor := session.foreground.(*ocrTestForeground) + monitor.mu.Lock() + monitor.state.Epoch++ + monitor.mu.Unlock() + session.ForegroundChanged() + case "lock": + session.gate.ocr = session + session.gate.SetLocked(true, nil, nil, nil, nil, &brailleWorker{}) + case "terminal": + session.gate.ocr = session + session.gate.SetSuspended(true) + case "dialog": + if session.Handle(input.CommandEvent{Command: input.Preferences}) { + t.Fatal("preferences swallowed") + } + case "shutdown": + session.stop() + } + select { + case <-jobContext.Done(): + case <-time.After(3 * time.Second): + t.Fatal("job not canceled") + } + engine.results <- ocr.Result{Text: "late private text"} + for ocr_test_receive(t, keys.calls) != "released" { + } + select { + case got := <-output.speech: + t.Fatalf("late output: %+v", got) + default: + } + }) + } +} + +func TestOCRSessionPasswordFocusAllowsVisibleCapture(t *testing.T) { + for _, command := range []input.Command{input.OCRObject, input.OCRWindow, input.OCRDesktop, input.OCRClipboard} { + t.Run(string(command), func(t *testing.T) { + session, _, capture, engine, output := ocr_test_session(t) + session.Observe(ocr_test_focus("/protected", "password text")) + session.Handle(input.CommandEvent{Command: command}) + ocr_test_receive(t, capture.calls) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "Visible label"} + if got := ocr_test_receive(t, output.speech); got.Text != "Visible label" { + t.Fatal(got) + } + }) + } +} + +func TestOCRSessionScreenSourcesWithoutAccessibility(t *testing.T) { + for _, command := range []input.Command{input.OCRWindow, input.OCRDesktop, input.OCRClipboard} { + for _, staleFocus := range []bool{false, true} { + t.Run(string(command)+fmt.Sprint("/stale=", staleFocus), func(t *testing.T) { + session, _, capture, engine, output := ocr_test_session(t) + session.geometry, session.interest = nil, nil + if staleFocus { + session.focusForeground = 99 + } else { + session.focus, session.window = atspi.ObjectID{}, atspi.ObjectID{} + } + session.Handle(input.CommandEvent{Command: command, Timestamp: 100}) + request := ocr_test_receive(t, capture.calls) + if request.Foreground != 42 || request.Bounds != (image.Rectangle{}) { + t.Fatalf("non-object capture: %+v", request) + } + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "Visible text"} + if got := ocr_test_receive(t, output.speech); got.Text != "Visible text" { + t.Fatal(got) + } + ocr_test_receive(t, output.frames) + session.Handle(input.CommandEvent{Command: input.OCRRefresh, Timestamp: 101}) + if command != input.OCRClipboard { + ocr_test_receive(t, capture.calls) + } + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "Updated text"} + if got := ocr_test_receive(t, output.speech); got.Text != "Updated text" { + t.Fatal(got) + } + ocr_test_receive(t, output.frames) + session.Handle(input.CommandEvent{Command: input.OCRDismiss}) + if got := ocr_test_receive(t, output.speech); got.Text != "OCR dismissed" { + t.Fatal(got) + } + }) + } + } +} + +func TestOCRSessionObjectStillRequiresAccessibleFocus(t *testing.T) { + for _, staleFocus := range []bool{false, true} { + session, _, capture, _, output := ocr_test_session(t) + if staleFocus { + session.focusForeground = 99 + } else { + session.focus = atspi.ObjectID{} + } + session.Handle(input.CommandEvent{Command: input.OCRObject}) + if got := ocr_test_receive(t, output.speech); got.Text != "OCR source unavailable" { + t.Fatal(got) + } + select { + case <-capture.calls: + t.Fatal("object OCR captured without a current accessible focus") + default: + } + } +} + +func TestOCRSessionLockRetiresInaccessibleWindowResult(t *testing.T) { + session, keys, _, engine, output := ocr_test_session(t) + session.focus, session.window = atspi.ObjectID{}, atspi.ObjectID{} + session.geometry = nil + session.Handle(input.CommandEvent{Command: input.OCRWindow}) + ocr_test_receive(t, keys.calls) + jobContext := ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "Visible text"} + ocr_test_receive(t, keys.calls) + ocr_test_receive(t, output.speech) + ocr_test_receive(t, output.frames) + session.gate.ocr = session + session.gate.SetLocked(true, nil, nil, nil, nil, &brailleWorker{}) + if jobContext.Err() != context.Canceled || session.Reviewing() { + t.Fatal("screen lock retained OCR result") + } + if got := ocr_test_receive(t, output.frames); got.Text != "" { + t.Fatal("screen lock retained OCR braille text") + } + for ocr_test_receive(t, keys.calls) != "released" { + } + for _, command := range []input.Command{input.OCRObject, input.OCRWindow, input.OCRDesktop, input.OCRClipboard} { + session.Handle(input.CommandEvent{Command: command}) + } + select { + case <-engine.calls: + t.Fatal("recognition started while locked") + default: + } +} + +func TestOCRSessionSourceAndDependencyErrors(t *testing.T) { + for _, failure := range []error{ocr.ErrUnavailable, nil, atspi.ErrOCRGeometry} { + session, keys, capture, engine, output := ocr_test_session(t) + engine.err = failure + if errors.Is(failure, atspi.ErrOCRGeometry) { + session.geometry.(*ocrTestGeometry).err = failure + } + command := input.OCRWindow + if errors.Is(failure, atspi.ErrOCRGeometry) { + command = input.OCRObject + } + session.Handle(input.CommandEvent{Command: command}) + if !errors.Is(failure, atspi.ErrOCRGeometry) { + ocr_test_receive(t, capture.calls) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{} + } + want := "No text recognized" + if failure == ocr.ErrUnavailable { + want = "OCR not available" + } + if failure == atspi.ErrOCRGeometry { + want = "OCR source unavailable" + } + if got := ocr_test_receive(t, output.speech); got.Text != want { + t.Fatal(got) + } + for ocr_test_receive(t, keys.calls) != "released" { + } + } +} + +func TestOCRSessionDelayedInitiatingInputAndChordRetirement(t *testing.T) { + session, _, _, engine, output := ocr_test_session(t) + session.Handle(input.CommandEvent{Command: input.OCRWindow, Timestamp: 100}) + jobContext := ocr_test_receive(t, engine.calls) + event := input.NewKeyEvent(1, true, "o") + event.Timestamp = 100 + session.Input(event) + if jobContext.Err() != nil { + t.Fatal("delayed command observation canceled job") + } + engine.results <- ocr.Result{Text: "result"} + ocr_test_receive(t, output.speech) + session.Input(input.NewKeyEvent(2, true, "Control_L")) + session.Input(input.NewKeyEvent(3, true, "Right")) + if jobContext.Err() != nil { + t.Fatal("claimed Ctrl+Right canceled result") + } + session.Input(input.NewKeyEvent(3, false, "Right")) + session.Input(input.NewKeyEvent(4, true, "g")) + if jobContext.Err() != context.Canceled { + t.Fatal("unbound Ctrl+G did not retire") + } +} + +func TestOCRSessionCancellationDuringCaptureAndInputEntry(t *testing.T) { + for _, phase := range []string{"capture", "input-entry"} { + t.Run(phase, func(t *testing.T) { + session, keys, capture, engine, output := ocr_test_session(t) + started := make(chan context.Context, 1) + block := func(ctx context.Context) error { started <- ctx; <-ctx.Done(); return ctx.Err() } + if phase == "capture" { + capture.run = block + } else { + keys.enter = block + } + session.Handle(input.CommandEvent{Command: input.OCRWindow}) + if phase == "input-entry" { + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "ready"} + } + jobContext := ocr_test_receive(t, started) + session.Retire() + if jobContext.Err() != context.Canceled { + t.Fatal("native operation not canceled") + } + for ocr_test_receive(t, keys.calls) != "released" { + } + select { + case got := <-output.speech: + t.Fatalf("canceled operation published: %+v", got) + default: + } + }) + } +} + +func TestOCRSessionReleaseFailureIsReported(t *testing.T) { + session, keys, _, engine, output := ocr_test_session(t) + keys.releaseErr = errors.New("release failed") + session.Handle(input.CommandEvent{Command: input.OCRWindow}) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "ready"} + ocr_test_receive(t, output.speech) + session.Retire() + if err := ocr_test_receive(t, session.failures); err != keys.releaseErr { + t.Fatal(err) + } +} + +func TestOCRSessionWaitForPhysicalReleaseRetries(t *testing.T) { + session, keys, _, engine, output := ocr_test_session(t) + count := 0 + keys.release = func() error { + count++ + if count == 1 { + return context.DeadlineExceeded + } + return nil + } + session.Handle(input.CommandEvent{Command: input.OCRWindow}) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "ready"} + ocr_test_receive(t, output.speech) + session.Retire() + releases := 0 + for releases < 2 { + if ocr_test_receive(t, keys.calls) == "released" { + releases++ + } + } + select { + case err := <-session.failures: + t.Fatalf("held physical key stopped reader: %v", err) + default: + } +} + +func TestOCRSessionRecognizesCthulhuAndNativeKeypadNames(t *testing.T) { + for _, name := range []string{"KP_Insert", "Caps_Lock", "KP_Next", "KP_Prior"} { + t.Run(name, func(t *testing.T) { + session, _, _, engine, output := ocr_test_session(t) + settings := session.settings() + settings.CthulhuModifierKeys = []string{"Insert", "KP_Insert", "Caps_Lock"} + session.live = &liveSettings{} + session.live.Store(settings) + session.Handle(input.CommandEvent{Command: input.OCRWindow}) + jobContext := ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "ready"} + ocr_test_receive(t, output.speech) + session.Input(input.NewKeyEvent(1, true, name)) + if jobContext.Err() != nil { + t.Fatalf("claimed native key %s retired OCR", name) + } + }) + } +} + +func TestOCRBrailleKeepsCursorInLongUnicodeLine(t *testing.T) { + line := strings.Repeat("界", 5000) + frame := ocr_braille_frame(ocr.Position{Line: line, Cursor: 4999}) + if len(frame.Text) > 10000 || frame.Cursor != 1999 || len([]rune(frame.Text)) != 2000 || []rune(frame.Text)[frame.Cursor] != '界' { + t.Fatalf("long-line cursor lost: bytes=%d cursor=%d", len(frame.Text), frame.Cursor) + } +} + +func TestOCRSelectionCopySayAllAndBrailleRouting(t *testing.T) { + session, _, _, engine, output := ocr_test_session(t) + copier := &ocrTestCopier{copied: make(chan string, 2)} + reader := &ocrTestReadAll{} + session.copier = copier + session.readAll = reader + session.Handle(input.CommandEvent{Command: input.OCRWindow, Timestamp: 100}) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "é one\n猫 two"} + ocr_test_receive(t, output.speech) + initial := ocr_test_receive(t, output.frames) + if initial.Virtual == nil || initial.Virtual.Generation == 0 || initial.Virtual.SourceStart != 0 { + t.Fatalf("missing OCR route: %+v", initial) + } + session.Handle(input.CommandEvent{Command: input.OCRNextCharacter, Chord: input.CommandChord{Modifiers: 1}, Timestamp: 101}) + ocr_test_receive(t, output.speech) + selected := ocr_test_receive(t, output.frames) + if selected.Cursor != 1 || len(selected.Dots) != 5 || selected.Dots[0] == 0 || selected.Dots[1] != 0 { + t.Fatalf("selection frame: %+v", selected) + } + session.Handle(input.CommandEvent{Command: input.OCRCopySelection, Timestamp: 102}) + if got := ocr_test_receive(t, copier.copied); got != "é" { + t.Fatalf("copied %q", got) + } + if got := ocr_test_receive(t, output.speech); got.Text != "OCR text copied to clipboard" { + t.Fatal(got) + } + ocr_test_receive(t, output.frames) // copy status + session.Handle(input.CommandEvent{Command: input.OCRSelectAll, Timestamp: 103}) + if got := ocr_test_receive(t, output.speech); got.Text != "OCR text selected" { + t.Fatal(got) + } + ocr_test_receive(t, output.frames) + session.Handle(input.CommandEvent{Command: input.OCRCopySelection, Timestamp: 104}) + if got := ocr_test_receive(t, copier.copied); got != "é one\n猫 two" { + t.Fatalf("copied all %q", got) + } + ocr_test_receive(t, output.speech) + ocr_test_receive(t, output.frames) + session.RouteBraille(context.Background(), initial.Virtual.Generation, 6) + if got := ocr_test_receive(t, output.speech); got.Text != "猫" { + t.Fatal(got) + } + routed := ocr_test_receive(t, output.frames) + if routed.Text != "猫 two" || routed.Cursor != 0 || routed.Virtual.SourceStart != 6 { + t.Fatalf("routed frame: %+v", routed) + } + session.Handle(input.CommandEvent{Command: input.ReadAll, Timestamp: 105}) + request := ocr_test_receive(t, output.speech) + if reader.timestamp != 105 || len(request.ReadAll) != 1 || request.ReadAll[0].Text != "猫 two" { + t.Fatalf("Say All request: %+v", request) + } + request.ReadAll[0].Began() + if got := ocr_test_receive(t, output.frames); got.Cursor != 0 || got.Virtual == nil { + t.Fatalf("Say All braille: %+v", got) + } + session.Retire() + request.ReadAll[0].Began() + select { + case got := <-output.frames: + if got.Text != "" { + t.Fatalf("late Say All frame: %+v", got) + } + default: + } +} + +func TestOCRBrailleWorkerRoutesOnlyCurrentVirtualFrame(t *testing.T) { + session, _, _, engine, output := ocr_test_session(t) + session.Handle(input.CommandEvent{Command: input.OCRWindow}) + ocr_test_receive(t, engine.calls) + engine.results <- ocr.Result{Text: "é猫"} + ocr_test_receive(t, output.speech) + frame := ocr_test_receive(t, output.frames) + native := &recordingBrailleRouter{calls: make(chan atspi.BrailleRoute, 1)} + worker := &brailleWorker{ocr: session, router: native, logger: slog.New(slog.DiscardHandler), wake: make(chan struct{}, 1), cancel: func() {}} + worker.EnqueueFrame(frame) + id := worker.current().ID + worker.route(context.Background(), braille.RoutingEvent{ID: id + 1, Offset: 1}) + select { + case <-output.speech: + t.Fatal("stale frame moved OCR cursor") + default: + } + worker.route(context.Background(), braille.RoutingEvent{ID: id, Offset: 1}) + if got := ocr_test_receive(t, output.speech); got.Text != "猫" { + t.Fatal(got) + } + if len(native.calls) != 0 { + t.Fatal("OCR routing moved the native caret") + } + session.Retire() + ocr_test_receive(t, output.frames) // routed presentation + ocr_test_receive(t, output.frames) // retired blank frame + worker.route(context.Background(), braille.RoutingEvent{ID: id, Offset: 0}) + select { + case <-output.speech: + t.Fatal("retired OCR route spoke") + default: + } +} diff --git a/internal/app/output_queue.go b/internal/app/output_queue.go new file mode 100644 index 0000000..9fe60f1 --- /dev/null +++ b/internal/app/output_queue.go @@ -0,0 +1,71 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +type outputQueue struct { + speech speechEnqueuer + sounds soundService + braille brailleFrameEnqueuer + live *liveSettings +} + +func (queue outputQueue) Enqueue(request speechRequest) { + if len(request.Sound) != 0 && (queue.sounds == nil || !queue.sounds.EnqueueBatch(request.Sound)) && request.FallbackText != "" { + request.Text = request.FallbackText + request.Chunks = request.FallbackChunks + } + if request.Text != "" || len(request.ReadAll) != 0 { + queue.speech.Enqueue(request) + } + if queue.braille != nil && queue.live != nil && request.Text != "" && request.Role == "system" && + request.Cause != "read-all" && request.Cause != "document-caret-line" { + if flasher, ok := queue.braille.(interface { + Flash(string, config.BrailleOptions) bool + }); ok { + flasher.Flash(request.Text, queue.live.Load().Braille) + } + } +} +func (queue outputQueue) Interrupt() { queue.speech.Interrupt() } + +func (queue outputQueue) InterruptForUser() { + if speech, ok := queue.speech.(interface{ InterruptForUser() }); ok { + speech.InterruptForUser() + } else { + queue.speech.Interrupt() + } +} + +func (queue outputQueue) InterruptForInput(event input.Event) bool { + if speech, ok := queue.speech.(interface{ InterruptForInput(input.Event) bool }); ok { + return speech.InterruptForInput(event) + } + queue.InterruptForUser() + return true +} + +type discardSpeech struct{} + +func (discardSpeech) Enqueue(speechRequest) {} + +func (discardSpeech) Interrupt() {} diff --git a/internal/app/output_queue_test.go b/internal/app/output_queue_test.go new file mode 100644 index 0000000..6b37946 --- /dev/null +++ b/internal/app/output_queue_test.go @@ -0,0 +1,54 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "reflect" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/sound" +) + +func TestOutputQueueUsesSpeechFallbackWhenSoundBatchIsRejected(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1), requests: make(chan speechRequest, 1)} + queue := outputQueue{speech: speech, sounds: rejectingSound{}} + queue.Enqueue(speechRequest{ + Text: "Power", Chunks: []string{"Power"}, FallbackText: "Power, toggle button, pressed", + FallbackChunks: []string{"Power", "toggle button", "pressed"}, + Sound: []sound.Cue{{Name: "button"}, {Name: "togglebutton_checked"}}, + }) + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.deliver(context.Background(), <-speech.requests); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(speaker.parts, []string{"Power", "toggle button", "pressed"}) { + t.Fatalf("sound fallback lost its pause chunks: %v", speaker.parts) + } + select { + case got := <-speech.spoken: + if got != "Power, toggle button, pressed" { + t.Fatalf("fallback speech = %q", got) + } + case <-time.After(time.Second): + t.Fatal("missing rejected-sound fallback speech") + } +} diff --git a/internal/app/pause_chunks_test.go b/internal/app/pause_chunks_test.go new file mode 100644 index 0000000..2b51b4e --- /dev/null +++ b/internal/app/pause_chunks_test.go @@ -0,0 +1,218 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestPauseChunksInterruptRemainingAnnouncement(t *testing.T) { + speaker := &controlledSpeaker{calls: make(chan speechCall, 10)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + presenter := eventPresenter{state: &eventLoopState{}, + logger: slog.New(slog.DiscardHandler), speech: worker} + presenter.state.presentationOptions = presentation.DefaultOptions() + presenter.speak(atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{Name: "Save, draft", Role: "button", Description: "Save document"})) + first := expectSpeechCall(t, speaker, "Save, draft") + worker.InterruptForUser() + close(expectSpeechCall(t, speaker, "cancel").done) + worker.Enqueue(speechRequest{Text: "New focus"}) + close(first.done) + close(expectSpeechCall(t, speaker, "cancel").done) // Settle the interrupted call. + close(expectSpeechCall(t, speaker, "New focus").done) +} + +func TestPauseChunksStopOnBackendFailure(t *testing.T) { + failure := errors.New("speech failed") + speaker := &fakeSpeaker{speakError: failure} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.history = newSpeechHistory(10) + spoken := presentation.FocusSpeechWithOptions(atspi.Snapshot{Name: "Save", Role: "button"}, presentation.DefaultOptions()) + err := worker.deliver(context.Background(), speechRequest{Text: spoken.Text, Chunks: spoken.Chunks}) + if !errors.Is(err, failure) { + t.Fatalf("delivery error = %v", err) + } + if got := worker.history.snapshot(); !reflect.DeepEqual(got, []string{"Save"}) { + t.Fatalf("undelivered chunks entered history: %v", got) + } +} + +func TestPauseChunksPreservePresentationDecorations(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSound = false + settings.Reading.PresentTooltips = true + live := &liveSettings{} + live.Store(settings) + options := presentationSettingsFromConfig(settings, true) + logger := slog.New(slog.DiscardHandler) + for _, test := range []struct { + name string + present func(*fakeSpeechQueue) + want []string + }{ + {"window title", func(queue *fakeSpeechQueue) { + presenter := eventPresenter{state: &eventLoopState{}, logger: logger, speech: queue, live: live} + event := atspi.NewEvent(atspi.WindowActivatedEvent, atspi.Snapshot{Name: "Save", Role: "button"}) + event.WindowTitle = "Save, button" + presenter.speak(event) + }, []string{"Save, button", "Save", "button"}}, + {"table", func(queue *fakeSpeechQueue) { + presenter := eventPresenter{state: &eventLoopState{}, logger: logger, speech: queue, live: live} + event := ownerEvent(atspi.FocusEvent, ":1.42", "/window", "/cell") + event.Source.Name, event.Source.Role, event.Source.GUITable = "One, Two", "table cell", true + event.Source.TableName, event.Source.TablePath = "Example, table", "/table" + event.WindowDescription = "Table help, details" + presenter.speak(event) + }, []string{"Example, table", "One, Two", "Table help, details"}}, + {"prompt", func(queue *fakeSpeechQueue) { + presenter := eventPresenter{state: &eventLoopState{}, logger: logger, speech: queue, live: live} + event := ownerEvent(atspi.WindowActivatedEvent, ":1.42", "/window", "/button") + event.Source.Name, event.Source.Role = "Save", "button" + event.WindowTitle, event.WindowMessage = "Question, details", "Save draft, or discard?" + presenter.speak(event) + }, []string{"Question, details", "Save draft, or discard?"}}, + {"browser wrapping", func(queue *fakeSpeechQueue) { + presentDocumentResult(logger, queue, review.Result{Moved: true, DocumentWrapped: true, + DocumentPosition: review.DocumentPosition{Snapshot: atspi.Snapshot{Name: "Read, draft", Role: "link"}}, + CaretErr: errors.New("caret unavailable")}, options) + }, []string{"Read, draft", "link", "Wrapping to top."}}, + {"tooltip", func(queue *fakeSpeechQueue) { + handler := accessibilityEventHandler{state: &eventLoopState{}, speech: queue, live: live} + event := atspi.NewEvent(atspi.ShowingStateEvent, atspi.Snapshot{Name: "Save, draft", Role: "tool tip"}) + event.Detail1 = 1 + handler.handleTooltip(event) + }, []string{"Save, draft", "tool tip"}}, + {"object review", func(queue *fakeSpeechQueue) { + presentObjectReviewResult(logger, queue, review.Result{Moved: true, + Position: review.Position{Current: atspi.Snapshot{Name: "Read, draft", Role: "link"}}}, options) + }, []string{"Read, draft", "link"}}, + } { + t.Run(test.name, func(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 1), requests: make(chan speechRequest, 1)} + test.present(queue) + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(logger, speaker) + if len(queue.requests) != 1 { + t.Fatal("presentation did not queue one announcement") + } + if err := worker.deliver(context.Background(), <-queue.requests); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(speaker.parts, test.want) { + t.Fatalf("backend chunks = %q, want %q", speaker.parts, test.want) + } + }) + } +} + +type PauseWaitSpeaker struct { + spellingTestSpeaker + voices []string + progress []int + line int +} + +func TestPauseChunksIncludeMnemonics(t *testing.T) { + for _, enabled := range []bool{false, true} { + settings := config.DefaultSettings() + settings.EnableSound = false + settings.Reading.EnablePauseBreaks = enabled + live := &liveSettings{} + live.Store(settings) + logger := slog.New(slog.DiscardHandler) + queue := &fakeSpeechQueue{spoken: make(chan string, 1), requests: make(chan speechRequest, 1)} + presenter := eventPresenter{state: &eventLoopState{}, logger: logger, speech: queue, live: live} + presenter.speak(atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{ + Name: "Open", Role: "button", Mnemonic: "o", + })) + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(logger, speaker) + if err := worker.deliver(context.Background(), <-queue.requests); err != nil { + t.Fatal(err) + } + want := []string{"Open button Alt o"} + if enabled { + want = []string{"Open", "button", "Alt o"} + } + if !reflect.DeepEqual(speaker.parts, want) { + t.Fatalf("pause breaks=%v: speech=%q, want %q", enabled, speaker.parts, want) + } + } +} + +func (speaker *PauseWaitSpeaker) SpeakVoiceAndWait(ctx context.Context, text, voice string, began func()) error { + if began != nil { + began() + } + speaker.voices = append(speaker.voices, voice) + speaker.progress = append(speaker.progress, speaker.line) + return speaker.Speak(ctx, text) +} + +func (speaker *PauseWaitSpeaker) SpeakAndWait(ctx context.Context, text string, began func()) error { + return speaker.SpeakVoiceAndWait(ctx, text, "default", began) +} + +func TestPauseChunksSayAllKeepsLineProgressAndVoice(t *testing.T) { + for _, enabled := range []bool{true, false} { + for _, style := range []string{"line", "sentence"} { + speaker := &PauseWaitSpeaker{line: -1} + settings := config.DefaultSettings() + settings.Reading.EnablePauseBreaks = enabled + settings.Reading.EnableIndentation = true + settings.SayAllStyle = style + queue := &fakeSpeechQueue{spoken: make(chan string, 1), requests: make(chan speechRequest, 1)} + lines := []atspi.DocumentLine{ + {Contents: []atspi.DocumentContent{{Text: "First, sentence. Second!", RawText: " First, sentence. Second!", + Snapshot: atspi.Snapshot{Path: "/link", Role: "link", Visited: true}}}}, + {Contents: []atspi.DocumentContent{{Text: "Next line", Snapshot: atspi.Snapshot{Path: "/text", Role: "text"}}}}, + } + var callbacks []int + result := review.Result{ReadAllContext: context.Background(), ReadAllLines: lines, + ReadAllProgress: func(line int) { callbacks = append(callbacks, line); speaker.line = line }} + presentReadAllResult(slog.New(slog.DiscardHandler), queue, result, presentationSettingsFromConfig(settings, true)) + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.reading = func() config.ReadingSettings { return settings.Reading } + if err := worker.deliver(context.Background(), <-queue.requests); err != nil { + t.Fatal(err) + } + want := []string{"indentation 2 columns, First, sentence. Second!", "visited link", "indentation 0 columns, Next line"} + wantProgress := []int{0, 0, 1} + wantVoices := []string{"hyperlink", "hyperlink", "default"} + if !enabled { + want = []string{"indentation 2 columns, First, sentence. Second! visited link", "indentation 0 columns, Next line"} + wantProgress, wantVoices = []int{0, 1}, []string{"hyperlink", "default"} + } + if style == "sentence" { + want[0] = "indentation 2 columns, First, sentence." + second := "Second!" + if !enabled { + want = []string{want[0], second, "visited link", want[1]} + } else { + want = []string{want[0], second, want[1], want[2]} + } + wantProgress, wantVoices = []int{0, 0, 0, 1}, []string{"hyperlink", "hyperlink", "hyperlink", "default"} + } + if !reflect.DeepEqual(speaker.parts, want) || !reflect.DeepEqual(speaker.progress, wantProgress) || + !reflect.DeepEqual(speaker.voices, wantVoices) || !reflect.DeepEqual(callbacks, []int{0, 1}) { + t.Fatalf("enabled=%v style=%s: speech=%v progress=%v voices=%v callbacks=%v", enabled, style, + speaker.parts, speaker.progress, speaker.voices, callbacks) + } + } + } +} diff --git a/internal/app/pending_presentation.go b/internal/app/pending_presentation.go new file mode 100644 index 0000000..ba69b71 --- /dev/null +++ b/internal/app/pending_presentation.go @@ -0,0 +1,61 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" +) + +// pendingPresentation owns one coalesced event and its captured input intent. +// Only the main event loop accesses it; timers never run presentation callbacks. +// Replacing or clearing an event disconnects its old timer from the select loop. +type pendingPresentation struct { + event atspi.Event + intent input.Intent + timer *time.Timer + ready <-chan time.Time +} + +func (pending *pendingPresentation) schedule(event atspi.Event, intent input.Intent, delay time.Duration) { + pending.clear() + pending.event, pending.intent = event, intent + pending.timer = time.NewTimer(delay) + pending.ready = pending.timer.C +} + +func (pending *pendingPresentation) clear() { + if pending.timer != nil { + pending.timer.Stop() + } + *pending = pendingPresentation{} +} + +func (pending *pendingPresentation) take() (atspi.Event, input.Intent) { + event, intent := pending.event, pending.intent + pending.clear() + return event, intent +} + +// pendingPresentations bounds delayed presentation to one event per family. +// Its lifetime is the event loop's lifetime, including adapter closure. +type pendingPresentations struct { + caret pendingPresentation + terminalFocus pendingPresentation + terminalDeletion pendingPresentation + browserButtonName pendingBrowserButtonName + radioSound pendingRadioSound +} + +func (pending *pendingPresentations) clear() { + pending.caret.clear() + pending.terminalFocus.clear() + pending.terminalDeletion.clear() + pending.browserButtonName.clear() + pending.radioSound.clear() +} diff --git a/internal/app/phonetic_hints.go b/internal/app/phonetic_hints.go new file mode 100644 index 0000000..c0ea6c5 --- /dev/null +++ b/internal/app/phonetic_hints.go @@ -0,0 +1,67 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "time" + "unicode/utf8" +) + +const phoneticHintDelay = 300 * time.Millisecond + +// The speech owner retains the hint with its character request. Waiting here +// keeps output ordered without blocking input or accessibility event handling; +// the normal input, settings, secure-session and shutdown barriers cancel it. +func (worker *speechWorker) deliver_phonetic_hint(ctx context.Context, request speechRequest) (bool, error) { + if !request.PhoneticHint || !request.Character || request.Role == "password text" || + worker.reading == nil || !worker.reading().PhoneticCharacterHints || worker.inputActivity == nil { + return false, nil + } + activity := worker.inputActivity() + letter, size := utf8.DecodeRuneInString(request.Text) + if !activity.PlainCharacterArrow || size != len(request.Text) || phoneticLetter(letter) == "" { + return false, nil + } + request.PhoneticHint = false + if err := worker.deliver(ctx, request); err != nil { + return true, err + } + hintContext, cancelHint := context.WithCancel(ctx) + defer cancelHint() + worker.mutex.Lock() + if worker.generation != request.deliveryGeneration { + worker.mutex.Unlock() + return true, context.Canceled + } + worker.hintCancel = cancelHint + worker.mutex.Unlock() + defer func() { + worker.mutex.Lock() + worker.hintCancel = nil + worker.mutex.Unlock() + }() + timer := time.NewTimer(phoneticHintDelay) + defer timer.Stop() + select { + case <-hintContext.Done(): + return true, hintContext.Err() + case <-timer.C: + } + worker.mutex.Lock() + interrupted := worker.generation != request.deliveryGeneration + worker.mutex.Unlock() + if interrupted || worker.inputActivity().InputSequence != activity.InputSequence || !worker.reading().PhoneticCharacterHints { + return true, nil + } + hint := speechRequest{ + // The character already presented its capital cues. This hint only + // clarifies its identity, using the normal voice even in links or Wine. + Text: phoneticLetter(letter), VoiceType: "default", Role: request.Role, Cause: "phonetic-character-hint", Append: true, + Window: request.Window, ExcludeFromHistory: request.ExcludeFromHistory, + deliveryGeneration: request.deliveryGeneration, + } + return true, worker.deliver(hintContext, hint) +} diff --git a/internal/app/phonetic_hints_test.go b/internal/app/phonetic_hints_test.go new file mode 100644 index 0000000..a2f53f4 --- /dev/null +++ b/internal/app/phonetic_hints_test.go @@ -0,0 +1,132 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "reflect" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestPhoneticHintsDelayAndEligibility(t *testing.T) { + for _, test := range []struct { + name, text string + enabled, arrow, eligible bool + want []string + }{ + {"enabled", "a", true, true, true, []string{"a", "alpha"}}, + {"capital", "A", true, true, true, []string{"A", "alpha"}}, + {"disabled", "a", false, true, true, []string{"a"}}, + {"modified arrow or Home", "a", true, false, true, []string{"a"}}, + {"typing or flat review", "a", true, true, false, []string{"a"}}, + {"space", "space", true, true, true, []string{"space"}}, + {"punctuation", "!", true, true, true, []string{"!"}}, + {"non Latin letter", "猫", true, true, true, []string{"猫"}}, + } { + t.Run(test.name, func(t *testing.T) { + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.reading = func() config.ReadingSettings { return config.ReadingSettings{PhoneticCharacterHints: test.enabled} } + worker.inputActivity = func() input.Activity { return input.Activity{PlainCharacterArrow: test.arrow, InputSequence: 1} } + start := time.Now() + if err := worker.deliver(context.Background(), speechRequest{Text: test.text, Character: true, PhoneticHint: test.eligible}); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(speaker.parts, test.want) { + t.Fatalf("speech = %v, want %v", speaker.parts, test.want) + } + if len(test.want) == 2 && time.Since(start) < phoneticHintDelay { + t.Fatal("hint arrived before its delay") + } + if !reflect.DeepEqual(speaker.characters, []string{test.text}) { + t.Fatalf("character speech changed: %v", speaker.characters) + } + }) + } +} + +type phoneticHintSpeaker struct{ parts chan string } + +func (*phoneticHintSpeaker) Connect(context.Context) error { return nil } +func (*phoneticHintSpeaker) Close(context.Context) error { return nil } +func (*phoneticHintSpeaker) Cancel(context.Context) error { return nil } +func (speaker *phoneticHintSpeaker) Speak(_ context.Context, text string) error { + speaker.parts <- text + return nil +} +func (speaker *phoneticHintSpeaker) SpeakCharacter(ctx context.Context, text string) error { + return speaker.Speak(ctx, text) +} + +func TestPhoneticHintFreshInputDoesNotWaitForDelay(t *testing.T) { + speaker := &phoneticHintSpeaker{parts: make(chan string, 4)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.reading = func() config.ReadingSettings { return config.ReadingSettings{PhoneticCharacterHints: true} } + worker.inputActivity = func() input.Activity { return input.Activity{PlainCharacterArrow: true, InputSequence: 1} } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.Enqueue(speechRequest{Text: "a", Character: true, PhoneticHint: true}) + if got := <-speaker.parts; got != "a" { + t.Fatal(got) + } + // Wait for the delay to be owned, then exercise the real input barrier. + deadline := time.After(time.Second) + for { + worker.mutex.Lock() + waiting := worker.hintCancel != nil + worker.mutex.Unlock() + if waiting { + break + } + select { + case <-deadline: + t.Fatal("hint delay was never registered") + case <-time.After(time.Millisecond): + } + } + if !worker.InterruptForInput(input.NewKeyEvent(1, true, "Right")) { + t.Fatal("fresh arrow did not interrupt pending hint") + } + worker.Enqueue(speechRequest{Text: "next"}) + select { + case got := <-speaker.parts: + if got != "next" { + t.Fatalf("stale hint survived fresh input: %q", got) + } + case <-time.After(200 * time.Millisecond): + t.Fatal("fresh input waited for the phonetic delay") + } +} + +func TestCharacterNavigationMarksHintEligibility(t *testing.T) { + queue := &fakeSpeechQueue{requests: make(chan speechRequest, 8), spoken: make(chan string, 8)} + state := &eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + presenter := eventPresenter{state: state, logger: slog.New(slog.DiscardHandler), speech: queue} + presenter.speak(atspi.Event{Type: atspi.CaretEvent, Source: atspi.Snapshot{Path: "/entry", Role: "entry", CaretCharacter: "a"}}) + if request := <-queue.requests; !request.PhoneticHint || !request.Character { + t.Fatalf("native character = %+v", request) + } + for _, command := range []review.DocumentCaretCommand{review.CaretNextCharacter, review.CaretPreviousCharacter, review.CaretLineStart, review.CaretNextWord} { + presentDocumentCaretResult(slog.New(slog.DiscardHandler), queue, review.Result{Moved: true, DocumentCaretCommand: command, DocumentCaretText: "a"}, presentation.DefaultOptions()) + request := <-queue.requests + want := command == review.CaretNextCharacter || command == review.CaretPreviousCharacter + if request.PhoneticHint != want { + t.Fatalf("%v hint = %t", command, request.PhoneticHint) + } + } +} diff --git a/internal/app/preferences.go b/internal/app/preferences.go new file mode 100644 index 0000000..afb53fc --- /dev/null +++ b/internal/app/preferences.go @@ -0,0 +1,186 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "strings" + "sync" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/speech" + "git.stormux.org/storm/cthulhu/internal/tentacle" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type speechSettingsUpdater interface { + UpdateSettings(context.Context, speech.Settings) error +} + +type brailleSettingsUpdater interface { + Configure(context.Context, bool) error +} + +// preferencesWorker owns session settings and at most one UI child. Open has a +// capacity-one, coalescing mailbox: repeated commands cannot queue windows or +// block input. The child permits one outstanding apply; messages are capped at +// 512 KiB. Shutdown cancels backend I/O, terminates the child, and joins the worker. +type preferencesWorker struct { + tentacles *tentacleRuntime + logger *slog.Logger + stagedReader *readerTransaction + extensionRequests chan readerSettingsCall + extensions map[string]*readerExtension + pageStore *tentacle.PageStore + savedPages tentacle.PageValues + pageLoadError error + speechOverride *tentaclewire.SpeechConfiguration + speechOverrideOwner string + extensionRevision uint64 + quickSettingKey string + settings config.Settings + globalSettings config.Settings + appSettings map[string]config.Settings + activeApp string + editApp string + editing config.Settings + editingActive bool + choosingApplication bool + updater any + open chan string + applicationChanges chan string + done chan struct{} + cancel context.CancelFunc + once sync.Once + live *liveSettings + history *speechHistory + speechWorker *speechWorker + refreshHistory func() + sound soundSettingsUpdater + geometry soundGeometryCaptureConfigurer + textAttributes textAttributeCaptureConfigurer + bindings interface { + SetKeyBindings(context.Context, []input.BindingOverride) error + } + braille brailleSettingsUpdater + documentReview *review.Worker + socket string + speechCommands chan input.Command + remoteChanges chan remoteSettingsChange + speechSetting int + announce func(string) + announceApply func(string) + announceEchoPreview func(string, string) + catalog speech.Catalog + discover func(context.Context, string) (speech.Catalog, error) + readSpeechDefaults func(context.Context, string) (speech.Settings, error) +} + +func newPreferencesWorker(logger *slog.Logger, settings config.Settings, updater any) *preferencesWorker { + return &preferencesWorker{logger: logger, settings: settings, globalSettings: settings, appSettings: make(map[string]config.Settings), updater: updater, + extensionRequests: make(chan readerSettingsCall, 16), extensions: make(map[string]*readerExtension), speechCommands: make(chan input.Command, 16), remoteChanges: make(chan remoteSettingsChange, 16), discover: speech.Discover, readSpeechDefaults: speech.ReadDefaults, open: make(chan string, 1), applicationChanges: make(chan string, 1), done: make(chan struct{})} +} + +func (worker *preferencesWorker) Start(ctx context.Context) error { + ctx, worker.cancel = context.WithCancel(ctx) + go func() { + defer close(worker.done) + for { + select { + case <-ctx.Done(): + return + case <-worker.extension_changes(): + worker.sync_extensions(ctx) + case call := <-worker.extensionRequests: + worker.handle_reader_call(ctx, call, false) + case command := <-worker.speechCommands: + worker.handleSpeechCommand(ctx, command) + case change := <-worker.remoteChanges: + change.result <- worker.applyRemoteChange(ctx, change) + case application := <-worker.applicationChanges: + worker.switchApplication(ctx, application) + case application := <-worker.open: + worker.choosingApplication = application == "\x01" + if application != "\x01" && !worker.beginEdit(ctx, application) { + continue + } + if err := worker.window(ctx); err != nil && ctx.Err() == nil { + worker.logger.Error("preferences window", "error", err) + } + worker.editingActive = false + worker.choosingApplication = false + select { + case application := <-worker.applicationChanges: + worker.switchApplication(ctx, application) + default: + } + } + } + }() + return nil +} + +func (worker *preferencesWorker) Open() { + select { + case worker.open <- "": + default: + } +} + +func (worker *preferencesWorker) OpenApplication() { + select { + case worker.open <- "\x00": + default: + } +} + +func (worker *preferencesWorker) ChooseApplication() { + select { + case worker.open <- "\x01": + default: + } +} + +// Focus handling only publishes the latest foreground application and never +// waits for settings I/O on the native event loop. +func (worker *preferencesWorker) SetApplication(application string) { + application = strings.TrimSpace(application) + if application == "" || strings.HasPrefix(strings.ToLower(application), "cthulhu") { + return + } + if worker.live != nil { + worker.live.requestedApplication.Store(&application) + worker.live.notify_clipboard() + } + select { + case worker.applicationChanges <- application: + default: + select { + case <-worker.applicationChanges: + default: + } + select { + case worker.applicationChanges <- application: + default: + } + } +} + +func (worker *preferencesWorker) Stop(ctx context.Context) error { + worker.once.Do(func() { + if worker.cancel != nil { + worker.cancel() + } + }) + select { + case <-worker.done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} diff --git a/internal/app/preferences_application.go b/internal/app/preferences_application.go new file mode 100644 index 0000000..eeddd58 --- /dev/null +++ b/internal/app/preferences_application.go @@ -0,0 +1,87 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "strings" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +func (worker *preferencesWorker) applicationSettings(application string) (config.Settings, error) { + if settings, ok := worker.appSettings[application]; ok { + return settings, nil + } + store, err := config.NewStore(worker.globalSettings.Path) + if err != nil { + return config.Settings{}, err + } + persistedGlobal, err := store.Load() + if err != nil { + return config.Settings{}, err + } + settings, mapped, err := store.LoadForApplication(application) + if err != nil { + return config.Settings{}, err + } + if !mapped { + return worker.globalSettings, nil + } + settings = config.RebaseApplicationSettings(persistedGlobal, worker.globalSettings, settings) + worker.appSettings[application] = settings + return settings, nil +} + +func (worker *preferencesWorker) switchApplication(ctx context.Context, application string) { + application = strings.TrimSpace(application) + if application == "" || application == worker.activeApp { + return + } + settings, err := worker.applicationSettings(application) + if err == nil { + err = worker.applyRuntime(ctx, settings) + } + if err != nil { + worker.logger.Error("switch application settings", "application", application, "error", err) + return + } + worker.activeApp = application + if worker.live != nil { + worker.live.application.Store(&application) + worker.live.notify_clipboard() + } +} + +func (worker *preferencesWorker) beginEdit(ctx context.Context, application string) bool { + // A focus event and its shortcut can arrive on separate goroutines. Use the + // latest accepted focus before deciding which application to edit. + select { + case focused := <-worker.applicationChanges: + worker.switchApplication(ctx, focused) + default: + } + if application == "\x00" { + application = worker.activeApp + if application == "" { + worker.announceSpeechSetting("No active application for application preferences.") + return false + } + } + worker.editApp = application + worker.editingActive = true + worker.editing = worker.globalSettings + if application != "" { + settings, err := worker.applicationSettings(application) + if err != nil { + worker.logger.Error("load application settings", "application", application, "error", err) + worker.announceSpeechSetting("Could not load application preferences.") + worker.editingActive = false + return false + } + worker.editing = settings + } + return true +} diff --git a/internal/app/preferences_application_test.go b/internal/app/preferences_application_test.go new file mode 100644 index 0000000..4ace5f4 --- /dev/null +++ b/internal/app/preferences_application_test.go @@ -0,0 +1,87 @@ +package app + +import ( + "context" + "log/slog" + "path/filepath" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +func TestApplicationPreferencesSwitchAndPersistIndependently(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + global := config.DefaultSettings() + global.Path = path + store, err := config.NewStore(path) + if err != nil { + t.Fatal(err) + } + if err := store.Save(global); err != nil { + t.Fatal(err) + } + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), global, + settingsUpdateFunc(func(context.Context, speech.Settings) error { return nil })) + worker.live = &liveSettings{} + worker.live.Store(global) + ctx := context.Background() + worker.switchApplication(ctx, "Example Editor") + if !worker.beginEdit(ctx, "\x00") || worker.editApp != "Example Editor" { + t.Fatal("application shortcut did not select focused application") + } + values := preferences.FromSettings(worker.editing) + values.TimeFormat = "24-hour" + values.Reading.AutomaticallyReadClipboardChanges = true + response := worker.apply(ctx, preferences.Request{Values: values, Save: true}) + if !response.Accepted || worker.settings.TimeFormat != "24-hour" || !worker.settings.Reading.AutomaticallyReadClipboardChanges { + t.Fatalf("application settings were not applied: %+v", response) + } + worker.editingActive = false + worker.switchApplication(ctx, "Other Editor") + if worker.settings.TimeFormat != global.TimeFormat || worker.settings.Reading.AutomaticallyReadClipboardChanges { + t.Fatal("application settings leaked to another application") + } + worker.switchApplication(ctx, "Example Editor") + if worker.settings.TimeFormat != "24-hour" || worker.live.Load().TimeFormat != "24-hour" { + t.Fatal("application settings were not restored on return") + } + worker.handleSpeechCommand(ctx, input.IncreaseSpeechSetting) + worker.handleSpeechCommand(ctx, input.SaveSpeechSettings) + if !worker.beginEdit(ctx, "") { + t.Fatal("global preferences did not open") + } + globalValues := preferences.FromSettings(worker.editing) + globalValues.DateFormat = "numbers-mdy" + if response := worker.apply(ctx, preferences.Request{Values: globalValues, Save: true}); !response.Accepted { + t.Fatalf("global setting was not applied: %+v", response) + } + worker.editingActive = false + if worker.settings.TimeFormat != "24-hour" || worker.settings.DateFormat != "numbers-mdy" { + t.Fatalf("application session did not inherit global date: %+v", worker.settings) + } + loaded, err := store.Load() + if err != nil || loaded.TimeFormat != global.TimeFormat || loaded.DateFormat != "numbers-mdy" { + t.Fatalf("global profile changed: %+v, %v", loaded, err) + } + appLoaded, mapped, err := store.LoadForApplication("Example Editor") + if err != nil || !mapped || appLoaded.TimeFormat != "24-hour" || appLoaded.DateFormat != "numbers-mdy" || appLoaded.DefaultVoice.Rate == nil || !appLoaded.Reading.AutomaticallyReadClipboardChanges { + t.Fatalf("application profile not saved: %+v, %t, %v", appLoaded, mapped, err) + } + if loaded.DefaultVoice.Rate != nil || loaded.Reading.AutomaticallyReadClipboardChanges { + t.Fatal("application speech shortcut overwrote global voice") + } + restarted := newPreferencesWorker(slog.New(slog.DiscardHandler), loaded, + settingsUpdateFunc(func(context.Context, speech.Settings) error { return nil })) + sessionGlobal := loaded + sessionGlobal.DateFormat = "numbers-dmy" + if response := restarted.applyNext(ctx, sessionGlobal, false, false); !response.Accepted { + t.Fatalf("session global change rejected: %+v", response) + } + restarted.switchApplication(ctx, "Example Editor") + if restarted.settings.DateFormat != "numbers-dmy" || restarted.settings.TimeFormat != "24-hour" || !restarted.settings.Reading.AutomaticallyReadClipboardChanges { + t.Fatalf("first application load lost session inheritance: %+v", restarted.settings) + } +} diff --git a/internal/app/preferences_apply.go b/internal/app/preferences_apply.go new file mode 100644 index 0000000..f6e05c0 --- /dev/null +++ b/internal/app/preferences_apply.go @@ -0,0 +1,263 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "reflect" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +func (worker *preferencesWorker) response(message string, accepted bool) preferences.Response { + settings := worker.settings + if worker.editingActive { + settings = worker.editing + } + store, err := config.NewStore(settings.Path) + if err == nil { + _, err = store.Load() + } + return preferences.Response{Values: preferences.FromSettings(settings), ExtensionPages: worker.extension_pages(), CanSave: err == nil, + Message: message, Accepted: accepted} +} + +func (worker *preferencesWorker) apply(ctx context.Context, request preferences.Request) preferences.Response { + base := worker.settings + if worker.editingActive { + base = worker.editing + } + next, err := request.Values.Merge(base) + if err != nil { + return worker.response("Settings were not applied: "+err.Error(), false) + } + transaction, err := worker.prepare_extension_pages(ctx, request.ExtensionPages) + if err != nil { + return worker.response("Tentacle settings were not applied: "+err.Error(), false) + } + worker.stagedReader = &transaction + defer func() { worker.stagedReader = nil }() + response := worker.applyNext(ctx, next, request.Save, request.Close) + if response.Accepted && request.Save && len(request.ExtensionPages) > 0 { + if err := worker.save_extension_pages(); err != nil { + response.Message = "Applied for this session, but tentacle preferences could not be saved: " + err.Error() + response.Close = false + } + } + return response +} + +func (worker *preferencesWorker) applyNext(ctx context.Context, next config.Settings, save, close bool) preferences.Response { + scopeApp := worker.activeApp + if worker.editingActive { + scopeApp = worker.editApp + } + if err := config.Validate(next); err != nil { + return worker.response("Settings were not applied: "+err.Error(), false) + } + if save && !worker.response("", false).CanSave { + return worker.response("This settings file cannot be saved by the Go preview. Use Apply for this session.", false) + } + if err := worker.applyRuntime(ctx, next); err != nil { + return worker.response(err.Error(), false) + } + if worker.editingActive { + worker.editing = next + } + if scopeApp != "" { + worker.appSettings[scopeApp] = next + } else { + oldGlobal := worker.globalSettings + for application, settings := range worker.appSettings { + worker.appSettings[application] = config.RebaseApplicationSettings(oldGlobal, next, settings) + } + worker.globalSettings = next + } + message := "Settings applied for this session." + if save { + store, err := config.NewStore(next.Path) + if err == nil { + if scopeApp != "" { + err = store.SaveForApplication(scopeApp, next) + } else { + err = store.Save(next) + } + } + if err != nil { + message = "Applied for this session, but could not save: " + err.Error() + } else { + message = "Settings applied and saved." + } + } + response := worker.response(message, true) + response.Close = close && save && message == "Settings applied and saved." + if worker.editingActive && worker.editApp != worker.activeApp { + previousApp := worker.activeApp + worker.activeApp = "" + if previousApp != "" { + worker.switchApplication(ctx, previousApp) + } + } + return response +} + +func (worker *preferencesWorker) applyRuntime(ctx context.Context, next config.Settings) error { + keyboardChanged := next.KeyboardLayout != worker.settings.KeyboardLayout || !reflect.DeepEqual(next.CthulhuModifierKeys, worker.settings.CthulhuModifierKeys) + bindingsChanged := keyboardChanged || !reflect.DeepEqual(next.KeyBindings, worker.settings.KeyBindings) + bindingsCommitted := false + if bindingsChanged { + if worker.bindings == nil { + return errors.New("Key bindings cannot be changed by this input backend.") + } + if err := worker.apply_keyboard(ctx, next, keyboardChanged); err != nil { + return errors.New("Key bindings were not applied: " + err.Error()) + } + defer func() { + if !bindingsCommitted { + rollbackCtx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := worker.apply_keyboard(rollbackCtx, worker.settings, keyboardChanged); err != nil { + worker.logger.Error("restore key bindings after failed preferences apply", "error", err) + } + } + }() + } + effectiveNext := worker.effective_settings(next) + effectiveCurrent := worker.effective_settings(worker.settings) + if worker.stagedReader != nil { + for _, extension := range worker.stagedReader.extensions { + if err := worker.reader_allowed(ctx, extension.session); err != nil { + return err + } + } + effectiveNext = next + if worker.stagedReader.override != nil { + effectiveNext = worker.stagedReader.override.Apply(next) + } + } + speechChanged := !reflect.DeepEqual(tentaclewire.SpeechFromSettings(effectiveNext), tentaclewire.SpeechFromSettings(effectiveCurrent)) + speechApplied := false + defer func() { + if speechApplied && !bindingsCommitted { + restoreCtx, cancel := context.WithTimeout(context.Background(), 6*time.Second) + defer cancel() + if err := worker.updateSpeech(restoreCtx, effectiveCurrent); err != nil { + worker.logger.Error("restore speech after failed preferences apply", "error", err) + } + } + }() + if next.EnableSpeech && (speechChanged || !worker.settings.EnableSpeech) { + if message := worker.apply_speech_settings(ctx, effectiveNext); message != "" { + return errors.New(message) + } + speechApplied = true + } + if next.EnableBraille != worker.settings.EnableBraille { + if worker.braille == nil { + return errors.New("Braille is unavailable in this build.") + } + if err := worker.braille.Configure(ctx, next.EnableBraille); err != nil { + return errors.New("Braille settings were not applied: " + err.Error()) + } + } + if next.EnableContractedBraille != worker.settings.EnableContractedBraille || + next.BrailleContractionTable != worker.settings.BrailleContractionTable { + if updater, ok := worker.braille.(interface{ SetContraction(bool, string) }); ok { + updater.SetContraction(next.EnableContractedBraille, next.BrailleContractionTable) + } + } + if worker.stagedReader != nil { + for _, extension := range worker.stagedReader.extensions { + if err := worker.reader_allowed(ctx, extension.session); err != nil { + return err + } + } + worker.extensions = worker.stagedReader.extensions + worker.speechOverride, worker.speechOverrideOwner = worker.stagedReader.override, worker.stagedReader.owner + } + bindingsCommitted = true + worker.commit_settings(next) + return nil +} + +func (worker *preferencesWorker) apply_keyboard(ctx context.Context, settings config.Settings, keyboardChanged bool) error { + if updater, ok := worker.bindings.(interface { + SetKeyboardConfiguration(context.Context, input.KeyboardLayout, []string, []input.BindingOverride) error + }); ok { + return updater.SetKeyboardConfiguration(ctx, input.KeyboardLayout(settings.KeyboardLayout), settings.CthulhuModifierKeys, settings.KeyBindings) + } + if keyboardChanged { + return errors.New("this input backend cannot change Cthulhu keys or keyboard layout") + } + return worker.bindings.SetKeyBindings(ctx, settings.KeyBindings) +} + +func (worker *preferencesWorker) apply_speech_settings(ctx context.Context, next config.Settings) string { + var err error + + if worker.updater == nil { + return "Speech is disabled or this backend cannot change settings." + } + if updater, ok := worker.updater.(interface { + UpdateConfiguration(context.Context, config.Settings) error + }); ok { + err = updater.UpdateConfiguration(ctx, next) + } else if updater, ok := worker.updater.(speechSettingsUpdater); ok { + if next.UseCustomEchoVoice { + return "This speech backend cannot use a custom echo voice." + } + err = updater.UpdateSettings(ctx, speechSettingsFromConfig(next)) + } else { + return "This backend cannot change speech settings." + } + if err != nil { + return "Settings were not applied: " + err.Error() + } + return "" +} + +// Commit follows the existing backend updates and keyboard rollback boundary. +// It publishes settings to runtime consumers without changing their ownership. +func (worker *preferencesWorker) commit_settings(next config.Settings) { + soundChanged := soundConfiguration(next) != soundConfiguration(worker.settings) + worker.settings = next + if updater, ok := worker.braille.(interface{ SetWordWrap(bool) }); ok { + updater.SetWordWrap(next.Braille.WordWrap) + } + if worker.speechWorker != nil && !next.EnableSpeech { + worker.speechWorker.SetEnabled(false) + } + if worker.history != nil { + worker.history.setLimit(next.SpeechHistoryLimit) + if worker.refreshHistory != nil { + worker.refreshHistory() + } + } + if worker.documentReview != nil { + worker.documentReview.SetDocumentBrailleEnabled(next.EnableBraille) + } + // Configure cancels playback. An application switch or unrelated setting + // must leave the startup cue running when its sound policy is unchanged. + if worker.sound != nil && soundChanged { + worker.sound.Configure(soundConfiguration(next)) + } + if worker.geometry != nil { + worker.geometry.SetCaptureSoundGeometry(captureSoundGeometry(next)) + } + if worker.textAttributes != nil { + worker.textAttributes.SetCaptureTextAttributes(captureTextAttributes(next)) + } + if worker.live != nil { + worker.live.Store(worker.effective_settings(next)) + } + if worker.speechWorker != nil && next.EnableSpeech { + worker.speechWorker.SetEnabled(true) + } +} diff --git a/internal/app/preferences_echo_preview_test.go b/internal/app/preferences_echo_preview_test.go new file mode 100644 index 0000000..312e0b1 --- /dev/null +++ b/internal/app/preferences_echo_preview_test.go @@ -0,0 +1,276 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + "reflect" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" +) + +type echoPreviewUpdater func(context.Context, config.Settings) error + +func (update echoPreviewUpdater) UpdateConfiguration(ctx context.Context, settings config.Settings) error { + return update(ctx, settings) +} + +func TestPreferencesEchoSliderPreviewsDraftWithoutChangingMainVoice(t *testing.T) { + settings := config.DefaultSettings() + settings.SpeechOutputModule = "main-module" + updater := &voiceConfigurationRecorder{} + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, updater) + live := &liveSettings{} + live.Store(settings) + worker.live = live + values := preferences.FromSettings(settings) + rate, pitch, volume := 78.2, 6.3, 10.0 + values.UseCustomEchoVoice, values.UseCustomEchoSpeechServer = true, true + values.EchoSpeechServer = "echo-module" + values.EchoVoice = config.Voice{Rate: &rate, AveragePitch: &pitch, Gain: &volume, + Family: &config.VoiceFamily{Name: "Echo voice", Lang: "en"}} + // Unapplied Speech-tab choices must not become the normal dialog voice. + values.SpeechOutputModule = "unapplied-module" + values.VoiceType = "uppercase" + values.Rate = &rate + for _, test := range []struct{ slider, want string }{{"rate", "78.2"}, {"pitch", "6.3"}, {"volume", "10.0"}, {"synthesizer", "echo-module"}, {"person", "Echo voice (en)"}} { + announced := "" + worker.announceEchoPreview = func(_ string, value string) { + if updater.calls == 0 || !reflect.DeepEqual(updater.settings.EchoVoice, values.EchoVoice) { + t.Fatal("value announced before installing draft echo voice") + } + announced = value + } + response := worker.preview(t.Context(), preferences.Request{Values: values, Preview: true, EchoPreview: test.slider}) + if !response.Accepted || !response.Preview || announced != test.want { + t.Fatalf("%s: response=%+v speech=%q", test.slider, response, announced) + } + if updater.settings.SpeechOutputModule != settings.SpeechOutputModule || + !reflect.DeepEqual(updater.settings.DefaultVoice, settings.DefaultVoice) || + !reflect.DeepEqual(updater.settings.SystemVoice, settings.SystemVoice) { + t.Fatal("echo preview changed ordinary voices") + } + if updater.settings.EchoSpeechServer != "echo-module" || !updater.settings.UseCustomEchoVoice { + t.Fatal("echo preview ignored the selected module") + } + if !reflect.DeepEqual(worker.settings, settings) || !reflect.DeepEqual(live.Load(), settings) { + t.Fatal("preview committed session or live settings") + } + } + if response := worker.restorePreview(t.Context()); !response.Accepted || !reflect.DeepEqual(updater.settings, settings) { + t.Fatal("Cancel did not restore committed speech settings") + } +} + +func TestPreferencesEchoPreviewRejectsInvalidDraftAndBackendFailure(t *testing.T) { + for _, test := range []string{"unknown slider", "disabled", "missing value", "out of range", "backend failure"} { + t.Run(test, func(t *testing.T) { + calls := 0 + settings := config.DefaultSettings() + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, echoPreviewUpdater(func(context.Context, config.Settings) error { + calls++ + return errors.New("preview unavailable") + })) + worker.announceEchoPreview = func(string, string) { t.Fatal("rejected preview spoke a value") } + values := preferences.FromSettings(settings) + volume := 5.0 + values.UseCustomEchoVoice = true + values.EchoVoice.Gain = &volume + request := preferences.Request{Values: values, Preview: true, EchoPreview: "volume"} + switch test { + case "unknown slider": + request.EchoPreview = "other" + case "disabled": + request.Values.UseCustomEchoVoice = false + case "missing value": + request.Values.EchoVoice.Gain = nil + case "out of range": + volume = 11 + } + if response := worker.preview(t.Context(), request); response.Accepted || !response.Preview { + t.Fatalf("invalid preview response: %+v", response) + } + wantCalls := 0 + if test == "backend failure" { + wantCalls = 1 + } + if calls != wantCalls { + t.Fatalf("backend updates=%d, want %d", calls, wantCalls) + } + }) + } +} + +func TestEchoPreviewValueKeepsBrailleWithoutDuplicateSpeech(t *testing.T) { + settings := config.DefaultSettings() + live := &liveSettings{} + live.Store(settings) + live.preferencesPID.Store(123) + source := atspi.Snapshot{BusName: ":1.42", Path: "/echo-volume", Name: "Key echo volume", + Role: "slider", Focused: true, ValueText: "5.0", ApplicationPID: 123} + state := &eventLoopState{} + state.current, state.focusedID = source, source.ID() + queue := &remoteSpeechQueue{} + frames := frameRecorder{frames: make(chan braille.Frame, 2)} + logger := slog.New(slog.DiscardHandler) + presenter := eventPresenter{state: state, logger: logger, speech: queue, live: live} + handler := accessibilityEventHandler{state: state, logger: logger, live: live, brailleOutput: frames} + for _, kind := range []string{atspi.ValueChangedEvent, atspi.AccessibleValueEvent} { + source.ValueText = "5.1" + event := atspi.NewEvent(kind, source) + handler.acceptFocusedEvent(event, input.Activity{}) + presenter.speak(event) + if len(queue.requests) != 0 { + t.Fatal("AT-SPI repeated the echo preview in the main voice") + } + if len(frames.frames) != 1 { + t.Fatal("echo preview suppressed Braille value updates") + } + if frame := <-frames.frames; !strings.Contains(frame.Text, "5.1") { + t.Fatalf("Braille did not receive the updated value: %+v", frame) + } + } + presenter.speak(atspi.NewEvent(atspi.FocusEvent, source)) + if len(queue.requests) != 0 { + t.Fatal("AT-SPI repeated the separately queued focus preview") + } +} + +func TestPreferencesEchoComboDefaultValuesUseDraftVoice(t *testing.T) { + settings := config.DefaultSettings() + updater := &voiceConfigurationRecorder{} + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, updater) + values := preferences.FromSettings(settings) + values.UseCustomEchoVoice, values.UseCustomEchoSpeechServer = true, true + values.EchoSpeechServer, values.EchoVoice.Family = "", nil + announced := "" + worker.announceEchoPreview = func(_ string, value string) { announced = value } + for _, control := range []string{"synthesizer", "person"} { + if response := worker.preview(t.Context(), preferences.Request{Values: values, Preview: true, EchoPreview: control}); !response.Accepted || announced != "Default" { + t.Fatalf("%s default preview: response=%+v text=%q", control, response, announced) + } + } +} + +func TestEchoPreviewGTKSelectedMenuItemCannotRepeat(t *testing.T) { + // Reproduce the native log sequence: combo focus, name update, then a + // selected menu-item snapshot whose OriginPath is the original combo. + for _, control := range []string{"Key echo speech synthesizer", "Key echo person"} { + settings := config.DefaultSettings() + live := &liveSettings{} + live.Store(settings) + live.preferencesPID.Store(123) + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + source := atspi.Snapshot{BusName: ":1.42", Path: "/combo", Role: "combo box", + Name: control, ValueText: "Default", Focused: true, ApplicationPID: 123} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, source) + source.ValueText = "Selected voice" + adapter.events <- atspi.NewEvent(atspi.AccessibleNameEvent, source) + selected := atspi.NewEvent(atspi.SelectionChangedEvent, atspi.Snapshot{BusName: source.BusName, + Path: "/selected", Name: "Selected voice", Role: "menu item", Selected: true}) + selected.OriginPath = source.Path + adapter.events <- selected + adapter.events <- atspi.NewEvent(atspi.AccessibleNameEvent, source) + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: source.BusName, + Path: "/apply", Name: "Apply", Role: "button", Focused: true}) + close(adapter.events) + queue := &remoteSpeechQueue{} + if err := processEventsWithSettings(t.Context(), slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, live); err != nil { + t.Fatal(err) + } + if len(queue.requests) != 1 || queue.requests[0].Text != "Apply, button" { + t.Fatalf("%s: native duplicate escaped preview ownership: %+v", control, queue.requests) + } + } +} + +func TestEchoPreviewSelectionOwnershipIsBoundedToChildAndControls(t *testing.T) { + preview := echoPreviewPresentation{} + source := atspi.Snapshot{BusName: ":1.42", Path: "/combo", Name: "Key echo person", Role: "combo box", ApplicationPID: 123} + if !preview.owns(atspi.NewEvent(atspi.FocusEvent, source), 123) { + t.Fatal("owned focus was not recognized") + } + selected := atspi.NewEvent(atspi.SelectionChangedEvent, atspi.Snapshot{BusName: source.BusName, Path: "/item", Role: "menu item"}) + selected.OriginPath = source.Path + if !preview.owns(selected, 123) { + t.Fatal("selected descendant was not recognized") + } + selected.Source.BusName = ":1.43" + if preview.owns(selected, 123) { + t.Fatal("selection in another application was suppressed") + } + selected.Source.BusName = source.BusName + selected.OriginPath = "/other-combo" + if preview.owns(selected, 123) { + t.Fatal("selection in another combo was suppressed") + } + selected.OriginPath = source.Path + if preview.owns(selected, 0) || preview.owns(selected, 456) { + t.Fatal("selection ownership survived preferences exit or replacement") + } + if preview.owns(atspi.NewEvent(atspi.FocusEvent, source), 456) { + t.Fatal("old child acquired the new preferences session") + } +} + +type echoPreviewWaitSpeaker struct{ controlledSpeaker } + +func (speaker *echoPreviewWaitSpeaker) SpeakAndWait(ctx context.Context, text string, _ func()) error { + return speaker.call(ctx, "default:"+text) +} + +func (speaker *echoPreviewWaitSpeaker) SpeakVoiceAndWait(ctx context.Context, text, voice string, _ func()) error { + return speaker.call(ctx, voice+":"+text) +} + +func TestEchoPreviewFocusSpeechWaitsForBothVoices(t *testing.T) { + speaker := &echoPreviewWaitSpeaker{controlledSpeaker{calls: make(chan speechCall, 8)}} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + worker.Enqueue(echo_preview_speech("Key echo person", "Selected voice")) + label := expectSpeechCall(t, &speaker.controlledSpeaker, "default:Key echo person") + worker.Enqueue(speechRequest{Text: "Later control"}) + select { + case call := <-speaker.calls: + t.Fatalf("queued output overtook the focus label: %s", call.text) + default: + } + close(label.done) + value := expectSpeechCall(t, &speaker.controlledSpeaker, "echo:Selected voice") + select { + case call := <-speaker.calls: + t.Fatalf("queued output cut off the echo value: %s", call.text) + default: + } + close(value.done) + close(expectSpeechCall(t, &speaker.controlledSpeaker, "Later control").done) +} + +func TestEchoPreviewFocusSpeechRemainsInterruptible(t *testing.T) { + speaker := &echoPreviewWaitSpeaker{controlledSpeaker{calls: make(chan speechCall, 8)}} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + worker.Enqueue(echo_preview_speech("Key echo person", "Selected voice")) + label := expectSpeechCall(t, &speaker.controlledSpeaker, "default:Key echo person") + close(label.done) + value := expectSpeechCall(t, &speaker.controlledSpeaker, "echo:Selected voice") + worker.InterruptForInput(input.Event{Pressed: true, Name: "Tab", Timestamp: 100}) + close(expectSpeechCall(t, &speaker.controlledSpeaker, "cancel").done) + close(value.done) +} diff --git a/internal/app/preferences_feedback_test.go b/internal/app/preferences_feedback_test.go new file mode 100644 index 0000000..47da097 --- /dev/null +++ b/internal/app/preferences_feedback_test.go @@ -0,0 +1,194 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "encoding/json" + "io" + "log/slog" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +type confirmationSpeaker struct{ controlledSpeaker } + +func (speaker *confirmationSpeaker) SpeakAndWait(ctx context.Context, text string, _ func()) error { + return speaker.call(ctx, text) +} + +func TestPreferencesConfirmationSurvivesAutomaticFocusUntilSpeechEnds(t *testing.T) { + speaker := &confirmationSpeaker{controlledSpeaker{calls: make(chan speechCall, 10)}} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + worker.Enqueue(speechRequest{Text: "Settings applied", Confirmation: true}) + confirmation := expectSpeechCall(t, &speaker.controlledSpeaker, "Settings applied") + worker.Enqueue(speechRequest{Text: "Window title"}) + worker.Enqueue(speechRequest{Text: "Focused control"}) + close(confirmation.done) // Represents the synth's END event, not SPEAK acknowledgement. + close(expectSpeechCall(t, &speaker.controlledSpeaker, "Window title").done) + close(expectSpeechCall(t, &speaker.controlledSpeaker, "Focused control").done) + worker.Enqueue(speechRequest{Text: "Later output"}) + close(expectSpeechCall(t, &speaker.controlledSpeaker, "Later output").done) +} + +func TestPreferencesConfirmationAllowsUserInterruption(t *testing.T) { + speaker := &confirmationSpeaker{controlledSpeaker{calls: make(chan speechCall, 10)}} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + display := &brailleWorker{wake: make(chan struct{}, 1), cancel: func() {}, connected: true} + display.EnqueueFrame(braille.Frame{Text: "Apply", Cursor: -1}) + display.FlashConfirmation("Settings applied", config.BrailleOptions{FlashMessages: true, FlashPersistent: true}) + display.EnqueueFrame(braille.Frame{Text: "Returned focus", Cursor: -1}) + gate := &focusGate{braille: display} + output := gatedSpeech{speech: worker, gate: gate} + worker.Enqueue(speechRequest{Text: "Settings applied", Confirmation: true}) + confirmation := expectSpeechCall(t, &speaker.controlledSpeaker, "Settings applied") + worker.Enqueue(speechRequest{Text: "Discarded focus"}) + if !output.InterruptForInput(input.Event{Pressed: true, Name: "Tab", Timestamp: 101}) { + t.Fatal("new user input did not interrupt") + } + if display.current().Text != "Returned focus" { + t.Fatal("new user input did not dismiss braille confirmation") + } + worker.mutex.Lock() + cleared := len(worker.pending) == 0 && worker.confirmationID == 0 + worker.mutex.Unlock() + if !cleared { + t.Fatal("user input retained speech confirmation or queued focus") + } + close(expectSpeechCall(t, &speaker.controlledSpeaker, "cancel").done) + close(confirmation.done) + close(expectSpeechCall(t, &speaker.controlledSpeaker, "cancel").done) +} + +func TestPreferencesBrailleConfirmationRestoresLatestFocusOnExpiry(t *testing.T) { + display := &brailleWorker{wake: make(chan struct{}, 1), cancel: func() {}, connected: true} + display.EnqueueFrame(braille.Frame{Text: "Apply", Cursor: -1}) + if !display.FlashConfirmation("Settings applied", config.BrailleOptions{FlashMessages: true, FlashTime: 20}) { + t.Fatal("confirmation was rejected") + } + <-display.wake + display.EnqueueFrame(braille.Frame{Text: "Window title", Cursor: -1}) + display.EnqueueFrame(braille.Frame{Text: "Latest focus", Cursor: 3}) + if display.current().Text != "Settings applied" { + t.Fatal("automatic focus replaced braille confirmation") + } + select { + case <-display.wake: + if frame := display.current(); frame.Text != "Latest focus" || frame.Cursor != 3 { + t.Fatalf("restored frame = %+v", frame) + } + case <-time.After(time.Second): + t.Fatal("confirmation did not expire") + } +} + +func TestPreferencesConfirmationRetiresOnScreenLock(t *testing.T) { + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.running = true + worker.Enqueue(speechRequest{Text: "Settings applied", Confirmation: true}) + display := &brailleWorker{wake: make(chan struct{}, 1), cancel: func() {}, connected: true} + options := config.BrailleOptions{FlashMessages: true, FlashPersistent: true} + display.EnqueueFrame(braille.Frame{Text: "Apply", Cursor: -1}) + display.FlashConfirmation("Settings applied", options) + worker.SetSecureInputActive(true) + display.SetSecureInputActive(true) + if len(worker.pending) != 0 || worker.confirmationID != 0 || display.protectedFlash || display.current().Text != "" { + t.Fatal("screen lock retained preferences confirmation") + } + if display.FlashConfirmation("Late confirmation", options) || display.protectedFlash { + t.Fatal("screen lock accepted late preferences confirmation") + } +} + +func TestPreferencesConfirmationAllowsCommandBeforeRecordedInput(t *testing.T) { + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.running = true + worker.ProtectCommand(100) + worker.Enqueue(speechRequest{Text: "Settings applied", Confirmation: true}) + worker.ProtectCommand(99) + if worker.confirmationID == 0 { + t.Fatal("older command interrupted confirmation") + } + worker.ProtectCommand(101) + if worker.confirmationID != 0 || len(worker.pending) != 0 { + t.Fatal("new command did not interrupt confirmation") + } + worker.Enqueue(speechRequest{Text: "Command result"}) + if worker.InterruptForInput(input.Event{Pressed: true, Timestamp: 101}) || len(worker.pending) != 1 { + t.Fatal("delayed initiating input discarded command result") + } +} + +func TestPreferencesApplyAnnouncesBeforeReplyAndPreservesSaveFailure(t *testing.T) { + for _, saveFailure := range []bool{false, true} { + t.Run(map[bool]string{false: "saved", true: "save failure"}[saveFailure], func(t *testing.T) { + ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second) + defer cancel() + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(context.Context, speech.Settings) error { + if saveFailure { + return os.Mkdir(settings.Path, 0700) // Runtime succeeds; subsequent disk save fails. + } + return nil + })) + messages := make(chan string, 1) + worker.announceApply = func(message string) { messages <- message } + reader, writer := io.Pipe() + defer reader.Close() + defer writer.Close() + stopIO := context.AfterFunc(ctx, func() { reader.CloseWithError(ctx.Err()); writer.CloseWithError(ctx.Err()) }) + defer stopIO() + requests := make(chan preferences.Request) + readDone := make(chan error, 1) + done := make(chan error, 1) + go func() { done <- worker.serve_preferences(ctx, ctx, json.NewEncoder(writer), requests, readDone) }() + values := preferences.FromSettings(settings) + rate := 65.0 + values.Rate = &rate + requests <- preferences.Request{Values: values, Save: true, Close: true} + // The pipe cannot write the reply until we start reading: feedback + // must already be queued so the helper's close cannot overtake it. + var message string + select { + case message = <-messages: + case <-ctx.Done(): + t.Fatal("feedback was not queued before the helper reply") + } + var response preferences.Response + if err := json.NewDecoder(reader).Decode(&response); err != nil || !response.Accepted { + t.Fatalf("apply response = %+v, %v", response, err) + } + if saveFailure { + if !strings.Contains(message, "could not save") || response.Close { + t.Fatalf("save failure was hidden: message=%q, close=%t", message, response.Close) + } + } else if message != "Settings applied" || !response.Close { + t.Fatalf("success: message=%q, close=%t", message, response.Close) + } + readDone <- io.EOF + if err := <-done; err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/internal/app/preferences_preview.go b/internal/app/preferences_preview.go new file mode 100644 index 0000000..07a65aa --- /dev/null +++ b/internal/app/preferences_preview.go @@ -0,0 +1,158 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "fmt" + "strings" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/preferences" +) + +func (worker *preferencesWorker) preview(ctx context.Context, request preferences.Request) preferences.Response { + if request.EchoPreview != "" { + return worker.preview_echo_voice(ctx, request) + } + next := worker.settings + if worker.editingActive { + next = worker.editing + } + next.DefaultVoice.Rate = request.Values.Rate + next.DefaultVoice.AveragePitch = request.Values.Pitch + next.DefaultVoice.Gain = request.Values.Volume + next.SpeechServerFactory = request.Values.SpeechServerFactory + next.HardwareSpeechDevice = request.Values.HardwareSpeechDevice + next.HardwareSpeechBaudRate = request.Values.HardwareSpeechBaudRate + next.SpeechOutputModule = request.Values.SpeechOutputModule + next.DefaultVoice.Family = request.Values.SpeechVoiceFamily + next.UppercaseVoice = request.Values.UppercaseVoice + next.HyperlinkVoice = request.Values.HyperlinkVoice + next.SystemVoice = request.Values.SystemVoice + // GUI feedback auditions the selected type; Cancel restores the committed + // configuration, while Apply receives the complete unmodified draft. + if kind := request.Values.VoiceType; kind != "" && kind != "default" { + next.DefaultVoice = config.EffectiveVoice(next, kind) + next.SystemVoice = config.Voice{} + } + response := worker.response("Speech settings previewed.", false) + response.Preview = true + if err := config.Validate(next); err != nil { + response.Message = "Speech settings were not previewed: " + err.Error() + return response + } + if err := worker.updateSpeech(ctx, next); err != nil { + response.Message = "Speech settings were not previewed: " + err.Error() + return response + } + response.Accepted = true + return response +} + +func (worker *preferencesWorker) preview_echo_voice(ctx context.Context, request preferences.Request) preferences.Response { + response := worker.response("Speech settings previewed.", false) + response.Preview = true + var value *float64 + text := "" + label := "" + switch request.EchoPreview { + case "rate": + value = request.Values.EchoVoice.Rate + label = "Key echo rate" + case "pitch": + value = request.Values.EchoVoice.AveragePitch + label = "Key echo pitch" + case "volume": + value = request.Values.EchoVoice.Gain + label = "Key echo volume" + case "synthesizer": + label = "Key echo speech synthesizer" + text = request.Values.EchoSpeechServer + if text == "" { + text = "Default" + } + case "person": + label = "Key echo person" + text = "Default" + if family := request.Values.EchoVoice.Family; family != nil { + text = family.Name + if language := strings.TrimSuffix(family.Lang+"-"+family.Dialect, "-"); language != "" { + text += " (" + language + ")" + } + } + } + if value != nil { + text = fmt.Sprintf("%.1f", *value) + } + if !request.Values.UseCustomEchoVoice || text == "" { + response.Message = "Choose a custom echo voice and a valid echo control value." + return response + } + // Preview only echo settings. Control labels and ordinary output retain + // the active profile's main voice; the draft is never committed here. + next := worker.settings + next.UseCustomEchoVoice = true + next.UseCustomEchoSpeechServer = request.Values.UseCustomEchoSpeechServer + next.EchoSpeechServer = request.Values.EchoSpeechServer + next.EchoVoice = request.Values.EchoVoice + if err := config.Validate(next); err != nil { + response.Message = "Speech settings were not previewed: " + err.Error() + return response + } + if err := worker.updateSpeech(ctx, next); err != nil { + response.Message = "Speech settings were not previewed: " + err.Error() + return response + } + if worker.announceEchoPreview != nil { + if !request.EchoPreviewFocus { + label = "" + } + worker.announceEchoPreview(label, text) + } + response.Accepted = true + return response +} + +func echo_preview_speech(label, value string) speechRequest { + parts := []readAllPart{} + if label != "" { + parts = append(parts, readAllPart{Text: label, VoiceType: "default"}) + } + parts = append(parts, readAllPart{Text: value, VoiceType: "echo"}) + // Both parts belong to one cancellable request and wait for completion. + // No second voice can cancel the first part merely by being queued next. + return speechRequest{Text: value, Role: "text", Cause: "echo-voice-preview", ReadAll: parts} +} + +func (worker *preferencesWorker) restorePreview(ctx context.Context) preferences.Response { + response := worker.response("Speech settings restored.", false) + if err := worker.updateSpeech(ctx, worker.effective_settings(worker.settings)); err != nil { + response.Message = "Speech settings could not be restored: " + err.Error() + return response + } + response.Accepted = true + response.Close = true + return response +} + +func (worker *preferencesWorker) updateSpeech(ctx context.Context, next config.Settings) error { + if worker.updater == nil { + return errors.New("speech is disabled or this backend cannot change settings") + } + if updater, ok := worker.updater.(interface { + UpdateConfiguration(context.Context, config.Settings) error + }); ok { + return updater.UpdateConfiguration(ctx, next) + } + if updater, ok := worker.updater.(speechSettingsUpdater); ok { + if next.UseCustomEchoVoice { + return errors.New("this speech backend cannot use a custom echo voice") + } + return updater.UpdateSettings(ctx, speechSettingsFromConfig(next)) + } + return errors.New("this backend cannot change speech settings") +} diff --git a/internal/app/preferences_preview_events.go b/internal/app/preferences_preview_events.go new file mode 100644 index 0000000..71a5663 --- /dev/null +++ b/internal/app/preferences_preview_events.go @@ -0,0 +1,47 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import "git.stormux.org/storm/cthulhu/internal/atspi" + +// The event loop remembers exactly five control identities for one preferences +// child. A new child or focus reset retires them. GTK reports combo selections +// as menu-item descendants with the owning combo in OriginPath. +type echoPreviewPresentation struct { + pid int64 + controls [5]atspi.ObjectID +} + +func (preview *echoPreviewPresentation) owns(event atspi.Event, pid int64) bool { + if preview.pid != pid { + *preview = echoPreviewPresentation{pid: pid} + } + if pid <= 0 { + return false + } + index := -1 + switch event.Source.Name { + case "Key echo rate": + index = 0 + case "Key echo pitch": + index = 1 + case "Key echo volume": + index = 2 + case "Key echo speech synthesizer": + index = 3 + case "Key echo person": + index = 4 + } + if index >= 0 && int64(event.Source.ApplicationPID) == pid && + (index < 3 && event.Source.Role == "slider" || index >= 3 && event.Source.Role == "combo box") { + preview.controls[index] = event.Source.ID() + return true + } + if event.Type == atspi.SelectionChangedEvent && event.Source.Role == "menu item" { + owner := atspi.NewObjectID(event.Source.BusName, event.OriginPath) + return owner.Valid() && (owner == preview.controls[3] || owner == preview.controls[4]) + } + return false +} diff --git a/internal/app/preferences_session.go b/internal/app/preferences_session.go new file mode 100644 index 0000000..4e6ee7d --- /dev/null +++ b/internal/app/preferences_session.go @@ -0,0 +1,275 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "os" + "os/exec" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/session" + "git.stormux.org/storm/cthulhu/internal/preferences" +) + +// Keep helper diagnostics bounded; GTK can repeat warnings while a display is +// unavailable. The child has no access to page content or the speech log. +type preferencesStderr struct{ data []byte } + +func (stderr *preferencesStderr) Write(p []byte) (int, error) { + const limit = 4096 + if room := limit - len(stderr.data); room > 0 { + stderr.data = append(stderr.data, p[:min(len(p), room)]...) + } + return len(p), nil +} + +func (stderr *preferencesStderr) String() string { + return string(bytes.TrimSpace(stderr.data)) +} + +func (worker *preferencesWorker) window(ctx context.Context) (result error) { + executable, err := os.Executable() + if err != nil { + return err + } + childCtx, stop := context.WithCancel(ctx) + defer stop() + command := exec.CommandContext(childCtx, executable, "--preferences-ui") + command.Env = session.GTKEnvironment() + command.WaitDelay = time.Second + in, err := command.StdinPipe() + if err != nil { + return err + } + out, err := command.StdoutPipe() + if err != nil { + in.Close() + return err + } + // Keep GTK and child startup errors off the protocol pipe, then include + // them in a failed window attempt so a broken pipe has a useful cause. + var diagnostic preferencesStderr + command.Stderr = &diagnostic + if err := command.Start(); err != nil { + in.Close() + out.Close() + return err + } + if worker.live != nil { + worker.live.preferencesPID.Store(int64(command.Process.Pid)) + defer worker.live.preferencesPID.Store(0) + } + defer func() { + stop() + in.Close() + out.Close() + waitErr := command.Wait() + if ctx.Err() != nil { + return + } + if result == nil && waitErr != nil { + result = fmt.Errorf("preferences helper exited: %w", waitErr) + } + if result != nil { + if detail := diagnostic.String(); detail != "" { + result = fmt.Errorf("%w (helper exit: %v; stderr: %s)", result, waitErr, detail) + } else { + result = fmt.Errorf("%w (helper exit: %v)", result, waitErr) + } + } + }() + encoder := json.NewEncoder(in) + initial, err := worker.initial_response(childCtx) + if err != nil { + return err + } + if err := preferences.EncodeInitial(encoder, initial); err != nil { + return err + } + requests := make(chan preferences.Request, 1) + readDone := make(chan error, 1) + readerStopped := make(chan struct{}) + go read_preferences_requests(childCtx, stop, out, requests, readDone, readerStopped) + defer func() { + stop() + out.Close() + <-readerStopped + }() + return worker.serve_preferences(ctx, childCtx, encoder, requests, readDone) +} + +func (worker *preferencesWorker) initial_response(childCtx context.Context) (preferences.Response, error) { + if worker.choosingApplication { + return preferences.Response{ChooseApplication: true}, nil + } + var err error + initial := worker.response("Apply and OK save settings. Cancel discards unapplied edits.", true) + initial.Application = worker.editApp + worker.sync_extensions(childCtx) + if worker.editApp == "" { + initial.ExtensionPages = worker.extension_pages() + } + if worker.editApp == "" { + snapshot := worker.tentacles.Snapshot() + initial.Tentacles = &snapshot + } + if !initial.CanSave { + initial.Message = "This file is read-only in the Go preview. Apply changes this session only; importing Python settings is not available yet." + } + catalogCtx, cancelCatalog := context.WithTimeout(childCtx, 4*time.Second) + initial.Catalog, err = worker.discover(catalogCtx, worker.socket) + cancelCatalog() + if err != nil { + worker.logger.Debug("discover echo voices", "error", err) + } + if worker.editing.SpeechServerFactory != "hardwarefactory" { + defaultsCtx, cancelDefaults := context.WithTimeout(childCtx, 500*time.Millisecond) + initial.SpeechDefaults, err = worker.readSpeechDefaults(defaultsCtx, worker.socket) + cancelDefaults() + if err != nil { + worker.logger.Debug("read speech defaults", "error", err) + } + } + if worker.editApp == "" { + if err := worker.load_extension_pages(childCtx); err != nil { + worker.logger.Warn("load tentacle preference pages", "error", err) + initial.Message += " Some tentacle pages could not load; their last valid controls were retained." + } + initial.ExtensionPages = worker.extension_pages() + } + return initial, nil +} + +// The reader owns decoding only. Its caller closes the pipe and joins it before +// waiting for the child; cancellation also releases a full request mailbox. +func read_preferences_requests(childCtx context.Context, stop context.CancelFunc, out io.Reader, requests chan<- preferences.Request, readDone chan<- error, readerStopped chan<- struct{}) { + defer close(readerStopped) + defer stop() + scanner := bufio.NewScanner(out) + scanner.Buffer(make([]byte, 4096), 512*1024) + for scanner.Scan() { + var request preferences.Request + if err := json.Unmarshal(scanner.Bytes(), &request); err != nil { + readDone <- err + return + } + select { + case requests <- request: + case <-childCtx.Done(): + readDone <- childCtx.Err() + return + } + } + readDone <- scanner.Err() +} + +// The worker goroutine serializes apply/preview replies and repeated-open +// requests. Preview restoration precedes pipe joins and child cleanup. +func (worker *preferencesWorker) serve_preferences(ctx, childCtx context.Context, encoder *json.Encoder, requests <-chan preferences.Request, readDone <-chan error) error { + previewActive := false + defer func() { + if !previewActive || ctx.Err() != nil { + return + } + restoreCtx, cancel := context.WithTimeout(context.Background(), 6*time.Second) + defer cancel() + if err := worker.updateSpeech(restoreCtx, worker.effective_settings(worker.settings)); err != nil { + worker.logger.Error("restore speech settings after preferences exit", "error", err) + } + }() + for { + select { + case <-ctx.Done(): + return ctx.Err() + case <-worker.extension_changes(): + worker.sync_extensions(ctx) + if worker.editApp == "" { + if err := encoder.Encode(preferences.Response{ExtensionsOnly: true, ExtensionPages: worker.extension_pages()}); err != nil { + return err + } + } + case call := <-worker.extensionRequests: + worker.handle_reader_call(ctx, call, true) + case command := <-worker.speechCommands: + if command == input.CycleProgressBarOutput { + worker.announceSpeechSetting("Close preferences before changing progress bar output with its shortcut.") + } else { + worker.announceSpeechSetting("Close preferences before using speech setting shortcuts.") + } + case <-worker.open: + // A present response raises the existing window without resetting edits. + if err := encoder.Encode(struct{ Present bool }{true}); err != nil { + return err + } + case err := <-readDone: + if errors.Is(err, io.EOF) { + return nil + } + return err + case request := <-requests: + if request.Tentacle != nil { + response := worker.manage_tentacle(childCtx, request) + if err := encoder.Encode(response); err != nil { + return err + } + continue + } + if worker.choosingApplication { + if request.Application == "" || len(request.Application) > 4096 || !worker.beginEdit(childCtx, request.Application) { + return errors.New("invalid application preferences selection") + } + worker.choosingApplication = false + initial, err := worker.initial_response(childCtx) + if err != nil { + return err + } + if err := preferences.EncodeInitial(encoder, initial); err != nil { + return err + } + continue + } + applyCtx, cancel := context.WithTimeout(childCtx, 6*time.Second) + var response preferences.Response + switch { + case request.Cancel: + response = worker.restorePreview(applyCtx) + case request.Preview: + response = worker.preview(applyCtx, request) + default: + response = worker.apply(applyCtx, request) + } + cancel() + if response.Accepted { + if request.Preview { + previewActive = true + } else { + previewActive = false + } + } + if childCtx.Err() != nil { + return nil + } + // Queue feedback before the helper restores focus or closes on OK. + if response.Accepted && !request.Preview && !request.Cancel && worker.announceApply != nil { + message := response.Message + if message == "Settings applied and saved." { + message = "Settings applied" + } + worker.announceApply(message) + } + if err := encoder.Encode(response); err != nil { + return fmt.Errorf("reply to preferences: %w", err) + } + } + } +} diff --git a/internal/app/preferences_session_test.go b/internal/app/preferences_session_test.go new file mode 100644 index 0000000..2710e7e --- /dev/null +++ b/internal/app/preferences_session_test.go @@ -0,0 +1,161 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "encoding/json" + "io" + "log/slog" + "path/filepath" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +func TestPreferencesSessionRestoresPreviewAfterRejectedApplyAndReopen(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + updates := make(chan speech.Settings, 3) + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(_ context.Context, value speech.Settings) error { + updates <- value + return nil + })) + worker.announceApply = func(message string) { t.Errorf("preview or rejected Apply announced success: %q", message) } + reader, writer := io.Pipe() + defer reader.Close() + defer writer.Close() + stopIO := context.AfterFunc(ctx, func() { + reader.CloseWithError(ctx.Err()) + writer.CloseWithError(ctx.Err()) + }) + defer stopIO() + requests := make(chan preferences.Request) + readDone := make(chan error, 1) + done := make(chan error, 1) + go func() { + done <- worker.serve_preferences(ctx, ctx, json.NewEncoder(writer), requests, readDone) + }() + decoder := json.NewDecoder(reader) + read_response := func() preferences.Response { + t.Helper() + var response preferences.Response + if err := decoder.Decode(&response); err != nil { + t.Fatal(err) + } + return response + } + rate := 75.0 + values := preferences.FromSettings(settings) + values.Rate = &rate + select { + case requests <- preferences.Request{Values: values, Preview: true}: + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + if response := read_response(); !response.Accepted || !response.Preview { + t.Fatalf("preview was rejected: %+v", response) + } + if len(updates) != 1 { + t.Fatal("preview did not produce exactly one speech update") + } + if update := <-updates; update.Rate == nil || *update.Rate == 0 { + t.Fatalf("preview did not reach speech: %+v", update) + } + worker.Open() + if response := read_response(); !response.Present || response.Close { + t.Fatalf("reopen did not raise the existing window: %+v", response) + } + values.Punctuation = 99 + select { + case requests <- preferences.Request{Values: values}: + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + if response := read_response(); response.Accepted || response.Close { + t.Fatalf("invalid draft committed or closed: %+v", response) + } + readDone <- io.EOF + select { + case err := <-done: + if err != nil { + t.Fatal(err) + } + case <-ctx.Done(): + t.Fatal("preferences session did not join after helper EOF") + } + if len(updates) != 1 { + t.Fatal("exit did not produce exactly one restoration update") + } + if update := <-updates; update.Rate != nil { + t.Fatalf("helper exit did not restore the server default rate: %+v", update) + } + if len(updates) != 0 || worker.settings.DefaultVoice.Rate != nil || worker.settings.VerbalizePunctuationStyle != settings.VerbalizePunctuationStyle { + t.Fatal("reopen or rejected apply committed preview settings") + } + if loaded, err := config.Load(settings.Path); err != nil || loaded.Loaded { + t.Fatalf("preview/rejection wrote settings: loaded=%t, err=%v", loaded.Loaded, err) + } +} + +func TestChooserSelectionSavesSelectedProfileWhileAnotherAppIsActive(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + store, err := config.NewStore(settings.Path) + if err != nil { + t.Fatal(err) + } + if err = store.Save(settings); err != nil { + t.Fatal(err) + } + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(context.Context, speech.Settings) error { return nil })) + worker.discover = func(context.Context, string) (speech.Catalog, error) { return nil, nil } + worker.switchApplication(ctx, "Focused Application") + worker.choosingApplication = true + reader, writer := io.Pipe() + defer reader.Close() + defer writer.Close() + stopIO := context.AfterFunc(ctx, func() { reader.CloseWithError(ctx.Err()); writer.CloseWithError(ctx.Err()) }) + defer stopIO() + requests := make(chan preferences.Request) + readDone := make(chan error, 1) + done := make(chan error, 1) + go func() { done <- worker.serve_preferences(ctx, ctx, json.NewEncoder(writer), requests, readDone) }() + requests <- preferences.Request{Application: "Chosen Application"} + decoder := json.NewDecoder(reader) + var initial preferences.Response + if err = decoder.Decode(&initial); err != nil { + t.Fatal(err) + } + if initial.Application != "Chosen Application" || initial.ChooseApplication || !initial.CanSave { + t.Fatalf("selected application preferences = %+v", initial) + } + values := initial.Values + values.Reading.AutomaticallyReadClipboardChanges = true + requests <- preferences.Request{Values: values, Save: true} + var response preferences.Response + if err = decoder.Decode(&response); err != nil || !response.Accepted { + t.Fatalf("apply = %+v, %v", response, err) + } + readDone <- io.EOF + if err = <-done; err != nil { + t.Fatal(err) + } + chosen, mapped, err := store.LoadForApplication("Chosen Application") + if err != nil || !mapped || !chosen.Reading.AutomaticallyReadClipboardChanges { + t.Fatalf("chosen override = %t, mapped %t, %v", chosen.Reading.AutomaticallyReadClipboardChanges, mapped, err) + } + focused, _, err := store.LoadForApplication("Focused Application") + if err != nil || focused.Reading.AutomaticallyReadClipboardChanges || worker.settings.Reading.AutomaticallyReadClipboardChanges { + t.Fatal("chosen application's preference leaked into focused application") + } +} diff --git a/internal/app/preferences_tentacles.go b/internal/app/preferences_tentacles.go new file mode 100644 index 0000000..8a52937 --- /dev/null +++ b/internal/app/preferences_tentacles.go @@ -0,0 +1,73 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/tentacle" +) + +func (worker *preferencesWorker) manage_tentacle(ctx context.Context, request preferences.Request) preferences.Response { + response := preferences.Response{} + if worker.choosingApplication || worker.editApp != "" || request.Application != "" { + response.Message = "Tentacles can only be managed in global preferences." + return response + } + if request.Save || request.Close || request.Cancel || request.Preview || request.Tentacle == nil { + response.Message = "Tentacle management must be a separate request." + return response + } + if request.Tentacle.Action == "settings" { + if request.Tentacle.Entry != nil || request.Tentacle.URL != "" { + response.Message = "Invalid tentacle settings request." + } else if err := worker.tentacles.OpenSettings(ctx, request.Tentacle.ID); err != nil { + response.Message = err.Error() + } else { + response.Accepted = true + } + return response + } + timeout := 6 * time.Second + if strings.HasPrefix(request.Tentacle.Action, "repository-") || strings.HasPrefix(request.Tentacle.Action, "install") { + timeout = 50 * time.Second + } + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + if err := worker.tentacles.Manage(ctx, *request.Tentacle); err != nil { + response.Message = "Tentacle operation was not accepted: " + err.Error() + if errors.Is(err, tentacle.ErrRegistrySync) { + response.Accepted = true + response.Message = "Tentacle configuration applied and saved, but durability could not be confirmed." + } + } else { + response.Accepted = true + response.Message = "Tentacle configuration saved; runtime status is shown separately." + if request.Tentacle.Action == "list" { + response.Message = "Tentacle status." + } + if request.Tentacle.Action == "retry" { + response.Message = "Tentacle is active." + } + switch request.Tentacle.Action { + case "install": + response.Message = "Tentacle installed and saved. Enable it when you are ready." + case "install-enable": + response.Message = "Tentacle installed and active." + case "repository-add": + response.Message = "Repository added. Its tentacles are listed in the table." + case "repository-refresh": + response.Message = "Repository catalog refreshed." + case "repository-remove": + response.Message = "Repository removed. Installed tentacles and settings were retained." + } + } + snapshot := worker.tentacles.Snapshot() + response.Tentacles = &snapshot + return response +} diff --git a/internal/app/preferences_test.go b/internal/app/preferences_test.go new file mode 100644 index 0000000..49cf09d --- /dev/null +++ b/internal/app/preferences_test.go @@ -0,0 +1,363 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + "os" + "path/filepath" + "reflect" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/sound" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +type settingsUpdateFunc func(context.Context, speech.Settings) error + +func TestPreferencesInitialRetainsLargeVoiceCatalog(t *testing.T) { + catalog := speech.Catalog{ + "module": make([]speech.Voice, 6000), + "other": {{Name: "Other voice", Language: "en"}}, + } + for index := range catalog["module"] { + catalog["module"][index].Name = strings.Repeat("v", 100) + } + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), config.DefaultSettings(), nil) + worker.discover = func(context.Context, string) (speech.Catalog, error) { return catalog, nil } + worker.readSpeechDefaults = func(context.Context, string) (speech.Settings, error) { return speech.Settings{}, nil } + response, err := worker.initial_response(t.Context()) + if err != nil || !reflect.DeepEqual(response.Catalog, catalog) { + t.Fatalf("initial response lost discovered voices: err=%v", err) + } +} + +func TestPreferencesWindowReportsHelperExit(t *testing.T) { + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), config.DefaultSettings(), nil) + worker.discover = func(context.Context, string) (speech.Catalog, error) { return nil, nil } + worker.readSpeechDefaults = func(context.Context, string) (speech.Settings, error) { return speech.Settings{}, nil } + // The test executable does not implement --preferences-ui. It exits before + // opening a dialog, as a broken helper would on the affected machine. + err := worker.window(t.Context()) + if err == nil || !strings.Contains(err.Error(), "helper exit") || + !strings.Contains(err.Error(), "preferences-ui") { + t.Fatalf("helper startup error = %v", err) + } +} + +func (update settingsUpdateFunc) UpdateSettings(ctx context.Context, settings speech.Settings) error { + return update(ctx, settings) +} + +type recordingSoundSettings struct { + configurations []sound.Configuration +} + +type recordingBrailleSettings struct { + values []bool + contraction []bool + tables []string + err error +} + +func (recorder *recordingBrailleSettings) SetContraction(enabled bool, table string) { + recorder.contraction = append(recorder.contraction, enabled) + recorder.tables = append(recorder.tables, table) +} + +func (recorder *recordingBrailleSettings) Configure(_ context.Context, enabled bool) error { + if recorder.err != nil { + return recorder.err + } + recorder.values = append(recorder.values, enabled) + return nil +} + +func TestPreferencesBrailleApplyAndFailure(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + braille := &recordingBrailleSettings{} + worker.braille = braille + values := preferences.FromSettings(settings) + values.EnableBraille = true + values.EnableContractedBraille = true + values.BrailleContractionTable = "en-us-g2.ctb" + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || len(braille.values) != 1 || !braille.values[0] || + len(braille.contraction) != 1 || !braille.contraction[0] || braille.tables[0] != "en-us-g2.ctb" { + t.Fatalf("enable: response=%+v calls=%v", response, braille.values) + } + loaded, err := config.Load(settings.Path) + if err != nil || !loaded.EnableBraille || !loaded.EnableContractedBraille || loaded.BrailleContractionTable != "en-us-g2.ctb" { + t.Fatalf("saved braille setting: %+v, %v", loaded, err) + } + braille.err = errors.New("helper unavailable") + values.EnableBraille = false + response = worker.apply(context.Background(), preferences.Request{Values: values}) + if response.Accepted || !worker.settings.EnableBraille { + t.Fatalf("failed disable changed setting: %+v", response) + } +} + +func (recorder *recordingSoundSettings) Configure(configuration sound.Configuration) { + recorder.configurations = append(recorder.configurations, configuration) +} + +func TestPreferencesApplySoundSettingsLiveAndPersisted(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + live := &liveSettings{} + live.Store(settings) + recorder := &recordingSoundSettings{} + geometry := &fakeAdapter{} + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + worker.live = live + worker.sound = recorder + worker.geometry = geometry + + values := preferences.FromSettings(settings) + values.EnableSound = false + values.SoundVolume = 0.8 + values.SoundSink = "pulse" + values.SoundTheme = "none" + values.PlaySoundForRole = false + values.PlaySoundForState = false + values.PlaySoundForPositionInSet = false + values.SpatializeObjectSounds = true + values.ProgressBar.OutputMode = "off" + values.ProgressBar.ReportBackground = true + values.RoleSoundPresentation = "speech_only" + + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || len(recorder.configurations) != 1 { + t.Fatalf("apply = %+v; sound updates = %+v", response, recorder.configurations) + } + wantConfiguration := sound.Configuration{Enabled: false, Sink: "pulse", Theme: "none", Volume: 0.8} + if recorder.configurations[0] != wantConfiguration { + t.Fatalf("sound configuration = %+v, want %+v", recorder.configurations[0], wantConfiguration) + } + if geometry.captureSoundGeometry { + t.Fatal("disabled sound retained synchronous event geometry capture") + } + if got := preferences.FromSettings(live.Load()); !reflect.DeepEqual(got, values) { + t.Fatalf("live values = %+v, want %+v", got, values) + } + loaded, err := config.Load(settings.Path) + if err != nil { + t.Fatal(err) + } + if got := preferences.FromSettings(loaded); !reflect.DeepEqual(got, values) { + t.Fatalf("saved values = %+v, want %+v", got, values) + } +} + +func TestCaptureSoundGeometryRequiresSpatializedObjectSounds(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSound = true + settings.SoundTheme = "default" + settings.SoundVolume = 1 + settings.SpatializeObjectSounds = true + settings.PlaySoundForRole = true + if !captureSoundGeometry(settings) { + t.Fatal("spatialized role sounds did not enable event geometry capture") + } + settings.PlaySoundForRole = false + settings.PlaySoundForState = false + if !captureSoundGeometry(settings) { + t.Fatal("spatialized position sounds did not enable event geometry capture") + } + settings.PlaySoundForPositionInSet = false + if captureSoundGeometry(settings) { + t.Fatal("geometry capture remained enabled without object sound categories") + } +} + +func TestPreferencesApplySaveAndRejectedDraft(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + var updates []speech.Settings + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(_ context.Context, value speech.Settings) error { + updates = append(updates, value) + return nil + })) + values := preferences.FromSettings(settings) + rate := 75.0 + values.Rate = &rate + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || len(updates) != 1 || *updates[0].Rate != 52 { + t.Fatalf("apply = %+v; updates = %+v", response, updates) + } + if _, err := os.Stat(settings.Path); err != nil || response.Close { + t.Fatalf("Apply did not save and stay open: %v", err) + } + badRate := 100.0 + bad := values + bad.Rate = &badRate + response = worker.apply(context.Background(), preferences.Request{Values: bad, Save: true}) + if response.Accepted || len(updates) != 1 || *worker.settings.DefaultVoice.Rate != rate { + t.Fatal("invalid draft changed session") + } + response = worker.apply(context.Background(), preferences.Request{Values: values, Save: true, Close: true}) + if !response.Accepted || !response.Close { + t.Fatalf("save = %+v", response) + } + loaded, err := config.Load(settings.Path) + if err != nil || loaded.DefaultVoice.Rate == nil || *loaded.DefaultVoice.Rate != rate { + t.Fatalf("saved settings = %+v; error %v", loaded, err) + } + if !reflect.DeepEqual(loaded.CthulhuModifierKeys, settings.CthulhuModifierKeys) || loaded.EnableSound != settings.EnableSound { + t.Fatal("saving changed unrelated settings") + } +} + +func TestPreferencesLegacyFileRemainsUntouched(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + contents := []byte("[general]\nenableSpeech = true\nunknownSetting = 'preserve me'\n") + if err := os.WriteFile(path, contents, 0o600); err != nil { + t.Fatal(err) + } + settings, err := config.Load(path) + if err != nil { + t.Fatal(err) + } + calls := 0 + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(context.Context, speech.Settings) error { calls++; return nil })) + request := preferences.Request{Values: preferences.FromSettings(settings), Save: true} + if response := worker.apply(context.Background(), request); response.Accepted || response.CanSave || calls != 0 { + t.Fatalf("legacy save = %+v, calls %d", response, calls) + } + request.Save = false + if response := worker.apply(context.Background(), request); !response.Accepted || calls != 0 { + t.Fatalf("session apply = %+v", response) + } + got, err := os.ReadFile(path) + if err != nil || string(got) != string(contents) { + t.Fatal("legacy file changed") + } +} + +func TestPreferencesBackendFailureDoesNotCommit(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(context.Context, speech.Settings) error { return errors.New("backend rejected voice") })) + values := preferences.FromSettings(settings) + values.Punctuation = 3 + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if response.Accepted || !reflect.DeepEqual(worker.settings, settings) { + t.Fatalf("failed apply committed: %+v", response) + } + if _, err := os.Stat(settings.Path); !errors.Is(err, os.ErrNotExist) { + t.Fatal("failed apply wrote a file") + } +} + +func TestPreferencesSpeechChoicesApplyAndPersist(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + var applied speech.Settings + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(_ context.Context, value speech.Settings) error { + applied = value + return nil + })) + values := preferences.FromSettings(settings) + values.SpeechOutputModule = "espeak-ng" + values.SpeechVoiceFamily = &config.VoiceFamily{Name: "Generic Voice", Lang: "en", Dialect: "US", Variant: "male"} + + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || applied.OutputModule != "espeak-ng" || + applied.Language != "en-US" || applied.SynthesisVoice != "Generic Voice" { + t.Fatalf("apply = %+v; applied = %+v", response, applied) + } + if worker.settings.SpeechOutputModule != "espeak-ng" || + worker.settings.DefaultVoice.Family == nil || worker.settings.DefaultVoice.Family.Name != "Generic Voice" { + t.Fatalf("session settings = %+v", worker.settings) + } + loaded, err := config.Load(settings.Path) + if err != nil || loaded.SpeechOutputModule != "espeak-ng" || + loaded.DefaultVoice.Family == nil || loaded.DefaultVoice.Family.Name != "Generic Voice" { + t.Fatalf("loaded settings = %+v; error %v", loaded, err) + } +} + +func TestPreferencesVoicePreviewDoesNotCommitAndCancelRestores(t *testing.T) { + settings := config.DefaultSettings() + originalRate, originalPitch, originalVolume := 40.0, 4.0, 6.0 + settings.DefaultVoice.Rate = &originalRate + settings.DefaultVoice.AveragePitch = &originalPitch + settings.DefaultVoice.Gain = &originalVolume + var updates []speech.Settings + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(_ context.Context, value speech.Settings) error { + updates = append(updates, value) + return nil + })) + values := preferences.FromSettings(settings) + previewRate, previewPitch, previewVolume := 75.0, 7.5, 8.0 + values.Rate = &previewRate + values.Pitch = &previewPitch + values.Volume = &previewVolume + response := worker.preview(context.Background(), preferences.Request{Values: values, Preview: true}) + if !response.Accepted || !response.Preview || len(updates) != 1 || + updates[0].Rate == nil || *updates[0].Rate != 52 || + updates[0].Pitch == nil || *updates[0].Pitch != 60 || + updates[0].Volume == nil || *updates[0].Volume != 85 { + t.Fatalf("preview = %+v; updates = %+v", response, updates) + } + if worker.settings.DefaultVoice.Rate == nil || *worker.settings.DefaultVoice.Rate != originalRate || + worker.settings.DefaultVoice.AveragePitch == nil || *worker.settings.DefaultVoice.AveragePitch != originalPitch || + worker.settings.DefaultVoice.Gain == nil || *worker.settings.DefaultVoice.Gain != originalVolume { + t.Fatal("preview committed session settings") + } + response = worker.restorePreview(context.Background()) + if !response.Accepted || !response.Close || len(updates) != 2 || + updates[1].Rate == nil || *updates[1].Rate != -18 || + updates[1].Pitch == nil || *updates[1].Pitch != -10 || + updates[1].Volume == nil || *updates[1].Volume != 55 { + t.Fatalf("restore = %+v; updates = %+v", response, updates) + } +} + +func TestPreferencesSaveFailureReportsSessionCommit(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(context.Context, speech.Settings) error { + // Another writer changes the file after preflight, before Store.Save. + return os.WriteFile(settings.Path, []byte("schema-version = 999\n"), 0o600) + })) + values := preferences.FromSettings(settings) + values.Punctuation = 3 + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || !strings.Contains(response.Message, "could not save") || worker.settings.VerbalizePunctuationStyle != 3 { + t.Fatalf("partial save result = %+v", response) + } + got, _ := os.ReadFile(settings.Path) + if string(got) != "schema-version = 999\n" { + t.Fatal("save replaced another writer's incompatible file") + } +} + +func TestPreferencesOpenCoalescesAndStopJoins(t *testing.T) { + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), config.DefaultSettings(), nil) + for range 100 { + worker.Open() + } + if len(worker.open) != 1 { + t.Fatal("open requests did not coalesce") + } + <-worker.open + ctx, cancel := context.WithCancel(context.Background()) + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + cancel() + if err := worker.Stop(context.Background()); err != nil { + t.Fatal(err) + } +} diff --git a/internal/app/progress_bars.go b/internal/app/progress_bars.go new file mode 100644 index 0000000..b59d80b --- /dev/null +++ b/internal/app/progress_bars.go @@ -0,0 +1,123 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "fmt" + "math" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/sound" + "git.stormux.org/storm/cthulhu/internal/webscripts" +) + +type ProgressBarEntry struct { + beep, speech float64 + beepKnown, speechKnown bool +} + +// ProgressBarHistory belongs to the event loop and survives focus changes. +// It is bounded and released with the loop. Native identities keep distinct +// bars independent even when they occupy the same screen position. +type ProgressBarHistory struct { + entries map[atspi.ObjectID]ProgressBarEntry + order []atspi.ObjectID +} + +func (history *ProgressBarHistory) report(id atspi.ObjectID, percentage float64, settings config.ProgressBarSettings) (bool, bool) { + if history.entries == nil { + history.entries = make(map[atspi.ObjectID]ProgressBarEntry) + } + entry, exists := history.entries[id] + beep := (settings.OutputMode == "beep" || settings.OutputMode == "both") && + (!entry.beepKnown || math.Abs(percentage-entry.beep) >= float64(settings.BeepPercentageInterval)) + speak := (settings.OutputMode == "speak" || settings.OutputMode == "both") && + (!entry.speechKnown || math.Abs(percentage-entry.speech) >= float64(settings.SpeechPercentageInterval)) + if !beep && !speak { + return false, false + } + if beep { + entry.beep, entry.beepKnown = percentage, true + } + if speak { + entry.speech, entry.speechKnown = percentage, true + } + if exists { + for index, candidate := range history.order { + if candidate == id { + history.order = append(history.order[:index], history.order[index+1:]...) + break + } + } + } else if len(history.order) == 32 { + delete(history.entries, history.order[0]) + history.order = history.order[1:] + } + history.entries[id] = entry + history.order = append(history.order, id) + return beep, speak +} + +// Handle progress before ordinary focused-object filtering. This path never +// changes window ownership, native focus, review or browser mode. +func (handler *accessibilityEventHandler) handle_progress_bar(event atspi.Event) bool { + percentage, shaderProgress := webscripts.ShaderProgress(event.Source.ApplicationProcess, event.Type, event.Source.Role, event.Source.Name) + if !shaderProgress && (!isValueChangeEvent(event.Type) || event.Source.Role != "progress bar") { + return false + } + settings := config.DefaultSettings() + if handler.live != nil { + settings = handler.live.Load() + } + if settings.ProgressBar.OutputMode == "off" || event.Source.StatesKnown && (!event.Source.Visible || !event.Source.Showing) { + // NVDA falls back to ordinary focused-control value reporting here. + return false + } + if shaderProgress && (event.Source.Defunct || event.Source.Indeterminate) { + return false + } + if !shaderProgress { + var valid bool + percentage, valid = presentation.ProgressPercentage(event.Source) + if !valid { + return false + } + } + state := handler.state + if handler.foreground != nil && event.Foreground.Epoch != state.foregroundState.Epoch { + return true + } + if handler.focusGate.Locked() { + return true + } + // Like NVDA, refresh braille only if this is already the displayed object. + if event.Source.ID() == state.current.ID() { + state.current = event.Source + state.brailleSnapshot = event.Source + if handler.brailleOutput != nil { + handler.brailleOutput.EnqueueFrame(brailleFocusFrameWithOptions(event.Source, settings.Braille, settings.TextAttributes)) + } + } + background := event.ForegroundMismatch || state.owner.window.Valid() && + (eventWindow(event) != state.owner.window || event.Source.BusName != state.owner.applicationBus) + if background && !settings.ProgressBar.ReportBackground || handler.focusGate.Suspended() && !settings.ProgressBar.ReportBackground { + return true + } + beep, speak := state.progressBars.report(event.Source.ID(), percentage, settings.ProgressBar) + request := speechRequest{Role: "progress bar", Cause: event.Type, Append: true, + Window: eventWindow(event), BypassFocusGate: settings.ProgressBar.ReportBackground} + if beep { + request.Sound = []sound.Cue{{Name: sound.ProgressCueName(percentage)}} + } + if speak { + request.Text = fmt.Sprintf("%d percent", int(percentage)) + } + if beep || speak { + handler.speech.Enqueue(request) + } + return true +} diff --git a/internal/app/progress_bars_test.go b/internal/app/progress_bars_test.go new file mode 100644 index 0000000..94e439d --- /dev/null +++ b/internal/app/progress_bars_test.go @@ -0,0 +1,249 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "log/slog" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestSteamShaderProgressUsesSharedOutputAndGates(t *testing.T) { + for _, step := range []struct { + name, mode string + background, reportBackground bool + hidden, defunct, locked, stale bool + wantHandled, wantBeep, wantSpeech bool + }{ + {name: "beep", mode: "beep", wantHandled: true, wantBeep: true}, + {name: "speak", mode: "speak", wantHandled: true, wantSpeech: true}, + {name: "both", mode: "both", wantHandled: true, wantBeep: true, wantSpeech: true}, + {name: "off", mode: "off"}, + {name: "background suppressed", mode: "both", background: true, wantHandled: true}, + {name: "background enabled", mode: "both", background: true, reportBackground: true, wantHandled: true, wantBeep: true, wantSpeech: true}, + {name: "hidden", mode: "both", hidden: true}, + {name: "defunct", mode: "both", defunct: true}, + {name: "secure", mode: "both", locked: true, wantHandled: true}, + {name: "stale", mode: "both", stale: true, wantHandled: true}, + } { + t.Run(step.name, func(t *testing.T) { + settings := config.DefaultSettings() + settings.ProgressBar.OutputMode = step.mode + settings.ProgressBar.ReportBackground = step.reportBackground + live := &liveSettings{} + live.Store(settings) + speech := &fakeSpeechQueue{spoken: make(chan string, 8), requests: make(chan speechRequest, 8)} + frames := frameRecorder{frames: make(chan braille.Frame, 8)} + state := &eventLoopState{} + state.current = atspi.Snapshot{BusName: ":1.1", Path: "/button", Role: "button"} + before := state.current + gate := &focusGate{} + gate.secure.Store(step.locked) + handler := &accessibilityEventHandler{state: state, live: live, speech: speech, focusGate: gate, brailleOutput: frames} + event := atspi.NewEvent(atspi.AccessibleNameEvent, atspi.Snapshot{BusName: ":1.1", Path: "/shader-status", Role: "static", + ApplicationProcess: "steamwebhelper", StatesKnown: true, Visible: true, Showing: !step.hidden, Defunct: step.defunct}) + event.ForegroundMismatch = step.background + if step.stale { + handler.foreground = &titleProbeSource{} + state.foregroundState.Epoch = 1 + } + for _, percentage := range []int{18, 18, 19, 100} { + event.Source.Name = fmt.Sprintf("Processing Vulkan shaders (%d%%)", percentage) + if handled := handler.handle_progress_bar(event); handled != step.wantHandled { + t.Fatalf("handled=%t, want %t", handled, step.wantHandled) + } + } + wantCount := 0 + if step.wantBeep { + wantCount = 3 + } else if step.wantSpeech { + wantCount = 2 + } + if len(speech.requests) != wantCount { + t.Fatalf("got %d requests, want %d", len(speech.requests), wantCount) + } + if wantCount > 0 { + request := <-speech.requests + if !request.Append || (len(request.Sound) == 1) != step.wantBeep || (request.Text == "18 percent") != step.wantSpeech { + t.Fatalf("shader output: %+v", request) + } + } + if state.current.ID() != before.ID() || state.focusedID.Valid() || len(frames.frames) != 0 { + t.Fatal("shader progress changed focus or unrelated braille") + } + }) + } +} + +func TestProgressSecureEpochAndBrailleGates(t *testing.T) { + settings := config.DefaultSettings() + settings.ProgressBar.ReportBackground = true + live := &liveSettings{} + live.Store(settings) + speech := &fakeSpeechQueue{spoken: make(chan string, 4), requests: make(chan speechRequest, 4)} + frames := frameRecorder{frames: make(chan braille.Frame, 4)} + gate := &focusGate{} + state := &eventLoopState{} + event := atspi.NewEvent(atspi.ValueChangedEvent, atspi.Snapshot{BusName: ":1.1", Path: "/progress", Role: "progress bar", Name: "Copy", ValueKnown: true, CurrentValue: 25, MaximumValue: 100}) + state.current = event.Source + handler := &accessibilityEventHandler{state: state, live: live, speech: speech, brailleOutput: frames, focusGate: gate} + gate.secure.Store(true) + handler.handle_progress_bar(event) + if len(speech.requests) != 0 || len(frames.frames) != 0 { + t.Fatal("progress bypassed secure input") + } + gate.secure.Store(false) + handler.foreground = &titleProbeSource{} + state.foregroundState.Epoch = 2 + event.Foreground.Epoch = 1 + handler.handle_progress_bar(event) + if len(speech.requests) != 0 || len(frames.frames) != 0 { + t.Fatal("stale epoch produced progress output") + } + event.Foreground.Epoch = 2 + handler.handle_progress_bar(event) + if len(speech.requests) != 1 || len(frames.frames) != 1 { + t.Fatal("displayed progress failed to update") + } + if frame := <-frames.frames; frame.Text != "Copy 25% progress bar" { + t.Fatalf("progress braille: %+v", frame) + } + event.Source.Path, event.Source.CurrentValue = "/other-progress", 50 + handler.handle_progress_bar(event) + if len(frames.frames) != 0 { + t.Fatal("unrelated progress took over braille") + } +} + +func TestProgressShortcutCyclesNVDAOrderWithoutSaving(t *testing.T) { + settings := config.DefaultSettings() + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + worker.live = &liveSettings{} + worker.live.Store(settings) + message := "" + worker.announce = func(text string) { message = text } + for _, step := range []struct{ mode, message string }{ + {"both", "Beep and speak progress bar updates"}, {"off", "No progress bar updates"}, + {"speak", "Speak progress bar updates"}, {"beep", "Beep for progress bar updates"}, + } { + worker.handleSpeechCommand(context.Background(), input.CycleProgressBarOutput) + if worker.live.Load().ProgressBar.OutputMode != step.mode || worker.globalSettings.ProgressBar.OutputMode != step.mode || message != step.message { + t.Fatalf("progress shortcut: mode=%s, message=%q", worker.settings.ProgressBar.OutputMode, message) + } + } + for _, layout := range []input.KeyboardLayout{input.DesktopKeyboardLayout, input.LaptopKeyboardLayout} { + for _, browse := range []bool{false, true} { + bindings, err := input.ResolveCommandBindings(layout, browse, nil) + chord := input.CommandChord{Symbol: 'u', CthulhuModifier: true} + if layout == input.LaptopKeyboardLayout { + chord.Modifiers = 1 + if bindings[input.CommandChord{Symbol: 'u', CthulhuModifier: true}] != input.ReviewPreviousLine { + t.Fatal("laptop previous-line review changed") + } + } + if err != nil || bindings[chord] != input.CycleProgressBarOutput { + t.Fatalf("progress binding: layout=%v browse=%v err=%v", layout, browse, err) + } + } + } +} + +func TestProgressThresholdsAreIndependentAndBidirectional(t *testing.T) { + var history ProgressBarHistory + settings := config.DefaultProgressBarSettings() + settings.OutputMode = "both" + id := atspi.NewObjectID(":1.1", "/progress/one") + for _, step := range []struct { + value float64 + beep, speak bool + }{ + {0, true, true}, {0, false, false}, {0.9, false, false}, {1, true, false}, + {9.9, true, false}, {10, false, true}, {11, true, false}, + {1, true, false}, {0, true, true}, {100, true, true}, {99, true, false}, + } { + beep, speak := history.report(id, step.value, settings) + if beep != step.beep || speak != step.speak { + t.Fatalf("%g: beep=%t speech=%t", step.value, beep, speak) + } + } + if beep, speak := history.report(atspi.NewObjectID(":1.1", "/progress/two"), 99, settings); !beep || !speak { + t.Fatal("independent bar did not report its initial value") + } + for index := 0; index < 100; index++ { + history.report(atspi.NewObjectID(":1.1", "/progress/"+string(rune('A'+index))), 0, settings) + } + if len(history.entries) != 32 || len(history.order) != 32 { + t.Fatal("progress history is unbounded") + } +} + +func TestProgressModesBackgroundAndFocusOwnership(t *testing.T) { + for _, mode := range []string{"off", "beep", "speak", "both"} { + t.Run(mode, func(t *testing.T) { + settings := config.DefaultSettings() + settings.ProgressBar.OutputMode = mode + settings.EnableSound, settings.PlaySoundForRole = false, false + live := &liveSettings{} + live.Store(settings) + speech := &fakeSpeechQueue{spoken: make(chan string, 8), requests: make(chan speechRequest, 8)} + state := &eventLoopState{} + state.owner = windowOwner{window: atspi.NewObjectID(":1.1", "/window"), applicationBus: ":1.1", focus: atspi.NewObjectID(":1.1", "/button")} + before := state.owner + handler := &accessibilityEventHandler{state: state, live: live, speech: speech} + event := atspi.NewEvent(atspi.ValueChangedEvent, atspi.Snapshot{BusName: ":1.1", Path: "/progress", Role: "progress bar", ValueKnown: true, CurrentValue: 50.25, MaximumValue: 100, StatesKnown: true, Visible: true, Showing: true}) + event.Window = state.owner.window + handled := handler.handle_progress_bar(event) + if mode == "off" { + if handled || len(speech.requests) != 0 { + t.Fatal("off bypassed focused-control fallback") + } + return + } + if !handled { + t.Fatal("unfocused foreground progress was not handled") + } + request := <-speech.requests + if !request.Append || request.Text != map[string]string{"beep": "", "speak": "50 percent", "both": "50 percent"}[mode] { + t.Fatalf("progress speech = %+v", request) + } + if (len(request.Sound) != 0) != (mode == "beep" || mode == "both") { + t.Fatalf("progress sounds = %+v", request.Sound) + } + if len(request.Sound) != 0 && request.Sound[0].Name != "generated-progress-tone:50.25" { + t.Fatal("fractional pitch was rounded") + } + if state.owner != before || state.focusedID.Valid() || state.current.ID().Valid() { + t.Fatal("progress stole focus") + } + event.Source.CurrentValue = 75 + event.ForegroundMismatch = true + handler.handle_progress_bar(event) + if len(speech.requests) != 0 { + t.Fatal("background reporting enabled by default") + } + settings.ProgressBar.ReportBackground = true + live.Store(settings) + handler.handle_progress_bar(event) + if len(speech.requests) != 1 { + t.Fatal("opted-in background reporting was lost") + } + <-speech.requests + event.Source.Showing = false + if handler.handle_progress_bar(event) { + t.Fatal("offscreen progress did not use focused fallback") + } + event.Source.Showing, event.Source.Indeterminate = true, true + if handler.handle_progress_bar(event) { + t.Fatal("indeterminate progress generated output") + } + }) + } +} diff --git a/internal/app/progress_browser_native_test.go b/internal/app/progress_browser_native_test.go new file mode 100644 index 0000000..004efac --- /dev/null +++ b/internal/app/progress_browser_native_test.go @@ -0,0 +1,79 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "os" + "os/exec" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// Standard web progress must reach the shared handler without Steam policy. +func TestNativeBrowserProgress(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + if output, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "Tab").CombinedOutput(); err != nil { + t.Fatalf("fixture focus: %s, %v", output, err) + } + for { + select { + case event := <-adapter.Events(): + if event.Type == atspi.FocusedStateEvent && event.Detail1 == 1 && event.Source.Name == "Update progress" { + goto focused + } + case <-ctx.Done(): + t.Fatal("update button focus missing") + } + } +focused: + speech := &fakeSpeechQueue{spoken: make(chan string, 8), requests: make(chan speechRequest, 8)} + handler := &accessibilityEventHandler{state: &eventLoopState{}, speech: speech} + if output, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "space").CombinedOutput(); err != nil { + t.Fatalf("update progress: %s, %v", output, err) + } + seen := make(map[string]bool) + for len(seen) < 2 { + select { + case event := <-adapter.Events(): + if !isValueChangeEvent(event.Type) || event.Source.Role != "progress bar" { + continue + } + wantTone := "" + switch event.Source.Name { + case "Native progress": + wantTone = "generated-progress-tone:20" + case "ARIA progress": + wantTone = "generated-progress-tone:30" + default: + continue + } + if seen[event.Source.Name] { + continue + } + if !handler.handle_progress_bar(event) || len(speech.requests) != 1 { + t.Fatalf("web progress was lost: %+v", event) + } + request := <-speech.requests + if len(request.Sound) != 1 || request.Sound[0].Name != wantTone || !request.Append || request.Text != "" { + t.Fatalf("web progress output: %+v", request) + } + seen[event.Source.Name] = true + case <-ctx.Done(): + t.Fatalf("web progress events missing; received %v", seen) + } + } +} diff --git a/internal/app/progress_native_test.go b/internal/app/progress_native_test.go new file mode 100644 index 0000000..8ab98d6 --- /dev/null +++ b/internal/app/progress_native_test.go @@ -0,0 +1,128 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "context" + "fmt" + "log/slog" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestNativeProgressBars(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_PROGRESS") != "1" { + t.Skip("requires private X11/AT-SPI progress fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Error(err) + } + }() + fixture := exec.CommandContext(ctx, "python3", "../../tests/gtk_progress.py") + fixture.Stderr = os.Stderr + commands, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + ready, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { commands.Close(); fixture.Process.Kill(); fixture.Wait() }() + line, err := bufio.NewReader(ready).ReadString('\n') + if err != nil || strings.TrimSpace(line) != "ready" { + t.Fatalf("fixture: %q %v", line, err) + } + focus := func(title string) { + t.Helper() + windows, err := exec.Command("xdotool", "search", "--onlyvisible", "--name", "^"+title+"$").Output() + if err != nil { + t.Fatal(err) + } + if err := exec.Command("xdotool", "windowfocus", "--sync", strings.Fields(string(windows))[0]).Run(); err != nil { + t.Fatal(err) + } + } + focus("Progress probe") + settings := config.DefaultSettings() + settings.ProgressBar.OutputMode = "both" + live := &liveSettings{} + live.Store(settings) + speech := &fakeSpeechQueue{spoken: make(chan string, 16), requests: make(chan speechRequest, 16)} + state := &eventLoopState{} + handler := &accessibilityEventHandler{state: state, live: live, speech: speech, logger: slog.New(slog.DiscardHandler)} + update := func(value float64, hidden ...bool) atspi.Event { + t.Helper() + command := fmt.Sprint(value) + if len(hidden) != 0 && hidden[0] { + command = "hide " + command + } + if _, err := fmt.Fprintln(commands, command); err != nil { + t.Fatal(err) + } + for { + select { + case <-ctx.Done(): + t.Fatal("progress value event missing") + return atspi.Event{} + case event := <-adapter.Events(): + if isValueChangeEvent(event.Type) && event.Source.Role == "progress bar" && event.Source.CurrentValue == value { + return event + } + } + } + } + event := update(0.5) + if event.Source.Focused || !event.Source.Visible || !event.Source.Showing || event.ForegroundMismatch { + t.Fatalf("foreground progress capture: %+v", event) + } + state.owner.window, state.owner.applicationBus = event.Window, event.Source.BusName + if !handler.handle_progress_bar(event) { + t.Fatal("foreground progress was lost") + } + request := <-speech.requests + if request.Text != "50 percent" || len(request.Sound) != 1 || request.Sound[0].Name != "generated-progress-tone:50" { + t.Fatalf("foreground progress output: %+v", request) + } + focus("Other probe") + event = update(0.75) + if !event.ForegroundMismatch { + t.Fatal("native background progress was not identified") + } + handler.handle_progress_bar(event) + if len(speech.requests) != 0 { + t.Fatal("background output enabled by default") + } + settings.ProgressBar.ReportBackground = true + live.Store(settings) + handler.handle_progress_bar(event) + request = <-speech.requests + if request.Text != "75 percent" || len(request.Sound) != 1 { + t.Fatalf("background output: %+v", request) + } + event = update(0.9, true) + if event.Source.Showing || handler.handle_progress_bar(event) { + t.Fatal("hidden progress generated automatic output") + } +} diff --git a/internal/app/progress_settings.go b/internal/app/progress_settings.go new file mode 100644 index 0000000..5cea800 --- /dev/null +++ b/internal/app/progress_settings.go @@ -0,0 +1,35 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import "git.stormux.org/storm/cthulhu/internal/config" + +// The preferences worker owns shortcut changes, just like GUI changes. +// Follow NVDA+U's off -> speak -> beep -> both -> off order. Saving remains +// explicit; application profiles continue to inherit unchanged global values. +func (worker *preferencesWorker) cycle_progress_output() { + next := worker.settings + message := "" + switch next.ProgressBar.OutputMode { + case "both": + next.ProgressBar.OutputMode, message = "off", "No progress bar updates" + case "off": + next.ProgressBar.OutputMode, message = "speak", "Speak progress bar updates" + case "speak": + next.ProgressBar.OutputMode, message = "beep", "Beep for progress bar updates" + default: + next.ProgressBar.OutputMode, message = "both", "Beep and speak progress bar updates" + } + if worker.activeApp != "" { + worker.appSettings[worker.activeApp] = next + } else { + for application, settings := range worker.appSettings { + worker.appSettings[application] = config.RebaseApplicationSettings(worker.globalSettings, next, settings) + } + worker.globalSettings = next + } + worker.commit_settings(next) + worker.announceSpeechSetting(message) +} diff --git a/internal/app/prompt_presentation.go b/internal/app/prompt_presentation.go new file mode 100644 index 0000000..4871e4f --- /dev/null +++ b/internal/app/prompt_presentation.go @@ -0,0 +1,56 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +type promptPresentation struct { + state *eventLoopState + event atspi.Event + activation bool + focus bool +} + +func newPromptPresentation(state *eventLoopState, event atspi.Event) promptPresentation { + control := event.Source.Role == "button" || event.Source.Role == "tree table" || event.Source.Role == "table cell" + return promptPresentation{ + state: state, + event: event, + activation: event.Type == atspi.WindowActivatedEvent && control && event.WindowMessage != "", + focus: isFocusGainEvent(event) && control && state.pendingPromptWindow.Valid() && event.Window == state.pendingPromptWindow, + } +} + +func (prompt promptPresentation) focusSpeech(spoken, fallback presentation.Speech) (presentation.Speech, presentation.Speech) { + if prompt.focus && !prompt.state.pendingPromptTextAnnounced && prompt.event.WindowMessage != "" { + spoken = spoken.Prepend(prompt.event.WindowMessage, ", ") + fallback = spoken + } + return spoken, fallback +} + +func (prompt promptPresentation) appendFocus() bool { + return prompt.focus && (prompt.state.pendingPromptTextAnnounced || prompt.event.WindowMessage != "") +} + +func (prompt promptPresentation) finishFocus() { + if isFocusGainEvent(prompt.event) && (prompt.event.Source.Role == "button" || prompt.event.Source.Role == "tree table" || prompt.event.Source.Role == "table cell") { + prompt.state.pendingPromptWindow = atspi.ObjectID{} + prompt.state.pendingPromptTextAnnounced = false + } +} + +func (prompt promptPresentation) rememberWindow() { + if (prompt.event.Type == atspi.WindowCreateEvent || prompt.event.Type == atspi.WindowActivatedEvent) && + (prompt.event.Source.Role == "alert" || prompt.event.Source.Role == "frame" || prompt.activation) && + prompt.event.Window.Valid() { + prompt.state.pendingPromptWindow = prompt.event.Window + prompt.state.pendingPromptTextAnnounced = prompt.event.Source.Text != "" || prompt.activation + } +} diff --git a/internal/app/prompt_presentation_test.go b/internal/app/prompt_presentation_test.go new file mode 100644 index 0000000..ee2b76c --- /dev/null +++ b/internal/app/prompt_presentation_test.go @@ -0,0 +1,450 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestAlertMessageFinishesBeforeInitialButton(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 4), requests: make(chan speechRequest, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 5)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + window := atspi.NewObjectID(":1.4", "/question") + alert := atspi.NewSnapshot(window.Path, "Question", "alert", "", "Version 0.6.0 is available. Open the releases page in your browser?") + alert.BusName = window.BusName + created := atspi.NewEvent(atspi.WindowCreateEvent, alert) + created.Window = window + adapter.events <- created + activated := atspi.NewEvent(atspi.WindowActivatedEvent, atspi.NewSnapshot(window.Path, "Question", "alert", "", "")) + activated.Source.BusName = window.BusName + activated.Window = window + adapter.events <- activated + for _, item := range []struct{ path, name string }{{"/question/no", "No"}, {"/question/yes", "Yes"}} { + button := atspi.NewSnapshot(item.path, item.name, "button", "", "") + button.BusName = window.BusName + focused := atspi.NewEvent(atspi.FocusedStateEvent, button) + focused.Window = window + focused.Detail1 = 1 + adapter.events <- focused + } + + for index, expected := range []struct { + text string + append bool + }{ + {"Question, alert, Version 0.6.0 is available. Open the releases page in your browser?", false}, + {"No, button", true}, + {"Yes, button", false}, + } { + select { + case request := <-speech.requests: + if request.Text != expected.text || request.Append != expected.append { + t.Fatalf("request %d = %q append %t, want %q append %t", index, request.Text, request.Append, expected.text, expected.append) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for request %d", index) + } + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestSimpleFramePromptMessageFinishesBeforeButton(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3), requests: make(chan speechRequest, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + window := atspi.NewObjectID(":1.5", "/prompt") + frame := atspi.NewSnapshot(window.Path, "Alert", "frame", "", "Microsoft Windows has been found! Would you like to remove it?") + frame.BusName = window.BusName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, frame) + activated.Window = window + adapter.events <- activated + for _, item := range []struct{ path, name string }{{"/prompt/yes", "gtk-yes"}, {"/prompt/no", "gtk-no"}} { + button := atspi.NewSnapshot(item.path, item.name, "button", "", "") + button.BusName = window.BusName + focused := atspi.NewEvent(atspi.FocusedStateEvent, button) + focused.Window = window + focused.Detail1 = 1 + adapter.events <- focused + } + for index, expected := range []struct { + text string + append bool + }{ + {"Alert, frame, Microsoft Windows has been found! Would you like to remove it?", false}, + {"gtk-yes, button", true}, + {"gtk-no, button", false}, + } { + select { + case request := <-speech.requests: + if request.Text != expected.text || request.Append != expected.append { + t.Fatalf("request %d = %q append %t, want %q append %t", index, request.Text, request.Append, expected.text, expected.append) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for request %d", index) + } + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestSimplePromptRecoversMessageAtFirstButton(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3), requests: make(chan speechRequest, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + window := atspi.NewObjectID(":1.6", "/prompt") + frame := atspi.NewSnapshot(window.Path, "Alert", "frame", "", "") + frame.BusName = window.BusName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, frame) + activated.Window = window + adapter.events <- activated + button := atspi.NewSnapshot("/prompt/yes", "gtk-yes", "button", "", "") + button.BusName = window.BusName + focused := atspi.NewEvent(atspi.FocusedStateEvent, button) + focused.Window = window + focused.Detail1 = 1 + focused.WindowMessage = "Microsoft Windows has been found! Would you like to remove it?" + adapter.events <- focused + for index, expected := range []struct { + text string + append bool + }{ + {"Alert, frame", false}, + {"Microsoft Windows has been found! Would you like to remove it?, gtk-yes, button", true}, + } { + select { + case request := <-speech.requests: + if request.Text != expected.text || request.Append != expected.append { + t.Fatalf("request %d = %q append %t, want %q append %t", index, request.Text, request.Append, expected.text, expected.append) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for request %d", index) + } + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestListPromptAnnouncesQuestionBeforeChoices(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3), requests: make(chan speechRequest, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + window := atspi.NewObjectID(":1.9", "/list") + list := atspi.NewSnapshot("/list/choices", "", "tree table", "", "") + list.BusName = window.BusName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, list) + activated.Window = window + activated.WindowTitle = "Select Sound Type" + activated.WindowMessage = "Which sound type would you like to use?" + adapter.events <- activated + focused := atspi.NewEvent(atspi.FocusedStateEvent, list) + focused.Window = window + focused.Detail1 = 1 + adapter.events <- focused + for index, expected := range []struct { + text string + append bool + }{ + {"Select Sound Type, Which sound type would you like to use?", false}, + {"tree table", true}, + } { + select { + case request := <-speech.requests: + if request.Text != expected.text || request.Append != expected.append { + t.Fatalf("request %d = %q append %t, want %q append %t", index, request.Text, request.Append, expected.text, expected.append) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for request %d", index) + } + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestListPromptAnnouncesQuestionWhenActivationTargetsFirstCell(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 2), requests: make(chan speechRequest, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + window := atspi.NewObjectID(":1.9", "/power") + cell := atspi.NewSnapshot("/power/list/first", "Power off", "table cell", "", "") + cell.BusName = window.BusName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, cell) + activated.Window = window + activated.WindowTitle = "I38" + activated.WindowMessage = "Power options" + adapter.events <- activated + select { + case request := <-speech.requests: + if request.Text != "I38, Power options" { + t.Fatalf("activation speech = %q", request.Text) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for list prompt") + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestListPromptRecoversQuestionOnFocus(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 2), requests: make(chan speechRequest, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + window := atspi.NewObjectID(":1.10", "/list") + frame := atspi.NewSnapshot(window.Path, "Select Sound Type", "frame", "", "") + frame.BusName = window.BusName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, frame) + activated.Window = window + adapter.events <- activated + list := atspi.NewSnapshot("/list/choices", "", "tree table", "", "") + list.BusName = window.BusName + focused := atspi.NewEvent(atspi.FocusedStateEvent, list) + focused.Window = window + focused.Detail1 = 1 + focused.WindowMessage = "Which sound type would you like to use?" + adapter.events <- focused + for index, expected := range []struct { + text string + append bool + }{ + {"Select Sound Type, frame", false}, + {"Which sound type would you like to use?, tree table", true}, + } { + select { + case request := <-speech.requests: + if request.Text != expected.text || request.Append != expected.append { + t.Fatalf("request %d = %q append %t, want %q append %t", index, request.Text, request.Append, expected.text, expected.append) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for request %d", index) + } + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestFocusedButtonActivationAnnouncesPromptBeforeButton(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3), requests: make(chan speechRequest, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + window := atspi.NewObjectID(":1.7", "/prompt") + button := atspi.NewSnapshot("/prompt/yes", "gtk-yes", "button", "", "") + button.BusName = window.BusName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, button) + activated.Window = window + activated.WindowTitle = "Alert" + activated.WindowMessage = "Microsoft Windows has been found! Would you like to remove it?" + adapter.events <- activated + focused := atspi.NewEvent(atspi.FocusedStateEvent, button) + focused.Window = window + focused.Detail1 = 1 + adapter.events <- focused + other := atspi.NewSnapshot("/prompt/no", "gtk-no", "button", "", "") + other.BusName = window.BusName + focusedOther := atspi.NewEvent(atspi.FocusedStateEvent, other) + focusedOther.Window = window + focusedOther.Detail1 = 1 + adapter.events <- focusedOther + for index, expected := range []struct { + text string + append bool + }{ + {"Alert, Microsoft Windows has been found! Would you like to remove it?", false}, + {"gtk-yes, button", true}, + {"gtk-no, button", false}, + } { + select { + case request := <-speech.requests: + if request.Text != expected.text || request.Append != expected.append { + t.Fatalf("request %d = %q append %t, want %q append %t", index, request.Text, request.Append, expected.text, expected.append) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for request %d", index) + } + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestFocusedButtonActivationAfterFocusKeepsPrompt(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 2), requests: make(chan speechRequest, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + window := atspi.NewObjectID(":1.8", "/prompt") + button := atspi.NewSnapshot("/prompt/yes", "gtk-yes", "button", "", "") + button.BusName = window.BusName + button.Focused = true + focused := atspi.NewEvent(atspi.FocusedStateEvent, button) + focused.Window = window + focused.Detail1 = 1 + adapter.events <- focused + activated := atspi.NewEvent(atspi.WindowActivatedEvent, button) + activated.Window = window + activated.WindowTitle = "Alert" + activated.WindowMessage = "Microsoft Windows has been found! Would you like to remove it?" + adapter.events <- activated + for index, expected := range []string{ + "gtk-yes, button", + "Alert, Microsoft Windows has been found! Would you like to remove it?", + } { + select { + case request := <-speech.requests: + if request.Text != expected { + t.Fatalf("request %d = %q, want %q", index, request.Text, expected) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for request %d", index) + } + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("timed out waiting for event loop to stop") + } +} + +func TestTerminalTextChangeSuppressesPromptReplayButPreservesNavigation(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + terminal := atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "Prompt") + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, terminal, "Output") + if got := <-speech.spoken; got != "Output" { + t.Fatalf("text = %q", got) + } + adapter.events <- atspi.NewEvent(atspi.CaretEvent, terminal) + // The caret timer must have fired before the next navigation event. + select { + case got := <-speech.spoken: + t.Fatalf("prompt replayed after insertion: %q", got) + case <-time.After(30 * time.Millisecond): + } + terminal.CaretCharacter = "P" + adapter.events <- atspi.NewEvent(atspi.CaretEvent, terminal) + select { + case got := <-speech.spoken: + if got != "P" { + t.Fatalf("caret navigation = %q", got) + } + case <-time.After(time.Second): + t.Fatal("caret navigation was suppressed") + } + terminal.CaretCharacter = "" + terminal.Text = "Another line" + adapter.events <- atspi.NewEvent(atspi.CaretEvent, terminal) + select { + case got := <-speech.spoken: + if got != "Another line" { + t.Fatalf("line navigation = %q", got) + } + case <-time.After(time.Second): + t.Fatal("line navigation was suppressed") + } + cancel() + <-completed +} diff --git a/internal/app/qt_controls_native_test.go b/internal/app/qt_controls_native_test.go new file mode 100644 index 0000000..a7ed8b9 --- /dev/null +++ b/internal/app/qt_controls_native_test.go @@ -0,0 +1,220 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" +) + +func TestNativeQtControlStates(t *testing.T) { + version := os.Getenv("CTHULHU_NATIVE_QT_CONTROLS") + if version != "5" && version != "6" { + t.Skip("requires private Qt control fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + native := atspi.New() + if err := native.Start(ctx); err != nil { + t.Fatal(err) + } + defer native.Stop(context.Background()) + adapter := &menuRecordingAdapter{Adapter: native, events: make(chan atspi.Event, 256)} + observed := make(chan atspi.Event, 256) + pumpDone := make(chan struct{}) + go func() { + defer close(pumpDone) + for { + select { + case event := <-native.Events(): + select { + case observed <- event: + case <-ctx.Done(): + return + } + select { + case adapter.events <- event: + case <-ctx.Done(): + return + } + case <-ctx.Done(): + return + } + } + }() + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 256)} + frames := make(chan braille.Frame, 256) + done := make(chan struct{}) + go func() { + defer close(done) + output := outputQueue{speech: queue, braille: frameRecorder{frames: frames}} + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), output, adapter, nil, nil, 0, + nil, nil, nil, nil) + }() + defer func() { cancel(); <-done; <-pumpDone }() + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + waitEvent := func(name, eventType string, checked bool) atspi.Event { + t.Helper() + for { + select { + case event := <-observed: + if event.Source.Name == name { + t.Logf("event: %s detail=%d checked=%v checkable=%v focused=%v window=%s", event.Type, event.Detail1, event.Source.Checked, event.Source.Checkable, event.Source.Focused, event.Window.Path) + } + if event.Source.Name == name && event.Type == eventType && event.Source.Checked == checked && + (eventType != atspi.FocusedStateEvent || event.Detail1 == 1) { + return event + } + case <-ctx.Done(): + t.Fatalf("missing %s event for %s checked=%v", eventType, name, checked) + } + } + } + waitSpeech := func(want string) { + t.Helper() + timer := time.NewTimer(2 * time.Second) + defer timer.Stop() + for { + select { + case request := <-queue.requests: + if request.Text == want || strings.HasSuffix(request.Text, ", "+want) { + t.Logf("speech: %q", request.Text) + return + } + case <-timer.C: + t.Fatalf("missing speech %q", want) + } + } + } + waitBraille := func(want string) { + t.Helper() + timer := time.NewTimer(2 * time.Second) + defer timer.Stop() + for { + select { + case frame := <-frames: + if frame.Text == want || strings.HasSuffix(frame.Text, " "+want) { + t.Logf("Braille: %q", frame.Text) + return + } + case <-timer.C: + t.Fatalf("missing Braille %q", want) + } + } + } + // Qt 5 omits STATE_CHECKABLE. Checked-state evidence must survive the + // next uncheck without assigning a state to unrelated menu commands. + for _, probe := range []struct{ key, name string }{{"F6", "Optional feature"}, {"F8", "Context option"}} { + for step, checked := range []bool{false, true, false} { + keys(probe.key) + event := waitEvent(probe.name, atspi.FocusedStateEvent, checked) + if event.Source.Checkable != (version == "6" || step > 0) { + t.Fatalf("Qt %s checkable metadata = %v", version, event.Source.Checkable) + } + role, suffix, indicator := "check menu item", ", not checked", "< > " + if checked { + suffix, indicator = ", checked", " " + } else if version == "5" && step == 0 { + role, suffix, indicator = "menu item", "", "" + } + waitSpeech(probe.name + ", " + role + suffix) + brailleText := indicator + probe.name + if role == "check menu item" { + brailleText += " check menu item" + } + waitBraille(brailleText) + if step < 2 { + keys("Return") + } else { + keys("Escape") + } + } + } + keys("F7") + waitEvent("Ordinary action", atspi.FocusedStateEvent, false) + waitSpeech("Ordinary action, menu item") + waitBraille("Ordinary action") + keys("Escape") + // Traverse between context-only entries and actions shared with the + // menu bar, in both directions and after reopening the popup. + for range 2 { + keys("F8") + waitEvent("Context option", atspi.FocusedStateEvent, false) + waitSpeech("Context option, check menu item, not checked") + for _, step := range []struct{ key, name string }{ + {"Down", "Ordinary action"}, {"Down", "Context command"}, + {"Down", "Optional feature"}, {"Up", "Context command"}, + {"Up", "Ordinary action"}, {"Up", "Context option"}, + } { + keys(step.key) + waitEvent(step.name, atspi.FocusedStateEvent, false) + wantSpeech, wantBraille := step.name+", menu item", step.name + if step.name == "Optional feature" || step.name == "Context option" { + wantSpeech = step.name + ", check menu item, not checked" + wantBraille = "< > " + step.name + " check menu item" + } + waitSpeech(wantSpeech) + waitBraille(wantBraille) + } + keys("Escape") + } + if version == "6" { + // When the provider exports CHECKABLE, withdrawing that capability is + // authoritative and must retire the prior evidence. + keys("F12") + keys("F6") + event := waitEvent("Optional feature", atspi.FocusedStateEvent, false) + if event.Source.Checkable { + t.Fatal("explicit removal of checkability was ignored") + } + waitSpeech("Optional feature, menu item") + waitBraille("Optional feature") + keys("Escape") + } + // Replacing an action with an ordinary action of the same name must not + // inherit the removed accessible's checkability evidence. + keys("F11") + keys("F6") + event := waitEvent("Optional feature", atspi.FocusedStateEvent, false) + if event.Source.Checkable { + t.Fatal("replacement action inherited checkability") + } + waitSpeech("Optional feature, menu item") + waitBraille("Optional feature") + keys("Escape") + for _, probe := range []struct{ key, name string }{{"F9", "Updates"}, {"F10", "Power"}} { + if probe.key == "F9" { + keys("F10") + } else { + keys("F9") + } + keys(probe.key) + waitEvent(probe.name, atspi.FocusedStateEvent, false) + waitSpeech(probe.name + ", check box, not checked") + for _, checked := range []bool{true, false} { + keys("space") + waitEvent(probe.name, "object:state-changed:checked", checked) + want, indicator := "not checked", "< > " + if checked { + want, indicator = "checked", " " + } + waitSpeech(want) + waitBraille(indicator + probe.name + " check box") + } + } +} diff --git a/internal/app/radio_sound.go b/internal/app/radio_sound.go new file mode 100644 index 0000000..6a04615 --- /dev/null +++ b/internal/app/radio_sound.go @@ -0,0 +1,85 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +const radioFocusSoundDelay = 250 * time.Millisecond + +// GTK can focus an unchecked radio before selecting it. Retain one state cue +// in the event loop while speech and Braille update immediately. A checked +// event replaces it; focus/input changes, lock and shutdown retire it. +type pendingRadioSound struct { + pendingPresentation + inputSequence uint64 +} + +func (presenter *eventPresenter) coalesce_radio_sound(event atspi.Event, cues []sound.Cue) []sound.Cue { + pending := &presenter.state.pending.radioSound + if isFocusGainEvent(event) && event.Source.ID() != pending.event.Source.ID() { + pending.clear() + } + if event.Source.Role != "radio button" { + return cues + } + if event.Type == "object:state-changed:checked" || event.Source.Checked { + pending.clear() + return cues + } + if !isFocusGainEvent(event) { + return cues + } + for index, cue := range cues { + if cue.Name != "radiobutton_unchecked" { + continue + } + sequence := recentInput(presenter.inputSource).InputSequence + if pending.event.Source.ID() != event.Source.ID() || pending.inputSequence != sequence || pending.ready == nil { + pending.schedule(event, input.NoIntent, radioFocusSoundDelay) + pending.inputSequence = sequence + presenter.logger.Debug("deferred unchecked radio focus sound") + } + retained := append([]sound.Cue(nil), cues[:index]...) + return append(retained, cues[index+1:]...) + } + return cues +} + +func (presenter *eventPresenter) flush_radio_sound(gate *focusGate) { + pending := &presenter.state.pending.radioSound + sequence := pending.inputSequence + event, _ := pending.take() + state := presenter.state + if event.Type == "" || gate.Locked() || gate.Suspended() || + state.focusedID != event.Source.ID() || state.current.ID() != event.Source.ID() || + state.current.Defunct || state.owner.window != eventWindow(event) || + recentInput(presenter.inputSource).InputSequence != sequence { + return + } + options := state.presentationOptions + if presenter.live != nil { + options = presentationSettingsFromConfig(presenter.live.Load(), true) + options.SoundCueAvailable = state.presentationOptions.SoundCueAvailable + } + event.Type = "object:state-changed:checked" + event.Source = state.current + // Admission already verified the cue. Let the output queue provide its + // normal speech fallback if the asset disappears before delayed playback. + options.SoundCueAvailable = nil + cues := presentation.EventSoundCues(event, options) + if len(cues) == 0 { + return + } + fallback := presentationFallbackSpeech(event, options) + presenter.speech.Enqueue(speechRequest{Sound: cues, FallbackText: fallback.Text, FallbackChunks: fallback.Chunks, + Role: event.Source.Role, Cause: "radio-focus-state"}) + presenter.logger.Debug("queued settled radio focus sound", "cue", cues[0].Name) +} diff --git a/internal/app/radio_sound_test.go b/internal/app/radio_sound_test.go new file mode 100644 index 0000000..a1e0387 --- /dev/null +++ b/internal/app/radio_sound_test.go @@ -0,0 +1,146 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +func radio_sound_fixture(t *testing.T) (*eventPresenter, *fakeSpeechQueue, func(atspi.Event)) { + t.Helper() + logger := slog.New(slog.DiscardHandler) + state := &eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + state.presentationOptions.EnableSound = true + state.presentationOptions.PlaySoundForState = true + state.presentationOptions.RoleSoundPresentation = "sound_only" + queue := &fakeSpeechQueue{spoken: make(chan string, 8), requests: make(chan speechRequest, 8)} + presenter := &eventPresenter{state: state, logger: logger, speech: queue} + handler := &accessibilityEventHandler{state: state, logger: logger} + t.Cleanup(state.pending.clear) + return presenter, queue, func(event atspi.Event) { + if !handler.acceptFocusedEvent(event, input.Activity{}) { + presenter.speak(event) + } + } +} + +func TestRadioFocusSoundCoalescesSelectionWithoutDelayingLabel(t *testing.T) { + presenter, queue, present := radio_sound_fixture(t) + option := atspi.Snapshot{BusName: ":1.7", Path: "/radio", Role: "radio button", Name: "Laptop", Mnemonic: "l"} + present(atspi.NewEvent(atspi.FocusEvent, option)) + request := <-queue.requests + if !strings.Contains(request.Text, "Laptop") || len(request.Sound) != 0 || presenter.state.pending.radioSound.ready == nil { + t.Fatalf("focus label/sound = %+v", request) + } + // The old member loses selection before GTK checks the focused member. + old := option + old.Path = "/previous" + present(atspi.NewEvent("object:state-changed:checked", old)) + if len(queue.requests) != 0 { + t.Fatal("unfocused member emitted a state sound") + } + option.Checked = true + checked := atspi.NewEvent("object:state-changed:checked", option) + checked.Source.Mnemonic = "" // State-only native captures skip mnemonic lookup. + checked.Detail1 = 1 + present(checked) + request = <-queue.requests + if len(request.Sound) != 1 || request.Sound[0].Name != "radiobutton_checked" || presenter.state.pending.radioSound.ready != nil { + t.Fatalf("selected sound = %+v", request) + } + if presenter.state.current.Mnemonic != option.Mnemonic { + t.Fatal("state update discarded focus metadata") + } + present(atspi.NewEvent(atspi.FocusEvent, option)) + if len(queue.requests) != 0 { + t.Fatal("duplicate focus replayed selected sound") + } +} + +func TestRadioFocusSoundRetiresStalePendingState(t *testing.T) { + for _, change := range []string{"none", "focus", "input", "window", "lock", "handoff", "defunct", "disabled"} { + t.Run(change, func(t *testing.T) { + presenter, queue, present := radio_sound_fixture(t) + option := atspi.Snapshot{BusName: ":1.7", Path: "/radio", Role: "radio button", Name: "Option"} + present(atspi.NewEvent(atspi.FocusEvent, option)) + <-queue.requests + gate := &focusGate{} + switch change { + case "focus": + present(atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: ":1.7", Path: "/next", Role: "button", Name: "Next"})) + <-queue.requests + case "input": + presenter.inputSource = fixedInputActivity{activity: input.Activity{InputSequence: 1}} + case "window": + presenter.state.owner.window = atspi.NewObjectID(":1.7", "/other") + case "lock": + gate.secure.Store(true) + case "handoff": + gate.suspended.Store(true) + case "defunct": + presenter.state.current.Defunct = true + case "disabled": + presenter.state.presentationOptions.EnableSound = false + } + presenter.flush_radio_sound(gate) + if change != "none" { + if len(queue.requests) != 0 { + t.Fatal("retired focus emitted a delayed sound") + } + return + } + request := <-queue.requests + if request.Text != "" || request.FallbackText != "not selected" || len(request.Sound) != 1 || request.Sound[0].Name != "radiobutton_unchecked" { + t.Fatalf("settled unchecked sound/fallback = %+v", request) + } + }) + } +} + +func TestProcessEventsFlushesUncheckedRadioSound(t *testing.T) { + presenter, queue, _ := radio_sound_fixture(t) + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + ctx, cancel := context.WithCancel(t.Context()) + done := make(chan error, 1) + go func() { + done <- processEvents(ctx, presenter.logger, queue, adapter, 0, presenter.state.presentationOptions) + }() + t.Cleanup(func() { cancel(); <-done }) + adapter.events <- atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: ":1.7", Path: "/radio", Role: "radio button", Name: "Option"}) + for index := range 2 { + select { + case request := <-queue.requests: + if index == 0 && (request.Text == "" || len(request.Sound) != 0) { + t.Fatalf("label was deferred or played unchecked sound: %+v", request) + } + if index == 1 && (len(request.Sound) != 1 || request.Sound[0] != (sound.Cue{Name: "radiobutton_unchecked"})) { + t.Fatalf("unchecked focus sound = %+v", request) + } + case <-time.After(time.Second): + t.Fatal("radio focus presentation did not finish") + } + } +} + +func TestDeferredRadioSoundPreservesUnavailableCueFallback(t *testing.T) { + presenter, queue, present := radio_sound_fixture(t) + present(atspi.NewEvent(atspi.FocusEvent, atspi.Snapshot{BusName: ":1.7", Path: "/radio", Role: "radio button", Name: "Option"})) + <-queue.requests + presenter.state.presentationOptions.SoundCueAvailable = func(string) bool { return false } + presenter.speech = outputQueue{speech: queue, sounds: rejectingSound{}} + presenter.flush_radio_sound(nil) + if request := <-queue.requests; request.Text != "not selected" { + t.Fatalf("missing state-sound fallback: %+v", request) + } +} diff --git a/internal/app/read_all.go b/internal/app/read_all.go new file mode 100644 index 0000000..4063934 --- /dev/null +++ b/internal/app/read_all.go @@ -0,0 +1,96 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "log/slog" + "strings" + "unicode" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func presentReadAllResult(logger *slog.Logger, speech speechEnqueuer, result review.Result, options presentation.Options) { + if result.ReadAllContext == nil || result.ReadAllContext.Err() != nil { + return + } + text := "" + var parts []readAllPart + if result.Err != nil { + logger.Warn("read all failed", "error", result.Err) + text = "Could not read from current location." + } else { + // Keep semantic roles audible in continuous reading, without firing all + // the page's sound cues before the speech has reached those objects. + options.RoleSoundPresentation = "sound_and_speech" + // Python reads each cell once in Say All rather than expanding every + // cell into the same complete row. + reading := config.DefaultSettings().Reading + if options.Reading != nil { + reading = *options.Reading + } + reading.ReadFullRowInDocumentTable, reading.ReadFullRowInSpreadSheet = false, false + options.Reading = &reading + options.ReadFullRowInGUITable = false + for index, line := range result.ReadAllLines { + if spoken := presentation.DocumentLineSpeechWithOptions(line, options); spoken.Text != "" { + var began func() + if result.ReadAllProgress != nil { + began = func() { result.ReadAllProgress(index) } + } + values := spoken.Chunks + if len(values) == 0 { + values = []string{spoken.Text} + } + var chunks []readAllPart + for _, value := range values { + chunks = append(chunks, readAllLineParts(value, began, options.SayAllStyle)...) + began = nil + } + chunks[0].Line = document_speech_line(line) + for index := range chunks { + chunks[index].VoiceType = document_line_voice(line) + } + chunks[0].Context = line.Context + parts = append(parts, chunks...) + } + } + } + if text != "" || len(parts) != 0 { + speech.Enqueue(speechRequest{Text: text, ReadAll: parts, Role: "system", Cause: "read-all", context: result.ReadAllContext}) + } +} + +// Keep each source line's first callback attached to its first spoken chunk. +// The review worker tracks line positions, so sentence mode splits within a +// line and never merges lines whose separate progress updates drive the caret. +func readAllLineParts(text string, began func(), style string) []readAllPart { + if style != "sentence" { + return []readAllPart{{Text: text, Began: began}} + } + runes := []rune(text) + var parts []readAllPart + start := 0 + for index, value := range runes { + if value != '.' && value != '!' && value != '?' { + continue + } + if index+1 < len(runes) && !unicode.IsSpace(runes[index+1]) { + continue + } + chunk := strings.TrimSpace(string(runes[start : index+1])) + if chunk != "" { + parts = append(parts, readAllPart{Text: chunk, Began: began}) + began = nil + } + start = index + 1 + } + if tail := strings.TrimSpace(string(runes[start:])); tail != "" { + parts = append(parts, readAllPart{Text: tail, Began: began}) + } + return parts +} diff --git a/internal/app/read_all_test.go b/internal/app/read_all_test.go new file mode 100644 index 0000000..fb13622 --- /dev/null +++ b/internal/app/read_all_test.go @@ -0,0 +1,193 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bytes" + "context" + "errors" + "log/slog" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/logging" +) + +type continuousSpeaker struct { + started chan string + finish chan struct{} +} + +func TestReadAllSentencePartsKeepLineProgress(t *testing.T) { + progress := 0 + parts := readAllLineParts("First sentence. Second sentence! Last words", func() { progress++ }, "sentence") + if len(parts) != 3 || parts[0].Text != "First sentence." || + parts[1].Text != "Second sentence!" || parts[2].Text != "Last words" { + t.Fatalf("sentence parts = %#v", parts) + } + if parts[0].Began == nil || parts[1].Began != nil || parts[2].Began != nil { + t.Fatalf("line progress callbacks = %#v", parts) + } + parts[0].Began() + if progress != 1 { + t.Fatalf("progress = %d", progress) + } + line := readAllLineParts("First sentence. Second sentence!", nil, "line") + if len(line) != 1 || line[0].Text != "First sentence. Second sentence!" { + t.Fatalf("line part = %#v", line) + } +} + +func TestReadAllContextArrivesAtItsLine(t *testing.T) { + speaker := &continuousSpeaker{started: make(chan string, 6), finish: make(chan struct{}, 2)} + speaker.finish <- struct{}{} + speaker.finish <- struct{}{} + reading := config.DefaultSettings().Reading + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.reading = func() config.ReadingSettings { return reading } + list := atspi.Snapshot{BusName: ":1.42", Path: "/list", Role: "list", Name: "Items"} + request := speechRequest{ReadAll: []readAllPart{ + {Text: "Before", Context: []atspi.Snapshot{}}, + {Text: "Inside", Context: []atspi.Snapshot{list}}, + }} + if err := worker.deliver(context.Background(), request); err != nil { + t.Fatal(err) + } + for _, want := range []string{"Before", "Items list", "Inside"} { + if got := <-speaker.started; got != want { + t.Fatalf("spoken %q, want %q", got, want) + } + } + reading.SayAllContextList = false + worker.speechContext = nil + speaker.finish <- struct{}{} + if err := worker.deliver(context.Background(), speechRequest{ReadAll: []readAllPart{{Text: "Inside again", Context: []atspi.Snapshot{list}}}}); err != nil { + t.Fatal(err) + } + if got := <-speaker.started; got != "Inside again" || len(speaker.started) != 0 { + t.Fatalf("disabled list context speech = %q; queued = %d", got, len(speaker.started)) + } +} + +func TestReadAllDiagnosticsIncludeOnlyDeliveredParts(t *testing.T) { + var output bytes.Buffer + speaker := &continuousSpeaker{started: make(chan string, 3), finish: make(chan struct{}, 1)} + speaker.finish <- struct{}{} + worker := newSpeechWorker(logging.New(&output, logging.Options{Level: slog.LevelDebug}), speaker) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + request := speechRequest{Cause: "read-all", Role: "system", ReadAll: []readAllPart{ + {Text: "First line"}, {Text: "Second line", Began: cancel}, {Text: "Unread line"}, + }} + if err := worker.deliver(ctx, request); !errors.Is(err, context.Canceled) { + t.Fatalf("interrupted reading: %v", err) + } + for _, expected := range []string{`"utterance":"First line"`, `"utterance":"Second line"`, `"read_all_index":1`} { + if !strings.Contains(output.String(), expected) { + t.Fatalf("reading diagnostics missing %s: %s", expected, output.String()) + } + } + if strings.Contains(output.String(), "Unread line") { + t.Fatalf("logged reading which never reached the backend: %s", output.String()) + } +} + +func (*continuousSpeaker) Connect(context.Context) error { return nil } +func (*continuousSpeaker) Close(context.Context) error { return nil } +func (*continuousSpeaker) Cancel(context.Context) error { return nil } +func (speaker *continuousSpeaker) Speak(_ context.Context, text string) error { + speaker.started <- text + return nil +} +func (speaker *continuousSpeaker) SpeakAndWait(ctx context.Context, text string, began func()) error { + if began != nil { + began() + } + speaker.started <- text + select { + case <-speaker.finish: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func TestReadAllQueuesPassiveFocusAndInterruptsOnNewInput(t *testing.T) { + for _, cause := range []string{"key", "focus"} { + t.Run(cause, func(t *testing.T) { + speaker := &continuousSpeaker{started: make(chan string, 4), finish: make(chan struct{})} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.Start(context.Background()) + defer worker.Stop(context.Background()) + ctx := worker.BeginReadAll(context.Background(), 100) + // The initiating key can reach XRecord after command dispatch. + if worker.InterruptForInput(input.Event{Pressed: true, Timestamp: 100}) || ctx.Err() != nil { + t.Fatal("read all canceled by its initiating key") + } + progress := make(chan int, 3) + worker.Enqueue(speechRequest{Cause: "read-all", context: ctx, ReadAll: []readAllPart{ + {Text: "First", Began: func() { progress <- 1 }}, + {Text: "Second", Began: func() { progress <- 2 }}, + {Text: "Third", Began: func() { progress <- 3 }}, + }}) + waitText := func(want string) { + t.Helper() + select { + case got := <-speaker.started: + if got != want { + t.Fatalf("speech %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } + waitText("First") + if <-progress != 1 { + t.Fatal("wrong starting position") + } + select { + case <-speaker.started: + t.Fatal("advanced before speech completed") + default: + } + speaker.finish <- struct{}{} + waitText("Second") + if <-progress != 2 { + t.Fatal("wrong second position") + } + if cause == "key" { + if !worker.InterruptForInput(input.Event{Pressed: true, Timestamp: 101}) { + t.Fatal("new key ignored") + } + } + worker.Enqueue(speechRequest{Text: "New focus", Cause: "focus:"}) + if cause == "focus" { + if ctx.Err() != nil { + t.Fatal("passive focus canceled Say All") + } + speaker.finish <- struct{}{} + waitText("Third") + if <-progress != 3 { + t.Fatal("passive focus changed the reading position") + } + speaker.finish <- struct{}{} + } else { + if ctx.Err() == nil { + t.Fatal("new input did not cancel Say All") + } + select { + case <-progress: + t.Fatal("reading position advanced after interruption") + default: + } + } + waitText("New focus") + }) + } +} diff --git a/internal/app/reading_context.go b/internal/app/reading_context.go new file mode 100644 index 0000000..a35145a --- /dev/null +++ b/internal/app/reading_context.go @@ -0,0 +1,131 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func (worker *speechWorker) context_messages(ancestors []atspi.Snapshot) []string { + return worker.context_messages_for(ancestors, false) +} + +func (worker *speechWorker) context_messages_for(ancestors []atspi.Snapshot, sayAll bool) []string { + if ancestors == nil || worker.reading == nil { + return nil + } + current := make([]atspi.Snapshot, 0, len(ancestors)) + for _, ancestor := range ancestors { + if presentation.ContextType(ancestor) != "" { + current = append(current, ancestor) + } + } + previous := worker.speechContext + worker.speechContext = current + settings := worker.reading() + contains := func(values []atspi.Snapshot, candidate atspi.Snapshot) bool { + for _, item := range values { + if item.ID() == candidate.ID() && item.Role == candidate.Role && item.XMLRoles == candidate.XMLRoles { + return true + } + } + return false + } + var messages []string + panelMessages := make(map[string]bool) + appendMessage := func(item atspi.Snapshot, message string) { + // Keep every container identity for later transitions, but say an + // identical panel label only once in this transition. + if presentation.ContextType(item) == "panel" { + if panelMessages[message] { + return + } + panelMessages[message] = true + } + messages = append(messages, message) + } + enabled := presentation.ContextEnabled + verbosity := 0 + if worker.verbosity != nil { + verbosity = worker.verbosity() + } + if sayAll { + enabled = presentation.SayAllContextEnabled + } + for _, item := range previous { + if !contains(current, item) && enabled(presentation.ContextType(item), settings) { + appendMessage(item, "Leaving "+presentation.ContextLabel(item)+".") + } + } + for index := len(current) - 1; index >= 0; index-- { + item := current[index] + if !contains(previous, item) && enabled(presentation.ContextType(item), settings) { + appendMessage(item, presentation.ContextCountLabel(item, verbosity)) + } + } + return messages +} + +func (worker *speechWorker) deliver_context(ctx context.Context, request speechRequest) error { + if request.ResetContext { + worker.speechContext = nil + return nil + } + return worker.deliver_context_for(ctx, request.Context, false) +} + +func (browser *browserModeController) speech_context_enabled() bool { + return browser != nil && browser.ready && browser.mode == review.BrowseMode && browser.document.Valid() +} + +// Review results can also come from focus mode or native text. Capture the +// mode on the event loop rather than reading browser state on speech delivery. +type contextSpeechQueue struct { + speechEnqueuer + enabled bool +} + +func (queue contextSpeechQueue) Enqueue(request speechRequest) { + request.ResetContext = request.ResetContext || !queue.enabled + queue.speechEnqueuer.Enqueue(request) +} + +func (worker *speechWorker) deliver_context_for(ctx context.Context, ancestors []atspi.Snapshot, sayAll bool) error { + for _, message := range worker.context_messages_for(ancestors, sayAll) { + worker.logDelivery(ctx, speechRequest{Role: "system", Cause: "reading-context", Append: true}, message, -1) + if voiced, ok := worker.speaker.(interface { + SpeakVoice(context.Context, string, string) error + }); ok { + if err := voiced.SpeakVoice(ctx, message, "system"); err != nil { + return err + } + } else if err := worker.speaker.Speak(ctx, message); err != nil { + return err + } + } + return nil +} + +func document_line_voice(line atspi.DocumentLine) string { + for _, content := range line.Contents { + if content.Snapshot.Role == "link" { + return "hyperlink" + } + } + return "default" +} + +func ancestor_voice(ancestors []atspi.Snapshot) string { + for _, ancestor := range ancestors { + if ancestor.Role == "link" { + return "hyperlink" + } + } + return "" +} diff --git a/internal/app/reading_context_test.go b/internal/app/reading_context_test.go new file mode 100644 index 0000000..88a427b --- /dev/null +++ b/internal/app/reading_context_test.go @@ -0,0 +1,96 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestContextAnnouncementsOnlyInBrowseMode(t *testing.T) { + logger := slog.New(slog.DiscardHandler) + queue := &fakeSpeechQueue{spoken: make(chan string, 16), requests: make(chan speechRequest, 16)} + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(logger, speaker) + worker.reading = func() config.ReadingSettings { return config.DefaultSettings().Reading } + browser := &browserModeController{} + state := &eventLoopState{} + state.presentationOptions = presentation.DefaultOptions() + presenter := eventPresenter{state: state, logger: logger, speech: queue, browser: browser} + table := atspi.Snapshot{BusName: ":1.42", Path: "/table", Role: "table", Name: "Timeline"} + control := atspi.Snapshot{BusName: table.BusName, Path: "/item", Role: "text", Name: "Item", + SpeechContext: []atspi.Snapshot{table}} + check := func(snapshot atspi.Snapshot, want []string) { + t.Helper() + // Each step represents fresh focus, even if its label is unchanged. + state.lastSpokenPath = "" + presenter.speak(atspi.NewEvent(atspi.FocusEvent, snapshot)) + speaker.parts = nil + if len(queue.requests) != 1 { + t.Fatalf("queued %d requests", len(queue.requests)) + } + if err := worker.deliver(context.Background(), <-queue.requests); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(speaker.parts, want) { + t.Fatalf("speech = %q, want %q", speaker.parts, want) + } + } + check(control, []string{"Item", "text"}) + terminal := atspi.Snapshot{BusName: ":1.43", Path: "/terminal", Role: "terminal", Name: "Terminal", + SpeechContext: []atspi.Snapshot{}} + check(terminal, []string{"Terminal", "terminal"}) + if len(worker.speechContext) != 0 { + t.Fatal("native context was retained") + } + browser.ready, browser.mode = true, review.BrowseMode + browser.document = atspi.NewObjectID(table.BusName, "/document") + check(control, []string{"Timeline table", "Item", "text"}) + outside := control + outside.Name, outside.SpeechContext = "Outside", []atspi.Snapshot{} + check(outside, []string{"Leaving Timeline table.", "Outside", "text"}) + check(control, []string{"Timeline table", "Item", "text"}) + // A workspace switch must clear browser context without saying its exit, + // even while asynchronous browser discovery still holds the old mode. + check(terminal, []string{"Terminal", "terminal"}) + check(control, []string{"Timeline table", "Item", "text"}) + browser.mode = review.FocusMode + check(control, []string{"Item", "text"}) + browser.mode = review.BrowseMode + check(control, []string{"Timeline table", "Item", "text"}) + browser.ready = false + check(control, []string{"Item", "text"}) +} + +func TestReviewContextSuppressedOutsideBrowseMode(t *testing.T) { + logger := slog.New(slog.DiscardHandler) + for _, enabled := range []bool{false, true} { + queue := &fakeSpeechQueue{spoken: make(chan string, 4), requests: make(chan speechRequest, 4)} + scoped := contextSpeechQueue{speechEnqueuer: queue, enabled: enabled} + list := atspi.Snapshot{BusName: ":1.42", Path: "/list", Role: "list", Name: "Items"} + speaker := &PauseWaitSpeaker{} + worker := newSpeechWorker(logger, speaker) + worker.reading = func() config.ReadingSettings { return config.DefaultSettings().Reading } + worker.speechContext = []atspi.Snapshot{{BusName: ":1.42", Path: "/previous", Role: "table"}} + scoped.Enqueue(speechRequest{ReadAll: []readAllPart{{Text: "Inside", Context: []atspi.Snapshot{list}}}}) + if err := worker.deliver(context.Background(), <-queue.requests); err != nil { + t.Fatal(err) + } + want := []string{"Inside"} + if enabled { + want = []string{"Leaving table.", "Items list", "Inside"} + } + if !reflect.DeepEqual(speaker.parts, want) { + t.Fatalf("browse=%v: speech=%q, want %q", enabled, speaker.parts, want) + } + } +} diff --git a/internal/app/reading_preferences_test.go b/internal/app/reading_preferences_test.go new file mode 100644 index 0000000..e47d996 --- /dev/null +++ b/internal/app/reading_preferences_test.go @@ -0,0 +1,307 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "log/slog" + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/notification" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +func TestIndentationTracksRawSpacingAndModes(t *testing.T) { + reading := config.DefaultSettings().Reading + reading.EnableIndentation = true + reading.IndentationPresentationMode = "both" + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.reading = func() config.ReadingSettings { return reading } + var cues []sound.Cue + worker.indentationCue = func(cue sound.Cue) { cues = append(cues, cue) } + id := atspi.ObjectID{BusName: ":1.42", Path: "/editor"} + for _, tc := range []struct { + raw, spoken, want string + frequency int + }{ + {"\t text", "text", "indentation 5 columns, text", 400}, + {"\t other", "other", "other", 0}, + {" text", "text", "indentation 2 columns, text", 210}, + {"text", "text", "indentation 0 columns, text", 150}, + {"\u00a0text", "text", "indentation 1 column, text", 280}, + {" text", "text", "text", 0}, + } { + cues = nil + if got := worker.line_text(tc.spoken, &speechLine{Object: id, Raw: tc.raw}); got != tc.want { + t.Fatalf("%q: %q, want %q", tc.raw, got, tc.want) + } + if tc.frequency == 0 { + if len(cues) != 0 { + t.Fatal("unchanged indentation beeped") + } + } else if len(cues) != 1 || cues[0].Name != sound.IndentationCueName(tc.frequency) { + t.Fatalf("indentation cue = %+v", cues) + } + } + reading.IndentationPresentationMode = "beeps" + if got := worker.line_text("text", &speechLine{Object: id, Raw: " text"}); got != "text" { + t.Fatal("beeps mode spoke indentation") + } + reading.OnlySpeakDisplayedText = true + cues = nil + if got := worker.line_text("text", &speechLine{Object: id, Raw: " text"}); got != "text" || len(cues) != 0 { + t.Fatal("displayed-text mode presented indentation") + } + reading.OnlySpeakDisplayedText, reading.EnableIndentation = false, false + if got := worker.line_text("text", &speechLine{Object: id, Raw: "text"}); got != "text" { + t.Fatal("disabled indentation spoke") + } +} + +func TestNavigationContextFlagsAndTransitions(t *testing.T) { + reading := config.DefaultSettings().Reading + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.reading = func() config.ReadingSettings { return reading } + list := atspi.Snapshot{BusName: ":1.42", Path: "/list", Role: "list", Name: "Items"} + panel := atspi.Snapshot{BusName: ":1.42", Path: "/panel", Role: "panel", Name: "Options"} + if got := worker.context_messages([]atspi.Snapshot{list, panel}); !reflect.DeepEqual(got, []string{"Options panel", "Items list"}) { + t.Fatalf("enter context = %v", got) + } + if got := worker.context_messages([]atspi.Snapshot{list, panel}); len(got) != 0 { + t.Fatal("unchanged context repeated") + } + reading.SpeakContextList = false + if got := worker.context_messages([]atspi.Snapshot{panel}); len(got) != 0 { + t.Fatal("disabled list exit announced") + } + if got := worker.context_messages([]atspi.Snapshot{}); !reflect.DeepEqual(got, []string{"Leaving Options panel."}) { + t.Fatalf("exit context = %v", got) + } + reading.OnlySpeakDisplayedText = true + if got := worker.context_messages([]atspi.Snapshot{list, panel}); len(got) != 0 { + t.Fatal("displayed-text mode announced context") + } +} + +func TestListContextCountFollowsSpeechVerbosity(t *testing.T) { + reading := config.DefaultSettings().Reading + verbosity := 1 + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.reading = func() config.ReadingSettings { return reading } + worker.verbosity = func() int { return verbosity } + list := atspi.Snapshot{BusName: ":1.42", Path: "/list", Role: "list", Name: "Tasks", ChildCount: 3, ChildCountKnown: true} + if got := worker.context_messages([]atspi.Snapshot{list}); !reflect.DeepEqual(got, []string{"Tasks, 3 items"}) { + t.Fatalf("verbose list context = %v", got) + } + worker.context_messages([]atspi.Snapshot{}) + verbosity = 0 + if got := worker.context_messages([]atspi.Snapshot{list}); !reflect.DeepEqual(got, []string{"Tasks list"}) { + t.Fatalf("brief list context = %v", got) + } +} + +func TestSayAllContextFlagsAreIndependentOfNavigation(t *testing.T) { + for _, test := range []struct { + role string + disable func(*config.ReadingSettings) + }{ + {"block quote", func(r *config.ReadingSettings) { r.SayAllContextBlockquote = false }}, + {"list", func(r *config.ReadingSettings) { r.SayAllContextList = false }}, + {"table", func(r *config.ReadingSettings) { r.SayAllContextTable = false }}, + {"panel", func(r *config.ReadingSettings) { r.SayAllContextPanel = false }}, + {"landmark", func(r *config.ReadingSettings) { r.SayAllContextLandmark = false }}, + {"form", func(r *config.ReadingSettings) { r.SayAllContextNonLandmarkForm = false }}, + } { + reading := config.DefaultSettings().Reading + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.reading = func() config.ReadingSettings { return reading } + ancestor := atspi.Snapshot{BusName: ":1.42", Path: "/context", Role: test.role} + if got := worker.context_messages_for([]atspi.Snapshot{ancestor}, true); len(got) != 1 { + t.Fatalf("%s Say All context = %v", test.role, got) + } + test.disable(&reading) + worker.speechContext = nil + if got := worker.context_messages_for([]atspi.Snapshot{ancestor}, true); len(got) != 0 { + t.Fatalf("%s disabled Say All context = %v", test.role, got) + } + worker.speechContext = nil + if got := worker.context_messages([]atspi.Snapshot{ancestor}); len(got) != 1 { + t.Fatalf("%s navigation context changed = %v", test.role, got) + } + } +} + +func TestNavigationContextCollapsesRepeatedPanels(t *testing.T) { + reading := config.DefaultSettings().Reading + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.reading = func() config.ReadingSettings { return reading } + panels := make([]atspi.Snapshot, 5) + for index := range panels { + panels[index] = atspi.Snapshot{BusName: ":1.42", Path: fmt.Sprintf("/panel/%d", index), Role: "panel"} + } + check := func(ancestors []atspi.Snapshot, want []string) { + t.Helper() + if got := worker.context_messages(ancestors); !reflect.DeepEqual(got, want) { + t.Fatalf("context = %v, want %v", got, want) + } + } + check(panels, []string{"panel"}) + check(panels, nil) + // Unknown context must not discard remembered container identities. + check(nil, nil) + check(panels, nil) + check(panels[4:], []string{"Leaving panel."}) + check(panels[4:], nil) + check([]atspi.Snapshot{}, []string{"Leaving panel."}) + check(panels, []string{"panel"}) + check([]atspi.Snapshot{}, []string{"Leaving panel."}) + + panels[0].Name, panels[1].Name = "Inner", "Outer" + panels[2].Role = "grouping" + list := atspi.Snapshot{BusName: ":1.42", Path: "/list", Role: "list", Name: "Items"} + ancestors := append([]atspi.Snapshot{list}, panels...) + check(ancestors, []string{"panel", "Outer panel", "Inner panel", "Items list"}) + check([]atspi.Snapshot{}, []string{"Leaving Items list.", "Leaving Inner panel.", "Leaving Outer panel.", "Leaving panel."}) + reading.SpeakContextPanel = false + check(ancestors, []string{"Items list"}) + check([]atspi.Snapshot{}, []string{"Leaving Items list."}) +} + +func TestDeletedCharacterRetainsCaseAndEchoRouting(t *testing.T) { + for _, custom := range []bool{false, true} { + settings := config.DefaultSettings() + settings.UseCustomEchoVoice = custom + live := &liveSettings{} + live.Store(settings) + queue := &fakeSpeechQueue{spoken: make(chan string, 1), requests: make(chan speechRequest, 1)} + state := &eventLoopState{} + presenter := eventPresenter{state: state, logger: slog.New(slog.DiscardHandler), speech: queue, live: live} + snapshot := atspi.Snapshot{BusName: ":1.42", Path: "/editor", Role: "entry", Editable: true} + for _, tc := range []struct { + payload, text string + character bool + }{ + {"A", "A", true}, {"a", "a", true}, {"É", "É", true}, {"é", "é", true}, + {"!", "!", true}, {" ", "space", false}, {"\n", "blank", false}, {"AB", "AB", false}, + } { + presenter.speak(atspi.NewEventWithPayload(atspi.TextDeletedEvent, snapshot, tc.payload)) + request := <-queue.requests + <-queue.spoken + if request.Text != tc.text || request.Character != tc.character || request.CustomEcho != (custom && tc.character) { + t.Fatalf("delete %q, custom=%v: %+v", tc.payload, custom, request) + } + } + } +} + +type voiceConfigurationRecorder struct { + settings config.Settings + calls int +} + +func (recorder *voiceConfigurationRecorder) UpdateConfiguration(_ context.Context, settings config.Settings) error { + recorder.settings = settings + recorder.calls++ + return nil +} + +func TestSpecialVoiceApplyPreviewAndCancel(t *testing.T) { + settings := config.DefaultSettings() + updater := &voiceConfigurationRecorder{} + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, updater) + values := preferences.FromSettings(settings) + pitch := 3.0 + values.HyperlinkVoice.AveragePitch = &pitch + values.VoiceType = "hyperlink" + if response := worker.preview(context.Background(), preferences.Request{Values: values}); !response.Accepted { + t.Fatal(response.Message) + } + if updater.settings.DefaultVoice.AveragePitch == nil || *updater.settings.DefaultVoice.AveragePitch != pitch || worker.settings.DefaultVoice.AveragePitch != nil { + t.Fatal("preview changed committed/default draft voice") + } + if response := worker.restorePreview(context.Background()); !response.Accepted || updater.settings.DefaultVoice.AveragePitch != nil { + t.Fatal("Cancel did not restore committed voice") + } + if response := worker.apply(context.Background(), preferences.Request{Values: values}); !response.Accepted { + t.Fatal(response.Message) + } + if updater.calls != 3 || *updater.settings.HyperlinkVoice.AveragePitch != pitch || updater.settings.DefaultVoice.AveragePitch != nil { + t.Fatal("special voice edit did not reach runtime independently") + } +} + +func TestTypedCapitalRetainsCharacterAndCustomEcho(t *testing.T) { + settings := config.DefaultSettings() + settings.UseCustomEchoVoice = true + live := &liveSettings{} + live.Store(settings) + queue := &fakeSpeechQueue{spoken: make(chan string, 2), requests: make(chan speechRequest, 2)} + state := &eventLoopState{} + state.presentationOptions = presentationSettingsFromConfig(settings, false) + presenter := eventPresenter{state: state, logger: slog.New(slog.DiscardHandler), speech: queue, live: live} + snapshot := atspi.Snapshot{BusName: ":1.42", Path: "/editor", Role: "entry", Editable: true} + presenter.speak(atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, "É")) + request := <-queue.requests + if request.Text != "É" || !request.Character || !request.CustomEcho { + t.Fatalf("capital insertion routing = %+v", request) + } + // Document spelling must retain case after replacing letters with words. + set_review_spelling(&request, "Aa", review.FlatPhonetic) + if !reflect.DeepEqual(request.SpellingVoices, []string{"uppercase", ""}) { + t.Fatal("phonetic spelling lost uppercase voice") + } +} + +func TestBriefNotificationSpeechPreservesDetailedHistory(t *testing.T) { + settings := config.DefaultSettings() + live := &liveSettings{} + queue := &fakeSpeechQueue{spoken: make(chan string, 2), requests: make(chan speechRequest, 2)} + history := notification.NewPresenter() + announcer := notificationAnnouncer{presenter: history, speech: queue, live: live} + entry := notification.Entry{Message: "Update: more details", Summary: "Update", Body: "more details"} + for _, detailed := range []bool{false, true} { + settings.Reading.MessagesAreDetailed = detailed + live.Store(settings) + announcer.Announce(entry) + request := <-queue.requests + want := entry.Summary + if detailed { + want = entry.Message + } + if request.Text != want { + t.Fatalf("detailed=%v: %q", detailed, request.Text) + } + } + if entries := history.Entries(); len(entries) == 0 || entries[0].Message != entry.Message { + t.Fatal("brief speech discarded notification details") + } +} + +func TestReadAllDoesNotExpandEveryCellToItsRow(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 2), requests: make(chan speechRequest, 2)} + list := atspi.Snapshot{BusName: ":1.42", Path: "/list", Role: "list"} + line := atspi.DocumentLine{Context: []atspi.Snapshot{list}} + for _, name := range []string{"One", "Two"} { + line.Contents = append(line.Contents, atspi.DocumentContent{Text: name, Snapshot: atspi.Snapshot{ + Path: "/" + name, Role: "table cell", TablePath: "/table", TableRowText: "One, Two", + }}) + } + result := review.Result{ReadAllContext: context.Background(), ReadAllLines: []atspi.DocumentLine{line}} + presentReadAllResult(slog.New(slog.DiscardHandler), queue, result, presentation.DefaultOptions()) + request := <-queue.requests + if len(request.ReadAll) != 2 || request.ReadAll[0].Text != "One" || request.ReadAll[1].Text != "Two" { + t.Fatalf("Say All repeated row: %+v", request.ReadAll) + } + if len(request.ReadAll[0].Context) != 1 || request.ReadAll[0].Context[0].ID() != list.ID() { + t.Fatalf("Say All lost line context: %+v", request.ReadAll[0]) + } +} diff --git a/internal/app/reading_speech.go b/internal/app/reading_speech.go new file mode 100644 index 0000000..8ecd5ec --- /dev/null +++ b/internal/app/reading_speech.go @@ -0,0 +1,99 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + "unicode" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +// Apply pronunciation choices to the final text handed to the speech backend. +// Python Cthulhu splits lower-to-upper case boundaries and numeric words. +func readingSpeechText(text string, settings config.ReadingSettings) string { + if settings.SpeakMultiCaseStringsAsWords { + var result strings.Builder + var previous rune + for _, current := range text { + if unicode.IsLower(previous) && unicode.IsUpper(current) { + result.WriteByte(' ') + } + result.WriteRune(current) + previous = current + } + text = result.String() + } + if !settings.SpeakNumbersAsDigits { + return text + } + var result strings.Builder + var word []rune + flush := func() { + if len(word) == 0 { + return + } + allNumbers := true + for _, value := range word { + if !unicode.IsNumber(value) { + allNumbers = false + break + } + } + for index, value := range word { + if allNumbers && index != 0 { + result.WriteByte(' ') + } + result.WriteRune(value) + } + word = word[:0] + } + for _, value := range text { + if unicode.IsLetter(value) || unicode.IsNumber(value) || value == '_' { + word = append(word, value) + } else { + flush() + result.WriteRune(value) + } + } + flush() + return result.String() +} + +// Replace complete words once, without feeding replacements back into the +// dictionary. This keeps punctuation and spacing from the accessible text. +func pronunciationSpeechText(text string, entries []config.PronunciationEntry) string { + if len(entries) == 0 { + return text + } + dictionary := make(map[string]string, len(entries)) + for _, entry := range entries { + dictionary[strings.ToLower(entry.Word)] = entry.Replacement + } + var output strings.Builder + var word []rune + flush := func() { + if len(word) == 0 { + return + } + original := string(word) + if replacement, ok := dictionary[strings.ToLower(original)]; ok { + output.WriteString(replacement) + } else { + output.WriteString(original) + } + word = word[:0] + } + for _, current := range text { + if unicode.IsLetter(current) || unicode.IsNumber(current) || current == '_' { + word = append(word, current) + } else { + flush() + output.WriteRune(current) + } + } + flush() + return output.String() +} diff --git a/internal/app/reading_speech_test.go b/internal/app/reading_speech_test.go new file mode 100644 index 0000000..4bfd720 --- /dev/null +++ b/internal/app/reading_speech_test.go @@ -0,0 +1,95 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestReadingSpeechText(t *testing.T) { + for _, test := range []struct { + name string + settings config.ReadingSettings + input string + want string + }{ + {"unchanged", config.ReadingSettings{}, "saveFile 123", "saveFile 123"}, + {"multicase", config.ReadingSettings{SpeakMultiCaseStringsAsWords: true}, "saveFile and HTTPServer", "save File and HTTPServer"}, + {"digits", config.ReadingSettings{SpeakNumbersAsDigits: true}, "Room 123, A12, ٤٥", "Room 1 2 3, A12, ٤ ٥"}, + {"both", config.ReadingSettings{SpeakNumbersAsDigits: true, SpeakMultiCaseStringsAsWords: true}, "orderNumber 42", "order Number 4 2"}, + } { + t.Run(test.name, func(t *testing.T) { + if got := readingSpeechText(test.input, test.settings); got != test.want { + t.Fatalf("speech text = %q, want %q", got, test.want) + } + }) + } +} + +func TestPronunciationPreservesCharacterReadingAndSpelling(t *testing.T) { + entries := []config.PronunciationEntry{{Word: "a", Replacement: "article"}, {Word: "space", Replacement: "blank"}} + for _, test := range []struct { + name string + request speechRequest + want []string + }{ + {"character", speechRequest{Text: "A", Character: true}, []string{"A"}}, + {"echo", speechRequest{Text: "a", Character: true, CustomEcho: true}, []string{"a"}}, + {"spelling", func() speechRequest { + request := speechRequest{Text: "Aa"} + set_review_spelling(&request, "Aa", review.FlatSpell) + return request + }(), []string{"A", "a"}}, + {"word", speechRequest{Text: "a"}, []string{"article"}}, + {"character name", speechRequest{Text: "space", Character: true}, []string{"blank"}}, + } { + t.Run(test.name, func(t *testing.T) { + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.textTransform = func(text string) string { return pronunciationSpeechText(text, entries) } + if err := worker.deliver(context.Background(), test.request); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(speaker.parts, test.want) { + t.Fatalf("delivered %q, want %q", speaker.parts, test.want) + } + }) + } +} + +func TestSpeechHistoryReplayDoesNotApplyPronunciationTwice(t *testing.T) { + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.history = newSpeechHistory(10) + worker.textTransform = func(text string) string { + return pronunciationSpeechText(text, []config.PronunciationEntry{ + {Word: "SQL", Replacement: "sequel"}, {Word: "sequel", Replacement: "next"}, + }) + } + if err := worker.deliver(context.Background(), speechRequest{Text: "SQL"}); err != nil { + t.Fatal(err) + } + recorded := worker.history.snapshot()[0] + if err := worker.deliver(context.Background(), speechRequest{Text: recorded, Role: "table cell", ExcludeFromHistory: true}); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(speaker.parts, []string{"sequel", "sequel"}) { + t.Fatalf("history replay changed recorded speech: %q", speaker.parts) + } +} + +func TestPronunciationSpeechTextReplacesWholeWordsOnce(t *testing.T) { + entries := []config.PronunciationEntry{{Word: "SQL", Replacement: "sequel"}, {Word: "sequel", Replacement: "next"}, {Word: "café", Replacement: "coffee"}} + input := "SQL, sql; SQLite café!" + if got := pronunciationSpeechText(input, entries); got != "sequel, sequel; SQLite coffee!" { + t.Fatalf("pronunciation = %q", got) + } +} diff --git a/internal/app/remote.go b/internal/app/remote.go new file mode 100644 index 0000000..26dee86 --- /dev/null +++ b/internal/app/remote.go @@ -0,0 +1,166 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "slices" + "strings" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/remote" + "git.stormux.org/storm/cthulhu/internal/wine" + "github.com/godbus/dbus/v5" +) + +type remoteSpeech struct { + speech speechEnqueuer + braille interface { + EnqueueMessage(string) bool + } + wine *wineEventPresenter + wineReview *wine.ReviewRegistry + showPreferences func() + quit func() + runtimeSnapshot func() string + live *liveSettings + preferences *preferencesWorker +} + +func (presenter remoteSpeech) RegisterProvider(sender string, path dbus.ObjectPath, version uint32) bool { + return presenter.wineReview != nil && presenter.wineReview.RegisterProvider(sender, path, version) +} +func (presenter remoteSpeech) PresentFocus(sender string, notice wine.ReviewFocusNotice) bool { + return presenter.wineReview != nil && presenter.wineReview.PresentFocus(sender, notice) +} +func (presenter remoteSpeech) BindWineReviewConnection(connection *dbus.Conn) { + if presenter.wineReview != nil { + presenter.wineReview.BindWineReviewConnection(connection) + } +} + +func (presenter remoteSpeech) ShowPreferences() bool { + if presenter.showPreferences == nil { + return false + } + presenter.showPreferences() + return true +} + +func (presenter remoteSpeech) Quit() bool { + if presenter.quit == nil { + return false + } + presenter.quit() + return true +} + +func (presenter remoteSpeech) RuntimeStateSnapshot() string { + if presenter.runtimeSnapshot == nil { + return "" + } + return presenter.runtimeSnapshot() +} + +func (presenter remoteSpeech) PresentAccessibleEvent(event remote.AccessibleEvent) bool { + return presenter.wine != nil && presenter.wine.present_event(event, presenter.presentWineEditor) +} + +func (presenter remoteSpeech) PresentMessage(message string) bool { + return presenter.presentMessage(message, "remote-present-message") +} + +func (presenter remoteSpeech) presentMessage(message, cause string) bool { + return presenter.presentRequest(speechRequest{ + Text: message, Role: "system", Cause: cause, Append: true, + }) +} + +func (presenter remoteSpeech) presentWineEditor(event remote.AccessibleEvent) bool { + // These action kinds are part of the helper editor protocol. Keep + // character identity for navigation and Backspace as well as typing. + kinds := strings.Fields(event.States) + inserted := slices.Contains(kinds, "kind=8") + settings := config.DefaultSettings() + if presenter.live != nil { + settings = presenter.live.Load() + } + if inserted && (settings.KeyEchoInEditFieldsOnly && !wineEchoEditField(event) || !wineTypingEchoEnabled(event.Name, settings)) { + return false + } + character := inserted || utf8.RuneCountInString(event.Name) == 1 + custom := false + if character && presenter.live != nil && (inserted || slices.Contains(kinds, "kind=7")) { + kind := "character" + if inserted && !settings.EnableEchoByCharacter { + kind = "key" + } + custom = customEcho(settings, kind) + } + return presenter.presentRequest(speechRequest{ + Text: event.Name, Role: "system", Cause: "wine-accessible-event", Append: true, + Character: character, CustomEcho: custom, + PhoneticHint: slices.Contains(kinds, "kind=5"), + }) +} + +func (presenter remoteSpeech) presentRequest(request speechRequest) bool { + if request.Text == "" { + return false + } + accepted := false + if presenter.speech != nil { + presenter.speech.Enqueue(request) + accepted = true + } + if presenter.braille != nil && presenter.braille.EnqueueMessage(request.Text) { + accepted = true + } + return accepted +} + +// The protocol's interrupt flag does not establish user input. External +// announcements obey the same queue policy as accessibility events; callers +// requesting an explicit stop can use CancelSpeech. +func (presenter remoteSpeech) SpeakText(text string, _ bool) bool { + if presenter.speech == nil || text == "" { + return false + } + presenter.speech.Enqueue(speechRequest{ + Text: text, + Role: "system", + Cause: "remote-speak-text", + Append: true, + }) + return true +} + +func (presenter remoteSpeech) BrailleMessage(text string) bool { + if presenter.braille == nil || text == "" { + return false + } + return presenter.braille.EnqueueMessage(text) +} + +func (presenter remoteSpeech) CancelSpeech() bool { + if presenter.speech == nil { + return false + } + presenter.speech.Interrupt() + return true +} diff --git a/internal/app/remote_control.go b/internal/app/remote_control.go new file mode 100644 index 0000000..aeecb03 --- /dev/null +++ b/internal/app/remote_control.go @@ -0,0 +1,353 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "math" + "reflect" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "github.com/godbus/dbus/v5" +) + +// The names are the Python service's public names. Each mapped field is read +// from the live snapshot and applied by the preferences worker. +var remoteFields = map[string]string{ + "SpeechManager.CapitalizationStyle": "CapitalizationStyle", + "SpeechManager.SpeakDescription": "SpeakDescription", + "SpeechManager.SpeakRowInGuiTable": "Reading.ReadFullRowInGUITable", + "TypingEchoManager.KeyEchoEnabled": "EnableKeyEcho", + "TypingEchoManager.CharacterEchoEnabled": "EnableEchoByCharacter", + "TypingEchoManager.WordEchoEnabled": "EnableEchoByWord", + "TypingEchoManager.SentenceEchoEnabled": "EnableEchoBySentence", + "TypingEchoManager.AlphabeticKeysEnabled": "EnableAlphabeticKeys", + "TypingEchoManager.NumericKeysEnabled": "EnableNumericKeys", + "TypingEchoManager.PunctuationKeysEnabled": "EnablePunctuationKeys", + "TypingEchoManager.SpaceEnabled": "EnableSpace", + "TypingEchoManager.ModifierKeysEnabled": "EnableModifierKeys", + "TypingEchoManager.FunctionKeysEnabled": "EnableFunctionKeys", + "TypingEchoManager.ActionKeysEnabled": "EnableActionKeys", + "TypingEchoManager.NavigationKeysEnabled": "EnableNavigationKeys", + "TypingEchoManager.DiacriticalKeysEnabled": "EnableDiacriticalKeys", +} + +func remoteField(settings *config.Settings, path string) reflect.Value { + value := reflect.ValueOf(settings).Elem() + for _, part := range strings.Split(path, ".") { + if value.Kind() != reflect.Struct { + return reflect.Value{} + } + value = value.FieldByName(part) + if !value.IsValid() { + return value + } + } + return value +} + +func remoteValue(settings config.Settings, module, property string) (dbus.Variant, bool) { + if module == "SpeechManager" { + switch property { + case "CurrentServer": + if !settings.EnableSpeech { + return dbus.MakeVariant(""), true + } + return dbus.MakeVariant("speechdispatcher"), true + case "AvailableServers": + return dbus.MakeVariant([]string{"speechdispatcher"}), true + case "CurrentSynthesizer": + return dbus.MakeVariant(settings.SpeechOutputModule), true + case "CurrentVoice": + if settings.DefaultVoice.Family != nil { + return dbus.MakeVariant(settings.DefaultVoice.Family.Name), true + } + return dbus.MakeVariant(""), true + case "Rate": + if settings.DefaultVoice.Rate != nil { + return dbus.MakeVariant(int32(*settings.DefaultVoice.Rate)), true + } + return dbus.MakeVariant(int32(50)), true + case "Pitch": + if settings.DefaultVoice.AveragePitch != nil { + return dbus.MakeVariant(*settings.DefaultVoice.AveragePitch), true + } + return dbus.MakeVariant(float64(5)), true + case "Volume": + if settings.DefaultVoice.Gain != nil { + return dbus.MakeVariant(*settings.DefaultVoice.Gain), true + } + return dbus.MakeVariant(float64(10)), true + case "SpeechIsEnabled": + return dbus.MakeVariant(settings.EnableSpeech), true + case "CapitalizationStyle": + // The old API cannot represent both cues; prefer the spoken cue. + style := "none" + if settings.BeepForCapitals { + style = "icon" + } + if settings.SayCapForCapitals { + style = "spell" + } + return dbus.MakeVariant(style), true + case "PunctuationLevel": + return dbus.MakeVariant([]string{"all", "most", "some", "none"}[settings.VerbalizePunctuationStyle]), true + } + } + path, ok := remoteFields[module+"."+property] + if !ok { + return dbus.Variant{}, false + } + field := remoteField(&settings, path) + if !field.IsValid() { + return dbus.Variant{}, false + } + return dbus.MakeVariant(field.Interface()), true +} + +type remoteSettingsChange struct { + module, property string + command string + value dbus.Variant + result chan bool + expires time.Time +} + +func (worker *preferencesWorker) RunRemoteCommand(command string) bool { + change := remoteSettingsChange{module: "SpeechManager", command: command, result: make(chan bool, 1), expires: time.Now().Add(2 * time.Second)} + select { + case worker.remoteChanges <- change: + default: + return false + } + select { + case accepted := <-change.result: + return accepted + case <-worker.done: + return false + case <-time.After(2 * time.Second): + return false + } +} + +func (worker *preferencesWorker) SetRemote(module, property string, value dbus.Variant) bool { + change := remoteSettingsChange{module: module, property: property, value: value, result: make(chan bool, 1), expires: time.Now().Add(2 * time.Second)} + select { + case worker.remoteChanges <- change: + default: + return false + } + select { + case accepted := <-change.result: + return accepted + case <-worker.done: + return false + case <-time.After(2 * time.Second): + return false + } +} + +func (worker *preferencesWorker) applyRemoteChange(ctx context.Context, change remoteSettingsChange) bool { + if time.Now().After(change.expires) { + return false + } + next := worker.settings + if change.command != "" { + if !adjustRemoteSpeech(&next, change.command) { + return false + } + } else { + if !setRemoteValue(&next, change.module, change.property, change.value) { + return false + } + } + applyCtx, cancel := context.WithDeadline(ctx, change.expires) + defer cancel() + return worker.applyNext(applyCtx, next, false, false).Accepted +} + +func adjustRemoteSpeech(settings *config.Settings, command string) bool { + var field **float64 + var defaultValue, step, upper float64 + delta := float64(1) + switch command { + case "DecreaseRate", "IncreaseRate": + field = &settings.DefaultVoice.Rate + defaultValue, step, upper = 50, 1, 99 + case "DecreasePitch", "IncreasePitch": + field = &settings.DefaultVoice.AveragePitch + defaultValue, step, upper = 5, 0.1, 9 + case "DecreaseVolume", "IncreaseVolume": + field = &settings.DefaultVoice.Gain + defaultValue, step, upper = 9, 0.1, 9 + default: + return false + } + if strings.HasPrefix(command, "Decrease") { + delta = -1 + } + value := defaultValue + if *field != nil { + value = **field + } + value = math.Round((value+delta*step)*10) / 10 + value = math.Max(0, math.Min(upper, value)) + *field = &value + return true +} + +func setRemoteValue(settings *config.Settings, module, property string, value dbus.Variant) bool { + key := module + "." + property + if module == "SpeechManager" { + switch property { + case "Rate", "Pitch", "Volume": + var number float64 + if property == "Rate" { + v, ok := value.Value().(int32) + if !ok || v < 0 || v > 99 { + return false + } + number = float64(v) + } else { + v, ok := value.Value().(float64) + if !ok { + return false + } + number = v + } + switch property { + case "Rate": + settings.DefaultVoice.Rate = &number + case "Pitch": + settings.DefaultVoice.AveragePitch = &number + case "Volume": + settings.DefaultVoice.Gain = &number + } + return true + case "CurrentSynthesizer": + v, ok := value.Value().(string) + if !ok || len(v) > 256 { + return false + } + settings.SpeechOutputModule = v + settings.DefaultVoice.Family = nil + return true + case "CurrentVoice": + v, ok := value.Value().(string) + if !ok || len(v) > 256 { + return false + } + if settings.DefaultVoice.Family == nil { + settings.DefaultVoice.Family = &config.VoiceFamily{} + } else { + family := *settings.DefaultVoice.Family + settings.DefaultVoice.Family = &family + } + settings.DefaultVoice.Family.Name = v + return true + case "CapitalizationStyle": + v, ok := value.Value().(string) + if !ok || (v != "none" && v != "spell" && v != "icon") { + return false + } + settings.SetCapitalizationStyle(v) + return true + case "PunctuationLevel": + v, ok := value.Value().(string) + if !ok { + return false + } + for i, name := range []string{"all", "most", "some", "none"} { + if strings.EqualFold(v, name) { + settings.VerbalizePunctuationStyle = i + return true + } + } + return false + } + } + path, ok := remoteFields[key] + if !ok { + return false + } + field := remoteField(settings, path) + if !field.IsValid() || !field.CanSet() { + return false + } + newValue := reflect.ValueOf(value.Value()) + if !newValue.IsValid() || newValue.Type() != field.Type() { + return false + } + field.Set(newValue) + return true +} + +func (presenter remoteSpeech) RemoteGet(module, property string) (dbus.Variant, bool) { + if presenter.live == nil { + return dbus.Variant{}, false + } + if module == "SpeechManager" && property == "SpeechIsEnabled" { + return dbus.MakeVariant(presenter.speech != nil && presenter.live.Load().EnableSpeech), true + } + if module == "SpeechManager" && presenter.speech == nil && (property == "CurrentServer" || property == "CurrentSynthesizer" || property == "CurrentVoice") { + return dbus.MakeVariant(""), true + } + return remoteValue(presenter.live.Load(), module, property) +} + +func (presenter remoteSpeech) RemoteModulesAvailable() bool { + return presenter.live != nil && presenter.preferences != nil +} + +func (presenter remoteSpeech) RemoteSet(module, property string, value dbus.Variant) bool { + return presenter.preferences != nil && presenter.preferences.SetRemote(module, property, value) +} + +var remoteSpeechCommands = map[string]input.Command{ + "SelectPreviousSpeechSetting": input.SelectPreviousSpeechSetting, + "SelectNextSpeechSetting": input.SelectNextSpeechSetting, + "DecreaseCurrentSpeechSetting": input.DecreaseSpeechSetting, + "IncreaseCurrentSpeechSetting": input.IncreaseSpeechSetting, + "SaveSpeechSettings": input.SaveSpeechSettings, +} + +func (presenter remoteSpeech) RemoteCommand(module, command string, notify bool) bool { + if module == "SpeechManager" { + if command == "InterruptSpeech" { + return presenter.CancelSpeech() + } + if strings.HasPrefix(command, "Decrease") || strings.HasPrefix(command, "Increase") { + if presenter.preferences == nil { + return false + } + accepted := presenter.preferences.RunRemoteCommand(command) + if accepted && notify { + if message, ok := map[string]string{"DecreaseRate": "Speech slower", "IncreaseRate": "Speech faster", "DecreasePitch": "Speech lower", "IncreasePitch": "Speech higher", "DecreaseVolume": "Speech softer", "IncreaseVolume": "Speech louder"}[command]; ok { + presenter.PresentMessage(message) + } + } + return accepted + } + if mapped, ok := remoteSpeechCommands[command]; ok && presenter.preferences != nil { + return presenter.preferences.TrySpeechCommand(mapped) + } + } + if module == "TypingEchoManager" && command == "CycleKeyEcho" && presenter.live != nil { + current := presenter.live.Load().EnableKeyEcho + accepted := presenter.RemoteSet(module, "KeyEchoEnabled", dbus.MakeVariant(!current)) + if accepted && notify { + if current { + presenter.PresentMessage("Key echo disabled") + } else { + presenter.PresentMessage("Key echo enabled") + } + } + return accepted + } + return false +} diff --git a/internal/app/remote_control_test.go b/internal/app/remote_control_test.go new file mode 100644 index 0000000..1af6490 --- /dev/null +++ b/internal/app/remote_control_test.go @@ -0,0 +1,94 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "os" + "path/filepath" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/speech" + "github.com/godbus/dbus/v5" +) + +type acceptingRemoteSpeechSettings struct{} + +func (acceptingRemoteSpeechSettings) UpdateSettings(context.Context, speech.Settings) error { + return nil +} + +func TestRemoteSettingsUseWorkerWithoutSaving(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + live := &liveSettings{} + live.Store(settings) + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, acceptingRemoteSpeechSettings{}) + worker.live = live + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + presenter := remoteSpeech{live: live, preferences: worker} + if !presenter.RemoteSet("TypingEchoManager", "KeyEchoEnabled", dbus.MakeVariant(true)) { + t.Fatal("key echo setting rejected") + } + value, ok := presenter.RemoteGet("TypingEchoManager", "KeyEchoEnabled") + if !ok || value.Value() != true { + t.Fatalf("live key echo = %v, %v", value, ok) + } + if !presenter.RemoteSet("SpeechManager", "PunctuationLevel", dbus.MakeVariant("none")) { + t.Fatal("punctuation setting rejected") + } + value, ok = presenter.RemoteGet("SpeechManager", "PunctuationLevel") + if !ok || value.Value() != "none" { + t.Fatalf("live punctuation = %v, %v", value, ok) + } + if presenter.RemoteSet("SpeechManager", "PunctuationLevel", dbus.MakeVariant("invalid")) { + t.Fatal("invalid punctuation accepted") + } + if presenter.RemoteSet("TypingEchoManager", "KeyEchoEnabled", dbus.MakeVariant("wrong type")) { + t.Fatal("wrong type accepted") + } + if !presenter.RemoteCommand("SpeechManager", "IncreaseRate", false) { + t.Fatal("rate command rejected") + } + value, ok = presenter.RemoteGet("SpeechManager", "Rate") + if !ok || value.Value() != int32(51) { + t.Fatalf("rate after command = %v, %v", value, ok) + } + if presenter.RemoteCommand("SpeechManager", "Unknown", false) { + t.Fatal("unknown command accepted") + } + if _, err := os.Stat(settings.Path); !os.IsNotExist(err) { + t.Fatalf("remote setter wrote settings file: %v", err) + } +} + +func TestLegacyRemoteCapitalStyleControlsIndependentCues(t *testing.T) { + settings := config.DefaultSettings() + for _, style := range []string{"icon", "spell", "none"} { + if !setRemoteValue(&settings, "SpeechManager", "CapitalizationStyle", dbus.MakeVariant(style)) { + t.Fatal("style rejected") + } + if !settings.RaisePitchForCapitals || settings.BeepForCapitals != (style == "icon") || settings.SayCapForCapitals != (style == "spell") { + t.Fatalf("style %s cue mapping", style) + } + value, ok := remoteValue(settings, "SpeechManager", "CapitalizationStyle") + if !ok || value.Value() != style { + t.Fatalf("style %s getter: %v", style, value) + } + } + settings.BeepForCapitals, settings.SayCapForCapitals = true, true + value, ok := remoteValue(settings, "SpeechManager", "CapitalizationStyle") + if !ok || value.Value() != "spell" { + t.Fatal("combined style compatibility") + } + if setRemoteValue(&settings, "SpeechManager", "CapitalizationStyle", dbus.MakeVariant("invalid")) { + t.Fatal("invalid style accepted") + } +} diff --git a/internal/app/remote_test.go b/internal/app/remote_test.go new file mode 100644 index 0000000..b1ef743 --- /dev/null +++ b/internal/app/remote_test.go @@ -0,0 +1,140 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import "testing" + +type remoteSpeechQueue struct { + requests []speechRequest + interrupts int +} + +type remoteBrailleQueue struct { + running bool + text []string +} + +func (queue *remoteBrailleQueue) EnqueueMessage(text string) bool { + if !queue.running { + return false + } + queue.text = append(queue.text, text) + return true +} + +func TestRemoteBrailleMessage(t *testing.T) { + queue := &remoteBrailleQueue{} + presenter := remoteSpeech{braille: queue} + if presenter.BrailleMessage("Unavailable") || len(queue.text) != 0 { + t.Fatal("message accepted while braille is stopped") + } + queue.running = true + if !presenter.BrailleMessage("Braille") || len(queue.text) != 1 || queue.text[0] != "Braille" { + t.Fatalf("braille message was not queued: %v", queue.text) + } + if presenter.BrailleMessage("") { + t.Fatal("empty message accepted") + } +} + +func TestRemotePresentMessageUsesSpeechAndBraille(t *testing.T) { + speech := &remoteSpeechQueue{} + braille := &remoteBrailleQueue{running: true} + presenter := remoteSpeech{speech: speech, braille: braille} + if !presenter.PresentMessage("Status") || len(speech.requests) != 1 || + len(braille.text) != 1 || braille.text[0] != "Status" { + t.Fatalf("present message: speech=%v braille=%v", speech.requests, braille.text) + } + if !(remoteSpeech{braille: braille}).PresentMessage("Braille only") { + t.Fatal("braille-only presentation rejected") + } +} + +func TestWineMessageKeepsSourcePrivateInSpeechRequest(t *testing.T) { + speech := &remoteSpeechQueue{} + presenter := remoteSpeech{speech: speech} + if !presenter.presentMessage("Game control", "wine-accessible-event") { + t.Fatal("Wine presentation rejected") + } + if len(speech.requests) != 1 || speech.requests[0].Cause != "wine-accessible-event" { + t.Fatalf("speech requests = %+v", speech.requests) + } +} + +func (queue *remoteSpeechQueue) Enqueue(request speechRequest) { + queue.requests = append(queue.requests, request) +} + +func (queue *remoteSpeechQueue) Interrupt() { + queue.interrupts++ +} + +func TestRemoteSpeechQueuesWithoutInterruptingByDefault(t *testing.T) { + queue := &remoteSpeechQueue{} + presenter := remoteSpeech{speech: queue} + if !presenter.PresentMessage("Status") { + t.Fatal("PresentMessage rejected available speech") + } + if !presenter.SpeakText("Queued", false) { + t.Fatal("SpeakText rejected available speech") + } + if queue.interrupts != 0 { + t.Fatalf("interrupts = %d, want 0", queue.interrupts) + } + if len(queue.requests) != 2 { + t.Fatalf("requests = %d, want 2", len(queue.requests)) + } + for index, request := range queue.requests { + if !request.Append { + t.Fatalf("request %d was not queued as append speech", index) + } + } +} + +func TestRemoteSpeechQueuesRegardlessOfInterruptFlag(t *testing.T) { + queue := &remoteSpeechQueue{} + presenter := remoteSpeech{speech: queue} + if !presenter.SpeakText("Now", true) { + t.Fatal("SpeakText rejected available speech") + } + if queue.interrupts != 0 { + t.Fatalf("interrupts = %d, want 0", queue.interrupts) + } + if len(queue.requests) != 1 || queue.requests[0].Text != "Now" || !queue.requests[0].Append { + t.Fatalf("request = %+v, want queued Now speech", queue.requests) + } +} + +func TestRemoteSpeechCancellationAndUnavailableBraille(t *testing.T) { + queue := &remoteSpeechQueue{} + presenter := remoteSpeech{speech: queue} + if !presenter.CancelSpeech() { + t.Fatal("CancelSpeech rejected available speech") + } + if queue.interrupts != 1 { + t.Fatalf("interrupts = %d, want 1", queue.interrupts) + } + if presenter.BrailleMessage("Braille") { + t.Fatal("BrailleMessage succeeded without a braille backend") + } + + unavailable := remoteSpeech{} + if unavailable.PresentMessage("Status") || unavailable.SpeakText("Text", false) || unavailable.CancelSpeech() { + t.Fatal("remote speech succeeded without a speech worker") + } +} diff --git a/internal/app/review_spelling.go b/internal/app/review_spelling.go new file mode 100644 index 0000000..93eeb46 --- /dev/null +++ b/internal/app/review_spelling.go @@ -0,0 +1,60 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + "unicode" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// Shared by review spelling and learn mode, matching Python Cthulhu's names. +func phoneticLetter(letter rune) string { + words := [...]string{"alpha", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", "india", "juliet", "kilo", "lima", "mike", "november", "oscar", "papa", "quebec", "romeo", "sierra", "tango", "uniform", "victor", "whiskey", "xray", "yankee", "zulu"} + letter = unicode.ToLower(letter) + if letter < 'a' || letter > 'z' { + return "" + } + return words[letter-'a'] +} + +func flat_review_speech(command input.Command) review.FlatSpeech { + switch command { + case input.ReviewSpellWord, input.ReviewSpellLine: + return review.FlatSpell + case input.ReviewPhoneticWord, input.ReviewPhoneticCharacter, input.ReviewPhoneticLine: + return review.FlatPhonetic + } + return review.FlatSpeak +} + +// Preserve blank/whitespace announcements. Otherwise spell Unicode runes as +// separate utterances, retaining repeated letters and character-mode speech. +func set_review_spelling(request *speechRequest, text string, style review.FlatSpeech) { + if style == review.FlatSpeak || strings.TrimSpace(text) == "" { + return + } + request.Line = nil // Spelled lines must not re-announce indentation for each letter. + request.Character = style == review.FlatSpell + for _, letter := range text { + kind := "" + part := presentation.FlatReviewText(string(letter), true) + if style == review.FlatPhonetic { + if unicode.IsUpper(letter) { + kind = "uppercase" + } + if name := phoneticLetter(letter); name != "" { + part = name + } else if unicode.IsLetter(letter) { + part = string(unicode.ToLower(letter)) + } + } + request.Spelling = append(request.Spelling, part) + request.SpellingVoices = append(request.SpellingVoices, kind) + } +} diff --git a/internal/app/review_spelling_test.go b/internal/app/review_spelling_test.go new file mode 100644 index 0000000..8db4f82 --- /dev/null +++ b/internal/app/review_spelling_test.go @@ -0,0 +1,100 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + "reflect" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestFlatReviewSpellingPresentation(t *testing.T) { + for _, tc := range []struct { + command input.Command + text string + parts []string + character bool + }{ + {input.ReviewCurrentWord, "book", nil, false}, + {input.ReviewCurrentLine, "A book!", nil, false}, + {input.ReviewSpellLine, "A book!", []string{"A", "space", "b", "o", "o", "k", "!"}, true}, + {input.ReviewPhoneticLine, "A book!", []string{"alpha", "space", "bravo", "oscar", "oscar", "kilo", "!"}, false}, + {input.ReviewCurrentCharacter, "b", nil, true}, + {input.ReviewPhoneticCharacter, "B", []string{"bravo"}, false}, + {input.ReviewSpellWord, "Book", []string{"B", "o", "o", "k"}, true}, + {input.ReviewPhoneticWord, "Book", []string{"bravo", "oscar", "oscar", "kilo"}, false}, + {input.ReviewSpellWord, "猫1!", []string{"猫", "1", "!"}, true}, + {input.ReviewPhoneticWord, "猫1!", []string{"猫", "1", "!"}, false}, + {input.ReviewPhoneticCharacter, " ", nil, true}, + {input.ReviewPhoneticWord, "", nil, false}, + } { + queue := &fakeSpeechQueue{requests: make(chan speechRequest, 1), spoken: make(chan string, 1)} + unit, step := flatReviewCommand(tc.command) + result := review.Result{FlatUnit: unit, FlatStep: step, FlatSpeech: flat_review_speech(tc.command), FlatPosition: review.FlatPosition{Text: tc.text}} + presentFlatReviewResult(slog.New(slog.DiscardHandler), queue, result) + request := <-queue.requests + if !reflect.DeepEqual(request.Spelling, tc.parts) || request.Character != tc.character { + t.Fatalf("%s %q request=%#v", tc.command, tc.text, request) + } + } +} + +type spellingTestSpeaker struct { + parts []string + characters []string + after func() +} + +func (*spellingTestSpeaker) Connect(context.Context) error { return nil } +func (*spellingTestSpeaker) Close(context.Context) error { return nil } +func (*spellingTestSpeaker) Cancel(context.Context) error { return nil } +func (speaker *spellingTestSpeaker) Speak(_ context.Context, text string) error { + speaker.parts = append(speaker.parts, text) + if speaker.after != nil { + speaker.after() + } + return nil +} +func (speaker *spellingTestSpeaker) SpeakCharacter(ctx context.Context, text string) error { + speaker.characters = append(speaker.characters, text) + return speaker.Speak(ctx, text) +} + +func TestReviewSpellingDeliveryAndInterruption(t *testing.T) { + for _, style := range []review.FlatSpeech{review.FlatSpell, review.FlatPhonetic} { + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + request := speechRequest{Text: "book", Cause: "flat-review"} + set_review_spelling(&request, strings.Repeat("book", 20), style) + if err := worker.deliver(context.Background(), request); err != nil { + t.Fatal(err) + } + if len(speaker.parts) != 80 { + t.Fatalf("long spelling lost letters: %d", len(speaker.parts)) + } + wantCharacters := 0 + if style == review.FlatSpell { + wantCharacters = 80 + } + if len(speaker.characters) != wantCharacters { + t.Fatalf("character-mode delivery=%d", len(speaker.characters)) + } + worker.running = true // Exercise the real interruption generation barrier. + speaker.parts = nil + speaker.after = worker.InterruptForUser + if err := worker.deliver(context.Background(), request); !errors.Is(err, context.Canceled) { + t.Fatalf("interrupt=%v", err) + } + if len(speaker.parts) != 1 { + t.Fatalf("spelling continued after input: %v", speaker.parts) + } + } +} diff --git a/internal/app/runtime_backends.go b/internal/app/runtime_backends.go new file mode 100644 index 0000000..adb711b --- /dev/null +++ b/internal/app/runtime_backends.go @@ -0,0 +1,134 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/lifecycle" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +// runtimeBackends carries constructed backends only between assembly and Run. +// The lifecycle runner owns their start/stop order after construction. +type runtimeBackends struct { + speechOutput speechEnqueuer + brailleOutput *brailleWorker + speechMessages *speechWorker + history *speechHistory + settingsUpdater any + inputListener InputListener + copyChanges <-chan struct{} + sounds soundService + services []lifecycle.Service +} + +// newRuntimeBackends registers sound, speech, speech worker, input, and the +// optional clipboard monitor in that order. The speech worker has a lifetime +// independent of the event-loop context so farewell can be delivered. +func newRuntimeBackends(options *Options, settings config.Settings, logger *slog.Logger, adapter Adapter) (*runtimeBackends, error) { + var speechOutput speechEnqueuer = discardSpeech{} + brailleOutput, err := newBrailleWorker(logger) + if err != nil { + return nil, err + } + brailleOutput.router, _ = adapter.(brailleRouter) + brailleOutput.SetContraction(settings.EnableContractedBraille, settings.BrailleContractionTable) + brailleOutput.SetWordWrap(settings.Braille.WordWrap) + backends := &runtimeBackends{ + speechOutput: speechOutput, + brailleOutput: brailleOutput, + services: make([]lifecycle.Service, 0, 5), + } + if options.newSound != nil { + backends.sounds = options.newSound() + } else { + backends.sounds = sound.New(logger, sound.NativePlayer{Sink: settings.SoundSink}, settings.SoundTheme, settings.SoundVolume) + } + if updater, ok := backends.sounds.(soundSettingsUpdater); ok { + updater.Configure(soundConfiguration(settings)) + } + backends.services = append(backends.services, lifecycle.Service{Name: "sound", Start: backends.sounds.Start, Stop: func(context.Context) error { + soundContext, cancelSound := context.WithTimeout(context.Background(), soundStopTimeout) + defer cancelSound() + logger.Debug("playing shutdown sound") + if err := backends.sounds.Stop(soundContext); err != nil { + logger.Warn("stop sound service", "error", err) + return err + } + logger.Debug("shutdown sound completed") + return nil + }}) + if options.newSpeaker == nil { + options.newSpeaker = func() Speaker { + return newConfiguredSpeaker(options.SpeechSocket, settings) + } + } + speaker := options.newSpeaker() + backends.settingsUpdater = speaker + backends.speechMessages = newSpeechWorker(logger, speaker) + backends.speechMessages.SetEnabled(settings.EnableSpeech) + if beeper, ok := backends.sounds.(interface{ SpeechBeep(context.Context) error }); ok { + backends.speechMessages.beep = beeper.SpeechBeep + } + if beeper, ok := backends.sounds.(interface{ CapitalBeep(context.Context) error }); ok { + backends.speechMessages.capitalBeep = beeper.CapitalBeep + } + backends.history = newSpeechHistory(settings.SpeechHistoryLimit) + backends.speechMessages.history = backends.history + backends.speechOutput = backends.speechMessages + if options.newInput == nil { + options.newInput = func() InputListener { return xorg.New() } + } + backends.inputListener = options.newInput() + backends.services = append(backends.services, + lifecycle.Service{Name: "speech", Start: func(ctx context.Context) error { + if !settings.EnableSpeech { + return nil + } + return speaker.Connect(ctx) + }, Stop: speaker.Close}, + lifecycle.Service{Name: "speech worker", Start: func(context.Context) error { + // The runner owns this worker's lifetime. Keeping it independent of + // the event-loop context lets graceful shutdown queue its farewell. + return backends.speechMessages.Start(context.Background()) + }, Stop: backends.speechMessages.Stop}, + ) + backends.services = append(backends.services, + desktopInputService("X11 listener", backends.inputListener, logger), + ) + if _, native := backends.inputListener.(*xorg.Listener); native { + clipboardMonitor := xorg.NewClipboardMonitor() + backends.services = append(backends.services, lifecycle.Service{ + Name: "clipboard changes", + Start: func(ctx context.Context) error { + if err := clipboardMonitor.Start(ctx); err != nil { + logger.Warn("copy feedback unavailable", "error", err) + return nil + } + backends.copyChanges = clipboardMonitor.Changes() + return nil + }, + Stop: clipboardMonitor.Stop, + }) + } + return backends, nil +} diff --git a/internal/app/runtime_commands.go b/internal/app/runtime_commands.go new file mode 100644 index 0000000..edbe793 --- /dev/null +++ b/internal/app/runtime_commands.go @@ -0,0 +1,291 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "errors" + "log/slog" + "os" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/notification" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// commandRuntime owns command dispatch while the event loop owns accessibility state. +type commandRuntime struct { + internalUI *internalUI + actionSource accessibleActionSource + tentacles *tentacleRuntime + logger *slog.Logger + commands commandListener + focusChanges <-chan xorg.FocusState + focusGate *focusGate + speechMessages *speechWorker + speechOutput speechEnqueuer + learn *learnModePresenter + browser *browserModeController + preferences *preferencesWorker + onPreferences func() + onSpeechHistory func() + onSpeechMonitor func() + onNotificationList func() + live *liveSettings + clipboardRequests chan<- struct{} + reviewRequests chan<- input.Command + attributeRequests chan<- struct{} + objectReview *review.Worker + ocr *ocrSession + notifications *notification.Presenter + stopRun context.CancelFunc +} + +func (worker commandRuntime) run(ctx context.Context) error { + logger := worker.logger + commands := worker.commands + focusChanges := worker.focusChanges + focusGate := worker.focusGate + speechMessages := worker.speechMessages + speechOutput := worker.speechOutput + learn := worker.learn + browser := worker.browser + preferences := worker.preferences + onPreferences := worker.onPreferences + onSpeechHistory := worker.onSpeechHistory + onSpeechMonitor := worker.onSpeechMonitor + onNotificationList := worker.onNotificationList + live := worker.live + clipboardRequests := worker.clipboardRequests + reviewRequests := worker.reviewRequests + objectReview := worker.objectReview + notifications := worker.notifications + stopRun := worker.stopRun + var tentacleAnnouncements <-chan string + var tentacleFailures <-chan error + if worker.tentacles != nil { + tentacleFailures = worker.tentacles.failures + tentacleAnnouncements = worker.tentacles.announcements + } + var ocrFailures <-chan error + if worker.ocr != nil { + ocrFailures = worker.ocr.failures + } + for { + select { + case <-ctx.Done(): + return nil + case message := <-tentacleAnnouncements: + if !focusGate.Locked() && !focusGate.Suspended() { + learn.present(message, "tentacle-status") + } + case err := <-tentacleFailures: + stopRun() + return err + case err := <-ocrFailures: + stopRun() + return err + case err := <-commands.Failures(): + stopRun() + return err + case state := <-focusChanges: + if !state.Known { + continue + } + if focusGate.SetSuspended(state.XTerm) { + if state.XTerm { + logger.Info("suspended for XTerm focus handoff") + } else { + logger.Info("resumed after XTerm focus handoff") + } + } + case state := <-commands.LockStates(): + if focusGate.Locked() { + continue + } + if speechMessages != nil { + speechMessages.ProtectCommand(state.Timestamp) + } + focusGate.dismiss_confirmation() + speechOutput.Enqueue(speechRequest{Text: state.Text(), Role: "system", Cause: "lock-state"}) + logger.Debug("keyboard lock state changed", "key", state.Name, "locked", state.Locked) + case event := <-commands.Commands(): + focusGate.retireTentacleOutput() + if focusGate.Locked() { + continue + } + command := event.Command + if speechMessages != nil { + speechMessages.ProtectCommand(event.Timestamp) + } + focusGate.dismiss_confirmation() + logger.Debug("keyboard command received", "command", command, "input_timestamp", event.Timestamp) + if worker.internalUI.Handle(event) { + continue + } + _, browserList := input.LookupDocumentList(command) + if worker.internalUI != nil && (browserList || command == input.ShowActions || command == input.InternalUIKey || command == input.InternalUIDismiss) { + stopRun() + return errors.New("internal UI event queue overflow") + } + if worker.ocr.Handle(event) { + continue + } + switch command { + case input.ToggleLearnMode, input.LearnKey, input.LearnDocumentation, input.LearnDefaultShortcuts, input.LearnApplicationShortcuts: + learn.handle(event) + continue + } + if !focusGate.Suspended() && worker.tentacles.Invoke(ctx, command) { + continue + } + if browser != nil { + browser.observeCommand(command) + } + switch command { + case input.DisableTentacles: + worker.tentacles.Disable() + learn.present("Tentacles disabled.", "tentacles-disabled") + case input.CycleSpeechMode: + if speechMessages != nil { + mode := speechMessages.cycle_speech_mode() + speechOutput.Enqueue(speechRequest{Text: mode.announcement(), Role: "system", Cause: "speech-mode", ForceSpeech: true}) + } + case input.Quit: + logger.Info("quit command received") + stopRun() + return nil + case input.ToggleDocumentMode, input.StickyFocusMode, input.StickyBrowseMode: + if browser != nil { + select { + case browser.toggles <- command: + default: + } + } + case input.SelectPreviousSpeechSetting, input.SelectNextSpeechSetting, input.DecreaseSpeechSetting, input.IncreaseSpeechSetting, input.SaveSpeechSettings, input.CycleProgressBarOutput: + logger.Debug("speech setting command received", "command", command) + preferences.SpeechCommand(command) + case input.Preferences: + logger.Info("preferences command received") + if onPreferences != nil { + onPreferences() + } + case input.ApplicationPreferences: + logger.Info("application preferences command received") + if preferences != nil { + preferences.OpenApplication() + } + case input.ChooseApplicationPreferences: + if preferences != nil { + preferences.ChooseApplication() + } + case input.PresentTime, input.PresentDate: + presentDateTime(speechOutput, live.Load(), command, time.Now()) + case input.PresentClipboard: + select { + case clipboardRequests <- struct{}{}: + default: + } + case input.ShowSpeechHistory: + if onSpeechHistory != nil { + onSpeechHistory() + } + case input.ToggleSpeechMonitor: + if onSpeechMonitor != nil { + onSpeechMonitor() + } + case input.PresentVersion: + presentVersion( + speechOutput, + atspi.Version(), + os.Getenv("XDG_SESSION_TYPE"), + os.Getenv("XDG_SESSION_DESKTOP"), + ) + case input.PresentLastNotification: + presentNotifications(speechOutput, notifications.PresentLast()) + case input.PresentPreviousNotification: + presentNotifications(speechOutput, notifications.PresentPrevious()) + case input.PresentNextNotification: + presentNotifications(speechOutput, notifications.PresentNext()) + case input.ShowNotificationList: + if onNotificationList != nil { + onNotificationList() + } + case input.PresentCurrentLine, input.SpellCurrentLine, input.PhoneticCurrentLine, input.WhereAmI, input.PresentWindowTitle, input.PresentCellFormula, input.SetColumnHeadersRow, input.ClearColumnHeadersRow, input.SetRowHeadersColumn, input.ClearRowHeadersColumn: + if command == input.WhereAmI { + logger.Info("where am I command received") + } else if command == input.PresentWindowTitle { + logger.Info("window title command received") + } else if command == input.PresentCellFormula { + logger.Info("cell formula command received") + } else if command == input.PresentCurrentLine || command == input.SpellCurrentLine || command == input.PhoneticCurrentLine { + logger.Debug("current line command received", "command", command) + } else { + logger.Info("Calc header command received", "command", command) + } + select { + case reviewRequests <- command: + default: + } + case input.PresentCharacterAttributes: + select { + case worker.attributeRequests <- struct{}{}: + default: + } + case input.ObjectParent: + queueObjectReviewMove(logger, objectReview, review.Parent) + case input.ObjectFirstChild: + queueObjectReviewMove(logger, objectReview, review.FirstChild) + case input.ObjectPreviousSibling: + queueObjectReviewMove(logger, objectReview, review.PreviousSibling) + case input.ObjectNextSibling: + queueObjectReviewMove(logger, objectReview, review.NextSibling) + case input.DocumentActivate: + if objectReview != nil { + if err := objectReview.ActivateDocumentCaret(); err != nil { + logger.Warn("queue document activation", "error", err) + } + } + case input.ReadAll: + if objectReview != nil && speechMessages != nil { + if err := objectReview.ReadAll(speechMessages.BeginReadAll(ctx, event.Timestamp)); err != nil { + logger.Warn("queue read all", "error", err) + } + } + default: + if target, level, backwards := documentReviewCommand(command); target != 0 { + if err := objectReview.MoveDocument(target, level, backwards); err != nil { + logger.Warn("queue document navigation", "error", err) + } + } else if caretCommand := documentCaretCommand(command); caretCommand != 0 { + if err := objectReview.MoveDocumentCaret(caretCommand); err != nil { + logger.Warn("queue document caret navigation", "error", err) + } + } else if unit, step := flatReviewCommand(command); unit != 0 { + logger.Info("flat review command received", "command", command) + if err := objectReview.ReadFlatWithSpeech(unit, step, flat_review_speech(command)); err != nil { + logger.Warn("queue flat review", "error", err) + } + } + } + } + } +} diff --git a/internal/app/runtime_commands_test.go b/internal/app/runtime_commands_test.go new file mode 100644 index 0000000..43b9fdb --- /dev/null +++ b/internal/app/runtime_commands_test.go @@ -0,0 +1,349 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestCommandRuntimeRoutesFocusPresentationRequests(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + commands := &fakeCommands{commands: make(chan input.CommandEvent, 1)} + requests := make(chan input.Command, 1) + worker := commandRuntime{logger: slog.New(slog.DiscardHandler), commands: commands, + reviewRequests: requests, stopRun: cancel} + done := make(chan error, 1) + go func() { done <- worker.run(ctx) }() + defer func() { + cancel() + select { + case err := <-done: + if err != nil { + t.Error(err) + } + case <-time.After(time.Second): + t.Error("command worker did not stop") + } + }() + for _, command := range []input.Command{input.PresentCurrentLine, input.SpellCurrentLine, input.PhoneticCurrentLine, input.WhereAmI, input.PresentWindowTitle, input.PresentCellFormula, input.SetColumnHeadersRow, input.ClearColumnHeadersRow, input.SetRowHeadersColumn, input.ClearRowHeadersColumn} { + commands.commands <- input.CommandEvent{Command: command} + select { + case got := <-requests: + if got != command { + t.Fatalf("focus request = %q, want %q", got, command) + } + case <-time.After(time.Second): + t.Fatalf("missing focus request %q", command) + } + } +} + +func TestRunRoutesPreferencesWithoutStoppingCommandHandling(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = false + settings.EnableSound = false + adapter := &fakeAdapter{events: make(chan atspi.Event)} + commands := &fakeCommands{commands: make(chan input.CommandEvent, 2)} + preferencesCalled := make(chan struct{}, 1) + completed := make(chan error, 1) + + go func() { + completed <- Run(context.Background(), Options{ + Logger: slog.New(slog.DiscardHandler), + Settings: &settings, + newCommands: func() commandListener { return commands }, + onPreferences: func() { preferencesCalled <- struct{}{} }, + newAdapter: func() Adapter { return adapter }, + newInput: func() InputListener { return &fakeInputListener{events: make(chan input.Event)} }, + }) + }() + + commands.commands <- input.CommandEvent{Command: input.Preferences} + select { + case <-preferencesCalled: + case <-time.After(time.Second): + t.Fatal("preferences callback was not invoked") + } + commands.commands <- input.CommandEvent{Command: input.Quit} + select { + case err := <-completed: + if err != nil { + t.Fatalf("Run: %v", err) + } + case <-time.After(time.Second): + t.Fatal("quit was not handled after preferences") + } +} + +func TestRunRoutesShowNotificationList(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = false + settings.EnableSound = false + adapter := &fakeAdapter{events: make(chan atspi.Event)} + commands := &fakeCommands{commands: make(chan input.CommandEvent, 2)} + listCalled := make(chan struct{}, 1) + completed := make(chan error, 1) + + go func() { + completed <- Run(context.Background(), Options{ + Logger: slog.New(slog.DiscardHandler), Settings: &settings, + newCommands: func() commandListener { return commands }, + onNotificationList: func() { listCalled <- struct{}{} }, + newAdapter: func() Adapter { return adapter }, + newInput: func() InputListener { return &fakeInputListener{events: make(chan input.Event)} }, + }) + }() + + commands.commands <- input.CommandEvent{Command: input.ShowNotificationList} + select { + case <-listCalled: + case <-time.After(time.Second): + t.Fatal("notification list callback was not invoked") + } + commands.commands <- input.CommandEvent{Command: input.Quit} + select { + case err := <-completed: + if err != nil { + t.Fatalf("Run: %v", err) + } + case <-time.After(time.Second): + t.Fatal("quit was not handled after opening the notification list") + } +} + +func TestRunRoutesNotificationCommands(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = true + settings.EnableSound = false + speaker := &fakeSpeaker{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + commands := &fakeCommands{commands: make(chan input.CommandEvent, 2)} + listCalled := make(chan struct{}, 1) + completed := make(chan error, 1) + + go func() { + completed <- Run(context.Background(), Options{ + Logger: slog.New(slog.DiscardHandler), Settings: &settings, + newCommands: func() commandListener { return commands }, + newSpeaker: func() Speaker { return speaker }, + newAdapter: func() Adapter { return adapter }, + newInput: func() InputListener { + return &fakeInputListener{ + events: make(chan input.Event), + modifierKeycodes: input.NewModifierKeycodes(37), + } + }, + onNotificationList: func() { + select { + case listCalled <- struct{}{}: + default: + } + }, + }) + }() + + select { + case message := <-speaker.spoken: + if !contains_string(startupMessages, message) { + t.Fatalf("startup speech = %q, want one of %q", message, startupMessages) + } + case <-time.After(time.Second): + t.Fatal("startup speech was not presented") + } + + commands.commands <- input.CommandEvent{Command: input.PresentLastNotification} + select { + case message := <-speaker.spoken: + if message != "No notification messages" { + t.Fatalf("last notification speech = %q, want %q", message, "No notification messages") + } + case <-time.After(time.Second): + t.Fatal("last notification speech was not presented") + } + + commands.commands <- input.CommandEvent{Command: input.ShowNotificationList} + select { + case <-listCalled: + case <-time.After(time.Second): + t.Fatal("notification list callback was not invoked") + } + commands.commands <- input.CommandEvent{Command: input.Quit} + select { + case err := <-completed: + if err != nil { + t.Fatalf("Run: %v", err) + } + case <-time.After(time.Second): + t.Fatal("quit was not handled after notification commands") + } +} + +func TestRunCommandLoopRemainsResponsiveDuringObjectCapture(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = true + settings.EnableSound = false + speaker := &fakeSpeaker{spoken: make(chan string, 3)} + inputListener := &fakeInputListener{ + events: make(chan input.Event), + modifierKeycodes: input.NewModifierKeycodes(37), + } + captureStarted := make(chan struct{}) + adapter := &fakeAdapter{ + events: make(chan atspi.Event, 1), + capture: func(ctx context.Context) (*atspi.AccessibleTree, error) { + close(captureStarted) + <-ctx.Done() + return nil, ctx.Err() + }, + } + commands := &fakeCommands{commands: make(chan input.CommandEvent, 2)} + completed := make(chan error, 1) + + go func() { + completed <- Run(context.Background(), Options{ + Logger: slog.New(slog.DiscardHandler), + Settings: &settings, + newSpeaker: func() Speaker { return speaker }, + newInput: func() InputListener { return inputListener }, + newCommands: func() commandListener { return commands }, + onPreferences: func() {}, + newAdapter: func() Adapter { return adapter }, + }) + }() + select { + case <-speaker.spoken: + case <-time.After(time.Second): + t.Fatal("startup speech was not delivered") + } + focus := atspi.NewSnapshot("/focused", "Focused", "push button", "", "") + focus.BusName = ":1.42" + adapter.events <- atspi.NewEvent(atspi.FocusEvent, focus) + for _, want := range []string{"Focused", "push button"} { + select { + case text := <-speaker.spoken: + if text != want { + t.Fatalf("focus speech = %q, want %q", text, want) + } + case <-time.After(time.Second): + t.Fatal("focus was not delivered before object review command") + } + } + commands.commands <- input.CommandEvent{Command: input.ObjectNextSibling} + select { + case <-captureStarted: + case <-time.After(time.Second): + t.Fatal("object review capture did not start") + } + commands.commands <- input.CommandEvent{Command: input.Quit} + select { + case err := <-completed: + if err != nil { + t.Fatalf("Run: %v", err) + } + case <-time.After(time.Second): + t.Fatal("quit command was blocked by object review capture") + } + if !adapter.stopped { + t.Fatal("adapter did not stop after capture cancellation") + } +} + +type attributeFakeAdapter struct { + *fakeAdapter + values map[string]string +} + +func (adapter *attributeFakeAdapter) ReadCharacterAttributes(_ context.Context, object atspi.ObjectID) (atspi.CharacterAttributes, error) { + return atspi.CharacterAttributes{Object: object, Values: adapter.values}, nil +} + +func TestRunPresentsCurrentCharacterColorNames(t *testing.T) { + for _, probe := range []struct { + names bool + want string + }{{true, "foreground color: red"}, {false, "foreground color: 255 0 0"}} { + t.Run(probe.want, func(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSound = false + settings.EnableBraille = false + settings.Reading.UseColorNames = probe.names + speaker := &fakeSpeaker{spoken: make(chan string, 4)} + adapter := &attributeFakeAdapter{ + fakeAdapter: &fakeAdapter{events: make(chan atspi.Event, 1)}, + values: map[string]string{"fg-color": "rgb(65535,0,0)"}, + } + commands := &fakeCommands{commands: make(chan input.CommandEvent, 2)} + ctx, cancel := context.WithCancel(context.Background()) + completed := make(chan error, 1) + go func() { + completed <- Run(ctx, Options{ + Logger: slog.New(slog.DiscardHandler), Settings: &settings, + newSpeaker: func() Speaker { return speaker }, + newAdapter: func() Adapter { return adapter }, + newCommands: func() commandListener { return commands }, + newInput: func() InputListener { return &fakeInputListener{events: make(chan input.Event)} }, + }) + }() + defer func() { + cancel() + select { + case err := <-completed: + if err != nil { + t.Error(err) + } + case <-time.After(2 * time.Second): + t.Error("reader did not stop") + } + }() + select { + case <-speaker.spoken: + case <-time.After(time.Second): + t.Fatal("startup speech missing") + } + focus := atspi.NewSnapshot("/entry", "Color entry", "entry", "", "") + focus.BusName = ":1.42" + adapter.events <- atspi.NewEvent(atspi.FocusEvent, focus) + for _, want := range []string{"Color entry", "entry"} { + select { + case got := <-speaker.spoken: + if got != want { + t.Fatalf("focus speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatal("focus speech missing") + } + } + commands.commands <- input.CommandEvent{Command: input.PresentCharacterAttributes} + select { + case spoken := <-speaker.spoken: + if spoken != probe.want { + t.Fatalf("character attributes = %q, want %q", spoken, probe.want) + } + case <-time.After(time.Second): + t.Fatal("character attribute command did not speak") + } + }) + } +} diff --git a/internal/app/runtime_notifications.go b/internal/app/runtime_notifications.go new file mode 100644 index 0000000..8b4bcb9 --- /dev/null +++ b/internal/app/runtime_notifications.go @@ -0,0 +1,57 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + + "git.stormux.org/storm/cthulhu/internal/lifecycle" + "git.stormux.org/storm/cthulhu/internal/notification" + "git.stormux.org/storm/cthulhu/internal/sessionbus" +) + +// newNotificationRuntime constructs notification services in their original +// registration order. The caller appends them before speech history and remote +// services, preserving reverse-order shutdown. +func newNotificationRuntime(logger *slog.Logger, speech speechEnqueuer, braille *brailleWorker, live *liveSettings, onList func()) (*notification.Presenter, func(), []lifecycle.Service) { + presenter := notification.NewPresenter() + announcer := ¬ificationAnnouncer{presenter: presenter, speech: speech, braille: braille, live: live} + var services []lifecycle.Service + if makoConnection, err := sessionbus.Connect(logger, "notifications"); err == nil { + makoMonitor := notification.NewMakoMonitor(makoConnection, presenter, announcer) + presenter.SetMakoController(makoMonitor) + services = append(services, lifecycle.Service{ + Name: "mako-notifications", + Start: func(ctx context.Context) error { + return makoMonitor.Start(ctx) + }, + Stop: func(ctx context.Context) error { + return makoMonitor.Stop(ctx) + }, + }) + } + if onList == nil { + list := newNotificationListWorker(logger, presenter, speech) + onList = list.Open + services = append(services, lifecycle.Service{ + Name: "notification list", Start: list.Start, Stop: list.Stop, + }) + } + return presenter, onList, services +} diff --git a/internal/app/runtime_platform.go b/internal/app/runtime_platform.go new file mode 100644 index 0000000..d531af0 --- /dev/null +++ b/internal/app/runtime_platform.go @@ -0,0 +1,67 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + + "git.stormux.org/storm/cthulhu/internal/lifecycle" + "git.stormux.org/storm/cthulhu/internal/platform/session" + "git.stormux.org/storm/cthulhu/internal/platform/wayland" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +type desktopInputBackend interface { + Start(context.Context) error + Stop(context.Context) error +} + +// Missing desktop keyboard capabilities must not prevent AT-SPI, speech and +// braille from running on Wayland. Explicit X11 backends keep their existing +// optional Xwayland startup behavior. +// Other backends retain their own startup contract. The lifecycle runner still +// owns cleanup, including a native listener whose startup failed. +func desktopInputService(name string, backend desktopInputBackend, logger *slog.Logger) lifecycle.Service { + service := lifecycle.Service{Name: name, Start: backend.Start, Stop: backend.Stop} + switch backend.(type) { + case *wayland.Keyboard: + service.Start = func(ctx context.Context) error { + err := backend.Start(ctx) + if ctx.Err() != nil { + return ctx.Err() + } + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return err + } + if err != nil { + logger.Warn("Wayland keyboard access unavailable; continuing with AT-SPI reading only", "error", err) + } + return nil + } + case *xorg.Listener, *xorg.CommandListener: + if session.Wayland() { + service.Start = func(ctx context.Context) error { + return startOptionalXorg(ctx, name, backend.Start, logger) + } + } + } + return service +} + +func startOptionalXorg(ctx context.Context, name string, start func(context.Context) error, logger *slog.Logger) error { + err := start(ctx) + if ctx.Err() != nil { + return ctx.Err() + } + if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { + return err + } + if err != nil { + logger.Warn("X11 input service unavailable on Wayland; continuing without it", "service", name, "error", err) + } + return nil +} diff --git a/internal/app/runtime_platform_test.go b/internal/app/runtime_platform_test.go new file mode 100644 index 0000000..b3783df --- /dev/null +++ b/internal/app/runtime_platform_test.go @@ -0,0 +1,104 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +func TestDesktopInputAvailability(t *testing.T) { + logger := slog.New(slog.DiscardHandler) + for _, kind := range []string{"x11", "wayland"} { + t.Run(kind, func(t *testing.T) { + t.Setenv("XDG_SESSION_TYPE", kind) + t.Setenv("DISPLAY", "") + backends := []desktopInputBackend{xorg.New(), xorg.NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout)} + for _, backend := range backends { + service := desktopInputService("test", backend, logger) + err := service.Start(context.Background()) + if (err == nil) != (kind == "wayland") { + t.Fatalf("%T startup in %s: %v", backend, kind, err) + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + if err := service.Stop(ctx); err != nil { + t.Errorf("%T cleanup: %v", backend, err) + } + cancel() + } + // Future non-Xorg backends must keep their own failure contract. + failure := errors.New("other backend failed") + other := &fakeInputListener{startError: failure} + if err := desktopInputService("other", other, logger).Start(context.Background()); !errors.Is(err, failure) { + t.Fatalf("other backend startup: %v", err) + } + }) + } +} + +func TestOptionalXorgPreservesCancellation(t *testing.T) { + logger := slog.New(slog.DiscardHandler) + for _, failure := range []error{context.Canceled, context.DeadlineExceeded} { + if err := startOptionalXorg(context.Background(), "test", func(context.Context) error { return failure }, logger); !errors.Is(err, failure) { + t.Fatalf("startup: %v, want %v", err, failure) + } + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if err := startOptionalXorg(ctx, "test", func(context.Context) error { return nil }, logger); !errors.Is(err, context.Canceled) { + t.Fatalf("canceled startup: %v", err) + } +} + +func TestRunWaylandWithoutX11SpeaksAndStops(t *testing.T) { + t.Setenv("XDG_SESSION_TYPE", "wayland") + t.Setenv("DISPLAY", "") + speaker := &fakeSpeaker{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan error, 1) + go func() { + completed <- Run(ctx, Options{ + Logger: slog.New(slog.DiscardHandler), + newSpeaker: func() Speaker { return speaker }, + newSound: func() soundService { return silentSound{} }, + newAdapter: func() Adapter { return adapter }, + }) + }() + adapter.events <- atspi.NewEvent("focus:", atspi.NewSnapshot("/accessible/save", "Save", "push button", "", "")) + for _, expected := range []string{"", "Save", "push button"} { + select { + case spoken := <-speaker.spoken: + if expected == "" && contains_string(startupMessages, spoken) || expected != "" && spoken == expected { + continue + } + t.Fatalf("speech = %q, expected %q", spoken, expected) + case err := <-completed: + t.Fatalf("runtime exited before focus speech: %v", err) + case <-time.After(3 * time.Second): + t.Fatal("runtime did not present focus with X11 unavailable") + } + } + cancel() + select { + case err := <-completed: + if err != nil { + t.Fatal(err) + } + case <-time.After(3 * time.Second): + t.Fatal("runtime did not stop") + } + if !adapter.stopped || !speaker.closed { + t.Fatal("runtime did not clean up AT-SPI and speech") + } +} diff --git a/internal/app/runtime_remote.go b/internal/app/runtime_remote.go new file mode 100644 index 0000000..9858b38 --- /dev/null +++ b/internal/app/runtime_remote.go @@ -0,0 +1,138 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "strconv" + "time" + + "git.stormux.org/storm/cthulhu/internal/lifecycle" + "git.stormux.org/storm/cthulhu/internal/nvda2cthulhu" + "git.stormux.org/storm/cthulhu/internal/remote" + "git.stormux.org/storm/cthulhu/internal/wine" +) + +// remoteServiceDependencies are held by the service closures for the lifetime +// of the runner. The input and adapter counters are read only on snapshot calls. +type remoteServiceDependencies struct { + logger *slog.Logger + stopRun context.CancelFunc + adapter Adapter + inputListener InputListener + speech *speechWorker + braille *brailleWorker + live *liveSettings + preferences *preferencesWorker + onPreferences func() +} + +func newRemoteRuntimeServices(deps remoteServiceDependencies) []lifecycle.Service { + remoteHandler := remoteSpeech{braille: lockFeedbackBraille{deps.braille}} + remoteHandler.live = deps.live + remoteHandler.preferences = deps.preferences + remoteHandler.showPreferences = deps.onPreferences + remoteHandler.quit = func() { time.AfterFunc(100*time.Millisecond, deps.stopRun) } + remoteHandler.runtimeSnapshot = func() string { + snapshot := "CTHULHU RUNTIME STATE SNAPSHOT\n[event_manager]\noverflow: " + strconv.FormatUint(deps.adapter.Overflow(), 10) + if deps.inputListener != nil { + snapshot += "\n[input_event_manager]\noverflow: " + strconv.FormatUint(deps.inputListener.Overflow(), 10) + } + return snapshot + } + if deps.speech != nil { + remoteHandler.speech = deps.speech + } + wineEvents := newWineEventPresenter(func(message string) bool { + return remoteHandler.presentMessage(message, "wine-accessible-event") + }) + wineEvents.logger = deps.logger + wineEvents.foreground, _ = deps.adapter.(foregroundMonitor) + wineEvents.titles, _ = deps.adapter.(windowTitleSource) + if deps.live != nil { + nativeEditField := deps.live.editFieldFocused + deps.live.editFieldFocused = func() bool { + return wineEvents.EditFieldFocused() || nativeEditField != nil && nativeEditField() + } + } + connectWineWindowTitles(wineEvents, deps.live, deps.adapter) + remoteHandler.wine = wineEvents + if deps.live != nil { + remoteHandler.wineReview = deps.live.wineReview + } + remoteService := remote.New(deps.logger, remoteHandler) + services := []lifecycle.Service{{ + Name: "self-voice D-Bus", + Start: func(ctx context.Context) error { + if err := remoteService.Start(ctx); err != nil { + deps.logger.Warn("Cthulhu D-Bus service unavailable", "error", err) + } + return nil + }, + Stop: func(ctx context.Context) error { + wineEvents.Close() + if err := remoteService.Stop(ctx); err != nil { + deps.logger.Warn("Cthulhu D-Bus service shutdown", "error", err) + } + return nil + }, + }} + if remoteHandler.wineReview != nil { + registry := remoteHandler.wineReview + // Reverse shutdown cancels captures before the borrowed service bus closes. + services = append(services, lifecycle.Service{Name: "Wine flat review", Start: func(ctx context.Context) error { + if err := registry.Start(ctx); err != nil { + deps.logger.Warn("Wine flat review unavailable", "error", err) + } + return nil + }, Stop: registry.Stop}) + } + orcaService := remote.NewOrca(deps.logger, remoteHandler) + services = append(services, lifecycle.Service{ + Name: "Orca compatibility D-Bus", + Start: func(ctx context.Context) error { + if err := orcaService.Start(ctx); err != nil { + deps.logger.Warn("Orca compatibility D-Bus service unavailable", "error", err) + } + return nil + }, + Stop: func(ctx context.Context) error { + if err := orcaService.Stop(ctx); err != nil { + deps.logger.Warn("Orca compatibility D-Bus service shutdown", "error", err) + } + return nil + }, + }) + bridgeServer := nvda2cthulhu.New(deps.logger, remoteHandler) + services = append(services, lifecycle.Service{ + Name: "NVDA to Cthulhu bridge", + Start: func(ctx context.Context) error { + if err := bridgeServer.Start(ctx); err != nil { + deps.logger.Warn("NVDA to Cthulhu bridge unavailable", "error", err) + } + return nil + }, + Stop: bridgeServer.Stop, + }) + wineManager := wine.New(deps.logger) + services = append(services, lifecycle.Service{ + Name: "Wine accessibility", Start: wineManager.Start, Stop: wineManager.Stop, + }) + return services +} diff --git a/internal/app/runtime_review.go b/internal/app/runtime_review.go new file mode 100644 index 0000000..e193780 --- /dev/null +++ b/internal/app/runtime_review.go @@ -0,0 +1,67 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + + "git.stormux.org/storm/cthulhu/internal/lifecycle" + "git.stormux.org/storm/cthulhu/internal/review" +) + +// newRuntimeReviewServices registers review after AT-SPI, then optional browser +// mode and secure lock. Reverse shutdown therefore stops review before AT-SPI +// releases native callback state. +func newRuntimeReviewServices(logger *slog.Logger, commands commandListener, adapter Adapter, inputListener InputListener, focusGate *focusGate, speechOutput speechEnqueuer, speechMessages *speechWorker, brailleOutput *brailleWorker, wineCapture ...wineReviewCapturer) (*review.Worker, *browserModeController, []lifecycle.Service, error) { + var capturer review.TreeCapturer = adapter + if len(wineCapture) > 0 && wineCapture[0] != nil { + capturer = &reviewCaptureRouter{native: adapter, wine: wineCapture[0]} + } + objectReview, err := review.NewWorker(capturer, objectReviewCaptureTimeout) + if err != nil { + return nil, nil, nil, err + } + if err := objectReview.SetFlatCaptureTimeout(flatReviewCaptureTimeout); err != nil { + return nil, nil, nil, err + } + if err := objectReview.SetDocumentCaptureTimeout(documentCaptureTimeout); err != nil { + return nil, nil, nil, err + } + services := []lifecycle.Service{{Name: "object review", Start: objectReview.Start, Stop: objectReview.Stop}} + var browser *browserModeController + if keys, ok := commands.(browseKeyOwner); ok { + if capturer, ok := adapter.(documentContextCapturer); ok { + browser = newBrowserModeController(inputListener, keys, capturer) + services = append(services, lifecycle.Service{Name: "browser mode", Start: browser.Start, Stop: browser.Stop}) + } + } + focusGate.speech = speechOutput + lockMonitor := &screenLockMonitor{logger: logger, setActive: func(active bool) { + focusGate.SetLocked(active, adapter, inputListener, commands, speechMessages, brailleOutput) + objectReview.ClearFocus() + logger.Info("I38lock secure mode changed", "active", active) + }} + services = append(services, lifecycle.Service{Name: "screen lock", Start: func(ctx context.Context) error { + if err := lockMonitor.Start(ctx); err != nil { + logger.Warn("I38lock monitor unavailable", "error", err) + } + return nil + }, Stop: lockMonitor.Stop}) + return objectReview, browser, services, nil +} diff --git a/internal/app/runtime_settings.go b/internal/app/runtime_settings.go new file mode 100644 index 0000000..8d854bc --- /dev/null +++ b/internal/app/runtime_settings.go @@ -0,0 +1,118 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/sound" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +func speechSettingsFromConfig(settings config.Settings) speech.Settings { + speechSettings := speech.Settings{ + OutputModule: settings.SpeechOutputModule, + Punctuation: map[int]string{0: "all", 1: "most", 2: "some", 3: "none"}[settings.VerbalizePunctuationStyle], + Capitalization: "none", + } + if settings.DefaultVoice.Rate != nil { + value := int(2*(*settings.DefaultVoice.Rate) - 98) + speechSettings.Rate = &value + } + if settings.DefaultVoice.AveragePitch != nil { + value := int(20*(*settings.DefaultVoice.AveragePitch) - 90) + speechSettings.Pitch = &value + } + if settings.DefaultVoice.Gain != nil { + value := int(15*(*settings.DefaultVoice.Gain) - 35) + speechSettings.Volume = &value + } + if family := settings.DefaultVoice.Family; family != nil { + speechSettings.Language = family.Lang + if family.Dialect != "" { + speechSettings.Language += "-" + family.Dialect + } + speechSettings.SynthesisVoice = family.Name + } + return speechSettings +} + +func inputEchoSettingsFromConfig(settings config.Settings) input.EchoSettings { + return input.EchoSettings{ + EnableKeyEcho: settings.EnableKeyEcho, + EnableModifierKeys: settings.EnableModifierKeys, + EnableFunctionKeys: settings.EnableFunctionKeys, + EnableActionKeys: settings.EnableActionKeys, + EnableNavigationKeys: settings.EnableNavigationKeys, + EnableDiacriticalKeys: settings.EnableDiacriticalKeys, + CthulhuModifierKeys: append([]string(nil), settings.CthulhuModifierKeys...), + } +} + +func presentationSettingsFromConfig(settings config.Settings, soundEnabled bool) presentation.Options { + return presentation.Options{ + Reading: &settings.Reading, + SpeakDescription: settings.SpeakDescription && !settings.Reading.OnlySpeakDisplayedText, + ReadFullRowInGUITable: settings.Reading.ReadFullRowInGUITable, + SpeechVerbosityLevel: settings.SpeechVerbosityLevel, + SpeakBlankLines: settings.Reading.SpeakBlankLines && !settings.Reading.OnlySpeakDisplayedText, + SayAllStyle: settings.SayAllStyle, + EnableSound: soundEnabled && soundConfiguration(settings).Enabled, + PlaySoundForRole: settings.PlaySoundForRole, + PlaySoundForState: settings.PlaySoundForState, + RoleSoundPresentation: settings.RoleSoundPresentation, + SpatializeObjectSounds: settings.SpatializeObjectSounds, + EnableKeyEcho: settings.EnableKeyEcho, + KeyEchoInEditFieldsOnly: settings.KeyEchoInEditFieldsOnly, + EnableEchoByCharacter: settings.EnableEchoByCharacter, + EnableEchoByWord: settings.EnableEchoByWord, + EnableEchoBySentence: settings.EnableEchoBySentence, + EnableAlphabeticKeys: settings.EnableAlphabeticKeys, + EnableNumericKeys: settings.EnableNumericKeys, + EnablePunctuationKeys: settings.EnablePunctuationKeys, + EnableSpace: settings.EnableSpace, + EnableDiacriticalKeys: settings.EnableDiacriticalKeys, + + PlaySoundForPositionInSet: settings.PlaySoundForPositionInSet, + } +} + +func soundConfiguration(settings config.Settings) sound.Configuration { + return sound.Configuration{ + Enabled: settings.EnableSound && settings.SoundTheme != "none" && settings.SoundVolume > 0, + Sink: settings.SoundSink, Theme: settings.SoundTheme, Volume: settings.SoundVolume, + } +} + +func captureSoundGeometry(settings config.Settings) bool { + return soundConfiguration(settings).Enabled && settings.SpatializeObjectSounds && + (settings.PlaySoundForRole || settings.PlaySoundForState || settings.PlaySoundForPositionInSet) +} + +func captureTextAttributes(settings config.Settings) bool { + if !settings.EnableBraille || settings.TextAttributes.Indicator == 0 { + return false + } + for _, choice := range settings.TextAttributes.Choices { + if choice.Braille { + return true + } + } + return false +} diff --git a/internal/app/runtime_settings_test.go b/internal/app/runtime_settings_test.go new file mode 100644 index 0000000..7a8be7a --- /dev/null +++ b/internal/app/runtime_settings_test.go @@ -0,0 +1,117 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestSpeechSettingsFromConfig(t *testing.T) { + rate, pitch, gain := 75.0, 4.5, 5.0 + settings := config.DefaultSettings() + settings.VerbalizePunctuationStyle = 2 + settings.CapitalizationStyle = "icon" + settings.DefaultVoice = config.Voice{ + Rate: &rate, + AveragePitch: &pitch, + Gain: &gain, + Family: &config.VoiceFamily{Name: "Generic Voice", Lang: "en", Dialect: "US"}, + } + + got := speechSettingsFromConfig(settings) + if got.Rate == nil || *got.Rate != 52 || got.Pitch == nil || *got.Pitch != 0 || + got.Volume == nil || *got.Volume != 40 { + t.Fatalf("converted voice values = rate %v pitch %v volume %v", got.Rate, got.Pitch, got.Volume) + } + if got.Punctuation != "some" || got.Capitalization != "none" || + got.Language != "en-US" || got.SynthesisVoice != "Generic Voice" { + t.Fatalf("converted speech settings = %#v", got) + } +} + +func TestSpeechSettingsLanguageWithoutPerson(t *testing.T) { + settings := config.DefaultSettings() + settings.DefaultVoice.Family = &config.VoiceFamily{Lang: "es"} + got := speechSettingsFromConfig(settings) + if got.Language != "es" || got.SynthesisVoice != "" { + t.Fatalf("language-only speech settings = %#v", got) + } +} + +func TestPresentationSettingsFromConfig(t *testing.T) { + settings := config.DefaultSettings() + settings.SpeakDescription = false + settings.PlaySoundForRole = true + settings.PlaySoundForState = true + settings.PlaySoundForPositionInSet = true + settings.RoleSoundPresentation = "speech_only" + settings.EnableKeyEcho = false + settings.EnableEchoByCharacter = true + settings.EnableEchoByWord = true + settings.EnableEchoBySentence = true + settings.EnableAlphabeticKeys = false + settings.EnableNumericKeys = false + settings.EnablePunctuationKeys = false + settings.EnableSpace = false + settings.EnableDiacriticalKeys = true + + got := presentationSettingsFromConfig(settings, true) + if got.SpeakDescription || !got.EnableSound || !got.PlaySoundForRole || !got.PlaySoundForState || !got.PlaySoundForPositionInSet || + got.RoleSoundPresentation != "speech_only" || got.EnableKeyEcho || !got.EnableEchoByCharacter || + !got.EnableEchoByWord || !got.EnableEchoBySentence || + got.EnableAlphabeticKeys || got.EnableNumericKeys || got.EnablePunctuationKeys || got.EnableSpace || + !got.EnableDiacriticalKeys { + t.Fatalf("presentation settings = %+v", got) + } + settings.EnableSound = false + settings.PlaySoundForPositionInSet = false + if got := presentationSettingsFromConfig(settings, true); got.PlaySoundForPositionInSet { + t.Fatal("disabled position setting remained enabled in presentation") + } + if got := presentationSettingsFromConfig(settings, true); got.EnableSound { + t.Fatal("disabled sound setting remained enabled in presentation") + } + settings.EnableSound = true + settings.SoundTheme = "none" + if got := presentationSettingsFromConfig(settings, true); got.EnableSound { + t.Fatal("none sound theme remained enabled in presentation") + } +} + +func TestInputEchoSettingsFromConfig(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableModifierKeys = false + settings.EnableFunctionKeys = false + settings.EnableActionKeys = false + settings.EnableNavigationKeys = true + settings.EnableDiacriticalKeys = true + settings.CthulhuModifierKeys = []string{"Insert"} + + got := inputEchoSettingsFromConfig(settings) + if !got.EnableKeyEcho || got.EnableModifierKeys || got.EnableFunctionKeys || got.EnableActionKeys || + !got.EnableNavigationKeys || !got.EnableDiacriticalKeys || len(got.CthulhuModifierKeys) != 1 || + got.CthulhuModifierKeys[0] != "Insert" { + t.Fatalf("input echo settings = %+v", got) + } + settings.CthulhuModifierKeys[0] = "KP_Insert" + if got.CthulhuModifierKeys[0] != "Insert" { + t.Fatal("input echo settings retained the mutable configuration slice") + } +} diff --git a/internal/app/runtime_shutdown.go b/internal/app/runtime_shutdown.go new file mode 100644 index 0000000..e0aa72a --- /dev/null +++ b/internal/app/runtime_shutdown.go @@ -0,0 +1,106 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "errors" + "log/slog" + "time" + + "git.stormux.org/storm/cthulhu/internal/lifecycle" +) + +// runtimeShutdown owns the ordered teardown after the event loop returns. +// The worker channels must close before preferences, braille, and speech stop. +type runtimeShutdown struct { + tentacles *tentacleRuntime + ocr *ocrSession + logger *slog.Logger + cancel context.CancelFunc + workers *runtimeWorkers + preferences *preferencesWorker + braille *brailleWorker + speech *speechWorker + focusGate *focusGate + services *lifecycle.Runner +} + +func stopRuntime(runtime runtimeShutdown) error { + runtime.cancel() + var tentacleError error + if runtime.tentacles != nil { + ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second) + tentacleError = runtime.tentacles.Stop(ctx) + cancel() + } + <-runtime.workers.commandDone + if runtime.workers.internalUIDone != nil { + <-runtime.workers.internalUIDone + } + <-runtime.workers.clipboardDone + <-runtime.workers.inputDone + <-runtime.workers.copyDone + <-runtime.workers.autoClipboardDone + if runtime.ocr != nil { + ocrContext, cancelOCR := context.WithTimeout(context.Background(), 5*time.Second) + if err := runtime.ocr.Stop(ocrContext); err != nil { + runtime.logger.Warn("stop OCR", "error", err) + } + cancelOCR() + } + // Join settings work before farewell and backend shutdown. The preferences + // service also remains in the runner so failed cleanup is retried there. + if runtime.preferences != nil { + preferencesContext, cancelPreferences := context.WithTimeout(context.Background(), 7*time.Second) + if err := runtime.preferences.Stop(preferencesContext); err != nil { + runtime.logger.Warn("stop preferences", "error", err) + } + cancelPreferences() + } + brailleContext, cancelBraille := context.WithTimeout(context.Background(), shutdownTimeout) + if err := runtime.braille.Stop(brailleContext); err != nil { + runtime.logger.Warn("stop braille", "error", err) + } + cancelBraille() + if runtime.speech != nil && !runtime.focusGate.Locked() { + farewellContext, cancelFarewell := context.WithTimeout(context.Background(), farewellTimeout) + runtime.speech.InterruptForUser() + farewellError := runtime.speech.EnqueueAndWait(farewellContext, speechRequest{ + Text: random_string(shutdownMessages), + Role: "system", + Cause: "shutdown", + }) + cancelFarewell() + if farewellError != nil { + runtime.logger.Warn("deliver shutdown message", "error", farewellError) + } else { + runtime.logger.Debug("shutdown message accepted") + } + } + shutdownContext, cancelShutdown := context.WithTimeout(context.Background(), shutdownTimeout) + defer cancelShutdown() + runtime.logger.Debug("stopping runtime services") + stopError := runtime.services.Stop(shutdownContext) + if stopError != nil { + runtime.logger.Warn("runtime services stopped with an error", "error", stopError) + } else { + runtime.logger.Debug("runtime services stopped") + } + return errors.Join(tentacleError, stopError) +} diff --git a/internal/app/runtime_test.go b/internal/app/runtime_test.go new file mode 100644 index 0000000..46af168 --- /dev/null +++ b/internal/app/runtime_test.go @@ -0,0 +1,261 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "errors" + "log/slog" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestRandomString(t *testing.T) { + if got := random_string(nil); got != "" { + t.Fatalf("random_string(nil) = %q, want empty string", got) + } + if got := random_string([]string{"only"}); got != "only" { + t.Fatalf("random_string(single item) = %q, want %q", got, "only") + } +} + +func TestRunStopsSpeechAfterInputStartupFailure(t *testing.T) { + speaker := &fakeSpeaker{spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + inputListener := &fakeInputListener{ + events: make(chan input.Event), + modifierKeycodes: input.NewModifierKeycodes(37), + startError: errors.New("no X display"), + } + + err := Run(context.Background(), Options{ + Logger: slog.New(slog.DiscardHandler), + newSpeaker: func() Speaker { return speaker }, + newCommands: func() commandListener { return silentCommands{} }, + newSound: func() soundService { return silentSound{} }, + newAdapter: func() Adapter { return adapter }, + newInput: func() InputListener { return inputListener }, + }) + if err == nil || !strings.Contains(err.Error(), "no X display") { + t.Fatalf("Run error = %v, want input startup failure", err) + } + if adapter.started { + t.Fatal("AT-SPI started after X11 listener startup failure") + } + if !speaker.closed { + t.Fatal("speech connection was not closed after X11 listener startup failure") + } +} + +func TestRunStopsStartedServicesAfterStartupFailure(t *testing.T) { + speaker := &fakeSpeaker{connectError: errors.New("connection refused"), spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + + err := Run(context.Background(), Options{ + Logger: slog.New(slog.DiscardHandler), + newSpeaker: func() Speaker { return speaker }, + newCommands: func() commandListener { return silentCommands{} }, + newSound: func() soundService { return silentSound{} }, + newAdapter: func() Adapter { return adapter }, + }) + if err == nil { + t.Fatal("Run returned nil after speech connection failure") + } + if adapter.started { + t.Fatal("AT-SPI started despite speech startup failure") + } +} + +func TestRunHonorsDisabledSpeech(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = false + adapter := &fakeAdapter{events: make(chan atspi.Event)} + close(adapter.events) + speakerCreated := false + speaker := &fakeSpeaker{spoken: make(chan string, 1)} + + err := Run(context.Background(), Options{ + Logger: slog.New(slog.DiscardHandler), + Settings: &settings, + newSpeaker: func() Speaker { + speakerCreated = true + return speaker + }, + newCommands: func() commandListener { return silentCommands{} }, + newSound: func() soundService { return silentSound{} }, + newAdapter: func() Adapter { return adapter }, + newInput: func() InputListener { return &fakeInputListener{events: make(chan input.Event)} }, + }) + if err != nil { + t.Fatalf("Run: %v", err) + } + if !speakerCreated { + t.Fatal("speech client was not available for live re-enabling") + } + if speaker.connected { + t.Fatal("speech backend connected while speech was disabled") + } + if !adapter.started || !adapter.stopped { + t.Fatal("AT-SPI lifecycle did not run while speech was disabled") + } +} + +func TestRunOpensPreferencesAtStartup(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = false + settings.EnableSound = false + adapter := &fakeAdapter{events: make(chan atspi.Event)} + commands := &fakeCommands{commands: make(chan input.CommandEvent, 1)} + preferencesCalled := make(chan bool, 1) + completed := make(chan error, 1) + + go func() { + completed <- Run(context.Background(), Options{ + Logger: slog.New(slog.DiscardHandler), + Settings: &settings, + OpenPreferences: true, + newCommands: func() commandListener { return commands }, + onPreferences: func() { + select { + case preferencesCalled <- adapter.started: + default: + } + }, + newAdapter: func() Adapter { return adapter }, + newInput: func() InputListener { return &fakeInputListener{events: make(chan input.Event)} }, + }) + }() + + select { + case adapterStarted := <-preferencesCalled: + if !adapterStarted { + t.Fatal("preferences were requested before runtime services started") + } + case <-time.After(time.Second): + t.Fatal("startup preferences callback was not invoked") + } + commands.commands <- input.CommandEvent{Command: input.Quit} + select { + case err := <-completed: + if err != nil { + t.Fatalf("Run: %v", err) + } + case <-time.After(time.Second): + t.Fatal("quit was not handled after startup preferences") + } +} + +func TestRunReachesSoundStopAfterEarlierServiceStopError(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = false + adapter := &fakeAdapter{ + events: make(chan atspi.Event, 1), + stopError: context.DeadlineExceeded, + } + sounds := &recordingSound{started: make(chan struct{})} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan error, 1) + // Sound starts first; cancellation there races later service startup. + // The startup callback runs only once the complete runtime is ready. + runtimeStarted := make(chan struct{}) + + go func() { + completed <- Run(ctx, Options{ + Logger: slog.New(slog.DiscardHandler), + Settings: &settings, + OpenPreferences: true, + onPreferences: func() { close(runtimeStarted) }, + newSound: func() soundService { return sounds }, + newCommands: func() commandListener { + return silentCommands{} + }, + newAdapter: func() Adapter { return adapter }, + newInput: func() InputListener { return &fakeInputListener{events: make(chan input.Event)} }, + }) + }() + + select { + case <-runtimeStarted: + case <-time.After(time.Second): + t.Fatal("runtime did not finish startup") + } + cancel() + select { + case err := <-completed: + if !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("Run error = %v, want deadline exceeded", err) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for Run to stop") + } + if !adapter.stopped { + t.Fatal("earlier service was not stopped") + } + if !sounds.stopped { + t.Fatal("final sound service was not reached") + } +} + +func TestRunReportsSoundStopError(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = false + soundError := errors.New("stop cue failed") + sounds := &recordingSound{started: make(chan struct{}), stopError: soundError} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan error, 1) + runtimeStarted := make(chan struct{}) + + go func() { + completed <- Run(ctx, Options{ + Logger: slog.New(slog.DiscardHandler), + Settings: &settings, + OpenPreferences: true, + onPreferences: func() { close(runtimeStarted) }, + newSound: func() soundService { return sounds }, + newCommands: func() commandListener { + return silentCommands{} + }, + newAdapter: func() Adapter { + return &fakeAdapter{events: make(chan atspi.Event, 1)} + }, + newInput: func() InputListener { return &fakeInputListener{events: make(chan input.Event)} }, + }) + }() + + select { + case <-runtimeStarted: + case <-time.After(time.Second): + t.Fatal("runtime did not finish startup") + } + cancel() + select { + case err := <-completed: + if !errors.Is(err, soundError) { + t.Fatalf("Run error = %v, want sound stop error", err) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for Run to stop") + } +} diff --git a/internal/app/runtime_workers.go b/internal/app/runtime_workers.go new file mode 100644 index 0000000..9359c91 --- /dev/null +++ b/internal/app/runtime_workers.go @@ -0,0 +1,96 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +// runtimeWorkers owns the event-loop companion workers. Only the event loop +// consumes reviewRequests; command and clipboard workers send to bounded queues. +// Each done channel closes after its worker exits. commandError is read after +// commandDone closes, so no additional synchronization is needed. +type runtimeWorkers struct { + reviewRequests <-chan input.Command + attributeRequests <-chan struct{} + commandDone <-chan struct{} + clipboardDone <-chan struct{} + inputDone <-chan struct{} + copyDone <-chan struct{} + autoClipboardDone <-chan struct{} + commandError error + internalUIDone <-chan struct{} + internalUI *internalUI +} + +// startRuntimeWorkers preserves startup order: clipboard, command, input, copy. +// The caller cancels ctx and joins these workers before stopping output services. +func startRuntimeWorkers(ctx context.Context, command commandRuntime, inputListener InputListener, settings config.Settings, copyChanges <-chan struct{}, braille *brailleWorker) *runtimeWorkers { + speech := gatedSpeech{speech: command.speechOutput, gate: command.focusGate} + learn := &learnModePresenter{tentacles: command.tentacles, ctx: ctx, logger: command.logger, speech: speech, braille: braille, live: command.live} + if owner, ok := command.commands.(interface{ BrowseNavigationEnabled() bool }); ok { + learn.browse = owner + } + command.learn = learn + clipboardRequests := make(chan struct{}, 1) + clipboardDone := runClipboardWorker(ctx, clipboardRequests, speech, readClipboardMessage) + command.clipboardRequests = clipboardRequests + reviewRequests := make(chan input.Command, 1) + command.reviewRequests = reviewRequests + attributeRequests := make(chan struct{}, 1) + command.attributeRequests = attributeRequests + commandDone := make(chan struct{}) + workers := &runtimeWorkers{ + reviewRequests: reviewRequests, + attributeRequests: attributeRequests, + commandDone: commandDone, + clipboardDone: clipboardDone, + } + if keys, ok := command.commands.(internalUIKeys); ok { + ui := &internalUI{notices: make(chan internalUINotice, 4), keys: keys, documents: command.objectReview, actions: command.actionSource, interest: command.objectReview, speech: speech, braille: braille, gate: command.focusGate, events: make(chan input.CommandEvent, 32), requests: make(chan internalUIRequest, 1), done: make(chan struct{})} + command.internalUI = ui + if command.tentacles != nil { + command.tentacles.forms = ui + command.tentacles.focusedItem = focusedTentacleItem(command.actionSource, ui) + } + workers.internalUI = ui + workers.internalUIDone = ui.done + go ui.run(ctx) + } + go func() { + defer close(commandDone) + workers.commandError = command.run(ctx) + }() + + inputDone := make(chan struct{}) + if inputListener != nil { + go func() { + defer close(inputDone) + processInputEvents(ctx, command.logger, speech, inputListener, inputEchoSettingsFromConfig(settings), command.live, command.commands, command.ocr) + }() + } else { + close(inputDone) + } + workers.inputDone = inputDone + workers.copyDone = runCopyFeedback(ctx, copyChanges, inputListener, speech, command.live, command.ocr) + workers.autoClipboardDone = run_automatic_clipboard(ctx, command.logger, command.live, command.focusGate, speech) + return workers +} diff --git a/internal/app/screen_lock.go b/internal/app/screen_lock.go new file mode 100644 index 0000000..508b561 --- /dev/null +++ b/internal/app/screen_lock.go @@ -0,0 +1,209 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "fmt" + "log/slog" + "os" + "path/filepath" + "time" + + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/sessionbus" + "github.com/godbus/dbus/v5" +) + +const screenLockBusName = "org.stormux.I38Lock1" + +type secureInputController interface{ SetSecureInputActive(bool) } + +// screenLockMonitor watches the same authenticated I38lock owner as Python. +// I38lock supplies its own feedback through the existing self-voice service. +type screenLockMonitor struct { + logger *slog.Logger + setActive func(bool) + connection *dbus.Conn + signals chan *dbus.Signal + cancel context.CancelFunc + done chan struct{} + owner string + active bool + trustedOwner func(context.Context, string) bool +} + +func (monitor *screenLockMonitor) Start(ctx context.Context) error { + connection, err := sessionbus.Connect(monitor.logger, "screen-lock") + if err != nil { + return err + } + monitor.connection = connection + monitor.signals = make(chan *dbus.Signal, 16) + connection.Signal(monitor.signals) + if err := connection.AddMatchSignal(screenLockMatch()...); err != nil { + connection.Close() + return err + } + monitor.trustedOwner = func(ctx context.Context, owner string) bool { + var pid uint32 + if err := connection.BusObject().CallWithContext(ctx, "org.freedesktop.DBus.GetConnectionUnixProcessID", 0, owner).Store(&pid); err != nil { + return false + } + executable, err := os.Readlink(fmt.Sprintf("/proc/%d/exe", pid)) + return err == nil && filepath.Base(executable) == "i38lock" + } + monitor.refresh(ctx) + watchContext, cancel := context.WithCancel(ctx) + monitor.cancel, monitor.done = cancel, make(chan struct{}) + go func() { + defer close(monitor.done) + for { + select { + case <-watchContext.Done(): + return + case signal, ok := <-monitor.signals: + if !ok { + return + } + if signal != nil { + monitor.refresh(watchContext) + } + } + } + }() + return nil +} + +func screenLockMatch() []dbus.MatchOption { + return []dbus.MatchOption{dbus.WithMatchSender("org.freedesktop.DBus"), dbus.WithMatchObjectPath("/org/freedesktop/DBus"), dbus.WithMatchInterface("org.freedesktop.DBus"), dbus.WithMatchMember("NameOwnerChanged"), dbus.WithMatchArg(0, screenLockBusName)} +} + +func (monitor *screenLockMonitor) refresh(ctx context.Context) { + queryContext, cancel := context.WithTimeout(ctx, 500*time.Millisecond) + defer cancel() + var owner string + err := monitor.connection.BusObject().CallWithContext(queryContext, "org.freedesktop.DBus.GetNameOwner", 0, screenLockBusName).Store(&owner) + if err != nil { + var busError dbus.Error + if !errors.As(err, &busError) || busError.Name != "org.freedesktop.DBus.Error.NameHasNoOwner" { + monitor.logger.Warn("query I38lock owner", "error", err) + return // Do not release secure mode after a failed bus query. + } + owner = "" + } + monitor.updateOwner(queryContext, owner) +} + +func (monitor *screenLockMonitor) updateOwner(ctx context.Context, owner string) { + if owner == monitor.owner { + return + } + monitor.owner = owner + active := owner != "" && monitor.trustedOwner(ctx, owner) + if owner != "" && !active { + monitor.logger.Warn("ignoring untrusted I38lock bus owner") + } + if active != monitor.active { + monitor.active = active + monitor.setActive(active) + } +} + +func (monitor *screenLockMonitor) Stop(ctx context.Context) error { + if monitor.cancel == nil { + return nil + } + monitor.cancel() + select { + case <-monitor.done: + case <-ctx.Done(): + return ctx.Err() + } + monitor.connection.RemoveSignal(monitor.signals) + _ = monitor.connection.RemoveMatchSignal(screenLockMatch()...) + return monitor.connection.Close() +} + +func (gate *focusGate) Locked() bool { return gate != nil && gate.secure.Load() } + +func (gate *focusGate) SetLocked(active bool, adapter Adapter, listener InputListener, commands commandListener, speech *speechWorker, display *brailleWorker) { + if active { + gate.ocr.Secure() + } + gate.mutex.Lock() + defer gate.mutex.Unlock() + if !gate.secure.CompareAndSwap(!active, active) { + return + } + gate.retireTentacleOutput() + for _, target := range []any{adapter, listener, commands} { + if controller, ok := target.(secureInputController); ok { + controller.SetSecureInputActive(active) + } + } + if gate.commands != nil { + gate.commands.SetCommandGrabs(!active && !gate.suspended.Load()) + } + if speech != nil { + speech.SetSecureInputActive(active) + } + display.SetSecureInputActive(active) + select { + case gate.lockChanges <- struct{}{}: + default: + } +} + +func (worker *speechWorker) SetSecureInputActive(active bool) { + worker.mutex.Lock() + defer worker.mutex.Unlock() + worker.secure = active + if active { + worker.startupUntil = time.Time{} + worker.interruptLocked() + } +} + +func (worker *brailleWorker) SetSecureInputActive(active bool) { + worker.mu.Lock() + worker.secure = active + // Retire flash restoration and routing targets even without a display. + worker.protectedFlash = false + worker.flashContext = nil + worker.flashGeneration++ + if worker.flashTimer != nil { + worker.flashTimer.Stop() + worker.flashTimer = nil + } + if worker.routeCancel != nil { + worker.routeCancel() + } + worker.frame, worker.baseFrame = braille.Frame{Cursor: -1}, braille.Frame{Cursor: -1} + worker.internalUIFrame = nil + worker.enqueueSecureFrameLocked(braille.Frame{Cursor: -1}, true) + worker.mu.Unlock() + worker.wakeDisplay() +} + +func (worker *brailleWorker) EnqueueSecureMessage(text string) bool { + if text == "" || len(text) > 10000 { + return false + } + worker.mu.Lock() + queued := worker.connected && worker.enqueueSecureFrameLocked(braille.Frame{Text: text, Cursor: -1}, true) + worker.mu.Unlock() + if queued { + worker.wakeDisplay() + } + return queued +} + +type lockFeedbackBraille struct{ worker *brailleWorker } + +func (display lockFeedbackBraille) EnqueueMessage(text string) bool { + return display.worker.EnqueueSecureMessage(text) +} diff --git a/internal/app/screen_lock_test.go b/internal/app/screen_lock_test.go new file mode 100644 index 0000000..d304303 --- /dev/null +++ b/internal/app/screen_lock_test.go @@ -0,0 +1,204 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "context" + "fmt" + "log/slog" + "os" + "os/exec" + "path/filepath" + "reflect" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "github.com/godbus/dbus/v5" +) + +func TestScreenLockRejectsLocalOutputButPreservesRemoteFeedback(t *testing.T) { + logger := slog.New(slog.DiscardHandler) + worker := newSpeechWorker(logger, nil) + worker.running = true // Retain requests for inspection without backend I/O. + worker.EnqueueStartup(speechRequest{Text: "Welcome", Cause: "startup"}) + display := &brailleWorker{cancel: func() {}, connected: true, wake: make(chan struct{}, 1)} + display.EnqueueFrame(braille.Frame{Text: "Desktop", Cursor: 0}) + display.Flash("Notice", config.BrailleOptions{FlashMessages: true, FlashPersistent: true}) + commands := &commandGrabRecorder{} + gate := newFocusGate(commands) + gate.speech = worker + gate.SetLocked(true, nil, nil, commands, worker, display) + if len(worker.pending) != 0 || !worker.startupUntil.IsZero() || display.current().Text != "" || display.baseFrame.Text != "" { + t.Fatal("lock retained desktop presentation or startup protection") + } + // A terminal focus transition must never reopen command grabs during lock. + gate.SetSuspended(true) + gate.SetSuspended(false) + for _, enabled := range commands.grabs() { + if enabled { + t.Fatal("terminal focus restored grabs while locked") + } + } + guarded := gatedSpeech{speech: worker, gate: gate} + guarded.Enqueue(speechRequest{Text: "Private desktop", BypassFocusGate: true}) + presentNotifications(guarded, []string{"Notification ready"}) + worker.Enqueue(speechRequest{Text: "Notification", Cause: "notification"}) + if guarded.InterruptForInput(input.Event{Pressed: true}) { + t.Fatal("password key interrupted locker feedback") + } + display.Enqueue("Private desktop") + display.EnqueueMessage("Notification") + if len(worker.pending) != 0 || display.current().Text != "" { + t.Fatal("local output escaped secure mode") + } + remote := remoteSpeech{speech: worker, braille: lockFeedbackBraille{display}} + if !remote.PresentMessage("Screen locked") || len(worker.pending) != 1 || worker.pending[0].Text != "Screen locked" || display.current().Text != "Screen locked" { + t.Fatal("I38lock feedback was suppressed") + } + gate.SetLocked(false, nil, nil, commands, worker, display) + if display.current().Text != "" { + t.Fatal("unlock retained locker feedback") + } + guarded.Enqueue(speechRequest{Text: "Desktop resumed"}) + if len(worker.pending) != 2 || !commands.grabs()[len(commands.grabs())-1] { + t.Fatal("unlock did not resume desktop presentation and grabs") + } +} + +func TestScreenLockOwnerAuthenticationAndReplacement(t *testing.T) { + var states []bool + monitor := &screenLockMonitor{logger: slog.New(slog.DiscardHandler), setActive: func(active bool) { states = append(states, active) }, trustedOwner: func(_ context.Context, owner string) bool { return owner == ":1.42" }} + for _, owner := range []string{":1.41", ":1.42", ":1.42", "", ":1.43"} { + monitor.updateOwner(context.Background(), owner) + } + if !reflect.DeepEqual(states, []bool{true, false}) { + t.Fatalf("lock transitions = %v", states) + } +} + +// Executed under a copied test executable named i38lock, so /proc/PID/exe +// exercises the production owner authentication rather than a mocked PID. +func TestI38lockOwnerHelper(t *testing.T) { + if os.Getenv("CTHULHU_LOCK_HELPER") != "1" { + t.Skip("subprocess helper") + } + connection, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + defer connection.Close() + if reply, err := connection.RequestName(screenLockBusName, dbus.NameFlagDoNotQueue); err != nil || reply != dbus.RequestNameReplyPrimaryOwner { + t.Fatalf("request lock name: %v, %v", reply, err) + } + fmt.Println("ready") + var input [1]byte + _, _ = os.Stdin.Read(input[:]) + _, _ = connection.ReleaseName(screenLockBusName) +} + +func TestNativeI38lockOwnerStartupUnlockAndSpoofing(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" { + t.Skip("requires private session bus") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + data, err := os.ReadFile(executable) + if err != nil { + t.Fatal(err) + } + path := filepath.Join(t.TempDir(), "i38lock") + if err := os.WriteFile(path, data, 0700); err != nil { + t.Fatal(err) + } + process := exec.CommandContext(ctx, path, "-test.run=^TestI38lockOwnerHelper$") + process.Env = append(os.Environ(), "CTHULHU_LOCK_HELPER=1") + stdout, err := process.StdoutPipe() + if err != nil { + t.Fatal(err) + } + stdin, err := process.StdinPipe() + if err != nil { + t.Fatal(err) + } + process.Stderr = os.Stderr + if err := process.Start(); err != nil { + t.Fatal(err) + } + defer process.Process.Kill() + line, err := bufio.NewReader(stdout).ReadString('\n') + if err != nil || line != "ready\n" { + t.Fatalf("helper ready = %q, %v", line, err) + } + states := make(chan bool, 8) + monitor := &screenLockMonitor{logger: slog.New(slog.DiscardHandler), setActive: func(active bool) { states <- active }} + if err := monitor.Start(ctx); err != nil { + t.Fatal(err) + } + defer monitor.Stop(context.Background()) + expect := func(want bool) { + t.Helper() + select { + case got := <-states: + if got != want { + t.Fatalf("secure state = %v, want %v", got, want) + } + case <-ctx.Done(): + t.Fatal("missing secure state transition") + } + } + expect(true) // Reader started after the screen was already locked. + stdin.Close() + if err := process.Wait(); err != nil { + t.Fatal(err) + } + expect(false) + spoof, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + defer spoof.Close() + if _, err := spoof.RequestName(screenLockBusName, dbus.NameFlagDoNotQueue); err != nil { + t.Fatal(err) + } + select { + case <-states: + t.Fatal("untrusted owner changed secure state") + case <-time.After(100 * time.Millisecond): + } + _, _ = spoof.ReleaseName(screenLockBusName) + // Verify a trusted owner appearing after subscription as well as startup. + process = exec.CommandContext(ctx, path, "-test.run=^TestI38lockOwnerHelper$") + process.Env = append(os.Environ(), "CTHULHU_LOCK_HELPER=1") + stdout, err = process.StdoutPipe() + if err != nil { + t.Fatal(err) + } + stdin, err = process.StdinPipe() + if err != nil { + t.Fatal(err) + } + if err := process.Start(); err != nil { + t.Fatal(err) + } + defer process.Process.Kill() + line, err = bufio.NewReader(stdout).ReadString('\n') + if err != nil || line != "ready\n" { + t.Fatalf("helper ready = %q, %v", line, err) + } + expect(true) + stdin.Close() + if err := process.Wait(); err != nil { + t.Fatal(err) + } + expect(false) +} diff --git a/internal/app/selection_native_test.go b/internal/app/selection_native_test.go new file mode 100644 index 0000000..7f49739 --- /dev/null +++ b/internal/app/selection_native_test.go @@ -0,0 +1,110 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestNativeBrowserSelection(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys %s: %v %s", chord, err, out) + } + } + var entry atspi.Snapshot + for attempt := 0; attempt < 30 && !entry.ID().Valid(); attempt++ { + keys("Tab") + timer := time.NewTimer(250 * time.Millisecond) + waitFocus: + for { + select { + case event := <-adapter.Events(): + if isFocusEvent(event.Type) && event.Source.Name == "Display name" && event.Source.Editable { + entry = event.Source + break waitFocus + } + case <-timer.C: + break waitFocus + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + timer.Stop() + } + if !entry.ID().Valid() { + t.Fatal("editable browser input not focused") + } + if out, err := exec.CommandContext(ctx, "xdotool", "type", "--clearmodifiers", "--delay", "20", "hello world").CombinedOutput(); err != nil { + t.Fatalf("type fixture text: %v %s", err, out) + } + waitSelection := func(want string) { + t.Helper() + deadline := time.NewTimer(3 * time.Second) + defer deadline.Stop() + for { + select { + case event := <-adapter.Events(): + if event.Type == atspi.TextSelectionChangedEvent && event.Source.ID() == entry.ID() && + strings.Contains(event.Source.SelectionText, want) { + if event.Source.SelectionEnd <= event.Source.SelectionStart { + t.Fatalf("selection range missing: %+v", event.Source) + } + return + } + case <-deadline.C: + t.Fatalf("no native selection containing %q", want) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + keys("ctrl+a") + waitSelection("hello world") + keys("Right") + keys("shift+Left") + waitSelection("d") + keys("ctrl+shift+Left") + waitSelection("world") + waitMutation := func(eventType string) { + t.Helper() + deadline := time.NewTimer(3 * time.Second) + defer deadline.Stop() + for { + select { + case event := <-adapter.Events(): + if event.Type == eventType && event.Source.ID() == entry.ID() { + return + } + case <-deadline.C: + t.Fatalf("no native %s in browser input", eventType) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + keys("ctrl+x") + waitMutation(atspi.TextDeletedEvent) + keys("ctrl+v") + waitMutation(atspi.TextInsertedEvent) +} diff --git a/internal/app/speech_delivery.go b/internal/app/speech_delivery.go new file mode 100644 index 0000000..923aa41 --- /dev/null +++ b/internal/app/speech_delivery.go @@ -0,0 +1,261 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "errors" + "fmt" + "log/slog" + "unicode/utf8" +) + +func (worker *speechWorker) deliver(ctx context.Context, request speechRequest) error { + if err := ctx.Err(); err != nil { + return err + } + // Suppressed utterances must not cancel the spoken mode announcement. + // Mode changes already interrupt the synth through the worker barrier. + if handled, err := worker.deliver_mode(ctx, request); handled { + return err + } + if handled, err := worker.deliver_phonetic_hint(ctx, request); handled { + return err + } + // Incoming output always queues. Only input/command handling may cancel + // earlier speech; a delayed state or focus event is not another user action. + if len(request.Spelling) != 0 { + // One parent request owns its context; letter recursion must not + // re-announce it or alter the original character's voice choice. + if err := worker.deliver_context(ctx, request); err != nil { + return err + } + request.Context = nil + parts := request.Spelling + voices := request.SpellingVoices + request.Spelling = nil + request.SpellingVoices = nil + request.Append = true + for index, part := range parts { + worker.mutex.Lock() + interrupted := worker.generation != request.deliveryGeneration + worker.mutex.Unlock() + if interrupted { + return context.Canceled + } + request.Text = part + request.VoiceType = "" + if index < len(voices) { + request.VoiceType = voices[index] + } + if err := worker.deliver(ctx, request); err != nil { + return err + } + } + return nil + } + if err := worker.deliver_context(ctx, request); err != nil { + return err + } + if len(request.ReadAll) != 0 { + reader, ok := worker.speaker.(interface { + SpeakAndWait(context.Context, string, func()) error + }) + if !ok { + return errors.New("speech backend does not support continuous reading") + } + for index, part := range request.ReadAll { + if err := ctx.Err(); err != nil { + return err + } + if part.Context != nil && !request.ResetContext { + if err := worker.deliver_context_for(ctx, part.Context, true); err != nil { + return err + } + } + text := worker.transformText(worker.line_text(part.Text, part.Line)) + delivery := request + delivery.VoiceType, delivery.CustomEcho = part.VoiceType, part.VoiceType == "echo" + worker.logDelivery(ctx, delivery, text, index) + if worker.history != nil && !request.ExcludeFromHistory && request.Cause != "speech-history" { + worker.history.add(text, request.Role) + } + var err error + if voiced, ok := worker.speaker.(interface { + SpeakVoiceAndWait(context.Context, string, string, func()) error + }); ok { + err = voiced.SpeakVoiceAndWait(ctx, text, part.VoiceType, part.Began) + } else { + err = reader.SpeakAndWait(ctx, text, part.Began) + } + if err != nil { + return err + } + } + return nil + } + if request.Uninterruptible { + reader, ok := worker.speaker.(interface { + speak_uninterruptible(context.Context, string) error + }) + if !ok { + return errors.New("speech backend does not support uninterruptible completion") + } + text := worker.transformText(worker.line_text(request.Text, request.Line)) + worker.record_delivery(ctx, request, text) + return reader.speak_uninterruptible(ctx, text) + } + if request.Confirmation { + text := worker.transformText(worker.line_text(request.Text, request.Line)) + worker.record_delivery(ctx, request, text) + if voiced, ok := worker.speaker.(interface { + SpeakVoiceAndWait(context.Context, string, string, func()) error + }); ok { + return voiced.SpeakVoiceAndWait(ctx, text, "system", nil) + } + reader, ok := worker.speaker.(interface { + SpeakAndWait(context.Context, string, func()) error + }) + if !ok { + return errors.New("speech backend does not support confirmation completion") + } + return reader.SpeakAndWait(ctx, text, nil) + } + speak := worker.speaker.Speak + kind := request.VoiceType + if kind == "" { + switch request.Role { + case "system": + kind = "system" + case "link": + kind = "hyperlink" + } + } + if voiced, ok := worker.speaker.(interface { + SpeakVoice(context.Context, string, string) error + }); ok { + speak = func(ctx context.Context, text string) error { return voiced.SpeakVoice(ctx, text, kind) } + } + if request.Character { + if character, ok := worker.speaker.(interface { + SpeakCharacter(context.Context, string) error + }); ok { + speak = character.SpeakCharacter + } + } + if request.CustomEcho && request.Character { + if echo, ok := worker.speaker.(interface { + SpeakEchoCharacter(context.Context, string) error + }); ok { + speak = echo.SpeakEchoCharacter + } + } else if request.CustomEcho { + if echo, ok := worker.speaker.(interface { + SpeakEcho(context.Context, string) error + }); ok { + speak = echo.SpeakEcho + } + } + // A key name and its resulting caret/focus feedback arrive separately. + // Wait for the key name's END before the next request can cancel it, + // including when the echo voice uses a different synthesizer. New input + // still cancels active speech through the worker's cancellation barrier. + if request.Cause == "key-echo" { + if voiced, ok := worker.speaker.(interface { + SpeakVoiceAndWait(context.Context, string, string, func()) error + }); ok { + if request.CustomEcho { + kind = "echo" + } + if request.Character && capitalCharacter(request.Text) { + kind = capitalVoice(request.CustomEcho) + } + speak = func(ctx context.Context, text string) error { + return voiced.SpeakVoiceAndWait(ctx, text, kind, nil) + } + } + } + chunks := request.Chunks + if len(chunks) == 0 { + chunks = []string{request.Text} + } + for index, chunk := range chunks { + if err := ctx.Err(); err != nil { + return err + } + worker.mutex.Lock() + interrupted := worker.generation != request.deliveryGeneration + worker.mutex.Unlock() + if interrupted { + return context.Canceled + } + if index == 0 { + chunk = worker.line_text(chunk, request.Line) + } + text := chunk + // Character navigation and literal spelling must retain the original + // letter and case. History rows contain the transformed delivery. + // Spoken character names still accept pronunciation replacements. + historyRow := request.ExcludeFromHistory && request.Role == "table cell" + if !historyRow && !(request.Character && utf8.RuneCountInString(chunk) == 1) { + text = worker.transformText(chunk) + } + if (request.Character && capitalCharacter(chunk)) || request.VoiceType == "uppercase" { + if err := worker.present_capital(ctx, request); err != nil { + return err + } + } + part := request + part.Append = request.Append || index > 0 + worker.record_delivery(ctx, part, text) + if err := speak(ctx, text); err != nil { + return fmt.Errorf("speak: %w", err) + } + } + return nil +} + +func (worker *speechWorker) record_delivery(ctx context.Context, request speechRequest, text string) { + worker.logDelivery(ctx, request, text, -1) + if worker.history != nil && !request.ExcludeFromHistory && request.Cause != "speech-history" { + worker.history.add(text, request.Role) + } +} + +func (worker *speechWorker) transformText(text string) string { + if worker.textTransform != nil { + return worker.textTransform(text) + } + return text +} + +// Log the text passed to the backend, including each Say All part rather than +// the entire queued batch. A delivery record is an attempt, not audible proof. +func (worker *speechWorker) logDelivery(ctx context.Context, request speechRequest, text string, readAllIndex int) { + if !worker.logger.Enabled(ctx, slog.LevelDebug) { + return + } + if request.Role == "password text" { + text = "[REDACTED]" + } + worker.logger.DebugContext(ctx, "delivering accessible presentation", + "role", request.Role, "cause", request.Cause, "utterance", text, + "append", true, "interrupt_previous", false, + "character", request.Character, "custom_echo", request.CustomEcho, + "read_all_index", readAllIndex) +} diff --git a/internal/app/speech_enable_test.go b/internal/app/speech_enable_test.go new file mode 100644 index 0000000..4c9d460 --- /dev/null +++ b/internal/app/speech_enable_test.go @@ -0,0 +1,62 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +func TestPreferencesEnableAndDisableSpeechDuringSession(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = false + speaker := &fakeSpeaker{spoken: make(chan string, 1)} + speechWorker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + speechWorker.SetEnabled(false) + if err := speechWorker.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer speechWorker.Stop(context.Background()) + updates := 0 + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, + settingsUpdateFunc(func(context.Context, speech.Settings) error { updates++; return nil })) + worker.speechWorker = speechWorker + enabled := settings + enabled.EnableSpeech = true + if err := worker.applyRuntime(context.Background(), enabled); err != nil { + t.Fatal(err) + } + if updates != 1 { + t.Fatalf("enabling speech made %d backend updates, want 1", updates) + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := speechWorker.EnqueueAndWait(ctx, speechRequest{Text: "enabled"}); err != nil { + t.Fatal(err) + } + if got := <-speaker.spoken; got != "enabled" { + t.Fatalf("spoken text = %q", got) + } + if err := worker.applyRuntime(context.Background(), settings); err != nil { + t.Fatal(err) + } + if updates != 1 { + t.Fatal("disabling speech reconnected the backend") + } + if err := speechWorker.EnqueueAndWait(ctx, speechRequest{Text: "disabled"}); !errors.Is(err, context.Canceled) { + t.Fatalf("disabled speech returned %v, want canceled", err) + } + select { + case got := <-speaker.spoken: + t.Fatalf("speech escaped disabled mode: %q", got) + default: + } +} diff --git a/internal/app/speech_history.go b/internal/app/speech_history.go new file mode 100644 index 0000000..7eca66c --- /dev/null +++ b/internal/app/speech_history.go @@ -0,0 +1,105 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + "sync" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +// speechHistory retains the most recent distinct utterances. The history +// window suspends capture so its own feedback never changes the list. +type speechHistory struct { + mu sync.Mutex + items []string + limit int + paused bool + monitor chan string +} + +func newSpeechHistory(limit int) *speechHistory { + if limit < config.MinSpeechHistoryLimit || limit > config.MaxSpeechHistoryLimit { + limit = config.DefaultSpeechHistoryLimit + } + return &speechHistory{limit: limit} +} + +func (h *speechHistory) setLimit(limit int) { + if limit < config.MinSpeechHistoryLimit || limit > config.MaxSpeechHistoryLimit { + return + } + h.mu.Lock() + defer h.mu.Unlock() + h.limit = limit + if len(h.items) > limit { + clear(h.items[limit:]) + h.items = h.items[:limit] + } +} + +func (h *speechHistory) add(text, role string) { + if role == "password text" { + return + } + text = strings.TrimSpace(text) + if text == "" { + return + } + h.mu.Lock() + defer h.mu.Unlock() + if h.monitor != nil { + select { + case h.monitor <- text: + default: + } + } + if h.paused { + return + } + for _, item := range h.items { + if item == text { + return + } + } + h.items = append(h.items, "") + copy(h.items[1:], h.items[:len(h.items)-1]) + h.items[0] = text + if len(h.items) > h.limit { + clear(h.items[h.limit:]) + h.items = h.items[:h.limit] + } +} + +func (h *speechHistory) snapshot() []string { + h.mu.Lock() + defer h.mu.Unlock() + return append([]string(nil), h.items...) +} + +func (h *speechHistory) remove(text string) bool { + h.mu.Lock() + defer h.mu.Unlock() + for i, item := range h.items { + if item == text { + h.items = append(h.items[:i], h.items[i+1:]...) + return true + } + } + return false +} + +func (h *speechHistory) setPaused(paused bool) { + h.mu.Lock() + h.paused = paused + h.mu.Unlock() +} + +func (h *speechHistory) setMonitor(ch chan string) { + h.mu.Lock() + h.monitor = ch + h.mu.Unlock() +} diff --git a/internal/app/speech_history_test.go b/internal/app/speech_history_test.go new file mode 100644 index 0000000..d4eb637 --- /dev/null +++ b/internal/app/speech_history_test.go @@ -0,0 +1,230 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "log/slog" + "path/filepath" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" +) + +func TestSpeechHistoryRetentionPauseAndRemoval(t *testing.T) { + h := newSpeechHistory(config.DefaultSpeechHistoryLimit) + h.add(" first ", "system") + h.add("first", "system") + h.add("secret", "password text") + for i := 0; i < 50; i++ { + h.add(fmt.Sprintf("item %d", i), "label") + } + items := h.snapshot() + if len(items) != 50 || items[0] != "item 49" || items[49] != "item 0" { + t.Fatalf("unexpected retained history: %v", items) + } + h.setPaused(true) + h.add("window feedback", "system") + if len(h.snapshot()) != 50 { + t.Fatal("paused speech changed history") + } + h.setPaused(false) + if !h.remove("item 20") || h.remove("item 20") { + t.Fatal("removal result is wrong") + } + h.add("item 20", "label") + if got := h.snapshot()[0]; got != "item 20" { + t.Fatalf("re-added item = %q", got) + } +} + +func TestSpeechHistoryLimitTrimsOldestAndCanGrow(t *testing.T) { + h := newSpeechHistory(1000) + for i := range 1001 { + h.add(fmt.Sprintf("item %d", i), "label") + } + if items := h.snapshot(); len(items) != 1000 || items[0] != "item 1000" || items[999] != "item 1" { + t.Fatalf("maximum history retention = %d items", len(items)) + } + h.setLimit(10) + items := h.snapshot() + if len(items) != 10 || items[0] != "item 1000" || items[9] != "item 991" { + t.Fatalf("trimmed history = %v", items) + } + h.setLimit(1000) + h.add("new item", "label") + if items = h.snapshot(); len(items) != 11 || items[0] != "new item" { + t.Fatalf("grown history = %v", items) + } +} + +func TestPreferencesApplyHistoryLimitLiveAndPersisted(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + history := newSpeechHistory(settings.SpeechHistoryLimit) + for i := range 20 { + history.add(fmt.Sprintf("item %d", i), "label") + } + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + worker.history = history + refreshes := 0 + worker.refreshHistory = func() { refreshes++ } + values := preferences.FromSettings(settings) + values.SpeechHistoryLimit = 10 + response := worker.apply(context.Background(), preferences.Request{Values: values, Save: true}) + if !response.Accepted || len(history.snapshot()) != 10 || refreshes != 1 { + t.Fatalf("limit was not applied immediately: response=%+v, count=%d, refreshes=%d", response, len(history.snapshot()), refreshes) + } + loaded, err := config.Load(settings.Path) + if err != nil || loaded.SpeechHistoryLimit != 10 { + t.Fatalf("saved history limit = %d, error %v", loaded.SpeechHistoryLimit, err) + } + for _, invalid := range []int{0, 1001} { + values.SpeechHistoryLimit = invalid + response = worker.apply(context.Background(), preferences.Request{Values: values}) + if response.Accepted || len(history.snapshot()) != 10 || refreshes != 1 { + t.Fatalf("invalid limit %d changed history: response=%+v", invalid, response) + } + } +} + +func TestSpeechHistoryMonitorIncludesDuplicatesWhileCapturePaused(t *testing.T) { + h := newSpeechHistory(config.DefaultSpeechHistoryLimit) + stream := make(chan string, 3) + h.setMonitor(stream) + h.setPaused(true) + h.add(" repeated ", "system") + h.add("repeated", "system") + h.add("private", "password text") + for i := 0; i < 2; i++ { + if got := <-stream; got != "repeated" { + t.Fatalf("monitor line = %q", got) + } + } + if len(stream) != 0 || len(h.snapshot()) != 0 { + t.Fatal("monitor leaked a password or captured paused speech") + } +} + +func TestSpeechDeliveryRecordsHistory(t *testing.T) { + speaker := &fakeSpeaker{spoken: make(chan string, 4)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.history = newSpeechHistory(config.DefaultSpeechHistoryLimit) + for _, request := range []speechRequest{ + {Text: "Delivered text", Role: "label"}, + {Text: "private text", Role: "password text"}, + {Text: "History row spoken after the window closes", Role: "table cell", ExcludeFromHistory: true}, + {Text: "Copied to clipboard.", Role: "system", Cause: "speech-history"}, + } { + if err := worker.deliver(context.Background(), request); err != nil { + t.Fatal(err) + } + } + items := worker.history.snapshot() + if len(items) != 1 || items[0] != "Delivered text" { + t.Fatalf("delivery history = %v", items) + } +} + +func TestSpeechHistoryWindowEventsDoNotEnterHistory(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3), requests: make(chan speechRequest, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + + historyWindow := atspi.NewObjectID(":1.73", "/history") + history := atspi.NewSnapshot(historyWindow.Path, speechHistoryWindowTitle, "frame", "", "") + history.BusName = historyWindow.BusName + activated := atspi.NewEvent(atspi.WindowActivatedEvent, history) + activated.Window = historyWindow + activated.WindowTitle = speechHistoryWindowTitle + adapter.events <- activated + + row := atspi.NewSnapshot("/history/row", "Previously spoken text", "table cell", "", "") + row.BusName = historyWindow.BusName + row.Focused = true + focused := atspi.NewEvent(atspi.FocusedStateEvent, row) + focused.Window = historyWindow + focused.Detail1 = 1 + adapter.events <- focused + + otherWindow := atspi.NewObjectID(":1.80", "/other") + other := atspi.NewSnapshot(otherWindow.Path, "Other window", "frame", "", "") + other.BusName = otherWindow.BusName + otherActivated := atspi.NewEvent(atspi.WindowActivatedEvent, other) + otherActivated.Window = otherWindow + otherActivated.WindowTitle = "Other window" + adapter.events <- otherActivated + + for index, excluded := range []bool{true, true, false} { + select { + case request := <-speech.requests: + if request.ExcludeFromHistory != excluded { + t.Fatalf("request %d (%q) excludes history = %t, want %t", index, request.Text, request.ExcludeFromHistory, excluded) + } + if index == 1 { + speaker := &spellingTestSpeaker{} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.textTransform = func(text string) string { + return pronunciationSpeechText(text, []config.PronunciationEntry{{Word: "Previously", Replacement: "Changed"}}) + } + if err := worker.deliver(ctx, request); err != nil { + t.Fatal(err) + } + if got := strings.Join(speaker.parts, " "); !strings.Contains(got, "Previously spoken text") { + t.Fatalf("history row changed during delivery: %q", got) + } + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for request %d", index) + } + } +} + +func TestRunRoutesSpeechHistoryCommands(t *testing.T) { + settings := config.DefaultSettings() + settings.EnableSpeech = false + settings.EnableSound = false + commands := &fakeCommands{commands: make(chan input.CommandEvent, 3)} + called := make(chan input.Command, 2) + done := make(chan error, 1) + go func() { + done <- Run(context.Background(), Options{ + Logger: slog.New(slog.DiscardHandler), Settings: &settings, + newCommands: func() commandListener { return commands }, + newAdapter: func() Adapter { return &fakeAdapter{events: make(chan atspi.Event)} }, + newInput: func() InputListener { return &fakeInputListener{events: make(chan input.Event)} }, + onSpeechHistory: func() { called <- input.ShowSpeechHistory }, + onSpeechMonitor: func() { called <- input.ToggleSpeechMonitor }, + }) + }() + for _, command := range []input.Command{input.ShowSpeechHistory, input.ToggleSpeechMonitor} { + commands.commands <- input.CommandEvent{Command: command} + select { + case got := <-called: + if got != command { + t.Fatalf("routed %s, want %s", got, command) + } + case <-time.After(time.Second): + t.Fatalf("command %s was not routed", command) + } + } + commands.commands <- input.CommandEvent{Command: input.Quit} + select { + case err := <-done: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("quit was not handled") + } +} diff --git a/internal/app/speech_history_window.go b/internal/app/speech_history_window.go new file mode 100644 index 0000000..75f37ff --- /dev/null +++ b/internal/app/speech_history_window.go @@ -0,0 +1,261 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "context" + "encoding/json" + "io" + "log/slog" + "os" + "os/exec" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/platform/session" + "git.stormux.org/storm/cthulhu/internal/speechhistoryui" +) + +const speechHistoryWindowTitle = "Speech History - Cthulhu" + +type speechHistoryWindows struct { + logger *slog.Logger + history *speechHistory + speech speechEnqueuer + gate *focusGate + open chan struct{} + refresh chan struct{} + toggle chan struct{} + done chan struct{} + cancel context.CancelFunc + once sync.Once +} + +func newSpeechHistoryWindows(logger *slog.Logger, history *speechHistory, speech speechEnqueuer, gate *focusGate) *speechHistoryWindows { + return &speechHistoryWindows{logger: logger, history: history, speech: speech, gate: gate, + open: make(chan struct{}, 1), refresh: make(chan struct{}, 1), toggle: make(chan struct{}, 1), done: make(chan struct{})} +} +func (w *speechHistoryWindows) Refresh() { + select { + case w.refresh <- struct{}{}: + default: + } +} +func (w *speechHistoryWindows) Open() { + select { + case w.open <- struct{}{}: + default: + } +} +func (w *speechHistoryWindows) ToggleMonitor() { + select { + case w.toggle <- struct{}{}: + default: + } +} +func (w *speechHistoryWindows) Start(ctx context.Context) error { + ctx, w.cancel = context.WithCancel(ctx) + go w.run(ctx) + return nil +} +func (w *speechHistoryWindows) Stop(ctx context.Context) error { + w.once.Do(func() { + if w.cancel != nil { + w.cancel() + } + }) + select { + case <-w.done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} +func (w *speechHistoryWindows) announce(text string) { + if w.gate != nil && (w.gate.Locked() || w.gate.Suspended()) { + return + } + w.speech.Enqueue(speechRequest{Text: text, Role: "system", Cause: "speech-history"}) +} +func (w *speechHistoryWindows) run(ctx context.Context) { + defer close(w.done) + var historyUpdates, monitorUpdates chan speechhistoryui.Message + var historyDone, monitorDone chan struct{} + var stopHistory, stopMonitor context.CancelFunc + defer func() { + if stopHistory != nil { + stopHistory() + } + if stopMonitor != nil { + stopMonitor() + } + if historyDone != nil { + <-historyDone + } + if monitorDone != nil { + <-monitorDone + } + w.history.setPaused(false) + w.history.setMonitor(nil) + }() + for { + select { + case <-ctx.Done(): + return + case <-w.open: + if historyUpdates != nil { + select { + case historyUpdates <- speechhistoryui.Message{Present: true}: + default: + } + continue + } + childCtx, cancel := context.WithCancel(ctx) + stopHistory = cancel + historyUpdates = make(chan speechhistoryui.Message, 4) + historyDone = make(chan struct{}) + w.history.setPaused(true) + go func() { + defer close(historyDone) + if err := w.window(childCtx, "history", historyUpdates, nil); err != nil && childCtx.Err() == nil { + w.logger.Error("speech history window", "error", err) + } + }() + case <-w.refresh: + if historyUpdates != nil { + update := speechhistoryui.Message{Items: append([]string{}, w.history.snapshot()...)} + select { + case historyUpdates <- update: + case <-ctx.Done(): + return + } + } + case <-historyDone: + historyUpdates, historyDone = nil, nil + stopHistory = nil + w.history.setPaused(false) + case <-w.toggle: + if monitorUpdates != nil { + stopMonitor() + w.announce("Speech monitor disabled.") + continue + } + childCtx, cancel := context.WithCancel(ctx) + stopMonitor = cancel + monitorUpdates = make(chan speechhistoryui.Message, 128) + monitorDone = make(chan struct{}) + stream := make(chan string, 128) + w.history.setMonitor(stream) + go func() { + defer close(monitorDone) + if err := w.window(childCtx, "monitor", monitorUpdates, stream); err != nil && childCtx.Err() == nil { + w.logger.Error("speech monitor window", "error", err) + } + }() + w.announce("Speech monitor enabled.") + case <-monitorDone: + monitorUpdates, monitorDone = nil, nil + stopMonitor = nil + w.history.setMonitor(nil) + } + } +} + +func (w *speechHistoryWindows) window(ctx context.Context, mode string, updates <-chan speechhistoryui.Message, stream <-chan string) error { + executable, err := os.Executable() + if err != nil { + return err + } + childCtx, stop := context.WithCancel(ctx) + defer stop() + command := exec.CommandContext(childCtx, executable, "--speech-history-ui") + command.Env = session.GTKEnvironment() + command.WaitDelay = time.Second + in, err := command.StdinPipe() + if err != nil { + return err + } + out, err := command.StdoutPipe() + if err != nil { + in.Close() + return err + } + command.Stderr = os.Stderr + if err := command.Start(); err != nil { + in.Close() + out.Close() + return err + } + defer func() { stop(); in.Close(); out.Close(); _ = command.Wait() }() + encoder := json.NewEncoder(in) + initial := speechhistoryui.Message{Mode: mode} + if mode == "history" { + initial.Items = append([]string{}, w.history.snapshot()...) + } + if err := encoder.Encode(initial); err != nil { + return err + } + requests := make(chan speechhistoryui.Request, 1) + readDone := make(chan error, 1) + go func() { + scanner := bufio.NewScanner(out) + scanner.Buffer(make([]byte, 4096), 1024*1024) + for scanner.Scan() { + var request speechhistoryui.Request + if err := json.Unmarshal(scanner.Bytes(), &request); err != nil { + readDone <- err + return + } + select { + case requests <- request: + case <-childCtx.Done(): + return + } + } + readDone <- scanner.Err() + }() + for { + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-readDone: + if err == nil || err == io.EOF { + return nil + } + return err + case update := <-updates: + if err := encoder.Encode(update); err != nil { + return err + } + case text := <-stream: + if text != "" { + if err := encoder.Encode(speechhistoryui.Message{Append: text}); err != nil { + return err + } + } + case request := <-requests: + switch request.Action { + case "copy": + w.announce("Copied to clipboard.") + case "empty": + w.announce("No speech history item selected.") + case "remove": + if request.Selection == "" { + w.announce("No speech history item selected.") + break + } + if w.history.remove(request.Selection) { + w.announce("Removed from history.") + } else { + w.announce("Item not found in history.") + } + if err := encoder.Encode(speechhistoryui.Message{Items: append([]string{}, w.history.snapshot()...), Selected: 0}); err != nil { + return err + } + } + } + } +} diff --git a/internal/app/speech_interrupt.go b/internal/app/speech_interrupt.go new file mode 100644 index 0000000..96d4586 --- /dev/null +++ b/internal/app/speech_interrupt.go @@ -0,0 +1,207 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" +) + +// Interrupt is for explicit user actions, never automatic presentation. +// It drops retained requests and wakes the owned cancellation worker. +// It must never perform backend I/O in the caller's event loop. +func (worker *speechWorker) Interrupt() { + worker.InterruptForUser() +} + +// The preferences worker changes speech availability after the backend has +// accepted a new configuration. Disabling also retires pending and active +// utterances before the new setting becomes visible to event producers. +func (worker *speechWorker) SetEnabled(enabled bool) { + worker.mutex.Lock() + defer worker.mutex.Unlock() + if worker.enabled == enabled { + return + } + worker.enabled = enabled + if !enabled { + worker.startupUntil = time.Time{} + worker.interruptLocked() + } +} + +func (worker *speechWorker) interruptLocked() { + if worker.hintCancel != nil { + worker.hintCancel() + } + if worker.uninterruptibleCancel != nil { + worker.uninterruptibleCancel() + } + worker.confirmationID = 0 + if worker.beepCancel != nil { + worker.beepCancel() + } + worker.titleInput.protectRepeats = false + worker.titleWindow = atspi.ObjectID{} + if worker.readAllCancel != nil { + worker.readAllCancel() + worker.readAllCancel = nil + } + if time.Now().Before(worker.startupUntil) { + return + } + if !worker.running { + return + } + completeSpeechRequests(worker.pending, context.Canceled) + worker.pending = nil + worker.generation++ + worker.interrupting = true + + select { + case worker.interrupt <- struct{}{}: + default: + } +} + +func (worker *speechWorker) BeginReadAll(ctx context.Context, timestamp uint32) context.Context { + worker.mutex.Lock() + defer worker.mutex.Unlock() + worker.startupUntil = time.Time{} + if !worker.has_uninterruptible_locked() { + worker.interruptLocked() + } else if worker.readAllCancel != nil { + worker.readAllCancel() + } + readContext, cancel := context.WithCancel(ctx) + worker.readAllCancel = cancel + worker.readAllTimestamp = timestamp + return readContext +} + +func (worker *speechWorker) InterruptForInput(event input.Event) bool { + worker.mutex.Lock() + defer worker.mutex.Unlock() + if event.Timestamp != 0 && worker.commandTimestamp != 0 && int32(event.Timestamp-worker.commandTimestamp) <= 0 { + return false + } + // XRecord and command grabs arrive on separate goroutines. A delayed + // copy of the initiating chord must not cancel the reading it just began. + if worker.readAllCancel != nil && event.Timestamp != 0 && worker.readAllTimestamp != 0 && int32(event.Timestamp-worker.readAllTimestamp) <= 0 { + return false + } + if worker.readAllCancel == nil && worker.titleInput.preserves(event) { + worker.logger.Debug("preserved title speech during held-key repeat", "input_timestamp", event.Timestamp, + "input_keycode", event.Keycode) + return false + } + if event.Timestamp != 0 { + worker.lastInputTimestamp = event.Timestamp + } + if worker.has_uninterruptible_locked() { + return false + } + worker.startupUntil = time.Time{} + worker.interruptLocked() + return true +} + +// ProtectCommand ignores delayed copies of input which already dispatched a +// command. A newly dispatched command interrupts existing speech, +// even when its XRecord input has not arrived yet. +func (worker *speechWorker) ProtectCommand(timestamp uint32) { + worker.mutex.Lock() + defer worker.mutex.Unlock() + if timestamp != 0 && worker.commandTimestamp != 0 && int32(timestamp-worker.commandTimestamp) <= 0 { + return + } + if timestamp != 0 { + worker.commandTimestamp = timestamp + } + if !worker.has_uninterruptible_locked() { + worker.startupUntil = time.Time{} + worker.interruptLocked() + } +} + +// Startup announcements need a brief window in which automatic focus events +// append instead of replacing them. A real key press ends that protection. +func (worker *speechWorker) EnqueueStartup(request speechRequest) { + worker.mutex.Lock() + worker.startupUntil = time.Now().Add(3 * time.Second) + worker.mutex.Unlock() + worker.Enqueue(request) +} + +func (worker *speechWorker) InterruptForUser() { + worker.mutex.Lock() + defer worker.mutex.Unlock() + if worker.has_uninterruptible_locked() { + return + } + worker.startupUntil = time.Time{} + worker.interruptLocked() +} + +func (worker *speechWorker) cancelActiveSpeech(ctx context.Context) { + defer close(worker.cancelDone) + for { + select { + case <-ctx.Done(): + return + case <-worker.interrupt: + } + worker.mutex.Lock() + select { + case <-worker.interrupt: + default: + } + generation := worker.generation + activeDone := worker.activeDone + worker.mutex.Unlock() + worker.cancelSpeech(ctx) + if activeDone != nil { + select { + case <-ctx.Done(): + return + case <-activeDone: + } + // SPEAK may have been accepted after the first CANCEL. Keep new + // requests behind the barrier until that in-flight call is settled. + worker.cancelSpeech(ctx) + } + worker.mutex.Lock() + if generation == worker.generation { + worker.interrupting = false + } + worker.mutex.Unlock() + select { + case worker.wake <- struct{}{}: + default: + } + } +} + +func (worker *speechWorker) cancelSpeech(ctx context.Context) { + if err := worker.speaker.Cancel(ctx); err != nil && ctx.Err() == nil { + worker.logger.Warn("interrupt speech", "error", err) + } +} diff --git a/internal/app/speech_key_echo_test.go b/internal/app/speech_key_echo_test.go new file mode 100644 index 0000000..c130ca4 --- /dev/null +++ b/internal/app/speech_key_echo_test.go @@ -0,0 +1,84 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +type keyEchoCompletionSpeaker struct{ controlledSpeaker } + +func (speaker *keyEchoCompletionSpeaker) SpeakEcho(ctx context.Context, text string) error { + return speaker.call(ctx, "queued:echo:"+text) +} + +func (speaker *keyEchoCompletionSpeaker) SpeakVoiceAndWait(ctx context.Context, text, voice string, _ func()) error { + return speaker.call(ctx, "completed:"+voice+":"+text) +} + +func TestSpeechWorkerKeyEchoCompletesBeforeCaretSpeech(t *testing.T) { + for _, custom := range []bool{false, true} { + t.Run(fmt.Sprint(custom), func(t *testing.T) { + speaker := &keyEchoCompletionSpeaker{controlledSpeaker{calls: make(chan speechCall, 8)}} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + worker.Enqueue(speechRequest{Text: "right", Role: "key", Cause: "key-echo", CustomEcho: custom}) + voice := "" + if custom { + voice = "echo" + } + echo := expectSpeechCall(t, &speaker.controlledSpeaker, "completed:"+voice+":right") + worker.Enqueue(speechRequest{Text: "h", Role: "entry", Cause: "object:text-caret-moved", Character: true}) + select { + case call := <-speaker.calls: + t.Fatalf("caret output overtook key echo completion: %s", call.text) + default: + } + close(echo.done) + close(expectSpeechCall(t, &speaker.controlledSpeaker, "h").done) + }) + } +} + +func TestSpeechWorkerKeyEchoWaitStillAllowsInputInterruption(t *testing.T) { + speaker := &keyEchoCompletionSpeaker{controlledSpeaker{calls: make(chan speechCall, 8)}} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + worker.Enqueue(speechRequest{Text: "right", Role: "key", Cause: "key-echo", CustomEcho: true}) + echo := expectSpeechCall(t, &speaker.controlledSpeaker, "completed:echo:right") + worker.Enqueue(speechRequest{Text: "stale character", Cause: "object:text-caret-moved"}) + if !worker.InterruptForInput(input.Event{Pressed: true, Name: "Left", Timestamp: 100}) { + t.Fatal("new input did not interrupt key echo") + } + close(expectSpeechCall(t, &speaker.controlledSpeaker, "cancel").done) + close(echo.done) // Backend reports cancellation of the old echo. + worker.Enqueue(speechRequest{Text: "left", Role: "key", Cause: "key-echo", CustomEcho: true}) + for { + select { + case call := <-speaker.calls: + close(call.done) + if call.text == "completed:echo:left" { + return + } + if call.text != "cancel" { + t.Fatalf("stale speech survived new input: %s", call.text) + } + case <-time.After(time.Second): + t.Fatal("new key echo did not resume after interruption") + } + } +} diff --git a/internal/app/speech_mode.go b/internal/app/speech_mode.go new file mode 100644 index 0000000..39e6268 --- /dev/null +++ b/internal/app/speech_mode.go @@ -0,0 +1,89 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "time" +) + +// The zero value preserves normal startup and the saved voice configuration. +// Modes last for this run only; they never alter enableSpeech or profiles. +type speechMode uint8 + +const ( + speechModeSpeech speechMode = iota + speechModeBeeps + speechModeOff +) + +func (mode speechMode) announcement() string { + switch mode { + case speechModeBeeps: + return "Speech Mode Beeps" + case speechModeOff: + return "Speech off" + default: + return "Speech Mode Speech" + } +} + +func (worker *speechWorker) cycle_speech_mode() speechMode { + worker.mutex.Lock() + defer worker.mutex.Unlock() + worker.mode = (worker.mode + 1) % 3 + worker.startupUntil = time.Time{} + worker.interruptLocked() + worker.logger.Debug("speech mode changed", "mode", worker.mode.announcement()) + return worker.mode +} + +// Capture mode and beep cancellation together so a concurrent mode change or +// key press cannot leave a beep running behind its interruption barrier. +func (worker *speechWorker) deliver_mode(ctx context.Context, request speechRequest) (bool, error) { + worker.mutex.Lock() + mode := worker.mode + if request.ForceSpeech || mode == speechModeSpeech { + worker.mutex.Unlock() + return false, nil + } + if mode == speechModeOff { + worker.mutex.Unlock() + worker.log_mode_delivery(ctx, request, mode) + return true, nil + } + beepContext, cancelBeep := context.WithCancel(ctx) + worker.beepCancel = cancelBeep + worker.mutex.Unlock() + worker.log_mode_delivery(ctx, request, mode) + defer func() { + cancelBeep() + worker.mutex.Lock() + worker.beepCancel = nil + worker.mutex.Unlock() + }() + if worker.beep == nil { + return true, errors.New("speech beep backend unavailable") + } + return true, worker.beep(beepContext) +} + +func (worker *speechWorker) log_mode_delivery(ctx context.Context, request speechRequest, mode speechMode) { + // Say All depends on synth completion. In beeps/off, do not run those + // callbacks and race the reading cursor to the end of the document. + text := request.Text + if len(request.ReadAll) != 0 { + text = request.ReadAll[0].Text + } + if worker.history != nil && !request.ExcludeFromHistory && request.Cause != "speech-history" { + worker.history.add(text, request.Role) + } + if request.Role == "password text" { + text = "[REDACTED]" + } + worker.logger.DebugContext(ctx, "speech replaced by mode", "mode", mode.announcement(), + "cause", request.Cause, "role", request.Role, "utterance", text) +} diff --git a/internal/app/speech_mode_test.go b/internal/app/speech_mode_test.go new file mode 100644 index 0000000..640e63d --- /dev/null +++ b/internal/app/speech_mode_test.go @@ -0,0 +1,182 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +type modeTestSpeaker struct{ spoken chan string } + +func (*modeTestSpeaker) Connect(context.Context) error { return nil } +func (*modeTestSpeaker) Close(context.Context) error { return nil } +func (*modeTestSpeaker) Cancel(context.Context) error { return nil } +func (speaker *modeTestSpeaker) Speak(_ context.Context, text string) error { + speaker.spoken <- text + return nil +} + +type modeTestBraille struct{ messages chan string } + +func (*modeTestBraille) EnqueueFrame(braille.Frame) {} +func (display *modeTestBraille) Flash(text string, _ config.BrailleOptions) bool { + display.messages <- text + return true +} + +func TestSpeechModesCoverEveryDeliveryPath(t *testing.T) { + for _, mode := range []speechMode{speechModeBeeps, speechModeOff} { + t.Run(mode.announcement(), func(t *testing.T) { + speaker := &fakeSpeaker{spoken: make(chan string, 10)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.mode = mode + beeps, began := 0, false + worker.beep = func(context.Context) error { beeps++; return nil } + for _, request := range []speechRequest{ + {Text: "Focused button"}, + {Text: "A", Character: true, PhoneticHint: true}, + {Text: "book", Spelling: []string{"b", "o", "o", "k"}, Character: true}, + {Text: "word", CustomEcho: true}, + {Text: "External message", Cause: "remote-speak"}, + {ReadAll: []readAllPart{{Text: "First line", Began: func() { began = true }}}}, + } { + if err := worker.deliver(context.Background(), request); err != nil { + t.Fatal(err) + } + } + if len(speaker.spoken) != 0 || speaker.canceled || began { + t.Fatal("silent/beeps mode used synth, canceled the mode announcement, or advanced Say All") + } + wantBeeps := 0 + if mode == speechModeBeeps { + wantBeeps = 6 + } + if beeps != wantBeeps { + t.Fatalf("beeps = %d, want %d", beeps, wantBeeps) + } + }) + } +} + +func TestSpeechModeCommandAnnouncesAndPreservesBraille(t *testing.T) { + speaker := &modeTestSpeaker{spoken: make(chan string, 5)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + beeps := make(chan struct{}, 5) + worker.beep = func(context.Context) error { beeps <- struct{}{}; return nil } + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + settings := config.DefaultSettings() + display := &modeTestBraille{messages: make(chan string, 10)} + live := &liveSettings{} + live.Store(settings) + output := outputQueue{speech: worker, braille: display, live: live} + commands := &fakeCommands{commands: make(chan input.CommandEvent)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + done := make(chan error, 1) + go func() { + done <- (commandRuntime{logger: slog.New(slog.DiscardHandler), commands: commands, + focusGate: &focusGate{}, focusChanges: make(chan xorg.FocusState), + speechMessages: worker, speechOutput: output}).run(ctx) + }() + for index, want := range []string{"Speech Mode Beeps", "Speech off", "Speech Mode Speech"} { + commands.commands <- input.CommandEvent{Command: input.CycleSpeechMode} + select { + case got := <-speaker.spoken: + if got != want { + t.Fatalf("announcement = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatal("mode announcement missing") + } + select { + case got := <-display.messages: + if got != want { + t.Fatalf("Braille = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatal("Braille mode announcement missing") + } + result := make(chan error, 1) + output.Enqueue(speechRequest{Text: "Ordinary message", Role: "system", Append: true, result: result}) + select { + case err := <-result: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("ordinary message did not complete") + } + if got := <-display.messages; got != "Ordinary message" { + t.Fatalf("ordinary Braille = %q", got) + } + switch index { + case 0: + if len(beeps) != 1 { + t.Fatalf("beeps = %d, want 1", len(beeps)) + } + case 1: + if len(beeps) != 1 || len(speaker.spoken) != 0 { + t.Fatal("off mode emitted output") + } + case 2: + if got := <-speaker.spoken; got != "Ordinary message" { + t.Fatalf("speech did not resume: %q", got) + } + } + } + cancel() + <-done +} + +func TestSpeechModeSwitchCancelsActiveBeepAndDropsPendingSpeech(t *testing.T) { + speaker := &modeTestSpeaker{spoken: make(chan string, 2)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.mode = speechModeBeeps + started := make(chan struct{}) + worker.beep = func(ctx context.Context) error { close(started); <-ctx.Done(); return ctx.Err() } + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + done := make(chan error, 1) + go func() { done <- worker.EnqueueAndWait(ctx, speechRequest{Text: "Active"}) }() + select { + case <-started: + case <-ctx.Done(): + t.Fatal("beep did not start") + } + worker.Enqueue(speechRequest{Text: "Queued"}) + if got := worker.cycle_speech_mode(); got != speechModeOff { + t.Fatalf("mode = %v", got) + } + select { + case err := <-done: + if !errors.Is(err, context.Canceled) { + t.Fatalf("beep result = %v", err) + } + case <-ctx.Done(): + t.Fatal("mode switch did not cancel beep") + } + if err := worker.EnqueueAndWait(ctx, speechRequest{Text: "Speech off", ForceSpeech: true}); err != nil { + t.Fatal(err) + } + if got := <-speaker.spoken; got != "Speech off" { + t.Fatalf("retained stale speech: %q", got) + } +} diff --git a/internal/app/speech_settings.go b/internal/app/speech_settings.go new file mode 100644 index 0000000..8169f5a --- /dev/null +++ b/internal/app/speech_settings.go @@ -0,0 +1,247 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "math" + "sort" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/speech" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +// Use the settings worker's bounded mailbox, keeping discovery, disk writes, +// and speech connection replacement off the input and focus paths. +func (worker *preferencesWorker) SpeechCommand(command input.Command) { + worker.TrySpeechCommand(command) +} + +func (worker *preferencesWorker) TrySpeechCommand(command input.Command) bool { + select { + case worker.speechCommands <- command: + return true + default: + return false + } +} + +func (worker *preferencesWorker) announceSpeechSetting(message string) { + if worker.announce != nil { + worker.announce(message) + } +} + +func (worker *preferencesWorker) handleSpeechCommand(ctx context.Context, command input.Command) { + if command == input.CycleProgressBarOutput { + worker.cycle_progress_output() + return + } + ctx, cancel := context.WithTimeout(ctx, 6*time.Second) + defer cancel() + if command == input.SaveSpeechSettings { + store, err := config.NewStore(worker.settings.Path) + if err == nil { + if worker.activeApp != "" { + err = store.SaveForApplication(worker.activeApp, worker.settings) + } else { + err = store.Save(worker.settings) + } + } + if err != nil { + worker.logger.Warn("save speech settings", "error", err) + worker.announceSpeechSetting("Speech settings could not be saved") + } else { + worker.announceSpeechSetting("Speech settings saved") + } + return + } + worker.sync_extensions(ctx) + quickSettings := worker.quick_settings() + settingIndex := worker.speechSetting + if worker.quickSettingKey != "" { + settingIndex = 4 + found := false + for index, setting := range quickSettings { + if setting.key == worker.quickSettingKey { + settingIndex = 5 + index + found = true + break + } + } + if !found && (command == input.IncreaseSpeechSetting || command == input.DecreaseSpeechSetting) { + worker.quickSettingKey, worker.speechSetting = "", 4 + worker.announceSpeechSetting("The selected speech setting is no longer available") + return + } + } + switch command { + case input.SelectPreviousSpeechSetting: + settingIndex = max(0, settingIndex-1) + case input.SelectNextSpeechSetting: + settingIndex = min(4+len(quickSettings), settingIndex+1) + } + worker.quickSettingKey = "" + if settingIndex >= 5 { + worker.quickSettingKey = quickSettings[settingIndex-5].key + } else { + worker.speechSetting = settingIndex + } + next := worker.effective_settings(worker.settings) + adjust := command == input.IncreaseSpeechSetting || command == input.DecreaseSpeechSetting + delta := 1 + if command == input.DecreaseSpeechSetting { + delta = -1 + } + if settingIndex >= 5 { + worker.handle_extension_quick(ctx, quickSettings[settingIndex-5], adjust, delta) + return + } + message := "" + switch worker.speechSetting { + case 0, 1, 2: + names := []string{"Rate", "Pitch", "Volume"} + fields := []**float64{&next.DefaultVoice.Rate, &next.DefaultVoice.AveragePitch, &next.DefaultVoice.Gain} + defaults := []float64{50, 5, 9} + limits := []float64{99, 9, 9} + steps := []float64{1, 0.1, 0.1} + field := fields[worker.speechSetting] + value := defaults[worker.speechSetting] + if *field != nil { + value = **field + } + if adjust { + value = math.Round((value+float64(delta)*steps[worker.speechSetting])*10) / 10 + value = math.Max(0, math.Min(limits[worker.speechSetting], value)) + *field = &value + } + message = fmt.Sprintf("%s %g", names[worker.speechSetting], value) + if *field == nil { + message = names[worker.speechSetting] + " server default" + } + case 3, 4: + if next.SpeechServerFactory == "hardwarefactory" { + if worker.speechSetting == 4 { + worker.announceSpeechSetting("Hardware speech has no selectable voices") + return + } + modules := []string{"litetalk", "doubletalk", "tripletalk", "dectalk"} + if adjust { + for index, module := range modules { + if module == next.SpeechOutputModule { + next.SpeechOutputModule = modules[max(0, min(len(modules)-1, index+delta))] + break + } + } + } + message = "Hardware synthesizer " + next.SpeechOutputModule + break + } + if worker.catalog == nil { + catalog, err := worker.discover(ctx, worker.socket) + if err != nil { + worker.announceSpeechSetting("Speech settings unavailable") + return + } + worker.catalog = catalog + } + if worker.speechSetting == 3 { + modules := []string{} + for module := range worker.catalog { + if module != "" { + modules = append(modules, module) + } + } + sort.Strings(modules) + if len(modules) == 0 { + worker.announceSpeechSetting("No speech-dispatcher modules available") + return + } + if adjust { + index := 0 + for i, module := range modules { + if module == next.SpeechOutputModule { + index = i + break + } + } + // An unspecified module is a server default, not a known list position. + if next.SpeechOutputModule != "" { + index = max(0, min(len(modules)-1, index+delta)) + } + next.SpeechOutputModule = modules[index] + next.DefaultVoice.Family = nil + if voices := quickSpeechVoices(next.SpeechOutputModule, worker.catalog[next.SpeechOutputModule]); len(voices) > 0 { + next.DefaultVoice.Family = &config.VoiceFamily{Name: voices[0].Name, Lang: voices[0].Language, Variant: voices[0].Variant} + } + } + name := next.SpeechOutputModule + if name == "" { + name = "server default" + } + message = "Speech-dispatcher module " + name + } else { + voices := quickSpeechVoices(next.SpeechOutputModule, worker.catalog[next.SpeechOutputModule]) + if len(voices) == 0 { + worker.announceSpeechSetting("No speech-dispatcher voices available") + return + } + name := "server default" + if family := next.DefaultVoice.Family; family != nil && family.Name != "" { + name = family.Name + } + if adjust { + index := 0 + for i, voice := range voices { + if voice.Name == name { + index = max(0, min(len(voices)-1, i+delta)) + break + } + } + voice := voices[index] + next.DefaultVoice.Family = &config.VoiceFamily{Name: voice.Name, Lang: voice.Language, Variant: voice.Variant} + name = voice.Name + } + message = "Speech-dispatcher voice " + name + } + } + if adjust { + err := config.Validate(next) + if err == nil { + err = worker.updateSpeech(ctx, next) + } + if err != nil { + worker.logger.Warn("adjust speech setting", "error", err) + worker.catalog = nil + worker.announceSpeechSetting("Speech settings were not applied") + return + } + if worker.speechOverride != nil { + value := tentaclewire.SpeechFromSettings(next) + worker.speechOverride = &value + } else { + worker.settings = next + } + if worker.live != nil { + worker.live.Store(next) + } + } + worker.announceSpeechSetting(message) +} + +// Keep eSpeak NG's language/variant cross product manageable in quick settings. +// Prefer an exact dialect, then a language-only voice if that dialect is absent. +// Unknown languages retain the catalog so the user can still select a voice. +func quickSpeechVoices(module string, voices []speech.Voice) []speech.Voice { + if !strings.Contains(strings.ToLower(module), "espeak-ng") { + return voices + } + return speech.LocaleVoices(voices) +} diff --git a/internal/app/speech_settings_test.go b/internal/app/speech_settings_test.go new file mode 100644 index 0000000..aa96a52 --- /dev/null +++ b/internal/app/speech_settings_test.go @@ -0,0 +1,209 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "errors" + "log/slog" + "path/filepath" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +func TestSpeechShortcutsApplySaveAndFailure(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + rate := 50.0 + settings.DefaultVoice.Rate = &rate + var applied speech.Settings + var updateError error + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(_ context.Context, next speech.Settings) error { + if updateError != nil { + return updateError + } + applied = next + return nil + })) + worker.live = &liveSettings{} + worker.live.Store(settings) + message := "" + worker.announce = func(text string) { message = text } + command := func(c input.Command) { t.Helper(); worker.handleSpeechCommand(context.Background(), c) } + command(input.IncreaseSpeechSetting) + if message != "Rate 51" || applied.Rate == nil || *applied.Rate != 4 || *worker.live.Load().DefaultVoice.Rate != 51 || rate != 50 { + t.Fatalf("rate: message %q, applied %+v, original %g", message, applied, rate) + } + updateError = errors.New("backend unavailable") + command(input.IncreaseSpeechSetting) + if message != "Speech settings were not applied" || *worker.live.Load().DefaultVoice.Rate != 51 { + t.Fatal("failed update changed session") + } + updateError = nil + worker.catalog = speech.Catalog{"": {{Name: "default", Language: "en"}}, "alpha": {{Name: "one", Language: "en"}, {Name: "two", Language: "en"}}, "beta": {{Name: "three", Language: "en"}}} + for _, want := range []string{"Pitch server default", "Volume server default", "Speech-dispatcher module server default"} { + command(input.SelectNextSpeechSetting) + if message != want { + t.Fatalf("got %q, want %q", message, want) + } + } + command(input.IncreaseSpeechSetting) + if applied.OutputModule != "alpha" || applied.SynthesisVoice != "one" { + t.Fatalf("module: %+v", applied) + } + command(input.SelectNextSpeechSetting) + command(input.IncreaseSpeechSetting) + if applied.SynthesisVoice != "two" { + t.Fatalf("voice: %+v", applied) + } + command(input.SelectNextSpeechSetting) + if worker.speechSetting != 4 { + t.Fatal("selector wrapped") + } + command(input.SaveSpeechSettings) + if message != "Speech settings saved" { + t.Fatal(message) + } + store, err := config.NewStore(settings.Path) + if err != nil { + t.Fatal(err) + } + saved, err := store.Load() + if err != nil { + t.Fatal(err) + } + if saved.SpeechOutputModule != "alpha" || saved.DefaultVoice.Family.Name != "two" || *saved.DefaultVoice.Rate != 51 { + t.Fatalf("saved settings did not retain speech choices: %+v", saved.DefaultVoice) + } + worker.settings.Path = t.TempDir() + command(input.SaveSpeechSettings) + if message != "Speech settings could not be saved" { + t.Fatal(message) + } + // A backend failure must not affect later selection or saving. + command(input.SelectPreviousSpeechSetting) + if worker.speechSetting != 3 { + t.Fatal("selector did not recover") + } +} + +func TestSpeechShortcutNumericBounds(t *testing.T) { + for index, maximum := range []float64{99, 9, 9} { + settings := config.DefaultSettings() + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, settingsUpdateFunc(func(context.Context, speech.Settings) error { return nil })) + worker.speechSetting = index + fields := []**float64{&worker.settings.DefaultVoice.Rate, &worker.settings.DefaultVoice.AveragePitch, &worker.settings.DefaultVoice.Gain} + *fields[index] = &maximum + worker.handleSpeechCommand(context.Background(), input.IncreaseSpeechSetting) + if **fields[index] != maximum { + t.Fatal("upper bound exceeded") + } + zero := 0.0 + *fields[index] = &zero + worker.handleSpeechCommand(context.Background(), input.DecreaseSpeechSetting) + if **fields[index] != 0 { + t.Fatal("lower bound exceeded") + } + worker.handleSpeechCommand(context.Background(), input.IncreaseSpeechSetting) + want := 0.1 + if index == 0 { + want = 1 + } + if **fields[index] != want { + t.Fatalf("step %g, want %g", **fields[index], want) + } + } +} + +func TestSpeechShortcutUnavailableDiscovery(t *testing.T) { + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), config.DefaultSettings(), nil) + worker.speechSetting = 3 + worker.discover = func(context.Context, string) (speech.Catalog, error) { return nil, errors.New("offline") } + message := "" + worker.announce = func(text string) { message = text } + worker.handleSpeechCommand(context.Background(), input.IncreaseSpeechSetting) + if message != "Speech settings unavailable" || worker.settings.SpeechOutputModule != "" { + t.Fatal(message) + } +} + +func TestQuickSpeechESpeakLocale(t *testing.T) { + voices := []speech.Voice{ + {Name: "de+max", Language: "de"}, + {Name: "en-us+max", Language: "en-us"}, + {Name: "en-gb", Language: "en-gb"}, + {Name: "en-us", Language: "en-us", Variant: "male"}, + {Name: "en", Language: "en"}, + {Name: "en-us+Storm", Language: "en-us"}, + } + for _, tc := range []struct { + name, all, messages, lang, module string + want []string + }{ + {"exact", "en_US.UTF-8", "de_DE", "en_GB", "espeak-ng", []string{"en-us", "en-us+max", "en-us+Storm"}}, + {"messages", "", "en_US@custom", "de_DE", "espeak-ng", []string{"en-us", "en-us+max", "en-us+Storm"}}, + {"lang", "", "", "en-GB.UTF-8", "espeak-ng", []string{"en-gb"}}, + {"language fallback", "en_AU", "", "", "espeak-ng", []string{"en"}}, + {"C fallback", "C.UTF-8", "", "", "espeak-ng", []string{"en-us", "en-us+max", "en-us+Storm"}}, + {"missing locale", "", "", "", "espeak-ng", []string{"en-us", "en-us+max", "en-us+Storm"}}, + {"unavailable language", "zz_ZZ", "", "", "espeak-ng", []string{"de+max", "en-us+max", "en-gb", "en-us", "en", "en-us+Storm"}}, + {"other module", "en_US", "", "", "other", []string{"de+max", "en-us+max", "en-gb", "en-us", "en", "en-us+Storm"}}, + } { + t.Run(tc.name, func(t *testing.T) { + t.Setenv("LC_ALL", tc.all) + t.Setenv("LC_MESSAGES", tc.messages) + t.Setenv("LANG", tc.lang) + got := quickSpeechVoices(tc.module, voices) + if len(got) != len(tc.want) { + t.Fatalf("voices = %v, want %v", got, tc.want) + } + for i, want := range tc.want { + if got[i].Name != want { + t.Fatalf("voices = %v, want %v", got, tc.want) + } + } + if voices[0].Name != "de+max" || voices[3].Name != "en-us" { + t.Fatal("catalog mutated") + } + }) + } +} + +func TestSpeechShortcutESpeakDefaultAndVariants(t *testing.T) { + t.Setenv("LC_ALL", "en_US.UTF-8") + var applied speech.Settings + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), config.DefaultSettings(), settingsUpdateFunc(func(_ context.Context, next speech.Settings) error { + applied = next + return nil + })) + worker.catalog = speech.Catalog{"espeak-ng": { + {Name: "de", Language: "de"}, + {Name: "en-us+max", Language: "en-us"}, + {Name: "en-us", Language: "en-us"}, + {Name: "fr", Language: "fr"}, + }} + worker.speechSetting = 3 + worker.handleSpeechCommand(context.Background(), input.IncreaseSpeechSetting) + if applied.OutputModule != "espeak-ng" || applied.SynthesisVoice != "en-us" || applied.Language != "en-us" { + t.Fatalf("module switch: %+v", applied) + } + worker.handleSpeechCommand(context.Background(), input.SelectNextSpeechSetting) + for _, tc := range []struct { + command input.Command + want string + }{ + {input.IncreaseSpeechSetting, "en-us+max"}, + {input.IncreaseSpeechSetting, "en-us+max"}, + {input.DecreaseSpeechSetting, "en-us"}, + {input.DecreaseSpeechSetting, "en-us"}, + } { + worker.handleSpeechCommand(context.Background(), tc.command) + if applied.SynthesisVoice != tc.want { + t.Fatalf("voice = %q, want %q", applied.SynthesisVoice, tc.want) + } + } +} diff --git a/internal/app/speech_title_input.go b/internal/app/speech_title_input.go new file mode 100644 index 0000000..0a8874b --- /dev/null +++ b/internal/app/speech_title_input.go @@ -0,0 +1,23 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import "git.stormux.org/storm/cthulhu/internal/input" + +// titleInputPolicy follows the latest accepted presentation, including the +// period after SPEAK returns while the synthesizer is still speaking it. +// Only automatic titles ignore repeats. Normal reading keeps its input policy. +// The speech worker's mutex owns this state. +type titleInputPolicy struct { + protectRepeats bool +} + +func (policy *titleInputPolicy) observe(request speechRequest) { + policy.protectRepeats = request.Cause == "window-title" && request.Text != "" +} + +func (policy *titleInputPolicy) preserves(event input.Event) bool { + return policy.protectRepeats && event.Pressed && !input.ShouldInterruptTitle(event) +} diff --git a/internal/app/speech_title_input_test.go b/internal/app/speech_title_input_test.go new file mode 100644 index 0000000..98d6e92 --- /dev/null +++ b/internal/app/speech_title_input_test.go @@ -0,0 +1,79 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestAutomaticTitleSurvivesMovementRepeatsBeforeAndAfterDelivery(t *testing.T) { + speaker := &fakeSpeaker{spoken: make(chan string, 1)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + worker.running = true + worker.Enqueue(speechRequest{Text: "Game status", Cause: "window-title", Append: true}) + repeat := input.Event{Name: "Up", Pressed: true, Repeat: true, Timestamp: 100} + if worker.InterruptForInput(repeat) || len(worker.pending) != 1 { + t.Fatal("repeat discarded queued title") + } + request, ok := worker.next() + if !ok { + t.Fatal("title missing from queue") + } + if err := worker.deliver(context.Background(), request); err != nil { + t.Fatal(err) + } + if text := <-speaker.spoken; text != "Game status" { + t.Fatalf("speech = %q", text) + } + if worker.InterruptForInput(repeat) || worker.generation != 0 { + t.Fatal("repeat interrupted title after backend accepted it") + } + if !worker.InterruptForInput(input.Event{Name: "Up", Pressed: true, Timestamp: 200}) { + t.Fatal("fresh movement key did not interrupt") + } +} + +func TestAutomaticTitleStillStopsForExplicitInput(t *testing.T) { + for _, event := range []input.Event{ + {Name: "Left", Pressed: true}, + {Name: "Control_L", Pressed: true, Repeat: true}, + {Name: "Control_R", Pressed: true, Repeat: true}, + {Name: "Escape", Pressed: true, Repeat: true}, + } { + t.Run(event.Name, func(t *testing.T) { + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.running = true + worker.Enqueue(speechRequest{Text: "Game status", Cause: "window-title", Append: true}) + if !worker.InterruptForInput(event) || len(worker.pending) != 0 || worker.generation != 1 { + t.Fatal("explicit input did not stop title speech") + } + }) + } +} + +func TestTitleProtectionDoesNotChangeOrdinaryReading(t *testing.T) { + for _, cause := range []string{"focus", "flat-review", "current-time", "key-echo", "read-all"} { + t.Run(cause, func(t *testing.T) { + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.running = true + worker.Enqueue(speechRequest{Text: "Game status", Cause: "window-title", Append: true}) + worker.Enqueue(speechRequest{Text: "Reading", Cause: cause}) + if !worker.InterruptForInput(input.Event{Name: "Up", Pressed: true, Repeat: true}) || len(worker.pending) != 0 { + t.Fatal("title protection leaked into ordinary reading") + } + }) + } + worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + worker.running = true + ctx := worker.BeginReadAll(context.Background(), 100) + worker.Enqueue(speechRequest{Text: "Game status", Cause: "window-title", Append: true}) + if !worker.InterruptForInput(input.Event{Name: "Up", Pressed: true, Repeat: true, Timestamp: 101}) || ctx.Err() != context.Canceled { + t.Fatal("appended title prevented held key from stopping Say All") + } +} diff --git a/internal/app/speech_uninterruptible.go b/internal/app/speech_uninterruptible.go new file mode 100644 index 0000000..7e787c3 --- /dev/null +++ b/internal/app/speech_uninterruptible.go @@ -0,0 +1,55 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "time" +) + +// Bound protection even if the backend never reports completion. The deadline +// starts at admission, covering time spent in the bounded pending queue too. +const uninterruptibleSpeechTimeout = 30 * time.Second + +func (worker *speechWorker) has_uninterruptible_locked() bool { + if worker.uninterruptibleContext != nil && worker.uninterruptibleContext.Err() == nil { + return true + } + for _, request := range worker.pending { + if request.Uninterruptible && request.context != nil && request.context.Err() == nil { + return true + } + } + return false +} + +// Preserve unrelated queued speech when explicitly stopping protected output. +// The existing cancellation barrier prevents CANCEL overtaking it. +func (worker *speechWorker) stop_uninterruptible() { + worker.mutex.Lock() + defer worker.mutex.Unlock() + retained := worker.pending[:0] + for _, request := range worker.pending { + if request.Uninterruptible { + completeSpeechRequest(request, context.Canceled) + } else { + retained = append(retained, request) + } + } + clear(worker.pending[len(retained):]) + worker.pending = retained + if worker.uninterruptibleCancel == nil || !worker.running { + return + } + worker.uninterruptibleCancel() + if worker.beepCancel != nil { + worker.beepCancel() + } + worker.generation++ + worker.interrupting = true + select { + case worker.interrupt <- struct{}{}: + default: + } +} diff --git a/internal/app/speech_worker.go b/internal/app/speech_worker.go new file mode 100644 index 0000000..a57fcb8 --- /dev/null +++ b/internal/app/speech_worker.go @@ -0,0 +1,419 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "errors" + "fmt" + "log/slog" + "strings" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +// speechQueueCapacity bounds work retained while the speech backend is slow. +// Requests remain FIFO. On overflow, the oldest pending request is discarded +// so that current focus is favored, and the loss is reported without content. +const speechQueueCapacity = 64 + +type speechRequest struct { + presentationGeneration *uint64 // Checked under the speech owner mutex. + presentationRevision *uint64 + + Window atspi.ObjectID + IntroducesWindow bool + ReadAll []readAllPart + CustomEcho bool + PhoneticHint bool // Eligible character navigation; gated by input and reading settings. + Character bool + VoiceType string + Line *speechLine + Context []atspi.Snapshot + ResetContext bool // Silently discard browse context outside browse mode. + Spelling []string // One cancellable queue item, with separate letter utterances. + SpellingVoices []string + Sound []sound.Cue + Chunks []string // Presentation pause boundaries; one cancellable queue item. + FallbackChunks []string + Text string + FallbackText string + Role string + Cause string + Append bool + ClipboardTimestamp uint32 + BypassFocusGate bool + ExcludeFromHistory bool + ForceSpeech bool // Only the speech-mode announcement bypasses the mode. + Confirmation bool // Wait for speech completion before automatic output. + Uninterruptible bool // Accepted tentacle message; ordinary input cannot cancel it. + confirmationID uint64 + deliveryGeneration uint64 + context context.Context + cancel context.CancelFunc + result chan error +} + +type readAllPart struct { + Text string + VoiceType string + Line *speechLine + Context []atspi.Snapshot + Began func() +} + +// speechWorker owns the pending queue under mutex. Delivery and cancellation +// have separate goroutines and joins; activeDone and generation form their +// barrier so cancellation cannot overtake newly accepted output. +type speechWorker struct { + logger *slog.Logger + speaker Speaker + history *speechHistory + beep func(context.Context) error + capitalBeep func(context.Context) error + capitalization func() (beep, sayCap bool) + textTransform func(string) string + inputActivity func() input.Activity + reading func() config.ReadingSettings + verbosity func() int + indentation indentationHistory // Owned by the serialized delivery goroutine. + speechContext []atspi.Snapshot // Same owner; replaced on each known navigation context. + indentationCue func(sound.Cue) + + mutex sync.Mutex + enabled bool + mode speechMode + hintCancel context.CancelFunc // Active phonetic delay, owned under mutex. + beepCancel context.CancelFunc + pending []speechRequest + wake chan struct{} + interrupt chan struct{} + runDone chan struct{} + cancelDone chan struct{} + cancel context.CancelFunc + secure bool + started bool + running bool + workerContext context.Context + overflow uint64 + reported uint64 + generation uint64 + interrupting bool + activeDone chan struct{} + startupUntil time.Time + readAllCancel context.CancelFunc + readAllTimestamp uint32 + commandTimestamp uint32 + lastInputTimestamp uint32 + titleWindow atspi.ObjectID + titleInput titleInputPolicy + confirmationID uint64 // Owned under mutex; reset on completion or user interruption. + confirmationSerial uint64 + + presentationRevision uint64 + uninterruptibleContext context.Context + uninterruptibleCancel context.CancelFunc +} + +func newSpeechWorker(logger *slog.Logger, speaker Speaker) *speechWorker { + return &speechWorker{ + logger: logger, + speaker: speaker, + enabled: true, + wake: make(chan struct{}, 1), + interrupt: make(chan struct{}, 1), + } +} + +func (worker *speechWorker) Start(ctx context.Context) error { + worker.mutex.Lock() + defer worker.mutex.Unlock() + if worker.started { + return errors.New("speech worker already started") + } + workerContext, cancel := context.WithCancel(ctx) + worker.workerContext = workerContext + worker.cancel = cancel + worker.started = true + worker.running = true + worker.runDone = make(chan struct{}) + worker.cancelDone = make(chan struct{}) + go worker.run(workerContext) + go worker.cancelActiveSpeech(workerContext) + return nil +} + +func (worker *speechWorker) Enqueue(request speechRequest) { + worker.mutex.Lock() + if request.presentationGeneration != nil && (*request.presentationGeneration != worker.generation || + request.presentationRevision == nil || *request.presentationRevision != worker.presentationRevision) { + worker.mutex.Unlock() + completeSpeechRequest(request, context.Canceled) + return + } + if !worker.enabled { + worker.mutex.Unlock() + completeSpeechRequest(request, context.Canceled) + return + } + // Equal millisecond timestamps can belong to the copy key and its result. + if request.ClipboardTimestamp != 0 && worker.lastInputTimestamp != 0 && int32(request.ClipboardTimestamp-worker.lastInputTimestamp) < 0 { + worker.mutex.Unlock() + completeSpeechRequest(request, context.Canceled) + return + } + if worker.secure && !strings.HasPrefix(request.Cause, "remote-") { + worker.mutex.Unlock() + completeSpeechRequest(request, context.Canceled) + return + } + if request.context != nil && request.context.Err() != nil { + worker.mutex.Unlock() + completeSpeechRequest(request, request.context.Err()) + return + } + if !worker.running { + worker.mutex.Unlock() + completeSpeechRequest(request, errors.New("speech worker is not running")) + return + } + request.Append = true + // A Tentacle ticket gates admission, not the lifetime of accepted speech. + // Passive focus changes can retire the ticket while this output finishes. + // Fresh input still cancels through the worker generation/barrier. + if request.presentationGeneration != nil && !request.Uninterruptible { + request.context = worker.workerContext + } + if request.Confirmation { + worker.confirmationSerial++ + request.confirmationID = worker.confirmationSerial + worker.confirmationID = request.confirmationID + } else if worker.confirmationID != 0 { + request.Append = true + } + if worker.has_uninterruptible_locked() { + request.Append = true + } + // Pair a title with the next announcement from its window. User input + // and explicit interruption retire this pairing; another window starts + // normally. This queues the continuation without protecting the title + // against navigation or estimating how long it will take to speak. + if worker.titleWindow.Valid() && request.Window == worker.titleWindow && !request.IntroducesWindow { + request.Append = true + } + worker.titleWindow = atspi.ObjectID{} + if request.IntroducesWindow && request.Text != "" { + worker.titleWindow = request.Window + } + if time.Now().Before(worker.startupUntil) && request.Cause != "startup" { + request.Append = true + } + if len(worker.pending) == speechQueueCapacity { + if worker.pending[0].confirmationID == worker.confirmationID { + worker.confirmationID = 0 + } + completeSpeechRequest(worker.pending[0], errors.New("speech request dropped after queue overflow")) + copy(worker.pending, worker.pending[1:]) + worker.pending = worker.pending[:speechQueueCapacity-1] + worker.overflow++ + } + worker.titleInput.observe(request) + worker.presentationRevision++ + worker.pending = append(worker.pending, request) + worker.mutex.Unlock() + + select { + case worker.wake <- struct{}{}: + default: + } +} + +func (worker *speechWorker) EnqueueAndWait(ctx context.Context, request speechRequest) error { + worker.mutex.Lock() + if worker.running { + requestContext, cancelRequest := context.WithCancel(worker.workerContext) + request.context = requestContext + request.cancel = cancelRequest + } + worker.mutex.Unlock() + + request.result = make(chan error, 1) + worker.Enqueue(request) + stopCallerWatch := context.AfterFunc(ctx, func() { + if request.cancel != nil { + request.cancel() + } + }) + select { + case err := <-request.result: + if request.cancel != nil { + request.cancel() + } + stopCallerWatch() + return err + case <-ctx.Done(): + if request.cancel != nil { + request.cancel() + } + stopCallerWatch() + return ctx.Err() + } +} + +func (worker *speechWorker) Stop(ctx context.Context) error { + worker.mutex.Lock() + if !worker.started { + worker.mutex.Unlock() + return nil + } + worker.running = false + worker.confirmationID = 0 + if worker.uninterruptibleCancel != nil { + worker.uninterruptibleCancel() + } + if worker.readAllCancel != nil { + worker.readAllCancel() + worker.readAllCancel = nil + } + completeSpeechRequests(worker.pending, context.Canceled) + worker.pending = nil + cancel := worker.cancel + runDone := worker.runDone + cancelDone := worker.cancelDone + worker.mutex.Unlock() + + cancel() + for _, done := range []chan struct{}{runDone, cancelDone} { + select { + case <-done: + case <-ctx.Done(): + worker.reportOverflow() + return fmt.Errorf("wait for speech worker: %w", ctx.Err()) + } + } + worker.reportOverflow() + return nil +} + +func (worker *speechWorker) run(ctx context.Context) { + defer close(worker.runDone) + defer func() { + worker.mutex.Lock() + worker.pending = nil + worker.running = false + worker.mutex.Unlock() + }() + + for { + select { + case <-ctx.Done(): + return + case <-worker.wake: + } + worker.reportOverflow() + + for { + if ctx.Err() != nil { + return + } + request, ok := worker.next() + if !ok { + break + } + deliveryContext := ctx + if request.context != nil { + deliveryContext = request.context + } + err := worker.deliver(deliveryContext, request) + completeSpeechRequest(request, err) + worker.mutex.Lock() + worker.uninterruptibleContext, worker.uninterruptibleCancel = nil, nil + if request.confirmationID == worker.confirmationID { + worker.confirmationID = 0 + } + close(worker.activeDone) + worker.activeDone = nil + worker.mutex.Unlock() + if err != nil { + if ctx.Err() != nil { + return + } + worker.logger.Error("deliver accessible presentation", "role", request.Role, "error", err) + } + } + } +} + +func completeSpeechRequests(requests []speechRequest, err error) { + for _, request := range requests { + completeSpeechRequest(request, err) + } +} + +func completeSpeechRequest(request speechRequest, err error) { + if request.Uninterruptible && request.cancel != nil { + request.cancel() + } + if request.result == nil { + return + } + select { + case request.result <- err: + default: + } +} + +func (worker *speechWorker) reportOverflow() { + worker.mutex.Lock() + if worker.overflow == worker.reported { + worker.mutex.Unlock() + return + } + dropped := worker.overflow - worker.reported + worker.reported = worker.overflow + total := worker.overflow + worker.mutex.Unlock() + worker.logger.Warn( + "speech queue overflow", + "dropped_requests", dropped, + "total_dropped_requests", total, + ) +} + +func (worker *speechWorker) next() (speechRequest, bool) { + worker.mutex.Lock() + defer worker.mutex.Unlock() + if !worker.running || worker.interrupting || len(worker.pending) == 0 { + return speechRequest{}, false + } + worker.activeDone = make(chan struct{}) + request := worker.pending[0] + if request.Uninterruptible { + worker.uninterruptibleContext, worker.uninterruptibleCancel = request.context, request.cancel + } + request.deliveryGeneration = worker.generation + copy(worker.pending, worker.pending[1:]) + worker.pending[len(worker.pending)-1] = speechRequest{} + worker.pending = worker.pending[:len(worker.pending)-1] + return request, true +} diff --git a/internal/app/speech_worker_test.go b/internal/app/speech_worker_test.go new file mode 100644 index 0000000..f8d080a --- /dev/null +++ b/internal/app/speech_worker_test.go @@ -0,0 +1,410 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "bytes" + "context" + "errors" + "fmt" + "log/slog" + "strings" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/logging" +) + +type blockingSpeaker struct { + started chan struct{} + once sync.Once +} + +func (speaker *blockingSpeaker) Connect(context.Context) error { return nil } +func (speaker *blockingSpeaker) Cancel(context.Context) error { return nil } +func (speaker *blockingSpeaker) Close(context.Context) error { return nil } + +func (speaker *blockingSpeaker) Speak(ctx context.Context, _ string) error { + speaker.once.Do(func() { close(speaker.started) }) + <-ctx.Done() + return ctx.Err() +} + +func TestSpeechWorkerDeliversInOrder(t *testing.T) { + speaker := &fakeSpeaker{spoken: make(chan string, 2)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatalf("Start: %v", err) + } + + worker.Enqueue(speechRequest{Text: "First", Role: "label"}) + worker.Enqueue(speechRequest{Text: "Second", Role: "button"}) + for _, want := range []string{"First", "Second"} { + select { + case got := <-speaker.spoken: + if got != want { + t.Fatalf("spoken text = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for %q", want) + } + } + + if err := worker.Stop(context.Background()); err != nil { + t.Fatalf("Stop: %v", err) + } +} + +func TestStartupSpeechSurvivesAutomaticFocusInterruption(t *testing.T) { + speaker := &blockingSpeaker{started: make(chan struct{})} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.EnqueueStartup(speechRequest{Text: "Welcome", Cause: "startup"}) + select { + case <-speaker.started: + case <-time.After(time.Second): + t.Fatal("startup speech did not begin") + } + worker.Enqueue(speechRequest{Text: "Focused control", Cause: "focus:"}) + worker.mutex.Lock() + retained := len(worker.pending) == 1 && worker.pending[0].Text == "Focused control" && worker.pending[0].Append + worker.mutex.Unlock() + if !retained { + t.Fatal("automatic focus did not append after protected startup speech") + } + worker.InterruptForUser() + worker.mutex.Lock() + cleared := len(worker.pending) == 0 && worker.startupUntil.IsZero() + worker.mutex.Unlock() + if !cleared { + t.Fatal("user key did not end startup protection and clear queued focus") + } +} + +func TestSpeechWorkerEnqueueAndWaitReportsDelivery(t *testing.T) { + speaker := &fakeSpeaker{spoken: make(chan string, 1)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + + delivered := make(chan error, 1) + go func() { + delivered <- worker.EnqueueAndWait(context.Background(), speechRequest{Text: shutdownMessages[0]}) + }() + if got := <-speaker.spoken; got != shutdownMessages[0] { + t.Fatalf("spoken text = %q, want %q", got, shutdownMessages[0]) + } + if err := <-delivered; err != nil { + t.Fatalf("EnqueueAndWait: %v", err) + } +} + +func TestEnqueueAndWaitTimeoutCancelsDelivery(t *testing.T) { + speaker := &blockingSpeaker{started: make(chan struct{})} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatalf("Start: %v", err) + } + defer worker.Stop(context.Background()) + + requestContext, cancelRequest := context.WithCancel(context.Background()) + defer cancelRequest() + delivered := make(chan error, 1) + go func() { + delivered <- worker.EnqueueAndWait(requestContext, speechRequest{Text: "Blocked"}) + }() + + select { + case <-speaker.started: + case <-time.After(time.Second): + t.Fatal("timed out waiting for speech delivery to start") + } + + worker.mutex.Lock() + activeDone := worker.activeDone + worker.mutex.Unlock() + if activeDone == nil { + t.Fatal("active speech request was not started") + } + cancelRequest() + if err := <-delivered; !errors.Is(err, context.Canceled) { + t.Fatalf("EnqueueAndWait error = %v, want canceled", err) + } + select { + case <-activeDone: + case <-time.After(time.Second): + t.Fatal("timed-out speech request was not canceled") + } +} + +func TestSpeechWorkerBoundsQueueAndKeepsNewestRequests(t *testing.T) { + speaker := &blockingSpeaker{started: make(chan struct{})} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatalf("Start: %v", err) + } + worker.Enqueue(speechRequest{Text: "Blocking"}) + + select { + case <-speaker.started: + case <-time.After(time.Second): + t.Fatal("timed out waiting for blocking speech call") + } + + for index := 0; index < speechQueueCapacity+2; index++ { + worker.Enqueue(speechRequest{Text: fmt.Sprintf("Pending %d", index)}) + } + + worker.mutex.Lock() + if got := len(worker.pending); got != speechQueueCapacity { + worker.mutex.Unlock() + t.Fatalf("pending requests = %d, want %d", got, speechQueueCapacity) + } + if got := worker.overflow; got != 2 { + worker.mutex.Unlock() + t.Fatalf("overflow = %d, want 2", got) + } + oldest := worker.pending[0].Text + worker.mutex.Unlock() + if oldest != "Pending 2" { + t.Fatalf("oldest retained request = %q, want %q", oldest, "Pending 2") + } + + stopContext, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := worker.Stop(stopContext); err != nil { + t.Fatalf("Stop: %v", err) + } + worker.mutex.Lock() + reported := worker.reported + worker.mutex.Unlock() + if reported != 2 { + t.Fatalf("reported overflow = %d, want 2", reported) + } +} + +type speechCall struct { + text string + done chan struct{} +} + +type controlledSpeaker struct { + calls chan speechCall +} + +func (speaker *controlledSpeaker) Connect(context.Context) error { return nil } +func (speaker *controlledSpeaker) Close(context.Context) error { return nil } +func (speaker *controlledSpeaker) Cancel(ctx context.Context) error { + return speaker.call(ctx, "cancel") +} +func (speaker *controlledSpeaker) Speak(ctx context.Context, text string) error { + return speaker.call(ctx, text) +} +func (speaker *controlledSpeaker) call(ctx context.Context, text string) error { + call := speechCall{text: text, done: make(chan struct{})} + select { + case speaker.calls <- call: + case <-ctx.Done(): + return ctx.Err() + } + select { + case <-call.done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func expectSpeechCall(t *testing.T, speaker *controlledSpeaker, want string) speechCall { + t.Helper() + select { + case call := <-speaker.calls: + if call.text != want { + t.Fatalf("call = %q, want %q", call.text, want) + } + return call + case <-time.After(time.Second): + t.Fatalf("waiting for %q", want) + return speechCall{} + } +} + +func TestInterruptDropsPendingAndOrdersNextSpeech(t *testing.T) { + speaker := &controlledSpeaker{calls: make(chan speechCall, 10)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + worker.Enqueue(speechRequest{Text: "Active"}) + active := expectSpeechCall(t, speaker, "Active") + worker.Enqueue(speechRequest{Text: "Discarded"}) + worker.Interrupt() + interrupt := expectSpeechCall(t, speaker, "cancel") + // Flooding interrupts is bounded and never waits for the backend. + for range 1000 { + worker.Interrupt() + } + worker.Enqueue(speechRequest{Text: "Next"}) + close(interrupt.done) + close(active.done) + // One follow-up cancellation closes the acceptance race; a coalesced + // second interrupt may add another. No stale request may reach Speak. + for { + select { + case call := <-speaker.calls: + if call.text != "cancel" && call.text != "Next" { + t.Fatalf("unexpected %q", call.text) + } + close(call.done) + if call.text == "Next" { + if err := worker.Stop(context.Background()); err != nil { + t.Fatal(err) + } + return + } + case <-time.After(time.Second): + t.Fatal("next speech did not resume") + } + } +} + +type stubbornCancelSpeaker struct { + blockingSpeaker + cancelStarted chan struct{} + release chan struct{} +} + +func (speaker *stubbornCancelSpeaker) Cancel(context.Context) error { + close(speaker.cancelStarted) + <-speaker.release + return nil +} + +func TestStopWaitsForCancellationEvenAfterDeliveryExits(t *testing.T) { + speaker := &stubbornCancelSpeaker{cancelStarted: make(chan struct{}), release: make(chan struct{})} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { close(speaker.release); worker.Stop(context.Background()) }) + worker.Interrupt() + select { + case <-speaker.cancelStarted: + case <-time.After(time.Second): + t.Fatal("cancel did not start") + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if err := worker.Stop(ctx); err == nil { + t.Fatal("Stop reported success with cancellation blocked") + } + <-worker.runDone + if err := worker.Stop(ctx); err == nil { + t.Fatal("repeated Stop forgot cancellation worker") + } +} + +type orderedSpeaker struct { + calls []string +} + +func (speaker *orderedSpeaker) Connect(context.Context) error { return nil } +func (speaker *orderedSpeaker) Close(context.Context) error { return nil } +func (speaker *orderedSpeaker) Cancel(context.Context) error { + speaker.calls = append(speaker.calls, "cancel") + return nil +} +func (speaker *orderedSpeaker) Speak(_ context.Context, text string) error { + speaker.calls = append(speaker.calls, text) + return nil +} + +func TestTerminalOutputAndPromptDoNotCancelEachOther(t *testing.T) { + speaker := &orderedSpeaker{} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + for _, request := range []speechRequest{ + {Text: "Command output", Role: "terminal", Append: true}, + {Text: "Prompt", Role: "terminal", Append: true}, + {Text: "Save", Role: "button"}, + } { + if err := worker.deliver(context.Background(), request); err != nil { + t.Fatal(err) + } + } + if got := fmt.Sprint(speaker.calls); got != "[Command output Prompt Save]" { + t.Fatalf("speech order = %s", got) + } +} + +func TestSpeechDeliveryDiagnosticsIncludeUtteranceAndPolicy(t *testing.T) { + var output bytes.Buffer + logger := logging.New(&output, logging.Options{Level: slog.LevelDebug}) + worker := newSpeechWorker(logger, &orderedSpeaker{}) + request := speechRequest{ + Text: "Terminal output with Café and 猫.", + Role: "terminal", + Cause: "object:text-changed:insert", + Append: true, + } + if err := worker.deliver(context.Background(), request); err != nil { + t.Fatal(err) + } + logText := output.String() + for _, expected := range []string{ + `"cause":"object:text-changed:insert"`, + `"append":true`, + `"interrupt_previous":false`, + `"utterance":"Terminal output with Café and 猫."`, + } { + if !strings.Contains(logText, expected) { + t.Fatalf("diagnostics %q do not contain %q", logText, expected) + } + } +} + +func TestNormalSpeechDeliveryDiagnosticsOmitUtterance(t *testing.T) { + var output bytes.Buffer + logger := logging.New(&output, logging.Options{Level: slog.LevelInfo}) + worker := newSpeechWorker(logger, &orderedSpeaker{}) + request := speechRequest{Text: "Terminal output", Role: "terminal"} + if err := worker.deliver(context.Background(), request); err != nil { + t.Fatal(err) + } + if strings.Contains(output.String(), request.Text) { + t.Fatalf("normal diagnostics exposed speech text: %q", output.String()) + } +} + +func TestSpeechDeliveryDiagnosticsProtectPasswordText(t *testing.T) { + var output bytes.Buffer + worker := newSpeechWorker(logging.New(&output, logging.Options{Level: slog.LevelDebug}), &orderedSpeaker{}) + request := speechRequest{Text: "generic-secret", Role: "password text"} + if err := worker.deliver(context.Background(), request); err != nil { + t.Fatal(err) + } + if strings.Contains(output.String(), request.Text) || !strings.Contains(output.String(), `"utterance":"[REDACTED]"`) { + t.Fatalf("protected speech diagnostics: %s", output.String()) + } +} diff --git a/internal/app/startup_sound_test.go b/internal/app/startup_sound_test.go new file mode 100644 index 0000000..ab99040 --- /dev/null +++ b/internal/app/startup_sound_test.go @@ -0,0 +1,104 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "reflect" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +// Hold the startup playback at the backend while application settings commit. +// No audio device or timing sleep is needed to observe synchronous cancellation. +type startupSoundPlayer struct { + started chan context.Context + release chan struct{} + once sync.Once +} + +func (player *startupSoundPlayer) Play(ctx context.Context, _ []byte, _, _ float64) error { + first := false + player.once.Do(func() { first = true }) + if first { + player.started <- ctx + select { + case <-ctx.Done(): + return ctx.Err() + case <-player.release: + } + } + return nil +} + +func TestApplicationSettingsPreserveStartupSoundUnlessSoundPolicyChanges(t *testing.T) { + for _, test := range []struct { + name string + change func(*config.Settings) + cancel bool + }{ + {name: "same settings", change: func(*config.Settings) {}}, + {name: "title reading override", change: func(settings *config.Settings) { + settings.Reading.AutomaticallyReadTitleChanges = false + }}, + {name: "volume override", cancel: true, change: func(settings *config.Settings) { + settings.SoundVolume = 0.8 + }}, + {name: "disabled sound", cancel: true, change: func(settings *config.Settings) { + settings.EnableSound = false + }}, + {name: "theme override", cancel: true, change: func(settings *config.Settings) { + settings.SoundTheme = "none" + }}, + {name: "sink override", cancel: true, change: func(settings *config.Settings) { + settings.SoundSink = "pulse" + }}, + } { + t.Run(test.name, func(t *testing.T) { + settings := config.DefaultSettings() + logger := slog.New(slog.DiscardHandler) + player := &startupSoundPlayer{started: make(chan context.Context, 1), release: make(chan struct{})} + service := sound.New(logger, player, settings.SoundTheme, settings.SoundVolume) + service.Configure(soundConfiguration(settings)) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + close(player.release) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Error(err) + } + }) + if !service.Enqueue(sound.Cue{Name: "start"}) { + t.Fatal("startup cue rejected") + } + var playback context.Context + select { + case playback = <-player.started: + case <-time.After(time.Second): + t.Fatal("startup cue did not reach backend") + } + worker := newPreferencesWorker(logger, settings, nil) + worker.sound = service + next := settings + test.change(&next) + worker.appSettings["Example Application"] = next + worker.switchApplication(context.Background(), "Example Application") + if worker.activeApp != "Example Application" || !reflect.DeepEqual(worker.settings, next) { + t.Fatal("application settings were not applied") + } + if got := playback.Err() == context.Canceled; got != test.cancel { + t.Fatalf("startup playback cancelled = %t, want %t", got, test.cancel) + } + }) + } +} diff --git a/internal/app/steam_activation_test.go b/internal/app/steam_activation_test.go new file mode 100644 index 0000000..42928f1 --- /dev/null +++ b/internal/app/steam_activation_test.go @@ -0,0 +1,274 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestWindowTitleChangesSuppressRepeatedNames(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 16)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 16)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.70", "/window", "/window") + activation.Source.Name, activation.Source.Role = "Original title", "frame" + activation.WindowTitle = "Original title" + adapter.events <- activation + expectActivationSpeech(t, queue.spoken, "Original title, frame") + changed := activation + changed.Type = atspi.AccessibleNameEvent + for _, title := range []string{"Original title", "Intermediate title", "Updated title", "Updated title", "", "Updated title"} { + changed.Source.Name = title + adapter.events <- changed + } + expectActivationSpeech(t, queue.spoken, "Updated title") + select { + case got := <-queue.spoken: + t.Fatalf("burst queued extra title %q", got) + default: + } +} + +func TestWindowActivationEstablishesFocusedObjectOwnership(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + + focused := atspi.Snapshot{ + BusName: ":1.70", + Path: "/focused", + ApplicationName: "steamwebhelper", + Name: "Library", + Role: "check box", + Focused: true, + } + activation := atspi.NewEvent(atspi.WindowActivatedEvent, focused) + activation.OriginPath = "/window" + adapter.events <- activation + expectActivationSpeech(t, queue.spoken, "Library, check box, not checked") + duplicate := activation + duplicate.Source.Name = "Duplicate activation" + adapter.events <- duplicate + select { + case got := <-queue.spoken: + t.Fatalf("duplicate activation spoke %q", got) + case <-time.After(30 * time.Millisecond): + } + + // Accessible paths are process-local. A background process using the same + // path must not be mistaken for the active Steam object. + background := focused + background.BusName = ":1.71" + background.ApplicationName = "Background Application" + background.Name = "Background" + background.Checked = true + changed := atspi.NewEvent("object:state-changed:checked", background) + changed.Detail1 = 1 + adapter.events <- changed + select { + case got := <-queue.spoken: + t.Fatalf("background path collision spoke %q", got) + case <-time.After(30 * time.Millisecond): + } + + focused.Checked = true + changed = atspi.NewEvent("object:state-changed:checked", focused) + changed.Detail1 = 1 + adapter.events <- changed + expectActivationSpeech(t, queue.spoken, "checked") +} + +func TestFocusBeforeActivationAnnouncesWindowTitleOnce(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + + focus := ownerEvent(atspi.FocusedStateEvent, ":1.70", "/window", "/entry") + focus.Source.Name = "Search" + focus.Source.Role = "entry" + focus.Source.Focused = true + focus.Detail1 = 1 + adapter.events <- focus + expectActivationSpeech(t, queue.spoken, "Search, entry") + + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.70", "/window", "/window") + activation.Source.Name = "Example Window" + activation.Source.Role = "frame" + activation.WindowTitle = "Example Window" + adapter.events <- activation + expectActivationSpeech(t, queue.spoken, "Example Window") + adapter.events <- activation + select { + case got := <-queue.spoken: + t.Fatalf("repeated activation spoke %q", got) + case <-time.After(30 * time.Millisecond): + } +} + +func TestActiveWindowNameChangeAnnouncesOnlyCurrentTitle(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.70", "/window", "/window") + activation.Source.Name = "Original title" + activation.Source.Role = "frame" + adapter.events <- activation + expectActivationSpeech(t, queue.spoken, "Original title, frame") + + background := ownerEvent(atspi.AccessibleNameEvent, ":1.70", "/other", "/other") + background.Source.Name = "Background title" + background.Source.Role = "frame" + adapter.events <- background + changed := ownerEvent(atspi.AccessibleNameEvent, ":1.70", "/window", "/window") + changed.Source.Name = "Updated title" + changed.Source.Role = "frame" + adapter.events <- changed + expectActivationSpeech(t, queue.spoken, "Updated title") + select { + case got := <-queue.spoken: + t.Fatalf("background title spoke %q", got) + case <-time.After(30 * time.Millisecond): + } +} + +func TestRepeatedWindowActivationPreservesFocusedDescendant(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + + window := atspi.Snapshot{ + BusName: ":1.70", + Path: "/window", + ApplicationName: "Example Application", + Name: "Example Window", + Role: "frame", + } + activation := atspi.NewEvent(atspi.WindowActivatedEvent, window) + activation.OriginPath = window.Path + adapter.events <- activation + expectActivationSpeech(t, queue.spoken, "Example Window, frame") + + focused := atspi.Snapshot{ + BusName: window.BusName, + Path: "/focused", + ApplicationName: window.ApplicationName, + Name: "Review target", + Role: "check box", + Focused: true, + } + focusEvent := atspi.NewEvent(atspi.FocusedStateEvent, focused) + focusEvent.Detail1 = 1 + adapter.events <- focusEvent + expectActivationSpeech(t, queue.spoken, "Review target, check box, not checked") + + // X11 grabs can cause the same top-level activation to be emitted again + // with the frame as its source. It must neither speak nor replace the + // focused descendant used by review and state-change filtering. + repeated := activation + repeated.Source.Name = "Repeated window activation" + adapter.events <- repeated + focused.Checked = true + changed := atspi.NewEvent("object:state-changed:checked", focused) + changed.Detail1 = 1 + adapter.events <- changed + expectActivationSpeech(t, queue.spoken, "checked") +} + +func TestWindowActivationIsFocusGain(t *testing.T) { + event := atspi.NewEvent(atspi.WindowActivatedEvent, atspi.Snapshot{}) + if !isFocusEvent(event.Type) || !isFocusGainEvent(event) { + t.Fatal("window activation was not treated as a focus gain") + } +} + +func TestWindowLifecycleClearsFocusedObjectOwnership(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 4)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 4)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, nil, nil, nil) + }() + defer func() { cancel(); <-done }() + + focused := atspi.Snapshot{ + BusName: ":1.70", + Path: "/focused", + ApplicationName: "Example Application", + Name: "Active control", + Role: "check box", + Focused: true, + } + activation := atspi.NewEvent(atspi.WindowActivatedEvent, focused) + activation.Window = atspi.NewObjectID(focused.BusName, "/window") + adapter.events <- activation + expectActivationSpeech(t, queue.spoken, "Active control, check box, not checked") + + deactivation := atspi.NewEvent(atspi.WindowDeactivatedEvent, atspi.Snapshot{ + BusName: focused.BusName, + Path: "/window", + Role: "frame", + }) + deactivation.Window = activation.Window + adapter.events <- deactivation + + changed := atspi.NewEvent("object:state-changed:checked", focused) + changed.Detail1 = 1 + adapter.events <- changed + select { + case got := <-queue.spoken: + t.Fatalf("event from deactivated window spoke %q", got) + case <-time.After(30 * time.Millisecond): + } +} + +func expectActivationSpeech(t *testing.T, spoken <-chan string, want string) { + t.Helper() + select { + case got := <-spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing speech %q", want) + } +} diff --git a/internal/app/table_native_test.go b/internal/app/table_native_test.go new file mode 100644 index 0000000..0eec37f --- /dev/null +++ b/internal/app/table_native_test.go @@ -0,0 +1,166 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/review" +) + +func TestNativeBrowserTables(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys %v %s", err, out) + } + } + var focus atspi.Snapshot + for attempt := 0; attempt < 25 && focus.Name != "Browser foundation"; attempt++ { + keys("Tab") + timer := time.NewTimer(200 * time.Millisecond) + drain: + for { + select { + case event := <-adapter.Events(): + if isFocusEvent(event.Type) { + focus = event.Source + } + if focus.Name == "Browser foundation" { + break drain + } + case <-timer.C: + break drain + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + timer.Stop() + } + if focus.Name != "Browser foundation" { + t.Fatal("fixture focus missing") + } + worker, err := review.NewWorker(adapter, 2*time.Second) + if err != nil { + t.Fatal(err) + } + if err = worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(focus.ID()) + commands := xorg.NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err = commands.Start(ctx); err != nil { + t.Fatal(err) + } + defer commands.Stop(context.Background()) + applied := func(enabled bool) { + t.Helper() + commands.SetBrowseNavigation(enabled) + deadline := time.Now().Add(time.Second) + for commands.BrowseNavigationEnabled() != enabled && time.Now().Before(deadline) { + time.Sleep(10 * time.Millisecond) + } + if commands.BrowseNavigationEnabled() != enabled { + t.Fatal("browse grabs did not change") + } + } + applied(true) + command := func(chord string) input.Command { + t.Helper() + keys(chord) + select { + case got := <-commands.Commands(): + return got.Command + case err := <-commands.Failures(): + t.Fatal(err) + case <-time.After(2 * time.Second): + t.Fatalf("no command for %s", chord) + } + return "" + } + // Mode changes replace native browse grabs between successive A presses. + if got := command("Insert+a"); got != input.ToggleDocumentMode { + t.Fatal(got) + } + applied(false) + if got := command("Insert+a"); got != input.StickyFocusMode { + t.Fatal(got) + } + if got := command("Insert+a"); got != input.StickyBrowseMode { + t.Fatal(got) + } + applied(true) + result := func() review.Result { + t.Helper() + select { + case got := <-worker.Results(): + if got.Err != nil || got.CaretErr != nil { + t.Fatalf("navigation errors %v %v", got.Err, got.CaretErr) + } + return got + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + return review.Result{} + } + if got := command("t"); got != input.DocumentNextTable { + t.Fatal(got) + } + if err = worker.MoveDocument(review.DocumentTable, 0, false); err != nil { + t.Fatal(err) + } + if got := result(); got.DocumentPosition.Snapshot.Name != "Navigation probe" { + t.Fatalf("table %+v", got) + } + for _, step := range []struct { + key, text string + moved bool + }{ + {"alt+shift+Home", "Item", true}, + {"alt+shift+Right", "Count", true}, + {"alt+shift+Down", "Five", true}, + {"alt+shift+Down", "Spans 2 columns.", true}, + {"alt+shift+Down", "blank Row 4, column 2.", true}, + {"alt+shift+Down", "Bottom of column.", false}, + {"alt+shift+Up", "Merged total", true}, + {"alt+shift+Up", "Five", true}, + {"alt+shift+End", "blank", true}, + {"alt+shift+Left", "Last item", true}, + } { + cmd := command(step.key) + if err = worker.MoveDocumentCaret(documentCaretCommand(cmd)); err != nil { + t.Fatal(err) + } + got := result() + if got.Moved != step.moved || !strings.Contains(got.DocumentCaretText, step.text) { + t.Fatalf("%s got %+v want %s", step.key, got, step.text) + } + if step.text == "Five" && !strings.Contains(got.DocumentCaretText, "Apples") { + t.Fatalf("row header missing: %q", got.DocumentCaretText) + } + if step.text == "Five" && (got.DocumentTableRowHeader != "Apples" || got.DocumentTableColumnHeader != "Count") { + t.Fatalf("table header metadata missing for verbosity: %+v", got) + } + } +} diff --git a/internal/app/tentacle_clipboard.go b/internal/app/tentacle_clipboard.go new file mode 100644 index 0000000..ca5b7d6 --- /dev/null +++ b/internal/app/tentacle_clipboard.go @@ -0,0 +1,137 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "errors" + "io" + "net/url" + "os" + "os/exec" + "path/filepath" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +func readClipboardTarget(ctx context.Context, target string) (string, error) { + command := exec.CommandContext(ctx, "xclip", "-selection", "clipboard", "-out", "-target", target) + command.WaitDelay = time.Second + pipe, err := command.StdoutPipe() + if err != nil { + return "", err + } + if err = command.Start(); err != nil { + return "", err + } + data, readErr := io.ReadAll(io.LimitReader(pipe, 8193)) + if readErr != nil || len(data) > 8192 { + command.Process.Kill() + command.Wait() + return "", errors.New("clipboard too large") + } + err = command.Wait() + return string(data), err +} +func readTentacleClipboard(ctx context.Context) (tentaclewire.Item, error) { + targets, err := readClipboardTarget(ctx, "TARGETS") + if err != nil { + return tentaclewire.Item{}, err + } + for _, target := range strings.Fields(targets) { + if target == "text/uri-list" || target == "x-special/gnome-copied-files" { + data, err := readClipboardTarget(ctx, target) + if err != nil { + return tentaclewire.Item{}, err + } + return singleClipboardURI(data) + } + } + for _, target := range []string{"UTF8_STRING", "text/plain;charset=utf-8", "text/plain", "STRING"} { + for _, available := range strings.Fields(targets) { + if available == target { + text, err := readClipboardTarget(ctx, target) + return tentaclewire.Item{Text: text}, err + } + } + } + for _, target := range strings.Fields(targets) { + if target == "image/png" { + return clipboardPNG(ctx) + } + } + return tentaclewire.Item{}, errors.New("clipboard has no transferable text or file") +} +func singleClipboardURI(data string) (tentaclewire.Item, error) { + // GTK file managers can include a C-string terminator in the X selection. + // Remove only that trailing byte; embedded NULs remain invalid URI data. + data = strings.TrimSuffix(data, "\x00") + var uris []string + for _, line := range strings.Split(data, "\n") { + line = strings.TrimSpace(line) + if line == "" || strings.HasPrefix(line, "#") || line == "copy" || line == "cut" { + continue + } + uris = append(uris, line) + } + if len(uris) != 1 { + return tentaclewire.Item{}, errors.New("copy exactly one file or folder") + } + parsed, err := url.Parse(uris[0]) + if err != nil || parsed.Scheme != "file" || parsed.Host != "" && parsed.Host != "localhost" || parsed.RawQuery != "" || parsed.Fragment != "" || !filepath.IsAbs(parsed.Path) || strings.ContainsRune(parsed.Path, '\x00') { + return tentaclewire.Item{}, errors.New("local file path unavailable") + } + return tentaclewire.Item{Path: parsed.Path}, nil +} + +func clipboardPNG(ctx context.Context) (tentaclewire.Item, error) { + directory, err := os.MkdirTemp("", "cthulhu-clipboard-*") + if err != nil { + return tentaclewire.Item{}, err + } + keep := false + defer func() { + if !keep { + os.RemoveAll(directory) + } + }() + path := filepath.Join(directory, "clipboard.png") + file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600) + if err != nil { + return tentaclewire.Item{}, err + } + defer file.Close() + command := exec.CommandContext(ctx, "xclip", "-selection", "clipboard", "-out", "-target", "image/png") + command.WaitDelay = time.Second + pipe, err := command.StdoutPipe() + if err != nil { + return tentaclewire.Item{}, err + } + if err = command.Start(); err != nil { + return tentaclewire.Item{}, err + } + count, copyErr := io.Copy(file, io.LimitReader(pipe, 32*1024*1024+1)) + if copyErr != nil || count > 32*1024*1024 { + command.Process.Kill() + command.Wait() + return tentaclewire.Item{}, errors.New("clipboard image too large") + } + if err = command.Wait(); err != nil { + return tentaclewire.Item{}, err + } + if count == 0 { + return tentaclewire.Item{}, errors.New("empty clipboard image") + } + if err = file.Close(); err != nil { + return tentaclewire.Item{}, err + } + keep = true + return tentaclewire.Item{Path: path, Temporary: true}, nil +} +func copyTentacleText(ctx context.Context, value string) error { + command := exec.CommandContext(ctx, "xclip", "-selection", "clipboard", "-in") + command.Stdin = strings.NewReader(value) + return command.Run() +} diff --git a/internal/app/tentacle_clipboard_test.go b/internal/app/tentacle_clipboard_test.go new file mode 100644 index 0000000..3e2c058 --- /dev/null +++ b/internal/app/tentacle_clipboard_test.go @@ -0,0 +1,93 @@ +package app + +import ( + "bytes" + "context" + "image" + "image/png" + "net/url" + "os" + "os/exec" + "path/filepath" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +func TestTentacleClipboardRequiresOneLocalFile(t *testing.T) { + for _, raw := range []string{"file:///tmp/a%20b\r\n", "copy\nfile:///tmp/a%20b\n", "cut\nfile://localhost/tmp/a%20b\n", "file:///tmp/a%20b\x00", "file:///tmp/a%20b\r\n\x00", "copy\nfile:///tmp/a%20b\n\x00"} { + value, err := singleClipboardURI(raw) + if err != nil || value.Path != "/tmp/a b" { + t.Fatal(value, err) + } + } + for _, raw := range []string{"", "file:///tmp/a\nfile:///tmp/b\n", "file://remote/tmp/a", "https://example.org/a", "file:///tmp/a?query", "file:///tmp/a\x00file:///tmp/b", "file:///tmp/a\x00\x00", "file:///tmp/a%00b", "file:///tmp/a\nfile:///tmp/b\x00"} { + if _, err := singleClipboardURI(raw); err == nil { + t.Fatal("accepted", raw) + } + } +} + +func TestNativeTentacleClipboardTargetsAndTemporaryImage(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_INTERNAL_UI") != "1" { + t.Skip("requires isolated Xorg clipboard") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + set := func(target string, data []byte) { + t.Helper() + command := exec.CommandContext(ctx, "xclip", "-selection", "clipboard", "-in", "-target", target) + command.Stdin = bytes.NewReader(data) + if err := command.Run(); err != nil { + t.Fatal(err) + } + } + path := filepath.Join(t.TempDir(), "one file.txt") + if err := os.WriteFile(path, []byte("fixture"), 0600); err != nil { + t.Fatal(err) + } + uri := (&url.URL{Scheme: "file", Path: path}).String() + var item tentaclewire.Item + var err error + for _, selection := range []struct{ target, data string }{ + {"text/uri-list", uri + "\r\n"}, + {"text/uri-list", uri + "\x00"}, // GTK file-manager selection terminator. + {"x-special/gnome-copied-files", "copy\n" + uri + "\n\x00"}, + } { + set(selection.target, []byte(selection.data)) + item, err = readTentacleClipboard(ctx) + if err != nil || item.Path != path || item.Temporary { + t.Fatal(selection.target, item, err) + } + } + set("text/uri-list", []byte(uri+"\nfile:///tmp/another\n")) + if _, err = readTentacleClipboard(ctx); err == nil { + t.Fatal("accepted multiple file-manager clipboard items") + } + text := "one\ntwo é猫" + if err = copyTentacleText(ctx, text); err != nil { + t.Fatal(err) + } + item, err = readTentacleClipboard(ctx) + if err != nil || item.Text != text || item.Path != "" { + t.Fatal(item, err) + } + var bitmap bytes.Buffer + if err = png.Encode(&bitmap, image.NewRGBA(image.Rect(0, 0, 2, 2))); err != nil { + t.Fatal(err) + } + set("image/png", bitmap.Bytes()) + item, err = readTentacleClipboard(ctx) + if err != nil || !item.Temporary || filepath.Base(item.Path) != "clipboard.png" { + t.Fatal(item, err) + } + defer os.RemoveAll(filepath.Dir(item.Path)) + data, err := os.ReadFile(item.Path) + if err != nil || !bytes.Equal(data, bitmap.Bytes()) { + t.Fatal("temporary clipboard image changed", err) + } + if info, _ := os.Stat(item.Path); info.Mode().Perm() != 0600 { + t.Fatal("temporary image is not private") + } +} diff --git a/internal/app/tentacle_install_test.go b/internal/app/tentacle_install_test.go new file mode 100644 index 0000000..60606cc --- /dev/null +++ b/internal/app/tentacle_install_test.go @@ -0,0 +1,280 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "context" + "crypto/sha256" + "errors" + "fmt" + "io" + "net/http" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/tentacle" +) + +type installTransport func(*http.Request) (*http.Response, error) + +func (transport installTransport) RoundTrip(request *http.Request) (*http.Response, error) { + return transport(request) +} + +func install_fixture(t *testing.T) (tentacle.Repository, []byte) { + t.Helper() + program, err := os.Executable() + if err != nil { + t.Fatal(err) + } + binary, err := os.ReadFile(program) + if err != nil { + t.Fatal(err) + } + marker := filepath.Join(t.TempDir(), "called") + manifest := fmt.Sprintf("format-version=1\nid='echo'\nname='Echo'\nversion='0.1'\nruntime='native'\nplatforms=['linux']\nentry-point=['bin/echo','-test.run=^TestTentacleReaderPeer$','--','reader-peer',%q]\napis=['commands']\ncapabilities=[]\n[protocol]\nmajor=1\nminor=0\n", marker) + var data bytes.Buffer + compressed := gzip.NewWriter(&data) + archive := tar.NewWriter(compressed) + for _, item := range []struct { + name string + data []byte + mode int64 + }{{"tentacle.toml", []byte(manifest), 0644}, {"bin/echo", binary, 0755}} { + if err := archive.WriteHeader(&tar.Header{Name: item.name, Size: int64(len(item.data)), Mode: item.mode}); err != nil { + t.Fatal(err) + } + if _, err := archive.Write(item.data); err != nil { + t.Fatal(err) + } + } + if err := archive.Close(); err != nil { + t.Fatal(err) + } + if err := compressed.Close(); err != nil { + t.Fatal(err) + } + digest := sha256.Sum256(data.Bytes()) + repository := tentacle.Repository{URL: "https://example.org/team/tentacles", ID: "example.tentacles", Name: "Example", Revision: strings.Repeat("a", 40), Tentacles: []tentacle.Manifest{{FormatVersion: 1, ID: "echo", Name: "Echo", Version: "0.1", Releases: []tentacle.Release{{Platform: "linux", Architecture: runtime.GOARCH, URL: "https://example.org/release.tar.gz", SHA256: fmt.Sprintf("%x", digest)}}}}} + return repository, data.Bytes() +} + +func set_install_transport(t *testing.T, transport installTransport) { + t.Helper() + previous := http.DefaultTransport + http.DefaultTransport = transport + t.Cleanup(func() { http.DefaultTransport = previous }) +} + +func TestRepositoryPackageInstallEnableDisableRemoveAndOfflineRestart(t *testing.T) { + test_repository_package_install(t, false) +} + +func TestSupervisedRepositoryPackageInstall(t *testing.T) { + test_repository_package_install(t, true) +} + +func test_repository_package_install(t *testing.T, contained bool) { + repository, data := install_fixture(t) + downloads := 0 + set_install_transport(t, func(*http.Request) (*http.Response, error) { + downloads++ + return &http.Response{StatusCode: 200, ContentLength: int64(len(data)), Body: io.NopCloser(bytes.NewReader(data)), Header: make(http.Header)}, nil + }) + registryPath := filepath.Join(t.TempDir(), "tentacles.toml") + owner, bindings := managed_tentacle_fixture(t, registryPath, contained) + if binary := os.Getenv("CTHULHU_TENTACLE_GUARDIAN_BINARY"); contained && binary != "" { + owner.guardianProgram = []string{binary, "--tentacle-guardian"} + } + owner.fetchRepository = func(context.Context, string) (tentacle.Repository, error) { return repository, nil } + if err := owner.Start(context.Background()); err != nil { + t.Fatal(err) + } + if err := owner.Manage(context.Background(), tentacle.ManagementRequest{Action: "repository-add", URL: repository.URL}); err != nil { + t.Fatal(err) + } + if err := owner.Manage(context.Background(), tentacle.ManagementRequest{Action: "install", ID: "echo", URL: repository.URL}); err != nil { + t.Fatal(err) + } + id := tentacle.PackageID(repository, "echo") + wait_managed_state(t, owner, id, "disabled") + entry := owner.Snapshot().Entries[0].Entry + if entry.Enabled || downloads != 1 { + t.Fatal(entry, downloads) + } + if err := owner.Manage(context.Background(), tentacle.ManagementRequest{Action: "install-enable", ID: "echo", URL: repository.URL}); err == nil { + t.Fatal("duplicate install accepted") + } + manage_tentacle(t, owner, "enable", id, nil) + wait_managed_state(t, owner, id, "active") + owner.Invoke(context.Background(), bindings.TentacleBindings()[0].Command) + waitTentacle(t, func() bool { _, err := os.Stat(entry.Program[len(entry.Program)-1]); return err == nil }) + manage_tentacle(t, owner, "disable", id, nil) + wait_managed_state(t, owner, id, "disabled") + if _, err := os.Stat(entry.Program[0]); err != nil { + t.Fatal("disable deleted package", err) + } + manage_tentacle(t, owner, "enable", id, nil) + wait_managed_state(t, owner, id, "active") + shutdown, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := owner.Stop(shutdown); err != nil { + t.Fatal(err) + } + restarted, _ := managed_tentacle_fixture(t, registryPath, contained) + if binary := os.Getenv("CTHULHU_TENTACLE_GUARDIAN_BINARY"); contained && binary != "" { + restarted.guardianProgram = []string{binary, "--tentacle-guardian"} + } + restarted.fetchRepository = func(context.Context, string) (tentacle.Repository, error) { + t.Error("restart fetched catalog") + return repository, nil + } + if err := restarted.Start(context.Background()); err != nil { + t.Fatal(err) + } + wait_managed_state(t, restarted, id, "active") + if downloads != 1 { + t.Fatal("enable/restart downloaded update", downloads) + } + if err := restarted.Manage(context.Background(), tentacle.ManagementRequest{Action: "repository-remove", URL: repository.URL}); err != nil { + t.Fatal(err) + } + if _, err := os.Stat(entry.Program[0]); err != nil { + t.Fatal("source removal deleted package", err) + } + manage_tentacle(t, restarted, "remove", id, nil) + waitTentacle(t, func() bool { _, err := os.Stat(entry.PackageDirectory); return os.IsNotExist(err) }) + disk, err := (&tentacle.Registry{Path: registryPath}).Load() + if err != nil || len(disk) != 0 { + t.Fatal(disk, err) + } +} + +func TestRepositoryPackageInstallFailureCancellationAndChangedCatalog(t *testing.T) { + repository, data := install_fixture(t) + for _, problem := range []string{"save failure", "cancel during download", "catalog changed", "emergency disable"} { + t.Run(problem, func(t *testing.T) { + registryPath := filepath.Join(t.TempDir(), "tentacles.toml") + registry := &tentacle.Registry{Path: registryPath} + if _, err := registry.Load(); err != nil { + t.Fatal(err) + } + if err := registry.SaveState(nil, []tentacle.Repository{repository}); err != nil { + t.Fatal(err) + } + owner, _ := managed_tentacle_fixture(t, registryPath, false) + if err := owner.Start(context.Background()); err != nil { + t.Fatal(err) + } + waitTentacle(t, func() bool { return len(owner.Snapshot().Repositories) == 1 }) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + set_install_transport(t, func(request *http.Request) (*http.Response, error) { + switch problem { + case "save failure": + if err := os.WriteFile(registryPath, []byte("# external edit\n"), 0600); err != nil { + t.Fatal(err) + } + case "cancel during download": + cancel() + case "catalog changed": + if err := owner.Manage(context.Background(), tentacle.ManagementRequest{Action: "repository-remove", URL: repository.URL}); err != nil { + t.Fatal(err) + } + case "emergency disable": + owner.Disable() + } + return &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader(data)), Header: make(http.Header)}, nil + }) + if err := owner.Manage(ctx, tentacle.ManagementRequest{Action: "install-enable", ID: "echo", URL: repository.URL}); err == nil { + t.Fatal("failed installation accepted") + } + if len(owner.Snapshot().Entries) != 0 { + t.Fatal("failed installation registered entry") + } + files, err := os.ReadDir(tentacle.PackageRoot(registryPath)) + if !os.IsNotExist(err) && err != nil { + t.Fatal(err) + } + if len(files) != 0 { + t.Fatal("failed installation left files", files) + } + }) + } +} + +func TestInstallEnableReportsActivationAndDisablesFailedStarts(t *testing.T) { + for _, problem := range []string{"none", "manager", "program", "registration", "bindings"} { + t.Run(problem, func(t *testing.T) { + repository, data := install_fixture(t) + set_install_transport(t, func(*http.Request) (*http.Response, error) { + return &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader(data)), Header: make(http.Header)}, nil + }) + registryPath := filepath.Join(t.TempDir(), "tentacles.toml") + owner, bindings := managed_tentacle_fixture(t, registryPath, false) + if problem == "manager" { + owner.newManager = func() (*tentacle.Manager, error) { return nil, errors.New("fixture containment unavailable") } + } + bindings.reject = problem == "bindings" + owner.preparePackage = func(ctx context.Context, root string, repo tentacle.Repository, id string) (*tentacle.PreparedPackage, error) { + prepared, err := tentacle.PreparePackage(ctx, root, repo, id) + if err == nil { + if problem == "program" { + if err := os.Remove(prepared.Entry.Program[0]); err != nil { + t.Fatal(err) + } + } + if problem == "registration" { + prepared.Entry.Program[len(prepared.Entry.Program)-1] = filepath.Join(t.TempDir(), "bad-startup") + } + } + return prepared, err + } + owner.fetchRepository = func(context.Context, string) (tentacle.Repository, error) { return repository, nil } + if err := owner.Start(context.Background()); err != nil { + t.Fatal(err) + } + if err := owner.Manage(context.Background(), tentacle.ManagementRequest{Action: "repository-add", URL: repository.URL}); err != nil { + t.Fatal(err) + } + worker := newPreferencesWorker(owner.logger, config.DefaultSettings(), nil) + worker.tentacles = owner + response := worker.manage_tentacle(context.Background(), preferences.Request{Tentacle: &tentacle.ManagementRequest{Action: "install-enable", URL: repository.URL, ID: "echo"}}) + if response.Accepted != (problem == "none") { + t.Fatalf("unexpected installation response: %+v", response) + } + if response.Tentacles == nil || len(response.Tentacles.Entries) != 1 { + t.Fatalf("missing installed state: %+v", response) + } + status := response.Tentacles.Entries[0] + if problem == "none" { + if status.State != "active" || !status.Entry.Enabled || !strings.Contains(response.Message, "active") { + t.Fatalf("success before activation: %+v %s", status, response.Message) + } + } else { + if status.Entry.Enabled || status.Message == "" || strings.Contains(response.Message, "installed and") { + t.Fatalf("failed startup reported success: %+v %s", status, response.Message) + } + if len(bindings.TentacleBindings()) != 0 { + t.Fatal("failed startup retained bindings") + } + if err := owner.Manage(context.Background(), tentacle.ManagementRequest{Action: "enable", ID: status.Entry.ID}); err == nil { + t.Fatal("failed enable reported success") + } + } + disk, err := (&tentacle.Registry{Path: registryPath}).Load() + if err != nil || len(disk) != 1 || disk[0].Enabled != (problem == "none") { + t.Fatalf("incorrect persisted enablement: %+v %v", disk, err) + } + }) + } +} diff --git a/internal/app/tentacle_interaction.go b/internal/app/tentacle_interaction.go new file mode 100644 index 0000000..2ba2f5e --- /dev/null +++ b/internal/app/tentacle_interaction.go @@ -0,0 +1,253 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os" + "path/filepath" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type tentacleForms interface { + Open(context.Context, interaction.Form) (<-chan internalUIResult, error) + Notice(context.Context, tentaclewire.Presentation) +} + +// One interaction per runtime. RPC requests remain short; human input and +// background transfer polling belong to this joined worker, never the input +// consumer. Session revocation cancels its form and retires all results. +func (runtime *tentacleRuntime) interact(ctx context.Context, command tentacleCommand, raw json.RawMessage) { + select { + case runtime.interactionSlots <- struct{}{}: + default: + runtime.report("A tentacle menu is already open.") + return + } + defer func() { <-runtime.interactionSlots }() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + stop := context.AfterFunc(command.session.OutputContext(), cancel) + defer stop() + var temporaryFiles []string + defer func() { + for _, path := range temporaryFiles { + os.RemoveAll(filepath.Dir(path)) + } + }() + for transitions := 0; transitions < 1024 && ctx.Err() == nil; transitions++ { + value, err := tentaclewire.DecodeInteraction(raw) + if err != nil || !runtime.validContinuation(command, value.Next) || !runtime.validContinuation(command, value.Poll) { + command.session.Disable() + runtime.output.RetireRevoked() + runtime.report("A tentacle returned an invalid interaction and was disabled.") + return + } + if runtime.output.gate.Locked() || runtime.output.gate.Suspended() { + return + } + if value.Clipboard != nil { + copyCtx, stopCopy := context.WithTimeout(ctx, time.Second) + err = copyTentacleText(copyCtx, *value.Clipboard) + stopCopy() + if err != nil { + value.Presentation = clipboardWriteFailure(value.Presentation) + } + } + if value.Reader != nil { + if !command.reader || runtime.readerSettings == nil || value.Next != "" && !runtime.reader_continuation(command, value.Next) { + command.session.Disable() + return + } + state, readerErr := runtime.readerSettings.request_reader(ctx, command.session, *value.Reader) + if value.Next == "" { + if readerErr != nil { + runtime.report("Tentacle settings were not applied: " + readerErr.Error()) + } + return + } + submission := tentaclewire.Submission{Reader: state} + if readerErr != nil { + submission.Error = readerErr.Error() + } + raw, err = runtime.callInteraction(ctx, command, value.Next, submission) + if err != nil { + return + } + continue + } + if value.Form == nil && value.Source == "" { + runtime.output.Present(runtime.output.Capture(command.session.OutputContext()), value.Presentation, "tentacle/"+command.id) + return + } + var submission tentaclewire.Submission + if value.Form != nil { + if runtime.forms == nil { + runtime.callInteraction(ctx, command, value.Next, tentaclewire.Submission{Cancelled: true}) + runtime.report("Internal UI unavailable.") + return + } + formCtx, closeForm := context.WithCancel(ctx) + replies, openErr := runtime.forms.Open(formCtx, *value.Form) + if openErr != nil { + closeForm() + runtime.callInteraction(ctx, command, value.Next, tentaclewire.Submission{Cancelled: true}) + runtime.report("Internal UI unavailable.") + return + } + if value.Speech != "" || value.Braille != "" { + runtime.forms.Notice(formCtx, value.Presentation) + } + reply, completed := runtime.waitTentacleForm(formCtx, command, value, replies) + closeForm() + if completed != nil { + // Wait for EndInternalUI before announcing completion or copying text. + select { + case <-replies: + case <-ctx.Done(): + return + } + raw = completed + continue + } + submission = tentaclewire.Submission{Activated: reply.Activated, Values: reply.Values, Cancelled: reply.Cancelled || reply.Err != nil} + } else { + itemCtx, stopItem := context.WithTimeout(ctx, time.Second) + var item tentaclewire.Item + if value.Source == "focus" { + if runtime.focusedItem == nil { + err = errors.New("focused item unavailable") + } else { + item, err = runtime.focusedItem(itemCtx) + } + } else { + item, err = readTentacleClipboard(itemCtx) + if item.Temporary { + temporaryFiles = append(temporaryFiles, item.Path) + item.Temporary = false + } + } + stopItem() + if err != nil { + submission.Error = "The requested item is unavailable or is not a single item" + } else { + submission.Item = &item + } + } + // A cancelled UI still gets a short cleanup invocation while its session is + // live. That lets the tentacle stop its background process on Escape/focus loss. + raw, err = runtime.callInteraction(ctx, command, value.Next, submission) + if err != nil { + return + } + if submission.Cancelled { + return + } + } +} + +func (runtime *tentacleRuntime) validContinuation(command tentacleCommand, id string) bool { + if id == "" { + return true + } + for _, registered := range command.session.Commands() { + if registered.ID == id { + return registered.Interaction && registered.Presentation + } + } + return false +} +func (runtime *tentacleRuntime) callInteraction(ctx context.Context, command tentacleCommand, id string, arguments any) (json.RawMessage, error) { + data, err := json.Marshal(arguments) + if err != nil { + return nil, err + } + replies, err := command.session.Invoke(ctx, id, data) + if err != nil { + return nil, err + } + result := <-replies + return result.Value, result.Err +} +func (runtime *tentacleRuntime) waitTentacleForm(ctx context.Context, command tentacleCommand, value tentaclewire.Interaction, replies <-chan internalUIResult) (internalUIResult, json.RawMessage) { + var ticks <-chan time.Time + if value.Poll != "" { + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + ticks = ticker.C + } + for { + select { + case reply := <-replies: + return reply, nil + case <-ctx.Done(): + return internalUIResult{Cancelled: true}, nil + case <-ticks: + raw, err := runtime.callInteraction(ctx, command, value.Poll, tentaclewire.Submission{}) + if err != nil { + return internalUIResult{Cancelled: true}, nil + } + status, err := tentaclewire.DecodeInteraction(raw) + if err != nil || status.Form != nil || status.Source != "" || status.Next != "" || status.Reader != nil { + command.session.Disable() + return internalUIResult{Cancelled: true}, nil + } + if status.Done { + return internalUIResult{}, raw + } + if status.Clipboard != nil { + if runtime.output.gate.Locked() || runtime.output.gate.Suspended() || ctx.Err() != nil { + return internalUIResult{Cancelled: true}, nil + } + copyCtx, stopCopy := context.WithTimeout(ctx, time.Second) + copyErr := copyTentacleText(copyCtx, *status.Clipboard) + stopCopy() + if copyErr != nil { + status.Presentation = clipboardWriteFailure(status.Presentation) + } + } + runtime.forms.Notice(ctx, status.Presentation) + } + } +} + +func focusedTentacleItem(source any, ui *internalUI) func(context.Context) (tentaclewire.Item, error) { + reader, ok := source.(interface { + ReadTransferItem(context.Context, atspi.ObjectID, int) (atspi.TransferItem, error) + }) + if !ok || ui.interest == nil { + return nil + } + return func(ctx context.Context) (tentaclewire.Item, error) { + interest, err := ui.interest.ObjectOfInterest(ctx) + if err != nil { + return tentaclewire.Item{}, err + } + if interest.HasZone { + return tentaclewire.Item{}, errors.New("flat review transfer unavailable") + } + item, err := reader.ReadTransferItem(ctx, interest.Object, interest.Offset) + return tentaclewire.Item{Text: item.Text, Path: item.Path}, err + } +} + +func clipboardWriteFailure(message tentaclewire.Presentation) tentaclewire.Presentation { + if message.Speech == "" { + message.Speech = "Clipboard text could not be saved" + } else { + message.Speech = fmt.Sprintf("%s. Clipboard text could not be saved", message.Speech) + } + if message.Braille == "" { + message.Braille = "Clipboard text could not be saved" + } else { + message.Braille = fmt.Sprintf("%s. Clipboard text could not be saved", message.Braille) + } + return message +} diff --git a/internal/app/tentacle_interaction_test.go b/internal/app/tentacle_interaction_test.go new file mode 100644 index 0000000..db03ab2 --- /dev/null +++ b/internal/app/tentacle_interaction_test.go @@ -0,0 +1,204 @@ +package app + +import ( + "context" + "encoding/json" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/tentacle" + sdk "git.stormux.org/storm/cthulhu/sdk/go/tentacle" + "log/slog" + "os" + "path/filepath" + "strings" + "testing" + "time" +) + +func TestTentacleInteractionPeer(t *testing.T) { + if len(os.Args) < 3 || os.Args[len(os.Args)-2] != "interaction-peer" { + return + } + marker := os.Args[len(os.Args)-1] + initial := func(context.Context, json.RawMessage) (any, error) { + if filepath.Base(marker) == "copy-failed" { + code := "7-alpha-beta" + return sdk.Interaction{Presentation: sdk.Presentation{Speech: "Wormhole code: " + code, Braille: "Wormhole code: " + code}, Clipboard: &code, Done: true}, nil + } + next := "submit" + if filepath.Base(marker) == "invalid" { + next = "unregistered" + } + return sdk.Interaction{Form: &sdk.Form{Title: "Wormhole menu", Elements: []sdk.Element{{ID: "code", Label: "Wormhole code", Kind: sdk.Entry, Required: true, MaxLength: 256}}}, Next: next}, nil + } + submit := func(_ context.Context, raw json.RawMessage) (any, error) { + os.WriteFile(marker, raw, 0600) + return sdk.Interaction{Presentation: sdk.Presentation{Speech: "Submitted", Braille: "Submitted"}}, nil + } + commands := []sdk.Command{ + {ID: "probe", Title: "Interactive probe", Presentation: true, Interaction: true, Bindings: []sdk.Binding{{Layout: "desktop", Scope: "global", Key: "F9"}}, Handle: initial}, + {ID: "submit", Title: "Submit", Presentation: true, Interaction: true, Handle: submit}, + } + if strings.HasPrefix(filepath.Base(marker), "settings") { + commands = append(commands, sdk.Command{ID: "settings", Title: "Probe settings", Settings: true, Presentation: true, Interaction: true, Handle: initial}) + } + err := sdk.Serve(os.Stdin, os.Stdout, commands) + if err != nil { + os.Exit(1) + } + os.Exit(0) +} +func interactiveFixture(t *testing.T, mode string) (*tentacleRuntime, *internalUI, *uiTestKeys, string) { + t.Helper() + directory := t.TempDir() + marker := filepath.Join(directory, mode) + executable, _ := os.Executable() + specs := []tentacle.Spec{{ID: "probe", Presentation: true, Interaction: true, Program: []string{executable, "-test.run=^TestTentacleInteractionPeer$", "--", "interaction-peer", marker}}} + data, _ := json.Marshal(specs) + path := filepath.Join(directory, "launch.json") + os.WriteFile(path, data, 0600) + bindings := &tentacleBindingRecorder{} + runtime := newTentacleRuntime(slog.New(slog.DiscardHandler), bindings, path, "") + runtime.output = tentacleOutputFixture(t) + runtime.newManager = func() (*tentacle.Manager, error) { return tentacle.NewManager(tentacle.DefaultLimits(), nil) } + keys := &uiTestKeys{} + output := &ocrTestOutput{speech: make(chan speechRequest, 32)} + ui := &internalUI{keys: keys, speech: output, gate: runtime.output.gate, events: make(chan input.CommandEvent, 16), requests: make(chan internalUIRequest, 1), notices: make(chan internalUINotice, 4), done: make(chan struct{})} + runtime.forms = ui + ctx, cancel := context.WithCancel(context.Background()) + go ui.run(ctx) + t.Cleanup(func() { + cancel() + <-ui.done + stopCtx, stopCancel := context.WithTimeout(context.Background(), 5*time.Second) + defer stopCancel() + if err := runtime.Stop(stopCtx); err != nil { + t.Error(err) + } + }) + if err := runtime.Start(ctx); err != nil { + t.Fatal(err) + } + waitTentacle(t, func() bool { + published := bindings.TentacleBindings() + if len(published) == 0 { + return false + } + // Native bindings are installed before activation publishes dispatch. + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + _, ready := runtime.commands[published[0].Command] + return ready + }) + runtime.Invoke(ctx, bindings.TentacleBindings()[0].Command) + return runtime, ui, keys, marker +} +func TestReaderTentacleHumanInputOutlivesRPCDeadline(t *testing.T) { + runtime, ui, keys, marker := interactiveFixture(t, "submitted") + waitTentacle(t, func() bool { return keys.InternalUISession() != 0 }) + // RequestTimeout is two seconds; a user can take longer to type a code. + time.Sleep(2100 * time.Millisecond) + if keys.InternalUISession() == 0 { + t.Fatal("RPC deadline cancelled human input") + } + runtime.output.Retire() // The native command consumer retires output on each key. + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Text: "7-alpha-beta"}) + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: 1, Chord: input.CommandChord{Symbol: 0xff0d}}) + waitTentacle(t, func() bool { _, err := os.Stat(marker); return err == nil }) + data, _ := os.ReadFile(marker) + var values sdk.Submission + if json.Unmarshal(data, &values) != nil || values.Values["code"].Text != "7-alpha-beta" || values.Cancelled { + t.Fatalf("submission %s", data) + } + waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 }) + if keys.InternalUISession() != 0 { + t.Fatal("input capture retained after submit") + } +} +func TestReaderTentacleFocusLossAndRevocationCloseForms(t *testing.T) { + for _, mode := range []string{"focus-loss", "disable"} { + t.Run(mode, func(t *testing.T) { + runtime, _, keys, marker := interactiveFixture(t, mode) + waitTentacle(t, func() bool { return keys.InternalUISession() != 0 }) + if mode == "disable" { + runtime.Disable() + } else { + keys.session.Store(0) + } + waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 }) + if keys.InternalUISession() != 0 { + t.Fatal("capture retained") + } + if mode == "focus-loss" { + data, err := os.ReadFile(marker) + var submitted sdk.Submission + if err != nil || json.Unmarshal(data, &submitted) != nil || !submitted.Cancelled { + t.Fatalf("cleanup was not delivered: %s %v", data, err) + } + } + }) + } +} +func TestReaderTentacleRejectsUnregisteredContinuation(t *testing.T) { + runtime, _, keys, _ := interactiveFixture(t, "invalid") + waitTentacle(t, func() bool { + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + return len(runtime.sessions) == 1 && len(runtime.sessions[0].Commands()) == 0 + }) + if keys.InternalUISession() != 0 { + t.Fatal("invalid form was opened") + } +} + +func TestInternalUINoticeCannotReachAnotherForm(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + keys := &uiTestKeys{} + output := &ocrTestOutput{speech: make(chan speechRequest, 16)} + ui := &internalUI{keys: keys, speech: output, gate: &focusGate{}, events: make(chan input.CommandEvent, 16), requests: make(chan internalUIRequest, 1), notices: make(chan internalUINotice, 4), done: make(chan struct{})} + go ui.run(ctx) + defer func() { cancel(); <-ui.done }() + form := interaction.Form{Title: "Receive", Elements: []interaction.Element{{ID: "code", Label: "Code", Kind: interaction.Entry}}} + formCtx, closeForm := context.WithCancel(ctx) + first, err := ui.Open(formCtx, form) + if err != nil { + t.Fatal(err) + } + <-output.speech + closeForm() + <-first + secondCtx, closeSecond := context.WithCancel(ctx) + defer closeSecond() + if _, err := ui.Open(secondCtx, form); err != nil { + t.Fatal(err) + } + <-output.speech + ui.Notice(formCtx, sdk.Presentation{Speech: "Stale code"}) + ui.Notice(secondCtx, sdk.Presentation{Speech: "New code"}) + select { + case got := <-output.speech: + if got.Text != "New code" { + t.Fatal(got) + } + case <-time.After(time.Second): + t.Fatal("notice not delivered") + } +} + +func TestReaderTentacleCopyFailureStillReadsCode(t *testing.T) { + t.Setenv("PATH", t.TempDir()) // The private peer is an absolute test executable. + runtime, _, keys, _ := interactiveFixture(t, "copy-failed") + waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 }) + runtime.output.speech.mutex.Lock() + defer runtime.output.speech.mutex.Unlock() + found := false + for _, request := range runtime.output.speech.pending { + if request.Text == "Wormhole code: 7-alpha-beta. Clipboard text could not be saved" { + found = true + } + } + if !found || keys.InternalUISession() != 0 { + t.Fatal("clipboard failure lost the code or retained input") + } +} diff --git a/internal/app/tentacle_management.go b/internal/app/tentacle_management.go new file mode 100644 index 0000000..7bce3b4 --- /dev/null +++ b/internal/app/tentacle_management.go @@ -0,0 +1,673 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "errors" + "fmt" + "reflect" + "slices" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/tentacle" +) + +type tentacleManagementCall struct { + ctx context.Context + request tentacle.ManagementRequest + result chan error + repository *tentacle.Repository + packageFiles *tentacle.PreparedPackage +} + +// A startup request is owned by the lifecycle worker until activation or failure. +// Cancellation only wakes that worker; it never mutates registry or session state. +type tentacleStartupCall struct { + call tentacleManagementCall + saveError error + stop func() bool +} + +func (runtime *tentacleRuntime) Snapshot() tentacle.Snapshot { + if runtime == nil { + return tentacle.Snapshot{Suppressed: true, Message: "Tentacle management is unavailable for this run."} + } + if runtime.registry == nil { + return tentacle.Snapshot{Suppressed: true, Message: "Explicit development launch lists cannot be managed here."} + } + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + result := runtime.snapshot + result.Repositories = tentacle.CloneRepositories(result.Repositories) + result.Entries = append([]tentacle.EntryStatus(nil), result.Entries...) + var bindings []input.BindingOverride + if runtime.input != nil && !runtime.disabled { + bindings = runtime.input.TentacleBindings() + } + for index := range result.Entries { + result.Entries[index].Entry.Program = append([]string(nil), result.Entries[index].Entry.Program...) + if runtime.disabled { + result.Entries[index].State = "suppressed" + } + result.Entries[index].Shortcuts = nil + for _, binding := range bindings { + command, exists := runtime.commands[binding.Command] + if !exists || command.entryID != result.Entries[index].Entry.ID { + continue + } + layout := "Desktop" + if binding.Layout == input.LaptopKeyboardLayout { + layout = "Laptop" + } + for _, key := range binding.Keys { + result.Entries[index].Shortcuts = append(result.Entries[index].Shortcuts, fmt.Sprintf("%s: %s (%s)", layout, key, command.title)) + } + } + } + result.Suppressed = runtime.disabled + return result +} + +// OpenSettings dispatches the explicitly registered settings command using +// the preferences window's lifetime, rather than a short management timeout. +// Settings storage and Save/Cancel belong to the tentacle's existing form. +func (runtime *tentacleRuntime) OpenSettings(ctx context.Context, id string) error { + if runtime == nil || runtime.registry == nil { + return tentacle.ErrUnavailable + } + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + if runtime.disabled { + return tentacle.ErrDisabled + } + index := slices.IndexFunc(runtime.snapshot.Entries, func(status tentacle.EntryStatus) bool { return status.Entry.ID == id }) + if index < 0 { + return errors.New("Select an installed tentacle first.") + } + if !runtime.snapshot.Entries[index].Entry.Enabled { + return errors.New("Enable this tentacle before opening its settings.") + } + if runtime.snapshot.Entries[index].State != "active" { + return errors.New("Tentacle settings are unavailable until the tentacle is active. Refresh status or retry.") + } + for key, command := range runtime.commands { + if command.entryID == id && command.settings { + return runtime.invokeLocked(ctx, key, command) + } + } + return errors.New("No settings for this tentacle.") +} + +// Manage fetches metadata on its caller's worker, then queues a transaction. +// Persistence, start and binding work stays on the lifecycle owner, never the +// native input callback or GTK thread. +func (runtime *tentacleRuntime) Manage(ctx context.Context, request tentacle.ManagementRequest) error { + if runtime == nil || runtime.registry == nil { + return tentacle.ErrUnavailable + } + if request.Action == "list" { + return nil + } + if request.Entry != nil { + entry := *request.Entry + entry.Program = append([]string(nil), entry.Program...) + request.Entry = &entry + } + call := tentacleManagementCall{ctx: ctx, request: request, result: make(chan error, 1)} + runtime.mutex.Lock() + disabled := runtime.disabled + runtime.mutex.Unlock() + if disabled { + return tentacle.ErrDisabled + } + if request.Action == "install" || request.Action == "install-enable" { + if request.Entry != nil { + return errors.New("unexpected tentacle entry in installation request") + } + snapshot := runtime.Snapshot() + if snapshot.Suppressed || snapshot.Message != "" { + return tentacle.ErrUnavailable + } + index := slices.IndexFunc(snapshot.Repositories, func(value tentacle.Repository) bool { return value.URL == request.URL }) + if index < 0 { + return errors.New("repository is not configured") + } + repository := snapshot.Repositories[index] + id := tentacle.PackageID(repository, request.ID) + if slices.ContainsFunc(snapshot.Entries, func(value tentacle.EntryStatus) bool { return value.Entry.ID == id }) { + return errors.New("tentacle is already installed") + } + runtime.mutex.Lock() + if runtime.repositoryBusy { + runtime.mutex.Unlock() + return tentacle.ErrBusy + } + runtime.repositoryBusy = true + runtime.mutex.Unlock() + defer func() { runtime.mutex.Lock(); runtime.repositoryBusy = false; runtime.mutex.Unlock() }() + prepare := runtime.preparePackage + if prepare == nil { + prepare = tentacle.PreparePackage + } + prepareCtx, cancel := context.WithTimeout(ctx, 45*time.Second) + stop := context.AfterFunc(runtime.lifecycleContext, cancel) + prepared, err := prepare(prepareCtx, tentacle.PackageRoot(runtime.registry.Path), repository, request.ID) + stop() + cancel() + if err != nil { + return err + } + defer prepared.Discard() + prepared.Entry.Enabled = request.Action == "install-enable" + call.packageFiles, call.repository = prepared, &repository + call.request = tentacle.ManagementRequest{Action: "add", ID: prepared.Entry.ID, Entry: &prepared.Entry} + } + if request.Action == "repository-add" || request.Action == "repository-refresh" { + if request.Entry != nil || request.ID != "" { + return errors.New("unexpected tentacle entry in repository request") + } + origin, err := tentacle.RepositoryURL(request.URL) + if err != nil { + return err + } + runtime.mutex.Lock() + if runtime.repositoryBusy { + runtime.mutex.Unlock() + return tentacle.ErrBusy + } + runtime.repositoryBusy = true + runtime.mutex.Unlock() + defer func() { runtime.mutex.Lock(); runtime.repositoryBusy = false; runtime.mutex.Unlock() }() + request.URL, call.request.URL = origin, origin + fetch := runtime.fetchRepository + if fetch == nil { + fetch = tentacle.FetchRepository + } + // Fetch on the Preferences worker, leaving lifecycle and native input + // free to disable, revoke, and process failures while the network waits. + fetchCtx, cancel := context.WithTimeout(ctx, 45*time.Second) + stop := context.AfterFunc(runtime.lifecycleContext, cancel) + repository, err := fetch(fetchCtx, origin) + stop() + cancel() + if err != nil { + return err + } + call.repository = &repository + } + select { + case runtime.requests <- call: + case <-ctx.Done(): + return ctx.Err() + case <-runtime.done: + return tentacle.ErrUnavailable + default: + return tentacle.ErrBusy + } + // Once queued, wait for the lifecycle owner's decision. Startup requests + // wake the owner on cancellation so rollback completes before the response; + // package files remain owned until the registry decision is known. + select { + case err := <-call.result: + return err + case <-runtime.done: + return tentacle.ErrUnavailable + } +} + +func change_tentacle_entries(entries []tentacle.Entry, request tentacle.ManagementRequest) ([]tentacle.Entry, error) { + next := tentacle.CloneEntries(entries) + index := slices.IndexFunc(next, func(entry tentacle.Entry) bool { return entry.ID == request.ID }) + if request.Action == "add" || request.Action == "update" { + if request.Entry == nil || request.Entry.ID != request.ID { + return nil, errors.New("a matching tentacle entry is required") + } + } else if request.Entry != nil { + return nil, errors.New("unexpected tentacle entry") + } + if request.Action != "add" && index < 0 { + return nil, errors.New("tentacle does not exist") + } + switch request.Action { + case "add": + if index >= 0 { + return nil, errors.New("tentacle already exists") + } + next = append(next, *request.Entry) + case "update": + next[index] = *request.Entry + case "remove": + next = slices.Delete(next, index, index+1) + case "enable": + next[index].Enabled = true + case "disable": + next[index].Enabled = false + case "retry": + if !next[index].Enabled { + return nil, errors.New("enable the tentacle before retrying") + } + default: + return nil, errors.New("unknown tentacle operation") + } + return next, tentacle.ValidateEntries(next) +} + +func (runtime *tentacleRuntime) run_managed(ctx context.Context) error { + entries, loadError := runtime.registry.Load() + repositories := runtime.registry.Repositories() + if loadError == nil { + if err := tentacle.RecoverPackages(tentacle.PackageRoot(runtime.registry.Path), entries); err != nil { + runtime.logger.Warn("recover tentacle packages", "error", err) + } + } + pending := make(map[string]bool) + sessions := make(map[string]*tentacle.Session) + problems := make(map[string]string) + startups := make(map[string]tentacleStartupCall) + removedPackages := make(map[string]tentacle.Entry) + for _, entry := range entries { + pending[entry.ID] = entry.Enabled + } + wake := make(chan struct{}, 1) + notify := func() { + select { + case wake <- struct{}{}: + default: + } + } + var manager *tentacle.Manager + var current *tentacle.Session + var ready <-chan struct{} + var active []*tentacle.Session + var watchers []<-chan struct{} + setSnapshot := func() { + result := tentacle.Snapshot{Repositories: tentacle.CloneRepositories(repositories)} + if loadError != nil { + result.Message = "Tentacle registry could not be loaded; no tentacles were started." + } + for _, entry := range entries { + status := tentacle.EntryStatus{Entry: entry, State: "disabled", Message: problems[entry.ID]} + if entry.Enabled { + status.State = "starting" + } + if session := sessions[entry.ID]; session != nil { + state, _ := session.Status() + status.State = string(state) + if state == tentacle.Ready { + status.State = "starting" + } + if (state == tentacle.Failed || state == tentacle.Stopped) && entry.Enabled && status.Message == "" { + status.Message = "Tentacle stopped; retry to start it again." + } + } + if pending[entry.ID] { + status.State = "starting" + } + if status.Message != "" && !pending[entry.ID] { + status.State = "failed" + } + if !entry.Enabled && sessions[entry.ID] == nil { + status.State = "disabled" + } + result.Entries = append(result.Entries, status) + } + runtime.mutex.Lock() + runtime.snapshot = result + runtime.mutex.Unlock() + } + setSnapshot() + if loadError != nil { + runtime.report("Tentacles could not start.") + } + defer func() { + runtime.Disable() + cleanup, cancel := context.WithTimeout(context.Background(), 7*time.Second) + defer cancel() + var bindingError error + if runtime.input != nil { + bindingError = runtime.input.SetTentacleBindings(cleanup, nil) + } + if runtime.readerContext.Err() != nil { + bindingError = nil + } + var managerError error + if manager != nil { + managerError = manager.Shutdown(cleanup) + } + for _, entry := range removedPackages { + if managerError == nil { + if err := tentacle.RemovePackage(tentacle.PackageRoot(runtime.registry.Path), entry); err != nil { + runtime.logger.Warn("remove tentacle package", "error", err) + } + } + } + for _, done := range watchers { + <-done + } + runtime.results.Wait() + runtime.stopError = errors.Join(bindingError, managerError) + if runtime.stopError != nil && runtime.readerContext.Err() == nil { + select { + case runtime.failures <- runtime.stopError: + default: + } + } + }() + ensureManager := func() error { + if manager != nil { + return nil + } + if runtime.input == nil { + return errors.New("native bindings are unavailable") + } + var err error + manager, err = runtime.makeManager() + return err + } + revoke := func(id string) { + if session := sessions[id]; session != nil { + session.Disable() + runtime.output.RetireRevoked() + } + } + replyStartup := func(id string, err error) { + startup, exists := startups[id] + if !exists { + return + } + delete(startups, id) + startup.stop() + if err == nil { + err = startup.saveError + } + setSnapshot() + startup.call.result <- err + } + failStartup := func(id, message string) { + problems[id] = message + if _, exists := startups[id]; !exists { + return + } + revoke(id) + if current != nil && current.TentacleID() == id { + current, ready = nil, nil + } + delete(pending, id) + next := tentacle.CloneEntries(entries) + for index := range next { + if next[index].ID == id { + next[index].Enabled = false + } + } + err := runtime.registry.Save(next) + if err == nil || errors.Is(err, tentacle.ErrRegistrySync) { + entries = next + } + if err != nil { + message += " The disabled state could not be saved durably: " + err.Error() + } + replyStartup(id, errors.New(message)) + } + defer func() { + for id := range startups { + failStartup(id, "Tentacle startup was cancelled before activation.") + } + }() + for { + if ctx.Err() != nil { + return nil + } + for id, startup := range startups { + if startup.call.ctx.Err() != nil { + failStartup(id, "Tentacle startup was cancelled before activation.") + } + } + // Reconcile revoked sessions before staging new native grabs. + retained := active[:0] + for _, session := range active { + if state, _ := session.Status(); state == tentacle.Active { + retained = append(retained, session) + } + } + changed := len(retained) != len(active) + active = retained + if changed { + runtime.publishCommands(active) + if err := runtime.bind(ctx, active); err != nil && ctx.Err() == nil { + select { + case runtime.failures <- err: + default: + } + return err + } + } + // Joined sessions release host capacity before an explicit retry/update. + for id, session := range sessions { + select { + case <-session.Done(): + if state, failure := session.Status(); state == tentacle.Failed { + runtime.logger.Warn("configured tentacle failed", "tentacle", id, "error", failure) + } + if !pending[id] { + index := slices.IndexFunc(entries, func(entry tentacle.Entry) bool { return entry.ID == id }) + if index >= 0 && entries[index].Enabled && problems[id] == "" { + problems[id] = "Tentacle stopped; retry to start it again." + runtime.report("A tentacle stopped unexpectedly.") + } + } + delete(sessions, id) + runtime.mutex.Lock() + runtime.sessions = slices.DeleteFunc(runtime.sessions, func(value *tentacle.Session) bool { return value == session }) + runtime.mutex.Unlock() + default: + } + } + if current == nil { + for id, entry := range removedPackages { + if sessions[id] != nil { + continue + } + if err := tentacle.RemovePackage(tentacle.PackageRoot(runtime.registry.Path), entry); err != nil { + runtime.logger.Warn("remove tentacle package", "error", err) + runtime.report("Tentacle was removed, but its package files could not be deleted.") + } + delete(removedPackages, id) + } + for _, entry := range entries { + if !pending[entry.ID] || sessions[entry.ID] != nil { + continue + } + pending[entry.ID] = false + err := ensureManager() + var session *tentacle.Session + if err == nil { + session, err = manager.Start(ctx, entry.Spec()) + } + if err != nil { + failStartup(entry.ID, "Tentacle could not start; check resource containment and its program, then enable it again.") + runtime.logger.Warn("start configured tentacle", "tentacle", entry.ID, "error", err) + runtime.report("A tentacle could not start.") + notify() + break + } + sessions[entry.ID] = session + runtime.mutex.Lock() + runtime.sessions = append(runtime.sessions, session) + if runtime.disabled { + session.Disable() + } + runtime.mutex.Unlock() + current, ready = session, session.Ready() + done := make(chan struct{}) + // Prune joined watcher handles so retries never accumulate history. + watchers = slices.DeleteFunc(watchers, func(done <-chan struct{}) bool { + select { + case <-done: + return true + default: + return false + } + }) + watchers = append(watchers, done) + go func() { + defer close(done) + select { + case <-session.Revoked(): + case <-ctx.Done(): + } + runtime.output.RetireRevoked() + runtime.signal_extensions() + notify() + <-session.Done() + notify() + }() + break + } + } + setSnapshot() + select { + case <-ctx.Done(): + return nil + case <-wake: + case call := <-runtime.requests: + if err := call.ctx.Err(); err != nil { + call.result <- err + continue + } + if loadError != nil { + call.result <- errors.New("tentacle registry could not be loaded; repair it and restart") + continue + } + runtime.mutex.Lock() + disabled := runtime.disabled + runtime.mutex.Unlock() + if disabled { + call.result <- tentacle.ErrDisabled + continue + } + if strings.HasPrefix(call.request.Action, "repository-") { + next, err := change_tentacle_repositories(repositories, call.request, call.repository) + if err == nil { + err = runtime.registry.SaveState(entries, next) + } + if err == nil || errors.Is(err, tentacle.ErrRegistrySync) { + repositories = next + setSnapshot() + } + call.result <- err + continue + } + if call.packageFiles != nil { + index := slices.IndexFunc(repositories, func(value tentacle.Repository) bool { return value.URL == call.repository.URL }) + if index < 0 || !reflect.DeepEqual(repositories[index], *call.repository) { + call.result <- errors.New("Repository changed during installation; refresh and try again.") + continue + } + } + if _, starting := startups[call.request.ID]; starting && call.request.Action != "disable" && call.request.Action != "remove" { + call.result <- tentacle.ErrBusy + continue + } + next, err := change_tentacle_entries(entries, call.request) + if err == nil && call.request.Action != "retry" && reflect.DeepEqual(next, entries) { + // Saved enablement is intent, not proof of a live session. An + // explicit enable/update must recover a failed or starting entry. + index := slices.IndexFunc(next, func(entry tentacle.Entry) bool { return entry.ID == call.request.ID }) + state := tentacle.Stopped + if session := sessions[call.request.ID]; session != nil { + state, _ = session.Status() + } + if !next[index].Enabled || state == tentacle.Active { + call.result <- nil + continue + } + } + if err == nil && call.request.Action != "retry" { + err = runtime.registry.Save(next) + } + if err == nil || errors.Is(err, tentacle.ErrRegistrySync) { + id := call.request.ID + replyStartup(id, errors.New("Tentacle startup was cancelled by another operation.")) + if call.packageFiles != nil { + call.packageFiles.Retain() + } + if call.request.Action == "remove" { + for _, entry := range entries { + if entry.ID == id && entry.PackageDirectory != "" { + removedPackages[id] = entry + } + } + } + revoke(id) + if current != nil && current.TentacleID() == id { + current, ready = nil, nil + } + entries = next + delete(problems, id) + delete(pending, id) + for _, entry := range entries { + if entry.ID == id { + pending[id] = entry.Enabled + } + } + // Immediately withdraw dispatch, without waiting for key release. + stillActive := slices.DeleteFunc(slices.Clone(active), func(session *tentacle.Session) bool { state, _ := session.Status(); return state != tentacle.Active }) + runtime.publishCommands(stillActive) + setSnapshot() + if pending[id] { + startups[id] = tentacleStartupCall{call: call, saveError: err, stop: context.AfterFunc(call.ctx, notify)} + continue + } + } + call.result <- err + case <-ready: + session := current + current, ready = nil, nil + if state, _ := session.Status(); state != tentacle.Ready { + failStartup(session.TentacleID(), "Tentacle failed during startup; check its program and resource limits, then enable it again.") + continue + } + if startup, exists := startups[session.TentacleID()]; exists && startup.call.ctx.Err() != nil { + failStartup(session.TentacleID(), "Tentacle startup was cancelled before activation.") + continue + } + candidate := append(slices.Clone(active), session) + if err := runtime.bind(ctx, candidate); err != nil { + session.Disable() + runtime.logger.Warn("configured tentacle bindings rejected", "tentacle", session.TentacleID(), "error", err) + runtime.report("A tentacle could not acquire its keyboard shortcuts.") + failStartup(session.TentacleID(), "Tentacle could not acquire its keyboard shortcuts; enable it again after resolving the conflict.") + continue + } + // Native binding setup can wait for held keys. Cancellation during + // that wait must roll back the new grabs before reporting failure. + activationError := ctx.Err() + if startup, exists := startups[session.TentacleID()]; exists && activationError == nil { + activationError = startup.call.ctx.Err() + } + if activationError == nil { + activationError = session.Activate() + } + if activationError != nil { + session.Disable() + if err := runtime.bind(ctx, active); err != nil && ctx.Err() == nil { + select { + case runtime.failures <- err: + default: + } + return err + } + failStartup(session.TentacleID(), "Tentacle stopped before activation; enable it again to retry.") + continue + } + active = candidate + runtime.publishCommands(active) + replyStartup(session.TentacleID(), nil) + runtime.logger.Info("configured tentacle active", "tentacle", session.TentacleID(), "session", session.Identity()) + } + } +} diff --git a/internal/app/tentacle_management_test.go b/internal/app/tentacle_management_test.go new file mode 100644 index 0000000..f223ea7 --- /dev/null +++ b/internal/app/tentacle_management_test.go @@ -0,0 +1,406 @@ +package app + +import ( + "context" + "errors" + "log/slog" + "os" + "path/filepath" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/tentacle" +) + +func managed_tentacle_fixture(t *testing.T, path string, contained bool) (*tentacleRuntime, *tentacleBindingRecorder) { + t.Helper() + bindings := &tentacleBindingRecorder{} + runtime := newTentacleRuntime(slog.New(slog.DiscardHandler), bindings, "", "auto") + runtime.registry = &tentacle.Registry{Path: path} + runtime.requests = make(chan tentacleManagementCall, 16) + if contained { + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + runtime.guardianProgram = []string{executable, "-test.run=^TestManagedTentacleGuardianPeer$", "--", "managed-guardian"} + } + if !contained { + runtime.newManager = func() (*tentacle.Manager, error) { return tentacle.NewManager(tentacle.DefaultLimits(), nil) } + } + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := runtime.Stop(ctx); err != nil { + t.Error(err) + } + }) + return runtime, bindings +} + +func manage_tentacle(t *testing.T, runtime *tentacleRuntime, action, id string, entry *tentacle.Entry) { + t.Helper() + ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second) + defer cancel() + if err := runtime.Manage(ctx, tentacle.ManagementRequest{Action: action, ID: id, Entry: entry}); err != nil { + t.Fatalf("%s: %v", action, err) + } +} + +func probe_entry(t *testing.T, id, mode string) tentacle.Entry { + t.Helper() + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + return tentacle.Entry{ID: id, Program: []string{executable, "-test.run=^TestTentacleReaderPeer$", "--", "reader-peer", filepath.Join(t.TempDir(), mode)}} +} + +func wait_managed_state(t *testing.T, runtime *tentacleRuntime, id, state string) { + t.Helper() + waitTentacle(t, func() bool { + for _, status := range runtime.Snapshot().Entries { + if status.Entry.ID == id { + return status.State == state + } + } + return false + }) +} + +func TestManagedTentaclePersistenceLifecycleAndRecovery(t *testing.T) { + path := filepath.Join(t.TempDir(), "tentacles.toml") + runtime, bindings := managed_tentacle_fixture(t, path, false) + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + first := probe_entry(t, "first", "called") + second := probe_entry(t, "second", "called") + manage_tentacle(t, runtime, "add", first.ID, &first) + manage_tentacle(t, runtime, "add", second.ID, &second) + if len(bindings.TentacleBindings()) != 0 { + t.Fatal("adding disabled entries launched them") + } + manage_tentacle(t, runtime, "enable", first.ID, nil) + wait_managed_state(t, runtime, first.ID, "active") + firstCommand := bindings.TentacleBindings()[0].Command + manage_tentacle(t, runtime, "enable", first.ID, nil) + if bindings.TentacleBindings()[0].Command != firstCommand { + t.Fatal("enable of active entry restarted it") + } + manage_tentacle(t, runtime, "enable", second.ID, nil) + wait_managed_state(t, runtime, second.ID, "active") + manage_tentacle(t, runtime, "disable", first.ID, nil) + wait_managed_state(t, runtime, first.ID, "disabled") + waitTentacle(t, func() bool { + bound := bindings.TentacleBindings() + return len(bound) > 0 && bound[0].Command != firstCommand + }) + runtime.Invoke(context.Background(), firstCommand) + if _, err := os.Stat(first.Program[len(first.Program)-1]); !os.IsNotExist(err) { + t.Fatal("stale command invoked disabled child") + } + secondCommand := bindings.TentacleBindings()[0].Command + manage_tentacle(t, runtime, "retry", second.ID, nil) + wait_managed_state(t, runtime, second.ID, "active") + if bindings.TentacleBindings()[0].Command == secondCommand { + t.Fatal("retry reused old session identity") + } + loaded, err := (&tentacle.Registry{Path: path}).Load() + if err != nil || len(loaded) != 2 || loaded[0].Enabled || !loaded[1].Enabled { + t.Fatalf("persisted state: %v %v", loaded, err) + } + runtime.Disable() + if err := runtime.Manage(context.Background(), tentacle.ManagementRequest{Action: "enable", ID: first.ID}); !errors.Is(err, tentacle.ErrDisabled) { + t.Fatalf("emergency bypass: %v", err) + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := runtime.Stop(ctx); err != nil { + t.Fatal(err) + } + restarted, _ := managed_tentacle_fixture(t, path, false) + if err := restarted.Start(context.Background()); err != nil { + t.Fatal(err) + } + wait_managed_state(t, restarted, second.ID, "active") + wait_managed_state(t, restarted, first.ID, "disabled") + manage_tentacle(t, restarted, "remove", first.ID, nil) + manage_tentacle(t, restarted, "remove", second.ID, nil) + loaded, err = (&tentacle.Registry{Path: path}).Load() + if err != nil || len(loaded) != 0 { + t.Fatalf("remove all: %v %v", loaded, err) + } + if _, err := os.Stat(second.Program[0]); err != nil { + t.Fatal("removing configuration deleted the executable") + } +} + +func TestManagedTentacleFailureRetryAndSaveFailure(t *testing.T) { + path := filepath.Join(t.TempDir(), "tentacles.toml") + runtime, bindings := managed_tentacle_fixture(t, path, false) + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + entry := probe_entry(t, "probe", "crash") + entry.Enabled = true + manage_tentacle(t, runtime, "add", entry.ID, &entry) + wait_managed_state(t, runtime, entry.ID, "active") + runtime.Invoke(context.Background(), bindings.TentacleBindings()[0].Command) + wait_managed_state(t, runtime, entry.ID, "failed") + if !runtime.Snapshot().Entries[0].Entry.Enabled { + t.Fatal("failure changed desired enablement") + } + manage_tentacle(t, runtime, "retry", entry.ID, nil) + wait_managed_state(t, runtime, entry.ID, "active") + entry.Program[len(entry.Program)-1] = filepath.Join(t.TempDir(), "called") + entry.Presentation = true + manage_tentacle(t, runtime, "update", entry.ID, &entry) + wait_managed_state(t, runtime, entry.ID, "active") + if !runtime.Snapshot().Entries[0].Entry.Presentation { + t.Fatal("grant lost") + } + if err := os.WriteFile(path, []byte("version = 1\n"), 0600); err != nil { + t.Fatal(err) + } + if err := runtime.Manage(context.Background(), tentacle.ManagementRequest{Action: "disable", ID: entry.ID}); err == nil { + t.Fatal("overwrote external edits") + } + if runtime.Snapshot().Entries[0].State != "active" { + t.Fatal("failed persistence changed runtime") + } +} + +func TestManagedTentacleEmptyAndBrokenRegistryDoNotLaunch(t *testing.T) { + for _, broken := range []bool{false, true} { + path := filepath.Join(t.TempDir(), "tentacles.toml") + if broken { + if err := os.WriteFile(path, []byte("invalid"), 0600); err != nil { + t.Fatal(err) + } + } + runtime, _ := managed_tentacle_fixture(t, path, false) + runtime.newManager = func() (*tentacle.Manager, error) { + t.Error("empty/broken registry initialized host") + return nil, tentacle.ErrUnavailable + } + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + entry := probe_entry(t, "probe", "called") + err := runtime.Manage(context.Background(), tentacle.ManagementRequest{Action: "add", ID: entry.ID, Entry: &entry}) + if (err != nil) != broken { + t.Fatalf("broken=%v: %v", broken, err) + } + if len(runtime.sessions) != 0 { + t.Fatal("launched unexpected child") + } + } +} + +func TestPreferencesTentacleOperationsAreGlobalAndSeparate(t *testing.T) { + runtime, _ := managed_tentacle_fixture(t, filepath.Join(t.TempDir(), "tentacles.toml"), false) + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), config.DefaultSettings(), nil) + worker.tentacles = runtime + entry := probe_entry(t, "probe", "called") + request := preferences.Request{Tentacle: &tentacle.ManagementRequest{Action: "add", ID: entry.ID, Entry: &entry}} + worker.editApp = "Example" + if response := worker.manage_tentacle(context.Background(), request); response.Accepted { + t.Fatal("application preferences added a program") + } + worker.editApp = "" + request.Save = true + if response := worker.manage_tentacle(context.Background(), request); response.Accepted { + t.Fatal("mixed settings request accepted") + } + request.Save = false + if response := worker.manage_tentacle(context.Background(), request); !response.Accepted || response.Tentacles == nil || len(response.Tentacles.Entries) != 1 { + t.Fatalf("add: %+v", response) + } +} + +func TestManagedTentacleGuardianPeer(t *testing.T) { + if len(os.Args) < 2 || os.Args[len(os.Args)-1] != "managed-guardian" { + return + } + if err := tentacle.RunSupervisor(context.Background()); err != nil { + os.Exit(1) + } + os.Exit(0) +} + +func TestManagedSupervisedTentacle(t *testing.T) { + runtime, bindings := managed_tentacle_fixture(t, filepath.Join(t.TempDir(), "tentacles.toml"), true) + readerGroup, err := os.ReadFile("/proc/self/cgroup") + if err != nil { + t.Fatal(err) + } + runtime.logger = slog.New(slog.NewTextHandler(os.Stderr, nil)) + defer func() { t.Logf("final status: %+v", runtime.Snapshot()) }() + executable, _ := os.Executable() + runtime.guardianProgram = []string{executable, "-test.run=^TestManagedTentacleGuardianPeer$", "--", "managed-guardian"} + if binary := os.Getenv("CTHULHU_TENTACLE_GUARDIAN_BINARY"); binary != "" { + runtime.guardianProgram = []string{binary, "--tentacle-guardian"} + } + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + entry := probe_entry(t, "probe", "called") + entry.Enabled = true + manage_tentacle(t, runtime, "add", entry.ID, &entry) + wait_managed_state(t, runtime, entry.ID, "active") + runtime.Invoke(context.Background(), bindings.TentacleBindings()[0].Command) + marker := entry.Program[len(entry.Program)-1] + waitTentacle(t, func() bool { _, err := os.Stat(marker); return err == nil }) + membership, err := os.ReadFile(marker) + if err != nil { + t.Fatal(err) + } + var aggregateGroup string + if os.Getenv("CTHULHU_TENTACLE_CGROUP_PARENT") != "" { + childGroup := filepath.Join("/sys/fs/cgroup", strings.TrimSpace(strings.TrimPrefix(string(membership), "0::"))) + aggregateGroup = filepath.Dir(childGroup) + for name, want := range map[string]string{"cpu.max": "25000 100000", "memory.max": "268435456", "pids.max": "64"} { + value, err := os.ReadFile(filepath.Join(childGroup, name)) + if err != nil || strings.TrimSpace(string(value)) != want { + t.Fatalf("%s: %q %v", name, value, err) + } + } + } + afterGroup, err := os.ReadFile("/proc/self/cgroup") + if err != nil || string(readerGroup) != string(afterGroup) { + t.Fatal("management moved the reader") + } + manage_tentacle(t, runtime, "disable", entry.ID, nil) + waitTentacle(t, func() bool { return len(bindings.TentacleBindings()) == 0 }) + manage_tentacle(t, runtime, "enable", entry.ID, nil) + wait_managed_state(t, runtime, entry.ID, "active") + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := runtime.Stop(ctx); err != nil { + t.Fatal(err) + } + if aggregateGroup != "" { + waitTentacle(t, func() bool { _, err := os.Stat(aggregateGroup); return os.IsNotExist(err) }) + } +} + +func TestManagedTentacleCancelledStartupAndConcurrentDisable(t *testing.T) { + for _, operation := range []string{"cancel", "disable", "remove"} { + t.Run(operation, func(t *testing.T) { + registryPath := filepath.Join(t.TempDir(), "tentacles.toml") + owner, bindings := managed_tentacle_fixture(t, registryPath, false) + if err := owner.Start(context.Background()); err != nil { + t.Fatal(err) + } + entry := probe_entry(t, "probe", "stall") + manage_tentacle(t, owner, "add", entry.ID, &entry) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + result := make(chan error, 1) + go func() { result <- owner.Manage(ctx, tentacle.ManagementRequest{Action: "enable", ID: entry.ID}) }() + wait_managed_state(t, owner, entry.ID, "starting") + if operation == "cancel" { + cancel() + } else { + manage_tentacle(t, owner, operation, entry.ID, nil) + } + select { + case err := <-result: + if err == nil { + t.Fatal("cancelled startup reported success") + } + case <-time.After(5 * time.Second): + t.Fatal("startup cancellation did not complete") + } + snapshot := owner.Snapshot() + if operation == "remove" { + if len(snapshot.Entries) != 0 { + t.Fatal(snapshot) + } + } else if len(snapshot.Entries) != 1 || snapshot.Entries[0].Entry.Enabled { + t.Fatal(snapshot) + } + if len(bindings.TentacleBindings()) != 0 { + t.Fatal("cancelled startup published bindings") + } + disk, err := (&tentacle.Registry{Path: registryPath}).Load() + if err != nil || len(disk) > 0 && disk[0].Enabled { + t.Fatalf("cancelled startup remained enabled: %+v %v", disk, err) + } + }) + } +} + +func TestManagedTentacleEnableRestartsFailedSession(t *testing.T) { + owner, bindings := managed_tentacle_fixture(t, filepath.Join(t.TempDir(), "tentacles.toml"), false) + if err := owner.Start(context.Background()); err != nil { + t.Fatal(err) + } + entry := probe_entry(t, "probe", "crash") + entry.Enabled = true + manage_tentacle(t, owner, "add", entry.ID, &entry) + command := bindings.TentacleBindings()[0].Command + owner.Invoke(context.Background(), command) + wait_managed_state(t, owner, entry.ID, "failed") + manage_tentacle(t, owner, "enable", entry.ID, nil) + status := owner.Snapshot().Entries[0] + if status.State != "active" || !status.Entry.Enabled || status.Message != "" { + t.Fatalf("enable reported success without restarting: %+v", status) + } + if current := bindings.TentacleBindings(); len(current) != 1 || current[0].Command == command { + t.Fatalf("enable did not publish a new session: %+v", current) + } +} + +type cancellingTentacleBindings struct { + *tentacleBindingRecorder + cancel context.CancelFunc +} + +func (bindings *cancellingTentacleBindings) SetTentacleBindings(ctx context.Context, next []input.BindingOverride) error { + err := bindings.tentacleBindingRecorder.SetTentacleBindings(ctx, next) + if len(next) > 1 { + // Cancellation arrives after native grabs succeed, before activation. + bindings.cancel() + } + return err +} + +func TestManagedTentacleCancellationDuringBindingsRollsBack(t *testing.T) { + path := filepath.Join(t.TempDir(), "tentacles.toml") + owner, bindings := managed_tentacle_fixture(t, path, false) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + owner.input = &cancellingTentacleBindings{tentacleBindingRecorder: bindings, cancel: cancel} + if err := owner.Start(context.Background()); err != nil { + t.Fatal(err) + } + first := probe_entry(t, "first", "called") + first.Enabled = true + manage_tentacle(t, owner, "add", first.ID, &first) + firstCommand := bindings.TentacleBindings()[0].Command + second := probe_entry(t, "second", "called") + manage_tentacle(t, owner, "add", second.ID, &second) + if err := owner.Manage(ctx, tentacle.ManagementRequest{Action: "enable", ID: second.ID}); err == nil { + t.Fatal("startup cancelled during binding reported success") + } + status := owner.Snapshot().Entries + if len(status) != 2 || status[0].State != "active" || status[1].Entry.Enabled { + t.Fatalf("incorrect rollback state: %+v", status) + } + if current := bindings.TentacleBindings(); len(current) != 1 || current[0].Command != firstCommand { + t.Fatalf("rollback did not preserve the first session's bindings: %+v", current) + } + disk, err := (&tentacle.Registry{Path: path}).Load() + if err != nil || len(disk) != 2 || !disk[0].Enabled || disk[1].Enabled { + t.Fatalf("incorrect persisted rollback: %+v %v", disk, err) + } +} diff --git a/internal/app/tentacle_output.go b/internal/app/tentacle_output.go new file mode 100644 index 0000000..ae9512a --- /dev/null +++ b/internal/app/tentacle_output.go @@ -0,0 +1,141 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "sync" + + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type tentacleOutputTicket struct { + ctx context.Context + session context.Context + speechGeneration uint64 + speechRevision uint64 + brailleSequence uint64 +} + +// tentacleOutput owns one explicit command's presentation lifetime. Any later +// command, foreground/mode transition or accessibility event retires it. This +// deliberately conservative revision gate exposes no accessible text/positions. +// Speech's interruption generation and braille's frame sequence are independent. +// Lock order: runtime, focus gate, output owner, then speech/braille owner. +type tentacleOutput struct { + mutex sync.Mutex + speech *speechWorker + braille *brailleWorker + gate *focusGate + live *liveSettings + current context.Context + cancel context.CancelFunc +} + +func (owner *tentacleOutput) Capture(parent context.Context) tentacleOutputTicket { + if owner == nil { + return tentacleOutputTicket{} + } + owner.mutex.Lock() + defer owner.mutex.Unlock() + owner.retireLocked() + ctx, cancel := context.WithCancel(parent) + owner.current, owner.cancel = ctx, cancel + ticket := tentacleOutputTicket{ctx: ctx, session: parent} + if owner.speech != nil { + owner.speech.mutex.Lock() + ticket.speechGeneration = owner.speech.generation + ticket.speechRevision = owner.speech.presentationRevision + owner.speech.mutex.Unlock() + } + if owner.braille != nil { + owner.braille.mu.Lock() + ticket.brailleSequence = owner.braille.sequence + owner.braille.mu.Unlock() + } + return ticket +} + +func (owner *tentacleOutput) Retire() { + if owner == nil { + return + } + owner.mutex.Lock() + defer owner.mutex.Unlock() + owner.retireLocked() +} + +// Stop additionally revokes accepted protected speech during reader shutdown, +// screen lock or explicit disable. Ordinary retirement only retires replies. +func (owner *tentacleOutput) Stop() { + if owner == nil { + return + } + owner.mutex.Lock() + defer owner.mutex.Unlock() + owner.retireLocked() + if owner.speech != nil { + owner.speech.stop_uninterruptible() + } +} + +func (owner *tentacleOutput) RetireRevoked() { + if owner == nil { + return + } + owner.mutex.Lock() + defer owner.mutex.Unlock() + if owner.current != nil && owner.current.Err() != nil { + owner.retireLocked() + } +} + +func (owner *tentacleOutput) retireLocked() { + if owner.cancel == nil { + return + } + owner.cancel() + if owner.braille != nil { + owner.braille.retirePresentation(owner.current) + } + owner.current, owner.cancel = nil, nil +} + +func (owner *tentacleOutput) Present(ticket tentacleOutputTicket, value tentaclewire.Presentation, command string) { + if owner == nil || ticket.ctx == nil { + return + } + if owner.gate != nil { + owner.gate.mutex.Lock() + defer owner.gate.mutex.Unlock() + } + owner.mutex.Lock() + defer owner.mutex.Unlock() + if ticket.ctx != owner.current || ticket.ctx.Err() != nil || owner.gate.Locked() || owner.gate.Suspended() { + return + } + if value.Speech != "" && owner.speech != nil { + request := speechRequest{Text: value.Speech, Role: "system", Cause: command, + context: ticket.ctx, presentationGeneration: &ticket.speechGeneration, presentationRevision: &ticket.speechRevision} + if value.Uninterruptible { + // Admission still checks the ticket; accepted speech belongs to the + // session so subsequent focus/command changes cannot cancel it. + request.Uninterruptible = true + request.context, request.cancel = context.WithTimeout(ticket.session, uninterruptibleSpeechTimeout) + } + owner.speech.Enqueue(request) + } + if value.Braille != "" && owner.braille != nil && owner.live != nil { + settings := owner.live.Load() + if settings.EnableBraille { + if owner.braille.flash_message_guarded(value.Braille, settings.Braille, false, ticket.ctx, ticket.brailleSequence) { + owner.braille.mu.Lock() + if owner.braille.flashContext == ticket.ctx { + owner.braille.logger.Debug("queued tentacle braille message", "command", command, + "frame_id", owner.braille.frame.ID, "braille_text", owner.braille.frame.Text) + } + owner.braille.mu.Unlock() + } + } + } +} diff --git a/internal/app/tentacle_output_test.go b/internal/app/tentacle_output_test.go new file mode 100644 index 0000000..becbdcc --- /dev/null +++ b/internal/app/tentacle_output_test.go @@ -0,0 +1,197 @@ +package app + +import ( + "context" + "log/slog" + "testing" + + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +func tentacleOutputFixture(t *testing.T) *tentacleOutput { + t.Helper() + live := &liveSettings{} + settings := config.DefaultSettings() + settings.EnableBraille = true + settings.Braille.FlashMessages = true + settings.Braille.FlashPersistent = true + live.Store(settings) + display := &brailleWorker{logger: slog.New(slog.DiscardHandler), cancel: func() {}, connected: true, wake: make(chan struct{}, 1), + frame: braille.Frame{Text: "Core focus", Cursor: -1}, baseFrame: braille.Frame{Text: "Core focus", Cursor: -1}} + speech := newSpeechWorker(slog.New(slog.DiscardHandler), nil) + speech.workerContext = t.Context() + speech.running = true // Inspect the bounded queue without a delivery goroutine. + owner := &tentacleOutput{speech: speech, braille: display, gate: newFocusGate(nil), live: live} + owner.gate.tentacleOutput = owner + t.Cleanup(owner.Retire) + return owner +} + +func TestTentacleIndependentOutputOwnership(t *testing.T) { + for _, change := range []string{"none", "speech interrupt", "new speech", "new braille", "braille disabled", "flashes disabled"} { + t.Run(change, func(t *testing.T) { + owner := tentacleOutputFixture(t) + ticket := owner.Capture(context.Background()) + expectSpeech, expectBraille := true, true + switch change { + case "speech interrupt": + owner.speech.InterruptForUser() + expectSpeech = false + case "new speech": + owner.speech.Enqueue(speechRequest{Text: "New core speech"}) + expectSpeech = false + case "new braille": + owner.braille.Enqueue("New core braille") + expectBraille = false + case "braille disabled": + settings := owner.live.Load() + settings.EnableBraille = false + owner.live.Store(settings) + expectBraille = false + case "flashes disabled": + settings := owner.live.Load() + settings.Braille.FlashMessages = false + owner.live.Store(settings) + expectBraille = false + } + owner.Present(ticket, tentaclewire.Presentation{Speech: "Tentacle speech", Braille: "Tentacle braille"}, "tentacle/test/probe") + gotSpeech := false + for _, request := range owner.speech.pending { + if request.Text == "Tentacle speech" { + gotSpeech = true + if request.context != owner.speech.workerContext || request.ForceSpeech || request.BypassFocusGate || request.Role != "system" { + t.Fatal("unsafe speech request") + } + } + } + if gotSpeech != expectSpeech || (owner.braille.current().Text == "Tentacle braille") != expectBraille { + t.Fatal("channel ownership bypassed") + } + if len(owner.braille.current().Routes) != 0 { + t.Fatal("message gained routing targets") + } + }) + } +} + +func TestTentacleRetiredAndBufferedOutput(t *testing.T) { + for _, change := range []string{"revision", "new command", "revoked", "handoff and resume", "lock and unlock"} { + t.Run(change, func(t *testing.T) { + owner := tentacleOutputFixture(t) + parent, cancel := context.WithCancel(context.Background()) + defer cancel() + ticket := owner.Capture(parent) + switch change { + case "revision": + owner.gate.retireTentacleOutput() + case "new command": + owner.Capture(context.Background()) + case "revoked": + cancel() + case "handoff and resume": + owner.gate.SetSuspended(true) + owner.gate.SetSuspended(false) + case "lock and unlock": + owner.gate.SetLocked(true, nil, nil, nil, owner.speech, owner.braille) + owner.gate.SetLocked(false, nil, nil, nil, owner.speech, owner.braille) + } + owner.Present(ticket, tentaclewire.Presentation{Speech: "Late speech", Braille: "Late braille"}, "tentacle/test/probe") + if len(owner.speech.pending) != 0 || owner.braille.current().Text == "Late braille" { + t.Fatal("retired output was accepted") + } + }) + } +} + +func TestTentacleAcceptedOutputRetirement(t *testing.T) { + for _, newer := range []bool{false, true} { + owner := tentacleOutputFixture(t) + parent, cancel := context.WithCancel(context.Background()) + ticket := owner.Capture(parent) + owner.Present(ticket, tentaclewire.Presentation{Speech: "Queued speech", Braille: "Tentacle flash"}, "tentacle/test/probe") + if len(owner.speech.pending) != 1 || owner.braille.current().Text != "Tentacle flash" { + t.Fatal("presentation not queued") + } + if newer { + owner.speech.Enqueue(speechRequest{Text: "New core output"}) + owner.braille.Flash("New core flash", owner.live.Load().Braille) + } + cancel() // Retiring the reply cannot cut off speech already accepted. + if !newer && owner.braille.current().Text != "Core focus" { + t.Fatal("revoked flash survived consumption") + } + owner.RetireRevoked() + if len(owner.speech.pending) == 0 || owner.speech.pending[0].Text != "Queued speech" || owner.speech.pending[0].context.Err() != nil { + t.Fatal("retirement discarded accepted speech") + } + if newer && (owner.braille.current().Text != "New core flash" || len(owner.speech.pending) != 2 || owner.speech.pending[1].Text != "New core output") { + t.Fatal("retirement displaced core output") + } + } +} + +func TestTentacleInitiatingInputAndLaterInterruption(t *testing.T) { + owner := tentacleOutputFixture(t) + owner.speech.ProtectCommand(100) + ticket := owner.Capture(context.Background()) + if owner.speech.InterruptForInput(input.Event{Timestamp: 100, Pressed: true}) { + t.Fatal("initiating chord interrupted command") + } + owner.Present(ticket, tentaclewire.Presentation{Speech: "Command result"}, "tentacle/test/probe") + if len(owner.speech.pending) != 1 { + t.Fatal("initiating input retired speech") + } + owner.speech.InterruptForInput(input.Event{Timestamp: 101, Pressed: true}) + if len(owner.speech.pending) != 0 { + t.Fatal("later input failed to interrupt") + } +} + +func TestTentacleCoreSpeechModes(t *testing.T) { + for _, mode := range []speechMode{speechModeSpeech, speechModeBeeps, speechModeOff} { + t.Run(mode.announcement(), func(t *testing.T) { + owner := tentacleOutputFixture(t) + speaker := &fakeSpeaker{spoken: make(chan string, 1)} + owner.speech.speaker = speaker + owner.speech.mode = mode + beeps := 0 + owner.speech.beep = func(context.Context) error { beeps++; return nil } + ticket := owner.Capture(context.Background()) + owner.Present(ticket, tentaclewire.Presentation{Speech: "Hello from a tentacle.", Braille: "Display message"}, "tentacle/test/probe") + request, ok := owner.speech.next() + if !ok { + t.Fatal("no queued presentation") + } + if err := owner.speech.deliver(request.context, request); err != nil { + t.Fatal(err) + } + if (len(speaker.spoken) == 1) != (mode == speechModeSpeech) || (beeps == 1) != (mode == speechModeBeeps) { + t.Fatal("tentacle bypassed core speech mode") + } + if owner.braille.current().Text != "Display message" { + t.Fatal("speech mode suppressed independent braille") + } + }) + } +} + +func TestTentacleRevocationPreservesQueuedCoreSpeech(t *testing.T) { + owner := tentacleOutputFixture(t) + speaker := &controlledSpeaker{calls: make(chan speechCall, 10)} + owner.speech.speaker = speaker + owner.speech.running = false + if err := owner.speech.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { owner.speech.Stop(context.Background()) }) + ticket := owner.Capture(context.Background()) + owner.Present(ticket, tentaclewire.Presentation{Speech: "Tentacle output"}, "tentacle/test/probe") + active := expectSpeechCall(t, speaker, "Tentacle output") + owner.speech.Enqueue(speechRequest{Text: "Later core speech", Append: true}) + owner.Retire() + close(active.done) + close(expectSpeechCall(t, speaker, "Later core speech").done) +} diff --git a/internal/app/tentacle_reader.go b/internal/app/tentacle_reader.go new file mode 100644 index 0000000..5cf9dbd --- /dev/null +++ b/internal/app/tentacle_reader.go @@ -0,0 +1,643 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "encoding/json" + "errors" + "path/filepath" + "reflect" + "sort" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/tentacle" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type readerExtension struct { + session *tentacle.Session + value tentaclewire.Extensions + revision uint64 +} + +type readerSettingsCall struct { + ctx context.Context + session *tentacle.Session + request tentaclewire.ReaderRequest + result chan readerSettingsResult +} +type readerSettingsResult struct { + state *tentaclewire.ReaderState + err error +} +type readerTransaction struct { + extensions map[string]*readerExtension + override *tentaclewire.SpeechConfiguration + owner string +} + +func copy_reader_value[T any](value T) T { + data, _ := json.Marshal(value) + var result T + _ = json.Unmarshal(data, &result) + return result +} + +func (runtime *tentacleRuntime) signal_extensions() { + if runtime == nil { + return + } + select { + case runtime.extensionChanges <- struct{}{}: + default: + } +} +func (worker *preferencesWorker) extension_changes() <-chan struct{} { + if worker.tentacles == nil { + return nil + } + return worker.tentacles.extensionChanges +} +func (runtime *tentacleRuntime) reader_sessions() map[string]*tentacle.Session { + sessions := map[string]*tentacle.Session{} + if runtime == nil { + return sessions + } + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + if runtime.disabled { + return sessions + } + for _, command := range runtime.commands { + if state, _ := command.session.Status(); command.reader && state == tentacle.Active { + sessions[command.session.Identity()] = command.session + } + } + return sessions +} + +// Called only by the settings owner. Revocation wakes this mailbox even if no +// preferences window is open. No native input callback waits for restoration. +func (worker *preferencesWorker) sync_extensions(ctx context.Context) { + if ctx.Err() != nil { + return + } + sessions := worker.tentacles.reader_sessions() + if worker.extensions == nil { + worker.extensions = map[string]*readerExtension{} + } + for id := range worker.extensions { + if sessions[id] == nil { + delete(worker.extensions, id) + } + } + for id, session := range sessions { + if worker.extensions[id] != nil { + continue + } + value := session.Extensions() + worker.load_page_store() + for index := range value.Pages { + page := &value.Pages[index] + if saved := worker.savedPages[session.TentacleID()][page.ID]; saved != nil && tentaclewire.ValidatePageValues(*page, saved) == nil { + page.Values = copy_reader_value(saved) + } + } + worker.extensionRevision++ + worker.extensions[id] = &readerExtension{session: session, value: value, revision: worker.extensionRevision} + if err := validate_reader_extensions(worker.extensions); err != nil { + delete(worker.extensions, id) + session.Disable() + worker.announceSpeechSetting("A tentacle exceeded the reader settings limits and was disabled.") + } + } + if worker.speechOverride != nil && sessions[worker.speechOverrideOwner] == nil { + restoreCtx, cancel := context.WithTimeout(ctx, 6*time.Second) + var err error + if worker.settings.EnableSpeech { + err = worker.updateSpeech(restoreCtx, worker.settings) + } + cancel() + if err != nil { + worker.logger.Error("restore speech after tentacle revocation", "error", err) + worker.announceSpeechSetting("The tentacle stopped, but normal speech settings could not be restored. The working voice has been retained.") + return + } + worker.speechOverride, worker.speechOverrideOwner = nil, "" + if worker.live != nil { + worker.live.Store(worker.settings) + } + } +} +func (worker *preferencesWorker) load_page_store() { + if worker.pageStore != nil { + return + } + worker.pageStore = &tentacle.PageStore{Path: filepath.Join(filepath.Dir(worker.settings.Path), "tentacle-preferences.json")} + worker.savedPages, worker.pageLoadError = worker.pageStore.Load() + if worker.savedPages == nil { + worker.savedPages = tentacle.PageValues{} + } + if worker.pageLoadError != nil { + worker.logger.Warn("load tentacle preferences", "error", worker.pageLoadError) + } +} + +func (worker *preferencesWorker) effective_settings(base config.Settings) config.Settings { + if worker.speechOverride != nil { + return worker.speechOverride.Apply(base) + } + return base +} +func (worker *preferencesWorker) extension_pages() []preferences.ExtensionPage { + if worker.editApp != "" { + return nil + } + var pages []preferences.ExtensionPage + for _, id := range sorted_extension_ids(worker.extensions) { + extension := worker.extensions[id] + for _, page := range extension.value.Pages { + pages = append(pages, preferences.ExtensionPage{Session: id, Revision: extension.revision, PreferencePage: copy_reader_value(page)}) + } + } + return pages +} +func sorted_extension_ids(extensions map[string]*readerExtension) []string { + ids := make([]string, 0, len(extensions)) + for id := range extensions { + ids = append(ids, id) + } + sort.Slice(ids, func(i, j int) bool { + left, right := extensions[ids[i]].session.TentacleID(), extensions[ids[j]].session.TentacleID() + if left != right { + return left < right + } + return ids[i] < ids[j] + }) + return ids +} +func (worker *preferencesWorker) reader_state(extension *readerExtension) tentaclewire.ReaderState { + return copy_reader_value(tentaclewire.ReaderState{Speech: tentaclewire.SpeechFromSettings(worker.effective_settings(worker.settings)), DefaultSpeech: tentaclewire.SpeechFromSettings(worker.settings), Extensions: extension.value}) +} +func (worker *preferencesWorker) request_reader(ctx context.Context, session *tentacle.Session, request tentaclewire.ReaderRequest) (*tentaclewire.ReaderState, error) { + call := readerSettingsCall{ctx: ctx, session: session, request: request, result: make(chan readerSettingsResult, 1)} + select { + case worker.extensionRequests <- call: + case <-ctx.Done(): + return nil, ctx.Err() + default: + return nil, tentacle.ErrBusy + } + select { + case result := <-call.result: + return result.state, result.err + case <-ctx.Done(): + return nil, ctx.Err() + case <-worker.done: + return nil, tentacle.ErrUnavailable + } +} +func (worker *preferencesWorker) handle_reader_call(ctx context.Context, call readerSettingsCall, windowOpen bool) { + callCtx, cancel := context.WithCancel(ctx) + defer cancel() + stop := context.AfterFunc(call.ctx, cancel) + defer stop() + if call.session != nil { + stopSession := context.AfterFunc(call.session.OutputContext(), cancel) + defer stopSession() + } + worker.sync_extensions(ctx) + state, err := worker.apply_reader_request(callCtx, call.session, call.request, windowOpen) + call.result <- readerSettingsResult{state, err} +} +func (worker *preferencesWorker) reader_allowed(ctx context.Context, session *tentacle.Session) error { + if err := ctx.Err(); err != nil { + return err + } + if session == nil { + return tentacle.ErrUnavailable + } + if state, _ := session.Status(); state != tentacle.Active || worker.extensions[session.Identity()] == nil { + return tentacle.ErrUnavailable + } + if worker.tentacles != nil && worker.tentacles.output != nil && worker.tentacles.output.gate != nil { + if worker.tentacles.output.gate.Locked() || worker.tentacles.output.gate.Suspended() { + return errors.New("reader interaction is unavailable") + } + } + return nil +} +func (worker *preferencesWorker) reader_transaction() readerTransaction { + extensions := map[string]*readerExtension{} + for id, extension := range worker.extensions { + extensions[id] = &readerExtension{session: extension.session, value: copy_reader_value(extension.value), revision: extension.revision} + } + return readerTransaction{extensions, copy_reader_value(worker.speechOverride), worker.speechOverrideOwner} +} +func (worker *preferencesWorker) stage_reader_request(ctx context.Context, transaction *readerTransaction, session *tentacle.Session, request tentaclewire.ReaderRequest) error { + if err := worker.reader_allowed(ctx, session); err != nil { + return err + } + if err := tentaclewire.ValidateReaderRequest(request); err != nil { + return err + } + id := session.Identity() + if request.Extensions != nil { + allowed := map[string]bool{} + for _, command := range session.Commands() { + if command.Reader && !command.Settings { + allowed[command.ID] = true + } + } + for _, page := range request.Extensions.Pages { + if !allowed[page.Command] { + return tentacle.ErrProtocol + } + } + for _, setting := range request.Extensions.QuickSettings { + if !allowed[setting.Command] { + return tentacle.ErrProtocol + } + } + transaction.extensions[id].value = copy_reader_value(*request.Extensions) + transaction.extensions[id].revision++ + } + if request.Speech != nil || request.RestoreSpeech { + if transaction.override != nil && transaction.owner != id { + return errors.New("another tentacle owns the active speech override") + } + if request.RestoreSpeech { + transaction.override, transaction.owner = nil, "" + } else { + next := request.Speech.Apply(worker.settings) + if err := config.Validate(next); err != nil { + return err + } + transaction.override, transaction.owner = copy_reader_value(request.Speech), id + } + } + return validate_reader_extensions(transaction.extensions) +} +func (worker *preferencesWorker) commit_reader_transaction(ctx context.Context, session *tentacle.Session, transaction readerTransaction) error { + if err := worker.reader_allowed(ctx, session); err != nil { + return err + } + next := worker.settings + if transaction.override != nil { + next = transaction.override.Apply(next) + } + if !reflect.DeepEqual(transaction.override, worker.speechOverride) && next.EnableSpeech { + operationCtx, cancel := context.WithTimeout(ctx, 6*time.Second) + stop := context.AfterFunc(session.OutputContext(), cancel) + err := worker.updateSpeech(operationCtx, next) + stop() + cancel() + if err != nil { + return err + } + if err := worker.reader_allowed(ctx, session); err != nil { + restoreCtx, restoreCancel := context.WithTimeout(context.Background(), 6*time.Second) + defer restoreCancel() + if restoreErr := worker.updateSpeech(restoreCtx, worker.effective_settings(worker.settings)); restoreErr != nil { + worker.logger.Error("restore revoked speech transaction", "error", restoreErr) + } + return err + } + } + worker.extensions = transaction.extensions + worker.speechOverride, worker.speechOverrideOwner = transaction.override, transaction.owner + if worker.live != nil { + worker.live.Store(next) + } + return nil +} +func (worker *preferencesWorker) apply_reader_request(ctx context.Context, session *tentacle.Session, request tentaclewire.ReaderRequest, windowOpen bool) (*tentaclewire.ReaderState, error) { + if err := worker.reader_allowed(ctx, session); err != nil { + return nil, err + } + if windowOpen && (request.Speech != nil || request.RestoreSpeech || request.Extensions != nil) { + return nil, errors.New("close preferences before changing reader settings from a command") + } + transaction := worker.reader_transaction() + if err := worker.stage_reader_request(ctx, &transaction, session, request); err != nil { + return nil, err + } + if err := worker.commit_reader_transaction(ctx, session, transaction); err != nil { + return nil, err + } + state := worker.reader_state(worker.extensions[session.Identity()]) + if request.Snapshot { + catalogCtx, cancel := context.WithTimeout(ctx, 4*time.Second) + catalog, err := worker.discover(catalogCtx, worker.socket) + cancel() + if err != nil { + return &state, errors.New("speech voice catalog is unavailable") + } + for module := range catalog { + if module != "" { + state.Modules = append(state.Modules, module) + } + } + sort.Strings(state.Modules) + state.Voices = append(state.Voices, catalog[request.Module]...) + // Keep a continuation below the RPC argument limit, explicitly marking + // partial catalogs instead of silently dropping voices. + for { + data, _ := json.Marshal(tentaclewire.Submission{Reader: &state}) + if len(data) <= tentacle.MaxReaderArgumentBytes { + break + } + state.CatalogTruncated = true + if len(state.Voices) > 0 { + state.Voices = state.Voices[:len(state.Voices)/2] + } else if len(state.Modules) > 0 { + state.Modules = state.Modules[:len(state.Modules)/2] + } else { + return nil, tentacle.ErrLimit + } + } + } + return &state, nil +} + +func (worker *preferencesWorker) extension_effect(ctx context.Context, extension *readerExtension, command string, event tentaclewire.ExtensionEvent) (tentaclewire.ReaderRequest, error) { + arguments := any(event) + for transition := 0; transition < 16; transition++ { + if err := worker.reader_allowed(ctx, extension.session); err != nil { + return tentaclewire.ReaderRequest{}, err + } + data, err := json.Marshal(arguments) + if err != nil { + return tentaclewire.ReaderRequest{}, err + } + replies, err := extension.session.Invoke(ctx, command, data) + if err != nil { + return tentaclewire.ReaderRequest{}, err + } + result := <-replies + if result.Err != nil { + return tentaclewire.ReaderRequest{}, result.Err + } + value, err := tentaclewire.DecodeInteraction(result.Value) + if err != nil || value.Reader == nil || value.Form != nil || value.Poll != "" || value.Source != "" || value.Clipboard != nil || value.Speech != "" || value.Braille != "" { + return tentaclewire.ReaderRequest{}, errors.New("extension callback must return only a reader settings proposal") + } + if !value.Reader.Snapshot { + if value.Next != "" { + return tentaclewire.ReaderRequest{}, tentacle.ErrProtocol + } + return *value.Reader, nil + } + if !worker.tentacles.reader_continuation(tentacleCommand{session: extension.session}, value.Next) { + return tentaclewire.ReaderRequest{}, tentacle.ErrProtocol + } + state, snapshotErr := worker.apply_reader_request(ctx, extension.session, *value.Reader, true) + submission := tentaclewire.Submission{Reader: state} + if snapshotErr != nil { + submission.Error = snapshotErr.Error() + } + arguments, command = submission, value.Next + } + return tentaclewire.ReaderRequest{}, errors.New("reader callback continuation limit reached") +} + +// Optional page loading happens before GTK constructs controls. Handlers may +// inspect the reader/catalog and replace declarations, but cannot apply speech. +func (worker *preferencesWorker) load_extension_pages(ctx context.Context) error { + loadCtx, cancel := context.WithTimeout(ctx, 6*time.Second) + defer cancel() + var failures error + for _, view := range worker.extension_pages() { + if !view.Load { + continue + } + extension := worker.extensions[view.Session] + if extension == nil { + continue + } + event := tentaclewire.ExtensionEvent{Event: "preferences.open", ID: view.ID, Reader: worker.reader_state(extension)} + request, err := worker.extension_effect(loadCtx, extension, view.Command, event) + if err == nil && (request.Speech != nil || request.RestoreSpeech || request.Extensions == nil) { + err = errors.New("opening a preference page may only update its declarations") + } + transaction := worker.reader_transaction() + if err == nil { + err = worker.stage_reader_request(loadCtx, &transaction, extension.session, request) + } + if err == nil { + worker.extensions = transaction.extensions + } else { + failures = errors.Join(failures, err) + } + } + worker.sync_extensions(ctx) + return failures +} + +func (worker *preferencesWorker) prepare_extension_pages(ctx context.Context, drafts []preferences.PageDraft) (readerTransaction, error) { + worker.sync_extensions(ctx) + transaction := worker.reader_transaction() + if len(drafts) == 0 { + return transaction, nil + } + if worker.editApp != "" || worker.choosingApplication { + return transaction, errors.New("tentacle pages are global preferences") + } + seen := map[string]bool{} + speechProposals := 0 + for _, draft := range drafts { + key := draft.Session + "/" + draft.ID + extension := worker.extensions[draft.Session] + if extension == nil || extension.revision != draft.Revision || seen[key] { + return transaction, errors.New("tentacle page changed or was removed; reopen preferences") + } + seen[key] = true + var page *tentaclewire.PreferencePage + for _, candidate := range extension.value.Pages { + if candidate.ID == draft.ID { + copy := candidate + page = © + break + } + } + if page == nil { + return transaction, tentacle.ErrProtocol + } + if err := tentaclewire.ValidatePageValues(*page, draft.Values); err != nil { + return transaction, err + } + for _, element := range page.Elements { + if element.Disabled && !reflect.DeepEqual(page.Values[element.ID], draft.Values[element.ID]) { + return transaction, tentacle.ErrProtocol + } + } + if reflect.DeepEqual(page.Values, draft.Values) { + continue + } + event := tentaclewire.ExtensionEvent{Event: "preferences.apply", ID: page.ID, Values: draft.Values, Reader: worker.reader_state(extension)} + request, err := worker.extension_effect(ctx, extension, page.Command, event) + if err != nil { + return transaction, err + } + if request.Speech != nil || request.RestoreSpeech { + speechProposals++ + } + if speechProposals > 1 { + return transaction, errors.New("multiple pages proposed conflicting speech changes") + } + if err := worker.stage_reader_request(ctx, &transaction, extension.session, request); err != nil { + return transaction, err + } + staged := transaction.extensions[draft.Session] + found := false + for index := range staged.value.Pages { + if staged.value.Pages[index].ID == page.ID { + // A callback may replace choices or normalize input. Otherwise + // the successfully submitted draft becomes its committed value. + if request.Extensions == nil { + staged.value.Pages[index].Values = copy_reader_value(draft.Values) + } + found = true + } + } + if !found { + return transaction, errors.New("an applied page cannot remove itself") + } + staged.revision++ + } + return transaction, validate_reader_extensions(transaction.extensions) +} + +func validate_reader_extensions(extensions map[string]*readerExtension) error { + total := 0 + for _, extension := range extensions { + if err := tentaclewire.ValidateExtensions(extension.value); err != nil { + return err + } + data, err := json.Marshal(extension.value) + if err != nil { + return err + } + total += len(data) + } + if total > 256*1024 { + return tentacle.ErrLimit + } + return nil +} +func (worker *preferencesWorker) save_extension_pages() error { + if worker.pageStore == nil { + return nil + } + if worker.pageLoadError != nil { + return worker.pageLoadError + } + values := copy_reader_value(worker.savedPages) + if values == nil { + values = tentacle.PageValues{} + } + for _, extension := range worker.extensions { + pages := map[string]map[string]interaction.Value{} + for _, page := range extension.value.Pages { + pages[page.ID] = copy_reader_value(page.Values) + } + if len(pages) > 0 { + values[extension.session.TentacleID()] = pages + } + } + if reflect.DeepEqual(values, worker.savedPages) { + return nil + } + if err := worker.pageStore.Save(values); err != nil { + return err + } + worker.savedPages = values + return nil +} + +type readerQuickSetting struct { + key string + extension *readerExtension + setting tentaclewire.QuickSetting +} + +func (worker *preferencesWorker) quick_settings() []readerQuickSetting { + var result []readerQuickSetting + for _, id := range sorted_extension_ids(worker.extensions) { + extension := worker.extensions[id] + for _, setting := range extension.value.QuickSettings { + result = append(result, readerQuickSetting{id + "/" + setting.ID, extension, setting}) + } + } + return result +} +func (worker *preferencesWorker) handle_extension_quick(ctx context.Context, setting readerQuickSetting, adjust bool, delta int) { + selected := 0 + for index, option := range setting.setting.Options { + if option.ID == setting.setting.Selected { + selected = index + break + } + } + candidate := selected + if adjust { + for index := selected + delta; index >= 0 && index < len(setting.setting.Options); index += delta { + if !setting.setting.Options[index].Disabled { + candidate = index + break + } + } + } + option := setting.setting.Options[candidate] + if candidate != selected { + event := tentaclewire.ExtensionEvent{Event: "quick-setting", ID: setting.setting.ID, Selected: option.ID, Reader: worker.reader_state(setting.extension)} + request, err := worker.extension_effect(ctx, setting.extension, setting.setting.Command, event) + transaction := worker.reader_transaction() + if err == nil { + err = worker.stage_reader_request(ctx, &transaction, setting.extension.session, request) + } + if err == nil { + found := false + extension := transaction.extensions[setting.extension.session.Identity()] + for index := range extension.value.QuickSettings { + current := &extension.value.QuickSettings[index] + if current.ID != setting.setting.ID { + continue + } + for _, choice := range current.Options { + if choice.ID == option.ID && !choice.Disabled { + current.Selected = option.ID + found = true + break + } + } + } + if !found { + err = errors.New("selected quick setting was removed by its callback") + } + } + if err == nil { + err = worker.commit_reader_transaction(ctx, setting.extension.session, transaction) + } + if err != nil { + worker.logger.Warn("apply tentacle quick setting", "error", err) + worker.announceSpeechSetting(setting.setting.Label + " was not changed") + return + } + } + worker.announceSpeechSetting(setting.setting.Label + " " + option.Label) +} + +func (runtime *tentacleRuntime) reader_continuation(command tentacleCommand, id string) bool { + for _, registered := range command.session.Commands() { + if registered.ID == id { + return registered.Reader && !registered.Settings + } + } + return false +} diff --git a/internal/app/tentacle_reader_test.go b/internal/app/tentacle_reader_test.go new file mode 100644 index 0000000..c6934e4 --- /dev/null +++ b/internal/app/tentacle_reader_test.go @@ -0,0 +1,665 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "log/slog" + "os" + "path/filepath" + "reflect" + "strconv" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/speech" + "git.stormux.org/storm/cthulhu/internal/tentacle" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" + sdk "git.stormux.org/storm/cthulhu/sdk/go/tentacle" +) + +// A private protocol fixture, not an installable or bundled tentacle. +func reader_probe_extensions() sdk.Extensions { + return sdk.Extensions{Pages: []sdk.PreferencePage{{ID: "probe", Title: "Extension probe", Command: "apply", Elements: []sdk.Element{ + {ID: "rate", Label: "Probe rate", Kind: sdk.Entry, Required: true, MaxLength: 3}, + {ID: "enabled", Label: "Probe enabled", Kind: sdk.CheckBox}, + {ID: "choice", Label: "Probe choice", Kind: sdk.List, Items: []sdk.ListItem{{ID: "first", Label: "First choice"}, {ID: "second", Label: "Second choice"}}}, + }, Values: map[string]sdk.Value{"rate": {Text: "70"}, "enabled": {}, "choice": {Selected: "first"}}}}, + QuickSettings: []sdk.QuickSetting{{ID: "probe", Label: "Probe mode", Command: "apply", Selected: "default", Options: []sdk.ListItem{{ID: "default", Label: "Default"}, {ID: "fast", Label: "Fast"}, {ID: "unavailable", Label: "Unavailable"}}}}} +} +func TestTentacleReaderExtensionPeer(t *testing.T) { + if len(os.Args) < 3 || os.Args[len(os.Args)-2] != "reader-extension-peer" { + return + } + mode := os.Args[len(os.Args)-1] + commands := []sdk.Command{{ID: "apply", Title: "Apply probe", Presentation: true, Interaction: true, Reader: true, Handle: func(ctx context.Context, arguments json.RawMessage) (any, error) { + var event sdk.ExtensionEvent + if err := json.Unmarshal(arguments, &event); err != nil { + return nil, err + } + if mode == "reject" { + return nil, errors.New("rejected") + } + if mode == "crash" { + os.Exit(3) + } + if event.Event == "exit" { + os.Exit(3) + } + if mode == "slow" { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-time.After(time.Minute): + return nil, nil + } + } + if event.Event == "preferences.open" { + if mode == "load-denied" { + configuration := event.Reader.DefaultSpeech + return sdk.Interaction{Reader: &sdk.ReaderRequest{Speech: &configuration}}, nil + } + if mode == "load-snapshot" { + return sdk.Interaction{Reader: &sdk.ReaderRequest{Snapshot: true, Module: "alpha"}, Next: "receive"}, nil + } + extensions := event.Reader.Extensions + extensions.Pages[0].Elements[1].Label = "Loaded probe enabled" + return sdk.Interaction{Reader: &sdk.ReaderRequest{Extensions: &extensions}}, nil + } + if event.Event == "preferences.apply" { + value, err := strconv.ParseFloat(event.Values["rate"].Text, 64) + if err != nil { + return nil, err + } + configuration := event.Reader.Speech + configuration.DefaultVoice.Rate = &value + extensions := event.Reader.Extensions + extensions.Pages[0].Values = event.Values + return sdk.Interaction{Reader: &sdk.ReaderRequest{Speech: &configuration, Extensions: &extensions}}, nil + } + if event.Event == "quick-setting" { + if event.Selected == "default" { + return sdk.Interaction{Reader: &sdk.ReaderRequest{RestoreSpeech: true}}, nil + } + configuration := event.Reader.Speech + rate := 80.0 + configuration.DefaultVoice.Rate = &rate + if event.Selected == "unavailable" { + configuration.Module = "unavailable" + } + return sdk.Interaction{Reader: &sdk.ReaderRequest{Speech: &configuration}}, nil + } + if event.Event == "snapshot" { + return sdk.Interaction{Reader: &sdk.ReaderRequest{Snapshot: true}, Next: "receive"}, nil + } + return nil, errors.New("unknown event") + }}, {ID: "receive", Title: "Receive probe", Presentation: true, Interaction: true, Reader: true, Handle: func(ctx context.Context, arguments json.RawMessage) (any, error) { + var submission sdk.Submission + if err := json.Unmarshal(arguments, &submission); err != nil { + return nil, err + } + if submission.Reader == nil || submission.Error != "" { + return nil, errors.New("no reader state") + } + if mode == "load-snapshot" { + if len(submission.Reader.Voices) != 1 || submission.Reader.Voices[0].Name != "Example voice" { + return nil, errors.New("missing voice catalog") + } + extensions := submission.Reader.Extensions + extensions.Pages[0].Elements[1].Label = "Loaded catalog probe" + return sdk.Interaction{Reader: &sdk.ReaderRequest{Extensions: &extensions}}, nil + } + configuration := submission.Reader.DefaultSpeech + rate := 77.0 + configuration.DefaultVoice.Rate = &rate + return sdk.Interaction{Reader: &sdk.ReaderRequest{Speech: &configuration}}, nil + }}} + extensions := reader_probe_extensions() + if strings.HasPrefix(mode, "load") { + extensions.Pages[0].Load = true + } + if err := sdk.ServeWithExtensions(os.Stdin, os.Stdout, commands, extensions); err != nil { + os.Exit(1) + } + os.Exit(0) +} + +type readerSpeechRecorder struct { + values []config.Settings + failure string + hook func() +} + +func (recorder *readerSpeechRecorder) UpdateConfiguration(ctx context.Context, next config.Settings) error { + if recorder.hook != nil { + recorder.hook() + } + if err := ctx.Err(); err != nil { + return err + } + if next.SpeechOutputModule == recorder.failure && recorder.failure != "" { + return errors.New("module unavailable") + } + recorder.values = append(recorder.values, copy_reader_value(next)) + return nil +} +func reader_extension_fixture(t *testing.T, mode string) (*preferencesWorker, *tentacle.Session, *readerSpeechRecorder) { + t.Helper() + manager, err := tentacle.NewManager(tentacle.DefaultLimits(), nil) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second) + defer cancel() + if err := manager.Shutdown(ctx); err != nil { + t.Error(err) + } + }) + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + session, err := manager.Start(t.Context(), tentacle.Spec{ID: "reader-probe", Program: []string{executable, "-test.run=^TestTentacleReaderExtensionPeer$", "--", "reader-extension-peer", mode}, Presentation: true, Interaction: true, ReaderSettings: true}) + if err != nil { + t.Fatal(err) + } + select { + case <-session.Ready(): + case <-time.After(5 * time.Second): + t.Fatal("handshake timed out") + } + if err := session.Activate(); err != nil { + state, reason := session.Status() + t.Fatal(err, state, reason) + } + runtime := newTentacleRuntime(slog.New(slog.DiscardHandler), &tentacleBindingRecorder{}, "", "") + runtime.output = tentacleOutputFixture(t) + runtime.publishCommands([]*tentacle.Session{session}) + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + rate := 50.0 + settings.DefaultVoice.Rate = &rate + recorder := &readerSpeechRecorder{failure: "unavailable"} + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, recorder) + worker.tentacles = runtime + runtime.readerSettings = worker + worker.live = &liveSettings{} + worker.live.Store(settings) + worker.discover = func(context.Context, string) (speech.Catalog, error) { + return speech.Catalog{"alpha": {{Name: "Example voice", Language: "en"}}}, nil + } + worker.sync_extensions(t.Context()) + return worker, session, recorder +} +func reader_page_request(worker *preferencesWorker, rate string) preferences.Request { + page := worker.extension_pages()[0] + values := copy_reader_value(page.Values) + values["rate"] = interaction.Value{Text: rate} + return preferences.Request{Values: preferences.FromSettings(worker.settings), ExtensionPages: []preferences.PageDraft{{Session: page.Session, ID: page.ID, Revision: page.Revision, Values: values}}} +} +func TestReaderExtensionPageApplyCancelSaveAndReopen(t *testing.T) { + worker, session, recorder := reader_extension_fixture(t, "normal") + before := copy_reader_value(worker.settings) + // Creating or editing a draft has no effect until Apply reaches the owner. + request := reader_page_request(worker, "73") + if len(recorder.values) != 0 || worker.speechOverride != nil { + t.Fatal("draft changed runtime") + } + request.Save = true + response := worker.apply(t.Context(), request) + if !response.Accepted { + t.Fatal(response.Message) + } + if len(recorder.values) != 1 || *recorder.values[0].DefaultVoice.Rate != 73 || *worker.live.Load().DefaultVoice.Rate != 73 { + t.Fatal("override was not applied") + } + if !reflect.DeepEqual(worker.settings, before) { + t.Fatal("override overwrote base settings") + } + if worker.extension_pages()[0].Values["rate"].Text != "73" { + t.Fatal("draft not committed") + } + store, _ := config.NewStore(worker.settings.Path) + saved, err := store.Load() + if err != nil || *saved.DefaultVoice.Rate != 50 { + t.Fatal("override was persisted as normal speech", err) + } + persisted, err := (&tentacle.PageStore{Path: worker.pageStore.Path}).Load() + if err != nil || persisted[session.TentacleID()]["probe"]["rate"].Text != "73" { + t.Fatal(persisted, err) + } + // Re-registering after a new session loads only saved page values, not speech. + worker.extensions = map[string]*readerExtension{} + worker.speechOverride, worker.speechOverrideOwner = nil, "" + worker.sync_extensions(t.Context()) + if worker.extension_pages()[0].Values["rate"].Text != "73" || worker.speechOverride != nil { + t.Fatal("page restoration activated speech") + } + response = worker.apply(t.Context(), request) + if response.Accepted { + t.Fatal("accepted a stale revision") + } +} +func TestReaderExtensionQuickNavigationRollbackDefaultAndBaseEdits(t *testing.T) { + worker, _, recorder := reader_extension_fixture(t, "normal") + var messages []string + worker.announce = func(message string) { messages = append(messages, message) } + worker.speechSetting = 4 + worker.handleSpeechCommand(t.Context(), input.SelectNextSpeechSetting) + if messages[len(messages)-1] != "Probe mode Default" { + t.Fatal(messages) + } + worker.handleSpeechCommand(t.Context(), input.IncreaseSpeechSetting) + if *worker.live.Load().DefaultVoice.Rate != 80 || *worker.settings.DefaultVoice.Rate != 50 { + t.Fatal("quick override corrupted base") + } + worker.handleSpeechCommand(t.Context(), input.IncreaseSpeechSetting) + if messages[len(messages)-1] != "Probe mode was not changed" || worker.quick_settings()[0].setting.Selected != "fast" || *worker.live.Load().DefaultVoice.Rate != 80 { + t.Fatal("failed switch committed") + } + // Built-in changes edit the active temporary override, not the normal voice. + worker.quickSettingKey = "" + worker.speechSetting = 0 + worker.handleSpeechCommand(t.Context(), input.IncreaseSpeechSetting) + if *worker.live.Load().DefaultVoice.Rate != 81 || *worker.settings.DefaultVoice.Rate != 50 { + t.Fatal("built-in adjustment changed base") + } + // A core preference edit still targets and saves the ordinary settings. + next := worker.settings + pitch := 6.0 + next.DefaultVoice.AveragePitch = &pitch + response := worker.applyNext(t.Context(), next, false, false) + if !response.Accepted || *worker.live.Load().DefaultVoice.Rate != 81 { + t.Fatal(response.Message) + } + worker.quickSettingKey = worker.quick_settings()[0].key + worker.handleSpeechCommand(t.Context(), input.DecreaseSpeechSetting) + if worker.speechOverride != nil || *worker.live.Load().DefaultVoice.Rate != 50 || *worker.live.Load().DefaultVoice.AveragePitch != 6 { + t.Fatal("default did not restore edited base") + } + if len(recorder.values) < 3 { + t.Fatal("backend not exercised") + } +} +func TestReaderExtensionRejectionCrashAndFailedApplyLeaveDraftUncommitted(t *testing.T) { + for _, mode := range []string{"reject", "crash", "normal"} { + t.Run(mode, func(t *testing.T) { + worker, _, recorder := reader_extension_fixture(t, mode) + request := reader_page_request(worker, "74") + if mode == "normal" { + worker.braille = &recordingBrailleSettings{err: errors.New("braille failed")} + request.Values.EnableBraille = !worker.settings.EnableBraille + } + response := worker.apply(t.Context(), request) + if response.Accepted || worker.speechOverride != nil || *worker.live.Load().DefaultVoice.Rate != 50 { + t.Fatal("failed apply committed", response.Message) + } + if mode == "normal" { + if len(recorder.values) != 2 || *recorder.values[0].DefaultVoice.Rate != 74 || *recorder.values[1].DefaultVoice.Rate != 50 { + t.Fatal("speech not rolled back after later failure", recorder.values) + } + if worker.extension_pages()[0].Values["rate"].Text != "70" { + t.Fatal("page values committed on failure") + } + } + }) + } +} +func TestReaderExtensionRevocationRestoresAndRemovesContributions(t *testing.T) { + worker, session, _ := reader_extension_fixture(t, "normal") + worker.quickSettingKey = worker.quick_settings()[0].key + value := tentaclewire.SpeechFromSettings(worker.settings) + rate := 82.0 + value.DefaultVoice.Rate = &rate + if _, err := worker.apply_reader_request(t.Context(), session, tentaclewire.ReaderRequest{Speech: &value}, false); err != nil { + t.Fatal(err) + } + session.Disable() + worker.sync_extensions(t.Context()) + if worker.speechOverride != nil || len(worker.extension_pages()) != 0 || len(worker.quick_settings()) != 0 || *worker.live.Load().DefaultVoice.Rate != 50 { + t.Fatal("revoked contributions survived") + } + if _, err := worker.apply_reader_request(t.Context(), session, tentaclewire.ReaderRequest{Speech: &value}, false); err == nil { + t.Fatal("late effect applied") + } + message := "" + worker.announce = func(text string) { message = text } + worker.handleSpeechCommand(t.Context(), input.IncreaseSpeechSetting) + if message != "The selected speech setting is no longer available" || worker.settings.DefaultVoice.Family != nil { + t.Fatal("a removed quick setting silently adjusted a different setting", message) + } +} +func TestReaderExtensionRevocationDuringBackendPreparation(t *testing.T) { + worker, session, recorder := reader_extension_fixture(t, "normal") + value := tentaclewire.SpeechFromSettings(worker.settings) + rate := 82.0 + value.DefaultVoice.Rate = &rate + recorder.hook = func() { session.Disable() } + _, err := worker.apply_reader_request(t.Context(), session, tentaclewire.ReaderRequest{Speech: &value}, false) + if err == nil || worker.speechOverride != nil || *worker.live.Load().DefaultVoice.Rate != 50 { + t.Fatal("revoked update committed", err) + } +} +func TestReaderExtensionSnapshotBoundsAndPreferenceWindowGate(t *testing.T) { + worker, session, _ := reader_extension_fixture(t, "normal") + worker.discover = func(context.Context, string) (speech.Catalog, error) { + voices := make([]speech.Voice, 10000) + for index := range voices { + voices[index] = speech.Voice{Name: strings.Repeat("Voice", 40), Language: "en"} + } + return speech.Catalog{"alpha": voices, "beta": nil}, nil + } + state, err := worker.apply_reader_request(t.Context(), session, tentaclewire.ReaderRequest{Snapshot: true, Module: "alpha"}, true) + if err != nil || !state.CatalogTruncated || len(state.Voices) == 0 || len(state.Modules) != 2 { + t.Fatal(state, err) + } + data, _ := json.Marshal(tentaclewire.Submission{Reader: state}) + if len(data) > tentacle.MaxReaderArgumentBytes { + t.Fatal("oversized continuation") + } + value := state.Speech + if _, err := worker.apply_reader_request(t.Context(), session, tentaclewire.ReaderRequest{Speech: &value}, true); err == nil { + t.Fatal("changed speech behind preferences draft") + } + ctx, cancel := context.WithCancel(t.Context()) + cancel() + if _, err := worker.apply_reader_request(ctx, session, tentaclewire.ReaderRequest{Speech: &value}, false); err == nil { + t.Fatal("cancelled request applied") + } + page := worker.extension_pages()[0] + page.Values["rate"] = interaction.Value{Text: "1"} + if worker.extension_pages()[0].Values["rate"].Text != "70" { + t.Fatal("snapshot aliases page values") + } +} +func TestReaderExtensionSlowCallbackTimesOutAndRetiresSession(t *testing.T) { + worker, session, _ := reader_extension_fixture(t, "slow") + ctx, cancel := context.WithTimeout(t.Context(), 40*time.Millisecond) + defer cancel() + response := worker.apply(ctx, reader_page_request(worker, "75")) + if response.Accepted || worker.speechOverride != nil { + t.Fatal("timeout applied") + } + waitTentacle(t, func() bool { state, _ := session.Status(); return state != tentacle.Active }) + worker.sync_extensions(t.Context()) + if len(worker.extension_pages()) != 0 { + t.Fatal("timed-out page survived") + } +} +func TestReaderExtensionWorkerMailboxAndProtocolContinuation(t *testing.T) { + worker, session, _ := reader_extension_fixture(t, "normal") + // The real runtime interaction asks the worker for a snapshot, receives it + // through the protocol continuation, and proposes a speech change. + if err := worker.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second) + defer cancel() + if err := worker.Stop(ctx); err != nil { + t.Error(err) + } + }) + command := tentacleCommand{session: session, id: "apply", reader: true, interactive: true, presentation: true} + raw, _ := json.Marshal(sdk.Interaction{Reader: &sdk.ReaderRequest{Snapshot: true}, Next: "receive"}) + worker.tentacles.interact(t.Context(), command, raw) + // Query through the same owner mailbox; do not read mutable worker state. + state, err := worker.request_reader(t.Context(), session, tentaclewire.ReaderRequest{Snapshot: true}) + if err != nil || state.Speech.DefaultVoice.Rate == nil || *state.Speech.DefaultVoice.Rate != 77 { + t.Fatal(state, err) + } + session.Disable() + worker.tentacles.signal_extensions() + // Sync is owner-serialized by the next request, proving queued late work is rejected. + if _, err := worker.request_reader(t.Context(), session, tentaclewire.ReaderRequest{RestoreSpeech: true}); err == nil { + t.Fatal("revoked mailbox work accepted") + } +} +func TestReaderExtensionPersistFailureReportsSessionOnly(t *testing.T) { + worker, _, _ := reader_extension_fixture(t, "normal") + if err := os.WriteFile(worker.pageStore.Path, []byte(`{}`), 0600); err != nil { + t.Fatal(err) + } + request := reader_page_request(worker, "76") + request.Save = true + request.Close = true + response := worker.apply(t.Context(), request) + if !response.Accepted || response.Close || !strings.Contains(response.Message, "could not be saved") { + t.Fatal(response) + } + data, _ := os.ReadFile(worker.pageStore.Path) + if !bytes.Equal(data, []byte(`{}`)) { + t.Fatal("overwrote external changes") + } +} + +func TestReaderExtensionApplicationOverlayAndDisabledSpeech(t *testing.T) { + worker, session, recorder := reader_extension_fixture(t, "normal") + value := tentaclewire.SpeechFromSettings(worker.settings) + rate := 83.0 + value.DefaultVoice.Rate = &rate + if _, err := worker.apply_reader_request(t.Context(), session, tentaclewire.ReaderRequest{Speech: &value}, false); err != nil { + t.Fatal(err) + } + appSettings := worker.settings + appRate := 61.0 + appSettings.DefaultVoice.Rate = &appRate + appSettings.SpeechVerbosityLevel = 0 + worker.appSettings["Example application"] = appSettings + worker.switchApplication(t.Context(), "Example application") + if *worker.live.Load().DefaultVoice.Rate != 83 || worker.live.Load().SpeechVerbosityLevel != 0 { + t.Fatal("application switch lost override or app preferences") + } + if _, err := worker.apply_reader_request(t.Context(), session, tentaclewire.ReaderRequest{RestoreSpeech: true}, false); err != nil { + t.Fatal(err) + } + if *worker.live.Load().DefaultVoice.Rate != 61 { + t.Fatal("did not restore current application's voice") + } + next := worker.settings + next.EnableSpeech = false + if err := worker.applyRuntime(t.Context(), next); err != nil { + t.Fatal(err) + } + count := len(recorder.values) + if _, err := worker.apply_reader_request(t.Context(), session, tentaclewire.ReaderRequest{Speech: &value}, false); err != nil { + t.Fatal(err) + } + if len(recorder.values) != count || worker.live.Load().EnableSpeech { + t.Fatal("override enabled or connected disabled speech") + } + next.EnableSpeech = true + if err := worker.applyRuntime(t.Context(), next); err != nil { + t.Fatal(err) + } + if len(recorder.values) != count+1 || *recorder.values[len(recorder.values)-1].DefaultVoice.Rate != 83 { + t.Fatal("reenabling did not apply pending override") + } + next.EnableSpeech = false + if err := worker.applyRuntime(t.Context(), next); err != nil { + t.Fatal(err) + } + count = len(recorder.values) + session.Disable() + worker.sync_extensions(t.Context()) + if worker.speechOverride != nil || len(recorder.values) != count { + t.Fatal("disabled speech required a backend restoration") + } +} +func TestReaderExtensionOwnershipLockAndAtomicContributionUpdate(t *testing.T) { + worker, first, _ := reader_extension_fixture(t, "normal") + _, second, _ := reader_extension_fixture(t, "other") + worker.tentacles.publishCommands([]*tentacle.Session{first, second}) + worker.sync_extensions(t.Context()) + value := tentaclewire.SpeechFromSettings(worker.settings) + rate := 85.0 + value.DefaultVoice.Rate = &rate + if _, err := worker.apply_reader_request(t.Context(), first, tentaclewire.ReaderRequest{Speech: &value}, false); err != nil { + t.Fatal(err) + } + for _, request := range []tentaclewire.ReaderRequest{{Speech: &value}, {RestoreSpeech: true}} { + if _, err := worker.apply_reader_request(t.Context(), second, request, false); err == nil { + t.Fatal("another session changed the owner's override") + } + } + extensions := copy_reader_value(worker.extensions[first.Identity()].value) + extensions.QuickSettings[0].Label = "Renamed probe" + value.Module = "unavailable" + if _, err := worker.apply_reader_request(t.Context(), first, tentaclewire.ReaderRequest{Speech: &value, Extensions: &extensions}, false); err == nil { + t.Fatal("unavailable module accepted") + } + if worker.extensions[first.Identity()].value.QuickSettings[0].Label != "Probe mode" { + t.Fatal("partial contribution update committed") + } + worker.tentacles.output.gate.secure.Store(true) + if _, err := worker.apply_reader_request(t.Context(), first, tentaclewire.ReaderRequest{RestoreSpeech: true}, false); err == nil { + t.Fatal("locked reader accepted request") + } + worker.tentacles.output.gate.secure.Store(false) + worker.tentacles.output.gate.suspended.Store(true) + if _, err := worker.apply_reader_request(t.Context(), first, tentaclewire.ReaderRequest{Snapshot: true}, false); err == nil { + t.Fatal("suspended reader exposed state") + } + worker.tentacles.output.gate.suspended.Store(false) +} +func TestReaderExtensionRestorationFailureRetainsWorkingVoiceAndReports(t *testing.T) { + worker, session, recorder := reader_extension_fixture(t, "normal") + value := tentaclewire.SpeechFromSettings(worker.settings) + value.Module = "alpha" + if _, err := worker.apply_reader_request(t.Context(), session, tentaclewire.ReaderRequest{Speech: &value}, false); err != nil { + t.Fatal(err) + } + worker.settings.SpeechOutputModule = "unavailable" + message := "" + worker.announce = func(text string) { message = text } + session.Disable() + worker.sync_extensions(t.Context()) + if worker.speechOverride == nil || worker.live.Load().SpeechOutputModule != "alpha" || !strings.Contains(message, "could not be restored") { + t.Fatal("failed restoration lost working speech", message) + } + if len(worker.extension_pages()) != 0 || len(worker.quick_settings()) != 0 { + t.Fatal("revoked UI survived failed restoration") + } + recorder.failure = "" + worker.sync_extensions(t.Context()) + if worker.speechOverride != nil || worker.live.Load().SpeechOutputModule != "unavailable" { + t.Fatal("later restoration did not recover") + } +} + +func TestReaderExtensionManagedLifecycleRestoresWithoutAnotherCommand(t *testing.T) { + for _, ending := range []string{"disable", "remove", "exit", "emergency"} { + t.Run(ending, func(t *testing.T) { + directory := t.TempDir() + runtime, _ := managed_tentacle_fixture(t, filepath.Join(directory, "tentacles.toml"), false) + runtime.output = tentacleOutputFixture(t) + settings := config.DefaultSettings() + settings.Path = filepath.Join(directory, "settings.toml") + baseRate := 50.0 + settings.DefaultVoice.Rate = &baseRate + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, &readerSpeechRecorder{}) + worker.tentacles = runtime + runtime.readerSettings = worker + worker.live = &liveSettings{} + worker.live.Store(settings) + worker.discover = func(context.Context, string) (speech.Catalog, error) { return speech.Catalog{}, nil } + if err := runtime.Start(t.Context()); err != nil { + t.Fatal(err) + } + if err := worker.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second) + defer cancel() + if err := worker.Stop(ctx); err != nil { + t.Error(err) + } + }) + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + entry := tentacle.Entry{ID: "managed-reader-probe", Enabled: true, Presentation: true, Interaction: true, ReaderSettings: true, Program: []string{executable, "-test.run=^TestTentacleReaderExtensionPeer$", "--", "reader-extension-peer", "normal"}} + manage_tentacle(t, runtime, "add", entry.ID, &entry) + sessions := runtime.reader_sessions() + if len(sessions) != 1 { + t.Fatal("reader session not published", runtime.Snapshot()) + } + var session *tentacle.Session + for _, value := range sessions { + session = value + } + configuration := tentaclewire.SpeechFromSettings(settings) + rate := 87.0 + configuration.DefaultVoice.Rate = &rate + if _, err := worker.request_reader(t.Context(), session, tentaclewire.ReaderRequest{Speech: &configuration}); err != nil { + t.Fatal(err) + } + if *worker.live.Load().DefaultVoice.Rate != 87 { + t.Fatal("override not active") + } + switch ending { + case "disable", "remove": + manage_tentacle(t, runtime, ending, entry.ID, nil) + case "exit": + replies, err := session.Invoke(t.Context(), "apply", json.RawMessage(`{"event":"exit"}`)) + if err != nil { + t.Fatal(err) + } + if result := <-replies; result.Err == nil { + t.Fatal("child did not exit") + } + case "emergency": + runtime.Disable() + } + // Observe the independent atomic snapshot only. No request or command + // is sent to the preferences worker to trigger reconciliation. + waitTentacle(t, func() bool { + return worker.live.Load().DefaultVoice.Rate != nil && *worker.live.Load().DefaultVoice.Rate == 50 + }) + }) + } +} + +func TestReaderExtensionPageLoadCanInspectCatalogWithoutChangingSpeech(t *testing.T) { + for _, mode := range []string{"load", "load-snapshot", "load-denied"} { + t.Run(mode, func(t *testing.T) { + worker, _, recorder := reader_extension_fixture(t, mode) + response, err := worker.initial_response(t.Context()) + if err != nil { + t.Fatal(err) + } + if len(recorder.values) != 0 || worker.speechOverride != nil { + t.Fatal("opening preferences changed speech") + } + if len(response.ExtensionPages) != 1 || response.ExtensionPages[0].Values["rate"].Text != "70" { + t.Fatal("load discarded page values") + } + label := response.ExtensionPages[0].Elements[1].Label + switch mode { + case "load": + if label != "Loaded probe enabled" { + t.Fatal(label) + } + case "load-snapshot": + if label != "Loaded catalog probe" { + t.Fatal("catalog continuation did not refresh page", label) + } + case "load-denied": + if label != "Probe enabled" || !strings.Contains(response.Message, "could not load") { + t.Fatal("speech-changing load was not rejected", label, response.Message) + } + } + }) + } +} diff --git a/internal/app/tentacle_repositories.go b/internal/app/tentacle_repositories.go new file mode 100644 index 0000000..280969e --- /dev/null +++ b/internal/app/tentacle_repositories.go @@ -0,0 +1,52 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "errors" + "slices" + + "git.stormux.org/storm/cthulhu/internal/tentacle" +) + +func change_tentacle_repositories(repositories []tentacle.Repository, request tentacle.ManagementRequest, repository *tentacle.Repository) ([]tentacle.Repository, error) { + if request.Entry != nil || request.ID != "" { + return nil, errors.New("unexpected tentacle entry in repository request") + } + origin, err := tentacle.RepositoryURL(request.URL) + if err != nil { + return nil, err + } + next := tentacle.CloneRepositories(repositories) + index := slices.IndexFunc(next, func(value tentacle.Repository) bool { return value.URL == origin }) + switch request.Action { + case "repository-add", "repository-refresh": + if repository == nil || repository.URL != origin { + return nil, errors.New("validated repository metadata is required") + } + candidate := tentacle.CloneRepositories([]tentacle.Repository{*repository})[0] + if request.Action == "repository-add" { + if index >= 0 { + return nil, errors.New("repository already added") + } + next = append(next, candidate) + } else { + if index < 0 { + return nil, errors.New("repository does not exist") + } + if next[index].ID != repository.ID { + return nil, errors.New("repository identity changed; the previous catalog was retained") + } + next[index] = candidate + } + case "repository-remove": + if index < 0 { + return nil, errors.New("repository does not exist") + } + next = slices.Delete(next, index, index+1) + default: + return nil, errors.New("unknown repository operation") + } + return next, tentacle.ValidateRepositories(next) +} diff --git a/internal/app/tentacle_repositories_test.go b/internal/app/tentacle_repositories_test.go new file mode 100644 index 0000000..0161522 --- /dev/null +++ b/internal/app/tentacle_repositories_test.go @@ -0,0 +1,109 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "errors" + "git.stormux.org/storm/cthulhu/internal/tentacle" + "path/filepath" + "strings" + "testing" +) + +func TestManagedRepositoryDiscoveryRefreshRemoveAndRestart(t *testing.T) { + registryPath := filepath.Join(t.TempDir(), "tentacles.toml") + runtime, _ := managed_tentacle_fixture(t, registryPath, false) + origin := "https://example.org/team/tentacles" + repository := tentacle.Repository{URL: origin, ID: "example.tentacles", Name: "Example", Revision: strings.Repeat("a", 40), Tentacles: []tentacle.Manifest{{FormatVersion: 1, ID: "echo", Name: "Echo", Version: "0.1"}}} + fail := false + runtime.fetchRepository = func(context.Context, string) (tentacle.Repository, error) { + if fail { + return tentacle.Repository{}, errors.New("invalid metadata") + } + return repository, nil + } + runtime.newManager = func() (*tentacle.Manager, error) { + t.Error("repository discovery started host") + return nil, tentacle.ErrUnavailable + } + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + manage := func(action string) error { + return runtime.Manage(context.Background(), tentacle.ManagementRequest{Action: action, URL: origin}) + } + if err := manage("repository-add"); err != nil { + t.Fatal(err) + } + if len(runtime.Snapshot().Repositories) != 1 || len(runtime.Snapshot().Entries) != 0 { + t.Fatal(runtime.Snapshot()) + } + if err := manage("repository-add"); err == nil { + t.Fatal("duplicate accepted") + } + fail = true + if err := manage("repository-refresh"); err == nil { + t.Fatal("invalid refresh accepted") + } + if runtime.Snapshot().Repositories[0].Revision != repository.Revision { + t.Fatal("lost last good catalog") + } + fail = false + repository.Revision = strings.Repeat("b", 40) + if err := manage("repository-refresh"); err != nil { + t.Fatal(err) + } + repository.ID = "different" + if err := manage("repository-refresh"); err == nil { + t.Fatal("changed identity accepted") + } + disk := &tentacle.Registry{Path: registryPath} + if _, err := disk.Load(); err != nil || len(disk.Repositories()) != 1 || disk.Repositories()[0].ID != "example.tentacles" || disk.Repositories()[0].Revision != strings.Repeat("b", 40) { + t.Fatalf("persisted repository: %+v %v", disk.Repositories(), err) + } + // Cached catalogs load at startup without invoking any fetch function. + restarted, _ := managed_tentacle_fixture(t, registryPath, false) + restarted.fetchRepository = func(context.Context, string) (tentacle.Repository, error) { + t.Error("startup fetched repository") + return repository, nil + } + if err := restarted.Start(context.Background()); err != nil { + t.Fatal(err) + } + waitTentacle(t, func() bool { return len(restarted.Snapshot().Repositories) == 1 }) + if err := manage("repository-remove"); err != nil { + t.Fatal(err) + } + if len(runtime.Snapshot().Repositories) != 0 { + t.Fatal("source not removed") + } +} + +func TestRepositoryRemovalRetainsInstalledEntries(t *testing.T) { + registryPath := filepath.Join(t.TempDir(), "tentacles.toml") + origin := "https://example.org/team/tentacles" + registry := &tentacle.Registry{Path: registryPath} + if _, err := registry.Load(); err != nil { + t.Fatal(err) + } + entry := probe_entry(t, "installed", "called") + entry.Repository = origin + entry.RepositoryID = "example.tentacles" + entry.LocalID = "echo" + repository := tentacle.Repository{URL: origin, ID: "example.tentacles", Name: "Example", Revision: strings.Repeat("a", 40)} + if err := registry.SaveState([]tentacle.Entry{entry}, []tentacle.Repository{repository}); err != nil { + t.Fatal(err) + } + runtime, _ := managed_tentacle_fixture(t, registryPath, false) + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + if err := runtime.Manage(context.Background(), tentacle.ManagementRequest{Action: "repository-remove", URL: origin}); err != nil { + t.Fatal(err) + } + snapshot := runtime.Snapshot() + if len(snapshot.Repositories) != 0 || len(snapshot.Entries) != 1 || snapshot.Entries[0].Entry.ID != entry.ID { + t.Fatal(snapshot) + } +} diff --git a/internal/app/tentacle_settings_test.go b/internal/app/tentacle_settings_test.go new file mode 100644 index 0000000..d37460f --- /dev/null +++ b/internal/app/tentacle_settings_test.go @@ -0,0 +1,84 @@ +package app + +import ( + "context" + "os" + "path/filepath" + "testing" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/tentacle" +) + +func TestPreferencesTentacleSettingsDispatchAndMissingSettings(t *testing.T) { + for _, mode := range []string{"settings-save", "settings-cancel", "settings-disable", "no-settings"} { + t.Run(mode, func(t *testing.T) { + directory := t.TempDir() + path, marker := filepath.Join(directory, "tentacles.toml"), filepath.Join(directory, mode) + runtime, _ := managed_tentacle_fixture(t, path, false) + runtime.output = tentacleOutputFixture(t) + keys := &uiTestKeys{} + output := &ocrTestOutput{speech: make(chan speechRequest, 32)} + ui := &internalUI{keys: keys, speech: output, gate: runtime.output.gate, events: make(chan input.CommandEvent, 16), requests: make(chan internalUIRequest, 1), notices: make(chan internalUINotice, 4), done: make(chan struct{})} + runtime.forms = ui + ctx, cancel := context.WithCancel(context.Background()) + go ui.run(ctx) + t.Cleanup(func() { cancel(); <-ui.done }) + if err := runtime.Start(ctx); err != nil { + t.Fatal(err) + } + executable, _ := os.Executable() + entry := tentacle.Entry{ID: "probe", Enabled: true, Presentation: true, Interaction: true, Program: []string{executable, "-test.run=^TestTentacleInteractionPeer$", "--", "interaction-peer", marker}} + manage_tentacle(t, runtime, "add", entry.ID, &entry) + waitTentacle(t, func() bool { + snapshot := runtime.Snapshot() + return len(snapshot.Entries) == 1 && snapshot.Entries[0].State == "active" + }) + before, _ := os.ReadFile(path) + snapshot := runtime.Snapshot() + if len(snapshot.Entries[0].Shortcuts) != 1 || snapshot.Entries[0].Shortcuts[0] != "Desktop: F9 (Interactive probe)" { + t.Fatal(snapshot) + } + snapshot.Entries[0].Shortcuts[0] = "modified copy" + if runtime.Snapshot().Entries[0].Shortcuts[0] == "modified copy" { + t.Fatal("snapshot shared shortcut storage") + } + worker := &preferencesWorker{tentacles: runtime} + response := worker.manage_tentacle(ctx, preferences.Request{Tentacle: &tentacle.ManagementRequest{Action: "settings", ID: entry.ID}}) + if mode == "no-settings" { + if response.Accepted || response.Message != "No settings for this tentacle." || keys.InternalUISession() != 0 { + t.Fatal(response) + } + return + } + if !response.Accepted || response.Message != "" { + t.Fatal(response) + } + waitTentacle(t, func() bool { return keys.InternalUISession() != 0 }) + sessionID := keys.InternalUISession() + switch mode { + case "settings-save": + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: sessionID, Text: "saved value"}) + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: sessionID, Chord: input.CommandChord{Symbol: 0xff0d}}) + case "settings-cancel": + ui.Handle(input.CommandEvent{Command: input.InternalUIKey, UISession: sessionID, Chord: input.CommandChord{Symbol: 0xff1b}}) + case "settings-disable": + manage_tentacle(t, runtime, "disable", entry.ID, nil) + } + waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 && keys.InternalUISession() == 0 }) + if mode != "settings-disable" { + after, _ := os.ReadFile(path) + if string(before) != string(after) { + t.Fatal("opening settings changed registry") + } + } + if mode == "settings-save" { + data, err := os.ReadFile(marker) + if err != nil || len(data) == 0 { + t.Fatal("settings submission was not delivered", err) + } + } + }) + } +} diff --git a/internal/app/tentacle_uninterruptible_test.go b/internal/app/tentacle_uninterruptible_test.go new file mode 100644 index 0000000..07e8aa2 --- /dev/null +++ b/internal/app/tentacle_uninterruptible_test.go @@ -0,0 +1,222 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type protectedSpeaker struct{ confirmationSpeaker } + +func (speaker *protectedSpeaker) speak_uninterruptible(ctx context.Context, text string) error { + return speaker.call(ctx, text) +} + +func protected_output_fixture(t *testing.T) (*tentacleOutput, *protectedSpeaker) { + t.Helper() + owner := tentacleOutputFixture(t) + speaker := &protectedSpeaker{confirmationSpeaker{controlledSpeaker{calls: make(chan speechCall, 20)}}} + owner.speech.speaker = speaker + owner.speech.running = false + if err := owner.speech.Start(t.Context()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { owner.speech.Stop(context.Background()) }) + return owner, speaker +} + +func TestTentacleUninterruptibleSurvivesInputAndFocusUntilEnd(t *testing.T) { + owner, speaker := protected_output_fixture(t) + ticket := owner.Capture(t.Context()) + owner.Present(ticket, tentaclewire.Presentation{Speech: "Hello world!", Braille: "Hello world!", Uninterruptible: true}, "tentacle/test/hello") + // Protection begins on admission, before the backend has accepted SPEAK. + if owner.speech.InterruptForInput(input.Event{Timestamp: 101, Pressed: true}) { + t.Fatal("queued greeting was interrupted") + } + greeting := expectSpeechCall(t, &speaker.controlledSpeaker, "Hello world!") + owner.speech.Interrupt() + owner.speech.InterruptForUser() + owner.speech.ProtectCommand(102) + owner.Capture(t.Context()) // Another command and ordinary focus retirement. + owner.gate.retireTentacleOutput() + if owner.speech.InterruptForInput(input.Event{Timestamp: 103, Pressed: true}) { + t.Fatal("active greeting was interrupted") + } + owner.speech.Enqueue(speechRequest{Text: "Focused control"}) + owner.speech.mutex.Lock() + if len(owner.speech.pending) != 1 || !owner.speech.pending[0].Append || !owner.speech.has_uninterruptible_locked() { + t.Error("core output did not queue behind protected speech") + } + owner.speech.mutex.Unlock() + select { + case call := <-speaker.calls: + t.Fatalf("backend was interrupted before END: %q", call.text) + default: + } + close(greeting.done) // Actual END, not the SPEAK acknowledgement. + focus := expectSpeechCall(t, &speaker.controlledSpeaker, "Focused control") + if !owner.speech.InterruptForInput(input.Event{Timestamp: 104, Pressed: true}) { + t.Fatal("protection leaked after completion") + } + close(expectSpeechCall(t, &speaker.controlledSpeaker, "cancel").done) + close(focus.done) +} + +func TestTentacleUninterruptibleStillRevokes(t *testing.T) { + for _, action := range []string{"session", "disable", "lock", "speech off", "mode", "stop", "lifetime"} { + t.Run(action, func(t *testing.T) { + owner, speaker := protected_output_fixture(t) + parent, cancel := context.WithCancel(t.Context()) + defer cancel() + ticket := owner.Capture(parent) + owner.Present(ticket, tentaclewire.Presentation{Speech: "Protected greeting", Uninterruptible: true}, "tentacle/test/hello") + owner.speech.mutex.Lock() + request := owner.speech.pending[0] + deadline, bounded := request.context.Deadline() + owner.speech.mutex.Unlock() + if !bounded || time.Until(deadline) > uninterruptibleSpeechTimeout { + t.Fatal("unbounded protected speech") + } + _ = expectSpeechCall(t, &speaker.controlledSpeaker, "Protected greeting") + switch action { + case "session": + cancel() + case "disable": + owner.Stop() + case "lock": + owner.gate.SetLocked(true, nil, nil, nil, owner.speech, owner.braille) + case "speech off": + owner.speech.SetEnabled(false) + case "mode": + owner.speech.cycle_speech_mode() + case "stop": + if err := owner.speech.Stop(t.Context()); err != nil { + t.Fatal(err) + } + case "lifetime": + // Retire the admitted lifetime deterministically. Its actual + // deadline is checked above, without a 30-second test sleep. + request.cancel() + } + if request.context.Err() == nil { + t.Fatal("protected lifetime survived revocation") + } + if action == "stop" { + return + } + // Complete cancellation calls, then prove delivery resumes. Off + // and disabled modes are restored only after their barrier drains. + owner.speech.SetEnabled(true) + owner.speech.mutex.Lock() + owner.speech.mode = speechModeSpeech + owner.speech.secure = false + owner.speech.mutex.Unlock() + owner.speech.Enqueue(speechRequest{Text: "Resumed"}) + for { + call := expect_next_speech_call(t, &speaker.controlledSpeaker) + close(call.done) + if call.text == "Resumed" { + return + } + if call.text != "cancel" { + t.Fatalf("unexpected output %q", call.text) + } + } + }) + } +} + +func expect_next_speech_call(t *testing.T, speaker *controlledSpeaker) speechCall { + t.Helper() + select { + case call := <-speaker.calls: + return call + case <-time.After(time.Second): + t.Fatal("speech failed to resume") + return speechCall{} + } +} + +func TestTentacleUninterruptibleCannotResurrectStaleReply(t *testing.T) { + for _, action := range []string{"input", "focus", "new speech", "revoked", "lock", "handoff"} { + t.Run(action, func(t *testing.T) { + owner := tentacleOutputFixture(t) + parent, cancel := context.WithCancel(t.Context()) + defer cancel() + ticket := owner.Capture(parent) + switch action { + case "input": + owner.speech.InterruptForUser() + case "focus": + owner.Retire() + case "new speech": + owner.speech.Enqueue(speechRequest{Text: "Core"}) + case "revoked": + cancel() + case "lock": + owner.gate.SetLocked(true, nil, nil, nil, owner.speech, owner.braille) + case "handoff": + owner.gate.SetSuspended(true) + } + owner.Present(ticket, tentaclewire.Presentation{Speech: "Stale", Uninterruptible: true}, "tentacle/test/hello") + for _, request := range owner.speech.pending { + if request.Text == "Stale" || request.Uninterruptible { + t.Fatal("protected option bypassed stale result check") + } + } + }) + } +} + +func TestTentacleProtectedStopPreservesCoreQueue(t *testing.T) { + owner, speaker := protected_output_fixture(t) + owner.Present(owner.Capture(t.Context()), tentaclewire.Presentation{Speech: "Greeting", Uninterruptible: true}, "tentacle/test/hello") + _ = expectSpeechCall(t, &speaker.controlledSpeaker, "Greeting") + owner.speech.Enqueue(speechRequest{Text: "Core output"}) + owner.Stop() + for { + call := expect_next_speech_call(t, &speaker.controlledSpeaker) + close(call.done) + if call.text == "Core output" { + return + } + if call.text != "cancel" { + t.Fatalf("unexpected output %q", call.text) + } + } +} + +func TestTentacleProtectedModesAndUnsupportedHardware(t *testing.T) { + for _, mode := range []speechMode{speechModeBeeps, speechModeOff} { + owner := tentacleOutputFixture(t) + owner.speech.mode = mode + beeps := 0 + owner.speech.beep = func(context.Context) error { beeps++; return nil } + owner.Present(owner.Capture(t.Context()), tentaclewire.Presentation{ + Speech: "Greeting", Braille: "Display", Uninterruptible: true, + }, "tentacle/test/hello") + request, ok := owner.speech.next() + if !ok { + t.Fatal("no protected presentation") + } + if err := owner.speech.deliver(request.context, request); err != nil { + t.Fatal(err) + } + completeSpeechRequest(request, nil) + if (beeps == 1) != (mode == speechModeBeeps) || owner.braille.current().Text != "Display" { + t.Fatal("protected presentation bypassed core output preferences") + } + } + // Hardware SpeakAndWait reports transmission rather than audible END. It + // must not be treated as a completion-capable protected-speech backend. + configured := &configuredSpeaker{active: &hardwareSpeaker{}} + if err := configured.speak_uninterruptible(t.Context(), "Greeting"); err == nil { + t.Fatal("hardware backend claimed audible completion") + } +} diff --git a/internal/app/tentacles.go b/internal/app/tentacles.go new file mode 100644 index 0000000..c501625 --- /dev/null +++ b/internal/app/tentacles.go @@ -0,0 +1,436 @@ +package app + +import ( + "context" + "errors" + "log/slog" + "os" + "strings" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/shortcutui" + "git.stormux.org/storm/cthulhu/internal/tentacle" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type tentacleInput interface { + SetTentacleBindings(context.Context, []input.BindingOverride) error + TentacleBindings() []input.BindingOverride +} + +type tentacleCommand struct { + session *tentacle.Session + entryID string + id, title, description string + presentation bool + interactive bool + reader bool + settings bool +} + +// tentacleRuntime owns local sessions for one reader lifetime. Its worker owns +// native publication; mutex protects dispatch snapshots and immediate disable. +// Only explicitly granted presentation commands reach the core output owner. +type tentacleRuntime struct { + readerSettings *preferencesWorker + extensionChanges chan struct{} + forms tentacleForms + focusedItem func(context.Context) (tentaclewire.Item, error) + interactionSlots chan struct{} + registry *tentacle.Registry + requests chan tentacleManagementCall + snapshot tentacle.Snapshot + guardianProgram []string // Private fixture seam; production uses this executable. + output *tentacleOutput + logger *slog.Logger + input tentacleInput + path, parent string + newManager func() (*tentacle.Manager, error) // private fixture seam + fetchRepository func(context.Context, string) (tentacle.Repository, error) // private fixture seam + preparePackage func(context.Context, string, tentacle.Repository, string) (*tentacle.PreparedPackage, error) // private fixture seam + repositoryBusy bool + mutex sync.Mutex + commands map[input.Command]tentacleCommand + sessions []*tentacle.Session + disabled bool + cancel context.CancelFunc + readerContext context.Context + lifecycleContext context.Context + done chan struct{} + failures chan error + announcements chan string + stopError error + results sync.WaitGroup + resultSlots chan struct{} +} + +func newTentacleRuntime(logger *slog.Logger, commands commandListener, path, parent string) *tentacleRuntime { + owner, _ := commands.(tentacleInput) + return &tentacleRuntime{logger: logger, input: owner, path: path, parent: parent, + extensionChanges: make(chan struct{}, 1), commands: make(map[input.Command]tentacleCommand), failures: make(chan error, 1), announcements: make(chan string, 1), interactionSlots: make(chan struct{}, 1), resultSlots: make(chan struct{}, 64)} +} + +func (runtime *tentacleRuntime) Start(ctx context.Context) error { + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + runtime.readerContext = ctx + ctx, runtime.cancel = context.WithCancel(ctx) + runtime.lifecycleContext = ctx + runtime.done = make(chan struct{}) + go func() { + defer close(runtime.done) + run := runtime.run + if runtime.registry != nil { + run = runtime.run_managed + } + if err := run(ctx); err != nil { + runtime.logger.Warn("tentacle startup failed", "error", err) + runtime.report("Tentacles could not start.") + } + }() + return nil +} + +func (runtime *tentacleRuntime) Disable() { + if runtime == nil { + return + } + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + runtime.disabled = true + runtime.output.Stop() + clear(runtime.commands) + runtime.signal_extensions() + for _, session := range runtime.sessions { + session.Disable() + } + if runtime.cancel != nil { + runtime.cancel() + } +} + +func (runtime *tentacleRuntime) Stop(ctx context.Context) error { + if runtime == nil { + return nil + } + runtime.Disable() + if runtime.done == nil { + return nil + } + select { + case <-runtime.done: + return runtime.stopError + case <-ctx.Done(): + return ctx.Err() + } +} + +func (runtime *tentacleRuntime) run(ctx context.Context) error { + if runtime.input == nil { + return errors.New("tentacles require native binding support") + } + specs, err := tentacle.LoadLocalSpecs(runtime.path) + if err != nil || len(specs) == 0 { + return err + } + manager, err := runtime.makeManager() + if err != nil { + return err + } + var watchers sync.WaitGroup + defer func() { + runtime.Disable() + cleanup, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + bindingError := runtime.input.SetTentacleBindings(cleanup, nil) + if runtime.readerContext.Err() != nil { + bindingError = nil + } + runtime.stopError = errors.Join(bindingError, manager.Shutdown(cleanup)) + watchers.Wait() + runtime.results.Wait() + if runtime.stopError != nil && runtime.readerContext.Err() == nil { + select { + case runtime.failures <- runtime.stopError: + default: + } + } + }() + wake := make(chan struct{}, 1) + var current *tentacle.Session + var ready <-chan struct{} + var active []*tentacle.Session + index := 0 + for { + if ctx.Err() != nil { + return nil + } + if current == nil && index < len(specs) { + spec := specs[index] + index++ + session, startError := manager.Start(ctx, spec) + if startError != nil { + runtime.logger.Warn("start local tentacle", "tentacle", spec.ID, "error", startError) + runtime.report("A tentacle could not start.") + continue + } + runtime.mutex.Lock() + runtime.sessions = append(runtime.sessions, session) + if runtime.disabled { + session.Disable() + } + runtime.mutex.Unlock() + current, ready = session, session.Ready() + watchers.Add(1) + go func() { + defer watchers.Done() + select { + case <-session.Revoked(): + case <-ctx.Done(): + } + runtime.output.RetireRevoked() + runtime.signal_extensions() + select { + case wake <- struct{}{}: + default: + } + }() + } + select { + case <-ctx.Done(): + return nil + case <-wake: + retained := active[:0] + for _, session := range active { + if state, failure := session.Status(); state == tentacle.Active { + retained = append(retained, session) + } else if state == tentacle.Failed { + runtime.logger.Warn("local tentacle failed", "session", session.Identity(), "error", failure) + runtime.report("A tentacle stopped unexpectedly.") + } + } + active = retained + runtime.publishCommands(active) + if err := runtime.bind(ctx, active); err != nil { + if ctx.Err() != nil { + return nil + } + runtime.failures <- err // Stop the reader if stale grabs cannot be removed. + return err + } + case <-ready: + session := current + current, ready = nil, nil + if state, failure := session.Status(); state != tentacle.Ready { + runtime.logger.Warn("local tentacle handshake failed", "error", failure) + runtime.report("A tentacle could not start.") + continue + } + candidate := append(append([]*tentacle.Session(nil), active...), session) + if err := runtime.bind(ctx, candidate); err != nil { + session.Disable() + runtime.logger.Warn("local tentacle bindings rejected", "error", err) + runtime.report("A tentacle could not acquire its keyboard shortcuts.") + continue + } + if err := session.Activate(); err != nil { + session.Disable() + if restore := runtime.bind(ctx, active); restore != nil && ctx.Err() == nil { + runtime.failures <- restore + return restore + } + continue + } + active = candidate + runtime.publishCommands(active) + runtime.logger.Info("local tentacle active", "session", session.Identity()) + } + } +} + +func (runtime *tentacleRuntime) bind(ctx context.Context, sessions []*tentacle.Session) error { + var bindings []input.BindingOverride + for _, session := range sessions { + for _, command := range session.Commands() { + for _, binding := range command.Bindings { + layout := input.DesktopKeyboardLayout + if binding.Layout == "laptop" { + layout = input.LaptopKeyboardLayout + } + bindings = append(bindings, input.BindingOverride{Layout: layout, Scope: binding.Scope, + Command: input.Command("tentacle/" + session.Identity() + "/" + command.ID), Keys: []string{binding.Key}}) + } + } + } + ctx, cancel := context.WithTimeout(ctx, time.Second) + defer cancel() + return runtime.input.SetTentacleBindings(ctx, bindings) +} + +func (runtime *tentacleRuntime) publishCommands(sessions []*tentacle.Session) { + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + defer runtime.signal_extensions() + clear(runtime.commands) + if runtime.disabled { + return + } + for _, session := range sessions { + for _, command := range session.Commands() { + runtime.commands[input.Command("tentacle/"+session.Identity()+"/"+command.ID)] = tentacleCommand{ + session: session, entryID: session.TentacleID(), id: command.ID, title: command.Title, + description: command.Description, presentation: command.Presentation, + interactive: command.Interaction, settings: command.Settings, reader: command.Reader, + } + } + } +} + +// Invoke never waits for a child or native binding transaction. Every result +// worker has a bounded slot and joins before lifecycle shutdown completes. +func (runtime *tentacleRuntime) Invoke(ctx context.Context, command input.Command) bool { + if runtime == nil || !strings.HasPrefix(string(command), "tentacle/") { + return false + } + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + registered, ok := runtime.commands[command] + if !ok || runtime.disabled { + return true + } + if err := runtime.invokeLocked(ctx, command, registered); err != nil { + runtime.logger.Debug("tentacle command rejected", "command", command, "error", err) + } + return true +} + +// Caller holds runtime.mutex so shutdown cannot race worker admission. +func (runtime *tentacleRuntime) invokeLocked(ctx context.Context, command input.Command, registered tentacleCommand) error { + select { + case runtime.resultSlots <- struct{}{}: + default: + return tentacle.ErrBusy + } + result, err := registered.session.Invoke(ctx, registered.id, nil) + if err != nil { + <-runtime.resultSlots + return err + } + var ticket tentacleOutputTicket + if registered.presentation { + ticket = runtime.output.Capture(registered.session.OutputContext()) + } + runtime.results.Add(1) + go func() { + defer runtime.results.Done() + defer func() { <-runtime.resultSlots }() + value := <-result + runtime.logger.Debug("tentacle command completed", "command", command, "request", value.ID, "error", value.Err) + if value.Err != nil || !registered.presentation { + return + } + if registered.interactive { + if ticket.ctx == nil || ticket.ctx.Err() != nil { + return + } + runtime.interact(ctx, registered, value.Value) + return + } + presentation, err := tentaclewire.DecodePresentation(value.Value) + if err != nil { + registered.session.Disable() + runtime.output.RetireRevoked() + runtime.logger.Warn("tentacle returned invalid presentation", "command", command, "error", err) + runtime.report("A tentacle returned an invalid message and was disabled.") + return + } + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + if !runtime.disabled && value.Session == registered.session.Identity() { + runtime.output.Present(ticket, presentation, string(command)) + } + }() + return nil +} + +func (runtime *tentacleRuntime) Describe(chord input.CommandChord, layout input.KeyboardLayout, browse bool) string { + if runtime == nil || runtime.input == nil { + return "" + } + bindings := runtime.input.TentacleBindings() + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + for _, binding := range bindings { + if binding.Layout != layout || binding.Scope == "browse" && !browse { + continue + } + bound, _ := input.ParseCommandChord(binding.Keys[0]) + registered, ok := runtime.commands[binding.Command] + if bound != chord || !ok { + continue + } + if state, _ := registered.session.Status(); state != tentacle.Active { + continue + } + if registered.description != "" { + return registered.description + } + return registered.title + } + return "" +} + +// ShortcutRows uses the acknowledged native assignments, including core remaps. +func (runtime *tentacleRuntime) ShortcutRows(layout input.KeyboardLayout) []shortcutui.Row { + if runtime == nil || runtime.input == nil { + return nil + } + bindings := runtime.input.TentacleBindings() + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + var rows []shortcutui.Row + for _, binding := range bindings { + registered, ok := runtime.commands[binding.Command] + if binding.Layout != layout || !ok { + continue + } + if state, _ := registered.session.Status(); state != tentacle.Active { + continue + } + label := registered.description + if label == "" { + label = registered.title + } + group := "Tentacles" + if binding.Scope == "browse" { + group = "Tentacles in browse mode" + } + rows = append(rows, shortcutui.Row{Group: group, Label: label, Keys: binding.Keys[0]}) + } + return rows +} + +func (runtime *tentacleRuntime) report(message string) { + select { + case runtime.announcements <- message: + default: + } +} + +// makeManager runs on the lifecycle worker, never on input or GTK callbacks. +func (runtime *tentacleRuntime) makeManager() (*tentacle.Manager, error) { + if runtime.newManager != nil { + return runtime.newManager() + } + program := runtime.guardianProgram + if len(program) == 0 { + executable, err := os.Executable() + if err != nil { + return nil, err + } + program = []string{executable, "--tentacle-guardian"} + } + return tentacle.NewSupervisedManager(program, runtime.parent) +} diff --git a/internal/app/tentacles_test.go b/internal/app/tentacles_test.go new file mode 100644 index 0000000..8b862fd --- /dev/null +++ b/internal/app/tentacles_test.go @@ -0,0 +1,473 @@ +package app + +import ( + "context" + "encoding/json" + "errors" + "log/slog" + "os" + "path/filepath" + "strings" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/tentacle" + sdk "git.stormux.org/storm/cthulhu/sdk/go/tentacle" +) + +// Subprocess fixture: no reader backend, network, or desktop access. +func TestTentacleReaderPeer(t *testing.T) { + if len(os.Args) < 3 || os.Args[len(os.Args)-2] != "reader-peer" { + return + } + marker := os.Args[len(os.Args)-1] + presentation := strings.HasPrefix(filepath.Base(marker), "present") + if filepath.Base(marker) == "bad-startup" { + os.Exit(2) + } + if filepath.Base(marker) == "stall" { + time.Sleep(time.Minute) + os.Exit(0) + } + err := sdk.Serve(os.Stdin, os.Stdout, []sdk.Command{{ID: "probe", Title: "Probe command", Description: "Run the private reader probe.", + Presentation: presentation, + Bindings: []sdk.Binding{{Layout: "desktop", Scope: "global", Key: "F9"}}, + Handle: func(ctx context.Context, _ json.RawMessage) (any, error) { + if filepath.Base(marker) == "crash" { + os.Exit(3) + } + group, _ := os.ReadFile("/proc/self/cgroup") + if err := os.WriteFile(marker, group, 0600); err != nil { + return nil, err + } + if filepath.Base(marker) == "present-delay" { + for { + if _, err := os.Stat(marker + ".release"); err == nil { + break + } + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-time.After(time.Millisecond): + } + } + } + if filepath.Base(marker) == "present-invalid" { + return map[string]any{"speech": "Private text", "unknown": true}, nil + } + if presentation { + return sdk.Presentation{Speech: "Hello, é猫😀é", Braille: "Display é猫😀é"}, nil + } + return nil, nil + }, + }}) + if err != nil { + os.Exit(1) + } + os.Exit(0) +} + +type tentacleBindingRecorder struct { + silentCommands + mutex sync.Mutex + bindings []input.BindingOverride + reject bool + removeError error +} + +func (recorder *tentacleBindingRecorder) SetTentacleBindings(_ context.Context, bindings []input.BindingOverride) error { + recorder.mutex.Lock() + defer recorder.mutex.Unlock() + if len(bindings) == 0 && recorder.removeError != nil { + return recorder.removeError + } + if recorder.reject && len(bindings) > 0 { + return errors.New("fixture grab collision") + } + recorder.bindings = input.CloneBindingOverrides(bindings) + return nil +} +func (recorder *tentacleBindingRecorder) TentacleBindings() []input.BindingOverride { + recorder.mutex.Lock() + defer recorder.mutex.Unlock() + return input.CloneBindingOverrides(recorder.bindings) +} + +func readerTentacleFixture(t *testing.T, mode string, contained bool) (*tentacleRuntime, *tentacleBindingRecorder, string) { + t.Helper() + directory := t.TempDir() + marker := filepath.Join(directory, mode) + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + specs := []tentacle.Spec{{ID: "probe", Presentation: strings.HasPrefix(mode, "present"), Program: []string{executable, "-test.run=^TestTentacleReaderPeer$", "--", "reader-peer", marker}}} + data, _ := json.Marshal(specs) + path := filepath.Join(directory, "launch.json") + if err := os.WriteFile(path, data, 0600); err != nil { + t.Fatal(err) + } + bindings := &tentacleBindingRecorder{reject: mode == "reject"} + runtime := newTentacleRuntime(slog.New(slog.DiscardHandler), bindings, path, "auto") + if contained { + runtime.guardianProgram = []string{executable, "-test.run=^TestManagedTentacleGuardianPeer$", "--", "managed-guardian"} + } + if !contained { + runtime.newManager = func() (*tentacle.Manager, error) { return tentacle.NewManager(tentacle.DefaultLimits(), nil) } + } + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 7*time.Second) + defer cancel() + if err := runtime.Stop(ctx); err != nil && !errors.Is(err, bindings.removeError) { + t.Error(err) + } + }) + return runtime, bindings, marker +} + +func waitTentacle(t *testing.T, check func() bool) { + t.Helper() + deadline := time.Now().Add(6 * time.Second) + for !check() { + if time.Now().After(deadline) { + t.Fatal("tentacle condition timed out") + } + time.Sleep(time.Millisecond) + } +} + +func TestReaderTentacleDispatchLearnDisable(t *testing.T) { + runtime, bindings, marker := readerTentacleFixture(t, "called", false) + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + f9, _ := input.ParseCommandChord("F9") + waitTentacle(t, func() bool { return runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" }) + settings := &liveSettings{} + settings.Store(config.DefaultSettings()) + speech := &learnSpeechRecorder{} + braille := &learnBrailleRecorder{} + presenter := &learnModePresenter{tentacles: runtime, live: settings, speech: speech, braille: braille, active: true} + presenter.handle(input.CommandEvent{Command: input.LearnKey, Chord: f9, KeyName: "F9"}) + if speech.texts[len(speech.texts)-1] != "Run the private reader probe." || braille.texts[len(braille.texts)-1] != "Run the private reader probe." { + t.Fatal("learn description missing") + } + if _, err := os.Stat(marker); !os.IsNotExist(err) { + t.Fatal("learn mode executed command") + } + rows := runtime.ShortcutRows(input.DesktopKeyboardLayout) + if len(rows) != 1 || rows[0].Keys != "F9" { + t.Fatalf("shortcut help: %+v", rows) + } + command := bindings.TentacleBindings()[0].Command + if !runtime.Invoke(context.Background(), command) { + t.Fatal("command not handled") + } + waitTentacle(t, func() bool { _, err := os.Stat(marker); return err == nil }) + runtime.Disable() + if runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" { + t.Fatal("disabled description remains") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := runtime.Stop(ctx); err != nil { + t.Fatal(err) + } + if len(bindings.TentacleBindings()) != 0 { + t.Fatal("disabled native bindings remain") + } + if len(runtime.resultSlots) != 0 { + t.Fatal("result workers remain") + } + if err := os.Remove(marker); err != nil { + t.Fatal(err) + } + runtime.Invoke(context.Background(), command) + if _, err := os.Stat(marker); !os.IsNotExist(err) { + t.Fatal("stale command executed") + } +} + +func TestReaderTentacleStartupDoesNotWaitForPeer(t *testing.T) { + runtime, bindings, _ := readerTentacleFixture(t, "stall", false) + started := make(chan error, 1) + go func() { started <- runtime.Start(context.Background()) }() + select { + case err := <-started: + if err != nil { + t.Fatal(err) + } + case <-time.After(200 * time.Millisecond): + t.Fatal("reader startup waited for handshake") + } + waitTentacle(t, func() bool { runtime.mutex.Lock(); defer runtime.mutex.Unlock(); return len(runtime.sessions) == 1 }) + runtime.Disable() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := runtime.Stop(ctx); err != nil { + t.Fatal(err) + } + if len(bindings.TentacleBindings()) != 0 { + t.Fatal("stalled peer published grabs") + } +} + +func TestReaderTentaclePresentation(t *testing.T) { + for _, mode := range []string{"present", "present-invalid", "present-delay"} { + t.Run(mode, func(t *testing.T) { + runtime, bindings, marker := readerTentacleFixture(t, mode, false) + owner := tentacleOutputFixture(t) + runtime.output = owner + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + f9, _ := input.ParseCommandChord("F9") + waitTentacle(t, func() bool { return runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" }) + command := bindings.TentacleBindings()[0].Command + runtime.Invoke(context.Background(), command) + waitTentacle(t, func() bool { _, err := os.Stat(marker); return err == nil }) + if mode == "present-delay" { + // Same focused control can change while the child computes. A + // consumed accessibility event retires the command's revision. + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan error, 1) + go func() { + done <- processEventsWithInput(ctx, slog.New(slog.DiscardHandler), discardSpeech{}, adapter, nil, nil, 0, owner.live, nil, owner.gate, nil) + }() + adapter.events <- atspi.NewEvent("object:text-changed:insert", atspi.Snapshot{}) + waitTentacle(t, func() bool { owner.mutex.Lock(); defer owner.mutex.Unlock(); return owner.current == nil }) + cancel() + if err := <-done; err != nil { + t.Fatal(err) + } + if err := os.WriteFile(marker+".release", nil, 0600); err != nil { + t.Fatal(err) + } + } + waitTentacle(t, func() bool { return len(runtime.resultSlots) == 0 }) + owner.speech.mutex.Lock() + pending := append([]speechRequest(nil), owner.speech.pending...) + owner.speech.mutex.Unlock() + if mode == "present" { + if len(pending) != 1 || pending[0].Text != "Hello, é猫😀é" || owner.braille.current().Text != "Display é猫😀é" { + t.Fatal("reader did not present the command result") + } + runtime.Disable() + if pending[0].context.Err() != nil || owner.braille.current().Text != "Core focus" { + t.Fatal("disable did not preserve accepted speech and retire the flash") + } + } else { + if len(pending) != 0 || owner.braille.current().Text != "Core focus" { + t.Fatal("invalid/stale reply reached output") + } + if mode == "present-invalid" { + waitTentacle(t, func() bool { return len(bindings.TentacleBindings()) == 0 }) + select { + case <-runtime.announcements: + default: + t.Fatal("invalid presentation was not reported") + } + } + } + }) + } +} + +func TestReaderTentacleCommandLoopHandoffAndEmergency(t *testing.T) { + runtime, bindings, marker := readerTentacleFixture(t, "called", false) + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + f9, _ := input.ParseCommandChord("F9") + waitTentacle(t, func() bool { return runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" }) + command := bindings.TentacleBindings()[0].Command + commands := &fakeCommands{commands: make(chan input.CommandEvent, 4)} + gate := newFocusGate(commands) + gate.SetSuspended(true) + barrier := make(chan struct{}, 1) + speech := &learnSpeechRecorder{} + braille := &learnBrailleRecorder{} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + worker := commandRuntime{logger: slog.New(slog.DiscardHandler), commands: commands, focusGate: gate, + tentacles: runtime, speechOutput: discardSpeech{}, stopRun: cancel, + learn: &learnModePresenter{speech: speech, braille: braille}, onPreferences: func() { barrier <- struct{}{} }} + done := make(chan error, 1) + go func() { done <- worker.run(ctx) }() + commands.commands <- input.CommandEvent{Command: command} + commands.commands <- input.CommandEvent{Command: input.Preferences} + select { + case <-barrier: + case <-time.After(time.Second): + t.Fatal("command loop stalled") + } + if _, err := os.Stat(marker); !os.IsNotExist(err) { + t.Fatal("handoff invoked tentacle") + } + gate.SetSuspended(false) + commands.commands <- input.CommandEvent{Command: command} + waitTentacle(t, func() bool { _, err := os.Stat(marker); return err == nil }) + commands.commands <- input.CommandEvent{Command: input.DisableTentacles} + commands.commands <- input.CommandEvent{Command: input.Quit} + select { + case err := <-done: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("emergency disable blocked Quit") + } + if len(speech.texts) != 1 || speech.texts[0] != "Tentacles disabled." || len(braille.texts) != 1 { + t.Fatalf("disable feedback: %v %v", speech.texts, braille.texts) + } + if runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" { + t.Fatal("emergency disable retained command") + } +} + +func TestReaderTentacleInvalidDelegationDoesNotLaunch(t *testing.T) { + runtime, bindings, marker := readerTentacleFixture(t, "called", true) + runtime.parent = t.TempDir() + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + select { + case <-runtime.done: + case <-time.After(time.Second): + t.Fatal("invalid delegation blocked startup") + } + if len(runtime.sessions) != 0 || len(bindings.TentacleBindings()) != 0 { + t.Fatal("invalid delegation admitted peer") + } + if _, err := os.Stat(marker); !os.IsNotExist(err) { + t.Fatal("uncontained fallback ran") + } + select { + case message := <-runtime.announcements: + if message != "Tentacles could not start." { + t.Fatal(message) + } + default: + t.Fatal("startup failure has no accessible status") + } +} + +func TestReaderTentacleCleanupFailureReachesReader(t *testing.T) { + runtime, bindings, _ := readerTentacleFixture(t, "called", false) + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + f9, _ := input.ParseCommandChord("F9") + waitTentacle(t, func() bool { return runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" }) + want := errors.New("fixture native removal failure") + bindings.mutex.Lock() + bindings.removeError = want + bindings.mutex.Unlock() + runtime.Disable() + select { + case err := <-runtime.failures: + if !errors.Is(err, want) { + t.Fatal(err) + } + case <-time.After(5 * time.Second): + t.Fatal("cleanup failure did not reach command loop") + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := runtime.Stop(ctx); !errors.Is(err, want) { + t.Fatalf("cleanup falsely succeeded: %v", err) + } +} + +func TestReaderTentacleFailedGrabAndCrashRevoke(t *testing.T) { + for _, mode := range []string{"reject", "crash"} { + t.Run(mode, func(t *testing.T) { + runtime, bindings, _ := readerTentacleFixture(t, mode, false) + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + f9, _ := input.ParseCommandChord("F9") + if mode == "crash" { + waitTentacle(t, func() bool { return runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" }) + runtime.Invoke(context.Background(), bindings.TentacleBindings()[0].Command) + } + waitTentacle(t, func() bool { + runtime.mutex.Lock() + defer runtime.mutex.Unlock() + if len(runtime.sessions) != 1 { + return false + } + select { + case <-runtime.sessions[0].Revoked(): + return true + default: + return false + } + }) + waitTentacle(t, func() bool { return len(bindings.TentacleBindings()) == 0 }) + if runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" { + t.Fatal("revoked command still described") + } + }) + } +} + +func TestNativeDelegatedReaderTentacle(t *testing.T) { + if os.Getenv("CTHULHU_TENTACLE_DELEGATED") != "1" { + t.Skip("requires the delegated reader launcher") + } + runtime, bindings, marker := readerTentacleFixture(t, "called", true) + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + f9, _ := input.ParseCommandChord("F9") + waitTentacle(t, func() bool { return runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" }) + runtime.Invoke(context.Background(), bindings.TentacleBindings()[0].Command) + waitTentacle(t, func() bool { _, err := os.Stat(marker); return err == nil }) + group, _ := os.ReadFile(marker) + parent, err := tentacle.DelegatedParent() + if err != nil { + t.Fatal(err) + } + expected := strings.TrimPrefix(parent, "/sys/fs/cgroup") + "/cthulhu-tentacles-" + if !strings.Contains(string(group), expected) || strings.Contains(string(group), "/reader/") { + t.Fatalf("child outside limited sibling subtree: %s", group) + } + t.Logf("contained command membership: %s", group) +} + +func TestNativeDelegatedReaderTentaclePresentation(t *testing.T) { + if os.Getenv("CTHULHU_TENTACLE_DELEGATED") != "1" { + t.Skip("requires the delegated reader launcher") + } + runtime, bindings, _ := readerTentacleFixture(t, "present", true) + owner := tentacleOutputFixture(t) + runtime.output = owner + if err := runtime.Start(context.Background()); err != nil { + t.Fatal(err) + } + f9, _ := input.ParseCommandChord("F9") + waitTentacle(t, func() bool { return runtime.Describe(f9, input.DesktopKeyboardLayout, false) != "" }) + runtime.Invoke(context.Background(), bindings.TentacleBindings()[0].Command) + waitTentacle(t, func() bool { + owner.speech.mutex.Lock() + defer owner.speech.mutex.Unlock() + return len(owner.speech.pending) == 1 && owner.braille.current().Text == "Display é猫😀é" + }) + if owner.braille.current().Text != "Display é猫😀é" { + t.Fatal("contained command did not present braille") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := runtime.Stop(ctx); err != nil { + t.Fatal(err) + } + if owner.braille.current().Text != "Core focus" { + t.Fatal("shutdown left tentacle output") + } +} diff --git a/internal/app/terminal_events.go b/internal/app/terminal_events.go new file mode 100644 index 0000000..8987d9b --- /dev/null +++ b/internal/app/terminal_events.go @@ -0,0 +1,19 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import "git.stormux.org/storm/cthulhu/internal/atspi" + +func should_ignore_terminal_scrollback(event atspi.Event) bool { + // VTE can remove old complete lines at the start of its accessible text + // while appending output at a different offset. These are not edits to + // the prompt. This event pattern occurs on both X11 and Wayland. + return event.Type == atspi.TextDeletedEvent && + event.Source.Role == "terminal" && event.Detail1 == 0 && + event.Source.TextCaretKnown && event.Source.BrailleLineStart > 0 && + event.TextChangeEndsLine && event.TextChangeLength > 0 && + event.TextChangeLength <= event.Source.BrailleLineStart +} diff --git a/internal/app/terminal_events_test.go b/internal/app/terminal_events_test.go new file mode 100644 index 0000000..20df10e --- /dev/null +++ b/internal/app/terminal_events_test.go @@ -0,0 +1,320 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "log/slog" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestProcessEventsTerminalScrollbackDeletionBothSessions(t *testing.T) { + for _, sessionType := range []string{"wayland", "x11"} { + t.Run(sessionType, func(t *testing.T) { + t.Setenv("XDG_SESSION_TYPE", sessionType) + // Both sessions must apply the same event policy, including + // an X11 launcher which also supplies WAYLAND_DISPLAY. + t.Setenv("WAYLAND_DISPLAY", "wayland-test") + speech := &fakeSpeechQueue{spoken: make(chan string, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + completed := make(chan struct{}) + go func() { + defer close(completed) + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + }() + t.Cleanup(func() { + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Error("event loop did not stop") + } + }) + + terminal := atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "Username@Host> ") + terminal.TextCaretKnown = true + terminal.BrailleLineStart = 300 + terminal.BrailleCaret = 315 + oldPrompt := "Username@Host> old command\n" + deletion := atspi.NewEventWithPayload(atspi.TextDeletedEvent, terminal, oldPrompt) + output := atspi.NewEventWithPayload(atspi.TextInsertedEvent, terminal, "Current command output") + output.Detail1 = 200 + // A caret event can arrive between the scroll and its insertion. + caret := atspi.NewEvent(atspi.CaretEvent, terminal) + adapter.events <- deletion + adapter.events <- caret + adapter.events <- output + + for _, want := range []string{"Current command output"} { + select { + case got := <-speech.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for %q", want) + } + } + for _, deleted := range []string{"x", "command"} { + edit := atspi.NewEventWithPayload(atspi.TextDeletedEvent, terminal, deleted) + edit.Detail1 = terminal.BrailleLineStart + adapter.events <- edit + select { + case got := <-speech.spoken: + if got != deleted { + t.Fatalf("editing speech = %q, want %q", got, deleted) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for deletion %q", deleted) + } + } + }) + } +} + +func TestTerminalScrollbackDeletionPreservesEditing(t *testing.T) { + t.Setenv("XDG_SESSION_TYPE", "wayland") + terminal := atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "Prompt") + terminal.TextCaretKnown = true + terminal.BrailleLineStart = 100 + terminal.BrailleCaret = 110 + base := atspi.NewEventWithPayload(atspi.TextDeletedEvent, terminal, "Old prompt\n") + for _, test := range []struct { + name string + modify func(*atspi.Event) + ignore bool + }{ + {"scroll", func(event *atspi.Event) {}, true}, + {"unicode offsets", func(event *atspi.Event) { + *event = atspi.NewEventWithPayload(atspi.TextDeletedEvent, terminal, strings.Repeat("猫", 40)+"\n") + }, true}, + {"backspace", func(event *atspi.Event) { event.Payload = "x"; event.Detail1 = 109 }, false}, + {"delete", func(event *atspi.Event) { event.Payload = "x"; event.Detail1 = 110 }, false}, + {"delete word", func(event *atspi.Event) { event.Payload = "command"; event.Detail1 = 100 }, false}, + {"first character", func(event *atspi.Event) { + *event = atspi.NewEventWithPayload(atspi.TextDeletedEvent, terminal, "x") + }, false}, + {"newline", func(event *atspi.Event) { event.Payload = "\n"; event.Detail1 = 100 }, false}, + {"current first line", func(event *atspi.Event) { event.Source.BrailleLineStart = 0 }, false}, + {"range reaches current line", func(event *atspi.Event) { event.Source.BrailleLineStart = 5 }, false}, + {"unknown caret", func(event *atspi.Event) { event.Source.TextCaretKnown = false }, false}, + {"partial line", func(event *atspi.Event) { + *event = atspi.NewEventWithPayload(atspi.TextDeletedEvent, terminal, "Old prompt") + }, false}, + {"editor", func(event *atspi.Event) { event.Source.Role = "text" }, false}, + {"insertion", func(event *atspi.Event) { event.Type = atspi.TextInsertedEvent }, false}, + } { + t.Run(test.name, func(t *testing.T) { + event := base + test.modify(&event) + if got := should_ignore_terminal_scrollback(event); got != test.ignore { + t.Fatalf("ignore = %v, want %v", got, test.ignore) + } + }) + } +} + +func TestProcessEventsCoalescesTerminalDeletionWithReplacementInsertion(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 3)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 3)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + terminal := atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "") + output := atspi.NewEventWithPayload(atspi.TextInsertedEvent, terminal, "Command output") + deletion := atspi.NewEventWithPayload(atspi.TextDeletedEvent, terminal, "old prompt") + deletion.Detail1 = 12 + prompt := atspi.NewEventWithPayload(atspi.TextInsertedEvent, terminal, "new prompt") + prompt.Detail1 = 12 + adapter.events <- output + adapter.events <- deletion + adapter.events <- prompt + + for _, expected := range []string{"Command output", "new prompt"} { + select { + case text := <-speech.spoken: + if text != expected { + t.Fatalf("spoken text = %q, want %q", text, expected) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for terminal speech %q", expected) + } + } + select { + case text := <-speech.spoken: + t.Fatalf("terminal redraw deletion was presented as %q", text) + case <-time.After(2 * terminalMutationDebounce): + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestProcessEventsPresentsStandaloneTerminalDeletion(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + terminal := atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "") + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, terminal, "x") + select { + case text := <-speech.spoken: + if text != "x" { + t.Fatalf("spoken deletion = %q, want %q", text, "x") + } + case <-time.After(time.Second): + t.Fatal("standalone terminal deletion was not presented") + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestProcessEventsDoesNotCoalesceTerminalChangesAtDifferentOffsets(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + terminal := atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "") + deletion := atspi.NewEventWithPayload(atspi.TextDeletedEvent, terminal, "x") + deletion.Detail1 = 12 + insertion := atspi.NewEventWithPayload(atspi.TextInsertedEvent, terminal, "y") + insertion.Detail1 = 13 + adapter.events <- deletion + adapter.events <- insertion + + for _, expected := range []string{"x", "y"} { + select { + case text := <-speech.spoken: + if text != expected { + t.Fatalf("spoken text = %q, want %q", text, expected) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for terminal speech %q", expected) + } + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestProcessEventsCoalescesTerminalFocusWithFollowingInsertion(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 2)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, time.Hour) + close(completed) + }() + + terminal := atspi.NewSnapshot("/accessible/terminal", "Terminal", "terminal", "", "Old prompt") + focused := atspi.NewEvent(atspi.FocusedStateEvent, terminal) + focused.Detail1 = 1 + adapter.events <- focused + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, terminal, "New prompt") + + select { + case text := <-speech.spoken: + if text != "New prompt" { + t.Fatalf("speech = %q, want only following insertion", text) + } + case <-time.After(time.Second): + t.Fatal("following terminal insertion was not presented") + } + select { + case text := <-speech.spoken: + t.Fatalf("redundant terminal focus was presented as %q", text) + default: + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestProcessEventsPresentsTerminalFocusWithoutFollowingInsertion(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + processEvents(ctx, slog.New(slog.DiscardHandler), speech, adapter, 0) + close(completed) + }() + + terminal := atspi.NewSnapshot("/accessible/terminal", "Terminal", "terminal", "", "Prompt") + terminal.ApplicationName = "TestTerminal" + focused := atspi.NewEvent(atspi.FocusedStateEvent, terminal) + focused.Detail1 = 1 + adapter.events <- focused + select { + case text := <-speech.spoken: + if text != "Terminal, terminal, Prompt" { + t.Fatalf("terminal focus speech = %q", text) + } + case <-time.After(time.Second): + t.Fatal("terminal focus was not presented after debounce") + } + + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} diff --git a/internal/app/test_helpers_test.go b/internal/app/test_helpers_test.go new file mode 100644 index 0000000..03a57c3 --- /dev/null +++ b/internal/app/test_helpers_test.go @@ -0,0 +1,247 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package app + +import ( + "context" + "sync" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +type fakeSpeaker struct { + connectError error + connected bool + speakError error + spoken chan string + closed bool + canceled bool + canceledOnClose bool +} + +func (speaker *fakeSpeaker) Connect(context.Context) error { + speaker.connected = true + return speaker.connectError +} + +func (speaker *fakeSpeaker) Speak(_ context.Context, text string) error { + if speaker.speakError != nil { + return speaker.speakError + } + speaker.spoken <- text + return nil +} + +func (speaker *fakeSpeaker) Cancel(context.Context) error { speaker.canceled = true; return nil } + +func (speaker *fakeSpeaker) Close(context.Context) error { + speaker.canceledOnClose = speaker.canceled + speaker.closed = true + return nil +} + +type fakeAdapter struct { + startError error + stopError error + started bool + stopped bool + events chan atspi.Event + tree *atspi.AccessibleTree + captureErr error + capture func(context.Context) (*atspi.AccessibleTree, error) + captureSoundGeometry bool +} + +type fakeSpeechQueue struct { + spoken chan string + requests chan speechRequest + interrupt chan struct{} +} + +type fixedInputActivity struct{ activity input.Activity } + +func (source fixedInputActivity) RecentInput() input.Activity { return source.activity } + +type sequencedInputActivity struct { + mutex sync.Mutex + sequence uint64 +} + +func (source *sequencedInputActivity) RecentInput() input.Activity { + source.mutex.Lock() + defer source.mutex.Unlock() + return input.Activity{Sequence: source.sequence} +} + +func (source *sequencedInputActivity) set(sequence uint64) { + source.mutex.Lock() + source.sequence = sequence + source.mutex.Unlock() +} + +func (queue *fakeSpeechQueue) Enqueue(request speechRequest) { + if queue.requests != nil { + queue.requests <- request + } + queue.spoken <- request.Text +} + +func (queue *fakeSpeechQueue) Interrupt() { + if queue.interrupt != nil { + queue.interrupt <- struct{}{} + } +} + +func (adapter *fakeAdapter) Events() <-chan atspi.Event { return adapter.events } + +func (adapter *fakeAdapter) Overflow() uint64 { return 0 } + +func (adapter *fakeAdapter) SetCaptureSoundGeometry(enabled bool) { + adapter.captureSoundGeometry = enabled +} + +func (adapter *fakeAdapter) CaptureDesktop(ctx context.Context) (*atspi.AccessibleTree, error) { + if adapter.capture != nil { + return adapter.capture(ctx) + } + return adapter.tree, adapter.captureErr +} + +func (adapter *fakeAdapter) CaptureReviewWindow(ctx context.Context, _ atspi.ObjectID) (*atspi.AccessibleTree, error) { + return adapter.CaptureDesktop(ctx) +} + +func (adapter *fakeAdapter) CaptureDocument(ctx context.Context, _ atspi.ObjectID) (*atspi.AccessibleTree, error) { + return adapter.CaptureDesktop(ctx) +} + +func (adapter *fakeAdapter) CaptureDocumentText(ctx context.Context, _ atspi.ObjectID) (*atspi.AccessibleTree, error) { + return adapter.CaptureDesktop(ctx) +} + +func (adapter *fakeAdapter) Start(context.Context) error { + adapter.started = true + return adapter.startError +} + +func (adapter *fakeAdapter) Stop(context.Context) error { + adapter.stopped = true + return adapter.stopError +} + +type fakeInputListener struct { + events chan input.Event + modifierKeycodes input.ModifierKeycodes + startError error + started bool + stopped bool +} + +func (listener *fakeInputListener) Events() <-chan input.Event { + return listener.events +} + +func (listener *fakeInputListener) ModifierKeycodes() input.ModifierKeycodes { + return listener.modifierKeycodes +} + +func (listener *fakeInputListener) Overflow() uint64 { return 0 } + +func (listener *fakeInputListener) Start(context.Context) error { + listener.started = true + return listener.startError +} + +func (listener *fakeInputListener) Stop(context.Context) error { + listener.stopped = true + return nil +} + +func contains_string(values []string, wanted string) bool { + for _, value := range values { + if value == wanted { + return true + } + } + return false +} + +type eventDiagnosticsWriter struct { + started chan struct{} + startOnce sync.Once + canceled chan struct{} + cancelOnce sync.Once +} + +func (writer *eventDiagnosticsWriter) Write([]byte) (int, error) { + writer.startOnce.Do(func() { close(writer.started) }) + <-writer.canceled + return 0, nil +} + +func (writer *eventDiagnosticsWriter) Cancel() error { + writer.cancelOnce.Do(func() { close(writer.canceled) }) + return nil +} + +func (writer *eventDiagnosticsWriter) Close() error { return nil } + +type silentSound struct{} + +type rejectingSound struct{ silentSound } + +type recordingSound struct { + started chan struct{} + stopped bool + stopError error +} + +func (sound *recordingSound) Start(context.Context) error { + close(sound.started) + return nil +} + +func (sound *recordingSound) Stop(context.Context) error { + sound.stopped = true + return sound.stopError +} + +func (sound *recordingSound) Enqueue(sound.Cue) bool { return true } + +func (sound *recordingSound) EnqueueBatch([]sound.Cue) bool { return true } + +func (sound *recordingSound) Available(string) bool { return true } + +type silentCommands struct{} + +type fakeCommands struct { + commands chan input.CommandEvent + lockStates chan input.LockState +} + +func (commands *fakeCommands) Commands() <-chan input.CommandEvent { return commands.commands } + +func (commands *fakeCommands) LockStates() <-chan input.LockState { return commands.lockStates } + +func (commands *fakeCommands) Failures() <-chan error { return nil } + +func (commands *fakeCommands) Start(context.Context) error { return nil } + +func (commands *fakeCommands) Stop(context.Context) error { return nil } diff --git a/internal/app/text_selection.go b/internal/app/text_selection.go new file mode 100644 index 0000000..f854a83 --- /dev/null +++ b/internal/app/text_selection.go @@ -0,0 +1,91 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// textSelection tracks only the focused text object. Its cached content is +// bounded by the native snapshot and is retired when focus changes. +type textSelection struct { + id atspi.ObjectID + start, end int + text string +} + +const selectionFragmentLimit = 120 +const lineSelectionFragmentLimit = 4096 + +func (selection *textSelection) reset(snapshot atspi.Snapshot) { + selection.id = snapshot.ID() + selection.start, selection.end = snapshot.SelectionStart, snapshot.SelectionEnd + selection.text = snapshot.SelectionText +} + +func (selection *textSelection) changed(snapshot atspi.Snapshot) string { + return selection.changedWithLimit(snapshot, selectionFragmentLimit) +} + +func (selection *textSelection) changedWithLimit(snapshot atspi.Snapshot, fragmentLimit int) string { + start, end := snapshot.SelectionStart, snapshot.SelectionEnd + if selection.id != snapshot.ID() { + selection.reset(snapshot) + return "" + } + oldStart, oldEnd, oldText := selection.start, selection.end, selection.text + selection.reset(snapshot) + if start == oldStart && end == oldEnd && oldText == snapshot.SelectionText { + return "" + } + if end <= start { + if oldEnd > oldStart { + return "selection removed" + } + return "" + } + if oldEnd <= oldStart { + return selectionFragment(snapshot.SelectionText, "selected", fragmentLimit) + } + var changes []string + if start > oldStart { + changes = append(changes, selectionFragment(selectionSlice(oldText, 0, min(oldEnd, start)-oldStart), "unselected", fragmentLimit)) + } + if end < oldEnd { + changes = append(changes, selectionFragment(selectionSlice(oldText, max(oldStart, end)-oldStart, oldEnd-oldStart), "unselected", fragmentLimit)) + } + if start < oldStart { + changes = append(changes, selectionFragment(selectionSlice(snapshot.SelectionText, 0, min(end, oldStart)-start), "selected", fragmentLimit)) + } + if end > oldEnd { + changes = append(changes, selectionFragment(selectionSlice(snapshot.SelectionText, max(start, oldEnd)-start, end-start), "selected", fragmentLimit)) + } + if len(changes) == 0 { + return "selection changed" + } + return strings.Join(changes, ", ") +} + +func selectionSlice(value string, start, end int) string { + runes := []rune(value) + if start < 0 || end > len(runes) || start >= end { + return "" + } + return string(runes[start:end]) +} + +func selectionFragment(value, change string, limit int) string { + if utf8.RuneCountInString(value) > limit { + return change + } + value = strings.Join(strings.Fields(value), " ") + if value == "" { + return change + } + return value + " " + change +} diff --git a/internal/app/text_selection_test.go b/internal/app/text_selection_test.go new file mode 100644 index 0000000..a66e023 --- /dev/null +++ b/internal/app/text_selection_test.go @@ -0,0 +1,213 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/logging" +) + +func TestTextSelectionDiagnosticsIncludeNativeOffsets(t *testing.T) { + var output bytes.Buffer + logger := logging.New(&output, logging.Options{Level: slog.LevelDebug}) + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 4)} + entry := atspi.Snapshot{BusName: ":1.7", Path: "/entry", Role: "entry", Editable: true, Focused: true} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + entry.TextCaretKnown, entry.BrailleCaret, entry.BrailleLineStart = true, 13, 10 + entry.SelectionStart, entry.SelectionEnd, entry.SelectionText = 11, 13, "猫a" + adapter.events <- atspi.NewEvent(atspi.TextSelectionChangedEvent, entry) + close(adapter.events) + if err := processEventsWithInput(context.Background(), logger, queue, adapter, nil, nil, 0, nil, nil, nil, nil); err != nil { + t.Fatal(err) + } + decoder := json.NewDecoder(&output) + for decoder.More() { + var record map[string]any + if err := decoder.Decode(&record); err != nil { + t.Fatal(err) + } + if record["message"] != "received accessibility event" || record["type"] != atspi.TextSelectionChangedEvent { + continue + } + for key, want := range map[string]any{"bus": ":1.7", "source_path": "/entry", "native_caret_known": true, + "native_caret_offset": float64(13), "native_line_start": float64(10), "selection_start": float64(11), "selection_end": float64(13)} { + if record[key] != want { + t.Fatalf("selection diagnostic %s = %v, want %v", key, record[key], want) + } + } + return + } + t.Fatal("selection event diagnostics missing") +} + +func TestTextSelectionCrossingAnchor(t *testing.T) { + old := atspi.Snapshot{BusName: ":1.7", Path: "/entry", SelectionStart: 0, SelectionEnd: 2, SelectionText: "ab"} + var selection textSelection + selection.reset(old) + newSelection := old + newSelection.SelectionStart, newSelection.SelectionEnd, newSelection.SelectionText = 3, 5, "de" + if got := selection.changed(newSelection); got != "ab unselected, de selected" { + t.Fatalf("crossed anchor = %q", got) + } +} + +func TestTextSelectionSpeaksChangedCharactersAndWords(t *testing.T) { + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 16)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + tracker := &input.IntentTracker{} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, tracker, nil, nil) + }() + defer func() { cancel(); <-done }() + expect := func(want string) { + t.Helper() + select { + case got := <-queue.requests: + if got.Text != want { + t.Fatalf("speech = %q, want %q", got.Text, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } + entry := atspi.Snapshot{BusName: ":1.7", Path: "/entry", Role: "entry", Name: "Message", Editable: true, Focused: true} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + expect("Message, entry") + + tracker.Observe(input.NewKeyEvent(0, true, "Shift_L")) + tracker.Observe(input.NewKeyEvent(0, true, "Right")) + entry.SelectionStart, entry.SelectionEnd, entry.SelectionText = 0, 1, "h" + adapter.events <- atspi.NewEvent(atspi.TextSelectionChangedEvent, entry) + expect("h selected") + entry.CaretCharacter = "h" + adapter.events <- atspi.NewEvent(atspi.CaretEvent, entry) + select { + case got := <-queue.requests: + t.Fatalf("selection caret spoke twice: %q", got.Text) + case <-time.After(30 * time.Millisecond): + } + + tracker.Observe(input.NewKeyEvent(0, true, "Control_L")) + tracker.Observe(input.NewKeyEvent(0, true, "Right")) + entry.SelectionEnd, entry.SelectionText = 5, "hello" + adapter.events <- atspi.NewEvent(atspi.TextSelectionChangedEvent, entry) + expect("ello selected") + + tracker.Observe(input.NewKeyEvent(0, true, "Left")) + entry.SelectionEnd, entry.SelectionText = 1, "h" + adapter.events <- atspi.NewEvent(atspi.TextSelectionChangedEvent, entry) + expect("ello unselected") + + adapter.events <- atspi.NewEvent(atspi.TextSelectionChangedEvent, entry) + select { + case got := <-queue.requests: + t.Fatalf("unchanged selection spoke: %q", got.Text) + case <-time.After(30 * time.Millisecond): + } + tracker.Observe(input.NewKeyEvent(0, false, "Control_L")) + longLine := "h" + strings.Repeat("a", 199) + tracker.Observe(input.NewKeyEvent(0, true, "Down")) + entry.SelectionEnd, entry.SelectionText = 200, longLine + adapter.events <- atspi.NewEvent(atspi.TextSelectionChangedEvent, entry) + expect(strings.Repeat("a", 199) + " selected") + tracker.Observe(input.NewKeyEvent(0, true, "Up")) + entry.SelectionEnd, entry.SelectionText = 1, "h" + adapter.events <- atspi.NewEvent(atspi.TextSelectionChangedEvent, entry) + expect(strings.Repeat("a", 199) + " unselected") + tracker.Observe(input.NewKeyEvent(0, false, "Shift_L")) + tracker.Observe(input.NewKeyEvent(0, true, "Right")) + entry.CaretCharacter = "o" + adapter.events <- atspi.NewEvent(atspi.CaretEvent, entry) + expect("o") +} + +func TestLongSelectionWithoutLineNavigationKeepsBoundedSpeech(t *testing.T) { + var selection textSelection + snapshot := atspi.Snapshot{BusName: ":1.7", Path: "/entry"} + selection.reset(snapshot) + snapshot.SelectionEnd, snapshot.SelectionText = 200, strings.Repeat("a", 200) + if got := selection.changed(snapshot); got != "selected" { + t.Fatalf("large non-line selection = %q", got) + } +} + +func TestLongLineSelectionExtendsUpward(t *testing.T) { + var selection textSelection + snapshot := atspi.Snapshot{BusName: ":1.7", Path: "/entry", SelectionStart: 200, SelectionEnd: 201, SelectionText: "z"} + selection.reset(snapshot) + snapshot.SelectionStart, snapshot.SelectionText = 0, strings.Repeat("a", 200)+"z" + if got, want := selection.changedWithLimit(snapshot, lineSelectionFragmentLimit), strings.Repeat("a", 200)+" selected"; got != want { + t.Fatalf("upward line selection = %q, want %q", got, want) + } +} + +func TestClipboardFeedbackRequiresEditableMutation(t *testing.T) { + queue := &autocompleteRequestQueue{requests: make(chan speechRequest, 16)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + tracker := &input.IntentTracker{} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, nil, nil, 0, nil, tracker, nil, nil) + }() + defer func() { cancel(); <-done }() + expect := func(want string) { + t.Helper() + select { + case got := <-queue.requests: + if got.Text != want { + t.Fatalf("speech = %q, want %q", got.Text, want) + } + case <-time.After(time.Second): + t.Fatalf("missing %q", want) + } + } + entry := atspi.Snapshot{BusName: ":1.7", Path: "/entry", Role: "entry", Name: "Message", Editable: true, Focused: true} + adapter.events <- atspi.NewEvent(atspi.FocusEvent, entry) + expect("Message, entry") + tracker.Observe(input.NewKeyEvent(0, true, "Control_L")) + tracker.Observe(input.NewKeyEvent(0, true, "v")) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, "hello") + expect("pasted from clipboard") + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, entry, " again") + entry.SelectionStart, entry.SelectionEnd, entry.SelectionText = 0, 5, "hello" + adapter.events <- atspi.NewEvent(atspi.TextSelectionChangedEvent, entry) + entry.CaretCharacter = "o" + adapter.events <- atspi.NewEvent(atspi.CaretEvent, entry) + select { + case got := <-queue.requests: + t.Fatalf("paste follow-up interrupted announcement: %q", got.Text) + case <-time.After(30 * time.Millisecond): + } + tracker.Observe(input.NewKeyEvent(0, true, "x")) + adapter.events <- atspi.NewEventWithPayload(atspi.TextDeletedEvent, entry, "hello") + expect("cut") + + password := entry + password.Path, password.Role = "/password", "password text" + adapter.events <- atspi.NewEvent(atspi.FocusEvent, password) + expect("Message, password text") + tracker.Observe(input.NewKeyEvent(0, true, "v")) + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, password, "secret") + select { + case got := <-queue.requests: + t.Fatalf("protected edit spoke: %q", got.Text) + case <-time.After(30 * time.Millisecond): + } +} diff --git a/internal/app/version.go b/internal/app/version.go new file mode 100644 index 0000000..30b8fa0 --- /dev/null +++ b/internal/app/version.go @@ -0,0 +1,18 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/version" + "git.stormux.org/storm/cthulhu/internal/wine" +) + +func presentVersion(speech speechEnqueuer, atspiVersion, sessionType, sessionDesktop string) { + speech.Enqueue(speechRequest{ + Text: version.Details(atspiVersion, sessionType, sessionDesktop, wine.InstalledVersion()), + Role: "system", + Cause: "version", + }) +} diff --git a/internal/app/version_test.go b/internal/app/version_test.go new file mode 100644 index 0000000..c1ece08 --- /dev/null +++ b/internal/app/version_test.go @@ -0,0 +1,31 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/version" + "git.stormux.org/storm/cthulhu/internal/wine" +) + +func TestPresentVersion(t *testing.T) { + speech := &fakeSpeechQueue{ + spoken: make(chan string, 1), + requests: make(chan speechRequest, 1), + interrupt: make(chan struct{}, 1), + } + presentVersion(speech, "2.58.0", "x11", "GNOME") + select { + case <-speech.interrupt: + t.Fatal("version result interrupted speech again") + default: + } + request := <-speech.requests + want := version.Details("2.58.0", "x11", "GNOME", wine.InstalledVersion()) + if request.Text != want || request.Role != "system" || request.Cause != "version" { + t.Fatalf("request = %+v, want %q as system version", request, want) + } +} diff --git a/internal/app/wayland_native_test.go b/internal/app/wayland_native_test.go new file mode 100644 index 0000000..0834ec0 --- /dev/null +++ b/internal/app/wayland_native_test.go @@ -0,0 +1,101 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "os" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "github.com/godbus/dbus/v5" +) + +type RuntimeKeyboardMonitor struct{ ready chan struct{} } +type RuntimeKeyGrab struct{ Symbol, Modifiers uint32 } + +func (*RuntimeKeyboardMonitor) WatchKeyboard() *dbus.Error { return nil } +func (monitor *RuntimeKeyboardMonitor) SetKeyGrabs([]uint32, []RuntimeKeyGrab) *dbus.Error { + select { + case monitor.ready <- struct{}{}: + default: + } + return nil +} + +func TestNativeWaylandRuntimeKeyboardPreferencesAndQuit(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" { + t.Skip("requires private dbus-run-session") + } + t.Setenv("XDG_SESSION_TYPE", "wayland") + t.Setenv("DISPLAY", "") + connection, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + defer connection.Close() + const managerName = "org.freedesktop.a11y.Manager" + const managerPath = dbus.ObjectPath("/org/freedesktop/a11y/Manager") + const monitorInterface = "org.freedesktop.a11y.KeyboardMonitor" + monitor := &RuntimeKeyboardMonitor{ready: make(chan struct{}, 1)} + if err := connection.Export(monitor, managerPath, monitorInterface); err != nil { + t.Fatal(err) + } + if result, err := connection.RequestName(managerName, dbus.NameFlagDoNotQueue); err != nil || result != dbus.RequestNameReplyPrimaryOwner { + t.Fatalf("keyboard manager: %v %v", result, err) + } + speaker := &fakeSpeaker{spoken: make(chan string, 32)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 1)} + preferences := make(chan struct{}, 1) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan error, 1) + go func() { + completed <- Run(ctx, Options{ + Logger: slog.New(slog.DiscardHandler), + newSpeaker: func() Speaker { return speaker }, newSound: func() soundService { return silentSound{} }, + newAdapter: func() Adapter { return adapter }, onPreferences: func() { preferences <- struct{}{} }, + }) + }() + select { + case <-monitor.ready: + case <-time.After(3 * time.Second): + t.Fatal("runtime did not select shared keyboard backend") + } + key := func(symbol uint32, code uint16, released bool) { + t.Helper() + if err := connection.Emit(managerPath, monitorInterface+".KeyEvent", released, uint32(0), symbol, uint32(0), code); err != nil { + t.Fatal(err) + } + } + key(0xff63, 118, false) + key(' ', 65, false) + key(' ', 65, true) + key(0xff63, 118, true) + select { + case <-preferences: + case err := <-completed: + t.Fatalf("runtime exited before preferences: %v", err) + case <-time.After(3 * time.Second): + t.Fatal("Wayland preferences shortcut was not dispatched") + } + key(0xff63, 118, false) + key('q', 24, false) + key(0xff63, 118, true) + key('q', 24, true) + select { + case err := <-completed: + if err != nil { + t.Fatal(err) + } + case <-time.After(4 * time.Second): + t.Fatal("Wayland quit shortcut did not stop runtime") + } + if !adapter.stopped || !speaker.closed { + t.Fatal("Wayland runtime shutdown leaked services") + } +} diff --git a/internal/app/webscripts.go b/internal/app/webscripts.go new file mode 100644 index 0000000..d3b799b --- /dev/null +++ b/internal/app/webscripts.go @@ -0,0 +1,97 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/notification" + "git.stormux.org/storm/cthulhu/internal/webscripts" +) + +// webScriptController is owned by processEventsWithInput. Delayed presentation +// runs in that loop, preserving event order without timer callback goroutines. +type webScriptController struct { + registry webscripts.Registry + timer *time.Timer + due <-chan time.Time + speech speechEnqueuer + notifications *notification.Presenter + braille interface { + Flash(string, config.BrailleOptions) bool + } + live *liveSettings + gate *focusGate +} + +func (controller *webScriptController) handle(event atspi.Event) bool { + retiring := event.Type == atspi.WindowDestroyedEvent || event.Type == atspi.DefunctStateEvent && event.Detail1 != 0 + if retiring { + id := event.Source.ID() + if event.Type == atspi.WindowDestroyedEvent && event.Window.Valid() { + id = event.Window + } + controller.registry.Retire(id.BusName, id.Path) + } + messages, handled := controller.registry.Receive(event.Source.ApplicationProcess, + event.Type, event.Detail1, event.WebNotification, time.Now()) + controller.present(messages) + if handled || retiring { + controller.schedule() + } + return handled +} + +func (controller *webScriptController) schedule() { + deadline := controller.registry.Deadline() + controller.due = nil + if controller.timer != nil { + controller.timer.Stop() + } + if deadline.IsZero() { + return + } + if controller.timer == nil { + controller.timer = time.NewTimer(time.Until(deadline)) + } else { + controller.timer.Reset(time.Until(deadline)) + } + controller.due = controller.timer.C +} + +func (controller *webScriptController) flush() { + if controller.gate.Locked() { + controller.reset() + return + } + controller.present(controller.registry.Flush(time.Now())) + controller.schedule() +} + +func (controller *webScriptController) present(messages []string) { + if controller.gate.Locked() { + return + } + for _, message := range messages { + controller.notifications.Save(message, notification.SaveOptions{AppName: "Steam", Source: "steam"}) + if controller.braille != nil { + options := config.DefaultSettings().Braille + if controller.live != nil { + options = controller.live.Load().Braille + } + controller.braille.Flash(message, options) + } + controller.speech.Enqueue(speechRequest{ + Text: message, Role: "notification", Cause: "steam-notification", BypassFocusGate: true, + }) + } +} + +func (controller *webScriptController) reset() { + controller.registry.Reset() + controller.schedule() +} diff --git a/internal/app/webscripts_test.go b/internal/app/webscripts_test.go new file mode 100644 index 0000000..6cba8bb --- /dev/null +++ b/internal/app/webscripts_test.go @@ -0,0 +1,114 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/notification" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/webscripts" +) + +func steamToastEvent(text string) atspi.Event { + source := atspi.NewSnapshot("/fragment", "", "static", "", "") + source.BusName = ":1.42" + source.ApplicationName = "Chromium" + source.ApplicationProcess = "steamwebhelper" + event := atspi.NewEventWithPayload(atspi.TextInsertedEvent, source, text) + event.WebNotification = &webscripts.Notification{BusName: source.BusName, RootPath: "/toast", WindowPath: "/steam", Text: text} + event.ForegroundMismatch = true + return event +} + +func TestSteamBackgroundNotificationReachesSpeechBrailleAndHistory(t *testing.T) { + adapter := &foregroundAdapter{fakeAdapter: fakeAdapter{events: make(chan atspi.Event, 8)}, changes: make(chan struct{}, 1)} + state := atspi.ForegroundState{Client: xorg.Foreground{Known: true, Window: 101}, Epoch: 1} + adapter.state.Store(&state) + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + gate := &focusGate{} + gate.SetSuspended(true) + display := &flashRecorder{} + history := notification.NewPresenter() + output := outputQueue{speech: gatedSpeech{speech: queue, gate: gate}, braille: display} + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan struct{}) + go func() { + defer close(done) + processEventsWithInput(ctx, slog.New(slog.DiscardHandler), output, adapter, nil, nil, 0, nil, nil, gate, history) + }() + defer func() { cancel(); <-done }() + adapter.events <- steamToastEvent("Username") + adapter.events <- steamToastEvent("Playing: Example Game") + select { + case message := <-queue.spoken: + if message != "Steam: Username Playing: Example Game" { + t.Fatalf("fragmented message: %q", message) + } + case <-time.After(2 * time.Second): + t.Fatal("background Steam notification was filtered or timer did not fire") + } + if !gate.Suspended() { + t.Fatal("background toast took foreground ownership") + } + if entries := history.Entries(); len(entries) != 1 || entries[0].Message != "Steam: Username Playing: Example Game" { + t.Fatalf("notification history: %+v", entries) + } + if len(display.messages) != 1 || display.messages[0] != "Steam: Username Playing: Example Game" { + t.Fatalf("braille messages: %q", display.messages) + } + // A Chromium page with identical metadata cannot borrow the Steam match. + other := steamToastEvent("Unrelated browser content") + other.Source.ApplicationProcess = "chromium" + other.Source.LiveRegion = true + adapter.events <- other + // A normal accepted focus event is a barrier for the rejected event above. + focus := ownerEvent(atspi.FocusedStateEvent, ":1.43", "/window", "/button") + focus.Source.Name, focus.Source.Role = "Current control", "button" + focus.Source.Focused, focus.Detail1, focus.Foreground = true, 1, state + adapter.events <- focus + expectActivationSpeech(t, queue.spoken, "Current control, button") + select { + case message := <-queue.spoken: + t.Fatalf("background Chromium spoke: %q", message) + default: + } + if len(history.Entries()) != 1 { + t.Fatal("background Chromium entered notification history") + } +} + +func TestSteamNotificationTimerCancelledOnLockAndDestruction(t *testing.T) { + for _, retire := range []string{"lock", "root", "window"} { + t.Run(retire, func(t *testing.T) { + queue := &fakeSpeechQueue{spoken: make(chan string, 1)} + history := notification.NewPresenter() + gate := &focusGate{} + controller := &webScriptController{speech: queue, notifications: history, gate: gate} + defer controller.reset() + if !controller.handle(steamToastEvent("Pending content")) || controller.due == nil { + t.Fatal("toast did not arm a timer") + } + switch retire { + case "lock": + gate.secure.Store(true) + controller.flush() + case "root": + event := atspi.NewEvent(atspi.DefunctStateEvent, atspi.Snapshot{BusName: ":1.42", Path: "/toast"}) + event.Detail1 = 1 + controller.handle(event) + case "window": + controller.handle(atspi.NewEvent(atspi.WindowDestroyedEvent, atspi.Snapshot{BusName: ":1.42", Path: "/steam"})) + } + if controller.due != nil || !controller.registry.Deadline().IsZero() || len(history.Entries()) != 0 { + t.Fatal("retired toast remained queued") + } + }) + } +} diff --git a/internal/app/window_owner.go b/internal/app/window_owner.go new file mode 100644 index 0000000..d0846c4 --- /dev/null +++ b/internal/app/window_owner.go @@ -0,0 +1,154 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// windowOwner keeps application, top-level window, and object focus as +// separate lifecycles. The event loop remains the sole owner of this state. +type windowOwner struct { + applicationBus string + window atspi.ObjectID + focus atspi.ObjectID + activated bool + title string +} + +func (owner *windowOwner) activate(event atspi.Event) (duplicate bool) { + window := eventWindow(event) + if window.Valid() && window == owner.window { + if owner.activated { + return true + } + owner.activated = true + owner.title = activationTitle(event) + return false + } + owner.window = window + owner.applicationBus = window.BusName + owner.focus = event.Source.ID() + owner.activated = true + owner.title = activationTitle(event) + return false +} + +func (owner *windowOwner) follow(event atspi.Event) bool { + window := eventWindow(event) + if owner.window.Valid() && window.Valid() && window != owner.window { + // A focused object can precede window:activate during an actual X11 + // handoff. The native adapter has already rejected objects in a known + // inactive window, so confirmed focused state may establish the new owner. + if !event.Source.Focused { + return false + } + owner.window = window + owner.applicationBus = window.BusName + owner.activated = false + owner.title = "" + } + if !owner.window.Valid() && window.Valid() { + owner.window = window + owner.applicationBus = window.BusName + owner.activated = false + owner.title = "" + } + owner.focus = event.Source.ID() + return true +} + +func (owner *windowOwner) end(event atspi.Event, consumedCommand bool) bool { + window := eventWindow(event) + if !owner.window.Valid() || !window.Valid() || window != owner.window { + return false + } + // Python rechecks active state because passive X11 grabs can emit a + // transient deactivate/activate pair while the same window stays active. + if event.Type == atspi.WindowDeactivatedEvent { + if consumedCommand || event.Source.StatesKnown && event.Source.Active { + return false + } + } + owner.clear() + return true +} + +// containsLoad permits a document replacement only inside the existing focus +// context. A load completion is not a window activation, even when a provider +// still reports focused or active state for a background document. +func (owner *windowOwner) containsLoad(event atspi.Event) bool { + window := eventWindow(event) + if owner.window.Valid() { + // The old document may become defunct before its replacement loads. + // Its window still owns the context even though object focus is gone. + return window == owner.window && event.Source.BusName == owner.applicationBus + } + return owner.focus.Valid() && event.Source.BusName == owner.focus.BusName +} + +func (owner *windowOwner) defunct(event atspi.Event) (windowEnded, focusEnded bool) { + if event.Detail1 == 0 { + return false, false + } + id := event.Source.ID() + if owner.window.Valid() && id == owner.window { + owner.clear() + return true, true + } + if owner.focus.Valid() && id == owner.focus { + owner.focus = atspi.ObjectID{} + return false, true + } + return false, false +} + +func (owner *windowOwner) clear() { + owner.applicationBus = "" + owner.window = atspi.ObjectID{} + owner.focus = atspi.ObjectID{} + owner.activated = false + owner.title = "" +} + +func activationTitle(event atspi.Event) string { + if title := strings.TrimSpace(event.WindowTitle); title != "" { + return title + } + if event.Source.ID() == eventWindow(event) { + return strings.TrimSpace(event.Source.Name) + } + return "" +} + +// Track empty names as well so restoring an earlier title is a real change. +func (owner *windowOwner) changeTitle(event atspi.Event) bool { + if !owner.window.Valid() || event.Source.ID() != owner.window { + return false + } + title := strings.TrimSpace(event.Source.Name) + if title == owner.title { + return false + } + owner.title = title + return title != "" +} + +func eventWindow(event atspi.Event) atspi.ObjectID { + if event.Window.Valid() { + return event.Window + } + // Window lifecycle fixtures and older adapters identify the top-level in + // OriginPath. For object events OriginPath is the object itself, so it must + // not be promoted to a window owner. + switch event.Type { + case atspi.WindowActivatedEvent, atspi.WindowDeactivatedEvent, atspi.WindowDestroyedEvent: + return atspi.NewObjectID(event.Source.BusName, event.OriginPath) + default: + return atspi.ObjectID{} + } +} diff --git a/internal/app/window_owner_test.go b/internal/app/window_owner_test.go new file mode 100644 index 0000000..32d27b6 --- /dev/null +++ b/internal/app/window_owner_test.go @@ -0,0 +1,106 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func ownerEvent(eventType, bus, window, focus string) atspi.Event { + event := atspi.NewEvent(eventType, atspi.Snapshot{BusName: bus, Path: focus}) + event.Window = atspi.NewObjectID(bus, window) + return event +} + +func TestWindowOwnerKeepsWindowAndFocusIndependent(t *testing.T) { + var owner windowOwner + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.40", "/window", "/button") + if owner.activate(activation) { + t.Fatal("first activation was treated as duplicate") + } + if owner.window != activation.Window || owner.focus != activation.Source.ID() || owner.applicationBus != ":1.40" { + t.Fatalf("owner = %#v", owner) + } + + focus := ownerEvent(atspi.FocusedStateEvent, ":1.40", "/window", "/entry") + if !owner.follow(focus) || owner.window != activation.Window || owner.focus != focus.Source.ID() { + t.Fatalf("focus did not remain in active window: %#v", owner) + } + if !owner.activate(activation) || owner.focus != focus.Source.ID() { + t.Fatal("duplicate activation replaced descendant focus") + } +} + +func TestFocusBeforeActivationStillAdmitsFirstWindowActivation(t *testing.T) { + var owner windowOwner + focus := ownerEvent(atspi.FocusedStateEvent, ":1.40", "/window", "/entry") + focus.Source.Focused = true + if !owner.follow(focus) || owner.activated { + t.Fatalf("focus-first ownership = %#v", owner) + } + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.40", "/window", "/window") + if owner.activate(activation) || owner.focus != focus.Source.ID() { + t.Fatalf("first activation lost focus or was skipped: %#v", owner) + } + if !owner.activate(activation) { + t.Fatal("repeated activation was not suppressed") + } +} + +func TestWindowOwnerRejectsBackgroundFocusAndUnrelatedLifecycle(t *testing.T) { + var owner windowOwner + owner.activate(ownerEvent(atspi.WindowActivatedEvent, ":1.40", "/window", "/button")) + if owner.follow(ownerEvent(atspi.FocusedStateEvent, ":1.41", "/other", "/entry")) { + t.Fatal("background focus changed ownership") + } + if owner.end(ownerEvent(atspi.WindowDestroyedEvent, ":1.41", "/other", "/other"), false) { + t.Fatal("unrelated destruction cleared ownership") + } + if !owner.window.Valid() { + t.Fatal("unrelated lifecycle cleared active window") + } +} + +func TestWindowOwnerHandlesTransientDeactivationAndDestruction(t *testing.T) { + var owner windowOwner + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.40", "/window", "/button") + owner.activate(activation) + deactivation := ownerEvent(atspi.WindowDeactivatedEvent, ":1.40", "/window", "/window") + deactivation.Source.StatesKnown = true + deactivation.Source.Active = true + if owner.end(deactivation, false) || !owner.window.Valid() { + t.Fatal("active key-grab deactivation cleared ownership") + } + deactivation.Source.StatesKnown = false + deactivation.Source.Active = false + if owner.end(deactivation, true) || !owner.window.Valid() { + t.Fatal("consumed-command deactivation cleared ownership") + } + destruction := ownerEvent(atspi.WindowDestroyedEvent, ":1.40", "/window", "/window") + if !owner.end(destruction, true) || owner.window.Valid() || owner.focus.Valid() || owner.applicationBus != "" { + t.Fatalf("destruction did not clear ownership: %#v", owner) + } +} + +func TestWindowOwnerClearsDefunctFocusWithoutDroppingWindow(t *testing.T) { + var owner windowOwner + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.40", "/window", "/button") + owner.activate(activation) + defunct := atspi.NewEvent(atspi.DefunctStateEvent, activation.Source) + defunct.Detail1 = 1 + windowEnded, focusEnded := owner.defunct(defunct) + if windowEnded || !focusEnded || !owner.window.Valid() || owner.focus.Valid() { + t.Fatalf("defunct focus result = windowEnded:%v focusEnded:%v owner:%#v", windowEnded, focusEnded, owner) + } + + windowDefunct := atspi.NewEvent(atspi.DefunctStateEvent, atspi.Snapshot{BusName: ":1.40", Path: "/window"}) + windowDefunct.Detail1 = 1 + windowEnded, focusEnded = owner.defunct(windowDefunct) + if !windowEnded || !focusEnded || owner.window.Valid() || owner.applicationBus != "" { + t.Fatalf("defunct window result = windowEnded:%v focusEnded:%v owner:%#v", windowEnded, focusEnded, owner) + } +} diff --git a/internal/app/window_speech_test.go b/internal/app/window_speech_test.go new file mode 100644 index 0000000..0bb3b69 --- /dev/null +++ b/internal/app/window_speech_test.go @@ -0,0 +1,97 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +func TestWindowTitleQueuesFollowingPresentation(t *testing.T) { + for _, title := range []string{"Cthulhu Preferences", "Cthulhu Preferences for Example Application"} { + t.Run(title, func(t *testing.T) { + speaker := &controlledSpeaker{calls: make(chan speechCall, 10)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + presenter := eventPresenter{state: &eventLoopState{}, logger: slog.New(slog.DiscardHandler), speech: worker} + presenter.state.presentationOptions = presentation.DefaultOptions() + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.70", "/window", "/window") + activation.Source.Name, activation.Source.Role = title, "dialog" + activation.WindowTitle = title + worker.ProtectCommand(100) + close(expectSpeechCall(t, speaker, "cancel").done) + presenter.speak(activation) + titleCall := expectSpeechCall(t, speaker, title) + if worker.InterruptForInput(input.Event{Pressed: true, Timestamp: 100}) { + t.Fatal("delayed initiating shortcut interrupted the title") + } + + focus := ownerEvent(atspi.FocusedStateEvent, ":1.70", "/window", "/general") + focus.Source.Name, focus.Source.Role = "General", "page tab" + focus.Detail1 = 1 + presenter.speak(focus) + close(titleCall.done) + close(expectSpeechCall(t, speaker, "dialog").done) + // A CANCEL here would discard the title still queued in the + // synthesizer, even though its SPEAK call has returned. + close(expectSpeechCall(t, speaker, "General").done) + close(expectSpeechCall(t, speaker, "page tab").done) + + focus.Source.Path, focus.Source.Name = "/speech", "Speech" + presenter.speak(focus) + close(expectSpeechCall(t, speaker, "Speech").done) + close(expectSpeechCall(t, speaker, "page tab").done) + }) + } +} + +func TestWindowTitlesAndOtherWindowsQueueUntilUserInterruption(t *testing.T) { + for _, test := range []struct { + name string + window atspi.ObjectID + untitled bool + interrupt func(*speechWorker) + }{ + {name: "another window", window: atspi.NewObjectID(":1.70", "/other")}, + {name: "another application", window: atspi.NewObjectID(":1.71", "/window")}, + {name: "unowned output"}, + {name: "no title announcement", window: atspi.NewObjectID(":1.70", "/window"), untitled: true}, + {name: "explicit interruption", window: atspi.NewObjectID(":1.70", "/window"), interrupt: (*speechWorker).Interrupt}, + {name: "navigation key", window: atspi.NewObjectID(":1.70", "/window"), interrupt: func(worker *speechWorker) { + worker.InterruptForInput(input.Event{Pressed: true, Timestamp: 101}) + }}, + } { + t.Run(test.name, func(t *testing.T) { + speaker := &controlledSpeaker{calls: make(chan speechCall, 10)} + worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { worker.Stop(context.Background()) }) + worker.Enqueue(speechRequest{Text: "Window title", Window: atspi.NewObjectID(":1.70", "/window"), IntroducesWindow: !test.untitled}) + titleCall := expectSpeechCall(t, speaker, "Window title") + if test.interrupt != nil { + test.interrupt(worker) + close(expectSpeechCall(t, speaker, "cancel").done) + } + worker.Enqueue(speechRequest{Text: "Next control", Window: test.window}) + close(titleCall.done) + if test.interrupt != nil { + // The cancellation barrier settles the in-flight title + // before the new focus request can speak. + close(expectSpeechCall(t, speaker, "cancel").done) + } + close(expectSpeechCall(t, speaker, "Next control").done) + }) + } +} diff --git a/internal/app/window_title_command_test.go b/internal/app/window_title_command_test.go new file mode 100644 index 0000000..3c249e0 --- /dev/null +++ b/internal/app/window_title_command_test.go @@ -0,0 +1,164 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +func TestPresentWindowTitleRepeatsDespiteAutomaticPolicy(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + changed.Source.Name = "Current page - Browser" + titles.accessible(changed) + titles.lastTitle = changed.Source.Name + for range 2 { + titles.present() + } + if len(queue.requests) != 2 || queue.interruptions != 0 || titles.pending != nil { + t.Fatalf("explicit titles = %+v; interruptions %d; pending %+v", queue.requests, queue.interruptions, titles.pending) + } + for _, request := range queue.requests { + if request.Text != changed.Source.Name || request.Cause != "present-window-title" || request.Role != "system" || + request.Append || request.BypassFocusGate || request.Window != titles.state.owner.window { + t.Fatalf("explicit request = %+v", request) + } + } + titles.flush() + if len(queue.requests) != 2 { + t.Fatal("a pending automatic title repeated the explicit request") + } +} + +func TestPresentWindowTitleForegroundSources(t *testing.T) { + for _, name := range []string{"native", "wine-child", "accessible", "stale-epoch", "wrong-window", "missing"} { + t.Run(name, func(t *testing.T) { + titles, queue, _ := titleControllerFixture(t) + titles.state.owner.title = "Accessible title" + titles.state.foregroundState = atspi.ForegroundState{Epoch: 2, Client: xorg.Foreground{Known: true, Window: 10}} + source := &titleProbeSource{title: atspi.ForegroundTitle{Epoch: 2, Title: xorg.WindowTitle{Window: 10, TitleWindow: 10, Title: "Native title"}}} + titles.source = source + want := "Native title" + switch name { + case "wine-child": + source.title.Title.TitleWindow = 11 + titles.state.owner.clear() + case "accessible": + titles.source = nil + want = "Accessible title" + case "stale-epoch": + source.title.Epoch-- + titles.state.owner.clear() + want = "Could not find current window title." + case "wrong-window": + source.title.Title.Window = 20 + titles.state.owner.clear() + want = "Could not find current window title." + case "missing": + source.title.Title.Title = " " + titles.state.owner.clear() + want = "Could not find current window title." + } + titles.present() + if len(queue.requests) != 1 || queue.requests[0].Text != want { + t.Fatalf("title = %+v, want %q", queue.requests, want) + } + }) + } +} + +func TestPresentWindowTitleFlashesOnBraille(t *testing.T) { + titles, speech, _ := titleControllerFixture(t) + display := &flashRecorder{} + titles.speech = outputQueue{speech: speech, braille: display, live: titles.live} + titles.present() + if len(display.messages) != 1 || display.messages[0] != "Original" { + t.Fatalf("title Braille = %v", display.messages) + } +} + +func TestPresentWindowTitleRespectsLockHandoffAndForegroundChange(t *testing.T) { + for _, name := range []string{"locked", "suspended", "foreground-changed"} { + t.Run(name, func(t *testing.T) { + titles, queue, _ := titleControllerFixture(t) + titles.gate = &focusGate{} + switch name { + case "locked": + titles.gate.secure.Store(true) + case "suspended": + titles.gate.suspended.Store(true) + case "foreground-changed": + titles.foreground = &titleProbeSource{title: atspi.ForegroundTitle{Epoch: 1}} + } + titles.present() + if len(queue.requests) != 0 || queue.interruptions != 0 { + t.Fatalf("unexpected title during %s: %+v", name, queue.requests) + } + }) + } +} + +func TestProcessEventsPresentWindowTitlePreservesFocus(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + speech := &fakeSpeechQueue{spoken: make(chan string, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event)} + requests := make(chan input.Command) + live := &liveSettings{} + settings := config.DefaultSettings() + settings.Reading.AutomaticallyReadTitleChanges = false + live.Store(settings) + done := make(chan error, 1) + go func() { + done <- processEventsWithSettings(ctx, slog.New(slog.DiscardHandler), speech, adapter, requests, nil, 0, live) + }() + t.Cleanup(func() { + cancel() + select { + case err := <-done: + if err != nil { + t.Error(err) + } + case <-time.After(time.Second): + t.Error("event loop did not stop") + } + }) + wait := func(want string) { + t.Helper() + select { + case got := <-speech.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("missing speech %q", want) + } + } + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.50", "/window", "/window") + activation.Source.Name, activation.Source.Role = "Page title", "frame" + adapter.events <- activation + wait("Page title, frame") + focus := ownerEvent(atspi.FocusEvent, ":1.50", "/window", "/button") + focus.Source.Name, focus.Source.Role, focus.Source.Focused = "Next post", "button", true + adapter.events <- focus + wait("Next post, button") + changed := activation + changed.Type, changed.Source.Name = atspi.AccessibleNameEvent, "Updated page title" + adapter.events <- changed + for range 2 { + requests <- input.PresentWindowTitle + wait("Updated page title") + } + requests <- input.WhereAmI + wait("Next post, button") +} diff --git a/internal/app/window_titles.go b/internal/app/window_titles.go new file mode 100644 index 0000000..f1de029 --- /dev/null +++ b/internal/app/window_titles.go @@ -0,0 +1,337 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "log/slog" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/wine" +) + +type windowTitleSource interface { + ForegroundTitle() atspi.ForegroundTitle + TitleChanges() <-chan struct{} +} + +type pendingWindowTitle struct { + text string + previousText string + window atspi.ObjectID + epoch uint64 + native xorg.WindowTitle + changed bool + application string + observedAt time.Time + inputSequence uint64 +} + +// windowTitleController is owned by the accessibility event loop. Discovery +// stays in the native adapter; this controller owns coalescing, preferences, +// and duplicate suppression across AT-SPI and X11. +type windowTitleController struct { + state *eventLoopState + live *liveSettings + gate *focusGate + speech speechEnqueuer + logger *slog.Logger + source windowTitleSource + foreground foregroundMonitor + inputSource any + lastNative atspi.ForegroundTitle + lastTitle string + application string + pending *pendingWindowTitle + timer *time.Timer + due <-chan time.Time +} + +const ( + windowTitleChangeDelay = 25 * time.Millisecond + windowTitleIntroductionDelay = 250 * time.Millisecond +) + +func (titles *windowTitleController) clearPending() { + if titles.timer != nil { + titles.timer.Stop() + } + titles.timer, titles.due, titles.pending = nil, nil, nil +} + +func (titles *windowTitleController) reset() { + titles.clearPending() + titles.lastTitle, titles.application = "", "" + titles.lastNative = atspi.ForegroundTitle{} +} + +func (titles *windowTitleController) activated(event atspi.Event) { + titles.lastTitle = titles.state.owner.title + // XTerm activation is consumed by the Fenrir handoff before presentation. + // Its native title still needs an introduction, even if AT-SPI named it. + if isXTermSnapshot(event.Source) { + titles.lastTitle = "" + } + titles.application = titles.applicationForEvent(event) + if titles.pending != nil && titles.pending.native.Window == 0 { + titles.clearPending() + } +} + +func (titles *windowTitleController) applicationForEvent(event atspi.Event) string { + if titles.source != nil { + native := titles.source.ForegroundTitle() + if native.Epoch == event.Foreground.Epoch && native.Title.Window != 0 && + native.Title.TitleWindow != native.Title.Window && native.Title.Application != "" { + return native.Title.Application + } + } + if event.Source.ApplicationName != "" { + return event.Source.ApplicationName + } + return event.Source.ApplicationProcess +} + +func (titles *windowTitleController) queue(pending pendingWindowTitle) { + if pending.observedAt.IsZero() { + pending.observedAt = time.Now() + pending.inputSequence = recentInput(titles.inputSource).TitleInterruptionSequence + } + if titles.pending != nil { + // Coalescing must not revive a burst interrupted since its first sample. + pending.inputSequence = titles.pending.inputSequence + // Compare the whole burst so an intervening status change cannot + // disappear behind a later title which mirrors an edit. + pending.previousText = titles.pending.previousText + } + if previous := titles.pending; previous != nil && !previous.changed && previous.epoch == pending.epoch && + previous.window == pending.window && previous.native.Window == pending.native.Window && + previous.native.TitleWindow == pending.native.TitleWindow { + pending.changed = false + } + titles.pending = &pending + // Keep the first deadline: continuous progress must not postpone speech + // forever. Each burst speaks its latest value rather than every update. + if titles.timer == nil { + delay := windowTitleIntroductionDelay + if pending.changed { + delay = windowTitleChangeDelay + } + titles.timer = time.NewTimer(delay) + titles.due = titles.timer.C + } +} + +func isWindowTitleEvent(event atspi.Event) bool { + return event.Type == atspi.AccessibleNameEvent && + (event.Source.Role == "frame" || event.Source.Role == "window" || event.Source.Role == "dialog") +} + +func (titles *windowTitleController) accessible(event atspi.Event) bool { + if !isWindowTitleEvent(event) { + return false + } + if event.Source.ID() == titles.state.owner.window && strings.TrimSpace(event.Source.Name) == "" { + titles.state.owner.changeTitle(event) + titles.clearPending() + titles.lastTitle = "" + return true + } + previousTitle := titles.state.owner.title + if !titles.state.owner.changeTitle(event) { + return true + } + titles.queue(pendingWindowTitle{text: strings.TrimSpace(event.Source.Name), + previousText: previousTitle, + window: titles.state.owner.window, epoch: titles.state.foregroundState.Epoch, + changed: true, application: titles.application}) + return true +} + +func (titles *windowTitleController) nativeChanged() { + latest := titles.source.ForegroundTitle() + if latest == titles.lastNative { + return + } + previous := titles.lastNative + titles.lastNative = latest + if latest.Title.Window == 0 { + titles.reset() + return + } + switched := latest.Epoch != previous.Epoch || latest.Title.Window != previous.Title.Window || + latest.Title.TitleWindow != previous.Title.TitleWindow + // Wine review establishes navigation ownership without speaking an + // activation. Its stored title is metadata, not an announced title. + accessibleActivation := titles.state.owner.activated && !wine.IsReviewID(titles.state.owner.window) + if switched { + titles.clearPending() + // An AT-SPI activation may already have introduced this client. + titles.lastTitle = titles.state.owner.title + if wine.IsReviewID(titles.state.owner.window) { + titles.lastTitle = "" + } + if strings.EqualFold(latest.Title.Application, "xterm") { + titles.lastTitle = "" + } + } + if latest.Title.Title == "" { + titles.clearPending() + titles.lastTitle = "" + return + } + changed := !switched + // AT-SPI can introduce a window before its first X11 title sample. A + // later differing sample is still a title change, not a new activation. + if switched && accessibleActivation && titles.state.owner.title != "" && + latest.Title.TitleWindow == latest.Title.Window && !strings.EqualFold(latest.Title.Application, "xterm") { + changed = true + } + previousTitle := previous.Title.Title + if switched { + previousTitle = "" + } + titles.queue(pendingWindowTitle{text: latest.Title.Title, previousText: previousTitle, epoch: latest.Epoch, + native: latest.Title, changed: changed}) +} + +func equivalentWindowTitles(first, second string) bool { + normalize := func(value string) string { return strings.Join(strings.Fields(strings.ToLower(value)), " ") } + first, second = normalize(first), normalize(second) + if first == "" || second == "" { + return false + } + // Compare full titles: a changed status suffix is meaningful information. + return first == second +} + +func (titles *windowTitleController) enabled() bool { + return titles.live == nil || titles.live.Load().Reading.AutomaticallyReadTitleChanges +} + +// Explicit requests bypass automatic-title preferences and duplicate suppression. +// Read copied foreground metadata only; never block the event loop on native I/O +// or move either the browser cursor or object focus. +func (titles *windowTitleController) present() { + if titles.gate.Locked() || titles.gate.Suspended() { + return + } + foreground := titles.state.foregroundState + if titles.foreground != nil && titles.foreground.Foreground().Epoch != foreground.Epoch { + return + } + titles.clearPending() + window := titles.state.owner.window + text := "" + if titles.source != nil { + latest := titles.source.ForegroundTitle() + if latest.Epoch == foreground.Epoch && latest.Title.Window != 0 && latest.Title.Window == foreground.Client.Window { + text = strings.TrimSpace(latest.Title.Title) + } + } + if text == "" && window.Valid() { + text = strings.TrimSpace(titles.state.owner.title) + } + if text == "" { + text = "Could not find current window title." + } else { + titles.lastTitle = text + } + titles.speech.Enqueue(speechRequest{Text: text, Role: "system", Cause: "present-window-title", + Window: window, ExcludeFromHistory: titles.state.historyWindow.Valid() && window == titles.state.historyWindow}) +} + +// repeats_focused_edit recognizes titles whose only changed portion mirrors +// the owned entry. Use copied focus and input evidence, never application names +// or field labels. Window introductions and unrelated status changes still speak. +func (titles *windowTitleController) repeats_focused_edit(previousTitle, title string) bool { + current := titles.state.current + if previousTitle == "" || !current.Editable || current.ReadOnly || !current.Focused || + !titles.state.focusedID.Valid() || current.ID() != titles.state.focusedID || + titles.state.owner.focus != current.ID() || current.BusName != titles.state.owner.window.BusName { + return false + } + activity := recentInput(titles.inputSource) + if activity.Intent != input.TypingIntent && activity.Intent != input.DeleteIntent && + activity.Clipboard != input.CutAction && activity.Clipboard != input.PasteAction { + return false + } + text := strings.TrimSpace(current.Text) + if text == "" || strings.Count(title, text) != 1 { + return false + } + start := strings.Index(title, text) + prefix, suffix := title[:start], title[start+len(text):] + return len(previousTitle) >= len(prefix)+len(suffix) && + strings.HasPrefix(previousTitle, prefix) && strings.HasSuffix(previousTitle, suffix) +} + +func (titles *windowTitleController) flush() { + pending := titles.pending + titles.clearPending() + if pending == nil || titles.gate.Locked() { + return + } + // Only a native foreground introduction may cross the terminal handoff. + // Content and subsequent title changes remain Fenrir's responsibility. + xtermIntroduction := !pending.changed && pending.native.Window != 0 && + strings.EqualFold(pending.native.Application, "xterm") + if titles.gate.Suspended() && !xtermIntroduction { + return + } + if titles.foreground != nil && pending.epoch != titles.foreground.Foreground().Epoch { + return + } + if pending.native.Window != 0 { + latest := titles.source.ForegroundTitle() + if latest.Epoch != pending.epoch || latest.Title != pending.native { + return + } + pending.window = titles.state.owner.window + pending.application = titles.application + if !pending.window.Valid() || wine.IsReviewID(pending.window) || pending.native.TitleWindow != pending.native.Window { + pending.application = pending.native.Application + } + } else if pending.window != titles.state.owner.window { + return + } + if strings.HasPrefix(strings.ToLower(pending.application), "cthulhu") { + pending.application = "" + } + if pending.application != "" && titles.live != nil && titles.live.onApplication != nil { + titles.live.onApplication(pending.application) + // Application switching is asynchronous. Wait for its committed + // settings before reading a title, including Wine without AT-SPI. + applied := titles.live.application.Load() + if applied == nil || *applied != pending.application { + titles.queue(*pending) + return + } + } + if pending.changed && !titles.enabled() { + titles.lastTitle = pending.text + return + } + if equivalentWindowTitles(titles.lastTitle, pending.text) { + return + } + titles.lastTitle = pending.text + if pending.changed && titles.repeats_focused_edit(pending.previousText, pending.text) { + return + } + if pending.inputSequence != recentInput(titles.inputSource).TitleInterruptionSequence { + return + } + if titles.logger != nil { + titles.logger.Debug("queued automatic window title", "title_changed", pending.changed, + "observed_to_queue_ms", time.Since(pending.observedAt).Milliseconds()) + } + titles.speech.Enqueue(speechRequest{Text: pending.text, Role: "system", Cause: "window-title", + Window: pending.window, Append: true, BypassFocusGate: xtermIntroduction, + ExcludeFromHistory: titles.state.historyWindow.Valid() && pending.window == titles.state.historyWindow}) +} diff --git a/internal/app/window_titles_native_test.go b/internal/app/window_titles_native_test.go new file mode 100644 index 0000000..027a683 --- /dev/null +++ b/internal/app/window_titles_native_test.go @@ -0,0 +1,157 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "bufio" + "context" + "encoding/json" + "log/slog" + "os" + "os/exec" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +func TestNativeAutomaticTitleDispatchLatency(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_WINDOW_TITLES") != "1" { + t.Skip("private Xvfb and D-Bus fixture only") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "python3", "-u", "../../tests/window_title_fixture.py") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err = fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + if !scanner.Scan() { + t.Fatal("fixture did not start") + } + adapter := atspi.New() + if err = adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + listener := xorg.New() + if err = listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + queue := &fakeSpeechQueue{spoken: make(chan string, 8)} + live := &liveSettings{} + live.Store(config.DefaultSettings()) + requests := make(chan input.Command, 1) + inputDone := make(chan struct{}) + go func() { + defer close(inputDone) + processInputEvents(ctx, slog.New(slog.DiscardHandler), queue, listener, input.EchoSettings{}, nil, nil) + }() + defer func() { cancel(); <-inputDone }() + completed := make(chan error, 1) + go func() { + completed <- processEventsWithInput(ctx, slog.New(slog.DiscardHandler), queue, adapter, requests, nil, 0, live, listener, nil, nil) + }() + defer func() { + cancel() + if err := <-completed; err != nil { + t.Error(err) + } + }() + wait := func(want string, deadline <-chan time.Time) { + t.Helper() + for { + select { + case got := <-queue.spoken: + if got != want { + t.Fatalf("title = %q, want %q", got, want) + } + return + case <-deadline: + t.Fatalf("title %q was not queued promptly", want) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + wait("Example title", time.After(2*time.Second)) + for _, title := range []string{"Status one", "Status two", "Status three"} { + data, _ := json.Marshal(map[string]string{"action": "title", "window": "normal", "title": title}) + began := time.Now() + deadline := time.After(200 * time.Millisecond) + if _, err = stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() || scanner.Text() != "ready" { + t.Fatal("fixture command failed") + } + wait(title, deadline) + t.Logf("X11 title update to speech queue: %s", time.Since(began)) + } + // The switch chord must not suppress the destination's introduction. The + // fixture has no window manager, so activate each destination explicitly. + for _, destination := range []struct{ window, title string }{ + {"unrelated", "Unrelated title"}, {"normal", "Status three"}, + } { + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "alt+Tab").CombinedOutput(); err != nil { + t.Fatalf("switch keys: %v %s", err, out) + } + data, _ := json.Marshal(map[string]string{"action": "activate", "window": destination.window}) + if _, err = stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() || scanner.Text() != "ready" { + t.Fatal("fixture switch failed") + } + wait(destination.title, time.After(2*time.Second)) + } + select { + case got := <-queue.spoken: + t.Fatalf("duplicate window title: %q", got) + case <-time.After(2 * windowTitleIntroductionDelay): + } + + // Exercise the actual desktop chord through command dispatch and the event + // loop, with automatic title changes disabled and no new focus event. + settings := live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + live.Store(settings) + commands := xorg.NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + if err = commands.Start(ctx); err != nil { + t.Fatal(err) + } + defer commands.Stop(context.Background()) + commandDone := make(chan error, 1) + go func() { + commandDone <- (commandRuntime{logger: slog.New(slog.DiscardHandler), commands: commands, + reviewRequests: requests, stopRun: cancel}).run(ctx) + }() + defer func() { + cancel() + if err := <-commandDone; err != nil { + t.Error(err) + } + }() + for range 2 { + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "Insert+KP_Enter").CombinedOutput(); err != nil { + t.Fatalf("title keys: %v %s", err, out) + } + wait("Status three", time.After(time.Second)) + } +} diff --git a/internal/app/window_titles_test.go b/internal/app/window_titles_test.go new file mode 100644 index 0000000..3c277a7 --- /dev/null +++ b/internal/app/window_titles_test.go @@ -0,0 +1,660 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "fmt" + "log/slog" + "path/filepath" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/preferences" +) + +type titleProbeSource struct{ title atspi.ForegroundTitle } + +func (source *titleProbeSource) ForegroundTitle() atspi.ForegroundTitle { return source.title } +func (source *titleProbeSource) TitleChanges() <-chan struct{} { return nil } +func (source *titleProbeSource) Foreground() atspi.ForegroundState { + return atspi.ForegroundState{Epoch: source.title.Epoch, Client: xorg.Foreground{Known: true, Window: source.title.Title.Window}} +} +func (source *titleProbeSource) ForegroundChanges() <-chan struct{} { return nil } + +type titleProbeQueue struct { + requests []speechRequest + interruptions int +} + +func (queue *titleProbeQueue) Enqueue(request speechRequest) { + queue.requests = append(queue.requests, request) +} +func (queue *titleProbeQueue) Interrupt() { queue.interruptions++ } + +func titleControllerFixture(t *testing.T) (*windowTitleController, *titleProbeQueue, atspi.Event) { + t.Helper() + queue := &titleProbeQueue{} + live := &liveSettings{} + live.Store(config.DefaultSettings()) + titles := &windowTitleController{state: &eventLoopState{}, live: live, speech: queue} + activation := ownerEvent(atspi.WindowActivatedEvent, ":1.50", "/window", "/window") + activation.Source.Name, activation.Source.Role = "Original", "frame" + titles.state.owner.activate(activation) + titles.activated(activation) + t.Cleanup(titles.reset) + changed := activation + changed.Type = atspi.AccessibleNameEvent + return titles, queue, changed +} + +func TestAutomaticTitlePolicyCoalescesAndPreservesSpeech(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + for _, text := range []string{"Loading", "Loading 50%", "Loading 100%"} { + changed.Source.Name = text + if !titles.accessible(changed) { + t.Fatal("title event not consumed") + } + } + titles.flush() + if len(queue.requests) != 1 || queue.requests[0].Text != "Loading 100%" || + !queue.requests[0].Append || queue.interruptions != 0 { + t.Fatalf("title burst = %+v, interruptions %d", queue.requests, queue.interruptions) + } + titles.accessible(changed) + titles.flush() + if len(queue.requests) != 1 { + t.Fatal("duplicate title was announced") + } + changed.Source.Name = "" + titles.accessible(changed) + changed.Source.Name = "Loading 100%" + titles.accessible(changed) + titles.flush() + if len(queue.requests) != 2 { + t.Fatal("restored title was not announced") + } +} + +func TestScheduledTitleInterruptedBeforeSpeechQueue(t *testing.T) { + for _, name := range []string{"c", "Tab", "Control_L", "Escape"} { + t.Run(name, func(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + tracker := &input.IntentTracker{} + titles.inputSource = tracker + changed.Source.Name = "Scheduled status" + titles.accessible(changed) + tracker.Observe(input.NewKeyEvent(0, true, name)) + // A newer sample in the same burst must not undo cancellation. + changed.Source.Name = "Latest status" + titles.accessible(changed) + titles.flush() + if len(queue.requests) != 0 || titles.pending != nil { + t.Fatal("interrupted title reached the speech queue") + } + // A genuinely later change still announces normally. + changed.Source.Name = "New status" + titles.accessible(changed) + titles.flush() + if len(queue.requests) != 1 || queue.requests[0].Text != "New status" { + t.Fatalf("later title = %+v", queue.requests) + } + }) + } +} + +func TestAutomaticTitleDoesNotRepeatFocusedEdit(t *testing.T) { + for _, native := range []bool{false, true} { + t.Run(fmt.Sprintf("native=%v", native), func(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + tracker := &input.IntentTracker{} + titles.inputSource = tracker + entry := atspi.Snapshot{BusName: changed.Source.BusName, Path: "/entry", Role: "entry", Editable: true, Focused: true} + titles.state.current = entry + titles.state.focusedID, titles.state.owner.focus = entry.ID(), entry.ID() + titles.state.owner.title, titles.lastTitle = "Compose: (empty) - Mail", "Compose: (empty) - Mail" + source := &titleProbeSource{title: atspi.ForegroundTitle{Epoch: 1, Title: xorg.WindowTitle{Window: 20, TitleWindow: 20, Title: titles.lastTitle}}} + if native { + titles.source, titles.foreground, titles.lastNative = source, source, source.title + } + change := func(text string) { + if native { + source.title.Title.Title = text + titles.nativeChanged() + } else { + changed.Source.Name = text + titles.accessible(changed) + } + titles.flush() + } + for _, step := range []struct{ key, text string }{{"D", "D"}, {"r", "Dr"}, {"BackSpace", "D"}} { + tracker.Observe(input.NewKeyEvent(0, true, step.key)) + titles.state.current.Text = step.text + change("Compose: " + step.text + " - Mail") + } + if len(queue.requests) != 0 { + t.Fatalf("titles repeated the edited text: %+v", queue.requests) + } + // The entry still owns focus and input is still recent. A changed + // status outside the edited value must nevertheless be announced. + change("Compose: D - Mail (saved)") + if len(queue.requests) != 1 || queue.requests[0].Text != "Compose: D - Mail (saved)" { + t.Fatalf("unrelated status title = %+v", queue.requests) + } + }) + } +} + +func TestAutomaticTitleEditFilterRequiresOwnedEdit(t *testing.T) { + for _, name := range []string{"no-input", "navigation", "read-only", "unfocused", "other-focus", "other-window", "empty", "ambiguous", "introduction"} { + t.Run(name, func(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + tracker := &input.IntentTracker{} + titles.inputSource = tracker + tracker.Observe(input.NewKeyEvent(0, true, "r")) + titles.state.current = atspi.Snapshot{BusName: changed.Source.BusName, Path: "/entry", Role: "entry", Text: "Draft", Editable: true, Focused: true} + titles.state.focusedID, titles.state.owner.focus = titles.state.current.ID(), titles.state.current.ID() + titles.state.owner.title, titles.lastTitle = "Compose: Draf - Mail", "Compose: Draf - Mail" + changed.Source.Name = "Compose: Draft - Mail" + switch name { + case "no-input": + titles.inputSource = nil + case "navigation": + tracker.Observe(input.NewKeyEvent(0, true, "Left")) + case "read-only": + titles.state.current.ReadOnly = true + case "unfocused": + titles.state.current.Focused = false + case "other-focus": + titles.state.owner.focus.Path = "/other" + case "other-window": + titles.state.current.BusName = ":1.99" + titles.state.focusedID, titles.state.owner.focus = titles.state.current.ID(), titles.state.current.ID() + case "empty": + titles.state.current.Text = "" + case "ambiguous": + changed.Source.Name = "Compose: Draft - Draft" + case "introduction": + titles.state.owner.title, titles.lastTitle = "", "" + } + titles.accessible(changed) + titles.flush() + if len(queue.requests) != 1 || queue.requests[0].Text != changed.Source.Name { + t.Fatalf("title without matching edit = %+v", queue.requests) + } + }) + } +} + +func TestScheduledNativeIntroductionPreservesSwitchAndRepeatInput(t *testing.T) { + titles, queue, _ := titleControllerFixture(t) + titles.state.owner.clear() + tracker := &input.IntentTracker{} + titles.inputSource = tracker + source := &titleProbeSource{title: atspi.ForegroundTitle{Epoch: 1, Title: xorg.WindowTitle{Window: 20, TitleWindow: 20, Title: "Other window"}}} + titles.source, titles.foreground = source, source + // Input initiating a switch precedes discovery of its destination title. + tracker.Observe(input.NewKeyEvent(0, true, "Tab")) + titles.nativeChanged() + repeat := input.NewKeyEvent(0, true, "Tab") + repeat.Repeat = true + tracker.Observe(repeat) + titles.flush() + if len(queue.requests) != 1 || queue.requests[0].Text != "Other window" { + t.Fatalf("destination title = %+v", queue.requests) + } + // Fresh typing after a subsequent switch cancels its delayed introduction. + source.title.Epoch++ + source.title.Title.Window, source.title.Title.TitleWindow = 21, 21 + source.title.Title.Title = "Next window" + titles.nativeChanged() + tracker.Observe(input.NewKeyEvent(0, true, "c")) + repeat = input.NewKeyEvent(0, true, "c") + repeat.Repeat = true + tracker.Observe(repeat) + titles.flush() + if len(queue.requests) != 1 { + t.Fatal("typing interruption was hidden by its later repeat") + } + // Returning to that window must introduce it again despite cancellation. + source.title.Epoch++ + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 2 || queue.requests[1].Text != "Next window" { + t.Fatalf("return title = %+v", queue.requests) + } +} + +func TestScheduledTitleCannotReviveWhileWaitingForSettings(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + tracker := &input.IntentTracker{} + titles.inputSource = tracker + titles.live.onApplication = func(string) {} + titles.application = "Example Application" + changed.Source.Name = "Pending application title" + titles.accessible(changed) + titles.flush() // Requeued until the application override is committed. + tracker.Observe(input.NewKeyEvent(0, true, "c")) + application := titles.application + titles.live.application.Store(&application) + titles.flush() + if len(queue.requests) != 0 || titles.pending != nil { + t.Fatal("settings retry revived an interrupted title") + } +} + +func TestAutomaticTitleUsesBrailleMessagePathAndKeepsFocus(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + display := &flashRecorder{} + titles.speech = outputQueue{speech: queue, braille: display, live: titles.live} + focused := titles.state.owner.focus + changed.Source.Name = "Updated title" + titles.accessible(changed) + titles.flush() + if len(display.messages) != 1 || display.messages[0] != "Updated title" || titles.state.owner.focus != focused { + t.Fatalf("title braille = %q, focus = %+v", display.messages, titles.state.owner.focus) + } + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + changed.Source.Name = "Silent title" + titles.accessible(changed) + titles.flush() + if len(display.messages) != 1 { + t.Fatal("disabled title still flashed on braille") + } +} + +func TestAutomaticTitlesRejectBackgroundDisabledAndStaleEvents(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + background := changed + background.Source.Path = "/background" + background.Source.Name = "Background" + titles.accessible(background) + titles.flush() + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + changed.Source.Name = "Disabled" + titles.accessible(changed) + titles.flush() + settings.Reading.AutomaticallyReadTitleChanges = true + titles.live.Store(settings) + changed.Source.Name = "Stale" + titles.accessible(changed) + titles.state.owner.clear() + titles.flush() + if len(queue.requests) != 0 { + t.Fatalf("unwanted titles = %+v", queue.requests) + } +} + +func TestAutomaticTitlesCancelEmptyAndLockedUpdates(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + changed.Source.Name = "Transient" + titles.accessible(changed) + changed.Source.Name = "" + titles.accessible(changed) + titles.flush() + titles.gate = newFocusGate(nil) + changed.Source.Name = "Locked title" + titles.accessible(changed) + titles.gate.secure.Store(true) + titles.flush() + titles.gate.secure.Store(false) + titles.gate.suspended.Store(true) + changed.Source.Name = "XTerm handoff" + titles.accessible(changed) + titles.flush() + if len(queue.requests) != 0 { + t.Fatalf("unwanted titles = %+v", queue.requests) + } +} + +func TestNativeXTermIntroductionDuringHandoff(t *testing.T) { + for _, accessible := range []bool{false, true} { + t.Run(map[bool]string{false: "native only", true: "accessible activation"}[accessible], func(t *testing.T) { + titles, queue, activation := titleControllerFixture(t) + titles.state.owner.clear() + titles.gate = newFocusGate(nil) + titles.gate.SetSuspended(true) + titles.speech = gatedSpeech{speech: queue, gate: titles.gate} + source := &titleProbeSource{title: atspi.ForegroundTitle{Epoch: 1, Title: xorg.WindowTitle{Window: 20, TitleWindow: 20, Title: "Shell", Application: "xterm"}}} + titles.source, titles.foreground = source, source + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + if accessible { + activation.Source.Name, activation.Source.ApplicationName = "Shell", "xterm" + activation.Foreground.Epoch = 1 + titles.state.owner.activate(activation) + titles.activated(activation) + } + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 1 || queue.requests[0].Text != "Shell" || !titles.gate.Suspended() { + t.Fatalf("handoff title = %+v; suspended = %t", queue.requests, titles.gate.Suspended()) + } + titles.nativeChanged() + titles.flush() + source.title.Title.Title = "Shell updated" + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 1 { + t.Fatal("handoff announced duplicate or terminal title change") + } + // Separate xterms can have the same title; each switch introduces it. + source.title.Epoch++ + source.title.Title.Window, source.title.Title.TitleWindow = 21, 21 + source.title.Title.Title = "Shell" + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 2 || queue.requests[1].Text != "Shell" { + t.Fatalf("second terminal introduction = %+v", queue.requests) + } + source.title.Epoch++ + source.title.Title.Window, source.title.Title.TitleWindow = 22, 22 + source.title.Title.Title = "Second shell" + titles.nativeChanged() + titles.gate.secure.Store(true) + titles.flush() + if len(queue.requests) != 2 { + t.Fatal("locked screen announced terminal title") + } + }) + } +} + +func TestNativeTitlesSharePolicyAndActivationDeduplication(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + source := &titleProbeSource{title: atspi.ForegroundTitle{Title: xorg.WindowTitle{Window: 10, TitleWindow: 10, Title: "Original"}}} + titles.source, titles.foreground = source, source + titles.nativeChanged() + titles.flush() + changed.Source.Name = "Changed" + titles.accessible(changed) + source.title.Title.Title = "Changed" + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 1 || queue.requests[0].Text != "Changed" { + t.Fatalf("duplicate source output = %+v", queue.requests) + } + source.title.Title.Title = "Changed again" + titles.nativeChanged() + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + titles.flush() + if len(queue.requests) != 1 { + t.Fatal("native change ignored disabled preference") + } + titles.state.owner.clear() + source.title.Epoch++ + source.title.Title.Window, source.title.Title.TitleWindow, source.title.Title.Title = 20, 20, "Other window" + titles.nativeChanged() + source.title.Title.Title = "Other window ready" + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 2 || queue.requests[1].Text != "Other window ready" { + t.Fatal("disabled title changes suppressed initial window introduction") + } +} + +func TestNativeTitleDropsOldForegroundAndTracksWineChildSwitch(t *testing.T) { + titles, queue, _ := titleControllerFixture(t) + titles.state.owner.clear() + source := &titleProbeSource{title: atspi.ForegroundTitle{Epoch: 1, Title: xorg.WindowTitle{Window: 10, TitleWindow: 11, Title: "Wine game"}}} + titles.source, titles.foreground = source, source + titles.nativeChanged() + source.title.Epoch++ + titles.flush() + if len(queue.requests) != 0 { + t.Fatal("old foreground title survived") + } + titles.nativeChanged() + titles.flush() + source.title.Title.TitleWindow, source.title.Title.Title = 12, "Wine dialog" + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 2 || queue.requests[1].Text != "Wine dialog" { + t.Fatalf("Wine child switch = %+v", queue.requests) + } +} + +func TestAutomaticTitlesWaitForApplicationOverride(t *testing.T) { + titles, queue, changed := titleControllerFixture(t) + titles.application = "Example Application" + titles.live.onApplication = func(string) {} + changed.Source.Name = "Changing title" + titles.accessible(changed) + titles.flush() + if len(queue.requests) != 0 || titles.pending == nil { + t.Fatal("title raced application settings") + } + application := titles.application + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + titles.live.application.Store(&application) + titles.flush() + if len(queue.requests) != 0 || titles.pending != nil { + t.Fatal("application override was not honored") + } +} + +func TestLateNativeSampleHonorsDisabledTitleChanges(t *testing.T) { + titles, queue, _ := titleControllerFixture(t) + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + source := &titleProbeSource{title: atspi.ForegroundTitle{Title: xorg.WindowTitle{Window: 10, TitleWindow: 10, Title: "Changed after activation"}}} + titles.source, titles.foreground = source, source + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 0 { + t.Fatal("first native sample bypassed disabled preference") + } +} + +func TestTitlePreferenceAppliesPersistsAndRestoresAcrossApplications(t *testing.T) { + settings := config.DefaultSettings() + settings.Path = filepath.Join(t.TempDir(), "settings.toml") + store, err := config.NewStore(settings.Path) + if err != nil { + t.Fatal(err) + } + if err = store.Save(settings); err != nil { + t.Fatal(err) + } + worker := newPreferencesWorker(slog.New(slog.DiscardHandler), settings, nil) + worker.live = &liveSettings{} + worker.live.Store(settings) + ctx := context.Background() + worker.switchApplication(ctx, "Noisy Application") + worker.beginEdit(ctx, "\x00") + values := preferences.FromSettings(worker.editing) + if !values.Reading.AutomaticallyReadTitleChanges { + t.Fatal("checkbox defaults off") + } + values.Reading.AutomaticallyReadTitleChanges = false + if response := worker.apply(ctx, preferences.Request{Values: values, Save: true}); !response.Accepted { + t.Fatal(response.Message) + } + worker.editingActive = false + worker.switchApplication(ctx, "Other Application") + if !worker.live.Load().Reading.AutomaticallyReadTitleChanges { + t.Fatal("override leaked") + } + worker.switchApplication(ctx, "Noisy Application") + if worker.live.Load().Reading.AutomaticallyReadTitleChanges { + t.Fatal("override lost on return") + } + reopened, err := config.NewStore(settings.Path) + if err != nil { + t.Fatal(err) + } + loaded, found, err := reopened.LoadForApplication("Noisy Application") + if err != nil || !found || loaded.Reading.AutomaticallyReadTitleChanges { + t.Fatalf("saved override = %t, %t, %v", loaded.Reading.AutomaticallyReadTitleChanges, found, err) + } + global, err := reopened.Load() + if err != nil || !global.Reading.AutomaticallyReadTitleChanges { + t.Fatalf("global default changed: %v", err) + } +} + +func TestWineTitlesUseSharedControllerWhileControlsStayReadable(t *testing.T) { + titles, queue, _ := titleControllerFixture(t) + titles.state.owner.clear() + titles.lastTitle = "" + control := make(chan string, 2) + owner := newWineEventPresenter(func(text string) bool { control <- text; return true }) + defer owner.Close() + connectWineWindowTitles(owner, titles.live, &fakeAdapter{}) + owner.pending = &winePresentation{source: "control", window: "Wine game", message: "Play, button", parts: []string{"Play", "button"}} + owner.flush() + if got := <-control; got != "Play, button" { + t.Fatalf("control included title: %q", got) + } + titles.wineChanged(<-titles.live.wineTitles) + titles.flush() + if len(queue.requests) != 1 || queue.requests[0].Text != "Wine game" { + t.Fatal("Wine initial title missing") + } + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + owner.pending = &winePresentation{source: "control", window: "Wine game loading", message: "Play, button", parts: []string{"Play", "button"}} + owner.flush() + <-control + titles.wineChanged(<-titles.live.wineTitles) + titles.flush() + if len(queue.requests) != 1 { + t.Fatal("Wine helper bypassed preference") + } + owner.pending = &winePresentation{source: "window", window: "Wine game ready", message: "Wine game ready", parts: []string{"Wine game ready"}} + owner.flush() + titles.wineChanged(<-titles.live.wineTitles) + titles.flush() + select { + case text := <-control: + t.Fatalf("title-only helper focus bypassed preference: %q", text) + default: + } + if len(queue.requests) != 1 { + t.Fatal("title-only focus bypassed preference") + } +} + +func TestWineTitleReportsCannotClaimUnrelatedForeground(t *testing.T) { + titles, queue, _ := titleControllerFixture(t) + source := &titleProbeSource{title: atspi.ForegroundTitle{Epoch: 1, Title: xorg.WindowTitle{Window: 10, TitleWindow: 10, Title: "Terminal"}}} + titles.source, titles.foreground = source, source + titles.wineChanged(wineWindowTitle{text: "Background game", foreground: source.title}) + titles.flush() + if len(queue.requests) != 0 { + t.Fatal("background helper title was announced") + } +} + +func TestWineReviewFocusDoesNotSuppressTitleIntroduction(t *testing.T) { + for _, desktop := range []bool{false, true} { + for _, reviewFirst := range []bool{false, true} { + t.Run(fmt.Sprintf("desktop=%t/reviewFirst=%t", desktop, reviewFirst), func(t *testing.T) { + c, registry, source, worker := reviewFocusSetup(t) + titles, queue, _ := titleControllerFixture(t) + titles.state = c.state + titles.source, titles.foreground = source, source + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + if desktop { + source.title.Title.TitleWindow = 21 + source.title.Title.Client.Window = 21 + } + introduce := func() { + if reviewFirst { + c.changed() + } + titles.nativeChanged() + c.changed() // The event loop syncs review focus again before flushing. + titles.wineChanged(wineWindowTitle{text: "Same title", foreground: source.title}) + titles.flush() + } + introduce() + if len(queue.requests) != 1 || queue.requests[0].Text != "Same title" { + t.Fatalf("Wine introduction = %+v", queue.requests) + } + if worker.Focus() != registry.notices[0].ID() || c.state.owner.title != "Same title" { + t.Fatal("title presentation changed Wine review ownership") + } + c.changed() + titles.nativeChanged() + titles.wineChanged(wineWindowTitle{text: "Same title", foreground: source.title}) + titles.flush() + if len(queue.requests) != 1 { + t.Fatal("duplicate Wine title was spoken") + } + registry.notices[0].Title = "Status changed" + source.title.Title.Title = "Status changed" + c.changed() + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 1 { + t.Fatal("Wine title change bypassed disabled preference") + } + // Returning to the same Wine window must introduce it again. + c.retire() + source.state.Epoch++ + source.title.Epoch = source.state.Epoch + registry.notices[0].Title = "Same title" + source.title.Title.Title = "Same title" + introduce() + if len(queue.requests) != 2 || queue.requests[1].Text != "Same title" { + t.Fatalf("return to Wine window = %+v", queue.requests) + } + }) + } + } +} + +func TestWineReviewTitlesUseNativeApplicationPreferences(t *testing.T) { + c, registry, source, _ := reviewFocusSetup(t) + titles, queue, _ := titleControllerFixture(t) + titles.state = c.state + titles.source, titles.foreground = source, source + var application string + titles.live.onApplication = func(name string) { application = name } + previousApplication := "Other Application" + titles.live.application.Store(&previousApplication) + c.changed() + titles.nativeChanged() + titles.flush() + if application != "fixture.exe" || len(queue.requests) != 0 || titles.pending == nil { + t.Fatalf("Wine title raced application settings: application=%q requests=%+v", application, queue.requests) + } + settings := titles.live.Load() + settings.Reading.AutomaticallyReadTitleChanges = false + titles.live.Store(settings) + titles.live.application.Store(&application) + titles.flush() + if len(queue.requests) != 1 || queue.requests[0].Text != "Same title" { + t.Fatalf("Wine introduction = %+v", queue.requests) + } + registry.notices[0].Title = "Changed status" + source.title.Title.Title = "Changed status" + c.changed() + titles.nativeChanged() + titles.flush() + if len(queue.requests) != 1 { + t.Fatal("Wine title ignored its application preference") + } +} diff --git a/internal/app/wine_echo_focus.go b/internal/app/wine_echo_focus.go new file mode 100644 index 0000000..6fd29a8 --- /dev/null +++ b/internal/app/wine_echo_focus.go @@ -0,0 +1,34 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "slices" + "strings" + + "git.stormux.org/storm/cthulhu/internal/remote" +) + +func wineEchoEditField(event remote.AccessibleEvent) bool { + return strings.EqualFold(event.Role, "edit") && event.Description != "password" && + !slices.Contains(strings.Split(event.States, ", "), "read only") && + !slices.Contains(strings.Split(event.States, ", "), "password") +} + +// Raw key names need current desktop ownership as well as Wine's last control. +// Text insertion feedback already passes the helper's focused-editor checks. +func (owner *wineEventPresenter) EditFieldFocused() bool { + owner.mu.Lock() + defer owner.mu.Unlock() + if owner.closed || !owner.editable || owner.protected || owner.focused == "" || + owner.foreground == nil || owner.titles == nil { + return false + } + foreground, title := owner.foreground.Foreground(), owner.titles.ForegroundTitle() + return foreground.Client.Known && foreground.Client.Window != 0 && + foreground.Epoch == owner.echoEpoch && title.Epoch == foreground.Epoch && + title.Title.Window == foreground.Client.Window && title.Title.Wine && title.Title.Focused && + equivalentWindowTitles(title.Title.Title, owner.echoTitle) +} diff --git a/internal/app/wine_echo_focus_test.go b/internal/app/wine_echo_focus_test.go new file mode 100644 index 0000000..a7954f1 --- /dev/null +++ b/internal/app/wine_echo_focus_test.go @@ -0,0 +1,98 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/remote" +) + +func TestWineEditFieldsOnlyTypingAndVoices(t *testing.T) { + settings := config.DefaultSettings() + settings.KeyEchoInEditFieldsOnly = true + settings.UseCustomEchoVoice = true + settings.UseCustomEchoForKey = true + settings.UseCustomEchoForCharacter = false + live := &liveSettings{} + live.Store(settings) + speech := &remoteSpeechQueue{} + braille := &remoteBrailleQueue{running: true} + presenter := remoteSpeech{speech: speech, braille: braille, live: live} + owner := newWineEventPresenter(func(string) bool { return true }) + defer owner.Close() + presenter.wine = owner + for _, tc := range []struct { + role, states, description string + want bool + }{ + {"edit", "", "", true}, {"read only edit", "", "", false}, {"edit", "read only", "", false}, + {"button", "", "", false}, {"text", "", "", false}, {"edit", "", "password", false}, + } { + presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "control", EventType: "focus", Role: tc.role, States: tc.states, Description: tc.description}) + owner.flush() + before := len(speech.requests) + accepted := presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "control", EventType: "text", Name: "A", States: "kind=8"}) + if accepted != tc.want || (len(speech.requests) > before) != tc.want { + t.Fatalf("role=%s states=%s protected=%s accepted=%v", tc.role, tc.states, tc.description, accepted) + } + if tc.want && (!speech.requests[before].CustomEcho || !speech.requests[before].Character || braille.text[len(braille.text)-1] != "A") { + t.Fatal("Wine key voice or braille lost") + } + } + presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "edit", EventType: "focus", Role: "edit"}) + owner.flush() + settings.EnableEchoByCharacter = true + live.Store(settings) + presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "edit", EventType: "text", Name: "a", States: "kind=8"}) + if speech.requests[len(speech.requests)-1].CustomEcho { + t.Fatal("character routing used key-only custom voice") + } + // Moving focus to a menu invalidates the preceding editor's text actions. + presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "menu", EventType: "focus", Role: "menu item"}) + owner.flush() + if presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "edit", EventType: "text", Name: "a", States: "kind=8"}) { + t.Fatal("old editor still echoes") + } +} + +func TestWineKeyEchoRequiresCurrentDesktopFocus(t *testing.T) { + _, _, monitor, _ := reviewFocusSetup(t) + owner := newWineEventPresenter(func(string) bool { return true }) + defer owner.Close() + owner.foreground, owner.titles = monitor, monitor + focus := remote.AccessibleEvent{SourceID: "edit", EventType: "focus", Role: "edit", WindowTitle: monitor.title.Title.Title} + owner.Present(focus) + owner.flush() + if !owner.EditFieldFocused() { + t.Fatal("current Wine editor rejected") + } + monitor.state.Epoch++ + if owner.EditFieldFocused() { + t.Fatal("stale Wine editor survived foreground switch") + } + monitor.title.Epoch = monitor.state.Epoch + owner.Present(focus) + owner.flush() + if !owner.EditFieldFocused() { + t.Fatal("new focus did not restore editor") + } + monitor.title.Title.Wine = false + if owner.EditFieldFocused() { + t.Fatal("native window reused Wine focus") + } + monitor.title.Title.Wine = true + focus.Role = "menu item" + owner.Present(focus) + owner.flush() + if owner.EditFieldFocused() { + t.Fatal("menu retained editor echo") + } + owner.Close() + if owner.EditFieldFocused() { + t.Fatal("closed helper retained focus") + } +} diff --git a/internal/app/wine_events.go b/internal/app/wine_events.go new file mode 100644 index 0000000..fbbb446 --- /dev/null +++ b/internal/app/wine_events.go @@ -0,0 +1,259 @@ +package app + +import ( + "fmt" + "log/slog" + "slices" + "strings" + "sync" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/presentation" + "git.stormux.org/storm/cthulhu/internal/remote" +) + +// wineEventPresenter coalesces transient Wine focus bursts before presenting +// normalized helper events. The helper never passes native object references. +type wineEventPresenter struct { + // mu serializes D-Bus actions with timer output and shutdown. Native + // objects remain in Wine; focused/protected live until the next focus event. + mu sync.Mutex + present func(string) bool + windowTitle func(string) + logger *slog.Logger + timer *time.Timer + timerGeneration uint64 + pending *winePresentation + focused string + protected bool + editable bool + echoEpoch uint64 + echoTitle string + foreground foregroundMonitor + titles windowTitleSource + window string + lastKey string + lastTime time.Time + closed bool +} + +type winePresentation struct { + source, window, message string + parts []string +} + +func newWineEventPresenter(present func(string) bool) *wineEventPresenter { + return &wineEventPresenter{present: present} +} + +// wineTypingEchoEnabled applies the native insertion policy to the helper's +// character labels. Navigation and deletion do not pass through this filter. +func wineTypingEchoEnabled(text string, settings config.Settings) bool { + switch text { + case "tab", "new line": + return settings.EnableKeyEcho && settings.EnableActionKeys + case "space": + text = " " + } + // The helper sends one accepted character per insertion. Do not treat an + // unexpected label as a multi-character paste, which has a different policy. + if utf8.RuneCountInString(text) != 1 { + return false + } + event := atspi.Event{Type: atspi.TextInsertedEvent, Payload: text, Source: atspi.Snapshot{Role: "text", Editable: true}} + return presentation.EventTextWithOptions(event, presentationSettingsFromConfig(settings, false)) != "" +} + +func (owner *wineEventPresenter) Present(event remote.AccessibleEvent) bool { + return owner.present_event(event, nil) +} + +func (owner *wineEventPresenter) present_event(event remote.AccessibleEvent, editor func(remote.AccessibleEvent) bool) bool { + owner.mu.Lock() + defer owner.mu.Unlock() + kind := strings.ToLower(event.EventType) + if owner.closed { + return false + } + if kind == "focus" { + owner.focused = event.SourceID + owner.editable = wineEchoEditField(event) + owner.echoTitle = event.WindowTitle + if owner.foreground != nil { + owner.echoEpoch = owner.foreground.Foreground().Epoch + } + owner.protected = event.Description == "password" || slices.Contains(strings.Split(event.States, ", "), "password") + } else if kind != "value" && kind != "selection" && kind != "text" && kind != "name" && kind != "state" { + return false + } else if event.SourceID != owner.focused { + window := owner.window + if owner.pending != nil { + window = owner.pending.window + } + if kind != "selection" || event.WindowTitle == "" || event.WindowTitle != window { + return false + } + } + if kind == "state" { + if event.Role != "" { + owner.editable = wineEchoEditField(event) + } else if slices.Contains(strings.Split(event.States, ", "), "read only") { + owner.editable = false + } + owner.protected = slices.Contains(strings.Split(event.States, ", "), "password") || event.Description == "password" + } + if owner.protected && event.SourceID == owner.focused { + event.Value = "" + } + if kind == "text" { + if owner.protected || event.Name == "" { + return false + } + // Establish the queued focus before the action. Neither focus merging + // nor duplicate suppression may consume repeated characters/actions. + owner.flush_pending() + if owner.logger != nil { + owner.logger.Debug("Wine editor feedback", "source", event.SourceID, + "native_utf16_selection", event.States, "text", event.Name) + } + // Retain action metadata so character output uses the reader's + // uppercase and custom typing voices after focus/password filtering. + if editor != nil { + if owner.editable { + event.Role = "edit" + } else { + event.Role = "" + } + return editor(event) + } + return owner.present(event.Name) + } + role := event.Role + if strings.EqualFold(role, "client") { + role = "" + } + parts := make([]string, 0, 5) + for _, part := range []string{event.Name, role, event.Value, event.Description} { + if part != "" { + parts = append(parts, part) + } + } + // Only the helper's normalized MSAA states are presentation data. Editor + // offsets/action kinds in this same field stay in debug diagnostics. + for _, state := range strings.Split(event.States, ", ") { + switch state { + case "checked", "not checked", "half checked", "selected", "pressed", "expanded", "collapsed", "unavailable", "read only", "password", "busy": + if !slices.Contains(parts, state) { + parts = append(parts, state) + } + } + } + if event.Position > 0 && event.Count > 0 { + parts = append(parts, fmt.Sprintf("%d of %d", event.Position, event.Count)) + } + if len(parts) == 0 && (kind != "focus" || event.WindowTitle == "") { + return false + } + message := strings.Join(parts, ", ") + key := event.SourceID + "\x00" + message + if message == "" { + key = event.SourceID + "\x00" + event.WindowTitle + } + // Losing native focus emits a state event for the previous control before + // the new focus arrives. Focus bookkeeping is absent from the normalized + // states, so an unchanged semantic presentation must stay quiet even when + // the last announcement was more than 100 ms ago. + if kind == "state" && key == owner.lastKey { + if owner.logger != nil { + owner.logger.Debug("Wine state unchanged", "source", event.SourceID, "text", message) + } + return false + } + if key == owner.lastKey && time.Since(owner.lastTime) < 100*time.Millisecond { + if kind == "focus" { + owner.pending = nil + } + return false + } + if kind == "focus" { + owner.pending = &winePresentation{source: event.SourceID, window: event.WindowTitle, message: message, parts: parts} + if owner.timer == nil { + generation := owner.timerGeneration + owner.timer = time.AfterFunc(50*time.Millisecond, func() { owner.flush_generation(generation) }) + } + return true + } + if pending := owner.pending; pending != nil && + (pending.source == event.SourceID || event.WindowTitle != "" && pending.window == event.WindowTitle) { + pending.source = event.SourceID + pending.message = message + pending.parts = parts + return true + } + owner.lastKey, owner.lastTime = key, time.Now() + return owner.present(message) +} + +func (owner *wineEventPresenter) flush() { + owner.mu.Lock() + defer owner.mu.Unlock() + owner.flush_pending() +} + +func (owner *wineEventPresenter) flush_generation(generation uint64) { + owner.mu.Lock() + defer owner.mu.Unlock() + if generation == owner.timerGeneration { + owner.flush_pending() + } +} + +// flush_pending requires mu to be held, including for immediate editor +// actions. Stop the old timer so it cannot flush a later focus burst early. +func (owner *wineEventPresenter) flush_pending() { + owner.timerGeneration++ + if owner.timer != nil { + owner.timer.Stop() + } + owner.timer = nil + pending := owner.pending + owner.pending = nil + if owner.closed || pending == nil { + return + } + message := pending.message + if owner.windowTitle != nil && message == pending.window { + // A client-name-only focus is a title report, not a control label. + message = "" + } + if pending.window != "" { + if pending.window != owner.window && owner.windowTitle != nil { + owner.windowTitle(pending.window) + } else if owner.windowTitle == nil && pending.window != owner.window && !slices.Contains(pending.parts, pending.window) { + if message != "" { + message += ", " + } + message += pending.window + } + owner.window = pending.window + } + owner.lastKey = pending.source + "\x00" + pending.message + owner.lastTime = time.Now() + if message != "" { + owner.present(message) + } +} + +func (owner *wineEventPresenter) Close() { + owner.mu.Lock() + defer owner.mu.Unlock() + owner.closed = true + owner.pending = nil + if owner.timer != nil { + owner.timer.Stop() + owner.timer = nil + } +} diff --git a/internal/app/wine_events_native_test.go b/internal/app/wine_events_native_test.go new file mode 100644 index 0000000..2271057 --- /dev/null +++ b/internal/app/wine_events_native_test.go @@ -0,0 +1,132 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "os" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/remote" + "github.com/godbus/dbus/v5" +) + +type wineTestOutput struct { + speech chan speechRequest + braille chan string +} + +func (output *wineTestOutput) Enqueue(request speechRequest) { output.speech <- request } +func (output *wineTestOutput) Interrupt() {} +func (output *wineTestOutput) EnqueueMessage(message string) bool { + output.braille <- message + return true +} + +func TestNativeSessionBusWineEvents(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" { + t.Skip("set CTHULHU_NATIVE_DBUS_TEST=1 inside a private session bus") + } + output := &wineTestOutput{speech: make(chan speechRequest, 32), braille: make(chan string, 32)} + settings := config.DefaultSettings() + settings.KeyEchoInEditFieldsOnly = true + live := &liveSettings{} + live.Store(settings) + handler := remoteSpeech{speech: output, braille: output, live: live} + owner := newWineEventPresenter(func(message string) bool { + return handler.presentMessage(message, "wine-accessible-event") + }) + defer owner.Close() + handler.wine = owner + service := remote.New(slog.New(slog.DiscardHandler), handler) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := service.Start(ctx); err != nil { + t.Fatal(err) + } + defer service.Stop(context.Background()) + client, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + defer client.Close() + object := client.Object(remote.BusName, remote.ObjectPath) + send := func(event remote.AccessibleEvent, want bool) { + t.Helper() + var accepted bool + if err := object.CallWithContext(ctx, remote.InterfaceName+".PresentAccessibleEvent", 0, + event.SourceID, event.EventType, event.Name, event.Role, event.Value, event.States, + event.Description, event.Position, event.Count, event.WindowTitle).Store(&accepted); err != nil { + t.Fatal(err) + } + if accepted != want { + t.Fatalf("%s accepted=%v want=%v", event.EventType, accepted, want) + } + } + send(remote.AccessibleEvent{SourceID: "42:text", EventType: "focus", Role: "edit", Value: "hello"}, true) + owner.flush() + for _, text := range []string{"l", "l", "e selected", "e deleted"} { + send(remote.AccessibleEvent{SourceID: "42:text", EventType: "text", Name: text, States: "start=1 end=2 kind=5"}, true) + } + for _, text := range []string{"A", "a", "É", "é"} { + send(remote.AccessibleEvent{SourceID: "42:text", EventType: "text", Name: text, States: "start=1 end=1 kind=8"}, true) + } + settings.EnableKeyEcho = false + live.Store(settings) + for _, text := range []string{"A", "space", "tab", "new line"} { + send(remote.AccessibleEvent{SourceID: "42:text", EventType: "text", Name: text, States: "kind=8"}, false) + } + send(remote.AccessibleEvent{SourceID: "42:text", EventType: "text", Name: "e", States: "kind=7"}, true) + settings.EnableKeyEcho = true + settings.EnableAlphabeticKeys = false + live.Store(settings) + send(remote.AccessibleEvent{SourceID: "42:text", EventType: "text", Name: "A", States: "kind=8"}, false) + settings.EnableAlphabeticKeys = true + live.Store(settings) + send(remote.AccessibleEvent{SourceID: "42:text", EventType: "text", Name: "A", States: "kind=8"}, true) + send(remote.AccessibleEvent{SourceID: "check", EventType: "focus", Name: "Option", Role: "check box", States: "not checked"}, true) + owner.flush() + send(remote.AccessibleEvent{SourceID: "check", EventType: "name", Name: "Renamed", Role: "check box", States: "not checked"}, true) + send(remote.AccessibleEvent{SourceID: "check", EventType: "state", Name: "Renamed", Role: "check box", States: "checked, unavailable"}, true) + send(remote.AccessibleEvent{SourceID: "42:text", EventType: "text", Name: "stale"}, false) + owner.flush() + send(remote.AccessibleEvent{SourceID: "yes", EventType: "focus", Name: "Yes", Role: "client"}, true) + owner.flush() + owner.mu.Lock() + owner.lastTime = time.Now().Add(-time.Second) + owner.mu.Unlock() + send(remote.AccessibleEvent{SourceID: "no", EventType: "state", Name: "No", Role: "client"}, false) + send(remote.AccessibleEvent{SourceID: "yes", EventType: "state", Name: "Yes", Role: "client"}, false) + send(remote.AccessibleEvent{SourceID: "no", EventType: "focus", Name: "No", Role: "client"}, true) + owner.flush() + owner.Close() + for _, want := range []string{"edit, hello", "l", "l", "e selected", "e deleted", "A", "a", "É", "é", "e", "A", "Option, check box, not checked", "Renamed, check box, not checked", "Renamed, check box, checked, unavailable", "Yes", "No"} { + select { + case request := <-output.speech: + if request.Text != want || !request.Append { + t.Fatalf("speech=%+v want=%q", request, want) + } + if (want == "A" || want == "a" || want == "É" || want == "é") && !request.Character { + t.Fatalf("Wine typing lost character routing: %+v", request) + } + case <-ctx.Done(): + t.Fatal("timed out awaiting speech queue") + } + select { + case message := <-output.braille: + if message != want { + t.Fatalf("braille=%q want=%q", message, want) + } + case <-ctx.Done(): + t.Fatal("timed out awaiting braille queue") + } + } + if len(output.speech) != 0 || len(output.braille) != 0 { + t.Fatal("unexpected extra Wine output") + } +} diff --git a/internal/app/wine_events_test.go b/internal/app/wine_events_test.go new file mode 100644 index 0000000..61e4c0e --- /dev/null +++ b/internal/app/wine_events_test.go @@ -0,0 +1,287 @@ +package app + +import ( + "bytes" + "log/slog" + "slices" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/remote" +) + +func TestWineEventFocusBurstAndSelection(t *testing.T) { + var spoken []string + owner := newWineEventPresenter(func(message string) bool { + spoken = append(spoken, message) + return true + }) + defer owner.Close() + if !owner.Present(remote.AccessibleEvent{SourceID: "window:1", EventType: "focus", Name: "Loading", Role: "client", WindowTitle: "Game"}) { + t.Fatal("focus was rejected") + } + if !owner.Present(remote.AccessibleEvent{SourceID: "window:2", EventType: "focus", Name: "Play", Role: "button", Position: 2, Count: 3, WindowTitle: "Game"}) { + t.Fatal("replacement focus was rejected") + } + if len(spoken) != 0 { + t.Fatalf("focus burst spoke early: %v", spoken) + } + owner.flush() + if len(spoken) != 1 || spoken[0] != "Play, button, 2 of 3, Game" { + t.Fatalf("focus presentation = %v", spoken) + } + if owner.Present(remote.AccessibleEvent{SourceID: "other", EventType: "value", Value: "unfocused", WindowTitle: "Game"}) { + t.Fatal("unfocused value was accepted") + } + if !owner.Present(remote.AccessibleEvent{SourceID: "list:item", EventType: "selection", Name: "Race", Role: "list item", WindowTitle: "Game"}) { + t.Fatal("same-window selection was rejected") + } + if len(spoken) != 2 || spoken[1] != "Race, list item" { + t.Fatalf("selection presentation = %v", spoken) + } +} + +func TestWineEventClosedAndEmptyFiltering(t *testing.T) { + owner := newWineEventPresenter(func(string) bool { return true }) + if owner.Present(remote.AccessibleEvent{SourceID: "source", EventType: "unknown", Name: "ignored"}) { + t.Fatal("unknown event accepted") + } + if owner.Present(remote.AccessibleEvent{SourceID: "source", EventType: "focus", Role: "client"}) { + t.Fatal("empty client focus accepted") + } + owner.Close() + if owner.Present(remote.AccessibleEvent{SourceID: "source", EventType: "focus", Name: "after stop"}) { + t.Fatal("event accepted after stop") + } +} + +func TestWineButtonFocusLossDoesNotRepeatPreviousControl(t *testing.T) { + speech := &remoteSpeechQueue{} + braille := &remoteBrailleQueue{running: true} + presenter := remoteSpeech{speech: speech, braille: braille} + owner := newWineEventPresenter(func(message string) bool { + return presenter.presentMessage(message, "wine-accessible-event") + }) + defer owner.Close() + buttons := []string{"Yes", "No", "Cancel", "No"} + owner.Present(remote.AccessibleEvent{SourceID: buttons[0], EventType: "focus", Name: buttons[0], Role: "client"}) + owner.flush() + for index := 1; index < len(buttons); index++ { + previous, current := buttons[index-1], buttons[index] + // Native Wine sends the new button's state, the previous button's + // focus-loss state, then the new focus after a pause between Tabs. + owner.mu.Lock() + owner.lastTime = time.Now().Add(-time.Second) + owner.mu.Unlock() + if owner.Present(remote.AccessibleEvent{SourceID: current, EventType: "state", Name: current, Role: "client"}) { + t.Fatal("next button's state accepted before focus") + } + if owner.Present(remote.AccessibleEvent{SourceID: previous, EventType: "state", Name: previous, Role: "client"}) { + t.Fatal("unchanged previous button repeated on focus loss") + } + owner.Present(remote.AccessibleEvent{SourceID: current, EventType: "focus", Name: current, Role: "client"}) + owner.flush() + } + var spoken []string + for _, request := range speech.requests { + spoken = append(spoken, request.Text) + } + if !slices.Equal(spoken, buttons) || !slices.Equal(braille.text, buttons) { + t.Fatalf("spoken=%v braille=%v; want %v", spoken, braille.text, buttons) + } +} + +func TestWineEditorActionsReachSpeechAndBrailleInOrder(t *testing.T) { + speech := &remoteSpeechQueue{} + braille := &remoteBrailleQueue{running: true} + var log bytes.Buffer + presenter := remoteSpeech{speech: speech, braille: braille} + owner := newWineEventPresenter(func(message string) bool { + return presenter.presentMessage(message, "wine-accessible-event") + }) + owner.logger = slog.New(slog.NewTextHandler(&log, &slog.HandlerOptions{Level: slog.LevelDebug})) + defer owner.Close() + presenter.wine = owner + if !presenter.PresentAccessibleEvent(remote.AccessibleEvent{ + SourceID: "42:text", EventType: "focus", Role: "edit", Value: "hello beta", + }) { + t.Fatal("editor focus rejected") + } + for _, text := range []string{"e", "l", "l", "beta", "second line", "s selected", "s unselected", "s deleted", "😀"} { + if !presenter.PresentAccessibleEvent(remote.AccessibleEvent{ + SourceID: "42:text", EventType: "text", Name: text, + States: "start=1 end=2 kind=5", + }) { + t.Fatalf("editor action %q rejected", text) + } + } + owner.flush() + want := []string{"edit, hello beta", "e", "l", "l", "beta", "second line", "s selected", "s unselected", "s deleted", "😀"} + var spoken []string + for _, request := range speech.requests { + spoken = append(spoken, request.Text) + if !request.Append || request.Cause != "wine-accessible-event" { + t.Fatalf("unexpected editor speech policy: %+v", request) + } + } + if !slices.Equal(spoken, want) || !slices.Equal(braille.text, want) { + t.Fatalf("spoken=%v braille=%v; want %v", spoken, braille.text, want) + } + for _, diagnostic := range []string{"Wine editor feedback", "42:text", "start=1 end=2 kind=5", "s deleted"} { + if !strings.Contains(log.String(), diagnostic) { + t.Fatalf("missing debug diagnostic %q: %s", diagnostic, log.String()) + } + } +} + +func TestWineEditorRejectsStaleAndPasswordActions(t *testing.T) { + var spoken []string + var log bytes.Buffer + owner := newWineEventPresenter(func(message string) bool { spoken = append(spoken, message); return true }) + owner.logger = slog.New(slog.NewTextHandler(&log, &slog.HandlerOptions{Level: slog.LevelDebug})) + defer owner.Close() + text := remote.AccessibleEvent{SourceID: "42:text", EventType: "text", Name: "private text"} + if owner.Present(text) { + t.Fatal("text accepted without focus") + } + owner.Present(remote.AccessibleEvent{SourceID: "42:text", EventType: "focus", Role: "edit"}) + owner.Present(remote.AccessibleEvent{SourceID: "menu", EventType: "focus", Name: "File", Role: "submenu"}) + if owner.Present(text) { + t.Fatal("text from editor accepted while menu owns focus") + } + owner.Present(remote.AccessibleEvent{SourceID: "42:text", EventType: "focus", Role: "edit", Value: "private text", Description: "password"}) + if owner.Present(text) { + t.Fatal("password action accepted") + } + owner.flush() + if !slices.Equal(spoken, []string{"edit, password"}) { + t.Fatalf("password focus/output = %v", spoken) + } + owner.Present(remote.AccessibleEvent{SourceID: "42:text", EventType: "focus", Role: "edit", States: "password"}) + if owner.Present(text) { + t.Fatal("MSAA password action accepted") + } + owner.Present(remote.AccessibleEvent{SourceID: "42:text", EventType: "focus", Role: "edit", Value: "blank"}) + if !owner.Present(remote.AccessibleEvent{SourceID: "42:text", EventType: "text", Name: "h"}) { + t.Fatal("ordinary editor did not recover after password focus") + } + if strings.Contains(log.String(), "private text") { + t.Fatalf("rejected/password text reached debug log: %s", log.String()) + } +} + +func TestWineFocusedNameAndStateChanges(t *testing.T) { + var spoken []string + owner := newWineEventPresenter(func(message string) bool { spoken = append(spoken, message); return true }) + defer owner.Close() + event := remote.AccessibleEvent{SourceID: "check", EventType: "focus", Name: "Option", Role: "check box", States: "not checked"} + owner.Present(event) + event.EventType, event.Name = "name", "Renamed option" + if !owner.Present(event) { + t.Fatal("focused name change rejected") + } + event.EventType, event.States = "state", "checked, unavailable" + if !owner.Present(event) { + t.Fatal("focused state change rejected") + } + owner.flush() + event.States = "not checked" + if !owner.Present(event) { + t.Fatal("unchecked state rejected") + } + for _, kind := range []string{"name", "state", "text"} { + event.SourceID, event.EventType = "background", kind + if owner.Present(event) { + t.Fatalf("background %s change accepted", kind) + } + } + want := []string{"Renamed option, check box, checked, unavailable", "Renamed option, check box, not checked"} + if !slices.Equal(spoken, want) { + t.Fatalf("spoken=%v want=%v", spoken, want) + } +} + +func TestWineEditorFlushInvalidatesOldTimer(t *testing.T) { + var spoken []string + owner := newWineEventPresenter(func(message string) bool { spoken = append(spoken, message); return true }) + defer owner.Close() + owner.Present(remote.AccessibleEvent{SourceID: "editor", EventType: "focus", Role: "edit"}) + owner.mu.Lock() + oldGeneration := owner.timerGeneration + owner.timer.Stop() + owner.mu.Unlock() + owner.Present(remote.AccessibleEvent{SourceID: "editor", EventType: "text", Name: "a"}) + owner.Present(remote.AccessibleEvent{SourceID: "menu", EventType: "focus", Name: "File"}) + owner.mu.Lock() + owner.timer.Stop() + owner.mu.Unlock() + // Model a timer that fired before Stop but was waiting for delivery. + owner.flush_generation(oldGeneration) + if !slices.Equal(spoken, []string{"edit", "a"}) { + t.Fatalf("stale timer delivered new focus: %v", spoken) + } + owner.flush() + if !slices.Equal(spoken, []string{"edit", "a", "File"}) { + t.Fatalf("menu focus lost: %v", spoken) + } +} + +func TestWineEditorCharacterSpeechRouting(t *testing.T) { + settings := config.DefaultSettings() + settings.UseCustomEchoVoice = true + live := &liveSettings{} + live.Store(settings) + speech := &remoteSpeechQueue{} + braille := &remoteBrailleQueue{running: true} + presenter := remoteSpeech{speech: speech, braille: braille, live: live} + owner := newWineEventPresenter(func(message string) bool { + return presenter.presentMessage(message, "wine-accessible-event") + }) + defer owner.Close() + presenter.wine = owner + presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "edit", EventType: "focus", Role: "edit"}) + owner.flush() + for _, tc := range []struct { + text, states string + character, custom bool + }{ + {"A", "kind=8", true, true}, + {"a", "start=1 end=1 kind=8", true, true}, + {"É", "kind=8", true, true}, + {"𐐀", "kind=8", true, true}, + {"😀", "kind=8", true, true}, + {"space", "kind=8", true, true}, + {"new line", "kind=8", true, true}, + {"tab", "kind=8", true, true}, + {"A", "kind=5", true, false}, + {"A", "kind=7", true, true}, + {"ABC", "kind=5", false, false}, + {"A selected", "kind=2", false, false}, + {"A deleted", "kind=4", false, false}, + {"A", "kind=80", true, false}, + } { + if !presenter.PresentAccessibleEvent(remote.AccessibleEvent{ + SourceID: "edit", EventType: "text", Name: tc.text, States: tc.states, + }) { + t.Fatalf("action rejected: %+v", tc) + } + request := speech.requests[len(speech.requests)-1] + if request.Text != tc.text || request.Character != tc.character || request.CustomEcho != tc.custom || + request.PhoneticHint != (tc.states == "kind=5") || + !request.Append || request.Cause != "wine-accessible-event" { + t.Fatalf("action %+v: request=%+v", tc, request) + } + if braille.text[len(braille.text)-1] != tc.text { + t.Fatalf("braille changed: %v", braille.text) + } + } + settings.EnableEchoByCharacter = true + settings.UseCustomEchoForCharacter = false + live.Store(settings) + presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "edit", EventType: "text", Name: "A", States: "kind=8"}) + if speech.requests[len(speech.requests)-1].CustomEcho { + t.Fatal("disabled custom character echo voice was used") + } +} diff --git a/internal/app/wine_review_capture.go b/internal/app/wine_review_capture.go new file mode 100644 index 0000000..ed39a4f --- /dev/null +++ b/internal/app/wine_review_capture.go @@ -0,0 +1,59 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "errors" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/wine" + "strings" +) + +type wineReviewCapturer interface { + Capture(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) +} +type reviewCaptureRouter struct { + native review.TreeCapturer + wine wineReviewCapturer +} + +func reservedWineID(id atspi.ObjectID) bool { + return id.Path == "/wine" || strings.HasPrefix(id.Path, "/wine/") +} +func (r *reviewCaptureRouter) FreshReviewWindow(id atspi.ObjectID) bool { return reservedWineID(id) } +func (r *reviewCaptureRouter) NativeCapturerFor(id atspi.ObjectID) review.TreeCapturer { + if reservedWineID(id) { + return nil + } + return r.native +} +func (r *reviewCaptureRouter) CaptureDesktop(ctx context.Context) (*atspi.AccessibleTree, error) { + return r.native.CaptureDesktop(ctx) +} +func (r *reviewCaptureRouter) CaptureReviewWindow(ctx context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { + if !reservedWineID(id) { + return r.native.CaptureReviewWindow(ctx, id) + } + if r.wine == nil || !wine.IsReviewID(id) { + return nil, wine.ErrReviewUnavailable + } + tree, err := r.wine.Capture(ctx, id) + if errors.Is(err, wine.ErrReviewLimited) { + err = review.ErrLimitedReview + } + return tree, err +} +func (r *reviewCaptureRouter) CaptureDocument(ctx context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { + if reservedWineID(id) { + return nil, wine.ErrReviewUnavailable + } + return r.native.CaptureDocument(ctx, id) +} +func (r *reviewCaptureRouter) CaptureDocumentText(ctx context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { + if reservedWineID(id) { + return nil, wine.ErrReviewUnavailable + } + return r.native.CaptureDocumentText(ctx, id) +} diff --git a/internal/app/wine_review_capture_test.go b/internal/app/wine_review_capture_test.go new file mode 100644 index 0000000..39dab39 --- /dev/null +++ b/internal/app/wine_review_capture_test.go @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "errors" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/wine" + "testing" +) + +type reviewNativeSpy struct { + calls []string + ids []atspi.ObjectID +} + +func (s *reviewNativeSpy) record(method string, id atspi.ObjectID) (*atspi.AccessibleTree, error) { + s.calls = append(s.calls, method) + s.ids = append(s.ids, id) + return nil, nil +} +func (s *reviewNativeSpy) CaptureDesktop(context.Context) (*atspi.AccessibleTree, error) { + return s.record("desktop", atspi.ObjectID{}) +} +func (s *reviewNativeSpy) CaptureReviewWindow(_ context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { + return s.record("review", id) +} +func (s *reviewNativeSpy) CaptureDocument(_ context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { + return s.record("document", id) +} +func (s *reviewNativeSpy) CaptureDocumentText(_ context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { + return s.record("text", id) +} + +type reviewWineSpy struct { + calls int + err error +} + +func (s *reviewWineSpy) Capture(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) { + s.calls++ + return nil, s.err +} +func TestReviewCaptureRouterNativeDelegation(t *testing.T) { + native := &reviewNativeSpy{} + r := &reviewCaptureRouter{native: native, wine: &reviewWineSpy{}} + id := atspi.NewObjectID(":1.2", "/linux") + r.CaptureDesktop(context.Background()) + r.CaptureReviewWindow(context.Background(), id) + r.CaptureDocument(context.Background(), id) + r.CaptureDocumentText(context.Background(), id) + if len(native.calls) != 4 || native.calls[0] != "desktop" || native.calls[1] != "review" || native.calls[2] != "document" || native.calls[3] != "text" || r.FreshReviewWindow(id) || r.NativeCapturerFor(id) != native { + t.Fatal("native delegation changed") + } + for _, got := range native.ids[1:] { + if got != id { + t.Fatal("native identity changed") + } + } +} +func TestReviewCaptureRouterWineIDsNeverReachATSPINativeCalls(t *testing.T) { + native := &reviewNativeSpy{} + provider := &reviewWineSpy{err: wine.ErrReviewLimited} + r := &reviewCaptureRouter{native: native, wine: provider} + ids := []atspi.ObjectID{wine.ReviewID(":1.2", "instance", "window", "input"), atspi.NewObjectID(":1.2", "/wine/malformed"), atspi.NewObjectID(":1.2", "/wine")} + for _, id := range ids { + if !r.FreshReviewWindow(id) || r.NativeCapturerFor(id) != nil { + t.Fatal("Wine optional native capability exposed") + } + if _, err := r.CaptureDocument(context.Background(), id); !errors.Is(err, wine.ErrReviewUnavailable) { + t.Fatal(err) + } + if _, err := r.CaptureDocumentText(context.Background(), id); !errors.Is(err, wine.ErrReviewUnavailable) { + t.Fatal(err) + } + _, err := r.CaptureReviewWindow(context.Background(), id) + if wine.IsReviewID(id) && !errors.Is(err, review.ErrLimitedReview) { + t.Fatal("limit message mapping lost") + } + } + if len(native.calls) != 0 || provider.calls != 1 { + t.Fatalf("native Wine calls: %+v", native.calls) + } +} diff --git a/internal/app/wine_review_focus.go b/internal/app/wine_review_focus.go new file mode 100644 index 0000000..315cd04 --- /dev/null +++ b/internal/app/wine_review_focus.go @@ -0,0 +1,125 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/wine" + "log/slog" +) + +type wineReviewFocusRegistry interface { + Focuses() []wine.ReviewFocusNotice + Current(atspi.ObjectID) bool +} + +// Only the event loop calls this controller. Inputs are copied metadata; +// foreground queries read the adapter's atomic cache and perform no native I/O. +type wineReviewFocusController struct { + registry wineReviewFocusRegistry + logger *slog.Logger + state *eventLoopState + foreground foregroundMonitor + titles windowTitleSource + gate *focusGate + worker *review.Worker + clear func() + active wine.ReviewFocusNotice + epoch uint64 +} + +func wineReviewBoundsMatch(bounds atspi.Rectangle, client xorg.Foreground) bool { + return client.Known && client.Window != 0 && bounds.Valid() && ((int64(bounds.X) == int64(client.X) && int64(bounds.Y) == int64(client.Y) && int64(bounds.Width) == int64(client.Width) && int64(bounds.Height) == int64(client.Height)) || + (int64(bounds.X) == int64(client.OuterX) && int64(bounds.Y) == int64(client.OuterY) && int64(bounds.Width) == int64(client.OuterWidth) && int64(bounds.Height) == int64(client.OuterHeight))) +} +func (c *wineReviewFocusController) eligible(notice wine.ReviewFocusNotice, fg atspi.ForegroundState, title atspi.ForegroundTitle) bool { + metadata := title.Title + if !fg.Client.Known || fg.Client.Window == 0 || title.Epoch != fg.Epoch || metadata.Window != fg.Client.Window || !metadata.Wine || !metadata.Focused || !equivalentWindowTitles(metadata.Title, notice.Title) { + return false + } + if metadata.TitleWindow == metadata.Window { + return wineReviewBoundsMatch(notice.Bounds, fg.Client) + } + if metadata.TitleWindow == 0 || metadata.Client.Window != metadata.TitleWindow { + return false + } + if wineReviewBoundsMatch(notice.Bounds, metadata.Client) { + return true + } + // Wine's virtual desktop uses desktop-local screen coordinates. Corroborate + // a translated rectangle against the actual focused X11 child, not a title. + return int64(notice.Bounds.X)+int64(fg.Client.X) == int64(metadata.Client.X) && int64(notice.Bounds.Y)+int64(fg.Client.Y) == int64(metadata.Client.Y) && + int64(notice.Bounds.Width) == int64(metadata.Client.Width) && int64(notice.Bounds.Height) == int64(metadata.Client.Height) && notice.Bounds.Valid() +} +func (c *wineReviewFocusController) changed() { + if c == nil || c.registry == nil || c.worker == nil || c.foreground == nil || c.titles == nil || c.gate.Locked() { + if c != nil { + c.retire() + } + return + } + fg, title := c.foreground.Foreground(), c.titles.ForegroundTitle() + var selected wine.ReviewFocusNotice + count := 0 + for _, notice := range c.registry.Focuses() { + eligible := c.eligible(notice, fg, title) + if !eligible && c.logger != nil { + c.logger.Debug("Wine review foreground mismatch", "sender", notice.Sender, + "window", notice.Window, "focus", notice.Focus, "revision", notice.Revision, + "source_bounds", notice.Bounds, "native_foreground", fg.Client, + "foreground_epoch", fg.Epoch, "title_epoch", title.Epoch, "title_metadata", title.Title) + } + if eligible { + selected = notice + count++ + } + } + if count != 1 || !c.registry.Current(selected.ID()) { + c.retire() + return + } + c.gate.SetSuspended(false) + transition := c.active.ID() != selected.ID() || c.active.Revision != selected.Revision || c.active.Protected != selected.Protected || c.epoch != fg.Epoch + if transition { + if c.clear != nil { + c.clear() + } else { + c.worker.ClearFocus() + } + c.worker.SyncFocus(selected.ID()) + } + c.active, c.epoch = selected, fg.Epoch + c.state.current = atspi.Snapshot{BusName: selected.Sender, Path: selected.ID().Path, Role: "text"} + if selected.Protected { + c.state.current.Role = "password text" + } + c.state.focusedID = selected.ID() + c.state.owner = windowOwner{applicationBus: selected.Sender, window: wine.ReviewID(selected.Sender, selected.Instance, selected.Window, selected.Window), focus: selected.ID(), activated: true, title: selected.Title} +} +func (c *wineReviewFocusController) foregroundChanged() { c.changed() } +func (c *wineReviewFocusController) retire() { + if c == nil || c.active.Sender == "" { + return + } + if c.worker != nil && c.worker.Focus() == c.active.ID() { + if c.clear != nil { + c.clear() + } else { + c.worker.ClearFocus() + } + } + if c.state != nil && c.state.owner.applicationBus == c.active.Sender { + c.state.owner.clear() + } + c.active = wine.ReviewFocusNotice{} + c.epoch = 0 +} +func (c *wineReviewFocusController) owns(id atspi.ObjectID) bool { + return c != nil && c.active.Sender != "" && c.active.ID() == id && c.registry.Current(id) +} +func (c *wineReviewFocusController) resultCurrent(result review.Result) bool { + c.changed() + return c.owns(result.FlatFocus) && flatReviewResultCurrent(c.worker, result) +} diff --git a/internal/app/wine_review_focus_test.go b/internal/app/wine_review_focus_test.go new file mode 100644 index 0000000..59a58d0 --- /dev/null +++ b/internal/app/wine_review_focus_test.go @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "context" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/wine" + "log/slog" + "testing" + "time" +) + +type reviewFocusRegistry struct{ notices []wine.ReviewFocusNotice } + +func (r *reviewFocusRegistry) Focuses() []wine.ReviewFocusNotice { + return append([]wine.ReviewFocusNotice(nil), r.notices...) +} + +func TestWineReviewSpeechBrailleAndSpelling(t *testing.T) { + c, _, _, worker := reviewFocusSetup(t) + c.changed() + queue := &fakeSpeechQueue{spoken: make(chan string, 10), requests: make(chan speechRequest, 10)} + frames := make(chan braille.Frame, 10) + handler := &eventReviewHandler{state: c.state, logger: slog.New(slog.DiscardHandler), speech: queue, objectReview: worker, wineReview: c, + brailleOutput: frameRecorder{frames: frames}, syncForeground: c.foregroundChanged} + for _, test := range []struct { + unit review.FlatUnit + style review.FlatSpeech + text string + }{ + {review.Line, review.FlatSpeak, "alpha beta"}, {review.Word, review.FlatSpell, "cat"}, {review.Character, review.FlatPhonetic, "c"}, + } { + handler.handle(review.Result{FlatUnit: test.unit, FlatSpeech: test.style, FlatFocus: worker.Focus(), DocumentEpoch: worker.DocumentEpoch(), FlatPosition: review.FlatPosition{Text: test.text}}) + request := <-queue.requests + if request.Cause != "flat-review" || (test.style != review.FlatSpeak && len(request.Spelling) == 0) { + t.Fatalf("shared presentation lost: %+v", request) + } + select { + case frame := <-frames: + if frame.Text != test.text || len(frame.Routes) != 0 || frame.Document != nil { + t.Fatalf("braille: %+v", frame) + } + case <-time.After(time.Second): + t.Fatal("Wine review braille frame missing") + } + } +} + +func TestWineReviewLockAndXTermHandoff(t *testing.T) { + c, _, _, worker := reviewFocusSetup(t) + c.gate = newFocusGate(nil) + c.gate.SetSuspended(true) + c.changed() + if c.gate.Suspended() || !worker.Focus().Valid() { + t.Fatal("Wine focus failed to resume review grabs") + } + c.gate.secure.Store(true) + c.changed() + if worker.Focus().Valid() { + t.Fatal("locked session kept Wine review focus") + } +} +func (r *reviewFocusRegistry) Current(id atspi.ObjectID) bool { + for _, n := range r.notices { + if n.ID() == id { + return true + } + } + return false +} + +type reviewFocusMonitor struct { + state atspi.ForegroundState + title atspi.ForegroundTitle +} + +func (m *reviewFocusMonitor) Foreground() atspi.ForegroundState { return m.state } +func (m *reviewFocusMonitor) ForegroundChanges() <-chan struct{} { return nil } +func (m *reviewFocusMonitor) ForegroundTitle() atspi.ForegroundTitle { return m.title } +func (m *reviewFocusMonitor) TitleChanges() <-chan struct{} { return nil } +func reviewFocusSetup(t *testing.T) (*wineReviewFocusController, *reviewFocusRegistry, *reviewFocusMonitor, *review.Worker) { + t.Helper() + n := wine.ReviewFocusNotice{Sender: ":1.20", Path: wine.ReviewObjectPath, Instance: "instance", Window: "window", Focus: "empty", Revision: 1, Title: "Same title", Role: "window", Bounds: atspi.Rectangle{X: -20, Y: 10, Width: 400, Height: 300}} + registry := &reviewFocusRegistry{notices: []wine.ReviewFocusNotice{n}} + monitor := &reviewFocusMonitor{state: atspi.ForegroundState{Epoch: 1, Client: xorg.Foreground{Known: true, Window: 20, X: -20, Y: 10, Width: 400, Height: 300}}} + monitor.title = atspi.ForegroundTitle{Epoch: 1, Title: xorg.WindowTitle{Window: 20, TitleWindow: 20, Title: n.Title, Application: "fixture.exe", Wine: true, Focused: true, Client: monitor.state.Client}} + worker, err := review.NewWorker(&fakeAdapter{}, time.Second) + if err != nil { + t.Fatal(err) + } + state := &eventLoopState{} + controller := &wineReviewFocusController{registry: registry, state: state, foreground: monitor, titles: monitor, worker: worker, clear: func() { state.current = atspi.Snapshot{}; state.focusedID = atspi.ObjectID{}; worker.ClearFocus() }} + return controller, registry, monitor, worker +} +func TestWineReviewIdenticalTitlesDoNotClaimForeground(t *testing.T) { + c, r, m, w := reviewFocusSetup(t) + r.notices[0].Bounds.X = 500 + c.changed() + if w.Focus().Valid() { + t.Fatal("title alone claimed focus") + } + r.notices[0].Bounds.X = -20 + duplicate := r.notices[0] + duplicate.Sender = ":1.21" + r.notices = append(r.notices, duplicate) + c.changed() + if w.Focus().Valid() { + t.Fatal("ambiguous providers claimed focus") + } + r.notices = r.notices[:1] + m.title.Title.Wine = false + c.changed() + if w.Focus().Valid() { + t.Fatal("Linux client claimed by stale Wine provider") + } + m.title.Title.Wine = true + c.changed() + if w.Focus() != r.notices[0].ID() { + t.Fatal("unique geometry did not establish focus") + } +} +func TestWineReviewForegroundAndVirtualDesktop(t *testing.T) { + c, r, m, w := reviewFocusSetup(t) + c.changed() + if w.Focus() != r.notices[0].ID() { + t.Fatal("negative coordinate focus missing") + } + m.state.Epoch++ + c.foregroundChanged() + if w.Focus().Valid() { + t.Fatal("old metadata epoch reused") + } + m.title.Epoch = m.state.Epoch + m.state.Client.Width = 800 + m.state.Client.Height = 600 + m.title.Title.TitleWindow = 21 + m.title.Title.Client = xorg.Foreground{Known: true, Window: 21, X: -20, Y: 10, Width: 400, Height: 300} + c.foregroundChanged() + if w.Focus() != r.notices[0].ID() { + t.Fatal("focused desktop child not matched") + } + m.title.Title.Focused = false + c.changed() + if w.Focus().Valid() { + t.Fatal("fallback desktop title claimed focus") + } +} +func TestWineReviewDropsOldResultsAndRestarts(t *testing.T) { + c, r, m, w := reviewFocusSetup(t) + c.changed() + old := review.Result{FlatUnit: review.Line, FlatFocus: w.Focus(), DocumentEpoch: w.DocumentEpoch()} + if !c.resultCurrent(old) { + t.Fatal("current result rejected") + } + c.changed() + if !c.resultCurrent(old) { + t.Fatal("duplicate retired cursor") + } + r.notices[0].Revision++ + c.changed() + if c.resultCurrent(old) { + t.Fatal("revision retained queued result") + } + old = review.Result{FlatUnit: review.Line, FlatFocus: w.Focus(), DocumentEpoch: w.DocumentEpoch()} + r.notices = nil + c.changed() + if c.resultCurrent(old) || w.Focus().Valid() { + t.Fatal("dead provider remained active") + } + m.state.Client.Known = false + c.changed() + if w.Focus().Valid() { + t.Fatal("unknown foreground accepted") + } + // Native ownership is restored by the normal native event path after retirement. + native := atspi.NewObjectID(":1.8", "/linux") + w.SyncFocus(native) + c.changed() + if w.Focus() != native { + t.Fatal("Wine retirement erased restored Linux focus") + } +} +func TestWineReviewEmptyFocusCanReachOutput(t *testing.T) { + c, r, _, w := reviewFocusSetup(t) + n := r.notices[0] + root := wine.ReviewID(n.Sender, n.Instance, n.Window, n.Window) + empty := n.ID() + output := wine.ReviewID(n.Sender, n.Instance, n.Window, "output") + geometry := func(b atspi.Rectangle) atspi.Geometry { + return atspi.Geometry{Bounds: b, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + } + tree, err := atspi.NewAccessibleTree(root, []atspi.TreeNode{ + {Snapshot: atspi.Snapshot{BusName: root.BusName, Path: root.Path, Role: "window"}, Geometry: geometry(n.Bounds), Children: []atspi.ObjectID{empty, output}}, + {Snapshot: atspi.Snapshot{BusName: empty.BusName, Path: empty.Path, Role: "text"}, Geometry: geometry(atspi.Rectangle{X: 0, Y: 40, Width: 200, Height: 20}), Text: atspi.VisibleText{Known: true, CaretKnown: true}}, + {Snapshot: atspi.Snapshot{BusName: output.BusName, Path: output.Path, Role: "text"}, Geometry: geometry(atspi.Rectangle{X: 0, Y: 100, Width: 200, Height: 20}), Text: atspi.VisibleText{Known: true, Ranges: []atspi.TextRange{{Start: 0, End: 11, Text: "alpha beta!", Bounds: atspi.Rectangle{X: 0, Y: 100, Width: 200, Height: 20}}}}}, + }) + if err != nil { + t.Fatal(err) + } + c.changed() + cursor := new(review.FlatCursor) + if err = cursor.Refresh(context.Background(), tree, w.Focus()); err != nil { + t.Fatal(err) + } + _, _, err = cursor.Read(review.Line, 0) + position, _, err := cursor.Read(review.Line, 1) + if err != nil || position.Text != "alpha beta!" { + t.Fatalf("empty anchor: %+v %v", position, err) + } +} diff --git a/internal/app/wine_review_native_test.go b/internal/app/wine_review_native_test.go new file mode 100644 index 0000000..475944e --- /dev/null +++ b/internal/app/wine_review_native_test.go @@ -0,0 +1,369 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package app + +import ( + "bufio" + "context" + "encoding/json" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "git.stormux.org/storm/cthulhu/internal/remote" + "git.stormux.org/storm/cthulhu/internal/review" + "git.stormux.org/storm/cthulhu/internal/wine" + "log/slog" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +type wineNativeOutput struct { + requests chan speechRequest + frames chan braille.Frame +} + +func (o *wineNativeOutput) Enqueue(request speechRequest) { o.requests <- request } +func (o *wineNativeOutput) Interrupt() {} +func (o *wineNativeOutput) EnqueueFrame(frame braille.Frame) { o.frames <- frame } + +func TestNativeWineReviewPhysicalKeys(t *testing.T) { + if os.Getenv("CTHULHU_WINE_REVIEW_BUILD") == "" { + t.Skip("requires isolated Wine build/display/session") + } + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) + defer cancel() + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelInfo})) + registry := wine.NewReviewRegistry(logger) + if err := registry.Start(ctx); err != nil { + t.Fatal(err) + } + defer registry.Stop(context.Background()) + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + commands := xorg.NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := commands.Start(ctx); err != nil { + t.Fatal(err) + } + defer commands.Stop(context.Background()) + gate := newFocusGate(commands) + worker, err := review.NewWorker(&reviewCaptureRouter{native: adapter, wine: registry}, time.Second) + if err != nil { + t.Fatal(err) + } + if err = worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + live := &liveSettings{wineReview: registry} + live.Store(config.DefaultSettings()) + output := &wineNativeOutput{requests: make(chan speechRequest, 256), frames: make(chan braille.Frame, 256)} + queue := outputQueue{speech: output, braille: output, live: live} + helperEvents := newWineEventPresenter(func(text string) bool { + output.Enqueue(speechRequest{Text: text, Cause: "wine-accessible-event"}) + return true + }) + defer helperEvents.Close() + service := remote.New(logger, remoteSpeech{speech: output, wine: helperEvents, wineReview: registry}) + if err = service.Start(ctx); err != nil { + t.Fatal(err) + } + defer service.Stop(context.Background()) + eventDone, commandDone := make(chan error, 1), make(chan error, 1) + go func() { + eventDone <- processEventsWithAttributes(ctx, logger, queue, adapter, nil, nil, worker, 0, live, nil, gate, nil, nil) + }() + go func() { + commandDone <- (commandRuntime{logger: logger, commands: commands, focusChanges: commands.FocusChanges(), focusGate: gate, speechOutput: queue, objectReview: worker, live: live, stopRun: cancel}).run(ctx) + }() + defer func() { + cancel() + if err := <-eventDone; err != nil { + t.Error(err) + } + if err := <-commandDone; err != nil { + t.Error(err) + } + }() + driver := exec.CommandContext(ctx, "python3", "-u", "../../tests/wine_review_x11.py") + stdin, err := driver.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := driver.StdoutPipe() + if err != nil { + t.Fatal(err) + } + driver.Stderr = os.Stderr + if err = driver.Start(); err != nil { + t.Fatal(err) + } + defer func() { + stdin.Close() + if err := driver.Wait(); err != nil && ctx.Err() == nil { + t.Error(err) + } + }() + scanner := bufio.NewScanner(stdout) + ready := func() { + t.Helper() + if !scanner.Scan() || scanner.Text() != "{\"ready\": true}" { + t.Fatalf("physical fixture not ready: %s", scanner.Text()) + } + } + ready() + send := func(command map[string]any) { + t.Helper() + data, _ := json.Marshal(command) + if _, err := stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + ready() + } + waitFocus := func() { + t.Helper() + deadline := time.Now().Add(6 * time.Second) + for { + matched := false + probe := &wineReviewFocusController{} + for _, notice := range registry.Focuses() { + if notice.ID() == worker.Focus() && probe.eligible(notice, adapter.Foreground(), adapter.ForegroundTitle()) { + matched = true + } + } + if matched { + return + } + if time.Now().After(deadline) { + t.Fatalf("Wine focus unavailable; notices=%+v foreground=%+v title=%+v", registry.Focuses(), adapter.Foreground(), adapter.ForegroundTitle()) + } + time.Sleep(10 * time.Millisecond) + } + } + waitFocus() + waitCaptureReady := func() { + t.Helper() + deadline := time.Now().Add(5 * time.Second) + for { + id := worker.Focus() + if _, err := registry.Capture(ctx, id); err == nil && registry.Current(id) && worker.Focus() == id { + return + } + if time.Now().After(deadline) { + t.Fatal("new native provider never reached a consistent capture") + } + time.Sleep(10 * time.Millisecond) + } + } + check := func(symbols []uint32, want string, spelling bool) { + t.Helper() + // Normal Linux focus frames can remain queued after switching back to + // Wine. Inspect only frames produced for this physical command. + for len(output.frames) > 0 { + <-output.frames + } + started := time.Now() + send(map[string]any{"action": "keys", "symbols": symbols}) + for { + select { + case request := <-output.requests: + if request.Cause != "flat-review" { + continue + } + if request.Text != want || (spelling && len(request.Spelling) == 0) { + t.Fatalf("keys %x: speech=%+v want=%q", symbols, request, want) + } + if spelling && want == "b" && request.Spelling[0] != "bravo" { + t.Fatalf("phonetic letter: %+v", request.Spelling) + } + t.Logf("keys %x: %q queued in %s", symbols, want, time.Since(started)) + if strings.Contains(request.Text, "private-review-secret") || strings.Contains(request.Text, "hidden-review-secret") { + t.Fatal("excluded text reached speech") + } + goto frame + case <-time.After(2 * time.Second): + tree, captureErr := registry.Capture(ctx, worker.Focus()) + t.Logf("capture=%+v error=%v focus=%+v notices=%+v foreground=%+v title=%+v", tree, captureErr, worker.Focus(), registry.Focuses(), adapter.Foreground(), adapter.ForegroundTitle()) + t.Fatalf("physical keys %x did not produce %q", symbols, want) + } + } + frame: + if !wine.IsReviewID(worker.Focus()) { + return + } + for { + select { + case f := <-output.frames: + if f.Text == "" { + continue + } + if len(f.Routes) != 0 || f.Document != nil || strings.Contains(f.Text, "private-review-secret") { + t.Fatalf("unsafe native routing: %+v", f) + } + return + case <-time.After(time.Second): + t.Fatal("review braille output missing") + } + } + } + check([]uint32{0xff97}, "alpha beta", false) + check([]uint32{0xff9a}, "second line", false) + check([]uint32{0xff95}, "alpha beta", false) + check([]uint32{0xff9d}, "alpha ", false) + check([]uint32{0xff9d}, "alpha ", true) + check([]uint32{0xff9d}, "alpha ", true) + check([]uint32{0xff98}, "beta", false) + check([]uint32{0xff99}, "b", false) + check([]uint32{0xff99}, "b", true) + check([]uint32{0xff9b}, "e", false) + check([]uint32{0xff9c}, "b", false) + check([]uint32{0xff63, 0xff9c}, "a", false) + check([]uint32{0xff63, 0xff98}, "line", false) + check([]uint32{0xff63, 0xff96}, "beta", false) + check([]uint32{0xff63, 0xff95}, "Command:", false) + check([]uint32{0xff63, 0xff9a}, "Open & close", false) + check([]uint32{0xff63, 0xff95}, "Command:", false) + check([]uint32{0xff9a}, "alpha beta", false) + check([]uint32{0xff98}, "beta", false) + send(map[string]any{"action": "check"}) + if os.Getenv("CTHULHU_WINE_REVIEW_WM") == "i3" { + send(map[string]any{"action": "keys", "symbols": []uint32{0xff53}}) + send(map[string]any{"action": "check", "check": "--check-right"}) + return + } + send(map[string]any{"action": "configure", "mode": 6}) + time.Sleep(200 * time.Millisecond) + check([]uint32{0xff9d}, "zeta", false) + // Seek the first text line from the window's caption, then verify an update + // within the same control without a native caret change. + check([]uint32{0xff63, 0xff95}, "Command:", false) + check([]uint32{0xff9a}, "omega zeta native & item", false) + send(map[string]any{"action": "check"}) + send(map[string]any{"action": "keys", "symbols": []uint32{0xff53}}) + send(map[string]any{"action": "check", "check": "--check-right"}) + send(map[string]any{"action": "configure", "mode": 8}) + positionDeadline := time.Now().Add(5 * time.Second) + for { + moved := false + for _, notice := range registry.Focuses() { + if notice.Bounds.X < 0 { + moved = true + } + } + if moved { + break + } + if time.Now().After(positionDeadline) { + t.Fatal("native window movement was not published") + } + time.Sleep(10 * time.Millisecond) + } + waitFocus() + check([]uint32{0xff97}, "alpha beta native & item", false) + oldFocus := worker.Focus() + send(map[string]any{"action": "restart-helper"}) + deadline := time.Now().Add(5 * time.Second) + for worker.Focus() == oldFocus || !wine.IsReviewID(worker.Focus()) { + if time.Now().After(deadline) { + t.Fatal("helper restart kept old review lifetime") + } + time.Sleep(10 * time.Millisecond) + } + waitFocus() + check([]uint32{0xff97}, "alpha beta native & item", false) + // Restart the actual service owner and registry connections. The helper must + // register again and authorize the newly owned connection for capture. + if err := service.Stop(context.Background()); err != nil { + t.Fatal(err) + } + if err := registry.Stop(context.Background()); err != nil { + t.Fatal(err) + } + worker.ClearFocus() + if err := registry.Start(ctx); err != nil { + t.Fatal(err) + } + if err := service.Start(ctx); err != nil { + t.Fatal(err) + } + waitFocus() + check([]uint32{0xff97}, "alpha beta native & item", false) + // A native Linux foreground change retires a queued Wine capture, while its + // blocked MSAA worker is still waiting in the application's window procedure. + send(map[string]any{"action": "configure", "mode": 10}) + waitFocus() + send(map[string]any{"action": "keys", "symbols": []uint32{0xff97}}) + send(map[string]any{"action": "linux"}) + deadline = time.Now().Add(5 * time.Second) + for !worker.Focus().Valid() || wine.IsReviewID(worker.Focus()) { + if time.Now().After(deadline) { + t.Fatalf("Linux focus not restored: %+v", worker.Focus()) + } + time.Sleep(10 * time.Millisecond) + } + check([]uint32{0xff97}, "Linux review ready", false) + lateDeadline := time.After(2 * time.Second) +late: + for { + select { + case request := <-output.requests: + if request.Cause == "flat-review" { + t.Fatalf("late Wine review result: %+v", request) + } + case <-lateDeadline: + break late + } + } + send(map[string]any{"action": "wine"}) + waitFocus() + firstPrefix := worker.Focus() + send(map[string]any{"action": "second-prefix"}) + deadline = time.Now().Add(5 * time.Second) + for worker.Focus().BusName == firstPrefix.BusName || !wine.IsReviewID(worker.Focus()) { + if time.Now().After(deadline) { + t.Fatal("identical titles shared a provider across prefixes") + } + time.Sleep(10 * time.Millisecond) + } + waitFocus() + if worker.Focus().BusName == firstPrefix.BusName { + t.Fatal("identical titles shared a provider across prefixes") + } + // The 32-bit hook host can publish initial lifetime events after its X11 + // window appears. Handshake on a consistent snapshot before this physical + // key; every key still captures again. Do not warm the stalled-call phase. + waitCaptureReady() + check([]uint32{0xff97}, "alpha beta native & item", false) + send(map[string]any{"action": "wine"}) + deadline = time.Now().Add(5 * time.Second) + for worker.Focus() != firstPrefix { + if time.Now().After(deadline) { + t.Fatal("return to first prefix lost its native lifetime") + } + time.Sleep(10 * time.Millisecond) + } + waitFocus() + if worker.Focus() != firstPrefix { + t.Fatal("return to first prefix lost its native lifetime") + } + check([]uint32{0xff97}, "alpha beta native & item", false) + oldDesktopFocus := worker.Focus() + send(map[string]any{"action": "virtual-desktop"}) + deadline = time.Now().Add(6 * time.Second) + for !wine.IsReviewID(worker.Focus()) || worker.Focus().BusName == oldDesktopFocus.BusName { + if time.Now().After(deadline) { + t.Fatal("virtual desktop restart kept the old helper lifetime") + } + time.Sleep(10 * time.Millisecond) + } + waitFocus() + waitCaptureReady() + check([]uint32{0xff97}, "alpha beta native & item", false) +} diff --git a/internal/app/wine_typing_echo_settings_test.go b/internal/app/wine_typing_echo_settings_test.go new file mode 100644 index 0000000..5e68b69 --- /dev/null +++ b/internal/app/wine_typing_echo_settings_test.go @@ -0,0 +1,117 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/remote" +) + +func TestWineTypingEchoUsesLiveSettings(t *testing.T) { + settings := config.DefaultSettings() + live := &liveSettings{} + live.Store(settings) + speech := &remoteSpeechQueue{} + braille := &remoteBrailleQueue{running: true} + presenter := remoteSpeech{speech: speech, braille: braille, live: live} + owner := newWineEventPresenter(func(message string) bool { + return presenter.presentMessage(message, "wine-accessible-event") + }) + defer owner.Close() + presenter.wine = owner + presenter.PresentAccessibleEvent(remote.AccessibleEvent{SourceID: "edit", EventType: "focus", Role: "edit"}) + owner.flush() + check := func(text, kind string, want bool) { + t.Helper() + beforeSpeech, beforeBraille := len(speech.requests), len(braille.text) + accepted := presenter.PresentAccessibleEvent(remote.AccessibleEvent{ + SourceID: "edit", EventType: "text", Name: text, States: "start=1 end=1 kind=" + kind, + }) + if accepted != want { + t.Errorf("%q kind=%s accepted=%v, want %v", text, kind, accepted, want) + } + if !want { + if len(speech.requests) != beforeSpeech || len(braille.text) != beforeBraille { + t.Errorf("disabled typing %q reached output", text) + } + return + } + if len(speech.requests) != beforeSpeech+1 || speech.requests[beforeSpeech].Text != text || + len(braille.text) != beforeBraille+1 || braille.text[beforeBraille] != text { + t.Errorf("enabled action %q missing from speech or braille", text) + } + } + for _, text := range []string{"A", "a", "a", "É", "𐐀", "7", "!", "😀", "space", "tab", "new line"} { + check(text, "8", true) + } + settings.EnableKeyEcho = false + settings.EnableEchoByCharacter = true + live.Store(settings) + for _, text := range []string{"a", "7", "!", "space", "tab", "new line"} { + check(text, "8", false) + } + // Reading, deletion and selection remain available with key echo disabled. + for _, action := range []struct{ text, kind string }{ + {"a", "5"}, {"a", "7"}, {"line of text", "1"}, {"a selected", "2"}, {"a deleted", "4"}, + } { + check(action.text, action.kind, true) + } + settings.EnableKeyEcho = true + settings.EnableEchoByCharacter = false + settings.EnableAlphabeticKeys = false + settings.EnableNumericKeys = false + settings.EnablePunctuationKeys = false + settings.EnableSpace = false + settings.EnableActionKeys = false + live.Store(settings) + for _, text := range []string{"A", "é", "𐐀", "7", "!", "😀", "space", "tab", "new line", "́"} { + check(text, "8", false) + } + settings.EnableEchoByCharacter = true + live.Store(settings) + for _, text := range []string{"A", "é", "7", "!", "😀", "space", "́"} { + check(text, "8", true) + } + for _, text := range []string{"tab", "new line"} { + check(text, "8", false) + } + settings.EnableEchoByCharacter = false + settings.EnableDiacriticalKeys = true + settings.EnableActionKeys = true + live.Store(settings) + for _, text := range []string{"́", "tab", "new line"} { + check(text, "8", true) + } + settings = config.DefaultSettings() + live.Store(settings) + check("a", "8", true) +} + +func TestWineTypingEchoFiltersCategoriesIndependently(t *testing.T) { + for _, tc := range []struct { + name, blocked, allowed string + disable func(*config.Settings) + }{ + {"alphabetic", "É", "7", func(s *config.Settings) { s.EnableAlphabeticKeys = false }}, + {"numeric", "7", "a", func(s *config.Settings) { s.EnableNumericKeys = false }}, + {"punctuation", "!", "a", func(s *config.Settings) { s.EnablePunctuationKeys = false }}, + {"symbol", "😀", "a", func(s *config.Settings) { s.EnablePunctuationKeys = false }}, + {"space", "space", "a", func(s *config.Settings) { s.EnableSpace = false }}, + {"action", "tab", "space", func(s *config.Settings) { s.EnableActionKeys = false }}, + } { + t.Run(tc.name, func(t *testing.T) { + settings := config.DefaultSettings() + tc.disable(&settings) + if wineTypingEchoEnabled(tc.blocked, settings) { + t.Errorf("disabled category echoed %q", tc.blocked) + } + if !wineTypingEchoEnabled(tc.allowed, settings) { + t.Errorf("unrelated category suppressed %q", tc.allowed) + } + }) + } +} diff --git a/internal/app/wine_window_titles.go b/internal/app/wine_window_titles.go new file mode 100644 index 0000000..0cee47e --- /dev/null +++ b/internal/app/wine_window_titles.go @@ -0,0 +1,62 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import "git.stormux.org/storm/cthulhu/internal/atspi" + +type wineWindowTitle struct { + text string + foreground atspi.ForegroundTitle +} + +// Wine control output stays in its presenter. Its titles use the same +// event-loop policy as native title changes, through a copied-data mailbox. +func connectWineWindowTitles(owner *wineEventPresenter, live *liveSettings, adapter Adapter) { + if live == nil { + return + } + live.wineTitles = make(chan wineWindowTitle, 1) + source, _ := adapter.(windowTitleSource) + owner.windowTitle = func(text string) { + update := wineWindowTitle{text: text} + if source != nil { + update.foreground = source.ForegroundTitle() + } + select { + case <-live.wineTitles: + default: + } + select { + case live.wineTitles <- update: + default: + } + } +} + +func (titles *windowTitleController) wineChanged(update wineWindowTitle) { + native := update.foreground.Title + // A helper may deliver a delayed focus after another program took the + // foreground. X11 metadata is authoritative when it is available. + if native.Window != 0 && !equivalentWindowTitles(native.Title, update.text) { + return + } + if titles.foreground != nil { + current := titles.foreground.Foreground() + if current.Client.Known && current.Client.Window == 0 { + return + } + } + changed := titles.lastTitle != "" + if titles.pending != nil { + changed = titles.pending.changed + } + if native.Window != 0 && (update.foreground.Epoch != titles.lastNative.Epoch || + native.Window != titles.lastNative.Title.Window || native.TitleWindow != titles.lastNative.Title.TitleWindow) { + changed = false + } + titles.queue(pendingWindowTitle{text: update.text, native: native, + window: titles.state.owner.window, epoch: update.foreground.Epoch, changed: changed, + application: titles.application}) +} diff --git a/internal/app/wine_window_titles_native_test.go b/internal/app/wine_window_titles_native_test.go new file mode 100644 index 0000000..26aed7f --- /dev/null +++ b/internal/app/wine_window_titles_native_test.go @@ -0,0 +1,213 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package app + +import ( + "context" + "log/slog" + "os" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/wine" +) + +type wineTitleLoopAdapter struct { + fakeAdapter + *reviewFocusMonitor +} + +type changingWineTitleAdapter struct { + wineTitleLoopAdapter + mu sync.Mutex + changes chan struct{} +} + +func (adapter *changingWineTitleAdapter) Foreground() atspi.ForegroundState { + adapter.mu.Lock() + defer adapter.mu.Unlock() + return adapter.state +} + +func (adapter *changingWineTitleAdapter) ForegroundTitle() atspi.ForegroundTitle { + adapter.mu.Lock() + defer adapter.mu.Unlock() + return adapter.title +} + +func (adapter *changingWineTitleAdapter) TitleChanges() <-chan struct{} { return adapter.changes } + +func TestPrivateWineReviewUpdatesPreserveQueuedTitleSpeech(t *testing.T) { + if os.Getenv("CTHULHU_WINE_TITLE_DBUS") != "1" { + t.Skip("requires a private D-Bus session") + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + logger := slog.New(slog.DiscardHandler) + registry := wine.NewReviewRegistry(logger) + if err := registry.Start(ctx); err != nil { + t.Fatal(err) + } + defer registry.Stop(context.Background()) + _, fixture, monitor, reviewWorker := reviewFocusSetup(t) + notice := fixture.notices[0] + if !registry.RegisterProvider(notice.Sender, wine.ReviewObjectPath, wine.ReviewProtocolVersion) || !registry.PresentFocus(notice.Sender, notice) { + t.Fatal("could not register private Wine focus") + } + adapter := &changingWineTitleAdapter{wineTitleLoopAdapter: wineTitleLoopAdapter{fakeAdapter: fakeAdapter{events: make(chan atspi.Event)}, reviewFocusMonitor: monitor}, changes: make(chan struct{}, 1)} + live := &liveSettings{wineReview: registry} + live.Store(config.DefaultSettings()) + speech := newSpeechWorker(logger, &fakeSpeaker{spoken: make(chan string, 4)}) + speech.running = true + done := make(chan error, 1) + go func() { + done <- processEventsWithInput(ctx, logger, speech, adapter, nil, reviewWorker, 0, live, nil, nil, nil) + }() + defer func() { + cancel() + if err := <-done; err != nil { + t.Error(err) + } + }() + wait := func(check func() bool) { + t.Helper() + for !check() { + select { + case <-ctx.Done(): + t.Fatal("Wine title replay timed out") + case <-time.After(time.Millisecond): + } + } + } + wait(func() bool { return reviewWorker.Focus() == notice.ID() }) + speech.mutex.Lock() + initiallyInterrupted := speech.generation != 0 + speech.mutex.Unlock() + if initiallyInterrupted { + t.Fatal("Wine review focus reset requested speech cancellation") + } + var initial speechRequest + wait(func() bool { var ok bool; initial, ok = speech.next(); return ok }) + if err := speech.deliver(ctx, initial); err != nil { + t.Fatal(err) + } + + for _, title := range []string{"East", "In front of the safe zone", "Leaving in front of the safe zone"} { + // The native caption changes before the helper's next metadata notice. + // The old notice loses eligibility, then a new revision reclaims focus. + adapter.mu.Lock() + adapter.title.Title.Title = title + adapter.mu.Unlock() + adapter.changes <- struct{}{} + wait(func() bool { return !reviewWorker.Focus().Valid() }) + speech.mutex.Lock() + interrupted := speech.generation != 0 + speech.mutex.Unlock() + if interrupted { + t.Fatal("Wine metadata retirement canceled title speech") + } + notice.Title = title + notice.Revision++ + if !registry.PresentFocus(notice.Sender, notice) { + t.Fatal("could not update Wine metadata") + } + wait(func() bool { return reviewWorker.Focus() == notice.ID() }) + wait(func() bool { + speech.mutex.Lock() + defer speech.mutex.Unlock() + return len(speech.pending) > 0 && speech.pending[len(speech.pending)-1].Text == title + }) + if speech.InterruptForInput(input.Event{Name: "Up", Pressed: true, Repeat: true}) { + t.Fatal("metadata update removed held-key protection") + } + } + speech.mutex.Lock() + generation := speech.generation + count := len(speech.pending) + speech.mutex.Unlock() + if generation != 0 || count != 3 { + t.Fatalf("metadata interrupted titles: generation=%d pending=%d", generation, count) + } + for _, want := range []string{"East", "In front of the safe zone", "Leaving in front of the safe zone"} { + request, ok := speech.next() + if !ok || request.Text != want || !request.Append { + t.Fatalf("queued title = %+v, want %q", request, want) + } + if err := speech.deliver(ctx, request); err != nil { + t.Fatal(err) + } + } + if !speech.InterruptForInput(input.Event{Name: "Down", Pressed: true}) { + t.Fatal("fresh press failed to stop speech") + } +} + +func TestPrivateWineTitleSurvivesReviewFocusBurst(t *testing.T) { + if os.Getenv("CTHULHU_WINE_TITLE_DBUS") != "1" { + t.Skip("requires a private D-Bus session") + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + logger := slog.New(slog.DiscardHandler) + registry := wine.NewReviewRegistry(logger) + if err := registry.Start(ctx); err != nil { + t.Fatal(err) + } + defer registry.Stop(context.Background()) + _, fixture, monitor, worker := reviewFocusSetup(t) + notice := fixture.notices[0] + if !registry.RegisterProvider(notice.Sender, wine.ReviewObjectPath, wine.ReviewProtocolVersion) || + !registry.PresentFocus(notice.Sender, notice) { + t.Fatal("could not register private Wine focus") + } + adapter := &wineTitleLoopAdapter{fakeAdapter: fakeAdapter{events: make(chan atspi.Event)}, reviewFocusMonitor: monitor} + live := &liveSettings{wineReview: registry} + settings := config.DefaultSettings() + settings.Reading.AutomaticallyReadTitleChanges = false + live.Store(settings) + queue := &fakeSpeechQueue{spoken: make(chan string, 8), requests: make(chan speechRequest, 8)} + done := make(chan error, 1) + go func() { + done <- processEventsWithInput(ctx, logger, queue, adapter, nil, worker, 0, live, nil, nil, nil) + }() + defer func() { + cancel() + if err := <-done; err != nil { + t.Error(err) + } + }() + for worker.Focus() != notice.ID() { + select { + case <-ctx.Done(): + t.Fatal("Wine review did not establish focus") + case <-time.After(time.Millisecond): + } + } + // Wine publishes the frame, then its focused edit control while the + // native title introduction is waiting. Both belong to the same window. + notice.Focus = "edit" + notice.Revision++ + if !registry.PresentFocus(notice.Sender, notice) { + t.Fatal("could not publish focused edit control") + } + select { + case request := <-queue.requests: + if request.Text != "Same title" || request.Cause != "window-title" || !request.Append { + t.Fatalf("Wine window introduction = %+v", request) + } + case <-time.After(time.Second): + t.Fatal("Wine review focus burst cancelled the title introduction") + } + notice.Revision++ + registry.PresentFocus(notice.Sender, notice) + select { + case request := <-queue.requests: + t.Fatalf("Wine control revision repeated the title: %+v", request) + case <-time.After(300 * time.Millisecond): + } +} diff --git a/internal/app/xterm_handoff_test.go b/internal/app/xterm_handoff_test.go new file mode 100644 index 0000000..3df1e3f --- /dev/null +++ b/internal/app/xterm_handoff_test.go @@ -0,0 +1,262 @@ +package app + +import ( + "context" + "log/slog" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/notification" +) + +type commandGrabRecorder struct { + commands chan input.CommandEvent + failures chan error + mutex sync.Mutex + values []bool +} + +func (recorder *commandGrabRecorder) Commands() <-chan input.CommandEvent { + return recorder.commands +} + +func (recorder *commandGrabRecorder) LockStates() <-chan input.LockState { return nil } +func (recorder *commandGrabRecorder) Failures() <-chan error { return recorder.failures } +func (recorder *commandGrabRecorder) Start(context.Context) error { return nil } +func (recorder *commandGrabRecorder) Stop(context.Context) error { return nil } + +func (recorder *commandGrabRecorder) SetCommandGrabs(enabled bool) { + recorder.mutex.Lock() + defer recorder.mutex.Unlock() + recorder.values = append(recorder.values, enabled) +} + +func (recorder *commandGrabRecorder) grabs() []bool { + recorder.mutex.Lock() + defer recorder.mutex.Unlock() + return append([]bool(nil), recorder.values...) +} + +func TestXTermFocusSuspendsAndResumesPresentationAndCommandGrabs(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 8), interrupt: make(chan struct{}, 8)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 8)} + commands := &commandGrabRecorder{ + commands: make(chan input.CommandEvent, 1), + failures: make(chan error, 1), + } + gate := newFocusGate(commands) + gate.speech = speech + history := notification.NewPresenter() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + defer close(completed) + processEventsWithInput( + ctx, + slog.New(slog.DiscardHandler), + outputQueue{speech: gatedSpeech{speech: speech, gate: gate}}, + adapter, + nil, + nil, + 0, + nil, + nil, + gate, + history, + ) + }() + + home := atspi.NewSnapshot("/home", "Home", "push button", "", "") + home.ApplicationName = "Browser" + terminal := atspi.NewSnapshot("/terminal", "XTerm", "terminal", "", "Prompt") + terminal.ApplicationName = "xterm" + notification := atspi.NewSnapshot("/notification", "", "frame", "", "") + notification.ApplicationName = "xfce4-notifyd" + notification.Text = "Notification ready" + browser := atspi.NewSnapshot("/browser", "Browser", "push button", "", "") + browser.ApplicationName = "Browser" + + xt := atspi.NewEvent(atspi.FocusedStateEvent, terminal) + xt.Detail1 = 1 + expectSpeech := func(want string) { + t.Helper() + select { + case got := <-speech.spoken: + if got != want { + t.Fatalf("speech = %q, want %q", got, want) + } + case <-time.After(time.Second): + t.Fatalf("timed out waiting for speech %q", want) + } + } + expectInterrupt := func() { + t.Helper() + select { + case <-speech.interrupt: + t.Fatal("passive XTerm focus interrupted Cthulhu speech") + default: + } + } + waitForGrabs := func(want []bool) { + t.Helper() + deadline := time.Now().Add(time.Second) + for { + if got := commands.grabs(); equalBools(got, want) { + return + } + if time.Now().After(deadline) { + t.Fatalf("command grabs = %v, want %v", commands.grabs(), want) + } + time.Sleep(time.Millisecond) + } + } + + adapter.events <- atspi.NewEvent(atspi.FocusEvent, home) + expectSpeech("Home, push button") + adapter.events <- xt + expectInterrupt() + waitForGrabs([]bool{false}) + + adapter.events <- atspi.NewEventWithPayload(atspi.TextInsertedEvent, terminal, "s") + time.Sleep(20 * time.Millisecond) + select { + case got := <-speech.spoken: + t.Fatalf("XTerm terminal event was presented as %q", got) + default: + } + + adapter.events <- atspi.NewEvent("window:create", notification) + expectSpeech("Notification Notification ready") + if !gate.Suspended() || !equalBools(commands.grabs(), []bool{false}) { + t.Fatal("notification restored XTerm keyboard handling") + } + if entries := history.Entries(); len(entries) != 1 || entries[0].Message != "Notification Notification ready" { + t.Fatalf("notification history = %+v", entries) + } + + adapter.events <- atspi.NewEvent(atspi.FocusEvent, browser) + expectSpeech("Browser, push button") + waitForGrabs([]bool{false, true}) + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func TestXTermFocusHonorsKnownApplication(t *testing.T) { + other := atspi.NewEvent(atspi.FocusedStateEvent, atspi.Snapshot{Role: "terminal", ApplicationName: "TestTerminal"}) + other.Detail1 = 1 + if isXTermFocus(other) { + t.Fatal("known non-XTerm terminal was classified as XTerm") + } + xterm := other + xterm.Source.ApplicationName = "xterm" + if !isXTermFocus(xterm) { + t.Fatal("XTerm application focus was not classified as XTerm") + } +} + +func TestXTermFocusDiscardsPendingSpeech(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 1), interrupt: make(chan struct{}, 1)} + adapter := &fakeAdapter{events: make(chan atspi.Event, 2)} + gate := newFocusGate(nil) + gate.speech = speech + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan struct{}) + go func() { + defer close(completed) + processEventsWithInput( + ctx, + slog.New(slog.DiscardHandler), + speech, + adapter, + nil, + nil, + time.Hour, + nil, + nil, + gate, + nil, + ) + }() + + entry := atspi.NewSnapshot("/entry", "Entry", "text", "", "Pending") + entry.Editable = true + terminal := atspi.NewSnapshot("/terminal", "XTerm", "terminal", "", "Prompt") + terminal.ApplicationName = "xterm" + + adapter.events <- atspi.NewEvent(atspi.CaretEvent, entry) + xt := atspi.NewEvent(atspi.FocusedStateEvent, terminal) + xt.Detail1 = 1 + adapter.events <- xt + + select { + case <-speech.interrupt: + t.Fatal("passive XTerm focus interrupted pending speech") + default: + } + time.Sleep(30 * time.Millisecond) + select { + case got := <-speech.spoken: + t.Fatalf("pending event was presented as %q", got) + default: + } + cancel() + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("event loop did not stop") + } +} + +func equalBools(left, right []bool) bool { + if len(left) != len(right) { + return false + } + for index, value := range left { + if value != right[index] { + return false + } + } + return true +} + +// Exercise the actual XRecord consumer, not only direct gate calls. Closing the +// input stream provides a deterministic barrier for all queued modifier events. +func TestDelegatedInputSuppressesInterruptAndEcho(t *testing.T) { + for _, suspended := range []bool{true, false} { + t.Run(map[bool]string{true: "delegated", false: "resumed"}[suspended], func(t *testing.T) { + speech := &fakeSpeechQueue{spoken: make(chan string, 16), interrupt: make(chan struct{}, 16)} + gate := newFocusGate(nil) + gate.SetSuspended(true) + if !suspended { + gate.SetSuspended(false) + } + listener := &fakeInputListener{events: make(chan input.Event, 4), modifierKeycodes: input.NewModifierKeycodes(37, 50)} + for _, code := range []uint8{37, 50} { + listener.events <- input.Event{Keycode: code, Pressed: true} + listener.events <- input.Event{Keycode: code, Pressed: false} + } + close(listener.events) + processInputEvents(context.Background(), slog.New(slog.DiscardHandler), gatedSpeech{speech, gate}, listener, input.EchoSettings{}, nil, nil) + want := 2 + if suspended { + want = 0 + } + if len(speech.interrupt) != want { + t.Fatalf("interrupts = %d, want %d", len(speech.interrupt), want) + } + gatedSpeech{speech, gate}.Enqueue(speechRequest{Text: "key echo"}) + if suspended && len(speech.spoken) != 0 { + t.Fatal("delegated echo reached speech") + } + }) + } +} diff --git a/internal/atspi/adapter.go b/internal/atspi/adapter.go new file mode 100644 index 0000000..90bbdef --- /dev/null +++ b/internal/atspi/adapter.go @@ -0,0 +1,443 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . +package atspi + +import ( + "context" + "errors" + "fmt" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "log/slog" + "runtime/cgo" + "sync" + "sync/atomic" + "unsafe" +) + +/* +#cgo pkg-config: atspi-2 gobject-2.0 +#include "adapter_native.h" +*/ +import "C" + +const eventQueueCapacity = 64 + +const ( + FocusEvent = "focus:" + FocusedStateEvent = "object:state-changed:focused" + WindowActivatedEvent = "window:activate" + WindowDeactivatedEvent = "window:deactivate" + WindowDestroyedEvent = "window:destroy" + WindowCreateEvent = "window:create" + CaretEvent = "object:text-caret-moved" + MouseButtonEvent = "mouse:button" + TextSelectionChangedEvent = "object:text-selection-changed" + TextInsertedEvent = "object:text-changed:insert" + TextDeletedEvent = "object:text-changed:delete" + ValueChangedEvent = "object:value-changed" + AccessibleValueEvent = "object:property-change:accessible-value" + AccessibleNameEvent = "object:property-change:accessible-name" + ActiveDescendantEvent = "object:active-descendant-changed" + SelectionChangedEvent = "object:selection-changed" + SelectedStateEvent = "object:state-changed:selected" + ChildrenChangedEvent = "object:children-changed" + ChildrenAddedEvent = "object:children-changed:add" + ChildrenRemovedEvent = "object:children-changed:remove" + DefunctStateEvent = "object:state-changed:defunct" + BoundsChangedEvent = "object:bounds-changed" + VisibleStateEvent = "object:state-changed:visible" + ShowingStateEvent = "object:state-changed:showing" + TextBoundsChangedEvent = "object:text-bounds-changed" + TextAttributesChangedEvent = "object:text-attributes-changed" + DocumentReloadEvent = "document:reload" + DocumentLoadCompleteEvent = "document:load-complete" + DocumentLoadStoppedEvent = "document:load-stopped" + BusyStateEvent = "object:state-changed:busy" +) + +var eventTypes = []string{ + FocusEvent, + FocusedStateEvent, + WindowActivatedEvent, + WindowDeactivatedEvent, + WindowDestroyedEvent, + WindowCreateEvent, + CaretEvent, + TextSelectionChangedEvent, + TextInsertedEvent, + TextDeletedEvent, + ValueChangedEvent, + AccessibleValueEvent, + AccessibleNameEvent, + ActiveDescendantEvent, + SelectionChangedEvent, + ChildrenChangedEvent, + DefunctStateEvent, + BoundsChangedEvent, + VisibleStateEvent, + ShowingStateEvent, + TextBoundsChangedEvent, + TextAttributesChangedEvent, + DocumentReloadEvent, + DocumentLoadCompleteEvent, + DocumentLoadStoppedEvent, + BusyStateEvent, + "object:state-changed:checked", + "object:state-changed:expanded", + "object:state-changed:indeterminate", + "object:state-changed:invalid-entry", + "object:state-changed:pressed", + "object:state-changed:read-only", + "object:state-changed:editable", + "object:state-changed:required", + SelectedStateEvent, + "object:state-changed:sensitive", + "object:state-changed:visited", + MouseButtonEvent, +} + +type Adapter struct { + captureLogger atomic.Pointer[slog.Logger] + libreOfficeHeaders libreOfficeHeaderStore // copied choices shared with the event loop + applicationProcesses map[string]string // GLib owner; bounded provider identity cache + webNotificationRoots map[ObjectID]bool // copied identities only; no native references + deferredLiveRegions deferredLiveRegionStore // GLib owner; copied identities only + foregroundReader *xorg.ForegroundReader // GLib thread only + foregroundProcesses map[int]bool // GLib thread; provider PID matches for current client + foreground atomic.Pointer[ForegroundState] + echoFocus atomic.Pointer[echoFocus] + eventListener *C.AtspiEventListener // GLib owner; released with subscriptions. + foregroundChanges chan struct{} + foregroundTitle atomic.Pointer[ForegroundTitle] + titleChanges chan struct{} + foregroundWindow ObjectID // GLib thread: correlated accessible for current X client + promptRefreshWindow ObjectID // GLib thread: frame activated before its prompt label appeared + promptScannedWindow ObjectID // GLib thread: avoid rescanning repeated activations + promptScannedEpoch uint64 + foregroundRecovery int // GLib thread: bounded retries while a new client publishes AT-SPI + recoveringForeground bool + + events chan Event + treeRequests chan treeCaptureRequest + overflow atomic.Uint64 + treeInvalidations atomic.Uint64 + backgroundEventsFiltered atomic.Uint64 // rejected before native target/snapshot queries + secureMutex sync.Mutex + secureContext context.Context + secureCancel context.CancelFunc + secureEpoch atomic.Uint64 + secure atomic.Bool + secureReset atomic.Bool + secureResync atomic.Bool + captureSound atomic.Bool + captureTextAttributes atomic.Bool + running atomic.Bool + ready atomic.Bool + loopDone chan struct{} + loopError error // published by closing loopDone + stopRequested bool // stopMutex; keep Stop retries from queuing stale quit sources + stopMutex sync.Mutex + treeMutex sync.Mutex + tree *AccessibleTree + documentTree *AccessibleTree + documentTextTree *AccessibleTree + nativeDocument map[ObjectID]*C.AtspiAccessible + documentLineCache map[ObjectID]DocumentCaretText // GLib owner; at most 64 bounded text objects + nativeReview map[ObjectID]*C.AtspiAccessible + nativeReviewBus string + navigationEcho map[ObjectID]uint8 + navigationCaretOffset int + navigationSelectionOffsets map[int]bool + nativeFocus []nativeFocusReference // owned only by the GLib thread + mouseApplication *C.AtspiAccessible // GLib owner; released on shutdown + mouseApplicationPID int + documentWindows map[ObjectID]nativeDocumentWindow + documentWindowIDs []ObjectID + selectedTabWindow ObjectID + activeDocument ObjectID + callbackHandle cgo.Handle + callbackData *C.cthulhu_callback_data +} + +type nativeFocusReference struct { + id ObjectID + source *C.AtspiAccessible + // Only programmatic browse positions carry this proof. A subsequent native + // focus event replaces the entry and clears it, even for the same object. + navigationDocument ObjectReference +} + +type nativeDocumentWindow struct { + id ObjectID + source *C.AtspiAccessible +} + +type treeCaptureResult struct { + soundGeometry [2]SoundGeometry + item TransferItem + actions ActionSet + point PointReview + ocr OCRGeometry + attributes CharacterAttributes + content DocumentContent + tree *AccessibleTree + owner DocumentContext + caret DocumentCaretText + err error +} + +type treeCaptureRequest struct { + soundObjects [2]ObjectReference + transferItem bool + listActions bool + actionTarget *ActionTarget + actionName string + pointReview bool + pointX, pointY int + pointPID int + ocrGeometry bool + ocrZone *Rectangle + readFocusedText bool + readFocusedLine bool + readAttributes bool + setFocusedCaret bool + brailleRoute *BrailleRoute + ctx context.Context + reviewFocus ObjectID + document bool + documentText bool + contextOnly bool + position ObjectReference + caretObject ObjectReference + caretOffset int + caretUnit DocumentCaretUnit + positionOffset int + usePositionOffset bool + activate bool + result chan treeCaptureResult +} + +// PointReview is copied metadata for the accessible at a screen point. +// Text ranges are optional and never include password contents. +type PointReview struct { + Snapshot Snapshot + Window ObjectID + Word, Line string + LineStart int + Offset int // native text offset at the pointer, or -1 +} + +func (adapter *Adapter) ReviewAtPoint(ctx context.Context, x, y, pid int) (PointReview, error) { + if ctx == nil { + return PointReview{}, errors.New("review pointer: nil context") + } + ctx, cancel := adapter.secureRequestContext(ctx) + defer cancel() + adapter.stopMutex.Lock() + defer adapter.stopMutex.Unlock() + if !adapter.ready.Load() || adapter.callbackData == nil { + return PointReview{}, errors.New("review pointer: adapter is not running") + } + request := treeCaptureRequest{ctx: ctx, pointReview: true, pointX: x, pointY: y, pointPID: pid, result: make(chan treeCaptureResult, 1)} + select { + case adapter.treeRequests <- request: + case <-ctx.Done(): + return PointReview{}, ctx.Err() + } + if C.cthulhu_request_tree_capture(C.gpointer(unsafe.Pointer(adapter.callbackData))) == 0 { + <-adapter.treeRequests + return PointReview{}, errors.New("schedule pointer review") + } + select { + case result := <-request.result: + return result.point, result.err + case <-ctx.Done(): + return PointReview{}, ctx.Err() + } +} + +func New() *Adapter { + adapter := &Adapter{ + events: make(chan Event, eventQueueCapacity), + foregroundChanges: make(chan struct{}, 1), + titleChanges: make(chan struct{}, 1), + treeRequests: make(chan treeCaptureRequest, 1), + } + // Direct adapter users historically receive geometry. The application + // narrows this before Start when object-sound spatialization is disabled. + adapter.captureSound.Store(true) + return adapter +} + +// SetCaptureSoundGeometry controls synchronous component and ancestor queries +// performed while copying event snapshots. It is safe to change while the +// adapter is running; the next callback observes the new setting. +func (adapter *Adapter) SetCaptureSoundGeometry(enabled bool) { + adapter.captureSound.Store(enabled) +} + +// SetCaptureTextAttributes enables bounded native run capture for braille. +// Disabled by default to avoid extra provider queries on ordinary focus events. +func (adapter *Adapter) SetCaptureTextAttributes(enabled bool) { + adapter.captureTextAttributes.Store(enabled) +} + +func (adapter *Adapter) Events() <-chan Event { + return adapter.events +} + +func (adapter *Adapter) Overflow() uint64 { + return adapter.overflow.Load() +} + +func (adapter *Adapter) TreeInvalidations() uint64 { + return adapter.treeInvalidations.Load() +} + +// CaptureDesktop copies the current AT-SPI desktop into the adapter's owned +// tree on the native event-loop thread. Calls are serialized with shutdown so +// callback data cannot be released while a capture is pending. +func (adapter *Adapter) CaptureDesktop(ctx context.Context) (*AccessibleTree, error) { + return adapter.capture(ctx, ObjectID{}, "desktop", false, false) +} + +// CaptureReviewWindow copies the focused application's tree into the owned +// model. Flat review needs only the focused frame or dialog, so excluding +// unrelated applications keeps capture bounded on busy desktops. +func (adapter *Adapter) CaptureReviewWindow(ctx context.Context, focus ObjectID) (*AccessibleTree, error) { + if !focus.Valid() { + return nil, errors.New("capture AT-SPI review window: invalid focus") + } + return adapter.capture(ctx, focus, "review window", false, false) +} + +// CaptureDocument captures semantics without flat review's viewport text work. +// Its independent tree cannot replace text required by an active flat cursor. +func (adapter *Adapter) CaptureDocument(ctx context.Context, focus ObjectID) (*AccessibleTree, error) { + if !focus.Valid() { + return nil, errors.New("capture AT-SPI document: invalid focus") + } + return adapter.capture(ctx, focus, "document", true, false) +} + +// CaptureDocumentText also captures visible text and range geometry. Line +// assembly needs those native details; structural navigation does not. +func (adapter *Adapter) CaptureDocumentText(ctx context.Context, focus ObjectID) (*AccessibleTree, error) { + if !focus.Valid() { + return nil, errors.New("capture AT-SPI document text: invalid focus") + } + return adapter.capture(ctx, focus, "document text", true, true) +} + +// SetCaptureLogger enables capture diagnostics when the logger accepts debug +// records. It can be updated without touching the GLib thread or native state. +func (adapter *Adapter) SetCaptureLogger(logger *slog.Logger) { + adapter.captureLogger.Store(logger) +} + +func (adapter *Adapter) capture(ctx context.Context, reviewFocus ObjectID, captureName string, document, documentText bool) (tree *AccessibleTree, err error) { + if ctx == nil { + return nil, fmt.Errorf("capture AT-SPI %s: nil context", captureName) + } + ctx, cancel := adapter.secureRequestContext(ctx) + defer cancel() + var trace *captureDiagnostics + if reviewFocus.Valid() { + ctx, trace = new_capture_diagnostics(ctx, adapter.captureLogger.Load(), reviewFocus) + if trace != nil && document { + trace.kind = "document" + } + defer func() { trace.finish(err) }() + } + if err := ctx.Err(); err != nil { + return nil, err + } + + adapter.stopMutex.Lock() + defer adapter.stopMutex.Unlock() + if !adapter.ready.Load() || adapter.callbackData == nil { + return nil, fmt.Errorf("capture AT-SPI %s: adapter is not running", captureName) + } + if err := ctx.Err(); err != nil { + return nil, err + } + + request := treeCaptureRequest{ + ctx: ctx, + reviewFocus: reviewFocus, + document: document, + documentText: documentText, + result: make(chan treeCaptureResult, 1), + } + trace.begin_stage("queue-wait", reviewFocus, "") + select { + case adapter.treeRequests <- request: + case <-ctx.Done(): + return nil, ctx.Err() + } + if C.cthulhu_request_tree_capture(C.gpointer(unsafe.Pointer(adapter.callbackData))) == 0 { + <-adapter.treeRequests + return nil, fmt.Errorf("schedule AT-SPI %s capture", captureName) + } + select { + case result := <-request.result: + return result.tree, result.err + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +func (adapter *Adapter) installTree(root ObjectID, nodes []TreeNode) (*AccessibleTree, error) { + return adapter.installCapturedTree(root, nodes, false, false) +} + +func (adapter *Adapter) installCapturedTree(root ObjectID, nodes []TreeNode, document, documentText bool) (*AccessibleTree, error) { + adapter.treeMutex.Lock() + defer adapter.treeMutex.Unlock() + owned := &adapter.tree + if documentText { + owned = &adapter.documentTextTree + } else if document { + owned = &adapter.documentTree + } + if *owned == nil { + tree, err := NewAccessibleTree(root, nodes) + if err != nil { + return nil, err + } + *owned = tree + return tree, nil + } + if err := (*owned).Replace(root, nodes); err != nil { + return nil, err + } + return *owned, nil +} + +func (adapter *Adapter) invalidateTree() { + adapter.treeMutex.Lock() + defer adapter.treeMutex.Unlock() + for _, tree := range []*AccessibleTree{adapter.tree, adapter.documentTree, adapter.documentTextTree} { + if tree == nil { + continue + } + root, err := tree.Root() + if err == nil { + adapter.treeInvalidations.Add(uint64(tree.Invalidate(root.ID()))) + } + } +} diff --git a/internal/atspi/adapter_actions_native.go b/internal/atspi/adapter_actions_native.go new file mode 100644 index 0000000..adff6f9 --- /dev/null +++ b/internal/atspi/adapter_actions_native.go @@ -0,0 +1,161 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "errors" +) + +type AccessibleAction struct{ Name, Label string } +type ActionTarget struct { + Object, Window, Focus ObjectID + Epoch uint64 + Role string +} +type ActionSet struct { + Target ActionTarget + Actions []AccessibleAction +} + +func (adapter *Adapter) AccessibleActions(ctx context.Context, object ObjectID) (ActionSet, error) { + result, err := adapter.documentOperation(ctx, treeCaptureRequest{listActions: true, reviewFocus: object}) + return result.actions, err +} +func (adapter *Adapter) PerformAccessibleAction(ctx context.Context, target ActionTarget, name string) error { + _, err := adapter.documentOperation(ctx, treeCaptureRequest{actionTarget: &target, actionName: name}) + return err +} + +// Native action work stays on the GLib owner, using retained review/document +// handles as well as focus. Never redirect a stale action to a new focus. +func (adapter *Adapter) native_action_source(object ObjectID) (*C.AtspiAccessible, ActionTarget, error) { + var source *C.AtspiAccessible + for _, item := range adapter.nativeFocus { + if item.id == object { + source = item.source + break + } + } + if source == nil { + source = adapter.nativeReview[object] + } + if source == nil { + source = adapter.nativeDocument[object] + } + if source == nil { + return nil, ActionTarget{}, ErrObjectNotFound + } + C.atspi_accessible_clear_cache_single(source) + states := C.atspi_accessible_get_state_set(source) + if states == nil { + return nil, ActionTarget{}, ErrStaleObject + } + defunct := C.atspi_state_set_contains(states, C.ATSPI_STATE_DEFUNCT) != 0 + C.g_object_unref(C.gpointer(states)) + if defunct { + return nil, ActionTarget{}, ErrStaleObject + } + window := C.cthulhu_window_ancestor(source) + if window == nil { + return nil, ActionTarget{}, ErrStaleObject + } + defer C.g_object_unref(C.gpointer(window)) + adapter.refreshForeground() + windowID := nativeObjectID(window) + if !adapter.matchesForeground(window, windowID) { + return nil, ActionTarget{}, ErrStaleObject + } + role := C.atspi_accessible_get_role_name(source, nil) + defer C.g_free(C.gpointer(role)) + target := ActionTarget{Object: object, Window: windowID, Epoch: adapter.Foreground().Epoch, Role: C.GoString(role)} + if len(adapter.nativeFocus) != 0 { + target.Focus = adapter.nativeFocus[len(adapter.nativeFocus)-1].id + } + return source, target, nil +} + +func (adapter *Adapter) native_actions(ctx context.Context, object ObjectID, expected *ActionTarget, name string) (ActionSet, error) { + if err := ctx.Err(); err != nil { + return ActionSet{}, err + } + source, target, err := adapter.native_action_source(object) + if err != nil { + return ActionSet{}, err + } + if expected != nil && target != *expected { + return ActionSet{}, ErrStaleObject + } + action := C.atspi_accessible_get_action_iface(source) + if action == nil { + return ActionSet{Target: target}, nil + } + defer C.g_object_unref(C.gpointer(action)) + var nativeErr *C.GError + count := int(C.atspi_action_get_n_actions(action, &nativeErr)) + if nativeErr != nil { + C.g_error_free(nativeErr) + return ActionSet{}, errors.New("could not read accessible actions") + } + if count < 0 || count > 256 { + return ActionSet{}, errors.New("invalid accessible action count") + } + result := ActionSet{Target: target} + seen := map[string]bool{} + for index := 0; index < count; index++ { + if err := ctx.Err(); err != nil { + return ActionSet{}, err + } + rawName := C.atspi_action_get_name(action, C.gint(index), nil) + actionName := sanitizeSnapshotField(C.GoString(rawName)) + C.g_free(C.gpointer(rawName)) + if actionName == "" || seen[actionName] { + continue + } + seen[actionName] = true + if expected != nil && actionName == name { + if adapter.secure.Load() || ctx.Err() != nil { + return ActionSet{}, ErrStaleObject + } + // Recheck ownership immediately before the external side effect. + _, current, checkErr := adapter.native_action_source(object) + if checkErr != nil || current != target { + return ActionSet{}, ErrStaleObject + } + if C.atspi_action_do_action(action, C.gint(index), &nativeErr) == 0 { + if nativeErr != nil { + C.g_error_free(nativeErr) + } + return ActionSet{}, errors.New("accessible action failed") + } + if nativeErr != nil { + C.g_error_free(nativeErr) + return ActionSet{}, errors.New("accessible action failed") + } + return result, nil + } + labelRaw := C.atspi_action_get_localized_name(action, C.gint(index), nil) + label := sanitizeSnapshotField(C.GoString(labelRaw)) + C.g_free(C.gpointer(labelRaw)) + if label == "" { + description := C.atspi_action_get_description(action, C.gint(index), nil) + label = sanitizeSnapshotField(C.GoString(description)) + C.g_free(C.gpointer(description)) + } + if label == "" { + label = actionName + } + result.Actions = append(result.Actions, AccessibleAction{Name: actionName, Label: label}) + } + if expected != nil { + return ActionSet{}, ErrStaleObject + } + return result, nil +} diff --git a/internal/atspi/adapter_capture.c b/internal/atspi/adapter_capture.c new file mode 100644 index 0000000..1188024 --- /dev/null +++ b/internal/atspi/adapter_capture.c @@ -0,0 +1,980 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "adapter_native.h" + +static gchar *cthulhu_capture_text(AtspiAccessible *source, gchar **beforeCaret, gint *startOffset); +static void cthulhu_capture_document_metrics(AtspiAccessible *source, cthulhu_snapshot *snapshot); +static gchar *cthulhu_table_cell_label(AtspiAccessible *source, guint depth, guint *remaining); + +// Some toolkits expose an edit field's label only as a relation, leaving its +// accessible name empty. Follow direct targets only, with a shared query and +// output budget; never infer a label from neighbouring controls or field text. +static gchar *cthulhu_text_control_label(AtspiAccessible *source) { + GArray *relations = atspi_accessible_get_relation_set(source, NULL); + if (relations == NULL) return NULL; + GString *label = g_string_new(""); + guint remaining = 16; + for (guint i = 0; i < MIN(relations->len, 32) && remaining > 0 && label->len < 4096; i++) { + AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i); + if (atspi_relation_get_relation_type(relation) != ATSPI_RELATION_LABELLED_BY) continue; + gint count = atspi_relation_get_n_targets(relation); + for (gint j = 0; j < count && remaining > 0 && label->len < 4096; j++) { + remaining--; + AtspiAccessible *target = atspi_relation_get_target(relation, j); + if (target == NULL) continue; + AtspiRole role = atspi_accessible_get_role(target, NULL); + gchar *text = NULL; + if (role != ATSPI_ROLE_PASSWORD_TEXT) { + text = atspi_accessible_get_name(target, NULL); + if ((text == NULL || *text == '\0') && + (role == ATSPI_ROLE_LABEL || role == ATSPI_ROLE_STATIC)) { + g_free(text); + AtspiText *labelText = atspi_accessible_get_text(target); + if (labelText != NULL) { + gint characterCount = atspi_text_get_character_count(labelText, NULL); + text = characterCount > 0 ? atspi_text_get_text(labelText, 0, MIN(characterCount, 1024), NULL) : NULL; + g_object_unref(labelText); + } else { + text = NULL; + } + } + } + if (text != NULL && *g_strstrip(text) != '\0') { + if (label->len != 0) g_string_append_c(label, ' '); + const gchar *end = NULL; + g_utf8_validate(text, MIN(strlen(text), 4096 - label->len), &end); + g_string_append_len(label, text, end - text); + } + g_free(text); + g_object_unref(target); + } + } + for (guint i = 0; i < relations->len; i++) + g_object_unref(g_array_index(relations, AtspiRelation *, i)); + g_array_unref(relations); + return g_string_free(label, FALSE); +} + +// Collect only the selected row. Walking an entire table on every arrow key +// would block input in large application tables. +gchar *cthulhu_table_context(AtspiAccessible *source, gint *rows, gint *columns, + gchar **tableName, gchar **tablePath, + gint *rowIndex, gint *columnIndex, gboolean *guiTable) { + AtspiAccessible *tableAccessible = NULL; + gint row = -1; + gint column = -1; + if (atspi_accessible_get_role(source, NULL) == ATSPI_ROLE_TABLE) { + tableAccessible = g_object_ref(source); + } else if (atspi_accessible_get_role(source, NULL) == ATSPI_ROLE_TABLE_CELL) { + AtspiTableCell *cell = atspi_accessible_get_table_cell(source); + if (cell != NULL) { + tableAccessible = atspi_table_cell_get_table(cell, NULL); + atspi_table_cell_get_position(cell, &row, &column, NULL); + g_object_unref(cell); + } + if (tableAccessible == NULL) { + AtspiAccessible *parent = atspi_accessible_get_parent(source, NULL); + if (parent != NULL && (atspi_accessible_get_role(parent, NULL) == ATSPI_ROLE_TABLE || + cthulhu_is_gtk_list_table(parent))) { + tableAccessible = parent; + gint index = atspi_accessible_get_index_in_parent(source, NULL); + AtspiTable *parentTable = atspi_accessible_get_table_iface(parent); + if (parentTable != NULL) { + row = atspi_table_get_row_at_index(parentTable, index, NULL); + column = atspi_table_get_column_at_index(parentTable, index, NULL); + g_object_unref(parentTable); + } + } else if (parent != NULL) { + g_object_unref(parent); + } + } + } + if (tableAccessible == NULL) return NULL; + *guiTable = TRUE; + AtspiAccessible *ancestor = g_object_ref(tableAccessible); + for (gint depth = 0; depth < 16 && ancestor != NULL; depth++) { + AtspiRole role = atspi_accessible_get_role(ancestor, NULL); + if (role == ATSPI_ROLE_DOCUMENT_WEB || role == ATSPI_ROLE_DOCUMENT_FRAME || + role == ATSPI_ROLE_DOCUMENT_TEXT || role == ATSPI_ROLE_DOCUMENT_SPREADSHEET) { + *guiTable = FALSE; + g_object_unref(ancestor); + ancestor = NULL; + break; + } + AtspiAccessible *parent = atspi_accessible_get_parent(ancestor, NULL); + g_object_unref(ancestor); + ancestor = parent; + } + if (ancestor != NULL) g_object_unref(ancestor); + AtspiTable *table = atspi_accessible_get_table_iface(tableAccessible); + if (table == NULL) { + g_object_unref(tableAccessible); + return NULL; + } + *rows = atspi_table_get_n_rows(table, NULL); + *columns = atspi_table_get_n_columns(table, NULL); + *tableName = atspi_accessible_get_name(tableAccessible, NULL); + *tablePath = g_strdup(cthulhu_accessible_path(tableAccessible)); + *rowIndex = row; + *columnIndex = column; + GString *result = g_string_new(NULL); + if (row >= 0 && row < *rows && *columns > 0 && *columns <= 32) { + guint remaining = 32; + for (gint column = 0; column < *columns; column++) { + AtspiAccessible *item = atspi_table_get_accessible_at(table, row, column, NULL); + if (item == NULL) continue; + gchar *name = atspi_accessible_get_name(item, NULL); + if ((name == NULL || *name == '\0') && remaining != 0 && + atspi_accessible_get_role(item, NULL) == ATSPI_ROLE_TABLE_CELL) { + g_free(name); + name = cthulhu_table_cell_label(item, 0, &remaining); + } + if (name != NULL && *name != '\0' && result->len + strlen(name) < 4096) { + if (result->len > 0) g_string_append(result, ", "); + g_string_append(result, name); + } + g_free(name); + g_object_unref(item); + } + } + g_object_unref(table); + g_object_unref(tableAccessible); + return g_string_free(result, FALSE); +} + +static gboolean cthulhu_capture_sound_rect(AtspiAccessible *source, gint *x, gint *y, + gint *width, gint *height) { + AtspiStateSet *states = atspi_accessible_get_state_set(source); + if (states == NULL) return FALSE; + gboolean available = atspi_state_set_contains(states, ATSPI_STATE_VISIBLE) && + atspi_state_set_contains(states, ATSPI_STATE_SHOWING); + g_object_unref(states); + if (!available) return FALSE; + AtspiComponent *component = atspi_accessible_get_component_iface(source); + if (component == NULL) return FALSE; + GError *error = NULL; + AtspiRect *rect = atspi_component_get_extents(component, ATSPI_COORD_TYPE_SCREEN, &error); + g_object_unref(component); + if (error != NULL) { + g_clear_error(&error); + if (rect != NULL) g_free(rect); + return FALSE; + } + if (rect == NULL || rect->width <= 0 || rect->height <= 0 || + rect->x == G_MININT || rect->y == G_MININT) { + if (rect != NULL) g_free(rect); + return FALSE; + } + *x = rect->x; + *y = rect->y; + *width = rect->width; + *height = rect->height; + g_free(rect); + return TRUE; +} + +void cthulhu_capture_sound_geometry(AtspiAccessible *source, cthulhu_snapshot *snapshot) { + snapshot->objectGeometryKnown = cthulhu_capture_sound_rect( + source, &snapshot->objectX, &snapshot->objectY, + &snapshot->objectWidth, &snapshot->objectHeight); + if (!snapshot->objectGeometryKnown) return; + + AtspiAccessible *current = g_object_ref(source); + for (gint depth = 0; current != NULL && depth < 256; depth++) { + GError *error = NULL; + AtspiRole role = atspi_accessible_get_role(current, &error); + if (error != NULL) { + g_clear_error(&error); + g_object_unref(current); + return; + } + if (role == ATSPI_ROLE_DIALOG || role == ATSPI_ROLE_FRAME || role == ATSPI_ROLE_WINDOW) { + snapshot->referenceGeometryKnown = cthulhu_capture_sound_rect( + current, &snapshot->referenceX, &snapshot->referenceY, + &snapshot->referenceWidth, &snapshot->referenceHeight); + g_object_unref(current); + return; + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, &error); + g_object_unref(current); + if (error != NULL) { + g_clear_error(&error); + if (parent != NULL) g_object_unref(parent); + return; + } + current = parent; + } + if (current != NULL) g_object_unref(current); +} + +static void cthulhu_capture_value(AtspiAccessible *source, cthulhu_snapshot *snapshot) { + GError *error = NULL; + AtspiRole role = atspi_accessible_get_role(source, &error); + if (error != NULL) { + g_error_free(error); + return; + } + switch (role) { + case ATSPI_ROLE_COMBO_BOX: { + // Many applications expose the selected item only through Selection. + // Prefer an already supplied description so well-behaved controls do + // not pay another synchronous AT-SPI round trip on every focus event. + if (snapshot->description != NULL && *snapshot->description != '\0') { + return; + } + AtspiSelection *selection = atspi_accessible_get_selection_iface(source); + if (selection == NULL) return; + AtspiAccessible *selected = atspi_selection_get_selected_child(selection, 0, &error); + g_object_unref(selection); + if (error != NULL) { + g_clear_error(&error); + if (selected != NULL) g_object_unref(selected); + return; + } + if (selected == NULL) return; + snapshot->valueText = atspi_accessible_get_name(selected, &error); + g_object_unref(selected); + if (error != NULL) { + g_clear_error(&error); + snapshot->valueText = NULL; + } + return; + } + case ATSPI_ROLE_DIAL: + case ATSPI_ROLE_PROGRESS_BAR: + case ATSPI_ROLE_SCROLL_BAR: + case ATSPI_ROLE_SLIDER: + break; + case ATSPI_ROLE_SPIN_BUTTON: + if (snapshot->text != NULL && *snapshot->text != '\0') { + return; + } + break; + case ATSPI_ROLE_SPLIT_PANE: + break; + default: + return; + } + + AtspiValue *value = atspi_accessible_get_value_iface(source); + if (value == NULL) { + return; + } + + error = NULL; + snapshot->valueText = atspi_value_get_text(value, &error); + if (error != NULL) { + g_error_free(error); + error = NULL; + } + + snapshot->currentValue = atspi_value_get_current_value(value, &error); + if (error != NULL) { + g_error_free(error); + error = NULL; + g_object_unref(value); + return; + } + snapshot->minimumValue = atspi_value_get_minimum_value(value, &error); + if (error != NULL) { + g_error_free(error); + error = NULL; + g_object_unref(value); + return; + } + snapshot->maximumValue = atspi_value_get_maximum_value(value, &error); + if (error == NULL) { + snapshot->valueKnown = TRUE; + } else { + g_clear_error(&error); + } + snapshot->minimumIncrement = atspi_value_get_minimum_increment(value, &error); + if (error != NULL) { + g_clear_error(&error); + snapshot->minimumIncrement = (snapshot->maximumValue - snapshot->minimumValue) / 100.0; + } + g_object_unref(value); +} + +// GTK tree rows can be unnamed while their renderer cells hold the visible +// label (including file names in Thunar's details view). Bound the lookup so +// a large or broken table cannot stall the event callback. +static gchar *cthulhu_table_cell_label(AtspiAccessible *source, guint depth, guint *remaining) { + if (source == NULL || *remaining == 0) return NULL; + (*remaining)--; + if (depth != 0) { + GError *error = NULL; + gchar *name = atspi_accessible_get_name(source, &error); + if (error != NULL) g_clear_error(&error); + if (name != NULL && *g_strstrip(name) != '\0') return name; + g_free(name); + } + if (depth >= 2) return NULL; + GError *error = NULL; + gint count = atspi_accessible_get_child_count(source, &error); + if (error != NULL) { + g_clear_error(&error); + return NULL; + } + for (gint index = 0; index < count && index < 12 && *remaining != 0; index++) { + AtspiAccessible *child = atspi_accessible_get_child_at_index(source, index, &error); + if (error != NULL) { + g_clear_error(&error); + continue; + } + if (child == NULL) continue; + gchar *name = cthulhu_table_cell_label(child, depth + 1, remaining); + g_object_unref(child); + if (name != NULL) return name; + } + return NULL; +} + +// Document cells can contain several text/link children. Collect their labels +// within a fixed budget, rather than the GUI row helper's first-label shortcut. +static gchar *cthulhu_document_cell_label(AtspiAccessible *source, guint depth, guint *remaining) { + if (!source || !*remaining || depth > 8) return NULL; + (*remaining)--; + gchar *name = atspi_accessible_get_name(source, NULL); + if (name && *g_strstrip(name)) return name; + g_free(name); + GString *text = g_string_new(NULL); + gint count = atspi_accessible_get_child_count(source, NULL); + for (gint i = 0; i < count && *remaining; i++) { + AtspiAccessible *child = atspi_accessible_get_child_at_index(source, i, NULL); + if (!child) continue; + gchar *label = cthulhu_document_cell_label(child, depth + 1, remaining); + g_object_unref(child); + if (label && *label) { + if (text->len) g_string_append_c(text, ' '); + g_string_append(text, label); + } + g_free(label); + } + return g_string_free(text, FALSE); +} + +// Header arrays own their accessible references. Copy labels before release. +static gchar *cthulhu_table_headers(GPtrArray *headers) { + if (!headers) return NULL; + GString *text = g_string_new(NULL); + guint remaining = 32; + for (guint i = 0; i < headers->len && remaining; i++) { + gchar *label = cthulhu_document_cell_label(g_ptr_array_index(headers, i), 0, &remaining); + if (label && *label) { + if (text->len) g_string_append(text, ", "); + g_string_append(text, label); + } + g_free(label); + } + g_ptr_array_unref(headers); + return g_string_free(text, FALSE); +} + +cthulhu_snapshot cthulhu_capture_snapshot(AtspiAccessible *source, gboolean captureText, + gboolean captureCaretCharacter, + gboolean captureDocumentMetadata, + gboolean captureSoundGeometry, + gboolean captureApplicationName) { + cthulhu_snapshot snapshot = {0}; + if (source == NULL) { + return snapshot; + } + snapshot.path = ATSPI_OBJECT(source)->path; + if (ATSPI_OBJECT(source)->app != NULL) { + snapshot.busName = ATSPI_OBJECT(source)->app->bus_name; + if (captureApplicationName) { + GError *applicationError = NULL; + AtspiAccessible *application = atspi_accessible_get_application(source, &applicationError); + if (applicationError != NULL) { + g_clear_error(&applicationError); + } + if (application != NULL) { + snapshot.applicationName = atspi_accessible_get_name(application, &applicationError); + if (applicationError != NULL) { + g_clear_error(&applicationError); + } + g_object_unref(application); + } + } + } + AtspiStateSet *states = atspi_accessible_get_state_set(source); + if (states != NULL) { + snapshot.statesKnown = TRUE; + snapshot.visible = atspi_state_set_contains(states, ATSPI_STATE_VISIBLE); + snapshot.showing = atspi_state_set_contains(states, ATSPI_STATE_SHOWING); + snapshot.active = atspi_state_set_contains(states, ATSPI_STATE_ACTIVE); + snapshot.autocomplete = atspi_state_set_contains(states, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION) && atspi_state_set_contains(states, ATSPI_STATE_SINGLE_LINE); + snapshot.focusable = atspi_state_set_contains(states, ATSPI_STATE_FOCUSABLE); + snapshot.focused = atspi_state_set_contains(states, ATSPI_STATE_FOCUSED); + snapshot.hasPopup = atspi_state_set_contains(states, ATSPI_STATE_HAS_POPUP); + snapshot.sensitiveKnown = TRUE; + snapshot.checkable = atspi_state_set_contains(states, ATSPI_STATE_CHECKABLE); + snapshot.checked = atspi_state_set_contains(states, ATSPI_STATE_CHECKED) || atspi_state_set_contains(states, ATSPI_STATE_PRESSED); + snapshot.defunct = atspi_state_set_contains(states, ATSPI_STATE_DEFUNCT); + snapshot.editable = atspi_state_set_contains(states, ATSPI_STATE_EDITABLE); + snapshot.expandable = atspi_state_set_contains(states, ATSPI_STATE_EXPANDABLE) || atspi_state_set_contains(states, ATSPI_STATE_EXPANDED); + snapshot.expanded = atspi_state_set_contains(states, ATSPI_STATE_EXPANDED); + snapshot.indeterminate = atspi_state_set_contains(states, ATSPI_STATE_INDETERMINATE); + snapshot.invalid = atspi_state_set_contains(states, ATSPI_STATE_INVALID_ENTRY) || atspi_state_set_contains(states, ATSPI_STATE_INVALID); + snapshot.multiselectable = atspi_state_set_contains(states, ATSPI_STATE_MULTISELECTABLE); + snapshot.readOnly = atspi_state_set_contains(states, ATSPI_STATE_READ_ONLY); + snapshot.required = atspi_state_set_contains(states, ATSPI_STATE_REQUIRED); + snapshot.selected = atspi_state_set_contains(states, ATSPI_STATE_SELECTED); + snapshot.sensitive = atspi_state_set_contains(states, ATSPI_STATE_SENSITIVE); + snapshot.visited = atspi_state_set_contains(states, ATSPI_STATE_VISITED); + g_object_unref(states); + } + GError *error = NULL; + snapshot.name = atspi_accessible_get_name(source, &error); + if (error != NULL) { + g_error_free(error); + error = NULL; + } + snapshot.role = atspi_accessible_get_role_name(source, &error); + if (error != NULL) { + g_error_free(error); + error = NULL; + } + if (!snapshot.defunct && (snapshot.name == NULL || *snapshot.name == '\0') && + (g_strcmp0(snapshot.role, "text") == 0 || g_strcmp0(snapshot.role, "entry") == 0 || + g_strcmp0(snapshot.role, "password text") == 0)) { + g_free(snapshot.name); + snapshot.name = cthulhu_text_control_label(source); + } + cthulhu_capture_menu_checkability(source, &snapshot); + if (!snapshot.defunct && (g_strcmp0(snapshot.role, "list") == 0 || + g_strcmp0(snapshot.role, "list box") == 0)) { + snapshot.childCount = atspi_accessible_get_child_count(source, &error); + snapshot.childCountKnown = error == NULL && snapshot.childCount >= 0; + g_clear_error(&error); + } + if (!snapshot.defunct && !captureDocumentMetadata && g_strcmp0(snapshot.role, "table cell") == 0 && + (snapshot.name == NULL || *snapshot.name == '\0')) { + guint remaining = 20; + gchar *label = cthulhu_table_cell_label(source, 0, &remaining); + if (label != NULL) { + g_free(snapshot.name); + snapshot.name = label; + } + } + snapshot.description = atspi_accessible_get_description(source, &error); + if (error != NULL) { + g_error_free(error); + } + if (captureDocumentMetadata) { + cthulhu_capture_document_metrics(source, &snapshot); + } + if (captureSoundGeometry) { + cthulhu_capture_sound_geometry(source, &snapshot); + } + // Copy only semantic attribute fields used by navigation; arbitrary + // browser attributes can include URLs and unrelated document data. + error = NULL; + GHashTable *attributes = NULL; + gboolean captureSetPosition = !snapshot.defunct && cthulhu_has_set_position(snapshot.role); + if (captureDocumentMetadata || g_strcmp0(snapshot.role, "heading") == 0 || captureSetPosition) { + attributes = atspi_accessible_get_attributes(source, &error); + } + if (error != NULL) { + g_clear_error(&error); + } + if (captureSetPosition) cthulhu_capture_set_position(source, attributes, &snapshot); + if (attributes != NULL) { + if (captureDocumentMetadata) { + snapshot.explicitName = g_strcmp0(g_hash_table_lookup(attributes, "explicit-name"), "true") == 0; + const gchar *xmlRoles = g_hash_table_lookup(attributes, "xml-roles"); + if (xmlRoles != NULL) { + snapshot.xmlRoles = g_strdup(xmlRoles); + } + const gchar *htmlTag = g_hash_table_lookup(attributes, "tag"); + if (htmlTag != NULL) snapshot.htmlTag = g_strdup(htmlTag); + const gchar *elementID = g_hash_table_lookup(attributes, "id"); + if (elementID != NULL) { + snapshot.elementID = g_strdup(elementID); + } + const gchar *containerLive = g_hash_table_lookup(attributes, "container-live"); + if (containerLive != NULL && (g_strcmp0(containerLive, "off") == 0 || + g_strcmp0(containerLive, "polite") == 0 || + g_strcmp0(containerLive, "assertive") == 0)) { + snapshot.liveRegion = TRUE; + } + const gchar *layoutGuess = g_hash_table_lookup(attributes, "layout-guess"); + if (g_strcmp0(layoutGuess, "true") == 0) { + snapshot.layoutTable = TRUE; + } + } + if (g_strcmp0(snapshot.role, "heading") == 0) { + const gchar *level = g_hash_table_lookup(attributes, "level"); + if (level != NULL && *level >= '1' && *level <= '9') { + gchar *end = NULL; + gint64 number = g_ascii_strtoll(level, &end, 10); + if (end != NULL && *end == '\0' && number <= G_MAXINT) { + snapshot.headingLevel = (gint)number; + } + } + } + if (attributes != NULL) g_hash_table_unref(attributes); + } + if (captureDocumentMetadata && (g_strcmp0(snapshot.role, "table") == 0 || g_strcmp0(snapshot.role, "tree table") == 0)) { + AtspiTable *table = atspi_accessible_get_table_iface(source); + if (table != NULL) { + error = NULL; + snapshot.tableRowCount = atspi_table_get_n_rows(table, &error); + if (error != NULL) { + g_clear_error(&error); + } + snapshot.tableColumnCount = atspi_table_get_n_columns(table, NULL); + g_object_unref(table); + } + } + if (captureDocumentMetadata && (g_strcmp0(snapshot.role, "table cell") == 0 || + g_strcmp0(snapshot.role, "column header") == 0 || g_strcmp0(snapshot.role, "row header") == 0)) { + if (!snapshot.name || !*snapshot.name) { + guint remaining = 64; + gchar *label = cthulhu_document_cell_label(source, 0, &remaining); + g_free(snapshot.name); + snapshot.name = label; + } + AtspiTableCell *cell = atspi_accessible_get_table_cell(source); + if (cell) { + error = NULL; + snapshot.tableRowIndex = snapshot.tableColumnIndex = -1; + atspi_table_cell_get_row_column_span(cell, &snapshot.tableRowIndex, &snapshot.tableColumnIndex, + &snapshot.tableRowSpan, &snapshot.tableColumnSpan, &error); + snapshot.tablePositionKnown = !error && snapshot.tableRowIndex >= 0 && snapshot.tableColumnIndex >= 0 && + snapshot.tableRowSpan > 0 && snapshot.tableColumnSpan > 0; + g_clear_error(&error); + snapshot.tableRowHeaders = cthulhu_table_headers(atspi_table_cell_get_row_header_cells(cell, NULL)); + snapshot.tableColumnHeaders = cthulhu_table_headers(atspi_table_cell_get_column_header_cells(cell, NULL)); + g_object_unref(cell); + } + } + AtspiAction *action = captureDocumentMetadata ? atspi_accessible_get_action_iface(source) : NULL; + if (action != NULL) { + error = NULL; + gint actionCount = atspi_action_get_n_actions(action, &error); + if (error != NULL) { + g_clear_error(&error); + } + for (gint index = 0; index < actionCount; index++) { + error = NULL; + gchar *actionName = atspi_action_get_name(action, index, &error); + if (error != NULL) { + g_clear_error(&error); + } + // Web providers use different action names for activation. Keep + // this list aligned with activateNativeDocumentObject so browse + // Enter can reach objects exposing click-ancestor or press. + if (actionName != NULL && + (g_ascii_strcasecmp(actionName, "click") == 0 || + g_ascii_strcasecmp(actionName, "click-ancestor") == 0 || + g_ascii_strcasecmp(actionName, "press") == 0 || + g_ascii_strcasecmp(actionName, "jump") == 0 || + g_ascii_strcasecmp(actionName, "open") == 0 || + g_ascii_strcasecmp(actionName, "activate") == 0)) { + snapshot.supportsClick = TRUE; + g_free(actionName); + break; + } + g_free(actionName); + } + g_object_unref(action); + } + // Text and caret capture make synchronous AT-SPI calls. Focus events for + // ordinary controls do not use that text in presentation, so avoid stalling + // the GLib event loop for each Tab stop. Focusable text controls include + // read-only entries: their current line is still part of focus speech. + // Caret events also need text when they originate in static web content. + gboolean focusableText = snapshot.focusable && + (g_strcmp0(snapshot.role, "text") == 0 || g_strcmp0(snapshot.role, "entry") == 0); + if (captureText && g_strcmp0(snapshot.role, "password text") != 0 && + (snapshot.editable || focusableText || g_strcmp0(snapshot.role, "terminal") == 0 || captureCaretCharacter)) { + snapshot.text = cthulhu_capture_text(source, &snapshot.textBeforeCaret, &snapshot.textStartOffset); + } + if (captureCaretCharacter && g_strcmp0(snapshot.role, "password text") != 0) { + snapshot.caretCharacter = cthulhu_capture_caret_unit(source, ATSPI_TEXT_GRANULARITY_CHAR); + } + cthulhu_capture_value(source, &snapshot); + return snapshot; +} + +static gchar *cthulhu_capture_text(AtspiAccessible *source, gchar **beforeCaret, gint *startOffset) { + *beforeCaret = NULL; + AtspiText *text = atspi_accessible_get_text(source); + if (text == NULL) { + return NULL; + } + GError *error = NULL; + gint caretOffset = atspi_text_get_caret_offset(text, &error); + if (error != NULL) { + g_error_free(error); + g_object_unref(text); + return NULL; + } + AtspiTextRange *range = cthulhu_text_get_string_at_offset( + text, caretOffset, ATSPI_TEXT_GRANULARITY_LINE, &error); + // AXText.get_line_at_offset retries Chromium's invalid end-of-text + // range. A valid empty range is a real blank line and must stay empty. + if (error == NULL && range != NULL && caretOffset > 0) { + gboolean retry = range->start_offset > caretOffset; + if (range->start_offset == -1 && range->end_offset == -1) { + gint count = atspi_text_get_character_count(text, &error); + retry = error == NULL && caretOffset == count; + } + if (retry) { + g_boxed_free(atspi_text_range_get_type(), range); + range = cthulhu_text_get_string_at_offset( + text, caretOffset - 1, ATSPI_TEXT_GRANULARITY_LINE, &error); + } + } + g_object_unref(text); + if (error != NULL) { + g_error_free(error); + if (range != NULL) g_boxed_free(atspi_text_range_get_type(), range); + return NULL; + } + if (range == NULL) { + return NULL; + } + gchar *content = g_strdup(range->content != NULL ? range->content : ""); + *startOffset = range->start_offset; + gint relativeCaret = caretOffset - range->start_offset; + glong characterCount = g_utf8_strlen(content, -1); + if (relativeCaret < 0) { + relativeCaret = 0; + } else if (relativeCaret > characterCount) { + relativeCaret = (gint)characterCount; + } + *beforeCaret = g_utf8_substring(content, 0, relativeCaret); + g_free(range->content); + g_free(range); + return content; +} + +static gchar *cthulhu_label_text(AtspiAccessible *source) { + AtspiText *text = atspi_accessible_get_text(source); + if (text != NULL) { + GError *error = NULL; + gint characterCount = atspi_text_get_character_count(text, &error); + if (error != NULL) { + g_clear_error(&error); + g_object_unref(text); + return NULL; + } + gchar *content = atspi_text_get_text(text, 0, characterCount, &error); + g_object_unref(text); + if (error != NULL) { + g_clear_error(&error); + return NULL; + } + return content != NULL ? content : g_strdup(""); + } + + GError *error = NULL; + gchar *name = atspi_accessible_get_name(source, &error); + if (error != NULL) g_error_free(error); + return name != NULL ? name : g_strdup(""); +} + +static void cthulhu_append_label_texts(AtspiAccessible *source, GString *contents, + int *visited) { + if (source == NULL || *visited >= 100 || contents->len >= 4096) return; + (*visited)++; + GError *error = NULL; + AtspiRole role = atspi_accessible_get_role(source, &error); + if (error != NULL) g_clear_error(&error); + if (role == ATSPI_ROLE_LABEL) { + gchar *text = cthulhu_label_text(source); + if (text != NULL && *text != '\0') { + if (contents->len != 0) g_string_append_c(contents, ' '); + g_string_append(contents, text); + } + g_free(text); + } + error = NULL; + gint childCount = atspi_accessible_get_child_count(source, &error); + if (error != NULL) { + g_clear_error(&error); + return; + } + for (gint index = 0; index < childCount && *visited < 100 && contents->len < 4096; index++) { + error = NULL; + AtspiAccessible *child = atspi_accessible_get_child_at_index(source, index, &error); + if (error != NULL) { + g_clear_error(&error); + continue; + } + cthulhu_append_label_texts(child, contents, visited); + if (child != NULL) g_object_unref(child); + } +} + +gchar *cthulhu_collect_notification_text(AtspiAccessible *source) { + if (source == NULL) return g_strdup(""); + GString *contents = g_string_new(""); + int visited = 0; + cthulhu_append_label_texts(source, contents, &visited); + return g_string_free(contents, FALSE); +} + +// YAD exposes prompts as labels beside buttons or a choice list. Keep the +// capture within that small shape; ordinary frames contain unrelated labels. +static gboolean cthulhu_append_prompt_labels(AtspiAccessible *source, GString *contents, + gint *visited, gint *buttons, gint *labels, gint *choices) { + if (source == NULL || *visited >= 100 || contents->len >= 4096) return FALSE; + (*visited)++; + GError *error = NULL; + AtspiRole role = atspi_accessible_get_role(source, &error); + if (error != NULL) { + g_clear_error(&error); + return FALSE; + } + if (role == ATSPI_ROLE_BUTTON) { + (*buttons)++; + return *buttons <= 4; + } + if (role == ATSPI_ROLE_LABEL || role == ATSPI_ROLE_STATIC) { + AtspiStateSet *states = atspi_accessible_get_state_set(source); + gboolean showing = states != NULL && atspi_state_set_contains(states, ATSPI_STATE_SHOWING); + if (states != NULL) g_object_unref(states); + if (!showing) return TRUE; + gchar *label = cthulhu_label_text(source); + if (label != NULL && *label != '\0') { + if (contents->len != 0) g_string_append_c(contents, ' '); + g_string_append(contents, label); + (*labels)++; + } + g_free(label); + return TRUE; + } + if (role == ATSPI_ROLE_ICON || role == ATSPI_ROLE_SCROLL_BAR) return TRUE; + if (role == ATSPI_ROLE_TREE_TABLE || role == ATSPI_ROLE_TREE || + role == ATSPI_ROLE_TABLE || role == ATSPI_ROLE_LIST) { + (*choices)++; + return *choices <= 1; + } + if (role != ATSPI_ROLE_FRAME && role != ATSPI_ROLE_DIALOG && + role != ATSPI_ROLE_FILLER && role != ATSPI_ROLE_PANEL && + role != ATSPI_ROLE_SCROLL_PANE) return FALSE; + gint childCount = atspi_accessible_get_child_count(source, &error); + if (error != NULL) { + g_clear_error(&error); + return FALSE; + } + for (gint index = 0; index < childCount; index++) { + AtspiAccessible *child = atspi_accessible_get_child_at_index(source, index, &error); + if (error != NULL || child == NULL) { + g_clear_error(&error); + if (child != NULL) g_object_unref(child); + return FALSE; + } + gboolean valid = cthulhu_append_prompt_labels(child, contents, visited, buttons, labels, choices); + g_object_unref(child); + if (!valid) return FALSE; + } + return TRUE; +} + +gchar *cthulhu_collect_simple_prompt_text(AtspiAccessible *source) { + if (source == NULL) return NULL; + GString *contents = g_string_new(""); + gint visited = 0, buttons = 0, labels = 0, choices = 0; + gboolean valid = cthulhu_append_prompt_labels(source, contents, &visited, &buttons, &labels, &choices); + if (!valid || labels == 0 || (buttons == 0 && choices == 0)) { + g_string_free(contents, TRUE); + return NULL; + } + return g_string_free(contents, FALSE); +} + +// Follow the same label/ancestor conventions used by GTK radio groups. A +// named panel or filler is the group's question, not the option's own name. +gchar *cthulhu_radio_group_name(AtspiAccessible *source) { + GArray *relations = atspi_accessible_get_relation_set(source, NULL); + if (relations != NULL) { + for (guint i = 0; i < relations->len; i++) { + AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i); + if (atspi_relation_get_relation_type(relation) == ATSPI_RELATION_LABELLED_BY && + atspi_relation_get_n_targets(relation) > 0) { + AtspiAccessible *label = atspi_relation_get_target(relation, 0); + gchar *name = label != NULL ? cthulhu_label_text(label) : NULL; + gchar *option = atspi_accessible_get_name(source, NULL); + gboolean ownLabel = g_strcmp0(name, option) == 0; + g_free(option); + if (label != NULL) g_object_unref(label); + for (guint j = 0; j < relations->len; j++) + g_object_unref(g_array_index(relations, AtspiRelation *, j)); + g_array_unref(relations); + if (name != NULL && *name != '\0' && !ownLabel) return name; + g_free(name); + relations = NULL; + break; + } + } + if (relations != NULL) { + for (guint i = 0; i < relations->len; i++) + g_object_unref(g_array_index(relations, AtspiRelation *, i)); + g_array_unref(relations); + } + } + AtspiAccessible *current = atspi_accessible_get_parent(source, NULL); + for (int depth = 0; current != NULL && depth < 16; depth++) { + AtspiRole role = atspi_accessible_get_role(current, NULL); + if (role == ATSPI_ROLE_FRAME || role == ATSPI_ROLE_DIALOG || role == ATSPI_ROLE_APPLICATION) { + g_object_unref(current); + return NULL; + } + if (role == ATSPI_ROLE_PANEL || role == ATSPI_ROLE_FILLER) { + gchar *name = atspi_accessible_get_name(current, NULL); + if (name != NULL && *name != '\0') { + g_object_unref(current); + return name; + } + g_free(name); + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, NULL); + g_object_unref(current); + current = parent; + } + if (current != NULL) g_object_unref(current); + return NULL; +} + +static void cthulhu_append_live_text(AtspiAccessible *source, GString *contents, int *visited) { + if (source == NULL || *visited >= 100 || contents->len >= 4096) return; + (*visited)++; + GError *error = NULL; + gint childCount = atspi_accessible_get_child_count(source, &error); + if (error != NULL) { + g_clear_error(&error); + childCount = 0; + } + guint before = contents->len; + for (gint index = 0; index < childCount && *visited < 100 && contents->len < 4096; index++) { + AtspiAccessible *child = atspi_accessible_get_child_at_index(source, index, &error); + if (error != NULL) g_clear_error(&error); + if (child != NULL) { + cthulhu_append_live_text(child, contents, visited); + g_object_unref(child); + } + } + if (contents->len == before) { + gchar *text = cthulhu_label_text(source); + if (text != NULL && *text != '\0') { + if (contents->len != 0) g_string_append_c(contents, ' '); + g_string_append(contents, text); + } + g_free(text); + } +} + +gchar *cthulhu_live_content(AtspiAccessible *source) { + GString *contents = g_string_new(""); + int visited = 0; + cthulhu_append_live_text(source, contents, &visited); + return g_string_free(contents, FALSE); +} + +gchar *cthulhu_capture_caret_unit(AtspiAccessible *source, AtspiTextGranularity unit) { + AtspiText *text = atspi_accessible_get_text(source); + if (text == NULL) { + return NULL; + } + GError *error = NULL; + gint caretOffset = atspi_text_get_caret_offset(text, &error); + if (error != NULL) { + g_error_free(error); + g_object_unref(text); + return NULL; + } + if (caretOffset < 0) { + g_object_unref(text); + return NULL; + } + AtspiTextRange *range = cthulhu_text_get_string_at_offset( + text, caretOffset, unit, &error); + g_object_unref(text); + if (error != NULL) { + g_error_free(error); + if (range != NULL) g_boxed_free(atspi_text_range_get_type(), range); + return NULL; + } + if (range == NULL) { + return NULL; + } + gchar *content = g_strdup(range->content != NULL ? range->content : ""); + g_free(range->content); + g_free(range); + return content; +} + +static void cthulhu_capture_document_metrics(AtspiAccessible *source, cthulhu_snapshot *snapshot) { + const gchar *role = snapshot->role; + /* Gecko can expose heading/link text directly without static children. */ + if (g_strcmp0(role, "paragraph") != 0 && + g_strcmp0(role, "heading") != 0 && + g_strcmp0(role, "link") != 0 && + g_strcmp0(role, "list item") != 0 && + g_strcmp0(role, "math") != 0 && + g_strcmp0(role, "static") != 0 && + g_strcmp0(role, "column header") != 0 && + g_strcmp0(role, "row header") != 0 && + g_strcmp0(role, "table cell") != 0 && + g_strcmp0(role, "table row") != 0 && + g_strcmp0(role, "text") != 0 && + g_strcmp0(role, "section") != 0 && + g_strcmp0(role, "article") != 0 && + g_strcmp0(role, "description term") != 0 && + g_strcmp0(role, "description value") != 0 && + g_strcmp0(role, "document email") != 0 && + g_strcmp0(role, "document frame") != 0 && + g_strcmp0(role, "document presentation") != 0 && + g_strcmp0(role, "document spreadsheet") != 0 && + g_strcmp0(role, "document text") != 0 && + g_strcmp0(role, "document web") != 0 && + g_strcmp0(role, "block quote") != 0 && + g_strcmp0(role, "description list") != 0 && + g_strcmp0(role, "form") != 0 && + g_strcmp0(role, "footer") != 0 && + g_strcmp0(role, "header") != 0 && + g_strcmp0(role, "landmark") != 0 && + g_strcmp0(role, "log") != 0 && + g_strcmp0(role, "list") != 0 && + g_strcmp0(role, "marquee") != 0 && + g_strcmp0(role, "panel") != 0 && + g_strcmp0(role, "table") != 0 && + g_strcmp0(role, "tree") != 0 && + g_strcmp0(role, "tree table") != 0) { + return; + } + AtspiText *text = atspi_accessible_get_text(source); + if (text == NULL) { + return; + } + GError *error = NULL; + gint characterCount = atspi_text_get_character_count(text, &error); + if (error != NULL) { + g_clear_error(&error); + g_object_unref(text); + return; + } + snapshot->characterCount = characterCount; + if (characterCount > 75) { + error = NULL; + gchar *contents = atspi_text_get_text(text, 0, characterCount, &error); + if (error != NULL) { + g_clear_error(&error); + } else if (contents != NULL) { + for (const gchar *cursor = contents; *cursor != '\0'; cursor = g_utf8_next_char(cursor)) { + if (g_utf8_get_char(cursor) == 0xFFFC) { + snapshot->embeddedObjectCount++; + } + } + g_free(contents); + } + } + g_object_unref(text); +} diff --git a/internal/atspi/adapter_document_native.go b/internal/atspi/adapter_document_native.go new file mode 100644 index 0000000..c26bc9c --- /dev/null +++ b/internal/atspi/adapter_document_native.go @@ -0,0 +1,662 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "errors" + "strings" + "unicode/utf8" + "unsafe" +) + +func (adapter *Adapter) nativeFocusIs(id ObjectID) bool { + return id.Valid() && len(adapter.nativeFocus) != 0 && adapter.nativeFocus[len(adapter.nativeFocus)-1].id == id +} + +// Native document handles are bounded by the capture's node limit. Only the +// GLib thread owns them; recapture and shutdown release every reference. +func (adapter *Adapter) clearNativeDocument() { + for _, source := range adapter.nativeDocument { + C.g_object_unref(C.gpointer(source)) + } + adapter.nativeDocument = nil + clear(adapter.documentLineCache) +} + +// Review handles belong to the GLib thread and are replaced atomically after +// each successful window capture. Keeping them permits dirty-node recapture. +func (adapter *Adapter) clearNativeReview() { + for _, source := range adapter.nativeReview { + C.g_object_unref(C.gpointer(source)) + } + adapter.nativeReview = nil + adapter.nativeReviewBus = "" +} + +func (adapter *Adapter) documentOperation(ctx context.Context, request treeCaptureRequest) (treeCaptureResult, error) { + ctx, cancel := adapter.secureRequestContext(ctx) + defer cancel() + if err := ctx.Err(); err != nil { + return treeCaptureResult{}, err + } + adapter.stopMutex.Lock() + defer adapter.stopMutex.Unlock() + if !adapter.ready.Load() || adapter.callbackData == nil { + return treeCaptureResult{}, errors.New("AT-SPI adapter is not running") + } + request.ctx, request.result = ctx, make(chan treeCaptureResult, 1) + select { + case adapter.treeRequests <- request: + case <-ctx.Done(): + return treeCaptureResult{}, ctx.Err() + } + if C.cthulhu_request_tree_capture(C.gpointer(unsafe.Pointer(adapter.callbackData))) == 0 { + <-adapter.treeRequests + return treeCaptureResult{}, errors.New("schedule document operation") + } + select { + case result := <-request.result: + return result, result.err + case <-ctx.Done(): + return treeCaptureResult{}, ctx.Err() + } +} + +func (adapter *Adapter) CaptureDocumentContext(ctx context.Context, focus ObjectID) (DocumentContext, error) { + result, err := adapter.documentOperation(ctx, treeCaptureRequest{reviewFocus: focus, contextOnly: true}) + return result.owner, err +} + +func (adapter *Adapter) SetDocumentPosition(ctx context.Context, position ObjectReference, focus ObjectID) error { + if !position.Valid() || !focus.Valid() { + return ErrStaleObject + } + _, err := adapter.documentOperation(ctx, treeCaptureRequest{position: position, reviewFocus: focus}) + return err +} + +// CaptureDocumentSoundGeometry refreshes only the presented object and its +// optional linked heading target, after navigation has scrolled them into view. +// It never changes the cached document semantics or retains new native handles. +func (adapter *Adapter) CaptureDocumentSoundGeometry(ctx context.Context, object, link ObjectReference) ([2]SoundGeometry, error) { + if !object.Valid() { + return [2]SoundGeometry{}, ErrStaleObject + } + if !adapter.captureSound.Load() { + return [2]SoundGeometry{}, nil + } + return retryDocumentSoundGeometry(ctx, link.Valid(), func(ctx context.Context) ([2]SoundGeometry, error) { + result, err := adapter.documentOperation(ctx, treeCaptureRequest{soundObjects: [2]ObjectReference{object, link}}) + return result.soundGeometry, err + }) +} + +func (adapter *Adapter) captureNativeDocumentSoundGeometry(ctx context.Context, objects [2]ObjectReference) ([2]SoundGeometry, error) { + var geometry [2]SoundGeometry + if !adapter.captureSound.Load() { + return geometry, nil + } + adapter.treeMutex.Lock() + tree := adapter.documentTree + adapter.treeMutex.Unlock() + if tree == nil { + return geometry, ErrStaleObject + } + for index, object := range objects { + if !object.Valid() { + continue + } + if err := ctx.Err(); err != nil { + return [2]SoundGeometry{}, err + } + if _, err := tree.Resolve(object); err != nil { + return [2]SoundGeometry{}, err + } + source := adapter.nativeDocument[object.ID()] + if source == nil { + return [2]SoundGeometry{}, ErrStaleObject + } + // SHOWING can still reflect the pre-scroll viewport in libatspi's cache. + C.atspi_accessible_clear_cache_single(source) + var captured C.cthulhu_snapshot + C.cthulhu_capture_sound_geometry(source, &captured) + geometry[index] = soundGeometryFromNative(captured) + } + if err := ctx.Err(); err != nil { + return [2]SoundGeometry{}, err + } + return geometry, nil +} + +// SetDocumentCaretPosition also places the browser caret at the virtual browse +// offset, so native Tab traversal starts from the announced location. +func (adapter *Adapter) SetDocumentCaretPosition(ctx context.Context, position ObjectReference, focus ObjectID, offset int) error { + if !position.Valid() || !focus.Valid() || offset < 0 { + return ErrStaleObject + } + _, err := adapter.documentOperation(ctx, treeCaptureRequest{position: position, reviewFocus: focus, positionOffset: offset, usePositionOffset: true}) + return err +} + +func (adapter *Adapter) ActivateDocumentObject(ctx context.Context, position ObjectReference, focus ObjectID) error { + if !position.Valid() || !focus.Valid() { + return ErrStaleObject + } + _, err := adapter.documentOperation(ctx, treeCaptureRequest{position: position, reviewFocus: focus, activate: true}) + return err +} + +func (adapter *Adapter) activateNativeDocumentObject(ctx context.Context, position ObjectReference, focus ObjectID) error { + if err := ctx.Err(); err != nil { + return err + } + adapter.treeMutex.Lock() + tree := adapter.documentTree + adapter.treeMutex.Unlock() + if tree == nil { + return ErrStaleObject + } + snapshot, err := tree.Resolve(position) + if err != nil { + return err + } + if snapshot.Role != "link" && !snapshot.SupportsClick { + return errors.New("current document object is not activatable") + } + if err := documentPositionMatchesFocus(tree, position, focus); err != nil { + return err + } + if len(adapter.nativeFocus) > 0 { + latest := adapter.nativeFocus[len(adapter.nativeFocus)-1].id + if latest != focus { + if err := document_position_matches_retained_focus(tree, position, adapter.nativeFocus[len(adapter.nativeFocus)-1]); err != nil { + return err + } + } + } + source := adapter.nativeDocument[position.ID()] + if source == nil { + return ErrStaleObject + } + role := C.atspi_accessible_get_role_name(source, nil) + currentRole := sanitizeSnapshotField(C.GoString(role)) + C.g_free(C.gpointer(role)) + if currentRole != snapshot.Role { + return ErrStaleObject + } + window := C.cthulhu_window_ancestor(source) + if window == nil { + return ErrStaleObject + } + foreground := adapter.matchesForeground(window, nativeObjectID(window)) + C.g_object_unref(C.gpointer(window)) + if !foreground { + return ErrStaleObject + } + action := C.atspi_accessible_get_action_iface(source) + if action == nil { + return errors.New("current document object has no accessible action") + } + defer C.g_object_unref(C.gpointer(action)) + names := []string{"click", "click-ancestor", "press", "jump", "open", "activate"} + var nativeErr *C.GError + count := int(C.atspi_action_get_n_actions(action, &nativeErr)) + if nativeErr != nil { + err := nativeError("get document actions", nativeErr) + C.g_error_free(nativeErr) + return err + } + // Read each action name once. Previously each preferred spelling caused + // another full round of synchronous accessibility calls. + actionNames := make([]string, min(max(count, 0), 64)) + for index := range actionNames { + if err := ctx.Err(); err != nil { + return err + } + name := C.atspi_action_get_name(action, C.gint(index), nil) + actionNames[index] = C.GoString(name) + C.g_free(C.gpointer(name)) + } + for _, wanted := range names { + for index, name := range actionNames { + if !strings.EqualFold(name, wanted) { + continue + } + if err := ctx.Err(); err != nil { + return err + } + var nativeErr *C.GError + activated := C.atspi_action_do_action(action, C.gint(index), &nativeErr) + if nativeErr != nil { + err := nativeError("activate document object", nativeErr) + C.g_error_free(nativeErr) + return err + } + if activated != 0 { + adapter.treeInvalidations.Add(uint64(tree.markAncestorChildrenChanged(position.ID()))) + return nil + } + } + } + return errors.New("current document object refused activation") +} + +// ReadDocumentCaret reads one bounded AT-SPI text unit on the GLib owner. +// The worker keeps the virtual offset; no native caret or focus is changed. +func (adapter *Adapter) ReadDocumentCaret(ctx context.Context, position ObjectReference, offset int, unit DocumentCaretUnit) (DocumentCaretText, error) { + if !position.Valid() || offset < 0 || !unit.Valid() { + return DocumentCaretText{}, ErrStaleObject + } + result, err := adapter.documentOperation(ctx, treeCaptureRequest{caretObject: position, caretOffset: offset, caretUnit: unit}) + return result.caret, err +} + +// ReadDocumentCharacters shares the normal GLib request/lifetime checks. The +// consumer can skip spaces in one block without one provider request per rune. +func (adapter *Adapter) ReadDocumentCharacters(ctx context.Context, position ObjectReference, offset int) (DocumentCaretText, error) { + return adapter.ReadDocumentCaret(ctx, position, offset, DocumentCaretCharacters) +} + +func (adapter *Adapter) readNativeDocumentCaret(ctx context.Context, position ObjectReference, offset int, unit DocumentCaretUnit) (DocumentCaretText, error) { + if err := ctx.Err(); err != nil { + return DocumentCaretText{}, err + } + adapter.treeMutex.Lock() + tree := adapter.documentTree + adapter.treeMutex.Unlock() + if tree == nil { + return DocumentCaretText{}, ErrStaleObject + } + snapshot, err := tree.Resolve(position) + if err != nil { + return DocumentCaretText{}, err + } + if (unit == DocumentCaretBrailleLine || unit == DocumentCaretCharacters) && snapshot.Role == "password text" { + return DocumentCaretText{}, ErrNoDocumentCaret + } + source := adapter.nativeDocument[position.ID()] + if source == nil { + return DocumentCaretText{}, ErrStaleObject + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return DocumentCaretText{}, ErrNoDocumentCaret + } + defer C.g_object_unref(C.gpointer(text)) + var nativeErr *C.GError + count := int(C.atspi_text_get_character_count(text, &nativeErr)) + if nativeErr != nil { + err := adapter.document_object_error(position.ID(), nativeError("get document text count", nativeErr)) + C.g_error_free(nativeErr) + return DocumentCaretText{}, err + } + if count == 0 && snapshot.CharacterCount > 0 && !snapshot.Editable && + (snapshot.Role == "static" || snapshot.Role == "text") { + return DocumentCaretText{}, adapter.document_text_became_empty(position.ID()) + } + if count <= 0 || offset >= count { + if unit != DocumentCaretBrailleLine || count <= 0 || offset != count { + return DocumentCaretText{CharacterCount: count}, nil + } + // A caret after the final character still belongs to the final line. + offset = count - 1 + } + if unit == DocumentCaretCharacters { + start := max(0, offset/128*128) + end := min(count, start+128) + content := C.atspi_text_get_text(text, C.gint(start), C.gint(end), &nativeErr) + if nativeErr != nil { + err := adapter.document_object_error(position.ID(), nativeError("read document characters", nativeErr)) + C.g_error_free(nativeErr) + C.g_free(C.gpointer(content)) + return DocumentCaretText{}, err + } + defer C.g_free(C.gpointer(content)) + return DocumentCaretText{Start: start, End: end, RawText: C.GoString(content), CharacterCount: count}, nil + } + if unit != DocumentCaretCharacter && unit != DocumentCaretWord { + line, err := adapter.readNativeDocumentLine(ctx, position.ID(), snapshot, text, offset, count) + if err != nil { + return DocumentCaretText{}, err + } + line.RawText = line.Text + if unit == DocumentCaretBrailleLine && adapter.captureTextAttributes.Load() { + line.TextAttributeRuns = native_text_attribute_runs(text, line.Start, line.End, TextAttributeRun{}) + } + if unit == DocumentCaretBrailleLine && C.atspi_text_get_n_selections(text, nil) > 0 { + if selection := C.atspi_text_get_selection(text, 0, nil); selection != nil { + line.SelectionStart, line.SelectionEnd = int(selection.start_offset), int(selection.end_offset) + C.g_free(C.gpointer(selection)) + } + } + // Geometry is optional: unavailable bounds keep object-local reading. + // Query on the GLib owner; no native reference leaves this operation. + if line.Start >= 0 && line.End > line.Start && line.End <= count { + var boundsErr error + line.Bounds, boundsErr = (nativeReviewText{text: text}).bounds(ctx, line.Start, line.End) + if boundsErr != nil { + if err := adapter.document_object_error(position.ID(), boundsErr); errors.Is(err, ErrDeadObject) { + return DocumentCaretText{}, err + } + } + if err := ctx.Err(); err != nil { + return DocumentCaretText{}, err + } + } + // Generated text can disappear between the count, line and geometry + // queries. Keep missing geometry optional for live text, but refresh a + // stale text object instead of dropping its fragment from the line. + if !snapshot.Editable && (snapshot.Role == "static" || snapshot.Role == "text") && + (!line.Bounds.Valid() || line.End <= line.Start) { + var verifyErr *C.GError + remaining := int(C.atspi_text_get_character_count(text, &verifyErr)) + if verifyErr != nil { + err := adapter.document_object_error(position.ID(), nativeError("verify document text count", verifyErr)) + C.g_error_free(verifyErr) + if errors.Is(err, ErrDeadObject) { + return DocumentCaretText{}, err + } + } else if remaining == 0 && count > 0 { + return DocumentCaretText{}, adapter.document_text_became_empty(position.ID()) + } + } + if unit == DocumentCaretLineRemainder && line.Start < offset && offset < line.End && offset-line.Start <= utf8.RuneCountInString(line.Text) { + line.Text = string([]rune(line.Text)[offset-line.Start:]) + line.Start = offset + } + if unit != DocumentCaretBrailleLine { + line.Misspelled = native_misspelled(text, offset) + line.Text = sanitizeSnapshotField(line.Text) + } + return line, nil + } + granularity := C.AtspiTextGranularity(C.ATSPI_TEXT_GRANULARITY_LINE) + switch unit { + case DocumentCaretCharacter: + granularity = C.AtspiTextGranularity(C.ATSPI_TEXT_GRANULARITY_CHAR) + case DocumentCaretWord: + granularity = C.AtspiTextGranularity(C.ATSPI_TEXT_GRANULARITY_WORD) + } + rangeText := C.atspi_text_get_string_at_offset(text, C.gint(offset), granularity, &nativeErr) + if nativeErr != nil { + err := adapter.document_object_error(position.ID(), nativeError("read document text", nativeErr)) + C.g_error_free(nativeErr) + return DocumentCaretText{}, err + } + if rangeText == nil { + return DocumentCaretText{CharacterCount: count}, nil + } + defer C.g_free(C.gpointer(rangeText)) + defer C.g_free(C.gpointer(rangeText.content)) + content := sanitizeSnapshotField(C.GoString(rangeText.content)) + if unit == DocumentCaretCharacter { + // Whitespace is a navigable character. Label normalization would + // erase it, preventing space speech and word delimiter detection. + content = documentCaretCharacter(C.GoString(rangeText.content)) + } + return DocumentCaretText{ + Start: int(rangeText.start_offset), End: int(rangeText.end_offset), + Text: content, CharacterCount: count, Misspelled: native_misspelled(text, offset), + }, nil +} + +// Capture only ancestors: changing focus must not require scanning a whole page. +func (adapter *Adapter) nativeDocumentContext(ctx context.Context, focus ObjectID) (DocumentContext, error) { + var source *C.AtspiAccessible + for _, item := range adapter.nativeFocus { + if item.id == focus { + source = (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(item.source))) + break + } + } + if source == nil { + return DocumentContext{}, ErrObjectNotFound + } + defer func() { + if source != nil { + C.g_object_unref(C.gpointer(source)) + } + }() + nodes := []TreeNode{} + seen := map[ObjectID]bool{} + var child ObjectID + for source != nil { + if err := ctx.Err(); err != nil { + return DocumentContext{}, err + } + C.atspi_accessible_clear_cache_single(source) + snapshot := snapshotFromNativeWithCaret(source, false, false, false, false) + if len(nodes) >= 256 || seen[snapshot.ID()] || snapshot.Defunct { + return DocumentContext{}, ErrStaleObject + } + seen[snapshot.ID()] = true + node := TreeNode{Snapshot: snapshot} + if child.Valid() { + node.Children = []ObjectID{child} + } + nodes = append(nodes, node) + child = snapshot.ID() + if snapshot.Role == "application" { + break + } + var nativeErr *C.GError + parent := C.atspi_accessible_get_parent(source, &nativeErr) + if nativeErr != nil { + if parent != nil { + C.g_object_unref(C.gpointer(parent)) + } + err := nativeError("document context parent", nativeErr) + C.g_error_free(nativeErr) + return DocumentContext{}, err + } + C.g_object_unref(C.gpointer(source)) + source = parent + } + tree, err := NewAccessibleTree(child, nodes) + if err != nil { + return DocumentContext{}, err + } + ref, err := tree.Reference(focus) + if err != nil { + return DocumentContext{}, err + } + return tree.DocumentContext(ref) +} + +func (adapter *Adapter) setNativeDocumentPosition(ctx context.Context, position ObjectReference, focus ObjectID, offset int, useOffset bool) error { + if err := ctx.Err(); err != nil { + return err + } + adapter.treeMutex.Lock() + tree := adapter.documentTree + adapter.treeMutex.Unlock() + if tree == nil { + return ErrStaleObject + } + snapshot, err := tree.Resolve(position) + if err != nil { + return err + } + source := adapter.nativeDocument[position.ID()] + if source == nil { + return ErrStaleObject + } + // Document captures are rooted at the outermost web document. Its + // identity remains valid when an unrelated changing label is marked stale. + document, err := tree.Root() + if err != nil { + return err + } + // Recheck on the GLib owner: focus can change after the worker queues us. + if len(adapter.nativeFocus) > 0 { + latest := adapter.nativeFocus[len(adapter.nativeFocus)-1].id + if latest != focus { + if err := document_position_matches_retained_focus(tree, position, adapter.nativeFocus[len(adapter.nativeFocus)-1]); err != nil { + return err + } + } + } + echoIDs, err := tree.subtreeIDs(position) + if err != nil { + return err + } + echoIDs = append(echoIDs, documentCaretEchoAncestors(tree, position)...) + adapter.navigationCaretOffset = offset + adapter.navigationSelectionOffsets = nil + adapter.navigationEcho = make(map[ObjectID]uint8, len(echoIDs)) + for _, id := range echoIDs { + adapter.navigationEcho[id] = 15 + } + component := C.atspi_accessible_get_component_iface(source) + if component != nil { + if documentTargetGrabsFocus(tree, position, snapshot) { + C.atspi_component_grab_focus(component, nil) + } + C.atspi_component_scroll_to(component, C.ATSPI_SCROLL_ANYWHERE, nil) + C.g_object_unref(C.gpointer(component)) + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + clear(adapter.navigationEcho) + // Images and other whole-object stops have a valid virtual position + // without a native text caret. Python's web setCaretPosition likewise + // only attempts SetCaretOffset when the object supports text. + adapter.rememberNativeFocus(source, position.ID()) + adapter.nativeFocus[len(adapter.nativeFocus)-1].navigationDocument = document + return nil + } + defer C.g_object_unref(C.gpointer(text)) + var nativeErr *C.GError + var caretOffset C.gint + if useOffset { + caretOffset = C.int(offset) + } else { + caretOffset = C.atspi_text_get_caret_offset(text, &nativeErr) + if nativeErr != nil { + err := adapter.document_object_error(position.ID(), nativeError("get document caret", nativeErr)) + C.g_error_free(nativeErr) + clear(adapter.navigationEcho) + return err + } + if caretOffset < 0 { + caretOffset = 0 + } + } + adapter.navigationCaretOffset = int(caretOffset) + // Python clears the previous selection before moving its browse caret. + for selections := min(int(C.atspi_text_get_n_selections(text, nil)), 16); selections > 0; selections-- { + // Removing a selection can first collapse to its start or end. Those + // intermediate caret events must not overwrite the requested position, + // particularly when routing Braille before the result reaches the UI. + selection := C.atspi_text_get_selection(text, 0, nil) + if selection != nil { + if adapter.navigationSelectionOffsets == nil { + adapter.navigationSelectionOffsets = make(map[int]bool) + } + adapter.navigationSelectionOffsets[int(selection.start_offset)] = true + adapter.navigationSelectionOffsets[int(selection.end_offset)] = true + C.g_free(C.gpointer(selection)) + } + C.atspi_text_remove_selection(text, 0, nil) + } + moved := C.atspi_text_set_caret_offset(text, caretOffset, &nativeErr) + if nativeErr != nil { + err := adapter.document_object_error(position.ID(), nativeError("set document caret", nativeErr)) + C.g_error_free(nativeErr) + clear(adapter.navigationEcho) + return err + } + if moved == 0 { + clear(adapter.navigationEcho) + return errors.New("browser refused document caret") + } + adapter.rememberNativeFocus(source, position.ID()) + adapter.nativeFocus[len(adapter.nativeFocus)-1].navigationDocument = document + return nil +} + +// A dynamic page can replace the text at a successfully placed browse caret +// before the next command. That remembered position is not evidence that native +// focus left the document. Retain its generation-checked document proof while +// continuing to reject actual focus changes to chrome or another document. +func document_position_matches_retained_focus(tree *AccessibleTree, position ObjectReference, focus nativeFocusReference) error { + err := documentPositionMatchesFocus(tree, position, focus.id) + if !errors.Is(err, ErrObjectNotFound) || !focus.navigationDocument.Valid() { + return err + } + owner, targetErr := tree.DocumentContext(position) + if targetErr != nil { + return targetErr + } + if owner.TopLevel != focus.navigationDocument { + return err + } + return nil +} + +// Python's web grabFocusWhenSettingCaret avoids moving native focus onto +// ordinary headings and entries. Focusing a heading inside a disclosure can +// focus its button and close the disclosure while the browse caret moves. +func documentTargetGrabsFocus(tree *AccessibleTree, position ObjectReference, snapshot Snapshot) bool { + if !snapshot.Focusable || snapshot.Editable || snapshot.Role == "entry" { + return false + } + if snapshot.Role != "heading" && snapshot.Role != "image" { + return true + } + tree.mu.RLock() + defer tree.mu.RUnlock() + entry, err := tree.resolveLocked(position) + if err != nil { + return false + } + if snapshot.Role == "image" { + for entry.hasParent { + parent, ok := tree.nodes[entry.parent] + if !ok { + return false + } + if parent.snapshot.Role == "link" { + return true + } + entry = parent + } + return false + } + if len(entry.children) != 1 { + return false + } + child, ok := tree.nodes[entry.children[0]] + return ok && child.snapshot.Role == "link" +} + +// Same-document focus changes caused by navigation are valid; chrome and other +// tabs must never be pulled back by a queued native caret/focus operation. +func documentPositionMatchesFocus(tree *AccessibleTree, position ObjectReference, focus ObjectID) error { + current, err := tree.Reference(focus) + if err != nil { + return err + } + owner, err := tree.DocumentContext(current) + if err != nil { + return err + } + target, err := tree.DocumentContext(position) + if err != nil { + return err + } + if owner.TopLevel != target.TopLevel { + return errors.New("document focus changed before navigation") + } + return nil +} + +// Foreground returns owned metadata without native calls from a consumer. diff --git a/internal/atspi/adapter_event_callback_native.go b/internal/atspi/adapter_event_callback_native.go new file mode 100644 index 0000000..5eafb72 --- /dev/null +++ b/internal/atspi/adapter_event_callback_native.go @@ -0,0 +1,608 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "net/url" + "runtime/cgo" + "strings" + "time" + "unsafe" +) + +func shouldSpeakEvent(eventType string, detail1 int) bool { + return eventType != FocusedStateEvent || detail1 == 1 +} + +// Every completion that can acquire document focus needs a retained native +// source for the subsequent context lookup, even without load-complete. +func shouldRetainNativeFocus(eventType string, detail1 int, chromeFocus ObjectID) bool { + switch eventType { + case FocusEvent, FocusedStateEvent, WindowActivatedEvent, ActiveDescendantEvent, SelectionChangedEvent, CaretEvent: + return true + case DocumentLoadCompleteEvent, DocumentLoadStoppedEvent: + return !chromeFocus.Valid() + case BusyStateEvent: + return detail1 == 0 && !chromeFocus.Valid() + default: + return false + } +} + +// selectNativeEventTarget returns a borrowed event source or a retained target. +// The callback releases a retained target after all native queries finish. +func selectNativeEventTarget(event *C.AtspiEvent, eventType string) (*C.AtspiAccessible, bool) { + target := event.source + ownedTarget := false + switch eventType { + case FocusEvent, FocusedStateEvent: + target = C.cthulhu_combo_ancestor(event.source) + if target == nil { + target = event.source + } else { + ownedTarget = true + } + // A table's first selected child is its active child only when the + // selection is unique. Multi-selection changes use their own events. + targetRole := C.atspi_accessible_get_role(target, nil) + listTable := targetRole == C.ATSPI_ROLE_LIST && C.cthulhu_is_gtk_list_table(target) != 0 + // GTK notebooks report container focus before the active tab when an + // X11 key grab ends. Resolve that container to its selected tab, as + // with menus, so ordinary duplicate-focus handling preserves review. + if targetRole == C.ATSPI_ROLE_MENU || targetRole == C.ATSPI_ROLE_PAGE_TAB_LIST || targetRole == C.ATSPI_ROLE_TABLE || listTable { + var child *C.AtspiAccessible + if targetRole == C.ATSPI_ROLE_TABLE || listTable { + child = C.cthulhu_table_selected_child(target) + } else { + child = C.cthulhu_selected_child(target) + } + if child != nil { + if ownedTarget { + C.g_object_unref(C.gpointer(target)) + } + target = child + ownedTarget = true + } + } + case WindowActivatedEvent: + C.cthulhu_refresh_frame_children(event.source) + target = C.cthulhu_popup_menu_target(event.source) + if target == nil { + target = C.cthulhu_focused_descendant(event.source) + } + if target == nil { + target = C.cthulhu_showing_web_document(event.source) + } + if target != nil { + ownedTarget = true + } else { + target = event.source + } + case ActiveDescendantEvent: + target = C.cthulhu_event_active_descendant(event) + case SelectionChangedEvent: + if C.atspi_accessible_get_role(event.source, nil) == C.ATSPI_ROLE_PAGE_TAB_LIST { + // libatspi resolves the selected child's index through its cached + // child list. Tab creation/removal makes that list stale. + C.atspi_accessible_clear_cache_single(event.source) + } + if C.atspi_accessible_get_role(event.source, nil) == C.ATSPI_ROLE_TABLE || C.cthulhu_is_gtk_list_table(event.source) != 0 { + target = C.cthulhu_table_selected_child(event.source) + } else { + target = C.cthulhu_selected_child(event.source) + } + ownedTarget = target != nil + } + return target, ownedTarget +} + +// captureNativeEventSnapshot enriches the target without changing event ownership. +// It runs on the GLib owner and retains no native references. +func (adapter *Adapter) captureNativeEventSnapshot(event *C.AtspiEvent, target *C.AtspiAccessible, eventType string, originID ObjectID, live nativeLiveProperties) (Snapshot, ObjectID) { + // Document focus/load presentation needs only the title. Real caret + // events still capture text, including carets hosted on document roots. + captureCaret := !isDocumentLifecycleEvent(eventType) && eventType != BusyStateEvent + if eventType == FocusEvent || eventType == FocusedStateEvent { + role := C.atspi_accessible_get_role(target, nil) + captureCaret = role != C.ATSPI_ROLE_DOCUMENT_WEB && role != C.ATSPI_ROLE_DOCUMENT_FRAME && role != C.ATSPI_ROLE_EMBEDDED + } + snapshot := snapshotFromNativeWithCaret(target, captureCaret, eventType == CaretEvent, false, adapter.captureSound.Load(), adapter.captureTextAttributes.Load()) + if snapshot.Editable && (eventType == CaretEvent || eventType == TextInsertedEvent || + eventType == TextDeletedEvent || eventType == TextSelectionChangedEvent) { + if editor := C.cthulhu_editable_root(target); editor != nil { + snapshot.EditableRoot = nativeObjectID(editor) + C.g_object_unref(C.gpointer(editor)) + } + } + snapshot.ApplicationProcess = adapter.applicationProcess(target) + if snapshot.Role == "slider" || + snapshot.Role == "combo box" && (snapshot.Name == "Key echo speech synthesizer" || snapshot.Name == "Key echo person") { + snapshot.ApplicationPID = int(C.atspi_accessible_get_process_id(target, nil)) + } + if snapshot.Role == "combo box" && strings.EqualFold(snapshot.ApplicationProcess, "firefox") { + snapshot.Autocomplete = snapshot.Autocomplete || + isFirefoxChromeAutocomplete(snapshot, C.cthulhu_in_active_document(target) != 0) + } + if eventType == TextInsertedEvent || eventType == ChildrenAddedEvent { + snapshot.LivePoliteness = live.politeness + snapshot.LiveRegion = live.politeness != "" && C.cthulhu_in_active_document(event.source) != 0 + if snapshot.LiveRegion { + snapshot.LiveAtomic = live.atomic + if eventType == TextInsertedEvent && snapshot.LiveAtomic { + text := C.cthulhu_atomic_live_content(event.source) + snapshot.Text = sanitizeSnapshotField(C.GoString(text)) + C.g_free(C.gpointer(text)) + } + if eventType == ChildrenAddedEvent { + if child := C.cthulhu_event_active_descendant(event); child != nil { + text := C.cthulhu_live_content(child) + if snapshot.LiveAtomic { + C.g_free(C.gpointer(text)) + text = C.cthulhu_atomic_live_content(event.source) + } + snapshot.Text = sanitizeSnapshotField(C.GoString(text)) + C.g_free(C.gpointer(text)) + } + } + } + } + if snapshot.BusName == "" { + snapshot.BusName = originID.BusName + } + if eventType == CaretEvent { + adapter.repairNativeCaretLine(target, &snapshot, int(C.cthulhu_event_detail1(event))) + } + if eventType == AccessibleNameEvent || snapshot.Role == "page tab" { + toolkit := C.atspi_accessible_get_toolkit_name(target, nil) + snapshot.ToolkitName = sanitizeSnapshotField(C.GoString(toolkit)) + C.g_free(C.gpointer(toolkit)) + } + if snapshot.Role == "page tab" { + document := C.cthulhu_document_ancestor(target) + snapshot.BrowserTab = isBrowserChromeTab(snapshot, document != nil) + if document != nil { + C.g_object_unref(C.gpointer(document)) + } + } + if (eventType == WindowCreateEvent || eventType == WindowActivatedEvent) && snapshot.Role == "frame" { + if labels := C.cthulhu_collect_simple_prompt_text(target); labels != nil { + snapshot.Text = sanitizeSnapshotField(C.GoString(labels)) + C.g_free(C.gpointer(labels)) + } + } + if eventType == WindowCreateEvent { + if snapshot.Role == "alert" { + if labels := C.cthulhu_collect_notification_text(target); labels != nil { + snapshot.Text = sanitizeSnapshotField(C.GoString(labels)) + C.g_free(C.gpointer(labels)) + } + } + switch strings.ToLower(snapshot.ApplicationName) { + case "notification-daemon", "notify-osd", "xfce4-notifyd", "mate-notification-daemon": + if labels := C.cthulhu_collect_notification_text(target); labels != nil { + snapshot.Text = sanitizeSnapshotField(C.GoString(labels)) + C.g_free(C.gpointer(labels)) + } + } + } + if snapshot.Autocomplete && (eventType == TextInsertedEvent || eventType == TextDeletedEvent || + eventType == FocusEvent || eventType == FocusedStateEvent) { + text := C.atspi_accessible_get_text(target) + if text != nil && C.atspi_text_get_n_selections(text, nil) > 0 { + selection := C.atspi_text_get_selection(text, 0, nil) + if selection != nil { + snapshot.SelectionStart, snapshot.SelectionEnd = int(selection.start_offset), int(selection.end_offset) + if selection.start_offset > 0 && selection.end_offset == C.atspi_text_get_character_count(text, nil) { + prefix := C.atspi_text_get_text(text, selection.start_offset-1, selection.start_offset, nil) + snapshot.CompletionPrefixCharacter = sanitizeCaretCharacter(C.GoString(prefix)) + C.g_free(C.gpointer(prefix)) + } + C.g_free(C.gpointer(selection)) + } + } + if text != nil { + C.g_object_unref(C.gpointer(text)) + } + } + + if eventType == CaretEvent && snapshot.Role != "password text" { + word := C.cthulhu_capture_caret_unit(target, C.ATSPI_TEXT_GRANULARITY_WORD) + snapshot.CaretWord = sanitizeSnapshotField(C.GoString(word)) + C.g_free(C.gpointer(word)) + } + var popupFor ObjectID + if snapshot.Role == "list item" || snapshot.Role == "list box" || snapshot.Role == "menu item" || + snapshot.Role == "button" || snapshot.Role == "push button" || snapshot.Role == "toggle button" { + if popupTarget := C.cthulhu_autocomplete_popup_target(target); popupTarget != nil { + popupFor = nativeObjectID(popupTarget) + snapshot.AutocompletePopup = popupFor.Valid() + C.g_object_unref(C.gpointer(popupTarget)) + } + } + return snapshot, popupFor +} + +// enrichNativeWindowEvent queries and releases the window on the GLib owner. +// It applies foreground, tab/document, table, and prompt state in query order. +func (adapter *Adapter) enrichNativeWindowEvent(event *C.AtspiEvent, target *C.AtspiAccessible, eventType string, snapshot Snapshot, focusEvent *Event) { + webNotification := focusEvent.WebNotification + window := C.cthulhu_window_ancestor(event.source) + var restoredDocument ObjectID + if window == nil && (eventType == FocusedStateEvent || eventType == FocusEvent || eventType == CaretEvent) { + window, restoredDocument = adapter.detachedDocumentWindow(event.source, eventType, focusEvent.Detail1) + } + focusEvent.Window = nativeObjectID(window) + if webNotification != nil { + webNotification.WindowPath = focusEvent.Window.Path + if adapter.webNotificationRoots == nil || len(adapter.webNotificationRoots) >= 64 { + adapter.webNotificationRoots = make(map[ObjectID]bool) + } + adapter.webNotificationRoots[NewObjectID(webNotification.BusName, webNotification.RootPath)] = true + } + focusEvent.WindowRecovered = restoredDocument.Valid() + if eventType == WindowActivatedEvent && (snapshot.Role == "tree table" || snapshot.Role == "table cell") && window != nil { + if labels := C.cthulhu_collect_simple_prompt_text(window); labels != nil { + focusEvent.WindowMessage = sanitizeSnapshotField(C.GoString(labels)) + C.g_free(C.gpointer(labels)) + } + if focusEvent.WindowMessage == "" && focusEvent.Window.Valid() { + adapter.promptRefreshWindow = focusEvent.Window + } + } + if eventType == WindowActivatedEvent && window != nil { + name := C.atspi_accessible_get_name(window, nil) + focusEvent.WindowTitle = sanitizeSnapshotField(C.GoString(name)) + C.g_free(C.gpointer(name)) + } + focusEvent.Foreground = adapter.Foreground() + focusedMenuItem := (eventType == FocusEvent || eventType == FocusedStateEvent) && + (snapshot.Role == "menu item" || snapshot.Role == "check menu item" || snapshot.Role == "radio menu item") && snapshot.Focused + if eventType == WindowActivatedEvent { + focusEvent.ForegroundMismatch = !adapter.matchForeground(window, focusEvent.Window, &focusEvent.ForegroundCheck, false) + } else { + focusEvent.ForegroundMismatch = !adapter.matchForeground(window, focusEvent.Window, nil, focusedMenuItem) + } + if !focusEvent.ForegroundMismatch && window != nil && + (eventType == WindowActivatedEvent || snapshot.Role == "table" || snapshot.Role == "table cell") { + description := C.atspi_accessible_get_description(window, nil) + if (description == nil || C.GoString(description) == "") && + (snapshot.Role == "table" || snapshot.Role == "table cell") && + (eventType == WindowActivatedEvent || eventType == FocusEvent || eventType == FocusedStateEvent) { + C.g_free(C.gpointer(description)) + C.atspi_accessible_clear_cache_single(window) + description = C.atspi_accessible_get_description(window, nil) + } + focusEvent.WindowDescription = sanitizeSnapshotField(C.GoString(description)) + C.g_free(C.gpointer(description)) + } + if !focusEvent.ForegroundMismatch && + (eventType == WindowActivatedEvent || eventType == FocusEvent || eventType == FocusedStateEvent || + eventType == SelectionChangedEvent || eventType == ActiveDescendantEvent || + eventType == AccessibleNameEvent && snapshot.Role == "table cell") && + (snapshot.Role == "table" || snapshot.Role == "table cell") { + var rows, columns C.gint + var tableName, tablePath *C.gchar + var rowIndex, columnIndex C.gint + var guiTable C.gboolean + rowText := C.cthulhu_table_context(target, &rows, &columns, &tableName, + &tablePath, &rowIndex, &columnIndex, &guiTable) + snapshot.TableRowCount = int(rows) + snapshot.TableColumnCount = int(columns) + snapshot.TableName = sanitizeSnapshotField(C.GoString(tableName)) + snapshot.TablePath = sanitizeSnapshotField(C.GoString(tablePath)) + snapshot.TableRowIndex = int(rowIndex) + snapshot.TableColumnIndex = int(columnIndex) + snapshot.TablePositionKnown = rowIndex >= 0 && columnIndex >= 0 + snapshot.TableRowText = sanitizeSnapshotField(C.GoString(rowText)) + snapshot.GUITable = guiTable != 0 + C.g_free(C.gpointer(tableName)) + C.g_free(C.gpointer(tablePath)) + C.g_free(C.gpointer(rowText)) + focusEvent.Source = snapshot + } + if !focusEvent.ForegroundMismatch { + captureLibreOfficeContext(target, &snapshot) + adapter.captureLibreOfficeHeaders(target, &snapshot, focusEvent.Window) + if eventType == SelectionChangedEvent && snapshot.Role == "table" && + snapshot.LibreOffice != nil && snapshot.LibreOffice.InSpreadsheet { + snapshot.LibreOffice.Selection = captureLibreOfficeSelection(target) + } + focusEvent.Source = snapshot + if eventType == FocusEvent || eventType == FocusedStateEvent && focusEvent.Detail1 != 0 || eventType == CaretEvent || eventType == ActiveDescendantEvent || eventType == SelectionChangedEvent { + snapshot.SpeechContext, snapshot.BrailleContext = native_speech_context(target) + for _, ancestor := range snapshot.SpeechContext { + if ancestor.Role == "document spreadsheet" { + snapshot.Spreadsheet = true + } + } + focusEvent.Source = snapshot + } + if snapshot.BrowserTab && (eventType == SelectedStateEvent && focusEvent.Detail1 != 0 && snapshot.Selected || + eventType == SelectionChangedEvent && snapshot.Selected && strings.EqualFold(snapshot.ToolkitName, "Gecko")) { + adapter.selectedTabWindow = focusEvent.Window + adapter.activeDocument = ObjectID{} + adapter.deferredLiveRegions = nil + } + if IsWebDocumentRole(snapshot.Role) && + (eventType == WindowActivatedEvent || eventType == FocusEvent || eventType == FocusedStateEvent && focusEvent.Detail1 != 0 || eventType == DocumentLoadCompleteEvent) { + adapter.rememberDocumentWindow(snapshot.ID(), window) + adapter.activeDocument = snapshot.ID() + adapter.selectedTabWindow = ObjectID{} + } else if restoredDocument.Valid() { + adapter.activeDocument = restoredDocument + } + } + if (eventType == WindowCreateEvent || eventType == WindowActivatedEvent) && snapshot.Role == "frame" { + adapter.promptRefreshWindow = ObjectID{} + if !focusEvent.ForegroundMismatch && snapshot.Text == "" && focusEvent.Window.Valid() { + adapter.promptRefreshWindow = focusEvent.Window + } + if eventType == WindowActivatedEvent && !focusEvent.ForegroundMismatch { + adapter.promptScannedWindow = focusEvent.Window + adapter.promptScannedEpoch = focusEvent.Foreground.Epoch + } + } + if eventType == WindowActivatedEvent && snapshot.Role == "button" && + !focusEvent.ForegroundMismatch && window != nil && focusEvent.Window.Valid() && + (adapter.promptScannedWindow != focusEvent.Window || adapter.promptScannedEpoch != focusEvent.Foreground.Epoch) { + adapter.promptScannedWindow = focusEvent.Window + adapter.promptScannedEpoch = focusEvent.Foreground.Epoch + if labels := C.cthulhu_collect_simple_prompt_text(window); labels != nil { + focusEvent.WindowMessage = sanitizeSnapshotField(C.GoString(labels)) + C.g_free(C.gpointer(labels)) + } + if focusEvent.WindowMessage == "" { + adapter.promptRefreshWindow = focusEvent.Window + } else { + adapter.promptRefreshWindow = ObjectID{} + } + } + if !focusEvent.ForegroundMismatch && window != nil && + (eventType == FocusEvent || eventType == FocusedStateEvent && focusEvent.Detail1 == 1) && + (snapshot.Role == "button" || snapshot.Role == "tree table" || snapshot.Role == "table cell") && focusEvent.Window == adapter.promptRefreshWindow { + if labels := C.cthulhu_collect_simple_prompt_text(window); labels != nil { + focusEvent.WindowMessage = sanitizeSnapshotField(C.GoString(labels)) + C.g_free(C.gpointer(labels)) + if focusEvent.WindowMessage != "" { + adapter.promptRefreshWindow = ObjectID{} + } + } + } + if window != nil { + C.g_object_unref(C.gpointer(window)) + } +} + +//export cthulhuAtspiEventCallback +func cthulhuAtspiEventCallback(event *C.AtspiEvent, userData unsafe.Pointer) { + if event == nil || userData == nil { + return + } + callbackHandle := cgo.Handle(C.cthulhu_callback_value((*C.cthulhu_callback_data)(userData))) + value := callbackHandle.Value() + adapter, validAdapter := value.(*Adapter) + if !validAdapter { + return + } + secureEpoch := adapter.secureEpoch.Load() + // Retire copied header identities even while locked. Tab lifecycle only + // checks roles; it never captures text or presents output. + nativeEventType := C.GoString(C.cthulhu_event_type(event)) + if strings.HasPrefix(nativeEventType, MouseButtonEvent+":") { + if !adapter.secure.Load() && strings.HasSuffix(nativeEventType, "p") { + // Like Orca, observe the shared AT-SPI pointer signal. No object + // capture or pointer coordinates are needed for navigation handoff. + clear(adapter.navigationEcho) + adapter.enqueueSecureEvent(Event{Type: MouseButtonEvent}, secureEpoch) + } + return + } + eventType := canonicalTextChangeEventType(nativeEventType) + originID := nativeObjectID(event.source) + if eventType == AccessibleNameEvent || eventType == DefunctStateEvent && C.cthulhu_event_detail1(event) != 0 { + C.cthulhu_forget_menu_checkability(event.source) + } + adapter.retireEchoFocus(eventType, int(C.cthulhu_event_detail1(event)), originID) + if eventType != DefunctStateEvent || C.cthulhu_event_detail1(event) != 0 { + adapter.retireLibreOfficeHeaders(event.source, eventType, originID) + } + if adapter.secure.Load() { + return + } + if eventType == "object:state-changed:checked" && + C.atspi_accessible_get_role(event.source, nil) == C.ATSPI_ROLE_MENU_ITEM { + C.cthulhu_note_menu_checkability(event.source) + } + + adapter.applySecureReset() + adapter.refreshForeground() + if isDocumentLifecycleEvent(eventType) || eventType == DefunctStateEvent && C.cthulhu_event_detail1(event) != 0 { + adapter.deferredLiveRegions.take(originID) + adapter.deferredLiveRegions.forget_document(originID) + } + if eventType == DefunctStateEvent && C.cthulhu_event_detail1(event) != 0 { + adapter.forgetDocumentWindow(originID) + } else if eventType == WindowDestroyedEvent { + adapter.forgetWindowDocuments(originID) + } + invalidated := adapter.applyTreeInvalidation(eventType, event) + if eventType == DefunctStateEvent && C.cthulhu_event_detail1(event) != 0 && adapter.webNotificationRoots[originID] { + delete(adapter.webNotificationRoots, originID) + // Retire a known toast before the normal dead-object early return. + // Do not query or retain the accessible which has just been destroyed. + retired := NewEvent(eventType, Snapshot{BusName: originID.BusName, Path: originID.Path, Defunct: true}) + retired.Detail1 = 1 + adapter.enqueueSecureEvent(retired, secureEpoch) + return + } + // Showing/child-added events normally finish at invalidation. A matched + // notification script needs their semantics before that early return, + // including when the provider is outside foreground ownership. + webNotification := adapter.webNotification(event) + if invalidated && webNotification == nil && eventType != ChildrenAddedEvent && (eventType != DefunctStateEvent || !adapter.nativeFocusIs(originID)) { + return + } + if !shouldSpeakEvent(eventType, int(C.cthulhu_event_detail1(event))) { + return + } + if adapter.filterNativeBackgroundEvent(event, eventType, originID, webNotification != nil) { + adapter.backgroundEventsFiltered.Add(1) + return + } + var live nativeLiveProperties + if eventType == TextInsertedEvent || eventType == ChildrenAddedEvent || eventType == BusyStateEvent { + live = capture_live_properties(event.source) + } + if invalidated && webNotification == nil && eventType == ChildrenAddedEvent && (live.politeness == "" || live.politeness == "off") { + return + } + deferLive, completeLive := adapter.prepare_live_region(event, eventType, originID, live) + if deferLive { + return + } + if completeLive { + eventType = TextInsertedEvent + } + if (isDocumentLifecycleEvent(eventType) || eventType == BusyStateEvent) && C.cthulhu_active_document(event.source) == 0 { + return + } + snapshotStarted := time.Now() + target := adapter.libreOfficeFocusTarget(event, eventType) + ownedTarget := target != nil + if target == nil { + target, ownedTarget = selectNativeEventTarget(event, eventType) + } + if target == nil { + return + } + if (eventType == FocusEvent || eventType == FocusedStateEvent) && + C.atspi_accessible_get_role(target, nil) == C.ATSPI_ROLE_MENU_ITEM { + // Qt menus can change their checked state without a state-change + // event. Reopening the menu must capture the current provider state. + C.atspi_accessible_clear_cache_single(target) + } + if (eventType == SelectedStateEvent || eventType == SelectionChangedEvent) && + C.atspi_accessible_get_role(target, nil) == C.ATSPI_ROLE_PAGE_TAB { + // Firefox can emit selected-state events from the previous tab; + // query the current state/name before using either event path. + C.atspi_accessible_clear_cache_single(target) + } + if eventType == WindowDeactivatedEvent { + // Match Python's key-grab churn check against fresh window state rather + // than an AT-SPI cache entry from before the deactivation event. + C.atspi_accessible_clear_cache_single(event.source) + } + payload := C.cthulhu_event_payload(event) + snapshot, popupFor := adapter.captureNativeEventSnapshot(event, target, eventType, originID, live) + if completeLive { + text := C.cthulhu_live_content(event.source) + snapshot.Text = sanitizeSnapshotField(C.GoString(text)) + snapshot.LiveAtomic = true + C.g_free(C.gpointer(payload)) + payload = text + } + // Shared Qt actions can report focus through their original, hidden menu + // even while another menu emits focus-gained for that very accessible. + // The explicit event establishes focus; the queried state may disagree. + // Do not transfer this evidence to a redirected descendant or a dead item. + if snapshot.ID() == originID && !snapshot.Defunct && + (eventType == FocusEvent || eventType == FocusedStateEvent && C.cthulhu_event_detail1(event) == 1) { + switch snapshot.Role { + case "menu item", "check menu item", "radio menu item": + snapshot.Focused = true + } + } + var inlineMenuID ObjectID + if eventType == SelectedStateEvent && C.cthulhu_event_detail1(event) == 1 && !snapshot.Defunct && + (snapshot.Role == "button" || snapshot.Role == "push button" || snapshot.Role == "toggle button" || + snapshot.Role == "menu item" || snapshot.Role == "check menu item" || snapshot.Role == "radio menu item") { + if menu := C.cthulhu_inline_menu_container(target); menu != nil { + inlineMenuID = nativeObjectID(menu) + C.g_object_unref(C.gpointer(menu)) + if inlineMenuID.Valid() && inlineMenuID.BusName == snapshot.BusName { + // The event's detail is authoritative even when libatspi still + // caches the previous SELECTED state on the first visit. + eventType, snapshot.Selected = ActiveDescendantEvent, true + } + } + } + // Chromium can drop ACTIVE from its visible main frame while a tiny + // same-process sibling claims it. On X11, the correlated foreground + // window is the stronger ownership check performed below. Keep the + // AT-SPI state filter when no X11 ownership data is available. + progressUpdate := snapshot.Role == "progress bar" && (eventType == ValueChangedEvent || eventType == AccessibleValueEvent) + inactiveProgress := progressUpdate && !adapter.Foreground().Client.Known && C.cthulhu_in_inactive_window(event.source) != 0 + if webNotification == nil && !progressUpdate && !adapter.Foreground().Client.Known && eventType != WindowCreateEvent && eventType != WindowActivatedEvent && + eventType != WindowDeactivatedEvent && eventType != WindowDestroyedEvent && !snapshot.AutocompletePopup && + C.cthulhu_in_inactive_window(event.source) != 0 { + C.g_free(C.gpointer(payload)) + if ownedTarget { + C.g_object_unref(C.gpointer(target)) + } + return + } + var chromeFocus ObjectID + if isDocumentLifecycleEvent(eventType) || eventType == BusyStateEvent { + chromeFocus = adapter.focusedChrome(snapshot.ID()) + } + + focusEvent := NewEventWithPayload( + eventType, + snapshot, + C.GoString(payload), + ) + if eventType != nativeEventType { + focusEvent.NativeType = nativeEventType + } + focusEvent.Detail1 = int(C.cthulhu_event_detail1(event)) + focusEvent.WebNotification = webNotification + focusEvent.PopupFor = popupFor + adapter.enrichNativeWindowEvent(event, target, eventType, snapshot, &focusEvent) + if inactiveProgress { + focusEvent.ForegroundMismatch = true + } + if !focusEvent.Window.Valid() && (eventType == WindowActivatedEvent || eventType == WindowDeactivatedEvent || eventType == WindowDestroyedEvent) { + focusEvent.Window = originID + } + if !focusEvent.ForegroundMismatch && !snapshot.Defunct && snapshot.Role != "invalid" { + if shouldRetainNativeFocus(eventType, focusEvent.Detail1, chromeFocus) && + !(eventType == SelectionChangedEvent && focusEvent.Source.LibreOffice != nil && focusEvent.Source.LibreOffice.InSpreadsheet) { + adapter.rememberNativeFocus(target, snapshot.ID()) + } + } + focusEvent.FocusOutsideDocument = chromeFocus + if eventType == DocumentLoadCompleteEvent { + uri := C.cthulhu_document_uri(event.source) + if uri != nil { + if parsed, err := url.Parse(C.GoString(uri)); err == nil { + focusEvent.DocumentFragment = sanitizeSnapshotField(parsed.Fragment) + } + C.g_free(C.gpointer(uri)) + } + } + focusEvent.SnapshotDuration = time.Since(snapshotStarted) + bit := documentNavigationEchoBit(focusEvent, adapter.navigationCaretOffset, adapter.navigationSelectionOffsets) + if adapter.navigationEcho[snapshot.ID()]&bit != 0 { + focusEvent.NavigationEcho = true + adapter.navigationEcho[snapshot.ID()] &^= bit + } else if eventType == CaretEvent || eventType == FocusEvent || eventType == FocusedStateEvent { + clear(adapter.navigationEcho) + } + focusEvent.OriginPath = sanitizeSnapshotField(C.GoString(C.cthulhu_accessible_path(event.source))) + if eventType == ActiveDescendantEvent && inlineMenuID.Valid() { + focusEvent.OriginPath = inlineMenuID.Path + } + C.g_free(C.gpointer(payload)) + if ownedTarget { + C.g_object_unref(C.gpointer(target)) + } + + adapter.enqueueSecureEvent(focusEvent, secureEpoch) +} diff --git a/internal/atspi/adapter_event_filter_native.go b/internal/atspi/adapter_event_filter_native.go new file mode 100644 index 0000000..f5b9ea9 --- /dev/null +++ b/internal/atspi/adapter_event_filter_native.go @@ -0,0 +1,71 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +// Reject routine background updates before resolving a selected descendant or +// capturing text, attributes, values and geometry. Global lifecycle events and +// supported notifications retain their existing handling. No new ownership is +// inferred from a background control's FOCUSED or SELECTED state. +func (adapter *Adapter) filterNativeBackgroundEvent(event *C.AtspiEvent, eventType string, origin ObjectID, webNotification bool) bool { + switch eventType { + case WindowCreateEvent, WindowActivatedEvent, WindowDeactivatedEvent, WindowDestroyedEvent, DefunctStateEvent: + return false + } + foreground := adapter.Foreground() + if !foreground.Client.Known || webNotification { + return false + } + // This reads libatspi's cached role/application name only. Missing metadata + // takes the established path so a newly published alert is not lost. + if C.cthulhu_may_be_background_notification(event.source) != 0 { + return false + } + if foreground.Client.Window == 0 || adapter.foregroundWindow.Valid() && origin.BusName != adapter.foregroundWindow.BusName { + return true + } + window := C.cthulhu_window_ancestor(event.source) + if window == nil { + // Chromium can detach its retained document while replacing the frame. + // The existing recovery path must resolve that association. + return false + } + defer C.g_object_unref(C.gpointer(window)) + focusedMenuItem := false + if eventType == FocusEvent || eventType == FocusedStateEvent && event.detail1 != 0 { + switch C.atspi_accessible_get_role(event.source, nil) { + case C.ATSPI_ROLE_MENU_ITEM, C.ATSPI_ROLE_CHECK_MENU_ITEM, C.ATSPI_ROLE_RADIO_MENU_ITEM: + focusedMenuItem = true + } + } + if adapter.matchForeground(window, nativeObjectID(window), nil, focusedMenuItem) { + return false + } + if origin.BusName == adapter.foregroundWindow.BusName { + // Browser suggestions and tooltips can occupy a different top-level + // without taking X11 focus. Preserve their existing event-loop checks; + // a popup-for relation alone never grants presentation ownership here. + role := C.atspi_accessible_get_role(event.source, nil) + if eventType == ShowingStateEvent && role == C.ATSPI_ROLE_TOOL_TIP { + return false + } + switch role { + case C.ATSPI_ROLE_LIST, C.ATSPI_ROLE_LIST_BOX, C.ATSPI_ROLE_LIST_ITEM, + C.ATSPI_ROLE_MENU, C.ATSPI_ROLE_MENU_ITEM, C.ATSPI_ROLE_PUSH_BUTTON, C.ATSPI_ROLE_TOGGLE_BUTTON: + if popupFor := C.cthulhu_autocomplete_popup_target(event.source); popupFor != nil { + id := nativeObjectID(popupFor) + C.g_object_unref(C.gpointer(popupFor)) + if id.Valid() && id.BusName == origin.BusName { + return false + } + } + } + } + return true +} diff --git a/internal/atspi/adapter_events.c b/internal/atspi/adapter_events.c new file mode 100644 index 0000000..8303be8 --- /dev/null +++ b/internal/atspi/adapter_events.c @@ -0,0 +1,782 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "adapter_native.h" + +extern void cthulhuAtspiEventCallback(AtspiEvent *event, void *userData); +extern void cthulhuAtspiTreeCaptureCallback(void *userData); +extern void cthulhuAtspiForegroundCallback(void *userData); +static gboolean foreground_tick(gpointer data) { cthulhuAtspiForegroundCallback(data); return G_SOURCE_CONTINUE; } +guint start_foreground_timer(gpointer data) { return g_timeout_add(50, foreground_tick, data); } + +const gchar *cthulhu_event_type(AtspiEvent *event) { + return event->type; +} + +gint cthulhu_event_detail1(AtspiEvent *event) { + return event->detail1; +} + +gchar *cthulhu_document_uri(AtspiAccessible *source) { + AtspiDocument *document = atspi_accessible_get_document_iface(source); + if (document == NULL) return NULL; + GError *error = NULL; + gchar *uri = atspi_document_get_attribute_value(document, "DocURL", &error); + if (error != NULL) { + g_clear_error(&error); + g_free(uri); + uri = NULL; + } + if (uri == NULL || *uri == '\0') { + g_free(uri); + uri = atspi_document_get_attribute_value(document, "URI", &error); + if (error != NULL) { + g_clear_error(&error); + g_free(uri); + uri = NULL; + } + } + g_object_unref(document); + return uri; +} + +gchar *cthulhu_event_payload(AtspiEvent *event) { + if (!G_IS_VALUE(&event->any_data) || !G_VALUE_HOLDS_STRING(&event->any_data)) { + return NULL; + } + return g_value_dup_string(&event->any_data); +} + +gchar *cthulhu_live_attribute(AtspiAccessible *source, const gchar *key) { + GError *error = NULL; + GHashTable *attributes = atspi_accessible_get_attributes(source, &error); + if (error != NULL) g_clear_error(&error); + if (attributes == NULL) return NULL; + gchar *value = g_strdup(g_hash_table_lookup(attributes, key)); + g_hash_table_unref(attributes); + return value; +} + +cthulhu_live_properties cthulhu_capture_live_properties(AtspiAccessible *source) { + cthulhu_live_properties properties = {0}; + GError *error = NULL; + GHashTable *attributes = atspi_accessible_get_attributes(source, &error); + if (error != NULL) g_clear_error(&error); + if (attributes == NULL) return properties; + properties.politeness = g_strdup(g_hash_table_lookup(attributes, "container-live")); + properties.atomic = g_strcmp0(g_hash_table_lookup(attributes, "container-atomic"), "true") == 0; + properties.busy = g_strcmp0(g_hash_table_lookup(attributes, "container-busy"), "true") == 0; + g_hash_table_unref(attributes); + return properties; +} + +// container-atomic is inherited. Chromium also publishes atomic=false on +// ordinary descendants, so only atomic=true identifies an enclosing region. +// The caller first checks the source's effective container-atomic attribute. +gchar *cthulhu_atomic_live_content(AtspiAccessible *source) { + AtspiAccessible *current = g_object_ref(source); + for (guint depth = 0; current != NULL && depth < 64; depth++) { + gchar *atomic = cthulhu_live_attribute(current, "atomic"); + gboolean boundary = g_strcmp0(atomic, "true") == 0; + g_free(atomic); + AtspiRole role = atspi_accessible_get_role(current, NULL); + if (boundary) { + gchar *content = cthulhu_live_content(current); + g_object_unref(current); + return content; + } + if (role == ATSPI_ROLE_DOCUMENT_WEB || role == ATSPI_ROLE_DOCUMENT_FRAME) { + g_object_unref(current); + return cthulhu_live_content(source); + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, NULL); + g_object_unref(current); + current = parent; + } + if (current != NULL) g_object_unref(current); + return NULL; +} + +AtspiAccessible *cthulhu_busy_live_container(AtspiAccessible *source) { + AtspiAccessible *current = g_object_ref(source); + for (guint depth = 0; current != NULL && depth < 64; depth++) { + AtspiStateSet *states = atspi_accessible_get_state_set(current); + gboolean busy = states != NULL && atspi_state_set_contains(states, ATSPI_STATE_BUSY); + if (states != NULL) g_object_unref(states); + if (busy) return current; + AtspiRole role = atspi_accessible_get_role(current, NULL); + if (role == ATSPI_ROLE_DOCUMENT_WEB || role == ATSPI_ROLE_DOCUMENT_FRAME) { + g_object_unref(current); + return NULL; + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, NULL); + g_object_unref(current); + current = parent; + } + if (current != NULL) g_object_unref(current); + return NULL; +} + +AtspiAccessible *cthulhu_event_active_descendant(AtspiEvent *event) { + if (!G_IS_VALUE(&event->any_data) || !G_VALUE_HOLDS_OBJECT(&event->any_data)) { + return NULL; + } + GObject *object = g_value_get_object(&event->any_data); + if (object == NULL || !ATSPI_IS_ACCESSIBLE(object)) { + return NULL; + } + return ATSPI_ACCESSIBLE(object); +} + +AtspiAccessible *cthulhu_selected_child(AtspiAccessible *source) { + AtspiSelection *selection = atspi_accessible_get_selection_iface(source); + if (selection == NULL) { + return NULL; + } + GError *error = NULL; + AtspiAccessible *child = atspi_selection_get_selected_child(selection, 0, &error); + g_object_unref(selection); + if (error != NULL) { + g_error_free(error); + return NULL; + } + return child; +} + +// GtkTreeView can override its role to LIST while retaining table cells and +// table selection. Ordinary lists and browser content keep their own policy. +gboolean cthulhu_is_gtk_list_table(AtspiAccessible *source) { + if (atspi_accessible_get_role(source, NULL) != ATSPI_ROLE_LIST) return FALSE; + AtspiTable *table = atspi_accessible_get_table_iface(source); + if (table == NULL) return FALSE; + g_object_unref(table); + gchar *toolkit = atspi_accessible_get_toolkit_name(source, NULL); + gboolean matches = g_ascii_strcasecmp(toolkit != NULL ? toolkit : "", "gtk") == 0; + g_free(toolkit); + return matches; +} + +// Selection counts cells, so a single GTK row with two columns already has +// two selected children. Query the table's selected rows before treating its +// first selected cell as the focus target. +AtspiAccessible *cthulhu_table_selected_child(AtspiAccessible *source) { + AtspiTable *table = atspi_accessible_get_table_iface(source); + if (table == NULL) return cthulhu_selected_child(source); + GError *error = NULL; + gint count = atspi_table_get_n_selected_rows(table, &error); + g_object_unref(table); + gboolean ambiguous = error == NULL && count > 1; + if (error != NULL) { + g_error_free(error); + } + return ambiguous ? NULL : cthulhu_selected_child(source); +} + +// Resolve the focused descendant at a window-activation boundary. Providers +// such as Steam's Chromium UI can activate a frame without emitting a usable +// object-focus event. Keep the synchronous callback work bounded so a broken +// or unusually large accessible tree cannot hold the AT-SPI event loop +// indefinitely. +typedef gboolean (*cthulhu_descendant_matcher)(AtspiAccessible *source); + +static gboolean cthulhu_is_focused_descendant(AtspiAccessible *source) { + AtspiStateSet *states = atspi_accessible_get_state_set(source); + gboolean matches = states != NULL && + atspi_state_set_contains(states, ATSPI_STATE_FOCUSED) && + !atspi_state_set_contains(states, ATSPI_STATE_DEFUNCT); + if (states != NULL) g_object_unref(states); + return matches; +} + +static gboolean cthulhu_is_showing_web_document(AtspiAccessible *source) { + GError *error = NULL; + AtspiRole role = atspi_accessible_get_role(source, &error); + if (error != NULL) { + g_clear_error(&error); + return FALSE; + } + if (role != ATSPI_ROLE_DOCUMENT_WEB && role != ATSPI_ROLE_DOCUMENT_FRAME && + role != ATSPI_ROLE_EMBEDDED) return FALSE; + AtspiStateSet *states = atspi_accessible_get_state_set(source); + gboolean matches = states != NULL && + atspi_state_set_contains(states, ATSPI_STATE_SHOWING) && + !atspi_state_set_contains(states, ATSPI_STATE_DEFUNCT); + if (states != NULL) g_object_unref(states); + return matches; +} + +static AtspiAccessible *cthulhu_find_matching_descendant( + AtspiAccessible *current, guint *visited, guint depth, + cthulhu_descendant_matcher matches) { + if (current == NULL || *visited >= 1024 || depth >= 128) return NULL; + (*visited)++; + if (matches(current)) return g_object_ref(current); + + GError *error = NULL; + gint childCount = atspi_accessible_get_child_count(current, &error); + if (error != NULL) { + g_clear_error(&error); + return NULL; + } + for (gint index = 0; index < childCount && *visited < 1024; index++) { + AtspiAccessible *child = atspi_accessible_get_child_at_index(current, index, &error); + if (error != NULL) { + g_clear_error(&error); + continue; + } + if (child == NULL) continue; + AtspiAccessible *result = cthulhu_find_matching_descendant( + child, visited, depth + 1, matches); + g_object_unref(child); + if (result != NULL) return result; + } + return NULL; +} + +static AtspiAccessible *cthulhu_matching_descendant( + AtspiAccessible *window, cthulhu_descendant_matcher matches) { + if (window == NULL) return NULL; + guint visited = 0; + GError *error = NULL; + gint childCount = atspi_accessible_get_child_count(window, &error); + if (error != NULL) { + g_clear_error(&error); + return NULL; + } + for (gint index = 0; index < childCount && visited < 1024; index++) { + AtspiAccessible *child = atspi_accessible_get_child_at_index(window, index, &error); + if (error != NULL) { + g_clear_error(&error); + continue; + } + if (child == NULL) continue; + AtspiAccessible *result = cthulhu_find_matching_descendant(child, &visited, 0, matches); + g_object_unref(child); + if (result != NULL) return result; + } + return NULL; +} + +void cthulhu_refresh_frame_children(AtspiAccessible *window) { + // Chromium may advertise a socket-backed child before its accessibility + // tree is initialized. Reading frame attributes activates the child tree; + // clear the stale child cache before asking for descendants. + gchar *toolkit = atspi_accessible_get_toolkit_name(window, NULL); + gboolean chromium = g_strcmp0(toolkit, "Chromium") == 0; + g_free(toolkit); + if (!chromium) return; + + GError *attributesError = NULL; + GHashTable *attributes = atspi_accessible_get_attributes(window, &attributesError); + if (attributesError != NULL) g_clear_error(&attributesError); + if (attributes != NULL) g_hash_table_unref(attributes); + atspi_accessible_clear_cache_single(window); +} + +static AtspiAccessible *cthulhu_collection_descendant(AtspiAccessible *window, + gboolean webDocument, gboolean *answered) { + *answered = FALSE; + AtspiCollection *collection = atspi_accessible_get_collection_iface(window); + if (collection != NULL) { + AtspiStateSet *states = atspi_state_set_new(NULL); + atspi_state_set_add(states, webDocument ? ATSPI_STATE_SHOWING : ATSPI_STATE_FOCUSED); + GArray *roles = NULL; + if (webDocument) { + roles = g_array_new(FALSE, FALSE, sizeof(AtspiRole)); + AtspiRole documentRoles[] = {ATSPI_ROLE_DOCUMENT_WEB, + ATSPI_ROLE_DOCUMENT_FRAME, ATSPI_ROLE_EMBEDDED}; + g_array_append_vals(roles, documentRoles, G_N_ELEMENTS(documentRoles)); + } + AtspiMatchRule *rule = atspi_match_rule_new(states, + ATSPI_Collection_MATCH_ALL, NULL, ATSPI_Collection_MATCH_ALL, + roles, webDocument ? ATSPI_Collection_MATCH_ANY : ATSPI_Collection_MATCH_ALL, NULL, + ATSPI_Collection_MATCH_ALL, FALSE); + GError *error = NULL; + GArray *matches = atspi_collection_get_matches(collection, rule, + ATSPI_Collection_SORT_ORDER_CANONICAL, 1, TRUE, &error); + AtspiAccessible *target = NULL; + *answered = error == NULL && matches != NULL; + if (error == NULL && matches != NULL && matches->len > 0) { + AtspiAccessible *candidate = g_array_index(matches, AtspiAccessible *, 0); + if (candidate != NULL) { + if (webDocument ? cthulhu_is_showing_web_document(candidate) : + cthulhu_is_focused_descendant(candidate)) { + target = g_object_ref(candidate); + } + } + } + if (error != NULL) g_clear_error(&error); + if (matches != NULL) { + // Collection results own each accessible as well as the array. + // Keep only the separate reference returned as target. + for (guint index = 0; index < matches->len; index++) { + AtspiAccessible *match = g_array_index(matches, AtspiAccessible *, index); + if (match != NULL) g_object_unref(match); + } + g_array_unref(matches); + } + g_object_unref(rule); + g_object_unref(states); + if (roles != NULL) g_array_unref(roles); + g_object_unref(collection); + return target; + } + return NULL; +} + +AtspiAccessible *cthulhu_focused_descendant(AtspiAccessible *window) { + // An empty successful Collection reply is conclusive. GTK briefly has + // no focused child when a combo popup closes; walking the entire window + // then delays the focus event which is already waiting to be processed. + gboolean answered; + AtspiAccessible *target = cthulhu_collection_descendant(window, FALSE, &answered); + if (answered) return target; + return cthulhu_matching_descendant(window, cthulhu_is_focused_descendant); +} + +AtspiAccessible *cthulhu_showing_web_document(AtspiAccessible *window) { + gboolean answered; + AtspiAccessible *target = cthulhu_collection_descendant(window, TRUE, &answered); + if (answered) return target; + return cthulhu_matching_descendant(window, cthulhu_is_showing_web_document); +} + +// Return the autocomplete entry named by a popup-for relation on this object +// or an ancestor. The caller owns the returned reference. +AtspiAccessible *cthulhu_autocomplete_popup_target(AtspiAccessible *source) { + AtspiAccessible *current = g_object_ref(source); + for (int depth = 0; current != NULL && depth < 16; depth++) { + AtspiRole role = atspi_accessible_get_role(current, NULL); + if (role == ATSPI_ROLE_DOCUMENT_WEB || role == ATSPI_ROLE_DOCUMENT_FRAME || role == ATSPI_ROLE_APPLICATION) { + g_object_unref(current); + return NULL; + } + GArray *relations = atspi_accessible_get_relation_set(current, NULL); + AtspiAccessible *found = NULL; + if (relations != NULL) { + for (guint i = 0; i < relations->len && found == NULL; i++) { + AtspiRelation *relation = g_array_index(relations, AtspiRelation *, i); + if (atspi_relation_get_relation_type(relation) != ATSPI_RELATION_POPUP_FOR) continue; + for (gint j = 0; j < atspi_relation_get_n_targets(relation); j++) { + AtspiAccessible *target = atspi_relation_get_target(relation, j); + if (target != NULL) { + AtspiRole targetRole = atspi_accessible_get_role(target, NULL); + AtspiStateSet *states = atspi_accessible_get_state_set(target); + gboolean autocomplete = targetRole == ATSPI_ROLE_AUTOCOMPLETE || (targetRole == ATSPI_ROLE_ENTRY && states != NULL && atspi_state_set_contains(states, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION)); + if (states != NULL) g_object_unref(states); + if (autocomplete) found = target; + else g_object_unref(target); + } + if (found != NULL) break; + } + } + for (guint i = 0; i < relations->len; i++) { + g_object_unref(g_array_index(relations, AtspiRelation *, i)); + } + g_array_unref(relations); + } + if (found != NULL) { g_object_unref(current); return found; } + AtspiAccessible *parent = atspi_accessible_get_parent(current, NULL); + g_object_unref(current); + current = parent; + } + if (current != NULL) g_object_unref(current); + return NULL; +} + +AtspiAccessible *cthulhu_combo_ancestor(AtspiAccessible *source) { + if (source == NULL) return NULL; + GError *error = NULL; + AtspiRole source_role = atspi_accessible_get_role(source, &error); + if (error != NULL) { + g_error_free(error); + return NULL; + } + if (source_role != ATSPI_ROLE_TOGGLE_BUTTON) return NULL; + + AtspiAccessible *current = g_object_ref(source); + for (int depth = 0; current != NULL && depth < 4; depth++) { + error = NULL; + AtspiRole role = atspi_accessible_get_role(current, &error); + if (error != NULL) { + g_error_free(error); + g_object_unref(current); + return NULL; + } + if (role == ATSPI_ROLE_COMBO_BOX) { + return current; + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, &error); + g_object_unref(current); + if (error != NULL) { + g_error_free(error); + return NULL; + } + current = parent; + } + if (current != NULL) { + g_object_unref(current); + } + return NULL; +} + +// Announce only a showing top-level document in the active window. +// Background tabs and embedded frame loads must not interrupt the user. +gboolean cthulhu_active_document(AtspiAccessible *source) { + if (source == NULL) return FALSE; + AtspiStateSet *states = atspi_accessible_get_state_set(source); + gboolean showing = states != NULL && atspi_state_set_contains(states, ATSPI_STATE_SHOWING); + if (states != NULL) g_object_unref(states); + if (!showing) return FALSE; + AtspiAccessible *current = g_object_ref(source); + for (int depth = 0; current != NULL && depth < 256; depth++) { + GError *error = NULL; + AtspiRole role = atspi_accessible_get_role(current, &error); + if (error != NULL) { g_error_free(error); g_object_unref(current); return FALSE; } + gboolean document = role == ATSPI_ROLE_DOCUMENT_WEB || role == ATSPI_ROLE_DOCUMENT_FRAME || role == ATSPI_ROLE_EMBEDDED; + if ((depth == 0 && !document) || (depth > 0 && document)) { + g_object_unref(current); + return FALSE; + } + if (role == ATSPI_ROLE_FRAME || role == ATSPI_ROLE_WINDOW) { + states = atspi_accessible_get_state_set(current); + gboolean active = states != NULL && atspi_state_set_contains(states, ATSPI_STATE_ACTIVE); + if (states != NULL) g_object_unref(states); + g_object_unref(current); + return active; + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, &error); + g_object_unref(current); + if (error != NULL) { + g_error_free(error); + if (parent != NULL) g_object_unref(parent); + return FALSE; + } + current = parent; + } + if (current != NULL) g_object_unref(current); + return FALSE; +} + +gboolean cthulhu_in_active_document(AtspiAccessible *source) { + AtspiAccessible *current = source != NULL ? g_object_ref(source) : NULL; + AtspiAccessible *document = NULL; + for (int depth = 0; current != NULL && depth < 256; depth++) { + AtspiRole role = atspi_accessible_get_role(current, NULL); + if (role == ATSPI_ROLE_DOCUMENT_WEB || role == ATSPI_ROLE_DOCUMENT_FRAME) { + if (document != NULL) g_object_unref(document); + document = g_object_ref(current); + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, NULL); + g_object_unref(current); + current = parent; + } + if (current != NULL) g_object_unref(current); + if (document == NULL) return FALSE; + gboolean active = cthulhu_active_document(document); + g_object_unref(document); + return active; +} + + +// Some applications continue emitting focus and text events after their X11 +// window loses activation. Check the containing top-level window: an embedded +// web dialog need not carry ACTIVE even when its frame is active. Missing state +// is inconclusive. +gboolean cthulhu_in_inactive_window(AtspiAccessible *source) { + AtspiAccessible *window = cthulhu_window_ancestor(source); + if (window == NULL) return FALSE; + AtspiStateSet *states = atspi_accessible_get_state_set(window); + gboolean inactive = states != NULL && !atspi_state_set_contains(states, ATSPI_STATE_ACTIVE); + if (states != NULL) g_object_unref(states); + g_object_unref(window); + return inactive; +} + +// GTK menus can live in their own AT-SPI window while X11 continues to name +// the invoking application window as the foreground client. Python Cthulhu +// accepts an active, showing window with one menu child in this situation. +gboolean cthulhu_active_menu_window(AtspiAccessible *window) { + if (window == NULL) return FALSE; + AtspiRole role = atspi_accessible_get_role(window, NULL); + if (role != ATSPI_ROLE_WINDOW && role != ATSPI_ROLE_FRAME) return FALSE; + AtspiStateSet *states = atspi_accessible_get_state_set(window); + gboolean active = states != NULL && atspi_state_set_contains(states, ATSPI_STATE_ACTIVE); + gboolean showing = states != NULL && atspi_state_set_contains(states, ATSPI_STATE_SHOWING); + if (states != NULL) g_object_unref(states); + if (!active || !showing || atspi_accessible_get_child_count(window, NULL) != 1) return FALSE; + AtspiAccessible *child = atspi_accessible_get_child_at_index(window, 0, NULL); + if (child == NULL) return FALSE; + AtspiRole childRole = atspi_accessible_get_role(child, NULL); + gboolean menu = childRole == ATSPI_ROLE_MENU; + if (role == ATSPI_ROLE_FRAME && childRole == ATSPI_ROLE_MENU_BAR) { + gchar *name = atspi_accessible_get_name(window, NULL); + menu = name == NULL || *name == '\0'; + g_free(name); + } + g_object_unref(child); + return menu; +} + +static gboolean cthulhu_is_menu(AtspiAccessible *source) { + return atspi_accessible_get_role(source, NULL) == ATSPI_ROLE_MENU; +} + +AtspiAccessible *cthulhu_popup_menu_target(AtspiAccessible *window) { + if (!cthulhu_active_menu_window(window)) return NULL; + AtspiAccessible *menu = cthulhu_matching_descendant(window, cthulhu_is_menu); + if (menu == NULL) return NULL; + AtspiAccessible *selected = cthulhu_selected_child(menu); + if (selected != NULL) { + g_object_unref(menu); + return selected; + } + return menu; +} + +// Compound native menu rows can report selection on an inner control without +// changing the menu's selected child. Return its menu only when a menu-item +// ancestor precedes that menu, and the chain reaches a native window without +// entering document content. The caller owns the returned reference. +AtspiAccessible *cthulhu_inline_menu_container(AtspiAccessible *source) { + AtspiAccessible *current = atspi_accessible_get_parent(source, NULL); + AtspiAccessible *menu = NULL; + gboolean inRow = FALSE; + for (int depth = 0; current != NULL && depth < 32; depth++) { + GError *error = NULL; + AtspiRole role = atspi_accessible_get_role(current, &error); + if (error != NULL) { g_error_free(error); break; } + if (role == ATSPI_ROLE_DOCUMENT_WEB || role == ATSPI_ROLE_DOCUMENT_FRAME || + role == ATSPI_ROLE_EMBEDDED || role == ATSPI_ROLE_APPLICATION) break; + if (role == ATSPI_ROLE_FRAME || role == ATSPI_ROLE_WINDOW) { + g_object_unref(current); + return menu; + } + if (menu == NULL) { + if (role == ATSPI_ROLE_MENU) { + if (!inRow) break; // Ordinary menu entries keep their existing events. + AtspiStateSet *states = atspi_accessible_get_state_set(current); + gboolean showing = states != NULL && + atspi_state_set_contains(states, ATSPI_STATE_SHOWING) && + !atspi_state_set_contains(states, ATSPI_STATE_DEFUNCT); + if (states != NULL) g_object_unref(states); + if (!showing) break; + menu = g_object_ref(current); + } else if (role == ATSPI_ROLE_MENU_ITEM || role == ATSPI_ROLE_CHECK_MENU_ITEM || + role == ATSPI_ROLE_RADIO_MENU_ITEM) { + inRow = TRUE; + } + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, &error); + g_object_unref(current); + current = parent; + if (error != NULL) { g_error_free(error); break; } + } + if (current != NULL) g_object_unref(current); + if (menu != NULL) g_object_unref(menu); + return NULL; +} + +const gchar *cthulhu_accessible_path(AtspiAccessible *source) { + return source != NULL ? ATSPI_OBJECT(source)->path : NULL; +} + +const gchar *cthulhu_accessible_bus_name(AtspiAccessible *source) { + if (source == NULL || ATSPI_OBJECT(source)->app == NULL) { + return NULL; + } + return ATSPI_OBJECT(source)->app->bus_name; +} + +// Cache-only classification: never contact an unrelated provider just to +// decide whether its event can be ignored. Unknown cache entries retain the +// ordinary validation path, including native alerts and notification daemons. +gboolean cthulhu_may_be_background_notification(AtspiAccessible *source) { + if (source == NULL || !(source->cached_properties & ATSPI_CACHE_ROLE)) return TRUE; + if (source->role == ATSPI_ROLE_ALERT || source->role == ATSPI_ROLE_NOTIFICATION) return TRUE; + AtspiApplication *application = source->parent.app; + AtspiAccessible *root = application != NULL ? application->root : NULL; + if (root == NULL || !(root->cached_properties & ATSPI_CACHE_NAME)) return TRUE; + const gchar *name = root->name != NULL ? root->name : ""; + return g_ascii_strcasecmp(name, "notification-daemon") == 0 || + g_ascii_strcasecmp(name, "mate-notification-daemon") == 0 || + g_ascii_strcasecmp(name, "xfce4-notifyd") == 0 || + g_ascii_strcasecmp(name, "notify-osd") == 0; +} + +// Return the containing top-level window. An embedded web dialog is part of +// its frame; a standalone dialog directly below the application owns itself. +AtspiAccessible *cthulhu_window_ancestor(AtspiAccessible *source) { + if (source == NULL) return NULL; + AtspiAccessible *current = g_object_ref(source); + for (gint depth = 0; current != NULL && depth < 256; depth++) { + GError *error = NULL; + AtspiRole role = atspi_accessible_get_role(current, &error); + if (error != NULL) { + g_clear_error(&error); + g_object_unref(current); + return NULL; + } + if (role == ATSPI_ROLE_FRAME || role == ATSPI_ROLE_WINDOW) { + return current; + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, &error); + // Qt can expose a top-level QWidget as a filler rather than a frame. + // Python's Qt utilities use the application-child boundary here. + if (parent != NULL && error == NULL && role != ATSPI_ROLE_APPLICATION && + atspi_accessible_get_role(parent, NULL) == ATSPI_ROLE_APPLICATION) { + g_object_unref(parent); + return current; + } + g_object_unref(current); + if (error != NULL) { + g_clear_error(&error); + if (parent != NULL) g_object_unref(parent); + return NULL; + } + current = parent; + } + if (current != NULL) g_object_unref(current); + return NULL; +} + +// Editors can retain native focus while their paragraphs emit typing/caret/ +// selection events. Use the nearest focusable writable ancestor or editable +// document. Never cross a document, password, or read-only editor boundary. +AtspiAccessible *cthulhu_editable_root(AtspiAccessible *source) { + AtspiAccessible *current = source != NULL ? g_object_ref(source) : NULL; + for (gint depth = 0; current != NULL && depth < 64; depth++) { + AtspiRole role = atspi_accessible_get_role(current, NULL); + if (role == ATSPI_ROLE_FRAME || role == ATSPI_ROLE_WINDOW || role == ATSPI_ROLE_APPLICATION) break; + AtspiStateSet *states = atspi_accessible_get_state_set(current); + gboolean blocked = states == NULL || role == ATSPI_ROLE_PASSWORD_TEXT || + atspi_state_set_contains(states, ATSPI_STATE_READ_ONLY) || + atspi_state_set_contains(states, ATSPI_STATE_DEFUNCT); + gboolean editable = !blocked && atspi_state_set_contains(states, ATSPI_STATE_EDITABLE); + gboolean focusable = !blocked && atspi_state_set_contains(states, ATSPI_STATE_FOCUSABLE); + if (states != NULL) g_object_unref(states); + gboolean document = role == ATSPI_ROLE_DOCUMENT_WEB || role == ATSPI_ROLE_DOCUMENT_FRAME; + if (editable && (focusable || document)) return current; + if (blocked || document || focusable) break; + AtspiAccessible *parent = atspi_accessible_get_parent(current, NULL); + g_object_unref(current); + current = parent; + } + if (current != NULL) g_object_unref(current); + return NULL; +} + +// Chromium can detach an existing document from its frame's AT-SPI parent +// chain while returning to a tab. Its document identity remains usable. +AtspiAccessible *cthulhu_document_ancestor(AtspiAccessible *source) { + AtspiAccessible *current = source != NULL ? g_object_ref(source) : NULL; + AtspiAccessible *document = NULL; + for (gint depth = 0; current != NULL && depth < 256; depth++) { + AtspiRole role = atspi_accessible_get_role(current, NULL); + if (role == ATSPI_ROLE_DOCUMENT_WEB || role == ATSPI_ROLE_DOCUMENT_FRAME) { + if (document != NULL) g_object_unref(document); + document = g_object_ref(current); + } + AtspiAccessible *parent = atspi_accessible_get_parent(current, NULL); + g_object_unref(current); + current = parent; + } + if (current != NULL) g_object_unref(current); + return document; +} + +static void cthulhu_event_callback(AtspiEvent *event, void *userData) { + cthulhuAtspiEventCallback(event, userData); + // libatspi passes each listener an owned boxed copy. Go retains only + // copied metadata and explicitly referenced accessibles. + if (event != NULL) g_boxed_free(ATSPI_TYPE_EVENT, event); +} + +AtspiEventListenerCB cthulhu_event_callback_pointer(void) { + return cthulhu_event_callback; +} + +static gboolean cthulhu_quit_event_loop(gpointer unused) { + (void) unused; + atspi_event_quit(); + return G_SOURCE_REMOVE; +} + +gboolean cthulhu_request_event_loop_quit(void) { + GSource *source = g_idle_source_new(); + if (source == NULL) { + return FALSE; + } + g_source_set_priority(source, G_PRIORITY_HIGH); + g_source_set_callback(source, cthulhu_quit_event_loop, NULL, NULL); + guint source_id = g_source_attach(source, g_main_context_default()); + g_source_unref(source); + return source_id != 0; +} + +typedef struct { + cthulhu_callback_data *owner; + GSource *source; +} cthulhu_pending_capture; + +static gboolean cthulhu_capture_tree_callback(gpointer userData) { + cthulhu_pending_capture *capture = userData; + cthulhuAtspiTreeCaptureCallback(capture->owner); + return G_SOURCE_REMOVE; +} + +static void cthulhu_capture_destroy(gpointer userData) { + cthulhu_pending_capture *capture = userData; + g_mutex_lock(&capture->owner->mutex); + capture->owner->captures = g_list_remove(capture->owner->captures, capture); + g_mutex_unlock(&capture->owner->mutex); + g_source_unref(capture->source); + g_free(capture); +} + +gboolean cthulhu_request_tree_capture(gpointer userData) { + cthulhu_callback_data *data = userData; + GSource *source = g_idle_source_new(); + if (source == NULL) { + return FALSE; + } + cthulhu_pending_capture *capture = g_new0(cthulhu_pending_capture, 1); + capture->owner = data; + capture->source = source; + g_source_set_priority(source, G_PRIORITY_HIGH); + g_source_set_callback(source, cthulhu_capture_tree_callback, capture, cthulhu_capture_destroy); + g_mutex_lock(&data->mutex); + data->captures = g_list_prepend(data->captures, capture); + guint source_id = g_source_attach(source, g_main_context_default()); + g_mutex_unlock(&data->mutex); + if (source_id == 0) g_source_destroy(source); + return source_id != 0; +} + + + +cthulhu_callback_data *cthulhu_callback_data_new(uintptr_t callback) { + cthulhu_callback_data *data = g_new0(cthulhu_callback_data, 1); + if (data != NULL) { + data->callback = callback; + g_mutex_init(&data->mutex); + } + return data; +} + +uintptr_t cthulhu_callback_value(const cthulhu_callback_data *data) { + return data->callback; +} + +void cthulhu_callback_data_free(cthulhu_callback_data *data) { + if (data == NULL) return; + // Dispatch has stopped and the Go request mutex excludes new sources. + // Destroy notifications remove each source and release its retained ref. + while (data->captures != NULL) { + cthulhu_pending_capture *capture = data->captures->data; + g_source_destroy(capture->source); + } + g_mutex_clear(&data->mutex); + g_free(data); +} diff --git a/internal/atspi/adapter_foreground_native.go b/internal/atspi/adapter_foreground_native.go new file mode 100644 index 0000000..47e7775 --- /dev/null +++ b/internal/atspi/adapter_foreground_native.go @@ -0,0 +1,338 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "runtime/cgo" + "unsafe" +) + +func (adapter *Adapter) Foreground() ForegroundState { + state := adapter.foreground.Load() + if state == nil { + return ForegroundState{} + } + return *state +} +func (adapter *Adapter) ForegroundChanges() <-chan struct{} { return adapter.foregroundChanges } +func (adapter *Adapter) refreshForeground() { + value := adapter.foregroundReader.Read() + previous := adapter.Foreground() + if value == previous.Client { + return + } + state := ForegroundState{Client: value, Epoch: previous.Epoch} + if value.Window != previous.Client.Window || value.PID != previous.Client.PID || value.Known != previous.Client.Known { + clear(adapter.foregroundProcesses) + } + if value.Known != previous.Client.Known || value.Window != previous.Client.Window { + state.Epoch++ + adapter.foregroundWindow = ObjectID{} + adapter.selectedTabWindow = ObjectID{} + adapter.activeDocument = ObjectID{} + adapter.foregroundRecovery = 8 + } + adapter.foreground.Store(&state) + select { + case adapter.foregroundChanges <- struct{}{}: + default: + } +} + +//export cthulhuAtspiForegroundCallback +func cthulhuAtspiForegroundCallback(data unsafe.Pointer) { + handle := cgo.Handle(C.cthulhu_callback_value((*C.cthulhu_callback_data)(data))) + adapter := handle.Value().(*Adapter) + adapter.applySecureReset() + if adapter.secure.Load() { + return + } + adapter.refreshForeground() + adapter.refreshWindowTitle() + if adapter.secureResync.Swap(false) { + adapter.foregroundRecovery = 8 + } + adapter.recoverForeground() +} + +func (adapter *Adapter) matchesForeground(window *C.AtspiAccessible, id ObjectID) bool { + return adapter.matchForeground(window, id, nil, false) +} + +func (adapter *Adapter) matchForeground(window *C.AtspiAccessible, id ObjectID, check *ForegroundCheck, focusedMenuItem bool) bool { + state := adapter.Foreground().Client + if !state.Known { + return true + } + if state.Window == 0 || window == nil { + if check != nil { + check.Reason = "no X11 foreground window or accessible window" + } + return false + } + pid := int(C.atspi_accessible_get_process_id(window, nil)) + if check != nil { + check.AccessiblePID = pid + } + pid = adapter.foregroundProcessID(pid) + if adapter.foregroundWindow.Valid() { + if adapter.foregroundWindow == id { + return true + } + matched := foregroundMenuPopupMatches(state, adapter.foregroundWindow, id, pid, + focusedMenuItem || C.cthulhu_active_menu_window(window) != 0) + if matched { + return true + } + } + // Same-process maximized windows can have identical bounds. As in + // Python canBeActiveWindow(clearCache=True), only correlate a freshly + // active, showing, non-iconified candidate. Never latch the first sibling + // merely because its geometry matches the X11 client. + C.atspi_accessible_clear_cache_single(window) + states := C.atspi_accessible_get_state_set(window) + if states == nil { + if check != nil { + check.Reason = "accessible window state unavailable" + } + return false + } + active := C.atspi_state_set_contains(states, C.ATSPI_STATE_ACTIVE) != 0 + showing := C.atspi_state_set_contains(states, C.ATSPI_STATE_SHOWING) != 0 + iconified := C.atspi_state_set_contains(states, C.ATSPI_STATE_ICONIFIED) != 0 + C.g_object_unref(C.gpointer(states)) + if check != nil { + check.Active, check.Showing, check.Iconified = active, showing, iconified + } + if !active || !showing || iconified { + if check != nil { + check.Reason = "accessible window inactive, hidden, or iconified" + } + return false + } + component := C.atspi_accessible_get_component_iface(window) + if component == nil { + if check != nil { + check.Reason = "accessible window component unavailable" + } + return false + } + bounds := C.atspi_component_get_extents(component, C.ATSPI_COORD_TYPE_SCREEN, nil) + C.g_object_unref(C.gpointer(component)) + if bounds == nil { + if check != nil { + check.Reason = "accessible window bounds unavailable" + } + return false + } + rectangle := Rectangle{X: int32(bounds.x), Y: int32(bounds.y), Width: int32(bounds.width), Height: int32(bounds.height)} + C.g_free(C.gpointer(bounds)) + if check != nil { + check.Bounds = rectangle + } + if !foregroundWindowMatches(state, pid, rectangle) { + if check != nil { + if state.PID > 0 && pid > 0 && state.PID != pid { + check.Reason = "process ID differs" + } else { + check.Reason = "window bounds differ" + } + } + return false + } + // Mozilla can replace its GTK application root with a Gecko root without + // changing the X11 client. Only inspect its window list after fresh state + // and geometry match. Existing siblings cannot retire the previous owner. + if adapter.foregroundWindow.Valid() && !adapter.replacesForegroundWindow(window, id, state.PID, pid) { + if check != nil { + check.Reason = "different accessible window from correlated foreground" + } + return false + } + if adapter.foregroundWindow.Valid() { + adapter.forgetNativeWindowFocus(adapter.foregroundWindow) + adapter.forgetWindowDocuments(adapter.foregroundWindow) + } + adapter.foregroundWindow = id + adapter.foregroundRecovery = 0 + return true +} + +func (adapter *Adapter) replacesForegroundWindow(window *C.AtspiAccessible, id ObjectID, foregroundPID, pid int) bool { + if foregroundPID <= 0 || pid != foregroundPID || id.BusName != adapter.foregroundWindow.BusName { + return false + } + application := C.atspi_accessible_get_parent(window, nil) + if application == nil { + return false + } + defer C.g_object_unref(C.gpointer(application)) + if C.atspi_accessible_get_role(application, nil) != C.ATSPI_ROLE_APPLICATION { + return false + } + // A retired GTK bridge can still answer queries after Gecko registers + // its replacement application. Do not let that detached root reclaim + // the client. GetApplication itself can use libatspi's old root cache. + desktop := C.atspi_get_desktop(0) + if desktop == nil { + return false + } + defer C.g_object_unref(C.gpointer(desktop)) + C.atspi_accessible_clear_cache_single(desktop) + var queryError *C.GError + applications := int(C.atspi_accessible_get_child_count(desktop, &queryError)) + if queryError != nil { + C.g_error_free(queryError) + return false + } + if applications <= 0 || applications > 128 { + return false + } + registered := false + for index := 0; index < applications; index++ { + child := C.atspi_accessible_get_child_at_index(desktop, C.gint(index), &queryError) + if queryError != nil { + C.g_error_free(queryError) + } + if child == nil { + return false + } + matches := nativeObjectID(child) == nativeObjectID(application) + C.g_object_unref(C.gpointer(child)) + if queryError != nil { + return false + } + if matches { + registered = true + break + } + } + if !registered { + return false + } + C.atspi_accessible_clear_cache_single(application) + count := int(C.atspi_accessible_get_child_count(application, &queryError)) + if queryError != nil { + C.g_error_free(queryError) + return false + } + if count <= 0 || count > 128 { + return false + } + windows := make([]ObjectID, 0, count) + for index := 0; index < count; index++ { + child := C.atspi_accessible_get_child_at_index(application, C.gint(index), &queryError) + if queryError != nil { + C.g_error_free(queryError) + } + if child == nil { + return false + } + childID := nativeObjectID(child) + C.g_object_unref(C.gpointer(child)) + if queryError != nil || !childID.Valid() { + return false + } + windows = append(windows, childID) + } + return foregroundWindowReplaced(adapter.foregroundWindow, id, windows) +} + +// Recovery runs only at foreground transitions, off the event consumer. It +// handles returning from an empty workspace when a toolkit retains focus and +// emits no new focused-child event. Searches and retries are bounded. +func (adapter *Adapter) recoverForeground() { + secureEpoch := adapter.secureEpoch.Load() + state := adapter.Foreground() + if adapter.foregroundRecovery == 0 || adapter.recoveringForeground || !state.Client.Known || state.Client.Window == 0 || state.Client.PID <= 0 { + return + } + adapter.foregroundRecovery-- + adapter.recoveringForeground = true + defer func() { adapter.recoveringForeground = false }() + desktop := C.atspi_get_desktop(0) + if desktop == nil { + return + } + defer C.g_object_unref(C.gpointer(desktop)) + count := min(int(C.atspi_accessible_get_child_count(desktop, nil)), 128) + for i := 0; i < count; i++ { + application := C.atspi_accessible_get_child_at_index(desktop, C.gint(i), nil) + if application == nil { + continue + } + pid := int(C.atspi_accessible_get_process_id(application, nil)) + if adapter.foregroundProcessID(pid) != state.Client.PID { + C.g_object_unref(C.gpointer(application)) + continue + } + windows := min(int(C.atspi_accessible_get_child_count(application, nil)), 128) + for j := 0; j < windows; j++ { + window := C.atspi_accessible_get_child_at_index(application, C.gint(j), nil) + if window == nil { + continue + } + if state.Epoch == adapter.Foreground().Epoch && adapter.matchesForeground(window, nativeObjectID(window)) { + target := adapter.libreOfficeFrameTarget(window) + officeFrame := target != nil + if target == nil { + target = C.cthulhu_focused_descendant(window) + } + if target == nil { + target = (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(window))) + } + // Recover the active child just as a normal focus event does. + role := C.atspi_accessible_get_role(target, nil) + var child *C.AtspiAccessible + if role == C.ATSPI_ROLE_TABLE { + child = C.cthulhu_table_selected_child(target) + } + if role == C.ATSPI_ROLE_MENU { + child = C.cthulhu_selected_child(target) + } + if child != nil { + C.g_object_unref(C.gpointer(target)) + target = child + } + snapshot := snapshotFromNativeWithCaret(target, true, false, false, adapter.captureSound.Load(), adapter.captureTextAttributes.Load()) + if officeFrame { + snapshot.ApplicationProcess = adapter.applicationProcess(target) + } + event := NewEvent(WindowActivatedEvent, snapshot) + event.Window = nativeObjectID(window) + name := C.atspi_accessible_get_name(window, nil) + event.WindowTitle = sanitizeSnapshotField(C.GoString(name)) + C.g_free(C.gpointer(name)) + if snapshot.Role == "tree table" || snapshot.Role == "table cell" { + if labels := C.cthulhu_collect_simple_prompt_text(window); labels != nil { + event.WindowMessage = sanitizeSnapshotField(C.GoString(labels)) + C.g_free(C.gpointer(labels)) + } + if event.WindowMessage == "" { + adapter.promptRefreshWindow = event.Window + } + } + event.OriginPath = event.Window.Path + event.Foreground = adapter.Foreground() + adapter.rememberNativeFocus(target, snapshot.ID()) + C.g_object_unref(C.gpointer(target)) + adapter.enqueueSecureEvent(event, secureEpoch) + C.g_object_unref(C.gpointer(window)) + C.g_object_unref(C.gpointer(application)) + return + } + C.g_object_unref(C.gpointer(window)) + } + C.g_object_unref(C.gpointer(application)) + } +} + +// SetSecureInputActive publishes policy to the GLib owner. Native references +// are released there; no caller outside that thread touches AT-SPI objects. diff --git a/internal/atspi/adapter_lifecycle_native.go b/internal/atspi/adapter_lifecycle_native.go new file mode 100644 index 0000000..596ecf6 --- /dev/null +++ b/internal/atspi/adapter_lifecycle_native.go @@ -0,0 +1,252 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + "git.stormux.org/storm/cthulhu/internal/platform/session" + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "runtime" + "runtime/cgo" + "sync" + "unsafe" +) + +// libatspi and its default GLib loop are process globals. Adapters may take +// turns owning them, but must never run concurrently. atspi_exit is reserved +// for process exit: its caches do not support an exit/init cycle. +var nativeAdapterOwner sync.Mutex +var nativeAdapterInit sync.Once +var nativeAdapterInitError error + +func (adapter *Adapter) Start(ctx context.Context) error { + adapter.stopMutex.Lock() + defer adapter.stopMutex.Unlock() + if !adapter.running.CompareAndSwap(false, true) { + return errors.New("AT-SPI adapter already started") + } + if !nativeAdapterOwner.TryLock() { + adapter.running.Store(false) + return errors.New("another AT-SPI adapter is running") + } + + adapter.echoFocus.Store(nil) + adapter.loopError = nil + adapter.stopRequested = false + adapter.loopDone = make(chan struct{}) + setupDone := make(chan error, 1) + go func() { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + defer close(adapter.loopDone) + defer nativeAdapterOwner.Unlock() + if err := adapter.initialize(); err != nil { + setupDone <- err + return + } + // Xwayland only describes X clients. Its empty or stale foreground + // must not veto native Wayland windows; use AT-SPI ownership there. + if !session.Wayland() { + adapter.foregroundReader = xorg.OpenForegroundReader() + } + adapter.promptRefreshWindow = ObjectID{} + adapter.promptScannedWindow = ObjectID{} + adapter.promptScannedEpoch = 0 + adapter.refreshForeground() + adapter.refreshWindowTitle() + timer := C.start_foreground_timer(C.gpointer(adapter.callbackData)) + setupDone <- nil + C.atspi_event_main() + if timer != 0 { + C.g_source_remove(timer) + } + // Deregistration can dispatch queued D-Bus events synchronously. Keep + // foreground state and retained accessibles alive until it finishes. + adapter.loopError = adapter.releaseNativeCallbacks() + adapter.foregroundReader.Close() + adapter.foregroundReader = nil + for _, focus := range adapter.nativeFocus { + C.g_object_unref(C.gpointer(focus.source)) + } + adapter.nativeFocus = nil + adapter.echoFocus.Store(nil) + adapter.libreOfficeHeaders.reset() + for _, known := range adapter.documentWindows { + C.g_object_unref(C.gpointer(known.source)) + } + adapter.documentWindows = nil + adapter.documentWindowIDs = nil + adapter.clearNativeDocument() + adapter.deferredLiveRegions = nil + adapter.clearNativeReview() + adapter.clearMouseApplication() + }() + + select { + case err := <-setupDone: + if err != nil { + <-adapter.loopDone + adapter.running.Store(false) + return err + } + if err := ctx.Err(); err != nil { + C.cthulhu_request_event_loop_quit() + <-adapter.loopDone + adapter.running.Store(false) + return err + } + adapter.ready.Store(true) + return nil + case <-ctx.Done(): + err := <-setupDone + if err != nil { + <-adapter.loopDone + adapter.running.Store(false) + return err + } + C.cthulhu_request_event_loop_quit() + <-adapter.loopDone + adapter.running.Store(false) + return ctx.Err() + } +} + +func (adapter *Adapter) initialize() error { + nativeAdapterInit.Do(func() { + if result := C.atspi_init(); result > 1 { + nativeAdapterInitError = fmt.Errorf("initialize AT-SPI: result %d", int(result)) + } + }) + if nativeAdapterInitError != nil { + return nativeAdapterInitError + } + // libatspi's ordinary default is 800 ms, but its startup grace period is + // much longer. Keep both bounded so a newly connected or wedged provider + // cannot indefinitely hold the event-loop thread during owned-tree capture. + C.atspi_set_timeout(800, 800) + + callbackHandle := cgo.NewHandle(adapter) + callbackData := C.cthulhu_callback_data_new(C.uintptr_t(callbackHandle)) + if callbackData == nil { + callbackHandle.Delete() + return errors.New("allocate AT-SPI callback data") + } + adapter.callbackHandle = callbackHandle + adapter.callbackData = callbackData + // Own one listener for all subscriptions, as Orca does. The callback + // convenience API lost mouse delivery when mixed with object subscriptions + // in the private native probe. + adapter.eventListener = C.atspi_event_listener_new( + C.AtspiEventListenerCB(C.cthulhu_event_callback_pointer()), C.gpointer(callbackData), nil) + if adapter.eventListener == nil { + C.cthulhu_callback_data_free(callbackData) + adapter.callbackHandle = 0 + adapter.callbackData = nil + callbackHandle.Delete() + return errors.New("allocate AT-SPI event listener") + } + + for _, eventType := range eventTypes { + if err := adapter.registerEvent(eventType); err != nil { + if cleanupErr := adapter.releaseNativeCallbacks(); cleanupErr != nil { + err = errors.Join(err, cleanupErr) + } + return err + } + } + + return nil +} + +func (adapter *Adapter) registerEvent(eventType string) error { + nativeEventType := C.CString(eventType) + var registerError *C.GError + registered := C.atspi_event_listener_register(adapter.eventListener, nativeEventType, ®isterError) + C.free(unsafe.Pointer(nativeEventType)) + if registerError != nil { + err := nativeError("register AT-SPI event listener "+eventType, registerError) + C.g_error_free(registerError) + return err + } + if registered == 0 { + return errors.New("register AT-SPI event listener " + eventType) + } + return nil +} + +func (adapter *Adapter) deregisterEvents() error { + var stopErr error + for _, eventType := range eventTypes { + nativeEventType := C.CString(eventType) + var deregisterError *C.GError + C.atspi_event_listener_deregister(adapter.eventListener, nativeEventType, &deregisterError) + C.free(unsafe.Pointer(nativeEventType)) + if deregisterError != nil { + stopErr = errors.Join(stopErr, nativeError("deregister AT-SPI event listener "+eventType, deregisterError)) + C.g_error_free(deregisterError) + } + } + if adapter.eventListener != nil { + C.g_object_unref(C.gpointer(adapter.eventListener)) + adapter.eventListener = nil + } + return stopErr +} + +// Called only by the GLib owner, after dispatch has stopped and request callers +// have been excluded. Destroy pending idle captures before releasing their +// callback data/handle; deregistration prevents later adapters reaching us. +func (adapter *Adapter) releaseNativeCallbacks() error { + err := adapter.deregisterEvents() + C.cthulhu_callback_data_free(adapter.callbackData) + adapter.callbackData = nil + if adapter.callbackHandle != 0 { + adapter.callbackHandle.Delete() + adapter.callbackHandle = 0 + } + for len(adapter.treeRequests) != 0 { + request := <-adapter.treeRequests + request.result <- treeCaptureResult{err: errors.New("AT-SPI adapter stopped")} + } + return err +} + +func (adapter *Adapter) Stop(ctx context.Context) error { + adapter.stopMutex.Lock() + defer adapter.stopMutex.Unlock() + if !adapter.running.Load() { + return nil + } + adapter.ready.Store(false) + + var stopErr error + // AT-SPI documents event-loop quit as an event-handler operation. Schedule + // it on the default GLib context owned by atspi_event_main instead of calling + // it synchronously from this arbitrary shutdown goroutine. + if !adapter.stopRequested { + if C.cthulhu_request_event_loop_quit() == 0 { + stopErr = errors.New("request AT-SPI event loop quit") + } else { + adapter.stopRequested = true + } + } + + select { + case <-adapter.loopDone: + case <-ctx.Done(): + return errors.Join(stopErr, fmt.Errorf("wait for AT-SPI event loop: %w", ctx.Err())) + } + stopErr = errors.Join(stopErr, adapter.loopError) + adapter.running.Store(false) + adapter.invalidateTree() + return stopErr +} diff --git a/internal/atspi/adapter_menu_states.c b/internal/atspi/adapter_menu_states.c new file mode 100644 index 0000000..daa3a20 --- /dev/null +++ b/internal/atspi/adapter_menu_states.c @@ -0,0 +1,48 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "adapter_native.h" + +// Owned by the native accessible, on the AT-SPI GLib thread. No accessible +// references or application labels are retained. Destruction frees the data; +// semantic identity changes and explicit capability removal retire it too. +static const gchar *menu_checkability_key = "cthulhu-menu-checkability"; +enum { CHECKABILITY_INFERRED = 1, CHECKABILITY_EXPLICIT = 2 }; + +void cthulhu_forget_menu_checkability(AtspiAccessible *source) { + if (source != NULL) + g_object_set_data(G_OBJECT(source), menu_checkability_key, NULL); +} + +void cthulhu_note_menu_checkability(AtspiAccessible *source) { + if (source != NULL && + GPOINTER_TO_INT(g_object_get_data(G_OBJECT(source), menu_checkability_key)) != CHECKABILITY_EXPLICIT) + g_object_set_data(G_OBJECT(source), menu_checkability_key, + GINT_TO_POINTER(CHECKABILITY_INFERRED)); +} + +void cthulhu_capture_menu_checkability(AtspiAccessible *source, cthulhu_snapshot *snapshot) { + if (snapshot->defunct || g_strcmp0(snapshot->role, "menu item") != 0) { + cthulhu_forget_menu_checkability(source); + return; + } + if (!snapshot->statesKnown) return; + + gint evidence = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(source), menu_checkability_key)); + if (snapshot->checkable) { + g_object_set_data(G_OBJECT(source), menu_checkability_key, + GINT_TO_POINTER(CHECKABILITY_EXPLICIT)); + } else if (snapshot->checked || snapshot->indeterminate) { + cthulhu_note_menu_checkability(source); + snapshot->checkable = TRUE; + } else if (evidence == CHECKABILITY_INFERRED) { + // Providers such as Qt 5 omit CHECKABLE in both states. Once CHECKED + // or a checked-state event proves this object's capability, retain it + // when the value becomes false. Absence alone proves nothing. + snapshot->checkable = TRUE; + } else { + // A provider which supplied CHECKABLE can explicitly withdraw it. + cthulhu_forget_menu_checkability(source); + } +} diff --git a/internal/atspi/adapter_native.h b/internal/atspi/adapter_native.h new file mode 100644 index 0000000..43f6ce9 --- /dev/null +++ b/internal/atspi/adapter_native.h @@ -0,0 +1,150 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef CTHULHU_ATSPI_NATIVE_H +#define CTHULHU_ATSPI_NATIVE_H + +#include +#include + +typedef struct { + const gchar *busName; + gchar *applicationName; + gchar *name; + gchar *role; + gchar *description; + const gchar *path; + gchar *text; + gint textStartOffset; + gchar *textBeforeCaret; + gchar *caretCharacter; + gboolean autocomplete; + gint headingLevel; + gint positionInSet, setSize; + gboolean visible; + gboolean showing; + gboolean statesKnown; + gboolean active; + gboolean focusable; + gboolean focused; + gboolean hasPopup; + gboolean checkable; + gboolean checked; + gboolean defunct; + gboolean editable; + gboolean expandable; + gboolean expanded; + gboolean indeterminate; + gboolean invalid; + gboolean multiselectable; + gboolean readOnly; + gboolean required; + gboolean selected; + gboolean sensitive; + gboolean sensitiveKnown; + gboolean valueKnown; + gboolean visited; + gboolean explicitName; + gdouble currentValue; + gdouble maximumValue; + gdouble minimumValue; + gdouble minimumIncrement; + gchar *valueText; + gchar *xmlRoles; + gchar *htmlTag; + gchar *elementID; + gboolean supportsClick; + gboolean liveRegion; + gboolean layoutTable; + gint childCount; + gboolean childCountKnown; + gint tableRowCount; + gint tableColumnCount, tableRowIndex, tableColumnIndex, tableRowSpan, tableColumnSpan; + gboolean tablePositionKnown; + gchar *tableRowHeaders, *tableColumnHeaders; + gint characterCount; + gint embeddedObjectCount; + gint objectX; + gint objectY; + gint objectWidth; + gint objectHeight; + gint referenceX; + gint referenceY; + gint referenceWidth; + gint referenceHeight; + gboolean objectGeometryKnown; + gboolean referenceGeometryKnown; +} cthulhu_snapshot; + +void cthulhu_capture_menu_checkability(AtspiAccessible *source, cthulhu_snapshot *snapshot); +void cthulhu_note_menu_checkability(AtspiAccessible *source); +void cthulhu_forget_menu_checkability(AtspiAccessible *source); + +typedef struct { + uintptr_t callback; + GMutex mutex; + GList *captures; +} cthulhu_callback_data; + +gchar *cthulhu_table_context(AtspiAccessible *source, gint *rows, gint *columns, + gchar **tableName, gchar **tablePath, + gint *rowIndex, gint *columnIndex, gboolean *guiTable); +cthulhu_snapshot cthulhu_capture_snapshot(AtspiAccessible *source, gboolean captureText, + gboolean captureCaretCharacter, + gboolean captureDocumentMetadata, + gboolean captureSoundGeometry, + gboolean captureApplicationName); +void cthulhu_capture_sound_geometry(AtspiAccessible *source, cthulhu_snapshot *snapshot); +gchar *cthulhu_collect_notification_text(AtspiAccessible *source); +gchar *cthulhu_collect_simple_prompt_text(AtspiAccessible *source); +gchar *cthulhu_radio_group_name(AtspiAccessible *source); +void cthulhu_capture_set_position(AtspiAccessible *source, GHashTable *attributes, cthulhu_snapshot *snapshot); +gboolean cthulhu_has_set_position(const gchar *role); +gchar *cthulhu_live_content(AtspiAccessible *source); +gchar *cthulhu_atomic_live_content(AtspiAccessible *source); +AtspiAccessible *cthulhu_busy_live_container(AtspiAccessible *source); +gchar *cthulhu_capture_caret_unit(AtspiAccessible *source, AtspiTextGranularity unit); +AtspiTextRange *cthulhu_text_get_string_at_offset(AtspiText *text, gint offset, + AtspiTextGranularity unit, GError **error); +guint start_foreground_timer(gpointer data); +const gchar *cthulhu_event_type(AtspiEvent *event); +gint cthulhu_event_detail1(AtspiEvent *event); +gchar *cthulhu_document_uri(AtspiAccessible *source); +gchar *cthulhu_event_payload(AtspiEvent *event); +gchar *cthulhu_live_attribute(AtspiAccessible *source, const gchar *key); +typedef struct { + gchar *politeness; + gboolean atomic; + gboolean busy; +} cthulhu_live_properties; +cthulhu_live_properties cthulhu_capture_live_properties(AtspiAccessible *source); +AtspiAccessible *cthulhu_event_active_descendant(AtspiEvent *event); +AtspiAccessible *cthulhu_selected_child(AtspiAccessible *source); +AtspiAccessible *cthulhu_table_selected_child(AtspiAccessible *source); +gboolean cthulhu_is_gtk_list_table(AtspiAccessible *source); +void cthulhu_refresh_frame_children(AtspiAccessible *window); +AtspiAccessible *cthulhu_focused_descendant(AtspiAccessible *window); +AtspiAccessible *cthulhu_showing_web_document(AtspiAccessible *window); +AtspiAccessible *cthulhu_autocomplete_popup_target(AtspiAccessible *source); +AtspiAccessible *cthulhu_combo_ancestor(AtspiAccessible *source); +gboolean cthulhu_active_document(AtspiAccessible *source); +gboolean cthulhu_in_active_document(AtspiAccessible *source); +gboolean cthulhu_in_inactive_window(AtspiAccessible *source); +gboolean cthulhu_active_menu_window(AtspiAccessible *window); +AtspiAccessible *cthulhu_popup_menu_target(AtspiAccessible *window); +AtspiAccessible *cthulhu_inline_menu_container(AtspiAccessible *source); +const gchar *cthulhu_accessible_path(AtspiAccessible *source); +const gchar *cthulhu_accessible_bus_name(AtspiAccessible *source); +AtspiAccessible *cthulhu_window_ancestor(AtspiAccessible *source); +gboolean cthulhu_may_be_background_notification(AtspiAccessible *source); +AtspiAccessible *cthulhu_document_ancestor(AtspiAccessible *source); +AtspiAccessible *cthulhu_editable_root(AtspiAccessible *source); +AtspiEventListenerCB cthulhu_event_callback_pointer(void); +gboolean cthulhu_request_event_loop_quit(void); +gboolean cthulhu_request_tree_capture(gpointer userData); +cthulhu_callback_data *cthulhu_callback_data_new(uintptr_t callback); +uintptr_t cthulhu_callback_value(const cthulhu_callback_data *data); +void cthulhu_callback_data_free(cthulhu_callback_data *data); + +#endif diff --git a/internal/atspi/adapter_native_test.go b/internal/atspi/adapter_native_test.go new file mode 100644 index 0000000..aaf1aea --- /dev/null +++ b/internal/atspi/adapter_native_test.go @@ -0,0 +1,854 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "context" + "errors" + "fmt" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeGUITablePresentation(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_GUI_TABLE") != "1" { + t.Skip("requires isolated GTK table fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + window := findNamedReference(t, tree, "Table presentation probe") + if !window.Valid() { + t.Fatal("GTK table window is absent from AT-SPI desktop") + } + frame, err := tree.Resolve(window) + if err != nil || frame.Description != "Select an item and press Enter to open it." { + t.Fatalf("GTK frame description = %q, %v", frame.Description, err) + } + if err := exec.Command("xdotool", "key", "Down").Run(); err != nil { + t.Fatal(err) + } +selectedRow: + for { + select { + case <-ctx.Done(): + t.Fatal("GTK table selection did not expose row context") + case event := <-adapter.Events(): + if event.Type != SelectionChangedEvent || event.Source.Name != "Beta" { + continue + } + if event.Source.TableName != "Probe items" || event.Source.TableRowCount != 2 || + event.Source.TableColumnCount != 2 || event.Source.TableRowText != "Beta, Shortcut" || + !event.Source.GUITable || !event.Source.TablePositionKnown || + event.Source.TableRowIndex != 1 || event.Source.TableColumnIndex != 0 || + event.Source.TablePath == "" || + event.WindowDescription != "Select an item and press Enter to open it." { + t.Fatalf("GTK selected row context = %#v", event.Source) + } + break selectedRow + } + } + if err := exec.Command("xdotool", "key", "Right").Run(); err != nil { + t.Fatal(err) + } + for { + select { + case <-ctx.Done(): + t.Fatal("GTK table did not expose horizontal cell movement") + case event := <-adapter.Events(): + if event.Type != ActiveDescendantEvent || event.Source.Name != "Shortcut" { + continue + } + if !event.Source.TablePositionKnown || event.Source.TableRowIndex != 1 || + event.Source.TableColumnIndex != 1 { + t.Fatalf("GTK horizontal cell context = %#v", event.Source) + } + return + } + } +} + +func TestNativeGUIListTableFocus(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_GUI_LIST_TABLE") != "1" { + t.Skip("requires isolated GTK table with list role") + } + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + list := findNamedReference(t, tree, "Probe items") + snapshot, err := tree.Resolve(list) + if err != nil || snapshot.Role != "list" { + t.Fatalf("fixture list role = %q, %v", snapshot.Role, err) + } + for _, name := range []string{"Alpha", "Beta"} { + if err := exec.Command("xdotool", "key", "Down").Run(); err != nil { + t.Fatal(err) + } + selected: + for { + select { + case <-ctx.Done(): + t.Fatalf("list table did not present %s", name) + case event := <-adapter.Events(): + if event.Type != FocusEvent && event.Type != FocusedStateEvent && event.Type != SelectionChangedEvent { + continue + } + if event.Source.ID() == list.ID() { + t.Fatalf("list table focus was not normalized to its selected cell: %#v", event.Source) + } + if event.Source.Name != name { + continue + } + if event.Source.Role != "table cell" || !event.Source.GUITable || + !event.Source.TablePositionKnown || event.Source.TablePath != list.ID().Path { + t.Fatalf("list table selected cell = %#v", event.Source) + } + break selected + } + } + } +} + +func TestNativeGUITableFocusPresentsSelectedChild(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_GUI_TABLE") != "1" { + t.Skip("requires isolated GTK table fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + window := findNamedReference(t, tree, "Table presentation probe") + if !window.Valid() { + t.Fatal("GTK table window is absent from AT-SPI desktop") + } + windowIDs, err := exec.Command("xdotool", "search", "--name", "Table presentation probe").Output() + if err != nil || len(strings.Fields(string(windowIDs))) == 0 { + t.Fatalf("GTK table window not found: %v", err) + } + if err := exec.Command("xdotool", "windowactivate", strings.Fields(string(windowIDs))[0]).Run(); err != nil { + t.Fatal(err) + } + for { + select { + case <-ctx.Done(): + t.Fatal("GTK table focus did not present selected child") + case event := <-adapter.Events(): + if event.Type != FocusEvent && event.Type != FocusedStateEvent { + continue + } + if event.Source.Role != "table cell" || event.Source.Name != "Alpha" { + t.Fatalf("focused table source = %#v", event.Source) + } + if event.Source.TableName != "Probe items" || !event.Source.GUITable || + !event.Source.TablePositionKnown || event.Source.TablePath == "" { + t.Fatalf("focused table context = %#v", event.Source) + } + return + } + } +} + +func TestNativeGUITableMultiselectionFocus(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_GUI_TABLE_MULTI") != "1" { + t.Skip("requires isolated multiselection GTK table fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + window := findNamedReference(t, tree, "Table presentation probe") + if !window.Valid() { + t.Fatal("GTK table window is absent from AT-SPI desktop") + } + for _, name := range []string{"Alpha", "Beta"} { + cell := findNamedReference(t, tree, name) + if !cell.Valid() { + t.Fatalf("%s cell is absent from the multiselection table", name) + } + snapshot, err := tree.Resolve(cell) + if err != nil || !snapshot.Selected { + t.Fatalf("%s cell is not selected: %#v, %v", name, snapshot, err) + } + } + // The fixture starts with a button focused and two table rows selected. + // Tab focuses the table; neither selected row is an unambiguous target. + if err := exec.Command("xdotool", "key", "Tab").Run(); err != nil { + t.Fatal(err) + } + for { + select { + case <-ctx.Done(): + t.Fatal("multiselection table focus event was not received") + case event := <-adapter.Events(): + if (event.Type != FocusEvent && event.Type != FocusedStateEvent) || event.Source.BusName != window.ID().BusName { + continue + } + if event.Source.Role == "button" || event.Source.Role == "push button" { + continue + } + wantRole := "table" + if os.Getenv("CTHULHU_NATIVE_GUI_LIST_TABLE") == "1" { + wantRole = "list" + } + if event.Source.Role != wantRole || event.Source.Name != "Probe items" { + t.Fatalf("multiselection focus guessed a row: %#v", event.Source) + } + return + } + } +} + +// Run as the first accessibility reader in a real Xorg session, then launch +// steam -bigpicture and press Tab twice without leaving Steam. This catches the frame-only provider state +// that a synthetic Chromium fixture cannot reproduce. +func TestNativeSteamBigPictureFocus(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_STEAM") != "1" { + t.Skip("requires a fresh Steam Big Picture launch in a real Xorg session") + } + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + frames := 0 + focused := make(map[ObjectID]string) + var steamWindow uint64 + for { + select { + case <-ctx.Done(): + t.Fatalf("Steam exposed %d frame activations and %d distinct named controls; launch Big Picture and press Tab at least twice before the timeout", frames, len(focused)) + case <-adapter.ForegroundChanges(): + foreground := adapter.Foreground().Client + if steamWindow != 0 && foreground.Known && foreground.Window != steamWindow { + t.Fatal("foreground left Steam before two controls were observed") + } + case event, ok := <-adapter.Events(): + if !ok { + t.Fatal("AT-SPI events stopped before Steam focus was observed") + } + pid := event.Foreground.Client.PID + if steamWindow != 0 && event.Foreground.Client.Known && + event.Foreground.Client.Window != 0 && event.Foreground.Client.Window != steamWindow { + t.Fatal("foreground left Steam before two controls were observed") + } + if pid <= 0 || event.ForegroundMismatch { + continue + } + comm, err := os.ReadFile(fmt.Sprintf("/proc/%d/comm", pid)) + if err != nil || strings.TrimSpace(string(comm)) != "steamwebhelper" { + continue + } + if steamWindow == 0 && event.Foreground.Client.Window != 0 { + steamWindow = event.Foreground.Client.Window + } + switch event.Type { + case WindowActivatedEvent: + if event.Source.Role == "frame" { + frames++ + } + case FocusEvent, FocusedStateEvent: + if event.Type == FocusedStateEvent && event.Detail1 == 0 { + continue + } + default: + continue + } + if !event.Source.Focused || !event.Window.Valid() || + event.Source.BusName != event.Window.BusName || + strings.TrimSpace(event.Source.Name) == "" || + !steamNavigationControl(event.Source.Role) { + continue + } + focused[event.Source.ID()] = event.Source.Role + if len(focused) >= 2 { + t.Logf("Steam exposed %d distinct focused controls after %d frame activations", len(focused), frames) + return + } + } + } +} + +func TestNativeThunarNestedFileCellLabel(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_THUNAR") != "1" { + t.Skip("requires an isolated Thunar details view with Alpha and Beta test files") + } + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + for _, name := range []string{"Alpha", "Beta"} { + child := findNamedReference(t, tree, name) + if !child.Valid() { + t.Fatalf("Thunar did not expose %s", name) + } + row, err := tree.Resolve(child) + if err != nil || row.Role != "table cell" || row.Name != name { + t.Fatalf("Thunar row for %s = %#v, %v", name, row, err) + } + parent, ok, err := tree.Parent(child) + if err != nil || !ok { + t.Fatalf("parent of %s: %v", name, err) + } + snapshot, err := tree.Resolve(parent) + if err != nil || snapshot.Role != "tree table" { + t.Fatalf("Thunar row %s is not the named child of the file view: %#v, %v", name, snapshot, err) + } + } + if err := exec.Command("xdotool", "key", "Down").Run(); err != nil { + t.Fatal(err) + } + for { + select { + case <-ctx.Done(): + t.Fatal("Thunar details navigation did not expose a file row") + case event := <-adapter.Events(): + if event.Source.Role != "table cell" || + (event.Type != SelectionChangedEvent && event.Type != ActiveDescendantEvent) || + (event.Source.Name != "Alpha" && event.Source.Name != "Beta") { + continue + } + if !strings.Contains(event.Source.TableRowText, event.Source.Name) { + t.Fatalf("Thunar file name missing from row %q for %q", event.Source.TableRowText, event.Source.Name) + } + return + } + } +} + +func steamNavigationControl(role string) bool { + switch role { + case "button", "push button", "toggle button", "check box", "link", "menu item", "page tab", "list item": + return true + default: + return false + } +} + +func TestNativeTreeCaptureDefunctAndShutdownInvalidation(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_ATSPI") != "1" { + t.Skip("requires isolated AT-SPI and X11 session") + } + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + textRef := findNamedReference(t, tree, "Review text probe") + numericRef := findNamedReference(t, tree, "Numeric value probe") + numeric, err := tree.Resolve(numericRef) + if err != nil || !numeric.ValueKnown || numeric.CurrentValue != 1.25 || numeric.MinimumIncrement != 0.01 { + t.Fatalf("native numeric value: known=%v value=%v increment=%v err=%v", numeric.ValueKnown, numeric.CurrentValue, numeric.MinimumIncrement, err) + } + assertNativeReviewText(t, tree, textRef, "Café 猫Second line") + if os.Getenv("CTHULHU_TREE_CONTAINER") == "list" { + assert_native_list_position(t, tree, "Persistent control", 1, 7) + assert_native_list_position(t, tree, "Removable control", 2, 7) + } + caretRef := findNamedReference(t, tree, "Caret review probe") + if captured, err := tree.VisibleText(caretRef); err != nil || !captured.CaretKnown || captured.CaretOffset != 6 { + t.Fatalf("native caret: known=%v offset=%d err=%v", captured.CaretKnown, captured.CaretOffset, err) + } + clippedRef := findNamedReference(t, tree, "Clipped review probe") + clippedText, clippedErr := tree.VisibleText(clippedRef) + var clippedContent strings.Builder + for _, r := range clippedText.Ranges { + clippedContent.WriteString(r.Text) + } + if clippedErr != nil || !clippedText.Known || !strings.HasPrefix(clippedContent.String(), "Clipped ") || strings.Contains(clippedContent.String(), "OFFSCREEN") { + t.Fatalf("native clipped text = %q known=%v err=%v", clippedContent.String(), clippedText.Known, clippedErr) + } + protected := findNamedReference(t, tree, "Protected text probe") + if captured, err := tree.VisibleText(protected); err != nil || captured.Known || len(captured.Ranges) != 0 { + t.Fatalf("protected review text was captured: known=%v ranges=%d err=%v", captured.Known, len(captured.Ranges), err) + } + assertNativeBrailleRouting(t, ctx, adapter) + pressTreeProbeKey(t, "t") + waitForSoundGeometry(t, ctx, adapter.Events()) + waitForWindowName(t, ctx, "Cthulhu Tree Probe Text Changed") + for { + _, err := tree.VisibleText(textRef) + if errors.Is(err, ErrStaleText) { + break + } + if err != nil { + t.Fatal(err) + } + select { + case <-ctx.Done(): + t.Fatal("text event did not invalidate review text") + case <-time.After(10 * time.Millisecond): + } + } + tree, err = adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + assertNativeReviewText(t, tree, textRef, "Changed 猫New line") + removable := findNamedReference(t, tree, "Removable control") + if !removable.Valid() { + t.Fatal("native capture did not contain removable control") + } + pressTreeProbeKey(t, "r") + waitForWindowName(t, ctx, "Cthulhu Tree Probe Removed") + waitForStale(t, ctx, tree, removable) + + treeAfterRemoval, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + if treeAfterRemoval != tree { + t.Fatal("recapture replaced the owned tree instance") + } + persistent := findNamedReference(t, tree, "Persistent control") + if !persistent.Valid() { + t.Fatal("recapture did not contain persistent control") + } + if os.Getenv("CTHULHU_TREE_CONTAINER") == "list" { + assert_native_list_position(t, tree, "Persistent control", 1, 6) + } + if os.Getenv("CTHULHU_TREE_CONTAINER") == "box" { + container := findNamedReference(t, tree, "Dynamic controls") + if !container.Valid() { + t.Fatal("dynamic container missing") + } + pressTreeProbeKey(t, "a") + waitForWindowName(t, ctx, "Cthulhu Tree Probe Added") + waitForStale(t, ctx, tree, persistent) + if _, ok, err := tree.FirstChild(container); ok || !errors.Is(err, ErrIncompleteTree) { + t.Fatalf("added children were treated as complete: %v %v", ok, err) + } + tree, err = adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + if _, ok, err := tree.FirstChild(container); !ok || err != nil { + t.Fatalf("recapture failed to restore container traversal: %v %v", ok, err) + } + if added := findNamedReference(t, tree, "Added control"); !added.Valid() { + t.Fatal("recapture did not contain added control") + } + persistent = findNamedReference(t, tree, "Persistent control") + if !persistent.Valid() { + t.Fatal("recapture lost persistent control") + } + } + if os.Getenv("CTHULHU_TREE_CONTAINER") == "box" { + container := findNamedReference(t, tree, "Dynamic controls") + before, err := tree.Geometry(container) + if err != nil || !before.BoundsKnown || !before.Visible || !before.Showing { + t.Fatalf("native component geometry unavailable: %v %v", before, err) + } + pressTreeProbeKey(t, "m") + waitForWindowName(t, ctx, "Cthulhu Tree Probe Resized") + waitForGeometryInvalidation(t, ctx, tree, container) + if _, err := tree.Resolve(container); err != nil { + t.Fatalf("resize removed object: %v", err) + } + tree, err = adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + after, err := tree.Geometry(container) + if err != nil || !after.BoundsKnown || after.Bounds.Width <= before.Bounds.Width { + t.Fatalf("resize geometry = %v %v; previous = %v", after, err, before) + } + persistent = findNamedReference(t, tree, "Persistent control") + pressTreeProbeKey(t, "h") + waitForWindowName(t, ctx, "Cthulhu Tree Probe Hidden") + waitForGeometryInvalidation(t, ctx, tree, persistent) + tree, err = adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + hidden, err := tree.Geometry(persistent) + if err != nil || !hidden.VisibilityKnown || hidden.Showing || hidden.BoundsKnown { + t.Fatalf("hidden object geometry = %v %v", hidden, err) + } + } + textRef = findNamedReference(t, tree, "Review text probe") + pressTreeProbeKey(t, "v") + waitForWindowName(t, ctx, "Cthulhu Tree Probe Text Hidden") + waitForGeometryInvalidation(t, ctx, tree, textRef) + if _, err := tree.VisibleText(textRef); !errors.Is(err, ErrStaleText) { + t.Fatalf("hidden text did not become stale: %v", err) + } + tree, err = adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + if hidden, err := tree.VisibleText(textRef); err != nil || hidden.Known || len(hidden.Ranges) != 0 { + t.Fatalf("hidden text retained: known=%v ranges=%d err=%v", hidden.Known, len(hidden.Ranges), err) + } + if adapter.TreeInvalidations() == 0 { + t.Fatal("native defunct event did not invalidate cached objects") + } + pressTreeProbeKey(t, "w") + waitForWindowLifecycle(t, ctx, adapter.Events()) + + if err := adapter.Stop(ctx); err != nil { + t.Fatal(err) + } + if _, err := tree.Resolve(persistent); !errors.Is(err, ErrStaleObject) { + t.Fatalf("adapter stop left a live reference: %v", err) + } +} + +func waitForWindowLifecycle(t *testing.T, ctx context.Context, events <-chan Event) { + t.Helper() + var activated ObjectID + deactivated := false + for { + select { + case <-ctx.Done(): + t.Fatalf("timed out waiting for window lifecycle: activated=%v deactivated=%v", activated.Valid(), deactivated) + case event := <-events: + switch event.Type { + case WindowActivatedEvent: + if event.Source.Name != "Activated control" { + continue + } + if (event.Source.Role != "button" && event.Source.Role != "push button") || !event.Source.Focused { + t.Fatalf("activation focus snapshot = %+v", event.Source) + } + if !event.Window.Valid() || event.Window.Path == event.Source.Path || event.Window.BusName != event.Source.BusName { + t.Fatalf("activation ownership missing: source=%+v window=%+v origin=%q", event.Source.ID(), event.Window, event.OriginPath) + } + activated = event.Window + case WindowDeactivatedEvent: + if activated.Valid() && event.Window == activated { + deactivated = true + } + case WindowDestroyedEvent: + if activated.Valid() && event.Window == activated { + if !deactivated { + t.Fatal("activated window was destroyed without a deactivation event") + } + return + } + } + } + } +} + +func waitForSoundGeometry(t *testing.T, ctx context.Context, events <-chan Event) { + t.Helper() + for { + select { + case <-ctx.Done(): + t.Fatal("timed out waiting for captured sound geometry") + case event := <-events: + if event.Source.SoundGeometry.ObjectKnown && event.Source.SoundGeometry.ReferenceKnown { + object := event.Source.SoundGeometry.Object + reference := event.Source.SoundGeometry.Reference + if object.Valid() && reference.Valid() { + return + } + } + } + } +} + +func assert_native_list_position(t *testing.T, tree *AccessibleTree, name string, position, size int) { + t.Helper() + label := findNamedReference(t, tree, name) + row, ok, err := tree.Parent(label) + if err != nil || !ok { + t.Fatalf("%s row missing: %v", name, err) + } + snapshot, err := tree.Resolve(row) + if err != nil || snapshot.PositionInSet != position || snapshot.SetSize != size { + t.Fatalf("%s (%s) position=%d size=%d, want %d of %d: %v", name, snapshot.Role, snapshot.PositionInSet, snapshot.SetSize, position, size, err) + } +} + +func findNamedReference(t *testing.T, tree *AccessibleTree, name string) ObjectReference { + t.Helper() + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + pending := []ObjectReference{root} + for len(pending) != 0 { + last := len(pending) - 1 + current := pending[last] + pending = pending[:last] + snapshot, resolveErr := tree.Resolve(current) + if resolveErr != nil { + t.Fatal(resolveErr) + } + if snapshot.Name == name { + return current + } + child, ok, childErr := tree.FirstChild(current) + if childErr != nil { + t.Fatal(childErr) + } + for ok { + pending = append(pending, child) + child, ok, childErr = tree.NextSibling(child) + if childErr != nil { + t.Fatal(childErr) + } + } + } + return ObjectReference{} +} + +func pressTreeProbeKey(t *testing.T, key string) { + t.Helper() + window := os.Getenv("CTHULHU_TREE_WINDOW") + if window == "" { + t.Fatal("CTHULHU_TREE_WINDOW is empty") + } + if err := exec.Command("xdotool", "windowfocus", window, "key", key).Run(); err != nil { + t.Fatalf("press %s in tree probe: %v", key, err) + } +} + +func waitForStale(t *testing.T, ctx context.Context, tree *AccessibleTree, reference ObjectReference) { + t.Helper() + ticker := time.NewTicker(10 * time.Millisecond) + defer ticker.Stop() + for { + if _, err := tree.Resolve(reference); errors.Is(err, ErrStaleObject) { + return + } + select { + case <-ctx.Done(): + t.Fatalf("reference did not become stale: %v", ctx.Err()) + case <-ticker.C: + } + } +} + +func waitForWindowName(t *testing.T, ctx context.Context, name string) { + t.Helper() + window := os.Getenv("CTHULHU_TREE_WINDOW") + ticker := time.NewTicker(10 * time.Millisecond) + defer ticker.Stop() + for { + output, err := exec.Command("xdotool", "getwindowname", window).Output() + if err == nil && string(output) == name+"\n" { + return + } + select { + case <-ctx.Done(): + t.Fatalf("GTK mutation %q was not observed: %v", name, ctx.Err()) + case <-ticker.C: + } + } +} + +func waitForGeometryInvalidation(t *testing.T, ctx context.Context, tree *AccessibleTree, reference ObjectReference) { + t.Helper() + ticker := time.NewTicker(10 * time.Millisecond) + defer ticker.Stop() + for { + _, err := tree.Geometry(reference) + if errors.Is(err, ErrStaleGeometry) { + return + } + if err != nil { + t.Fatalf("object identity lost during geometry change: %v", err) + } + select { + case <-ctx.Done(): + t.Fatalf("geometry did not become stale: %v", ctx.Err()) + case <-ticker.C: + } + } +} + +func assertNativeReviewText(t *testing.T, tree *AccessibleTree, ref ObjectReference, want string) { + t.Helper() + captured, err := tree.VisibleText(ref) + if err != nil || !captured.Known { + for current := ref; current.Valid(); { + snap, _ := tree.Resolve(current) + bounds, boundsErr := tree.Geometry(current) + t.Logf("review ancestor role=%q geometry=%+v err=%v", snap.Role, bounds, boundsErr) + parent, ok, _ := tree.Parent(current) + if !ok { + break + } + current = parent + } + t.Fatalf("native visible text unavailable: known=%v limited=%v err=%v", captured.Known, captured.Limited, err) + } + var content strings.Builder + for _, r := range captured.Ranges { + content.WriteString(r.Text) + } + if content.String() != want { + t.Fatalf("native text = %q, want %q", content.String(), want) + } + geometry, err := tree.Geometry(ref) + if err != nil || !captured.valid(geometry) { + t.Fatalf("invalid native text geometry: %v", err) + } +} + +func TestNativeGUITableScreenLockRecovery(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_GUI_TABLE") != "1" { + t.Skip("requires isolated GTK table fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + if _, err := adapter.CaptureDesktop(ctx); err != nil { + t.Fatal(err) + } + key := func(name string) { + t.Helper() + if err := exec.CommandContext(ctx, "xdotool", "key", name).Run(); err != nil { + t.Fatal(err) + } + } + key("Down") + for { + select { + case event := <-adapter.Events(): + if event.Type == SelectionChangedEvent && event.Source.Name == "Beta" { + goto locked + } + case <-ctx.Done(): + t.Fatal("initial table focus did not arrive") + } + } +locked: + adapter.SetSecureInputActive(true) + if _, err := adapter.CaptureDesktop(ctx); err == nil { + t.Fatal("desktop capture was allowed while locked") + } + key("Up") + select { + case <-adapter.Events(): + t.Fatal("AT-SPI content escaped secure mode") + case <-time.After(100 * time.Millisecond): + } + adapter.SetSecureInputActive(false) + // The provider retains focus and need not emit any fresh focus event. Unlock + // must recover the current focused object without requiring another key. + for { + select { + case event := <-adapter.Events(): + if event.Type == WindowActivatedEvent { + if event.Source.Name != "Alpha" { + t.Fatalf("unlock focus = %q, want Alpha", event.Source.Name) + } + return + } + case <-ctx.Done(): + t.Fatal("unlock did not recover retained GTK focus") + } + } +} diff --git a/internal/atspi/adapter_ocr_native.go b/internal/atspi/adapter_ocr_native.go new file mode 100644 index 0000000..63b9349 --- /dev/null +++ b/internal/atspi/adapter_ocr_native.go @@ -0,0 +1,147 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "time" +) + +// CaptureOCRGeometry runs only a narrow target/ancestor query on the GLib +// owner. Call it from a worker, not the event loop. A zone remains provider +// coordinates and is validated/clipped to the fresh object's bounds. +func (adapter *Adapter) CaptureOCRGeometry(ctx context.Context, object ObjectID, zone *Rectangle) (OCRGeometry, error) { + if !object.Valid() { + return OCRGeometry{}, ErrObjectNotFound + } + ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond) + defer cancel() + var ownedZone *Rectangle + if zone != nil { + copy := *zone + ownedZone = © + } + result, err := adapter.documentOperation(ctx, treeCaptureRequest{ocrGeometry: true, reviewFocus: object, ocrZone: ownedZone}) + return result.ocr, err +} + +func (adapter *Adapter) nativeOCRGeometry(ctx context.Context, object ObjectID, zone *Rectangle) (OCRGeometry, error) { + var source *C.AtspiAccessible + for _, item := range adapter.nativeFocus { + if item.id == object { + source = item.source + break + } + } + if source == nil { + source = adapter.nativeReview[object] + } + if source == nil { + source = adapter.nativeDocument[object] + } + if source == nil { + return OCRGeometry{}, ErrObjectNotFound + } + adapter.refreshForeground() + before := adapter.Foreground() + if !before.Client.Known || before.Client.Window == 0 || before.Client.PID <= 0 { + return OCRGeometry{}, ErrOCRGeometry + } + // Reject dead source/ancestor content without querying text. OCR reads only + // visible pixels, so a password role does not prohibit capture geometry. + current := (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(source))) + valid := false + seen := make(map[ObjectID]bool) + for depth := 0; current != nil && depth < 128 && ctx.Err() == nil; depth++ { + id := nativeObjectID(current) + C.atspi_accessible_clear_cache_single(current) + states := C.atspi_accessible_get_state_set(current) + safe := states != nil && C.atspi_state_set_contains(states, C.ATSPI_STATE_DEFUNCT) == 0 + if states != nil { + C.g_object_unref(C.gpointer(states)) + } + role := C.atspi_accessible_get_role(current, nil) + if !safe || !id.Valid() || seen[id] || role == C.ATSPI_ROLE_INVALID { + C.g_object_unref(C.gpointer(current)) + return OCRGeometry{}, ErrOCRGeometry + } + seen[id] = true + if isWindowRole(role) { + valid = true + C.g_object_unref(C.gpointer(current)) + current = nil + break + } + parent := C.atspi_accessible_get_parent(current, nil) + C.g_object_unref(C.gpointer(current)) + current = parent + } + if current != nil { + C.g_object_unref(C.gpointer(current)) + } + if err := ctx.Err(); err != nil { + return OCRGeometry{}, err + } + if !valid { + return OCRGeometry{}, ErrOCRGeometry + } + window := C.cthulhu_window_ancestor(source) + if window == nil { + return OCRGeometry{}, ErrOCRGeometry + } + defer C.g_object_unref(C.gpointer(window)) + if adapter.foregroundProcessID(int(C.atspi_accessible_get_process_id(window, nil))) != before.Client.PID || (adapter.foregroundWindow.Valid() && adapter.foregroundWindow != nativeObjectID(window)) { + return OCRGeometry{}, ErrOCRGeometry + } + states := C.atspi_accessible_get_state_set(window) + active := states != nil && C.atspi_state_set_contains(states, C.ATSPI_STATE_ACTIVE) != 0 && C.atspi_state_set_contains(states, C.ATSPI_STATE_ICONIFIED) == 0 + if states != nil { + C.g_object_unref(C.gpointer(states)) + } + if !active { + return OCRGeometry{}, ErrOCRGeometry + } + geometry, err := geometryFromNative(ctx, source) + if err != nil { + return OCRGeometry{}, err + } + windowGeometry, err := geometryFromNative(ctx, window) + if err != nil { + return OCRGeometry{}, err + } + if !geometry.BoundsKnown || !windowGeometry.BoundsKnown { + return OCRGeometry{}, ErrOCRGeometry + } + bounds := geometry.Bounds + if zone != nil { + clipped, ok := zone.Intersection(bounds) + // A stale zone must not move or expand its captured area implicitly. + if !ok || clipped != *zone { + return OCRGeometry{}, ErrStaleGeometry + } + bounds = clipped + } + screen, err := ocr_screen_bounds(bounds, windowGeometry.Bounds, before.Client) + adapter.refreshForeground() + if err := ctx.Err(); err != nil { + return OCRGeometry{}, err + } + if adapter.Foreground() != before { + return OCRGeometry{}, ErrStaleGeometry + } + if err != nil { + return OCRGeometry{}, err + } + return OCRGeometry{Object: object, ProviderBounds: bounds, WindowBounds: windowGeometry.Bounds, ScreenBounds: screen, Foreground: before}, nil +} + +func isWindowRole(role C.AtspiRole) bool { + return role == C.ATSPI_ROLE_FRAME || role == C.ATSPI_ROLE_DIALOG || role == C.ATSPI_ROLE_WINDOW +} diff --git a/internal/atspi/adapter_position.c b/internal/atspi/adapter_position.c new file mode 100644 index 0000000..40be846 --- /dev/null +++ b/internal/atspi/adapter_position.c @@ -0,0 +1,127 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "adapter_native.h" + +gboolean cthulhu_has_set_position(const gchar *role) { + return g_strcmp0(role, "list item") == 0 || g_strcmp0(role, "tree item") == 0 || + g_strcmp0(role, "menu item") == 0 || g_strcmp0(role, "check menu item") == 0 || + g_strcmp0(role, "radio menu item") == 0 || g_strcmp0(role, "page tab") == 0 || + g_strcmp0(role, "radio button") == 0; +} + +static gint cthulhu_positive_integer(const gchar *value) { + if (value == NULL || *value < '0' || *value > '9') return 0; + gchar *end = NULL; + gint64 number = g_ascii_strtoll(value, &end, 10); + if (*end != '\0' || number <= 0 || number > G_MAXINT) return 0; + return (gint)number; +} + +static gboolean cthulhu_menu_item(AtspiRole role) { + return role == ATSPI_ROLE_MENU_ITEM || role == ATSPI_ROLE_CHECK_MENU_ITEM || + role == ATSPI_ROLE_RADIO_MENU_ITEM; +} + +static gboolean cthulhu_group_member(AtspiRelation *relation, AtspiAccessible *child) { + for (gint index = 0; index < atspi_relation_get_n_targets(relation); index++) { + AtspiAccessible *target = atspi_relation_get_target(relation, index); + gboolean matches = target != NULL && + g_strcmp0(cthulhu_accessible_bus_name(target), cthulhu_accessible_bus_name(child)) == 0 && + g_strcmp0(cthulhu_accessible_path(target), cthulhu_accessible_path(child)) == 0; + if (target != NULL) g_object_unref(target); + if (matches) return TRUE; + } + return FALSE; +} + +void cthulhu_capture_set_position(AtspiAccessible *source, GHashTable *attributes, + cthulhu_snapshot *snapshot) { + const gchar *position = attributes == NULL ? NULL : g_hash_table_lookup(attributes, "posinset"); + const gchar *size = attributes == NULL ? NULL : g_hash_table_lookup(attributes, "setsize"); + // Explicit provider values describe virtualized and hierarchical sets. + // Partial, unknown (-1), or invalid values must not become sibling guesses. + if (position != NULL || size != NULL) { + gint parsedPosition = cthulhu_positive_integer(position); + gint parsedSize = cthulhu_positive_integer(size); + if (parsedPosition > 0 && parsedPosition <= parsedSize) { + snapshot->positionInSet = parsedPosition; + snapshot->setSize = parsedSize; + } + return; + } + GError *error = NULL; + AtspiAccessible *parent = atspi_accessible_get_parent(source, &error); + if (error != NULL || parent == NULL) { + g_clear_error(&error); + if (parent != NULL) g_object_unref(parent); + return; + } + AtspiRole sourceRole = atspi_accessible_get_role(source, &error); + GArray *relations = NULL; + AtspiRelation *memberRelation = NULL; + if (error != NULL) goto cleanup; + if (sourceRole == ATSPI_ROLE_RADIO_BUTTON) { + relations = atspi_accessible_get_relation_set(source, &error); + if (error != NULL) goto cleanup; + for (guint index = 0; relations != NULL && index < relations->len; index++) { + AtspiRelation *relation = g_array_index(relations, AtspiRelation *, index); + if (atspi_relation_get_relation_type(relation) == ATSPI_RELATION_MEMBER_OF) { + memberRelation = relation; + if (atspi_relation_get_n_targets(relation) > 128) goto cleanup; + break; + } + } + } + AtspiRole parentRole = atspi_accessible_get_role(parent, &error); + if (error != NULL) goto cleanup; + // A flattened tree does not reliably describe logical sibling sets. + if (sourceRole == ATSPI_ROLE_TREE_ITEM) goto cleanup; + if (sourceRole == ATSPI_ROLE_LIST_ITEM && parentRole != ATSPI_ROLE_LIST && parentRole != ATSPI_ROLE_LIST_BOX) + goto cleanup; + if (sourceRole == ATSPI_ROLE_PAGE_TAB && parentRole != ATSPI_ROLE_PAGE_TAB_LIST) goto cleanup; + if (cthulhu_menu_item(sourceRole) && parentRole != ATSPI_ROLE_MENU && parentRole != ATSPI_ROLE_MENU_BAR) + goto cleanup; + gint count = atspi_accessible_get_child_count(parent, &error); + if (error != NULL) goto cleanup; + if (count <= 0) goto cleanup; + gint index = atspi_accessible_get_index_in_parent(source, &error); + if (error != NULL || index < 0 || index >= count) goto cleanup; + // Lists and tab lists expose their items in child order, including large + // sets. This uses a fixed number of queries rather than a sibling walk. + if (sourceRole == ATSPI_ROLE_LIST_ITEM || sourceRole == ATSPI_ROLE_PAGE_TAB) { + snapshot->positionInSet = index + 1; + snapshot->setSize = count; + goto cleanup; + } + // Menus contain separators; radio containers can contain labels and + // unrelated controls. Count only item peers, with bounded native work. + if (count > 128) goto cleanup; + gint itemPosition = 0, setSize = 0; + for (gint childIndex = 0; childIndex < count; childIndex++) { + AtspiAccessible *child = atspi_accessible_get_child_at_index(parent, childIndex, &error); + if (error != NULL || child == NULL) { + if (child != NULL) g_object_unref(child); + goto cleanup; + } + AtspiRole childRole = atspi_accessible_get_role(child, &error); + gboolean member = memberRelation == NULL || cthulhu_group_member(memberRelation, child); + g_object_unref(child); + if (error != NULL) goto cleanup; + if (!member) continue; + if (childRole != sourceRole && !(cthulhu_menu_item(sourceRole) && cthulhu_menu_item(childRole))) continue; + setSize++; + if (childIndex == index) itemPosition = setSize; + } + snapshot->positionInSet = itemPosition; + snapshot->setSize = setSize; +cleanup: + if (relations != NULL) { + for (guint index = 0; index < relations->len; index++) + g_object_unref(g_array_index(relations, AtspiRelation *, index)); + g_array_unref(relations); + } + g_clear_error(&error); + g_object_unref(parent); +} diff --git a/internal/atspi/adapter_references_native.go b/internal/atspi/adapter_references_native.go new file mode 100644 index 0000000..44fb32d --- /dev/null +++ b/internal/atspi/adapter_references_native.go @@ -0,0 +1,416 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + "time" +) + +func (adapter *Adapter) captureDesktop(ctx context.Context, reviewFocus ObjectID, document, documentText bool) (*AccessibleTree, error) { + if document { + trace := capture_diagnostics(ctx) + trace.begin_stage("root-selection", reviewFocus, "") + root, err := adapter.nativeDocumentRoot(ctx, reviewFocus) + adapter.treeMutex.Lock() + previousTree := adapter.documentTree + adapter.treeMutex.Unlock() + if (errors.Is(err, ErrObjectNotFound) || errors.Is(err, ErrStaleObject)) && previousTree != nil && len(adapter.nativeFocus) != 0 { + // Dynamic pages can remove the browse cursor without sending a new + // focus event. Recover only from the newest retained native focus in + // the same document. A chrome or other-tab focus is not a fallback. + currentRoot, rootErr := previousTree.Root() + for i := len(adapter.nativeFocus) - 1; rootErr == nil && i >= 0; i-- { + latest := adapter.nativeFocus[i] + if latest.id.BusName != reviewFocus.BusName { + break + } + C.atspi_accessible_clear_cache_single(latest.source) + states := C.atspi_accessible_get_state_set(latest.source) + if states == nil { + continue + } + dead := C.atspi_state_set_contains(states, C.ATSPI_STATE_DEFUNCT) != 0 + C.g_object_unref(C.gpointer(states)) + if dead { + continue + } + // A removed browse target can retain a non-defunct proxy after + // Chromium has dropped its accessible object. Its role is then + // invalid; try the preceding real focus instead. + if C.atspi_accessible_get_role(latest.source, nil) == C.ATSPI_ROLE_INVALID { + continue + } + candidate, candidateErr := adapter.nativeDocumentRoot(ctx, latest.id) + if candidateErr != nil { + break + } + if nativeObjectID(candidate) == currentRoot.ID() { + root, err = candidate, nil + } else { + C.g_object_unref(C.gpointer(candidate)) + } + break + } + } + if err != nil { + return nil, err + } + trace.set_root(nativeObjectID(root), "document") + trace.begin_stage("cache-preparation", nativeObjectID(root), "") + cache := nativeTreeCache{} + if !documentText && previousTree != nil { + cache.nodes = previousTree.nativeRefresh(nativeObjectID(root)) + cache.sources = adapter.nativeDocument + } + // Retain this bounded capture for narrow OCR geometry queries too. + retained := make(map[ObjectID]*C.AtspiAccessible) + rootID, nodes, err := captureNativeTree(ctx, root, "", true, documentText, retained, cache) + var tree *AccessibleTree + if err == nil { + tree, err = adapter.installCapturedTree(rootID, nodes, true, documentText) + } + if err != nil { + for _, source := range retained { + C.g_object_unref(C.gpointer(source)) + } + return nil, err + } + adapter.clearNativeDocument() + adapter.nativeDocument = retained + return tree, nil + } + trace := capture_diagnostics(ctx) + trace.begin_stage("root-selection", reviewFocus, "") + rootScope := "window" + var rootSource *C.AtspiAccessible + if reviewFocus.Valid() { + // A flat-review command only needs its owning window. Starting from + // the desktop walks every window in the browser process, including + // unrelated tabs and detached windows, before selecting this one. + for _, item := range adapter.nativeFocus { + if item.id == reviewFocus { + rootSource = C.cthulhu_window_ancestor(item.source) + break + } + } + } + if rootSource == nil { + rootScope = "desktop" + rootSource = C.atspi_get_desktop(0) + } + if rootSource == nil { + return nil, errors.New("capture AT-SPI review window: root is unavailable") + } + trace.set_root(nativeObjectID(rootSource), rootScope) + trace.begin_stage("cache-preparation", nativeObjectID(rootSource), "") + retained := make(map[ObjectID]*C.AtspiAccessible) + cache := nativeTreeCache{} + if reviewFocus.BusName != "" { + if adapter.nativeReviewBus == reviewFocus.BusName { + adapter.treeMutex.Lock() + previousTree := adapter.tree + adapter.treeMutex.Unlock() + if previousTree != nil { + cache.nodes = previousTree.nativeRefresh(nativeObjectID(rootSource)) + cache.sources = adapter.nativeReview + } + } + } + root, nodes, err := captureNativeTree(ctx, rootSource, reviewFocus.BusName, document, documentText, retained, cache) + if err != nil { + for _, source := range retained { + C.g_object_unref(C.gpointer(source)) + } + return nil, err + } + trace.begin_stage("tree-installation", root, "") + tree, err := adapter.installCapturedTree(root, nodes, document, documentText) + if err != nil { + for _, source := range retained { + C.g_object_unref(C.gpointer(source)) + } + return nil, err + } + trace.begin_stage("reference-cleanup", root, "") + adapter.clearNativeReview() + adapter.nativeReview = retained + adapter.nativeReviewBus = reviewFocus.BusName + trace.begin_stage("result-delivery", root, "") + return tree, nil +} + +// Remember a bounded set of event sources so document capture can start at +// native focus, without rediscovering it through cached browser chrome. All +// references are used and released on the GLib thread, including at shutdown. +func (adapter *Adapter) rememberNativeFocus(source *C.AtspiAccessible, id ObjectID) { + if !id.Valid() { + return + } + for i, item := range adapter.nativeFocus { + if item.id == id { + C.g_object_unref(C.gpointer(item.source)) + adapter.nativeFocus = append(adapter.nativeFocus[:i], adapter.nativeFocus[i+1:]...) + break + } + } + if len(adapter.nativeFocus) == 16 { + C.g_object_unref(C.gpointer(adapter.nativeFocus[0].source)) + adapter.nativeFocus = adapter.nativeFocus[1:] + } + owned := (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(source))) + adapter.nativeFocus = append(adapter.nativeFocus, nativeFocusReference{id: id, source: owned}) +} + +// An unregistered bridge window must not remain a focused chrome candidate +// after its replacement has acquired the same X11 client. Other windows keep +// their retained focus references. This runs only on the GLib owner. +func (adapter *Adapter) forgetNativeWindowFocus(windowID ObjectID) { + retained := adapter.nativeFocus[:0] + for _, item := range adapter.nativeFocus { + window := C.cthulhu_window_ancestor(item.source) + retired := nativeObjectID(window) == windowID + if window != nil { + C.g_object_unref(C.gpointer(window)) + } + if retired { + C.g_object_unref(C.gpointer(item.source)) + } else { + retained = append(retained, item) + } + } + adapter.nativeFocus = retained +} + +// Keep an exact document-to-frame association across Chromium tab switches. +// Some returned tabs temporarily lose their AT-SPI parent chain, although +// their document identity and the already correlated frame remain live. +func (adapter *Adapter) rememberDocumentWindow(document ObjectID, window *C.AtspiAccessible) { + if !document.Valid() || window == nil { + return + } + if adapter.documentWindows == nil { + adapter.documentWindows = make(map[ObjectID]nativeDocumentWindow) + } + if old, ok := adapter.documentWindows[document]; ok { + C.g_object_unref(C.gpointer(old.source)) + } else { + if len(adapter.documentWindowIDs) == 32 { + oldest := adapter.documentWindowIDs[0] + C.g_object_unref(C.gpointer(adapter.documentWindows[oldest].source)) + delete(adapter.documentWindows, oldest) + adapter.documentWindowIDs = adapter.documentWindowIDs[1:] + } + adapter.documentWindowIDs = append(adapter.documentWindowIDs, document) + } + adapter.documentWindows[document] = nativeDocumentWindow{ + id: nativeObjectID(window), source: (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(window))), + } +} + +func (adapter *Adapter) forgetDocumentWindow(document ObjectID) { + known, ok := adapter.documentWindows[document] + if !ok { + return + } + C.g_object_unref(C.gpointer(known.source)) + delete(adapter.documentWindows, document) + for i, id := range adapter.documentWindowIDs { + if id == document { + adapter.documentWindowIDs = append(adapter.documentWindowIDs[:i], adapter.documentWindowIDs[i+1:]...) + break + } + } + if adapter.activeDocument == document { + adapter.activeDocument = ObjectID{} + } +} + +func (adapter *Adapter) forgetWindowDocuments(window ObjectID) { + for _, id := range append([]ObjectID(nil), adapter.documentWindowIDs...) { + if adapter.documentWindows[id].id == window { + adapter.forgetDocumentWindow(id) + } + } + if adapter.selectedTabWindow == window { + adapter.selectedTabWindow = ObjectID{} + } +} + +func (adapter *Adapter) detachedDocumentWindow(source *C.AtspiAccessible, eventType string, detail int) (*C.AtspiAccessible, ObjectID) { + if adapter.selectedTabWindow == (ObjectID{}) && !adapter.activeDocument.Valid() { + return nil, ObjectID{} + } + var document *C.AtspiAccessible + if _, known := adapter.documentWindows[nativeObjectID(source)]; known { + document = (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(source))) + } else { + document = C.cthulhu_document_ancestor(source) + } + if document == nil { + return nil, ObjectID{} + } + id := nativeObjectID(document) + states := C.atspi_accessible_get_state_set(document) + showing := states != nil && C.atspi_state_set_contains(states, C.ATSPI_STATE_SHOWING) != 0 && + C.atspi_state_set_contains(states, C.ATSPI_STATE_VISIBLE) != 0 && + C.atspi_state_set_contains(states, C.ATSPI_STATE_DEFUNCT) == 0 + if states != nil { + C.g_object_unref(C.gpointer(states)) + } + C.g_object_unref(C.gpointer(document)) + known, ok := adapter.documentWindows[id] + if !showing || !ok || !restoredDocumentWindowAllowed(id, adapter.activeDocument, + adapter.selectedTabWindow, known.id, eventType, detail) { + return nil, ObjectID{} + } + frameStates := C.atspi_accessible_get_state_set(known.source) + frameActive := frameStates != nil && C.atspi_state_set_contains(frameStates, C.ATSPI_STATE_ACTIVE) != 0 && + C.atspi_state_set_contains(frameStates, C.ATSPI_STATE_SHOWING) != 0 && + C.atspi_state_set_contains(frameStates, C.ATSPI_STATE_DEFUNCT) == 0 + if frameStates != nil { + C.g_object_unref(C.gpointer(frameStates)) + } + if !frameActive { + return nil, ObjectID{} + } + return (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(known.source))), id +} + +func restoredDocumentWindowAllowed(document, active, selectedWindow, knownWindow ObjectID, eventType string, detail int) bool { + if !document.Valid() || !knownWindow.Valid() { + return false + } + if eventType == FocusedStateEvent && detail == 0 { + return false + } + if document == active { + return true + } + return selectedWindow == knownWindow && eventType == FocusedStateEvent && detail != 0 +} + +// Called only by the GLib owner at load completion. Chromium can finish an +// earlier load after the user has returned to chrome. Window activation alone +// cannot distinguish that from a load which should acquire document focus. +func (adapter *Adapter) focusedChrome(document ObjectID) ObjectID { + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() + for i := len(adapter.nativeFocus) - 1; i >= 0 && ctx.Err() == nil; i-- { + item := adapter.nativeFocus[i] + if item.id.BusName != document.BusName || item.id == document { + continue + } + C.atspi_accessible_clear_cache_single(item.source) + states := C.atspi_accessible_get_state_set(item.source) + if states == nil { + continue + } + focused := C.atspi_state_set_contains(states, C.ATSPI_STATE_FOCUSED) != 0 + C.g_object_unref(C.gpointer(states)) + if !focused { + continue + } + root, err := adapter.nativeDocumentRoot(ctx, item.id) + if root != nil { + C.g_object_unref(C.gpointer(root)) + } + if errors.Is(err, ErrNotInDocument) { + return item.id + } + } + return ObjectID{} +} + +// Return an owned reference to the outermost document containing focus. +// Parent traversal is bounded and never scans other windows or tabs. +func (adapter *Adapter) nativeDocumentRoot(ctx context.Context, focus ObjectID) (*C.AtspiAccessible, error) { + var source *C.AtspiAccessible + for _, item := range adapter.nativeFocus { + if item.id == focus { + source = (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(item.source))) + break + } + } + if source == nil { + return nil, fmt.Errorf("%w: document focus bus %q path %q", ErrObjectNotFound, focus.BusName, focus.Path) + } + C.atspi_accessible_clear_cache_single(source) + states := C.atspi_accessible_get_state_set(source) + if states != nil { + dead := C.atspi_state_set_contains(states, C.ATSPI_STATE_DEFUNCT) != 0 + C.g_object_unref(C.gpointer(states)) + if dead { + C.g_object_unref(C.gpointer(source)) + return nil, ErrStaleObject + } + } + var document *C.AtspiAccessible + defer func() { + if source != nil { + C.g_object_unref(C.gpointer(source)) + } + if document != nil { + C.g_object_unref(C.gpointer(document)) + } + }() + seen := make(map[ObjectID]bool) + for depth := 0; source != nil; depth++ { + if err := ctx.Err(); err != nil { + return nil, err + } + id := nativeObjectID(source) + if depth >= 256 || seen[id] { + return nil, ErrInvalidTree + } + seen[id] = true + C.atspi_accessible_clear_cache_single(source) + var nativeErr *C.GError + role := C.atspi_accessible_get_role(source, &nativeErr) + if nativeErr != nil { + err := nativeError("query document ancestor role", nativeErr) + C.g_error_free(nativeErr) + return nil, err + } + if role == C.ATSPI_ROLE_DOCUMENT_WEB || role == C.ATSPI_ROLE_DOCUMENT_FRAME || role == C.ATSPI_ROLE_EMBEDDED { + if document != nil { + C.g_object_unref(C.gpointer(document)) + } + document = (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(source))) + } + if role == C.ATSPI_ROLE_APPLICATION { + break + } + parent := C.atspi_accessible_get_parent(source, &nativeErr) + if nativeErr != nil { + if parent != nil { + C.g_object_unref(C.gpointer(parent)) + } + err := nativeError("query document ancestor", nativeErr) + C.g_error_free(nativeErr) + return nil, err + } + C.g_object_unref(C.gpointer(source)) + source = parent + } + if document == nil { + return nil, ErrNotInDocument + } + root := document + document = nil + return root, nil +} + +// geometryFromNative runs only during owned-tree capture on the GLib thread. +// All interface/state/rectangle references are released here; only scalar +// values cross the boundary. Unsupported or failed component queries leave +// bounds unknown, while cancellation aborts capture. diff --git a/internal/atspi/adapter_secure_native.go b/internal/atspi/adapter_secure_native.go new file mode 100644 index 0000000..08289c6 --- /dev/null +++ b/internal/atspi/adapter_secure_native.go @@ -0,0 +1,100 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" +) + +func (adapter *Adapter) SetSecureInputActive(active bool) { + adapter.secureMutex.Lock() + defer adapter.secureMutex.Unlock() + if adapter.secureCancel != nil { + adapter.secureCancel() + } + adapter.secureContext, adapter.secureCancel = context.WithCancel(context.Background()) + if active { + adapter.secureCancel() + } + adapter.secure.Store(active) + adapter.echoFocus.Store(nil) + adapter.secureEpoch.Add(1) + adapter.secureReset.Store(true) + if !active { + adapter.secureResync.Store(true) + } + for { + select { + case <-adapter.events: + default: + return + } + } +} + +func (adapter *Adapter) applySecureReset() { + if !adapter.secureReset.Swap(false) { + return + } + adapter.deferredLiveRegions = nil + adapter.invalidateTree() + adapter.treeMutex.Lock() + adapter.tree, adapter.documentTree, adapter.documentTextTree = nil, nil, nil + adapter.treeMutex.Unlock() + adapter.clearNativeDocument() + adapter.clearNativeReview() + adapter.clearMouseApplication() + for _, focus := range adapter.nativeFocus { + C.g_object_unref(C.gpointer(focus.source)) + } + adapter.nativeFocus = nil + for id := range adapter.documentWindows { + adapter.forgetDocumentWindow(id) + } + adapter.activeDocument, adapter.selectedTabWindow = ObjectID{}, ObjectID{} + adapter.foregroundWindow, adapter.promptRefreshWindow = ObjectID{}, ObjectID{} + adapter.promptScannedWindow = ObjectID{} + clear(adapter.navigationEcho) +} + +// Lock transitions cancel captures already in progress as well as later ones. +func (adapter *Adapter) secureRequestContext(ctx context.Context) (context.Context, context.CancelFunc) { + adapter.secureMutex.Lock() + defer adapter.secureMutex.Unlock() + if adapter.secureContext == nil { + adapter.secureContext, adapter.secureCancel = context.WithCancel(context.Background()) + } + requestContext, cancel := context.WithCancel(ctx) + if adapter.secure.Load() { + cancel() + } + stop := context.AfterFunc(adapter.secureContext, cancel) + return requestContext, func() { stop(); cancel() } +} + +// Serialize final delivery with lock queue retirement, including callbacks +// that began snapshotting before the lock name appeared. +func (adapter *Adapter) enqueueSecureEvent(event Event, epoch uint64) { + adapter.secureMutex.Lock() + defer adapter.secureMutex.Unlock() + if adapter.secure.Load() || epoch != adapter.secureEpoch.Load() { + return + } + adapter.observeEchoFocus(event) + // Editable transitions refresh key echo without adding a spoken state. + if event.Type == "object:state-changed:editable" { + return + } + select { + case adapter.events <- event: + default: + adapter.overflow.Add(1) + } +} diff --git a/internal/atspi/adapter_snapshot_native.go b/internal/atspi/adapter_snapshot_native.go new file mode 100644 index 0000000..4ea0aed --- /dev/null +++ b/internal/atspi/adapter_snapshot_native.go @@ -0,0 +1,190 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "fmt" + "strings" + "time" +) + +func nativeError(operation string, nativeError *C.GError) error { + if nativeError == nil { + return fmt.Errorf("%s failed", operation) + } + return fmt.Errorf("%s: %s", operation, C.GoString(nativeError.message)) +} + +func snapshotFromNative(source *C.AtspiAccessible) Snapshot { + return snapshotFromNativeWithCaret(source, true, false, false, true) +} + +func snapshotFromNativeWithCaret(source *C.AtspiAccessible, text, caretCharacter, documentMetadata, soundGeometry bool, captureAttributes ...bool) Snapshot { + return snapshotFromNativeWithOptions(source, text, caretCharacter, documentMetadata, soundGeometry, true, captureAttributes...) +} + +func snapshotFromNativeWithOptions(source *C.AtspiAccessible, text, caretCharacter, documentMetadata, soundGeometry, applicationName bool, captureAttributes ...bool) Snapshot { + captureText := C.gboolean(0) + if text { + captureText = 1 + } + captureCaretCharacter := C.gboolean(0) + if caretCharacter { + captureCaretCharacter = 1 + } + captureDocumentMetadata := C.gboolean(0) + if documentMetadata { + captureDocumentMetadata = 1 + } + captureSoundGeometry := C.gboolean(0) + if soundGeometry { + captureSoundGeometry = 1 + } + captureApplicationName := C.gboolean(0) + if applicationName { + captureApplicationName = 1 + } + captured := C.cthulhu_capture_snapshot(source, captureText, captureCaretCharacter, captureDocumentMetadata, captureSoundGeometry, captureApplicationName) + textContent := C.GoString(captured.text) + snapshot := NewSnapshotWithCaretCharacter( + C.GoString(captured.path), + C.GoString(captured.name), + C.GoString(captured.role), + C.GoString(captured.description), + textContent, + C.GoString(captured.caretCharacter), + ) + snapshot.TextCaretKnown = captured.text != nil && captured.textStartOffset >= 0 + if text && snapshot.Role != "password text" { + switch snapshot.Role { + case "button", "push button", "check box", "radio button", "toggle button", "menu item", "check menu item", "radio menu item": + snapshot.Mnemonic = native_mnemonic(source) + } + } + if snapshot.TextCaretKnown { + captureBrailleLine(&snapshot, textContent, C.GoString(captured.textBeforeCaret), int(captured.textStartOffset)) + if text := C.atspi_accessible_get_text(source); text != nil { + snapshot.TextAttributeRun = native_text_attribute_run(text, snapshot.BrailleCaret) + snapshot.Misspelled = TextAttributesMisspelled(snapshot.TextAttributeRun.Values) + if len(captureAttributes) != 0 && captureAttributes[0] { + start := snapshot.BrailleLineStart + snapshot.TextAttributeRuns = native_text_attribute_runs(text, start, start+len([]rune(snapshot.BrailleLine)), snapshot.TextAttributeRun) + } + if C.atspi_text_get_n_selections(text, nil) > 0 { + if selection := C.atspi_text_get_selection(text, 0, nil); selection != nil { + snapshot.SelectionStart, snapshot.SelectionEnd = int(selection.start_offset), int(selection.end_offset) + if snapshot.Role != "password text" && snapshot.SelectionEnd > snapshot.SelectionStart { + end := min(snapshot.SelectionEnd, snapshot.SelectionStart+maxSnapshotFieldLength) + selected := C.atspi_text_get_text(text, C.gint(snapshot.SelectionStart), C.gint(end), nil) + snapshot.SelectionText = strings.ToValidUTF8(C.GoString(selected), "�") + C.g_free(C.gpointer(selected)) + } + C.g_free(C.gpointer(selection)) + } + } + C.g_object_unref(C.gpointer(text)) + } + } + if caretCharacter && captured.editable == 0 && snapshot.Role != "terminal" && strings.ContainsRune(textContent, '\ufffc') { + budget := embeddedTextBudget{nodes: 32, characters: maxSnapshotFieldLength, deadline: time.Now().Add(100 * time.Millisecond)} + // Hypertext offsets refer to raw characters, before whitespace folding. + snapshot.Text = sanitizeSnapshotField(expandNativeEmbeddedText(source, textContent, int(captured.textStartOffset), 0, &budget)) + } + snapshot.BusName = sanitizeSnapshotField(C.GoString(captured.busName)) + if snapshot.Role == "radio button" { + group := C.cthulhu_radio_group_name(source) + snapshot.RadioGroupName = sanitizeSnapshotField(C.GoString(group)) + C.g_free(C.gpointer(group)) + } + snapshot.ApplicationName = sanitizeSnapshotField(C.GoString(captured.applicationName)) + snapshot.Visible = captured.visible != 0 + snapshot.Showing = captured.showing != 0 + snapshot.StatesKnown = captured.statesKnown != 0 + snapshot.Active = captured.active != 0 + snapshot.Autocomplete = captured.autocomplete != 0 && snapshot.Role == "entry" + snapshot.Focusable = captured.focusable != 0 + snapshot.Focused = captured.focused != 0 + snapshot.HasPopup = captured.hasPopup != 0 + snapshot.Checkable = captured.checkable != 0 + snapshot.Checked = captured.checked != 0 + snapshot.Defunct = captured.defunct != 0 + snapshot.Editable = captured.editable != 0 + snapshot.Expandable = captured.expandable != 0 + snapshot.Expanded = captured.expanded != 0 + snapshot.Indeterminate = captured.indeterminate != 0 + snapshot.Invalid = captured.invalid != 0 + snapshot.Multiselectable = captured.multiselectable != 0 + snapshot.ReadOnly = captured.readOnly != 0 + snapshot.Required = captured.required != 0 + snapshot.Selected = captured.selected != 0 + snapshot.Sensitive = captured.sensitive != 0 + snapshot.SensitiveKnown = captured.sensitiveKnown != 0 + snapshot.ValueKnown = captured.valueKnown != 0 + snapshot.Visited = captured.visited != 0 + snapshot.ExplicitName = captured.explicitName != 0 + snapshot.HeadingLevel = int(captured.headingLevel) + snapshot.PositionInSet = int(captured.positionInSet) + snapshot.SetSize = int(captured.setSize) + snapshot.SupportsClick = captured.supportsClick != 0 + snapshot.LiveRegion = captured.liveRegion != 0 + snapshot.LayoutTable = captured.layoutTable != 0 + snapshot.ChildCount = int(captured.childCount) + snapshot.ChildCountKnown = captured.childCountKnown != 0 + snapshot.TableRowCount = int(captured.tableRowCount) + snapshot.TableColumnCount = int(captured.tableColumnCount) + snapshot.TableRowIndex = int(captured.tableRowIndex) + snapshot.TableColumnIndex = int(captured.tableColumnIndex) + snapshot.TableRowSpan = int(captured.tableRowSpan) + snapshot.TableColumnSpan = int(captured.tableColumnSpan) + snapshot.TablePositionKnown = captured.tablePositionKnown != 0 + snapshot.TableRowHeaders = sanitizeSnapshotField(C.GoString(captured.tableRowHeaders)) + snapshot.TableColumnHeaders = sanitizeSnapshotField(C.GoString(captured.tableColumnHeaders)) + C.g_free(C.gpointer(captured.tableRowHeaders)) + C.g_free(C.gpointer(captured.tableColumnHeaders)) + snapshot.CharacterCount = int(captured.characterCount) + snapshot.EmbeddedObjectCount = int(captured.embeddedObjectCount) + snapshot.XMLRoles = sanitizeSnapshotField(C.GoString(captured.xmlRoles)) + snapshot.HTMLTag = sanitizeSnapshotField(C.GoString(captured.htmlTag)) + snapshot.ElementID = sanitizeSnapshotField(C.GoString(captured.elementID)) + snapshot.CurrentValue = float64(captured.currentValue) + snapshot.MaximumValue = float64(captured.maximumValue) + snapshot.MinimumValue = float64(captured.minimumValue) + snapshot.MinimumIncrement = float64(captured.minimumIncrement) + snapshot.ValueText = sanitizeSnapshotField(C.GoString(captured.valueText)) + snapshot.TextBeforeCaret = sanitizeTextContext(C.GoString(captured.textBeforeCaret)) + snapshot.SoundGeometry = soundGeometryFromNative(captured) + C.g_free(C.gpointer(captured.applicationName)) + C.g_free(C.gpointer(captured.name)) + C.g_free(C.gpointer(captured.role)) + C.g_free(C.gpointer(captured.description)) + C.g_free(C.gpointer(captured.text)) + C.g_free(C.gpointer(captured.textBeforeCaret)) + C.g_free(C.gpointer(captured.caretCharacter)) + C.g_free(C.gpointer(captured.valueText)) + C.g_free(C.gpointer(captured.xmlRoles)) + C.g_free(C.gpointer(captured.htmlTag)) + C.g_free(C.gpointer(captured.elementID)) + return snapshot +} + +func soundGeometryFromNative(captured C.cthulhu_snapshot) SoundGeometry { + return SoundGeometry{ + Object: Rectangle{X: int32(captured.objectX), Y: int32(captured.objectY), Width: int32(captured.objectWidth), Height: int32(captured.objectHeight)}, + Reference: Rectangle{X: int32(captured.referenceX), Y: int32(captured.referenceY), Width: int32(captured.referenceWidth), Height: int32(captured.referenceHeight)}, + ObjectKnown: captured.objectGeometryKnown != 0, ReferenceKnown: captured.referenceGeometryKnown != 0, + } +} + +func nativeObjectID(source *C.AtspiAccessible) ObjectID { + return NewObjectID( + C.GoString(C.cthulhu_accessible_bus_name(source)), + C.GoString(C.cthulhu_accessible_path(source)), + ) +} diff --git a/internal/atspi/adapter_text_boundary.c b/internal/atspi/adapter_text_boundary.c new file mode 100644 index 0000000..47fff03 --- /dev/null +++ b/internal/atspi/adapter_text_boundary.c @@ -0,0 +1,57 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "adapter_native.h" +#include + +AtspiTextRange *cthulhu_text_get_string_at_offset(AtspiText *text, gint offset, + AtspiTextGranularity unit, GError **error) { + if (unit != ATSPI_TEXT_GRANULARITY_LINE || offset < 0) { + return atspi_text_get_string_at_offset(text, offset, unit, error); + } + + // Chromium can retain layout boundaries past truncated hypertext. In a + // captured crash, LINE at the final U+2026 (140 of 141 characters) tried + // to take a substring starting at 146 and aborted the entire browser. + // Checking returned boundaries is too late: use bounded GetText for an + // ellipsis before invoking the provider's boundary calculation. + GError *probeError = NULL; + guint character = atspi_text_get_character_at_offset(text, offset, &probeError); + if (probeError != NULL) { + g_propagate_error(error, probeError); + return NULL; + } + if (character != 0x2026) { + return atspi_text_get_string_at_offset(text, offset, unit, error); + } + gint count = atspi_text_get_character_count(text, &probeError); + if (probeError != NULL) { + g_propagate_error(error, probeError); + return NULL; + } + if (count <= 0 || offset != count - 1) { + return atspi_text_get_string_at_offset(text, offset, unit, error); + } + + gint start = MAX(0, offset - 4095); + gchar *content = atspi_text_get_text(text, start, offset + 1, error); + if (content == NULL) return NULL; + if (!g_utf8_validate(content, -1, NULL) || + g_utf8_strlen(content, -1) != offset + 1 - start || + !g_str_has_suffix(content, "\342\200\246")) { + g_free(content); + return NULL; + } + + // Preserve explicit line breaks. A provider's visual wrapping is unsafe + // at this character; retain the bounded logical line and native offsets. + gchar *line = strrchr(content, '\n'); + line = line != NULL ? line + 1 : content; + AtspiTextRange *range = g_new0(AtspiTextRange, 1); + range->start_offset = start + g_utf8_pointer_to_offset(content, line); + range->end_offset = offset + 1; + range->content = g_strdup(line); + g_free(content); + return range; +} diff --git a/internal/atspi/adapter_tree_native.go b/internal/atspi/adapter_tree_native.go new file mode 100644 index 0000000..c44ccbe --- /dev/null +++ b/internal/atspi/adapter_tree_native.go @@ -0,0 +1,670 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + "runtime/cgo" + "strings" + "time" + "unsafe" +) + +func geometryFromNative(ctx context.Context, source *C.AtspiAccessible) (Geometry, error) { + return geometryFromNativeWithBounds(ctx, source, true) +} + +func geometryFromNativeWithBounds(ctx context.Context, source *C.AtspiAccessible, captureBounds bool) (Geometry, error) { + geometry := Geometry{} + if err := ctx.Err(); err != nil { + return geometry, err + } + states := C.atspi_accessible_get_state_set(source) + if states == nil { + return geometry, ctx.Err() + } + geometry.VisibilityKnown = true + geometry.Visible = C.atspi_state_set_contains(states, C.ATSPI_STATE_VISIBLE) != 0 + geometry.Showing = C.atspi_state_set_contains(states, C.ATSPI_STATE_SHOWING) != 0 + C.g_object_unref(C.gpointer(states)) + // libatspi specifies that component bounds are meaningful only when both + // states are present. Avoid querying hidden/offscreen components. + if !captureBounds || !geometry.Visible || !geometry.Showing { + return geometry, ctx.Err() + } + if err := ctx.Err(); err != nil { + return geometry, err + } + component := C.atspi_accessible_get_component_iface(source) + if component == nil { + return geometry, ctx.Err() + } + defer C.g_object_unref(C.gpointer(component)) + if err := ctx.Err(); err != nil { + return geometry, err + } + var nativeErr *C.GError + bounds := C.atspi_component_get_extents(component, C.ATSPI_COORD_TYPE_SCREEN, &nativeErr) + if bounds != nil { + defer C.g_free(C.gpointer(bounds)) + } + if nativeErr != nil { + C.g_error_free(nativeErr) + return geometry, ctx.Err() + } + if bounds != nil { + rectangle := Rectangle{X: int32(bounds.x), Y: int32(bounds.y), Width: int32(bounds.width), Height: int32(bounds.height)} + if rectangle.Valid() { + geometry.Bounds = rectangle + geometry.BoundsKnown = true + } + } + return geometry, ctx.Err() +} + +func admitNativeChild(scheduled map[ObjectID]struct{}, childID ObjectID) bool { + if _, duplicate := scheduled[childID]; duplicate { + return false + } + scheduled[childID] = struct{}{} + return true +} + +type nativeTreeCache struct { + nodes map[ObjectID]treeEntry + sources map[ObjectID]*C.AtspiAccessible +} + +// captureNativeTree copies the desktop or, when reviewBusName is set, just the +// focused application's subtree. The latter keeps flat review independent of +// unrelated AT-SPI providers that can be slow or transiently unavailable. +func captureNativeTree(ctx context.Context, root *C.AtspiAccessible, reviewBusName string, document, documentText bool, retained map[ObjectID]*C.AtspiAccessible, cache nativeTreeCache) (ObjectID, []TreeNode, error) { + trace := capture_diagnostics(ctx) + trace.begin_stage("tree-setup", ObjectID{}, "") + reviewOnly := !document && reviewBusName != "" + rootID := nativeObjectID(root) + if !rootID.Valid() { + C.g_object_unref(C.gpointer(root)) + return ObjectID{}, nil, fmt.Errorf("%w: native root identity is invalid", ErrInvalidTree) + } + type pendingNode struct { + source *C.AtspiAccessible + clip Rectangle + clipped bool + clipChanged bool + parentIndex int + } + pending := []pendingNode{{source: root, parentIndex: -1}} + textBytes := 0 + scheduled := map[ObjectID]struct{}{rootID: {}} + nodes := make([]TreeNode, 0, 128) + // Embedded frames can belong to another AT-SPI process. Application names + // are stable within one bus, including during flat review of a large page. + applicationNames := make(map[string]string) + releasePending := func() { + for _, item := range pending { + C.g_object_unref(C.gpointer(item.source)) + } + } + + for len(pending) != 0 { + if err := ctx.Err(); err != nil { + releasePending() + return ObjectID{}, nil, err + } + last := len(pending) - 1 + item := pending[last] + source := item.source + pending = pending[:last] + sourceID := nativeObjectID(source) + cached, known := cache.nodes[sourceID] + refresh := !known || cached.snapshotInvalid || cached.textInvalid || cached.geometryInvalid || cached.childrenInvalid || cached.childrenUnavailable + snapshot := cached.snapshot + trace.begin_stage("snapshot", sourceID, snapshot.Role) + if refresh { + // Only changed/new objects require synchronous provider queries. + // Reusing live siblings matches Python's event-driven web cache and + // prevents a small insertion from repeatedly timing out on a big page. + // New document and flat-review nodes already have libatspi's + // cached child lists. Clearing them forces another child-count + // request even for a cached leaf, which can fail on a busy provider. + // Known dirty entries still need a fresh provider snapshot. Preserve + // the existing full refresh for desktop/object capture. + if known || (!document && !reviewOnly) { + C.atspi_accessible_clear_cache_single(source) + } else if reviewOnly { + // A browse scroll can leave SHOWING cached from the previous + // viewport without a state-change event for each descendant. + // Refresh states on entry to visual capture, while preserving + // cached children and interfaces for slow native providers. + source.cached_properties &^= C.ATSPI_CACHE_STATES + } + // Navigation refreshes sound geometry only for the announced target, + // after scrolling. Capturing it for every descendant repeats native + // ancestor walks and can exhaust the document capture deadline. + applicationName, knownApplication := applicationNames[nativeObjectID(source).BusName] + if knownApplication { + snapshot = snapshotFromNativeWithOptions(source, !document, false, document, false, false) + snapshot.ApplicationName = applicationName + } else { + snapshot = snapshotFromNativeWithCaret(source, !document, false, document, false) + } + } + trace.progress(snapshot.Role, len(nodes), len(pending)+1, textBytes) + if _, knownApplication := applicationNames[snapshot.BusName]; !knownApplication { + applicationNames[snapshot.BusName] = snapshot.ApplicationName + } + if snapshot.Defunct { + if (document || reviewOnly) && item.parentIndex >= 0 { + // Providers can retire a descendant after exposing it in its + // parent's child list. Drop that edge and keep the live window. + children := nodes[item.parentIndex].Children + for index, child := range children { + if child == snapshot.ID() { + nodes[item.parentIndex].Children = append(children[:index], children[index+1:]...) + break + } + } + C.g_object_unref(C.gpointer(source)) + continue + } + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, fmt.Errorf("%w: bus %q path %q", ErrDeadObject, snapshot.BusName, snapshot.Path) + } + if retained != nil { + retained[snapshot.ID()] = (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(source))) + } + + trace.begin_stage("geometry", snapshot.ID(), snapshot.Role) + geometry := cached.geometry + var geometryErr error + if refresh { + geometry, geometryErr = geometryFromNativeWithBounds(ctx, source, !document || documentText) + } + if geometryErr != nil { + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, geometryErr + } + + clip, clipped := item.clip, item.clipped + if geometry.BoundsKnown { + if clipped { + clip, _ = clip.Intersection(geometry.Bounds) + } else { + clip = geometry.Bounds + clipped = true + } + } else if geometry.VisibilityKnown && (!geometry.Visible || !geometry.Showing) && snapshot.Role != "application" && snapshot.Role != "desktop frame" { + clip, clipped = Rectangle{}, true + } + childClip, childClipped := clip, clipped + if snapshot.Role == "page tab" && geometry.Visible && geometry.Showing { + // A tab's bounds describe its header, while its accessible children + // can be the displayed page below it. Preserve the parent viewport. + childClip, childClipped = item.clip, item.clipped + } + trace.begin_stage("visible-text", snapshot.ID(), snapshot.Role) + text := VisibleText{Limited: true, Issue: TextTreeLimit} + if (!document || documentText) && textBytes < maxTreeTextBytes { + if known && !cached.textInvalid && !cached.geometryInvalid && !item.clipChanged { + text = cached.text + } else { + var textErr error + text, textErr = textFromNative(ctx, source, geometry, snapshot, clip) + if textErr != nil { + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, textErr + } + } + size := 0 + for _, r := range text.Ranges { + size += len(r.Text) + } + if textBytes+size > maxTreeTextBytes { + text = VisibleText{Limited: true, Issue: TextTreeLimit} + trace.text_issue(TextTreeLimit) + } else { + textBytes += size + } + } + + trace.begin_stage("table-viewport", snapshot.ID(), snapshot.Role) + // Visual review cannot use descendants of hidden controls. Inactive + // notebook pages and closed GTK combo menus can expose thousands of + // children; traversing them can exhaust the entire capture deadline. + // Keep semantic document and desktop/object capture complete. + captureChildren := !reviewOnly || !geometry.VisibilityKnown || + (geometry.Visible && geometry.Showing) || snapshot.Role == "application" || snapshot.Role == "desktop frame" + // A visibility change can reveal children omitted by an earlier review + // capture, even when the provider emits no children-changed event. + cachedChildren := known && !cached.childrenInvalid && !cached.childrenUnavailable && (!reviewOnly || !cached.geometryInvalid) + childrenUnavailable := false + for _, id := range cached.children { + if cache.sources[id] == nil { + cachedChildren = false + break + } + } + var childCountError *C.GError + childCount := len(cached.children) + var tableChildren []*C.AtspiAccessible + tableViewport := false + if reviewOnly && captureChildren { + var tableErr error + tableChildren, tableViewport, tableErr = native_review_table_children(ctx, source, clip) + if tableErr != nil { + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, fmt.Errorf("%w (bus %q path %q role %q)", tableErr, snapshot.BusName, snapshot.Path, snapshot.Role) + } + // The pending stack takes its own reference to each admitted cell. + defer func(children []*C.AtspiAccessible) { + for _, child := range children { + C.g_object_unref(C.gpointer(child)) + } + }(tableChildren) + } + trace.begin_stage("child-count", snapshot.ID(), snapshot.Role) + if !captureChildren { + childCount = 0 + } else if tableViewport { + childCount = len(tableChildren) + } else if !cachedChildren { + // Snapshot refresh above already cleared dirty entries. Clearing + // again discards the state and interface data just fetched. + childCount = int(C.atspi_accessible_get_child_count(source, &childCountError)) + } + if childCountError != nil { + err := fmt.Errorf("%w (bus %q path %q role %q captured_nodes %d)", + nativeError("query AT-SPI child count", childCountError), snapshot.BusName, snapshot.Path, snapshot.Role, len(nodes)) + C.g_error_free(childCountError) + if !reviewOnly || item.parentIndex < 0 || ctx.Err() != nil { + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, err + } + childCount, childrenUnavailable = 0, true + } + if childCount < 0 { + if reviewOnly && item.parentIndex >= 0 && ctx.Err() == nil { + childCount, childrenUnavailable = 0, true + } else { + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, fmt.Errorf("query AT-SPI child count: negative result (bus %q path %q role %q captured_nodes %d)", + snapshot.BusName, snapshot.Path, snapshot.Role, len(nodes)) + } + } + if reviewBusName == "" && len(scheduled)+childCount > maxTreeNodes { + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, fmt.Errorf("%w: native tree exceeds limit %d", ErrInvalidTree, maxTreeNodes) + } + + trace.begin_stage("child-enumeration", snapshot.ID(), snapshot.Role) + children := make([]ObjectID, 0, childCount) + for index := 0; index < childCount; index++ { + if err := ctx.Err(); err != nil { + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, err + } + var childError *C.GError + var child *C.AtspiAccessible + if tableViewport { + child = (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(tableChildren[index]))) + } else if cachedChildren { + child = (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(cache.sources[cached.children[index]]))) + } else { + child = C.atspi_accessible_get_child_at_index(source, C.gint(index), &childError) + } + if childError != nil { + err := nativeError("query AT-SPI child", childError) + C.g_error_free(childError) + if child != nil { + C.g_object_unref(C.gpointer(child)) + } + if reviewOnly && ctx.Err() == nil { + childrenUnavailable = true + continue + } + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, err + } + if child == nil { + // Child lists can change between the count and lookup calls. Match + // Python Cthulhu's traversal policy: omit an unavailable child while + // retaining the rest of the current parent snapshot. A missing child + // must not prevent flat review of an otherwise live focused window. + continue + } + childID := nativeObjectID(child) + if !childID.Valid() { + C.g_object_unref(C.gpointer(child)) + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, fmt.Errorf("%w: native child identity is invalid", ErrInvalidTree) + } + if reviewBusName != "" && childID.BusName != reviewBusName { + C.g_object_unref(C.gpointer(child)) + continue + } + if len(scheduled) >= maxTreeNodes { + C.g_object_unref(C.gpointer(child)) + C.g_object_unref(C.gpointer(source)) + releasePending() + return ObjectID{}, nil, fmt.Errorf("%w: native tree exceeds limit %d", ErrInvalidTree, maxTreeNodes) + } + if !admitNativeChild(scheduled, childID) { + // Chromium can transiently expose the same accessible through more + // than one child edge while replacing document content. Python's + // flat-review traversal tolerates that provider defect. Keep the + // first edge so the owned snapshot remains a proper tree rather than + // rejecting the entire active window. + C.g_object_unref(C.gpointer(child)) + continue + } + children = append(children, childID) + pending = append(pending, pendingNode{source: child, clip: childClip, clipped: childClipped, + clipChanged: item.clipChanged || !known || cached.geometryInvalid, parentIndex: len(nodes)}) + } + if document && refresh { + snapshot.TextChildren = nativeTextChildren(ctx, source, snapshot.CharacterCount, children) + } + nodes = append(nodes, TreeNode{Snapshot: snapshot, Children: children, Geometry: geometry, Text: text, ChildrenUnavailable: childrenUnavailable}) + trace.progress(snapshot.Role, len(nodes), len(pending), textBytes) + C.g_object_unref(C.gpointer(source)) + } + return rootID, nodes, nil +} + +//export cthulhuAtspiTreeCaptureCallback +func cthulhuAtspiTreeCaptureCallback(userData unsafe.Pointer) { + if userData == nil { + return + } + callbackHandle := cgo.Handle(C.cthulhu_callback_value((*C.cthulhu_callback_data)(userData))) + adapter, ok := callbackHandle.Value().(*Adapter) + if !ok { + return + } + request := <-adapter.treeRequests + capture_diagnostics(request.ctx).begin_stage("callback-setup", request.reviewFocus, "") + adapter.applySecureReset() + if request.ctx.Err() != nil { + request.result <- treeCaptureResult{err: request.ctx.Err()} + return + } + if adapter.secure.Load() { + request.result <- treeCaptureResult{err: errors.New("screen lock active")} + return + } + if request.transferItem { + item, err := adapter.nativeTransferItem(request.ctx, request.reviewFocus, request.positionOffset) + request.result <- treeCaptureResult{item: item, err: err} + } else if request.listActions || request.actionTarget != nil { + object := request.reviewFocus + if request.actionTarget != nil { + object = request.actionTarget.Object + } + actions, err := adapter.native_actions(request.ctx, object, request.actionTarget, request.actionName) + request.result <- treeCaptureResult{actions: actions, err: err} + } else if request.ocrGeometry { + geometry, err := adapter.nativeOCRGeometry(request.ctx, request.reviewFocus, request.ocrZone) + request.result <- treeCaptureResult{ocr: geometry, err: err} + } else if request.pointReview { + point, err := adapter.nativeReviewAtPoint(request.ctx, request.pointX, request.pointY, request.pointPID) + request.result <- treeCaptureResult{point: point, err: err} + } else if request.brailleRoute != nil { + err := adapter.routeNativeBraille(request.ctx, *request.brailleRoute) + request.result <- treeCaptureResult{err: err} + } else if request.setFocusedCaret { + err := adapter.setNativeFocusedTextCaret(request.ctx, request.reviewFocus, request.positionOffset) + request.result <- treeCaptureResult{err: err} + } else if request.readFocusedLine { + content, err := adapter.read_native_focused_line(request.ctx, request.reviewFocus) + request.result <- treeCaptureResult{content: content, err: err} + } else if request.readFocusedText { + content, err := adapter.readNativeFocusedText(request.ctx, request.reviewFocus) + request.result <- treeCaptureResult{content: content, err: err} + } else if request.readAttributes { + attributes, err := adapter.readNativeCharacterAttributes(request.ctx, request.reviewFocus) + request.result <- treeCaptureResult{attributes: attributes, err: err} + } else if request.contextOnly { + owner, err := adapter.nativeDocumentContext(request.ctx, request.reviewFocus) + request.result <- treeCaptureResult{owner: owner, err: err} + } else if request.caretObject.Valid() { + caret, err := adapter.readNativeDocumentCaret(request.ctx, request.caretObject, request.caretOffset, request.caretUnit) + request.result <- treeCaptureResult{caret: caret, err: err} + } else if request.activate { + err := adapter.activateNativeDocumentObject(request.ctx, request.position, request.reviewFocus) + request.result <- treeCaptureResult{err: err} + } else if request.soundObjects[0].Valid() { + geometry, err := adapter.captureNativeDocumentSoundGeometry(request.ctx, request.soundObjects) + request.result <- treeCaptureResult{soundGeometry: geometry, err: err} + } else if request.position.Valid() { + err := adapter.setNativeDocumentPosition(request.ctx, request.position, request.reviewFocus, request.positionOffset, request.usePositionOffset) + request.result <- treeCaptureResult{err: err} + } else { + tree, err := adapter.captureDesktop(request.ctx, request.reviewFocus, request.document, request.documentText) + request.result <- treeCaptureResult{tree: tree, err: err} + } +} + +func (adapter *Adapter) applyTreeInvalidation(eventType string, event *C.AtspiEvent) bool { + if isDocumentLifecycleEvent(eventType) { + clear(adapter.navigationEcho) + sourceID := nativeObjectID(event.source) + adapter.treeMutex.Lock() + documentTree := adapter.documentTree + adapter.treeMutex.Unlock() + replacement := false + if documentTree != nil { + root, err := documentTree.Root() + if err == nil && root.ID().BusName == sourceID.BusName { + _, err = documentTree.Reference(sourceID) + replacement = errors.Is(err, ErrObjectNotFound) + } + } + adapter.invalidateTreeEvent(eventType, 0, sourceID, ObjectID{}) + // A replacement page can have a different accessible path from the + // captured document. In that case invalidating the event source is a + // no-op. Retire the old tree only when this is the focused document; + // background tabs must not displace the active browse position. + if replacement && len(adapter.nativeFocus) != 0 { + focus := adapter.nativeFocus[len(adapter.nativeFocus)-1].id + ctx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond) + active, err := adapter.nativeDocumentRoot(ctx, focus) + cancel() + if err == nil { + activeID := nativeObjectID(active) + C.g_object_unref(C.gpointer(active)) + adapter.invalidateReplacedDocument(sourceID, activeID) + } + } + return false + } + childrenAdded := strings.HasPrefix(eventType, ChildrenAddedEvent) + childrenRemoved := strings.HasPrefix(eventType, ChildrenRemovedEvent) + textChanged := strings.HasPrefix(eventType, TextInsertedEvent) || strings.HasPrefix(eventType, TextDeletedEvent) || eventType == TextBoundsChangedEvent || eventType == TextAttributesChangedEvent || eventType == CaretEvent + if textChanged { + adapter.invalidateTreeEvent(eventType, int(C.cthulhu_event_detail1(event)), nativeObjectID(event.source), ObjectID{}) + return eventType == TextBoundsChangedEvent || eventType == TextAttributesChangedEvent + } + geometryChanged := eventType == BoundsChangedEvent || eventType == VisibleStateEvent || eventType == ShowingStateEvent + semanticChanged := semanticSnapshotChanged(eventType) + if !childrenAdded && !childrenRemoved && eventType != DefunctStateEvent && !geometryChanged && !semanticChanged { + return false + } + sourceID := nativeObjectID(event.source) + if semanticChanged { + adapter.invalidateTreeEvent(eventType, int(C.cthulhu_event_detail1(event)), sourceID, ObjectID{}) + return false + } + childID := ObjectID{} + if childrenRemoved { + child := C.cthulhu_event_active_descendant(event) + childID = nativeObjectID(child) + } + detail1 := int(C.cthulhu_event_detail1(event)) + // Setting Chromium's caret can retire the target or one of its descendants + // and immediately replace it with a new provider object. That defunct event + // is part of the navigation echo, but its native object is still dead. + // Retain the document and live siblings while refreshing the affected + // parent's children, so navigation can recover the replacement. + navigationDefunct := eventType == DefunctStateEvent && detail1 != 0 && adapter.navigationEcho[sourceID] != 0 + adapter.invalidateTreeEventWithPolicy(eventType, detail1, sourceID, childID, navigationDefunct) + if navigationDefunct { + delete(adapter.navigationEcho, sourceID) + } + return true +} + +func (adapter *Adapter) invalidateReplacedDocument(sourceID, activeID ObjectID) { + if !sourceID.Valid() || sourceID != activeID { + return + } + adapter.treeMutex.Lock() + trees := []*AccessibleTree{adapter.tree, adapter.documentTree, adapter.documentTextTree} + adapter.treeMutex.Unlock() + for _, tree := range trees { + if tree == nil { + continue + } + root, err := tree.Root() + if err != nil || root.ID().BusName != sourceID.BusName { + continue + } + if _, err := tree.Reference(sourceID); err == nil { + continue + } + adapter.treeInvalidations.Add(uint64(tree.Invalidate(root.ID()))) + } +} + +func (adapter *Adapter) invalidateTreeEvent(eventType string, detail1 int, sourceID, childID ObjectID) { + adapter.invalidateTreeEventWithPolicy(eventType, detail1, sourceID, childID, false) +} + +func (adapter *Adapter) invalidateTreeEventWithPolicy(eventType string, detail1 int, sourceID, childID ObjectID, navigationDefunct bool) { + if eventType == DefunctStateEvent && detail1 == 0 { + return + } + if eventType != CaretEvent { + // Background providers cannot change the owned document's text lines. + for id := range adapter.documentLineCache { + if id.BusName == sourceID.BusName { + delete(adapter.documentLineCache, id) + } + } + } + adapter.treeMutex.Lock() + trees := []*AccessibleTree{adapter.tree, adapter.documentTree, adapter.documentTextTree} + adapter.treeMutex.Unlock() + for index, tree := range trees { + if navigationDefunct && index == 1 && tree != nil { + tree.mu.RLock() + entry := tree.nodes[sourceID] + tree.mu.RUnlock() + adapter.treeInvalidations.Add(uint64(tree.Invalidate(sourceID))) + if entry.hasParent { + adapter.treeInvalidations.Add(uint64(tree.MarkChildrenChanged(entry.parent))) + } + continue + } + // Structural matching consumes the semantic document snapshot. Other + // owned trees remain usable for object/flat review until their own + // established text, geometry, child, or lifecycle invalidation. + if semanticSnapshotChanged(eventType) && index != 1 { + continue + } + // Caret position and viewport bounds do not change semantic order, + // names or hidden state. Flat review still needs these invalidations. + if index == 1 && (eventType == CaretEvent || eventType == BoundsChangedEvent || eventType == TextBoundsChangedEvent || eventType == ShowingStateEvent) { + continue + } + // The visual-line tree receives layout, visibility, and text + // invalidations. A caret event supplies its current offset separately, + // so it does not make otherwise-current line geometry stale. + if index == 2 && eventType == CaretEvent { + continue + } + if index == 1 && tree != nil && (strings.HasPrefix(eventType, ChildrenAddedEvent) || + strings.HasPrefix(eventType, ChildrenRemovedEvent) && !childID.Valid()) { + adapter.treeInvalidations.Add(uint64(tree.MarkChildrenChanged(sourceID))) + continue + } + adapter.invalidateCapturedTree(tree, eventType, detail1, sourceID, childID) + } +} + +func (adapter *Adapter) invalidateCapturedTree(tree *AccessibleTree, eventType string, detail1 int, sourceID, childID ObjectID) { + if tree == nil { + return + } + + removed := 0 + switch { + case isDocumentLifecycleEvent(eventType): + // Browsers can reuse an accessible path when replacing a document. + // Retire its generation, including all descendants, before recapture. + removed = tree.Invalidate(sourceID) + case strings.HasPrefix(eventType, TextInsertedEvent) || strings.HasPrefix(eventType, TextDeletedEvent) || eventType == TextBoundsChangedEvent || eventType == TextAttributesChangedEvent || eventType == CaretEvent: + removed = tree.InvalidateText(sourceID) + case eventType == BoundsChangedEvent || eventType == VisibleStateEvent || eventType == ShowingStateEvent: + removed = tree.InvalidateGeometry(sourceID) + case eventType == DefunctStateEvent: + removed = tree.Invalidate(sourceID) + case semanticSnapshotChanged(eventType): + // Refresh changed semantics without discarding document/caret identities. + // Events outside this tree remain a no-op. + removed = tree.InvalidateSnapshot(sourceID) + case strings.HasPrefix(eventType, ChildrenAddedEvent): + removed = tree.InvalidateChildren(sourceID) + case strings.HasPrefix(eventType, ChildrenRemovedEvent): + if childID.Valid() { + removed = tree.Invalidate(childID) + } else { + removed = tree.InvalidateChildren(sourceID) + } + } + adapter.treeInvalidations.Add(uint64(removed)) +} + +func semanticSnapshotChanged(eventType string) bool { + if eventType == AccessibleNameEvent || eventType == ValueChangedEvent || eventType == AccessibleValueEvent { + return true + } + switch eventType { + case "object:state-changed:checked", + "object:state-changed:expanded", + "object:state-changed:indeterminate", + "object:state-changed:invalid-entry", + "object:state-changed:pressed", + "object:state-changed:read-only", + "object:state-changed:required", + "object:state-changed:selected", + "object:state-changed:sensitive", + "object:state-changed:visited": + return true + default: + return false + } +} + +func isDocumentLifecycleEvent(eventType string) bool { + return eventType == DocumentReloadEvent || eventType == DocumentLoadCompleteEvent || eventType == DocumentLoadStoppedEvent +} diff --git a/internal/atspi/adapter_tree_test.go b/internal/atspi/adapter_tree_test.go new file mode 100644 index 0000000..198a2aa --- /dev/null +++ b/internal/atspi/adapter_tree_test.go @@ -0,0 +1,515 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "context" + "errors" + "fmt" + "testing" + "time" +) + +func TestAdmitNativeChildKeepsFirstTreeEdge(t *testing.T) { + child := NewObjectID(":1.42", "/child") + scheduled := make(map[ObjectID]struct{}) + if !admitNativeChild(scheduled, child) { + t.Fatal("first child edge was rejected") + } + if admitNativeChild(scheduled, child) { + t.Fatal("duplicate child edge was accepted") + } + if len(scheduled) != 1 { + t.Fatalf("scheduled children = %d, want 1", len(scheduled)) + } +} + +func TestActivationRefreshesAncestorOrderWithoutRetiringSiblings(t *testing.T) { + tree := testTree(t) + root, _ := tree.Root() + sibling, _, _ := tree.FirstChild(root) + parent, _ := tree.Reference(testID("/second")) + target, _, _ := tree.FirstChild(parent) + if got := tree.markAncestorChildrenChanged(target.ID()); got != 3 { + t.Fatalf("invalidated = %d, want target and two ancestors", got) + } + for _, ref := range []ObjectReference{target, parent, root} { + if _, err := tree.Resolve(ref); err != nil { + t.Fatalf("activation retired a live identity: %v", err) + } + if _, _, err := tree.FirstChild(ref); !errors.Is(err, ErrIncompleteTree) { + t.Fatalf("activated ancestry retained old child order: %v", err) + } + } + if _, err := tree.Resolve(sibling); err != nil { + t.Fatalf("activation retired unrelated sibling: %v", err) + } + if _, _, err := tree.FirstChild(sibling); err != nil { + t.Fatalf("activation invalidated unrelated child order: %v", err) + } + if got := tree.markAncestorChildrenChanged(target.ID()); got != 0 { + t.Fatalf("repeated activation invalidated %d fresh entries", got) + } + if got := tree.markAncestorChildrenChanged(testID("/missing")); got != 0 { + t.Fatalf("unknown activation invalidated %d entries", got) + } +} + +func TestDocumentCompletionRetainsNativeFocusWithoutChromeFocus(t *testing.T) { + chrome := NewObjectID(":1.42", "/address") + for _, eventType := range []string{DocumentLoadCompleteEvent, DocumentLoadStoppedEvent, BusyStateEvent} { + t.Run(eventType, func(t *testing.T) { + if !shouldRetainNativeFocus(eventType, 0, ObjectID{}) { + t.Fatal("completion cannot resolve its document without a retained native source") + } + if shouldRetainNativeFocus(eventType, 0, chrome) { + t.Fatal("background completion displaced retained chrome focus") + } + }) + } + for _, eventType := range []string{DocumentReloadEvent, BusyStateEvent} { + if shouldRetainNativeFocus(eventType, 1, ObjectID{}) { + t.Fatalf("loading start %q acquired document focus", eventType) + } + } +} + +func TestDetachedDocumentWindowRequiresSelectedOwnedTab(t *testing.T) { + document := NewObjectID(":1.42", "/old_document") + window := NewObjectID(":1.42", "/browser_window") + other := NewObjectID(":1.42", "/other_window") + for _, tc := range []struct { + name string + active, selected, known ObjectID + eventType string + detail int + want bool + }{ + {"returned selected tab", ObjectID{}, window, window, FocusedStateEvent, 1, true}, + {"other window selected", ObjectID{}, other, window, FocusedStateEvent, 1, false}, + {"background focus loss", ObjectID{}, window, window, FocusedStateEvent, 0, false}, + {"active focus loss", document, ObjectID{}, window, FocusedStateEvent, 0, false}, + {"background caret", ObjectID{}, window, window, CaretEvent, 1, false}, + {"established document caret", document, ObjectID{}, window, CaretEvent, 1, true}, + } { + t.Run(tc.name, func(t *testing.T) { + if got := restoredDocumentWindowAllowed(document, tc.active, tc.selected, tc.known, tc.eventType, tc.detail); got != tc.want { + t.Fatalf("window restoration = %t, want %t", got, tc.want) + } + }) + } +} + +func TestCaptureDesktopRejectsUnavailableAdapterAndCanceledContext(t *testing.T) { + adapter := New() + if _, err := adapter.CaptureDesktop(context.Background()); err == nil { + t.Fatal("capture succeeded before adapter start") + } + canceled, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := adapter.CaptureDesktop(canceled); !errors.Is(err, context.Canceled) { + t.Fatalf("canceled capture error = %v", err) + } + if _, err := adapter.CaptureDesktop(nil); err == nil { + t.Fatal("capture accepted a nil context") + } +} + +func TestDocumentSoundGeometryHonorsCaptureGateAndCancellation(t *testing.T) { + adapter := New() + tree := testTree(t) + object, _ := tree.Reference(testID("/first")) + adapter.SetCaptureSoundGeometry(false) + geometry, err := adapter.CaptureDocumentSoundGeometry(context.Background(), object, ObjectReference{}) + if err != nil || geometry != [2]SoundGeometry{} { + t.Fatalf("disabled sound geometry accessed the stopped adapter: %+v, %v", geometry, err) + } + adapter.SetCaptureSoundGeometry(true) + canceled, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := adapter.CaptureDocumentSoundGeometry(canceled, object, ObjectReference{}); !errors.Is(err, context.Canceled) { + t.Fatalf("canceled geometry capture error = %v", err) + } + adapter.documentTree = tree + tree.Invalidate(object.ID()) + if _, err := adapter.captureNativeDocumentSoundGeometry(context.Background(), [2]ObjectReference{object}); !errors.Is(err, ErrStaleObject) { + t.Fatalf("stale geometry reference accepted: %v", err) + } +} + +func TestDocumentCaptureTreeIsIndependentAndInvalidated(t *testing.T) { + for _, eventType := range []string{ChildrenAddedEvent, DefunctStateEvent, DocumentReloadEvent, "shutdown"} { + t.Run(eventType, func(t *testing.T) { + adapter := New() + adapter.tree = testTree(t) + adapter.documentTree = testTree(t) + root, _ := adapter.tree.Root() + reviewRef, _ := adapter.tree.Reference(testID("/first")) + documentRef, _ := adapter.documentTree.Reference(testID("/first")) + if eventType == "shutdown" { + adapter.invalidateTree() + } else { + adapter.invalidateTreeEvent(eventType, 1, root.ID(), ObjectID{}) + } + if _, err := adapter.tree.Resolve(reviewRef); !errors.Is(err, ErrStaleObject) { + t.Fatalf("review reference survived %s: %v", eventType, err) + } + if eventType == ChildrenAddedEvent { + if _, err := adapter.documentTree.Resolve(documentRef); err != nil { + t.Fatalf("insertion retired surviving document child: %v", err) + } + documentRoot, _ := adapter.documentTree.Root() + if _, _, err := adapter.documentTree.FirstChild(documentRoot); !errors.Is(err, ErrIncompleteTree) { + t.Fatalf("insertion left old child order navigable: %v", err) + } + } else if _, err := adapter.documentTree.Resolve(documentRef); !errors.Is(err, ErrStaleObject) { + t.Fatalf("document reference survived %s: %v", eventType, err) + } + }) + } + adapter := New() + adapter.tree = testTree(t) + root, _ := adapter.tree.Root() + reviewRef, _ := adapter.tree.Reference(testID("/first")) + snapshot := NewSnapshot(root.ID().Path, "Document", "document web", "", "") + snapshot.BusName = root.ID().BusName + document, err := adapter.installCapturedTree(root.ID(), []TreeNode{{Snapshot: snapshot}}, true, false) + if err != nil { + t.Fatal(err) + } + if document == adapter.tree { + t.Fatal("document capture replaced review tree") + } + if _, err := adapter.tree.Resolve(reviewRef); err != nil { + t.Fatalf("document capture invalidated independent review position: %v", err) + } +} + +func TestReplacementDocumentRetiresOnlyActiveApplicationTree(t *testing.T) { + adapter := New() + adapter.documentTree = testTree(t) + old, err := adapter.documentTree.Reference(testID("/first")) + if err != nil { + t.Fatal(err) + } + replacement := testID("/replacement") + adapter.invalidateTreeEvent(DocumentLoadCompleteEvent, 0, replacement, ObjectID{}) + if _, err := adapter.documentTree.Resolve(old); err != nil { + t.Fatalf("unknown load source unexpectedly retired tree: %v", err) + } + adapter.invalidateReplacedDocument(replacement, testID("/background")) + if _, err := adapter.documentTree.Resolve(old); err != nil { + t.Fatalf("inactive document retired tree: %v", err) + } + adapter.invalidateReplacedDocument(replacement, replacement) + if _, err := adapter.documentTree.Resolve(old); !errors.Is(err, ErrStaleObject) { + t.Fatalf("active replacement left old document available: %v", err) + } +} + +func TestDocumentTextTreeTracksLayoutInvalidationIndependently(t *testing.T) { + adapter := New() + adapter.documentTree = testTree(t) + adapter.documentTextTree = testTree(t) + semantic, _ := adapter.documentTree.Reference(testID("/first")) + visual, _ := adapter.documentTextTree.Reference(testID("/first")) + + adapter.invalidateTreeEvent(BoundsChangedEvent, 0, testID("/first"), ObjectID{}) + if _, err := adapter.documentTree.Geometry(semantic); err != nil { + t.Fatalf("semantic document geometry was invalidated: %v", err) + } + if _, err := adapter.documentTextTree.Geometry(visual); !errors.Is(err, ErrStaleGeometry) { + t.Fatalf("visual document geometry error = %v, want stale geometry", err) + } + + adapter.documentTextTree = testTree(t) + visual, _ = adapter.documentTextTree.Reference(testID("/first")) + adapter.invalidateTreeEvent(CaretEvent, 1, testID("/first"), ObjectID{}) + if _, err := adapter.documentTextTree.VisibleText(visual); err != nil { + t.Fatalf("caret event invalidated reusable visual text: %v", err) + } +} + +func TestAdapterTreeInvalidationPolicy(t *testing.T) { + t.Run("unrelated semantic events preserve document", func(t *testing.T) { + for _, eventType := range []string{AccessibleNameEvent, AccessibleValueEvent, ValueChangedEvent, "object:state-changed:selected", "object:state-changed:checked", "object:state-changed:sensitive"} { + t.Run(eventType, func(t *testing.T) { + adapter := New() + adapter.documentTree = testTree(t) + cached, _ := adapter.documentTree.Reference(testID("/first")) + for _, source := range []ObjectID{testID("/browser-chrome"), {BusName: ":1.999", Path: cached.ID().Path}, {}} { + adapter.invalidateTreeEvent(eventType, 1, source, ObjectID{}) + if _, err := adapter.documentTree.Resolve(cached); err != nil { + t.Fatalf("outside event from %v discarded document: %v", source, err) + } + } + if got := adapter.TreeInvalidations(); got != 0 { + t.Fatalf("unrelated events invalidated %d objects", got) + } + adapter.invalidateTreeEvent(eventType, 1, cached.ID(), ObjectID{}) + if _, err := adapter.documentTree.Resolve(cached); !errors.Is(err, ErrStaleSnapshot) { + t.Fatalf("in-document change did not retire snapshot: %v", err) + } + }) + } + }) + + t.Run("semantic change preserves identities for refresh", func(t *testing.T) { + tree := testTree(t) + adapter := New() + adapter.documentTree = tree + cached, _ := tree.Reference(testID("/first")) + adapter.invalidateTreeEvent(AccessibleNameEvent, 0, cached.ID(), ObjectID{}) + if _, err := tree.Resolve(cached); !errors.Is(err, ErrStaleSnapshot) { + t.Fatalf("semantic snapshot error = %v, want stale semantics", err) + } + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + current, err := tree.Reference(cached.ID()) + if err != nil || current != cached { + t.Fatalf("name change retired the current identity: %v", err) + } + cachedNodes := tree.nativeRefresh(root.ID()) + if len(cachedNodes) == 0 || !cachedNodes[cached.ID()].snapshotInvalid { + t.Fatal("semantic refresh omitted the dirty object") + } + nodes := make([]TreeNode, 0, len(cachedNodes)) + for id, entry := range cachedNodes { + if id == cached.ID() { + entry.snapshot.Name = "Updated name" + } + nodes = append(nodes, TreeNode{Snapshot: entry.snapshot, Children: entry.children, Geometry: entry.geometry, Text: entry.text}) + } + if err := tree.Replace(root.ID(), nodes); err != nil { + t.Fatal(err) + } + snapshot, err := tree.Resolve(cached) + if err != nil || snapshot.Name != "Updated name" { + t.Fatalf("refreshed object = %+v, %v", snapshot, err) + } + tree.InvalidateSnapshot(cached.ID()) + tree.MarkChildrenChanged(root.ID()) + if plan := tree.nativeRefresh(root.ID()); !plan[root.ID()].childrenInvalid || !plan[cached.ID()].snapshotInvalid { + t.Fatal("incremental refresh lost a dirty child list or snapshot") + } + tree.Invalidate(root.ID()) + if plan := tree.nativeRefresh(root.ID()); plan != nil { + t.Fatal("incremental refresh retained a replaced document") + } + }) + + t.Run("known removal", func(t *testing.T) { + tree := testTree(t) + adapter := New() + adapter.tree = tree + removed, _ := tree.Reference(testID("/second")) + kept, _ := tree.Reference(testID("/first")) + adapter.invalidateTreeEvent(ChildrenRemovedEvent, 0, testID("/root"), removed.ID()) + if _, err := tree.Resolve(removed); !errors.Is(err, ErrStaleObject) { + t.Fatalf("removed reference error = %v", err) + } + if _, err := tree.Resolve(kept); err != nil { + t.Fatalf("unrelated sibling became stale: %v", err) + } + if got := adapter.TreeInvalidations(); got != 2 { + t.Fatalf("invalidation count = %d, want 2", got) + } + }) + + t.Run("addition invalidates cached children", func(t *testing.T) { + tree := testTree(t) + adapter := New() + adapter.tree = tree + root, _ := tree.Root() + child, _, _ := tree.FirstChild(root) + adapter.invalidateTreeEvent(ChildrenAddedEvent+":system", 1, root.ID(), ObjectID{}) + if _, err := tree.Resolve(root); err != nil { + t.Fatalf("parent became stale: %v", err) + } + if _, err := tree.Resolve(child); !errors.Is(err, ErrStaleObject) { + t.Fatalf("cached child error = %v, want stale object", err) + } + if got := adapter.TreeInvalidations(); got != 3 { + t.Fatalf("invalidation count = %d, want 3", got) + } + }) + + t.Run("defunct false is ignored", func(t *testing.T) { + tree := testTree(t) + adapter := New() + adapter.tree = tree + root, _ := tree.Root() + adapter.invalidateTreeEvent(DefunctStateEvent, 0, root.ID(), ObjectID{}) + if _, err := tree.Resolve(root); err != nil { + t.Fatalf("false defunct state invalidated root: %v", err) + } + adapter.invalidateTreeEvent(DefunctStateEvent, 1, root.ID(), ObjectID{}) + if _, err := tree.Resolve(root); !errors.Is(err, ErrStaleObject) { + t.Fatalf("defunct root error = %v, want stale object", err) + } + }) + + t.Run("navigation defunct refreshes semantic children", func(t *testing.T) { + owned := testTree(t) + document := testTree(t) + visual := testTree(t) + adapter := New() + adapter.tree = owned + adapter.documentTree = document + adapter.documentTextTree = visual + root, _ := document.Root() + sibling, _ := document.Reference(testID("/second")) + target := testID("/first") + adapter.invalidateTreeEventWithPolicy(DefunctStateEvent, 1, target, ObjectID{}, true) + for name, tree := range map[string]*AccessibleTree{"owned": owned, "visual": visual, "document": document} { + if _, err := tree.Reference(target); !errors.Is(err, ErrObjectNotFound) { + t.Fatalf("%s target error = %v, want missing", name, err) + } + } + for _, reference := range []ObjectReference{root, sibling} { + if _, err := document.Resolve(reference); err != nil { + t.Fatalf("navigation defunct invalidated live context: %v", err) + } + } + if _, _, err := document.FirstChild(root); !errors.Is(err, ErrIncompleteTree) { + t.Fatalf("navigation defunct did not refresh parent children: %v", err) + } + }) +} + +func TestAdapterInvalidatesGeometryWithoutRemovingObjects(t *testing.T) { + for _, eventType := range []string{BoundsChangedEvent, VisibleStateEvent, ShowingStateEvent} { + for _, detail := range []int{0, 1} { + t.Run(eventType+fmt.Sprint(detail), func(t *testing.T) { + tree := testTree(t) + adapter := New() + adapter.tree = tree + second, _ := tree.Reference(testID("/second")) + child, _, _ := tree.FirstChild(second) + adapter.invalidateTreeEvent(eventType, detail, second.ID(), ObjectID{}) + for _, ref := range []ObjectReference{second, child} { + if _, err := tree.Geometry(ref); !errors.Is(err, ErrStaleGeometry) { + t.Fatalf("geometry error = %v", err) + } + if _, err := tree.Resolve(ref); err != nil { + t.Fatalf("object invalidated: %v", err) + } + } + }) + } + } +} + +func TestQueuedDocumentPositionRejectsDepartedFocus(t *testing.T) { + tree, err := NewAccessibleTree(testID("/root"), documentTestNodes()) + if err != nil { + t.Fatal(err) + } + position, err := tree.Reference(testID("/heading")) + if err != nil { + t.Fatal(err) + } + for _, tc := range []struct { + path string + allowed bool + }{ + {"/heading", true}, {"/link", true}, {"/chrome", false}, {"/other", false}, {"/gone", false}, + } { + if err := documentPositionMatchesFocus(tree, position, testID(tc.path)); (err == nil) != tc.allowed { + t.Fatalf("focus %s: %v", tc.path, err) + } + } + tree.Invalidate(testID("/heading")) + if err := documentPositionMatchesFocus(tree, position, testID("/link")); err == nil { + t.Fatal("stale target accepted") + } +} + +func TestRemovedBrowseCaretRetainsOnlyItsDocument(t *testing.T) { + for _, test := range []struct { + name, path, document string + staleDocument bool + allowed bool + }{ + {"removed browse text", "/gone", "/doc", false, true}, + {"removed native focus", "/gone", "", false, false}, + {"browser chrome", "/chrome", "/doc", false, false}, + {"other document", "/other", "/doc", false, false}, + {"removed other-tab caret", "/gone", "/other", false, false}, + {"replaced document generation", "/gone", "/doc", true, false}, + } { + t.Run(test.name, func(t *testing.T) { + tree, err := NewAccessibleTree(testID("/root"), documentTestNodes()) + if err != nil { + t.Fatal(err) + } + focus := nativeFocusReference{id: testID(test.path)} + if test.document != "" { + focus.navigationDocument, err = tree.Reference(testID(test.document)) + if err != nil { + t.Fatal(err) + } + } + if test.staleDocument { + tree.Invalidate(testID("/doc")) + if err := tree.Replace(testID("/root"), documentTestNodes()); err != nil { + t.Fatal(err) + } + } + position, err := tree.Reference(testID("/heading")) + if err != nil { + t.Fatal(err) + } + if err := document_position_matches_retained_focus(tree, position, focus); (err == nil) != test.allowed { + t.Fatalf("caret ownership error = %v, allowed = %t", err, test.allowed) + } + tree.Invalidate(position.ID()) + if err := document_position_matches_retained_focus(tree, position, focus); err == nil { + t.Fatal("removed target accepted") + } + }) + } +} + +func TestSecureInputCancelsCapturesAcrossLockTransitions(t *testing.T) { + adapter := New() + before, cancelBefore := adapter.secureRequestContext(context.Background()) + defer cancelBefore() + adapter.SetSecureInputActive(true) + select { + case <-before.Done(): + case <-time.After(time.Second): + t.Fatal("lock did not cancel in-flight capture") + } + during, cancelDuring := adapter.secureRequestContext(context.Background()) + defer cancelDuring() + if during.Err() == nil { + t.Fatal("capture allowed while locked") + } + adapter.SetSecureInputActive(false) + after, cancelAfter := adapter.secureRequestContext(context.Background()) + defer cancelAfter() + if after.Err() != nil { + t.Fatal("unlock left captures canceled") + } + if before.Err() == nil || during.Err() == nil { + t.Fatal("unlock revived old capture") + } +} diff --git a/internal/atspi/adapter_window_title.go b/internal/atspi/adapter_window_title.go new file mode 100644 index 0000000..71a7f5f --- /dev/null +++ b/internal/atspi/adapter_window_title.go @@ -0,0 +1,36 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import "git.stormux.org/storm/cthulhu/internal/platform/xorg" + +// ForegroundTitle binds copied title metadata to the foreground ownership epoch. +type ForegroundTitle struct { + Title xorg.WindowTitle + Epoch uint64 +} + +func (adapter *Adapter) ForegroundTitle() ForegroundTitle { + if title := adapter.foregroundTitle.Load(); title != nil { + return *title + } + return ForegroundTitle{} +} + +func (adapter *Adapter) TitleChanges() <-chan struct{} { return adapter.titleChanges } + +// Called only by the GLib owner; consumers never issue X11 requests. +func (adapter *Adapter) refreshWindowTitle() { + state := adapter.Foreground() + value := ForegroundTitle{Title: adapter.foregroundReader.ReadTitle(state.Client.Window), Epoch: state.Epoch} + if value == adapter.ForegroundTitle() { + return + } + adapter.foregroundTitle.Store(&value) + select { + case adapter.titleChanges <- struct{}{}: + default: + } +} diff --git a/internal/atspi/alert_native_test.go b/internal/atspi/alert_native_test.go new file mode 100644 index 0000000..c439f66 --- /dev/null +++ b/internal/atspi/alert_native_test.go @@ -0,0 +1,313 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeGTKAlertMessage(t *testing.T) { + window := os.Getenv("CTHULHU_ALERT_WINDOW") + if window == "" { + t.Skip("requires the private GTK alert fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + for _, args := range [][]string{{"windowfocus", window}, {"key", "--clearmodifiers", "u"}} { + if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("xdotool %s: %v: %s", args[0], err, output) + } + } + for { + select { + case <-ctx.Done(): + t.Fatal("GTK alert window:create with its message was not captured") + case event := <-adapter.Events(): + if event.Type != WindowCreateEvent || event.Source.Role != "alert" { + continue + } + if event.Source.Text != "Version 0.6.0 is available. Open the releases page in your browser?" { + t.Fatalf("alert text = %q", event.Source.Text) + } + return + } + } +} + +func TestNativeYADQuestionMessage(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_YAD") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + command := exec.CommandContext(ctx, "yad", "--image", "dialog-question", "--title", "Alert", + "--button=gtk-yes:0", "--button=gtk-no:1", + "--text", "Microsoft Windows has been found! Would you like to remove it?") + if err := command.Start(); err != nil { + t.Fatal(err) + } + defer func() { + _ = command.Process.Kill() + _ = command.Wait() + }() + var yadWindow string + for yadWindow == "" && ctx.Err() == nil { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Alert$").Output() + if err == nil { + yadWindow = strings.TrimSpace(string(output)) + } + if yadWindow == "" { + time.Sleep(20 * time.Millisecond) + } + } + if yadWindow == "" { + t.Fatal("YAD window did not appear") + } + if output, err := exec.CommandContext(ctx, "xdotool", "windowfocus", strings.Split(yadWindow, "\n")[0]).CombinedOutput(); err != nil { + t.Fatalf("focus YAD window: %v: %s", err, output) + } + for { + select { + case <-ctx.Done(): + t.Fatal("YAD question was not captured on activation or button focus") + case event := <-adapter.Events(): + question := "Microsoft Windows has been found! Would you like to remove it?" + if event.Type == WindowActivatedEvent && event.Source.Role == "frame" && event.Source.Name == "Alert" { + if !event.Window.Valid() || event.Window != event.Source.ID() { + t.Fatalf("YAD frame ownership = %#v, source = %#v", event.Window, event.Source.ID()) + } + if event.Source.Text == question { + return + } + if output, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "Tab").CombinedOutput(); err != nil { + t.Fatalf("focus YAD button: %v: %s", err, output) + } + } + if (event.Type == FocusEvent || event.Type == FocusedStateEvent && event.Detail1 == 1) && + event.Source.Role == "button" && event.WindowMessage == question { + if !event.Window.Valid() || event.Window == event.Source.ID() { + t.Fatalf("YAD button ownership = %#v, source = %#v", event.Window, event.Source.ID()) + } + return + } + } + } +} + +func TestNativeYADListMessage(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_YAD") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + command := exec.CommandContext(ctx, "yad", "--list", "--title=Select Sound Type", + "--text=Which sound type would you like to use?", "--column=Option", "--no-headers", + "--selectable-labels", "--search-column=1", "--height=400", "--width=600") + command.Stdin = strings.NewReader("stereo\nhrtf\n") + if err := command.Start(); err != nil { + t.Fatal(err) + } + defer func() { + _ = command.Process.Kill() + _ = command.Wait() + }() + var yadWindow string + for yadWindow == "" && ctx.Err() == nil { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Select Sound Type$").Output() + if err == nil { + yadWindow = strings.TrimSpace(string(output)) + } + if yadWindow == "" { + time.Sleep(20 * time.Millisecond) + } + } + if yadWindow == "" { + t.Fatal("YAD list window did not appear") + } + if output, err := exec.CommandContext(ctx, "xdotool", "windowfocus", strings.Split(yadWindow, "\n")[0]).CombinedOutput(); err != nil { + t.Fatalf("focus YAD list window: %v: %s", err, output) + } + for { + select { + case <-ctx.Done(): + t.Fatal("YAD list question was not captured on activation") + case event := <-adapter.Events(): + if event.Source.ApplicationName != "yad" || + (event.Type != WindowActivatedEvent && event.Type != FocusEvent && + (event.Type != FocusedStateEvent || event.Detail1 != 1)) { + continue + } + if event.Source.Role != "tree table" && event.Source.Role != "frame" { + continue + } + question := event.WindowMessage + if event.Source.Role == "frame" && event.Type == WindowActivatedEvent { + question = event.Source.Text + } + if question == "" { + continue + } + if question != "Which sound type would you like to use?" { + t.Fatalf("YAD list question = %q on %q activation", question, event.Source.Role) + } + return + } + } +} + +func TestNativeYADPowerListMessage(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_YAD") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + command := exec.CommandContext(ctx, "yad", "--title", "I38", "--text", "Power options", "--list", + "--column", "Action", "--column", "Description", + "Power off", "Shut down the system", "Reboot", "Restart the system", + "Log out", "Exit the current session", "--print-column=1", "--separator=", + "--button", "Select:0", "--button", "Cancel:1") + if err := command.Start(); err != nil { + t.Fatal(err) + } + defer func() { + _ = command.Process.Kill() + _ = command.Wait() + }() + var window string + for window == "" && ctx.Err() == nil { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^I38$").Output() + if err == nil { + window = strings.TrimSpace(string(output)) + } + if window == "" { + time.Sleep(20 * time.Millisecond) + } + } + if window == "" { + t.Fatal("I38 list did not appear") + } + if output, err := exec.CommandContext(ctx, "xdotool", "windowfocus", strings.Split(window, "\n")[0]).CombinedOutput(); err != nil { + t.Fatalf("focus I38 list: %v: %s", err, output) + } + for { + select { + case <-ctx.Done(): + t.Fatal("I38 power prompt was not captured") + case event := <-adapter.Events(): + if event.Source.ApplicationName == "yad" && (event.Source.Role == "tree table" || event.Source.Role == "table cell") && + (event.Type == WindowActivatedEvent || event.Type == FocusedStateEvent && event.Detail1 == 1) && + event.WindowMessage == "Power options" { + return + } + } + } +} + +func TestNativeGTKRadioGroupName(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_RADIO") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + command := exec.CommandContext(ctx, "/usr/bin/python3", "../../tests/gtk_radio_group.py") + if err := command.Start(); err != nil { + t.Fatal(err) + } + defer func() { + _ = command.Process.Kill() + _ = command.Wait() + }() + var window string + for window == "" && ctx.Err() == nil { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Radio group probe$").Output() + if err == nil { + window = strings.TrimSpace(string(output)) + } + if window == "" { + time.Sleep(20 * time.Millisecond) + } + } + if window == "" { + t.Fatal("GTK radio window did not appear") + } + for _, args := range [][]string{{"windowfocus", strings.Split(window, "\n")[0]}, {"key", "Tab"}} { + if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("xdotool %s: %v: %s", args[0], err, output) + } + } + for { + select { + case <-ctx.Done(): + t.Fatal("GTK radio group name was not captured") + case event := <-adapter.Events(): + if event.Source.Role == "radio button" && event.Source.Focused { + if event.Source.RadioGroupName != "Punctuation Level" { + t.Fatalf("radio group = %q", event.Source.RadioGroupName) + } + return + } + } + } +} diff --git a/internal/atspi/background_events_native_test.go b/internal/atspi/background_events_native_test.go new file mode 100644 index 0000000..3b2118c --- /dev/null +++ b/internal/atspi/background_events_native_test.go @@ -0,0 +1,208 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "bufio" + "context" + "fmt" + "io" + "os" + "os/exec" + "strings" + "testing" + "time" + + "github.com/godbus/dbus/v5" +) + +func TestBackgroundInvalidationPreservesOtherProviderLines(t *testing.T) { + owned := NewObjectID(":1.42", "/line") + other := NewObjectID(":1.43", "/line") + adapter := New() + adapter.documentLineCache = map[ObjectID]DocumentCaretText{owned: {}, other: {}} + adapter.invalidateTreeEvent(TextInsertedEvent, 0, other, ObjectID{}) + if _, ok := adapter.documentLineCache[owned]; !ok { + t.Fatal("background text change cleared the owned provider's line cache") + } + if _, ok := adapter.documentLineCache[other]; ok { + t.Fatal("changed provider's line cache survived invalidation") + } + adapter.invalidateTreeEvent(AccessibleNameEvent, 0, owned, ObjectID{}) + if len(adapter.documentLineCache) != 0 { + t.Fatal("owned provider change failed to invalidate its lines") + } +} + +func TestNativeBackgroundEventFiltering(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BACKGROUND_EVENTS") != "1" { + t.Skip("requires private Xorg/AT-SPI session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + + type fixture struct { + input io.WriteCloser + output *bufio.Reader + xid string + } + start := func(name string) fixture { + command := exec.CommandContext(ctx, "/usr/bin/python3", "../../tests/gtk_background_events.py", name) + input, err := command.StdinPipe() + if err != nil { + t.Fatal(err) + } + output, err := command.StdoutPipe() + if err != nil { + t.Fatal(err) + } + command.Stderr = os.Stderr + if err := command.Start(); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { input.Close(); command.Process.Kill(); command.Wait() }) + reader := bufio.NewReader(output) + line, err := reader.ReadString('\n') + fields := strings.Fields(line) + if err != nil || len(fields) != 2 || fields[0] != "ready" { + t.Fatalf("fixture readiness: %q, %v", line, err) + } + return fixture{input, reader, fields[1]} + } + wait := func(predicate func(Event) bool) Event { + t.Helper() + var last Event + count := 0 + for { + select { + case event := <-adapter.Events(): + last = event + count++ + if predicate(event) { + return event + } + case <-ctx.Done(): + t.Fatalf("native event missing: %v; filtered=%d received=%d last=%s %s %q", ctx.Err(), adapter.backgroundEventsFiltered.Load(), count, last.Type, last.Source.Role, last.Source.Name) + } + } + } + focus := func(xid string) { + t.Helper() + if output, err := exec.CommandContext(ctx, "xdotool", "windowfocus", "--sync", xid).CombinedOutput(); err != nil { + t.Fatalf("focus: %s, %v", output, err) + } + } + background := start("Background fixture") + foreground := start("Foreground fixture") + // Publish the complete AT-SPI cache, including table cells, before flooding. + if _, err := adapter.CaptureDesktop(ctx); err != nil { + t.Fatal(err) + } + focus(foreground.xid) + fmt.Fprintln(foreground.input, "edit") + owned := wait(func(event Event) bool { + return event.Type == TextInsertedEvent && event.Payload == "Updated text" && !event.ForegroundMismatch + }) + + sessionBus, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + defer sessionBus.Close() + var address string + if err := sessionBus.Object("org.a11y.Bus", "/org/a11y/bus").CallWithContext(ctx, "org.a11y.Bus.GetAddress", 0).Store(&address); err != nil { + t.Fatal(err) + } + control, err := dbus.Connect(address) + if err != nil { + t.Fatal(err) + } + defer control.Close() + monitor, err := dbus.Connect(address) + if err != nil { + t.Fatal(err) + } + defer monitor.Close() + if err := monitor.BusObject().CallWithContext(ctx, "org.freedesktop.DBus.Monitoring.BecomeMonitor", 0, []string{"type='method_call'"}, uint32(0)).Err; err != nil { + t.Fatal(err) + } + messages := make(chan *dbus.Message, 65536) + monitor.Eavesdrop(messages) + + flood := func(generation string, sameProvider bool) { + t.Helper() + before := adapter.backgroundEventsFiltered.Load() + fmt.Fprintln(background.input, "flood "+generation) + marker := wait(func(event Event) bool { + return event.Type == TextInsertedEvent && event.Payload == "Flood complete "+generation + }) + if (marker.Source.BusName == owned.Source.BusName) != sameProvider { + t.Fatal("fixture provider identity did not match test case") + } + if count := adapter.backgroundEventsFiltered.Load() - before; count < 300 { + t.Fatalf("filtered %d events; want at least 300 real selection updates", count) + } + if err := control.Object(marker.Source.BusName, dbus.ObjectPath(marker.Source.Path)).CallWithContext(ctx, "org.freedesktop.DBus.Peer.Ping", 0).Err; err != nil { + t.Fatal(err) + } + queries := 0 + reading: + for { + select { + case message := <-messages: + if message.Headers[dbus.FieldDestination].Value() != marker.Source.BusName { + continue + } + member := message.Headers[dbus.FieldMember].Value() + if member == "Ping" { + break reading + } + if message.Headers[dbus.FieldPath].Value() == dbus.ObjectPath(marker.Source.Path) { + continue + } + switch message.Headers[dbus.FieldInterface].Value() { + case "org.a11y.atspi.Selection", "org.a11y.atspi.Table", "org.a11y.atspi.Text", "org.a11y.atspi.Value": + queries++ + } + case <-ctx.Done(): + t.Fatal("monitor barrier missing") + } + } + if queries != 0 { + t.Fatalf("background flood caused %d selection/table/text/value queries", queries) + } + t.Logf("%s: filtered at least 300 updates with zero content queries", generation) + } + flood("other-provider", false) + + // The same application can have an inactive sibling on the same bus. + fmt.Fprintln(background.input, "sibling") + line, err := background.output.ReadString('\n') + fields := strings.Fields(line) + if err != nil || len(fields) != 2 || fields[0] != "sibling" { + t.Fatalf("sibling readiness: %q, %v", line, err) + } + if _, err := adapter.CaptureDesktop(ctx); err != nil { + t.Fatal(err) + } + focus(fields[1]) + owned = wait(func(event Event) bool { + return !event.ForegroundMismatch && event.Source.Name == "Background fixture sibling entry" + }) + flood("same-provider", true) + + // Returning to the previously noisy window must read its current selection. + focus(background.xid) + fmt.Fprintln(background.input, "focus-table") + wait(func(event Event) bool { + return !event.ForegroundMismatch && event.Source.Name == "Result 1" && event.Source.GUITable + }) + t.Log("returning to the noisy application delivers current table focus") +} diff --git a/internal/atspi/braille_native.go b/internal/atspi/braille_native.go new file mode 100644 index 0000000..a2e5331 --- /dev/null +++ b/internal/atspi/braille_native.go @@ -0,0 +1,142 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#cgo pkg-config: atspi-2 glib-2.0 gobject-2.0 +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "unicode/utf8" +) + +// BrailleRoute refers to the exact source span which produced the display. +// Revalidate it on the GLib thread so edits or focus changes cannot route a +// delayed hardware key into different content. +type BrailleRoute struct { + Focus ObjectID + Position ObjectReference // Valid only for document browse routing. + Line string + Start, Offset int +} + +func (adapter *Adapter) RouteBraille(ctx context.Context, route BrailleRoute) error { + _, err := adapter.documentOperation(ctx, treeCaptureRequest{brailleRoute: &route}) + return err +} + +func validBrailleRoute(snapshot Snapshot, route BrailleRoute) bool { + return route.Focus.Valid() && snapshot.ID() == route.Focus && !snapshot.Defunct && snapshot.StatesKnown && snapshot.Focused && + snapshot.Role != "password text" && snapshot.TextCaretKnown && + snapshot.BrailleLineStart == route.Start && snapshot.BrailleLine == route.Line && + route.Start >= 0 && route.Offset >= route.Start && + route.Offset-route.Start <= utf8.RuneCountInString(route.Line) +} + +func (adapter *Adapter) routeNativeBraille(ctx context.Context, route BrailleRoute) error { + if err := ctx.Err(); err != nil { + return err + } + if route.Position.Valid() { + return adapter.route_document_braille(ctx, route) + } + if !adapter.nativeFocusIs(route.Focus) { + return ErrStaleObject + } + source := adapter.nativeFocus[len(adapter.nativeFocus)-1].source + // Request caret capture even for read-only text. Ordinary focus snapshots + // deliberately avoid querying non-editable text on the event hot path. + snapshot := snapshotFromNativeWithCaret(source, true, true, false, false) + if !validBrailleRoute(snapshot, route) { + return ErrStaleObject + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return ErrNoDocumentCaret + } + defer C.g_object_unref(C.gpointer(text)) + if err := ctx.Err(); err != nil { + return err + } + var nativeErr *C.GError + placed := C.atspi_text_set_caret_offset(text, C.gint(route.Offset), &nativeErr) + if nativeErr != nil { + err := nativeError("route braille caret", nativeErr) + C.g_error_free(nativeErr) + return err + } + if placed == 0 { + return ErrNoDocumentCaret + } + return nil +} + +func (adapter *Adapter) route_document_braille(ctx context.Context, route BrailleRoute) error { + adapter.treeMutex.Lock() + tree := adapter.documentTree + adapter.treeMutex.Unlock() + if tree == nil || len(adapter.nativeFocus) == 0 { + return ErrStaleObject + } + snapshot, err := tree.Resolve(route.Position) + if err != nil || snapshot.Role == "password text" || snapshot.Defunct { + return ErrStaleObject + } + if err = documentPositionMatchesFocus(tree, route.Position, route.Focus); err != nil { + return err + } + latest := adapter.nativeFocus[len(adapter.nativeFocus)-1].id + if err = documentPositionMatchesFocus(tree, route.Position, latest); err != nil { + return err + } + source := adapter.nativeDocument[route.Position.ID()] + if source == nil { + return ErrStaleObject + } + // Recheck the protected state and foreground before reading fresh content. + C.atspi_accessible_clear_cache_single(source) + fresh := snapshotFromNativeWithCaret(source, false, false, false, false) + if fresh.Role != snapshot.Role || fresh.Defunct || fresh.Role == "password text" { + return ErrStaleObject + } + window := C.cthulhu_window_ancestor(source) + if window == nil { + return ErrStaleObject + } + foreground := adapter.matchesForeground(window, nativeObjectID(window)) + C.g_object_unref(C.gpointer(window)) + if !foreground { + return ErrStaleObject + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return ErrNoDocumentCaret + } + defer C.g_object_unref(C.gpointer(text)) + length := utf8.RuneCountInString(route.Line) + if route.Start < 0 || route.Offset < route.Start || route.Offset > route.Start+length || length == 0 { + return ErrStaleObject + } + count := int(C.atspi_text_get_character_count(text, nil)) + if route.Start+length > count { + return ErrStaleObject + } + var nativeErr *C.GError + content := C.atspi_text_get_text(text, C.gint(route.Start), C.gint(route.Start+length), &nativeErr) + if nativeErr != nil { + err := nativeError("validate document braille text", nativeErr) + C.g_error_free(nativeErr) + return err + } + unchanged := C.GoString(content) == route.Line + C.g_free(C.gpointer(content)) + if !unchanged { + return ErrStaleObject + } + return adapter.setNativeDocumentPosition(ctx, route.Position, route.Focus, route.Offset, true) +} diff --git a/internal/atspi/braille_test.go b/internal/atspi/braille_test.go new file mode 100644 index 0000000..16abefd --- /dev/null +++ b/internal/atspi/braille_test.go @@ -0,0 +1,119 @@ +package atspi + +import ( + "context" + "errors" + "strings" + "testing" + "unicode/utf8" +) + +func TestBrailleCaptureKeepsTruncatedUnicodeOrigin(t *testing.T) { + raw := strings.Repeat("猫", 2000) + " é" + var snapshot Snapshot + captureBrailleLine(&snapshot, raw, raw[:len(raw)-len("é")], 19) + removed := utf8.RuneCountInString(raw) - utf8.RuneCountInString(snapshot.BrailleLine) + if snapshot.BrailleLineStart != 19+removed || snapshot.BrailleCaret != 2021 || !strings.HasSuffix(snapshot.BrailleLine, " é") { + t.Fatalf("origin=%d caret=%d", snapshot.BrailleLineStart, snapshot.BrailleCaret) + } +} + +func TestBrailleRouteRejectsChangedLineAndFocus(t *testing.T) { + s := NewSnapshot("/entry", "Message", "entry", "", "é猫") + s.BusName, s.TextCaretKnown = ":1.42", true + s.StatesKnown, s.Focused = true, true + captureBrailleLine(&s, "é猫", "é", 12) + route := BrailleRoute{Focus: s.ID(), Line: "é猫", Start: 12, Offset: 14} + if !validBrailleRoute(s, route) { + t.Fatal("valid EOL route rejected") + } + for _, change := range []func(*Snapshot){ + func(s *Snapshot) { s.BusName = ":1.43" }, + func(s *Snapshot) { s.Path = "/other" }, + func(s *Snapshot) { s.BrailleLine = "ab" }, + func(s *Snapshot) { s.BrailleLineStart++ }, + func(s *Snapshot) { s.Defunct = true }, + func(s *Snapshot) { s.Focused = false }, + func(s *Snapshot) { s.StatesKnown = false }, + func(s *Snapshot) { s.Role = "password text" }, + func(s *Snapshot) { s.TextCaretKnown = false }, + } { + changed := s + change(&changed) + if validBrailleRoute(changed, route) { + t.Fatalf("accepted stale/protected route %+v", changed) + } + } + for _, offset := range []int{-1, 11, 15} { + route.Offset = offset + if validBrailleRoute(s, route) { + t.Fatalf("accepted offset %d", offset) + } + } +} + +func assertNativeBrailleRouting(t *testing.T, ctx context.Context, adapter *Adapter) { + t.Helper() + wait := func(name string, offset int) Snapshot { + t.Helper() + for { + select { + case e := <-adapter.Events(): + if e.Source.Name != name { + continue + } + if offset < 0 && (e.Type == FocusEvent || e.Type == FocusedStateEvent && e.Detail1 == 1) { + return e.Source + } + if offset >= 0 && e.Type == CaretEvent && e.Source.BrailleCaret == offset { + return e.Source + } + case <-ctx.Done(): + t.Fatalf("missing native braille event for %s offset %d", name, offset) + } + } + } + pressTreeProbeKey(t, "F6") + s := wait("Caret review probe", -1) + if !s.TextCaretKnown || s.BrailleLine != "Caret 猫 text" { + t.Fatalf("native braille snapshot %+v", s) + } + route := BrailleRoute{Focus: s.ID(), Line: s.BrailleLine, Start: s.BrailleLineStart} + for _, offset := range []int{1, 6, 7, 12, 6} { + route.Offset = offset + if err := adapter.RouteBraille(ctx, route); err != nil { + t.Fatalf("route offset %d: %v", offset, err) + } + wait("Caret review probe", offset) + } + waitLine := func(line string) { + t.Helper() + for { + select { + case event := <-adapter.Events(): + if event.Source.ID() == s.ID() && event.Source.BrailleLine == line { + return + } + case <-ctx.Done(): + t.Fatal("edited braille line was not captured") + } + } + } + pressTreeProbeKey(t, "z") + waitLine("Caret z猫 text") + if err := adapter.RouteBraille(ctx, route); !errors.Is(err, ErrStaleObject) { + t.Fatalf("stale text route: %v", err) + } + pressTreeProbeKey(t, "BackSpace") + waitLine("Caret 猫 text") + pressTreeProbeKey(t, "F7") + secret := wait("Protected text probe", -1) + if secret.TextCaretKnown || secret.BrailleLine != "" { + t.Fatal("captured protected braille text") + } + if err := adapter.RouteBraille(ctx, route); !errors.Is(err, ErrStaleObject) { + t.Fatalf("old focus route: %v", err) + } + pressTreeProbeKey(t, "F8") + wait("Numeric value probe", -1) +} diff --git a/internal/atspi/browser_live_native_test.go b/internal/atspi/browser_live_native_test.go new file mode 100644 index 0000000..42364cd --- /dev/null +++ b/internal/atspi/browser_live_native_test.go @@ -0,0 +1,118 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeBrowserAtomicLiveRegion(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stop, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := adapter.Stop(stop); err != nil { + t.Error(err) + } + }() + window, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "Cthulhu Browser Probe").Output() + if err != nil || len(strings.Fields(string(window))) == 0 { + t.Fatalf("browser window: %s: %v", window, err) + } + if out, err := exec.CommandContext(ctx, "xdotool", "windowfocus", strings.Fields(string(window))[0]).CombinedOutput(); err != nil { + t.Fatalf("focus: %s: %v", out, err) + } + for _, test := range []struct { + key, marker, want string + atomic bool + }{ + {"F9", "Completed", "Download status: Completed", true}, + {"F10", "Verified", "Account status: Verified", true}, + {"F11", "Inner update", "Inner update", false}, + } { + t.Run(test.key, func(t *testing.T) { + if out, err := exec.CommandContext(ctx, "xdotool", "key", test.key).CombinedOutput(); err != nil { + t.Fatalf("trigger: %s: %v", out, err) + } + deadline := time.NewTimer(5 * time.Second) + defer deadline.Stop() + for { + select { + case event := <-adapter.Events(): + if !event.Source.LiveRegion || (!strings.Contains(event.Source.Text, test.marker) && !strings.Contains(event.Payload, test.marker)) { + continue + } + if event.Source.LiveAtomic != test.atomic || event.Source.LiveAtomic && event.Source.Text != test.want { + t.Fatalf("atomic=%v text=%q payload=%q; want atomic=%v text=%q", event.Source.LiveAtomic, event.Source.Text, event.Payload, test.atomic, test.want) + } + if !test.atomic && strings.Contains(event.Source.Text, "Outer context:") { + t.Fatalf("crossed atomic=false boundary: %q", event.Source.Text) + } + return + case <-deadline.C: + t.Fatal("live update missing") + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + }) + } + // A busy region must remain silent while its intermediate contents change. + if out, err := exec.CommandContext(ctx, "xdotool", "key", "F12").CombinedOutput(); err != nil { + t.Fatalf("busy start: %s %v", out, err) + } + quiet := time.NewTimer(200 * time.Millisecond) +quietLoop: + for { + select { + case event := <-adapter.Events(): + if event.Source.LiveRegion && (strings.Contains(event.Source.Text, "Intermediate update") || strings.Contains(event.Payload, "Intermediate update")) { + t.Fatalf("busy region announced incomplete text: %+v", event) + } + case <-quiet.C: + break quietLoop + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + quiet.Stop() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "F7").CombinedOutput(); err != nil { + t.Fatalf("busy complete: %s %v", out, err) + } + completion := time.NewTimer(5 * time.Second) + defer completion.Stop() + for { + select { + case event := <-adapter.Events(): + if event.Source.LiveRegion && strings.Contains(event.Source.Text, "Intermediate update") { + if event.Type != TextInsertedEvent && event.Type != ChildrenAddedEvent { + t.Fatalf("live completion changed focus/lifecycle: %+v", event) + } + if event.Source.Text != "Busy status: Intermediate update" { + t.Fatalf("completion text: %q", event.Source.Text) + } + return + } + case <-completion.C: + t.Fatal("busy completion missing") + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + +} diff --git a/internal/atspi/browser_native_test.go b/internal/atspi/browser_native_test.go new file mode 100644 index 0000000..141b4f7 --- /dev/null +++ b/internal/atspi/browser_native_test.go @@ -0,0 +1,483 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "context" + "net/http" + "net/http/httptest" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeBrowserLiveRegion(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stop, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := adapter.Stop(stop); err != nil { + t.Error(err) + } + }() + window, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "Cthulhu Browser Probe").Output() + if err != nil || len(strings.Fields(string(window))) == 0 { + t.Fatalf("browser window: %s: %v", window, err) + } + if out, err := exec.CommandContext(ctx, "xdotool", "windowfocus", strings.Fields(string(window))[0]).CombinedOutput(); err != nil { + t.Fatalf("focus: %s: %v", out, err) + } + if out, err := exec.CommandContext(ctx, "xdotool", "key", "F9").CombinedOutput(); err != nil { + t.Fatalf("trigger live region: %s: %v", out, err) + } + deadline := time.NewTimer(5 * time.Second) + defer deadline.Stop() + for { + select { + case event := <-adapter.Events(): + if event.Type != ChildrenAddedEvent && event.Type != TextInsertedEvent { + continue + } + t.Logf("update type=%s role=%s live=%t politeness=%q text=%q payload=%q", event.Type, event.Source.Role, event.Source.LiveRegion, event.Source.LivePoliteness, event.Source.Text, event.Payload) + if event.Source.LiveRegion && event.Source.LivePoliteness == "polite" && + (strings.Contains(event.Source.Text, "Username: Test message") || strings.Contains(event.Payload, "Username: Test message")) { + return + } + case <-deadline.C: + t.Fatal("active browser live-region update was not captured") + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } +} + +func TestNativeBrowser(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stop, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := adapter.Stop(stop); err != nil { + t.Error(err) + } + }() + // Session services can map windows after the launcher first focuses Brave. + window, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "Cthulhu Browser Probe").Output() + if err != nil { + t.Fatal(err) + } + windows := strings.Fields(string(window)) + if len(windows) == 0 { + t.Fatal("browser window missing") + } + if out, err := exec.CommandContext(ctx, "xdotool", "windowfocus", windows[0]).CombinedOutput(); err != nil { + t.Fatalf("focus: %s: %v", out, err) + } + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + for _, name := range []string{"Browser foundation", "Reading section", "Example link", "Display name", "Secret", "Remember choice", "Details"} { + ref := findNamedReference(t, tree, name) + snapshot, err := tree.Resolve(ref) + if err != nil { + t.Fatal(err) + } + t.Logf("%s: role=%s text=%q", name, snapshot.Role, snapshot.Text) + } + + heading, err := tree.Resolve(findNamedReference(t, tree, "Reading section")) + if err != nil || heading.HeadingLevel != 2 { + t.Fatalf("heading level=%d err=%v", heading.HeadingLevel, err) + } + required, err := tree.Resolve(findNamedReference(t, tree, "Display name")) + if err != nil || !required.Required || !required.Editable { + t.Fatalf("entry semantics: %+v %v", required, err) + } + + for _, tc := range []struct { + name string + focusable, popup bool + }{ + {"Reading section", true, false}, + {"Ordinary unfocusable heading", false, false}, + {"Display name", true, false}, + {"Details", true, false}, + {"Popup actions", true, true}, + {"Popup toggle", true, true}, + {"Ordinary action", true, false}, + } { + snapshot, err := tree.Resolve(findNamedReference(t, tree, tc.name)) + if err != nil || !snapshot.StatesKnown || snapshot.Focusable != tc.focusable || snapshot.HasPopup != tc.popup { + t.Fatalf("native mode states for %s: %+v, %v", tc.name, snapshot, err) + } + } + pageRef := findNamedReference(t, tree, "Browser foundation") + pageContext, err := tree.DocumentContext(pageRef) + if err != nil { + t.Fatal(err) + } + embedded := findNamedReference(t, tree, "Embedded heading") + embeddedContext, err := tree.DocumentContext(embedded) + if err != nil { + t.Fatal(err) + } + ordinary := findNamedReference(t, tree, "Ordinary unfocusable heading") + ordinaryContext, err := tree.DocumentContext(ordinary) + if err != nil { + t.Fatal(err) + } + if embeddedContext.TopLevel != pageContext.TopLevel || embeddedContext.Document == pageContext.Document || + ordinaryContext.Document != pageContext.Document { + t.Fatalf("document ownership: embedded=%+v ordinary=%+v page=%+v", embeddedContext, ordinaryContext, pageContext) + } + chromeRef := findNamedReference(t, tree, "Address and search bar") + if _, err := tree.DocumentContext(chromeRef); err != ErrNotInDocument { + t.Fatalf("browser chrome belongs to document: %v", err) + } + // Browser chrome has a version-dependent number of Tab stops. Locate the + // first page heading with a bounded real-key traversal, then verify order. + expected := []string{"Browser foundation", "Reading section", "Example link", "Display name", "Secret", "Remember choice", "Details"} + next := 0 + for attempts := 0; attempts < 35 && next < len(expected); attempts++ { + if out, err := exec.CommandContext(ctx, "xdotool", "key", "Tab").CombinedOutput(); err != nil { + t.Fatalf("keys: %s: %v", out, err) + } + timer := time.NewTimer(500 * time.Millisecond) + events: + for { + select { + case event := <-adapter.Events(): + if event.Type != "focus:" && event.Type != "object:state-changed:focused" { + continue + } + if event.Source.Name == expected[next] { + if !event.Source.StatesKnown || !event.Source.Focusable || !event.Source.Focused { + t.Fatalf("native focus states missing: %+v", event.Source) + } + if event.Source.Name == "Secret" && (event.Source.Text != "" || event.Source.CaretCharacter != "" || event.Source.TextBeforeCaret != "") { + t.Fatal("password snapshot contains text") + } + t.Logf("focus %s: %s", event.Source.Name, event.Source.Role) + next++ + timer.Stop() + break events + } + if next > 0 { + t.Fatalf("focus %q; expected %q", event.Source.Name, expected[next]) + } + case <-timer.C: + break events + case <-ctx.Done(): + timer.Stop() + t.Fatal(ctx.Err()) + } + } + } + if next != len(expected) { + t.Fatalf("only reached %d of %d page controls", next, len(expected)) + } + waitEvent := func(name, kind string, state func(Snapshot) bool) { + t.Helper() + timeout := time.NewTimer(3 * time.Second) + defer timeout.Stop() + for { + select { + case event := <-adapter.Events(): + if event.Source.Name == name && event.Type == kind && state(event.Source) { + return + } + case <-timeout.C: + t.Fatalf("missing %s event for %s", kind, name) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + key := func(keys ...string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", append([]string{"key"}, keys...)...).CombinedOutput(); err != nil { + t.Fatalf("keys: %s: %v", out, err) + } + } + key("space") + waitEvent("Details", "object:state-changed:expanded", func(s Snapshot) bool { return s.Expanded }) + key("F8") + waitEvent("Cthulhu Browser Probe updated", AccessibleNameEvent, func(s Snapshot) bool { + if s.ToolkitName != "Chromium" { + t.Fatalf("browser name event toolkit = %q", s.ToolkitName) + } + return true + }) + key("shift+Tab") + waitEvent("Remember choice", "object:state-changed:focused", func(s Snapshot) bool { return true }) + key("space") + waitEvent("Remember choice", "object:state-changed:checked", func(s Snapshot) bool { return s.Checked }) + // Move between page controls before checking focus loss. Chromium can keep + // the DOM's focused state when its address bar owns desktop focus. + tree, err = adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + previous, err := tree.Resolve(findNamedReference(t, tree, "Details")) + if err != nil || !previous.StatesKnown || previous.Focused { + t.Fatalf("recapture retained old focused state: %+v, %v", previous, err) + } + key("ctrl+l") + // Recapture after scrolling/focus events before resolving chrome ownership. + waitEvent("Address and search bar", "object:state-changed:focused", func(s Snapshot) bool { return s.Editable }) + tree, err = adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + chrome := findNamedReference(t, tree, "Address and search bar") + if _, err := tree.DocumentContext(chrome); err != ErrNotInDocument { + t.Fatalf("address bar document: %v", err) + } + foundInsertion, foundPopup := false, false + key("c") + timerTyping := time.NewTimer(250 * time.Millisecond) +readTyping: + for { + select { + case event := <-adapter.Events(): + if event.Type == TextInsertedEvent && event.Payload == "c" && event.Source.Editable && event.Source.Autocomplete { + foundInsertion = true + } + if event.Source.Role == "list item" && event.Source.AutocompletePopup && event.PopupFor == chrome.ID() { + foundPopup = true + } + case <-timerTyping.C: + break readTyping + } + } + if !foundInsertion || !foundPopup { + t.Fatalf("address semantics: insertion=%v popup=%v", foundInsertion, foundPopup) + } + key("Escape", "Escape", "Escape") + waitEvent("Remember choice", "object:state-changed:focused", func(s Snapshot) bool { return s.Checked }) + pageRef = findNamedReference(t, tree, "Browser foundation") + key("ctrl+r") + loadTimer := time.NewTimer(5 * time.Second) + defer loadTimer.Stop() +waitLoad: + for { + select { + case event := <-adapter.Events(): + if event.Type == DocumentLoadCompleteEvent { + if event.Source.Name != "Cthulhu Browser Probe" || event.Source.Text != "" { + t.Fatalf("loaded title snapshot: %+v", event.Source) + } + break waitLoad + } + case <-loadTimer.C: + t.Fatal("active document load announcement missing") + } + } + deadline := time.NewTimer(5 * time.Second) + defer deadline.Stop() + ticker := time.NewTicker(20 * time.Millisecond) + defer ticker.Stop() +waitReload: + for { + select { + case <-ticker.C: + if _, err := tree.Resolve(pageRef); err != nil { + break waitReload + } + case <-deadline.C: + t.Fatal("browser reload retained old document reference") + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + // A fresh document must be discoverable after the adapter has already + // cached the browser tree, not only when connecting to a preloaded page. + for attempts := 0; attempts < 25; attempts++ { + key("Tab") + timer := time.NewTimer(250 * time.Millisecond) + waitFocus: + for { + select { + case event := <-adapter.Events(): + if event.Type == FocusedStateEvent && event.Source.Name == "Browser foundation" { + timer.Stop() + captureCtx, stopCapture := context.WithTimeout(ctx, 2*time.Second) + captured, err := adapter.CaptureDocument(captureCtx, event.Source.ID()) + stopCapture() + if err != nil { + t.Fatal(err) + } + ref, err := captured.Reference(event.Source.ID()) + if err != nil { + t.Fatal(err) + } + doc, err := captured.Document(ctx, ref) + if err != nil { + t.Fatal(err) + } + foundFragment := false + for _, node := range doc.Nodes { + if node.Snapshot.ElementID == "target" { + foundFragment = true + break + } + } + if !foundFragment { + t.Fatal("document capture omitted the target element ID") + } + root, err := captured.Root() + if err != nil || root != doc.Context.TopLevel || captured == tree { + t.Fatalf("document capture must own only the document: root=%v error=%v", root, err) + } + link := findNamedReference(t, captured, "Example link") + if err := adapter.ActivateDocumentObject(ctx, link, event.Source.ID()); err != nil { + t.Fatalf("activate captured link: %v", err) + } + activated := false + for attempts := 0; attempts < 20 && !activated; attempts++ { + updated, err := adapter.CaptureDocument(ctx, link.ID()) + if err == nil { + root, rootErr := updated.Root() + if rootErr == nil { + document, documentErr := updated.Document(ctx, root) + if documentErr == nil { + for _, node := range document.Nodes { + if node.Snapshot.Name == "Text refreshed after the ordinary heading." { + activated = true + break + } + } + } + } + } + if !activated { + time.Sleep(50 * time.Millisecond) + } + } + if !activated { + t.Fatal("captured link action did not update the page") + } + testNativeBrowserBackgroundLoad(t, adapter) + return + } + case <-timer.C: + break waitFocus + case <-ctx.Done(): + timer.Stop() + t.Fatal(ctx.Err()) + } + } + } + t.Fatal("reloaded heading focus missing") +} + +func testNativeBrowserBackgroundLoad(t *testing.T, adapter *Adapter) { + t.Helper() + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + requested, release := make(chan struct{}, 1), make(chan struct{}) + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/hold" { + select { + case requested <- struct{}{}: + default: + } + select { + case <-release: + case <-r.Context().Done(): + } + w.WriteHeader(http.StatusNoContent) + return + } + w.Header().Set("Content-Type", "text/html") + _, _ = w.Write([]byte(`Pending page

Content

Pending image`)) + })) + defer func() { + select { + case <-release: + default: + close(release) + } + server.Close() + }() + key := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %s: %v", out, err) + } + } + key("ctrl+l") + if out, err := exec.CommandContext(ctx, "xdotool", "type", "--clearmodifiers", server.URL).CombinedOutput(); err != nil { + t.Fatalf("type local URL: %s: %v", out, err) + } + key("Return") + select { + case <-requested: + case <-ctx.Done(): + t.Fatal("page did not request its held resource") + } + // Discard focus events from navigating to the held page. Only a fresh + // address focus after Ctrl+L can release the response and complete loading. + for len(adapter.events) > 0 { + <-adapter.events + } + key("ctrl+l") + var chrome ObjectID + for !chrome.Valid() { + select { + case event := <-adapter.Events(): + if event.Type == FocusedStateEvent && event.Source.Autocomplete && event.Source.Focused { + chrome = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal("address focus missing during page load") + } + } + close(release) + for { + select { + case event := <-adapter.Events(): + if event.Type == DocumentLoadCompleteEvent && event.Source.Name == "Pending page" { + if event.FocusOutsideDocument != chrome { + t.Fatalf("load lost native chrome focus: got %v want %v", event.FocusOutsideDocument, chrome) + } + return + } + case <-ctx.Done(): + t.Fatal("background load event missing") + } + } +} diff --git a/internal/atspi/capture_diagnostics.go b/internal/atspi/capture_diagnostics.go new file mode 100644 index 0000000..9c04b5b --- /dev/null +++ b/internal/atspi/capture_diagnostics.go @@ -0,0 +1,153 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "log/slog" + "sync" + "time" +) + +type captureDiagnosticKey struct{} + +type captureStageTiming struct { + Stage string `json:"stage"` + Calls int `json:"calls"` + Duration time.Duration `json:"duration"` + MaxDuration time.Duration `json:"max_duration"` + SlowestBus string `json:"slowest_bus"` + SlowestPath string `json:"slowest_path"` + SlowestRole string `json:"slowest_role"` +} + +// One request owns these copied diagnostics. The caller can finish them while +// the GLib thread is still inside a native call; no native references cross +// threads. A finished trace ignores later updates from that call. +type captureDiagnostics struct { + mutex sync.Mutex + logger *slog.Logger + kind string + started time.Time + stageStarted time.Time + stage string + object ObjectID + role string + root ObjectID + rootScope string + capturedNodes int + pendingNodes int + textBytes int + textIssues map[TextCaptureIssue]int + timings []captureStageTiming + finished bool +} + +func (trace *captureDiagnostics) text_issue(issue TextCaptureIssue) { + if trace == nil { + return + } + trace.mutex.Lock() + defer trace.mutex.Unlock() + if !trace.finished { + if trace.textIssues == nil { + trace.textIssues = make(map[TextCaptureIssue]int) + } + trace.textIssues[issue]++ + } +} + +func new_capture_diagnostics(ctx context.Context, logger *slog.Logger, focus ObjectID) (context.Context, *captureDiagnostics) { + if logger == nil || !logger.Enabled(ctx, slog.LevelDebug) { + return ctx, nil + } + now := time.Now() + trace := &captureDiagnostics{logger: logger, started: now, stageStarted: now, stage: "request-lock", object: focus} + return context.WithValue(ctx, captureDiagnosticKey{}, trace), trace +} + +func capture_diagnostics(ctx context.Context) *captureDiagnostics { + trace, _ := ctx.Value(captureDiagnosticKey{}).(*captureDiagnostics) + return trace +} + +func (trace *captureDiagnostics) record_stage(now time.Time) { + duration := now.Sub(trace.stageStarted) + index := 0 + for index < len(trace.timings) && trace.timings[index].Stage != trace.stage { + index++ + } + if index == len(trace.timings) { + trace.timings = append(trace.timings, captureStageTiming{Stage: trace.stage}) + } + timing := &trace.timings[index] + timing.Calls++ + timing.Duration += duration + if duration > timing.MaxDuration { + timing.MaxDuration = duration + timing.SlowestBus, timing.SlowestPath, timing.SlowestRole = trace.object.BusName, trace.object.Path, trace.role + } +} + +func (trace *captureDiagnostics) begin_stage(stage string, object ObjectID, role string) { + if trace == nil { + return + } + trace.mutex.Lock() + defer trace.mutex.Unlock() + if trace.finished { + return + } + now := time.Now() + trace.record_stage(now) + trace.stage, trace.object, trace.role, trace.stageStarted = stage, object, role, now +} + +func (trace *captureDiagnostics) set_root(root ObjectID, scope string) { + if trace == nil { + return + } + trace.mutex.Lock() + defer trace.mutex.Unlock() + if !trace.finished { + trace.root, trace.rootScope = root, scope + } +} + +func (trace *captureDiagnostics) progress(role string, capturedNodes, pendingNodes, textBytes int) { + if trace == nil { + return + } + trace.mutex.Lock() + defer trace.mutex.Unlock() + if !trace.finished { + trace.role = role + trace.capturedNodes, trace.pendingNodes, trace.textBytes = capturedNodes, pendingNodes, textBytes + } +} + +func (trace *captureDiagnostics) finish(err error) { + if trace == nil { + return + } + trace.mutex.Lock() + defer trace.mutex.Unlock() + if trace.finished { + return + } + now := time.Now() + trace.record_stage(now) + trace.finished = true + message := "flat review capture timing" + if trace.kind != "" { + message = trace.kind + " capture timing" + } + trace.logger.Debug(message, "duration", now.Sub(trace.started), "error", err, + "last_stage", trace.stage, "stage_duration", now.Sub(trace.stageStarted), + "bus", trace.object.BusName, "object_path", trace.object.Path, "role", trace.role, + "root_bus", trace.root.BusName, "root_path", trace.root.Path, "root_scope", trace.rootScope, + "captured_nodes", trace.capturedNodes, "pending_nodes", trace.pendingNodes, "text_bytes", trace.textBytes, + "text_issues", trace.textIssues, + "stages", trace.timings) +} diff --git a/internal/atspi/capture_diagnostics_test.go b/internal/atspi/capture_diagnostics_test.go new file mode 100644 index 0000000..7819939 --- /dev/null +++ b/internal/atspi/capture_diagnostics_test.go @@ -0,0 +1,90 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/logging" +) + +func TestCaptureDiagnosticsTimeoutDuringNativeCall(t *testing.T) { + var output bytes.Buffer + logger := logging.New(&output, logging.Options{Level: slog.LevelDebug}) + ctx, trace := new_capture_diagnostics(context.Background(), logger, NewObjectID(":1.7", "/focus")) + if capture_diagnostics(ctx) != trace { + t.Fatal("capture context lost its diagnostics") + } + root := NewObjectID(":1.7", "/window") + cell := NewObjectID(":1.7", "/cell") + trace.set_root(root, "window") + trace.begin_stage("queue-wait", root, "frame") + started, resume, done := make(chan struct{}), make(chan struct{}), make(chan struct{}) + go func() { + defer close(done) + trace.begin_stage("visible-text", cell, "table cell") + trace.progress("table cell", 12, 3, 250) + close(started) + <-resume // The native operation is still running when its caller times out. + trace.begin_stage("child-count", cell, "table cell") + trace.progress("table cell", 13, 2, 400) + trace.set_root(NewObjectID(":1.7", "/late-root"), "desktop") + trace.finish(nil) + }() + <-started + trace.finish(context.DeadlineExceeded) + close(resume) + <-done + var record struct { + Error string `json:"error"` + Duration time.Duration `json:"duration"` + LastStage string `json:"last_stage"` + ObjectPath string `json:"object_path"` + Role string `json:"role"` + RootPath string `json:"root_path"` + RootScope string `json:"root_scope"` + CapturedNodes int `json:"captured_nodes"` + PendingNodes int `json:"pending_nodes"` + TextBytes int `json:"text_bytes"` + Stages []captureStageTiming `json:"stages"` + } + if err := json.Unmarshal(output.Bytes(), &record); err != nil { + t.Fatalf("expected one diagnostic record: %v: %s", err, output.Bytes()) + } + if record.Error != context.DeadlineExceeded.Error() || record.LastStage != "visible-text" || record.ObjectPath != cell.Path || record.Role != "table cell" { + t.Fatalf("timeout lost the in-progress operation: %+v", record) + } + if record.RootPath != root.Path || record.RootScope != "window" || record.CapturedNodes != 12 || record.PendingNodes != 3 || record.TextBytes != 250 { + t.Fatalf("late native completion changed timeout metadata: %+v", record) + } + var total time.Duration + for _, stage := range record.Stages { + total += stage.Duration + if stage.Stage == "visible-text" && (stage.SlowestPath != cell.Path || stage.MaxDuration <= 0) { + t.Fatalf("slow operation identity missing: %+v", stage) + } + } + if total != record.Duration || total <= 0 { + t.Fatalf("stage durations %v do not cover capture duration %v", total, record.Duration) + } +} + +func TestCaptureDiagnosticsRequiresDebugLogging(t *testing.T) { + ctx := context.Background() + for _, logger := range []*slog.Logger{nil, logging.New(nil, logging.Options{Level: slog.LevelInfo})} { + gotContext, trace := new_capture_diagnostics(ctx, logger, ObjectID{}) + if gotContext != ctx || trace != nil { + t.Fatal("disabled diagnostics added capture state") + } + trace.begin_stage("snapshot", ObjectID{}, "") + trace.progress("", 0, 0, 0) + trace.set_root(ObjectID{}, "") + trace.finish(nil) + } +} diff --git a/internal/atspi/catalog_native_test.go b/internal/atspi/catalog_native_test.go new file mode 100644 index 0000000..0aebdf6 --- /dev/null +++ b/internal/atspi/catalog_native_test.go @@ -0,0 +1,99 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeBrowserCatalogCapture(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := New() + adapter.SetCaptureSoundGeometry(true) + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + // Move away from the autofocus control and back to obtain a fresh event. + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "Tab", "shift+Tab").CombinedOutput(); err != nil { + t.Fatalf("focus catalog: %v %s", err, out) + } + var focus ObjectID + for !focus.Valid() { + select { + case event := <-adapter.Events(): + if event.Type == FocusedStateEvent && event.Detail1 == 1 && event.Source.Name == "Choose language" { + focus = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + started := time.Now() + captureContext, captureCancel := context.WithTimeout(ctx, 2*time.Second) + tree, err := adapter.CaptureDocument(captureContext, focus) + captureCancel() + elapsed := time.Since(started) + if err != nil { + t.Fatal(err) + } + root, _ := tree.Root() + document, err := tree.Document(ctx, root) + if err != nil { + t.Fatal(err) + } + t.Logf("cold catalog capture: %v, %d nodes", elapsed, len(document.Nodes)) + if len(document.Nodes) < 4800 { + t.Fatalf("catalog capture lost nodes: %d", len(document.Nodes)) + } + lastHeading := findNamedReference(t, tree, "Movie 599") + line, err := adapter.ReadDocumentCaret(ctx, lastHeading, 0, DocumentCaretBrailleLine) + if err != nil || strings.TrimSpace(line.Text) != "Movie 599" { + t.Fatalf("last catalog heading text = %+v, %v", line, err) + } + geometry, err := adapter.CaptureDocumentSoundGeometry(ctx, findNamedReference(t, tree, "Choose language"), ObjectReference{}) + if err != nil || !geometry[0].ObjectKnown || !geometry[0].ReferenceKnown { + t.Fatalf("catalog control sound geometry = %+v, %v", geometry[0], err) + } + if elapsed >= 2*time.Second { + t.Fatalf("cold catalog capture exceeded runtime budget: %v", elapsed) + } + // Dirty semantics/children must refresh even though cold nodes reuse the + // native event cache. Removed objects must not survive the refresh. + if out, err := exec.CommandContext(ctx, "xdotool", "key", "F9").CombinedOutput(); err != nil { + t.Fatalf("update catalog: %v %s", err, out) + } + for { + select { + case event := <-adapter.Events(): + if event.Type != AccessibleNameEvent || event.Source.Name != "Catalog updated" { + continue + } + captureContext, captureCancel = context.WithTimeout(ctx, 2*time.Second) + tree, err = adapter.CaptureDocument(captureContext, focus) + captureCancel() + if err != nil { + t.Fatal(err) + } + findNamedReference(t, tree, "Updated movie") + findNamedReference(t, tree, "New movie") + if _, err := tree.Resolve(lastHeading); err == nil { + t.Fatal("removed catalog heading remained live") + } + return + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } +} diff --git a/internal/atspi/character_attributes_native.go b/internal/atspi/character_attributes_native.go new file mode 100644 index 0000000..31b46b5 --- /dev/null +++ b/internal/atspi/character_attributes_native.go @@ -0,0 +1,102 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "unsafe" +) + +// CharacterAttributes is a copy of the current AT-SPI text attribute run. +// Native handles remain on the GLib thread. +type CharacterAttributes struct { + Object ObjectID + Values map[string]string +} + +var spokenCharacterAttributeKeys = [...]string{ + "size", "family-name", "weight", "indent", "underline", + "strikethrough", "justification", "style", "paragraph-style", + "text-spelling", "fg-color", "bg-color", "invalid", "invalid-spelling", "spelling", +} + +func (adapter *Adapter) ReadCharacterAttributes(ctx context.Context, object ObjectID) (CharacterAttributes, error) { + if !object.Valid() { + return CharacterAttributes{}, ErrStaleObject + } + result, err := adapter.documentOperation(ctx, treeCaptureRequest{reviewFocus: object, readAttributes: true}) + return result.attributes, err +} + +func (adapter *Adapter) readNativeCharacterAttributes(ctx context.Context, object ObjectID) (CharacterAttributes, error) { + if err := ctx.Err(); err != nil { + return CharacterAttributes{}, err + } + if len(adapter.nativeFocus) == 0 || adapter.nativeFocus[len(adapter.nativeFocus)-1].id.BusName != object.BusName { + return CharacterAttributes{}, ErrStaleObject + } + var source *C.AtspiAccessible + if adapter.nativeFocusIs(object) { + source = adapter.nativeFocus[len(adapter.nativeFocus)-1].source + } else { + source = adapter.nativeDocument[object] + } + if source == nil { + return CharacterAttributes{}, ErrStaleObject + } + if C.atspi_accessible_get_role(source, nil) == C.ATSPI_ROLE_PASSWORD_TEXT { + return CharacterAttributes{Object: object}, nil + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return CharacterAttributes{Object: object}, nil + } + defer C.g_object_unref(C.gpointer(text)) + var nativeErr *C.GError + count := C.atspi_text_get_character_count(text, &nativeErr) + if nativeErr != nil { + err := nativeError("read character attribute text length", nativeErr) + C.g_error_free(nativeErr) + return CharacterAttributes{}, err + } + if count <= 0 { + return CharacterAttributes{Object: object}, nil + } + offset := C.atspi_text_get_caret_offset(text, &nativeErr) + if nativeErr != nil { + err := nativeError("read character attribute caret", nativeErr) + C.g_error_free(nativeErr) + return CharacterAttributes{}, err + } + if offset < 0 || offset >= count { + offset = count - 1 + } + var start, end C.gint + attributes := C.atspi_text_get_attribute_run(text, offset, 1, &start, &end, &nativeErr) + if nativeErr != nil { + err := nativeError("read character attributes", nativeErr) + C.g_error_free(nativeErr) + return CharacterAttributes{}, err + } + if attributes == nil { + return CharacterAttributes{Object: object}, nil + } + defer C.g_hash_table_unref(attributes) + result := CharacterAttributes{Object: object, Values: make(map[string]string)} + for _, key := range spokenCharacterAttributeKeys { + name := C.CString(key) + value := C.g_hash_table_lookup(attributes, C.gconstpointer(unsafe.Pointer(name))) + C.free(unsafe.Pointer(name)) + if value != nil { + result.Values[key] = sanitizeSnapshotField(C.GoString((*C.char)(value))) + } + } + return result, ctx.Err() +} diff --git a/internal/atspi/current_line_native.go b/internal/atspi/current_line_native.go new file mode 100644 index 0000000..f18fe57 --- /dev/null +++ b/internal/atspi/current_line_native.go @@ -0,0 +1,86 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#cgo pkg-config: atspi-2 glib-2.0 gobject-2.0 +#include +*/ +import "C" + +import ( + "context" + "errors" + "strings" +) + +// ReadFocusedLine reads only the line containing the current native caret. +func (adapter *Adapter) ReadFocusedLine(ctx context.Context, focus ObjectID) (DocumentContent, error) { + result, err := adapter.documentOperation(ctx, treeCaptureRequest{reviewFocus: focus, readFocusedLine: true}) + return result.content, err +} + +func (adapter *Adapter) read_native_focused_line(ctx context.Context, focus ObjectID) (DocumentContent, error) { + if err := ctx.Err(); err != nil { + return DocumentContent{}, err + } + if !adapter.nativeFocusIs(focus) { + return DocumentContent{}, ErrStaleObject + } + source := adapter.nativeFocus[len(adapter.nativeFocus)-1].source + snapshot := snapshotFromNativeWithCaret(source, false, false, false, false) + if snapshot.Role == "password text" { + return DocumentContent{}, ErrNoDocumentCaret + } + content := DocumentContent{Snapshot: snapshot, Text: snapshot.Name} + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return content, ctx.Err() + } + defer C.g_object_unref(C.gpointer(text)) + reader := nativeReviewText{text: text, terminal: snapshot.Role == "terminal"} + count, err := reader.count(ctx) + if err != nil { + return DocumentContent{}, err + } + content.Text = "" + if count == 0 { + return content, ctx.Err() + } + var nativeErr *C.GError + offset := int(C.atspi_text_get_caret_offset(text, &nativeErr)) + if nativeErr != nil { + err := nativeError("read current line caret", nativeErr) + C.g_error_free(nativeErr) + return DocumentContent{}, err + } + // A text object without a caret reads from its first line, as NVDA does. + offset = min(max(0, offset), count) + if offset == count { + last := C.atspi_text_get_text(text, C.gint(count-1), C.gint(count), &nativeErr) + if last != nil { + defer C.g_free(C.gpointer(last)) + } + if nativeErr != nil { + err := nativeError("read current line end", nativeErr) + C.g_error_free(nativeErr) + return DocumentContent{}, err + } + // A trailing newline puts the caret on an empty final line. + if strings.HasSuffix(C.GoString(last), "\n") { + content.Start, content.End = count, count + return content, ctx.Err() + } + offset-- + } + line, err := reader.line(ctx, offset) + if err != nil { + return DocumentContent{}, err + } + if line.Start < 0 || line.Start > offset || line.End <= offset || line.End > count { + return DocumentContent{}, errors.New("read current line: invalid text range") + } + content.Start, content.End, content.Text, content.RawText = line.Start, line.End, line.Text, line.Text + return content, ctx.Err() +} diff --git a/internal/atspi/current_line_native_test.go b/internal/atspi/current_line_native_test.go new file mode 100644 index 0000000..6a80407 --- /dev/null +++ b/internal/atspi/current_line_native_test.go @@ -0,0 +1,99 @@ +package atspi + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeCurrentLine(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_CURRENT_LINE") != "1" { + t.Skip("requires private Xvfb and AT-SPI") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-u", "../../tests/current_line_fixture.py") + fixture.Stderr = os.Stderr + stdin, _ := fixture.StdinPipe() + stdout, _ := fixture.StdoutPipe() + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + ready := func() { + t.Helper() + if !scanner.Scan() || scanner.Text() != "ready" { + t.Fatalf("fixture not ready: %q %v", scanner.Text(), scanner.Err()) + } + } + ready() + var focus ObjectID + lastControl := "" + for _, probe := range []struct { + control, text string + offset int + want string + password bool + }{ + {"entry", "Café 猫 complete", 7, "Café 猫 complete", false}, + {"text", "First\nSecond café 猫\nThird", 11, "Second café 猫", false}, + {"entry", "Final line", 10, "Final line", false}, + {"text", "First\n\nLast", 6, "", false}, + {"entry", "", 0, "", false}, + {"text", "Final\n", 6, "", false}, + {"password", "private test text", 5, "", true}, + {"button", "", 0, "Example button", false}, + } { + command, _ := json.Marshal(map[string]any{"action": "focus", "control": probe.control, "text": probe.text, "offset": probe.offset}) + fmt.Fprintln(stdin, string(command)) + ready() + if probe.control != lastControl { + for { + select { + case event := <-adapter.Events(): + if event.Type == "object:state-changed:focused" && event.Detail1 == 1 && + (event.Source.Name == map[string]string{"entry": "Entry", "text": "Text", "password": "Password", "button": "Example button"}[probe.control]) { + focus = event.Source.ID() + goto focused + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + focused: + lastControl = probe.control + content, err := adapter.ReadFocusedLine(ctx, focus) + if probe.password { + if err == nil || content.Text != "" || content.Snapshot.Name != "" { + t.Fatalf("password report: %+v %v", content, err) + } + continue + } + if err != nil || strings.TrimRight(content.Text, "\r\n") != probe.want { + t.Fatalf("%s offset %d: %+v %v, want %q", probe.control, probe.offset, content, err, probe.want) + } + if probe.control != "button" { + fmt.Fprintf(stdin, "{\"action\":\"caret\",\"control\":%q}\n", probe.control) + if !scanner.Scan() || scanner.Text() != fmt.Sprint(probe.offset) { + t.Fatalf("caret moved: %q, want %d", scanner.Text(), probe.offset) + } + ready() + } + } + if _, err := adapter.ReadFocusedLine(ctx, ObjectID{BusName: focus.BusName, Path: "/stale"}); err == nil { + t.Fatal("accepted stale native focus") + } +} diff --git a/internal/atspi/document.go b/internal/atspi/document.go new file mode 100644 index 0000000..8fc5660 --- /dev/null +++ b/internal/atspi/document.go @@ -0,0 +1,195 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "context" + "errors" +) + +var ErrNotInDocument = errors.New("accessible is outside web document content") + +// DocumentContext identifies both the innermost document and the outermost +// document containing an object. Ancestors run from the object to the tree +// root. All data is copied under one tree lock; no native references escape. +type DocumentContext struct { + Document ObjectReference + TopLevel ObjectReference + Ancestors []Snapshot +} + +// IsWebDocumentRole follows the shared Python web script's document roles. +// Generic text/spreadsheet documents must not enable browser key handling. +func IsWebDocumentRole(role string) bool { + return role == "document web" || role == "document frame" || role == "embedded" +} + +func (tree *AccessibleTree) DocumentContext(reference ObjectReference) (DocumentContext, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + return tree.documentContextLocked(reference) +} + +func (tree *AccessibleTree) documentContextLocked(reference ObjectReference) (DocumentContext, error) { + entry, err := tree.resolveLocked(reference) + if err != nil { + return DocumentContext{}, err + } + var result DocumentContext + for { + if entry.snapshotInvalid { + return DocumentContext{}, ErrStaleSnapshot + } + result.Ancestors = append(result.Ancestors, entry.snapshot) + if IsWebDocumentRole(entry.snapshot.Role) { + if !result.Document.Valid() { + result.Document = reference + } + result.TopLevel = reference + } + if !entry.hasParent { + break + } + id := entry.parent + entry = tree.nodes[id] + reference = newObjectReference(id, entry) + } + if !result.Document.Valid() { + return DocumentContext{}, ErrNotInDocument + } + return result, nil +} + +// DocumentNode is one owned semantic object in document tree order. Visible +// does not mean on-screen: document navigation must include offscreen content. +type DocumentNode struct { + Reference ObjectReference + Parent ObjectID + Snapshot Snapshot + Geometry Geometry + Text VisibleText + Hidden bool + // ParentEditable is captured with the node so entry matching stays + // constant-time instead of rescanning the complete document per candidate. + ParentEditable bool + Children []ObjectID +} + +type DocumentSnapshot struct { + Context DocumentContext + Nodes []DocumentNode + data *documentData +} + +// Document copies the top-level document, including embedded documents but +// excluding browser chrome and other tabs. A stale/incomplete capture fails +// atomically. It does not use flat review's viewport-limited text ranges. +func (tree *AccessibleTree) Document(ctx context.Context, reference ObjectReference) (DocumentSnapshot, error) { + view, err := tree.DocumentView(ctx, reference) + if err != nil { + return DocumentSnapshot{}, err + } + view.Nodes = append([]DocumentNode(nil), view.Nodes...) + view.data = nil + return view, nil +} + +// DocumentView validates the complete document atomically and shares its +// immutable data. Like NavigationDocument, the returned Nodes are read-only. +func (tree *AccessibleTree) DocumentView(ctx context.Context, reference ObjectReference) (DocumentSnapshot, error) { + tree.mu.Lock() + defer tree.mu.Unlock() + view, err := tree.navigation_document_locked(ctx, reference) + if err != nil { + return DocumentSnapshot{}, err + } + if err := tree.validate_document_range_locked(ctx, view, 0, len(view.Nodes)-1); err != nil { + return DocumentSnapshot{}, err + } + return view, nil +} + +// NavigationDocument shares immutable document data until Replace or removal +// changes the tree. Callers must not modify Nodes or their nested slices. Dirty +// entries remain in the view: navigation validates the path it actually uses +// with ValidateDocumentRange rather than recapturing unrelated page updates. +func (tree *AccessibleTree) NavigationDocument(ctx context.Context, reference ObjectReference) (DocumentSnapshot, error) { + tree.mu.Lock() + defer tree.mu.Unlock() + return tree.navigation_document_locked(ctx, reference) +} + +func (tree *AccessibleTree) navigation_document_locked(ctx context.Context, reference ObjectReference) (DocumentSnapshot, error) { + if err := ctx.Err(); err != nil { + return DocumentSnapshot{}, err + } + owner, err := tree.documentContextLocked(reference) + if err != nil { + return DocumentSnapshot{}, err + } + if data := tree.documents[owner.TopLevel.ID()]; data != nil { + return DocumentSnapshot{Context: owner, Nodes: data.nodes, data: data}, nil + } + capacity := 128 + if owner.TopLevel.ID() == tree.root { + capacity = len(tree.nodes) + } + result := DocumentSnapshot{Context: owner, Nodes: make([]DocumentNode, 0, capacity)} + type pendingNode struct { + id ObjectID + hidden bool + } + pending := []pendingNode{{id: owner.TopLevel.ID()}} + for len(pending) > 0 { + if err := ctx.Err(); err != nil { + return DocumentSnapshot{}, err + } + last := len(pending) - 1 + next := pending[last] + pending = pending[:last] + entry, present := tree.nodes[next.id] + if !present { + return DocumentSnapshot{}, ErrIncompleteTree + } + hidden := next.hidden || entry.geometry.VisibilityKnown && !entry.geometry.Visible + parentEditable := false + if entry.hasParent { + parentEditable = tree.nodes[entry.parent].snapshot.Editable + } + result.Nodes = append(result.Nodes, DocumentNode{ + Parent: entry.parent, + Reference: newObjectReference(next.id, entry), + Snapshot: entry.snapshot, + Geometry: entry.geometry, + Text: entry.text, + Hidden: hidden, + ParentEditable: parentEditable, + Children: entry.children, + }) + for i := len(entry.children) - 1; i >= 0; i-- { + pending = append(pending, pendingNode{entry.children[i], hidden}) + } + } + result.data = new_document_data(result.Nodes) + populate_document_rows(&result) + if tree.documents == nil { + tree.documents = make(map[ObjectID]*documentData) + } + tree.documents[owner.TopLevel.ID()] = result.data + return result, nil +} diff --git a/internal/atspi/document_caret.go b/internal/atspi/document_caret.go new file mode 100644 index 0000000..ab8b285 --- /dev/null +++ b/internal/atspi/document_caret.go @@ -0,0 +1,43 @@ +package atspi + +import "unicode/utf8" + +// DocumentCaretUnit selects the AT-SPI text granularity for virtual browsing. +type DocumentCaretUnit uint8 + +const ( + DocumentCaretCharacter DocumentCaretUnit = iota + 1 + DocumentCaretWord + DocumentCaretLine + DocumentCaretLineRemainder + // DocumentCaretBrailleLine preserves native spacing for display offsets. + DocumentCaretBrailleLine + // DocumentCaretCharacters returns a bounded block of raw characters for + // whitespace traversal. It does not normalize spaces or query line geometry. + DocumentCaretCharacters +) + +func (unit DocumentCaretUnit) Valid() bool { + return unit >= DocumentCaretCharacter && unit <= DocumentCaretCharacters +} + +type DocumentCaretText struct { + TextAttributeRuns []TextAttributeRun + Start int + End int + Text string + RawText string + Misspelled bool + CharacterCount int + SelectionStart, SelectionEnd int + // Bounds describe this native line, including offscreen document text. + Bounds Rectangle +} + +func documentCaretCharacter(value string) string { + if value == "" { + return "" + } + character, _ := utf8.DecodeRuneInString(value) + return string(character) +} diff --git a/internal/atspi/document_caret_echo.go b/internal/atspi/document_caret_echo.go new file mode 100644 index 0000000..dd78dff --- /dev/null +++ b/internal/atspi/document_caret_echo.go @@ -0,0 +1,59 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +func documentNavigationEchoBit(event Event, offset int, selectionOffsets map[int]bool) uint8 { + switch event.Type { + case FocusEvent: + return 1 + case FocusedStateEvent: + return 2 + case CaretEvent: + // New native selection is user input, even if its endpoint happens + // to match a previously requested caret or collapsed selection. + if event.Source.TextCaretKnown && event.Source.SelectionEnd > event.Source.SelectionStart { + return 0 + } + if event.Detail1 == offset { + return 4 + } + if event.Source.TextCaretKnown && selectionOffsets[event.Detail1] { + return 8 + } + } + return 0 +} + +// Chromium can echo a static text caret on its enclosing label/paragraph. +// Include only a single-child chain sharing the complete text offset domain. +// Composite parents have their own hypertext offsets and cannot be matched. +func documentCaretEchoAncestors(tree *AccessibleTree, reference ObjectReference) []ObjectID { + var ids []ObjectID + child, err := tree.Resolve(reference) + if err != nil || child.CharacterCount <= 0 { + return nil + } + for attempts := 0; attempts < maxTreeNodes; attempts++ { + parent, ok, err := tree.Parent(reference) + if err != nil || !ok { + break + } + snapshot, err := tree.Resolve(parent) + if err != nil || IsWebDocumentRole(snapshot.Role) || snapshot.Editable || snapshot.CharacterCount != child.CharacterCount { + break + } + first, ok, err := tree.FirstChild(parent) + if err != nil || !ok || first != reference { + break + } + last, ok, err := tree.LastChild(parent) + if err != nil || !ok || last != reference { + break + } + ids = append(ids, parent.ID()) + reference, child = parent, snapshot + } + return ids +} diff --git a/internal/atspi/document_caret_echo_test.go b/internal/atspi/document_caret_echo_test.go new file mode 100644 index 0000000..a8f8502 --- /dev/null +++ b/internal/atspi/document_caret_echo_test.go @@ -0,0 +1,26 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import "testing" + +func TestDocumentRoutingSelectionCollapseEcho(t *testing.T) { + for _, test := range []struct { + offset, start, end int + want uint8 + }{ + {0, 0, 0, 8}, // Selection removal temporarily collapses at zero. + {1, 0, 0, 4}, // Requested route completes at one. + {2, 0, 0, 0}, // An unrelated native movement is not an echo. + {0, 0, 1, 0}, // A fresh native selection must never be swallowed. + {1, 0, 1, 0}, + } { + event := NewEvent(CaretEvent, Snapshot{TextCaretKnown: true, SelectionStart: test.start, SelectionEnd: test.end}) + event.Detail1 = test.offset + if got := documentNavigationEchoBit(event, 1, map[int]bool{0: true, 1: true}); got != test.want { + t.Fatalf("offset %d, selection %d:%d: bit %d, want %d", test.offset, test.start, test.end, got, test.want) + } + } +} diff --git a/internal/atspi/document_caret_test.go b/internal/atspi/document_caret_test.go new file mode 100644 index 0000000..596594c --- /dev/null +++ b/internal/atspi/document_caret_test.go @@ -0,0 +1,15 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import "testing" + +func TestDocumentCaretCharacterPreservesDelimiters(t *testing.T) { + for _, value := range []string{"", " ", "\t", "\n", "\r", "\u00a0", "猫", "é", "\ufffc"} { + if got := documentCaretCharacter(value); got != value { + t.Errorf("character %q became %q", value, got) + } + } +} diff --git a/internal/atspi/document_error.go b/internal/atspi/document_error.go new file mode 100644 index 0000000..19e6f65 --- /dev/null +++ b/internal/atspi/document_error.go @@ -0,0 +1,61 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "fmt" + "strings" +) + +// A removed Chromium generated-text object can return zero characters before +// its removal event reaches us. Refresh its metadata and parent's child order +// rather than silently skipping text from an obsolete snapshot. Empty text +// alone does not prove removal, so keep identities and live siblings intact. +func (adapter *Adapter) document_text_became_empty(object ObjectID) error { + adapter.treeMutex.Lock() + tree := adapter.documentTree + adapter.treeMutex.Unlock() + if tree != nil { + tree.mu.RLock() + entry := tree.nodes[object] + tree.mu.RUnlock() + adapter.treeInvalidations.Add(uint64(tree.InvalidateSnapshot(object))) + if entry.hasParent { + adapter.treeInvalidations.Add(uint64(tree.MarkChildrenChanged(entry.parent))) + } + } + delete(adapter.documentLineCache, object) + return ErrStaleText +} + +// libatspi forwards Chromium's missing-object response as an untyped GError. +// Match the queried path exactly; a timeout or unsupported caret is not proof +// that the virtual reading position has disappeared. +func (adapter *Adapter) document_object_error(object ObjectID, err error) error { + if err == nil || !object.Valid() || !strings.HasSuffix(strings.TrimSpace(err.Error()), + "could not be processed as object "+object.Path+" does not exist") { + return err + } + adapter.treeMutex.Lock() + trees := []*AccessibleTree{adapter.tree, adapter.documentTree, adapter.documentTextTree} + adapter.treeMutex.Unlock() + for _, tree := range trees { + if tree == nil { + continue + } + tree.mu.RLock() + entry := tree.nodes[object] + tree.mu.RUnlock() + adapter.treeInvalidations.Add(uint64(tree.Invalidate(object))) + if entry.hasParent { + // Virtualized pages can replace the enclosing post or feed, not + // just this target. Refresh every ancestor's child list so capture + // reaches the live replacement rather than reusing stale branches. + adapter.treeInvalidations.Add(uint64(tree.markAncestorChildrenChanged(entry.parent))) + } + } + clear(adapter.documentLineCache) + return fmt.Errorf("%w: %w", ErrDeadObject, err) +} diff --git a/internal/atspi/document_error_test.go b/internal/atspi/document_error_test.go new file mode 100644 index 0000000..0b44cf6 --- /dev/null +++ b/internal/atspi/document_error_test.go @@ -0,0 +1,120 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "errors" + "fmt" + "testing" +) + +func TestDocumentMissingObjectRetiresCachedTarget(t *testing.T) { + adapter := New() + adapter.tree, adapter.documentTree, adapter.documentTextTree = testTree(t), testTree(t), testTree(t) + object := testID("/second") + failure := fmt.Errorf("get document caret: Method %q with signature %q on interface %q could not be processed as object %s does not exist\n", + "Get", "ss", "org.freedesktop.DBus.Properties", object.Path) + err := adapter.document_object_error(object, failure) + if !errors.Is(err, ErrDeadObject) || !errors.Is(err, failure) { + t.Fatalf("missing-object error lost classification or details: %v", err) + } + for _, tree := range []*AccessibleTree{adapter.tree, adapter.documentTree, adapter.documentTextTree} { + if _, err := tree.Reference(object); !errors.Is(err, ErrObjectNotFound) { + t.Fatalf("removed target remains cached: %v", err) + } + if _, err := tree.Reference(testID("/grandchild")); !errors.Is(err, ErrObjectNotFound) { + t.Fatalf("removed descendant remains cached: %v", err) + } + if _, err := tree.Reference(testID("/first")); err != nil { + t.Fatalf("live sibling was retired: %v", err) + } + root, _ := tree.Root() + if _, _, err := tree.FirstChild(root); !errors.Is(err, ErrIncompleteTree) { + t.Fatalf("parent child order was not marked for refresh: %v", err) + } + } +} + +func TestDocumentCaretFailuresDoNotRetireLiveTargets(t *testing.T) { + for _, message := range []string{ + "browser refused document caret", + "get document caret: timeout", + "get document caret: unknown property CaretOffset", + "could not be processed as object /other does not exist", + "could not be processed as object /second_child does not exist", + } { + t.Run(message, func(t *testing.T) { + adapter := New() + adapter.documentTree = testTree(t) + failure := errors.New(message) + if err := adapter.document_object_error(testID("/second"), failure); err != failure { + t.Fatalf("ordinary failure reclassified: %v", err) + } + if _, err := adapter.documentTree.Reference(testID("/second")); err != nil { + t.Fatalf("unconfirmed removal retired live target: %v", err) + } + }) + } +} + +func TestDocumentEmptyTextRefreshesMetadataAndParentWithoutRetiringTargets(t *testing.T) { + adapter := New() + tree := testTree(t) + adapter.documentTree = tree + object := testID("/second") + target, _ := tree.Reference(object) + sibling, _ := tree.Reference(testID("/first")) + if err := adapter.document_text_became_empty(object); !errors.Is(err, ErrStaleText) { + t.Fatalf("unexpected empty-text classification: %v", err) + } + if current, err := tree.Reference(object); err != nil || current != target { + t.Fatalf("empty text retired an unconfirmed target: %v", err) + } + if _, err := tree.Resolve(target); !errors.Is(err, ErrStaleSnapshot) { + t.Fatalf("text metadata did not require refresh: %v", err) + } + if _, err := tree.Resolve(sibling); err != nil { + t.Fatalf("live sibling was invalidated: %v", err) + } + root, _ := tree.Root() + if _, _, err := tree.FirstChild(root); !errors.Is(err, ErrIncompleteTree) { + t.Fatalf("parent's children did not require refresh: %v", err) + } +} + +func TestDocumentMissingDescendantRefreshesAncestorChildOrder(t *testing.T) { + adapter := New() + adapter.tree, adapter.documentTree, adapter.documentTextTree = testTree(t), testTree(t), testTree(t) + object := testID("/grandchild") + failure := fmt.Errorf("get document caret: could not be processed as object %s does not exist", object.Path) + if err := adapter.document_object_error(object, failure); !errors.Is(err, ErrDeadObject) { + t.Fatal(err) + } + for _, tree := range []*AccessibleTree{adapter.tree, adapter.documentTree, adapter.documentTextTree} { + for _, id := range []ObjectID{testID("/second"), testID("/root")} { + ref, err := tree.Reference(id) + if err != nil { + t.Fatal(err) + } + if _, _, err := tree.FirstChild(ref); !errors.Is(err, ErrIncompleteTree) { + t.Fatalf("ancestor %s retained obsolete child order: %v", id.Path, err) + } + } + // Refresh ancestry without declaring unrelated siblings dead or dirty. + sibling, err := tree.Reference(testID("/first")) + if err != nil { + t.Fatal(err) + } + if _, err := tree.Resolve(sibling); err != nil { + t.Fatal(err) + } + if _, _, err := tree.FirstChild(sibling); err != nil { + t.Fatal(err) + } + if _, err := tree.Reference(object); !errors.Is(err, ErrObjectNotFound) { + t.Fatalf("missing object survived: %v", err) + } + } +} diff --git a/internal/atspi/document_hypertext_native.go b/internal/atspi/document_hypertext_native.go new file mode 100644 index 0000000..cf543d3 --- /dev/null +++ b/internal/atspi/document_hypertext_native.go @@ -0,0 +1,76 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include +*/ +import "C" + +import "context" + +// Capture only single-character embedded children. Chromium's ordinary text +// descendants share their parent's offset domain and need no extra ranges. +// Require every child to occupy one placeholder, avoiding duplicate text from +// containers which also expose their plain text through static children. +// All handles stay on the GLib owner and are released before returning. +func nativeTextChildren(ctx context.Context, source *C.AtspiAccessible, count int, children []ObjectID) []TextChild { + if count <= 0 || len(children) == 0 { + return nil + } + hypertext := C.atspi_accessible_get_hypertext_iface(source) + if hypertext == nil { + return nil + } + defer C.g_object_unref(C.gpointer(hypertext)) + links := int(C.atspi_hypertext_get_n_links(hypertext, nil)) + if links <= 0 || links != len(children) { + return nil + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return nil + } + defer C.g_object_unref(C.gpointer(text)) + known := make(map[ObjectID]bool, len(children)) + for _, child := range children { + known[child] = true + } + var result []TextChild + previous := -1 + for index := 0; index < links; index++ { + if ctx.Err() != nil { + return nil + } + link := C.atspi_hypertext_get_link(hypertext, C.gint(index), nil) + if link == nil { + return nil + } + start := int(C.atspi_hyperlink_get_start_index(link, nil)) + end := int(C.atspi_hyperlink_get_end_index(link, nil)) + child := C.atspi_hyperlink_get_object(link, 0, nil) + var id ObjectID + if child != nil { + id = nativeObjectID(child) + C.g_object_unref(C.gpointer(child)) + } + C.g_object_unref(C.gpointer(link)) + if start <= previous || end != start+1 || start < 0 || end > count || !known[id] { + return nil + } + value := C.atspi_text_get_text(text, C.gint(start), C.gint(end), nil) + placeholder := value != nil && C.GoString(value) == "\ufffc" + if value != nil { + C.g_free(C.gpointer(value)) + } + if !placeholder { + return nil + } + delete(known, id) + result = append(result, TextChild{Offset: start, Child: id}) + previous = start + } + return result +} diff --git a/internal/atspi/document_line.go b/internal/atspi/document_line.go new file mode 100644 index 0000000..e221dca --- /dev/null +++ b/internal/atspi/document_line.go @@ -0,0 +1,131 @@ +package atspi + +import ( + "context" + "errors" + "math" +) + +var ErrNoDocumentCaret = errors.New("document caret line unavailable") + +type DocumentContent struct { + Reference ObjectReference + Snapshot Snapshot + Start int + End int + Text string + RawText string + // Separator is display spacing before this object, outside its native range. + Separator string + Bounds Rectangle +} + +type DocumentLine struct { + Context []Snapshot + Document ObjectReference + Contents []DocumentContent +} + +func (tree *AccessibleTree) DocumentLineAtOffset(ctx context.Context, reference ObjectReference, offset int) (DocumentLine, error) { + document, err := tree.DocumentView(ctx, reference) + if err != nil { + return DocumentLine{}, err + } + + caretIndex := -1 + if reference.Valid() { + for index, node := range document.Nodes { + if node.Reference == reference { + caretIndex = index + break + } + } + } + if caretIndex < 0 { + for index, node := range document.Nodes { + if node.Text.CaretKnown { + caretIndex = index + break + } + } + } + if caretIndex < 0 { + return DocumentLine{}, ErrNoDocumentCaret + } + + caretNode := document.Nodes[caretIndex] + if offset < 0 { + offset = caretNode.Text.CaretOffset + } + if offset < 0 { + return DocumentLine{}, ErrNoDocumentCaret + } + + caretRange, found := textRangeAtOffset(caretNode.Text, offset) + if !found || !caretRange.Bounds.Valid() { + return DocumentLine{}, ErrNoDocumentCaret + } + + ancestors := document.Context.Ancestors + if len(ancestors) > 0 && ancestors[0].ID() == reference.ID() { + ancestors = ancestors[1:] + } + line := DocumentLine{Document: document.Context.TopLevel, Context: ancestors} + for _, node := range document.Nodes { + if node.Hidden { + continue + } + for _, textRange := range node.Text.Ranges { + if !boundsAreOnSameLine(caretRange.Bounds, textRange.Bounds) { + continue + } + if textRange.Text == "" { + continue + } + line.Contents = append(line.Contents, DocumentContent{ + Reference: node.Reference, + Snapshot: node.Snapshot, + Start: textRange.Start, + End: textRange.End, + Text: textRange.Text, + RawText: textRange.Text, + Bounds: textRange.Bounds, + }) + } + } + if len(line.Contents) == 0 { + return DocumentLine{}, ErrNoDocumentCaret + } + return line, nil +} + +func textRangeAtOffset(text VisibleText, offset int) (TextRange, bool) { + for _, textRange := range text.Ranges { + if textRange.Start <= offset && offset < textRange.End { + return textRange, true + } + } + for _, textRange := range text.Ranges { + if textRange.Start <= offset && offset <= textRange.End { + return textRange, true + } + } + return TextRange{}, false +} + +func boundsAreOnSameLine(first, second Rectangle) bool { + if first == second { + return true + } + if !first.Valid() || !second.Valid() { + return false + } + top := max(first.Y, second.Y) + bottom := min(first.Y+first.Height, second.Y+second.Height) + if bottom <= top { + return false + } + firstCenter := first.Y + first.Height/2 + secondCenter := second.Y + second.Height/2 + return math.Abs(float64(firstCenter-secondCenter)) <= 5 +} diff --git a/internal/atspi/document_lines_native.go b/internal/atspi/document_lines_native.go new file mode 100644 index 0000000..eaceb0e --- /dev/null +++ b/internal/atspi/document_lines_native.go @@ -0,0 +1,118 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include +*/ +import "C" + +import ( + "context" + "strings" + "time" + "unicode/utf8" +) + +func (adapter *Adapter) readNativeDocumentLine(ctx context.Context, id ObjectID, snapshot Snapshot, text *C.AtspiText, offset, count int) (DocumentCaretText, error) { + source := nativeReviewText{text: text} + line, err := source.line(ctx, offset) + if err != nil { + return DocumentCaretText{}, err + } + result := DocumentCaretText{Start: line.Start, End: line.End, Text: line.Text, CharacterCount: count} + if snapshot.Editable || snapshot.Role == "password text" || snapshot.HTMLTag == "pre" || snapshot.HTMLTag == "code" || count > maxReviewLineCharacters || + len(strings.Fields(line.Text)) > 1 || line.Start == 0 && line.End == count { + return result, nil + } + if cached, ok := adapter.documentLineCache[id]; ok && cached.CharacterCount == count { + if cached.End > 0 { + return cached, nil + } + return result, nil + } + adapter.treeMutex.Lock() + tree := adapter.documentTree + adapter.treeMutex.Unlock() + if tree != nil { + if ref, err := tree.Reference(id); err == nil { + if owner, err := tree.DocumentContext(ref); err == nil { + for _, ancestor := range owner.Ancestors { + if ancestor.HTMLTag == "pre" || ancestor.HTMLTag == "code" || strings.Contains(" "+ancestor.XMLRoles+" ", " code ") { + return result, nil + } + } + } + } + } + var nativeErr *C.GError + value := C.atspi_text_get_text(text, 0, C.gint(count), &nativeErr) + if value != nil { + defer C.g_free(C.gpointer(value)) + } + if nativeErr != nil { + C.g_error_free(nativeErr) + return result, nil + } + content := strings.ToValidUTF8(C.GoString(value), "�") + if utf8.RuneCountInString(content) != count { + return result, nil + } + probe, cancel := context.WithTimeout(ctx, 100*time.Millisecond) + repair, probeErr := documentLinesAreTokens(probe, source, content) + cancel() + if probeErr != nil { + return result, ctx.Err() + } + if adapter.documentLineCache == nil || len(adapter.documentLineCache) >= 64 { + adapter.documentLineCache = make(map[ObjectID]DocumentCaretText) + } + cached := DocumentCaretText{CharacterCount: count} + if repair { + cached.End, cached.Text = count, content + result = cached + } + adapter.documentLineCache[id] = cached + return result, nil +} + +// Repair only owned web text, on the GLib owner. Native selections use the +// same logical line as virtual browsing, including braille cursor placement. +func (adapter *Adapter) repairNativeCaretLine(source *C.AtspiAccessible, snapshot *Snapshot, offset int) { + if !snapshot.TextCaretKnown || snapshot.Editable || snapshot.Role == "password text" || offset < 0 { + return + } + adapter.treeMutex.Lock() + tree := adapter.documentTree + adapter.treeMutex.Unlock() + if tree == nil { + return + } + ref, err := tree.Reference(snapshot.ID()) + if err != nil { + return + } + if _, err = tree.DocumentContext(ref); err != nil { + return + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return + } + defer C.g_object_unref(C.gpointer(text)) + count := int(C.atspi_text_get_character_count(text, nil)) + if count <= 0 || offset > count { + return + } + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() + line, err := adapter.readNativeDocumentLine(ctx, snapshot.ID(), *snapshot, text, min(offset, count-1), count) + if err != nil || line.Start < 0 || line.End <= line.Start { + return + } + snapshot.Text = sanitizeSnapshotField(line.Text) + snapshot.BrailleLine, snapshot.BrailleLineStart, snapshot.BrailleCaret = line.Text, line.Start, offset + snapshot.CharacterCount = count +} diff --git a/internal/atspi/document_lines_native_test.go b/internal/atspi/document_lines_native_test.go new file mode 100644 index 0000000..ae7f37f --- /dev/null +++ b/internal/atspi/document_lines_native_test.go @@ -0,0 +1,94 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeBrowserLogicalLines(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "Tab").CombinedOutput(); err != nil { + t.Fatalf("focus editable lines: %v %s", err, out) + } + var focus ObjectID + for !focus.Valid() { + select { + case event := <-adapter.Events(): + if (event.Type == FocusEvent || event.Type == FocusedStateEvent && event.Detail1 == 1) && event.Source.Name == "Editable lines" { + focus = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + tree, err := adapter.CaptureDocument(ctx, focus) + if err != nil { + t.Fatal(err) + } + text := findNamedReference(t, tree, "What's on your mind?") + for _, offset := range []int{0, 7, 10, 15, 20} { + line, err := adapter.ReadDocumentCaret(ctx, text, offset, DocumentCaretBrailleLine) + if err != nil || line.Start != 0 || line.End != 20 || line.Text != "What's on your mind?" { + t.Fatalf("line at %d = %+v, %v", offset, line, err) + } + } + remainder, err := adapter.ReadDocumentCaret(ctx, text, 7, DocumentCaretLineRemainder) + if err != nil || remainder.Start != 7 || remainder.Text != "on your mind?" { + t.Fatalf("remainder = %+v, %v", remainder, err) + } + for _, test := range []struct{ name, first string }{ + {"First Second", "First"}, {"Code text", "Code"}, {"Editable lines", "First"}, + } { + ref := findNamedReference(t, tree, test.name) + line, err := adapter.ReadDocumentCaret(ctx, ref, 0, DocumentCaretBrailleLine) + if err != nil || strings.TrimSpace(line.Text) != test.first { + t.Fatalf("preserved %s line = %+v, %v", test.name, line, err) + } + } + for _, name := range []string{"Truncated preview…", "猫🐈…", "…"} { + ref := findNamedReference(t, tree, name) + if !ref.Valid() { + t.Fatalf("ellipsis object %q missing", name) + } + offset := len([]rune(name)) - 1 + for _, unit := range []DocumentCaretUnit{DocumentCaretLine, DocumentCaretBrailleLine, DocumentCaretLineRemainder} { + line, err := adapter.ReadDocumentCaret(ctx, ref, offset, unit) + if err != nil || line.End != offset+1 || !strings.HasSuffix(line.Text, "…") { + t.Fatalf("ellipsis %q unit %d = %+v, %v", name, unit, line, err) + } + } + if err := adapter.SetDocumentCaretPosition(ctx, ref, focus, offset); err != nil { + t.Fatalf("place caret on ellipsis: %v", err) + } + // Drain the actual native caret event, exercising snapshot text, + // character/word capture and logical-line repair before proceeding. + for { + select { + case event := <-adapter.Events(): + if event.Type == CaretEvent && strings.HasSuffix(event.Source.BrailleLine, "…") { + goto caretCaptured + } + case <-ctx.Done(): + t.Fatal("ellipsis caret event missing: ", ctx.Err()) + } + } + caretCaptured: + } +} diff --git a/internal/atspi/document_rows.go b/internal/atspi/document_rows.go new file mode 100644 index 0000000..b63f9a6 --- /dev/null +++ b/internal/atspi/document_rows.go @@ -0,0 +1,94 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "sort" + "strings" +) + +// Derive rows from the already captured document. This performs no native +// queries and keeps large tables bounded to 32 cells and 4096 bytes per row. +func populate_document_rows(document *DocumentSnapshot) { + nodes := document.data.indices + type rowKey struct { + table ObjectID + row int + } + rows := make(map[rowKey][]int) + owners := make(map[int]rowKey) + for index, node := range document.Nodes { + if node.Hidden || !node.Snapshot.TablePositionKnown || node.Snapshot.Role != "table cell" { + continue + } + current := node.Parent + var owner ObjectID + spreadsheet := false + for depth := 0; depth < 32 && current.Valid(); depth++ { + parentIndex, exists := nodes[current] + if !exists { + break + } + parent := document.Nodes[parentIndex] + if owner == (ObjectID{}) && parent.Snapshot.Role == "table" { + owner = current + } + if parent.Snapshot.Role == "document spreadsheet" { + spreadsheet = true + } + current = parent.Parent + } + if !owner.Valid() { + continue + } + document.Nodes[index].Snapshot.Spreadsheet = spreadsheet + document.Nodes[index].Snapshot.TablePath = owner.Path + key := rowKey{owner, node.Snapshot.TableRowIndex} + if len(rows[key]) < 32 { + rows[key] = append(rows[key], index) + } + owners[index] = key + } + texts := make(map[rowKey]string, len(rows)) + dependencies := make(map[rowKey][]ObjectReference, len(rows)) + for key, indices := range rows { + sort.SliceStable(indices, func(a, b int) bool { + return document.Nodes[indices[a]].Snapshot.TableColumnIndex < document.Nodes[indices[b]].Snapshot.TableColumnIndex + }) + // Validation follows the same bounded set used to derive row text. + // Include cells past the byte limit too: shorter updated labels could + // make those cells newly contribute to the next row summary. + references := make([]ObjectReference, len(indices)) + for index, member := range indices { + references[index] = document.Nodes[member].Reference + } + dependencies[key] = references + var parts []string + length := 0 + for _, index := range indices { + snapshot := document.Nodes[index].Snapshot + label := strings.TrimSpace(snapshot.Name) + if label == "" { + label = strings.TrimSpace(snapshot.Text) + } + if label == "" { + label = "blank" + } + if length+len(label)+2 > 4096 { + break + } + length += len(label) + 2 + parts = append(parts, label) + } + texts[key] = strings.Join(parts, ", ") + } + if len(owners) > 0 { + document.data.rows = make(map[ObjectID][]ObjectReference, len(owners)) + } + for index, key := range owners { + document.Nodes[index].Snapshot.TableRowText = texts[key] + document.data.rows[document.Nodes[index].Reference.ID()] = dependencies[key] + } +} diff --git a/internal/atspi/document_rows_test.go b/internal/atspi/document_rows_test.go new file mode 100644 index 0000000..8bb629b --- /dev/null +++ b/internal/atspi/document_rows_test.go @@ -0,0 +1,54 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "testing" +) + +func TestDocumentRowsKeepNestedTablesAndRowsSeparate(t *testing.T) { + node := func(path, role string, children ...ObjectID) TreeNode { + n := testNode(path, path, children...) + n.Snapshot.Role = role + return n + } + cell := func(path, label string, row, column int, children ...ObjectID) TreeNode { + n := node(path, "table cell", children...) + n.Snapshot.Name = label + n.Snapshot.TablePositionKnown = true + n.Snapshot.TableRowIndex, n.Snapshot.TableColumnIndex = row, column + return n + } + tree, err := NewAccessibleTree(testID("/doc"), []TreeNode{ + node("/doc", "document web", testID("/sheet")), + node("/sheet", "document spreadsheet", testID("/outer")), + node("/outer", "table", testID("/b"), testID("/a"), testID("/c")), + cell("/b", "Two", 0, 1), + cell("/a", "One", 0, 0, testID("/inner")), + cell("/c", "Next", 1, 0), + node("/inner", "table", testID("/i")), + cell("/i", "Nested", 0, 0), + }) + if err != nil { + t.Fatal(err) + } + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + document, err := tree.Document(context.Background(), root) + if err != nil { + t.Fatal(err) + } + wants := map[string]string{"/a": "One, Two", "/b": "One, Two", "/c": "Next", "/i": "Nested"} + for _, item := range document.Nodes { + if want, ok := wants[item.Snapshot.Path]; ok { + if item.Snapshot.TableRowText != want || !item.Snapshot.Spreadsheet { + t.Fatalf("row %s: %+v", item.Snapshot.Path, item.Snapshot) + } + } + } +} diff --git a/internal/atspi/document_sound.go b/internal/atspi/document_sound.go new file mode 100644 index 0000000..0eec8d2 --- /dev/null +++ b/internal/atspi/document_sound.go @@ -0,0 +1,40 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "time" +) + +// A successful ScrollTo can precede the browser's visibility/geometry update. +// Retry missing geometry on the calling worker, leaving the native event owner +// free to process those updates. Unsupported geometry gets at most 50ms of +// extra waiting; native calls remain bounded by the caller's context. +func retryDocumentSoundGeometry(ctx context.Context, linked bool, capture func(context.Context) ([2]SoundGeometry, error)) ([2]SoundGeometry, error) { + for attempt := 0; ; attempt++ { + if err := ctx.Err(); err != nil { + return [2]SoundGeometry{}, err + } + geometry, err := capture(ctx) + if err != nil { + return [2]SoundGeometry{}, err + } + ready := geometry[0].ObjectKnown && geometry[0].ReferenceKnown + if linked { + ready = ready && geometry[1].ObjectKnown && geometry[1].ReferenceKnown + } + if ready || attempt == 5 { + return geometry, nil + } + timer := time.NewTimer(10 * time.Millisecond) + select { + case <-ctx.Done(): + timer.Stop() + return [2]SoundGeometry{}, ctx.Err() + case <-timer.C: + } + } +} diff --git a/internal/atspi/document_sound_test.go b/internal/atspi/document_sound_test.go new file mode 100644 index 0000000..99fe28c --- /dev/null +++ b/internal/atspi/document_sound_test.go @@ -0,0 +1,77 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "errors" + "testing" +) + +func TestDocumentSoundGeometryWaitsForBrowserScroll(t *testing.T) { + ready := SoundGeometry{ObjectKnown: true, ReferenceKnown: true, + Object: Rectangle{X: 18, Y: 147, Width: 102, Height: 13}, + Reference: Rectangle{Width: 800, Height: 600}} + for _, linked := range []bool{false, true} { + calls := 0 + geometry, err := retryDocumentSoundGeometry(context.Background(), linked, func(context.Context) ([2]SoundGeometry, error) { + calls++ + // Scroll completion can reach the heading and link at different times. + if calls == 1 { + return [2]SoundGeometry{}, nil + } + if calls == 2 { + return [2]SoundGeometry{ready, {}}, nil + } + return [2]SoundGeometry{ready, ready}, nil + }) + wantCalls := 2 + if linked { + wantCalls = 3 + } + if err != nil || calls != wantCalls || geometry[0] != ready || linked && geometry[1] != ready { + t.Fatalf("linked=%t: calls=%d geometry=%+v err=%v", linked, calls, geometry, err) + } + } +} + +func TestDocumentSoundGeometryRetryBoundsAndCancellation(t *testing.T) { + for _, scenario := range []string{"ready", "unavailable", "stale", "cancelled", "already cancelled"} { + t.Run(scenario, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if scenario == "already cancelled" { + cancel() + } + calls := 0 + _, err := retryDocumentSoundGeometry(ctx, false, func(context.Context) ([2]SoundGeometry, error) { + calls++ + switch scenario { + case "ready": + return [2]SoundGeometry{{ObjectKnown: true, ReferenceKnown: true}, {}}, nil + case "stale": + return [2]SoundGeometry{}, ErrStaleObject + case "cancelled": + cancel() + } + return [2]SoundGeometry{}, nil + }) + wantCalls, wantErr := 1, error(nil) + switch scenario { + case "unavailable": + wantCalls = 6 + case "stale": + wantErr = ErrStaleObject + case "cancelled": + wantErr = context.Canceled + case "already cancelled": + wantCalls, wantErr = 0, context.Canceled + } + if calls != wantCalls || !errors.Is(err, wantErr) { + t.Fatalf("calls=%d err=%v, want calls=%d err=%v", calls, err, wantCalls, wantErr) + } + }) + } +} diff --git a/internal/atspi/document_test.go b/internal/atspi/document_test.go new file mode 100644 index 0000000..e23462d --- /dev/null +++ b/internal/atspi/document_test.go @@ -0,0 +1,369 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "context" + "errors" + "reflect" + "sync" + "testing" + "unicode/utf8" +) + +func documentTestNodes() []TreeNode { + node := func(path, role string, children ...ObjectID) TreeNode { + n := testNode(path, path, children...) + n.Snapshot.Role = role + return n + } + return []TreeNode{ + node("/root", "frame", testID("/chrome"), testID("/doc"), testID("/other")), + node("/chrome", "entry"), + node("/doc", "document web", testID("/heading"), testID("/inner")), + node("/heading", "heading"), + node("/inner", "document frame", testID("/link")), + node("/link", "link"), + node("/other", "document web"), + } +} + +func TestDocumentTargetFocusPolicyForHeadings(t *testing.T) { + nodes := []TreeNode{ + testNode("/doc", "/doc", testID("/ordinary"), testID("/linked"), testID("/button"), testID("/entry"), testID("/image"), testID("/imageLink")), + testNode("/ordinary", "/ordinary", testID("/text")), + testNode("/text", "/text"), + testNode("/linked", "/linked", testID("/link")), + testNode("/link", "/link"), + testNode("/button", "/button"), + testNode("/entry", "/entry"), + testNode("/image", "/image"), + testNode("/imageLink", "/imageLink", testID("/linkedImage")), + testNode("/linkedImage", "/linkedImage"), + } + nodes[0].Snapshot.Role = "document web" + for i, role := range map[int]string{1: "heading", 2: "static", 3: "heading", 4: "link", 5: "button", 6: "entry", 7: "image", 8: "link", 9: "image"} { + nodes[i].Snapshot.Role = role + nodes[i].Snapshot.Focusable = true + } + tree, err := NewAccessibleTree(testID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + for _, tc := range []struct { + path string + want bool + }{ + {"/ordinary", false}, + {"/linked", true}, + {"/button", true}, + {"/entry", false}, + {"/image", false}, + {"/linkedImage", true}, + } { + ref, err := tree.Reference(testID(tc.path)) + if err != nil { + t.Fatal(err) + } + snapshot, err := tree.Resolve(ref) + if err != nil { + t.Fatal(err) + } + if got := documentTargetGrabsFocus(tree, ref, snapshot); got != tc.want { + t.Errorf("focus policy for %s = %v, want %v", tc.path, got, tc.want) + } + } +} + +func TestDocumentOwnershipAndOrder(t *testing.T) { + tree, err := NewAccessibleTree(testID("/root"), documentTestNodes()) + if err != nil { + t.Fatal(err) + } + ref, _ := tree.Reference(testID("/link")) + doc, err := tree.Document(context.Background(), ref) + if err != nil { + t.Fatal(err) + } + if doc.Context.Document.ID() != testID("/inner") || doc.Context.TopLevel.ID() != testID("/doc") { + t.Fatalf("wrong document ownership: %+v", doc.Context) + } + var paths []string + for _, node := range doc.Nodes { + paths = append(paths, node.Snapshot.Path) + } + if !reflect.DeepEqual(paths, []string{"/doc", "/heading", "/inner", "/link"}) { + t.Fatalf("document order: %v", paths) + } + var ancestors []string + for _, node := range doc.Context.Ancestors { + ancestors = append(ancestors, node.Path) + } + if !reflect.DeepEqual(ancestors, []string{"/link", "/inner", "/doc", "/root"}) { + t.Fatalf("ancestry: %v", ancestors) + } + doc.Nodes[0].Snapshot.Name = "mutated" + doc.Context.Ancestors[0].Name = "mutated" + again, err := tree.Document(context.Background(), ref) + if err != nil || again.Nodes[0].Snapshot.Name != "/doc" || again.Context.Ancestors[0].Name != "/link" { + t.Fatalf("snapshot aliasing: %+v %v", again, err) + } + chrome, _ := tree.Reference(testID("/chrome")) + if _, err := tree.DocumentContext(chrome); !errors.Is(err, ErrNotInDocument) { + t.Fatalf("browser chrome ownership: %v", err) + } +} + +func TestDocumentRejectsStaleCapture(t *testing.T) { + for _, tc := range []struct { + name string + invalidate func(*AccessibleTree) + want error + }{ + {"children", func(tree *AccessibleTree) { tree.InvalidateChildren(testID("/inner")) }, ErrIncompleteTree}, + {"text", func(tree *AccessibleTree) { tree.InvalidateText(testID("/link")) }, ErrStaleText}, + {"visibility", func(tree *AccessibleTree) { tree.InvalidateGeometry(testID("/inner")) }, ErrStaleGeometry}, + {"document", func(tree *AccessibleTree) { tree.Invalidate(testID("/doc")) }, ErrStaleObject}, + } { + t.Run(tc.name, func(t *testing.T) { + tree, _ := NewAccessibleTree(testID("/root"), documentTestNodes()) + ref, _ := tree.Reference(testID("/heading")) + tc.invalidate(tree) + doc, err := tree.Document(context.Background(), ref) + if !errors.Is(err, tc.want) || len(doc.Nodes) != 0 { + t.Fatalf("partial/stale document: %+v %v", doc, err) + } + }) + } +} + +func TestDocumentVisibilityAndCancellation(t *testing.T) { + nodes := documentTestNodes() + nodes[3].Geometry = Geometry{VisibilityKnown: true, Visible: true} // Offscreen, still navigable. + nodes[4].Geometry = Geometry{VisibilityKnown: true} // Hidden ancestor. + tree, _ := NewAccessibleTree(testID("/root"), nodes) + ref, _ := tree.Reference(testID("/heading")) + doc, err := tree.Document(context.Background(), ref) + if err != nil || doc.Nodes[1].Hidden || !doc.Nodes[2].Hidden || !doc.Nodes[3].Hidden { + t.Fatalf("visibility: %+v %v", doc, err) + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := tree.Document(ctx, ref); !errors.Is(err, context.Canceled) { + t.Fatal(err) + } +} + +func TestDocumentLineAssemblesSameVisualRow(t *testing.T) { + nodes := documentTestNodes() + lineNode := func(index int, path, role, content string, bounds Rectangle, caret bool) { + snapshot := NewSnapshot(path, path, role, "", content) + snapshot.BusName = ":1.42" + nodes[index].Snapshot = snapshot + nodes[index].Geometry = Geometry{Bounds: bounds, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + text := VisibleText{Known: true, Ranges: []TextRange{{ + Start: 0, End: utf8.RuneCountInString(content), Text: content, Bounds: bounds, + }}} + if caret { + text.CaretKnown, text.CaretOffset = true, 1 + } + nodes[index].Text = text + } + lineNode(3, "/heading", "heading", "Before", Rectangle{X: 0, Y: 100, Width: 50, Height: 20}, true) + lineNode(5, "/link", "link", "link text", Rectangle{X: 100, Y: 100, Width: 80, Height: 20}, true) + lineNode(6, "/other", "paragraph", "Other row", Rectangle{X: 0, Y: 200, Width: 80, Height: 20}, false) + tree, err := NewAccessibleTree(testID("/root"), nodes) + if err != nil { + t.Fatal(err) + } + ref, err := tree.Reference(testID("/link")) + if err != nil { + t.Fatal(err) + } + line, err := tree.DocumentLineAtOffset(context.Background(), ref, -1) + if err != nil { + t.Fatal(err) + } + var contents []string + for _, content := range line.Contents { + contents = append(contents, content.Text) + } + if !reflect.DeepEqual(contents, []string{"Before", "link text"}) { + t.Fatalf("line contents = %q", contents) + } + if line.Document.ID() != testID("/doc") { + t.Fatalf("line document = %#v", line.Document) + } +} + +func TestDocumentLineExcludesHiddenAndOtherRows(t *testing.T) { + nodes := documentTestNodes() + content := func(index int, text string, bounds Rectangle, caret bool) { + nodes[index].Snapshot.Role = "static" + nodes[index].Geometry = Geometry{Bounds: bounds, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + nodes[index].Text = VisibleText{Known: true, Ranges: []TextRange{{ + Start: 0, End: utf8.RuneCountInString(text), Text: text, Bounds: bounds, + }}} + if caret { + nodes[index].Text.CaretKnown, nodes[index].Text.CaretOffset = true, 3 + } + } + content(3, "Visible", Rectangle{X: 0, Y: 100, Width: 50, Height: 20}, true) + content(5, "Hidden", Rectangle{X: 100, Y: 100, Width: 50, Height: 20}, false) + content(6, "Other row", Rectangle{X: 0, Y: 200, Width: 80, Height: 20}, false) + nodes[4].Geometry = Geometry{VisibilityKnown: true, Visible: false} + tree, err := NewAccessibleTree(testID("/root"), nodes) + if err != nil { + t.Fatal(err) + } + ref, err := tree.Reference(testID("/heading")) + if err != nil { + t.Fatal(err) + } + line, err := tree.DocumentLineAtOffset(context.Background(), ref, -1) + if err != nil { + t.Fatal(err) + } + if len(line.Contents) != 1 || line.Contents[0].Text != "Visible" { + t.Fatalf("line contents = %#v", line.Contents) + } + emptyNodes := documentTestNodes() + withoutCaretTree, err := NewAccessibleTree(testID("/root"), emptyNodes) + if err != nil { + t.Fatal(err) + } + withoutCaret, err := withoutCaretTree.Reference(testID("/heading")) + if err != nil { + t.Fatal(err) + } + if _, err := withoutCaretTree.DocumentLineAtOffset(context.Background(), withoutCaret, -1); !errors.Is(err, ErrNoDocumentCaret) { + t.Fatalf("missing caret error = %v", err) + } +} + +func TestDocumentLineAcceptsEndOfTextCaretOffset(t *testing.T) { + nodes := documentTestNodes() + content := "Visible" + nodes[3].Snapshot.Role = "static" + nodes[3].Geometry = Geometry{ + Bounds: Rectangle{X: 0, Y: 100, Width: 50, Height: 20}, BoundsKnown: true, + VisibilityKnown: true, Visible: true, Showing: true, + } + nodes[3].Text = VisibleText{Known: true, Ranges: []TextRange{{ + Start: 0, End: utf8.RuneCountInString(content), Text: content, + Bounds: nodes[3].Geometry.Bounds, + }}} + tree, err := NewAccessibleTree(testID("/root"), nodes) + if err != nil { + t.Fatal(err) + } + reference, err := tree.Reference(testID("/heading")) + if err != nil { + t.Fatal(err) + } + line, err := tree.DocumentLineAtOffset(context.Background(), reference, utf8.RuneCountInString(content)) + if err != nil { + t.Fatal(err) + } + if len(line.Contents) != 1 || line.Contents[0].Text != content { + t.Fatalf("line contents = %#v", line.Contents) + } +} + +func TestDocumentLifecycleRetiresReusedIdentity(t *testing.T) { + for _, kind := range []string{DocumentReloadEvent, DocumentLoadCompleteEvent, DocumentLoadStoppedEvent} { + t.Run(kind, func(t *testing.T) { + nodes := documentTestNodes() + tree, _ := NewAccessibleTree(testID("/root"), nodes) + adapter := New() + adapter.tree = tree + doc, _ := tree.Reference(testID("/doc")) + child, _ := tree.Reference(testID("/link")) + chrome, _ := tree.Reference(testID("/chrome")) + adapter.invalidateTreeEvent(kind, 0, doc.ID(), ObjectID{}) + if err := tree.Replace(testID("/root"), nodes); err != nil { + t.Fatal(err) + } + for _, ref := range []ObjectReference{doc, child} { + if _, err := tree.Resolve(ref); !errors.Is(err, ErrStaleObject) { + t.Fatalf("reused reference survived: %v", err) + } + } + if _, err := tree.Resolve(chrome); err != nil { + t.Fatalf("unrelated chrome: %v", err) + } + if adapter.TreeInvalidations() != 4 { + t.Fatalf("invalidation count: %d", adapter.TreeInvalidations()) + } + }) + } +} + +func TestDocumentCaptureIsAtomicAcrossReplacement(t *testing.T) { + tree, _ := NewAccessibleTree(testID("/root"), documentTestNodes()) + ref, _ := tree.Reference(testID("/link")) + var workers sync.WaitGroup + workers.Add(1) + go func() { + defer workers.Done() + for i := 0; i < 100; i++ { + nodes := documentTestNodes() + for j := range nodes { + nodes[j].Snapshot.Name = "replacement" + } + if err := tree.Replace(testID("/root"), nodes); err != nil { + t.Error(err) + return + } + } + }() + for i := 0; i < 100; i++ { + doc, err := tree.Document(context.Background(), ref) + if err != nil { + t.Fatal(err) + } + replaced := doc.Context.Ancestors[0].Name == "replacement" + for _, node := range doc.Nodes { + if (node.Snapshot.Name == "replacement") != replaced { + t.Fatal("mixed document captures") + } + } + } + workers.Wait() +} + +func TestDocumentIgnoresCaretAndViewportInvalidation(t *testing.T) { + for _, event := range []string{CaretEvent, BoundsChangedEvent, TextBoundsChangedEvent, ShowingStateEvent, TextInsertedEvent, VisibleStateEvent} { + t.Run(event, func(t *testing.T) { + adapter := New() + adapter.documentTree, _ = NewAccessibleTree(testID("/root"), documentTestNodes()) + adapter.tree, _ = NewAccessibleTree(testID("/root"), documentTestNodes()) + ref, _ := adapter.documentTree.Reference(testID("/heading")) + adapter.invalidateTreeEvent(event, 1, ref.ID(), ObjectID{}) + _, err := adapter.documentTree.Document(context.Background(), ref) + mustRefresh := event == TextInsertedEvent || event == VisibleStateEvent + if (err != nil) != mustRefresh { + t.Fatalf("document error = %v, refresh = %v", err, mustRefresh) + } + flatRef, _ := adapter.tree.Reference(testID("/heading")) + if _, err := adapter.tree.Document(context.Background(), flatRef); err == nil { + t.Fatal("flat review failed to invalidate") + } + }) + } +} diff --git a/internal/atspi/document_text_lines.go b/internal/atspi/document_text_lines.go new file mode 100644 index 0000000..2cae038 --- /dev/null +++ b/internal/atspi/document_text_lines.go @@ -0,0 +1,47 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "strings" + "unicode" + "unicode/utf8" +) + +// Match Python web elementLinesAreSingleWords/Chars: CSS text can expose one +// token per native LINE despite belonging to one logical line. The caller +// excludes editable and preformatted text and caches the bounded decision. +func documentLinesAreTokens(ctx context.Context, source reviewTextSource, content string) (bool, error) { + count := utf8.RuneCountInString(content) + if count < 2 || count > maxReviewLineCharacters || float64(strings.Count(content, "\ufffc"))/float64(count) > .3 { + return false, nil + } + words := strings.FieldsFunc(content, func(value rune) bool { return unicode.IsSpace(value) || value == '\ufffc' }) + singleWords, singleChars := len(words) > 1, true + for offset, attempts := 0, 0; offset < count; attempts++ { + if err := ctx.Err(); err != nil { + return false, err + } + if attempts >= maxReviewRanges { + return false, nil + } + line, err := source.line(ctx, offset) + if err != nil { + return false, err + } + if line.Start < 0 || line.Start > offset || line.End <= offset || line.End > count { + return false, nil + } + value := strings.TrimSpace(line.Text) + singleWords = singleWords && len(strings.Fields(line.Text)) == 1 + singleChars = singleChars && (value == "" || value == "\ufffc" || value == "�" || utf8.RuneCountInString(value) == 1) + if !singleWords && !singleChars { + return false, nil + } + offset = line.End + } + return singleWords || singleChars, ctx.Err() +} diff --git a/internal/atspi/document_text_lines_test.go b/internal/atspi/document_text_lines_test.go new file mode 100644 index 0000000..236fc58 --- /dev/null +++ b/internal/atspi/document_text_lines_test.go @@ -0,0 +1,46 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "errors" + "testing" +) + +func TestDocumentLinesAreTokens(t *testing.T) { + for _, test := range []struct { + name, text string + lines []TextRange + want bool + }{ + {"words", "What's on your mind?", []TextRange{{Start: 0, End: 7, Text: "What's "}, {Start: 7, End: 10, Text: "on "}, {Start: 10, End: 15, Text: "your "}, {Start: 15, End: 20, Text: "mind?"}}, true}, + {"unicode characters", "é 文", []TextRange{{Start: 0, End: 1, Text: "é"}, {Start: 1, End: 2, Text: " "}, {Start: 2, End: 3, Text: "文"}}, true}, + {"ordinary lines", "First line\nSecond line", []TextRange{{Start: 0, End: 11, Text: "First line\n"}, {Start: 11, End: 22, Text: "Second line"}}, false}, + {"one word", "autocomplete", []TextRange{{Start: 0, End: 12, Text: "autocomplete"}}, false}, + {"embedded objects", "\ufffc\ufffc\ufffc hello", nil, false}, + {"non advancing provider", "one two", []TextRange{{Start: 0, End: 0, Text: "one"}}, false}, + } { + t.Run(test.name, func(t *testing.T) { + source := fakeReviewText{lines: make(map[int]TextRange)} + for _, line := range test.lines { + source.lines[line.Start] = line + } + got, err := documentLinesAreTokens(context.Background(), source, test.text) + if err != nil || got != test.want { + t.Fatalf("repair = %v, %v; want %v", got, err, test.want) + } + }) + } +} + +func TestDocumentLinesProbeHonorsCancellation(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + source := fakeReviewText{cancel: cancel, lines: map[int]TextRange{0: {Start: 0, End: 2, Text: "a "}, 2: {Start: 2, End: 3, Text: "b"}}} + _, err := documentLinesAreTokens(ctx, source, "a b") + if !errors.Is(err, context.Canceled) { + t.Fatalf("probe error = %v", err) + } +} diff --git a/internal/atspi/document_view.go b/internal/atspi/document_view.go new file mode 100644 index 0000000..4b705b0 --- /dev/null +++ b/internal/atspi/document_view.go @@ -0,0 +1,172 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import "context" + +// Owned by AccessibleTree under its mutex. Published data is immutable and can +// outlive a replacement; ValidateDocumentRange rejects retired views. Dirty +// flags stay in treeEntry, so an unrelated invalidation need not rebuild this. +type documentData struct { + nodes []DocumentNode + indices map[ObjectID]int + ends []int + rows map[ObjectID][]ObjectReference +} + +func new_document_data(nodes []DocumentNode) *documentData { + data := &documentData{nodes: nodes, indices: make(map[ObjectID]int, len(nodes)), ends: make([]int, len(nodes))} + for index, node := range nodes { + data.indices[node.Reference.ID()] = index + data.ends[index] = index + } + for index := len(nodes) - 1; index > 0; index-- { + parent := data.indices[nodes[index].Parent] + data.ends[parent] = max(data.ends[parent], data.ends[index]) + } + return data +} + +// SameContent identifies a shared immutable view, not merely matching object +// paths. A replacement with surviving identities still has different content. +func (document DocumentSnapshot) SameContent(other DocumentSnapshot) bool { + return document.data != nil && document.data == other.data +} + +func (document DocumentSnapshot) Index(id ObjectID) (int, bool) { + if document.data != nil { + index, ok := document.data.indices[id] + return index, ok + } + for index, node := range document.Nodes { + if node.Reference.ID() == id { + return index, true + } + } + return 0, false +} + +func (document DocumentSnapshot) Node(id ObjectID) (DocumentNode, bool) { + index, ok := document.Index(id) + if !ok { + return DocumentNode{}, false + } + return document.Nodes[index], true +} + +func (document DocumentSnapshot) SubtreeEnd(index int) int { + if document.data != nil { + return document.data.ends[index] + } + end := index + for next := index + 1; next < len(document.Nodes); next++ { + parent, ok := document.Index(document.Nodes[next].Parent) + if !ok || parent < index { + break + } + end = next + } + return end +} + +func document_entry_error(entry treeEntry) error { + switch { + case entry.snapshotInvalid: + return ErrStaleSnapshot + case entry.childrenInvalid: + return ErrIncompleteTree + case entry.textInvalid: + return ErrStaleText + case entry.geometryInvalid: + return ErrStaleGeometry + } + return nil +} + +// ValidateDocumentRange checks traversed objects, including skipped/hidden +// candidates, before committing a move. Ancestor metadata always matters; +// ancestor child order matters when crossing objects. A character move within +// one live leaf therefore survives insertions elsewhere in its parent. +func (tree *AccessibleTree) ValidateDocumentRange(ctx context.Context, document DocumentSnapshot, from, to int) error { + tree.mu.RLock() + defer tree.mu.RUnlock() + return tree.validate_document_range_locked(ctx, document, from, to) +} + +// ValidateDocumentOrder also checks ancestor child order when a structural +// search or a document-boundary jump will leave its current object. +func (tree *AccessibleTree) ValidateDocumentOrder(ctx context.Context, document DocumentSnapshot, index int) error { + tree.mu.RLock() + defer tree.mu.RUnlock() + return tree.validate_document_path_locked(ctx, document, index, index, true) +} + +func (tree *AccessibleTree) validate_document_range_locked(ctx context.Context, document DocumentSnapshot, from, to int) error { + return tree.validate_document_path_locked(ctx, document, from, to, from != to) +} + +func (tree *AccessibleTree) validate_document_path_locked(ctx context.Context, document DocumentSnapshot, from, to int, requireOrder bool) error { + if err := ctx.Err(); err != nil { + return err + } + if document.data == nil || tree.documents[document.Context.TopLevel.ID()] != document.data { + return ErrStaleObject + } + if from < 0 || to < 0 || from >= len(document.Nodes) || to >= len(document.Nodes) { + return ErrStaleObject + } + for index := min(from, to); index <= max(from, to); index++ { + if err := ctx.Err(); err != nil { + return err + } + node := document.Nodes[index] + entry, err := tree.resolveLocked(node.Reference) + if err != nil { + return err + } + if err := document_entry_error(entry); err != nil { + return err + } + if err := tree.validate_document_row_locked(document, node.Reference.ID()); err != nil { + return err + } + for entry.hasParent { + entry = tree.nodes[entry.parent] + if entry.snapshotInvalid { + return ErrStaleSnapshot + } + if entry.geometryInvalid { + return ErrStaleGeometry + } + if requireOrder && entry.childrenInvalid { + return ErrIncompleteTree + } + // Hypertext ranges interleave parent-owned text with embedded + // children. An insertion can change those ranges without changing + // the accessible child list. Refresh before crossing objects, while + // allowing movement within an unchanged child to remain local. + if requireOrder && entry.textInvalid && len(entry.snapshot.TextChildren) != 0 { + return ErrStaleText + } + if err := tree.validate_document_row_locked(document, entry.snapshot.ID()); err != nil { + return err + } + } + } + return nil +} + +func (tree *AccessibleTree) validate_document_row_locked(document DocumentSnapshot, id ObjectID) error { + for _, reference := range document.data.rows[id] { + entry, err := tree.resolveLocked(reference) + if err != nil { + return err + } + if err := document_entry_error(entry); err != nil { + return err + } + } + return nil +} diff --git a/internal/atspi/document_view_test.go b/internal/atspi/document_view_test.go new file mode 100644 index 0000000..1707eef --- /dev/null +++ b/internal/atspi/document_view_test.go @@ -0,0 +1,163 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "errors" + "sync" + "testing" +) + +func TestNavigationDocumentConcurrentReplacementKeepsViewsImmutable(t *testing.T) { + tree, _ := NewAccessibleTree(testID("/root"), documentTestNodes()) + ref, _ := tree.Reference(testID("/heading")) + var workers sync.WaitGroup + workers.Add(1) + go func() { + defer workers.Done() + for range 100 { + nodes := documentTestNodes() + for index := range nodes { + nodes[index].Snapshot.Name = "Replacement" + } + if err := tree.Replace(testID("/root"), nodes); err != nil { + t.Error(err) + return + } + } + }() + defer workers.Wait() + for range 100 { + view, err := tree.NavigationDocument(context.Background(), ref) + if err != nil { + t.Fatal(err) + } + replaced := view.Context.Ancestors[0].Name == "Replacement" + for _, node := range view.Nodes { + if (node.Snapshot.Name == "Replacement") != replaced { + t.Fatal("mixed replacement data in shared view") + } + } + if err := tree.ValidateDocumentRange(context.Background(), view, 0, len(view.Nodes)-1); err != nil && !errors.Is(err, ErrStaleObject) { + t.Fatal(err) + } + } +} + +func TestNavigationDocumentSharesOnlyImmutableData(t *testing.T) { + tree, _ := NewAccessibleTree(testID("/root"), documentTestNodes()) + ref, _ := tree.Reference(testID("/heading")) + first, err := tree.NavigationDocument(context.Background(), ref) + if err != nil { + t.Fatal(err) + } + second, err := tree.NavigationDocument(context.Background(), ref) + if err != nil || !first.SameContent(second) || &first.Nodes[0] != &second.Nodes[0] { + t.Fatal("unchanged document data was rebuilt", err) + } + copy, err := tree.Document(context.Background(), ref) + if err != nil { + t.Fatal(err) + } + copy.Nodes[0].Snapshot.Name = "Changed copy" + if first.Nodes[0].Snapshot.Name == "Changed copy" { + t.Fatal("owned snapshot modified shared navigation data") + } + for index, node := range first.Nodes { + if got, ok := first.Index(node.Reference.ID()); !ok || got != index { + t.Fatalf("index for %v = %d, %v", node.Reference.ID(), got, ok) + } + if end := first.SubtreeEnd(index); end < index || end >= len(first.Nodes) { + t.Fatalf("invalid subtree end %d", end) + } + } +} + +func TestNavigationDocumentValidatesOnlyTraversedBranches(t *testing.T) { + for _, test := range []struct { + name string + invalidate func(*AccessibleTree) + want error + }{ + {"text", func(tree *AccessibleTree) { tree.InvalidateText(testID("/link")) }, ErrStaleText}, + {"semantics", func(tree *AccessibleTree) { tree.InvalidateSnapshot(testID("/link")) }, ErrStaleSnapshot}, + {"geometry", func(tree *AccessibleTree) { tree.InvalidateGeometry(testID("/inner")) }, ErrStaleGeometry}, + {"children", func(tree *AccessibleTree) { tree.MarkChildrenChanged(testID("/inner")) }, ErrIncompleteTree}, + } { + t.Run(test.name, func(t *testing.T) { + tree, _ := NewAccessibleTree(testID("/root"), documentTestNodes()) + ref, _ := tree.Reference(testID("/heading")) + view, err := tree.NavigationDocument(context.Background(), ref) + if err != nil { + t.Fatal(err) + } + test.invalidate(tree) + current, err := tree.NavigationDocument(context.Background(), ref) + if err != nil || !current.SameContent(view) { + t.Fatal("unrelated dirty branch rebuilt document", err) + } + heading, _ := view.Index(ref.ID()) + if err := tree.ValidateDocumentRange(context.Background(), view, heading, heading); err != nil { + t.Fatal("unrelated update blocked current heading", err) + } + if err := tree.ValidateDocumentRange(context.Background(), view, heading, len(view.Nodes)-1); !errors.Is(err, test.want) { + t.Fatalf("traversed stale branch: %v, want %v", err, test.want) + } + }) + } +} + +func TestNavigationDocumentRejectsRetiredViewsAndCanceledMoves(t *testing.T) { + tree, _ := NewAccessibleTree(testID("/root"), documentTestNodes()) + ref, _ := tree.Reference(testID("/heading")) + view, _ := tree.NavigationDocument(context.Background(), ref) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if err := tree.ValidateDocumentRange(ctx, view, 0, 0); !errors.Is(err, context.Canceled) { + t.Fatal(err) + } + if err := tree.Replace(testID("/root"), documentTestNodes()); err != nil { + t.Fatal(err) + } + if err := tree.ValidateDocumentRange(context.Background(), view, 0, 0); !errors.Is(err, ErrStaleObject) { + t.Fatal("replacement retained old view", err) + } + fresh, _ := tree.NavigationDocument(context.Background(), ref) + if fresh.SameContent(view) { + t.Fatal("replacement reused navigation data") + } + tree.Invalidate(testID("/link")) + if err := tree.ValidateDocumentRange(context.Background(), fresh, 0, 0); !errors.Is(err, ErrStaleObject) { + t.Fatal("removal retained old topology", err) + } +} + +func TestNavigationDocumentValidatesDerivedRowDependencies(t *testing.T) { + node := func(path, role string, children ...ObjectID) TreeNode { + n := testNode(path, path, children...) + n.Snapshot.Role = role + return n + } + nodes := []TreeNode{node("/doc", "document web", testID("/table")), node("/table", "table", testID("/first"), testID("/second")), node("/first", "table cell", testID("/text")), node("/text", "static"), node("/second", "table cell")} + for _, index := range []int{2, 4} { + nodes[index].Snapshot.TablePositionKnown = true + nodes[index].Snapshot.TableColumnIndex = index/2 - 1 + } + tree, err := NewAccessibleTree(testID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + ref, _ := tree.Reference(testID("/text")) + view, err := tree.NavigationDocument(context.Background(), ref) + if err != nil { + t.Fatal(err) + } + index, _ := view.Index(ref.ID()) + tree.InvalidateText(testID("/second")) + if err := tree.ValidateDocumentRange(context.Background(), view, index, index); !errors.Is(err, ErrStaleText) { + t.Fatal("cached full row ignored a changed sibling cell", err) + } +} diff --git a/internal/atspi/echo_focus.go b/internal/atspi/echo_focus.go new file mode 100644 index 0000000..cc27fcb --- /dev/null +++ b/internal/atspi/echo_focus.go @@ -0,0 +1,69 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +// IsEchoEditField requires positive editable metadata. Text roles alone also +// describe labels and read-only documents; terminals are not edit fields. +func IsEchoEditField(snapshot Snapshot) bool { + return snapshot.Editable && !snapshot.ReadOnly && !snapshot.Defunct && + snapshot.Role != "password text" && snapshot.Role != "terminal" +} + +type echoFocus struct { + object, origin, window ObjectID + epoch uint64 + editable bool +} + +// EditFieldFocused reads copied metadata only. The GLib owner publishes it; +// foreground epochs reject stale focus even before queued events are consumed. +func (adapter *Adapter) EditFieldFocused() bool { + focus := adapter.echoFocus.Load() + foreground := adapter.Foreground() + return !adapter.secure.Load() && focus != nil && focus.editable && + focus.epoch == foreground.Epoch && (!foreground.Client.Known || foreground.Client.Window != 0) +} + +func (adapter *Adapter) observeEchoFocus(event Event) { + if event.ForegroundMismatch || event.Foreground.Epoch != adapter.Foreground().Epoch { + return + } + current := adapter.echoFocus.Load() + if event.Type == WindowActivatedEvent && !event.Source.Focused { + if current != nil && event.Window != current.window { + adapter.echoFocus.Store(nil) + } + return + } + gain := event.Type == FocusEvent || event.Type == FocusedStateEvent && event.Detail1 != 0 || + event.Type == WindowActivatedEvent && event.Source.Focused + if !gain && (current == nil || current.object != event.Source.ID()) { + return + } + if !event.Source.ID().Valid() { + return + } + origin := NewObjectID(event.Source.BusName, event.OriginPath) + if !gain && current != nil { + origin = current.origin + } + adapter.echoFocus.Store(&echoFocus{object: event.Source.ID(), origin: origin, + window: event.Window, epoch: event.Foreground.Epoch, + editable: IsEchoEditField(event.Source) && event.Source.Focused}) +} + +// Retire before filtering focus losses or dead objects out of speech delivery. +func (adapter *Adapter) retireEchoFocus(kind string, detail int, source ObjectID) { + current := adapter.echoFocus.Load() + if current == nil { + return + } + matched := source == current.object || source == current.origin || source == current.window + if (kind == FocusedStateEvent && detail == 0 || kind == DefunctStateEvent && detail != 0 || + kind == WindowDestroyedEvent || kind == WindowDeactivatedEvent) && matched || + (kind == FocusEvent || kind == FocusedStateEvent && detail != 0) && source.BusName == current.object.BusName { + adapter.echoFocus.Store(nil) + } +} diff --git a/internal/atspi/echo_focus_native_test.go b/internal/atspi/echo_focus_native_test.go new file mode 100644 index 0000000..d4c8ac4 --- /dev/null +++ b/internal/atspi/echo_focus_native_test.go @@ -0,0 +1,72 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "testing" + "time" +) + +func TestNativeEchoEditFieldFocus(t *testing.T) { + if os.Getenv("CTHULHU_SPEECH_METADATA") != "1" { + t.Skip("requires private GTK speech fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stop, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := adapter.Stop(stop); err != nil { + t.Error(err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + for _, probe := range []struct { + key, name string + want bool + }{ + {"F9", "Mnemonic probe", false}, + {"F10", "Indentation probe", true}, + {"F9", "Mnemonic probe", false}, + {"F11", "Color attribute probe", true}, + {"F7", "Protected text probe", false}, + {"shift+F10", "Indentation probe", false}, + {"F10", "Indentation probe", true}, + } { + reference := findNamedReference(t, tree, probe.name) + snapshot, err := tree.Resolve(reference) + if err != nil { + t.Fatal(err) + } + pressTreeProbeKey(t, probe.key) + deadline := time.NewTimer(time.Second) + tick := time.NewTicker(5 * time.Millisecond) + matched := false + for !matched { + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-deadline.C: + t.Fatalf("%s: cached editable=%v want=%v", probe.key, adapter.EditFieldFocused(), probe.want) + case <-adapter.Events(): + case <-tick.C: + } + focus := adapter.echoFocus.Load() + // A false result must describe this control, not a focus-event gap. + matched = focus != nil && focus.object == snapshot.ID() && adapter.EditFieldFocused() == probe.want + } + deadline.Stop() + tick.Stop() + } +} diff --git a/internal/atspi/echo_focus_test.go b/internal/atspi/echo_focus_test.go new file mode 100644 index 0000000..acd3db2 --- /dev/null +++ b/internal/atspi/echo_focus_test.go @@ -0,0 +1,106 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import "testing" + +func TestEchoEditFieldRequiresEditableMetadata(t *testing.T) { + for _, tc := range []struct { + name string + snapshot Snapshot + want bool + }{ + {"entry", Snapshot{Role: "text", Editable: true}, true}, + {"web contenteditable", Snapshot{Role: "section", Editable: true}, true}, + {"editable combo", Snapshot{Role: "combo box", Editable: true}, true}, + {"unknown text", Snapshot{Role: "text"}, false}, + {"read only", Snapshot{Role: "text", Editable: true, ReadOnly: true}, false}, + {"password", Snapshot{Role: "password text", Editable: true}, false}, + {"terminal", Snapshot{Role: "terminal", Editable: true}, false}, + {"defunct", Snapshot{Role: "text", Editable: true, Defunct: true}, false}, + } { + t.Run(tc.name, func(t *testing.T) { + if got := IsEchoEditField(tc.snapshot); got != tc.want { + t.Fatalf("editable=%v want=%v", got, tc.want) + } + }) + } +} + +func TestEchoFocusLifetime(t *testing.T) { + adapter := New() + source := Snapshot{BusName: ":1.5", Path: "/edit", Role: "text", Editable: true, Focused: true, StatesKnown: true} + event := Event{Type: FocusedStateEvent, Detail1: 1, Source: source, Window: NewObjectID(source.BusName, "/window"), OriginPath: "/child"} + if adapter.EditFieldFocused() { + t.Fatal("unknown focus allowed") + } + gain := func() { + adapter.observeEchoFocus(event) + if !adapter.EditFieldFocused() { + t.Fatal("focused editor rejected") + } + } + gain() + // Background updates and losses do not replace the current editor. + adapter.retireEchoFocus(FocusedStateEvent, 0, NewObjectID(":1.6", "/edit")) + other := event + other.Source.Path = "/other" + other.ForegroundMismatch = true + adapter.observeEchoFocus(other) + if !adapter.EditFieldFocused() { + t.Fatal("unrelated event retired editor") + } + for _, tc := range []struct { + kind string + detail int + id ObjectID + }{ + {FocusedStateEvent, 0, source.ID()}, {FocusedStateEvent, 0, NewObjectID(source.BusName, "/child")}, + {DefunctStateEvent, 1, source.ID()}, {WindowDestroyedEvent, 0, event.Window}, {WindowDeactivatedEvent, 0, event.Window}, + {FocusedStateEvent, 1, NewObjectID(source.BusName, "/button")}, + } { + gain() + adapter.retireEchoFocus(tc.kind, tc.detail, tc.id) + if adapter.EditFieldFocused() { + t.Fatalf("stale focus after %s", tc.kind) + } + } + gain() + readonly := event + readonly.Type = "object:state-changed:read-only" + readonly.Source.ReadOnly = true + adapter.observeEchoFocus(readonly) + if adapter.EditFieldFocused() { + t.Fatal("read-only change retained echo") + } + gain() + adapter.foreground.Store(&ForegroundState{Epoch: 1}) + if adapter.EditFieldFocused() { + t.Fatal("foreground change retained echo") + } + adapter.observeEchoFocus(event) + if adapter.EditFieldFocused() { + t.Fatal("old event restored echo") + } + adapter.foreground.Store(nil) + gain() + unknownWindow := event + unknownWindow.Type = WindowActivatedEvent + unknownWindow.Window = NewObjectID(":1.6", "/window") + unknownWindow.Source = Snapshot{BusName: ":1.6", Path: "/window", Role: "frame"} + adapter.observeEchoFocus(unknownWindow) + if adapter.EditFieldFocused() { + t.Fatal("unknown window retained previous editor without X11 metadata") + } + gain() + adapter.SetSecureInputActive(true) + if adapter.EditFieldFocused() { + t.Fatal("lock retained echo") + } + adapter.SetSecureInputActive(false) + if adapter.EditFieldFocused() { + t.Fatal("unlock restored stale echo") + } +} diff --git a/internal/atspi/edit_labels_native_test.go b/internal/atspi/edit_labels_native_test.go new file mode 100644 index 0000000..0f8d627 --- /dev/null +++ b/internal/atspi/edit_labels_native_test.go @@ -0,0 +1,91 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi_test + +import ( + "context" + "os" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/presentation" +) + +// Missing LABELLED_BY capture must fail even when the toolkit leaves Name empty. +func TestNativeEditFieldLabels(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_EDIT_LABELS") != "1" { + t.Skip("requires isolated edit label fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Error(err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + fields := map[string]atspi.Snapshot{} + var walk func(atspi.ObjectReference) + walk = func(ref atspi.ObjectReference) { + snapshot, err := tree.Resolve(ref) + if err != nil { + t.Fatal(err) + } + if snapshot.Description != "" { + fields[snapshot.Description] = snapshot + } + child, ok, err := tree.FirstChild(ref) + if err != nil { + t.Fatal(err) + } + for ok { + walk(child) + child, ok, err = tree.NextSibling(child) + if err != nil { + t.Fatal(err) + } + } + } + walk(root) + for _, test := range []struct{ id, name string }{ + {"related", "Nickname"}, + {"multiple", "Account identifier"}, + {"named", "Explicit name"}, + {"unlabelled", ""}, + {"protected", "Password"}, + } { + t.Run(test.id, func(t *testing.T) { + snapshot, ok := fields[test.id] + if !ok { + t.Fatal("missing edit field") + } + if snapshot.Name != test.name { + t.Errorf("field label = %q, want %q", snapshot.Name, test.name) + } + spoken := presentation.FocusText(snapshot) + if test.name != "" && !strings.Contains(spoken, test.name) { + t.Errorf("speech %q omits label %q", spoken, test.name) + } + if test.id == "protected" && (snapshot.Text != "" || strings.Contains(spoken, "secret value")) { + t.Fatal("password contents exposed") + } + }) + } +} diff --git a/internal/atspi/firefox_native_test.go b/internal/atspi/firefox_native_test.go new file mode 100644 index 0000000..f786fc2 --- /dev/null +++ b/internal/atspi/firefox_native_test.go @@ -0,0 +1,202 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeFirefoxBaseline(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_FIREFOX") != "1" { + t.Skip("requires private Firefox session") + } + ctx, cancel := context.WithTimeout(context.Background(), 35*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stop, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := adapter.Stop(stop); err != nil { + t.Error(err) + } + }() + + window, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "Cthulhu Firefox Baseline").Output() + if err != nil || len(strings.Fields(string(window))) == 0 { + t.Fatalf("Firefox window: %s: %v", window, err) + } + if out, err := exec.CommandContext(ctx, "xdotool", "windowfocus", strings.Fields(string(window))[0]).CombinedOutput(); err != nil { + t.Fatalf("focus Firefox: %s: %v", out, err) + } + var tree *AccessibleTree + for ctx.Err() == nil { + tree, err = adapter.CaptureDesktop(ctx) + if err == nil && findNamedReference(t, tree, "Firefox baseline heading").Valid() { + break + } + time.Sleep(200 * time.Millisecond) + } + if err != nil { + t.Fatalf("capture Firefox desktop: %v", err) + } + heading := findNamedReference(t, tree, "Firefox baseline heading") + if !heading.Valid() { + t.Fatal("Firefox page heading absent from AT-SPI tree") + } + snapshot, err := tree.Resolve(heading) + if err != nil { + t.Fatal(err) + } + if snapshot.HeadingLevel != 1 { + t.Fatalf("Firefox heading semantics: role=%q level=%d", snapshot.Role, snapshot.HeadingLevel) + } + owner, err := tree.DocumentContext(heading) + if err != nil { + t.Fatalf("Firefox heading has no web document: %v", err) + } + document, err := tree.Document(ctx, heading) + if err != nil { + t.Fatalf("capture Firefox document: %v", err) + } + paragraphFound := false + for _, node := range document.Nodes { + paragraphFound = paragraphFound || node.Snapshot.Role == "paragraph" + } + if !paragraphFound { + t.Fatal("Firefox paragraph absent from document") + } + for _, name := range []string{"Firefox baseline link", "Firefox baseline entry"} { + if !findNamedReference(t, tree, name).Valid() { + t.Errorf("Firefox page object %q absent", name) + } + } + documentRoot, err := tree.Resolve(owner.Document) + if err != nil || documentRoot.Role != "document web" { + t.Fatalf("Firefox document root=%+v err=%v", documentRoot, err) + } + t.Logf("Firefox document role=%q nodes=%d heading=%q", documentRoot.Role, len(document.Nodes), snapshot.Name) + if out, err := exec.CommandContext(ctx, "xdotool", "key", "ctrl+l").CombinedOutput(); err != nil { + t.Fatalf("focus address bar: %s: %v", out, err) + } + deadline := time.NewTimer(5 * time.Second) + defer deadline.Stop() +chromeFocus: + for { + select { + case event := <-adapter.Events(): + if event.Source.ApplicationProcess != "firefox" || !event.Source.Focused || event.Source.Role != "combo box" { + continue + } + if event.Type != FocusEvent && event.Type != FocusedStateEvent { + continue + } + if _, err := adapter.CaptureDocumentContext(ctx, event.Source.ID()); err != ErrNotInDocument { + t.Fatalf("Firefox chrome %q belongs to page document: %v", event.Source.Name, err) + } + if !event.Source.Autocomplete || !event.Source.HasPopup || !event.Source.Editable { + t.Fatalf("Firefox address bar semantics: role=%q editable=%t popup=%t autocomplete=%t", event.Source.Role, event.Source.Editable, event.Source.HasPopup, event.Source.Autocomplete) + } + t.Logf("Firefox chrome focus role=%q name=%q process=%q editable=%t popup=%t autocomplete=%t", event.Source.Role, event.Source.Name, event.Source.ApplicationProcess, event.Source.Editable, event.Source.HasPopup, event.Source.Autocomplete) + break chromeFocus + case <-deadline.C: + t.Fatal("Firefox address-bar focus event missing") + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + // Return through Firefox's real keyboard order; a tree-only capture cannot + // establish whether the reader can recapture the active page after chrome. + for attempt := 0; attempt < 25; attempt++ { + if out, err := exec.CommandContext(ctx, "xdotool", "key", "Tab").CombinedOutput(); err != nil { + t.Fatalf("tab from Firefox chrome: %s: %v", out, err) + } + wait := time.NewTimer(300 * time.Millisecond) + events: + for { + select { + case event := <-adapter.Events(): + if (event.Type != FocusEvent && event.Type != FocusedStateEvent) || event.Source.ApplicationProcess != "firefox" || !event.Source.Focused { + continue + } + if event.Source.Name != "Firefox baseline link" && event.Source.Name != "Firefox baseline entry" { + continue + } + wait.Stop() + owner, err := adapter.CaptureDocumentContext(ctx, event.Source.ID()) + if err != nil || !owner.Document.Valid() { + t.Fatalf("Firefox page focus context: %v", err) + } + page, err := adapter.CaptureDocument(ctx, event.Source.ID()) + if err != nil { + t.Fatalf("Firefox focused document capture: %v", err) + } + ref := findNamedReference(t, page, "Firefox baseline heading") + if !ref.Valid() { + t.Fatal("Firefox heading missing from focused document capture") + } + for _, name := range []string{"Firefox baseline heading", "Firefox baseline link"} { + object := findNamedReference(t, page, name) + snapshot, err := page.Resolve(object) + if err != nil || snapshot.CharacterCount == 0 { + t.Fatalf("browse text metrics missing for %q: count=%d err=%v", name, snapshot.CharacterCount, err) + } + } + inline := findNamedReference(t, page, "Inline message link") + parent, ok, err := page.Parent(inline) + if err != nil || !ok { + t.Fatalf("inline parent: %v", err) + } + mixed, err := page.Resolve(parent) + if err != nil || len(mixed.TextChildren) != 1 || mixed.TextChildren[0].Offset != 13 || mixed.TextChildren[0].Child != inline.ID() { + t.Fatalf("mixed native text offsets: children=%v err=%v", mixed.TextChildren, err) + } + mixedLine, err := adapter.ReadDocumentCaret(ctx, parent, 0, DocumentCaretBrailleLine) + if err != nil || mixedLine.RawText != "Mixed before \ufffc after." { + t.Fatalf("mixed native line=%q err=%v", mixedLine.RawText, err) + } + var paragraph ObjectReference + captured, err := page.Document(ctx, ref) + if err != nil { + t.Fatal(err) + } + for _, name := range []string{"Firefox baseline heading", "Firefox baseline link"} { + item, err := page.Resolve(findNamedReference(t, page, name)) + if err != nil || item.CharacterCount != len([]rune(name)) { + t.Errorf("Firefox document text metadata for %q: characters=%d err=%v", name, item.CharacterCount, err) + } + } + for _, node := range captured.Nodes { + if node.Snapshot.Role == "paragraph" { + paragraph = node.Reference + break + } + } + if !paragraph.Valid() { + t.Fatal("Firefox paragraph missing from focused document capture") + } + line, err := adapter.ReadDocumentCaret(ctx, paragraph, 0, DocumentCaretBrailleLine) + if err != nil || strings.TrimSpace(line.Text) != "Firefox baseline paragraph." { + t.Fatalf("Firefox paragraph line=%q err=%v", line.Text, err) + } + t.Logf("Firefox page focus role=%q name=%q", event.Source.Role, event.Source.Name) + return + case <-wait.C: + break events + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + wait.Stop() + } + t.Fatal("Firefox page focus unreachable from address bar with Tab") +} diff --git a/internal/atspi/flatpak_process.go b/internal/atspi/flatpak_process.go new file mode 100644 index 0000000..e26189b --- /dev/null +++ b/internal/atspi/flatpak_process.go @@ -0,0 +1,100 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "fmt" + "io" + "os" + "strings" + "syscall" +) + +type flatpakInstance struct { + application, instance string +} + +// Flatpak gives its D-Bus proxy and application the same /.flatpak-info. +// Compare a running instance, never just an application ID: two instances of +// the same application must not acquire one another's foreground window. +func readFlatpakInstance(procRoot string, pid int) flatpakInstance { + if pid <= 0 { + return flatpakInstance{} + } + file, err := os.OpenFile(fmt.Sprintf("%s/%d/root/.flatpak-info", procRoot, pid), os.O_RDONLY|syscall.O_NONBLOCK, 0) + if err != nil { + return flatpakInstance{} + } + defer file.Close() + const limit = 64 * 1024 + stat, err := file.Stat() + if err != nil || !stat.Mode().IsRegular() || stat.Size() > limit { + return flatpakInstance{} + } + data, err := io.ReadAll(io.LimitReader(file, limit+1)) + if err != nil || len(data) > limit { + return flatpakInstance{} + } + var result flatpakInstance + var section string + for _, line := range strings.Split(string(data), "\n") { + line = strings.TrimSpace(line) + if line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") { + continue + } + if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { + section = line + continue + } + key, value, ok := strings.Cut(line, "=") + if !ok { + return flatpakInstance{} + } + key, value = strings.TrimSpace(key), strings.TrimSpace(value) + if section == "[Application]" && key == "name" { + if result.application != "" { + return flatpakInstance{} + } + result.application = value + } + if section == "[Instance]" && key == "instance-id" { + if result.instance != "" { + return flatpakInstance{} + } + result.instance = value + } + } + if result.application == "" || result.instance == "" { + return flatpakInstance{} + } + return result +} + +func sameFlatpakInstance(procRoot string, first, second int) bool { + identity := readFlatpakInstance(procRoot, first) + return identity != (flatpakInstance{}) && identity == readFlatpakInstance(procRoot, second) +} + +// Owned by the GLib thread and cleared with the foreground client. This only +// resolves process identity; fresh window state and geometry still decide +// whether an accessible can own focus. +func (adapter *Adapter) foregroundProcessID(pid int) int { + client := adapter.Foreground().Client + if client.Window == 0 || client.PID <= 0 || pid <= 0 || pid == client.PID { + return pid + } + matched, known := adapter.foregroundProcesses[pid] + if !known { + matched = sameFlatpakInstance("/proc", client.PID, pid) + if adapter.foregroundProcesses == nil || len(adapter.foregroundProcesses) >= 128 { + adapter.foregroundProcesses = make(map[int]bool) + } + adapter.foregroundProcesses[pid] = matched + } + if matched { + return client.PID + } + return pid +} diff --git a/internal/atspi/flatpak_process_test.go b/internal/atspi/flatpak_process_test.go new file mode 100644 index 0000000..1ae6c5a --- /dev/null +++ b/internal/atspi/flatpak_process_test.go @@ -0,0 +1,54 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "testing" +) + +func TestFlatpakProcessInstanceBoundaries(t *testing.T) { + root := t.TempDir() + write := func(pid int, data string) { + t.Helper() + dir := filepath.Join(root, fmt.Sprint(pid), "root") + if err := os.MkdirAll(dir, 0700); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(dir, ".flatpak-info"), []byte(data), 0600); err != nil { + t.Fatal(err) + } + } + metadata := "[Application]\nname=org.example.App\n[Instance]\ninstance-id=123\n" + write(100, metadata) + for _, test := range []struct { + name, data string + want bool + }{ + {"same instance", metadata, true}, + {"other instance of same app", strings.ReplaceAll(metadata, "123", "456"), false}, + {"other app", strings.ReplaceAll(metadata, "org.example.App", "org.example.Other"), false}, + {"app ID alone", "[Application]\nname=org.example.App\n", false}, + {"instance ID alone", "[Instance]\ninstance-id=123\n", false}, + {"wrong section", "[Application]\nname=org.example.App\ninstance-id=123\n", false}, + {"empty metadata", "", false}, + {"malformed metadata", metadata + "broken", false}, + {"duplicate identity", metadata + "instance-id=456\n", false}, + {"oversized metadata", metadata + strings.Repeat("#", 65536), false}, + } { + t.Run(test.name, func(t *testing.T) { + write(200, test.data) + if got := sameFlatpakInstance(root, 100, 200); got != test.want { + t.Fatalf("same instance = %v; want %v", got, test.want) + } + }) + } + if sameFlatpakInstance(root, 100, 300) || sameFlatpakInstance(root, 300, 400) || sameFlatpakInstance(root, 0, 0) { + t.Fatal("missing process or unknown identity matched") + } +} diff --git a/internal/atspi/foreground.go b/internal/atspi/foreground.go new file mode 100644 index 0000000..d15f807 --- /dev/null +++ b/internal/atspi/foreground.go @@ -0,0 +1,64 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "math" + "slices" + + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +// The native caller supplies a complete, fresh, bounded application window +// list, and separately checks the candidate's process, state and geometry. +func foregroundWindowReplaced(previous, candidate ObjectID, windows []ObjectID) bool { + return previous.Valid() && candidate.Valid() && previous != candidate && + previous.BusName == candidate.BusName && slices.Contains(windows, candidate) && + !slices.Contains(windows, previous) +} + +// Epoch changes with the foreground client, including departure to an empty +// workspace. Moving/resizing the same client does not reset reading ownership. +type ForegroundState struct { + Client xorg.Foreground + Epoch uint64 +} + +func foregroundWindowMatches(client xorg.Foreground, pid int, bounds Rectangle) bool { + if client.PID > 0 && pid > 0 && client.PID != pid { + return false + } + if !bounds.Valid() || client.Width <= 0 || client.Height <= 0 { + return false + } + inner := Rectangle{X: int32(client.X), Y: int32(client.Y), Width: int32(client.Width), Height: int32(client.Height)} + outer := Rectangle{X: int32(client.OuterX), Y: int32(client.OuterY), Width: int32(client.OuterWidth), Height: int32(client.OuterHeight)} + return bounds == inner || bounds == outer || + scaledWindowMatches(bounds, inner) || scaledWindowMatches(bounds, outer) +} + +// Some Chromium windows report AT-SPI extents in logical pixels while X11 +// reports physical pixels. Require the same origin and proportional dimensions +// so a smaller dialog or unrelated sibling cannot claim the foreground client. +func scaledWindowMatches(accessible, xWindow Rectangle) bool { + if !accessible.Valid() || !xWindow.Valid() || accessible.X != xWindow.X || accessible.Y != xWindow.Y { + return false + } + scaleX := float64(xWindow.Width) / float64(accessible.Width) + scaleY := float64(xWindow.Height) / float64(accessible.Height) + if scaleX < 0.5 || scaleX > 3 || scaleY < 0.5 || scaleY > 3 { + return false + } + return math.Abs(scaleX-scaleY) <= 0.01*math.Max(scaleX, scaleY) +} + +// A menu popup remains within the foreground application's AT-SPI bus even +// when its own accessible frame does not match the X11 foreground client's +// bounds. The caller must confirm an active menu window or a focused menu item. +func foregroundMenuPopupMatches(client xorg.Foreground, foregroundWindow, popupWindow ObjectID, pid int, menuContext bool) bool { + return menuContext && client.Window != 0 && foregroundWindow.Valid() && popupWindow.Valid() && + foregroundWindow != popupWindow && foregroundWindow.BusName == popupWindow.BusName && + (client.PID <= 0 || pid <= 0 || client.PID == pid) +} diff --git a/internal/atspi/foreground_native_test.go b/internal/atspi/foreground_native_test.go new file mode 100644 index 0000000..75eb8ab --- /dev/null +++ b/internal/atspi/foreground_native_test.go @@ -0,0 +1,60 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "strconv" + "testing" + "time" +) + +// The GTK provider publishes its host PID over AT-SPI, but its X11 property +// deliberately contains a different PID, as with a Flatpak PID namespace. +func TestNativeForegroundProcessIdentity(t *testing.T) { + if os.Getenv("CTHULHU_FOREGROUND_PID") != "1" { + t.Skip("requires isolated GTK/X11 process identity fixture") + } + pid, err := strconv.Atoi(os.Getenv("CTHULHU_TREE_PID")) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + if _, err := adapter.CaptureDesktop(ctx); err != nil { + t.Fatal(err) + } + if foreground := adapter.Foreground(); foreground.Client.PID != pid { + t.Fatalf("foreground PID = %d; want host provider PID %d (window property is 252)", foreground.Client.PID, pid) + } + if err := exec.CommandContext(ctx, "xdotool", "key", "F6").Run(); err != nil { + t.Fatal(err) + } + for { + select { + case event := <-adapter.Events(): + if event.Type != FocusedStateEvent || event.Detail1 == 0 || event.Source.Name != "Caret review probe" { + continue + } + wantMismatch := os.Getenv("CTHULHU_FOREGROUND_PROXY_OTHER") == "1" + if event.ForegroundMismatch != wantMismatch || event.Foreground.Client.PID != pid || !event.Window.Valid() { + t.Fatalf("foreground mismatch = %v; want %v: %+v", event.ForegroundMismatch, wantMismatch, event) + } + if os.Getenv("CTHULHU_FOREGROUND_PROXY") == "1" && event.Source.ApplicationProcess != "xdg-dbus-proxy" { + t.Fatalf("fixture did not use a separate D-Bus proxy: %q", event.Source.ApplicationProcess) + } + return + case <-ctx.Done(): + t.Fatal("foreground control focus event missing") + } + } +} diff --git a/internal/atspi/foreground_test.go b/internal/atspi/foreground_test.go new file mode 100644 index 0000000..d9344c7 --- /dev/null +++ b/internal/atspi/foreground_test.go @@ -0,0 +1,100 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package atspi + +import ( + "git.stormux.org/storm/cthulhu/internal/platform/xorg" + "testing" +) + +func TestForegroundWindowCorrelation(t *testing.T) { + client := xorg.Foreground{Known: true, Window: 45, PID: 123, X: 10, Y: 30, Width: 400, Height: 300, OuterX: 8, OuterY: 5, OuterWidth: 404, OuterHeight: 327} + for _, test := range []struct { + name string + pid int + bounds Rectangle + want bool + }{ + {"client", 123, Rectangle{10, 30, 400, 300}, true}, + {"decorated", 123, Rectangle{8, 5, 404, 327}, true}, + {"other process", 124, Rectangle{10, 30, 400, 300}, false}, + {"same process other window", 123, Rectangle{420, 30, 400, 300}, false}, + {"same process scaled window", 123, Rectangle{10, 30, 200, 150}, true}, + {"scaled window shifted", 123, Rectangle{11, 30, 200, 150}, false}, + {"scaled window wrong aspect", 123, Rectangle{10, 30, 200, 120}, false}, + {"scaled window too small", 123, Rectangle{10, 30, 100, 75}, false}, + {"other process scaled window", 124, Rectangle{10, 30, 200, 150}, false}, + {"dialog", 123, Rectangle{40, 50, 200, 100}, false}, + {"missing bounds", 123, Rectangle{}, false}, + } { + t.Run(test.name, func(t *testing.T) { + if got := foregroundWindowMatches(client, test.pid, test.bounds); got != test.want { + t.Fatalf("match = %v, want %v", got, test.want) + } + }) + } +} + +func TestForegroundWindowCorrelationSteamBigPictureScale(t *testing.T) { + client := xorg.Foreground{Known: true, Window: 83886130, PID: 111, X: 0, Y: 0, Width: 1920, Height: 1080, + OuterX: 0, OuterY: 0, OuterWidth: 1920, OuterHeight: 1080} + if !foregroundWindowMatches(client, 111, Rectangle{X: 0, Y: 0, Width: 1353, Height: 761}) { + t.Fatal("same-process logical-pixel frame did not match X11 foreground") + } +} + +func TestForegroundMenuPopupCorrelation(t *testing.T) { + client := xorg.Foreground{Known: true, Window: 45, PID: 123} + main := NewObjectID(":1.40", "/main") + popup := NewObjectID(":1.40", "/popup") + for _, test := range []struct { + name string + client xorg.Foreground + main ObjectID + popup ObjectID + pid int + menu bool + want bool + }{ + {"active menu in foreground application", client, main, popup, 123, true, true}, + {"inactive menu", client, main, popup, 123, false, false}, + {"other application", client, main, NewObjectID(":1.41", "/popup"), 123, true, false}, + {"other process", client, main, popup, 124, true, false}, + {"ordinary sibling window", client, main, popup, 123, false, false}, + {"no foreground client", xorg.Foreground{Known: true}, main, popup, 123, true, false}, + {"no owned main window", client, ObjectID{}, popup, 123, true, false}, + } { + t.Run(test.name, func(t *testing.T) { + if got := foregroundMenuPopupMatches(test.client, test.main, test.popup, test.pid, test.menu); got != test.want { + t.Fatalf("match = %v, want %v", got, test.want) + } + }) + } +} + +func TestForegroundWindowReplacement(t *testing.T) { + previous := NewObjectID(":1.40", "/gtk_frame") + candidate := NewObjectID(":1.40", "/gecko_frame") + sibling := NewObjectID(":1.40", "/other_window") + for _, test := range []struct { + name string + previous, candidate ObjectID + windows []ObjectID + want bool + }{ + {"replaced application root", previous, candidate, []ObjectID{candidate, sibling}, true}, + {"existing sibling cannot take ownership", previous, candidate, []ObjectID{previous, candidate}, false}, + {"unregistered candidate", previous, candidate, []ObjectID{sibling}, false}, + {"missing window list", previous, candidate, nil, false}, + {"other provider", previous, NewObjectID(":1.41", "/frame"), []ObjectID{NewObjectID(":1.41", "/frame")}, false}, + {"no previous owner", ObjectID{}, candidate, []ObjectID{candidate}, false}, + {"unchanged owner", candidate, candidate, []ObjectID{candidate}, false}, + } { + t.Run(test.name, func(t *testing.T) { + if got := foregroundWindowReplaced(test.previous, test.candidate, test.windows); got != test.want { + t.Fatalf("replacement = %v, want %v", got, test.want) + } + }) + } +} diff --git a/internal/atspi/geometry.go b/internal/atspi/geometry.go new file mode 100644 index 0000000..a129b10 --- /dev/null +++ b/internal/atspi/geometry.go @@ -0,0 +1,69 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import "math" + +// Rectangle uses AT-SPI screen coordinates. Negative positions are valid on +// multi-monitor desktops. Edges use int64 arithmetic to avoid native gint +// overflow. Zero-sized rectangles cannot contribute a flat-review zone. +type Rectangle struct { + X, Y, Width, Height int32 +} + +func (rect Rectangle) Valid() bool { + return rect.Width > 0 && rect.Height > 0 && rect.X != math.MinInt32 && rect.Y != math.MinInt32 +} + +// Intersection clips a screen rectangle without wrapping at native integer +// limits. A disjoint, empty, or unavailable rectangle has no intersection. +func (rect Rectangle) Intersection(other Rectangle) (Rectangle, bool) { + if !rect.Valid() || !other.Valid() { + return Rectangle{}, false + } + left := max(int64(rect.X), int64(other.X)) + top := max(int64(rect.Y), int64(other.Y)) + right := min(int64(rect.X)+int64(rect.Width), int64(other.X)+int64(other.Width)) + bottom := min(int64(rect.Y)+int64(rect.Height), int64(other.Y)+int64(other.Height)) + if right <= left || bottom <= top { + return Rectangle{}, false + } + return Rectangle{int32(left), int32(top), int32(right - left), int32(bottom - top)}, true +} + +// Geometry is owned capture-time component data, separate from focus snapshots. +// Bounds are meaningful only when visibility is known and the object is both +// visible and showing. Neither state establishes that another window does not +// obscure the object. Unsupported components retain unknown bounds. +type Geometry struct { + Bounds Rectangle + BoundsKnown bool + VisibilityKnown bool + Visible bool + Showing bool +} + +func (geometry Geometry) valid() bool { + if !geometry.VisibilityKnown && (geometry.Visible || geometry.Showing) { + return false + } + if geometry.BoundsKnown { + return geometry.VisibilityKnown && geometry.Visible && geometry.Showing && geometry.Bounds.Valid() + } + return geometry.Bounds == (Rectangle{}) +} diff --git a/internal/atspi/geometry_test.go b/internal/atspi/geometry_test.go new file mode 100644 index 0000000..9b9cf77 --- /dev/null +++ b/internal/atspi/geometry_test.go @@ -0,0 +1,136 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "errors" + "math" + "sync" + "testing" +) + +func TestRectangleIntersection(t *testing.T) { + tests := []struct { + name string + first, second, want Rectangle + ok bool + }{ + {"overlap", Rectangle{10, 20, 30, 40}, Rectangle{20, 30, 50, 60}, Rectangle{20, 30, 20, 30}, true}, + {"negative monitor", Rectangle{-100, -50, 90, 40}, Rectangle{-80, -30, 50, 50}, Rectangle{-80, -30, 50, 20}, true}, + {"touching edge", Rectangle{0, 0, 10, 10}, Rectangle{10, 0, 5, 5}, Rectangle{}, false}, + {"disjoint", Rectangle{0, 0, 10, 10}, Rectangle{20, 0, 5, 5}, Rectangle{}, false}, + {"empty", Rectangle{}, Rectangle{0, 0, 10, 10}, Rectangle{}, false}, + {"negative size", Rectangle{0, 0, -1, 10}, Rectangle{0, 0, 10, 10}, Rectangle{}, false}, + {"unavailable position", Rectangle{math.MinInt32, 0, 10, 10}, Rectangle{math.MinInt32, 0, 10, 10}, Rectangle{}, false}, + {"edge overflow", Rectangle{math.MaxInt32 - 5, 0, 10, 10}, Rectangle{math.MaxInt32 - 2, 1, 10, 10}, Rectangle{math.MaxInt32 - 2, 1, 7, 9}, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, ok := tt.first.Intersection(tt.second) + if ok != tt.ok || got != tt.want { + t.Fatalf("intersection = %v %v, want %v %v", got, ok, tt.want, tt.ok) + } + }) + } +} + +func TestTreeGeometryInvalidationPreservesHierarchy(t *testing.T) { + nodes := []TreeNode{ + testNode("/root", "Window", testID("/first"), testID("/second")), + testNode("/first", "First"), + testNode("/second", "Second", testID("/child")), + testNode("/child", "Child"), + } + geometry := Geometry{Bounds: Rectangle{-10, 20, 30, 40}, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + for i := range nodes { + nodes[i].Geometry = geometry + } + tree, err := NewAccessibleTree(testID("/root"), nodes) + if err != nil { + t.Fatal(err) + } + second, _ := tree.Reference(testID("/second")) + child, _, _ := tree.FirstChild(second) + first, _ := tree.Reference(testID("/first")) + if count := tree.InvalidateGeometry(second.ID()); count != 2 { + t.Fatalf("invalidated %d", count) + } + if count := tree.InvalidateGeometry(second.ID()); count != 0 { + t.Fatalf("repeat invalidated %d", count) + } + for _, ref := range []ObjectReference{second, child} { + if _, err := tree.Geometry(ref); !errors.Is(err, ErrStaleGeometry) { + t.Fatalf("geometry = %v", err) + } + if _, err := tree.Resolve(ref); err != nil { + t.Fatalf("geometry invalidation destroyed identity: %v", err) + } + } + if got, err := tree.Geometry(first); err != nil || got != geometry { + t.Fatalf("unrelated geometry = %v %v", got, err) + } + if got, ok, err := tree.FirstChild(second); err != nil || !ok || got != child { + t.Fatalf("child = %v %v %v", got, ok, err) + } + nodes[2].Geometry.Bounds.X = 25 + if err := tree.Replace(testID("/root"), nodes); err != nil { + t.Fatal(err) + } + if got, err := tree.Geometry(second); err != nil || got.Bounds.X != 25 { + t.Fatalf("recapture = %v %v", got, err) + } + tree.Invalidate(second.ID()) + if _, err := tree.Geometry(child); !errors.Is(err, ErrStaleObject) { + t.Fatalf("removed geometry = %v", err) + } +} + +func TestTreeRejectsMalformedGeometry(t *testing.T) { + for _, geometry := range []Geometry{ + {Showing: true}, + {Bounds: Rectangle{0, 0, 10, 10}}, + {BoundsKnown: true}, + {Bounds: Rectangle{0, 0, 10, 10}, BoundsKnown: true, VisibilityKnown: true, Visible: true}, + } { + node := testNode("/root", "Window") + node.Geometry = geometry + if _, err := NewAccessibleTree(testID("/root"), []TreeNode{node}); !errors.Is(err, ErrInvalidTree) { + t.Fatalf("accepted malformed geometry %v: %v", geometry, err) + } + } +} + +func TestTreeGeometryConcurrentInvalidation(t *testing.T) { + tree := testTree(t) + ref, _ := tree.Reference(testID("/second")) + var readers sync.WaitGroup + for range 8 { + readers.Add(1) + go func() { + defer readers.Done() + for range 100 { + if _, err := tree.Geometry(ref); err != nil && !errors.Is(err, ErrStaleGeometry) { + t.Errorf("geometry: %v", err) + return + } + } + }() + } + tree.InvalidateGeometry(ref.ID()) + readers.Wait() +} diff --git a/internal/atspi/libreoffice.go b/internal/atspi/libreoffice.go new file mode 100644 index 0000000..351a90f --- /dev/null +++ b/internal/atspi/libreoffice.go @@ -0,0 +1,65 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "strings" + "unicode/utf8" +) + +// LibreOfficeContext is bounded, copied metadata from the native owner. It +// describes Calc's cell and temporary editor objects, without native handles. +// Presentation and application policy must not query the provider themselves. +type LibreOfficeContext struct { + InSpreadsheet bool + Cell bool + CellEditor bool + EditorParent ObjectID + ContainerFocused bool + CellText string + Coordinates string + Formula string + Document ObjectID + SheetName string // provider's page-name; table objects are recreated on tab switches + Selection *LibreOfficeSelection +} + +// LibreOfficeSelection never expands a sheet. Complete small selections carry +// at most 64 positions; larger selections carry counts and boundary samples. +// Kind is cells, rows, columns, or all. Count is a lower bound when +// CountLimited is true. +type LibreOfficeSelection struct { + Kind string + Count int + CountLimited bool + Complete bool + Cells []LibreOfficeCell + // Boundary samples distinguish equal-sized large selections. They do + // not prove that every cell between the endpoints is selected. + First, Last LibreOfficeCell +} + +type LibreOfficeCell struct{ Row, Column int } + +const libreOfficeSelectionLimit = 64 + +// IsLibreOfficeProcess uses /proc identity verified by the adapter. An +// accessible name or document title must never enable application policy. +func IsLibreOfficeProcess(process string) bool { + return process == "soffice.bin" +} + +// Preserve spaces inside formula string literals and keep the beginning when +// bounding long expressions. Text context's default suffix is for caret lines. +func sanitizeLibreOfficeFormula(value string) string { + value = strings.ToValidUTF8(value, "�") + if len(value) > maxSnapshotFieldLength { + value = value[:maxSnapshotFieldLength] + for !utf8.ValidString(value) { + value = value[:len(value)-1] + } + } + return sanitizeTextContext(value) +} diff --git a/internal/atspi/libreoffice_headers.go b/internal/atspi/libreoffice_headers.go new file mode 100644 index 0000000..11ccbfc --- /dev/null +++ b/internal/atspi/libreoffice_headers.go @@ -0,0 +1,109 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "errors" + "sync" +) + +// Choices contain only identities and coordinates, never provider objects or +// cell text. They survive focus/lock/tab changes and expire on document/window +// destruction, sheet topology/name changes and shutdown. A fixed limit bounds +// missed deaths. Calc recreates its table objects on every sheet switch. +type libreOfficeHeaderKey struct { + window, document ObjectID + sheet string +} + +type libreOfficeHeaderChoice struct { + row, column int + rowSet, columnSet bool +} + +type libreOfficeHeaderStore struct { + mutex sync.Mutex + choices map[libreOfficeHeaderKey]libreOfficeHeaderChoice +} + +func libreOfficeHeaderIdentity(snapshot Snapshot, window ObjectID) (libreOfficeHeaderKey, bool) { + context := snapshot.LibreOffice + key := libreOfficeHeaderKey{window: window} + if context != nil { + key.document = context.Document + key.sheet = context.SheetName + } + valid := IsLibreOfficeProcess(snapshot.ApplicationProcess) && !snapshot.Defunct && + snapshot.Role == "table cell" && context != nil && context.InSpreadsheet && context.Cell && + snapshot.TablePositionKnown && snapshot.TableRowIndex >= 0 && snapshot.TableColumnIndex >= 0 && + key.window.Valid() && key.document.Valid() && key.sheet != "" && snapshot.TablePath != "" && + key.window.BusName == snapshot.BusName && key.document.BusName == snapshot.BusName + return key, valid +} + +// ConfigureLibreOfficeHeader is called only for the event loop's owned cell. +// It copies a choice without querying AT-SPI or waiting for the GLib thread. +// columnHeaders selects the row that supplies column headings; otherwise the +// current column supplies row headings. clear removes only that axis. +func (adapter *Adapter) ConfigureLibreOfficeHeader(snapshot Snapshot, window ObjectID, columnHeaders, clear bool) error { + key, valid := libreOfficeHeaderIdentity(snapshot, window) + if !valid || adapter.secure.Load() { + return errors.New("Not in a Calc cell.") + } + store := &adapter.libreOfficeHeaders + store.mutex.Lock() + defer store.mutex.Unlock() + choice, exists := store.choices[key] + if !exists && !clear && len(store.choices) >= 64 { + return errors.New("Header choices are full. Clear a sheet's headers first.") + } + if columnHeaders { + choice.row, choice.rowSet = snapshot.TableRowIndex, !clear + } else { + choice.column, choice.columnSet = snapshot.TableColumnIndex, !clear + } + if !choice.rowSet && !choice.columnSet { + delete(store.choices, key) + return nil + } + if store.choices == nil { + store.choices = make(map[libreOfficeHeaderKey]libreOfficeHeaderChoice) + } + store.choices[key] = choice + return nil +} + +func (store *libreOfficeHeaderStore) get(key libreOfficeHeaderKey) libreOfficeHeaderChoice { + store.mutex.Lock() + defer store.mutex.Unlock() + return store.choices[key] +} + +func (store *libreOfficeHeaderStore) forget(id ObjectID) { + store.mutex.Lock() + defer store.mutex.Unlock() + for key := range store.choices { + if id == key.window || id == key.document { + delete(store.choices, key) + } + } +} + +func (store *libreOfficeHeaderStore) hasBus(bus string) bool { + store.mutex.Lock() + defer store.mutex.Unlock() + for key := range store.choices { + if key.window.BusName == bus { + return true + } + } + return false +} + +func (store *libreOfficeHeaderStore) reset() { + store.mutex.Lock() + defer store.mutex.Unlock() + store.choices = nil +} diff --git a/internal/atspi/libreoffice_headers_native.go b/internal/atspi/libreoffice_headers_native.go new file mode 100644 index 0000000..e3017a5 --- /dev/null +++ b/internal/atspi/libreoffice_headers_native.go @@ -0,0 +1,103 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import "strings" + +// Sheet names are unique within a Calc document. Conservatively retire choices +// for this window when sheet tabs are added, removed or renamed, so a +// deleted/recreated name cannot inherit an old sheet's choice. Switching tabs +// only changes selected state and does not retire choices. +func (adapter *Adapter) retireLibreOfficeHeaders(source *C.AtspiAccessible, eventType string, origin ObjectID) { + if eventType == WindowDestroyedEvent || eventType == DefunctStateEvent { + adapter.libreOfficeHeaders.forget(origin) + } + if (eventType != AccessibleNameEvent && !strings.HasPrefix(eventType, ChildrenChangedEvent)) || + !adapter.libreOfficeHeaders.hasBus(origin.BusName) { + return + } + role := C.atspi_accessible_get_role(source, nil) + if eventType == AccessibleNameEvent && role == C.ATSPI_ROLE_PAGE_TAB || + strings.HasPrefix(eventType, ChildrenChangedEvent) && role == C.ATSPI_ROLE_PAGE_TAB_LIST { + window := C.cthulhu_window_ancestor(source) + if window != nil { + adapter.libreOfficeHeaders.forget(nativeObjectID(window)) + C.g_object_unref(C.gpointer(window)) + } + } +} + +// GLib owner only: at most two direct cell lookups, with no sheet enumeration +// or retained native references. Read fresh text on each accepted snapshot so +// edits to a heading are reflected when the user next visits a data cell. +func (adapter *Adapter) captureLibreOfficeHeaders(source *C.AtspiAccessible, snapshot *Snapshot, window ObjectID) { + key, valid := libreOfficeHeaderIdentity(*snapshot, window) + if !valid { + return + } + choice := adapter.libreOfficeHeaders.get(key) + if !choice.rowSet && !choice.columnSet { + return + } + cell := C.atspi_accessible_get_table_cell(source) + if cell == nil { + return + } + defer C.g_object_unref(C.gpointer(cell)) + accessible := C.atspi_table_cell_get_table(cell, nil) + if accessible == nil { + return + } + defer C.g_object_unref(C.gpointer(accessible)) + if nativeObjectID(accessible) != NewObjectID(snapshot.BusName, snapshot.TablePath) { + return + } + table := C.atspi_accessible_get_table_iface(accessible) + if table == nil { + return + } + defer C.g_object_unref(C.gpointer(table)) + if choice.columnSet && choice.column != snapshot.TableColumnIndex { + snapshot.TableRowHeaders = libreOfficeHeaderText(table, snapshot.TableRowIndex, choice.column) + } + if choice.rowSet && choice.row != snapshot.TableRowIndex { + snapshot.TableColumnHeaders = libreOfficeHeaderText(table, choice.row, snapshot.TableColumnIndex) + } +} + +func libreOfficeHeaderText(table *C.AtspiTable, row, column int) string { + cell := C.atspi_table_get_accessible_at(table, C.gint(row), C.gint(column), nil) + if cell == nil { + return "" + } + defer C.g_object_unref(C.gpointer(cell)) + if C.atspi_accessible_get_role(cell, nil) != C.ATSPI_ROLE_TABLE_CELL { + return "" + } + C.atspi_accessible_clear_cache_single(cell) + states := C.atspi_accessible_get_state_set(cell) + if states == nil { + return "" + } + defunct := C.atspi_state_set_contains(states, C.ATSPI_STATE_DEFUNCT) != 0 + C.g_object_unref(C.gpointer(states)) + if defunct { + return "" + } + text := C.atspi_accessible_get_text_iface(cell) + if text == nil { + return "" + } + defer C.g_object_unref(C.gpointer(text)) + length := max(0, min(int(C.atspi_text_get_character_count(text, nil)), maxSnapshotFieldLength)) + content := C.atspi_text_get_text(text, 0, C.gint(length), nil) + defer C.g_free(C.gpointer(content)) + return sanitizeSnapshotField(C.GoString(content)) +} diff --git a/internal/atspi/libreoffice_headers_test.go b/internal/atspi/libreoffice_headers_test.go new file mode 100644 index 0000000..4c4306c --- /dev/null +++ b/internal/atspi/libreoffice_headers_test.go @@ -0,0 +1,161 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "fmt" + "sync" + "testing" +) + +func headerTestSnapshot() (Snapshot, ObjectID) { + return Snapshot{BusName: ":1.42", Path: "/cell", TablePath: "/sheet", Role: "table cell", + ApplicationProcess: "soffice.bin", TablePositionKnown: true, TableRowIndex: 2, TableColumnIndex: 3, + LibreOffice: &LibreOfficeContext{Cell: true, InSpreadsheet: true, Document: NewObjectID(":1.42", "/document"), SheetName: "Example"}}, NewObjectID(":1.42", "/window") +} + +func TestLibreOfficeHeadersScopeLifetimeAndIndependentAxes(t *testing.T) { + adapter := New() + snapshot, window := headerTestSnapshot() + key, _ := libreOfficeHeaderIdentity(snapshot, window) + if err := adapter.ConfigureLibreOfficeHeader(snapshot, window, true, false); err != nil { + t.Fatal(err) + } + if err := adapter.ConfigureLibreOfficeHeader(snapshot, window, false, false); err != nil { + t.Fatal(err) + } + choice := adapter.libreOfficeHeaders.get(key) + if !choice.rowSet || choice.row != 2 || !choice.columnSet || choice.column != 3 { + t.Fatalf("choice = %+v", choice) + } + snapshot.TablePath = "/recreated-sheet-table" + recreated, _ := libreOfficeHeaderIdentity(snapshot, window) + if adapter.libreOfficeHeaders.get(recreated) != choice { + t.Fatal("sheet switch lost the document choice") + } + for _, other := range []libreOfficeHeaderKey{ + {NewObjectID(":1.42", "/other-window"), key.document, key.sheet}, + {key.window, NewObjectID(":1.42", "/other-document"), key.sheet}, + {key.window, key.document, "Other"}, + {NewObjectID(":1.43", "/window"), NewObjectID(":1.43", "/document"), "Example"}, + } { + if got := adapter.libreOfficeHeaders.get(other); got.rowSet || got.columnSet { + t.Fatalf("headers crossed identity: %+v", other) + } + } + if err := adapter.ConfigureLibreOfficeHeader(snapshot, window, true, true); err != nil { + t.Fatal(err) + } + if got := adapter.libreOfficeHeaders.get(key); got.rowSet || !got.columnSet { + t.Fatalf("clearing one axis changed the other: %+v", got) + } + // Locking retires output/native focus, but document choices survive. + adapter.SetSecureInputActive(true) + if err := adapter.ConfigureLibreOfficeHeader(snapshot, window, true, false); err == nil { + t.Fatal("configuration accepted while locked") + } + adapter.SetSecureInputActive(false) + if !adapter.libreOfficeHeaders.get(key).columnSet { + t.Fatal("lock discarded the document choice") + } + adapter.libreOfficeHeaders.forget(NewObjectID(":1.42", "/other-window")) + if !adapter.libreOfficeHeaders.get(key).columnSet { + t.Fatal("unrelated destruction discarded choice") + } + for _, id := range []ObjectID{key.document, key.window} { + if err := adapter.ConfigureLibreOfficeHeader(snapshot, window, false, false); err != nil { + t.Fatal(err) + } + adapter.libreOfficeHeaders.forget(id) + if got := adapter.libreOfficeHeaders.get(key); got.rowSet || got.columnSet { + t.Fatalf("destruction retained choice: %+v", id) + } + } + _ = adapter.ConfigureLibreOfficeHeader(snapshot, window, false, false) + adapter.libreOfficeHeaders.reset() + if len(adapter.libreOfficeHeaders.choices) != 0 { + t.Fatal("shutdown retained choices") + } + _ = adapter.ConfigureLibreOfficeHeader(snapshot, window, true, false) + adapter.libreOfficeHeaders.forget(NewObjectID(":1.42", "/other-window")) + if !adapter.libreOfficeHeaders.get(key).rowSet { + t.Fatal("unrelated tab changes retired choice") + } + adapter.libreOfficeHeaders.forget(window) + if adapter.libreOfficeHeaders.get(key).rowSet { + t.Fatal("sheet topology change retained choice") + } +} + +func TestLibreOfficeHeadersRejectInvalidContextAndBoundChoices(t *testing.T) { + for _, invalid := range []string{"process", "editor", "defunct", "position", "negative", "document", "sheet", "bus", "window"} { + snapshot, window := headerTestSnapshot() + switch invalid { + case "process": + snapshot.ApplicationProcess = "chromium" + case "editor": + snapshot.Role = "paragraph" + case "defunct": + snapshot.Defunct = true + case "position": + snapshot.TablePositionKnown = false + case "negative": + snapshot.TableColumnIndex = -1 + case "document": + snapshot.LibreOffice.Document = ObjectID{} + case "sheet": + snapshot.LibreOffice.SheetName = "" + case "bus": + window.BusName = ":1.43" + case "window": + window = ObjectID{} + } + adapter := New() + if err := adapter.ConfigureLibreOfficeHeader(snapshot, window, true, false); err == nil { + t.Fatalf("accepted invalid %s context", invalid) + } + } + adapter := New() + snapshot, window := headerTestSnapshot() + for index := 0; index < 65; index++ { + snapshot.LibreOffice.SheetName = fmt.Sprintf("Sheet%d", index) + err := adapter.ConfigureLibreOfficeHeader(snapshot, window, true, false) + if (err != nil) != (index == 64) { + t.Fatalf("bounded choice %d: %v", index, err) + } + } + snapshot.LibreOffice.SheetName = "Sheet0" + if err := adapter.ConfigureLibreOfficeHeader(snapshot, window, true, true); err != nil { + t.Fatal(err) + } + snapshot.LibreOffice.SheetName = "Sheet64" + if err := adapter.ConfigureLibreOfficeHeader(snapshot, window, true, false); err != nil { + t.Fatal("clear did not free capacity:", err) + } +} + +func TestLibreOfficeHeadersConcurrentCaptureAndCommands(t *testing.T) { + adapter := New() + snapshot, window := headerTestSnapshot() + key, _ := libreOfficeHeaderIdentity(snapshot, window) + var workers sync.WaitGroup + for index := 0; index < 3; index++ { + workers.Add(1) + go func(index int) { + defer workers.Done() + for count := 0; count < 100; count++ { + switch index { + case 0: + _ = adapter.ConfigureLibreOfficeHeader(snapshot, window, true, count%2 == 0) + case 1: + _ = adapter.libreOfficeHeaders.get(key) + case 2: + adapter.libreOfficeHeaders.forget(window) + } + } + }(index) + } + workers.Wait() +} diff --git a/internal/atspi/libreoffice_native.go b/internal/atspi/libreoffice_native.go new file mode 100644 index 0000000..482a201 --- /dev/null +++ b/internal/atspi/libreoffice_native.go @@ -0,0 +1,211 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import "unsafe" + +// libreOfficeFocusTarget keeps Office frame activation separate from document +// focus, resolves a Calc editor's direct text children, and preserves the sheet +// source for selection events. F2 focuses its temporary panel; the paragraph +// can appear later, on typing. +// The callback owns and releases the returned reference. No sheet is walked. +func (adapter *Adapter) libreOfficeFocusTarget(event *C.AtspiEvent, eventType string) *C.AtspiAccessible { + if eventType != FocusEvent && eventType != FocusedStateEvent && eventType != SelectionChangedEvent && eventType != WindowActivatedEvent || + !IsLibreOfficeProcess(adapter.applicationProcess(event.source)) { + return nil + } + if eventType == WindowActivatedEvent { + return adapter.libreOfficeFrameTarget(event.source) + } + role := C.atspi_accessible_get_role(event.source, nil) + if eventType == SelectionChangedEvent { + // Keep the sheet as the selection source. Its first selected cell + // is not necessarily the active cell (and can be far offscreen). + if role == C.ATSPI_ROLE_TABLE { + parent := C.atspi_accessible_get_parent(event.source, nil) + if parent != nil { + spreadsheet := C.atspi_accessible_get_role(parent, nil) == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET + C.g_object_unref(C.gpointer(parent)) + if spreadsheet { + return (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(event.source))) + } + } + } + return nil + } + if role == C.ATSPI_ROLE_TABLE { + parent := C.atspi_accessible_get_parent(event.source, nil) + if parent != nil { + if C.atspi_accessible_get_role(parent, nil) == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET { + // Orca clears stale table state around Calc focus transitions. + C.atspi_accessible_clear_cache_single(event.source) + } + C.g_object_unref(C.gpointer(parent)) + } + return nil + } + if role != C.ATSPI_ROLE_PANEL && role != C.ATSPI_ROLE_EXTENDED { + return nil + } + parent := C.atspi_accessible_get_parent(event.source, nil) + if parent == nil { + return nil + } + spreadsheet := C.atspi_accessible_get_role(parent, nil) == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET + C.g_object_unref(C.gpointer(parent)) + if !spreadsheet { + return nil + } + count := min(int(C.atspi_accessible_get_child_count(event.source, nil)), 4) + for index := 0; index < count; index++ { + child := C.atspi_accessible_get_child_at_index(event.source, C.gint(index), nil) + if child == nil { + continue + } + states := C.atspi_accessible_get_state_set(child) + focused := states != nil && C.atspi_state_set_contains(states, C.ATSPI_STATE_FOCUSED) != 0 && + C.atspi_state_set_contains(states, C.ATSPI_STATE_DEFUNCT) == 0 + if states != nil { + C.g_object_unref(C.gpointer(states)) + } + if focused && C.atspi_accessible_get_role(child, nil) == C.ATSPI_ROLE_PARAGRAPH { + return child + } + C.g_object_unref(C.gpointer(child)) + } + return nil +} + +// Both real activation events and X11 foreground recovery must avoid searching +// Calc's previous view while it rebuilds controls on workbook return. Own the +// frame and let the following cell/editor events establish document focus. +// Dialogs retain ordinary focused-control resolution. The caller owns the ref. +func (adapter *Adapter) libreOfficeFrameTarget(source *C.AtspiAccessible) *C.AtspiAccessible { + if !IsLibreOfficeProcess(adapter.applicationProcess(source)) || + C.atspi_accessible_get_role(source, nil) != C.ATSPI_ROLE_FRAME { + return nil + } + return (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(source))) +} + +func captureLibreOfficeContext(source *C.AtspiAccessible, snapshot *Snapshot) { + if !IsLibreOfficeProcess(snapshot.ApplicationProcess) || snapshot.Defunct { + return + } + switch snapshot.Role { + case "table", "table cell", "paragraph", "panel", "extended": + default: + return + } + context := LibreOfficeContext{} + parentRole := C.AtspiRole(C.ATSPI_ROLE_INVALID) + grandparentRole := C.AtspiRole(C.ATSPI_ROLE_INVALID) + current := (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(source))) + for depth := 0; current != nil && depth < 32; depth++ { + role := C.atspi_accessible_get_role(current, nil) + if depth == 1 { + parentRole = role + context.EditorParent = nativeObjectID(current) + } + if depth == 2 { + grandparentRole = role + } + if role == C.ATSPI_ROLE_TABLE { + states := C.atspi_accessible_get_state_set(current) + if states != nil { + context.ContainerFocused = C.atspi_state_set_contains(states, C.ATSPI_STATE_FOCUSED) != 0 + C.g_object_unref(C.gpointer(states)) + } + } + if role == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET { + context.InSpreadsheet = true + context.Document = nativeObjectID(current) + if snapshot.Role == "table cell" { + // The document/view survives sheet switches; its table does not. + // Read the provider's uncached page-name, never a localized title. + C.atspi_accessible_clear_cache_single(current) + attributes := C.atspi_accessible_get_attributes(current, nil) + if attributes != nil { + key := C.CString("page-name") + // Identity must preserve whitespace: distinct sheet names + // must not collapse onto the same key. Reject oversized names. + context.SheetName = C.GoString((*C.gchar)(C.g_hash_table_lookup(attributes, C.gconstpointer(key)))) + if len(context.SheetName) > maxSnapshotFieldLength { + context.SheetName = "" + } + C.free(unsafe.Pointer(key)) + C.g_hash_table_unref(attributes) + } + } + C.g_object_unref(C.gpointer(current)) + current = nil + break + } + if role == C.ATSPI_ROLE_FRAME || role == C.ATSPI_ROLE_DIALOG || role == C.ATSPI_ROLE_APPLICATION { + C.g_object_unref(C.gpointer(current)) + current = nil + break + } + parent := C.atspi_accessible_get_parent(current, nil) + C.g_object_unref(C.gpointer(current)) + current = parent + } + if current != nil { + C.g_object_unref(C.gpointer(current)) + } + if !context.InSpreadsheet { + return + } + context.Cell = snapshot.Role == "table cell" + context.CellEditor = (snapshot.Role == "panel" || snapshot.Role == "extended") && + parentRole == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET || + snapshot.Role == "paragraph" && (parentRole == C.ATSPI_ROLE_PANEL || parentRole == C.ATSPI_ROLE_EXTENDED) && + grandparentRole == C.ATSPI_ROLE_DOCUMENT_SPREADSHEET + if context.Cell { + context.Coordinates = snapshot.Name + // Orca requests uncached attributes: editing can replace a formula + // without replacing the accessible cell. + C.atspi_accessible_clear_cache_single(source) + attributes := C.atspi_accessible_get_attributes(source, nil) + if attributes != nil { + columnKey, rowKey := C.CString("colindextext"), C.CString("rowindextext") + column := C.GoString((*C.gchar)(C.g_hash_table_lookup(attributes, C.gconstpointer(columnKey)))) + row := C.GoString((*C.gchar)(C.g_hash_table_lookup(attributes, C.gconstpointer(rowKey)))) + C.free(unsafe.Pointer(columnKey)) + C.free(unsafe.Pointer(rowKey)) + if column != "" && row != "" { + context.Coordinates = sanitizeSnapshotField(column + row) + } + // Current providers use lowercase; Orca also accepts Formula. + for _, key := range []string{"formula", "Formula"} { + name := C.CString(key) + value := C.g_hash_table_lookup(attributes, C.gconstpointer(name)) + C.free(unsafe.Pointer(name)) + if value != nil { + context.Formula = sanitizeLibreOfficeFormula(C.GoString((*C.gchar)(value))) + break + } + } + C.g_hash_table_unref(attributes) + } + text := C.atspi_accessible_get_text_iface(source) + if text != nil { + // Calc's value is Text, while Name is the coordinate. Cell caret + // offsets can be invalid, so capture contents independently. + length := max(0, min(int(C.atspi_text_get_character_count(text, nil)), maxSnapshotFieldLength)) + content := C.atspi_text_get_text(text, 0, C.gint(length), nil) + context.CellText = sanitizeTextContext(C.GoString(content)) + C.g_free(C.gpointer(content)) + C.g_object_unref(C.gpointer(text)) + } + } + snapshot.Spreadsheet = true + snapshot.LibreOffice = &context +} diff --git a/internal/atspi/libreoffice_selection_native.go b/internal/atspi/libreoffice_selection_native.go new file mode 100644 index 0000000..14963f5 --- /dev/null +++ b/internal/atspi/libreoffice_selection_native.go @@ -0,0 +1,135 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +// Only the native owner calls this, after foreground validation. Counts use a +// fixed number of RPCs; no selected-row/column arrays or sheet walks are used. +// LibreOffice itself scans its row marks when answering selected-row counts. +func captureLibreOfficeSelection(source *C.AtspiAccessible) *LibreOfficeSelection { + selection := C.atspi_accessible_get_selection_iface(source) + table := C.atspi_accessible_get_table_iface(source) + if selection == nil || table == nil { + if selection != nil { + C.g_object_unref(C.gpointer(selection)) + } + if table != nil { + C.g_object_unref(C.gpointer(table)) + } + return nil + } + defer C.g_object_unref(C.gpointer(selection)) + defer C.g_object_unref(C.gpointer(table)) + var queryError *C.GError + count := int(C.atspi_selection_get_n_selected_children(selection, &queryError)) + if queryError != nil { + C.g_error_free(queryError) + return nil + } + if count < 0 { + return nil + } + result := &LibreOfficeSelection{Kind: "cells", Count: count, CountLimited: count == 1<<31-1} + if count == 0 { + result.Complete = true + return result + } + rows := int(C.atspi_table_get_n_rows(table, &queryError)) + if queryError != nil { + C.g_error_free(queryError) + return nil + } + columns := int(C.atspi_table_get_n_columns(table, &queryError)) + if queryError != nil { + C.g_error_free(queryError) + return nil + } + selectedRows, selectedColumns := 0, 0 + // A small selection cannot contain a whole row or column. Avoid making + // LibreOffice scan all its row marks for ordinary Shift+Arrow movement. + if count >= columns { + selectedRows = int(C.atspi_table_get_n_selected_rows(table, &queryError)) + if queryError != nil { + C.g_error_free(queryError) + return nil + } + } + if count >= rows { + selectedColumns = int(C.atspi_table_get_n_selected_columns(table, &queryError)) + if queryError != nil { + C.g_error_free(queryError) + return nil + } + } + if rows <= 0 || columns <= 0 || selectedRows < 0 || selectedColumns < 0 { + return nil + } + if selectedRows == rows || selectedColumns == columns { + return &LibreOfficeSelection{Kind: "all", Complete: true} + } + stride := 1 + // Only classify pure row/column selections. Mixed selections retain an + // honest cell count. GTK caps counts above INT_MAX, rather than wrapping. + if !result.CountLimited && selectedRows > 0 && int64(selectedRows)*int64(columns) == int64(count) { + result.Kind, result.Count, result.CountLimited = "rows", selectedRows, false + stride = columns + } else if !result.CountLimited && selectedColumns > 0 && int64(selectedColumns)*int64(rows) == int64(count) { + result.Kind, result.Count, result.CountLimited = "columns", selectedColumns, false + } + indices := make([]int, 0, libreOfficeSelectionLimit) + if result.Count > libreOfficeSelectionLimit { + indices = append(indices, 0, count-1) + } else { + for index := 0; index < result.Count; index++ { + indices = append(indices, index*stride) + } + } + for _, index := range indices { + child := C.atspi_selection_get_selected_child(selection, C.gint(index), &queryError) + if queryError != nil { + C.g_error_free(queryError) + if child != nil { + C.g_object_unref(C.gpointer(child)) + } + return nil + } + if child == nil { + return nil + } + cell := C.atspi_accessible_get_table_cell(child) + var row, column C.gint + valid := false + if cell != nil { + valid = C.atspi_table_cell_get_position(cell, &row, &column, &queryError) != 0 + C.g_object_unref(C.gpointer(cell)) + } + C.g_object_unref(C.gpointer(child)) + if queryError != nil { + C.g_error_free(queryError) + return nil + } + if !valid || row < 0 || column < 0 || int(row) >= rows || int(column) >= columns { + return nil + } + position := LibreOfficeCell{Row: int(row), Column: int(column)} + if result.Kind == "rows" { + position.Column = 0 + } + if result.Kind == "columns" { + position.Row = 0 + } + result.Cells = append(result.Cells, position) + } + result.First, result.Last = result.Cells[0], result.Cells[len(result.Cells)-1] + result.Complete = result.Count <= libreOfficeSelectionLimit + if !result.Complete { + result.Cells = nil + } + return result +} diff --git a/internal/atspi/libreoffice_test.go b/internal/atspi/libreoffice_test.go new file mode 100644 index 0000000..cb96e34 --- /dev/null +++ b/internal/atspi/libreoffice_test.go @@ -0,0 +1,23 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "strings" + "testing" + "unicode/utf8" +) + +func TestLibreOfficeFormulaPreservesLiteralSpacesAndBoundedPrefix(t *testing.T) { + formula := `="two spaces"` + if got := sanitizeLibreOfficeFormula(formula); got != formula { + t.Fatalf("formula literal changed: %q", got) + } + formula += strings.Repeat("猫", maxSnapshotFieldLength) + got := sanitizeLibreOfficeFormula(formula) + if len(got) > maxSnapshotFieldLength || !utf8.ValidString(got) || !strings.HasPrefix(formula, got) { + t.Fatalf("invalid bounded formula prefix: bytes=%d", len(got)) + } +} diff --git a/internal/atspi/lifecycle_native_test.go b/internal/atspi/lifecycle_native_test.go new file mode 100644 index 0000000..0ad5c2d --- /dev/null +++ b/internal/atspi/lifecycle_native_test.go @@ -0,0 +1,216 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "runtime" + "testing" + "time" +) + +func TestNativeSequentialAdapterLifecycle(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_LIFECYCLE") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-c", ` +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk +window = Gtk.Window(title="Adapter lifecycle probe") +box = Gtk.Box() +window.add(box) +for name in ("First", "Second"): + box.pack_start(Gtk.Button(label=name), True, True, 0) +window.show_all() +Gtk.main() +`) + fixture.Stderr = os.Stderr + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { + _ = fixture.Process.Kill() + _ = fixture.Wait() + }() + var stopped []*Adapter + first := New() + // Start a fresh adapter, then restart the original instance. Events must + // reach only the current listener even though the provider stays alive. + for cycle, adapter := range []*Adapter{first, New(), first, New()} { + if err := adapter.Start(ctx); err != nil { + t.Fatalf("cycle %d start: %v", cycle, err) + } + if cycle == 0 { + other := New() + if err := other.Start(ctx); err == nil { + t.Fatal("concurrent adapter acquired the global AT-SPI loop") + } + } + func() { + defer func() { + stopCtx, stop := context.WithTimeout(context.Background(), 3*time.Second) + defer stop() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("cycle %d stop: %v", cycle, err) + } + }() + var window ObjectReference + for !window.Valid() && ctx.Err() == nil { + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + window = findNamedReference(t, tree, "Adapter lifecycle probe") + } + if !window.Valid() { + t.Fatal("fixture window missing") + } + for _, args := range [][]string{{"search", "--sync", "--onlyvisible", "--name", "^Adapter lifecycle probe$", "windowfocus"}, {"key", "Tab"}} { + if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("xdotool: %v: %s", err, output) + } + } + for { + select { + case event := <-adapter.Events(): + if event.Type == FocusedStateEvent && event.Detail1 == 1 && + (event.Source.Name == "First" || event.Source.Name == "Second") { + return + } + case <-ctx.Done(): + t.Fatal("focus event missing after adapter restart") + } + } + }() + if adapter.callbackData != nil || adapter.callbackHandle != 0 || adapter.eventListener != nil { + t.Fatal("stopped adapter retained native callbacks") + } + for _, old := range stopped { + if old == adapter { + continue + } + select { + case event := <-old.Events(): + t.Fatalf("stopped adapter received %s", event.Type) + default: + } + } + for len(adapter.events) != 0 { + <-adapter.events + } + stopped = append(stopped, adapter) + } +} + +func TestNativeAdapterPendingCaptureShutdown(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_LIFECYCLE") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + // Initialize on the GLib owner without starting dispatch so a canceled + // request deterministically leaves its idle callback pending at shutdown. + func() { + nativeAdapterOwner.Lock() + defer nativeAdapterOwner.Unlock() + runtime.LockOSThread() + defer runtime.UnlockOSThread() + adapter := New() + if err := adapter.initialize(); err != nil { + t.Fatal(err) + } + adapter.ready.Store(true) + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Millisecond) + defer cancel() + _, err := adapter.CaptureDesktop(ctx) + if err != context.DeadlineExceeded || len(adapter.treeRequests) != 1 { + t.Fatalf("pending capture = %d, %v", len(adapter.treeRequests), err) + } + adapter.ready.Store(false) + if err := adapter.releaseNativeCallbacks(); err != nil { + t.Fatal(err) + } + if len(adapter.treeRequests) != 0 || adapter.callbackHandle != 0 { + t.Fatal("shutdown retained pending capture") + } + }() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + if err := adapter.Stop(ctx); err != nil { + t.Error(err) + } + }() + if _, err := adapter.CaptureDesktop(ctx); err != nil { + t.Fatal(err) + } +} + +func TestNativeCanceledAdapterStart(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_LIFECYCLE") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + adapter := New() + if err := adapter.Start(ctx); err != context.Canceled { + t.Fatalf("canceled start = %v", err) + } + if adapter.running.Load() || adapter.ready.Load() || adapter.callbackData != nil || adapter.eventListener != nil { + t.Fatal("canceled startup retained native resources") + } + ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + if err := adapter.Stop(ctx); err != nil { + t.Fatal(err) + } +} + +func TestNativeAdapterStopRetry(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_LIFECYCLE") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + old := New() + if err := old.Start(ctx); err != nil { + t.Fatal(err) + } + expired, expire := context.WithCancel(ctx) + expire() + // The quit request can finish after this caller times out. Retrying Stop + // must not attach another global quit callback that kills a later adapter. + _ = old.Stop(expired) + select { + case <-old.loopDone: + case <-ctx.Done(): + t.Fatal("timed-out shutdown did not finish") + } + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + if err := adapter.Stop(ctx); err != nil { + t.Error(err) + } + }() + if err := old.Stop(ctx); err != nil { + t.Fatal(err) + } + if _, err := adapter.CaptureDesktop(ctx); err != nil { + t.Fatal(err) + } +} diff --git a/internal/atspi/live_regions.go b/internal/atspi/live_regions.go new file mode 100644 index 0000000..fc584fd --- /dev/null +++ b/internal/atspi/live_regions.go @@ -0,0 +1,46 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +type deferredLiveRegion struct{ object, document ObjectID } + +// No text or native handles survive the event. Completion re-reads the owned +// active region. Secure input, shutdown and document replacement retire it. +type deferredLiveRegionStore []deferredLiveRegion + +func (store *deferredLiveRegionStore) remember(object, document ObjectID) { + if !object.Valid() || !document.Valid() { + return + } + for _, entry := range *store { + if entry.object == object { + return + } + } + if len(*store) == 32 { + *store = (*store)[1:] + } + *store = append(*store, deferredLiveRegion{object, document}) +} + +func (store *deferredLiveRegionStore) take(object ObjectID) (ObjectID, bool) { + for index, entry := range *store { + if entry.object == object { + *store = append((*store)[:index], (*store)[index+1:]...) + return entry.document, true + } + } + return ObjectID{}, false +} + +func (store *deferredLiveRegionStore) forget_document(document ObjectID) { + kept := (*store)[:0] + for _, entry := range *store { + if entry.document != document { + kept = append(kept, entry) + } + } + *store = kept +} diff --git a/internal/atspi/live_regions_native.go b/internal/atspi/live_regions_native.go new file mode 100644 index 0000000..b18c8d5 --- /dev/null +++ b/internal/atspi/live_regions_native.go @@ -0,0 +1,66 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +type nativeLiveProperties struct { + politeness string + atomic, busy bool +} + +func capture_live_properties(source *C.AtspiAccessible) nativeLiveProperties { + properties := C.cthulhu_capture_live_properties(source) + defer C.g_free(C.gpointer(properties.politeness)) + return nativeLiveProperties{sanitizeSnapshotField(C.GoString(properties.politeness)), properties.atomic != 0, properties.busy != 0} +} + +// Called after foreground filtering. A completion is transformed into a live +// insertion so it cannot acquire focus or enter document-loading policy. +func (adapter *Adapter) prepare_live_region(event *C.AtspiEvent, eventType string, origin ObjectID, properties nativeLiveProperties) (deferEvent, complete bool) { + if eventType != TextInsertedEvent && eventType != ChildrenAddedEvent && eventType != BusyStateEvent { + return false, false + } + var savedDocument ObjectID + if eventType == BusyStateEvent { + if C.cthulhu_event_detail1(event) != 0 { + return false, false + } + var found bool + savedDocument, found = adapter.deferredLiveRegions.take(origin) + if !found { + return false, false + } + } + if properties.politeness == "" || properties.politeness == "off" { + return eventType == BusyStateEvent, false + } + if eventType != BusyStateEvent && !properties.busy { + return false, false + } + if C.cthulhu_in_active_document(event.source) == 0 { + return eventType == BusyStateEvent, false + } + document := C.cthulhu_document_ancestor(event.source) + if document == nil { + return eventType == BusyStateEvent, false + } + documentID := nativeObjectID(document) + C.g_object_unref(C.gpointer(document)) + if savedDocument.Valid() && savedDocument != documentID { + return true, false + } + if properties.busy { + if owner := C.cthulhu_busy_live_container(event.source); owner != nil { + adapter.deferredLiveRegions.remember(nativeObjectID(owner), documentID) + C.g_object_unref(C.gpointer(owner)) + return true, false + } + } + return false, eventType == BusyStateEvent +} diff --git a/internal/atspi/live_regions_test.go b/internal/atspi/live_regions_test.go new file mode 100644 index 0000000..6e69184 --- /dev/null +++ b/internal/atspi/live_regions_test.go @@ -0,0 +1,39 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "fmt" + "testing" +) + +func TestDeferredLiveRegionLifetime(t *testing.T) { + var store deferredLiveRegionStore + for index := range 40 { + store.remember(testID(fmt.Sprintf("/region/%d", index)), testID("/document")) + } + if len(store) != 32 { + t.Fatalf("unbounded deferred state: %d", len(store)) + } + if _, found := store.take(testID("/region/0")); found { + t.Fatal("oldest entry not evicted") + } + store.remember(testID("/region/39"), testID("/document")) + if len(store) != 32 { + t.Fatal("duplicate added a second entry") + } + document, found := store.take(testID("/region/39")) + if !found || document != testID("/document") { + t.Fatal("lost deferred owner") + } + if _, found = store.take(testID("/region/39")); found { + t.Fatal("completed update remained deferred") + } + store.remember(testID("/other_region"), testID("/other_document")) + store.forget_document(testID("/document")) + if len(store) != 1 || store[0].document != testID("/other_document") { + t.Fatal("document retirement retained old entries or removed another document") + } +} diff --git a/internal/atspi/model.go b/internal/atspi/model.go new file mode 100644 index 0000000..17135b0 --- /dev/null +++ b/internal/atspi/model.go @@ -0,0 +1,463 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "strings" + "time" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/webscripts" +) + +const maxSnapshotFieldLength = 4096 + +type Snapshot struct { + TextAttributeRun TextAttributeRun + TextAttributeRuns []TextAttributeRun + Mnemonic string + Misspelled bool + SpeechContext []Snapshot // Bounded copied ancestor metadata, without native handles. + BrailleContext []Snapshot // Nearest ancestor first, including window/application. + Spreadsheet bool + LibreOffice *LibreOfficeContext + // BrowserTab identifies browser chrome, excluding page-authored tab widgets. + BrowserTab bool + // ExplicitName distinguishes an author-supplied link label from a name + // derived from descendants. Only the former makes a link one browse stop. + ExplicitName bool + // Autocomplete describes a single-line completion entry. Popup ownership + // comes from the native POPUP_FOR relation, not a control's name. + Autocomplete, AutocompletePopup bool + SupportsClick bool + LiveRegion bool + LivePoliteness string + LiveAtomic bool + LayoutTable bool + // ChildCount is copied only for list containers. A failed provider query + // leaves ChildCountKnown false so zero is not mistaken for an empty list. + ChildCount int + ChildCountKnown bool + + TableRowCount int + TableColumnCount int + TableName string + TablePath string + TableRowIndex int + TableColumnIndex int + TablePositionKnown bool + TableRowSpan, TableColumnSpan int + TableRowHeaders, TableColumnHeaders string + TableRowText string + GUITable bool + CharacterCount int + EmbeddedObjectCount int + // TextChildren maps embedded-object characters to native child offsets. + // Captured for hypertext containers; nil leaves ordinary leaf traversal. + TextChildren []TextChild + // Selection offsets are captured for text-bearing focused events. + SelectionStart, SelectionEnd int + SelectionText string + CompletionPrefixCharacter string + // CaretWord is captured only for caret movement, not tree traversal. + CaretWord string + // StatesKnown reports whether native capture returned a state set. + // A missing set must not be interpreted as known non-focusable content. + Visible, Showing bool + StatesKnown bool + Active bool + Focusable bool + Focused bool + HasPopup bool + HeadingLevel int + Checkable bool + Checked bool + Defunct bool + Editable bool + // EditableRoot identifies the nearest focusable writable editor or editable + // web document. Paragraph events can belong to its native focus. + EditableRoot ObjectID + Expandable bool + Expanded bool + Indeterminate bool + Invalid bool + Multiselectable bool + ReadOnly bool + Required bool + Selected bool + Sensitive bool + SensitiveKnown bool + ValueKnown bool + Visited bool + CurrentValue float64 + MaximumValue float64 + MinimumValue float64 + MinimumIncrement float64 + BusName string + Path string + Name string + Role string + RadioGroupName string + Description string + Text string + // BrailleLine preserves the captured line's spacing; Text is normalized + // for speech and cannot locate a cursor after repeated spaces. + BrailleLine string + // Absolute Unicode offsets, before speech normalization. + BrailleLineStart int + BrailleCaret int + CaretCharacter string + TextBeforeCaret string + TextCaretKnown bool + ValueText string + ApplicationName string + // ApplicationProcess is resolved from the provider PID, not page content. + ApplicationProcess string + // ApplicationPID identifies owned preferences controls during voice previews. + ApplicationPID int + // ToolkitName is captured for name-change events to select web policy + // even before document focus or an address-bar event has arrived. + ToolkitName string + XMLRoles string + HTMLTag string + ElementID string + + // PositionInSet is one-based; zero means unavailable. SetSize must be + // positive and at least PositionInSet before presentation uses it. + PositionInSet, SetSize int + + // SoundGeometry contains immutable screen geometry copied on the AT-SPI + // event-loop thread. Presentation and audio workers never retain or query + // the native accessibles from which it was derived. + SoundGeometry SoundGeometry +} + +// ControlRole includes checkable menu semantics even when a provider exposes +// the ordinary menu-item role. Checked and mixed states also establish this +// capability when the provider omits STATE_CHECKABLE. +func (snapshot Snapshot) ControlRole() string { + if snapshot.Role == "menu item" && (snapshot.Checkable || snapshot.Checked || snapshot.Indeterminate) { + return "check menu item" + } + return snapshot.Role +} + +// TextChild is a single embedded-object character in an owned text container. +// Its offset belongs to the parent; Child retains no native handle. +type TextChild struct { + Offset int + Child ObjectID +} + +// TextAttributeRun is the native attribute range at the caret, copied without +// retaining an AT-SPI object. Offsets are Unicode character offsets. +type TextAttributeRun struct { + Start, End int + Values map[string]string +} + +func captureBrailleLine(snapshot *Snapshot, text, beforeCaret string, start int) { + snapshot.BrailleLine = sanitizeTextContext(text) + // sanitizeTextContext retains a bounded suffix. Retain its source origin, + // and hide a caret which is outside that suffix rather than misrouting it. + snapshot.BrailleLineStart = start + utf8.RuneCountInString(text) - utf8.RuneCountInString(snapshot.BrailleLine) + snapshot.BrailleCaret = start + utf8.RuneCountInString(beforeCaret) +} + +type SoundGeometry struct { + Object, Reference Rectangle + ObjectKnown bool + ReferenceKnown bool +} + +// ObjectID identifies one accessible for the lifetime of its AT-SPI bus +// connection. Object paths alone are not unique because different +// applications can publish the same path. +type ObjectID struct { + BusName string + Path string +} + +func NewObjectID(busName, path string) ObjectID { + return ObjectID{ + BusName: sanitizeSnapshotField(busName), + Path: sanitizeSnapshotField(path), + } +} + +func (id ObjectID) Valid() bool { + return id.BusName != "" && id.Path != "" && + validBusName(id.BusName) && validObjectPath(id.Path) && + id == NewObjectID(id.BusName, id.Path) +} + +func validBusName(name string) bool { + if len(name) > 255 { + return false + } + unique := strings.HasPrefix(name, ":") + if unique { + name = strings.TrimPrefix(name, ":") + } + parts := strings.Split(name, ".") + if len(parts) < 2 { + return false + } + for _, part := range parts { + if part == "" { + return false + } + for index, character := range []byte(part) { + letter := character >= 'A' && character <= 'Z' || character >= 'a' && character <= 'z' + digit := character >= '0' && character <= '9' + if !letter && !digit && character != '_' && character != '-' { + return false + } + if index == 0 && !unique && digit { + return false + } + } + } + return true +} + +func validObjectPath(path string) bool { + if path == "/" { + return true + } + if !strings.HasPrefix(path, "/") || strings.HasSuffix(path, "/") { + return false + } + for _, part := range strings.Split(path[1:], "/") { + if part == "" { + return false + } + for _, character := range []byte(part) { + letter := character >= 'A' && character <= 'Z' || character >= 'a' && character <= 'z' + digit := character >= '0' && character <= '9' + if !letter && !digit && character != '_' { + return false + } + } + } + return true +} + +func (snapshot Snapshot) ID() ObjectID { + return ObjectID{BusName: snapshot.BusName, Path: snapshot.Path} +} + +type Event struct { + // WebNotification is selected on the native owner before background-event + // filtering. It contains copied content and no retained native references. + WebNotification *webscripts.Notification + Foreground ForegroundState + ForegroundMismatch bool + // ForegroundCheck contains numeric, text-free diagnostics for rejected + // window activations. Other events leave it empty. + ForegroundCheck ForegroundCheck + // PopupFor is the autocomplete entry named by the popup's AT-SPI relation. + PopupFor ObjectID + + // FocusOutsideDocument is a freshly verified chrome focus at load + // completion. A page loading behind it must not acquire browse keys. + FocusOutsideDocument ObjectID + // DocumentFragment is the URL fragment of a completed web document load. + DocumentFragment string + // Window identifies the nearest dialog/window/frame which owns Source. + // It is captured from the original event source before activation may be + // redirected to a focused descendant. + Window ObjectID + // WindowRecovered reports an owned frame restored after a browser tab + // temporarily detached its document's AT-SPI parent chain. + WindowRecovered bool + // WindowTitle is the top-level AT-SPI name captured on activation, even + // when Source is the focused descendant. + WindowTitle string + // WindowDescription is the top-level accessible description on activation. + WindowDescription string + // WindowMessage is a simple frame prompt recovered when its first button + // takes focus after activation arrived before the label was available. + WindowMessage string + NavigationEcho bool + SnapshotDuration time.Duration + Type string + // NativeType retains the original AT-SPI type when an event is normalized. + // Presentation policies use the canonical Type. + NativeType string + Source Snapshot + OriginPath string + Payload string + Detail1 int + // TextChangeLength and TextChangeEndsLine describe the original payload, + // before speech normalization collapses whitespace and limits its length. + TextChangeLength int + TextChangeEndsLine bool +} + +type ForegroundCheck struct { + Reason string + AccessiblePID int + Active bool + Showing bool + Iconified bool + Bounds Rectangle +} + +func NewSnapshot(path, name, role, description, text string) Snapshot { + return NewSnapshotWithCaretCharacter(path, name, role, description, text, "") +} + +func NewSnapshotWithCaretCharacter(path, name, role, description, text, caretCharacter string) Snapshot { + return Snapshot{ + Path: sanitizeSnapshotField(path), + Name: sanitizeSnapshotField(name), + Role: sanitizeSnapshotField(role), + Description: sanitizeSnapshotField(description), + Text: sanitizeSnapshotField(text), + CaretCharacter: sanitizeCaretCharacter(caretCharacter), + } +} + +func NewEvent(eventType string, source Snapshot) Event { + eventType = sanitizeSnapshotField(eventType) + // A checked-state transition proves checkability even when the provider + // omits STATE_CHECKABLE and the new checked value is false. + if eventType == "object:state-changed:checked" && source.Role == "menu item" { + source.Checkable = true + } + event := Event{Type: canonicalTextChangeEventType(eventType), Source: source, OriginPath: source.Path} + if event.Type != eventType { + event.NativeType = eventType + } + return event +} + +// AT-SPI appends an origin to some text mutations (for example, :system). +// The reader handles those mutations by kind; leaving the suffix on Type +// makes them fall through as ordinary object presentation events. +func canonicalTextChangeEventType(eventType string) string { + for _, kind := range []string{TextInsertedEvent, TextDeletedEvent} { + if eventType == kind || strings.HasPrefix(eventType, kind+":") { + return kind + } + } + return eventType +} + +func isBrowserChromeTab(snapshot Snapshot, inDocument bool) bool { + if snapshot.Role != "page tab" || inDocument { + return false + } + switch strings.ToLower(snapshot.ToolkitName) { + case "chromium", "gecko", "webkit", "webkitgtk": + return true + } + return false +} + +// Firefox exposes its address bar as an editable popup combo box without the +// supports-autocompletion state used by Chromium. Keep the fallback in chrome: +// page controls with the same role still use their own document behavior. +func isFirefoxChromeAutocomplete(snapshot Snapshot, inDocument bool) bool { + return !inDocument && strings.EqualFold(snapshot.ApplicationProcess, "firefox") && + snapshot.Role == "combo box" && snapshot.Editable && !snapshot.ReadOnly && snapshot.HasPopup +} + +func NewManagedDescendantEvent(eventType, originPath string, source Snapshot) Event { + event := NewEvent(eventType, source) + event.OriginPath = sanitizeSnapshotField(originPath) + return event +} + +func NewEventWithPayload(eventType string, source Snapshot, payload string) Event { + event := NewEvent(eventType, source) + event.Payload = sanitizeTextPayload(payload) + if event.Type == TextInsertedEvent || event.Type == TextDeletedEvent { + event.TextChangeLength = utf8.RuneCountInString(payload) + event.TextChangeEndsLine = strings.HasSuffix(payload, "\n") + } + return event +} + +func sanitizeTextPayload(value string) string { + // Preserve single-character delimiters so typing-echo policy can + // distinguish space, tab, and line boundaries. Other snapshot fields + // continue to trim surrounding whitespace. + switch value { + case " ", "\t", "\n": + return value + case "\r", "\r\n": + return "\n" + } + return sanitizeSnapshotField(value) +} + +func sanitizeTextContext(value string) string { + value = strings.ToValidUTF8(value, "�") + value = strings.Map(func(character rune) rune { + if character == '\r' { + return '\n' + } + if character != '\n' && character != '\t' && unicode.IsControl(character) { + return '�' + } + return character + }, value) + if len(value) > maxSnapshotFieldLength { + value = value[len(value)-maxSnapshotFieldLength:] + for !utf8.ValidString(value) { + value = value[1:] + } + } + return value +} + +func sanitizeSnapshotField(value string) string { + value = strings.ToValidUTF8(value, "�") + value = strings.Map(func(character rune) rune { + if character == '\n' || character == '\r' || character == '\t' { + return ' ' + } + return character + }, value) + value = strings.Join(strings.Fields(value), " ") + value = strings.TrimSpace(value) + if len(value) > maxSnapshotFieldLength { + value = value[:maxSnapshotFieldLength] + for !utf8.ValidString(value) { + value = value[:len(value)-1] + } + } + return value +} + +func sanitizeCaretCharacter(value string) string { + value = strings.ToValidUTF8(value, "�") + characters := []rune(value) + if len(characters) == 0 { + return "" + } + switch characters[0] { + case '\n', '\r': + return "blank" + default: + return string(characters[0]) + } +} diff --git a/internal/atspi/model_test.go b/internal/atspi/model_test.go new file mode 100644 index 0000000..e1cbdd3 --- /dev/null +++ b/internal/atspi/model_test.go @@ -0,0 +1,243 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "strings" + "testing" +) + +func TestShouldSpeakEvent(t *testing.T) { + tests := []struct { + name string + eventType string + detail1 int + want bool + }{ + {name: "focus event", eventType: FocusEvent, detail1: 0, want: true}, + {name: "focused state", eventType: FocusedStateEvent, detail1: 1, want: true}, + {name: "unfocused state", eventType: FocusedStateEvent, detail1: 0, want: false}, + {name: "window activation", eventType: WindowActivatedEvent, detail1: 0, want: true}, + {name: "value changed", eventType: ValueChangedEvent, detail1: 0, want: true}, + {name: "other state", eventType: "object:state-changed:checked", detail1: 1, want: true}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := shouldSpeakEvent(test.eventType, test.detail1); got != test.want { + t.Fatalf("shouldSpeakEvent(%q, %d) = %v, want %v", test.eventType, test.detail1, got, test.want) + } + }) + } +} + +func TestTextChangeOriginIsCanonicalized(t *testing.T) { + for _, test := range []struct{ incoming, want string }{ + {TextInsertedEvent + ":system", TextInsertedEvent}, + {TextDeletedEvent + ":system", TextDeletedEvent}, + {TextInsertedEvent, TextInsertedEvent}, + {TextDeletedEvent, TextDeletedEvent}, + {"object:text-caret-moved", "object:text-caret-moved"}, + {"object:text-changed:insertion", "object:text-changed:insertion"}, + } { + if got := canonicalTextChangeEventType(test.incoming); got != test.want { + t.Errorf("canonicalTextChangeEventType(%q) = %q, want %q", test.incoming, got, test.want) + } + if got := NewEvent(test.incoming, Snapshot{}).Type; got != test.want { + t.Errorf("NewEvent(%q).Type = %q, want %q", test.incoming, got, test.want) + } + if test.incoming != test.want && NewEvent(test.incoming, Snapshot{}).NativeType != test.incoming { + t.Errorf("NewEvent(%q) lost its native type", test.incoming) + } + } +} + +func TestFirefoxChromeAutocompleteBoundary(t *testing.T) { + address := Snapshot{ApplicationProcess: "firefox", Role: "combo box", Editable: true, HasPopup: true} + if !isFirefoxChromeAutocomplete(address, false) { + t.Fatal("Firefox chrome address bar was not recognized") + } + for _, test := range []struct { + name string + snapshot Snapshot + inDocument bool + }{ + {"page form", address, true}, + {"Thunderbird", Snapshot{ApplicationProcess: "thunderbird", Role: "combo box", Editable: true, HasPopup: true}, false}, + {"Chromium", Snapshot{ApplicationProcess: "chromium", Role: "combo box", Editable: true, HasPopup: true}, false}, + {"read only", Snapshot{ApplicationProcess: "firefox", Role: "combo box", ReadOnly: true, Editable: true, HasPopup: true}, false}, + {"no popup", Snapshot{ApplicationProcess: "firefox", Role: "combo box", Editable: true}, false}, + } { + if isFirefoxChromeAutocomplete(test.snapshot, test.inDocument) { + t.Errorf("%s was classified as Firefox chrome autocomplete", test.name) + } + } +} + +func TestAdapterRegistersWindowLifecycle(t *testing.T) { + for _, wanted := range []string{WindowActivatedEvent, WindowDeactivatedEvent, WindowDestroyedEvent} { + found := false + for _, eventType := range eventTypes { + if eventType == wanted { + found = true + break + } + } + if !found { + t.Fatalf("window lifecycle event %q is not registered", wanted) + } + } +} + +func TestNewSnapshotSanitizesFields(t *testing.T) { + snapshot := NewSnapshot("/org/a11y/atspi/accessible/1", " Generic\r\nname ", "text frame", "Invalid: \xff", "Current\r\nline ") + if snapshot.Path != "/org/a11y/atspi/accessible/1" { + t.Fatalf("path = %q", snapshot.Path) + } + if snapshot.Name != "Generic name" { + t.Fatalf("name = %q, want %q", snapshot.Name, "Generic name") + } + if snapshot.Description != "Invalid: �" { + t.Fatalf("description = %q, want %q", snapshot.Description, "Invalid: �") + } +} + +func TestObjectIDIncludesBusNameAndPath(t *testing.T) { + snapshot := NewSnapshot("/org/a11y/atspi/accessible/1", "Example", "push button", "", "") + snapshot.BusName = ":1.42" + if got := snapshot.ID(); got != (ObjectID{BusName: ":1.42", Path: "/org/a11y/atspi/accessible/1"}) { + t.Fatalf("object ID = %#v", got) + } + if NewObjectID(" :1.42\n", " /org/a11y/atspi/accessible/1 ") != snapshot.ID() { + t.Fatal("new object ID was not sanitized") + } + if !(ObjectID{BusName: "org.a11y.atspi.Registry", Path: "/org/a11y/atspi/accessible/root"}).Valid() { + t.Fatal("well-known registry identity is invalid") + } + for _, invalid := range []ObjectID{ + {BusName: "missing-dot", Path: "/object"}, + {BusName: "7org.example", Path: "/object"}, + {BusName: "org.example", Path: "relative"}, + {BusName: "org.example", Path: "/invalid path"}, + {BusName: "org.example", Path: "/double//separator"}, + } { + if invalid.Valid() { + t.Fatalf("invalid identity accepted: %#v", invalid) + } + } +} + +func TestNewSnapshotLimitsFieldLength(t *testing.T) { + for _, character := range []string{"é", "€", "😀"} { + t.Run(character, func(t *testing.T) { + snapshot := NewSnapshot("", strings.Repeat(character, 5000), "", "", "") + if len(snapshot.Name) > maxSnapshotFieldLength { + t.Fatalf("name length = %d, want <= %d", len(snapshot.Name), maxSnapshotFieldLength) + } + if !strings.HasSuffix(snapshot.Name, character) { + t.Fatal("field truncation split a UTF-8 rune") + } + }) + } +} + +func TestNewSnapshotWithCaretCharacter(t *testing.T) { + snapshot := NewSnapshotWithCaretCharacter( + "/accessible/terminal", "", "terminal", "", "prompt ls", "l", + ) + if snapshot.CaretCharacter != "l" { + t.Fatalf("caret character = %q, want %q", snapshot.CaretCharacter, "l") + } +} + +func TestNewSnapshotPreservesCaretSpace(t *testing.T) { + snapshot := NewSnapshotWithCaretCharacter("", "", "", "", "", " space ") + if snapshot.CaretCharacter != " " { + t.Fatalf("caret character = %q, want %q", snapshot.CaretCharacter, " ") + } +} + +func TestNewEventWithPayloadSanitizesPayload(t *testing.T) { + event := NewEventWithPayload(TextInsertedEvent, NewSnapshot("/accessible/terminal", "", "terminal", "", ""), "l\r\n") + if event.Type != TextInsertedEvent { + t.Fatalf("type = %q, want %q", event.Type, TextInsertedEvent) + } + if event.Payload != "l" { + t.Fatalf("payload = %q, want %q", event.Payload, "l") + } +} + +func TestTextChangeRetainsOriginalRangeMetadata(t *testing.T) { + source := NewSnapshot("/accessible/terminal", "", "terminal", "", "") + for _, eventType := range []string{TextInsertedEvent, TextDeletedEvent, TextDeletedEvent + ":system"} { + event := NewEventWithPayload(eventType, source, "猫 command\r\n") + if event.Payload != "猫 command" || event.TextChangeLength != 12 || !event.TextChangeEndsLine { + t.Fatalf("text change = %#v", event) + } + } +} + +func TestNewEventWithPayloadPreservesInsertedSpace(t *testing.T) { + event := NewEventWithPayload(TextInsertedEvent, NewSnapshot("/accessible/editor", "", "text", "", ""), " ") + if event.Payload != " " { + t.Fatalf("payload = %q, want one space", event.Payload) + } +} + +func TestNewEventWithPayloadPreservesTextDelimiters(t *testing.T) { + snapshot := NewSnapshot("/accessible/editor", "", "text", "", "") + for input, want := range map[string]string{"\t": "\t", "\n": "\n", "\r": "\n", "\r\n": "\n"} { + event := NewEventWithPayload(TextInsertedEvent, snapshot, input) + if event.Payload != want { + t.Fatalf("payload for %q = %q, want %q", input, event.Payload, want) + } + } +} + +func TestSanitizeTextContextPreservesBoundariesAndLimitsLength(t *testing.T) { + context := sanitizeTextContext("First. Second. \r\n") + if context != "First. Second. \n\n" { + t.Fatalf("context = %q", context) + } + context = sanitizeTextContext(strings.Repeat("é", maxSnapshotFieldLength)) + if len(context) > maxSnapshotFieldLength || !strings.HasPrefix(context, "é") { + t.Fatalf("bounded context has %d bytes and invalid rune boundary", len(context)) + } +} + +func TestNewManagedDescendantEventPreservesOrigin(t *testing.T) { + source := NewSnapshot("/accessible/result", "Result", "table cell", "", "") + event := NewManagedDescendantEvent(SelectionChangedEvent, " /accessible/list\n", source) + if event.Source.Path != "/accessible/result" { + t.Fatalf("source path = %q", event.Source.Path) + } + if event.OriginPath != "/accessible/list" { + t.Fatalf("origin path = %q", event.OriginPath) + } +} +func TestBrowserChromeTabExcludesDocumentWidgets(t *testing.T) { + for _, toolkit := range []string{"Chromium", "Gecko", "WebKitGTK"} { + tab := Snapshot{Role: "page tab", ToolkitName: toolkit} + if !isBrowserChromeTab(tab, false) || isBrowserChromeTab(tab, true) { + t.Fatalf("chrome/document classification for %s", toolkit) + } + } + if isBrowserChromeTab(Snapshot{Role: "page tab", ToolkitName: "gtk"}, false) || + isBrowserChromeTab(Snapshot{Role: "button", ToolkitName: "Chromium"}, false) { + t.Fatal("ordinary application control classified as browser tab") + } +} diff --git a/internal/atspi/mouse_review_native.go b/internal/atspi/mouse_review_native.go new file mode 100644 index 0000000..0a22ad6 --- /dev/null +++ b/internal/atspi/mouse_review_native.go @@ -0,0 +1,238 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "strings" +) + +func (adapter *Adapter) clearMouseApplication() { + if adapter.mouseApplication != nil { + C.g_object_unref(C.gpointer(adapter.mouseApplication)) + } + adapter.mouseApplication = nil + adapter.mouseApplicationPID = 0 +} + +func (adapter *Adapter) mouseApplicationForPID(ctx context.Context, pid int) *C.AtspiAccessible { + if pid <= 0 || ctx.Err() != nil { + return nil + } + if adapter.mouseApplicationPID == pid && adapter.mouseApplication != nil { + return adapter.mouseApplication + } + adapter.clearMouseApplication() + desktop := C.atspi_get_desktop(0) + if desktop == nil { + return nil + } + defer C.g_object_unref(C.gpointer(desktop)) + count := min(int(C.atspi_accessible_get_child_count(desktop, nil)), 128) + for i := 0; i < count && ctx.Err() == nil; i++ { + app := C.atspi_accessible_get_child_at_index(desktop, C.gint(i), nil) + if app == nil { + continue + } + if int(C.atspi_accessible_get_process_id(app, nil)) == pid { + adapter.mouseApplication, adapter.mouseApplicationPID = app, pid + return app + } + C.g_object_unref(C.gpointer(app)) + } + return nil +} + +func nativeContainsPoint(source *C.AtspiAccessible, x, y int) bool { + component := C.atspi_accessible_get_component_iface(source) + if component == nil { + return false + } + defer C.g_object_unref(C.gpointer(component)) + var nativeErr *C.GError + inside := C.atspi_component_contains(component, C.gint(x), C.gint(y), C.ATSPI_COORD_TYPE_SCREEN, &nativeErr) != 0 + if nativeErr != nil { + C.g_error_free(nativeErr) + return false + } + return inside +} + +func nativePointArea(source *C.AtspiAccessible) int64 { + component := C.atspi_accessible_get_component_iface(source) + if component == nil { + return 1 << 62 + } + defer C.g_object_unref(C.gpointer(component)) + var nativeErr *C.GError + rect := C.atspi_component_get_extents(component, C.ATSPI_COORD_TYPE_SCREEN, &nativeErr) + if nativeErr != nil { + C.g_error_free(nativeErr) + } + if rect == nil { + return 1 << 62 + } + defer C.g_free(C.gpointer(rect)) + if rect.width <= 0 || rect.height <= 0 { + return 1 << 62 + } + return int64(rect.width) * int64(rect.height) +} + +func nativeAccessibleAtPoint(source *C.AtspiAccessible, x, y int) *C.AtspiAccessible { + component := C.atspi_accessible_get_component_iface(source) + if component == nil { + return nil + } + defer C.g_object_unref(C.gpointer(component)) + var nativeErr *C.GError + child := C.atspi_component_get_accessible_at_point(component, C.gint(x), C.gint(y), C.ATSPI_COORD_TYPE_SCREEN, &nativeErr) + if nativeErr != nil { + C.g_error_free(nativeErr) + } + return child +} + +func nativePointText(ctx context.Context, source, window *C.AtspiAccessible, x, y int) (word, line string, lineStart, nativeOffset int) { + if C.atspi_accessible_get_role(source, nil) == C.ATSPI_ROLE_PASSWORD_TEXT { + return "", "", -1, -1 + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return "", "", -1, -1 + } + defer C.g_object_unref(C.gpointer(text)) + var nativeErr *C.GError + offset := C.atspi_text_get_offset_at_point(text, C.gint(x), C.gint(y), C.ATSPI_COORD_TYPE_SCREEN, &nativeErr) + if nativeErr != nil { + C.g_error_free(nativeErr) + nativeErr = nil + } + if offset < 0 { + component := C.atspi_accessible_get_component_iface(window) + if component != nil { + rect := C.atspi_component_get_extents(component, C.ATSPI_COORD_TYPE_SCREEN, &nativeErr) + if nativeErr != nil { + C.g_error_free(nativeErr) + nativeErr = nil + } + if rect != nil { + offset = C.atspi_text_get_offset_at_point(text, C.gint(x)-rect.x, C.gint(y)-rect.y, C.ATSPI_COORD_TYPE_WINDOW, &nativeErr) + C.g_free(C.gpointer(rect)) + if nativeErr != nil { + C.g_error_free(nativeErr) + nativeErr = nil + } + } + C.g_object_unref(C.gpointer(component)) + } + } + if offset < 0 { + // GTK text entries can report -1 at points inside displayed glyphs. + // Inspect a bounded number of character rectangles as a fallback. + count := min(int(C.atspi_text_get_character_count(text, nil)), 128) + for i := 0; i < count && ctx.Err() == nil; i++ { + rect := C.atspi_text_get_character_extents(text, C.gint(i), C.ATSPI_COORD_TYPE_SCREEN, &nativeErr) + if nativeErr != nil { + C.g_error_free(nativeErr) + nativeErr = nil + } + if rect == nil { + continue + } + inside := C.gint(x) >= rect.x && C.gint(x) < rect.x+rect.width && + C.gint(y) >= rect.y && C.gint(y) < rect.y+rect.height + C.g_free(C.gpointer(rect)) + if inside { + offset = C.gint(i) + break + } + } + } + if offset < 0 { + return "", "", -1, -1 + } + read := func(granularity C.AtspiTextGranularity) (string, int) { + var err *C.GError + value := C.cthulhu_text_get_string_at_offset(text, offset, granularity, &err) + if err != nil { + C.g_error_free(err) + } + if value == nil { + return "", -1 + } + defer C.g_free(C.gpointer(value)) + defer C.g_free(C.gpointer(value.content)) + return sanitizeSnapshotField(C.GoString(value.content)), int(value.start_offset) + } + word, _ = read(C.ATSPI_TEXT_GRANULARITY_WORD) + line, lineStart = read(C.ATSPI_TEXT_GRANULARITY_LINE) + return strings.TrimSpace(word), strings.TrimSpace(line), lineStart, int(offset) +} + +// nativeReviewAtPoint runs on the GLib owner. It retains only the current +// application; all window and descendant references are released per query. +func (adapter *Adapter) nativeReviewAtPoint(ctx context.Context, x, y, pid int) (PointReview, error) { + var result PointReview + app := adapter.mouseApplicationForPID(ctx, pid) + if app == nil || ctx.Err() != nil { + return result, ctx.Err() + } + var window *C.AtspiAccessible + bestArea := int64(1 << 62) + count := min(int(C.atspi_accessible_get_child_count(app, nil)), 64) + for i := 0; i < count && ctx.Err() == nil; i++ { + candidate := C.atspi_accessible_get_child_at_index(app, C.gint(i), nil) + if candidate == nil { + continue + } + if nativeContainsPoint(candidate, x, y) { + area := nativePointArea(candidate) + if window == nil || area <= bestArea { + if window != nil { + C.g_object_unref(C.gpointer(window)) + } + window, bestArea = candidate, area + continue + } + } + C.g_object_unref(C.gpointer(candidate)) + } + if window == nil || ctx.Err() != nil { + if window != nil { + C.g_object_unref(C.gpointer(window)) + } + return result, ctx.Err() + } + defer C.g_object_unref(C.gpointer(window)) + result.Window = nativeObjectID(window) + current := (*C.AtspiAccessible)(C.g_object_ref(C.gpointer(window))) + defer func() { C.g_object_unref(C.gpointer(current)) }() + for depth := 0; depth < 24 && ctx.Err() == nil; depth++ { + child := nativeAccessibleAtPoint(current, x, y) + if child == nil { + break + } + if nativeObjectID(child) == nativeObjectID(current) || !nativeContainsPoint(child, x, y) { + C.g_object_unref(C.gpointer(child)) + break + } + C.g_object_unref(C.gpointer(current)) + current = child + } + if ctx.Err() != nil { + return PointReview{}, ctx.Err() + } + result.Snapshot = snapshotFromNativeWithOptions(current, false, false, false, false, true) + if result.Snapshot.Defunct || result.Snapshot.Role == "password text" { + return result, nil + } + result.Word, result.Line, result.LineStart, result.Offset = nativePointText(ctx, current, window, x, y) + return result, nil +} diff --git a/internal/atspi/mouse_review_native_test.go b/internal/atspi/mouse_review_native_test.go new file mode 100644 index 0000000..707e21a --- /dev/null +++ b/internal/atspi/mouse_review_native_test.go @@ -0,0 +1,81 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package atspi + +import ( + "context" + "os" + "os/exec" + "strconv" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +func TestNativeMouseReviewPointerAndHitTest(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_MOUSE_REVIEW") != "1" { + t.Skip("requires private GTK and Xorg fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stop := context.WithTimeout(context.Background(), 3*time.Second) + defer stop() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + pointer := xorg.OpenPointerReader() + if pointer == nil { + t.Fatal("X pointer reader unavailable") + } + defer pointer.Close() + for _, item := range []struct { + name, role string + protected bool + }{ + {"Caret review probe", "text", false}, + {"Protected text probe", "password text", true}, + } { + ref := findNamedReference(t, tree, item.name) + if !ref.Valid() { + t.Fatalf("%s absent", item.name) + } + geometry, err := tree.Geometry(ref) + if err != nil || !geometry.BoundsKnown { + t.Fatalf("%s geometry: %+v, %v", item.name, geometry, err) + } + x := int(geometry.Bounds.X + min(25, geometry.Bounds.Width/2)) + y := int(geometry.Bounds.Y + geometry.Bounds.Height/2) + if out, err := exec.Command("xdotool", "mousemove", strconv.Itoa(x), strconv.Itoa(y)).CombinedOutput(); err != nil { + t.Fatalf("move pointer: %s: %v", out, err) + } + position := pointer.Read() + if !position.Known || position.PID <= 0 || position.X != x || position.Y != y { + t.Fatalf("%s pointer = %+v", item.name, position) + } + point, err := adapter.ReviewAtPoint(ctx, position.X, position.Y, position.PID) + if err != nil { + t.Fatal(err) + } + if point.Snapshot.Role != item.role || point.Snapshot.Name != item.name || !point.Window.Valid() { + t.Fatalf("%s hit test = %+v", item.name, point) + } + if item.protected && (point.Word != "" || point.Line != "") { + t.Fatalf("password content exposed: %+v", point) + } + if !item.protected && (point.Line == "" || point.Offset < 0) { + t.Fatalf("entry text missing: %+v", point) + } + } +} diff --git a/internal/atspi/ocr_geometry.go b/internal/atspi/ocr_geometry.go new file mode 100644 index 0000000..4f41cff --- /dev/null +++ b/internal/atspi/ocr_geometry.go @@ -0,0 +1,97 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "errors" + "image" + "math" + + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +var ErrOCRGeometry = errors.New("OCR source bounds unavailable") + +// OCRGeometry is an owned snapshot. ProviderBounds/WindowBounds use AT-SPI +// coordinates; ScreenBounds uses physical X11 root pixels. It authorizes +// capture only, never activation. Foreground must still match at capture time. +type OCRGeometry struct { + Object ObjectID + ProviderBounds, WindowBounds Rectangle + ScreenBounds image.Rectangle + Foreground ForegroundState +} + +// Match the source's own fresh top-level window, allowing the same proportional +// scaling supported by the capture contract. Origins must match either the +// physical or uniformly scaled root. Unknown origins are rejected. Use measured +// per-axis ratios, not DPI. +func ocr_screen_bounds(bounds, window Rectangle, client xorg.Foreground) (image.Rectangle, error) { + if !bounds.Valid() || !window.Valid() || !client.Known || client.Window == 0 { + return image.Rectangle{}, ErrOCRGeometry + } + inner := Rectangle{int32(client.X), int32(client.Y), int32(client.Width), int32(client.Height)} + outer := Rectangle{int32(client.OuterX), int32(client.OuterY), int32(client.OuterWidth), int32(client.OuterHeight)} + matched := Rectangle{} + // Exact matches take precedence over a proportional decoration match. + for _, candidate := range []Rectangle{inner, outer} { + if window == candidate { + matched = candidate + break + } + } + if !matched.Valid() { + for _, candidate := range []Rectangle{inner, outer} { + if ocr_window_matches(window, candidate) { + if matched.Valid() && matched != candidate { + return image.Rectangle{}, ErrOCRGeometry + } + matched = candidate + } + } + } + if !matched.Valid() { + return image.Rectangle{}, ErrOCRGeometry + } + clipped, ok := bounds.Intersection(window) + if !ok { + return image.Rectangle{}, ErrOCRGeometry + } + + // Use exact integer edge ratios. Provider windows can exceed the OCR image + // pixel cap while the chosen object/zone remains a small valid capture. + map_edge := func(value int64, origin, extent, screenOrigin, screenExtent int32, upper bool) int { + numerator := (value - int64(origin)) * int64(screenExtent) + if upper { + numerator += int64(extent) - 1 + } + return int(int64(screenOrigin) + numerator/int64(extent)) + } + mapped := image.Rect(map_edge(int64(clipped.X), window.X, window.Width, matched.X, matched.Width, false), + map_edge(int64(clipped.Y), window.Y, window.Height, matched.Y, matched.Height, false), + map_edge(int64(clipped.X)+int64(clipped.Width), window.X, window.Width, matched.X, matched.Width, true), + map_edge(int64(clipped.Y)+int64(clipped.Height), window.Y, window.Height, matched.Y, matched.Height, true)) + if mapped.Empty() { + return image.Rectangle{}, ErrOCRGeometry + } + + return mapped, nil +} + +// GTK can scale the root origin as well as dimensions; Chromium may retain +// a physical root origin. Admit these two measured contracts only. Other +// monitor-dependent origin conventions need separate evidence. +func ocr_window_matches(provider, native Rectangle) bool { + if !provider.Valid() || !native.Valid() { + return false + } + scaleX, scaleY := float64(native.Width)/float64(provider.Width), float64(native.Height)/float64(provider.Height) + if scaleX < 0.5 || scaleX > 3 || scaleY < 0.5 || scaleY > 3 || math.Abs(scaleX-scaleY) > 0.01*math.Max(scaleX, scaleY) { + return false + } + return provider.X == native.X && provider.Y == native.Y || + math.Abs(float64(provider.X)*scaleX-float64(native.X)) <= 1 && + math.Abs(float64(provider.Y)*scaleY-float64(native.Y)) <= 1 +} diff --git a/internal/atspi/ocr_geometry_test.go b/internal/atspi/ocr_geometry_test.go new file mode 100644 index 0000000..082c9e0 --- /dev/null +++ b/internal/atspi/ocr_geometry_test.go @@ -0,0 +1,48 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "image" + "math" + "testing" + + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +func TestOCRProviderCoordinateConversion(t *testing.T) { + for _, test := range []struct { + name string + window, object Rectangle + client xorg.Foreground + want image.Rectangle + fail bool + }{ + {name: "physical", window: Rectangle{40, 30, 300, 200}, object: Rectangle{50, 45, 80, 50}, client: xorg.Foreground{Known: true, Window: 1, X: 40, Y: 30, Width: 300, Height: 200}, want: image.Rect(50, 45, 130, 95)}, + {name: "scaled provider", window: Rectangle{40, 30, 150, 100}, object: Rectangle{45, 35, 40, 25}, client: xorg.Foreground{Known: true, Window: 1, X: 40, Y: 30, Width: 300, Height: 200}, want: image.Rect(50, 40, 130, 90)}, + {name: "round outward", window: Rectangle{40, 30, 200, 100}, object: Rectangle{41, 31, 1, 1}, client: xorg.Foreground{Known: true, Window: 1, X: 40, Y: 30, Width: 301, Height: 151}, want: image.Rect(41, 31, 44, 34)}, + {name: "negative clip", window: Rectangle{-200, -100, 300, 200}, object: Rectangle{-220, -110, 50, 40}, client: xorg.Foreground{Known: true, Window: 1, X: -200, Y: -100, Width: 300, Height: 200}, want: image.Rect(-200, -100, -170, -70)}, + {name: "decorations", window: Rectangle{40, 30, 300, 220}, object: Rectangle{50, 55, 80, 50}, client: xorg.Foreground{Known: true, Window: 1, X: 40, Y: 50, Width: 300, Height: 200, OuterX: 40, OuterY: 30, OuterWidth: 300, OuterHeight: 220}, want: image.Rect(50, 55, 130, 105)}, + {name: "large window small object", window: Rectangle{0, 0, 7680, 4320}, object: Rectangle{20, 20, 40, 30}, client: xorg.Foreground{Known: true, Window: 1, Width: 7680, Height: 4320}, want: image.Rect(20, 20, 60, 50)}, + {name: "unknown origin", window: Rectangle{math.MinInt32, 0, 300, 200}, object: Rectangle{0, 0, 10, 10}, fail: true}, + {name: "disjoint", window: Rectangle{40, 30, 300, 200}, object: Rectangle{400, 0, 10, 10}, client: xorg.Foreground{Known: true, Window: 1, X: 40, Y: 30, Width: 300, Height: 200}, fail: true}, + {name: "nonuniform scale", window: Rectangle{40, 30, 300, 200}, object: Rectangle{50, 45, 80, 50}, client: xorg.Foreground{Known: true, Window: 1, X: 40, Y: 30, Width: 600, Height: 200}, fail: true}, + {name: "scaled root origin", window: Rectangle{20, 15, 150, 100}, object: Rectangle{25, 20, 40, 25}, client: xorg.Foreground{Known: true, Window: 1, X: 40, Y: 30, Width: 300, Height: 200}, want: image.Rect(50, 40, 130, 90)}, + {name: "ambiguous decoration scale", window: Rectangle{0, 0, 100, 100}, object: Rectangle{0, 0, 20, 20}, client: xorg.Foreground{Known: true, Window: 1, Width: 200, Height: 200, OuterWidth: 202, OuterHeight: 202}, fail: true}, + } { + t.Run(test.name, func(t *testing.T) { + got, err := ocr_screen_bounds(test.object, test.window, test.client) + if test.fail { + if err == nil { + t.Fatalf("accepted ambiguous bounds: %v", got) + } + return + } + if err != nil || got != test.want { + t.Fatalf("got %v %v, want %v", got, err, test.want) + } + }) + } +} diff --git a/internal/atspi/ocr_native_test.go b/internal/atspi/ocr_native_test.go new file mode 100644 index 0000000..cb3f639 --- /dev/null +++ b/internal/atspi/ocr_native_test.go @@ -0,0 +1,141 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "bufio" + "context" + "encoding/json" + "image" + "image/color" + "os" + "os/exec" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/ocr" +) + +func TestNativeOCRProviderGeometry(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_OCR_GEOMETRY") != "1" { + t.Skip("requires private Xorg/AT-SPI session") + } + executable := os.Getenv("CTHULHU_OCR_CAPTURE_BINARY") + if executable == "" { + t.Fatal("set freshly built CTHULHU_OCR_CAPTURE_BINARY") + } + ctx, cancel := context.WithTimeout(context.Background(), 40*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + for _, scale := range []string{"1", "2"} { + t.Run("scale"+scale, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-u", "../../tests/ocr_geometry_fixture.py") + fixture.Env = append(os.Environ(), "GDK_SCALE="+scale, "NO_AT_BRIDGE=0", "GTK_MODULES=gail:atk-bridge") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err = fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + type state struct { + Window uint64 + Target [4]int + Focus uint64 + } + read := func() state { + t.Helper() + if !scanner.Scan() { + t.Fatal("fixture did not respond") + } + var s state + if err = json.Unmarshal(scanner.Bytes(), &s); err != nil { + t.Fatal(err) + } + return s + } + initial := read() + action := func(name string) state { + t.Helper() + data, _ := json.Marshal(map[string]string{"action": name}) + if _, err = stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + return read() + } + var tree *AccessibleTree + var ref ObjectReference + for !ref.Valid() { + tree, err = adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + ref = findNamedReference(t, tree, "Painted target") + if !ref.Valid() { + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(10 * time.Millisecond): + } + } + } + geometry, err := adapter.CaptureOCRGeometry(ctx, ref.ID(), nil) + expected := image.Rect(initial.Target[0], initial.Target[1], initial.Target[2], initial.Target[3]) + if err != nil || geometry.ScreenBounds != expected || geometry.Foreground.Client.Window != initial.Window { + provider, _ := tree.Geometry(ref) + t.Fatalf("geometry=%+v err=%v want=%v provider=%+v foreground=%+v", geometry, err, expected, provider, adapter.Foreground()) + } + result, err := ocr.NewCapturer(executable).Capture(ctx, ocr.CaptureRequest{Kind: ocr.ObjectSource, Bounds: geometry.ScreenBounds, Foreground: initial.Window, Generation: 1}) + if err != nil { + t.Fatal(err) + } + for _, point := range []image.Point{image.Pt(0, 0), image.Pt(result.Pixels.Bounds().Dx()-1, result.Pixels.Bounds().Dy()-1)} { + if got := color.RGBAModel.Convert(result.Pixels.At(point.X, point.Y)); got != (color.RGBA{51, 102, 153, 255}) { + t.Fatalf("mapped pixel %v = %v", point, got) + } + } + zone := geometry.ProviderBounds + zone.Width /= 2 + zone.Height /= 2 + part, err := adapter.CaptureOCRGeometry(ctx, ref.ID(), &zone) + if err != nil || part.ScreenBounds.Dx() != expected.Dx()/2 || part.ScreenBounds.Dy() != expected.Dy()/2 { + t.Fatalf("zone: %+v %v", part, err) + } + invalid := zone + invalid.X -= 10 + if _, err = adapter.CaptureOCRGeometry(ctx, ref.ID(), &invalid); err == nil { + t.Fatal("outside zone accepted") + } + after := action("state") + if after.Focus != initial.Focus { + t.Fatal("geometry/capture stole focus") + } + protected := findNamedReference(t, tree, "Protected target") + if !protected.Valid() { + t.Fatal("protected entry missing") + } + if _, err = adapter.CaptureOCRGeometry(ctx, protected.ID(), nil); err != nil { + t.Fatalf("masked password capture geometry unavailable: %v", err) + } + action("hide") + if _, err = adapter.CaptureOCRGeometry(ctx, ref.ID(), nil); err == nil { + t.Fatal("hidden source accepted") + } + }) + } +} diff --git a/internal/atspi/pointer_native_test.go b/internal/atspi/pointer_native_test.go new file mode 100644 index 0000000..431b7a7 --- /dev/null +++ b/internal/atspi/pointer_native_test.go @@ -0,0 +1,42 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "testing" + "time" +) + +func TestNativePointerInput(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + ticker := time.NewTicker(100 * time.Millisecond) + defer ticker.Stop() + for { + select { + case <-ticker.C: + if out, err := exec.CommandContext(ctx, "xdotool", "mousemove", "200", "200", "click", "1").CombinedOutput(); err != nil { + t.Fatalf("click: %v %s", err, out) + } + case event := <-adapter.Events(): + if event.Type == MouseButtonEvent { + return + } + case <-ctx.Done(): + t.Fatal("shared AT-SPI pointer press was not delivered") + } + } +} diff --git a/internal/atspi/position_native_test.go b/internal/atspi/position_native_test.go new file mode 100644 index 0000000..ec03722 --- /dev/null +++ b/internal/atspi/position_native_test.go @@ -0,0 +1,65 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "testing" + "time" +) + +func TestNativeBrowserSetPositions(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + for _, test := range []struct { + name string + position, size int + }{ + {"First item", 1, 3}, {"Middle item", 2, 3}, {"Last item", 3, 3}, + {"Virtual item", 501, 1001}, {"Unknown size", 0, 0}, + {"Nested tree item", 2, 4}, + {"First menu item", 1, 2}, {"Second menu item", 2, 2}, + {"First radio", 1, 2}, {"Second radio", 2, 2}, + } { + snapshot, err := tree.Resolve(findNamedReference(t, tree, test.name)) + if err != nil || snapshot.PositionInSet != test.position || snapshot.SetSize != test.size { + t.Errorf("%s (%s): position %d of %d, want %d of %d, err=%v", test.name, snapshot.Role, + snapshot.PositionInSet, snapshot.SetSize, test.position, test.size, err) + } + } + // Snapshot capture for a focused event must carry provider metadata too, + // rather than only the document-tree path used by browse navigation. + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "Tab").CombinedOutput(); err != nil { + t.Fatalf("focus virtual item: %v %s", err, out) + } + for { + select { + case event := <-adapter.Events(): + if event.Type != FocusedStateEvent || event.Detail1 != 1 || event.Source.Name != "Virtual item" { + continue + } + if event.Source.PositionInSet != 501 || event.Source.SetSize != 1001 { + t.Fatalf("focus lost set position: %+v", event.Source) + } + return + case <-ctx.Done(): + t.Fatal("virtual item focus event missing") + } + } +} diff --git a/internal/atspi/preferences_native_test.go b/internal/atspi/preferences_native_test.go new file mode 100644 index 0000000..d6f554f --- /dev/null +++ b/internal/atspi/preferences_native_test.go @@ -0,0 +1,245 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "encoding/json" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/preferences" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +func TestNativePreferencesDropdownEscape(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_PREFERENCES") != "1" { + t.Skip("requires private Xvfb/AT-SPI session and preferences binary") + } + largeCatalog := os.Getenv("CTHULHU_PREFS_LARGE_CATALOG") == "1" + if largeCatalog { + t.Setenv("LC_ALL", "en_US.UTF-8") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + wmConfig := filepath.Join(t.TempDir(), "i3.config") + if err := os.WriteFile(wmConfig, []byte("font pango:monospace 10\nipc-socket "+filepath.Join(filepath.Dir(wmConfig), "i3.sock")+"\n"), 0600); err != nil { + t.Fatal(err) + } + wm := exec.CommandContext(ctx, "i3", "-c", wmConfig) + wm.Env = append(os.Environ(), "I3SOCK="+filepath.Join(filepath.Dir(wmConfig), "i3.sock")) + wm.Stderr = os.Stderr + wm.Stdout = os.Stderr + if err := wm.Start(); err != nil { + t.Fatal(err) + } + defer func() { + _ = wm.Process.Kill() + _ = wm.Wait() + }() + for { + output, _ := exec.CommandContext(ctx, "xprop", "-root", "_NET_SUPPORTING_WM_CHECK").Output() + if strings.Contains(string(output), "0x") { + break + } + select { + case <-ctx.Done(): + t.Fatal("private window manager did not start") + case <-time.After(20 * time.Millisecond): + } + } + adapter := New() + adapter.SetCaptureSoundGeometry(false) + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stop := context.WithTimeout(context.Background(), 3*time.Second) + defer stop() + if err := adapter.Stop(stopCtx); err != nil { + t.Errorf("stop adapter: %v", err) + } + }() + command := exec.CommandContext(ctx, os.Getenv("CTHULHU_BINARY"), "--preferences-ui") + in, err := command.StdinPipe() + if err != nil { + t.Fatal(err) + } + command.Stderr = os.Stderr + if err := command.Start(); err != nil { + t.Fatal(err) + } + helperDone := make(chan error, 1) + go func() { helperDone <- command.Wait() }() + helperJoined := false + defer func() { + in.Close() + _ = command.Process.Kill() + if !helperJoined { + <-helperDone + } + }() + settings := config.DefaultSettings() + settings.DefaultVoice.Family = &config.VoiceFamily{Name: "Test voice", Lang: "en"} + if largeCatalog { + settings.DefaultVoice.Family = nil + } + initial := preferences.Response{Values: preferences.FromSettings(settings), + CanSave: true, Accepted: true, Message: "Preferences test ready.", + Catalog: speech.Catalog{"": {{Name: "Test voice", Language: "en"}}, "test-module": nil}} + if largeCatalog { + // The helper inherits the test's locale; only 100 of the 6,000 + // eSpeak voices should be built into its Person menu. + for i := 0; i < 6000; i++ { + language := "de" + if i < 100 { + language = "en" + } + initial.Catalog["espeak-ng"] = append(initial.Catalog["espeak-ng"], + speech.Voice{Name: fmt.Sprintf("Test voice %d", i), Language: language}) + } + } + if err := json.NewEncoder(in).Encode(initial); err != nil { + t.Fatal(err) + } + wait_event := func(timeout time.Duration, match func(Event) bool) Event { + t.Helper() + timer := time.NewTimer(timeout) + defer timer.Stop() + for { + select { + case event := <-adapter.Events(): + t.Logf("%s %s %q capture=%s", event.Type, event.Source.Role, event.Source.Name, event.SnapshotDuration) + if event.Type == FocusedStateEvent && event.Detail1 == 1 { + // Match the running reader's browser-mode classification. + // Without these fresh ancestry queries, stale cached focus + // hides the no-focus interval when the popup closes. + _, _ = adapter.CaptureDocumentContext(ctx, event.Source.ID()) + } + if match(event) { + return event + } + case <-timer.C: + t.Fatal("expected preferences event missing") + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + focused := func(name string) func(Event) bool { + return func(event Event) bool { + return event.Type == FocusedStateEvent && event.Detail1 == 1 && event.Source.Name == name + } + } + wait_event(5*time.Second, func(event Event) bool { return event.Type == WindowActivatedEvent }) + xdotool := func(args ...string) string { + t.Helper() + output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput() + if err != nil { + t.Fatalf("xdotool %v: %v: %s", args, err, output) + } + return strings.TrimSpace(string(output)) + } + window := xdotool("search", "--onlyvisible", "--name", "^Cthulhu Preferences$") + xdotool("windowfocus", window) + capture_review := func(name, wantName string, focus ObjectID) { + t.Helper() + captureCtx, stop := context.WithTimeout(ctx, 2*time.Second) + defer stop() + started := time.Now() + tree, err := adapter.CaptureReviewWindow(captureCtx, focus) + if err != nil { + t.Fatalf("%s review capture after %s: %v", name, time.Since(started), err) + } + snapshot, err := tree.ReviewWindow(captureCtx, focus) + if err != nil { + t.Fatalf("%s review window: %v", name, err) + } + ranges, found := 0, false + for _, node := range snapshot.Nodes { + ranges += len(node.Text.Ranges) + if node.Geometry.Visible && node.Geometry.Showing && node.Geometry.BoundsKnown && node.Snapshot.Name == wantName { + found = true + } + if node.Geometry.VisibilityKnown && (!node.Geometry.Visible || !node.Geometry.Showing) && len(node.Children) != 0 { + t.Fatalf("%s review traversed hidden %s %q", name, node.Snapshot.Role, node.Snapshot.Name) + } + } + if !found { + t.Fatalf("%s review is missing visible %q", name, wantName) + } + t.Logf("%s review: %d nodes, %d text ranges in %s", name, len(snapshot.Nodes), ranges, time.Since(started)) + } + // Match the reported workflow: focus the General tab header itself. + xdotool("key", "ctrl+Page_Down", "ctrl+Page_Up") + general := wait_event(5*time.Second, focused("General")) + capture_review("General", "Desktop", general.Source.ID()) + xdotool("key", "ctrl+Page_Down", "ctrl+Page_Down") + speech := wait_event(5*time.Second, focused("Speech")) + capture_review("Speech", "Enable speech", speech.Source.ID()) + xdotool("key", "Tab", "Tab") + wait_event(5*time.Second, focused("Speech system")) + xdotool("key", "alt+Down") + popup := wait_event(5*time.Second, focused("Speech Dispatcher")) + capture_review("open dropdown", "Speech Dispatcher", popup.Source.ID()) + xdotool("key", "Escape") + combo := wait_event(1500*time.Millisecond, focused("Speech system")) + capture_review("closed dropdown", "Speech system", combo.Source.ID()) + xdotool("key", "alt+Down") + popup = wait_event(5*time.Second, focused("Speech Dispatcher")) + capture_review("reopened dropdown", "Speech Dispatcher", popup.Source.ID()) + xdotool("key", "Escape") + wait_event(1500*time.Millisecond, focused("Speech system")) + xdotool("key", "ctrl+Page_Up", "ctrl+Page_Up") + general = wait_event(5*time.Second, focused("Desktop")) + capture_review("returned General", "Desktop", general.Source.ID()) + xdotool("key", "shift+Tab") + wait_event(5*time.Second, focused("General")) + xdotool("key", "--clearmodifiers", "ctrl+Page_Down", "ctrl+Page_Down") + wait_event(5*time.Second, focused("Speech")) + xdotool("key", "Tab", "Tab") + wait_event(5*time.Second, focused("Speech system")) + xdotool("key", "alt+Down") + wait_event(5*time.Second, focused("Speech Dispatcher")) + started := time.Now() + xdotool("key", "Escape") + wait_event(1500*time.Millisecond, focused("Speech system")) + t.Logf("dropdown Escape restored focus in %s", time.Since(started)) + xdotool("key", "Tab") + wait_event(1500*time.Millisecond, focused("Speech synthesizer")) + xdotool("key", "alt+Down") + wait_event(5*time.Second, focused("Default")) + xdotool("key", "Escape") + wait_event(1500*time.Millisecond, focused("Speech synthesizer")) + if largeCatalog { + xdotool("key", "Down") + } + xdotool("key", "Tab") + wait_event(1500*time.Millisecond, focused("Language")) + if largeCatalog { + xdotool("key", "Tab") + wait_event(1500*time.Millisecond, focused("Person")) + xdotool("key", "alt+Down") + wait_event(1500*time.Millisecond, focused("Default")) + xdotool("key", "Escape") + wait_event(1500*time.Millisecond, focused("Person")) + } + xdotool("key", "Escape") + select { + case err := <-helperDone: + helperJoined = true + if err != nil { + t.Fatal(err) + } + case <-time.After(1500 * time.Millisecond): + t.Fatal("Escape did not close preferences promptly") + } +} diff --git a/internal/atspi/read_all_native.go b/internal/atspi/read_all_native.go new file mode 100644 index 0000000..9f1ff3a --- /dev/null +++ b/internal/atspi/read_all_native.go @@ -0,0 +1,130 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#cgo pkg-config: atspi-2 glib-2.0 gobject-2.0 +#include +*/ +import "C" + +import ( + "context" + "errors" +) + +func (adapter *Adapter) ReadFocusedText(ctx context.Context, focus ObjectID) (DocumentContent, error) { + result, err := adapter.documentOperation(ctx, treeCaptureRequest{reviewFocus: focus, readFocusedText: true}) + return result.content, err +} + +func (adapter *Adapter) SetFocusedTextCaret(ctx context.Context, focus ObjectID, offset int) error { + _, err := adapter.documentOperation(ctx, treeCaptureRequest{reviewFocus: focus, setFocusedCaret: true, positionOffset: offset}) + return err +} + +func (adapter *Adapter) setNativeFocusedTextCaret(ctx context.Context, focus ObjectID, offset int) error { + if err := ctx.Err(); err != nil { + return err + } + if !adapter.nativeFocusIs(focus) || offset < 0 { + return ErrStaleObject + } + source := adapter.nativeFocus[len(adapter.nativeFocus)-1].source + if C.atspi_accessible_get_role(source, nil) == C.ATSPI_ROLE_PASSWORD_TEXT { + return ErrNoDocumentCaret + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return ErrNoDocumentCaret + } + defer C.g_object_unref(C.gpointer(text)) + adapter.navigationEcho = map[ObjectID]uint8{focus: 7} + var nativeErr *C.GError + placed := C.atspi_text_set_caret_offset(text, C.gint(offset), &nativeErr) + if nativeErr != nil { + err := nativeError("place read all caret", nativeErr) + C.g_error_free(nativeErr) + return err + } + if placed == 0 { + delete(adapter.navigationEcho, focus) + return ErrNoDocumentCaret + } + return nil +} + +func (adapter *Adapter) readNativeFocusedText(ctx context.Context, focus ObjectID) (DocumentContent, error) { + if err := ctx.Err(); err != nil { + return DocumentContent{}, err + } + if !adapter.nativeFocusIs(focus) { + return DocumentContent{}, ErrStaleObject + } + source := adapter.nativeFocus[len(adapter.nativeFocus)-1].source + snapshot := snapshotFromNativeWithCaret(source, false, false, false, false) + content := DocumentContent{Snapshot: snapshot} + if snapshot.Role == "password text" { + return content, nil + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return content, nil + } + defer C.g_object_unref(C.gpointer(text)) + var nativeErr *C.GError + count := int(C.atspi_text_get_character_count(text, &nativeErr)) + if nativeErr != nil { + err := nativeError("read all character count", nativeErr) + C.g_error_free(nativeErr) + return DocumentContent{}, err + } + offset := int(C.atspi_text_get_caret_offset(text, &nativeErr)) + if nativeErr != nil { + err := nativeError("read all caret offset", nativeErr) + C.g_error_free(nativeErr) + return DocumentContent{}, err + } + offset = max(0, offset) + if snapshot.Role == "terminal" && count > 0 { + terminal := nativeReviewText{text: text, terminal: true} + terminalCount, err := terminal.count(ctx) + if err != nil { + return DocumentContent{}, err + } + count = terminalCount + if count > 0 { + // A terminal caret commonly sits after the prompt's last character. + // Python Say All reads its containing line, including that prompt, + // before advancing. Keep editable controls' exact caret behavior. + line, err := terminal.line(ctx, min(offset, count-1)) + if err != nil { + return DocumentContent{}, err + } + if line.Start < 0 || line.Start > offset || line.End <= line.Start || line.End > count { + return DocumentContent{}, errors.New("read all: invalid terminal line offsets") + } + offset = line.Start + } + } + if count-offset > 1<<20 { + return DocumentContent{}, errors.New("read all: text exceeds speech capture limit") + } + if offset >= count { + content.Snapshot.Name, content.Snapshot.Text = "", "" + return content, nil + } + value := C.atspi_text_get_text(text, C.gint(offset), C.gint(count), &nativeErr) + if value != nil { + defer C.g_free(C.gpointer(value)) + } + if nativeErr != nil { + err := nativeError("read all text", nativeErr) + C.g_error_free(nativeErr) + return DocumentContent{}, err + } + content.Start, content.End, content.Text = offset, count, C.GoString(value) + return content, ctx.Err() +} diff --git a/internal/atspi/replaced_feed_native_test.go b/internal/atspi/replaced_feed_native_test.go new file mode 100644 index 0000000..eda64b7 --- /dev/null +++ b/internal/atspi/replaced_feed_native_test.go @@ -0,0 +1,137 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "errors" + "fmt" + "os" + "os/exec" + "testing" + "time" +) + +func TestNativeBrowserMissingFeedRefreshesWholeBranch(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + keys := func(args ...string) { + t.Helper() + if output, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("xdotool: %v: %s", err, output) + } + } + desktop, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + start := findNamedReference(t, desktop, "Feed start") + bounds, err := desktop.Geometry(start) + if err != nil || !bounds.BoundsKnown { + t.Fatalf("feed start bounds unavailable: %+v, %v", bounds, err) + } + keys("key", "--clearmodifiers", "ctrl+l") + keys("mousemove", "--sync", fmt.Sprint(bounds.Bounds.X+bounds.Bounds.Width/2), fmt.Sprint(bounds.Bounds.Y+bounds.Bounds.Height/2), "click", "1") + focused := false + for !focused { + select { + case event := <-adapter.Events(): + focused = event.Type == FocusedStateEvent && event.Detail1 == 1 && event.Source.ID() == start.ID() + case <-ctx.Done(): + t.Fatal("feed start focus: ", ctx.Err()) + } + } + tree, err := adapter.CaptureDocument(ctx, start.ID()) + if err != nil { + t.Fatal(err) + } + root, _ := tree.Root() + doc, err := tree.Document(ctx, root) + if err != nil { + t.Fatal(err) + } + // Keep the captured semantics from before replacement. This explicitly + // models a provider omitting the structural events for an enclosing feed. + oldNodes := make([]TreeNode, 0, len(doc.Nodes)) + for _, node := range doc.Nodes { + oldNodes = append(oldNodes, TreeNode{Snapshot: node.Snapshot, Children: node.Children, Geometry: node.Geometry, Text: node.Text}) + } + missing := findNamedReference(t, tree, "Later post") + otherOld := findNamedReference(t, tree, "Earlier post") + keys("key", "--clearmodifiers", "F9") + replaced := false + for !replaced { + select { + case event := <-adapter.Events(): + replaced = event.Type == AccessibleNameEvent && event.Source.Name == "Feed replacement complete" + case <-ctx.Done(): + t.Fatal("feed replacement: ", ctx.Err()) + } + } + if err := tree.Replace(root.ID(), oldNodes); err != nil { + t.Fatal(err) + } + // Use the current generation after restoring the deliberately stale cache. + missing, err = tree.Reference(missing.ID()) + if err != nil { + t.Fatal(err) + } + _, err = adapter.ReadDocumentCaret(ctx, missing, 0, DocumentCaretBrailleLine) + if !errors.Is(err, ErrDeadObject) { + t.Fatalf("missing feed target = %v, want confirmed removal", err) + } + // libatspi can dispatch late defunct events during the failed native + // read. Restore the omitted-event scenario after that call, then replay + // its genuine missing-object response against the stale owned snapshot. + if restoreErr := tree.Replace(root.ID(), oldNodes); restoreErr != nil { + t.Fatal(restoreErr) + } + if replayErr := adapter.document_object_error(missing.ID(), err); !errors.Is(replayErr, ErrDeadObject) { + t.Fatal(replayErr) + } + tree, err = adapter.CaptureDocument(ctx, start.ID()) + if err != nil { + t.Fatal(err) + } + if _, err := tree.Reference(otherOld.ID()); !errors.Is(err, ErrObjectNotFound) { + t.Fatalf("recapture retained another dead heading: %v", err) + } + + root, err = tree.Root() + if err != nil { + t.Fatal(err) + } + fresh, err := tree.Document(ctx, root) + if err != nil { + t.Fatal(err) + } + expected := []string{"Later refreshed post", "Middle refreshed post", "Earlier refreshed post"} + headingIndex := 0 + for index := len(fresh.Nodes) - 1; index >= 0; index-- { + node := fresh.Nodes[index] + if node.Snapshot.Role != "heading" { + continue + } + if headingIndex >= len(expected) || node.Snapshot.Name != expected[headingIndex] { + t.Fatalf("unexpected backward heading %q at index %d", node.Snapshot.Name, headingIndex) + } + text, err := adapter.ReadDocumentCaret(ctx, node.Reference, 0, DocumentCaretBrailleLine) + if err != nil || text.Text != expected[headingIndex] { + t.Fatalf("backward feed reading %q = %+v, %v", expected[headingIndex], text, err) + } + headingIndex++ + } + if headingIndex != len(expected) { + t.Fatalf("backward headings = %d, want %d", headingIndex, len(expected)) + } +} diff --git a/internal/atspi/review.go b/internal/atspi/review.go new file mode 100644 index 0000000..e906bed --- /dev/null +++ b/internal/atspi/review.go @@ -0,0 +1,95 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "context" + "errors" +) + +var ErrNoReviewWindow = errors.New("focused object has no review window") + +// ReviewSnapshot owns one window's nodes and their generation-checked +// references. Keeping references alongside nodes prevents a reused object ID +// from inheriting an independent review position from a removed object. +type ReviewSnapshot struct { + Nodes []TreeNode + References map[ObjectID]ObjectReference +} + +// ReviewWindow copies the focused menu, dialog, or window in tree order under +// one read lock. A consumer must not assemble layout from separately locked +// getters: replacement between getters could mix two different captures. +// Stale descendants fail the whole operation rather than yielding partial +// screen content. Call this on the review worker, never the input/event loop. +func (tree *AccessibleTree) ReviewWindow(ctx context.Context, focus ObjectID) (ReviewSnapshot, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + if err := ctx.Err(); err != nil { + return ReviewSnapshot{}, err + } + entry, ok := tree.nodes[focus] + if !ok { + return ReviewSnapshot{}, ErrObjectNotFound + } + root := focus + for { + switch entry.snapshot.Role { + case "menu", "popup menu", "dialog", "alert", "frame", "window": + goto found + } + if !entry.hasParent { + return ReviewSnapshot{}, ErrNoReviewWindow + } + root = entry.parent + entry = tree.nodes[root] + } +found: + var nodes []TreeNode + references := make(map[ObjectID]ObjectReference) + pending := []ObjectID{root} + for len(pending) > 0 { + if err := ctx.Err(); err != nil { + return ReviewSnapshot{}, err + } + id := pending[len(pending)-1] + pending = pending[:len(pending)-1] + entry, ok := tree.nodes[id] + if !ok { + return ReviewSnapshot{}, ErrStaleObject + } + if entry.childrenInvalid { + return ReviewSnapshot{}, ErrIncompleteTree + } + if entry.geometryInvalid { + return ReviewSnapshot{}, ErrStaleGeometry + } + if entry.textInvalid { + return ReviewSnapshot{}, ErrStaleText + } + text := entry.text + text.Ranges = append([]TextRange(nil), text.Ranges...) + nodes = append(nodes, TreeNode{Snapshot: entry.snapshot, Geometry: entry.geometry, + Text: text, Children: append([]ObjectID(nil), entry.children...), ChildrenUnavailable: entry.childrenUnavailable}) + references[id] = newObjectReference(id, entry) + for i := len(entry.children) - 1; i >= 0; i-- { + pending = append(pending, entry.children[i]) + } + } + return ReviewSnapshot{Nodes: nodes, References: references}, nil +} diff --git a/internal/atspi/review_cache_native_test.go b/internal/atspi/review_cache_native_test.go new file mode 100644 index 0000000..9291a6c --- /dev/null +++ b/internal/atspi/review_cache_native_test.go @@ -0,0 +1,253 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "bufio" + "bytes" + "context" + "encoding/json" + "fmt" + "log/slog" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/logging" +) + +func TestNativeFlatReviewPreservesProviderCache(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_REVIEW_CACHE") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + test_native_review_provider(t, "cache") +} + +func TestNativeFlatReviewBoundsSlowLongRanges(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_REVIEW_BOUNDS") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + test_native_review_provider(t, "bounds") +} + +func TestNativeFlatReviewClippedViewport(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_REVIEW_CLIPPED") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + test_native_review_provider(t, "clipped") +} + +func TestNativeFlatReviewLargeTextViewport(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_REVIEW_VIEWPORT") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + // Adapter ownership is process-global; each mode runs in its own process. + mode := os.Getenv("CTHULHU_NATIVE_REVIEW_VIEWPORT_MODE") + if mode != "lines" && mode != "long" { + t.Fatal("set viewport mode to lines or long") + } + test_native_review_provider(t, mode) +} + +func TestNativeFlatReviewUnavailableSubtree(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_REVIEW_SUBTREE") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + test_native_review_provider(t, "children") +} + +func TestNativeFlatReviewZeroAreaGlyph(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_REVIEW_GLYPHS") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + test_native_review_provider(t, "glyphs") +} + +func test_native_review_provider(t *testing.T, mode string) { + t.Helper() + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + flags, err := exec.CommandContext(ctx, "pkg-config", "--cflags", "--libs", "gtk+-3.0").Output() + if err != nil { + t.Fatal(err) + } + binary := filepath.Join(t.TempDir(), "review-cache-fixture") + args := append([]string{"../../tests/review_cache_fixture.c", "-o", binary}, strings.Fields(string(flags))...) + if output, err := exec.CommandContext(ctx, "cc", args...).CombinedOutput(); err != nil { + t.Fatalf("build fixture: %v: %s", err, output) + } + var diagnostics bytes.Buffer + adapter := New() + adapter.SetCaptureLogger(logging.New(&diagnostics, logging.Options{Level: slog.LevelDebug})) + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + fixture := exec.CommandContext(ctx, binary, mode) + fixture.Stderr = os.Stderr + input, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + output, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { + _ = fixture.Process.Kill() + _ = fixture.Wait() + }() + if output, err := exec.CommandContext(ctx, "xdotool", "search", "--sync", "--onlyvisible", "--name", "^Review cache probe$", "windowfocus").CombinedOutput(); err != nil { + t.Fatalf("focus fixture: %v: %s", err, output) + } + var focus ObjectID + for !focus.Valid() { + select { + case event := <-adapter.Events(): + if event.Type == WindowActivatedEvent && event.WindowTitle == "Review cache probe" { + focus = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal("fixture focus missing") + } + } + scanner := bufio.NewScanner(output) + command := func(request, want string) { + t.Helper() + if _, err := fmt.Fprintln(input, request); err != nil { + t.Fatal(err) + } + if !scanner.Scan() || scanner.Text() != want { + t.Fatalf("fixture %s: %q, %v", request, scanner.Text(), scanner.Err()) + } + } + if mode == "bounds" || mode == "clipped" || mode == "long" || mode == "lines" || mode == "glyphs" { + command("measure", "measuring") + } else if mode != "children" { + command("arm", "armed") + } + if mode == "lines" { + command("scroll", "scrolled") + } + tree, err := adapter.CaptureReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + var timing struct { + Message string `json:"message"` + RootScope string `json:"root_scope"` + CapturedNodes int `json:"captured_nodes"` + Stages []captureStageTiming `json:"stages"` + } + if err := json.Unmarshal(diagnostics.Bytes(), &timing); err != nil { + t.Fatalf("capture diagnostics: %v: %s", err, diagnostics.Bytes()) + } + if timing.Message != "flat review capture timing" || timing.RootScope != "window" || timing.CapturedNodes == 0 { + t.Fatalf("missing capture scope/progress: %+v", timing) + } + if mode == "children" { + broken := findNamedReference(t, tree, "Broken subtree") + if !broken.Valid() { + t.Fatal("broken subtree fixture missing") + } + command("arm", "armed") + tree.InvalidateChildren(broken.ID()) + tree, err = adapter.CaptureReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + snapshot, err := tree.ReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + omitted, healthy := false, false + for _, node := range snapshot.Nodes { + omitted = omitted || node.Snapshot.ID() == broken.ID() && node.ChildrenUnavailable + for _, span := range node.Text.Ranges { + healthy = healthy || span.Text == "Cached review text" + } + } + if !omitted || !healthy { + t.Fatalf("subtree recovery: omission=%v healthy=%v", omitted, healthy) + } + return + } + for _, want := range []string{"queue-wait", "root-selection", "snapshot", "geometry", "visible-text", "table-viewport", "child-count", "child-enumeration", "tree-installation"} { + found := false + for _, stage := range timing.Stages { + if stage.Stage == want && stage.Calls > 0 && stage.Duration > 0 { + found = true + } + } + if !found { + t.Errorf("capture timing missing stage %q: %+v", want, timing) + } + } + if mode == "bounds" || mode == "clipped" || mode == "long" || mode == "lines" || mode == "glyphs" { + label := findNamedReference(t, tree, "Long review label") + if !label.Valid() { + t.Fatal("long label missing from review") + } + text, err := tree.VisibleText(label) + if err != nil || !text.Known || text.Limited || len(text.Ranges) == 0 { + t.Fatalf("long label text: %+v, %v", text, err) + } + if mode == "bounds" { + command("largest", "largest 128") + command("repeated", "repeated 0") + } + if mode == "lines" && text.Ranges[0].Start <= maxReviewCharacters { + t.Fatalf("line viewport did not seek scrolled native offsets: %d", text.Ranges[0].Start) + } + if mode == "glyphs" { + for _, span := range text.Ranges { + if span.Start <= 5 && span.End > 5 { + t.Fatalf("zero-area glyph included as visible text: %+v", span) + } + } + } + if mode == "clipped" { + characters := 0 + for _, span := range text.Ranges { + characters += utf8.RuneCountInString(span.Text) + } + if characters <= maxReviewRanges || len(text.Ranges) > 21 { + t.Fatalf("fixture must capture hundreds of characters as visual spans: characters=%d ranges=%d", characters, len(text.Ranges)) + } + } + return + } + label := findNamedReference(t, tree, "Cached review text") + if !label.Valid() { + t.Fatal("cached label missing from review") + } + command("count", "count 0") + command("change", "changed") + for { + select { + case event := <-adapter.Events(): + if event.Source.ID() == label.ID() && strings.HasPrefix(event.Type, "object:text-changed:") { + goto changed + } + case <-ctx.Done(): + t.Fatal("text change missing") + } + } +changed: + tree, err = adapter.CaptureReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + if !findNamedReference(t, tree, "Changed review text").Valid() { + t.Fatal("dirty label retained old provider data") + } +} diff --git a/internal/atspi/review_table_native.go b/internal/atspi/review_table_native.go new file mode 100644 index 0000000..7c49e34 --- /dev/null +++ b/internal/atspi/review_table_native.go @@ -0,0 +1,237 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "context" + "fmt" +) + +// native_review_table_children enumerates a selectable table's viewport, as +// Orca's flat review does. GTK exposes every offscreen row as a child; fetching +// that list creates thousands of transient cell proxies during timeline refresh. +// Returned references belong to the caller. All queries run on the GLib owner. +func native_review_table_children(ctx context.Context, source *C.AtspiAccessible, clip Rectangle) (children []*C.AtspiAccessible, handled bool, err error) { + if !clip.Valid() { + return nil, false, nil + } + table := C.atspi_accessible_get_table_iface(source) + if table == nil { + return nil, false, nil + } + defer C.g_object_unref(C.gpointer(table)) + selection := C.atspi_accessible_get_selection_iface(source) + if selection == nil { + return nil, false, nil + } + defer C.g_object_unref(C.gpointer(selection)) + component := C.atspi_accessible_get_component_iface(source) + if component == nil { + return nil, false, nil + } + defer C.g_object_unref(C.gpointer(component)) + defer func() { + if err != nil { + for _, child := range children { + C.g_object_unref(C.gpointer(child)) + } + children = nil + } + }() + var queryError *C.GError + rows := int(C.atspi_table_get_n_rows(table, &queryError)) + if queryError != nil { + err = nativeError("query review table rows", queryError) + C.g_error_free(queryError) + return nil, true, err + } + columns := int(C.atspi_table_get_n_columns(table, &queryError)) + if queryError != nil { + err = nativeError("query review table columns", queryError) + C.g_error_free(queryError) + return nil, true, err + } + if rows < 0 || columns < 0 { + return nil, true, fmt.Errorf("%w: negative review table dimensions", ErrInvalidTree) + } + // Native focus normalization uses the first selected cell of a uniquely + // selected row. Keep that identity as an anchor when horizontal scrolling + // hides its column; its geometry still excludes it from review output. + if rows > 0 { + if selected := C.atspi_selection_get_selected_child(selection, 0, nil); selected != nil { + children = append(children, selected) + } + } + appendHeaders := func(first, last int) error { + if last-first >= maxTreeNodes { + return fmt.Errorf("%w: visible table exceeds limit %d", ErrInvalidTree, maxTreeNodes) + } + for column := first; column <= last; column++ { + if err := ctx.Err(); err != nil { + return err + } + header := C.atspi_table_get_column_header(table, C.gint(column), nil) + if header == nil { + continue + } + geometry, geometryErr := geometryFromNative(ctx, header) + _, intersects := geometry.Bounds.Intersection(clip) + if geometryErr == nil && geometry.Visible && geometry.Showing && intersects { + children = append(children, header) + } else { + C.g_object_unref(C.gpointer(header)) + } + if geometryErr != nil { + return geometryErr + } + } + return nil + } + if rows == 0 || columns == 0 { + err = appendHeaders(0, columns-1) + return children, true, err + } + // Start just below the table's header. Hit testing avoids walking from row + // zero when the viewport is thousands of rows down the model. A header's + // bounds let us skip directly to its bottom edge. + seedRow, seedColumn := -1, -1 + bottom := int64(clip.Y) + int64(clip.Height) + for y := int64(clip.Y) + 1; y < bottom && seedRow < 0; y++ { + if err := ctx.Err(); err != nil { + return children, true, err + } + for _, x := range []int64{int64(clip.X) + 1, int64(clip.X) + int64(clip.Width)/2} { + child := C.atspi_component_get_accessible_at_point(component, C.gint(x), C.gint(y), C.ATSPI_COORD_TYPE_SCREEN, &queryError) + if queryError != nil { + err = nativeError("locate visible review table cell", queryError) + C.g_error_free(queryError) + if child != nil { + C.g_object_unref(C.gpointer(child)) + } + return children, true, err + } + if child == nil { + continue + } + row, column := -1, -1 + if C.atspi_accessible_get_role(child, nil) == C.ATSPI_ROLE_TABLE_CELL { + if cell := C.atspi_accessible_get_table_cell(child); cell != nil { + var nativeRow, nativeColumn C.gint + C.atspi_table_cell_get_position(cell, &nativeRow, &nativeColumn, &queryError) + if queryError == nil { + row, column = int(nativeRow), int(nativeColumn) + } else { + err = nativeError("query visible review cell position", queryError) + C.g_error_free(queryError) + C.g_object_unref(C.gpointer(cell)) + C.g_object_unref(C.gpointer(child)) + return children, true, err + } + C.g_object_unref(C.gpointer(cell)) + } else { + index := C.atspi_accessible_get_index_in_parent(child, nil) + row = int(C.atspi_table_get_row_at_index(table, index, nil)) + column = int(C.atspi_table_get_column_at_index(table, index, nil)) + } + } + geometry, geometryErr := geometryFromNative(ctx, child) + C.g_object_unref(C.gpointer(child)) + if geometryErr != nil { + return children, true, geometryErr + } + if row >= 0 && row < rows && column >= 0 && column < columns { + seedRow, seedColumn = row, column + break + } + if geometry.BoundsKnown { + y = max(y, int64(geometry.Bounds.Y)+int64(geometry.Bounds.Height)-1) + } + } + } + if seedRow < 0 { + // An empty or clipped body can still have visible column headers. + err = appendHeaders(0, columns-1) + return children, true, err + } + visible := func(row, column int, keep bool) (bool, error) { + if err := ctx.Err(); err != nil { + return false, err + } + child := C.atspi_table_get_accessible_at(table, C.gint(row), C.gint(column), &queryError) + if queryError != nil { + err := nativeError("query visible review table cell", queryError) + C.g_error_free(queryError) + queryError = nil + if child != nil { + C.g_object_unref(C.gpointer(child)) + } + return false, err + } + if child == nil { + return false, nil + } + geometry, geometryErr := geometryFromNative(ctx, child) + _, intersects := geometry.Bounds.Intersection(clip) + showing := geometry.Visible && geometry.Showing && geometry.BoundsKnown && intersects + if keep && showing && geometryErr == nil { + children = append(children, child) + } else { + C.g_object_unref(C.gpointer(child)) + } + return showing, geometryErr + } + firstRow, lastRow := seedRow, seedRow + firstColumn, lastColumn := seedColumn, seedColumn + for _, axis := range []struct { + first, last *int + limit int + row bool + }{{&firstRow, &lastRow, rows, true}, {&firstColumn, &lastColumn, columns, false}} { + for _, step := range []int{-1, 1} { + edge := axis.first + if step > 0 { + edge = axis.last + } + for next := *edge + step; next >= 0 && next < axis.limit; next += step { + if *axis.last-*axis.first >= maxTreeNodes { + return children, true, fmt.Errorf("%w: visible table exceeds limit %d", ErrInvalidTree, maxTreeNodes) + } + row, column := seedRow, seedColumn + if axis.row { + row = next + } else { + column = next + } + showing, err := visible(row, column, false) + if err != nil { + return children, true, err + } + if !showing { + break + } + *edge = next + } + } + } + if err := appendHeaders(firstColumn, lastColumn); err != nil { + return children, true, err + } + for row := firstRow; row <= lastRow; row++ { + for column := firstColumn; column <= lastColumn; column++ { + if len(children) >= maxTreeNodes { + return children, true, fmt.Errorf("%w: visible table exceeds limit %d", ErrInvalidTree, maxTreeNodes) + } + if _, err := visible(row, column, true); err != nil { + return children, true, err + } + } + } + return children, true, nil +} diff --git a/internal/atspi/review_table_native_test.go b/internal/atspi/review_table_native_test.go new file mode 100644 index 0000000..9003d18 --- /dev/null +++ b/internal/atspi/review_table_native_test.go @@ -0,0 +1,217 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "os/exec" + "testing" + "time" +) + +func TestNativeFlatReviewLargeGTKTable(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_REVIEW_TABLE") != "1" { + t.Skip("requires private Xvfb/AT-SPI session") + } + for _, mode := range []string{"large", "small", "empty", "horizontal", "compound"} { + t.Run(mode, func(t *testing.T) { test_native_review_table(t, mode) }) + } +} + +func test_native_review_table(t *testing.T, mode string) { + t.Helper() + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-c", ` +import gi, sys +gi.require_version("Gtk", "3.0") +gi.require_version("Gdk", "3.0") +from gi.repository import Gdk, GLib, Gtk +mode = sys.argv[1] +Gtk.Settings.get_default().set_property("gtk-enable-animations", False) +window = Gtk.Window(title="Flat table review probe") +window.set_default_size(400, 240) +window.connect("destroy", Gtk.main_quit) +store = Gtk.ListStore(str, str, str) +rowCount = {"empty": 0, "small": 2, "horizontal": 20, "compound": 20}.get(mode, 6000) +for index in range(rowCount): + store.append(["Row %04d" % index, "Kind %04d" % index, "Detail %04d" % index]) +view = Gtk.TreeView(model=store) +view.get_accessible().set_name("Review table") +column = Gtk.TreeViewColumn("Items", Gtk.CellRendererText(), text=0) +if mode == "compound": + icon = Gtk.CellRendererPixbuf() + icon.set_property("icon-name", "text-x-generic") + column.pack_start(icon, False) +view.append_column(column) +if mode == "horizontal": + view.append_column(Gtk.TreeViewColumn("Kind", Gtk.CellRendererText(), text=1)) + view.append_column(Gtk.TreeViewColumn("Detail", Gtk.CellRendererText(), text=2)) + for column in view.get_columns(): + column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) + column.set_fixed_width(250) +scroller = Gtk.ScrolledWindow() +scroller.add(view) +window.add(scroller) +window.show_all() +def ready(): + if rowCount: + path = Gtk.TreePath.new_from_indices([rowCount//2]) + column = view.get_columns()[-1] if mode == "horizontal" else None + view.set_cursor(path, column) + view.scroll_to_cell(path, column, True, 0.5, 1) + window.present() + view.grab_focus() + acknowledge_paint("Flat table review ready") + return False +def acknowledge_paint(title): + def painted(clock): + clock.disconnect(handlerId) + window.set_title(title) + handlerId = window.get_frame_clock().connect("after-paint", painted) + window.queue_draw() +GLib.idle_add(ready) +def on_key(_window, event): + if event.keyval == Gdk.KEY_F6: + store[4500][0] = "Updated 4500" + path = Gtk.TreePath.new_from_indices([4500]) + view.set_cursor(path) + view.scroll_to_cell(path, None, True, 0.5, 0) + acknowledge_paint("Flat table review updated") + return True + return False +window.connect("key-press-event", on_key) +Gtk.main() +`, mode) + fixture.Stderr = os.Stderr + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { + _ = fixture.Process.Kill() + _ = fixture.Wait() + }() + if output, err := exec.CommandContext(ctx, "xdotool", "search", "--sync", "--onlyvisible", "--name", "^Flat table review (probe|ready)$", "windowfocus").CombinedOutput(); err != nil { + t.Fatalf("focus fixture: %v: %s", err, output) + } + var focus ObjectID + painted := false + for !focus.Valid() || !painted { + select { + case event := <-adapter.Events(): + painted = painted || event.Source.Name == "Flat table review ready" || event.WindowTitle == "Flat table review ready" + if (event.Source.Role == "table cell" || event.Source.Name == "Review table") && + (event.Type == FocusEvent || event.Type == FocusedStateEvent && event.Detail1 == 1) { + focus = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal("table focus missing") + } + } + captureCtx, captureCancel := context.WithTimeout(ctx, 5*time.Second) + defer captureCancel() + tree, err := adapter.CaptureReviewWindow(captureCtx, focus) + if err != nil { + t.Fatal(err) + } + snapshot, err := tree.ReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + want := "Row 3000" + switch mode { + case "small": + want = "Row 0001" + case "empty": + want = "Items" + case "horizontal": + want = "Detail 0010" + case "compound": + want = "Row 0010" + } + found := false + headerFound := false + visibleNames := make(map[string]bool) + for _, node := range snapshot.Nodes { + if node.Geometry.Visible && node.Geometry.Showing && node.Geometry.BoundsKnown { + visibleNames[node.Snapshot.Name] = true + } + if node.Snapshot.Name == want && node.Geometry.Visible && node.Geometry.Showing && node.Geometry.BoundsKnown { + found = true + } + if node.Snapshot.Role == "table column header" { + headerFound = true + } + if mode == "horizontal" && node.Snapshot.Name == "Row 0010" && len(node.Text.Ranges) != 0 { + t.Fatal("captured text from horizontally hidden focus anchor") + } + } + if !found { + for _, node := range snapshot.Nodes { + t.Logf("node: %q %q geometry=%+v", node.Snapshot.Name, node.Snapshot.Role, node.Geometry) + } + t.Fatalf("visible content %q missing", want) + } + if !headerFound { + t.Fatal("visible column header missing") + } + if mode == "large" && (!visibleNames["Row 2999"] || !visibleNames["Row 3001"]) { + t.Fatal("visible rows adjacent to focus are missing") + } + t.Logf("captured %d viewport objects", len(snapshot.Nodes)) + if len(snapshot.Nodes) > 100 { + t.Fatalf("captured %d nodes for a small table viewport", len(snapshot.Nodes)) + } + if mode != "large" { + return + } + if output, err := exec.CommandContext(ctx, "xdotool", "key", "F6").CombinedOutput(); err != nil { + t.Fatalf("scroll fixture: %v: %s", err, output) + } + updated, painted := false, false + for !updated || !painted { + select { + case event := <-adapter.Events(): + painted = painted || event.Source.Name == "Flat table review updated" || event.WindowTitle == "Flat table review updated" + if event.Source.Name == "Updated 4500" && (event.Type == ActiveDescendantEvent || + event.Type == FocusEvent || event.Type == FocusedStateEvent && event.Detail1 == 1) { + focus = event.Source.ID() + updated = true + } + case <-ctx.Done(): + t.Fatal("updated table focus missing") + } + } + tree, err = adapter.CaptureReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + snapshot, err = tree.ReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + found = false + visibleNames = make(map[string]bool) + for _, node := range snapshot.Nodes { + if node.Geometry.Visible && node.Geometry.Showing && node.Geometry.BoundsKnown { + visibleNames[node.Snapshot.Name] = true + } + if node.Snapshot.Name == "Updated 4500" && node.Geometry.Visible && node.Geometry.Showing && node.Geometry.BoundsKnown { + found = true + } + if node.Snapshot.Name == "Row 3000" && len(node.Text.Ranges) > 0 { + t.Fatal("recapture retained the previous viewport's text") + } + } + if !found || !visibleNames["Row 4499"] || !visibleNames["Row 4501"] || len(snapshot.Nodes) > 100 { + t.Fatalf("updated viewport: found=%t nodes=%d", found, len(snapshot.Nodes)) + } +} diff --git a/internal/atspi/review_test.go b/internal/atspi/review_test.go new file mode 100644 index 0000000..df6e157 --- /dev/null +++ b/internal/atspi/review_test.go @@ -0,0 +1,99 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "context" + "errors" + "testing" +) + +func reviewTree(t *testing.T) (*AccessibleTree, ObjectID) { + t.Helper() + id := func(path string) ObjectID { return NewObjectID(":1.42", path) } + node := func(path, role string, children ...ObjectID) TreeNode { + s := NewSnapshot(path, path, role, "", "") + s.BusName = ":1.42" + return TreeNode{Snapshot: s, Children: children} + } + tree, err := NewAccessibleTree(id("/desktop"), []TreeNode{ + node("/desktop", "desktop frame", id("/window"), id("/other")), + node("/window", "frame", id("/button"), id("/dialog")), + node("/button", "push button"), + node("/dialog", "dialog", id("/entry")), + node("/entry", "entry"), + node("/other", "frame"), + }) + if err != nil { + t.Fatal(err) + } + return tree, id("/button") +} + +func TestReviewWindowScopeAndOwnership(t *testing.T) { + tree, focus := reviewTree(t) + snapshot, err := tree.ReviewWindow(context.Background(), focus) + nodes := snapshot.Nodes + if err != nil { + t.Fatal(err) + } + if len(nodes) != 4 || nodes[0].Snapshot.Path != "/window" || nodes[1].Snapshot.Path != "/button" || nodes[3].Snapshot.Path != "/entry" { + t.Fatalf("unexpected window: %#v", nodes) + } + nodes[0].Children[0] = ObjectID{} + focus.Path = "/entry" + snapshot, err = tree.ReviewWindow(context.Background(), focus) + nodes = snapshot.Nodes + if err != nil || len(nodes) != 2 || nodes[0].Snapshot.Path != "/dialog" { + t.Fatalf("dialog scope: %#v, %v", nodes, err) + } + focus.Path = "/button" + if _, err := tree.ReviewWindow(context.Background(), focus); err != nil { + t.Fatal("caller mutated tree:", err) + } +} + +func TestReviewWindowRejectsStaleDataAndCancellation(t *testing.T) { + for _, tc := range []struct { + name string + invalidate func(*AccessibleTree, ObjectID) + want error + }{ + {"children", func(tree *AccessibleTree, id ObjectID) { tree.InvalidateChildren(id) }, ErrIncompleteTree}, + {"geometry", func(tree *AccessibleTree, id ObjectID) { tree.InvalidateGeometry(id) }, ErrStaleGeometry}, + {"text", func(tree *AccessibleTree, id ObjectID) { tree.InvalidateText(id) }, ErrStaleText}, + } { + t.Run(tc.name, func(t *testing.T) { + tree, focus := reviewTree(t) + tc.invalidate(tree, focus) + if snapshot, err := tree.ReviewWindow(context.Background(), focus); snapshot.Nodes != nil || !errors.Is(err, tc.want) { + t.Fatalf("nodes=%v err=%v", snapshot.Nodes, err) + } + }) + } + tree, focus := reviewTree(t) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := tree.ReviewWindow(ctx, focus); !errors.Is(err, context.Canceled) { + t.Fatal(err) + } + focus.Path = "/desktop" + if _, err := tree.ReviewWindow(context.Background(), focus); !errors.Is(err, ErrNoReviewWindow) { + t.Fatal(err) + } +} diff --git a/internal/atspi/session_native_test.go b/internal/atspi/session_native_test.go new file mode 100644 index 0000000..31c55f5 --- /dev/null +++ b/internal/atspi/session_native_test.go @@ -0,0 +1,47 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +// A private X server represents an available Xwayland connection here. It does +// not establish compositor support, only that X metadata cannot veto AT-SPI. +func TestNativeWaylandForegroundPolicy(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_WAYLAND_POLICY") != "1" { + t.Skip("requires private Xvfb and D-Bus") + } + reader := xorg.OpenForegroundReader() + if reader == nil { + t.Fatal("private X11 display unavailable") + } + reader.Close() + t.Setenv("XDG_SESSION_TYPE", "wayland") + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + adapter := New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stop := context.WithTimeout(context.Background(), 3*time.Second) + defer stop() + if err := adapter.Stop(stopCtx); err != nil { + t.Error(err) + } + }() + if adapter.Foreground().Client.Known { + t.Fatal("X11 foreground used as Wayland desktop authority") + } + if !adapter.matchesForeground(nil, ObjectID{}) { + t.Fatal("missing X11 foreground rejected Wayland accessibility") + } +} diff --git a/internal/atspi/speech_metadata_native.go b/internal/atspi/speech_metadata_native.go new file mode 100644 index 0000000..e7910e2 --- /dev/null +++ b/internal/atspi/speech_metadata_native.go @@ -0,0 +1,151 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#include "adapter_native.h" +*/ +import "C" + +import ( + "strings" + "time" + "unsafe" +) + +func native_mnemonic(source *C.AtspiAccessible) string { + action := C.atspi_accessible_get_action_iface(source) + if action == nil { + return "" + } + defer C.g_object_unref(C.gpointer(action)) + if C.atspi_action_get_n_actions(action, nil) <= 0 { + return "" + } + binding := C.atspi_action_get_key_binding(action, 0, nil) + defer C.g_free(C.gpointer(binding)) + parts := strings.Split(C.GoString(binding), ";") + if len(parts) == 0 { + return "" + } + // AT-SPI's first field is the mnemonic. Empty mnemonic fields must not + // turn an unrelated accelerator into a fabricated mnemonic. + return sanitizeSnapshotField(parts[0]) +} + +func native_misspelled(text *C.AtspiText, offset int) bool { + run := native_text_attribute_run(text, offset) + return TextAttributesMisspelled(run.Values) +} + +func native_text_attribute_run(text *C.AtspiText, offset int) TextAttributeRun { + if offset < 0 { + return TextAttributeRun{} + } + var start, end C.gint + attributes := C.atspi_text_get_attribute_run(text, C.gint(offset), 0, &start, &end, nil) + if attributes == nil { + return TextAttributeRun{} + } + defer C.g_hash_table_unref(attributes) + run := TextAttributeRun{Start: int(start), End: int(end), Values: make(map[string]string)} + for _, key := range spokenCharacterAttributeKeys { + name := C.CString(key) + value := C.g_hash_table_lookup(attributes, C.gconstpointer(unsafe.Pointer(name))) + C.free(unsafe.Pointer(name)) + if value != nil { + run.Values[key] = sanitizeSnapshotField(C.GoString((*C.char)(value))) + } + } + return run +} + +// Each provider request can block. Stop after a bounded number of runs and a +// short deadline; the caret run is still available if a provider is slow. +func native_text_attribute_runs(text *C.AtspiText, start, end int, caret TextAttributeRun) []TextAttributeRun { + if start < 0 || end <= start { + return nil + } + deadline := time.Now().Add(60 * time.Millisecond) + var runs []TextAttributeRun + for offset := start; offset < end && len(runs) < 32 && time.Now().Before(deadline); { + run := caret + if offset < run.Start || offset >= run.End { + run = native_text_attribute_run(text, offset) + } + if run.End <= offset { + break + } + runs = append(runs, run) + offset = run.End + } + return runs +} + +// Queries stay on the GLib owner. This copies only container metadata, bounded +// by depth and time, and never scans children or retains native references. +func native_speech_context(source *C.AtspiAccessible) ([]Snapshot, []Snapshot) { + result := make([]Snapshot, 0) + brailleContext := make([]Snapshot, 0) + speechOpen := true + current := C.atspi_accessible_get_parent(source, nil) + deadline := time.Now().Add(100 * time.Millisecond) + for depth := 0; current != nil && depth < 16 && time.Now().Before(deadline); depth++ { + roleName := C.atspi_accessible_get_role_name(current, nil) + role := C.GoString(roleName) + C.g_free(C.gpointer(roleName)) + if role == "application" || role == "frame" || role == "window" || role == "dialog" { + speechOpen = false + } + id := nativeObjectID(current) + item := Snapshot{BusName: id.BusName, Path: id.Path, Role: role} + name := C.atspi_accessible_get_name(current, nil) + item.Name = sanitizeSnapshotField(C.GoString(name)) + C.g_free(C.gpointer(name)) + if role == "application" { + brailleContext = append(brailleContext, item) + break + } + if speechOpen { + switch role { + case "block quote", "blockquote", "list", "list box", "table", "tree table", "panel", "grouping", "landmark", "form", "section", "document spreadsheet", "link": + if (role == "list" || role == "list box") && time.Now().Before(deadline) { + var childError *C.GError + count := C.atspi_accessible_get_child_count(current, &childError) + item.ChildCount, item.ChildCountKnown = int(count), childError == nil && count >= 0 + if childError != nil { + C.g_error_free(childError) + } + } + if role == "section" || role == "form" || role == "landmark" || role == "table" { + attributes := C.atspi_accessible_get_attributes(current, nil) + if attributes != nil { + for _, field := range []struct { + key string + target *string + }{{"xml-roles", &item.XMLRoles}, {"tag", &item.HTMLTag}} { + key := C.CString(field.key) + *field.target = sanitizeSnapshotField(C.GoString((*C.char)(C.g_hash_table_lookup(attributes, C.gconstpointer(unsafe.Pointer(key)))))) + C.free(unsafe.Pointer(key)) + } + key := C.CString("layout-guess") + item.LayoutTable = C.GoString((*C.char)(C.g_hash_table_lookup(attributes, C.gconstpointer(unsafe.Pointer(key))))) == "true" + C.free(unsafe.Pointer(key)) + C.g_hash_table_unref(attributes) + } + } + result = append(result, item) + } + } + brailleContext = append(brailleContext, item) + parent := C.atspi_accessible_get_parent(current, nil) + C.g_object_unref(C.gpointer(current)) + current = parent + } + if current != nil { + C.g_object_unref(C.gpointer(current)) + } + return result, brailleContext +} diff --git a/internal/atspi/speech_metadata_native_test.go b/internal/atspi/speech_metadata_native_test.go new file mode 100644 index 0000000..7c51857 --- /dev/null +++ b/internal/atspi/speech_metadata_native_test.go @@ -0,0 +1,125 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "os" + "strings" + "testing" + "time" +) + +func TestNativeSpeechMetadata(t *testing.T) { + if os.Getenv("CTHULHU_SPEECH_METADATA") != "1" { + t.Skip("requires private GTK speech fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + adapter := New() + adapter.SetCaptureTextAttributes(true) + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Error(err) + } + }() + for _, probe := range []struct{ key, name string }{{"F9", "Mnemonic probe"}, {"F10", "Indentation probe"}} { + pressTreeProbeKey(t, probe.key) + for { + select { + case <-ctx.Done(): + t.Fatal("missing speech metadata focus event", probe.name) + case event := <-adapter.Events(): + if !((event.Type == FocusEvent || event.Type == FocusedStateEvent) && event.Source.Name == probe.name) { + continue + } + windowContext := false + for _, ancestor := range event.Source.BrailleContext { + if ancestor.Role == "frame" && ancestor.Name != "" { + windowContext = true + } + } + if !windowContext { + t.Fatalf("missing native braille window context: %+v", event.Source.BrailleContext) + } + if probe.key == "F9" { + if !strings.Contains(strings.ToLower(event.Source.Mnemonic), "a") { + t.Fatalf("missing native mnemonic: %q", event.Source.Mnemonic) + } + } else { + if event.Source.BrailleLine != "\t Indented É" { + t.Fatalf("raw indentation lost: %q", event.Source.BrailleLine) + } + found := false + for _, ancestor := range event.Source.SpeechContext { + if (ancestor.Role == "list" || ancestor.Role == "list box") && ancestor.Name == "Dynamic controls" { + if !ancestor.ChildCountKnown || ancestor.ChildCount != 10 { + t.Fatalf("native list count unavailable: %+v", ancestor) + } + found = true + } + } + if !found { + t.Fatalf("missing native list context: %+v", event.Source.SpeechContext) + } + } + goto nextProbe + } + } + nextProbe: + } + pressTreeProbeKey(t, "F11") + for { + select { + case <-ctx.Done(): + t.Fatal("missing color attribute focus event") + case event := <-adapter.Events(): + if (event.Type != FocusEvent && event.Type != FocusedStateEvent) || event.Source.Name != "Color attribute probe" { + continue + } + if len(event.Source.TextAttributeRuns) == 0 || event.Source.TextAttributeRuns[0].Values["fg-color"] == "" { + t.Fatalf("native braille attribute runs missing: %+v", event.Source.TextAttributeRuns) + } + if !event.Source.Misspelled || !TextAttributesMisspelled(event.Source.TextAttributeRuns[0].Values) { + t.Fatalf("native error underline lost its spelling indicator: %+v", event.Source.TextAttributeRuns) + } + attributes, err := adapter.ReadCharacterAttributes(ctx, event.Source.ID()) + if err != nil { + t.Fatal(err) + } + if !TextAttributesMisspelled(attributes.Values) { + t.Fatalf("character attributes lost spelling indicator: %+v", attributes.Values) + } + if color := attributes.Values["fg-color"]; color == "" { + t.Fatalf("native foreground color missing: %+v", attributes.Values) + } else { + t.Logf("native foreground color: %q", color) + } + goto protectedProbe + } + } +protectedProbe: + pressTreeProbeKey(t, "F7") + for { + select { + case <-ctx.Done(): + t.Fatal("missing protected text focus event") + case event := <-adapter.Events(): + if (event.Type != FocusEvent && event.Type != FocusedStateEvent) || event.Source.Name != "Protected text probe" { + continue + } + attributes, err := adapter.ReadCharacterAttributes(ctx, event.Source.ID()) + if err != nil || len(attributes.Values) != 0 { + t.Fatalf("password attributes: %+v, %v", attributes.Values, err) + } + return + } + } +} diff --git a/internal/atspi/tentacle_item_native.go b/internal/atspi/tentacle_item_native.go new file mode 100644 index 0000000..c46b937 --- /dev/null +++ b/internal/atspi/tentacle_item_native.go @@ -0,0 +1,82 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package atspi + +/* +#include "adapter_native.h" +static char *tentacle_attribute(GHashTable *attributes, const char *key) { + return attributes ? g_hash_table_lookup(attributes, key) : NULL; +} +*/ +import "C" +import ( + "context" + "errors" + "strings" + "unsafe" +) + +type TransferItem struct{ Text, Path string } + +// ReadTransferItem reads one current line or one explicit path from the +// foreground object. It never walks descendants or reads password contents. +func (adapter *Adapter) ReadTransferItem(ctx context.Context, object ObjectID, offset int) (TransferItem, error) { + result, err := adapter.documentOperation(ctx, treeCaptureRequest{transferItem: true, reviewFocus: object, positionOffset: offset}) + return result.item, err +} +func (adapter *Adapter) nativeTransferItem(ctx context.Context, object ObjectID, offset int) (TransferItem, error) { + source, _, err := adapter.native_action_source(object) + if err != nil || ctx.Err() != nil { + return TransferItem{}, ErrStaleObject + } + if C.atspi_accessible_get_role(source, nil) == C.ATSPI_ROLE_PASSWORD_TEXT { + return TransferItem{}, errors.New("protected item") + } + attributes := C.atspi_accessible_get_attributes(source, nil) + if attributes != nil { + defer C.g_hash_table_unref(attributes) + for _, key := range []string{"file-uri", "uri", "file-path"} { + rawKey := C.CString(key) + raw := C.tentacle_attribute(attributes, rawKey) + C.free(unsafe.Pointer(rawKey)) + if raw != nil { + path := C.GoString(raw) + if strings.HasPrefix(path, "file:") || strings.HasPrefix(path, "/") { + return TransferItem{Path: path}, nil + } + } + } + } + snapshot := snapshotFromNativeWithCaret(source, false, false, false, false) + // File icons and rows without explicit paths must not become text messages. + if snapshot.Role == "icon" || snapshot.Role == "list item" || snapshot.Role == "table cell" && !snapshot.Spreadsheet { + return TransferItem{}, errors.New("file item does not expose a reliable path") + } + value := snapshot.Name + text := C.atspi_accessible_get_text_iface(source) + if text != nil { + defer C.g_object_unref(C.gpointer(text)) + if offset < 0 { + offset = int(C.atspi_text_get_caret_offset(text, nil)) + if offset < 0 { + offset = 0 + } + } + line := C.cthulhu_text_get_string_at_offset(text, C.gint(offset), C.ATSPI_TEXT_GRANULARITY_LINE, nil) + if line == nil { + return TransferItem{}, errors.New("focused line unavailable") + } + value = C.GoString(line.content) + C.g_free(C.gpointer(line.content)) + C.g_free(C.gpointer(line)) + // Native line delimiters are not part of the message; retain actual spacing. + value = strings.TrimRight(value, "\r\n") + } + if len(value) >= 4096 { + return TransferItem{}, errors.New("focused item exceeds transfer limit") + } + if value == "" { + return TransferItem{}, errors.New("focused item has no text or path") + } + return TransferItem{Text: strings.NewReplacer("\r\n", " ", "\r", " ", "\n", " ").Replace(value)}, nil +} diff --git a/internal/atspi/testdata/text_boundary.c b/internal/atspi/testdata/text_boundary.c new file mode 100644 index 0000000..0095153 --- /dev/null +++ b/internal/atspi/testdata/text_boundary.c @@ -0,0 +1,98 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "adapter_native.h" +#include + +static const gchar *content; +static guint boundaryCalls, characterCalls, textCalls; +static gboolean failProbe, changedText; + +guint atspi_text_get_character_at_offset(AtspiText *text, gint offset, GError **error) { + characterCalls++; + if (failProbe) { + g_set_error_literal(error, g_quark_from_static_string("probe"), 1, "removed text"); + return 0; + } + return offset >= 0 && offset < g_utf8_strlen(content, -1) + ? g_utf8_get_char(g_utf8_offset_to_pointer(content, offset)) : 0; +} + +gint atspi_text_get_character_count(AtspiText *text, GError **error) { + return g_utf8_strlen(content, -1); +} + +gchar *atspi_text_get_text(AtspiText *text, gint start, gint end, GError **error) { + textCalls++; + if (changedText) return g_strdup(""); + g_assert_cmpint(start, >=, 0); + g_assert_cmpint(end - start, <=, 4096); + g_assert_cmpint(end, <=, g_utf8_strlen(content, -1)); + const gchar *first = g_utf8_offset_to_pointer(content, start); + return g_strndup(first, g_utf8_offset_to_pointer(content, end) - first); +} + +AtspiTextRange *atspi_text_get_string_at_offset(AtspiText *text, gint offset, + AtspiTextGranularity unit, GError **error) { + boundaryCalls++; + // Model the verified browser failure: asking for LINE at the final + // ellipsis aborts inside the provider, before it can return a bad range. + if (unit == ATSPI_TEXT_GRANULARITY_LINE && offset >= 0 && + offset == g_utf8_strlen(content, -1) - 1) { + g_assert_cmpuint(g_utf8_get_char(g_utf8_offset_to_pointer(content, offset)), !=, 0x2026); + } + AtspiTextRange *range = g_new0(AtspiTextRange, 1); + range->end_offset = g_utf8_strlen(content, -1); + range->content = g_strdup(content); + return range; +} + +static void assert_range(const gchar *value, gint offset, AtspiTextGranularity unit, + gint start, gint end, const gchar *expected, guint calls) { + content = value; + boundaryCalls = characterCalls = textCalls = 0; + GError *error = NULL; + AtspiTextRange *range = cthulhu_text_get_string_at_offset(NULL, offset, unit, &error); + g_assert_no_error(error); + g_assert_nonnull(range); + g_assert_cmpint(range->start_offset, ==, start); + g_assert_cmpint(range->end_offset, ==, end); + g_assert_cmpstr(range->content, ==, expected); + g_assert_cmpuint(boundaryCalls, ==, calls); + if (unit != ATSPI_TEXT_GRANULARITY_LINE || offset < 0) g_assert_cmpuint(characterCalls, ==, 0); + g_assert_cmpuint(textCalls, ==, calls == 0 ? 1 : 0); + g_free(range->content); + g_free(range); +} + +int main(void) { + assert_range("Truncated text…", 14, ATSPI_TEXT_GRANULARITY_LINE, 0, 15, "Truncated text…", 0); + assert_range("…", 0, ATSPI_TEXT_GRANULARITY_LINE, 0, 1, "…", 0); + assert_range("First\n猫🐈…", 8, ATSPI_TEXT_GRANULARITY_LINE, 6, 9, "猫🐈…", 0); + assert_range("Ordinary text", 12, ATSPI_TEXT_GRANULARITY_LINE, 0, 13, "Ordinary text", 1); + assert_range("An… inside", 2, ATSPI_TEXT_GRANULARITY_LINE, 0, 10, "An… inside", 1); + assert_range("Text…", 4, ATSPI_TEXT_GRANULARITY_CHAR, 0, 5, "Text…", 1); + assert_range("Text…", 4, ATSPI_TEXT_GRANULARITY_WORD, 0, 5, "Text…", 1); + assert_range("Text…", -1, ATSPI_TEXT_GRANULARITY_LINE, 0, 5, "Text…", 1); + gchar *prefix = g_strnfill(5000, 'x'); + gchar *longText = g_strconcat(prefix, "…", NULL); + assert_range(longText, 5000, ATSPI_TEXT_GRANULARITY_LINE, 905, 5001, longText + 905, 0); + g_free(prefix); + g_free(longText); + + content = "Changed…"; + boundaryCalls = 0; + changedText = TRUE; + GError *error = NULL; + g_assert_null(cthulhu_text_get_string_at_offset(NULL, 7, ATSPI_TEXT_GRANULARITY_LINE, &error)); + g_assert_no_error(error); + g_assert_cmpuint(boundaryCalls, ==, 0); + changedText = FALSE; + failProbe = TRUE; + g_assert_null(cthulhu_text_get_string_at_offset(NULL, 7, ATSPI_TEXT_GRANULARITY_LINE, &error)); + g_assert_nonnull(error); + g_assert_cmpuint(boundaryCalls, ==, 0); + g_clear_error(&error); + return 0; +} diff --git a/internal/atspi/text.go b/internal/atspi/text.go new file mode 100644 index 0000000..2236979 --- /dev/null +++ b/internal/atspi/text.go @@ -0,0 +1,552 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "context" + "errors" + "math" + "strings" + "unicode" + "unicode/utf8" +) + +const ( + // A large terminal viewport can contain thousands of padded cells. + // Keep the per-line query and web line-repair budgets independently small. + maxReviewCharacters = 1 << 16 + maxReviewLineCharacters = 4096 + maxReviewRanges = 256 + maxTreeTextBytes = 1 << 20 + maxReviewBoundsCharacters = 128 +) + +var ErrStaleText = errors.New("accessible text requires recapture") + +var errReviewLineTooLong = errors.New("review line requires viewport retrieval") + +// TextCaptureIssue describes omitted text without retaining provider content. +type TextCaptureIssue string + +const ( + TextViewportUnavailable TextCaptureIssue = "viewport-unavailable" + TextCharacterLimit TextCaptureIssue = "character-limit" + TextRangeLimit TextCaptureIssue = "range-limit" + TextTreeLimit TextCaptureIssue = "tree-byte-limit" + TextProviderFailure TextCaptureIssue = "text-provider-failure" + TextViewportScanLimit TextCaptureIssue = "viewport-query-limit" +) + +// TextRange owns exact UTF-8 text and AT-SPI character offsets [Start, End). +// Bounds are clipped screen coordinates. Offsets count Unicode code points, +// not bytes or grapheme clusters. Embedded objects have their own tree nodes. +type TextRange struct { + Start, End int + Text string + Bounds Rectangle +} + +// VisibleText distinguishes a complete capture from unavailable or oversized +// text. A limited capture contains no partial ranges. Known empty text is valid. +// Visibility describes component clipping, not occlusion by other windows. +type VisibleText struct { + Known bool + Limited bool + Issue TextCaptureIssue + Ranges []TextRange + CaretKnown bool + CaretOffset int +} + +func (text VisibleText) valid(geometry Geometry) bool { + if text.CaretKnown && (!text.Known || text.CaretOffset < 0) || !text.CaretKnown && text.CaretOffset != 0 { + return false + } + if text.Known && (text.Limited || text.Issue != "") || !text.Known && len(text.Ranges) != 0 || len(text.Ranges) > maxReviewRanges { + return false + } + if text.Known && !geometry.BoundsKnown { + return false + } + previous, characters := 0, 0 + for _, r := range text.Ranges { + // Native offsets can include arbitrarily long offscreen scrollback. + // Bound the captured characters, not their absolute source offsets. + if r.Start < previous || r.End <= r.Start || !utf8.ValidString(r.Text) || utf8.RuneCountInString(r.Text) != r.End-r.Start || strings.ContainsRune(r.Text, '\ufffc') { + return false + } + // A newline-only range represents a blank visual row. Mixed text + // and line breaks must still be split by the capture provider. + if strings.ContainsAny(r.Text, "\n\r") && strings.Trim(r.Text, "\n\r") != "" { + return false + } + clipped, ok := r.Bounds.Intersection(geometry.Bounds) + if !ok || clipped != r.Bounds { + return false + } + previous = r.End + characters += r.End - r.Start + } + return characters <= maxReviewCharacters +} + +func (tree *AccessibleTree) VisibleText(reference ObjectReference) (VisibleText, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + entry, err := tree.resolveLocked(reference) + if err != nil { + return VisibleText{}, err + } + if entry.textInvalid || entry.geometryInvalid { + return VisibleText{}, ErrStaleText + } + text := entry.text + text.Ranges = append([]TextRange(nil), text.Ranges...) + return text, nil +} + +// InvalidateText preserves identity and geometry. Layout invalidation also +// invalidates text via geometryInvalid, including every moved descendant. +func (tree *AccessibleTree) InvalidateText(id ObjectID) int { + tree.mu.Lock() + defer tree.mu.Unlock() + entry, ok := tree.nodes[id] + if !ok || entry.textInvalid { + return 0 + } + entry.textInvalid = true + entry.text = VisibleText{} + tree.nodes[id] = entry + return 1 +} + +type reviewTextSource interface { + count(context.Context) (int, error) + line(context.Context, int) (TextRange, error) + bounds(context.Context, int, int) (Rectangle, error) +} + +// Optional spatial retrieval avoids requesting an entire enormous native line. +// Implementations must bound copied characters and ranges before returning. +type reviewViewportSource interface { + viewport(context.Context, int, int, Rectangle) ([]TextRange, error) +} + +// bounded_review_bounds preserves the full range's bounding rectangle without +// asking a provider to measure thousands of characters in one synchronous call. +// GTK text cells can exceed libatspi's timeout on such requests. Union every +// chunk rather than inferring bounds from endpoints, which would lose bidi runs. +func bounded_review_bounds(ctx context.Context, start, end int, query func(context.Context, int, int) (Rectangle, error)) (Rectangle, error) { + var bounds Rectangle + for offset := start; offset < end; { + if err := ctx.Err(); err != nil { + return Rectangle{}, err + } + next := offset + min(end-offset, maxReviewBoundsCharacters) + chunk, err := query(ctx, offset, next) + if err != nil { + return Rectangle{}, err + } + offset = next + // Formatting characters can have no rectangle; other chunks still + // contribute to the complete range, just as in the provider's union. + if !chunk.Valid() { + continue + } + if !bounds.Valid() { + bounds = chunk + continue + } + left, top := min(bounds.X, chunk.X), min(bounds.Y, chunk.Y) + right := max(int64(bounds.X)+int64(bounds.Width), int64(chunk.X)+int64(chunk.Width)) + bottom := max(int64(bounds.Y)+int64(bounds.Height), int64(chunk.Y)+int64(chunk.Height)) + if right-int64(left) > math.MaxInt32 || bottom-int64(top) > math.MaxInt32 { + return Rectangle{}, errors.New("review range bounds exceed coordinate limits") + } + bounds = Rectangle{left, top, int32(right - int64(left)), int32(bottom - int64(top))} + } + return bounds, ctx.Err() +} + +// VTE can report UTF-8 bytes as its character count while its text and line +// methods use character offsets. Locate the actual end with bounded single- +// character queries, without copying or scanning terminal scrollback. +func terminalCharacterCount(ctx context.Context, reported int, exists func(context.Context, int) (bool, error)) (int, error) { + if reported <= 0 { + return reported, ctx.Err() + } + present, err := exists(ctx, reported-1) + if err != nil || present { + return reported, err + } + low, high := 0, reported-1 + for low < high { + if err := ctx.Err(); err != nil { + return 0, err + } + middle := low + (high-low)/2 + present, err := exists(ctx, middle) + if err != nil { + return 0, err + } + if present { + low = middle + 1 + } else { + high = middle + } + } + return low, ctx.Err() +} + +// captureVisibleText finds the visible portion of native text before walking +// its visual lines. This avoids starting at an offscreen terminal scrollback +// offset: some terminal providers return the first on-screen line when asked +// for offset zero, with a later reported start offset. +func captureVisibleText(ctx context.Context, source reviewTextSource, clip Rectangle) (VisibleText, error) { + unknown := VisibleText{} + if err := ctx.Err(); err != nil { + return unknown, err + } + count, err := source.count(ctx) + if err != nil { + return unknown, err + } + if count < 0 { + return unknown, errors.New("negative review character count") + } + start, end, err := visibleTextOffsets(ctx, source, count, clip) + if err != nil && count > maxReviewCharacters { + if ctx.Err() != nil { + return unknown, ctx.Err() + } + start, end, err = visible_line_offsets(ctx, source, count, clip) + } + if err != nil { + if ctx.Err() != nil { + return unknown, ctx.Err() + } + if count > maxReviewCharacters { + return capture_review_viewport(ctx, source, count, clip, TextViewportUnavailable) + } + // Some otherwise usable GTK text providers do not expose per-character + // extents. Retain the established bounded line capture for those small + // objects; large providers still need a viewport to avoid scrollback. + start, end = 0, count + } + if end-start > maxReviewCharacters { + if spatial, ok := source.(reviewViewportSource); ok { + ranges, spatialErr := spatial.viewport(ctx, start, end, clip) + if spatialErr == nil && len(ranges) > 0 { + return capture_review_lines(ctx, source, count, 0, count, clip, ranges) + } + if errors.Is(spatialErr, errReviewViewportScanLimit) { + return VisibleText{Limited: true, Issue: TextViewportScanLimit}, ctx.Err() + } + if ctx.Err() != nil { + return unknown, ctx.Err() + } + } + } + if end-start > maxReviewCharacters { + return VisibleText{Limited: true, Issue: TextCharacterLimit}, nil + } + return capture_review_lines(ctx, source, count, start, end, clip, nil) +} + +func capture_review_lines(ctx context.Context, source reviewTextSource, count, start, end int, clip Rectangle, spatial []TextRange) (VisibleText, error) { + unknown := VisibleText{} + if spatial != nil { + if err := validate_viewport_ranges(spatial, count); err != nil { + return unknown, err + } + spatial = split_viewport_lines(spatial) + } + result := VisibleText{Known: true} + characters := 0 + for offset, lines := start, 0; offset < end; lines++ { + if err := ctx.Err(); err != nil { + return unknown, err + } + if spatial != nil && lines == len(spatial) { + break + } + if lines >= maxReviewRanges { + return VisibleText{Limited: true, Issue: TextRangeLimit}, nil + } + var line TextRange + var err error + if spatial != nil { + line = spatial[lines] + if line.Start < offset { + return unknown, errors.New("unordered review viewport ranges") + } + offset = line.Start + } else { + line, err = source.line(ctx, offset) + } + if errors.Is(err, errReviewLineTooLong) { + return capture_review_viewport(ctx, source, count, clip, TextCharacterLimit) + } + if err != nil { + return unknown, err + } + // Some AT-SPI providers return a line whose reported start is just + // after the requested offset. Python Cthulhu retries one character + // earlier for that provider quirk before rejecting the capture. + if spatial == nil && line.Start > offset && offset > 0 { + line, err = source.line(ctx, offset-1) + if err != nil { + return unknown, err + } + } + if line.Start < 0 || line.Start > offset || line.End <= offset || line.End > count || len(line.Text) > maxReviewCharacters*utf8.UTFMax || !utf8.ValidString(line.Text) || utf8.RuneCountInString(line.Text) != line.End-line.Start { + return unknown, errors.New("invalid review line offsets or content") + } + lineStart := max(line.Start, offset) + lineEnd := min(line.End, end) + characters += lineEnd - lineStart + if characters > maxReviewCharacters { + return VisibleText{Limited: true, Issue: TextCharacterLimit}, nil + } + runes := []rune(line.Text)[lineStart-line.Start : lineEnd-line.Start] + // Python retains newline-only TextZones. Keep their exact offsets and + // native bounds so empty terminal rows remain navigable and speak blank. + blankLine := len(runes) > 0 && strings.Trim(string(runes), "\n\r") == "" + for start := 0; start < len(runes); { + if !blankLine && (runes[start] == '\n' || runes[start] == '\r') || runes[start] == '\ufffc' { + start++ + continue + } + end := start + 1 + if blankLine { + // Some terminal providers combine consecutive empty visual rows + // into one newline-only line range. Preserve each row as its own + // range so line review can advance through all of them. Treat CRLF + // as one row rather than two. + if runes[start] == '\r' && end < len(runes) && runes[end] == '\n' { + end++ + } + } else { + for end < len(runes) && runes[end] != '\n' && runes[end] != '\r' && runes[end] != '\ufffc' { + end++ + } + } + bounds, err := source.bounds(ctx, lineStart+start, lineStart+end) + if err != nil { + return unknown, err + } + if !bounds.Valid() { + return unknown, errors.New("unavailable review line geometry") + } + clipped, visible := bounds.Intersection(clip) + singleRow := true + if spatial != nil && visible && end-start > 1 { + first, firstErr := source.bounds(ctx, lineStart+start, lineStart+start+1) + last, lastErr := source.bounds(ctx, lineStart+end-1, lineStart+end) + if firstErr != nil || lastErr != nil { + return unknown, errors.Join(firstErr, lastErr) + } + singleRow = first.Valid() && last.Valid() && first.Y == last.Y && first.Height == last.Height + } + if visible && singleRow && (clipped == bounds || clipped.X == bounds.X && clipped.Width == bounds.Width) { + // Vertical clipping of one visual row does not hide letters. + // This also supports providers with only line rectangles. + result.Ranges = append(result.Ranges, TextRange{lineStart + start, lineStart + end, string(runes[start:end]), clipped}) + } else if visible { + // A clipped rectangle alone cannot hide offscreen characters. Check each + // visible character, preserving disjoint spans. Reject offscreen blocks + // first so a horizontally clipped long line does not require thousands + // of individual provider calls. Test every block for bidi text. + // Keep consecutive visible characters on the same visual row in + // one range. The budget bounds spans, not individual glyphs. + // Flush at an offset gap so bidi runs never include hidden text. + spanStart, spanEnd := -1, -1 + var spanBounds Rectangle + flushSpan := func() { + if spanStart >= 0 { + result.Ranges = append(result.Ranges, TextRange{lineStart + spanStart, lineStart + spanEnd, string(runes[spanStart:spanEnd]), spanBounds}) + spanStart = -1 + } + } + for blockStart := start; blockStart < end; { + blockEnd := blockStart + min(end-blockStart, maxReviewBoundsCharacters) + if end-start > maxReviewBoundsCharacters { + blockBounds, err := source.bounds(ctx, lineStart+blockStart, lineStart+blockEnd) + if err != nil { + return unknown, err + } + if _, ok := blockBounds.Intersection(clip); !ok { + blockStart = blockEnd + continue + } + } + for i := blockStart; i < blockEnd; i++ { + if err := ctx.Err(); err != nil { + return unknown, err + } + charBounds, err := source.bounds(ctx, lineStart+i, lineStart+i+1) + if err != nil { + return unknown, err + } + charClip, ok := charBounds.Intersection(clip) + if !charBounds.Valid() && spanEnd == i && spanStart >= 0 && review_cluster_continuation(runes[i]) { + // Combining marks and joiners belong to the visible base + // even when they have no independent glyph rectangle. + charClip, ok = spanBounds, true + } + if ok { + if spanStart >= 0 && (spanEnd != i || spanBounds.Y != charClip.Y || spanBounds.Height != charClip.Height) { + flushSpan() + } + if spanStart < 0 { + spanStart, spanBounds = i, charClip + } else { + left := min(spanBounds.X, charClip.X) + right := max(int64(spanBounds.X)+int64(spanBounds.Width), int64(charClip.X)+int64(charClip.Width)) + spanBounds.X, spanBounds.Width = left, int32(right-int64(left)) + } + spanEnd = i + 1 + } + if len(result.Ranges) > maxReviewRanges { + return VisibleText{Limited: true, Issue: TextRangeLimit}, nil + } + } + blockStart = blockEnd + } + flushSpan() + } + if len(result.Ranges) > maxReviewRanges { + return VisibleText{Limited: true, Issue: TextRangeLimit}, nil + } + start = end + } + offset = max(line.End, offset+1) + } + return result, ctx.Err() +} + +func review_cluster_continuation(character rune) bool { + return unicode.IsMark(character) || character == '\u200c' || character == '\u200d' +} + +// visibleTextOffsets uses character extents only to locate the native viewport; +// the returned text remains line-based. AT-SPI text offsets are ordered by +// visual rows for the providers supported by flat review, allowing bounded +// binary searches instead of a scan through terminal scrollback. +func visibleTextOffsets(ctx context.Context, source reviewTextSource, count int, clip Rectangle) (int, int, error) { + if count == 0 { + return 0, 0, nil + } + if !clip.Valid() { + return 0, 0, errors.New("invalid review text clip") + } + bottom := int64(clip.Y) + int64(clip.Height) + first, err := searchTextOffset(ctx, source, count, func(bounds Rectangle) bool { + return int64(bounds.Y)+int64(bounds.Height) > int64(clip.Y) + }) + if err != nil { + return 0, 0, err + } + if first == count { + return count, count, nil + } + end, err := searchTextOffset(ctx, source, count, func(bounds Rectangle) bool { + return int64(bounds.Y) >= bottom + }) + if err != nil { + return 0, 0, err + } + if end < first { + return 0, 0, errors.New("invalid review text viewport order") + } + return first, end, nil +} + +func searchTextOffset(ctx context.Context, source reviewTextSource, count int, after func(Rectangle) bool) (int, error) { + low, high := 0, count + for low < high { + if err := ctx.Err(); err != nil { + return 0, err + } + middle := low + (high-low)/2 + bounds, err := source.bounds(ctx, middle, middle+1) + if err != nil { + return 0, err + } + if !bounds.Valid() { + return 0, errors.New("invalid review character bounds") + } + if after(bounds) { + high = middle + } else { + low = middle + 1 + } + } + return low, nil +} + +// recover_review_component distinguishes synthetic Text interfaces from failed +// text-bearing objects. It never invents offsets or uses editable values as names. +// A label is usable only when it exactly matches the bounded native text and the +// component is fully inside the clip. Embedded-only text belongs to children. +func recover_review_component(ctx context.Context, source interface { + reviewTextSource + reviewSpanSource +}, snapshot Snapshot, geometry Geometry, clip Rectangle) (VisibleText, bool) { + if snapshot.Editable { + return VisibleText{}, false + } + label := false + switch snapshot.Role { + case "button", "push button", "toggle button", "check box", "radio button", "page tab", + "menu item", "check menu item", "radio menu item", "link", "label", "static", "separator": + label = true + case "frame", "panel", "tool bar", "page tab list", "alert", "menu", "menu bar": + default: + return VisibleText{}, false + } + count, err := source.count(ctx) + if err != nil || count <= 0 || count > maxReviewLineCharacters { + return VisibleText{}, false + } + var content strings.Builder + for start := 0; start < count; { + end := start + min(count-start, maxReviewBoundsCharacters) + span, err := source.text_span(ctx, start, end) + if err != nil || !utf8.ValidString(span) || utf8.RuneCountInString(span) != end-start { + return VisibleText{}, false + } + content.WriteString(span) + start = end + } + if ctx.Err() != nil { + return VisibleText{}, false + } + value := content.String() + if strings.Trim(value, "\ufffc") == "" { + // Review will visit the embedded children and count unavailable + // subtrees separately. No text of this object's own was lost. + return VisibleText{Known: true}, true + } + if label && snapshot.Name != "" && value == snapshot.Name && geometry.BoundsKnown && geometry.Bounds == clip { + // Leave text unknown: layout uses the existing synthetic name path + // only if children do not already supply displayed content. + return VisibleText{}, true + } + return VisibleText{}, false +} diff --git a/internal/atspi/text_attributes.go b/internal/atspi/text_attributes.go new file mode 100644 index 0000000..d2b0bfb --- /dev/null +++ b/internal/atspi/text_attributes.go @@ -0,0 +1,18 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +// TextAttributesMisspelled recognizes provider spelling markers for native +// snapshots, character-attribute speech, and braille. Python Cthulhu also +// recognizes the error/spelling underline values used by some toolkits. +func TextAttributesMisspelled(values map[string]string) bool { + for _, key := range []string{"invalid", "invalid-spelling", "text-spelling", "spelling"} { + value := values[key] + if value == "spelling" || key != "invalid" && (value == "true" || value == "misspelled") { + return true + } + } + return values["underline"] == "error" || values["underline"] == "spelling" +} diff --git a/internal/atspi/text_boundary_test.go b/internal/atspi/text_boundary_test.go new file mode 100644 index 0000000..38a8c75 --- /dev/null +++ b/internal/atspi/text_boundary_test.go @@ -0,0 +1,29 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func TestTextBoundaryAvoidsProviderEllipsisAbort(t *testing.T) { + flags, err := exec.Command("pkg-config", "--cflags", "--libs", "atspi-2").CombinedOutput() + if err != nil { + t.Fatalf("native text dependencies: %v: %s", err, flags) + } + binary := filepath.Join(t.TempDir(), "text-boundary") + args := []string{"-Wall", "-Wextra", "-Werror", "-Wno-unused-parameter", "-I.", + "adapter_text_boundary.c", "testdata/text_boundary.c", "-o", binary} + args = append(args, strings.Fields(string(flags))...) + if output, err := exec.Command("cc", args...).CombinedOutput(); err != nil { + t.Fatalf("compile native boundary regression: %v: %s", err, output) + } + if output, err := exec.Command(binary).CombinedOutput(); err != nil { + t.Fatalf("native boundary regression: %v: %s", err, output) + } +} diff --git a/internal/atspi/text_bounds_test.go b/internal/atspi/text_bounds_test.go new file mode 100644 index 0000000..02591c9 --- /dev/null +++ b/internal/atspi/text_bounds_test.go @@ -0,0 +1,119 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "errors" + "strings" + "testing" +) + +type longReviewText struct { + runes []rune + queries int + largest int +} + +func (source *longReviewText) count(context.Context) (int, error) { return len(source.runes), nil } +func (source *longReviewText) line(context.Context, int) (TextRange, error) { + return TextRange{Start: 0, End: len(source.runes), Text: string(source.runes)}, nil +} +func (source *longReviewText) bounds(ctx context.Context, start, end int) (Rectangle, error) { + return bounded_review_bounds(ctx, start, end, func(_ context.Context, first, last int) (Rectangle, error) { + source.queries++ + source.largest = max(source.largest, last-first) + if last-first > 128 { + return Rectangle{}, errors.New("provider timed out measuring a long range") + } + return Rectangle{X: int32(first * 10), Width: int32((last - first) * 10), Height: 20}, nil + }) +} + +func TestCaptureVisibleTextBoundsLongHorizontalLine(t *testing.T) { + source := &longReviewText{runes: []rune(strings.Repeat("é猫", 1712))} + clip := Rectangle{X: 1000, Width: 300, Height: 20} + got, err := captureVisibleText(context.Background(), source, clip) + if err != nil || !got.Known || got.Limited { + t.Fatalf("long line: %+v, %v", got, err) + } + var spoken strings.Builder + for _, part := range got.Ranges { + if part.Start < 100 || part.End > 130 { + t.Fatalf("offscreen range retained: %+v", part) + } + spoken.WriteString(part.Text) + } + if spoken.String() != string(source.runes[100:130]) || source.largest > 128 || source.queries > 400 { + t.Fatalf("clipping: text_bytes=%d largest_query=%d queries=%d", spoken.Len(), source.largest, source.queries) + } + if !got.valid(Geometry{BoundsKnown: true, Bounds: clip}) { + t.Fatal("long clipped line violates owned text invariants") + } +} + +func TestBoundedReviewBoundsIncludesInteriorAndEmptyChunks(t *testing.T) { + rectangles := []Rectangle{{X: 500, Width: 100, Height: 20}, {X: -50, Width: 300, Height: 20}, {}, {X: 400, Width: 50, Height: 20}} + queries := 0 + got, err := bounded_review_bounds(context.Background(), 0, 512, func(_ context.Context, start, end int) (Rectangle, error) { + if end-start > 128 { + t.Fatalf("oversized query: %d", end-start) + } + queries++ + return rectangles[start/128], nil + }) + if err != nil || got != (Rectangle{X: -50, Width: 650, Height: 20}) || queries != 4 { + t.Fatalf("union lost interior bidi or empty chunks: %+v, %v, queries=%d", got, err, queries) + } +} + +func TestBoundedReviewBoundsStopsOnFailureOrCancellation(t *testing.T) { + providerError := errors.New("provider unavailable") + if _, err := bounded_review_bounds(context.Background(), 0, 512, func(context.Context, int, int) (Rectangle, error) { + return Rectangle{}, providerError + }); !errors.Is(err, providerError) { + t.Fatalf("provider error hidden: %v", err) + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + queries := 0 + _, err := bounded_review_bounds(ctx, 0, 512, func(context.Context, int, int) (Rectangle, error) { + queries++ + cancel() + return Rectangle{Width: 100, Height: 20}, nil + }) + if !errors.Is(err, context.Canceled) || queries != 1 { + t.Fatalf("cancellation: %v queries=%d", err, queries) + } +} + +// Even a block entirely inside the viewport can contain zero-area glyphs. +// A horizontally clipped line must retain its existing per-glyph exclusions. +type zeroGlyphReviewText struct{ longReviewText } + +func (source *zeroGlyphReviewText) bounds(ctx context.Context, start, end int) (Rectangle, error) { + if start == 5 && end == 6 { + return Rectangle{}, ctx.Err() + } + return source.longReviewText.bounds(ctx, start, end) +} + +func TestCaptureVisibleTextClippedInteriorBlockExcludesZeroAreaGlyph(t *testing.T) { + source := &zeroGlyphReviewText{longReviewText: longReviewText{runes: []rune(strings.Repeat("x", 400))}} + got, err := captureVisibleText(context.Background(), source, Rectangle{Width: 2000, Height: 20}) + if err != nil || !got.Known || got.Limited { + t.Fatalf("capture: %+v, %v", got, err) + } + characters := 0 + for _, span := range got.Ranges { + if span.Start <= 5 && span.End > 5 { + t.Fatalf("zero-area glyph included: %+v", span) + } + characters += span.End - span.Start + } + if characters != 199 { + t.Fatalf("visible characters=%d, want 199", characters) + } +} diff --git a/internal/atspi/text_component_test.go b/internal/atspi/text_component_test.go new file mode 100644 index 0000000..86e2f0e --- /dev/null +++ b/internal/atspi/text_component_test.go @@ -0,0 +1,54 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "strings" + "testing" + "unicode/utf8" +) + +func TestReviewComponentRecoveryRequiresVerifiedContent(t *testing.T) { + clip := Rectangle{Width: 200, Height: 20} + for _, tc := range []struct { + name, role, native, label string + editable, clipped, want, known bool + }{ + {name: "named toolbar control", role: "button", native: "Back", label: "Back", want: true}, + {name: "named separator", role: "separator", native: "Separator", label: "Separator", want: true}, + {name: "named label", role: "static", native: "Café 猫", label: "Café 猫", want: true}, + {name: "child-only container", role: "panel", native: "\ufffc\ufffc", want: true, known: true}, + {name: "child-only tab", role: "page tab", native: "\ufffc", label: "Tab metadata", want: true, known: true}, + {name: "mixed container", role: "panel", native: "Text\ufffc", label: "Text"}, + {name: "mismatched name", role: "button", native: "Visible", label: "Other"}, + {name: "editable field", role: "entry", native: "Visible", label: "Visible", editable: true}, + {name: "readonly field", role: "entry", native: "Visible", label: "Visible"}, + {name: "password", role: "password text", native: "Secret", label: "Secret"}, + {name: "terminal", role: "terminal", native: "Text", label: "Text"}, + {name: "clipped label", role: "static", native: "Hidden suffix", label: "Hidden suffix", clipped: true}, + {name: "oversized label", role: "button", native: strings.Repeat("x", maxReviewLineCharacters+1), label: strings.Repeat("x", maxReviewLineCharacters+1)}, + } { + t.Run(tc.name, func(t *testing.T) { + source := &pointReviewText{fakeReviewText: fakeReviewText{characters: utf8.RuneCountInString(tc.native)}, textByOffset: map[int]string{}} + for i, r := range []rune(tc.native) { + source.textByOffset[i] = string(r) + } + geometry := Geometry{Bounds: clip, BoundsKnown: true} + if tc.clipped { + geometry.Bounds.Width++ + } + got, ok := recover_review_component(context.Background(), source, Snapshot{Role: tc.role, Name: tc.label, Editable: tc.editable}, geometry, clip) + if ok != tc.want || got.Known != tc.known || len(got.Ranges) != 0 || got.CaretKnown { + t.Fatalf("recovery = %+v, %v", got, ok) + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, ok := recover_review_component(ctx, source, Snapshot{Role: tc.role, Name: tc.label}, geometry, clip); ok { + t.Fatal("recovered canceled request") + } + }) + } +} diff --git a/internal/atspi/text_native.go b/internal/atspi/text_native.go new file mode 100644 index 0000000..153fbd3 --- /dev/null +++ b/internal/atspi/text_native.go @@ -0,0 +1,326 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +/* +#cgo pkg-config: atspi-2 +#include "adapter_native.h" +#include +// Bound the Go copy even when an application returns an oversized line. +static int review_text_length(const gchar *text, int limit) { + if (!text) return -1; + return (int)strnlen(text, limit + 1); +} +*/ +import "C" + +import ( + "context" + "errors" + "strings" + "time" + "unicode/utf8" +) + +// Expansion follows ScriptUtilities.expandEOCs for the captured line only. +// All native references stay on the GLib owner. Bound nested provider work +// and output separately; one native call is also bounded by libatspi's timeout. +type embeddedTextBudget struct { + nodes, characters int + deadline time.Time +} + +func expandNativeEmbeddedText(source *C.AtspiAccessible, content string, start, depth int, budget *embeddedTextBudget) string { + var result strings.Builder + offset := start - 1 + for _, char := range content { + offset++ + if budget.characters <= 0 { + break + } + if char != '\ufffc' { + result.WriteRune(char) + budget.characters-- + continue + } + if depth >= 8 || budget.nodes <= 0 || time.Now().After(budget.deadline) { + continue + } + budget.nodes-- + result.WriteString(expandNativeEmbeddedChild(source, offset, depth+1, budget)) + } + return result.String() +} + +func expandNativeEmbeddedChild(source *C.AtspiAccessible, offset, depth int, budget *embeddedTextBudget) string { + hypertext := C.atspi_accessible_get_hypertext_iface(source) + if hypertext == nil { + return "" + } + defer C.g_object_unref(C.gpointer(hypertext)) + var nativeErr *C.GError + index := C.atspi_hypertext_get_link_index(hypertext, C.gint(offset), &nativeErr) + if nativeErr != nil { + C.g_error_free(nativeErr) + return "" + } + if index < 0 { + return "" + } + link := C.atspi_hypertext_get_link(hypertext, index, nil) + if link == nil { + return "" + } + defer C.g_object_unref(C.gpointer(link)) + child := C.atspi_hyperlink_get_object(link, 0, nil) + if child == nil { + return "" + } + defer C.g_object_unref(C.gpointer(child)) + role := C.atspi_accessible_get_role(child, nil) + if role == C.ATSPI_ROLE_PASSWORD_TEXT { + return "" + } + text := C.atspi_accessible_get_text_iface(child) + if text == nil { + return "" + } + defer C.g_object_unref(C.gpointer(text)) + count := C.atspi_text_get_character_count(text, nil) + if count <= 0 || time.Now().After(budget.deadline) { + return "" + } + content := C.atspi_text_get_text(text, 0, min(count, C.gint(maxSnapshotFieldLength)), nil) + if content == nil { + return "" + } + defer C.g_free(C.gpointer(content)) + length := int(C.review_text_length(content, C.int(maxSnapshotFieldLength*utf8.UTFMax))) + if length < 0 || length > maxSnapshotFieldLength*utf8.UTFMax { + return "" + } + expanded := expandNativeEmbeddedText(child, C.GoStringN(content, C.int(length)), 0, depth, budget) + switch role { + case C.ATSPI_ROLE_HEADING, C.ATSPI_ROLE_LIST, C.ATSPI_ROLE_LIST_ITEM, C.ATSPI_ROLE_PARAGRAPH, + C.ATSPI_ROLE_SECTION, C.ATSPI_ROLE_TABLE, C.ATSPI_ROLE_TABLE_CELL, C.ATSPI_ROLE_TABLE_ROW: + if budget.characters > 0 { + expanded += " " + budget.characters-- + } + } + return expanded +} + +type nativeReviewText struct { + text *C.AtspiText + terminal bool + // Exact range rectangles belong to one synchronous text capture. Reuse + // block measurements during clipping without retaining state across commands. + boundsCache map[[2]int]Rectangle +} + +func (source nativeReviewText) count(ctx context.Context) (int, error) { + if err := ctx.Err(); err != nil { + return 0, err + } + var nativeErr *C.GError + count := C.atspi_text_get_character_count(source.text, &nativeErr) + if nativeErr != nil { + C.g_error_free(nativeErr) + return 0, errors.New("query review character count") + } + if source.terminal && count > 0 { + return terminalCharacterCount(ctx, int(count), source.characterExists) + } + return int(count), ctx.Err() +} + +func (source nativeReviewText) characterExists(ctx context.Context, offset int) (bool, error) { + if err := ctx.Err(); err != nil { + return false, err + } + var nativeErr *C.GError + text := C.atspi_text_get_text(source.text, C.gint(offset), C.gint(offset+1), &nativeErr) + if text != nil { + defer C.g_free(C.gpointer(text)) + } + if nativeErr != nil { + C.g_error_free(nativeErr) + return false, errors.New("query terminal review character") + } + length := int(C.review_text_length(text, C.int(utf8.UTFMax))) + if length < 0 || length > utf8.UTFMax { + return false, errors.New("invalid terminal review character") + } + value := C.GoStringN(text, C.int(length)) + if !utf8.ValidString(value) || utf8.RuneCountInString(value) > 1 { + return false, errors.New("invalid terminal review character") + } + return length != 0, ctx.Err() +} + +func (source nativeReviewText) line(ctx context.Context, offset int) (TextRange, error) { + if err := ctx.Err(); err != nil { + return TextRange{}, err + } + var nativeErr *C.GError + line := C.cthulhu_text_get_string_at_offset(source.text, C.gint(offset), C.ATSPI_TEXT_GRANULARITY_LINE, &nativeErr) + if line != nil { + defer C.g_boxed_free(C.atspi_text_range_get_type(), C.gpointer(line)) + } + if nativeErr != nil { + C.g_error_free(nativeErr) + return TextRange{}, errors.New("query review line") + } + if line == nil { + return TextRange{}, errors.New("missing review line") + } + length := int(C.review_text_length(line.content, C.int(maxReviewLineCharacters*utf8.UTFMax))) + if length < 0 || length > maxReviewLineCharacters*utf8.UTFMax { + return TextRange{}, errReviewLineTooLong + } + return TextRange{Start: int(line.start_offset), End: int(line.end_offset), Text: C.GoStringN(line.content, C.int(length))}, ctx.Err() +} + +func (source nativeReviewText) viewport(ctx context.Context, start, end int, clip Rectangle) ([]TextRange, error) { + return point_review_viewport(ctx, source, start, end, clip) +} + +func (source nativeReviewText) offset_at_point(ctx context.Context, x, y int32) (int, error) { + if err := ctx.Err(); err != nil { + return 0, err + } + var nativeErr *C.GError + offset := C.atspi_text_get_offset_at_point(source.text, C.gint(x), C.gint(y), C.ATSPI_COORD_TYPE_SCREEN, &nativeErr) + if nativeErr != nil { + C.g_error_free(nativeErr) + return 0, errors.New("query review offset at point") + } + return int(offset), ctx.Err() +} + +func (source nativeReviewText) text_span(ctx context.Context, start, end int) (string, error) { + if err := ctx.Err(); err != nil { + return "", err + } + if end <= start || end-start > maxReviewBoundsCharacters { + return "", errors.New("invalid review span request") + } + var nativeErr *C.GError + content := C.atspi_text_get_text(source.text, C.gint(start), C.gint(end), &nativeErr) + if content != nil { + defer C.g_free(C.gpointer(content)) + } + if nativeErr != nil { + C.g_error_free(nativeErr) + return "", errors.New("query review text span") + } + length := int(C.review_text_length(content, C.int((end-start)*utf8.UTFMax))) + if length < 0 || length > (end-start)*utf8.UTFMax { + return "", errors.New("invalid review span length") + } + value := C.GoStringN(content, C.int(length)) + if !utf8.ValidString(value) || utf8.RuneCountInString(value) != end-start { + return "", errors.New("invalid review span offsets or content") + } + return value, ctx.Err() +} + +func (source nativeReviewText) bounds(ctx context.Context, start, end int) (Rectangle, error) { + rect, err := bounded_review_bounds(ctx, start, end, source.range_bounds) + if err != nil { + return Rectangle{}, err + } + return rect, ctx.Err() +} + +func (source nativeReviewText) range_bounds(ctx context.Context, start, end int) (Rectangle, error) { + if err := ctx.Err(); err != nil { + return Rectangle{}, err + } + key := [2]int{start, end} + if bounds, known := source.boundsCache[key]; known { + return bounds, nil + } + var nativeErr *C.GError + bounds := C.atspi_text_get_range_extents(source.text, C.gint(start), C.gint(end), C.ATSPI_COORD_TYPE_SCREEN, &nativeErr) + if bounds != nil { + defer C.g_free(C.gpointer(bounds)) + } + if nativeErr != nil { + err := nativeError("query review range bounds", nativeErr) + C.g_error_free(nativeErr) + return Rectangle{}, err + } + if bounds == nil { + return Rectangle{}, errors.New("missing review range bounds") + } + rect := Rectangle{int32(bounds.x), int32(bounds.y), int32(bounds.width), int32(bounds.height)} + if err := ctx.Err(); err != nil { + return Rectangle{}, err + } + if source.boundsCache != nil { + source.boundsCache[key] = rect + } + return rect, nil +} + +// Only called from captureNativeTree on the adapter's GLib thread. Unsupported, +// hidden, protected, and failed text queries remain unavailable to review. +func textFromNative(ctx context.Context, accessible *C.AtspiAccessible, geometry Geometry, snapshot Snapshot, clip Rectangle) (VisibleText, error) { + if err := ctx.Err(); err != nil { + return VisibleText{}, err + } + if !geometry.BoundsKnown || !clip.Valid() || snapshot.Role == "password text" { + return VisibleText{}, nil + } + text := C.atspi_accessible_get_text_iface(accessible) + if text == nil { + return VisibleText{}, ctx.Err() + } + defer C.g_object_unref(C.gpointer(text)) + source := nativeReviewText{text: text, terminal: snapshot.Role == "terminal", boundsCache: make(map[[2]int]Rectangle)} + result, err := captureVisibleText(ctx, source, clip) + if err != nil { + if ctx.Err() != nil { + return VisibleText{}, ctx.Err() + } + result = VisibleText{Issue: TextProviderFailure} + } + if result.Issue == TextProviderFailure && ctx.Err() == nil { + // Some providers advertise Text on component-only controls and + // containers. Verify their bounded content before allowing the + // established accessible-name/child-content path to handle them. + if recovered, ok := recover_review_component(ctx, source, snapshot, geometry, clip); ok { + result = recovered + } + } + if result.Issue != "" { + capture_diagnostics(ctx).text_issue(result.Issue) + } + if result.Known && ctx.Err() == nil { + var nativeErr *C.GError + offset := int(C.atspi_text_get_caret_offset(text, &nativeErr)) + if nativeErr != nil { + C.g_error_free(nativeErr) + } else if offset >= 0 { + result.CaretKnown, result.CaretOffset = true, offset + } + } + return result, ctx.Err() +} diff --git a/internal/atspi/text_test.go b/internal/atspi/text_test.go new file mode 100644 index 0000000..2dda98e --- /dev/null +++ b/internal/atspi/text_test.go @@ -0,0 +1,473 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "context" + "errors" + "reflect" + "strings" + "sync" + "testing" +) + +type fakeReviewText struct { + characters int + lines map[int]TextRange + rectangles map[[2]int]Rectangle + failure error + cancel context.CancelFunc +} + +func (s fakeReviewText) count(ctx context.Context) (int, error) { return s.characters, s.failure } +func (s fakeReviewText) line(ctx context.Context, offset int) (TextRange, error) { + if s.cancel != nil { + s.cancel() + } + return s.lines[offset], s.failure +} +func (s fakeReviewText) bounds(ctx context.Context, start, end int) (Rectangle, error) { + if bounds, ok := s.rectangles[[2]int{start, end}]; ok { + return bounds, ctx.Err() + } + for span, bounds := range s.rectangles { + if span[0] <= start && end <= span[1] { + return bounds, ctx.Err() + } + } + return Rectangle{}, ctx.Err() +} + +func TestCaptureVisibleTextUnicodeClippingAndEmbeddedObjects(t *testing.T) { + clip := Rectangle{-10, 0, 20, 20} + source := fakeReviewText{characters: 8, lines: map[int]TextRange{ + 0: {Start: 0, End: 4, Text: "é猫x\n"}, 4: {Start: 4, End: 8, Text: "a\ufffcbz"}, + }, rectangles: map[[2]int]Rectangle{ + {0, 3}: {-20, 0, 30, 10}, {0, 1}: {-20, 0, 10, 10}, {1, 2}: {-10, 0, 10, 10}, {2, 3}: {0, 0, 10, 10}, + {4, 5}: {-10, 10, 5, 10}, {6, 8}: {-5, 10, 10, 10}, + }} + got, err := captureVisibleText(context.Background(), source, clip) + want := VisibleText{Known: true, Ranges: []TextRange{ + {1, 3, "猫x", Rectangle{-10, 0, 20, 10}}, + {4, 5, "a", Rectangle{-10, 10, 5, 10}}, {6, 8, "bz", Rectangle{-5, 10, 10, 10}}, + }} + if err != nil || !reflect.DeepEqual(got, want) { + t.Fatalf("capture = %#v %v, want %#v", got, err, want) + } +} + +func TestCaptureVisibleTextRejectsBadProgressAndCancellation(t *testing.T) { + for _, line := range []TextRange{ + {Start: 0, End: 0, Text: ""}, {Start: 1, End: 2, Text: "x"}, + {Start: 0, End: 3, Text: "abc"}, {Start: 0, End: 2, Text: "é"}, {Start: 0, End: 2, Text: "\xffx"}, + } { + got, err := captureVisibleText(context.Background(), fakeReviewText{characters: 2, lines: map[int]TextRange{0: line}}, Rectangle{0, 0, 10, 10}) + if err == nil || got.Known || len(got.Ranges) != 0 { + t.Fatalf("bad line accepted: %#v => %#v %v", line, got, err) + } + } + ctx, cancel := context.WithCancel(context.Background()) + source := fakeReviewText{characters: 1, lines: map[int]TextRange{0: {Start: 0, End: 1, Text: "x"}}, rectangles: map[[2]int]Rectangle{{0, 1}: {0, 0, 1, 1}}, cancel: cancel} + if _, err := captureVisibleText(ctx, source, Rectangle{0, 0, 10, 10}); !errors.Is(err, context.Canceled) { + t.Fatalf("cancellation = %v", err) + } +} + +func TestCaptureVisibleTextRetriesProviderLineStartAheadOfOffset(t *testing.T) { + source := fakeReviewText{characters: 5, lines: map[int]TextRange{ + 0: {Start: 0, End: 2, Text: "ab"}, + 1: {Start: 2, End: 5, Text: "cde"}, + 2: {Start: 3, End: 5, Text: "de"}, + }, rectangles: map[[2]int]Rectangle{ + {0, 2}: {0, 0, 2, 1}, {2, 5}: {0, 1, 3, 1}, + }} + got, err := captureVisibleText(context.Background(), source, Rectangle{0, 0, 10, 10}) + want := VisibleText{Known: true, Ranges: []TextRange{ + {0, 2, "ab", Rectangle{0, 0, 2, 1}}, {2, 5, "cde", Rectangle{0, 1, 3, 1}}, + }} + if err != nil || !reflect.DeepEqual(got, want) { + t.Fatalf("capture = %#v %v, want %#v", got, err, want) + } +} + +func TestCaptureVisibleTextSeeksTerminalViewportBeforeReadingLines(t *testing.T) { + const count = 1000000 + source := fakeReviewText{characters: count, lines: map[int]TextRange{ + 420000: {Start: 420000, End: 420005, Text: "first"}, + 420005: {Start: 420005, End: 420011, Text: "second"}, + }, rectangles: map[[2]int]Rectangle{ + {0, 420000}: {0, -20, 1, 10}, + {420000, 420005}: {0, 0, 5, 10}, + {420005, 420011}: {0, 10, 6, 10}, + {420011, count}: {0, 20, 1, 10}, + }} + got, err := captureVisibleText(context.Background(), source, Rectangle{0, 0, 100, 20}) + want := VisibleText{Known: true, Ranges: []TextRange{ + {420000, 420005, "first", Rectangle{0, 0, 5, 10}}, + {420005, 420011, "second", Rectangle{0, 10, 6, 10}}, + }} + if err != nil || !reflect.DeepEqual(got, want) { + t.Fatalf("capture = %#v %v, want %#v", got, err, want) + } + got.CaretKnown, got.CaretOffset = true, 420010 + if !got.valid(Geometry{BoundsKnown: true, Bounds: Rectangle{0, 0, 100, 20}}) { + t.Fatal("visible terminal scrollback offsets rejected by tree validation") + } +} + +func TestCaptureVisibleTextLargeTerminalScreen(t *testing.T) { + const columns, rows = 160, 55 + source := fakeReviewText{characters: columns * rows, lines: map[int]TextRange{}, rectangles: map[[2]int]Rectangle{}} + for row := 0; row < rows; row++ { + start := row * columns + source.lines[start] = TextRange{Start: start, End: start + columns, Text: strings.Repeat("x", columns)} + source.rectangles[[2]int{start, start + columns}] = Rectangle{0, int32(row * 17), columns * 8, 17} + } + clip := Rectangle{0, 0, columns * 8, rows * 17} + got, err := captureVisibleText(context.Background(), source, clip) + if err != nil || !got.Known || got.Limited || len(got.Ranges) != rows { + t.Fatalf("large terminal capture: known=%v limited=%v ranges=%d err=%v", got.Known, got.Limited, len(got.Ranges), err) + } + got.CaretKnown, got.CaretOffset = true, source.characters-1 + if !got.valid(Geometry{BoundsKnown: true, Bounds: clip}) { + t.Fatal("large terminal capture rejected by tree validation") + } +} + +func TestCaptureVisibleTextLimitsAndEmpty(t *testing.T) { + for _, count := range []int{0, maxReviewCharacters + 1, -1} { + got, err := captureVisibleText(context.Background(), fakeReviewText{characters: count}, Rectangle{0, 0, 10, 10}) + if count == 0 && (err != nil || !got.Known || len(got.Ranges) != 0) { + t.Fatalf("empty = %#v %v", got, err) + } + if count > maxReviewCharacters && (err != nil || !got.Limited || got.Known || len(got.Ranges) != 0) { + t.Fatalf("limit = %#v %v", got, err) + } + if count < 0 && err == nil { + t.Fatal("negative count accepted") + } + } + count := maxReviewCharacters + 1 + oversized := fakeReviewText{characters: count, rectangles: map[[2]int]Rectangle{{0, count}: {0, 0, 10, 10}}} + if got, err := captureVisibleText(context.Background(), oversized, Rectangle{0, 0, 10, 10}); err != nil || !got.Limited || got.Known || len(got.Ranges) != 0 { + t.Fatalf("oversized visible viewport: %#v %v", got, err) + } + source := fakeReviewText{characters: maxReviewRanges + 1, lines: map[int]TextRange{}, rectangles: map[[2]int]Rectangle{}} + for i := 0; i < source.characters; i++ { + source.lines[i] = TextRange{Start: i, End: i + 1, Text: "x"} + source.rectangles[[2]int{i, i + 1}] = Rectangle{0, 0, 1, 1} + } + got, err := captureVisibleText(context.Background(), source, Rectangle{0, 0, 10, 10}) + if err != nil || !got.Limited || len(got.Ranges) != 0 { + t.Fatalf("range limit = %#v %v", got, err) + } +} + +// A horizontally clipped viewport has hundreds of visible characters, but +// only a few visual rows. The range budget must count spans, not characters. +type clippedReviewText struct{ rows, columns int } + +func (s clippedReviewText) count(context.Context) (int, error) { return s.rows * s.columns, nil } +func (s clippedReviewText) line(_ context.Context, offset int) (TextRange, error) { + start := offset / s.columns * s.columns + return TextRange{Start: start, End: start + s.columns, Text: strings.Repeat("é", s.columns)}, nil +} +func (s clippedReviewText) bounds(_ context.Context, start, end int) (Rectangle, error) { + return Rectangle{X: int32(start%s.columns*10 - 50), Y: int32(start / s.columns * 12), Width: int32((end - start) * 10), Height: 12}, nil +} + +func TestCaptureVisibleTextClippedViewportUsesSpans(t *testing.T) { + source := clippedReviewText{rows: 20, columns: 400} + clip := Rectangle{X: 3, Width: 394, Height: int32(source.rows * 12)} + got, err := captureVisibleText(context.Background(), source, clip) + if err != nil || !got.Known || got.Limited || len(got.Ranges) != source.rows { + t.Fatalf("clipped capture: known=%v limited=%v ranges=%d err=%v", got.Known, got.Limited, len(got.Ranges), err) + } + for row, span := range got.Ranges { + want := TextRange{Start: row*source.columns + 5, End: row*source.columns + 45, Text: strings.Repeat("é", 40), Bounds: Rectangle{X: 3, Y: int32(row * 12), Width: 394, Height: 12}} + if span != want { + t.Fatalf("row %d: %+v, want %+v", row, span, want) + } + } + if !got.valid(Geometry{BoundsKnown: true, Bounds: clip}) { + t.Fatal("clipped viewport rejected by tree validation") + } +} + +func TestCaptureVisibleTextClippedSpanCrossesGeometryBlocks(t *testing.T) { + source := clippedReviewText{rows: 1, columns: 400} + got, err := captureVisibleText(context.Background(), source, Rectangle{X: 3, Width: 2594, Height: 12}) + want := VisibleText{Known: true, Ranges: []TextRange{ + {5, 265, strings.Repeat("é", 260), Rectangle{3, 0, 2594, 12}}, + }} + if err != nil || !reflect.DeepEqual(got, want) { + t.Fatalf("cross-block capture = %+v %v, want %+v", got, err, want) + } +} + +func TestCaptureVisibleTextClippedDisjointSpanLimit(t *testing.T) { + count := (maxReviewRanges + 1) * 2 + source := fakeReviewText{characters: count, lines: map[int]TextRange{ + 0: {Start: 0, End: count, Text: strings.Repeat("x", count)}, + }, rectangles: map[[2]int]Rectangle{{0, count}: {-10, 0, 30, 10}}} + for i := 0; i < count; i++ { + source.rectangles[[2]int{i, i + 1}] = Rectangle{X: int32(i % 2 * 20), Width: 10, Height: 10} + } + got, err := captureVisibleText(context.Background(), source, Rectangle{0, 0, 10, 10}) + if err != nil || !got.Limited || got.Known || len(got.Ranges) != 0 { + t.Fatalf("disjoint span limit: %+v %v", got, err) + } +} + +func TestCaptureVisibleTextClippedBidiKeepsHiddenGaps(t *testing.T) { + source := fakeReviewText{characters: 5, lines: map[int]TextRange{ + 0: {Start: 0, End: 5, Text: "אבXגד"}, + }, rectangles: map[[2]int]Rectangle{ + {0, 5}: {-10, 0, 70, 10}, + {0, 1}: {30, 0, 10, 10}, {1, 2}: {20, 0, 10, 10}, + {2, 3}: {50, 0, 10, 10}, + {3, 4}: {10, 0, 10, 10}, {4, 5}: {0, 0, 10, 10}, + }} + got, err := captureVisibleText(context.Background(), source, Rectangle{0, 0, 40, 10}) + want := VisibleText{Known: true, Ranges: []TextRange{ + {0, 2, "אב", Rectangle{20, 0, 20, 10}}, + {3, 5, "גד", Rectangle{0, 0, 20, 10}}, + }} + if err != nil || !reflect.DeepEqual(got, want) { + t.Fatalf("bidi capture = %+v %v, want %+v", got, err, want) + } +} + +func BenchmarkCaptureVisibleTextClipped(b *testing.B) { + source := clippedReviewText{rows: 4, columns: 100} + clip := Rectangle{X: 3, Width: 394, Height: int32(source.rows * 12)} + b.ReportAllocs() + for b.Loop() { + got, err := captureVisibleText(context.Background(), source, clip) + if err != nil || !got.Known || got.Limited { + b.Fatalf("clipped capture: known=%v limited=%v err=%v", got.Known, got.Limited, err) + } + } +} + +func textNode() TreeNode { + node := testNode("/root", "Text") + node.Geometry = Geometry{Bounds: Rectangle{-10, 0, 20, 20}, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + node.Text = VisibleText{Known: true, Ranges: []TextRange{{0, 2, "é猫", Rectangle{-10, 0, 20, 10}}}} + return node +} + +func TestTreeTextOwnershipInvalidationAndReplacement(t *testing.T) { + node := textNode() + tree, err := NewAccessibleTree(node.Snapshot.ID(), []TreeNode{node}) + if err != nil { + t.Fatal(err) + } + ref, _ := tree.Root() + node.Text.Ranges[0].Text = "xx" + got, _ := tree.VisibleText(ref) + if got.Ranges[0].Text != "é猫" { + t.Fatal("tree retained caller slice") + } + got.Ranges[0].Text = "yy" + got, _ = tree.VisibleText(ref) + if got.Ranges[0].Text != "é猫" { + t.Fatal("tree exposed owned slice") + } + if n := tree.InvalidateText(ref.ID()); n != 1 { + t.Fatalf("invalidated %d", n) + } + if n := tree.InvalidateText(ref.ID()); n != 0 { + t.Fatalf("repeat invalidated %d", n) + } + if _, err := tree.VisibleText(ref); !errors.Is(err, ErrStaleText) { + t.Fatalf("stale = %v", err) + } + if _, err := tree.Geometry(ref); err != nil { + t.Fatal(err) + } + if _, err := tree.Resolve(ref); err != nil { + t.Fatal(err) + } + if err := tree.Replace(node.Snapshot.ID(), []TreeNode{node}); err != nil { + t.Fatal(err) + } + if got, err := tree.VisibleText(ref); err != nil || got.Ranges[0].Text != "xx" { + t.Fatalf("replace = %#v %v", got, err) + } + tree.InvalidateGeometry(ref.ID()) + if _, err := tree.VisibleText(ref); !errors.Is(err, ErrStaleText) { + t.Fatalf("layout = %v", err) + } + tree.Invalidate(ref.ID()) + if _, err := tree.VisibleText(ref); !errors.Is(err, ErrStaleObject) { + t.Fatalf("removed = %v", err) + } +} + +func TestTreeRejectsMalformedText(t *testing.T) { + for _, text := range []VisibleText{ + {Ranges: []TextRange{{0, 1, "x", Rectangle{0, 0, 1, 1}}}}, + {Known: true, Limited: true}, + {Known: true, Ranges: []TextRange{{0, 2, "é", Rectangle{0, 0, 1, 1}}}}, + {Known: true, Ranges: []TextRange{{0, 1, "x", Rectangle{10, 0, 1, 1}}}}, + {Known: true, Ranges: []TextRange{{0, 1, "\ufffc", Rectangle{0, 0, 1, 1}}}}, + {Known: true, Ranges: []TextRange{{0, 3, "a\nb", Rectangle{0, 0, 1, 1}}}}, + {Known: true, Ranges: []TextRange{{0, 1, "x", Rectangle{0, 0, 1, 1}}, {0, 1, "x", Rectangle{0, 0, 1, 1}}}}, + } { + node := textNode() + node.Text = text + if _, err := NewAccessibleTree(node.Snapshot.ID(), []TreeNode{node}); !errors.Is(err, ErrInvalidTree) { + t.Fatalf("accepted %#v: %v", text, err) + } + } + node := textNode() + node.Geometry = Geometry{} + if _, err := NewAccessibleTree(node.Snapshot.ID(), []TreeNode{node}); !errors.Is(err, ErrInvalidTree) { + t.Fatalf("text without geometry accepted: %v", err) + } +} + +func TestTreeTextConcurrentInvalidation(t *testing.T) { + node := textNode() + tree, err := NewAccessibleTree(node.Snapshot.ID(), []TreeNode{node}) + if err != nil { + t.Fatal(err) + } + ref, _ := tree.Root() + var readers sync.WaitGroup + for range 8 { + readers.Add(1) + go func() { + defer readers.Done() + for range 100 { + _, err := tree.VisibleText(ref) + if err != nil && !errors.Is(err, ErrStaleText) { + t.Errorf("read: %v", err) + } + } + }() + } + tree.InvalidateText(ref.ID()) + readers.Wait() +} + +func TestAdapterTextInvalidationPolicy(t *testing.T) { + for _, event := range []string{TextInsertedEvent, TextDeletedEvent + ":system", TextBoundsChangedEvent, TextAttributesChangedEvent, CaretEvent} { + tree := testTree(t) + adapter := New() + adapter.tree = tree + first, _ := tree.Reference(testID("/first")) + second, _ := tree.Reference(testID("/second")) + adapter.invalidateTreeEvent(event, 0, first.ID(), ObjectID{}) + if _, err := tree.VisibleText(first); !errors.Is(err, ErrStaleText) { + t.Fatalf("%s: %v", event, err) + } + if _, err := tree.VisibleText(second); err != nil { + t.Fatalf("unrelated text: %v", err) + } + if _, err := tree.Resolve(first); err != nil { + t.Fatal(err) + } + } +} + +func TestTreeTextTotalBudget(t *testing.T) { + root := testNode("/root", "Window") + nodes := []TreeNode{root} + for i := 0; i <= maxTreeTextBytes/(maxReviewCharacters*3); i++ { + node := textNode() + node.Snapshot.Path = "/n" + strings.Repeat("x", i+1) + node.Text.Ranges[0] = TextRange{0, maxReviewCharacters, strings.Repeat("猫", maxReviewCharacters), Rectangle{0, 0, 1, 1}} + nodes = append(nodes, node) + nodes[0].Children = append(nodes[0].Children, node.Snapshot.ID()) + } + if _, err := NewAccessibleTree(root.Snapshot.ID(), nodes); !errors.Is(err, ErrInvalidTree) { + t.Fatalf("total budget: %v", err) + } +} + +func TestTerminalCharacterCount(t *testing.T) { + for _, tc := range []struct{ reported, actual int }{{0, 0}, {49, 48}, {30, 10}, {10, 10}, {1000000, 700000}, {8, 0}} { + calls := 0 + got, err := terminalCharacterCount(context.Background(), tc.reported, func(ctx context.Context, offset int) (bool, error) { + calls++ + if offset < 0 || offset >= tc.reported { + t.Fatalf("offset out of bounds: %d", offset) + } + return offset < tc.actual, nil + }) + if err != nil || got != tc.actual || calls > 22 { + t.Fatalf("%+v: count=%d calls=%d err=%v", tc, got, calls, err) + } + } + failure := errors.New("provider unavailable") + if _, err := terminalCharacterCount(context.Background(), 10, func(context.Context, int) (bool, error) { return false, failure }); !errors.Is(err, failure) { + t.Fatalf("failure = %v", err) + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := terminalCharacterCount(ctx, 10, func(ctx context.Context, _ int) (bool, error) { return false, ctx.Err() }); !errors.Is(err, context.Canceled) { + t.Fatalf("cancellation = %v", err) + } +} + +func TestCaptureVisibleTextRetainsBlankRows(t *testing.T) { + source := fakeReviewText{characters: 6, lines: map[int]TextRange{ + 0: {Start: 0, End: 2, Text: "a\n"}, + 2: {Start: 2, End: 3, Text: "\n"}, + 3: {Start: 3, End: 5, Text: "b\n"}, + 5: {Start: 5, End: 6, Text: "\n"}, + }, rectangles: map[[2]int]Rectangle{ + {0, 2}: {0, 0, 10, 10}, {2, 3}: {0, 10, 10, 10}, + {3, 5}: {0, 20, 10, 10}, {5, 6}: {0, 30, 10, 10}, + }} + clip := Rectangle{0, 0, 10, 40} + got, err := captureVisibleText(context.Background(), source, clip) + want := VisibleText{Known: true, Ranges: []TextRange{ + {0, 1, "a", Rectangle{0, 0, 10, 10}}, + {2, 3, "\n", Rectangle{0, 10, 10, 10}}, + {3, 4, "b", Rectangle{0, 20, 10, 10}}, + {5, 6, "\n", Rectangle{0, 30, 10, 10}}, + }} + if err != nil || !reflect.DeepEqual(got, want) { + t.Fatalf("capture=%+v err=%v want=%+v", got, err, want) + } + if !got.valid(Geometry{BoundsKnown: true, Bounds: clip}) { + t.Fatal("blank row capture rejected by tree validation") + } +} + +func TestCaptureVisibleTextSplitsCombinedBlankRows(t *testing.T) { + source := fakeReviewText{characters: 4, lines: map[int]TextRange{ + 0: {Start: 0, End: 4, Text: "\n\r\n\n"}, + }, rectangles: map[[2]int]Rectangle{ + {0, 1}: {0, 0, 10, 10}, + {1, 3}: {0, 10, 10, 10}, + {3, 4}: {0, 20, 10, 10}, + }} + got, err := captureVisibleText(context.Background(), source, Rectangle{0, 0, 10, 30}) + want := VisibleText{Known: true, Ranges: []TextRange{ + {0, 1, "\n", Rectangle{0, 0, 10, 10}}, + {1, 3, "\r\n", Rectangle{0, 10, 10, 10}}, + {3, 4, "\n", Rectangle{0, 20, 10, 10}}, + }} + if err != nil || !reflect.DeepEqual(got, want) { + t.Fatalf("capture = %#v %v, want %#v", got, err, want) + } +} diff --git a/internal/atspi/text_viewport.go b/internal/atspi/text_viewport.go new file mode 100644 index 0000000..3bfdf5d --- /dev/null +++ b/internal/atspi/text_viewport.go @@ -0,0 +1,282 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "errors" + "sort" + "strings" + "unicode/utf8" +) + +var errReviewViewportScanLimit = errors.New("review viewport scan limit") + +type reviewSpanSource interface { + bounds(context.Context, int, int) (Rectangle, error) + text_span(context.Context, int, int) (string, error) +} + +type reviewPointSource interface { + reviewSpanSource + offset_at_point(context.Context, int32, int32) (int, error) +} + +// Walk visible glyph rectangles rather than logical offsets. Logical offsets +// need not increase left-to-right (bidi), and a single line can be enormous. +// Check every intervening pixel when a provider cannot identify a glyph. A +// finite query budget rejects sparse or defective providers without omissions. +func point_review_viewport(ctx context.Context, source reviewPointSource, start, end int, clip Rectangle) ([]TextRange, error) { + if end <= start { + return nil, nil + } + first, err := review_endpoint_bounds(ctx, source, start, end, false) + if err != nil { + return nil, err + } + last, err := review_endpoint_bounds(ctx, source, start, end, true) + if err != nil { + return nil, err + } + top := max(int64(clip.Y), int64(first.Y)) + bottom := min(int64(clip.Y)+int64(clip.Height), int64(last.Y)+int64(last.Height)) + right := int64(clip.X) + int64(clip.Width) + offsets := make(map[int]Rectangle) + queries := 0 + for y := top; y < bottom; { + nextRow := bottom + found := false + rowCovered := true + for x := int64(clip.X); x < right; { + if err := ctx.Err(); err != nil { + return nil, err + } + if queries >= 4096 { + return nil, errReviewViewportScanLimit + } + queries++ + offset, err := source.offset_at_point(ctx, int32(x), int32(y)) + if err != nil { + return nil, err + } + if offset < start || offset >= end { + rowCovered = false + x++ + continue + } + bounds, known := offsets[offset] + if !known { + bounds, err = source.bounds(ctx, offset, offset+1) + if err != nil { + return nil, err + } + } + if !bounds.Valid() || x < int64(bounds.X) || x >= int64(bounds.X)+int64(bounds.Width) || y < int64(bounds.Y) || y >= int64(bounds.Y)+int64(bounds.Height) { + rowCovered = false + x++ + continue + } + offsets[offset] = bounds + found = true + nextRow = min(nextRow, int64(bounds.Y)+int64(bounds.Height)) + x = min(right, int64(bounds.X)+int64(bounds.Width)) + } + if found && rowCovered { + y = nextRow + } else { + y++ + } + } + ordered := make([]int, 0, len(offsets)) + for offset := range offsets { + ordered = append(ordered, offset) + } + sort.Ints(ordered) + var ranges []TextRange + for index := 0; index < len(ordered); { + if len(ranges) >= maxReviewRanges { + return nil, errors.New("review viewport range limit") + } + first := ordered[index] + bounds := offsets[first] + next := index + 1 + for next < len(ordered) && ordered[next] == ordered[next-1]+1 && next-index < maxReviewBoundsCharacters && offsets[ordered[next]].Y == bounds.Y && offsets[ordered[next]].Height == bounds.Height { + next++ + } + last := ordered[next-1] + 1 + content, err := source.text_span(ctx, first, last) + if err != nil { + return nil, err + } + // A mark or joiner may have no point of its own. Retain a bounded + // continuation of a visible base without including hidden letters. + limit := min(end, last+maxReviewBoundsCharacters) + if next < len(ordered) { + limit = min(limit, ordered[next]) + } + if last < limit { + tail, err := source.text_span(ctx, last, limit) + if err != nil { + return nil, err + } + for _, character := range tail { + if !review_cluster_continuation(character) { + break + } + bounds, err := source.bounds(ctx, last, last+1) + if err != nil { + return nil, err + } + if _, visible := bounds.Intersection(clip); bounds.Valid() && !visible { + break + } + content += string(character) + last++ + } + if last == limit && limit < end && (next == len(ordered) || limit < ordered[next]) { + following, err := source.text_span(ctx, last, last+1) + if err != nil { + return nil, err + } + for _, character := range following { + if review_cluster_continuation(character) { + return nil, errReviewViewportScanLimit + } + } + } + } + ranges = append(ranges, TextRange{Start: first, End: last, Text: content}) + index = next + } + return ranges, ctx.Err() +} + +// Trailing newlines and formatting characters can have no glyph rectangle. +// Look only within a bounded edge block, rather than discarding a long line +// or scanning arbitrary offscreen text to find an endpoint. +func review_endpoint_bounds(ctx context.Context, source reviewSpanSource, start, end int, backwards bool) (Rectangle, error) { + for index := 0; index < min(end-start, maxReviewBoundsCharacters); index++ { + if err := ctx.Err(); err != nil { + return Rectangle{}, err + } + offset := start + index + if backwards { + offset = end - index - 1 + } + bounds, err := source.bounds(ctx, offset, offset+1) + if err != nil { + return Rectangle{}, err + } + if bounds.Valid() { + return bounds, nil + } + } + return Rectangle{}, errors.New("unavailable review viewport endpoint geometry") +} + +// Line rectangles can be usable when single-character extents are missing. +// Move by complete line boundaries on each binary-search step; never scan +// scrollback or accept a non-progressing/provider-clamped line as a match. +func visible_line_offsets(ctx context.Context, source reviewTextSource, count int, clip Rectangle) (int, int, error) { + if !clip.Valid() { + return 0, 0, errors.New("invalid review text clip") + } + search := func(bottom bool) (int, error) { + low, high := 0, count + for low < high { + if err := ctx.Err(); err != nil { + return 0, err + } + middle := low + (high-low)/2 + line, err := source.line(ctx, middle) + if err != nil { + return 0, err + } + if line.Start < 0 || line.Start > middle || line.End <= middle || line.End > count || line.End-line.Start > maxReviewLineCharacters { + return 0, errors.New("invalid review viewport line offsets") + } + bounds, err := source.bounds(ctx, line.Start, line.End) + if err != nil { + return 0, err + } + if !bounds.Valid() { + return 0, errors.New("invalid review line bounds") + } + after := int64(bounds.Y)+int64(bounds.Height) > int64(clip.Y) + if bottom { + after = int64(bounds.Y) >= int64(clip.Y)+int64(clip.Height) + } + if after { + high = max(low, line.Start) + } else { + low = min(high, line.End) + } + } + return low, nil + } + start, err := search(false) + if err != nil || start == count { + return start, start, err + } + end, err := search(true) + if err == nil && end < start { + err = errors.New("invalid review line viewport order") + } + return start, end, err +} + +func capture_review_viewport(ctx context.Context, source reviewTextSource, count int, clip Rectangle, reason TextCaptureIssue) (VisibleText, error) { + if spatial, ok := source.(reviewViewportSource); ok { + ranges, err := spatial.viewport(ctx, 0, count, clip) + if ctx.Err() != nil { + return VisibleText{}, ctx.Err() + } + if err == nil && len(ranges) > 0 { + return capture_review_lines(ctx, source, count, 0, count, clip, ranges) + } + if errors.Is(err, errReviewViewportScanLimit) { + reason = TextViewportScanLimit + } + } + return VisibleText{Limited: true, Issue: reason}, ctx.Err() +} + +// Validate all spatial output before accepting any of it. Native offsets can +// be large, but the amount of copied text and the number of spans cannot. +func validate_viewport_ranges(ranges []TextRange, count int) error { + if len(ranges) > maxReviewRanges { + return errors.New("review viewport range limit") + } + previous, characters := 0, 0 + for _, span := range ranges { + if span.Start < previous || span.End <= span.Start || span.End > count || !utf8.ValidString(span.Text) || utf8.RuneCountInString(span.Text) != span.End-span.Start { + return errors.New("invalid review viewport text") + } + characters += span.End - span.Start + if characters > maxReviewCharacters { + return errReviewLineTooLong + } + previous = span.End + } + return nil +} + +// Provider spatial ranges need not stop at line breaks. Split without making +// another whole-line native request; wrapping is handled by glyph geometry. +func split_viewport_lines(ranges []TextRange) []TextRange { + var lines []TextRange + for _, span := range ranges { + start := span.Start + for _, content := range strings.SplitAfter(span.Text, "\n") { + if content == "" { + continue + } + end := start + utf8.RuneCountInString(content) + lines = append(lines, TextRange{Start: start, End: end, Text: content}) + start = end + } + } + return lines +} diff --git a/internal/atspi/text_viewport_test.go b/internal/atspi/text_viewport_test.go new file mode 100644 index 0000000..3624903 --- /dev/null +++ b/internal/atspi/text_viewport_test.go @@ -0,0 +1,228 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "context" + "errors" + "reflect" + "strings" + "testing" +) + +type lineGeometryText struct { + lineCalls int +} + +func (*lineGeometryText) count(context.Context) (int, error) { return 1000000, nil } +func (source *lineGeometryText) line(ctx context.Context, offset int) (TextRange, error) { + source.lineCalls++ + start := offset / 100 * 100 + return TextRange{Start: start, End: start + 100, Text: strings.Repeat("é", 100)}, ctx.Err() +} +func (*lineGeometryText) bounds(ctx context.Context, start, end int) (Rectangle, error) { + if end-start == 1 { + return Rectangle{}, errors.New("character rectangles unavailable") + } + return Rectangle{Y: int32(start/100-4200) * 10, Width: 100, Height: 10}, ctx.Err() +} + +func TestCaptureVisibleTextDiscoversLargeViewportFromLines(t *testing.T) { + source := &lineGeometryText{} + clip := Rectangle{Width: 100, Height: 20} + got, err := captureVisibleText(context.Background(), source, clip) + want := VisibleText{Known: true, Ranges: []TextRange{ + {420000, 420100, strings.Repeat("é", 100), Rectangle{Width: 100, Height: 10}}, + {420100, 420200, strings.Repeat("é", 100), Rectangle{Y: 10, Width: 100, Height: 10}}, + }} + if err != nil || !reflect.DeepEqual(got, want) || source.lineCalls > 40 { + t.Fatalf("line viewport = %+v, %v; calls=%d", got, err, source.lineCalls) + } +} + +type spatialReviewText struct { + clippedReviewText + ranges []TextRange + lineCalls, viewportCalls int + cancel context.CancelFunc +} + +func (source *spatialReviewText) line(ctx context.Context, offset int) (TextRange, error) { + source.lineCalls++ + return TextRange{}, errReviewLineTooLong +} +func (source *spatialReviewText) viewport(ctx context.Context, start, end int, clip Rectangle) ([]TextRange, error) { + source.viewportCalls++ + if source.cancel != nil { + source.cancel() + } + return source.ranges, ctx.Err() +} + +func TestCaptureVisibleTextRetrievesLongLineViewportWithoutWholeLine(t *testing.T) { + source := &spatialReviewText{clippedReviewText: clippedReviewText{rows: 1, columns: 1000000}, ranges: []TextRange{ + {Start: 500005, End: 500045, Text: strings.Repeat("é", 40)}, + }} + clip := Rectangle{X: 5000003, Width: 394, Height: 12} + got, err := captureVisibleText(context.Background(), source, clip) + want := VisibleText{Known: true, Ranges: []TextRange{{500005, 500045, strings.Repeat("é", 40), clip}}} + if err != nil || !reflect.DeepEqual(got, want) || source.lineCalls != 0 || source.viewportCalls != 1 { + t.Fatalf("spatial capture = %+v, %v; line=%d viewport=%d", got, err, source.lineCalls, source.viewportCalls) + } +} + +func TestCaptureVisibleTextRejectsInvalidSpatialOutput(t *testing.T) { + for _, ranges := range [][]TextRange{ + {{Start: 8, End: 10, Text: "x"}}, + {{Start: 8, End: 10, Text: "é猫"}, {Start: 7, End: 8, Text: "x"}}, + {{Start: 0, End: maxReviewCharacters + 1, Text: strings.Repeat("x", maxReviewCharacters+1)}}, + {{Start: 999999, End: 1000001, Text: "xx"}}, + } { + source := &spatialReviewText{clippedReviewText: clippedReviewText{rows: 1, columns: 1000000}, ranges: ranges} + got, err := captureVisibleText(context.Background(), source, Rectangle{Width: 100, Height: 12}) + if err == nil || got.Known || len(got.Ranges) != 0 { + t.Fatalf("invalid spatial capture accepted: %+v %v", got, err) + } + } +} + +func TestCaptureVisibleTextSpatialCancellation(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + source := &spatialReviewText{clippedReviewText: clippedReviewText{rows: 1, columns: 1000000}, cancel: cancel} + got, err := captureVisibleText(ctx, source, Rectangle{Width: 100, Height: 12}) + if !errors.Is(err, context.Canceled) || got.Known || got.Limited { + t.Fatalf("spatial cancellation = %+v %v", got, err) + } +} + +type pointReviewText struct { + fakeReviewText + pointCalls int + textByOffset map[int]string +} + +func (source *pointReviewText) offset_at_point(ctx context.Context, x, y int32) (int, error) { + source.pointCalls++ + for span, bounds := range source.rectangles { + if span[1]-span[0] == 1 && int64(x) >= int64(bounds.X) && int64(x) < int64(bounds.X)+int64(bounds.Width) && int64(y) >= int64(bounds.Y) && int64(y) < int64(bounds.Y)+int64(bounds.Height) { + return span[0], ctx.Err() + } + } + return -1, ctx.Err() +} +func (source *pointReviewText) text_span(ctx context.Context, start, end int) (string, error) { + var text strings.Builder + for offset := start; offset < end; offset++ { + character, ok := source.textByOffset[offset] + if !ok { + character = "x" + } + text.WriteString(character) + } + return text.String(), ctx.Err() +} + +func TestPointReviewViewportKeepsDisjointBidiOffsets(t *testing.T) { + source := &pointReviewText{fakeReviewText: fakeReviewText{rectangles: map[[2]int]Rectangle{ + {0, 1}: {-100, 0, 10, 10}, {99999, 100000}: {100, 0, 10, 10}, + {10, 11}: {30, 0, 10, 10}, {70000, 70001}: {10, 0, 10, 10}, {80000, 80001}: {20, 0, 10, 10}, + }}, textByOffset: map[int]string{10: "א", 70000: "猫", 80000: "é"}} + ranges, err := point_review_viewport(context.Background(), source, 0, 100000, Rectangle{X: 10, Width: 30, Height: 10}) + if err != nil || len(ranges) != 3 || source.pointCalls != 3 { + t.Fatalf("point bidi = %+v, %v; calls=%d", ranges, err, source.pointCalls) + } + for index, offset := range []int{10, 70000, 80000} { + if ranges[index].Start != offset || ranges[index].Text != source.textByOffset[offset] { + t.Fatalf("point bidi lost native offset: %+v", ranges) + } + } +} + +func TestPointReviewViewportDoesNotSkipVerticallyInsetGlyph(t *testing.T) { + source := &pointReviewText{fakeReviewText: fakeReviewText{rectangles: map[[2]int]Rectangle{ + {0, 1}: {0, 0, 10, 20}, {1, 2}: {10, 5, 10, 10}, {2, 3}: {20, 0, 10, 20}, + }}, textByOffset: map[int]string{0: "A", 1: "é", 2: "B"}} + ranges, err := point_review_viewport(context.Background(), source, 0, 3, Rectangle{Width: 30, Height: 20}) + if err != nil || len(ranges) != 3 || ranges[1].Text != "é" { + t.Fatalf("inset glyph omitted: %+v %v", ranges, err) + } +} + +func TestPointReviewViewportBoundsSparseProviderWork(t *testing.T) { + source := &pointReviewText{fakeReviewText: fakeReviewText{rectangles: map[[2]int]Rectangle{ + {0, 1}: {-100, 0, 10, 100}, {99999, 100000}: {1000, 0, 10, 100}, + }}} + ranges, err := point_review_viewport(context.Background(), source, 0, 100000, Rectangle{Width: 100, Height: 100}) + if !errors.Is(err, errReviewViewportScanLimit) || len(ranges) != 0 || source.pointCalls != 4096 { + t.Fatalf("sparse provider work: ranges=%d calls=%d err=%v", len(ranges), source.pointCalls, err) + } +} + +func TestPointReviewViewportRetainsLineWithZeroAreaTrailingNewline(t *testing.T) { + source := &pointReviewText{fakeReviewText: fakeReviewText{rectangles: map[[2]int]Rectangle{ + {0, 1}: {Width: 10, Height: 10}, {1, 2}: {X: 10, Width: 10, Height: 10}, {2, 3}: {}, + }}, textByOffset: map[int]string{0: "é", 1: "猫", 2: "\n"}} + ranges, err := point_review_viewport(context.Background(), source, 0, 3, Rectangle{Width: 20, Height: 20}) + if err != nil || len(ranges) != 1 || ranges[0].Text != "é猫" || ranges[0].End != 2 { + t.Fatalf("trailing newline discarded visible glyphs: %+v %v", ranges, err) + } +} + +func TestCaptureVisibleTextSkipsZeroAreaGlyphsWithoutLosingOtherText(t *testing.T) { + source := fakeReviewText{characters: 6, lines: map[int]TextRange{ + 0: {Start: 0, End: 6, Text: "abcXYZ"}, + }, rectangles: map[[2]int]Rectangle{ + {0, 6}: {Width: 60, Height: 10}, + {0, 1}: {Width: 10, Height: 10}, {1, 2}: {X: 10, Width: 10, Height: 10}, + {2, 3}: {}, {3, 4}: {X: 20, Width: 10, Height: 10}, + {4, 5}: {X: 40, Width: 10, Height: 10}, {5, 6}: {X: 50, Width: 10, Height: 10}, + }} + got, err := captureVisibleText(context.Background(), source, Rectangle{Width: 30, Height: 10}) + want := VisibleText{Known: true, Ranges: []TextRange{ + {0, 2, "ab", Rectangle{Width: 20, Height: 10}}, + {3, 4, "X", Rectangle{X: 20, Width: 10, Height: 10}}, + }} + if err != nil || !reflect.DeepEqual(got, want) { + t.Fatalf("zero-area glyph capture = %+v, %v; want %+v", got, err, want) + } +} + +func TestCaptureVisibleTextRetainsZeroAreaCombiningMark(t *testing.T) { + source := fakeReviewText{characters: 4, lines: map[int]TextRange{ + 0: {Start: 0, End: 4, Text: "a\u0301bc"}, + }, rectangles: map[[2]int]Rectangle{ + {0, 4}: {Width: 40, Height: 10}, {0, 1}: {Width: 10, Height: 10}, + {1, 2}: {}, {2, 3}: {X: 10, Width: 10, Height: 10}, {3, 4}: {X: 30, Width: 10, Height: 10}, + }} + got, err := captureVisibleText(context.Background(), source, Rectangle{Width: 20, Height: 10}) + if err != nil || !got.Known || len(got.Ranges) != 1 || got.Ranges[0].Text != "a\u0301b" || got.Ranges[0].End != 3 { + t.Fatalf("visible accent lost: %+v %v", got, err) + } +} + +func TestPointReviewViewportRetainsZeroAreaCombiningMark(t *testing.T) { + source := &pointReviewText{fakeReviewText: fakeReviewText{rectangles: map[[2]int]Rectangle{ + {0, 1}: {Width: 10, Height: 10}, {1, 2}: {}, {2, 3}: {X: 10, Width: 10, Height: 10}, + }}, textByOffset: map[int]string{0: "a", 1: "\u0301", 2: "b"}} + ranges, err := point_review_viewport(context.Background(), source, 0, 3, Rectangle{Width: 20, Height: 10}) + if err != nil || len(ranges) != 2 || ranges[0].Text != "a\u0301" || ranges[0].End != 2 || ranges[1].Text != "b" { + t.Fatalf("point traversal lost accent: %+v %v", ranges, err) + } +} + +func TestPointReviewViewportRejectsExcessiveClusterWithoutPartialText(t *testing.T) { + const finalOffset = maxReviewBoundsCharacters + 2 + source := &pointReviewText{fakeReviewText: fakeReviewText{rectangles: map[[2]int]Rectangle{ + {0, 1}: {Width: 10, Height: 10}, {finalOffset, finalOffset + 1}: {X: 10, Width: 10, Height: 10}, + }}, textByOffset: map[int]string{0: "a", finalOffset: "b"}} + for offset := 1; offset < finalOffset; offset++ { + source.textByOffset[offset] = "\u0301" + } + ranges, err := point_review_viewport(context.Background(), source, 0, finalOffset+1, Rectangle{Width: 20, Height: 10}) + if !errors.Is(err, errReviewViewportScanLimit) || len(ranges) != 0 { + t.Fatalf("cluster limit silently omitted text: %+v %v", ranges, err) + } +} diff --git a/internal/atspi/tree.go b/internal/atspi/tree.go new file mode 100644 index 0000000..577c667 --- /dev/null +++ b/internal/atspi/tree.go @@ -0,0 +1,586 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "errors" + "fmt" + "sync" +) + +// Large browser documents can expose more than ten thousand accessible nodes. +// Capture still has a time limit and a finite node budget on the native thread. +const maxTreeNodes = 30000 + +var ( + ErrStaleGeometry = errors.New("accessible geometry requires recapture") + ErrIncompleteTree = errors.New("accessible children require recapture") + ErrInvalidTree = errors.New("invalid accessible tree") + ErrDeadObject = errors.New("defunct accessible object") + ErrObjectNotFound = errors.New("accessible object not found") + ErrStaleObject = errors.New("stale accessible object") + ErrStaleSnapshot = errors.New("accessible semantics require recapture") +) + +// TreeNode is an owned, immutable accessible snapshot and the identities of +// its children in application-provided order. NewAccessibleTree and Replace +// copy Children before retaining a node. +type TreeNode struct { + Geometry Geometry + Text VisibleText + Snapshot Snapshot + Children []ObjectID + // Review-only capture could not enumerate part of this object's children. + ChildrenUnavailable bool +} + +// ObjectReference is a generation-checked reference to an owned snapshot. A +// reference becomes stale when its object or an ancestor is invalidated, or +// when a replacement tree no longer contains that object. +type ObjectReference struct { + id ObjectID + generation uint64 +} + +func (reference ObjectReference) ID() ObjectID { + return reference.id +} + +func (reference ObjectReference) Valid() bool { + return reference.id.Valid() && reference.generation != 0 +} + +type treeEntry struct { + snapshotInvalid bool + text VisibleText + textInvalid bool + geometry Geometry + geometryInvalid bool + childrenInvalid bool + childrenUnavailable bool + snapshot Snapshot + children []ObjectID + parent ObjectID + hasParent bool + generation uint64 +} + +// AccessibleTree owns a validated accessibility tree. It contains no native +// references and supports concurrent readers while events replace or +// invalidate cached objects. +type AccessibleTree struct { + mu sync.RWMutex + root ObjectID + nodes map[ObjectID]treeEntry + nextGeneration uint64 + documents map[ObjectID]*documentData +} + +func NewAccessibleTree(root ObjectID, nodes []TreeNode) (*AccessibleTree, error) { + tree := &AccessibleTree{} + if err := tree.Replace(root, nodes); err != nil { + return nil, err + } + return tree, nil +} + +// Replace atomically installs a complete tree. References to identities that +// remain live retain their generation; removed identities become stale. If an +// invalidated identity later reappears, it receives a new generation. +func (tree *AccessibleTree) Replace(root ObjectID, nodes []TreeNode) error { + next, err := validateTree(root, nodes) + if err != nil { + return err + } + + tree.mu.Lock() + defer tree.mu.Unlock() + for id, entry := range next { + if current, ok := tree.nodes[id]; ok { + entry.generation = current.generation + } else { + tree.nextGeneration++ + if tree.nextGeneration == 0 { + // Reaching this would require creating more than 2^64 distinct + // object generations in one process. Keep zero reserved for an + // invalid reference if it nevertheless occurs. + tree.nextGeneration++ + } + entry.generation = tree.nextGeneration + } + next[id] = entry + } + tree.root = root + tree.nodes = next + tree.documents = nil + return nil +} + +func (tree *AccessibleTree) Root() (ObjectReference, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + entry, ok := tree.nodes[tree.root] + if !ok { + return ObjectReference{}, ErrObjectNotFound + } + return newObjectReference(tree.root, entry), nil +} + +func (tree *AccessibleTree) Reference(id ObjectID) (ObjectReference, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + entry, ok := tree.nodes[id] + if !ok { + return ObjectReference{}, fmt.Errorf("%w: bus %q path %q", ErrObjectNotFound, id.BusName, id.Path) + } + return newObjectReference(id, entry), nil +} + +func (tree *AccessibleTree) Resolve(reference ObjectReference) (Snapshot, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + entry, err := tree.resolveLocked(reference) + if err != nil { + return Snapshot{}, err + } + return entry.snapshot, nil +} + +// InvalidateSnapshot refreshes presentation and matching data without retiring +// a live identity. A renamed button is still the same browse-caret position. +func (tree *AccessibleTree) InvalidateSnapshot(id ObjectID) int { + tree.mu.Lock() + defer tree.mu.Unlock() + entry, ok := tree.nodes[id] + if !ok || entry.snapshotInvalid { + return 0 + } + entry.snapshotInvalid = true + tree.nodes[id] = entry + return 1 +} + +// nativeRefresh copies a dirty tree for incremental native recapture. +// Unchanged nodes and child lists can be reused; dirty fields and newly added +// objects must be read from the provider. A missing or replaced root cannot +// inherit this cache. +func (tree *AccessibleTree) nativeRefresh(root ObjectID) map[ObjectID]treeEntry { + tree.mu.RLock() + defer tree.mu.RUnlock() + if tree.root != root { + return nil + } + if _, ok := tree.nodes[root]; !ok { + return nil + } + dirty := false + nodes := make(map[ObjectID]treeEntry, len(tree.nodes)) + for id, entry := range tree.nodes { + dirty = dirty || entry.snapshotInvalid || entry.childrenInvalid || entry.textInvalid || entry.geometryInvalid + entry.children = append([]ObjectID(nil), entry.children...) + entry.text.Ranges = append([]TextRange(nil), entry.text.Ranges...) + nodes[id] = entry + } + if !dirty { + return nil + } + return nodes +} + +// subtreeIDs returns the captured identities rooted at reference. It is used +// only by the native adapter to classify the bounded burst of caret/focus and +// defunct events produced by browser caret placement. No native references +// escape through this copy. +func (tree *AccessibleTree) subtreeIDs(reference ObjectReference) ([]ObjectID, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + if _, err := tree.resolveLocked(reference); err != nil { + return nil, err + } + result := make([]ObjectID, 0, 4) + pending := []ObjectID{reference.id} + for len(pending) != 0 { + last := len(pending) - 1 + id := pending[last] + pending = pending[:last] + entry, ok := tree.nodes[id] + if !ok { + return nil, ErrIncompleteTree + } + result = append(result, id) + pending = append(pending, entry.children...) + } + return result, nil +} + +// Geometry returns capture-time screen bounds, or ErrStaleGeometry after a +// layout/visibility event. Structural identity remains live across such events. +func (tree *AccessibleTree) Geometry(reference ObjectReference) (Geometry, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + entry, err := tree.resolveLocked(reference) + if err != nil { + return Geometry{}, err + } + if entry.geometryInvalid { + return Geometry{}, ErrStaleGeometry + } + return entry.geometry, nil +} + +// InvalidateGeometry marks an object's subtree for recapture without changing +// focus snapshots, identity generations, or child/sibling traversal. Moving a +// container can move every descendant. Work is bounded by maxTreeNodes. +func (tree *AccessibleTree) InvalidateGeometry(id ObjectID) int { + tree.mu.Lock() + defer tree.mu.Unlock() + pending := []ObjectID{id} + invalidated := 0 + for len(pending) != 0 { + last := len(pending) - 1 + currentID := pending[last] + pending = pending[:last] + entry, ok := tree.nodes[currentID] + if !ok || entry.geometryInvalid { + // A marked ancestor already marked its entire subtree. Only a + // complete Replace can introduce fresh descendants. + continue + } + pending = append(pending, entry.children...) + invalidated++ + entry.geometryInvalid = true + tree.nodes[currentID] = entry + } + return invalidated +} + +func (tree *AccessibleTree) Parent(reference ObjectReference) (ObjectReference, bool, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + entry, err := tree.resolveLocked(reference) + if err != nil { + return ObjectReference{}, false, err + } + if !entry.hasParent { + return ObjectReference{}, false, nil + } + parent := tree.nodes[entry.parent] + return newObjectReference(entry.parent, parent), true, nil +} + +func (tree *AccessibleTree) FirstChild(reference ObjectReference) (ObjectReference, bool, error) { + return tree.child(reference, false) +} + +func (tree *AccessibleTree) LastChild(reference ObjectReference) (ObjectReference, bool, error) { + return tree.child(reference, true) +} + +func (tree *AccessibleTree) child(reference ObjectReference, last bool) (ObjectReference, bool, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + entry, err := tree.resolveLocked(reference) + if err != nil { + return ObjectReference{}, false, err + } + if entry.childrenInvalid { + return ObjectReference{}, false, ErrIncompleteTree + } + if len(entry.children) == 0 { + return ObjectReference{}, false, nil + } + index := 0 + if last { + index = len(entry.children) - 1 + } + id := entry.children[index] + return newObjectReference(id, tree.nodes[id]), true, nil +} + +func (tree *AccessibleTree) PreviousSibling(reference ObjectReference) (ObjectReference, bool, error) { + return tree.sibling(reference, -1) +} + +func (tree *AccessibleTree) NextSibling(reference ObjectReference) (ObjectReference, bool, error) { + return tree.sibling(reference, 1) +} + +func (tree *AccessibleTree) sibling(reference ObjectReference, direction int) (ObjectReference, bool, error) { + tree.mu.RLock() + defer tree.mu.RUnlock() + entry, err := tree.resolveLocked(reference) + if err != nil { + return ObjectReference{}, false, err + } + if !entry.hasParent { + return ObjectReference{}, false, nil + } + parent := tree.nodes[entry.parent] + for index, id := range parent.children { + if id != reference.id { + continue + } + siblingIndex := index + direction + if siblingIndex < 0 || siblingIndex >= len(parent.children) { + return ObjectReference{}, false, nil + } + siblingID := parent.children[siblingIndex] + return newObjectReference(siblingID, tree.nodes[siblingID]), true, nil + } + return ObjectReference{}, false, fmt.Errorf("%w: parent does not contain child", ErrInvalidTree) +} + +// Invalidate removes an object and all of its descendants. It returns the +// number of removed objects. An unknown identity is an idempotent no-op. +func (tree *AccessibleTree) Invalidate(id ObjectID) int { + tree.mu.Lock() + defer tree.mu.Unlock() + entry, ok := tree.nodes[id] + if !ok { + return 0 + } + tree.documents = nil + if entry.hasParent { + parent := tree.nodes[entry.parent] + for index, childID := range parent.children { + if childID == id { + parent.children = append(parent.children[:index:index], parent.children[index+1:]...) + tree.nodes[entry.parent] = parent + break + } + } + } + + removed := 0 + pending := []ObjectID{id} + for len(pending) != 0 { + last := len(pending) - 1 + currentID := pending[last] + pending = pending[:last] + current, present := tree.nodes[currentID] + if !present { + continue + } + pending = append(pending, current.children...) + delete(tree.nodes, currentID) + removed++ + } + return removed +} + +// InvalidateChildren removes every descendant of a live parent while keeping +// the parent reference valid. Structural additions use this conservative path +// because the cached child order is no longer complete until the next capture. +// Child traversal returns ErrIncompleteTree until Replace installs a fresh tree; +// the parent snapshot and its own parent/sibling relationships remain usable. +func (tree *AccessibleTree) InvalidateChildren(parentID ObjectID) int { + tree.mu.Lock() + defer tree.mu.Unlock() + parent, ok := tree.nodes[parentID] + if !ok { + return 0 + } + tree.documents = nil + pending := append([]ObjectID(nil), parent.children...) + parent.children = nil + parent.childrenInvalid = true + tree.nodes[parentID] = parent + removed := 0 + for len(pending) != 0 { + last := len(pending) - 1 + currentID := pending[last] + pending = pending[:last] + current, present := tree.nodes[currentID] + if !present { + continue + } + pending = append(pending, current.children...) + delete(tree.nodes, currentID) + removed++ + } + return removed +} + +// MarkChildrenChanged requires fresh child order without declaring the existing +// children dead. A document insertion does not replace its surviving siblings. +// Document traversal refuses the old order until Replace validates the capture; +// explicit removals and lifecycle events still retire their object generations. +func (tree *AccessibleTree) MarkChildrenChanged(parentID ObjectID) int { + tree.mu.Lock() + defer tree.mu.Unlock() + parent, ok := tree.nodes[parentID] + if !ok || parent.childrenInvalid { + return 0 + } + parent.childrenInvalid = true + tree.nodes[parentID] = parent + return 1 +} + +// markAncestorChildrenChanged refreshes child order up to the root. Web +// providers can reveal or replace whole branches without children-changed +// events. Keep surviving identities and unrelated snapshots so recapture +// discovers the current branch from the nearest live ancestor. +func (tree *AccessibleTree) markAncestorChildrenChanged(id ObjectID) int { + tree.mu.Lock() + defer tree.mu.Unlock() + invalidated := 0 + for { + entry, ok := tree.nodes[id] + if !ok { + return invalidated + } + if !entry.childrenInvalid { + entry.childrenInvalid = true + tree.nodes[id] = entry + invalidated++ + } + if !entry.hasParent { + return invalidated + } + id = entry.parent + } +} + +func (tree *AccessibleTree) resolveLocked(reference ObjectReference) (treeEntry, error) { + entry, ok := tree.nodes[reference.id] + if !ok { + if reference.Valid() { + return treeEntry{}, fmt.Errorf("%w: bus %q path %q", ErrStaleObject, reference.id.BusName, reference.id.Path) + } + return treeEntry{}, fmt.Errorf("%w: bus %q path %q", ErrObjectNotFound, reference.id.BusName, reference.id.Path) + } + if reference.generation == 0 || reference.generation != entry.generation { + return treeEntry{}, fmt.Errorf("%w: bus %q path %q", ErrStaleObject, reference.id.BusName, reference.id.Path) + } + if entry.snapshotInvalid { + return treeEntry{}, ErrStaleSnapshot + } + return entry, nil +} + +func newObjectReference(id ObjectID, entry treeEntry) ObjectReference { + return ObjectReference{id: id, generation: entry.generation} +} + +func validateTree(root ObjectID, nodes []TreeNode) (map[ObjectID]treeEntry, error) { + if !root.Valid() { + return nil, fmt.Errorf("%w: root identity is empty", ErrInvalidTree) + } + if len(nodes) == 0 { + return nil, fmt.Errorf("%w: tree is empty", ErrInvalidTree) + } + if len(nodes) > maxTreeNodes { + return nil, fmt.Errorf("%w: %d nodes exceeds limit %d", ErrInvalidTree, len(nodes), maxTreeNodes) + } + + entries := make(map[ObjectID]treeEntry, len(nodes)) + textBytes := 0 + for _, node := range nodes { + id := node.Snapshot.ID() + if !id.Valid() { + return nil, fmt.Errorf("%w: node identity is empty", ErrInvalidTree) + } + if _, exists := entries[id]; exists { + return nil, fmt.Errorf("%w: duplicate bus %q path %q", ErrInvalidTree, id.BusName, id.Path) + } + if node.Snapshot.Defunct { + return nil, fmt.Errorf("%w: %w at bus %q path %q", ErrInvalidTree, ErrDeadObject, id.BusName, id.Path) + } + if !node.Geometry.valid() { + return nil, fmt.Errorf("%w: invalid component geometry", ErrInvalidTree) + } + if !node.Text.valid(node.Geometry) { + return nil, fmt.Errorf("%w: invalid visible text", ErrInvalidTree) + } + for _, r := range node.Text.Ranges { + textBytes += len(r.Text) + } + if textBytes > maxTreeTextBytes { + return nil, fmt.Errorf("%w: visible text exceeds tree limit", ErrInvalidTree) + } + text := node.Text + text.Ranges = append([]TextRange(nil), text.Ranges...) + children := append([]ObjectID(nil), node.Children...) + entries[id] = treeEntry{snapshot: node.Snapshot, children: children, geometry: node.Geometry, text: text, childrenUnavailable: node.ChildrenUnavailable} + } + if _, ok := entries[root]; !ok { + return nil, fmt.Errorf("%w: root is missing", ErrInvalidTree) + } + + parents := make(map[ObjectID]ObjectID, len(nodes)-1) + for parentID, entry := range entries { + seenChildren := make(map[ObjectID]struct{}, len(entry.children)) + for _, childID := range entry.children { + if !childID.Valid() { + return nil, fmt.Errorf("%w: child identity is empty", ErrInvalidTree) + } + if _, exists := entries[childID]; !exists { + return nil, fmt.Errorf("%w: child bus %q path %q is missing", ErrInvalidTree, childID.BusName, childID.Path) + } + if _, duplicate := seenChildren[childID]; duplicate { + return nil, fmt.Errorf("%w: duplicate child bus %q path %q", ErrInvalidTree, childID.BusName, childID.Path) + } + seenChildren[childID] = struct{}{} + if _, exists := parents[childID]; exists { + return nil, fmt.Errorf("%w: child bus %q path %q has multiple parents", ErrInvalidTree, childID.BusName, childID.Path) + } + parents[childID] = parentID + } + } + if _, hasParent := parents[root]; hasParent { + return nil, fmt.Errorf("%w: root has a parent", ErrInvalidTree) + } + for id, entry := range entries { + parent, hasParent := parents[id] + if id != root && !hasParent { + return nil, fmt.Errorf("%w: bus %q path %q is disconnected", ErrInvalidTree, id.BusName, id.Path) + } + entry.parent = parent + entry.hasParent = hasParent + entries[id] = entry + } + + visited := make(map[ObjectID]bool, len(entries)) + active := make(map[ObjectID]bool, len(entries)) + var visit func(ObjectID) error + visit = func(id ObjectID) error { + if active[id] { + return fmt.Errorf("%w: cycle at bus %q path %q", ErrInvalidTree, id.BusName, id.Path) + } + if visited[id] { + return nil + } + active[id] = true + for _, childID := range entries[id].children { + if err := visit(childID); err != nil { + return err + } + } + active[id] = false + visited[id] = true + return nil + } + if err := visit(root); err != nil { + return nil, err + } + if len(visited) != len(entries) { + return nil, fmt.Errorf("%w: tree contains unreachable nodes", ErrInvalidTree) + } + return entries, nil +} diff --git a/internal/atspi/tree_test.go b/internal/atspi/tree_test.go new file mode 100644 index 0000000..a98ab77 --- /dev/null +++ b/internal/atspi/tree_test.go @@ -0,0 +1,408 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "errors" + "fmt" + "sync" + "testing" +) + +func testID(path string) ObjectID { + return ObjectID{BusName: ":1.42", Path: path} +} + +func testNode(path, name string, children ...ObjectID) TreeNode { + snapshot := NewSnapshot(path, name, "push button", "", "") + snapshot.BusName = ":1.42" + return TreeNode{Snapshot: snapshot, Children: children} +} + +func testTree(t *testing.T) *AccessibleTree { + t.Helper() + tree, err := NewAccessibleTree(testID("/root"), []TreeNode{ + testNode("/root", "Window", testID("/first"), testID("/second")), + testNode("/first", "First"), + testNode("/second", "Second", testID("/grandchild")), + testNode("/grandchild", "Grandchild"), + }) + if err != nil { + t.Fatal(err) + } + return tree +} + +func TestAccessibleTreeTraversal(t *testing.T) { + tree := testTree(t) + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + first, ok, err := tree.FirstChild(root) + if err != nil || !ok || first.ID() != testID("/first") { + t.Fatalf("first child = %#v, %v, %v", first, ok, err) + } + second, ok, err := tree.NextSibling(first) + if err != nil || !ok || second.ID() != testID("/second") { + t.Fatalf("next sibling = %#v, %v, %v", second, ok, err) + } + previous, ok, err := tree.PreviousSibling(second) + if err != nil || !ok || previous.ID() != first.ID() { + t.Fatalf("previous sibling = %#v, %v, %v", previous, ok, err) + } + last, ok, err := tree.LastChild(root) + if err != nil || !ok || last.ID() != second.ID() { + t.Fatalf("last child = %#v, %v, %v", last, ok, err) + } + parent, ok, err := tree.Parent(second) + if err != nil || !ok || parent.ID() != root.ID() { + t.Fatalf("parent = %#v, %v, %v", parent, ok, err) + } + grandchild, ok, err := tree.FirstChild(second) + if err != nil || !ok { + t.Fatalf("grandchild = %#v, %v, %v", grandchild, ok, err) + } + snapshot, err := tree.Resolve(grandchild) + if err != nil || snapshot.Name != "Grandchild" { + t.Fatalf("resolved snapshot = %#v, %v", snapshot, err) + } +} + +func TestAccessibleTreeTraversalBoundaries(t *testing.T) { + tree := testTree(t) + root, _ := tree.Root() + first, _, _ := tree.FirstChild(root) + second, _, _ := tree.LastChild(root) + grandchild, _, _ := tree.FirstChild(second) + + checks := []struct { + name string + call func() (ObjectReference, bool, error) + }{ + {name: "root parent", call: func() (ObjectReference, bool, error) { return tree.Parent(root) }}, + {name: "root sibling", call: func() (ObjectReference, bool, error) { return tree.NextSibling(root) }}, + {name: "first previous", call: func() (ObjectReference, bool, error) { return tree.PreviousSibling(first) }}, + {name: "last next", call: func() (ObjectReference, bool, error) { return tree.NextSibling(second) }}, + {name: "leaf child", call: func() (ObjectReference, bool, error) { return tree.FirstChild(grandchild) }}, + } + for _, check := range checks { + t.Run(check.name, func(t *testing.T) { + _, ok, err := check.call() + if err != nil || ok { + t.Fatalf("ok = %v, error = %v", ok, err) + } + }) + } +} + +func TestAccessibleTreeInvalidatesSubtreeAndDetachesIt(t *testing.T) { + tree := testTree(t) + root, _ := tree.Root() + second, _, _ := tree.LastChild(root) + grandchild, _, _ := tree.FirstChild(second) + + if removed := tree.Invalidate(second.ID()); removed != 2 { + t.Fatalf("removed = %d, want 2", removed) + } + if _, err := tree.Resolve(second); !errors.Is(err, ErrStaleObject) { + t.Fatalf("second error = %v, want stale object", err) + } + if _, err := tree.Resolve(grandchild); !errors.Is(err, ErrStaleObject) { + t.Fatalf("grandchild error = %v, want stale object", err) + } + last, ok, err := tree.LastChild(root) + if err != nil || !ok || last.ID() != testID("/first") { + t.Fatalf("remaining last child = %#v, %v, %v", last, ok, err) + } + if removed := tree.Invalidate(second.ID()); removed != 0 { + t.Fatalf("second invalidation removed = %d, want 0", removed) + } +} + +func TestAccessibleTreeInvalidatesChildrenAndKeepsParent(t *testing.T) { + tree := testTree(t) + root, _ := tree.Root() + first, _, _ := tree.FirstChild(root) + second, _, _ := tree.LastChild(root) + if removed := tree.InvalidateChildren(root.ID()); removed != 3 { + t.Fatalf("removed = %d, want 3", removed) + } + if _, err := tree.Resolve(root); err != nil { + t.Fatalf("root became stale: %v", err) + } + if _, err := tree.Resolve(first); !errors.Is(err, ErrStaleObject) { + t.Fatalf("first error = %v, want stale object", err) + } + if _, err := tree.Resolve(second); !errors.Is(err, ErrStaleObject) { + t.Fatalf("second error = %v, want stale object", err) + } + if _, ok, err := tree.FirstChild(root); !errors.Is(err, ErrIncompleteTree) || ok { + t.Fatalf("root child after invalidation: ok = %v, error = %v", ok, err) + } +} + +func TestAccessibleTreeCopiesSubtreeIdentities(t *testing.T) { + tree := testTree(t) + first, err := tree.Reference(testID("/second")) + if err != nil { + t.Fatal(err) + } + ids, err := tree.subtreeIDs(first) + if err != nil { + t.Fatal(err) + } + want := map[ObjectID]bool{testID("/second"): true, testID("/grandchild"): true} + if len(ids) != len(want) { + t.Fatalf("subtree identities = %v", ids) + } + for _, id := range ids { + if !want[id] { + t.Fatalf("unexpected subtree identity %v", id) + } + } +} + +func TestAccessibleTreeReferenceGeneration(t *testing.T) { + tree := testTree(t) + first, err := tree.Reference(testID("/first")) + if err != nil { + t.Fatal(err) + } + updated := []TreeNode{ + testNode("/root", "Window", testID("/first")), + testNode("/first", "Updated"), + } + if err := tree.Replace(testID("/root"), updated); err != nil { + t.Fatal(err) + } + snapshot, err := tree.Resolve(first) + if err != nil || snapshot.Name != "Updated" { + t.Fatalf("stable reference resolved %#v, %v", snapshot, err) + } + + tree.Invalidate(first.ID()) + if err := tree.Replace(testID("/root"), updated); err != nil { + t.Fatal(err) + } + if _, err := tree.Resolve(first); !errors.Is(err, ErrStaleObject) { + t.Fatalf("reintroduced object resolved with old reference: %v", err) + } + reintroduced, err := tree.Reference(first.ID()) + if err != nil { + t.Fatal(err) + } + if reintroduced == first { + t.Fatal("reintroduced object reused its invalidated generation") + } +} + +func TestAccessibleTreeReplaceFailureIsAtomicAndChildrenAreOwned(t *testing.T) { + children := []ObjectID{testID("/child")} + tree, err := NewAccessibleTree(testID("/root"), []TreeNode{ + testNode("/root", "Root", children...), + testNode("/child", "Child"), + }) + if err != nil { + t.Fatal(err) + } + root, _ := tree.Root() + children[0] = testID("/changed") + child, ok, err := tree.FirstChild(root) + if err != nil || !ok || child.ID() != testID("/child") { + t.Fatalf("owned child = %#v, %v, %v", child, ok, err) + } + + err = tree.Replace(testID("/root"), []TreeNode{ + testNode("/root", "Broken", testID("/missing")), + }) + if !errors.Is(err, ErrInvalidTree) { + t.Fatalf("replace error = %v, want invalid tree", err) + } + snapshot, err := tree.Resolve(root) + if err != nil || snapshot.Name != "Root" { + t.Fatalf("tree changed after rejected replacement: %#v, %v", snapshot, err) + } +} + +func TestAccessibleTreeSeparatesSamePathOnDifferentBuses(t *testing.T) { + rootSnapshot := NewSnapshot("/same", "First application", "application", "", "") + rootSnapshot.BusName = ":1.10" + childSnapshot := NewSnapshot("/same", "Second application", "application", "", "") + childSnapshot.BusName = ":1.11" + childID := childSnapshot.ID() + tree, err := NewAccessibleTree(rootSnapshot.ID(), []TreeNode{ + {Snapshot: rootSnapshot, Children: []ObjectID{childID}}, + {Snapshot: childSnapshot}, + }) + if err != nil { + t.Fatal(err) + } + child, err := tree.Reference(childID) + if err != nil { + t.Fatal(err) + } + got, err := tree.Resolve(child) + if err != nil || got.Name != "Second application" { + t.Fatalf("snapshot = %#v, error = %v", got, err) + } +} + +func TestAccessibleTreeRejectsMalformedTrees(t *testing.T) { + root := testID("/root") + defunct := testNode("/root", "Defunct") + defunct.Snapshot.Defunct = true + tests := []struct { + name string + root ObjectID + nodes []TreeNode + }{ + {name: "empty root", nodes: []TreeNode{testNode("/root", "Root")}}, + {name: "empty tree", root: root}, + {name: "missing root", root: root, nodes: []TreeNode{testNode("/other", "Other")}}, + {name: "empty node identity", root: root, nodes: []TreeNode{{Snapshot: Snapshot{}}}}, + {name: "malformed node identity", root: root, nodes: []TreeNode{{Snapshot: Snapshot{BusName: "not unique", Path: "relative"}}}}, + {name: "defunct node", root: root, nodes: []TreeNode{defunct}}, + {name: "duplicate node", root: root, nodes: []TreeNode{testNode("/root", "One"), testNode("/root", "Two")}}, + {name: "missing child", root: root, nodes: []TreeNode{testNode("/root", "Root", testID("/missing"))}}, + {name: "duplicate child", root: root, nodes: []TreeNode{ + testNode("/root", "Root", testID("/child"), testID("/child")), testNode("/child", "Child"), + }}, + {name: "multiple parents", root: root, nodes: []TreeNode{ + testNode("/root", "Root", testID("/one"), testID("/two")), + testNode("/one", "One", testID("/child")), testNode("/two", "Two", testID("/child")), + testNode("/child", "Child"), + }}, + {name: "cycle", root: root, nodes: []TreeNode{ + testNode("/root", "Root", testID("/child")), testNode("/child", "Child", root), + }}, + {name: "disconnected", root: root, nodes: []TreeNode{ + testNode("/root", "Root"), testNode("/other", "Other"), + }}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _, err := NewAccessibleTree(test.root, test.nodes) + if !errors.Is(err, ErrInvalidTree) { + t.Fatalf("error = %v, want invalid tree", err) + } + }) + } +} + +func TestAccessibleTreeRejectsOversizedTree(t *testing.T) { + nodes := make([]TreeNode, maxTreeNodes+1) + for index := range nodes { + nodes[index] = testNode(fmt.Sprintf("/%d", index), "Node") + } + _, err := NewAccessibleTree(testID("/0"), nodes) + if !errors.Is(err, ErrInvalidTree) { + t.Fatalf("error = %v, want invalid tree", err) + } +} + +func TestAccessibleTreeAcceptsLargeBrowserDocument(t *testing.T) { + const count = 10001 // The former limit rejected this complete document. + nodes := make([]TreeNode, count) + children := make([]ObjectID, 0, count-1) + for index := 1; index < count; index++ { + path := fmt.Sprintf("/%d", index) + children = append(children, testID(path)) + nodes[index] = testNode(path, "Heading") + nodes[index].Snapshot.Role = "heading" + } + nodes[0] = testNode("/0", "Document", children...) + nodes[0].Snapshot.Role = "document web" + tree, err := NewAccessibleTree(testID("/0"), nodes) + if err != nil { + t.Fatal(err) + } + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + document, err := tree.Document(t.Context(), root) + if err != nil || len(document.Nodes) != count { + t.Fatalf("large document: nodes=%d, err=%v", len(document.Nodes), err) + } +} + +func TestAccessibleTreeConcurrentInvalidation(t *testing.T) { + tree := testTree(t) + reference, err := tree.Reference(testID("/grandchild")) + if err != nil { + t.Fatal(err) + } + start := make(chan struct{}) + done := make(chan struct{}) + var wait sync.WaitGroup + for range 8 { + wait.Add(1) + go func() { + defer wait.Done() + <-start + for { + select { + case <-done: + return + default: + _, resolveErr := tree.Resolve(reference) + if resolveErr != nil && !errors.Is(resolveErr, ErrStaleObject) { + t.Errorf("resolve error = %v", resolveErr) + return + } + } + } + }() + } + close(start) + tree.Invalidate(testID("/second")) + close(done) + wait.Wait() + if _, err := tree.Resolve(reference); !errors.Is(err, ErrStaleObject) { + t.Fatalf("final resolve error = %v, want stale object", err) + } +} + +func TestAccessibleTreeInvalidatedEmptyChildrenRequireRecapture(t *testing.T) { + tree := testTree(t) + leaf, _ := tree.Reference(testID("/first")) + tree.InvalidateChildren(leaf.ID()) + for _, traverse := range []func(ObjectReference) (ObjectReference, bool, error){tree.FirstChild, tree.LastChild} { + if _, ok, err := traverse(leaf); ok || !errors.Is(err, ErrIncompleteTree) { + t.Fatalf("invalidated empty children: ok=%v err=%v", ok, err) + } + } + if _, err := tree.Resolve(leaf); err != nil { + t.Fatal(err) + } + if _, ok, err := tree.Parent(leaf); err != nil || !ok { + t.Fatalf("parent: %v %v", ok, err) + } + if err := tree.Replace(testID("/root"), []TreeNode{ + testNode("/root", "Window", testID("/first")), + testNode("/first", "First", testID("/added")), + testNode("/added", "Added"), + }); err != nil { + t.Fatal(err) + } + child, ok, err := tree.FirstChild(leaf) + if err != nil || !ok || child.ID() != testID("/added") { + t.Fatalf("recaptured child: %v %v %v", child, ok, err) + } +} diff --git a/internal/atspi/version.go b/internal/atspi/version.go new file mode 100644 index 0000000..253f7d5 --- /dev/null +++ b/internal/atspi/version.go @@ -0,0 +1,32 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +/* +#cgo pkg-config: atspi-2 +#include +*/ +import "C" + +import "fmt" + +func Version() string { + var major, minor, micro C.gint + C.atspi_get_version(&major, &minor, µ) + return fmt.Sprintf("%d.%d.%d", int(major), int(minor), int(micro)) +} diff --git a/internal/atspi/version_test.go b/internal/atspi/version_test.go new file mode 100644 index 0000000..a162920 --- /dev/null +++ b/internal/atspi/version_test.go @@ -0,0 +1,36 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package atspi + +import ( + "strconv" + "strings" + "testing" +) + +func TestVersionIsNumericTriple(t *testing.T) { + parts := strings.Split(Version(), ".") + if len(parts) != 3 { + t.Fatalf("Version() = %q, want major.minor.micro", Version()) + } + for _, part := range parts { + if _, err := strconv.Atoi(part); err != nil { + t.Fatalf("Version() component %q is not numeric: %v", part, err) + } + } +} diff --git a/internal/atspi/webscripts_native.go b/internal/atspi/webscripts_native.go new file mode 100644 index 0000000..85b8425 --- /dev/null +++ b/internal/atspi/webscripts_native.go @@ -0,0 +1,218 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +/* +#cgo pkg-config: atspi-2 gobject-2.0 +#include +static AtspiAccessible *web_ref(AtspiAccessible *source) { return g_object_ref(source); } +static AtspiAccessible *web_event_child(AtspiEvent *event) { + if (!G_IS_VALUE(&event->any_data) || !G_VALUE_HOLDS_OBJECT(&event->any_data)) return NULL; + GObject *child = g_value_get_object(&event->any_data); + return child && ATSPI_IS_ACCESSIBLE(child) ? ATSPI_ACCESSIBLE(child) : NULL; +} +static gchar *web_event_text(AtspiEvent *event) { + return G_IS_VALUE(&event->any_data) && G_VALUE_HOLDS_STRING(&event->any_data) + ? g_value_dup_string(&event->any_data) : NULL; +} +static void web_live_attributes(AtspiAccessible *source, gchar **live, gchar **containerLive) { + GHashTable *attributes = atspi_accessible_get_attributes(source, NULL); + if (!attributes) return; + *live = g_strdup(g_hash_table_lookup(attributes, "live")); + *containerLive = g_strdup(g_hash_table_lookup(attributes, "container-live")); + g_hash_table_unref(attributes); +} +*/ +import "C" + +import ( + "fmt" + "os" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/webscripts" +) + +// Process identity is copied once per provider bus on the GLib owner. A failed +// lookup remains unknown and never enables an application exception. +func (adapter *Adapter) applicationProcess(source *C.AtspiAccessible) string { + id := nativeObjectID(source) + if !id.Valid() { + return "" + } + if process, known := adapter.applicationProcesses[id.BusName]; known { + return process + } + pid := C.atspi_accessible_get_process_id(source, nil) + if pid == 0 { + return "" + } + content, err := os.ReadFile(fmt.Sprintf("/proc/%d/comm", pid)) + if err != nil { + return "" + } + process := strings.TrimSpace(string(content)) + if adapter.applicationProcesses == nil { + adapter.applicationProcesses = make(map[string]string) + } + if len(adapter.applicationProcesses) >= 64 { + clear(adapter.applicationProcesses) + } + adapter.applicationProcesses[id.BusName] = process + return process +} + +// Capture semantic roots only for a matched script and relevant event. Normal +// Chromium events do not incur ancestor scans or notification text traversal. +// No C pointer escapes this function; the callback still owns the event source. +func (adapter *Adapter) webNotification(event *C.AtspiEvent) *webscripts.Notification { + if !webscripts.NotificationEvent(C.GoString(event._type), int(event.detail1)) || + webscripts.MatchProcess(adapter.applicationProcess(event.source)) != webscripts.Steam { + return nil + } + source := event.source + if C.GoString(event._type) == ChildrenAddedEvent { + source = C.web_event_child(event) + } + if source == nil || nativeObjectID(source).BusName != nativeObjectID(event.source).BusName { + return nil + } + // Providers can emit insertion before the accessible-name update. Refresh + // only the changed object so an old cached name cannot replace new text. + if C.GoString(event._type) == TextInsertedEvent { + C.atspi_accessible_clear_cache_single(source) + } + deadline := time.Now().Add(50 * time.Millisecond) + var ancestors []*C.AtspiAccessible + var candidates []webscripts.NotificationCandidate + defer func() { + for _, ancestor := range ancestors { + C.g_object_unref(C.gpointer(ancestor)) + } + }() + for current := C.web_ref(source); current != nil; { + ancestors = append(ancestors, current) + role := C.atspi_accessible_get_role(current, nil) + candidate := webscripts.NotificationCandidate{} + switch role { + case C.ATSPI_ROLE_NOTIFICATION: + candidate.Role = "notification" + case C.ATSPI_ROLE_ALERT: + candidate.Role = "alert" + } + var live, containerLive *C.gchar + C.web_live_attributes(current, &live, &containerLive) + candidate.Live, candidate.ContainerLive = C.GoString(live), C.GoString(containerLive) + C.g_free(C.gpointer(live)) + C.g_free(C.gpointer(containerLive)) + candidates = append(candidates, candidate) + if candidate.Role != "" || role == C.ATSPI_ROLE_APPLICATION || + len(ancestors) >= 32 || time.Now().After(deadline) { + break + } + current = C.atspi_accessible_get_parent(current, nil) + } + index := webscripts.NotificationRoot(candidates) + if index < 0 { + return nil + } + root := ancestors[index] + id := nativeObjectID(root) + if !id.Valid() { + return nil + } + text := webNotificationText(root, ancestors[index+1:], deadline) + if text == "" && C.GoString(event._type) == TextInsertedEvent { + payload := C.web_event_text(event) + text = sanitizeSnapshotField(C.GoString(payload)) + C.g_free(C.gpointer(payload)) + } + return &webscripts.Notification{BusName: id.BusName, RootPath: id.Path, Text: text} +} + +func webReadableText(source *C.AtspiAccessible) string { + if C.atspi_accessible_get_role(source, nil) == C.ATSPI_ROLE_PASSWORD_TEXT { + return "" + } + name := C.atspi_accessible_get_name(source, nil) + content := sanitizeSnapshotField(C.GoString(name)) + C.g_free(C.gpointer(name)) + if content != "" { + return content + } + text := C.atspi_accessible_get_text_iface(source) + if text == nil { + return "" + } + defer C.g_object_unref(C.gpointer(text)) + count := min(int(C.atspi_text_get_character_count(text, nil)), maxSnapshotFieldLength) + if count <= 0 { + return "" + } + value := C.atspi_text_get_text(text, 0, C.gint(count), nil) + content = sanitizeSnapshotField(strings.ReplaceAll(C.GoString(value), "\ufffc", "")) + C.g_free(C.gpointer(value)) + return content +} + +func webNotificationText(root *C.AtspiAccessible, ancestors []*C.AtspiAccessible, deadline time.Time) string { + if text := webReadableText(root); text != "" { + return text + } + var labels []string + var button, readable string + remaining := 64 + var visit func(*C.AtspiAccessible, int) + visit = func(source *C.AtspiAccessible, depth int) { + if remaining <= 0 || depth >= 8 || time.Now().After(deadline) { + return + } + remaining-- + role := C.atspi_accessible_get_role(source, nil) + if role == C.ATSPI_ROLE_PASSWORD_TEXT { + return + } + text := webReadableText(source) + if text != "" { + switch role { + case C.ATSPI_ROLE_LABEL, C.ATSPI_ROLE_STATIC, C.ATSPI_ROLE_TEXT: + labels = append(labels, text) + case C.ATSPI_ROLE_PUSH_BUTTON: + if button == "" { + button = text + } + } + if readable == "" { + readable = text + } + } + count := min(int(C.atspi_accessible_get_child_count(source, nil)), remaining) + for index := 0; index < count && remaining > 0 && time.Now().Before(deadline); index++ { + if child := C.atspi_accessible_get_child_at_index(source, C.gint(index), nil); child != nil { + visit(child, depth+1) + C.g_object_unref(C.gpointer(child)) + } + } + } + visit(root, 0) + if len(labels) != 0 { + return sanitizeSnapshotField(strings.Join(labels, " ")) + } + if button != "" { + return button + } + for _, ancestor := range ancestors { + if time.Now().After(deadline) { + break + } + if C.atspi_accessible_get_role(ancestor, nil) == C.ATSPI_ROLE_PUSH_BUTTON { + if text := webReadableText(ancestor); text != "" { + return text + } + } + } + return readable +} diff --git a/internal/atspi/webscripts_native_test.go b/internal/atspi/webscripts_native_test.go new file mode 100644 index 0000000..cd53b2e --- /dev/null +++ b/internal/atspi/webscripts_native_test.go @@ -0,0 +1,145 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "bufio" + "context" + "fmt" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeWebScriptNotificationCapture(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_WEBSCRIPTS") != "1" { + t.Skip("requires private Xorg/AT-SPI session") + } + adapterCtx, adapterCancel := context.WithTimeout(context.Background(), 25*time.Second) + defer adapterCancel() + adapter := New() + if err := adapter.Start(adapterCtx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + for _, processName := range []string{"steamwebhelper", "chromium"} { + t.Run(processName, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + command := exec.CommandContext(ctx, "python3", "../../tests/gtk_web_notification.py", processName) + input, err := command.StdinPipe() + if err != nil { + t.Fatal(err) + } + output, err := command.StdoutPipe() + if err != nil { + t.Fatal(err) + } + command.Stderr = os.Stderr + if err := command.Start(); err != nil { + t.Fatal(err) + } + defer func() { input.Close(); command.Process.Kill(); command.Wait() }() + ready, err := bufio.NewReader(output).ReadString('\n') + fields := strings.Fields(ready) + if err != nil || len(fields) != 2 || fields[0] != "ready" { + t.Fatalf("fixture readiness: %q, %v", ready, err) + } + // Enumerate the fixture once so GTK publishes its initially hidden + // alert accessibles before we request showing/text events. + if _, err := adapter.CaptureDesktop(ctx); err != nil { + t.Fatal(err) + } + // Keep the toast window outside foreground ownership. Events must + // carry copied notification data without acquiring native focus. + if output, err := exec.CommandContext(ctx, "xdotool", "windowfocus", "--sync", fields[1]).CombinedOutput(); err != nil { + t.Fatalf("foreground focus unavailable: %s, %v", output, err) + } + fmt.Fprintln(input, "show") + if processName == "chromium" { + fmt.Fprintln(input, "update") + fmt.Fprintln(input, "barrier") + } + var root ObjectID + for !root.Valid() { + select { + case event := <-adapter.Events(): + if event.Source.ApplicationProcess != processName { + continue + } + if processName == "chromium" { + if event.Type == TextInsertedEvent && event.Payload == "Username is now online" { + t.Fatal("ordinary background Chromium text reached snapshot delivery") + } + if event.Type != TextInsertedEvent || event.Payload != "Notification barrier" || event.Source.Role != "alert" { + continue + } + if event.WebNotification != nil { + t.Fatal("generic Chromium received Steam metadata") + } + return + } + if event.Type != ShowingStateEvent || event.Detail1 == 0 || event.Source.Role != "alert" { + continue + } + message := event.WebNotification + if !event.ForegroundMismatch { + t.Fatal("toast fixture was not outside foreground ownership") + } + if message == nil || message.Text != "Username Playing: Example Game" { + t.Fatalf("toast text: %+v", message) + } + root = NewObjectID(message.BusName, message.RootPath) + if root != event.Source.ID() { + t.Fatal("showing event did not use the alert root") + } + case <-ctx.Done(): + t.Fatal("toast showing event missing") + } + } + fmt.Fprintln(input, "update") + for { + select { + case event := <-adapter.Events(): + if event.Source.ApplicationProcess != processName || event.Type != TextInsertedEvent || event.Payload != "Username is now online" { + continue + } + message := event.WebNotification + if message == nil || NewObjectID(message.BusName, message.RootPath) != root || !strings.Contains(message.Text, "Username is now online") { + t.Fatalf("fragment did not recover complete alert ancestor: %+v", message) + } + fmt.Fprintln(input, "destroy") + for { + select { + case ending := <-adapter.Events(): + if ending.Type == DefunctStateEvent && ending.Source.ID() == root && ending.Detail1 != 0 { + fmt.Fprintln(input, "add") + for { + select { + case added := <-adapter.Events(): + if added.Type == ChildrenAddedEvent && added.Source.ApplicationProcess == processName && added.WebNotification != nil && added.WebNotification.RootPath != added.Source.Path { + if added.WebNotification.Text != "A new toast" { + t.Fatalf("child-added did not use the added toast root: %+v", added.WebNotification) + } + return + } + case <-ctx.Done(): + t.Fatal("added toast did not reach notification handling") + } + } + } + case <-ctx.Done(): + t.Fatal("destroyed toast root did not reach lifecycle handling") + } + } + case <-ctx.Done(): + t.Fatal("toast text insertion missing") + } + } + }) + } +} diff --git a/internal/atspi/window_title_native_test.go b/internal/atspi/window_title_native_test.go new file mode 100644 index 0000000..9367844 --- /dev/null +++ b/internal/atspi/window_title_native_test.go @@ -0,0 +1,100 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package atspi + +import ( + "bufio" + "context" + "encoding/json" + "os" + "os/exec" + "testing" + "time" +) + +func TestNativeForegroundTitlePublication(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_WINDOW_TITLES") != "1" { + t.Skip("private Xvfb and D-Bus fixture only") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "python3", "-u", "../../tests/window_title_fixture.py") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err = fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + if !scanner.Scan() { + t.Fatal("fixture did not start") + } + var windows map[string]uint64 + if err = json.Unmarshal(scanner.Bytes(), &windows); err != nil { + t.Fatal(err) + } + adapter := New() + if err = adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + waitTitle := func(window, child uint64, text string) ForegroundTitle { + t.Helper() + for { + value := adapter.ForegroundTitle() + if value.Title.Window == window && value.Title.TitleWindow == child && value.Title.Title == text { + return value + } + select { + case <-adapter.TitleChanges(): + case <-ctx.Done(): + t.Fatalf("missing title %q: %+v", text, value) + } + } + } + command := func(action, window, title string) { + t.Helper() + data, _ := json.Marshal(map[string]string{"action": action, "window": window, "title": title}) + if _, err = stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() || scanner.Text() != "ready" { + t.Fatal("fixture command failed") + } + } + initial := waitTitle(windows["normal"], windows["normal"], "Example title") + command("title", "normal", "Changed without AT-SPI") + changed := waitTitle(windows["normal"], windows["normal"], "Changed without AT-SPI") + if changed.Epoch != initial.Epoch { + t.Fatal("title change reset foreground ownership") + } + command("activate", "desktop", "") + command("focus", "control", "") + wine := waitTitle(windows["desktop"], windows["game"], "Wine game") + if wine.Epoch == initial.Epoch || wine.Title.Application != "game.exe" { + t.Fatalf("Wine ownership = %+v", wine) + } + if !wine.Title.Wine || !wine.Title.Focused || !wine.Title.Client.Known || + wine.Title.Client.Window != windows["game"] || wine.Title.Client.Width != 250 || wine.Title.Client.Height != 150 { + t.Fatalf("Wine child geometry/focus missing: %+v", wine) + } + command("focus", "second", "") + dialog := waitTitle(windows["desktop"], windows["second"], "Wine dialog") + if dialog.Epoch != wine.Epoch { + t.Fatal("Wine child change reset desktop ownership") + } + command("destroy", "desktop", "") + empty := waitTitle(0, 0, "") + if empty.Epoch == wine.Epoch { + t.Fatal("lost foreground kept its epoch") + } +} diff --git a/internal/braille/braille.go b/internal/braille/braille.go new file mode 100644 index 0000000..c4eb8d8 --- /dev/null +++ b/internal/braille/braille.go @@ -0,0 +1,276 @@ +// Package braille provides the initial, device-independent BrlAPI diagnostic. +package braille + +import ( + "context" + "errors" + "fmt" + "io" + "runtime" + "strings" + "time" +) + +var ErrUnavailable = errors.New("BrlAPI support is unavailable; rebuild with -tags brlapi") + +type Geometry struct{ Columns, Rows int } + +func (g Geometry) Cells() (int, error) { + if g.Columns <= 0 || g.Rows <= 0 || g.Columns > 4096 || g.Rows > 4096/g.Columns { + return 0, errors.New("unsupported braille display geometry") + } + return g.Columns * g.Rows, nil +} + +type Key int + +// Frame is an uncontracted line. Cursor is a zero-based rune offset into Text; +// -1 hides the cursor. The helper converts it to BrlAPI's one-based cell. +type Frame struct { + Text string `json:"text"` + Cursor int `json:"cursor"` + ID uint64 `json:"id"` + Contract bool `json:"contract,omitempty"` + Table string `json:"table,omitempty"` + ExpandAtCursor bool `json:"expandAtCursor,omitempty"` + WordWrap bool `json:"wordWrap,omitempty"` + Dots []byte `json:"dots,omitempty"` + // Routing metadata stays in the parent, never in the helper protocol. + Routes []TextRoute `json:"-"` + Virtual *VirtualRoute `json:"-"` + Document *DocumentRoute `json:"-"` +} + +// DocumentRoute identifies the page and review epoch which produced a frame. +// Each TextRoute still maps cells to the individual native text object. +type DocumentRoute struct { + Epoch uint64 + FocusBus, FocusPath, DocumentBus, DocumentPath string +} + +// VirtualRoute maps a temporary text frame to a generation-owned cursor. +// End includes the synthetic end-of-line cell when the cursor is there. +type VirtualRoute struct { + Generation uint64 + Start, End, SourceStart int +} + +// TextRoute maps a half-open span of uncontracted cells to source characters. +// End-of-line indicator cells clamp to the end of SourceText. +type TextRoute struct { + Start, End, SourceStart, TextLength int + BusName, Path, SourceText string +} + +type RoutingEvent struct { + ID uint64 `json:"id"` + Offset int `json:"offset"` +} + +const ( + NoKey Key = iota + PanLeft + PanRight + // Route keys encode the zero-based physical cell as RouteBase + cell. + RouteBase Key = 0x10000 +) + +// Backend calls are serialized by the session owner. ReadKey must not wait +// for input. Only supported commands are claimed; other keys stay with BRLTTY. +type Backend interface { + Open() (Geometry, error) + Write(text string, cursor int) error // cursor: 0 hides it, otherwise one-based + ReadKey() (Key, error) + Close() error +} + +// viewport holds displayed cells and their source offsets for routing. +// Uncontracted text uses one Unicode rune per cell; liblouis supplies maps +// when a frame requests contraction. +type viewport struct { + text []rune + width, offset int + cursor int + id uint64 + inputPositions []int + wordWrap bool + dots []byte + panHistory []int +} + +func (v *viewport) replace(text string) { + v.setFrame(Frame{Text: text, Cursor: -1}) +} + +func (v *viewport) setFrame(frame Frame) error { + length := len([]rune(frame.Text)) + if frame.Cursor < -1 || frame.Cursor > length { + return errors.New("invalid braille cursor offset") + } + positions := make([]int, length) + if len(frame.Dots) != 0 && len(frame.Dots) != length { + return errors.New("invalid braille indicator length") + } + for i := range positions { + positions[i] = i + } + if frame.Contract && frame.Text != "" { + translated, mapped, cursor, err := translate(frame.Text, frame.Table, frame.Cursor, frame.ExpandAtCursor) + if err != nil { + return err + } + frame.Text, positions, frame.Cursor = translated, mapped, cursor + } + if frame.Cursor == len([]rune(frame.Text)) { + frame.Text += " " + positions = append(positions, length) + } + v.text = []rune(strings.Map(func(r rune) rune { + if r < 32 || r >= 127 && r < 160 { + return ' ' + } + return r + }, frame.Text)) + v.offset = 0 + v.cursor = frame.Cursor + v.id = frame.ID + v.inputPositions = positions + v.wordWrap = frame.WordWrap + v.panHistory = nil + v.dots = make([]byte, len(positions)) + for index, source := range positions { + end := source + 1 + if frame.Contract { + end = length + for _, next := range positions[index+1:] { + if next > source { + end = next + break + } + } + } + for input := source; input < min(end, len(frame.Dots)); input++ { + v.dots[index] |= frame.Dots[input] + } + } + if frame.Cursor >= v.width && v.width > 0 { + v.offset = frame.Cursor / v.width * v.width + } + return nil +} + +func (v *viewport) route(key Key) (RoutingEvent, bool) { + cell := int(key - RouteBase) + if key < RouteBase || cell < 0 || cell >= v.width || v.offset+cell >= v.visible_end() { + return RoutingEvent{}, false + } + return RoutingEvent{ID: v.id, Offset: v.inputPositions[v.offset+cell]}, true +} + +func (v *viewport) pan(key Key) bool { + previous := v.offset + switch key { + case PanLeft: + if len(v.panHistory) > 0 { + v.offset = v.panHistory[len(v.panHistory)-1] + v.panHistory = v.panHistory[:len(v.panHistory)-1] + } else { + v.offset = max(0, v.offset-v.width) + } + case PanRight: + if next := v.visible_end(); next < len(v.text) { + v.panHistory = append(v.panHistory, v.offset) + v.offset = next + } + } + return previous != v.offset +} + +func (v *viewport) frame() string { + end := v.visible_end() + return string(v.text[v.offset:end]) + strings.Repeat(" ", v.width-(end-v.offset)) +} + +func (v *viewport) displayDots() []byte { + result := make([]byte, v.width) + copy(result, v.dots[v.offset:v.visible_end()]) + return result +} + +func (v *viewport) displayCursor() int { + if v.cursor < v.offset || v.cursor >= v.visible_end() { + return 0 + } + return v.cursor - v.offset + 1 +} + +func braille_space(cell rune) bool { return cell == ' ' || cell == '\u2800' } + +// Pad the remainder of a wrapped page instead of showing half of the next +// word. Overlong words still advance by the display width. Do not hide a caret +// which the initial viewport was positioned to show. +func (v *viewport) visible_end() int { + end := min(len(v.text), v.offset+v.width) + if v.wordWrap && end < len(v.text) && !braille_space(v.text[end]) && + !braille_space(v.text[end-1]) { + for boundary := end - 1; boundary > v.offset; boundary-- { + if braille_space(v.text[boundary]) { + if v.cursor >= boundary+1 && v.cursor < end { + return end + } + return boundary + 1 + } + } + } + return end +} + +// Diagnostic uses only a generic fixture, never live application content. +// It owns the backend until cancellation or error and always releases it. +func Diagnostic(ctx context.Context, backend Backend, output io.Writer) (result error) { + if err := ctx.Err(); err != nil { + return err + } + // Keep every BrlAPI operation on the connection's original OS thread. + runtime.LockOSThread() + defer runtime.UnlockOSThread() + geometry, err := backend.Open() + // Close also cleans up a partially opened connection. + defer func() { result = errors.Join(result, backend.Close()) }() + if err != nil { + return fmt.Errorf("connect to BRLTTY: %w", err) + } + cells, err := geometry.Cells() + if err != nil { + return err + } + if err := ctx.Err(); err != nil { + return err + } + v := viewport{width: cells} + v.replace("Cthulhu braille test. Pan right to read this sentence, then pan left to return.") + if err := backend.Write(v.frame(), 0); err != nil { + return err + } + if _, err := fmt.Fprintf(output, "BrlAPI connected: %d columns, %d rows. Use display pan keys; Ctrl+C exits.\n", geometry.Columns, geometry.Rows); err != nil { + return err + } + ticker := time.NewTicker(20 * time.Millisecond) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return nil + case <-ticker.C: + key, err := backend.ReadKey() + if err != nil { + return err + } + if v.pan(key) { + if err := backend.Write(v.frame(), 0); err != nil { + return err + } + } + } + } +} diff --git a/internal/braille/braille_test.go b/internal/braille/braille_test.go new file mode 100644 index 0000000..7314d20 --- /dev/null +++ b/internal/braille/braille_test.go @@ -0,0 +1,222 @@ +package braille + +import ( + "bytes" + "context" + "errors" + "io" + "strings" + "testing" +) + +func TestViewportUnicodePanningAndReplacement(t *testing.T) { + v := viewport{width: 4} + v.replace("é界abcde") + if got := v.frame(); got != "é界ab" { + t.Fatalf("first frame: %q", got) + } + if v.pan(PanLeft) { + t.Fatal("panned before beginning") + } + if !v.pan(PanRight) || v.frame() != "cde " { + t.Fatalf("second frame: %q", v.frame()) + } + if v.pan(PanRight) { + t.Fatal("panned past end") + } + if !v.pan(PanLeft) || v.frame() != "é界ab" { + t.Fatal("could not return to first frame") + } + v.pan(PanRight) + v.replace("x") + if v.offset != 0 || v.frame() != "x " { + t.Fatalf("replacement retained old cells: %q", v.frame()) + } + v.replace("") + if v.frame() != " " { + t.Fatal("empty frame was not cleared") + } + v.replace("\x00\n\t\x7f") + if v.frame() != " " { + t.Fatal("control characters reached display") + } +} + +func TestViewportWordWrapAndIndicators(t *testing.T) { + v := viewport{width: 6} + if err := v.setFrame(Frame{Text: "one two three", Cursor: -1, WordWrap: true, + Dots: []byte{0, 0, 0, 0, 0x40, 0x40, 0, 0, 0, 0, 0, 0, 0}}); err != nil { + t.Fatal(err) + } + if v.frame() != "one " { + t.Fatalf("first wrapped frame=%q", v.frame()) + } + if !v.pan(PanRight) || v.frame() != "two " || v.offset != 4 || v.displayDots()[0] != 0x40 { + t.Fatalf("wrapped frame=%q offset=%d dots=%v", v.frame(), v.offset, v.displayDots()) + } + if !v.pan(PanLeft) || v.offset != 0 { + t.Fatalf("left offset=%d", v.offset) + } + if err := v.setFrame(Frame{Text: "abcdefghij", Cursor: -1, WordWrap: true}); err != nil { + t.Fatal(err) + } + if !v.pan(PanRight) || v.offset != 6 { + t.Fatalf("long word offset=%d", v.offset) + } +} + +func TestViewportCursorFollowsCaretAndPanning(t *testing.T) { + v := viewport{width: 4} + if err := v.setFrame(Frame{Text: "é界abcde", Cursor: 5}); err != nil { + t.Fatal(err) + } + if v.frame() != "cde " || v.displayCursor() != 2 { + t.Fatalf("caret page: frame=%q cursor=%d", v.frame(), v.displayCursor()) + } + if !v.pan(PanLeft) || v.displayCursor() != 0 { + t.Fatal("cursor remained visible outside the panned viewport") + } + if !v.pan(PanRight) || v.displayCursor() != 2 { + t.Fatal("cursor did not reappear on its page") + } + if err := v.setFrame(Frame{Text: "abcd", Cursor: 4}); err != nil { + t.Fatal(err) + } + if v.frame() != " " || v.displayCursor() != 1 { + t.Fatalf("end-of-line cell: frame=%q cursor=%d", v.frame(), v.displayCursor()) + } + for _, cursor := range []int{-2, 5} { + if err := v.setFrame(Frame{Text: "abcd", Cursor: cursor}); err == nil { + t.Fatalf("accepted cursor %d", cursor) + } + } +} + +func TestGeometry(t *testing.T) { + for _, g := range []Geometry{{0, 1}, {20, 0}, {-1, 1}, {4097, 1}, {1, 4097}, {4096, 4096}} { + if _, err := g.Cells(); err == nil { + t.Errorf("accepted %+v", g) + } + } + if cells, err := (Geometry{20, 2}).Cells(); err != nil || cells != 40 { + t.Fatalf("multirow: %d, %v", cells, err) + } +} + +type fakeBackend struct { + geometry Geometry + openErr, writeErr, readErr, closeErr error + opens, closes int + writes []string + cursors []int + keys []Key + cancel context.CancelFunc +} + +func (f *fakeBackend) Open() (Geometry, error) { f.opens++; return f.geometry, f.openErr } +func (f *fakeBackend) Write(text string, cursor int) error { + f.writes = append(f.writes, text) + f.cursors = append(f.cursors, cursor) + return f.writeErr +} +func (f *fakeBackend) ReadKey() (Key, error) { + if len(f.keys) > 0 { + key := f.keys[0] + f.keys = f.keys[1:] + return key, f.readErr + } + if f.cancel != nil { + f.cancel() + } + return NoKey, f.readErr +} +func (f *fakeBackend) Close() error { f.closes++; return f.closeErr } + +func TestDiagnosticPansAndReleases(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + f := &fakeBackend{geometry: Geometry{20, 1}, keys: []Key{PanRight, PanLeft}, cancel: cancel} + var output bytes.Buffer + if err := Diagnostic(ctx, f, &output); err != nil { + t.Fatal(err) + } + if f.opens != 1 || f.closes != 1 || len(f.writes) != 3 { + t.Fatalf("lifecycle: %+v", f) + } + if f.writes[0] != f.writes[2] || f.writes[0] == f.writes[1] { + t.Fatalf("pan frames: %q", f.writes) + } + if !strings.Contains(output.String(), "20 columns, 1 rows") { + t.Fatal(output.String()) + } +} + +func TestDiagnosticFailureCleanup(t *testing.T) { + failure := errors.New("fake failure") + for _, stage := range []string{"open", "geometry", "write", "read", "close"} { + t.Run(stage, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + f := &fakeBackend{geometry: Geometry{20, 1}, cancel: cancel} + switch stage { + case "open": + f.openErr = failure + case "geometry": + f.geometry = Geometry{} + case "write": + f.writeErr = failure + case "read": + f.readErr = failure + case "close": + f.closeErr = failure + } + err := Diagnostic(ctx, f, io.Discard) + if err == nil { + t.Fatal("failure was lost") + } + if stage != "geometry" && !errors.Is(err, failure) { + t.Fatalf("lost cause: %v", err) + } + if f.closes != 1 { + t.Fatalf("close count: %d", f.closes) + } + if (stage == "open" || stage == "geometry") && len(f.writes) > 0 { + t.Fatal("wrote without a valid display") + } + }) + } +} + +func TestDiagnosticCanceledBeforeOpen(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + f := &fakeBackend{} + if err := Diagnostic(ctx, f, io.Discard); !errors.Is(err, context.Canceled) { + t.Fatal(err) + } + if f.opens != 0 { + t.Fatal("opened after cancellation") + } +} + +func TestViewportRoutingRejectsPaddingAndTracksReplacement(t *testing.T) { + v := viewport{width: 4} + if err := v.setFrame(Frame{ID: 1, Text: "é猫abc", Cursor: -1}); err != nil { + t.Fatal(err) + } + v.pan(PanRight) + if got, ok := v.route(RouteBase); !ok || got != (RoutingEvent{ID: 1, Offset: 4}) { + t.Fatalf("route %+v %v", got, ok) + } + for _, key := range []Key{PanLeft, RouteBase + 1, RouteBase + 4, RouteBase - 1} { + if _, ok := v.route(key); ok { + t.Fatalf("routed invalid cell %d", key) + } + } + if err := v.setFrame(Frame{ID: 2, Text: "new", Cursor: -1}); err != nil { + t.Fatal(err) + } + if got, ok := v.route(RouteBase + 1); !ok || got != (RoutingEvent{ID: 2, Offset: 1}) { + t.Fatalf("replacement route %+v %v", got, ok) + } +} diff --git a/internal/braille/client.go b/internal/braille/client.go new file mode 100644 index 0000000..b81ad73 --- /dev/null +++ b/internal/braille/client.go @@ -0,0 +1,120 @@ +package braille + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "runtime" + "time" +) + +// RunClient owns BrlAPI inside the disposable helper process. The parent can +// terminate this process if a native call blocks or BRLTTY disconnects. +func RunClient(ctx context.Context, backend Backend, input io.ReadCloser, ready io.Writer) (result error) { + // Keep the session on one OS thread. Migration between Open and ReadKey + // produced an unexpected EOF with the live BRLTTY connection. + runtime.LockOSThread() + defer runtime.UnlockOSThread() + geometry, err := backend.Open() + defer func() { result = errors.Join(result, backend.Close()) }() + if err != nil { + return err + } + cells, err := geometry.Cells() + if err != nil { + return err + } + if _, err := io.WriteString(ready, "ready\n"); err != nil { + return err + } + frames := make(chan Frame, 1) + readErrors := make(chan error, 1) + readDone := make(chan struct{}) + // The session owns its input reader: close unblocks Scan, then join it. + defer func() { _ = input.Close(); <-readDone }() + go func() { + defer close(readDone) + scanner := bufio.NewScanner(input) + scanner.Buffer(make([]byte, 4096), 65536) + for scanner.Scan() { + var frame Frame + if err := json.Unmarshal(scanner.Bytes(), &frame); err != nil { + readErrors <- fmt.Errorf("decode braille frame: %w", err) + return + } + offerLatestFrame(frames, frame) + } + readErrors <- scanner.Err() + }() + v := viewport{width: cells} + encoder := json.NewEncoder(ready) + ticker := time.NewTicker(20 * time.Millisecond) + defer ticker.Stop() + inputClosed := false + for { + if inputClosed && len(frames) == 0 { + return nil + } + select { + case <-ctx.Done(): + return nil + case err := <-readErrors: + if err != nil { + return err + } + inputClosed = true + readErrors = nil + case frame := <-frames: + if err := v.setFrame(frame); err != nil { + return err + } + if err := writeViewport(backend, &v); err != nil { + return err + } + case <-ticker.C: + key, err := backend.ReadKey() + if err != nil { + return err + } + if v.pan(key) { + if err := writeViewport(backend, &v); err != nil { + return err + } + } + if event, ok := v.route(key); ok { + if err := encoder.Encode(event); err != nil { + return err + } + } + } + } +} + +type dotWriter interface { + WriteWithDots(string, int, []byte) error +} + +func writeViewport(backend Backend, viewport *viewport) error { + if writer, ok := backend.(dotWriter); ok { + return writer.WriteWithDots(viewport.frame(), viewport.displayCursor(), viewport.displayDots()) + } + return backend.Write(viewport.frame(), viewport.displayCursor()) +} + +// The consumer may remove the old frame after the first nonblocking send +// fails. Draining must therefore also be nonblocking. +func offerLatestFrame(frames chan Frame, frame Frame) { + select { + case frames <- frame: + return + default: + } + select { + case <-frames: + default: + } + frames <- frame +} diff --git a/internal/braille/client_test.go b/internal/braille/client_test.go new file mode 100644 index 0000000..7e22925 --- /dev/null +++ b/internal/braille/client_test.go @@ -0,0 +1,111 @@ +package braille + +import ( + "bytes" + "context" + "io" + "strings" + "testing" + "time" +) + +type clientBackend struct { + fakeBackend + cancel context.CancelFunc +} + +func (backend *clientBackend) Write(text string, cursor int) error { + if err := backend.fakeBackend.Write(text, cursor); err != nil { + return err + } + backend.cancel() + return nil +} + +func TestRunClientShowsLiveFrameAndReleasesDisplay(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + backend := &clientBackend{fakeBackend: fakeBackend{geometry: Geometry{20, 1}}, cancel: cancel} + input := strings.NewReader("{\"text\":\"Save, push button\",\"cursor\":-1}\n") + var ready bytes.Buffer + if err := RunClient(ctx, backend, io.NopCloser(input), &ready); err != nil { + t.Fatal(err) + } + if ready.String() != "ready\n" || len(backend.writes) != 1 || + backend.writes[0] != "Save, push button " || backend.opens != 1 || backend.closes != 1 { + t.Fatalf("client lifecycle: ready=%q backend=%+v", ready.String(), backend) + } +} + +func TestRunClientPlacesCursorOnUnicodeCaret(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + backend := &clientBackend{fakeBackend: fakeBackend{geometry: Geometry{4, 1}}, cancel: cancel} + input := strings.NewReader("{\"text\":\"é界abcde\",\"cursor\":5}\n") + if err := RunClient(ctx, backend, io.NopCloser(input), &bytes.Buffer{}); err != nil { + t.Fatal(err) + } + if len(backend.writes) != 1 || backend.writes[0] != "cde " || + len(backend.cursors) != 1 || backend.cursors[0] != 2 { + t.Fatalf("writes=%q cursors=%v", backend.writes, backend.cursors) + } +} + +func TestRunClientRejectsInvalidCursorAndCloses(t *testing.T) { + backend := &fakeBackend{geometry: Geometry{4, 1}} + err := RunClient(context.Background(), backend, + io.NopCloser(strings.NewReader("{\"text\":\"abc\",\"cursor\":4}\n")), &bytes.Buffer{}) + if err == nil || backend.opens != 1 || backend.closes != 1 || len(backend.writes) != 0 { + t.Fatalf("error=%v backend=%+v", err, backend) + } +} + +func TestOfferLatestFrameReplacesPendingFrame(t *testing.T) { + frames := make(chan Frame, 1) + offerLatestFrame(frames, Frame{Text: "old"}) + offerLatestFrame(frames, Frame{Text: "new"}) + if frame := <-frames; frame.Text != "new" { + t.Fatalf("retained %q", frame.Text) + } + offerLatestFrame(frames, Frame{Text: "newer"}) + if frame := <-frames; frame.Text != "newer" { + t.Fatalf("lost empty-queue update: %q", frame.Text) + } +} + +type routingBackend struct{ fakeBackend } + +func (b *routingBackend) ReadKey() (Key, error) { + if len(b.writes) == 0 { + return NoKey, nil + } + return b.fakeBackend.ReadKey() +} + +func TestRunClientRoutesDisplayedFrameAfterPanningAndJoinsReader(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + input, writer := io.Pipe() + defer writer.Close() + backend := &routingBackend{fakeBackend{geometry: Geometry{4, 1}, keys: []Key{PanRight, RouteBase + 1}, cancel: cancel}} + var output bytes.Buffer + done := make(chan error, 1) + go func() { done <- RunClient(ctx, backend, input, &output) }() + if _, err := io.WriteString(writer, "{\"text\":\"é猫abcdef\",\"cursor\":-1,\"id\":42}\n"); err != nil { + t.Fatal(err) + } + if err := <-done; err != nil { + t.Fatal(err) + } + if output.String() != "ready\n{\"id\":42,\"offset\":5}\n" { + t.Fatalf("helper output %q", output.String()) + } + if backend.closes != 1 { + t.Fatalf("close count %d", backend.closes) + } + // The writer has deliberately remained open; return requires the session to + // close the blocked input reader and join it. + if _, err := writer.Write([]byte("x")); err == nil { + t.Fatal("reader still open") + } +} diff --git a/internal/braille/native.go b/internal/braille/native.go new file mode 100644 index 0000000..0581b33 --- /dev/null +++ b/internal/braille/native.go @@ -0,0 +1,225 @@ +//go:build brlapi && cgo + +package braille + +/* +#cgo LDFLAGS: -lbrlapi +#include +#include +#include +#include + +typedef struct cth_brl cth_brl; +struct cth_brl { + brlapi_handle_t *handle; + unsigned int columns, rows; + int opened, entered, failed; +}; + +// The default BrlAPI handler terminates the process and can dump a packet. +// Record a failure instead; never print display contents or packet payloads. +static void cth_exception(brlapi_handle_t *handle, int error, + brlapi_packetType_t type, const void *packet, size_t size) { + cth_brl *owner = brlapi__getClientData(handle); + if (owner) owner->failed = 1; +} + +static cth_brl *cth_alloc(void) { + cth_brl *s = calloc(1, sizeof(*s)); + if (!s) return NULL; + s->handle = calloc(1, brlapi_getHandleSize()); + if (!s->handle) { free(s); return NULL; } + return s; +} + +static int cth_open(cth_brl *s, int routing) { + // NULL settings use BrlAPI's normal local connection/authentication. + if (brlapi__openConnection(s->handle, NULL, NULL) < 0) return -1; + s->opened = 1; + brlapi__setClientData(s->handle, s); + brlapi__setExceptionHandler(s->handle, cth_exception); + if (brlapi__getDisplaySize(s->handle, &s->columns, &s->rows) < 0 || s->failed) return -1; + if (!s->columns || !s->rows || s->columns > 4096 || s->rows > 4096/s->columns) return -2; + // Screen readers take the root of their terminal path. BrlAPI prepends + // WINDOWPATH or XDG_VTNR, so this follows the active graphical session. + if (brlapi__enterTtyModeWithPath(s->handle, NULL, 0, NULL) < 0 || s->failed) return -3; + s->entered = 1; + if (brlapi__ignoreAllKeys(s->handle) < 0 || s->failed) return -4; + brlapi_keyCode_t keys[] = { + BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_FWINLT, + BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_FWINRT + }; + if (brlapi__acceptKeys(s->handle, brlapi_rangeType_key, keys, 2) < 0 || s->failed) return -4; + if (routing) { + brlapi_keyCode_t route = BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_ROUTE; + if (brlapi__acceptKeys(s->handle, brlapi_rangeType_command, &route, 1) < 0 || s->failed) return -4; + } + return 0; +} + +static int cth_write(cth_brl *s, const char *text, int size, int cursor, + const unsigned char *andMask, const unsigned char *orMask) { + if (s->failed) return -1; + brlapi_writeArguments_t args = BRLAPI_WRITEARGUMENTS_INITIALIZER; + args.regionBegin = 1; + args.regionSize = s->columns * s->rows; + args.text = text; + args.textSize = size; + args.charset = "UTF-8"; + args.cursor = cursor; + args.andMask = andMask; + args.orMask = orMask; + int result = brlapi__write(s->handle, &args); + return s->failed ? -1 : result; +} + +static int cth_read(cth_brl *s, char *error, size_t errorSize) { + if (s->failed) return -1; + brlapi_keyCode_t code; + int result = brlapi__readKey(s->handle, 0, &code); + if (s->failed) return -1; + if (result < 0 && brlapi_errno == BRLAPI_ERROR_LIBCERR && brlapi_libcerrno == EINTR) return 0; + if (result < 0) brlapi_strerror_r(&brlapi_error, error, errorSize); + if (result <= 0) return result; + if ((code & BRLAPI_KEY_TYPE_MASK) != BRLAPI_KEY_TYPE_CMD) return 0; + if ((code & BRLAPI_KEY_CMD_BLK_MASK) == BRLAPI_KEY_CMD_ROUTE) + return 0x10000 + (code & BRLAPI_KEY_CMD_ARG_MASK); + switch (code & BRLAPI_KEY_CODE_MASK) { + case BRLAPI_KEY_CMD_FWINLT: return 1; + case BRLAPI_KEY_CMD_FWINRT: return 2; + default: return 0; + } +} + +static int cth_close(cth_brl *s) { + int result = 0; + if (s->entered && !s->failed) result = brlapi__leaveTtyMode(s->handle); + if (s->failed) result = -1; + if (s->opened) brlapi__closeConnection(s->handle); + free(s->handle); + free(s); + return result; +} +*/ +import "C" + +import ( + "errors" + "sync" + "unicode/utf8" + "unsafe" +) + +type native struct { + mu sync.Mutex + session *C.cth_brl + cells int + routing bool +} + +func New() Backend { return &native{} } + +// NewRouting claims routing keys as well as pan commands for the live helper. +func NewRouting() Backend { return &native{routing: true} } + +func (n *native) Open() (Geometry, error) { + n.mu.Lock() + defer n.mu.Unlock() + if n.session != nil { + return Geometry{}, errors.New("BrlAPI connection already open") + } + s := C.cth_alloc() + if s == nil { + return Geometry{}, errors.New("allocate BrlAPI connection") + } + routing := C.int(0) + if n.routing { + routing = 1 + } + if code := C.cth_open(s, routing); code != 0 { + C.cth_close(s) + switch code { + case -2: + return Geometry{}, errors.New("unsupported braille display geometry") + case -3: + return Geometry{}, errors.New("acquire BrlAPI terminal path; check WINDOWPATH, XDG_VTNR, and terminal ownership") + case -4: + return Geometry{}, errors.New("configure BrlAPI commands") + default: + return Geometry{}, errors.New("BrlAPI connection or display query failed; check BRLTTY and authorization") + } + } + n.session = s + g := Geometry{Columns: int(s.columns), Rows: int(s.rows)} + n.cells, _ = g.Cells() + return g, nil +} + +func (n *native) Write(text string, cursor int) error { + return n.WriteWithDots(text, cursor, nil) +} + +func (n *native) WriteWithDots(text string, cursor int, dots []byte) error { + n.mu.Lock() + defer n.mu.Unlock() + if n.session == nil { + return errors.New("BrlAPI connection is closed") + } + if !utf8.ValidString(text) || utf8.RuneCountInString(text) != n.cells || cursor < 0 || cursor > n.cells { + return errors.New("invalid braille frame") + } + if len(dots) != 0 && len(dots) != n.cells { + return errors.New("invalid braille indicator length") + } + value := C.CString(text) + defer C.free(unsafe.Pointer(value)) + andMask := make([]byte, n.cells) + orMask := make([]byte, n.cells) + for index, cell := range []rune(text) { + andMask[index] = 0xff + if len(dots) != 0 { + orMask[index] = dots[index] + } + if cell >= 0x2800 && cell <= 0x28ff { + andMask[index] = 0 + orMask[index] |= byte(cell - 0x2800) + } + } + if C.cth_write(n.session, value, C.int(len(text)), C.int(cursor), + (*C.uchar)(unsafe.Pointer(&andMask[0])), (*C.uchar)(unsafe.Pointer(&orMask[0]))) < 0 { + return errors.New("BrlAPI display write failed") + } + return nil +} + +func (n *native) ReadKey() (Key, error) { + n.mu.Lock() + defer n.mu.Unlock() + if n.session == nil { + return NoKey, errors.New("BrlAPI connection is closed") + } + var detail [256]C.char + key := C.cth_read(n.session, &detail[0], C.size_t(len(detail))) + if key < 0 { + if detail[0] != 0 { + return NoKey, errors.New("BrlAPI key read failed: " + C.GoString(&detail[0])) + } + return NoKey, errors.New("BrlAPI key read failed after protocol exception") + } + return Key(key), nil +} + +func (n *native) Close() error { + n.mu.Lock() + defer n.mu.Unlock() + if n.session == nil { + return nil + } + result := C.cth_close(n.session) + n.session = nil + n.cells = 0 + if result < 0 { + return errors.New("release BrlAPI terminal failed") + } + return nil +} diff --git a/internal/braille/native_test.go b/internal/braille/native_test.go new file mode 100644 index 0000000..8989953 --- /dev/null +++ b/internal/braille/native_test.go @@ -0,0 +1,20 @@ +//go:build brlapi && cgo + +package braille + +import "testing" + +func TestNativeClosedLifecycle(t *testing.T) { + backend := New() + if err := backend.Write("", 0); err == nil { + t.Fatal("write on closed connection succeeded") + } + if _, err := backend.ReadKey(); err == nil { + t.Fatal("read on closed connection succeeded") + } + for range 2 { + if err := backend.Close(); err != nil { + t.Fatal(err) + } + } +} diff --git a/internal/braille/regions.go b/internal/braille/regions.go new file mode 100644 index 0000000..2953524 --- /dev/null +++ b/internal/braille/regions.go @@ -0,0 +1,42 @@ +package braille + +import ( + "errors" + "strings" + "unicode/utf8" +) + +// Region is one semantic piece of a braille line. Cursor is a zero-based rune +// offset within Text, including the position just after the final rune. +type Region struct { + Text string + Cursor int +} + +// Line follows Python Cthulhu's Line: regions are concatenated exactly as +// supplied and one region may own the visible cursor. A focus of -1 hides it. +type Line struct { + Regions []Region + Focus int +} + +func (line Line) Frame() (Frame, error) { + if line.Focus < -1 || line.Focus >= len(line.Regions) { + return Frame{}, errors.New("invalid focused braille region") + } + var text strings.Builder + cursor := -1 + position := 0 + for index, region := range line.Regions { + length := utf8.RuneCountInString(region.Text) + if index == line.Focus { + if region.Cursor < 0 || region.Cursor > length { + return Frame{}, errors.New("invalid braille region cursor") + } + cursor = position + region.Cursor + } + text.WriteString(region.Text) + position += length + } + return Frame{Text: text.String(), Cursor: cursor}, nil +} diff --git a/internal/braille/regions_test.go b/internal/braille/regions_test.go new file mode 100644 index 0000000..702fa77 --- /dev/null +++ b/internal/braille/regions_test.go @@ -0,0 +1,35 @@ +package braille + +import ( + "reflect" + "testing" +) + +func TestLineComposesFocusedRegionWithoutChangingSpacing(t *testing.T) { + line := Line{Regions: []Region{ + {Text: "Context "}, + {Text: "é界", Cursor: 1}, + {Text: " entry"}, + }, Focus: 1} + frame, err := line.Frame() + if err != nil || !reflect.DeepEqual(frame, Frame{Text: "Context é界 entry", Cursor: 9}) { + t.Fatalf("frame=%+v err=%v", frame, err) + } + line.Focus = -1 + frame, err = line.Frame() + if err != nil || frame.Cursor != -1 { + t.Fatalf("unfocused frame=%+v err=%v", frame, err) + } +} + +func TestLineRejectsInvalidFocusAndCursor(t *testing.T) { + for _, line := range []Line{ + {Focus: 0}, + {Regions: []Region{{Text: "x"}}, Focus: -2}, + {Regions: []Region{{Text: "x", Cursor: 2}}, Focus: 0}, + } { + if _, err := line.Frame(); err == nil { + t.Fatalf("accepted invalid line %+v", line) + } + } +} diff --git a/internal/braille/tables.go b/internal/braille/tables.go new file mode 100644 index 0000000..105fa81 --- /dev/null +++ b/internal/braille/tables.go @@ -0,0 +1,56 @@ +package braille + +import ( + "os" + "path/filepath" + "sort" + "strings" +) + +const tableDirectory = "/usr/share/liblouis/tables" + +type TableOption struct { + Label string + File string +} + +// AvailableTables lists installed literary and computer tables for the +// current message locale. English US also offers UEB tables. +func AvailableTables() []TableOption { + locale := "" + for _, key := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} { + if value := os.Getenv(key); value != "" { + locale = value + break + } + } + return tablesForLocale(tableDirectory, locale) +} + +func tablesForLocale(dir, locale string) []TableOption { + locale = strings.ToLower(strings.ReplaceAll(strings.Split(strings.Split(locale, ".")[0], "@")[0], "_", "-")) + if locale == "" || locale == "c" || locale == "posix" { + locale = "en-us" + } + entries, err := os.ReadDir(dir) + if err != nil { + return nil + } + var result []TableOption + for _, entry := range entries { + name := entry.Name() + lower := strings.ToLower(name) + if entry.IsDir() || !(strings.HasSuffix(lower, ".ctb") || strings.HasSuffix(lower, ".utb")) || + strings.Contains(lower, "interline") || strings.Contains(lower, "mathtext") || + !(strings.HasPrefix(lower, locale+"-") || locale == "en-us" && strings.HasPrefix(lower, "en-ueb-")) { + continue + } + label := strings.TrimSuffix(strings.TrimSuffix(name, ".ctb"), ".utb") + label = strings.ReplaceAll(label, "-g1", " Grade 1") + label = strings.ReplaceAll(label, "-g2", " Grade 2") + label = strings.ReplaceAll(label, "-g3", " Grade 3") + result = append(result, TableOption{Label: label, File: filepath.Join(dir, name)}) + } + sort.Slice(result, func(i, j int) bool { return result[i].Label < result[j].Label }) + return result +} diff --git a/internal/braille/tables_test.go b/internal/braille/tables_test.go new file mode 100644 index 0000000..110f29a --- /dev/null +++ b/internal/braille/tables_test.go @@ -0,0 +1,23 @@ +package braille + +import ( + "os" + "path/filepath" + "testing" +) + +func TestTablesForLocaleIncludesUSEnglishAndUEB(t *testing.T) { + dir := t.TempDir() + for _, name := range []string{"en-us-g1.ctb", "en-us-g2.ctb", "en-ueb-g2.ctb", "en-us-interline.ctb", "en-gb-g1.utb", "fr-fr-g2.ctb"} { + if err := os.WriteFile(filepath.Join(dir, name), nil, 0600); err != nil { + t.Fatal(err) + } + } + options := tablesForLocale(dir, "en_US.UTF-8") + if len(options) != 3 || options[0].Label != "en-ueb Grade 2" || options[2].File != filepath.Join(dir, "en-us-g2.ctb") { + t.Fatalf("US tables = %+v", options) + } + if options = tablesForLocale(dir, "fr_FR.UTF-8"); len(options) != 1 || options[0].Label != "fr-fr Grade 2" { + t.Fatalf("French tables = %+v", options) + } +} diff --git a/internal/braille/translate_native.go b/internal/braille/translate_native.go new file mode 100644 index 0000000..6923bc7 --- /dev/null +++ b/internal/braille/translate_native.go @@ -0,0 +1,117 @@ +//go:build brlapi && cgo + +package braille + +/* +#cgo pkg-config: liblouis +#include +#include +*/ +import "C" + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "sort" + "strings" + "unsafe" +) + +// translate retains liblouis's output-to-input positions so a routing key +// addresses the original text rather than a cell in the shortened line. +func translate(text, table string, cursor int, expand bool) (string, []int, int, error) { + if table == "" { + table = defaultContractionTable() + } + cTable := C.CString(table) + defer C.free(unsafe.Pointer(cTable)) + if C.lou_checkTable(cTable) == 0 { + return "", nil, 0, fmt.Errorf("invalid liblouis table %q", table) + } + source := []rune(text) + in := make([]C.widechar, len(source)) + for index, value := range source { + in[index] = C.widechar(value) + } + // Supply a bounded output buffer; translation fails if a table needs more. + out := make([]C.widechar, len(source)*8+32) + inputPos := make([]C.int, len(out)) + outputPos := make([]C.int, len(in)) + inLength, outLength := C.int(len(in)), C.int(len(out)) + cursorPos := C.int(cursor) + mode := C.int(C.dotsIO) + if expand && cursor >= 0 && cursor < len(source) && source[cursor] != ' ' { + mode |= C.compbrlAtCursor + } + if C.lou_translate(cTable, &in[0], &inLength, &out[0], &outLength, nil, nil, + &outputPos[0], &inputPos[0], &cursorPos, mode) == 0 { + return "", nil, 0, errors.New("liblouis translation failed") + } + if int(inLength) != len(in) || outLength < 0 || int(outLength) > len(out) { + return "", nil, 0, errors.New("liblouis returned invalid translation lengths") + } + result := make([]rune, int(outLength)) + positions := make([]int, int(outLength)) + for index := range result { + if out[index]&0x8000 == 0 || out[index]&^C.widechar(0x80ff) != 0 { + return "", nil, 0, errors.New("liblouis returned invalid braille dots") + } + result[index] = 0x2800 + rune(out[index]&0xff) + positions[index] = int(inputPos[index]) + if positions[index] < 0 || positions[index] >= len(source) { + return "", nil, 0, errors.New("liblouis returned invalid position map") + } + } + if cursor == len(source) { + cursorPos = outLength + } + if cursor < 0 { + cursorPos = -1 + } + if cursorPos < -1 || cursorPos > outLength { + return "", nil, 0, errors.New("liblouis returned invalid cursor") + } + return string(result), positions, int(cursorPos), nil +} + +func defaultContractionTable() string { + locale := "" + for _, name := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} { + if value := os.Getenv(name); value != "" { + locale = value + break + } + } + locale = strings.ToLower(strings.ReplaceAll(strings.Split(strings.Split(locale, ".")[0], "@")[0], "_", "-")) + if locale == "" || locale == "c" || locale == "posix" { + locale = "en-us" + } + entries, err := os.ReadDir("/usr/share/liblouis/tables") + if err != nil { + return "en-us-g2.ctb" + } + var candidates []string + for _, entry := range entries { + name := strings.ToLower(entry.Name()) + if entry.IsDir() || !strings.HasPrefix(name, locale+"-") || + !(strings.HasSuffix(name, ".ctb") || strings.HasSuffix(name, ".utb")) || + strings.Contains(name, "interline") || strings.Contains(name, "mathtext") { + continue + } + candidates = append(candidates, entry.Name()) + } + sort.Strings(candidates) + for _, grade := range []string{"g2", "g1", "comp6", "comp8"} { + for _, name := range candidates { + if strings.Contains(name, grade) { + return filepath.Join("/usr/share/liblouis/tables", name) + } + } + } + if len(candidates) > 0 { + return filepath.Join("/usr/share/liblouis/tables", candidates[0]) + } + return "en-us-g2.ctb" +} diff --git a/internal/braille/translate_native_test.go b/internal/braille/translate_native_test.go new file mode 100644 index 0000000..747cf6f --- /dev/null +++ b/internal/braille/translate_native_test.go @@ -0,0 +1,73 @@ +//go:build brlapi && cgo + +package braille + +import "testing" + +func TestContractedWordWrapAndPartialSelection(t *testing.T) { + v := viewport{width: 4} + if err := v.setFrame(Frame{Text: "the cat", Cursor: -1, Contract: true, + Table: "en-us-g2.ctb", WordWrap: true, Dots: []byte{0, 0x40, 0, 0, 0, 0, 0}}); err != nil { + t.Fatal(err) + } + if v.frame() != "⠮⠀ " || v.displayDots()[0] != 0x40 { + t.Fatalf("wrapped contraction=%q dots=%v", v.frame(), v.displayDots()) + } + if _, ok := v.route(RouteBase + 2); ok { + t.Fatal("padding cell was routed into undisplayed text") + } + if !v.pan(PanRight) || v.frame() != "⠉⠁⠞ " || v.offset != 2 { + t.Fatalf("panned word=%q offset=%d", v.frame(), v.offset) + } + if !v.pan(PanLeft) || v.offset != 0 { + t.Fatal("wrapped pan left did not restore its page") + } +} + +func TestContractionMapsCursorAndRouting(t *testing.T) { + for _, cursor := range []int{-1, 0, 4, len([]rune("the cat"))} { + v := viewport{width: 4} + if err := v.setFrame(Frame{ID: 7, Text: "the cat", Cursor: cursor, Contract: true, Table: "en-us-g2.ctb"}); err != nil { + t.Fatal(err) + } + if cursor == -1 && (string(v.text) != "⠮⠀⠉⠁⠞" || v.inputPositions[0] != 0 || v.inputPositions[1] != 3) { + t.Fatalf("unexpected translation %q, positions %v", string(v.text), v.inputPositions) + } + if cursor == -1 { + if event, ok := v.route(RouteBase + 1); !ok || event != (RoutingEvent{ID: 7, Offset: 3}) { + t.Fatalf("contracted route = %+v, %v", event, ok) + } + if !v.pan(PanRight) { + t.Fatal("contracted line did not pan") + } + if event, ok := v.route(RouteBase); !ok || event != (RoutingEvent{ID: 7, Offset: 6}) { + t.Fatalf("panned contracted route = %+v, %v", event, ok) + } + } + if len(v.text) >= len([]rune("the cat")) && cursor < 0 { + t.Fatalf("text was not contracted: %q", string(v.text)) + } + for cell, original := range v.inputPositions { + if original < 0 || original > len([]rune("the cat")) { + t.Fatalf("cell %d has invalid source offset %d", cell, original) + } + } + if cursor == len([]rune("the cat")) && v.cursor != len(v.text)-1 { + t.Fatalf("end cursor %d, text %q", v.cursor, string(v.text)) + } + } + if _, _, _, err := translate("the", "missing-table.ctb", -1, false); err == nil { + t.Fatal("missing table accepted") + } + plain, _, _, err := translate("the cat", "en-us-g2.ctb", 0, false) + if err != nil { + t.Fatal(err) + } + expanded, _, _, err := translate("the cat", "en-us-g2.ctb", 0, true) + if err != nil { + t.Fatal(err) + } + if plain == expanded { + t.Fatalf("computer braille at cursor did not expand word: %q", expanded) + } +} diff --git a/internal/braille/translate_unavailable.go b/internal/braille/translate_unavailable.go new file mode 100644 index 0000000..e8ca815 --- /dev/null +++ b/internal/braille/translate_unavailable.go @@ -0,0 +1,9 @@ +//go:build !brlapi || !cgo + +package braille + +import "errors" + +func translate(string, string, int, bool) (string, []int, int, error) { + return "", nil, 0, errors.New("contracted braille requires a helper built with -tags brlapi and liblouis") +} diff --git a/internal/braille/unavailable.go b/internal/braille/unavailable.go new file mode 100644 index 0000000..6d601d3 --- /dev/null +++ b/internal/braille/unavailable.go @@ -0,0 +1,12 @@ +//go:build !brlapi || !cgo + +package braille + +type unavailable struct{} + +func New() Backend { return unavailable{} } +func NewRouting() Backend { return unavailable{} } +func (unavailable) Open() (Geometry, error) { return Geometry{}, ErrUnavailable } +func (unavailable) Write(string, int) error { return ErrUnavailable } +func (unavailable) ReadKey() (Key, error) { return NoKey, ErrUnavailable } +func (unavailable) Close() error { return nil } diff --git a/internal/braille/unavailable_test.go b/internal/braille/unavailable_test.go new file mode 100644 index 0000000..8ac85ef --- /dev/null +++ b/internal/braille/unavailable_test.go @@ -0,0 +1,21 @@ +//go:build !brlapi || !cgo + +package braille + +import ( + "bytes" + "context" + "errors" + "testing" +) + +func TestDiagnosticUnavailable(t *testing.T) { + var output bytes.Buffer + err := Diagnostic(context.Background(), New(), &output) + if !errors.Is(err, ErrUnavailable) { + t.Fatalf("error: %v", err) + } + if output.Len() != 0 { + t.Fatal("unavailable backend reported connected") + } +} diff --git a/internal/clipboard/clipboard.go b/internal/clipboard/clipboard.go new file mode 100644 index 0000000..65d7901 --- /dev/null +++ b/internal/clipboard/clipboard.go @@ -0,0 +1,109 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package clipboard + +import ( + "encoding/json" + "io" + "net/url" + "os" + "path" + "path/filepath" + "strconv" + "strings" + "syscall" +) + +// Snapshot contains only the clipboard facts needed for Cthulhu's announcement. +type Snapshot struct { + Text string `json:"text"` + HasText bool `json:"hasText"` + Image bool `json:"image"` + URIs []string `json:"uris"` +} + +// WriteMessage is called only by the short lived clipboard helper process. +// URI filesystem checks stay here so the parent can enforce a read deadline. +func WriteMessage(output io.Writer) error { + snapshot, err := read_native() + if err != nil { + return err + } + return json.NewEncoder(output).Encode(struct { + Message string `json:"message"` + }{Message: Format(snapshot)}) +} + +func Format(snapshot Snapshot) string { + if snapshot.Image { + return "The clipboard contains a image" + } + if len(snapshot.URIs) != 0 { + return format_uris(snapshot.URIs) + } + if snapshot.HasText { + return "Text in clipboard " + snapshot.Text + } + return "The clipboard is empty" +} + +func format_uris(uris []string) string { + objects := make([]string, 0, len(uris)) + for _, raw := range uris { + if raw == "" { + continue + } + parsed, err := url.Parse(raw) + if err != nil { + objects = append(objects, raw) + continue + } + name := path.Base(parsed.Path) + if name == "." || name == "/" { + name = raw + } + parts := []string{name} + if parsed.Scheme == "file" && (parsed.Host == "" || parsed.Host == "localhost") { + localPath := parsed.Path + link := false + if info, err := os.Lstat(localPath); err == nil && info.Mode()&os.ModeSymlink != 0 { + link = true + } + if info, err := os.Stat(localPath); err == nil { + if info.IsDir() { + parts = append(parts, "Folder") + } else if info.Mode().IsRegular() { + parts = append(parts, "File") + } + if !link && is_mount(localPath, info) { + parts = append(parts, "Disk") + } + } + if link { + parts = append(parts, "Link") + } + } + objects = append(objects, strings.Join(parts, " ")) + } + if len(objects) == 0 { + return "The clipboard is empty" + } + label := " Object in clipboard " + if len(objects) > 1 { + label = " Objects in clipboard " + } + return strconv.Itoa(len(objects)) + label + strings.Join(objects, " ") +} + +func is_mount(localPath string, info os.FileInfo) bool { + parentPath := filepath.Dir(filepath.Clean(localPath)) + parent, err := os.Stat(parentPath) + if err != nil { + return false + } + currentStat, currentOK := info.Sys().(*syscall.Stat_t) + parentStat, parentOK := parent.Sys().(*syscall.Stat_t) + return currentOK && parentOK && (currentStat.Dev != parentStat.Dev || currentStat.Ino == parentStat.Ino) +} diff --git a/internal/clipboard/clipboard_test.go b/internal/clipboard/clipboard_test.go new file mode 100644 index 0000000..5bc1f79 --- /dev/null +++ b/internal/clipboard/clipboard_test.go @@ -0,0 +1,56 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package clipboard + +import ( + "net/url" + "os" + "path/filepath" + "testing" +) + +func TestFormatClipboardContent(t *testing.T) { + for _, test := range []struct { + name string + snapshot Snapshot + want string + }{ + {"empty", Snapshot{}, "The clipboard is empty"}, + {"text", Snapshot{HasText: true, Text: "hello"}, "Text in clipboard hello"}, + {"empty text", Snapshot{HasText: true}, "Text in clipboard "}, + {"image overrides text", Snapshot{HasText: true, Text: "hello", Image: true}, "The clipboard contains a image"}, + } { + t.Run(test.name, func(t *testing.T) { + if got := Format(test.snapshot); got != test.want { + t.Fatalf("got %q, want %q", got, test.want) + } + }) + } +} + +func TestFormatURIObjects(t *testing.T) { + root := t.TempDir() + folder := filepath.Join(root, "a folder") + file := filepath.Join(root, "a file") + link := filepath.Join(root, "link") + if err := os.Mkdir(folder, 0700); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(file, []byte("x"), 0600); err != nil { + t.Fatal(err) + } + if err := os.Symlink(file, link); err != nil { + t.Fatal(err) + } + uri := func(localPath string) string { return (&url.URL{Scheme: "file", Path: localPath}).String() } + snapshot := Snapshot{URIs: []string{uri(folder), uri(file), uri(link)}} + want := "3 Objects in clipboard a folder Folder a file File link File Link" + if got := Format(snapshot); got != want { + t.Fatalf("got %q, want %q", got, want) + } + if got := Format(Snapshot{URIs: []string{"", uri(file)}}); got != "1 Object in clipboard a file File" { + t.Fatalf("single URI = %q", got) + } +} diff --git a/internal/clipboard/native.go b/internal/clipboard/native.go new file mode 100644 index 0000000..816a4db --- /dev/null +++ b/internal/clipboard/native.go @@ -0,0 +1,68 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package clipboard + +/* +#cgo pkg-config: gtk+-3.0 +#include + +typedef struct { + char *text; + char **uris; + int image; + int initialized; +} ClipboardSnapshot; + +static ClipboardSnapshot read_clipboard(void) { + ClipboardSnapshot result = {0}; + if (!gtk_init_check(NULL, NULL)) return result; + result.initialized = 1; + GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + if (!clipboard) { result.initialized = 0; return result; } + result.text = gtk_clipboard_wait_for_text(clipboard); + GdkPixbuf *image = gtk_clipboard_wait_for_image(clipboard); + if (image) { + result.image = 1; + g_object_unref(image); + } + if (gtk_clipboard_wait_is_uris_available(clipboard)) { + result.uris = gtk_clipboard_wait_for_uris(clipboard); + } + return result; +} + +static void free_clipboard(ClipboardSnapshot *snapshot) { + g_free(snapshot->text); + g_strfreev(snapshot->uris); +} +*/ +import "C" + +import ( + "errors" + "unsafe" +) + +func read_native() (Snapshot, error) { + native := C.read_clipboard() + defer C.free_clipboard(&native) + if native.initialized == 0 { + return Snapshot{}, errors.New("cannot access the desktop clipboard") + } + snapshot := Snapshot{Image: native.image != 0, HasText: native.text != nil} + if native.text != nil { + snapshot.Text = C.GoString(native.text) + } + if native.uris != nil { + for offset := uintptr(0); ; offset += unsafe.Sizeof(uintptr(0)) { + uri := *(**C.char)(unsafe.Add(unsafe.Pointer(native.uris), offset)) + if uri == nil { + break + } + snapshot.URIs = append(snapshot.URIs, C.GoString(uri)) + } + } + return snapshot, nil +} diff --git a/internal/clipboard/watch.c b/internal/clipboard/watch.c new file mode 100644 index 0000000..eb499a6 --- /dev/null +++ b/internal/clipboard/watch.c @@ -0,0 +1,70 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "watch.h" +static GQueue changes = G_QUEUE_INIT; +static gboolean watchEnabled; +static unsigned long long watchEpoch; + +void clipboard_watch_free(ClipboardChange *change) { + if (--change->references) return; + g_free(change->text); + g_free(change); +} + +static void text_received(GtkClipboard *clipboard, const gchar *text, gpointer data) { + (void)clipboard; + ClipboardChange *change = data; + change->text = g_strdup(text); + change->done = TRUE; + clipboard_watch_free(change); +} + +static void targets_received(GtkClipboard *clipboard, GdkAtom *targets, gint count, gpointer data) { + ClipboardChange *change = data; + if (!watchEnabled || watchEpoch != change->epoch || !targets || + gtk_targets_include_image(targets, count, FALSE) || + gtk_targets_include_uri(targets, count) || + !gtk_targets_include_text(targets, count)) { + change->done = TRUE; + clipboard_watch_free(change); + return; + } + // No image or file payload is requested, only a text target. + gtk_clipboard_request_text(clipboard, text_received, change); +} + +static void owner_changed(GtkClipboard *clipboard, GdkEventOwnerChange *event, gpointer data) { + (void)data; + if (!watchEnabled) return; + if (g_queue_get_length(&changes) >= 128) + clipboard_watch_free(g_queue_pop_head(&changes)); + ClipboardChange *change = g_new0(ClipboardChange, 1); + change->epoch = watchEpoch; + change->timestamp = event->time; + change->deadline = g_get_monotonic_time() + 3 * G_TIME_SPAN_SECOND; + change->references = 2; // queue and asynchronous callback + g_queue_push_tail(&changes, change); + gtk_clipboard_request_targets(clipboard, targets_received, change); +} + +int clipboard_watch_init(void) { + if (!gtk_init_check(NULL, NULL)) return 0; + GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + if (!clipboard) return 0; + g_signal_connect(clipboard, "owner-change", G_CALLBACK(owner_changed), NULL); + return 1; +} + +void clipboard_watch_enable(int enabled, unsigned long long epoch) { + watchEnabled = enabled; + watchEpoch = epoch; +} +void clipboard_watch_iterate(void) { + while (gtk_events_pending()) gtk_main_iteration_do(FALSE); +} +ClipboardChange *clipboard_watch_next(void) { + ClipboardChange *change = g_queue_peek_head(&changes); + if (!change || (!change->done && g_get_monotonic_time() < change->deadline)) return NULL; + return g_queue_pop_head(&changes); +} diff --git a/internal/clipboard/watch.go b/internal/clipboard/watch.go new file mode 100644 index 0000000..902a4ad --- /dev/null +++ b/internal/clipboard/watch.go @@ -0,0 +1,100 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package clipboard + +/* +#include "watch.h" +*/ +import "C" + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "io" + "runtime" + "time" +) + +type WatchSettings struct { + Enabled bool + Epoch uint64 +} + +type TextChange struct { + Text string + Epoch uint64 + Timestamp uint32 + Ready bool +} + +// WatchText keeps a GTK selection connection warm so successive clipboard +// changes are captured asynchronously and emitted in arrival order. Disabled +// applications never request clipboard targets or contents. +func WatchText(ctx context.Context, input io.Reader, output io.Writer) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + settings := make(chan WatchSettings, 1) + inputDone := make(chan error, 1) + go func() { + scanner := bufio.NewScanner(input) + scanner.Buffer(make([]byte, 1024), 4096) + for scanner.Scan() { + var request WatchSettings + if err := json.Unmarshal(scanner.Bytes(), &request); err != nil { + inputDone <- err + return + } + select { + case settings <- request: + case <-ctx.Done(): + return + } + } + inputDone <- scanner.Err() + }() + if C.clipboard_watch_init() == 0 { + return errors.New("cannot watch clipboard on this display") + } + encoder := json.NewEncoder(output) + if err := encoder.Encode(TextChange{Ready: true}); err != nil { + return err + } + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-inputDone: + return err + case request := <-settings: + enabled := C.int(0) + if request.Enabled { + enabled = 1 + } + C.clipboard_watch_enable(enabled, C.ulonglong(request.Epoch)) + if err := encoder.Encode(TextChange{Ready: true, Epoch: request.Epoch}); err != nil { + return err + } + case <-ticker.C: + C.clipboard_watch_iterate() + for { + change := C.clipboard_watch_next() + if change == nil { + break + } + value := TextChange{Text: C.GoString(change.text), Epoch: uint64(change.epoch), Timestamp: uint32(change.timestamp)} + C.clipboard_watch_free(change) + if err := encoder.Encode(value); err != nil { + return err + } + } + } + } +} diff --git a/internal/clipboard/watch.h b/internal/clipboard/watch.h new file mode 100644 index 0000000..8a9bccb --- /dev/null +++ b/internal/clipboard/watch.h @@ -0,0 +1,17 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include +typedef struct { + char *text; + unsigned long long epoch; + gboolean done; + gint64 deadline; + guint timestamp; + int references; +} ClipboardChange; +int clipboard_watch_init(void); +void clipboard_watch_enable(int enabled, unsigned long long epoch); +void clipboard_watch_iterate(void); +ClipboardChange *clipboard_watch_next(void); +void clipboard_watch_free(ClipboardChange *change); diff --git a/internal/config/application_store_test.go b/internal/config/application_store_test.go new file mode 100644 index 0000000..efce51a --- /dev/null +++ b/internal/config/application_store_test.go @@ -0,0 +1,53 @@ +package config + +import ( + "path/filepath" + "testing" +) + +func TestApplicationSettingsPersistWithoutChangingGlobalProfile(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + global := DefaultSettings() + global.TimeFormat = "24-hour" + if err := store.Save(global); err != nil { + t.Fatal(err) + } + application := global + application.TimeFormat = "12-hour" + if err := store.SaveForApplication("Example Editor", application); err != nil { + t.Fatal(err) + } + other := global + other.DateFormat = "numbers-ymd" + if err := store.SaveForApplication("Other Editor", other); err != nil { + t.Fatal(err) + } + reopened, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + loaded, err := reopened.Load() + if err != nil || loaded.TimeFormat != "24-hour" || loaded.ActiveProfile != "default" { + t.Fatalf("global = %+v, %v", loaded, err) + } + appLoaded, found, err := reopened.LoadForApplication("Example Editor") + if err != nil || !found || appLoaded.TimeFormat != "12-hour" { + t.Fatalf("application = %+v, found %t, %v", appLoaded, found, err) + } + missing, found, err := reopened.LoadForApplication("Unknown Editor") + if err != nil || found || missing.TimeFormat != "24-hour" { + t.Fatalf("unmapped = %+v, found %t, %v", missing, found, err) + } + global.DateFormat = "numbers-mdy" + if err := reopened.Save(global); err != nil { + t.Fatal(err) + } + appLoaded, found, err = reopened.LoadForApplication("Example Editor") + if err != nil || !found || appLoaded.TimeFormat != "12-hour" || appLoaded.DateFormat != "numbers-mdy" { + t.Fatalf("application after global save = %+v, found %t, %v", appLoaded, found, err) + } +} diff --git a/internal/config/bindings_test.go b/internal/config/bindings_test.go new file mode 100644 index 0000000..6e9ce8f --- /dev/null +++ b/internal/config/bindings_test.go @@ -0,0 +1,42 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package config + +import ( + "git.stormux.org/storm/cthulhu/internal/input" + "path/filepath" + "reflect" + "testing" +) + +func TestKeyBindingsSaveLoadAndIsolation(t *testing.T) { + store, err := NewStore(filepath.Join(t.TempDir(), "settings.toml")) + if err != nil { + t.Fatal(err) + } + settings := DefaultSettings() + settings.KeyBindings = []input.BindingOverride{ + {Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Preferences, Keys: []string{"Cthulhu+Ctrl+F8"}}, + {Layout: input.LaptopKeyboardLayout, Scope: "browse", Command: input.DocumentNextHeading, Keys: []string{}}, + } + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + loaded, err := store.Load() + if err != nil || !reflect.DeepEqual(settings.KeyBindings, loaded.KeyBindings) { + t.Fatalf("round trip: %+v %v", loaded.KeyBindings, err) + } + loaded.KeyBindings[0].Keys[0] = "F1" + if store.Current().KeyBindings[0].Keys[0] == "F1" { + t.Fatal("caller changed store bindings") + } + settings.KeyBindings = nil + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + loaded, err = store.Load() + if err != nil || len(loaded.KeyBindings) != 0 { + t.Fatalf("reset failed: %+v %v", loaded.KeyBindings, err) + } +} diff --git a/internal/config/capitalization.go b/internal/config/capitalization.go new file mode 100644 index 0000000..b3548e4 --- /dev/null +++ b/internal/config/capitalization.go @@ -0,0 +1,13 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +// SetCapitalizationStyle adapts the old exclusive choice to independent cues. +// Pitch has always been configured separately and is left untouched. +func (settings *Settings) SetCapitalizationStyle(style string) { + settings.CapitalizationStyle = style + settings.BeepForCapitals = style == "icon" + settings.SayCapForCapitals = style == "spell" +} diff --git a/internal/config/capitalization_test.go b/internal/config/capitalization_test.go new file mode 100644 index 0000000..fa39235 --- /dev/null +++ b/internal/config/capitalization_test.go @@ -0,0 +1,104 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +import ( + "fmt" + "path/filepath" + "testing" +) + +func TestCapitalChoicesPersistIndependently(t *testing.T) { + defaults := DefaultSettings() + if !defaults.RaisePitchForCapitals || defaults.BeepForCapitals || defaults.SayCapForCapitals { + t.Fatal("only capital pitch should default on") + } + store, err := NewStore(filepath.Join(t.TempDir(), "settings.toml")) + if err != nil { + t.Fatal(err) + } + for mask := 0; mask < 8; mask++ { + settings := defaults + settings.RaisePitchForCapitals = mask&1 != 0 + settings.BeepForCapitals = mask&2 != 0 + settings.SayCapForCapitals = mask&4 != 0 + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + loaded, err := Load(store.path) + if err != nil { + t.Fatal(err) + } + checkCapitalChoices(t, loaded, settings) + app := defaults + if err := store.SaveForApplication("editor", app); err != nil { + t.Fatal(err) + } + loaded, found, err := store.LoadForApplication("editor") + if err != nil || !found { + t.Fatalf("application load: %v, %v", found, err) + } + checkCapitalChoices(t, loaded, app) + loaded, err = store.Load() + if err != nil { + t.Fatal(err) + } + checkCapitalChoices(t, loaded, settings) + } +} + +func checkCapitalChoices(t *testing.T, got, want Settings) { + t.Helper() + if got.RaisePitchForCapitals != want.RaisePitchForCapitals || + got.BeepForCapitals != want.BeepForCapitals || got.SayCapForCapitals != want.SayCapForCapitals { + t.Fatalf("capital choices: pitch=%v beep=%v cap=%v; want %v %v %v", + got.RaisePitchForCapitals, got.BeepForCapitals, got.SayCapForCapitals, + want.RaisePitchForCapitals, want.BeepForCapitals, want.SayCapForCapitals) + } +} + +func TestOldCapitalStylesMigrate(t *testing.T) { + for _, style := range []string{"none", "spell", "icon"} { + for _, versioned := range []bool{false, true} { + contents := fmt.Sprintf("[general]\ncapitalizationStyle = %q\n", style) + if versioned { + contents = fmt.Sprintf("schema-version = 2\nactive-profile = 'default'\n[profiles.default.speech]\ncapitalization-style = %q\n", style) + } + settings, err := Load(writeConfig(t, contents)) + if err != nil { + t.Fatal(err) + } + if !settings.RaisePitchForCapitals || settings.BeepForCapitals != (style == "icon") || settings.SayCapForCapitals != (style == "spell") { + t.Fatalf("old %s, versioned=%v: %+v", style, versioned, settings) + } + } + } + settings, err := Load(writeConfig(t, "schema-version = 2\nactive-profile = 'default'\n[profiles.default.speech]\ncapitalization-style = 'spell'\nsay-cap-for-capitals = false\nbeep-for-capitals = true\nraise-pitch-for-capitals = false\n")) + if err != nil { + t.Fatal(err) + } + if settings.RaisePitchForCapitals || settings.SayCapForCapitals || !settings.BeepForCapitals { + t.Fatal("explicit independent choices did not override old style") + } +} + +func TestCapitalPitchCanBeDisabledWithExplicitUppercaseVoice(t *testing.T) { + settings := DefaultSettings() + normal, upper := 4.0, 8.0 + settings.DefaultVoice.AveragePitch = &normal + settings.UppercaseVoice.AveragePitch = &upper + settings.RaisePitchForCapitals = false + if got := *EffectiveVoice(settings, "uppercase").AveragePitch; got != normal { + t.Fatalf("pitch=%v", got) + } + settings.DefaultVoice.AveragePitch = nil + if EffectiveVoice(settings, "uppercase").AveragePitch != nil { + t.Fatal("server default pitch was lost") + } + settings.RaisePitchForCapitals = true + if got := *EffectiveVoice(settings, "uppercase").AveragePitch; got != upper { + t.Fatalf("pitch=%v", got) + } +} diff --git a/internal/config/clipboard_test.go b/internal/config/clipboard_test.go new file mode 100644 index 0000000..7d1d218 --- /dev/null +++ b/internal/config/clipboard_test.go @@ -0,0 +1,16 @@ +package config + +import ( + "path/filepath" + "testing" +) + +func TestClipboardReadingDefaultsOffForExistingSettings(t *testing.T) { + settings, err := Load(filepath.Join("testdata", "settings-v2.toml")) + if err != nil { + t.Fatal(err) + } + if settings.Reading.AutomaticallyReadClipboardChanges { + t.Fatal("omitted clipboard reading preference defaults on") + } +} diff --git a/internal/config/codec.go b/internal/config/codec.go new file mode 100644 index 0000000..7b4c044 --- /dev/null +++ b/internal/config/codec.go @@ -0,0 +1,145 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "bytes" + "errors" + "fmt" + "sort" + "strings" + + "github.com/pelletier/go-toml/v2" +) + +func defaultDocument() writableDocument { + return writableDocument{ + SchemaVersion: CurrentSchemaVersion, + ActiveProfile: "default", + Profiles: map[string]writableProfile{ + "default": profileFromSettings(DefaultSettings()), + }, + Applications: make(map[string]string), + } +} + +func decodeWritable(contents []byte) (Settings, error) { + _, settings, err := decodeDocument(contents) + return settings, err +} + +func decodeDocument(contents []byte) (writableDocument, Settings, error) { + var envelope struct { + SchemaVersion int `toml:"schema-version"` + } + if err := toml.Unmarshal(contents, &envelope); err != nil { + return writableDocument{}, Settings{}, fmt.Errorf("parse settings: %w", err) + } + if envelope.SchemaVersion != CurrentSchemaVersion { + return writableDocument{}, Settings{}, fmt.Errorf("unsupported settings schema version %d; expected %d", envelope.SchemaVersion, CurrentSchemaVersion) + } + var document writableDocument + decoder := toml.NewDecoder(bytes.NewReader(contents)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&document); err != nil { + var strictError *toml.StrictMissingError + if errors.As(err, &strictError) { + return writableDocument{}, Settings{}, fmt.Errorf("parse settings schema %d: %s", CurrentSchemaVersion, strictError.String()) + } + return writableDocument{}, Settings{}, fmt.Errorf("parse settings schema %d: %w", CurrentSchemaVersion, err) + } + settings, err := effectiveSettings(document) + if err != nil { + return writableDocument{}, Settings{}, err + } + return document, settings, nil +} + +func effectiveSettings(document writableDocument) (Settings, error) { + if strings.TrimSpace(document.ActiveProfile) == "" { + return Settings{}, errors.New("validate configuration: active-profile is empty") + } + profile, exists := document.Profiles[document.ActiveProfile] + if !exists { + return Settings{}, fmt.Errorf("validate configuration: active profile %q does not exist", document.ActiveProfile) + } + for _, name := range sortedKeys(document.Profiles) { + candidate := document.Profiles[name] + if strings.TrimSpace(name) != name || name == "" { + return Settings{}, fmt.Errorf("validate configuration: invalid profile name %q", name) + } + if err := validateCommandValue("profile name", name); err != nil { + return Settings{}, err + } + candidateSettings := DefaultSettings() + applyProfile(&candidateSettings, candidate) + if err := validate(candidateSettings); err != nil { + return Settings{}, fmt.Errorf("profile %q: %w", name, err) + } + } + for _, application := range sortedKeys(document.Applications) { + profileName := document.Applications[application] + if strings.TrimSpace(application) != application || application == "" { + return Settings{}, fmt.Errorf("validate configuration: invalid application identifier %q", application) + } + if err := validateCommandValue("application identifier", application); err != nil { + return Settings{}, err + } + if _, exists := document.Profiles[profileName]; !exists { + return Settings{}, fmt.Errorf("validate configuration: application %q selects missing profile %q", application, profileName) + } + } + settings := DefaultSettings() + applyProfile(&settings, profile) + settings.ActiveProfile = document.ActiveProfile + return settings, nil +} + +func sortedKeys[Value any](values map[string]Value) []string { + keys := make([]string, 0, len(values)) + for key := range values { + keys = append(keys, key) + } + sort.Strings(keys) + return keys +} + +func encodeWritable(settings Settings) ([]byte, error) { + document := defaultDocument() + profileName := settings.ActiveProfile + if profileName == "" { + profileName = document.ActiveProfile + } + document.ActiveProfile = profileName + document.Profiles = map[string]writableProfile{profileName: profileFromSettings(settings)} + return encodeDocument(document) +} + +func encodeDocument(document writableDocument) ([]byte, error) { + if document.SchemaVersion != CurrentSchemaVersion { + return nil, fmt.Errorf("encode settings schema version %d; expected %d", document.SchemaVersion, CurrentSchemaVersion) + } + if _, err := effectiveSettings(document); err != nil { + return nil, err + } + contents, err := toml.Marshal(document) + if err != nil { + return nil, fmt.Errorf("encode settings: %w", err) + } + return contents, nil +} diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..b3f75bf --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,109 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "errors" + "fmt" + "io" + "os" + "path/filepath" + + "github.com/pelletier/go-toml/v2" +) + +const maxConfigSize = 1024 * 1024 + +func DefaultPath() (string, error) { + if dataHome := os.Getenv("XDG_DATA_HOME"); dataHome != "" { + return filepath.Join(dataHome, "cthulhu", "user-settings-go.toml"), nil + } + home, err := os.UserHomeDir() + if err != nil { + return "", fmt.Errorf("resolve home directory: %w", err) + } + return filepath.Join(home, ".local", "share", "cthulhu", "user-settings-go.toml"), nil +} + +// Load reads legacy Python settings or the current versioned schema without +// modifying the file. A present schema marker always selects strict decoding. +func Load(path string) (Settings, error) { + settings := DefaultSettings() + if path == "" { + var err error + path, err = DefaultPath() + if err != nil { + return Settings{}, err + } + } + settings.Path = path + + file, err := os.Open(path) + if errors.Is(err, os.ErrNotExist) { + return settings, nil + } + if err != nil { + return Settings{}, fmt.Errorf("open configuration: %w", err) + } + defer file.Close() + + contents, err := io.ReadAll(io.LimitReader(file, maxConfigSize+1)) + if err != nil { + return Settings{}, fmt.Errorf("read configuration: %w", err) + } + if len(contents) > maxConfigSize { + return Settings{}, fmt.Errorf("configuration exceeds %d bytes", maxConfigSize) + } + + var envelope struct { + SchemaVersion *int `toml:"schema-version"` + } + if err := toml.Unmarshal(contents, &envelope); err != nil { + return Settings{}, fmt.Errorf("parse configuration: %w", err) + } + if envelope.SchemaVersion != nil { + settings, err := decodeWritable(contents) + if err != nil { + return Settings{}, err + } + settings.Path = path + settings.Loaded = true + return settings, nil + } + + var parsed document + if err := toml.Unmarshal(contents, &parsed); err != nil { + return Settings{}, fmt.Errorf("parse configuration: %w", err) + } + apply(&settings, parsed.General) + + profileName := selectedProfile(parsed.General, parsed.Profiles) + if profileName != "" { + profile, exists := parsed.Profiles[profileName] + if !exists { + return Settings{}, fmt.Errorf("configured profile %q does not exist", profileName) + } + apply(&settings, profile) + } + settings.ActiveProfile = profileName + settings.Loaded = true + if err := validate(settings); err != nil { + return Settings{}, err + } + return settings, nil +} diff --git a/internal/config/config_test.go b/internal/config/config_test.go new file mode 100644 index 0000000..2765559 --- /dev/null +++ b/internal/config/config_test.go @@ -0,0 +1,284 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "os" + "path/filepath" + "reflect" + "strings" + "testing" +) + +func TestLoadVersionedSettingsMatchesStore(t *testing.T) { + path := filepath.Join("testdata", "settings-v2.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + want, err := store.Load() + if err != nil { + t.Fatal(err) + } + got, err := Load(path) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("runtime settings = %#v, want store settings %#v", got, want) + } +} + +func TestLegacySayAllStyleMapsToRuntimeChoice(t *testing.T) { + for legacy, want := range map[string]string{"0": "line", "1": "sentence"} { + settings, err := Load(writeConfig(t, "[general]\nsayAllStyle = "+legacy+"\n")) + if err != nil { + t.Fatal(err) + } + if settings.SayAllStyle != want { + t.Fatalf("legacy Say All style %s loaded as %q", legacy, settings.SayAllStyle) + } + } +} + +func TestLoadRejectsInvalidVersionedSettingsWithoutWriting(t *testing.T) { + for name, contents := range map[string]string{ + "old": "schema-version = 1\n[general]\n", + "future": "schema-version = 3\nactive-profile = 'default'\n[profiles.default]\n", + "zero": "schema-version = 0\n[general]\n", + "negative": "schema-version = -1\n[general]\n", + "wrong type": "schema-version = '1'\n[general]\n", + "unknown field": "schema-version = 2\nactive-profile = 'default'\n[profiles.default]\nfuture-setting = true\n", + "legacy field": "schema-version = 2\nactive-profile = 'default'\n[profiles.default.speech]\nenableSpeech = false\n", + "invalid value": "schema-version = 2\nactive-profile = 'default'\n[profiles.default.sound]\nvolume = 2.0\n", + "malformed": "schema-version = 2\n[profiles\n", + } { + t.Run(name, func(t *testing.T) { + path := writeConfig(t, contents) + if _, err := Load(path); err == nil { + t.Fatal("Load accepted invalid versioned settings") + } + got, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if string(got) != contents { + t.Fatal("Load changed the settings file") + } + }) + } +} + +func TestLoadMergesGeneralAndStartingProfile(t *testing.T) { + path := writeConfig(t, ` +[general] +enableSpeech = true +speechServerFactory = "speechdispatcherfactory" +speakDescription = true +speechVerbosityLevel = 1 +verbalizePunctuationStyle = 2 +capitalizationStyle = "spell" +keyboardLayout = 1 +cthulhuModifierKeys = ["Insert", "KP_Insert"] +enableKeyEcho = true +enableEchoByCharacter = false +enableEchoByWord = true +enableEchoBySentence = false +enableAlphabeticKeys = true +enableNumericKeys = true +enablePunctuationKeys = false +enableSpace = true +enableModifierKeys = true +enableFunctionKeys = true +enableActionKeys = true +enableNavigationKeys = false +enableDiacriticalKeys = false +startingProfile = ["Quiet", "quiet"] +unknownFutureSetting = true + +[general.voices.default] +rate = 40.0 +average-pitch = 5.0 +gain = 8.0 + +[profiles.quiet] +speakDescription = false +enableKeyEcho = false +enableEchoByCharacter = true +enableEchoByWord = false +enableEchoBySentence = true +enableAlphabeticKeys = false +speechServerFactory = "cthulhu.speechdispatcherfactory" + +[profiles.quiet.voices.default] +rate = 75.0 + +[profiles.quiet.voices.default.family] +name = "Generic Voice" +lang = "en" +dialect = "US" +`) + + settings, err := Load(path) + if err != nil { + t.Fatalf("Load: %v", err) + } + if !settings.Loaded || settings.ActiveProfile != "quiet" { + t.Fatalf("loaded/profile = %v/%q, want true/quiet", settings.Loaded, settings.ActiveProfile) + } + if settings.SpeakDescription || settings.EnableKeyEcho { + t.Fatal("profile boolean overrides were not applied") + } + if !settings.EnableEchoByCharacter || settings.EnableEchoByWord || !settings.EnableEchoBySentence || + settings.EnableAlphabeticKeys || settings.EnablePunctuationKeys || + !settings.EnableNumericKeys || !settings.EnableSpace || !settings.EnableModifierKeys || + !settings.EnableFunctionKeys || !settings.EnableActionKeys || settings.EnableNavigationKeys || settings.EnableDiacriticalKeys { + t.Fatalf("typing echo settings = %+v", settings) + } + if settings.SpeechServerFactory != "cthulhu.speechdispatcherfactory" { + t.Fatalf("speech server factory = %q", settings.SpeechServerFactory) + } + if settings.DefaultVoice.Rate == nil || *settings.DefaultVoice.Rate != 75 { + t.Fatalf("voice rate = %v, want 75", settings.DefaultVoice.Rate) + } + if settings.DefaultVoice.Gain == nil || *settings.DefaultVoice.Gain != 8 { + t.Fatalf("voice gain = %v, want inherited value 8", settings.DefaultVoice.Gain) + } + if settings.DefaultVoice.Family == nil || settings.DefaultVoice.Family.Name != "Generic Voice" { + t.Fatalf("voice family = %#v", settings.DefaultVoice.Family) + } +} + +func TestLoadMissingFileUsesDefaults(t *testing.T) { + settings, err := Load(filepath.Join(t.TempDir(), "missing.toml")) + if err != nil { + t.Fatalf("Load: %v", err) + } + if settings.Loaded { + t.Fatal("missing file reported as loaded") + } + if !settings.EnableSpeech || !settings.SpeakDescription || !settings.Reading.EnableMnemonicSpeaking || settings.KeyboardLayout != 1 { + t.Fatalf("unexpected defaults: %#v", settings) + } +} + +func TestDefaultPathUsesGoDevelopmentFile(t *testing.T) { + dataHome := filepath.Join(t.TempDir(), "data") + t.Setenv("XDG_DATA_HOME", dataHome) + path, err := DefaultPath() + if err != nil { + t.Fatal(err) + } + if want := filepath.Join(dataHome, "cthulhu", "user-settings-go.toml"); path != want { + t.Fatalf("DefaultPath = %q, want %q", path, want) + } +} + +func TestDefaultLoadDoesNotFallBackToPythonSettings(t *testing.T) { + dataHome := filepath.Join(t.TempDir(), "data") + t.Setenv("XDG_DATA_HOME", dataHome) + directory := filepath.Join(dataHome, "cthulhu") + if err := os.MkdirAll(directory, 0o700); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(directory, "user-settings.toml"), []byte("[general]\nenableSpeech = false\n"), 0o600); err != nil { + t.Fatal(err) + } + settings, err := Load("") + if err != nil { + t.Fatal(err) + } + if settings.Loaded || !settings.EnableSpeech || filepath.Base(settings.Path) != "user-settings-go.toml" { + t.Fatalf("default settings = %#v", settings) + } +} + +func TestLoadRejectsInvalidSettings(t *testing.T) { + path := writeConfig(t, "[general]\nkeyboardLayout = 9\n") + _, err := Load(path) + if err == nil || !strings.Contains(err.Error(), "keyboardLayout") { + t.Fatalf("Load error = %v, want keyboardLayout validation error", err) + } +} + +func TestLoadRejectsOversizedFile(t *testing.T) { + path := filepath.Join(t.TempDir(), "user-settings.toml") + if err := os.WriteFile(path, []byte(strings.Repeat("#", maxConfigSize+1)), 0o600); err != nil { + t.Fatalf("write oversized config: %v", err) + } + _, err := Load(path) + if err == nil || !strings.Contains(err.Error(), "exceeds") { + t.Fatalf("Load error = %v, want size error", err) + } +} + +func writeConfig(t *testing.T, contents string) string { + t.Helper() + path := filepath.Join(t.TempDir(), "user-settings.toml") + if err := os.WriteFile(path, []byte(contents), 0o600); err != nil { + t.Fatalf("write config: %v", err) + } + return path +} + +func TestSoundSettingsMergeAndValidate(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + if err := os.WriteFile(path, []byte(`[general] +soundVolume = 0.4 +soundTheme = "default" +[profiles.default] +enableSound = true +soundVolume = 0.7 +soundSink = "pulse" +playSoundForRole = true +playSoundForState = true +roleSoundPresentation = "sound_only" +`), 0o600); err != nil { + t.Fatal(err) + } + settings, err := Load(path) + if err != nil { + t.Fatal(err) + } + if settings.SoundVolume != 0.7 || !settings.PlaySoundForRole || !settings.PlaySoundForState || settings.RoleSoundPresentation != "sound_only" { + t.Fatalf("sound settings = %+v", settings) + } + if err := os.WriteFile(path, []byte("[general]\nroleSoundPresentation = \"speech_only\"\n"), 0o600); err != nil { + t.Fatal(err) + } + if _, err := Load(path); err != nil { + t.Fatalf("speech-only role presentation was rejected: %v", err) + } + for _, line := range []string{`soundVolume = -0.1`, `soundVolume = 1.1`, `soundVolume = nan`, `soundTheme = "../other"`, `soundSink = "invalid"`, `roleSoundPresentation = "invalid"`} { + if err := os.WriteFile(path, []byte("[general]\n"+line+"\n"), 0o600); err != nil { + t.Fatal(err) + } + if _, err := Load(path); err == nil { + t.Fatalf("accepted %s", line) + } + } +} + +func TestLoadRejectsNonFiniteVoiceValues(t *testing.T) { + for _, value := range []string{"nan", "+inf", "-inf"} { + path := writeConfig(t, "[general.voices.default]\nrate = "+value+"\n") + if _, err := Load(path); err == nil || !strings.Contains(err.Error(), "default voice rate") { + t.Fatalf("Load rate %s error = %v", value, err) + } + } +} diff --git a/internal/config/defaults.go b/internal/config/defaults.go new file mode 100644 index 0000000..75ef09a --- /dev/null +++ b/internal/config/defaults.go @@ -0,0 +1,93 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import "git.stormux.org/storm/cthulhu/internal/input" + +func DefaultSettings() Settings { + return Settings{ + OCR: OCRSettings{Layout: 3, Scale: 1, Threshold: 200, RefreshInterval: 1500, ConfirmClick: true}, + TimeFormat: "locale", DateFormat: "locale", + EnableSound: true, SoundVolume: 0.5, SoundSink: "auto", SoundTheme: "default", + PlaySoundForRole: true, PlaySoundForState: true, PlaySoundForPositionInSet: true, + ProgressBar: DefaultProgressBarSettings(), + RoleSoundPresentation: "sound_and_speech", + EnableSpeech: true, + SpeechHistoryLimit: DefaultSpeechHistoryLimit, + SpeechInterruption: input.InterruptionSettings{Mode: input.InterruptAllKeys}, + Braille: BrailleOptions{Verbosity: 1, SelectionIndicator: 0xc0, LinkIndicator: 0xc0, + FlashMessages: true, FlashTime: 5000, FlashDetailed: true}, + SpeechServerFactory: "speechdispatcherfactory", + HardwareSpeechBaudRate: 9600, + SpeakDescription: true, + SpeechVerbosityLevel: 1, + SayAllStyle: "line", + TextAttributes: DefaultTextAttributes(), + Reading: ReadingSettings{ + AutomaticallyReadTitleChanges: true, + EnablePauseBreaks: true, + SpeakNumbersAsDigits: false, + SpeakMultiCaseStringsAsWords: false, + EnableIndentation: false, + IndentationPresentationMode: "speech", + OnlySpeakDisplayedText: false, + SpeakBlankLines: true, + EnableMnemonicSpeaking: true, + EnablePositionSpeaking: false, + EnableTutorialMessages: false, + MessagesAreDetailed: true, + UseColorNames: true, + SpeakMisspelledIndicator: true, + SpeakContextBlockquote: true, + SpeakContextList: true, + SpeakContextTable: true, + SpeakContextPanel: true, + SpeakContextLandmark: true, + SpeakContextNonLandmarkForm: true, + SayAllContextBlockquote: true, + SayAllContextList: true, + SayAllContextTable: true, + SayAllContextPanel: true, + SayAllContextLandmark: true, + SayAllContextNonLandmarkForm: true, + ReadFullRowInGUITable: true, + ReadFullRowInDocumentTable: true, + ReadFullRowInSpreadSheet: false, + }, + VerbalizePunctuationStyle: 1, + CapitalizationStyle: "none", + RaisePitchForCapitals: true, + KeyboardLayout: 1, + CthulhuModifierKeys: []string{"Insert", "KP_Insert"}, + UseCustomEchoForKey: true, + UseCustomEchoForCharacter: true, + EnableKeyEcho: true, + EnableEchoByCharacter: false, + EnableEchoByWord: false, + EnableEchoBySentence: false, + EnableAlphabeticKeys: true, + EnableNumericKeys: true, + EnablePunctuationKeys: true, + EnableSpace: true, + EnableModifierKeys: true, + EnableFunctionKeys: true, + EnableActionKeys: true, + EnableNavigationKeys: false, + EnableDiacriticalKeys: false, + } +} diff --git a/internal/config/greeter.go b/internal/config/greeter.go new file mode 100644 index 0000000..08c9b42 --- /dev/null +++ b/internal/config/greeter.go @@ -0,0 +1,86 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +import ( + "errors" + "fmt" + "io" + "os" + "path/filepath" +) + +// WriteGreeterSettings installs the effective saved profile at path. The caller +// must run as the destination account; no privileged filesystem writes are needed. +func WriteGreeterSettings(path string, settings Settings) error { + contents, err := GreeterSettings(settings) + if err != nil { + return err + } + if settings.Path != "" { + sourcePath, err := filepath.Abs(settings.Path) + if err != nil { + return err + } + targetPath, err := filepath.Abs(path) + if err != nil { + return err + } + source, sourceErr := os.Stat(settings.Path) + target, targetErr := os.Stat(path) + if sourcePath == targetPath || sourceErr == nil && targetErr == nil && os.SameFile(source, target) { + return errors.New("greeter copy cannot replace the source settings") + } + } + if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil { + return fmt.Errorf("create greeter settings directory: %w", err) + } + temporary, err := os.CreateTemp(filepath.Dir(path), ".greeter-settings-*.toml") + if err != nil { + return fmt.Errorf("create greeter settings copy: %w", err) + } + defer os.Remove(temporary.Name()) + if _, err := temporary.Write(contents); err != nil { + temporary.Close() + return err + } + if err := temporary.Sync(); err != nil { + temporary.Close() + return err + } + if err := temporary.Close(); err != nil { + return err + } + if err := os.Rename(temporary.Name(), path); err != nil { + return fmt.Errorf("replace greeter settings copy: %w", err) + } + return syncDirectory(filepath.Dir(path)) +} + +// GreeterSettings encodes a complete active profile without application mappings +// or other profiles. Tentacle registries are stored separately and are not copied. +func GreeterSettings(settings Settings) ([]byte, error) { + if err := validate(settings); err != nil { + return nil, err + } + return encodeDocument(writableDocument{ + SchemaVersion: CurrentSchemaVersion, + ActiveProfile: "greeter", + Profiles: map[string]writableProfile{"greeter": profileFromSettings(settings)}, + }) +} + +// ReadGreeterSettings reads the bounded snapshot from an already-open pipe. +// Reopening /dev/stdin after switching users can fail its ownership checks. +func ReadGreeterSettings(reader io.Reader) (Settings, error) { + contents, err := io.ReadAll(io.LimitReader(reader, maxConfigSize+1)) + if err != nil { + return Settings{}, fmt.Errorf("read greeter settings: %w", err) + } + if len(contents) > maxConfigSize { + return Settings{}, fmt.Errorf("greeter settings exceed %d bytes", maxConfigSize) + } + return decodeWritable(contents) +} diff --git a/internal/config/greeter_test.go b/internal/config/greeter_test.go new file mode 100644 index 0000000..019dc7d --- /dev/null +++ b/internal/config/greeter_test.go @@ -0,0 +1,110 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +import ( + "bytes" + "os" + "path/filepath" + "reflect" + "strings" + "testing" +) + +func TestGreeterCopyUsesOnlyEffectiveActiveProfile(t *testing.T) { + directory := t.TempDir() + sourcePath := filepath.Join(directory, "source.toml") + contents := []byte("schema-version = 2\nactive-profile = 'custom'\n" + + "[profiles.custom.speech.default-voice]\nrate = 73.0\n" + + "[profiles.custom.keyboard]\nlayout = 2\nscreen-reader-keys = ['Caps_Lock']\n" + + "[profiles.custom.braille]\nenabled = true\n" + + "[profiles.application.speech]\nenabled = false\n" + + "[applications]\n'example-editor' = 'application'\n") + if err := os.WriteFile(sourcePath, contents, 0o600); err != nil { + t.Fatal(err) + } + settings, err := Load(sourcePath) + if err != nil { + t.Fatal(err) + } + targetPath := filepath.Join(directory, "greeter.toml") + // Repeated exports must replace stale profiles and mappings too. + if err := os.WriteFile(targetPath, contents, 0o644); err != nil { + t.Fatal(err) + } + if err := WriteGreeterSettings(targetPath, settings); err != nil { + t.Fatal(err) + } + exported, err := Load(targetPath) + if err != nil { + t.Fatal(err) + } + settings.Path, settings.ActiveProfile = targetPath, "greeter" + if !reflect.DeepEqual(exported, settings) { + t.Fatalf("export changed effective settings: got %#v, want %#v", exported, settings) + } + data, _ := os.ReadFile(targetPath) + document, _, err := decodeDocument(data) + if err != nil || len(document.Profiles) != 1 || len(document.Applications) != 0 { + t.Fatalf("export retained other profiles: %+v, %v", document, err) + } + info, _ := os.Stat(targetPath) + if info.Mode().Perm() != 0o600 { + t.Fatalf("export permissions = %o", info.Mode().Perm()) + } + unchanged, _ := os.ReadFile(sourcePath) + if string(unchanged) != string(contents) { + t.Fatal("export changed source settings") + } +} + +func TestGreeterPipeRejectsInvalidOrOversizedSettings(t *testing.T) { + for _, contents := range []string{"", "schema-version = 999", strings.Repeat(" ", maxConfigSize+1)} { + if _, err := ReadGreeterSettings(strings.NewReader(contents)); err == nil { + t.Fatal("accepted invalid or oversized settings pipe") + } + } + settings := DefaultSettings() + settings.EnableEchoByWord = true + contents, err := GreeterSettings(settings) + if err != nil { + t.Fatal(err) + } + copied, err := ReadGreeterSettings(bytes.NewReader(contents)) + if err != nil || copied.ActiveProfile != "greeter" || !copied.EnableEchoByWord { + t.Fatalf("pipe round trip = %#v, error %v", copied, err) + } +} + +func TestGreeterCopyPreservesSourceAndExistingOutputOnFailure(t *testing.T) { + directory := t.TempDir() + source := filepath.Join(directory, "source.toml") + if err := os.WriteFile(source, []byte("original"), 0o600); err != nil { + t.Fatal(err) + } + settings := DefaultSettings() + settings.Path = source + alias := filepath.Join(directory, "alias.toml") + if err := os.Symlink(source, alias); err != nil { + t.Fatal(err) + } + for _, path := range []string{source, alias} { + if err := WriteGreeterSettings(path, settings); err == nil { + t.Fatal("export replaced its own source") + } + } + target := filepath.Join(directory, "target.toml") + if err := os.WriteFile(target, []byte("previous export"), 0o600); err != nil { + t.Fatal(err) + } + settings.SoundVolume = 2.0 + if err := WriteGreeterSettings(target, settings); err == nil { + t.Fatal("invalid settings were exported") + } + data, _ := os.ReadFile(target) + if string(data) != "previous export" { + t.Fatal("failed export changed existing output") + } +} diff --git a/internal/config/hardware_test.go b/internal/config/hardware_test.go new file mode 100644 index 0000000..357489a --- /dev/null +++ b/internal/config/hardware_test.go @@ -0,0 +1,61 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +import ( + "path/filepath" + "testing" +) + +func TestHardwareSettingsPersistInApplicationProfile(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + global := DefaultSettings() + if err := store.Save(global); err != nil { + t.Fatal(err) + } + application := global + application.SpeechServerFactory = "hardwarefactory" + application.SpeechOutputModule = "dectalk" + application.HardwareSpeechDevice = "/dev/ttyTEST0" + application.HardwareSpeechBaudRate = 19200 + if err := store.SaveForApplication("Example Editor", application); err != nil { + t.Fatal(err) + } + reopened, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + loaded, found, err := reopened.LoadForApplication("Example Editor") + if err != nil || !found || loaded.SpeechServerFactory != "hardwarefactory" || + loaded.SpeechOutputModule != "dectalk" || loaded.HardwareSpeechDevice != "/dev/ttyTEST0" || loaded.HardwareSpeechBaudRate != 19200 { + t.Fatalf("hardware profile=%+v found=%v error=%v", loaded, found, err) + } + loaded, err = reopened.Load() + if err != nil || loaded.SpeechServerFactory != "speechdispatcherfactory" || loaded.HardwareSpeechDevice != "" || loaded.HardwareSpeechBaudRate != 9600 { + t.Fatalf("hardware override changed global settings=%+v error=%v", loaded, err) + } +} + +func TestHardwareSettingsLoadPythonAndRejectInvalidDevices(t *testing.T) { + loaded, err := Load(writeConfig(t, `[general] +speechServerFactory = "hardwarefactory" +speechServerInfo = ["LiteTalk", "litetalk"] +hardwareSpeechDevice = "/dev/ttyTEST0" +hardwareSpeechBaudRate = 9600 +`)) + if err != nil || loaded.SpeechOutputModule != "litetalk" || loaded.HardwareSpeechDevice != "/dev/ttyTEST0" { + t.Fatalf("Python hardware settings=%+v error=%v", loaded, err) + } + for _, device := range []string{"", "auto", "ttyTEST0", "/dev/ttyTEST0\n"} { + loaded.HardwareSpeechDevice = device + if err := Validate(loaded); err == nil { + t.Fatalf("accepted device %q", device) + } + } +} diff --git a/internal/config/interruption_test.go b/internal/config/interruption_test.go new file mode 100644 index 0000000..4fe9060 --- /dev/null +++ b/internal/config/interruption_test.go @@ -0,0 +1,46 @@ +package config + +import ( + "path/filepath" + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestSpeechInterruptionPersistenceAndApplicationProfiles(t *testing.T) { + settings, err := Load(writeConfig(t, "schema-version = 2\nactive-profile = 'default'\n[profiles.default]\n")) + if err != nil || settings.SpeechInterruption.Mode != input.InterruptAllKeys { + t.Fatalf("omitted preference changed default: %+v, %v", settings.SpeechInterruption, err) + } + store, err := NewStore(filepath.Join(t.TempDir(), "settings.toml")) + if err != nil { + t.Fatal(err) + } + settings.SpeechInterruption = input.InterruptionSettings{Mode: input.InterruptCustomKeys, Keys: []string{"Tab", "Return", "Control_R"}} + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + loaded, err := store.Load() + if err != nil || !reflect.DeepEqual(settings.SpeechInterruption, loaded.SpeechInterruption) { + t.Fatalf("saved keys = %+v, %v", loaded.SpeechInterruption, err) + } + application := cloneSettings(loaded) + application.SpeechInterruption.Mode = input.InterruptCommonKeys + if err := store.SaveForApplication("Editor", application); err != nil { + t.Fatal(err) + } + app, found, err := store.LoadForApplication("Editor") + if err != nil || !found || app.SpeechInterruption.Mode != input.InterruptCommonKeys { + t.Fatalf("application settings = %+v, %t, %v", app.SpeechInterruption, found, err) + } + global, err := store.Load() + if err != nil || global.SpeechInterruption.Mode != input.InterruptCustomKeys { + t.Fatalf("application altered global = %+v, %v", global.SpeechInterruption, err) + } + copy := cloneSettings(global) + copy.SpeechInterruption.Keys[0] = "Escape" + if global.SpeechInterruption.Keys[0] != "Tab" { + t.Fatal("settings snapshots share mutable keys") + } +} diff --git a/internal/config/legacy.go b/internal/config/legacy.go new file mode 100644 index 0000000..f2405fa --- /dev/null +++ b/internal/config/legacy.go @@ -0,0 +1,140 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "strings" +) + +type rawReadingSettings struct { + EnablePauseBreaks *bool `toml:"enablePauseBreaks"` + SpeakNumbersAsDigits *bool `toml:"speakNumbersAsDigits"` + SpeakMultiCaseStringsAsWords *bool `toml:"speakMultiCaseStringsAsWords"` + EnableIndentation *bool `toml:"enableIndentation"` + OnlySpeakDisplayedText *bool `toml:"onlySpeakDisplayedText"` + SpeakBlankLines *bool `toml:"speakBlankLines"` + EnableMnemonicSpeaking *bool `toml:"enableMnemonicSpeaking"` + EnablePositionSpeaking *bool `toml:"enablePositionSpeaking"` + EnableTutorialMessages *bool `toml:"enableTutorialMessages"` + MessagesAreDetailed *bool `toml:"messagesAreDetailed"` + UseColorNames *bool `toml:"useColorNames"` + PresentTooltips *bool `toml:"presentToolTips"` + EnableMouseReview *bool `toml:"enableMouseReview"` + SpeakMisspelledIndicator *bool `toml:"speakMisspelledIndicator"` + SpeakContextBlockquote *bool `toml:"speakContextBlockquote"` + SpeakContextList *bool `toml:"speakContextList"` + SpeakContextTable *bool `toml:"speakContextTable"` + SpeakContextPanel *bool `toml:"speakContextPanel"` + SpeakContextLandmark *bool `toml:"speakContextLandmark"` + SpeakContextNonLandmarkForm *bool `toml:"speakContextNonLandmarkForm"` + SayAllContextBlockquote *bool `toml:"sayAllContextBlockquote"` + SayAllContextList *bool `toml:"sayAllContextList"` + SayAllContextTable *bool `toml:"sayAllContextTable"` + SayAllContextPanel *bool `toml:"sayAllContextPanel"` + SayAllContextLandmark *bool `toml:"sayAllContextLandmark"` + SayAllContextNonLandmarkForm *bool `toml:"sayAllContextNonLandmarkForm"` + ReadFullRowInGUITable *bool `toml:"readFullRowInGUITable"` + ReadFullRowInDocumentTable *bool `toml:"readFullRowInDocumentTable"` + ReadFullRowInSpreadSheet *bool `toml:"readFullRowInSpreadSheet"` +} + +type rawSettings struct { + TimeFormat *string `toml:"time-format"` + DateFormat *string `toml:"date-format"` + UseCustomEchoVoice *bool `toml:"useCustomEchoVoice"` + UseCustomEchoSpeechServer *bool `toml:"useCustomEchoSpeechServer"` + UseCustomEchoForKey *bool `toml:"useCustomEchoForKey"` + UseCustomEchoForCharacter *bool `toml:"useCustomEchoForCharacter"` + UseCustomEchoForWord *bool `toml:"useCustomEchoForWord"` + UseCustomEchoForSentence *bool `toml:"useCustomEchoForSentence"` + EchoVoice *Voice `toml:"echoVoice"` + EchoSpeechServerInfo []string `toml:"echoSpeechServerInfo"` + + EnableSound *bool `toml:"enableSound"` + SoundVolume *float64 `toml:"soundVolume"` + SoundSink *string `toml:"soundSink"` + SoundTheme *string `toml:"soundTheme"` + PlaySoundForRole *bool `toml:"playSoundForRole"` + PlaySoundForState *bool `toml:"playSoundForState"` + PlaySoundForPositionInSet *bool `toml:"playSoundForPositionInSet"` + PlaySoundForValue *bool `toml:"playSoundForValue"` + SpatializeObjectSounds *bool `toml:"spatializeObjectSounds"` + BeepProgressBarUpdates *bool `toml:"beepProgressBarUpdates"` + ProgressBarBeepInterval *int `toml:"progressBarBeepInterval"` + RoleSoundPresentation *string `toml:"roleSoundPresentation"` + + StartingProfile []string `toml:"startingProfile"` + ActiveProfile []string `toml:"activeProfile"` + EnableSpeech *bool `toml:"enableSpeech"` + EnableBraille *bool `toml:"enableBraille"` + EnableContractedBraille *bool `toml:"enableContractedBraille"` + BrailleContractionTable *string `toml:"brailleContractionTable"` + BrailleRolenameStyle *int `toml:"brailleRolenameStyle"` + BrailleDisableEOL *bool `toml:"disableBrailleEOL"` + BrailleWordWrap *bool `toml:"enableBrailleWordWrap"` + BrailleVerbosity *int `toml:"brailleVerbosityLevel"` + BrailleSelectionIndicator *int `toml:"brailleSelectorIndicator"` + BrailleLinkIndicator *int `toml:"brailleLinkIndicator"` + BrailleFlashMessages *bool `toml:"enableFlashMessages"` + BrailleFlashTime *int `toml:"brailleFlashTime"` + BrailleFlashPersistent *bool `toml:"flashIsPersistent"` + BrailleFlashDetailed *bool `toml:"flashIsDetailed"` + SpeechServerInfo []string `toml:"speechServerInfo"` + HardwareSpeechDevice *string `toml:"hardwareSpeechDevice"` + HardwareSpeechBaudRate *int `toml:"hardwareSpeechBaudRate"` + SpeechServerFactory *string `toml:"speechServerFactory"` + SpeakDescription *bool `toml:"speakDescription"` + SpeechVerbosityLevel *int `toml:"speechVerbosityLevel"` + SayAllStyle *int `toml:"sayAllStyle"` + Reading rawReadingSettings `toml:"reading"` + VerbalizePunctuationStyle *int `toml:"verbalizePunctuationStyle"` + CapitalizationStyle *string `toml:"capitalizationStyle"` + KeyboardLayout *int `toml:"keyboardLayout"` + CthulhuModifierKeys *[]string `toml:"cthulhuModifierKeys"` + EnableKeyEcho *bool `toml:"enableKeyEcho"` + EnableEchoByCharacter *bool `toml:"enableEchoByCharacter"` + EnableEchoByWord *bool `toml:"enableEchoByWord"` + EnableEchoBySentence *bool `toml:"enableEchoBySentence"` + EnableAlphabeticKeys *bool `toml:"enableAlphabeticKeys"` + EnableNumericKeys *bool `toml:"enableNumericKeys"` + EnablePunctuationKeys *bool `toml:"enablePunctuationKeys"` + EnableSpace *bool `toml:"enableSpace"` + EnableModifierKeys *bool `toml:"enableModifierKeys"` + EnableFunctionKeys *bool `toml:"enableFunctionKeys"` + EnableActionKeys *bool `toml:"enableActionKeys"` + EnableNavigationKeys *bool `toml:"enableNavigationKeys"` + EnableDiacriticalKeys *bool `toml:"enableDiacriticalKeys"` + Voices map[string]Voice `toml:"voices"` +} + +type document struct { + General rawSettings `toml:"general"` + Profiles map[string]rawSettings `toml:"profiles"` +} + +func selectedProfile(general rawSettings, profiles map[string]rawSettings) string { + for _, profile := range [][]string{general.StartingProfile, general.ActiveProfile} { + if len(profile) >= 2 && strings.TrimSpace(profile[1]) != "" { + return profile[1] + } + } + if _, exists := profiles["default"]; exists { + return "default" + } + return "" +} diff --git a/internal/config/legacy_mapping.go b/internal/config/legacy_mapping.go new file mode 100644 index 0000000..2de74c6 --- /dev/null +++ b/internal/config/legacy_mapping.go @@ -0,0 +1,335 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "git.stormux.org/storm/cthulhu/internal/datetime" +) + +func apply(settings *Settings, values rawSettings) { + // Keep the established patch order; absent fields leave prior values intact. + apply_legacy_sound(settings, values) + apply_legacy_output(settings, values) + apply_legacy_speech_service(settings, values) + apply_legacy_reading(settings, values) + apply_legacy_speech_formats(settings, values) + apply_legacy_keyboard(settings, values) + apply_legacy_echo(settings, values) + apply_legacy_default_voice(settings, values) +} + +func apply_legacy_sound(settings *Settings, values rawSettings) { + if values.EnableSound != nil { + settings.EnableSound = *values.EnableSound + } + if values.SoundVolume != nil { + settings.SoundVolume = *values.SoundVolume + } + if values.SoundSink != nil { + settings.SoundSink = *values.SoundSink + } + if values.SoundTheme != nil { + settings.SoundTheme = *values.SoundTheme + } + if values.PlaySoundForRole != nil { + settings.PlaySoundForRole = *values.PlaySoundForRole + } + if values.PlaySoundForState != nil { + settings.PlaySoundForState = *values.PlaySoundForState + } + if values.PlaySoundForPositionInSet != nil { + settings.PlaySoundForPositionInSet = *values.PlaySoundForPositionInSet + } + if values.SpatializeObjectSounds != nil { + settings.SpatializeObjectSounds = *values.SpatializeObjectSounds + } + if values.RoleSoundPresentation != nil { + settings.RoleSoundPresentation = *values.RoleSoundPresentation + } +} + +func apply_legacy_output(settings *Settings, values rawSettings) { + if values.EnableSpeech != nil { + settings.EnableSpeech = *values.EnableSpeech + } + if values.EnableBraille != nil { + settings.EnableBraille = *values.EnableBraille + } + if values.EnableContractedBraille != nil { + settings.EnableContractedBraille = *values.EnableContractedBraille + } + if values.BrailleContractionTable != nil { + settings.BrailleContractionTable = *values.BrailleContractionTable + } + if values.BrailleRolenameStyle != nil { + settings.Braille.AbbreviateRoles = *values.BrailleRolenameStyle == 0 + } + if values.BrailleDisableEOL != nil { + settings.Braille.DisableEOL = *values.BrailleDisableEOL + } + if values.BrailleWordWrap != nil { + settings.Braille.WordWrap = *values.BrailleWordWrap + } + if values.BrailleVerbosity != nil { + settings.Braille.Verbosity = *values.BrailleVerbosity + } + if values.BrailleSelectionIndicator != nil { + settings.Braille.SelectionIndicator = *values.BrailleSelectionIndicator + } + if values.BrailleLinkIndicator != nil { + settings.Braille.LinkIndicator = *values.BrailleLinkIndicator + } + if values.BrailleFlashMessages != nil { + settings.Braille.FlashMessages = *values.BrailleFlashMessages + } + if values.BrailleFlashTime != nil { + settings.Braille.FlashTime = *values.BrailleFlashTime + } + if values.BrailleFlashPersistent != nil { + settings.Braille.FlashPersistent = *values.BrailleFlashPersistent + } + if values.BrailleFlashDetailed != nil { + settings.Braille.FlashDetailed = *values.BrailleFlashDetailed + } +} + +func apply_legacy_speech_service(settings *Settings, values rawSettings) { + if values.HardwareSpeechDevice != nil { + settings.HardwareSpeechDevice = *values.HardwareSpeechDevice + } + if values.HardwareSpeechBaudRate != nil { + settings.HardwareSpeechBaudRate = *values.HardwareSpeechBaudRate + } + if values.SpeechServerFactory != nil { + settings.SpeechServerFactory = *values.SpeechServerFactory + } + if settings.SpeechServerFactory == "hardwarefactory" && len(values.SpeechServerInfo) > 1 { + settings.SpeechOutputModule = values.SpeechServerInfo[1] + } + if values.SpeakDescription != nil { + settings.SpeakDescription = *values.SpeakDescription + } + if values.SpeechVerbosityLevel != nil { + settings.SpeechVerbosityLevel = *values.SpeechVerbosityLevel + } + if values.SayAllStyle != nil { + settings.SayAllStyle = map[int]string{0: "line", 1: "sentence"}[*values.SayAllStyle] + } +} + +func apply_legacy_reading(settings *Settings, values rawSettings) { + if values.Reading.OnlySpeakDisplayedText != nil { + settings.Reading.OnlySpeakDisplayedText = *values.Reading.OnlySpeakDisplayedText + } + if values.Reading.SpeakBlankLines != nil { + settings.Reading.SpeakBlankLines = *values.Reading.SpeakBlankLines + } + if values.Reading.EnableMnemonicSpeaking != nil { + settings.Reading.EnableMnemonicSpeaking = *values.Reading.EnableMnemonicSpeaking + } + if values.Reading.EnablePositionSpeaking != nil { + settings.Reading.EnablePositionSpeaking = *values.Reading.EnablePositionSpeaking + } + if values.Reading.EnableTutorialMessages != nil { + settings.Reading.EnableTutorialMessages = *values.Reading.EnableTutorialMessages + } + if values.Reading.MessagesAreDetailed != nil { + settings.Reading.MessagesAreDetailed = *values.Reading.MessagesAreDetailed + } + if values.Reading.UseColorNames != nil { + settings.Reading.UseColorNames = *values.Reading.UseColorNames + } + if values.Reading.PresentTooltips != nil { + settings.Reading.PresentTooltips = *values.Reading.PresentTooltips + } + if values.Reading.EnableMouseReview != nil { + settings.Reading.EnableMouseReview = *values.Reading.EnableMouseReview + } + if values.Reading.SpeakMisspelledIndicator != nil { + settings.Reading.SpeakMisspelledIndicator = *values.Reading.SpeakMisspelledIndicator + } + if values.Reading.EnablePauseBreaks != nil { + settings.Reading.EnablePauseBreaks = *values.Reading.EnablePauseBreaks + } + if values.Reading.SpeakNumbersAsDigits != nil { + settings.Reading.SpeakNumbersAsDigits = *values.Reading.SpeakNumbersAsDigits + } + if values.Reading.SpeakMultiCaseStringsAsWords != nil { + settings.Reading.SpeakMultiCaseStringsAsWords = *values.Reading.SpeakMultiCaseStringsAsWords + } + if values.Reading.EnableIndentation != nil { + settings.Reading.EnableIndentation = *values.Reading.EnableIndentation + } + if values.Reading.SpeakContextBlockquote != nil { + settings.Reading.SpeakContextBlockquote = *values.Reading.SpeakContextBlockquote + } + if values.Reading.SpeakContextList != nil { + settings.Reading.SpeakContextList = *values.Reading.SpeakContextList + } + if values.Reading.SpeakContextTable != nil { + settings.Reading.SpeakContextTable = *values.Reading.SpeakContextTable + } + if values.Reading.SpeakContextPanel != nil { + settings.Reading.SpeakContextPanel = *values.Reading.SpeakContextPanel + } + if values.Reading.SpeakContextLandmark != nil { + settings.Reading.SpeakContextLandmark = *values.Reading.SpeakContextLandmark + } + if values.Reading.SpeakContextNonLandmarkForm != nil { + settings.Reading.SpeakContextNonLandmarkForm = *values.Reading.SpeakContextNonLandmarkForm + } + if values.Reading.SayAllContextBlockquote != nil { + settings.Reading.SayAllContextBlockquote = *values.Reading.SayAllContextBlockquote + } + if values.Reading.SayAllContextList != nil { + settings.Reading.SayAllContextList = *values.Reading.SayAllContextList + } + if values.Reading.SayAllContextTable != nil { + settings.Reading.SayAllContextTable = *values.Reading.SayAllContextTable + } + if values.Reading.SayAllContextPanel != nil { + settings.Reading.SayAllContextPanel = *values.Reading.SayAllContextPanel + } + if values.Reading.SayAllContextLandmark != nil { + settings.Reading.SayAllContextLandmark = *values.Reading.SayAllContextLandmark + } + if values.Reading.SayAllContextNonLandmarkForm != nil { + settings.Reading.SayAllContextNonLandmarkForm = *values.Reading.SayAllContextNonLandmarkForm + } + if values.Reading.ReadFullRowInGUITable != nil { + settings.Reading.ReadFullRowInGUITable = *values.Reading.ReadFullRowInGUITable + } + if values.Reading.ReadFullRowInDocumentTable != nil { + settings.Reading.ReadFullRowInDocumentTable = *values.Reading.ReadFullRowInDocumentTable + } + if values.Reading.ReadFullRowInSpreadSheet != nil { + settings.Reading.ReadFullRowInSpreadSheet = *values.Reading.ReadFullRowInSpreadSheet + } +} + +func apply_legacy_speech_formats(settings *Settings, values rawSettings) { + if values.VerbalizePunctuationStyle != nil { + settings.VerbalizePunctuationStyle = *values.VerbalizePunctuationStyle + } + if values.CapitalizationStyle != nil { + settings.SetCapitalizationStyle(*values.CapitalizationStyle) + } + if values.TimeFormat != nil { + settings.TimeFormat = *values.TimeFormat + } + if values.DateFormat != nil { + settings.DateFormat = datetime.NormalizeDate(*values.DateFormat) + } +} + +func apply_legacy_keyboard(settings *Settings, values rawSettings) { + if values.KeyboardLayout != nil { + settings.KeyboardLayout = *values.KeyboardLayout + } + if values.CthulhuModifierKeys != nil { + settings.CthulhuModifierKeys = append([]string(nil), (*values.CthulhuModifierKeys)...) + } +} + +func apply_legacy_echo(settings *Settings, values rawSettings) { + if values.UseCustomEchoVoice != nil { + settings.UseCustomEchoVoice = *values.UseCustomEchoVoice + } + if values.UseCustomEchoSpeechServer != nil { + settings.UseCustomEchoSpeechServer = *values.UseCustomEchoSpeechServer + } + if values.UseCustomEchoForKey != nil { + settings.UseCustomEchoForKey = *values.UseCustomEchoForKey + } + if values.UseCustomEchoForCharacter != nil { + settings.UseCustomEchoForCharacter = *values.UseCustomEchoForCharacter + } + if values.UseCustomEchoForWord != nil { + settings.UseCustomEchoForWord = *values.UseCustomEchoForWord + } + if values.UseCustomEchoForSentence != nil { + settings.UseCustomEchoForSentence = *values.UseCustomEchoForSentence + } + if values.EchoVoice != nil { + mergeVoice(&settings.EchoVoice, *values.EchoVoice) + } + if len(values.EchoSpeechServerInfo) > 1 { + settings.EchoSpeechServer = values.EchoSpeechServerInfo[1] + } + if values.EnableKeyEcho != nil { + settings.EnableKeyEcho = *values.EnableKeyEcho + } + if values.EnableEchoByCharacter != nil { + settings.EnableEchoByCharacter = *values.EnableEchoByCharacter + } + if values.EnableEchoByWord != nil { + settings.EnableEchoByWord = *values.EnableEchoByWord + } + if values.EnableEchoBySentence != nil { + settings.EnableEchoBySentence = *values.EnableEchoBySentence + } + if values.EnableAlphabeticKeys != nil { + settings.EnableAlphabeticKeys = *values.EnableAlphabeticKeys + } + if values.EnableNumericKeys != nil { + settings.EnableNumericKeys = *values.EnableNumericKeys + } + if values.EnablePunctuationKeys != nil { + settings.EnablePunctuationKeys = *values.EnablePunctuationKeys + } + if values.EnableSpace != nil { + settings.EnableSpace = *values.EnableSpace + } + if values.EnableModifierKeys != nil { + settings.EnableModifierKeys = *values.EnableModifierKeys + } + if values.EnableFunctionKeys != nil { + settings.EnableFunctionKeys = *values.EnableFunctionKeys + } + if values.EnableActionKeys != nil { + settings.EnableActionKeys = *values.EnableActionKeys + } + if values.EnableNavigationKeys != nil { + settings.EnableNavigationKeys = *values.EnableNavigationKeys + } + if values.EnableDiacriticalKeys != nil { + settings.EnableDiacriticalKeys = *values.EnableDiacriticalKeys + } +} + +func apply_legacy_default_voice(settings *Settings, values rawSettings) { + if voice, exists := values.Voices["default"]; exists { + mergeVoice(&settings.DefaultVoice, voice) + } +} + +func mergeVoice(target *Voice, source Voice) { + if source.Rate != nil { + target.Rate = source.Rate + } + if source.AveragePitch != nil { + target.AveragePitch = source.AveragePitch + } + if source.Gain != nil { + target.Gain = source.Gain + } + if source.Family != nil { + family := *source.Family + target.Family = &family + } +} diff --git a/internal/config/ocr_test.go b/internal/config/ocr_test.go new file mode 100644 index 0000000..2fdcc17 --- /dev/null +++ b/internal/config/ocr_test.go @@ -0,0 +1,48 @@ +package config + +import "testing" + +func TestOCRSettingsPersistAndRebase(t *testing.T) { + settings := DefaultSettings() + settings.OCR = OCRSettings{Language: "fra+eng", Layout: 11, Scale: 3, Grayscale: true, + Invert: true, BlackWhite: true, Threshold: 231, AutoRefresh: true, RefreshInterval: 700, + ConfirmClick: false, CopyFirstResult: true, AutoReadAll: true} + encoded, err := encodeWritable(settings) + if err != nil { + t.Fatal(err) + } + decoded, err := decodeWritable(encoded) + if err != nil { + t.Fatal(err) + } + if decoded.OCR != settings.OCR { + t.Fatalf("OCR settings changed: %+v", decoded.OCR) + } + global := DefaultSettings() + application := global + application.OCR.Language = "deu" + global.OCR.AutoReadAll = true + application.OCR.AutoReadAll = false + newGlobal := global + newGlobal.OCR.Scale = 2 + rebased := RebaseApplicationSettings(global, newGlobal, application) + if rebased.OCR.Language != "deu" || rebased.OCR.Scale != 2 || rebased.OCR.AutoReadAll { + t.Fatalf("OCR override rebase: %+v", rebased.OCR) + } +} + +func TestOCRAutoReadAllDefaultsAndExplicitFalse(t *testing.T) { + settings := DefaultSettings() + if settings.OCR.AutoReadAll { + t.Fatal("automatic OCR reading must default off") + } + settings.OCR.AutoReadAll = true + apply_profile_ocr(&settings.OCR, writableOCR{}) + if !settings.OCR.AutoReadAll { + t.Fatal("omitted setting changed inherited value") + } + apply_profile_ocr(&settings.OCR, writableOCR{AutoReadAll: boolPointer(false)}) + if settings.OCR.AutoReadAll { + t.Fatal("explicit false did not override inherited value") + } +} diff --git a/internal/config/patch_contract_test.go b/internal/config/patch_contract_test.go new file mode 100644 index 0000000..23b75a6 --- /dev/null +++ b/internal/config/patch_contract_test.go @@ -0,0 +1,69 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +import "testing" + +func TestLoadExplicitZeroAndEmptyOverridesAcrossSchemas(t *testing.T) { + for name, contents := range map[string]string{ + "legacy profile overrides general": ` +[general] +enableSpeech = true +enableBraille = true +soundVolume = 0.8 +cthulhuModifierKeys = ["Insert"] +echoSpeechServerInfo = ["server", "test-module"] +[general.voices.default] +rate = 75 +[profiles.default] +enableSpeech = false +enableBraille = false +soundVolume = 0.0 +playSoundForRole = false +cthulhuModifierKeys = [] +echoSpeechServerInfo = ["server", ""] +[profiles.default.reading] +speakBlankLines = false +[profiles.default.voices.default] +rate = 0 +`, + "versioned patch overrides defaults": ` +schema-version = 2 +active-profile = "default" +[profiles.default.speech] +enabled = false +[profiles.default.speech.default-voice] +rate = 0 +[profiles.default.braille] +enabled = false +[profiles.default.sound] +volume = 0.0 +play-for-role = false +[profiles.default.keyboard] +screen-reader-keys = [] +[profiles.default.key-echo] +speech-server = "" +[profiles.default.presentation.reading] +speak-blank-lines = false +`, + } { + t.Run(name, func(t *testing.T) { + settings, err := Load(writeConfig(t, contents)) + if err != nil { + t.Fatal(err) + } + if settings.EnableSpeech || settings.EnableBraille || settings.SoundVolume != 0 || + settings.PlaySoundForRole || settings.Reading.SpeakBlankLines || + len(settings.CthulhuModifierKeys) != 0 || settings.EchoSpeechServer != "" || + settings.DefaultVoice.Rate == nil || *settings.DefaultVoice.Rate != 0 { + t.Fatalf("explicit false/zero/empty values were lost: %+v", settings) + } + if !settings.EnableSound || !settings.PlaySoundForState || !settings.EnableKeyEcho || + !settings.Reading.ReadFullRowInGUITable || settings.DefaultVoice.Gain != nil { + t.Fatalf("omitted fields changed their defaults: %+v", settings) + } + }) + } +} diff --git a/internal/config/phonetic_hints_test.go b/internal/config/phonetic_hints_test.go new file mode 100644 index 0000000..c65848a --- /dev/null +++ b/internal/config/phonetic_hints_test.go @@ -0,0 +1,45 @@ +package config + +import ( + "path/filepath" + "testing" +) + +func TestPhoneticHintsDefaultPersistenceAndApplicationOverride(t *testing.T) { + settings := DefaultSettings() + if settings.Reading.PhoneticCharacterHints { + t.Fatal("phonetic hints must default off") + } + omitted, err := Load(writeConfig(t, "schema-version = 2\nactive-profile = 'default'\n[profiles.default]\n")) + if err != nil || omitted.Reading.PhoneticCharacterHints { + t.Fatalf("omitted setting = %t, %v", omitted.Reading.PhoneticCharacterHints, err) + } + store, err := NewStore(filepath.Join(t.TempDir(), "settings.toml")) + if err != nil { + t.Fatal(err) + } + settings.Reading.PhoneticCharacterHints = true + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + loaded, err := store.Load() + if err != nil || !loaded.Reading.PhoneticCharacterHints { + t.Fatalf("saved setting = %t, %v", loaded.Reading.PhoneticCharacterHints, err) + } + inherited, _, err := store.LoadForApplication("Editor") + if err != nil || !inherited.Reading.PhoneticCharacterHints { + t.Fatalf("inherited setting = %t, %v", inherited.Reading.PhoneticCharacterHints, err) + } + loaded.Reading.PhoneticCharacterHints = false + if err := store.SaveForApplication("Editor", loaded); err != nil { + t.Fatal(err) + } + overridden, found, err := store.LoadForApplication("Editor") + if err != nil || !found || overridden.Reading.PhoneticCharacterHints { + t.Fatalf("application override = %t, %t, %v", overridden.Reading.PhoneticCharacterHints, found, err) + } + global, err := store.Load() + if err != nil || !global.Reading.PhoneticCharacterHints { + t.Fatalf("application override changed global = %t, %v", global.Reading.PhoneticCharacterHints, err) + } +} diff --git a/internal/config/profile_mapping.go b/internal/config/profile_mapping.go new file mode 100644 index 0000000..f78f79d --- /dev/null +++ b/internal/config/profile_mapping.go @@ -0,0 +1,605 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "reflect" + + "git.stormux.org/storm/cthulhu/internal/datetime" + "git.stormux.org/storm/cthulhu/internal/input" +) + +// Application profiles store only values that differ from the global profile. +// The writable schema is made of nested value structs and pointer fields, so +// clearing equal leaves preserves its existing patch semantics. +func applicationProfileDifference(global, application Settings) writableProfile { + base := profileFromSettings(global) + result := profileFromSettings(application) + clearEqualProfileFields(reflect.ValueOf(&result).Elem(), reflect.ValueOf(base)) + return result +} + +func clearEqualProfileFields(result, base reflect.Value) { + for index := 0; index < result.NumField(); index++ { + field, baseline := result.Field(index), base.Field(index) + if field.Kind() == reflect.Struct { + clearEqualProfileFields(field, baseline) + } else if reflect.DeepEqual(field.Interface(), baseline.Interface()) { + field.SetZero() + } + } +} + +// RebaseApplicationSettings keeps session-only application choices when the +// global profile changes, while newly inherited values follow the new global. +func RebaseApplicationSettings(oldGlobal, newGlobal, application Settings) Settings { + patch := applicationProfileDifference(oldGlobal, application) + rebased := newGlobal + applyProfile(&rebased, patch) + rebased.ActiveProfile = application.ActiveProfile + return rebased +} + +func profileFromSettings(settings Settings) writableProfile { + return writableProfile{ + OCR: writableOCR{Language: stringPointer(settings.OCR.Language), Layout: intPointer(settings.OCR.Layout), Scale: intPointer(settings.OCR.Scale), Grayscale: boolPointer(settings.OCR.Grayscale), Invert: boolPointer(settings.OCR.Invert), BlackWhite: boolPointer(settings.OCR.BlackWhite), Threshold: intPointer(settings.OCR.Threshold), AutoRefresh: boolPointer(settings.OCR.AutoRefresh), RefreshInterval: intPointer(settings.OCR.RefreshInterval), ConfirmClick: boolPointer(settings.OCR.ConfirmClick), CopyFirstResult: boolPointer(settings.OCR.CopyFirstResult), AutoReadAll: boolPointer(settings.OCR.AutoReadAll)}, + ProgressBar: writableProgressBar{ + OutputMode: stringPointer(settings.ProgressBar.OutputMode), + ReportBackground: boolPointer(settings.ProgressBar.ReportBackground), + BeepPercentageInterval: intPointer(settings.ProgressBar.BeepPercentageInterval), + SpeechPercentageInterval: intPointer(settings.ProgressBar.SpeechPercentageInterval), + }, + Presentation: writablePresentation{ + Pronunciations: pronunciationSlicePointer(settings.Pronunciations), + TextAttributes: writableTextAttributes{Choices: textAttributeSlicePointer(settings.TextAttributes.Choices), Indicator: intPointer(settings.TextAttributes.Indicator)}, + TimeFormat: stringPointer(settings.TimeFormat), DateFormat: stringPointer(settings.DateFormat), + SpeakDescription: boolPointer(settings.SpeakDescription), + SpeechVerbosityLevel: intPointer(settings.SpeechVerbosityLevel), + SayAllStyle: stringPointer(settings.SayAllStyle), + Reading: writableReading{ + AutomaticallyReadClipboardChanges: boolPointer(settings.Reading.AutomaticallyReadClipboardChanges), + AutomaticallyReadTitleChanges: boolPointer(settings.Reading.AutomaticallyReadTitleChanges), + PhoneticCharacterHints: boolPointer(settings.Reading.PhoneticCharacterHints), + EnablePauseBreaks: boolPointer(settings.Reading.EnablePauseBreaks), + SpeakNumbersAsDigits: boolPointer(settings.Reading.SpeakNumbersAsDigits), + SpeakMultiCaseStringsAsWords: boolPointer(settings.Reading.SpeakMultiCaseStringsAsWords), + EnableIndentation: boolPointer(settings.Reading.EnableIndentation), + IndentationPresentationMode: stringPointer(settings.Reading.IndentationPresentationMode), + OnlySpeakDisplayedText: boolPointer(settings.Reading.OnlySpeakDisplayedText), + SpeakBlankLines: boolPointer(settings.Reading.SpeakBlankLines), + EnableMnemonicSpeaking: boolPointer(settings.Reading.EnableMnemonicSpeaking), + EnablePositionSpeaking: boolPointer(settings.Reading.EnablePositionSpeaking), + EnableTutorialMessages: boolPointer(settings.Reading.EnableTutorialMessages), + MessagesAreDetailed: boolPointer(settings.Reading.MessagesAreDetailed), + UseColorNames: boolPointer(settings.Reading.UseColorNames), + PresentTooltips: boolPointer(settings.Reading.PresentTooltips), + EnableMouseReview: boolPointer(settings.Reading.EnableMouseReview), + SpeakMisspelledIndicator: boolPointer(settings.Reading.SpeakMisspelledIndicator), + SpeakContextBlockquote: boolPointer(settings.Reading.SpeakContextBlockquote), + SpeakContextList: boolPointer(settings.Reading.SpeakContextList), + SpeakContextTable: boolPointer(settings.Reading.SpeakContextTable), + SpeakContextPanel: boolPointer(settings.Reading.SpeakContextPanel), + SpeakContextLandmark: boolPointer(settings.Reading.SpeakContextLandmark), + SpeakContextNonLandmarkForm: boolPointer(settings.Reading.SpeakContextNonLandmarkForm), + SayAllContextBlockquote: boolPointer(settings.Reading.SayAllContextBlockquote), + SayAllContextList: boolPointer(settings.Reading.SayAllContextList), + SayAllContextTable: boolPointer(settings.Reading.SayAllContextTable), + SayAllContextPanel: boolPointer(settings.Reading.SayAllContextPanel), + SayAllContextLandmark: boolPointer(settings.Reading.SayAllContextLandmark), + SayAllContextNonLandmarkForm: boolPointer(settings.Reading.SayAllContextNonLandmarkForm), + ReadFullRowInGUITable: boolPointer(settings.Reading.ReadFullRowInGUITable), + ReadFullRowInDocumentTable: boolPointer(settings.Reading.ReadFullRowInDocumentTable), + ReadFullRowInSpreadSheet: boolPointer(settings.Reading.ReadFullRowInSpreadSheet), + }, + }, + Speech: writableSpeech{ + Interruption: interruption_pointer(settings.SpeechInterruption), + HardwareDevice: stringPointer(settings.HardwareSpeechDevice), + HardwareBaudRate: intPointer(settings.HardwareSpeechBaudRate), + Enabled: boolPointer(settings.EnableSpeech), ServerFactory: stringPointer(settings.SpeechServerFactory), + HistoryLimit: intPointer(settings.SpeechHistoryLimit), + Punctuation: intPointer(settings.VerbalizePunctuationStyle), Capitalization: stringPointer(settings.CapitalizationStyle), + RaisePitchForCapitals: boolPointer(settings.RaisePitchForCapitals), + BeepForCapitals: boolPointer(settings.BeepForCapitals), + SayCapForCapitals: boolPointer(settings.SayCapForCapitals), + DefaultVoice: voicePointer(settings.DefaultVoice), + UppercaseVoice: voicePointer(settings.UppercaseVoice), + HyperlinkVoice: voicePointer(settings.HyperlinkVoice), + SystemVoice: voicePointer(settings.SystemVoice), + OutputModule: stringPointer(settings.SpeechOutputModule), + }, + Braille: writableBraille{Enabled: boolPointer(settings.EnableBraille), + Contracted: boolPointer(settings.EnableContractedBraille), + ContractionTable: stringPointer(settings.BrailleContractionTable), + AbbreviateRoles: boolPointer(settings.Braille.AbbreviateRoles), + DisableEOL: boolPointer(settings.Braille.DisableEOL), WordWrap: boolPointer(settings.Braille.WordWrap), + Verbosity: intPointer(settings.Braille.Verbosity), SelectionIndicator: intPointer(settings.Braille.SelectionIndicator), + LinkIndicator: intPointer(settings.Braille.LinkIndicator), FlashMessages: boolPointer(settings.Braille.FlashMessages), + FlashTime: intPointer(settings.Braille.FlashTime), FlashPersistent: boolPointer(settings.Braille.FlashPersistent), + FlashDetailed: boolPointer(settings.Braille.FlashDetailed)}, + Sound: writableSound{ + Enabled: boolPointer(settings.EnableSound), Volume: floatPointer(settings.SoundVolume), + Sink: stringPointer(settings.SoundSink), Theme: stringPointer(settings.SoundTheme), + PlayForRole: boolPointer(settings.PlaySoundForRole), PlayForState: boolPointer(settings.PlaySoundForState), + PlayForPosition: boolPointer(settings.PlaySoundForPositionInSet), + Spatialize: boolPointer(settings.SpatializeObjectSounds), + RolePresentationStrategy: stringPointer(settings.RoleSoundPresentation), + }, + Keyboard: writableKeyboard{ + Bindings: bindingSlicePointer(settings.KeyBindings), + Layout: intPointer(settings.KeyboardLayout), + ScreenReaderKeys: stringSlicePointer(settings.CthulhuModifierKeys), + }, + KeyEcho: writableKeyEcho{ + UseCustomEchoVoice: boolPointer(settings.UseCustomEchoVoice), + UseCustomEchoSpeechServer: boolPointer(settings.UseCustomEchoSpeechServer), + UseCustomEchoForKey: boolPointer(settings.UseCustomEchoForKey), + UseCustomEchoForCharacter: boolPointer(settings.UseCustomEchoForCharacter), + UseCustomEchoForWord: boolPointer(settings.UseCustomEchoForWord), + UseCustomEchoForSentence: boolPointer(settings.UseCustomEchoForSentence), + EchoVoice: voicePointer(settings.EchoVoice), EchoSpeechServer: stringPointer(settings.EchoSpeechServer), + + EditFieldsOnly: boolPointer(settings.KeyEchoInEditFieldsOnly), + Enabled: boolPointer(settings.EnableKeyEcho), ByCharacter: boolPointer(settings.EnableEchoByCharacter), + ByWord: boolPointer(settings.EnableEchoByWord), BySentence: boolPointer(settings.EnableEchoBySentence), + Alphabetic: boolPointer(settings.EnableAlphabeticKeys), Numeric: boolPointer(settings.EnableNumericKeys), + Punctuation: boolPointer(settings.EnablePunctuationKeys), Space: boolPointer(settings.EnableSpace), + Modifiers: boolPointer(settings.EnableModifierKeys), FunctionKeys: boolPointer(settings.EnableFunctionKeys), + ActionKeys: boolPointer(settings.EnableActionKeys), NavigationKeys: boolPointer(settings.EnableNavigationKeys), + Diacritical: boolPointer(settings.EnableDiacriticalKeys), + }, + } +} + +func applyProfile(settings *Settings, profile writableProfile) { + apply_profile_ocr(&settings.OCR, profile.OCR) + // Keep the established patch order; absent fields leave prior values intact. + apply_profile_formats(settings, profile) + apply_profile_echo_voice(settings, profile) + apply_profile_reading(settings, profile) + apply_profile_output(settings, profile) + apply_profile_speech(settings, profile) + apply_profile_sound(settings, profile) + if value := profile.ProgressBar.OutputMode; value != nil { + settings.ProgressBar.OutputMode = *value + } + if value := profile.ProgressBar.ReportBackground; value != nil { + settings.ProgressBar.ReportBackground = *value + } + if value := profile.ProgressBar.BeepPercentageInterval; value != nil { + settings.ProgressBar.BeepPercentageInterval = *value + } + if value := profile.ProgressBar.SpeechPercentageInterval; value != nil { + settings.ProgressBar.SpeechPercentageInterval = *value + } + apply_profile_keyboard(settings, profile) + apply_profile_echo_keys(settings, profile) +} + +func apply_profile_ocr(settings *OCRSettings, patch writableOCR) { + if patch.Language != nil { + settings.Language = *patch.Language + } + if patch.Layout != nil { + settings.Layout = *patch.Layout + } + if patch.Scale != nil { + settings.Scale = *patch.Scale + } + if patch.Grayscale != nil { + settings.Grayscale = *patch.Grayscale + } + if patch.Invert != nil { + settings.Invert = *patch.Invert + } + if patch.BlackWhite != nil { + settings.BlackWhite = *patch.BlackWhite + } + if patch.Threshold != nil { + settings.Threshold = *patch.Threshold + } + if patch.AutoRefresh != nil { + settings.AutoRefresh = *patch.AutoRefresh + } + if patch.RefreshInterval != nil { + settings.RefreshInterval = *patch.RefreshInterval + } + if patch.ConfirmClick != nil { + settings.ConfirmClick = *patch.ConfirmClick + } + if patch.CopyFirstResult != nil { + settings.CopyFirstResult = *patch.CopyFirstResult + } + if patch.AutoReadAll != nil { + settings.AutoReadAll = *patch.AutoReadAll + } +} + +func apply_profile_formats(settings *Settings, profile writableProfile) { + if v := profile.Presentation.TimeFormat; v != nil { + settings.TimeFormat = *v + } + if v := profile.Presentation.DateFormat; v != nil { + settings.DateFormat = datetime.NormalizeDate(*v) + } +} + +func apply_profile_echo_voice(settings *Settings, profile writableProfile) { + if v := profile.KeyEcho.UseCustomEchoVoice; v != nil { + settings.UseCustomEchoVoice = *v + } + if v := profile.KeyEcho.UseCustomEchoSpeechServer; v != nil { + settings.UseCustomEchoSpeechServer = *v + } + if v := profile.KeyEcho.UseCustomEchoForKey; v != nil { + settings.UseCustomEchoForKey = *v + } + if v := profile.KeyEcho.UseCustomEchoForCharacter; v != nil { + settings.UseCustomEchoForCharacter = *v + } + if v := profile.KeyEcho.UseCustomEchoForWord; v != nil { + settings.UseCustomEchoForWord = *v + } + if v := profile.KeyEcho.UseCustomEchoForSentence; v != nil { + settings.UseCustomEchoForSentence = *v + } + if v := profile.KeyEcho.EchoVoice; v != nil { + settings.EchoVoice = cloneVoice(*v) + } + if v := profile.KeyEcho.EchoSpeechServer; v != nil { + settings.EchoSpeechServer = *v + } +} + +func apply_profile_reading(settings *Settings, profile writableProfile) { + if value := profile.Presentation.Pronunciations; value != nil { + settings.Pronunciations = append([]PronunciationEntry(nil), (*value)...) + } + if value := profile.Presentation.TextAttributes.Choices; value != nil { + settings.TextAttributes.Choices = append([]TextAttributeChoice(nil), (*value)...) + } + if value := profile.Presentation.TextAttributes.Indicator; value != nil { + settings.TextAttributes.Indicator = *value + } + if value := profile.Presentation.SpeakDescription; value != nil { + settings.SpeakDescription = *value + } + if value := profile.Presentation.SpeechVerbosityLevel; value != nil { + settings.SpeechVerbosityLevel = *value + } + if value := profile.Presentation.SayAllStyle; value != nil { + settings.SayAllStyle = *value + } + if value := profile.Presentation.Reading.AutomaticallyReadClipboardChanges; value != nil { + settings.Reading.AutomaticallyReadClipboardChanges = *value + } + if value := profile.Presentation.Reading.AutomaticallyReadTitleChanges; value != nil { + settings.Reading.AutomaticallyReadTitleChanges = *value + } + if value := profile.Presentation.Reading.OnlySpeakDisplayedText; value != nil { + settings.Reading.OnlySpeakDisplayedText = *value + } + if value := profile.Presentation.Reading.PhoneticCharacterHints; value != nil { + settings.Reading.PhoneticCharacterHints = *value + } + if value := profile.Presentation.Reading.EnablePauseBreaks; value != nil { + settings.Reading.EnablePauseBreaks = *value + } + if value := profile.Presentation.Reading.SpeakNumbersAsDigits; value != nil { + settings.Reading.SpeakNumbersAsDigits = *value + } + if value := profile.Presentation.Reading.SpeakMultiCaseStringsAsWords; value != nil { + settings.Reading.SpeakMultiCaseStringsAsWords = *value + } + if value := profile.Presentation.Reading.EnableIndentation; value != nil { + settings.Reading.EnableIndentation = *value + } + if value := profile.Presentation.Reading.IndentationPresentationMode; value != nil { + settings.Reading.IndentationPresentationMode = *value + } + if value := profile.Presentation.Reading.SpeakBlankLines; value != nil { + settings.Reading.SpeakBlankLines = *value + } + if value := profile.Presentation.Reading.EnableMnemonicSpeaking; value != nil { + settings.Reading.EnableMnemonicSpeaking = *value + } + if value := profile.Presentation.Reading.EnablePositionSpeaking; value != nil { + settings.Reading.EnablePositionSpeaking = *value + } + if value := profile.Presentation.Reading.EnableTutorialMessages; value != nil { + settings.Reading.EnableTutorialMessages = *value + } + if value := profile.Presentation.Reading.MessagesAreDetailed; value != nil { + settings.Reading.MessagesAreDetailed = *value + } + if value := profile.Presentation.Reading.UseColorNames; value != nil { + settings.Reading.UseColorNames = *value + } + if value := profile.Presentation.Reading.PresentTooltips; value != nil { + settings.Reading.PresentTooltips = *value + } + if value := profile.Presentation.Reading.EnableMouseReview; value != nil { + settings.Reading.EnableMouseReview = *value + } + if value := profile.Presentation.Reading.SpeakMisspelledIndicator; value != nil { + settings.Reading.SpeakMisspelledIndicator = *value + } + if value := profile.Presentation.Reading.SpeakContextBlockquote; value != nil { + settings.Reading.SpeakContextBlockquote = *value + } + if value := profile.Presentation.Reading.SpeakContextList; value != nil { + settings.Reading.SpeakContextList = *value + } + if value := profile.Presentation.Reading.SpeakContextTable; value != nil { + settings.Reading.SpeakContextTable = *value + } + if value := profile.Presentation.Reading.SpeakContextPanel; value != nil { + settings.Reading.SpeakContextPanel = *value + } + if value := profile.Presentation.Reading.SpeakContextLandmark; value != nil { + settings.Reading.SpeakContextLandmark = *value + } + if value := profile.Presentation.Reading.SpeakContextNonLandmarkForm; value != nil { + settings.Reading.SpeakContextNonLandmarkForm = *value + } + if value := profile.Presentation.Reading.SayAllContextBlockquote; value != nil { + settings.Reading.SayAllContextBlockquote = *value + } + if value := profile.Presentation.Reading.SayAllContextList; value != nil { + settings.Reading.SayAllContextList = *value + } + if value := profile.Presentation.Reading.SayAllContextTable; value != nil { + settings.Reading.SayAllContextTable = *value + } + if value := profile.Presentation.Reading.SayAllContextPanel; value != nil { + settings.Reading.SayAllContextPanel = *value + } + if value := profile.Presentation.Reading.SayAllContextLandmark; value != nil { + settings.Reading.SayAllContextLandmark = *value + } + if value := profile.Presentation.Reading.SayAllContextNonLandmarkForm; value != nil { + settings.Reading.SayAllContextNonLandmarkForm = *value + } + if value := profile.Presentation.Reading.ReadFullRowInGUITable; value != nil { + settings.Reading.ReadFullRowInGUITable = *value + } + if value := profile.Presentation.Reading.ReadFullRowInDocumentTable; value != nil { + settings.Reading.ReadFullRowInDocumentTable = *value + } + if value := profile.Presentation.Reading.ReadFullRowInSpreadSheet; value != nil { + settings.Reading.ReadFullRowInSpreadSheet = *value + } +} + +func apply_profile_output(settings *Settings, profile writableProfile) { + if value := profile.Speech.Interruption; value != nil { + settings.SpeechInterruption = *interruption_pointer(*value) + } + if value := profile.Speech.Enabled; value != nil { + settings.EnableSpeech = *value + } + if value := profile.Speech.HistoryLimit; value != nil { + settings.SpeechHistoryLimit = *value + } + if value := profile.Braille.Enabled; value != nil { + settings.EnableBraille = *value + } + if value := profile.Braille.Contracted; value != nil { + settings.EnableContractedBraille = *value + } + if value := profile.Braille.ContractionTable; value != nil { + settings.BrailleContractionTable = *value + } + if value := profile.Braille.AbbreviateRoles; value != nil { + settings.Braille.AbbreviateRoles = *value + } + if value := profile.Braille.DisableEOL; value != nil { + settings.Braille.DisableEOL = *value + } + if value := profile.Braille.WordWrap; value != nil { + settings.Braille.WordWrap = *value + } + if value := profile.Braille.Verbosity; value != nil { + settings.Braille.Verbosity = *value + } + if value := profile.Braille.SelectionIndicator; value != nil { + settings.Braille.SelectionIndicator = *value + } + if value := profile.Braille.LinkIndicator; value != nil { + settings.Braille.LinkIndicator = *value + } + if value := profile.Braille.FlashMessages; value != nil { + settings.Braille.FlashMessages = *value + } + if value := profile.Braille.FlashTime; value != nil { + settings.Braille.FlashTime = *value + } + if value := profile.Braille.FlashPersistent; value != nil { + settings.Braille.FlashPersistent = *value + } + if value := profile.Braille.FlashDetailed; value != nil { + settings.Braille.FlashDetailed = *value + } +} + +func interruption_pointer(settings input.InterruptionSettings) *input.InterruptionSettings { + settings.Keys = append([]string(nil), settings.Keys...) + return &settings +} + +func apply_profile_speech(settings *Settings, profile writableProfile) { + if value := profile.Speech.HardwareDevice; value != nil { + settings.HardwareSpeechDevice = *value + } + if value := profile.Speech.HardwareBaudRate; value != nil { + settings.HardwareSpeechBaudRate = *value + } + if value := profile.Speech.ServerFactory; value != nil { + settings.SpeechServerFactory = *value + } + if value := profile.Speech.Punctuation; value != nil { + settings.VerbalizePunctuationStyle = *value + } + if value := profile.Speech.Capitalization; value != nil { + settings.SetCapitalizationStyle(*value) + } + if value := profile.Speech.RaisePitchForCapitals; value != nil { + settings.RaisePitchForCapitals = *value + } + if value := profile.Speech.BeepForCapitals; value != nil { + settings.BeepForCapitals = *value + } + if value := profile.Speech.SayCapForCapitals; value != nil { + settings.SayCapForCapitals = *value + } + if value := profile.Speech.OutputModule; value != nil { + settings.SpeechOutputModule = *value + } + if value := profile.Speech.DefaultVoice; value != nil { + settings.DefaultVoice = cloneVoice(*value) + } + if value := profile.Speech.UppercaseVoice; value != nil { + settings.UppercaseVoice = cloneVoice(*value) + } + if value := profile.Speech.HyperlinkVoice; value != nil { + settings.HyperlinkVoice = cloneVoice(*value) + } + if value := profile.Speech.SystemVoice; value != nil { + settings.SystemVoice = cloneVoice(*value) + } +} + +func apply_profile_sound(settings *Settings, profile writableProfile) { + if value := profile.Sound.Enabled; value != nil { + settings.EnableSound = *value + } + if value := profile.Sound.Volume; value != nil { + settings.SoundVolume = *value + } + if value := profile.Sound.Sink; value != nil { + settings.SoundSink = *value + } + if value := profile.Sound.Theme; value != nil { + settings.SoundTheme = *value + } + if value := profile.Sound.PlayForRole; value != nil { + settings.PlaySoundForRole = *value + } + if value := profile.Sound.PlayForState; value != nil { + settings.PlaySoundForState = *value + } + if value := profile.Sound.PlayForPosition; value != nil { + settings.PlaySoundForPositionInSet = *value + } + if value := profile.Sound.Spatialize; value != nil { + settings.SpatializeObjectSounds = *value + } + if value := profile.Sound.RolePresentationStrategy; value != nil { + settings.RoleSoundPresentation = *value + } +} + +func apply_profile_keyboard(settings *Settings, profile writableProfile) { + if value := profile.Keyboard.Bindings; value != nil { + settings.KeyBindings = input.CloneBindingOverrides(*value) + } + if value := profile.Keyboard.Layout; value != nil { + settings.KeyboardLayout = *value + } + if value := profile.Keyboard.ScreenReaderKeys; value != nil { + settings.CthulhuModifierKeys = append([]string(nil), (*value)...) + } +} + +func apply_profile_echo_keys(settings *Settings, profile writableProfile) { + if value := profile.KeyEcho.Enabled; value != nil { + settings.EnableKeyEcho = *value + } + if value := profile.KeyEcho.EditFieldsOnly; value != nil { + settings.KeyEchoInEditFieldsOnly = *value + } + if value := profile.KeyEcho.ByCharacter; value != nil { + settings.EnableEchoByCharacter = *value + } + if value := profile.KeyEcho.ByWord; value != nil { + settings.EnableEchoByWord = *value + } + if value := profile.KeyEcho.BySentence; value != nil { + settings.EnableEchoBySentence = *value + } + if value := profile.KeyEcho.Alphabetic; value != nil { + settings.EnableAlphabeticKeys = *value + } + if value := profile.KeyEcho.Numeric; value != nil { + settings.EnableNumericKeys = *value + } + if value := profile.KeyEcho.Punctuation; value != nil { + settings.EnablePunctuationKeys = *value + } + if value := profile.KeyEcho.Space; value != nil { + settings.EnableSpace = *value + } + if value := profile.KeyEcho.Modifiers; value != nil { + settings.EnableModifierKeys = *value + } + if value := profile.KeyEcho.FunctionKeys; value != nil { + settings.EnableFunctionKeys = *value + } + if value := profile.KeyEcho.ActionKeys; value != nil { + settings.EnableActionKeys = *value + } + if value := profile.KeyEcho.NavigationKeys; value != nil { + settings.EnableNavigationKeys = *value + } + if value := profile.KeyEcho.Diacritical; value != nil { + settings.EnableDiacriticalKeys = *value + } +} + +func boolPointer(value bool) *bool { return &value } + +func intPointer(value int) *int { return &value } + +func floatPointer(value float64) *float64 { return &value } + +func stringPointer(value string) *string { return &value } + +func stringSlicePointer(value []string) *[]string { + copy := append([]string(nil), value...) + return © +} + +func pronunciationSlicePointer(value []PronunciationEntry) *[]PronunciationEntry { + copy := append([]PronunciationEntry{}, value...) + return © +} + +func textAttributeSlicePointer(value []TextAttributeChoice) *[]TextAttributeChoice { + copy := append([]TextAttributeChoice{}, value...) + return © +} + +func voicePointer(value Voice) *Voice { copy := cloneVoice(value); return © } + +func bindingSlicePointer(value []input.BindingOverride) *[]input.BindingOverride { + copy := input.CloneBindingOverrides(value) + if copy == nil { + copy = []input.BindingOverride{} + } + return © +} diff --git a/internal/config/progress_test.go b/internal/config/progress_test.go new file mode 100644 index 0000000..125188d --- /dev/null +++ b/internal/config/progress_test.go @@ -0,0 +1,90 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func TestProgressSettingsPersistenceAndInheritance(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + global := DefaultSettings() + global.ProgressBar.OutputMode = "both" + global.ProgressBar.ReportBackground = true + if err := store.Save(global); err != nil { + t.Fatal(err) + } + application := global + application.ProgressBar.OutputMode = "off" + if err := store.SaveForApplication("Example Application", application); err != nil { + t.Fatal(err) + } + loaded, err := store.Load() + if err != nil || loaded.ProgressBar != global.ProgressBar { + t.Fatalf("global progress: %+v, %v", loaded.ProgressBar, err) + } + app, found, err := store.LoadForApplication("Example Application") + if err != nil || !found || app.ProgressBar != application.ProgressBar { + t.Fatalf("application progress: %+v, %v", app.ProgressBar, err) + } + global.ProgressBar.ReportBackground = false + global.ProgressBar.SpeechPercentageInterval = 5 + if err := store.Save(global); err != nil { + t.Fatal(err) + } + app, _, err = store.LoadForApplication("Example Application") + if err != nil || app.ProgressBar.OutputMode != "off" || app.ProgressBar.ReportBackground || app.ProgressBar.SpeechPercentageInterval != 5 { + t.Fatalf("inherited progress: %+v, %v", app.ProgressBar, err) + } +} + +func TestObsoleteProgressFieldsDoNotBreakExistingFiles(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + contents := "schema-version = 2\nactive-profile = 'default'\n[profiles.default.sound]\nbeep-progress-updates = false\nprogress-beep-interval = 7\nplay-for-value = true\n" + if err := os.WriteFile(path, []byte(contents), 0600); err != nil { + t.Fatal(err) + } + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + settings, err := store.Load() + if err != nil || settings.ProgressBar != DefaultProgressBarSettings() { + t.Fatalf("existing settings: %+v, %v", settings.ProgressBar, err) + } + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + data, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + for _, key := range []string{"beep-progress-updates", "progress-beep-interval", "play-for-value"} { + if strings.Contains(string(data), key) { + t.Fatalf("obsolete field %s was saved", key) + } + } +} + +func TestInvalidProgressSettingsRejected(t *testing.T) { + for _, change := range []func(*ProgressBarSettings){ + func(s *ProgressBarSettings) { s.OutputMode = "invalid" }, + func(s *ProgressBarSettings) { s.BeepPercentageInterval = 0 }, + func(s *ProgressBarSettings) { s.SpeechPercentageInterval = 101 }, + } { + settings := DefaultSettings() + change(&settings.ProgressBar) + if Validate(settings) == nil { + t.Fatalf("invalid progress settings accepted: %+v", settings.ProgressBar) + } + } +} diff --git a/internal/config/schema.go b/internal/config/schema.go new file mode 100644 index 0000000..c16cca6 --- /dev/null +++ b/internal/config/schema.go @@ -0,0 +1,202 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "git.stormux.org/storm/cthulhu/internal/input" +) + +const CurrentSchemaVersion = 2 + +type writableDocument struct { + SchemaVersion int `toml:"schema-version"` + ActiveProfile string `toml:"active-profile"` + Profiles map[string]writableProfile `toml:"profiles"` + Applications map[string]string `toml:"applications,omitempty"` +} + +// Profiles are patches over built-in defaults. The writer emits a complete +// active profile so saved behavior remains stable if defaults later change. +type writableProfile struct { + OCR writableOCR `toml:"ocr"` + ProgressBar writableProgressBar `toml:"progress-bar"` + Presentation writablePresentation `toml:"presentation"` + Speech writableSpeech `toml:"speech"` + Braille writableBraille `toml:"braille"` + Sound writableSound `toml:"sound"` + Keyboard writableKeyboard `toml:"keyboard"` + KeyEcho writableKeyEcho `toml:"key-echo"` +} + +type writableOCR struct { + Language *string `toml:"language,omitempty"` + Layout *int `toml:"layout,omitempty"` + Scale *int `toml:"scale,omitempty"` + Grayscale *bool `toml:"grayscale,omitempty"` + Invert *bool `toml:"invert,omitempty"` + BlackWhite *bool `toml:"black-white,omitempty"` + Threshold *int `toml:"threshold,omitempty"` + AutoRefresh *bool `toml:"auto-refresh,omitempty"` + RefreshInterval *int `toml:"refresh-interval-ms,omitempty"` + ConfirmClick *bool `toml:"confirm-click,omitempty"` + CopyFirstResult *bool `toml:"copy-first-result,omitempty"` + AutoReadAll *bool `toml:"auto-read-all,omitempty"` +} + +type writableProgressBar struct { + OutputMode *string `toml:"output-mode,omitempty"` + ReportBackground *bool `toml:"report-background,omitempty"` + BeepPercentageInterval *int `toml:"beep-percentage-interval,omitempty"` + SpeechPercentageInterval *int `toml:"speech-percentage-interval,omitempty"` +} + +type writablePresentation struct { + TimeFormat *string `toml:"time-format,omitempty"` + DateFormat *string `toml:"date-format,omitempty"` + SpeakDescription *bool `toml:"speak-description,omitempty"` + SpeechVerbosityLevel *int `toml:"speech-verbosity-level,omitempty"` + SayAllStyle *string `toml:"say-all-style,omitempty"` + Reading writableReading `toml:"reading,omitempty"` + Pronunciations *[]PronunciationEntry `toml:"pronunciations,omitempty"` + TextAttributes writableTextAttributes `toml:"text-attributes,omitempty"` +} + +type writableTextAttributes struct { + Choices *[]TextAttributeChoice `toml:"choices,omitempty"` + Indicator *int `toml:"indicator,omitempty"` +} + +type writableReading struct { + AutomaticallyReadClipboardChanges *bool `toml:"automatically-read-clipboard-changes,omitempty"` + AutomaticallyReadTitleChanges *bool `toml:"automatically-read-title-changes,omitempty"` + PhoneticCharacterHints *bool `toml:"phonetic-character-hints,omitempty"` + EnablePauseBreaks *bool `toml:"enable-pause-breaks,omitempty"` + SpeakNumbersAsDigits *bool `toml:"speak-numbers-as-digits,omitempty"` + SpeakMultiCaseStringsAsWords *bool `toml:"speak-multicase-strings-as-words,omitempty"` + EnableIndentation *bool `toml:"enable-indentation,omitempty"` + IndentationPresentationMode *string `toml:"indentation-presentation-mode,omitempty"` + OnlySpeakDisplayedText *bool `toml:"only-speak-displayed-text,omitempty"` + SpeakBlankLines *bool `toml:"speak-blank-lines,omitempty"` + EnableMnemonicSpeaking *bool `toml:"enable-mnemonic-speaking,omitempty"` + EnablePositionSpeaking *bool `toml:"enable-position-speaking,omitempty"` + EnableTutorialMessages *bool `toml:"enable-tutorial-messages,omitempty"` + MessagesAreDetailed *bool `toml:"messages-are-detailed,omitempty"` + UseColorNames *bool `toml:"use-color-names,omitempty"` + PresentTooltips *bool `toml:"present-tooltips,omitempty"` + EnableMouseReview *bool `toml:"enable-mouse-review,omitempty"` + SpeakMisspelledIndicator *bool `toml:"speak-misspelled-indicator,omitempty"` + SpeakContextBlockquote *bool `toml:"speak-context-blockquote,omitempty"` + SpeakContextList *bool `toml:"speak-context-list,omitempty"` + SpeakContextTable *bool `toml:"speak-context-table,omitempty"` + SpeakContextPanel *bool `toml:"speak-context-panel,omitempty"` + SpeakContextLandmark *bool `toml:"speak-context-landmark,omitempty"` + SpeakContextNonLandmarkForm *bool `toml:"speak-context-non-landmark-form,omitempty"` + SayAllContextBlockquote *bool `toml:"say-all-context-blockquote,omitempty"` + SayAllContextList *bool `toml:"say-all-context-list,omitempty"` + SayAllContextTable *bool `toml:"say-all-context-table,omitempty"` + SayAllContextPanel *bool `toml:"say-all-context-panel,omitempty"` + SayAllContextLandmark *bool `toml:"say-all-context-landmark,omitempty"` + SayAllContextNonLandmarkForm *bool `toml:"say-all-context-non-landmark-form,omitempty"` + ReadFullRowInGUITable *bool `toml:"read-full-row-in-gui-table,omitempty"` + ReadFullRowInDocumentTable *bool `toml:"read-full-row-in-document-table,omitempty"` + ReadFullRowInSpreadSheet *bool `toml:"read-full-row-in-spreadsheet,omitempty"` +} + +type writableSpeech struct { + Interruption *input.InterruptionSettings `toml:"interruption,omitempty"` + HardwareDevice *string `toml:"hardware-device,omitempty"` + HardwareBaudRate *int `toml:"hardware-baud-rate,omitempty"` + OutputModule *string `toml:"output-module,omitempty"` + Enabled *bool `toml:"enabled,omitempty"` + HistoryLimit *int `toml:"history-limit,omitempty"` + ServerFactory *string `toml:"server-factory,omitempty"` + Punctuation *int `toml:"punctuation-style,omitempty"` + Capitalization *string `toml:"capitalization-style,omitempty"` + RaisePitchForCapitals *bool `toml:"raise-pitch-for-capitals,omitempty"` + BeepForCapitals *bool `toml:"beep-for-capitals,omitempty"` + SayCapForCapitals *bool `toml:"say-cap-for-capitals,omitempty"` + DefaultVoice *Voice `toml:"default-voice,omitempty"` + UppercaseVoice *Voice `toml:"uppercase-voice,omitempty"` + HyperlinkVoice *Voice `toml:"hyperlink-voice,omitempty"` + SystemVoice *Voice `toml:"system-voice,omitempty"` +} + +type writableBraille struct { + Enabled *bool `toml:"enabled,omitempty"` + Contracted *bool `toml:"contracted,omitempty"` + ContractionTable *string `toml:"contraction-table,omitempty"` + AbbreviateRoles *bool `toml:"abbreviate-roles,omitempty"` + DisableEOL *bool `toml:"disable-eol,omitempty"` + WordWrap *bool `toml:"word-wrap,omitempty"` + Verbosity *int `toml:"verbosity,omitempty"` + SelectionIndicator *int `toml:"selection-indicator,omitempty"` + LinkIndicator *int `toml:"link-indicator,omitempty"` + FlashMessages *bool `toml:"flash-messages,omitempty"` + FlashTime *int `toml:"flash-time,omitempty"` + FlashPersistent *bool `toml:"flash-persistent,omitempty"` + FlashDetailed *bool `toml:"flash-detailed,omitempty"` +} + +type writableSound struct { + // Retain recognition of existing version 2 fields. They are no longer used + // or emitted when saving settings; progress output has its own policy. + PlayForValue *bool `toml:"play-for-value,omitempty"` + BeepProgressUpdates *bool `toml:"beep-progress-updates,omitempty"` + ProgressBeepInterval *int `toml:"progress-beep-interval,omitempty"` + Enabled *bool `toml:"enabled,omitempty"` + Volume *float64 `toml:"volume,omitempty"` + Sink *string `toml:"sink,omitempty"` + Theme *string `toml:"theme,omitempty"` + PlayForRole *bool `toml:"play-for-role,omitempty"` + PlayForState *bool `toml:"play-for-state,omitempty"` + PlayForPosition *bool `toml:"play-for-position,omitempty"` + Spatialize *bool `toml:"spatialize,omitempty"` + RolePresentationStrategy *string `toml:"role-presentation-strategy,omitempty"` +} + +type writableKeyboard struct { + Bindings *[]input.BindingOverride `toml:"bindings,omitempty"` + Layout *int `toml:"layout,omitempty"` + ScreenReaderKeys *[]string `toml:"screen-reader-keys,omitempty"` +} + +type writableKeyEcho struct { + UseCustomEchoVoice *bool `toml:"custom-voice,omitempty"` + UseCustomEchoSpeechServer *bool `toml:"custom-speech-server,omitempty"` + UseCustomEchoForKey *bool `toml:"custom-for-key,omitempty"` + UseCustomEchoForCharacter *bool `toml:"custom-for-character,omitempty"` + UseCustomEchoForWord *bool `toml:"custom-for-word,omitempty"` + UseCustomEchoForSentence *bool `toml:"custom-for-sentence,omitempty"` + EchoVoice *Voice `toml:"voice,omitempty"` + EchoSpeechServer *string `toml:"speech-server,omitempty"` + + Enabled *bool `toml:"enabled,omitempty"` + EditFieldsOnly *bool `toml:"edit-fields-only,omitempty"` + ByCharacter *bool `toml:"by-character,omitempty"` + ByWord *bool `toml:"by-word,omitempty"` + BySentence *bool `toml:"by-sentence,omitempty"` + Alphabetic *bool `toml:"alphabetic,omitempty"` + Numeric *bool `toml:"numeric,omitempty"` + Punctuation *bool `toml:"punctuation,omitempty"` + Space *bool `toml:"space,omitempty"` + Modifiers *bool `toml:"modifiers,omitempty"` + FunctionKeys *bool `toml:"function-keys,omitempty"` + ActionKeys *bool `toml:"action-keys,omitempty"` + NavigationKeys *bool `toml:"navigation-keys,omitempty"` + Diacritical *bool `toml:"diacritical,omitempty"` +} diff --git a/internal/config/settings.go b/internal/config/settings.go new file mode 100644 index 0000000..ec9b322 --- /dev/null +++ b/internal/config/settings.go @@ -0,0 +1,218 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "git.stormux.org/storm/cthulhu/internal/input" +) + +type VoiceFamily struct { + Name string `toml:"name"` + Lang string `toml:"lang"` + Dialect string `toml:"dialect"` + Variant string `toml:"variant"` +} + +type Voice struct { + Rate *float64 `toml:"rate"` + AveragePitch *float64 `toml:"average-pitch"` + Gain *float64 `toml:"gain"` + Family *VoiceFamily `toml:"family"` +} + +type ReadingSettings struct { + AutomaticallyReadClipboardChanges bool + AutomaticallyReadTitleChanges bool + PhoneticCharacterHints bool + EnablePauseBreaks bool + SpeakNumbersAsDigits bool + SpeakMultiCaseStringsAsWords bool + EnableIndentation bool + IndentationPresentationMode string + OnlySpeakDisplayedText bool + SpeakBlankLines bool + EnableMnemonicSpeaking bool + EnablePositionSpeaking bool + EnableTutorialMessages bool + MessagesAreDetailed bool + UseColorNames bool + PresentTooltips bool + EnableMouseReview bool + SpeakMisspelledIndicator bool + SpeakContextBlockquote bool + SpeakContextList bool + SpeakContextTable bool + SpeakContextPanel bool + SpeakContextLandmark bool + SpeakContextNonLandmarkForm bool + SayAllContextBlockquote bool + SayAllContextList bool + SayAllContextTable bool + SayAllContextPanel bool + SayAllContextLandmark bool + SayAllContextNonLandmarkForm bool + ReadFullRowInGUITable bool + ReadFullRowInDocumentTable bool + ReadFullRowInSpreadSheet bool +} + +type PronunciationEntry struct { + Word string `toml:"word"` + Replacement string `toml:"replacement"` +} + +type TextAttributeChoice struct { + Key string `toml:"key"` + Speak bool `toml:"speak"` + Braille bool `toml:"braille"` +} + +type TextAttributeSettings struct { + Choices []TextAttributeChoice + Indicator int +} + +var TextAttributeKeys = [...]string{ + "size", "family-name", "weight", "indent", "underline", "strikethrough", + "justification", "style", "paragraph-style", "text-spelling", "fg-color", "bg-color", +} + +func DefaultTextAttributes() TextAttributeSettings { + choices := make([]TextAttributeChoice, 0, len(TextAttributeKeys)) + for _, key := range TextAttributeKeys { + choices = append(choices, TextAttributeChoice{Key: key, Speak: true}) + } + return TextAttributeSettings{Choices: choices} +} + +// ProgressBarSettings follows NVDA's output modes and percentage thresholds. +type ProgressBarSettings struct { + OutputMode string + ReportBackground bool + BeepPercentageInterval int + SpeechPercentageInterval int +} + +func DefaultProgressBarSettings() ProgressBarSettings { + return ProgressBarSettings{OutputMode: "beep", BeepPercentageInterval: 1, SpeechPercentageInterval: 10} +} + +type Settings struct { + OCR OCRSettings + ProgressBar ProgressBarSettings + TimeFormat string + DateFormat string + EnableSound bool + SoundVolume float64 + SoundSink string + SoundTheme string + PlaySoundForRole bool + PlaySoundForState bool + PlaySoundForPositionInSet bool + SpatializeObjectSounds bool + RoleSoundPresentation string + + Path string + Loaded bool + ActiveProfile string + EnableSpeech bool + SpeechHistoryLimit int + SpeechInterruption input.InterruptionSettings + EnableBraille bool + EnableContractedBraille bool + BrailleContractionTable string + Braille BrailleOptions + HardwareSpeechDevice string + HardwareSpeechBaudRate int + SpeechServerFactory string + SpeakDescription bool + SpeechVerbosityLevel int + SayAllStyle string + Reading ReadingSettings + Pronunciations []PronunciationEntry + TextAttributes TextAttributeSettings + VerbalizePunctuationStyle int + CapitalizationStyle string // Compatibility with older settings and the remote API. + RaisePitchForCapitals bool + BeepForCapitals bool + SayCapForCapitals bool + KeyBindings []input.BindingOverride + KeyboardLayout int + CthulhuModifierKeys []string + EnableKeyEcho bool + KeyEchoInEditFieldsOnly bool + EnableEchoByCharacter bool + EnableEchoByWord bool + EnableEchoBySentence bool + EnableAlphabeticKeys bool + EnableNumericKeys bool + EnablePunctuationKeys bool + EnableSpace bool + EnableModifierKeys bool + EnableFunctionKeys bool + EnableActionKeys bool + EnableNavigationKeys bool + EnableDiacriticalKeys bool + UseCustomEchoVoice bool + UseCustomEchoSpeechServer bool + UseCustomEchoForKey bool + UseCustomEchoForCharacter bool + UseCustomEchoForWord bool + UseCustomEchoForSentence bool + EchoVoice Voice + EchoSpeechServer string + SpeechOutputModule string + DefaultVoice Voice + UppercaseVoice Voice + HyperlinkVoice Voice + SystemVoice Voice +} + +type OCRSettings struct { + Language string + Layout int + Scale int + Grayscale bool + Invert bool + BlackWhite bool + Threshold int + AutoRefresh bool + RefreshInterval int // Milliseconds. + ConfirmClick bool + CopyFirstResult bool + AutoReadAll bool +} + +const ( + DefaultSpeechHistoryLimit = 50 + MinSpeechHistoryLimit = 1 + MaxSpeechHistoryLimit = 1000 +) + +type BrailleOptions struct { + AbbreviateRoles bool + DisableEOL bool + WordWrap bool + Verbosity int + SelectionIndicator int + LinkIndicator int + FlashMessages bool + FlashTime int + FlashPersistent bool + FlashDetailed bool +} diff --git a/internal/config/settings_copy.go b/internal/config/settings_copy.go new file mode 100644 index 0000000..16c9863 --- /dev/null +++ b/internal/config/settings_copy.go @@ -0,0 +1,57 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "git.stormux.org/storm/cthulhu/internal/input" +) + +func cloneSettings(settings Settings) Settings { + settings.SpeechInterruption.Keys = append([]string(nil), settings.SpeechInterruption.Keys...) + settings.KeyBindings = input.CloneBindingOverrides(settings.KeyBindings) + settings.CthulhuModifierKeys = append([]string(nil), settings.CthulhuModifierKeys...) + settings.Pronunciations = append([]PronunciationEntry(nil), settings.Pronunciations...) + settings.TextAttributes.Choices = append([]TextAttributeChoice(nil), settings.TextAttributes.Choices...) + settings.DefaultVoice = cloneVoice(settings.DefaultVoice) + settings.UppercaseVoice = cloneVoice(settings.UppercaseVoice) + settings.HyperlinkVoice = cloneVoice(settings.HyperlinkVoice) + settings.SystemVoice = cloneVoice(settings.SystemVoice) + settings.EchoVoice = cloneVoice(settings.EchoVoice) + return settings +} + +func cloneVoice(voice Voice) Voice { + clone := voice + if voice.Rate != nil { + value := *voice.Rate + clone.Rate = &value + } + if voice.AveragePitch != nil { + value := *voice.AveragePitch + clone.AveragePitch = &value + } + if voice.Gain != nil { + value := *voice.Gain + clone.Gain = &value + } + if voice.Family != nil { + family := *voice.Family + clone.Family = &family + } + return clone +} diff --git a/internal/config/store.go b/internal/config/store.go new file mode 100644 index 0000000..bf51fb9 --- /dev/null +++ b/internal/config/store.go @@ -0,0 +1,285 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "bytes" + "crypto/sha256" + "encoding/hex" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "strings" + "sync" + "syscall" +) + +// Store owns the versioned Go configuration. An explicitly selected +// Python-era file fails strict decoding and cannot be replaced by Save. +type Store struct { + ioMu sync.Mutex + mu sync.RWMutex + path string + lastGood Settings + rename func(string, string) error +} + +func DefaultStorePath() (string, error) { return DefaultPath() } + +func NewStore(path string) (*Store, error) { + if path == "" { + var err error + path, err = DefaultStorePath() + if err != nil { + return nil, err + } + } + defaults := DefaultSettings() + defaults.Path = path + return &Store{path: path, lastGood: cloneSettings(defaults), rename: os.Rename}, nil +} + +func (store *Store) Path() string { return store.path } + +// Current returns a copy of the last configuration which parsed and validated. +func (store *Store) Current() Settings { + store.mu.RLock() + defer store.mu.RUnlock() + return cloneSettings(store.lastGood) +} + +// Load returns the last known good configuration together with any read, +// parse, schema, or validation error. A missing file selects built-in defaults. +func (store *Store) Load() (Settings, error) { + store.ioMu.Lock() + defer store.ioMu.Unlock() + contents, err := readStoreFile(store.path) + if errors.Is(err, os.ErrNotExist) { + defaults := DefaultSettings() + defaults.Path = store.path + store.setCurrent(defaults) + return cloneSettings(defaults), nil + } + if err != nil { + return store.Current(), err + } + _, settings, err := decodeDocument(contents) + if err != nil { + return store.Current(), err + } + settings.Path = store.path + settings.Loaded = true + store.setCurrent(settings) + return cloneSettings(settings), nil +} + +// Save updates only the active profile and preserves all other profiles and +// application mappings. It validates before using an atomic replacement. +func (store *Store) Save(settings Settings) error { + return store.save(settings, "") +} + +// LoadForApplication returns the selected application profile, or the global +// profile when no application settings have been saved. +func (store *Store) LoadForApplication(application string) (Settings, bool, error) { + store.ioMu.Lock() + defer store.ioMu.Unlock() + document, _, err := store.documentForSave() + if err != nil { + return Settings{}, false, err + } + global, err := effectiveSettings(document) + if err != nil { + return Settings{}, false, err + } + name, found := document.Applications[application] + if found { + applyProfile(&global, document.Profiles[name]) + global.ActiveProfile = name + } + global.Path, global.Loaded = store.path, true + return global, found, nil +} + +// SaveForApplication creates or updates a dedicated profile without changing +// the global profile or other application mappings. +func (store *Store) SaveForApplication(application string, settings Settings) error { + if application == "" || application != strings.TrimSpace(application) { + return errors.New("invalid application identifier") + } + if err := validateCommandValue("application identifier", application); err != nil { + return err + } + return store.save(settings, application) +} + +func (store *Store) save(settings Settings, application string) error { + store.ioMu.Lock() + defer store.ioMu.Unlock() + if err := validate(settings); err != nil { + return err + } + document, original, err := store.documentForSave() + if err != nil { + return err + } + global, err := effectiveSettings(document) + if err != nil { + return err + } + profileName := document.ActiveProfile + if application == "" { + if settings.ActiveProfile != "" { + profileName = settings.ActiveProfile + } + if _, exists := document.Profiles[profileName]; !exists { + return fmt.Errorf("active profile %q does not exist", profileName) + } + } else { + profileName = document.Applications[application] + if profileName == "" { + hash := sha256.Sum256([]byte(application)) + profileName = "application-" + hex.EncodeToString(hash[:]) + } + if document.Applications == nil { + document.Applications = make(map[string]string) + } + document.Applications[application] = profileName + } + profile := profileFromSettings(settings) + if application != "" { + profile = applicationProfileDifference(global, settings) + } + document.Profiles[profileName] = profile + contents, err := encodeDocument(document) + if err != nil { + return err + } + if err := os.MkdirAll(filepath.Dir(store.path), 0o700); err != nil { + return fmt.Errorf("create settings directory: %w", err) + } + temporary, err := os.CreateTemp(filepath.Dir(store.path), ".settings-*.toml") + if err != nil { + return fmt.Errorf("create temporary settings file: %w", err) + } + temporaryPath := temporary.Name() + keepTemporary := false + defer func() { + if !keepTemporary { + _ = os.Remove(temporaryPath) + } + }() + if err := temporary.Chmod(0o600); err != nil { + _ = temporary.Close() + return fmt.Errorf("restrict temporary settings file: %w", err) + } + if _, err := temporary.Write(contents); err != nil { + _ = temporary.Close() + return fmt.Errorf("write temporary settings file: %w", err) + } + if err := temporary.Sync(); err != nil { + _ = temporary.Close() + return fmt.Errorf("flush temporary settings file: %w", err) + } + if err := temporary.Close(); err != nil { + return fmt.Errorf("close temporary settings file: %w", err) + } + if err := ensureUnchanged(store.path, original); err != nil { + return err + } + if err := store.rename(temporaryPath, store.path); err != nil { + return fmt.Errorf("replace settings file: %w", err) + } + keepTemporary = true + saved, err := effectiveSettings(document) + if err != nil { + return err + } + saved.Path = store.path + saved.Loaded = true + store.setCurrent(saved) + if err := syncDirectory(filepath.Dir(store.path)); err != nil { + return fmt.Errorf("flush settings directory: %w", err) + } + return nil +} + +func (store *Store) documentForSave() (writableDocument, []byte, error) { + contents, err := readStoreFile(store.path) + if errors.Is(err, os.ErrNotExist) { + return defaultDocument(), nil, nil + } + if err != nil { + return writableDocument{}, nil, err + } + document, _, err := decodeDocument(contents) + if err != nil { + return writableDocument{}, nil, fmt.Errorf("refuse to replace existing settings without a successful versioned load: %w", err) + } + return document, contents, nil +} + +func ensureUnchanged(path string, original []byte) error { + current, err := readStoreFile(path) + if original == nil && errors.Is(err, os.ErrNotExist) { + return nil + } + if err != nil { + return fmt.Errorf("verify settings before replacement: %w", err) + } + if original == nil || !bytes.Equal(current, original) { + return errors.New("settings changed while being saved; no file was replaced") + } + return nil +} + +func readStoreFile(path string) ([]byte, error) { + file, err := os.Open(path) + if err != nil { + return nil, err + } + defer file.Close() + contents, err := io.ReadAll(io.LimitReader(file, maxConfigSize+1)) + if err != nil { + return nil, fmt.Errorf("read settings: %w", err) + } + if len(contents) > maxConfigSize { + return nil, fmt.Errorf("settings exceed %d bytes", maxConfigSize) + } + return contents, nil +} + +func (store *Store) setCurrent(settings Settings) { + store.mu.Lock() + defer store.mu.Unlock() + store.lastGood = cloneSettings(settings) +} + +func syncDirectory(path string) error { + directory, err := os.Open(path) + if err != nil { + return err + } + defer directory.Close() + if err := directory.Sync(); err != nil && !errors.Is(err, syscall.EINVAL) && !errors.Is(err, syscall.ENOTSUP) { + return err + } + return nil +} diff --git a/internal/config/store_test.go b/internal/config/store_test.go new file mode 100644 index 0000000..8c46d1f --- /dev/null +++ b/internal/config/store_test.go @@ -0,0 +1,387 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +package config + +import ( + "errors" + "os" + "path/filepath" + "reflect" + "strings" + "testing" +) + +func TestStoreSaveAndLoadRoundTrip(t *testing.T) { + path := filepath.Join(t.TempDir(), "cthulhu", "settings.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + settings := DefaultSettings() + settings.EnableSpeech = false + settings.SpeechHistoryLimit = 1000 + settings.SayAllStyle = "sentence" + settings.Reading.EnableMnemonicSpeaking = false + settings.Reading.SayAllContextList = false + settings.Reading.SayAllContextPanel = false + settings.Reading.PresentTooltips = true + settings.Reading.EnableMouseReview = true + settings.EnableBraille = true + settings.EnableContractedBraille = true + settings.BrailleContractionTable = "en-us-g2.ctb" + settings.Braille = BrailleOptions{AbbreviateRoles: true, DisableEOL: true, WordWrap: true, + Verbosity: 0, SelectionIndicator: 0x40, LinkIndicator: 0x80, + FlashMessages: true, FlashTime: 3200, FlashPersistent: true, FlashDetailed: false} + settings.VerbalizePunctuationStyle = 3 + settings.CthulhuModifierKeys = []string{"Insert"} + rate := 72.0 + settings.DefaultVoice.Rate = &rate + if err := store.Save(settings); err != nil { + t.Fatalf("Save: %v", err) + } + + info, err := os.Stat(path) + if err != nil { + t.Fatal(err) + } + if permissions := info.Mode().Perm(); permissions != 0o600 { + t.Fatalf("settings permissions = %04o, want 0600", permissions) + } + contents, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if !strings.Contains(string(contents), "schema-version = 2") || + !strings.Contains(string(contents), "[profiles.default.speech]") || + !strings.Contains(string(contents), "history-limit = 1000") { + t.Fatalf("settings do not contain schema version:\n%s", contents) + } + + reopened, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + loaded, err := reopened.Load() + if err != nil { + t.Fatalf("Load: %v", err) + } + settings.Path, settings.Loaded, settings.ActiveProfile = path, true, "default" + if !reflect.DeepEqual(loaded, settings) { + t.Fatalf("loaded settings differ:\n got: %#v\nwant: %#v", loaded, settings) + } +} + +func TestLoadUpgradesLegacyDateFormatIDs(t *testing.T) { + for source, target := range map[string]string{ + "ymd": "numbers-ymd", + "mdy": "numbers-mdy", + "dmy": "numbers-dmy", + } { + path := filepath.Join(t.TempDir(), "settings.toml") + contents := "schema-version = 2\nactive-profile = 'default'\n[profiles.default.presentation]\ntime-format = '24-hour'\ndate-format = '" + source + "'\n" + if err := os.WriteFile(path, []byte(contents), 0o600); err != nil { + t.Fatal(err) + } + settings, err := Load(path) + if err != nil { + t.Fatalf("%s: Load: %v", source, err) + } + if settings.TimeFormat != "24-hour" || settings.DateFormat != target { + t.Fatalf("%s: formats = (%s, %s), want (24-hour, %s)", source, + settings.TimeFormat, settings.DateFormat, target) + } + } +} + +func TestStoreMissingFileUsesDefaults(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + settings, err := store.Load() + if err != nil { + t.Fatal(err) + } + if settings.Loaded || settings.Path != path || !settings.EnableSpeech || + settings.SpeechHistoryLimit != DefaultSpeechHistoryLimit { + t.Fatalf("missing settings = %#v", settings) + } +} + +func TestStoreRejectsSchemaVersionsAndUnknownFields(t *testing.T) { + for name, contents := range map[string]string{ + "missing": `[general]`, + "future": "schema-version = 3\nactive-profile = 'default'\n[profiles.default]\n", + "unknown": "schema-version = 2\nactive-profile = 'default'\n[profiles.default]\nfuture-setting = true\n", + } { + t.Run(name, func(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + if err := os.WriteFile(path, []byte(contents), 0o600); err != nil { + t.Fatal(err) + } + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + loaded, err := store.Load() + if err == nil { + t.Fatal("Load accepted incompatible settings") + } + if !reflect.DeepEqual(loaded, store.Current()) || loaded.Loaded { + t.Fatalf("last good settings were not retained: %#v", loaded) + } + }) + } +} + +func TestStoreVersionFixtures(t *testing.T) { + current, err := os.ReadFile(filepath.Join("testdata", "settings-v2.toml")) + if err != nil { + t.Fatal(err) + } + settings, err := decodeWritable(current) + if err != nil { + t.Fatalf("decode current fixture: %v", err) + } + if settings.SpeakDescription || settings.VerbalizePunctuationStyle != 2 || settings.DefaultVoice.Rate == nil || *settings.DefaultVoice.Rate != 65 { + t.Fatalf("current fixture settings = %#v", settings) + } + + future, err := os.ReadFile(filepath.Join("testdata", "settings-v3.toml")) + if err != nil { + t.Fatal(err) + } + if _, err := decodeWritable(future); err == nil || !strings.Contains(err.Error(), "schema version 3") { + t.Fatalf("future fixture error = %v", err) + } +} + +func TestStoreLoadFailureRetainsLastGood(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + settings := DefaultSettings() + settings.SpeakDescription = false + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + good := store.Current() + if err := os.WriteFile(path, []byte("schema-version = 2\n[profiles\n"), 0o600); err != nil { + t.Fatal(err) + } + loaded, err := store.Load() + if err == nil { + t.Fatal("Load accepted malformed settings") + } + if !reflect.DeepEqual(loaded, good) || !reflect.DeepEqual(store.Current(), good) { + t.Fatalf("last good changed:\n got: %#v\nwant: %#v", loaded, good) + } +} + +func TestStoreValidationFailureDoesNotTouchFile(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + settings := DefaultSettings() + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + original, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + settings.SoundVolume = 2 + if err := store.Save(settings); err == nil { + t.Fatal("Save accepted invalid settings") + } + after, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(after, original) { + t.Fatal("validation failure changed the settings file") + } +} + +func TestStoreRefusesToReplaceLegacyFile(t *testing.T) { + path := filepath.Join(t.TempDir(), "user-settings.toml") + legacy := []byte("[general]\nenableSpeech = false\nunknownPythonSetting = true\n") + if err := os.WriteFile(path, legacy, 0o600); err != nil { + t.Fatal(err) + } + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + if err := store.Save(DefaultSettings()); err == nil || !strings.Contains(err.Error(), "refuse to replace") { + t.Fatalf("Save error = %v", err) + } + after, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(after, legacy) { + t.Fatal("legacy file changed") + } +} + +func TestDefaultStorePathUsesGoDevelopmentSettingsPath(t *testing.T) { + t.Setenv("XDG_DATA_HOME", filepath.Join(t.TempDir(), "data")) + path, err := DefaultStorePath() + if err != nil { + t.Fatal(err) + } + want := filepath.Join(os.Getenv("XDG_DATA_HOME"), "cthulhu", "user-settings-go.toml") + if path != want { + t.Fatalf("DefaultStorePath = %q, want %q", path, want) + } +} + +func TestStoreRenameFailurePreservesOriginalAndCleansTemporary(t *testing.T) { + directory := t.TempDir() + path := filepath.Join(directory, "settings.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + settings := DefaultSettings() + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + original, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + store.rename = func(_, _ string) error { return errors.New("injected rename failure") } + settings.EnableSpeech = false + if err := store.Save(settings); err == nil || !strings.Contains(err.Error(), "injected rename failure") { + t.Fatalf("Save error = %v", err) + } + after, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(after, original) { + t.Fatal("rename failure changed the settings file") + } + temporary, err := filepath.Glob(filepath.Join(directory, ".settings-*.toml")) + if err != nil { + t.Fatal(err) + } + if len(temporary) != 0 { + t.Fatalf("temporary files remain: %v", temporary) + } +} + +func TestStoreCopiesMutableSettings(t *testing.T) { + store, err := NewStore(filepath.Join(t.TempDir(), "settings.toml")) + if err != nil { + t.Fatal(err) + } + settings := DefaultSettings() + rate := 40.0 + settings.DefaultVoice.Rate = &rate + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + settings.CthulhuModifierKeys[0] = "changed" + rate = 99 + current := store.Current() + if current.CthulhuModifierKeys[0] != "Insert" || current.DefaultVoice.Rate == nil || *current.DefaultVoice.Rate != 40 { + t.Fatalf("stored settings alias caller memory: %#v", current) + } + current.CthulhuModifierKeys[0] = "changed again" + *current.DefaultVoice.Rate = 1 + again := store.Current() + if again.CthulhuModifierKeys[0] != "Insert" || *again.DefaultVoice.Rate != 40 { + t.Fatalf("Current aliases store memory: %#v", again) + } +} + +func TestStoreSavePreservesOtherProfilesAndApplicationMappings(t *testing.T) { + directory := t.TempDir() + path := filepath.Join(directory, "user-settings-go.toml") + fixture, err := os.ReadFile(filepath.Join("testdata", "settings-v2.toml")) + if err != nil { + t.Fatal(err) + } + if err := os.WriteFile(path, fixture, 0o600); err != nil { + t.Fatal(err) + } + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + settings, err := store.Load() + if err != nil { + t.Fatal(err) + } + settings.VerbalizePunctuationStyle = 3 + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + contents, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + document, loaded, err := decodeDocument(contents) + if err != nil { + t.Fatal(err) + } + if loaded.VerbalizePunctuationStyle != 3 || loaded.ActiveProfile != "default" { + t.Fatalf("saved active profile = %#v", loaded) + } + if document.Applications["org.example.Editor"] != "quiet" { + t.Fatalf("application mappings = %#v", document.Applications) + } + quiet := DefaultSettings() + applyProfile(&quiet, document.Profiles["quiet"]) + if quiet.EnableSpeech { + t.Fatal("save changed the unrelated quiet profile") + } +} + +func TestStoreRejectsInvalidProfileTopology(t *testing.T) { + for name, contents := range map[string]string{ + "missing active profile": "schema-version = 2\nactive-profile = 'missing'\n[profiles.default]\n", + "missing application profile": "schema-version = 2\nactive-profile = 'default'\n[applications]\n'org.example.Editor' = 'missing'\n[profiles.default]\n", + "invalid inactive profile": "schema-version = 2\nactive-profile = 'default'\n[profiles.default]\n[profiles.broken.sound]\nvolume = 2.0\n", + } { + t.Run(name, func(t *testing.T) { + if _, err := decodeWritable([]byte(contents)); err == nil { + t.Fatal("invalid profile topology was accepted") + } + }) + } +} + +func TestEnsureUnchangedDetectsExternalCreationAndModification(t *testing.T) { + path := filepath.Join(t.TempDir(), "user-settings-go.toml") + if err := ensureUnchanged(path, nil); err != nil { + t.Fatalf("missing file changed unexpectedly: %v", err) + } + if err := os.WriteFile(path, []byte("created"), 0o600); err != nil { + t.Fatal(err) + } + if err := ensureUnchanged(path, nil); err == nil || !strings.Contains(err.Error(), "changed while being saved") { + t.Fatalf("external creation error = %v", err) + } + if err := ensureUnchanged(path, []byte("original")); err == nil || !strings.Contains(err.Error(), "changed while being saved") { + t.Fatalf("external modification error = %v", err) + } + if err := ensureUnchanged(path, []byte("created")); err != nil { + t.Fatalf("unchanged file rejected: %v", err) + } +} diff --git a/internal/config/testdata/settings-v1.toml b/internal/config/testdata/settings-v1.toml new file mode 100644 index 0000000..0923b6c --- /dev/null +++ b/internal/config/testdata/settings-v1.toml @@ -0,0 +1,34 @@ +schema-version = 1 + +[general] +enable-sound = true +sound-volume = 0.5 +sound-sink = "auto" +sound-theme = "default" +play-sound-for-role = false +play-sound-for-state = false +role-sound-presentation = "sound_and_speech" +enable-speech = true +speech-server-factory = "speechdispatcherfactory" +speak-description = false +speech-verbosity-level = 1 +verbalize-punctuation-style = 2 +capitalization-style = "none" +keyboard-layout = 1 +cthulhu-modifier-keys = ["Insert", "KP_Insert"] +enable-key-echo = true +enable-echo-by-character = false +enable-echo-by-word = false +enable-echo-by-sentence = false +enable-alphabetic-keys = true +enable-numeric-keys = true +enable-punctuation-keys = true +enable-space = true +enable-modifier-keys = true +enable-function-keys = true +enable-action-keys = true +enable-navigation-keys = false +enable-diacritical-keys = false + +[general.default-voice] +rate = 65.0 diff --git a/internal/config/testdata/settings-v2.toml b/internal/config/testdata/settings-v2.toml new file mode 100644 index 0000000..55e981c --- /dev/null +++ b/internal/config/testdata/settings-v2.toml @@ -0,0 +1,17 @@ +schema-version = 2 +active-profile = "default" + +[applications] +"org.example.Editor" = "quiet" + +[profiles.default.presentation] +speak-description = false + +[profiles.default.speech] +punctuation-style = 2 + +[profiles.default.speech.default-voice] +rate = 65.0 + +[profiles.quiet.speech] +enabled = false diff --git a/internal/config/testdata/settings-v3.toml b/internal/config/testdata/settings-v3.toml new file mode 100644 index 0000000..ba74edd --- /dev/null +++ b/internal/config/testdata/settings-v3.toml @@ -0,0 +1,4 @@ +schema-version = 3 +active-profile = "default" + +[profiles.default] diff --git a/internal/config/text_preferences_test.go b/internal/config/text_preferences_test.go new file mode 100644 index 0000000..246314a --- /dev/null +++ b/internal/config/text_preferences_test.go @@ -0,0 +1,37 @@ +package config + +import ( + "path/filepath" + "reflect" + "testing" +) + +func TestTextPreferencesPersistAndInheritByApplication(t *testing.T) { + store, err := NewStore(filepath.Join(t.TempDir(), "settings.toml")) + if err != nil { + t.Fatal(err) + } + global := DefaultSettings() + global.Pronunciations = []PronunciationEntry{{Word: "SQL", Replacement: "sequel"}} + global.TextAttributes.Choices[0].Speak = false + global.TextAttributes.Choices[0].Braille = true + global.TextAttributes.Indicator = 0x40 + if err := store.Save(global); err != nil { + t.Fatal(err) + } + loaded, err := store.Load() + if err != nil || !reflect.DeepEqual(loaded.Pronunciations, global.Pronunciations) || !reflect.DeepEqual(loaded.TextAttributes, global.TextAttributes) { + t.Fatalf("loaded preferences = %+v, %+v, %v", loaded.Pronunciations, loaded.TextAttributes, err) + } + app := cloneSettings(global) + app.Pronunciations = []PronunciationEntry{{Word: "SQL", Replacement: "S Q L"}} + app.TextAttributes.Choices[0], app.TextAttributes.Choices[1] = app.TextAttributes.Choices[1], app.TextAttributes.Choices[0] + app.TextAttributes.Indicator = 0xc0 + if err := store.SaveForApplication("Editor", app); err != nil { + t.Fatal(err) + } + actual, found, err := store.LoadForApplication("Editor") + if err != nil || !found || !reflect.DeepEqual(actual.Pronunciations, app.Pronunciations) || !reflect.DeepEqual(actual.TextAttributes, app.TextAttributes) { + t.Fatalf("application preferences = %+v, %+v, %t, %v", actual.Pronunciations, actual.TextAttributes, found, err) + } +} diff --git a/internal/config/validation.go b/internal/config/validation.go new file mode 100644 index 0000000..9737d41 --- /dev/null +++ b/internal/config/validation.go @@ -0,0 +1,262 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package config + +import ( + "errors" + "fmt" + "math" + "path/filepath" + "strings" + "unicode" + + "git.stormux.org/storm/cthulhu/internal/datetime" + "git.stormux.org/storm/cthulhu/internal/input" +) + +// Validate checks the complete configuration without touching the filesystem. +func Validate(settings Settings) error { return validate(settings) } + +func validate(settings Settings) error { + if err := settings.SpeechInterruption.Validate(); err != nil { + return err + } + if settings.OCR.Layout != 3 && settings.OCR.Layout != 6 && settings.OCR.Layout != 11 || + settings.OCR.Scale < 1 || settings.OCR.Scale > 4 || settings.OCR.Threshold < 0 || settings.OCR.Threshold > 255 || + settings.OCR.RefreshInterval < 500 || settings.OCR.RefreshInterval > 60000 || + len(settings.OCR.Language) > 1024 || strings.ContainsAny(settings.OCR.Language, "\x00\r\n\t ") { + return errors.New("validate configuration: invalid OCR settings") + } + if settings.Braille.Verbosity < 0 || settings.Braille.Verbosity > 1 || + settings.Braille.FlashTime < 0 || settings.Braille.FlashTime > 60000 { + return errors.New("validate configuration: invalid braille settings") + } + if len(settings.Pronunciations) > 256 { + return errors.New("too many pronunciation entries") + } + words := make(map[string]bool, len(settings.Pronunciations)) + for _, entry := range settings.Pronunciations { + word := strings.ToLower(entry.Word) + if word == "" || strings.TrimSpace(entry.Word) != entry.Word || + len(entry.Word) > 128 || len(entry.Replacement) > 512 || + strings.ContainsAny(entry.Word, "\x00\r\n\t ") || + strings.ContainsAny(entry.Replacement, "\x00\r\n") || words[word] { + return errors.New("pronunciation entries need unique, single words and valid replacements") + } + words[word] = true + for _, character := range entry.Word { + if !unicode.IsLetter(character) && !unicode.IsNumber(character) && character != '_' { + return errors.New("pronunciation words may contain only letters, numbers, or underscores") + } + } + } + if settings.TextAttributes.Indicator != 0 && settings.TextAttributes.Indicator != 0x40 && + settings.TextAttributes.Indicator != 0x80 && settings.TextAttributes.Indicator != 0xc0 { + return errors.New("invalid text attribute braille indicator") + } + if len(settings.TextAttributes.Choices) != len(TextAttributeKeys) { + return errors.New("text attributes list must include every supported attribute") + } + allowed, seen := make(map[string]bool), make(map[string]bool) + for _, key := range TextAttributeKeys { + allowed[key] = true + } + for _, choice := range settings.TextAttributes.Choices { + if !allowed[choice.Key] || seen[choice.Key] { + return errors.New("invalid or duplicate text attribute") + } + seen[choice.Key] = true + } + for _, indicator := range []int{settings.Braille.SelectionIndicator, settings.Braille.LinkIndicator} { + if indicator != 0 && indicator != 0x40 && indicator != 0x80 && indicator != 0xc0 { + return errors.New("validate configuration: invalid braille indicator") + } + } + if len(settings.BrailleContractionTable) > 256 || strings.ContainsAny(settings.BrailleContractionTable, "\x00\r\n,") { + return errors.New("validate configuration: invalid braille contraction table") + } + if !datetime.ValidTime(settings.TimeFormat) { + return errors.New("choose a valid time format") + } + if !datetime.ValidDate(settings.DateFormat) { + return errors.New("choose a valid date format") + } + if settings.SoundVolume < 0 || settings.SoundVolume > 1 || math.IsNaN(settings.SoundVolume) || math.IsInf(settings.SoundVolume, 0) { + return errors.New("validate configuration: soundVolume must be between 0 and 1") + } + switch settings.SoundSink { + case "auto", "pipewire", "pulse", "alsa": + default: + return fmt.Errorf("validate configuration: unknown soundSink %q", settings.SoundSink) + } + if settings.SoundTheme == "" || filepath.Base(settings.SoundTheme) != settings.SoundTheme || settings.SoundTheme == "." || settings.SoundTheme == ".." { + return errors.New("validate configuration: invalid soundTheme") + } + switch settings.ProgressBar.OutputMode { + case "off", "beep", "speak", "both": + default: + return errors.New("choose a valid progress bar output mode") + } + if settings.ProgressBar.BeepPercentageInterval < 1 || settings.ProgressBar.BeepPercentageInterval > 100 || + settings.ProgressBar.SpeechPercentageInterval < 1 || settings.ProgressBar.SpeechPercentageInterval > 100 { + return errors.New("progress bar percentage intervals must be between 1 and 100") + } + switch settings.RoleSoundPresentation { + case "sound_and_speech", "speech_only", "sound_only": + default: + return errors.New("validate configuration: invalid roleSoundPresentation") + } + + if settings.SpeechServerFactory != "speechdispatcherfactory" && + settings.SpeechServerFactory != "cthulhu.speechdispatcherfactory" && + settings.SpeechServerFactory != "hardwarefactory" { + return fmt.Errorf( + "validate configuration: speechServerFactory %q is not supported by the preview", + settings.SpeechServerFactory, + ) + } + if len(settings.HardwareSpeechDevice) > 1024 || strings.ContainsAny(settings.HardwareSpeechDevice, "\x00\r\n") { + return errors.New("invalid hardware speech device") + } + switch settings.HardwareSpeechBaudRate { + case 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200: + default: + return errors.New("choose a supported hardware speech baud rate") + } + if settings.SpeechServerFactory == "hardwarefactory" { + if settings.UseCustomEchoVoice && settings.UseCustomEchoSpeechServer { + return errors.New("a separate echo synthesizer requires Speech Dispatcher; disable custom echo voice for hardware speech") + } + switch settings.SpeechOutputModule { + case "litetalk", "doubletalk", "tripletalk", "dectalk": + default: + return errors.New("choose a hardware speech synthesizer") + } + if !filepath.IsAbs(settings.HardwareSpeechDevice) { + return errors.New("choose an explicit serial device path for hardware speech") + } + } + switch settings.SpeechVerbosityLevel { + case 0, 1: + default: + return fmt.Errorf("validate configuration: speechVerbosityLevel %d is not 0 or 1", settings.SpeechVerbosityLevel) + } + if settings.SayAllStyle != "line" && settings.SayAllStyle != "sentence" { + return fmt.Errorf("validate configuration: say-all-style %q is invalid", settings.SayAllStyle) + } + if settings.SpeechHistoryLimit < MinSpeechHistoryLimit || settings.SpeechHistoryLimit > MaxSpeechHistoryLimit { + return fmt.Errorf("validate configuration: speech history limit %d must be between %d and %d", + settings.SpeechHistoryLimit, MinSpeechHistoryLimit, MaxSpeechHistoryLimit) + } + if settings.VerbalizePunctuationStyle < 0 || settings.VerbalizePunctuationStyle > 3 { + return fmt.Errorf( + "validate configuration: verbalizePunctuationStyle %d is outside 0 through 3", + settings.VerbalizePunctuationStyle, + ) + } + switch settings.CapitalizationStyle { + case "none", "spell", "icon": + default: + return fmt.Errorf("validate configuration: capitalizationStyle %q is invalid", settings.CapitalizationStyle) + } + if err := input.ValidateBindingOverrides(settings.KeyBindings); err != nil { + return fmt.Errorf("key bindings: %w", err) + } + if settings.KeyboardLayout != 1 && settings.KeyboardLayout != 2 { + return fmt.Errorf("validate configuration: keyboardLayout %d is not 1 or 2", settings.KeyboardLayout) + } + for _, key := range settings.CthulhuModifierKeys { + if err := validateCommandValue("cthulhuModifierKeys", key); err != nil { + return err + } + } + if strings.ContainsAny(settings.SpeechOutputModule, "\r\n\x00") { + return errors.New("invalid speech output module") + } + if strings.ContainsAny(settings.EchoSpeechServer, "\r\n\x00") { + return fmt.Errorf("invalid echo speech synthesizer") + } + if err := validateVoice(settings.EchoVoice, true); err != nil { + return fmt.Errorf("echo voice: %w", err) + } + if err := validateVoice(settings.DefaultVoice); err != nil { + return err + } + for _, voice := range []Voice{settings.UppercaseVoice, settings.HyperlinkVoice, settings.SystemVoice} { + if err := validateVoice(voice); err != nil { + return err + } + } + switch settings.Reading.IndentationPresentationMode { + case "", "speech", "beeps", "both": + default: + return errors.New("invalid indentation presentation mode") + } + return nil +} + +func validateVoice(voice Voice, echo ...bool) error { + values := []struct { + name string + value *float64 + maximum float64 + }{ + {name: "rate", value: voice.Rate, maximum: 99}, + {name: "average-pitch", value: voice.AveragePitch, maximum: 9}, + {name: "gain", value: voice.Gain, maximum: 9}, + } + if len(echo) != 0 && echo[0] { + values[0].maximum = 100 + values[1].maximum = 10 + values[2].maximum = 10 + } + for _, field := range values { + name, value, maximum := field.name, field.value, field.maximum + if value == nil { + continue + } + if *value < 0 || *value > maximum || math.IsNaN(*value) || math.IsInf(*value, 0) { + return fmt.Errorf("validate configuration: default voice %s %.2f is outside 0 through %.0f", name, *value, maximum) + } + } + if voice.Family == nil { + return nil + } + familyValues := []struct { + name string + value string + }{ + {name: "name", value: voice.Family.Name}, + {name: "lang", value: voice.Family.Lang}, + {name: "dialect", value: voice.Family.Dialect}, + {name: "variant", value: voice.Family.Variant}, + } + for _, field := range familyValues { + if err := validateCommandValue("default voice family "+field.name, field.value); err != nil { + return err + } + } + return nil +} + +func validateCommandValue(name, value string) error { + if strings.ContainsAny(value, "\r\n\x00") { + return fmt.Errorf("validate configuration: %s contains a control character", name) + } + return nil +} diff --git a/internal/config/voices.go b/internal/config/voices.go new file mode 100644 index 0000000..7fa9a33 --- /dev/null +++ b/internal/config/voices.go @@ -0,0 +1,32 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +// EffectiveVoice resolves a sparse voice over Default. Uppercase retains the +// established automatic pitch unless overridden or capital pitch is disabled. +func EffectiveVoice(settings Settings, kind string) Voice { + voice := cloneVoice(settings.DefaultVoice) + var override Voice + switch kind { + case "uppercase": + pitch := 7.0 + if voice.AveragePitch != nil { + pitch = min(9, max(pitch, *voice.AveragePitch+2)) + } + if settings.RaisePitchForCapitals { + voice.AveragePitch = &pitch + } + override = settings.UppercaseVoice + if !settings.RaisePitchForCapitals { + override.AveragePitch = nil + } + case "hyperlink": + override = settings.HyperlinkVoice + case "system": + override = settings.SystemVoice + } + mergeVoice(&voice, cloneVoice(override)) + return voice +} diff --git a/internal/config/voices_test.go b/internal/config/voices_test.go new file mode 100644 index 0000000..fc4b3fb --- /dev/null +++ b/internal/config/voices_test.go @@ -0,0 +1,86 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +import ( + "path/filepath" + "reflect" + "testing" +) + +func TestVoiceTypesPersistAndInheritAcrossApplications(t *testing.T) { + settings := DefaultSettings() + rate, pitch, gain := 62.0, 8.0, 4.0 + settings.DefaultVoice = Voice{Rate: &rate, AveragePitch: &pitch, Gain: &gain, Family: &VoiceFamily{Name: "Default person", Lang: "en"}} + upper, link, system := 8.5, 3.0, 2.0 + settings.UppercaseVoice.AveragePitch = &upper + settings.HyperlinkVoice.Rate = &link + settings.SystemVoice.Gain = &system + settings.Reading.IndentationPresentationMode = "both" + store, err := NewStore(filepath.Join(t.TempDir(), "settings.toml")) + if err != nil { + t.Fatal(err) + } + if err := store.Save(settings); err != nil { + t.Fatal(err) + } + loaded, err := store.Load() + if err != nil { + t.Fatal(err) + } + for _, kind := range []string{"uppercase", "hyperlink", "system"} { + if !reflect.DeepEqual(EffectiveVoice(loaded, kind), EffectiveVoice(settings, kind)) { + t.Fatalf("%s did not persist", kind) + } + } + if loaded.Reading.IndentationPresentationMode != "both" { + t.Fatal("indentation mode lost") + } + appSettings := loaded + appPitch := 5.0 + appSettings.UppercaseVoice.AveragePitch = &appPitch + if err := store.SaveForApplication("example-app", appSettings); err != nil { + t.Fatal(err) + } + application, found, err := store.LoadForApplication("example-app") + if err != nil || !found || *EffectiveVoice(application, "uppercase").AveragePitch != 5 { + t.Fatalf("application voice = %+v, %v", application.UppercaseVoice, err) + } + global, err := store.Load() + if err != nil || *EffectiveVoice(global, "uppercase").AveragePitch != 8.5 { + t.Fatal("application voice changed global voice") + } + *store.Current().UppercaseVoice.AveragePitch = 0 + if *store.Current().UppercaseVoice.AveragePitch != 8.5 { + t.Fatal("voice snapshots alias") + } + appSettings.UppercaseVoice = Voice{} + if err := store.SaveForApplication("example-app", appSettings); err != nil { + t.Fatal(err) + } + application, found, err = store.LoadForApplication("example-app") + if err != nil || !found || application.UppercaseVoice.AveragePitch != nil || *EffectiveVoice(application, "uppercase").AveragePitch != 9 { + t.Fatalf("application automatic pitch reset = %+v, %v", application.UppercaseVoice, err) + } +} + +func TestAutomaticUppercasePitchAndExplicitOverride(t *testing.T) { + settings := DefaultSettings() + for _, tc := range []struct{ normal, upper float64 }{{3, 7}, {5, 7}, {7, 9}, {8, 9}, {9, 9}} { + settings.DefaultVoice.AveragePitch = &tc.normal + if got := *EffectiveVoice(settings, "uppercase").AveragePitch; got != tc.upper { + t.Fatalf("normal %g: uppercase %g, want %g", tc.normal, got, tc.upper) + } + } + chosen := 6.0 + settings.UppercaseVoice.AveragePitch = &chosen + if *EffectiveVoice(settings, "uppercase").AveragePitch != chosen { + t.Fatal("explicit uppercase pitch ignored") + } + settings.Reading.IndentationPresentationMode = "invalid" + if Validate(settings) == nil { + t.Fatal("invalid indentation mode accepted") + } +} diff --git a/internal/config/window_titles_test.go b/internal/config/window_titles_test.go new file mode 100644 index 0000000..0b43565 --- /dev/null +++ b/internal/config/window_titles_test.go @@ -0,0 +1,58 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package config + +import ( + "os" + "path/filepath" + "testing" +) + +func TestTitleChangePreferenceDefaultsForExistingSettings(t *testing.T) { + settings, err := Load(filepath.Join("testdata", "settings-v2.toml")) + if err != nil { + t.Fatal(err) + } + if !settings.Reading.AutomaticallyReadTitleChanges { + t.Fatal("omitted title preference defaults off") + } +} + +func TestTitleChangePreferenceRoundTripAndInheritance(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings.toml") + store, err := NewStore(path) + if err != nil { + t.Fatal(err) + } + global := DefaultSettings() + if err = store.Save(global); err != nil { + t.Fatal(err) + } + application := global + application.Reading.AutomaticallyReadTitleChanges = false + if err = store.SaveForApplication("Noisy Application", application); err != nil { + t.Fatal(err) + } + contents, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + _, loaded, err := decodeDocument(contents) + if err != nil || !loaded.Reading.AutomaticallyReadTitleChanges { + t.Fatalf("global = %t, %v", loaded.Reading.AutomaticallyReadTitleChanges, err) + } + restored, found, err := store.LoadForApplication("Noisy Application") + if err != nil || !found || restored.Reading.AutomaticallyReadTitleChanges { + t.Fatalf("override = %t, found %t, %v", restored.Reading.AutomaticallyReadTitleChanges, found, err) + } + global.Reading.AutomaticallyReadTitleChanges = false + if err = store.Save(global); err != nil { + t.Fatal(err) + } + inherited, _, err := store.LoadForApplication("Other Application") + if err != nil || inherited.Reading.AutomaticallyReadTitleChanges { + t.Fatalf("inheritance = %t, %v", inherited.Reading.AutomaticallyReadTitleChanges, err) + } +} diff --git a/internal/datetime/datetime.go b/internal/datetime/datetime.go new file mode 100644 index 0000000..dbbed08 --- /dev/null +++ b/internal/datetime/datetime.go @@ -0,0 +1,154 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package datetime + +/* +#include +#include +#include +*/ +import "C" + +import ( + "time" + "unsafe" +) + +type Option struct { + Value string + Label string +} + +var timeFormats = []struct { + Value string + Spec string +}{ + {"locale", "%X"}, + {"12-hour", "%I:%M %p"}, + {"12-hour-seconds", "%I:%M:%S %p"}, + {"24-hour-seconds", "%H:%M:%S"}, + {"24-hour-seconds-words", "%H hours, %M minutes and %S seconds"}, + {"24-hour", "%H:%M"}, + {"24-hour-words", "%H hours and %M minutes"}, +} + +var dateFormats = []struct { + Value string + Spec string +}{ + {"locale", "%x"}, + {"numbers-dm", "%d/%m"}, + {"numbers-md", "%m/%d"}, + {"numbers-dmy", "%d/%m/%Y"}, + {"numbers-mdy", "%m/%d/%Y"}, + {"numbers-ymd", "%Y/%m/%d"}, + {"full-dm", "%A, %-d %B"}, + {"full-md", "%A, %B %-d"}, + {"full-dmy", "%A, %-d %B, %Y"}, + {"full-mdy", "%A, %B %-d, %Y"}, + {"full-ymd", "%Y. %B %-d, %A"}, + {"abbreviated-dm", "%a, %-d %b"}, + {"abbreviated-md", "%a, %b %-d"}, + {"abbreviated-dmy", "%a, %-d %b, %Y"}, + {"abbreviated-mdy", "%a, %b %-d, %Y"}, + {"abbreviated-ymd", "%Y. %b %-d, %a"}, +} + +func init() { + locale := C.CString("") + defer C.free(unsafe.Pointer(locale)) + C.setlocale(C.LC_TIME, locale) +} + +func TimeOptions(now time.Time) []Option { + return options(timeFormats, now) +} + +func DateOptions(now time.Time) []Option { + return options(dateFormats, now) +} + +func options(formats []struct { + Value string + Spec string +}, now time.Time) []Option { + result := make([]Option, 0, len(formats)) + for _, item := range formats { + result = append(result, Option{Value: item.Value, Label: format(now, item.Spec)}) + } + return result +} + +func FormatTime(value string, now time.Time) (string, bool) { + return formatValue(timeFormats, value, now) +} + +func FormatDate(value string, now time.Time) (string, bool) { + return formatValue(dateFormats, value, now) +} + +func ValidTime(value string) bool { + return valid(timeFormats, value) +} + +func ValidDate(value string) bool { + return valid(dateFormats, value) +} + +func NormalizeDate(value string) string { + switch value { + case "ymd": + return "numbers-ymd" + case "mdy": + return "numbers-mdy" + case "dmy": + return "numbers-dmy" + default: + return value + } +} + +func formatValue(formats []struct { + Value string + Spec string +}, value string, now time.Time) (string, bool) { + for _, item := range formats { + if item.Value == value { + return format(now, item.Spec), true + } + } + return "", false +} + +func valid(formats []struct { + Value string + Spec string +}, value string) bool { + for _, item := range formats { + if item.Value == value { + return true + } + } + return false +} + +func format(now time.Time, spec string) string { + cSpec := C.CString(spec) + defer C.free(unsafe.Pointer(cSpec)) + tm := C.struct_tm{ + tm_year: C.int(now.Year() - 1900), + tm_mon: C.int(int(now.Month()) - 1), + tm_mday: C.int(now.Day()), + tm_hour: C.int(now.Hour()), + tm_min: C.int(now.Minute()), + tm_sec: C.int(now.Second()), + tm_wday: C.int(int(now.Weekday())), + tm_yday: C.int(now.YearDay() - 1), + tm_isdst: -1, + } + buffer := make([]C.char, 512) + length := C.strftime(&buffer[0], C.size_t(len(buffer)), cSpec, &tm) + return C.GoStringN(&buffer[0], C.int(length)) +} diff --git a/internal/input/bindings.go b/internal/input/bindings.go new file mode 100644 index 0000000..26b923f --- /dev/null +++ b/internal/input/bindings.go @@ -0,0 +1,316 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import ( + "fmt" + "sort" + "strconv" + "strings" +) + +// An override replaces all shortcuts for one command in one layout and scope. +// An empty Keys slice disables it; removing the override restores defaults. +type BindingOverride struct { + Layout KeyboardLayout `toml:"layout"` + Scope string `toml:"scope"` + Command Command `toml:"command"` + Keys []string `toml:"keys"` +} + +type BindingRow struct { + Scope string + Command Command + Label string + Keys string + DefaultKeys string +} + +func CloneBindingOverrides(overrides []BindingOverride) []BindingOverride { + if len(overrides) == 0 { + return nil + } + copy := append([]BindingOverride{}, overrides...) + for i := range copy { + copy[i].Keys = append([]string{}, overrides[i].Keys...) + } + return copy +} + +func bindingDefaults(layout KeyboardLayout, scope string) CommandBindings { + global := DefaultCommandBindings(layout) + if scope == "global" { + return global + } + browse := BrowseCommandBindings(layout) + for chord := range global { + delete(browse, chord) + } + return browse +} + +func CommandLabel(command Command) string { + if binding, ok := LookupDocumentList(command); ok { + return "List " + strings.ToLower(binding.Title) + } + switch command { + case PresentCurrentLine: + return "Read the current line" + case PresentWindowTitle: + return "Read the current window title" + case PresentCellFormula: + return "Present the formula for the current cell" + case SetColumnHeadersRow: + return "Use the current row as Calc column headers" + case ClearColumnHeadersRow: + return "Clear Calc column headers" + case SetRowHeadersColumn: + return "Use the current column as Calc row headers" + case ClearRowHeadersColumn: + return "Clear Calc row headers" + case OCRObject: + return "Recognize object of interest" + case OCRWindow: + return "Recognize active window" + case OCRDesktop: + return "Recognize desktop" + case OCRClipboard: + return "Recognize clipboard image" + case OCRRefresh: + return "Refresh OCR result" + } + words := strings.Split(string(command), "-") + if len(words) > 0 && words[0] != "" { + words[0] = strings.ToUpper(words[0][:1]) + words[0][1:] + } + return strings.Join(words, " ") +} + +// ResolveCommandBindings removes replaced defaults before inserting any custom +// chords, allowing swaps while rejecting collisions with unchanged commands. +func ResolveCommandBindings(layout KeyboardLayout, browse bool, overrides []BindingOverride) (CommandBindings, error) { + global := bindingDefaults(layout, "global") + document := bindingDefaults(layout, "browse") + for _, override := range overrides { + if override.Layout != layout { + continue + } + bindings := global + if override.Scope == "browse" { + bindings = document + } + for chord, command := range bindings { + if command == override.Command { + delete(bindings, chord) + } + } + } + for _, override := range overrides { + if override.Layout != layout { + continue + } + bindings := global + if override.Scope == "browse" { + bindings = document + } + for _, key := range override.Keys { + chord, err := ParseCommandChord(key) + if err != nil { + return nil, err + } + if previous := bindings[chord]; previous != "" { + return nil, fmt.Errorf("%s conflicts with %s", key, CommandLabel(previous)) + } + bindings[chord] = override.Command + } + } + for chord, command := range document { + if previous := global[chord]; previous != "" { + return nil, fmt.Errorf("%s conflicts with %s in browse mode", FormatCommandChord(chord), CommandLabel(previous)) + } + if browse { + global[chord] = command + } + } + return global, nil +} + +func ValidateBindingOverrides(overrides []BindingOverride) error { + if len(overrides) > 256 { + return fmt.Errorf("too many key binding overrides") + } + seen := make(map[string]bool) + for _, override := range overrides { + if override.Layout != DesktopKeyboardLayout && override.Layout != LaptopKeyboardLayout { + return fmt.Errorf("invalid binding layout") + } + if override.Scope != "global" && override.Scope != "browse" { + return fmt.Errorf("invalid binding scope") + } + known := false + for _, row := range BindingRows(override.Layout, nil) { + known = known || row.Scope == override.Scope && row.Command == override.Command + } + if !known { + return fmt.Errorf("unknown %s command %q", override.Scope, override.Command) + } + id := fmt.Sprintf("%d/%s/%s", override.Layout, override.Scope, override.Command) + if seen[id] { + return fmt.Errorf("duplicate override for %s", CommandLabel(override.Command)) + } + seen[id] = true + if len(override.Keys) > 8 { + return fmt.Errorf("too many shortcuts for %s", CommandLabel(override.Command)) + } + } + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + if _, err := ResolveCommandBindings(layout, true, overrides); err != nil { + return err + } + } + return nil +} + +func BindingRows(layout KeyboardLayout, overrides []BindingOverride) []BindingRow { + var rows []BindingRow + for _, scope := range []string{"global", "browse"} { + groups := make(map[Command][]string) + for chord, command := range bindingDefaults(layout, scope) { + groups[command] = append(groups[command], FormatCommandChord(chord)) + } + if scope == "browse" { + for _, binding := range DocumentListBindings() { + if _, exists := groups[binding.Command]; !exists { + groups[binding.Command] = nil + } + } + } + if scope == "global" { + for _, command := range []Command{PresentCellFormula, SetColumnHeadersRow, ClearColumnHeadersRow, SetRowHeadersColumn, ClearRowHeadersColumn, PresentDate, StickyFocusMode, StickyBrowseMode, PresentPreviousNotification, PresentNextNotification, OCRObject, OCRWindow, OCRDesktop, OCRClipboard} { + if _, exists := groups[command]; !exists { + groups[command] = nil + } + } + } + for command, keys := range groups { + sort.Strings(keys) + defaults := strings.Join(keys, "; ") + for _, override := range overrides { + if override.Layout == layout && override.Scope == scope && override.Command == command { + keys = override.Keys + break + } + } + rows = append(rows, BindingRow{scope, command, CommandLabel(command), strings.Join(keys, "; "), defaults}) + } + } + sort.Slice(rows, func(i, j int) bool { + if rows[i].Scope != rows[j].Scope { + return rows[i].Scope < rows[j].Scope + } + return rows[i].Label < rows[j].Label + }) + return rows +} + +var namedKeySymbols = map[string]uint32{ + "Space": 0x20, "Tab": 0xff09, "Return": 0xff0d, "Escape": 0xff1b, + "BackSpace": 0xff08, "Delete": 0xffff, "Home": 0xff50, "End": 0xff57, + "Left": 0xff51, "Up": 0xff52, "Right": 0xff53, "Down": 0xff54, + "Page_Up": 0xff55, "Page_Down": 0xff56, "Pause": 0xff13, "Print": 0xff61, + "KP_Enter": 0xff8d, "KP_Home": 0xff95, "KP_Left": 0xff96, "KP_Up": 0xff97, + "KP_Right": 0xff98, "KP_Down": 0xff99, "KP_Page_Up": 0xff9a, "KP_Page_Down": 0xff9b, + "KP_End": 0xff9c, "KP_Begin": 0xff9d, "KP_Delete": 0xff9f, + "KP_Multiply": 0xffaa, "KP_Add": 0xffab, "KP_Separator": 0xffac, + "KP_Subtract": 0xffad, "KP_Decimal": 0xffae, "KP_Divide": 0xffaf, + "semicolon": ';', "plus": '+', +} + +func ParseCommandChord(text string) (CommandChord, error) { + var chord CommandChord + if len(text) > 128 { + return chord, fmt.Errorf("shortcut is too long") + } + parts := strings.Split(strings.TrimSpace(text), "+") + for _, part := range parts[:len(parts)-1] { + switch strings.ToLower(strings.TrimSpace(part)) { + case "cthulhu": + if chord.CthulhuModifier { + return chord, fmt.Errorf("duplicate Cthulhu modifier") + } + chord.CthulhuModifier = true + case "ctrl", "control": + if chord.Modifiers&4 != 0 { + return chord, fmt.Errorf("duplicate Control modifier") + } + chord.Modifiers |= 4 + case "shift": + if chord.Modifiers&1 != 0 { + return chord, fmt.Errorf("duplicate Shift modifier") + } + chord.Modifiers |= 1 + case "alt": + if chord.Modifiers&8 != 0 { + return chord, fmt.Errorf("duplicate Alt modifier") + } + chord.Modifiers |= 8 + case "super": + if chord.Modifiers&64 != 0 { + return chord, fmt.Errorf("duplicate Super modifier") + } + chord.Modifiers |= 64 + default: + return chord, fmt.Errorf("unknown modifier %q", part) + } + } + name := strings.TrimSpace(parts[len(parts)-1]) + for key, symbol := range namedKeySymbols { + if strings.EqualFold(key, name) { + chord.Symbol = symbol + return chord, nil + } + } + if len(name) > 1 && (name[0] == 'F' || name[0] == 'f') { + if number, err := strconv.Atoi(name[1:]); err == nil && number >= 1 && number <= 35 { + chord.Symbol = uint32(0xffbd + number) + return chord, nil + } + } + if len(name) == 1 && name[0] >= 33 && name[0] <= 126 { + chord.Symbol = uint32(strings.ToLower(name)[0]) + return chord, nil + } + return chord, fmt.Errorf("unknown key %q; use a letter, function key, or named key such as Space", name) +} + +func FormatCommandChord(chord CommandChord) string { + var parts []string + if chord.CthulhuModifier { + parts = append(parts, "Cthulhu") + } + for _, modifier := range []struct { + mask uint16 + name string + }{{4, "Ctrl"}, {1, "Shift"}, {8, "Alt"}, {64, "Super"}} { + if chord.Modifiers&modifier.mask != 0 { + parts = append(parts, modifier.name) + } + } + name := "" + for key, symbol := range namedKeySymbols { + if symbol == chord.Symbol { + name = key + break + } + } + if name == "" { + if chord.Symbol >= 0xffbe && chord.Symbol <= 0xffe0 { + name = fmt.Sprintf("F%d", chord.Symbol-0xffbd) + } else { + name = string(rune(chord.Symbol)) + } + } + return strings.Join(append(parts, name), "+") +} diff --git a/internal/input/bindings_test.go b/internal/input/bindings_test.go new file mode 100644 index 0000000..31cef19 --- /dev/null +++ b/internal/input/bindings_test.go @@ -0,0 +1,122 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import ( + "reflect" + "testing" +) + +func TestBindingDefaultsRoundTrip(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for chord := range BrowseCommandBindings(layout) { + parsed, err := ParseCommandChord(FormatCommandChord(chord)) + if err != nil || parsed != chord { + t.Fatalf("%+v round trip: %+v %v", chord, parsed, err) + } + } + got, err := ResolveCommandBindings(layout, true, nil) + if err != nil || !reflect.DeepEqual(got, BrowseCommandBindings(layout)) { + t.Fatalf("default changed: %v", err) + } + } +} + +func TestBindingOverridesScopesLayoutsAndDisable(t *testing.T) { + overrides := []BindingOverride{ + {DesktopKeyboardLayout, "global", Preferences, []string{"Cthulhu+Ctrl+F8", "Alt+F9"}}, + {DesktopKeyboardLayout, "browse", DocumentNextHeading, []string{"F6"}}, + {DesktopKeyboardLayout, "global", Quit, []string{}}, + } + if err := ValidateBindingOverrides(overrides); err != nil { + t.Fatal(err) + } + for _, browse := range []bool{false, true} { + bindings, err := ResolveCommandBindings(DesktopKeyboardLayout, browse, overrides) + if err != nil { + t.Fatal(err) + } + for _, key := range []string{"Cthulhu+Space", "Cthulhu+q"} { + chord, _ := ParseCommandChord(key) + if bindings[chord] != "" { + t.Fatalf("old binding %s remains", key) + } + } + chord, _ := ParseCommandChord("Alt+F9") + if bindings[chord] != Preferences { + t.Fatal("custom global missing") + } + if bindings[CommandChord{Symbol: 'h', CthulhuModifier: true}] != ToggleLearnMode { + t.Fatal("learn mode shortcut lost") + } + chord, _ = ParseCommandChord("F6") + if (bindings[chord] == DocumentNextHeading) != browse || bindings[CommandChord{Symbol: 'h'}] != "" { + t.Fatal("browse scope leaked or old heading remains") + } + } + laptop, _ := ResolveCommandBindings(LaptopKeyboardLayout, false, overrides) + if !reflect.DeepEqual(laptop, DefaultCommandBindings(LaptopKeyboardLayout)) { + t.Fatal("desktop override changed laptop") + } + if !reflect.DeepEqual(CloneBindingOverrides(overrides), overrides) { + t.Fatal("clone changed overrides") + } + clone := CloneBindingOverrides(overrides) + clone[0].Keys[0] = "F1" + if overrides[0].Keys[0] == "F1" { + t.Fatal("clone aliases keys") + } +} + +func TestBindingValidation(t *testing.T) { + for _, overrides := range [][]BindingOverride{ + {{DesktopKeyboardLayout, "global", Preferences, []string{"Cthulhu+q"}}}, + {{DesktopKeyboardLayout, "global", Preferences, []string{"h"}}}, + {{DesktopKeyboardLayout, "browse", DocumentNextHeading, []string{"Cthulhu+q"}}}, + {{DesktopKeyboardLayout, "global", Preferences, []string{"F8", "f8"}}}, + {{DesktopKeyboardLayout, "global", Preferences, []string{"Insert"}}}, + {{DesktopKeyboardLayout, "global", Command("unknown"), []string{"F8"}}}, + {{KeyboardLayout(0), "global", Preferences, []string{"F8"}}}, + {{DesktopKeyboardLayout, "unknown", Preferences, []string{"F8"}}}, + {{DesktopKeyboardLayout, "global", Preferences, nil}, {DesktopKeyboardLayout, "global", Preferences, nil}}, + } { + if err := ValidateBindingOverrides(overrides); err == nil { + t.Fatalf("accepted %+v", overrides) + } + } + for _, key := range []string{"", "Ctrl+", "Ctrl+Ctrl+x", "Cthulhu+Cthulhu+x", "Hyper+x", "F36", "Ctrl+\n"} { + if _, err := ParseCommandChord(key); err == nil { + t.Fatalf("accepted %q", key) + } + } + swaps := []BindingOverride{{DesktopKeyboardLayout, "global", Quit, []string{"Cthulhu+Space"}}, {DesktopKeyboardLayout, "global", Preferences, []string{"Cthulhu+q"}}} + if err := ValidateBindingOverrides(swaps); err != nil { + t.Fatalf("swap: %v", err) + } + unbound := []BindingOverride{{DesktopKeyboardLayout, "global", PresentDate, []string{"F8"}}} + if err := ValidateBindingOverrides(unbound); err != nil { + t.Fatalf("unbound command: %v", err) + } +} + +func TestCustomBindingRouterBalancedReleaseAndMultiPress(t *testing.T) { + overrides := []BindingOverride{{DesktopKeyboardLayout, "global", PresentTime, []string{"Cthulhu+Ctrl+Alt+F8"}}} + bindings, err := ResolveCommandBindings(DesktopKeyboardLayout, true, overrides) + if err != nil { + t.Fatal(err) + } + router := NewCommandRouter([]uint32{0xff63}, bindings) + for _, want := range []Command{PresentTime, PresentDate} { + router.Handle(0xff63, 1, 0, true) + consumed, command := router.Handle(0xffc5, 2, 4|8, true) + if !consumed || command != want { + t.Fatalf("%v %s want %s", consumed, command, want) + } + router.Handle(0xff63, 1, 0, false) + if consumed, command = router.Handle(0xffc5, 2, 4|8, false); !consumed || command != "" { + t.Fatal("custom release unbalanced") + } + } +} diff --git a/internal/input/clipboard_test.go b/internal/input/clipboard_test.go new file mode 100644 index 0000000..e5e7335 --- /dev/null +++ b/internal/input/clipboard_test.go @@ -0,0 +1,43 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "testing" + +func TestClipboardChordConsumesBothReleaseOrders(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, modifierFirst := range []bool{false, true} { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(layout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle('c', 54, 1, true); !consumed || command != PresentClipboard { + t.Fatalf("layout %d: Cthulhu+Shift+C = %v %q", layout, consumed, command) + } + if consumed, command := router.Handle('c', 54, 1, true); !consumed || command != "" { + t.Fatalf("layout %d: repeated C = %v %q", layout, consumed, command) + } + if modifierFirst { + if consumed, command := router.Handle(0xff63, 118, 1, false); !consumed || command != "" { + t.Fatalf("layout %d: modifier release = %v %q", layout, consumed, command) + } + } + if consumed, command := router.Handle('c', 54, 1, false); !consumed || command != "" { + t.Fatalf("layout %d: C release = %v %q", layout, consumed, command) + } + if !modifierFirst { + if consumed, command := router.Handle(0xff63, 118, 0, false); !consumed || command != "" { + t.Fatalf("layout %d: modifier release = %v %q", layout, consumed, command) + } + } + } + } +} + +func TestClipboardChordRequiresShift(t *testing.T) { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(DesktopKeyboardLayout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle('c', 54, 0, true); consumed || command != "" { + t.Fatalf("unshifted C = %v %q", consumed, command) + } +} diff --git a/internal/input/commands.go b/internal/input/commands.go new file mode 100644 index 0000000..72c417e --- /dev/null +++ b/internal/input/commands.go @@ -0,0 +1,479 @@ +package input + +import "time" + +// Command is a semantic request; native callbacks never execute application work. +type Command string + +const ( + SelectPreviousSpeechSetting Command = "select-previous-speech-setting" + SelectNextSpeechSetting Command = "select-next-speech-setting" + DecreaseSpeechSetting Command = "decrease-speech-setting" + IncreaseSpeechSetting Command = "increase-speech-setting" + SaveSpeechSettings Command = "save-speech-settings" + PresentTime Command = "present-time" + PresentDate Command = "present-date" + PresentClipboard Command = "present-clipboard" + PresentCurrentLine Command = "present-current-line" + SpellCurrentLine Command = "spell-current-line" + PhoneticCurrentLine Command = "phonetic-current-line" + ShowSpeechHistory Command = "show-speech-history" + ToggleSpeechMonitor Command = "toggle-speech-monitor" + CycleSpeechMode Command = "cycle-speech-mode" + CycleProgressBarOutput Command = "cycle-progress-bar-output" + PresentVersion Command = "present-version" + ToggleLearnMode Command = "toggle-learn-mode" + ShowActions Command = "show-actions" + InternalUIKey Command = "internal-ui-key" + InternalUIDismiss Command = "internal-ui-dismiss" + LearnKey Command = "learn-key" + LearnDocumentation Command = "learn-documentation" + LearnDefaultShortcuts Command = "learn-default-shortcuts" + LearnApplicationShortcuts Command = "learn-application-shortcuts" + StickyFocusMode Command = "sticky-focus-mode" + StickyBrowseMode Command = "sticky-browse-mode" + ToggleDocumentMode Command = "toggle-document-mode" + DocumentNextHeading Command = "document-next-heading" + DocumentPreviousHeading Command = "document-previous-heading" + DocumentNextLink Command = "document-next-link" + DocumentPreviousLink Command = "document-previous-link" + DocumentNextButton Command = "document-next-button" + DocumentPreviousButton Command = "document-previous-button" + DocumentNextCheckBox Command = "document-next-check-box" + DocumentPreviousCheckBox Command = "document-previous-check-box" + DocumentNextList Command = "document-next-list" + DocumentPreviousList Command = "document-previous-list" + DocumentNextSeparator Command = "document-next-separator" + DocumentPreviousSeparator Command = "document-previous-separator" + DocumentNextHeadingAtLevel1 Command = "document-next-heading-at-level-1" + DocumentPreviousHeadingAtLevel1 Command = "document-previous-heading-at-level-1" + DocumentNextHeadingAtLevel2 Command = "document-next-heading-at-level-2" + DocumentPreviousHeadingAtLevel2 Command = "document-previous-heading-at-level-2" + DocumentNextHeadingAtLevel3 Command = "document-next-heading-at-level-3" + DocumentPreviousHeadingAtLevel3 Command = "document-previous-heading-at-level-3" + DocumentNextHeadingAtLevel4 Command = "document-next-heading-at-level-4" + DocumentPreviousHeadingAtLevel4 Command = "document-previous-heading-at-level-4" + DocumentNextHeadingAtLevel5 Command = "document-next-heading-at-level-5" + DocumentPreviousHeadingAtLevel5 Command = "document-previous-heading-at-level-5" + DocumentNextHeadingAtLevel6 Command = "document-next-heading-at-level-6" + DocumentPreviousHeadingAtLevel6 Command = "document-previous-heading-at-level-6" + DocumentNextBlockQuote Command = "document-next-block-quote" + DocumentPreviousBlockQuote Command = "document-previous-block-quote" + DocumentNextComboBox Command = "document-next-combo-box" + DocumentPreviousComboBox Command = "document-previous-combo-box" + DocumentNextEntry Command = "document-next-entry" + DocumentPreviousEntry Command = "document-previous-entry" + DocumentNextFormField Command = "document-next-form-field" + DocumentPreviousFormField Command = "document-previous-form-field" + DocumentNextImage Command = "document-next-image" + DocumentPreviousImage Command = "document-previous-image" + DocumentNextLandmark Command = "document-next-landmark" + DocumentPreviousLandmark Command = "document-previous-landmark" + DocumentNextListItem Command = "document-next-list-item" + DocumentPreviousListItem Command = "document-previous-list-item" + DocumentNextLiveRegion Command = "document-next-live-region" + DocumentPreviousLiveRegion Command = "document-previous-live-region" + DocumentNextParagraph Command = "document-next-paragraph" + DocumentPreviousParagraph Command = "document-previous-paragraph" + DocumentNextRadioButton Command = "document-next-radio-button" + DocumentPreviousRadioButton Command = "document-previous-radio-button" + DocumentNextTable Command = "document-next-table" + DocumentPreviousTable Command = "document-previous-table" + DocumentNextUnvisitedLink Command = "document-next-unvisited-link" + DocumentPreviousUnvisitedLink Command = "document-previous-unvisited-link" + DocumentNextVisitedLink Command = "document-next-visited-link" + DocumentPreviousVisitedLink Command = "document-previous-visited-link" + DocumentNextClickable Command = "document-next-clickable" + DocumentPreviousClickable Command = "document-previous-clickable" + DocumentNextChunk Command = "document-next-chunk" + DocumentPreviousChunk Command = "document-previous-chunk" + DocumentCaretNextCharacter Command = "document-caret-next-character" + DocumentCaretPreviousCharacter Command = "document-caret-previous-character" + DocumentCaretNextWord Command = "document-caret-next-word" + DocumentCaretPreviousWord Command = "document-caret-previous-word" + DocumentCaretNextLine Command = "document-caret-next-line" + DocumentCaretPreviousLine Command = "document-caret-previous-line" + DocumentCaretLineStart Command = "document-caret-line-start" + DocumentCaretLineEnd Command = "document-caret-line-end" + DocumentCaretDocumentStart Command = "document-caret-document-start" + DocumentCaretDocumentEnd Command = "document-caret-document-end" + DocumentTableLeft Command = "document-table-left" + DocumentTableRight Command = "document-table-right" + DocumentTableUp Command = "document-table-up" + DocumentTableDown Command = "document-table-down" + DocumentTableFirst Command = "document-table-first" + DocumentTableLast Command = "document-table-last" + DocumentActivate Command = "document-activate" + ReadAll Command = "read-all" + DisableTentacles Command = "disable-tentacles" + Quit Command = "quit" + Preferences Command = "preferences" + ApplicationPreferences Command = "application-preferences" + ChooseApplicationPreferences Command = "choose-application-preferences" + PresentCellFormula Command = "present-cell-formula" + SetColumnHeadersRow Command = "set-column-headers-row" + ClearColumnHeadersRow Command = "clear-column-headers-row" + SetRowHeadersColumn Command = "set-row-headers-column" + ClearRowHeadersColumn Command = "clear-row-headers-column" + WhereAmI Command = "where-am-i" + PresentWindowTitle Command = "present-window-title" + PresentCharacterAttributes Command = "present-character-attributes" + PresentLastNotification Command = "present-last-notification" + PresentPreviousNotification Command = "present-previous-notification" + PresentNextNotification Command = "present-next-notification" + ShowNotificationList Command = "show-notification-list" + ObjectParent Command = "object-parent" + ObjectFirstChild Command = "object-first-child" + ObjectPreviousSibling Command = "object-previous-sibling" + ObjectNextSibling Command = "object-next-sibling" + ReviewWindowStart Command = "review-window-start" + ReviewWindowEnd Command = "review-window-end" + ReviewPreviousLine Command = "review-previous-line" + ReviewCurrentLine Command = "review-current-line" + ReviewSpellLine Command = "review-spell-line" + ReviewPhoneticLine Command = "review-phonetic-line" + ReviewNextLine Command = "review-next-line" + ReviewPreviousWord Command = "review-previous-word" + ReviewCurrentWord Command = "review-current-word" + ReviewSpellWord Command = "review-spell-word" + ReviewPhoneticWord Command = "review-phonetic-word" + ReviewNextWord Command = "review-next-word" + ReviewPreviousCharacter Command = "review-previous-character" + ReviewCurrentCharacter Command = "review-current-character" + ReviewPhoneticCharacter Command = "review-phonetic-character" + ReviewNextCharacter Command = "review-next-character" + ReviewWordAbove Command = "review-word-above" + ReviewWordBelow Command = "review-word-below" + ReviewLineEnd Command = "review-line-end" +) + +type KeyboardLayout int + +const ( + DesktopKeyboardLayout KeyboardLayout = 1 + LaptopKeyboardLayout KeyboardLayout = 2 +) + +const ( + returnKeySymbol uint32 = 0xff0d + keypadEnterKeySymbol uint32 = 0xff8d + leftKeySymbol uint32 = 0xff51 + upKeySymbol uint32 = 0xff52 + rightKeySymbol uint32 = 0xff53 + downKeySymbol uint32 = 0xff54 + leftControlKeySymbol uint32 = 0xffe3 + rightControlKeySymbol uint32 = 0xffe4 + leftShiftKeySymbol uint32 = 0xffe1 + rightShiftKeySymbol uint32 = 0xffe2 + controlModifier uint16 = 1 << 2 +) + +type CommandChord struct { + Symbol uint32 + Modifiers uint16 + CthulhuModifier bool +} + +type CommandBindings map[CommandChord]Command + +// CommandEvent retains the initiating X server time across asynchronous delivery. +type CommandEvent struct { + Command Command + Timestamp uint32 + Chord CommandChord + KeyName string + LearnModeStarted bool + UISession uint64 + Text string +} + +type LockState struct { + Name string + Locked bool + Timestamp uint32 +} + +func (state LockState) Text() string { + if state.Locked { + return state.Name + " on" + } + return state.Name + " off" +} + +func DefaultCommandBindings(layout KeyboardLayout) CommandBindings { + bindings := CommandBindings{ + {Symbol: 'a', Modifiers: 1, CthulhuModifier: true}: ShowActions, + {Symbol: leftKeySymbol, CthulhuModifier: true}: SelectPreviousSpeechSetting, + {Symbol: rightKeySymbol, CthulhuModifier: true}: SelectNextSpeechSetting, + {Symbol: downKeySymbol, CthulhuModifier: true}: DecreaseSpeechSetting, + {Symbol: upKeySymbol, CthulhuModifier: true}: IncreaseSpeechSetting, + {Symbol: upKeySymbol, Modifiers: 1, CthulhuModifier: true}: PresentCurrentLine, + {Symbol: 's', Modifiers: controlModifier | 1, CthulhuModifier: true}: SaveSpeechSettings, + {Symbol: 't', CthulhuModifier: true}: PresentTime, + {Symbol: 'c', Modifiers: 1, CthulhuModifier: true}: PresentClipboard, + {Symbol: 'h', Modifiers: controlModifier, CthulhuModifier: true}: ShowSpeechHistory, + {Symbol: 'd', Modifiers: 1, CthulhuModifier: true}: ToggleSpeechMonitor, + {Symbol: 's', CthulhuModifier: true}: CycleSpeechMode, + {Symbol: 'u', CthulhuModifier: true}: CycleProgressBarOutput, + {Symbol: 'v', Modifiers: 1, CthulhuModifier: true}: PresentVersion, + {Symbol: 'a', CthulhuModifier: true}: ToggleDocumentMode, + {Symbol: 'h', CthulhuModifier: true}: ToggleLearnMode, + {Symbol: 0xffbe, CthulhuModifier: true}: ToggleLearnMode, + {Symbol: 'h', Modifiers: 1, CthulhuModifier: true}: DocumentPreviousHeading, + {Symbol: 'k', CthulhuModifier: true, Modifiers: controlModifier}: DocumentNextLink, + {Symbol: 'k', Modifiers: controlModifier | 1, CthulhuModifier: true}: DocumentPreviousLink, + {Symbol: 'q', CthulhuModifier: true}: Quit, + {Symbol: 'q', Modifiers: 5, CthulhuModifier: true}: DisableTentacles, + {Symbol: 'n', CthulhuModifier: true}: PresentLastNotification, + {Symbol: 'n', Modifiers: controlModifier, CthulhuModifier: true}: ShowNotificationList, + {Symbol: ' ', CthulhuModifier: true}: Preferences, + {Symbol: ' ', Modifiers: controlModifier, CthulhuModifier: true}: ApplicationPreferences, + {Symbol: ' ', Modifiers: 1, CthulhuModifier: true}: ApplicationPreferences, + {Symbol: ' ', Modifiers: controlModifier | 1, CthulhuModifier: true}: ChooseApplicationPreferences, + {Symbol: 'f', CthulhuModifier: true}: PresentCharacterAttributes, + {Symbol: upKeySymbol, Modifiers: controlModifier, CthulhuModifier: true}: ObjectParent, + {Symbol: downKeySymbol, Modifiers: controlModifier, CthulhuModifier: true}: ObjectFirstChild, + {Symbol: leftKeySymbol, Modifiers: controlModifier, CthulhuModifier: true}: ObjectPreviousSibling, + {Symbol: rightKeySymbol, Modifiers: controlModifier, CthulhuModifier: true}: ObjectNextSibling, + } + if layout == DesktopKeyboardLayout { + bindings[CommandChord{Symbol: 'o', CthulhuModifier: true}] = OCRWindow + bindings[CommandChord{Symbol: 0xffab}] = ReadAll // KP_Add + bindings[CommandChord{Symbol: keypadEnterKeySymbol}] = WhereAmI + bindings[CommandChord{Symbol: keypadEnterKeySymbol, CthulhuModifier: true}] = PresentWindowTitle + bindings[CommandChord{Symbol: '=', CthulhuModifier: true}] = PresentCellFormula + bindings[CommandChord{Symbol: 0xff95, CthulhuModifier: true}] = ReviewWindowStart + bindings[CommandChord{Symbol: 0xff9a, CthulhuModifier: true}] = ReviewWindowEnd + bindings[CommandChord{Symbol: 0xff96, CthulhuModifier: true}] = ReviewWordAbove + bindings[CommandChord{Symbol: 0xff98, CthulhuModifier: true}] = ReviewWordBelow + bindings[CommandChord{Symbol: 0xff9c, CthulhuModifier: true}] = ReviewLineEnd + } else if layout == LaptopKeyboardLayout { + bindings[CommandChord{Symbol: 'o', Modifiers: 1, CthulhuModifier: true}] = OCRWindow + bindings[CommandChord{Symbol: 'u', Modifiers: 1, CthulhuModifier: true}] = CycleProgressBarOutput + bindings[CommandChord{Symbol: ';', CthulhuModifier: true}] = ReadAll + bindings[CommandChord{Symbol: returnKeySymbol, CthulhuModifier: true}] = WhereAmI + bindings[CommandChord{Symbol: '/', CthulhuModifier: true}] = PresentWindowTitle + bindings[CommandChord{Symbol: 'u', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewWindowStart + bindings[CommandChord{Symbol: 'o', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewWindowEnd + bindings[CommandChord{Symbol: 'j', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewWordAbove + bindings[CommandChord{Symbol: 'l', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewWordBelow + bindings[CommandChord{Symbol: 'm', Modifiers: controlModifier, CthulhuModifier: true}] = ReviewLineEnd + } + for _, binding := range []struct { + desktop, laptop uint32 + command Command + }{ + {0xff95, 'u', ReviewPreviousLine}, {0xff97, 'i', ReviewCurrentLine}, {0xff9a, 'o', ReviewNextLine}, + {0xff96, 'j', ReviewPreviousWord}, {0xff9d, 'k', ReviewCurrentWord}, {0xff98, 'l', ReviewNextWord}, + {0xff9c, 'm', ReviewPreviousCharacter}, {0xff99, ',', ReviewCurrentCharacter}, {0xff9b, '.', ReviewNextCharacter}, + } { + if layout == DesktopKeyboardLayout { + bindings[CommandChord{Symbol: binding.desktop}] = binding.command + } + if layout == LaptopKeyboardLayout { + bindings[CommandChord{Symbol: binding.laptop, CthulhuModifier: true}] = binding.command + } + } + return bindings +} + +// CommandRouter owns the pressed state of screen-reader modifiers and consumed +// command keys. Commands are emitted on press; native owners retain the grab +// independently until the chord releases, including during handler shutdown. +type CommandRouter struct { + now func() time.Time + lastTimePress time.Time + lastModePress time.Time + modePresses int + lastReviewPress time.Time + lastReviewChord CommandChord + reviewPresses int + modifiers map[uint32]bool + bindings CommandBindings + down map[uint16]bool + consumed map[uint16]bool +} + +func NewCommandRouter(modifiers []uint32, bindings CommandBindings) *CommandRouter { + router := &CommandRouter{ + now: time.Now, + modifiers: make(map[uint32]bool), + bindings: make(CommandBindings, len(bindings)), + down: make(map[uint16]bool), + consumed: make(map[uint16]bool), + } + for _, symbol := range modifiers { + router.modifiers[symbol] = true + } + for chord, command := range bindings { + router.bindings[chord] = command + } + return router +} + +func (router *CommandRouter) Handle(symbol uint32, code uint16, modifiers uint16, pressed bool) (bool, Command) { + consume := false + if !pressed { + consume = router.down[code] || router.consumed[code] + delete(router.down, code) + delete(router.consumed, code) + } else if router.modifiers[symbol] { + router.down[code] = true + consume = true + } else if router.consumed[code] { + consume = true + } else { + chord := CommandChord{ + Symbol: symbol, + Modifiers: modifiers &^ uint16(2|16), + CthulhuModifier: len(router.down) != 0, + } + if command := router.bindings[chord]; command != "" { + router.consumed[code] = true + command = router.review_press(command, chord) + if command == ToggleDocumentMode { + now := router.now() + if !router.lastModePress.IsZero() && now.Sub(router.lastModePress) >= 0 && now.Sub(router.lastModePress) <= 500*time.Millisecond { + router.modePresses++ + } else { + router.modePresses = 1 + } + router.lastModePress = now + switch router.modePresses { + case 2: + command = StickyFocusMode + case 3: + command = StickyBrowseMode + router.lastModePress = time.Time{} + } + } else { + router.lastModePress = time.Time{} + } + if command == PresentTime { + now := router.now() + if !router.lastTimePress.IsZero() && now.Sub(router.lastTimePress) >= 0 && now.Sub(router.lastTimePress) <= 500*time.Millisecond { + command = PresentDate + router.lastTimePress = time.Time{} + } else { + router.lastTimePress = now + } + } else { + router.lastTimePress = time.Time{} + } + return true, command + } + router.lastTimePress = time.Time{} + router.lastModePress = time.Time{} + router.lastReviewPress = time.Time{} + } + return consume, "" +} + +func (router *CommandRouter) IsModifier(symbol uint32) bool { + switch symbol { + case leftControlKeySymbol, rightControlKeySymbol, leftShiftKeySymbol, rightShiftKeySymbol, + 0xffe7, 0xffe8, 0xffe9, 0xffea, 0xffeb, 0xffec, 0xffed, 0xffee: // Meta, Alt, Super, Hyper. + return true + } + return router.modifiers[symbol] +} + +// Chord reports the keys currently held before handling the next press. +func (router *CommandRouter) Chord(symbol uint32, modifiers uint16) CommandChord { + return CommandChord{Symbol: symbol, Modifiers: modifiers &^ uint16(2|16), CthulhuModifier: len(router.down) != 0} +} + +func (router *CommandRouter) Reset() { + clear(router.down) + clear(router.consumed) +} + +// Browse bindings are installed only while the runtime owns live web content. +func BrowseCommandBindings(layout KeyboardLayout) CommandBindings { + bindings := DefaultCommandBindings(layout) + caretBindings := CommandBindings{ + {Symbol: leftKeySymbol, Modifiers: 1 | 8}: DocumentTableLeft, + {Symbol: rightKeySymbol, Modifiers: 1 | 8}: DocumentTableRight, + {Symbol: upKeySymbol, Modifiers: 1 | 8}: DocumentTableUp, + {Symbol: downKeySymbol, Modifiers: 1 | 8}: DocumentTableDown, + {Symbol: 0xff50, Modifiers: 1 | 8}: DocumentTableFirst, + {Symbol: 0xff57, Modifiers: 1 | 8}: DocumentTableLast, + {Symbol: rightKeySymbol}: DocumentCaretNextCharacter, + {Symbol: leftKeySymbol}: DocumentCaretPreviousCharacter, + {Symbol: rightKeySymbol, Modifiers: controlModifier}: DocumentCaretNextWord, + {Symbol: leftKeySymbol, Modifiers: controlModifier}: DocumentCaretPreviousWord, + {Symbol: downKeySymbol}: DocumentCaretNextLine, + {Symbol: upKeySymbol}: DocumentCaretPreviousLine, + {Symbol: 0xff50}: DocumentCaretLineStart, + {Symbol: 0xff57}: DocumentCaretLineEnd, + {Symbol: 0xff50, Modifiers: controlModifier}: DocumentCaretDocumentStart, + {Symbol: 0xff57, Modifiers: controlModifier}: DocumentCaretDocumentEnd, + {Symbol: returnKeySymbol}: DocumentActivate, + } + for chord, command := range caretBindings { + bindings[chord] = command + } + documentBindings := []struct { + symbol uint32 + next Command + previous Command + }{ + {'h', DocumentNextHeading, DocumentPreviousHeading}, + {'k', DocumentNextLink, DocumentPreviousLink}, + {'b', DocumentNextButton, DocumentPreviousButton}, + {'x', DocumentNextCheckBox, DocumentPreviousCheckBox}, + {'l', DocumentNextList, DocumentPreviousList}, + {'s', DocumentNextSeparator, DocumentPreviousSeparator}, + {'q', DocumentNextBlockQuote, DocumentPreviousBlockQuote}, + {'c', DocumentNextComboBox, DocumentPreviousComboBox}, + {'e', DocumentNextEntry, DocumentPreviousEntry}, + {'f', DocumentNextFormField, DocumentPreviousFormField}, + {'g', DocumentNextImage, DocumentPreviousImage}, + {'m', DocumentNextLandmark, DocumentPreviousLandmark}, + {'i', DocumentNextListItem, DocumentPreviousListItem}, + {'d', DocumentNextLiveRegion, DocumentPreviousLiveRegion}, + {'p', DocumentNextParagraph, DocumentPreviousParagraph}, + {'r', DocumentNextRadioButton, DocumentPreviousRadioButton}, + {'t', DocumentNextTable, DocumentPreviousTable}, + {'u', DocumentNextUnvisitedLink, DocumentPreviousUnvisitedLink}, + {'v', DocumentNextVisitedLink, DocumentPreviousVisitedLink}, + {'a', DocumentNextClickable, DocumentPreviousClickable}, + {'o', DocumentNextChunk, DocumentPreviousChunk}, + } + for _, binding := range documentBindings { + bindings[CommandChord{Symbol: binding.symbol}] = binding.next + bindings[CommandChord{Symbol: binding.symbol, Modifiers: 1}] = binding.previous + } + for _, binding := range DocumentListBindings() { + if binding.Symbol != 0 { + bindings[CommandChord{Symbol: binding.Symbol, Modifiers: 1 | 8}] = binding.Command + } + } + headingLevels := []struct { + level int + next Command + previous Command + }{ + {1, DocumentNextHeadingAtLevel1, DocumentPreviousHeadingAtLevel1}, + {2, DocumentNextHeadingAtLevel2, DocumentPreviousHeadingAtLevel2}, + {3, DocumentNextHeadingAtLevel3, DocumentPreviousHeadingAtLevel3}, + {4, DocumentNextHeadingAtLevel4, DocumentPreviousHeadingAtLevel4}, + {5, DocumentNextHeadingAtLevel5, DocumentPreviousHeadingAtLevel5}, + {6, DocumentNextHeadingAtLevel6, DocumentPreviousHeadingAtLevel6}, + } + for _, binding := range headingLevels { + symbol := uint32('0' + binding.level) + bindings[CommandChord{Symbol: symbol}] = binding.next + bindings[CommandChord{Symbol: symbol, Modifiers: 1}] = binding.previous + } + return bindings +} + +// ReplaceBindings preserves multi-press timing across browse grab changes. +// Native owners call this only after every consumed key has been released. +func (router *CommandRouter) ReplaceBindings(bindings CommandBindings) { + router.bindings = make(CommandBindings, len(bindings)) + for chord, command := range bindings { + router.bindings[chord] = command + } +} diff --git a/internal/input/commands_test.go b/internal/input/commands_test.go new file mode 100644 index 0000000..936e8e0 --- /dev/null +++ b/internal/input/commands_test.go @@ -0,0 +1,344 @@ +package input + +import "testing" + +func TestQuitConsumesBalancedChord(t *testing.T) { + for _, modifierFirst := range []bool{false, true} { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(DesktopKeyboardLayout)) + check := func(symbol uint32, code uint16, pressed, consume bool, command Command) { + t.Helper() + gotConsume, gotCommand := router.Handle(symbol, code, 0, pressed) + if gotConsume != consume || gotCommand != command { + t.Fatalf("got %v %q, want %v %q", gotConsume, gotCommand, consume, command) + } + } + check('q', 24, true, false, "") + check('q', 24, false, false, "") + check(0xff63, 118, true, true, "") + check('q', 24, true, true, Quit) + check('q', 24, true, true, "") // auto-repeat + if modifierFirst { + check(0xff63, 118, false, true, "") + check('q', 24, false, true, "") + } else { + check('q', 24, false, true, "") + check(0xff63, 118, false, true, "") + } + check('q', 24, true, false, "") + } +} + +func TestUnknownChordPassesThrough(t *testing.T) { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(DesktopKeyboardLayout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle('x', 53, 0, true); consumed || command != "" { + t.Fatal("unknown command consumed") + } + router.Reset() + if consumed, command := router.Handle('x', 53, 0, false); consumed || command != "" { + t.Fatal("unknown command release consumed after pass-through reset") + } + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle('q', 24, 4, true); consumed || command != "" { + t.Fatal("Control+Insert+q became quit") + } + router.Reset() + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle('q', 24, 2|16, true); !consumed || command != Quit { + t.Fatal("lock keys prevented quit chord") + } +} + +func TestBindingTableRoutesPreferencesOnPress(t *testing.T) { + bindings := DefaultCommandBindings(DesktopKeyboardLayout) + router := NewCommandRouter([]uint32{0xff63, 0xff9e}, bindings) + bindings[CommandChord{Symbol: ' ', CthulhuModifier: true}] = Quit + + if consumed, command := router.Handle(0xff9e, 90, 0, true); !consumed || command != "" { + t.Fatalf("modifier press = %v %q", consumed, command) + } + if consumed, command := router.Handle(' ', 65, 0, true); !consumed || command != Preferences { + t.Fatalf("space press = %v %q", consumed, command) + } + if consumed, command := router.Handle(0xff9e, 90, 0, false); !consumed || command != "" { + t.Fatalf("modifier release = %v %q", consumed, command) + } + if consumed, command := router.Handle(' ', 65, 0, false); !consumed || command != "" { + t.Fatalf("space release = %v %q, want no command", consumed, command) + } +} + +func TestApplicationPreferencesShortcut(t *testing.T) { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(DesktopKeyboardLayout)) + if consumed, command := router.Handle(0xff63, 90, 0, true); !consumed || command != "" { + t.Fatalf("modifier press = %v %q", consumed, command) + } + if consumed, command := router.Handle(' ', 65, controlModifier, true); !consumed || command != ApplicationPreferences { + t.Fatalf("Cthulhu+Ctrl+Space = %v %q", consumed, command) + } + if consumed, command := router.Handle(' ', 65, controlModifier, false); !consumed || command != "" { + t.Fatalf("shortcut release = %v %q", consumed, command) + } +} + +func TestApplicationPreferenceShiftShortcutsInBothLayouts(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, tc := range []struct { + modifiers uint16 + want Command + }{ + {1, ApplicationPreferences}, {controlModifier | 1, ChooseApplicationPreferences}, + } { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(layout)) + router.Handle(0xff63, 90, 0, true) + if consumed, command := router.Handle(' ', 65, tc.modifiers, true); !consumed || command != tc.want { + t.Fatalf("layout %v shortcut = %v %q, want %q", layout, consumed, command, tc.want) + } + if consumed, command := router.Handle(' ', 65, tc.modifiers, false); !consumed || command != "" { + t.Fatalf("shortcut release = %v %q", consumed, command) + } + } + } +} + +func TestLaptopBindingRoutesWhereAmI(t *testing.T) { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(LaptopKeyboardLayout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle(returnKeySymbol, 36, 0, true); !consumed || command != WhereAmI { + t.Fatalf("Return press = %v %q", consumed, command) + } + if consumed, command := router.Handle(returnKeySymbol, 36, 0, false); !consumed || command != "" { + t.Fatalf("Return release = %v %q", consumed, command) + } + if consumed, command := router.Handle(0xff63, 118, 0, false); !consumed || command != "" { + t.Fatalf("modifier release = %v %q, want no command", consumed, command) + } +} + +func TestCellFormulaBindingAndLaptopOverride(t *testing.T) { + chord := CommandChord{Symbol: '=', CthulhuModifier: true} + if got := DefaultCommandBindings(DesktopKeyboardLayout)[chord]; got != PresentCellFormula { + t.Fatalf("desktop formula binding = %q", got) + } + if got := DefaultCommandBindings(LaptopKeyboardLayout)[chord]; got != "" { + t.Fatalf("laptop formula should be unbound by default: %q", got) + } + overrides := []BindingOverride{{Layout: LaptopKeyboardLayout, Scope: "global", + Command: PresentCellFormula, Keys: []string{"Cthulhu+="}}} + if err := ValidateBindingOverrides(overrides); err != nil { + t.Fatal(err) + } + bindings, err := ResolveCommandBindings(LaptopKeyboardLayout, false, overrides) + if err != nil || bindings[chord] != PresentCellFormula { + t.Fatalf("laptop formula override = %q, %v", bindings[chord], err) + } +} + +func TestCalcHeaderCommandsCanBeBoundInBothLayouts(t *testing.T) { + commands := []Command{SetColumnHeadersRow, ClearColumnHeadersRow, SetRowHeadersColumn, ClearRowHeadersColumn} + keys := []string{"Cthulhu+Ctrl+Shift+r", "Cthulhu+Ctrl+Alt+r", "Cthulhu+Ctrl+Shift+c", "Cthulhu+Ctrl+Alt+c"} + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + var overrides []BindingOverride + for index, command := range commands { + overrides = append(overrides, BindingOverride{Layout: layout, Scope: "global", Command: command, Keys: []string{keys[index]}}) + } + if err := ValidateBindingOverrides(overrides); err != nil { + t.Fatal(err) + } + bindings, err := ResolveCommandBindings(layout, false, overrides) + if err != nil { + t.Fatal(err) + } + for index, command := range commands { + chord, _ := ParseCommandChord(keys[index]) + if bindings[chord] != command { + t.Fatalf("layout %v: %s did not bind", layout, command) + } + } + if got := bindings[CommandChord{Symbol: 'c', Modifiers: 1, CthulhuModifier: true}]; got != PresentClipboard { + t.Fatalf("header commands displaced clipboard: %s", got) + } + } +} + +func TestCharacterAttributesShortcutInBothLayouts(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + bindings := DefaultCommandBindings(layout) + if got := bindings[CommandChord{Symbol: 'f', CthulhuModifier: true}]; got != PresentCharacterAttributes { + t.Fatalf("layout %v Cthulhu+F = %q", layout, got) + } + } +} + +func TestBrowseReturnActivatesWithoutChangingDefaultReturn(t *testing.T) { + for name, bindings := range map[string]CommandBindings{ + "default": DefaultCommandBindings(DesktopKeyboardLayout), + "browse": BrowseCommandBindings(DesktopKeyboardLayout), + } { + router := NewCommandRouter([]uint32{0xff63}, bindings) + consumed, command := router.Handle(returnKeySymbol, 36, 0, true) + if name == "browse" && (!consumed || command != DocumentActivate) { + t.Fatalf("browse Return = %v %q", consumed, command) + } + if name == "default" && (consumed || command != "") { + t.Fatalf("default Return = %v %q", consumed, command) + } + } +} + +func TestDesktopBindingRoutesWhereAmIWithoutModifier(t *testing.T) { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(DesktopKeyboardLayout)) + if consumed, command := router.Handle(keypadEnterKeySymbol, 104, 0, true); !consumed || command != WhereAmI { + t.Fatalf("KP Enter press = %v %q", consumed, command) + } + if consumed, command := router.Handle(keypadEnterKeySymbol, 104, 0, false); !consumed || command != "" { + t.Fatalf("KP Enter release = %v %q, want no command", consumed, command) + } +} + +func TestWhereAmIBindingsAreLayoutSpecific(t *testing.T) { + desktop := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(DesktopKeyboardLayout)) + desktop.Handle(0xff63, 118, 0, true) + if consumed, command := desktop.Handle(returnKeySymbol, 36, 0, true); consumed || command != "" { + t.Fatalf("desktop Cthulhu+Return = %v %q, want unbound", consumed, command) + } + + laptop := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(LaptopKeyboardLayout)) + if consumed, command := laptop.Handle(keypadEnterKeySymbol, 104, 0, true); consumed || command != "" { + t.Fatalf("laptop KP Enter = %v %q, want unbound", consumed, command) + } +} + +func TestObjectNavigationBindingsMatchPython(t *testing.T) { + tests := []struct { + symbol uint32 + command Command + }{ + {upKeySymbol, ObjectParent}, + {downKeySymbol, ObjectFirstChild}, + {leftKeySymbol, ObjectPreviousSibling}, + {rightKeySymbol, ObjectNextSibling}, + } + for _, test := range tests { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(DesktopKeyboardLayout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle(test.symbol, 111, controlModifier, true); !consumed || command != test.command { + t.Fatalf("symbol %#x press = %v %q", test.symbol, consumed, command) + } + if consumed, command := router.Handle(test.symbol, 111, controlModifier, false); !consumed || command != "" { + t.Fatalf("symbol %#x release = %v %q", test.symbol, consumed, command) + } + if consumed, command := router.Handle(0xff63, 118, controlModifier, false); !consumed || command != "" { + t.Fatalf("symbol %#x modifier release = %v %q, want %q", test.symbol, consumed, command, Command("")) + } + } +} + +func TestObjectNavigationRequiresControl(t *testing.T) { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(DesktopKeyboardLayout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle(upKeySymbol, 111, 0, true); !consumed || command != IncreaseSpeechSetting { + t.Fatalf("Cthulhu+Up = %v %q, want speech adjustment", consumed, command) + } +} + +func TestControlPressDoesNotMakeObjectNavigationPassThrough(t *testing.T) { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(DesktopKeyboardLayout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle(leftControlKeySymbol, 37, 0, true); consumed || command != "" { + t.Fatalf("Control press = %v %q", consumed, command) + } + if !router.IsModifier(leftControlKeySymbol) || !router.IsModifier(rightControlKeySymbol) { + t.Fatal("Control key was not classified as a chord modifier") + } + if consumed, command := router.Handle(upKeySymbol, 111, controlModifier, true); !consumed || command != ObjectParent { + t.Fatalf("Up press = %v %q", consumed, command) + } +} + +func TestBindingTableMatchesExactAdditionalModifiers(t *testing.T) { + bindings := CommandBindings{{Symbol: 'x', Modifiers: 4, CthulhuModifier: true}: Preferences} + router := NewCommandRouter([]uint32{0xff63}, bindings) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle('x', 53, 0, true); consumed || command != "" { + t.Fatal("binding matched without its Control modifier") + } + router.Reset() + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle('x', 53, 4, true); !consumed || command != Preferences { + t.Fatal("binding did not match its Control modifier") + } +} + +func TestBrowseCommandsPreserveShiftAndReleaseOrder(t *testing.T) { + for _, tc := range []struct { + symbol uint32 + mods uint16 + want Command + }{ + {'h', 0, DocumentNextHeading}, {'h', 1, DocumentPreviousHeading}, + {'k', 0, DocumentNextLink}, {'k', 1, DocumentPreviousLink}, + {'b', 0, DocumentNextButton}, {'b', 1, DocumentPreviousButton}, + {'x', 0, DocumentNextCheckBox}, {'x', 1, DocumentPreviousCheckBox}, + {'l', 0, DocumentNextList}, {'l', 1, DocumentPreviousList}, + {'s', 0, DocumentNextSeparator}, {'s', 1, DocumentPreviousSeparator}, + {'q', 0, DocumentNextBlockQuote}, {'q', 1, DocumentPreviousBlockQuote}, + {'c', 0, DocumentNextComboBox}, {'c', 1, DocumentPreviousComboBox}, + {'e', 0, DocumentNextEntry}, {'e', 1, DocumentPreviousEntry}, + {'f', 0, DocumentNextFormField}, {'f', 1, DocumentPreviousFormField}, + {'g', 0, DocumentNextImage}, {'g', 1, DocumentPreviousImage}, + {'m', 0, DocumentNextLandmark}, {'m', 1, DocumentPreviousLandmark}, + {'i', 0, DocumentNextListItem}, {'i', 1, DocumentPreviousListItem}, + {'d', 0, DocumentNextLiveRegion}, {'d', 1, DocumentPreviousLiveRegion}, + {'p', 0, DocumentNextParagraph}, {'p', 1, DocumentPreviousParagraph}, + {'r', 0, DocumentNextRadioButton}, {'r', 1, DocumentPreviousRadioButton}, + {'t', 0, DocumentNextTable}, {'t', 1, DocumentPreviousTable}, + {'u', 0, DocumentNextUnvisitedLink}, {'u', 1, DocumentPreviousUnvisitedLink}, + {'v', 0, DocumentNextVisitedLink}, {'v', 1, DocumentPreviousVisitedLink}, + {'a', 0, DocumentNextClickable}, {'a', 1, DocumentPreviousClickable}, + {'o', 0, DocumentNextChunk}, {'o', 1, DocumentPreviousChunk}, + {'1', 0, DocumentNextHeadingAtLevel1}, {'1', 1, DocumentPreviousHeadingAtLevel1}, + {'2', 0, DocumentNextHeadingAtLevel2}, {'2', 1, DocumentPreviousHeadingAtLevel2}, + {'3', 0, DocumentNextHeadingAtLevel3}, {'3', 1, DocumentPreviousHeadingAtLevel3}, + {'4', 0, DocumentNextHeadingAtLevel4}, {'4', 1, DocumentPreviousHeadingAtLevel4}, + {'5', 0, DocumentNextHeadingAtLevel5}, {'5', 1, DocumentPreviousHeadingAtLevel5}, + {'6', 0, DocumentNextHeadingAtLevel6}, {'6', 1, DocumentPreviousHeadingAtLevel6}, + {'h', 4, ""}, {'k', 8, ""}, + } { + router := NewCommandRouter([]uint32{0xff63}, BrowseCommandBindings(DesktopKeyboardLayout)) + consumed, command := router.Handle(tc.symbol, 43, tc.mods, true) + if consumed != (tc.want != "") || command != tc.want { + t.Fatalf("press: %v %s", consumed, command) + } + consumed, command = router.Handle(tc.symbol, 43, tc.mods, false) + if consumed != (tc.want != "") || command != "" { + t.Fatalf("release: %v %s want %s", consumed, command, Command("")) + } + } +} + +func TestSpeechSettingBindings(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, bindings := range []CommandBindings{DefaultCommandBindings(layout), BrowseCommandBindings(layout)} { + for _, test := range []struct { + symbol uint32 + modifiers uint16 + command Command + }{ + {leftKeySymbol, 0, SelectPreviousSpeechSetting}, {rightKeySymbol, 0, SelectNextSpeechSetting}, + {upKeySymbol, 0, IncreaseSpeechSetting}, {downKeySymbol, 0, DecreaseSpeechSetting}, + {'s', controlModifier | 1, SaveSpeechSettings}, + } { + router := NewCommandRouter([]uint32{0xff63}, bindings) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle(test.symbol, 111, test.modifiers, true); !consumed || command != test.command { + t.Fatalf("press: %v %q", consumed, command) + } + router.Handle(0xff63, 118, 0, false) + if consumed, command := router.Handle(test.symbol, 111, test.modifiers, false); !consumed || command != "" { + t.Fatalf("release: %v %q", consumed, command) + } + } + } + } +} diff --git a/internal/input/current_line_test.go b/internal/input/current_line_test.go new file mode 100644 index 0000000..259ea65 --- /dev/null +++ b/internal/input/current_line_test.go @@ -0,0 +1,35 @@ +package input + +import ( + "testing" + "time" +) + +func TestCurrentLineBindingAndPresses(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, bindings := range []CommandBindings{DefaultCommandBindings(layout), BrowseCommandBindings(layout)} { + router := NewCommandRouter([]uint32{0xff63}, bindings) + now := time.Unix(100, 0) + router.now = func() time.Time { return now } + router.Handle(0xff63, 118, 0, true) + press := func(modifiers uint16, want Command) { + t.Helper() + if consumed, got := router.Handle(upKeySymbol, 111, modifiers, true); !consumed || got != want { + t.Fatalf("layout %d: consumed=%v command=%s want=%s", layout, consumed, got, want) + } + if consumed, got := router.Handle(upKeySymbol, 111, modifiers, true); !consumed || got != "" { + t.Fatal("held arrow repeated command") + } + router.Handle(upKeySymbol, 111, modifiers, false) + } + press(1, PresentCurrentLine) + press(1, SpellCurrentLine) + press(1, PhoneticCurrentLine) + press(1, PresentCurrentLine) + now = now.Add(501 * time.Millisecond) + press(1, PresentCurrentLine) + press(0, IncreaseSpeechSetting) + press(1, PresentCurrentLine) + } + } +} diff --git a/internal/input/date_time_test.go b/internal/input/date_time_test.go new file mode 100644 index 0000000..0e23919 --- /dev/null +++ b/internal/input/date_time_test.go @@ -0,0 +1,47 @@ +package input + +import ( + "testing" + "time" +) + +func TestTimeDatePresses(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, modifierFirst := range []bool{false, true} { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(layout)) + now := time.Unix(100, 0) + router.now = func() time.Time { return now } + press := func(want Command) { + t.Helper() + router.Handle(0xff63, 118, 0, true) + if consumed, got := router.Handle('t', 28, 0, true); !consumed || got != want { + t.Fatalf("press = %v %s; want %s", consumed, got, want) + } + if consumed, got := router.Handle('t', 28, 0, true); !consumed || got != "" { + t.Fatal("held key repeated command") + } + codes := []uint16{28, 118} + if modifierFirst { + codes = []uint16{118, 28} + } + for _, code := range codes { + if consumed, got := router.Handle(0, code, 0, false); !consumed || got != "" { + t.Fatal("unbalanced release") + } + } + router.Reset() // Native owner finishes each fully released chord. + } + press(PresentTime) + now = now.Add(500 * time.Millisecond) + press(PresentDate) + press(PresentTime) + now = now.Add(501 * time.Millisecond) + press(PresentTime) + router.Handle(0xff63, 118, 0, true) + router.Handle('x', 53, 0, true) + router.Handle('x', 53, 0, false) + router.Handle(0xff63, 118, 0, false) + press(PresentTime) + } + } +} diff --git a/internal/input/document_lists.go b/internal/input/document_lists.go new file mode 100644 index 0000000..1d2490b --- /dev/null +++ b/internal/input/document_lists.go @@ -0,0 +1,88 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +const ( + DocumentListBlockQuotes Command = "document-list-block-quotes" + DocumentListButtons Command = "document-list-buttons" + DocumentListCheckBoxes Command = "document-list-check-boxes" + DocumentListComboBoxes Command = "document-list-combo-boxes" + DocumentListEntries Command = "document-list-entries" + DocumentListFormFields Command = "document-list-form-fields" + DocumentListHeadings Command = "document-list-headings" + DocumentListImages Command = "document-list-images" + DocumentListLandmarks Command = "document-list-landmarks" + DocumentListLists Command = "document-list-lists" + DocumentListListItems Command = "document-list-list-items" + DocumentListParagraphs Command = "document-list-paragraphs" + DocumentListRadioButtons Command = "document-list-radio-buttons" + DocumentListTables Command = "document-list-tables" + DocumentListLinks Command = "document-list-links" + DocumentListUnvisitedLinks Command = "document-list-unvisited-links" + DocumentListVisitedLinks Command = "document-list-visited-links" + DocumentListLargeObjects Command = "document-list-large-objects" + DocumentListClickables Command = "document-list-clickables" + DocumentListHeadingsAtLevel1 Command = "document-list-headings-at-level-1" + DocumentListHeadingsAtLevel2 Command = "document-list-headings-at-level-2" + DocumentListHeadingsAtLevel3 Command = "document-list-headings-at-level-3" + DocumentListHeadingsAtLevel4 Command = "document-list-headings-at-level-4" + DocumentListHeadingsAtLevel5 Command = "document-list-headings-at-level-5" + DocumentListHeadingsAtLevel6 Command = "document-list-headings-at-level-6" + DocumentListAnnotations Command = "document-list-annotations" + DocumentListInternalFrames Command = "document-list-internal-frames" + DocumentListMath Command = "document-list-math" +) + +// DocumentListBinding describes browser lists independently of presentation. +// Unbound commands remain available in the shortcut editor, as in Orca. +type DocumentListBinding struct { + Command Command + Symbol uint32 + Title string + Next Command + Level int +} + +func DocumentListBindings() []DocumentListBinding { + return []DocumentListBinding{ + {Command: DocumentListBlockQuotes, Symbol: 'q', Title: "Block quotes", Next: DocumentNextBlockQuote}, + {Command: DocumentListButtons, Symbol: 'b', Title: "Buttons", Next: DocumentNextButton}, + {Command: DocumentListCheckBoxes, Symbol: 'x', Title: "Check boxes", Next: DocumentNextCheckBox}, + {Command: DocumentListComboBoxes, Symbol: 'c', Title: "Combo boxes", Next: DocumentNextComboBox}, + {Command: DocumentListEntries, Symbol: 'e', Title: "Text entries", Next: DocumentNextEntry}, + {Command: DocumentListFormFields, Symbol: 'f', Title: "Form fields", Next: DocumentNextFormField}, + {Command: DocumentListHeadings, Symbol: 'h', Title: "Headings", Next: DocumentNextHeading}, + {Command: DocumentListImages, Symbol: 'g', Title: "Images", Next: DocumentNextImage}, + {Command: DocumentListLandmarks, Symbol: 'm', Title: "Landmarks", Next: DocumentNextLandmark}, + {Command: DocumentListLists, Symbol: 'l', Title: "Lists", Next: DocumentNextList}, + {Command: DocumentListListItems, Symbol: 'i', Title: "List items", Next: DocumentNextListItem}, + {Command: DocumentListParagraphs, Symbol: 'p', Title: "Paragraphs", Next: DocumentNextParagraph}, + {Command: DocumentListRadioButtons, Symbol: 'r', Title: "Radio buttons", Next: DocumentNextRadioButton}, + {Command: DocumentListTables, Symbol: 't', Title: "Tables", Next: DocumentNextTable}, + {Command: DocumentListLinks, Symbol: 'k', Title: "Links", Next: DocumentNextLink}, + {Command: DocumentListUnvisitedLinks, Symbol: 'u', Title: "Unvisited links", Next: DocumentNextUnvisitedLink}, + {Command: DocumentListVisitedLinks, Symbol: 'v', Title: "Visited links", Next: DocumentNextVisitedLink}, + {Command: DocumentListLargeObjects, Symbol: 'o', Title: "Large objects", Next: DocumentNextChunk}, + {Command: DocumentListClickables, Symbol: 'a', Title: "Clickables", Next: DocumentNextClickable}, + {Command: DocumentListHeadingsAtLevel1, Symbol: '1', Title: "Headings at level 1", Next: DocumentNextHeading, Level: 1}, + {Command: DocumentListHeadingsAtLevel2, Symbol: '2', Title: "Headings at level 2", Next: DocumentNextHeading, Level: 2}, + {Command: DocumentListHeadingsAtLevel3, Symbol: '3', Title: "Headings at level 3", Next: DocumentNextHeading, Level: 3}, + {Command: DocumentListHeadingsAtLevel4, Symbol: '4', Title: "Headings at level 4", Next: DocumentNextHeading, Level: 4}, + {Command: DocumentListHeadingsAtLevel5, Symbol: '5', Title: "Headings at level 5", Next: DocumentNextHeading, Level: 5}, + {Command: DocumentListHeadingsAtLevel6, Symbol: '6', Title: "Headings at level 6", Next: DocumentNextHeading, Level: 6}, + {Command: DocumentListAnnotations, Title: "Annotations"}, + {Command: DocumentListInternalFrames, Title: "Internal frames"}, + {Command: DocumentListMath, Title: "Math"}, + } +} + +func LookupDocumentList(command Command) (DocumentListBinding, bool) { + for _, binding := range DocumentListBindings() { + if binding.Command == command { + return binding, true + } + } + return DocumentListBinding{}, false +} diff --git a/internal/input/document_lists_test.go b/internal/input/document_lists_test.go new file mode 100644 index 0000000..a64c556 --- /dev/null +++ b/internal/input/document_lists_test.go @@ -0,0 +1,46 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "testing" + +func TestDocumentListShortcutsAndCustomization(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + bindings := BrowseCommandBindings(layout) + bound := 0 + for _, binding := range DocumentListBindings() { + if binding.Symbol == 0 { + continue + } + bound++ + chord := CommandChord{Symbol: binding.Symbol, Modifiers: 9} + if bindings[chord] != binding.Command || DefaultCommandBindings(layout)[chord] != "" { + t.Fatalf("%s has incorrect scope or shortcut", binding.Command) + } + outside := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(layout)) + if consumed, command := outside.Handle(binding.Symbol, 100, 9, true); consumed || command != "" { + t.Fatalf("%s intercepted outside browse mode", binding.Command) + } + router := NewCommandRouter([]uint32{0xff63}, bindings) + if consumed, command := router.Handle(binding.Symbol, 100, 9, true); !consumed || command != binding.Command { + t.Fatalf("%s was not dispatched: %v %s", binding.Command, consumed, command) + } + if consumed, _ := router.Handle(binding.Symbol, 100, 9, false); !consumed { + t.Fatal("lost list key release") + } + } + if bound != 25 { + t.Fatalf("got %d shortcuts, want 19 types and 6 heading levels", bound) + } + overrides := []BindingOverride{{Layout: layout, Scope: "browse", Command: DocumentListMath, Keys: []string{"Alt+Shift+y"}}} + if err := ValidateBindingOverrides(overrides); err != nil { + t.Fatal(err) + } + custom, err := ResolveCommandBindings(layout, true, overrides) + if err != nil || custom[CommandChord{Symbol: 'y', Modifiers: 9}] != DocumentListMath { + t.Fatalf("unbound list customization: %v", err) + } + } +} diff --git a/internal/input/document_test.go b/internal/input/document_test.go new file mode 100644 index 0000000..44c25f5 --- /dev/null +++ b/internal/input/document_test.go @@ -0,0 +1,50 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package input + +import "testing" + +func TestDocumentChords(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, tc := range []struct { + symbol uint32 + mask uint16 + want Command + }{ + {'h', 0, ToggleLearnMode}, {'h', 1, DocumentPreviousHeading}, + {'k', controlModifier, DocumentNextLink}, {'k', controlModifier | 1, DocumentPreviousLink}, + } { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(layout)) + if consumed, _ := router.Handle(tc.symbol, 43, tc.mask, true); consumed { + t.Fatal("plain document key consumed") + } + router.Handle(tc.symbol, 43, tc.mask, false) + router.Handle(0xff63, 118, tc.mask, true) + if consumed, command := router.Handle(tc.symbol, 43, tc.mask, true); !consumed || command != tc.want { + t.Fatal("press did not dispatch command") + } + router.Handle(0xff63, 118, tc.mask, false) + if consumed, command := router.Handle(tc.symbol, 43, tc.mask, false); !consumed || command != "" { + t.Fatalf("got %v %v want %v", consumed, command, tc.want) + } + } + } + if got := DefaultCommandBindings(LaptopKeyboardLayout)[CommandChord{Symbol: 'k', CthulhuModifier: true}]; got != ReviewCurrentWord { + t.Fatal("laptop word binding replaced") + } +} diff --git a/internal/input/flat_review_test.go b/internal/input/flat_review_test.go new file mode 100644 index 0000000..777c55d --- /dev/null +++ b/internal/input/flat_review_test.go @@ -0,0 +1,191 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package input + +import ( + "testing" + "time" +) + +func TestReviewMultiPressSequences(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, modifierFirst := range []bool{false, true} { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(layout)) + now := time.Unix(100, 0) + router.now = func() time.Time { return now } + wordKey, charKey, lineKey := uint32(0xff9d), uint32(0xff99), uint32(0xff97) + if layout == LaptopKeyboardLayout { + wordKey, charKey, lineKey = 'k', ',', 'i' + } + press := func(symbol uint32, want Command) { + t.Helper() + if layout == LaptopKeyboardLayout { + router.Handle(0xff63, 118, 0, true) + } + if consumed, got := router.Handle(symbol, 30, 0, true); !consumed || got != want { + t.Fatalf("layout=%d press=%x got=%s want=%s", layout, symbol, got, want) + } + if consumed, got := router.Handle(symbol, 30, 0, true); !consumed || got != "" { + t.Fatal("held-key repeat dispatched") + } + if layout == LaptopKeyboardLayout && modifierFirst { + router.Handle(0xff63, 118, 0, false) + } + if consumed, got := router.Handle(symbol, 30, 0, false); !consumed || got != "" { + t.Fatal("unbalanced release") + } + if layout == LaptopKeyboardLayout && !modifierFirst { + router.Handle(0xff63, 118, 0, false) + } + router.Reset() + router.ReplaceBindings(BrowseCommandBindings(layout)) + } + press(lineKey, ReviewCurrentLine) + press(lineKey, ReviewSpellLine) + press(lineKey, ReviewPhoneticLine) + press(lineKey, ReviewCurrentLine) + now = now.Add(501 * time.Millisecond) + press(lineKey, ReviewCurrentLine) + press(charKey, ReviewCurrentCharacter) + now = now.Add(500 * time.Millisecond) + press(charKey, ReviewPhoneticCharacter) + press(charKey, ReviewCurrentCharacter) + press(wordKey, ReviewCurrentWord) // Different chord resets the sequence. + press(wordKey, ReviewSpellWord) + press(wordKey, ReviewPhoneticWord) + press(wordKey, ReviewCurrentWord) + now = now.Add(501 * time.Millisecond) + press(wordKey, ReviewCurrentWord) + router.Handle(0xffbe, 67, 0, true) // Unbound intervening key. + router.Handle(0xffbe, 67, 0, false) + press(wordKey, ReviewCurrentWord) + now = now.Add(-time.Millisecond) + press(wordKey, ReviewCurrentWord) // Clock reversal must not count. + } + } +} + +func TestFlatReviewLayoutBindingsAndBalancedRelease(t *testing.T) { + for _, tc := range []struct { + desktop, laptop uint32 + command Command + }{ + {0xff95, 'u', ReviewPreviousLine}, {0xff97, 'i', ReviewCurrentLine}, {0xff9a, 'o', ReviewNextLine}, + {0xff96, 'j', ReviewPreviousWord}, {0xff9d, 'k', ReviewCurrentWord}, {0xff98, 'l', ReviewNextWord}, + {0xff9c, 'm', ReviewPreviousCharacter}, {0xff99, ',', ReviewCurrentCharacter}, {0xff9b, '.', ReviewNextCharacter}, + } { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, modifierFirst := range []bool{false, true} { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(layout)) + symbol := tc.desktop + if layout == LaptopKeyboardLayout { + symbol = tc.laptop + if consumed, _ := router.Handle(symbol, 30, 0, true); consumed { + t.Fatal("unmodified laptop letter consumed") + } + router.Handle(symbol, 30, 0, false) + router.Handle(0xff63, 118, 0, true) + } + if consumed, cmd := router.Handle(symbol, 30, 0, true); !consumed || cmd != tc.command { + t.Fatalf("press: %v %q", consumed, cmd) + } + if consumed, cmd := router.Handle(symbol, 30, 0, true); !consumed || cmd != "" { + t.Fatalf("repeat: %v %q", consumed, cmd) + } + if layout == LaptopKeyboardLayout && modifierFirst { + router.Handle(0xff63, 118, 0, false) + } + consumed, cmd := router.Handle(symbol, 30, 0, false) + if !consumed { + t.Fatal("review release leaked") + } + if layout == LaptopKeyboardLayout && !modifierFirst { + if cmd != "" { + t.Fatal("command emitted while Insert held") + } + _, cmd = router.Handle(0xff63, 118, 0, false) + } + if cmd != "" { + t.Fatalf("release dispatched %q", cmd) + } + } + } + } +} + +func TestFlatReviewWindowBindingsAndBalancedRelease(t *testing.T) { + for _, tc := range []struct { + symbol uint32 + layout KeyboardLayout + modifiers uint16 + command Command + }{ + {0xff95, DesktopKeyboardLayout, 0, ReviewWindowStart}, + {0xff9a, DesktopKeyboardLayout, 0, ReviewWindowEnd}, + {'u', LaptopKeyboardLayout, controlModifier, ReviewWindowStart}, + {'o', LaptopKeyboardLayout, controlModifier, ReviewWindowEnd}, + } { + for _, releaseModifierFirst := range []bool{false, true} { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(tc.layout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle(tc.symbol, 30, tc.modifiers, true); !consumed || command != tc.command { + t.Fatalf("press: consumed=%v command=%q", consumed, command) + } + releases := []struct { + symbol uint32 + code uint16 + }{{tc.symbol, 30}, {0xff63, 118}} + if releaseModifierFirst { + releases[0], releases[1] = releases[1], releases[0] + } + for _, key := range releases { + if consumed, command := router.Handle(key.symbol, key.code, 0, false); !consumed || command != "" { + t.Fatalf("release: consumed=%v command=%q", consumed, command) + } + } + } + } +} + +func TestFlatReviewVerticalAndLineEndBindings(t *testing.T) { + for _, tc := range []struct { + symbol uint32 + layout KeyboardLayout + modifiers uint16 + command Command + }{ + {0xff96, DesktopKeyboardLayout, 0, ReviewWordAbove}, + {0xff98, DesktopKeyboardLayout, 0, ReviewWordBelow}, + {0xff9c, DesktopKeyboardLayout, 0, ReviewLineEnd}, + {'j', LaptopKeyboardLayout, controlModifier, ReviewWordAbove}, + {'l', LaptopKeyboardLayout, controlModifier, ReviewWordBelow}, + {'m', LaptopKeyboardLayout, controlModifier, ReviewLineEnd}, + } { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(tc.layout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle(tc.symbol, 30, tc.modifiers, true); !consumed || command != tc.command { + t.Fatalf("press: consumed=%v command=%q want=%q", consumed, command, tc.command) + } + if consumed, command := router.Handle(tc.symbol, 30, 0, false); !consumed || command != "" { + t.Fatalf("release: consumed=%v command=%q", consumed, command) + } + if consumed, command := router.Handle(0xff63, 118, 0, false); !consumed || command != "" { + t.Fatalf("modifier release: consumed=%v command=%q", consumed, command) + } + } +} diff --git a/internal/input/input.go b/internal/input/input.go new file mode 100644 index 0000000..e6339ab --- /dev/null +++ b/internal/input/input.go @@ -0,0 +1,127 @@ +package input + +import ( + "strconv" + "strings" +) + +type KeyKind uint8 + +const ( + KeyUnknown KeyKind = iota + KeyModifier + KeyFunction + KeyAction + KeyNavigation + KeyDiacritical +) + +type Event struct { + Timestamp uint32 // X server milliseconds, for ordering independent listeners. + Keycode uint8 + Pressed bool + Repeat bool // X11 autorepeat, distinct from a new physical key press. + Name string + Text string + Kind KeyKind +} + +type EchoSettings struct { + EnableKeyEcho bool + EnableModifierKeys bool + EnableFunctionKeys bool + EnableActionKeys bool + EnableNavigationKeys bool + EnableDiacriticalKeys bool + CthulhuModifierKeys []string +} + +func NewKeyEvent(keycode uint8, pressed bool, name string) Event { + kind, text := classifyKey(name) + return Event{Keycode: keycode, Pressed: pressed, Name: name, Text: text, Kind: kind} +} + +func EchoText(event Event, settings EchoSettings) string { + if !event.Pressed || !settings.EnableKeyEcho { + return "" + } + var enabled bool + switch event.Kind { + case KeyModifier: + enabled = settings.EnableModifierKeys + case KeyFunction: + enabled = settings.EnableFunctionKeys + case KeyAction: + enabled = settings.EnableActionKeys + case KeyNavigation: + enabled = settings.EnableNavigationKeys + case KeyDiacritical: + enabled = settings.EnableDiacriticalKeys + } + if !enabled { + return "" + } + return event.Text +} + +func classifyKey(name string) (KeyKind, string) { + if text, exists := map[string]string{ + "Shift_L": "left shift", "Shift_R": "right shift", + "Control_L": "left control", "Control_R": "right control", + "Alt_L": "left alt", "Alt_R": "right alt", + "Meta_L": "left meta", "Meta_R": "right meta", + "ISO_Level3_Shift": "Alt Gr", + }[name]; exists { + return KeyModifier, text + } + if strings.HasPrefix(name, "F") { + number, err := strconv.Atoi(strings.TrimPrefix(name, "F")) + if err == nil && number >= 1 && number <= 12 { + return KeyFunction, strings.ToLower(name) + } + } + if text, exists := map[string]string{ + "Return": "return", "KP_Enter": "enter", "Escape": "escape", + "Tab": "tab", "ISO_Left_Tab": "left tab", "BackSpace": "backspace", + "Delete": "delete", "KP_Delete": "delete", + "Page_Up": "page up", "KP_Page_Up": "page up", "Prior": "page up", "KP_Prior": "page up", + "Page_Down": "page down", "KP_Page_Down": "page down", "Next": "page down", "KP_Next": "page down", + }[name]; exists { + return KeyAction, text + } + if text, exists := map[string]string{ + "Left": "left", "KP_Left": "left", "Right": "right", "KP_Right": "right", + "Up": "up", "KP_Up": "up", "Down": "down", "KP_Down": "down", + "Home": "home", "KP_Home": "home", "End": "end", "KP_End": "end", + }[name]; exists { + return KeyNavigation, text + } + if strings.HasPrefix(name, "dead_") { + text := strings.ReplaceAll(strings.TrimPrefix(name, "dead_"), "_", " ") + if text == "abovering" { + text = "ring" + } + return KeyDiacritical, text + } + return KeyUnknown, "" +} + +type ModifierKeycodes [256]bool + +func NewModifierKeycodes(keycodes ...uint8) ModifierKeycodes { + var modifiers ModifierKeycodes + for _, keycode := range keycodes { + modifiers[keycode] = true + } + return modifiers +} + +func (modifiers ModifierKeycodes) Contains(keycode uint8) bool { + return modifiers[keycode] +} + +// Automatic titles survive held-key repeats, but fresh input and explicit +// stop keys cancel both scheduled and already queued title speech. +func ShouldInterruptTitle(event Event) bool { + return event.Pressed && (!event.Repeat || event.Name == "Control_L" || event.Name == "Control_R" || event.Name == "Escape") +} diff --git a/internal/input/input_test.go b/internal/input/input_test.go new file mode 100644 index 0000000..465e36e --- /dev/null +++ b/internal/input/input_test.go @@ -0,0 +1,89 @@ +package input + +import "testing" + +func TestShouldInterruptSpeechOnKeyPress(t *testing.T) { + tests := []struct { + name string + event Event + want bool + }{ + {name: "left control press", event: Event{Keycode: 37, Pressed: true}, want: true}, + {name: "left shift press", event: Event{Keycode: 50, Pressed: true}, want: true}, + {name: "right shift press", event: Event{Keycode: 62, Pressed: true}, want: true}, + {name: "left control release", event: Event{Keycode: 37, Pressed: false}, want: false}, + {name: "letter press", event: Event{Keycode: 38, Pressed: true}, want: true}, + {name: "up press at table boundary", event: NewKeyEvent(111, true, "Up"), want: true}, + {name: "up release", event: NewKeyEvent(111, false, "Up"), want: false}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := (InterruptionSettings{Mode: InterruptAllKeys}).ShouldInterrupt(test.event); got != test.want { + t.Fatalf("ShouldInterruptSpeech() = %v, want %v", got, test.want) + } + }) + } +} + +func TestModifierKeycodesSupportsHighX11Keycodes(t *testing.T) { + modifiers := NewModifierKeycodes(37, 105) + + if !modifiers.Contains(37) || !modifiers.Contains(105) { + t.Fatal("Control keycodes were omitted") + } + if modifiers.Contains(38) { + t.Fatal("unrelated keycode was marked as a modifier") + } +} + +func TestNewKeyEventClassifiesNonPrintableKeys(t *testing.T) { + tests := []struct { + name string + kind KeyKind + text string + }{ + {name: "Control_L", kind: KeyModifier, text: "left control"}, + {name: "ISO_Level3_Shift", kind: KeyModifier, text: "Alt Gr"}, + {name: "F12", kind: KeyFunction, text: "f12"}, + {name: "Return", kind: KeyAction, text: "return"}, + {name: "KP_Page_Down", kind: KeyAction, text: "page down"}, + {name: "Left", kind: KeyNavigation, text: "left"}, + {name: "KP_Home", kind: KeyNavigation, text: "home"}, + {name: "dead_acute", kind: KeyDiacritical, text: "acute"}, + {name: "dead_abovering", kind: KeyDiacritical, text: "ring"}, + {name: "a", kind: KeyUnknown, text: ""}, + {name: "F13", kind: KeyUnknown, text: ""}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + event := NewKeyEvent(42, true, test.name) + if event.Kind != test.kind || event.Text != test.text || event.Name != test.name { + t.Fatalf("event = %+v, want kind %v and text %q", event, test.kind, test.text) + } + }) + } +} + +func TestEchoTextHonorsNonPrintableCategories(t *testing.T) { + settings := EchoSettings{EnableKeyEcho: true, EnableModifierKeys: true, EnableFunctionKeys: true, + EnableActionKeys: true, EnableNavigationKeys: true, EnableDiacriticalKeys: true} + for _, name := range []string{"Control_L", "F1", "Tab", "Right", "dead_acute"} { + event := NewKeyEvent(42, true, name) + if got := EchoText(event, settings); got == "" { + t.Fatalf("EchoText(%q) was empty", name) + } + } + settings.EnableNavigationKeys = false + if got := EchoText(NewKeyEvent(42, true, "Right"), settings); got != "" { + t.Fatalf("disabled navigation echo = %q", got) + } + settings.EnableKeyEcho = false + if got := EchoText(NewKeyEvent(42, true, "F1"), settings); got != "" { + t.Fatalf("disabled key echo = %q", got) + } + settings.EnableKeyEcho = true + if got := EchoText(NewKeyEvent(42, false, "F1"), settings); got != "" { + t.Fatalf("release echo = %q", got) + } +} diff --git a/internal/input/intent.go b/internal/input/intent.go new file mode 100644 index 0000000..a775585 --- /dev/null +++ b/internal/input/intent.go @@ -0,0 +1,154 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import ( + "strings" + "sync" + "time" +) + +// Intent records only the kind of input, never the text the user typed. +type Intent uint8 + +const ( + NoIntent Intent = iota + TypingIntent + LineIntent + WordIntent + CharacterIntent + DeleteIntent + OtherIntent +) + +type Activity struct { + // InputSequence counts every key press without expiring with presentation + // intent. Virtual navigation uses it to distinguish + // native input from delayed application events, even after a quiet period. + InputSequence uint64 + // Unlike presentation intent, this counter never expires. Deferred titles + // may be waiting for application settings after ordinary input has aged out. + TitleInterruptionSequence uint64 + PlainCharacterArrow bool + Selecting bool + Intent Intent + Sequence uint64 + Clipboard ClipboardAction +} + +type ClipboardAction uint8 + +const ( + NoClipboardAction ClipboardAction = iota + CopyAction + CutAction + PasteAction +) + +type IntentTracker struct { + titleInterruptionSequence uint64 + sequence uint64 + mutex sync.Mutex + held map[string]bool + intent Intent + clipboard ClipboardAction + plainCharacterArrow bool + selecting bool + at time.Time +} + +func (tracker *IntentTracker) Observe(event Event) { + tracker.mutex.Lock() + defer tracker.mutex.Unlock() + if event.Pressed { + tracker.sequence++ + } + if ShouldInterruptTitle(event) { + tracker.titleInterruptionSequence++ + } + if tracker.held == nil { + tracker.held = make(map[string]bool) + } + if event.Kind == KeyModifier || event.Name == "Super_L" || event.Name == "Super_R" { + tracker.held[event.Name] = event.Pressed + if event.Pressed { + tracker.intent, tracker.at = OtherIntent, time.Now() + tracker.clipboard = NoClipboardAction + tracker.selecting = false + tracker.plainCharacterArrow = false + } + return + } + if !event.Pressed { + return + } + ctrl := tracker.held["Control_L"] || tracker.held["Control_R"] + shift := tracker.held["Shift_L"] || tracker.held["Shift_R"] + alt := tracker.held["Alt_L"] || tracker.held["Alt_R"] || tracker.held["Meta_L"] || tracker.held["Meta_R"] + intent := OtherIntent + tracker.clipboard = NoClipboardAction + name := strings.TrimPrefix(event.Name, "KP_") + if !alt { + if ctrl && !shift { + switch strings.ToLower(name) { + case "c": + tracker.clipboard = CopyAction + case "x": + tracker.clipboard = CutAction + case "v": + tracker.clipboard = PasteAction + } + } + switch name { + case "Up", "Down", "Page_Up", "Page_Down", "Prior", "Next": + intent = LineIntent + case "Left", "Right": + intent = CharacterIntent + if ctrl { + intent = WordIntent + } + case "Home", "End": + intent = CharacterIntent + if ctrl { + intent = LineIntent + } + case "Insert", "Caps_Lock", "Num_Lock", "Scroll_Lock", "Super_L", "Super_R": + intent = OtherIntent + case "BackSpace", "Delete": + intent = DeleteIntent + default: + if !ctrl && (event.Name != "" && event.Kind == KeyUnknown) { + intent = TypingIntent + } + } + } + tracker.plainCharacterArrow = (name == "Left" || name == "Right") && !ctrl && !shift && !alt && + !tracker.held["Super_L"] && !tracker.held["Super_R"] && + !tracker.held["ISO_Level3_Shift"] && !tracker.held["ISO_Level5_Shift"] + tracker.selecting = shift && (intent == CharacterIntent || intent == WordIntent || intent == LineIntent) + tracker.intent, tracker.at = intent, time.Now() +} + +func (tracker *IntentTracker) RecentIntent() Intent { return tracker.RecentInput().Intent } + +// Reset retires held modifiers and presentation intent across secure input. +func (tracker *IntentTracker) Reset() { + tracker.mutex.Lock() + defer tracker.mutex.Unlock() + clear(tracker.held) + tracker.intent, tracker.at = OtherIntent, time.Time{} + tracker.clipboard, tracker.selecting = NoClipboardAction, false + tracker.plainCharacterArrow = false +} + +func (tracker *IntentTracker) RecentInput() Activity { + tracker.mutex.Lock() + defer tracker.mutex.Unlock() + if time.Since(tracker.at) > time.Second { + return Activity{InputSequence: tracker.sequence, TitleInterruptionSequence: tracker.titleInterruptionSequence} + } + return Activity{PlainCharacterArrow: tracker.plainCharacterArrow, InputSequence: tracker.sequence, Intent: tracker.intent, Sequence: tracker.sequence, Clipboard: tracker.clipboard, Selecting: tracker.selecting, + TitleInterruptionSequence: tracker.titleInterruptionSequence} +} diff --git a/internal/input/intent_test.go b/internal/input/intent_test.go new file mode 100644 index 0000000..ac09de3 --- /dev/null +++ b/internal/input/intent_test.go @@ -0,0 +1,148 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import ( + "testing" + "time" +) + +func TestIntentTracksModifiersAndExpires(t *testing.T) { + tracker := &IntentTracker{} + for _, step := range []struct { + name string + pressed bool + want Intent + }{ + {"Down", true, LineIntent}, {"Down", false, LineIntent}, + {"Right", true, CharacterIntent}, {"Control_L", true, OtherIntent}, + {"Right", true, WordIntent}, {"Control_R", true, OtherIntent}, + {"Control_L", false, OtherIntent}, {"Left", true, WordIntent}, + {"Control_R", false, WordIntent}, {"Left", true, CharacterIntent}, + {"s", true, TypingIntent}, {"period", true, TypingIntent}, + {"BackSpace", true, DeleteIntent}, {"Return", true, OtherIntent}, + {"Alt_L", true, OtherIntent}, {"Down", true, OtherIntent}, + } { + tracker.Observe(NewKeyEvent(0, step.pressed, step.name)) + if got := tracker.RecentIntent(); got != step.want { + t.Fatalf("%s pressed=%v: %v, want %v", step.name, step.pressed, got, step.want) + } + } + tracker.at = time.Now().Add(-2 * time.Second) + if tracker.RecentIntent() != NoIntent { + t.Fatal("stale input reused") + } +} + +func TestIntentTracksClipboardChords(t *testing.T) { + tracker := &IntentTracker{} + press := func(name string) Activity { + tracker.Observe(NewKeyEvent(0, true, name)) + return tracker.RecentInput() + } + press("Shift_L") + if got := press("Right"); got.Intent != CharacterIntent || !got.Selecting { + t.Fatalf("Shift+Right = %+v", got) + } + press("Control_L") + if got := press("Left"); got.Intent != WordIntent || !got.Selecting { + t.Fatalf("Ctrl+Shift+Left = %+v", got) + } + tracker.Observe(NewKeyEvent(0, false, "Shift_L")) + for _, tc := range []struct { + key string + want ClipboardAction + }{ + {"c", CopyAction}, {"x", CutAction}, {"v", PasteAction}, + } { + if got := press(tc.key); got.Clipboard != tc.want { + t.Fatalf("Ctrl+%s = %+v", tc.key, got) + } + } + if got := press("Right"); got.Clipboard != NoClipboardAction { + t.Fatalf("next key retained clipboard action: %+v", got) + } + tracker.Observe(NewKeyEvent(0, false, "Control_L")) + if got := press("v"); got.Clipboard != NoClipboardAction { + t.Fatalf("plain v = %+v", got) + } +} + +func TestSelectionIntentEndsWithPlainNavigation(t *testing.T) { + tracker := &IntentTracker{} + tracker.Observe(NewKeyEvent(0, true, "Shift_L")) + tracker.Observe(NewKeyEvent(0, true, "Down")) + if got := tracker.RecentInput(); !got.Selecting || got.Intent != LineIntent { + t.Fatalf("Shift+Down = %+v", got) + } + tracker.Observe(NewKeyEvent(0, false, "Shift_L")) + tracker.Observe(NewKeyEvent(0, true, "Right")) + if got := tracker.RecentInput(); got.Selecting || got.Intent != CharacterIntent { + t.Fatalf("Right = %+v", got) + } +} + +func TestTitleInterruptionTracksFreshPressesAndStopKeys(t *testing.T) { + tracker := &IntentTracker{} + for _, step := range []struct { + name string + pressed bool + repeat bool + want uint64 + }{ + {"a", true, false, 1}, {"a", false, false, 1}, + {"a", true, true, 1}, {"Down", true, false, 2}, + {"Down", true, true, 2}, {"Control_L", true, true, 3}, + {"Control_R", true, true, 4}, {"Escape", true, true, 5}, + } { + event := NewKeyEvent(0, step.pressed, step.name) + event.Repeat = step.repeat + tracker.Observe(event) + if got := tracker.RecentInput().TitleInterruptionSequence; got != step.want { + t.Fatalf("%+v: title interruption sequence = %d", step, got) + } + } + tracker.at = time.Now().Add(-2 * time.Second) + if got := tracker.RecentInput(); got.Intent != NoIntent || got.TitleInterruptionSequence != 5 { + t.Fatalf("expired activity = %+v", got) + } + tracker.Reset() + if got := tracker.RecentInput().TitleInterruptionSequence; got != 5 { + t.Fatalf("reset lost interruption history: %d", got) + } +} + +func TestNavigationInputIdentitySurvivesIdle(t *testing.T) { + tracker := &IntentTracker{} + tracker.Observe(NewKeyEvent(0, true, "h")) + tracker.at = time.Now().Add(-2 * time.Second) + if got := tracker.RecentInput(); got.InputSequence != 1 || got.Sequence != 0 || got.Intent != NoIntent { + t.Fatalf("idle input identity = %+v", got) + } +} + +func TestPlainCharacterArrowsExcludeOtherNavigation(t *testing.T) { + for _, modifier := range []string{"", "Shift_L", "Control_L", "Alt_L", "Super_L", "ISO_Level3_Shift"} { + for _, key := range []string{"Left", "Right", "KP_Left", "Home", "End", "Up", "a"} { + var tracker IntentTracker + if modifier != "" { + tracker.Observe(NewKeyEvent(1, true, modifier)) + } + tracker.Observe(NewKeyEvent(2, true, key)) + want := modifier == "" && (key == "Left" || key == "Right" || key == "KP_Left") + if got := tracker.RecentInput().PlainCharacterArrow; got != want { + t.Fatalf("%s+%s hint = %t, want %t", modifier, key, got, want) + } + tracker.Observe(NewKeyEvent(2, false, key)) + if tracker.RecentInput().PlainCharacterArrow != want { + t.Fatal("releasing arrow discarded presentation intent") + } + tracker.Reset() + if tracker.RecentInput().PlainCharacterArrow { + t.Fatal("reset retained phonetic arrow") + } + } + } +} diff --git a/internal/input/interruption.go b/internal/input/interruption.go new file mode 100644 index 0000000..3277891 --- /dev/null +++ b/internal/input/interruption.go @@ -0,0 +1,72 @@ +package input + +import ( + "errors" + "strings" +) + +const ( + InterruptAllKeys = "all" + InterruptCommonKeys = "common" + InterruptCustomKeys = "custom" + MaxInterruptionKeys = 64 +) + +// InterruptionSettings selects individual keys, independently of key echo and +// command bindings. Reader commands retain their own explicit cancellation. +type InterruptionSettings struct { + Mode string `toml:"mode"` + Keys []string `toml:"keys"` +} + +func (settings InterruptionSettings) Validate() error { + switch settings.Mode { + case InterruptAllKeys, InterruptCommonKeys, InterruptCustomKeys: + default: + return errors.New("choose a valid speech interruption mode") + } + if len(settings.Keys) > MaxInterruptionKeys { + return errors.New("too many speech interruption keys") + } + if settings.Mode == InterruptCustomKeys && len(settings.Keys) == 0 { + return errors.New("record at least one speech interruption key") + } + seen := make(map[string]bool, len(settings.Keys)) + for _, name := range settings.Keys { + key := strings.ToLower(name) + if name == "" || len(name) > 128 || seen[key] { + return errors.New("speech interruption keys must have unique, valid key names") + } + for _, character := range name { + if character != '_' && !(character >= 'a' && character <= 'z') && + !(character >= 'A' && character <= 'Z') && !(character >= '0' && character <= '9') { + return errors.New("invalid speech interruption key name") + } + } + seen[key] = true + } + return nil +} + +func (settings InterruptionSettings) ShouldInterrupt(event Event) bool { + if !event.Pressed { + return false + } + switch settings.Mode { + case InterruptCommonKeys: + switch event.Name { + case "Control_L", "Control_R", "Return", "KP_Enter", "space", "KP_Space", "Escape": + return true + } + return false + case InterruptCustomKeys: + for _, name := range settings.Keys { + if strings.EqualFold(name, event.Name) || name == "Tab" && event.Name == "ISO_Left_Tab" { + return true + } + } + return false + default: + return true + } +} diff --git a/internal/input/interruption_test.go b/internal/input/interruption_test.go new file mode 100644 index 0000000..23e5b5e --- /dev/null +++ b/internal/input/interruption_test.go @@ -0,0 +1,47 @@ +package input + +import "testing" + +func TestSpeechInterruptionModes(t *testing.T) { + for _, name := range []string{"Control_L", "Control_R", "Return", "KP_Enter", "space", "KP_Space", "Escape", "Shift_L", "Tab", "Up", "a", "F8"} { + for _, pressed := range []bool{false, true} { + for _, repeat := range []bool{false, true} { + event := NewKeyEvent(42, pressed, name) + event.Repeat = repeat + common := name == "Control_L" || name == "Control_R" || name == "Return" || name == "KP_Enter" || name == "space" || name == "KP_Space" || name == "Escape" + for mode, want := range map[string]bool{InterruptAllKeys: pressed, InterruptCommonKeys: pressed && common, + InterruptCustomKeys: pressed && (name == "Tab" || name == "F8")} { + settings := InterruptionSettings{Mode: mode, Keys: []string{"Tab", "F8"}} + if got := settings.ShouldInterrupt(event); got != want { + t.Fatalf("mode=%s event=%+v: interrupt=%t, want %t", mode, event, got, want) + } + } + } + } + } + settings := InterruptionSettings{Mode: InterruptCustomKeys, Keys: []string{"a", "Control_R"}} + if !settings.ShouldInterrupt(Event{Pressed: true, Name: "A"}) || settings.ShouldInterrupt(Event{Pressed: true, Name: "Control_L"}) { + t.Fatal("custom keys must ignore letter case and preserve left/right modifiers") + } + settings.Keys = []string{"Tab", "Prior", "XF86AudioMute"} + for _, name := range []string{"ISO_Left_Tab", "Prior", "XF86AudioMute"} { + if !settings.ShouldInterrupt(Event{Pressed: true, Name: name}) { + t.Fatalf("recorded key %s did not match its input name", name) + } + } +} + +func TestSpeechInterruptionValidation(t *testing.T) { + for _, settings := range []InterruptionSettings{ + {Mode: "unknown"}, {Mode: InterruptCustomKeys}, + {Mode: InterruptCustomKeys, Keys: []string{"Tab", "Tab"}}, + {Mode: InterruptCustomKeys, Keys: []string{"a", "A"}}, + {Mode: InterruptCustomKeys, Keys: []string{"Ctrl+Enter"}}, + {Mode: InterruptCustomKeys, Keys: []string{""}}, + {Mode: InterruptCustomKeys, Keys: make([]string, MaxInterruptionKeys+1)}, + } { + if err := settings.Validate(); err == nil { + t.Fatalf("accepted invalid settings %+v", settings) + } + } +} diff --git a/internal/input/notification_commands_test.go b/internal/input/notification_commands_test.go new file mode 100644 index 0000000..7ab3ab2 --- /dev/null +++ b/internal/input/notification_commands_test.go @@ -0,0 +1,30 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "testing" + +func TestNotificationCommandBindingsMatchReference(t *testing.T) { + for name, bindings := range map[string]CommandBindings{ + "desktop": DefaultCommandBindings(DesktopKeyboardLayout), + "laptop": DefaultCommandBindings(LaptopKeyboardLayout), + "desktop browse": BrowseCommandBindings(DesktopKeyboardLayout), + "laptop browse": BrowseCommandBindings(LaptopKeyboardLayout), + } { + t.Run(name, func(t *testing.T) { + if got := bindings[CommandChord{Symbol: 'n', CthulhuModifier: true}]; got != PresentLastNotification { + t.Fatalf("Cthulhu+N = %q, want %q", got, PresentLastNotification) + } + if got := bindings[CommandChord{Symbol: 'n', Modifiers: controlModifier, CthulhuModifier: true}]; got != ShowNotificationList { + t.Fatalf("Cthulhu+Ctrl+N = %q, want %q", got, ShowNotificationList) + } + for chord, command := range bindings { + if command == PresentPreviousNotification || command == PresentNextNotification { + t.Fatalf("reference leaves %s unbound; found chord %#v", command, chord) + } + } + }) + } +} diff --git a/internal/input/ocr.go b/internal/input/ocr.go new file mode 100644 index 0000000..8660b94 --- /dev/null +++ b/internal/input/ocr.go @@ -0,0 +1,75 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +const ( + OCRObject Command = "ocr-object" + OCRWindow Command = "ocr-window" + OCRDesktop Command = "ocr-desktop" + OCRClipboard Command = "ocr-clipboard" + OCRPreviousCharacter Command = "ocr-previous-character" + OCRNextCharacter Command = "ocr-next-character" + OCRPreviousWord Command = "ocr-previous-word" + OCRNextWord Command = "ocr-next-word" + OCRPreviousLine Command = "ocr-previous-line" + OCRNextLine Command = "ocr-next-line" + OCRLineStart Command = "ocr-line-start" + OCRLineEnd Command = "ocr-line-end" + OCRDocumentStart Command = "ocr-document-start" + OCRDocumentEnd Command = "ocr-document-end" + OCRPreviousPage Command = "ocr-previous-page" + OCRNextPage Command = "ocr-next-page" + OCRSelectAll Command = "ocr-select-all" + OCRCopySelection Command = "ocr-copy-selection" + OCRActivate Command = "ocr-activate" + OCRRefresh Command = "ocr-refresh" + OCRDismiss Command = "ocr-dismiss" + OCRDismissAndPass Command = "ocr-dismiss-and-pass" +) + +// OCRPendingBindings claims cancellation only while capture/recognition runs. +func OCRPendingBindings(global CommandBindings) CommandBindings { + bindings := make(CommandBindings, len(global)+1) + for chord, command := range global { + bindings[chord] = command + } + bindings[CommandChord{Symbol: 0xff1b}] = OCRDismiss + return bindings +} + +// OCRCommandBindings overlays the temporary document controls on configured +// global commands. It never imports browser structural bindings. Chord retains +// Shift for the future selection owner; no extra persisted binding scope exists. +func OCRCommandBindings(global CommandBindings) CommandBindings { + bindings := make(CommandBindings, len(global)+32) + for chord, command := range global { + bindings[chord] = command + } + for _, binding := range []struct { + symbol uint32 + modifiers uint16 + command Command + }{ + {leftKeySymbol, 0, OCRPreviousCharacter}, {rightKeySymbol, 0, OCRNextCharacter}, + {leftKeySymbol, controlModifier, OCRPreviousWord}, {rightKeySymbol, controlModifier, OCRNextWord}, + {upKeySymbol, 0, OCRPreviousLine}, {downKeySymbol, 0, OCRNextLine}, + {0xff50, 0, OCRLineStart}, {0xff57, 0, OCRLineEnd}, + {0xff50, controlModifier, OCRDocumentStart}, {0xff57, controlModifier, OCRDocumentEnd}, + {0xff55, 0, OCRPreviousPage}, {0xff56, 0, OCRNextPage}, + } { + for _, shift := range []uint16{0, 1} { + bindings[CommandChord{Symbol: binding.symbol, Modifiers: binding.modifiers | shift}] = binding.command + } + } + bindings[CommandChord{Symbol: 'a', Modifiers: controlModifier}] = OCRSelectAll + bindings[CommandChord{Symbol: 'c', Modifiers: controlModifier}] = OCRCopySelection + bindings[CommandChord{Symbol: returnKeySymbol}] = OCRActivate + bindings[CommandChord{Symbol: ' '}] = OCRActivate + bindings[CommandChord{Symbol: 0xffc2, CthulhuModifier: true}] = OCRRefresh + bindings[CommandChord{Symbol: 0xff1b}] = OCRDismiss + bindings[CommandChord{Symbol: 0xff09}] = OCRDismissAndPass + bindings[CommandChord{Symbol: 0xff09, Modifiers: 1}] = OCRDismissAndPass + return bindings +} diff --git a/internal/input/ocr_test.go b/internal/input/ocr_test.go new file mode 100644 index 0000000..5783861 --- /dev/null +++ b/internal/input/ocr_test.go @@ -0,0 +1,84 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "testing" + +func TestOCRReaderShortcutsAndConfigurableSources(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + modifiers := uint16(0) + if layout == LaptopKeyboardLayout { + modifiers = 1 + } + bindings := DefaultCommandBindings(layout) + if bindings[CommandChord{Symbol: 'o', Modifiers: modifiers, CthulhuModifier: true}] != OCRWindow { + t.Fatal("missing primary OCR shortcut") + } + pending := OCRPendingBindings(bindings) + if pending[CommandChord{Symbol: downKeySymbol}] != "" || pending[CommandChord{Symbol: 0xff1b}] != OCRDismiss { + t.Fatal("pending OCR claimed navigation") + } + for _, command := range []Command{OCRObject, OCRWindow, OCRDesktop, OCRClipboard} { + if err := ValidateBindingOverrides([]BindingOverride{{Layout: layout, Scope: "global", Command: command, Keys: []string{"Cthulhu+F8"}}}); err != nil { + t.Fatal(err) + } + found := false + for _, row := range BindingRows(layout, nil) { + if row.Command == command && row.Scope == "global" { + found = true + if command == OCRWindow && row.DefaultKeys == "" { + t.Fatal("window OCR shortcut missing from preferences") + } + } + } + if !found { + t.Fatalf("missing configurable source %s", command) + } + } + } +} + +func TestOCRBindingsPreserveGlobalAndLaptopReview(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + global := DefaultCommandBindings(layout) + bindings := OCRCommandBindings(global) + if bindings[CommandChord{Symbol: 0xffc2, CthulhuModifier: true}] != OCRRefresh || + bindings[CommandChord{Symbol: 0xff55}] != OCRPreviousPage || bindings[CommandChord{Symbol: 0xff56}] != OCRNextPage { + t.Fatal("OCR refresh or page navigation binding missing") + } + for chord, command := range global { + if chord.CthulhuModifier && bindings[chord] != command { + t.Fatalf("global changed: %v", chord) + } + } + for _, symbol := range []uint32{'h', 'b', 'l', 'o', 'x'} { + if bindings[CommandChord{Symbol: symbol}] != "" { + t.Fatalf("OCR claimed structural key %c", symbol) + } + } + router := NewCommandRouter([]uint32{0xff63}, bindings) + for _, test := range []struct { + symbol uint32 + modifiers uint16 + want Command + }{ + {leftKeySymbol, 0, OCRPreviousCharacter}, {rightKeySymbol, 1 | controlModifier, OCRNextWord}, + {downKeySymbol, 0, OCRNextLine}, {'a', controlModifier, OCRSelectAll}, + {'c', controlModifier, OCRCopySelection}, {0xff09, 1, OCRDismissAndPass}, {0xff1b, 0, OCRDismiss}, + } { + consume, command := router.Handle(test.symbol, 42, test.modifiers, true) + if !consume || command != test.want { + t.Fatalf("chord got %v %s, want %s", consume, command, test.want) + } + consume, command = router.Handle(test.symbol, 42, test.modifiers, false) + if !consume || command != "" { + t.Fatal("lost held release") + } + } + if layout == LaptopKeyboardLayout && bindings[CommandChord{Symbol: 'o', CthulhuModifier: true}] != ReviewNextLine { + t.Fatal("laptop next line changed") + } + } +} diff --git a/internal/input/read_all_test.go b/internal/input/read_all_test.go new file mode 100644 index 0000000..8cf929d --- /dev/null +++ b/internal/input/read_all_test.go @@ -0,0 +1,29 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "testing" + +func TestReadAllBindings(t *testing.T) { + for _, browse := range []bool{false, true} { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + bindings := DefaultCommandBindings(layout) + if browse { + bindings = BrowseCommandBindings(layout) + } + symbol := uint32(0xffab) + modifier := layout == LaptopKeyboardLayout + if modifier { + symbol = ';' + } + if got := bindings[CommandChord{Symbol: symbol, CthulhuModifier: modifier}]; got != ReadAll { + t.Fatalf("layout %d browse %v: %q", layout, browse, got) + } + if bindings[CommandChord{Symbol: symbol, Modifiers: controlModifier, CthulhuModifier: modifier}] != "" { + t.Fatal("read all intercepted modified application shortcut") + } + } + } +} diff --git a/internal/input/repeat.go b/internal/input/repeat.go new file mode 100644 index 0000000..90fea6b --- /dev/null +++ b/internal/input/repeat.go @@ -0,0 +1,31 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +// RepeatTracker is owned by the native input producer. Classic X11 repeats +// release and press with the same timestamp; detectable autorepeat emits +// another press while the key remains down. Neither is a fresh physical press. +type RepeatTracker struct { + held [256]bool + releasedTimestamp [256]uint32 +} + +func (tracker *RepeatTracker) Observe(event Event) bool { + code := event.Keycode + if !event.Pressed { + tracker.held[code] = false + tracker.releasedTimestamp[code] = event.Timestamp + return false + } + repeated := tracker.held[code] || event.Timestamp != 0 && + tracker.releasedTimestamp[code] == event.Timestamp + tracker.held[code] = true + tracker.releasedTimestamp[code] = 0 + return repeated +} + +func (tracker *RepeatTracker) Reset() { + *tracker = RepeatTracker{} +} diff --git a/internal/input/repeat_test.go b/internal/input/repeat_test.go new file mode 100644 index 0000000..6650137 --- /dev/null +++ b/internal/input/repeat_test.go @@ -0,0 +1,39 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "testing" + +func TestRepeatTrackerRecognizesNativeSequences(t *testing.T) { + var tracker RepeatTracker + steps := []struct { + code uint8 + pressed bool + timestamp uint32 + repeat bool + }{ + {38, true, 100, false}, + {38, true, 110, true}, // Detectable autorepeat. + {39, true, 111, false}, // Another key is still a fresh press. + {38, false, 120, false}, + {38, true, 120, true}, // Classic X11 release/press pair. + {38, false, 130, false}, + {38, true, 140, false}, // Real release and new press. + {39, false, ^uint32(0), false}, + {39, true, 1, false}, // Timestamp wrap is not a repeat. + {38, false, 0, false}, + {38, true, 0, false}, // Unknown timestamps cannot prove a release/press pair. + {38, true, 0, true}, + } + for index, step := range steps { + if got := tracker.Observe(Event{Keycode: step.code, Pressed: step.pressed, Timestamp: step.timestamp}); got != step.repeat { + t.Fatalf("step %d: repeat = %t, want %t", index, got, step.repeat) + } + } + tracker.Reset() + if tracker.Observe(Event{Keycode: 38, Pressed: true, Timestamp: 150}) { + t.Fatal("secure reset retained held keys") + } +} diff --git a/internal/input/review_presses.go b/internal/input/review_presses.go new file mode 100644 index 0000000..f560d1d --- /dev/null +++ b/internal/input/review_presses.go @@ -0,0 +1,57 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "time" + +// The router owns this sequence across fully released chords and browse grab +// updates. Another key/chord, timeout, or the final press retires it. Held-key +// repeats never reach this helper. Reset only clears held keys, as for time/date. +func (router *CommandRouter) review_press(command Command, chord CommandChord) Command { + if command != ReviewCurrentCharacter && command != ReviewCurrentWord && command != ReviewCurrentLine && command != PresentCurrentLine { + router.lastReviewPress = time.Time{} + return command + } + now := router.now() + if chord == router.lastReviewChord && !router.lastReviewPress.IsZero() && + now.Sub(router.lastReviewPress) >= 0 && now.Sub(router.lastReviewPress) <= 500*time.Millisecond { + router.reviewPresses++ + } else { + router.reviewPresses = 1 + } + router.lastReviewChord, router.lastReviewPress = chord, now + if command == ReviewCurrentCharacter && router.reviewPresses == 2 { + router.lastReviewPress = time.Time{} + return ReviewPhoneticCharacter + } + if command == ReviewCurrentWord { + switch router.reviewPresses { + case 2: + return ReviewSpellWord + case 3: + router.lastReviewPress = time.Time{} + return ReviewPhoneticWord + } + } + if command == ReviewCurrentLine { + switch router.reviewPresses { + case 2: + return ReviewSpellLine + case 3: + router.lastReviewPress = time.Time{} + return ReviewPhoneticLine + } + } + if command == PresentCurrentLine { + switch router.reviewPresses { + case 2: + return SpellCurrentLine + case 3: + router.lastReviewPress = time.Time{} + return PhoneticCurrentLine + } + } + return command +} diff --git a/internal/input/speech_history_test.go b/internal/input/speech_history_test.go new file mode 100644 index 0000000..7e0ab7a --- /dev/null +++ b/internal/input/speech_history_test.go @@ -0,0 +1,20 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "testing" + +func TestSpeechHistoryBindingsInBothLayouts(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, bindings := range []CommandBindings{DefaultCommandBindings(layout), BrowseCommandBindings(layout)} { + if got := bindings[CommandChord{Symbol: 'h', Modifiers: controlModifier, CthulhuModifier: true}]; got != ShowSpeechHistory { + t.Fatalf("layout %d history = %q", layout, got) + } + if got := bindings[CommandChord{Symbol: 'd', Modifiers: 1, CthulhuModifier: true}]; got != ToggleSpeechMonitor { + t.Fatalf("layout %d monitor = %q", layout, got) + } + } + } +} diff --git a/internal/input/speech_mode_test.go b/internal/input/speech_mode_test.go new file mode 100644 index 0000000..ec1e189 --- /dev/null +++ b/internal/input/speech_mode_test.go @@ -0,0 +1,36 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "testing" + +func TestSpeechModeBindings(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, browse := range []bool{false, true} { + bindings, err := ResolveCommandBindings(layout, browse, nil) + if err != nil { + t.Fatal(err) + } + if got := bindings[CommandChord{Symbol: 's', CthulhuModifier: true}]; got != CycleSpeechMode { + t.Fatalf("layout %d browse %v: %q", layout, browse, got) + } + if got := bindings[CommandChord{Symbol: 's', Modifiers: 1 | controlModifier, CthulhuModifier: true}]; got != SaveSpeechSettings { + t.Fatalf("speech settings save changed: %q", got) + } + if browse && bindings[CommandChord{Symbol: 's'}] != DocumentNextSeparator { + t.Fatal("unmodified separator navigation changed") + } + custom, err := ResolveCommandBindings(layout, browse, []BindingOverride{{ + Layout: layout, Scope: "global", Command: CycleSpeechMode, Keys: []string{"Cthulhu+F8"}, + }}) + if err != nil { + t.Fatal(err) + } + if _, exists := custom[CommandChord{Symbol: 's', CthulhuModifier: true}]; exists { + t.Fatal("custom binding retained the old shortcut") + } + } + } +} diff --git a/internal/input/sticky_test.go b/internal/input/sticky_test.go new file mode 100644 index 0000000..1213644 --- /dev/null +++ b/internal/input/sticky_test.go @@ -0,0 +1,55 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import ( + "testing" + "time" +) + +func TestStickyPressesSurviveBrowseBindings(t *testing.T) { + router := NewCommandRouter([]uint32{0xff63}, BrowseCommandBindings(DesktopKeyboardLayout)) + now := time.Unix(100, 0) + router.now = func() time.Time { return now } + press := func(want Command) { + t.Helper() + router.Handle(0xff63, 118, 0, true) + if consumed, got := router.Handle('a', 38, 0, true); !consumed || got != want { + t.Fatalf("got %v %s want %s", consumed, got, want) + } + if _, got := router.Handle('a', 38, 0, true); got != "" { + t.Fatal("autorepeat changed mode") + } + router.Handle('a', 38, 0, false) + router.Handle(0xff63, 118, 0, false) + router.Reset() + now = now.Add(100 * time.Millisecond) + } + press(ToggleDocumentMode) + router.ReplaceBindings(DefaultCommandBindings(DesktopKeyboardLayout)) + press(StickyFocusMode) + press(StickyBrowseMode) + router.ReplaceBindings(BrowseCommandBindings(DesktopKeyboardLayout)) + now = now.Add(time.Second) + press(ToggleDocumentMode) + router.Handle('x', 53, 0, true) + router.Handle('x', 53, 0, false) + press(ToggleDocumentMode) +} + +func TestTableBindingsOnlyInBrowse(t *testing.T) { + for chord, command := range BrowseCommandBindings(DesktopKeyboardLayout) { + if chord.Modifiers != 9 { + continue + } + if DefaultCommandBindings(DesktopKeyboardLayout)[chord] != "" { + t.Fatal("table key grabbed outside browse") + } + router := NewCommandRouter(nil, BrowseCommandBindings(DesktopKeyboardLayout)) + if consumed, got := router.Handle(chord.Symbol, 100, 9, true); !consumed || got != command { + t.Fatalf("table binding %v %s", consumed, got) + } + } +} diff --git a/internal/input/tentacle_bindings.go b/internal/input/tentacle_bindings.go new file mode 100644 index 0000000..8be8e14 --- /dev/null +++ b/internal/input/tentacle_bindings.go @@ -0,0 +1,46 @@ +package input + +import ( + "fmt" + "strings" +) + +// Tentacle bindings are runtime registrations, never persisted core overrides. +// The native input owner arbitrates them again whenever core settings change. +func ValidateTentacleBindings(bindings []BindingOverride) error { + if len(bindings) > 16*32*4 { + return fmt.Errorf("too many tentacle bindings") + } + for _, binding := range bindings { + if !strings.HasPrefix(string(binding.Command), "tentacle/") || len(binding.Command) > 400 || + (binding.Layout != DesktopKeyboardLayout && binding.Layout != LaptopKeyboardLayout) || + (binding.Scope != "global" && binding.Scope != "browse") || len(binding.Keys) != 1 { + return fmt.Errorf("invalid tentacle binding") + } + if _, err := ParseCommandChord(binding.Keys[0]); err != nil { + return err + } + } + return nil +} + +// MergeTentacleBindings preserves core bindings and registration order. A +// conflicting suggestion stays unbound. Callers validate both inputs first. +func MergeTentacleBindings(core, suggestions []BindingOverride) []BindingOverride { + result := CloneBindingOverrides(core) + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + occupied, _ := ResolveCommandBindings(layout, true, core) + for _, suggestion := range suggestions { + if suggestion.Layout != layout { + continue + } + chord, _ := ParseCommandChord(suggestion.Keys[0]) + if occupied[chord] != "" { + continue + } + occupied[chord] = suggestion.Command + result = append(result, CloneBindingOverrides([]BindingOverride{suggestion})[0]) + } + } + return result +} diff --git a/internal/input/tentacle_bindings_test.go b/internal/input/tentacle_bindings_test.go new file mode 100644 index 0000000..b6694a8 --- /dev/null +++ b/internal/input/tentacle_bindings_test.go @@ -0,0 +1,62 @@ +package input + +import "testing" + +func TestTentacleWormholeShortcutAvailableOnBothLayouts(t *testing.T) { + chord, err := ParseCommandChord("Cthulhu+Ctrl+Shift+W") + if err != nil { + t.Fatal(err) + } + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + suggestions := []BindingOverride{{Layout: layout, Scope: "global", Command: "tentacle/wormhole/menu", Keys: []string{"Cthulhu+Ctrl+Shift+W"}}} + merged := MergeTentacleBindings(nil, suggestions) + bindings, err := ResolveCommandBindings(layout, true, merged) + if err != nil || bindings[chord] != "tentacle/wormhole/menu" { + t.Fatalf("layout %v: shortcut %v, error %v", layout, bindings[chord], err) + } + } +} + +func TestTentacleBindingsCoreWinsAcrossScopesAndRemapping(t *testing.T) { + suggestions := []BindingOverride{ + {DesktopKeyboardLayout, "global", "tentacle/a/one", []string{"F9"}}, + {DesktopKeyboardLayout, "browse", "tentacle/b/two", []string{"F9"}}, + {DesktopKeyboardLayout, "global", "tentacle/a/quit", []string{"Cthulhu+q"}}, + {LaptopKeyboardLayout, "global", "tentacle/b/two", []string{"F9"}}, + } + if err := ValidateTentacleBindings(suggestions); err != nil { + t.Fatal(err) + } + for _, core := range [][]BindingOverride{nil, {{DesktopKeyboardLayout, "browse", DocumentNextHeading, []string{"F9"}}}} { + merged := MergeTentacleBindings(core, suggestions) + bindings, err := ResolveCommandBindings(DesktopKeyboardLayout, true, merged) + if err != nil { + t.Fatal(err) + } + f9, _ := ParseCommandChord("F9") + want := Command("tentacle/a/one") + if core != nil { + want = DocumentNextHeading + } + if bindings[f9] != want { + t.Fatalf("F9 = %s want %s", bindings[f9], want) + } + quit, _ := ParseCommandChord("Cthulhu+q") + if bindings[quit] != Quit { + t.Fatal("tentacle replaced Quit") + } + laptop, _ := ResolveCommandBindings(LaptopKeyboardLayout, true, merged) + if laptop[f9] != "tentacle/b/two" { + t.Fatal("layouts share reservations") + } + } +} + +func TestTentacleBindingsRejectCoreIdentity(t *testing.T) { + if ValidateTentacleBindings([]BindingOverride{{DesktopKeyboardLayout, "global", Quit, []string{"F9"}}}) == nil { + t.Fatal("accepted core identity") + } + if ValidateBindingOverrides([]BindingOverride{{DesktopKeyboardLayout, "global", "tentacle/a/one", []string{"F9"}}}) == nil { + t.Fatal("persisted runtime registration") + } +} diff --git a/internal/input/version_test.go b/internal/input/version_test.go new file mode 100644 index 0000000..1bec55c --- /dev/null +++ b/internal/input/version_test.go @@ -0,0 +1,17 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package input + +import "testing" + +func TestVersionChord(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + router := NewCommandRouter([]uint32{0xff63}, DefaultCommandBindings(layout)) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle('v', 55, 1, true); !consumed || command != PresentVersion { + t.Fatalf("layout %d: Cthulhu+Shift+V = %v %q", layout, consumed, command) + } + } +} diff --git a/internal/input/window_title_test.go b/internal/input/window_title_test.go new file mode 100644 index 0000000..22d24a6 --- /dev/null +++ b/internal/input/window_title_test.go @@ -0,0 +1,42 @@ +package input + +import "testing" + +func TestWindowTitleBindings(t *testing.T) { + for _, layout := range []KeyboardLayout{DesktopKeyboardLayout, LaptopKeyboardLayout} { + for _, modifierFirst := range []bool{false, true} { + symbol, code := keypadEnterKeySymbol, uint16(104) + if layout == LaptopKeyboardLayout { + symbol, code = '/', 61 + } + bindings, err := ResolveCommandBindings(layout, true, nil) + if err != nil { + t.Fatal(err) + } + router := NewCommandRouter([]uint32{0xff63}, bindings) + router.Handle(0xff63, 118, 0, true) + if consumed, command := router.Handle(symbol, code, 0, true); !consumed || command != PresentWindowTitle { + t.Fatalf("layout %v title press = %v %q", layout, consumed, command) + } + if consumed, command := router.Handle(symbol, code, 0, true); !consumed || command != "" { + t.Fatalf("title repeat = %v %q", consumed, command) + } + keys := []struct { + symbol uint32 + code uint16 + }{{symbol, code}, {0xff63, 118}} + if modifierFirst { + keys[0], keys[1] = keys[1], keys[0] + } + for _, key := range keys { + if consumed, command := router.Handle(key.symbol, key.code, 0, false); !consumed || command != "" { + t.Fatalf("title release = %v %q", consumed, command) + } + } + // The command remains available through the preferences binding editor. + if err := ValidateBindingOverrides([]BindingOverride{{Layout: layout, Scope: "global", Command: PresentWindowTitle, Keys: []string{"Cthulhu+Ctrl+t"}}}); err != nil { + t.Fatal(err) + } + } + } +} diff --git a/internal/interaction/session.go b/internal/interaction/session.go new file mode 100644 index 0000000..00649d6 --- /dev/null +++ b/internal/interaction/session.go @@ -0,0 +1,488 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package interaction implements focus-free controls. It owns no keyboard, +// accessibility objects, output services or callbacks; the reader owns those. +package interaction + +import ( + "errors" + "fmt" + "strings" + "unicode" + "unicode/utf8" +) + +type Kind uint8 + +const ( + List Kind = iota + 1 + Entry + CheckBox + Button +) + +type Item struct { + ID string `json:"id"` + Label string `json:"label"` + Disabled bool `json:"disabled,omitempty"` +} +type Element struct { + ID string `json:"id"` + Label string `json:"label"` + Kind Kind `json:"kind"` + Items []Item `json:"items,omitempty"` + Text string `json:"text,omitempty"` + Checked bool `json:"checked,omitempty"` + Disabled bool `json:"disabled,omitempty"` + Required bool `json:"required,omitempty"` + MaxLength int `json:"max_length,omitempty"` +} +type Form struct { + Title string `json:"title"` + Elements []Element `json:"elements"` +} +type Key uint8 + +const ( + Text Key = iota + Up + Down + Left + Right + Home + End + PageUp + PageDown + Tab + Enter + Escape + Backspace + Delete +) + +type Event struct { + Key Key + Text string + Shift, Control, Alt bool +} +type Presentation struct { + Speech, Braille string + Cursor int +} + +// Effect describes a host operation. Activation does not close the form: the +// caller can validate, replace it with another form, or finish the interaction. +type Effect struct { + Presentation + Activated string + Cancelled, Paste bool + Copy *string +} +type Value struct { + Text string `json:"text,omitempty"` + Selected string `json:"selected,omitempty"` + Checked bool `json:"checked,omitempty"` +} +type elementState struct { + element Element + selected, caret, anchor int + prefix string +} +type Session struct { + title string + elements []elementState + focus int + closed bool +} + +const maxTextLength = 8192 + +func NewSession(form Form) (*Session, error) { + return new_session(form, 256, 64) +} + +// ValidatePreferences shares control validation with internal forms, while +// allowing a native, scrolling page to contain several full voice editors. +func ValidatePreferences(form Form) error { + _, err := new_session(form, 256, 256) + return err +} + +// NewNavigationSession is for core document lists. External forms retain +// their smaller protocol limit. The selected row follows the reading caret. +func NewNavigationSession(title string, items []Item, selected int) (*Session, error) { + session, err := new_session(Form{Title: title, Elements: []Element{{ID: "items", Label: title, Kind: List, Items: items}}}, 65536, 64) + if err == nil && selected >= 0 && selected < len(items) && !items[selected].Disabled { + session.elements[0].selected = selected + } + return session, err +} + +func new_session(form Form, maxItems, maxElements int) (*Session, error) { + if form.Title == "" || len(form.Title) > 1024 || len(form.Elements) == 0 || len(form.Elements) > maxElements { + return nil, fmt.Errorf("a titled form with 1 to %d controls is required", maxElements) + } + session := &Session{title: form.Title, focus: -1} + ids := map[string]bool{} + for _, element := range form.Elements { + if element.ID == "" || len(element.ID) > 1024 || element.Label == "" || len(element.Label) > 1024 || ids[element.ID] || element.Kind < List || element.Kind > Button { + return nil, errors.New("controls need unique IDs, labels and supported kinds") + } + ids[element.ID] = true + if element.MaxLength == 0 { + element.MaxLength = maxTextLength + } + if element.MaxLength < 1 || element.MaxLength > maxTextLength || len([]rune(element.Text)) > element.MaxLength { + return nil, errors.New("invalid entry length") + } + if !utf8.ValidString(element.Text) || strings.ContainsAny(element.Text, "\r\n\x00") { + return nil, errors.New("entries must contain single-line text") + } + for _, character := range element.Text { + if unicode.IsControl(character) { + return nil, errors.New("entries must contain single-line text") + } + } + element.Items = append([]Item(nil), element.Items...) + state := elementState{element: element, selected: -1, caret: len([]rune(element.Text)), anchor: len([]rune(element.Text))} + itemIDs := map[string]bool{} + if len(element.Items) > maxItems { + return nil, errors.New("too many list items") + } + for index, item := range element.Items { + if item.ID == "" || len(item.ID) > 1024 || item.Label == "" || len(item.Label) > 1024 || itemIDs[item.ID] { + return nil, errors.New("list items need unique IDs and labels") + } + itemIDs[item.ID] = true + if state.selected < 0 && !item.Disabled { + state.selected = index + } + } + if element.Kind == List && state.selected < 0 { + state.element.Disabled = true + } + session.elements = append(session.elements, state) + if session.focus < 0 && !state.element.Disabled { + session.focus = len(session.elements) - 1 + } + } + if session.focus < 0 { + return nil, errors.New("form has no enabled controls") + } + return session, nil +} + +func (session *Session) Presentation() Presentation { + if session.closed { + return Presentation{} + } + state := &session.elements[session.focus] + element := state.element + text := element.Label + cursor := -1 + switch element.Kind { + case List: + text += fmt.Sprintf(": %s, %d of %d", element.Items[state.selected].Label, state.selected+1, len(element.Items)) + case Entry: + text += ", edit: " + element.Text + cursor = len([]rune(element.Label+", edit: ")) + state.caret + if state.caret != state.anchor { + text += fmt.Sprintf(" (selected %d characters)", abs(state.caret-state.anchor)) + } + case CheckBox: + if element.Checked { + text += ", checked" + } else { + text += ", unchecked" + } + case Button: + text += ", button" + } + speech := text + if element.Kind == List { + speech = element.Items[state.selected].Label + } + return Presentation{Speech: speech, Braille: text, Cursor: cursor} +} + +func (session *Session) Opening() Presentation { + output := session.Presentation() + if !session.closed && len(session.elements) > 1 && session.elements[session.focus].element.Kind == List { + output.Speech = session.elements[session.focus].element.Label + ". " + output.Speech + } + output.Speech = session.title + ". " + output.Speech + return output +} + +func (session *Session) Values() map[string]Value { + values := make(map[string]Value, len(session.elements)) + for _, state := range session.elements { + value := Value{Text: state.element.Text, Checked: state.element.Checked} + if state.element.Kind == List && state.selected >= 0 { + value.Selected = state.element.Items[state.selected].ID + } + values[state.element.ID] = value + } + return values +} + +func (session *Session) Handle(event Event) Effect { + if session.closed { + return Effect{} + } + if event.Key == Escape { + session.closed = true + return Effect{Cancelled: true} + } + if event.Key == Tab { + step := 1 + if event.Shift { + step = -1 + } + for range len(session.elements) { + session.focus = (session.focus + step + len(session.elements)) % len(session.elements) + if !session.elements[session.focus].element.Disabled { + break + } + } + output := session.Presentation() + // A list in a multi-control form needs its field label when Tab enters + // it. A menu's only control uses its opening title instead. + state := &session.elements[session.focus] + if len(session.elements) > 1 && state.element.Kind == List { + output.Speech = state.element.Label + ". " + output.Speech + } + return Effect{Presentation: output} + } + state := &session.elements[session.focus] + if event.Alt { + return Effect{} + } + if event.Key == Enter || state.element.Kind == Button && event.Key == Text && event.Text == " " && !event.Control { + for _, candidate := range session.elements { + if candidate.element.Kind == Entry && candidate.element.Required && !candidate.element.Disabled && strings.TrimSpace(candidate.element.Text) == "" { + return Effect{Presentation: Presentation{Speech: candidate.element.Label + " is required", Braille: candidate.element.Label + " is required", Cursor: -1}} + } + } + id := state.element.ID + if state.element.Kind == List { + id = state.element.Items[state.selected].ID + } + return Effect{Activated: id} + } + switch state.element.Kind { + case List: + step := 0 + switch event.Key { + case Up: + step = -1 + case Down: + step = 1 + case PageUp: + step = -10 + case PageDown: + step = 10 + case Home: + state.selected = 0 + step = 1 + case End: + state.selected = len(state.element.Items) - 1 + step = -1 + case Text: + if event.Control || event.Text == "" { + return Effect{} + } + prefix := state.prefix + strings.ToLower(event.Text) + if !state.find_prefix(prefix) { + prefix = strings.ToLower(event.Text) + state.find_prefix(prefix) + } + state.prefix = prefix + return Effect{Presentation: session.Presentation()} + default: + return Effect{} + } + state.prefix = "" + if event.Key == Home || event.Key == End { + for state.element.Items[state.selected].Disabled { + state.selected += step + } + } else { + for count := 0; count < abs(step); count++ { + previous := state.selected + for next := previous + sign(step); next >= 0 && next < len(state.element.Items); next += sign(step) { + if !state.element.Items[next].Disabled { + state.selected = next + break + } + } + } + } + case CheckBox: + if event.Key != Text || event.Text != " " || event.Control { + return Effect{} + } + state.element.Checked = !state.element.Checked + case Button: + return Effect{} + case Entry: + return session.edit(event) + } + return Effect{Presentation: session.Presentation()} +} + +func (state *elementState) find_prefix(prefix string) bool { + for offset := 1; offset <= len(state.element.Items); offset++ { + index := (state.selected + offset) % len(state.element.Items) + item := state.element.Items[index] + if !item.Disabled && strings.HasPrefix(strings.ToLower(item.Label), prefix) { + state.selected = index + return true + } + } + return false +} +func sign(value int) int { + if value < 0 { + return -1 + } + return 1 +} +func abs(value int) int { + if value < 0 { + return -value + } + return value +} + +func (session *Session) edit(event Event) Effect { + state := &session.elements[session.focus] + characters := []rune(state.element.Text) + start, end := min(state.caret, state.anchor), max(state.caret, state.anchor) + if event.Control && event.Key == Text { + switch strings.ToLower(event.Text) { + case "a": + state.anchor, state.caret = 0, len(characters) + output := session.Presentation() + output.Speech = "Selected all" + return Effect{Presentation: output} + case "v": + return Effect{Paste: true} + case "c", "x": + if start == end { + return Effect{} + } + text := string(characters[start:end]) + // Cutting is completed by the host only after clipboard write succeeds. + return Effect{Copy: &text} + default: + return Effect{} + } + } + if event.Key == Left || event.Key == Right || event.Key == Home || event.Key == End { + next := state.caret + switch event.Key { + case Left: + if !event.Shift && start != end { + next = start + } else { + next = max(0, next-1) + if event.Control { + for next > 0 && unicode.IsSpace(characters[next]) { + next-- + } + for next > 0 && !unicode.IsSpace(characters[next-1]) { + next-- + } + } + } + case Right: + if !event.Shift && start != end { + next = end + } else { + next = min(len(characters), next+1) + if event.Control { + for next < len(characters) && !unicode.IsSpace(characters[next]) { + next++ + } + for next < len(characters) && unicode.IsSpace(characters[next]) { + next++ + } + } + } + case Home: + next = 0 + case End: + next = len(characters) + } + state.caret = next + if !event.Shift { + state.anchor = next + } + output := session.Presentation() + if next == len(characters) { + output.Speech = "End of text" + } else { + output.Speech = string(characters[next]) + } + if event.Shift { + output.Speech += ", selected" + } + return Effect{Presentation: output} + } + if event.Key == Backspace || event.Key == Delete { + if start == end { + if event.Key == Backspace { + start = max(0, start-1) + } else { + end = min(len(characters), end+1) + } + } + if start == end { + return Effect{} + } + removed := string(characters[start:end]) + state.element.Text = string(append(characters[:start], characters[end:]...)) + state.caret, state.anchor = start, start + output := session.Presentation() + output.Speech = "Deleted " + removed + return Effect{Presentation: output} + } + if event.Key == Text && event.Text != "" && !event.Control { + return session.Insert(event.Text) + } + return Effect{} +} + +// Insert handles typing and paste atomically; invalid/oversized input leaves +// the field and selection untouched. +func (session *Session) Insert(text string) Effect { + if session.closed { + return Effect{} + } + state := &session.elements[session.focus] + if state.element.Kind != Entry { + return Effect{} + } + if !utf8.ValidString(text) { + return Effect{Presentation: Presentation{Speech: "Invalid text", Braille: "Invalid text", Cursor: -1}} + } + characters := []rune(state.element.Text) + start, end := min(state.caret, state.anchor), max(state.caret, state.anchor) + inserted := []rune(text) + for _, character := range inserted { + if unicode.IsControl(character) { + return Effect{Presentation: Presentation{Speech: "Only single-line text is accepted", Braille: "Only single-line text is accepted", Cursor: -1}} + } + } + if len(characters)-(end-start)+len(inserted) > state.element.MaxLength { + return Effect{Presentation: Presentation{Speech: "Text limit reached", Braille: "Text limit reached", Cursor: -1}} + } + state.element.Text = string(characters[:start]) + text + string(characters[end:]) + state.caret, state.anchor = start+len(inserted), start+len(inserted) + output := session.Presentation() + output.Speech = text + return Effect{Presentation: output} +} diff --git a/internal/interaction/session_test.go b/internal/interaction/session_test.go new file mode 100644 index 0000000..5a28cc5 --- /dev/null +++ b/internal/interaction/session_test.go @@ -0,0 +1,191 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package interaction + +import ( + "strconv" + "strings" + "testing" +) + +func TestNavigationListsRetainExternalFormLimit(t *testing.T) { + items := make([]Item, 300) + for index := range items { + items[index] = Item{ID: strconv.Itoa(index), Label: "Example item"} + } + if _, err := NewSession(Form{Title: "External form", Elements: []Element{{ID: "items", Label: "Items", Kind: List, Items: items}}}); err == nil { + t.Fatal("external form exceeded its protocol limit") + } + session, err := NewNavigationSession("Links", items, 299) + if err != nil { + t.Fatal(err) + } + if effect := session.Handle(Event{Key: Enter}); effect.Activated != "299" { + t.Fatalf("lost initial selection: %+v", effect) + } +} + +func TestListNavigationAndIndependentSessions(t *testing.T) { + form := Form{Title: "Actions", Elements: []Element{{ID: "actions", Label: "Actions", Kind: List, Items: []Item{{ID: "click", Label: "Click"}, {ID: "skip", Label: "Unavailable", Disabled: true}, {ID: "press", Label: "Press"}, {ID: "ancestor", Label: "Click ancestor"}}}}} + first, err := NewSession(form) + if err != nil { + t.Fatal(err) + } + second, _ := NewSession(form) + if opening := first.Opening().Speech; opening != "Actions. Click" { + t.Fatalf("opening speech = %q", opening) + } + if moved := first.Handle(Event{Key: Down}).Speech; moved != "Press" { + t.Fatalf("option speech = %q", moved) + } + if effect := first.Handle(Event{Key: Enter}); effect.Activated != "press" { + t.Fatalf("selection = %+v", effect) + } + if second.Handle(Event{Key: Enter}).Activated != "click" { + t.Fatal("sessions share state") + } + first.Handle(Event{Key: End}) + first.Handle(Event{Key: Down}) + if first.Handle(Event{Key: Enter}).Activated != "ancestor" { + t.Fatal("boundary moved selection") + } + first.Handle(Event{Key: Home}) + first.Handle(Event{Text: "p"}) + if first.Handle(Event{Key: Enter}).Activated != "press" { + t.Fatal("typeahead failed") + } + if !first.Handle(Event{Key: Escape}).Cancelled || first.Handle(Event{Key: Enter}).Activated != "" { + t.Fatal("cancelled session remained usable") + } + form.Elements[0].Items[0].Label = "Changed" + if !strings.Contains(second.Presentation().Speech, "Click") { + t.Fatal("caller mutation changed session") + } +} + +func TestCallerSuppliedMenuTitleAndFormListLabel(t *testing.T) { + menu, err := NewSession(Form{Title: "Wormhole Menu", Elements: []Element{{ID: "choices", Label: "Options", Kind: List, Items: []Item{{ID: "send", Label: "Send focused item"}, {ID: "receive", Label: "Receive file"}}}}}) + if err != nil { + t.Fatal(err) + } + if opening := menu.Opening().Speech; opening != "Wormhole Menu. Send focused item" { + t.Fatalf("custom title = %q", opening) + } + if moved := menu.Handle(Event{Key: Down}).Speech; moved != "Receive file" { + t.Fatalf("custom menu option = %q", moved) + } + if focus := menu.Handle(Event{Key: Tab}).Speech; focus != "Receive file" { + t.Fatalf("menu repeated title on Tab: %q", focus) + } + form, _ := NewSession(Form{Title: "Example", Elements: []Element{{ID: "code", Label: "Code", Kind: Entry}, {ID: "method", Label: "Method", Kind: List, Items: []Item{{ID: "send", Label: "Send"}}}}}) + if focus := form.Handle(Event{Key: Tab}).Speech; focus != "Method. Send" { + t.Fatalf("form list lost its field label: %q", focus) + } +} + +func TestFormTraversalEditingAndValidation(t *testing.T) { + session, err := NewSession(Form{Title: "Receive", Elements: []Element{{ID: "code", Label: "Code", Kind: Entry, Required: true, MaxLength: 8}, {ID: "disabled", Label: "Disabled", Kind: Button, Disabled: true}, {ID: "keep", Label: "Keep", Kind: CheckBox}, {ID: "submit", Label: "Receive", Kind: Button}}}) + if err != nil { + t.Fatal(err) + } + if !strings.Contains(session.Handle(Event{Key: Enter}).Speech, "required") { + t.Fatal("missing required validation") + } + session.Handle(Event{Text: "ab猫"}) + session.Handle(Event{Key: Left, Shift: true}) + session.Insert("é") + if session.Values()["code"].Text != "abé" { + t.Fatal("Unicode selection replacement") + } + session.Handle(Event{Key: Home}) + session.Handle(Event{Key: Delete}) + if session.Values()["code"].Text != "bé" { + t.Fatal("Unicode deletion") + } + session.Handle(Event{Text: "a", Control: true}) + if effect := session.Handle(Event{Text: "c", Control: true}); effect.Copy == nil || *effect.Copy != "bé" { + t.Fatal("copy selection") + } + if !session.Handle(Event{Text: "v", Control: true}).Paste { + t.Fatal("paste host request missing") + } + before := session.Values()["code"].Text + if !strings.Contains(session.Insert("too long to fit").Speech, "limit") || session.Values()["code"].Text != before { + t.Fatal("oversized insertion changed field") + } + if !strings.Contains(session.Insert("bad\ntext").Speech, "single-line") { + t.Fatal("multiline paste accepted") + } + if session.Insert(string([]byte{0xff})).Speech != "Invalid text" || session.Values()["code"].Text != before { + t.Fatal("invalid UTF-8 paste changed entry") + } + session.Handle(Event{Key: Tab}) + session.Handle(Event{Text: " "}) + if !session.Values()["keep"].Checked { + t.Fatal("checkbox not toggled / disabled control took focus") + } + session.Handle(Event{Key: Tab}) + if session.Handle(Event{Key: Enter}).Activated != "submit" { + t.Fatal("button did not submit") + } + session.Handle(Event{Key: Tab}) + if !strings.Contains(session.Presentation().Speech, "Code") { + t.Fatal("Tab did not wrap") + } + session.Handle(Event{Key: Tab, Shift: true}) + if session.Handle(Event{Key: Enter}).Activated != "submit" { + t.Fatal("Shift Tab did not wrap") + } +} + +func TestWordMovementAndSelection(t *testing.T) { + session, _ := NewSession(Form{Title: "Edit", Elements: []Element{{ID: "text", Label: "Text", Kind: Entry, Text: "one two 猫"}}}) + session.Handle(Event{Key: Left, Control: true, Shift: true}) + if effect := session.Handle(Event{Text: "c", Control: true}); effect.Copy == nil || *effect.Copy != "猫" { + t.Fatal("word selection") + } + session.Handle(Event{Key: Backspace}) + if session.Values()["text"].Text != "one two " { + t.Fatal("word selection deletion") + } + session.Handle(Event{Key: Home}) + session.Handle(Event{Key: Right, Control: true}) + session.Insert("é") + if session.Values()["text"].Text != "one étwo " { + t.Fatalf("word movement = %+v", session.Values()) + } +} + +func TestInvalidForms(t *testing.T) { + for _, form := range []Form{{}, {Title: "Empty", Elements: []Element{{ID: "list", Label: "List", Kind: List}}}, {Title: "Duplicate", Elements: []Element{{ID: "same", Label: "First", Kind: Button}, {ID: "same", Label: "Second", Kind: Entry}}}} { + if _, err := NewSession(form); err == nil { + t.Fatalf("accepted invalid form %+v", form) + } + } +} + +func TestButtonActivationValidatesRequiredEntries(t *testing.T) { + for _, event := range []Event{{Key: Enter}, {Key: Text, Text: " "}} { + t.Run(map[Key]string{Enter: "Enter", Text: "Space"}[event.Key], func(t *testing.T) { + session, err := NewSession(Form{Title: "Receive", Elements: []Element{ + {ID: "code", Label: "Code", Kind: Entry, Required: true}, + {ID: "submit", Label: "Receive", Kind: Button}, + }}) + if err != nil { + t.Fatal(err) + } + session.Handle(Event{Key: Tab}) + if effect := session.Handle(event); effect.Activated != "" || effect.Speech != "Code is required" { + t.Fatalf("empty required field accepted: %+v", effect) + } + session.Handle(Event{Key: Tab, Shift: true}) + session.Insert("1234") + session.Handle(Event{Key: Tab}) + if effect := session.Handle(event); effect.Activated != "submit" { + t.Fatalf("completed form rejected: %+v", effect) + } + }) + } +} diff --git a/internal/lifecycle/lifecycle.go b/internal/lifecycle/lifecycle.go new file mode 100644 index 0000000..b22e97a --- /dev/null +++ b/internal/lifecycle/lifecycle.go @@ -0,0 +1,154 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package lifecycle + +import ( + "context" + "errors" + "fmt" + "log/slog" +) + +type State string + +const ( + StateNew State = "New" + StateStarting State = "Starting" + StateRunning State = "Running" + StateStopping State = "Stopping" + StateStopped State = "Stopped" + StateFailed State = "Failed" +) + +type Service struct { + Name string + Start func(context.Context) error + Stop func(context.Context) error +} + +type Runner struct { + state State + services []Service + started []int + logger *slog.Logger +} + +func New(services ...Service) (*Runner, error) { + return NewWithLogger(nil, services...) +} + +func NewWithLogger(logger *slog.Logger, services ...Service) (*Runner, error) { + names := make(map[string]struct{}, len(services)) + for index, service := range services { + switch { + case service.Name == "": + return nil, fmt.Errorf("service %d has no name", index) + case service.Start == nil: + return nil, fmt.Errorf("service %q has no start function", service.Name) + case service.Stop == nil: + return nil, fmt.Errorf("service %q has no stop function", service.Name) + } + if _, exists := names[service.Name]; exists { + return nil, fmt.Errorf("duplicate service name %q", service.Name) + } + names[service.Name] = struct{}{} + } + return &Runner{ + state: StateNew, + services: append([]Service(nil), services...), + logger: logger, + }, nil +} + +func (runner *Runner) State() State { + return runner.state +} + +func (runner *Runner) Start(ctx context.Context) error { + if ctx == nil { + return errors.New("lifecycle start requires a non-nil context") + } + switch runner.state { + case StateNew: + case StateRunning, StateStarting, StateStopping, StateStopped, StateFailed: + return fmt.Errorf("cannot start from state %s", runner.state) + } + + runner.state = StateStarting + for index, service := range runner.services { + if err := ctx.Err(); err != nil { + return runner.failStartup(fmt.Errorf("start %q canceled: %w", service.Name, err)) + } + if err := service.Start(ctx); err != nil { + return runner.failStartup(fmt.Errorf("start %q: %w", service.Name, err)) + } + runner.started = append(runner.started, index) + } + runner.state = StateRunning + return nil +} + +func (runner *Runner) Stop(ctx context.Context) error { + if ctx == nil { + return errors.New("lifecycle stop requires a non-nil context") + } + switch runner.state { + case StateNew: + runner.state = StateStopped + return nil + case StateRunning: + case StateStopped: + return nil + case StateStarting, StateStopping, StateFailed: + return fmt.Errorf("cannot stop from state %s", runner.state) + } + + runner.state = StateStopping + stopError := runner.stopStartedServices(ctx) + runner.state = StateStopped + return stopError +} + +func (runner *Runner) failStartup(startError error) error { + runner.state = StateFailed + runner.state = StateStopping + stopError := runner.stopStartedServices(context.Background()) + runner.state = StateStopped + return errors.Join(startError, stopError) +} + +func (runner *Runner) stopStartedServices(ctx context.Context) error { + var stopErrors []error + for index := len(runner.started) - 1; index >= 0; index-- { + serviceIndex := runner.started[index] + service := runner.services[serviceIndex] + if runner.logger != nil { + runner.logger.Debug("lifecycle service stopping", "service", service.Name) + } + if err := service.Stop(ctx); err != nil { + stopErrors = append(stopErrors, fmt.Errorf("stop %q: %w", service.Name, err)) + if runner.logger != nil { + runner.logger.Warn("lifecycle service stop failed", "service", service.Name, "error", err) + } + } else if runner.logger != nil { + runner.logger.Debug("lifecycle service stopped", "service", service.Name) + } + } + runner.started = nil + return errors.Join(stopErrors...) +} diff --git a/internal/lifecycle/lifecycle_test.go b/internal/lifecycle/lifecycle_test.go new file mode 100644 index 0000000..d3f9f39 --- /dev/null +++ b/internal/lifecycle/lifecycle_test.go @@ -0,0 +1,176 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package lifecycle + +import ( + "bytes" + "context" + "errors" + "log/slog" + "strings" + "testing" +) + +func TestStartAndStopReverseOrder(t *testing.T) { + var events []string + runner, err := New( + Service{ + Name: "first", + Start: func(context.Context) error { events = append(events, "start first"); return nil }, + Stop: func(context.Context) error { events = append(events, "stop first"); return nil }, + }, + Service{ + Name: "second", + Start: func(context.Context) error { events = append(events, "start second"); return nil }, + Stop: func(context.Context) error { events = append(events, "stop second"); return nil }, + }, + ) + if err != nil { + t.Fatalf("New: %v", err) + } + if err := runner.Start(context.Background()); err != nil { + t.Fatalf("Start: %v", err) + } + if runner.State() != StateRunning { + t.Fatalf("state after start = %s, want %s", runner.State(), StateRunning) + } + if err := runner.Stop(context.Background()); err != nil { + t.Fatalf("Stop: %v", err) + } + want := strings.Join([]string{"start first", "start second", "stop second", "stop first"}, ",") + if got := strings.Join(events, ","); got != want { + t.Fatalf("events = %q, want %q", got, want) + } + if runner.State() != StateStopped { + t.Fatalf("state after stop = %s, want %s", runner.State(), StateStopped) + } +} + +func TestStartupFailureStopsStartedServices(t *testing.T) { + startFailure := errors.New("start failed") + stopFailure := errors.New("stop failed") + var stopped bool + runner, err := New( + Service{ + Name: "ready", + Start: func(context.Context) error { return nil }, + Stop: func(context.Context) error { + stopped = true + return stopFailure + }, + }, + Service{ + Name: "broken", + Start: func(context.Context) error { return startFailure }, + Stop: func(context.Context) error { return nil }, + }, + ) + if err != nil { + t.Fatalf("New: %v", err) + } + + err = runner.Start(context.Background()) + if !errors.Is(err, startFailure) || !errors.Is(err, stopFailure) { + t.Fatalf("Start error = %v, want both start and stop failures", err) + } + if !stopped { + t.Fatal("started service was not stopped") + } + if runner.State() != StateStopped { + t.Fatalf("state after failed start = %s, want %s", runner.State(), StateStopped) + } +} + +func TestCanceledStartDoesNotCallService(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + var called bool + runner, err := New(Service{ + Name: "service", + Start: func(context.Context) error { + called = true + return nil + }, + Stop: func(context.Context) error { return nil }, + }) + if err != nil { + t.Fatalf("New: %v", err) + } + err = runner.Start(ctx) + if !errors.Is(err, context.Canceled) { + t.Fatalf("Start error = %v, want context.Canceled", err) + } + if called { + t.Fatal("service start was called after cancellation") + } + if runner.State() != StateStopped { + t.Fatalf("state after canceled start = %s, want %s", runner.State(), StateStopped) + } +} + +func TestStopIsIdempotent(t *testing.T) { + runner, err := New(Service{ + Name: "service", + Start: func(context.Context) error { return nil }, + Stop: func(context.Context) error { return nil }, + }) + if err != nil { + t.Fatalf("New: %v", err) + } + if err := runner.Start(context.Background()); err != nil { + t.Fatalf("Start: %v", err) + } + if err := runner.Stop(context.Background()); err != nil { + t.Fatalf("first Stop: %v", err) + } + if err := runner.Stop(context.Background()); err != nil { + t.Fatalf("second Stop: %v", err) + } +} + +func TestStopLogsCompletedServiceStages(t *testing.T) { + var logs bytes.Buffer + logger := slog.New(slog.NewTextHandler(&logs, &slog.HandlerOptions{Level: slog.LevelDebug})) + runner, err := NewWithLogger(logger, Service{ + Name: "service", + Start: func(context.Context) error { return nil }, + Stop: func(context.Context) error { return nil }, + }) + if err != nil { + t.Fatalf("NewWithLogger: %v", err) + } + if err := runner.Start(context.Background()); err != nil { + t.Fatalf("Start: %v", err) + } + if err := runner.Stop(context.Background()); err != nil { + t.Fatalf("Stop: %v", err) + } + + output := logs.String() + if !strings.Contains(output, "lifecycle service stopping") || + !strings.Contains(output, "lifecycle service stopped") || + !strings.Contains(output, "service") { + t.Fatalf("stop logs = %q, want stopping and stopped records for service", output) + } +} + +func TestNewRejectsInvalidService(t *testing.T) { + if _, err := New(Service{Name: "invalid"}); err == nil { + t.Fatal("New accepted a service without functions") + } +} diff --git a/internal/logging/async.go b/internal/logging/async.go new file mode 100644 index 0000000..c982fe7 --- /dev/null +++ b/internal/logging/async.go @@ -0,0 +1,405 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package logging + +import ( + "context" + "errors" + "fmt" + "io" + "log/slog" + "os" + "sync" + "sync/atomic" + "time" +) + +const ( + defaultDiagnosticsCapacity = 256 + defaultStopTimeout = 2 * time.Second + defaultCancelGrace = 100 * time.Millisecond +) + +type DiagnosticsWriter interface { + Write([]byte) (int, error) + Cancel() error + Close() error +} + +type AsyncOptions struct { + Options + Capacity int + StopTimeout time.Duration + CancelGrace time.Duration +} + +type diagnosticRecord struct { + data []byte + critical bool +} + +type Diagnostics struct { + writer DiagnosticsWriter + formatter *Handler + logger *slog.Logger + queue []diagnosticRecord + wake chan struct{} + stopSignal chan struct{} + done chan struct{} + mutex sync.Mutex + stopOnce sync.Once + errorsMutex sync.Mutex + stopMutex sync.Mutex + writeErrors []error + stopError error + stopSet bool + dropped atomic.Uint64 + reported atomic.Uint64 + capacity int + stopTimeout time.Duration + cancelGrace time.Duration +} + +func NewAsync(writer DiagnosticsWriter, options AsyncOptions) *Diagnostics { + if writer == nil { + writer = NewPassthroughWriter(nil) + } + if options.Capacity <= 0 { + options.Capacity = defaultDiagnosticsCapacity + } + if options.StopTimeout <= 0 { + options.StopTimeout = defaultStopTimeout + } + if options.CancelGrace <= 0 { + options.CancelGrace = defaultCancelGrace + } + diagnostics := &Diagnostics{ + writer: writer, + formatter: newHandler(nil, options.Options), + queue: make([]diagnosticRecord, 0, options.Capacity), + wake: make(chan struct{}, 1), + stopSignal: make(chan struct{}), + done: make(chan struct{}), + capacity: options.Capacity, + stopTimeout: options.StopTimeout, + cancelGrace: options.CancelGrace, + } + diagnostics.logger = slog.New(&asyncHandler{ + diagnostics: diagnostics, + base: diagnostics.formatter, + }) + go diagnostics.run() + return diagnostics +} + +func (diagnostics *Diagnostics) Logger() *slog.Logger { + return diagnostics.logger +} + +func (diagnostics *Diagnostics) Dropped() uint64 { + return diagnostics.dropped.Load() +} + +func (diagnostics *Diagnostics) Stop(ctx context.Context) error { + if ctx == nil { + return errors.New("diagnostics stop requires a non-nil context") + } + diagnostics.signalStop() + + stopContext, cancel := context.WithTimeout(ctx, diagnostics.stopTimeout) + defer cancel() + if !diagnostics.waitOrCancel(stopContext) { + diagnostics.setStopError(fmt.Errorf("flush diagnostics: %w", stopContext.Err())) + return diagnostics.stopErrorValue() + } + diagnostics.setStopError(errors.Join(diagnostics.writeErrorsValue()...)) + return diagnostics.stopErrorValue() +} + +func (diagnostics *Diagnostics) signalStop() { + diagnostics.stopOnce.Do(func() { + close(diagnostics.stopSignal) + diagnostics.wakeup() + }) +} + +func (diagnostics *Diagnostics) waitOrCancel(ctx context.Context) bool { + deadline, hasDeadline := ctx.Deadline() + if hasDeadline { + cancelDelay := time.Until(deadline) - diagnostics.cancelGrace + if cancelDelay > 0 { + timer := time.NewTimer(cancelDelay) + select { + case <-diagnostics.done: + timer.Stop() + return true + case <-timer.C: + } + } + } else { + select { + case <-diagnostics.done: + return true + case <-time.After(diagnostics.cancelGrace): + } + } + if err := diagnostics.writer.Cancel(); err != nil { + diagnostics.appendWriteError(fmt.Errorf("cancel diagnostics writer: %w", err)) + } + select { + case <-diagnostics.done: + return true + case <-ctx.Done(): + return false + } +} + +func (diagnostics *Diagnostics) run() { + defer close(diagnostics.done) + for { + diagnostics.mutex.Lock() + if len(diagnostics.queue) == 0 { + if !diagnostics.accepting() { + diagnostics.mutex.Unlock() + diagnostics.reportDrops() + diagnostics.mutex.Lock() + if len(diagnostics.queue) == 0 { + diagnostics.mutex.Unlock() + break + } + } else { + wake := diagnostics.wake + diagnostics.mutex.Unlock() + select { + case <-wake: + case <-diagnostics.stopSignal: + } + continue + } + } + record := diagnostics.queue[0] + diagnostics.queue = diagnostics.queue[1:] + diagnostics.mutex.Unlock() + + if _, err := diagnostics.writer.Write(record.data); err != nil { + diagnostics.appendWriteError(fmt.Errorf("write diagnostics: %w", err)) + } + diagnostics.reportDrops() + } + if err := diagnostics.writer.Close(); err != nil { + diagnostics.appendWriteError(fmt.Errorf("close diagnostics writer: %w", err)) + } +} + +func (diagnostics *Diagnostics) accepting() bool { + select { + case <-diagnostics.stopSignal: + return false + default: + return true + } +} + +func (diagnostics *Diagnostics) enqueue(record diagnosticRecord) { + diagnostics.mutex.Lock() + if !diagnostics.accepting() { + diagnostics.mutex.Unlock() + diagnostics.dropped.Add(1) + return + } + if len(diagnostics.queue) == diagnostics.capacity { + diagnostics.dropped.Add(1) + var admitted bool + diagnostics.queue, admitted = makeRoom(diagnostics.queue, record.critical) + if !admitted { + diagnostics.mutex.Unlock() + return + } + } + diagnostics.queue = append(diagnostics.queue, record) + diagnostics.mutex.Unlock() + diagnostics.wakeup() +} + +func makeRoom(queue []diagnosticRecord, incomingCritical bool) ([]diagnosticRecord, bool) { + for index, record := range queue { + if !record.critical { + copy(queue[index:], queue[index+1:]) + queue[len(queue)-1] = diagnosticRecord{} + return queue[:len(queue)-1], true + } + } + if !incomingCritical { + return queue, false + } + copy(queue, queue[1:]) + queue[len(queue)-1] = diagnosticRecord{} + return queue[:len(queue)-1], true +} + +func (diagnostics *Diagnostics) reportDrops() { + total := diagnostics.dropped.Load() + reported := diagnostics.reported.Swap(total) + if total == reported { + return + } + record := slog.NewRecord(time.Now(), slog.LevelWarn, "diagnostics queue overflow", 0) + record.AddAttrs( + slog.Uint64("dropped_messages", total-reported), + slog.Uint64("total_dropped_messages", total), + ) + if _, err := diagnostics.writer.Write(diagnostics.formatter.format(record)); err != nil { + diagnostics.appendWriteError(fmt.Errorf("write diagnostics overflow report: %w", err)) + } +} + +func (diagnostics *Diagnostics) wakeup() { + select { + case diagnostics.wake <- struct{}{}: + default: + } +} + +func (diagnostics *Diagnostics) appendWriteError(err error) { + diagnostics.errorsMutex.Lock() + defer diagnostics.errorsMutex.Unlock() + diagnostics.writeErrors = append(diagnostics.writeErrors, err) +} + +func (diagnostics *Diagnostics) writeErrorsValue() []error { + diagnostics.errorsMutex.Lock() + defer diagnostics.errorsMutex.Unlock() + return append([]error(nil), diagnostics.writeErrors...) +} + +func (diagnostics *Diagnostics) setStopError(err error) { + diagnostics.stopMutex.Lock() + defer diagnostics.stopMutex.Unlock() + if !diagnostics.stopSet { + diagnostics.stopError = err + diagnostics.stopSet = true + } +} + +func (diagnostics *Diagnostics) stopErrorValue() error { + diagnostics.stopMutex.Lock() + defer diagnostics.stopMutex.Unlock() + return diagnostics.stopError +} + +type asyncHandler struct { + diagnostics *Diagnostics + base *Handler +} + +func (handler *asyncHandler) Enabled(ctx context.Context, level slog.Level) bool { + return handler.base.Enabled(ctx, level) +} + +func (handler *asyncHandler) Handle(_ context.Context, record slog.Record) error { + if !handler.base.Enabled(context.Background(), record.Level) { + return nil + } + handler.diagnostics.enqueue(diagnosticRecord{ + data: handler.base.format(record), + critical: record.Level >= slog.LevelWarn, + }) + return nil +} + +func (handler *asyncHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + clone := *handler + clone.base = handler.base.WithAttrs(attrs).(*Handler) + return &clone +} + +func (handler *asyncHandler) WithGroup(name string) slog.Handler { + clone := *handler + clone.base = handler.base.WithGroup(name).(*Handler) + return &clone +} + +type passthroughWriter struct { + writer io.Writer +} + +func NewPassthroughWriter(writer io.Writer) DiagnosticsWriter { + if writer == nil { + writer = io.Discard + } + return passthroughWriter{writer: writer} +} + +func (writer passthroughWriter) Write(data []byte) (int, error) { + return writer.writer.Write(data) +} + +func (writer passthroughWriter) Cancel() error { return nil } + +func (writer passthroughWriter) Close() error { return nil } + +type fileWriter struct { + file *os.File + fallback io.Writer + closeOnce sync.Once +} + +func OpenFile(path string, fallback io.Writer, appendLog bool) (DiagnosticsWriter, error) { + if path == "" || path == "." || path == ".." { + return nil, errors.New("invalid diagnostics file path") + } + // Keep writes at the end even after truncation: an outgoing reader may + // still append its shutdown records while --replace is in progress. + flags := os.O_WRONLY | os.O_CREATE | os.O_APPEND + if !appendLog { + flags |= os.O_TRUNC + } + file, err := os.OpenFile(path, flags, 0o600) + if err != nil { + return nil, fmt.Errorf("open diagnostics file: %w", err) + } + return &fileWriter{file: file, fallback: fallback}, nil +} + +func (writer *fileWriter) Write(data []byte) (int, error) { + if writer.fallback != nil { + if _, err := writer.fallback.Write(data); err != nil { + return 0, fmt.Errorf("write diagnostics fallback: %w", err) + } + } + return writer.file.Write(data) +} + +func (writer *fileWriter) Cancel() error { + return writer.close() +} + +func (writer *fileWriter) Close() error { + return writer.close() +} + +func (writer *fileWriter) close() error { + var closeError error + writer.closeOnce.Do(func() { + closeError = writer.file.Close() + }) + if errors.Is(closeError, os.ErrClosed) { + return nil + } + return closeError +} diff --git a/internal/logging/async_test.go b/internal/logging/async_test.go new file mode 100644 index 0000000..2a75b61 --- /dev/null +++ b/internal/logging/async_test.go @@ -0,0 +1,388 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package logging + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "log/slog" + "os" + "path/filepath" + "strings" + "sync" + "testing" + "time" +) + +type controlledWriter struct { + mutex sync.Mutex + output bytes.Buffer + started chan struct{} + startOnce sync.Once + release chan struct{} + canceled chan struct{} + cancelOnce sync.Once + writeError error + autoRelease bool + closed bool +} + +func newControlledWriter() *controlledWriter { + return &controlledWriter{ + started: make(chan struct{}), + release: make(chan struct{}, 1), + canceled: make(chan struct{}), + } +} + +func (writer *controlledWriter) Write(data []byte) (int, error) { + writer.startOnce.Do(func() { close(writer.started) }) + select { + case <-writer.release: + case <-writer.canceled: + return 0, errors.New("diagnostics writer canceled") + } + if writer.autoRelease { + select { + case writer.release <- struct{}{}: + default: + } + } + writer.mutex.Lock() + defer writer.mutex.Unlock() + if writer.writeError != nil { + return 0, writer.writeError + } + return writer.output.Write(data) +} + +func (writer *controlledWriter) Cancel() error { + writer.cancelOnce.Do(func() { close(writer.canceled) }) + return nil +} + +func (writer *controlledWriter) Close() error { + writer.mutex.Lock() + defer writer.mutex.Unlock() + writer.closed = true + return nil +} + +func (writer *controlledWriter) releaseWrites(count int) { + for index := 0; index < count; index++ { + writer.release <- struct{}{} + } +} + +func (writer *controlledWriter) lines() []string { + writer.mutex.Lock() + defer writer.mutex.Unlock() + return strings.Split(strings.TrimSpace(writer.output.String()), "\n") +} + +func messageNames(t *testing.T, lines []string) []string { + t.Helper() + messages := make([]string, 0, len(lines)) + for _, line := range lines { + if line == "" { + continue + } + var record map[string]any + if err := json.Unmarshal([]byte(line), &record); err != nil { + t.Fatalf("invalid diagnostics JSON %q: %v", line, err) + } + messages = append(messages, fmt.Sprint(record["message"])) + } + return messages +} + +func TestAsyncLoggingDoesNotBlockOnBlockedWriter(t *testing.T) { + writer := newControlledWriter() + diagnostics := NewAsync(writer, AsyncOptions{Options: Options{Level: slog.LevelDebug}, Capacity: 4, StopTimeout: 100 * time.Millisecond, CancelGrace: 10 * time.Millisecond}) + logger := diagnostics.Logger() + completed := make(chan struct{}) + go func() { + logger.Debug("accessibility event") + close(completed) + }() + + select { + case <-completed: + case <-time.After(time.Second): + t.Fatal("slog call blocked on diagnostics writer") + } + if diagnostics.Dropped() != 0 { + t.Fatalf("dropped messages = %d, want 0", diagnostics.Dropped()) + } + writer.Cancel() + if err := diagnostics.Stop(context.Background()); err == nil || !strings.Contains(err.Error(), "diagnostics writer canceled") { + t.Fatalf("Stop error = %v, want canceled writer error", err) + } +} + +func TestAsyncLoggingFlushesInOrder(t *testing.T) { + writer := newControlledWriter() + diagnostics := NewAsync(writer, AsyncOptions{Capacity: 8, StopTimeout: time.Second, CancelGrace: 10 * time.Millisecond}) + logger := diagnostics.Logger() + for _, message := range []string{"first", "second", "third", "fourth"} { + logger.Info(message) + } + writer.releaseWrites(4) + + if err := diagnostics.Stop(context.Background()); err != nil { + t.Fatalf("Stop: %v", err) + } + got := messageNames(t, writer.lines()) + want := []string{"first", "second", "third", "fourth"} + if fmt.Sprint(got) != fmt.Sprint(want) { + t.Fatalf("messages = %v, want %v", got, want) + } +} + +func TestAsyncLoggingSaturationKeepsCriticalMessagesAndReportsDrops(t *testing.T) { + writer := newControlledWriter() + writer.autoRelease = true + diagnostics := NewAsync(writer, AsyncOptions{Options: Options{Level: slog.LevelDebug}, Capacity: 2, StopTimeout: time.Second, CancelGrace: 10 * time.Millisecond}) + logger := diagnostics.Logger() + logger.Debug("debug 1") + select { + case <-writer.started: + case <-time.After(time.Second): + t.Fatal("diagnostics writer did not start") + } + logger.Debug("debug 2") + logger.Debug("debug 3") + logger.Error("critical message") + writer.releaseWrites(1) + + if err := diagnostics.Stop(context.Background()); err != nil { + t.Fatalf("Stop: %v", err) + } + messages := messageNames(t, writer.lines()) + joined := strings.Join(messages, "\n") + if !strings.Contains(joined, "critical message") { + t.Fatalf("critical message was dropped: %q", joined) + } + if strings.Contains(joined, "debug 2") { + t.Fatalf("oldest queued debug message was retained: %q", joined) + } + if !strings.Contains(joined, "diagnostics queue overflow") { + t.Fatalf("overflow report missing: %q", joined) + } + if diagnostics.Dropped() == 0 { + t.Fatal("drop count was not observable") + } +} + +func TestAsyncLoggingNoncriticalRecordCannotEvictCriticalRecords(t *testing.T) { + writer := newControlledWriter() + writer.autoRelease = true + diagnostics := NewAsync(writer, AsyncOptions{Options: Options{Level: slog.LevelDebug}, Capacity: 2, StopTimeout: time.Second, CancelGrace: 10 * time.Millisecond}) + logger := diagnostics.Logger() + logger.Debug("active writer") + select { + case <-writer.started: + case <-time.After(time.Second): + t.Fatal("diagnostics writer did not start") + } + logger.Warn("warning 1") + logger.Error("error 2") + logger.Debug("discarded debug") + writer.releaseWrites(1) + + if err := diagnostics.Stop(context.Background()); err != nil { + t.Fatalf("Stop: %v", err) + } + joined := strings.Join(messageNames(t, writer.lines()), "\n") + for _, message := range []string{"warning 1", "error 2", "diagnostics queue overflow"} { + if !strings.Contains(joined, message) { + t.Fatalf("%q missing from diagnostics: %q", message, joined) + } + } + if strings.Contains(joined, "discarded debug") { + t.Fatalf("noncritical record displaced a critical record: %q", joined) + } +} + +type failingWriter struct{} + +func (failingWriter) Write([]byte) (int, error) { + return 0, errors.New("write failed") +} + +func (failingWriter) Cancel() error { return nil } +func (failingWriter) Close() error { return nil } + +func TestAsyncStopReportsWriteFailure(t *testing.T) { + diagnostics := NewAsync(failingWriter{}, AsyncOptions{Capacity: 4, StopTimeout: time.Second, CancelGrace: 10 * time.Millisecond}) + diagnostics.Logger().Error("critical message") + + err := diagnostics.Stop(context.Background()) + if err == nil || !strings.Contains(err.Error(), "write diagnostics: write failed") { + t.Fatalf("Stop error = %v, want write failure", err) + } + if err := diagnostics.Stop(context.Background()); err == nil || !strings.Contains(err.Error(), "write failed") { + t.Fatalf("repeated Stop error = %v, want preserved write failure", err) + } +} + +type timeoutWriter struct { + release chan struct{} +} + +func (writer *timeoutWriter) Write([]byte) (int, error) { + <-writer.release + return 0, nil +} + +func (writer *timeoutWriter) Cancel() error { return nil } +func (writer *timeoutWriter) Close() error { return nil } + +func TestAsyncStopTimeoutIsPreservedAndRepeatedStopJoins(t *testing.T) { + writer := &timeoutWriter{release: make(chan struct{})} + diagnostics := NewAsync(writer, AsyncOptions{Capacity: 4, StopTimeout: 40 * time.Millisecond, CancelGrace: 10 * time.Millisecond}) + diagnostics.Logger().Info("blocked message") + + ctx, cancel := context.WithTimeout(context.Background(), 80*time.Millisecond) + defer cancel() + firstError := diagnostics.Stop(ctx) + if !errors.Is(firstError, context.DeadlineExceeded) { + t.Fatalf("first Stop error = %v, want deadline exceeded", firstError) + } + + writer.release <- struct{}{} + secondError := diagnostics.Stop(context.Background()) + if !errors.Is(secondError, context.DeadlineExceeded) { + t.Fatalf("second Stop error = %v, want preserved deadline exceeded", secondError) + } +} + +func TestAsyncRepeatedStopAfterSuccess(t *testing.T) { + var output bytes.Buffer + diagnostics := NewAsync(NewPassthroughWriter(&output), AsyncOptions{Capacity: 4, StopTimeout: time.Second, CancelGrace: 10 * time.Millisecond}) + diagnostics.Logger().Info("message") + + if err := diagnostics.Stop(context.Background()); err != nil { + t.Fatalf("first Stop: %v", err) + } + if err := diagnostics.Stop(context.Background()); err != nil { + t.Fatalf("second Stop: %v", err) + } + if !strings.Contains(output.String(), "message") { + t.Fatalf("flushed output = %q", output.String()) + } +} + +func TestOpenFileIsAppendOnlyOwnerRestrictedAndCancellable(t *testing.T) { + path := filepath.Join(t.TempDir(), "diagnostics.log") + writer, err := OpenFile(path, nil, true) + if err != nil { + t.Fatalf("OpenFile: %v", err) + } + if _, err := writer.Write([]byte("first\n")); err != nil { + t.Fatalf("Write: %v", err) + } + if err := writer.Close(); err != nil { + t.Fatalf("Close: %v", err) + } + + info, err := os.Stat(path) + if err != nil { + t.Fatal(err) + } + if info.Mode().Perm() != 0o600 { + t.Fatalf("file mode = %o, want 0600", info.Mode().Perm()) + } + writer, err = OpenFile(path, nil, true) + if err != nil { + t.Fatalf("reopen: %v", err) + } + if _, err := writer.Write([]byte("second\n")); err != nil { + t.Fatalf("append: %v", err) + } + if err := writer.Cancel(); err != nil { + t.Fatalf("Cancel: %v", err) + } + data, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if string(data) != "first\nsecond\n" { + t.Fatalf("file contents = %q, want append-only data", string(data)) + } +} + +var _ io.Writer = (*controlledWriter)(nil) + +func TestOpenFileReplacesPreviousContents(t *testing.T) { + path := filepath.Join(t.TempDir(), "diagnostics.log") + if err := os.WriteFile(path, []byte("previous session with longer contents\n"), 0o600); err != nil { + t.Fatal(err) + } + writer, err := OpenFile(path, nil, false) + if err != nil { + t.Fatal(err) + } + if _, err := writer.Write([]byte("new session\n")); err != nil { + t.Fatal(err) + } + if err := writer.Close(); err != nil { + t.Fatal(err) + } + data, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if string(data) != "new session\n" { + t.Fatalf("file contents = %q", data) + } +} + +func TestFreshLogPreservesWritesFromOutgoingReader(t *testing.T) { + path := filepath.Join(t.TempDir(), "diagnostics.log") + old, err := OpenFile(path, nil, true) + if err != nil { + t.Fatal(err) + } + defer old.Close() + if _, err := old.Write([]byte("old session\n")); err != nil { + t.Fatal(err) + } + next, err := OpenFile(path, nil, false) + if err != nil { + t.Fatal(err) + } + defer next.Close() + if _, err := old.Write([]byte("outgoing shutdown\n")); err != nil { + t.Fatal(err) + } + if _, err := next.Write([]byte("new session\n")); err != nil { + t.Fatal(err) + } + data, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if string(data) != "outgoing shutdown\nnew session\n" { + t.Fatalf("overlapping reader writes = %q", data) + } +} diff --git a/internal/logging/logging.go b/internal/logging/logging.go new file mode 100644 index 0000000..0d076f8 --- /dev/null +++ b/internal/logging/logging.go @@ -0,0 +1,231 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package logging + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "log/slog" + "runtime" + "strings" + "sync" + "time" +) + +const redactedValue = "[REDACTED]" + +type Options struct { + Level slog.Level + AddSource bool + SensitiveKeys []string +} + +type Handler struct { + writer io.Writer + writerLock *sync.Mutex + level slog.Level + addSource bool + sensitiveKeys map[string]struct{} + group string + attrs []slog.Attr +} + +func New(writer io.Writer, options Options) *slog.Logger { + return slog.New(newHandler(writer, options)) +} + +func newHandler(writer io.Writer, options Options) *Handler { + if writer == nil { + writer = io.Discard + } + level := options.Level + if level == 0 { + level = slog.LevelInfo + } + sensitiveKeys := map[string]struct{}{} + for _, key := range append(defaultSensitiveKeys(), options.SensitiveKeys...) { + sensitiveKeys[lowercaseKey(key)] = struct{}{} + } + return &Handler{ + writer: writer, + writerLock: &sync.Mutex{}, + level: level, + addSource: options.AddSource, + sensitiveKeys: sensitiveKeys, + } +} + +func (handler *Handler) Enabled(_ context.Context, level slog.Level) bool { + return level >= handler.level +} + +func (handler *Handler) Handle(_ context.Context, record slog.Record) error { + _, err := handler.write(handler.format(record)) + return err +} + +func (handler *Handler) format(record slog.Record) []byte { + var buffer bytes.Buffer + buffer.WriteByte('{') + appendField(&buffer, "message", record.Message) + appendField(&buffer, "level", record.Level.String()) + if handler.addSource && record.PC != 0 { + frame, _ := runtime.CallersFrames([]uintptr{record.PC}).Next() + appendField(&buffer, "source", fmt.Sprintf("%s:%d", frame.File, frame.Line)) + appendField(&buffer, "function", frame.Function) + } + + for _, attr := range handler.attrs { + handler.appendAttr(&buffer, attr, "") + } + record.Attrs(func(attr slog.Attr) bool { + handler.appendAttr(&buffer, attr, handler.group) + return true + }) + + appendField(&buffer, "time", record.Time.Format(time.RFC3339Nano)) + + buffer.WriteByte('}') + buffer.WriteByte('\n') + return buffer.Bytes() +} + +func (handler *Handler) write(data []byte) (int, error) { + handler.writerLock.Lock() + defer handler.writerLock.Unlock() + return handler.writer.Write(data) +} + +func (handler *Handler) WithAttrs(attrs []slog.Attr) slog.Handler { + clone := *handler + clone.attrs = append([]slog.Attr(nil), handler.attrs...) + prefix := "" + if handler.group != "" { + prefix = handler.group + "." + } + for _, attr := range attrs { + if prefix == "" { + clone.attrs = append(clone.attrs, attr) + continue + } + clone.attrs = append(clone.attrs, slog.Attr{Key: prefix + attr.Key, Value: attr.Value}) + } + return &clone +} + +func (handler *Handler) WithGroup(name string) slog.Handler { + if name == "" { + return handler + } + clone := *handler + if handler.group == "" { + clone.group = name + } else { + clone.group = handler.group + "." + name + } + return &clone +} + +func (handler *Handler) appendAttr(buffer *bytes.Buffer, attr slog.Attr, prefix string) { + attr.Value = attr.Value.Resolve() + if attr.Equal(slog.Attr{}) { + return + } + if attr.Value.Kind() == slog.KindGroup { + groupPrefix := prefix + if attr.Key != "" && prefix != "" { + groupPrefix = prefix + "." + attr.Key + } else if attr.Key != "" { + groupPrefix = attr.Key + } + for _, child := range attr.Value.Group() { + handler.appendAttr(buffer, child, groupPrefix) + } + return + } + + key := attr.Key + if prefix != "" { + key = prefix + "." + attr.Key + } + var value any + if attr.Value.Kind() == slog.KindString { + value = attr.Value.String() + } else { + value = attr.Value.Any() + } + if handler.isSensitive(key) { + value = redactedValue + } else if err, ok := value.(error); ok { + value = err.Error() + } + appendField(buffer, key, value) +} + +func (handler *Handler) isSensitive(key string) bool { + normalized := lowercaseKey(key) + if _, exists := handler.sensitiveKeys[normalized]; exists { + return true + } + lastDot := len(normalized) - 1 + for lastDot >= 0 && normalized[lastDot] != '.' { + lastDot-- + } + _, exists := handler.sensitiveKeys[normalized[lastDot+1:]] + return exists +} + +func appendField(buffer *bytes.Buffer, key string, value any) { + if buffer.Len() > 1 { + buffer.WriteByte(',') + } + encodedKey, err := json.Marshal(key) + if err != nil { + encodedKey = []byte(fmt.Sprintf("%q", key)) + } + encodedValue, err := json.Marshal(value) + if err != nil { + encodedValue = []byte(fmt.Sprintf("%q", fmt.Sprint(value))) + } + buffer.Write(encodedKey) + buffer.WriteByte(':') + buffer.Write(encodedValue) +} + +func defaultSensitiveKeys() []string { + return []string{ + "authorization", + "document_text", + "host", + "hostname", + "password", + "private_text", + "protected_text", + "secret", + "token", + "url", + "username", + } +} + +func lowercaseKey(key string) string { + return strings.ToLower(key) +} diff --git a/internal/logging/logging_test.go b/internal/logging/logging_test.go new file mode 100644 index 0000000..b713e19 --- /dev/null +++ b/internal/logging/logging_test.go @@ -0,0 +1,158 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package logging + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "log/slog" + "strings" + "testing" +) + +func TestRedactsSensitiveFieldsAndGroups(t *testing.T) { + var output bytes.Buffer + logger := New(&output, Options{}) + + logger.Info( + "request accepted", + "password", "generic-secret", + "username", "Username", + "request", slog.GroupValue( + slog.String("token", "generic-token"), + slog.String("role", "input"), + ), + ) + + line := output.String() + if !json.Valid([]byte(line)) { + t.Fatalf("output is not valid JSON: %q", line) + } + if strings.Contains(line, "generic-secret") || strings.Contains(line, "generic-token") { + t.Fatalf("sensitive value was logged: %q", line) + } + if !strings.Contains(line, redactedValue) { + t.Fatalf("redaction marker missing: %q", line) + } + if !strings.Contains(line, `"request.role":"input"`) { + t.Fatalf("non-sensitive group value missing: %q", line) + } +} + +func TestJSONTimestampIsLastField(t *testing.T) { + var output bytes.Buffer + logger := New(&output, Options{}) + logger.Info("starting", "role", "screen-reader") + + line := output.String() + timeIndex := strings.LastIndex(line, `"time":`) + roleIndex := strings.LastIndex(line, `"role":`) + if timeIndex < 0 || roleIndex < 0 { + t.Fatalf("structured field missing: %q", line) + } + if timeIndex < roleIndex || !strings.HasPrefix(line[timeIndex:], `"time":"`) || + !strings.HasSuffix(line, "\"}\n") { + t.Fatalf("time is not the last field: %q", line) + } + if !strings.Contains(line, `"message":"starting"`) || !strings.Contains(line, `"role":"screen-reader"`) { + t.Fatalf("expected fields missing: %q", line) + } +} + +func TestRespectsLevelAndCustomSensitiveKey(t *testing.T) { + var output bytes.Buffer + logger := New(&output, Options{ + Level: slog.LevelWarn, + SensitiveKeys: []string{"api_key"}, + }) + + logger.Info("debug event", "api_key", "generic-key") + if output.Len() != 0 { + t.Fatalf("disabled info event was written: %q", output.String()) + } + logger.Warn("warning event", "api_key", "generic-key") + if !strings.Contains(output.String(), redactedValue) { + t.Fatalf("custom sensitive key was not redacted: %q", output.String()) + } +} + +func TestErrorsIncludeWrappedAndJoinedMessages(t *testing.T) { + var output bytes.Buffer + logger := New(&output, Options{}) + logger.Error("delivery failed", "error", errors.Join( + fmt.Errorf("send speech: %w", errors.New("connection closed")), + errors.New("cancellation failed"), + )) + var record map[string]any + if err := json.Unmarshal(output.Bytes(), &record); err != nil { + t.Fatal(err) + } + if record["error"] != "send speech: connection closed\ncancellation failed" { + t.Fatalf("error = %v", record["error"]) + } +} + +func TestDebugLevelAndSource(t *testing.T) { + for _, enabled := range []bool{false, true} { + var output bytes.Buffer + level := slog.LevelInfo + if enabled { + level = slog.LevelDebug + } + logger := New(&output, Options{Level: level, AddSource: enabled}) + logger.Debug("event received") + if !enabled { + if output.Len() != 0 { + t.Fatal("debug logged without debug level") + } + continue + } + var record map[string]any + if err := json.Unmarshal(output.Bytes(), &record); err != nil { + t.Fatal(err) + } + if !strings.Contains(fmt.Sprint(record["source"]), "logging_test.go:") || + !strings.Contains(fmt.Sprint(record["function"]), "TestDebugLevelAndSource") { + t.Fatalf("missing call site: %v", record) + } + } +} + +type diagnosticValue struct{} + +func (diagnosticValue) LogValue() slog.Value { + return slog.GroupValue(slog.String("token", "generic-token"), slog.String("role", "terminal")) +} + +func TestResolvedAndBoundGroups(t *testing.T) { + var output bytes.Buffer + logger := New(&output, Options{}).WithGroup("speech").With( + slog.Group("request", slog.String("role", "terminal")), + ) + logger.Info("event", "details", diagnosticValue{}) + var record map[string]any + if err := json.Unmarshal(output.Bytes(), &record); err != nil { + t.Fatal(err) + } + if record["speech.request.role"] != "terminal" || record["speech.details.role"] != "terminal" || + record["speech.details.token"] != redactedValue { + t.Fatalf("incorrect grouped values: %v", record) + } +} diff --git a/internal/notification/mako.go b/internal/notification/mako.go new file mode 100644 index 0000000..9dab888 --- /dev/null +++ b/internal/notification/mako.go @@ -0,0 +1,395 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package notification + +import ( + "context" + "fmt" + "html" + "regexp" + "strings" + "sync" + + "github.com/godbus/dbus/v5" +) + +const ( + MakoSource = "mako" + makoBusName = "org.freedesktop.Notifications" + makoObjectPath = "/fr/emersion/Mako" + makoInterface = "fr.emersion.Mako" +) + +type MakoConnection interface { + Signal(chan<- *dbus.Signal) + RemoveSignal(subscription chan<- *dbus.Signal) + Object(dest string, path dbus.ObjectPath) dbus.BusObject + AddMatchSignal(match ...dbus.MatchOption) error + RemoveMatchSignal(match ...dbus.MatchOption) error + Close() error +} + +type MakoAnnouncer interface { + Announce(entry Entry) +} + +type MakoMonitor struct { + connection MakoConnection + presenter *Presenter + announcer MakoAnnouncer + + mutex sync.Mutex + generation int + available bool + known map[int]struct{} + running bool + stop chan struct{} + stopped chan struct{} + subscription <-chan *dbus.Signal +} + +type MakoController interface { + IsCurrent(entry Entry) bool + Dismiss(notificationID int) bool + InvokeAction(notificationID int, actionKey string) bool +} + +func NewMakoMonitor(connection MakoConnection, presenter *Presenter, announcer MakoAnnouncer) *MakoMonitor { + return &MakoMonitor{ + connection: connection, + presenter: presenter, + announcer: announcer, + known: make(map[int]struct{}), + stop: make(chan struct{}), + stopped: make(chan struct{}), + } +} + +func (monitor *MakoMonitor) Start(ctx context.Context) error { + monitor.mutex.Lock() + if monitor.running { + monitor.mutex.Unlock() + return nil + } + monitor.running = true + monitor.stop = make(chan struct{}) + monitor.stopped = make(chan struct{}) + monitor.mutex.Unlock() + + go monitor.watch(ctx) + return nil +} + +func (monitor *MakoMonitor) Stop(ctx context.Context) error { + monitor.mutex.Lock() + if !monitor.running { + monitor.mutex.Unlock() + return nil + } + monitor.running = false + close(monitor.stop) + monitor.mutex.Unlock() + + select { + case <-monitor.stopped: + case <-ctx.Done(): + return ctx.Err() + } + + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + monitor.unsubscribe() + monitor.presenter.MarkSourceUnavailable(MakoSource) + clear(monitor.known) + monitor.available = false + return monitor.connection.Close() +} + +func (monitor *MakoMonitor) Refresh(announceNew bool) bool { + monitor.mutex.Lock() + available := monitor.available + monitor.mutex.Unlock() + if !available { + return false + } + + notifications, err := monitor.list() + if err != nil { + monitor.markUnavailable() + return false + } + monitor.sync(notifications, announceNew) + return true +} + +func (monitor *MakoMonitor) activate(announceNew bool) bool { + notifications, err := monitor.list() + if err != nil { + monitor.markUnavailable() + return false + } + monitor.mutex.Lock() + monitor.generation++ + monitor.available = true + clear(monitor.known) + monitor.mutex.Unlock() + monitor.sync(notifications, announceNew) + return true +} + +func (monitor *MakoMonitor) Dismiss(notificationID int) bool { + options := map[string]dbus.Variant{ + "id": dbus.MakeVariant(uint32(notificationID)), + "group": dbus.MakeVariant(false), + "history": dbus.MakeVariant(true), + "all": dbus.MakeVariant(false), + } + if err := monitor.object().Call("fr.emersion.Mako.DismissNotifications", 0, options).Err; err != nil { + return false + } + monitor.Refresh(false) + return true +} + +func (monitor *MakoMonitor) InvokeAction(notificationID int, actionKey string) bool { + if err := monitor.object().Call("fr.emersion.Mako.InvokeAction", 0, uint32(notificationID), actionKey).Err; err != nil { + return false + } + monitor.Refresh(false) + return true +} + +func (monitor *MakoMonitor) IsCurrent(entry Entry) bool { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + return monitor.available && entry.Source == MakoSource && + entry.SourceGeneration == monitor.generation && entry.Live +} + +func (monitor *MakoMonitor) Generation() int { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + return monitor.generation +} + +func (monitor *MakoMonitor) watch(ctx context.Context) { + defer close(monitor.stopped) + signals := make(chan *dbus.Signal, 16) + monitor.subscription = signals + monitor.connection.Signal(signals) + defer monitor.connection.RemoveSignal(signals) + + if err := monitor.connection.AddMatchSignal( + dbus.WithMatchObjectPath(makoObjectPath), + dbus.WithMatchInterface("org.freedesktop.DBus.Properties"), + ); err != nil { + monitor.markUnavailable() + return + } + if err := monitor.connection.AddMatchSignal( + dbus.WithMatchSender("org.freedesktop.DBus"), + dbus.WithMatchObjectPath("/org/freedesktop/DBus"), + dbus.WithMatchInterface("org.freedesktop.DBus"), + dbus.WithMatchMember("NameOwnerChanged"), + ); err != nil { + monitor.markUnavailable() + return + } + monitor.activate(false) + + for { + select { + case <-ctx.Done(): + return + case <-monitor.stop: + return + case signal := <-signals: + monitor.handleSignal(signal) + } + } +} + +func (monitor *MakoMonitor) handleSignal(signal *dbus.Signal) { + if signal == nil { + return + } + switch signal.Name { + case "org.freedesktop.DBus.Properties.PropertiesChanged": + if signal.Path == makoObjectPath { + monitor.Refresh(true) + } + case "org.freedesktop.DBus.NameOwnerChanged": + if signal.Path != "/org/freedesktop/DBus" || len(signal.Body) < 3 { + return + } + name, _ := signal.Body[0].(string) + newOwner, _ := signal.Body[2].(string) + if name != makoBusName { + return + } + if newOwner == "" { + monitor.markUnavailable() + } else { + monitor.activate(false) + } + } +} + +func (monitor *MakoMonitor) sync(notifications []map[string]dbus.Variant, announceNew bool) { + parsed := make([]LiveMetadata, 0, len(notifications)) + ids := make([]int, 0, len(notifications)) + live := make(map[int]LiveMetadata) + for _, notification := range notifications { + metadata, id := parseMako(notification) + if id == nil { + continue + } + parsed = append(parsed, metadata) + ids = append(ids, *id) + live[*id] = metadata + } + monitor.presenter.SyncLive(MakoSource, monitor.Generation(), live) + if announceNew { + for index, id := range ids { + if monitor.knownID(id) { + continue + } + notificationID := id + monitor.announcer.Announce(Entry{ + Message: parsed[index].Message, + Source: MakoSource, + SourceGeneration: monitor.Generation(), + NotificationID: ¬ificationID, + Live: true, + Actions: parsed[index].Actions, + AppName: parsed[index].AppName, + Summary: parsed[index].Summary, + Body: parsed[index].Body, + Urgency: parsed[index].Urgency, + DesktopEntry: parsed[index].DesktopEntry, + }) + } + } + monitor.replaceKnown(live) +} + +func (monitor *MakoMonitor) list() ([]map[string]dbus.Variant, error) { + var reply []map[string]dbus.Variant + object := monitor.object() + if err := object.Call(makoInterface+".ListNotifications", 0).Store(&reply); err != nil { + return nil, fmt.Errorf("list mako notifications: %w", err) + } + return reply, nil +} + +func (monitor *MakoMonitor) object() dbus.BusObject { + return monitor.connection.Object(makoBusName, makoObjectPath) +} + +func (monitor *MakoMonitor) knownID(id int) bool { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + _, known := monitor.known[id] + return known +} + +func (monitor *MakoMonitor) replaceKnown(live map[int]LiveMetadata) { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + monitor.known = make(map[int]struct{}, len(live)) + for id := range live { + monitor.known[id] = struct{}{} + } +} + +func (monitor *MakoMonitor) markUnavailable() { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + monitor.available = false + clear(monitor.known) + monitor.presenter.MarkSourceUnavailable(MakoSource) +} + +func (monitor *MakoMonitor) unsubscribe() { + if monitor.subscription != nil { + _ = monitor.connection.RemoveMatchSignal( + dbus.WithMatchObjectPath(makoObjectPath), + dbus.WithMatchInterface("org.freedesktop.DBus.Properties"), + ) + _ = monitor.connection.RemoveMatchSignal( + dbus.WithMatchSender("org.freedesktop.DBus"), + dbus.WithMatchObjectPath("/org/freedesktop/DBus"), + dbus.WithMatchInterface("org.freedesktop.DBus"), + dbus.WithMatchMember("NameOwnerChanged"), + ) + } +} + +var ( + makoTagPattern = regexp.MustCompile(`<[^>]+>`) + makoWhitespacePattern = regexp.MustCompile(`\s+`) +) + +func parseMako(notification map[string]dbus.Variant) (LiveMetadata, *int) { + id, idValid := notification["id"].Value().(uint32) + if !idValid { + return LiveMetadata{}, nil + } + metadata := LiveMetadata{ + AppName: normalizeMakoText(notification["app-name"]), + Summary: normalizeMakoText(notification["summary"]), + Body: normalizeMakoText(notification["body"]), + DesktopEntry: normalizeMakoText(notification["desktop-entry"]), + } + if value, valid := notification["urgency"].Value().(int32); valid { + metadata.Urgency = int(value) + } else { + metadata.Urgency = -1 + } + if actions, valid := notification["actions"].Value().(map[string]dbus.Variant); valid { + metadata.Actions = make(map[string]string, len(actions)) + for key, action := range actions { + value := normalizeMakoText(action) + if value == "" { + value = key + } + metadata.Actions[key] = value + } + } + notificationID := int(id) + metadata.Message = buildMakoMessage(metadata) + return metadata, ¬ificationID +} + +func normalizeMakoText(variant dbus.Variant) string { + text, valid := variant.Value().(string) + if !valid { + return "" + } + text = html.UnescapeString(text) + text = makoTagPattern.ReplaceAllString(text, " ") + text = makoWhitespacePattern.ReplaceAllString(text, " ") + return strings.TrimSpace(text) +} + +func buildMakoMessage(metadata LiveMetadata) string { + parts := []string{MessageNotification} + if metadata.Summary != "" { + parts = append(parts, metadata.Summary) + } + if metadata.Body != "" && metadata.Body != metadata.Summary { + parts = append(parts, metadata.Body) + } + if len(parts) == 1 { + fallback := metadata.AppName + if fallback == "" { + fallback = metadata.DesktopEntry + } + if fallback != "" { + parts = append(parts, fallback) + } + } + return strings.Join(parts, " ") +} diff --git a/internal/notification/mako_test.go b/internal/notification/mako_test.go new file mode 100644 index 0000000..644e25c --- /dev/null +++ b/internal/notification/mako_test.go @@ -0,0 +1,228 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package notification + +import ( + "context" + "errors" + "testing" + + "github.com/godbus/dbus/v5" +) + +func TestMakoSyncAnnouncesOnlyNewNotifications(t *testing.T) { + presenter := NewPresenter() + announcer := &fakeAnnouncer{} + monitor := NewMakoMonitor(nil, presenter, announcer) + monitor.available = true + + notifications := []map[string]dbus.Variant{makoNotification(7)} + monitor.sync(notifications, true) + if len(announcer.entries) != 1 { + t.Fatalf("announced %d notifications, want 1", len(announcer.entries)) + } + if announcer.entries[0].Message != "Notification Mail You have one message" { + t.Fatalf("message = %q", announcer.entries[0].Message) + } + + monitor.sync(notifications, true) + if len(announcer.entries) != 1 { + t.Fatalf("announced %d notifications after refresh, want 1", len(announcer.entries)) + } +} + +func TestMakoParseNormalizesMetadata(t *testing.T) { + metadata, id := parseMako(makoNotification(9)) + if id == nil || *id != 9 { + t.Fatalf("id = %v, want 9", id) + } + if metadata.AppName != "Application" || metadata.Summary != "Mail" || + metadata.Body != "You have one message" || metadata.DesktopEntry != "application" || + metadata.Urgency != 2 || metadata.Actions["default"] != "View" { + t.Fatalf("metadata = %+v", metadata) + } +} + +func TestMakoStopMarksLiveHistoryUnavailable(t *testing.T) { + presenter := NewPresenter() + notificationID := 12 + presenter.Save("Notification Mail", SaveOptions{ + Source: MakoSource, NotificationID: ¬ificationID, Live: true, + }) + monitor := NewMakoMonitor(&fakeMakoConnection{}, presenter, &fakeAnnouncer{}) + monitor.available = true + monitor.running = true + monitor.stop = make(chan struct{}) + monitor.stopped = make(chan struct{}) + close(monitor.stopped) + if err := monitor.Stop(context.Background()); err != nil { + t.Fatalf("stop mako: %v", err) + } + entries := presenter.Entries() + if len(entries) != 1 || entries[0].Live { + t.Fatalf("entries = %+v, want one unavailable entry", entries) + } +} + +func TestMakoOwnerLossMarksLiveHistoryUnavailable(t *testing.T) { + presenter := NewPresenter() + notificationID := 12 + presenter.Save("Notification Mail", SaveOptions{ + Source: MakoSource, NotificationID: ¬ificationID, Live: true, + }) + monitor := NewMakoMonitor(&fakeMakoConnection{}, presenter, &fakeAnnouncer{}) + monitor.available = true + monitor.handleSignal(&dbus.Signal{ + Name: "org.freedesktop.DBus.NameOwnerChanged", + Path: "/org/freedesktop/DBus", + Body: []interface{}{makoBusName, ":1.10", ""}, + }) + + entries := presenter.Entries() + if monitor.available || len(entries) != 1 || entries[0].Live { + t.Fatalf("available = %v, entries = %+v", monitor.available, entries) + } +} + +func TestMakoUnsupportedDaemonMarksHistoryUnavailable(t *testing.T) { + presenter := NewPresenter() + notificationID := 12 + presenter.Save("Notification Mail", SaveOptions{ + Source: MakoSource, NotificationID: ¬ificationID, Live: true, + }) + monitor := NewMakoMonitor(&fakeMakoConnection{ + object: &fakeMakoObject{err: errors.New("object does not exist")}, + }, presenter, &fakeAnnouncer{}) + monitor.available = true + + if monitor.Refresh(false) { + t.Fatal("unsupported notification daemon reported as available") + } + entries := presenter.Entries() + if len(entries) != 1 || entries[0].Live { + t.Fatalf("entries = %+v, want one unavailable entry", entries) + } + if len(presenter.ActionsForEntry(entries[0])) != 0 { + t.Fatal("unsupported notification daemon retained live actions") + } +} + +func TestPresenterRoutesLiveMakoActions(t *testing.T) { + presenter := NewPresenter() + controller := &fakeMakoController{} + presenter.SetMakoController(controller) + notificationID := 6 + entry := presenter.Save("Notification Mail New message", SaveOptions{ + Source: MakoSource, SourceGeneration: 1, + NotificationID: ¬ificationID, Live: true, + Actions: map[string]string{"default": "View"}, + }) + + if !presenter.CanControlEntry(entry) { + t.Fatal("live mako entry was not controllable") + } + if actions := presenter.ActionsForEntry(entry); actions["default"] != "View" { + t.Fatalf("actions = %q, want View", actions["default"]) + } + + messages, dismissed := presenter.DismissEntry(entry) + if !dismissed || messages[0] != MessageDismissed { + t.Fatalf("dismiss = %v %q", dismissed, messages) + } + if len(presenter.Entries()) != 0 || controller.dismissed[0] != 6 { + t.Fatalf("entries = %+v dismissed = %v", presenter.Entries(), controller.dismissed) + } + + actionMessages, invoked := presenter.InvokeActionEntry(entry, "default") + if !invoked || actionMessages[0] != MessageActionInvoked || controller.invoked[0] != (makoAction{6, "default"}) { + t.Fatalf("invoke = %v %q", invoked, actionMessages) + } +} + +func makoNotification(id uint32) map[string]dbus.Variant { + return map[string]dbus.Variant{ + "id": dbus.MakeVariant(id), + "app-name": dbus.MakeVariant("Application"), + "summary": dbus.MakeVariant("Mail"), + "body": dbus.MakeVariant("You have one message"), + "desktop-entry": dbus.MakeVariant("application"), + "urgency": dbus.MakeVariant(int32(2)), + "actions": dbus.MakeVariant(map[string]dbus.Variant{"default": dbus.MakeVariant("View")}), + } +} + +type fakeAnnouncer struct{ entries []Entry } + +func (announcer *fakeAnnouncer) Announce(entry Entry) { + announcer.entries = append(announcer.entries, entry) +} + +type fakeMakoConnection struct { + object *fakeMakoObject +} + +func (connection *fakeMakoConnection) Signal(chan<- *dbus.Signal) {} + +func (connection *fakeMakoConnection) RemoveSignal(chan<- *dbus.Signal) {} +func (connection *fakeMakoConnection) Object(string, dbus.ObjectPath) dbus.BusObject { + return connection.object +} +func (connection *fakeMakoConnection) AddMatchSignal(...dbus.MatchOption) error { return nil } +func (connection *fakeMakoConnection) RemoveMatchSignal(...dbus.MatchOption) error { return nil } +func (connection *fakeMakoConnection) Close() error { return nil } + +type fakeMakoObject struct { + err error +} + +func (object *fakeMakoObject) Call(string, dbus.Flags, ...interface{}) *dbus.Call { + return &dbus.Call{Err: object.err} +} +func (object *fakeMakoObject) CallWithContext(context.Context, string, dbus.Flags, ...interface{}) *dbus.Call { + return &dbus.Call{Err: object.err} +} +func (object *fakeMakoObject) Go(string, dbus.Flags, chan *dbus.Call, ...interface{}) *dbus.Call { + return &dbus.Call{Err: object.err} +} +func (object *fakeMakoObject) GoWithContext(context.Context, string, dbus.Flags, chan *dbus.Call, ...interface{}) *dbus.Call { + return &dbus.Call{Err: object.err} +} +func (object *fakeMakoObject) AddMatchSignal(string, string, ...dbus.MatchOption) *dbus.Call { + return &dbus.Call{Err: object.err} +} +func (object *fakeMakoObject) RemoveMatchSignal(string, string, ...dbus.MatchOption) *dbus.Call { + return &dbus.Call{Err: object.err} +} +func (object *fakeMakoObject) GetProperty(string) (dbus.Variant, error) { + return dbus.Variant{}, object.err +} +func (object *fakeMakoObject) StoreProperty(string, interface{}) error { + return object.err +} +func (object *fakeMakoObject) SetProperty(string, interface{}) error { + return object.err +} +func (object *fakeMakoObject) Destination() string { return makoBusName } +func (object *fakeMakoObject) Path() dbus.ObjectPath { return makoObjectPath } + +type makoAction struct { + id int + key string +} + +type fakeMakoController struct { + dismissed []int + invoked []makoAction +} + +func (controller *fakeMakoController) IsCurrent(Entry) bool { return true } +func (controller *fakeMakoController) Dismiss(id int) bool { + controller.dismissed = append(controller.dismissed, id) + return true +} +func (controller *fakeMakoController) InvokeAction(id int, key string) bool { + controller.invoked = append(controller.invoked, makoAction{id, key}) + return true +} diff --git a/internal/notification/presenter.go b/internal/notification/presenter.go new file mode 100644 index 0000000..9d1fb92 --- /dev/null +++ b/internal/notification/presenter.go @@ -0,0 +1,442 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package notification + +import ( + "fmt" + "math" + "sync" + "time" +) + +var noMessages []string + +const historySize = 55 + +const ( + MessageNotification = "Notification" + MessageListBottom = "Bottom" + MessageListTop = "Top" + MessageNoMessages = "No notification messages" + MessageUnavailable = "Notification is no longer available" + MessageNoActions = "No notification actions available" + MessageDismissed = "Notification dismissed" + MessageActionInvoked = "Notification action invoked" + SourceGeneric = "generic" + ListTitle = "Notifications" + ListColumnMessages = "Notifications" + ListColumnReceived = "Received" + ListDismissButton = "Dismiss Notification" + ListActionsButton = "Notification Actions" + ListActionsTitle = "Notification Actions" + ListInvokeActionButton = "Invoke Action" + ListClearButton = "Clear" + ListCopyButton = "Copy" + ListCloseButton = "Close" +) + +type Entry struct { + ID string + Message string + Timestamp time.Time + Source string + SourceGeneration int + NotificationID *int + Live bool + Actions map[string]string + AppName string + Summary string + Body string + Urgency int + DesktopEntry string +} + +type SaveOptions struct { + Source string + SourceGeneration int + NotificationID *int + Live bool + Actions map[string]string + AppName string + Summary string + Body string + Urgency int + DesktopEntry string +} + +type LiveMetadata struct { + Message string + Actions map[string]string + AppName string + Summary string + Body string + Urgency int + DesktopEntry string +} + +type Presenter struct { + mutex sync.Mutex + now func() time.Time + mako MakoController + + entries []Entry + currentIndex int +} + +func NewPresenter() *Presenter { + return &Presenter{now: time.Now, currentIndex: -1} +} + +func NewPresenterAt(now func() time.Time) *Presenter { + return &Presenter{now: now, currentIndex: -1} +} + +func (presenter *Presenter) SetMakoController(controller MakoController) { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + presenter.mako = controller +} + +func (presenter *Presenter) Save(message string, options ...SaveOptions) Entry { + option := SaveOptions{} + if len(options) != 0 { + option = options[0] + } + if option.Source == "" { + option.Source = SourceGeneric + } + + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + if excess := len(presenter.entries) - historySize + 1; excess > 0 { + presenter.entries = presenter.entries[excess:] + } + entry := Entry{ + Message: message, + Timestamp: presenter.now(), + Source: option.Source, + SourceGeneration: option.SourceGeneration, + NotificationID: option.NotificationID, + Live: option.Live, + Actions: cloneActions(option.Actions), + AppName: option.AppName, + Summary: option.Summary, + Body: option.Body, + Urgency: option.Urgency, + DesktopEntry: option.DesktopEntry, + } + presenter.entries = append(presenter.entries, entry) + return entry +} + +func (presenter *Presenter) Clear() { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + presenter.entries = nil + presenter.currentIndex = -1 +} + +func (presenter *Presenter) Entries() []Entry { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + return append([]Entry(nil), presenter.entries...) +} + +func (presenter *Presenter) EntriesForList() []Entry { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + return presenter.entriesForList() +} + +func (presenter *Presenter) ListTitle() string { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + return presenter.listTitle() +} + +func (presenter *Presenter) EntryText(entry Entry) string { + presenter.mutex.Lock() + now := presenter.now() + presenter.mutex.Unlock() + return entryText(entry, now) +} + +func (presenter *Presenter) ReceivedTime(timestamp time.Time) string { + presenter.mutex.Lock() + now := presenter.now() + presenter.mutex.Unlock() + return relativeTime(timestamp, now) +} + +func (presenter *Presenter) RefreshLive() bool { + presenter.mutex.Lock() + controller := presenter.mako + presenter.mutex.Unlock() + refresher, ok := controller.(interface{ Refresh(bool) bool }) + if !ok { + return false + } + return refresher.Refresh(false) +} + +func (presenter *Presenter) Remove(entry Entry) bool { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + for index, candidate := range presenter.entries { + if entriesEqual(candidate, entry) { + presenter.entries = append(presenter.entries[:index], presenter.entries[index+1:]...) + presenter.removeIndex(index) + return true + } + } + return false +} + +func (presenter *Presenter) SyncLive(source string, generation int, live map[int]LiveMetadata) { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + for index := range presenter.entries { + entry := &presenter.entries[index] + if entry.Source != source || entry.SourceGeneration != generation { + continue + } + if entry.NotificationID == nil { + continue + } + if metadata, exists := live[*entry.NotificationID]; exists { + entry.Live = true + if metadata.Message != "" { + entry.Message = metadata.Message + } + entry.Actions = cloneActions(metadata.Actions) + entry.AppName = metadata.AppName + entry.Summary = metadata.Summary + entry.Body = metadata.Body + entry.Urgency = metadata.Urgency + entry.DesktopEntry = metadata.DesktopEntry + } else if entry.Live { + entry.Live = false + } + } +} + +func (presenter *Presenter) MarkSourceUnavailable(source string) { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + for index := range presenter.entries { + if presenter.entries[index].Source == source && presenter.entries[index].Live { + presenter.entries[index].Live = false + } + } +} + +func (presenter *Presenter) CanControlEntry(entry Entry) bool { + presenter.mutex.Lock() + controller := presenter.mako + presenter.mutex.Unlock() + return entry.Live && entry.NotificationID != nil && controller != nil && controller.IsCurrent(entry) +} + +func (presenter *Presenter) ActionsForEntry(entry Entry) map[string]string { + if !presenter.CanControlEntry(entry) { + return map[string]string{} + } + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + return cloneActions(entry.Actions) +} + +func (presenter *Presenter) DismissEntry(entry Entry) ([]string, bool) { + if !presenter.CanControlEntry(entry) { + return []string{MessageUnavailable}, false + } + presenter.mutex.Lock() + controller := presenter.mako + presenter.mutex.Unlock() + if controller == nil || !controller.Dismiss(*entry.NotificationID) { + return []string{MessageUnavailable}, false + } + entry.Live = false + presenter.Remove(entry) + return []string{MessageDismissed}, true +} + +func (presenter *Presenter) InvokeActionEntry(entry Entry, actionKey string) ([]string, bool) { + if !presenter.CanControlEntry(entry) { + return []string{MessageUnavailable}, false + } + presenter.mutex.Lock() + controller := presenter.mako + presenter.mutex.Unlock() + if controller == nil || !controller.InvokeAction(*entry.NotificationID, actionKey) { + return []string{MessageUnavailable}, false + } + return []string{MessageActionInvoked}, true +} + +func (presenter *Presenter) PresentLast() []string { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + if len(presenter.entries) == 0 { + return []string{MessageNoMessages} + } + presenter.currentIndex = -1 + return []string{entryText(presenter.entries[len(presenter.entries)-1], presenter.now())} +} + +func (presenter *Presenter) PresentPrevious() []string { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + if len(presenter.entries) == 0 { + return []string{MessageNoMessages} + } + messages := noMessages + next := presenter.currentIndex - 1 + if next < -len(presenter.entries) { + messages = append(messages, MessageListTop) + } else { + presenter.currentIndex = next + } + current := len(presenter.entries) + presenter.currentIndex + return append(messages, entryText(presenter.entries[current], presenter.now())) +} + +func (presenter *Presenter) PresentNext() []string { + presenter.mutex.Lock() + defer presenter.mutex.Unlock() + if len(presenter.entries) == 0 { + return []string{MessageNoMessages} + } + messages := noMessages + if presenter.currentIndex == -1 { + messages = append(messages, MessageListBottom) + } else { + next := presenter.currentIndex + 1 + if next > -1 { + messages = append(messages, MessageListBottom) + } else { + presenter.currentIndex = next + } + } + current := len(presenter.entries) + presenter.currentIndex + return append(messages, entryText(presenter.entries[current], presenter.now())) +} + +func (presenter *Presenter) removeIndex(index int) { + if len(presenter.entries) == 0 { + presenter.currentIndex = -1 + return + } + if presenter.currentIndex == -1 { + return + } + // Navigation uses negative offsets from the newest entry; removal receives + // a forward slice index. Preserve the selected entry when it survives, or + // select its successor when removed, without retaining an out-of-range offset. + current := len(presenter.entries) + 1 + presenter.currentIndex + if index < current { + current-- + } + current = min(current, len(presenter.entries)-1) + presenter.currentIndex = current - len(presenter.entries) +} + +func (presenter *Presenter) entriesForList() []Entry { + entries := append([]Entry(nil), presenter.entries...) + for left, right := 0, len(entries)-1; left < right; left, right = left+1, right-1 { + entries[left], entries[right] = entries[right], entries[left] + } + return entries +} + +func (presenter *Presenter) listTitle() string { + return plural(len(presenter.entries), "%d notification", "%d notifications") +} + +func entryText(entry Entry, now time.Time) string { + return fmt.Sprintf("%s %s", entry.Message, relativeTime(entry.Timestamp, now)) +} + +func relativeTime(timestamp, now time.Time) string { + elapsed := now.Sub(timestamp) + switch { + case elapsed < time.Minute: + count := int(elapsed.Seconds()) + return plural(count, "%d second ago", "%d seconds ago") + case elapsed < time.Hour: + count := roundLikePython(elapsed.Minutes()) + return plural(count, "%d minute ago", "%d minutes ago") + case elapsed < 24*time.Hour: + count := roundLikePython(elapsed.Hours()) + return plural(count, "%d hour ago", "%d hours ago") + default: + count := roundLikePython(elapsed.Hours() / 24) + return plural(count, "%d day ago", "%d days ago") + } +} + +func plural(count int, singular, pluralFormat string) string { + if count == 1 { + return fmt.Sprintf(singular, count) + } + return fmt.Sprintf(pluralFormat, count) +} + +func roundLikePython(value float64) int { + lower := math.Floor(value) + fraction := value - lower + switch { + case fraction > 0.5: + return int(lower) + 1 + case fraction == 0.5 && int(lower)%2 != 0: + return int(lower) + 1 + default: + return int(lower) + } +} + +func cloneActions(actions map[string]string) map[string]string { + if len(actions) == 0 { + return map[string]string{} + } + clone := make(map[string]string, len(actions)) + for key, value := range actions { + clone[key] = value + } + return clone +} + +func entriesEqual(left, right Entry) bool { + return left.Message == right.Message && + left.Timestamp.Equal(right.Timestamp) && + left.Source == right.Source && + left.SourceGeneration == right.SourceGeneration && + notificationIDsEqual(left.NotificationID, right.NotificationID) && + actionsEqual(left.Actions, right.Actions) && + left.AppName == right.AppName && + left.Summary == right.Summary && + left.Body == right.Body && + left.Urgency == right.Urgency && + left.DesktopEntry == right.DesktopEntry +} + +func notificationIDsEqual(left, right *int) bool { + if left == nil || right == nil { + return left == right + } + return *left == *right +} + +func actionsEqual(left, right map[string]string) bool { + if len(left) != len(right) { + return false + } + for key, value := range left { + if right[key] != value { + return false + } + } + return true +} diff --git a/internal/notification/presenter_test.go b/internal/notification/presenter_test.go new file mode 100644 index 0000000..c516831 --- /dev/null +++ b/internal/notification/presenter_test.go @@ -0,0 +1,123 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package notification + +import ( + "testing" + "time" +) + +func TestPresenterSavesHistoryAndEnforcesMaximumSize(t *testing.T) { + now := time.Unix(1_800_000_000, 0) + presenter := NewPresenterAt(func() time.Time { return now }) + for number := 0; number < historySize+2; number++ { + presenter.Save(time.Unix(int64(number), 0).Format("2006")) + now = now.Add(time.Second) + } + entries := presenter.Entries() + if len(entries) != historySize { + t.Fatalf("history length = %d, want %d", len(entries), historySize) + } + if entries[0].Source != SourceGeneric { + t.Fatalf("first source = %q, want %q", entries[0].Source, SourceGeneric) + } +} + +func TestPresenterNavigationMatchesReferenceBoundaries(t *testing.T) { + now := time.Unix(1_800_000_000, 0) + presenter := NewPresenterAt(func() time.Time { return now }) + presenter.Save("first") + presenter.Save("second") + + assertMessages := func(t *testing.T, got []string, want ...string) { + t.Helper() + if len(got) != len(want) { + t.Fatalf("message count = %d, want %d: %q", len(got), len(want), got) + } + for index := range want { + if got[index] != want[index] { + t.Fatalf("message %d = %q, want %q", index, got[index], want[index]) + } + } + } + t.Run("last", func(t *testing.T) { + assertMessages(t, presenter.PresentLast(), "second 0 seconds ago") + }) + t.Run("previous then top", func(t *testing.T) { + assertMessages(t, presenter.PresentPrevious(), "first 0 seconds ago") + assertMessages(t, presenter.PresentPrevious(), MessageListTop, "first 0 seconds ago") + }) + t.Run("next then bottom", func(t *testing.T) { + assertMessages(t, presenter.PresentNext(), "second 0 seconds ago") + assertMessages(t, presenter.PresentNext(), MessageListBottom, "second 0 seconds ago") + assertMessages(t, presenter.PresentNext(), MessageListBottom, "second 0 seconds ago") + }) + t.Run("empty", func(t *testing.T) { + empty := NewPresenterAt(func() time.Time { return now }) + assertMessages(t, empty.PresentLast(), MessageNoMessages) + assertMessages(t, empty.PresentPrevious(), MessageNoMessages) + assertMessages(t, empty.PresentNext(), MessageNoMessages) + }) +} + +func TestPresenterStartsAtLatestNotification(t *testing.T) { + now := time.Unix(1_800_000_000, 0) + presenter := NewPresenterAt(func() time.Time { return now }) + presenter.Save("first") + presenter.Save("second") + + assertMessages(t, presenter.PresentPrevious(), "first 0 seconds ago") +} + +func TestPresenterRemovalKeepsHistoryNavigationValid(t *testing.T) { + for _, removeAt := range []int{0, 1, 2} { + t.Run(time.Duration(removeAt).String(), func(t *testing.T) { + now := time.Unix(1_800_000_000, 0) + presenter := NewPresenterAt(func() time.Time { return now }) + entries := []Entry{presenter.Save("first"), presenter.Save("second"), presenter.Save("third")} + presenter.PresentPrevious() + presenter.PresentPrevious() + if !presenter.Remove(entries[removeAt]) { + t.Fatal("notification was not removed") + } + want := "first 0 seconds ago" + if removeAt == 0 { + want = "second 0 seconds ago" + } + assertMessages(t, presenter.PresentPrevious(), MessageListTop, want) + presenter.PresentNext() + }) + } +} + +func assertMessages(t *testing.T, got []string, want ...string) { + t.Helper() + if len(got) != len(want) { + t.Fatalf("message count = %d, want %d: %q", len(got), len(want), got) + } + for index := range want { + if got[index] != want[index] { + t.Fatalf("message %d = %q, want %q", index, got[index], want[index]) + } + } +} + +func TestRelativeTimeUsesReferenceRounding(t *testing.T) { + now := time.Unix(1_800_000_000, 0) + for _, test := range []struct { + elapsed time.Duration + want string + }{ + {90 * time.Second, "2 minutes ago"}, + {150 * time.Second, "2 minutes ago"}, + {89 * time.Second, "1 minute ago"}, + {90 * time.Minute, "2 hours ago"}, + {90 * time.Hour, "4 days ago"}, + } { + if got := relativeTime(now.Add(-test.elapsed), now); got != test.want { + t.Fatalf("relativeTime(%s) = %q, want %q", test.elapsed, got, test.want) + } + } +} diff --git a/internal/notificationui/native.c b/internal/notificationui/native.c new file mode 100644 index 0000000..e2402de --- /dev/null +++ b/internal/notificationui/native.c @@ -0,0 +1,263 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native.h" + +#include +#include + +enum { ACTION_NONE, ACTION_COPY, ACTION_DISMISS, ACTION_CLEAR, ACTION_CLOSE, + ACTION_SELECTION, ACTION_INVOKE }; + +static GtkWidget *dialog; +static GtkListStore *model; +static GtkTreeSelection *selection; +static GtkWidget *dismiss_button; +static GtkWidget *actions_box; +static GtkWidget *actions_status; +static int action_code; +static int suppress_selection; +static char *selected_action_key; +static char *selected_id_cache; + +static void set_action(int code) { + if (!action_code) action_code = code; +} + +static void response(GtkDialog *widget, int response_id, gpointer data) { + (void)widget; + (void)data; + if (response_id == ACTION_COPY) set_action(ACTION_COPY); + else if (response_id == ACTION_DISMISS) set_action(ACTION_DISMISS); + else if (response_id == ACTION_CLEAR) set_action(ACTION_CLEAR); + else if (response_id == ACTION_CLOSE) set_action(ACTION_CLOSE); +} + +static void selection_changed(GtkTreeSelection *widget, gpointer data) { + (void)widget; + (void)data; + if (!suppress_selection) set_action(ACTION_SELECTION); +} + +static void action_clicked(GtkButton *button, gpointer data) { + (void)data; + const char *key = g_object_get_data(G_OBJECT(button), "cthulhu-action-key"); + g_free(selected_action_key); + selected_action_key = g_strdup(key ? key : ""); + set_action(ACTION_INVOKE); +} + +static void clear_action_buttons(void) { + if (!actions_box) return; + GList *children = gtk_container_get_children(GTK_CONTAINER(actions_box)); + for (GList *item = children; item; item = item->next) gtk_widget_destroy(GTK_WIDGET(item->data)); + g_list_free(children); +} + +static void set_actions(char **keys, char **labels, int count) { + clear_action_buttons(); + for (int index = 0; index < count; index++) { + const char *label = labels && labels[index] && labels[index][0] ? labels[index] : keys[index]; + GtkWidget *button = gtk_button_new_with_label(label ? label : ""); + char *key = g_strdup(keys && keys[index] ? keys[index] : ""); + g_object_set_data_full(G_OBJECT(button), "cthulhu-action-key", key, g_free); + g_signal_connect(button, "clicked", G_CALLBACK(action_clicked), NULL); + gtk_box_pack_start(GTK_BOX(actions_box), button, FALSE, FALSE, 0); + } + gtk_widget_show_all(actions_box); +} + +int notification_list_init(const char *title, const char *message_header, + const char *received_header) { + if (!gtk_init_check(NULL, NULL)) return 0; + g_set_application_name("Cthulhu Notifications"); + dialog = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(dialog), title ? title : "Notifications"); + gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 400); + gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); + gtk_dialog_add_button(GTK_DIALOG(dialog), "Copy", ACTION_COPY); + dismiss_button = gtk_dialog_add_button(GTK_DIALOG(dialog), "Dismiss Notification", ACTION_DISMISS); + gtk_dialog_add_button(GTK_DIALOG(dialog), "Clear", ACTION_CLEAR); + gtk_dialog_add_button(GTK_DIALOG(dialog), "Close", ACTION_CLOSE); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), ACTION_CLOSE); + g_signal_connect(dialog, "response", G_CALLBACK(response), NULL); + + GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + GtkWidget *grid = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(grid), 12); + gtk_container_add(GTK_CONTAINER(content), grid); + GtkWidget *scrolled = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_set_hexpand(scrolled, TRUE); + gtk_widget_set_vexpand(scrolled, TRUE); + gtk_container_add(GTK_CONTAINER(grid), scrolled); + + model = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + GtkWidget *tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); + gtk_widget_set_hexpand(tree, TRUE); + gtk_widget_set_vexpand(tree, TRUE); + AtkObject *tree_accessible = gtk_widget_get_accessible(tree); + if (tree_accessible) atk_object_set_name(tree_accessible, title ? title : "Notifications"); + for (int column = 0; column < 2; column++) { + const char *header = column == 0 ? message_header : received_header; + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn *view = gtk_tree_view_column_new_with_attributes(header, renderer, + "text", column, NULL); + if (header && header[0]) gtk_tree_view_column_set_sort_column_id(view, column); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree), view); + } + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + g_signal_connect(selection, "changed", G_CALLBACK(selection_changed), NULL); + gtk_container_add(GTK_CONTAINER(scrolled), tree); + + GtkWidget *frame = gtk_frame_new("Notification Actions"); + gtk_frame_set_label_align(GTK_FRAME(frame), 0.0, 0.5); + AtkObject *frame_accessible = gtk_widget_get_accessible(frame); + if (frame_accessible) atk_object_set_name(frame_accessible, "Notification Actions"); + gtk_grid_attach_next_to(GTK_GRID(grid), frame, scrolled, GTK_POS_BOTTOM, 1, 1); + GtkWidget *actions_content = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); + g_object_set(actions_content, "margin-top", 6, "margin-bottom", 6, + "margin-start", 6, "margin-end", 6, NULL); + gtk_container_add(GTK_CONTAINER(frame), actions_content); + actions_status = gtk_label_new(""); + gtk_label_set_xalign(GTK_LABEL(actions_status), 0); + gtk_label_set_line_wrap(GTK_LABEL(actions_status), TRUE); + gtk_widget_set_no_show_all(actions_status, TRUE); + gtk_box_pack_start(GTK_BOX(actions_content), actions_status, FALSE, FALSE, 0); + actions_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); + gtk_box_pack_start(GTK_BOX(actions_content), actions_box, FALSE, FALSE, 0); + return 1; +} + +void notification_list_set_entries(char **messages, char **received, int count, + char **ids, const char *selected, int can_control, + char **action_keys, char **action_labels, + int action_count) { + if (!model) return; + suppress_selection = 1; + gtk_list_store_clear(model); + for (int index = 0; index < count; index++) { + GtkTreeIter iterator; + gtk_list_store_append(model, &iterator); + gtk_list_store_set(model, &iterator, 0, messages && messages[index] ? messages[index] : "", + 1, received && received[index] ? received[index] : "", + 2, ids && ids[index] ? ids[index] : "", -1); + } + GtkTreeIter iterator; + gboolean found = FALSE; + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iterator)) { + do { + char *value = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(model), &iterator, 2, &value, -1); + if (value && selected && !g_strcmp0(value, selected)) found = TRUE; + g_free(value); + if (found) { + GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iterator); + gtk_tree_selection_select_path(selection, path); + gtk_tree_path_free(path); + break; + } + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iterator)); + } + if (!found) gtk_tree_selection_unselect_all(selection); + gtk_widget_set_sensitive(dismiss_button, can_control != 0); + if (!can_control) { + clear_action_buttons(); + gtk_label_set_text(GTK_LABEL(actions_status), "Notification is no longer available"); + gtk_widget_show(actions_status); + } else if (!action_count) { + clear_action_buttons(); + gtk_label_set_text(GTK_LABEL(actions_status), "No notification actions available"); + gtk_widget_show(actions_status); + } else { + set_actions(action_keys, action_labels, action_count); + gtk_label_set_text(GTK_LABEL(actions_status), ""); + gtk_widget_hide(actions_status); + } + suppress_selection = 0; +} + +void notification_list_show(void) { + if (!dialog) return; + gtk_widget_show_all(dialog); + gtk_window_present(GTK_WINDOW(dialog)); +} + +void notification_list_present(void) { + if (!dialog) return; + gtk_window_present(GTK_WINDOW(dialog)); +} + +void notification_list_iterate(void) { + while (gtk_events_pending()) gtk_main_iteration(); +} + +int notification_list_action(void) { + int result = action_code; + action_code = ACTION_NONE; + return result; +} + +int notification_list_selected(void) { + GtkTreeIter iterator; + GtkTreeModel *selected_model = NULL; + if (!selection || !gtk_tree_selection_get_selected(selection, &selected_model, &iterator)) return -1; + GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &iterator); + if (!path) return -1; + int *indices = gtk_tree_path_get_indices(path); + int selected = indices && indices[0] >= 0 ? indices[0] : -1; + gtk_tree_path_free(path); + return selected; +} + +int notification_list_selected_row(void) { + int selected = notification_list_selected(); + return selected >= 0 ? selected : 0; +} + +const char *notification_list_selected_id(void) { + GtkTreeIter iterator; + GtkTreeModel *selected_model = NULL; + if (!selection || !gtk_tree_selection_get_selected(selection, &selected_model, &iterator)) return ""; + char *identifier = NULL; + gtk_tree_model_get(selected_model, &iterator, 2, &identifier, -1); + g_free(selected_id_cache); + selected_id_cache = identifier ? identifier : g_strdup(""); + return selected_id_cache; +} + +const char *notification_list_selected_action(void) { + return selected_action_key ? selected_action_key : ""; +} + +int notification_list_copy(void) { + GtkTreeIter iterator; + GtkTreeModel *selected_model = NULL; + if (!selection || !gtk_tree_selection_get_selected(selection, &selected_model, &iterator)) return 0; + char *message = NULL; + char *received = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(model), &iterator, 0, &message, 1, &received, -1); + char *text = g_strjoin("\t", message ? message : "", received && received[0] ? received : NULL, NULL); + GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clipboard, text, -1); + gtk_clipboard_store(clipboard); + g_free(text); + g_free(message); + g_free(received); + return 1; +} + +void notification_list_close(void) { + if (!dialog) return; + gtk_widget_destroy(dialog); + dialog = NULL; + model = NULL; + selection = NULL; + dismiss_button = NULL; + actions_box = NULL; + actions_status = NULL; + g_free(selected_action_key); + selected_action_key = NULL; + g_free(selected_id_cache); + selected_id_cache = NULL; +} diff --git a/internal/notificationui/native.h b/internal/notificationui/native.h new file mode 100644 index 0000000..139a594 --- /dev/null +++ b/internal/notificationui/native.h @@ -0,0 +1,21 @@ +#ifndef CTHULHU_NOTIFICATION_UI_NATIVE_H +#define CTHULHU_NOTIFICATION_UI_NATIVE_H + +int notification_list_init(const char *title, const char *message_header, + const char *received_header); +void notification_list_set_entries(char **messages, char **received, int count, + char **ids, const char *selected, int can_control, + char **action_keys, char **action_labels, + int action_count); +void notification_list_show(void); +void notification_list_present(void); +void notification_list_iterate(void); +int notification_list_action(void); +int notification_list_selected(void); +int notification_list_selected_row(void); +const char *notification_list_selected_id(void); +const char *notification_list_selected_action(void); +int notification_list_copy(void); +void notification_list_close(void); + +#endif diff --git a/internal/notificationui/protocol.go b/internal/notificationui/protocol.go new file mode 100644 index 0000000..a3cab46 --- /dev/null +++ b/internal/notificationui/protocol.go @@ -0,0 +1,35 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package notificationui + +type Action struct { + Key string `json:"key"` + Label string `json:"label"` +} + +type Entry struct { + ID string `json:"id,omitempty"` + Message string `json:"message"` + Received string `json:"received"` + CanControl bool `json:"canControl"` + Actions []Action `json:"actions"` +} + +type Response struct { + Present bool `json:"present,omitempty"` + Close bool `json:"close,omitempty"` + Title string `json:"title,omitempty"` + Entries []Entry `json:"entries"` + Selected string `json:"selected"` +} + +type Request struct { + Selection string `json:"selection,omitempty"` + Row *int `json:"row,omitempty"` + Copy bool `json:"copy,omitempty"` + Dismiss bool `json:"dismiss,omitempty"` + Clear bool `json:"clear,omitempty"` + Action string `json:"action,omitempty"` +} diff --git a/internal/notificationui/ui.go b/internal/notificationui/ui.go new file mode 100644 index 0000000..9fa0841 --- /dev/null +++ b/internal/notificationui/ui.go @@ -0,0 +1,200 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package notificationui + +/* +#cgo pkg-config: gtk+-3.0 +#include +#include "native.h" +*/ +import "C" + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "io" + "runtime" + "time" + "unsafe" +) + +// Run owns all GTK calls on one OS thread. The parent supplies a private pipe; +// no widget invokes speech directly. +func Run(ctx context.Context, input io.Reader, output io.Writer) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + updates := make(chan Response, 1) + errorsIn := make(chan error, 1) + go func() { + scanner := bufio.NewScanner(input) + scanner.Buffer(make([]byte, 4096), 1024*1024) + for scanner.Scan() { + var response Response + if err := json.Unmarshal(scanner.Bytes(), &response); err != nil { + errorsIn <- err + return + } + select { + case updates <- response: + case <-ctx.Done(): + return + } + } + errorsIn <- scanner.Err() + }() + + var initial Response + select { + case initial = <-updates: + case err := <-errorsIn: + if errors.Is(err, io.EOF) { + return nil + } + return err + case <-ctx.Done(): + return ctx.Err() + } + title := C.CString(initial.Title) + defer C.free(unsafe.Pointer(title)) + messageHeader := C.CString("Notifications") + defer C.free(unsafe.Pointer(messageHeader)) + receivedHeader := C.CString("Received") + defer C.free(unsafe.Pointer(receivedHeader)) + if C.notification_list_init(title, messageHeader, receivedHeader) == 0 { + return errors.New("cannot open the notification list on this display") + } + defer C.notification_list_close() + apply(initial) + C.notification_list_show() + + encoder := json.NewEncoder(output) + ticker := time.NewTicker(10 * time.Millisecond) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-errorsIn: + if errors.Is(err, io.EOF) { + return nil + } + return err + case response := <-updates: + if response.Close { + return nil + } + if response.Present { + C.notification_list_present() + continue + } + apply(response) + case <-ticker.C: + C.notification_list_iterate() + switch C.notification_list_action() { + case 1: + if C.notification_list_copy() != 0 { + if err := encoder.Encode(Request{Copy: true}); err != nil { + return err + } + } + case 2: + selection := C.GoString(C.notification_list_selected_id()) + row := int(C.notification_list_selected_row()) + if err := encoder.Encode(Request{Dismiss: true, Selection: selection, Row: &row}); err != nil { + return err + } + case 3: + if err := encoder.Encode(Request{Clear: true}); err != nil { + return err + } + case 4: + return nil + case 5: + selection := C.GoString(C.notification_list_selected_id()) + row := int(C.notification_list_selected_row()) + if err := encoder.Encode(Request{Selection: selection, Row: &row}); err != nil { + return err + } + case 6: + action := C.GoString(C.notification_list_selected_action()) + selection := C.GoString(C.notification_list_selected_id()) + row := int(C.notification_list_selected_row()) + if err := encoder.Encode(Request{Action: action, Selection: selection, Row: &row}); err != nil { + return err + } + } + } + } +} + +func apply(response Response) { + messages := make([]*C.char, len(response.Entries)) + received := make([]*C.char, len(response.Entries)) + identifiers := make([]*C.char, len(response.Entries)) + for index, entry := range response.Entries { + identifiers[index] = C.CString(entry.ID) + messages[index] = C.CString(entry.Message) + received[index] = C.CString(entry.Received) + } + defer func() { + for _, value := range messages { + C.free(unsafe.Pointer(value)) + } + for _, value := range received { + C.free(unsafe.Pointer(value)) + } + for _, value := range identifiers { + C.free(unsafe.Pointer(value)) + } + }() + + selectedID := C.CString(response.Selected) + defer C.free(unsafe.Pointer(selectedID)) + var selectedEntry Entry + for _, entry := range response.Entries { + if entry.ID == response.Selected { + selectedEntry = entry + break + } + } + actionKeys := make([]*C.char, len(selectedEntry.Actions)) + actionLabels := make([]*C.char, len(selectedEntry.Actions)) + for index, action := range selectedEntry.Actions { + actionKeys[index] = C.CString(action.Key) + actionLabels[index] = C.CString(action.Label) + } + defer func() { + for _, value := range actionKeys { + C.free(unsafe.Pointer(value)) + } + for _, value := range actionLabels { + C.free(unsafe.Pointer(value)) + } + }() + + C.notification_list_set_entries( + cStringArray(messages), cStringArray(received), C.int(len(response.Entries)), + cStringArray(identifiers), selectedID, cBoolean(selectedEntry.CanControl), + cStringArray(actionKeys), cStringArray(actionLabels), C.int(len(selectedEntry.Actions)), + ) +} + +func cStringArray(values []*C.char) **C.char { + if len(values) == 0 { + return nil + } + return (**C.char)(unsafe.Pointer(&values[0])) +} + +func cBoolean(value bool) C.int { + if value { + return 1 + } + return 0 +} diff --git a/internal/nvda2cthulhu/messagepack.go b/internal/nvda2cthulhu/messagepack.go new file mode 100644 index 0000000..e475b42 --- /dev/null +++ b/internal/nvda2cthulhu/messagepack.go @@ -0,0 +1,210 @@ +// Package nvda2cthulhu accepts the local WebSocket protocol used by NVDA +// compatibility bridges and routes it to Cthulhu's speech and braille queues. +package nvda2cthulhu + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "math" +) + +type messagePackBinary string + +func decodeMessagePack(reader *bytes.Reader) (any, error) { + return decodeMessagePackDepth(reader, 0) +} + +func decodeMessagePackDepth(reader *bytes.Reader, depth int) (any, error) { + if depth > 64 { + return nil, errors.New("MessagePack nesting exceeds limit") + } + code, err := reader.ReadByte() + if err != nil { + return nil, err + } + switch { + case code <= 0x7f: + return int64(code), nil + case code >= 0xe0: + return int64(int8(code)), nil + case code >= 0x80 && code <= 0x8f: + return decodeMessagePackMap(reader, int(code&0x0f), depth) + case code >= 0x90 && code <= 0x9f: + return decodeMessagePackArray(reader, int(code&0x0f), depth) + case code >= 0xa0 && code <= 0xbf: + return decodeMessagePackString(reader, int(code&0x1f)) + case code == 0xc0: + return nil, nil + case code == 0xc2: + return false, nil + case code == 0xc3: + return true, nil + case code == 0xc4 || code == 0xc5 || code == 0xc6: + length, err := decodeLength(reader, code, 0xc4) + if err != nil { + return nil, err + } + value := make([]byte, length) + if _, err := io.ReadFull(reader, value); err != nil { + return nil, err + } + return messagePackBinary(value), nil + case code >= 0xca && code <= 0xcb: + return decodeMessagePackFloat(reader, code) + case code >= 0xcc && code <= 0xd3: + return decodeMessagePackInteger(reader, code) + case code == 0xd9 || code == 0xda || code == 0xdb: + length, err := decodeLength(reader, code, 0xd9) + if err != nil { + return nil, err + } + return decodeMessagePackString(reader, length) + case code == 0xdc || code == 0xdd: + length, err := decodeLength(reader, code, 0xdc) + if err != nil { + return nil, err + } + return decodeMessagePackArray(reader, length, depth) + case code == 0xde || code == 0xdf: + length, err := decodeLength(reader, code, 0xde) + if err != nil { + return nil, err + } + return decodeMessagePackMap(reader, length, depth) + default: + return nil, fmt.Errorf("unsupported MessagePack type 0x%02x", code) + } +} + +func decodeLength(reader *bytes.Reader, code, base byte) (int, error) { + var size int + switch code - base { + case 0: + size = 1 + case 1: + size = 2 + case 2: + size = 4 + default: + return 0, fmt.Errorf("invalid length type 0x%02x", code) + } + buffer := make([]byte, size) + if _, err := io.ReadFull(reader, buffer); err != nil { + return 0, err + } + value := uint64(0) + for _, octet := range buffer { + value = value<<8 | uint64(octet) + } + if value > uint64(maxPayload) { + return 0, errors.New("MessagePack value exceeds 64 KiB") + } + return int(value), nil +} + +func decodeMessagePackString(reader *bytes.Reader, length int) (string, error) { + value := make([]byte, length) + if _, err := io.ReadFull(reader, value); err != nil { + return "", err + } + return string(value), nil +} + +func decodeMessagePackFloat(reader *bytes.Reader, code byte) (any, error) { + var buffer []byte + if code == 0xca { + buffer = make([]byte, 4) + } else { + buffer = make([]byte, 8) + } + if _, err := io.ReadFull(reader, buffer); err != nil { + return nil, err + } + if code == 0xca { + bits := binary.BigEndian.Uint32(buffer) + return float64(math.Float32frombits(bits)), nil + } + return math.Float64frombits(binary.BigEndian.Uint64(buffer)), nil +} + +func decodeMessagePackInteger(reader *bytes.Reader, code byte) (any, error) { + switch code { + case 0xcc, 0xd0: + buffer := make([]byte, 1) + if _, err := io.ReadFull(reader, buffer); err != nil { + return nil, err + } + if code == 0xcc { + return uint64(buffer[0]), nil + } + return int64(int8(buffer[0])), nil + case 0xcd, 0xd1: + buffer := make([]byte, 2) + if _, err := io.ReadFull(reader, buffer); err != nil { + return nil, err + } + value := binary.BigEndian.Uint16(buffer) + if code == 0xcd { + return uint64(value), nil + } + return int64(int16(value)), nil + case 0xce, 0xd2: + buffer := make([]byte, 4) + if _, err := io.ReadFull(reader, buffer); err != nil { + return nil, err + } + value := binary.BigEndian.Uint32(buffer) + if code == 0xce { + return uint64(value), nil + } + return int64(int32(value)), nil + case 0xcf, 0xd3: + buffer := make([]byte, 8) + if _, err := io.ReadFull(reader, buffer); err != nil { + return nil, err + } + value := binary.BigEndian.Uint64(buffer) + if code == 0xcf { + return value, nil + } + return int64(value), nil + default: + return nil, fmt.Errorf("invalid integer type 0x%02x", code) + } +} + +func decodeMessagePackArray(reader *bytes.Reader, length, depth int) ([]any, error) { + values := make([]any, length) + for index := range values { + value, err := decodeMessagePackDepth(reader, depth+1) + if err != nil { + return nil, err + } + values[index] = value + } + return values, nil +} + +func decodeMessagePackMap(reader *bytes.Reader, length, depth int) (map[any]any, error) { + values := make(map[any]any, length) + for range length { + key, err := decodeMessagePackDepth(reader, depth+1) + if err != nil { + return nil, err + } + switch key.(type) { + case string, messagePackBinary: + default: + return nil, errors.New("MessagePack map key must be text") + } + value, err := decodeMessagePackDepth(reader, depth+1) + if err != nil { + return nil, err + } + values[key] = value + } + return values, nil +} diff --git a/internal/nvda2cthulhu/messagepack_test.go b/internal/nvda2cthulhu/messagepack_test.go new file mode 100644 index 0000000..853602e --- /dev/null +++ b/internal/nvda2cthulhu/messagepack_test.go @@ -0,0 +1,44 @@ +package nvda2cthulhu + +import ( + "bytes" + "testing" + + "github.com/gorilla/websocket" +) + +func TestDecodeMessagePackRequests(t *testing.T) { + tests := []struct { + name string + payload []byte + want bridgeRequest + }{ + {name: "fix string", payload: []byte{0xa4, 'G', 'a', 'm', 'e'}, want: bridgeRequest{kind: "SpeakText", text: "Game"}}, + {name: "map with string", payload: []byte{0x81, 0xa9, 'S', 'p', 'e', 'a', 'k', 'T', 'e', 'x', 't', 0xa4, 'G', 'a', 'm', 'e'}, want: bridgeRequest{kind: "SpeakText", text: "Game"}}, + {name: "array cancel", payload: []byte{0x91, 0xac, 'C', 'a', 'n', 'c', 'e', 'l', 'S', 'p', 'e', 'e', 'c', 'h'}, want: bridgeRequest{kind: "CancelSpeech"}}, + {name: "bin value", payload: []byte{0x81, 0xab, 'B', 'r', 'a', 'i', 'l', 'l', 'e', 'T', 'e', 'x', 't', 0xc4, 0x02, 'O', 'K'}, want: bridgeRequest{kind: "BrailleText", text: "OK"}}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := decodeRequest(websocket.BinaryMessage, test.payload) + if err != nil { + t.Fatalf("decodeRequest() error = %v", err) + } + if got.kind != test.want.kind || got.text != test.want.text { + t.Fatalf("decodeRequest() = %+v, want %+v", got, test.want) + } + }) + } +} + +func TestDecodeMessagePackRejectsMalformedContainers(t *testing.T) { + for _, payload := range [][]byte{ + {0x81, 0x90, 0xc0}, // An array key cannot be inserted into a Go map. + append(append([]byte{}, bytes.Repeat([]byte{0x91}, 66)...), 0xc0), + {0xa2, 'O', 'K', 0xc0}, // One WebSocket frame contains exactly one request. + } { + if _, err := decodeRequest(websocket.BinaryMessage, payload); err == nil { + t.Fatalf("accepted malformed MessagePack payload %x", payload) + } + } +} diff --git a/internal/nvda2cthulhu/protocol.go b/internal/nvda2cthulhu/protocol.go new file mode 100644 index 0000000..98375f2 --- /dev/null +++ b/internal/nvda2cthulhu/protocol.go @@ -0,0 +1,154 @@ +// Package nvda2cthulhu accepts the local WebSocket protocol used by NVDA +// compatibility bridges and routes it to Cthulhu's speech and braille queues. +package nvda2cthulhu + +import ( + "bytes" + "errors" + "strconv" + "strings" + + "github.com/gorilla/websocket" +) + +func (server *Server) deliver(request bridgeRequest) { + switch request.kind { + case "SpeakText": + if server.handler.SpeakText(request.text, true) { + server.logger.Debug("NVDA to Cthulhu speech accepted", "bytes", len(request.text)) + } else { + server.logger.Warn("NVDA to Cthulhu speech rejected", "bytes", len(request.text)) + } + case "BrailleText": + if server.handler.BrailleMessage(request.text) { + server.logger.Debug("NVDA to Cthulhu braille accepted", "bytes", len(request.text)) + } else { + server.logger.Debug("NVDA to Cthulhu braille unavailable") + } + case "CancelSpeech": + if server.handler.CancelSpeech() { + server.logger.Debug("NVDA to Cthulhu cancellation accepted") + } else { + server.logger.Warn("NVDA to Cthulhu cancellation rejected") + } + } +} + +type bridgeRequest struct { + kind, text string +} + +func decodeRequest(messageType int, payload []byte) (bridgeRequest, error) { + if len(payload) > maxPayload { + return bridgeRequest{}, errors.New("message exceeds 64 KiB") + } + switch messageType { + case websocket.TextMessage: + return parseRequest(string(payload)) + case websocket.BinaryMessage: + reader := bytes.NewReader(payload) + value, err := decodeMessagePack(reader) + if err != nil { + return bridgeRequest{}, err + } + if reader.Len() != 0 { + return bridgeRequest{}, errors.New("trailing MessagePack data") + } + return parseRequest(value) + default: + return bridgeRequest{}, errors.New("unsupported WebSocket message type") + } +} + +func parseRequest(value any) (bridgeRequest, error) { + switch payload := value.(type) { + case string: + if strings.TrimSpace(payload) == "" { + return bridgeRequest{}, errors.New("blank text request") + } + if payload == "CancelSpeech" { + return bridgeRequest{kind: "CancelSpeech"}, nil + } + return bridgeRequest{kind: "SpeakText", text: payload}, nil + case map[any]any: + if len(payload) != 1 { + return bridgeRequest{}, errors.New("map request must contain exactly one entry") + } + for key, value := range payload { + return keyedRequest(coerceText(key), value) + } + case map[string]any: + if len(payload) != 1 { + return bridgeRequest{}, errors.New("map request must contain exactly one entry") + } + for key, value := range payload { + return keyedRequest(key, value) + } + case []any: + if len(payload) == 0 { + return bridgeRequest{}, errors.New("array request is empty") + } + kind := coerceText(payload[0]) + if kind == "CancelSpeech" { + return bridgeRequest{kind: "CancelSpeech"}, nil + } + if len(payload) < 2 { + return bridgeRequest{}, errors.New("array request has no value") + } + return keyedRequest(kind, payload[1]) + } + return bridgeRequest{}, errors.New("unsupported MessagePack payload") +} + +func keyedRequest(kind string, value any) (bridgeRequest, error) { + switch kind { + case "CancelSpeech": + return bridgeRequest{kind: "CancelSpeech"}, nil + case "SpeakText", "BrailleText": + if strings.TrimSpace(coerceText(value)) == "" { + return bridgeRequest{}, errors.New("blank text request") + } + return bridgeRequest{kind: kind, text: coerceText(value)}, nil + default: + return bridgeRequest{}, errors.New("unsupported request kind") + } +} + +func coerceText(value any) string { + switch text := value.(type) { + case string: + return text + case messagePackBinary: + return string(text) + case nil: + return "" + case bool: + return strconv.FormatBool(text) + case int: + return strconv.Itoa(text) + case int8: + return strconv.FormatInt(int64(text), 10) + case int16: + return strconv.FormatInt(int64(text), 10) + case int32: + return strconv.FormatInt(int64(text), 10) + case int64: + return strconv.FormatInt(text, 10) + case uint: + return strconv.FormatUint(uint64(text), 10) + case uint8: + return strconv.FormatUint(uint64(text), 10) + case uint16: + return strconv.FormatUint(uint64(text), 10) + case uint32: + return strconv.FormatUint(uint64(text), 10) + case uint64: + return strconv.FormatUint(text, 10) + case float32: + return strconv.FormatFloat(float64(text), 'g', -1, 32) + case float64: + return strconv.FormatFloat(text, 'g', -1, 64) + default: + return "" + } +} diff --git a/internal/nvda2cthulhu/protocol_test.go b/internal/nvda2cthulhu/protocol_test.go new file mode 100644 index 0000000..f2483eb --- /dev/null +++ b/internal/nvda2cthulhu/protocol_test.go @@ -0,0 +1,40 @@ +package nvda2cthulhu + +import ( + "testing" +) + +func TestParseRequestMatchesPythonCompatibilityProtocol(t *testing.T) { + tests := []struct { + name string + value any + want bridgeRequest + }{ + {name: "text", value: "Game text", want: bridgeRequest{kind: "SpeakText", text: "Game text"}}, + {name: "cancel string", value: "CancelSpeech", want: bridgeRequest{kind: "CancelSpeech"}}, + {name: "speech map", value: map[any]any{"SpeakText": "Map text"}, want: bridgeRequest{kind: "SpeakText", text: "Map text"}}, + {name: "braille map", value: map[string]any{"BrailleText": "Braille"}, want: bridgeRequest{kind: "BrailleText", text: "Braille"}}, + {name: "cancel map", value: map[any]any{"CancelSpeech": nil}, want: bridgeRequest{kind: "CancelSpeech"}}, + {name: "speech array", value: []any{"SpeakText", "Array text"}, want: bridgeRequest{kind: "SpeakText", text: "Array text"}}, + {name: "cancel array", value: []any{"CancelSpeech"}, want: bridgeRequest{kind: "CancelSpeech"}}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := parseRequest(test.value) + if err != nil { + t.Fatalf("parseRequest() error = %v", err) + } + if got.kind != test.want.kind || got.text != test.want.text { + t.Fatalf("parseRequest() = %+v, want %+v", got, test.want) + } + }) + } +} + +func TestParseRequestRejectsUnknownAndMalformedPayloads(t *testing.T) { + for _, value := range []any{"", map[any]any{}, map[any]any{"Two": "values", "SpeakText": "text"}, []any{}, []any{"Unknown", "value"}} { + if request, err := parseRequest(value); err == nil { + t.Fatalf("parseRequest(%#v) = %+v, want error", value, request) + } + } +} diff --git a/internal/nvda2cthulhu/server.go b/internal/nvda2cthulhu/server.go new file mode 100644 index 0000000..262eb2a --- /dev/null +++ b/internal/nvda2cthulhu/server.go @@ -0,0 +1,196 @@ +// Package nvda2cthulhu accepts the local WebSocket protocol used by NVDA +// compatibility bridges and routes it to Cthulhu's speech and braille queues. +package nvda2cthulhu + +import ( + "context" + "errors" + "fmt" + "log/slog" + "net" + "net/http" + "net/url" + "os" + "strconv" + "sync" + "time" + + "github.com/gorilla/websocket" +) + +const ( + defaultPort = 3457 + hostEnv = "NVDA2SPEECHD_HOST" + maxPayload = 64 * 1024 +) + +// Handler accepts already-decoded bridge requests. Implementations must +// enqueue backend work instead of waiting for speech or braille output. +type Handler interface { + SpeakText(string, bool) bool + BrailleMessage(string) bool + CancelSpeech() bool +} + +// Server owns the local bridge listener and active WebSocket connections. +type Server struct { + logger *slog.Logger + handler Handler + connections map[*websocket.Conn]struct{} + connectionWait sync.WaitGroup + stopOnce sync.Once + stopped chan struct{} + + mutex sync.Mutex + server *http.Server +} + +// New creates a bridge server. A nil logger discards diagnostics. +func New(logger *slog.Logger, handler Handler) *Server { + if logger == nil { + logger = slog.New(slog.DiscardHandler) + } + return &Server{ + logger: logger, + handler: handler, + connections: make(map[*websocket.Conn]struct{}), + stopped: make(chan struct{}), + } +} + +// Start binds the same local address used by Python Cthulhu. The listener is +// established before Start returns, while connection handling stays async. +func (server *Server) Start(ctx context.Context) error { + listener, err := net.Listen("tcp", bindAddress()) + if err != nil { + return fmt.Errorf("bind NVDA to Cthulhu bridge: %w", err) + } + httpServer := &http.Server{ + Handler: http.HandlerFunc(server.handleHTTP), + ReadHeaderTimeout: 5 * time.Second, + } + server.mutex.Lock() + server.server = httpServer + server.mutex.Unlock() + go func() { + if err := httpServer.Serve(listener); err != nil && !errors.Is(err, http.ErrServerClosed) { + server.logger.Warn("NVDA to Cthulhu server stopped", "error", err) + } + }() + server.logger.Info("NVDA to Cthulhu listening", "address", bindAddress()) + return nil +} + +// Stop closes the listener and active connections. +func (server *Server) Stop(ctx context.Context) error { + server.stopOnce.Do(func() { + close(server.stopped) + }) + server.mutex.Lock() + httpServer := server.server + connections := make([]*websocket.Conn, 0, len(server.connections)) + for connection := range server.connections { + connections = append(connections, connection) + } + server.mutex.Unlock() + for _, connection := range connections { + _ = connection.Close() + } + if httpServer == nil { + return server.waitConnections(ctx) + } + if err := httpServer.Shutdown(ctx); err != nil && !errors.Is(err, context.Canceled) { + return fmt.Errorf("stop NVDA to Cthulhu bridge: %w", err) + } + return server.waitConnections(ctx) +} + +func (server *Server) handleHTTP(response http.ResponseWriter, request *http.Request) { + if request.URL.Path != "/" { + http.NotFound(response, request) + return + } + upgrader := websocket.Upgrader{ + CheckOrigin: allowedOrigin, + } + connection, err := upgrader.Upgrade(response, request, nil) + if err != nil { + server.logger.Warn("NVDA to Cthulhu connection rejected", "error", err) + return + } + defer connection.Close() + server.mutex.Lock() + select { + case <-server.stopped: + server.mutex.Unlock() + return + default: + server.connectionWait.Add(1) + server.connections[connection] = struct{}{} + server.mutex.Unlock() + } + defer func() { + server.mutex.Lock() + delete(server.connections, connection) + server.mutex.Unlock() + server.connectionWait.Done() + }() + connection.SetReadLimit(maxPayload) + server.logger.Debug("NVDA to Cthulhu client connected", "remote", connection.RemoteAddr().String()) + for { + messageType, payload, err := connection.ReadMessage() + if err != nil { + if !websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) { + server.logger.Debug("NVDA to Cthulhu client disconnected", "error", err) + } + return + } + if len(payload) > maxPayload { + server.logger.Warn("NVDA to Cthulhu message too large", "size", len(payload)) + return + } + request, err := decodeRequest(messageType, payload) + if err != nil { + server.logger.Warn("NVDA to Cthulhu rejected message", "error", err) + continue + } + server.deliver(request) + } +} + +func (server *Server) waitConnections(ctx context.Context) error { + done := make(chan struct{}) + go func() { + server.connectionWait.Wait() + close(done) + }() + select { + case <-done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func bindAddress() string { + port := defaultPort + if value := os.Getenv(hostEnv); value != "" { + if parsed, err := url.Parse(value); err == nil && parsed.Port() != "" { + port, _ = strconv.Atoi(parsed.Port()) + } + } + return net.JoinHostPort("127.0.0.1", strconv.Itoa(port)) +} + +func allowedOrigin(request *http.Request) bool { + origin := request.Header.Get("Origin") + if origin == "" { + return true // Native bridge clients do not send a browser origin. + } + parsed, err := url.Parse(origin) + if err != nil || (parsed.Scheme != "http" && parsed.Scheme != "https") || parsed.User != nil { + return false + } + host := parsed.Hostname() + return host == "localhost" || net.ParseIP(host).IsLoopback() +} diff --git a/internal/nvda2cthulhu/server_test.go b/internal/nvda2cthulhu/server_test.go new file mode 100644 index 0000000..4e2137f --- /dev/null +++ b/internal/nvda2cthulhu/server_test.go @@ -0,0 +1,171 @@ +package nvda2cthulhu + +import ( + "context" + "fmt" + "net" + "net/http" + "net/http/httptest" + "os" + "strings" + "sync" + "testing" + "time" + + "github.com/gorilla/websocket" +) + +type recordingHandler struct { + mutex sync.Mutex + spoken []string + interrupt []bool + braille []string + canceled int +} + +func (handler *recordingHandler) SpeakText(text string, interrupt bool) bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.spoken = append(handler.spoken, text) + handler.interrupt = append(handler.interrupt, interrupt) + return true +} + +func (handler *recordingHandler) BrailleMessage(text string) bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.braille = append(handler.braille, text) + return true +} + +func (handler *recordingHandler) CancelSpeech() bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.canceled++ + return true +} + +func TestAllowedOriginAcceptsNativeAndLoopbackClients(t *testing.T) { + for _, test := range []struct { + origin string + want bool + }{ + {"", true}, + {"http://127.0.0.1:3457", true}, + {"http://localhost:3457", true}, + {"https://[::1]:3457", true}, + {"https://example.com", false}, + {"null", false}, + } { + request := httptest.NewRequest(http.MethodGet, "http://127.0.0.1:3457/", nil) + if test.origin != "" { + request.Header.Set("Origin", test.origin) + } + if got := allowedOrigin(request); got != test.want { + t.Errorf("allowedOrigin(%q) = %v, want %v", test.origin, got, test.want) + } + } +} + +func liveSocketTest(t *testing.T) { + t.Helper() + handler := &recordingHandler{} + server := New(nil, handler) + httpTest := httptest.NewServer(http.HandlerFunc(server.handleHTTP)) + defer httpTest.Close() + url := "ws" + strings.TrimPrefix(httpTest.URL, "http") + connection, _, err := websocket.DefaultDialer.Dial(url, nil) + if err != nil { + t.Fatalf("dial WebSocket: %v", err) + } + defer connection.Close() + + if err := connection.WriteMessage(websocket.TextMessage, []byte("Accessibility mod loaded.")); err != nil { + t.Fatalf("write speech text: %v", err) + } + if err := connection.WriteMessage(websocket.BinaryMessage, []byte{0x81, 0xab, 'B', 'r', 'a', 'i', 'l', 'l', 'e', 'T', 'e', 'x', 't', 0xa2, 'O', 'K'}); err != nil { + t.Fatalf("write braille text: %v", err) + } + if err := connection.WriteMessage(websocket.TextMessage, []byte("CancelSpeech")); err != nil { + t.Fatalf("write cancellation: %v", err) + } + + waitForHandlerCalls(t, handler) + handler.mutex.Lock() + defer handler.mutex.Unlock() + if len(handler.spoken) != 1 || handler.spoken[0] != "Accessibility mod loaded." || len(handler.interrupt) != 1 || !handler.interrupt[0] { + t.Fatalf("speech calls = %v, interrupts = %v", handler.spoken, handler.interrupt) + } + if len(handler.braille) != 1 || handler.braille[0] != "OK" { + t.Fatalf("braille calls = %v", handler.braille) + } + if handler.canceled != 1 { + t.Fatalf("cancellations = %d, want 1", handler.canceled) + } +} + +func TestServerHandlesWebSocketRequests(t *testing.T) { + if os.Getenv("CTHULHU_LIVE_SOCKET_TEST") != "1" { + t.Skip("set CTHULHU_LIVE_SOCKET_TEST=1 to allow a local TCP listener") + } + liveSocketTest(t) +} + +func TestStartStopClosesActiveConnection(t *testing.T) { + if os.Getenv("CTHULHU_LIVE_SOCKET_TEST") != "1" { + t.Skip("set CTHULHU_LIVE_SOCKET_TEST=1 to allow a local TCP listener") + } + listener, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("find port: %v", err) + } + port := listener.Addr().(*net.TCPAddr).Port + if err := listener.Close(); err != nil { + t.Fatalf("release port: %v", err) + } + t.Setenv(hostEnv, fmt.Sprintf("http://127.0.0.1:%d", port)) + + server := New(nil, &recordingHandler{}) + if err := server.Start(context.Background()); err != nil { + t.Fatalf("start server: %v", err) + } + connection, _, err := websocket.DefaultDialer.Dial(fmt.Sprintf("ws://127.0.0.1:%d", port), nil) + if err != nil { + t.Fatalf("dial server: %v", err) + } + defer connection.Close() + if err := server.Stop(context.Background()); err != nil { + t.Fatalf("stop server: %v", err) + } + if _, _, err := connection.ReadMessage(); err == nil { + t.Fatal("active connection remained open after Stop") + } +} + +func waitForHandlerCalls(t *testing.T, handler *recordingHandler) { + t.Helper() + deadline := time.Now().Add(2 * time.Second) + for time.Now().Before(deadline) { + handler.mutex.Lock() + done := len(handler.spoken) == 1 && len(handler.braille) == 1 && handler.canceled == 1 + handler.mutex.Unlock() + if done { + return + } + time.Sleep(10 * time.Millisecond) + } +} + +func TestBindAddressUsesPythonDefault(t *testing.T) { + t.Setenv(hostEnv, "http://127.0.0.1") + if address := bindAddress(); address != "127.0.0.1:3457" { + t.Fatalf("default address = %q", address) + } +} + +func TestStopWithoutStartSucceeds(t *testing.T) { + server := New(nil, nil) + if err := server.Stop(context.Background()); err != nil { + t.Fatalf("stop unstarted server: %v", err) + } +} diff --git a/internal/ocr/capture.go b/internal/ocr/capture.go new file mode 100644 index 0000000..41735b8 --- /dev/null +++ b/internal/ocr/capture.go @@ -0,0 +1,247 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "image" + "image/png" + "io" + "os/exec" + "time" +) + +var ( + ErrCapture = errors.New("OCR capture unavailable") + ErrSource = errors.New("OCR source unavailable") + ErrSourceChanged = errors.New("OCR source changed") +) + +type SourceKind string + +const ( + ObjectSource SourceKind = "object" + WindowSource SourceKind = "window" + DesktopSource SourceKind = "desktop" + ClipboardSource SourceKind = "clipboard" + maxCaptureHeader = 4096 + captureTimeout = 2 * time.Second +) + +// CaptureRequest is an immutable job snapshot. Bounds are physical X11 root +// pixels, not GTK logical coordinates. The future target owner must convert +// provider coordinates before requesting capture and retain its object identity. +// Generation belongs to that owner, which must retire jobs on focus/lock/loss. +// Foreground is required even for clipboard capture. Window may name a child of +// Foreground (for example a Wine client); zero selects the foreground client. +type CaptureRequest struct { + Kind SourceKind + Bounds image.Rectangle + Foreground uint64 + Window uint64 + Generation uint64 +} + +func (request CaptureRequest) Validate() error { + if request.Foreground == 0 || request.Foreground > 0xffffffff || request.Window > 0xffffffff || request.Generation == 0 { + return ErrSource + } + switch request.Kind { + case ObjectSource: + if !valid_screen_rectangle(request.Bounds) { + return ErrSource + } + case WindowSource, DesktopSource, ClipboardSource: + if request.Bounds != (image.Rectangle{}) { + return ErrSource + } + default: + return ErrSource + } + if request.Kind != WindowSource && request.Window != 0 { + return ErrSource + } + return nil +} + +// CaptureHeader precedes a PNG on the private pipe. Rectangles describe physical +// root pixels. No monitor topology, object identity or activation authorization +// is inferred from them. Clipboard pixels have no screen mapping. +type CaptureHeader struct { + Request CaptureRequest + SourceWindow uint64 + RootBounds image.Rectangle + SourceBounds image.Rectangle + ScreenBounds image.Rectangle + Status string +} + +type Capture struct { + CaptureHeader + Pixels image.Image + Transform Transform +} + +// Capturer owns one helper at a time. It performs no startup I/O. Run Capture +// on a worker, never the input/event thread. The executable must be the reader +// binary supporting --ocr-capture; it is invoked directly without a shell. +type Capturer struct { + gate chan struct{} + command func(context.Context, ...string) *exec.Cmd +} + +func NewCapturer(executable string) *Capturer { + return &Capturer{gate: make(chan struct{}, 1), command: func(ctx context.Context, args ...string) *exec.Cmd { + return exec.CommandContext(ctx, executable, args...) + }} +} + +func (capturer *Capturer) Capture(ctx context.Context, request CaptureRequest) (Capture, error) { + if err := request.Validate(); err != nil { + return Capture{}, err + } + ctx, cancel := context.WithTimeout(ctx, captureTimeout) + defer cancel() + select { + case capturer.gate <- struct{}{}: + defer func() { <-capturer.gate }() + case <-ctx.Done(): + return Capture{}, ctx.Err() + } + if err := ctx.Err(); err != nil { + return Capture{}, err + } + input, err := json.Marshal(request) + if err != nil { + return Capture{}, ErrSource + } + output, _, err := run_process(ctx, capturer.command, input, maxImageBytes+maxCaptureHeader, "--ocr-capture") + if err != nil { + if errors.Is(err, ErrUnavailable) || errors.Is(err, ErrRecognition) { + return Capture{}, ErrCapture + } + return Capture{}, err + } + capture, err := decode_capture(output, request) + if ctx.Err() != nil { + return Capture{}, ctx.Err() + } + return capture, err +} + +// ReadCaptureRequest bounds and validates the helper's one request before any +// GTK/X11 initialization. Unknown fields and trailing messages are rejected. +func ReadCaptureRequest(input io.Reader) (CaptureRequest, error) { + data, err := io.ReadAll(io.LimitReader(input, maxCaptureHeader+1)) + if err != nil || len(data) > maxCaptureHeader { + return CaptureRequest{}, ErrLimit + } + var request CaptureRequest + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + if decoder.Decode(&request) != nil || decoder.Decode(new(any)) != io.EOF { + return CaptureRequest{}, ErrSource + } + return request, request.Validate() +} + +// WriteCaptureResponse retains a complete bounded frame before publishing it. +// Failures contain a fixed status only; native diagnostics never cross the pipe. +func WriteCaptureResponse(output io.Writer, header CaptureHeader, pixels image.Image) error { + data, err := json.Marshal(header) + if err != nil || len(data)+1 > maxCaptureHeader { + return ErrLimit + } + buffer := &bounded_buffer{ctx: context.Background(), limit: maxImageBytes + maxCaptureHeader} + _, _ = buffer.Write(append(data, '\n')) + if header.Status == "" { + if pixels == nil || !valid_dimensions(pixels.Bounds().Dx(), pixels.Bounds().Dy()) { + return ErrInvalidImage + } + if err := png.Encode(buffer, pixels); err != nil { + return err + } + } + _, err = output.Write(buffer.Bytes()) + return err +} + +func decode_capture(data []byte, request CaptureRequest) (Capture, error) { + separator := bytes.IndexByte(data, '\n') + if separator < 0 || separator >= maxCaptureHeader || len(data) > maxImageBytes+maxCaptureHeader { + return Capture{}, ErrCapture + } + var header CaptureHeader + decoder := json.NewDecoder(bytes.NewReader(data[:separator])) + decoder.DisallowUnknownFields() + if decoder.Decode(&header) != nil || decoder.Decode(new(any)) != io.EOF || header.Request != request { + return Capture{}, ErrCapture + } + if header.Status != "" { + if len(data) != separator+1 { + return Capture{}, ErrCapture + } + switch header.Status { + case "unavailable": + return Capture{}, ErrCapture + case "source": + return Capture{}, ErrSource + case "changed": + return Capture{}, ErrSourceChanged + case "limit": + return Capture{}, ErrLimit + default: + return Capture{}, ErrCapture + } + } + payload := data[separator+1:] + config, err := png.DecodeConfig(bytes.NewReader(payload)) + if err != nil { + return Capture{}, ErrCapture + } + if !valid_dimensions(config.Width, config.Height) { + return Capture{}, ErrLimit + } + transform := Transform{ImageContent: image.Rect(0, 0, config.Width, config.Height)} + if request.Kind == ClipboardSource { + if header.SourceWindow != 0 || header.RootBounds != (image.Rectangle{}) || header.SourceBounds != (image.Rectangle{}) || header.ScreenBounds != (image.Rectangle{}) { + return Capture{}, ErrCapture + } + } else { + if !valid_screen_rectangle(header.RootBounds) || !valid_screen_rectangle(header.SourceBounds) || + !valid_screen_rectangle(header.ScreenBounds) || !header.ScreenBounds.In(header.RootBounds) || !header.ScreenBounds.In(header.SourceBounds) || + header.ScreenBounds.Dx() != config.Width || header.ScreenBounds.Dy() != config.Height { + return Capture{}, ErrCapture + } + sourceWindow := request.Foreground + if request.Kind == WindowSource && request.Window != 0 { + sourceWindow = request.Window + } + if request.Kind == DesktopSource { + sourceWindow = 0 + if header.SourceBounds != header.RootBounds || header.ScreenBounds != header.RootBounds { + return Capture{}, ErrCapture + } + } else if request.Kind == ObjectSource && header.ScreenBounds != request.Bounds.Intersect(header.SourceBounds).Intersect(header.RootBounds) { + return Capture{}, ErrCapture + } + if request.Kind == WindowSource && header.ScreenBounds != header.SourceBounds.Intersect(header.RootBounds) { + return Capture{}, ErrCapture + } + if header.SourceWindow != sourceWindow { + return Capture{}, ErrCapture + } + transform.HasScreenMapping, transform.ScreenBounds = true, header.ScreenBounds + } + payloadReader := bytes.NewReader(payload) + pixels, err := png.Decode(payloadReader) + if err != nil || payloadReader.Len() != 0 { + return Capture{}, ErrCapture + } + return Capture{CaptureHeader: header, Pixels: pixels, Transform: transform}, nil +} diff --git a/internal/ocr/capture_native_test.go b/internal/ocr/capture_native_test.go new file mode 100644 index 0000000..2461da1 --- /dev/null +++ b/internal/ocr/capture_native_test.go @@ -0,0 +1,231 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "image" + "image/color" + "os" + "os/exec" + "testing" + "time" +) + +// Run only on a private display with a freshly built helper binary. +func TestNativeOCRCapture(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_OCR_CAPTURE") != "1" { + t.Skip("private Xvfb fixture only") + } + executable := os.Getenv("CTHULHU_OCR_CAPTURE_BINARY") + if executable == "" { + t.Fatal("set CTHULHU_OCR_CAPTURE_BINARY to a freshly built reader") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-u", "../../tests/ocr_capture_fixture.py") + fixture.Env = append(os.Environ(), "NO_AT_BRIDGE=1", "GTK_MODULES=") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err = fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { _ = stdin.Close(); _ = fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + if !scanner.Scan() { + t.Fatal("fixture did not start") + } + var windows map[string]uint64 + if err = json.Unmarshal(scanner.Bytes(), &windows); err != nil { + t.Fatal(err) + } + command := func(command map[string]any) map[string]uint64 { + t.Helper() + data, _ := json.Marshal(command) + if _, err := stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() { + t.Fatal("fixture did not respond") + } + var state map[string]uint64 + if err := json.Unmarshal(scanner.Bytes(), &state); err != nil { + t.Fatal(err) + } + return state + } + state := func() map[string]uint64 { return command(map[string]any{"action": "state"}) } + capturer := NewCapturer(executable) + request := CaptureRequest{Kind: WindowSource, Foreground: windows["window"], Generation: 1} + capture := func(request CaptureRequest) Capture { + t.Helper() + before := state() + result, err := capturer.Capture(ctx, request) + if err != nil { + t.Fatal(err) + } + after := state() + if before["focus"] != after["focus"] || before["windows"] != after["windows"] { + t.Fatalf("capture changed native focus/windows: %v -> %v", before, after) + } + return result + } + expectPixel := func(result Capture, point image.Point, want color.RGBA) { + t.Helper() + got := color.RGBAModel.Convert(result.Pixels.At(point.X, point.Y)).(color.RGBA) + if got != want { + t.Fatalf("pixel %v = %v, want %v", point, got, want) + } + } + // XGetImage uses physical pixels at both GDK scales. Provider conversion is + // intentionally a separate target-owner gate, not established by this test. + for _, scale := range []string{"1", "2"} { + t.Setenv("GDK_SCALE", scale) + result := capture(request) + if result.ScreenBounds != image.Rect(40, 30, 340, 230) || result.Pixels.Bounds() != image.Rect(0, 0, 300, 200) { + t.Fatalf("scale %s capture: %+v", scale, result.CaptureHeader) + } + expectPixel(result, image.Pt(0, 0), color.RGBA{0x33, 0x66, 0x99, 255}) + expectPixel(result, image.Pt(10, 15), color.RGBA{0xab, 0xcd, 0xef, 255}) + mapped, ok := result.Transform.ScreenRectangle(image.Rect(10, 15, 20, 25)) + if !ok || mapped != image.Rect(50, 45, 60, 55) { + t.Fatalf("pixel mapping: %v, %v", mapped, ok) + } + } + t.Setenv("GDK_SCALE", "1") + // A usable X11 source must not be rejected solely by the session label. + // This tests policy on Xvfb, not capture on a real Wayland compositor. + t.Setenv("XDG_SESSION_TYPE", "wayland") + expectPixel(capture(request), image.Pt(0, 0), color.RGBA{0x33, 0x66, 0x99, 255}) + t.Setenv("XDG_SESSION_TYPE", "x11") + childRequest := request + childRequest.Window = windows["child"] + child := capture(childRequest) + if child.ScreenBounds != image.Rect(50, 45, 130, 95) { + t.Fatalf("child capture: %+v", child.CaptureHeader) + } + expectPixel(child, image.Pt(0, 0), color.RGBA{0xab, 0xcd, 0xef, 255}) + objectRequest := request + objectRequest.Kind, objectRequest.Bounds = ObjectSource, image.Rect(-10, -10, 90, 100) + if result := capture(objectRequest); result.ScreenBounds != image.Rect(40, 30, 90, 100) { + t.Fatalf("object clip: %+v", result.CaptureHeader) + } + objectRequest.Bounds = image.Rect(-100, -100, -1, -1) + if _, err := capturer.Capture(ctx, objectRequest); !errors.Is(err, ErrSource) { + t.Fatalf("offscreen source: %v", err) + } + desktopRequest := request + desktopRequest.Kind = DesktopSource + desktop := capture(desktopRequest) + if desktop.ScreenBounds != desktop.RootBounds || desktop.SourceWindow != 0 { + t.Fatalf("desktop: %+v", desktop.CaptureHeader) + } + expectPixel(desktop, image.Pt(350, 30), color.RGBA{0x99, 0x22, 0x44, 255}) + if os.Getenv("CTHULHU_NATIVE_OCR") == "1" { + command(map[string]any{"action": "activate", "window": "painted"}) + paintedRequest := request + paintedRequest.Foreground = windows["painted"] + painted := capture(paintedRequest) + result, err := NewEngine().Recognize(ctx, painted.Pixels, Options{}) + if err != nil || result.Text != "OCR test window\nOpen Settings\nValue 42" { + t.Fatalf("captured X11 recognition: %q, %v", result.Text, err) + } + word, ok := result.WordAt(0) + mapped, mappedOK := painted.Transform.ScreenRectangle(word.Bounds) + if !ok || !mappedOK || !mapped.In(painted.ScreenBounds) { + t.Fatalf("recognized screen word mapping: %v, %v", mapped, mappedOK) + } + command(map[string]any{"action": "activate"}) + } + clipboardRequest := request + clipboardRequest.Kind = ClipboardSource + clipboard := capture(clipboardRequest) + if clipboard.Transform.HasScreenMapping || clipboard.Pixels.Bounds() != image.Rect(0, 0, 640, 220) { + t.Fatalf("clipboard mapping: %+v", clipboard.CaptureHeader) + } + command(map[string]any{"action": "clipboard-text"}) + if _, err := capturer.Capture(ctx, clipboardRequest); !errors.Is(err, ErrSource) { + t.Fatalf("text clipboard captured as image: %v", err) + } + // The earlier snapshot survives clipboard replacement and is recognized from + // those owned pixels rather than fetching the current clipboard again. + if os.Getenv("CTHULHU_NATIVE_OCR") == "1" { + result, err := NewEngine().Recognize(ctx, clipboard.Pixels, Options{}) + if err != nil || result.Text != "OCR test window\nOpen Settings\nValue 42" { + t.Fatalf("captured clipboard recognition: %q, %v", result.Text, err) + } + } + // Synchronize on the real selection request, switch foreground during the + // native transfer, and release pixels. The helper must reject that result. + command(map[string]any{"action": "clipboard-block"}) + completed := make(chan error, 1) + go func() { _, err := capturer.Capture(ctx, clipboardRequest); completed <- err }() + if !scanner.Scan() || scanner.Text() != `{"capture-request": 1}` { + t.Fatal("clipboard capture did not request its pixels") + } + command(map[string]any{"action": "activate", "window": "other"}) + command(map[string]any{"action": "clipboard-release"}) + if err := <-completed; !errors.Is(err, ErrSourceChanged) { + t.Fatalf("foreground change during capture: %v", err) + } + command(map[string]any{"action": "activate"}) + go func() { _, err := capturer.Capture(ctx, clipboardRequest); completed <- err }() + if !scanner.Scan() || scanner.Text() != `{"capture-request": 1}` { + t.Fatal("geometry-change capture did not start") + } + command(map[string]any{"action": "resize", "width": 310, "height": 210}) + command(map[string]any{"action": "clipboard-release"}) + if err := <-completed; !errors.Is(err, ErrSourceChanged) { + t.Fatalf("geometry change during capture: %v", err) + } + command(map[string]any{"action": "resize", "width": 300, "height": 200}) + // A provider that never replies must not hold the reader's worker forever. + go func() { _, err := capturer.Capture(ctx, clipboardRequest); completed <- err }() + if !scanner.Scan() || scanner.Text() != `{"capture-request": 1}` { + t.Fatal("blocked clipboard capture did not start") + } + if err := <-completed; !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("blocked native clipboard deadline: %v", err) + } + command(map[string]any{"action": "clipboard-text"}) + command(map[string]any{"action": "overlay"}) + expectPixel(capture(request), image.Pt(0, 0), color.RGBA{0xaa, 0x11, 0, 255}) + command(map[string]any{"action": "move", "x": -20, "y": -10}) + if result := capture(request); result.ScreenBounds != image.Rect(0, 0, 280, 190) || result.SourceBounds != image.Rect(-20, -10, 280, 190) { + t.Fatalf("negative window clip: %+v", result.CaptureHeader) + } + command(map[string]any{"action": "activate", "window": "other"}) + if _, err := capturer.Capture(ctx, request); !errors.Is(err, ErrSourceChanged) { + t.Fatalf("foreground mismatch: %v", err) + } + childRequest.Foreground = windows["other"] + childRequest.Window = windows["child"] + if _, err := capturer.Capture(ctx, childRequest); !errors.Is(err, ErrSource) { + t.Fatalf("unrelated window accepted: %v", err) + } + command(map[string]any{"action": "activate"}) + command(map[string]any{"action": "hide"}) + if _, err := capturer.Capture(ctx, request); !errors.Is(err, ErrSource) { + t.Fatalf("hidden window: %v", err) + } + command(map[string]any{"action": "destroy"}) + if _, err := capturer.Capture(ctx, request); !errors.Is(err, ErrSource) { + t.Fatalf("destroyed window: %v", err) + } + t.Setenv("DISPLAY", "") + if _, err := capturer.Capture(ctx, request); !errors.Is(err, ErrCapture) { + t.Fatalf("missing display: %v", err) + } +} diff --git a/internal/ocr/capture_test.go b/internal/ocr/capture_test.go new file mode 100644 index 0000000..2988337 --- /dev/null +++ b/internal/ocr/capture_test.go @@ -0,0 +1,232 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "bytes" + "context" + "encoding/binary" + "encoding/json" + "errors" + "hash/crc32" + "image" + "image/color" + "io" + "math" + "os" + "os/exec" + "strconv" + "strings" + "syscall" + "testing" + "time" +) + +func capture_request() CaptureRequest { + return CaptureRequest{Kind: ObjectSource, Bounds: image.Rect(-20, 10, 30, 50), Foreground: 123, Generation: 7} +} + +func capture_frame(t *testing.T, header CaptureHeader, pixels image.Image) []byte { + t.Helper() + var output bytes.Buffer + if err := WriteCaptureResponse(&output, header, pixels); err != nil { + t.Fatal(err) + } + return output.Bytes() +} + +func TestCaptureRequestRejectsUnownedOrInvalidSources(t *testing.T) { + base := capture_request() + if err := base.Validate(); err != nil { + t.Fatal(err) + } + mutations := []func(*CaptureRequest){ + func(r *CaptureRequest) { r.Foreground = 0 }, + func(r *CaptureRequest) { r.Foreground = 1 << 32 }, + func(r *CaptureRequest) { r.Generation = 0 }, + func(r *CaptureRequest) { r.Kind = "unknown" }, + func(r *CaptureRequest) { r.Bounds = image.Rectangle{} }, + func(r *CaptureRequest) { r.Bounds.Min.X = math.MinInt32 }, + func(r *CaptureRequest) { r.Bounds = image.Rect(0, 0, MaxPixels+1, 1) }, + func(r *CaptureRequest) { r.Window = 42 }, + func(r *CaptureRequest) { r.Kind = WindowSource }, + } + for _, mutate := range mutations { + request := base + mutate(&request) + if !errors.Is(request.Validate(), ErrSource) { + t.Fatalf("invalid request accepted: %+v", request) + } + } + for _, kind := range []SourceKind{WindowSource, DesktopSource, ClipboardSource} { + request := base + request.Kind, request.Bounds = kind, image.Rectangle{} + if err := request.Validate(); err != nil { + t.Fatal(err) + } + } + data, _ := json.Marshal(base) + request, err := ReadCaptureRequest(bytes.NewReader(data)) + if err != nil || request != base { + t.Fatalf("request roundtrip: %+v, %v", request, err) + } + for _, invalid := range [][]byte{nil, []byte("{}"), append(append([]byte(nil), data...), data...), []byte(`{"Private":"generic"}`), bytes.Repeat([]byte{' '}, maxCaptureHeader+1)} { + if _, err := ReadCaptureRequest(bytes.NewReader(invalid)); err == nil { + t.Fatal("invalid private request accepted") + } + } +} + +func TestCaptureFrameClippingAndGeneration(t *testing.T) { + request := capture_request() + header := CaptureHeader{Request: request, SourceWindow: request.Foreground, + RootBounds: image.Rect(0, 0, 100, 100), SourceBounds: image.Rect(-10, 0, 80, 80), ScreenBounds: image.Rect(0, 10, 30, 50)} + pixels := image.NewRGBA(image.Rect(0, 0, 30, 40)) + pixels.Set(1, 2, color.RGBA{12, 34, 56, 255}) + frame := capture_frame(t, header, pixels) + result, err := decode_capture(frame, request) + if err != nil { + t.Fatal(err) + } + if color.RGBAModel.Convert(result.Pixels.At(1, 2)) != pixels.At(1, 2) { + t.Fatal("pixels changed") + } + if _, err := decode_capture(append(append([]byte(nil), frame...), 'x'), request); !errors.Is(err, ErrCapture) { + t.Fatalf("trailing payload accepted: %v", err) + } + mapped, ok := result.Transform.ScreenRectangle(image.Rect(1, 2, 3, 4)) + if !ok || mapped != image.Rect(1, 12, 3, 14) { + t.Fatalf("mapping: %v, %v", mapped, ok) + } + request.Generation++ + if _, err := decode_capture(frame, request); !errors.Is(err, ErrCapture) { + t.Fatalf("old generation accepted: %v", err) + } + request.Generation-- + for _, change := range []func(*CaptureHeader){ + func(h *CaptureHeader) { h.ScreenBounds.Min.X = -1 }, + func(h *CaptureHeader) { h.SourceBounds = image.Rect(50, 50, 80, 80) }, + func(h *CaptureHeader) { h.SourceWindow++ }, + func(h *CaptureHeader) { h.ScreenBounds.Max.X++ }, + } { + bad := header + change(&bad) + if _, err := decode_capture(capture_frame(t, bad, pixels), request); err == nil { + t.Fatalf("invalid mapping accepted: %+v", bad) + } + } +} + +func TestCaptureClipboardDoesNotMapToScreen(t *testing.T) { + request := CaptureRequest{Kind: ClipboardSource, Foreground: 123, Generation: 1} + header := CaptureHeader{Request: request} + pixels := image.NewRGBA(image.Rect(0, 0, 10, 10)) + result, err := decode_capture(capture_frame(t, header, pixels), request) + if err != nil || result.Transform.HasScreenMapping { + t.Fatalf("clipboard: %+v, %v", result, err) + } + header.ScreenBounds = image.Rect(0, 0, 10, 10) + if _, err := decode_capture(capture_frame(t, header, pixels), request); err == nil { + t.Fatal("clipboard gained coordinates") + } +} + +func TestCaptureProtocolErrorsAndPixelLimit(t *testing.T) { + request := capture_request() + for status, want := range map[string]error{"unavailable": ErrCapture, "source": ErrSource, "changed": ErrSourceChanged, "limit": ErrLimit, "Private diagnostics": ErrCapture} { + frame := capture_frame(t, CaptureHeader{Request: request, Status: status}, nil) + _, err := decode_capture(frame, request) + if !errors.Is(err, want) || strings.Contains(err.Error(), "Private") { + t.Fatalf("status %q: %v", status, err) + } + if _, err := decode_capture(append(frame, 'x'), request); !errors.Is(err, ErrCapture) { + t.Fatal("failure with payload accepted") + } + } + clipboard := CaptureRequest{Kind: ClipboardSource, Foreground: 123, Generation: 1} + frame := capture_frame(t, CaptureHeader{Request: clipboard}, image.NewRGBA(image.Rect(0, 0, 1, 1))) + start := bytes.IndexByte(frame, '\n') + 1 + // A valid CRC and malicious IHDR are rejected before allocating pixel data. + binary.BigEndian.PutUint32(frame[start+16:start+20], 10000) + binary.BigEndian.PutUint32(frame[start+20:start+24], 10000) + binary.BigEndian.PutUint32(frame[start+29:start+33], crc32.ChecksumIEEE(frame[start+12:start+29])) + if _, err := decode_capture(frame, clipboard); !errors.Is(err, ErrLimit) { + t.Fatalf("oversize PNG: %v", err) + } + for _, invalid := range [][]byte{nil, []byte("{}\nnot a png"), bytes.Repeat([]byte{'x'}, maxCaptureHeader+1)} { + if _, err := decode_capture(invalid, request); !errors.Is(err, ErrCapture) { + t.Fatalf("invalid response: %v", err) + } + } +} + +func TestCapturerMissingHelperAndCancellation(t *testing.T) { + request := capture_request() + if _, err := NewCapturer("/nonexistent-ocr-capture-helper").Capture(context.Background(), request); !errors.Is(err, ErrCapture) { + t.Fatalf("missing helper: %v", err) + } + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + readyRead, readyWrite, err := os.Pipe() + if err != nil { + t.Fatal(err) + } + defer readyRead.Close() + defer readyWrite.Close() + capturer := NewCapturer(executable) + capturer.command = func(ctx context.Context, args ...string) *exec.Cmd { + command := exec.CommandContext(ctx, executable, "-test.run=^TestCaptureChildProcess$", "--", args[0]) + command.Env = append(os.Environ(), "CTHULHU_CAPTURE_TEST_CHILD=1") + command.ExtraFiles = []*os.File{readyWrite} + return command + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + completed := make(chan error, 1) + go func() { _, err := capturer.Capture(ctx, request); completed <- err }() + _ = readyRead.SetReadDeadline(time.Now().Add(5 * time.Second)) + data := make([]byte, 64) + count, err := readyRead.Read(data) + if err != nil { + t.Fatal(err) + } + pid, err := strconv.Atoi(strings.TrimSpace(string(data[:count]))) + if err != nil { + t.Fatal(err) + } + waitContext, waitCancel := context.WithCancel(context.Background()) + waitCancel() + if _, err := capturer.Capture(waitContext, request); !errors.Is(err, context.Canceled) { + t.Fatalf("waiting cancellation: %v", err) + } + cancel() + select { + case err := <-completed: + if !errors.Is(err, context.Canceled) { + t.Fatalf("running cancellation: %v", err) + } + case <-time.After(3 * time.Second): + t.Fatal("capture did not join cancelled helper") + } + if err := syscall.Kill(pid, 0); !errors.Is(err, syscall.ESRCH) { + t.Fatalf("helper still alive or unreaped: %v", err) + } +} + +func TestCaptureChildProcess(t *testing.T) { + if os.Getenv("CTHULHU_CAPTURE_TEST_CHILD") != "1" { + return + } + if _, err := io.ReadAll(os.Stdin); err != nil { + os.Exit(20) + } + ready := os.NewFile(3, "ready") + _, _ = ready.WriteString(strconv.Itoa(os.Getpid()) + "\n") + _ = ready.Close() + time.Sleep(time.Hour) + os.Exit(0) +} diff --git a/internal/ocr/cursor.go b/internal/ocr/cursor.go new file mode 100644 index 0000000..45554d4 --- /dev/null +++ b/internal/ocr/cursor.go @@ -0,0 +1,169 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "sort" + "strings" +) + +type Unit uint8 + +const ( + Character Unit = iota + 1 + WordUnit + LineUnit + PageUnit + LineStart + LineEnd + DocumentStart + DocumentEnd +) + +// Cursor owns a virtual rune offset. It has no native accessible identity and +// never moves application focus. A session discards it on retirement. +type Cursor struct { + result Result + text []rune + lines []Span + lineTexts []string + offset, column int +} + +type Position struct { + Offset int + Text string + Line string + LineStart int + Cursor int // Rune offset within Line, including its end position. + Moved bool +} + +type ReadLine struct { + Offset int + Text string +} + +func NewCursor(result Result) *Cursor { + cursor := &Cursor{result: result, text: []rune(result.Text), lineTexts: strings.Split(result.Text, "\n")} + start := 0 + for index, char := range cursor.text { + if char == '\n' { + cursor.lines = append(cursor.lines, Span{start, index}) + start = index + 1 + } + } + cursor.lines = append(cursor.lines, Span{start, len(cursor.text)}) + return cursor +} + +func (cursor *Cursor) line_index() int { + return sort.Search(len(cursor.lines), func(index int) bool { return cursor.lines[index].End >= cursor.offset }) +} + +func (cursor *Cursor) Current(unit Unit) Position { + lineIndex := cursor.line_index() + line := cursor.lines[lineIndex] + position := Position{Offset: cursor.offset, Line: cursor.lineTexts[lineIndex], LineStart: line.Start, Cursor: cursor.offset - line.Start} + switch unit { + case Character, LineStart, LineEnd: + if cursor.offset < len(cursor.text) { + position.Text = string(cursor.text[cursor.offset]) + } + case WordUnit: + if word, ok := cursor.result.WordAt(cursor.offset); ok { + position.Text = word.Text + } + default: + position.Text = position.Line + } + return position +} + +func (cursor *Cursor) Move(unit Unit, step int) Position { + previous := cursor.offset + lineIndex := cursor.line_index() + line := cursor.lines[lineIndex] + switch unit { + case Character: + cursor.offset = max(0, min(len(cursor.text), cursor.offset+step)) + case WordUnit: + if step > 0 { + index := sort.Search(len(cursor.result.Words), func(index int) bool { return cursor.result.Words[index].Start > cursor.offset }) + if index < len(cursor.result.Words) { + cursor.offset = cursor.result.Words[index].Start + } + } else if step < 0 { + index := sort.Search(len(cursor.result.Words), func(index int) bool { return cursor.result.Words[index].Start >= cursor.offset }) - 1 + if index >= 0 { + cursor.offset = cursor.result.Words[index].Start + } + } + case LineUnit, PageUnit: + if unit == PageUnit { + step *= 20 + } + next := max(0, min(len(cursor.lines)-1, lineIndex+step)) + if next != lineIndex { + cursor.offset = cursor.lines[next].Start + min(cursor.column, cursor.lines[next].End-cursor.lines[next].Start) + } + case LineStart: + cursor.offset = line.Start + case LineEnd: + cursor.offset = line.End + case DocumentStart: + cursor.offset = 0 + case DocumentEnd: + cursor.offset = len(cursor.text) + } + if unit != LineUnit && unit != PageUnit { + cursor.column = cursor.offset - cursor.lines[cursor.line_index()].Start + } + position := cursor.Current(unit) + position.Moved = previous != cursor.offset + return position +} + +// Set moves only the virtual cursor. It rejects offsets outside the recognized +// text so a stale routing request cannot produce an invalid position. +func (cursor *Cursor) Set(offset int) (Position, bool) { + if offset < 0 || offset > len(cursor.text) { + return Position{}, false + } + cursor.offset = offset + cursor.column = offset - cursor.lines[cursor.line_index()].Start + return cursor.Current(Character), true +} + +func (cursor *Cursor) Length() int { return len(cursor.text) } +func (cursor *Cursor) Offset() int { return cursor.offset } +func (cursor *Cursor) Text() string { return cursor.result.Text } +func (cursor *Cursor) CurrentWord() (Word, bool) { return cursor.result.WordAt(cursor.offset) } + +func (cursor *Cursor) Slice(start, end int) (string, bool) { + if start < 0 || end < start || end > len(cursor.text) { + return "", false + } + return string(cursor.text[start:end]), true +} + +// LinesFrom returns whole lines after the virtual cursor. The first line +// begins at the cursor position; following lines retain recognition order. +func (cursor *Cursor) LinesFrom() []ReadLine { + index := cursor.line_index() + first := index + parts := make([]ReadLine, 0, len(cursor.lines)-index) + for ; index < len(cursor.lines); index++ { + line := cursor.lines[index] + start := line.Start + if index == first { + start = cursor.offset + } + if start < line.End { + parts = append(parts, ReadLine{Offset: start, Text: string(cursor.text[start:line.End])}) + } + } + return parts +} diff --git a/internal/ocr/cursor_continuous_test.go b/internal/ocr/cursor_continuous_test.go new file mode 100644 index 0000000..9b8f421 --- /dev/null +++ b/internal/ocr/cursor_continuous_test.go @@ -0,0 +1,23 @@ +package ocr + +import "testing" + +func TestCursorReadAllAndRoutingOffsets(t *testing.T) { + cursor := NewCursor(Result{Text: "é one\n\n猫 two"}) + if _, ok := cursor.Set(2); !ok { + t.Fatal("valid rune offset rejected") + } + lines := cursor.LinesFrom() + if len(lines) != 2 || lines[0].Text != "one" || lines[0].Offset != 2 || lines[1].Text != "猫 two" || lines[1].Offset != 7 { + t.Fatalf("lines from cursor: %+v", lines) + } + if _, ok := cursor.Set(-1); ok { + t.Fatal("negative route accepted") + } + if _, ok := cursor.Set(cursor.Length() + 1); ok { + t.Fatal("out of range route accepted") + } + if got, ok := cursor.Slice(0, 1); !ok || got != "é" { + t.Fatalf("rune selection: %q %t", got, ok) + } +} diff --git a/internal/ocr/cursor_test.go b/internal/ocr/cursor_test.go new file mode 100644 index 0000000..9463355 --- /dev/null +++ b/internal/ocr/cursor_test.go @@ -0,0 +1,59 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import "testing" + +func TestCursorUnicodeLinesAndEngineWordOrder(t *testing.T) { + result := Result{Text: "é e\u0301\n\nאב 42", Words: []Word{ + {Text: "é", Span: Span{0, 1}}, {Text: "e\u0301", Span: Span{2, 4}}, + {Text: "אב", Span: Span{6, 8}}, {Text: "42", Span: Span{9, 11}}, + }} + cursor := NewCursor(result) + if got := cursor.Current(LineUnit); got.Text != "é e\u0301" || got.Offset != 0 || got.Cursor != 0 { + t.Fatalf("initial: %+v", got) + } + if got := cursor.Move(WordUnit, 1); got.Text != "e\u0301" || got.Offset != 2 || got.Cursor != 2 { + t.Fatalf("combining word: %+v", got) + } + if got := cursor.Move(Character, 1); got.Text != "\u0301" || got.Offset != 3 { + t.Fatalf("combining character: %+v", got) + } + if got := cursor.Move(LineUnit, 1); got.Text != "" || got.Offset != 5 || got.Cursor != 0 { + t.Fatalf("blank paragraph: %+v", got) + } + if got := cursor.Move(LineUnit, 1); got.Text != "אב 42" || got.Offset != 9 || got.Cursor != 3 { + t.Fatalf("preserved column: %+v", got) + } + if got := cursor.Move(WordUnit, -1); got.Text != "אב" || got.Offset != 6 { + t.Fatalf("RTL engine order: %+v", got) + } + if got := cursor.Move(DocumentEnd, 0); got.Offset != 11 || got.Cursor != 5 || got.Text != "אב 42" { + t.Fatalf("end: %+v", got) + } + if got := cursor.Move(Character, 1); got.Moved || got.Offset != 11 { + t.Fatalf("past end: %+v", got) + } + cursor.Move(DocumentStart, 0) + if got := cursor.Move(Character, -1); got.Moved || got.Offset != 0 { + t.Fatalf("before start: %+v", got) + } +} + +func TestCursorLineEndsSeparatorsAndEmptyDocument(t *testing.T) { + cursor := NewCursor(Result{Text: "one\ntwo\n"}) + if got := cursor.Move(LineEnd, 0); got.Offset != 3 || got.Text != "\n" || got.Cursor != 3 { + t.Fatalf("line end: %+v", got) + } + if got := cursor.Move(Character, 1); got.Offset != 4 || got.Text != "t" || got.Line != "two" || got.Cursor != 0 { + t.Fatalf("cross separator: %+v", got) + } + if got := cursor.Move(DocumentEnd, 0); got.Offset != 8 || got.Line != "" || got.Cursor != 0 { + t.Fatalf("trailing blank: %+v", got) + } + if got := NewCursor(Result{}).Move(Character, 1); got.Offset != 0 || got.Text != "" || got.Moved { + t.Fatalf("empty: %+v", got) + } +} diff --git a/internal/ocr/engine.go b/internal/ocr/engine.go new file mode 100644 index 0000000..3e21172 --- /dev/null +++ b/internal/ocr/engine.go @@ -0,0 +1,252 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "bytes" + "context" + "errors" + "fmt" + "image" + "image/png" + "os/exec" + "sort" + "strconv" + "strings" + "time" +) + +const ( + discoveryTimeout = 2 * time.Second + recognitionTimeout = 15 * time.Second + maxCatalogBytes = 64 << 10 + maxImageBytes = 64 << 20 + maxStderrBytes = 16 << 10 +) + +type Layout int + +const ( + AutomaticPage Layout = 3 + SingleBlock Layout = 6 + SparseText Layout = 11 +) + +// Options is a per-job snapshot. Empty language chooses eng when installed, +// otherwise the first installed recognition language in sorted order. An +// explicit language expression is never replaced with a fallback. +type Options struct { + Language string + Layout Layout // Zero uses AutomaticPage; other unsupported values fail. + Scale int // Zero uses original size; 1 through 4 are explicit factors. + Grayscale bool + Invert bool + BlackWhite bool + Threshold int +} + +// Catalog contains recognition languages, excluding orientation-only osd data. +// Discovery is on demand, not part of reader startup. Each request rescans so +// installing/removing data does not require restarting the reader. +type Catalog struct { + Languages []string + DefaultLanguage string +} + +// Engine serializes its subprocesses. Call its blocking methods from a worker, +// never a native callback, GTK thread or the reader's event/input loop. A +// canceled call kills and reaps its process before releasing ownership. +type Engine struct { + gate chan struct{} + command func(context.Context, ...string) *exec.Cmd +} + +// NewEngine performs no dependency lookup, native initialization or I/O. +func NewEngine() *Engine { + return &Engine{gate: make(chan struct{}, 1), command: func(ctx context.Context, args ...string) *exec.Cmd { + return exec.CommandContext(ctx, "tesseract", args...) + }} +} + +func (engine *Engine) acquire(ctx context.Context) error { + select { + case engine.gate <- struct{}{}: + if err := ctx.Err(); err != nil { + <-engine.gate + return err + } + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (engine *Engine) Discover(ctx context.Context) (Catalog, error) { + ctx, cancel := context.WithTimeout(ctx, discoveryTimeout) + defer cancel() + if err := engine.acquire(ctx); err != nil { + return Catalog{}, err + } + defer func() { <-engine.gate }() + return engine.discover(ctx) +} + +func (engine *Engine) discover(ctx context.Context) (Catalog, error) { + ctx, cancel := context.WithTimeout(ctx, discoveryTimeout) + defer cancel() + output, _, err := engine.run(ctx, nil, maxCatalogBytes, "--list-langs") + if err != nil { + if errors.Is(err, ErrRecognition) { + return Catalog{}, fmt.Errorf("%w: language discovery failed", ErrUnavailable) + } + return Catalog{}, err + } + return parse_catalog(string(output)) +} + +func parse_catalog(output string) (Catalog, error) { + lines := strings.Split(strings.TrimSpace(output), "\n") + header := strings.TrimSuffix(lines[0], "\r") + countStart := strings.LastIndex(header, "(") + if !strings.HasPrefix(header, "List of available languages in ") || !strings.HasSuffix(header, "):") || countStart < 0 { + return Catalog{}, fmt.Errorf("%w: invalid language catalog", ErrUnavailable) + } + count, err := strconv.Atoi(header[countStart+1 : len(header)-2]) + if err != nil || count < 0 || count > 512 || count != len(lines)-1 { + return Catalog{}, fmt.Errorf("%w: invalid language catalog", ErrUnavailable) + } + var catalog Catalog + seen := make(map[string]bool) + for _, line := range lines[1:] { + language := strings.TrimSuffix(line, "\r") + if !valid_language(language) || seen[language] { + return Catalog{}, fmt.Errorf("%w: invalid language catalog", ErrUnavailable) + } + seen[language] = true + if language != "osd" { + catalog.Languages = append(catalog.Languages, language) + } + } + if len(catalog.Languages) == 0 { + return Catalog{}, fmt.Errorf("%w: no recognition language data installed", ErrUnavailable) + } + sort.Strings(catalog.Languages) + catalog.DefaultLanguage = catalog.Languages[0] + if seen["eng"] { + catalog.DefaultLanguage = "eng" + } + return catalog, nil +} + +// valid_language permits upstream script/Latin-style identifiers, without +// accepting path traversal, options, whitespace or expression delimiters. +func valid_language(language string) bool { + if language == "" || len(language) > 128 { + return false + } + parts := strings.Split(language, "/") + if len(parts) > 2 || (len(parts) == 2 && parts[0] != "script") { + return false + } + for _, part := range parts { + if part == "" || part[0] == '-' { + return false + } + for _, char := range part { + if !(char >= 'a' && char <= 'z' || char >= 'A' && char <= 'Z' || char >= '0' && char <= '9' || char == '_' || char == '-') { + return false + } + } + } + return true +} + +func (catalog Catalog) resolve_language(expression string) (string, error) { + if expression == "" { + return catalog.DefaultLanguage, nil + } + if len(expression) > 1024 { + return "", fmt.Errorf("%w: invalid language selection", ErrUnavailable) + } + seen := make(map[string]bool) + for _, language := range strings.Split(expression, "+") { + if !valid_language(language) || language == "osd" || seen[language] { + return "", fmt.Errorf("%w: invalid language selection", ErrUnavailable) + } + seen[language] = true + index := sort.SearchStrings(catalog.Languages, language) + if index == len(catalog.Languages) || catalog.Languages[index] != language { + return "", fmt.Errorf("%w: selected language data is not installed", ErrUnavailable) + } + } + return expression, nil +} + +// Recognize encodes one owned image to PNG in memory and obtains text and +// coordinates from one TSV recognition invocation. The caller must not mutate +// pixels until this method returns. No images or text are logged or persisted. +func (engine *Engine) Recognize(ctx context.Context, pixels image.Image, options Options) (Result, error) { + ctx, cancel := context.WithTimeout(ctx, recognitionTimeout) + defer cancel() + if pixels == nil || !valid_dimensions(pixels.Bounds().Dx(), pixels.Bounds().Dy()) { + return Result{}, ErrInvalidImage + } + if options.Layout == 0 { + options.Layout = AutomaticPage + } + if options.Layout != AutomaticPage && options.Layout != SingleBlock && options.Layout != SparseText { + return Result{}, fmt.Errorf("%w: unsupported text layout", ErrRecognition) + } + if err := engine.acquire(ctx); err != nil { + return Result{}, err + } + defer func() { <-engine.gate }() + var err error + pixels, err = Preprocess(ctx, pixels, options) + if err != nil { + return Result{}, err + } + catalog, err := engine.discover(ctx) + if err != nil { + return Result{}, err + } + language, err := catalog.resolve_language(options.Language) + if err != nil { + return Result{}, err + } + encoded := &bounded_buffer{limit: maxImageBytes, ctx: ctx} + if err := png.Encode(encoded, pixels); err != nil { + if ctx.Err() != nil { + return Result{}, ctx.Err() + } + if errors.Is(err, ErrLimit) { + return Result{}, ErrLimit + } + return Result{}, ErrInvalidImage + } + output, diagnostics, err := engine.run(ctx, encoded.Bytes(), maxTSVBytes, + "stdin", "stdout", "-l", language, "--psm", strconv.Itoa(int(options.Layout)), "tsv") + // Tesseract may exit successfully after loading only part of a multi-language + // expression. Never silently accept that degraded selection. + if strings.Contains(string(diagnostics), "Error opening data file") || + strings.Contains(string(diagnostics), "Failed loading language") || + strings.Contains(string(diagnostics), "couldn't load any languages") { + if ctx.Err() != nil { + return Result{}, ctx.Err() + } + return Result{}, fmt.Errorf("%w: selected language data could not be loaded", ErrUnavailable) + } + if err != nil { + return Result{}, err + } + if err := ctx.Err(); err != nil { + return Result{}, err + } + result, err := ParseTSV(bytes.NewReader(output), pixels.Bounds().Dx(), pixels.Bounds().Dy()) + if ctx.Err() != nil { + return Result{}, ctx.Err() + } + return result, err +} diff --git a/internal/ocr/engine_test.go b/internal/ocr/engine_test.go new file mode 100644 index 0000000..950983b --- /dev/null +++ b/internal/ocr/engine_test.go @@ -0,0 +1,431 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "bufio" + "bytes" + "context" + "errors" + "fmt" + "image" + "image/png" + "io" + "os" + "os/exec" + "reflect" + "strconv" + "strings" + "syscall" + "testing" + "time" +) + +func TestCatalogAndOrderedLanguages(t *testing.T) { + catalog, err := parse_catalog("List of available languages in \"/data\" (4):\nfra\nosd\nscript/Latin\neng\n") + if err != nil || catalog.DefaultLanguage != "eng" || + !reflect.DeepEqual(catalog.Languages, []string{"eng", "fra", "script/Latin"}) { + t.Fatalf("catalog: %+v, %v", catalog, err) + } + for _, expression := range []string{"", "fra+eng", "script/Latin"} { + got, err := catalog.resolve_language(expression) + want := expression + if want == "" { + want = "eng" + } + if err != nil || got != want { + t.Fatalf("language expression %q: %q, %v", expression, got, err) + } + } + for _, expression := range []string{"osd", "deu", "fra+missing", "eng+eng", "eng+", "+eng", "../eng", "-l eng", "eng;command", "fra\neng"} { + if _, err := catalog.resolve_language(expression); !errors.Is(err, ErrUnavailable) { + t.Fatalf("invalid/uninstalled expression %q accepted: %v", expression, err) + } + } + other, err := parse_catalog("List of available languages in \"/data\" (2):\nfra\ndeu\n") + if err != nil || other.DefaultLanguage != "deu" { + t.Fatalf("default without English: %+v, %v", other, err) + } +} + +func TestMissingAndMalformedCatalogs(t *testing.T) { + for _, output := range []string{ + "", "Private fixture text", + "List of available languages in \"/data\" (0):\n", + "List of available languages in \"/data\" (1):\nosd\n", + "List of available languages in \"/data\" (2):\neng\neng\n", + "List of available languages in \"/data\" (1):\neng\nfra\n", + "List of available languages in \"/data\" (1):\n../eng\n", + } { + _, err := parse_catalog(output) + if !errors.Is(err, ErrUnavailable) || !strings.HasPrefix(err.Error(), "OCR not available") || strings.Contains(err.Error(), "Private") { + t.Fatalf("unavailable message: %v", err) + } + } +} + +func test_engine(t *testing.T, mode string) *Engine { + t.Helper() + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + engine := NewEngine() + engine.command = func(ctx context.Context, args ...string) *exec.Cmd { + command := exec.CommandContext(ctx, executable, append([]string{"-test.run=^TestOCRChildProcess$", "--"}, args...)...) + command.Env = append(os.Environ(), "CTHULHU_OCR_TEST_PROCESS=1", "CTHULHU_OCR_TEST_MODE="+mode) + return command + } + return engine +} + +func TestEngineRecognizesOneTSVInvocation(t *testing.T) { + engine := test_engine(t, "success") + original := engine.command + var invocations [][]string + engine.command = func(ctx context.Context, args ...string) *exec.Cmd { + invocations = append(invocations, append([]string(nil), args...)) + return original(ctx, args...) + } + // A nonzero source origin is encoded as a normalized recognition image. + pixels := image.NewRGBA(image.Rect(-5, 10, 95, 110)) + result, err := engine.Recognize(context.Background(), pixels, Options{Language: "fra+eng", Layout: SingleBlock}) + if err != nil || result.Text != "é 中文" || result.Width != 100 || result.Height != 100 { + t.Fatalf("recognition: %+v, %v", result, err) + } + want := [][]string{{"--list-langs"}, {"stdin", "stdout", "-l", "fra+eng", "--psm", "6", "tsv"}} + if !reflect.DeepEqual(invocations, want) { + t.Fatalf("invocations: %v, want %v", invocations, want) + } + if result.Words[1].Span != (Span{2, 4}) { + t.Fatal("process result lost rune offsets") + } + if _, err := engine.Discover(context.Background()); err != nil { + t.Fatalf("engine did not release process ownership: %v", err) + } +} + +func TestEngineMissingExecutableAndUnavailableLanguage(t *testing.T) { + engine := NewEngine() // Constructing it never checks or loads OCR dependencies. + engine.command = func(ctx context.Context, args ...string) *exec.Cmd { + return exec.CommandContext(ctx, "/nonexistent-ocr-test-engine", args...) + } + if _, err := engine.Discover(context.Background()); !errors.Is(err, ErrUnavailable) { + t.Fatalf("missing executable: %v", err) + } + if _, err := engine.Recognize(context.Background(), image.NewGray(image.Rect(0, 0, 100, 100)), Options{}); !errors.Is(err, ErrUnavailable) { + t.Fatalf("missing executable recognition: %v", err) + } + engine = test_engine(t, "success") + original := engine.command + var invocations int + engine.command = func(ctx context.Context, args ...string) *exec.Cmd { + invocations++ + return original(ctx, args...) + } + if _, err := engine.Recognize(context.Background(), image.NewGray(image.Rect(0, 0, 100, 100)), Options{Language: "missing"}); !errors.Is(err, ErrUnavailable) || invocations != 1 { + t.Fatalf("missing language was substituted or invoked: %v, %d", err, invocations) + } +} + +func TestDefaultEngineWithoutRuntimeDependencies(t *testing.T) { + // Use the real constructor and default executable lookup, with no helper + // injection. Even initialization and an attempted job need no installed OCR. + t.Setenv("PATH", t.TempDir()) + engine := NewEngine() + if _, err := engine.Discover(context.Background()); !errors.Is(err, ErrUnavailable) || err.Error() != "OCR not available" { + t.Fatalf("missing default backend: %v", err) + } + if _, err := engine.Recognize(context.Background(), image.NewGray(image.Rect(0, 0, 100, 100)), Options{}); !errors.Is(err, ErrUnavailable) { + t.Fatalf("recognition without dependencies: %v", err) + } +} + +func TestEngineFailuresAndOutputBounds(t *testing.T) { + for _, test := range []struct { + mode string + want error + }{ + {"failure", ErrRecognition}, + {"invalid", ErrInvalidOutput}, + {"partial-language", ErrUnavailable}, + {"missing-data", ErrUnavailable}, + {"no-languages", ErrUnavailable}, + {"stdout-limit", ErrLimit}, + {"stderr-limit", ErrLimit}, + {"catalog-limit", ErrLimit}, + } { + t.Run(test.mode, func(t *testing.T) { + engine := test_engine(t, test.mode) + result, err := engine.Recognize(context.Background(), image.NewGray(image.Rect(0, 0, 100, 100)), Options{}) + if !errors.Is(err, test.want) || result.Text != "" || len(result.Words) != 0 { + t.Fatalf("result: %+v, error: %v; want %v", result, err, test.want) + } + if strings.Contains(err.Error(), "Private") { + t.Fatal("native diagnostics leaked into error") + } + }) + } +} + +func TestEngineRejectsInvalidImageAndLayoutBeforeStartingChild(t *testing.T) { + engine := NewEngine() + engine.command = func(context.Context, ...string) *exec.Cmd { + t.Fatal("child invoked for invalid request") + return nil + } + for _, pixels := range []image.Image{nil, image.NewGray(image.Rectangle{}), oversized_image{}} { + if _, err := engine.Recognize(context.Background(), pixels, Options{}); !errors.Is(err, ErrInvalidImage) { + t.Fatalf("invalid image: %v", err) + } + } + if _, err := engine.Recognize(context.Background(), image.NewGray(image.Rect(0, 0, 100, 100)), Options{Layout: 4}); !errors.Is(err, ErrRecognition) { + t.Fatalf("invalid layout: %v", err) + } +} + +type oversized_image struct{ image.Image } + +func (oversized_image) Bounds() image.Rectangle { return image.Rect(0, 0, MaxPixels, 2) } + +func TestEngineCancellationReapsChildAndUnblocksWaitingRequest(t *testing.T) { + t.Run("cancel", func(t *testing.T) { check_child_cancellation(t, false) }) + t.Run("deadline", func(t *testing.T) { check_child_cancellation(t, true) }) +} + +func check_child_cancellation(t *testing.T, deadline bool) { + t.Helper() + engine := test_engine(t, "wait") + original := engine.command + readyRead, readyWrite, err := os.Pipe() + if err != nil { + t.Fatal(err) + } + defer readyRead.Close() + defer readyWrite.Close() + children := make(chan *exec.Cmd, 2) + engine.command = func(ctx context.Context, args ...string) *exec.Cmd { + command := original(ctx, args...) + if args[0] == "stdin" { + command.ExtraFiles = []*os.File{readyWrite} + children <- command + } + return command + } + ctx, cancel := context.WithCancel(context.Background()) + if deadline { + cancel() + ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) + } + defer cancel() + done := make(chan error, 1) + go func() { + _, err := engine.Recognize(ctx, image.NewGray(image.Rect(0, 0, 100, 100)), Options{}) + done <- err + }() + if err := readyRead.SetReadDeadline(time.Now().Add(5 * time.Second)); err != nil { + t.Fatal(err) + } + if _, err := io.ReadFull(readyRead, make([]byte, 1)); err != nil { + t.Fatalf("child not ready: %v", err) + } + // A second call must not overlap recognition; it can cancel while waiting. + waitCtx, waitCancel := context.WithTimeout(context.Background(), 40*time.Millisecond) + defer waitCancel() + if _, err := engine.Discover(waitCtx); !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("waiting call failed to cancel: %v", err) + } + want := error(context.Canceled) + if deadline { + want = context.DeadlineExceeded + } else { + cancel() + } + select { + case err := <-done: + if !errors.Is(err, want) { + t.Fatalf("cancel: %v", err) + } + case <-time.After(5 * time.Second): + t.Fatal("canceled recognition did not join") + } + child := <-children + if child.ProcessState == nil { + t.Fatal("child Wait was not joined") + } + if _, err := syscall.Wait4(child.Process.Pid, nil, syscall.WNOHANG, nil); !errors.Is(err, syscall.ECHILD) { + t.Fatalf("child was not reaped: %v", err) + } + if _, err := engine.Discover(context.Background()); err != nil { + t.Fatalf("ownership not released after cancellation: %v", err) + } +} + +func TestEngineRetiresDescendantsHoldingPipes(t *testing.T) { + engine := test_engine(t, "orphan") + original := engine.command + readyRead, readyWrite, err := os.Pipe() + if err != nil { + t.Fatal(err) + } + defer readyRead.Close() + defer readyWrite.Close() + engine.command = func(ctx context.Context, args ...string) *exec.Cmd { + command := original(ctx, args...) + if args[0] == "stdin" { + command.ExtraFiles = []*os.File{readyWrite} + } + return command + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + done := make(chan error, 1) + go func() { + _, err := engine.Recognize(ctx, image.NewGray(image.Rect(0, 0, 100, 100)), Options{}) + done <- err + }() + if err := readyRead.SetReadDeadline(time.Now().Add(5 * time.Second)); err != nil { + t.Fatal(err) + } + line, err := bufio.NewReader(readyRead).ReadString('\n') + if err != nil { + t.Fatal(err) + } + pid, err := strconv.Atoi(strings.TrimSpace(line)) + if err != nil || pid <= 0 { + t.Fatalf("invalid descendant PID: %q, %v", line, err) + } + select { + case err := <-done: + if !errors.Is(err, ErrRecognition) { + t.Fatalf("inherited pipes did not fail within WaitDelay: %v", err) + } + case <-ctx.Done(): + t.Fatal("inherited pipes stalled process cleanup") + } + // SIGKILL delivery and adoption by init are asynchronous. A zombie has exited + // and holds no pipes; the parent engine cannot reap an adopted grandchild. + deadline := time.NewTimer(time.Second) + defer deadline.Stop() + poll := time.NewTicker(10 * time.Millisecond) + defer poll.Stop() + for { + status, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid)) + if errors.Is(err, os.ErrNotExist) { + break + } + if err != nil { + t.Fatal(err) + } + fields := strings.Fields(string(status[strings.LastIndexByte(string(status), ')')+1:])) + if len(fields) != 0 && fields[0] == "Z" { + break + } + select { + case <-deadline.C: + t.Fatal("descendant survived process-group cleanup") + case <-poll.C: + } + } +} + +func TestEngineExpiredDeadlineStartsNoChild(t *testing.T) { + engine := NewEngine() + engine.command = func(context.Context, ...string) *exec.Cmd { + t.Fatal("started child after expired deadline") + return nil + } + ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(-time.Second)) + defer cancel() + if _, err := engine.Discover(ctx); !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("expired discovery: %v", err) + } +} + +func TestBoundedBufferCannotBypassWriteLimit(t *testing.T) { + buffer := &bounded_buffer{limit: 5, ctx: context.Background()} + if _, err := io.Copy(buffer, strings.NewReader("0123456789")); !errors.Is(err, ErrLimit) || buffer.Len() > 5 { + t.Fatalf("writer limit bypassed: %d bytes, %v", buffer.Len(), err) + } +} + +// TestOCRChildProcess is an executable process fixture, not a mock of exec.Wait. +func TestOCRChildProcess(t *testing.T) { + if os.Getenv("CTHULHU_OCR_TEST_PROCESS") != "1" { + return + } + args := os.Args + for len(args) != 0 && args[0] != "--" { + args = args[1:] + } + if len(args) < 2 { + os.Exit(20) + } + args = args[1:] + mode := os.Getenv("CTHULHU_OCR_TEST_MODE") + if args[0] == "hold-pipes" { + ready := os.NewFile(3, "ready") + _, _ = fmt.Fprintln(ready, os.Getpid()) + _ = ready.Close() + time.Sleep(time.Hour) + os.Exit(0) + } + if args[0] == "--list-langs" { + switch mode { + case "no-languages": + fmt.Print("List of available languages in \"/data\" (1):\nosd\n") + case "catalog-limit": + fmt.Print(strings.Repeat("x", maxCatalogBytes+1)) + default: + fmt.Print("List of available languages in \"/data\" (3):\neng\nfra\nosd\n") + } + os.Exit(0) + } + if os.Getenv("OMP_THREAD_LIMIT") != "1" || os.Getenv("LC_ALL") != "C" { + os.Exit(21) + } + encoded, err := io.ReadAll(io.LimitReader(os.Stdin, 1<<20)) + if err != nil { + os.Exit(22) + } + pixels, err := png.Decode(bytes.NewReader(encoded)) + if err != nil || pixels.Bounds() != image.Rect(0, 0, 100, 100) { + os.Exit(23) + } + switch mode { + case "orphan": + child := exec.Command(os.Args[0], "-test.run=^TestOCRChildProcess$", "--", "hold-pipes") + child.Env = os.Environ() + child.Stdout, child.Stderr = os.Stdout, os.Stderr + child.ExtraFiles = []*os.File{os.NewFile(3, "ready")} + if err := child.Start(); err != nil { + os.Exit(24) + } + case "failure": + fmt.Fprint(os.Stderr, "Private fixture diagnostics") + os.Exit(1) + case "missing-data": + fmt.Fprint(os.Stderr, "Error opening data file /private/data/eng.traineddata\n") + os.Exit(1) + case "partial-language": + fmt.Fprint(os.Stderr, "Failed loading language 'fra'\n") + case "invalid": + fmt.Print("Private malformed TSV") + os.Exit(0) + case "stdout-limit": + fmt.Print(strings.Repeat("x", maxTSVBytes+1)) + os.Exit(0) + case "stderr-limit": + fmt.Fprint(os.Stderr, strings.Repeat("x", maxStderrBytes+1)) + os.Exit(0) + case "wait": + ready := os.NewFile(3, "ready") + _, _ = ready.Write([]byte{1}) + _ = ready.Close() + time.Sleep(time.Hour) + } + fmt.Print(tsvHeader + "\n5\t1\t1\t1\t1\t1\t0\t0\t10\t10\t95\té\n5\t1\t1\t1\t1\t2\t20\t0\t10\t10\t90\t中文\n") + os.Exit(0) +} diff --git a/internal/ocr/model.go b/internal/ocr/model.go new file mode 100644 index 0000000..08961ea --- /dev/null +++ b/internal/ocr/model.go @@ -0,0 +1,157 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package ocr provides local recognition without build-time OCR dependencies. +// Captures, review sessions and native input remain separate owners. +package ocr + +import ( + "errors" + "image" + "math" + "sort" + "unicode" + "unicode/utf8" +) + +var ( + ErrUnavailable = errors.New("OCR not available") + ErrInvalidImage = errors.New("invalid OCR image") + ErrInvalidOutput = errors.New("invalid OCR output") + ErrLimit = errors.New("OCR limit exceeded") + ErrRecognition = errors.New("OCR recognition failed") +) + +const ( + MaxPixels = 16_000_000 + MaxTextBytes = 1 << 20 + maxTSVBytes = 8 << 20 + maxWords = 100_000 + maxRows = 200_000 +) + +// LineID preserves the full engine hierarchy, including line numbers which +// restart in each paragraph. Result order is engine order, not screen Y/X order. +type LineID struct { + Page, Block, Paragraph, Line int +} + +// Span is a half-open range of Unicode code points, never UTF-8 bytes. +// Combining marks retain their original offsets; text is not normalized. +type Span struct { + Start, End int +} + +type Word struct { + Text string + Confidence float64 + Bounds image.Rectangle + Span +} + +type Line struct { + ID LineID + Span + WordStart, WordEnd int +} + +// Result owns plain text and word rectangles in recognition-image pixels. +// An empty document is a successful recognition with no text. +type Result struct { + Text string + Width, Height int + Words []Word + Lines []Line +} + +// WordAt deliberately rejects separators and end-of-document positions. +// A later activation owner must validate source freshness before clicking. +func (result Result) WordAt(offset int) (Word, bool) { + index := sort.Search(len(result.Words), func(index int) bool { + return result.Words[index].End > offset + }) + if index == len(result.Words) || offset < result.Words[index].Start { + return Word{}, false + } + word := result.Words[index] + runeIndex := 0 + for _, char := range word.Text { + if runeIndex == offset-word.Start { + return word, !unicode.IsSpace(char) + } + runeIndex++ + } + return Word{}, false +} + +// ByteOffset explicitly bridges the reader's rune offsets to Go string slices. +// The offset at the end of the document is valid. +func (result Result) ByteOffset(offset int) (int, bool) { + if offset < 0 { + return 0, false + } + runeIndex := 0 + for byteIndex := range result.Text { + if runeIndex == offset { + return byteIndex, true + } + runeIndex++ + } + return len(result.Text), runeIndex == offset +} + +// Transform maps the content rectangle within the processed image to the +// clipped capture rectangle on screen. ImageContent accounts for padding; +// independent ratios account for rounded scaling in each axis. A clipboard +// image has HasScreenMapping=false and cannot supply screen coordinates. +// This mapping says nothing about source identity, freshness or monitor gaps. +type Transform struct { + ImageContent image.Rectangle + ScreenBounds image.Rectangle + HasScreenMapping bool +} + +// ScreenRectangle rounds outward and clips padding to the actual capture. +// Invalid, empty and entirely padded rectangles have no screen mapping. +func (transform Transform) ScreenRectangle(bounds image.Rectangle) (image.Rectangle, bool) { + content, screen := transform.ImageContent, transform.ScreenBounds + if !transform.HasScreenMapping || !valid_dimensions(content.Dx(), content.Dy()) || + content.Min.X < 0 || content.Min.Y < 0 || content.Max.X > MaxPixels || content.Max.Y > MaxPixels || + !valid_screen_rectangle(screen) { + return image.Rectangle{}, false + } + bounds = bounds.Intersect(content) + if bounds.Empty() { + return image.Rectangle{}, false + } + mapX := func(x int) float64 { + return float64(screen.Min.X) + float64(x-content.Min.X)*float64(screen.Dx())/float64(content.Dx()) + } + mapY := func(y int) float64 { + return float64(screen.Min.Y) + float64(y-content.Min.Y)*float64(screen.Dy())/float64(content.Dy()) + } + mapped := image.Rect(int(math.Floor(mapX(bounds.Min.X))), int(math.Floor(mapY(bounds.Min.Y))), + int(math.Ceil(mapX(bounds.Max.X))), int(math.Ceil(mapY(bounds.Max.Y)))) + mapped = mapped.Intersect(screen) + return mapped, !mapped.Empty() +} + +func valid_screen_rectangle(bounds image.Rectangle) bool { + return bounds.Min.X > math.MinInt32 && bounds.Min.Y > math.MinInt32 && + bounds.Max.X <= math.MaxInt32 && bounds.Max.Y <= math.MaxInt32 && + bounds.Max.X > bounds.Min.X && bounds.Max.Y > bounds.Min.Y && + int64(bounds.Max.X)-int64(bounds.Min.X) <= MaxPixels && + int64(bounds.Max.Y)-int64(bounds.Min.Y) <= MaxPixels +} + +func valid_dimensions(width, height int) bool { + return width > 0 && height > 0 && height <= MaxPixels && width <= MaxPixels/height +} + +func valid_word_bounds(bounds image.Rectangle, width, height int) bool { + return bounds.Min.X >= 0 && bounds.Min.Y >= 0 && !bounds.Empty() && + bounds.Max.X <= width && bounds.Max.Y <= height +} + +func rune_length(text string) int { return utf8.RuneCountInString(text) } diff --git a/internal/ocr/model_test.go b/internal/ocr/model_test.go new file mode 100644 index 0000000..a777ace --- /dev/null +++ b/internal/ocr/model_test.go @@ -0,0 +1,90 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "image" + "math" + "testing" +) + +func TestTransformScreenRectangle(t *testing.T) { + transform := Transform{ + ImageContent: image.Rect(10, 20, 310, 221), + ScreenBounds: image.Rect(-120, -50, -20, 50), + HasScreenMapping: true, + } + for _, test := range []struct { + name string + bounds, expected image.Rectangle + valid bool + }{ + {"full", transform.ImageContent, transform.ScreenBounds, true}, + {"independent axes", image.Rect(13, 22, 19, 26), image.Rect(-119, -50, -117, -47), true}, + {"partial padding", image.Rect(0, 0, 13, 22), image.Rect(-120, -50, -119, -49), true}, + {"only padding", image.Rect(0, 0, 10, 20), image.Rectangle{}, false}, + {"empty", image.Rectangle{}, image.Rectangle{}, false}, + {"beyond image", image.Rect(400, 400, 410, 410), image.Rectangle{}, false}, + } { + t.Run(test.name, func(t *testing.T) { + got, valid := transform.ScreenRectangle(test.bounds) + if got != test.expected || valid != test.valid { + t.Fatalf("mapped %v, %v; want %v, %v", got, valid, test.expected, test.valid) + } + }) + } + transform.HasScreenMapping = false + if _, valid := transform.ScreenRectangle(transform.ImageContent); valid { + t.Fatal("clipboard image acquired screen coordinates") + } + transform.HasScreenMapping = true + transform.ScreenBounds = image.Rect(math.MinInt32, 0, math.MinInt32+100, 100) + if _, valid := transform.ScreenRectangle(transform.ImageContent); valid { + t.Fatal("unknown native origin acquired coordinates") + } + transform.ScreenBounds = image.Rect(-math.MaxInt32, 0, math.MaxInt32, 100) + if _, valid := transform.ScreenRectangle(transform.ImageContent); valid { + t.Fatal("overflow-sized screen rectangle acquired coordinates") + } +} + +func TestRuneOffsetsAndWordHitTesting(t *testing.T) { + result := Result{ + Text: "é 中文\ne\u0301", + Words: []Word{ + {Text: "é", Span: Span{0, 1}}, + {Text: "中文", Span: Span{2, 4}}, + {Text: "e\u0301", Span: Span{5, 7}}, + }, + } + for offset, want := range []int{0, 2, 3, 6, 9, 10, 11, 13} { + got, valid := result.ByteOffset(offset) + if !valid || got != want { + t.Fatalf("byte offset %d = %d, %v; want %d", offset, got, valid, want) + } + } + for _, offset := range []int{-1, 1, 4, 7, 8} { + if word, valid := result.WordAt(offset); valid { + t.Fatalf("separator/end offset %d chose %q", offset, word.Text) + } + } + for _, offset := range []int{0, 2, 3, 5, 6} { + if _, valid := result.WordAt(offset); !valid { + t.Fatalf("word offset %d missing", offset) + } + } + for _, offset := range []int{-1, 8} { + if _, valid := result.ByteOffset(offset); valid { + t.Fatalf("invalid rune offset %d accepted", offset) + } + } + if offset, valid := (Result{}).ByteOffset(0); offset != 0 || !valid { + t.Fatal("empty document lost its end position") + } + phrase := Result{Text: "a b", Words: []Word{{Text: "a b", Span: Span{0, 3}}}} + if _, valid := phrase.WordAt(1); valid { + t.Fatal("whitespace inside an engine word acquired an activation target") + } +} diff --git a/internal/ocr/native_test.go b/internal/ocr/native_test.go new file mode 100644 index 0000000..43e547e --- /dev/null +++ b/internal/ocr/native_test.go @@ -0,0 +1,74 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "context" + "image" + "os" + "strings" + "testing" + "time" +) + +// This is a real installed-engine check, intentionally opt-in. Ordinary tests +// and the reader build must work with no tesseract executable or language data. +func TestNativeTesseract(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_OCR") != "1" { + t.Skip("set CTHULHU_NATIVE_OCR=1 to test installed Tesseract") + } + engine := NewEngine() + catalog, err := engine.Discover(context.Background()) + if err != nil { + t.Fatal(err) + } + if language, err := catalog.resolve_language("eng"); err != nil || language != "eng" { + t.Fatal("the native painted-text fixture requires installed English data") + } + file, err := os.Open("testdata/painted-text.png") + if err != nil { + t.Fatal(err) + } + defer file.Close() + pixels, _, err := image.Decode(file) + if err != nil { + t.Fatal(err) + } + for _, layout := range []Layout{AutomaticPage, SingleBlock, SparseText} { + start := time.Now() + result, err := engine.Recognize(context.Background(), pixels, Options{Language: "eng", Layout: layout}) + if err != nil { + t.Fatal(err) + } + // Accept ordinary spacing/case variation between engine/model versions; + // this simple fixture is a pipe/coordinate proof, not an accuracy corpus. + actual := strings.ToLower(strings.Join(strings.Fields(result.Text), " ")) + if actual != "ocr test window open settings value 42" { + t.Fatalf("PSM %d did not read the known fixture: %q", layout, result.Text) + } + if len(result.Lines) != 3 || len(result.Words) != 7 { + t.Fatalf("PSM %d lost line/word structure: %+v", layout, result) + } + for _, word := range result.Words { + if !valid_word_bounds(word.Bounds, result.Width, result.Height) || + word.Bounds.Min.X < 20 || word.Bounds.Min.Y < 15 || word.Bounds.Max.Y > 185 { + t.Fatalf("PSM %d word outside painted area: %+v", layout, word) + } + } + t.Logf("PSM %d: %d words, %d lines, total %s (includes catalog and PNG encoding)", layout, len(result.Words), len(result.Lines), time.Since(start)) + } + scaled, err := engine.Recognize(context.Background(), pixels, Options{Language: "eng", Layout: SingleBlock, Scale: 2, Grayscale: true}) + if err != nil { + t.Fatal(err) + } + if scaled.Width != pixels.Bounds().Dx()*2 || scaled.Height != pixels.Bounds().Dy()*2 || len(scaled.Words) == 0 { + t.Fatalf("scaled recognition did not retain image coordinates: %dx%d, %d words", scaled.Width, scaled.Height, len(scaled.Words)) + } + for _, word := range scaled.Words { + if !valid_word_bounds(word.Bounds, scaled.Width, scaled.Height) { + t.Fatalf("invalid scaled word: %+v", word) + } + } +} diff --git a/internal/ocr/page_test.go b/internal/ocr/page_test.go new file mode 100644 index 0000000..377b59e --- /dev/null +++ b/internal/ocr/page_test.go @@ -0,0 +1,30 @@ +package ocr + +import ( + "strings" + "testing" +) + +func TestPageMovementRetainsColumnAndBounds(t *testing.T) { + lines := make([]string, 45) + for index := range lines { + lines[index] = "abcd" + } + cursor := NewCursor(Result{Text: strings.Join(lines, "\n")}) + cursor.Set(3) + if got := cursor.Move(PageUnit, 1); got.Line != "abcd" || got.Cursor != 3 || got.Offset != 103 { + t.Fatal(got) + } + if got := cursor.Move(PageUnit, 1); got.Offset != 203 { + t.Fatal(got) + } + if got := cursor.Move(PageUnit, 1); got.Offset != 223 { + t.Fatal(got) + } + if got := cursor.Move(PageUnit, 1); got.Moved { + t.Fatal(got) + } + if got := cursor.Move(PageUnit, -1); got.Offset != 123 { + t.Fatal(got) + } +} diff --git a/internal/ocr/preprocess.go b/internal/ocr/preprocess.go new file mode 100644 index 0000000..cdbd950 --- /dev/null +++ b/internal/ocr/preprocess.go @@ -0,0 +1,57 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "context" + "image" + "image/color" +) + +// Preprocess returns owned pixels in recognition coordinates. Scale uses nearest +// neighbor sampling so recognized word boxes map back through the capture transform. +func Preprocess(ctx context.Context, source image.Image, options Options) (image.Image, error) { + if source == nil || !valid_dimensions(source.Bounds().Dx(), source.Bounds().Dy()) { + return nil, ErrInvalidImage + } + scale := options.Scale + if scale == 0 { + scale = 1 + } + width, height := source.Bounds().Dx(), source.Bounds().Dy() + if scale < 1 || scale > 4 || height > MaxPixels/scale || !valid_dimensions(width*scale, height*scale) || + options.Threshold < 0 || options.Threshold > 255 { + return nil, ErrLimit + } + if scale == 1 && !options.Grayscale && !options.Invert && !options.BlackWhite { + return source, nil + } + processed := image.NewRGBA(image.Rect(0, 0, width*scale, height*scale)) + for y := 0; y < height*scale; y++ { + if y%32 == 0 && ctx.Err() != nil { + return nil, ctx.Err() + } + for x := 0; x < width*scale; x++ { + r, g, b, _ := source.At(source.Bounds().Min.X+x/scale, source.Bounds().Min.Y+y/scale).RGBA() + red, green, blue := uint8(r>>8), uint8(g>>8), uint8(b>>8) + gray := uint8((299*uint32(red) + 587*uint32(green) + 114*uint32(blue) + 500) / 1000) + if options.Grayscale || options.BlackWhite { + red, green, blue = gray, gray, gray + } + if options.Invert { + red, green, blue = 255-red, 255-green, 255-blue + } + if options.BlackWhite { + value := uint8(0) + if int(red) >= options.Threshold { + value = 255 + } + red, green, blue = value, value, value + } + processed.SetRGBA(x, y, color.RGBA{R: red, G: green, B: blue, A: 255}) + } + } + return processed, ctx.Err() +} diff --git a/internal/ocr/preprocess_test.go b/internal/ocr/preprocess_test.go new file mode 100644 index 0000000..6faca37 --- /dev/null +++ b/internal/ocr/preprocess_test.go @@ -0,0 +1,47 @@ +package ocr + +import ( + "context" + "image" + "image/color" + "testing" +) + +func TestPreprocessScaleThresholdAndLimit(t *testing.T) { + source := image.NewRGBA(image.Rect(4, 5, 6, 6)) + source.SetRGBA(4, 5, color.RGBA{R: 20, G: 20, B: 20, A: 255}) + source.SetRGBA(5, 5, color.RGBA{R: 220, G: 220, B: 220, A: 255}) + processed, err := Preprocess(context.Background(), source, Options{Scale: 2, BlackWhite: true, Threshold: 200}) + if err != nil { + t.Fatal(err) + } + if processed.Bounds() != image.Rect(0, 0, 4, 2) { + t.Fatal(processed.Bounds()) + } + for x := 0; x < 4; x++ { + r, _, _, _ := processed.At(x, 0).RGBA() + want := uint32(0) + if x >= 2 { + want = 0xffff + } + if r != want { + t.Fatalf("pixel %d = %d", x, r) + } + } + if _, err := Preprocess(context.Background(), source, Options{Scale: 5}); err != ErrLimit { + t.Fatal(err) + } +} + +func TestPreprocessInversion(t *testing.T) { + source := image.NewRGBA(image.Rect(0, 0, 1, 1)) + source.SetRGBA(0, 0, color.RGBA{R: 10, G: 20, B: 30, A: 255}) + processed, err := Preprocess(context.Background(), source, Options{Invert: true}) + if err != nil { + t.Fatal(err) + } + r, g, b, _ := processed.At(0, 0).RGBA() + if r != 245*257 || g != 235*257 || b != 225*257 { + t.Fatalf("inverted pixel %d %d %d", r, g, b) + } +} diff --git a/internal/ocr/process.go b/internal/ocr/process.go new file mode 100644 index 0000000..3965aee --- /dev/null +++ b/internal/ocr/process.go @@ -0,0 +1,107 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "bytes" + "context" + "errors" + "os" + "os/exec" + "strings" + "syscall" + "time" +) + +// bounded_buffer never retains more than limit bytes. Child-output overflow +// cancels its process immediately instead of leaving a stopped pipe reader. +type bounded_buffer struct { + data bytes.Buffer + limit int + ctx context.Context + cancel context.CancelFunc + overflow bool +} + +func (buffer *bounded_buffer) Write(data []byte) (int, error) { + if err := buffer.ctx.Err(); err != nil { + return 0, err + } + if len(data) > buffer.limit-buffer.Len() { + buffer.overflow = true + if buffer.cancel != nil { + buffer.cancel() + } + return 0, ErrLimit + } + return buffer.data.Write(data) +} + +func (buffer *bounded_buffer) Bytes() []byte { return buffer.data.Bytes() } +func (buffer *bounded_buffer) Len() int { return buffer.data.Len() } + +func (engine *Engine) run(parent context.Context, input []byte, limit int, args ...string) ([]byte, []byte, error) { + return run_process(parent, engine.command, input, limit, args...) +} + +func run_process(parent context.Context, factory func(context.Context, ...string) *exec.Cmd, input []byte, limit int, args ...string) ([]byte, []byte, error) { + ctx, cancel := context.WithCancel(parent) + defer cancel() + command := factory(ctx, args...) + // This reader targets Linux/Xorg. Own the whole process group, including + // descendants that might inherit pipes from a wrapper executable. + command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + kill := func() error { + if command.Process == nil { + return os.ErrProcessDone + } + err := syscall.Kill(-command.Process.Pid, syscall.SIGKILL) + if errors.Is(err, syscall.ESRCH) { + return os.ErrProcessDone + } + return err + } + command.Cancel = kill + command.WaitDelay = time.Second + command.Env = process_environment(command.Env) + command.Stdin = bytes.NewReader(input) + output := &bounded_buffer{limit: limit, ctx: ctx, cancel: cancel} + diagnostics := &bounded_buffer{limit: maxStderrBytes, ctx: ctx, cancel: cancel} + command.Stdout, command.Stderr = output, diagnostics + err := command.Run() + // WaitDelay closes inherited pipes after a bound, but os/exec only kills the + // direct child then. Retire any remaining group before admitting another job. + if command.Process != nil { + _ = kill() + } + if parent.Err() != nil { + return nil, nil, parent.Err() + } + if output.overflow || diagnostics.overflow { + return nil, nil, ErrLimit + } + if err != nil { + if errors.Is(err, exec.ErrNotFound) || errors.Is(err, os.ErrNotExist) || errors.Is(err, os.ErrPermission) { + return nil, nil, ErrUnavailable + } + // Never forward native stderr: it can contain captured text or paths. + return nil, diagnostics.Bytes(), ErrRecognition + } + return output.Bytes(), diagnostics.Bytes(), nil +} + +func process_environment(environment []string) []string { + if environment == nil { + environment = os.Environ() + } + result := make([]string, 0, len(environment)+2) + for _, entry := range environment { + if !strings.HasPrefix(entry, "LC_ALL=") && !strings.HasPrefix(entry, "OMP_THREAD_LIMIT=") { + result = append(result, entry) + } + } + // Stable CLI diagnostics; avoid using every core for a desktop OCR request. + return append(result, "LC_ALL=C", "OMP_THREAD_LIMIT=1") +} diff --git a/internal/ocr/testdata/painted-text.png b/internal/ocr/testdata/painted-text.png new file mode 100644 index 0000000000000000000000000000000000000000..9b1c0f32ef5b7939aa8edc06b03a583e373be24d GIT binary patch literal 11544 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV7SA<#K6FiU(ii)6cj9Pn&|5~G4xw*g2b=Ci}QZHHJ;6U=7Plj`TM)xt$Ow9+Vc9~t5>fw zwIy;eFff$pGVhaSU|{%Q<;1|o!0>>P$$)`@fnT73k%6J2fq{pC;Q%vB0s{ksoB{(g z1H%UfMhOOn26m1E3=9l54m8xVtI0z}h=b+axpT2Kch*L4=VD=Mbl6b;|DT?n2}48L zFWv)1JO6xnc{wpL(Yc+kw4`K;hl-h*88bUy%!Y)64-dD$e*OA(XmnN8ujTXWtTHdD zh>MFC7Z*D_J4Z*~Ug+Ge7q{of^7(bE)~*eWJazW0?*bPcvFOOi%8CjWc6N0Yl@lqO z`sOYO(ON3HYv<0=HEeTVxA`(LFo;U*_4M(1bASK-Hs{;7ZoRv=H(GD{{w=GfOqtRt zte#~jsI0tLR69&WTwHrfX=!QgOIHbtf(LJJZ?`V!^Y!)J!WJHWoloR?d)^I|w!{`E zMa3g0Pp<6l|NZrP{N>df^Y8D2c(3XuqcP9tlj`$XSXffh)3Z;6#l`K*y1Hs-@pCgX zv#b-_il6(%$KTfuUzcIGB1EgVukYTD!en--KgZ?kfBgJuTlr}Tb1EYPgO!6mqlJx4 z&FgDxO>~7ir|Co%y}Pq>(V|7qo;~~Y>C=@fSNiS$-MDjSPMU|04-W@NMs{{^-UwtjoKOG_y5cH@Bcp@m;e9casR4SS~GpVJv!RGX3d(z?fmU6EfG;sS$S7qUS59l zzUMZS5CP`?2SFT>qweastT^wOXIv#_wx zu%GxeD=SONw#wvePD)BhRMe_~s|}3IFXF1Jf2W_HSGvY?7PG-&19APhlzMiXx<3)8 zvxF4I0yu0q5WI1+?4J$oi!_apIGkL0;?=Y%?s z96FSAVS!^}VxoE8ofn(BnHkor%d$WC@uT8f+59O}zFhjVbLUQ_i5<`GZ%AY=4|j56 zik`ab#>(F5Yzgn0UsZp9ml>H`y*ReCv@{`M!LBps&YjbG|HEjej*5!Q=SCxAW9w@w zrFH*)rqBBS_xt_u8>&;idV70sa>?6NESQk^{oUP?>*n`s4&Pnp%dl?EnmIMN!J@-`Jy*)2qzyAH=qVm*g$u`T14-d}FG!{)$|4>xO@L;{?_K$nQ*T-$S zjKr zlP59zYAP=;^F7?ofBw{|R}Pa+r0wf$*19ATqTwGjnaj~c8Nq_slN8T+GsXE~6>-+BAyOQYf`fxoQ=h)P zyxhH4>ZsVAZMn1e>GLt{nO7p&ke!uvKqcQ(LxoYPRs(8}lYCUi|oQJO5PUE7z{|Nfc?SU@$_D)RfNme$0uXf+aE=%jf{;i2Qr6# z{{DS`@$+-X3L`II%D}W@M~5)s%d^@9U>eLHG0~pS zv!rqJzI|~@6FXd#CVHrdaJ4!uJUBmN`J8!b=Enq_7A;=f+tVY_c5_o|_uRR6I|P-d z>BrYSIMBFfkBzPA3?m~WDdRLA#V0Q>FMngAD&?dibaF@Grtnews2x z#HnNL+P4o5Hs7v30?H>ReNWx^FUrfy`{vkk|M^}^gPb~M&z{}3vN-v8U+BFbZ*Ce# zUAuK_R_(DhXO16lS1T$i+HrgLzefxQ;wR}bZ`iukbhe(B)}>7$o}QeC4Y*7TR%>Z$ zUiAEYBmF>bZmz1Ts<>XvhwtCjLFuElrA33s_!Zao+gksFqobw2zf>@{2l-3QZ_bQ~ z6AiPk=}h#va_w5#>uYQO{{G(H*0yW+?&`|Q+W&vQuU)(LSBBZck}EgzWO&t+kN24x z86_FV>?~?s7hLxGnyyve!EgU>wO(5(6fONdDl|0oV$0sWd)u-??e-^}wz9Iy(l~AB zwsOsykQ-NzinBBPn^ba#IqiMq_4V=BH;I_5-vYY`l9xgOEvQnCmXevii!#qRaH@Oadj1ymiG4FKYm>Jc>c_pGpVPi{rvUoRc4FB zL(lZuT3gvqsn=&Mkj%=;%DcbM*J5GE*$cUv@hN9-PH}z~|KkyZ!}NG-_z;wulCe!)3#4Iz>uqU zbS3uT+FKut}}sZ*!A_scES?pwNS*}CZMe$UUUwe(0Dx9Mp+Ci{4Kapg+? ze*ft8Yj1I`r5BfW&o8_bUd5rfbm>y5O)F*W5|@W+?_pWmaQC!a_tmqYLQkkfrs4US zna;wIk&(A}UOjvIbmMzQ?K1}x|L>{)|8J&oddW>MK4<5{Z*OnE{N>-@-}7y&udREe zFY8xQR<`W(#iHWk)2B{ZUGrd7Q&ao=?CkD}k4k%w%3Bt-?2c$z=Vrmn%lpzg>gds< z{PK276qmU7%e{HEaN4wK&h31vEiwCQBGo2eoaxoq*Eegw<4Wz?UtbnB@2#w?lxowv zbm`I*^Kb9&&Yre*#fpH6eW#C}+gtVdths1e>1R+ofkl@6!GQw~-+U)6^`4$pS9AN$ z9T^!JoyjLT6y4n1oMtk3rkBur>yMko&K}pZ>hX3oL_QD;_>6h zhv#a!8prId`ughX>Mt)#r+@u$B+0P0a#o^5>3Zqd{dKWVy&{q}&WO!QzQ3vULX z=+UD`FPd0OcdxdNmtm+-ePO}C-FisYy6i%Ur)Ot>|M_Ni{*Y%n`ug9$e_y`dPsr)o z`uP0x^zZq)#s)v0&Cbuz(bUzIHBLLTHT$}W%&wg~EAQ{Coo$}~&SA58?kyK#c0QSm z>*}9bm>B0Sj*f|0^KSJq?eKL=I#;Y%ak!m-_3Bm2mZ>QzDOp<1yj%42)YPfk;j3Po zr>CcHHom(fKP&UHif-Y2rVE{qxD;FLF6Lxp+}M^o+i9ZShxz}1&Np$i_gc7N`=Uio zhmCH%vA%!t;>A1b3j@}!UF$tfXJPTyHEY(~aJAgA>*rC%hVX`W*S`GtAGSX3>@|I% zPA4a)Ns}jccXvleMaAu@m^f|Px0CAg3*t>?8KrjZI{H&dS$XH$uiwAh7d$v1U;igC zHdc4?Ni8icIhzUrX=!OGDX;J+{G6PDD;_SDPhQZ*FYmW`ZN$b!vFfMSE!~=PbCbIN zyn^eKQVORZ{r3HPe}BKehQWh}(f=Q_qo7ehX`)9{ zQ`4hIkK}Btu3Whi5*|K%?%ch_&;82S-tQ=UY;{2;_e6?O>-U|a`y>LRqfgg)H=jCv zIyiFbw0P&B&REf!tE)oqyyfNPExG9K)G>4B&Fk^?bLY>$f9X%KmBByeNEu)nVH7!i7V|{Z*R|E zzCAy;#DZaSd1a@|r$0Z7-}+B`dtc*0UDb+h+rlbWs!g53ydlkL;e^=zn`3=13DpL7 zZ`!aSpzrCMV1Fl%_xJW*y}G!c;f%qVrQXx8?6vjbFf=pcj@2>v-?(y;d&Dx18x0JoTb$Yt~<<>G& z12eO@okdT@<7+NX6caY8{`N-ExlO=n*6i6=Sq-Mz{dmBrl$9Fy{jL* z51l%d_50h~%gcO|xBvL{>)qYm;fEK^Gcz;m?Cd-h?lxO3v(q}us_>D^({IK1SHJwF zc+GRNnyQM*2JO;<$cTs|$B(a$;p~<&OggfD|G!li0-r@~$+);Oc=-z-^HTTp%XdFK zVsI#5e*J^qwYoVHsIjUS3{bU*EfT?ld(uB_$`%o;52Z?B1nI zlO{|ssQ*_ZE-tRDtla5xX?6JemBGv3-P^l+)v8sWeJ}OwHhE_M?<4H2)*DQW%btGv>GN}Qt?U2&*_wUb%iCL9Tl?&pGda1r z?fmlZ-oKX@5JL*rtL}X=Kc7yIe|LBH_eV#&pFK;{*4EC>&W4P%^vT&) zota_y_t)3US0643TDftfq2iINS55Wx*B`EAU~mX$;W_+b<*Ui+{&jyo9>00><}0Hc zw{GR#*-?13OO%ameYpFd1C7kt*Ve3Dx$@$iw;vxLul@b)>Pf*;=>}J&i7|TRMMYXV zI#)bDGcd$CS9R9#9Ip9vQk{{JQEHLC;*vdkKt)aQ^K-d5Ial0`cP(EVy}hliZJ)_6 zCWZs?v*VZwDk^?lTN|Ajr6Qyox#`KBoyD%Mu4m7lefsq2%9ShS>;G)rxzqCOgc&m= z1OzTzySA)dOo3_j?{cd7?7W1SpXetP1WyS^jHJ44CFW{>gt@~!rZ_w2E0 zba0S=C*<_$^Jmuod1q!A-g@%z+R8k!Eq;2jiHV676+a#vZ1(l_)z#ItwY9yzKK}ok zo5oHjuC0yE{QLX+`*6J()23}Jd3j0Exh*0hqT^^%bo6bT;%l{OdYD(H`njI>NWB{DTtTrWmr`sv%%wKqD?9`BdW z&%fC>H!v@6-Lm>RC%1mNwZ3wBbDb7W5P0&R=uv@?BnB;@!jKT;m+nKr}q7PHv3!L{D+6zFK^=7Z?@%1qwynE zhVnO;Vs{ic>WHn@PRhwS^DjJ*E6VxArz z3GXMRrl!6r`<8d^UcGt#y+0owI!GcYua z+@2R(RaNEd+v}sIt)tV^*;!axy0rTD_xJwkqAP9IO`RGV5)$I)*B7F-cHKI=(pOhN z<7s-<*1M-on^qP(pWpt^glSVfRMh?F<%Hkln=iQdb@~B)-UG5bN=i#h_f~&jR(-O_A3?EOAuhZ1lo_sRJ)YR0{ z(sH_f{Jkximp?o_ym`~6EqhNfFvL1dXPogn>nwC+!3Q+5P-gu-Pfx77{`Xt+r-wJn zo+`gr>7Mw0srU33dhYJW+xg|ShB_4VWFXwm6a=b4!rq4Kk;ze)~#DJ^DG%0zArrO837qF;MzZ>xtaO*KHlwY>-z0} zWjs34$t8XE?Ahd`q>NwB=hy4$>OOs!n*ZYB#fv%dGf$s6lXHHat;yNBJI`*d{+=f; zF5cQ(R#tZK;6anx@9$!#vR*ALE$!{@Ha0X|SpV$#^Y=G5r(ay;DkmrR?Af#Y{eQnr zkFT3KfByPSYy8fwIKAcjrK87=T{`mY?ChNzr)}D@<v^|m{j zf#DQroF+T_=9X{SK3uI%W(q5#=RE?A@9n&M`Ev1{9fd6uwr$(?`uh6Kwsp{rUNs zmzQ_vZD}bfz1Uq_3Lm?bmw#WdK%v$0p_S!gz03E!uV1=U^!l2vQ-^~>#GZ8EeJBE-bRPD$qE zMS#RMxq1(B*xnK6~z#IyA!L3_bTI%8}^Y;4s`MWF~bF8JMq_$YPv%Y)x z?*C`||IYLC+FDzCWh^JvvUdFW`K@pJ_HswZ#=P_3u(YlHwPokdnF5cVJxj~YUAr#o z+fq~3ix)4txw-Ki&bhhi=(%%wM>+&gPuI6Ec)$?0g{|S8&veEa)vtA6UHs3_t!HWF z@8jd+lj_=By?WKE8@+e(Cj9Zw&CR`&-g3t)eZui#J)opHS`u65# z@#AB?yLRpR{r&y>J3A-OT^14%aiZ_qt5-d{e5&7cN}*?%lh%xVZcE|7)|ev#b3X8656|y72OUi`ZLCA3sYu z?61D{d)w`q7ORAv7GAh~`Sbq&zxNv(8&B7d_cM>%TlMwX+1Vz4Pt6V7y-xof5MZCE^AKXhn@$vET zOwi!;wr$%^Ns6R}Yiej}F6^9VTfIs8=DaTrjLchRc3rEj@=%(XaeZCvn~;ZBu7u30 zC_V2X{bv8%XZ6`KP+W*t6qB<0?oN^$+TCGxv%ik_Uv{&bL^p(6B! z1p_-9+oprbFE1_4`5vzfE3WU%!3x=HT$R z_WwTiPnjap+Pih@)^0J~MK4zdFV{MAA#!Jts;`TytE^p3MC@5pQ&T}f!ILLXO8Kqo zUK_uE9)CVpR}@XnWMH_Lu|3ZH_nNr9v)0C|2(`AfsHm%pi;HjHvSm-j zMutne0t*P$Y#-zDwB0$7e}p*xIP8 z>$D#~e{Np+>B)x=9~Qg!FI&F+`Lk#HDn2gSx^?TujfU3Nzb`Cwetf(?{q~!O4;OCO z5`6qzM^bj&ww#-j)%``Tt-4~zzxeKPi7T;;rPJ4~Ti5q@&!nYGpMHCLTi&+n%B4#| zVPRt8;>$OD;3!vJ!!52S;G`nt84wT<6LV*=d;hFivtGS=wQ2L_@^^P$zIfr$-6L)8 z7dx4Op<>~52A%1rZ}toAyE4bJSV~H2igx1rXL53Kv+R#;D0>?<_3VnZYnL+5*1wv{ z7;*ZWfRm1nPTsveD<>N-+Ln8JnUVT;XYN~162AyHNVa+U`K8(SF75ek*d|~1qfyrt z(%apAN|V8%e8FSIj8g{=BpmOP<>chd-}iG_Th6v^+jf_~x2yYOv0G@Gmr&=EBb~xp z;f_KaEUUxU_jPpzMP4{_Mn_dO_2s3dCJ8H2Qd76q{{EJEd0A$L!*yxfsuC}+uA((> z&q&sOILKadRD*ZR$;I};%l&%0yMuSO&04xNwWh{q?j@gpwFWn@UoU@uZ?DueyR92H zdiwaxF-UAWC(XlfK{Cr)X0Et|ghlnYH=EPX&$F-pcWZ0*(xpp7LqpTj(#p!p4!7}s z{{FrG``z-bF&i)4ylJVc`}Vkey-nGhh_bS>($cMS=iY7M6h3t5P)$vZiHM1r*}eVs z|96$X=99H5`T6PTo;`cIy11O3o!QyjCn~%9&9}2PFbFujO3l~Y?dH4XSofT3tKpPik( zEpeVrC1`SZu66k(*H{%H&xi<#`?{9P{8w0}&wyFacV!yn-ZLX`UtEt(!&nqM@E-pU){^oRladB~b z`~BbV*Y7WXf3Ie{AcI5tuJ_p<3=9nQi4skNYViTio-&SA5fAi*Kz&g}7n&jJVkE=A z7mNErJurn2pFdyT2Wl#3tjyp4H!NJYvedTv+nGCeVm>Ti9ll=cd1hwj$rC4TY)(Ia zsFi!~-o0<%yy@xbQ4#8FZa%!kbF$sV?)w?#%oT*%qDapRk(tPBl#9_h{(S|;q;W##UE zyseE5+%~*l_dAz&Ccm7`j+B!^PA8=E_k4VDQJJ~f@2^P3)%FF?&(0Q?mj}%WuUVs0 zUjF^krJzM=98sJ1?AcTJ_}J9x(}kUCYHRi5_pO=!jETWv`O8i0IcaI%?p43PXkxu* z4d3jq^ZEQ7?R-Me?Uwzf{3IC1ji$@};J-+sUD_Kh1i8r4+Q z)h~1Uo}Q)~JpK7)fBU7CCOvbOFJE5&<6(PTT->#5*V@|J`uh5Um-%$|^-c3yDw{F2 zX~`0mThVv-*YBS>GctWuQE~C@J(b43_ji@9{+!Fqz)+i5qNS?Z8kU`t6B8S|RxjGm zkMC?+LP9`5fP;Beb#->e^5*8lTeGiU3H4Byv9z?*%(1WkXQR8Xh_$QPM>9L zDgr9=p_BSyme$tycN98*HodrJ)v8tD>*HD`Ja~|>>*&3E^TOs$nslj=>;2u`$K#@R z#@w5^jgg_@--{o%3G(vu|NZ?f>@;iEtVfR?T}e&ey}z!muJ+fLi_4x(nj~azZ*Nvq z-iviAzU+rU_O&&dT3VYnZ@#@XJG@={;i}cE7jwG1ANS*X!wj+o;r0(sb$8D8Ec}q>)G1wUAD|kZL+AC*s&u=cI?`9DeUjx_x00HKb2kazyAOC z`j?@&u`jxcNLE*&Nv!Uk}^eevbp00QCZC_s>zr0*f(!>`Bo7vy$@-Z;Px_!4zsILAk zX`FUp%PBvD-G&wx5lRy?feu%-Bp!ZzykA#G=iA%c*JqY(nl)=yQ&ZEc*RMGh1qB6}+4-(`Ze?Itz+YAA zc7jjm__1TBQjFfM6W5R1V4LtuYSOeeK3Ol}H!8||lO)>q9Zt^5va0@;Q+m^_SIYId z?)@Ewi(|jW@2~s2`~5!UmYn-39?=c4S9b0j1d|ldNDgDEE9EG$S-H( zA$)3eeC*z;(gz0`xy5uWs=j1|g@u)tZap>A_l-{c-bELuPx`-dEeQ0=?tA`h`RV=) zO(UaE2bC#QEZGA!VJ@!E8% zs`s=D7mEJ<`8jEl&@Mw|Wo2XI$pT49NkSqbN6!BL@bIu^@G_gqPfwPbZr{4~<-VO> zQPI)2r_R4v<+$P&6)BW^ka9q%idY2=G{AKkZaUyH!b zn02d7SCwek+uuKa{Q1FV_Ld1Vjnn7ZR9-r9qT{_ABZGtW3quBJY3cLx?dLD!m$Nx> z?pV;fe^S!YmtBR6i;F|Ql_V!6^~qRXYBbxid-wMj7n=npO`g2iKz_Esr8{@_6g+e) z{k%MEU5ux2U|?W7zkFDE$E;biIyyLRHD5pW>gsCK{xog}q!v6_#oz8uA=I_sz)Ew70KMPfKgk$rM#pRrh{5S)&w= z?P*W@4bRLn?Y{f^{d;+N`S^eUg{fZB($e#7Dkn{tup#B7kkkWVVd2t(y%KGeH@zYx zB_-c{e#y!$w&DBE}O*|KGej7`OdRiUf%?(dTo6ufxS?9Se5P$R$g_qVAYD$}M-JKWCy|JCaC@9ytE z&sV!TIVT4+F+XR{oU^md{bv{)ym;~Ag$oz1T)A@gtgeQJhMC#7pP!#+Utf3i!bvs; zh5)sMEpd*ZWxFM;@;U5-X~it5jaIrX maxRows || limited.N <= 0 { + return Result{}, ErrLimit + } + fields := strings.SplitN(scanner.Text(), "\t", 12) + if len(fields) != 12 { + return Result{}, invalid_row(rows) + } + var numbers [10]int + for index := range numbers { + number, err := strconv.ParseInt(fields[index], 10, 32) + if err != nil || number < 0 { + return Result{}, invalid_row(rows) + } + numbers[index] = int(number) + } + level := numbers[0] + if level < 1 || level > 5 || numbers[1] < 1 { + return Result{}, invalid_row(rows) + } + for index := 2; index <= 5; index++ { + if (index <= level && numbers[index] < 1) || (index > level && numbers[index] != 0) { + return Result{}, invalid_row(rows) + } + } + confidence, err := strconv.ParseFloat(fields[10], 64) + if err != nil || math.IsNaN(confidence) || math.IsInf(confidence, 0) || confidence < -1 || confidence > 100 { + return Result{}, invalid_row(rows) + } + // Subtraction avoids overflowing 32-bit additions on ARM builds. + left, top, boxWidth, boxHeight := numbers[6], numbers[7], numbers[8], numbers[9] + if left > width || top > height || boxWidth > width-left || boxHeight > height-top { + return Result{}, invalid_row(rows) + } + wordText := fields[11] + if !utf8.ValidString(wordText) || strings.ContainsFunc(wordText, unicode.IsControl) { + return Result{}, invalid_row(rows) + } + if level != 5 { + if wordText != "" || confidence != -1 { + return Result{}, invalid_row(rows) + } + continue + } + if strings.TrimSpace(wordText) == "" { + continue + } + bounds := image.Rect(left, top, left+boxWidth, top+boxHeight) + if !valid_word_bounds(bounds, width, height) || strings.TrimSpace(wordText) != wordText { + return Result{}, invalid_row(rows) + } + separatorBytes := 0 + if len(result.Words) != 0 { + separatorBytes = 1 + } + if len(result.Words) >= maxWords || text.Len()+len(wordText)+separatorBytes > MaxTextBytes { + return Result{}, ErrLimit + } + id := LineID{numbers[1], numbers[2], numbers[3], numbers[4]} + if len(result.Lines) == 0 || result.Lines[len(result.Lines)-1].ID != id { + if closedLines[id] { + return Result{}, invalid_row(rows) + } + if len(result.Lines) != 0 { + closedLines[result.Lines[len(result.Lines)-1].ID] = true + text.WriteByte('\n') + offset++ + } + result.Lines = append(result.Lines, Line{ID: id, Span: Span{Start: offset}, WordStart: len(result.Words)}) + } else { + text.WriteByte(' ') + offset++ + } + start := offset + text.WriteString(wordText) + offset += rune_length(wordText) + result.Words = append(result.Words, Word{wordText, confidence, bounds, Span{start, offset}}) + line := &result.Lines[len(result.Lines)-1] + line.End, line.WordEnd = offset, len(result.Words) + } + if limited.N <= 0 { + return Result{}, ErrLimit + } + if scanner.Err() != nil { + if errors.Is(scanner.Err(), bufio.ErrTooLong) { + return Result{}, ErrLimit + } + return Result{}, fmt.Errorf("%w: reading TSV", ErrInvalidOutput) + } + result.Text = text.String() + return result, nil +} + +func invalid_row(row int) error { + return fmt.Errorf("%w: TSV row %d", ErrInvalidOutput, row) +} diff --git a/internal/ocr/tsv_test.go b/internal/ocr/tsv_test.go new file mode 100644 index 0000000..04940d5 --- /dev/null +++ b/internal/ocr/tsv_test.go @@ -0,0 +1,135 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package ocr + +import ( + "errors" + "image" + "strings" + "testing" + "unicode/utf8" +) + +func TestParseTSVHierarchyUnicodeAndEngineOrder(t *testing.T) { + data := tsvHeader + "\n" + + "1\t1\t0\t0\t0\t0\t0\t0\t200\t100\t-1\t\n" + + "2\t1\t1\t0\t0\t0\t0\t0\t200\t100\t-1\t\n" + + "3\t1\t1\t1\t0\t0\t0\t0\t200\t100\t-1\t\n" + + "4\t1\t1\t1\t1\t0\t0\t0\t200\t100\t-1\t\n" + + "5\t1\t1\t1\t1\t1\t100\t50\t30\t20\t0\té\n" + + "5\t1\t1\t1\t1\t2\t10\t50\t30\t20\t-1\t中文\n" + + "5\t1\t1\t2\t1\t1\t10\t10\t30\t20\t95.25\te\u0301\n" + + "5\t2\t1\t1\t1\t1\t10\t10\t30\t20\t85\tNext" + result, err := ParseTSV(strings.NewReader(data), 200, 100) + if err != nil { + t.Fatal(err) + } + if result.Text != "é 中文\ne\u0301\nNext" || len(result.Lines) != 3 || len(result.Words) != 4 { + t.Fatalf("wrong assembly: %+v", result) + } + if result.Words[1].Span != (Span{2, 4}) || result.Words[2].Span != (Span{5, 7}) || + result.Words[1].Confidence != -1 || result.Words[0].Confidence != 0 || + result.Words[0].Bounds != image.Rect(100, 50, 130, 70) { + t.Fatalf("lost Unicode offsets, low confidence or coordinates: %+v", result.Words) + } + if result.Lines[1].ID != (LineID{1, 1, 2, 1}) || result.Lines[1].Span != (Span{5, 7}) || + result.Lines[1].WordStart != 2 || result.Lines[1].WordEnd != 3 { + t.Fatalf("lost paragraph/line ownership: %+v", result.Lines) + } +} + +func TestParseTSVEmptyAndQuotedWords(t *testing.T) { + for _, data := range []string{tsvHeader + "\n", tsvHeader + "\r\n1\t1\t0\t0\t0\t0\t0\t0\t100\t100\t-1\t\r\n"} { + result, err := ParseTSV(strings.NewReader(data), 100, 100) + if err != nil || result.Text != "" || len(result.Words) != 0 { + t.Fatalf("empty result: %+v, %v", result, err) + } + } + data := tsvHeader + "\n5\t1\t1\t1\t1\t1\t0\t0\t10\t10\t99\t\"word\"\n" + result, err := ParseTSV(strings.NewReader(data), 100, 100) + if err != nil || result.Text != `"word"` { + t.Fatalf("TSV word treated as CSV quoting: %+v, %v", result, err) + } +} + +func TestParseTSVRejectsMalformedOutputAtomically(t *testing.T) { + row := "5\t1\t1\t1\t1\t1\t0\t0\t10\t10\t90\tPrivate fixture text" + for _, bad := range []string{ + "missing fields", + strings.Replace(row, "5\t", "6\t", 1), + strings.Replace(row, "5\t1", "5\t0", 1), + strings.Replace(row, "0\t0\t10\t10", "-1\t0\t10\t10", 1), + strings.Replace(row, "0\t0\t10\t10", "95\t0\t10\t10", 1), + strings.Replace(row, "0\t0\t10\t10", "0\t0\t0\t10", 1), + strings.Replace(row, "0\t0\t10\t10", "0\t0\t2147483647\t10", 1), + strings.Replace(row, "90\t", "NaN\t", 1), + strings.Replace(row, "90\t", "+Inf\t", 1), + strings.Replace(row, "90\t", "101\t", 1), + strings.Replace(row, "90\t", "-2\t", 1), + row + "\x00", + row + "\xff", + row + "\textra field", + row + " ", + } { + result, err := ParseTSV(strings.NewReader(tsvHeader+"\n"+row+"\n"+bad+"\n"), 100, 100) + if !errors.Is(err, ErrInvalidOutput) || result.Text != "" || len(result.Words) != 0 { + t.Fatalf("accepted malformed row or partial document: %+v, %v", result, err) + } + if strings.Contains(err.Error(), "Private") { + t.Fatal("recognized text leaked into error") + } + } + if _, err := ParseTSV(strings.NewReader("not a TSV header"), 100, 100); !errors.Is(err, ErrInvalidOutput) { + t.Fatal("invalid header accepted") + } + if _, err := ParseTSV(strings.NewReader(tsvHeader), MaxPixels, 2); !errors.Is(err, ErrInvalidImage) { + t.Fatal("pixel limit ignored") + } +} + +func TestParseTSVLimitsAndRevisitedLine(t *testing.T) { + if _, err := ParseTSV(strings.NewReader(tsvHeader+"\n"+strings.Repeat("x", 64<<10)), 100, 100); !errors.Is(err, ErrLimit) { + t.Fatalf("unbounded row: %v", err) + } + row := "5\t1\t1\t1\t1\t1\t0\t0\t10\t10\t90\tword\n" + secondLine := strings.Replace(row, "1\t1\t1\t1\t1\t", "1\t1\t1\t2\t1\t", 1) + if _, err := ParseTSV(strings.NewReader(tsvHeader+"\n"+row+secondLine+row), 100, 100); !errors.Is(err, ErrInvalidOutput) { + t.Fatalf("revisited line accepted: %v", err) + } + largeWord := "5\t1\t1\t1\t1\t1\t0\t0\t10\t10\t90\t" + strings.Repeat("x", 60<<10) + "\n" + if _, err := ParseTSV(strings.NewReader(tsvHeader+"\n"+strings.Repeat(largeWord, 20)), 100, 100); !errors.Is(err, ErrLimit) { + t.Fatalf("text limit ignored: %v", err) + } + if _, err := ParseTSV(strings.NewReader(tsvHeader+"\n"+strings.Repeat(row, maxWords+1)), 100, 100); !errors.Is(err, ErrLimit) { + t.Fatalf("word limit ignored: %v", err) + } +} + +func FuzzParseTSV(f *testing.F) { + f.Add(tsvHeader + "\n5\t1\t1\t1\t1\t1\t1\t1\t10\t10\t90\t中文\n") + f.Add("") + f.Fuzz(func(t *testing.T, data string) { + result, err := ParseTSV(strings.NewReader(data), 200, 100) + if err != nil { + if result.Text != "" || len(result.Words) != 0 { + t.Fatal("partial result escaped a parser failure") + } + return + } + if !utf8.ValidString(result.Text) || len(result.Text) > MaxTextBytes { + t.Fatal("invalid document text") + } + lastEnd := 0 + for _, word := range result.Words { + start, startOK := result.ByteOffset(word.Start) + end, endOK := result.ByteOffset(word.End) + if !startOK || !endOK || word.Start < lastEnd || word.End <= word.Start || + result.Text[start:end] != word.Text || !valid_word_bounds(word.Bounds, result.Width, result.Height) { + t.Fatal("invalid word map") + } + lastEnd = word.End + } + }) +} diff --git a/internal/ocrcapture/capture.go b/internal/ocrcapture/capture.go new file mode 100644 index 0000000..6901e4f --- /dev/null +++ b/internal/ocrcapture/capture.go @@ -0,0 +1,89 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package ocrcapture is used only by the short-lived, headless native helper. +// The reader's worker uses ocr.Capturer and never calls GTK/X11 capture in-process. +package ocrcapture + +/* +#cgo pkg-config: gtk+-3.0 x11 +#include "native.h" +*/ +import "C" + +import ( + "bytes" + "context" + "image" + "image/png" + "io" + "os" + "runtime" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/ocr" +) + +func Run(ctx context.Context, input io.Reader, output io.Writer) error { + request, err := ocr.ReadCaptureRequest(input) + if err != nil { + return err + } + if err := ctx.Err(); err != nil { + return err + } + header := ocr.CaptureHeader{Request: request, Status: "unavailable"} + runtime.LockOSThread() + defer runtime.UnlockOSThread() + // This backend captures physical X11 pixels, including Xwayland when it + // provides them. Native display/source checks decide availability. + _ = os.Setenv("GDK_BACKEND", "x11") + _ = os.Setenv("NO_AT_BRIDGE", "1") + kind := map[ocr.SourceKind]int{ocr.ObjectSource: 1, ocr.WindowSource: 2, ocr.DesktopSource: 3, ocr.ClipboardSource: 4}[request.Kind] + native := C.cthulhu_ocr_capture(C.int(kind), C.ulong(request.Foreground), C.ulong(request.Window), + C.int(request.Bounds.Min.X), C.int(request.Bounds.Min.Y), C.int(request.Bounds.Max.X), C.int(request.Bounds.Max.Y)) + defer C.cthulhu_ocr_capture_free(&native) + if err := ctx.Err(); err != nil { + return err + } + if native.status != 0 { + header.Status = map[int]string{1: "unavailable", 2: "source", 3: "changed", 4: "limit"}[int(native.status)] + return ocr.WriteCaptureResponse(output, header, nil) + } + header.Status = "" + var pixels image.Image + if request.Kind == ocr.ClipboardSource { + data := C.GoBytes(unsafe.Pointer(native.clipboard), native.clipboardLength) + config, decodeErr := png.DecodeConfig(bytes.NewReader(data)) + if decodeErr != nil { + header.Status = "source" + } else if config.Width <= 0 || config.Height <= 0 || config.Height > ocr.MaxPixels || config.Width > ocr.MaxPixels/config.Height { + header.Status = "limit" + } else { + pixels, decodeErr = png.Decode(bytes.NewReader(data)) + if decodeErr != nil { + header.Status = "source" + } + } + } else { + header.SourceWindow = uint64(native.sourceWindow) + header.RootBounds = image.Rect(0, 0, int(native.rootWidth), int(native.rootHeight)) + header.SourceBounds = image.Rect(int(native.sourceX), int(native.sourceY), int(native.sourceX)+int(native.sourceWidth), int(native.sourceY)+int(native.sourceHeight)) + header.ScreenBounds = image.Rect(int(native.x), int(native.y), int(native.x)+int(native.width), int(native.y)+int(native.height)) + width, height := int(native.width), int(native.height) + stride := int(C.gdk_pixbuf_get_rowstride(native.pixels)) + data := C.GoBytes(unsafe.Pointer(C.gdk_pixbuf_get_pixels(native.pixels)), C.int((height-1)*stride+width*3)) + owned := image.NewRGBA(image.Rect(0, 0, width, height)) + for row := range height { + for column := range width { + source := row*stride + column*3 + target := row*owned.Stride + column*4 + copy(owned.Pix[target:target+3], data[source:source+3]) + owned.Pix[target+3] = 255 + } + } + pixels = owned + } + return ocr.WriteCaptureResponse(output, header, pixels) +} diff --git a/internal/ocrcapture/native.c b/internal/ocrcapture/native.c new file mode 100644 index 0000000..04b137f --- /dev/null +++ b/internal/ocrcapture/native.c @@ -0,0 +1,154 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "native.h" +#include +#include +#include +#include + +// Status codes: unavailable, source unavailable, source changed, limit. +static Window active_window(Display *display, Window root) { + Atom type; + int format; + unsigned long count, remaining; + unsigned char *data = NULL; + Window window = None; + if (XGetWindowProperty(display, root, + XInternAtom(display, "_NET_ACTIVE_WINDOW", False), 0, 1, False, + XA_WINDOW, &type, &format, &count, &remaining, &data) == Success && + data && type == XA_WINDOW && format == 32 && count == 1) + window = *(Window *)data; + if (data) XFree(data); + return window; +} + +static int is_descendant(Display *display, Window window, Window ancestor) { + for (int depth = 0; window && depth < 64; depth++) { + if (window == ancestor) return 1; + Window root, parent, *children = NULL; + unsigned int count; + int ok = XQueryTree(display, window, &root, &parent, &children, &count); + if (children) XFree(children); + if (!ok || parent == window) break; + window = parent; + } + return 0; +} + +static int window_bounds(Display *display, Window root, Window window, + int *x, int *y, int *width, int *height) { + XWindowAttributes attributes; + Window child; + if (!XGetWindowAttributes(display, window, &attributes) || + attributes.map_state != IsViewable || attributes.class != InputOutput || + !XTranslateCoordinates(display, window, root, 0, 0, x, y, &child)) return 0; + *width = attributes.width; + *height = attributes.height; + return *width > 0 && *height > 0; +} + +static guchar component(unsigned long pixel, unsigned long mask) { + if (!mask) return 0; + unsigned long value = pixel & mask; + while (!(mask & 1)) { mask >>= 1; value >>= 1; } + return (guchar)(((uint64_t)value * 255 + mask / 2) / mask); +} + +OCRCapture cthulhu_ocr_capture(int kind, unsigned long foreground, + unsigned long window, int x, int y, int right, int bottom) { + OCRCapture result = {.status = 1}; + if (!gtk_init_check(NULL, NULL)) return result; + GdkDisplay *gdkDisplay = gdk_display_get_default(); + if (!GDK_IS_X11_DISPLAY(gdkDisplay)) return result; + Display *display = gdk_x11_display_get_xdisplay(gdkDisplay); + Window root = DefaultRootWindow(display); + gdk_x11_display_error_trap_push(gdkDisplay); + result.status = 2; + if (active_window(display, root) != foreground) { result.status = 3; goto done; } + Window source = window ? window : foreground; + int sourceX, sourceY, sourceWidth, sourceHeight; + if (!is_descendant(display, source, foreground) || !window_bounds(display, root, + source, &sourceX, &sourceY, &sourceWidth, &sourceHeight)) goto done; + + if (kind == 4) { + // Accept PNG image data only. Never fetch text, URIs or private formats. + GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + GtkSelectionData *selection = gtk_clipboard_wait_for_contents(clipboard, + gdk_atom_intern_static_string("image/png")); + if (!selection) goto done; + int length = gtk_selection_data_get_length(selection); + if (length > 64 * 1024 * 1024) result.status = 4; + else if (length > 0 && gtk_selection_data_get_format(selection) == 8) { + result.clipboard = g_memdup2(gtk_selection_data_get_data(selection), length); + result.clipboardLength = length; + result.status = 0; + } + gtk_selection_data_free(selection); + } else { + XWindowAttributes rootAttributes; + if (!XGetWindowAttributes(display, root, &rootAttributes)) goto done; + // TrueColor pixels are physical root pixels even with GDK_SCALE=2. + // Indexed/direct-color visuals would require a different color contract. + if (rootAttributes.visual->class != TrueColor) { result.status = 1; goto done; } + result.rootWidth = rootAttributes.width; + result.rootHeight = rootAttributes.height; + result.sourceWindow = kind == 3 ? 0 : source; + result.sourceX = kind == 3 ? 0 : sourceX; + result.sourceY = kind == 3 ? 0 : sourceY; + result.sourceWidth = kind == 3 ? result.rootWidth : sourceWidth; + result.sourceHeight = kind == 3 ? result.rootHeight : sourceHeight; + int64_t left = result.sourceX, top = result.sourceY; + int64_t endX = left + result.sourceWidth, endY = top + result.sourceHeight; + if (kind == 1) { + left = MAX(left, x); top = MAX(top, y); + endX = MIN(endX, right); endY = MIN(endY, bottom); + } + left = MAX(left, 0); top = MAX(top, 0); + endX = MIN(endX, result.rootWidth); endY = MIN(endY, result.rootHeight); + if (endX <= left || endY <= top) goto done; + int64_t width = endX - left, height = endY - top; + if (height > 16000000 || width > 16000000 / height) { result.status = 4; goto done; } + result.x = left; result.y = top; result.width = width; result.height = height; + XImage *pixels = XGetImage(display, root, result.x, result.y, + result.width, result.height, AllPlanes, ZPixmap); + if (!pixels) { result.status = 1; goto done; } + result.pixels = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, result.width, result.height); + if (!result.pixels) { XDestroyImage(pixels); result.status = 1; goto done; } + guchar *rgb = gdk_pixbuf_get_pixels(result.pixels); + int stride = gdk_pixbuf_get_rowstride(result.pixels); + for (int row = 0; row < result.height; row++) { + for (int column = 0; column < result.width; column++) { + unsigned long pixel = XGetPixel(pixels, column, row); + guchar *target = rgb + row * stride + column * 3; + target[0] = component(pixel, rootAttributes.visual->red_mask); + target[1] = component(pixel, rootAttributes.visual->green_mask); + target[2] = component(pixel, rootAttributes.visual->blue_mask); + } + } + XDestroyImage(pixels); + result.status = 0; + } + // Reject movement, destruction or a foreground switch during pixel/clipboard + // transfer. Later activation must still recapture/revalidate independently. + if (result.status == 0) { + int nextX, nextY, nextWidth, nextHeight; + if (active_window(display, root) != foreground || + !window_bounds(display, root, source, &nextX, &nextY, &nextWidth, &nextHeight) || + nextX != sourceX || nextY != sourceY || + nextWidth != sourceWidth || nextHeight != sourceHeight) result.status = 3; + } +done: + XSync(display, False); + if (gdk_x11_display_error_trap_pop(gdkDisplay)) result.status = 2; + if (result.status) cthulhu_ocr_capture_free(&result); + return result; +} + +void cthulhu_ocr_capture_free(OCRCapture *capture) { + if (capture->pixels) g_object_unref(capture->pixels); + g_free(capture->clipboard); + capture->pixels = NULL; + capture->clipboard = NULL; +} diff --git a/internal/ocrcapture/native.h b/internal/ocrcapture/native.h new file mode 100644 index 0000000..a7097e1 --- /dev/null +++ b/internal/ocrcapture/native.h @@ -0,0 +1,20 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#pragma once +#include + +typedef struct { + int status; + unsigned long sourceWindow; + int rootWidth, rootHeight; + int sourceX, sourceY, sourceWidth, sourceHeight; + int x, y, width, height; + GdkPixbuf *pixels; + guchar *clipboard; + int clipboardLength; +} OCRCapture; + +OCRCapture cthulhu_ocr_capture(int kind, unsigned long foreground, + unsigned long window, int x, int y, int right, int bottom); +void cthulhu_ocr_capture_free(OCRCapture *capture); diff --git a/internal/ocrconfirm/confirm.c b/internal/ocrconfirm/confirm.c new file mode 100644 index 0000000..b7705c8 --- /dev/null +++ b/internal/ocrconfirm/confirm.c @@ -0,0 +1,24 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include + +int cthulhu_ocr_confirm(const char *word) { + if (!gtk_init_check(NULL, NULL)) return 0; + GtkWidget *dialog = gtk_dialog_new_with_buttons("Confirm OCR click", NULL, + GTK_DIALOG_MODAL, "_Cancel", GTK_RESPONSE_CANCEL, + "_Activate", GTK_RESPONSE_OK, NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL); + GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + gchar *message = g_strdup_printf("Activate recognized word “%s” at its screen position?", word); + GtkWidget *label = gtk_label_new(message); + g_free(message); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_container_add(GTK_CONTAINER(content), label); + gtk_widget_show_all(dialog); + int response = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + while (gtk_events_pending()) gtk_main_iteration(); + return response == GTK_RESPONSE_OK; +} diff --git a/internal/ocrconfirm/confirm.go b/internal/ocrconfirm/confirm.go new file mode 100644 index 0000000..de21392 --- /dev/null +++ b/internal/ocrconfirm/confirm.go @@ -0,0 +1,35 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package ocrconfirm runs only in the short-lived confirmation helper. +package ocrconfirm + +/* +#cgo pkg-config: gtk+-3.0 +#include +int cthulhu_ocr_confirm(const char *word); +*/ +import "C" + +import ( + "bytes" + "io" + "unicode/utf8" + "unsafe" +) + +func Run(input io.Reader, output io.Writer) error { + data, err := io.ReadAll(io.LimitReader(input, 4097)) + if err != nil || len(data) == 0 || len(data) > 4096 || !utf8.Valid(data) || bytes.IndexByte(data, 0) >= 0 { + return io.ErrUnexpectedEOF + } + word := C.CString(string(data)) + defer C.free(unsafe.Pointer(word)) + if C.cthulhu_ocr_confirm(word) == 1 { + _, err = io.WriteString(output, "yes\n") + } else { + _, err = io.WriteString(output, "cancel\n") + } + return err +} diff --git a/internal/parity/parity.go b/internal/parity/parity.go new file mode 100644 index 0000000..04376bf --- /dev/null +++ b/internal/parity/parity.go @@ -0,0 +1,177 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package parity + +import ( + "encoding/csv" + "errors" + "fmt" + "io" +) + +var ErrSchema = errors.New("parity ledger schema") + +const ( + StatusPending = "pending" + StatusInProgress = "in-progress" + StatusImplemented = "implemented" + StatusAuditRequired = "audit-required" + StatusAcceptedOmission = "accepted-omission" +) + +var allowedStatuses = map[string]struct{}{ + StatusPending: {}, + StatusInProgress: {}, + StatusImplemented: {}, + StatusAuditRequired: {}, + StatusAcceptedOmission: {}, +} + +var columns = []string{ + "id", + "python_source", + "subsystem", + "behavior", + "owner", + "go_destination", + "status", + "automated_evidence", + "x11_evidence", + "wayland_evidence", + "speech_evidence", + "braille_evidence", + "notes", +} + +type Record struct { + ID string + PythonSource string + Subsystem string + Behavior string + Owner string + GoDestination string + Status string + AutomatedEvidence string + X11Evidence string + WaylandEvidence string + SpeechEvidence string + BrailleEvidence string + Notes string +} + +type ParseError struct { + Row int + Err error +} + +func (parseError *ParseError) Error() string { + return fmt.Sprintf("row %d: %v", parseError.Row, parseError.Err) +} + +func (parseError *ParseError) Unwrap() error { + return parseError.Err +} + +func Load(reader io.Reader) ([]Record, error) { + csvReader := csv.NewReader(reader) + csvReader.FieldsPerRecord = len(columns) + csvReader.TrimLeadingSpace = true + + header, err := csvReader.Read() + if err != nil { + return nil, &ParseError{Row: 1, Err: fmt.Errorf("%w: read header: %w", ErrSchema, err)} + } + for index, column := range header { + if column != columns[index] { + return nil, &ParseError{ + Row: 1, + Err: fmt.Errorf("%w: column %d is %q, want %q", ErrSchema, index+1, column, columns[index]), + } + } + } + + ids := make(map[string]struct{}) + var records []Record + for row := 2; ; row++ { + fields, readErr := csvReader.Read() + if errors.Is(readErr, io.EOF) { + break + } + if readErr != nil { + return nil, &ParseError{Row: row, Err: fmt.Errorf("read record: %w", readErr)} + } + record := Record{ + ID: fields[0], + PythonSource: fields[1], + Subsystem: fields[2], + Behavior: fields[3], + Owner: fields[4], + GoDestination: fields[5], + Status: fields[6], + AutomatedEvidence: fields[7], + X11Evidence: fields[8], + WaylandEvidence: fields[9], + SpeechEvidence: fields[10], + BrailleEvidence: fields[11], + Notes: fields[12], + } + if err := validate(record, row, ids); err != nil { + return nil, err + } + records = append(records, record) + } + return records, nil +} + +func validate(record Record, row int, ids map[string]struct{}) error { + for field, value := range map[string]string{ + "id": record.ID, + "python_source": record.PythonSource, + "subsystem": record.Subsystem, + "behavior": record.Behavior, + "status": record.Status, + } { + if value == "" { + return &ParseError{Row: row, Err: fmt.Errorf("%w: %s is empty", ErrSchema, field)} + } + } + if _, exists := allowedStatuses[record.Status]; !exists { + return &ParseError{ + Row: row, + Err: fmt.Errorf("%w: invalid status %q", ErrSchema, record.Status), + } + } + if _, exists := ids[record.ID]; exists { + return &ParseError{ + Row: row, + Err: fmt.Errorf("%w: duplicate id %q", ErrSchema, record.ID), + } + } + if record.GoDestination == "" && record.Status != StatusAcceptedOmission { + return &ParseError{ + Row: row, + Err: fmt.Errorf("%w: go_destination is empty for status %q", ErrSchema, record.Status), + } + } + ids[record.ID] = struct{}{} + return nil +} + +func FormatStatuses() string { + return "pending, in-progress, implemented, audit-required, accepted-omission" +} diff --git a/internal/parity/parity_test.go b/internal/parity/parity_test.go new file mode 100644 index 0000000..f911ee1 --- /dev/null +++ b/internal/parity/parity_test.go @@ -0,0 +1,88 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package parity + +import ( + "errors" + "strings" + "testing" +) + +func TestLoadValidLedger(t *testing.T) { + ledger := strings.Join([]string{ + strings.Join(columns, ","), + "core-startup,src/cthulhu/cthulhu.py,core,start the screen reader,Storm Dragon,internal/app,pending,,,,,,initial inventory", + "web-navigation,src/cthulhu/scripts/web/script.py,web,structural navigation,Storm Dragon,internal/script,pending,,,,,,initial inventory", + }, "\n") + + records, err := Load(strings.NewReader(ledger)) + if err != nil { + t.Fatalf("Load: %v", err) + } + if len(records) != 2 { + t.Fatalf("record count = %d, want 2", len(records)) + } +} + +func TestLoadRejectsInvalidRecords(t *testing.T) { + tests := []struct { + name string + ledger string + wantErr error + }{ + { + name: "missing header", + ledger: "id\n", + wantErr: ErrSchema, + }, + { + name: "invalid status", + ledger: strings.Join([]string{ + strings.Join(columns, ","), + "one,source.py,core,behavior,owner,destination,unknown,,,,,,note", + }, "\n"), + wantErr: ErrSchema, + }, + { + name: "duplicate id", + ledger: strings.Join([]string{ + strings.Join(columns, ","), + "one,source.py,core,behavior,owner,destination,pending,,,,,,note", + "one,source.py,core,behavior,owner,destination,pending,,,,,,note", + }, "\n"), + wantErr: ErrSchema, + }, + { + name: "missing destination", + ledger: strings.Join([]string{ + strings.Join(columns, ","), + "one,source.py,core,behavior,owner,,pending,,,,,,note", + }, "\n"), + wantErr: ErrSchema, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _, err := Load(strings.NewReader(test.ledger)) + if !errors.Is(err, test.wantErr) { + t.Fatalf("Load error = %v, want %v", err, test.wantErr) + } + }) + } +} diff --git a/internal/platform/session/session.go b/internal/platform/session/session.go new file mode 100644 index 0000000..c7f56e4 --- /dev/null +++ b/internal/platform/session/session.go @@ -0,0 +1,31 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package session keeps desktop session policy independent of native backends. +package session + +import ( + "os" + "strings" +) + +// Wayland respects an explicit session type; WAYLAND_DISPLAY is a fallback for +// launchers that do not set XDG_SESSION_TYPE. +func Wayland() bool { + kind := strings.ToLower(strings.TrimSpace(os.Getenv("XDG_SESSION_TYPE"))) + if kind != "" { + return kind == "wayland" + } + return strings.TrimSpace(os.Getenv("WAYLAND_DISPLAY")) != "" +} + +// GTKEnvironment preserves Xorg focus correlation in explicit X11 sessions. +// Elsewhere GTK inherits the user's backend choice and selects its own default. +func GTKEnvironment() []string { + environment := os.Environ() + if strings.EqualFold(strings.TrimSpace(os.Getenv("XDG_SESSION_TYPE")), "x11") { + environment = append(environment, "GDK_BACKEND=x11") + } + return environment +} diff --git a/internal/platform/session/session_test.go b/internal/platform/session/session_test.go new file mode 100644 index 0000000..3601b1c --- /dev/null +++ b/internal/platform/session/session_test.go @@ -0,0 +1,44 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package session + +import ( + "strings" + "testing" +) + +func TestDesktopEnvironment(t *testing.T) { + for _, test := range []struct { + name, kind, display, backend, wantBackend string + wayland bool + }{ + {"Xorg", "x11", "", "wayland", "x11", false}, + {"Xorg with inherited Wayland display", "x11", "wayland-0", "", "x11", false}, + {"Wayland", "wayland", "wayland-0", "", "", true}, + {"Wayland user backend", "wayland", "wayland-0", "x11", "x11", true}, + {"normalized session", " Wayland ", "", "wayland,x11", "wayland,x11", true}, + {"Wayland display fallback", "", "wayland-0", "", "", true}, + {"unspecified session", "", "", "wayland,x11", "wayland,x11", false}, + {"explicit other session", "tty", "wayland-0", "", "", false}, + } { + t.Run(test.name, func(t *testing.T) { + t.Setenv("XDG_SESSION_TYPE", test.kind) + t.Setenv("WAYLAND_DISPLAY", test.display) + t.Setenv("GDK_BACKEND", test.backend) + t.Setenv("CTHULHU_TEST_INHERITED", "preserved") + if got := Wayland(); got != test.wayland { + t.Fatalf("Wayland = %v, want %v", got, test.wayland) + } + values := make(map[string]string) + for _, entry := range GTKEnvironment() { + key, value, _ := strings.Cut(entry, "=") + values[key] = value + } + if values["GDK_BACKEND"] != test.wantBackend || values["CTHULHU_TEST_INHERITED"] != "preserved" { + t.Fatalf("GTK backend = %q, inherited value = %q", values["GDK_BACKEND"], values["CTHULHU_TEST_INHERITED"]) + } + }) + } +} diff --git a/internal/platform/wayland/keyboard.go b/internal/platform/wayland/keyboard.go new file mode 100644 index 0000000..64156c0 --- /dev/null +++ b/internal/platform/wayland/keyboard.go @@ -0,0 +1,243 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package wayland implements the shared accessibility KeyboardMonitor interface. +// It has no compositor names, configuration formats, or desktop-specific paths. +package wayland + +import ( + "context" + "errors" + "fmt" + "log/slog" + "sync" + "sync/atomic" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +type keyboardConfiguration struct { + layout input.KeyboardLayout + modifiers []string + bindings []input.BindingOverride +} + +type keyboardUpdate struct { + ctx context.Context + configuration keyboardConfiguration + result chan error +} + +// Keyboard owns both monitoring and commands. Only its run goroutine touches +// the connection, pressed keys, and command router. Requested policy is atomic; +// binding changes are acknowledged after held keys release. Stop joins that +// owner and closes its private connection, releasing every compositor grab. +type Keyboard struct { + logger *slog.Logger + mutex sync.Mutex + configuration keyboardConfiguration + started bool + cancel context.CancelFunc + done chan struct{} + wake chan struct{} + updates chan keyboardUpdate + commands chan input.CommandEvent + locks chan input.LockState + failures chan error + events chan input.Event + secureMutex sync.Mutex + secure atomic.Bool + secureGeneration atomic.Uint64 + enabled atomic.Bool + browse atomic.Bool + nativeButton atomic.Bool + applied atomic.Bool + browseApplied atomic.Bool + active atomic.Bool + learn atomic.Bool + learnEcho atomic.Bool + overflow atomic.Uint64 + intent input.IntentTracker +} + +func New(modifiers []string, layout input.KeyboardLayout, logger *slog.Logger) *Keyboard { + if logger == nil { + logger = slog.New(slog.DiscardHandler) + } + keyboard := &Keyboard{ + logger: logger, + configuration: keyboardConfiguration{layout: layout, modifiers: append([]string(nil), modifiers...)}, + wake: make(chan struct{}, 1), updates: make(chan keyboardUpdate), + commands: make(chan input.CommandEvent, 32), locks: make(chan input.LockState, 16), + failures: make(chan error, 1), events: make(chan input.Event, 64), + } + keyboard.enabled.Store(true) + return keyboard +} + +// Monitor shares input with the command owner; its lifecycle is owned by Keyboard. +type Monitor struct{ keyboard *Keyboard } + +func (keyboard *Keyboard) Monitor() *Monitor { return &Monitor{keyboard: keyboard} } +func (monitor *Monitor) Start(ctx context.Context) error { return ctx.Err() } +func (monitor *Monitor) Stop(context.Context) error { return nil } +func (monitor *Monitor) Events() <-chan input.Event { return monitor.keyboard.events } +func (monitor *Monitor) Overflow() uint64 { return monitor.keyboard.overflow.Load() } +func (monitor *Monitor) ModifierKeycodes() input.ModifierKeycodes { return input.ModifierKeycodes{} } +func (monitor *Monitor) RecentInput() input.Activity { return monitor.keyboard.intent.RecentInput() } +func (monitor *Monitor) RecentIntent() input.Intent { return monitor.keyboard.intent.RecentIntent() } +func (monitor *Monitor) SetSecureInputActive(active bool) { + monitor.keyboard.SetSecureInputActive(active) +} + +func (keyboard *Keyboard) Start(ctx context.Context) error { + keyboard.mutex.Lock() + defer keyboard.mutex.Unlock() + if keyboard.started { + return errors.New("Wayland keyboard already started") + } + if err := ctx.Err(); err != nil { + return err + } + if err := validate_configuration(keyboard.configuration); err != nil { + return err + } + keyboard.started = true + workerContext, cancel := context.WithCancel(ctx) + keyboard.cancel, keyboard.done = cancel, make(chan struct{}) + setup := make(chan error, 1) + go keyboard.run(workerContext, keyboard.configuration, setup) + return <-setup +} + +func (keyboard *Keyboard) Stop(ctx context.Context) error { + keyboard.mutex.Lock() + cancel, done := keyboard.cancel, keyboard.done + keyboard.mutex.Unlock() + if cancel == nil { + return nil + } + cancel() + select { + case <-done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (keyboard *Keyboard) Commands() <-chan input.CommandEvent { return keyboard.commands } +func (keyboard *Keyboard) LockStates() <-chan input.LockState { return keyboard.locks } +func (keyboard *Keyboard) Failures() <-chan error { return keyboard.failures } +func (keyboard *Keyboard) CommandGrabsEnabled() bool { + return keyboard.applied.Load() && keyboard.enabled.Load() && !keyboard.secure.Load() +} +func (keyboard *Keyboard) BrowseNavigationEnabled() bool { + return keyboard.CommandGrabsEnabled() && keyboard.browse.Load() && keyboard.browseApplied.Load() +} +func (keyboard *Keyboard) CommandGrabActive() bool { return keyboard.active.Load() } +func (keyboard *Keyboard) LearnModeActive() bool { return keyboard.learn.Load() } +func (keyboard *Keyboard) LearnModeEchoActive() bool { return keyboard.learnEcho.Load() } + +func (keyboard *Keyboard) notify() { + select { + case keyboard.wake <- struct{}{}: + default: + } +} +func (keyboard *Keyboard) SetCommandGrabs(enabled bool) { + keyboard.enabled.Store(enabled) + keyboard.notify() +} +func (keyboard *Keyboard) SetBrowseNavigation(enabled bool) { + keyboard.browse.Store(enabled) + keyboard.notify() +} +func (keyboard *Keyboard) SetNativeButtonFocus(focused bool) { + keyboard.nativeButton.Store(focused) + keyboard.notify() +} + +func (keyboard *Keyboard) SetSecureInputActive(active bool) { + keyboard.secureMutex.Lock() + defer keyboard.secureMutex.Unlock() + if keyboard.secure.Swap(active) != active { + keyboard.secureGeneration.Add(1) + } + keyboard.intent.Reset() + if active { + keyboard.browse.Store(false) + } + for { + select { + case <-keyboard.events: + case <-keyboard.commands: + case <-keyboard.locks: + default: + keyboard.notify() + return + } + } +} + +func validate_configuration(configuration keyboardConfiguration) error { + if configuration.layout != input.DesktopKeyboardLayout && configuration.layout != input.LaptopKeyboardLayout { + return fmt.Errorf("invalid keyboard layout %d", configuration.layout) + } + if _, err := modifier_symbols(configuration.modifiers); err != nil { + return err + } + return input.ValidateBindingOverrides(configuration.bindings) +} + +func (keyboard *Keyboard) SetKeyBindings(ctx context.Context, bindings []input.BindingOverride) error { + keyboard.mutex.Lock() + configuration := keyboard.configuration + keyboard.mutex.Unlock() + return keyboard.SetKeyboardConfiguration(ctx, configuration.layout, configuration.modifiers, bindings) +} + +func (keyboard *Keyboard) SetKeyboardConfiguration(ctx context.Context, layout input.KeyboardLayout, modifiers []string, bindings []input.BindingOverride) error { + configuration := keyboardConfiguration{layout: layout, modifiers: append([]string(nil), modifiers...), bindings: input.CloneBindingOverrides(bindings)} + if err := ctx.Err(); err != nil { + return err + } + if err := validate_configuration(configuration); err != nil { + return err + } + keyboard.mutex.Lock() + if !keyboard.started { + keyboard.configuration = configuration + keyboard.mutex.Unlock() + return nil + } + done := keyboard.done + keyboard.mutex.Unlock() + update := keyboardUpdate{ctx: ctx, configuration: configuration, result: make(chan error, 1)} + select { + case keyboard.updates <- update: + case <-done: + return errors.New("Wayland keyboard is unavailable") + case <-ctx.Done(): + return ctx.Err() + } + // The owner resolves cancellation before returning, so a failed preference + // update cannot silently commit after its caller has rolled back settings. + select { + case err := <-update.result: + return err + case <-done: + return errors.New("Wayland keyboard stopped") + } +} + +func (keyboard *Keyboard) fail(err error) { + select { + case keyboard.failures <- err: + default: + } +} + +const callTimeout = 750 * time.Millisecond diff --git a/internal/platform/wayland/protocol.go b/internal/platform/wayland/protocol.go new file mode 100644 index 0000000..da8aa70 --- /dev/null +++ b/internal/platform/wayland/protocol.go @@ -0,0 +1,299 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package wayland + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/sessionbus" + "github.com/godbus/dbus/v5" +) + +const ( + managerName = "org.freedesktop.a11y.Manager" + managerPath = dbus.ObjectPath("/org/freedesktop/a11y/Manager") + monitorInterface = "org.freedesktop.a11y.KeyboardMonitor" +) + +// godbus's default handler can reorder signals after a channel fills. Keyboard +// events need a bounded FIFO: overflow terminates the backend and releases grabs. +type signalQueue struct { + keyboard *Keyboard + signals chan queuedSignal + overflow chan struct{} + once sync.Once +} + +type queuedSignal struct { + signal *dbus.Signal + generation uint64 +} + +func (queue *signalQueue) DeliverSignal(_ string, _ string, signal *dbus.Signal) { + if signal.Path != managerPath && signal.Name != "org.freedesktop.DBus.NameOwnerChanged" { + return + } + generation := queue.keyboard.secureGeneration.Load() + if signal.Name == monitorInterface+".KeyEvent" && queue.keyboard.secure.Load() { + return + } + select { + case queue.signals <- queuedSignal{signal: signal, generation: generation}: + default: + queue.once.Do(func() { close(queue.overflow) }) + } +} +func (*signalQueue) Terminate() {} + +type keyboardOwner struct { + keyboard *Keyboard + connection *dbus.Conn + owner string + configuration keyboardConfiguration + policy keyboardPolicy + bindings input.CommandBindings + router *input.CommandRouter + held map[uint16]uint32 + captured map[uint16]bool + learning bool + started time.Time + sequence uint32 + generation uint64 +} + +func (owner *keyboardOwner) call(ctx context.Context, method string, arguments ...any) error { + deadline, cancel := context.WithTimeout(ctx, callTimeout) + defer cancel() + return owner.connection.Object(owner.owner, managerPath).CallWithContext(deadline, monitorInterface+"."+method, 0, arguments...).Err +} + +func (owner *keyboardOwner) requested_policy() keyboardPolicy { + keyboard := owner.keyboard + if !keyboard.enabled.Load() || keyboard.secure.Load() { + owner.learning = false + keyboard.learn.Store(false) + } + return keyboardPolicy{enabled: keyboard.enabled.Load(), browse: keyboard.browse.Load(), button: keyboard.nativeButton.Load(), secure: keyboard.secure.Load(), learn: owner.learning} +} + +func (owner *keyboardOwner) retire_secure_generation() { + generation := owner.keyboard.secureGeneration.Load() + if generation == owner.generation { + return + } + // A complete lock/unlock can occur before the owner wakes. Retire held + // keys even when the final secure boolean is unchanged. + owner.generation = generation + owner.router.Reset() + clear(owner.held) + clear(owner.captured) + owner.learning = false + owner.keyboard.learn.Store(false) + owner.keyboard.active.Store(false) +} + +func (owner *keyboardOwner) configure(ctx context.Context, configuration keyboardConfiguration, policy keyboardPolicy) error { + symbols, grabs, bindings := make_grabs(configuration, policy) + if err := owner.call(ctx, "SetKeyGrabs", symbols, grabs); err != nil { + return err + } + if policy.learn != owner.policy.learn { + method := "UngrabKeyboard" + if policy.learn { + method = "GrabKeyboard" + } + if err := owner.call(ctx, method); err != nil { + return err + } + } + owner.configuration, owner.policy, owner.bindings = configuration, policy, bindings + owner.router = input.NewCommandRouter(symbols, bindings) + owner.keyboard.applied.Store(policy.enabled && !policy.secure) + owner.keyboard.browseApplied.Store(policy.browse && policy.enabled && !policy.secure) + owner.keyboard.learnEcho.Store(policy.learn) + return nil +} + +func (keyboard *Keyboard) run(ctx context.Context, configuration keyboardConfiguration, setup chan<- error) { + defer close(keyboard.done) + defer keyboard.applied.Store(false) + defer keyboard.browseApplied.Store(false) + defer keyboard.active.Store(false) + defer keyboard.learn.Store(false) + defer keyboard.learnEcho.Store(false) + queue := &signalQueue{keyboard: keyboard, signals: make(chan queuedSignal, 256), overflow: make(chan struct{})} + connection, err := sessionbus.Connect(keyboard.logger, "Wayland keyboard", dbus.WithSignalHandler(queue)) + if err != nil { + setup <- err + return + } + defer connection.Close() // Also releases grabs if setup only partly succeeded. + owner := &keyboardOwner{keyboard: keyboard, connection: connection, configuration: configuration, + held: make(map[uint16]uint32), captured: make(map[uint16]bool), started: time.Now()} + deadline, cancel := context.WithTimeout(ctx, callTimeout) + err = connection.BusObject().CallWithContext(deadline, "org.freedesktop.DBus.GetNameOwner", 0, managerName).Store(&owner.owner) + cancel() + if err != nil { + setup <- fmt.Errorf("shared accessibility keyboard interface unavailable: %w", err) + return + } + if err := connection.AddMatchSignal(dbus.WithMatchSender("org.freedesktop.DBus"), dbus.WithMatchInterface("org.freedesktop.DBus"), dbus.WithMatchMember("NameOwnerChanged"), dbus.WithMatchArg(0, managerName)); err != nil { + setup <- err + return + } + if err := connection.AddMatchSignal(dbus.WithMatchSender(owner.owner), dbus.WithMatchObjectPath(managerPath), dbus.WithMatchInterface(monitorInterface), dbus.WithMatchMember("KeyEvent")); err != nil { + setup <- err + return + } + // Some implementations authorize watches through the client's well-known + // accessibility name. Use a Cthulhu identity, never claim another reader's. + if result, err := connection.RequestName("org.stormux.Cthulhu.KeyboardMonitor", dbus.NameFlagDoNotQueue); err != nil || result != dbus.RequestNameReplyPrimaryOwner { + if err == nil { + err = errors.New("Cthulhu keyboard name is already owned") + } + setup <- err + return + } + policy := owner.requested_policy() + if !policy.secure { + if err := owner.call(ctx, "WatchKeyboard"); err != nil { + setup <- err + return + } + } + if err := owner.configure(ctx, configuration, policy); err != nil { + setup <- err + return + } + keyboard.logger.Info("using shared Wayland accessibility keyboard interface") + setup <- nil + if err := owner.loop(ctx, queue); err != nil && ctx.Err() == nil { + keyboard.fail(err) + } +} + +func (owner *keyboardOwner) loop(ctx context.Context, queue *signalQueue) error { + keyboard := owner.keyboard + var pending *keyboardUpdate + defer func() { + if pending != nil { + pending.result <- errors.New("Wayland keyboard stopped") + } + }() + timer := time.NewTicker(20 * time.Millisecond) + defer timer.Stop() + var drainUntil time.Time + for { + stopping := ctx.Err() != nil + if stopping { + if len(owner.captured) == 0 { + return nil + } + if drainUntil.IsZero() { + drainUntil = time.Now().Add(callTimeout) + } + if time.Now().After(drainUntil) { + return nil + } + } + owner.retire_secure_generation() + policy := owner.requested_policy() + if policy.secure != owner.policy.secure { + owner.learning, policy.learn = false, false + keyboard.learn.Store(false) + clear(owner.held) + clear(owner.captured) + keyboard.active.Store(false) + method := "WatchKeyboard" + if policy.secure { + method = "UnwatchKeyboard" + } + if err := owner.call(ctx, method); err != nil { + return err + } + } + if !stopping && len(owner.held) == 0 { + if pending != nil { + update := pending + pending = nil + err := update.ctx.Err() + if err == nil { + err = owner.configure(update.ctx, update.configuration, policy) + } + if err != nil { + // SetKeyGrabs may have reached the compositor before a timeout. + // Restore the complete previous configuration before reporting failure. + if rollback := owner.configure(ctx, owner.configuration, policy); rollback != nil { + update.result <- errors.Join(err, rollback) + return rollback + } + } else { + keyboard.mutex.Lock() + keyboard.configuration = update.configuration + keyboard.mutex.Unlock() + } + update.result <- err + } else if policy != owner.policy { + if err := owner.configure(ctx, owner.configuration, policy); err != nil { + return err + } + } + } + updates := keyboard.updates + if pending != nil || stopping { + updates = nil + } + var canceled <-chan struct{} + if pending != nil { + canceled = pending.ctx.Done() + } + select { + case <-timer.C: + case <-keyboard.wake: + case <-canceled: + pending.result <- pending.ctx.Err() + pending = nil + case update := <-updates: + pending = &update + case <-queue.overflow: + return errors.New("Wayland keyboard signal queue overflow") + case <-owner.connection.Context().Done(): + return errors.New("Wayland keyboard connection closed") + case queued := <-queue.signals: + signal := queued.signal + if signal.Name == "org.freedesktop.DBus.NameOwnerChanged" && signal.Sender == "org.freedesktop.DBus" { + var name, previous, next string + if dbus.Store(signal.Body, &name, &previous, &next) == nil && name == managerName && previous == owner.owner && next != owner.owner { + return errors.New("Wayland accessibility keyboard service disappeared; restart Cthulhu after the service returns") + } + continue + } + if signal.Sender != owner.owner || signal.Path != managerPath || signal.Name != monitorInterface+".KeyEvent" { + continue + } + if queued.generation != keyboard.secureGeneration.Load() { + continue + } + var key keyEvent + if err := dbus.Store(signal.Body, &key.released, &key.state, &key.symbol, &key.character, &key.code); err != nil { + return fmt.Errorf("invalid accessibility key event: %w", err) + } + if stopping { + if key.released { + delete(owner.captured, key.code) + } + continue + } + if err := owner.handle_key(key); err != nil { + return err + } + } + } +} diff --git a/internal/platform/wayland/protocol_test.go b/internal/platform/wayland/protocol_test.go new file mode 100644 index 0000000..53e7253 --- /dev/null +++ b/internal/platform/wayland/protocol_test.go @@ -0,0 +1,408 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package wayland + +import ( + "context" + "errors" + "os" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" + "github.com/godbus/dbus/v5" +) + +type MonitorSnapshot struct { + modifiers []uint32 + grabs []keyGrab + watching, grabbed bool + client string +} + +// FakeKeyboardMonitor verifies the real D-Bus wire contract without pretending +// to prove physical key suppression by a compositor. +type FakeKeyboardMonitor struct { + connection *dbus.Conn + mutex sync.Mutex + state MonitorSnapshot + changes chan MonitorSnapshot + rejectNext bool + rejectWatch bool +} + +func (monitor *FakeKeyboardMonitor) publish() { + copy := monitor.state + copy.modifiers = append([]uint32(nil), copy.modifiers...) + copy.grabs = append([]keyGrab(nil), copy.grabs...) + monitor.changes <- copy +} + +func (monitor *FakeKeyboardMonitor) WatchKeyboard(sender dbus.Sender) *dbus.Error { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + if monitor.rejectWatch { + return dbus.NewError("org.freedesktop.DBus.Error.AccessDenied", []any{"watch denied"}) + } + monitor.state.client, monitor.state.watching = string(sender), true + monitor.publish() + return nil +} +func (monitor *FakeKeyboardMonitor) UnwatchKeyboard() *dbus.Error { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + monitor.state.watching = false + monitor.publish() + return nil +} +func (monitor *FakeKeyboardMonitor) GrabKeyboard() *dbus.Error { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + monitor.state.grabbed = true + monitor.publish() + return nil +} +func (monitor *FakeKeyboardMonitor) UngrabKeyboard() *dbus.Error { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + monitor.state.grabbed = false + monitor.publish() + return nil +} +func (monitor *FakeKeyboardMonitor) SetKeyGrabs(modifiers []uint32, grabs []keyGrab) *dbus.Error { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + if monitor.rejectNext { + monitor.rejectNext = false + return dbus.NewError("org.freedesktop.DBus.Error.Failed", []any{"grab update denied"}) + } + monitor.state.modifiers, monitor.state.grabs = modifiers, grabs + monitor.publish() + return nil +} + +func start_monitor(t *testing.T) *FakeKeyboardMonitor { + t.Helper() + if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" { + t.Skip("requires CTHULHU_NATIVE_DBUS_TEST=1 and a private dbus-run-session") + } + if os.Getenv("DBUS_SESSION_BUS_ADDRESS") == "" { + t.Fatal("missing private session bus") + } + connection, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { connection.Close() }) + monitor := &FakeKeyboardMonitor{connection: connection, changes: make(chan MonitorSnapshot, 128)} + if err := connection.Export(monitor, managerPath, monitorInterface); err != nil { + t.Fatal(err) + } + if result, err := connection.RequestName(managerName, dbus.NameFlagDoNotQueue); err != nil || result != dbus.RequestNameReplyPrimaryOwner { + t.Fatalf("manager name: %v %v", result, err) + } + return monitor +} + +func start_keyboard(t *testing.T, monitor *FakeKeyboardMonitor) *Keyboard { + t.Helper() + keyboard := New([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout, nil) + if err := keyboard.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := keyboard.Stop(ctx); err != nil { + t.Error(err) + } + }) + wait_snapshot(t, monitor, func(state MonitorSnapshot) bool { return len(state.modifiers) == 3 }) + return keyboard +} + +func wait_snapshot(t *testing.T, monitor *FakeKeyboardMonitor, check func(MonitorSnapshot) bool) MonitorSnapshot { + t.Helper() + for { + select { + case state := <-monitor.changes: + if check(state) { + return state + } + case <-time.After(3 * time.Second): + t.Fatal("keyboard protocol update timed out") + } + } +} + +func emit_key(t *testing.T, connection *dbus.Conn, client string, symbol uint32, code uint16, state uint32, released bool) { + t.Helper() + message := &dbus.Message{Type: dbus.TypeSignal, Headers: map[dbus.HeaderField]dbus.Variant{ + dbus.FieldDestination: dbus.MakeVariant(client), dbus.FieldPath: dbus.MakeVariant(managerPath), + dbus.FieldInterface: dbus.MakeVariant(monitorInterface), dbus.FieldMember: dbus.MakeVariant("KeyEvent"), + dbus.FieldSignature: dbus.MakeVariant(dbus.SignatureOf(released, state, symbol, uint32(0), code)), + }, Body: []any{released, state, symbol, uint32(0), code}} + if call := connection.Send(message, make(chan *dbus.Call, 1)); call.Err != nil { + t.Fatal(call.Err) + } +} + +func (monitor *FakeKeyboardMonitor) key(t *testing.T, symbol uint32, code uint16, state uint32, released bool) { + monitor.mutex.Lock() + client := monitor.state.client + monitor.mutex.Unlock() + emit_key(t, monitor.connection, client, symbol, code, state, released) +} + +func await_command(t *testing.T, keyboard *Keyboard, command input.Command) input.CommandEvent { + t.Helper() + select { + case event := <-keyboard.commands: + if event.Command != command { + t.Fatalf("command = %q, want %q", event.Command, command) + } + return event + case <-time.After(3 * time.Second): + t.Fatalf("command %q timed out", command) + } + return input.CommandEvent{} +} + +func await_input(t *testing.T, keyboard *Keyboard, name string) input.Event { + t.Helper() + select { + case event := <-keyboard.events: + if event.Name != name { + t.Fatalf("input = %q, want %q", event.Name, name) + } + return event + case <-time.After(3 * time.Second): + t.Fatalf("input %q timed out", name) + } + return input.Event{} +} + +func TestNativeKeyboardProtocolCommandsMonitoringAndCleanup(t *testing.T) { + monitor := start_monitor(t) + keyboard := start_keyboard(t, monitor) + monitor.key(t, 'x', 53, 0, false) + monitor.key(t, 'x', 53, 0, true) + press := await_input(t, keyboard, "x") + release := await_input(t, keyboard, "x") + if !press.Pressed || release.Pressed || release.Timestamp <= press.Timestamp { + t.Fatal("input transition order lost") + } + for _, modifierFirst := range []bool{false, true} { + monitor.key(t, 0xff63, 118, 0, false) + monitor.key(t, 's', 39, 0, false) + monitor.key(t, 's', 39, 0, false) + await_command(t, keyboard, input.CycleSpeechMode) + if modifierFirst { + monitor.key(t, 0xff63, 118, 0, true) + } + monitor.key(t, 's', 39, 0, true) + if !modifierFirst { + monitor.key(t, 0xff63, 118, 0, true) + } + monitor.key(t, 'x', 53, 0, false) + monitor.key(t, 'x', 53, 0, true) + await_input(t, keyboard, "x") + await_input(t, keyboard, "x") + if len(keyboard.commands) != 0 || keyboard.CommandGrabActive() { + t.Fatal("repeat command or sticky reader modifier") + } + } + monitor.mutex.Lock() + client := monitor.state.client + monitor.mutex.Unlock() + if err := keyboard.Stop(context.Background()); err != nil { + t.Fatal(err) + } + var exists bool + if err := monitor.connection.BusObject().Call("org.freedesktop.DBus.NameHasOwner", 0, client).Store(&exists); err != nil || exists { + t.Fatalf("keyboard connection retained after Stop: %v %v", exists, err) + } +} + +func TestNativeKeyboardBrowseSecureAndLearnTransitions(t *testing.T) { + monitor := start_monitor(t) + keyboard := start_keyboard(t, monitor) + keyboard.SetBrowseNavigation(true) + wait_snapshot(t, monitor, func(state MonitorSnapshot) bool { + for _, grab := range state.grabs { + if grab.Symbol == 'h' { + return true + } + } + return false + }) + monitor.key(t, 'h', 43, 0, false) + monitor.key(t, 'h', 43, 0, true) + await_command(t, keyboard, input.DocumentNextHeading) + keyboard.SetNativeButtonFocus(true) + wait_snapshot(t, monitor, func(state MonitorSnapshot) bool { + for _, grab := range state.grabs { + if grab.Symbol == 0xff0d { + return false + } + } + return true + }) + keyboard.SetSecureInputActive(true) + wait_snapshot(t, monitor, func(state MonitorSnapshot) bool { + return !state.watching && len(state.modifiers) == 0 && len(state.grabs) == 0 + }) + keyboard.SetSecureInputActive(false) + wait_snapshot(t, monitor, func(state MonitorSnapshot) bool { return state.watching && len(state.modifiers) == 3 }) + monitor.key(t, 0xff63, 118, 0, false) + monitor.key(t, 'h', 43, 0, false) + if !await_command(t, keyboard, input.ToggleLearnMode).LearnModeStarted { + t.Fatal("learn did not begin") + } + monitor.key(t, 'h', 43, 0, true) + monitor.key(t, 0xff63, 118, 0, true) + wait_snapshot(t, monitor, func(state MonitorSnapshot) bool { return state.grabbed }) + monitor.key(t, 'q', 24, 0, false) + monitor.key(t, 'q', 24, 0, true) + await_command(t, keyboard, input.LearnKey) + monitor.key(t, 0xff1b, 9, 0, false) + monitor.key(t, 0xff1b, 9, 0, true) + if await_command(t, keyboard, input.ToggleLearnMode).LearnModeStarted { + t.Fatal("Escape entered learn mode") + } + wait_snapshot(t, monitor, func(state MonitorSnapshot) bool { return !state.grabbed }) + keyboard.SetCommandGrabs(false) + wait_snapshot(t, monitor, func(state MonitorSnapshot) bool { + return len(state.modifiers) == 0 && len(state.grabs) == 0 && !state.grabbed + }) + monitor.key(t, 'q', 24, 0, false) + monitor.key(t, 'q', 24, 0, true) + await_input(t, keyboard, "q") + await_input(t, keyboard, "q") +} + +func TestNativeKeyboardBindingUpdateRollbackAndHeldCancellation(t *testing.T) { + monitor := start_monitor(t) + keyboard := start_keyboard(t, monitor) + monitor.key(t, 0xff63, 118, 0, false) + monitor.key(t, 's', 39, 0, false) + await_command(t, keyboard, input.CycleSpeechMode) + ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond) + defer cancel() + if err := keyboard.SetKeyboardConfiguration(ctx, input.LaptopKeyboardLayout, []string{"Caps_Lock"}, nil); !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("held update = %v", err) + } + monitor.key(t, 's', 39, 0, true) + monitor.key(t, 0xff63, 118, 0, true) + monitor.mutex.Lock() + monitor.rejectNext = true + monitor.mutex.Unlock() + if err := keyboard.SetKeyboardConfiguration(context.Background(), input.LaptopKeyboardLayout, []string{"Caps_Lock"}, nil); err == nil { + t.Fatal("rejected update accepted") + } + monitor.key(t, 0xff63, 118, 0, false) + monitor.key(t, ' ', 65, 0, false) + await_command(t, keyboard, input.Preferences) + monitor.key(t, ' ', 65, 0, true) + monitor.key(t, 0xff63, 118, 0, true) + bindings := []input.BindingOverride{{Layout: input.LaptopKeyboardLayout, Scope: "global", Command: input.Preferences, Keys: []string{"Cthulhu+p"}}} + if err := keyboard.SetKeyboardConfiguration(context.Background(), input.LaptopKeyboardLayout, []string{"Caps_Lock"}, bindings); err != nil { + t.Fatal(err) + } + monitor.key(t, 0xffe5, 66, 0, false) + monitor.key(t, 'p', 33, 0, false) + await_command(t, keyboard, input.Preferences) + monitor.key(t, 'p', 33, 0, true) + monitor.key(t, 0xffe5, 66, 0, true) +} + +func TestNativeKeyboardRejectsSpoofedSignalsAndServiceLoss(t *testing.T) { + monitor := start_monitor(t) + keyboard := start_keyboard(t, monitor) + impostor, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + defer impostor.Close() + monitor.mutex.Lock() + client := monitor.state.client + monitor.mutex.Unlock() + emit_key(t, impostor, client, 0xff63, 118, 0, false) + if err := impostor.BusObject().Call("org.freedesktop.DBus.GetId", 0).Err; err != nil { + t.Fatal(err) + } + monitor.key(t, 's', 39, 0, false) + monitor.key(t, 's', 39, 0, true) + await_input(t, keyboard, "s") + await_input(t, keyboard, "s") + if len(keyboard.commands) != 0 { + t.Fatal("untrusted signal created reader modifier") + } + monitor.connection.ReleaseName(managerName) + select { + case <-keyboard.failures: + case <-time.After(3 * time.Second): + t.Fatal("service loss not detected") + } + select { + case <-keyboard.done: + case <-time.After(3 * time.Second): + t.Fatal("service loss did not close keyboard connection") + } +} + +func TestNativeKeyboardDeniedWatchCleansUp(t *testing.T) { + monitor := start_monitor(t) + monitor.mutex.Lock() + monitor.rejectWatch = true + monitor.mutex.Unlock() + keyboard := New([]string{"Insert"}, input.DesktopKeyboardLayout, nil) + if err := keyboard.Start(context.Background()); err == nil { + t.Fatal("denied watch accepted") + } + if err := keyboard.Stop(context.Background()); err != nil { + t.Fatal(err) + } + var exists bool + if err := monitor.connection.BusObject().Call("org.freedesktop.DBus.NameHasOwner", 0, "org.stormux.Cthulhu.KeyboardMonitor").Store(&exists); err != nil || exists { + t.Fatal("partial startup retained keyboard identity") + } +} + +func TestNativeKeyboardRapidSecureCycleRetiresHeldModifier(t *testing.T) { + monitor := start_monitor(t) + keyboard := start_keyboard(t, monitor) + monitor.key(t, 0xff63, 118, 0, false) + monitor.key(t, 't', 28, 0, false) + await_command(t, keyboard, input.PresentTime) + keyboard.SetSecureInputActive(true) + keyboard.SetSecureInputActive(false) + // The old physical releases may have been discarded while secure. Plain Q + // must reach monitoring rather than becoming a stale Cthulhu+Q command. + monitor.key(t, 'q', 24, 0, false) + monitor.key(t, 'q', 24, 0, true) + await_input(t, keyboard, "q") + await_input(t, keyboard, "q") + if len(keyboard.commands) != 0 || keyboard.CommandGrabActive() { + t.Fatal("secure cycle retained reader chord") + } +} + +func TestNativeKeyboardStartsSecureWithoutMonitoringOrGrabs(t *testing.T) { + monitor := start_monitor(t) + keyboard := New([]string{"Insert"}, input.DesktopKeyboardLayout, nil) + keyboard.SetSecureInputActive(true) + if err := keyboard.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer keyboard.Stop(context.Background()) + state := wait_snapshot(t, monitor, func(MonitorSnapshot) bool { return true }) + if state.watching || state.grabbed || len(state.modifiers) != 0 || len(state.grabs) != 0 { + t.Fatal("secure startup acquired keyboard access") + } + keyboard.SetSecureInputActive(false) + wait_snapshot(t, monitor, func(state MonitorSnapshot) bool { return state.watching && len(state.modifiers) == 1 }) +} diff --git a/internal/platform/wayland/routing.go b/internal/platform/wayland/routing.go new file mode 100644 index 0000000..101488c --- /dev/null +++ b/internal/platform/wayland/routing.go @@ -0,0 +1,195 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package wayland + +/* +#cgo pkg-config: xkbcommon +#include +*/ +import "C" + +import ( + "errors" + "fmt" + "sort" + "time" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +type keyGrab struct{ Symbol, Modifiers uint32 } +type keyboardPolicy struct{ enabled, browse, button, secure, learn bool } + +func modifier_symbols(names []string) ([]uint32, error) { + var symbols []uint32 + for _, name := range names { + switch name { + case "Insert": + symbols = append(symbols, 0xff63) + case "KP_Insert": + symbols = append(symbols, 0xff9e, 0xffb0) // NumLock alias. + case "Caps_Lock": + symbols = append(symbols, 0xffe5) + default: + return nil, fmt.Errorf("command modifier %q is unsupported; use Insert, KP_Insert, or Caps_Lock", name) + } + } + return symbols, nil +} + +func key_name(symbol uint32) string { + var buffer [128]C.char + length := C.xkb_keysym_get_name(C.xkb_keysym_t(symbol), &buffer[0], C.size_t(len(buffer))) + if length <= 0 || int(length) >= len(buffer) { + return "" + } + return C.GoString((*C.char)(unsafe.Pointer(&buffer[0]))) +} + +func lower_symbol(symbol uint32) uint32 { return uint32(C.xkb_keysym_to_lower(C.xkb_keysym_t(symbol))) } + +// KeyboardMonitor sends keysyms rather than a keymap. Letter case is defined +// by XKB; punctuation's physical Shift pairing cannot be inferred from it. +func shifted_symbol(symbol uint32) uint32 { + return uint32(C.xkb_keysym_to_upper(C.xkb_keysym_t(symbol))) +} + +func normalize_symbol(symbol uint32) uint32 { + symbol = lower_symbol(symbol) + if symbol == 0xfe20 { + return 0xff09 + } // ISO_Left_Tab. + return symbol +} + +func make_grabs(configuration keyboardConfiguration, policy keyboardPolicy) ([]uint32, []keyGrab, input.CommandBindings) { + bindings, _ := input.ResolveCommandBindings(configuration.layout, policy.browse, configuration.bindings) + if policy.button { + for chord, command := range bindings { + if command == input.DocumentActivate && !chord.CthulhuModifier { + delete(bindings, chord) + } + } + } + if !policy.enabled || policy.secure { + return []uint32{}, []keyGrab{}, bindings + } + symbols, _ := modifier_symbols(configuration.modifiers) + unique := make(map[keyGrab]bool) + for chord := range bindings { + if chord.CthulhuModifier { + continue + } + for _, locks := range []uint32{0, 2, 16, 18} { + mask := uint32(chord.Modifiers) | locks + unique[keyGrab{chord.Symbol, mask}] = true + // Implementations differ in whether a shifted/capitalized keysym is + // emitted; both forms resolve to the same semantic command. + if mask&3 != 0 { + unique[keyGrab{shifted_symbol(chord.Symbol), mask}] = true + } + } + } + grabs := make([]keyGrab, 0, len(unique)) + for grab := range unique { + grabs = append(grabs, grab) + } + sort.Slice(grabs, func(i, j int) bool { + if grabs[i].Symbol == grabs[j].Symbol { + return grabs[i].Modifiers < grabs[j].Modifiers + } + return grabs[i].Symbol < grabs[j].Symbol + }) + return symbols, grabs, bindings +} + +type keyEvent struct { + released bool + state, symbol, character uint32 + code uint16 +} + +func (owner *keyboardOwner) handle_key(key keyEvent) error { + keyboard := owner.keyboard + keyboard.secureMutex.Lock() + defer keyboard.secureMutex.Unlock() + if keyboard.secure.Load() || owner.policy.secure { + return nil + } + // A fresh signal can win the select before the policy wakeup. Reset at + // delivery as well so it cannot inherit a modifier from before locking. + owner.retire_secure_generation() + owner.sequence = max(owner.sequence+1, uint32(time.Since(owner.started).Milliseconds())+1) + timestamp := owner.sequence // One local clock shared by monitoring and commands. + symbol := normalize_symbol(key.symbol) + if key.symbol == 0xffb0 && owner.router.IsModifier(0xff9e) { + symbol = 0xff9e + } + previous, repeated := owner.held[key.code] + if previous != 0 { + symbol = previous + } // Releases may arrive after Shift/locks change. + if key.released { + delete(owner.held, key.code) + } else { + owner.held[key.code] = symbol + } + chord := owner.router.Chord(symbol, uint16(key.state)) + consumed, command := false, input.Command("") + if owner.policy.enabled && (key.released || key.state <= 0xffff) { + consumed, command = owner.router.Handle(symbol, key.code, uint16(key.state), !key.released) + } + if key.released { + delete(owner.captured, key.code) + } else if consumed || owner.learning { + owner.captured[key.code] = true + } + keyboard.active.Store(len(owner.captured) != 0 || owner.learning) + if !key.released && !repeated && owner.learning { + command = input.LearnKey + switch { + case symbol == 0xff1b || owner.bindings[chord] == input.ToggleLearnMode: + command = input.ToggleLearnMode + case symbol == 0xffbe && chord.Modifiers == 0 && !chord.CthulhuModifier: + command = input.LearnDocumentation + case symbol == 0xffbf && chord.Modifiers == 0 && !chord.CthulhuModifier: + command = input.LearnDefaultShortcuts + case symbol == 0xffc0 && chord.Modifiers == 0 && !chord.CthulhuModifier: + command = input.LearnApplicationShortcuts + } + if command != input.LearnKey { + owner.learning = false + keyboard.learn.Store(false) + } + } else if command == input.ToggleLearnMode { + owner.learning = true + keyboard.learn.Store(true) + keyboard.learnEcho.Store(true) + } + if command != "" && !repeated { + event := input.CommandEvent{Command: command, Timestamp: timestamp, Chord: chord, KeyName: key_name(symbol), LearnModeStarted: command == input.ToggleLearnMode && owner.learning} + select { + case keyboard.commands <- event: + default: + return errors.New("Wayland command queue overflow") + } + } + // Command presses must not race their own speech through the independent + // monitoring worker. Modifier observation still tracks normal input intent. + if !consumed && !owner.policy.learn && command == "" && key.code <= 255 { + event := input.NewKeyEvent(uint8(key.code), !key.released, key_name(key.symbol)) + event.Timestamp, event.Repeat = timestamp, !key.released && repeated + keyboard.intent.Observe(event) + select { + case keyboard.events <- event: + default: + keyboard.overflow.Add(1) + } + } else if !consumed && key.code > 255 { + keyboard.overflow.Add(1) + } + return nil +} diff --git a/internal/platform/wayland/routing_test.go b/internal/platform/wayland/routing_test.go new file mode 100644 index 0000000..b4a1728 --- /dev/null +++ b/internal/platform/wayland/routing_test.go @@ -0,0 +1,214 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package wayland + +import ( + "context" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" + "github.com/godbus/dbus/v5" +) + +func test_owner(t *testing.T, layout input.KeyboardLayout, modifiers ...string) *keyboardOwner { + t.Helper() + keyboard := New(modifiers, layout, nil) + policy := keyboardPolicy{enabled: true} + symbols, _, bindings := make_grabs(keyboard.configuration, policy) + return &keyboardOwner{keyboard: keyboard, configuration: keyboard.configuration, policy: policy, + bindings: bindings, router: input.NewCommandRouter(symbols, bindings), held: make(map[uint16]uint32), captured: make(map[uint16]bool), started: time.Now()} +} + +func send_key(t *testing.T, owner *keyboardOwner, symbol uint32, code uint16, state uint32, released bool) { + t.Helper() + if err := owner.handle_key(keyEvent{symbol: symbol, code: code, state: state, released: released}); err != nil { + t.Fatal(err) + } +} + +func next_command(t *testing.T, keyboard *Keyboard, command input.Command) input.CommandEvent { + t.Helper() + select { + case event := <-keyboard.commands: + if event.Command != command { + t.Fatalf("command = %q, want %q", event.Command, command) + } + return event + default: + t.Fatalf("missing command %q", command) + } + return input.CommandEvent{} +} + +func TestReaderChordsDispatchOnceAndReleaseBothOrders(t *testing.T) { + for _, modifier := range []struct { + name string + symbol uint32 + }{{"Insert", 0xff63}, {"KP_Insert", 0xff9e}, {"KP_Insert", 0xffb0}, {"Caps_Lock", 0xffe5}} { + for _, modifierFirst := range []bool{false, true} { + owner := test_owner(t, input.DesktopKeyboardLayout, modifier.name) + send_key(t, owner, modifier.symbol, 118, 0, false) + send_key(t, owner, 's', 39, 0, false) + send_key(t, owner, 's', 39, 0, false) + event := next_command(t, owner.keyboard, input.CycleSpeechMode) + if !event.Chord.CthulhuModifier || event.Timestamp == 0 { + t.Fatal("missing chord identity") + } + if modifierFirst { + send_key(t, owner, modifier.symbol, 118, 0, true) + } + send_key(t, owner, 's', 39, 0, true) + if !modifierFirst { + send_key(t, owner, modifier.symbol, 118, 0, true) + } + if owner.keyboard.active.Load() || len(owner.held) != 0 || len(owner.keyboard.commands) != 0 { + t.Fatal("repeat or held state survived release") + } + send_key(t, owner, 's', 39, 0, false) + if len(owner.keyboard.commands) != 0 { + t.Fatal("plain typing became a command") + } + } + } +} + +func TestTypingIntentModifiersRepeatsAndHighKeycodes(t *testing.T) { + owner := test_owner(t, input.DesktopKeyboardLayout, "Insert") + send_key(t, owner, 0xffe3, 37, 0, false) + send_key(t, owner, 0xff53, 114, 4, false) + if owner.keyboard.intent.RecentIntent() != input.WordIntent { + t.Fatal("Control+Right lost editing intent") + } + send_key(t, owner, 0xff53, 114, 4, false) + for index := 0; index < 3; index++ { + event := <-owner.keyboard.events + if event.Repeat != (index == 2) { + t.Fatalf("repeat for event %d = %v", index, event.Repeat) + } + } + if len(owner.keyboard.commands) != 0 { + t.Fatal("typing was routed as a command") + } + send_key(t, owner, 'x', 293, 0, false) // Must never alias physical Control at 37. + if len(owner.keyboard.events) != 0 || owner.keyboard.overflow.Load() != 1 { + t.Fatal("wide keycode was truncated") + } +} + +func TestBrowseCaseLocksAndFocusedButton(t *testing.T) { + configuration := keyboardConfiguration{layout: input.DesktopKeyboardLayout, modifiers: []string{"Insert"}} + for _, mask := range []uint32{0, 2, 16, 18} { + policy := keyboardPolicy{enabled: true, browse: true} + symbols, grabs, bindings := make_grabs(configuration, policy) + owner := test_owner(t, configuration.layout, "Insert") + owner.bindings, owner.policy, owner.router = bindings, policy, input.NewCommandRouter(symbols, bindings) + send_key(t, owner, 'H', 43, mask|1, false) + next_command(t, owner.keyboard, input.DocumentPreviousHeading) + send_key(t, owner, 'h', 43, mask, true) + if len(owner.held) != 0 { + t.Fatal("changed release symbol left a key held") + } + found := false + for _, grab := range grabs { + if grab == (keyGrab{'H', mask | 1}) { + found = true + } + } + if !found { + t.Fatal("shifted heading grab missing") + } + } + _, grabs, bindings := make_grabs(configuration, keyboardPolicy{enabled: true, browse: true, button: true}) + if bindings[input.CommandChord{Symbol: 0xff0d}] != "" { + t.Fatal("native Return still activates document") + } + for _, grab := range grabs { + if grab.Symbol == 0xff0d { + t.Fatal("native button Return remains grabbed") + } + } + modifiers, grabs, _ := make_grabs(configuration, keyboardPolicy{secure: true, enabled: true, browse: true}) + if len(modifiers) != 0 || len(grabs) != 0 { + t.Fatal("secure input retains grabs") + } +} + +func TestLearnModeAndSecureReset(t *testing.T) { + owner := test_owner(t, input.LaptopKeyboardLayout, "Insert") + send_key(t, owner, 0xff63, 118, 0, false) + send_key(t, owner, 'h', 43, 0, false) + if !next_command(t, owner.keyboard, input.ToggleLearnMode).LearnModeStarted { + t.Fatal("learn mode did not begin") + } + send_key(t, owner, 'h', 43, 0, true) + send_key(t, owner, 0xff63, 118, 0, true) + owner.policy.learn = true // The protocol owner installs its full grab after release. + send_key(t, owner, 'q', 24, 0, false) + next_command(t, owner.keyboard, input.LearnKey) + send_key(t, owner, 'q', 24, 0, true) + send_key(t, owner, 0xff1b, 9, 0, false) + if next_command(t, owner.keyboard, input.ToggleLearnMode).LearnModeStarted { + t.Fatal("Escape restarted learn mode") + } + if owner.learning { + t.Fatal("Escape left learn mode active") + } + owner.keyboard.SetSecureInputActive(true) + send_key(t, owner, 'p', 33, 0, false) + if len(owner.keyboard.events) != 0 || len(owner.keyboard.commands) != 0 { + t.Fatal("secure input leaked output") + } +} + +func TestSignalQueueBoundedOrderedAndSecureGeneration(t *testing.T) { + keyboard := New([]string{"Insert"}, input.DesktopKeyboardLayout, nil) + queue := &signalQueue{keyboard: keyboard, signals: make(chan queuedSignal, 2), overflow: make(chan struct{})} + for index := 0; index < 3; index++ { + queue.DeliverSignal("", "", &dbus.Signal{Path: managerPath, Name: monitorInterface + ".KeyEvent", Body: []any{uint32(index)}}) + } + select { + case <-queue.overflow: + default: + t.Fatal("overflow did not fail closed") + } + for index := 0; index < 2; index++ { + if (<-queue.signals).signal.Body[0] != uint32(index) { + t.Fatal("signal order changed") + } + } + keyboard.SetSecureInputActive(true) + queue.DeliverSignal("", "", &dbus.Signal{Path: managerPath, Name: monitorInterface + ".KeyEvent"}) + if len(queue.signals) != 0 { + t.Fatal("secure key queued") + } + keyboard.SetSecureInputActive(false) + queue.DeliverSignal("", "", &dbus.Signal{Path: managerPath, Name: monitorInterface + ".KeyEvent"}) + if (<-queue.signals).generation != 2 { + t.Fatal("secure generation not advanced") + } +} + +func TestKeyboardConfigurationValidation(t *testing.T) { + keyboard := New([]string{"Insert"}, input.DesktopKeyboardLayout, nil) + if err := keyboard.SetKeyboardConfiguration(context.Background(), input.LaptopKeyboardLayout, []string{"Caps_Lock"}, nil); err != nil { + t.Fatal(err) + } + if err := keyboard.SetKeyboardConfiguration(context.Background(), input.DesktopKeyboardLayout, []string{"Super_L"}, nil); err == nil { + t.Fatal("unsupported modifier accepted") + } + if keyboard.configuration.layout != input.LaptopKeyboardLayout { + t.Fatal("failed update changed configuration") + } +} + +func TestUnknownModifierBitsDoNotDispatchTruncatedChord(t *testing.T) { + owner := test_owner(t, input.DesktopKeyboardLayout, "Insert") + send_key(t, owner, 0xff63, 118, 0, false) + send_key(t, owner, 'q', 24, 1<<20, false) + if len(owner.keyboard.commands) != 0 { + t.Fatal("wide modifier mask became Cthulhu+Q") + } +} diff --git a/internal/platform/xorg/applications.go b/internal/platform/xorg/applications.go new file mode 100644 index 0000000..e8b481f --- /dev/null +++ b/internal/platform/xorg/applications.go @@ -0,0 +1,33 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +/* +#include "window_title.h" +*/ +import "C" + +import "unsafe" + +type ApplicationWindow struct { + Application string + PID int + Wine bool +} + +// ApplicationWindows runs on the native owner thread, like ReadTitle. +func (reader *ForegroundReader) ApplicationWindows() []ApplicationWindow { + if reader == nil { + return nil + } + var count C.int + native := C.cthulhu_list_application_windows(reader.display, &count) + defer C.cthulhu_free_application_windows(native, count) + var windows []ApplicationWindow + for _, window := range unsafe.Slice(native, int(count)) { + windows = append(windows, ApplicationWindow{C.GoString(window.application), int(window.pid), window.wine != 0}) + } + return windows +} diff --git a/internal/platform/xorg/clipboard.go b/internal/platform/xorg/clipboard.go new file mode 100644 index 0000000..b798656 --- /dev/null +++ b/internal/platform/xorg/clipboard.go @@ -0,0 +1,124 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +/* +#cgo pkg-config: x11 xfixes +#include +#include +#include + +static int watch_clipboard(Display *display, int *event_base) { + int error_base; + if (!XFixesQueryExtension(display, event_base, &error_base)) return 0; + Atom clipboard = XInternAtom(display, "CLIPBOARD", False); + XFixesSelectSelectionInput(display, DefaultRootWindow(display), clipboard, + XFixesSetSelectionOwnerNotifyMask); + XSync(display, False); + return 1; +} + +static int next_clipboard_change(Display *display, int event_base) { + while (XPending(display)) { + XEvent event; + XNextEvent(display, &event); + if (event.type == event_base + XFixesSelectionNotify) { + XFixesSelectionNotifyEvent *change = (XFixesSelectionNotifyEvent *)&event; + if (change->owner != None) return 1; + } + } + return 0; +} +*/ +import "C" + +import ( + "context" + "errors" + "runtime" + "sync" + "time" +) + +// ClipboardMonitor reports successful X11 clipboard ownership changes. It +// never reads clipboard contents or blocks the keyboard listener. +type ClipboardMonitor struct { + changes chan struct{} + cancel context.CancelFunc + done chan struct{} + mutex sync.Mutex +} + +func NewClipboardMonitor() *ClipboardMonitor { + return &ClipboardMonitor{changes: make(chan struct{}, 16)} +} + +func (monitor *ClipboardMonitor) Changes() <-chan struct{} { return monitor.changes } + +func (monitor *ClipboardMonitor) Start(ctx context.Context) error { + monitor.mutex.Lock() + defer monitor.mutex.Unlock() + if monitor.done != nil { + return errors.New("clipboard monitor already started") + } + ready := make(chan error, 1) + watchCtx, cancel := context.WithCancel(ctx) + done := make(chan struct{}) + go func() { + defer close(done) + runtime.LockOSThread() + defer runtime.UnlockOSThread() + display := C.XOpenDisplay(nil) + if display == nil { + ready <- errors.New("clipboard monitor: no X11 display") + return + } + defer C.XCloseDisplay(display) + var eventBase C.int + if C.watch_clipboard(display, &eventBase) == 0 { + ready <- errors.New("clipboard monitor: XFixes unavailable") + return + } + ready <- nil + ticker := time.NewTicker(20 * time.Millisecond) + defer ticker.Stop() + for { + select { + case <-watchCtx.Done(): + return + case <-ticker.C: + if C.next_clipboard_change(display, eventBase) != 0 { + select { + case monitor.changes <- struct{}{}: + default: + } + } + } + } + }() + if err := <-ready; err != nil { + cancel() + <-done + return err + } + monitor.cancel, monitor.done = cancel, done + return nil +} + +func (monitor *ClipboardMonitor) Stop(ctx context.Context) error { + monitor.mutex.Lock() + cancel, done := monitor.cancel, monitor.done + monitor.mutex.Unlock() + if done == nil { + return nil + } + cancel() + select { + case <-done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} diff --git a/internal/platform/xorg/clipboard_native_test.go b/internal/platform/xorg/clipboard_native_test.go new file mode 100644 index 0000000..87bb5ef --- /dev/null +++ b/internal/platform/xorg/clipboard_native_test.go @@ -0,0 +1,41 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeClipboardOwnerChange(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + monitor := NewClipboardMonitor() + if err := monitor.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + if err := monitor.Stop(context.Background()); err != nil { + t.Error(err) + } + }() + command := exec.CommandContext(ctx, "xclip", "-selection", "clipboard", "-i") + command.Stdin = strings.NewReader("same text") + if err := command.Run(); err != nil { + t.Fatal(err) + } + select { + case <-monitor.Changes(): + case <-ctx.Done(): + t.Fatal("clipboard owner change was not observed") + } +} diff --git a/internal/platform/xorg/commands.go b/internal/platform/xorg/commands.go new file mode 100644 index 0000000..7ead9f5 --- /dev/null +++ b/internal/platform/xorg/commands.go @@ -0,0 +1,114 @@ +package xorg + +import ( + "context" + "sync" + "sync/atomic" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +type CommandListener struct { + secureMutex sync.Mutex + secure atomic.Bool + ocrApplied atomic.Bool + ocrPending atomic.Bool + browse atomic.Bool + browseApplied atomic.Bool + nativeButtonFocus atomic.Bool + nativeButtonApplied atomic.Bool + grabActive atomic.Bool + commandsEnabled atomic.Bool + commandsApplied atomic.Bool + learnMode atomic.Bool + learnEcho atomic.Bool + uiSession atomic.Uint64 + uiSequence atomic.Uint64 + uiClose atomic.Uint64 + uiEcho atomic.Bool + uiUpdates chan uiUpdate + focusChanges chan FocusState + modifiers []string + layout input.KeyboardLayout + bindingOverrides []input.BindingOverride + tentacleBindings []input.BindingOverride + registrationMutex sync.RWMutex + appliedTentacles []input.BindingOverride + bindingUpdates chan bindingUpdate + // Bounded FIFO; overflow fails the listener rather than blocking key releases. + commands chan input.CommandEvent + lockStates chan input.LockState + failures chan error + done chan struct{} + cancel context.CancelFunc + mutex sync.Mutex +} + +type FocusState struct { + Known bool + XTerm bool +} + +func (listener *CommandListener) publishFocusState(state FocusState) { + select { + case listener.focusChanges <- state: + default: + select { + case <-listener.focusChanges: + default: + } + listener.focusChanges <- state + } +} + +func NewCommands(modifiers []string, layout input.KeyboardLayout) *CommandListener { + return &CommandListener{ + modifiers: append([]string(nil), modifiers...), + bindingUpdates: make(chan bindingUpdate), + uiUpdates: make(chan uiUpdate), + layout: layout, + commands: make(chan input.CommandEvent, 16), + lockStates: make(chan input.LockState, 16), + failures: make(chan error, 1), + focusChanges: make(chan FocusState, 1), + } +} + +// SetBrowseNavigation publishes policy; the X11 owner changes grabs between +// complete chords, preserving every key release during a mode transition. +func (listener *CommandListener) SetBrowseNavigation(enabled bool) { listener.browse.Store(enabled) } + +// SetNativeButtonFocus leaves Return to a standard button with real DOM focus. +// Virtual browse targets elsewhere still use Cthulhu's document activation. +func (listener *CommandListener) SetNativeButtonFocus(focused bool) { + listener.nativeButtonFocus.Store(focused) +} + +func (listener *CommandListener) SetCommandGrabs(enabled bool) { + listener.commandsEnabled.Store(enabled) +} + +// BrowseNavigationEnabled reports whether requested browse grabs have reached X11. +func (listener *CommandListener) BrowseNavigationEnabled() bool { + return !listener.ocrApplied.Load() && !listener.secure.Load() && listener.browse.Load() && listener.browseApplied.Load() && listener.commandsApplied.Load() +} + +func (listener *CommandListener) CommandGrabsEnabled() bool { + return (listener.commandsEnabled.Load() && !listener.secure.Load()) && listener.commandsApplied.Load() +} + +// CommandGrabActive reports whether the listener currently owns an explicit +// keyboard grab for a possible command chord. This becomes true on the first +// grabbed press, before the complete chord can be resolved and dispatched. +func (listener *CommandListener) CommandGrabActive() bool { return listener.grabActive.Load() } + +func (listener *CommandListener) LearnModeActive() bool { return listener.learnMode.Load() } +func (listener *CommandListener) LearnModeEchoActive() bool { return listener.learnEcho.Load() } + +func (listener *CommandListener) Commands() <-chan input.CommandEvent { return listener.commands } +func (listener *CommandListener) LockStates() <-chan input.LockState { return listener.lockStates } + +func (listener *CommandListener) Failures() <-chan error { return listener.failures } +func (listener *CommandListener) FocusChanges() <-chan FocusState { + return listener.focusChanges +} diff --git a/internal/platform/xorg/commands_bindings.go b/internal/platform/xorg/commands_bindings.go new file mode 100644 index 0000000..fe62ba2 --- /dev/null +++ b/internal/platform/xorg/commands_bindings.go @@ -0,0 +1,220 @@ +package xorg + +/* +#include "commands_native.h" +#include +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + "git.stormux.org/storm/cthulhu/internal/input" + "strings" +) + +type bindingUpdate struct { + tentacles []input.BindingOverride + replaceTentacles bool + ocrForeground uint64 + ocrReview *bool + ocrPending *bool + layout input.KeyboardLayout + modifiers []string + replaceKeyboard bool + ctx context.Context + overrides []input.BindingOverride + result chan error +} + +// SetKeyBindings validates and acknowledges a native update after the current +// chord releases. Before Start it sets the configuration used at startup. +func (listener *CommandListener) SetKeyBindings(ctx context.Context, overrides []input.BindingOverride) error { + return listener.update_keyboard(ctx, bindingUpdate{overrides: overrides}) +} + +// SetKeyboardConfiguration applies layout, modifier keys, and shortcuts together +// after held keys release. A failed native grab retains the whole old setup. +func (listener *CommandListener) SetKeyboardConfiguration(ctx context.Context, layout input.KeyboardLayout, modifiers []string, overrides []input.BindingOverride) error { + if layout != input.DesktopKeyboardLayout && layout != input.LaptopKeyboardLayout { + return fmt.Errorf("invalid keyboard layout %d", layout) + } + if _, err := command_modifier_symbols(modifiers); err != nil { + return err + } + return listener.update_keyboard(ctx, bindingUpdate{layout: layout, modifiers: append([]string(nil), modifiers...), overrides: overrides, replaceKeyboard: true}) +} + +func (listener *CommandListener) update_keyboard(ctx context.Context, update bindingUpdate) error { + if err := ctx.Err(); err != nil { + return err + } + if err := input.ValidateBindingOverrides(update.overrides); err != nil { + return err + } + update.overrides = input.CloneBindingOverrides(update.overrides) + listener.mutex.Lock() + if listener.done == nil { + if update.replaceTentacles { + listener.tentacleBindings = update.tentacles + } else { + listener.bindingOverrides = update.overrides + } + if update.replaceKeyboard { + listener.layout, listener.modifiers = update.layout, update.modifiers + } + listener.mutex.Unlock() + return nil + } + done := listener.done + listener.mutex.Unlock() + update.ctx, update.result = ctx, make(chan error, 1) + select { + case listener.bindingUpdates <- update: + case <-done: + return errors.New("command listener has stopped") + case <-ctx.Done(): + return ctx.Err() + } + select { + case err := <-update.result: + return err + case <-done: + return errors.New("command listener has stopped") + } +} + +// SetTentacleBindings replaces all runtime suggestions atomically after held +// keys release. Native failure restores the previous complete configuration. +func (listener *CommandListener) SetTentacleBindings(ctx context.Context, bindings []input.BindingOverride) error { + if err := input.ValidateTentacleBindings(bindings); err != nil { + return err + } + return listener.update_keyboard(ctx, bindingUpdate{replaceTentacles: true, tentacles: input.CloneBindingOverrides(bindings)}) +} + +func (listener *CommandListener) TentacleBindings() []input.BindingOverride { + listener.registrationMutex.RLock() + defer listener.registrationMutex.RUnlock() + return input.CloneBindingOverrides(listener.appliedTentacles) +} + +func (listener *CommandListener) publishTentacleBindings(merged []input.BindingOverride) { + listener.registrationMutex.Lock() + defer listener.registrationMutex.Unlock() + listener.appliedTentacles = nil + for _, binding := range merged { + if strings.HasPrefix(string(binding.Command), "tentacle/") { + listener.appliedTentacles = append(listener.appliedTentacles, input.CloneBindingOverrides([]input.BindingOverride{binding})[0]) + } + } +} + +func command_modifier_symbols(modifiers []string) ([]uint32, error) { + var symbols []uint32 + for _, name := range modifiers { + switch name { + case "Insert": + symbols = append(symbols, 0xff63) + case "KP_Insert": + symbols = append(symbols, 0xff9e) + case "Caps_Lock": + symbols = append(symbols, 0xffe5) + default: + return nil, fmt.Errorf("command modifier %q is unsupported; use Insert, KP_Insert, or Caps_Lock", name) + } + } + return symbols, nil +} + +func resolvedBindings(layout input.KeyboardLayout, browse bool, overrides []input.BindingOverride) input.CommandBindings { + bindings, _ := input.ResolveCommandBindings(layout, browse, overrides) + return bindings +} + +func configureNativeBindings(device *C.CommandDevice, layout input.KeyboardLayout, modifiers []string, overrides []input.BindingOverride) error { + return configure_native_bindings(device, layout, modifiers, overrides, false) +} + +func configure_native_bindings(device *C.CommandDevice, layout input.KeyboardLayout, modifiers []string, overrides []input.BindingOverride, ocrReview bool, pending ...bool) error { + symbols, err := command_modifier_symbols(modifiers) + if err != nil { + return err + } + var insertCode, keypadCode, capsCode C.int + for _, symbol := range symbols { + code := C.XKeysymToKeycode(device.display, C.KeySym(symbol)) + if code == 0 { + return fmt.Errorf("Cthulhu modifier %x is unavailable on this X11 keymap", symbol) + } + switch symbol { + case 0xff63: + insertCode = C.int(code) + case 0xff9e: + keypadCode = C.int(code) + case 0xffe5: + capsCode = C.int(code) + } + } + global := resolvedBindings(layout, false, overrides) + browse := resolvedBindings(layout, true, overrides) + if ocrReview { + browse = input.OCRCommandBindings(global) + if len(pending) > 0 && pending[0] { + browse = input.OCRPendingBindings(global) + } + } + customizedBrowse := make(map[input.CommandChord]bool) + for _, override := range overrides { + if override.Layout == layout && override.Scope == "browse" { + for _, key := range override.Keys { + chord, _ := input.ParseCommandChord(key) + customizedBrowse[chord] = true + } + } + } + var native []C.NativeBinding + var extraModifierMask uint16 + for chord, command := range browse { + if chord.CthulhuModifier { + extraModifierMask |= chord.Modifiers & (8 | 64) + // Such commands are delivered after a screen-reader modifier grab. + // Validate that the native keymap can actually produce the symbol. + code := C.XKeysymToKeycode(device.display, C.KeySym(chord.Symbol)) + if code == 0 || uint32(C.XkbKeycodeToKeysym(device.display, code, 0, 0)) != chord.Symbol { + return fmt.Errorf("key %s is unavailable as a base key on this X11 keymap", input.FormatCommandChord(chord)) + } + continue + } + value := C.NativeBinding{symbol: C.ulong(chord.Symbol), modifiers: C.uint(chord.Modifiers)} + if global[chord] == "" || ocrReview { + value.browseOnly = 1 + } + if customizedBrowse[chord] && !ocrReview { + value.probe = 1 + } + if command == input.DocumentActivate { + value.activate = 1 + } + native = append(native, value) + } + // Own Control/Shift from their press in temporary review. Otherwise the + // application can see a modifier press whose release the arrow grab owns. + // Unbound chords are replayed whole after all their physical keys release. + if ocrReview && !(len(pending) > 0 && pending[0]) { + for _, symbol := range []uint32{0xffe1, 0xffe2, 0xffe3, 0xffe4} { + for _, mask := range []uint16{0, 1, 4, 5} { + native = append(native, C.NativeBinding{symbol: C.ulong(symbol), modifiers: C.uint(mask), browseOnly: 1}) + } + } + } + var first *C.NativeBinding + if len(native) != 0 { + first = &native[0] + } + if err := C.configure_command_bindings(device, first, C.int(len(native)), C.uint(extraModifierMask), insertCode, keypadCode, capsCode); err != 0 { + return fmt.Errorf("change X11 key bindings: native error %d (key unavailable or grabbed by another application)", int(err)) + } + return nil +} diff --git a/internal/platform/xorg/commands_chord.go b/internal/platform/xorg/commands_chord.go new file mode 100644 index 0000000..b02a948 --- /dev/null +++ b/internal/platform/xorg/commands_chord.go @@ -0,0 +1,178 @@ +package xorg + +/* +#include "commands_native.h" +#include +*/ +import "C" + +import ( + "errors" + "fmt" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +// Wait for the complete chord: Shift+CapsLock+V remains a version command. +func is_caps_lock_toggle(keys []C.CommandKey) bool { + caps, shift := false, false + for _, key := range keys { + if key.modifiers & ^C.int(1) != 0 { + return false + } + shift = shift || key.modifiers&1 != 0 + switch key.symbol { + case 0xffe5: + caps = true + case 0xffe1, 0xffe2: + shift = true + default: + return false + } + } + return caps && shift +} + +func (owner *commandOwner) handleKey(key C.CommandKey) bool { + owner.listener.grabActive.Store(true) + // Focus policy can change while the native owner waits for an X + // event. Replay a stale browse-only press against the requested + // policy, including custom symbols outside the default key list. + if !owner.learnMode && owner.uiSession == 0 && len(owner.held) == 0 && key.pressed != 0 && !owner.listener.browse.Load() && !owner.ocrReview && + !owner.router.IsModifier(uint32(key.symbol)) && owner.globalBindings[input.CommandChord{Symbol: uint32(key.symbol), Modifiers: uint16(key.modifiers)}] == "" { + owner.passThrough = true + } + if key.pressed != 0 { + owner.held[int(key.code)] = true + } else { + delete(owner.held, int(key.code)) + } + owner.buffered = append(owner.buffered, key) + if owner.uiSession != 0 { + if !owner.handle_internal_key(key) { + return false + } + } else if owner.learnMode { + if !owner.handleLearnKey(key) { + return false + } + } else if !owner.passThrough && !owner.handleRoutedKey(key) { + return false + } + if len(owner.held) == 0 && !owner.finishChord() { + return false + } + return true +} + +func (owner *commandOwner) handleLearnKey(key C.CommandKey) bool { + owner.bound = true + if key.pressed == 0 { + owner.router.Handle(uint32(key.symbol), uint16(key.code), uint16(key.modifiers), false) + return true + } + chord := owner.router.Chord(uint32(key.symbol), uint16(key.modifiers)) + _, command := owner.router.Handle(uint32(key.symbol), uint16(key.code), uint16(key.modifiers), true) + action := input.LearnKey + switch { + case uint32(key.symbol) == 0xff1b || command == input.ToggleLearnMode: + action = input.ToggleLearnMode + case chord.Symbol == 0xffbe && chord.Modifiers == 0 && !chord.CthulhuModifier: + action = input.LearnDocumentation + case chord.Symbol == 0xffbf && chord.Modifiers == 0 && !chord.CthulhuModifier: + action = input.LearnDefaultShortcuts + case chord.Symbol == 0xffc0 && chord.Modifiers == 0 && !chord.CthulhuModifier: + action = input.LearnApplicationShortcuts + } + if action != input.LearnKey { + owner.learnMode = false + owner.listener.learnMode.Store(false) + } + name := "" + if nativeName := C.XKeysymToString(C.KeySym(key.symbol)); nativeName != nil { + name = C.GoString(nativeName) + } + if owner.workerContext.Err() == nil && !owner.listener.enqueueSecureCommand(input.CommandEvent{Command: action, Timestamp: uint32(key.timestamp), Chord: chord, KeyName: name}) { + owner.listener.failures <- errors.New("X11 learn mode queue overflow") + return false + } + return true +} + +func (owner *commandOwner) handleRoutedKey(key C.CommandKey) bool { + consumed, command := owner.router.Handle(uint32(key.symbol), uint16(key.code), uint16(key.modifiers), key.pressed != 0) + if key.pressed != 0 && !owner.router.IsModifier(uint32(key.symbol)) { + if consumed { + owner.bound = true + } else if !owner.bound { + owner.passThrough = true + } + } + if command != "" { + if owner.ocrReview && (command == input.OCRDismiss || command == input.OCRDismissAndPass) { + owner.dismissOCR = true + if command == input.OCRDismissAndPass { + owner.bound = false + owner.passThrough = true + } + } + if command == input.ToggleLearnMode { + if owner.ocrReview { + owner.dismissOCR = true + } + owner.learnMode = true + owner.listener.learnMode.Store(true) + owner.listener.learnEcho.Store(true) + } + uiSession := uint64(0) + if command == input.ShowActions { + if owner.ocrReview && !owner.leave_ocr_review() { + return false + } + var err error + uiSession, err = owner.begin_internal_ui() + if err != nil { + // An unavailable modal grab is a failed command, not a failed reader. + uiSession = 0 + } + } + if owner.workerContext.Err() == nil && !owner.listener.enqueueSecureCommand(input.CommandEvent{UISession: uiSession, Command: command, Timestamp: uint32(key.timestamp), Chord: owner.router.Chord(uint32(key.symbol), uint16(key.modifiers)), LearnModeStarted: command == input.ToggleLearnMode}) { + owner.listener.failures <- errors.New("X11 command queue overflow") + return false + } + } + return true +} + +func (owner *commandOwner) finishChord() bool { + if !owner.bound && owner.device.capsCode != 0 && is_caps_lock_toggle(owner.buffered) { + C.toggle_command_caps_lock(owner.device) + if result := C.replay_command_keys(owner.device, &owner.buffered[0], C.int(len(owner.buffered))); result != 0 { + owner.listener.failures <- fmt.Errorf("release Caps Lock toggle chord: native error %d", int(result)) + return false + } + } else if owner.passThrough || !owner.bound { + result := C.replay_command_keys(owner.device, &owner.buffered[0], C.int(len(owner.buffered))) + if result != 0 { + owner.listener.failures <- fmt.Errorf("replay unbound X11 chord: native error %d", int(result)) + return false + } + } else if !owner.learnMode && owner.uiSession == 0 { + C.release_command_keyboard(owner.device) + } + owner.router.Reset() + owner.buffered = owner.buffered[:0] + owner.bound = false + owner.passThrough = false + if owner.dismissOCR { + owner.dismissOCR = false + if !owner.leave_ocr_review() { + return false + } + } + owner.listener.grabActive.Store(owner.learnMode || owner.uiSession != 0) + owner.listener.uiEcho.Store(owner.uiSession != 0) + owner.listener.learnMode.Store(owner.learnMode) + owner.listener.learnEcho.Store(owner.learnMode) + return true +} diff --git a/internal/platform/xorg/commands_foreground.go b/internal/platform/xorg/commands_foreground.go new file mode 100644 index 0000000..5b5c0dd --- /dev/null +++ b/internal/platform/xorg/commands_foreground.go @@ -0,0 +1,70 @@ +package xorg + +/* +#cgo pkg-config: xres +#include "commands_native.h" +#include +*/ +import "C" + +func ActiveWindowIsXTerm() bool { + return C.cthulhu_active_window_is_xterm() != 0 +} + +// Foreground is an immutable X11 client identity and its screen rectangle. +// Known with Window == 0 means no foreground client, not missing metadata. +type Foreground struct { + Known bool + Window uint64 + PID int + // PropertyPID retains _NET_WM_PID for diagnostics. PID uses the X server's + // local client identity when available, so Flatpak namespaces agree with AT-SPI. + PropertyPID int + X, Y, Width, Height int + OuterX, OuterY, OuterWidth, OuterHeight int +} + +// ForegroundReader has no goroutine. Its native event-loop owner opens, reads, +// and closes it on that thread; no consumer performs X11 I/O. +type ForegroundReader struct { + display *C.Display + clientPIDs bool + pidWindow uint64 + propertyPID, clientPID int +} + +func OpenForegroundReader() *ForegroundReader { + display := C.XOpenDisplay(nil) + if display == nil { + return nil + } + return &ForegroundReader{display: display, clientPIDs: C.cthulhu_xres_client_pids_supported(display) != 0} +} +func (reader *ForegroundReader) Read() Foreground { + if reader == nil { + return Foreground{} + } + value := C.read_foreground(reader.display) + window, propertyPID := uint64(value.window), int(value.pid) + // The connection's owner also owns this one-client cache. Window departure + // (including no foreground) or a changed property discards the old identity. + // Resizing and ordinary input never trigger an extra server query. + if window != reader.pidWindow || propertyPID != reader.propertyPID { + reader.pidWindow, reader.propertyPID, reader.clientPID = window, propertyPID, 0 + if window != 0 && reader.clientPIDs { + reader.clientPID = int(C.cthulhu_xres_client_pid(reader.display, C.Window(window))) + } + } + pid := propertyPID + if reader.clientPID > 0 { + pid = reader.clientPID + } + return Foreground{Known: value.known != 0, Window: window, PID: pid, PropertyPID: propertyPID, + X: int(value.x), Y: int(value.y), Width: int(value.width), Height: int(value.height), OuterX: int(value.outerX), OuterY: int(value.outerY), OuterWidth: int(value.outerWidth), OuterHeight: int(value.outerHeight)} +} +func (reader *ForegroundReader) Close() { + if reader != nil { + C.XCloseDisplay(reader.display) + reader.display = nil + } +} diff --git a/internal/platform/xorg/commands_native.c b/internal/platform/xorg/commands_native.c new file mode 100644 index 0000000..47a577d --- /dev/null +++ b/internal/platform/xorg/commands_native.c @@ -0,0 +1,651 @@ + +#include "commands_native.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +static pthread_mutex_t error_mutex = PTHREAD_MUTEX_INITIALIZER; +static Display *error_display; +static int grab_error; +static int (*previous_error_handler)(Display *, XErrorEvent *); +static int command_error(Display *display, XErrorEvent *event) { + if (display == error_display) { grab_error = event->error_code; return 0; } + return previous_error_handler ? previous_error_handler(display, event) : 0; +} +// Metadata readers share the keyboard owner's guard because Xlib's error +// handler is process-wide. Each begin/end pair runs in one native call. +void cthulhu_x11_begin_read(Display *display) { + pthread_mutex_lock(&error_mutex); + XSync(display, False); + error_display = display; + grab_error = 0; + previous_error_handler = XSetErrorHandler(command_error); +} +int cthulhu_x11_end_read(Display *display) { + XSync(display, False); + int failed = grab_error; + XSetErrorHandler(previous_error_handler); + error_display = NULL; + pthread_mutex_unlock(&error_mutex); + return failed; +} +static int cthulhu_identifier_is_xterm(const char *identifier) { + if (identifier == NULL) return 0; + char lower[256]; + size_t length = strlen(identifier); + if (length == 0 || length >= sizeof(lower)) return 0; + for (size_t index = 0; index <= length; index++) { + lower[index] = (char)tolower((unsigned char)identifier[index]); + } + const char *base = strrchr(lower, '/'); + base = base != NULL ? base + 1 : lower; + return strcmp(base, "xterm") == 0; +} +static unsigned char *cthulhu_window_property( + Display *display, + Window window, + Atom property, + Atom *type, + int *format, + unsigned long *items +) { + unsigned char *data = NULL; + unsigned long bytesAfter = 0; + if (XGetWindowProperty( + display, + window, + property, + 0, + 1024, + False, + AnyPropertyType, + type, + format, + items, + &bytesAfter, + &data) != Success || data == NULL) { + if (data != NULL) XFree(data); + return NULL; + } + return data; +} + +static unsigned long cthulhu_single_window_property(Display *display, Window window, + Atom property, Atom expectedType) { + Atom type = None; + int format = 0; + unsigned long items = 0, value = 0; + unsigned char *data = cthulhu_window_property(display, window, property, &type, &format, &items); + if (data != NULL && type == expectedType && format == 32 && items == 1) + value = ((unsigned long *)data)[0]; + if (data != NULL) XFree(data); + return value; +} + +// A minimal window manager can focus GTK's input-only keyboard grab window +// when a combo popup appears. Resolve only a mapped transient popup in that +// grab's explicit window group, with matching process metadata throughout. +// The caller holds the X11 error guard; disappearing windows fail closed. +static Window cthulhu_input_grab_owner(Display *display, Window focus) { + Window root = DefaultRootWindow(display); + XWindowAttributes attributes; + if (focus == None || focus == PointerRoot || focus == root || + !XGetWindowAttributes(display, focus, &attributes) || + attributes.class != InputOnly || !attributes.override_redirect || + attributes.map_state != IsViewable) + return focus; + + Atom leaderAtom = XInternAtom(display, "WM_CLIENT_LEADER", False); + Atom pidAtom = XInternAtom(display, "_NET_WM_PID", False); + Atom typeAtom = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); + Window leader = cthulhu_single_window_property(display, focus, leaderAtom, XA_WINDOW); + unsigned long pid = cthulhu_single_window_property(display, focus, pidAtom, XA_CARDINAL); + if (leader == None || pid == 0) return focus; + + Window treeRoot, parent, *children = NULL; + unsigned int count = 0; + if (!XQueryTree(display, root, &treeRoot, &parent, &children, &count)) return focus; + Window result = focus; + if (count <= 256) { + Atom comboType = XInternAtom(display, "_NET_WM_WINDOW_TYPE_COMBO", False); + Atom popupType = XInternAtom(display, "_NET_WM_WINDOW_TYPE_POPUP_MENU", False); + Atom dropdownType = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU", False); + // XQueryTree returns stacking order, bottom to top. + for (unsigned int index = count; index > 0; index--) { + Window candidate = children[index - 1], owner = None; + if (candidate == focus || !XGetWindowAttributes(display, candidate, &attributes) || + attributes.class != InputOutput || !attributes.override_redirect || + attributes.map_state != IsViewable) + continue; + Atom type = cthulhu_single_window_property(display, candidate, typeAtom, XA_ATOM); + if (type != comboType && type != popupType && type != dropdownType) continue; + if (cthulhu_single_window_property(display, candidate, leaderAtom, XA_WINDOW) != leader || + cthulhu_single_window_property(display, candidate, pidAtom, XA_CARDINAL) != pid || + !XGetTransientForHint(display, candidate, &owner) || owner == None || + owner == root || owner == candidate || + !XGetWindowAttributes(display, owner, &attributes) || + attributes.class != InputOutput || attributes.override_redirect || + attributes.map_state != IsViewable || + cthulhu_single_window_property(display, owner, leaderAtom, XA_WINDOW) != leader || + cthulhu_single_window_property(display, owner, pidAtom, XA_CARDINAL) != pid) + continue; + result = owner; + break; + } + } + if (children != NULL) XFree(children); + return result; +} +// Follow the mapped child under the pointer. The client PID is usually on a +// descendant of the window-manager frame; keep the first PID found on that path. +PointerPosition cthulhu_read_pointer(Display *display) { + PointerPosition result = {0}; + cthulhu_x11_begin_read(display); + Window root = DefaultRootWindow(display), queryRoot, child; + int rootX, rootY, winX, winY; unsigned int mask; + if (XQueryPointer(display, root, &queryRoot, &child, &result.x, &result.y, + &winX, &winY, &mask)) { + result.known = 1; + Atom pidAtom = XInternAtom(display, "_NET_WM_PID", False); + for (int depth = 0; child != None && depth < 32; depth++) { + Window current = child; + Atom type = None; int format = 0; unsigned long items = 0; + unsigned char *data = cthulhu_window_property(display, current, pidAtom, + &type, &format, &items); + if (data && type == XA_CARDINAL && format == 32 && items == 1) { + result.pid = (int)((unsigned long *)data)[0]; + result.window = current; + } + if (data) XFree(data); + if (!XQueryPointer(display, current, &queryRoot, &child, + &rootX, &rootY, &winX, &winY, &mask)) break; + } + } + if (cthulhu_x11_end_read(display)) result = (PointerPosition){0}; + return result; +} +// Read-only metadata connection, owned by the caller's native event thread. +// All requests which can race window destruction share the Xlib error guard. +Foreground read_foreground(Display *display) { + Foreground result = {0}; + pthread_mutex_lock(&error_mutex); + XSync(display,False); + error_display=display; grab_error=0; + previous_error_handler=XSetErrorHandler(command_error); + Window root=DefaultRootWindow(display), window=None; + Atom type=None; int format=0; unsigned long items=0; + unsigned char *data=cthulhu_window_property(display,root, + XInternAtom(display,"_NET_ACTIVE_WINDOW",False),&type,&format,&items); + if (data && type==XA_WINDOW && format==32 && items==1) { + result.known=1; window=((Window *)data)[0]; + } else { + // Non-EWMH X11 sessions (including the native fixture): resolve + // input focus to its client ancestor and resolve input-only popup grabs. + int revert; XGetInputFocus(display,&window,&revert); + result.known=1; + for (int depth=0; window!=None && window!=PointerRoot && window!=root && depth<64; depth++) { + Atom stateType=None; int stateFormat=0; unsigned long stateItems=0; + unsigned char *state=cthulhu_window_property(display,window, + XInternAtom(display,"WM_STATE",False),&stateType,&stateFormat,&stateItems); + if (state) XFree(state); + if (stateType!=None) break; + Window treeRoot,parent,*children=NULL; unsigned int count=0; + if (!XQueryTree(display,window,&treeRoot,&parent,&children,&count)) break; + if (children) XFree(children); + if (parent==root || parent==None) break; + window=parent; + } + window=cthulhu_input_grab_owner(display,window); + } + if (data) XFree(data); + if (window!=None && window!=PointerRoot && window!=root) { + XWindowAttributes attributes; + if (XGetWindowAttributes(display,window,&attributes) && attributes.map_state==IsViewable) { + result.window=window; + Window child; + XTranslateCoordinates(display,window,root,0,0,&result.x,&result.y,&child); + result.width=attributes.width; result.height=attributes.height; + result.outerX=result.x; result.outerY=result.y; + result.outerWidth=result.width; result.outerHeight=result.height; + data=cthulhu_window_property(display,window,XInternAtom(display,"_NET_FRAME_EXTENTS",False),&type,&format,&items); + if (data && type==XA_CARDINAL && format==32 && items==4) { + unsigned long *edges=(unsigned long *)data; + if (edges[0]<1024 && edges[1]<1024 && edges[2]<1024 && edges[3]<1024) { + result.outerX-=edges[0]; result.outerY-=edges[2]; + result.outerWidth+=edges[0]+edges[1]; result.outerHeight+=edges[2]+edges[3]; + } + } + if (data) XFree(data); + data=cthulhu_window_property(display,window,XInternAtom(display,"_NET_WM_PID",False),&type,&format,&items); + if (data && type==XA_CARDINAL && format==32 && items==1) result.pid=(int)((unsigned long *)data)[0]; + if (data) XFree(data); + } + } + XSync(display,False); + // A disappearing client is an observed loss, not a process-fatal BadWindow. + if (grab_error) { result.window=0; result.pid=0; } + XSetErrorHandler(previous_error_handler); error_display=NULL; + pthread_mutex_unlock(&error_mutex); + return result; +} +int cthulhu_focus_metadata_unchecked(Display *display, SteamFocusSample *steam) { + Window root = DefaultRootWindow(display); + Atom activeAtom = XInternAtom(display, "_NET_ACTIVE_WINDOW", False); + Atom type = None; + int format = 0; + unsigned long items = 0; + unsigned char *data = cthulhu_window_property(display, root, activeAtom, &type, &format, &items); + if (data == NULL || type != XA_WINDOW || format != 32 || items < 1) { + if (data != NULL) XFree(data); + return 0; + } + Window window = ((Window *)data)[0]; + XFree(data); + if (steam != NULL) { + steam->known = 1; + steam->window = window; + } + if (window == None || window == root) { + return 0; + } + + Atom classAtom = XInternAtom(display, "WM_CLASS", False); + data = cthulhu_window_property(display, window, classAtom, &type, &format, &items); + int matched = 0; + int identified = 0; + if (data != NULL && type == XA_STRING && format == 8 && items > 0) { + identified = 1; + char *identifier = (char *)data; + if (cthulhu_identifier_is_xterm(identifier)) matched = 1; + char *classIdentifier = identifier + strlen(identifier) + 1; + if (steam != NULL && (unsigned char *)classIdentifier < data + items) { + steam->steam = strcmp(identifier, "steamwebhelper") == 0 && + strcmp(classIdentifier, "steam") == 0; + } + if (!matched && (unsigned char *)classIdentifier < data + items) { + matched = cthulhu_identifier_is_xterm(classIdentifier); + } + } + if (data != NULL) XFree(data); + if (matched) { + return 1; + } + if (identified) return 2; + + Atom pidAtom = XInternAtom(display, "_NET_WM_PID", False); + data = cthulhu_window_property(display, window, pidAtom, &type, &format, &items); + long pid = -1; + if (data != NULL && type == XA_CARDINAL && format == 32 && items > 0) { + pid = (long)((unsigned long *)data)[0]; + identified = 1; + } + if (data != NULL) XFree(data); + if (pid > 0) { + char path[64]; + snprintf(path, sizeof(path), "/proc/%ld/cmdline", pid); + FILE *cmdline = fopen(path, "rb"); + if (cmdline != NULL) { + char executable[256]; + size_t length = fread(executable, 1, sizeof(executable) - 1, cmdline); + fclose(cmdline); + executable[length] = '\0'; + matched = cthulhu_identifier_is_xterm(executable); + identified = 1; + } + } + if (matched) return 1; + return identified ? 2 : 0; +} +int cthulhu_display_active_window_xterm_match(Display *display) { + pthread_mutex_lock(&error_mutex); + XSync(display,False); + error_display=display; grab_error=0; + previous_error_handler=XSetErrorHandler(command_error); + int match=cthulhu_focus_metadata_unchecked(display, NULL); + XSync(display,False); + if (grab_error) match=0; + XSetErrorHandler(previous_error_handler); error_display=NULL; + pthread_mutex_unlock(&error_mutex); + return match; +} +int cthulhu_active_window_is_xterm(void) { + Display *display = XOpenDisplay(NULL); + if (display == NULL) return 0; + int match = cthulhu_display_active_window_xterm_match(display); + XCloseDisplay(display); + return match == 1; +} +// Ignore Scroll Lock only when its modifier slot has no other meaning. In +// particular, a slot shared with AltGr/level switching must remain significant. +static unsigned int scroll_lock_modifiers(Display *display) { + unsigned int mask = XkbKeysymToModifiers(display, XK_Scroll_Lock) & + ~(ShiftMask | ControlMask | Mod1Mask | Mod4Mask); + if (!mask) return 0; + XModifierKeymap *mapping = XGetModifierMapping(display); + if (mapping == NULL) return 0; + int minCode, maxCode, symbolsPerCode; + XDisplayKeycodes(display, &minCode, &maxCode); + KeySym *symbols = XGetKeyboardMapping(display, minCode, + maxCode - minCode + 1, &symbolsPerCode); + if (symbols == NULL) { XFreeModifiermap(mapping); return 0; } + for (int slot = 0; slot < 8; slot++) { + unsigned int bit = 1u << slot; + if (!(mask & bit)) continue; + for (int index = 0; index < mapping->max_keypermod; index++) { + int code = mapping->modifiermap[slot * mapping->max_keypermod + index]; + if (!code) continue; + if (code < minCode || code > maxCode) { mask &= ~bit; break; } + for (int symbolIndex = 0; symbolIndex < symbolsPerCode; symbolIndex++) { + KeySym symbol = symbols[(code - minCode) * symbolsPerCode + symbolIndex]; + if (symbol != NoSymbol && symbol != XK_Scroll_Lock) mask &= ~bit; + } + } + } + XFree(symbols); + XFreeModifiermap(mapping); + return mask; +} +static void grab_command_keys(CommandDevice *device) { + // Modifier-first chords must be observed even before the command key is + // known. Lock modifiers are transparent; NumLock preserves keypad typing. + unsigned int allowedModifiers = device->ignoredModifierMask | + ControlMask | ShiftMask | device->extraModifierMask; + for (unsigned int mask=0;mask<256;mask++) { + if (mask & ~allowedModifiers) continue; + if (device->capsCode) XGrabKey(device->display,device->capsCode,mask,device->root,False,GrabModeAsync,GrabModeSync); + if (device->insertCode) XGrabKey(device->display,device->insertCode,mask,device->root,False,GrabModeAsync,GrabModeSync); + if (device->keypadCode && !(mask & device->numlockMask)) XGrabKey(device->display,device->keypadCode,mask,device->root,False,GrabModeAsync,GrabModeSync); + } + for (int j=0;jbindingCount;j++) { + NativeBinding binding=device->bindings[j]; + if (binding.browseOnly && !device->browse && !(device->probeBindings && binding.probe)) continue; + int code=XKeysymToKeycode(device->display,binding.symbol); + if (!code) continue; + for (unsigned int mask=0;mask<256;mask++) { + if ((mask & ~device->ignoredModifierMask) != binding.modifiers) continue; + // Non-numeric keypad navigation has a different meaning with NumLock. + if (binding.symbol>=XK_KP_Home && binding.symbol<=XK_KP_Delete && (mask & device->numlockMask)) continue; + XGrabKey(device->display,code,mask,device->root,False,GrabModeAsync,GrabModeSync); + } + } +} +int set_command_keys(CommandDevice *device, int enabled) { + pthread_mutex_lock(&error_mutex); + XSync(device->display,False); + error_display=device->display; grab_error=0; + previous_error_handler=XSetErrorHandler(command_error); + XUngrabKey(device->display,AnyKey,AnyModifier,device->root); + if (!enabled) { + // A synchronous passive grab may already have activated before Go + // consumes its press. XUngrabKey only removes future registrations. + XUngrabKeyboard(device->display,CurrentTime); + device->active=0; + } + if (enabled) grab_command_keys(device); + XSync(device->display,False); + int error=grab_error; + if (error && enabled) { + XUngrabKey(device->display,AnyKey,AnyModifier,device->root); + XSync(device->display,False); + } + XSetErrorHandler(previous_error_handler); error_display=NULL; + pthread_mutex_unlock(&error_mutex); + device->commands=enabled && !error; + return error; +} +// Replace passive grabs transactionally. A conflicting grab restores the old +// configuration so preferences can report the failure without losing controls. +int configure_command_bindings(CommandDevice *device, NativeBinding *bindings, int count, unsigned int extraModifierMask, int insertCode, int keypadCode, int capsCode) { + NativeBinding *copy=count ? malloc(sizeof(NativeBinding)*count) : NULL; + if (count && !copy) return -3; + if (count) memcpy(copy,bindings,sizeof(NativeBinding)*count); + for (int i=0;idisplay,copy[i].symbol); + if (!code || XkbKeycodeToKeysym(device->display,code,0,0)!=copy[i].symbol) { free(copy); return -2; } + } + int previousInsert=device->insertCode, previousKeypad=device->keypadCode, previousCaps=device->capsCode; + NativeBinding *previous=device->bindings; + int previousCount=device->bindingCount, enabled=device->commands; + unsigned int previousMask=device->extraModifierMask; + device->bindings=copy; device->bindingCount=count; device->extraModifierMask=extraModifierMask; + device->insertCode=insertCode; device->keypadCode=keypadCode; device->capsCode=capsCode; + // Probe newly customized browse-only chords even outside browse mode, so + // Apply can reject a conflict instead of failing on the next mode change. + for (int i=0;ibrowse) device->probeBindings=1; + int probing=device->probeBindings; + int error=set_command_keys(device,enabled); + device->probeBindings=0; + if (!error && probing) error=set_command_keys(device,enabled); + if (error) { + device->bindings=previous; device->bindingCount=previousCount; device->extraModifierMask=previousMask; + device->insertCode=previousInsert; device->keypadCode=previousKeypad; device->capsCode=previousCaps; + int restoreError=set_command_keys(device,enabled); + free(copy); + return restoreError ? -6 : error; + } + free(previous); + if (capsCode && !previousCaps) { + device->capsLocked=0; + XkbLockModifiers(device->display,XkbUseCoreKbd,LockMask,0); + XSync(device->display,False); + } + return 0; +} +int set_browse_keys(CommandDevice *device, int enabled) { + int previous=device->browse; + device->browse=enabled; + int error=set_command_keys(device,device->commands); + if (error) { + device->browse=previous; + set_command_keys(device,1); + } + device->browseWindow=read_foreground(device->display).window; + return error; +} +CommandDevice *open_commands(int useInsert, int useKeypad, int useCaps, int *error) { + CommandDevice *device = calloc(1,sizeof(CommandDevice)); + if (!device) { *error=-3; return NULL; } + device->display = XOpenDisplay(NULL); + if (!device->display) { free(device); *error = -1; return NULL; } + int eventBase, errorBase, majorVersion, minorVersion; + if (!XTestQueryExtension(device->display,&eventBase,&errorBase,&majorVersion,&minorVersion)) { + XCloseDisplay(device->display); free(device); *error=-5; return NULL; + } + Bool repeatSupported=False; + if (!XkbSetDetectableAutoRepeat(device->display,True,&repeatSupported) || !repeatSupported) { + XCloseDisplay(device->display); free(device); *error=-4; return NULL; + } + device->root = DefaultRootWindow(device->display); + int xkbOpcode, xkbError, xkbMajor=XkbMajorVersion, xkbMinor=XkbMinorVersion; + if (!XkbQueryExtension(device->display,&xkbOpcode,&device->xkbEvent,&xkbError,&xkbMajor,&xkbMinor)) { + XCloseDisplay(device->display); free(device); *error=-7; return NULL; + } + const char *lockNames[]={"Caps Lock","Num Lock","Scroll Lock"}; + for (int i=0;i<3;i++) { + int index; Bool state; + if (XkbGetNamedIndicator(device->display,XInternAtom(device->display,lockNames[i],False),&index,&state,NULL,NULL)) { + device->lockIndicators[i]=1u<display,XkbUseCoreKbd,XkbIndicatorStateNotifyMask,XkbIndicatorStateNotifyMask); + device->insertCode = useInsert ? XKeysymToKeycode(device->display,XK_Insert) : 0; + device->keypadCode = useKeypad ? XKeysymToKeycode(device->display,XK_KP_Insert) : 0; + device->capsCode = useCaps ? XKeysymToKeycode(device->display,XK_Caps_Lock) : 0; + device->numlockMask = XkbKeysymToModifiers(device->display,XK_Num_Lock); + device->ignoredModifierMask = LockMask | device->numlockMask | + scroll_lock_modifiers(device->display); + if ((useInsert && !device->insertCode) || (useKeypad && !device->keypadCode) || (useCaps && !device->capsCode)) { + XCloseDisplay(device->display); free(device); *error=-2; return NULL; + } + *error=set_command_keys(device,1); + if (*error) { XCloseDisplay(device->display); free(device); return NULL; } + if (device->capsCode) { + XkbLockModifiers(device->display,XkbUseCoreKbd,LockMask,0); + XSync(device->display,False); + } + return device; +} +int command_lock_state(CommandDevice *device) { + unsigned int indicators=0; + XkbGetIndicatorState(device->display,XkbUseCoreKbd,&indicators); + int locks=0; + for (int i=0;i<3;i++) if (indicators & device->lockIndicators[i]) locks |= 1<capsCode) locks=(locks & ~1) | device->capsLocked; + return locks; +} +void toggle_command_caps_lock(CommandDevice *device) { + device->capsLocked=!device->capsLocked; + XkbLockModifiers(device->display,XkbUseCoreKbd,LockMask,device->capsLocked ? LockMask:0); + XSync(device->display,False); +} +int next_command_key(CommandDevice *device, CommandKey *key) { + if (!XPending(device->display)) { + struct pollfd fd={ConnectionNumber(device->display),POLLIN,0}; + int result=poll(&fd,1,20); + if (result<0 && errno==EINTR) return 0; + if (result<0 || (fd.revents & (POLLERR|POLLHUP|POLLNVAL))) return -1; + if (result==0) return 0; + } + XEvent event; + XNextEvent(device->display,&event); + if (event.type==device->xkbEvent && ((XkbEvent *)&event)->any.xkb_type==XkbIndicatorStateNotify) { + key->locks=command_lock_state(device); + key->timestamp=((XkbEvent *)&event)->indicators.time; + return 2; + } + if (event.type!=KeyPress && event.type!=KeyRelease) return 0; + // Events captured before suspension can still be queued in Xlib after + // the grabs are released. Discard that old reader input; it must neither + // dispatch commands nor acquire a new explicit grab in the delegated app. + if (!device->commands) return 0; + // Preserve the intentional capitalization state on both modifier edges. + if (device->capsCode && event.xkey.keycode==(unsigned)device->capsCode) { + XkbLockModifiers(device->display,XkbUseCoreKbd,LockMask,device->capsLocked ? LockMask:0); + XSync(device->display,False); + } + if (!device->active && event.type==KeyPress) { + KeySym symbol=XLookupKeysym(&event.xkey,0); + unsigned int modifiers=event.xkey.state & ~device->ignoredModifierMask; + int browseOnly=0, activate=0; + for (int i=0;ibindingCount;i++) { + NativeBinding binding=device->bindings[i]; + if (binding.symbol==symbol && binding.modifiers==modifiers) { + browseOnly=binding.browseOnly; activate=binding.activate; break; + } + } + if (browseOnly) { + Foreground foreground=read_foreground(device->display); + if (!device->browse || !foreground.known || foreground.window==0 || + foreground.window!=device->browseWindow) { + XAllowEvents(device->display,ReplayKeyboard,event.xkey.time); XFlush(device->display); return 0; + } + } + // Python leaves Return on a natively focused standard button to the + // application. Replay the real press before taking an explicit grab. + if (symbol==XK_Return && activate && device->browse && device->nativeButtonFocus && + !(event.xkey.state & (ControlMask|ShiftMask))) { + XAllowEvents(device->display,ReplayKeyboard,event.xkey.time); XFlush(device->display); return 0; + } + // Upgrade our passive Insert grab to an explicit grab. Unlike a passive + // grab, this stays active if Insert is released before the command key. + int status=XGrabKeyboard(device->display,device->root,False,GrabModeAsync,GrabModeAsync,event.xkey.time); + if (status!=GrabSuccess) { XAllowEvents(device->display,ReplayKeyboard,event.xkey.time); XFlush(device->display); return -2; } + device->active=1; + } + key->pressed=(event.type==KeyPress); key->code=event.xkey.keycode; + key->symbol=XLookupKeysym(&event.xkey,0); + key->modifiers=event.xkey.state & ~device->ignoredModifierMask; + key->text[0]=0; key->textSymbol=0; + if (device->internalUI && event.type==KeyPress) { + char ignored[64]; KeySym translated; + XLookupString(&event.xkey,ignored,sizeof(ignored),&translated,NULL); + key->textSymbol=translated; + if (!(event.xkey.state & (ControlMask|Mod1Mask|Mod4Mask))) { + if (device->composeState) xkb_compose_state_feed(device->composeState,translated); + enum xkb_compose_status status=device->composeState ? xkb_compose_state_get_status(device->composeState) : XKB_COMPOSE_NOTHING; + if (status==XKB_COMPOSE_COMPOSED) { + xkb_compose_state_get_utf8(device->composeState,key->text,sizeof(key->text)); + xkb_compose_state_reset(device->composeState); + } else if (status==XKB_COMPOSE_CANCELLED) { + xkb_compose_state_reset(device->composeState); + } else if (status==XKB_COMPOSE_NOTHING) { + xkb_keysym_to_utf8(translated,key->text,sizeof(key->text)); + } + } else { + xkb_keysym_to_utf8(XLookupKeysym(&event.xkey,0),key->text,sizeof(key->text)); + } + } + key->timestamp=event.xkey.time; + return 1; +} +void release_command_keyboard(CommandDevice *device) { + XUngrabKeyboard(device->display,CurrentTime); XFlush(device->display); device->active=0; +} +int replay_command_keys(CommandDevice *device, CommandKey *keys, int count) { + pthread_mutex_lock(&error_mutex); + XSync(device->display,False); + error_display=device->display; grab_error=0; + previous_error_handler=XSetErrorHandler(command_error); + XUngrabKeyboard(device->display,CurrentTime); + XUngrabKey(device->display,AnyKey,AnyModifier,device->root); + device->active=0; + int injected=1; + for (int i=0;icapsCode && keys[i].code==device->capsCode) continue; + if (!XTestFakeKeyEvent(device->display,keys[i].code,keys[i].pressed,CurrentTime)) injected=0; + } + if (device->commands) grab_command_keys(device); + XSync(device->display,False); + XSetErrorHandler(previous_error_handler); + int error=grab_error; + error_display=NULL; + pthread_mutex_unlock(&error_mutex); + if (!injected) return -1; + return error; +} +void close_commands(CommandDevice *device) { + if (device->composeState) xkb_compose_state_unref(device->composeState); + if (device->composeTable) xkb_compose_table_unref(device->composeTable); + if (device->textContext) xkb_context_unref(device->textContext); + if (device->active) release_command_keyboard(device); + XUngrabKey(device->display,AnyKey,AnyModifier,device->root); + XSync(device->display,False); XCloseDisplay(device->display); free(device->bindings); free(device); +} + +int acquire_internal_keyboard(CommandDevice *device) { + if (!device->active) { + int status=XGrabKeyboard(device->display,device->root,False,GrabModeAsync,GrabModeAsync,CurrentTime); + if (status!=GrabSuccess) return status; + device->active=1; + } + if (!device->textContext) { + device->textContext=xkb_context_new(XKB_CONTEXT_NO_FLAGS); + const char *locale=getenv("LC_ALL"); + if (!locale || !*locale) locale=getenv("LC_CTYPE"); + if (!locale || !*locale) locale=getenv("LANG"); + if (!locale || !*locale) locale="C"; + if (device->textContext) device->composeTable=xkb_compose_table_new_from_locale(device->textContext,locale,XKB_COMPOSE_COMPILE_NO_FLAGS); + if (device->composeTable) device->composeState=xkb_compose_state_new(device->composeTable,XKB_COMPOSE_STATE_NO_FLAGS); + } + if (device->composeState) xkb_compose_state_reset(device->composeState); + device->internalUI=1; + return 0; +} +void reset_internal_compose(CommandDevice *device) { + device->internalUI=0; + if (device->composeState) xkb_compose_state_reset(device->composeState); +} diff --git a/internal/platform/xorg/commands_native.h b/internal/platform/xorg/commands_native.h new file mode 100644 index 0000000..0b28ad7 --- /dev/null +++ b/internal/platform/xorg/commands_native.h @@ -0,0 +1,63 @@ +#ifndef CTHULHU_COMMANDS_NATIVE_H +#define CTHULHU_COMMANDS_NATIVE_H + +#include + +typedef struct { unsigned long symbol; unsigned int modifiers; int browseOnly, activate, probe; } NativeBinding; +typedef struct { + NativeBinding *bindings; + int bindingCount, probeBindings; + unsigned int extraModifierMask; + Display *display; + Window root; + int insertCode, keypadCode, capsCode, numlockMask; + unsigned int ignoredModifierMask; + int xkbEvent, capsLocked; + struct xkb_context *textContext; + struct xkb_compose_table *composeTable; + struct xkb_compose_state *composeState; + unsigned int lockIndicators[3]; + int commands; + int active; + int internalUI; + int browse; + int nativeButtonFocus; + Window browseWindow; +} CommandDevice; +typedef struct { int pressed, code, symbol, textSymbol, modifiers, locks; unsigned long timestamp; char text[64]; } CommandKey; +typedef struct { + int known, pid, x, y, width, height, outerX, outerY, outerWidth, outerHeight; + unsigned long window; +} Foreground; +typedef struct { int known, pid, x, y; unsigned long window; } PointerPosition; +typedef struct { int known, pid, steam, innerFocus; Window window, focus; } SteamFocusSample; +typedef struct { int xterm; SteamFocusSample steam; } CommandFocusSample; + +int cthulhu_active_window_is_xterm(void); +int cthulhu_display_active_window_xterm_match(Display *display); +Foreground read_foreground(Display *display); +int cthulhu_xres_client_pids_supported(Display *display); +int cthulhu_xres_client_pid(Display *display, Window window); +PointerPosition cthulhu_read_pointer(Display *display); +// Caller holds the X11 read guard; optional Steam metadata shares the same +// active-window and WM_CLASS reads as the XTerm match. +int cthulhu_focus_metadata_unchecked(Display *display, SteamFocusSample *steam); +CommandFocusSample cthulhu_read_command_focus(Display *display, int steam_enabled); +int cthulhu_restore_steam_focus(Display *display, Window wrapper, int pid, Window target); +void cthulhu_x11_begin_read(Display *display); +int cthulhu_x11_end_read(Display *display); +int set_command_keys(CommandDevice *device, int enabled); +int configure_command_bindings(CommandDevice *device, NativeBinding *bindings, int count, unsigned int extraModifierMask, int insertCode, int keypadCode, int capsCode); +int set_browse_keys(CommandDevice *device, int enabled); +CommandDevice *open_commands(int useInsert, int useKeypad, int useCaps, int *error); +int command_lock_state(CommandDevice *device); +void toggle_command_caps_lock(CommandDevice *device); +int next_command_key(CommandDevice *device, CommandKey *key); +int acquire_internal_keyboard(CommandDevice *device); +void reset_internal_compose(CommandDevice *device); +void release_command_keyboard(CommandDevice *device); +int replay_command_keys(CommandDevice *device, CommandKey *keys, int count); +void close_commands(CommandDevice *device); +int cthulhu_ocr_click(unsigned long foreground, int x, int y, int root_width, int root_height); + +#endif diff --git a/internal/platform/xorg/commands_ocr.go b/internal/platform/xorg/commands_ocr.go new file mode 100644 index 0000000..447ad9b --- /dev/null +++ b/internal/platform/xorg/commands_ocr.go @@ -0,0 +1,117 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +/* +#include "commands_native.h" +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +// SetOCRReview acknowledges a transactional context change only after every +// held chord has released. It belongs on a session worker, not the command +// consumer. Failure retains the old context. Secure/terminal policy still wins. +// The session must dismiss on real focus changes and ordinary XRecord input. +func (listener *CommandListener) SetOCRReview(ctx context.Context, enabled bool) error { + return listener.set_ocr_context(ctx, enabled, false, 0) +} + +// SetOCRPending owns Escape only; recognition never claims document navigation. +func (listener *CommandListener) SetOCRPending(ctx context.Context, enabled bool) error { + return listener.set_ocr_context(ctx, enabled, enabled, 0) +} + +// SetOCRContext admits a live session only in its expected foreground client. +func (listener *CommandListener) SetOCRContext(ctx context.Context, foreground uint64, pending bool) error { + if foreground == 0 { + return errors.New("OCR foreground unavailable") + } + return listener.set_ocr_context(ctx, true, pending, foreground) +} + +func (listener *CommandListener) set_ocr_context(ctx context.Context, enabled, pending bool, foreground uint64) error { + if err := ctx.Err(); err != nil { + return err + } + listener.mutex.Lock() + done := listener.done + listener.mutex.Unlock() + if done == nil { + return errors.New("command listener is not running") + } + update := bindingUpdate{ctx: ctx, ocrReview: &enabled, ocrPending: &pending, ocrForeground: foreground, result: make(chan error, 1)} + select { + case listener.bindingUpdates <- update: + case <-ctx.Done(): + return ctx.Err() + case <-done: + return errors.New("command listener has stopped") + } + select { + case err := <-update.result: + return err + case <-ctx.Done(): + return ctx.Err() + case <-done: + return errors.New("command listener has stopped") + } +} + +func (listener *CommandListener) OCRReviewEnabled() bool { + return !listener.ocrPending.Load() && !listener.secure.Load() && listener.commandsEnabled.Load() && listener.commandsApplied.Load() && listener.ocrApplied.Load() +} + +func (owner *commandOwner) context_bindings() input.CommandBindings { + if owner.ocrReview { + if owner.ocrPending { + return input.OCRPendingBindings(owner.globalBindings) + } + return input.OCRCommandBindings(owner.globalBindings) + } + return resolvedBindings(owner.layout, owner.device.browse != 0, owner.overrides) +} + +// Configure grabs and routing together. Native replacement restores old +// bindings on error; restore its old mode too before reporting a failed entry. +func configure_context_bindings(device *C.CommandDevice, layout input.KeyboardLayout, modifiers []string, overrides []input.BindingOverride, browse, ocrReview bool, pending ...bool) error { + previous, enabled := device.browse, device.commands + device.browse = 0 + if browse || ocrReview { + device.browse = 1 + } + err := configure_native_bindings(device, layout, modifiers, overrides, ocrReview, pending...) + if err != nil { + device.browse = previous + if result := C.set_command_keys(device, enabled); result != 0 { + return fmt.Errorf("restore X11 input context: native error %d", int(result)) + } + return err + } + device.browseWindow = C.read_foreground(device.display).window + return nil +} + +func (owner *commandOwner) leave_ocr_review() bool { + if !owner.ocrReview { + return true + } + if err := configure_context_bindings(owner.device, owner.layout, owner.modifiers, owner.overrides, owner.listener.browse.Load(), false); err != nil { + owner.listener.failures <- err + return false + } + owner.ocrReview, owner.ocrPending = false, false + owner.listener.ocrPending.Store(false) + owner.listener.ocrApplied.Store(false) + owner.listener.browseApplied.Store(owner.device.browse != 0) + owner.router.ReplaceBindings(owner.context_bindings()) + return true +} diff --git a/internal/platform/xorg/commands_owner.go b/internal/platform/xorg/commands_owner.go new file mode 100644 index 0000000..12bbe2a --- /dev/null +++ b/internal/platform/xorg/commands_owner.go @@ -0,0 +1,113 @@ +package xorg + +/* +#cgo pkg-config: x11 xtst +#include "commands_native.h" +#include +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + "runtime" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +const xtermFocusCheckInterval = 100 * time.Millisecond + +func (listener *CommandListener) Start(ctx context.Context) error { + if err := ctx.Err(); err != nil { + return err + } + listener.mutex.Lock() + defer listener.mutex.Unlock() + if listener.done != nil { + return errors.New("command listener already started") + } + symbols, err := command_modifier_symbols(listener.modifiers) + if err != nil { + return err + } + var useInsert, useKeypad, useCaps C.int + for _, symbol := range symbols { + switch symbol { + case 0xff63: + useInsert = 1 + case 0xff9e: + useKeypad = 1 + case 0xffe5: + useCaps = 1 + } + } + workerContext, cancel := context.WithCancel(ctx) + listener.cancel = cancel + listener.done = make(chan struct{}) + setup := make(chan error, 1) + go func() { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + defer close(listener.done) + defer listener.grabActive.Store(false) + defer listener.learnMode.Store(false) + defer listener.learnEcho.Store(false) + defer listener.uiSession.Store(0) + defer listener.uiEcho.Store(false) + var nativeError C.int + listener.commandsEnabled.Store(true) + device := C.open_commands(useInsert, useKeypad, useCaps, &nativeError) + if device == nil { + setup <- fmt.Errorf("open X11 command listener: native error %d (a conflicting command-key grab may already exist)", int(nativeError)) + return + } + defer C.close_commands(device) + defer listener.browseApplied.Store(false) + defer listener.ocrApplied.Store(false) + defer listener.commandsApplied.Store(false) + listener.commandsApplied.Store(true) + layout := listener.layout + modifiers := append([]string(nil), listener.modifiers...) + core := input.CloneBindingOverrides(listener.bindingOverrides) + tentacles := input.CloneBindingOverrides(listener.tentacleBindings) + overrides := input.MergeTentacleBindings(core, tentacles) + if err := configureNativeBindings(device, layout, modifiers, overrides); err != nil { + setup <- err + return + } + listener.publishTentacleBindings(overrides) + defer listener.publishTentacleBindings(nil) + setup <- nil + listener.runCommandLoop(workerContext, device, layout, modifiers, core, tentacles, symbols) + }() + select { + case err := <-setup: + if err != nil { + cancel() + <-listener.done + } + return err + case <-ctx.Done(): + cancel() + <-listener.done + return ctx.Err() + } +} + +func (listener *CommandListener) Stop(ctx context.Context) error { + listener.mutex.Lock() + cancel, done := listener.cancel, listener.done + listener.mutex.Unlock() + if done == nil { + return nil + } + cancel() + select { + case <-done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} diff --git a/internal/platform/xorg/commands_owner_loop.go b/internal/platform/xorg/commands_owner_loop.go new file mode 100644 index 0000000..d213707 --- /dev/null +++ b/internal/platform/xorg/commands_owner_loop.go @@ -0,0 +1,282 @@ +package xorg + +/* +#include "commands_native.h" +#include +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +// commandOwner is confined to the X11 command goroutine and its locked OS thread. +// Its chord buffer and router are reset on completed chords and secure input; +// the whole owner is discarded when the listener stops. +type commandOwner struct { + listener *CommandListener + workerContext context.Context + device *C.CommandDevice + layout input.KeyboardLayout + modifiers []string + overrides []input.BindingOverride + core, tentacles []input.BindingOverride + symbols []uint32 + globalBindings input.CommandBindings + router *input.CommandRouter + held map[int]bool + buffered []C.CommandKey + bound, passThrough, learnMode bool + ocrReview, dismissOCR bool + ocrPending bool + uiSession uint64 + uiWindow, uiFocus C.Window + lastLocks, lastFocusMatch C.int + lastFocusCheck, drainDeadline time.Time + steamFocus steamFocusRepair +} + +func (listener *CommandListener) runCommandLoop(workerContext context.Context, device *C.CommandDevice, layout input.KeyboardLayout, modifiers []string, core, tentacles []input.BindingOverride, symbols []uint32) { + owner := &commandOwner{listener: listener, workerContext: workerContext, device: device, layout: layout, modifiers: modifiers, core: core, tentacles: tentacles, overrides: input.MergeTentacleBindings(core, tentacles), symbols: symbols, held: make(map[int]bool)} + owner.run() +} + +func (owner *commandOwner) run() { + owner.publishFocus() + owner.globalBindings = resolvedBindings(owner.layout, false, owner.overrides) + owner.router = input.NewCommandRouter(owner.symbols, owner.globalBindings) + owner.lastLocks = C.command_lock_state(owner.device) + for { + if owner.workerContext.Err() != nil { + if !owner.bound || len(owner.held) == 0 { + break + } + // Quit dispatches on press. Keep consuming its physical releases + // during shutdown, bounded in case a device disappears. + if owner.drainDeadline.IsZero() { + owner.drainDeadline = time.Now().Add(time.Second) + } + if time.Now().After(owner.drainDeadline) { + break + } + } + if !owner.sync_internal_ui() { + return + } + if !owner.applyBindingUpdate() { + return + } + if time.Since(owner.lastFocusCheck) >= xtermFocusCheckInterval { + owner.check_steam_focus(owner.publishFocus()) + } + owner.resetForSecureInput() + if !owner.syncGrabs() { + return + } + var key C.CommandKey + result := C.next_command_key(owner.device, &key) + if result < 0 { + owner.listener.failures <- fmt.Errorf("X11 command listener failed: %d", int(result)) + return + } + if result == 0 { + continue + } + if result == 2 { + owner.publishLocks(key) + continue + } + if !owner.handleKey(key) { + return + } + } + if len(owner.buffered) != 0 && !owner.bound { + result := C.replay_command_keys(owner.device, &owner.buffered[0], C.int(len(owner.buffered))) + if result != 0 { + owner.listener.failures <- fmt.Errorf("replay interrupted X11 chord: native error %d", int(result)) + } + } +} + +func (owner *commandOwner) publishFocus() steamFocusSample { + match, steam := read_command_focus(owner.device.display, !owner.listener.secure.Load() && owner.workerContext.Err() == nil) + owner.lastFocusCheck = time.Now() + if match == 0 || C.int(match) == owner.lastFocusMatch { + return steam + } + owner.lastFocusMatch = C.int(match) + state := FocusState{Known: true, XTerm: match == 1} + owner.listener.SetCommandGrabs(!state.XTerm) + owner.listener.publishFocusState(state) + return steam +} + +// Native xterm focus vetoes delayed accessibility requests to restore grabs. +// lastFocusMatch belongs to this owner and survives unknown focus samples; +// only a known non-xterm window ends the handoff. +func (owner *commandOwner) commandGrabsAllowed() bool { + return owner.lastFocusMatch != 1 && owner.listener.commandsEnabled.Load() && !owner.listener.secure.Load() +} + +func (owner *commandOwner) applyBindingUpdate() bool { + if len(owner.held) == 0 { + select { + case update := <-owner.listener.bindingUpdates: + nextLayout, nextModifiers := owner.layout, owner.modifiers + if update.replaceKeyboard { + nextLayout, nextModifiers = update.layout, update.modifiers + } + nextCore, nextTentacles := owner.core, owner.tentacles + if update.replaceTentacles { + nextTentacles = update.tentacles + } else if update.ocrReview == nil { + nextCore = update.overrides + } + nextOverrides, nextOCR := input.MergeTentacleBindings(nextCore, nextTentacles), owner.ocrReview + nextPending := owner.ocrPending + if update.ocrPending != nil { + nextPending = *update.ocrPending + } + if update.ocrReview != nil { + nextOverrides, nextOCR = owner.overrides, *update.ocrReview + } + err := update.ctx.Err() + if err == nil && nextOCR && (!owner.commandGrabsAllowed() || owner.learnMode) { + err = errors.New("OCR review input unavailable") + } + if err == nil && nextOCR { + foreground := C.read_foreground(owner.device.display) + if foreground.known == 0 || foreground.window == 0 || update.ocrForeground != 0 && uint64(foreground.window) != update.ocrForeground { + err = errors.New("OCR foreground unavailable") + } + } + if err == nil { + err = configure_context_bindings(owner.device, nextLayout, nextModifiers, nextOverrides, owner.listener.browse.Load(), nextOCR, nextPending) + } + if err == nil { + owner.layout, owner.modifiers, owner.overrides = nextLayout, nextModifiers, nextOverrides + owner.core, owner.tentacles = nextCore, nextTentacles + owner.listener.publishTentacleBindings(nextOverrides) + owner.ocrReview, owner.ocrPending = nextOCR, nextPending + owner.listener.ocrPending.Store(nextPending) + owner.listener.ocrApplied.Store(nextOCR) + owner.listener.browseApplied.Store(owner.device.browse != 0 && !nextOCR) + owner.symbols, _ = command_modifier_symbols(owner.modifiers) + owner.globalBindings = resolvedBindings(owner.layout, false, owner.overrides) + owner.router = input.NewCommandRouter(owner.symbols, owner.context_bindings()) + } + + update.result <- err + if owner.device.commands == 0 && owner.listener.commandsApplied.Load() { + owner.listener.failures <- errors.New("X11 could not restore command grabs") + return false + } + default: + } + } + return true +} + +func (owner *commandOwner) resetForSecureInput() { + if owner.listener.secure.Load() && (owner.ocrReview || owner.device.commands != 0 || owner.device.active != 0 || len(owner.held) != 0) { + C.release_command_keyboard(owner.device) + C.set_command_keys(owner.device, 0) + owner.listener.commandsApplied.Store(false) + owner.listener.grabActive.Store(false) + owner.learnMode = false + owner.listener.learnMode.Store(false) + owner.listener.learnEcho.Store(false) + owner.dismiss_internal_ui() + owner.listener.uiEcho.Store(false) + clear(owner.held) + owner.buffered = nil + owner.bound, owner.passThrough = false, false + owner.ocrReview, owner.ocrPending = false, false + owner.listener.ocrPending.Store(false) + owner.listener.ocrApplied.Store(false) + if err := configure_context_bindings(owner.device, owner.layout, owner.modifiers, owner.overrides, false, false); err != nil { + owner.listener.failures <- err + } + owner.router = input.NewCommandRouter(owner.symbols, resolvedBindings(owner.layout, false, owner.overrides)) + } +} + +func (owner *commandOwner) syncGrabs() bool { + if owner.ocrReview && len(owner.held) == 0 { + foreground := C.read_foreground(owner.device.display) + if foreground.known == 0 || foreground.window == 0 || foreground.window != owner.device.browseWindow { + if !owner.leave_ocr_review() { + return false + } + if !owner.listener.enqueueSecureCommand(input.CommandEvent{Command: input.OCRDismiss}) { + return false + } + } + } + enabled := owner.commandGrabsAllowed() + if owner.ocrReview && !enabled && len(owner.held) == 0 { + if !owner.leave_ocr_review() { + return false + } + } + if len(owner.held) == 0 && !enabled && owner.learnMode { + // Learn mode keeps an explicit keyboard grab between chords. Removing + // passive command grabs alone cannot give that keyboard back to Fenrir. + C.release_command_keyboard(owner.device) + owner.learnMode = false + owner.router.Reset() + owner.listener.grabActive.Store(false) + owner.listener.learnMode.Store(false) + owner.listener.learnEcho.Store(false) + } + if len(owner.held) == 0 && (owner.device.commands != 0) != enabled { + value := C.int(0) + if enabled { + value = 1 + } + if err := C.set_command_keys(owner.device, value); err != 0 { + owner.listener.failures <- fmt.Errorf("change X11 command grabs: native error %d", int(err)) + return false + } + owner.listener.commandsApplied.Store(enabled) + } + if !owner.ocrReview && len(owner.held) == 0 && (owner.device.commands != 0) && + (owner.device.browse != 0) != owner.listener.browse.Load() { + enabled := owner.listener.browse.Load() + value := C.int(0) + if enabled { + value = 1 + } + if err := C.set_browse_keys(owner.device, value); err != 0 { + owner.listener.failures <- fmt.Errorf("change X11 browse grabs: native error %d", int(err)) + return false + } + bindings := resolvedBindings(owner.layout, false, owner.overrides) + if enabled { + bindings = resolvedBindings(owner.layout, true, owner.overrides) + } + owner.router.ReplaceBindings(bindings) + owner.listener.browseApplied.Store(enabled) + } + owner.device.nativeButtonFocus = 0 + if owner.listener.nativeButtonFocus.Load() && !owner.ocrReview { + owner.device.nativeButtonFocus = 1 + } + owner.listener.nativeButtonApplied.Store(owner.device.nativeButtonFocus != 0) + return true +} + +func (owner *commandOwner) publishLocks(key C.CommandKey) { + for index, name := range []string{"Caps Lock", "Num Lock", "Scroll Lock"} { + mask := C.int(1 << index) + if (key.locks^owner.lastLocks)&mask != 0 { + owner.listener.publish_lock_state(input.LockState{Name: name, Locked: key.locks&mask != 0, Timestamp: uint32(key.timestamp)}) + } + } + owner.lastLocks = key.locks +} diff --git a/internal/platform/xorg/commands_security.go b/internal/platform/xorg/commands_security.go new file mode 100644 index 0000000..173b92d --- /dev/null +++ b/internal/platform/xorg/commands_security.go @@ -0,0 +1,54 @@ +package xorg + +import ( + "errors" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func (listener *CommandListener) SetSecureInputActive(active bool) { + listener.secureMutex.Lock() + defer listener.secureMutex.Unlock() + listener.secure.Store(active) + if active { + listener.browse.Store(false) + listener.nativeButtonFocus.Store(false) + } + for { + select { + case <-listener.commands: + case <-listener.lockStates: + default: + return + } + } +} + +func (listener *CommandListener) publish_lock_state(state input.LockState) { + listener.secureMutex.Lock() + defer listener.secureMutex.Unlock() + if listener.secure.Load() { + return + } + select { + case listener.lockStates <- state: + default: + select { + case listener.failures <- errors.New("X11 lock state queue overflow"): + default: + } + } +} + +func (listener *CommandListener) enqueueSecureCommand(command input.CommandEvent) bool { + listener.secureMutex.Lock() + defer listener.secureMutex.Unlock() + if listener.secure.Load() { + return true + } + select { + case listener.commands <- command: + return true + default: + return false + } +} diff --git a/internal/platform/xorg/commands_ui.go b/internal/platform/xorg/commands_ui.go new file mode 100644 index 0000000..f0547f9 --- /dev/null +++ b/internal/platform/xorg/commands_ui.go @@ -0,0 +1,175 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +/* +#cgo pkg-config: xkbcommon +#include "commands_native.h" +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +type uiReply struct { + session uint64 + err error +} +type uiUpdate struct { + ctx context.Context + closeSession uint64 + result chan uiReply +} + +func (listener *CommandListener) InternalUISession() uint64 { return listener.uiSession.Load() } +func (listener *CommandListener) InternalUIActive() bool { return listener.uiSession.Load() != 0 } +func (listener *CommandListener) InternalUIEchoActive() bool { return listener.uiEcho.Load() } + +// BeginInternalUI acknowledges exclusive capture without changing X input +// focus. EndInternalUI waits for physical releases, and cannot close a newer UI. +func (listener *CommandListener) BeginInternalUI(ctx context.Context) (uint64, error) { + return listener.update_internal_ui(ctx, 0) +} +func (listener *CommandListener) EndInternalUI(ctx context.Context, session uint64) error { + if session == 0 { + return errors.New("missing internal UI session") + } + // Revoke promptly even when the acknowledgement must wait for a held key. + if session > listener.uiSequence.Load() { + return errors.New("unknown internal UI session") + } + for previous := listener.uiClose.Load(); previous < session; previous = listener.uiClose.Load() { + if listener.uiClose.CompareAndSwap(previous, session) { + break + } + } + _, err := listener.update_internal_ui(ctx, session) + return err +} +func (listener *CommandListener) update_internal_ui(ctx context.Context, closeSession uint64) (uint64, error) { + listener.mutex.Lock() + done := listener.done + listener.mutex.Unlock() + if done == nil { + return 0, errors.New("command listener is not running") + } + update := uiUpdate{ctx: ctx, closeSession: closeSession, result: make(chan uiReply, 1)} + select { + case listener.uiUpdates <- update: + case <-ctx.Done(): + return 0, ctx.Err() + case <-done: + return 0, errors.New("command listener stopped") + } + select { + case result := <-update.result: + return result.session, result.err + case <-done: + return 0, errors.New("command listener stopped") + } +} + +func (owner *commandOwner) begin_internal_ui() (uint64, error) { + if !owner.commandGrabsAllowed() || owner.learnMode || owner.ocrReview || owner.uiSession != 0 { + return 0, errors.New("internal UI input unavailable") + } + var revert C.int + C.XGetInputFocus(owner.device.display, &owner.uiFocus, &revert) + if owner.uiFocus == 0 || owner.uiFocus == 1 { + return 0, errors.New("no focused application") + } + owner.uiWindow = C.read_foreground(owner.device.display).window + if status := C.acquire_internal_keyboard(owner.device); status != 0 { + return 0, fmt.Errorf("internal keyboard capture failed: %d", int(status)) + } + owner.uiSession = owner.listener.uiSequence.Add(1) + owner.listener.uiSession.Store(owner.uiSession) + owner.listener.uiEcho.Store(true) + owner.listener.grabActive.Store(true) + return owner.uiSession, nil +} + +func (owner *commandOwner) dismiss_internal_ui() { + owner.uiSession = 0 + owner.listener.uiSession.Store(0) + C.reset_internal_compose(owner.device) + if len(owner.held) == 0 { + C.release_command_keyboard(owner.device) + owner.listener.uiEcho.Store(false) + owner.listener.grabActive.Store(false) + } +} +func (owner *commandOwner) report_ui_failure(err error) bool { + owner.listener.failures <- err + return false +} +func (owner *commandOwner) sync_internal_ui() bool { + if owner.uiSession != 0 { + var focus C.Window + var revert C.int + C.XGetInputFocus(owner.device.display, &focus, &revert) + requestedClose := owner.listener.uiClose.Load() == owner.uiSession + if requestedClose || !owner.commandGrabsAllowed() || focus != owner.uiFocus || C.read_foreground(owner.device.display).window != owner.uiWindow { + session := owner.uiSession + owner.dismiss_internal_ui() + // Retain ownership of the current chord until its releases arrive. + owner.bound = len(owner.held) != 0 + if !requestedClose && !owner.listener.enqueueSecureCommand(input.CommandEvent{Command: input.InternalUIDismiss, UISession: session}) { + return owner.report_ui_failure(errors.New("internal UI queue overflow")) + } + } + } + if len(owner.held) == 0 { + select { + case update := <-owner.listener.uiUpdates: + result := uiReply{err: update.ctx.Err()} + if result.err == nil { + if update.closeSession != 0 { + if update.closeSession == owner.uiSession { + owner.dismiss_internal_ui() + } + } else { + result.session, result.err = owner.begin_internal_ui() + } + } + update.result <- result + default: + } + } + return true +} + +func (owner *commandOwner) handle_internal_key(key C.CommandKey) bool { + owner.bound = true + owner.router.Handle(uint32(key.symbol), uint16(key.code), uint16(key.modifiers), key.pressed != 0) + if key.pressed == 0 { + return true + } + symbol := uint32(key.symbol) + if key.textSymbol != 0 { + symbol = uint32(key.textSymbol) + } + chord := owner.router.Chord(symbol, uint16(key.modifiers)) + // Reader modifiers and their initiating chord never become field contents. + if owner.router.IsModifier(uint32(key.symbol)) { + return true + } + if chord.CthulhuModifier && uint32(key.symbol) != 0xff1b { + return true + } + event := input.CommandEvent{Command: input.InternalUIKey, UISession: owner.uiSession, Timestamp: uint32(key.timestamp), Chord: chord, Text: C.GoString(&key.text[0])} + if uint32(key.symbol) == 0xff1b { + owner.dismiss_internal_ui() + } + if !owner.listener.enqueueSecureCommand(event) { + return owner.report_ui_failure(errors.New("internal UI queue overflow")) + } + return true +} diff --git a/internal/platform/xorg/foreground_pid.c b/internal/platform/xorg/foreground_pid.c new file mode 100644 index 0000000..4630936 --- /dev/null +++ b/internal/platform/xorg/foreground_pid.c @@ -0,0 +1,40 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "commands_native.h" +#include +#include + +int cthulhu_xres_client_pids_supported(Display *display) { + int event, error, major = 0, minor = 0; + cthulhu_x11_begin_read(display); + int supported = XResQueryExtension(display, &event, &error) && + XResQueryVersion(display, &major, &minor) && + (major > 1 || (major == 1 && minor >= 2)); + if (cthulhu_x11_end_read(display)) return 0; + return supported; +} + +// _NET_WM_PID is written by the application in its own PID namespace. XRes +// identifies the local connection from the server side instead. Unsupported +// servers, remote clients and disappeared clients retain the property fallback. +int cthulhu_xres_client_pid(Display *display, Window window) { + XResClientIdSpec spec = {.client = window, .mask = XRES_CLIENT_ID_PID_MASK}; + XResClientIdValue *ids = NULL; + long count = 0; + int pid = 0; + cthulhu_x11_begin_read(display); + if (XResQueryClientIds(display, 1, &spec, &count, &ids) == Success) { + for (long i = 0; i < count; i++) { + pid_t candidate = XResGetClientPid(&ids[i]); + if (candidate > 0) { + pid = candidate; + break; + } + } + } + if (ids) XResClientIdsDestroy(count, ids); + if (cthulhu_x11_end_read(display)) return 0; + return pid; +} diff --git a/internal/platform/xorg/grab_foreground_native_test.go b/internal/platform/xorg/grab_foreground_native_test.go new file mode 100644 index 0000000..7967033 --- /dev/null +++ b/internal/platform/xorg/grab_foreground_native_test.go @@ -0,0 +1,82 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "os" + "os/exec" + "runtime" + "testing" + "time" +) + +func TestNativeInputOnlyGrabForeground(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_GRAB_FOREGROUND") != "1" { + t.Skip("requires private X11 window-group fixture") + } + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-u", "../../../tests/x11_grab_fixture.py") + input, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + output, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { input.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(output) + if !scanner.Scan() { + t.Fatal("window fixture did not start") + } + var windows map[string]uint64 + if err := json.Unmarshal(scanner.Bytes(), &windows); err != nil { + t.Fatal(err) + } + reader := OpenForegroundReader() + if reader == nil { + t.Fatal("private X11 connection unavailable") + } + defer reader.Close() + for _, test := range []struct{ action, want string }{ + {"popup", "owner"}, + {"hidden", "grab"}, + {"other-group", "grab"}, + {"other-pid", "grab"}, + {"ordinary-window", "grab"}, + {"no-owner", "grab"}, + {"foreign-owner", "grab"}, + {"input-output-focus", "other"}, + {"ewmh", "other"}, + {"popup", "owner"}, + } { + t.Run(test.action, func(t *testing.T) { + if _, err := fmt.Fprintln(input, test.action); err != nil { + t.Fatal(err) + } + if !scanner.Scan() || scanner.Text() != "ready" { + t.Fatal("fixture command failed") + } + got := reader.Read() + if !got.Known || got.Window != windows[test.want] || got.PID != fixture.Process.Pid { + t.Fatalf("foreground = %+v; want %s owned by PID %d", got, test.want, fixture.Process.Pid) + } + if test.want == "owner" && (got.X != 20 || got.Y != 30 || got.Width != 600 || got.Height != 400) { + t.Fatalf("grab did not retain transient owner's bounds: %+v", got) + } + }) + } +} diff --git a/internal/platform/xorg/listener.go b/internal/platform/xorg/listener.go new file mode 100644 index 0000000..8520dd6 --- /dev/null +++ b/internal/platform/xorg/listener.go @@ -0,0 +1,399 @@ +package xorg + +/* +#cgo pkg-config: x11 xtst +#include +#include +#include +#include +#include +#include + +void cthulhuRecordKeyEvent(uintptr_t closure, int pressed, int keycode, uint32_t timestamp); + +static void cthulhuRecordCallback(XPointer closure, XRecordInterceptData *data) { + if (data->category != XRecordFromServer || data->data_len < 2) { + XRecordFreeData(data); + return; + } + + const unsigned char *event = (const unsigned char *)data->data; + if (event[0] == KeyPress || event[0] == KeyRelease) { + uint32_t timestamp; + memcpy(×tamp, event + 4, sizeof(timestamp)); + if (data->client_swapped) timestamp = __builtin_bswap32(timestamp); + cthulhuRecordKeyEvent((uintptr_t)closure, event[0] == KeyPress, event[1], timestamp); + } + XRecordFreeData(data); +} + +static unsigned char *cthulhuModifierKeycodes(Display *display) { + unsigned char *modifiers = calloc(256, sizeof(unsigned char)); + if (modifiers == NULL) { + return NULL; + } + int minKeycode = 0; + int maxKeycode = 0; + XDisplayKeycodes(display, &minKeycode, &maxKeycode); + + for (int keycode = minKeycode; keycode <= maxKeycode; keycode++) { + int symbolCount = 0; + KeySym *symbols = XGetKeyboardMapping(display, keycode, 1, &symbolCount); + if (symbols == NULL) { + continue; + } + for (int index = 0; index < symbolCount; index++) { + KeySym symbol = symbols[index]; + if (symbol == XK_Control_L || symbol == XK_Control_R || + symbol == XK_Shift_L || symbol == XK_Shift_R) { + modifiers[keycode] = 1; + } + } + XFree(symbols); + } + return modifiers; +} + +static char **cthulhuKeyNames(Display *display) { + char **names = calloc(256, sizeof(char *)); + if (names == NULL) { + return NULL; + } + int minKeycode = 0; + int maxKeycode = 0; + XDisplayKeycodes(display, &minKeycode, &maxKeycode); + int symbolsPerKeycode = 0; + KeySym *symbols = XGetKeyboardMapping( + display, minKeycode, maxKeycode - minKeycode + 1, &symbolsPerKeycode); + if (symbols == NULL) { + free(names); + return NULL; + } + for (int keycode = minKeycode; keycode <= maxKeycode; keycode++) { + int offset = (keycode - minKeycode) * symbolsPerKeycode; + for (int index = 0; index < symbolsPerKeycode; index++) { + KeySym symbol = symbols[offset + index]; + if (symbol == NoSymbol) { + continue; + } + const char *name = XKeysymToString(symbol); + if (name != NULL) { + names[keycode] = strdup(name); + break; + } + } + } + XFree(symbols); + return names; +} + +static XRecordRange *cthulhuAllocKeyRange(Display *display) { + XRecordRange *range = XRecordAllocRange(); + if (range != NULL) { + range->device_events.first = KeyPress; + range->device_events.last = KeyRelease; + } + return range; +} + +static XRecordContext cthulhuCreateKeyContext(Display *display, XRecordRange *range) { + XRecordClientSpec client = XRecordAllClients; + return XRecordCreateContext(display, 0, &client, 1, &range, 1); +} + +static XPointer cthulhuClosure(uintptr_t closure) { + return (XPointer)(uintptr_t)closure; +} + +static XRecordInterceptProc cthulhuRecordProc() { + return cthulhuRecordCallback; +} +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + "runtime" + "sync" + "sync/atomic" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +const eventQueueCapacity = 32 + +type Listener struct { + secureMutex sync.Mutex + secure atomic.Bool + intent input.IntentTracker + keyRepeats input.RepeatTracker // XRecord owner, under secureMutex. + controlDisplay *C.Display + recordDisplay *C.Display + recordContext C.XRecordContext + enableDone chan int + stopDone chan error + events chan input.Event + modifierCodes input.ModifierKeycodes + keyNames [256]string + overflow atomic.Uint64 + started bool + stopping bool + stopped bool + stopError error + registryID uint64 + mutex sync.Mutex +} + +var listenerRegistry = struct { + mutex sync.Mutex + nextID uint64 + listeners map[uint64]*Listener +}{listeners: make(map[uint64]*Listener)} + +func New() *Listener { + return &Listener{events: make(chan input.Event, eventQueueCapacity)} +} + +func (listener *Listener) Start(ctx context.Context) error { + if err := ctx.Err(); err != nil { + return err + } + + listener.mutex.Lock() + if listener.started { + listener.mutex.Unlock() + return errors.New("X11 listener already started") + } + listener.mutex.Unlock() + + controlDisplay := C.XOpenDisplay(nil) + if controlDisplay == nil { + return errors.New("X11 listener startup: no display") + } + recordDisplay := C.XOpenDisplay(nil) + if recordDisplay == nil { + C.XCloseDisplay(controlDisplay) + return errors.New("X11 listener startup: no record display") + } + + var major, minor C.int + if C.XRecordQueryVersion(controlDisplay, &major, &minor) == 0 { + C.XCloseDisplay(recordDisplay) + C.XCloseDisplay(controlDisplay) + return errors.New("X11 listener startup: XRecord unavailable") + } + + keyRange := C.cthulhuAllocKeyRange(controlDisplay) + if keyRange == nil { + C.XCloseDisplay(recordDisplay) + C.XCloseDisplay(controlDisplay) + return errors.New("X11 listener startup: allocate record range") + } + recordContext := C.cthulhuCreateKeyContext(controlDisplay, keyRange) + C.XFree(unsafe.Pointer(keyRange)) + if recordContext == 0 { + C.XCloseDisplay(recordDisplay) + C.XCloseDisplay(controlDisplay) + return errors.New("X11 listener startup: create record context") + } + + listenerRegistry.mutex.Lock() + listenerRegistry.nextID++ + listener.registryID = listenerRegistry.nextID + listenerRegistry.listeners[listener.registryID] = listener + listenerRegistry.mutex.Unlock() + + listener.mutex.Lock() + listener.controlDisplay = controlDisplay + listener.recordDisplay = recordDisplay + listener.recordContext = recordContext + modifierCodes := C.cthulhuModifierKeycodes(controlDisplay) + if modifierCodes == nil { + listener.mutex.Unlock() + listenerRegistry.mutex.Lock() + delete(listenerRegistry.listeners, listener.registryID) + listenerRegistry.mutex.Unlock() + C.XRecordFreeContext(controlDisplay, recordContext) + C.XCloseDisplay(recordDisplay) + C.XCloseDisplay(controlDisplay) + return errors.New("X11 listener startup: allocate modifier keycodes") + } + keyNames := C.cthulhuKeyNames(controlDisplay) + if keyNames == nil { + C.free(unsafe.Pointer(modifierCodes)) + listener.mutex.Unlock() + listenerRegistry.mutex.Lock() + delete(listenerRegistry.listeners, listener.registryID) + listenerRegistry.mutex.Unlock() + C.XRecordFreeContext(controlDisplay, recordContext) + C.XCloseDisplay(recordDisplay) + C.XCloseDisplay(controlDisplay) + return errors.New("X11 listener startup: allocate key names") + } + for keycode := range listener.modifierCodes { + listener.modifierCodes[keycode] = (*[256]C.uchar)(unsafe.Pointer(modifierCodes))[keycode] != 0 + keyName := (*[256]*C.char)(unsafe.Pointer(keyNames))[keycode] + if keyName != nil { + listener.keyNames[keycode] = C.GoString(keyName) + C.free(unsafe.Pointer(keyName)) + } + } + C.free(unsafe.Pointer(modifierCodes)) + C.free(unsafe.Pointer(keyNames)) + listener.enableDone = make(chan int, 1) + listener.started = true + listener.stopped = false + listener.mutex.Unlock() + + closure := C.cthulhuClosure(C.uintptr_t(uintptr(listener.registryID))) + go func() { + runtime.LockOSThread() + status := C.XRecordEnableContext( + recordDisplay, + recordContext, + C.cthulhuRecordProc(), + closure, + ) + listener.enableDone <- int(status) + }() + return nil +} + +func (listener *Listener) Stop(ctx context.Context) error { + listener.mutex.Lock() + if !listener.started { + listener.mutex.Unlock() + return nil + } + if listener.stopped { + stopError := listener.stopError + listener.mutex.Unlock() + return stopError + } + if listener.stopping { + stopDone := listener.stopDone + listener.mutex.Unlock() + select { + case stopError := <-stopDone: + return stopError + case <-ctx.Done(): + return fmt.Errorf("wait for X11 listener stop: %w", ctx.Err()) + } + } + controlDisplay := listener.controlDisplay + recordDisplay := listener.recordDisplay + recordContext := listener.recordContext + enableDone := listener.enableDone + listener.stopping = true + stopDone := make(chan error, 1) + listener.stopDone = stopDone + listener.mutex.Unlock() + + go listener.stop(controlDisplay, recordDisplay, recordContext, enableDone, stopDone) + + select { + case stopError := <-stopDone: + return stopError + case <-ctx.Done(): + return fmt.Errorf("wait for X11 listener stop: %w", ctx.Err()) + } +} + +func (listener *Listener) stop( + controlDisplay *C.Display, + recordDisplay *C.Display, + recordContext C.XRecordContext, + enableDone <-chan int, + stopDone chan<- error, +) { + var stopError error + if C.XRecordDisableContext(controlDisplay, recordContext) == 0 { + stopError = errors.New("X11 listener stop: disable record context") + } + C.XSync(controlDisplay, 0) + + select { + case status := <-enableDone: + if status == 0 { + stopError = errors.Join(stopError, errors.New("X11 listener stop: record loop exited with failure")) + } + } + + if C.XRecordFreeContext(controlDisplay, recordContext) == 0 { + stopError = errors.Join(stopError, errors.New("X11 listener stop: free record context")) + } + C.XCloseDisplay(recordDisplay) + C.XCloseDisplay(controlDisplay) + + listenerRegistry.mutex.Lock() + delete(listenerRegistry.listeners, listener.registryID) + listenerRegistry.mutex.Unlock() + + listener.mutex.Lock() + listener.stopped = true + listener.stopError = stopError + listener.mutex.Unlock() + stopDone <- stopError +} + +func (listener *Listener) RecentInput() input.Activity { return listener.intent.RecentInput() } + +func (listener *Listener) RecentIntent() input.Intent { return listener.intent.RecentIntent() } + +func (listener *Listener) Events() <-chan input.Event { + return listener.events +} + +func (listener *Listener) ModifierKeycodes() input.ModifierKeycodes { + listener.mutex.Lock() + defer listener.mutex.Unlock() + return listener.modifierCodes +} + +func (listener *Listener) Overflow() uint64 { + return listener.overflow.Load() +} + +//export cthulhuRecordKeyEvent +func cthulhuRecordKeyEvent(closure uintptr, pressed C.int, keycode C.int, timestamp C.uint32_t) { + listenerRegistry.mutex.Lock() + listener := listenerRegistry.listeners[uint64(closure)] + listenerRegistry.mutex.Unlock() + if listener == nil { + return + } + listener.secureMutex.Lock() + defer listener.secureMutex.Unlock() + if listener.secure.Load() { + return + } + + eventKeycode := uint8(keycode) + event := input.NewKeyEvent(eventKeycode, pressed != 0, listener.keyNames[eventKeycode]) + event.Timestamp = uint32(timestamp) + event.Repeat = listener.keyRepeats.Observe(event) + listener.intent.Observe(event) + select { + case listener.events <- event: + default: + listener.overflow.Add(1) + } +} + +func (listener *Listener) SetSecureInputActive(active bool) { + listener.secureMutex.Lock() + defer listener.secureMutex.Unlock() + listener.secure.Store(active) + listener.intent.Reset() + listener.keyRepeats.Reset() + for { + select { + case <-listener.events: + default: + return + } + } +} diff --git a/internal/platform/xorg/listener_native_test.go b/internal/platform/xorg/listener_native_test.go new file mode 100644 index 0000000..f951ce5 --- /dev/null +++ b/internal/platform/xorg/listener_native_test.go @@ -0,0 +1,1141 @@ +package xorg + +import ( + "bufio" + "context" + "fmt" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestNativeModifierPressRelease(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + for range 2 { + listener := New() + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + if err := listener.Start(ctx); err != nil { + cancel() + t.Fatal(err) + } + // Allow the asynchronous XRecord enable request to reach the server. + time.Sleep(50 * time.Millisecond) + if err := exec.Command("xdotool", "key", "Control_L", "Shift_L", "q").Run(); err != nil { + t.Fatal(err) + } + presses, releases := 0, 0 + seenNames := map[string]bool{} + for presses < 2 || releases < 2 { + select { + case event := <-listener.Events(): + if listener.ModifierKeycodes().Contains(event.Keycode) { + seenNames[event.Name] = true + if event.Pressed { + presses++ + } else { + releases++ + } + } + case <-ctx.Done(): + t.Fatal("lost Control/Shift press or release") + } + } + if listener.Overflow() != 0 { + t.Fatal("unexpected native overflow") + } + if !seenNames["Control_L"] || !seenNames["Shift_L"] { + t.Fatalf("normalized modifier names = %v", seenNames) + } + if err := exec.Command("xdotool", "key", "F1", "Tab", "Left").Run(); err != nil { + t.Fatal(err) + } + seenKinds := map[string]input.KeyKind{} + for len(seenKinds) < 3 { + select { + case event := <-listener.Events(): + if event.Pressed && (event.Name == "F1" || event.Name == "Tab" || event.Name == "Left") { + seenKinds[event.Text] = event.Kind + } + case <-ctx.Done(): + t.Fatalf("lost named non-printable key events: %v", seenKinds) + } + } + if seenKinds["f1"] != input.KeyFunction || seenKinds["tab"] != input.KeyAction || seenKinds["left"] != input.KeyNavigation { + t.Fatalf("normalized non-printable keys = %v", seenKinds) + } + // The events above establish XRecord readiness. Exercise server + // autorepeat, then a real release/new press of the same movement key. + waitUp := func(pressed bool) input.Event { + t.Helper() + for { + select { + case event := <-listener.Events(): + if event.Name == "Up" && event.Pressed == pressed { + return event + } + case <-ctx.Done(): + t.Fatal("lost movement key event") + } + } + } + if err := exec.CommandContext(ctx, "xdotool", "keydown", "Up").Run(); err != nil { + t.Fatal(err) + } + if waitUp(true).Repeat || !waitUp(true).Repeat { + t.Fatal("held-key repeat was not distinguished from first press") + } + injected := make(chan error, 1) + go func() { + if err := exec.CommandContext(ctx, "xdotool", "keyup", "Up").Run(); err != nil { + injected <- err + return + } + injected <- exec.CommandContext(ctx, "xdotool", "key", "F2").Run() + }() + // Drain past the release using an ordered marker. A classic repeat's + // release may already be queued before the actual key-up. + released := false + for !released { + select { + case event := <-listener.Events(): + if event.Name == "F2" && event.Pressed { + released = true + } + case <-ctx.Done(): + t.Fatal("lost key release marker") + } + } + if err := <-injected; err != nil { + t.Fatal(err) + } + if err := exec.CommandContext(ctx, "xdotool", "key", "Up").Run(); err != nil { + t.Fatal(err) + } + if waitUp(true).Repeat { + t.Fatal("fresh movement press classified as repeat") + } + if err := listener.Stop(ctx); err != nil { + t.Fatal(err) + } + if err := listener.Stop(ctx); err != nil { + t.Fatal(err) + } + cancel() + } +} + +func TestNativeLearnModeCapturesKeysAndRestoresCommands(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second) + defer cancel() + listener := NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + key := func(name string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", name).CombinedOutput(); err != nil { + t.Fatalf("send %s: %v %s", name, err, out) + } + } + want := func(command input.Command) input.CommandEvent { + t.Helper() + select { + case event := <-listener.Commands(): + if event.Command != command { + t.Fatalf("got %+v, want %s", event, command) + } + return event + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + return input.CommandEvent{} + } + for _, opener := range []string{"Insert+h", "Insert+F1"} { + key(opener) + want(input.ToggleLearnMode) + if !listener.LearnModeActive() || !listener.CommandGrabActive() { + t.Fatal("learn mode released keyboard after opening chord") + } + key("q") + if event := want(input.LearnKey); event.KeyName != "q" || event.Chord.Symbol != 'q' { + t.Fatalf("learn key = %+v", event) + } + key("Insert+q") + want(input.LearnKey) + if event := want(input.LearnKey); event.Chord.Symbol != 'q' || !event.Chord.CthulhuModifier { + t.Fatalf("learned quit chord = %+v", event) + } + key("F1") + want(input.LearnDocumentation) + if listener.LearnModeActive() { + t.Fatal("F1 did not release learn mode") + } + } + key("Insert+h") + want(input.ToggleLearnMode) + key("F2") + want(input.LearnDefaultShortcuts) + key("Insert+F1") + want(input.ToggleLearnMode) + key("F3") + want(input.LearnApplicationShortcuts) + key("Insert+h") + want(input.ToggleLearnMode) + key("Escape") + want(input.ToggleLearnMode) + key("Insert+h") + want(input.ToggleLearnMode) + key("Insert+F1") + want(input.LearnKey) // The modifier itself is also named in learn mode. + want(input.ToggleLearnMode) + if listener.LearnModeActive() || listener.CommandGrabActive() { + t.Fatal("exit did not release keyboard") + } + key("Insert+F1") + want(input.ToggleLearnMode) + key("Insert+h") + want(input.LearnKey) + want(input.ToggleLearnMode) + if listener.LearnModeActive() { + t.Fatal("Cthulhu H did not exit learn mode") + } + key("Insert+q") + want(input.Quit) + key("Insert+h") + want(input.ToggleLearnMode) + listener.SetSecureInputActive(true) + for listener.LearnModeActive() || listener.CommandGrabActive() { + select { + case <-time.After(time.Millisecond): + case <-ctx.Done(): + t.Fatal("secure mode retained learn keyboard grab") + } + } + for listener.commandsApplied.Load() { + select { + case <-time.After(time.Millisecond): + case <-ctx.Done(): + t.Fatal("secure mode retained command grabs") + } + } + listener.SetSecureInputActive(false) + for !listener.CommandGrabsEnabled() { + select { + case <-time.After(time.Millisecond): + case <-ctx.Done(): + t.Fatal("unlock did not restore command grabs") + } + } + key("Insert+F1") + if event := want(input.ToggleLearnMode); !event.LearnModeStarted { + t.Fatal("learn mode did not restart after secure mode") + } + key("Escape") + want(input.ToggleLearnMode) +} + +func TestNativeLearnModeKeepsKeysFromFocusedApplication(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second) + defer cancel() + logfile, err := os.CreateTemp(t.TempDir(), "xev-keys-*") + if err != nil { + t.Fatal(err) + } + defer logfile.Close() + probe := exec.CommandContext(ctx, "xev", "-name", "Cthulhu Learn Capture", "-event", "keyboard") + probe.Stdout = logfile + if err := probe.Start(); err != nil { + t.Fatal(err) + } + defer func() { _ = probe.Process.Kill(); _ = probe.Wait() }() + window := "" + for window == "" { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Cthulhu Learn Capture$").Output() + if err == nil { + window = strings.TrimSpace(string(output)) + } + if ctx.Err() != nil { + t.Fatal(ctx.Err()) + } + time.Sleep(10 * time.Millisecond) + } + if err := exec.CommandContext(ctx, "xdotool", "windowfocus", window).Run(); err != nil { + t.Fatal(err) + } + listener := NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + for _, name := range []string{"Insert+h", "z", "Escape", "y"} { + if output, err := exec.CommandContext(ctx, "xdotool", "key", name).CombinedOutput(); err != nil { + t.Fatalf("send %s: %v %s", name, err, output) + } + } + if err := probe.Process.Kill(); err != nil { + t.Fatal(err) + } + _ = probe.Wait() + contents, err := os.ReadFile(logfile.Name()) + if err != nil { + t.Fatal(err) + } + if strings.Contains(string(contents), "keysym 0x7a, z") || !strings.Contains(string(contents), "keysym 0x79, y") { + t.Fatalf("learned z leaked or ordinary y failed to reach application: %s", contents) + } +} + +func TestNativeBrowseKeyTransitions(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser X server") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + listener := NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + key := func(args ...string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + ready := func(want bool) { + t.Helper() + tick := time.NewTicker(time.Millisecond) + defer tick.Stop() + for listener.browseApplied.Load() != want { + select { + case <-tick.C: + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + command := func(want input.Command) { + t.Helper() + select { + case got := <-listener.Commands(): + if got.Command != want { + t.Fatalf("command %s want %s", got.Command, want) + } + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + listener.SetBrowseNavigation(true) + ready(true) + for _, tc := range []struct { + letter string + want input.Command + }{ + {"h", input.DocumentNextHeading}, + {"k", input.DocumentNextLink}, + {"b", input.DocumentNextButton}, + {"x", input.DocumentNextCheckBox}, + {"l", input.DocumentNextList}, + {"s", input.DocumentNextSeparator}, + {"q", input.DocumentNextBlockQuote}, + {"c", input.DocumentNextComboBox}, + {"e", input.DocumentNextEntry}, + {"f", input.DocumentNextFormField}, + {"g", input.DocumentNextImage}, + {"m", input.DocumentNextLandmark}, + {"i", input.DocumentNextListItem}, + {"d", input.DocumentNextLiveRegion}, + {"p", input.DocumentNextParagraph}, + {"r", input.DocumentNextRadioButton}, + {"t", input.DocumentNextTable}, + {"u", input.DocumentNextUnvisitedLink}, + {"v", input.DocumentNextVisitedLink}, + {"a", input.DocumentNextClickable}, + {"o", input.DocumentNextChunk}, + } { + key("keydown", tc.letter) + command(tc.want) + key("keyup", tc.letter) + } + key("key", "shift+x") + command(input.DocumentPreviousCheckBox) + for _, tc := range []struct { + key string + want input.Command + }{ + {"Down", input.DocumentCaretNextLine}, + {"Up", input.DocumentCaretPreviousLine}, + {"Right", input.DocumentCaretNextCharacter}, + {"Left", input.DocumentCaretPreviousCharacter}, + {"ctrl+Right", input.DocumentCaretNextWord}, + {"ctrl+Left", input.DocumentCaretPreviousWord}, + {"Home", input.DocumentCaretLineStart}, + {"End", input.DocumentCaretLineEnd}, + {"ctrl+Home", input.DocumentCaretDocumentStart}, + {"ctrl+End", input.DocumentCaretDocumentEnd}, + } { + key("key", tc.key) + command(tc.want) + } + for _, level := range []int{1, 2, 3, 4, 5, 6} { + key("key", fmt.Sprintf("%d", level)) + command(input.Command(fmt.Sprintf("document-next-heading-at-level-%d", level))) + key("key", fmt.Sprintf("shift+%d", level)) + command(input.Command(fmt.Sprintf("document-previous-heading-at-level-%d", level))) + } + key("key", "Return") + command(input.DocumentActivate) + listener.SetNativeButtonFocus(true) + for !listener.nativeButtonApplied.Load() { + select { + case <-ctx.Done(): + t.Fatal("button focus policy was not applied") + case <-time.After(time.Millisecond): + } + } + key("key", "Return") + select { + case got := <-listener.Commands(): + t.Fatalf("native button Return was consumed as %s", got.Command) + case <-time.After(100 * time.Millisecond): + } + listener.SetNativeButtonFocus(false) + for listener.nativeButtonApplied.Load() { + select { + case <-ctx.Done(): + t.Fatal("button focus policy was not cleared") + case <-time.After(time.Millisecond): + } + } + key("key", "Return") + command(input.DocumentActivate) + key("keydown", "h") + command(input.DocumentNextHeading) + // The press has reached X11 before changing policy. Its release must remain + // owned by the original chord even though the next h will pass through. + listener.SetBrowseNavigation(false) + key("keyup", "h") + ready(false) + key("key", "alt+shift+k", "alt+shift+a") + select { + case got := <-listener.Commands(): + t.Fatalf("list shortcut consumed outside browse mode: %s", got.Command) + case <-time.After(100 * time.Millisecond): + } + listener.SetBrowseNavigation(true) + ready(true) + key("key", "Num_Lock") + key("key", "shift+h") + command(input.DocumentPreviousHeading) + key("key", "Num_Lock") + key("keydown", "Insert", "keydown", "a", "keyup", "Insert", "keyup", "a") + command(input.ToggleDocumentMode) + key("keydown", "Insert", "keydown", "ctrl", "keydown", "space", "keyup", "space", "keyup", "ctrl", "keyup", "Insert") + command(input.ApplicationPreferences) + key("key", "Insert+shift+space") + command(input.ApplicationPreferences) + key("key", "Insert+ctrl+shift+space") + command(input.ChooseApplicationPreferences) + key("key", "h") + command(input.DocumentNextHeading) + // Chromium can move raw X input focus into a child while its foreground + // client remains the same. Browse arrows must remain owned across that + // transition; an exact XGetInputFocus comparison loses every later arrow. + parentOutput, err := exec.CommandContext(ctx, "xdotool", "getwindowfocus").Output() + if err != nil { + t.Fatal(err) + } + parent := strings.TrimSpace(string(parentOutput)) + childFocus := exec.CommandContext(ctx, "python3", "tests/x11_focus_child.py", parent) + childFocus.Dir = "../../.." + childInput, err := childFocus.StdinPipe() + if err != nil { + t.Fatal(err) + } + childOutput, err := childFocus.StdoutPipe() + if err != nil { + t.Fatal(err) + } + if err := childFocus.Start(); err != nil { + t.Fatal(err) + } + defer childFocus.Process.Kill() + childID := bufio.NewScanner(childOutput) + if !childID.Scan() { + t.Fatalf("child focus fixture did not start: %v", childID.Err()) + } + if got, err := exec.CommandContext(ctx, "xdotool", "getwindowfocus").Output(); err != nil || + strings.TrimSpace(string(got)) != childID.Text() { + t.Fatalf("X input focus did not move to child: %q, %v", got, err) + } + key("key", "Down") + command(input.DocumentCaretNextLine) + // Native focus keys must still reach the application after consecutive + // browse arrows; Steam uses Tab and Escape for its own navigation. + key("key", "Up") + command(input.DocumentCaretPreviousLine) + key("key", "Down") + command(input.DocumentCaretNextLine) + for listener.grabActive.Load() { + select { + case <-time.After(time.Millisecond): + case <-ctx.Done(): + t.Fatal("browse keyboard grab was not released") + } + } + events, err := os.CreateTemp(t.TempDir(), "child-keys-*.log") + if err != nil { + t.Fatal(err) + } + defer events.Close() + xev := exec.CommandContext(ctx, "stdbuf", "-oL", "xev", "-id", childID.Text(), "-event", "keyboard") + xev.Stdout = events + if err := xev.Start(); err != nil { + t.Fatal(err) + } + defer xev.Process.Kill() + time.Sleep(50 * time.Millisecond) + key("key", "Tab") + key("key", "Escape") + for { + contents, err := os.ReadFile(events.Name()) + if err != nil { + t.Fatal(err) + } + if strings.Contains(string(contents), "keysym 0xff09, Tab") && + strings.Contains(string(contents), "keysym 0xff1b, Escape") { + break + } + select { + case <-time.After(10 * time.Millisecond): + case <-ctx.Done(): + t.Fatalf("Tab/Escape did not reach the focused child after browse arrows: %s", contents) + } + } + _ = xev.Process.Kill() + _ = xev.Wait() + if _, err := childInput.Write([]byte("\n")); err != nil { + t.Fatal(err) + } + if err := childFocus.Wait(); err != nil { + t.Fatal(err) + } + + // Browse grabs are updated asynchronously after focus changes. Every + // passively grabbed browse key must be replayed if it arrives while the + // recorded browser window is no longer focused. + xterm := exec.CommandContext(ctx, "xterm", "-T", "Cthulhu Browse Replay", "-e", "bash", "-c", "IFS= read -r -n 1 value; test \"$value\" = q") + if err := xterm.Start(); err != nil { + t.Fatal(err) + } + window := "" + for window == "" { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Cthulhu Browse Replay$").Output() + if err == nil { + window = strings.TrimSpace(string(output)) + } + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(10 * time.Millisecond): + } + } + key("windowfocus", window) + key("key", "q") + if err := xterm.Wait(); err != nil { + t.Fatalf("stale browse grab did not replay q to the new focus: %v", err) + } + if err := listener.Stop(ctx); err != nil { + t.Fatal(err) + } + // Reacquisition proves cleanup released both static and browse grabs. + next := NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := next.Start(ctx); err != nil { + t.Fatal(err) + } + defer next.Stop(context.Background()) +} + +func TestNativeCommandGrabSuspensionAndRestoration(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + listener := NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + ready := func(listener *CommandListener, want bool) { + t.Helper() + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + for listener.commandsApplied.Load() != want { + select { + case <-ticker.C: + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + } + + ready(listener, true) + listener.SetCommandGrabs(false) + ready(listener, false) + + reacquire := NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := reacquire.Start(ctx); err != nil { + t.Fatalf("suspended listener still owned command grabs: %v", err) + } + if err := reacquire.Stop(context.Background()); err != nil { + t.Fatal(err) + } + + listener.SetCommandGrabs(true) + ready(listener, true) + select { + case err := <-listener.Failures(): + t.Fatal(err) + default: + } +} + +func TestNativeActiveWindowIsXTerm(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + xterm := exec.CommandContext(ctx, "xterm", "-T", "Cthulhu XTerm Match", "-e", "sleep", "3") + if err := xterm.Start(); err != nil { + t.Fatal(err) + } + defer func() { + _ = xterm.Wait() + }() + var window string + for window == "" { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--name", "^Cthulhu XTerm Match$").Output() + if err == nil { + window = strings.TrimSpace(string(output)) + } + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(10 * time.Millisecond): + } + } + if err := exec.CommandContext(ctx, "xdotool", "windowfocus", window).Run(); err != nil { + t.Fatal(err) + } + for !ActiveWindowIsXTerm() { + select { + case <-ctx.Done(): + t.Fatal("active X11 window was not identified as XTerm") + case <-time.After(10 * time.Millisecond): + } + } +} + +func TestNativeDispatchBeforeRelease(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + for _, layout := range []input.KeyboardLayout{input.DesktopKeyboardLayout, input.LaptopKeyboardLayout} { + for _, modifierFirst := range []bool{false, true} { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + listener := NewCommands([]string{"Insert"}, layout) + if err := listener.Start(ctx); err != nil { + cancel() + t.Fatal(err) + } + defer listener.Stop(context.Background()) + heldKeys := make(map[string]bool) + defer func() { + // A failed press-time assertion must not leave synthetic keys + // held on the display shared by the remaining native tests. + cleanupContext, cleanupCancel := context.WithTimeout(context.Background(), time.Second) + defer cleanupCancel() + for name := range heldKeys { + if out, err := exec.CommandContext(cleanupContext, "xdotool", "keyup", name).CombinedOutput(); err != nil { + t.Errorf("release held %s: %v %s", name, err, out) + } + } + }() + key := func(args ...string) { + t.Helper() + if args[0] == "keydown" { + heldKeys[args[1]] = true + } + if out, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + if args[0] == "keyup" { + delete(heldKeys, args[1]) + } + } + type bindingCase struct { + keys []string + want input.Command + } + cases := []bindingCase{ + {[]string{"Insert", "t"}, input.PresentTime}, + {[]string{"Insert", "t"}, input.PresentDate}, + {[]string{"Insert", "Shift_L", "c"}, input.PresentClipboard}, + {[]string{"Insert", "Control_L", "h"}, input.ShowSpeechHistory}, + {[]string{"Insert", "Shift_L", "d"}, input.ToggleSpeechMonitor}, + {[]string{"Insert", "space"}, input.Preferences}, + {[]string{"Insert", "Control_L", "Up"}, input.ObjectParent}, + {[]string{"Insert", "h"}, input.ToggleLearnMode}, + {[]string{"Insert", "a"}, input.ToggleDocumentMode}, + } + if layout == input.DesktopKeyboardLayout { + cases = append(cases, bindingCase{[]string{"KP_Add"}, input.ReadAll}, bindingCase{[]string{"Insert", "equal"}, input.PresentCellFormula}) + cases = append(cases, bindingCase{[]string{"KP_Enter"}, input.WhereAmI}, bindingCase{[]string{"KP_Up"}, input.ReviewCurrentLine}) + cases = append(cases, bindingCase{[]string{"Insert", "KP_Enter"}, input.PresentWindowTitle}) + cases = append(cases, + bindingCase{[]string{"KP_Down"}, input.ReviewCurrentCharacter}, + bindingCase{[]string{"KP_Down"}, input.ReviewPhoneticCharacter}, + bindingCase{[]string{"KP_Begin"}, input.ReviewCurrentWord}, + bindingCase{[]string{"KP_Begin"}, input.ReviewSpellWord}, + bindingCase{[]string{"KP_Begin"}, input.ReviewPhoneticWord}) + } else { + cases = append(cases, bindingCase{[]string{"Insert", "semicolon"}, input.ReadAll}) + cases = append(cases, bindingCase{[]string{"Insert", "Return"}, input.WhereAmI}, bindingCase{[]string{"Insert", "i"}, input.ReviewCurrentLine}) + cases = append(cases, bindingCase{[]string{"Insert", "slash"}, input.PresentWindowTitle}) + cases = append(cases, + bindingCase{[]string{"Insert", "comma"}, input.ReviewCurrentCharacter}, + bindingCase{[]string{"Insert", "comma"}, input.ReviewPhoneticCharacter}, + bindingCase{[]string{"Insert", "k"}, input.ReviewCurrentWord}, + bindingCase{[]string{"Insert", "k"}, input.ReviewSpellWord}, + bindingCase{[]string{"Insert", "k"}, input.ReviewPhoneticWord}) + } + cases = append(cases, bindingCase{[]string{"Insert", "q"}, input.Quit}) + for _, tc := range cases { + for _, name := range tc.keys { + key("keydown", name) + } + select { + case got := <-listener.Commands(): + if got.Command != tc.want { + t.Fatalf("command = %s, want %s", got.Command, tc.want) + } + if tc.want == input.ToggleLearnMode && !got.LearnModeStarted { + t.Fatal("Cthulhu+H did not start learn mode on press") + } + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatalf("no press-time %s: %v", tc.want, ctx.Err()) + } + // Cancellation occurs while Quit is still physically held. + if tc.want == input.Quit { + listener.cancel() + } + for i := range tc.keys { + index := len(tc.keys) - 1 - i + if modifierFirst { + index = i + } + key("keyup", tc.keys[index]) + } + if tc.want == input.ToggleLearnMode { + // Leave learn mode before checking ordinary shortcuts again. + key("keydown", "Escape") + select { + case got := <-listener.Commands(): + if got.Command != input.ToggleLearnMode || got.LearnModeStarted { + t.Fatalf("learn mode exit = %+v", got) + } + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatalf("no press-time learn mode exit: %v", ctx.Err()) + } + key("keyup", "Escape") + } + } + if err := listener.Stop(ctx); err != nil { + t.Fatal(err) + } + select { + case got := <-listener.Commands(): + t.Fatalf("release dispatched %s", got.Command) + default: + } + cancel() + } + } +} + +func TestNativeSecureInputDropsKeysAndRestoresGrabs(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + keys := New() + if err := keys.Start(ctx); err != nil { + t.Fatal(err) + } + defer keys.Stop(context.Background()) + commands := NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := commands.Start(ctx); err != nil { + t.Fatal(err) + } + defer commands.Stop(context.Background()) + commands.SetBrowseNavigation(true) + key := func(name string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", name).CombinedOutput(); err != nil { + t.Fatalf("key: %v %s", err, out) + } + } + // A received event establishes that the XRecord listener is ready. + time.Sleep(50 * time.Millisecond) + key("F1") + select { + case <-keys.Events(): + case <-ctx.Done(): + t.Fatal("XRecord did not become ready") + } + keys.SetSecureInputActive(true) + commands.SetSecureInputActive(true) + commands.SetCommandGrabs(true) // Simulate foreground polling during lock. + for commands.commandsApplied.Load() { + select { + case <-time.After(time.Millisecond): + case <-ctx.Done(): + t.Fatal("secure mode did not release native grabs") + } + } + // Another X11 client must actually be able to take the same passive grabs. + other := NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := other.Start(ctx); err != nil { + t.Fatalf("secure listener retained grabs: %v", err) + } + if err := other.Stop(context.Background()); err != nil { + t.Fatal(err) + } + key("h") + key("Return") + select { + case event := <-keys.Events(): + t.Fatalf("secure input was captured: %v", event.Kind) + case <-time.After(100 * time.Millisecond): + } + select { + case <-commands.Commands(): + t.Fatal("command executed during secure input") + default: + } + if keys.RecentInput().Sequence != 0 { + t.Fatal("secure input retained presentation intent") + } + keys.SetSecureInputActive(false) + commands.SetSecureInputActive(false) + for !commands.CommandGrabsEnabled() { + select { + case <-time.After(time.Millisecond): + case <-ctx.Done(): + t.Fatal("unlock did not restore grabs") + } + } + key("F1") + select { + case event := <-keys.Events(): + if event.Name != "F1" { + t.Fatalf("unlock replayed stale key %q", event.Name) + } + case <-ctx.Done(): + t.Fatal("unlock did not restore XRecord events") + } +} + +func TestNativeCustomBindingsUpdateAndRelease(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + // Own a foreground client; browse-only grabs deliberately replay when + // no client owns focus or the foreground window has changed. + probe := exec.CommandContext(ctx, "xev", "-name", "Cthulhu Custom Bindings", "-event", "keyboard") + if err := probe.Start(); err != nil { + t.Fatal(err) + } + defer func() { _ = probe.Process.Kill(); _ = probe.Wait() }() + window := "" + for window == "" { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Cthulhu Custom Bindings$").Output() + if err == nil { + window = strings.TrimSpace(string(output)) + } + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + if err := exec.CommandContext(ctx, "xdotool", "windowfocus", window).Run(); err != nil { + t.Fatal(err) + } + listener := NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + custom := []input.BindingOverride{ + {Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Preferences, Keys: []string{"Cthulhu+Ctrl+Alt+y", "F9"}}, + {Layout: input.DesktopKeyboardLayout, Scope: "browse", Command: input.DocumentNextHeading, Keys: []string{"F6"}}, + } + if err := listener.SetKeyBindings(ctx, custom); err != nil { + t.Fatal(err) + } + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + key := func(args ...string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + command := func(want input.Command) { + t.Helper() + select { + case got := <-listener.Commands(): + if got.Command != want { + t.Fatalf("command %s want %s", got.Command, want) + } + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + key("keydown", "Insert", "keydown", "Control_L", "keydown", "Alt_L", "keydown", "y") + command(input.Preferences) + // Queue a new configuration while Y is held: it must wait for releases. + applied := make(chan error, 1) + go func() { applied <- listener.SetKeyBindings(ctx, nil) }() + select { + case err := <-applied: + t.Fatalf("update completed while keys were held: %v", err) + case <-time.After(40 * time.Millisecond): + } + key("keyup", "Insert", "keyup", "Control_L", "keyup", "Alt_L", "keyup", "y") + if err := <-applied; err != nil { + t.Fatal(err) + } + key("keydown", "Insert", "key", "space", "keyup", "Insert") + command(input.Preferences) + if err := listener.SetKeyBindings(ctx, custom); err != nil { + t.Fatal(err) + } + key("key", "F9") + command(input.Preferences) + listener.SetBrowseNavigation(true) + for !listener.BrowseNavigationEnabled() { + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + key("key", "F6") + command(input.DocumentNextHeading) + listener.SetBrowseNavigation(false) + for listener.browseApplied.Load() { + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + key("key", "F6") + key("key", "F9") + command(input.Preferences) // F6 outside browse mode must not dispatch. + competitor := NewCommands([]string{"KP_Insert"}, input.LaptopKeyboardLayout) + if err := competitor.SetKeyBindings(ctx, []input.BindingOverride{{Layout: input.LaptopKeyboardLayout, Scope: "global", Command: input.PresentDate, Keys: []string{"F10"}}}); err != nil { + t.Fatal(err) + } + if err := competitor.Start(ctx); err != nil { + t.Fatal(err) + } + collision := input.CloneBindingOverrides(custom) + collision[0].Keys = []string{"F10"} + if err := listener.SetKeyBindings(ctx, collision); err == nil { + t.Fatal("accepted conflicting native grab") + } + key("key", "F9") + command(input.Preferences) // Native rollback retained the old shortcut. + browseCollision := input.CloneBindingOverrides(custom) + browseCollision[1].Keys = []string{"F10"} + if err := listener.SetKeyBindings(ctx, browseCollision); err == nil { + t.Fatal("accepted conflicting prospective browse grab") + } + key("key", "F9") + command(input.Preferences) + if err := competitor.Stop(ctx); err != nil { + t.Fatal(err) + } + unavailable := input.CloneBindingOverrides(custom) + unavailable[0].Keys = []string{"Cthulhu+F35"} + if err := listener.SetKeyBindings(ctx, unavailable); err == nil { + t.Fatal("accepted unavailable key") + } + key("key", "F9") + command(input.Preferences) // Rejected update preserved the previous router. +} + +func TestNativeModifierConfigurationUpdate(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + listener := NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + key := func(args ...string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + command := func(want input.Command) { + t.Helper() + select { + case got := <-listener.Commands(): + if got.Command != want { + t.Fatalf("command %s want %s", got.Command, want) + } + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + lockState := func() string { + t.Helper() + out, err := exec.CommandContext(ctx, "xset", "q").Output() + if err != nil { + t.Fatal(err) + } + fields := strings.Fields(string(out)) + for i, field := range fields { + if field == "LED" && i+2 < len(fields) && fields[i+1] == "mask:" { + return fields[i+2] + } + } + t.Fatalf("missing keyboard LED mask: %s", out) + return "" + } + initialLock := lockState() + key("key", "Caps_Lock") + if lockState() == initialLock { + t.Fatal("ordinary Caps Lock did not toggle before configuration") + } + key("keydown", "Insert", "keydown", "space") + command(input.Preferences) + applied := make(chan error, 1) + go func() { + applied <- listener.SetKeyboardConfiguration(ctx, input.LaptopKeyboardLayout, []string{"Caps_Lock"}, nil) + }() + select { + case err := <-applied: + t.Fatalf("modifier update completed with keys held: %v", err) + case <-time.After(40 * time.Millisecond): + } + key("keyup", "Insert", "keyup", "space") + if err := <-applied; err != nil { + t.Fatal(err) + } + before := lockState() + key("keydown", "Caps_Lock", "keydown", "semicolon", "keyup", "Caps_Lock", "keyup", "semicolon") + command(input.ReadAll) // Laptop bindings became active with the modifier. + key("keydown", "Caps_Lock", "key", "space", "keyup", "Caps_Lock") + command(input.Preferences) + if after := lockState(); after != before { + t.Fatalf("Caps Lock commands changed lock state: %s -> %s", before, after) + } + if before != initialLock { + t.Fatalf("configuring Caps Lock did not clear existing capitalization: %s -> %s", initialLock, before) + } + key("key", "Caps_Lock") + if after := lockState(); after != before { + t.Fatalf("configured Caps Lock alone toggled capitalization: %s -> %s", before, after) + } + key("keydown", "Caps_Lock", "key", "z", "keyup", "Caps_Lock") + if after := lockState(); after != before { + t.Fatalf("unbound Caps Lock chord toggled capitalization: %s -> %s", before, after) + } + competitor := NewCommands([]string{"KP_Insert"}, input.DesktopKeyboardLayout) + if err := competitor.Start(ctx); err != nil { + t.Fatal(err) + } + if err := listener.SetKeyboardConfiguration(ctx, input.DesktopKeyboardLayout, []string{"KP_Insert"}, nil); err == nil { + t.Fatal("accepted conflicting modifier grab") + } + key("keydown", "Caps_Lock", "key", "semicolon", "keyup", "Caps_Lock") + command(input.ReadAll) // Failed update retained both layout and Caps Lock. + if err := competitor.Stop(ctx); err != nil { + t.Fatal(err) + } + if err := listener.SetKeyboardConfiguration(ctx, input.DesktopKeyboardLayout, []string{"Insert", "KP_Insert", "Caps_Lock"}, nil); err != nil { + t.Fatal(err) + } + for _, modifier := range []string{"Insert", "KP_Insert", "Caps_Lock"} { + key("keydown", modifier, "key", "space", "keyup", modifier) + command(input.Preferences) + } + // With every modifier disabled, a shortcut without Cthulhu remains usable. + custom := []input.BindingOverride{{Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Preferences, Keys: []string{"F9"}}} + if err := listener.SetKeyboardConfiguration(ctx, input.DesktopKeyboardLayout, nil, custom); err != nil { + t.Fatal(err) + } + key("keydown", "Insert", "key", "space", "keyup", "Insert") + key("key", "F9") + command(input.Preferences) + key("key", "Caps_Lock") + if lockState() == before { + t.Fatal("unchecked Caps Lock did not restore normal lock behavior") + } + key("key", "Caps_Lock") + if lockState() != before { + t.Fatal("unchecked Caps Lock did not unlock normally") + } + + if err := listener.Stop(ctx); err != nil { + t.Fatal(err) + } + // An empty modifier set must also be accepted on restart. + empty := NewCommands(nil, input.LaptopKeyboardLayout) + if err := empty.Start(ctx); err != nil { + t.Fatal(err) + } + if err := empty.Stop(ctx); err != nil { + t.Fatal(err) + } +} diff --git a/internal/platform/xorg/locks_native_test.go b/internal/platform/xorg/locks_native_test.go new file mode 100644 index 0000000..595bc3e --- /dev/null +++ b/internal/platform/xorg/locks_native_test.go @@ -0,0 +1,128 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestNativeLockStatesAndShiftCapsLock(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + listener := NewCommands([]string{"Caps_Lock"}, input.LaptopKeyboardLayout) + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + key := func(args ...string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + state := func(name string, locked bool) { + t.Helper() + select { + case event := <-listener.LockStates(): + if event.Name != name || event.Locked != locked || event.Timestamp == 0 { + t.Fatalf("lock state = %+v, want %s %v with timestamp", event, name, locked) + } + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatalf("missing lock state %s %v", name, locked) + } + } + command := func(want input.Command) { + t.Helper() + select { + case event := <-listener.Commands(): + if event.Command != want || event.Timestamp == 0 { + t.Fatalf("command = %+v, want %s with timestamp", event, want) + } + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatalf("missing command %s", want) + } + } + lockMask := func() string { + t.Helper() + out, err := exec.CommandContext(ctx, "xset", "q").Output() + if err != nil { + t.Fatal(err) + } + fields := strings.Fields(string(out)) + for index, field := range fields { + if field == "LED" && index+2 < len(fields) { + return fields[index+2] + } + } + t.Fatal("missing lock state") + return "" + } + initial := lockMask() + // Caps Lock alone and Shift+CapsLock+V must not toggle capitalization. + key("key", "Caps_Lock") + key("keydown", "Shift_L", "keydown", "Caps_Lock", "key", "v", "keyup", "Shift_L", "keyup", "Caps_Lock") + command(input.PresentVersion) + if lockMask() != initial { + t.Fatal("version chord changed capitalization") + } + for _, shift := range []string{"Shift_L", "Shift_R"} { + key("keydown", shift, "key", "Caps_Lock", "keyup", shift) + state("Caps Lock", true) + if lockMask() == initial { + t.Fatal("Shift+CapsLock did not enable capitalization") + } + // The reader modifier and commands still work while capitalization is on. + key("keydown", "Caps_Lock", "key", "t", "keyup", "Caps_Lock") + command(input.PresentTime) + key("keydown", "Caps_Lock", "keydown", shift, "key", "v", "keyup", "Caps_Lock", "keyup", shift) + command(input.PresentVersion) + if lockMask() == initial { + t.Fatal("reader chord cleared capitalization") + } + // Reverse modifier order and release Shift first. + key("keydown", "Caps_Lock", "keydown", shift, "keyup", shift, "keyup", "Caps_Lock") + state("Caps Lock", false) + if lockMask() != initial { + t.Fatal("Shift+CapsLock did not disable capitalization") + } + } + key("key", "Num_Lock") + state("Num Lock", true) + key("key", "Num_Lock") + state("Num Lock", false) + // A default keymap may leave Scroll Lock without a lock action. Exercise + // the XKB indicator itself to verify its actual state notifications. + for _, enabled := range []bool{true, false} { + option := "led" + if !enabled { + option = "-led" + } + if out, err := exec.CommandContext(ctx, "xset", option, "named", "Scroll Lock").CombinedOutput(); err != nil { + t.Fatalf("Scroll Lock indicator: %v %s", err, out) + } + state("Scroll Lock", enabled) + } + if err := listener.SetKeyboardConfiguration(ctx, input.LaptopKeyboardLayout, nil, nil); err != nil { + t.Fatal(err) + } + key("key", "Caps_Lock") + state("Caps Lock", true) + key("key", "Caps_Lock") + state("Caps Lock", false) +} diff --git a/internal/platform/xorg/ocr_click.c b/internal/platform/xorg/ocr_click.c new file mode 100644 index 0000000..8199e53 --- /dev/null +++ b/internal/platform/xorg/ocr_click.c @@ -0,0 +1,50 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "commands_native.h" +#include + +int cthulhu_ocr_click(unsigned long foreground, int x, int y, int root_width, int root_height) { + Display *display = XOpenDisplay(NULL); + if (!display) return 0; + Window root = DefaultRootWindow(display), query_root, child; + XWindowAttributes attributes; + int pointer_x, pointer_y, window_x, window_y; + unsigned int mask; + int event_base, error_base, major, minor; + int ok = XGetWindowAttributes(display, root, &attributes) && + attributes.width == root_width && attributes.height == root_height && + x >= 0 && x < root_width && y >= 0 && y < root_height && + XTestQueryExtension(display, &event_base, &error_base, &major, &minor) && + XQueryPointer(display, root, &query_root, &child, &pointer_x, &pointer_y, + &window_x, &window_y, &mask) && + read_foreground(display).window == foreground; + int moved = 0; + if (ok) { + cthulhu_x11_begin_read(display); + moved = XTestFakeMotionEvent(display, -1, x, y, CurrentTime); + ok = moved; + XSync(display, False); + if (cthulhu_x11_end_read(display)) ok = 0; + } + if (ok && read_foreground(display).window == foreground) { + cthulhu_x11_begin_read(display); + int pressed = XTestFakeButtonEvent(display, 1, True, CurrentTime); + XSync(display, False); + int released = !pressed || XTestFakeButtonEvent(display, 1, False, CurrentTime); + XTestFakeMotionEvent(display, -1, pointer_x, pointer_y, CurrentTime); + XSync(display, False); + int native_error = cthulhu_x11_end_read(display); + ok = pressed && released && !native_error; + } else { + ok = 0; + if (moved) { + cthulhu_x11_begin_read(display); + XTestFakeMotionEvent(display, -1, pointer_x, pointer_y, CurrentTime); + cthulhu_x11_end_read(display); + } + } + XCloseDisplay(display); + return ok; +} diff --git a/internal/platform/xorg/ocr_click.go b/internal/platform/xorg/ocr_click.go new file mode 100644 index 0000000..97c23b7 --- /dev/null +++ b/internal/platform/xorg/ocr_click.go @@ -0,0 +1,36 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +/* +#include "commands_native.h" +*/ +import "C" + +import ( + "context" + "errors" + "image" +) + +// ClickOCR performs one X11 button press and release after review ownership +// has been released. The native call checks active client and root dimensions. +func (listener *CommandListener) ClickOCR(ctx context.Context, foreground uint64, root image.Rectangle, point image.Point) error { + if ctx.Err() != nil { + return ctx.Err() + } + listener.secureMutex.Lock() + defer listener.secureMutex.Unlock() + if listener.secure.Load() || listener.ocrApplied.Load() || foreground == 0 || root.Min != (image.Point{}) || !point.In(root) { + return errors.New("OCR click unavailable") + } + if ctx.Err() != nil { + return ctx.Err() + } + if C.cthulhu_ocr_click(C.ulong(foreground), C.int(point.X), C.int(point.Y), C.int(root.Dx()), C.int(root.Dy())) == 0 { + return errors.New("OCR click source changed") + } + return nil +} diff --git a/internal/platform/xorg/ocr_click_native_test.go b/internal/platform/xorg/ocr_click_native_test.go new file mode 100644 index 0000000..f16392a --- /dev/null +++ b/internal/platform/xorg/ocr_click_native_test.go @@ -0,0 +1,83 @@ +package xorg + +import ( + "bufio" + "context" + "encoding/json" + "image" + "os" + "os/exec" + "testing" + "time" +) + +func TestNativeOCRClickReleasesButtonAndRestoresPointer(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_OCR_CLICK") != "1" { + t.Skip("requires private Xorg display") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-u", "../../../tests/ocr_click_fixture.py") + input, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + output, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { input.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(output) + if !scanner.Scan() { + t.Fatal("fixture did not start") + } + var source struct { + Window uint64 + Width, Height int + Pointer []int + } + if err := json.Unmarshal(scanner.Bytes(), &source); err != nil { + t.Fatal(err) + } + listener := &CommandListener{} + root := image.Rect(0, 0, source.Width, source.Height) + listener.secure.Store(true) + if err := listener.ClickOCR(ctx, source.Window, root, image.Pt(60, 60)); err == nil { + t.Fatal("clicked during secure input") + } + listener.secure.Store(false) + if err := listener.ClickOCR(ctx, source.Window+1, root, image.Pt(60, 60)); err == nil { + t.Fatal("clicked wrong foreground") + } + if err := listener.ClickOCR(ctx, source.Window, root, image.Pt(60, 60)); err != nil { + t.Fatal(err) + } + if _, err := input.Write([]byte("events\n")); err != nil { + t.Fatal(err) + } + if !scanner.Scan() { + t.Fatal("fixture did not report events") + } + var result struct { + Events []struct { + Pressed bool + Button, X, Y int + } + Pointer []int + } + if err := json.Unmarshal(scanner.Bytes(), &result); err != nil { + t.Fatal(err) + } + if len(result.Events) != 2 || !result.Events[0].Pressed || result.Events[1].Pressed || + result.Events[0].Button != 1 || result.Events[1].Button != 1 || + result.Events[0].X != 60 || result.Events[0].Y != 60 || result.Events[1].X != 60 || result.Events[1].Y != 60 { + t.Fatalf("click events: %+v", result.Events) + } + if len(result.Pointer) != 2 || len(source.Pointer) != 2 || result.Pointer[0] != source.Pointer[0] || result.Pointer[1] != source.Pointer[1] { + t.Fatalf("pointer not restored: %+v", result.Pointer) + } +} diff --git a/internal/platform/xorg/ocr_native_test.go b/internal/platform/xorg/ocr_native_test.go new file mode 100644 index 0000000..d27480d --- /dev/null +++ b/internal/platform/xorg/ocr_native_test.go @@ -0,0 +1,348 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +import ( + "bufio" + "context" + "encoding/json" + "os" + "os/exec" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestNativeOCRReviewInput(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_OCR_REVIEW") != "1" { + t.Skip("requires private Xorg display") + } + for _, layout := range []input.KeyboardLayout{input.DesktopKeyboardLayout, input.LaptopKeyboardLayout} { + name := "desktop" + if layout == input.LaptopKeyboardLayout { + name = "laptop" + } + t.Run(name, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-u", "../../../tests/ocr_review_fixture.py") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err = fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + if !scanner.Scan() { + t.Fatal("fixture did not start") + } + var windows map[string]uint64 + if err = json.Unmarshal(scanner.Bytes(), &windows); err != nil { + t.Fatal(err) + } + type deliveredKey struct { + Pressed bool + Symbol uint32 + Modifiers uint16 + Window uint64 + } + type state struct { + Focus uint64 + Keys []deliveredKey + } + action := func(value map[string]any) state { + t.Helper() + data, _ := json.Marshal(value) + if _, err := stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() { + t.Fatal("fixture did not respond") + } + var result state + if err := json.Unmarshal(scanner.Bytes(), &result); err != nil { + t.Fatal(err) + } + return result + } + clear := func() { action(map[string]any{"action": "clear"}) } + snapshot := func() state { return action(map[string]any{"action": "state"}) } + listener := NewCommands([]string{"Insert"}, layout) + if err = listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + key := func(args ...string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + defer func() { + exec.Command("xdotool", "keyup", "Insert", "Control_L", "Shift_L", "Down", "Escape", "Tab", "o").Run() + }() + ready := func(predicate func() bool) { + t.Helper() + for !predicate() { + select { + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatalf("%v: OCR=%v commandsApplied=%v requested=%v secure=%v", ctx.Err(), listener.ocrApplied.Load(), listener.commandsApplied.Load(), listener.commandsEnabled.Load(), listener.secure.Load()) + case <-time.After(time.Millisecond): + } + } + } + command := func(want input.Command) input.CommandEvent { + t.Helper() + select { + case got := <-listener.Commands(): + if got.Command != want { + t.Fatalf("got %s want %s", got.Command, want) + } + return got + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatalf("%v: OCR=%v commandsApplied=%v requested=%v secure=%v", ctx.Err(), listener.ocrApplied.Load(), listener.commandsApplied.Load(), listener.commandsEnabled.Load(), listener.secure.Load()) + } + return input.CommandEvent{} + } + drained := func() { ready(func() bool { return !listener.CommandGrabActive() }) } + noLeak := func() { + t.Helper() + drained() + got := snapshot() + balance := make(map[uint32]int) + for _, event := range got.Keys { + if event.Symbol != 0xffe1 && event.Symbol != 0xffe3 { + t.Fatalf("review leaked navigation: %+v", got) + } + if event.Pressed { + balance[event.Symbol]++ + } else { + balance[event.Symbol]-- + } + } + for _, count := range balance { + if count != 0 { + t.Fatalf("unbalanced native modifier: %+v", got) + } + } + if got.Focus != windows["window"] { + t.Fatalf("review leaked/changed focus: %+v", got) + } + } + listener.SetBrowseNavigation(true) + ready(listener.BrowseNavigationEnabled) + listener.SetNativeButtonFocus(true) + // A conflict must reject entry and preserve the existing browser context. + action(map[string]any{"action": "conflict"}) + if err = listener.SetOCRReview(ctx, true); err == nil { + t.Fatal("conflicting Ctrl+C grab accepted") + } + if listener.OCRReviewEnabled() || !listener.BrowseNavigationEnabled() { + t.Fatal("failed entry lost old context") + } + key("key", "h") + command(input.DocumentNextHeading) + drained() + action(map[string]any{"action": "unconflict"}) + clear() + // Recognition claims Escape only, even when the application's Ctrl+C + // grab prevents full review. Arrows and structural letters pass. + action(map[string]any{"action": "conflict"}) + if err = listener.SetOCRContext(ctx, windows["other"], true); err == nil { + t.Fatal("pending entry accepted another foreground") + } + if err = listener.SetOCRContext(ctx, windows["window"], true); err != nil { + t.Fatal(err) + } + if listener.OCRReviewEnabled() || listener.BrowseNavigationEnabled() { + t.Fatal("pending context exposed full review/browser navigation") + } + key("key", "Down") + key("key", "h") + gotPending := snapshot() + if len(gotPending.Keys) != 4 || gotPending.Keys[0].Symbol != 0xff54 || gotPending.Keys[2].Symbol != 'h' { + t.Fatalf("pending navigation: %+v", gotPending) + } + clear() + key("key", "Escape") + command(input.OCRDismiss) + noLeak() + ready(listener.BrowseNavigationEnabled) + action(map[string]any{"action": "unconflict"}) + clear() + // A timed-out entry must never activate when the held key later releases. + key("keydown", "Insert") + ready(listener.CommandGrabActive) + expired, cancelEntry := context.WithTimeout(ctx, 25*time.Millisecond) + if err = listener.SetOCRReview(expired, true); err != context.DeadlineExceeded { + t.Fatalf("waiting entry: %v", err) + } + cancelEntry() + key("keyup", "Insert") + if err = listener.SetOCRReview(ctx, false); err != nil { + t.Fatal(err) + } + if listener.OCRReviewEnabled() { + t.Fatal("expired entry activated later") + } + // Entry waits for the full initiating chord, including modifier release. + key("keydown", "Insert") + ready(listener.CommandGrabActive) + applied := make(chan error, 1) + go func() { applied <- listener.SetOCRReview(ctx, true) }() + select { + case err := <-applied: + t.Fatalf("entered on held modifier: %v", err) + case <-time.After(25 * time.Millisecond): + } + key("keyup", "Insert") + if err = <-applied; err != nil { + t.Fatal(err) + } + ready(listener.OCRReviewEnabled) + clear() + for _, test := range []struct { + chord string + want input.Command + }{ + {"Down", input.OCRNextLine}, {"Up", input.OCRPreviousLine}, {"Left", input.OCRPreviousCharacter}, + {"ctrl+Right", input.OCRNextWord}, {"Home", input.OCRLineStart}, {"ctrl+End", input.OCRDocumentEnd}, + {"shift+Down", input.OCRNextLine}, {"ctrl+a", input.OCRSelectAll}, {"ctrl+c", input.OCRCopySelection}, + {"Return", input.OCRActivate}, {"space", input.OCRActivate}, + } { + key("key", test.chord) + event := command(test.want) + if test.chord == "shift+Down" && event.Chord.Modifiers&1 == 0 { + t.Fatal("selection modifier lost") + } + noLeak() + clear() + } + if layout == input.LaptopKeyboardLayout { + key("key", "Insert+o") + command(input.ReviewNextLine) + noLeak() + clear() + } + // Alt+Tab remains available to the application/window manager. + key("key", "alt+Tab") + got := snapshot() + tabPresses, tabReleases := 0, 0 + for _, event := range got.Keys { + if event.Symbol == 0xff09 { + if event.Pressed { + tabPresses++ + } else { + tabReleases++ + } + } + } + if tabPresses != 1 || tabReleases != 1 { + t.Fatalf("Alt+Tab did not pass: %+v", got) + } + clear() + // Structural letters reach the app rather than inventing OCR headings. + key("key", "h") + got = snapshot() + if len(got.Keys) != 2 || got.Keys[0].Symbol != 'h' { + t.Fatalf("structural letter: %+v", got) + } + clear() + key("key", "ctrl+z") + got = snapshot() + if len(got.Keys) != 4 { + t.Fatalf("unbound Control chord not replayed whole: %+v", got) + } + clear() + // Exit also waits for the complete navigation key release. + key("keydown", "Down") + command(input.OCRNextLine) + go func() { applied <- listener.SetOCRReview(ctx, false) }() + select { + case err := <-applied: + t.Fatalf("exited on held arrow: %v", err) + case <-time.After(25 * time.Millisecond): + } + key("keyup", "Down") + if err = <-applied; err != nil { + t.Fatal(err) + } + noLeak() + ready(listener.BrowseNavigationEnabled) + key("key", "h") + command(input.DocumentNextHeading) + drained() + clear() + if err = listener.SetOCRReview(ctx, true); err != nil { + t.Fatal(err) + } + key("key", "Escape") + command(input.OCRDismiss) + ready(func() bool { return !listener.OCRReviewEnabled() }) + noLeak() + for _, chord := range []string{"Tab", "shift+Tab"} { + if err = listener.SetOCRReview(ctx, true); err != nil { + t.Fatal(err) + } + clear() + key("key", chord) + command(input.OCRDismissAndPass) + ready(func() bool { return !listener.OCRReviewEnabled() }) + drained() + got = snapshot() + presses, releases := 0, 0 + for _, event := range got.Keys { + if event.Symbol == 0xff09 { + if event.Pressed { + presses++ + } else { + releases++ + } + } + } + if got.Focus != windows["window"] || presses != 1 || releases != 1 { + t.Fatalf("Tab replay: %+v", got) + } + } + // Focus loss retires temporary input; a following arrow reaches the new app. + if err = listener.SetOCRReview(ctx, true); err != nil { + t.Fatal(err) + } + listener.SetBrowseNavigation(false) + action(map[string]any{"action": "activate", "other": true}) + command(input.OCRDismiss) + ready(func() bool { return !listener.OCRReviewEnabled() }) + clear() + key("key", "Down") + got = snapshot() + if len(got.Keys) != 2 || got.Keys[0].Window != windows["other"] { + t.Fatalf("focus-loss routing: %+v", got) + } + action(map[string]any{"action": "activate"}) + if err = listener.SetOCRReview(ctx, true); err != nil { + t.Fatal(err) + } + listener.SetSecureInputActive(true) + ready(func() bool { return !listener.ocrApplied.Load() && !listener.CommandGrabsEnabled() }) + listener.SetSecureInputActive(false) + ready(listener.CommandGrabsEnabled) + if listener.OCRReviewEnabled() { + t.Fatal("unlock revived OCR") + } + }) + } +} diff --git a/internal/platform/xorg/pointer.go b/internal/platform/xorg/pointer.go new file mode 100644 index 0000000..c2e151b --- /dev/null +++ b/internal/platform/xorg/pointer.go @@ -0,0 +1,44 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +package xorg + +/* +#cgo pkg-config: x11 +#include "commands_native.h" +*/ +import "C" + +type PointerPosition struct { + X, Y, PID int + Window uint64 + Known bool +} + +// PointerReader owns one X connection. Use it from one goroutine and close it +// after that goroutine has stopped. +type PointerReader struct{ display *C.Display } + +func OpenPointerReader() *PointerReader { + display := C.XOpenDisplay(nil) + if display == nil { + return nil + } + return &PointerReader{display: display} +} + +func (reader *PointerReader) Read() PointerPosition { + if reader == nil || reader.display == nil { + return PointerPosition{} + } + value := C.cthulhu_read_pointer(reader.display) + return PointerPosition{X: int(value.x), Y: int(value.y), PID: int(value.pid), + Window: uint64(value.window), Known: value.known != 0} +} + +func (reader *PointerReader) Close() { + if reader != nil && reader.display != nil { + C.XCloseDisplay(reader.display) + reader.display = nil + } +} diff --git a/internal/platform/xorg/scroll_lock_native_test.go b/internal/platform/xorg/scroll_lock_native_test.go new file mode 100644 index 0000000..567d14f --- /dev/null +++ b/internal/platform/xorg/scroll_lock_native_test.go @@ -0,0 +1,178 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +import ( + "bufio" + "context" + "encoding/json" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestNativeScrollLockCommandGrabs(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + for _, shared := range []bool{false, true} { + name := "scroll_only" + if shared { + name = "shared_level_shift" + } + t.Run(name, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + run := func(program string, args ...string) { + t.Helper() + if out, err := exec.CommandContext(ctx, program, args...).CombinedOutput(); err != nil { + t.Fatalf("%s: %v %s", program, err, out) + } + } + original, err := exec.CommandContext(ctx, "xmodmap", "-pm").Output() + if err != nil { + t.Fatal(err) + } + var originalSymbols []string + for _, line := range strings.Split(string(original), "\n") { + fields := strings.Fields(line) + if len(fields) > 0 && fields[0] == "mod3" { + for index := 1; index < len(fields); index += 2 { + originalSymbols = append(originalSymbols, fields[index]) + } + } + } + defer func() { + args := []string{"-e", "clear mod3"} + if len(originalSymbols) > 0 { + args = append(args, "-e", "add mod3 = "+strings.Join(originalSymbols, " ")) + } + if out, err := exec.Command("xmodmap", args...).CombinedOutput(); err != nil { + t.Errorf("restore modifier mapping: %v %s", err, out) + } + }() + mapping := "Scroll_Lock" + if shared { + mapping += " ISO_Level5_Shift" + } + run("xmodmap", "-e", "clear mod3", "-e", "add mod3 = "+mapping) + + fixture := exec.CommandContext(ctx, "python3", "-u", "../../../tests/ocr_review_fixture.py") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + if !scanner.Scan() { + t.Fatal("key sink did not start") + } + type deliveredKey struct { + Pressed bool + Symbol uint32 + Modifiers uint16 + } + action := func(command map[string]string) []deliveredKey { + t.Helper() + data, _ := json.Marshal(command) + if _, err := stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() { + t.Fatal("key sink did not respond") + } + var state struct{ Keys []deliveredKey } + if err := json.Unmarshal(scanner.Bytes(), &state); err != nil { + t.Fatal(err) + } + return state.Keys + } + listener := NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + if err := listener.SetKeyBindings(ctx, []input.BindingOverride{{Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Preferences, Keys: []string{"Cthulhu+Space", "Cthulhu+Ctrl+Alt+y"}}}); err != nil { + t.Fatal(err) + } + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + command := func(want input.Command) { + t.Helper() + select { + case event := <-listener.Commands(): + if event.Command != want { + t.Fatalf("command = %s, want %s", event.Command, want) + } + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatalf("missing command %s", want) + } + for listener.CommandGrabActive() { + select { + case <-ctx.Done(): + t.Fatal("command grab did not release") + case <-time.After(time.Millisecond): + } + } + } + press := func(name string) { + t.Helper() + action(map[string]string{"action": "key", "name": name}) + } + press("Scroll_Lock") + defer exec.Command("xdotool", "key", "Scroll_Lock").Run() + action(map[string]string{"action": "clear"}) + press("KP_Begin") + if shared { + keys := action(map[string]string{"action": "state"}) + if len(keys) != 2 || keys[0].Symbol != 0xff9d || !keys[0].Pressed || keys[1].Pressed || keys[0].Modifiers&32 == 0 { + t.Fatalf("shared layout modifier was consumed: %+v", keys) + } + return + } + command(input.ReviewCurrentWord) + for _, test := range []struct { + chord string + want input.Command + }{ + {"Insert+space", input.Preferences}, + {"Insert+Control_L+Down", input.ObjectFirstChild}, + {"Insert+Shift_L+v", input.PresentVersion}, + {"Insert+Control_L+Alt_L+y", input.Preferences}, + } { + run("xdotool", "key", test.chord) + command(test.want) + } + if keys := action(map[string]string{"action": "state"}); len(keys) != 0 { + t.Fatalf("reader commands leaked: %+v", keys) + } + press("Num_Lock") + defer exec.Command("xdotool", "key", "Num_Lock").Run() + action(map[string]string{"action": "clear"}) + press("KP_Begin") + keys := action(map[string]string{"action": "state"}) + if len(keys) != 2 || keys[0].Symbol != 0xff9d || !keys[0].Pressed || keys[1].Pressed || keys[0].Modifiers&16 == 0 { + t.Fatalf("NumLock typing was consumed: %+v", keys) + } + select { + case got := <-listener.Commands(): + t.Fatalf("unbound key dispatched: %+v", got) + default: + } + }) + } +} diff --git a/internal/platform/xorg/steam_focus.c b/internal/platform/xorg/steam_focus.c new file mode 100644 index 0000000..4afbb29 --- /dev/null +++ b/internal/platform/xorg/steam_focus.c @@ -0,0 +1,106 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "commands_native.h" +#include +#include +#include + +static int steam_active_window(Display *display, Window *window) { + Atom type; int format; + unsigned long count, remaining; + unsigned char *data = NULL; + int known = XGetWindowProperty(display, DefaultRootWindow(display), XInternAtom(display, "_NET_ACTIVE_WINDOW", False), + 0, 1, False, XA_WINDOW, &type, &format, &count, &remaining, &data) == Success && + data != NULL && type == XA_WINDOW && format == 32 && count == 1; + if (known) *window = ((Window *)data)[0]; + if (data != NULL) XFree(data); + return known; +} + +static int steam_window_pid(Display *display, Window window) { + Atom type; int format; + unsigned long count, remaining; + unsigned char *data = NULL; + int pid = 0; + if (XGetWindowProperty(display, window, XInternAtom(display, "_NET_WM_PID", False), + 0, 1, False, XA_CARDINAL, &type, &format, &count, + &remaining, &data) == Success && data != NULL && + type == XA_CARDINAL && format == 32 && count == 1) { + pid = (int)((unsigned long *)data)[0]; + } + if (data != NULL) XFree(data); + return pid; +} + +static int steam_wrapper(Display *display, Window window) { + XClassHint hint = {0}; + int matches = XGetClassHint(display, window, &hint) && + hint.res_name != NULL && hint.res_class != NULL && + strcmp(hint.res_name, "steamwebhelper") == 0 && strcmp(hint.res_class, "steam") == 0; + if (hint.res_name != NULL) XFree(hint.res_name); + if (hint.res_class != NULL) XFree(hint.res_class); + return matches; +} + +static int steam_browser_child(Display *display, Window wrapper, int pid, Window child) { + XWindowAttributes attributes; + if (child == None || child == PointerRoot || child == wrapper || + !XGetWindowAttributes(display, child, &attributes) || attributes.map_state != IsViewable || + attributes.class != InputOutput || steam_window_pid(display, child) != pid) return 0; + for (int depth = 0; depth < 32; depth++) { + Window root, parent, *children = NULL; + unsigned int count; + if (!XQueryTree(display, child, &root, &parent, &children, &count)) return 0; + if (children != NULL) XFree(children); + if (parent == wrapper) return 1; + if (parent == None || parent == root) return 0; + child = parent; + } + return 0; +} + +CommandFocusSample cthulhu_read_command_focus(Display *display, int steam_enabled) { + CommandFocusSample result = {0}; + SteamFocusSample *sample = &result.steam; + cthulhu_x11_begin_read(display); + result.xterm = cthulhu_focus_metadata_unchecked(display, steam_enabled ? sample : NULL); + if (sample->steam) { + sample->pid = steam_window_pid(display, sample->window); + sample->steam = sample->pid > 0; + int revert; + XGetInputFocus(display, &sample->focus, &revert); + if (sample->steam) sample->innerFocus = steam_browser_child(display, sample->window, sample->pid, sample->focus); + } + if (cthulhu_x11_end_read(display)) result = (CommandFocusSample){0}; + return result; +} + +int cthulhu_restore_steam_focus(Display *display, Window wrapper, int pid, Window target) { + cthulhu_x11_begin_read(display); + int restored = 0, revert; + Window focus, active = None; + XGetInputFocus(display, &focus, &revert); + char heldKeys[32]; + XQueryKeymap(display, heldKeys); + int keyHeld = 0; + for (int i = 0; i < 32; i++) keyHeld |= heldKeys[i]; + if (!keyHeld && focus == wrapper && steam_active_window(display, &active) && active == wrapper && + steam_wrapper(display, wrapper) && + steam_window_pid(display, wrapper) == pid && steam_browser_child(display, wrapper, pid, target)) { + // Recheck foreground immediately before changing input focus: cached + // children must never pull keyboard input out of a different client. + if (steam_active_window(display, &active) && active == wrapper) { + XGetInputFocus(display, &focus, &revert); + if (focus == wrapper) { + XSetInputFocus(display, target, RevertToParent, CurrentTime); + XSync(display, False); + XGetInputFocus(display, &focus, &revert); + restored = focus == target; + } + } + } + if (cthulhu_x11_end_read(display)) restored = 0; + return restored; +} diff --git a/internal/platform/xorg/steam_focus.go b/internal/platform/xorg/steam_focus.go new file mode 100644 index 0000000..a9c7c82 --- /dev/null +++ b/internal/platform/xorg/steam_focus.go @@ -0,0 +1,87 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +/* +#include "commands_native.h" +*/ +import "C" + +type steamFocusSample struct { + window, focus uint64 + pid int + known, steam bool + innerFocus bool +} + +// The command owner retains one verified Steam browser child. A foreground +// transition arms at most one repair during the next ten 100ms focus samples. +// Steam's own restoration wins; we never choose a child from its geometry. +type steamFocusRepair struct { + previousWindow, window, target uint64 + pid int + checksLeft, outerSamples int +} + +func (repair *steamFocusRepair) observe(sample steamFocusSample) uint64 { + if !sample.known { + return 0 + } + if sample.window != repair.previousWindow { + repair.previousWindow = sample.window + repair.checksLeft, repair.outerSamples = 10, 0 + } + if !sample.steam { + repair.checksLeft, repair.outerSamples = 0, 0 + return 0 + } + if sample.innerFocus { + repair.window, repair.pid, repair.target = sample.window, sample.pid, sample.focus + repair.outerSamples = 0 + } + if repair.checksLeft == 0 { + return 0 + } + repair.checksLeft-- + if sample.focus != sample.window { + repair.outerSamples = 0 + return 0 + } + repair.outerSamples++ + if repair.outerSamples < 2 || sample.window != repair.window || sample.pid != repair.pid { + return 0 + } + return repair.target +} + +func read_command_focus(display *C.Display, steamEnabled bool) (int, steamFocusSample) { + var enabled C.int + if steamEnabled { + enabled = 1 + } + result := C.cthulhu_read_command_focus(display, enabled) + value := result.steam + return int(result.xterm), steamFocusSample{window: uint64(value.window), focus: uint64(value.focus), pid: int(value.pid), + known: value.known != 0, steam: value.steam != 0, innerFocus: value.innerFocus != 0} +} + +func restore_steam_focus(display *C.Display, window uint64, pid int, target uint64) bool { + return C.cthulhu_restore_steam_focus(display, C.Window(window), C.int(pid), C.Window(target)) != 0 +} + +func (owner *commandOwner) check_steam_focus(sample steamFocusSample) { + if owner.listener.secure.Load() || owner.workerContext.Err() != nil { + owner.steamFocus.checksLeft = 0 + return + } + target := owner.steamFocus.observe(sample) + if target == 0 || !owner.commandGrabsAllowed() || len(owner.held) != 0 || owner.device.active != 0 || + owner.learnMode || owner.uiSession != 0 || owner.ocrReview || owner.ocrPending { + return + } + if restore_steam_focus(owner.device.display, sample.window, sample.pid, target) { + owner.steamFocus.checksLeft = 0 + } +} diff --git a/internal/platform/xorg/steam_focus_native_test.go b/internal/platform/xorg/steam_focus_native_test.go new file mode 100644 index 0000000..fd53865 --- /dev/null +++ b/internal/platform/xorg/steam_focus_native_test.go @@ -0,0 +1,179 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +import ( + "bufio" + "context" + "encoding/json" + "os" + "os/exec" + "runtime" + "testing" + "time" +) + +func TestNativeSteamFocusRepair(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_STEAM_FOCUS") != "1" { + t.Skip("requires private X11 Steam fixture") + } + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "python3", "-u", "../../../tests/steam_focus_fixture.py") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + if !scanner.Scan() { + t.Fatal("Steam fixture did not start") + } + var windows map[string]uint64 + if err := json.Unmarshal(scanner.Bytes(), &windows); err != nil { + t.Fatal(err) + } + command := func(action, window string) { + t.Helper() + data, _ := json.Marshal(map[string]string{"action": action, "window": window}) + if _, err := stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() || scanner.Text() != "ready" { + t.Fatal("Steam fixture command failed") + } + } + key := func(action, name string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", action, name).CombinedOutput(); err != nil { + t.Fatalf("key: %v %s", err, out) + } + } + reader := OpenForegroundReader() + if reader == nil { + t.Fatal("cannot open private X11 display") + } + defer reader.Close() + readSteam := func() steamFocusSample { + t.Helper() + match, sample := read_command_focus(reader.display, true) + if match != 2 { + t.Fatalf("Steam/ordinary window XTerm match = %d", match) + } + return sample + } + match, disabled := read_command_focus(reader.display, false) + if match != 2 || disabled != (steamFocusSample{}) { + t.Fatalf("disabled Steam sampling = %d, %+v", match, disabled) + } + sample := readSteam() + if !sample.steam || !sample.innerFocus || sample.focus != windows["browser"] { + t.Fatalf("initial browser focus not recognized: %+v", sample) + } + repair := steamFocusRepair{} + repair.observe(sample) + roundTrip := func() uint64 { + t.Helper() + command("activate", "other") + other := readSteam() + if !other.known || other.window != windows["other"] || other.steam || other.focus != 0 || other.pid != 0 { + t.Fatalf("ordinary window queried Steam details: %+v", other) + } + repair.observe(other) + command("activate", "steam") + if target := repair.observe(readSteam()); target != 0 { + t.Fatal("Steam restoration grace sample was skipped") + } + return repair.observe(readSteam()) + } + target := roundTrip() + if target != windows["browser"] || !restore_steam_focus(reader.display, sample.window, sample.pid, target) { + t.Fatal("main browser keyboard focus was not repaired") + } + key("key", "Escape") + data, _ := json.Marshal(map[string]string{"action": "events"}) + if _, err := stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() { + t.Fatal("fixture key delivery missing") + } + var events []struct { + Window uint64 + Pressed bool + Escape bool + } + if err := json.Unmarshal(scanner.Bytes(), &events); err != nil { + t.Fatal(err) + } + if len(events) != 2 || !events[0].Escape || !events[0].Pressed || !events[1].Escape || events[1].Pressed || + events[0].Window != target || events[1].Window != target { + t.Fatalf("Escape was not delivered to restored browser: %+v", events) + } + command("focus", "popup") + if target := repair.observe(readSteam()); target != 0 { + t.Fatal("valid popup focus was overridden") + } + target = roundTrip() + if target != windows["popup"] || !restore_steam_focus(reader.display, sample.window, sample.pid, target) { + t.Fatal("popup keyboard focus was not repaired") + } + command("focus", "browser") + if restore_steam_focus(reader.display, sample.window, sample.pid, target) { + t.Fatal("valid search/control browser focus was overridden") + } + command("activate", "steam") + key("keydown", "Control_L") + blocked := restore_steam_focus(reader.display, sample.window, sample.pid, target) + key("keyup", "Control_L") + if blocked { + t.Fatal("focus moved while a physical modifier was held") + } + command("activate", "other") + if restore_steam_focus(reader.display, sample.window, sample.pid, target) { + t.Fatal("repair stole focus from another application") + } + command("activate", "steam") + if restore_steam_focus(reader.display, sample.window, sample.pid, windows["otherChild"]) { + t.Fatal("repair targeted an unrelated child") + } + command("unmap", "popupHost") + if restore_steam_focus(reader.display, sample.window, sample.pid, target) { + t.Fatal("repair focused a hidden popup") + } + command("map", "popupHost") + command("pid", "popup") + if restore_steam_focus(reader.display, sample.window, sample.pid, target) { + t.Fatal("repair focused a child from a different process") + } + command("destroy", "popup") + if restore_steam_focus(reader.display, sample.window, sample.pid, target) { + t.Fatal("repair focused a destroyed popup") + } + command("class", "steam") + if readSteam().steam || restore_steam_focus(reader.display, sample.window, sample.pid, windows["browser"]) { + t.Fatal("repair changed focus in an ordinary application") + } + command("xterm", "steam") + match, terminal := read_command_focus(reader.display, true) + if match != 1 || !terminal.known || terminal.steam || terminal.focus != 0 { + t.Fatalf("XTerm class change = %d, %+v", match, terminal) + } + command("unknown", "steam") + match, unknown := read_command_focus(reader.display, true) + if match != 0 || unknown != (steamFocusSample{}) { + t.Fatalf("unknown foreground = %d, %+v", match, unknown) + } +} diff --git a/internal/platform/xorg/steam_focus_test.go b/internal/platform/xorg/steam_focus_test.go new file mode 100644 index 0000000..d2079a7 --- /dev/null +++ b/internal/platform/xorg/steam_focus_test.go @@ -0,0 +1,70 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +import "testing" + +func TestSteamFocusRepairActivation(t *testing.T) { + repair := steamFocusRepair{} + inner := steamFocusSample{known: true, steam: true, window: 10, focus: 12, pid: 123, innerFocus: true} + if target := repair.observe(inner); target != 0 { + t.Fatal("valid browser focus requested a repair") + } + repair.observe(steamFocusSample{known: true, window: 20, focus: 20}) + outer := inner + outer.focus, outer.innerFocus = 10, false + if target := repair.observe(outer); target != 0 { + t.Fatal("repair did not allow Steam its first restoration sample") + } + if target := repair.observe(outer); target != 12 { + t.Fatalf("repair target = %d, want remembered browser child 12", target) + } +} + +func TestSteamFocusRepairPreservesControlAndWindowBoundaries(t *testing.T) { + for _, test := range []struct { + name string + sample steamFocusSample + }{ + {"other application", steamFocusSample{known: true, window: 20, focus: 20}}, + {"other Steam window", steamFocusSample{known: true, steam: true, window: 30, focus: 30, pid: 123}}, + {"reused window with different process", steamFocusSample{known: true, steam: true, window: 10, focus: 10, pid: 456}}, + {"already focused browser popup", steamFocusSample{known: true, steam: true, window: 10, focus: 14, pid: 123, innerFocus: true}}, + {"external keyboard focus", steamFocusSample{known: true, steam: true, window: 10, focus: 99, pid: 123}}, + {"unknown foreground", steamFocusSample{}}, + } { + t.Run(test.name, func(t *testing.T) { + repair := steamFocusRepair{} + repair.observe(steamFocusSample{known: true, steam: true, window: 10, focus: 12, pid: 123, innerFocus: true}) + repair.observe(steamFocusSample{known: true, window: 20}) + for i := 0; i < 12; i++ { + if target := repair.observe(test.sample); target != 0 { + t.Fatalf("unexpected focus repair to %d", target) + } + } + }) + } +} + +func TestSteamFocusRepairRemembersPopupAndExpires(t *testing.T) { + repair := steamFocusRepair{} + inner := steamFocusSample{known: true, steam: true, window: 10, focus: 12, pid: 123, innerFocus: true} + repair.observe(inner) + inner.focus = 14 + repair.observe(inner) + repair.observe(steamFocusSample{known: true, window: 20}) + outer := inner + outer.focus, outer.innerFocus = 10, false + repair.observe(outer) + if target := repair.observe(outer); target != 14 { + t.Fatalf("target = %d, want most recently focused popup 14", target) + } + for i := 0; i < 10; i++ { + repair.observe(inner) + } + if target := repair.observe(outer); target != 0 { + t.Fatalf("repair remained armed after activation window expired: %d", target) + } +} diff --git a/internal/platform/xorg/tentacle_native_test.go b/internal/platform/xorg/tentacle_native_test.go new file mode 100644 index 0000000..6300f32 --- /dev/null +++ b/internal/platform/xorg/tentacle_native_test.go @@ -0,0 +1,197 @@ +package xorg + +import ( + "context" + "git.stormux.org/storm/cthulhu/internal/input" + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeTentacleBindingsUpdateAndRelease(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + // Own a foreground client; browse-only grabs deliberately replay when + // no client owns focus or the foreground window has changed. + probe := exec.CommandContext(ctx, "xev", "-name", "Cthulhu Tentacle Bindings", "-event", "keyboard") + if err := probe.Start(); err != nil { + t.Fatal(err) + } + defer func() { _ = probe.Process.Kill(); _ = probe.Wait() }() + window := "" + for window == "" { + output, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Cthulhu Tentacle Bindings$").Output() + if err == nil { + window = strings.TrimSpace(string(output)) + } + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + if err := exec.CommandContext(ctx, "xdotool", "windowfocus", window).Run(); err != nil { + t.Fatal(err) + } + listener := NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + custom := []input.BindingOverride{ + {Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Command("tentacle/test/global"), Keys: []string{"Cthulhu+Ctrl+Alt+y"}}, + {Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Command("tentacle/test/global"), Keys: []string{"F9"}}, + {Layout: input.DesktopKeyboardLayout, Scope: "browse", Command: input.Command("tentacle/test/browse"), Keys: []string{"F6"}}, + {Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Command("tentacle/test/wormhole"), Keys: []string{"Cthulhu+Ctrl+Shift+W"}}, + } + if err := listener.SetTentacleBindings(ctx, custom); err != nil { + t.Fatal(err) + } + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + key := func(args ...string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + command := func(want input.Command) { + t.Helper() + select { + case got := <-listener.Commands(): + if got.Command != want { + t.Fatalf("command %s want %s", got.Command, want) + } + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + key("keydown", "Insert", "keydown", "Control_L", "keydown", "Alt_L", "keydown", "y") + command(input.Command("tentacle/test/global")) + // Queue a new configuration while Y is held: it must wait for releases. + applied := make(chan error, 1) + go func() { applied <- listener.SetTentacleBindings(ctx, nil) }() + select { + case err := <-applied: + t.Fatalf("update completed while keys were held: %v", err) + case <-time.After(40 * time.Millisecond): + } + key("keyup", "Insert", "keyup", "Control_L", "keyup", "Alt_L", "keyup", "y") + if err := <-applied; err != nil { + t.Fatal(err) + } + key("keydown", "Insert", "key", "space", "keyup", "Insert") + command(input.Preferences) + if err := listener.SetTentacleBindings(ctx, custom); err != nil { + t.Fatal(err) + } + key("key", "F9") + command(input.Command("tentacle/test/global")) + key("keydown", "Insert", "keydown", "Control_L", "keydown", "Shift_L", "key", "w", "keyup", "Shift_L", "keyup", "Control_L", "keyup", "Insert") + command(input.Command("tentacle/test/wormhole")) + // All modifiers released: an ordinary W must reach the focused application. + key("key", "w") + key("key", "F9") + command(input.Command("tentacle/test/global")) + if err := listener.SetKeyBindings(ctx, []input.BindingOverride{{Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.Preferences, Keys: []string{"F9"}}}); err != nil { + t.Fatal(err) + } + key("key", "F9") + command(input.Preferences) + if err := listener.SetKeyBindings(ctx, nil); err != nil { + t.Fatal(err) + } + key("key", "F9") + command(input.Command("tentacle/test/global")) + key("keydown", "Insert", "key", "h", "keyup", "Insert") + command(input.ToggleLearnMode) + key("key", "F9") + command(input.LearnKey) + key("key", "Escape") + command(input.ToggleLearnMode) + listener.SetBrowseNavigation(true) + for !listener.BrowseNavigationEnabled() { + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + key("key", "F6") + command(input.Command("tentacle/test/browse")) + listener.SetBrowseNavigation(false) + for listener.browseApplied.Load() { + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + key("key", "F6") + key("key", "F9") + command(input.Command("tentacle/test/global")) // F6 outside browse mode must not dispatch. + competitor := NewCommands([]string{"KP_Insert"}, input.LaptopKeyboardLayout) + if err := competitor.SetKeyBindings(ctx, []input.BindingOverride{{Layout: input.LaptopKeyboardLayout, Scope: "global", Command: input.PresentDate, Keys: []string{"F10"}}}); err != nil { + t.Fatal(err) + } + if err := competitor.Start(ctx); err != nil { + t.Fatal(err) + } + collision := input.CloneBindingOverrides(custom) + collision[0].Keys = []string{"F10"} + if err := listener.SetTentacleBindings(ctx, collision); err == nil { + t.Fatal("accepted conflicting native grab") + } + key("key", "F9") + command(input.Command("tentacle/test/global")) // Native rollback retained the old shortcut. + browseCollision := input.CloneBindingOverrides(custom) + browseCollision[2].Keys = []string{"F10"} + if err := listener.SetTentacleBindings(ctx, browseCollision); err == nil { + t.Fatal("accepted conflicting prospective browse grab") + } + key("key", "F9") + command(input.Command("tentacle/test/global")) + if err := competitor.Stop(ctx); err != nil { + t.Fatal(err) + } + unavailable := input.CloneBindingOverrides(custom) + unavailable[0].Keys = []string{"Cthulhu+F35"} + if err := listener.SetTentacleBindings(ctx, unavailable); err == nil { + t.Fatal("accepted unavailable key") + } + key("key", "F9") + command(input.Command("tentacle/test/global")) // Rejected update preserved the previous router. + listener.SetSecureInputActive(true) + for listener.CommandGrabsEnabled() { + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + key("key", "F9") + listener.SetSecureInputActive(false) + for !listener.CommandGrabsEnabled() { + select { + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + key("key", "F9") + command(input.Command("tentacle/test/global")) + if err := listener.SetTentacleBindings(ctx, nil); err != nil { + t.Fatal(err) + } + if len(listener.TentacleBindings()) != 0 { + t.Fatal("removed bindings still published") + } + key("key", "F9") + key("keydown", "Insert", "key", "space", "keyup", "Insert") + command(input.Preferences) +} diff --git a/internal/platform/xorg/ui_native_test.go b/internal/platform/xorg/ui_native_test.go new file mode 100644 index 0000000..4f3aab9 --- /dev/null +++ b/internal/platform/xorg/ui_native_test.go @@ -0,0 +1,206 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestNativeInternalUICapturesAndReleases(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + log, err := os.CreateTemp(t.TempDir(), "keys-") + if err != nil { + t.Fatal(err) + } + defer log.Close() + probe := exec.CommandContext(ctx, "stdbuf", "-oL", "xev", "-name", "Internal UI probe", "-event", "keyboard") + probe.Stdout = log + if err := probe.Start(); err != nil { + t.Fatal(err) + } + defer func() { _ = probe.Process.Kill(); _ = probe.Wait() }() + var window string + for window == "" { + data, err := exec.CommandContext(ctx, "xdotool", "search", "--onlyvisible", "--name", "^Internal UI probe$").Output() + if err == nil { + window = strings.TrimSpace(string(data)) + } + if ctx.Err() != nil { + t.Fatal("probe did not open") + } + time.Sleep(10 * time.Millisecond) + } + if err := exec.CommandContext(ctx, "xdotool", "windowfocus", window).Run(); err != nil { + t.Fatal(err) + } + listener := NewCommands([]string{"Insert"}, input.DesktopKeyboardLayout) + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + key := func(names ...string) { + t.Helper() + args := append([]string{"key"}, names...) + if data, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("keys %v: %v %s", names, err, data) + } + } + want := func(command input.Command) input.CommandEvent { + t.Helper() + select { + case event := <-listener.Commands(): + if event.Command != command { + t.Fatalf("command=%s, want %s", event.Command, command) + } + return event + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatalf("missing %s", command) + } + return input.CommandEvent{} + } + key("Insert+shift+a") + opened := want(input.ShowActions) + if opened.UISession == 0 || listener.InternalUISession() != opened.UISession { + t.Fatal("actions did not capture atomically") + } + for _, name := range []string{"Down", "Up", "shift+a", "exclam", "U00e9", "Return"} { + key(name) + event := want(input.InternalUIKey) + if event.UISession != opened.UISession { + t.Fatal("wrong session") + } + if name == "shift+a" && event.Text != "A" { + t.Fatalf("shift translation=%q", event.Text) + } + if name == "exclam" && event.Text != "!" { + t.Fatalf("punctuation=%q", event.Text) + } + if name == "U00e9" && event.Text != "é" { + t.Fatalf("unicode=%q", event.Text) + } + } + if focus, err := exec.CommandContext(ctx, "xdotool", "getwindowfocus").Output(); err != nil || strings.TrimSpace(string(focus)) != window { + t.Fatal("capture changed application focus") + } + key("Escape") + want(input.InternalUIKey) + for listener.InternalUIEchoActive() { + if ctx.Err() != nil { + t.Fatal("Escape did not release") + } + time.Sleep(time.Millisecond) + } + key("y") + // An independently opened form uses the same ownership and stale-close rules. + second, err := listener.BeginInternalUI(ctx) + if err != nil { + t.Fatal(err) + } + if err := listener.EndInternalUI(ctx, opened.UISession); err != nil { + t.Fatal(err) + } + if listener.InternalUISession() != second { + t.Fatal("stale close revoked new form") + } + key("z") + want(input.InternalUIKey) + if err := exec.CommandContext(ctx, "xdotool", "keydown", "Return").Run(); err != nil { + t.Fatal(err) + } + want(input.InternalUIKey) + closed := make(chan error, 1) + go func() { closed <- listener.EndInternalUI(ctx, second) }() + for listener.InternalUISession() != 0 { + if ctx.Err() != nil { + t.Fatal("held-key close did not revoke UI") + } + time.Sleep(time.Millisecond) + } + select { + case <-closed: + t.Fatal("close acknowledged before physical release") + default: + } + if err := exec.CommandContext(ctx, "xdotool", "keyup", "Return").Run(); err != nil { + t.Fatal(err) + } + if err := <-closed; err != nil { + t.Fatal(err) + } + if err := listener.EndInternalUI(ctx, second); err != nil { + t.Fatal(err) + } + third, err := listener.BeginInternalUI(ctx) + if err != nil { + t.Fatal(err) + } + if err := exec.CommandContext(ctx, "xdotool", "keydown", "Shift_L", "F12").Run(); err != nil { + t.Fatal(err) + } + want(input.InternalUIKey) + listener.SetSecureInputActive(true) + for listener.InternalUISession() != 0 || listener.InternalUIEchoActive() { + if ctx.Err() != nil { + t.Fatal("lock did not revoke") + } + time.Sleep(time.Millisecond) + } + if err := exec.CommandContext(ctx, "xdotool", "keyup", "F12", "Shift_L").Run(); err != nil { + t.Fatal(err) + } + if _, err := listener.BeginInternalUI(ctx); err == nil { + t.Fatal("opened during lock") + } + listener.SetSecureInputActive(false) + if err := listener.EndInternalUI(ctx, third); err != nil { + t.Fatal(err) + } + if background := os.Getenv("CTHULHU_UI_BACKGROUND"); background != "" { + fourth, err := listener.BeginInternalUI(ctx) + if err != nil { + t.Fatal(err) + } + if err := exec.CommandContext(ctx, "xdotool", "windowfocus", background).Run(); err != nil { + t.Fatal(err) + } + dismissed := want(input.InternalUIDismiss) + if dismissed.UISession != fourth || listener.InternalUISession() != 0 { + t.Fatal("focus change did not revoke interaction") + } + if err := exec.CommandContext(ctx, "xdotool", "windowfocus", window).Run(); err != nil { + t.Fatal(err) + } + } + key("Insert+t") + want(input.PresentTime) + key("y") + _ = probe.Process.Kill() + _ = probe.Wait() + data, err := os.ReadFile(log.Name()) + if err != nil { + t.Fatal(err) + } + for _, name := range []string{"keysym 0xff54, Down", "keysym 0xff52, Up", "keysym 0xff0d, Return", "keysym 0xff1b, Escape", "keysym 0x7a, z", "keysym 0x41, A", "keysym 0x21, exclam", "keysym 0xe9, eacute"} { + if strings.Contains(string(data), name) { + t.Fatalf("UI key leaked to application: %s", name) + } + } + if !strings.Contains(string(data), "keysym 0x79, y") { + t.Fatal("ordinary typing did not resume") + } +} diff --git a/internal/platform/xorg/window_title.c b/internal/platform/xorg/window_title.c new file mode 100644 index 0000000..fd100c9 --- /dev/null +++ b/internal/platform/xorg/window_title.c @@ -0,0 +1,273 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "window_title.h" +#include "commands_native.h" +#include +#include +#include +#include +#include +#include +#include + +static unsigned long read_pid(Display *display, Window window); +static int wine_process(Display *display, Window window) { + unsigned long pid = read_pid(display, window); + if (!pid) return 0; + char path[64], executable[1024]; + snprintf(path, sizeof(path), "/proc/%lu/exe", pid); + ssize_t length = readlink(path, executable, sizeof(executable) - 1); + if (length <= 0 || length >= (ssize_t)sizeof(executable) - 1) return 0; + executable[length] = 0; + const char *name = strrchr(executable, '/'); + if (!name) return 0; + ++name; + return !strcmp(name, "wine") || !strcmp(name, "wine64") || + !strcmp(name, "wine-preloader") || !strcmp(name, "wine64-preloader"); +} + +static char *read_title(Display *display, Window window) { + Atom actualType; + int format; + unsigned long items, remaining; + unsigned char *data = NULL; + Atom name = XInternAtom(display, "_NET_WM_NAME", False); + if (XGetWindowProperty(display, window, name, 0, 1024, False, + XInternAtom(display, "UTF8_STRING", False), &actualType, &format, + &items, &remaining, &data) == Success && data && format == 8 && items) { + char *title = strndup((char *)data, items); + XFree(data); + return title; + } + if (data) XFree(data); + XTextProperty property = {0}; + char *title = NULL; + if (XGetWMName(display, window, &property) && property.value) { + char **strings = NULL; + int count = 0; + if (Xutf8TextPropertyToTextList(display, &property, &strings, &count) >= Success && count > 0) + title = strdup(strings[0]); + if (strings) XFreeStringList(strings); + XFree(property.value); + } + return title; +} + +static int is_wine_desktop(const char *title) { + return title && strcasestr(title, "Wine Desktop") != NULL; +} + +static char *read_application(Display *display, Window window) { + XClassHint hint = {0}; + char *application = NULL; + if (XGetClassHint(display, window, &hint)) { + const char *name = hint.res_name && *hint.res_name ? hint.res_name : hint.res_class; + if (name) application = strdup(name); + } + if (hint.res_name) XFree(hint.res_name); + if (hint.res_class) XFree(hint.res_class); + return application; +} + +static Window parent_window(Display *display, Window window) { + Window root, parent, *children = NULL; + unsigned int count; + if (!XQueryTree(display, window, &root, &parent, &children, &count)) return None; + if (children) XFree(children); + return parent; +} + +static int is_descendant(Display *display, Window window, Window desktop) { + for (int depth = 0; window && depth < 64; depth++) { + if (window == desktop) return 1; + Window parent = parent_window(display, window); + if (parent == window) break; + window = parent; + } + return 0; +} + +static int usable_child(Display *display, Window window, WindowTitle *result) { + XWindowAttributes attributes; + if (!XGetWindowAttributes(display, window, &attributes) || attributes.map_state != IsViewable) + return 0; + char *title = read_title(display, window); + if (!title || !*title || is_wine_desktop(title) || + !strcasecmp(title, "Default IME") || !strcasecmp(title, "Program Manager")) { + free(title); + return 0; + } + char *application = read_application(display, window); + XClassHint hint = {0}; + XGetClassHint(display, window, &hint); + const char *identifiers[] = {hint.res_name, hint.res_class}; + int infrastructure = 0; + for (unsigned int i = 0; i < 2; i++) { + if (identifiers[i] && (!strcasecmp(identifiers[i], "wine-access.exe") || + !strcasecmp(identifiers[i], "cthulhu-wine-access.exe") || + (!strcasecmp(identifiers[i], "nvda.exe") && !strcasecmp(title, "NVDA")))) + infrastructure = 1; + } + if (hint.res_name) XFree(hint.res_name); + if (hint.res_class) XFree(hint.res_class); + if (infrastructure) { + free(title); + free(application); + return 0; + } + result->titleWindow = window; + result->title = title; + result->application = application; + return 1; +} + +// Prefer the focused child's titled ancestor, after proving that focus belongs +// to this desktop. Fallback traversal is bounded and ignores hidden children. +static void read_wine_title(Display *display, Window desktop, WindowTitle *result) { + Window focus; + int revert; + XGetInputFocus(display, &focus, &revert); + if (focus != None && focus != PointerRoot && is_descendant(display, focus, desktop)) { + for (int depth = 0; focus && focus != desktop && depth < 64; depth++) { + if (usable_child(display, focus, result)) { result->focused = 1; return; } + focus = parent_window(display, focus); + } + } + Window queue[200] = {desktop}; + unsigned int queued = 1; + for (unsigned int index = 0; index < queued; index++) { + if (index && usable_child(display, queue[index], result)) return; + Window root, parent, *children = NULL; + unsigned int count; + if (XQueryTree(display, queue[index], &root, &parent, &children, &count)) { + for (unsigned int child = 0; child < count && queued < 200; child++) + queue[queued++] = children[child]; + } + if (children) XFree(children); + } +} + +WindowTitle cthulhu_read_window_title(Display *display, Window window) { + WindowTitle result = {0}; + if (!display || !window) return result; + cthulhu_x11_begin_read(display); + XWindowAttributes attributes; + if (XGetWindowAttributes(display, window, &attributes) && attributes.map_state == IsViewable) { + result.window = window; + char *title = read_title(display, window); + if (is_wine_desktop(title)) { + result.wine = 1; + free(title); + read_wine_title(display, window, &result); + } else { + result.titleWindow = window; + result.title = title; + result.application = read_application(display, window); + XClassHint hint = {0}; + if (XGetClassHint(display, window, &hint)) { + result.wine = hint.res_class && !strcasecmp(hint.res_class, "Wine"); + if (hint.res_name) XFree(hint.res_name); + if (hint.res_class) XFree(hint.res_class); + } + // Current Wine uses the program's .exe for both WM_CLASS fields. + // The actual client process distinguishes it from a Linux window + // with the same title or class, without any prefix environment. + result.wine = result.wine || wine_process(display, window); + Window focus; + int revert; + XGetInputFocus(display, &focus, &revert); + result.focused = focus != None && focus != PointerRoot && is_descendant(display, focus, window); + } + XWindowAttributes child; + Window translated; + if (result.titleWindow && XGetWindowAttributes(display, result.titleWindow, &child) && + child.map_state == IsViewable && XTranslateCoordinates(display, result.titleWindow, + DefaultRootWindow(display), 0, 0, &result.x, &result.y, &translated)) { + result.width = child.width; + result.height = child.height; + } + } + if (cthulhu_x11_end_read(display)) { + free(result.title); + free(result.application); + result = (WindowTitle){0}; + } + return result; +} + +static unsigned long read_pid(Display *display, Window window) { + Atom type; + int format; + unsigned long items, remaining, pid = 0; + unsigned char *data = NULL; + if (XGetWindowProperty(display, window, XInternAtom(display, "_NET_WM_PID", False), + 0, 1, False, XA_CARDINAL, &type, &format, &items, &remaining, &data) == Success && + data && type == XA_CARDINAL && format == 32 && items) pid = *(unsigned long *)data; + if (data) XFree(data); + return pid; +} + +// Enumerate clients, then Wine desktop children, without relying on focus. +// A bounded root traversal also serves window managers without an EWMH list. +ApplicationWindow *cthulhu_list_application_windows(Display *display, int *count) { + *count = 0; + if (!display) return NULL; + ApplicationWindow *result = calloc(4096, sizeof(*result)); + if (!result) return NULL; + cthulhu_x11_begin_read(display); + Window queue[4096]; + int wine[4096] = {0}; + unsigned int queued = 0; + Atom type; + int format; + unsigned long items, remaining; + unsigned char *data = NULL; + Window root = DefaultRootWindow(display); + if (XGetWindowProperty(display, root, XInternAtom(display, "_NET_CLIENT_LIST", False), + 0, 4096, False, XA_WINDOW, &type, &format, &items, &remaining, &data) == Success && + data && type == XA_WINDOW && format == 32 && items) { + Window *clients = (Window *)data; + for (unsigned long i = 0; i < items && queued < 4096; i++) queue[queued++] = clients[i]; + } else { + queue[queued++] = root; + } + if (data) XFree(data); + for (unsigned int i = 0; i < queued; i++) { + char *title = read_title(display, queue[i]); + int desktop = is_wine_desktop(title); + free(title); + char *application = read_application(display, queue[i]); + int descend = !application || !*application || desktop || wine[i]; + if (application && *application && !desktop) { + // Skip Wine infrastructure using the same title discovery rules. + WindowTitle child = {0}; + if (!wine[i] || usable_child(display, queue[i], &child)) { + result[*count] = (ApplicationWindow){application, read_pid(display, queue[i]), wine[i]}; + (*count)++; + application = NULL; + } + free(child.title); + free(child.application); + } + free(application); + if (descend) { + Window treeRoot, parent, *children = NULL; + unsigned int childCount; + if (XQueryTree(display, queue[i], &treeRoot, &parent, &children, &childCount)) { + for (unsigned int j = 0; j < childCount && queued < 4096; j++) { + queue[queued] = children[j]; + wine[queued++] = wine[i] || desktop; + } + } + if (children) XFree(children); + } + } + cthulhu_x11_end_read(display); + return result; +} + +void cthulhu_free_application_windows(ApplicationWindow *windows, int count) { + for (int i = 0; i < count; i++) free(windows[i].application); + free(windows); +} diff --git a/internal/platform/xorg/window_title.go b/internal/platform/xorg/window_title.go new file mode 100644 index 0000000..e3aefc9 --- /dev/null +++ b/internal/platform/xorg/window_title.go @@ -0,0 +1,42 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +/* +#cgo CFLAGS: -D_GNU_SOURCE +#include "window_title.h" +#include +*/ +import "C" + +import ( + "strings" + "unsafe" +) + +// WindowTitle contains only copied metadata. Window is the foreground client; +// TitleWindow may be a program inside its Wine desktop. Application is WM_CLASS +// for programs without an AT-SPI application identity. +type WindowTitle struct { + Window, TitleWindow uint64 + Title, Application string + Wine, Focused bool + Client Foreground +} + +// ReadTitle runs on the same native owner thread as Read and Close. +func (reader *ForegroundReader) ReadTitle(window uint64) WindowTitle { + if reader == nil || reader.display == nil || window == 0 { + return WindowTitle{} + } + value := C.cthulhu_read_window_title(reader.display, C.Window(window)) + defer C.free(unsafe.Pointer(value.title)) + defer C.free(unsafe.Pointer(value.application)) + return WindowTitle{Window: uint64(value.window), TitleWindow: uint64(value.titleWindow), + Wine: value.wine != 0, Focused: value.focused != 0, + Client: Foreground{Known: value.width > 0 && value.height > 0, Window: uint64(value.titleWindow), X: int(value.x), Y: int(value.y), Width: int(value.width), Height: int(value.height)}, + Title: strings.TrimSpace(strings.ToValidUTF8(C.GoString(value.title), "\ufffd")), + Application: strings.TrimSpace(strings.ToValidUTF8(C.GoString(value.application), "\ufffd"))} +} diff --git a/internal/platform/xorg/window_title.h b/internal/platform/xorg/window_title.h new file mode 100644 index 0000000..59879eb --- /dev/null +++ b/internal/platform/xorg/window_title.h @@ -0,0 +1,21 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#ifndef CTHULHU_WINDOW_TITLE_H +#define CTHULHU_WINDOW_TITLE_H +#include + +typedef struct { + unsigned long window, titleWindow; + char *title, *application; + int wine, focused, x, y, width, height; +} WindowTitle; +WindowTitle cthulhu_read_window_title(Display *display, Window window); +typedef struct { + char *application; + unsigned long pid; + int wine; +} ApplicationWindow; +ApplicationWindow *cthulhu_list_application_windows(Display *display, int *count); +void cthulhu_free_application_windows(ApplicationWindow *windows, int count); +#endif diff --git a/internal/platform/xorg/window_title_native_test.go b/internal/platform/xorg/window_title_native_test.go new file mode 100644 index 0000000..5fdb8d2 --- /dev/null +++ b/internal/platform/xorg/window_title_native_test.go @@ -0,0 +1,142 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package xorg + +import ( + "bufio" + "context" + "encoding/json" + "os" + "os/exec" + "runtime" + "testing" + "time" +) + +func TestNativeWindowTitleDiscovery(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_WINDOW_TITLES") != "1" { + t.Skip("isolated Xvfb fixture only") + } + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "python3", "-u", "../../../tests/window_title_fixture.py") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err = fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + if !scanner.Scan() { + t.Fatal("fixture did not start") + } + var windows map[string]uint64 + if err = json.Unmarshal(scanner.Bytes(), &windows); err != nil { + t.Fatal(err) + } + command := func(action, window, title string) { + t.Helper() + data, _ := json.Marshal(map[string]string{"action": action, "window": window, "title": title}) + if _, err = stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() || scanner.Text() != "ready" { + t.Fatal("fixture command failed") + } + } + reader := OpenForegroundReader() + if reader == nil { + t.Fatal("cannot open X11") + } + defer reader.Close() + // Flatpak's _NET_WM_PID is in a different namespace from the AT-SPI + // provider. XRes must identify the actual local connection owner instead. + xres := os.Getenv("CTHULHU_XRES_DISABLED") != "1" + if reader.clientPIDs != xres { + t.Fatalf("XRes client PID support = %v; want %v", reader.clientPIDs, xres) + } + checkPID := func(property int) { + t.Helper() + want := property + if xres { + want = fixture.Process.Pid + } + foreground := reader.Read() + if foreground.PID != want || foreground.PropertyPID != property { + t.Fatalf("foreground = %+v; want PID %d and property %d", foreground, want, property) + } + } + checkPID(0) + command("pid", "normal", "252") + checkPID(252) + checkPID(252) // cached reads must retain the host identity + command("pid", "normal", "253") + checkPID(253) + command("empty", "normal", "") + if foreground := reader.Read(); foreground.Window != 0 || foreground.PID != 0 || foreground.PropertyPID != 0 { + t.Fatalf("empty workspace retained a client: %+v", foreground) + } + command("activate", "normal", "") + checkPID(253) + applications := reader.ApplicationWindows() + var foundExample, foundGame bool + for _, application := range applications { + switch application.Application { + case "example": + foundExample = true + case "game.exe": + foundGame = application.Wine + case "wine-access.exe", "cthulhu-wine-access.exe", "hidden.exe": + t.Fatalf("infrastructure/hidden Wine window listed: %+v", application) + } + } + if !foundExample || !foundGame { + t.Fatalf("running applications incomplete: %+v", applications) + } + expect := func(window, titledWindow, title, application string) { + t.Helper() + foreground := reader.Read() + value := reader.ReadTitle(foreground.Window) + if value.Window != windows[window] || value.TitleWindow != windows[titledWindow] || value.Title != title || value.Application != application { + t.Fatalf("title = %+v; want %s/%s %q application %q", value, window, titledWindow, title, application) + } + } + expect("normal", "normal", "Example title", "example") + command("title", "normal", "Unicode café 日本語") + expect("normal", "normal", "Unicode café 日本語", "example") + command("legacy", "normal", "Legacy title") + expect("normal", "normal", "Legacy title", "example") + command("activate", "desktop", "") + checkPID(0) + command("focus", "control", "") + expect("desktop", "game", "Wine game", "game.exe") + command("title", "game", "Wine game loading") + expect("desktop", "game", "Wine game loading", "game.exe") + command("focus", "second", "") + expect("desktop", "second", "Wine dialog", "game.exe") + command("focus", "unrelated", "") + expect("desktop", "game", "Wine game loading", "game.exe") + command("hide", "game", "") + expect("desktop", "second", "Wine dialog", "game.exe") + command("destroy", "desktop", "") + if foreground := reader.Read(); foreground.Window != 0 || foreground.PID != 0 { + t.Fatalf("destroyed window retained a client: %+v", foreground) + } + if value := reader.ReadTitle(windows["desktop"]); value != (WindowTitle{}) { + t.Fatalf("destroyed desktop = %+v", value) + } + command("activate", "normal", "") + checkPID(253) + expect("normal", "normal", "Legacy title", "example") +} diff --git a/internal/platform/xorg/xterm_handoff_native_test.go b/internal/platform/xorg/xterm_handoff_native_test.go new file mode 100644 index 0000000..0988b48 --- /dev/null +++ b/internal/platform/xorg/xterm_handoff_native_test.go @@ -0,0 +1,191 @@ +package xorg + +import ( + "bufio" + "context" + "encoding/json" + "os" + "os/exec" + "path/filepath" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestNativeSuspendedQueuedKey(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + probe := filepath.Join(t.TempDir(), "suspension-probe") + if out, err := exec.CommandContext(ctx, "cc", "-I.", "../../../tests/xorg_suspension_probe.c", "commands_native.c", "-o", probe, "-lX11", "-lXtst", "-lxkbcommon", "-lpthread").CombinedOutput(); err != nil { + t.Fatalf("compile native probe: %v: %s", err, out) + } + for _, mode := range []string{"queued", "replay", "passive"} { + t.Run(mode, func(t *testing.T) { + if out, err := exec.CommandContext(ctx, probe, mode).CombinedOutput(); err != nil { + t.Fatalf("native suspension: %v: %s", err, out) + } + }) + } +} + +// Exercise the native grab owner, including the late SetCommandGrabs request +// made by accessibility focus handling after the native xterm handoff. +func TestNativeXTermHandoffKeepsKeypadReleased(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + for _, scenario := range []struct { + name string + learn, held bool + }{ + {name: "delayed_focus"}, + {name: "held_command", held: true}, + {name: "learn_mode", learn: true}, + } { + t.Run(scenario.name, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second) + defer cancel() + fixture := exec.CommandContext(ctx, "python3", "-u", "../../../tests/ocr_review_fixture.py") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + scanner := bufio.NewScanner(stdout) + if !scanner.Scan() { + t.Fatal("key sink did not start") + } + type deliveredKey struct { + Pressed bool + Symbol uint32 + } + action := func(command map[string]string) []deliveredKey { + t.Helper() + data, _ := json.Marshal(command) + if _, err := stdin.Write(append(data, '\n')); err != nil { + t.Fatal(err) + } + if !scanner.Scan() { + t.Fatal("key sink did not respond") + } + var state struct{ Keys []deliveredKey } + if err := json.Unmarshal(scanner.Bytes(), &state); err != nil { + t.Fatal(err) + } + return state.Keys + } + listener := NewCommands([]string{"Insert", "KP_Insert"}, input.DesktopKeyboardLayout) + if err := listener.Start(ctx); err != nil { + t.Fatal(err) + } + defer listener.Stop(context.Background()) + wait := func(predicate func() bool) { + t.Helper() + for !predicate() { + select { + case err := <-listener.Failures(): + t.Fatal(err) + case <-ctx.Done(): + t.Fatal(ctx.Err()) + case <-time.After(time.Millisecond): + } + } + } + focus := func(xterm bool) { + t.Helper() + wait(func() bool { + select { + case state := <-listener.FocusChanges(): + return state.Known && state.XTerm == xterm + default: + return false + } + }) + } + key := func(args ...string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil { + t.Fatalf("key injection: %v %s", err, out) + } + } + command := func(want input.Command) { + t.Helper() + select { + case got := <-listener.Commands(): + if got.Command != want { + t.Fatalf("command = %s, want %s", got.Command, want) + } + case <-ctx.Done(): + t.Fatal("reader command did not arrive") + } + } + focus(false) + if scenario.learn { + key("key", "Insert+h") + command(input.ToggleLearnMode) + } else { + if scenario.held { + defer exec.Command("xdotool", "keyup", "KP_Begin").Run() + key("keydown", "KP_Begin") + } else { + key("key", "KP_Begin") + } + command(input.ReviewCurrentWord) + if !scenario.held { + wait(func() bool { return !listener.CommandGrabActive() }) + } + } + action(map[string]string{"action": "class", "name": "XTerm"}) + focus(true) + if scenario.held { + if !listener.CommandGrabActive() { + t.Fatal("handoff released the keyboard before the command key") + } + key("keyup", "KP_Begin") + } + wait(func() bool { return !listener.commandsApplied.Load() }) + if !scenario.learn { + listener.SetCommandGrabs(true) + } + // Let several native focus polls see the unchanged xterm. A late + // accessibility resume must not reacquire any passive keypad grab. + time.Sleep(3 * xtermFocusCheckInterval) + for _, unknown := range []bool{false, true} { + if unknown { + action(map[string]string{"action": "unknown"}) + time.Sleep(2 * xtermFocusCheckInterval) + } + action(map[string]string{"action": "clear"}) + key("key", "KP_Begin") + keys := action(map[string]string{"action": "state"}) + if len(keys) != 2 || keys[0].Symbol != 0xff9d || !keys[0].Pressed || keys[1].Symbol != 0xff9d || keys[1].Pressed { + t.Fatalf("xterm keypad press/release = %+v; unknown=%t, grabs=%t, active=%t", keys, unknown, listener.CommandGrabsEnabled(), listener.CommandGrabActive()) + } + select { + case got := <-listener.Commands(): + t.Fatalf("xterm key became reader command: %+v", got) + default: + } + } + action(map[string]string{"action": "class", "name": "example"}) + action(map[string]string{"action": "activate"}) + focus(false) + wait(listener.CommandGrabsEnabled) + key("key", "KP_Begin") + command(input.ReviewCurrentWord) + wait(func() bool { return !listener.CommandGrabActive() }) + }) + } +} diff --git a/internal/preferences/applications.go b/internal/preferences/applications.go new file mode 100644 index 0000000..6fa3c61 --- /dev/null +++ b/internal/preferences/applications.go @@ -0,0 +1,135 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#cgo pkg-config: atspi-2 +#include +#include "native_applications.h" +*/ +import "C" + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "os" + "sort" + "strings" + "time" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +type applicationIdentity struct { + name string + pid int +} + +func application_choices(accessible []applicationIdentity, windows []xorg.ApplicationWindow) []string { + names := make(map[string]bool) + byPID := make(map[int]string) + add := func(name string) { + name = strings.TrimSpace(name) + if name != "" && !strings.HasPrefix(strings.ToLower(name), "cthulhu") { + names[name] = true + } + } + for _, application := range accessible { + add(application.name) + if application.pid != 0 { + byPID[application.pid] = application.name + } + } + for _, window := range windows { + name := window.Application + if !window.Wine && byPID[window.PID] != "" { + name = byPID[window.PID] + } + add(name) + } + var choices []string + for name := range names { + choices = append(choices, name) + } + sort.Slice(choices, func(i, j int) bool { return strings.ToLower(choices[i]) < strings.ToLower(choices[j]) }) + return choices +} + +func running_applications() []string { + var count C.int + native := C.prefs_application_names(&count) + defer C.prefs_free_application_names(native, count) + var accessible []applicationIdentity + for _, application := range unsafe.Slice(native, int(count)) { + name := C.GoString(application.name) + if strings.TrimSpace(name) == "" && application.pid != 0 { + // Match the reader's process-name fallback for nameless providers. + if content, err := os.ReadFile(fmt.Sprintf("/proc/%d/comm", application.pid)); err == nil { + name = strings.TrimSpace(string(content)) + } + } + accessible = append(accessible, applicationIdentity{name, int(application.pid)}) + } + reader := xorg.OpenForegroundReader() + defer reader.Close() + return application_choices(accessible, reader.ApplicationWindows()) +} + +// The chooser shares the preferences child and bounded pipe protocol. Cancel +// emits no request, so it cannot open a profile or submit settings. +func choose_application(ctx context.Context, updates <-chan Response, errorsIn <-chan error, output io.Writer) (Response, bool, error) { + choices := running_applications() + if C.prefs_application_chooser_init() == 0 { + return Response{}, false, errors.New("cannot open application chooser on this display") + } + defer C.prefs_application_chooser_close() + for _, choice := range choices { + name := C.CString(choice) + C.prefs_application_chooser_add(name) + C.free(unsafe.Pointer(name)) + } + C.prefs_application_chooser_present() + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + selected := false + for { + select { + case <-ctx.Done(): + return Response{}, false, ctx.Err() + case err := <-errorsIn: + return Response{}, false, err + case response := <-updates: + if response.Present { + C.prefs_application_chooser_present() + } else if selected { + return response, true, nil + } + case <-ticker.C: + C.prefs_application_chooser_iterate() + switch C.prefs_application_chooser_action() { + case 2: + return Response{}, false, nil + case 1: + if selected { + continue + } + name := C.prefs_application_chooser_selected() + if name == nil { + continue + } + application := C.GoString(name) + C.free(unsafe.Pointer(name)) + if err := json.NewEncoder(output).Encode(Request{Application: application}); err != nil { + return Response{}, false, err + } + selected = true + } + } + } +} diff --git a/internal/preferences/applications_test.go b/internal/preferences/applications_test.go new file mode 100644 index 0000000..7e617af --- /dev/null +++ b/internal/preferences/applications_test.go @@ -0,0 +1,23 @@ +package preferences + +import ( + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/platform/xorg" +) + +func TestApplicationChoicesUseProfileIdentityAndWineChildren(t *testing.T) { + accessible := []applicationIdentity{{"Example Browser", 1}, {"Cthulhu Preferences", 2}, {"Example Terminal", 3}, {"Unknown PID Application", 0}, {"Other Unknown PID Application", 0}} + windows := []xorg.ApplicationWindow{ + {Application: "browser-instance", PID: 1}, + {Application: "browser-second-window", PID: 1}, + {Application: "Game.exe", PID: 1, Wine: true}, + {Application: "Game.exe", Wine: true}, + {Application: "Example Editor", PID: 4}, + } + want := []string{"Example Browser", "Example Editor", "Example Terminal", "Game.exe", "Other Unknown PID Application", "Unknown PID Application"} + if got := application_choices(accessible, windows); !reflect.DeepEqual(got, want) { + t.Fatalf("applications = %v, want %v", got, want) + } +} diff --git a/internal/preferences/bindings.go b/internal/preferences/bindings.go new file mode 100644 index 0000000..5ea1fcf --- /dev/null +++ b/internal/preferences/bindings.go @@ -0,0 +1,147 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "strings" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +var modifierKeys = []string{"Insert", "KP_Insert", "Caps_Lock"} + +func (session *uiSession) setKeyBindings(values Values) { + session.bindingDraft = input.CloneBindingOverrides(values.KeyBindings) + setCheck("generalDesktopButton", values.KeyboardLayout != 2) + setCheck("generalLaptopButton", values.KeyboardLayout == 2) + setModifierKeys(values.CthulhuModifierKeys) + session.bindingLayout = values.KeyboardLayout + if session.bindingLayout != 2 { + session.bindingLayout = 1 + } + setCheck("keyBindingDesktopButton", session.bindingLayout == 1) + setCheck("keyBindingLaptopButton", session.bindingLayout == 2) + session.populateKeyBindings(0) +} + +func (session *uiSession) refreshKeyBindingLayout() { + layout := 1 + if getCheck("keyBindingLaptopButton") { + layout = 2 + } + if layout != session.bindingLayout && (layout == 1 || layout == 2) { + session.bindingLayout = layout + session.populateKeyBindings(0) + } +} + +func (session *uiSession) populateKeyBindings(selected int) { + session.bindingRows = input.BindingRows(input.KeyboardLayout(session.bindingLayout), session.bindingDraft) + C.prefs_bindings_clear() + for _, row := range session.bindingRows { + scope := "Global" + if row.Scope == "browse" { + scope = "Browse mode" + } + keys := row.Keys + if keys == "" { + keys = "Unbound" + } + label, scopeText, shortcuts, defaults := C.CString(row.Label), C.CString(scope), C.CString(keys), C.CString(row.DefaultKeys) + C.prefs_binding_append(label, scopeText, shortcuts, defaults) + C.free(unsafe.Pointer(label)) + C.free(unsafe.Pointer(scopeText)) + C.free(unsafe.Pointer(shortcuts)) + C.free(unsafe.Pointer(defaults)) + } + C.prefs_binding_select(C.int(selected)) + // Keep the editor empty when the selected command has been disabled. + if selected >= 0 && selected < len(session.bindingRows) { + id, text := C.CString("keyBindingEntry"), C.CString(session.bindingRows[selected].Keys) + C.prefs_entry_set(id, text) + C.free(unsafe.Pointer(id)) + C.free(unsafe.Pointer(text)) + } +} + +func (session *uiSession) editKeyBinding(action int) { + selected := int(C.prefs_binding_selected()) + if action != 7 && (selected < 0 || selected >= len(session.bindingRows)) { + return + } + draft := input.CloneBindingOverrides(session.bindingDraft) + var row input.BindingRow + if selected >= 0 && selected < len(session.bindingRows) { + row = session.bindingRows[selected] + } + kept := draft[:0] + for _, override := range draft { + matches := override.Layout == input.KeyboardLayout(session.bindingLayout) && (action == 7 || (override.Scope == row.Scope && override.Command == row.Command)) + if !matches { + kept = append(kept, override) + } + } + draft = kept + if action == 4 || action == 5 { + keys := []string{} + if action == 4 { + id := C.CString("keyBindingEntry") + text := C.GoString(C.prefs_entry_get(id)) + C.free(unsafe.Pointer(id)) + if strings.TrimSpace(text) != "" { + for _, key := range strings.Split(text, ";") { + chord, err := input.ParseCommandChord(key) + if err != nil { + status(err.Error(), true) + return + } + keys = append(keys, input.FormatCommandChord(chord)) + } + } + } + draft = append(draft, input.BindingOverride{Layout: input.KeyboardLayout(session.bindingLayout), Scope: row.Scope, Command: row.Command, Keys: keys}) + } + if err := input.ValidateBindingOverrides(draft); err != nil { + status(err.Error(), true) + return + } + session.bindingDraft = draft + session.populateKeyBindings(selected) + status("Binding updated. Apply or OK commits these changes.", true) +} + +func setModifierKeys(keys []string) { + for _, key := range modifierKeys { + enabled := false + for _, configured := range keys { + if configured == key { + enabled = true + break + } + } + id := C.CString(key) + C.prefs_modifier_set(id, boolean(enabled)) + C.free(unsafe.Pointer(id)) + } +} + +func getModifierKeys() []string { + keys := []string{} + for _, key := range modifierKeys { + id := C.CString(key) + if C.prefs_modifier_get(id) != 0 { + keys = append(keys, key) + } + C.free(unsafe.Pointer(id)) + } + return keys +} diff --git a/internal/preferences/braille.go b/internal/preferences/braille.go new file mode 100644 index 0000000..e2f25f3 --- /dev/null +++ b/internal/preferences/braille.go @@ -0,0 +1,111 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "errors" + "path/filepath" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/braille" +) + +func setBrailleChoice(brief, verbose string, value int) { + setCheck(brief, value == 0) + setCheck(verbose, value != 0) +} + +func setBrailleIndicator(prefix string, value int) { + suffix := map[int]string{0: "NoneButton", 0x40: "7Button", 0x80: "8Button", 0xc0: "BothButton"}[value] + setCheck(prefix+suffix, true) +} + +func getBrailleIndicator(prefix string) int { + for _, option := range []struct { + suffix string + dots int + }{ + {"7Button", 0x40}, {"8Button", 0x80}, {"BothButton", 0xc0}, + } { + if getCheck(prefix + option.suffix) { + return option.dots + } + } + return 0 +} + +func (session *uiSession) set_braille_values(values Values) { + setCheck("enableBrailleCheckButton", values.EnableBraille) + setCheck("contractedBrailleCheckButton", values.EnableContractedBraille) + setCheck("abbrevRolenames", values.Braille.AbbreviateRoles) + setCheck("disableBrailleEOLCheckButton", values.Braille.DisableEOL) + setCheck("enableBrailleWordWrapCheckButton", values.Braille.WordWrap) + setCheck("enableFlashMessagesCheckButton", values.Braille.FlashMessages) + setCheck("flashIsPersistentCheckButton", values.Braille.FlashPersistent) + setCheck("flashIsDetailedCheckButton", values.Braille.FlashDetailed) + setSpin("brailleFlashTimeSpinButton", float64(values.Braille.FlashTime)/1000) + setBrailleChoice("brailleBriefButton", "brailleVerboseButton", values.Braille.Verbosity) + setBrailleIndicator("brailleSelection", values.Braille.SelectionIndicator) + setBrailleIndicator("brailleLink", values.Braille.LinkIndicator) + session.contractionTables = braille.AvailableTables() + comboID := C.CString("contractionTableCombo") + C.prefs_combo_clear(comboID) + defaultLabel := C.CString("Automatic for current language") + C.prefs_combo_append(comboID, defaultLabel) + C.free(unsafe.Pointer(defaultLabel)) + selected := 0 + for index, table := range session.contractionTables { + label := C.CString(table.Label) + C.prefs_combo_append(comboID, label) + C.free(unsafe.Pointer(label)) + if table.File == values.BrailleContractionTable || filepath.Base(table.File) == values.BrailleContractionTable { + selected = index + 1 + } + } + if values.BrailleContractionTable != "" && selected == 0 { + // Keep a saved table available even after a locale change or package update. + session.contractionTables = append(session.contractionTables, braille.TableOption{ + Label: "Saved: " + filepath.Base(values.BrailleContractionTable), + File: values.BrailleContractionTable, + }) + label := C.CString(session.contractionTables[len(session.contractionTables)-1].Label) + C.prefs_combo_append(comboID, label) + C.free(unsafe.Pointer(label)) + selected = len(session.contractionTables) + } + C.prefs_combo_set(comboID, C.int(selected)) + C.free(unsafe.Pointer(comboID)) +} + +func (session *uiSession) get_braille_values(values *Values) error { + values.EnableBraille = getCheck("enableBrailleCheckButton") + values.EnableContractedBraille = getCheck("contractedBrailleCheckButton") + values.Braille.AbbreviateRoles = getCheck("abbrevRolenames") + values.Braille.DisableEOL = getCheck("disableBrailleEOLCheckButton") + values.Braille.WordWrap = getCheck("enableBrailleWordWrapCheckButton") + values.Braille.FlashMessages = getCheck("enableFlashMessagesCheckButton") + values.Braille.FlashPersistent = getCheck("flashIsPersistentCheckButton") + values.Braille.FlashDetailed = getCheck("flashIsDetailedCheckButton") + values.Braille.FlashTime = int(getSpin("brailleFlashTimeSpinButton") * 1000) + if getCheck("brailleVerboseButton") { + values.Braille.Verbosity = 1 + } + values.Braille.SelectionIndicator = getBrailleIndicator("brailleSelection") + values.Braille.LinkIndicator = getBrailleIndicator("brailleLink") + selectedTable := getCombo("contractionTableCombo") + if selectedTable < 0 || selectedTable > len(session.contractionTables) { + return errors.New("Choose a contraction table.") + } + if selectedTable > 0 { + values.BrailleContractionTable = session.contractionTables[selectedTable-1].File + } + return nil +} diff --git a/internal/preferences/catalog_protocol.go b/internal/preferences/catalog_protocol.go new file mode 100644 index 0000000..cad03fd --- /dev/null +++ b/internal/preferences/catalog_protocol.go @@ -0,0 +1,124 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +import ( + "bufio" + "context" + "encoding/json" + "fmt" + "io" + "sort" + + "git.stormux.org/storm/cthulhu/internal/speech" +) + +const initialMessageLimit = 512 * 1024 + +type catalogPart struct { + Catalog speech.Catalog + CatalogPending bool +} + +// EncodeInitial keeps each protocol line bounded without removing voices or +// languages. The helper assembles the catalog before constructing GTK controls. +func EncodeInitial(encoder *json.Encoder, response Response) error { + encoded, err := json.Marshal(response) + if err != nil { + return err + } + if len(encoded)+1 <= initialMessageLimit { + return encoder.Encode(json.RawMessage(encoded)) + } + catalog := response.Catalog + response.Catalog = nil + response.CatalogPending = true + encoded, err = json.Marshal(response) + if err != nil { + return err + } + if len(encoded)+1 > initialMessageLimit { + return fmt.Errorf("preferences settings exceed %d-byte protocol limit", initialMessageLimit) + } + if err := encoder.Encode(json.RawMessage(encoded)); err != nil { + return err + } + modules := make([]string, 0, len(catalog)) + for module := range catalog { + modules = append(modules, module) + } + sort.Strings(modules) + for _, module := range modules { + voices := catalog[module] + for { + count := min(len(voices), 128) + for { + encoded, err = json.Marshal(catalogPart{ + Catalog: speech.Catalog{module: voices[:count]}, CatalogPending: true, + }) + if err != nil { + return err + } + if len(encoded)+1 <= initialMessageLimit { + break + } + if count <= 1 { + return fmt.Errorf("preferences voice in module %q exceeds %d-byte protocol limit", module, initialMessageLimit) + } + count /= 2 + } + if err := encoder.Encode(json.RawMessage(encoded)); err != nil { + return err + } + voices = voices[count:] + if len(voices) == 0 { + break + } + } + } + return encoder.Encode(catalogPart{}) +} + +// read_responses owns catalog assembly for the lifetime of the helper pipe. +// Only complete responses reach GTK, including after application selection. +func read_responses(ctx context.Context, input io.Reader, updates chan<- Response, errorsIn chan<- error) { + scanner := bufio.NewScanner(input) + scanner.Buffer(make([]byte, 4096), 1024*1024) + var initial *Response + for scanner.Scan() { + var response Response + if err := json.Unmarshal(scanner.Bytes(), &response); err != nil { + errorsIn <- err + return + } + if initial != nil { + if initial.Catalog == nil { + initial.Catalog = make(speech.Catalog) + } + for module, voices := range response.Catalog { + initial.Catalog[module] = append(initial.Catalog[module], voices...) + } + if response.CatalogPending { + continue + } + response = *initial + response.CatalogPending = false + initial = nil + } else if response.CatalogPending { + initial = &response + continue + } + select { + case updates <- response: + case <-ctx.Done(): + return + } + } + err := scanner.Err() + if err == nil && initial != nil { + err = io.ErrUnexpectedEOF + } + errorsIn <- err +} diff --git a/internal/preferences/catalog_protocol_test.go b/internal/preferences/catalog_protocol_test.go new file mode 100644 index 0000000..fb2ca31 --- /dev/null +++ b/internal/preferences/catalog_protocol_test.go @@ -0,0 +1,113 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "io" + "reflect" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/speech" +) + +func TestInitialCatalogRoundTrip(t *testing.T) { + for _, size := range []struct{ count, nameBytes int }{{1, 100}, {6000, 100}, {4, 250000}} { + count := size.count + catalog := speech.Catalog{ + "espeak-ng": make([]speech.Voice, count), + "other": {{Name: "Other voice", Language: "es"}}, + "empty": nil, + } + for index := range catalog["espeak-ng"] { + catalog["espeak-ng"][index] = speech.Voice{Name: strings.Repeat("v", size.nameBytes), Language: "de"} + } + // The last entry must survive even when it lies beyond the old cutoff. + catalog["espeak-ng"][count-1] = speech.Voice{Name: "English voice", Language: "en"} + initial := Response{Catalog: catalog, Message: "Preferences ready.", Application: "Example", CanSave: true, Accepted: true} + var wire bytes.Buffer + encoder := json.NewEncoder(&wire) + if err := encoder.Encode(Response{ChooseApplication: true}); err != nil { + t.Fatal(err) + } + if err := EncodeInitial(encoder, initial); err != nil { + t.Fatal(err) + } + for _, line := range bytes.Split(bytes.TrimSpace(wire.Bytes()), []byte{'\n'}) { + if len(line)+1 > initialMessageLimit { + t.Fatalf("protocol line has %d bytes", len(line)+1) + } + } + // Reopening after the chooser uses the same response reader. Subsequent + // present requests must not be absorbed into the assembled catalog. + if err := encoder.Encode(Response{Present: true}); err != nil { + t.Fatal(err) + } + updates := make(chan Response, 3) + errorsIn := make(chan error, 1) + read_responses(t.Context(), &wire, updates, errorsIn) + if err := <-errorsIn; err != nil { + t.Fatal(err) + } + if got := <-updates; !got.ChooseApplication { + t.Fatal("application chooser response was mixed into the catalog") + } + if got := <-updates; !reflect.DeepEqual(got, initial) { + t.Fatalf("catalog or session metadata changed for %d voices", count) + } + if got := <-updates; !got.Present || got.Catalog != nil { + t.Fatal("present response was mixed into the initial catalog") + } + } +} + +func TestInitialCatalogRejectsOversizedEntry(t *testing.T) { + for _, initial := range []Response{ + {Message: strings.Repeat("x", initialMessageLimit)}, + {Catalog: speech.Catalog{"espeak-ng": {{Name: strings.Repeat("x", initialMessageLimit)}}}}, + } { + var wire bytes.Buffer + if err := EncodeInitial(json.NewEncoder(&wire), initial); err == nil { + t.Fatal("oversized settings or voice accepted") + } + } +} + +func TestInitialCatalogIncompleteAndCancellation(t *testing.T) { + updates := make(chan Response, 1) + errorsIn := make(chan error, 1) + read_responses(t.Context(), strings.NewReader(`{"CatalogPending":true}`+"\n"), updates, errorsIn) + if err := <-errorsIn; !errors.Is(err, io.ErrUnexpectedEOF) || len(updates) != 0 { + t.Fatalf("incomplete catalog reached the UI: %v", err) + } + ctx, cancel := context.WithCancel(t.Context()) + cancel() + read_responses(ctx, strings.NewReader("{}\n"), make(chan Response), errorsIn) +} + +func TestDefaultVoicesFiltersESpeakAndDefaultAlias(t *testing.T) { + t.Setenv("LC_ALL", "en_US.UTF-8") + voices := []speech.Voice{{Name: "German", Language: "de"}, {Name: "English", Language: "en-US"}} + session := &uiSession{catalog: speech.Catalog{"": voices, "espeak-ng": voices, "other": voices}} + for _, module := range []string{"", "espeak-ng"} { + if got := session.default_voices(module); !reflect.DeepEqual(got, voices[1:]) { + t.Fatalf("module %q: %v", module, got) + } + } + if got := session.default_voices("other"); !reflect.DeepEqual(got, voices) { + t.Fatal("other synthesizer was filtered") + } + if !reflect.DeepEqual(session.catalog["espeak-ng"], voices) { + t.Fatal("language selection lost the full catalog") + } + session.catalog[""] = voices[:1] + if got := session.default_voices(""); !reflect.DeepEqual(got, voices[:1]) { + t.Fatal("unidentified default synthesizer was filtered") + } +} diff --git a/internal/preferences/catalog_voices.go b/internal/preferences/catalog_voices.go new file mode 100644 index 0000000..53179ce --- /dev/null +++ b/internal/preferences/catalog_voices.go @@ -0,0 +1,32 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +import ( + "slices" + "strings" + + "git.stormux.org/storm/cthulhu/internal/speech" +) + +// default_voices filters eSpeak's language/variant combinations for controls +// without an explicit language selection. Saved voices remain available through +// the caller's selected-family entry, and the full language catalog is retained. +func (session *uiSession) default_voices(module string) []speech.Voice { + voices := session.catalog[module] + if strings.Contains(strings.ToLower(module), "espeak") { + return speech.LocaleVoices(voices) + } + if module == "" { + // Speech Dispatcher also lists the default synthesizer under an empty + // module name. Match its catalog to identify eSpeak without guessing. + for name, candidates := range session.catalog { + if strings.Contains(strings.ToLower(name), "espeak") && slices.Equal(voices, candidates) { + return speech.LocaleVoices(voices) + } + } + } + return voices +} diff --git a/internal/preferences/echo.go b/internal/preferences/echo.go new file mode 100644 index 0000000..7cca5c5 --- /dev/null +++ b/internal/preferences/echo.go @@ -0,0 +1,171 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "sort" + "strings" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +func echoChecks(values *Values) []struct { + id string + value *bool +} { + return []struct { + id string + value *bool + }{ + {"enableAlphabeticKeysCheckButton", &values.EnableAlphabeticKeys}, + {"enableNumericKeysCheckButton", &values.EnableNumericKeys}, + {"enablePunctuationKeysCheckButton", &values.EnablePunctuationKeys}, + {"enableSpaceCheckButton", &values.EnableSpace}, + {"enableModifierKeysCheckButton", &values.EnableModifierKeys}, + {"enableFunctionKeysCheckButton", &values.EnableFunctionKeys}, + {"enableActionKeysCheckButton", &values.EnableActionKeys}, + {"enableNavigationKeysCheckButton", &values.EnableNavigationKeys}, + {"enableDiacriticalKeysCheckButton", &values.EnableDiacriticalKeys}, + {"enableEchoByCharacterCheckButton", &values.EnableEchoByCharacter}, + {"enableEchoByWordCheckButton", &values.EnableEchoByWord}, + {"enableEchoBySentenceCheckButton", &values.EnableEchoBySentence}, + {"useCustomEchoVoiceCheckButton", &values.UseCustomEchoVoice}, + {"useCustomEchoForKeyCheckButton", &values.UseCustomEchoForKey}, + {"useCustomEchoForCharacterCheckButton", &values.UseCustomEchoForCharacter}, + {"useCustomEchoForWordCheckButton", &values.UseCustomEchoForWord}, + {"useCustomEchoForSentenceCheckButton", &values.UseCustomEchoForSentence}, + } +} + +func (session *uiSession) setEchoVoice(values Values) { + module := values.SpeechOutputModule + if values.UseCustomEchoSpeechServer { + module = values.EchoSpeechServer + } + session.echoModules = []string{""} + for module := range session.catalog { + if module != "" { + session.echoModules = append(session.echoModules, module) + } + } + sort.Strings(session.echoModules[1:]) + selected := 0 + if module != "" { + selected = -1 + for i, candidate := range session.echoModules { + if candidate == module { + selected = i + } + } + if selected < 0 { + selected = len(session.echoModules) + session.echoModules = append(session.echoModules, module) + } + } + labels := append([]string(nil), session.echoModules...) + labels[0] = "Default" + comboItems("echoSpeechServers", labels, selected) + session.populateEchoFamilies(module, values.EchoVoice.Family) + for _, item := range []struct { + id string + value *float64 + fallback float64 + }{ + {"echoRateScale", values.EchoVoice.Rate, voiceFallback(values.Rate, 50)}, + {"echoPitchScale", values.EchoVoice.AveragePitch, voiceFallback(values.Pitch, 5)}, + {"echoVolumeScale", values.EchoVoice.Gain, voiceFallback(values.Volume, 10)}, + } { + id := C.CString(item.id) + C.prefs_range_set(id, C.double(voiceFallback(item.value, item.fallback))) + C.free(unsafe.Pointer(id)) + } +} + +func voiceFallback(value *float64, fallback float64) float64 { + if value != nil { + return *value + } + return fallback +} + +func (session *uiSession) populateEchoFamilies(module string, selected *config.VoiceFamily) { + session.activeEchoModule = module + session.echoFamilies = []*config.VoiceFamily{nil} + labels := []string{"Default"} + index := 0 + for _, voice := range session.default_voices(module) { + family := &config.VoiceFamily{Name: voice.Name, Lang: voice.Language, Variant: voice.Variant} + session.echoFamilies = append(session.echoFamilies, family) + labels = append(labels, voice.Name+" ("+voice.Language+")") + if selected != nil && selected.Name == voice.Name && strings.EqualFold(strings.TrimSuffix(selected.Lang+"-"+selected.Dialect, "-"), voice.Language) { + index = len(labels) - 1 + } + } + if selected != nil && index == 0 { + index = len(labels) + session.echoFamilies = append(session.echoFamilies, selected) + labels = append(labels, selected.Name+" ("+selected.Lang+")") + } + comboItems("echoSpeechFamilies", labels, index) +} + +func (session *uiSession) selectedEchoModule() string { + i := getCombo("echoSpeechServers") + if i >= 0 && i < len(session.echoModules) { + return session.echoModules[i] + } + return "" +} + +func (session *uiSession) refreshEchoVoices() { + module := session.selectedEchoModule() + if module != session.activeEchoModule { + session.populateEchoFamilies(module, nil) + } +} + +func (session *uiSession) getEchoVoice() (config.Voice, string) { + var voice config.Voice + for _, item := range []struct { + id string + target **float64 + }{ + {"echoRateScale", &voice.Rate}, {"echoPitchScale", &voice.AveragePitch}, {"echoVolumeScale", &voice.Gain}, + } { + id := C.CString(item.id) + value := float64(C.prefs_number_value(id)) + C.free(unsafe.Pointer(id)) + *item.target = &value + } + i := getCombo("echoSpeechFamilies") + if i >= 0 && i < len(session.echoFamilies) { + voice.Family = session.echoFamilies[i] + } + return voice, session.selectedEchoModule() +} + +func set_echo_checks(values Values) { + setCheck("keyEchoDisabledRadio", !values.EnableKeyEcho) + setCheck("keyEchoEnabledRadio", values.EnableKeyEcho && !values.KeyEchoInEditFieldsOnly) + setCheck("keyEchoEditFieldsRadio", values.EnableKeyEcho && values.KeyEchoInEditFieldsOnly) + for _, check := range echoChecks(&values) { + setCheck(check.id, *check.value) + } +} + +func get_echo_checks(values *Values) { + values.EnableKeyEcho = !getCheck("keyEchoDisabledRadio") + values.KeyEchoInEditFieldsOnly = getCheck("keyEchoEditFieldsRadio") + for _, check := range echoChecks(values) { + *check.value = getCheck(check.id) + } +} diff --git a/internal/preferences/extensions.go b/internal/preferences/extensions.go new file mode 100644 index 0000000..80c50b6 --- /dev/null +++ b/internal/preferences/extensions.go @@ -0,0 +1,117 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "fmt" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" + "unsafe" +) + +func extension_page_key(page ExtensionPage) string { return page.Session + "/" + page.ID } + +// GTK owns native focus. Refreshes keep unchanged widgets and their unapplied +// drafts, and move focus to the notebook before removing a revoked page. +func (session *uiSession) set_extension_pages(pages []ExtensionPage) error { + selected := C.GoString(C.prefs_extension_selected()) + ids := map[string]bool{} + for _, page := range pages { + key := extension_page_key(page) + if page.Session == "" || ids[key] { + return fmt.Errorf("invalid extension page identity") + } + ids[key] = true + if err := tentaclewire.ValidateExtensions(tentaclewire.Extensions{Pages: []tentaclewire.PreferencePage{page.PreferencePage}}); err != nil { + return err + } + } + keep := map[string]bool{} + for _, previous := range session.extensionPages { + key := extension_page_key(previous) + for _, page := range pages { + if extension_page_key(page) == key && page.Revision == previous.Revision { + keep[key] = true + break + } + } + if !keep[key] { + cKey := C.CString(key) + C.prefs_extension_remove(cKey) + C.free(unsafe.Pointer(cKey)) + } + } + for _, page := range pages { + key := extension_page_key(page) + if keep[key] { + continue + } + cKey, title := C.CString(key), C.CString(page.Title) + C.prefs_extension_add(cKey, title) + C.free(unsafe.Pointer(title)) + for row, element := range page.Elements { + id, label := C.CString(element.ID), C.CString(element.Label) + C.prefs_extension_control(cKey, id, label, C.int(element.Kind), C.int(row), C.int(element.MaxLength), boolean(element.Disabled)) + C.free(unsafe.Pointer(label)) + for _, option := range element.Items { + optionID, optionLabel := C.CString(option.ID), C.CString(option.Label) + C.prefs_extension_option(cKey, id, optionID, optionLabel, boolean(option.Disabled)) + C.free(unsafe.Pointer(optionID)) + C.free(unsafe.Pointer(optionLabel)) + } + value := page.Values[element.ID] + text := value.Text + if element.Kind == interaction.List { + text = value.Selected + } + cText := C.CString(text) + C.prefs_extension_set(cKey, id, C.int(element.Kind), cText, boolean(value.Checked)) + C.free(unsafe.Pointer(cText)) + C.free(unsafe.Pointer(id)) + } + C.free(unsafe.Pointer(cKey)) + } + session.extensionPages = pages + if selected != "" { + key := C.CString(selected) + C.prefs_extension_select(key) + C.free(unsafe.Pointer(key)) + } + return nil +} +func (session *uiSession) extension_drafts() ([]PageDraft, error) { + var drafts []PageDraft + for _, page := range session.extensionPages { + values := map[string]interaction.Value{} + key := C.CString(extension_page_key(page)) + for _, element := range page.Elements { + id := C.CString(element.ID) + value := interaction.Value{} + switch element.Kind { + case interaction.List: + value.Selected = C.GoString(C.prefs_extension_text(key, id, C.int(element.Kind))) + case interaction.Entry: + value.Text = C.GoString(C.prefs_extension_text(key, id, C.int(element.Kind))) + case interaction.CheckBox: + value.Checked = C.prefs_extension_checked(key, id) != 0 + } + C.free(unsafe.Pointer(id)) + values[element.ID] = value + } + C.free(unsafe.Pointer(key)) + declaration := page.PreferencePage + declaration.Values = values + if err := tentaclewire.ValidateExtensions(tentaclewire.Extensions{Pages: []tentaclewire.PreferencePage{declaration}}); err != nil { + return nil, fmt.Errorf("Check the values on %s: %w", page.Title, err) + } + drafts = append(drafts, PageDraft{Session: page.Session, ID: page.ID, Revision: page.Revision, Values: values}) + } + return drafts, nil +} diff --git a/internal/preferences/general.go b/internal/preferences/general.go new file mode 100644 index 0000000..e2731db --- /dev/null +++ b/internal/preferences/general.go @@ -0,0 +1,79 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "errors" + "time" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/datetime" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func setFormatCombo(name string, options []datetime.Option, value string) { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + C.prefs_combo_clear(id) + for _, option := range options { + text := C.CString(option.Label) + C.prefs_combo_append(id, text) + C.free(unsafe.Pointer(text)) + } + C.prefs_combo_set(id, C.int(formatIndex(options, value))) +} + +func formatIndex(options []datetime.Option, value string) int { + for index, option := range options { + if option.Value == value { + return index + } + } + return 0 +} + +func (session *uiSession) set_general_values(values Values) { + session.progressBar = values.ProgressBar + session.setKeyBindings(values) + setCombo("progressBarOutputCombo", map[string]int{"off": 0, "beep": 1, "speak": 2, "both": 3}[values.ProgressBar.OutputMode]) + setCheck("reportBackgroundProgressBarsCheckButton", values.ProgressBar.ReportBackground) + now := time.Now() + setFormatCombo("timeFormatCombo", datetime.TimeOptions(now), values.TimeFormat) + setFormatCombo("dateFormatCombo", datetime.DateOptions(now), values.DateFormat) +} + +func (session *uiSession) get_general_values(values *Values) error { + values.KeyBindings = input.CloneBindingOverrides(session.bindingDraft) + values.KeyboardLayout = 1 + if getCheck("generalLaptopButton") { + values.KeyboardLayout = 2 + } + values.CthulhuModifierKeys = getModifierKeys() + ti, di := getCombo("timeFormatCombo"), getCombo("dateFormatCombo") + now := time.Now() + timeOptions := datetime.TimeOptions(now) + dateOptions := datetime.DateOptions(now) + if ti < 0 || ti >= len(timeOptions) || di < 0 || di >= len(dateOptions) { + return errors.New("Choose a time and date format.") + } + mode := getCombo("progressBarOutputCombo") + if mode < 0 || mode > 3 { + return errors.New("Choose a progress bar output mode.") + } + // Percentage intervals are configured in TOML, so retain them when the + // visible mode and background controls are applied or previewed. + values.ProgressBar = session.progressBar + values.ProgressBar.OutputMode = []string{"off", "beep", "speak", "both"}[mode] + values.ProgressBar.ReportBackground = getCheck("reportBackgroundProgressBarsCheckButton") + values.TimeFormat = timeOptions[ti].Value + values.DateFormat = dateOptions[di].Value + return nil +} diff --git a/internal/preferences/interruption_test.go b/internal/preferences/interruption_test.go new file mode 100644 index 0000000..8e32460 --- /dev/null +++ b/internal/preferences/interruption_test.go @@ -0,0 +1,27 @@ +package preferences + +import ( + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func TestSpeechInterruptionValuesRoundTrip(t *testing.T) { + settings := config.DefaultSettings() + values := FromSettings(settings) + values.SpeechInterruption = input.InterruptionSettings{Mode: input.InterruptCustomKeys, Keys: []string{"Tab", "Return"}} + merged, err := values.Merge(settings) + if err != nil || !reflect.DeepEqual(FromSettings(merged), values) { + t.Fatalf("interruption values did not round trip: %+v, %v", merged.SpeechInterruption, err) + } + values.SpeechInterruption.Keys[0] = "Escape" + if merged.SpeechInterruption.Keys[0] != "Tab" { + t.Fatal("merged settings share the UI's mutable keys") + } + values.SpeechInterruption.Keys = nil + if _, err := values.Merge(settings); err == nil { + t.Fatal("accepted custom mode without keys") + } +} diff --git a/internal/preferences/native.c b/internal/preferences/native.c new file mode 100644 index 0000000..5678caa --- /dev/null +++ b/internal/preferences/native.c @@ -0,0 +1,317 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native_internal.h" + +static GtkBuilder *builder; +static int action; +static int voice_changed; +static int echoPreview; +static gboolean echoPreviewFocus; +static const char *echoControls[] = {"echoRateScale", "echoPitchScale", "echoVolumeScale", + "echoSpeechServers", "echoSpeechFamilies"}; +// Borrowed from the builder for the duration of one Apply/OK request. +static GtkWidget *busy_focus; +void prefs_set_action(int value) { action = value; } +GtkWidget *prefs_widget(const char *id) { return GTK_WIDGET(gtk_builder_get_object(builder, id)); } +static void name_accessible_tree(AtkObject *object, const char *name) { + const char *current = atk_object_get_name(object); + if (!current || !current[0]) atk_object_set_name(object, name); + int children = atk_object_get_n_accessible_children(object); + for (int i = 0; i < children; i++) { + AtkObject *child = atk_object_ref_accessible_child(object, i); + if (!child) continue; + name_accessible_tree(child, name); + g_object_unref(child); + } +} +static void name_widget(const char *id, const char *name) { + name_accessible_tree(gtk_widget_get_accessible(prefs_widget(id)), name); +} +static void describe_combo_tree(AtkObject *object, const char *name, const char *value) { + AtkRole role = atk_object_get_role(object); + if (role == ATK_ROLE_COMBO_BOX || role == ATK_ROLE_PUSH_BUTTON || + role == ATK_ROLE_TOGGLE_BUTTON) { + atk_object_set_name(object, name); + atk_object_set_description(object, value); + } + int children = atk_object_get_n_accessible_children(object); + for (int i = 0; i < children; i++) { + AtkObject *child = atk_object_ref_accessible_child(object, i); + if (!child) continue; + describe_combo_tree(child, name, value); + g_object_unref(child); + } +} +static void combo_changed(GtkComboBox *combo, gpointer data) { + gchar *value = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo)); + describe_combo_tree(gtk_widget_get_accessible(GTK_WIDGET(combo)), + (const char *)data, value ? value : ""); + g_free(value); +} +void prefs_describe_combo(GtkWidget *control, const char *label) { + combo_changed(GTK_COMBO_BOX(control), (gpointer)label); +} +static void free_signal_data(gpointer data, GClosure *closure) { + (void)closure; + g_free(data); +} +static void set_focus_chain(const char *container_id, const char *ids[], unsigned int count) { + GList *chain = NULL; + for (unsigned int i = 0; i < count; i++) chain = g_list_append(chain, prefs_widget(ids[i])); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + gtk_container_set_focus_chain(GTK_CONTAINER(prefs_widget(container_id)), chain); + G_GNUC_END_IGNORE_DEPRECATIONS + g_list_free(chain); +} +static void clicked(GtkButton *button, gpointer data) { + action = GPOINTER_TO_INT(data); + if (action == 1 || action == 2) busy_focus = GTK_WIDGET(button); +} +static gboolean closing(GtkWidget *window, GdkEvent *event, gpointer data) { action = 3; return TRUE; } +static gboolean key(GtkWidget *window, GdkEventKey *event, gpointer data) { + if (event->keyval == GDK_KEY_Escape) { action = 3; return TRUE; } + return FALSE; +} +static void voice_value_changed(GtkWidget *control, gpointer data) { + (void)control; (void)data; + voice_changed = 1; +} +static void speech_number_changed(GtkWidget *control, gpointer data) { + g_object_set_data(G_OBJECT(control), "number-edited", GINT_TO_POINTER(1)); + voice_value_changed(control, data); +} +static gboolean echo_control_focused(GtkWidget *control) { + GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(prefs_widget("window"))); + return focus && (focus == control || gtk_widget_is_ancestor(focus, control)); +} +static void echo_value_changed(GtkWidget *control, gpointer data) { + if (echo_control_focused(control) && prefs_check_get("useCustomEchoVoiceCheckButton")) { + echoPreview = GPOINTER_TO_INT(data); + echoPreviewFocus = FALSE; + } +} +static void echo_focus_changed(GtkWindow *window, GtkWidget *focus, gpointer data) { + (void)window; (void)data; + echoPreview = 0; + if (!focus || !prefs_check_get("useCustomEchoVoiceCheckButton")) return; + for (unsigned i = 0; i < G_N_ELEMENTS(echoControls); i++) { + GtkWidget *control = prefs_widget(echoControls[i]); + if (focus == control || gtk_widget_is_ancestor(focus, control)) { + echoPreview = i + 1; + echoPreviewFocus = TRUE; + return; + } + } +} +static gboolean voice_scale_key_press(GtkWidget *control, GdkEventKey *event, gpointer data) { + (void)data; + if (event->state & gtk_accelerator_get_default_mod_mask()) return FALSE; + double step; + switch (event->keyval) { + case GDK_KEY_Up: case GDK_KEY_KP_Up: step = 1.0; break; + case GDK_KEY_Down: case GDK_KEY_KP_Down: step = -1.0; break; + case GDK_KEY_Right: case GDK_KEY_KP_Right: step = 0.1; break; + case GDK_KEY_Left: case GDK_KEY_KP_Left: step = -0.1; break; + default: return FALSE; + } + // GtkRange clamps at the adjustment's bounds and emits value-changed, + // preserving accessible value updates and the existing preview path. + GtkRange *range = GTK_RANGE(control); + gtk_range_set_value(range, gtk_range_get_value(range) + step); + return TRUE; +} +static void echo_sensitivity(GtkToggleButton *button, gpointer data) { + (void)button; (void)data; + int enabled = !prefs_check_get("keyEchoDisabledRadio"); + const char *categories[] = {"enableAlphabeticKeysCheckButton", "enableNumericKeysCheckButton", + "enablePunctuationKeysCheckButton", "enableSpaceCheckButton", "enableModifierKeysCheckButton", + "enableFunctionKeysCheckButton", "enableActionKeysCheckButton", "enableNavigationKeysCheckButton", + "enableDiacriticalKeysCheckButton"}; + for (unsigned i = 0; i < G_N_ELEMENTS(categories); i++) gtk_widget_set_sensitive(prefs_widget(categories[i]), enabled); + int custom = prefs_check_get("useCustomEchoVoiceCheckButton"); + const char *voice[] = {"echoSpeechServers", "echoSpeechFamilies", "echoRateScale", "echoPitchScale", "echoVolumeScale"}; + for (unsigned i = 0; i < G_N_ELEMENTS(voice); i++) gtk_widget_set_sensitive(prefs_widget(voice[i]), custom); + gtk_widget_set_sensitive(prefs_widget("useCustomEchoForKeyCheckButton"), custom && enabled); + gtk_widget_set_sensitive(prefs_widget("useCustomEchoForCharacterCheckButton"), custom && prefs_check_get("enableEchoByCharacterCheckButton")); + gtk_widget_set_sensitive(prefs_widget("useCustomEchoForWordCheckButton"), custom && prefs_check_get("enableEchoByWordCheckButton")); + gtk_widget_set_sensitive(prefs_widget("useCustomEchoForSentenceCheckButton"), custom && prefs_check_get("enableEchoBySentenceCheckButton")); +} +static void sound_sensitivity(GtkToggleButton *button, gpointer data) { + (void)button; (void)data; + int enabled = prefs_check_get("enableSoundCheckButton"); + const char *controls[] = {"soundVolumeScale", "soundSinkCombo", "soundThemeCombo", + "roleSoundPresentationCombo", "playSoundForRoleCheckButton", "playSoundForStateCheckButton", + "playSoundForPositionInSetCheckButton", "spatializeObjectSoundsCheckButton"}; + for (unsigned i = 0; i < G_N_ELEMENTS(controls); i++) gtk_widget_set_sensitive(prefs_widget(controls[i]), enabled); +} +static void ocr_sensitivity(GtkToggleButton *button, gpointer data) { + (void)button; (void)data; + gtk_widget_set_sensitive(prefs_widget("ocrBlackWhiteValueSpinButton"), prefs_check_get("ocrBlackWhiteCheckButton")); + gtk_widget_set_sensitive(prefs_widget("ocrRefreshIntervalSpinButton"), prefs_check_get("ocrAutoRefreshCheckButton")); +} +int prefs_init(const char *xml) { + if (!gtk_init_check(NULL, NULL)) return 0; + g_set_application_name("Cthulhu Preferences"); + builder = gtk_builder_new(); + GError *error = NULL; + if (!gtk_builder_add_from_string(builder, xml, -1, &error)) { + if (error) g_error_free(error); + g_object_unref(builder); builder = NULL; + return 0; + } + prefs_init_reading_settings(); + prefs_init_key_bindings(); + prefs_init_modifiers(); + prefs_init_interruption(); + prefs_init_pronunciation(); + prefs_init_text_attributes(); + prefs_init_tentacles(); + AtkObject *reading_accessible = gtk_widget_get_accessible(prefs_widget("readingSettingsTreeview")); + atk_object_set_name(reading_accessible, "Reading settings"); + atk_object_set_description(reading_accessible, "Use arrow keys to move between settings and Space to toggle the selected setting."); + g_signal_connect(prefs_widget("apply"), "clicked", G_CALLBACK(clicked), GINT_TO_POINTER(1)); + g_signal_connect(prefs_widget("save"), "clicked", G_CALLBACK(clicked), GINT_TO_POINTER(2)); + g_signal_connect(prefs_widget("cancel"), "clicked", G_CALLBACK(clicked), GINT_TO_POINTER(3)); + g_signal_connect(prefs_widget("window"), "delete-event", G_CALLBACK(closing), NULL); + g_signal_connect(prefs_widget("window"), "key-press-event", G_CALLBACK(key), NULL); + const char *ids[] = {"rate", "pitch", "volume"}; + for (int i = 0; i < 3; i++) { + g_signal_connect(prefs_widget(ids[i]), "value-changed", G_CALLBACK(speech_number_changed), NULL); + } + const char *voiceScales[] = {"rate", "pitch", "volume", "echoRateScale", "echoPitchScale", "echoVolumeScale"}; + for (unsigned i = 0; i < G_N_ELEMENTS(voiceScales); i++) { + GtkWidget *control = prefs_widget(voiceScales[i]); + g_signal_connect(control, "key-press-event", G_CALLBACK(voice_scale_key_press), NULL); + atk_object_set_description(gtk_widget_get_accessible(control), + "Up and Down change by 1; Left and Right change by 0.1."); + } + for (unsigned i = 0; i < G_N_ELEMENTS(echoControls); i++) + g_signal_connect(prefs_widget(echoControls[i]), i < 3 ? "value-changed" : "changed", + G_CALLBACK(echo_value_changed), GINT_TO_POINTER(i + 1)); + g_signal_connect(prefs_widget("window"), "set-focus", G_CALLBACK(echo_focus_changed), NULL); + const char *voiceCombos[] = { + "speechSystems", "speechServers", "speechLanguages", "speechFamilies", "voiceTypesCombo", "hardwareBaudCombo", + }; + for (unsigned i = 0; i < G_N_ELEMENTS(voiceCombos); i++) { + g_signal_connect(prefs_widget(voiceCombos[i]), "changed", + G_CALLBACK(voice_value_changed), NULL); + } + g_signal_connect(prefs_widget("hardwareDeviceEntry"), "changed", G_CALLBACK(voice_value_changed), NULL); + GtkEntryCompletion *completion = gtk_entry_completion_new(); + GtkListStore *devices = gtk_list_store_new(1, G_TYPE_STRING); + gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(devices)); + gtk_entry_completion_set_text_column(completion, 0); + gtk_entry_completion_set_inline_completion(completion, TRUE); + gtk_entry_set_completion(GTK_ENTRY(prefs_widget("hardwareDeviceEntry")), completion); + g_object_unref(completion); + g_object_unref(devices); + const char *labelled[] = {"rate", "pitch", "volume"}; + for (unsigned i = 0; i < G_N_ELEMENTS(labelled); i++) { + gchar *id = g_strconcat(labelled[i], "_label", NULL); + name_widget(labelled[i], gtk_label_get_text(GTK_LABEL(prefs_widget(id)))); + g_free(id); + } + const struct { const char *id; const char *name; } named[] = { + {"timeFormatCombo", "Time format"}, + {"dateFormatCombo", "Date format"}, + {"progressBarOutputCombo", "Progress bar output"}, + {"sayAllStyle", "Say All by"}, + {"soundVolumeScale", "Sound volume"}, + {"soundSinkCombo", "Audio backend"}, + {"soundThemeCombo", "Sound theme"}, + {"roleSoundPresentationCombo", "Element presentation"}, + {"speechSystems", "Speech system"}, + {"speechServers", "Speech synthesizer"}, + {"speechLanguages", "Language"}, + {"speechFamilies", "Person"}, + {"speechHistoryLimitSpinButton", "Speech history entries"}, + {"voiceTypesCombo", "Voice type"}, + {"hardwareDeviceEntry", "Serial device"}, + {"hardwareBaudCombo", "Serial baud rate"}, + {"contractionTableCombo", "Contraction table"}, + {"brailleFlashTimeSpinButton", "Flash message duration"}, + {"echoSpeechServers", "Key echo speech synthesizer"}, + {"echoSpeechFamilies", "Key echo person"}, + {"echoRateScale", "Key echo rate"}, + {"echoPitchScale", "Key echo pitch"}, + {"echoVolumeScale", "Key echo volume"}, + {"keyBindingEntry", "Shortcuts"}, + {"ocrScaleSpinButton", "OCR scale factor"}, + {"ocrBlackWhiteValueSpinButton", "Black and white threshold"}, + {"ocrLanguageEntry", "OCR recognition languages"}, + {"ocrLayoutCombo", "OCR text layout"}, + {"ocrRefreshIntervalSpinButton", "OCR refresh interval in milliseconds"}, + }; + for (unsigned int i = 0; i < G_N_ELEMENTS(named); i++) { + name_widget(named[i].id, named[i].name); + GtkWidget *control = prefs_widget(named[i].id); + if (GTK_IS_COMBO_BOX(control) && + gtk_combo_box_get_active(GTK_COMBO_BOX(control)) < 0) { + gtk_combo_box_set_active(GTK_COMBO_BOX(control), 0); + } + if (GTK_IS_COMBO_BOX_TEXT(control)) { + g_signal_connect_data(control, "changed", G_CALLBACK(combo_changed), + g_strdup(named[i].name), free_signal_data, 0); + } + } + const char *keyboard_focus[] = { + "generalDesktopButton", "generalLaptopButton", + }; + set_focus_chain("keyboard_layout_controls", keyboard_focus, + G_N_ELEMENTS(keyboard_focus)); + const char *echo_toggles[] = {"keyEchoDisabledRadio", "keyEchoEnabledRadio", "keyEchoEditFieldsRadio", "useCustomEchoVoiceCheckButton", "enableEchoByCharacterCheckButton", "enableEchoByWordCheckButton", "enableEchoBySentenceCheckButton"}; + for (unsigned i = 0; i < G_N_ELEMENTS(echo_toggles); i++) g_signal_connect(prefs_widget(echo_toggles[i]), "toggled", G_CALLBACK(echo_sensitivity), NULL); + echo_sensitivity(NULL, NULL); + g_signal_connect(prefs_widget("enableSoundCheckButton"), "toggled", G_CALLBACK(sound_sensitivity), NULL); + sound_sensitivity(NULL, NULL); + g_signal_connect(prefs_widget("ocrBlackWhiteCheckButton"), "toggled", G_CALLBACK(ocr_sensitivity), NULL); + g_signal_connect(prefs_widget("ocrAutoRefreshCheckButton"), "toggled", G_CALLBACK(ocr_sensitivity), NULL); + ocr_sensitivity(NULL, NULL); + gtk_widget_show_all(prefs_widget("window")); + for (unsigned int i = 0; i < G_N_ELEMENTS(named); i++) { + GtkWidget *control = prefs_widget(named[i].id); + if (GTK_IS_COMBO_BOX_TEXT(control)) { + combo_changed(GTK_COMBO_BOX(control), (gpointer)named[i].name); + } + } + gtk_widget_grab_focus(prefs_widget("notebook")); + return 1; +} +void prefs_set_application(const char *name) { + if (!name || !name[0]) return; + // Hiding a notebook child leaves its tab in the AT-SPI tree. Remove the + // page entirely so application preferences expose no global controls. + GtkNotebook *notebook = GTK_NOTEBOOK(prefs_widget("notebook")); + gtk_notebook_remove_page(notebook, gtk_notebook_page_num(notebook, prefs_widget("tentacles_page"))); + gchar *title = g_strdup_printf("Cthulhu Preferences for %s", name); + gtk_window_set_title(GTK_WINDOW(prefs_widget("window")), title); + g_free(title); +} +void prefs_iterate(void) { for (int i = 0; i < 64 && g_main_context_pending(NULL); i++) g_main_context_iteration(NULL, FALSE); } +int prefs_action(void) { int result = action; action = 0; return result; } +int prefs_voice_changed(void) { int result = voice_changed; voice_changed = 0; return result; } +int prefs_echo_preview(int *focused) { + int result = echoPreview; + echoPreview = 0; + if (focused) *focused = echoPreviewFocus; + if (result && (!echo_control_focused(prefs_widget(echoControls[result - 1])) || + !prefs_check_get("useCustomEchoVoiceCheckButton"))) return 0; + return result; +} +void prefs_busy(int busy, int can_save) { + gtk_widget_set_sensitive(prefs_widget("notebook"), !busy); + gtk_widget_set_sensitive(prefs_widget("apply"), !busy); + gtk_widget_set_sensitive(prefs_widget("save"), !busy && can_save); + if (!busy && busy_focus) { + if (gtk_widget_get_sensitive(busy_focus)) gtk_widget_grab_focus(busy_focus); + busy_focus = NULL; + } +} +void prefs_present(void) { gtk_window_present(GTK_WINDOW(prefs_widget("window"))); } +void prefs_close(void) { prefs_extensions_close(); busy_focus = NULL; gtk_widget_destroy(prefs_widget("window")); g_object_unref(builder); builder = NULL; } +void prefs_status(const char *message, int focus) { + gtk_entry_set_text(GTK_ENTRY(prefs_widget("status")), message); + atk_object_set_name(gtk_widget_get_accessible(prefs_widget("status")), message); + if (focus) gtk_widget_grab_focus(prefs_widget("status")); +} diff --git a/internal/preferences/native.h b/internal/preferences/native.h new file mode 100644 index 0000000..574508e --- /dev/null +++ b/internal/preferences/native.h @@ -0,0 +1,83 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include +int prefs_init(const char *xml); +void prefs_set_application(const char *name); +void prefs_iterate(void); +int prefs_action(void); +int prefs_voice_changed(void); +int prefs_echo_preview(int *focused); +void prefs_busy(int busy, int can_save); +void prefs_present(void); +void prefs_close(void); +void prefs_status(const char *message, int focus); +void prefs_number_set(const char *id, double value); +double prefs_number_value(const char *id); +int prefs_number_edited(const char *id); +void prefs_choice_set(const char *id, int value); +int prefs_choice_get(const char *id); +void prefs_hardware_devices_clear(void); +void prefs_hardware_device_append(const char *text); +void prefs_hardware_device_set(const char *text); +const char *prefs_hardware_device_get(void); +void prefs_hardware_sensitivity(int enabled); +void prefs_combo_set(const char *id, int value); +int prefs_combo_get(const char *id); + +void prefs_check_set(const char *id, int value); +int prefs_check_get(const char *id); +void prefs_reading_set(const char *id, int value); +int prefs_reading_get(const char *id); +void prefs_range_set(const char *id, double value); +void prefs_spin_set(const char *id, double value); +double prefs_spin_get(const char *id); +void prefs_combo_clear(const char *id); +void prefs_combo_append(const char *id, const char *text); +void prefs_entry_set(const char *id, const char *text); +const char *prefs_entry_get(const char *id); + +void prefs_bindings_clear(void); +void prefs_binding_append(const char *label, const char *scope, const char *keys, const char *defaults); +int prefs_binding_selected(void); +void prefs_binding_select(int row); + +void prefs_modifier_set(const char *id, int enabled); +void prefs_interruption_clear(void); +void prefs_interruption_append(const char *name); +int prefs_interruption_count(void); +const char *prefs_interruption_key(int index); +int prefs_modifier_get(const char *id); +void prefs_init_pronunciation(void); +void prefs_pronunciation_clear(void); +void prefs_pronunciation_append(const char *word, const char *replacement); +int prefs_pronunciation_count(void); +char *prefs_pronunciation_value(int row, int column); +void prefs_init_text_attributes(void); +void prefs_text_attributes_clear(void); +void prefs_text_attribute_append(const char *key, const char *label, int speak, int braille); +int prefs_text_attribute_count(void); +char *prefs_text_attribute_key(int row); +int prefs_text_attribute_enabled(int row, int column); + +void prefs_tentacles_clear(void); +void prefs_tentacle_append(int enabled, const char *name, const char *state, const char *version, const char *repository, const char *message, const char *shortcuts); +int prefs_tentacle_selected(void); +void prefs_tentacle_select(int row); +void prefs_tentacle_controls(int available, int installed, int enabled, int repository); +int prefs_tentacle_confirm(const char *message, const char *label); +void prefs_tentacle_repositories_clear(void); +void prefs_tentacle_repository_append(const char *label); +int prefs_tentacle_repository_selected(void); +void prefs_tentacle_repository_select(int page); + +void prefs_extension_add(const char *key, const char *title); +void prefs_extension_remove(const char *key); +void prefs_extensions_close(void); +const char *prefs_extension_selected(void); +void prefs_extension_select(const char *key); +void prefs_extension_control(const char *page, const char *id, const char *label, int kind, int row, int max_length, int disabled); +void prefs_extension_option(const char *page, const char *id, const char *option, const char *label, int disabled); +void prefs_extension_set(const char *page, const char *id, int kind, const char *text, int checked); +const char *prefs_extension_text(const char *page, const char *id, int kind); +int prefs_extension_checked(const char *page, const char *id); diff --git a/internal/preferences/native_applications.c b/internal/preferences/native_applications.c new file mode 100644 index 0000000..6d0c4b2 --- /dev/null +++ b/internal/preferences/native_applications.c @@ -0,0 +1,136 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native_applications.h" +#include + +// Used only in the isolated preferences helper. The reader's AT-SPI loop +// and timeout remain untouched. +AccessibleApplication *prefs_application_names(int *count) { + *count = 0; + if (atspi_init() != 0) return NULL; + atspi_set_timeout(250, 250); + AtspiAccessible *desktop = atspi_get_desktop(0); + if (!desktop) { atspi_exit(); return NULL; } + GError *error = NULL; + int children = MIN(atspi_accessible_get_child_count(desktop, &error), 4096); + g_clear_error(&error); + AccessibleApplication *names = g_new0(AccessibleApplication, MAX(children, 1)); + for (int i = 0; i < children; i++) { + AtspiAccessible *application = atspi_accessible_get_child_at_index(desktop, i, &error); + g_clear_error(&error); + if (!application) continue; + char *name = atspi_accessible_get_name(application, &error); + g_clear_error(&error); + unsigned int pid = atspi_accessible_get_process_id(application, &error); + g_clear_error(&error); + if ((name && *name) || pid) names[(*count)++] = (AccessibleApplication){name, pid}; + else g_free(name); + g_object_unref(application); + } + g_object_unref(desktop); + atspi_exit(); + return names; +} + +void prefs_free_application_names(AccessibleApplication *names, int count) { + for (int i = 0; i < count; i++) g_free(names[i].name); + g_free(names); +} + +static GtkWidget *chooser, *applicationTree; +static GtkListStore *applicationStore; +static int chooserAction; + +static void chooser_response(GtkDialog *dialog, gint response, gpointer data) { + (void)dialog; (void)data; + chooserAction = response == GTK_RESPONSE_OK ? 1 : 2; +} + +static void chooser_activate(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer data) { + (void)view; (void)path; (void)column; (void)data; + chooserAction = 1; +} + +static gboolean chooser_delete(GtkWidget *widget, GdkEvent *event, gpointer data) { + (void)widget; (void)event; (void)data; + chooserAction = 2; + return TRUE; +} + +static gboolean chooser_key(GtkWidget *widget, GdkEventKey *event, gpointer data) { + (void)widget; (void)data; + if (event->keyval != GDK_KEY_Escape) return FALSE; + chooserAction = 2; + return TRUE; +} + +int prefs_application_chooser_init(void) { + if (!gtk_init_check(NULL, NULL)) return 0; + chooserAction = 0; + chooser = gtk_dialog_new_with_buttons("Choose Application Preferences", NULL, 0, + "_Cancel", GTK_RESPONSE_CANCEL, "_Open Preferences", GTK_RESPONSE_OK, NULL); + gtk_window_set_default_size(GTK_WINDOW(chooser), 480, 420); + gtk_dialog_set_default_response(GTK_DIALOG(chooser), GTK_RESPONSE_OK); + GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(chooser)); + GtkWidget *label = gtk_label_new_with_mnemonic("Choose an _application:"); + gtk_box_pack_start(GTK_BOX(content), label, FALSE, FALSE, 6); + GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_set_vexpand(scroll, TRUE); + gtk_box_pack_start(GTK_BOX(content), scroll, TRUE, TRUE, 6); + applicationStore = gtk_list_store_new(1, G_TYPE_STRING); + applicationTree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(applicationStore)); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(applicationTree), -1, + "Application", gtk_cell_renderer_text_new(), "text", 0, NULL); + gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(applicationTree)), GTK_SELECTION_SINGLE); + gtk_label_set_mnemonic_widget(GTK_LABEL(label), applicationTree); + atk_object_set_name(gtk_widget_get_accessible(applicationTree), "Applications"); + atk_object_set_description(gtk_widget_get_accessible(applicationTree), + "Use arrow keys to choose a running application. Enter opens its preferences. Escape cancels. Tab leaves the list."); + gtk_container_add(GTK_CONTAINER(scroll), applicationTree); + g_signal_connect(chooser, "response", G_CALLBACK(chooser_response), NULL); + g_signal_connect(chooser, "delete-event", G_CALLBACK(chooser_delete), NULL); + g_signal_connect(chooser, "key-press-event", G_CALLBACK(chooser_key), NULL); + g_signal_connect(applicationTree, "row-activated", G_CALLBACK(chooser_activate), NULL); + return 1; +} + +void prefs_application_chooser_add(const char *name) { + GtkTreeIter iter; + gtk_list_store_append(applicationStore, &iter); + gtk_list_store_set(applicationStore, &iter, 0, name, -1); +} + +void prefs_application_chooser_present(void) { + gtk_widget_show_all(chooser); + gtk_window_present(GTK_WINDOW(chooser)); + GtkTreePath *path = NULL; + gtk_tree_view_get_cursor(GTK_TREE_VIEW(applicationTree), &path, NULL); + if (!path && gtk_tree_model_iter_n_children(GTK_TREE_MODEL(applicationStore), NULL)) { + path = gtk_tree_path_new_first(); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(applicationTree), path, NULL, FALSE); + } + if (path) gtk_tree_path_free(path); + gtk_widget_grab_focus(applicationTree); +} + +void prefs_application_chooser_iterate(void) { + while (gtk_events_pending()) gtk_main_iteration_do(FALSE); +} +int prefs_application_chooser_action(void) { return chooserAction; } +char *prefs_application_chooser_selected(void) { + GtkTreeIter iter; + if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(applicationTree)), NULL, &iter)) { + chooserAction = 0; + return NULL; + } + char *name = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(applicationStore), &iter, 0, &name, -1); + return name; +} +void prefs_application_chooser_close(void) { + gtk_widget_destroy(chooser); + g_object_unref(applicationStore); + chooser = applicationTree = NULL; + applicationStore = NULL; +} diff --git a/internal/preferences/native_applications.h b/internal/preferences/native_applications.h new file mode 100644 index 0000000..72b195a --- /dev/null +++ b/internal/preferences/native_applications.h @@ -0,0 +1,14 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include +typedef struct { char *name; unsigned int pid; } AccessibleApplication; +AccessibleApplication *prefs_application_names(int *count); +void prefs_free_application_names(AccessibleApplication *names, int count); +int prefs_application_chooser_init(void); +void prefs_application_chooser_add(const char *name); +void prefs_application_chooser_present(void); +void prefs_application_chooser_iterate(void); +int prefs_application_chooser_action(void); +char *prefs_application_chooser_selected(void); +void prefs_application_chooser_close(void); diff --git a/internal/preferences/native_bindings.c b/internal/preferences/native_bindings.c new file mode 100644 index 0000000..488a362 --- /dev/null +++ b/internal/preferences/native_bindings.c @@ -0,0 +1,155 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native_internal.h" + +static GtkListStore *binding_store; +static void binding_selected(GtkTreeSelection *selection, gpointer data) { + (void)data; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean selected = gtk_tree_selection_get_selected(selection, &model, &iter); + const char *controls[] = {"keyBindingEntry", "keyBindingSet", "keyBindingClear", "keyBindingReset"}; + for (unsigned i = 0; i < G_N_ELEMENTS(controls); i++) gtk_widget_set_sensitive(prefs_widget(controls[i]), selected); + gchar *keys = NULL; + if (selected) gtk_tree_model_get(model, &iter, 2, &keys, -1); + gtk_entry_set_text(GTK_ENTRY(prefs_widget("keyBindingEntry")), keys && strcmp(keys, "Unbound") != 0 ? keys : ""); + g_free(keys); +} +static void binding_clicked(GtkButton *button, gpointer data) { (void)button; prefs_set_action(GPOINTER_TO_INT(data)); } +void prefs_init_key_bindings(void) { + binding_store = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + GtkTreeView *tree = GTK_TREE_VIEW(prefs_widget("keyBindingsTreeview")); + gtk_tree_view_set_model(tree, GTK_TREE_MODEL(binding_store)); + const char *titles[] = {"Command", "Scope", "Binding", "Default binding"}; + for (int i = 0; i < 4; i++) { + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_append_column(tree, gtk_tree_view_column_new_with_attributes(titles[i], renderer, "text", i, NULL)); + } + gtk_tree_selection_set_mode(gtk_tree_view_get_selection(tree), GTK_SELECTION_SINGLE); + g_signal_connect(gtk_tree_view_get_selection(tree), "changed", G_CALLBACK(binding_selected), NULL); + const char *buttons[] = {"keyBindingSet", "keyBindingClear", "keyBindingReset", "keyBindingResetAll"}; + for (int i = 0; i < 4; i++) g_signal_connect(prefs_widget(buttons[i]), "clicked", G_CALLBACK(binding_clicked), GINT_TO_POINTER(i + 4)); + atk_object_set_name(gtk_widget_get_accessible(GTK_WIDGET(tree)), "Key bindings"); + binding_selected(gtk_tree_view_get_selection(tree), NULL); + g_object_unref(binding_store); // The tree owns the model. +} +void prefs_bindings_clear(void) { gtk_list_store_clear(binding_store); } +void prefs_binding_append(const char *label, const char *scope, const char *keys, const char *defaults) { + GtkTreeIter iter; + gtk_list_store_append(binding_store, &iter); + gtk_list_store_set(binding_store, &iter, 0, label, 1, scope, 2, keys, 3, defaults, -1); +} +int prefs_binding_selected(void) { + GtkTreeModel *model; + GtkTreeIter iter; + if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(prefs_widget("keyBindingsTreeview"))), &model, &iter)) return -1; + GtkTreePath *path = gtk_tree_model_get_path(model, &iter); + int row = gtk_tree_path_get_indices(path)[0]; + gtk_tree_path_free(path); + return row; +} +void prefs_binding_select(int row) { + if (row < 0) return; + GtkTreePath *path = gtk_tree_path_new_from_indices(row, -1); + // Setting the cursor grabs focus and can switch the notebook to this page + // while loading preferences or changing the layout combo. Select the row + // without moving keyboard focus out of the current control. + GtkTreeView *tree = GTK_TREE_VIEW(prefs_widget("keyBindingsTreeview")); + gtk_tree_selection_select_path(gtk_tree_view_get_selection(tree), path); + gtk_tree_view_scroll_to_cell(tree, path, NULL, FALSE, 0, 0); + gtk_tree_path_free(path); +} +static GtkListStore *modifierStore; +static const struct { const char *id; const char *label; } modifierRows[] = { + {"Insert", "Insert"}, {"KP_Insert", "Numpad Insert"}, {"Caps_Lock", "Caps Lock"}, +}; +static void name_modifier_cells(void) { + AtkObject *accessible = gtk_widget_get_accessible(prefs_widget("cthulhuModifiersTreeview")); + if (!ATK_IS_TABLE(accessible)) return; + for (unsigned i = 0; i < G_N_ELEMENTS(modifierRows); i++) { + AtkObject *cell = atk_table_ref_at(ATK_TABLE(accessible), i, 0); + if (!cell) continue; + gboolean enabled = prefs_modifier_get(modifierRows[i].id); + const char *name = enabled ? "checked" : "unchecked"; + if (g_strcmp0(atk_object_get_name(cell), name) != 0) atk_object_set_name(cell, name); + g_object_unref(cell); + } +} +void prefs_modifier_set(const char *id, int enabled) { + for (unsigned i = 0; i < G_N_ELEMENTS(modifierRows); i++) { + if (strcmp(id, modifierRows[i].id) != 0) continue; + if (prefs_modifier_get(id) == (enabled != 0)) return; + GtkTreeIter iter; + if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(modifierStore), &iter, NULL, i)) + gtk_list_store_set(modifierStore, &iter, 1, enabled != 0, -1); + name_modifier_cells(); + return; + } +} +int prefs_modifier_get(const char *id) { + for (unsigned i = 0; i < G_N_ELEMENTS(modifierRows); i++) { + if (strcmp(id, modifierRows[i].id) != 0) continue; + GtkTreeIter iter; + gboolean enabled = FALSE; + if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(modifierStore), &iter, NULL, i)) + gtk_tree_model_get(GTK_TREE_MODEL(modifierStore), &iter, 1, &enabled, -1); + return enabled; + } + return FALSE; +} +static void toggle_modifier_path(const char *pathString) { + GtkTreeIter iter; + if (!gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(modifierStore), &iter, pathString)) return; + gboolean enabled; + gtk_tree_model_get(GTK_TREE_MODEL(modifierStore), &iter, 1, &enabled, -1); + gtk_list_store_set(modifierStore, &iter, 1, !enabled, -1); + name_modifier_cells(); +} +static void modifier_toggled(GtkCellRendererToggle *renderer, gchar *pathString, gpointer data) { + (void)renderer; (void)data; + toggle_modifier_path(pathString); +} +static gboolean modifier_key_press(GtkWidget *view, GdkEventKey *event, gpointer data) { + (void)data; + if (event->keyval != GDK_KEY_space && event->keyval != GDK_KEY_KP_Space) return FALSE; + GtkTreePath *path = NULL; + gtk_tree_view_get_cursor(GTK_TREE_VIEW(view), &path, NULL); + if (!path) return FALSE; + gchar *pathString = gtk_tree_path_to_string(path); + toggle_modifier_path(pathString); + g_free(pathString); + gtk_tree_path_free(path); + return TRUE; +} +static void layout_modifiers(GtkToggleButton *button, gpointer data) { + if (!gtk_toggle_button_get_active(button)) return; + int laptop = GPOINTER_TO_INT(data); + prefs_modifier_set("Insert", FALSE); + prefs_modifier_set("KP_Insert", !laptop); + prefs_modifier_set("Caps_Lock", laptop); +} +void prefs_init_modifiers(void) { + modifierStore = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN); + for (unsigned i = 0; i < G_N_ELEMENTS(modifierRows); i++) { + GtkTreeIter iter; + gtk_list_store_append(modifierStore, &iter); + gtk_list_store_set(modifierStore, &iter, 0, modifierRows[i].label, 1, FALSE, -1); + } + GtkTreeView *view = GTK_TREE_VIEW(prefs_widget("cthulhuModifiersTreeview")); + gtk_tree_view_set_model(view, GTK_TREE_MODEL(modifierStore)); + GtkCellRenderer *textRenderer = gtk_cell_renderer_text_new(); + GtkCellRenderer *toggleRenderer = gtk_cell_renderer_toggle_new(); + g_signal_connect(toggleRenderer, "toggled", G_CALLBACK(modifier_toggled), NULL); + gtk_tree_view_append_column(view, gtk_tree_view_column_new_with_attributes("Enabled", toggleRenderer, "active", 1, NULL)); + gtk_tree_view_append_column(view, gtk_tree_view_column_new_with_attributes("Cthulhu key", textRenderer, "text", 0, NULL)); + g_signal_connect(view, "key-press-event", G_CALLBACK(modifier_key_press), NULL); + AtkObject *accessible = gtk_widget_get_accessible(GTK_WIDGET(view)); + atk_object_set_name(accessible, "Cthulhu modifier keys"); + atk_object_set_description(accessible, "Use arrow keys to select Insert, Numpad Insert, or Caps Lock. Space toggles each key independently. Tab leaves the table."); + g_signal_connect(prefs_widget("generalDesktopButton"), "toggled", G_CALLBACK(layout_modifiers), GINT_TO_POINTER(0)); + g_signal_connect(prefs_widget("generalLaptopButton"), "toggled", G_CALLBACK(layout_modifiers), GINT_TO_POINTER(1)); + name_modifier_cells(); + g_object_unref(modifierStore); // The tree owns the model. +} + diff --git a/internal/preferences/native_extensions.c b/internal/preferences/native_extensions.c new file mode 100644 index 0000000..6503432 --- /dev/null +++ b/internal/preferences/native_extensions.c @@ -0,0 +1,138 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native_internal.h" + +static GHashTable *extensionPages; +static GHashTable *extensionControls; + +static void extension_combo_changed(GtkComboBox *combo, gpointer data) { + (void)data; + prefs_describe_combo(GTK_WIDGET(combo), g_object_get_data(G_OBJECT(combo), "extension-label")); +} + +static char *control_key(const char *page, const char *id) { + return g_strconcat(page, "/", id, NULL); +} +static GtkWidget *extension_control(const char *page, const char *id) { + char *key = control_key(page, id); + GtkWidget *widget = extensionControls ? g_hash_table_lookup(extensionControls, key) : NULL; + g_free(key); + return widget; +} +void prefs_extension_add(const char *key, const char *title) { + if (!extensionPages) { + extensionPages = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + extensionControls = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + } + GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + GtkWidget *grid = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(grid), 8); + gtk_grid_set_column_spacing(GTK_GRID(grid), 12); + gtk_container_set_border_width(GTK_CONTAINER(grid), 12); + gtk_container_add(GTK_CONTAINER(scroll), grid); + g_object_set_data(G_OBJECT(scroll), "extension-grid", grid); + gtk_notebook_append_page(GTK_NOTEBOOK(prefs_widget("notebook")), scroll, gtk_label_new(title)); + g_hash_table_insert(extensionPages, g_strdup(key), scroll); + gtk_widget_show_all(scroll); +} +void prefs_extension_remove(const char *key) { + if (!extensionPages) return; + GtkWidget *page = g_hash_table_lookup(extensionPages, key); + if (!page) return; + GtkNotebook *notebook = GTK_NOTEBOOK(prefs_widget("notebook")); + int pageIndex = gtk_notebook_page_num(notebook, page); + GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(prefs_widget("window"))); + if (gtk_notebook_get_current_page(notebook) == pageIndex) { + // Switch while the old page is still realized. GTK must not attempt to + // restore a focus child from a page whose controls are being destroyed. + gtk_notebook_set_current_page(notebook, 0); + gtk_widget_grab_focus(GTK_WIDGET(notebook)); + } else if (focus && gtk_widget_is_ancestor(focus, page)) { + gtk_widget_grab_focus(GTK_WIDGET(notebook)); + } + GHashTableIter iterator; + gpointer controlKey, widget; + char *prefix = g_strconcat(key, "/", NULL); + g_hash_table_iter_init(&iterator, extensionControls); + while (g_hash_table_iter_next(&iterator, &controlKey, &widget)) { + if (g_str_has_prefix(controlKey, prefix)) g_hash_table_iter_remove(&iterator); + } + g_free(prefix); + gtk_notebook_remove_page(notebook, pageIndex); + g_hash_table_remove(extensionPages, key); +} +void prefs_extensions_close(void) { + g_clear_pointer(&extensionControls, g_hash_table_destroy); + g_clear_pointer(&extensionPages, g_hash_table_destroy); +} +const char *prefs_extension_selected(void) { + if (!extensionPages) return ""; + GtkNotebook *notebook = GTK_NOTEBOOK(prefs_widget("notebook")); + GtkWidget *current = gtk_notebook_get_nth_page(notebook, gtk_notebook_get_current_page(notebook)); + GHashTableIter iterator; + gpointer key, page; + g_hash_table_iter_init(&iterator, extensionPages); + while (g_hash_table_iter_next(&iterator, &key, &page)) { + if (page == current) return key; + } + return ""; +} +void prefs_extension_select(const char *key) { + if (!extensionPages) return; + GtkWidget *page = g_hash_table_lookup(extensionPages, key); + if (page) { + GtkNotebook *notebook = GTK_NOTEBOOK(prefs_widget("notebook")); + gtk_notebook_set_current_page(notebook, gtk_notebook_page_num(notebook, page)); + } +} +void prefs_extension_control(const char *pageKey, const char *id, const char *label, int kind, int row, int maxLength, int disabled) { + GtkWidget *page = g_hash_table_lookup(extensionPages, pageKey); + GtkWidget *grid = g_object_get_data(G_OBJECT(page), "extension-grid"); + GtkWidget *control; + if (kind == 1) { + control = gtk_combo_box_text_new(); + // Focus the internal combo button so Tab and Shift+Tab leave it normally. + gtk_widget_set_can_focus(control, FALSE); + g_object_set_data_full(G_OBJECT(control), "extension-label", g_strdup(label), g_free); + g_signal_connect(control, "changed", G_CALLBACK(extension_combo_changed), NULL); + } else if (kind == 2) { + control = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(control), maxLength ? maxLength : 8192); + } else { + control = gtk_check_button_new_with_label(label); + } + atk_object_set_name(gtk_widget_get_accessible(control), label); + gtk_widget_set_hexpand(control, TRUE); + gtk_widget_set_sensitive(control, !disabled); + if (kind != 3) { + GtkWidget *name = gtk_label_new(label); + gtk_label_set_xalign(GTK_LABEL(name), 0); + gtk_label_set_mnemonic_widget(GTK_LABEL(name), control); + gtk_grid_attach(GTK_GRID(grid), name, 0, row, 1, 1); + gtk_grid_attach(GTK_GRID(grid), control, 1, row, 1, 1); + } else { + gtk_grid_attach(GTK_GRID(grid), control, 0, row, 2, 1); + } + g_hash_table_insert(extensionControls, control_key(pageKey, id), control); + gtk_widget_show_all(grid); +} +void prefs_extension_option(const char *page, const char *id, const char *option, const char *label, int disabled) { + // Disabled choices are omitted from native selection, preserving their IDs + // in the host schema so an old/malicious draft is still rejected there. + if (!disabled) gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(extension_control(page, id)), option, label); +} +void prefs_extension_set(const char *page, const char *id, int kind, const char *text, int checked) { + GtkWidget *widget = extension_control(page, id); + if (kind == 1) gtk_combo_box_set_active_id(GTK_COMBO_BOX(widget), text); + else if (kind == 2) gtk_entry_set_text(GTK_ENTRY(widget), text); + else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), checked); +} +const char *prefs_extension_text(const char *page, const char *id, int kind) { + GtkWidget *widget = extension_control(page, id); + const char *value = kind == 1 ? gtk_combo_box_get_active_id(GTK_COMBO_BOX(widget)) : gtk_entry_get_text(GTK_ENTRY(widget)); + return value ? value : ""; +} +int prefs_extension_checked(const char *page, const char *id) { + return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(extension_control(page, id))); +} diff --git a/internal/preferences/native_internal.h b/internal/preferences/native_internal.h new file mode 100644 index 0000000..242d791 --- /dev/null +++ b/internal/preferences/native_internal.h @@ -0,0 +1,20 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#ifndef CTHULHU_PREFERENCES_NATIVE_INTERNAL_H +#define CTHULHU_PREFERENCES_NATIVE_INTERNAL_H +#include "native.h" + +// Private C boundary. The window owner retains the builder and action slot; +// widget models and signal callbacks stay with their respective tables. +GtkWidget *prefs_widget(const char *id); +void prefs_describe_combo(GtkWidget *control, const char *label); +void prefs_set_action(int value); +void prefs_init_key_bindings(void); +void prefs_init_modifiers(void); +void prefs_init_interruption(void); +void prefs_init_reading_settings(void); +void prefs_init_pronunciation(void); +void prefs_init_text_attributes(void); +void prefs_init_tentacles(void); +#endif diff --git a/internal/preferences/native_interruption.c b/internal/preferences/native_interruption.c new file mode 100644 index 0000000..06afc29 --- /dev/null +++ b/internal/preferences/native_interruption.c @@ -0,0 +1,188 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native_internal.h" +#include +#include + +// The preferences window owns the accepted draft. Each recorder owns a fresh +// candidate and held modifier set; cancelling or destroying it discards both. +typedef struct { + GtkWidget *dialog; + GtkWidget *entry; + GPtrArray *keys; + GHashTable *modifiers; +} KeyRecorder; + +static GPtrArray *interruption_keys(void) { + return g_object_get_data(G_OBJECT(prefs_widget("window")), "interruption-keys"); +} + +static char *key_label(const char *name) { + const struct { const char *name; const char *label; } labels[] = { + {"Control_L", "Left Control"}, {"Control_R", "Right Control"}, + {"Shift_L", "Left Shift"}, {"Shift_R", "Right Shift"}, + {"Alt_L", "Left Alt"}, {"Alt_R", "Right Alt"}, + {"Super_L", "Left Super"}, {"Super_R", "Right Super"}, + {"Return", "Enter"}, {"KP_Enter", "Numpad Enter"}, {"space", "Space"}, + }; + for (unsigned i = 0; i < G_N_ELEMENTS(labels); i++) + if (strcmp(name, labels[i].name) == 0) return g_strdup(labels[i].label); + guint keyval = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS); + return keyval == XKB_KEY_NoSymbol ? g_strdup(name) : gtk_accelerator_get_label(keyval, 0); +} + +static void show_keys(GtkWidget *entry, GPtrArray *keys) { + GString *text = g_string_new(NULL); + for (unsigned i = 0; i < keys->len; i++) { + char *label = key_label(g_ptr_array_index(keys, i)); + if (i) g_string_append(text, ", "); + g_string_append(text, label); + g_free(label); + } + gtk_entry_set_text(GTK_ENTRY(entry), text->len ? text->str : "No keys defined"); + g_string_free(text, TRUE); +} + +void prefs_interruption_clear(void) { + g_ptr_array_set_size(interruption_keys(), 0); + show_keys(prefs_widget("interruptionKeysEntry"), interruption_keys()); +} + +void prefs_interruption_append(const char *name) { + g_ptr_array_add(interruption_keys(), g_strdup(name)); + show_keys(prefs_widget("interruptionKeysEntry"), interruption_keys()); +} + +int prefs_interruption_count(void) { return interruption_keys()->len; } +const char *prefs_interruption_key(int index) { return g_ptr_array_index(interruption_keys(), index); } + +static void interruption_sensitivity(GtkToggleButton *button, gpointer data) { + (void)button; (void)data; + gboolean custom = prefs_check_get("interruptCustomKeysRadio"); + gtk_widget_set_sensitive(prefs_widget("recordInterruptionKeysButton"), custom); + gtk_widget_set_sensitive(prefs_widget("interruptionKeysEntry"), custom); +} + +static void record_key(KeyRecorder *recorder, guint keyval) { + // GTK and X11 use different aliases for Page Up and multimedia keys. + // Persist XKB names, matching both input observers rather than GTK names. + char name[128]; + int length = xkb_keysym_get_name(gdk_keyval_to_lower(keyval), name, sizeof(name)); + if (length <= 0 || (unsigned)length >= sizeof(name)) return; + for (unsigned i = 0; i < recorder->keys->len; i++) + if (strcmp(name, g_ptr_array_index(recorder->keys, i)) == 0) return; + if (recorder->keys->len == 64) return; + g_ptr_array_add(recorder->keys, g_strdup(name)); + show_keys(recorder->entry, recorder->keys); + gtk_dialog_set_response_sensitive(GTK_DIALOG(recorder->dialog), GTK_RESPONSE_OK, TRUE); +} + +static guint recording_keyval(GdkEventKey *event) { + if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) return event->keyval; + // Match the base names published by the X11 observer, including keypad + // keys with Num Lock enabled. This records individual keys, not chords. + GdkKeymapKey key = {event->hardware_keycode, 0, 0}; + guint keyval = gdk_keymap_lookup_key(gdk_keymap_get_for_display(gdk_display_get_default()), &key); + return keyval ? keyval : event->keyval; +} + +static gboolean recording_key(GtkWidget *dialog, GdkEventKey *event, gpointer data) { + KeyRecorder *recorder = data; + guint state = event->state & gtk_accelerator_get_default_mod_mask(); + gboolean finish = state == GDK_CONTROL_MASK && + (event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter); + gboolean cancel = state == GDK_CONTROL_MASK && event->keyval == GDK_KEY_Escape; + if (event->type == GDK_KEY_PRESS && (finish || cancel)) { + g_hash_table_remove_all(recorder->modifiers); + if (cancel || recorder->keys->len) + gtk_dialog_response(GTK_DIALOG(dialog), cancel ? GTK_RESPONSE_CANCEL : GTK_RESPONSE_OK); + else + gtk_entry_set_text(GTK_ENTRY(recorder->entry), "Record at least one key, then press Control+Enter."); + return TRUE; + } + guint keyval = recording_keyval(event); + if (event->is_modifier) { + // Record modifiers on release so the Control used to finish or cancel + // never becomes an interruption key just because it ended recording. + if (event->type == GDK_KEY_PRESS) + g_hash_table_add(recorder->modifiers, GUINT_TO_POINTER(keyval)); + else if (g_hash_table_remove(recorder->modifiers, GUINT_TO_POINTER(keyval))) + record_key(recorder, keyval); + } else if (event->type == GDK_KEY_PRESS) { + record_key(recorder, keyval); + } + // Consume Tab, Enter, Escape and Space before GTK focus/default actions. + return TRUE; +} + +static gboolean recording_focus_out(GtkWidget *dialog, GdkEventFocus *event, gpointer data) { + (void)dialog; (void)event; + KeyRecorder *recorder = data; + g_hash_table_remove_all(recorder->modifiers); + return FALSE; +} + +static void free_recorder(gpointer data) { + KeyRecorder *recorder = data; + g_ptr_array_unref(recorder->keys); + g_hash_table_unref(recorder->modifiers); + g_free(recorder); +} + +static void recording_response(GtkDialog *dialog, int response, gpointer data) { + KeyRecorder *recorder = data; + if (response == GTK_RESPONSE_OK && recorder->keys->len) { + prefs_interruption_clear(); + for (unsigned i = 0; i < recorder->keys->len; i++) + prefs_interruption_append(g_ptr_array_index(recorder->keys, i)); + } + gtk_widget_destroy(GTK_WIDGET(dialog)); + gtk_window_present(GTK_WINDOW(prefs_widget("window"))); + gtk_widget_grab_focus(prefs_widget("recordInterruptionKeysButton")); +} + +static void start_recording(GtkButton *button, gpointer data) { + (void)button; (void)data; + const char *instructions = "Press each key that should interrupt speech. " + "Tab, Enter, Space, and Escape can be recorded. " + "Press and release a modifier by itself to record it. " + "Control+Enter finishes; Control+Escape cancels. " + "Recording replaces the previous keys. Up to 64 keys can be recorded."; + KeyRecorder *recorder = g_new0(KeyRecorder, 1); + recorder->keys = g_ptr_array_new_with_free_func(g_free); + recorder->modifiers = g_hash_table_new(g_direct_hash, g_direct_equal); + recorder->dialog = gtk_dialog_new_with_buttons("Record interruption keys", + GTK_WINDOW(prefs_widget("window")), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + "Cancel recording", GTK_RESPONSE_CANCEL, "Finish recording", GTK_RESPONSE_OK, NULL); + g_object_set_data_full(G_OBJECT(recorder->dialog), "key-recorder", recorder, free_recorder); + GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(recorder->dialog)); + gtk_container_set_border_width(GTK_CONTAINER(content), 12); + GtkWidget *label = gtk_label_new(instructions); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_label_set_max_width_chars(GTK_LABEL(label), 65); + gtk_box_pack_start(GTK_BOX(content), label, FALSE, FALSE, 8); + recorder->entry = gtk_entry_new(); + gtk_editable_set_editable(GTK_EDITABLE(recorder->entry), FALSE); + atk_object_set_name(gtk_widget_get_accessible(recorder->entry), instructions); + atk_object_set_description(gtk_widget_get_accessible(recorder->dialog), instructions); + gtk_box_pack_start(GTK_BOX(content), recorder->entry, FALSE, FALSE, 8); + show_keys(recorder->entry, recorder->keys); + gtk_dialog_set_response_sensitive(GTK_DIALOG(recorder->dialog), GTK_RESPONSE_OK, FALSE); + g_signal_connect(recorder->dialog, "key-press-event", G_CALLBACK(recording_key), recorder); + g_signal_connect(recorder->dialog, "key-release-event", G_CALLBACK(recording_key), recorder); + g_signal_connect(recorder->dialog, "focus-out-event", G_CALLBACK(recording_focus_out), recorder); + g_signal_connect(recorder->dialog, "response", G_CALLBACK(recording_response), recorder); + gtk_widget_show_all(recorder->dialog); + gtk_widget_grab_focus(recorder->entry); +} + +void prefs_init_interruption(void) { + g_object_set_data_full(G_OBJECT(prefs_widget("window")), "interruption-keys", + g_ptr_array_new_with_free_func(g_free), (GDestroyNotify)g_ptr_array_unref); + g_signal_connect(prefs_widget("interruptCustomKeysRadio"), "toggled", G_CALLBACK(interruption_sensitivity), NULL); + g_signal_connect(prefs_widget("recordInterruptionKeysButton"), "clicked", G_CALLBACK(start_recording), NULL); + atk_object_set_description(gtk_widget_get_accessible(prefs_widget("recordInterruptionKeysButton")), + "Record individual keys. Control+Enter finishes; Control+Escape cancels."); + atk_object_set_name(gtk_widget_get_accessible(prefs_widget("interruptionKeysEntry")), "Defined interruption keys"); + interruption_sensitivity(NULL, NULL); +} diff --git a/internal/preferences/native_reading.c b/internal/preferences/native_reading.c new file mode 100644 index 0000000..2db8ff2 --- /dev/null +++ b/internal/preferences/native_reading.c @@ -0,0 +1,204 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native_internal.h" + +static GtkListStore *reading_store; +static const struct { const char *id; const char *label; const char *description; } reading_rows[] = { + {"only_speak_displayed_text", "Only speak displayed text", + "Limits reading to displayed names, text and values. Omits extra information such as control types, states and container announcements."}, + {"automatically_read_title_changes", "Automatically read title changes", + "Announces changes to the active window's title, such as a new page title in a browser."}, + {"automatically_read_clipboard_changes", "Automatically read clipboard changes", + "Automatically reads new text when the clipboard contents change, such as after copying text."}, + {"phonetic_character_hints", "Phonetic character hints", + "When navigating characters with Left or Right, adds a phonetic name after a 300 ms pause, for example, a then alpha. Further input cancels the hint."}, + {"enable_pause_breaks", "Break speech into chunks between pauses", + "Separates parts of an announcement with pauses, such as between a control's name, type and state."}, + {"speak_numbers_as_digits", "Speak numbers as digits", + "Reads numbers one digit at a time, for example, 123 as one two three."}, + {"speak_multicase_strings_as_words", "Speak multicase strings as words", + "Separates words where a lowercase letter is followed by an uppercase letter, for example, saveFile as save File."}, + {"enable_indentation", "Enable indentation presentation", + "Reports changes in a line's leading spaces and tabs using the selected indentation presentation mode."}, + {"speak_blank_lines", "Speak blank lines", + "Says blank when navigating to an empty line, instead of leaving it silent."}, + {"enable_mnemonic_speaking", "Speak object mnemonics", + "Announces a control's access key when the application provides one, such as Alt+O for an Open button."}, + {"enable_position_speaking", "Speak child position", + "Announces an item's position within a group when available, for example, 2 of 5."}, + {"enable_tutorial_messages", "Speak tutorial messages", + "Adds brief instructions for using the focused control, such as Press Space to toggle for a checkbox."}, + {"speak_description", "Speak object descriptions", + "Reads additional descriptive text supplied by the application for a control or window."}, + {"messages_are_detailed", "System messages are detailed", + "Reads a notification's full message when available. When disabled, reads just its summary when one is provided."}, + {"use_color_names", "Speak colors as names", + "Uses color names when reporting text colors, instead of their numeric color values."}, + {"speak_misspelled_indicator", "Speak misspelled-word indicator", + "Says misspelled when reading text that the application's spell checker has marked as incorrect."}, + {"speak_context_blockquote", "Announce block quotes during navigation", + "Announces when you enter or leave a block quote in browser browse mode."}, + {"speak_context_list", "Announce lists during navigation", + "Announces when you enter or leave a list in browser browse mode."}, + {"speak_context_table", "Announce tables during navigation", + "Announces when you enter or leave a data table in browser browse mode."}, + {"speak_context_panel", "Announce panels during navigation", + "Announces when you enter or leave a panel or group of controls in browser browse mode."}, + {"speak_context_landmark", "Announce landmarks during navigation", + "Announces when you enter or leave a landmark in browser browse mode, such as a page's main content or navigation region."}, + {"speak_context_non_landmark_form", "Announce forms during navigation", + "Announces when you enter or leave a form that is not a landmark in browser browse mode."}, + {"read_full_row_in_gui_table", "Speak full row in GUI tables", + "Reads all cells in a row when moving between rows in application tables, including this settings table. Left and Right read individual cells."}, + {"read_full_row_in_document_table", "Speak full row in document tables", + "Reads the whole row when navigating rows in a document or web page table. Moving between columns reads individual cells."}, + {"read_full_row_in_spreadsheet", "Speak full row in spreadsheets", + "Reads the whole row when navigating rows in a spreadsheet. Moving between columns reads individual cells."}, + {"present_tooltips", "Present tooltips", + "Reads tooltip text when the application displays it."}, + {"enable_mouse_review", "Speak object under mouse", + "Reads the object under the mouse pointer as you move the mouse."}, + {"say_all_context_blockquote", "Announce block quotes in Say All", + "Announces entry into and exit from block quotes during continuous reading with Say All. This is separate from navigation announcements."}, + {"say_all_context_list", "Announce lists in Say All", + "Announces entry into and exit from lists during continuous reading with Say All. This is separate from navigation announcements."}, + {"say_all_context_table", "Announce tables in Say All", + "Announces entry into and exit from data tables during continuous reading with Say All. This is separate from navigation announcements."}, + {"say_all_context_panel", "Announce panels in Say All", + "Announces entry into and exit from panels or groups of controls during continuous reading with Say All. This is separate from navigation announcements."}, + {"say_all_context_non_landmark_form", "Announce forms in Say All", + "Announces entry into and exit from forms that are not landmarks during continuous reading with Say All. This is separate from navigation announcements."}, + {"say_all_context_landmark", "Announce landmarks in Say All", + "Announces entry into and exit from landmarks, such as main content or navigation regions, during continuous reading with Say All. This is separate from navigation announcements."}, +}; + +enum { + READING_ID, + READING_LABEL, + READING_ENABLED, + READING_DESCRIPTION, + READING_N_COLUMNS +}; +static void name_reading_toggle_cells(void); + +static void reading_toggled(GtkCellRendererToggle *renderer, gchar *path_string, gpointer data) { + (void)renderer; (void)data; + GtkTreeIter iter; + if (!gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(reading_store), &iter, path_string)) { + return; + } + gboolean active; + gtk_tree_model_get(GTK_TREE_MODEL(reading_store), &iter, READING_ENABLED, &active, -1); + gtk_list_store_set(reading_store, &iter, READING_ENABLED, !active, -1); + name_reading_toggle_cells(); +} + +static gboolean reading_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) { + (void)data; + if (event->keyval != GDK_KEY_space && event->keyval != GDK_KEY_KP_Space) return FALSE; + GtkTreePath *path = NULL; + gtk_tree_view_get_cursor(GTK_TREE_VIEW(widget), &path, NULL); + if (!path) return FALSE; + GtkTreeIter iter; + gboolean found = gtk_tree_model_get_iter(GTK_TREE_MODEL(reading_store), &iter, path); + gtk_tree_path_free(path); + if (!found) return FALSE; + gboolean active; + gtk_tree_model_get(GTK_TREE_MODEL(reading_store), &iter, READING_ENABLED, &active, -1); + gtk_list_store_set(reading_store, &iter, READING_ENABLED, !active, -1); + name_reading_toggle_cells(); + return TRUE; +} + +static void name_reading_toggle_cells(void) { + AtkObject *accessible = gtk_widget_get_accessible(prefs_widget("readingSettingsTreeview")); + if (!ATK_IS_TABLE(accessible)) return; + for (unsigned int i = 0; i < G_N_ELEMENTS(reading_rows); i++) { + AtkObject *cell = atk_table_ref_at(ATK_TABLE(accessible), i, 0); + if (!cell) continue; + GtkTreeIter iter; + gboolean active = FALSE; + if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(reading_store), &iter, NULL, i)) + gtk_tree_model_get(GTK_TREE_MODEL(reading_store), &iter, READING_ENABLED, &active, -1); + const char *name = active ? "checked" : "unchecked"; + if (g_strcmp0(atk_object_get_name(cell), name) != 0) atk_object_set_name(cell, name); + g_object_unref(cell); + } +} + +void prefs_init_reading_settings(void) { + reading_store = gtk_list_store_new(READING_N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING); + for (unsigned int i = 0; i < G_N_ELEMENTS(reading_rows); i++) { + GtkTreeIter iter; + gtk_list_store_append(reading_store, &iter); + gtk_list_store_set(reading_store, &iter, + READING_ID, reading_rows[i].id, + READING_LABEL, reading_rows[i].label, + READING_ENABLED, FALSE, + READING_DESCRIPTION, reading_rows[i].description, + -1); + } + + GtkTreeView *view = GTK_TREE_VIEW(prefs_widget("readingSettingsTreeview")); + gtk_tree_view_set_model(view, GTK_TREE_MODEL(reading_store)); + gtk_tree_view_set_headers_visible(view, TRUE); + GtkCellRenderer *text_renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn *setting_column = gtk_tree_view_column_new_with_attributes( + "Setting", text_renderer, "text", READING_LABEL, NULL); + GtkCellRenderer *toggle_renderer = gtk_cell_renderer_toggle_new(); + g_object_set(toggle_renderer, "activatable", TRUE, NULL); + g_signal_connect(toggle_renderer, "toggled", G_CALLBACK(reading_toggled), NULL); + GtkTreeViewColumn *enabled_column = gtk_tree_view_column_new_with_attributes( + "Enabled", toggle_renderer, "active", READING_ENABLED, NULL); + gtk_tree_view_append_column(view, enabled_column); + gtk_tree_view_append_column(view, setting_column); + GtkCellRenderer *descriptionRenderer = gtk_cell_renderer_text_new(); + g_object_set(descriptionRenderer, "wrap-mode", PANGO_WRAP_WORD_CHAR, "wrap-width", 280, NULL); + GtkTreeViewColumn *descriptionColumn = gtk_tree_view_column_new_with_attributes( + "Description", descriptionRenderer, "text", READING_DESCRIPTION, NULL); + gtk_tree_view_column_set_expand(descriptionColumn, TRUE); + gtk_tree_view_append_column(view, descriptionColumn); + g_signal_connect(view, "key-press-event", G_CALLBACK(reading_key_press), NULL); + name_reading_toggle_cells(); +} + +void prefs_reading_set(const char *id, int value) { + GtkTreeIter iter; + gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(reading_store), &iter); + while (valid) { + gchar *row_id; + gboolean active; + gtk_tree_model_get(GTK_TREE_MODEL(reading_store), &iter, + READING_ID, &row_id, READING_ENABLED, &active, -1); + if (g_strcmp0(row_id, id) == 0) { + if (active != (value != 0)) { + gtk_list_store_set(reading_store, &iter, READING_ENABLED, value != 0, -1); + name_reading_toggle_cells(); + } + g_free(row_id); + return; + } + g_free(row_id); + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(reading_store), &iter); + } +} + +int prefs_reading_get(const char *id) { + GtkTreeIter iter; + gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(reading_store), &iter); + while (valid) { + gchar *row_id; + gtk_tree_model_get(GTK_TREE_MODEL(reading_store), &iter, READING_ID, &row_id, -1); + if (g_strcmp0(row_id, id) == 0) { + gboolean active; + gtk_tree_model_get(GTK_TREE_MODEL(reading_store), &iter, READING_ENABLED, &active, -1); + g_free(row_id); + return active ? 1 : 0; + } + g_free(row_id); + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(reading_store), &iter); + } + return 0; +} + diff --git a/internal/preferences/native_tentacles.c b/internal/preferences/native_tentacles.c new file mode 100644 index 0000000..9cc3df8 --- /dev/null +++ b/internal/preferences/native_tentacles.c @@ -0,0 +1,163 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native_internal.h" + +static GtkListStore *tentacleStore; +static gboolean updating; + +static void name_toggle_cells(void) { + AtkObject *accessible = gtk_widget_get_accessible(prefs_widget("tentaclesTree")); + if (!ATK_IS_TABLE(accessible)) return; + int rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(tentacleStore), NULL); + for (int row = 0; row < rows; row++) { + AtkObject *cell = atk_table_ref_at(ATK_TABLE(accessible), row, 0); + if (!cell) continue; + GtkTreeIter iter; + gboolean enabled = FALSE; + gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(tentacleStore), &iter, NULL, row); + gtk_tree_model_get(GTK_TREE_MODEL(tentacleStore), &iter, 0, &enabled, -1); + atk_object_set_name(cell, enabled ? "checked" : "unchecked"); + g_object_unref(cell); + } +} +static void tentacle_selected(GtkTreeSelection *selection, gpointer data) { + (void)selection; (void)data; + if (!updating) prefs_set_action(16); +} +static void tentacle_clicked(GtkButton *button, gpointer data) { + (void)button; + prefs_set_action(GPOINTER_TO_INT(data)); +} +static void tentacle_toggled(GtkCellRendererToggle *renderer, gchar *pathString, gpointer data) { + (void)renderer; (void)data; + if (updating) return; + GtkTreePath *path = gtk_tree_path_new_from_string(pathString); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(prefs_widget("tentaclesTree")), path, NULL, FALSE); + gtk_tree_path_free(path); + // The accepted backend snapshot owns the check state; never check + // optimistically before persistence or after an operation has failed. + prefs_set_action(11); +} +static gboolean tentacle_key(GtkWidget *widget, GdkEventKey *event, gpointer data) { + (void)widget; (void)data; + if (event->keyval != GDK_KEY_space && event->keyval != GDK_KEY_KP_Space) return FALSE; + prefs_set_action(11); + return TRUE; +} +static void repository_switched(GtkNotebook *notebook, GtkWidget *page, guint index, gpointer data) { + (void)notebook; (void)index; (void)data; + GtkWidget *scroll = prefs_widget("tentacleTableScroll"); + GtkWidget *parent = gtk_widget_get_parent(scroll); + if (parent != page) { + g_object_ref(scroll); + gtk_container_remove(GTK_CONTAINER(parent), scroll); + gtk_container_add(GTK_CONTAINER(page), scroll); + g_object_unref(scroll); + } + if (!updating) prefs_set_action(17); +} +void prefs_init_tentacles(void) { + updating = FALSE; + tentacleStore = gtk_list_store_new(7, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + GtkTreeView *tree = GTK_TREE_VIEW(prefs_widget("tentaclesTree")); + gtk_tree_view_set_model(tree, GTK_TREE_MODEL(tentacleStore)); + GtkCellRenderer *toggle = gtk_cell_renderer_toggle_new(); + g_signal_connect(toggle, "toggled", G_CALLBACK(tentacle_toggled), NULL); + gtk_tree_view_append_column(tree, gtk_tree_view_column_new_with_attributes("Enabled", toggle, "active", 0, NULL)); + const char *titles[] = {"Name", "Status", "Version", "Repository", "Details", "Shortcuts"}; + for (unsigned i = 0; i < G_N_ELEMENTS(titles); i++) { + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_append_column(tree, gtk_tree_view_column_new_with_attributes(titles[i], renderer, "text", i + 1, NULL)); + } + gtk_tree_selection_set_mode(gtk_tree_view_get_selection(tree), GTK_SELECTION_SINGLE); + g_signal_connect(gtk_tree_view_get_selection(tree), "changed", G_CALLBACK(tentacle_selected), NULL); + g_signal_connect(tree, "key-press-event", G_CALLBACK(tentacle_key), NULL); + g_signal_connect(prefs_widget("tentacleRepositories"), "switch-page", G_CALLBACK(repository_switched), NULL); + const struct { const char *id; int action; } buttons[] = { + {"tentacleNew", 9}, {"tentacleRetry", 13}, {"tentacleRemove", 14}, + {"tentacleRefresh", 15}, {"tentacleRepositoryRemove", 12}, {"tentacleRepositoryRefresh", 18}, + {"tentacleInstall", 19}, {"tentacleSettings", 20}, + }; + for (unsigned i = 0; i < G_N_ELEMENTS(buttons); i++) + g_signal_connect(prefs_widget(buttons[i].id), "clicked", G_CALLBACK(tentacle_clicked), GINT_TO_POINTER(buttons[i].action)); + atk_object_set_name(gtk_widget_get_accessible(GTK_WIDGET(tree)), "Tentacles"); + atk_object_set_name(gtk_widget_get_accessible(prefs_widget("tentacleRepositoryURL")), "Repository URL"); + atk_object_set_name(gtk_widget_get_accessible(prefs_widget("tentacleRepositories")), "Tentacle repositories"); + g_object_unref(tentacleStore); // Owned by the tree. +} +void prefs_tentacles_clear(void) { + updating = TRUE; + gtk_list_store_clear(tentacleStore); +} +void prefs_tentacle_append(int enabled, const char *name, const char *state, const char *version, const char *repository, const char *message, const char *shortcuts) { + GtkTreeIter iter; + gtk_list_store_append(tentacleStore, &iter); + gtk_list_store_set(tentacleStore, &iter, 0, enabled != 0, 1, name, 2, state, 3, version, 4, repository, 5, message, 6, shortcuts, -1); +} +int prefs_tentacle_selected(void) { + GtkTreeModel *model; + GtkTreeIter iter; + GtkTreeView *tree = GTK_TREE_VIEW(prefs_widget("tentaclesTree")); + if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection(tree), &model, &iter)) return -1; + GtkTreePath *path = gtk_tree_model_get_path(model, &iter); + int row = gtk_tree_path_get_indices(path)[0]; + gtk_tree_path_free(path); + return row; +} +void prefs_tentacle_select(int row) { + updating = TRUE; + GtkTreeView *tree = GTK_TREE_VIEW(prefs_widget("tentaclesTree")); + gtk_tree_selection_unselect_all(gtk_tree_view_get_selection(tree)); + if (row >= 0) { + GtkTreePath *path = gtk_tree_path_new_from_indices(row, -1); + if (gtk_widget_has_focus(GTK_WIDGET(tree))) gtk_tree_view_set_cursor(tree, path, NULL, FALSE); + else gtk_tree_selection_select_path(gtk_tree_view_get_selection(tree), path); + gtk_tree_path_free(path); + } + name_toggle_cells(); + updating = FALSE; +} +void prefs_tentacle_controls(int available, int installed, int enabled, int repository) { + gtk_widget_set_sensitive(prefs_widget("tentacleNew"), available); + gtk_widget_set_sensitive(prefs_widget("tentacleRepositoryURL"), available); + gtk_widget_set_sensitive(prefs_widget("tentacleRetry"), available && installed && enabled); + gtk_widget_set_sensitive(prefs_widget("tentacleSettings"), available && installed); + gtk_widget_set_sensitive(prefs_widget("tentacleRemove"), available && installed); + gtk_widget_set_sensitive(prefs_widget("tentacleInstall"), available && !installed && prefs_tentacle_selected() >= 0); + gtk_widget_set_sensitive(prefs_widget("tentacleRepositoryRefresh"), available && repository); + gtk_widget_set_sensitive(prefs_widget("tentacleRepositoryRemove"), available && repository); +} +int prefs_tentacle_confirm(const char *message, const char *label) { + GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(prefs_widget("window")), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, "%s", message); + gtk_window_set_title(GTK_WINDOW(dialog), "Install tentacle"); + gtk_dialog_add_button(GTK_DIALOG(dialog), "Cancel", GTK_RESPONSE_CANCEL); + gtk_dialog_add_button(GTK_DIALOG(dialog), label, GTK_RESPONSE_ACCEPT); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL); + int response = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + return response == GTK_RESPONSE_ACCEPT; +} +void prefs_tentacle_repositories_clear(void) { + updating = TRUE; + GtkNotebook *notebook = GTK_NOTEBOOK(prefs_widget("tentacleRepositories")); + gtk_notebook_set_current_page(notebook, 0); + while (gtk_notebook_get_n_pages(notebook) > 1) gtk_notebook_remove_page(notebook, -1); + updating = FALSE; +} +void prefs_tentacle_repository_append(const char *label) { + updating = TRUE; + GtkWidget *page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_notebook_append_page(GTK_NOTEBOOK(prefs_widget("tentacleRepositories")), page, gtk_label_new(label)); + gtk_widget_show_all(page); + updating = FALSE; +} +int prefs_tentacle_repository_selected(void) { + return gtk_notebook_get_current_page(GTK_NOTEBOOK(prefs_widget("tentacleRepositories"))); +} +void prefs_tentacle_repository_select(int page) { + updating = TRUE; + gtk_notebook_set_current_page(GTK_NOTEBOOK(prefs_widget("tentacleRepositories")), page); + updating = FALSE; +} diff --git a/internal/preferences/native_text_attributes.c b/internal/preferences/native_text_attributes.c new file mode 100644 index 0000000..ab78534 --- /dev/null +++ b/internal/preferences/native_text_attributes.c @@ -0,0 +1,200 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native_internal.h" + +enum { WORD, REPLACEMENT }; +static GtkListStore *pronunciations; + +static void pronunciation_edited(GtkCellRendererText *renderer, gchar *path, gchar *text, gpointer data) { + (void)renderer; + GtkTreeIter iter; + if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(pronunciations), &iter, path)) + gtk_list_store_set(pronunciations, &iter, GPOINTER_TO_INT(data), text, -1); +} + +static void pronunciation_add(GtkButton *button, gpointer data) { + (void)button; (void)data; + GtkTreeIter iter; + gtk_list_store_append(pronunciations, &iter); + gtk_list_store_set(pronunciations, &iter, WORD, "", REPLACEMENT, "", -1); + GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(pronunciations), &iter); + GtkTreeView *view = GTK_TREE_VIEW(prefs_widget("pronunciationTreeView")); + gtk_widget_grab_focus(GTK_WIDGET(view)); + gtk_tree_view_set_cursor(view, path, gtk_tree_view_get_column(view, WORD), TRUE); + gtk_tree_path_free(path); +} + +static void pronunciation_delete(GtkButton *button, gpointer data) { + (void)button; (void)data; + GtkTreeIter iter; + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(prefs_widget("pronunciationTreeView"))); + if (gtk_tree_selection_get_selected(selection, NULL, &iter)) gtk_list_store_remove(pronunciations, &iter); + gtk_widget_grab_focus(prefs_widget("pronunciationTreeView")); +} + +static gboolean pronunciation_key(GtkWidget *widget, GdkEventKey *event, gpointer data) { + (void)data; + if (event->keyval != GDK_KEY_Return && event->keyval != GDK_KEY_KP_Enter && event->keyval != GDK_KEY_F2) return FALSE; + GtkTreePath *path = NULL; + GtkTreeViewColumn *column = NULL; + gtk_tree_view_get_cursor(GTK_TREE_VIEW(widget), &path, &column); + if (!path) return FALSE; + gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), path, column ? column : gtk_tree_view_get_column(GTK_TREE_VIEW(widget), 0), TRUE); + gtk_tree_path_free(path); + return TRUE; +} + +void prefs_init_pronunciation(void) { + GtkTreeView *view = GTK_TREE_VIEW(prefs_widget("pronunciationTreeView")); + pronunciations = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); + gtk_tree_view_set_model(view, GTK_TREE_MODEL(pronunciations)); + const char *labels[] = {"Word", "Pronunciation"}; + for (int column = 0; column < 2; column++) { + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + g_object_set(renderer, "editable", TRUE, NULL); + g_signal_connect(renderer, "edited", G_CALLBACK(pronunciation_edited), GINT_TO_POINTER(column)); + gtk_tree_view_append_column(view, gtk_tree_view_column_new_with_attributes(labels[column], renderer, "text", column, NULL)); + } + atk_object_set_name(gtk_widget_get_accessible(GTK_WIDGET(view)), "Pronunciation dictionary"); + atk_object_set_description(gtk_widget_get_accessible(GTK_WIDGET(view)), "Select a cell and press Enter to edit it. Tab moves to the next control."); + g_signal_connect(view, "key-press-event", G_CALLBACK(pronunciation_key), NULL); + g_signal_connect(prefs_widget("pronunciationAddButton"), "clicked", G_CALLBACK(pronunciation_add), NULL); + g_signal_connect(prefs_widget("pronunciationDeleteButton"), "clicked", G_CALLBACK(pronunciation_delete), NULL); + g_object_unref(pronunciations); +} + +void prefs_pronunciation_clear(void) { gtk_list_store_clear(pronunciations); } +void prefs_pronunciation_append(const char *word, const char *replacement) { + GtkTreeIter iter; + gtk_list_store_append(pronunciations, &iter); + gtk_list_store_set(pronunciations, &iter, WORD, word, REPLACEMENT, replacement, -1); +} +int prefs_pronunciation_count(void) { return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(pronunciations), NULL); } +char *prefs_pronunciation_value(int row, int column) { + GtkTreeIter iter; + if (column < 0 || column > 1 || !gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pronunciations), &iter, NULL, row)) return NULL; + char *value = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(pronunciations), &iter, column, &value, -1); + return value; +} + +enum { ATTRIBUTE_KEY, ATTRIBUTE_LABEL, ATTRIBUTE_SPEAK, ATTRIBUTE_BRAILLE }; +static GtkListStore *attributes; + +static void attribute_toggle(GtkCellRendererToggle *renderer, gchar *path, gpointer data) { + (void)renderer; + GtkTreeIter iter; + int column = GPOINTER_TO_INT(data); + if (!gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(attributes), &iter, path)) return; + gboolean active = FALSE; + gtk_tree_model_get(GTK_TREE_MODEL(attributes), &iter, column, &active, -1); + gtk_list_store_set(attributes, &iter, column, !active, -1); +} + +static gboolean attribute_key(GtkWidget *widget, GdkEventKey *event, gpointer data) { + (void)data; + if (event->keyval != GDK_KEY_space && event->keyval != GDK_KEY_KP_Space) return FALSE; + GtkTreePath *path = NULL; + GtkTreeViewColumn *column = NULL; + gtk_tree_view_get_cursor(GTK_TREE_VIEW(widget), &path, &column); + if (!path) return FALSE; + GtkTreeIter iter; + gboolean found = gtk_tree_model_get_iter(GTK_TREE_MODEL(attributes), &iter, path); + gtk_tree_path_free(path); + if (!found) return FALSE; + int selected = column == gtk_tree_view_get_column(GTK_TREE_VIEW(widget), 2) ? ATTRIBUTE_BRAILLE : ATTRIBUTE_SPEAK; + gboolean active = FALSE; + gtk_tree_model_get(GTK_TREE_MODEL(attributes), &iter, selected, &active, -1); + gtk_list_store_set(attributes, &iter, selected, !active, -1); + return TRUE; +} + +static void attribute_move(GtkButton *button, gpointer data) { + (void)button; + GtkTreeView *view = GTK_TREE_VIEW(prefs_widget("textAttributesTreeView")); + GtkTreeIter iter, other; + if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection(view), NULL, &iter)) return; + GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(attributes), &iter); + int row = gtk_tree_path_get_indices(path)[0]; + int last = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(attributes), NULL) - 1; + int target = row; + switch (GPOINTER_TO_INT(data)) { + case 0: target = 0; break; + case 1: target = row - 1; break; + case 2: target = row + 1; break; + case 3: target = last; break; + } + if (target >= 0 && target <= last && target != row && + gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(attributes), &other, NULL, target)) { + if (target < row) gtk_list_store_move_before(attributes, &iter, &other); + else gtk_list_store_move_after(attributes, &iter, &other); + GtkTreePath *new_path = gtk_tree_path_new_from_indices(target, -1); + gtk_tree_view_set_cursor(view, new_path, NULL, FALSE); + gtk_tree_path_free(new_path); + } + gtk_tree_path_free(path); + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +static void attribute_select_all(GtkButton *button, gpointer data) { + (void)button; + gboolean active = GPOINTER_TO_INT(data) != 0; + GtkTreeIter iter; + gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(attributes), &iter); + while (valid) { + gtk_list_store_set(attributes, &iter, ATTRIBUTE_SPEAK, active, ATTRIBUTE_BRAILLE, active, -1); + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(attributes), &iter); + } +} + +static void attribute_reset(GtkButton *button, gpointer data) { (void)button; (void)data; prefs_set_action(8); } + +void prefs_init_text_attributes(void) { + GtkTreeView *view = GTK_TREE_VIEW(prefs_widget("textAttributesTreeView")); + attributes = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); + gtk_tree_view_set_model(view, GTK_TREE_MODEL(attributes)); + GtkCellRenderer *text = gtk_cell_renderer_text_new(); + gtk_tree_view_append_column(view, gtk_tree_view_column_new_with_attributes("Attribute", text, "text", ATTRIBUTE_LABEL, NULL)); + const char *labels[] = {"Speak", "Braille"}; + for (int i = 0; i < 2; i++) { + GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new(); + g_object_set(renderer, "activatable", TRUE, NULL); + g_signal_connect(renderer, "toggled", G_CALLBACK(attribute_toggle), GINT_TO_POINTER(i+ATTRIBUTE_SPEAK)); + gtk_tree_view_append_column(view, gtk_tree_view_column_new_with_attributes(labels[i], renderer, "active", i+ATTRIBUTE_SPEAK, NULL)); + } + g_signal_connect(view, "key-press-event", G_CALLBACK(attribute_key), NULL); + AtkObject *accessible = gtk_widget_get_accessible(GTK_WIDGET(view)); + atk_object_set_name(accessible, "Text attributes"); + atk_object_set_description(accessible, "Use arrows to select an attribute. Space toggles the selected Speak or Braille column. Use the Move buttons to change order."); + const char *moves[] = {"textMoveToTopButton", "textMoveUpOneButton", "textMoveDownOneButton", "textMoveToBottomButton"}; + for (int i = 0; i < 4; i++) g_signal_connect(prefs_widget(moves[i]), "clicked", G_CALLBACK(attribute_move), GINT_TO_POINTER(i)); + g_signal_connect(prefs_widget("textSelectAllButton"), "clicked", G_CALLBACK(attribute_select_all), GINT_TO_POINTER(1)); + g_signal_connect(prefs_widget("textUnselectAllButton"), "clicked", G_CALLBACK(attribute_select_all), GINT_TO_POINTER(0)); + g_signal_connect(prefs_widget("textResetButton"), "clicked", G_CALLBACK(attribute_reset), NULL); + g_object_unref(attributes); +} + +void prefs_text_attributes_clear(void) { gtk_list_store_clear(attributes); } +void prefs_text_attribute_append(const char *key, const char *label, int speak, int braille) { + GtkTreeIter iter; + gtk_list_store_append(attributes, &iter); + gtk_list_store_set(attributes, &iter, ATTRIBUTE_KEY, key, ATTRIBUTE_LABEL, label, + ATTRIBUTE_SPEAK, speak != 0, ATTRIBUTE_BRAILLE, braille != 0, -1); +} +int prefs_text_attribute_count(void) { return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(attributes), NULL); } +char *prefs_text_attribute_key(int row) { + GtkTreeIter iter; + if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(attributes), &iter, NULL, row)) return NULL; + char *key = NULL; + gtk_tree_model_get(GTK_TREE_MODEL(attributes), &iter, ATTRIBUTE_KEY, &key, -1); + return key; +} +int prefs_text_attribute_enabled(int row, int column) { + GtkTreeIter iter; + if (column < ATTRIBUTE_SPEAK || column > ATTRIBUTE_BRAILLE || + !gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(attributes), &iter, NULL, row)) return 0; + gboolean active = FALSE; + gtk_tree_model_get(GTK_TREE_MODEL(attributes), &iter, column, &active, -1); + return active; +} diff --git a/internal/preferences/native_widgets.c b/internal/preferences/native_widgets.c new file mode 100644 index 0000000..0fa22dd --- /dev/null +++ b/internal/preferences/native_widgets.c @@ -0,0 +1,69 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native_internal.h" + +void prefs_number_set(const char *id, double value) { + GtkWidget *control = prefs_widget(id); + gtk_range_set_value(GTK_RANGE(control), value); + // Loading an effective value must not turn inheritance into an override. + g_object_set_data(G_OBJECT(control), "number-edited", NULL); +} +double prefs_number_value(const char *id) { return gtk_range_get_value(GTK_RANGE(prefs_widget(id))); } +int prefs_number_edited(const char *id) { + return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(prefs_widget(id)), "number-edited")); +} +void prefs_choice_set(const char *id, int value) { + gchar *name = g_strdup_printf("%s_%d", id, value); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_widget(name)), TRUE); + g_free(name); +} +int prefs_choice_get(const char *id) { + for (int i = 0; i < 4; i++) { + gchar *name = g_strdup_printf("%s_%d", id, i); + GtkWidget *button = prefs_widget(name); + g_free(name); + if (button && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) return i; + } + return -1; +} +void prefs_combo_set(const char *id, int value) { + gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_widget(id)), value); +} +int prefs_combo_get(const char *id) { + return gtk_combo_box_get_active(GTK_COMBO_BOX(prefs_widget(id))); +} + +void prefs_check_set(const char *id, int value) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prefs_widget(id)), value); } +int prefs_check_get(const char *id) { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prefs_widget(id))); } + +void prefs_range_set(const char *id, double value) { gtk_range_set_value(GTK_RANGE(prefs_widget(id)), value); } +void prefs_spin_set(const char *id, double value) { gtk_spin_button_set_value(GTK_SPIN_BUTTON(prefs_widget(id)), value); } +double prefs_spin_get(const char *id) { return gtk_spin_button_get_value(GTK_SPIN_BUTTON(prefs_widget(id))); } +void prefs_combo_clear(const char *id) { gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(prefs_widget(id))); } +void prefs_combo_append(const char *id, const char *text) { gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(prefs_widget(id)), text); } +void prefs_hardware_devices_clear(void) { + GtkEntryCompletion *completion = gtk_entry_get_completion(GTK_ENTRY(prefs_widget("hardwareDeviceEntry"))); + gtk_list_store_clear(GTK_LIST_STORE(gtk_entry_completion_get_model(completion))); +} +void prefs_hardware_device_append(const char *text) { + GtkEntryCompletion *completion = gtk_entry_get_completion(GTK_ENTRY(prefs_widget("hardwareDeviceEntry"))); + GtkListStore *model = GTK_LIST_STORE(gtk_entry_completion_get_model(completion)); + GtkTreeIter row; + gtk_list_store_append(model, &row); + gtk_list_store_set(model, &row, 0, text, -1); +} +void prefs_hardware_device_set(const char *text) { + gtk_entry_set_text(GTK_ENTRY(prefs_widget("hardwareDeviceEntry")), text); +} +const char *prefs_hardware_device_get(void) { + return gtk_entry_get_text(GTK_ENTRY(prefs_widget("hardwareDeviceEntry"))); +} +void prefs_hardware_sensitivity(int enabled) { + gtk_widget_set_sensitive(prefs_widget("hardwareDeviceEntry"), enabled); + gtk_widget_set_sensitive(prefs_widget("hardwareBaudCombo"), enabled); + gtk_widget_set_sensitive(prefs_widget("speechLanguages"), !enabled); + gtk_widget_set_sensitive(prefs_widget("speechFamilies"), !enabled); +} +void prefs_entry_set(const char *id, const char *text) { gtk_entry_set_text(GTK_ENTRY(prefs_widget(id)), text); } +const char *prefs_entry_get(const char *id) { return gtk_entry_get_text(GTK_ENTRY(prefs_widget(id))); } diff --git a/internal/preferences/ocr.go b/internal/preferences/ocr.go new file mode 100644 index 0000000..226b726 --- /dev/null +++ b/internal/preferences/ocr.go @@ -0,0 +1,53 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +func setOCRValues(value config.OCRSettings) { + id, content := C.CString("ocrLanguageEntry"), C.CString(value.Language) + C.prefs_entry_set(id, content) + C.free(unsafe.Pointer(id)) + C.free(unsafe.Pointer(content)) + setCombo("ocrLayoutCombo", map[int]int{3: 0, 6: 1, 11: 2}[value.Layout]) + setSpin("ocrScaleSpinButton", float64(value.Scale)) + setCheck("ocrGrayscaleCheckButton", value.Grayscale) + setCheck("ocrInvertCheckButton", value.Invert) + setCheck("ocrBlackWhiteCheckButton", value.BlackWhite) + setSpin("ocrBlackWhiteValueSpinButton", float64(value.Threshold)) + setCheck("ocrAutoRefreshCheckButton", value.AutoRefresh) + setSpin("ocrRefreshIntervalSpinButton", float64(value.RefreshInterval)) + setCheck("ocrConfirmClickCheckButton", value.ConfirmClick) + setCheck("ocrCopyToClipboardCheckButton", value.CopyFirstResult) + setCheck("ocrAutoReadAllCheckButton", value.AutoReadAll) +} + +func getOCRValues() config.OCRSettings { + id := C.CString("ocrLanguageEntry") + language := C.GoString(C.prefs_entry_get(id)) + C.free(unsafe.Pointer(id)) + layout := 3 + if index := getCombo("ocrLayoutCombo"); index >= 0 && index < 3 { + layout = []int{3, 6, 11}[index] + } + return config.OCRSettings{ + Language: language, Layout: layout, Scale: int(getSpin("ocrScaleSpinButton")), + Grayscale: getCheck("ocrGrayscaleCheckButton"), Invert: getCheck("ocrInvertCheckButton"), + BlackWhite: getCheck("ocrBlackWhiteCheckButton"), Threshold: int(getSpin("ocrBlackWhiteValueSpinButton")), + AutoRefresh: getCheck("ocrAutoRefreshCheckButton"), RefreshInterval: int(getSpin("ocrRefreshIntervalSpinButton")), + ConfirmClick: getCheck("ocrConfirmClickCheckButton"), CopyFirstResult: getCheck("ocrCopyToClipboardCheckButton"), + AutoReadAll: getCheck("ocrAutoReadAllCheckButton"), + } +} diff --git a/internal/preferences/preferences.ui b/internal/preferences/preferences.ui new file mode 100644 index 0000000..69e9694 --- /dev/null +++ b/internal/preferences/preferences.ui @@ -0,0 +1,331 @@ + + + + 0 + 99 + 0.1 + 5 + + + 0 + 9 + 0.1 + 1 + + + 0 + 9 + 0.1 + 1 + + 01000.11 + 0100.11 + 0100.11 + 010.50.050.1 + 060515 + 1100050110 + + 1120 + 101 + + + 0100 + 501 + + 1411 + 0255200110 + 5006000015001001000 + + Cthulhu Preferences + 760 + 560 + 12 + + + vertical + 10 + + + True + True + + + + never + + vertical + 12 + 8 + Keyboard Layout + 812 + _DesktopTrueTrue + _LaptopTrueTruegeneralDesktopButton + + + False + False + Progress _bar output:TrueprogressBarOutputCombo0 + FalseOffBeepSpeakBeep and speak + Report back_ground progress barsTrueTrue + + + + General + + + + never + + vertical + 12 + 8 + Enable _soundsTrueTrue + TrueTruesound_volume_adjustment2rightSound volume + FalseAutomaticPipeWirePulseAudioALSA + FalseDefaultNone + FalseSound and speechSpeech onlySound only + Play sound for _roleTrueTrue + Play sound for _stateTrueTrue + Play sound for p_osition in setTrueTrue + Use stereo _position for object soundsTrueTrue + + + + Sounds + + + + never + + vertical + 12 + 10 + _Enable speechTrueTrue + + 10 + 12 + Speech _system:TruespeechSystems100 + FalseSpeech DispatcherHardware serial synthesizer10 + Speech synthesi_zer:TruespeechServers101 + FalseDefault11 + _Language:TruespeechLanguages102 + FalseDefault12 + _Person:TruespeechFamilies103 + FalseDefault13 + FalseDefaultUppercaseHyperlinkSystem14 + _Voice type:TruevoiceTypesCombo104 + Vo_lume:Truevolume105 + volume_adjustmentTrue1Trueright15 + Pi_tch:Truepitch106 + pitch_adjustmentTrue1Trueright16 + _Rate:Truerate107 + rate_adjustmentTrue1Trueright17 + Capital lettersvertical68 + Raise pitch for capital lettersTrue + Beep for capital lettersTrue + Say “cap” before capital lettersTrue + 082 + TrueSerial device path; completion offers detected devices112 + Serial _device:TruehardwareDeviceEntry1012 + Serial baud rate:hardwareBaudCombo1014 + False1200240048009600192003840057600115200114 + + + vertical + 8 + 12 + Verbosity812 + Brie_fTrueTrue + Ver_boseTrueTruespeechBriefButton + + Speech interruptionvertical88 + All keys interruptTrue + Control, Enter, Space, and EscapeTrueinterruptAllKeysRadio + Define interruption keysTrueinterruptAllKeysRadio + Record interruption keysTrue + Defined keys:interruptionKeysEntry0 + TrueFalse + + Speech history812 + History _entries:TruespeechHistoryLimitSpinButton + Truespeech_history_limit_adjustmentTrueNumber of spoken items kept in history + + Punctuation Level812 + _NoneTrueTrue + So_meTrueTruepunctuation_3 + M_ostTrueTruepunctuation_3 + _AllTrueTruepunctuation_3 + + Say All88 + FalseSentenceLine + + Reading settingsneverTrueTrue + Indentation812 + SpeechTrue + BeepsTrueindentationSpeechButton + Speech and beepsTrueindentationSpeechButton + + + 0152 + + + + + + + Speech + + + neververtical128 + Enable _brailleTrueTrue + _Abbreviated role namesTrueTrue + Disable end of line symbolTrue + Enable contracted brailleTrue + FalseContraction table for the current language + Enable word wrapTrue + Braille verbosity128 + BriefTrue + VerboseTruebrailleBriefButton + + Selection indicator: NoneTrue + Selection indicator: Dot 7TruebrailleSelectionNoneButton + Selection indicator: Dot 8TruebrailleSelectionNoneButton + Selection indicator: Dots 7 and 8TruebrailleSelectionNoneButton + Link indicator: NoneTrue + Link indicator: Dot 7TruebrailleLinkNoneButton + Link indicator: Dot 8TruebrailleLinkNoneButton + Link indicator: Dots 7 and 8TruebrailleLinkNoneButton + Enable flash messagesTrue + Truebraille_flash_adjustmentFlash message duration in seconds + Messages are persistentTrue + Messages are detailedTrue + + Braille + + neververtical127 + Disable key echoTrue + Enable key echoTruekeyEchoDisabledRadio + Key echo in edit fieldsTruekeyEchoDisabledRadio + Enable alphabetic keysTrue + Enable numeric keysTrue + Enable punctuation keysTrue + Enable spaceTrue + Enable modifier keysTrue + Enable function keysTrue + Enable action keysTrue + Enable navigation keysTrue + Enable diacritical keysTrue + Use custom echo voiceTrue + Speech synthesizerechoSpeechServers0 + FalseDefault + VoiceechoSpeechFamilies0 + FalseDefault + 1echo_rate_adjustmentTrueTrueKey echo rate + 1echo_pitch_adjustmentTrueTrueKey echo pitch + 1echo_volume_adjustmentTrueTrueKey echo volume + Use the custom voice for:vertical78 + Key namesTrue + Typed charactersTrue + WordsTrue + SentencesTrue + + Enable echo by characterTrue + Enable echo by wordTrue + Enable echo by sentenceTrue + + Key Echo + + vertical128 + 110neverTrueTrue + 8 + Edit bindings for layout + Desktop bindingsTrue + Laptop bindingsTruekeyBindingDesktopButton + + Select a command. Enter shortcuts separated by semicolons and press Set binding, for example Cthulhu+Ctrl+F8; Alt+F9. Changes are committed with Apply or OK.True0 + TrueTrueTrue + 8 + _ShortcutsTruekeyBindingEntry + TrueTrue + + start + Set bindingTrue + Clear bindingTrue + Restore default bindingTrue + Restore all bindings for this layoutTrue + + + Key Bindings + + vertical128 + TrueTrue + end_New entryTrueTrue_DeleteTrueTrue + + Pronunciation + + vertical128 + TrueTrue + Select _AllTrueTrue_Unselect AllTrueTrue_ResetTrueTrue + Move to _topTrueTrueMove _upTrueTrueMove _downTrueTrueMove to _bottomTrueTrue + Braille indicator: NoneTrue + Braille indicator: Dot 7TruetextBrailleNoneButton + Braille indicator: Dot 8TruetextBrailleNoneButton + Braille indicator: Dots 7 and 8TruetextBrailleNoneButton + + Text Attributes + + neververtical128 + TrueInstalled language codes, for example eng or fra+engRecognition languages. Leave empty for the installed default. + FalseAutomatic pageSingle text blockSparse text + Trueocr_scale_adjustmentImage scale factor, 1 through 4 + _Grayscale imageTrueTrue + _Invert imageTrueTrue + _Black and white imageTrueTrue + Trueocr_threshold_adjustmentBlack and white threshold, 0 through 255 + Automatically _read the first OCR resultTrueTrue + _Periodically refresh screen OCRTrueTrue + Trueocr_refresh_adjustmentRefresh interval in milliseconds + _Confirm OCR coordinate clicksTrueTrue + Copy first OCR result to _clipboardTrueTrue + + OCR + + vertical128 + Tentacle management changes take effect immediately.True0 + 8 + Repository _URLTruetentacleRepositoryURL + TrueTrue + Add repositoryTrue + + TrueTrueTrue + vertical + 100TrueTrueTrue + + All tentacles + + start6 + InstallTrue + SettingsTrue + RetryTrue + Remove tentacleTrue + Refresh statusTrue + Refresh repositoryTrue + Remove repositoryTrue + + + Tentacles + + + _StatusTruestatus0 + FalseTrue + end8 + _HelpTrueTrue + _ApplyTrueTrue + _CancelTrueTrue + _OKTrueTrueTrue + + + + + diff --git a/internal/preferences/protocol.go b/internal/preferences/protocol.go new file mode 100644 index 0000000..b17dd42 --- /dev/null +++ b/internal/preferences/protocol.go @@ -0,0 +1,138 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package preferences implements the isolated GTK preferences process and its +// bounded, typed protocol. The UI never opens settings files or speech sockets. +package preferences + +import ( + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/speech" + "git.stormux.org/storm/cthulhu/internal/tentacle" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type Values struct { + Pronunciations []config.PronunciationEntry + TextAttributes config.TextAttributeSettings + OCR config.OCRSettings + ProgressBar config.ProgressBarSettings + KeyboardLayout int + CthulhuModifierKeys []string + KeyBindings []input.BindingOverride + TimeFormat string + DateFormat string + EnableSound bool + EnableSpeech bool + SpeechHistoryLimit int + SpeechInterruption input.InterruptionSettings + SpeechVerbosityLevel int + SayAllStyle string + EnableBraille bool + EnableContractedBraille bool + BrailleContractionTable string + Braille config.BrailleOptions + SoundVolume float64 + SoundSink string + SoundTheme string + PlaySoundForRole bool + PlaySoundForState bool + PlaySoundForPositionInSet bool + SpatializeObjectSounds bool + RoleSoundPresentation string + EnableKeyEcho bool + KeyEchoInEditFieldsOnly bool + EnableAlphabeticKeys bool + EnableNumericKeys bool + EnablePunctuationKeys bool + EnableSpace bool + EnableModifierKeys bool + EnableFunctionKeys bool + EnableActionKeys bool + EnableNavigationKeys bool + EnableDiacriticalKeys bool + EnableEchoByCharacter bool + EnableEchoByWord bool + EnableEchoBySentence bool + UseCustomEchoVoice bool + UseCustomEchoSpeechServer bool + UseCustomEchoForKey bool + UseCustomEchoForCharacter bool + UseCustomEchoForWord bool + UseCustomEchoForSentence bool + EchoVoice config.Voice + EchoSpeechServer string + + Rate *float64 + Pitch *float64 + Volume *float64 + SpeechServerFactory string + HardwareSpeechDevice string + HardwareSpeechBaudRate int + SpeechOutputModule string + SpeechVoiceFamily *config.VoiceFamily + UppercaseVoice config.Voice + HyperlinkVoice config.Voice + SystemVoice config.Voice + VoiceType string // Preview selection; never persisted as reader state. + Punctuation int + RaisePitchForCapitals bool + BeepForCapitals bool + SayCapForCapitals bool + Reading config.ReadingSettings + SpeakDescription bool +} + +type ExtensionPage struct { + Session string + Revision uint64 + tentaclewire.PreferencePage +} + +type PageDraft struct { + Session string + ID string + Revision uint64 + Values map[string]interaction.Value +} + +type Request struct { + ExtensionPages []PageDraft `json:",omitempty"` + Tentacle *tentacle.ManagementRequest + Application string + Values Values + Save bool + Close bool + // Preview applies the default voice controls to the running speech + // backend without committing session or persistent settings. + Preview bool + // EchoPreview identifies the focused echo control (rate, pitch, volume, + // synthesizer or person). Only its value uses the draft echo voice. + EchoPreview string `json:",omitempty"` + // Focus previews include the control label in the normal voice before its value. + EchoPreviewFocus bool `json:",omitempty"` + // Cancel restores the last committed settings after a live preview. + Cancel bool +} + +type Response struct { + ExtensionPages []ExtensionPage `json:",omitempty"` + ExtensionsOnly bool `json:",omitempty"` + Tentacles *tentacle.Snapshot `json:",omitempty"` + ChooseApplication bool + Catalog speech.Catalog + SpeechDefaults speech.Settings + CatalogPending bool // More catalog parts follow before the UI can initialize. + Application string + Present bool + Close bool + Values Values + CanSave bool + Message string + Preview bool + // Accepted distinguishes committed session values from rejected drafts. + Accepted bool +} diff --git a/internal/preferences/protocol_test.go b/internal/preferences/protocol_test.go new file mode 100644 index 0000000..a1b60a8 --- /dev/null +++ b/internal/preferences/protocol_test.go @@ -0,0 +1,160 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +import ( + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestSoundValuesDefaultAndMerge(t *testing.T) { + settings := config.DefaultSettings() + values := FromSettings(settings) + if !values.EnableSound || !values.PlaySoundForRole || !values.PlaySoundForState || + !values.PlaySoundForPositionInSet || + values.ProgressBar.OutputMode != "beep" || values.SpatializeObjectSounds { + t.Fatalf("default sound checkboxes = %+v", values) + } + + values.EnableSound = false + values.EnableBraille = true + values.EnableContractedBraille = true + values.BrailleContractionTable = "en-us-g2.ctb" + values.SoundVolume = 0.75 + values.SoundSink = "pulse" + values.SoundTheme = "none" + values.PlaySoundForRole = false + values.PlaySoundForState = false + values.PlaySoundForPositionInSet = false + values.SpatializeObjectSounds = true + values.ProgressBar.OutputMode = "off" + values.ProgressBar.ReportBackground = true + values.RoleSoundPresentation = "speech_only" + + merged, err := values.Merge(settings) + if err != nil { + t.Fatal(err) + } + if got := FromSettings(merged); !reflect.DeepEqual(got, values) { + t.Fatalf("sound values did not round trip:\n got %+v\nwant %+v", got, values) + } +} + +func TestReadingValuesRoundTrip(t *testing.T) { + settings := config.DefaultSettings() + values := FromSettings(settings) + if values.Reading.OnlySpeakDisplayedText || !values.Reading.SpeakBlankLines || + !values.SpeakDescription || values.Reading.ReadFullRowInSpreadSheet || + !values.EnableSpeech || !values.Reading.EnablePauseBreaks || + values.Reading.SpeakNumbersAsDigits || values.Reading.SpeakMultiCaseStringsAsWords || + values.Reading.EnableIndentation || values.Reading.PhoneticCharacterHints { + t.Fatalf("default reading values = %+v", values) + } + + values.EnableSpeech = false + values.SayAllStyle = "sentence" + values.SpeechVerbosityLevel = 0 + values.Reading.OnlySpeakDisplayedText = true + values.Reading.EnablePauseBreaks = false + values.Reading.SpeakNumbersAsDigits = true + values.Reading.SpeakMultiCaseStringsAsWords = true + values.Reading.EnableIndentation = true + values.Reading.PhoneticCharacterHints = true + values.Reading.SpeakBlankLines = false + values.Reading.EnableMnemonicSpeaking = true + values.Reading.EnablePositionSpeaking = true + values.Reading.EnableTutorialMessages = true + values.Reading.MessagesAreDetailed = false + values.Reading.UseColorNames = false + values.Reading.PresentTooltips = true + values.Reading.EnableMouseReview = true + values.Reading.SpeakMisspelledIndicator = false + values.Reading.SpeakContextBlockquote = false + values.Reading.SpeakContextList = false + values.Reading.SpeakContextTable = false + values.Reading.SpeakContextPanel = false + values.Reading.SpeakContextLandmark = false + values.Reading.SpeakContextNonLandmarkForm = false + values.Reading.SayAllContextBlockquote = false + values.Reading.SayAllContextList = false + values.Reading.SayAllContextTable = false + values.Reading.SayAllContextPanel = false + values.Reading.SayAllContextLandmark = false + values.Reading.SayAllContextNonLandmarkForm = false + values.Reading.ReadFullRowInGUITable = false + values.Reading.ReadFullRowInDocumentTable = false + values.Reading.ReadFullRowInSpreadSheet = true + values.SpeakDescription = false + + merged, err := values.Merge(settings) + if err != nil { + t.Fatal(err) + } + if got := FromSettings(merged); !reflect.DeepEqual(got, values) { + t.Fatalf("reading values did not round trip:\n got %+v\nwant %+v", got, values) + } +} + +func TestSpeechValuesRoundTrip(t *testing.T) { + settings := config.DefaultSettings() + settings.SpeechHistoryLimit = 1000 + family := &config.VoiceFamily{Name: "Generic Voice", Lang: "en", Dialect: "US", Variant: "male"} + settings.SpeechOutputModule = "espeak-ng" + settings.DefaultVoice.Family = family + + values := FromSettings(settings) + if values.SpeechOutputModule != "espeak-ng" || values.SpeechVoiceFamily != family || values.SpeechHistoryLimit != 1000 { + t.Fatalf("speech values = %+v", values) + } + merged, err := values.Merge(settings) + if err != nil { + t.Fatal(err) + } + if merged.SpeechOutputModule != "espeak-ng" || merged.DefaultVoice.Family != family || merged.SpeechHistoryLimit != 1000 { + t.Fatalf("merged speech values = %+v", merged) + } +} + +func TestKeyboardValuesMergeAndOwnership(t *testing.T) { + settings := config.DefaultSettings() + values := FromSettings(settings) + values.KeyboardLayout = 2 + values.CthulhuModifierKeys = []string{"Caps_Lock", "Insert"} + merged, err := values.Merge(settings) + if err != nil { + t.Fatal(err) + } + if merged.KeyboardLayout != 2 || !reflect.DeepEqual(merged.CthulhuModifierKeys, values.CthulhuModifierKeys) { + t.Fatalf("keyboard settings were not merged: %+v", merged) + } + values.CthulhuModifierKeys[0] = "KP_Insert" + if merged.CthulhuModifierKeys[0] != "Caps_Lock" { + t.Fatal("merged modifiers alias the UI values") + } + values.CthulhuModifierKeys = []string{} + merged, err = values.Merge(settings) + if err != nil || len(merged.CthulhuModifierKeys) != 0 { + t.Fatalf("cannot disable all modifiers: %v", err) + } +} + +func TestCapitalCheckboxesRoundTrip(t *testing.T) { + for mask := 0; mask < 8; mask++ { + settings := config.DefaultSettings() + values := FromSettings(settings) + values.RaisePitchForCapitals = mask&1 != 0 + values.BeepForCapitals = mask&2 != 0 + values.SayCapForCapitals = mask&4 != 0 + merged, err := values.Merge(settings) + if err != nil { + t.Fatal(err) + } + if got := FromSettings(merged); !reflect.DeepEqual(got, values) { + t.Fatalf("mask %d did not round trip", mask) + } + } +} diff --git a/internal/preferences/reading.go b/internal/preferences/reading.go new file mode 100644 index 0000000..6d143f9 --- /dev/null +++ b/internal/preferences/reading.go @@ -0,0 +1,75 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "unsafe" +) + +func setReading(values Values) { + for _, item := range readingChecks(&values) { + id := C.CString(item.id) + C.prefs_reading_set(id, boolean(*item.value)) + C.free(unsafe.Pointer(id)) + } +} + +func getReading(values *Values) { + for _, item := range readingChecks(values) { + id := C.CString(item.id) + *item.value = C.prefs_reading_get(id) != 0 + C.free(unsafe.Pointer(id)) + } +} + +func readingChecks(values *Values) []struct { + id string + value *bool +} { + return []struct { + id string + value *bool + }{ + {"only_speak_displayed_text", &values.Reading.OnlySpeakDisplayedText}, + {"automatically_read_title_changes", &values.Reading.AutomaticallyReadTitleChanges}, + {"automatically_read_clipboard_changes", &values.Reading.AutomaticallyReadClipboardChanges}, + {"phonetic_character_hints", &values.Reading.PhoneticCharacterHints}, + {"enable_pause_breaks", &values.Reading.EnablePauseBreaks}, + {"speak_numbers_as_digits", &values.Reading.SpeakNumbersAsDigits}, + {"speak_multicase_strings_as_words", &values.Reading.SpeakMultiCaseStringsAsWords}, + {"enable_indentation", &values.Reading.EnableIndentation}, + {"speak_blank_lines", &values.Reading.SpeakBlankLines}, + {"enable_mnemonic_speaking", &values.Reading.EnableMnemonicSpeaking}, + {"enable_position_speaking", &values.Reading.EnablePositionSpeaking}, + {"enable_tutorial_messages", &values.Reading.EnableTutorialMessages}, + {"messages_are_detailed", &values.Reading.MessagesAreDetailed}, + {"use_color_names", &values.Reading.UseColorNames}, + {"present_tooltips", &values.Reading.PresentTooltips}, + {"enable_mouse_review", &values.Reading.EnableMouseReview}, + {"speak_misspelled_indicator", &values.Reading.SpeakMisspelledIndicator}, + {"speak_context_blockquote", &values.Reading.SpeakContextBlockquote}, + {"speak_context_list", &values.Reading.SpeakContextList}, + {"speak_context_table", &values.Reading.SpeakContextTable}, + {"speak_context_panel", &values.Reading.SpeakContextPanel}, + {"speak_context_landmark", &values.Reading.SpeakContextLandmark}, + {"speak_context_non_landmark_form", &values.Reading.SpeakContextNonLandmarkForm}, + {"say_all_context_blockquote", &values.Reading.SayAllContextBlockquote}, + {"say_all_context_list", &values.Reading.SayAllContextList}, + {"say_all_context_table", &values.Reading.SayAllContextTable}, + {"say_all_context_panel", &values.Reading.SayAllContextPanel}, + {"say_all_context_landmark", &values.Reading.SayAllContextLandmark}, + {"say_all_context_non_landmark_form", &values.Reading.SayAllContextNonLandmarkForm}, + {"read_full_row_in_gui_table", &values.Reading.ReadFullRowInGUITable}, + {"read_full_row_in_document_table", &values.Reading.ReadFullRowInDocumentTable}, + {"read_full_row_in_spreadsheet", &values.Reading.ReadFullRowInSpreadSheet}, + {"speak_description", &values.SpeakDescription}, + } +} diff --git a/internal/preferences/session.go b/internal/preferences/session.go new file mode 100644 index 0000000..d8c8674 --- /dev/null +++ b/internal/preferences/session.go @@ -0,0 +1,39 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +import ( + "git.stormux.org/storm/cthulhu/internal/braille" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +// uiSession lives for one helper window. Only the locked GTK thread in Run +// accesses these fields; pipe readers deliver immutable responses by channel. +type uiSession struct { + extensionPages []ExtensionPage + progressBar config.ProgressBarSettings + catalog speech.Catalog + speechDefaults speech.Settings + contractionTables []braille.TableOption + soundThemes []string + echoModules []string + echoFamilies []*config.VoiceFamily + activeEchoModule string + speechModules []string + speechLanguages []string + speechFamilies []*config.VoiceFamily + activeSpeechSystem int + softwareModule string + hardwareModule string + activeSpeechModule string + activeSpeechLanguage string + voiceDrafts [4]config.Voice + activeVoiceType int + bindingDraft []input.BindingOverride + bindingRows []input.BindingRow + bindingLayout int +} diff --git a/internal/preferences/sound.go b/internal/preferences/sound.go new file mode 100644 index 0000000..e95dec0 --- /dev/null +++ b/internal/preferences/sound.go @@ -0,0 +1,78 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +import ( + "errors" +) + +func soundChecks(values *Values) []struct { + id string + value *bool +} { + return []struct { + id string + value *bool + }{ + {"enableSoundCheckButton", &values.EnableSound}, + {"playSoundForRoleCheckButton", &values.PlaySoundForRole}, + {"playSoundForStateCheckButton", &values.PlaySoundForState}, + {"playSoundForPositionInSetCheckButton", &values.PlaySoundForPositionInSet}, + {"spatializeObjectSoundsCheckButton", &values.SpatializeObjectSounds}, + } +} + +func (session *uiSession) setSoundTheme(theme string) { + session.soundThemes = []string{"default", "none"} + selected := 0 + if theme == "none" { + selected = 1 + } else if theme != "" && theme != "default" { + selected = len(session.soundThemes) + session.soundThemes = append(session.soundThemes, theme) + } + labels := make([]string, len(session.soundThemes)) + for i, value := range session.soundThemes { + if value == "default" { + labels[i] = "Default" + } else if value == "none" { + labels[i] = "None" + } else { + labels[i] = value + } + } + comboItems("soundThemeCombo", labels, selected) +} + +func set_sound_checks(values Values) { + for _, check := range soundChecks(&values) { + setCheck(check.id, *check.value) + } +} + +func (session *uiSession) set_sound_values(values Values) { + setRange("soundVolumeScale", values.SoundVolume) + setCombo("soundSinkCombo", map[string]int{"auto": 0, "pipewire": 1, "pulse": 2, "alsa": 3}[values.SoundSink]) + session.setSoundTheme(values.SoundTheme) + setCombo("roleSoundPresentationCombo", map[string]int{"sound_and_speech": 0, "speech_only": 1, "sound_only": 2}[values.RoleSoundPresentation]) +} + +func get_sound_checks(values *Values) { + for _, check := range soundChecks(values) { + *check.value = getCheck(check.id) + } +} + +func (session *uiSession) get_sound_values(values *Values) error { + values.SoundVolume = getRange("soundVolumeScale") + sink, theme, presentation := getCombo("soundSinkCombo"), getCombo("soundThemeCombo"), getCombo("roleSoundPresentationCombo") + if sink < 0 || sink > 3 || theme < 0 || theme >= len(session.soundThemes) || presentation < 0 || presentation > 2 { + return errors.New("Choose valid sound output settings.") + } + values.SoundSink = []string{"auto", "pipewire", "pulse", "alsa"}[sink] + values.SoundTheme = session.soundThemes[theme] + values.RoleSoundPresentation = []string{"sound_and_speech", "speech_only", "sound_only"}[presentation] + return nil +} diff --git a/internal/preferences/speech.go b/internal/preferences/speech.go new file mode 100644 index 0000000..184d75f --- /dev/null +++ b/internal/preferences/speech.go @@ -0,0 +1,436 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "errors" + "fmt" + "math" + "path/filepath" + "sort" + "strings" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +func (session *uiSession) setSpeechVoice(values Values) { + session.voiceDrafts = [4]config.Voice{ + {Rate: values.Rate, AveragePitch: values.Pitch, Gain: values.Volume, Family: values.SpeechVoiceFamily}, + values.UppercaseVoice, values.HyperlinkVoice, values.SystemVoice, + } + setCombo("voiceTypesCombo", session.activeVoiceType) + session.activeSpeechSystem = 0 + if values.SpeechServerFactory == "hardwarefactory" { + session.activeSpeechSystem = 1 + } + setCombo("speechSystems", session.activeSpeechSystem) + devices := []string{} + for _, pattern := range []string{"/dev/ttyS*", "/dev/ttyUSB*", "/dev/ttyACM*", "/dev/serial/by-id/*"} { + matches, _ := filepath.Glob(pattern) + devices = append(devices, matches...) + } + sort.Strings(devices) + C.prefs_hardware_devices_clear() + for _, device := range devices { + label := C.CString(device) + C.prefs_hardware_device_append(label) + C.free(unsafe.Pointer(label)) + } + device := C.CString(values.HardwareSpeechDevice) + C.prefs_hardware_device_set(device) + C.free(unsafe.Pointer(device)) + baudIndex := 3 + for index, baud := range hardwareBaudRates { + if baud == values.HardwareSpeechBaudRate { + baudIndex = index + } + } + setCombo("hardwareBaudCombo", baudIndex) + C.prefs_hardware_sensitivity(C.int(session.activeSpeechSystem)) + session.populateSpeechModules(values) + session.load_voice_editor() +} + +var hardwareBaudRates = []int{1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200} + +func (session *uiSession) populateSpeechModules(values Values) { + if session.activeSpeechSystem == 1 { + session.speechModules = []string{"litetalk", "doubletalk", "tripletalk", "dectalk"} + selected := 0 + for index, module := range session.speechModules { + if module == values.SpeechOutputModule { + selected = index + } + } + comboItems("speechServers", []string{"LiteTalk", "DoubleTalk", "TripleTalk", "DECtalk"}, selected) + session.activeSpeechModule = session.speechModules[selected] + comboItems("speechLanguages", []string{"Default"}, 0) + comboItems("speechFamilies", []string{"Default"}, 0) + return + } + session.speechModules = []string{""} + for module := range session.catalog { + if module != "" { + session.speechModules = append(session.speechModules, module) + } + } + sort.Strings(session.speechModules[1:]) + selected := 0 + if values.SpeechOutputModule != "" { + selected = -1 + for i, module := range session.speechModules { + if module == values.SpeechOutputModule { + selected = i + } + } + if selected < 0 { + selected = len(session.speechModules) + session.speechModules = append(session.speechModules, values.SpeechOutputModule) + } + } + labels := append([]string(nil), session.speechModules...) + labels[0] = "Default" + comboItems("speechServers", labels, selected) + session.populateSpeechLanguages(values.SpeechOutputModule, "", values.SpeechVoiceFamily) +} + +func (session *uiSession) populateSpeechLanguages(module, language string, selected *config.VoiceFamily) { + session.activeSpeechModule = module + session.speechLanguages = []string{""} + seen := map[string]bool{"": true} + for _, voice := range session.catalog[module] { + if seen[voice.Language] { + continue + } + seen[voice.Language] = true + session.speechLanguages = append(session.speechLanguages, voice.Language) + } + index := 0 + if selected != nil { + language = strings.TrimSuffix(selected.Lang+"-"+selected.Dialect, "-") + } + for i, candidate := range session.speechLanguages { + if strings.EqualFold(candidate, language) { + index = i + break + } + } + if selected != nil && index == 0 && language != "" { + session.speechLanguages = append(session.speechLanguages, language) + index = len(session.speechLanguages) - 1 + } + labels := append([]string(nil), session.speechLanguages...) + labels[0] = "Default" + comboItems("speechLanguages", labels, index) + session.populateSpeechFamilies(module, session.speechLanguages[index], selected) +} + +func (session *uiSession) populateSpeechFamilies(module, language string, selected *config.VoiceFamily) { + session.activeSpeechLanguage = language + session.speechFamilies = []*config.VoiceFamily{nil} + labels := []string{"Default"} + index := 0 + voices := session.catalog[module] + if language == "" { + voices = session.default_voices(module) + } + for _, voice := range voices { + if language != "" && !strings.EqualFold(voice.Language, language) { + continue + } + family := &config.VoiceFamily{Name: voice.Name, Lang: voice.Language, Variant: voice.Variant} + session.speechFamilies = append(session.speechFamilies, family) + labels = append(labels, voice.Name+" ("+voice.Language+")") + if selected != nil && selected.Name == voice.Name && + strings.EqualFold(strings.TrimSuffix(selected.Lang+"-"+selected.Dialect, "-"), voice.Language) { + index = len(labels) - 1 + } + } + if selected != nil && selected.Name != "" && index == 0 { + index = len(labels) + session.speechFamilies = append(session.speechFamilies, selected) + labels = append(labels, selected.Name+" ("+selected.Lang+")") + } + comboItems("speechFamilies", labels, index) +} + +func (session *uiSession) selectedSpeechModule() string { + i := getCombo("speechServers") + if i >= 0 && i < len(session.speechModules) { + return session.speechModules[i] + } + return "" +} + +func (session *uiSession) selectedSpeechFamily() *config.VoiceFamily { + i := getCombo("speechFamilies") + if i >= 0 && i < len(session.speechFamilies) { + if family := session.speechFamilies[i]; family != nil { + return family + } + languageIndex := getCombo("speechLanguages") + if languageIndex > 0 && languageIndex < len(session.speechLanguages) { + return &config.VoiceFamily{Lang: session.speechLanguages[languageIndex]} + } + } + return nil +} + +func (session *uiSession) refreshSpeechVoices() { + voiceType := getCombo("voiceTypesCombo") + if voiceType >= 0 && voiceType < len(session.voiceDrafts) && voiceType != session.activeVoiceType { + voice, err := session.read_voice_editor() + if err != nil { + status(err.Error(), true) + setCombo("voiceTypesCombo", session.activeVoiceType) + return + } + session.voiceDrafts[session.activeVoiceType] = voice + session.activeVoiceType = voiceType + session.load_voice_editor() + return + } + system := getCombo("speechSystems") + if system != session.activeSpeechSystem { + if voice, err := session.read_voice_editor(); err == nil { + session.voiceDrafts[session.activeVoiceType] = voice + } + if session.activeSpeechSystem == 0 { + session.softwareModule = session.selectedSpeechModule() + } else { + session.hardwareModule = session.selectedSpeechModule() + } + session.activeSpeechSystem = system + module := session.softwareModule + if system == 1 { + module = session.hardwareModule + } + session.populateSpeechModules(Values{SpeechOutputModule: module}) + C.prefs_hardware_sensitivity(C.int(system)) + if system == 0 { + session.reconcile_voice_families(session.selectedSpeechModule()) + } + session.load_voice_editor() + } + if system == 1 { + return + } + module := session.selectedSpeechModule() + if module != session.activeSpeechModule { + if voice, err := session.read_voice_editor(); err == nil { + session.voiceDrafts[session.activeVoiceType] = voice + } + session.reconcile_voice_families(module) + session.populateSpeechLanguages(module, session.activeSpeechLanguage, session.voiceDrafts[session.activeVoiceType].Family) + return + } + languageIndex := getCombo("speechLanguages") + if languageIndex < 0 || languageIndex >= len(session.speechLanguages) { + return + } + language := session.speechLanguages[languageIndex] + if language != session.activeSpeechLanguage { + session.populateSpeechFamilies(module, language, nil) + } +} + +func (session *uiSession) reconcile_voice_families(module string) { + for index, voice := range session.voiceDrafts { + family := voice.Family + if family == nil { + continue + } + language := strings.TrimSuffix(family.Lang+"-"+family.Dialect, "-") + languageFound, exact := false, false + for _, candidate := range session.catalog[module] { + if strings.EqualFold(candidate.Language, language) { + languageFound = true + if candidate.Name == family.Name { + exact = true + break + } + } + } + if exact { + continue + } + if languageFound { + session.voiceDrafts[index].Family = &config.VoiceFamily{Lang: language} + } else { + session.voiceDrafts[index].Family = nil + } + } +} + +func set_speech_support(values Values) { + setCheck("interruptAllKeysRadio", values.SpeechInterruption.Mode != input.InterruptCommonKeys && values.SpeechInterruption.Mode != input.InterruptCustomKeys) + setCheck("interruptCommonKeysRadio", values.SpeechInterruption.Mode == input.InterruptCommonKeys) + setCheck("interruptCustomKeysRadio", values.SpeechInterruption.Mode == input.InterruptCustomKeys) + C.prefs_interruption_clear() + for _, name := range values.SpeechInterruption.Keys { + key := C.CString(name) + C.prefs_interruption_append(key) + C.free(unsafe.Pointer(key)) + } + setCheck("speechSupportCheckButton", values.EnableSpeech) + setSpin("speechHistoryLimitSpinButton", float64(values.SpeechHistoryLimit)) + setCheck("speechBriefButton", values.SpeechVerbosityLevel == 0) + setCheck("speechVerboseButton", values.SpeechVerbosityLevel != 0) + setCombo("sayAllStyle", map[string]int{"sentence": 0, "line": 1}[values.SayAllStyle]) + mode := values.Reading.IndentationPresentationMode + setCheck("indentationSpeechButton", mode == "" || mode == "speech") + setCheck("indentationBeepsButton", mode == "beeps") + setCheck("indentationSpeechAndBeepsButton", mode == "both") +} + +func set_speech_numbers(values Values, inherited config.Voice, defaults speech.Settings) { + for _, item := range []struct { + id string + value *float64 + inherited *float64 + server *int + scale float64 + offset float64 + fallback float64 + }{ + {"rate", values.Rate, inherited.Rate, defaults.Rate, 2, 98, 50}, + {"pitch", values.Pitch, inherited.AveragePitch, defaults.Pitch, 20, 90, 5}, + {"volume", values.Volume, inherited.Gain, defaults.Volume, 15, 35, 5}, + } { + id := C.CString(item.id) + value := item.fallback + if item.server != nil { + value = math.Round((float64(*item.server)+item.offset)/item.scale*10) / 10 + } + if item.inherited != nil { + value = *item.inherited + } + if item.value != nil { + value = *item.value + } + C.prefs_number_set(id, C.double(value)) + C.free(unsafe.Pointer(id)) + } +} + +func set_speech_presentation(values Values) { + setChoice("punctuation", values.Punctuation) + setCheck("raisePitchForCapitals", values.RaisePitchForCapitals) + setCheck("beepForCapitals", values.BeepForCapitals) + setCheck("sayCapForCapitals", values.SayCapForCapitals) + setReading(values) +} + +func get_speech_support(values *Values) { + values.SpeechInterruption.Mode = input.InterruptAllKeys + if getCheck("interruptCommonKeysRadio") { + values.SpeechInterruption.Mode = input.InterruptCommonKeys + } else if getCheck("interruptCustomKeysRadio") { + values.SpeechInterruption.Mode = input.InterruptCustomKeys + } + for i := C.int(0); i < C.prefs_interruption_count(); i++ { + values.SpeechInterruption.Keys = append(values.SpeechInterruption.Keys, C.GoString(C.prefs_interruption_key(i))) + } + values.EnableSpeech = getCheck("speechSupportCheckButton") + values.SpeechHistoryLimit = int(getSpin("speechHistoryLimitSpinButton")) + values.Reading.IndentationPresentationMode = "speech" + if getCheck("indentationBeepsButton") { + values.Reading.IndentationPresentationMode = "beeps" + } else if getCheck("indentationSpeechAndBeepsButton") { + values.Reading.IndentationPresentationMode = "both" + } + values.SpeechVerbosityLevel = 1 + if getCheck("speechBriefButton") { + values.SpeechVerbosityLevel = 0 + } + if getCombo("sayAllStyle") == 0 { + values.SayAllStyle = "sentence" + } else { + values.SayAllStyle = "line" + } +} + +func (session *uiSession) get_speech_values(values *Values) error { + voice, err := session.read_voice_editor() + if err != nil { + return err + } + session.voiceDrafts[session.activeVoiceType] = voice + defaultVoice := session.voiceDrafts[0] + values.Rate, values.Pitch, values.Volume = defaultVoice.Rate, defaultVoice.AveragePitch, defaultVoice.Gain + values.SpeechVoiceFamily = defaultVoice.Family + values.UppercaseVoice, values.HyperlinkVoice, values.SystemVoice = session.voiceDrafts[1], session.voiceDrafts[2], session.voiceDrafts[3] + values.VoiceType = []string{"default", "uppercase", "hyperlink", "system"}[session.activeVoiceType] + values.EchoVoice, values.EchoSpeechServer = session.getEchoVoice() + // The synthesizer dropdown now owns this choice directly. Retain the + // existing settings field so older profiles keep their meaning on load. + values.UseCustomEchoSpeechServer = true + values.SpeechServerFactory = "speechdispatcherfactory" + if session.activeSpeechSystem == 1 { + values.SpeechServerFactory = "hardwarefactory" + } + values.HardwareSpeechDevice = C.GoString(C.prefs_hardware_device_get()) + indexBaud := getCombo("hardwareBaudCombo") + if indexBaud < 0 || indexBaud >= len(hardwareBaudRates) { + return errors.New("Choose a serial baud rate.") + } + values.HardwareSpeechBaudRate = hardwareBaudRates[indexBaud] + values.SpeechOutputModule = session.selectedSpeechModule() + values.Punctuation = getChoice("punctuation") + values.RaisePitchForCapitals = getCheck("raisePitchForCapitals") + values.BeepForCapitals = getCheck("beepForCapitals") + values.SayCapForCapitals = getCheck("sayCapForCapitals") + return nil +} + +func (session *uiSession) load_voice_editor() { + voice := session.voiceDrafts[session.activeVoiceType] + settings := config.Settings{RaisePitchForCapitals: true, DefaultVoice: session.voiceDrafts[0], UppercaseVoice: session.voiceDrafts[1], HyperlinkVoice: session.voiceDrafts[2], SystemVoice: session.voiceDrafts[3]} + kind := []string{"default", "uppercase", "hyperlink", "system"}[session.activeVoiceType] + defaults := session.speechDefaults + if session.activeSpeechSystem == 1 { + defaults = speech.Settings{} + } + set_speech_numbers(Values{Rate: voice.Rate, Pitch: voice.AveragePitch, Volume: voice.Gain}, config.EffectiveVoice(settings, kind), defaults) + if session.activeSpeechSystem != 1 { + session.populateSpeechLanguages(session.selectedSpeechModule(), "", voice.Family) + } +} + +func (session *uiSession) read_voice_editor() (config.Voice, error) { + voice := session.voiceDrafts[session.activeVoiceType] + for _, item := range []struct { + id string + target **float64 + max float64 + }{ + {"rate", &voice.Rate, 99}, {"pitch", &voice.AveragePitch, 9}, {"volume", &voice.Gain, 9}, + } { + id := C.CString(item.id) + edited := C.prefs_number_edited(id) != 0 + value := float64(C.prefs_number_value(id)) + C.free(unsafe.Pointer(id)) + if !edited { + continue + } + if !(value >= 0 && value <= item.max) { + return voice, fmt.Errorf("Enter a %s between 0 and %.0f.", item.id, item.max) + } + *item.target = &value + } + if session.activeSpeechSystem != 1 { + voice.Family = session.selectedSpeechFamily() + } + return voice, nil +} diff --git a/internal/preferences/tentacles.go b/internal/preferences/tentacles.go new file mode 100644 index 0000000..2671a0d --- /dev/null +++ b/internal/preferences/tentacles.go @@ -0,0 +1,285 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "errors" + "fmt" + "reflect" + "slices" + "strings" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/tentacle" +) + +type tentacleRow struct { + key string + status tentacle.EntryStatus + installed bool +} + +type tentaclePage struct { + snapshot *tentacle.Snapshot + rows []tentacleRow + origins []string + selectedKey string +} + +func tentacle_rows(snapshot *tentacle.Snapshot, origin string) []tentacleRow { + if snapshot == nil { + return nil + } + var rows []tentacleRow + seen := make(map[string]bool) + repositoryIDs := make(map[string]string) + for _, repository := range snapshot.Repositories { + repositoryIDs[repository.URL] = repository.ID + } + for _, status := range snapshot.Entries { + entry := status.Entry + localID := entry.LocalID + if localID == "" { + localID = entry.ID + } + key := entry.Repository + "\x00" + entry.RepositoryID + "\x00" + localID + seen[key] = true + if origin == "" || entry.Repository == origin && entry.RepositoryID == repositoryIDs[origin] { + rows = append(rows, tentacleRow{key: key, status: status, installed: true}) + } + } + for _, repository := range snapshot.Repositories { + if origin != "" && repository.URL != origin { + continue + } + for _, manifest := range repository.Tentacles { + key := repository.URL + "\x00" + repository.ID + "\x00" + manifest.ID + if seen[key] { + continue + } + status := tentacle.EntryStatus{ + Entry: tentacle.Entry{ID: manifest.ID, LocalID: manifest.ID, Name: manifest.Name, Version: manifest.Version, Repository: repository.URL, RepositoryID: repository.ID}, + State: "Available", + Message: manifest.Description, + } + rows = append(rows, tentacleRow{key: key, status: status}) + } + } + return rows +} + +func (page *tentaclePage) selected() *tentacleRow { + row := int(C.prefs_tentacle_selected()) + if row < 0 || row >= len(page.rows) { + return nil + } + return &page.rows[row] +} + +func (page *tentaclePage) origin() string { + index := int(C.prefs_tentacle_repository_selected()) - 1 + if index < 0 || index >= len(page.origins) { + return "" + } + return page.origins[index] +} + +func (page *tentaclePage) controls() { + selected := page.selected() + installed, enabled := false, false + if selected != nil { + installed, enabled = selected.installed, selected.status.Entry.Enabled + } + available := page.snapshot != nil && !page.snapshot.Suppressed && page.snapshot.Message == "" + C.prefs_tentacle_controls(boolean(available), boolean(installed), boolean(enabled), boolean(page.origin() != "")) +} + +func (page *tentaclePage) render() { + page.rows = tentacle_rows(page.snapshot, page.origin()) + C.prefs_tentacles_clear() + selectedRow := -1 + for index, row := range page.rows { + entry := row.status.Entry + name := entry.Name + if name == "" { + name = entry.ID + } + repository := tentacle.RepositoryLabel(entry.Repository) + if entry.Repository == "" { + repository = "Local development" + } + texts := []*C.char{C.CString(name), C.CString(row.status.State), C.CString(entry.Version), C.CString(repository), C.CString(row.status.Message), C.CString(strings.Join(row.status.Shortcuts, "; "))} + C.prefs_tentacle_append(boolean(entry.Enabled), texts[0], texts[1], texts[2], texts[3], texts[4], texts[5]) + for _, text := range texts { + C.free(unsafe.Pointer(text)) + } + if row.key == page.selectedKey { + selectedRow = index + } + } + C.prefs_tentacle_select(C.int(selectedRow)) + page.controls() +} + +func (page *tentaclePage) populate(snapshot *tentacle.Snapshot) { + if selected := page.selected(); selected != nil { + page.selectedKey = selected.key + } + origin := page.origin() + var origins []string + if snapshot != nil { + for _, repository := range snapshot.Repositories { + origins = append(origins, repository.URL) + } + } + if !reflect.DeepEqual(page.origins, origins) { + C.prefs_tentacle_repositories_clear() + selectedPage := 0 + labels := make(map[string]int) + for _, value := range origins { + labels[tentacle.RepositoryLabel(value)]++ + } + for index, value := range origins { + label := tentacle.RepositoryLabel(value) + if labels[label] > 1 { + label = value + } + text := C.CString(label) + C.prefs_tentacle_repository_append(text) + C.free(unsafe.Pointer(text)) + if value == origin { + selectedPage = index + 1 + } + } + page.origins = origins + C.prefs_tentacle_repository_select(C.int(selectedPage)) + } + page.snapshot = snapshot + page.render() +} + +func (page *tentaclePage) action(action int) (*tentacle.ManagementRequest, error) { + if action == 16 { + if selected := page.selected(); selected != nil { + page.selectedKey = selected.key + } + page.controls() + return nil, nil + } + if action == 17 { + page.render() + return nil, nil + } + if action == 15 { + return &tentacle.ManagementRequest{Action: "list"}, nil + } + if page.snapshot == nil || page.snapshot.Suppressed || page.snapshot.Message != "" { + message := "Tentacle management is unavailable for this run." + if page.snapshot != nil && page.snapshot.Message != "" { + message = page.snapshot.Message + } + return nil, errors.New(message) + } + if action == 9 { + id := C.CString("tentacleRepositoryURL") + origin, err := tentacle.RepositoryURL(C.GoString(C.prefs_entry_get(id))) + C.free(unsafe.Pointer(id)) + if err != nil { + return nil, err + } + return &tentacle.ManagementRequest{Action: "repository-add", URL: origin}, nil + } + if action == 12 || action == 18 { + origin := page.origin() + if origin == "" { + return nil, errors.New("Select a repository tab first.") + } + operation := "repository-remove" + if action == 18 { + operation = "repository-refresh" + } + return &tentacle.ManagementRequest{Action: operation, URL: origin}, nil + } + selected := page.selected() + if selected == nil { + return nil, errors.New("Select a tentacle first.") + } + page.selectedKey = selected.key + if !selected.installed { + if action != 11 && action != 19 { + return nil, errors.New("Install this tentacle first.") + } + entry := selected.status.Entry + var manifest *tentacle.Manifest + for _, repository := range page.snapshot.Repositories { + if repository.URL == entry.Repository && repository.ID == entry.RepositoryID { + for index := range repository.Tentacles { + if repository.Tentacles[index].ID == entry.LocalID { + manifest = &repository.Tentacles[index] + break + } + } + } + } + if manifest == nil || len(manifest.Releases) == 0 { + return nil, errors.New("No package has been published for this tentacle. Refresh the repository after a release is published.") + } + permissions := "This tentacle can register reader commands." + if slices.Contains(manifest.Capabilities, "presentation") { + permissions = "This tentacle can register reader commands and send speech and braille messages." + } + if slices.Contains(manifest.Capabilities, "interaction") { + permissions = "This tentacle can register reader commands, send speech and braille messages, open internal forms, read the focused item and clipboard when invoked, and write clipboard text." + } + if slices.Contains(manifest.Capabilities, "reader-settings") { + permissions += " It can also add preferences pages and quick settings, inspect speech voices, and temporarily change the reader voice configuration." + } + operation, label := "install", "Install" + if action == 11 { + operation, label = "install-enable", "Install and enable" + } + message := fmt.Sprintf("%s %s version %s from %s?\n\n%s\n\nOnly install packages from publishers you trust. Tentacles run with your account's access; resource limits do not protect your files or network.\n\nTentacle management changes take effect immediately.", label, entry.Name, entry.Version, entry.Repository, permissions) + text, button := C.CString(message), C.CString(label) + accepted := C.prefs_tentacle_confirm(text, button) + C.free(unsafe.Pointer(text)) + C.free(unsafe.Pointer(button)) + if accepted == 0 { + return nil, nil + } + return &tentacle.ManagementRequest{Action: operation, ID: entry.LocalID, URL: entry.Repository}, nil + } + operation := "" + switch action { + case 11: + operation = "enable" + if selected.status.Entry.Enabled { + operation = "disable" + } + case 13: + operation = "retry" + case 14: + operation = "remove" + case 20: + operation = "settings" + default: + return nil, errors.New("Unknown tentacle action.") + } + return &tentacle.ManagementRequest{Action: operation, ID: selected.status.Entry.ID}, nil +} + +func (page *tentaclePage) accepted(request *tentacle.ManagementRequest) { + if request.Action == "repository-add" { + id, empty := C.CString("tentacleRepositoryURL"), C.CString("") + C.prefs_entry_set(id, empty) + C.free(unsafe.Pointer(id)) + C.free(unsafe.Pointer(empty)) + } + page.controls() +} diff --git a/internal/preferences/tentacles_test.go b/internal/preferences/tentacles_test.go new file mode 100644 index 0000000..909db52 --- /dev/null +++ b/internal/preferences/tentacles_test.go @@ -0,0 +1,40 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package preferences + +import ( + "git.stormux.org/storm/cthulhu/internal/tentacle" + "testing" +) + +func TestTentacleRepositoryViewsAndRemovedSource(t *testing.T) { + first := "https://example.org/team/first" + second := "https://other.example.org/team/second" + snapshot := &tentacle.Snapshot{ + Entries: []tentacle.EntryStatus{{Entry: tentacle.Entry{ID: "installed", LocalID: "echo", Repository: first, RepositoryID: "example.first", Enabled: true}}, {Entry: tentacle.Entry{ID: "local"}}}, + Repositories: []tentacle.Repository{ + {URL: first, ID: "example.first", Tentacles: []tentacle.Manifest{{ID: "echo"}, {ID: "other"}}}, + {URL: second, ID: "example.second", Tentacles: []tentacle.Manifest{{ID: "echo"}}}, + }, + } + all := tentacle_rows(snapshot, "") + if len(all) != 4 || !all[0].installed || !all[0].status.Entry.Enabled || all[2].installed || all[0].key == all[3].key { + t.Fatalf("All view: %+v", all) + } + filtered := tentacle_rows(snapshot, first) + if len(filtered) != 2 || filtered[0].status.Entry.ID != "installed" || filtered[1].status.Entry.ID != "other" { + t.Fatalf("repository view: %+v", filtered) + } + snapshot.Repositories[0].ID = "example.replacement" + if replacement := tentacle_rows(snapshot, first); len(replacement) != 2 || replacement[0].installed { + t.Fatalf("replacement source claimed old installation: %+v", replacement) + } + snapshot.Repositories = snapshot.Repositories[1:] + remaining := tentacle_rows(snapshot, "") + if len(remaining) != 3 || remaining[0].status.Entry.ID != "installed" { + t.Fatalf("removed source lost installed entry: %+v", remaining) + } + if rows := tentacle_rows(nil, ""); len(rows) != 0 { + t.Fatal(rows) + } +} diff --git a/internal/preferences/text_attributes.go b/internal/preferences/text_attributes.go new file mode 100644 index 0000000..124c046 --- /dev/null +++ b/internal/preferences/text_attributes.go @@ -0,0 +1,97 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "errors" + "strings" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/config" +) + +var textAttributeLabels = map[string]string{ + "size": "Font size", "family-name": "Font family", "weight": "Weight", + "indent": "Indent", "underline": "Underline", "strikethrough": "Strikethrough", + "justification": "Justification", "style": "Style", "paragraph-style": "Paragraph style", + "text-spelling": "Spelling", "fg-color": "Foreground color", "bg-color": "Background color", +} + +func setPronunciations(entries []config.PronunciationEntry) { + C.prefs_pronunciation_clear() + for _, entry := range entries { + word, replacement := C.CString(entry.Word), C.CString(entry.Replacement) + C.prefs_pronunciation_append(word, replacement) + C.free(unsafe.Pointer(word)) + C.free(unsafe.Pointer(replacement)) + } +} + +func getPronunciations() ([]config.PronunciationEntry, error) { + var entries []config.PronunciationEntry + for row := 0; row < int(C.prefs_pronunciation_count()); row++ { + word := C.prefs_pronunciation_value(C.int(row), 0) + replacement := C.prefs_pronunciation_value(C.int(row), 1) + entry := config.PronunciationEntry{Word: strings.TrimSpace(C.GoString(word)), Replacement: C.GoString(replacement)} + C.g_free(C.gpointer(word)) + C.g_free(C.gpointer(replacement)) + if entry.Word == "" && entry.Replacement == "" { + continue + } + if entry.Word == "" || entry.Replacement == "" { + return nil, errors.New("each pronunciation entry needs a word and a replacement") + } + entries = append(entries, entry) + } + return entries, nil +} + +func setTextAttributes(settings config.TextAttributeSettings) { + C.prefs_text_attributes_clear() + for _, choice := range settings.Choices { + key, label := C.CString(choice.Key), C.CString(textAttributeLabels[choice.Key]) + C.prefs_text_attribute_append(key, label, boolean(choice.Speak), boolean(choice.Braille)) + C.free(unsafe.Pointer(key)) + C.free(unsafe.Pointer(label)) + } + buttons := []string{"textBrailleNoneButton", "textBraille7Button", "textBraille8Button", "textBrailleBothButton"} + index := 0 + switch settings.Indicator { + case 0x40: + index = 1 + case 0x80: + index = 2 + case 0xc0: + index = 3 + } + setCheck(buttons[index], true) +} + +func getTextAttributes() config.TextAttributeSettings { + settings := config.TextAttributeSettings{} + for row := 0; row < int(C.prefs_text_attribute_count()); row++ { + key := C.prefs_text_attribute_key(C.int(row)) + choice := config.TextAttributeChoice{Key: C.GoString(key), + Speak: C.prefs_text_attribute_enabled(C.int(row), 2) != 0, + Braille: C.prefs_text_attribute_enabled(C.int(row), 3) != 0} + C.g_free(C.gpointer(key)) + settings.Choices = append(settings.Choices, choice) + } + switch { + case getCheck("textBraille7Button"): + settings.Indicator = 0x40 + case getCheck("textBraille8Button"): + settings.Indicator = 0x80 + case getCheck("textBrailleBothButton"): + settings.Indicator = 0xc0 + } + return settings +} diff --git a/internal/preferences/ui.go b/internal/preferences/ui.go new file mode 100644 index 0000000..cd8bf45 --- /dev/null +++ b/internal/preferences/ui.go @@ -0,0 +1,237 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#cgo pkg-config: gtk+-3.0 xkbcommon +#include +#include "native.h" +*/ +import "C" + +import ( + "context" + _ "embed" + "encoding/json" + "errors" + "io" + "runtime" + "time" + "unsafe" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/tentacle" +) + +//go:embed preferences.ui +var layout string + +// Run owns all GTK calls on one OS thread. Its caller supplies private pipes; +// closing the parent pipe closes the window. No widget invokes speech directly. +func Run(ctx context.Context, input io.Reader, output io.Writer) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + updates := make(chan Response, 1) + errorsIn := make(chan error, 1) + go read_responses(ctx, input, updates, errorsIn) + var initial Response + select { + case initial = <-updates: + case err := <-errorsIn: + return err + case <-ctx.Done(): + return ctx.Err() + } + if initial.ChooseApplication { + response, chosen, err := choose_application(ctx, updates, errorsIn, output) + if err != nil || !chosen { + return err + } + initial = response + } + xml := C.CString(layout) + defer C.free(unsafe.Pointer(xml)) + if C.prefs_init(xml) == 0 { + return errors.New("cannot open GTK preferences on this display") + } + defer C.prefs_close() + if initial.Application != "" { + name := C.CString(initial.Application) + C.prefs_set_application(name) + C.free(unsafe.Pointer(name)) + } + session := &uiSession{catalog: initial.Catalog, speechDefaults: initial.SpeechDefaults, soundThemes: []string{"default", "none"}} + session.setValues(initial.Values) + if err := session.set_extension_pages(initial.ExtensionPages); err != nil { + return err + } + tentacles := &tentaclePage{} + tentacles.populate(initial.Tentacles) + var tentaclePending *tentacle.ManagementRequest + C.prefs_voice_changed() + C.prefs_echo_preview(nil) + status(initial.Message, false) + canSave, busy := initial.CanSave, false + previewPending, previewDirty := false, false + C.prefs_busy(0, boolean(canSave)) + encoder := json.NewEncoder(output) + // AT-SPI calls into this GTK process are served by the same event pump. + // Focus snapshots make several synchronous calls, so a 10 ms poll adds + // noticeable delay to every Tab stop in the dialog. + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-errorsIn: + return err + case response := <-updates: + if response.ExtensionsOnly { + if err := session.set_extension_pages(response.ExtensionPages); err != nil { + return err + } + continue + } + if response.Present { + C.prefs_present() + continue + } + if response.Preview { + previewPending = false + if !response.Accepted { + status(response.Message, true) + } + continue + } + if response.Close { + return nil + } + if tentaclePending != nil { + settingsOpened := tentaclePending.Action == "settings" && response.Accepted + // Management commits independently of the ordinary settings draft. + // Its response does not contain Values or CanSave. + if response.Tentacles != nil { + tentacles.populate(response.Tentacles) + if response.Accepted { + tentacles.accepted(tentaclePending) + } + } + tentaclePending, busy = nil, false + C.prefs_busy(0, boolean(canSave)) + if !settingsOpened { + status(response.Message, true) + } + continue + } + busy, canSave = false, response.CanSave + if response.Accepted { + session.setValues(response.Values) + if err := session.set_extension_pages(response.ExtensionPages); err != nil { + return err + } + C.prefs_voice_changed() + C.prefs_echo_preview(nil) + } + C.prefs_busy(0, boolean(canSave)) + status(response.Message, !response.Accepted) + case <-ticker.C: + C.prefs_iterate() + session.refreshEchoVoices() + session.refreshSpeechVoices() + session.refreshKeyBindingLayout() + action := C.prefs_action() + if action >= 9 && action <= 20 && !busy { + request, err := tentacles.action(int(action)) + if err != nil { + status(err.Error(), true) + continue + } + if request != nil { + if err := encoder.Encode(Request{Tentacle: request}); err != nil { + return err + } + tentaclePending, busy = request, true + // Keep the focused Settings button enabled while the internal + // form takes keyboard ownership without moving native focus. + if request.Action != "settings" { + C.prefs_busy(1, boolean(canSave)) + } + if request.Action == "install" || request.Action == "install-enable" { + status("Downloading and checking the tentacle package. Close preferences to cancel before it is saved.", true) + } + } + continue + } + if action == 8 { + setTextAttributes(config.DefaultTextAttributes()) + continue + } + if action >= 4 && action <= 7 { + session.editKeyBinding(int(action)) + continue + } + if action == 3 { + // The parent restores any active preview when this helper exits. + return nil + } + if C.prefs_voice_changed() != 0 { + previewDirty = true + } + if (action == 1 || action == 2) && !busy { + values, err := session.getValues() + if err != nil { + status(err.Error(), true) + continue + } + drafts, err := session.extension_drafts() + if err != nil { + status(err.Error(), true) + continue + } + request := Request{Values: values, ExtensionPages: drafts, Save: canSave, Close: action == 2} + data, err := json.Marshal(request) + if err != nil { + return err + } + if len(data)+1 > initialMessageLimit { + status("Preferences changes exceed the message limit. Shorten the edited values.", true) + continue + } + if err := encoder.Encode(json.RawMessage(data)); err != nil { + return err + } + busy = true + previewDirty = false + C.prefs_busy(1, boolean(canSave)) + continue + } + if previewPending || busy { + continue + } + echoPreview := "" + var echoFocus C.int + if control := int(C.prefs_echo_preview(&echoFocus)); control != 0 { + echoPreview = []string{"rate", "pitch", "volume", "synthesizer", "person"}[control-1] + } + if !previewDirty && echoPreview == "" { + continue + } + values, err := session.getValues() + if err != nil { + status(err.Error(), true) + previewDirty = false + continue + } + if err := encoder.Encode(Request{Values: values, Preview: true, EchoPreview: echoPreview, EchoPreviewFocus: echoFocus != 0}); err != nil { + return err + } + previewPending = true + previewDirty = false + } + } +} diff --git a/internal/preferences/ui_values.go b/internal/preferences/ui_values.go new file mode 100644 index 0000000..2eb3393 --- /dev/null +++ b/internal/preferences/ui_values.go @@ -0,0 +1,47 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +func (session *uiSession) setValues(values Values) { + setPronunciations(values.Pronunciations) + setTextAttributes(values.TextAttributes) + setOCRValues(values.OCR) + session.set_general_values(values) + set_sound_checks(values) + set_speech_support(values) + session.set_braille_values(values) + session.set_sound_values(values) + session.setEchoVoice(values) + session.setSpeechVoice(values) + set_echo_checks(values) + set_speech_presentation(values) +} + +func (session *uiSession) getValues() (Values, error) { + var values Values + var err error + if values.Pronunciations, err = getPronunciations(); err != nil { + return values, err + } + values.TextAttributes = getTextAttributes() + values.OCR = getOCRValues() + if err := session.get_general_values(&values); err != nil { + return values, err + } + get_sound_checks(&values) + get_speech_support(&values) + if err := session.get_braille_values(&values); err != nil { + return values, err + } + if err := session.get_sound_values(&values); err != nil { + return values, err + } + get_echo_checks(&values) + getReading(&values) + if err := session.get_speech_values(&values); err != nil { + return values, err + } + return values, nil +} diff --git a/internal/preferences/values.go b/internal/preferences/values.go new file mode 100644 index 0000000..3f1f8b8 --- /dev/null +++ b/internal/preferences/values.go @@ -0,0 +1,143 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package preferences implements the isolated GTK preferences process and its +// bounded, typed protocol. The UI never opens settings files or speech sockets. +package preferences + +import ( + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/input" +) + +func FromSettings(settings config.Settings) Values { + return Values{OCR: settings.OCR, Pronunciations: append([]config.PronunciationEntry(nil), settings.Pronunciations...), + TextAttributes: config.TextAttributeSettings{Choices: append([]config.TextAttributeChoice(nil), settings.TextAttributes.Choices...), Indicator: settings.TextAttributes.Indicator}, + KeyboardLayout: settings.KeyboardLayout, CthulhuModifierKeys: append([]string(nil), settings.CthulhuModifierKeys...), + KeyBindings: input.CloneBindingOverrides(settings.KeyBindings), TimeFormat: settings.TimeFormat, DateFormat: settings.DateFormat, + EnableSound: settings.EnableSound, EnableBraille: settings.EnableBraille, + EnableSpeech: settings.EnableSpeech, + SpeechHistoryLimit: settings.SpeechHistoryLimit, + SpeechInterruption: input.InterruptionSettings{Mode: settings.SpeechInterruption.Mode, + Keys: append([]string(nil), settings.SpeechInterruption.Keys...)}, + SpeechVerbosityLevel: settings.SpeechVerbosityLevel, + SayAllStyle: settings.SayAllStyle, + EnableContractedBraille: settings.EnableContractedBraille, BrailleContractionTable: settings.BrailleContractionTable, + Braille: settings.Braille, + SoundVolume: settings.SoundVolume, SoundSink: settings.SoundSink, + SoundTheme: settings.SoundTheme, PlaySoundForRole: settings.PlaySoundForRole, + PlaySoundForState: settings.PlaySoundForState, PlaySoundForPositionInSet: settings.PlaySoundForPositionInSet, + SpatializeObjectSounds: settings.SpatializeObjectSounds, + ProgressBar: settings.ProgressBar, + RoleSoundPresentation: settings.RoleSoundPresentation, + Rate: settings.DefaultVoice.Rate, Pitch: settings.DefaultVoice.AveragePitch, + Volume: settings.DefaultVoice.Gain, Punctuation: settings.VerbalizePunctuationStyle, + RaisePitchForCapitals: settings.RaisePitchForCapitals, + BeepForCapitals: settings.BeepForCapitals, + SayCapForCapitals: settings.SayCapForCapitals, + SpeechOutputModule: settings.SpeechOutputModule, + SpeechServerFactory: settings.SpeechServerFactory, + HardwareSpeechDevice: settings.HardwareSpeechDevice, + HardwareSpeechBaudRate: settings.HardwareSpeechBaudRate, + SpeechVoiceFamily: settings.DefaultVoice.Family, + UppercaseVoice: settings.UppercaseVoice, + HyperlinkVoice: settings.HyperlinkVoice, + SystemVoice: settings.SystemVoice, + Reading: settings.Reading, + SpeakDescription: settings.SpeakDescription, + EnableKeyEcho: settings.EnableKeyEcho, + KeyEchoInEditFieldsOnly: settings.KeyEchoInEditFieldsOnly, + EnableAlphabeticKeys: settings.EnableAlphabeticKeys, + EnableNumericKeys: settings.EnableNumericKeys, + EnablePunctuationKeys: settings.EnablePunctuationKeys, + EnableSpace: settings.EnableSpace, + EnableModifierKeys: settings.EnableModifierKeys, + EnableFunctionKeys: settings.EnableFunctionKeys, + EnableActionKeys: settings.EnableActionKeys, + EnableNavigationKeys: settings.EnableNavigationKeys, + EnableDiacriticalKeys: settings.EnableDiacriticalKeys, + EnableEchoByCharacter: settings.EnableEchoByCharacter, + EnableEchoByWord: settings.EnableEchoByWord, + EnableEchoBySentence: settings.EnableEchoBySentence, + UseCustomEchoVoice: settings.UseCustomEchoVoice, + UseCustomEchoSpeechServer: settings.UseCustomEchoSpeechServer, + UseCustomEchoForKey: settings.UseCustomEchoForKey, + UseCustomEchoForCharacter: settings.UseCustomEchoForCharacter, + UseCustomEchoForWord: settings.UseCustomEchoForWord, + UseCustomEchoForSentence: settings.UseCustomEchoForSentence, + EchoVoice: settings.EchoVoice, EchoSpeechServer: settings.EchoSpeechServer, + } +} + +func (values Values) Merge(settings config.Settings) (config.Settings, error) { + settings.Pronunciations = append([]config.PronunciationEntry(nil), values.Pronunciations...) + settings.TextAttributes = config.TextAttributeSettings{Choices: append([]config.TextAttributeChoice(nil), values.TextAttributes.Choices...), Indicator: values.TextAttributes.Indicator} + settings.OCR = values.OCR + settings.KeyboardLayout = values.KeyboardLayout + settings.CthulhuModifierKeys = append([]string(nil), values.CthulhuModifierKeys...) + settings.KeyBindings = input.CloneBindingOverrides(values.KeyBindings) + settings.TimeFormat = values.TimeFormat + settings.DateFormat = values.DateFormat + settings.EnableSound = values.EnableSound + settings.EnableSpeech = values.EnableSpeech + settings.SpeechHistoryLimit = values.SpeechHistoryLimit + settings.SpeechInterruption = input.InterruptionSettings{Mode: values.SpeechInterruption.Mode, + Keys: append([]string(nil), values.SpeechInterruption.Keys...)} + settings.SpeechVerbosityLevel = values.SpeechVerbosityLevel + settings.SayAllStyle = values.SayAllStyle + settings.EnableBraille = values.EnableBraille + settings.EnableContractedBraille = values.EnableContractedBraille + settings.BrailleContractionTable = values.BrailleContractionTable + settings.Braille = values.Braille + settings.SoundVolume = values.SoundVolume + settings.SoundSink = values.SoundSink + settings.SoundTheme = values.SoundTheme + settings.PlaySoundForRole = values.PlaySoundForRole + settings.PlaySoundForState = values.PlaySoundForState + settings.PlaySoundForPositionInSet = values.PlaySoundForPositionInSet + settings.SpatializeObjectSounds = values.SpatializeObjectSounds + settings.ProgressBar = values.ProgressBar + settings.RoleSoundPresentation = values.RoleSoundPresentation + settings.EnableKeyEcho = values.EnableKeyEcho + settings.KeyEchoInEditFieldsOnly = values.KeyEchoInEditFieldsOnly + settings.EnableAlphabeticKeys = values.EnableAlphabeticKeys + settings.EnableNumericKeys = values.EnableNumericKeys + settings.EnablePunctuationKeys = values.EnablePunctuationKeys + settings.EnableSpace = values.EnableSpace + settings.EnableModifierKeys = values.EnableModifierKeys + settings.EnableFunctionKeys = values.EnableFunctionKeys + settings.EnableActionKeys = values.EnableActionKeys + settings.EnableNavigationKeys = values.EnableNavigationKeys + settings.EnableDiacriticalKeys = values.EnableDiacriticalKeys + settings.EnableEchoByCharacter = values.EnableEchoByCharacter + settings.EnableEchoByWord = values.EnableEchoByWord + settings.EnableEchoBySentence = values.EnableEchoBySentence + settings.UseCustomEchoVoice = values.UseCustomEchoVoice + settings.UseCustomEchoSpeechServer = values.UseCustomEchoSpeechServer + settings.UseCustomEchoForKey = values.UseCustomEchoForKey + settings.UseCustomEchoForCharacter = values.UseCustomEchoForCharacter + settings.UseCustomEchoForWord = values.UseCustomEchoForWord + settings.UseCustomEchoForSentence = values.UseCustomEchoForSentence + settings.EchoVoice = values.EchoVoice + settings.EchoSpeechServer = values.EchoSpeechServer + settings.DefaultVoice.Rate = values.Rate + settings.DefaultVoice.AveragePitch = values.Pitch + settings.DefaultVoice.Gain = values.Volume + settings.SpeechOutputModule = values.SpeechOutputModule + settings.SpeechServerFactory = values.SpeechServerFactory + settings.HardwareSpeechDevice = values.HardwareSpeechDevice + settings.HardwareSpeechBaudRate = values.HardwareSpeechBaudRate + settings.DefaultVoice.Family = values.SpeechVoiceFamily + settings.UppercaseVoice = values.UppercaseVoice + settings.HyperlinkVoice = values.HyperlinkVoice + settings.SystemVoice = values.SystemVoice + settings.VerbalizePunctuationStyle = values.Punctuation + settings.CapitalizationStyle = "none" + settings.RaisePitchForCapitals = values.RaisePitchForCapitals + settings.BeepForCapitals = values.BeepForCapitals + settings.SayCapForCapitals = values.SayCapForCapitals + settings.Reading = values.Reading + settings.SpeakDescription = values.SpeakDescription + return settings, config.Validate(settings) +} diff --git a/internal/preferences/widgets.go b/internal/preferences/widgets.go new file mode 100644 index 0000000..5df5a9a --- /dev/null +++ b/internal/preferences/widgets.go @@ -0,0 +1,100 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package preferences + +/* +#include +#include "native.h" +*/ +import "C" + +import ( + "unsafe" +) + +func boolean(value bool) C.int { + if value { + return 1 + } + return 0 +} + +func status(message string, focus bool) { + text := C.CString(message) + defer C.free(unsafe.Pointer(text)) + C.prefs_status(text, boolean(focus)) +} + +func setChoice(name string, value int) { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + C.prefs_choice_set(id, C.int(value)) +} + +func getChoice(name string) int { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + return int(C.prefs_choice_get(id)) +} + +func setCombo(name string, value int) { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + C.prefs_combo_set(id, C.int(value)) +} + +func getCombo(name string) int { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + return int(C.prefs_combo_get(id)) +} + +func setCheck(name string, value bool) { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + C.prefs_check_set(id, boolean(value)) +} + +func getCheck(name string) bool { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + return C.prefs_check_get(id) != 0 +} + +func setRange(name string, value float64) { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + C.prefs_range_set(id, C.double(value)) +} + +func getRange(name string) float64 { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + return float64(C.prefs_number_value(id)) +} + +func setSpin(name string, value float64) { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + C.prefs_spin_set(id, C.double(value)) +} + +func getSpin(name string) float64 { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + return float64(C.prefs_spin_get(id)) +} + +func comboItems(name string, labels []string, selected int) { + id := C.CString(name) + defer C.free(unsafe.Pointer(id)) + C.prefs_combo_clear(id) + for _, label := range labels { + text := C.CString(label) + C.prefs_combo_append(id, text) + C.free(unsafe.Pointer(text)) + } + C.prefs_combo_set(id, C.int(selected)) +} diff --git a/internal/presentation/control_values.go b/internal/presentation/control_values.go new file mode 100644 index 0000000..c2fb542 --- /dev/null +++ b/internal/presentation/control_values.go @@ -0,0 +1,203 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import ( + "fmt" + "math" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// ComboBoxSelectionText presents the current choice without repeating the +// control's label or role. Native combo snapshots prefer selected-child text. +func ComboBoxSelectionText(snapshot atspi.Snapshot) string { + if value := controlValue(snapshot); value != "" { + return value + } + if snapshot.Text != "" { + return snapshot.Text + } + return snapshot.Name +} + +func controlValue(snapshot atspi.Snapshot) string { + switch snapshot.Role { + case "combo box": + if snapshot.ValueText != "" { + return snapshot.ValueText + } + return snapshot.Description + case "spin button": + if snapshot.Text != "" { + return snapshot.Text + } + if snapshot.ValueText != "" { + return snapshot.ValueText + } + if !snapshot.ValueKnown { + return snapshot.Text + } + case "dial", "progress bar", "scroll bar", "slider", "split pane": + default: + return "" + } + if snapshot.ValueText != "" { + return snapshot.ValueText + } + if !snapshot.ValueKnown || math.IsNaN(snapshot.CurrentValue) || math.IsInf(snapshot.CurrentValue, 0) { + return "" + } + if snapshot.Role != "progress bar" { + // Python's textForValue formats the actual value using the provider's + // minimum increment, rather than normalizing controls to percentages. + increment := snapshot.MinimumIncrement + if increment < 0 || math.IsNaN(increment) || math.IsInf(increment, 0) { + return "" + } + places := 0 + if increment > 0 { + places = int(math.Ceil(math.Max(0, -math.Log10(increment)))) + } else if math.Abs(snapshot.CurrentValue) < 1 { + places = 1 + } + return fmt.Sprintf("%.*f", places, snapshot.CurrentValue) + } + if snapshot.MaximumValue == snapshot.MinimumValue { + return "" + } + percentage := math.Round((snapshot.CurrentValue - snapshot.MinimumValue) / + (snapshot.MaximumValue - snapshot.MinimumValue) * 100) + return fmt.Sprintf("%.0f percent", percentage) +} + +func controlStates(snapshot atspi.Snapshot) []string { + var states []string + switch snapshot.ControlRole() { + case "check box", "check menu item": + switch { + case snapshot.Indeterminate: + states = append(states, "partially checked") + case snapshot.Checked: + states = append(states, "checked") + default: + states = append(states, "not checked") + } + case "radio button", "radio menu item": + if snapshot.Checked { + states = append(states, "selected") + } else { + states = append(states, "not selected") + } + case "switch": + if snapshot.Checked { + states = append(states, "on") + } else { + states = append(states, "off") + } + case "toggle button": + if snapshot.Checked { + states = append(states, "pressed") + } else { + states = append(states, "not pressed") + } + } + if snapshot.Expandable { + if snapshot.Expanded { + states = append(states, "expanded") + } else { + states = append(states, "collapsed") + } + } + if snapshot.Selected && presentsSelectedState(snapshot.Role) { + states = append(states, "selected") + } + if snapshot.Multiselectable { + states = append(states, "multi-select") + } + if snapshot.ReadOnly { + states = append(states, "read only") + } + if snapshot.Required { + states = append(states, "required") + } + if snapshot.Invalid { + states = append(states, "invalid entry") + } + if snapshot.SensitiveKnown && !snapshot.Sensitive { + states = append(states, "grayed") + } + return states +} + +func presentsSelectedState(role string) bool { + switch role { + case "icon", "list item", "tree item": + return true + default: + return false + } +} + +func stateChangeText(snapshot atspi.Snapshot, eventType string) string { + switch eventType { + case "object:state-changed:checked", "object:state-changed:indeterminate", "object:state-changed:pressed": + for _, state := range controlStates(snapshot) { + switch state { + case "partially checked", "checked", "not checked", "selected", "not selected", "on", "off", "pressed", "not pressed": + return state + } + } + case "object:state-changed:expanded": + if snapshot.Expanded { + return "expanded" + } + return "collapsed" + case "object:state-changed:invalid-entry": + if snapshot.Invalid { + return "invalid entry" + } + case "object:state-changed:read-only": + if snapshot.ReadOnly { + return "read only" + } + return "editable" + case "object:state-changed:required": + if snapshot.Required { + return "required" + } + case "object:state-changed:selected": + if snapshot.Role == "table cell" { + if snapshot.Selected { + return "selected" + } + return "" + } + if presentsSelectedState(snapshot.Role) { + if snapshot.Selected { + return "selected" + } + return "not selected" + } + case "object:state-changed:sensitive": + if snapshot.SensitiveKnown && !snapshot.Sensitive { + return "grayed" + } + } + return "" +} diff --git a/internal/presentation/control_values_test.go b/internal/presentation/control_values_test.go new file mode 100644 index 0000000..0a219f5 --- /dev/null +++ b/internal/presentation/control_values_test.go @@ -0,0 +1,211 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestFocusTextPresentsControlStates(t *testing.T) { + tests := []struct { + name string + snapshot atspi.Snapshot + want string + }{ + {name: "unchecked checkbox", snapshot: atspi.Snapshot{Name: "Updates", Role: "check box"}, want: "Updates, check box, not checked"}, + {name: "checked checkbox", snapshot: atspi.Snapshot{Name: "Updates", Role: "check box", Checked: true}, want: "Updates, check box, checked"}, + {name: "mixed checkbox", snapshot: atspi.Snapshot{Name: "Updates", Role: "check box", Indeterminate: true}, want: "Updates, check box, partially checked"}, + {name: "selected radio", snapshot: atspi.Snapshot{Name: "Automatic", Role: "radio button", Checked: true}, want: "Automatic, radio button, selected"}, + {name: "radio group", snapshot: atspi.Snapshot{Name: "Some", Role: "radio button", RadioGroupName: "Punctuation Level", Checked: true}, want: "Punctuation Level, Some, radio button, selected"}, + {name: "switch off", snapshot: atspi.Snapshot{Name: "Network", Role: "switch"}, want: "Network, switch, off"}, + {name: "toggle pressed", snapshot: atspi.Snapshot{Name: "Bold", Role: "toggle button", Checked: true}, want: "Bold, toggle button, pressed"}, + {name: "collapsed item", snapshot: atspi.Snapshot{Name: "Documents", Role: "tree item", Expandable: true}, want: "Documents, tree item, collapsed"}, + {name: "expanded selected item", snapshot: atspi.Snapshot{Name: "Documents", Role: "tree item", Expandable: true, Expanded: true, Selected: true}, want: "Documents, tree item, expanded, selected"}, + {name: "selected menu item", snapshot: atspi.Snapshot{Name: "Open", Role: "menu item", Selected: true}, want: "Open, menu item"}, + {name: "unchecked generic menu", snapshot: atspi.Snapshot{Name: "Updates", Role: "menu item", Checkable: true}, want: "Updates, check menu item, not checked"}, + {name: "checked generic menu without marker", snapshot: atspi.Snapshot{Name: "Updates", Role: "menu item", Checked: true}, want: "Updates, check menu item, checked"}, + {name: "mixed generic menu", snapshot: atspi.Snapshot{Name: "Updates", Role: "menu item", Indeterminate: true}, want: "Updates, check menu item, partially checked"}, + {name: "ordinary menu", snapshot: atspi.Snapshot{Name: "Open", Role: "menu item"}, want: "Open, menu item"}, + {name: "selected table cell", snapshot: atspi.Snapshot{Name: "First post", Role: "table cell", Selected: true}, want: "First post"}, + {name: "field requirements", snapshot: atspi.Snapshot{Name: "Account", Role: "text", ReadOnly: true, Required: true, Invalid: true}, want: "Account, text, read only, required, invalid entry"}, + {name: "disabled control", snapshot: atspi.Snapshot{Name: "Apply", Role: "push button", SensitiveKnown: true}, want: "Apply, push button, grayed"}, + {name: "unknown sensitivity", snapshot: atspi.Snapshot{Name: "Apply", Role: "push button"}, want: "Apply, push button"}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := FocusText(test.snapshot); got != test.want { + t.Fatalf("FocusText() = %q, want %q", got, test.want) + } + }) + } +} + +func TestEventTextPresentsOnlyChangedState(t *testing.T) { + tests := []struct { + name string + event atspi.Event + want string + }{ + {name: "checked", event: atspi.NewEvent("object:state-changed:checked", atspi.Snapshot{Name: "Updates", Role: "check box", Checked: true}), want: "checked"}, + {name: "generic menu checked", event: atspi.NewEvent("object:state-changed:checked", atspi.Snapshot{Name: "Updates", Role: "menu item", Checkable: true, Checked: true}), want: "checked"}, + {name: "generic menu unchecked without marker", event: atspi.NewEvent("object:state-changed:checked", atspi.Snapshot{Name: "Updates", Role: "menu item"}), want: "not checked"}, + {name: "expanded", event: atspi.NewEvent("object:state-changed:expanded", atspi.Snapshot{Name: "Files", Role: "tree item", Expanded: true}), want: "expanded"}, + {name: "menu selection omitted", event: atspi.NewEvent("object:state-changed:selected", atspi.Snapshot{Name: "Open", Role: "menu item", Selected: true}), want: ""}, + {name: "tree selection", event: atspi.NewEvent("object:state-changed:selected", atspi.Snapshot{Name: "Files", Role: "tree item", Selected: true}), want: "selected"}, + {name: "table cell selected", event: atspi.NewEvent("object:state-changed:selected", atspi.Snapshot{Name: "First post", Role: "table cell", Selected: true}), want: "selected"}, + {name: "table cell unselected", event: atspi.NewEvent("object:state-changed:selected", atspi.Snapshot{Name: "First post", Role: "table cell"}), want: ""}, + {name: "available omitted", event: atspi.NewEvent("object:state-changed:sensitive", atspi.Snapshot{Name: "Save", Role: "push button", SensitiveKnown: true, Sensitive: true}), want: ""}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := EventText(test.event); got != test.want { + t.Fatalf("EventText() = %q, want %q", got, test.want) + } + }) + } +} + +func TestEventTextPresentsValueWithoutRepeatingControl(t *testing.T) { + snapshot := atspi.Snapshot{Name: "Volume", Role: "slider", ValueKnown: true, + CurrentValue: 42, MinimumValue: 0, MaximumValue: 100} + event := atspi.NewEvent(atspi.ValueChangedEvent, snapshot) + if got := EventText(event); got != "42" { + t.Fatalf("EventText() = %q, want %q", got, "42") + } +} + +func TestFocusTextPresentsControlValues(t *testing.T) { + tests := []struct { + name string + snapshot atspi.Snapshot + want string + }{ + { + name: "application value text", + snapshot: atspi.Snapshot{Name: "Volume", Role: "slider", ValueKnown: true, + CurrentValue: 50, MinimumValue: 0, MaximumValue: 100, ValueText: "medium"}, + want: "Volume, slider, medium", + }, + { + name: "combo selected item", + snapshot: atspi.Snapshot{Name: "Time format", Role: "combo box", ValueText: "24-hour"}, + want: "Time format, combo box, 24-hour", + }, + { + name: "spin button actual value from nonzero range", + snapshot: atspi.Snapshot{Name: "Zoom", Role: "spin button", ValueKnown: true, + CurrentValue: 150, MinimumValue: 100, MaximumValue: 200}, + want: "Zoom, spin button, 150", + }, + { + name: "rounded percentage", + snapshot: atspi.Snapshot{Name: "Download", Role: "progress bar", ValueKnown: true, + CurrentValue: 1, MinimumValue: 0, MaximumValue: 3}, + want: "Download, progress bar, 33 percent", + }, + { + name: "unknown value", + snapshot: atspi.Snapshot{Name: "Volume", Role: "slider", + CurrentValue: 50, MinimumValue: 0, MaximumValue: 100}, + want: "Volume, slider", + }, + { + name: "actual value remains available for a fixed range", + snapshot: atspi.Snapshot{Name: "Volume", Role: "slider", ValueKnown: true, + CurrentValue: 50, MinimumValue: 100, MaximumValue: 100}, + want: "Volume, slider, 50", + }, + { + name: "value excluded from unrelated role", + snapshot: atspi.Snapshot{Name: "Save", Role: "push button", ValueKnown: true, + CurrentValue: 50, MinimumValue: 0, MaximumValue: 100, ValueText: "medium"}, + want: "Save, push button", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := FocusText(test.snapshot); got != test.want { + t.Fatalf("FocusText() = %q, want %q", got, test.want) + } + }) + } +} + +func TestNumericValueUsesProviderPrecision(t *testing.T) { + for _, test := range []struct { + name string + value, increment float64 + want string + }{ + {"integer", 150, 1, "150"}, + {"hundredths", 1.25, 0.01, "1.25"}, + {"quarter step", 1.25, 0.25, "1.2"}, + {"zero increment fractional", 0.5, 0, "0.5"}, + {"negative fractional", -0.5, 0, "-0.5"}, + {"invalid increment", 1, -1, ""}, + } { + t.Run(test.name, func(t *testing.T) { + for _, role := range []string{"slider", "spin button", "dial", "scroll bar", "split pane"} { + snapshot := atspi.Snapshot{Role: role, ValueKnown: true, CurrentValue: test.value, + MinimumIncrement: test.increment, MinimumValue: -100, MaximumValue: 200} + if got := EventText(atspi.NewEvent(atspi.ValueChangedEvent, snapshot)); got != test.want { + t.Fatalf("%s: value = %q, want %q", role, got, test.want) + } + } + }) + } +} + +func TestSliderFocusUsesCurrentValueInsteadOfStaleText(t *testing.T) { + for _, tc := range []struct { + name, text, valueText, description, want string + valueKnown bool + }{ + {"previous value", "4.0", "", "", "4.5", true}, + {"previous tenth", "4.4", "", "", "4.5", true}, + {"same value different formatting", "4.50", "", "", "4.5", true}, + {"provider value text", "4.0", "medium", "", "medium", true}, + {"description", "4.0", "", "Voice pitch", "4.5, Voice pitch", true}, + {"text without value", "4.0", "", "", "4.0", false}, + } { + t.Run(tc.name, func(t *testing.T) { + snapshot := atspi.Snapshot{Name: "Pitch:", Role: "slider", Text: tc.text, + ValueKnown: tc.valueKnown, CurrentValue: 4.5, MinimumIncrement: 0.1, + ValueText: tc.valueText, Description: tc.description} + if got := FocusText(snapshot); got != "Pitch:, slider, "+tc.want { + t.Fatalf("focus speech = %q", got) + } + options := DefaultOptions() + reading := reading_options(options) + reading.OnlySpeakDisplayedText = true + options.Reading = &reading + want := tc.want + if tc.description != "" { + want = "4.5" + } + if got := FocusTextWithOptions(snapshot, options); got != "Pitch: "+want { + t.Fatalf("displayed-only speech = %q", got) + } + }) + } +} diff --git a/internal/presentation/document_line.go b/internal/presentation/document_line.go new file mode 100644 index 0000000..11220a4 --- /dev/null +++ b/internal/presentation/document_line.go @@ -0,0 +1,127 @@ +package presentation + +import ( + "fmt" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +// DocumentLineText mirrors the web script's content presentation: join the +// displayed text for each same-line object and speak common role/state details. +func DocumentLineText(line atspi.DocumentLine) string { + return DocumentLineTextWithOptions(line, DefaultOptions()) +} + +func DocumentLineTextWithOptions(line atspi.DocumentLine, options Options) string { + return DocumentLineSpeechWithOptions(line, options).Text +} + +func DocumentLineSpeechWithOptions(line atspi.DocumentLine, options Options) Speech { + reading := reading_options(options) + var parts []string + seen := make(map[atspi.ObjectID]bool) + type rowKey struct { + bus, path string + row int + } + rows := make(map[rowKey]bool) + for _, content := range line.Contents { + text := strings.TrimSpace(content.Text) + if content.Snapshot.Role == "table cell" && content.Snapshot.TableRowText != "" && FullRowEnabled(content.Snapshot, options) { + key := rowKey{content.Snapshot.BusName, content.Snapshot.TablePath, content.Snapshot.TableRowIndex} + if key.path != "" { + if rows[key] { + continue + } + rows[key] = true + } + text = content.Snapshot.TableRowText + } + if text == "" { + text = strings.TrimSpace(content.Snapshot.Name) + } + appendPart(&parts, text) + if reading.OnlySpeakDisplayedText { + continue + } + id := content.Snapshot.ID() + if seen[id] { + continue + } + _, roleCue := roleSoundCue(content.Snapshot, options) + _, stateCue := stateSoundCue(content.Snapshot, options) + role := lineRole(content.Snapshot) + if options.SpeechVerbosityLevel == 0 && (role == "icon" || role == "canvas") { + role = "" + } + if role != "" && !((roleCue || stateCue) && options.RoleSoundPresentation == "sound_only") { + appendPart(&parts, role) + } + states := controlStates(content.Snapshot) + if stateCue && options.RoleSoundPresentation == "sound_only" { + states = removeReplacedState(states) + } + for _, state := range states { + appendPart(&parts, state) + } + appendPart(&parts, controlValue(content.Snapshot)) + if reading.SpeakMisspelledIndicator && content.Snapshot.Misspelled { + appendPart(&parts, "misspelled") + } + seen[id] = true + } + if len(parts) == 0 { + if !options.SpeakBlankLines { + return Speech{} + } + return Speech{Text: "blank"} + } + return SpeechWithOptions(parts, options) +} + +// A text object can contribute several ranges to a visual line. Present its +// role and state sounds once, in document order. +func DocumentLineSoundCues(line atspi.DocumentLine, options Options) []sound.Cue { + var cues []sound.Cue + seen := make(map[atspi.ObjectID]bool) + for _, content := range line.Contents { + id := content.Snapshot.ID() + if !seen[id] { + cues = append(cues, SoundCues(content.Snapshot, options)...) + seen[id] = true + } + } + return cues +} + +func appendPart(parts *[]string, part string) { + if part == "" { + return + } + *parts = append(*parts, part) +} + +// Keep this deliberately small: line reading presents displayed text plus +// the role/state details Python's web generator keeps for common content. +func lineRole(snapshot atspi.Snapshot) string { + switch snapshot.Role { + case "heading": + if snapshot.HeadingLevel > 0 { + return fmt.Sprintf("heading level %d", snapshot.HeadingLevel) + } + return "heading" + case "link": + if snapshot.Visited { + return "visited link" + } + return "link" + case "footer", "form", "label", "menu item", "paragraph", "section", + "redundant object", "unknown", "table cell", "text", "static", + "content suggestion", "list item", "list", "document frame", + "document web", "alert", "row header", "toggle button": + return "" + } + return snapshot.Role +} diff --git a/internal/presentation/document_line_test.go b/internal/presentation/document_line_test.go new file mode 100644 index 0000000..50f79c2 --- /dev/null +++ b/internal/presentation/document_line_test.go @@ -0,0 +1,88 @@ +package presentation + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestDocumentLineText(t *testing.T) { + line := atspi.DocumentLine{Contents: []atspi.DocumentContent{ + {Snapshot: atspi.Snapshot{BusName: ":1.42", Path: "/text", Role: "static"}, Text: "Read "}, + {Snapshot: atspi.Snapshot{BusName: ":1.42", Path: "/link", Role: "link"}, Text: "the link"}, + {Snapshot: atspi.Snapshot{BusName: ":1.42", Path: "/heading", Role: "heading", HeadingLevel: 2}, Text: ""}, + }} + if got := DocumentLineText(line); got != "Read, the link, link, heading level 2" { + t.Fatalf("DocumentLineText() = %q", got) + } + + line.Contents = line.Contents[:2] + line.Contents[1].Snapshot.Visited = true + if got := DocumentLineText(line); got != "Read, the link, visited link" { + t.Fatalf("visited line = %q", got) + } + + blank := atspi.DocumentLine{Contents: []atspi.DocumentContent{{ + Snapshot: atspi.Snapshot{BusName: ":1.42", Path: "/blank", Role: "static"}, Text: "\n", + }}} + if got := DocumentLineText(blank); got != "blank" { + t.Fatalf("blank line = %q", got) + } + withoutBlank := DefaultOptions() + withoutBlank.SpeakBlankLines = false + if got := DocumentLineTextWithOptions(blank, withoutBlank); got != "" { + t.Fatalf("disabled blank line = %q", got) + } + + listLine := atspi.DocumentLine{Contents: []atspi.DocumentContent{{ + Snapshot: atspi.Snapshot{BusName: ":1.42", Path: "/item", Role: "list item"}, Text: "List text", + }}} + if got := DocumentLineText(listLine); got != "List text" { + t.Fatalf("list item role = %q", got) + } + + controls := atspi.DocumentLine{Contents: []atspi.DocumentContent{ + {Snapshot: atspi.Snapshot{BusName: ":1.42", Path: "/save", Role: "push button"}, Text: "Save"}, + {Snapshot: atspi.Snapshot{BusName: ":1.42", Path: "/updates", Role: "check box", Checked: true}, Text: "Updates"}, + }} + if got := DocumentLineText(controls); got != "Save, push button, Updates, check box, checked" { + t.Fatalf("control line = %q", got) + } + + repeated := atspi.DocumentLine{Contents: []atspi.DocumentContent{ + {Snapshot: atspi.Snapshot{BusName: ":1.1", Path: "/one", Role: "static"}, Text: "the"}, + {Snapshot: atspi.Snapshot{BusName: ":1.1", Path: "/two", Role: "static"}, Text: "the"}, + }} + if got := DocumentLineText(repeated); got != "the, the" { + t.Fatalf("repeated line content = %q", got) + } +} + +func TestDocumentLineSoundPolicy(t *testing.T) { + link := atspi.Snapshot{BusName: ":1.42", Path: "/link", Role: "link", Visited: true} + line := atspi.DocumentLine{Contents: []atspi.DocumentContent{ + {Snapshot: link, Text: "Read"}, {Snapshot: link, Text: "more"}, + {Snapshot: atspi.Snapshot{BusName: ":1.42", Path: "/check", Role: "check box", Checked: true}, Text: "Updates"}, + }} + options := DefaultOptions() + options.EnableSound, options.PlaySoundForRole, options.PlaySoundForState = true, true, true + options.RoleSoundPresentation = "sound_only" + cues := DocumentLineSoundCues(line, options) + if len(cues) != 2 || cues[0].Name != "link_visited" || cues[1].Name != "checkbox_checked" { + t.Fatalf("line cues = %#v", cues) + } + if got := DocumentLineTextWithOptions(line, options); got != "Read, more, Updates" { + t.Fatalf("sound-only text = %q", got) + } + options.PlaySoundForRole = false + if got := DocumentLineSoundCues(line, options); len(got) != 1 || got[0].Name != "checkbox_checked" { + t.Fatalf("state-only cues = %#v", got) + } + options.RoleSoundPresentation = "speech_only" + if got := DocumentLineSoundCues(line, options); len(got) != 0 { + t.Fatalf("speech-only cues = %#v", got) + } + if got := DocumentLineTextWithOptions(line, options); got != "Read, visited link, more, Updates, check box, checked" { + t.Fatalf("speech-only text = %q", got) + } +} diff --git a/internal/presentation/flat_review.go b/internal/presentation/flat_review.go new file mode 100644 index 0000000..91a85cd --- /dev/null +++ b/internal/presentation/flat_review.go @@ -0,0 +1,42 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import "strings" + +// FlatReviewText renders owned review text without altering the offsets in the +// navigation model. Single whitespace characters must be audible. +func FlatReviewText(text string, character bool) string { + if character { + switch text { + case " ": + return "space" + case "\t": + return "tab" + case "\u00a0": + return "no break space" + } + } + if strings.TrimSpace(text) == "" { + if !character && strings.Trim(text, "\r\n") != "" { + return "white space" + } + return "blank" + } + return text +} diff --git a/internal/presentation/flat_review_test.go b/internal/presentation/flat_review_test.go new file mode 100644 index 0000000..4cdf4f3 --- /dev/null +++ b/internal/presentation/flat_review_test.go @@ -0,0 +1,37 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import "testing" + +func TestFlatReviewWhitespaceAndExactText(t *testing.T) { + for _, tc := range []struct { + text string + character bool + want string + }{ + {" ", true, "space"}, {"\t", true, "tab"}, {"\u00a0", true, "no break space"}, + {" ", false, "white space"}, {"\t", false, "white space"}, + {"\n", false, "blank"}, {"\n", true, "blank"}, {"\r\n", false, "blank"}, + {"", true, "blank"}, {"é🙂", false, "é🙂"}, {"!", true, "!"}, + } { + if got := FlatReviewText(tc.text, tc.character); got != tc.want { + t.Fatalf("text=%q got=%q", tc.text, got) + } + } +} diff --git a/internal/presentation/libreoffice.go b/internal/presentation/libreoffice.go new file mode 100644 index 0000000..dcbb68d --- /dev/null +++ b/internal/presentation/libreoffice.go @@ -0,0 +1,78 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package presentation + +import ( + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// Normalize only the presentation copy. Native names remain coordinates for +// ownership and diagnostics. Orca's soffice generator speaks contents first, +// then the coordinate; an empty Text value is a blank cell, not a missing name. +func libreOfficeFocusSnapshot(snapshot atspi.Snapshot, options Options) atspi.Snapshot { + context := snapshot.LibreOffice + if !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) || + context == nil || !context.InSpreadsheet { + return snapshot + } + if snapshot.Role == "table" { + // Orca omits table size for spreadsheets. These dimensions describe + // the sheet capacity, not the populated data. + snapshot.TableRowCount, snapshot.TableColumnCount = 0, 0 + snapshot.Multiselectable, snapshot.SensitiveKnown = false, false + return snapshot + } + if context.CellEditor && snapshot.Role == "paragraph" { + snapshot.Role = "" + snapshot.SensitiveKnown = false + return snapshot + } + if snapshot.Role != "table cell" || !context.Cell { + return snapshot + } + snapshot.Name = strings.TrimSpace(context.CellText) + snapshot.Text = context.Coordinates + // Calc cell formatting in Orca omits container selection capabilities + // and insensitive-state chatter; these bits are not cell availability. + snapshot.Multiselectable = false + snapshot.SensitiveKnown = false + if reading_options(options).OnlySpeakDisplayedText { + snapshot.Text = "" + return snapshot + } + if snapshot.Name == "" { + snapshot.Name = "blank" + } + return snapshot +} + +// LibreOfficeCellFormula limits Office presentation to verified Calc cells. +func LibreOfficeCellFormula(snapshot atspi.Snapshot) string { + context := snapshot.LibreOffice + if !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) || snapshot.Defunct || + snapshot.Role != "table cell" || context == nil || !context.InSpreadsheet || !context.Cell { + return "" + } + return context.Formula +} + +// LibreOfficeFormulaText follows Orca's explicit formula command: non-formula +// cells report their value, including "empty" when there is no value. +func LibreOfficeFormulaText(snapshot atspi.Snapshot) string { + context := snapshot.LibreOffice + if !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) || snapshot.Defunct || + snapshot.Role != "table cell" || context == nil || !context.InSpreadsheet || !context.Cell { + return "Not in a table." + } + if formula := LibreOfficeCellFormula(snapshot); formula != "" { + return formula + } + if strings.TrimSpace(context.CellText) != "" { + return context.CellText + } + return "empty" +} diff --git a/internal/presentation/libreoffice_selection.go b/internal/presentation/libreoffice_selection.go new file mode 100644 index 0000000..22cd71f --- /dev/null +++ b/internal/presentation/libreoffice_selection.go @@ -0,0 +1,102 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package presentation + +import ( + "fmt" + "slices" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func calcColumnLabel(column int) string { + label := "" + for column++; column > 0; column = (column - 1) / 26 { + label = string(rune('A'+(column-1)%26)) + label + } + return label +} + +func calcCellLabel(cell atspi.LibreOfficeCell) string { + return fmt.Sprintf("%s%d", calcColumnLabel(cell.Column), cell.Row+1) +} + +// LibreOfficeSelectionText formats copied metadata only. A large selection's +// endpoints never imply a filled rectangle. Small disjoint selections retain +// their gaps; at most eight rectangles are spoken before using a count. +func LibreOfficeSelectionText(selection atspi.LibreOfficeSelection, action string) string { + if selection.Kind == "all" { + return "All cells " + action + "." + } + if selection.Count == 0 { + return "" + } + if !selection.Complete || len(selection.Cells) > 64 { + return libreOfficeSelectionCount(selection, action) + } + cells := slices.Clone(selection.Cells) + slices.SortFunc(cells, func(a, b atspi.LibreOfficeCell) int { + if a.Row != b.Row { + return a.Row - b.Row + } + return a.Column - b.Column + }) + cells = slices.Compact(cells) + type rectangle struct{ first, last atspi.LibreOfficeCell } + var ranges []rectangle + for index := 0; index < len(cells); { + first, last := cells[index], cells[index] + index++ + for index < len(cells) && (selection.Kind == "rows" && cells[index].Row == last.Row+1 || + selection.Kind != "rows" && cells[index].Row == last.Row && cells[index].Column == last.Column+1) { + last = cells[index] + index++ + } + merged := false + if selection.Kind == "cells" { + for i := range ranges { + previous := &ranges[i] + if previous.first.Column == first.Column && previous.last.Column == last.Column && previous.last.Row+1 == first.Row { + previous.last.Row = last.Row + merged = true + break + } + } + } + if !merged { + ranges = append(ranges, rectangle{first, last}) + } + } + if len(ranges) > 8 { + return libreOfficeSelectionCount(selection, action) + } + var messages []string + for _, span := range ranges { + first, last := calcCellLabel(span.first), calcCellLabel(span.last) + singular, plural := "Cell", "Cells" + if selection.Kind == "rows" { + first, last = fmt.Sprint(span.first.Row+1), fmt.Sprint(span.last.Row+1) + singular, plural = "Row", "Rows" + } else if selection.Kind == "columns" { + first, last = calcColumnLabel(span.first.Column), calcColumnLabel(span.last.Column) + singular, plural = "Column", "Columns" + } + if first == last { + messages = append(messages, fmt.Sprintf("%s %s %s.", singular, first, action)) + } else { + messages = append(messages, fmt.Sprintf("%s %s to %s %s.", plural, first, last, action)) + } + } + return strings.Join(messages, " ") +} + +func libreOfficeSelectionCount(selection atspi.LibreOfficeSelection, action string) string { + prefix := "" + if selection.CountLimited { + prefix = "At least " + } + return fmt.Sprintf("%s%d %s %s.", prefix, selection.Count, selection.Kind, action) +} diff --git a/internal/presentation/libreoffice_selection_test.go b/internal/presentation/libreoffice_selection_test.go new file mode 100644 index 0000000..533d20b --- /dev/null +++ b/internal/presentation/libreoffice_selection_test.go @@ -0,0 +1,45 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package presentation + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestLibreOfficeSelectionPreservesGapsAndBoundsOutput(t *testing.T) { + for _, test := range []struct { + name string + selection atspi.LibreOfficeSelection + want string + }{ + {"rectangle", atspi.LibreOfficeSelection{Kind: "cells", Count: 4, Complete: true, + Cells: []atspi.LibreOfficeCell{{Row: 0, Column: 0}, {Row: 0, Column: 1}, {Row: 1, Column: 0}, {Row: 1, Column: 1}}}, "Cells A1 to B2 selected."}, + {"disjoint", atspi.LibreOfficeSelection{Kind: "cells", Count: 4, Complete: true, + Cells: []atspi.LibreOfficeCell{{Row: 0, Column: 0}, {Row: 0, Column: 1}, {Row: 0, Column: 3}, {Row: 1, Column: 3}}}, "Cells A1 to B1 selected. Cells D1 to D2 selected."}, + {"row gaps", atspi.LibreOfficeSelection{Kind: "rows", Count: 3, Complete: true, + Cells: []atspi.LibreOfficeCell{{Row: 0, Column: 0}, {Row: 1, Column: 0}, {Row: 3, Column: 0}}}, "Rows 1 to 2 selected. Row 4 selected."}, + {"column labels", atspi.LibreOfficeSelection{Kind: "columns", Count: 2, Complete: true, + Cells: []atspi.LibreOfficeCell{{Row: 0, Column: 25}, {Row: 0, Column: 26}}}, "Columns Z to AA selected."}, + {"large", atspi.LibreOfficeSelection{Kind: "cells", Count: 1000000000, + First: atspi.LibreOfficeCell{Row: 0, Column: 0}, Last: atspi.LibreOfficeCell{Row: 999999, Column: 999}}, "1000000000 cells selected."}, + {"capped", atspi.LibreOfficeSelection{Kind: "cells", Count: 2147483647, CountLimited: true}, "At least 2147483647 cells selected."}, + {"all", atspi.LibreOfficeSelection{Kind: "all", Complete: true}, "All cells selected."}, + } { + t.Run(test.name, func(t *testing.T) { + if got := LibreOfficeSelectionText(test.selection, "selected"); got != test.want { + t.Fatalf("got %q, want %q", got, test.want) + } + }) + } + selection := atspi.LibreOfficeSelection{Kind: "cells", Count: 9, Complete: true} + for index := 0; index < 9; index++ { + selection.Cells = append(selection.Cells, atspi.LibreOfficeCell{Row: index, Column: index}) + } + if got := LibreOfficeSelectionText(selection, "unselected"); got != "9 cells unselected." { + t.Fatalf("fragmented selection = %q", got) + } +} diff --git a/internal/presentation/libreoffice_test.go b/internal/presentation/libreoffice_test.go new file mode 100644 index 0000000..56cc7a1 --- /dev/null +++ b/internal/presentation/libreoffice_test.go @@ -0,0 +1,92 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package presentation + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestLibreOfficeCellValueCoordinatesAndDisplayedText(t *testing.T) { + for _, value := range []string{"42", "", "é 猫"} { + snapshot := atspi.Snapshot{Role: "table cell", Name: "B3", Text: value, ApplicationProcess: "soffice.bin", + LibreOffice: &atspi.LibreOfficeContext{InSpreadsheet: true, Cell: true, CellText: value, Coordinates: "B3"}} + want := value + ", B3" + if value == "" { + want = "blank, B3" + } + if got := FocusText(snapshot); got != want { + t.Fatalf("cell %q = %q, want %q", value, got, want) + } + reading := config.DefaultSettings().Reading + reading.OnlySpeakDisplayedText = true + options := DefaultOptions() + options.Reading = &reading + if got := FocusTextWithOptions(snapshot, options); got != value { + t.Fatalf("displayed cell %q = %q", value, got) + } + if snapshot.Name != "B3" || snapshot.Text != value { + t.Fatal("presentation mutated native semantics") + } + } +} + +func TestLibreOfficePresentationRequiresVerifiedCellContext(t *testing.T) { + for _, process := range []string{"", "chromium", "steamwebhelper"} { + snapshot := atspi.Snapshot{Role: "table cell", Name: "B3", Text: "42", ApplicationProcess: process, + LibreOffice: &atspi.LibreOfficeContext{InSpreadsheet: true, Cell: true, CellText: "wrong", Coordinates: "wrong"}} + if got := FocusText(snapshot); got != "B3, 42" { + t.Fatalf("other process %q got LibreOffice policy: %q", process, got) + } + } +} + +func TestLibreOfficeFormulaPresentation(t *testing.T) { + for _, value := range []string{"43", ""} { + snapshot := atspi.Snapshot{Role: "table cell", ApplicationProcess: "soffice.bin", + LibreOffice: &atspi.LibreOfficeContext{InSpreadsheet: true, Cell: true, + Coordinates: "C1", CellText: value, Formula: "=B1+1"}} + want := value + ", C1, has formula" + if value == "" { + want = "blank, C1, has formula" + } + if got := FocusText(snapshot); got != want { + t.Fatalf("formula cell = %q, want %q", got, want) + } + if got := LibreOfficeFormulaText(snapshot); got != "=B1+1" { + t.Fatalf("formula command = %q", got) + } + options := DefaultOptions() + reading := config.DefaultSettings().Reading + reading.OnlySpeakDisplayedText = true + options.Reading = &reading + if got := FocusTextWithOptions(snapshot, options); got != value { + t.Fatalf("displayed text includes formula metadata: %q", got) + } + snapshot.LibreOffice.Formula = "" + want = value + if value == "" { + want = "empty" + } + if got := LibreOfficeFormulaText(snapshot); got != want { + t.Fatalf("non-formula command = %q, want %q", got, want) + } + } + for _, snapshot := range []atspi.Snapshot{ + {}, + {Role: "paragraph", ApplicationProcess: "soffice.bin"}, + {Role: "table cell", ApplicationProcess: "chromium", LibreOffice: &atspi.LibreOfficeContext{InSpreadsheet: true, Cell: true, Formula: "wrong"}}, + {Role: "table cell", Defunct: true, ApplicationProcess: "soffice.bin", LibreOffice: &atspi.LibreOfficeContext{InSpreadsheet: true, Cell: true, Formula: "wrong"}}, + } { + if got := LibreOfficeFormulaText(snapshot); got != "Not in a table." { + t.Fatalf("unverified cell = %q", got) + } + if got := LibreOfficeCellFormula(snapshot); got != "" { + t.Fatalf("unverified formula = %q", got) + } + } +} diff --git a/internal/presentation/position_sound_test.go b/internal/presentation/position_sound_test.go new file mode 100644 index 0000000..9d58ae7 --- /dev/null +++ b/internal/presentation/position_sound_test.go @@ -0,0 +1,80 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package presentation + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +func TestPositionSoundPolicy(t *testing.T) { + base := Options{EnableSound: true, PlaySoundForPositionInSet: true, RoleSoundPresentation: "sound_and_speech"} + for _, test := range []struct { + name string + position, size int + want string + }{ + {"first", 1, 3, sound.PositionCueName(0)}, + {"middle", 2, 3, sound.PositionCueName(0.5)}, + {"last", 3, 3, sound.PositionCueName(1)}, + {"virtual set", 501, 1001, sound.PositionCueName(0.5)}, + {"unknown", 0, 0, ""}, {"negative", -1, 3, ""}, + {"outside set", 4, 3, ""}, {"unknown size", 1, -1, ""}, + {"single item", 1, 1, ""}, + } { + t.Run(test.name, func(t *testing.T) { + snapshot := atspi.Snapshot{Name: "Example", Role: "list item", PositionInSet: test.position, SetSize: test.size} + cues := SoundCues(snapshot, base) + if test.want == "" { + if len(cues) != 0 { + t.Fatalf("invalid set produced cues: %v", cues) + } + } else if len(cues) != 1 || cues[0].Name != test.want { + t.Fatalf("position cues = %v, want %s", cues, test.want) + } + if got := FocusTextWithOptions(snapshot, base); got != "Example, list item" { + t.Fatalf("position cue changed speech: %q", got) + } + }) + } + snapshot := atspi.Snapshot{Role: "radio button", Checked: true, PositionInSet: 2, SetSize: 3} + for _, gate := range []string{"disabled sounds", "disabled position", "speech only", "unavailable", "defunct"} { + options, source := base, snapshot + switch gate { + case "disabled sounds": + options.EnableSound = false + case "disabled position": + options.PlaySoundForPositionInSet = false + case "speech only": + options.RoleSoundPresentation = "speech_only" + case "unavailable": + options.SoundCueAvailable = func(string) bool { return false } + case "defunct": + source.Defunct = true + } + if got := SoundCues(source, options); len(got) != 0 { + t.Errorf("%s cues: %v", gate, got) + } + } + base.PlaySoundForState = true + base.RoleSoundPresentation = "sound_only" + if got := SoundCues(snapshot, base); len(got) != 2 || got[0].Name != "radiobutton_checked" || got[1].Name != sound.PositionCueName(0.5) { + t.Fatalf("state/position order = %v", got) + } + if got := EventSoundCues(atspi.NewEvent("object:state-changed:checked", snapshot), base); len(got) != 1 || got[0].Name != "radiobutton_checked" { + t.Fatalf("state change replayed position: %v", got) + } + for _, eventType := range []string{atspi.FocusEvent, atspi.FocusedStateEvent, atspi.ActiveDescendantEvent, atspi.SelectionChangedEvent} { + if got := EventSoundCues(atspi.NewEvent(eventType, snapshot), base); len(got) != 2 { + t.Errorf("%s cues: %v", eventType, got) + } + } + line := atspi.DocumentLine{Contents: []atspi.DocumentContent{{Snapshot: snapshot}, {Snapshot: snapshot}}} + if got := DocumentLineSoundCues(line, base); len(got) != 2 { + t.Fatalf("line replayed position: %v", got) + } +} diff --git a/internal/presentation/presentation.go b/internal/presentation/presentation.go new file mode 100644 index 0000000..1a27e84 --- /dev/null +++ b/internal/presentation/presentation.go @@ -0,0 +1,318 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import ( + "fmt" + "strings" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" +) + +type Options struct { + Reading *config.ReadingSettings + EnableSound bool + PlaySoundForRole bool + PlaySoundForState bool + RoleSoundPresentation string + SpatializeObjectSounds bool + SoundCueAvailable func(string) bool + SpeakDescription bool + ReadFullRowInGUITable bool + SpeechVerbosityLevel int + SpeakBlankLines bool + SayAllStyle string + EnableKeyEcho bool + KeyEchoInEditFieldsOnly bool + EnableEchoByCharacter bool + EnableEchoByWord bool + EnableEchoBySentence bool + EnableAlphabeticKeys bool + EnableNumericKeys bool + EnablePunctuationKeys bool + EnableSpace bool + EnableDiacriticalKeys bool + + PlaySoundForPositionInSet bool +} + +func DefaultOptions() Options { + return Options{ + SpeakDescription: true, + ReadFullRowInGUITable: true, + SpeechVerbosityLevel: 1, + SpeakBlankLines: true, + SayAllStyle: "line", + EnableKeyEcho: true, + EnableAlphabeticKeys: true, + EnableNumericKeys: true, + EnablePunctuationKeys: true, + EnableSpace: true, + } +} + +func FocusText(snapshot atspi.Snapshot) string { + return FocusTextWithOptions(snapshot, DefaultOptions()) +} + +func FocusTextWithOptions(snapshot atspi.Snapshot, options Options) string { + return FocusSpeechWithOptions(snapshot, options).Text +} + +func FocusSpeechWithOptions(snapshot atspi.Snapshot, options Options) Speech { + snapshot = libreOfficeFocusSnapshot(snapshot, options) + // GTK sliders can expose the previous displayed number through Text + // while Value already contains the current number. Present Value once. + if snapshot.Role == "slider" && controlValue(snapshot) != "" { + snapshot.Text = "" + } + reading := reading_options(options) + var parts []string + role := snapshot.ControlRole() + if role == "entry" && snapshot.Autocomplete { + role = "autocomplete" + } + if role == "heading" && snapshot.HeadingLevel > 0 { + role = fmt.Sprintf("heading level %d", snapshot.HeadingLevel) + } + if role == "link" && snapshot.Visited { + role = "visited link" + } + if role == "table cell" { + role = "" + if FullRowEnabled(snapshot, options) && snapshot.TableRowText != "" { + if snapshot.Text == snapshot.Name { + snapshot.Text = "" + } + snapshot.Name = snapshot.TableRowText + } + } + if reading.OnlySpeakDisplayedText { + return SpeechWithOptions([]string{displayed_focus_text(snapshot)}, options) + } + if role == "table" && snapshot.TableRowCount > 0 && snapshot.TableColumnCount > 0 { + if options.SpeechVerbosityLevel == 0 { + role = "table" + } else { + rowWord, columnWord := "rows", "columns" + if snapshot.TableRowCount == 1 { + rowWord = "row" + } + if snapshot.TableColumnCount == 1 { + columnWord = "column" + } + role = fmt.Sprintf("table with %d %s %d %s", snapshot.TableRowCount, rowWord, + snapshot.TableColumnCount, columnWord) + } + } + if options.SpeechVerbosityLevel == 0 && (role == "icon" || role == "canvas") { + role = "" + } + _, replaceRole := roleSoundCue(snapshot, options) + if options.RoleSoundPresentation == "sound_only" && replaceRole { + role = "" + } + if options.SpeechVerbosityLevel != 0 && snapshot.ChildCountKnown && snapshot.ChildCount > 0 { + switch snapshot.Role { + case "list", "list box": + role = itemCountText(snapshot.ChildCount) + } + } + fields := []string{} + if snapshot.Role == "radio button" && snapshot.RadioGroupName != snapshot.Name { + fields = append(fields, snapshot.RadioGroupName) + } + if snapshot.Role == "table cell" { + fields = append(fields, + TableHeaderText(snapshot.TableRowHeaders, "row header", options.SpeechVerbosityLevel), + TableHeaderText(snapshot.TableColumnHeaders, "column header", options.SpeechVerbosityLevel)) + } + fields = append(fields, snapshot.Name, role) + states := controlStates(snapshot) + _, replaceState := stateSoundCue(snapshot, options) + if options.RoleSoundPresentation == "sound_only" && replaceState { + states = removeReplacedState(states) + } + fields = append(fields, states...) + fields = append(fields, controlValue(snapshot)) + if options.SpeakDescription { + fields = append(fields, snapshot.Description) + } + if snapshot.Role != "spin button" { + fields = append(fields, snapshot.Text) + } + if snapshot.Autocomplete && snapshot.SelectionEnd > snapshot.SelectionStart { + fields = append(fields, "selected") + } + if reading.EnablePositionSpeaking && snapshot.PositionInSet > 0 && snapshot.SetSize >= snapshot.PositionInSet { + fields = append(fields, fmt.Sprintf("%d of %d", snapshot.PositionInSet, snapshot.SetSize)) + } + if reading.EnableMnemonicSpeaking && snapshot.Mnemonic != "" { + fields = append(fields, spokenMnemonic(snapshot.Mnemonic)) + } + if reading.EnableTutorialMessages { + fields = append(fields, control_tutorial(snapshot)) + } + if reading.SpeakMisspelledIndicator && snapshot.Misspelled { + fields = append(fields, "misspelled") + } + if LibreOfficeCellFormula(snapshot) != "" { + fields = append(fields, "has formula") + } + for _, part := range fields { + if part != "" && !contains(parts, part) { + parts = append(parts, part) + } + } + return SpeechWithOptions(parts, options) +} + +func spokenMnemonic(value string) string { + value = strings.ReplaceAll(value, "<", "") + value = strings.ReplaceAll(value, ">", " ") + return strings.Join(strings.Fields(value), " ") +} + +func removeReplacedState(states []string) []string { + for index, state := range states { + switch state { + case "partially checked", "checked", "not checked", "selected", "not selected", "on", "off", "pressed", "not pressed": + return append(states[:index:index], states[index+1:]...) + } + } + return states +} + +func contains(values []string, candidate string) bool { + for _, value := range values { + if value == candidate { + return true + } + } + return false +} + +func EventText(event atspi.Event) string { + return EventTextWithOptions(event, DefaultOptions()) +} + +func EventTextWithOptions(event atspi.Event, options Options) string { + return EventSpeechWithOptions(event, options).Text +} + +func EventSpeechWithOptions(event atspi.Event, options Options) Speech { + switch event.Type { + case atspi.WindowActivatedEvent: + speech := FocusSpeechWithOptions(event.Source, options) + focus := speech.Text + if event.Source.Role == "table cell" && event.Source.TableName != "" { + table := atspi.Snapshot{Role: "table", TableRowCount: event.Source.TableRowCount, + TableColumnCount: event.Source.TableColumnCount, ApplicationProcess: event.Source.ApplicationProcess, + LibreOffice: event.Source.LibreOffice} + speech = speech.Prepend(FocusTextWithOptions(table, options), ", ") + speech = speech.Prepend(event.Source.TableName, ", ") + focus = speech.Text + } + title := strings.TrimSpace(event.WindowTitle) + if options.SpeakDescription && event.WindowDescription != "" && event.WindowDescription != event.Source.Description { + speech = speech.Append(event.WindowDescription, ", ") + focus = speech.Text + } + if title == "" || title == event.Source.Name { + return speech.WithText(focus) + } + if focus == "" { + return Speech{Text: title} + } + return speech.Prepend(title, ", ") + case atspi.DocumentLoadCompleteEvent: + if atspi.IsWebDocumentRole(event.Source.Role) { + return Speech{Text: strings.TrimSpace(event.Source.Name)} + } + return Speech{} + case atspi.CaretEvent: + if event.Source.CaretCharacter != "" { + return Speech{Text: caretCharacterText(event.Source.CaretCharacter)} + } + if event.Source.Text != "" { + return Speech{Text: event.Source.Text} + } + case atspi.TextInsertedEvent: + if !shouldEchoInsertion(event.Payload, insertionEchoOptions(event, options)) { + return Speech{} + } + if event.Payload == " " { + return Speech{Text: "space"} + } + return Speech{Text: event.Payload} + case atspi.TextDeletedEvent: + if utf8.RuneCountInString(event.Payload) == 1 && unicode.IsSpace(firstRune(event.Payload)) { + return Speech{Text: caretCharacterText(event.Payload)} + } + return Speech{Text: event.Payload} + case atspi.ValueChangedEvent, atspi.AccessibleValueEvent: + return Speech{Text: controlValue(event.Source)} + case "object:state-changed:checked", + "object:state-changed:expanded", + "object:state-changed:indeterminate", + "object:state-changed:invalid-entry", + "object:state-changed:pressed", + "object:state-changed:read-only", + "object:state-changed:required", + "object:state-changed:selected", + "object:state-changed:sensitive": + if reading_options(options).OnlySpeakDisplayedText { + return Speech{} + } + text := stateChangeText(event.Source, event.Type) + if options.RoleSoundPresentation == "sound_only" && isReplaceableStateEvent(event.Type) { + if _, replaced := stateSoundCue(event.Source, options); replaced { + return Speech{} + } + } + return Speech{Text: text} + } + return FocusSpeechWithOptions(event.Source, options) +} + +func isReplaceableStateEvent(eventType string) bool { + switch eventType { + case "object:state-changed:checked", "object:state-changed:indeterminate", "object:state-changed:pressed": + return true + default: + return false + } +} + +func caretCharacterText(character string) string { + switch character { + case " ": + return "space" + case "\t": + return "tab" + case "\u00a0": + return "no break space" + } + if unicode.IsSpace(firstRune(character)) { + return "blank" + } + return character +} diff --git a/internal/presentation/presentation_test.go b/internal/presentation/presentation_test.go new file mode 100644 index 0000000..2a18429 --- /dev/null +++ b/internal/presentation/presentation_test.go @@ -0,0 +1,294 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import ( + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestBriefSpeechReducesOptionalRoleDetail(t *testing.T) { + options := DefaultOptions() + table := atspi.Snapshot{Role: "table", TableRowCount: 2, TableColumnCount: 3} + if got := FocusTextWithOptions(table, options); got != "table with 2 rows 3 columns" { + t.Fatalf("verbose table = %q", got) + } + options.SpeechVerbosityLevel = 0 + if got := FocusTextWithOptions(table, options); got != "table" { + t.Fatalf("brief table = %q", got) + } + icon := atspi.Snapshot{Name: "Weather", Role: "icon"} + if got := FocusTextWithOptions(icon, options); got != "Weather" { + t.Fatalf("brief icon = %q", got) + } + list := atspi.Snapshot{Name: "Tasks", Role: "list", ChildCount: 3, ChildCountKnown: true} + if got := FocusTextWithOptions(list, options); got != "Tasks, list" { + t.Fatalf("brief list = %q", got) + } + options.SpeechVerbosityLevel = 1 + if got := FocusTextWithOptions(list, options); got != "Tasks, 3 items" { + t.Fatalf("verbose list = %q", got) + } + list.ChildCount = 1 + if got := FocusTextWithOptions(list, options); got != "Tasks, 1 item" { + t.Fatalf("singular list = %q", got) + } + list.ChildCountKnown = false + if got := FocusTextWithOptions(list, options); got != "Tasks, list" { + t.Fatalf("unknown list count = %q", got) + } + cell := atspi.Snapshot{Name: "42", Role: "table cell", TableRowHeaders: "Monday", TableColumnHeaders: "Total"} + if got := FocusTextWithOptions(cell, options); got != "Monday row header, Total column header, 42" { + t.Fatalf("verbose cell headers = %q", got) + } + options.SpeechVerbosityLevel = 0 + if got := FocusTextWithOptions(cell, options); got != "Monday, Total, 42" { + t.Fatalf("brief cell headers = %q", got) + } +} + +func TestFocusText(t *testing.T) { + tests := []struct { + name string + snapshot atspi.Snapshot + want string + }{ + {name: "all fields", snapshot: atspi.Snapshot{Name: "Save", Role: "push button"}, want: "Save, push button"}, + {name: "role only", snapshot: atspi.Snapshot{Role: "text frame"}, want: "text frame"}, + {name: "empty", snapshot: atspi.Snapshot{}, want: ""}, + {name: "description", snapshot: atspi.Snapshot{Name: "Example", Role: "dialog", Description: "Generic description"}, want: "Example, dialog, Generic description"}, + {name: "text", snapshot: atspi.Snapshot{Role: "terminal", Text: "Current terminal line"}, want: "terminal, Current terminal line"}, + {name: "selected autocomplete", snapshot: atspi.Snapshot{Name: "Address and search bar", Role: "entry", Autocomplete: true, Text: "https://example.test", SelectionEnd: 20}, want: "Address and search bar, autocomplete, https://example.test, selected"}, + {name: "table cell omits redundant role", snapshot: atspi.Snapshot{Name: "Budget", Role: "table cell"}, want: "Budget"}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := FocusText(test.snapshot); got != test.want { + t.Fatalf("FocusText() = %q, want %q", got, test.want) + } + }) + } +} + +func TestFocusTextCanOmitDescription(t *testing.T) { + snapshot := atspi.Snapshot{Name: "Example", Role: "dialog", Description: "Generic description"} + options := Options{SpeakDescription: false} + if got := FocusTextWithOptions(snapshot, options); got != "Example, dialog" { + t.Fatalf("FocusTextWithOptions() = %q, want %q", got, "Example, dialog") + } + combo := atspi.Snapshot{Name: "Time format", Role: "combo box", ValueText: "24-hour"} + if got := FocusTextWithOptions(combo, options); got != "Time format, combo box, 24-hour" { + t.Fatalf("FocusTextWithOptions() combo = %q", got) + } + comboFromDescription := atspi.Snapshot{Name: "Time format", Role: "combo box", Description: "24-hour"} + if got := FocusTextWithOptions(comboFromDescription, options); got != "Time format, combo box, 24-hour" { + t.Fatalf("FocusTextWithOptions() combo description = %q", got) + } + spinFromText := atspi.Snapshot{Name: "Progress bar update frequency in seconds", Role: "spin button", Text: "10"} + if got := FocusTextWithOptions(spinFromText, options); got != "Progress bar update frequency in seconds, spin button, 10" { + t.Fatalf("FocusTextWithOptions() spin text = %q", got) + } + spinValueText := atspi.Snapshot{Name: "Zoom", Role: "spin button", Text: "150", ValueText: "150 percent"} + if got := FocusTextWithOptions(spinValueText, options); got != "Zoom, spin button, 150" { + t.Fatalf("FocusTextWithOptions() spin value text = %q", got) + } +} + +func TestEventTextUsesCaretLine(t *testing.T) { + snapshot := atspi.NewSnapshotWithCaretCharacter( + "/accessible/terminal", "", "terminal", "", "Current terminal line", "", + ) + focus := atspi.NewEvent(atspi.CaretEvent, snapshot) + if got := EventText(focus); got != "Current terminal line" { + t.Fatalf("EventText() = %q, want caret line", got) + } +} + +func TestEventTextPrefersCaretCharacter(t *testing.T) { + snapshot := atspi.NewSnapshotWithCaretCharacter( + "/accessible/terminal", "", "terminal", "", "prompt ls", "l", + ) + event := atspi.NewEvent(atspi.CaretEvent, snapshot) + if got := EventText(event); got != "l" { + t.Fatalf("EventText() = %q, want %q", got, "l") + } +} + +func TestEventTextNamesWhitespaceCaretCharacters(t *testing.T) { + tests := []struct { + character string + want string + }{ + {character: " ", want: "space"}, + {character: "\t", want: "tab"}, + {character: "\u00a0", want: "no break space"}, + {character: "\u2003", want: "blank"}, + } + for _, test := range tests { + snapshot := atspi.NewSnapshotWithCaretCharacter( + "/accessible/terminal", "", "terminal", "", "prompt", test.character, + ) + event := atspi.NewEvent(atspi.CaretEvent, snapshot) + if got := EventText(event); got != test.want { + t.Fatalf("EventText(%q) = %q, want %q", test.character, got, test.want) + } + } +} + +func TestEventTextUsesChangedText(t *testing.T) { + tests := []struct { + name string + event atspi.Event + want string + fallback string + }{ + { + name: "insert", + event: atspi.NewEventWithPayload( + atspi.TextInsertedEvent, + atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "prompt l"), + "l", + ), + want: "l", + }, + { + name: "delete", + event: atspi.NewEventWithPayload( + atspi.TextDeletedEvent, + atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "prompt"), + "s", + ), + want: "s", + }, + { + name: "delete space", + event: atspi.NewEventWithPayload( + atspi.TextDeletedEvent, + atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "prompt"), + " ", + ), + want: "space", + }, + { + name: "empty insert payload", + event: atspi.NewEventWithPayload( + atspi.TextInsertedEvent, + atspi.NewSnapshot("/accessible/terminal", "", "terminal", "", "prompt"), + "", + ), + want: "", + fallback: "terminal, prompt", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := EventText(test.event); got != test.want { + t.Fatalf("EventText() = %q, want %q", got, test.want) + } + if test.fallback == "" { + return + } + if got := FocusText(test.event.Source); got != test.fallback { + t.Fatalf("FocusText() = %q, want %q", got, test.fallback) + } + }) + } +} + +func TestWebSemantics(t *testing.T) { + cases := []struct { + snapshot atspi.Snapshot + want string + }{ + {atspi.Snapshot{Name: "Section", Role: "heading", HeadingLevel: 2}, "Section, heading level 2"}, + {atspi.Snapshot{Name: "Section", Role: "heading"}, "Section, heading"}, + {atspi.Snapshot{Name: "Section", Role: "heading", HeadingLevel: -1}, "Section, heading"}, + {atspi.Snapshot{Name: "Custom", Role: "heading", HeadingLevel: 9}, "Custom, heading level 9"}, + {atspi.Snapshot{Name: "Example", Role: "link", Visited: true}, "Example, visited link"}, + {atspi.Snapshot{Name: "Example", Role: "link"}, "Example, link"}, + {atspi.Snapshot{Name: "Save", Role: "button", HeadingLevel: 2, Visited: true}, "Save, button"}, + } + for _, c := range cases { + if got := FocusText(c.snapshot); got != c.want { + t.Errorf("got %q; want %q", got, c.want) + } + if got := EventText(atspi.NewEvent("object:state-changed:focused", c.snapshot)); got != c.want { + t.Errorf("event got %q; want %q", got, c.want) + } + } +} + +func TestWindowActivationIncludesTopLevelTitle(t *testing.T) { + tests := []struct { + title, source, role, want string + }{ + {"Editor - Notes", "Save", "button", "Editor - Notes, Save, button"}, + {"Page title", "Page title", "document web", "Page title, document web"}, + {"", "Save", "button", "Save, button"}, + } + for _, test := range tests { + event := atspi.NewEvent(atspi.WindowActivatedEvent, atspi.Snapshot{Name: test.source, Role: test.role}) + event.WindowTitle = test.title + if got := EventText(event); got != test.want { + t.Errorf("title %q: got %q, want %q", test.title, got, test.want) + } + } +} + +func TestGUITablePresentation(t *testing.T) { + table := atspi.Snapshot{Name: "Desktop items", Role: "table", TableRowCount: 11, TableColumnCount: 2} + if got := FocusText(table); got != "Desktop items, table with 11 rows 2 columns" { + t.Fatalf("table focus = %q", got) + } + cell := atspi.Snapshot{Name: "Steam", Text: "Steam", Role: "table cell", TableName: "Desktop items", + TableRowCount: 11, TableColumnCount: 2, TableRowText: "Steam, Shortcut", GUITable: true} + if got := EventText(atspi.NewEvent(atspi.SelectionChangedEvent, cell)); got != "Steam, Shortcut" { + t.Fatalf("selected row = %q", got) + } + if got := EventTextWithOptions(atspi.NewEvent(atspi.SelectionChangedEvent, cell), + Options{ReadFullRowInGUITable: false}); got != "Steam" { + t.Fatalf("single cell setting = %q", got) + } + activation := atspi.NewEvent(atspi.WindowActivatedEvent, cell) + activation.WindowTitle = "I38 Desktop" + activation.WindowDescription = "Select a desktop item and press Enter to open it." + if got := EventText(activation); got != "I38 Desktop, Desktop items, table with 11 rows 2 columns, Steam, Shortcut, Select a desktop item and press Enter to open it." { + t.Fatalf("window activation = %q", got) + } + if got := EventTextWithOptions(activation, Options{SpeakDescription: false}); strings.Contains(got, "Select a desktop item") { + t.Fatalf("disabled description = %q", got) + } +} + +func TestDocumentLoadAnnouncesOnlyTitle(t *testing.T) { + for _, tc := range []struct{ role, name, want string }{ + {"document web", "Page title", "Page title"}, + {"document frame", "Page title", "Page title"}, + {"document web", "", ""}, + {"entry", "Address bar", ""}, + } { + snapshot := atspi.NewSnapshot("/doc", tc.name, tc.role, "Description", "Page contents") + if got := EventText(atspi.NewEvent(atspi.DocumentLoadCompleteEvent, snapshot)); got != tc.want { + t.Fatalf("%s: got %q, want %q", tc.role, got, tc.want) + } + } +} diff --git a/internal/presentation/reading.go b/internal/presentation/reading.go new file mode 100644 index 0000000..cfc9f14 --- /dev/null +++ b/internal/presentation/reading.go @@ -0,0 +1,191 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package presentation + +import ( + "fmt" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" +) + +func reading_options(options Options) config.ReadingSettings { + if options.Reading != nil { + return *options.Reading + } + return config.DefaultSettings().Reading +} +func join_speech_parts(parts []string, options Options) string { + if !reading_options(options).EnablePauseBreaks { + return strings.Join(parts, " ") + } + return strings.Join(parts, ", ") +} +func displayed_focus_text(snapshot atspi.Snapshot) string { + var parts []string + for _, text := range []string{snapshot.Name, snapshot.Text, controlValue(snapshot)} { + if text != "" && !contains(parts, text) { + parts = append(parts, text) + } + } + return strings.Join(parts, " ") +} +func control_tutorial(snapshot atspi.Snapshot) string { + switch snapshot.Role { + case "push button", "button": + return "Press Space to activate." + case "check box", "toggle button": + return "Press Space to toggle." + case "radio button": + return "Use arrow keys to select an option." + case "combo box": + return "Press Alt+Down to open the list." + case "slider", "spin button": + return "Use arrow keys to change the value." + case "entry", "text": + if snapshot.Editable && !snapshot.ReadOnly { + return "Type to enter text." + } + case "list", "list box", "tree", "tree table": + return "Use arrow keys to move between items." + } + return "" +} + +func FullRowEnabled(snapshot atspi.Snapshot, options Options) bool { + reading := reading_options(options) + if snapshot.Spreadsheet { + return reading.ReadFullRowInSpreadSheet + } + if snapshot.GUITable { + return options.ReadFullRowInGUITable + } + return reading.ReadFullRowInDocumentTable +} + +// ContextType matches Python's separate container and landmark preferences. +func ContextType(snapshot atspi.Snapshot) string { + switch snapshot.Role { + case "block quote", "blockquote": + return "blockquote" + case "list", "list box": + return "list" + case "table", "tree table": + if !snapshot.LayoutTable { + return "table" + } + case "panel", "grouping": + return "panel" + case "landmark": + return "landmark" + case "form": + if snapshot.Name == "" { + return "form" + } + return "landmark" + } + for _, role := range strings.Fields(snapshot.XMLRoles) { + switch role { + case "banner", "complementary", "contentinfo", "main", "navigation", "search", "region": + return "landmark" + case "form": + if snapshot.Name != "" { + return "landmark" + } + return "form" + } + } + if strings.EqualFold(snapshot.HTMLTag, "blockquote") { + return "blockquote" + } + return "" +} + +func ContextEnabled(kind string, reading config.ReadingSettings) bool { + if reading.OnlySpeakDisplayedText { + return false + } + switch kind { + case "blockquote": + return reading.SpeakContextBlockquote + case "list": + return reading.SpeakContextList + case "table": + return reading.SpeakContextTable + case "panel": + return reading.SpeakContextPanel + case "landmark": + return reading.SpeakContextLandmark + case "form": + return reading.SpeakContextNonLandmarkForm + } + return false +} + +// Say All has its own context choices, independent of navigation speech. +func SayAllContextEnabled(kind string, reading config.ReadingSettings) bool { + if reading.OnlySpeakDisplayedText { + return false + } + switch kind { + case "blockquote": + return reading.SayAllContextBlockquote + case "list": + return reading.SayAllContextList + case "table": + return reading.SayAllContextTable + case "panel": + return reading.SayAllContextPanel + case "landmark": + return reading.SayAllContextLandmark + case "form": + return reading.SayAllContextNonLandmarkForm + } + return false +} + +func ContextLabel(snapshot atspi.Snapshot) string { + role := ContextType(snapshot) + if role == "blockquote" { + role = "block quote" + } + if role == "landmark" && snapshot.XMLRoles != "" { + role = strings.Fields(snapshot.XMLRoles)[0] + " landmark" + } + if snapshot.Name != "" { + return snapshot.Name + " " + role + } + return role +} + +func itemCountText(count int) string { + if count == 1 { + return "1 item" + } + return fmt.Sprintf("%d items", count) +} + +// TableHeaderText preserves the provider's header label and adds the role +// wording used by verbose speech. Brief speech keeps the label alone. +func TableHeaderText(label, role string, verbosity int) string { + if label == "" || verbosity == 0 { + return label + } + return label + " " + role +} + +// ContextCountLabel adds provider-backed list size to a new context entry. +// The ordinary context label remains stable for exits and brief speech. +func ContextCountLabel(snapshot atspi.Snapshot, verbosity int) string { + if verbosity != 0 && snapshot.ChildCountKnown && snapshot.ChildCount > 0 && + (snapshot.Role == "list" || snapshot.Role == "list box") { + if snapshot.Name != "" { + return snapshot.Name + ", " + itemCountText(snapshot.ChildCount) + } + return itemCountText(snapshot.ChildCount) + } + return ContextLabel(snapshot) +} diff --git a/internal/presentation/reading_test.go b/internal/presentation/reading_test.go new file mode 100644 index 0000000..abb37da --- /dev/null +++ b/internal/presentation/reading_test.go @@ -0,0 +1,125 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package presentation + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/config" +) + +func TestReadingPreferencesChangeControlOutput(t *testing.T) { + reading := config.DefaultSettings().Reading + options := DefaultOptions() + options.Reading = &reading + snapshot := atspi.Snapshot{Name: "Save", Role: "button", Description: "Save document", Mnemonic: "s", PositionInSet: 2, SetSize: 3} + reading.EnableMnemonicSpeaking, reading.EnablePositionSpeaking, reading.EnableTutorialMessages = true, true, true + text := FocusTextWithOptions(snapshot, options) + want := "Save, button, Save document, 2 of 3, s, Press Space to activate." + if text != want { + t.Fatalf("enabled extras = %q, want %q", text, want) + } + reading.EnableMnemonicSpeaking, reading.EnablePositionSpeaking, reading.EnableTutorialMessages = false, false, false + if got := FocusTextWithOptions(snapshot, options); got != "Save, button, Save document" { + t.Fatalf("disabled extras: %q", got) + } + reading.EnablePauseBreaks = false + if got := FocusTextWithOptions(snapshot, options); got != "Save button Save document" { + t.Fatalf("pause breaks survived: %q", got) + } + reading.OnlySpeakDisplayedText = true + if got := FocusTextWithOptions(snapshot, options); got != "Save" { + t.Fatalf("displayed text: %q", got) + } + if got := EventTextWithOptions(atspi.NewEvent("object:state-changed:checked", atspi.Snapshot{Role: "check box", Checked: true}), options); got != "" { + t.Fatalf("state speech survived displayed-only: %q", got) + } + reading.OnlySpeakDisplayedText = false + line := atspi.DocumentLine{Contents: []atspi.DocumentContent{{Text: "word", Snapshot: atspi.Snapshot{Role: "text", Misspelled: true}}}} + if got := DocumentLineTextWithOptions(line, options); got != "word misspelled" { + t.Fatalf("misspelling: %q", got) + } + reading.SpeakMisspelledIndicator = false + if got := DocumentLineTextWithOptions(line, options); got != "word" { + t.Fatalf("disabled misspelling: %q", got) + } +} + +func TestMnemonicSpeechFiltersAngleBracketsWithoutChangingNames(t *testing.T) { + settings := config.DefaultSettings() + settings.Reading.EnableMnemonicSpeaking = true + options := DefaultOptions() + options.Reading = &settings.Reading + snapshot := atspi.Snapshot{Name: "o", Role: "button", Mnemonic: "o"} + want := "o, button, Alt o" + for settings.VerbalizePunctuationStyle = 0; settings.VerbalizePunctuationStyle <= 3; settings.VerbalizePunctuationStyle++ { + if got := FocusTextWithOptions(snapshot, options); got != want { + t.Fatalf("punctuation style %d = %q, want %q", settings.VerbalizePunctuationStyle, got, want) + } + } +} + +func TestDocumentAndSpreadsheetFullRowsUseIndependentFlags(t *testing.T) { + reading := config.DefaultSettings().Reading + options := DefaultOptions() + options.Reading = &reading + cell := atspi.Snapshot{Role: "table cell", Name: "Cell one", TableRowText: "Cell one, Cell two"} + if got := FocusTextWithOptions(cell, options); got != cell.TableRowText { + t.Fatalf("document row = %q", got) + } + reading.ReadFullRowInDocumentTable = false + if got := FocusTextWithOptions(cell, options); got != cell.Name { + t.Fatalf("document cell = %q", got) + } + cell.Spreadsheet = true + reading.ReadFullRowInDocumentTable = true + if got := FocusTextWithOptions(cell, options); got != cell.Name { + t.Fatalf("document flag affected spreadsheet: %q", got) + } + reading.ReadFullRowInSpreadSheet = true + if got := FocusTextWithOptions(cell, options); got != cell.TableRowText { + t.Fatalf("spreadsheet row = %q", got) + } +} + +func TestDocumentLineReadsEachTableRowOnce(t *testing.T) { + line := atspi.DocumentLine{} + for _, name := range []string{"One", "Two"} { + line.Contents = append(line.Contents, atspi.DocumentContent{Text: name, Snapshot: atspi.Snapshot{ + BusName: ":1.42", Path: "/" + name, Role: "table cell", TablePath: "/table", TableRowText: "One, Two", + }}) + } + if got := DocumentLineText(line); got != "One, Two" { + t.Fatalf("repeated row: %q", got) + } +} + +func TestEachNavigationContextHasItsOwnPreference(t *testing.T) { + for _, tc := range []struct { + snapshot atspi.Snapshot + kind string + disable func(*config.ReadingSettings) + }{ + {atspi.Snapshot{Role: "block quote"}, "blockquote", func(r *config.ReadingSettings) { r.SpeakContextBlockquote = false }}, + {atspi.Snapshot{Role: "list"}, "list", func(r *config.ReadingSettings) { r.SpeakContextList = false }}, + {atspi.Snapshot{Role: "table"}, "table", func(r *config.ReadingSettings) { r.SpeakContextTable = false }}, + {atspi.Snapshot{Role: "panel"}, "panel", func(r *config.ReadingSettings) { r.SpeakContextPanel = false }}, + {atspi.Snapshot{Role: "section", XMLRoles: "navigation"}, "landmark", func(r *config.ReadingSettings) { r.SpeakContextLandmark = false }}, + {atspi.Snapshot{Role: "form"}, "form", func(r *config.ReadingSettings) { r.SpeakContextNonLandmarkForm = false }}, + } { + reading := config.DefaultSettings().Reading + if ContextType(tc.snapshot) != tc.kind || !ContextEnabled(tc.kind, reading) { + t.Fatalf("missing context: %+v", tc) + } + tc.disable(&reading) + if ContextEnabled(tc.kind, reading) { + t.Fatalf("disabled context: %s", tc.kind) + } + } + if ContextType(atspi.Snapshot{Role: "table", LayoutTable: true}) != "" { + t.Fatal("layout table announced") + } +} diff --git a/internal/presentation/sound_cues.go b/internal/presentation/sound_cues.go new file mode 100644 index 0000000..6e09762 --- /dev/null +++ b/internal/presentation/sound_cues.go @@ -0,0 +1,209 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import ( + "math" + "strconv" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +// ProgressPercentage normalizes the native range, retaining fractional values. +// Text percentages are used when a provider has no AT-SPI Value interface. +func ProgressPercentage(snapshot atspi.Snapshot) (float64, bool) { + if snapshot.Role != "progress bar" || snapshot.Defunct || snapshot.Indeterminate { + return 0, false + } + var percentage float64 + if snapshot.ValueKnown { + if math.IsNaN(snapshot.CurrentValue) || math.IsInf(snapshot.CurrentValue, 0) || + math.IsNaN(snapshot.MinimumValue) || math.IsInf(snapshot.MinimumValue, 0) || + math.IsNaN(snapshot.MaximumValue) || math.IsInf(snapshot.MaximumValue, 0) || snapshot.MaximumValue <= snapshot.MinimumValue { + return 0, false + } + percentage = (snapshot.CurrentValue - snapshot.MinimumValue) * 100 / (snapshot.MaximumValue - snapshot.MinimumValue) + } else { + value := strings.Trim(strings.TrimSpace(snapshot.ValueText), "%\x00") + var err error + percentage, err = strconv.ParseFloat(value, 64) + if err != nil { + return 0, false + } + } + if math.IsNaN(percentage) || math.IsInf(percentage, 0) { + return 0, false + } + return min(100, max(0, percentage)), true +} + +func ProgressValueSound(snapshot atspi.Snapshot) string { + percentage, valid := ProgressPercentage(snapshot) + if !valid { + return "" + } + return sound.ProgressCueName(percentage) +} + +// SoundCues uses the same immutable accessible snapshot as speech presentation. +// Role and state cues remain categorized until their independent replacement +// decisions have been made. +func SoundCues(snapshot atspi.Snapshot, options Options) []sound.Cue { + if !options.EnableSound { + return nil + } + if options.RoleSoundPresentation == "speech_only" { + return nil + } + + stateCue, hasStateCue := stateSoundCue(snapshot, options) + var cues []sound.Cue + // A toggle's state cue already identifies the button. Keep role and state + // replacement decisions independent for speech and disabled/unavailable cues. + if cue, ok := roleSoundCue(snapshot, options); ok && !(snapshot.Role == "toggle button" && hasStateCue) { + cues = append(cues, cue) + } + if hasStateCue { + cues = append(cues, stateCue) + } + if cue, ok := position_sound_cue(snapshot, options); ok { + cues = append(cues, cue) + } + return cues +} + +func position_sound_cue(snapshot atspi.Snapshot, options Options) (sound.Cue, bool) { + if !options.EnableSound || !options.PlaySoundForPositionInSet || options.RoleSoundPresentation == "speech_only" || + snapshot.Defunct || snapshot.SetSize <= 1 || snapshot.PositionInSet < 1 || snapshot.PositionInSet > snapshot.SetSize { + return sound.Cue{}, false + } + position := float64(snapshot.PositionInSet-1) / float64(snapshot.SetSize-1) + name := sound.PositionCueName(position) + if !cueAvailable(options, name) { + return sound.Cue{}, false + } + return sound.Cue{Name: name, Pan: objectSoundPan(snapshot, options)}, true +} + +// EventSoundCues avoids replaying a role cue for an event which presents only +// a changed state. Focus and other object presentation still include both. +func EventSoundCues(event atspi.Event, options Options) []sound.Cue { + if event.Type == "object:state-changed:focused" { + return SoundCues(event.Source, options) + } + if strings.HasPrefix(event.Type, "object:state-changed:") { + if !isReplaceableStateEvent(event.Type) { + return nil + } + if cue, ok := stateSoundCue(event.Source, options); ok { + return []sound.Cue{cue} + } + return nil + } + return SoundCues(event.Source, options) +} + +func roleSoundCue(snapshot atspi.Snapshot, options Options) (sound.Cue, bool) { + if !options.EnableSound || !options.PlaySoundForRole || options.RoleSoundPresentation == "speech_only" { + return sound.Cue{}, false + } + name := map[string]string{ + "push button": "button", + "button": "button", + "toggle button": "button", + "combo box": "combobox", + }[snapshot.Role] + if snapshot.Role == "link" { + name = "link" + if snapshot.Visited { + name = "link_visited" + } + } + if name == "" || !cueAvailable(options, name) { + return sound.Cue{}, false + } + return sound.Cue{Name: name, Pan: objectSoundPan(snapshot, options)}, true +} + +func stateSoundCue(snapshot atspi.Snapshot, options Options) (sound.Cue, bool) { + if !options.EnableSound || !options.PlaySoundForState || options.RoleSoundPresentation == "speech_only" { + return sound.Cue{}, false + } + name := "" + stateBase := map[string]string{ + "check box": "checkbox", + "check menu item": "checkbox", + "radio button": "radiobutton", + "radio menu item": "radiobutton", + "toggle button": "togglebutton", + "switch": "switch", + }[snapshot.ControlRole()] + switch { + case stateBase == "": + case snapshot.Indeterminate && stateBase == "checkbox": + name = stateBase + "_mixed" + case stateBase == "switch": + if snapshot.Checked { + name = "switch_on" + } else { + name = "switch_off" + } + case snapshot.Checked: + name = stateBase + "_checked" + default: + name = stateBase + "_unchecked" + } + if name == "" || !cueAvailable(options, name) { + return sound.Cue{}, false + } + return sound.Cue{Name: name, Pan: objectSoundPan(snapshot, options)}, true +} + +func cueAvailable(options Options, name string) bool { + return options.SoundCueAvailable == nil || options.SoundCueAvailable(name) +} + +func objectSoundPan(snapshot atspi.Snapshot, options Options) float64 { + if !options.SpatializeObjectSounds { + return 0 + } + geometry := snapshot.SoundGeometry + object, reference := geometry.Object, geometry.Reference + if !geometry.ObjectKnown || !geometry.ReferenceKnown || !object.Valid() || !reference.Valid() { + return 0 + } + objectLeft := int64(object.X) + objectRight := objectLeft + int64(object.Width) + referenceLeft := int64(reference.X) + referenceRight := referenceLeft + int64(reference.Width) + if objectLeft < referenceLeft || objectRight > referenceRight { + return 0 + } + center := float64(objectLeft) + float64(object.Width)/2 + position := (center - float64(referenceLeft)) / float64(reference.Width) + const edge = 0.05 + if position <= edge { + return -1 + } + if position >= 1-edge { + return 1 + } + return ((position-edge)/(1-2*edge)*2 - 1) +} diff --git a/internal/presentation/sound_cues_test.go b/internal/presentation/sound_cues_test.go new file mode 100644 index 0000000..6a593db --- /dev/null +++ b/internal/presentation/sound_cues_test.go @@ -0,0 +1,280 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import ( + "math" + "reflect" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/sound" +) + +func TestRoleAndStateSoundPolicy(t *testing.T) { + options := Options{EnableSound: true, PlaySoundForRole: true, PlaySoundForState: true} + for _, test := range []struct { + snapshot atspi.Snapshot + want []string + }{ + {atspi.Snapshot{Role: "push button"}, []string{"button"}}, + {atspi.Snapshot{Role: "check box", Checked: true}, []string{"checkbox_checked"}}, + {atspi.Snapshot{Role: "check box", Indeterminate: true}, []string{"checkbox_mixed"}}, + {atspi.Snapshot{Role: "check box"}, []string{"checkbox_unchecked"}}, + {atspi.Snapshot{Role: "menu item", Checkable: true}, []string{"checkbox_unchecked"}}, + {atspi.Snapshot{Role: "menu item", Checked: true}, []string{"checkbox_checked"}}, + {atspi.Snapshot{Role: "menu item", Indeterminate: true}, []string{"checkbox_mixed"}}, + {atspi.Snapshot{Role: "menu item"}, nil}, + {atspi.Snapshot{Role: "toggle button", Checked: true}, []string{"togglebutton_checked"}}, + {atspi.Snapshot{Role: "toggle button"}, []string{"togglebutton_unchecked"}}, + {atspi.Snapshot{Role: "switch", Checked: true}, []string{"switch_on"}}, + {atspi.Snapshot{Role: "switch"}, []string{"switch_off"}}, + {atspi.Snapshot{Role: "link", Visited: true}, []string{"link_visited"}}, + {atspi.Snapshot{Role: "entry"}, nil}, + {atspi.Snapshot{Role: "terminal"}, nil}, + } { + if got := cueNames(SoundCues(test.snapshot, options)); !reflect.DeepEqual(got, test.want) { + t.Fatalf("cues = %#v, want %#v", got, test.want) + } + } + options.RoleSoundPresentation = "sound_only" + if got := FocusTextWithOptions(atspi.Snapshot{Name: "Save", Role: "push button"}, options); got != "Save" { + t.Fatal(got) + } + options.EnableSound = false + if got := FocusTextWithOptions(atspi.Snapshot{Name: "Save", Role: "push button"}, options); got != "Save, push button" { + t.Fatal(got) + } + options.EnableSound = true + options.RoleSoundPresentation = "speech_only" + if got := SoundCues(atspi.Snapshot{Role: "push button"}, options); got != nil { + t.Fatalf("speech-only role presentation produced cues %#v", got) + } + options.RoleSoundPresentation = "sound_and_speech" + options.PlaySoundForRole = false + if got := cueNames(SoundCues(atspi.Snapshot{Role: "toggle button", Checked: true}, options)); !reflect.DeepEqual(got, []string{"togglebutton_checked"}) { + t.Fatalf("disabled role sound produced cues %#v", got) + } + options.PlaySoundForRole = true + options.PlaySoundForState = false + if got := cueNames(SoundCues(atspi.Snapshot{Role: "toggle button", Checked: true}, options)); !reflect.DeepEqual(got, []string{"button"}) { + t.Fatalf("disabled state sound produced cues %#v", got) + } + options.PlaySoundForRole = false + if got := SoundCues(atspi.Snapshot{Role: "toggle button", Checked: true}, options); got != nil { + t.Fatalf("disabled role and state sounds produced cues %#v", got) + } +} + +func TestFocusedEventSoundCues(t *testing.T) { + options := Options{EnableSound: true, PlaySoundForRole: true, PlaySoundForState: true, RoleSoundPresentation: "sound_and_speech"} + for _, test := range []struct { + name string + snapshot atspi.Snapshot + want []string + }{ + {"button", atspi.Snapshot{Role: "button"}, []string{"button"}}, + {"link", atspi.Snapshot{Role: "link"}, []string{"link"}}, + {"visited link", atspi.Snapshot{Role: "link", Visited: true}, []string{"link_visited"}}, + {"checked toggle", atspi.Snapshot{Role: "toggle button", Checked: true}, []string{"togglebutton_checked"}}, + {"unchecked toggle", atspi.Snapshot{Role: "toggle button"}, []string{"togglebutton_unchecked"}}, + } { + t.Run(test.name, func(t *testing.T) { + for _, eventType := range []string{"focus:", "object:state-changed:focused"} { + event := atspi.NewEvent(eventType, test.snapshot) + if got := cueNames(EventSoundCues(event, options)); !reflect.DeepEqual(got, test.want) { + t.Errorf("%s cues = %v, want %v", eventType, got, test.want) + } + } + }) + } + checked := atspi.NewEvent("object:state-changed:checked", atspi.Snapshot{Role: "check box", Checked: true}) + if got := cueNames(EventSoundCues(checked, options)); !reflect.DeepEqual(got, []string{"checkbox_checked"}) { + t.Errorf("checked state cues = %v", got) + } + autocompleteState := atspi.NewEvent("object:state-changed:selected", atspi.Snapshot{Role: "entry", Autocomplete: true}) + if got := EventSoundCues(autocompleteState, options); got != nil { + t.Errorf("autocomplete state replayed role cue: %v", got) + } +} + +func TestToggleSoundPreservesUnavailableStateFeedback(t *testing.T) { + options := Options{ + EnableSound: true, PlaySoundForRole: true, PlaySoundForState: true, + RoleSoundPresentation: "sound_only", + SoundCueAvailable: func(name string) bool { return name == "button" }, + } + for _, checked := range []bool{false, true} { + snapshot := atspi.Snapshot{Name: "Power", Role: "toggle button", Checked: checked} + if got := cueNames(SoundCues(snapshot, options)); !reflect.DeepEqual(got, []string{"button"}) { + t.Fatalf("unavailable state cue, checked=%v: %v", checked, got) + } + wantText := "Power, not pressed" + if checked { + wantText = "Power, pressed" + } + if got := FocusTextWithOptions(snapshot, options); got != wantText { + t.Fatalf("unavailable state speech = %q, want %q", got, wantText) + } + } +} + +func cueNames(cues []sound.Cue) []string { + if cues == nil { + return nil + } + names := make([]string, len(cues)) + for index, cue := range cues { + names[index] = cue.Name + } + return names +} + +func TestProgressValueSound(t *testing.T) { + snapshot := atspi.Snapshot{Role: "progress bar", ValueKnown: true, MinimumValue: 0, CurrentValue: 50, MaximumValue: 100} + if got := ProgressValueSound(snapshot); got != "generated-progress-tone:50" { + t.Fatalf("progress sound = %q", got) + } + snapshot.CurrentValue = 200 + if got := ProgressValueSound(snapshot); got != "generated-progress-tone:100" { + t.Fatalf("clamped progress sound = %q", got) + } + snapshot.Role = "slider" + if got := ProgressValueSound(snapshot); got != "" { + t.Fatalf("slider generated progress sound %q", got) + } +} + +func TestProgressPercentagesRetainFractionsAndRejectInvalidValues(t *testing.T) { + for _, step := range []struct { + snapshot atspi.Snapshot + value float64 + valid bool + }{ + {atspi.Snapshot{Role: "progress bar", ValueKnown: true, MinimumValue: 10, CurrentValue: 20, MaximumValue: 30}, 50, true}, + {atspi.Snapshot{Role: "progress bar", ValueText: "12.5%"}, 12.5, true}, + {atspi.Snapshot{Role: "progress bar", ValueText: "101%"}, 100, true}, + {atspi.Snapshot{Role: "progress bar", ValueText: "NaN"}, 0, false}, + {atspi.Snapshot{Role: "progress bar", ValueText: "+Inf"}, 0, false}, + {atspi.Snapshot{Role: "progress bar", ValueText: "working"}, 0, false}, + {atspi.Snapshot{Role: "progress bar", ValueKnown: true, MaximumValue: 0}, 0, false}, + {atspi.Snapshot{Role: "progress bar", ValueText: "50%", Indeterminate: true}, 0, false}, + } { + value, valid := ProgressPercentage(step.snapshot) + if value != step.value || valid != step.valid { + t.Fatalf("progress %+v: %g, %t", step.snapshot, value, valid) + } + } +} + +func TestElementPresentationStrategiesKeepRoleAndStateIndependent(t *testing.T) { + toggle := atspi.Snapshot{Name: "Power", Role: "toggle button", Checked: true} + for _, test := range []struct { + strategy string + role bool + state bool + text string + cues []string + }{ + {"speech_only", true, true, "Power, toggle button, pressed", nil}, + {"sound_and_speech", true, true, "Power, toggle button, pressed", []string{"togglebutton_checked"}}, + {"sound_only", true, true, "Power", []string{"togglebutton_checked"}}, + {"sound_only", false, true, "Power, toggle button", []string{"togglebutton_checked"}}, + {"sound_only", true, false, "Power, pressed", []string{"button"}}, + {"sound_only", false, false, "Power, toggle button, pressed", nil}, + } { + options := Options{EnableSound: true, PlaySoundForRole: test.role, PlaySoundForState: test.state, RoleSoundPresentation: test.strategy} + if got := FocusTextWithOptions(toggle, options); got != test.text { + t.Errorf("%s role=%v state=%v text=%q, want %q", test.strategy, test.role, test.state, got, test.text) + } + if got := cueNames(SoundCues(toggle, options)); !reflect.DeepEqual(got, test.cues) { + t.Errorf("%s role=%v state=%v cues=%v, want %v", test.strategy, test.role, test.state, got, test.cues) + } + } + + checkbox := atspi.Snapshot{Name: "Accept", Role: "check box", Checked: true, Required: true, Invalid: true} + options := Options{EnableSound: true, PlaySoundForRole: true, PlaySoundForState: true, RoleSoundPresentation: "sound_only"} + if got := FocusTextWithOptions(checkbox, options); got != "Accept, check box, required, invalid entry" { + t.Fatalf("sound-only checkbox text = %q", got) + } + unsupported := atspi.Snapshot{Name: "Document", Role: "text frame", Expandable: true, Expanded: true} + if got := FocusTextWithOptions(unsupported, options); got != "Document, text frame, expanded" { + t.Fatalf("unsupported state text = %q", got) + } + options.SoundCueAvailable = func(string) bool { return false } + if got := FocusTextWithOptions(toggle, options); got != "Power, toggle button, pressed" { + t.Fatalf("unavailable cue fallback text = %q", got) + } +} + +func TestStateChangeSoundOnlySuppressesOnlyReplacedState(t *testing.T) { + options := Options{EnableSound: true, PlaySoundForRole: true, PlaySoundForState: true, RoleSoundPresentation: "sound_only"} + event := atspi.NewEvent("object:state-changed:checked", atspi.Snapshot{Role: "check box", Checked: true}) + if got := EventTextWithOptions(event, options); got != "" { + t.Fatalf("checked state remained spoken: %q", got) + } + unsupported := atspi.NewEvent("object:state-changed:expanded", atspi.Snapshot{Role: "text frame", Expandable: true, Expanded: true}) + if got := EventTextWithOptions(unsupported, options); got != "expanded" { + t.Fatalf("unsupported expanded state = %q", got) + } + toggleExpanded := atspi.NewEvent("object:state-changed:expanded", atspi.Snapshot{Role: "toggle button", Checked: true, Expandable: true, Expanded: true}) + if got := EventSoundCues(toggleExpanded, options); got != nil { + t.Fatalf("expanded event replayed unrelated cues %#v", got) + } + options.PlaySoundForState = false + if got := EventTextWithOptions(event, options); got != "checked" { + t.Fatalf("disabled state fallback = %q", got) + } +} + +func TestObjectSoundPanUsesCapturedGeometry(t *testing.T) { + base := atspi.SoundGeometry{ObjectKnown: true, ReferenceKnown: true, Reference: atspi.Rectangle{X: 100, Y: 20, Width: 1000, Height: 600}} + for _, test := range []struct { + name string + object atspi.Rectangle + want float64 + }{ + {"left", atspi.Rectangle{X: 100, Y: 100, Width: 10, Height: 10}, -1}, + {"center", atspi.Rectangle{X: 595, Y: 100, Width: 10, Height: 10}, 0}, + {"right", atspi.Rectangle{X: 1090, Y: 100, Width: 10, Height: 10}, 1}, + {"intermediate", atspi.Rectangle{X: 350, Y: 100, Width: 10, Height: 10}, -0.5444444444444445}, + } { + geometry := base + geometry.Object = test.object + snapshot := atspi.Snapshot{Role: "push button", SoundGeometry: geometry} + options := Options{EnableSound: true, PlaySoundForRole: true, RoleSoundPresentation: "sound_only", SpatializeObjectSounds: true} + cues := SoundCues(snapshot, options) + if len(cues) != 1 || math.Abs(cues[0].Pan-test.want) > 1e-9 { + t.Errorf("%s pan = %#v, want %v", test.name, cues, test.want) + } + } + invalid := base + invalid.Object = atspi.Rectangle{X: 0, Y: 0, Width: 0, Height: 10} + if got := SoundCues(atspi.Snapshot{Role: "push button", SoundGeometry: invalid}, Options{EnableSound: true, PlaySoundForRole: true, SpatializeObjectSounds: true}); got[0].Pan != 0 { + t.Fatalf("invalid geometry pan = %v", got[0].Pan) + } + clipped := base + clipped.Object = atspi.Rectangle{X: 50, Y: 100, Width: 10, Height: 10} + if got := SoundCues(atspi.Snapshot{Role: "push button", SoundGeometry: clipped}, Options{EnableSound: true, PlaySoundForRole: true, SpatializeObjectSounds: true}); got[0].Pan != 0 { + t.Fatalf("clipped geometry pan = %v", got[0].Pan) + } + centered := SoundCues(atspi.Snapshot{Role: "push button", SoundGeometry: base}, Options{EnableSound: true, PlaySoundForRole: true}) + if centered[0].Pan != 0 { + t.Fatalf("disabled spatialization pan = %v", centered[0].Pan) + } +} diff --git a/internal/presentation/speech.go b/internal/presentation/speech.go new file mode 100644 index 0000000..114c1c2 --- /dev/null +++ b/internal/presentation/speech.go @@ -0,0 +1,65 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package presentation + +// Speech retains presentation boundaries independently of the display text. +// Source punctuation is always part of its original chunk. +type Speech struct { + Text string + Chunks []string +} + +func SpeechWithOptions(parts []string, options Options) Speech { + var nonempty []string + for _, part := range parts { + if part != "" { + nonempty = append(nonempty, part) + } + } + parts = nonempty + result := Speech{Text: join_speech_parts(parts, options)} + if reading_options(options).EnablePauseBreaks { + result.Chunks = parts + } + return result +} + +// WithText replaces the presentation only when its text has changed. +func (speech Speech) WithText(text string) Speech { + if text == speech.Text { + return speech + } + return Speech{Text: text} +} + +// Prepend and Append carry explicitly added presentation boundaries without +// inspecting source text for punctuation or matching it inside another string. +func (speech Speech) Prepend(text, separator string) Speech { + if text == "" { + return speech + } + if speech.Text == "" { + return Speech{Text: text} + } + result := Speech{Text: text + separator + speech.Text} + if len(speech.Chunks) != 0 { + result.Chunks = append([]string{text}, speech.Chunks...) + } + return result +} + +func (speech Speech) Append(text, separator string) Speech { + if text == "" { + return speech + } + if speech.Text == "" { + return Speech{Text: text} + } + result := Speech{Text: speech.Text + separator + text} + if len(speech.Chunks) != 0 { + result.Chunks = append(append([]string(nil), speech.Chunks...), text) + } + return result +} diff --git a/internal/presentation/text_label_native_test.go b/internal/presentation/text_label_native_test.go new file mode 100644 index 0000000..7142959 --- /dev/null +++ b/internal/presentation/text_label_native_test.go @@ -0,0 +1,98 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package presentation + +import ( + "bufio" + "context" + "fmt" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestNativeTextLabelRelations(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_TEXT_LABELS") != "1" { + t.Skip("requires private GTK/AT-SPI session") + } + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + fixture := exec.CommandContext(ctx, "/usr/bin/python3", "-u", "../../tests/text_label_fixture.py") + fixture.Env = append(os.Environ(), "NO_AT_BRIDGE=0", "GTK_MODULES=gail:atk-bridge") + stdin, err := fixture.StdinPipe() + if err != nil { + t.Fatal(err) + } + stdout, err := fixture.StdoutPipe() + if err != nil { + t.Fatal(err) + } + fixture.Stderr = os.Stderr + if err := fixture.Start(); err != nil { + t.Fatal(err) + } + defer func() { stdin.Close(); fixture.Wait() }() + if scanner := bufio.NewScanner(stdout); !scanner.Scan() || scanner.Text() != "ready" { + t.Fatal("fixture did not start") + } + var previous atspi.ObjectID + for index, probe := range []struct{ name, value string }{ + {"Destination:", ""}, + {"Display name:", "Example document"}, + {"Preferred name", "Example value"}, + {"Secret:", ""}, + {"", "Unlabeled value"}, + {"Account identifier", ""}, + {"Read-only summary:", "Example summary"}, + } { + if _, err := fmt.Fprintln(stdin, index); err != nil { + t.Fatal(err) + } + waitFocus: + for { + select { + case <-ctx.Done(): + t.Fatal("missing entry focus", index) + case event := <-adapter.Events(): + if (event.Type != atspi.FocusEvent && event.Type != atspi.FocusedStateEvent) || !event.Source.Focused { + continue + } + snapshot := event.Source + if snapshot.Role != "text" && snapshot.Role != "password text" { + continue + } + if snapshot.ID() == previous { + continue + } + previous = snapshot.ID() + if snapshot.Name != probe.name { + t.Errorf("entry %d name = %q, want %q", index, snapshot.Name, probe.name) + } + if probe.name == "Read-only summary:" && snapshot.Editable { + t.Error("read-only fixture unexpectedly exposes editable state") + } + speech := FocusText(snapshot) + for _, part := range []string{probe.name, probe.value} { + if part != "" && !strings.Contains(speech, part) { + t.Errorf("entry %d speech %q omits %q", index, speech, part) + } + } + if strings.Contains(speech, "private fixture value") { + t.Error("password content leaked into speech") + } + break waitFocus + } + } + } +} diff --git a/internal/presentation/typing_echo.go b/internal/presentation/typing_echo.go new file mode 100644 index 0000000..8b814ea --- /dev/null +++ b/internal/presentation/typing_echo.go @@ -0,0 +1,152 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import ( + "strings" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TypingEchoText(event atspi.Event, previousText string, options Options) string { + text, _ := TypingEcho(event, previousText, options) + return text +} + +func TypingEcho(event atspi.Event, previousText string, options Options) (string, string) { + options = insertionEchoOptions(event, options) + kind := "" + if event.Type == atspi.TextInsertedEvent && utf8.RuneCountInString(event.Payload) == 1 { + kind = "key" + if options.EnableEchoByCharacter { + kind = "character" + } + } + characterEcho := EventTextWithOptions(event, options) + if event.Type != atspi.TextInsertedEvent || !options.EnableKeyEcho || utf8.RuneCountInString(event.Payload) != 1 { + return characterEcho, kind + } + context := event.Source.TextBeforeCaret + if context == "" { + context = event.Source.Text + } + if (event.Payload == "\n" || event.Payload == "\t") && strings.TrimSpace(context) == "" { + context = previousText + } + if options.EnableEchoBySentence { + if sentence := completedSentence(context, event.Payload); sentence != "" { + return sentence, "sentence" + } + } + if options.EnableEchoByWord { + if word := completedWord(context, event.Payload); word != "" { + return word, "word" + } + } + return characterEcho, kind +} + +func completedWord(context, inserted string) string { + if !isWordDelimiter(inserted) { + return "" + } + context = strings.TrimSuffix(context, inserted) + characters := []rune(context) + if len(characters) == 0 || isWordDelimiter(string(characters[len(characters)-1])) { + return "" + } + start := len(characters) - 1 + for start >= 0 && !isWordDelimiter(string(characters[start])) { + start-- + } + return string(characters[start+1:]) +} + +func completedSentence(context, inserted string) string { + context = strings.TrimSuffix(context, inserted) + characters := []rune(context) + if len(characters) == 0 { + return "" + } + if inserted != "\n" && inserted != "\r" { + if !unicode.IsSpace(firstRune(inserted)) || !strings.ContainsRune("!.?:;", characters[len(characters)-1]) { + return "" + } + } + start := 0 + for index := 1; index < len(characters); index++ { + if characters[index] == '\n' || characters[index] == '\r' || + unicode.IsSpace(characters[index]) && strings.ContainsRune("!.?:;", characters[index-1]) { + start = index + 1 + } + } + return strings.TrimSpace(string(characters[start:])) +} + +func isWordDelimiter(value string) bool { + if utf8.RuneCountInString(value) != 1 { + return false + } + r := firstRune(value) + return unicode.IsSpace(r) || strings.ContainsRune("!*+,-./:;<=>?@[\\]^_{|}", r) || r == '\u00a0' +} + +func firstRune(value string) rune { + r, _ := utf8.DecodeRuneInString(value) + return r +} + +// Edit-fields-only changes typing echo, not pasted text or application output. +func insertionEchoOptions(event atspi.Event, options Options) Options { + if options.KeyEchoInEditFieldsOnly && !atspi.IsEchoEditField(event.Source) { + options.EnableKeyEcho = false + } + return options +} + +func shouldEchoInsertion(text string, options Options) bool { + if text == "" { + return false + } + if utf8.RuneCountInString(text) != 1 { + return true + } + if !options.EnableKeyEcho { + return false + } + r, _ := utf8.DecodeRuneInString(text) + if options.EnableEchoByCharacter && unicode.IsPrint(r) { + return true + } + switch { + case unicode.IsLetter(r): + return options.EnableAlphabeticKeys + case unicode.IsNumber(r): + return options.EnableNumericKeys + case unicode.IsPunct(r) || unicode.IsSymbol(r): + return options.EnablePunctuationKeys + case r == ' ': + return options.EnableSpace + case unicode.Is(unicode.Mn, r) || unicode.Is(unicode.Mc, r) || unicode.Is(unicode.Me, r): + return options.EnableDiacriticalKeys + default: + return false + } +} diff --git a/internal/presentation/typing_echo_test.go b/internal/presentation/typing_echo_test.go new file mode 100644 index 0000000..2445333 --- /dev/null +++ b/internal/presentation/typing_echo_test.go @@ -0,0 +1,166 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package presentation + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestEventTextAppliesPrintableKeyEchoSettings(t *testing.T) { + tests := []struct { + name string + payload string + update func(*Options) + want string + }{ + {name: "alphabetic enabled", payload: "a", want: "a"}, + {name: "alphabetic disabled", payload: "a", update: func(options *Options) { options.EnableAlphabeticKeys = false }}, + {name: "numeric disabled", payload: "7", update: func(options *Options) { options.EnableNumericKeys = false }}, + {name: "punctuation disabled", payload: "!", update: func(options *Options) { options.EnablePunctuationKeys = false }}, + {name: "symbol uses punctuation setting", payload: "€", update: func(options *Options) { options.EnablePunctuationKeys = false }}, + {name: "space enabled", payload: " ", want: "space"}, + {name: "space disabled", payload: " ", update: func(options *Options) { options.EnableSpace = false }}, + {name: "diacritical enabled", payload: "́", update: func(options *Options) { options.EnableDiacriticalKeys = true }, want: "́"}, + {name: "character echo overrides category", payload: "a", update: func(options *Options) { + options.EnableAlphabeticKeys = false + options.EnableEchoByCharacter = true + }, want: "a"}, + {name: "key echo disables character echo", payload: "a", update: func(options *Options) { + options.EnableKeyEcho = false + options.EnableEchoByCharacter = true + }}, + {name: "multi-character insertion is not a key echo", payload: "pasted text", update: func(options *Options) { + options.EnableKeyEcho = false + }, want: "pasted text"}, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + options := DefaultOptions() + if test.update != nil { + test.update(&options) + } + event := atspi.NewEventWithPayload( + atspi.TextInsertedEvent, + atspi.NewSnapshot("/accessible/editor", "", "text", "", ""), + test.payload, + ) + if got := EventTextWithOptions(event, options); got != test.want { + t.Fatalf("EventTextWithOptions() = %q, want %q", got, test.want) + } + }) + } +} + +func TestSentenceEchoStopsAtPreviousLine(t *testing.T) { + options := DefaultOptions() + options.EnableEchoBySentence = true + for _, context := range []string{"First line\nSecond line. ", "First line\rSecond line. "} { + event := atspi.NewEvent(atspi.TextInsertedEvent, atspi.Snapshot{TextBeforeCaret: context}) + event.Payload = " " + if got := TypingEchoText(event, "", options); got != "Second line." { + t.Fatalf("sentence echo = %q, want only the current sentence", got) + } + } +} + +func TestTypingEchoTextAppliesWordAndSentenceSettings(t *testing.T) { + options := DefaultOptions() + options.EnableEchoByWord = true + snapshot := atspi.NewSnapshot("/accessible/editor", "", "text", "", "hello ") + snapshot.Editable = true + snapshot.TextBeforeCaret = "hello " + event := atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, " ") + if got := TypingEchoText(event, "", options); got != "hello" { + t.Fatalf("word echo = %q, want hello", got) + } + + snapshot.TextBeforeCaret = "hello," + event = atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, ",") + if got := TypingEchoText(event, "", options); got != "hello" { + t.Fatalf("punctuation word echo = %q, want hello", got) + } + + snapshot.TextBeforeCaret = "hello " + event = atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, " ") + if got := TypingEchoText(event, "", options); got != "space" { + t.Fatalf("repeated delimiter echo = %q, want space", got) + } + + options.EnableEchoBySentence = true + snapshot.TextBeforeCaret = "First. Second. " + event = atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, " ") + if got := TypingEchoText(event, "", options); got != "Second." { + t.Fatalf("sentence echo = %q, want Second.", got) + } + + snapshot.TextBeforeCaret = "" + snapshot.Text = "" + event = atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, "\n") + if got := TypingEchoText(event, "Line without punctuation", options); got != "Line without punctuation" { + t.Fatalf("newline sentence echo = %q", got) + } + + options.EnableKeyEcho = false + if got := TypingEchoText(event, "Line without punctuation", options); got != "" { + t.Fatalf("disabled key echo sentence = %q", got) + } +} + +func TestTypingEchoInEditFieldsOnly(t *testing.T) { + options := DefaultOptions() + options.KeyEchoInEditFieldsOnly = true + options.EnableEchoByWord = true + options.EnableEchoBySentence = true + for _, tc := range []struct { + name string + source atspi.Snapshot + want bool + }{ + {"entry", atspi.Snapshot{Role: "text", Editable: true}, true}, + {"contenteditable", atspi.Snapshot{Role: "section", Editable: true}, true}, + {"readonly", atspi.Snapshot{Role: "text", Editable: true, ReadOnly: true}, false}, + {"terminal", atspi.Snapshot{Role: "terminal"}, false}, + {"unknown", atspi.Snapshot{Role: "text"}, false}, + {"password", atspi.Snapshot{Role: "password text", Editable: true}, false}, + } { + t.Run(tc.name, func(t *testing.T) { + for _, payload := range []string{"a", " "} { + event := atspi.Event{Type: atspi.TextInsertedEvent, Source: tc.source, Payload: payload} + event.Source.TextBeforeCaret = "Hello. " + text, _ := TypingEcho(event, "", options) + if (text != "") != tc.want { + t.Fatalf("payload=%q echo=%q wanted enabled=%v", payload, text, tc.want) + } + } + if tc.source.Role != "password text" { + event := atspi.Event{Type: atspi.TextInsertedEvent, Source: tc.source, Payload: "pasted or application text"} + if got := TypingEchoText(event, "", options); got != event.Payload { + t.Fatalf("ordinary text lost: %q", got) + } + event.Type = atspi.TextDeletedEvent + event.Payload = "a" + if got := EventTextWithOptions(event, options); got != "a" { + t.Fatalf("deletion lost: %q", got) + } + } + }) + } +} diff --git a/internal/remote/endpoint.go b/internal/remote/endpoint.go new file mode 100644 index 0000000..e537eb3 --- /dev/null +++ b/internal/remote/endpoint.go @@ -0,0 +1,273 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +// Package remote publishes Cthulhu's bounded self-voice D-Bus API. +package remote + +import ( + "encoding/xml" + "log/slog" + "sync" + + "git.stormux.org/storm/cthulhu/internal/version" + "github.com/godbus/dbus/v5" +) + +type endpoint struct { + logger *slog.Logger + handler Handler + authorize func(dbus.Sender) bool + + mutex sync.Mutex + accepting bool + active int + idle chan struct{} +} + +func newEndpoint(logger *slog.Logger, handler Handler, authorize func(dbus.Sender) bool) *endpoint { + if logger == nil { + logger = slog.New(slog.DiscardHandler) + } + return &endpoint{logger: logger, handler: handler, authorize: authorize} +} + +func (endpoint *endpoint) startAccepting() { + endpoint.mutex.Lock() + endpoint.accepting = true + endpoint.mutex.Unlock() +} + +func (endpoint *endpoint) begin(sender dbus.Sender, method string) *dbus.Error { + endpoint.mutex.Lock() + if !endpoint.accepting { + endpoint.mutex.Unlock() + endpoint.logger.Debug("self-voice D-Bus call unavailable", "method", method, "sender", sender) + return &dbus.Error{ + Name: "org.stormux.Cthulhu1.Error.Unavailable", + Body: []any{"self-voice service is not accepting requests"}, + } + } + endpoint.active++ + endpoint.mutex.Unlock() + if endpoint.authorize == nil || !endpoint.authorize(sender) { + endpoint.end() + endpoint.logger.Warn("self-voice D-Bus call denied", "method", method, "sender", sender) + return &dbus.Error{ + Name: "org.freedesktop.DBus.Error.AccessDenied", + Body: []any{"self-voice requests are restricted to the runtime user"}, + } + } + endpoint.logger.Debug("self-voice D-Bus call accepted", "method", method, "sender", sender) + return nil +} + +func (endpoint *endpoint) end() { + endpoint.mutex.Lock() + endpoint.active-- + if endpoint.active == 0 && endpoint.idle != nil { + close(endpoint.idle) + endpoint.idle = nil + } + endpoint.mutex.Unlock() +} + +func (endpoint *endpoint) stopAccepting() <-chan struct{} { + endpoint.mutex.Lock() + defer endpoint.mutex.Unlock() + endpoint.accepting = false + if endpoint.active == 0 { + idle := make(chan struct{}) + close(idle) + return idle + } + if endpoint.idle == nil { + endpoint.idle = make(chan struct{}) + } + return endpoint.idle +} + +func (endpoint *endpoint) logRequest(method string) { + endpoint.logger.Debug("self-voice D-Bus request", "method", method) +} + +func (endpoint *endpoint) logResponse(method string, result any) { + endpoint.logger.Debug("self-voice D-Bus response", "method", method, "result", result) +} + +func (endpoint *endpoint) PresentMessage(sender dbus.Sender, message string) (bool, *dbus.Error) { + endpoint.logRequest("PresentMessage") + if err := endpoint.begin(sender, "PresentMessage"); err != nil { + return false, err + } + defer endpoint.end() + if len(message) > maxTextBytes { + endpoint.logResponse("PresentMessage", false) + return false, nil + } + accepted := endpoint.handler.PresentMessage(message) + endpoint.logResponse("PresentMessage", accepted) + return accepted, nil +} + +func (endpoint *endpoint) ShowPreferences(sender dbus.Sender) (bool, *dbus.Error) { + if err := endpoint.begin(sender, "ShowPreferences"); err != nil { + return false, err + } + defer endpoint.end() + if handler, ok := endpoint.handler.(ControlHandler); ok { + return handler.ShowPreferences(), nil + } + return false, nil +} + +func (endpoint *endpoint) GetVersion(sender dbus.Sender) (string, *dbus.Error) { + if err := endpoint.begin(sender, "GetVersion"); err != nil { + return "", err + } + defer endpoint.end() + return version.String(), nil +} + +func (endpoint *endpoint) GetRuntimeStateSnapshot(sender dbus.Sender) (string, *dbus.Error) { + if err := endpoint.begin(sender, "GetRuntimeStateSnapshot"); err != nil { + return "", err + } + defer endpoint.end() + if handler, ok := endpoint.handler.(ControlHandler); ok { + return handler.RuntimeStateSnapshot(), nil + } + return "", nil +} + +func (endpoint *endpoint) Quit(sender dbus.Sender) (bool, *dbus.Error) { + if err := endpoint.begin(sender, "Quit"); err != nil { + return false, err + } + defer endpoint.end() + if handler, ok := endpoint.handler.(ControlHandler); ok { + return handler.Quit(), nil + } + return false, nil +} + +func (endpoint *endpoint) SpeakText(sender dbus.Sender, text string, interrupt bool) (bool, *dbus.Error) { + endpoint.logRequest("SpeakText") + if err := endpoint.begin(sender, "SpeakText"); err != nil { + return false, err + } + defer endpoint.end() + if text == "" || len(text) > maxTextBytes { + endpoint.logResponse("SpeakText", false) + return false, nil + } + accepted := endpoint.handler.SpeakText(text, interrupt) + endpoint.logResponse("SpeakText", accepted) + return accepted, nil +} + +func (endpoint *endpoint) BrailleMessage(sender dbus.Sender, text string) (bool, *dbus.Error) { + endpoint.logRequest("BrailleMessage") + if err := endpoint.begin(sender, "BrailleMessage"); err != nil { + return false, err + } + defer endpoint.end() + if text == "" || len(text) > maxTextBytes { + endpoint.logResponse("BrailleMessage", false) + return false, nil + } + accepted := endpoint.handler.BrailleMessage(text) + endpoint.logResponse("BrailleMessage", accepted) + return accepted, nil +} + +func (endpoint *endpoint) CancelSpeech(sender dbus.Sender) (bool, *dbus.Error) { + endpoint.logRequest("CancelSpeech") + if err := endpoint.begin(sender, "CancelSpeech"); err != nil { + return false, err + } + defer endpoint.end() + accepted := endpoint.handler.CancelSpeech() + endpoint.logResponse("CancelSpeech", accepted) + return accepted, nil +} + +func (endpoint *endpoint) SpeakSsml(sender dbus.Sender, requestID, ssml string) (int32, *dbus.Error) { + endpoint.logRequest("SpeakSsml") + if err := endpoint.begin(sender, "SpeakSsml"); err != nil { + return windowsErrorInvalidParameter, err + } + defer endpoint.end() + if len(requestID) > maxRequestIDBytes || len(ssml) > maxTextBytes || !validSSML(ssml) { + endpoint.logResponse("SpeakSsml", windowsErrorInvalidParameter) + return windowsErrorInvalidParameter, nil + } + endpoint.logResponse("SpeakSsml", windowsErrorNotSupported) + return windowsErrorNotSupported, nil +} + +func (endpoint *endpoint) PresentAccessibleEvent(sender dbus.Sender, sourceID, eventType, name, role, value, states, description string, position, count int32, windowTitle string) (bool, *dbus.Error) { + endpoint.logRequest("PresentAccessibleEvent") + if err := endpoint.begin(sender, "PresentAccessibleEvent"); err != nil { + return false, err + } + defer endpoint.end() + for _, field := range []string{sourceID, eventType, name, role, value, states, description, windowTitle} { + if len(field) > 4096 { + endpoint.logResponse("PresentAccessibleEvent", false) + return false, nil + } + } + if sourceID == "" { + endpoint.logResponse("PresentAccessibleEvent", false) + return false, nil + } + accepted := endpoint.handler.PresentAccessibleEvent(AccessibleEvent{ + SourceID: sourceID, EventType: eventType, Name: name, Role: role, + Value: value, States: states, Description: description, + Position: position, Count: count, WindowTitle: windowTitle, + }) + endpoint.logResponse("PresentAccessibleEvent", accepted) + return accepted, nil +} + +func validSSML(value string) bool { + var root struct { + XMLName xml.Name + } + if err := xml.Unmarshal([]byte(value), &root); err != nil { + return false + } + return root.XMLName.Local == "speak" +} + +// speechManagerEndpoint shares authorization and shutdown accounting with the +// main service. Python's notify_user argument does not affect speech cancellation. +type speechManagerEndpoint struct { + endpoint *endpoint +} + +func (manager *speechManagerEndpoint) InterruptSpeech(sender dbus.Sender, _ bool) (bool, *dbus.Error) { + endpoint := manager.endpoint + endpoint.logRequest("InterruptSpeech") + if err := endpoint.begin(sender, "InterruptSpeech"); err != nil { + return false, err + } + defer endpoint.end() + accepted := endpoint.handler.CancelSpeech() + endpoint.logResponse("InterruptSpeech", accepted) + return accepted, nil +} diff --git a/internal/remote/endpoint_test.go b/internal/remote/endpoint_test.go new file mode 100644 index 0000000..1ea418e --- /dev/null +++ b/internal/remote/endpoint_test.go @@ -0,0 +1,207 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package remote + +import ( + "bytes" + "log/slog" + "strings" + "testing" + + "github.com/godbus/dbus/v5" +) + +func TestEndpointDiagnosticsDoNotLogRequestContents(t *testing.T) { + const private = "Private game text 7a9e" + var output bytes.Buffer + logger := slog.New(slog.NewJSONHandler(&output, &slog.HandlerOptions{Level: slog.LevelDebug})) + endpoint := newEndpoint(logger, &recordingHandler{result: true}, func(dbus.Sender) bool { return true }) + endpoint.startAccepting() + sender := dbus.Sender(":1.5") + endpoint.PresentMessage(sender, private) + endpoint.SpeakText(sender, private, true) + endpoint.BrailleMessage(sender, private) + endpoint.SpeakSsml(sender, private, private) + endpoint.PresentAccessibleEvent(sender, private, private, private, private, private, + private, private, 1, 1, private) + if strings.Contains(output.String(), private) { + t.Fatalf("debug diagnostics exposed request text: %q", output.String()) + } + if !strings.Contains(output.String(), `"method":"PresentAccessibleEvent"`) { + t.Fatalf("debug diagnostics lost method outcome: %q", output.String()) + } +} + +func TestEndpointDispatchesSpeechMethods(t *testing.T) { + handler := &recordingHandler{result: true} + endpoint := authorizedEndpoint(handler) + sender := dbus.Sender(":1.5") + + if accepted, err := endpoint.PresentMessage(sender, "Status"); err != nil || !accepted { + t.Fatalf("PresentMessage = (%v, %v), want (true, nil)", accepted, err) + } + if accepted, err := endpoint.SpeakText(sender, "Queued", false); err != nil || !accepted { + t.Fatalf("SpeakText queued = (%v, %v), want (true, nil)", accepted, err) + } + if accepted, err := endpoint.SpeakText(sender, "Now", true); err != nil || !accepted { + t.Fatalf("SpeakText interrupting = (%v, %v), want (true, nil)", accepted, err) + } + if accepted, err := endpoint.CancelSpeech(sender); err != nil || !accepted { + t.Fatalf("CancelSpeech = (%v, %v), want (true, nil)", accepted, err) + } + if accepted, err := endpoint.PresentAccessibleEvent(sender, "42:0:0", "focus", "Start", "button", "", "", "", 1, 3, "Game"); err != nil || !accepted { + t.Fatalf("PresentAccessibleEvent = (%v, %v), want (true, nil)", accepted, err) + } + + handler.mutex.Lock() + defer handler.mutex.Unlock() + if got := strings.Join(handler.presented, ","); got != "Status" { + t.Fatalf("presented = %q, want Status", got) + } + if got := strings.Join(handler.spoken, ","); got != "Queued,Now" { + t.Fatalf("spoken = %q, want Queued,Now", got) + } + if len(handler.interrupts) != 2 || handler.interrupts[0] || !handler.interrupts[1] { + t.Fatalf("interrupts = %v, want [false true]", handler.interrupts) + } + if handler.canceled != 1 { + t.Fatalf("canceled = %d, want 1", handler.canceled) + } + if len(handler.wine) != 1 || handler.wine[0].Name != "Start" || handler.wine[0].Count != 3 { + t.Fatalf("wine event = %+v", handler.wine) + } +} + +func TestEndpointLogsMethodsAndOutcomes(t *testing.T) { + var output bytes.Buffer + logger := slog.New(slog.NewTextHandler(&output, &slog.HandlerOptions{Level: slog.LevelDebug})) + endpoint := newEndpoint(logger, &recordingHandler{result: true}, func(dbus.Sender) bool { return true }) + endpoint.startAccepting() + + if accepted, err := endpoint.SpeakText(dbus.Sender(":1.9"), "Prism message", true); err != nil || !accepted { + t.Fatalf("SpeakText = (%v, %v), want (true, nil)", accepted, err) + } + if accepted, err := endpoint.PresentAccessibleEvent( + dbus.Sender(":1.9"), "window:1", "focus", "Start", "button", "Ready", "focused", "Description", 1, 3, "Game", + ); err != nil || !accepted { + t.Fatalf("PresentAccessibleEvent = (%v, %v), want (true, nil)", accepted, err) + } + + logged := output.String() + for _, expected := range []string{ + "method=SpeakText", + "method=PresentAccessibleEvent", + "result=true", + } { + if !strings.Contains(logged, expected) { + t.Fatalf("debug log missing %q:\n%s", expected, logged) + } + } + for _, private := range []string{"Prism message", "Start", "Ready", "Description"} { + if strings.Contains(logged, private) { + t.Fatalf("debug log exposed %q:\n%s", private, logged) + } + } +} + +func TestEndpointRejectsUnavailableInvalidAndOversizedRequests(t *testing.T) { + handler := &recordingHandler{result: false} + endpoint := authorizedEndpoint(handler) + sender := dbus.Sender(":1.6") + + if accepted, _ := endpoint.BrailleMessage(sender, "Braille"); accepted { + t.Fatal("BrailleMessage succeeded without a braille backend") + } + if accepted, _ := endpoint.SpeakText(sender, "", false); accepted { + t.Fatal("SpeakText accepted empty text") + } + if accepted, _ := endpoint.SpeakText(sender, strings.Repeat("x", maxTextBytes+1), false); accepted { + t.Fatal("SpeakText accepted oversized text") + } + + handler.mutex.Lock() + defer handler.mutex.Unlock() + if len(handler.spoken) != 0 { + t.Fatalf("invalid speech reached handler: %v", handler.spoken) + } + if got := strings.Join(handler.braille, ","); got != "Braille" { + t.Fatalf("braille handler calls = %q, want Braille", got) + } +} + +func TestEndpointRejectsUnauthorizedAndStoppedCalls(t *testing.T) { + handler := &recordingHandler{result: true} + endpoint := newEndpoint(slog.New(slog.DiscardHandler), handler, func(dbus.Sender) bool { return false }) + endpoint.startAccepting() + if accepted, err := endpoint.SpeakText(dbus.Sender(":1.7"), "Private", false); accepted || err == nil || err.Name != "org.freedesktop.DBus.Error.AccessDenied" { + t.Fatalf("SpeakText = (%v, %v), want access denied", accepted, err) + } + idle := endpoint.stopAccepting() + select { + case <-idle: + default: + t.Fatal("idle endpoint did not stop immediately") + } + if accepted, err := endpoint.CancelSpeech(dbus.Sender(":1.7")); accepted || err == nil || err.Name != "org.stormux.Cthulhu1.Error.Unavailable" { + t.Fatalf("CancelSpeech = (%v, %v), want unavailable", accepted, err) + } +} + +func TestSpeakSsmlMatchesUnsupportedCompatibilityContract(t *testing.T) { + endpoint := authorizedEndpoint(&recordingHandler{result: true}) + sender := dbus.Sender(":1.8") + tests := []struct { + name string + ssml string + want int32 + }{ + {name: "valid", ssml: `Hello`, want: windowsErrorNotSupported}, + {name: "namespace", ssml: `Hello`, want: windowsErrorNotSupported}, + {name: "malformed", ssml: ``, want: windowsErrorInvalidParameter}, + {name: "wrong root", ssml: `Hello`, want: windowsErrorInvalidParameter}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := endpoint.SpeakSsml(sender, "request", test.ssml) + if err != nil || got != test.want { + t.Fatalf("SpeakSsml = (%d, %v), want (%d, nil)", got, err, test.want) + } + }) + } +} + +func TestSpeechManagerAuthorizationAndShutdown(t *testing.T) { + handler := &recordingHandler{result: true} + endpoint := newEndpoint(nil, handler, func(dbus.Sender) bool { return false }) + endpoint.startAccepting() + manager := &speechManagerEndpoint{endpoint: endpoint} + if accepted, err := manager.InterruptSpeech(":1.5", true); accepted || err == nil || err.Name != "org.freedesktop.DBus.Error.AccessDenied" { + t.Fatalf("unauthorized InterruptSpeech: accepted=%v error=%v", accepted, err) + } + endpoint.authorize = func(dbus.Sender) bool { return true } + if accepted, err := manager.InterruptSpeech(":1.5", false); !accepted || err != nil { + t.Fatalf("authorized call: %v, %v", accepted, err) + } + <-endpoint.stopAccepting() + if accepted, err := manager.InterruptSpeech(":1.5", true); accepted || err == nil { + t.Fatal("call accepted after shutdown") + } + if handler.canceled != 1 { + t.Fatalf("cancellations = %d", handler.canceled) + } +} diff --git a/internal/remote/introspection.go b/internal/remote/introspection.go new file mode 100644 index 0000000..0da3c96 --- /dev/null +++ b/internal/remote/introspection.go @@ -0,0 +1,59 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +// Package remote publishes Cthulhu's bounded self-voice D-Bus API. +package remote + +import ( + "github.com/godbus/dbus/v5/introspect" +) + +func introspectionMethods() []introspect.Method { + return serviceMethods(false) +} + +func serviceMethods(orca bool) []introspect.Method { + methods := []introspect.Method{ + {Name: "ShowPreferences", Args: []introspect.Arg{{Name: "accepted", Type: "b", Direction: "out"}}}, + {Name: "GetVersion", Args: []introspect.Arg{{Name: "version", Type: "s", Direction: "out"}}}, + {Name: "Quit", Args: []introspect.Arg{{Name: "accepted", Type: "b", Direction: "out"}}}, + {Name: "PresentMessage", Args: []introspect.Arg{{Name: "message", Type: "s", Direction: "in"}, {Name: "accepted", Type: "b", Direction: "out"}}}, + } + if orca { + return append(methods, introspect.Method{Name: "ListModules", Args: []introspect.Arg{{Name: "modules", Type: "as", Direction: "out"}}}, introspect.Method{Name: "ListCommands", Args: []introspect.Arg{{Name: "commands", Type: "a(ss)", Direction: "out"}}}) + } + return append(methods, + introspect.Method{Name: "RegisterWineReviewProvider", Args: []introspect.Arg{{Name: "path", Type: "o", Direction: "in"}, {Name: "version", Type: "u", Direction: "in"}, {Name: "accepted", Type: "b", Direction: "out"}}}, + introspect.Method{Name: "PresentWineReviewFocus", Args: []introspect.Arg{ + {Name: "instance", Type: "s", Direction: "in"}, {Name: "window", Type: "s", Direction: "in"}, {Name: "focus", Type: "s", Direction: "in"}, {Name: "revision", Type: "t", Direction: "in"}, + {Name: "title", Type: "s", Direction: "in"}, {Name: "role", Type: "s", Direction: "in"}, {Name: "protected", Type: "b", Direction: "in"}, {Name: "bounds", Type: "(iiii)", Direction: "in"}, {Name: "accepted", Type: "b", Direction: "out"}, + }}, + introspect.Method{Name: "GetRuntimeStateSnapshot", Args: []introspect.Arg{{Name: "snapshot", Type: "s", Direction: "out"}}}, + introspect.Method{Name: "SpeakText", Args: []introspect.Arg{{Name: "text", Type: "s", Direction: "in"}, {Name: "interrupt", Type: "b", Direction: "in"}, {Name: "accepted", Type: "b", Direction: "out"}}}, + introspect.Method{Name: "BrailleMessage", Args: []introspect.Arg{{Name: "text", Type: "s", Direction: "in"}, {Name: "accepted", Type: "b", Direction: "out"}}}, + introspect.Method{Name: "CancelSpeech", Args: []introspect.Arg{{Name: "accepted", Type: "b", Direction: "out"}}}, + introspect.Method{Name: "SpeakSsml", Args: []introspect.Arg{{Name: "requestId", Type: "s", Direction: "in"}, {Name: "ssml", Type: "s", Direction: "in"}, {Name: "result", Type: "i", Direction: "out"}}}, + introspect.Method{Name: "PresentAccessibleEvent", Args: []introspect.Arg{ + {Name: "sourceId", Type: "s", Direction: "in"}, {Name: "eventType", Type: "s", Direction: "in"}, + {Name: "name", Type: "s", Direction: "in"}, {Name: "role", Type: "s", Direction: "in"}, + {Name: "value", Type: "s", Direction: "in"}, {Name: "states", Type: "s", Direction: "in"}, + {Name: "description", Type: "s", Direction: "in"}, {Name: "position", Type: "i", Direction: "in"}, + {Name: "count", Type: "i", Direction: "in"}, {Name: "windowTitle", Type: "s", Direction: "in"}, + {Name: "accepted", Type: "b", Direction: "out"}, + }}, + ) +} diff --git a/internal/remote/modules.go b/internal/remote/modules.go new file mode 100644 index 0000000..d4d5d27 --- /dev/null +++ b/internal/remote/modules.go @@ -0,0 +1,386 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package remote + +import ( + "fmt" + "sort" + + "github.com/godbus/dbus/v5" + "github.com/godbus/dbus/v5/introspect" +) + +const ( + typingEchoInterface = "org.stormux.Cthulhu1.TypingEchoManager" + orcaModuleInterface = "org.gnome.Orca.Module" +) + +// ModuleHandler is implemented by the runtime settings and command owners. +// The remote layer never changes a settings snapshot directly. +type ModuleHandler interface { + RemoteGet(module, property string) (dbus.Variant, bool) + RemoteSet(module, property string, value dbus.Variant) bool + RemoteCommand(module, command string, notify bool) bool +} + +// ModuleAvailability lets a handler suppress modules until its settings owner +// is wired. Handlers without this method are expected to provide their own +// complete module implementation. +type ModuleAvailability interface{ RemoteModulesAvailable() bool } + +type propertySpec struct { + name, signature string + writable bool +} +type commandSpec struct{ name, description string } +type moduleSpec struct { + name string + properties []propertySpec + commands []commandSpec +} + +var modules = []moduleSpec{ + {name: "SpeechManager", properties: []propertySpec{ + {"CurrentServer", "s", false}, {"AvailableServers", "as", false}, + {"CurrentSynthesizer", "s", true}, {"CurrentVoice", "s", true}, + {"Rate", "i", true}, {"Pitch", "d", true}, {"Volume", "d", true}, + {"SpeechIsEnabled", "b", false}, {"PunctuationLevel", "s", true}, + {"CapitalizationStyle", "s", true}, {"SpeakDescription", "b", true}, + {"SpeakRowInGuiTable", "b", true}, + }, commands: []commandSpec{ + {"SelectPreviousSpeechSetting", "Selects the previous speech setting."}, + {"SelectNextSpeechSetting", "Selects the next speech setting."}, + {"DecreaseCurrentSpeechSetting", "Decreases the selected speech setting."}, + {"IncreaseCurrentSpeechSetting", "Increases the selected speech setting."}, + {"SaveSpeechSettings", "Saves the current speech settings."}, + {"InterruptSpeech", "Stops current speech."}, + {"DecreaseRate", "Decreases speech rate."}, {"IncreaseRate", "Increases speech rate."}, + {"DecreasePitch", "Decreases speech pitch."}, {"IncreasePitch", "Increases speech pitch."}, + {"DecreaseVolume", "Decreases speech volume."}, {"IncreaseVolume", "Increases speech volume."}, + }}, + {name: "TypingEchoManager", properties: []propertySpec{ + {"KeyEchoEnabled", "b", true}, {"CharacterEchoEnabled", "b", true}, + {"WordEchoEnabled", "b", true}, {"SentenceEchoEnabled", "b", true}, + {"AlphabeticKeysEnabled", "b", true}, {"NumericKeysEnabled", "b", true}, + {"PunctuationKeysEnabled", "b", true}, {"SpaceEnabled", "b", true}, + {"ModifierKeysEnabled", "b", true}, {"FunctionKeysEnabled", "b", true}, + {"ActionKeysEnabled", "b", true}, {"NavigationKeysEnabled", "b", true}, + {"DiacriticalKeysEnabled", "b", true}, + }, commands: []commandSpec{{"CycleKeyEcho", "Cycles typing echo mode."}}}, +} + +func modulePath(base dbus.ObjectPath, name string) dbus.ObjectPath { + return dbus.ObjectPath(string(base) + "/" + name) +} + +func moduleFor(name string) *moduleSpec { + for i := range modules { + if modules[i].name == name { + return &modules[i] + } + } + return nil +} + +func (spec moduleSpec) property(name string) (propertySpec, bool) { + for _, item := range spec.properties { + if item.name == name { + return item, true + } + } + return propertySpec{}, false +} + +func (spec moduleSpec) command(name string) bool { + for _, item := range spec.commands { + if item.name == name { + return true + } + } + return false +} + +func (spec moduleSpec) introspection(orca bool) introspect.Interface { + iface := "org.stormux.Cthulhu1." + spec.name + if orca { + iface = orcaModuleInterface + } + result := introspect.Interface{Name: iface} + if orca { + result.Methods = orcaModuleMethods() + } else { + for _, command := range spec.commands { + result.Methods = append(result.Methods, introspect.Method{Name: command.name, Args: []introspect.Arg{ + {Name: "notify_user", Type: "b", Direction: "in"}, {Name: "accepted", Type: "b", Direction: "out"}, + }}) + } + for _, property := range spec.properties { + access := "read" + if property.writable { + access = "readwrite" + } + result.Properties = append(result.Properties, introspect.Property{Name: property.name, Type: property.signature, Access: access}) + } + } + return result +} + +func orcaModuleMethods() []introspect.Method { + return []introspect.Method{ + {Name: "ExecuteRuntimeGetter", Args: []introspect.Arg{{Name: "getter_name", Type: "s", Direction: "in"}, {Name: "value", Type: "v", Direction: "out"}}}, + {Name: "ExecuteRuntimeSetter", Args: []introspect.Arg{{Name: "setter_name", Type: "s", Direction: "in"}, {Name: "value", Type: "v", Direction: "in"}, {Name: "accepted", Type: "b", Direction: "out"}}}, + {Name: "ExecuteCommand", Args: []introspect.Arg{{Name: "command_name", Type: "s", Direction: "in"}, {Name: "notify_user", Type: "b", Direction: "in"}, {Name: "accepted", Type: "b", Direction: "out"}}}, + {Name: "ListCommands", Args: []introspect.Arg{{Name: "commands", Type: "a(ss)", Direction: "out"}}}, + {Name: "ListRuntimeGetters", Args: []introspect.Arg{{Name: "getters", Type: "a(ss)", Direction: "out"}}}, + {Name: "ListRuntimeSetters", Args: []introspect.Arg{{Name: "setters", Type: "a(ss)", Direction: "out"}}}, + {Name: "ListParameterizedCommands", Args: []introspect.Arg{{Name: "commands", Type: "a(ssa(ss))", Direction: "out"}}}, + {Name: "ExecuteParameterizedCommand", Args: []introspect.Arg{{Name: "command_name", Type: "s", Direction: "in"}, {Name: "parameters", Type: "a{sv}", Direction: "in"}, {Name: "notify_user", Type: "b", Direction: "in"}, {Name: "result", Type: "v", Direction: "out"}}}, + } +} + +type namedDescription struct{ Name, Description string } +type parameterizedDescription struct { + Name, Description string + Parameters []namedDescription +} + +type moduleEndpoint struct { + endpoint *endpoint + spec moduleSpec +} + +func (module *moduleEndpoint) control() ModuleHandler { + handler, _ := module.endpoint.handler.(ModuleHandler) + return handler +} + +func unsupported(message string) *dbus.Error { + return &dbus.Error{Name: "org.freedesktop.DBus.Error.NotSupported", Body: []any{message}} +} + +func (module *moduleEndpoint) ExecuteRuntimeGetter(sender dbus.Sender, name string) (dbus.Variant, *dbus.Error) { + if err := module.endpoint.begin(sender, "ExecuteRuntimeGetter"); err != nil { + return dbus.Variant{}, err + } + defer module.endpoint.end() + if len(name) > 256 { + return dbus.Variant{}, unsupported("getter name is too long") + } + if _, ok := module.spec.property(name); !ok || module.control() == nil { + return dbus.Variant{}, unsupported("getter is unavailable") + } + if value, ok := module.control().RemoteGet(module.spec.name, name); ok { + return value, nil + } + return dbus.Variant{}, unsupported("getter is unavailable") +} + +func (module *moduleEndpoint) ExecuteRuntimeSetter(sender dbus.Sender, name string, value dbus.Variant) (bool, *dbus.Error) { + if err := module.endpoint.begin(sender, "ExecuteRuntimeSetter"); err != nil { + return false, err + } + defer module.endpoint.end() + property, ok := module.spec.property(name) + if !ok || !property.writable || module.control() == nil { + return false, unsupported("setter is unavailable") + } + if value.Signature().String() != property.signature { + return false, &dbus.Error{Name: "org.freedesktop.DBus.Error.InvalidArgs", Body: []any{"property type mismatch"}} + } + return module.control().RemoteSet(module.spec.name, name, value), nil +} + +func (module *moduleEndpoint) ExecuteCommand(sender dbus.Sender, name string, notify bool) (bool, *dbus.Error) { + if err := module.endpoint.begin(sender, "ExecuteCommand"); err != nil { + return false, err + } + defer module.endpoint.end() + if !module.spec.command(name) || module.control() == nil { + return false, unsupported("command is unavailable") + } + return module.control().RemoteCommand(module.spec.name, name, notify), nil +} + +func (module *moduleEndpoint) ListCommands(sender dbus.Sender) ([]namedDescription, *dbus.Error) { + if err := module.endpoint.begin(sender, "ListCommands"); err != nil { + return nil, err + } + defer module.endpoint.end() + list := make([]namedDescription, 0, len(module.spec.commands)) + for _, item := range module.spec.commands { + list = append(list, namedDescription{item.name, item.description}) + } + return list, nil +} +func (module *moduleEndpoint) ListRuntimeGetters(sender dbus.Sender) ([]namedDescription, *dbus.Error) { + if err := module.endpoint.begin(sender, "ListRuntimeGetters"); err != nil { + return nil, err + } + defer module.endpoint.end() + list := make([]namedDescription, 0, len(module.spec.properties)) + for _, item := range module.spec.properties { + list = append(list, namedDescription{item.name, "Returns " + item.name + "."}) + } + return list, nil +} +func (module *moduleEndpoint) ListRuntimeSetters(sender dbus.Sender) ([]namedDescription, *dbus.Error) { + if err := module.endpoint.begin(sender, "ListRuntimeSetters"); err != nil { + return nil, err + } + defer module.endpoint.end() + list := []namedDescription{} + for _, item := range module.spec.properties { + if item.writable { + list = append(list, namedDescription{item.name, "Sets " + item.name + " for this session."}) + } + } + return list, nil +} +func (module *moduleEndpoint) ListParameterizedCommands(sender dbus.Sender) ([]parameterizedDescription, *dbus.Error) { + if err := module.endpoint.begin(sender, "ListParameterizedCommands"); err != nil { + return nil, err + } + defer module.endpoint.end() + return []parameterizedDescription{}, nil +} +func (module *moduleEndpoint) ExecuteParameterizedCommand(sender dbus.Sender, _ string, _ map[string]dbus.Variant, _ bool) (dbus.Variant, *dbus.Error) { + if err := module.endpoint.begin(sender, "ExecuteParameterizedCommand"); err != nil { + return dbus.Variant{}, err + } + defer module.endpoint.end() + return dbus.Variant{}, unsupported("parameterized command is unavailable") +} + +type modulePropertiesEndpoint struct { + module *moduleEndpoint + iface string +} + +func (properties *modulePropertiesEndpoint) Get(sender dbus.Sender, iface, name string) (dbus.Variant, *dbus.Error) { + module := properties.module + if err := module.endpoint.begin(sender, "Properties.Get"); err != nil { + return dbus.Variant{}, err + } + defer module.endpoint.end() + if iface != properties.iface { + return dbus.Variant{}, &dbus.Error{Name: "org.freedesktop.DBus.Error.UnknownInterface", Body: []any{iface}} + } + if _, ok := module.spec.property(name); !ok { + return dbus.Variant{}, &dbus.Error{Name: "org.freedesktop.DBus.Error.UnknownProperty", Body: []any{name}} + } + if module.control() == nil { + return dbus.Variant{}, unsupported("property is unavailable") + } + value, ok := module.control().RemoteGet(module.spec.name, name) + if !ok { + return dbus.Variant{}, unsupported("property is unavailable") + } + return value, nil +} +func (properties *modulePropertiesEndpoint) Set(sender dbus.Sender, iface, name string, value dbus.Variant) *dbus.Error { + module := properties.module + if err := module.endpoint.begin(sender, "Properties.Set"); err != nil { + return err + } + defer module.endpoint.end() + if iface != properties.iface { + return &dbus.Error{Name: "org.freedesktop.DBus.Error.UnknownInterface", Body: []any{iface}} + } + property, ok := module.spec.property(name) + if !ok { + return &dbus.Error{Name: "org.freedesktop.DBus.Error.UnknownProperty", Body: []any{name}} + } + if !property.writable { + return &dbus.Error{Name: "org.freedesktop.DBus.Error.PropertyReadOnly", Body: []any{name}} + } + if value.Signature().String() != property.signature { + return &dbus.Error{Name: "org.freedesktop.DBus.Error.InvalidArgs", Body: []any{fmt.Sprintf("%s requires %s", name, property.signature)}} + } + if module.control() == nil || !module.control().RemoteSet(module.spec.name, name, value) { + return unsupported("setting was not applied") + } + return nil +} +func (properties *modulePropertiesEndpoint) GetAll(sender dbus.Sender, iface string) (map[string]dbus.Variant, *dbus.Error) { + module := properties.module + if err := module.endpoint.begin(sender, "Properties.GetAll"); err != nil { + return nil, err + } + defer module.endpoint.end() + if iface != properties.iface { + return nil, &dbus.Error{Name: "org.freedesktop.DBus.Error.UnknownInterface", Body: []any{iface}} + } + values := make(map[string]dbus.Variant) + if module.control() == nil { + return nil, unsupported("properties are unavailable") + } + for _, property := range module.spec.properties { + if value, ok := module.control().RemoteGet(module.spec.name, property.name); ok { + values[property.name] = value + } + } + return values, nil +} + +func sortedModuleNames() []string { + names := make([]string, 0, len(modules)) + for _, module := range modules { + names = append(names, module.name) + } + sort.Strings(names) + return names +} + +func nativeCommand(endpoint *endpoint, module, name string, sender dbus.Sender, notify bool) (bool, *dbus.Error) { + if err := endpoint.begin(sender, name); err != nil { + return false, err + } + defer endpoint.end() + handler, ok := endpoint.handler.(ModuleHandler) + if !ok { + return false, unsupported("command is unavailable") + } + return handler.RemoteCommand(module, name, notify), nil +} + +func (manager *speechManagerEndpoint) SelectPreviousSpeechSetting(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "SelectPreviousSpeechSetting", sender, notify) +} +func (manager *speechManagerEndpoint) SelectNextSpeechSetting(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "SelectNextSpeechSetting", sender, notify) +} +func (manager *speechManagerEndpoint) DecreaseCurrentSpeechSetting(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "DecreaseCurrentSpeechSetting", sender, notify) +} +func (manager *speechManagerEndpoint) IncreaseCurrentSpeechSetting(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "IncreaseCurrentSpeechSetting", sender, notify) +} +func (manager *speechManagerEndpoint) SaveSpeechSettings(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "SaveSpeechSettings", sender, notify) +} +func (manager *speechManagerEndpoint) DecreaseRate(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "DecreaseRate", sender, notify) +} +func (manager *speechManagerEndpoint) IncreaseRate(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "IncreaseRate", sender, notify) +} +func (manager *speechManagerEndpoint) DecreasePitch(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "DecreasePitch", sender, notify) +} +func (manager *speechManagerEndpoint) IncreasePitch(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "IncreasePitch", sender, notify) +} +func (manager *speechManagerEndpoint) DecreaseVolume(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "DecreaseVolume", sender, notify) +} +func (manager *speechManagerEndpoint) IncreaseVolume(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "SpeechManager", "IncreaseVolume", sender, notify) +} + +type typingEchoEndpoint struct{ endpoint *endpoint } + +func (manager *typingEchoEndpoint) CycleKeyEcho(sender dbus.Sender, notify bool) (bool, *dbus.Error) { + return nativeCommand(manager.endpoint, "TypingEchoManager", "CycleKeyEcho", sender, notify) +} diff --git a/internal/remote/modules_test.go b/internal/remote/modules_test.go new file mode 100644 index 0000000..4a88812 --- /dev/null +++ b/internal/remote/modules_test.go @@ -0,0 +1,239 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package remote + +import ( + "context" + "log/slog" + "os" + "strings" + "testing" + + "github.com/godbus/dbus/v5" +) + +type moduleRecordingHandler struct { + recordingHandler + value bool + command string + preferencesShown bool + quitRequested bool +} + +func (handler *moduleRecordingHandler) ShowPreferences() bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.preferencesShown = true + return true +} +func (handler *moduleRecordingHandler) Quit() bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.quitRequested = true + return true +} +func (handler *moduleRecordingHandler) RuntimeStateSnapshot() string { + return "CTHULHU RUNTIME STATE SNAPSHOT\n[event_manager]\noverflow: 0" +} + +func (handler *moduleRecordingHandler) RemoteGet(module, property string) (dbus.Variant, bool) { + if module == "TypingEchoManager" && property == "KeyEchoEnabled" { + handler.mutex.Lock() + defer handler.mutex.Unlock() + return dbus.MakeVariant(handler.value), true + } + return dbus.Variant{}, false +} +func (handler *moduleRecordingHandler) RemoteSet(module, property string, value dbus.Variant) bool { + if module != "TypingEchoManager" || property != "KeyEchoEnabled" { + return false + } + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.value = value.Value().(bool) + return true +} +func (handler *moduleRecordingHandler) RemoteCommand(module, command string, _ bool) bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.command = module + "." + command + return true +} + +func TestNativeAndOrcaModuleBus(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" { + t.Skip("set CTHULHU_NATIVE_DBUS_TEST=1 inside a private session bus") + } + handler := &moduleRecordingHandler{recordingHandler: recordingHandler{result: true}} + logger := slog.New(slog.DiscardHandler) + native := New(logger, handler) + orca := NewOrca(logger, handler) + if err := native.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { native.Stop(context.Background()) }) + if err := orca.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { orca.Stop(context.Background()) }) + client, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + defer client.Close() + for _, test := range []struct { + name string + path dbus.ObjectPath + iface string + }{ + {BusName, ObjectPath, InterfaceName}, {OrcaBusName, OrcaObjectPath, OrcaInterfaceName}, + } { + object := client.Object(test.name, test.path) + var version string + if err := object.Call(test.iface+".GetVersion", 0).Store(&version); err != nil || !strings.Contains(version, "Cthulhu") { + t.Fatalf("GetVersion: %q, %v", version, err) + } + var accepted bool + if err := object.Call(test.iface+".ShowPreferences", 0).Store(&accepted); err != nil || !accepted { + t.Fatalf("ShowPreferences: %v, %v", accepted, err) + } + if err := object.Call(test.iface+".Quit", 0).Store(&accepted); err != nil || !accepted { + t.Fatalf("Quit: %v, %v", accepted, err) + } + } + var speechXML string + if err := client.Object(BusName, SpeechManagerPath).Call("org.freedesktop.DBus.Introspectable.Introspect", 0).Store(&speechXML); err != nil { + t.Fatal(err) + } + for _, signature := range []string{`property name="Rate" type="i" access="readwrite"`, `property name="Pitch" type="d" access="readwrite"`, `method name="IncreaseRate"`} { + if !strings.Contains(speechXML, signature) { + t.Fatalf("speech introspection missing %s: %s", signature, speechXML) + } + } + handler.mutex.Lock() + shown, quit := handler.preferencesShown, handler.quitRequested + handler.mutex.Unlock() + if !shown || !quit { + t.Fatal("control calls did not reach runtime owner") + } + var snapshot string + if err := client.Object(BusName, ObjectPath).Call(InterfaceName+".GetRuntimeStateSnapshot", 0).Store(&snapshot); err != nil || !strings.Contains(snapshot, "RUNTIME STATE SNAPSHOT") { + t.Fatalf("snapshot = %q, %v", snapshot, err) + } + + for _, test := range []struct { + name string + path dbus.ObjectPath + iface string + }{ + {BusName, modulePath(ObjectPath, "TypingEchoManager"), typingEchoInterface}, + {OrcaBusName, modulePath(OrcaObjectPath, "TypingEchoManager"), orcaModuleInterface}, + } { + object := client.Object(test.name, test.path) + var xml string + if err := object.Call("org.freedesktop.DBus.Introspectable.Introspect", 0).Store(&xml); err != nil { + t.Fatal(err) + } + if !strings.Contains(xml, `name="`+test.iface+`"`) { + t.Fatalf("missing interface %s in %s", test.iface, xml) + } + if test.name == BusName { + if !strings.Contains(xml, `property name="KeyEchoEnabled" type="b" access="readwrite"`) { + t.Fatalf("missing property: %s", xml) + } + if !strings.Contains(xml, `method name="CycleKeyEcho"`) { + t.Fatalf("missing command: %s", xml) + } + } else if !strings.Contains(xml, `method name="ExecuteRuntimeSetter"`) { + t.Fatalf("missing generic protocol: %s", xml) + } + } + + nativeObject := client.Object(BusName, modulePath(ObjectPath, "TypingEchoManager")) + var value dbus.Variant + if err := nativeObject.Call("org.freedesktop.DBus.Properties.Get", 0, typingEchoInterface, "KeyEchoEnabled").Store(&value); err != nil { + t.Fatal(err) + } + if value.Value() != false { + t.Fatalf("initial value = %v", value) + } + if err := nativeObject.Call("org.freedesktop.DBus.Properties.Set", 0, typingEchoInterface, "KeyEchoEnabled", dbus.MakeVariant(true)).Err; err != nil { + t.Fatal(err) + } + handler.mutex.Lock() + gotValue := handler.value + handler.mutex.Unlock() + if !gotValue { + t.Fatal("native setter did not reach runtime owner") + } + if err := nativeObject.Call("org.freedesktop.DBus.Properties.Set", 0, typingEchoInterface, "KeyEchoEnabled", dbus.MakeVariant("wrong type")).Err; err == nil { + t.Fatal("wrong type accepted") + } + + orcaObject := client.Object(OrcaBusName, modulePath(OrcaObjectPath, "TypingEchoManager")) + if err := orcaObject.Call(orcaModuleInterface+".ExecuteRuntimeGetter", 0, "KeyEchoEnabled").Store(&value); err != nil { + t.Fatal(err) + } + if value.Value() != true { + t.Fatalf("Orca getter = %v", value) + } + var accepted bool + if err := orcaObject.Call(orcaModuleInterface+".ExecuteRuntimeSetter", 0, "KeyEchoEnabled", dbus.MakeVariant(false)).Store(&accepted); err != nil || !accepted { + t.Fatalf("Orca setter = %v, %v", accepted, err) + } + if err := orcaObject.Call(orcaModuleInterface+".ExecuteCommand", 0, "CycleKeyEcho", true).Store(&accepted); err != nil || !accepted { + t.Fatalf("Orca command = %v, %v", accepted, err) + } + handler.mutex.Lock() + gotCommand := handler.command + handler.mutex.Unlock() + if gotCommand != "TypingEchoManager.CycleKeyEcho" { + t.Fatalf("command owner got %q", gotCommand) + } + if err := orcaObject.Call(orcaModuleInterface+".ExecuteCommand", 0, "Unsupported", true).Err; err == nil { + t.Fatal("unsupported command falsely succeeded") + } + + var names []string + if err := client.Object(OrcaBusName, OrcaObjectPath).Call(OrcaInterfaceName+".ListModules", 0).Store(&names); err != nil { + t.Fatal(err) + } + if strings.Join(names, ",") != "SpeechManager,TypingEchoManager" { + t.Fatalf("modules = %v", names) + } + var commands []namedDescription + if err := client.Object(OrcaBusName, OrcaObjectPath).Call(OrcaInterfaceName+".ListCommands", 0).Store(&commands); err != nil || len(commands) != 6 { + t.Fatalf("service commands = %v, %v", commands, err) + } + if err := orcaObject.Call(orcaModuleInterface+".ListRuntimeGetters", 0).Store(&commands); err != nil || len(commands) != 13 { + t.Fatalf("module getters = %v, %v", commands, err) + } + var parameterized []parameterizedDescription + if err := orcaObject.Call(orcaModuleInterface+".ListParameterizedCommands", 0).Store(¶meterized); err != nil || len(parameterized) != 0 { + t.Fatalf("parameterized commands = %v, %v", parameterized, err) + } + var result dbus.Variant + if err := orcaObject.Call(orcaModuleInterface+".ExecuteParameterizedCommand", 0, "Unsupported", map[string]dbus.Variant{}, false).Store(&result); err == nil { + t.Fatal("unsupported parameterized command falsely succeeded") + } + conflict := NewOrca(logger, handler) + if err := conflict.Start(context.Background()); err == nil { + conflict.Stop(context.Background()) + t.Fatal("second Orca name acquired") + } + if err := orca.Stop(context.Background()); err != nil { + t.Fatal(err) + } + if err := nativeObject.Call("org.freedesktop.DBus.Properties.Get", 0, typingEchoInterface, "KeyEchoEnabled").Store(&value); err != nil { + t.Fatalf("native service lost when Orca stopped: %v", err) + } + replacement := NewOrca(logger, handler) + if err := replacement.Start(context.Background()); err != nil { + t.Fatalf("Orca name not reacquired: %v", err) + } + if err := replacement.Stop(context.Background()); err != nil { + t.Fatal(err) + } +} diff --git a/internal/remote/registrations.go b/internal/remote/registrations.go new file mode 100644 index 0000000..d0af0ed --- /dev/null +++ b/internal/remote/registrations.go @@ -0,0 +1,85 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package remote + +import "github.com/godbus/dbus/v5/introspect" + +// service_bindings builds exports in their existing registration order. Start +// performs exports and rollback; Stop reverses this list before releasing names. +func service_bindings(endpoint *endpoint, orca bool, handler Handler) []serviceBinding { + path, iface := ObjectPath, InterfaceName + if orca { + path, iface = OrcaObjectPath, OrcaInterfaceName + } + var mainEndpoint any = endpoint + if orca { + mainEndpoint = &orcaServiceEndpoint{endpoint: endpoint} + } + registrations := []serviceBinding{ + {path, iface, mainEndpoint}, + {path, "org.freedesktop.DBus.Introspectable", introspect.NewIntrospectable(&introspect.Node{ + Name: string(path), + Interfaces: []introspect.Interface{{Name: iface, Methods: serviceMethods(orca)}}, + })}, + } + if !orca { + registrations[1].value = introspect.NewIntrospectable(&introspect.Node{ + Name: string(path), Interfaces: []introspect.Interface{{Name: iface, Methods: serviceMethods(false)}}, + Children: []introspect.Node{{Name: "SpeechManager"}}, + }) + registrations = append(registrations, serviceBinding{SpeechManagerPath, SpeechManagerInterface, &speechManagerEndpoint{endpoint: endpoint}}) + registrations = append(registrations, serviceBinding{SpeechManagerPath, "org.freedesktop.DBus.Introspectable", introspect.NewIntrospectable(&introspect.Node{ + Name: string(SpeechManagerPath), + Interfaces: []introspect.Interface{{Name: SpeechManagerInterface, Methods: []introspect.Method{ + {Name: "InterruptSpeech", Args: []introspect.Arg{ + {Name: "notify_user", Type: "b", Direction: "in"}, + {Name: "accepted", Type: "b", Direction: "out"}, + }}, + }}}, + })}) + } + _, hasModules := handler.(ModuleHandler) + if available, ok := handler.(ModuleAvailability); ok && !available.RemoteModulesAvailable() { + hasModules = false + } + if hasModules { + children := make([]introspect.Node, 0, len(modules)) + for _, spec := range modules { + module := &moduleEndpoint{endpoint: endpoint, spec: spec} + moduleObjectPath := modulePath(path, spec.name) + moduleIface := "org.stormux.Cthulhu1." + spec.name + var object any + if orca { + moduleIface = orcaModuleInterface + object = module + } else if spec.name == "SpeechManager" { + // SpeechManager was registered above for existing self-voice clients. + object = nil + } else { + object = &typingEchoEndpoint{endpoint: endpoint} + } + if object != nil { + registrations = append(registrations, serviceBinding{moduleObjectPath, moduleIface, object}) + } + registrations = append(registrations, serviceBinding{moduleObjectPath, "org.freedesktop.DBus.Properties", &modulePropertiesEndpoint{module: module, iface: moduleIface}}) + introspection := introspect.NewIntrospectable(&introspect.Node{ + Name: string(moduleObjectPath), Interfaces: []introspect.Interface{spec.introspection(orca)}, + }) + if !orca && spec.name == "SpeechManager" { + registrations[3].value = introspection + } else { + registrations = append(registrations, serviceBinding{moduleObjectPath, "org.freedesktop.DBus.Introspectable", introspection}) + } + children = append(children, introspect.Node{Name: spec.name}) + } + root := &introspect.Node{Name: string(path), Interfaces: []introspect.Interface{{Name: iface, Methods: serviceMethods(orca)}}, Children: children} + registrations[1].value = introspect.NewIntrospectable(root) + if orca { + registrations[0].value = &orcaServiceEndpoint{endpoint: endpoint, modules: sortedModuleNames()} + } + } + return registrations +} diff --git a/internal/remote/service.go b/internal/remote/service.go new file mode 100644 index 0000000..18b9d7b --- /dev/null +++ b/internal/remote/service.go @@ -0,0 +1,322 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +// Package remote publishes Cthulhu's bounded self-voice D-Bus API. +package remote + +import ( + "context" + "errors" + "fmt" + "log/slog" + "os" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/sessionbus" + "github.com/godbus/dbus/v5" +) + +const ( + BusName = "org.stormux.Cthulhu1.Service" + InterfaceName = "org.stormux.Cthulhu1.Service" + ObjectPath = dbus.ObjectPath("/org/stormux/Cthulhu1/Service") + + SpeechManagerInterface = "org.stormux.Cthulhu1.SpeechManager" + SpeechManagerPath = dbus.ObjectPath("/org/stormux/Cthulhu1/Service/SpeechManager") + OrcaBusName = "org.gnome.Orca.Service" + OrcaInterfaceName = "org.gnome.Orca.Service" + OrcaObjectPath = dbus.ObjectPath("/org/gnome/Orca/Service") + + maxTextBytes = 64 * 1024 + maxRequestIDBytes = 256 + authorizeTimeout = 500 * time.Millisecond + + windowsErrorNotSupported int32 = 50 + windowsErrorInvalidParameter int32 = 87 +) + +// Handler accepts already-authorized presentation requests. Implementations +// must return quickly and enqueue backend work rather than delivering it inline. +type Handler interface { + PresentMessage(string) bool + SpeakText(string, bool) bool + BrailleMessage(string) bool + CancelSpeech() bool + PresentAccessibleEvent(AccessibleEvent) bool +} + +// ControlHandler is optional so existing self-voice users keep their contract. +// Implementations enqueue commands with their existing owners and return promptly. +type ControlHandler interface { + ShowPreferences() bool + Quit() bool + RuntimeStateSnapshot() string +} + +// AccessibleEvent is the normalized, bounded Wine helper payload. It contains +// no native object references and is safe to hand to the presentation owner. +type AccessibleEvent struct { + SourceID, EventType, Name, Role, Value, States, Description, WindowTitle string + Position, Count int32 +} + +type connection interface { + Export(any, dbus.ObjectPath, string) error + RequestName(string, dbus.RequestNameFlags) (dbus.RequestNameReply, error) + ReleaseName(string) (dbus.ReleaseNameReply, error) + UnixUser(context.Context, string) (uint32, error) + Close() error +} + +type dbusConnection struct { + *dbus.Conn +} + +func (connection dbusConnection) UnixUser(ctx context.Context, sender string) (uint32, error) { + var uid uint32 + call := connection.BusObject().CallWithContext( + ctx, + "org.freedesktop.DBus.GetConnectionUnixUser", + 0, + sender, + ) + if err := call.Store(&uid); err != nil { + return 0, err + } + return uid, nil +} + +type connector func() (connection, error) + +// Service owns the session-bus connection, exported object, and well-known +// name. The lifecycle owner must call Stop before its Handler is stopped. +type Service struct { + logger *slog.Logger + handler Handler + connect connector + orca bool + + mutex sync.Mutex + connection connection + endpoint *endpoint + ownedName bool + bindings []serviceBinding +} + +type serviceBinding struct { + path dbus.ObjectPath + iface string + value any +} + +// NewOrca creates an independent compatibility service. A running Orca owns +// its name exclusively; a name conflict does not affect the native service. +func NewOrca(logger *slog.Logger, handler Handler) *Service { + service := New(logger, handler) + service.orca = true + return service +} + +func New(logger *slog.Logger, handler Handler) *Service { + return newService(logger, handler, func() (connection, error) { + connection, err := sessionbus.Connect(logger, "self-voice") + if err != nil { + return nil, err + } + return dbusConnection{Conn: connection}, nil + }) +} + +func newService(logger *slog.Logger, handler Handler, connect connector) *Service { + if logger == nil { + logger = slog.New(slog.DiscardHandler) + } + return &Service{logger: logger, handler: handler, connect: connect} +} + +func (service *Service) Start(ctx context.Context) error { + if ctx == nil { + return errors.New("remote service start requires a non-nil context") + } + if err := ctx.Err(); err != nil { + return fmt.Errorf("start remote service: %w", err) + } + if service.handler == nil { + return errors.New("start remote service without a handler") + } + + service.mutex.Lock() + defer service.mutex.Unlock() + if service.connection != nil { + return errors.New("remote service already started") + } + connection, err := service.connect() + if err != nil { + return fmt.Errorf("connect to session bus: %w", err) + } + endpoint := newEndpoint(service.logger, service.handler, func(sender dbus.Sender) bool { + authorizeContext, cancel := context.WithTimeout(context.Background(), authorizeTimeout) + defer cancel() + uid, err := connection.UnixUser(authorizeContext, string(sender)) + return err == nil && uid == uint32(os.Getuid()) + }) + + name := BusName + if service.orca { + name = OrcaBusName + } + registrations := service_bindings(endpoint, service.orca, service.handler) + started := false + exported := 0 + defer func() { + if !started { + for index := exported - 1; index >= 0; index-- { + binding := registrations[index] + connection.Export(nil, binding.path, binding.iface) + } + connection.Close() + } + }() + for _, binding := range registrations { + if err := connection.Export(binding.value, binding.path, binding.iface); err != nil { + return fmt.Errorf("export %s: %w", binding.iface, err) + } + exported++ + } + reply, err := connection.RequestName(name, dbus.NameFlagDoNotQueue) + if err != nil { + return fmt.Errorf("request D-Bus name %s: %w", name, err) + } + if reply != dbus.RequestNameReplyPrimaryOwner && reply != dbus.RequestNameReplyAlreadyOwner { + return fmt.Errorf("D-Bus name %s is already owned", name) + } + + endpoint.startAccepting() + service.connection = connection + service.endpoint = endpoint + service.ownedName = true + service.bindings = registrations + if !service.orca { + if handler, ok := service.handler.(WineReviewConnectionHandler); ok { + if native, ok := connection.(dbusConnection); ok { + handler.BindWineReviewConnection(native.Conn) + } + } + } + started = true + service.logger.Debug("remote D-Bus service ready", "name", name) + return nil +} + +func (service *Service) Stop(ctx context.Context) error { + if ctx == nil { + return errors.New("remote service stop requires a non-nil context") + } + service.mutex.Lock() + connection := service.connection + endpoint := service.endpoint + ownedName := service.ownedName + bindings := service.bindings + service.connection = nil + service.endpoint = nil + service.ownedName = false + service.bindings = nil + service.mutex.Unlock() + if connection == nil { + return nil + } + + idle := endpoint.stopAccepting() + if !service.orca { + if handler, ok := service.handler.(WineReviewConnectionHandler); ok { + handler.BindWineReviewConnection(nil) + } + } + var stopErrors []error + name := BusName + if service.orca { + name = OrcaBusName + } + for i := len(bindings) - 1; i >= 0; i-- { + binding := bindings[i] + if err := connection.Export(nil, binding.path, binding.iface); err != nil { + stopErrors = append(stopErrors, fmt.Errorf("unexport %s: %w", binding.iface, err)) + } + } + if ownedName { + if reply, err := connection.ReleaseName(name); err != nil { + stopErrors = append(stopErrors, fmt.Errorf("release D-Bus name %s: %w", name, err)) + } else if reply != dbus.ReleaseNameReplyReleased && reply != dbus.ReleaseNameReplyNonExistent { + stopErrors = append(stopErrors, fmt.Errorf("release D-Bus name %s: reply %d", name, reply)) + } + } + select { + case <-idle: + case <-ctx.Done(): + stopErrors = append(stopErrors, fmt.Errorf("wait for self-voice calls: %w", ctx.Err())) + } + if err := connection.Close(); err != nil { + stopErrors = append(stopErrors, fmt.Errorf("close session bus: %w", err)) + } + return errors.Join(stopErrors...) +} + +// Keep the Orca export limited to the methods it actually advertises. +type orcaServiceEndpoint struct { + endpoint *endpoint + modules []string +} + +func (service *orcaServiceEndpoint) ShowPreferences(sender dbus.Sender) (bool, *dbus.Error) { + return service.endpoint.ShowPreferences(sender) +} + +func (service *orcaServiceEndpoint) PresentMessage(sender dbus.Sender, message string) (bool, *dbus.Error) { + return service.endpoint.PresentMessage(sender, message) +} + +func (service *orcaServiceEndpoint) GetVersion(sender dbus.Sender) (string, *dbus.Error) { + return service.endpoint.GetVersion(sender) +} + +func (service *orcaServiceEndpoint) Quit(sender dbus.Sender) (bool, *dbus.Error) { + return service.endpoint.Quit(sender) +} + +func (service *orcaServiceEndpoint) ListModules(sender dbus.Sender) ([]string, *dbus.Error) { + if err := service.endpoint.begin(sender, "ListModules"); err != nil { + return nil, err + } + defer service.endpoint.end() + return append([]string(nil), service.modules...), nil +} + +func (service *orcaServiceEndpoint) ListCommands(sender dbus.Sender) ([]namedDescription, *dbus.Error) { + if err := service.endpoint.begin(sender, "ListCommands"); err != nil { + return nil, err + } + defer service.endpoint.end() + return []namedDescription{ + {"GetVersion", "Returns Cthulhu's version."}, + {"ListCommands", "Lists available service commands."}, + {"ListModules", "Lists available modules."}, + {"PresentMessage", "Presents a message."}, + {"Quit", "Quits Cthulhu."}, + {"ShowPreferences", "Shows preferences."}, + }, nil +} diff --git a/internal/remote/service_test.go b/internal/remote/service_test.go new file mode 100644 index 0000000..9a0aa9a --- /dev/null +++ b/internal/remote/service_test.go @@ -0,0 +1,324 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. + +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. + +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package remote + +import ( + "context" + "errors" + "log/slog" + "os" + "strings" + "sync" + "testing" + "time" + + "github.com/godbus/dbus/v5" +) + +type recordingHandler struct { + mutex sync.Mutex + presented []string + spoken []string + interrupts []bool + canceled int + braille []string + wine []AccessibleEvent + result bool +} + +func (handler *recordingHandler) PresentMessage(message string) bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.presented = append(handler.presented, message) + return handler.result +} + +func (handler *recordingHandler) SpeakText(text string, interrupt bool) bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.spoken = append(handler.spoken, text) + handler.interrupts = append(handler.interrupts, interrupt) + return handler.result +} + +func (handler *recordingHandler) BrailleMessage(text string) bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.braille = append(handler.braille, text) + return false +} + +func (handler *recordingHandler) CancelSpeech() bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.canceled++ + return handler.result +} + +func (handler *recordingHandler) PresentAccessibleEvent(event AccessibleEvent) bool { + handler.mutex.Lock() + defer handler.mutex.Unlock() + handler.wine = append(handler.wine, event) + return handler.result +} + +func authorizedEndpoint(handler Handler) *endpoint { + endpoint := newEndpoint(slog.New(slog.DiscardHandler), handler, func(dbus.Sender) bool { return true }) + endpoint.startAccepting() + return endpoint +} + +type fakeConnection struct { + mutex sync.Mutex + exports []string + requestReply dbus.RequestNameReply + requestError error + releaseReply dbus.ReleaseNameReply + closed bool + failExport string +} + +func (connection *fakeConnection) Export(value any, _ dbus.ObjectPath, iface string) error { + connection.mutex.Lock() + defer connection.mutex.Unlock() + if value != nil && iface == connection.failExport { + return errors.New("simulated export failure") + } + action := "export " + if value == nil { + action = "unexport " + } + connection.exports = append(connection.exports, action+iface) + return nil +} + +func TestServiceExportFailureClosesOnlyItsConnection(t *testing.T) { + failed := &fakeConnection{requestReply: dbus.RequestNameReplyPrimaryOwner, failExport: "org.freedesktop.DBus.Introspectable"} + service := newService(slog.New(slog.DiscardHandler), &recordingHandler{result: true}, func() (connection, error) { return failed, nil }) + service.orca = true + if err := service.Start(context.Background()); err == nil { + t.Fatal("export failure was ignored") + } + if !failed.closed { + t.Fatal("failed Orca connection was left open") + } + ready := &fakeConnection{requestReply: dbus.RequestNameReplyPrimaryOwner, releaseReply: dbus.ReleaseNameReplyReleased} + native := newService(slog.New(slog.DiscardHandler), &recordingHandler{result: true}, func() (connection, error) { return ready, nil }) + if err := native.Start(context.Background()); err != nil { + t.Fatalf("native service after Orca export failure: %v", err) + } + if err := native.Stop(context.Background()); err != nil { + t.Fatal(err) + } +} + +func (connection *fakeConnection) RequestName(string, dbus.RequestNameFlags) (dbus.RequestNameReply, error) { + return connection.requestReply, connection.requestError +} + +func (connection *fakeConnection) ReleaseName(string) (dbus.ReleaseNameReply, error) { + return connection.releaseReply, nil +} + +func (connection *fakeConnection) UnixUser(context.Context, string) (uint32, error) { + return uint32(os.Getuid()), nil +} + +func (connection *fakeConnection) Close() error { + connection.closed = true + return nil +} + +func TestServiceOwnsAndReleasesName(t *testing.T) { + fakeBus := &fakeConnection{ + requestReply: dbus.RequestNameReplyPrimaryOwner, + releaseReply: dbus.ReleaseNameReplyReleased, + } + service := newService(slog.New(slog.DiscardHandler), &recordingHandler{result: true}, func() (connection, error) { + return fakeBus, nil + }) + if err := service.Start(context.Background()); err != nil { + t.Fatalf("Start: %v", err) + } + if err := service.Stop(context.Background()); err != nil { + t.Fatalf("Stop: %v", err) + } + if !fakeBus.closed { + t.Fatal("session bus connection was not closed") + } + want := []string{ + "export " + InterfaceName, + "export org.freedesktop.DBus.Introspectable", + "export " + SpeechManagerInterface, + "export org.freedesktop.DBus.Introspectable", + "unexport org.freedesktop.DBus.Introspectable", + "unexport " + SpeechManagerInterface, + "unexport org.freedesktop.DBus.Introspectable", + "unexport " + InterfaceName, + } + if got := strings.Join(fakeBus.exports, ","); got != strings.Join(want, ",") { + t.Fatalf("exports = %q, want %q", got, strings.Join(want, ",")) + } +} + +func TestNativeSessionBusSelfVoice(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" { + t.Skip("set CTHULHU_NATIVE_DBUS_TEST=1 inside a private session bus") + } + handler := &recordingHandler{result: true} + service := New(slog.New(slog.DiscardHandler), handler) + if err := service.Start(context.Background()); err != nil { + t.Fatalf("Start: %v", err) + } + t.Cleanup(func() { service.Stop(context.Background()) }) + + conflict := New(slog.New(slog.DiscardHandler), handler) + if err := conflict.Start(context.Background()); err == nil { + conflict.Stop(context.Background()) + t.Fatal("second service acquired the well-known name") + } + + client, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatalf("connect client: %v", err) + } + defer client.Close() + object := client.Object(BusName, ObjectPath) + var accepted bool + if err := object.Call(InterfaceName+".SpeakText", 0, "Native message", false).Store(&accepted); err != nil { + t.Fatalf("SpeakText: %v", err) + } + if !accepted { + t.Fatal("SpeakText was not accepted") + } + if err := object.Call(InterfaceName+".PresentAccessibleEvent", 0, + "42:0:0", "focus", "Start", "button", "", "", "", int32(1), int32(3), "Game").Store(&accepted); err != nil { + t.Fatalf("PresentAccessibleEvent: %v", err) + } + if !accepted { + t.Fatal("PresentAccessibleEvent was not accepted") + } + if err := object.Call(InterfaceName+".BrailleMessage", 0, "Braille").Store(&accepted); err != nil { + t.Fatalf("BrailleMessage: %v", err) + } + if accepted { + t.Fatal("BrailleMessage succeeded without a braille backend") + } + var ssmlResult int32 + if err := object.Call(InterfaceName+".SpeakSsml", 0, "request", "Text").Store(&ssmlResult); err != nil { + t.Fatalf("SpeakSsml: %v", err) + } + if ssmlResult != windowsErrorNotSupported { + t.Fatalf("SpeakSsml = %d, want %d", ssmlResult, windowsErrorNotSupported) + } + var xml string + if err := object.Call("org.freedesktop.DBus.Introspectable.Introspect", 0).Store(&xml); err != nil { + t.Fatalf("Introspect: %v", err) + } + for _, method := range []string{"PresentMessage", "SpeakText", "BrailleMessage", "CancelSpeech", "SpeakSsml", "PresentAccessibleEvent"} { + if !strings.Contains(xml, `method name="`+method+`"`) { + t.Fatalf("introspection does not contain %s: %s", method, xml) + } + } + + manager := client.Object(BusName, SpeechManagerPath) + for _, notifyUser := range []bool{true, false} { + if err := manager.Call(SpeechManagerInterface+".InterruptSpeech", 0, notifyUser).Store(&accepted); err != nil || !accepted { + t.Fatalf("InterruptSpeech(%v): accepted=%v, error=%v", notifyUser, accepted, err) + } + } + handler.mutex.Lock() + canceled := handler.canceled + handler.mutex.Unlock() + if canceled != 2 { + t.Fatalf("InterruptSpeech cancellations = %d", canceled) + } + if err := manager.Call("org.freedesktop.DBus.Introspectable.Introspect", 0).Store(&xml); err != nil { + t.Fatal(err) + } + if !strings.Contains(xml, `method name="InterruptSpeech"`) || !strings.Contains(xml, `type="b" direction="in"`) { + t.Fatalf("missing SpeechManager signature: %s", xml) + } + if err := service.Stop(context.Background()); err != nil { + t.Fatalf("Stop: %v", err) + } + if err := manager.Call(SpeechManagerInterface+".InterruptSpeech", 0, true).Store(&accepted); err == nil { + t.Fatal("SpeechManager accepted a call after Stop") + } + replacement := New(slog.New(slog.DiscardHandler), handler) + if err := replacement.Start(context.Background()); err != nil { + t.Fatalf("replacement Start after name release: %v", err) + } + if err := replacement.Stop(context.Background()); err != nil { + t.Fatalf("replacement Stop: %v", err) + } +} + +func TestServiceRejectsNameConflictAndCleansUp(t *testing.T) { + fakeBus := &fakeConnection{requestReply: dbus.RequestNameReplyExists} + service := newService(slog.New(slog.DiscardHandler), &recordingHandler{result: true}, func() (connection, error) { + return fakeBus, nil + }) + err := service.Start(context.Background()) + if err == nil || !strings.Contains(err.Error(), "already owned") { + t.Fatalf("Start error = %v, want name ownership error", err) + } + if !fakeBus.closed { + t.Fatal("conflicted session bus connection was not closed") + } +} + +func TestServicePropagatesConnectionFailure(t *testing.T) { + want := errors.New("no session bus") + service := newService(slog.New(slog.DiscardHandler), &recordingHandler{}, func() (connection, error) { + return nil, want + }) + if err := service.Start(context.Background()); !errors.Is(err, want) { + t.Fatalf("Start error = %v, want %v", err, want) + } +} + +func TestStopWaitsForActiveCall(t *testing.T) { + started := make(chan struct{}) + release := make(chan struct{}) + endpoint := newEndpoint(slog.New(slog.DiscardHandler), &recordingHandler{}, func(dbus.Sender) bool { + close(started) + <-release + return true + }) + endpoint.startAccepting() + done := make(chan struct{}) + go func() { + endpoint.CancelSpeech(dbus.Sender(":1.9")) + close(done) + }() + <-started + idle := endpoint.stopAccepting() + select { + case <-idle: + t.Fatal("endpoint became idle while a call was active") + default: + } + close(release) + select { + case <-idle: + case <-time.After(time.Second): + t.Fatal("endpoint did not become idle") + } + <-done +} diff --git a/internal/remote/wine_review.go b/internal/remote/wine_review.go new file mode 100644 index 0000000..0f650b3 --- /dev/null +++ b/internal/remote/wine_review.go @@ -0,0 +1,37 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package remote + +import ( + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/wine" + "github.com/godbus/dbus/v5" +) + +// Optional so legacy handlers and Orca exports retain their existing contract. +type WineReviewHandler interface { + RegisterProvider(string, dbus.ObjectPath, uint32) bool + PresentFocus(string, wine.ReviewFocusNotice) bool +} +type WineReviewConnectionHandler interface{ BindWineReviewConnection(*dbus.Conn) } + +func (e *endpoint) RegisterWineReviewProvider(sender dbus.Sender, path dbus.ObjectPath, version uint32) (bool, *dbus.Error) { + if err := e.begin(sender, "RegisterWineReviewProvider"); err != nil { + return false, err + } + defer e.end() + if handler, ok := e.handler.(WineReviewHandler); ok { + return handler.RegisterProvider(string(sender), path, version), nil + } + return false, nil +} +func (e *endpoint) PresentWineReviewFocus(sender dbus.Sender, instance, window, focus string, revision uint64, title, role string, protected bool, bounds atspi.Rectangle) (bool, *dbus.Error) { + if err := e.begin(sender, "PresentWineReviewFocus"); err != nil { + return false, err + } + defer e.end() + if handler, ok := e.handler.(WineReviewHandler); ok { + return handler.PresentFocus(string(sender), wine.ReviewFocusNotice{Instance: instance, Window: window, Focus: focus, Revision: revision, Title: title, Role: role, Protected: protected, Bounds: bounds}), nil + } + return false, nil +} diff --git a/internal/remote/wine_review_test.go b/internal/remote/wine_review_test.go new file mode 100644 index 0000000..6d40c16 --- /dev/null +++ b/internal/remote/wine_review_test.go @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package remote + +import ( + "context" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/wine" + "github.com/godbus/dbus/v5" + "os" + "testing" + "time" +) + +type reviewRecordingHandler struct { + *recordingHandler + registry *wine.ReviewRegistry +} + +func (h reviewRecordingHandler) RegisterProvider(sender string, path dbus.ObjectPath, version uint32) bool { + return h.registry.RegisterProvider(sender, path, version) +} +func (h reviewRecordingHandler) PresentFocus(sender string, notice wine.ReviewFocusNotice) bool { + return h.registry.PresentFocus(sender, notice) +} +func (h reviewRecordingHandler) BindWineReviewConnection(conn *dbus.Conn) { + h.registry.BindWineReviewConnection(conn) +} +func TestWineReviewAuthorizationAndOptionalHandler(t *testing.T) { + r := wine.NewReviewRegistry(nil) + endpoint := newEndpoint(nil, reviewRecordingHandler{&recordingHandler{}, r}, func(dbus.Sender) bool { return false }) + endpoint.startAccepting() + if accepted, err := endpoint.RegisterWineReviewProvider(":1.2", wine.ReviewObjectPath, 1); accepted || err == nil || err.Name != "org.freedesktop.DBus.Error.AccessDenied" { + t.Fatal("unauthorized registration accepted") + } + optional := newEndpoint(nil, &recordingHandler{}, func(dbus.Sender) bool { return true }) + optional.startAccepting() + if accepted, err := optional.RegisterWineReviewProvider(":1.2", wine.ReviewObjectPath, 1); accepted || err != nil { + t.Fatal("older handler compatibility broken") + } +} + +type nativeReviewEndpoint struct { + conn *dbus.Conn + calls chan struct{} + bounds atspi.Rectangle +} + +func (f *nativeReviewEndpoint) CaptureWindow(sender dbus.Sender, window, focus string, revision uint64) (map[string]dbus.Variant, *dbus.Error) { + var owner string + if err := f.conn.BusObject().Call("org.freedesktop.DBus.GetNameOwner", 0, BusName).Store(&owner); err != nil || owner != string(sender) { + return nil, dbus.NewError("org.freedesktop.DBus.Error.AccessDenied", nil) + } + select { + case f.calls <- struct{}{}: + default: + } + node := map[string]dbus.Variant{"id": dbus.MakeVariant(window), "parent": dbus.MakeVariant(""), "role": dbus.MakeVariant("window"), "name": dbus.MakeVariant("native fixture"), "protected": dbus.MakeVariant(false), "visible": dbus.MakeVariant(true), "bounds": dbus.MakeVariant(f.bounds), "text_known": dbus.MakeVariant(false), "caret_known": dbus.MakeVariant(false), "caret": dbus.MakeVariant(uint64(0)), "caret_utf16": dbus.MakeVariant(uint64(0)), "ranges": dbus.MakeVariant([]wine.ReviewRange{})} + return map[string]dbus.Variant{"version": dbus.MakeVariant(uint32(1)), "instance": dbus.MakeVariant("instance"), "window": dbus.MakeVariant(window), "focus": dbus.MakeVariant(focus), "revision": dbus.MakeVariant(revision), "status": dbus.MakeVariant("ok"), "bounds": dbus.MakeVariant(f.bounds), "nodes": dbus.MakeVariant([]map[string]dbus.Variant{node})}, nil +} +func TestNativeSessionBusWineReview(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" { + t.Skip("requires private session bus") + } + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + registry := wine.NewReviewRegistry(nil) + if err := registry.Start(ctx); err != nil { + t.Fatal(err) + } + defer registry.Stop(context.Background()) + service := New(nil, reviewRecordingHandler{&recordingHandler{}, registry}) + if err := service.Start(ctx); err != nil { + t.Fatal(err) + } + defer service.Stop(context.Background()) + provider, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + defer provider.Close() + fixture := &nativeReviewEndpoint{conn: provider, calls: make(chan struct{}, 1), bounds: atspi.Rectangle{X: -10, Y: 20, Width: 400, Height: 300}} + if err = provider.Export(fixture, wine.ReviewObjectPath, wine.ReviewInterface); err != nil { + t.Fatal(err) + } + remote := provider.Object(BusName, ObjectPath) + var accepted bool + if err = remote.CallWithContext(ctx, InterfaceName+".RegisterWineReviewProvider", 0, wine.ReviewObjectPath, uint32(1)).Store(&accepted); err != nil || !accepted { + t.Fatalf("registration: %v %v", accepted, err) + } + if err = remote.CallWithContext(ctx, InterfaceName+".PresentWineReviewFocus", 0, "instance", "window", "window", uint64(1), "same title", "window", false, fixture.bounds).Store(&accepted); err != nil || !accepted { + t.Fatalf("focus: %v %v", accepted, err) + } + notices := registry.Focuses() + if len(notices) != 1 { + t.Fatalf("focus mailbox: %+v", notices) + } + id := notices[0].ID() + tree, err := registry.Capture(ctx, id) + if err != nil || tree == nil { + t.Fatalf("actual owner capture: %v", err) + } + wrong, err := dbus.ConnectSessionBus() + if err != nil { + t.Fatal(err) + } + defer wrong.Close() + if err = wrong.Object(id.BusName, wine.ReviewObjectPath).CallWithContext(ctx, wine.ReviewInterface+".CaptureWindow", 0, "window", "window", uint64(1)).Err; err == nil { + t.Fatal("different unique connection accepted") + } + provider.Close() + for registry.Current(id) { + select { + case <-registry.Changes(): + case <-ctx.Done(): + t.Fatal("dead provider remained current") + } + } + if len(registry.Focuses()) != 0 { + t.Fatal("dead focus retained") + } +} diff --git a/internal/review/current_line.go b/internal/review/current_line.go new file mode 100644 index 0000000..8b16a46 --- /dev/null +++ b/internal/review/current_line.go @@ -0,0 +1,80 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// ReadCurrentLine leaves both the native caret and review cursors untouched. +func (worker *Worker) ReadCurrentLine(browse bool, style FlatSpeech) error { + if style > FlatPhonetic { + return ErrInvalidDirection + } + select { + case worker.requests <- request{currentLine: true, currentLineBrowse: browse, flatSpeech: style, + documentEpoch: worker.documentEpoch.Load(), queuedAt: time.Now()}: + return nil + default: + return ErrRequestQueueFull + } +} + +func (worker *Worker) read_current_line(ctx context.Context, cursor *DocumentCursor, browse bool) Result { + result := Result{CurrentLine: true, CurrentLineBrowse: browse, DocumentFocus: worker.focus()} + if !result.DocumentFocus.Valid() { + result.Err = ErrNoCurrent + return result + } + deadline, cancel := context.WithTimeout(ctx, worker.captureTimeout) + defer cancel() + if !browse { + reader, ok := worker.nativeCapturerFor(result.DocumentFocus).(interface { + ReadFocusedLine(context.Context, atspi.ObjectID) (atspi.DocumentContent, error) + }) + if !ok { + result.Err = atspi.ErrNoDocumentCaret + return result + } + content, err := reader.ReadFocusedLine(deadline, result.DocumentFocus) + result.Err = err + result.DocumentCaretText, result.DocumentCaretRawText = content.Text, content.RawText + result.DocumentPosition.Snapshot = content.Snapshot + return result + } + // Start a private cursor at the saved browse position. Going to line start + // before reading avoids Say All's deliberate "rest of this line" behavior. + if cursor != nil { + cursor = &DocumentCursor{tree: cursor.tree, active: cursor.active, places: append([]documentPlace(nil), cursor.places...)} + _, result.Err = cursor.syncActionFocus(deadline, result.DocumentFocus) + } else { + result.Err = ErrNoCurrent + } + if documentNeedsCapture(result.Err) { + cursor, result.Err = worker.refreshDocumentCursor(deadline, cursor, result.DocumentFocus) + } + if result.Err != nil { + return result + } + reader, ok := worker.nativeCapturerFor(result.DocumentFocus).(DocumentCaretReader) + if !ok { + result.Err = atspi.ErrNoDocumentCaret + return result + } + _, cursor, result.Err = worker.readAllMove(deadline, cursor, reader, CaretLineStart, result.DocumentFocus) + if result.Err != nil { + return result + } + movement, _, err := worker.readAllMove(deadline, cursor, reader, CaretReadLine, result.DocumentFocus) + result.Err = err + result.DocumentPosition, result.DocumentCaretText = movement.Position, movement.Text + result.DocumentCaretRawText, result.DocumentCaretLine = movement.RawText, movement.Line + if result.DocumentCaretText == "" && wholeCaretNode(movement.Position.Snapshot) { + result.DocumentCaretText = movement.Position.Snapshot.Name + } + return result +} diff --git a/internal/review/current_line_test.go b/internal/review/current_line_test.go new file mode 100644 index 0000000..f86d7cb --- /dev/null +++ b/internal/review/current_line_test.go @@ -0,0 +1,109 @@ +package review + +import ( + "context" + "reflect" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type currentLineCapturer struct { + *readAllCapturer + content atspi.DocumentContent + reads int +} + +func (capturer *currentLineCapturer) ReadFocusedLine(context.Context, atspi.ObjectID) (atspi.DocumentContent, error) { + capturer.reads++ + return capturer.content, nil +} + +func TestCurrentLineUsesNativeFocusOutsideBrowse(t *testing.T) { + capturer := ¤tLineCapturer{content: atspi.DocumentContent{Text: "Native caret line"}} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + worker.SyncFocus(webID("/entry")) + for _, style := range []FlatSpeech{FlatSpeak, FlatSpell, FlatPhonetic} { + if err := worker.ReadCurrentLine(false, style); err != nil { + t.Fatal(err) + } + result := waitResult(t, worker) + if !result.CurrentLine || result.CurrentLineBrowse || result.FlatSpeech != style || result.Err != nil || result.DocumentCaretText != "Native caret line" { + t.Fatalf("native current line: %+v", result) + } + } + if capturer.reads != 3 { + t.Fatal("native line was cached") + } +} + +func TestCurrentLineReadsWholeBrowseLineWithoutMoving(t *testing.T) { + reader := caretTextReader{webID("/text"): "First line\nSecond café 猫\nThird", webID("/next"): "Next"} + cursor := newCaretTextCursor(t, reader) + capturer := &readAllCapturer{tree: cursor.tree, caretTextReader: reader} + worker, _ := NewWorker(capturer, time.Second) + worker.SyncFocus(webID("/text")) + for range 15 { + if _, err := cursor.MoveCaret(context.Background(), reader, CaretNextCharacter); err != nil { + t.Fatal(err) + } + } + before := append([]documentPlace(nil), cursor.places...) + result := worker.read_current_line(context.Background(), cursor, true) + if result.Err != nil || strings.TrimSpace(result.DocumentCaretText) != "Second café 猫" { + t.Fatalf("whole browse line from middle: %+v", result) + } + if !reflect.DeepEqual(cursor.places, before) || capturer.nativePlacements != 0 { + t.Fatal("report changed browse or native caret") + } +} + +func TestCurrentLineJoinsBrowseFragmentsWithoutMoving(t *testing.T) { + cursor, reader := fragment_cursor(t, "paragraph") + if _, err := cursor.MoveCaret(context.Background(), reader, CaretNextWord); err != nil { + t.Fatal(err) + } + capturer := &readAllCapturer{tree: cursor.tree, caretTextReader: reader.caretTextReader} + // Retain the fixture's geometry so the report can collect both fragments. + source := ¤tLineFragmentCapturer{readAllCapturer: capturer, fragmentTextReader: reader} + worker, _ := NewWorker(source, time.Second) + worker.SyncFocus(webID("/one")) + before := append([]documentPlace(nil), cursor.places...) + result := worker.read_current_line(context.Background(), cursor, true) + if result.Err != nil || result.DocumentCaretText != "One two." || !reflect.DeepEqual(cursor.places, before) { + t.Fatalf("fragmented current line: %+v", result) + } +} + +func TestCurrentLineReadsBrowseControlLabel(t *testing.T) { + doc := atspi.Snapshot{BusName: webID("/doc").BusName, Path: "/doc", Role: "document web"} + button := atspi.Snapshot{BusName: doc.BusName, Path: "/button", Role: "push button", Name: "Example button"} + tree, err := atspi.NewAccessibleTree(doc.ID(), []atspi.TreeNode{ + {Snapshot: doc, Children: []atspi.ObjectID{button.ID()}}, {Snapshot: button}, + }) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + if _, err := cursor.SyncFocus(context.Background(), button.ID()); err != nil { + t.Fatal(err) + } + worker, _ := NewWorker(&readAllCapturer{tree: tree, caretTextReader: caretTextReader{}}, time.Second) + worker.SyncFocus(button.ID()) + result := worker.read_current_line(context.Background(), cursor, true) + if result.Err != nil || result.DocumentCaretText != "Example button" { + t.Fatalf("browse control label: %+v", result) + } +} + +type currentLineFragmentCapturer struct { + *readAllCapturer + fragmentTextReader +} + +func (capturer *currentLineFragmentCapturer) ReadDocumentCaret(ctx context.Context, ref atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + return capturer.fragmentTextReader.ReadDocumentCaret(ctx, ref, offset, unit) +} diff --git a/internal/review/cursor.go b/internal/review/cursor.go new file mode 100644 index 0000000..8ccc97f --- /dev/null +++ b/internal/review/cursor.go @@ -0,0 +1,198 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +// Package review owns navigation state over immutable AT-SPI snapshots. +package review + +import ( + "errors" + "fmt" + "sync" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +var ( + ErrNoCurrent = errors.New("review cursor has no current object") + ErrInvalidDirection = errors.New("invalid review direction") +) + +type Direction int + +const ( + Parent Direction = iota + 1 + FirstChild + PreviousSibling + NextSibling +) + +func (direction Direction) String() string { + switch direction { + case Parent: + return "parent" + case FirstChild: + return "first-child" + case PreviousSibling: + return "previous-sibling" + case NextSibling: + return "next-sibling" + default: + return fmt.Sprintf("direction(%d)", direction) + } +} + +// Position contains owned snapshots for the cursor's current and previous +// objects. HasPrevious distinguishes an absent previous object from an empty +// snapshot. +type Position struct { + Current atspi.Snapshot + Previous atspi.Snapshot + HasPrevious bool +} + +// Cursor owns object-navigation state over one AccessibleTree. Focus updates +// and navigation may arrive from different goroutines, so Cursor serializes +// its references while AccessibleTree validates their generations. +type Cursor struct { + mu sync.Mutex + tree *atspi.AccessibleTree + current atspi.ObjectReference + previous atspi.ObjectReference + lastFocus atspi.ObjectID +} + +func NewCursor(tree *atspi.AccessibleTree) (*Cursor, error) { + if tree == nil { + return nil, errors.New("create review cursor: nil accessible tree") + } + return &Cursor{tree: tree}, nil +} + +// SyncFocus moves the cursor to focus only when focus changes. Repeated focus +// snapshots therefore do not pull a user back from an independently reviewed +// object. If invalidation made the current reference stale, SyncFocus repairs +// it from the current focus identity when possible. +func (cursor *Cursor) SyncFocus(focus atspi.ObjectID) (Position, error) { + cursor.mu.Lock() + defer cursor.mu.Unlock() + + if !focus.Valid() { + return Position{}, errors.New("sync review cursor: invalid focus identity") + } + if focus == cursor.lastFocus && cursor.current.Valid() { + if position, err := cursor.positionLocked(); err == nil { + return position, nil + } else if !errors.Is(err, atspi.ErrStaleObject) { + return Position{}, err + } + } + + reference, err := cursor.tree.Reference(focus) + if err != nil { + return Position{}, fmt.Errorf("sync review cursor: %w", err) + } + cursor.setCurrentLocked(reference) + cursor.lastFocus = focus + return cursor.positionLocked() +} + +func (cursor *Cursor) Current() (Position, error) { + cursor.mu.Lock() + defer cursor.mu.Unlock() + return cursor.positionLocked() +} + +// Move traverses one owned-tree relationship. A boundary leaves the cursor in +// place and returns moved=false. Stale references and malformed state are +// errors and also leave the cursor unchanged. +func (cursor *Cursor) Move(direction Direction) (position Position, moved bool, err error) { + cursor.mu.Lock() + defer cursor.mu.Unlock() + + if !cursor.current.Valid() { + return Position{}, false, ErrNoCurrent + } + if _, err := cursor.tree.Resolve(cursor.current); err != nil { + return Position{}, false, fmt.Errorf("move review cursor: %w", err) + } + + var next atspi.ObjectReference + var ok bool + switch direction { + case Parent: + next, ok, err = cursor.tree.Parent(cursor.current) + case FirstChild: + next, ok, err = cursor.tree.FirstChild(cursor.current) + case PreviousSibling: + next, ok, err = cursor.tree.PreviousSibling(cursor.current) + case NextSibling: + next, ok, err = cursor.tree.NextSibling(cursor.current) + default: + return Position{}, false, fmt.Errorf("%w: %d", ErrInvalidDirection, direction) + } + if err != nil { + return Position{}, false, fmt.Errorf("move review cursor: %w", err) + } + if !ok { + position, err := cursor.positionLocked() + return position, false, err + } + if _, err := cursor.tree.Resolve(next); err != nil { + return Position{}, false, fmt.Errorf("resolve review destination: %w", err) + } + cursor.setCurrentLocked(next) + position, err = cursor.positionLocked() + return position, true, err +} + +func (cursor *Cursor) Reset() { + cursor.mu.Lock() + defer cursor.mu.Unlock() + cursor.current = atspi.ObjectReference{} + cursor.previous = atspi.ObjectReference{} + cursor.lastFocus = atspi.ObjectID{} +} + +func (cursor *Cursor) setCurrentLocked(reference atspi.ObjectReference) { + if cursor.current.Valid() && cursor.current != reference { + cursor.previous = cursor.current + } else if !cursor.current.Valid() { + cursor.previous = atspi.ObjectReference{} + } + cursor.current = reference +} + +func (cursor *Cursor) positionLocked() (Position, error) { + if !cursor.current.Valid() { + return Position{}, ErrNoCurrent + } + current, err := cursor.tree.Resolve(cursor.current) + if err != nil { + return Position{}, fmt.Errorf("resolve current review object: %w", err) + } + position := Position{Current: current} + if cursor.previous.Valid() { + previous, previousErr := cursor.tree.Resolve(cursor.previous) + if previousErr == nil { + position.Previous = previous + position.HasPrevious = true + } else if !errors.Is(previousErr, atspi.ErrStaleObject) { + return Position{}, fmt.Errorf("resolve previous review object: %w", previousErr) + } + } + return position, nil +} diff --git a/internal/review/cursor_test.go b/internal/review/cursor_test.go new file mode 100644 index 0000000..765087d --- /dev/null +++ b/internal/review/cursor_test.go @@ -0,0 +1,193 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "errors" + "sync" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestDirectionNames(t *testing.T) { + tests := map[Direction]string{ + Parent: "parent", + FirstChild: "first-child", + PreviousSibling: "previous-sibling", + NextSibling: "next-sibling", + Direction(99): "direction(99)", + } + for direction, expected := range tests { + if got := direction.String(); got != expected { + t.Fatalf("direction %d = %q, want %q", direction, got, expected) + } + } +} + +func objectID(path string) atspi.ObjectID { + return atspi.NewObjectID(":1.42", path) +} + +func node(path, name string, children ...atspi.ObjectID) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, name, "push button", "", "") + snapshot.BusName = ":1.42" + return atspi.TreeNode{Snapshot: snapshot, Children: children} +} + +func newTree(t *testing.T) *atspi.AccessibleTree { + t.Helper() + tree, err := atspi.NewAccessibleTree(objectID("/root"), []atspi.TreeNode{ + node("/root", "Window", objectID("/first"), objectID("/second")), + node("/first", "First"), + node("/second", "Second", objectID("/grandchild")), + node("/grandchild", "Grandchild"), + }) + if err != nil { + t.Fatal(err) + } + return tree +} + +func TestCursorFollowsChangedFocusAndPreservesIndependentNavigation(t *testing.T) { + cursor, err := NewCursor(newTree(t)) + if err != nil { + t.Fatal(err) + } + position, err := cursor.SyncFocus(objectID("/first")) + if err != nil || position.Current.Name != "First" || position.HasPrevious { + t.Fatalf("initial position = %#v, error = %v", position, err) + } + + position, moved, err := cursor.Move(NextSibling) + if err != nil || !moved || position.Current.Name != "Second" || !position.HasPrevious || position.Previous.Name != "First" { + t.Fatalf("next position = %#v, moved = %v, error = %v", position, moved, err) + } + position, err = cursor.SyncFocus(objectID("/first")) + if err != nil || position.Current.Name != "Second" { + t.Fatalf("repeated focus pulled cursor back: position = %#v, error = %v", position, err) + } + + position, err = cursor.SyncFocus(objectID("/grandchild")) + if err != nil || position.Current.Name != "Grandchild" || !position.HasPrevious || position.Previous.Name != "Second" { + t.Fatalf("changed focus position = %#v, error = %v", position, err) + } +} + +func TestCursorTraversesRelationshipsAndPreservesBoundaries(t *testing.T) { + cursor, _ := NewCursor(newTree(t)) + if _, err := cursor.SyncFocus(objectID("/second")); err != nil { + t.Fatal(err) + } + + position, moved, err := cursor.Move(FirstChild) + if err != nil || !moved || position.Current.Name != "Grandchild" { + t.Fatalf("child position = %#v, moved = %v, error = %v", position, moved, err) + } + position, moved, err = cursor.Move(FirstChild) + if err != nil || moved || position.Current.Name != "Grandchild" { + t.Fatalf("child boundary = %#v, moved = %v, error = %v", position, moved, err) + } + position, moved, err = cursor.Move(Parent) + if err != nil || !moved || position.Current.Name != "Second" { + t.Fatalf("parent position = %#v, moved = %v, error = %v", position, moved, err) + } + position, moved, err = cursor.Move(PreviousSibling) + if err != nil || !moved || position.Current.Name != "First" { + t.Fatalf("previous position = %#v, moved = %v, error = %v", position, moved, err) + } + position, moved, err = cursor.Move(PreviousSibling) + if err != nil || moved || position.Current.Name != "First" { + t.Fatalf("previous boundary = %#v, moved = %v, error = %v", position, moved, err) + } +} + +func TestCursorRepairsStaleCurrentFromUnchangedFocus(t *testing.T) { + tree := newTree(t) + cursor, _ := NewCursor(tree) + if _, err := cursor.SyncFocus(objectID("/first")); err != nil { + t.Fatal(err) + } + tree.Invalidate(objectID("/first")) + if _, err := cursor.Current(); !errors.Is(err, atspi.ErrStaleObject) { + t.Fatalf("current error = %v, want stale object", err) + } + if err := tree.Replace(objectID("/root"), []atspi.TreeNode{ + node("/root", "Window", objectID("/first")), + node("/first", "Reintroduced"), + }); err != nil { + t.Fatal(err) + } + position, err := cursor.SyncFocus(objectID("/first")) + if err != nil || position.Current.Name != "Reintroduced" { + t.Fatalf("repaired position = %#v, error = %v", position, err) + } +} + +func TestCursorErrorsDoNotMoveAndResetClearsState(t *testing.T) { + cursor, _ := NewCursor(newTree(t)) + if _, _, err := cursor.Move(Parent); !errors.Is(err, ErrNoCurrent) { + t.Fatalf("empty move error = %v", err) + } + if _, err := cursor.SyncFocus(atspi.ObjectID{}); err == nil { + t.Fatal("invalid focus was accepted") + } + if _, err := cursor.SyncFocus(objectID("/first")); err != nil { + t.Fatal(err) + } + if _, _, err := cursor.Move(Direction(99)); !errors.Is(err, ErrInvalidDirection) { + t.Fatalf("invalid direction error = %v", err) + } + position, err := cursor.Current() + if err != nil || position.Current.Name != "First" { + t.Fatalf("position after invalid move = %#v, error = %v", position, err) + } + cursor.Reset() + if _, err := cursor.Current(); !errors.Is(err, ErrNoCurrent) { + t.Fatalf("reset current error = %v", err) + } +} + +func TestCursorSerializesFocusAndNavigation(t *testing.T) { + cursor, _ := NewCursor(newTree(t)) + if _, err := cursor.SyncFocus(objectID("/first")); err != nil { + t.Fatal(err) + } + var wait sync.WaitGroup + for index := 0; index < 20; index++ { + wait.Add(2) + go func() { + defer wait.Done() + _, _ = cursor.SyncFocus(objectID("/first")) + }() + go func() { + defer wait.Done() + _, _, _ = cursor.Move(NextSibling) + }() + } + wait.Wait() + if _, err := cursor.Current(); err != nil { + t.Fatal(err) + } +} + +func TestNewCursorRejectsNilTree(t *testing.T) { + if _, err := NewCursor(nil); err == nil { + t.Fatal("nil tree was accepted") + } +} diff --git a/internal/review/document.go b/internal/review/document.go new file mode 100644 index 0000000..cba3d7e --- /dev/null +++ b/internal/review/document.go @@ -0,0 +1,641 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "strings" + "sync" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// NavigationOrigin distinguishes native focus from document navigation for +// the future browse/focus-mode policy. Flat review never changes this cursor. +type NavigationOrigin uint8 + +const ( + NativeNavigation NavigationOrigin = iota + StructuralNavigation + CaretNavigation +) + +type DocumentPosition struct { + Document atspi.ObjectReference + Object atspi.ObjectReference + Snapshot atspi.Snapshot + // LinkedHeading is the link associated with a heading target, if any. + LinkedHeading *atspi.Snapshot + Origin NavigationOrigin + Offset int +} + +// DocumentMoveResult reports whether a semantic move crossed a document +// boundary and wrapped to the opposite end. +type DocumentMoveResult struct { + Position DocumentPosition + Moved bool + Wrapped bool +} + +// ErrNoDocumentAction is a valid reading location without an unambiguous +// activation target. It does not require a document recapture. +var ErrNoDocumentAction = errors.New("current document item has no activation target") + +type documentPlace struct { + document atspi.ObjectReference + object atspi.ObjectReference + focus atspi.ObjectReference + origin NavigationOrigin + offset int + tableCell atspi.ObjectID + tableRow, tableColumn int + // A text child can be replaced while its parent and adjacent siblings live. + // Generation-checked boundaries distinguish replacement from insertion. + textParent, textPrevious, textNext atspi.ObjectReference + // Bounded surviving ancestry is a navigation fallback, never an action target. + recoveryParents []atspi.ObjectReference +} + +// DocumentCursor remembers at most 16 document positions in least-recently- +// used order. Leaving a document suspends navigation without losing its place; +// invalidated/reused identities cannot inherit it. The caller owns the tree's +// capture/recapture lifecycle. Methods serialize cursor state and do no native +// work, key handling, focus changes, or speech. +type DocumentCursor struct { + mu sync.Mutex + tree *atspi.AccessibleTree + places []documentPlace + active atspi.ObjectReference + caretDocument atspi.DocumentSnapshot + caretRanges []caretRange + caretLookup *caretRangeLookup + lineOwners map[int]atspi.ObjectID +} + +// rebindPlace keeps the selected target after a semantic refresh retires its +// old tree references between a move and native caret placement. +func (cursor *DocumentCursor) rebindPlace(tree *atspi.AccessibleTree, oldPosition, newPosition DocumentPosition) { + cursor.mu.Lock() + defer cursor.mu.Unlock() + if cursor.tree != tree || len(cursor.places) == 0 { + return + } + place := &cursor.places[len(cursor.places)-1] + if place.document != oldPosition.Document || place.object != oldPosition.Object { + return + } + place.document = newPosition.Document + place.object = newPosition.Object + if focus, err := tree.Reference(place.focus.ID()); err == nil { + place.focus = focus + } + cursor.active = newPosition.Document +} + +func NewDocumentCursor(tree *atspi.AccessibleTree) (*DocumentCursor, error) { + if tree == nil { + return nil, errors.New("create document cursor: nil accessible tree") + } + return &DocumentCursor{tree: tree}, nil +} + +// ActivationTarget resolves the current browse position, including text +// children inside a link, without consulting the browser's retained focus. +func (cursor *DocumentCursor) ActivationTarget() (atspi.ObjectReference, error) { + cursor.mu.Lock() + defer cursor.mu.Unlock() + if !cursor.active.Valid() || len(cursor.places) == 0 { + return atspi.ObjectReference{}, ErrNoCurrent + } + place := cursor.places[len(cursor.places)-1] + if place.document != cursor.active { + return atspi.ObjectReference{}, ErrNoCurrent + } + current := place.object + var clickable atspi.ObjectReference + selectedHeading := false + for depth := 0; depth < 128; depth++ { + snapshot, err := cursor.tree.Resolve(current) + if err != nil { + return atspi.ObjectReference{}, err + } + if depth == 0 { + selectedHeading = snapshot.Role == "heading" + } + if snapshot.Role == "link" { + return current, nil + } + if !clickable.Valid() && snapshot.SupportsClick && + snapshot.Role != "document web" && snapshot.Role != "document frame" { + clickable = current + } + if current == place.document { + break + } + parent, ok, err := cursor.tree.Parent(current) + if err != nil { + return atspi.ObjectReference{}, err + } + if !ok { + break + } + current = parent + } + if place.origin == StructuralNavigation && selectedHeading { + doc, err := cursor.tree.DocumentView(context.Background(), place.object) + if err != nil { + return atspi.ObjectReference{}, err + } + link, ok, ambiguous := linkedHeadingNode(doc, place.object) + if ok { + return link.Reference, nil + } + if ambiguous { + return atspi.ObjectReference{}, ErrNoDocumentAction + } + } + if clickable.Valid() { + return clickable, nil + } + return atspi.ObjectReference{}, ErrNoDocumentAction +} + +func (cursor *DocumentCursor) SyncFocus(ctx context.Context, focus atspi.ObjectID) (DocumentPosition, error) { + position, _, err := cursor.sync_focus(ctx, focus) + return position, err +} + +// The outcome explains whether focus synchronization retained the reading +// position, recovered a replacement text child, or fell back to native focus. +func (cursor *DocumentCursor) sync_focus(ctx context.Context, focus atspi.ObjectID) (DocumentPosition, string, error) { + cursor.mu.Lock() + defer cursor.mu.Unlock() + // Failed ownership resolution must never leave web navigation active for + // the previous focus (e.g. address bar, another application, stale object). + cursor.active = atspi.ObjectReference{} + ref, err := cursor.tree.Reference(focus) + if err != nil { + return DocumentPosition{}, "focus-unresolved", err + } + doc, err := cursor.tree.NavigationDocument(ctx, ref) + if err != nil { + return DocumentPosition{}, "document-unresolved", err + } + place := documentPlace{document: doc.Context.TopLevel, object: ref, focus: ref} + recovery := "new-document" + removeIndex := -1 + for index, saved := range cursor.places { + if saved.document != place.document { + if saved.document.ID() == place.document.ID() { + recovery = "document-replaced" + } + continue + } + recovery = "focus-changed" + if saved.focus == ref || saved.object == ref { + recovery = "saved-object-missing" + if _, ok := documentObject(doc, saved.object); ok { + recovery = "preserved" + place = saved + place.focus = ref + } else if replacement, ok := replacement_text_node(doc, saved); ok { + recovery = "replaced-text-child" + place = saved + place.focus, place.object = ref, replacement.Reference + place.offset = min(saved.offset, max(0, replacement.Snapshot.CharacterCount-1)) + } else if parent, ok := survivingDocumentParent(doc, saved); ok { + recovery = "surviving-parent" + place.object = parent.Reference + } + } + removeIndex = index + break + } + placeIndex, ok := doc.Index(place.object.ID()) + if !ok { + return DocumentPosition{}, "saved-object-missing", atspi.ErrStaleObject + } + if err := cursor.tree.ValidateDocumentRange(ctx, doc, placeIndex, placeIndex); err != nil { + return DocumentPosition{}, "document-unresolved", err + } + if removeIndex >= 0 { + cursor.places = append(cursor.places[:removeIndex], cursor.places[removeIndex+1:]...) + } + remember_text_parent(doc, &place) + if len(cursor.places) == 16 { + cursor.places = cursor.places[1:] + } + cursor.places = append(cursor.places, place) + cursor.active = place.document + return documentPosition(doc, place), recovery, nil +} + +// JumpToFragment follows a browser document load whose URI names an element. +// The browser has already scrolled to that element; keep the independent +// browse cursor with the first named link in its subtree when available. +func (cursor *DocumentCursor) JumpToFragment(ctx context.Context, fragment string) (DocumentPosition, bool, error) { + cursor.mu.Lock() + defer cursor.mu.Unlock() + if !cursor.active.Valid() || len(cursor.places) == 0 || fragment == "" { + return DocumentPosition{}, false, ErrNoCurrent + } + place := &cursor.places[len(cursor.places)-1] + doc, err := cursor.tree.DocumentView(ctx, place.object) + if err != nil { + return DocumentPosition{}, false, err + } + indexByID := make(map[atspi.ObjectID]int, len(doc.Nodes)) + for index, node := range doc.Nodes { + indexByID[node.Reference.ID()] = index + } + var target *atspi.DocumentNode + for index := range doc.Nodes { + if doc.Nodes[index].Snapshot.ElementID != fragment || doc.Nodes[index].Hidden { + continue + } + root := &doc.Nodes[index] + target = root + var namedDescendant *atspi.DocumentNode + pending := append([]atspi.ObjectID(nil), root.Children...) + for len(pending) > 0 { + id := pending[0] + pending = pending[1:] + childIndex, ok := indexByID[id] + if !ok { + continue + } + child := &doc.Nodes[childIndex] + if child.Hidden { + continue + } + if namedDescendant == nil && child.Snapshot.Name != "" { + namedDescendant = child + } + if child.Snapshot.Role == "link" && child.Snapshot.Name != "" { + target = child + break + } + pending = append(append([]atspi.ObjectID(nil), child.Children...), pending...) + } + if target == root && namedDescendant != nil { + target = namedDescendant + } + break + } + if target == nil { + return DocumentPosition{}, false, nil + } + place.object, place.offset, place.origin = target.Reference, 0, CaretNavigation + return documentPosition(doc, *place), true, nil +} + +type DocumentTarget uint8 + +const ( + DocumentHeading DocumentTarget = iota + 1 + DocumentLink + DocumentButton + DocumentCheckBox + DocumentList + DocumentSeparator + DocumentBlockQuote + DocumentComboBox + DocumentEntry + DocumentFormField + DocumentImage + DocumentLandmark + DocumentListItem + DocumentLiveRegion + DocumentParagraph + DocumentRadioButton + DocumentTable + DocumentUnvisitedLink + DocumentVisitedLink + DocumentClickable + DocumentChunk + DocumentAnnotation + DocumentInternalFrame + DocumentMath +) + +// Move searches in accessible tree order, wrapping once to the opposite end. +// Heading level zero means any level. This is a semantic traversal primitive, +// not yet the full Python structural-navigation policy or a native caret/focus +// operation. +func (cursor *DocumentCursor) Move(ctx context.Context, target DocumentTarget, level int, backwards bool) (DocumentMoveResult, error) { + cursor.mu.Lock() + defer cursor.mu.Unlock() + if !validDocumentTarget(target) || level < 0 || level > 6 || target != DocumentHeading && level != 0 { + return DocumentMoveResult{}, errors.New("invalid document navigation target") + } + if !cursor.active.Valid() || len(cursor.places) == 0 { + return DocumentMoveResult{}, ErrNoCurrent + } + place := &cursor.places[len(cursor.places)-1] + doc, err := cursor.tree.NavigationDocument(ctx, place.object) + if err != nil { + return DocumentMoveResult{}, err + } + // Reparenting a live object into a different document must not transfer + // the old document's cursor, even when the object's ID remains live. + if doc.Context.TopLevel != place.document { + return DocumentMoveResult{}, atspi.ErrStaleObject + } + index, found := doc.Index(place.object.ID()) + if !found || doc.Nodes[index].Reference != place.object { + return DocumentMoveResult{}, atspi.ErrStaleObject + } + if err := cursor.tree.ValidateDocumentOrder(ctx, doc, index); err != nil { + return DocumentMoveResult{}, err + } + // Anchor at the nearest matching ancestor without rebuilding parent maps. + for parent := place.object.ID(); parent.Valid(); { + candidate, ok := doc.Node(parent) + if !ok { + break + } + if documentTargetMatches(target, candidate, level) { + index, _ = doc.Index(parent) + break + } + parent = candidate.Parent + } + commit := func(targetIndex int, wrapped bool) (DocumentMoveResult, error) { + if err := cursor.tree.ValidateDocumentRange(ctx, doc, targetIndex, doc.SubtreeEnd(targetIndex)); err != nil { + return DocumentMoveResult{}, err + } + place.tableCell = atspi.ObjectID{} + place.object, place.origin, place.offset = doc.Nodes[targetIndex].Reference, StructuralNavigation, 0 + remember_text_parent(doc, place) + return DocumentMoveResult{Position: documentPosition(doc, *place), Moved: true, Wrapped: wrapped}, nil + } + step := 1 + if backwards { + step = -1 + } + // Validate every traversed node, including nonmatches and hidden nodes: a + // dirty candidate must be refreshed before it can be skipped safely. + for i := index + step; i >= 0 && i < len(doc.Nodes); i += step { + if err := cursor.tree.ValidateDocumentRange(ctx, doc, i-step, i); err != nil { + return DocumentMoveResult{}, err + } + node := doc.Nodes[i] + if !node.Hidden && documentTargetMatches(target, node, level) { + return commit(i, false) + } + } + start, end := 0, index + if backwards { + start, end = len(doc.Nodes)-1, index + } + for i := start; ; i += step { + if err := cursor.tree.ValidateDocumentRange(ctx, doc, i, i); err != nil { + return DocumentMoveResult{}, err + } + node := doc.Nodes[i] + if !node.Hidden && documentTargetMatches(target, node, level) { + return commit(i, true) + } + if i == end { + break + } + } + return DocumentMoveResult{Position: documentPosition(doc, *place)}, nil +} + +func validDocumentTarget(target DocumentTarget) bool { + return target >= DocumentHeading && target <= DocumentMath +} + +func documentTargetMatches(target DocumentTarget, node atspi.DocumentNode, level int) bool { + snapshot := node.Snapshot + switch target { + case DocumentHeading: + return snapshot.Role == "heading" && (level == 0 || snapshot.HeadingLevel == level) + case DocumentLink: + return snapshot.Role == "link" && snapshot.Focusable + case DocumentButton: + return snapshot.Role == "button" || snapshot.Role == "push button" || snapshot.Role == "toggle button" + case DocumentCheckBox: + return snapshot.Role == "check box" + case DocumentList: + return snapshot.Role == "list" + case DocumentSeparator: + return snapshot.Role == "separator" + case DocumentBlockQuote: + return snapshot.Role == "block quote" + case DocumentComboBox: + return snapshot.Role == "combo box" + case DocumentEntry: + return snapshot.Editable && snapshot.Focusable && !node.ParentEditable + case DocumentFormField: + return snapshot.Focusable && documentFormFieldRole(snapshot) + case DocumentImage: + return snapshot.Role == "image" || snapshot.Role == "image map" + case DocumentLandmark: + return snapshot.Role == "landmark" + case DocumentListItem: + return snapshot.Role == "list item" + case DocumentLiveRegion: + return snapshot.LiveRegion + case DocumentParagraph: + if snapshot.Role == "heading" { + return true + } + return snapshot.Role == "paragraph" && snapshot.CharacterCount > 2 + case DocumentRadioButton: + return snapshot.Role == "radio button" + case DocumentTable: + return snapshot.Role == "table" && len(node.Children) != 0 && snapshot.TableRowCount > 0 && !snapshot.LayoutTable + case DocumentUnvisitedLink: + return snapshot.Role == "link" && snapshot.Focusable && !snapshot.Visited + case DocumentVisitedLink: + return snapshot.Role == "link" && snapshot.Focusable && snapshot.Visited + case DocumentClickable: + return snapshot.SupportsClick && !snapshot.Focusable && !documentClickExcludedRole(snapshot) && !documentHasXMLRole(snapshot, "gridcell") + case DocumentAnnotation: + return snapshot.Role == "content deletion" || snapshot.Role == "content insertion" || snapshot.Role == "mark" + case DocumentInternalFrame: + return snapshot.Role == "internal frame" + case DocumentMath: + return snapshot.Role == "math" + case DocumentChunk: + if documentChunkRole(snapshot) { + return snapshot.Role == "heading" || snapshot.Role == "list" || snapshot.Role == "table" || + (snapshot.CharacterCount > 75 && snapshot.EmbeddedObjectCount*20 < snapshot.CharacterCount) + } + return false + default: + return false + } +} + +func documentHasXMLRole(snapshot atspi.Snapshot, role string) bool { + for _, candidate := range strings.Fields(snapshot.XMLRoles) { + if candidate == role { + return true + } + } + return false +} + +func documentFormFieldRole(snapshot atspi.Snapshot) bool { + switch snapshot.Role { + case "button", "push button", "check box", "radio button", "combo box", "list box", "entry", "password text", "spin button", "toggle button": + return true + case "document frame", "text": + if snapshot.Role == "document frame" { + return snapshot.Editable + } + return true + default: + return false + } +} + +func documentClickExcludedRole(snapshot atspi.Snapshot) bool { + switch snapshot.Role { + case "combo box", "entry", "list box", "menu", "menu item", "check menu item", "radio menu item", "page tab", "page tab list", "password text", "progress bar", "slider", "spin button", "tool bar", "tree item", "tree table", "tree": + return true + default: + return false + } +} + +func documentChunkRole(snapshot atspi.Snapshot) bool { + switch snapshot.Role { + case "heading", "list item", "math", "paragraph", "static", "column header", "row header", "table cell", "table row", "text", "section", "article", "description term", "description value", "document email", "document frame", "document presentation", "document spreadsheet", "document text", "document web", "block quote", "description list", "form", "footer", "header", "landmark", "log", "list", "marquee", "panel", "table", "tree", "tree table": + return true + default: + return false + } +} + +func documentObject(doc atspi.DocumentSnapshot, ref atspi.ObjectReference) (atspi.Snapshot, bool) { + node, ok := doc.Node(ref.ID()) + if !ok || node.Reference != ref { + return atspi.Snapshot{}, false + } + return node.Snapshot, true +} + +func documentPosition(doc atspi.DocumentSnapshot, place documentPlace) DocumentPosition { + snapshot, _ := documentObject(doc, place.object) + position := DocumentPosition{Document: place.document, Object: place.object, Snapshot: snapshot, Origin: place.origin, Offset: place.offset} + if place.origin == StructuralNavigation && snapshot.Role == "heading" { + if link, ok, _ := linkedHeadingNode(doc, place.object); ok { + position.LinkedHeading = &link.Snapshot + } + } + return position +} + +// A heading inside a link and a heading containing exactly one link have the +// same activation target. With multiple links, use the link at the first +// readable caret position, matching Python's heading navigation. A heading +// starting with plain text has no unambiguous link target. +func linkedHeadingNode(doc atspi.DocumentSnapshot, heading atspi.ObjectReference) (atspi.DocumentNode, bool, bool) { + root, ok := doc.Node(heading.ID()) + if !ok || root.Reference != heading || root.Snapshot.Role != "heading" { + return atspi.DocumentNode{}, false, false + } + for parent := root.Parent; parent.Valid(); { + node, found := doc.Node(parent) + if !found || atspi.IsWebDocumentRole(node.Snapshot.Role) { + break + } + if node.Snapshot.Role == "link" { + return node, true, false + } + parent = node.Parent + } + var match atspi.DocumentNode + count := 0 + pending := append([]atspi.ObjectID(nil), root.Children...) + for len(pending) != 0 && count < 2 { + id := pending[len(pending)-1] + pending = pending[:len(pending)-1] + node, found := doc.Node(id) + if !found || node.Hidden || node.Snapshot.Role == "heading" { + continue + } + if node.Snapshot.Role == "link" { + match, count = node, count+1 + continue + } + pending = append(pending, node.Children...) + } + if count > 1 { + // Semantic captures need not include text offsets (notably Gecko's + // link leaves). Use readable content and provider child order here. + pending = append([]atspi.ObjectID(nil), root.Children...) + for left, right := 0, len(pending)-1; left < right; left, right = left+1, right-1 { + pending[left], pending[right] = pending[right], pending[left] + } + for len(pending) != 0 { + id := pending[len(pending)-1] + pending = pending[:len(pending)-1] + node, found := doc.Node(id) + if !found || node.Hidden { + continue + } + if node.Snapshot.Role == "heading" || atspi.IsWebDocumentRole(node.Snapshot.Role) { + break + } + readable := strings.TrimSpace(node.Snapshot.Name+node.Snapshot.Text) != "" || node.Snapshot.CharacterCount > 0 + if !wholeCaretNode(node.Snapshot) && !(readable && (len(node.Children) == 0 || node.Snapshot.Role == "link")) { + for child := len(node.Children) - 1; child >= 0; child-- { + pending = append(pending, node.Children[child]) + } + continue + } + var firstLink atspi.DocumentNode + for id.Valid() { + if id == heading.ID() { + if firstLink.Reference.Valid() { + // Gecko may omit plain text between child accessibles. + // A named first link must also start the heading label. + headingName := strings.TrimSpace(root.Snapshot.Name) + linkName := strings.TrimSpace(firstLink.Snapshot.Name) + if headingName != "" && linkName != "" && !strings.HasPrefix(headingName, linkName) { + break + } + return firstLink, true, false + } + break + } + node, found := doc.Node(id) + if !found { + break + } + if node.Snapshot.Role == "heading" || atspi.IsWebDocumentRole(node.Snapshot.Role) { + break + } + if node.Snapshot.Role == "link" && !firstLink.Reference.Valid() { + firstLink = node + } + id = node.Parent + } + // Only the heading's starting caret position can select a link. + break + } + } + return match, count == 1, count > 1 +} diff --git a/internal/review/document_activation_test.go b/internal/review/document_activation_test.go new file mode 100644 index 0000000..fafe61d --- /dev/null +++ b/internal/review/document_activation_test.go @@ -0,0 +1,151 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type refreshingActivator struct { + *readAllCapturer + target atspi.ObjectID + staleOnce bool +} + +func TestActivationDoesNotRecaptureNonClickableText(t *testing.T) { + cursor := newCaretTextCursor(t, caretTextReader{webID("/text"): "Ordinary paragraph"}) + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, _ := NewWorker(capturer, time.Second) + worker.SyncFocus(webID("/text")) + result, _ := worker.activateDocumentCaret(context.Background(), cursor, 0) + if !errors.Is(result.Err, ErrNoDocumentAction) || len(capturer.calls) != 0 { + t.Fatalf("plain text triggered a capture: %+v", result) + } +} + +func TestActivationRejectsReplacedDocumentGeneration(t *testing.T) { + tree := activationTree(t, true) + cursor, _ := NewDocumentCursor(tree) + cursor.SyncFocus(context.Background(), webID("/focused")) + cursor.places[0].object, _ = tree.Reference(webID("/selected")) + tree.Invalidate(webID("/doc")) + nodes := []atspi.TreeNode{ + {Snapshot: atspi.Snapshot{BusName: webID("/doc").BusName, Path: "/doc", Role: "document web"}, Children: []atspi.ObjectID{webID("/focused"), webID("/selected")}}, + {Snapshot: atspi.Snapshot{BusName: webID("/focused").BusName, Path: "/focused", Role: "link"}}, + {Snapshot: atspi.Snapshot{BusName: webID("/selected").BusName, Path: "/selected", Role: "link"}}, + } + if err := tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + activator := &refreshingActivator{readAllCapturer: &readAllCapturer{tree: tree}} + worker, _ := NewWorker(activator, time.Second) + worker.SyncFocus(webID("/focused")) + result, _ := worker.activateDocumentCaret(context.Background(), cursor, 0) + if result.Err == nil || activator.target.Valid() { + t.Fatalf("activation crossed a document generation: %+v, %v", result, activator.target) + } +} + +func TestBrowseNamedCustomClickableAndActivateAncestor(t *testing.T) { + reader := caretTextReader{webID("/start"): "Before action", webID("/label"): "Visible label", webID("/after"): "After action"} + for _, explicit := range []bool{false, true} { + nodes := []atspi.TreeNode{ + {Snapshot: atspi.Snapshot{BusName: webID("/doc").BusName, Path: "/doc", Role: "document web"}, Children: []atspi.ObjectID{webID("/start"), webID("/custom"), webID("/after")}}, + {Snapshot: atspi.Snapshot{BusName: webID("/start").BusName, Path: "/start", Role: "static", CharacterCount: 13}}, + {Snapshot: atspi.Snapshot{BusName: webID("/custom").BusName, Path: "/custom", Role: "section", Name: "Perform action", SupportsClick: true, ExplicitName: explicit}, Children: []atspi.ObjectID{webID("/label")}}, + {Snapshot: atspi.Snapshot{BusName: webID("/label").BusName, Path: "/label", Role: "static", CharacterCount: 13}}, + {Snapshot: atspi.Snapshot{BusName: webID("/after").BusName, Path: "/after", Role: "static", CharacterCount: 12}}, + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + cursor.SyncFocus(context.Background(), webID("/start")) + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextLine) + want := webID("/label") + if explicit { + want = webID("/custom") + } + if err != nil || !move.Moved || move.Position.Object.ID() != want { + t.Fatalf("custom clickable stop: %+v, %v", move, err) + } + target, err := cursor.ActivationTarget() + if err != nil || target.ID() != webID("/custom") { + t.Fatalf("activation target = %v, %v", target, err) + } + move, err = cursor.MoveCaret(context.Background(), reader, CaretNextLine) + if err != nil || move.Text != "After action" { + t.Fatalf("clickable trapped navigation: %+v, %v", move, err) + } + } +} + +func (activator *refreshingActivator) ActivateDocumentObject(_ context.Context, target atspi.ObjectReference, _ atspi.ObjectID) error { + if activator.staleOnce { + activator.staleOnce = false + return atspi.ErrStaleObject + } + activator.target = target.ID() + return nil +} + +func activationTree(t *testing.T, includeSelected bool) *atspi.AccessibleTree { + t.Helper() + root := atspi.TreeNode{Snapshot: atspi.Snapshot{BusName: webID("/doc").BusName, Path: "/doc", Role: "document web"}, Children: []atspi.ObjectID{webID("/focused")}} + nodes := []atspi.TreeNode{root, {Snapshot: atspi.Snapshot{BusName: webID("/focused").BusName, Path: "/focused", Role: "link"}}} + if includeSelected { + nodes[0].Children = append(nodes[0].Children, webID("/selected")) + nodes = append(nodes, atspi.TreeNode{Snapshot: atspi.Snapshot{BusName: webID("/selected").BusName, Path: "/selected", Role: "link"}}) + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + return tree +} + +func TestActivationRecoversUncapturedAndStaleCursors(t *testing.T) { + for _, kind := range []string{"uncaptured", "stale", "removed", "native-stale"} { + t.Run(kind, func(t *testing.T) { + fresh := activationTree(t, kind != "removed") + activator := &refreshingActivator{readAllCapturer: &readAllCapturer{tree: fresh}, staleOnce: kind == "native-stale"} + worker, _ := NewWorker(activator, time.Second) + worker.SyncFocus(webID("/focused")) + var cursor *DocumentCursor + if kind != "uncaptured" { + old := activationTree(t, true) + cursor, _ = NewDocumentCursor(old) + cursor.SyncFocus(context.Background(), webID("/focused")) + cursor.places[0].object, _ = old.Reference(webID("/selected")) + if kind != "native-stale" { + old.Invalidate(webID("/selected")) + } + } + result, updated := worker.activateDocumentCaret(context.Background(), cursor, 0) + if kind == "removed" { + if result.Err == nil || activator.target.Valid() { + t.Fatal("activated a different link after selected link disappeared") + } + } else { + want := webID("/selected") + if kind == "uncaptured" { + want = webID("/focused") + } + if result.Err != nil || activator.target != want { + t.Fatalf("activation = %v, %v; want %v", activator.target, result.Err, want) + } + if current, err := updated.ActivationTarget(); err != nil || current.ID() != want { + t.Fatalf("cursor lost after activation: %v, %v", current, err) + } + } + }) + } +} diff --git a/internal/review/document_benchmark_test.go b/internal/review/document_benchmark_test.go new file mode 100644 index 0000000..a349846 --- /dev/null +++ b/internal/review/document_benchmark_test.go @@ -0,0 +1,224 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "fmt" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// Include focus synchronization and worker bookkeeping, which the primitive +// heading benchmark intentionally excludes. Native provider work is separate. +func BenchmarkDocumentWorkerHeadingNavigation(b *testing.B) { + for _, contentNodes := range []int{100, 1000, 10000} { + b.Run(fmt.Sprintf("nodes-%d", contentNodes), func(b *testing.B) { + tree, ids := benchmark_document_tree(b, contentNodes) + cursor, err := NewDocumentCursor(tree) + if err != nil { + b.Fatal(err) + } + worker, err := NewWorker(&fakeCapturer{}, time.Second) + if err != nil { + b.Fatal(err) + } + middle := contentNodes / 40 * 20 + worker.SyncFocus(ids[middle]) + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, ids[middle]); err != nil { + b.Fatal(err) + } + b.ReportAllocs() + for b.Loop() { + for _, backwards := range []bool{false, true} { + result, next := worker.moveDocument(ctx, cursor, DocumentHeading, 2, backwards, 0) + cursor = next + want := ids[middle+20] + if backwards { + want = ids[middle] + } + if result.Err != nil || !result.Moved || result.DocumentPosition.Object.ID() != want || result.DocumentDiagnostics.CaptureAttempts != 0 { + b.Fatalf("worker move: moved=%v error=%v", result.Moved, result.Err) + } + } + } + }) + } +} + +func BenchmarkDocumentCaretNavigation(b *testing.B) { + for _, contentNodes := range []int{100, 1000, 10000} { + b.Run(fmt.Sprintf("nodes-%d", contentNodes), func(b *testing.B) { + tree, ids := benchmark_document_tree(b, contentNodes) + cursor, err := NewDocumentCursor(tree) + if err != nil { + b.Fatal(err) + } + middle := contentNodes/2 + 2 + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, ids[middle]); err != nil { + b.Fatal(err) + } + reader := caretTextReader{ids[middle]: fmt.Sprintf("Café sample %d", middle)} + // Build the view's reusable ranges before measuring repeated keys. + for _, command := range []DocumentCaretCommand{CaretNextCharacter, CaretPreviousCharacter} { + if _, err := cursor.MoveCaret(ctx, reader, command); err != nil { + b.Fatal(err) + } + } + b.ReportAllocs() + for b.Loop() { + for _, command := range []DocumentCaretCommand{CaretNextCharacter, CaretPreviousCharacter} { + move, err := cursor.MoveCaret(ctx, reader, command) + want := 1 + if command == CaretPreviousCharacter { + want = 0 + } + if err != nil || !move.Moved || move.Position.Object.ID() != ids[middle] || move.Position.Offset != want { + b.Fatalf("caret move: moved=%v error=%v", move.Moved, err) + } + } + } + }) + } +} + +// benchmark_document_tree models an already captured page, not native AT-SPI +// capture. Each section has twenty content objects: a heading, a link, and +// ordinary text. Pairs of objects share a visual row, including Unicode text. +func benchmark_document_tree(b *testing.B, contentNodes int) (*atspi.AccessibleTree, []atspi.ObjectID) { + b.Helper() + rootID := webID("/benchmark/document") + root := atspi.NewSnapshot(rootID.Path, "Benchmark page", "document web", "", "") + root.BusName = rootID.BusName + nodes := []atspi.TreeNode{{Snapshot: root}} + contentIDs := make([]atspi.ObjectID, contentNodes) + sectionIndex := 0 + for index := range contentNodes { + if index%20 == 0 { + sectionID := webID(fmt.Sprintf("/benchmark/section_%d", index/20)) + section := atspi.NewSnapshot(sectionID.Path, "", "section", "", "") + section.BusName = sectionID.BusName + nodes[0].Children = append(nodes[0].Children, sectionID) + sectionIndex = len(nodes) + nodes = append(nodes, atspi.TreeNode{Snapshot: section}) + } + id := webID(fmt.Sprintf("/benchmark/content_%d", index)) + contentIDs[index] = id + role, text := "static", fmt.Sprintf("Café sample %d", index) + switch index % 20 { + case 0: + role, text = "heading", fmt.Sprintf("Heading %d", index/20) + case 1: + role, text = "link", fmt.Sprintf("Link %d", index/20) + } + snapshot := atspi.NewSnapshot(id.Path, text, role, "", text) + snapshot.BusName = id.BusName + snapshot.CharacterCount = utf8.RuneCountInString(text) + if role == "heading" { + snapshot.HeadingLevel = 2 + } + bounds := atspi.Rectangle{X: int32(index%2) * 200, Y: int32(index/2) * 24, Width: 180, Height: 20} + nodes[sectionIndex].Children = append(nodes[sectionIndex].Children, id) + nodes = append(nodes, atspi.TreeNode{ + Snapshot: snapshot, + Geometry: atspi.Geometry{Bounds: bounds, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true}, + Text: atspi.VisibleText{Known: true, Ranges: []atspi.TextRange{{ + Start: 0, End: snapshot.CharacterCount, Text: text, Bounds: bounds, + }}}, + }) + } + tree, err := atspi.NewAccessibleTree(rootID, nodes) + if err != nil { + b.Fatal(err) + } + return tree, contentIDs +} + +func BenchmarkDocumentSnapshot(b *testing.B) { + for _, contentNodes := range []int{100, 1000, 10000} { + b.Run(fmt.Sprintf("nodes-%d", contentNodes), func(b *testing.B) { + tree, _ := benchmark_document_tree(b, contentNodes) + root, err := tree.Root() + if err != nil { + b.Fatal(err) + } + ctx := context.Background() + wantNodes := contentNodes + contentNodes/20 + 1 + b.ReportAllocs() + for b.Loop() { + document, err := tree.Document(ctx, root) + if err != nil || len(document.Nodes) != wantNodes { + b.Fatalf("document snapshot: nodes=%d, error=%v", len(document.Nodes), err) + } + } + }) + } +} + +func BenchmarkDocumentHeadingNavigation(b *testing.B) { + for _, contentNodes := range []int{100, 1000, 10000} { + for _, scenario := range []string{"adjacent", "wrap"} { + b.Run(fmt.Sprintf("nodes-%d/%s", contentNodes, scenario), func(b *testing.B) { + tree, contentIDs := benchmark_document_tree(b, contentNodes) + cursor, err := NewDocumentCursor(tree) + if err != nil { + b.Fatal(err) + } + ctx := context.Background() + startIndex := contentNodes / 40 * 20 + wantWrapped := scenario == "wrap" + if wantWrapped { + startIndex = contentNodes - 20 + } + nextIndex := (startIndex + 20) % contentNodes + if _, err := cursor.SyncFocus(ctx, contentIDs[startIndex]); err != nil { + b.Fatal(err) + } + b.ReportAllocs() + for b.Loop() { + // One operation is a round trip. Returning to the same heading + // keeps the workload independent of the calibrated loop count. + move, err := cursor.Move(ctx, DocumentHeading, 2, false) + if err != nil || !move.Moved || move.Position.Object.ID() != contentIDs[nextIndex] || move.Wrapped != wantWrapped { + b.Fatalf("forward heading navigation: moved=%v, error=%v", move.Moved, err) + } + move, err = cursor.Move(ctx, DocumentHeading, 2, true) + if err != nil || !move.Moved || move.Position.Object.ID() != contentIDs[startIndex] || move.Wrapped != wantWrapped { + b.Fatalf("backward heading navigation: moved=%v, error=%v", move.Moved, err) + } + } + }) + } + } +} + +func BenchmarkDocumentLineAssembly(b *testing.B) { + for _, contentNodes := range []int{100, 1000, 10000} { + b.Run(fmt.Sprintf("nodes-%d", contentNodes), func(b *testing.B) { + tree, contentIDs := benchmark_document_tree(b, contentNodes) + middle := contentNodes / 2 + reference, err := tree.Reference(contentIDs[middle]) + if err != nil { + b.Fatal(err) + } + ctx := context.Background() + b.ReportAllocs() + for b.Loop() { + line, err := tree.DocumentLineAtOffset(ctx, reference, 1) + if err != nil || len(line.Contents) != 2 { + b.Fatalf("line assembly: contents=%d, error=%v", len(line.Contents), err) + } + if line.Contents[0].Reference.ID() != contentIDs[middle] || line.Contents[1].Reference.ID() != contentIDs[middle+1] { + b.Fatal("line assembly returned the wrong visual row") + } + } + }) + } +} diff --git a/internal/review/document_braille.go b/internal/review/document_braille.go new file mode 100644 index 0000000..b67220c --- /dev/null +++ b/internal/review/document_braille.go @@ -0,0 +1,75 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// readDocumentBraille reads the accepted line and selection ranges for its +// inline fragments. Optional display reads never fail or repeat navigation. +func (worker *Worker) readDocumentBraille(ctx context.Context, result Result) Result { + if !worker.documentBraille.Load() || !result.Moved || result.Err != nil || result.CaretErr != nil || + !worker.CurrentDocumentResult(result) || worker.focus() != result.DocumentFocus || + result.DocumentCaretCommand >= TableLeft || result.DocumentPosition.Snapshot.Role == "password text" { + return result + } + // Explicitly named links are atomic browse objects. Their native text may + // contain only a numeric badge; braille must use the same accessible label + // as speech rather than enriching it with that incomplete child text. + if snapshot := result.DocumentPosition.Snapshot; snapshot.Role == "link" && wholeCaretNode(snapshot) { + return result + } + reader, ok := worker.nativeCapturerFor(result.DocumentFocus).(DocumentCaretReader) + if !ok || !result.DocumentPosition.Object.Valid() { + return result + } + // Display enrichment must not hold ordinary speech/navigation for the + // longer whole-document capture timeout. + deadline, cancel := context.WithTimeout(ctx, min(worker.captureTimeout, 100*time.Millisecond)) + defer cancel() + line, err := reader.ReadDocumentCaret(deadline, result.DocumentPosition.Object, result.DocumentPosition.Offset, atspi.DocumentCaretBrailleLine) + if err != nil { + result.DocumentBrailleErr = err + return result + } + if line.Start < 0 || result.DocumentPosition.Offset < line.Start || + result.DocumentPosition.Offset-line.Start > utf8.RuneCountInString(line.Text) || line.Text == "" { + result.DocumentBrailleErr = atspi.ErrNoDocumentCaret + return result + } + result.DocumentBrailleLine = &line + if assembled := result.DocumentCaretLine; assembled != nil { + copyLine := *assembled + copyLine.Contents = append([]atspi.DocumentContent(nil), assembled.Contents...) + for index := range copyLine.Contents { + content := ©Line.Contents[index] + content.Snapshot.SelectionStart, content.Snapshot.SelectionEnd = 0, 0 + selected := line + if content.Snapshot.ID() != result.DocumentPosition.Object.ID() { + if !content.Reference.Valid() { + continue + } + selected, err = reader.ReadDocumentCaret(deadline, content.Reference, content.Start, atspi.DocumentCaretBrailleLine) + if err != nil { + continue + } + } + start, end := content.Start-selected.Start, content.Start-selected.Start+utf8.RuneCountInString(content.RawText) + runes := []rune(selected.Text) + if start < 0 || end > len(runes) || string(runes[start:end]) != content.RawText { + continue + } + content.Snapshot.SelectionStart, content.Snapshot.SelectionEnd = selected.SelectionStart, selected.SelectionEnd + content.Snapshot.TextAttributeRuns = selected.TextAttributeRuns + } + result.DocumentCaretLine = ©Line + } + return result +} diff --git a/internal/review/document_braille_routing.go b/internal/review/document_braille_routing.go new file mode 100644 index 0000000..e69ccc0 --- /dev/null +++ b/internal/review/document_braille_routing.go @@ -0,0 +1,134 @@ +package review + +import ( + "context" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type documentBrailleRequest struct { + ctx context.Context + focus, document, target atspi.ObjectID + line string + start, offset int + done chan error +} + +// RouteDocumentBraille shares the navigation FIFO. The display session may +// wait, but input and event callbacks never wait for native caret placement. +func (worker *Worker) RouteDocumentBraille(ctx context.Context, epoch uint64, focus, document, target atspi.ObjectID, line string, start, offset int) error { + if err := ctx.Err(); err != nil { + return err + } + route := &documentBrailleRequest{ctx: ctx, focus: focus, document: document, target: target, line: line, start: start, offset: offset, done: make(chan error, 1)} + select { + case worker.requests <- request{brailleRoute: route, documentEpoch: epoch, queuedAt: time.Now()}: + default: + return ErrRequestQueueFull + } + select { + case err := <-route.done: + return err + case <-ctx.Done(): + return ctx.Err() + } +} + +func (worker *Worker) route_document_braille(ctx context.Context, cursor *DocumentCursor, request request) (result Result) { + route := request.brailleRoute + result = Result{DocumentBrailleRoute: true, DocumentCaretCommand: CaretReadLine, DocumentFocus: route.focus, DocumentEpoch: request.documentEpoch} + defer func() { route.done <- result.Err }() + if cursor == nil || worker.focus() != route.focus || !worker.CurrentDocumentResult(result) { + result.Err = atspi.ErrStaleObject + return + } + ctx, cancel := context.WithTimeout(ctx, worker.captureTimeout) + stop := context.AfterFunc(route.ctx, cancel) + defer stop() + defer cancel() + if result.Err = route.ctx.Err(); result.Err != nil { + return + } + target, err := cursor.tree.Reference(route.target) + if err != nil { + result.Err = err + return + } + owner, err := cursor.tree.DocumentContext(target) + if err != nil || owner.TopLevel.ID() != route.document { + result.Err = atspi.ErrStaleObject + return + } + router, ok := worker.nativeCapturerFor(route.focus).(interface { + RouteBraille(context.Context, atspi.BrailleRoute) error + }) + if !ok { + result.Err = atspi.ErrNoDocumentCaret + return + } + reader, ok := worker.nativeCapturerFor(route.focus).(DocumentCaretReader) + if !ok { + result.Err = atspi.ErrNoDocumentCaret + return + } + doc, err := cursor.tree.DocumentView(ctx, target) + if err != nil { + result.Err = err + return + } + node, caretOffset, err := native_caret_node(ctx, reader, doc, route.target, route.offset) + if err != nil { + result.Err = err + return + } + if node.Hidden { + result.Err = atspi.ErrStaleObject + return + } + result.Err = router.RouteBraille(ctx, atspi.BrailleRoute{Focus: route.focus, Position: target, Line: route.line, Start: route.start, Offset: route.offset}) + if result.Err != nil || worker.focus() != route.focus || !worker.CurrentDocumentResult(result) { + if result.Err == nil { + result.Err = atspi.ErrStaleObject + } + return + } + // Keep the document anchor; a routed inline child is not native focus. + cursor.mu.Lock() + if len(cursor.places) == 0 || cursor.active.ID() != route.document { + cursor.mu.Unlock() + result.Err = atspi.ErrStaleObject + return + } + place := &cursor.places[len(cursor.places)-1] + place.object, place.offset, place.origin = node.Reference, caretOffset, CaretNavigation + place.tableCell = atspi.ObjectID{} + remember_text_parent(doc, place) + snapshot, err := cursor.tree.Resolve(node.Reference) + result.DocumentPosition = DocumentPosition{Document: owner.TopLevel, Object: node.Reference, Snapshot: snapshot, Offset: caretOffset, Origin: CaretNavigation} + cursor.mu.Unlock() + result.Err, result.Moved = err, err == nil + result.DocumentCaretContext = owner.Ancestors + if result.Moved && worker.documentBraille.Load() { + // Optional assembly refresh preserves surrounding inline fragments while + // retaining the exact routed offset. It never repeats caret placement. + deadline, cancel := context.WithTimeout(ctx, 100*time.Millisecond) + defer cancel() + indices := caretNodeRanges(doc.Nodes) + position := -1 + for index, candidate := range indices { + if doc.Nodes[candidate.index].Reference == node.Reference && caretOffset >= candidate.start && caretOffset < candidate.end { + position = index + break + } + } + if position >= 0 { + parts, err := collect_visual_line(deadline, reader, doc, indices, visual_line_owners(doc.Nodes), position, caretOffset, true) + if err == nil && len(parts) > 1 { + line, _, _ := assemble_visual_line(cursor.tree, doc, parts) + result.DocumentCaretLine = &line + } + } + } + return +} diff --git a/internal/review/document_braille_routing_test.go b/internal/review/document_braille_routing_test.go new file mode 100644 index 0000000..c5e8505 --- /dev/null +++ b/internal/review/document_braille_routing_test.go @@ -0,0 +1,91 @@ +package review + +import ( + "context" + "errors" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type brailleDocumentNavigator struct { + *boundaryNavigator + routes chan atspi.BrailleRoute + routeErr error +} + +func (navigator *brailleDocumentNavigator) RouteBraille(ctx context.Context, route atspi.BrailleRoute) error { + if err := ctx.Err(); err != nil { + return err + } + navigator.routes <- route + return navigator.routeErr +} + +func TestDocumentBrailleRoutingUpdatesBrowseCursorAndRejectsStaleRequests(t *testing.T) { + text := caretTextReader{webID("/text"): "é猫 word", webID("/next"): "Next line"} + navigator := &brailleDocumentNavigator{boundaryNavigator: &boundaryNavigator{fakeCapturer: &fakeCapturer{calls: make(chan captureCall, 1)}, caretTextReader: text}, routes: make(chan atspi.BrailleRoute, 4)} + worker, cancel := startWorker(t, navigator, time.Second) + defer cancel() + worker.SetDocumentBrailleEnabled(true) + worker.SyncFocus(webID("/text")) + if err := worker.MoveDocumentCaret(CaretDocumentStart); err != nil { + t.Fatal(err) + } + call := <-navigator.calls + call.result <- captureResult{tree: newCaretTextCursor(t, text).tree} + first := waitResult(t, worker) + ctx, stop := context.WithTimeout(context.Background(), time.Second) + defer stop() + route := func(epoch uint64, focus, document atspi.ObjectID) error { + return worker.RouteDocumentBraille(ctx, epoch, focus, document, webID("/text"), "é猫 word", 0, 4) + } + if err := route(first.DocumentEpoch, first.DocumentFocus, first.DocumentPosition.Document.ID()); err != nil { + t.Fatal(err) + } + routed := waitResult(t, worker) + if !routed.DocumentBrailleRoute || !routed.Moved || routed.DocumentPosition.Offset != 4 || routed.DocumentBrailleLine == nil { + t.Fatalf("route result = %+v", routed) + } + if native := <-navigator.routes; !native.Position.Valid() || native.Offset != 4 || native.Focus != first.DocumentFocus { + t.Fatalf("native route = %+v", native) + } + if err := worker.MoveDocumentCaret(CaretNextCharacter); err != nil { + t.Fatal(err) + } + if result := waitResult(t, worker); result.DocumentPosition.Offset != 5 || result.DocumentCaretText != "o" { + t.Fatalf("arrow did not follow routed cursor: %+v", result) + } + navigator.routeErr = atspi.ErrStaleObject + if err := route(first.DocumentEpoch, first.DocumentFocus, first.DocumentPosition.Document.ID()); !errors.Is(err, atspi.ErrStaleObject) { + t.Fatalf("native refusal = %v", err) + } + if failed := waitResult(t, worker); failed.Moved { + t.Fatal("native refusal moved the virtual cursor") + } + <-navigator.routes + if err := worker.MoveDocumentCaret(CaretNextCharacter); err != nil { + t.Fatal(err) + } + if result := waitResult(t, worker); result.DocumentPosition.Offset != 6 { + t.Fatalf("failed routing changed cursor: %+v", result) + } + navigator.routeErr = nil + canceled, stopCanceled := context.WithCancel(ctx) + stopCanceled() + if err := worker.RouteDocumentBraille(canceled, first.DocumentEpoch, first.DocumentFocus, first.DocumentPosition.Document.ID(), webID("/text"), "é猫 word", 0, 0); !errors.Is(err, context.Canceled) { + t.Fatalf("canceled routing = %v", err) + } + if err := route(first.DocumentEpoch, first.DocumentFocus, webID("/other")); !errors.Is(err, atspi.ErrStaleObject) { + t.Fatalf("other page route = %v", err) + } + waitResult(t, worker) + worker.ResetDocument(first.DocumentFocus) + if err := route(first.DocumentEpoch, first.DocumentFocus, first.DocumentPosition.Document.ID()); !errors.Is(err, atspi.ErrStaleObject) { + t.Fatalf("retired epoch route = %v", err) + } + if len(navigator.routes) != 0 { + t.Fatal("stale route reached native owner") + } +} diff --git a/internal/review/document_braille_test.go b/internal/review/document_braille_test.go new file mode 100644 index 0000000..3d9b0ca --- /dev/null +++ b/internal/review/document_braille_test.go @@ -0,0 +1,81 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type documentBrailleReader struct { + *fakeCapturer + line atspi.DocumentCaretText + err error + calls int +} + +func (reader *documentBrailleReader) ReadDocumentCaret(_ context.Context, _ atspi.ObjectReference, _ int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + if unit != atspi.DocumentCaretBrailleLine { + return atspi.DocumentCaretText{}, errors.New("expected raw braille line") + } + reader.calls++ + return reader.line, reader.err +} + +func TestDocumentBrailleReadsOnlyEnabledAcceptedNavigation(t *testing.T) { + reader := &documentBrailleReader{fakeCapturer: &fakeCapturer{}, line: atspi.DocumentCaretText{Start: 10, End: 17, Text: "é猫 line"}} + worker, err := NewWorker(reader, time.Second) + if err != nil { + t.Fatal(err) + } + cursor := newCaretTextCursor(t, caretTextReader{webID("/text"): "Text"}) + position, err := cursor.tree.Reference(webID("/text")) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/text")) + result := Result{Moved: true, DocumentCaretCommand: CaretNextCharacter, DocumentFocus: webID("/text"), + DocumentPosition: DocumentPosition{Object: position, Offset: 12}} + for _, test := range []struct { + name string + modify func(*Result) + }{ + {"disabled", func(*Result) { worker.SetDocumentBrailleEnabled(false) }}, + {"boundary", func(r *Result) { r.Moved = false }}, + {"navigation failure", func(r *Result) { r.Err = atspi.ErrStaleObject }}, + {"placement failure", func(r *Result) { r.CaretErr = atspi.ErrStaleObject }}, + {"retired page", func(r *Result) { r.DocumentEpoch++ }}, + {"other focus", func(r *Result) { r.DocumentFocus = webID("/other") }}, + {"table", func(r *Result) { r.DocumentCaretCommand = TableRight }}, + {"password", func(r *Result) { r.DocumentPosition.Snapshot.Role = "password text" }}, + {"explicit link", func(r *Result) { + r.DocumentPosition.Snapshot = atspi.Snapshot{Role: "link", Name: "Example Game 2 copies", ExplicitName: true} + }}, + } { + t.Run(test.name, func(t *testing.T) { + worker.SetDocumentBrailleEnabled(true) + r := result + test.modify(&r) + got := worker.readDocumentBraille(context.Background(), r) + if got.DocumentBrailleLine != nil || reader.calls != 0 { + t.Fatalf("unaccepted navigation read display text: %+v; calls=%d", got, reader.calls) + } + }) + } + worker.SetDocumentBrailleEnabled(true) + got := worker.readDocumentBraille(context.Background(), result) + if got.DocumentBrailleLine == nil || got.DocumentBrailleLine.Text != reader.line.Text || reader.calls != 1 { + t.Fatalf("raw line not preserved: %+v; calls=%d", got, reader.calls) + } + reader.err = atspi.ErrStaleObject + got = worker.readDocumentBraille(context.Background(), result) + if got.DocumentBrailleLine != nil || got.Err != nil || !got.Moved || !errors.Is(got.DocumentBrailleErr, reader.err) { + t.Fatalf("braille read failure changed successful navigation: %+v", got) + } +} diff --git a/internal/review/document_caret.go b/internal/review/document_caret.go new file mode 100644 index 0000000..23e5fd2 --- /dev/null +++ b/internal/review/document_caret.go @@ -0,0 +1,170 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// DocumentCaretCommand follows Python Cthulhu's browse caret key families. +type DocumentCaretCommand uint8 + +const ( + CaretNextCharacter DocumentCaretCommand = iota + 1 + CaretPreviousCharacter + CaretNextWord + CaretPreviousWord + CaretNextLine + CaretPreviousLine + CaretLineStart + CaretLineEnd + CaretDocumentStart + CaretDocumentEnd + CaretReadLine + TableLeft + TableRight + TableUp + TableDown + TableFirst + TableLast +) + +func (command DocumentCaretCommand) valid() bool { + return command >= CaretNextCharacter && command <= TableLast +} + +func (command DocumentCaretCommand) String() string { + names := [...]string{"invalid", "next-character", "previous-character", + "next-word", "previous-word", "next-line", "previous-line", "line-start", + "line-end", "document-start", "document-end", "read-line", "table-left", + "table-right", "table-up", "table-down", "table-first", "table-last"} + if !command.valid() { + return names[0] + } + return names[command] +} + +type DocumentCaretReader interface { + ReadDocumentCaret(context.Context, atspi.ObjectReference, int, atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) +} + +type DocumentCharacterReader interface { + ReadDocumentCharacters(context.Context, atspi.ObjectReference, int) (atspi.DocumentCaretText, error) +} + +type DocumentCaretMove struct { + Position DocumentPosition + Text string + RawText string + Misspelled bool + // Line retains each object's native range for an assembled visual line. + Line *atspi.DocumentLine + TablePrefix, TableSuffix string + + TableRowHeader, TableColumnHeader string + + Moved bool + // Text range used for this move, in Unicode character offsets. Named + // links use accessible-label offsets rather than native text offsets. + Start, End int +} + +// MoveCaret advances the independent browse position using AT-SPI text units +// or accessible-label units for explicitly named links. +// It does not depend on Chromium's retained native caret. A stale captured +// document is reported to the worker for one bounded refresh. +func (cursor *DocumentCursor) MoveCaret(ctx context.Context, reader DocumentCaretReader, command DocumentCaretCommand) (DocumentCaretMove, error) { + if !command.valid() || reader == nil { + return DocumentCaretMove{}, ErrInvalidDirection + } + cursor.mu.Lock() + defer cursor.mu.Unlock() + if !cursor.active.Valid() || len(cursor.places) == 0 { + return DocumentCaretMove{}, ErrNoCurrent + } + saved := &cursor.places[len(cursor.places)-1] + next := *saved + place := &next + doc, err := cursor.tree.NavigationDocument(ctx, place.object) + if err != nil { + return DocumentCaretMove{}, err + } + if doc.Context.TopLevel != place.document { + return DocumentCaretMove{}, atspi.ErrStaleObject + } + current, found := doc.Index(place.object.ID()) + if !found || doc.Nodes[current].Reference != place.object { + return DocumentCaretMove{}, atspi.ErrStaleObject + } + if err := cursor.tree.ValidateDocumentRange(ctx, doc, current, current); err != nil { + return DocumentCaretMove{}, err + } + if command >= TableLeft { + movement, err := cursor.moveTable(ctx, doc, place, command) + if err == nil && movement.Moved { + *saved = next + } + return movement, err + } + place.tableCell = atspi.ObjectID{} + if !doc.SameContent(cursor.caretDocument) { + cursor.caretDocument = doc + cursor.caretRanges = caretNodeRanges(doc.Nodes) + cursor.caretLookup = new_caret_range_lookup(cursor.caretRanges, len(doc.Nodes)) + cursor.lineOwners = visual_line_owners(doc.Nodes) + } + indices := cursor.caretRanges + if len(indices) == 0 { + if err := cursor.tree.ValidateDocumentRange(ctx, doc, 0, len(doc.Nodes)-1); err != nil { + return DocumentCaretMove{}, err + } + return DocumentCaretMove{Position: documentPosition(doc, *place)}, nil + } + var movement DocumentCaretMove + navigationReader := &navigationTextReader{DocumentCaretReader: reader, tree: cursor.tree, document: doc, anchor: current} + reader = navigationReader + if characters, ok := navigationReader.DocumentCaretReader.(DocumentCharacterReader); ok { + reader = &navigationCharacterReader{navigationTextReader: navigationReader, source: characters} + } + switch command { + case CaretNextWord, CaretPreviousWord, CaretNextCharacter, CaretPreviousCharacter: + movement, err = moveCaretText(ctx, reader, doc, place, indices, cursor.caretLookup, current, + command == CaretPreviousWord || command == CaretPreviousCharacter, + command == CaretNextWord || command == CaretPreviousWord) + default: + movement, err = move_caret_line(ctx, reader, cursor.tree, doc, place, indices, cursor.caretLookup, current, command, cursor.lineOwners) + } + if err == nil && movement.Moved { + target, found := doc.Index(place.object.ID()) + if !found { + return DocumentCaretMove{}, atspi.ErrStaleObject + } + // Successful text already belongs to this move even if the provider + // removes its ancestor immediately afterwards. Repeating that move + // during recovery would skip the line. Synthetic whole-object stops + // still need validation because they bypass the native text reader. + if !navigationReader.did_read(place.object) { + if err := cursor.tree.ValidateDocumentRange(ctx, doc, current, target); err != nil { + return DocumentCaretMove{}, err + } + } + remember_text_parent(doc, place) + *saved = next + } else if err == nil { + // Reaching a boundary must not silently skip newly readable text in a + // dirty object which had no caret range in the captured view. + boundary := len(doc.Nodes) - 1 + if command == CaretPreviousCharacter || command == CaretPreviousWord || command == CaretPreviousLine || command == CaretDocumentStart { + boundary = 0 + } + if err := cursor.tree.ValidateDocumentRange(ctx, doc, current, boundary); err != nil { + return DocumentCaretMove{}, err + } + } + return movement, err +} diff --git a/internal/review/document_caret_editable_test.go b/internal/review/document_caret_editable_test.go new file mode 100644 index 0000000..6623b22 --- /dev/null +++ b/internal/review/document_caret_editable_test.go @@ -0,0 +1,109 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "strings" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func editable_caret_cursor(t *testing.T) (*DocumentCursor, caretTextReader) { + t.Helper() + reader := caretTextReader{ + webID("/before"): "Suggested wording", + webID("/editor"): "\ufffc\ufffc", + webID("/first"): "Review the code.\nReport actionable issues.", + webID("/second"): "Explain the evidence.", + webID("/secret"): "Private fixture text", + webID("/after"): "Following paragraph", + } + node := func(path, role string, editable bool, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, "", role, "", "") + snapshot.BusName = webID(path).BusName + snapshot.Editable = editable + snapshot.CharacterCount = utf8.RuneCountInString(reader[webID(path)]) + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "document web", false, "/before", "/editor", "/password", "/after"), + node("/before", "static", false), + node("/editor", "entry", true, "/paragraph", "/second"), + node("/paragraph", "paragraph", true, "/first"), + node("/first", "static", true), + node("/second", "static", true), + node("/password", "password text", true, "/secret"), + // Even a provider which omits editable state on a password child + // must not expose that child's text through browse navigation. + node("/secret", "static", false), + node("/after", "static", false), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(context.Background(), webID("/before")); err != nil { + t.Fatal(err) + } + return cursor, reader +} + +func TestDocumentCaretReadsEditableDescendants(t *testing.T) { + ctx := context.Background() + cursor, reader := editable_caret_cursor(t) + for _, step := range []struct { + command DocumentCaretCommand + want string + }{ + {CaretNextLine, "Review the code."}, + {CaretNextLine, "Report actionable issues."}, + {CaretNextLine, "Explain the evidence."}, + {CaretNextLine, "Following paragraph"}, + {CaretPreviousLine, "Explain the evidence."}, + {CaretPreviousLine, "Report actionable issues."}, + {CaretLineStart, "R"}, + {CaretNextCharacter, "e"}, + {CaretNextWord, "Report"}, + {CaretPreviousLine, "Review the code."}, + {CaretPreviousLine, "Suggested wording"}, + } { + move, err := cursor.MoveCaret(ctx, reader, step.command) + if err != nil || !move.Moved || strings.TrimSpace(move.Text) != step.want { + t.Fatalf("%s: %q at %s, moved %t, %v; want %q", step.command, move.Text, + move.Position.Snapshot.Path, move.Moved, err, step.want) + } + } +} + +func TestReadAllIncludesEditableDescendants(t *testing.T) { + cursor, reader := editable_caret_cursor(t) + capturer := &readAllCapturer{tree: cursor.tree, caretTextReader: reader} + worker, err := NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/before")) + result := worker.readAll(context.Background(), cursor) + want := []string{"Suggested wording", "Review the code.", "Report actionable issues.", "Explain the evidence.", "Following paragraph"} + if result.Err != nil || len(result.ReadAllLines) != len(want) { + t.Fatalf("Read All: %d lines, %v; want %d", len(result.ReadAllLines), result.Err, len(want)) + } + for index, line := range result.ReadAllLines { + if got := strings.TrimSpace(line.Contents[0].Text); got != want[index] { + t.Fatalf("Read All line %d: %q; want %q", index, got, want[index]) + } + } +} diff --git a/internal/review/document_caret_glyph_test.go b/internal/review/document_caret_glyph_test.go new file mode 100644 index 0000000..b828bfe --- /dev/null +++ b/internal/review/document_caret_glyph_test.go @@ -0,0 +1,137 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func glyph_cursor(t *testing.T, parentRole string, modify func(*atspi.Snapshot)) (*DocumentCursor, caretTextReader) { + t.Helper() + reader := caretTextReader{webID("/before"): "Member", webID("/icon"): "\uf005", webID("/after"): "Join Date"} + node := func(path, role string, children ...string) atspi.TreeNode { + text := reader[webID(path)] + snapshot := atspi.NewSnapshot(path, text, role, "", text) + snapshot.BusName, snapshot.StatesKnown = webID(path).BusName, true + snapshot.CharacterCount = utf8.RuneCountInString(text) + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + root := node("/doc", "document web", "/before", "/rank", "/after") + root.Snapshot.Focusable = true // A focusable document must not protect every icon. + parent := node("/rank", parentRole, "/icon") + if parentRole == "pre" || parentRole == "code" { + parent.Snapshot.HTMLTag = parentRole + } + icon := node("/icon", "static") + if modify != nil { + modify(&icon.Snapshot) + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + root, node("/before", "static"), parent, icon, node("/after", "static"), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(context.Background(), webID("/before")); err != nil { + t.Fatal(err) + } + return cursor, reader +} + +func TestDocumentCaretSkipsDecorativeGlyph(t *testing.T) { + ctx := context.Background() + for _, command := range []DocumentCaretCommand{CaretNextLine, CaretNextCharacter, CaretNextWord} { + t.Run(command.String(), func(t *testing.T) { + cursor, reader := glyph_cursor(t, "section", nil) + if command != CaretNextLine { + cursor.places[0].offset = len("Member") - 1 + } + move, err := cursor.MoveCaret(ctx, reader, command) + if err != nil || !move.Moved || move.Position.Object.ID() != webID("/after") { + t.Fatalf("forward: %+v, %v", move, err) + } + move, err = cursor.MoveCaret(ctx, reader, CaretPreviousLine) + if err != nil || !move.Moved || move.Text != "Member" { + t.Fatalf("backward: %+v, %v", move, err) + } + }) + } + // Focus/routing may leave the cursor on an omitted icon. Both directions + // must still reach surrounding text rather than report a stale position. + for _, command := range []DocumentCaretCommand{CaretNextLine, CaretPreviousLine} { + cursor, reader := glyph_cursor(t, "section", nil) + if _, err := cursor.SyncFocus(ctx, webID("/icon")); err != nil { + t.Fatal(err) + } + move, err := cursor.MoveCaret(ctx, reader, command) + want := "Join Date" + if command == CaretPreviousLine { + want = "Member" + } + if err != nil || !move.Moved || move.Text != want { + t.Fatalf("from icon %s: %+v, %v", command, move, err) + } + } +} + +func TestDocumentCaretPreservesMeaningfulGlyphs(t *testing.T) { + for _, test := range []struct { + name, parentRole string + modify func(*atspi.Snapshot) + }{ + {"link", "link", nil}, + {"code", "code", nil}, + {"pre", "pre", nil}, + {"focusable", "section", func(s *atspi.Snapshot) { s.Focusable = true }}, + {"clickable", "section", func(s *atspi.Snapshot) { s.SupportsClick = true }}, + {"editable", "section", func(s *atspi.Snapshot) { s.Editable, s.Role = true, "entry" }}, + {"named", "section", func(s *atspi.Snapshot) { s.ExplicitName = true }}, + {"description", "section", func(s *atspi.Snapshot) { s.Description = "Rating" }}, + {"unknown states", "section", func(s *atspi.Snapshot) { s.StatesKnown = false }}, + {"ordinary symbol", "section", func(s *atspi.Snapshot) { s.Name, s.Text = "★", "★" }}, + {"mixed text", "section", func(s *atspi.Snapshot) { s.Name, s.Text, s.CharacterCount = "Star \uf005", "Star \uf005", 6 }}, + {"different text", "section", func(s *atspi.Snapshot) { s.Text = "X" }}, + } { + t.Run(test.name, func(t *testing.T) { + cursor, reader := glyph_cursor(t, test.parentRole, test.modify) + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextLine) + if err != nil || !move.Moved || move.Position.Object.ID() != webID("/icon") { + t.Fatalf("meaningful glyph omitted: %+v, %v", move, err) + } + }) + } +} + +func TestReadAllSkipsDecorativeGlyph(t *testing.T) { + cursor, reader := glyph_cursor(t, "section", nil) + capturer := &readAllCapturer{tree: cursor.tree, caretTextReader: reader} + worker, err := NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/before")) + result := worker.readAll(context.Background(), cursor) + if result.Err != nil || len(result.ReadAllLines) != 2 { + t.Fatalf("Read All: %+v", result) + } + for index, want := range []string{"Member", "Join Date"} { + if got := result.ReadAllLines[index].Contents[0].Text; got != want { + t.Fatalf("line %d: %q, want %q", index, got, want) + } + } +} diff --git a/internal/review/document_caret_line.go b/internal/review/document_caret_line.go new file mode 100644 index 0000000..b2a0f82 --- /dev/null +++ b/internal/review/document_caret_line.go @@ -0,0 +1,177 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// move_caret_line handles line and document boundaries under the cursor lock +// held by MoveCaret. Text-unit movement has its separate traversal helper. +func move_caret_object_line(ctx context.Context, reader DocumentCaretReader, doc atspi.DocumentSnapshot, place *documentPlace, indices []caretRange, lookup *caretRangeLookup, current int, command DocumentCaretCommand) (DocumentCaretMove, error) { + unit := atspi.DocumentCaretLine + if command == CaretReadLine { + unit = atspi.DocumentCaretLineRemainder + } + position, same := lookup.position(indices, current, place.offset) + backwards := command == CaretPreviousLine || command == CaretDocumentEnd + if command == CaretDocumentStart { + position = 0 + } else if command == CaretDocumentEnd { + position = len(indices) - 1 + } + offset := place.offset + if !same || command == CaretDocumentStart { + offset = 0 + } + if command == CaretDocumentEnd { + offset = indices[position].end - 1 + } + if backwards && command != CaretDocumentEnd && !same { + position-- + if position < 0 { + return DocumentCaretMove{Position: documentPosition(doc, *place)}, nil + } + offset = indices[position].end - 1 + } + initialPosition := position + for attempts := 0; attempts < len(indices)+1; attempts++ { + if position < 0 || position >= len(indices) { + return DocumentCaretMove{Position: documentPosition(doc, *place)}, nil + } + node := doc.Nodes[indices[position].index] + if named_link_label(node.Snapshot) != "" && (command == CaretLineStart || command == CaretLineEnd) { + offset = 0 + if command == CaretLineEnd { + offset = caret_text_count(node.Snapshot) - 1 + } + character, err := read_caret_text(ctx, reader, node, offset, atspi.DocumentCaretCharacter) + if err != nil { + return DocumentCaretMove{}, err + } + place.object, place.offset, place.origin = node.Reference, offset, CaretNavigation + return DocumentCaretMove{Position: documentPosition(doc, *place), Text: character.Text, Moved: true, Start: character.Start, End: character.End}, nil + } + if node.Snapshot.CharacterCount == 0 || wholeCaretNode(node.Snapshot) { + if (command == CaretNextLine || command == CaretPreviousLine) && node.Reference == place.object { + if backwards { + position-- + if position >= 0 { + offset = indices[position].end - 1 + } + } else { + position++ + offset = 0 + } + continue + } + place.object, place.offset, place.origin = node.Reference, 0, CaretNavigation + return DocumentCaretMove{Position: documentPosition(doc, *place), Moved: true}, nil + } + if offset < indices[position].start { + offset = indices[position].start + } + if command == CaretReadLine && offset >= indices[position].end { + position++ + offset = 0 + continue + } + if offset >= indices[position].end { + offset = indices[position].end - 1 + } + piece, readErr := readCaretRange(ctx, reader, doc, indices[position], offset, unit) + if readErr != nil && !errors.Is(readErr, atspi.ErrNoDocumentCaret) { + return DocumentCaretMove{}, readErr + } + if readErr == nil && piece.End > piece.Start && strings.TrimSpace(piece.Text) != "\ufffc" { + nextOffset := offset + sameCurrent := position == initialPosition && same || + place.origin == StructuralNavigation && position == initialPosition && indices[position].index >= current + switch command { + case CaretNextLine: + if sameCurrent { + nextOffset = piece.End + if nextOffset < piece.CharacterCount { + piece, readErr = readCaretRange(ctx, reader, doc, indices[position], nextOffset, unit) + if readErr != nil { + return DocumentCaretMove{}, readErr + } + } else { + position++ + if position >= len(indices) { + return DocumentCaretMove{Position: documentPosition(doc, *place)}, nil + } + offset = 0 + continue + } + } + nextOffset = piece.Start + case CaretPreviousLine: + if sameCurrent { + if piece.Start > indices[position].start { + piece, readErr = readCaretRange(ctx, reader, doc, indices[position], piece.Start-1, unit) + if readErr != nil { + return DocumentCaretMove{}, readErr + } + } else { + position-- + if position < 0 { + return DocumentCaretMove{Position: documentPosition(doc, *place)}, nil + } + offset = indices[position].end - 1 + continue + } + } + nextOffset = piece.Start + case CaretLineStart: + nextOffset = piece.Start + case CaretLineEnd, CaretDocumentEnd: + nextOffset = max(piece.Start, piece.End-1) + case CaretDocumentStart: + nextOffset = piece.Start + } + if piece.End <= piece.Start || strings.TrimSpace(piece.Text) == "\ufffc" { + // An embedded-object placeholder is a container, not spoken text. + if backwards { + position-- + if position >= 0 { + offset = indices[position].end - 1 + } + } else { + position++ + offset = 0 + } + continue + } + spoken := piece.Text + if command == CaretLineStart || command == CaretLineEnd { + character, charErr := readCaretRange(ctx, reader, doc, indices[position], nextOffset, atspi.DocumentCaretCharacter) + if charErr != nil { + return DocumentCaretMove{}, charErr + } + spoken = character.Text + } + place.object = node.Reference + place.offset = nextOffset + place.origin = CaretNavigation + return DocumentCaretMove{Position: documentPosition(doc, *place), Text: spoken, RawText: piece.RawText, Misspelled: piece.Misspelled, Moved: true, Start: piece.Start, End: piece.End}, nil + } + if backwards { + position-- + if position >= 0 { + offset = indices[position].end - 1 + } + } else { + position++ + offset = 0 + } + } + return DocumentCaretMove{Position: documentPosition(doc, *place)}, nil +} diff --git a/internal/review/document_caret_nodes.go b/internal/review/document_caret_nodes.go new file mode 100644 index 0000000..a5641f9 --- /dev/null +++ b/internal/review/document_caret_nodes.go @@ -0,0 +1,121 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "strings" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func wholeCaretNode(snapshot atspi.Snapshot) bool { + if snapshot.Role == "link" { + return snapshot.ExplicitName && strings.TrimSpace(snapshot.Name) != "" + } + if snapshot.Role == "image" { + return snapshot.Name != "" || snapshot.Description != "" + } + // An explicitly named custom clickable is an atomic stop just like a + // named link. Ordinary clickable text remains readable by character/word. + if snapshot.SupportsClick && snapshot.ExplicitName && strings.TrimSpace(snapshot.Name) != "" && + !snapshot.Editable && !atspi.IsWebDocumentRole(snapshot.Role) { + return true + } + switch snapshot.Role { + case "button", "check box", "check menu item", "list box", "menu item", "page tab", + "radio menu item", "radio button", "push button", "toggle button": + return true + } + return false +} + +// Passive tooltips appear when their owner receives focus and disappear when +// caret placement moves focus away. Entering their text can strand navigation +// on a removed object and repeatedly recover to the owner's container. Match +// Orca's web caret policy while retaining focusable/editable tooltip content. +func passive_caret_tooltip(snapshot atspi.Snapshot) bool { + return snapshot.Role == "tool tip" && !snapshot.Focusable && !snapshot.Editable +} + +// caret_node_indices preserves provider order and treats whole controls as one +// stop. MoveCaret holds the document cursor lock while using these indices. +func caret_node_indices(nodes []atspi.DocumentNode, object atspi.ObjectReference) ([]int, int) { + // Container text normally embeds its child text. Whole controls are one + // caret stop even when their label is a child or they have no text interface. + // Python's web _treatObjectAsWhole makes the same distinction. + indices := make([]int, 0, len(nodes)) + current := -1 + skipped := make(map[atspi.ObjectID]bool) + protected := make(map[atspi.ObjectID]bool, len(nodes)) + var skipChildren func([]atspi.ObjectID) + children := make(map[atspi.ObjectID][]atspi.ObjectID, len(nodes)) + for _, node := range nodes { + children[node.Reference.ID()] = node.Children + } + skipChildren = func(ids []atspi.ObjectID) { + for _, id := range ids { + if skipped[id] { + continue + } + skipped[id] = true + skipChildren(children[id]) + } + } + for index, node := range nodes { + snapshot := node.Snapshot + // Icon-font text inside links, controls, editable text or code can + // carry meaning. Preserve that entire subtree, including static leaves. + protected[node.Reference.ID()] = protected[node.Parent] || snapshot.Editable || + !atspi.IsWebDocumentRole(snapshot.Role) && (snapshot.Focusable || snapshot.SupportsClick || snapshot.ExplicitName) || + snapshot.Role == "link" || wholeCaretNode(snapshot) || + snapshot.HTMLTag == "pre" || snapshot.HTMLTag == "code" || + strings.Contains(" "+snapshot.XMLRoles+" ", " code ") + if node.Reference == object { + current = index + } + if node.Hidden || skipped[node.Reference.ID()] { + continue + } + if snapshot.Role == "password text" || passive_caret_tooltip(snapshot) { + skipChildren(node.Children) + continue + } + if !protected[node.Reference.ID()] && decorative_caret_glyph(node) { + continue + } + if wholeCaretNode(node.Snapshot) { + indices = append(indices, index) + skipChildren(node.Children) + } else if node.Snapshot.Editable && + (node.Snapshot.Role == "entry" || node.Snapshot.Role == "text") && + (node.Snapshot.CharacterCount == 0 || len(node.Children) == 0) { + indices = append(indices, index) + } else if len(node.Children) == 0 && node.Snapshot.CharacterCount > 0 { + // Rich editors expose their contents as editable text leaves. + // Browse reading must descend into them just like ordinary text; + // the entry's embedded-object placeholders are not its contents. + indices = append(indices, index) + } + } + return indices, current +} + +// Python's web hasValidName/isUselessEmptyElement rejects standalone unnamed +// private-use icons. Keep this narrower: only a known non-interactive static +// leaf with one matching name/text character is omitted from browse reading. +func decorative_caret_glyph(node atspi.DocumentNode) bool { + snapshot := node.Snapshot + if snapshot.Role != "static" || !snapshot.StatesKnown || snapshot.Focusable || + snapshot.Editable || node.ParentEditable || snapshot.SupportsClick || snapshot.ExplicitName || + snapshot.Description != "" || len(node.Children) != 0 || snapshot.CharacterCount != 1 || + (snapshot.Text != "" && snapshot.Text != snapshot.Name) { + return false + } + character, size := utf8.DecodeRuneInString(snapshot.Name) + return size == len(snapshot.Name) && unicode.Is(unicode.Co, character) +} diff --git a/internal/review/document_caret_ranges.go b/internal/review/document_caret_ranges.go new file mode 100644 index 0000000..739be43 --- /dev/null +++ b/internal/review/document_caret_ranges.go @@ -0,0 +1,186 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "strings" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// A range uses native text offsets, except for explicitly named links whose +// label offsets stay virtual. Hypertext containers can occur more than once, +// before and after their embedded children. +type caretRange struct{ index, start, end int } + +func caretNodeRanges(nodes []atspi.DocumentNode) []caretRange { + indices, _ := caret_node_indices(nodes, atspi.ObjectReference{}) + eligible := make(map[int]bool, len(indices)) + byID := make(map[atspi.ObjectID]int, len(nodes)) + for _, index := range indices { + eligible[index] = true + } + for index, node := range nodes { + byID[node.Reference.ID()] = index + } + var result []caretRange + var visit func(int) + visit = func(index int) { + node := nodes[index] + if node.Hidden || node.Snapshot.Role == "password text" || passive_caret_tooltip(node.Snapshot) { + return + } + children := node.Snapshot.TextChildren + valid := len(children) > 0 && !node.Snapshot.Editable && !wholeCaretNode(node.Snapshot) + previous := -1 + direct := make(map[atspi.ObjectID]bool, len(node.Children)) + for _, id := range node.Children { + direct[id] = true + } + for _, child := range children { + if child.Offset <= previous || child.Offset >= node.Snapshot.CharacterCount || !direct[child.Child] { + valid = false + break + } + previous = child.Offset + } + if valid { + offset := 0 + for _, child := range children { + if offset < child.Offset { + result = append(result, caretRange{index, offset, child.Offset}) + } + if childIndex, ok := byID[child.Child]; ok { + visit(childIndex) + } + delete(direct, child.Child) + offset = child.Offset + 1 + } + if offset < node.Snapshot.CharacterCount { + result = append(result, caretRange{index, offset, node.Snapshot.CharacterCount}) + } + for _, id := range node.Children { + if direct[id] { + if child, ok := byID[id]; ok { + visit(child) + } + } + } + return + } + if eligible[index] { + result = append(result, caretRange{index, 0, caret_text_count(node.Snapshot)}) + if wholeCaretNode(node.Snapshot) { + return + } + } + for _, id := range node.Children { + if child, ok := byID[id]; ok { + visit(child) + } + } + } + if len(nodes) > 0 { + visit(0) + } + return result +} + +// Object-local range positions also handle a hypertext parent occurring on +// both sides of an embedded child. after preserves provider traversal order, +// which is not monotonically increasing in document node index. +type caretRangeLookup struct { + objects [][]int + after []int +} + +func new_caret_range_lookup(ranges []caretRange, nodeCount int) *caretRangeLookup { + lookup := &caretRangeLookup{objects: make([][]int, nodeCount), after: make([]int, nodeCount)} + for position, item := range ranges { + lookup.objects[item.index] = append(lookup.objects[item.index], position) + } + following := len(ranges) + for index := nodeCount - 1; index >= 0; index-- { + lookup.after[index] = following + if positions := lookup.objects[index]; len(positions) > 0 { + following = min(following, positions[0]) + } + } + return lookup +} + +func (lookup *caretRangeLookup) containing(ranges []caretRange, current, offset int) int { + for _, position := range lookup.objects[current] { + item := ranges[position] + if offset >= item.start && offset < max(item.start+1, item.end) { + return position + } + } + return -1 +} + +func (lookup *caretRangeLookup) position(ranges []caretRange, current, offset int) (int, bool) { + if position := lookup.containing(ranges, current, offset); position >= 0 { + return position, true + } + // Word and Read All cursors may be just after the final character. + for _, position := range lookup.objects[current] { + if offset == ranges[position].end { + return position, true + } + } + return lookup.after[current], false +} + +func readCaretRange(ctx context.Context, reader DocumentCaretReader, doc atspi.DocumentSnapshot, item caretRange, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + offset = max(item.start, min(offset, item.end-1)) + node := doc.Nodes[item.index] + text, err := read_caret_text(ctx, reader, node, offset, unit) + if err != nil || text.End <= text.Start { + return text, err + } + if item.start == 0 && item.end == caret_text_count(node.Snapshot) { + return text, nil + } + if text.Start < 0 || text.Start > offset || text.End <= offset || text.End > text.CharacterCount { + return text, nil + } + start, end := max(text.Start, item.start), min(text.End, item.end) + if start >= end { + return atspi.DocumentCaretText{CharacterCount: item.end}, nil + } + if start != text.Start || end != text.End { + raw := text.RawText + if raw == "" { + raw = text.Text + } + // Speech may be whitespace-normalized. Clip using the raw native text; + // never treat offsets in a normalized string as native character offsets. + runes := []rune(raw) + if unit == atspi.DocumentCaretLineRemainder && len(runes) > text.End-text.Start { + runes = runes[len(runes)-(text.End-text.Start):] + } + if len(runes) != text.End-text.Start { + return atspi.DocumentCaretText{}, atspi.ErrNoDocumentCaret + } + raw = string(runes[start-text.Start : end-text.Start]) + if text.RawText != "" { + text.RawText = raw + text.Text = strings.Join(strings.Fields(raw), " ") + } else { + text.Text = raw + } + text.Start, text.End = start, end + } + // Range-local traversal must stop at the embedded object. The retained + // snapshot still has the full native character count for routing/placement. + text.CharacterCount = item.end + if unit == atspi.DocumentCaretCharacter && utf8.RuneCountInString(text.Text) > 1 { + return atspi.DocumentCaretText{}, atspi.ErrNoDocumentCaret + } + return text, nil +} diff --git a/internal/review/document_caret_test.go b/internal/review/document_caret_test.go new file mode 100644 index 0000000..76fa329 --- /dev/null +++ b/internal/review/document_caret_test.go @@ -0,0 +1,562 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "fmt" + "testing" + "time" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type caretTextReader map[atspi.ObjectID]string + +func (reader caretTextReader) ReadDocumentCaret(_ context.Context, reference atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + value := reader[reference.ID()] + runes := []rune(value) + if offset < 0 || offset >= len(runes) { + return atspi.DocumentCaretText{CharacterCount: len(runes)}, nil + } + if unit == atspi.DocumentCaretCharacter { + return atspi.DocumentCaretText{Start: offset, End: offset + 1, Text: string(runes[offset]), CharacterCount: len(runes)}, nil + } + if unit == atspi.DocumentCaretWord { + start := offset + for start > 0 && !unicode.IsSpace(runes[start-1]) { + start-- + } + end := offset + for end < len(runes) && !unicode.IsSpace(runes[end]) { + end++ + } + for end < len(runes) && unicode.IsSpace(runes[end]) { + end++ + } + return atspi.DocumentCaretText{Start: start, End: end, Text: string(runes[start:end]), CharacterCount: len(runes)}, nil + } + start, end := offset, offset + for start > 0 && runes[start-1] != '\n' { + start-- + } + if unit == atspi.DocumentCaretLineRemainder { + start = offset + } + for end < len(runes) && runes[end] != '\n' { + end++ + } + if end < len(runes) { + end++ + } + return atspi.DocumentCaretText{Start: start, End: end, Text: string(runes[start:end]), CharacterCount: len(runes)}, nil +} + +func newCaretTextCursor(t *testing.T, reader caretTextReader) *DocumentCursor { + t.Helper() + nodes := []atspi.TreeNode{} + for _, path := range []string{"/doc", "/text", "/next"} { + snapshot := atspi.NewSnapshot(path, "", "static", "", "") + snapshot.BusName = webID(path).BusName + snapshot.CharacterCount = utf8.RuneCountInString(reader[webID(path)]) + node := atspi.TreeNode{Snapshot: snapshot} + if path == "/doc" { + node.Snapshot.Role = "document web" + node.Children = []atspi.ObjectID{webID("/text"), webID("/next")} + } + nodes = append(nodes, node) + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(context.Background(), webID("/text")); err != nil { + t.Fatal(err) + } + return cursor +} + +func TestDocumentCaretFromTrailingNonTextObject(t *testing.T) { + reader := caretTextReader{webID("/text"): "Last line"} + for _, test := range []struct { + command DocumentCaretCommand + path string + moved bool + }{ + {CaretNextLine, "/next", false}, + {CaretPreviousLine, "/text", true}, + {CaretDocumentStart, "/text", true}, + {CaretDocumentEnd, "/text", true}, + } { + t.Run(fmt.Sprint(test.command), func(t *testing.T) { + cursor := newCaretTextCursor(t, reader) + if _, err := cursor.SyncFocus(context.Background(), webID("/next")); err != nil { + t.Fatal(err) + } + move, err := cursor.MoveCaret(context.Background(), reader, test.command) + if err != nil || move.Moved != test.moved || move.Position.Object.ID() != webID(test.path) { + t.Fatalf("move = %+v, %v", move, err) + } + }) + } +} + +func TestDocumentCaretSkipsUnresolvedEmbeddedCharacters(t *testing.T) { + reader := caretTextReader{webID("/text"): "A\ufffc\ufeffB", webID("/next"): "C"} + cursor := newCaretTextCursor(t, reader) + for _, step := range []struct { + command DocumentCaretCommand + text string + offset int + }{ + {CaretNextCharacter, "B", 3}, + {CaretPreviousCharacter, "A", 0}, + } { + move, err := cursor.MoveCaret(context.Background(), reader, step.command) + if err != nil || !move.Moved || move.Text != step.text || move.Position.Offset != step.offset { + t.Fatalf("command %v: got %+v, %v", step.command, move, err) + } + } +} + +func TestDocumentCaretMovesFromConversationIntoControls(t *testing.T) { + reader := caretTextReader{ + webID("/message"): "Last reply", + webID("/label"): "Voice", + } + node := func(path, name, role string, count int, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, name, role, "", "") + snapshot.BusName = webID(path).BusName + snapshot.CharacterCount = count + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + entry := node("/composer", "Message", "entry", 0) + entry.Snapshot.Editable = true + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "", "document web", 0, "/message", "/voice", "/composer"), + node("/message", "", "static", 10), + node("/voice", "Voice", "button", 0, "/label"), + node("/label", "", "static", 5), + entry, + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, webID("/message")); err != nil { + t.Fatal(err) + } + for _, step := range []struct { + command DocumentCaretCommand + path string + moved bool + }{ + {CaretDocumentEnd, "/composer", true}, + {CaretPreviousLine, "/voice", true}, + {CaretPreviousLine, "/message", true}, + {CaretNextLine, "/voice", true}, + {CaretNextLine, "/composer", true}, + {CaretNextLine, "/composer", false}, + {CaretPreviousCharacter, "/voice", true}, + {CaretNextCharacter, "/composer", true}, + } { + move, err := cursor.MoveCaret(ctx, reader, step.command) + if err != nil || move.Moved != step.moved || move.Position.Object.ID() != webID(step.path) { + t.Fatalf("command %v: got %+v, %v; want %s moved %t", step.command, move, err, step.path, step.moved) + } + } +} + +func TestDocumentCaretReachesNamedImageInsideLink(t *testing.T) { + ctx := context.Background() + reader := caretTextReader{webID("/quote_text"): "Quote"} + node := func(path, name, role string, count int, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, name, role, "", "") + snapshot.BusName = webID(path).BusName + snapshot.CharacterCount = count + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "", "document web", 0, "/quote", "/decorative", "/thumb", "/next"), + node("/quote", "Quote", "link", 5, "/quote_text"), + node("/quote_text", "", "static", 5), + node("/decorative", "", "image", 0), + node("/thumb", "Thumbs up", "link", 1, "/thumb_image"), + node("/thumb_image", "Thumbs up", "image", 0), + node("/next", "Next post", "heading", 0), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, webID("/quote_text")); err != nil { + t.Fatal(err) + } + move, err := cursor.MoveCaret(ctx, reader, CaretNextLine) + if err != nil || !move.Moved || move.Position.Object.ID() != webID("/thumb_image") { + t.Fatalf("after Quote: %+v, %v", move, err) + } +} + +func TestDocumentCaretExplicitLinkPreservesNameInsteadOfBadge(t *testing.T) { + ctx := context.Background() + reader := caretTextReader{webID("/heading"): "Recent Games", webID("/badge"): "2", webID("/ordinary_text"): "Ordinary link"} + node := func(path, name, role string, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, name, role, "", "") + snapshot.BusName = webID(path).BusName + snapshot.CharacterCount = len([]rune(reader[webID(path)])) + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + card := node("/card", "Example Game 2 copies", "link", "/badge") + card.Snapshot.ExplicitName = true + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "", "document web", "/heading", "/card", "/ordinary", "/after"), + node("/heading", "Recent Games", "heading"), card, node("/badge", "", "static"), + node("/ordinary", "Ordinary link", "link", "/ordinary_text"), node("/ordinary_text", "", "static"), + node("/after", "After cards", "button"), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, webID("/heading")); err != nil { + t.Fatal(err) + } + for _, step := range []struct { + command DocumentCaretCommand + path, text string + }{ + {CaretNextLine, "/card", ""}, + {CaretNextCharacter, "/card", "x"}, + {CaretPreviousCharacter, "/card", "E"}, + {CaretNextWord, "/card", "Example "}, + {CaretNextWord, "/card", "Game "}, + {CaretNextLine, "/ordinary_text", "Ordinary link"}, + {CaretNextCharacter, "/ordinary_text", "r"}, + {CaretPreviousLine, "/card", ""}, + {CaretPreviousLine, "/heading", "Recent Games"}, + } { + move, err := cursor.MoveCaret(ctx, reader, step.command) + if err != nil || !move.Moved || move.Position.Object.ID() != webID(step.path) || move.Text != step.text { + t.Fatalf("%v: %+v, %v; want %s %q", step.command, move, err, step.path, step.text) + } + if step.path == "/card" && move.Position.Snapshot.Name != "Example Game 2 copies" { + t.Fatalf("lost card label: %+v", move.Position.Snapshot) + } + } +} + +func TestDocumentCaretNamedLinkCharacterBoundaries(t *testing.T) { + for _, nativeText := range []string{"", "2", "\ufffc"} { + t.Run(fmt.Sprintf("native=%q", nativeText), func(t *testing.T) { + reader := caretTextReader{webID("/text"): nativeText, webID("/next"): "."} + cursor := newCaretTextCursor(t, reader) + ctx := context.Background() + ref, err := cursor.tree.Reference(webID("/text")) + if err != nil { + t.Fatal(err) + } + snapshot, err := cursor.tree.Resolve(ref) + if err != nil { + t.Fatal(err) + } + snapshot.Role, snapshot.Name, snapshot.ExplicitName = "link", "É猫 Info", true + if err := cursor.tree.Replace(webID("/doc"), []atspi.TreeNode{ + {Snapshot: atspi.Snapshot{BusName: webID("/doc").BusName, Path: "/doc", Role: "document web"}, Children: []atspi.ObjectID{webID("/text"), webID("/next")}}, + {Snapshot: snapshot}, + {Snapshot: atspi.Snapshot{BusName: webID("/next").BusName, Path: "/next", Role: "static", CharacterCount: 1}}, + }); err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, webID("/text")); err != nil { + t.Fatal(err) + } + for _, step := range []struct { + command DocumentCaretCommand + text string + offset int + }{ + {CaretNextCharacter, "猫", 1}, + {CaretPreviousCharacter, "É", 0}, + {CaretNextCharacter, "猫", 1}, + {CaretNextCharacter, " ", 2}, + {CaretNextCharacter, "I", 3}, + {CaretNextCharacter, "n", 4}, + {CaretNextCharacter, "f", 5}, + {CaretNextCharacter, "o", 6}, + {CaretNextCharacter, ".", 0}, + {CaretPreviousCharacter, "o", 6}, + {CaretPreviousWord, "Info", 3}, + {CaretPreviousWord, "É猫 ", 0}, + {CaretLineEnd, "o", 6}, + {CaretLineStart, "É", 0}, + } { + move, err := cursor.MoveCaret(ctx, reader, step.command) + if err != nil || !move.Moved || move.Text != step.text || move.Position.Offset != step.offset { + t.Fatalf("%v: %+v, %v; want %q at %d", step.command, move, err, step.text, step.offset) + } + } + navigator := &boundaryNavigator{fakeCapturer: &fakeCapturer{}, caretTextReader: reader} + worker, err := NewWorker(navigator, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/text")) + for index, want := range []string{"猫", " "} { + result, _ := worker.moveDocumentCaret(ctx, cursor, CaretNextCharacter, 0) + if result.Err != nil || result.CaretErr != nil || result.DocumentCaretText != want || + result.DocumentPosition.Offset != index+1 || navigator.offset != 0 || navigator.position != result.DocumentPosition.Object { + t.Fatalf("label offset changed native anchor or lost review progress: %+v; native offset=%d", result, navigator.offset) + } + } + }) + } +} + +func TestDocumentCaretKeepsDocumentFocusAfterTopLeafIsRemoved(t *testing.T) { + reader := caretTextReader{webID("/first"): "First", webID("/next"): "Next"} + document := atspi.NewSnapshot("/doc", "", "document web", "", "") + document.BusName = webID("/doc").BusName + first := atspi.NewSnapshot("/first", "", "static", "", "") + first.BusName, first.CharacterCount = document.BusName, 5 + next := atspi.NewSnapshot("/next", "", "static", "", "") + next.BusName, next.CharacterCount = document.BusName, 4 + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + {Snapshot: document, Children: []atspi.ObjectID{webID("/first"), webID("/next")}}, + {Snapshot: first}, {Snapshot: next}, + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, webID("/doc")); err != nil { + t.Fatal(err) + } + start, err := cursor.MoveCaret(ctx, reader, CaretDocumentStart) + if err != nil || start.Position.Object.ID() != webID("/first") { + t.Fatalf("top of document: %+v, %v", start, err) + } + if err := tree.Replace(webID("/doc"), []atspi.TreeNode{ + {Snapshot: document, Children: []atspi.ObjectID{webID("/next")}}, + {Snapshot: next}, + }); err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, webID("/doc")); err != nil { + t.Fatalf("stable document focus lost: %v", err) + } + move, err := cursor.MoveCaret(ctx, reader, CaretNextCharacter) + if err != nil || !move.Moved || move.Text != "N" || move.Position.Object.ID() != webID("/next") { + t.Fatalf("arrow after removed top leaf: %+v, %v", move, err) + } +} + +func TestDocumentCaretPreviousLineSkipsPlaceholderBackwards(t *testing.T) { + reader := caretTextReader{webID("/text"): "A", webID("/next"): "\ufffc\nB"} + cursor := newCaretTextCursor(t, reader) + ctx := context.Background() + end, err := cursor.MoveCaret(ctx, reader, CaretDocumentEnd) + if err != nil || end.Text != "B" { + t.Fatalf("document end: %+v, %v", end, err) + } + previous, err := cursor.MoveCaret(ctx, reader, CaretPreviousLine) + if err != nil || !previous.Moved || previous.Text != "A" { + t.Fatalf("previous line across placeholder: %+v, %v", previous, err) + } +} + +func TestDocumentCaretWordDirectionAndWhitespace(t *testing.T) { + reader := caretTextReader{webID("/text"): "Alpha beta 猫", webID("/next"): "Next"} + cursor := newCaretTextCursor(t, reader) + ctx := context.Background() + // Python nextContext/previousContext starts one character away, skips + // whitespace, and then chooses the containing word, even on reversal. + for _, step := range []struct { + command DocumentCaretCommand + path string + offset int + text string + }{ + {CaretNextWord, "/text", 5, "Alpha "}, + {CaretNextWord, "/text", 11, "beta "}, + {CaretPreviousWord, "/text", 6, "beta "}, + {CaretPreviousWord, "/text", 0, "Alpha "}, + {CaretNextWord, "/text", 5, "Alpha "}, + {CaretNextWord, "/text", 11, "beta "}, + {CaretNextWord, "/text", 13, "猫"}, + {CaretNextWord, "/next", 4, "Next"}, + {CaretPreviousCharacter, "/next", 3, "t"}, + {CaretPreviousWord, "/next", 0, "Next"}, + {CaretPreviousWord, "/text", 12, "猫"}, + } { + move, err := cursor.MoveCaret(ctx, reader, step.command) + if err != nil || !move.Moved || move.Position.Object.ID() != webID(step.path) || move.Position.Offset != step.offset || move.Text != step.text { + t.Fatalf("command %v: got %+v, %v; want %s:%d %q", step.command, move, err, step.path, step.offset, step.text) + } + } +} + +type invalidWordReader struct { + caretTextReader + word atspi.DocumentCaretText + err error +} + +func (reader invalidWordReader) ReadDocumentCaret(ctx context.Context, reference atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + if reference.ID() == webID("/text") && unit == atspi.DocumentCaretWord { + return reader.word, reader.err + } + return reader.caretTextReader.ReadDocumentCaret(ctx, reference, offset, unit) +} + +func TestDocumentCaretWordAcrossInvalidEmojiRange(t *testing.T) { + text := caretTextReader{webID("/text"): "🧻", webID("/next"): "After emoji"} + for _, test := range []struct { + name string + word atspi.DocumentCaretText + }{ + {"negative end", atspi.DocumentCaretText{Start: 0, End: -1, Text: "�", CharacterCount: 1}}, + {"empty range", atspi.DocumentCaretText{CharacterCount: 1}}, + {"range outside text", atspi.DocumentCaretText{Start: 0, End: 2, Text: "�", CharacterCount: 1}}, + {"empty text", atspi.DocumentCaretText{Start: 0, End: 1, CharacterCount: 1}}, + } { + t.Run(test.name, func(t *testing.T) { + reader := invalidWordReader{caretTextReader: text, word: test.word} + cursor := newCaretTextCursor(t, text) + ctx := context.Background() + if _, err := cursor.MoveCaret(ctx, reader, CaretDocumentEnd); err != nil { + t.Fatal(err) + } + for _, step := range []struct { + command DocumentCaretCommand + path string + offset int + text string + }{ + {CaretPreviousWord, "/next", 6, "emoji"}, + {CaretPreviousWord, "/next", 0, "After "}, + {CaretPreviousWord, "/text", 0, "🧻"}, + {CaretNextWord, "/next", 5, "After "}, + {CaretPreviousWord, "/next", 0, "After "}, + {CaretPreviousWord, "/text", 0, "🧻"}, + } { + move, err := cursor.MoveCaret(ctx, reader, step.command) + if err != nil || !move.Moved || move.Position.Object.ID() != webID(step.path) || move.Position.Offset != step.offset || move.Text != step.text { + t.Fatalf("%v: got %+v, %v; want %s:%d %q", step.command, move, err, step.path, step.offset, step.text) + } + } + }) + } +} + +func TestDocumentCaretWordPreservesNativeErrors(t *testing.T) { + text := caretTextReader{webID("/text"): "🧻🧻", webID("/next"): "After"} + for _, nativeErr := range []error{atspi.ErrStaleObject, context.Canceled, atspi.ErrNoDocumentCaret} { + reader := invalidWordReader{caretTextReader: text, err: nativeErr} + cursor := newCaretTextCursor(t, text) + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextWord) + if !errors.Is(err, nativeErr) || move.Moved { + t.Fatalf("native error %v: got %+v, %v", nativeErr, move, err) + } + } +} + +func TestDocumentCaretContinuesFromStructuralHeading(t *testing.T) { + reader := caretTextReader{ + webID("/first_text"): "First heading", + webID("/old_text"): "Old position", + webID("/second_text"): "Second heading", + webID("/next_text"): "Text after second heading", + } + node := func(path, role string, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, path, role, "", "") + snapshot.BusName = webID(path).BusName + snapshot.CharacterCount = utf8.RuneCountInString(reader[webID(path)]) + if role == "heading" { + snapshot.HeadingLevel = 2 + } + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + tree, err := atspi.NewAccessibleTree(webID("/root"), []atspi.TreeNode{ + node("/root", "frame", "/doc"), + node("/doc", "document web", "/first", "/old", "/second", "/next"), + node("/first", "heading", "/first_text"), + node("/first_text", "static"), + node("/old", "paragraph", "/old_text"), + node("/old_text", "static"), + node("/second", "heading", "/second_text"), + node("/second_text", "static"), + node("/next", "paragraph", "/next_text"), + node("/next_text", "static"), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, webID("/old_text")); err != nil { + t.Fatal(err) + } + jump, err := cursor.Move(ctx, DocumentHeading, 0, false) + if err != nil || jump.Position.Object.ID() != webID("/second") { + t.Fatalf("heading jump = %+v, %v", jump, err) + } + line, err := cursor.MoveCaret(ctx, reader, CaretNextLine) + if err != nil || !line.Moved || line.Text != "Text after second heading" { + t.Fatalf("Down after heading = %+v, %v", line, err) + } + if _, err := cursor.SyncFocus(ctx, webID("/next_text")); err != nil { + t.Fatal(err) + } + character, err := cursor.MoveCaret(ctx, reader, CaretNextCharacter) + if err != nil || character.Text != "e" || character.Position.Offset != 1 { + t.Fatalf("Right after line = %+v, %v", character, err) + } + start, err := cursor.MoveCaret(ctx, reader, CaretDocumentStart) + if err != nil || start.Text != "First heading" || start.Position.Object.ID() != webID("/first_text") { + t.Fatalf("Ctrl+Home = %+v, %v", start, err) + } +} diff --git a/internal/review/document_caret_text.go b/internal/review/document_caret_text.go new file mode 100644 index 0000000..b3750eb --- /dev/null +++ b/internal/review/document_caret_text.go @@ -0,0 +1,139 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// Python caret_navigation starts a word move at the adjacent non-space +// character, rather than the next/previous word boundary. In particular, +// reversing at the end of a word must read that word, not skip over it. +func moveCaretText(ctx context.Context, reader DocumentCaretReader, doc atspi.DocumentSnapshot, place *documentPlace, indices []caretRange, lookup *caretRangeLookup, current int, backwards, byWord bool) (DocumentCaretMove, error) { + step := 1 + if backwards { + step = -1 + } + position, same := lookup.position(indices, current, place.offset) + offset := 0 + if same { + offset = place.offset + step + } else if backwards { + position-- + if position >= 0 { + offset = indices[position].end - 1 + } + } else if place.origin == StructuralNavigation { + offset = 1 + } + for position >= 0 && position < len(indices) { + if err := ctx.Err(); err != nil { + return DocumentCaretMove{}, err + } + node := doc.Nodes[indices[position].index] + if caret_text_count(node.Snapshot) == 0 || wholeCaretNode(node.Snapshot) && named_link_label(node.Snapshot) == "" { + if node.Reference != place.object { + place.object, place.offset, place.origin = node.Reference, 0, CaretNavigation + return DocumentCaretMove{Position: documentPosition(doc, *place), Moved: true}, nil + } + position += step + offset = 0 + if backwards && position >= 0 { + offset = indices[position].end - 1 + } + continue + } + if !backwards { + offset = max(offset, indices[position].start) + } + if offset >= indices[position].start && offset < indices[position].end { + character, err := readCaretRange(ctx, reader, doc, indices[position], offset, atspi.DocumentCaretCharacter) + if err != nil && !errors.Is(err, atspi.ErrNoDocumentCaret) { + return DocumentCaretMove{}, err + } + if err == nil && character.End > character.Start { + value, _ := utf8.DecodeRuneInString(character.Text) + if character.Text == "" || byWord && unicode.IsSpace(value) || value == '\ufffc' || value == '\ufeff' { + if blocks, ok := reader.(DocumentCharacterReader); byWord && unicode.IsSpace(value) && ok && named_link_label(node.Snapshot) == "" { + nextOffset, err := skip_word_spaces(ctx, blocks, node.Reference, indices[position], offset, step) + if err != nil { + return DocumentCaretMove{}, err + } + if nextOffset != offset { + offset = nextOffset + continue + } + } + offset += step + continue + } + if !byWord { + place.object, place.offset, place.origin = node.Reference, character.Start, CaretNavigation + return DocumentCaretMove{Position: documentPosition(doc, *place), Text: character.Text, Misspelled: character.Misspelled, Moved: true, Start: character.Start, End: character.End}, nil + } + word, err := readCaretRange(ctx, reader, doc, indices[position], offset, atspi.DocumentCaretWord) + if err != nil { + return DocumentCaretMove{}, err + } + if word.Text == "" || word.Start < 0 || word.Start > offset || word.End <= offset || word.End > word.CharacterCount { + // Chromium can expose an emoji as a valid character but + // return a broken WORD range (for example, end = -1). + // Read that character as a unit rather than trapping word + // navigation at the same position on every key press. + if character.Start < 0 || character.Start > offset || character.End <= offset || character.End > character.CharacterCount { + return DocumentCaretMove{}, atspi.ErrNoDocumentCaret + } + word = character + } + nextOffset := word.Start + if !backwards { + nextOffset = word.End + // WORD ranges may contain a trailing delimiter. Query its + // actual character; spoken word text can be normalized. + last, err := readCaretRange(ctx, reader, doc, indices[position], word.End-1, atspi.DocumentCaretCharacter) + if err != nil { + return DocumentCaretMove{}, err + } + value, _ := utf8.DecodeRuneInString(last.Text) + if unicode.IsSpace(value) { + nextOffset-- + } + } + place.object, place.offset, place.origin = node.Reference, nextOffset, CaretNavigation + return DocumentCaretMove{Position: documentPosition(doc, *place), Text: word.Text, Misspelled: word.Misspelled, Moved: true, Start: word.Start, End: word.End}, nil + } + } + position += step + offset = 0 + if backwards && position >= 0 { + offset = indices[position].end - 1 + } + } + return DocumentCaretMove{Position: documentPosition(doc, *place)}, nil +} + +// Keep native Unicode offsets and stop at embedded-object range boundaries. +// A broken optional block cannot advance the cursor; ordinary unit reads then +// retain their existing provider-error handling. +func skip_word_spaces(ctx context.Context, reader DocumentCharacterReader, object atspi.ObjectReference, item caretRange, offset, step int) (int, error) { + block, err := reader.ReadDocumentCharacters(ctx, object, offset) + if err != nil { + return offset, err + } + runes := []rune(block.RawText) + if block.Start < 0 || block.Start > offset || block.End <= offset || block.End > block.CharacterCount || len(runes) != block.End-block.Start { + return offset, nil + } + for offset >= item.start && offset < item.end && offset >= block.Start && offset < block.End && unicode.IsSpace(runes[offset-block.Start]) { + offset += step + } + return offset, nil +} diff --git a/internal/review/document_diagnostics.go b/internal/review/document_diagnostics.go new file mode 100644 index 0000000..16b2f73 --- /dev/null +++ b/internal/review/document_diagnostics.go @@ -0,0 +1,66 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import "git.stormux.org/storm/cthulhu/internal/atspi" + +// DocumentDiagnostics records bounded metadata for one navigation command. It +// never reads native objects or retains accessible text for diagnostic purposes. +type DocumentDiagnostics struct { + Attempts []DocumentAttempt `json:"attempts"` + CaptureAttempts int `json:"capture_attempts"` + CursorRecreated bool `json:"cursor_recreated"` + FocusRecovered bool `json:"focus_recovered"` +} + +type DocumentAttempt struct { + Focus atspi.ObjectID `json:"focus"` + Before DocumentState `json:"before"` + Synced DocumentState `json:"synced"` + After DocumentState `json:"after"` + Recovery string `json:"recovery"` + Stage string `json:"stage"` + Error string `json:"error,omitempty"` +} + +type DocumentState struct { + Document atspi.ObjectID `json:"document"` + Object atspi.ObjectID `json:"object"` + Focus atspi.ObjectID `json:"focus"` + TextParent atspi.ObjectID `json:"text_parent"` + Offset int `json:"offset"` + Origin string `json:"origin"` + Active bool `json:"active"` +} + +func (cursor *DocumentCursor) diagnostic_state() DocumentState { + if cursor == nil { + return DocumentState{} + } + cursor.mu.Lock() + defer cursor.mu.Unlock() + if len(cursor.places) == 0 { + return DocumentState{} + } + place := cursor.places[len(cursor.places)-1] + origin := "native" + switch place.origin { + case StructuralNavigation: + origin = "structural" + case CaretNavigation: + origin = "caret" + } + return DocumentState{Document: place.document.ID(), Object: place.object.ID(), + Focus: place.focus.ID(), TextParent: place.textParent.ID(), Offset: place.offset, + Origin: origin, Active: cursor.active == place.document} +} + +func (result *Result) record_document_attempt(cursor *DocumentCursor, attempt DocumentAttempt, err error) { + attempt.After = cursor.diagnostic_state() + if err != nil { + attempt.Error = err.Error() + } + result.DocumentDiagnostics.Attempts = append(result.DocumentDiagnostics.Attempts, attempt) +} diff --git a/internal/review/document_hypertext_test.go b/internal/review/document_hypertext_test.go new file mode 100644 index 0000000..2e6c07e --- /dev/null +++ b/internal/review/document_hypertext_test.go @@ -0,0 +1,280 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "testing" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func hypertextCursor(t *testing.T) (*DocumentCursor, caretTextReader) { + t.Helper() + return hypertextCursorWithLabel(t, "") +} + +func hypertextCursorWithLabel(t *testing.T, label string) (*DocumentCursor, caretTextReader) { + t.Helper() + reader := caretTextReader{webID("/body"): "Before \ufffc after.", webID("/link"): "Read more", webID("/tail"): "Next paragraph"} + node := func(path, role string, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, "", role, "", "") + snapshot.BusName = webID(path).BusName + snapshot.CharacterCount = utf8.RuneCountInString(reader[webID(path)]) + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + body := node("/body", "section", "/link") + body.Snapshot.TextChildren = []atspi.TextChild{{Offset: 7, Child: webID("/link")}} + link := node("/link", "link") + if label != "" { + link.Snapshot.Name, link.Snapshot.ExplicitName, link.Snapshot.CharacterCount = label, true, 0 + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "document web", "/body", "/tail"), body, link, node("/tail", "paragraph"), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(context.Background(), webID("/doc")); err != nil { + t.Fatal(err) + } + return cursor, reader +} + +func TestDocumentCaretReadsTextAroundEmbeddedLink(t *testing.T) { + cursor, reader := hypertextCursor(t) + for _, step := range []struct { + command DocumentCaretCommand + text, path string + offset int + }{ + {CaretDocumentStart, "Before ", "/body", 0}, + {CaretNextLine, "Read more", "/link", 0}, + {CaretNextLine, " after.", "/body", 8}, + {CaretNextLine, "Next paragraph", "/tail", 0}, + {CaretPreviousLine, " after.", "/body", 8}, + {CaretPreviousLine, "Read more", "/link", 0}, + {CaretPreviousLine, "Before ", "/body", 0}, + } { + move, err := cursor.MoveCaret(context.Background(), reader, step.command) + if err != nil || !move.Moved || move.Text != step.text || move.Position.Object.ID() != webID(step.path) || move.Position.Offset != step.offset { + t.Fatalf("%s: move=%+v err=%v; want %q at %s:%d", step.command, move, err, step.text, step.path, step.offset) + } + } +} + +func TestDocumentCaretCharactersCrossEmbeddedLink(t *testing.T) { + cursor, reader := hypertextCursor(t) + if _, err := cursor.MoveCaret(context.Background(), reader, CaretDocumentStart); err != nil { + t.Fatal(err) + } + var text string + for i := 0; i < 64; i++ { + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextCharacter) + if err != nil { + t.Fatal(err) + } + if move.Position.Object.ID() == webID("/tail") { + break + } + text += move.Text + } + if text != "efore Read more after." { + t.Fatalf("characters=%q", text) + } +} + +func TestNativeCaretKeepsHypertextParentOffsets(t *testing.T) { + cursor, reader := hypertextCursor(t) + if err := cursor.syncNativeCaret(context.Background(), reader, webID("/body"), 9); err != nil { + t.Fatal(err) + } + move, err := cursor.MoveCaret(context.Background(), reader, CaretPreviousCharacter) + if err != nil || move.Text != " " || move.Position.Offset != 8 || move.Position.Object.ID() != webID("/body") { + t.Fatalf("native hypertext caret: text=%q offset=%d err=%v", move.Text, move.Position.Offset, err) + } +} + +func TestDocumentCaretWordsCrossEmbeddedLink(t *testing.T) { + cursor, reader := hypertextCursor(t) + if _, err := cursor.MoveCaret(context.Background(), reader, CaretDocumentStart); err != nil { + t.Fatal(err) + } + for _, step := range []struct { + command DocumentCaretCommand + text, path string + offset int + }{ + {CaretNextWord, "Before ", "/body", 6}, + {CaretNextWord, "Read ", "/link", 4}, + {CaretNextWord, "more", "/link", 9}, + {CaretNextWord, "after.", "/body", 15}, + {CaretPreviousWord, "after.", "/body", 9}, + {CaretPreviousWord, "more", "/link", 5}, + } { + move, err := cursor.MoveCaret(context.Background(), reader, step.command) + if err != nil || move.Text != step.text || move.Position.Object.ID() != webID(step.path) || move.Position.Offset != step.offset { + t.Fatalf("%s: text=%q offset=%d err=%v; want %q at %s:%d", step.command, move.Text, move.Position.Offset, err, step.text, step.path, step.offset) + } + } +} + +func TestNativeCaretOnAdjacentEmbeddedLinks(t *testing.T) { + reader := caretTextReader{webID("/body"): "A\ufffc\ufffcZ", webID("/link1"): "One", webID("/link2"): "Two"} + node := func(path, role string, children ...string) atspi.TreeNode { + s := atspi.NewSnapshot(path, "", role, "", "") + s.BusName = webID(path).BusName + s.CharacterCount = utf8.RuneCountInString(reader[webID(path)]) + n := atspi.TreeNode{Snapshot: s} + for _, child := range children { + n.Children = append(n.Children, webID(child)) + } + return n + } + body := node("/body", "paragraph", "/link1", "/link2") + body.Snapshot.TextChildren = []atspi.TextChild{{Offset: 1, Child: webID("/link1")}, {Offset: 2, Child: webID("/link2")}} + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{node("/doc", "document web", "/body"), body, node("/link1", "link"), node("/link2", "link")}) + if err != nil { + t.Fatal(err) + } + for _, cmd := range []DocumentCaretCommand{CaretNextCharacter, CaretPreviousCharacter} { + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if err = cursor.syncNativeCaret(context.Background(), reader, webID("/body"), 2); err != nil { + t.Fatal(err) + } + move, err := cursor.MoveCaret(context.Background(), reader, cmd) + t.Logf("command=%s text=%q object=%s offset=%d err=%v", cmd, move.Text, move.Position.Object.ID().Path, move.Position.Offset, err) + want := "w" + if cmd == CaretPreviousCharacter { + want = "e" + } + if move.Text != want { + t.Errorf("want %q", want) + } + } +} + +func TestDocumentCaretEmbeddedNamedLinkKeepsLabelOffsets(t *testing.T) { + cursor, reader := hypertextCursorWithLabel(t, "É猫 Info") + for _, step := range []struct { + command DocumentCaretCommand + text, path string + offset int + }{ + {CaretDocumentStart, "Before ", "/body", 0}, + {CaretNextLine, "", "/link", 0}, + {CaretNextCharacter, "猫", "/link", 1}, + {CaretNextWord, "Info", "/link", 7}, + {CaretNextCharacter, " ", "/body", 8}, + {CaretPreviousCharacter, "o", "/link", 6}, + {CaretLineStart, "É", "/link", 0}, + {CaretPreviousCharacter, " ", "/body", 6}, + } { + move, err := cursor.MoveCaret(context.Background(), reader, step.command) + if err != nil || !move.Moved || move.Text != step.text || move.Position.Object.ID() != webID(step.path) || move.Position.Offset != step.offset { + t.Fatalf("%s: text=%q at %s:%d err=%v; want %q at %s:%d", step.command, move.Text, move.Position.Object.ID().Path, move.Position.Offset, err, step.text, step.path, step.offset) + } + } +} + +func TestDocumentCaretHypertextCannotEscapePasswordSubtree(t *testing.T) { + cursor, _ := hypertextCursor(t) + doc, err := cursor.tree.Document(context.Background(), cursor.places[0].object) + if err != nil { + t.Fatal(err) + } + // Even if editable state is missing, no nested hypertext may reintroduce + // the text suppressed by the password ancestor. + doc.Nodes[0].Snapshot.Role = "password text" + if ranges := caretNodeRanges(doc.Nodes); len(ranges) != 0 { + t.Fatalf("password subtree exposed caret ranges: %+v", ranges) + } +} + +// Plain-text changes need not change accessible children or their identities. +func TestDocumentCaretRefreshesChangedHypertextAncestor(t *testing.T) { + for _, command := range []DocumentCaretCommand{CaretNextCharacter, CaretPreviousCharacter, CaretNextWord, CaretPreviousWord, CaretNextLine, CaretPreviousLine, CaretReadLine} { + t.Run(command.String(), func(t *testing.T) { + reader := caretTextReader{webID("/body"): "\ufffc\ufffc", webID("/one"): "A", webID("/two"): "B"} + makeNode := func(path, role string, children ...string) atspi.TreeNode { + s := atspi.NewSnapshot(path, "", role, "", "") + s.BusName = webID(path).BusName + s.CharacterCount = utf8.RuneCountInString(reader[webID(path)]) + n := atspi.TreeNode{Snapshot: s} + for _, child := range children { + n.Children = append(n.Children, webID(child)) + } + return n + } + body := makeNode("/body", "paragraph", "/one", "/two") + body.Snapshot.TextChildren = []atspi.TextChild{{Offset: 0, Child: webID("/one")}, {Offset: 1, Child: webID("/two")}} + nodes := []atspi.TreeNode{makeNode("/doc", "document web", "/body"), body, makeNode("/one", "link"), makeNode("/two", "link")} + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + path := "/one" + if command == CaretPreviousCharacter || command == CaretPreviousWord || command == CaretPreviousLine { + path = "/two" + } + if _, err = cursor.SyncFocus(context.Background(), webID(path)); err != nil { + t.Fatal(err) + } + reader[webID("/body")] = "\ufffc inserted \ufffc" + tree.InvalidateText(webID("/body")) + if command == CaretReadLine { + cursor.places[0].offset = 1 + } + before := cursor.places[0] + move, err := cursor.MoveCaret(context.Background(), reader, command) + if !errors.Is(err, atspi.ErrStaleText) { + t.Fatalf("skipped parent insertion: move=%+v error=%v", move, err) + } + if after := cursor.places[0]; after.object != before.object || after.offset != before.offset { + t.Fatal("failed move changed position") + } + // A successful refresh must expose the insertion on the retry, + // retaining both embedded link identities and the original position. + nodes[1].Snapshot.CharacterCount = utf8.RuneCountInString(reader[webID("/body")]) + nodes[1].Snapshot.TextChildren = []atspi.TextChild{{Offset: 0, Child: webID("/one")}, {Offset: nodes[1].Snapshot.CharacterCount - 1, Child: webID("/two")}} + if err := tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + move, err = cursor.MoveCaret(context.Background(), reader, command) + if err != nil || !move.Moved || move.Position.Object.ID() != webID("/body") { + t.Fatalf("refreshed move skipped insertion: %+v error=%v", move, err) + } + }) + } +} + +func TestDocumentCaretLocalMoveSurvivesHypertextInsertion(t *testing.T) { + cursor, reader := hypertextCursor(t) + if _, err := cursor.SyncFocus(context.Background(), webID("/link")); err != nil { + t.Fatal(err) + } + cursor.tree.InvalidateText(webID("/body")) + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextCharacter) + if err != nil || move.Text != "e" { + t.Fatalf("local character: %+v %v", move, err) + } + if _, err = cursor.MoveCaret(context.Background(), reader, CaretNextLine); !errors.Is(err, atspi.ErrStaleText) { + t.Fatalf("crossing changed hypertext: %v", err) + } +} diff --git a/internal/review/document_inline_replacement_test.go b/internal/review/document_inline_replacement_test.go new file mode 100644 index 0000000..5d6b98f --- /dev/null +++ b/internal/review/document_inline_replacement_test.go @@ -0,0 +1,269 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "fmt" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func inline_replacement_cursor(t *testing.T, role string, slot int) (*DocumentCursor, caretTextReader, []atspi.TreeNode) { + t.Helper() + reader := caretTextReader{webID("/before"): "Published", webID("/old"): "↺ by Publisher", webID("/after"): "Article continues"} + paths := []string{"/before", "/after"} + paths = append(paths[:slot], append([]string{"/old"}, paths[slot:]...)...) + nodes := []atspi.TreeNode{ + {Snapshot: atspi.Snapshot{BusName: webID("/doc").BusName, Path: "/doc", Role: "document web"}, Children: []atspi.ObjectID{webID("/paragraph")}}, + {Snapshot: atspi.Snapshot{BusName: webID("/doc").BusName, Path: "/paragraph", Role: role}}, + } + if role == "link" { + nodes[1].Snapshot.Focusable, nodes[1].Snapshot.SupportsClick = true, true + } + for _, path := range paths { + nodes[1].Children = append(nodes[1].Children, webID(path)) + nodes = append(nodes, atspi.TreeNode{Snapshot: atspi.Snapshot{BusName: webID(path).BusName, + Path: path, Role: "static", CharacterCount: utf8.RuneCountInString(reader[webID(path)])}}) + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(context.Background(), webID("/paragraph")); err != nil { + t.Fatal(err) + } + if _, err := cursor.MoveCaret(context.Background(), reader, CaretReadLine); err != nil { + t.Fatal(err) + } + for index := 0; index < slot; index++ { + if _, err := cursor.MoveCaret(context.Background(), reader, CaretNextLine); err != nil { + t.Fatal(err) + } + } + return cursor, reader, nodes +} + +func TestDocumentCaretRecoversReplacedInlineText(t *testing.T) { + for _, role := range []string{"paragraph", "heading", "section", "link"} { + for slot := 0; slot < 3; slot++ { + t.Run(fmt.Sprintf("%s/%d", role, slot), func(t *testing.T) { + cursor, reader, nodes := inline_replacement_cursor(t, role, slot) + ctx := context.Background() + for generation := 0; generation < 4; generation++ { + path := fmt.Sprintf("/replacement%d", generation) + reader[webID(path)] = "↺ by Publisher" + nodes[1].Children[slot] = webID(path) + nodes[slot+2].Snapshot.Path = path + if err := cursor.tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + position, recovery, err := cursor.sync_focus(ctx, webID("/paragraph")) + if err != nil || recovery != "replaced-text-child" || position.Object.ID() != webID(path) { + t.Fatalf("replacement %d: %+v, %s, %v", generation, position, recovery, err) + } + move := func(command DocumentCaretCommand, want string) { + t.Helper() + result, err := cursor.MoveCaret(ctx, reader, command) + if err != nil || !result.Moved || result.Text != want { + t.Fatalf("%s after replacement %d: %+v, %v; want %q", command, generation, result, err, want) + } + } + move(CaretNextCharacter, " ") // Unicode offsets remain character based. + move(CaretPreviousCharacter, "↺") + if slot == 2 { + move(CaretPreviousLine, "Article continues") + move(CaretNextLine, "↺ by Publisher") + } else { + want := "Article continues" + if slot == 0 { + want = "Published" + } + move(CaretNextLine, want) + move(CaretPreviousLine, "↺ by Publisher") + } + } + }) + } + } +} + +func TestDocumentLinkReplacementPreservesActivationOwnership(t *testing.T) { + for _, kind := range []string{"same link", "replaced link", "named link", "editable link"} { + t.Run(kind, func(t *testing.T) { + cursor, _, nodes := inline_replacement_cursor(t, "link", 1) + ctx := context.Background() + originalTarget, err := cursor.ActivationTarget() + if err != nil || originalTarget.ID() != webID("/paragraph") { + t.Fatalf("original link target: %v, %v", originalTarget.ID(), err) + } + nodes[1].Children[1] = webID("/new") + nodes[3].Snapshot.Path = "/new" + switch kind { + case "replaced link": + cursor.tree.Invalidate(webID("/paragraph")) + case "named link": + nodes[1].Snapshot.ExplicitName = true + case "editable link": + nodes[1].Snapshot.Editable = true + } + if err := cursor.tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + if _, err := cursor.syncActionFocus(ctx, webID("/paragraph")); err == nil { + t.Fatal("activation silently recovered a missing text target") + } + position, recovery, err := cursor.sync_focus(ctx, webID("/paragraph")) + if err != nil { + t.Fatal(err) + } + if kind != "same link" { + if recovery == "replaced-text-child" || position.Object.ID() == webID("/new") { + t.Fatal("changed link inherited the old text cursor") + } + return + } + target, err := cursor.ActivationTarget() + if err != nil || recovery != "replaced-text-child" || target != originalTarget { + t.Fatalf("navigation changed link ownership: target=%v recovery=%s err=%v", target.ID(), recovery, err) + } + }) + } +} + +func TestReadAllAfterInlineReplacementRecovery(t *testing.T) { + cursor, reader, nodes := inline_replacement_cursor(t, "paragraph", 1) + nodes[1].Children[1] = webID("/new") + nodes[3].Snapshot.Path = "/new" + reader[webID("/new")] = reader[webID("/old")] + if err := cursor.tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + worker, _ := NewWorker(&readAllCapturer{tree: cursor.tree, caretTextReader: reader}, time.Second) + worker.SyncFocus(webID("/paragraph")) + result := worker.readAll(context.Background(), cursor) + if result.Err != nil || len(result.ReadAllLines) != 2 { + t.Fatalf("Read All after inline replacement: %+v", result) + } + for index, want := range []string{"↺ by Publisher", "Article continues"} { + if got := result.ReadAllLines[index].Contents[0].Text; got != want { + t.Fatalf("line %d = %q, want %q", index, got, want) + } + } +} + +func TestReadAllRecoveryRejectsReplacedDocument(t *testing.T) { + for _, refresh := range []bool{false, true} { + t.Run(fmt.Sprint(refresh), func(t *testing.T) { + cursor, reader, nodes := inline_replacement_cursor(t, "link", 1) + cursor.tree.Invalidate(webID("/doc")) + if err := cursor.tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + worker, _ := NewWorker(&readAllCapturer{tree: cursor.tree, caretTextReader: reader}, time.Second) + worker.SyncFocus(webID("/paragraph")) + if refresh { + if _, err := worker.refresh_read_all_cursor(context.Background(), cursor, webID("/paragraph")); err == nil { + t.Fatal("Read All refresh crossed a document generation") + } + return + } + result := worker.readAll(context.Background(), cursor) + if result.Err == nil || len(result.ReadAllLines) != 0 { + t.Fatal("Read All inherited the position in a replacement document") + } + }) + } +} + +func TestDocumentInlineReplacementRetainsAndClampsUnicodeOffset(t *testing.T) { + for _, replacement := range []string{"↺ by Another publisher", "↺"} { + t.Run(replacement, func(t *testing.T) { + cursor, reader, nodes := inline_replacement_cursor(t, "paragraph", 1) + ctx := context.Background() + move, err := cursor.MoveCaret(ctx, reader, CaretNextWord) + if err != nil || move.Position.Offset != 4 { + t.Fatalf("word movement: offset=%d err=%v", move.Position.Offset, err) + } + nodes[1].Children[1] = webID("/new") + nodes[3].Snapshot.Path = "/new" + nodes[3].Snapshot.CharacterCount = utf8.RuneCountInString(replacement) + reader[webID("/new")] = replacement + if err := cursor.tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + position, recovery, err := cursor.sync_focus(ctx, webID("/paragraph")) + wantOffset := min(move.Position.Offset, utf8.RuneCountInString(replacement)-1) + if err != nil || recovery != "replaced-text-child" || position.Offset != wantOffset { + t.Fatalf("replacement: offset=%d want=%d recovery=%s err=%v", position.Offset, wantOffset, recovery, err) + } + }) + } +} + +func TestDocumentInlineReplacementRejectsAmbiguousOrInteractiveChanges(t *testing.T) { + for _, kind := range []string{"inserted child", "removed neighbor", "replaced neighbor", "reordered neighbors", + "replaced parent", "replaced document", "hidden parent", "editable parent", "clickable parent", "focusable parent", + "hidden child", "editable child", "clickable child", "focusable child", "named child", "password child", "native origin"} { + t.Run(kind, func(t *testing.T) { + cursor, reader, nodes := inline_replacement_cursor(t, "paragraph", 1) + nodes[1].Children[1] = webID("/new") + nodes[3].Snapshot.Path = "/new" + reader[webID("/new")] = reader[webID("/old")] + switch kind { + case "inserted child": + nodes[1].Children = append(nodes[1].Children[:2], webID("/extra"), webID("/after")) + nodes = append(nodes, atspi.TreeNode{Snapshot: atspi.Snapshot{BusName: webID("/extra").BusName, Path: "/extra", Role: "static", CharacterCount: 5}}) + case "removed neighbor": + nodes[1].Children = nodes[1].Children[1:] + nodes = append(nodes[:2], nodes[3:]...) + case "replaced neighbor": + cursor.tree.Invalidate(webID("/before")) + case "reordered neighbors": + nodes[1].Children[0], nodes[1].Children[2] = nodes[1].Children[2], nodes[1].Children[0] + case "replaced parent": + cursor.tree.Invalidate(webID("/paragraph")) + case "replaced document": + cursor.tree.Invalidate(webID("/doc")) + case "hidden parent": + nodes[1].Geometry.VisibilityKnown = true + case "editable parent": + nodes[1].Snapshot.Editable = true + case "clickable parent": + nodes[1].Snapshot.SupportsClick = true + case "focusable parent": + nodes[1].Snapshot.Focusable = true + case "hidden child": + nodes[3].Geometry.VisibilityKnown = true + case "editable child": + nodes[3].Snapshot.Editable = true + case "clickable child": + nodes[3].Snapshot.SupportsClick = true + case "focusable child": + nodes[3].Snapshot.Focusable = true + case "named child": + nodes[3].Snapshot.ExplicitName = true + case "password child": + nodes[3].Snapshot.Role = "password text" + case "native origin": + cursor.places[0].origin = NativeNavigation + } + if err := cursor.tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + position, recovery, err := cursor.sync_focus(context.Background(), webID("/paragraph")) + if err != nil || recovery == "replaced-text-child" || position.Object.ID() == webID("/new") { + t.Fatalf("unsafe replacement accepted: object=%+v recovery=%s err=%v", position.Object.ID(), recovery, err) + } + }) + } +} diff --git a/internal/review/document_line_worker.go b/internal/review/document_line_worker.go new file mode 100644 index 0000000..a8f709c --- /dev/null +++ b/internal/review/document_line_worker.go @@ -0,0 +1,86 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// ReadDocumentLine queues a caret-line capture and assembly request. +func (worker *Worker) ReadDocumentLine(focus atspi.ObjectID, offset int) (uint64, error) { + if !focus.Valid() { + return 0, ErrInvalidDirection + } + sequence := worker.lineSequence.Add(1) + if sequence == 0 { + sequence = worker.lineSequence.Add(1) + } + select { + case worker.requests <- request{documentEpoch: worker.documentEpoch.Load(), line: true, lineRequest: sequence, lineFocus: focus, lineOffset: offset, queuedAt: time.Now()}: + return sequence, nil + default: + return 0, ErrRequestQueueFull + } +} + +func (worker *Worker) readDocumentLine(ctx context.Context, tree *atspi.AccessibleTree, request uint64, focus atspi.ObjectID, offset int) (Result, *atspi.AccessibleTree) { + result := Result{DocumentLine: true, DocumentLineRequest: request, DocumentLineFocus: focus} + if !focus.Valid() { + result.Err = ErrNoCurrent + return result, tree + } + if tree != nil { + if reference, err := tree.Reference(focus); err == nil { + if line, err := tree.DocumentLineAtOffset(ctx, reference, offset); err == nil { + result.DocumentLineData = line + result.Moved = true + return result, tree + } + } + } + captureContext, cancel := context.WithTimeout(ctx, worker.documentCaptureTimeout) + captureStarted := time.Now() + tree, err := worker.capturer.CaptureDocumentText(captureContext, focus) + result.CaptureDuration = time.Since(captureStarted) + cancel() + if err != nil { + result.Err = err + return result, tree + } + if tree == nil { + result.Err = errors.New("capture document text tree: nil tree") + return result, nil + } + reference, err := tree.Reference(focus) + if err != nil { + result.Err = err + return result, tree + } + line, err := tree.DocumentLineAtOffset(ctx, reference, offset) + if err != nil { + result.Err = err + return result, tree + } + result.DocumentLineData = line + result.Moved = true + return result, tree +} diff --git a/internal/review/document_lists.go b/internal/review/document_lists.go new file mode 100644 index 0000000..a295044 --- /dev/null +++ b/internal/review/document_lists.go @@ -0,0 +1,251 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "strings" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// DocumentListSnapshot retains exact generation-checked references. Opening a list +// never moves the cursor. Selection cannot recapture or substitute an item. +type DocumentListSnapshot struct { + Entries []DocumentListEntry + Selected int + Target DocumentTarget + Level int + focus atspi.ObjectID + revision uint64 + epoch uint64 + tree *atspi.AccessibleTree +} + +type DocumentListEntry struct { + DocumentPosition + Label string +} + +type documentListReply struct { + list DocumentListSnapshot + err error +} +type documentListRequest struct { + ctx context.Context + target DocumentTarget + level int + result chan documentListReply +} +type documentListSelection struct { + list DocumentListSnapshot + index int +} + +// ListDocument is called by the UI worker, never by the input/event loops. +func (worker *Worker) ListDocument(ctx context.Context, target DocumentTarget, level int) (DocumentListSnapshot, error) { + if err := ctx.Err(); err != nil { + return DocumentListSnapshot{}, err + } + if !validDocumentTarget(target) || level < 0 || level > 6 || target != DocumentHeading && level != 0 { + return DocumentListSnapshot{}, ErrInvalidDirection + } + worker.stateMutex.Lock() + done, started := worker.done, worker.started + worker.stateMutex.Unlock() + if !started { + return DocumentListSnapshot{}, ErrNoCurrent + } + query := &documentListRequest{ctx: ctx, target: target, level: level, result: make(chan documentListReply, 1)} + select { + case worker.requests <- request{documentList: query}: + case <-ctx.Done(): + return DocumentListSnapshot{}, ctx.Err() + case <-done: + return DocumentListSnapshot{}, ErrNoCurrent + } + select { + case reply := <-query.result: + return reply.list, reply.err + case <-ctx.Done(): + return DocumentListSnapshot{}, ctx.Err() + case <-done: + return DocumentListSnapshot{}, ErrNoCurrent + } +} + +func (worker *Worker) SelectDocumentList(list DocumentListSnapshot, index int) error { + if index < 0 || index >= len(list.Entries) || list.tree == nil { + return ErrInvalidDirection + } + select { + case worker.requests <- request{documentEpoch: list.epoch, listSelection: &documentListSelection{list: list, index: index}, queuedAt: time.Now()}: + return nil + default: + return ErrRequestQueueFull + } +} + +func (worker *Worker) listDocument(ctx context.Context, cursor *DocumentCursor, query *documentListRequest) (DocumentListSnapshot, error) { + if err := query.ctx.Err(); err != nil { + return DocumentListSnapshot{}, err + } + worker.stateMutex.Lock() + list := DocumentListSnapshot{Target: query.target, Level: query.level, focus: worker.latestFocus, revision: worker.focusRevision, epoch: worker.documentEpoch.Load()} + worker.stateMutex.Unlock() + if !list.focus.Valid() { + return list, ErrNoCurrent + } + captureContext, cancel := context.WithTimeout(ctx, worker.documentCaptureTimeout) + defer cancel() + stop := context.AfterFunc(query.ctx, cancel) + defer stop() + tree, err := worker.capturer.CaptureDocument(captureContext, list.focus) + if err != nil { + return list, err + } + if tree == nil { + return list, errors.New("capture document list: nil tree") + } + ref, err := tree.Reference(list.focus) + if err != nil { + return list, err + } + doc, err := tree.DocumentView(captureContext, ref) + if err != nil { + return list, err + } + current := list.focus + if cursor != nil { + cursor.mu.Lock() + if len(cursor.places) > 0 { + place := cursor.places[len(cursor.places)-1] + if place.document == doc.Context.TopLevel && (place.focus.ID() == list.focus || place.object.ID() == list.focus) { + current = place.object.ID() + } + } + cursor.mu.Unlock() + } + list.tree = tree + // Unnamed clickable sections and containers often expose their readable + // label only in static descendants. Assemble bounded labels once, in + // reverse tree order, instead of rescanning each candidate's subtree. + labels := make(map[atspi.ObjectID]string, len(doc.Nodes)) + for index := len(doc.Nodes) - 1; index >= 0; index-- { + node := doc.Nodes[index] + if node.Hidden { + continue + } + label := node.Snapshot.Name + if node.Snapshot.Role != "password text" { + if label == "" { + label = node.Snapshot.Text + } + if label == "" { + var parts []string + size := 0 + for _, child := range node.Children { + if part := labels[child]; part != "" { + parts = append(parts, part) + size += len(part) + } + if size >= 900 { + break + } + } + label = strings.Join(parts, " ") + } + } + runes := []rune(label) + if len(runes) > 225 { + label = string(runes[:225]) + } + labels[node.Reference.ID()] = label + } + parents := make(map[atspi.ObjectID]atspi.ObjectID, len(doc.Nodes)) + indices := make(map[atspi.ObjectID]int) + for _, node := range doc.Nodes { + parents[node.Reference.ID()] = node.Parent + if node.Hidden || !documentTargetMatches(query.target, node, query.level) { + continue + } + indices[node.Reference.ID()] = len(list.Entries) + list.Entries = append(list.Entries, DocumentListEntry{DocumentPosition: DocumentPosition{Document: doc.Context.TopLevel, Object: node.Reference, Snapshot: node.Snapshot, Origin: StructuralNavigation}, Label: labels[node.Reference.ID()]}) + } + for id := current; id.Valid(); id = parents[id] { + if index, ok := indices[id]; ok { + list.Selected = index + break + } + } + if !worker.currentDocumentList(list) { + return DocumentListSnapshot{}, atspi.ErrStaleObject + } + return list, captureContext.Err() +} + +func (worker *Worker) currentDocumentList(list DocumentListSnapshot) bool { + worker.stateMutex.Lock() + defer worker.stateMutex.Unlock() + return list.focus == worker.latestFocus && list.revision == worker.focusRevision && list.epoch == worker.documentEpoch.Load() +} + +func (worker *Worker) selectDocumentList(ctx context.Context, cursor *DocumentCursor, selection *documentListSelection) (Result, *DocumentCursor) { + list := selection.list + result := Result{DocumentEpoch: list.epoch, DocumentTarget: list.Target, DocumentLevel: list.Level, DocumentFocus: list.focus} + if !worker.currentDocumentList(list) { + result.Err = atspi.ErrStaleObject + return result, cursor + } + position := list.Entries[selection.index] + if _, err := list.tree.Resolve(position.Object); err != nil { + result.Err = err + return result, cursor + } + doc, err := list.tree.DocumentView(ctx, position.Object) + if err != nil { + result.Err = err + return result, cursor + } + if doc.Context.TopLevel != position.Document { + result.Err = atspi.ErrStaleObject + return result, cursor + } + found := false + for _, node := range doc.Nodes { + if node.Reference == position.Object && !node.Hidden && documentTargetMatches(list.Target, node, list.Level) { + found = true + break + } + } + if !found { + result.Err = atspi.ErrStaleObject + return result, cursor + } + if cursor == nil || cursor.tree != list.tree { + cursor, _ = NewDocumentCursor(list.tree) + } + if _, err := cursor.SyncFocus(ctx, list.focus); err != nil { + result.Err = err + return result, cursor + } + if !worker.currentDocumentList(list) { + result.Err = atspi.ErrStaleObject + return result, cursor + } + cursor.mu.Lock() + place := &cursor.places[len(cursor.places)-1] + place.object, place.offset, place.origin = position.Object, 0, StructuralNavigation + place.tableCell = atspi.ObjectID{} + remember_text_parent(doc, place) + result.DocumentPosition = documentPosition(doc, *place) + cursor.mu.Unlock() + result.Moved = true + // Use the exact validated target; retry/recapture belongs to ordinary + // navigation and must not choose a replacement for a menu selection. + return worker.placeDocument(ctx, cursor, result), cursor +} diff --git a/internal/review/document_lists_test.go b/internal/review/document_lists_test.go new file mode 100644 index 0000000..03959b2 --- /dev/null +++ b/internal/review/document_lists_test.go @@ -0,0 +1,143 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestDocumentListPreservesCursorAndSelectsExactTarget(t *testing.T) { + tree, cursor := webCursor(t) + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, webID("/doc")); err != nil { + t.Fatal(err) + } + capturer := &readAllCapturer{tree: tree} + worker, _ := NewWorker(capturer, time.Second) + worker.SyncFocus(webID("/doc")) + before := cursor.diagnostic_state() + list, err := worker.listDocument(ctx, cursor, &documentListRequest{ctx: ctx, target: DocumentHeading}) + if err != nil || len(list.Entries) != 2 { + t.Fatalf("heading list: %+v %v", list, err) + } + if after := cursor.diagnostic_state(); after != before { + t.Fatalf("opening moved cursor: %+v -> %+v", before, after) + } + result, cursor := worker.selectDocumentList(ctx, cursor, &documentListSelection{list: list, index: 1}) + if result.Err != nil || !result.Moved || result.DocumentPosition.Object != list.Entries[1].Object { + t.Fatalf("selection: %+v", result) + } + list, err = worker.listDocument(ctx, cursor, &documentListRequest{ctx: ctx, target: DocumentHeading}) + if err != nil || list.Selected != 1 { + t.Fatalf("did not preserve current row: %+v %v", list, err) + } + filtered, err := worker.listDocument(ctx, cursor, &documentListRequest{ctx: ctx, target: DocumentHeading, level: 2}) + if err != nil || len(filtered.Entries) != 2 || filtered.Entries[0].Snapshot.HeadingLevel != 2 { + t.Fatalf("level filter: %+v %v", filtered, err) + } +} + +func TestDocumentListRejectsChangedTargetsAndOwnership(t *testing.T) { + for _, change := range []string{"target removed", "target reused", "target hidden", "focus changed", "document reloaded"} { + t.Run(change, func(t *testing.T) { + tree, cursor := webCursor(t) + ctx := context.Background() + worker, _ := NewWorker(&readAllCapturer{tree: tree}, time.Second) + worker.SyncFocus(webID("/doc")) + list, err := worker.listDocument(ctx, cursor, &documentListRequest{ctx: ctx, target: DocumentHeading}) + if err != nil { + t.Fatal(err) + } + switch change { + case "target removed": + tree.Invalidate(list.Entries[0].Object.ID()) + case "target reused": + tree.Invalidate(list.Entries[0].Object.ID()) + if err := tree.Replace(webID("/root"), webNodes()); err != nil { + t.Fatal(err) + } + case "target hidden": + nodes := webNodes() + nodes[3].Geometry = atspi.Geometry{VisibilityKnown: true} + if err := tree.Replace(webID("/root"), nodes); err != nil { + t.Fatal(err) + } + case "focus changed": + worker.SyncFocus(webID("/chrome")) + case "document reloaded": + worker.ResetDocument(webID("/doc")) + } + result, _ := worker.selectDocumentList(ctx, cursor, &documentListSelection{list: list, index: 0}) + if result.Err == nil || result.Moved { + t.Fatalf("stale selection succeeded: %+v", result) + } + }) + } +} + +func TestDocumentListDescendantLabelsExcludeHiddenAndPasswordText(t *testing.T) { + node := func(path, role, text string, children ...string) atspi.TreeNode { + snapshot := atspi.Snapshot{BusName: webID(path).BusName, Path: path, Role: role, Text: text} + entry := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + entry.Children = append(entry.Children, webID(child)) + } + return entry + } + nodes := []atspi.TreeNode{ + node("/doc", "document web", "", "/clickable"), + node("/clickable", "section", "", "/text", "/hidden", "/password"), + node("/text", "static", "Clickable text"), + node("/hidden", "static", "Hidden content"), + node("/password", "password text", "private fixture password"), + } + nodes[1].Snapshot.SupportsClick = true + nodes[3].Geometry = atspi.Geometry{VisibilityKnown: true} + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + worker, _ := NewWorker(&readAllCapturer{tree: tree}, time.Second) + worker.SyncFocus(webID("/doc")) + ctx := context.Background() + list, err := worker.listDocument(ctx, nil, &documentListRequest{ctx: ctx, target: DocumentClickable}) + if err != nil || len(list.Entries) != 1 || list.Entries[0].Label != "Clickable text" { + t.Fatalf("unsafe or missing descendant label: %+v %v", list, err) + } +} + +func TestWorkerDocumentListUsesOrderedRequests(t *testing.T) { + tree, _ := webCursor(t) + worker, cancel := startWorker(t, &readAllCapturer{tree: tree}, time.Second) + defer cancel() + worker.SyncFocus(webID("/doc")) + ctx, stop := context.WithTimeout(context.Background(), time.Second) + defer stop() + list, err := worker.ListDocument(ctx, DocumentHeading, 0) + if err != nil { + t.Fatal(err) + } + if err := worker.SelectDocumentList(list, 1); err != nil { + t.Fatal(err) + } + result := waitResult(t, worker) + if result.Err != nil || !result.Moved || result.DocumentPosition.Object != list.Entries[1].Object { + t.Fatalf("queued selection: %+v", result) + } +} + +func TestAdditionalDocumentListRoles(t *testing.T) { + for target, roles := range map[DocumentTarget][]string{DocumentAnnotation: {"content deletion", "content insertion", "mark"}, DocumentInternalFrame: {"internal frame"}, DocumentMath: {"math"}} { + for _, role := range roles { + if !documentTargetMatches(target, atspi.DocumentNode{Snapshot: atspi.Snapshot{Role: role}}, 0) { + t.Fatalf("missing %s", role) + } + } + } +} diff --git a/internal/review/document_mode.go b/internal/review/document_mode.go new file mode 100644 index 0000000..59c70cf --- /dev/null +++ b/internal/review/document_mode.go @@ -0,0 +1,185 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import "git.stormux.org/storm/cthulhu/internal/atspi" + +// DocumentMode is a policy result, not permission to install keyboard grabs. +// Inactive suspends web commands outside a live document, including chrome. +type DocumentMode uint8 + +const ( + InactiveMode DocumentMode = iota + BrowseMode + FocusMode +) + +// ModeSettings mirrors the three Python web navigation-origin preferences. +type ModeSettings struct { + StructuralTriggersFocus bool + CaretTriggersFocus bool + NativeTriggersFocus bool +} + +func DefaultModeSettings() ModeSettings { + return ModeSettings{NativeTriggersFocus: true} +} + +// ModeTraits contains semantic facts which the current owned snapshots do not +// yet capture. A future native resolver must supply these before runtime key +// routing uses this policy; false must not stand in for an unknown query. +type ModeTraits struct { + LayoutOnlyTable bool + TextBlock bool + NamedActionWithoutUsefulChildren bool + PDFViewer bool + GridDescendant bool + ContentEditableWithEmbeddedObjects bool +} + +type ModeInput struct { + Context atspi.DocumentContext + Traits ModeTraits + Origin NavigationOrigin + SayAll bool + UnmodifiedArrow bool + PreviousNavigableTooltip bool +} + +// DocumentModeState belongs to one browser policy owner. It performs no native +// work, speech, or input mutation. Its zero value starts in browse mode. The +// owner serializes calls and resets it when that browser owner is retired. +// Chrome/application suspension does not discard sticky state. +type DocumentModeState struct { + current DocumentMode + sticky DocumentMode +} + +func (state *DocumentModeState) Current() DocumentMode { + if state.current == FocusMode { + return FocusMode + } + return BrowseMode +} + +func (state *DocumentModeState) Sticky() DocumentMode { return state.sticky } + +// Toggle is a manual toggle: like Python it clears either sticky mode. +func (state *DocumentModeState) Toggle() DocumentMode { + if state.Current() == FocusMode { + state.current = BrowseMode + } else { + state.current = FocusMode + } + state.sticky = InactiveMode + return state.current +} + +func (state *DocumentModeState) SetSticky(mode DocumentMode) { + if mode != BrowseMode && mode != FocusMode { + return + } + state.current, state.sticky = mode, mode +} + +// Update follows scripts/web/script.py:useFocusMode precedence. The caller +// resolves a fresh DocumentContext; stale identities must not reuse a cached +// context. Inactive results never change the remembered web mode. +func (state *DocumentModeState) Update(input ModeInput, settings ModeSettings) DocumentMode { + if !input.Context.Document.Valid() || !input.Context.TopLevel.Valid() || len(input.Context.Ancestors) == 0 || input.Context.Ancestors[0].Defunct || !input.Context.Ancestors[0].StatesKnown { + return InactiveMode + } + mode := state.decide(input, settings) + state.current = mode + return mode +} + +func (state *DocumentModeState) decide(input ModeInput, settings ModeSettings) DocumentMode { + if state.sticky != InactiveMode { + return state.sticky + } + if input.SayAll { + return BrowseMode + } + switch input.Origin { + case StructuralNavigation: + if !settings.StructuralTriggersFocus { + return BrowseMode + } + case CaretNavigation: + if !settings.CaretTriggersFocus && !input.PreviousNavigableTooltip { + return BrowseMode + } + default: + if !settings.NativeTriggersFocus { + return state.Current() + } + } + if focusModeWidget(input) { + return FocusMode + } + if state.Current() != FocusMode { + return BrowseMode + } + role := input.Context.Ancestors[0].Role + if input.UnmodifiedArrow && (role == "link" || role == "radio button") { + return FocusMode + } + if hasModeAncestor(input, "embedded") { + if role == "document web" || role == "tool tip" && input.Context.Ancestors[0].Focused { + return BrowseMode + } + return FocusMode + } + return BrowseMode +} + +func focusModeWidget(input ModeInput) bool { + object := input.Context.Ancestors[0] + traits := input.Traits + if object.Editable || object.Expandable && object.Focusable && object.Role != "link" { + return true + } + switch object.Role { + case "combo box", "entry", "list box", "menu", "menu item", "check menu item", "radio menu item", "page tab", "password text", "progress bar", "slider", "spin button", "tool bar", "tree item", "tree table", "tree": + return true + case "table", "table cell": + if traits.LayoutOnlyTable { + return false + } + case "list item": + return hasModeAncestor(input, "list box") + } + if object.HasPopup && (object.Role == "button" || object.Role == "push button" || object.Role == "toggle button") { + return true + } + if (object.Role == "embedded" || object.Role == "table" || object.Role == "table cell") && + !traits.TextBlock && !traits.NamedActionWithoutUsefulChildren && !traits.PDFViewer { + return true + } + return traits.GridDescendant || hasModeAncestor(input, "menu") || hasModeAncestor(input, "tool bar") || traits.ContentEditableWithEmbeddedObjects +} + +func hasModeAncestor(input ModeInput, role string) bool { + for _, ancestor := range input.Context.Ancestors[1:] { + if ancestor.Role == role { + return true + } + } + return false +} diff --git a/internal/review/document_mode_test.go b/internal/review/document_mode_test.go new file mode 100644 index 0000000..2a13536 --- /dev/null +++ b/internal/review/document_mode_test.go @@ -0,0 +1,219 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func modeInput(t *testing.T, role string, ancestors ...string) ModeInput { + t.Helper() + tree, _ := webCursor(t) + ref, err := tree.Reference(webID("/first")) + if err != nil { + t.Fatal(err) + } + context, err := tree.DocumentContext(ref) + if err != nil { + t.Fatal(err) + } + context.Ancestors = []atspi.Snapshot{{Role: role, StatesKnown: true}} + for _, role := range ancestors { + context.Ancestors = append(context.Ancestors, atspi.Snapshot{Role: role}) + } + context.Ancestors = append(context.Ancestors, atspi.Snapshot{Role: "document web"}) + return ModeInput{Context: context} +} + +func TestDocumentModeWidgetRoles(t *testing.T) { + for _, role := range []string{"combo box", "entry", "list box", "menu", "menu item", "check menu item", "radio menu item", "page tab", "password text", "progress bar", "slider", "spin button", "tool bar", "tree item", "tree table", "tree", "table", "table cell", "embedded"} { + t.Run(role, func(t *testing.T) { + var state DocumentModeState + if got := state.Update(modeInput(t, role), DefaultModeSettings()); got != FocusMode { + t.Fatalf("got %v", got) + } + }) + } + for _, role := range []string{"heading", "paragraph", "link", "push button", "check box", "radio button", "list item", "document web"} { + t.Run(role, func(t *testing.T) { + var state DocumentModeState + if got := state.Update(modeInput(t, role), DefaultModeSettings()); got != BrowseMode { + t.Fatalf("got %v", got) + } + }) + } +} + +func TestDocumentModeWidgetSemantics(t *testing.T) { + for _, tc := range []struct { + name string + role string + ancestors []string + traits ModeTraits + editable, expandable bool + focusable, hasPopup bool + want DocumentMode + }{ + {name: "editable paragraph", role: "paragraph", editable: true, want: FocusMode}, + {name: "expandable button", role: "push button", expandable: true, focusable: true, want: FocusMode}, + {name: "unfocusable expandable", role: "push button", expandable: true, want: BrowseMode}, + {name: "expandable link", role: "link", expandable: true, focusable: true, want: BrowseMode}, + {name: "native popup button", role: "button", hasPopup: true, want: FocusMode}, + {name: "popup toggle", role: "toggle button", hasPopup: true, want: FocusMode}, + {name: "popup link", role: "link", hasPopup: true, want: BrowseMode}, + {name: "popup button", role: "push button", hasPopup: true, want: FocusMode}, + {name: "listbox item", role: "list item", ancestors: []string{"list box"}, want: FocusMode}, + {name: "ordinary list", role: "list item", ancestors: []string{"list"}, want: BrowseMode}, + {name: "menu descendant", role: "check box", ancestors: []string{"menu"}, want: FocusMode}, + {name: "toolbar descendant", role: "push button", ancestors: []string{"tool bar"}, want: FocusMode}, + {name: "grid descendant", role: "check box", traits: ModeTraits{GridDescendant: true}, want: FocusMode}, + {name: "layout table", role: "table", traits: ModeTraits{LayoutOnlyTable: true, GridDescendant: true}, want: BrowseMode}, + {name: "layout cell", role: "table cell", traits: ModeTraits{LayoutOnlyTable: true}, want: BrowseMode}, + {name: "editable layout cell", role: "table cell", editable: true, traits: ModeTraits{LayoutOnlyTable: true}, want: FocusMode}, + {name: "PDF table", role: "table", traits: ModeTraits{PDFViewer: true}, want: BrowseMode}, + {name: "text block", role: "embedded", traits: ModeTraits{TextBlock: true}, want: BrowseMode}, + {name: "named action", role: "embedded", traits: ModeTraits{NamedActionWithoutUsefulChildren: true}, want: BrowseMode}, + {name: "embedded editor", role: "section", traits: ModeTraits{ContentEditableWithEmbeddedObjects: true}, want: FocusMode}, + } { + t.Run(tc.name, func(t *testing.T) { + input := modeInput(t, tc.role, tc.ancestors...) + input.Traits = tc.traits + input.Context.Ancestors[0].Editable = tc.editable + input.Context.Ancestors[0].Expandable = tc.expandable + input.Context.Ancestors[0].Focusable = tc.focusable + input.Context.Ancestors[0].HasPopup = tc.hasPopup + var state DocumentModeState + if got := state.Update(input, DefaultModeSettings()); got != tc.want { + t.Fatalf("got %v want %v", got, tc.want) + } + }) + } +} + +func TestDocumentModePrecedence(t *testing.T) { + for _, tc := range []struct { + name string + origin NavigationOrigin + settings ModeSettings + sticky DocumentMode + sayAll, tooltip bool + want DocumentMode + }{ + {name: "native default", settings: DefaultModeSettings(), want: FocusMode}, + {name: "structural default", origin: StructuralNavigation, settings: DefaultModeSettings(), want: BrowseMode}, + {name: "caret default", origin: CaretNavigation, settings: DefaultModeSettings(), want: BrowseMode}, + {name: "structural opt in", origin: StructuralNavigation, settings: ModeSettings{StructuralTriggersFocus: true}, want: FocusMode}, + {name: "caret opt in", origin: CaretNavigation, settings: ModeSettings{CaretTriggersFocus: true}, want: FocusMode}, + {name: "tooltip escape", origin: CaretNavigation, tooltip: true, want: FocusMode}, + {name: "say all", settings: DefaultModeSettings(), sayAll: true, want: BrowseMode}, + {name: "sticky focus beats say all", sticky: FocusMode, sayAll: true, origin: StructuralNavigation, want: FocusMode}, + {name: "sticky browse beats editable", sticky: BrowseMode, settings: DefaultModeSettings(), want: BrowseMode}, + {name: "native disabled retains browse", want: BrowseMode}, + } { + t.Run(tc.name, func(t *testing.T) { + var state DocumentModeState + state.SetSticky(tc.sticky) + input := modeInput(t, "entry") + input.Origin, input.SayAll, input.PreviousNavigableTooltip = tc.origin, tc.sayAll, tc.tooltip + if got := state.Update(input, tc.settings); got != tc.want { + t.Fatalf("got %v want %v", got, tc.want) + } + }) + } + state := DocumentModeState{} + state.Toggle() + if got := state.Update(modeInput(t, "paragraph"), ModeSettings{}); got != FocusMode { + t.Fatal("disabled native policy did not preserve focus mode") + } +} + +func TestDocumentModeFocusRetention(t *testing.T) { + for _, tc := range []struct { + name, role string + ancestors []string + arrow, focused bool + want DocumentMode + }{ + {name: "arrow link", role: "link", arrow: true, want: FocusMode}, + {name: "tab link", role: "link", want: BrowseMode}, + {name: "arrow radio", role: "radio button", arrow: true, want: FocusMode}, + {name: "arrow button", role: "push button", arrow: true, want: BrowseMode}, + {name: "web app button", role: "push button", ancestors: []string{"embedded"}, want: FocusMode}, + {name: "web app document", role: "document web", ancestors: []string{"embedded"}, want: BrowseMode}, + {name: "focused tooltip", role: "tool tip", ancestors: []string{"embedded"}, focused: true, want: BrowseMode}, + {name: "unfocused tooltip", role: "tool tip", ancestors: []string{"embedded"}, want: FocusMode}, + } { + t.Run(tc.name, func(t *testing.T) { + input := modeInput(t, tc.role, tc.ancestors...) + input.UnmodifiedArrow, input.Context.Ancestors[0].Focused = tc.arrow, tc.focused + var state DocumentModeState + state.Toggle() + if got := state.Update(input, DefaultModeSettings()); got != tc.want { + t.Fatalf("got %v want %v", got, tc.want) + } + // Retention conditions must not themselves enter focus mode. + state = DocumentModeState{} + if got := state.Update(input, DefaultModeSettings()); got != BrowseMode { + t.Fatalf("entered focus mode: %v", got) + } + }) + } +} + +func TestDocumentModeStickySuspensionAndToggle(t *testing.T) { + for _, sticky := range []DocumentMode{FocusMode, BrowseMode} { + var state DocumentModeState + state.SetSticky(sticky) + if got := state.Update(ModeInput{}, DefaultModeSettings()); got != InactiveMode { + t.Fatal("web policy active outside document") + } + if state.Sticky() != sticky || state.Current() != sticky { + t.Fatal("suspension lost sticky mode") + } + input := modeInput(t, "entry") + if got := state.Update(input, DefaultModeSettings()); got != sticky { + t.Fatal("return lost sticky mode") + } + input.Context.Ancestors[0].Defunct = true + if got := state.Update(input, DefaultModeSettings()); got != InactiveMode { + t.Fatal("defunct object activated policy") + } + if got := state.Toggle(); got == sticky || state.Sticky() != InactiveMode { + t.Fatal("manual toggle failed to reverse and clear sticky mode") + } + } +} + +func TestDocumentModeUnknownStates(t *testing.T) { + input := modeInput(t, "entry") + input.Context.Ancestors[0].StatesKnown = false + var state DocumentModeState + state.SetSticky(FocusMode) + if got := state.Update(input, DefaultModeSettings()); got != InactiveMode { + t.Fatalf("missing native states enabled mode: %v", got) + } + if state.Current() != FocusMode || state.Sticky() != FocusMode { + t.Fatal("unavailable states discarded remembered mode") + } + input.Context.Ancestors[0].StatesKnown = true + if got := state.Update(input, DefaultModeSettings()); got != FocusMode { + t.Fatalf("recaptured states did not restore mode: %v", got) + } +} diff --git a/internal/review/document_named_link.go b/internal/review/document_named_link.go new file mode 100644 index 0000000..b089f0f --- /dev/null +++ b/internal/review/document_named_link.go @@ -0,0 +1,60 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "strings" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func named_link_label(snapshot atspi.Snapshot) string { + if snapshot.Role == "link" && snapshot.ExplicitName && !snapshot.Editable { + return strings.TrimSpace(snapshot.Name) + } + return "" +} + +func caret_text_count(snapshot atspi.Snapshot) int { + if label := named_link_label(snapshot); label != "" { + return utf8.RuneCountInString(label) + } + return snapshot.CharacterCount +} + +// Named links can expose no Text interface, or only a badge/embedded object. +// Review the label used by line speech, retaining the link for activation. +// These offsets belong to the label and must never become native text offsets. +func read_caret_text(ctx context.Context, reader DocumentCaretReader, node atspi.DocumentNode, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + if err := ctx.Err(); err != nil { + return atspi.DocumentCaretText{}, err + } + label := named_link_label(node.Snapshot) + if label == "" { + return reader.ReadDocumentCaret(ctx, node.Reference, offset, unit) + } + characters := []rune(label) + result := atspi.DocumentCaretText{CharacterCount: len(characters)} + if offset < 0 || offset >= len(characters) { + return result, nil + } + start, end := offset, offset+1 + if unit == atspi.DocumentCaretWord { + for start > 0 && !unicode.IsSpace(characters[start-1]) { + start-- + } + for end < len(characters) && !unicode.IsSpace(characters[end]) { + end++ + } + for end < len(characters) && unicode.IsSpace(characters[end]) { + end++ + } + } + result.Start, result.End, result.Text = start, end, string(characters[start:end]) + return result, nil +} diff --git a/internal/review/document_native_caret.go b/internal/review/document_native_caret.go new file mode 100644 index 0000000..e099d7e --- /dev/null +++ b/internal/review/document_native_caret.go @@ -0,0 +1,137 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// Native selections can report their caret on a label/paragraph rather than +// its static text child. Transfer offsets only when both expose the identical +// text range. Captured hypertext parents own their direct-text offsets; +// embedded or ambiguous child offsets must never be guessed. +func (cursor *DocumentCursor) syncNativeCaret(ctx context.Context, reader DocumentCaretReader, focus atspi.ObjectID, offset int) error { + if offset < 0 { + return atspi.ErrNoDocumentCaret + } + if _, err := cursor.SyncFocus(ctx, focus); err != nil { + return err + } + cursor.mu.Lock() + defer cursor.mu.Unlock() + place := &cursor.places[len(cursor.places)-1] + doc, err := cursor.tree.DocumentView(ctx, place.focus) + if err != nil { + return err + } + node, offset, err := native_caret_node(ctx, reader, doc, focus, offset) + if err != nil { + return err + } + + place.object, place.offset, place.origin = node.Reference, offset, CaretNavigation + place.tableCell = atspi.ObjectID{} + remember_text_parent(doc, place) + return nil +} + +func native_caret_node(ctx context.Context, reader DocumentCaretReader, doc atspi.DocumentSnapshot, focus atspi.ObjectID, offset int) (atspi.DocumentNode, int, error) { + node, _ := doc.Node(focus) + if !node.Reference.Valid() || offset < 0 || offset > node.Snapshot.CharacterCount || node.Snapshot.Editable || node.Snapshot.Role == "password text" { + return atspi.DocumentNode{}, 0, atspi.ErrNoDocumentCaret + } + for len(node.Children) != 0 && !wholeCaretNode(node.Snapshot) { + if len(node.Snapshot.TextChildren) != 0 { + embedded := atspi.ObjectID{} + for _, child := range node.Snapshot.TextChildren { + if child.Offset == offset { + embedded = child.Child + break + } + } + if !embedded.Valid() { + return node, offset, nil + } + child, ok := doc.Node(embedded) + if !ok || child.Hidden || child.Snapshot.Editable || child.Snapshot.Role == "password text" { + return atspi.DocumentNode{}, 0, atspi.ErrNoDocumentCaret + } + node, offset = child, 0 + continue + } + if len(node.Children) != 1 { + return atspi.DocumentNode{}, 0, atspi.ErrNoDocumentCaret + } + child, ok := doc.Node(node.Children[0]) + if !ok || child.Hidden || child.Snapshot.Editable || child.Snapshot.CharacterCount != node.Snapshot.CharacterCount { + return atspi.DocumentNode{}, 0, atspi.ErrNoDocumentCaret + } + probeOffset := max(0, min(offset, node.Snapshot.CharacterCount-1)) + parentText, err := reader.ReadDocumentCaret(ctx, node.Reference, probeOffset, atspi.DocumentCaretBrailleLine) + if err != nil { + return atspi.DocumentNode{}, 0, err + } + childText, err := reader.ReadDocumentCaret(ctx, child.Reference, probeOffset, atspi.DocumentCaretBrailleLine) + if err != nil { + return atspi.DocumentNode{}, 0, err + } + if parentText.Start != childText.Start || parentText.End != childText.End || parentText.Text == "" || parentText.Text != childText.Text { + return atspi.DocumentNode{}, 0, atspi.ErrNoDocumentCaret + } + node = child + } + return node, offset, nil +} + +// Use the navigation FIFO so a subsequent intercepted arrow sees the native +// selection endpoint, even if capturing the document is still in progress. +func (worker *Worker) SyncDocumentCaret(focus atspi.ObjectID, offset int) error { + if !focus.Valid() || offset < 0 { + return atspi.ErrNoDocumentCaret + } + select { + case worker.requests <- request{documentEpoch: worker.documentEpoch.Load(), nativeCaret: true, nativeCaretFocus: focus, nativeCaretOffset: offset}: + return nil + default: + return ErrRequestQueueFull + } +} + +func (worker *Worker) syncDocumentCaret(ctx context.Context, cursor *DocumentCursor, request request) (Result, *DocumentCursor) { + result := Result{DocumentNativeCaret: true, DocumentEpoch: request.documentEpoch, DocumentFocus: request.nativeCaretFocus} + if worker.focus() != request.nativeCaretFocus { + result.Err = atspi.ErrStaleObject + return result, cursor + } + reader, ok := worker.nativeCapturerFor(request.nativeCaretFocus).(DocumentCaretReader) + if !ok { + result.Err = atspi.ErrNoDocumentCaret + return result, cursor + } + ctx, cancel := context.WithTimeout(ctx, worker.captureTimeout) + defer cancel() + if cursor == nil { + cursor, result.Err = worker.refreshDocumentCursor(ctx, nil, request.nativeCaretFocus) + if result.Err != nil { + return result, cursor + } + } + result.Err = cursor.syncNativeCaret(ctx, reader, request.nativeCaretFocus, request.nativeCaretOffset) + if documentNeedsCapture(result.Err) { + fresh, captureErr := worker.refreshDocumentCursor(ctx, cursor, request.nativeCaretFocus) + if captureErr == nil && worker.focus() == request.nativeCaretFocus { + cursor = fresh + result.Err = cursor.syncNativeCaret(ctx, reader, request.nativeCaretFocus, request.nativeCaretOffset) + } else if captureErr != nil { + result.Err = captureErr + } + } + if result.Err == nil { + result.DocumentPosition, result.Err = cursor.SyncFocus(ctx, request.nativeCaretFocus) + } + return result, cursor +} diff --git a/internal/review/document_native_caret_test.go b/internal/review/document_native_caret_test.go new file mode 100644 index 0000000..66c8314 --- /dev/null +++ b/internal/review/document_native_caret_test.go @@ -0,0 +1,115 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func mirroredCaretCursor(t *testing.T, text caretTextReader, multiple bool) *DocumentCursor { + t.Helper() + var nodes []atspi.TreeNode + for _, path := range []string{"/doc", "/paragraph", "/text", "/other"} { + snapshot := atspi.Snapshot{BusName: webID(path).BusName, Path: path, Role: "static", CharacterCount: utf8.RuneCountInString(text[webID(path)])} + node := atspi.TreeNode{Snapshot: snapshot} + if path == "/doc" { + node.Snapshot.Role = "document web" + node.Children = []atspi.ObjectID{webID("/paragraph")} + } + if path == "/paragraph" { + node.Snapshot.Role = "paragraph" + node.Children = []atspi.ObjectID{webID("/text")} + if multiple { + node.Children = append(node.Children, webID("/other")) + } + } + if path == "/other" && !multiple { + continue + } + nodes = append(nodes, node) + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + return cursor +} + +func TestNativeCaretSelectionEndpointTransfersToTextChild(t *testing.T) { + text := caretTextReader{webID("/paragraph"): "When autocomplete", webID("/text"): "When autocomplete"} + cursor := mirroredCaretCursor(t, text, false) + for _, offset := range []int{6, 11, 17, 9, 0} { + if err := cursor.syncNativeCaret(context.Background(), text, webID("/paragraph"), offset); err != nil { + t.Fatal(err) + } + move, err := cursor.MoveCaret(context.Background(), text, CaretPreviousCharacter) + if err != nil { + t.Fatal(err) + } + if offset > 0 && (move.Position.Object.ID() != webID("/text") || move.Position.Offset != offset-1) { + t.Fatalf("offset %d: move = %+v", offset, move) + } + } +} + +func TestNativeCaretRejectsAmbiguousOffsetDomains(t *testing.T) { + for _, test := range []struct { + name, child string + multiple bool + offset int + }{ + {"different text same count", "other", false, 2}, + {"different count", "shorter", false, 2}, + {"embedded text", "hello", false, 2}, + {"multiple children", "hello", true, 2}, + {"invalid offset", "hello", false, 6}, + } { + t.Run(test.name, func(t *testing.T) { + parent := "hello" + if test.name == "embedded text" { + parent = "\ufffc" + } + text := caretTextReader{webID("/paragraph"): parent, webID("/text"): test.child} + cursor := mirroredCaretCursor(t, text, test.multiple) + if err := cursor.syncNativeCaret(context.Background(), text, webID("/paragraph"), test.offset); !errors.Is(err, atspi.ErrNoDocumentCaret) { + t.Fatalf("sync = %v", err) + } + }) + } +} + +func TestWorkerNativeCaretHandoffPrecedesNextArrow(t *testing.T) { + text := caretTextReader{webID("/text"): "When autocomplete"} + navigator := &boundaryNavigator{fakeCapturer: &fakeCapturer{}, caretTextReader: text} + worker, err := NewWorker(navigator, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/text")) + cursor := newCaretTextCursor(t, text) + syncResult, cursor := worker.syncDocumentCaret(context.Background(), cursor, request{nativeCaretFocus: webID("/text"), nativeCaretOffset: 11}) + if syncResult.Err != nil || syncResult.DocumentPosition.Offset != 11 { + t.Fatalf("handoff = %+v", syncResult) + } + result, _ := worker.moveDocumentCaret(context.Background(), cursor, CaretNextCharacter, 0) + if result.Err != nil || result.DocumentPosition.Offset != 12 || result.DocumentCaretText != "p" || navigator.offset != 12 { + t.Fatalf("move after selection = %+v; native offset = %d", result, navigator.offset) + } + worker.SyncFocus(webID("/next")) + stale, _ := worker.syncDocumentCaret(context.Background(), cursor, request{nativeCaretFocus: webID("/text"), nativeCaretOffset: 2}) + if !errors.Is(stale.Err, atspi.ErrStaleObject) { + t.Fatalf("stale sync = %+v", stale) + } +} diff --git a/internal/review/document_navigation_reader.go b/internal/review/document_navigation_reader.go new file mode 100644 index 0000000..fe54aaf --- /dev/null +++ b/internal/review/document_navigation_reader.go @@ -0,0 +1,64 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// One move owns this wrapper. Validate the path before native reads so stale +// range lengths and omitted candidates trigger recovery without consuming a +// different object's text or advancing the retained cursor. +type navigationTextReader struct { + DocumentCaretReader + tree *atspi.AccessibleTree + document atspi.DocumentSnapshot + anchor int + readObjects []atspi.ObjectReference +} + +func (reader *navigationTextReader) ReadDocumentCaret(ctx context.Context, object atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + index, found := reader.document.Index(object.ID()) + if !found || reader.document.Nodes[index].Reference != object { + return atspi.DocumentCaretText{}, atspi.ErrStaleObject + } + if err := reader.tree.ValidateDocumentRange(ctx, reader.document, reader.anchor, index); err != nil { + return atspi.DocumentCaretText{}, err + } + text, err := reader.DocumentCaretReader.ReadDocumentCaret(ctx, object, offset, unit) + if err == nil { + reader.readObjects = append(reader.readObjects, object) + } + return text, err +} + +func (reader *navigationTextReader) did_read(object atspi.ObjectReference) bool { + for _, read := range reader.readObjects { + if read == object { + return true + } + } + return false +} + +// Character blocks belong to one word command and never survive an event or +// recapture. Native spelling and actual word boundaries still use normal reads. +type navigationCharacterReader struct { + *navigationTextReader + source DocumentCharacterReader +} + +func (reader *navigationCharacterReader) ReadDocumentCharacters(ctx context.Context, object atspi.ObjectReference, offset int) (atspi.DocumentCaretText, error) { + index, found := reader.document.Index(object.ID()) + if !found || reader.document.Nodes[index].Reference != object { + return atspi.DocumentCaretText{}, atspi.ErrStaleObject + } + if err := reader.tree.ValidateDocumentRange(ctx, reader.document, reader.anchor, index); err != nil { + return atspi.DocumentCaretText{}, err + } + return reader.source.ReadDocumentCharacters(ctx, object, offset) +} diff --git a/internal/review/document_navigation_test.go b/internal/review/document_navigation_test.go new file mode 100644 index 0000000..6504934 --- /dev/null +++ b/internal/review/document_navigation_test.go @@ -0,0 +1,83 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestDocumentCaretDefersUnrelatedUpdatesUntilTraversed(t *testing.T) { + for _, test := range []struct { + name string + invalidate func(*atspi.AccessibleTree) + want error + }{ + {"text", func(tree *atspi.AccessibleTree) { tree.InvalidateText(webID("/next")) }, atspi.ErrStaleText}, + {"semantics", func(tree *atspi.AccessibleTree) { tree.InvalidateSnapshot(webID("/next")) }, atspi.ErrStaleSnapshot}, + {"geometry", func(tree *atspi.AccessibleTree) { tree.InvalidateGeometry(webID("/next")) }, atspi.ErrStaleGeometry}, + } { + t.Run(test.name, func(t *testing.T) { + reader := caretTextReader{webID("/text"): "Alpha", webID("/next"): "Next"} + cursor := newCaretTextCursor(t, reader) + test.invalidate(cursor.tree) + if _, err := cursor.SyncFocus(context.Background(), webID("/text")); err != nil { + t.Fatal("unrelated update blocked focus synchronization", err) + } + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextCharacter) + if err != nil || !move.Moved || move.Text != "l" { + t.Fatalf("local character move: %+v %v", move, err) + } + _, err = cursor.MoveCaret(context.Background(), reader, CaretNextLine) + if !errors.Is(err, test.want) { + t.Fatalf("dirty target read: %v, want %v", err, test.want) + } + if place := cursor.places[0]; place.object.ID() != webID("/text") || place.offset != 1 { + t.Fatalf("failed move changed position: %+v", place) + } + }) + } +} + +func TestDocumentCaretKeepsLocalTextThroughParentInsertion(t *testing.T) { + reader := caretTextReader{webID("/text"): "Alpha", webID("/next"): "Next"} + cursor := newCaretTextCursor(t, reader) + cursor.tree.MarkChildrenChanged(webID("/doc")) + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextCharacter) + if err != nil || !move.Moved || move.Text != "l" { + t.Fatalf("parent insertion blocked live text: %+v %v", move, err) + } + if _, err := cursor.MoveCaret(context.Background(), reader, CaretNextLine); !errors.Is(err, atspi.ErrIncompleteTree) { + t.Fatal("crossed stale child order", err) + } +} + +func TestDocumentStructuralMoveDefersUnrelatedBranch(t *testing.T) { + nodes := []atspi.TreeNode{ + {Snapshot: atspi.Snapshot{BusName: webID("/doc").BusName, Path: "/doc", Role: "document web"}, Children: []atspi.ObjectID{webID("/one"), webID("/two"), webID("/later")}}, + {Snapshot: atspi.Snapshot{BusName: webID("/one").BusName, Path: "/one", Role: "heading", Name: "First"}}, + {Snapshot: atspi.Snapshot{BusName: webID("/two").BusName, Path: "/two", Role: "heading", Name: "Second"}}, + {Snapshot: atspi.Snapshot{BusName: webID("/later").BusName, Path: "/later", Role: "static", Name: "Later"}}, + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + if _, err := cursor.SyncFocus(context.Background(), webID("/one")); err != nil { + t.Fatal(err) + } + tree.InvalidateText(webID("/later")) + move, err := cursor.Move(context.Background(), DocumentHeading, 0, false) + if err != nil || !move.Moved || move.Position.Object.ID() != webID("/two") { + t.Fatalf("unrelated update blocked adjacent heading: %+v %v", move, err) + } + if _, err := cursor.Move(context.Background(), DocumentHeading, 0, false); !errors.Is(err, atspi.ErrStaleText) { + t.Fatal("wrapped across dirty content", err) + } +} diff --git a/internal/review/document_replacement.go b/internal/review/document_replacement.go new file mode 100644 index 0000000..3fb233d --- /dev/null +++ b/internal/review/document_replacement.go @@ -0,0 +1,134 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import "git.stormux.org/storm/cthulhu/internal/atspi" + +// Orca recovers removed caret contexts from the surviving parent. Here the +// bounded case is one plain text leaf between the same adjacent siblings. +// Retain only its parent and two generation-checked boundary references; +// labels and child indices alone cannot establish the old reading position. +func remember_text_parent(doc atspi.DocumentSnapshot, place *documentPlace) { + place.textParent = atspi.ObjectReference{} + place.textPrevious, place.textNext = atspi.ObjectReference{}, atspi.ObjectReference{} + place.recoveryParents = nil + node, ok := doc.Node(place.object.ID()) + if !ok || node.Reference != place.object { + return + } + plainText := replacement_text_leaf(node) + for parentID := node.Parent; parentID.Valid(); { + parent, ok := doc.Node(parentID) + if !ok { + break + } + if len(place.recoveryParents) == 0 && plainText && replacement_text_parent(parent) { + place.textParent = parent.Reference + for childIndex, id := range parent.Children { + if id != place.object.ID() { + continue + } + if childIndex > 0 { + if sibling, ok := doc.Node(parent.Children[childIndex-1]); ok { + place.textPrevious = sibling.Reference + } + } + if childIndex+1 < len(parent.Children) { + if sibling, ok := doc.Node(parent.Children[childIndex+1]); ok { + place.textNext = sibling.Reference + } + } + if childIndex > 0 && !place.textPrevious.Valid() || childIndex+1 < len(parent.Children) && !place.textNext.Valid() { + place.textParent = atspi.ObjectReference{} + } + break + } + } + if parent.Reference == place.document || len(place.recoveryParents) == 32 { + break + } + place.recoveryParents = append(place.recoveryParents, parent.Reference) + parentID = parent.Parent + } +} + +// Navigation may restart within a surviving container when a page replaces +// several text children at once. Never transfer offsets or use this fallback +// for actions, and never cross a document generation, hidden or editable area. +func survivingDocumentParent(doc atspi.DocumentSnapshot, saved documentPlace) (atspi.DocumentNode, bool) { + if saved.document != doc.Context.TopLevel { + return atspi.DocumentNode{}, false + } + for _, parent := range saved.recoveryParents { + for _, node := range doc.Nodes { + if node.Reference == parent && !node.Hidden && !node.ParentEditable && + !node.Snapshot.Editable && !node.Snapshot.Focusable && !node.Snapshot.SupportsClick && + !atspi.IsWebDocumentRole(node.Snapshot.Role) { + return node, true + } + } + } + return atspi.DocumentNode{}, false +} + +func replacement_text_node(doc atspi.DocumentSnapshot, saved documentPlace) (atspi.DocumentNode, bool) { + if saved.document != doc.Context.TopLevel || !saved.textParent.Valid() || saved.origin != CaretNavigation { + return atspi.DocumentNode{}, false + } + byID := make(map[atspi.ObjectID]*atspi.DocumentNode, len(doc.Nodes)) + for index := range doc.Nodes { + node := &doc.Nodes[index] + byID[node.Reference.ID()] = node + } + for _, parent := range doc.Nodes { + if parent.Reference != saved.textParent || !replacement_text_parent(parent) { + continue + } + for index, id := range parent.Children { + var previous, next atspi.ObjectReference + if index > 0 { + sibling := byID[parent.Children[index-1]] + if sibling == nil { + continue + } + previous = sibling.Reference + } + if index+1 < len(parent.Children) { + sibling := byID[parent.Children[index+1]] + if sibling == nil { + continue + } + next = sibling.Reference + } + child := byID[id] + if previous == saved.textPrevious && next == saved.textNext && child != nil && replacement_text_leaf(*child) { + return *child, true + } + } + } + return atspi.DocumentNode{}, false +} + +func replacement_text_parent(node atspi.DocumentNode) bool { + if len(node.Children) == 0 || node.Hidden || node.ParentEditable || node.Snapshot.Editable { + return false + } + // Ordinary links retain their native text children. CSS-generated text + // (including ::before) can be recreated when its native caret is placed. + // Recover only navigation within the same surviving link and sibling + // boundaries. Activation still checks the saved target before SyncFocus. + if node.Snapshot.Role == "link" { + return !node.Snapshot.ExplicitName + } + return !node.Snapshot.Focusable && !node.Snapshot.SupportsClick && + (node.Snapshot.Role == "paragraph" || node.Snapshot.Role == "heading" || node.Snapshot.Role == "section") +} + +func replacement_text_leaf(node atspi.DocumentNode) bool { + return len(node.Children) == 0 && !node.Hidden && !node.ParentEditable && + !node.Snapshot.Editable && !node.Snapshot.Focusable && !node.Snapshot.SupportsClick && + !node.Snapshot.ExplicitName && node.Snapshot.CharacterCount > 0 && + (node.Snapshot.Role == "static" || node.Snapshot.Role == "text") +} diff --git a/internal/review/document_replacement_test.go b/internal/review/document_replacement_test.go new file mode 100644 index 0000000..241af55 --- /dev/null +++ b/internal/review/document_replacement_test.go @@ -0,0 +1,155 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestDocumentCaretRecoversSingleReplacedTextChild(t *testing.T) { + for _, kind := range []string{"single text", "multiple children", "editable", "replaced paragraph", "replaced document"} { + t.Run(kind, func(t *testing.T) { + reader := caretTextReader{webID("/old"): "Current total 10000 units", webID("/new"): "Current total 10001 units"} + node := func(path, role string, children ...atspi.ObjectID) atspi.TreeNode { + return atspi.TreeNode{Snapshot: atspi.Snapshot{BusName: webID(path).BusName, Path: path, Role: role, + CharacterCount: utf8.RuneCountInString(reader[webID(path)])}, Children: children} + } + nodes := []atspi.TreeNode{node("/doc", "document web", webID("/paragraph")), + node("/paragraph", "paragraph", webID("/old")), node("/old", "static")} + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, webID("/doc")); err != nil { + t.Fatal(err) + } + move, err := cursor.MoveCaret(ctx, reader, CaretNextLine) + if err != nil || move.Text != reader[webID("/old")] { + t.Fatalf("initial line = %+v, %v", move, err) + } + nodes[1].Children = []atspi.ObjectID{webID("/new")} + nodes[2] = node("/new", "static") + switch kind { + case "multiple children": + nodes[1].Children = append(nodes[1].Children, webID("/extra")) + nodes = append(nodes, node("/extra", "static")) + case "editable": + nodes[1].Snapshot.Editable = true + case "replaced paragraph": + tree.Invalidate(webID("/paragraph")) + case "replaced document": + tree.Invalidate(webID("/doc")) + } + if err := tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + position, recovery, err := cursor.sync_focus(ctx, webID("/doc")) + if err != nil { + t.Fatal(err) + } + if kind != "single text" { + wantRecovery := "saved-object-missing" + if kind == "replaced document" { + wantRecovery = "document-replaced" + } else if kind == "multiple children" { + wantRecovery = "surviving-parent" + } + if recovery != wantRecovery { + t.Fatalf("recovery = %q, want %q", recovery, wantRecovery) + } + if position.Object.ID() == webID("/new") { + t.Fatal("ambiguous or replaced context inherited the old caret") + } + return + } + if recovery != "replaced-text-child" { + t.Fatalf("replacement recovery = %q", recovery) + } + move, err = cursor.MoveCaret(ctx, reader, CaretNextCharacter) + if err != nil || move.Text != "u" || move.Position.Offset != 1 || move.Position.Object.ID() != webID("/new") { + t.Fatalf("Right after text replacement = %+v, %v", move, err) + } + }) + } +} + +func TestDocumentRecoveryKeepsVirtualPlaceWhenNativeAnchorDisappears(t *testing.T) { + ctx := context.Background() + reader := caretTextReader{webID("/text"): "First paragraph", webID("/next"): "Selected paragraph"} + cursor := newCaretTextCursor(t, reader) + move, err := cursor.MoveCaret(ctx, reader, CaretNextLine) + if err != nil || move.Position.Object.ID() != webID("/next") { + t.Fatalf("select second paragraph: %+v, %v", move, err) + } + worker, _ := NewWorker(&readAllCapturer{tree: cursor.tree}, time.Second) + worker.SyncFocus(webID("/text")) + nodes := []atspi.TreeNode{ + {Snapshot: atspi.Snapshot{BusName: webID("/doc").BusName, Path: "/doc", Role: "document web"}, Children: []atspi.ObjectID{webID("/next")}}, + {Snapshot: atspi.Snapshot{BusName: webID("/next").BusName, Path: "/next", Role: "static", CharacterCount: len(reader[webID("/next")])}}, + } + if err := cursor.tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + result := Result{DocumentFocus: webID("/text")} + if !worker.recoverCapturedDocumentFocus(cursor, cursor.tree, &result) { + t.Fatal("removed native anchor was not recovered") + } + if _, err := cursor.SyncFocus(ctx, result.DocumentFocus); err != nil { + t.Fatal(err) + } + move, err = cursor.MoveCaret(ctx, reader, CaretNextCharacter) + if err != nil || move.Text != "e" || move.Position.Object.ID() != webID("/next") || move.Position.Offset != 1 { + t.Fatalf("virtual position reset after native anchor removal: %+v, %v", move, err) + } +} + +func TestDocumentRecoveryUsesSurvivingContainerWithoutTransferringOffset(t *testing.T) { + for _, command := range []DocumentCaretCommand{CaretNextLine, CaretPreviousLine} { + t.Run(command.String(), func(t *testing.T) { + ctx := context.Background() + reader := caretTextReader{webID("/before"): "Previous paragraph", webID("/old"): "Old contents", webID("/new"): "Replacement contents"} + node := func(path, role string, children ...atspi.ObjectID) atspi.TreeNode { + return atspi.TreeNode{Snapshot: atspi.Snapshot{BusName: webID(path).BusName, Path: path, Role: role, + CharacterCount: len(reader[webID(path)])}, Children: children} + } + nodes := []atspi.TreeNode{node("/doc", "document web", webID("/before"), webID("/section")), + node("/before", "static"), node("/section", "section", webID("/paragraph")), + node("/paragraph", "paragraph", webID("/old")), node("/old", "static")} + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + cursor.SyncFocus(ctx, webID("/doc")) + cursor.MoveCaret(ctx, reader, CaretNextLine) + cursor.MoveCaret(ctx, reader, CaretNextLine) + cursor.MoveCaret(ctx, reader, CaretNextWord) + nodes[2].Children = []atspi.ObjectID{webID("/new")} + nodes = append(nodes[:3], node("/new", "static")) + if err := tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + position, recovery, err := cursor.sync_focus(ctx, webID("/doc")) + if err != nil || recovery != "surviving-parent" || position.Object.ID() != webID("/section") || position.Offset != 0 { + t.Fatalf("container recovery: %+v, %s, %v", position, recovery, err) + } + move, err := cursor.MoveCaret(ctx, reader, command) + want := "Replacement contents" + if command == CaretPreviousLine { + want = "Previous paragraph" + } + if err != nil || !move.Moved || move.Text != want { + t.Fatalf("navigation after replacement: %+v, %v", move, err) + } + }) + } +} diff --git a/internal/review/document_requests.go b/internal/review/document_requests.go new file mode 100644 index 0000000..60a85a5 --- /dev/null +++ b/internal/review/document_requests.go @@ -0,0 +1,69 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "time" +) + +func (worker *Worker) MoveDocumentCaret(command DocumentCaretCommand) error { + if !command.valid() { + return ErrInvalidDirection + } + select { + case worker.requests <- request{documentEpoch: worker.documentEpoch.Load(), caretCommand: command, queuedAt: time.Now()}: + return nil + default: + return ErrRequestQueueFull + } +} + +func (worker *Worker) ActivateDocumentCaret() error { + select { + case worker.requests <- request{documentEpoch: worker.documentEpoch.Load(), activate: true, queuedAt: time.Now()}: + return nil + default: + return ErrRequestQueueFull + } +} + +func (worker *Worker) ReadAll(ctx context.Context) error { + if ctx == nil { + return errors.New("read all: nil context") + } + select { + case worker.requests <- request{documentEpoch: worker.documentEpoch.Load(), readAll: ctx, queuedAt: time.Now()}: + return nil + default: + return ErrRequestQueueFull + } +} + +func (worker *Worker) JumpToDocumentFragment(fragment string) error { + if fragment == "" { + return ErrInvalidDirection + } + select { + case worker.requests <- request{documentEpoch: worker.documentEpoch.Load(), fragment: fragment, queuedAt: time.Now()}: + return nil + default: + return ErrRequestQueueFull + } +} diff --git a/internal/review/document_sound_test.go b/internal/review/document_sound_test.go new file mode 100644 index 0000000..ec7d4c1 --- /dev/null +++ b/internal/review/document_sound_test.go @@ -0,0 +1,103 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "reflect" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type soundGeometryNavigator struct { + *fakeDocumentNavigator + geometry [2]atspi.SoundGeometry + err error + reads int + t *testing.T +} + +func (navigator *soundGeometryNavigator) CaptureDocumentSoundGeometry(_ context.Context, object, link atspi.ObjectReference) ([2]atspi.SoundGeometry, error) { + navigator.reads++ + select { + case placed := <-navigator.calls: + if placed.position != object || link.ID() != webID("/topic_link") { + navigator.t.Fatal("geometry refresh did not follow placement of the selected heading and link") + } + default: + navigator.t.Fatal("geometry read before scrolling the target") + } + return navigator.geometry, navigator.err +} + +func TestDocumentSoundGeometryRefreshPreservesSemanticsAndPlacement(t *testing.T) { + oldGeometry := atspi.SoundGeometry{ObjectKnown: true, Object: atspi.Rectangle{X: 900, Y: 3000, Width: 50, Height: 15}} + freshGeometry := atspi.SoundGeometry{ + ObjectKnown: true, ReferenceKnown: true, + Object: atspi.Rectangle{X: 100, Y: 300, Width: 50, Height: 15}, + Reference: atspi.Rectangle{Width: 1000, Height: 600}, + } + for _, name := range []string{"fresh", "unavailable", "refresh failed", "placement failed"} { + t.Run(name, func(t *testing.T) { + node := func(path, role string, children ...atspi.ObjectID) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, "Topic", role, "", "") + snapshot.BusName = webID(path).BusName + snapshot.SoundGeometry = oldGeometry + return atspi.TreeNode{Snapshot: snapshot, Children: children} + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "document web", webID("/heading")), + node("/heading", "heading", webID("/topic_link")), + node("/topic_link", "link"), + }) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + document, _ := tree.Root() + heading, _ := tree.Reference(webID("/heading")) + linkRef, _ := tree.Reference(webID("/topic_link")) + snapshot, _ := tree.Resolve(heading) + link, _ := tree.Resolve(linkRef) + navigator := &soundGeometryNavigator{fakeDocumentNavigator: newFakeDocumentNavigator(), t: t} + want := atspi.SoundGeometry{} + switch name { + case "fresh": + navigator.geometry = [2]atspi.SoundGeometry{freshGeometry, freshGeometry} + want = freshGeometry + case "refresh failed": + navigator.err = context.DeadlineExceeded + case "placement failed": + navigator.placementErr <- atspi.ErrStaleObject + want = oldGeometry + } + worker, _ := NewWorker(navigator, time.Second) + worker.SyncFocus(webID("/doc")) + result := worker.placeDocument(context.Background(), cursor, Result{ + Moved: true, DocumentEpoch: worker.DocumentEpoch(), DocumentFocus: webID("/doc"), + DocumentPosition: DocumentPosition{Document: document, Object: heading, Snapshot: snapshot, LinkedHeading: &link}, + }) + if result.Err != nil || !errors.Is(result.DocumentSoundErr, navigator.err) { + t.Fatalf("sound refresh affected navigation: %+v", result) + } + if result.DocumentPosition.Snapshot.SoundGeometry != want || result.DocumentPosition.LinkedHeading.SoundGeometry != want { + t.Fatalf("geometry after %s = %+v", name, result.DocumentPosition) + } + if link.SoundGeometry != oldGeometry { + t.Fatal("refresh mutated the previously captured link snapshot") + } + cached, _ := tree.Resolve(heading) + if !reflect.DeepEqual(cached, snapshot) { + t.Fatal("refresh changed cached document semantics or geometry") + } + if name == "placement failed" && navigator.reads != 0 { + t.Fatal("failed caret placement still queried sound geometry") + } + }) + } +} diff --git a/internal/review/document_table.go b/internal/review/document_table.go new file mode 100644 index 0000000..a5df0ee --- /dev/null +++ b/internal/review/document_table.go @@ -0,0 +1,243 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "fmt" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// moveTable uses provider coordinates, never child order as a rectangular grid. +// The virtual coordinate survives a spanning cell so reversing direction keeps +// the user's column/row. Nested tables have independent coordinate spaces. +func (cursor *DocumentCursor) moveTable(ctx context.Context, doc atspi.DocumentSnapshot, place *documentPlace, command DocumentCaretCommand) (DocumentCaretMove, error) { + tableIndex, found := document_table_index(doc, place.object.ID()) + message := func(text string) (DocumentCaretMove, error) { + return DocumentCaretMove{Position: documentPosition(doc, *place), Text: text}, nil + } + if !found { + return message("Not in a table.") + } + table := doc.Nodes[tableIndex] + tableEnd := doc.SubtreeEnd(tableIndex) + if err := cursor.tree.ValidateDocumentRange(ctx, doc, tableIndex, tableEnd); err != nil { + return DocumentCaretMove{}, err + } + var current atspi.DocumentNode + for id, depth := place.object.ID(), 0; id.Valid() && id != table.Reference.ID() && depth < 128; depth++ { + node, ok := doc.Node(id) + if !ok { + break + } + role := node.Snapshot.Role + if (role == "table cell" || role == "row header" || role == "column header") && !node.Snapshot.TablePositionKnown { + return message("Table coordinates unavailable.") + } + if node.Snapshot.TablePositionKnown { + current = node + break + } + id = node.Parent + } + rows, columns := table.Snapshot.TableRowCount, table.Snapshot.TableColumnCount + if rows <= 0 || columns <= 0 { + return message("Table coordinates unavailable.") + } + row, col := current.Snapshot.TableRowIndex, current.Snapshot.TableColumnIndex + if current.Reference.Valid() && place.tableCell == current.Reference.ID() { + row, col = place.tableRow, place.tableColumn + } + dr, dc := 0, 0 + switch command { + case TableLeft: + dc = -1 + case TableRight: + dc = 1 + case TableUp: + dr = -1 + case TableDown: + dr = 1 + case TableFirst: + row, col = 0, 0 + case TableLast: + row, col = rows-1, columns-1 + } + // A table structural stop starts at its first cell on directional movement. + if current.Reference.Valid() { + row += dr + col += dc + } else if command != TableLast { + row, col = 0, 0 + } + cells := make([]atspi.DocumentNode, 0) + for index := tableIndex + 1; index <= tableEnd; index++ { + node := doc.Nodes[index] + if node.Snapshot.Role == "table" || node.Snapshot.Role == "tree table" { + index = doc.SubtreeEnd(index) + continue + } + if node.Snapshot.TablePositionKnown && !node.Hidden { + cells = append(cells, node) + } + } + for attempts := 0; attempts <= len(cells)+1; attempts++ { + if err := ctx.Err(); err != nil { + return DocumentCaretMove{}, err + } + if col < 0 { + return message("Beginning of row.") + } + if col >= columns { + return message("End of row.") + } + if row < 0 { + return message("Top of column.") + } + if row >= rows { + return message("Bottom of column.") + } + var target atspi.DocumentNode + for _, node := range cells { + s := node.Snapshot + if row >= s.TableRowIndex && row < s.TableRowIndex+max(1, s.TableRowSpan) && col >= s.TableColumnIndex && col < s.TableColumnIndex+max(1, s.TableColumnSpan) { + target = node + break + } + } + if !target.Reference.Valid() && (dr != 0 || dc != 0) { + target, row, col = next_available_table_cell(cells, current, row, col, dr, dc) + } + if !target.Reference.Valid() { + return message("Table cell unavailable.") + } + s := target.Snapshot + if target.Reference == current.Reference && (dr != 0 || dc != 0) { + // Jump over the span rather than iterating potentially huge dimensions. + if dr > 0 { + row = s.TableRowIndex + max(1, s.TableRowSpan) + } + if dr < 0 { + row = s.TableRowIndex - 1 + } + if dc > 0 { + col = s.TableColumnIndex + max(1, s.TableColumnSpan) + } + if dc < 0 { + col = s.TableColumnIndex - 1 + } + continue + } + parts := []string{} + rowHeader, columnHeader := "", "" + if s.TableRowHeaders != "" && s.TableRowHeaders != current.Snapshot.TableRowHeaders { + rowHeader = s.TableRowHeaders + parts = append(parts, rowHeader) + } + if s.TableColumnHeaders != "" && s.TableColumnHeaders != current.Snapshot.TableColumnHeaders { + columnHeader = s.TableColumnHeaders + parts = append(parts, columnHeader) + } + label := strings.TrimSpace(s.Name) + prefix := strings.Join(parts, " ") + prefixCount := len(parts) + if label == "" { + label = strings.TrimSpace(strings.ReplaceAll(s.Text, "\ufffc", "")) + } + if label == "" { + label = "blank" + } + parts = append(parts, label, fmt.Sprintf("Row %d, column %d.", s.TableRowIndex+1, s.TableColumnIndex+1)) + if s.TableRowSpan > 1 { + parts = append(parts, fmt.Sprintf("Spans %d rows.", s.TableRowSpan)) + } + if s.TableColumnSpan > 1 { + parts = append(parts, fmt.Sprintf("Spans %d columns.", s.TableColumnSpan)) + } + suffix := strings.Join(parts[prefixCount+1:], " ") + place.object, place.offset, place.origin = target.Reference, 0, StructuralNavigation + place.tableCell, place.tableRow, place.tableColumn = target.Reference.ID(), row, col + return DocumentCaretMove{Position: documentPosition(doc, *place), Text: strings.Join(parts, " "), TablePrefix: prefix, TableSuffix: suffix, + TableRowHeader: rowHeader, TableColumnHeader: columnHeader, Moved: true}, nil + } + return message("Table cell unavailable.") +} + +// Use the immutable document index and avoid rebuilding whole-page parent maps. +func document_table_index(doc atspi.DocumentSnapshot, id atspi.ObjectID) (int, bool) { + for depth := 0; id.Valid() && depth < 128; depth++ { + index, ok := doc.Index(id) + if !ok { + break + } + node := doc.Nodes[index] + if node.Snapshot.Role == "table" || node.Snapshot.Role == "tree table" { + return index, true + } + id = node.Parent + } + return 0, false +} + +// Search captured cells rather than iterating potentially enormous sparse +// dimensions. Horizontal neighbors can occupy a lower row of a spanning cell. +func next_available_table_cell(cells []atspi.DocumentNode, current atspi.DocumentNode, row, col, dr, dc int) (atspi.DocumentNode, int, int) { + var target atspi.DocumentNode + bestRow, bestCol := row, col + for _, node := range cells { + if node.Reference == current.Reference { + continue + } + s := node.Snapshot + rowEnd, colEnd := s.TableRowIndex+max(1, s.TableRowSpan)-1, s.TableColumnIndex+max(1, s.TableColumnSpan)-1 + candidateRow, candidateCol := row, col + if dr != 0 { + if col < s.TableColumnIndex || col > colEnd { + continue + } + if dr > 0 { + candidateRow = max(row, s.TableRowIndex) + if candidateRow > rowEnd { + continue + } + } else { + candidateRow = min(row, rowEnd) + if candidateRow < s.TableRowIndex { + continue + } + } + if target.Reference.Valid() && (dr > 0 && candidateRow >= bestRow || dr < 0 && candidateRow <= bestRow) { + continue + } + } else { + lastRow := row + if current.Reference.Valid() { + lastRow = max(row, current.Snapshot.TableRowIndex+max(1, current.Snapshot.TableRowSpan)-1) + } + candidateRow = max(row, s.TableRowIndex) + if candidateRow > rowEnd || candidateRow > lastRow { + continue + } + if dc > 0 { + candidateCol = max(col, s.TableColumnIndex) + if candidateCol > colEnd { + continue + } + } else { + candidateCol = min(col, colEnd) + if candidateCol < s.TableColumnIndex { + continue + } + } + if target.Reference.Valid() && (candidateRow > bestRow || candidateRow == bestRow && (dc > 0 && candidateCol >= bestCol || dc < 0 && candidateCol <= bestCol)) { + continue + } + } + target, bestRow, bestCol = node, candidateRow, candidateCol + } + return target, bestRow, bestCol +} diff --git a/internal/review/document_table_test.go b/internal/review/document_table_test.go new file mode 100644 index 0000000..d0f9f28 --- /dev/null +++ b/internal/review/document_table_test.go @@ -0,0 +1,179 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestTableNavigationSpansHeadersAndBoundaries(t *testing.T) { + node := func(path, role, name string, children ...string) atspi.TreeNode { + s := atspi.NewSnapshot(path, name, role, "", "") + s.BusName = webID(path).BusName + n := atspi.TreeNode{Snapshot: s} + for _, child := range children { + n.Children = append(n.Children, webID(child)) + } + return n + } + nodes := []atspi.TreeNode{node("/doc", "document web", "", "/table", "/outside"), node("/table", "table", "", "/a", "/b", "/c", "/d", "/e"), node("/outside", "paragraph", "Outside")} + nodes[1].Snapshot.TableRowCount, nodes[1].Snapshot.TableColumnCount = 3, 2 + for _, c := range []struct { + path, name string + row, col, rs, cs int + }{{"/a", "A", 0, 0, 1, 1}, {"/b", "B", 0, 1, 1, 1}, {"/c", "Merged", 1, 0, 1, 2}, {"/d", "D", 2, 0, 1, 1}, {"/e", "", 2, 1, 1, 1}} { + n := node(c.path, "table cell", c.name) + n.Snapshot.TablePositionKnown = true + n.Snapshot.TableRowIndex, n.Snapshot.TableColumnIndex = c.row, c.col + n.Snapshot.TableRowSpan, n.Snapshot.TableColumnSpan = c.rs, c.cs + if c.col == 1 { + n.Snapshot.TableColumnHeaders = "Second" + } + nodes = append(nodes, n) + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + cursor.SyncFocus(context.Background(), webID("/table")) + for _, step := range []struct { + command DocumentCaretCommand + path, text string + moved bool + }{ + {TableFirst, "/a", "Row 1, column 1.", true}, + {TableRight, "/b", "Second B", true}, + {TableDown, "/c", "Spans 2 columns.", true}, + {TableDown, "/e", "blank Row 3, column 2.", true}, + {TableUp, "/c", "Merged", true}, + {TableUp, "/b", "B", true}, + {TableUp, "/b", "Top of column.", false}, + {TableRight, "/b", "End of row.", false}, + {TableLast, "/e", "blank", true}, + {TableDown, "/e", "Bottom of column.", false}, + {TableFirst, "/a", "A", true}, + {TableLeft, "/a", "Beginning of row.", false}, + } { + got, err := cursor.MoveCaret(context.Background(), caretTextReader{}, step.command) + if err != nil || got.Moved != step.moved || got.Position.Object.ID() != webID(step.path) || !strings.Contains(got.Text, step.text) { + t.Fatalf("command %v: %+v, %v", step.command, got, err) + } + } + cursor.SyncFocus(context.Background(), webID("/outside")) + got, err := cursor.MoveCaret(context.Background(), caretTextReader{}, TableRight) + if err != nil || got.Moved || got.Text != "Not in a table." { + t.Fatalf("outside: %+v %v", got, err) + } +} + +func TestTableNavigationRowSpanAndNestedTable(t *testing.T) { + makeNode := func(path, role string, children ...string) atspi.TreeNode { + s := atspi.NewSnapshot(path, path, role, "", "") + s.BusName = webID(path).BusName + n := atspi.TreeNode{Snapshot: s} + for _, child := range children { + n.Children = append(n.Children, webID(child)) + } + return n + } + doc := makeNode("/doc", "document web", "/table") + table := makeNode("/table", "table", "/a", "/b", "/c") + table.Snapshot.TableRowCount, table.Snapshot.TableColumnCount = 2, 2 + a := makeNode("/a", "table cell", "/nested") + b := makeNode("/b", "table cell") + c := makeNode("/c", "table cell") + for _, n := range []*atspi.TreeNode{&a, &b, &c} { + n.Snapshot.TablePositionKnown = true + n.Snapshot.TableRowSpan = 1 + n.Snapshot.TableColumnSpan = 1 + } + a.Snapshot.TableRowSpan = 2 + b.Snapshot.TableColumnIndex = 1 + c.Snapshot.TableRowIndex = 1 + c.Snapshot.TableColumnIndex = 1 + nested := makeNode("/nested", "table", "/inner") + nested.Snapshot.TableRowCount = 1 + nested.Snapshot.TableColumnCount = 1 + inner := makeNode("/inner", "table cell") + inner.Snapshot.TablePositionKnown = true + inner.Snapshot.TableRowSpan = 1 + inner.Snapshot.TableColumnSpan = 1 + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{doc, table, a, b, c, nested, inner}) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + cursor.SyncFocus(context.Background(), webID("/c")) + for _, step := range []struct { + cmd DocumentCaretCommand + path string + }{{TableLeft, "/a"}, {TableRight, "/c"}, {TableUp, "/b"}, {TableLeft, "/a"}, {TableRight, "/b"}} { + got, err := cursor.MoveCaret(context.Background(), caretTextReader{}, step.cmd) + if err != nil || got.Position.Object.ID() != webID(step.path) { + t.Fatalf("%v: %+v %v", step.cmd, got, err) + } + } + cursor.SyncFocus(context.Background(), webID("/inner")) + got, err := cursor.MoveCaret(context.Background(), caretTextReader{}, TableRight) + if err != nil || got.Moved || got.Text != "End of row." { + t.Fatalf("nested table escaped: %+v %v", got, err) + } +} + +func TestTableNavigationSkipsHolesAndKeepsLocalDependencies(t *testing.T) { + makeNode := func(path, role string, children ...string) atspi.TreeNode { + s := atspi.NewSnapshot(path, path, role, "", "") + s.BusName = webID(path).BusName + n := atspi.TreeNode{Snapshot: s} + for _, child := range children { + n.Children = append(n.Children, webID(child)) + } + return n + } + nodes := []atspi.TreeNode{makeNode("/doc", "document web", "/table", "/ticker"), makeNode("/table", "table", "/a", "/b", "/c"), makeNode("/ticker", "static")} + nodes[1].Snapshot.TableRowCount, nodes[1].Snapshot.TableColumnCount = 1000000, 3 + for _, cell := range []struct { + path string + row, col, span int + }{{"/a", 0, 0, 1000000}, {"/b", 1, 1, 1}, {"/c", 999999, 1, 1}} { + n := makeNode(cell.path, "table cell") + n.Snapshot.TablePositionKnown = true + n.Snapshot.TableRowIndex, n.Snapshot.TableColumnIndex, n.Snapshot.TableRowSpan = cell.row, cell.col, cell.span + nodes = append(nodes, n) + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + if _, err = cursor.SyncFocus(context.Background(), webID("/a")); err != nil { + t.Fatal(err) + } + tree.InvalidateText(webID("/ticker")) + for _, step := range []struct { + command DocumentCaretCommand + path string + }{{TableRight, "/b"}, {TableDown, "/c"}, {TableUp, "/b"}, {TableLeft, "/a"}, {TableRight, "/b"}} { + move, err := cursor.MoveCaret(context.Background(), caretTextReader{}, step.command) + if err != nil || !move.Moved || move.Position.Object.ID() != webID(step.path) { + t.Fatalf("%s: %+v error=%v", step.command, move, err) + } + } + // Changed cells inside the table must still refresh the coordinate/header view. + tree.InvalidateSnapshot(webID("/c")) + before := cursor.places[0] + if _, err = cursor.MoveCaret(context.Background(), caretTextReader{}, TableDown); !errors.Is(err, atspi.ErrStaleSnapshot) { + t.Fatalf("stale cell ignored: %v", err) + } + if after := cursor.places[0]; after.object != before.object || after.tableRow != before.tableRow { + t.Fatal("failed move changed table position") + } +} diff --git a/internal/review/document_test.go b/internal/review/document_test.go new file mode 100644 index 0000000..29631b5 --- /dev/null +++ b/internal/review/document_test.go @@ -0,0 +1,514 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "fmt" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func webID(path string) atspi.ObjectID { return atspi.NewObjectID(":1.73", path) } + +func TestLinkedHeadingNavigationAndActivation(t *testing.T) { + for _, tc := range []struct { + name, heading, link string + multiple bool + }{ + {"heading contains link", "/heading", "/link", false}, + {"link contains heading", "/heading", "/link", false}, + {"ambiguous links", "/heading", "", true}, + {"leading post link", "/heading", "/link1", false}, + {"leading link without text offsets", "/heading", "/link1", false}, + {"plain text before multiple links", "/heading", "", true}, + {"plain text omitted from children", "/heading", "", true}, + } { + t.Run(tc.name, func(t *testing.T) { + node := func(path, role string, children ...string) atspi.TreeNode { + s := atspi.NewSnapshot(path, "", role, "", "") + s.BusName = webID(path).BusName + if role == "heading" { + s.Name, s.HeadingLevel = "Linked heading", 2 + } + if role == "link" { + s.Visited = true + } + n := atspi.TreeNode{Snapshot: s} + for _, child := range children { + n.Children = append(n.Children, webID(child)) + } + return n + } + nodes := []atspi.TreeNode{node("/doc", "document web", "/start"), node("/start", "paragraph")} + switch tc.name { + case "link contains heading": + nodes[0].Children = append(nodes[0].Children, webID("/link")) + nodes = append(nodes, node("/link", "link", "/heading"), node("/heading", "heading")) + case "ambiguous links", "leading post link", "leading link without text offsets", "plain text before multiple links", "plain text omitted from children": + nodes[0].Children = append(nodes[0].Children, webID("/heading")) + nodes = append(nodes, node("/heading", "heading", "/link1", "/link2"), node("/link1", "link"), node("/link2", "link")) + nodes[2].Snapshot.SupportsClick = true + if tc.name != "ambiguous links" { + nodes[3].Children = []atspi.ObjectID{webID("/post_text")} + nodes[4].Children = []atspi.ObjectID{webID("/date_text")} + nodes = append(nodes, node("/post_text", "static"), node("/date_text", "static")) + nodes[5].Snapshot.Name, nodes[5].Snapshot.CharacterCount = "#1", 2 + nodes[6].Snapshot.Name, nodes[6].Snapshot.CharacterCount = "Date", 4 + } + if tc.name == "leading link without text offsets" || tc.name == "plain text omitted from children" { + nodes[2].Snapshot.Name = "#1 Date" + nodes[3].Snapshot.Name, nodes[4].Snapshot.Name = "#1", "Date" + nodes[5].Snapshot.CharacterCount, nodes[6].Snapshot.CharacterCount = 0, 0 + } + if tc.name == "plain text omitted from children" { + nodes[2].Snapshot.Name = "Post #1 Date" + } + if tc.name == "plain text before multiple links" { + nodes[2].Children = append([]atspi.ObjectID{webID("/prefix")}, nodes[2].Children...) + nodes = append(nodes, node("/prefix", "static")) + nodes[len(nodes)-1].Snapshot.Name, nodes[len(nodes)-1].Snapshot.CharacterCount = "Post", 4 + } + default: + nodes[0].Children = append(nodes[0].Children, webID("/heading")) + nodes = append(nodes, node("/heading", "heading", "/static"), node("/static", "static", "/link"), node("/link", "link")) + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, _ := NewDocumentCursor(tree) + if _, err := cursor.SyncFocus(context.Background(), webID("/start")); err != nil { + t.Fatal(err) + } + move, err := cursor.Move(context.Background(), DocumentHeading, 2, false) + if err != nil || !move.Moved || move.Position.Object.ID() != webID(tc.heading) { + t.Fatalf("heading move = %+v, %v", move, err) + } + target, err := cursor.ActivationTarget() + if tc.multiple { + if move.Position.LinkedHeading != nil || !errors.Is(err, ErrNoDocumentAction) { + t.Fatalf("ambiguous heading resolved: %+v, %v", move.Position.LinkedHeading, err) + } + } else if err != nil || target.ID() != webID(tc.link) || move.Position.LinkedHeading == nil || !move.Position.LinkedHeading.Visited { + t.Fatalf("linked heading = %+v, target %v, err %v", move.Position, target.ID(), err) + } + }) + } +} + +func TestDocumentFragmentSelectsPostPermalink(t *testing.T) { + node := func(path, name, role, id string, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, name, role, "", "") + snapshot.BusName = webID(path).BusName + snapshot.ElementID = id + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "Forum", "document web", "", "/first", "/second"), + node("/first", "", "section", "p1", "/first_link"), + node("/first_link", "#1", "link", ""), + node("/second", "", "section", "p2", "/heading"), + node("/heading", "#2 User", "heading", "", "/second_link"), + node("/second_link", "#2", "link", ""), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, webID("/doc")); err != nil { + t.Fatal(err) + } + position, found, err := cursor.JumpToFragment(ctx, "p2") + if err != nil || !found || position.Object.ID() != webID("/second_link") { + t.Fatalf("fragment position = %+v, found %t, err %v", position, found, err) + } + if _, found, err := cursor.JumpToFragment(ctx, "absent"); err != nil || found { + t.Fatalf("missing fragment: found %t, err %v", found, err) + } +} + +func webNodes() []atspi.TreeNode { + node := func(path, role string, children ...string) atspi.TreeNode { + s := atspi.NewSnapshot(path, path, role, "", "") + s.BusName = webID(path).BusName + if role == "heading" { + s.HeadingLevel = 2 + } + n := atspi.TreeNode{Snapshot: s} + for _, child := range children { + n.Children = append(n.Children, webID(child)) + } + return n + } + return []atspi.TreeNode{ + node("/root", "frame", "/chrome", "/doc", "/other"), + node("/chrome", "entry"), + node("/doc", "document web", "/first", "/hidden", "/second", "/nested", "/button", "/checkbox", "/list", "/separator"), + node("/first", "heading"), + node("/hidden", "heading"), + node("/second", "heading"), + node("/nested", "document web", "/link"), + func() atspi.TreeNode { + link := node("/link", "link") + link.Snapshot.Focusable = true + return link + }(), + node("/other", "document web", "/otherHeading"), + node("/otherHeading", "heading"), + node("/button", "push button"), + node("/checkbox", "check box"), + node("/list", "list"), + node("/separator", "separator"), + } +} + +func webCursor(t *testing.T) (*atspi.AccessibleTree, *DocumentCursor) { + t.Helper() + nodes := webNodes() + nodes[4].Geometry = atspi.Geometry{VisibilityKnown: true} + nodes[5].Geometry = atspi.Geometry{VisibilityKnown: true, Visible: true} + tree, err := atspi.NewAccessibleTree(webID("/root"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + return tree, cursor +} + +func TestDocumentCursorNavigationAndChromeRoundTrip(t *testing.T) { + _, cursor := webCursor(t) + ctx := context.Background() + position, err := cursor.SyncFocus(ctx, webID("/first")) + if err != nil || position.Origin != NativeNavigation { + t.Fatalf("focus: %+v %v", position, err) + } + move, err := cursor.Move(ctx, DocumentHeading, 2, false) + if err != nil || !move.Moved || move.Position.Snapshot.Path != "/second" || move.Position.Origin != StructuralNavigation || move.Wrapped { + t.Fatalf("heading: %+v %v", move, err) + } + // Duplicate focus events and leaving/returning through chrome preserve + // a separately navigated position; a new native target overrides it. + for _, chrome := range []bool{false, true} { + if chrome { + if _, err := cursor.SyncFocus(ctx, webID("/chrome")); !errors.Is(err, atspi.ErrNotInDocument) { + t.Fatal(err) + } + if _, err := cursor.Move(ctx, DocumentHeading, 0, false); !errors.Is(err, ErrNoCurrent) { + t.Fatal(err) + } + } + position, err = cursor.SyncFocus(ctx, webID("/first")) + if err != nil || position.Snapshot.Path != "/second" { + t.Fatalf("lost position: %+v %v", position, err) + } + } + move, err = cursor.Move(ctx, DocumentLink, 0, false) + if err != nil || !move.Moved || move.Position.Snapshot.Path != "/link" || move.Position.Document.ID() != webID("/doc") || move.Wrapped { + t.Fatalf("embedded link: %+v %v", move, err) + } + move, err = cursor.Move(ctx, DocumentHeading, 0, false) + if err != nil || !move.Moved || !move.Wrapped || move.Position.Snapshot.Path != "/first" { + t.Fatalf("forward heading wrap: %+v %v", move, err) + } + move, err = cursor.Move(ctx, DocumentHeading, 0, true) + if err != nil || !move.Moved || !move.Wrapped || move.Position.Snapshot.Path != "/second" { + t.Fatalf("backward heading: %+v %v", move, err) + } + position, err = cursor.SyncFocus(ctx, webID("/link")) + if err != nil || position.Snapshot.Path != "/link" || position.Origin != NativeNavigation { + t.Fatalf("native focus: %+v %v", position, err) + } +} + +func TestDocumentCursorDoesNotReanchorMatchingNestedTarget(t *testing.T) { + nodes := webNodes() + for i := range nodes { + if nodes[i].Snapshot.Path == "/list" { + nodes[i].Children = []atspi.ObjectID{webID("/inner_list")} + } + } + nodes = append(nodes, atspi.TreeNode{Snapshot: atspi.Snapshot{ + BusName: webID("/inner_list").BusName, Path: "/inner_list", Role: "list", + }}) + tree, err := atspi.NewAccessibleTree(webID("/root"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, webID("/inner_list")); err != nil { + t.Fatal(err) + } + move, err := cursor.Move(ctx, DocumentList, 0, false) + if err != nil || move.Position.Snapshot.Path != "/list" || !move.Wrapped { + t.Fatalf("next list should advance from the nested list and wrap: %+v, %v", move, err) + } + if _, err := cursor.SyncFocus(ctx, webID("/separator")); err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, webID("/inner_list")); err != nil { + t.Fatal(err) + } + move, err = cursor.Move(ctx, DocumentList, 0, true) + if err != nil || move.Position.Snapshot.Path != "/list" || move.Wrapped { + t.Fatalf("previous list should reach containing list without wrapping: %+v, %v", move, err) + } +} + +func TestDocumentCursorAnchorsNavigationAtMatchingAncestor(t *testing.T) { + node := func(path, role string, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, path, role, "", "") + snapshot.BusName = webID(path).BusName + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + first := node("/first", "link", "/first/text") + first.Snapshot.Focusable = true + second := node("/second", "link") + second.Snapshot.Focusable = true + tree, err := atspi.NewAccessibleTree(webID("/root"), []atspi.TreeNode{ + node("/root", "frame", "/doc"), + node("/doc", "document web", "/first", "/second"), + first, + node("/first/text", "static"), + second, + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(context.Background(), webID("/first/text")); err != nil { + t.Fatal(err) + } + move, err := cursor.Move(context.Background(), DocumentLink, 0, true) + if err != nil || !move.Moved || !move.Wrapped || move.Position.Snapshot.Path != "/second" { + t.Fatalf("previous link from descendant = %+v, %v", move, err) + } +} + +func TestDocumentCursorStructuralTargets(t *testing.T) { + _, cursor := webCursor(t) + ctx := context.Background() + cursor.SyncFocus(ctx, webID("/first")) + for _, tc := range []struct { + target DocumentTarget + path string + }{ + {DocumentButton, "/button"}, + {DocumentCheckBox, "/checkbox"}, + {DocumentList, "/list"}, + {DocumentSeparator, "/separator"}, + } { + move, err := cursor.Move(ctx, tc.target, 0, false) + if err != nil || !move.Moved || move.Position.Snapshot.Path != tc.path || move.Position.Origin != StructuralNavigation || move.Wrapped { + t.Fatalf("target %v: %+v err=%v", tc.target, move, err) + } + move, err = cursor.Move(ctx, tc.target, 0, false) + if err != nil || !move.Moved || !move.Wrapped || move.Position.Snapshot.Path != tc.path { + t.Fatalf("target %v wrap: %+v err=%v", tc.target, move, err) + } + cursor.SyncFocus(ctx, webID("/first")) + } + if _, err := cursor.Move(ctx, DocumentHeading, 7, false); err == nil { + t.Fatal("invalid heading level accepted") + } +} + +func TestDocumentCursorReferenceStructuralTargets(t *testing.T) { + snapshot := func(path, role string, configure func(*atspi.Snapshot)) atspi.TreeNode { + s := atspi.NewSnapshot(path, path, role, "", "") + s.BusName = webID(path).BusName + if configure != nil { + configure(&s) + } + return atspi.TreeNode{Snapshot: s} + } + nodes := []atspi.TreeNode{ + snapshot("/doc", "document web", nil), + snapshot("/start", "section", nil), + snapshot("/blockquote", "block quote", nil), + snapshot("/combo", "combo box", nil), + snapshot("/entry", "entry", func(s *atspi.Snapshot) { s.Editable, s.Focusable = true, true }), + snapshot("/form", "push button", func(s *atspi.Snapshot) { s.Focusable = true }), + snapshot("/image", "image", nil), + snapshot("/landmark", "landmark", nil), + snapshot("/listitem", "list item", nil), + snapshot("/live", "section", func(s *atspi.Snapshot) { s.LiveRegion = true }), + snapshot("/paragraph", "paragraph", func(s *atspi.Snapshot) { s.CharacterCount = 4 }), + snapshot("/radio", "radio button", nil), + snapshot("/table", "table", func(s *atspi.Snapshot) { s.TableRowCount = 1 }), + snapshot("/tablecell", "table cell", nil), + snapshot("/unvisited", "link", func(s *atspi.Snapshot) { s.Focusable = true }), + snapshot("/visited", "link", func(s *atspi.Snapshot) { s.Focusable, s.Visited = true, true }), + snapshot("/clickable", "section", func(s *atspi.Snapshot) { s.SupportsClick = true }), + snapshot("/chunk", "paragraph", func(s *atspi.Snapshot) { s.CharacterCount, s.EmbeddedObjectCount = 80, 1 }), + snapshot("/heading", "heading", func(s *atspi.Snapshot) { s.HeadingLevel = 3 }), + } + nodes[0].Children = []atspi.ObjectID{ + webID("/start"), webID("/blockquote"), webID("/combo"), webID("/entry"), + webID("/form"), webID("/image"), webID("/landmark"), webID("/listitem"), + webID("/live"), webID("/paragraph"), webID("/radio"), webID("/table"), + webID("/unvisited"), webID("/visited"), webID("/clickable"), + webID("/chunk"), webID("/heading"), + } + nodes[12].Children = []atspi.ObjectID{webID("/tablecell")} + tree, err := atspi.NewAccessibleTree(webID("/doc"), nodes) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + if _, err := cursor.SyncFocus(ctx, webID("/start")); err != nil { + t.Fatal(err) + } + for _, tc := range []struct { + target DocumentTarget + level int + path string + }{ + {DocumentBlockQuote, 0, "/blockquote"}, + {DocumentComboBox, 0, "/combo"}, + {DocumentEntry, 0, "/entry"}, + {DocumentFormField, 0, "/form"}, + {DocumentImage, 0, "/image"}, + {DocumentLandmark, 0, "/landmark"}, + {DocumentListItem, 0, "/listitem"}, + {DocumentLiveRegion, 0, "/live"}, + {DocumentParagraph, 0, "/paragraph"}, + {DocumentRadioButton, 0, "/radio"}, + {DocumentTable, 0, "/table"}, + {DocumentUnvisitedLink, 0, "/unvisited"}, + {DocumentVisitedLink, 0, "/visited"}, + {DocumentClickable, 0, "/clickable"}, + {DocumentChunk, 0, "/chunk"}, + {DocumentHeading, 3, "/heading"}, + } { + move, err := cursor.Move(ctx, tc.target, tc.level, false) + if err != nil || !move.Moved || move.Position.Snapshot.Path != tc.path { + t.Fatalf("target %v level %d: %+v err=%v", tc.target, tc.level, move, err) + } + if _, err := cursor.SyncFocus(ctx, webID("/start")); err != nil { + t.Fatal(err) + } + } +} + +func TestDocumentCursorTabsAndInvalidation(t *testing.T) { + tree, cursor := webCursor(t) + ctx := context.Background() + cursor.SyncFocus(ctx, webID("/first")) + cursor.Move(ctx, DocumentHeading, 0, false) + cursor.SyncFocus(ctx, webID("/otherHeading")) + position, err := cursor.SyncFocus(ctx, webID("/first")) + if err != nil || position.Snapshot.Path != "/second" { + t.Fatalf("tab restoration: %+v %v", position, err) + } + tree.Invalidate(webID("/doc")) + if _, err := cursor.Move(ctx, DocumentHeading, 0, false); !errors.Is(err, atspi.ErrStaleObject) { + t.Fatal(err) + } + if err := tree.Replace(webID("/root"), webNodes()); err != nil { + t.Fatal(err) + } + position, err = cursor.SyncFocus(ctx, webID("/first")) + if err != nil || position.Snapshot.Path != "/first" || position.Origin != NativeNavigation { + t.Fatalf("inherited stale position: %+v %v", position, err) + } + if _, err := cursor.SyncFocus(ctx, webID("/missing")); !errors.Is(err, atspi.ErrObjectNotFound) { + t.Fatal(err) + } + if _, err := cursor.Move(ctx, DocumentHeading, 0, false); !errors.Is(err, ErrNoCurrent) { + t.Fatal(err) + } +} + +func TestDocumentCursorRejectsReparentedObject(t *testing.T) { + tree, cursor := webCursor(t) + ctx := context.Background() + cursor.SyncFocus(ctx, webID("/first")) + nodes := webNodes() + nodes[2].Children = nodes[2].Children[1:] + nodes[8].Children = append(nodes[8].Children, webID("/first")) + if err := tree.Replace(webID("/root"), nodes); err != nil { + t.Fatal(err) + } + if _, err := cursor.Move(ctx, DocumentHeading, 0, false); !errors.Is(err, atspi.ErrStaleObject) { + t.Fatal(err) + } +} + +func TestDocumentCursorCanceledMovePreservesPosition(t *testing.T) { + _, cursor := webCursor(t) + cursor.SyncFocus(context.Background(), webID("/first")) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := cursor.Move(ctx, DocumentHeading, 0, false); !errors.Is(err, context.Canceled) { + t.Fatal(err) + } + move, err := cursor.Move(context.Background(), DocumentHeading, 0, true) + if err != nil || !move.Moved || !move.Wrapped || move.Position.Snapshot.Path != "/second" { + t.Fatalf("position after canceled move: %+v %v", move, err) + } +} + +func TestDocumentCursorBoundsRememberedDocuments(t *testing.T) { + _, cursor := webCursor(t) + ctx := context.Background() + for i := 0; i < 20; i++ { + nodes := webNodes() + // Simulate reused native paths after each page replacement. + cursor.tree.Invalidate(webID("/doc")) + nodes[3].Snapshot.Name = fmt.Sprintf("page %d", i) + if err := cursor.tree.Replace(webID("/root"), nodes); err != nil { + t.Fatal(err) + } + position, err := cursor.SyncFocus(ctx, webID("/first")) + if err != nil || position.Snapshot.Name != fmt.Sprintf("page %d", i) { + t.Fatalf("page %d position: %+v %v", i, position, err) + } + } + if len(cursor.places) != 16 { + t.Fatalf("remembered %d documents", len(cursor.places)) + } +} diff --git a/internal/review/document_tooltip_test.go b/internal/review/document_tooltip_test.go new file mode 100644 index 0000000..179d34d --- /dev/null +++ b/internal/review/document_tooltip_test.go @@ -0,0 +1,101 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func tooltip_cursor(t *testing.T, focusable, editable, hypertext bool) (*DocumentCursor, caretTextReader) { + t.Helper() + reader := caretTextReader{webID("/before"): "Project", webID("/tiptext"): "Project", webID("/after"): "After"} + node := func(path, role string, children ...atspi.ObjectID) atspi.TreeNode { + return atspi.TreeNode{Snapshot: atspi.Snapshot{BusName: webID(path).BusName, Path: path, + Role: role, StatesKnown: true, CharacterCount: len(reader[webID(path)])}, Children: children} + } + tip := node("/tip", "tool tip", webID("/tiptext")) + tip.Snapshot.Focusable, tip.Snapshot.Editable = focusable, editable + if hypertext { + // Text around an embedded child must not bypass subtree exclusion. + tip.Snapshot.CharacterCount = 3 + tip.Snapshot.TextChildren = []atspi.TextChild{{Offset: 1, Child: webID("/tiptext")}} + reader[webID("/tip")] = "x\ufffcy" + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "document web", webID("/before"), webID("/tip"), webID("/after")), + node("/before", "static"), tip, node("/tiptext", "static"), node("/after", "static"), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(context.Background(), webID("/before")); err != nil { + t.Fatal(err) + } + return cursor, reader +} + +func TestDocumentCaretSkipsPassiveTooltip(t *testing.T) { + for _, hypertext := range []bool{false, true} { + for _, command := range []DocumentCaretCommand{CaretNextLine, CaretNextCharacter, CaretNextWord} { + t.Run(command.String(), func(t *testing.T) { + cursor, reader := tooltip_cursor(t, false, false, hypertext) + if command != CaretNextLine { + cursor.places[0].offset = len("Project") - 1 + } + move, err := cursor.MoveCaret(context.Background(), reader, command) + if err != nil || !move.Moved || move.Position.Object.ID() != webID("/after") { + t.Fatalf("forward: %+v, %v", move, err) + } + reverse := CaretPreviousLine + if command == CaretNextCharacter { + reverse = CaretPreviousCharacter + } else if command == CaretNextWord { + reverse = CaretPreviousWord + } + cursor.places[0].offset = 0 + move, err = cursor.MoveCaret(context.Background(), reader, reverse) + if err != nil || !move.Moved || move.Position.Object.ID() != webID("/before") { + t.Fatalf("backward: %+v, %v", move, err) + } + }) + } + } +} + +func TestDocumentCaretPreservesInteractiveTooltip(t *testing.T) { + for _, focusable := range []bool{false, true} { + cursor, reader := tooltip_cursor(t, focusable, !focusable, false) + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextLine) + if err != nil || !move.Moved || move.Position.Object.ID() != webID("/tiptext") { + t.Fatalf("interactive tooltip: %+v, %v", move, err) + } + } +} + +func TestReadAllSkipsPassiveTooltip(t *testing.T) { + cursor, reader := tooltip_cursor(t, false, false, true) + worker, err := NewWorker(&readAllCapturer{tree: cursor.tree, caretTextReader: reader}, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/before")) + result := worker.readAll(context.Background(), cursor) + if result.Err != nil || len(result.ReadAllLines) != 2 { + t.Fatalf("Read All: %+v", result) + } + for index, want := range []string{"Project", "After"} { + if got := result.ReadAllLines[index].Contents[0].Text; got != want { + t.Fatalf("line %d = %q, want %q", index, got, want) + } + } +} diff --git a/internal/review/document_visual_line.go b/internal/review/document_visual_line.go new file mode 100644 index 0000000..d47249c --- /dev/null +++ b/internal/review/document_visual_line.go @@ -0,0 +1,284 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "math" + "strings" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// A visual line is temporary move-owned data. The retained cursor always uses +// an actual object's native offset, never an offset in the joined string. +type visualLinePart struct { + index int + text atspi.DocumentCaretText +} + +type visualLineReader struct { + DocumentCaretReader + cache map[visualLineKey]atspi.DocumentCaretText +} + +type visualLineKey struct { + object atspi.ObjectReference + offset int + unit atspi.DocumentCaretUnit +} + +func (reader *visualLineReader) ReadDocumentCaret(ctx context.Context, object atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + if err := ctx.Err(); err != nil { + return atspi.DocumentCaretText{}, err + } + key := visualLineKey{object, offset, unit} + if text, ok := reader.cache[key]; ok { + return text, nil + } + text, err := reader.DocumentCaretReader.ReadDocumentCaret(ctx, object, offset, unit) + if err == nil { + reader.cache[key] = text + } + return text, err +} + +func move_caret_line(ctx context.Context, source DocumentCaretReader, tree *atspi.AccessibleTree, doc atspi.DocumentSnapshot, place *documentPlace, indices []caretRange, lookup *caretRangeLookup, current int, command DocumentCaretCommand, owners map[int]atspi.ObjectID) (DocumentCaretMove, error) { + reader := &visualLineReader{DocumentCaretReader: source, cache: make(map[visualLineKey]atspi.DocumentCaretText)} + next := *place + // Move beyond the entire current line, even when character/word movement + // left the cursor in a middle fragment or structural navigation chose its + // heading container. The object-local mover still handles empty controls. + if command == CaretNextLine || command == CaretPreviousLine { + position := lookup.containing(indices, current, place.offset) + if place.origin == StructuralNavigation && lookup.after[current] < len(indices) && (position < 0 || lookup.after[current] < position) { + position = lookup.after[current] + } + if position >= 0 { + parts, err := collect_visual_line(ctx, reader, doc, indices, owners, position, place.offset, true) + if err != nil { + return DocumentCaretMove{}, err + } + if len(parts) > 1 { + part := parts[0] + if command == CaretNextLine { + part = parts[len(parts)-1] + } + next.object, next.offset, next.origin = doc.Nodes[part.index].Reference, part.text.Start, CaretNavigation + current = part.index + } + } + } + movement, err := move_caret_object_line(ctx, reader, doc, &next, indices, lookup, current, command) + if err != nil || !movement.Moved { + if err == nil { + movement.Position = documentPosition(doc, *place) + } + return movement, err + } + nextIndex, _ := doc.Index(next.object.ID()) + position := lookup.containing(indices, nextIndex, next.offset) + if position >= 0 { + parts, err := collect_visual_line(ctx, reader, doc, indices, owners, position, next.offset, command != CaretReadLine) + if err != nil { + return DocumentCaretMove{}, err + } + if len(parts) > 1 { + part := parts[0] + if command == CaretLineEnd || command == CaretDocumentEnd { + part = parts[len(parts)-1] + } + next.object, next.offset = doc.Nodes[part.index].Reference, part.text.Start + if command == CaretLineEnd || command == CaretDocumentEnd { + next.offset = part.text.End - 1 + } + movement.Start, movement.End = part.text.Start, part.text.End + line, raw, misspelled := assemble_visual_line(tree, doc, parts) + movement.Line, movement.RawText, movement.Misspelled = &line, raw, movement.Misspelled || misspelled + movement.Text = strings.Join(strings.Fields(movement.RawText), " ") + if command == CaretLineStart || command == CaretLineEnd { + character, err := reader.ReadDocumentCaret(ctx, next.object, next.offset, atspi.DocumentCaretCharacter) + if err != nil { + return DocumentCaretMove{}, err + } + movement.Text = character.Text + } + movement.Position = documentPosition(doc, next) + } + } + *place = next + return movement, nil +} + +// Retain semantic boundaries even if unrelated blocks have matching y values. +// Inline spans/emphasis do not introduce boundaries. Links remain independent +// stops with their existing activation, voice, state and sound presentation. +func visual_line_owners(nodes []atspi.DocumentNode) map[int]atspi.ObjectID { + owners := make(map[int]atspi.ObjectID, len(nodes)) + byID := make(map[atspi.ObjectID]atspi.ObjectID, len(nodes)) + for index, node := range nodes { + owner := byID[node.Parent] + snapshot := node.Snapshot + switch snapshot.Role { + case "paragraph", "heading", "list item", "table cell", "row header", "column header", "link", "document web", "document frame", "embedded": + owner = node.Reference.ID() + case "section": + if snapshot.HTMLTag != "span" { + owner = node.Reference.ID() + } + } + if snapshot.Editable || wholeCaretNode(snapshot) || snapshot.Role == "password text" || + snapshot.HTMLTag == "pre" || snapshot.HTMLTag == "code" || strings.Contains(" "+snapshot.XMLRoles+" ", " code ") { + // Exclude the whole subtree, including static code descendants. + owner = atspi.ObjectID{} + byID[node.Reference.ID()] = owner + owners[index] = owner + continue + } + // An excluded ancestor must stay excluded through nested blocks. + if parent, known := byID[node.Parent]; known && !parent.Valid() { + owner = atspi.ObjectID{} + } + byID[node.Reference.ID()] = owner + owners[index] = owner + } + return owners +} + +func collect_visual_line(ctx context.Context, reader DocumentCaretReader, doc atspi.DocumentSnapshot, indices []caretRange, owners map[int]atspi.ObjectID, position, offset int, left bool) ([]visualLinePart, error) { + index := indices[position].index + node := doc.Nodes[index] + if !owners[index].Valid() || node.Snapshot.Editable || wholeCaretNode(node.Snapshot) || node.Snapshot.CharacterCount <= 0 { + return nil, nil + } + unit := atspi.DocumentCaretLine + if !left { + unit = atspi.DocumentCaretLineRemainder + } + text, err := readCaretRange(ctx, reader, doc, indices[position], min(offset, indices[position].end-1), unit) + if errors.Is(err, atspi.ErrNoDocumentCaret) { + return nil, nil + } + if err != nil { + return nil, err + } + if !visual_line_text(text) { + return nil, nil + } + if !left && text.RawText != "" { + // Native remainder speech keeps the full raw line for indentation; + // assembly needs only the characters after the starting caret. + runes := []rune(text.RawText) + if length := text.End - text.Start; length < len(runes) { + text.RawText = string(runes[len(runes)-length:]) + } + } + parts := []visualLinePart{{index, text}} + characters := utf8.RuneCountInString(text.Text) + for _, direction := range []int{-1, 1} { + if direction < 0 && !left { + continue + } + for next := position + direction; next >= 0 && next < len(indices); next += direction { + candidate := indices[next].index + if owners[candidate] != owners[index] { + break + } + probe := indices[next].start + if direction < 0 { + probe = indices[next].end - 1 + } + piece, err := readCaretRange(ctx, reader, doc, indices[next], probe, atspi.DocumentCaretLine) + if errors.Is(err, atspi.ErrNoDocumentCaret) { + break + } + if err != nil { + return nil, err + } + if !visual_line_text(piece) || !visual_line_bounds(text.Bounds, piece.Bounds) { + break + } + // A fragment containing a hard newline ends the line, even when + // a provider reports identical/overlapping bounds for both rows. + previous, following := parts[len(parts)-1].text, piece + if direction < 0 { + previous, following = piece, parts[0].text + } + if strings.ContainsAny(previous.RawText, "\r\n") || strings.ContainsAny(previous.Text, "\r\n") || strings.HasPrefix(following.RawText, "\n") || strings.HasPrefix(following.Text, "\n") { + break + } + characters += utf8.RuneCountInString(piece.Text) + if len(parts) >= 256 || characters > 65536 { + return nil, errors.New("document visual line exceeds capture limit") + } + part := visualLinePart{candidate, piece} + if direction < 0 { + parts = append([]visualLinePart{part}, parts...) + } else { + parts = append(parts, part) + } + } + } + return parts, nil +} + +func visual_line_text(text atspi.DocumentCaretText) bool { + return text.Bounds.Valid() && text.Start >= 0 && text.End > text.Start && text.End <= text.CharacterCount && + !strings.ContainsRune(text.Text, '\ufffc') && (text.Text != "" || text.RawText != "") +} + +func visual_line_bounds(first, second atspi.Rectangle) bool { + if !first.Valid() || !second.Valid() { + return false + } + top := max(int64(first.Y), int64(second.Y)) + bottom := min(int64(first.Y)+int64(first.Height), int64(second.Y)+int64(second.Height)) + return bottom > top && math.Abs(float64(first.Y)+float64(first.Height)/2-float64(second.Y)-float64(second.Height)/2) <= 5 +} + +func visual_line_space(first, second atspi.DocumentCaretText) bool { + left, right := first.RawText, second.RawText + if left == "" { + left = first.Text + } + if right == "" { + right = second.Text + } + last, _ := utf8.DecodeLastRuneInString(left) + start, _ := utf8.DecodeRuneInString(right) + gap := max(int64(second.Bounds.X)-int64(first.Bounds.X)-int64(first.Bounds.Width), int64(first.Bounds.X)-int64(second.Bounds.X)-int64(second.Bounds.Width)) + return gap > 1 && !unicode.IsSpace(last) && !unicode.IsSpace(start) +} + +func assemble_visual_line(tree *atspi.AccessibleTree, doc atspi.DocumentSnapshot, parts []visualLinePart) (atspi.DocumentLine, string, bool) { + misspelled := false + line := atspi.DocumentLine{Document: doc.Context.TopLevel} + var raw strings.Builder + for i, part := range parts { + value := part.text.RawText + if value == "" { + value = part.text.Text + } + // Preserve native spacing and punctuation across span boundaries. + separator := "" + if i > 0 && visual_line_space(parts[i-1].text, part.text) { + separator = " " + } + raw.WriteString(separator) + raw.WriteString(value) + snapshot := doc.Nodes[part.index].Snapshot + if context, err := tree.DocumentContext(doc.Nodes[part.index].Reference); err == nil { + snapshot.BrailleContext = context.Ancestors + } + snapshot.Misspelled = part.text.Misspelled + misspelled = misspelled || part.text.Misspelled + line.Contents = append(line.Contents, atspi.DocumentContent{Reference: doc.Nodes[part.index].Reference, Snapshot: snapshot, + Start: part.text.Start, End: part.text.End, Text: part.text.Text, RawText: value, Separator: separator, Bounds: part.text.Bounds}) + } + return line, raw.String(), misspelled +} diff --git a/internal/review/document_visual_line_native_test.go b/internal/review/document_visual_line_native_test.go new file mode 100644 index 0000000..f1b1502 --- /dev/null +++ b/internal/review/document_visual_line_native_test.go @@ -0,0 +1,214 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestNativeBrowserFragmentLines(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + // Reach the textarea without enabling the browser's native caret mode. + if output, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", "Tab", "Tab").CombinedOutput(); err != nil { + t.Fatalf("focus: %v %s", err, output) + } + var focus atspi.ObjectID + for !focus.Valid() { + select { + case event := <-adapter.Events(): + if (event.Type == atspi.FocusEvent || event.Type == atspi.FocusedStateEvent && event.Detail1 == 1) && event.Source.Name == "Fragment probe focus" { + focus = event.Source.ID() + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + tree, err := adapter.CaptureDocument(ctx, focus) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(ctx, focus); err != nil { + t.Fatal(err) + } + reference, err := tree.Reference(focus) + if err != nil { + t.Fatal(err) + } + document, err := tree.Document(ctx, reference) + if err != nil { + t.Fatal(err) + } + glyphCount := 0 + for _, node := range document.Nodes { + if node.Snapshot.Role == "static" && node.Snapshot.Name == "\uf005" && node.Snapshot.CharacterCount == 1 { + glyphCount++ + } + } + if glyphCount < 5 { + t.Fatalf("fixture did not expose its star text objects: %d", glyphCount) + } + for _, step := range []struct { + command DocumentCaretCommand + want string + }{ + {CaretDocumentStart, "Fragmented response"}, + {CaretNextLine, "One two three."}, + {CaretNextLine, "Four five six."}, + {CaretPreviousLine, "One two three."}, + {CaretLineEnd, "."}, + {CaretNextLine, "Four five six."}, + {CaretNextLine, "Next paragraph."}, + {CaretNextLine, "Before"}, + {CaretNextLine, "ordinary link"}, + {CaretNextLine, "after."}, + {CaretNextLine, "Split heading"}, + {CaretNextLine, "Code first"}, + {CaretNextLine, ""}, // Preserve the provider's separate preformatted newline. + {CaretNextLine, "Code second"}, + {CaretNextLine, "Member rank"}, + {CaretNextLine, "Join Date"}, // Skip the five separate decorative stars. + {CaretPreviousLine, "Member rank"}, + {CaretNextLine, "Join Date"}, + } { + move, err := cursor.MoveCaret(ctx, adapter, step.command) + if err != nil || !move.Moved || strings.TrimSpace(move.Text) != step.want { + t.Fatalf("%s: %+v, %v; want %q", step.command, move, err, step.want) + } + } + control, err := cursor.MoveCaret(ctx, adapter, CaretNextLine) + if err != nil || !control.Moved || control.Position.Snapshot.Role != "push button" && control.Position.Snapshot.Role != "button" || control.Position.Snapshot.Name != "Rating details" { + t.Fatalf("labeled icon control: %+v, %v", control, err) + } + for _, want := range []string{"Mixed \uf005 text.", "★"} { + move, err := cursor.MoveCaret(ctx, adapter, CaretNextLine) + if err != nil || !move.Moved || strings.TrimSpace(move.Text) != want { + t.Fatalf("meaningful symbol: %+v, %v; want %q", move, err, want) + } + } + if _, err := cursor.MoveCaret(ctx, adapter, CaretDocumentStart); err != nil { + t.Fatal(err) + } + inline, err := cursor.MoveCaret(ctx, adapter, CaretNextLine) + if err != nil { + t.Fatal(err) + } + worker, err := NewWorker(adapter, 3*time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(focus) + worker.SetDocumentBrailleEnabled(true) + if inline.Line == nil || len(inline.Line.Contents) < 2 { + t.Fatalf("missing inline fragments: %+v", inline) + } + content := inline.Line.Contents[1] + displayRoute := &documentBrailleRequest{ctx: ctx, focus: focus, document: inline.Position.Document.ID(), target: content.Snapshot.ID(), + line: content.RawText, start: content.Start, offset: content.Start + 1, done: make(chan error, 1)} + routed := worker.route_document_braille(ctx, cursor, request{brailleRoute: displayRoute}) + if routed.Err != nil || !routed.Moved || routed.DocumentPosition.Offset != content.Start+1 || routed.DocumentCaretLine == nil || len(routed.DocumentCaretLine.Contents) < 2 { + t.Fatalf("native inline braille route = %+v", routed) + } + if err := <-displayRoute.done; err != nil { + t.Fatal(err) + } + worker.readDocumentBraille(ctx, routed) + // A mismatched displayed source must be rejected by the native owner. + ref, _ := tree.Reference(content.Snapshot.ID()) + if err := adapter.RouteBraille(ctx, atspi.BrailleRoute{Position: ref, Focus: focus, Line: "changed", Start: content.Start, Offset: content.Start}); err == nil { + t.Fatal("native routing accepted changed display text") + } + if _, err := cursor.MoveCaret(ctx, adapter, CaretDocumentStart); err != nil { + t.Fatal(err) + } + if _, err := cursor.MoveCaret(ctx, adapter, CaretNextLine); err != nil { + t.Fatal(err) + } + result := worker.readAll(ctx, cursor) + if result.Err != nil || len(result.ReadAllLines) < 3 { + t.Fatalf("Read All: %+v", result) + } + for index, want := range []string{"One two three.", "Four five six.", "Next paragraph."} { + if got := result.ReadAllLines[index].Contents[0].Text; got != want { + t.Fatalf("Read All line %d: %q, want %q", index, got, want) + } + } + rankFound := false + for index, line := range result.ReadAllLines { + if line.Contents[0].Text == "Member rank" { + rankFound = true + if index+1 >= len(result.ReadAllLines) || result.ReadAllLines[index+1].Contents[0].Text != "Join Date" { + t.Fatal("Read All stopped on decorative rank icons") + } + } + } + if !rankFound { + t.Fatal("Read All did not reach member rank") + } + var editableLines []string + for _, line := range result.ReadAllLines { + text := strings.TrimSpace(line.Contents[0].Text) + if text == "Review the code." || text == "Report actionable issues." || text == "After the suggestion." { + editableLines = append(editableLines, text) + } + } + if strings.Join(editableLines, "|") != "Review the code.|Report actionable issues.|After the suggestion." { + t.Fatalf("Read All skipped or duplicated embedded editor text: %q", editableLines) + } + // Fragmented headings must also hand Down to following content as a unit. + if _, err := cursor.MoveCaret(ctx, adapter, CaretDocumentStart); err != nil { + t.Fatal(err) + } + move, err := cursor.Move(ctx, DocumentHeading, 2, false) + if err != nil || !move.Moved { + t.Fatalf("heading: %+v, %v", move, err) + } + next, err := cursor.MoveCaret(ctx, adapter, CaretNextLine) + if err != nil || next.Text != "Code first" { + t.Fatalf("Down after split heading: %+v, %v", next, err) + } + move, err = cursor.Move(ctx, DocumentHeading, 2, false) + if err != nil || !move.Moved || move.Position.Snapshot.Name != "Embedded suggestion" { + t.Fatalf("editor heading: %q, %v", move.Position.Snapshot.Name, err) + } + for _, step := range []struct { + command DocumentCaretCommand + want string + }{ + {CaretNextLine, ""}, // Stop on the editor control before entering its text. + {CaretNextLine, "Review the code."}, + {CaretNextLine, "Report actionable issues."}, + {CaretNextLine, "After the suggestion."}, + {CaretPreviousLine, "Report actionable issues."}, + {CaretPreviousLine, "Review the code."}, + {CaretNextCharacter, "e"}, + {CaretNextWord, "Review"}, + } { + movement, err := cursor.MoveCaret(ctx, adapter, step.command) + if err != nil || !movement.Moved || strings.TrimSpace(movement.Text) != step.want { + t.Fatalf("embedded editor %s: %q (%s, %s, count %d), moved %t, %v; want %q", step.command, movement.Text, + movement.Position.Snapshot.Role, movement.Position.Snapshot.Path, movement.Position.Snapshot.CharacterCount, movement.Moved, err, step.want) + } + } +} diff --git a/internal/review/document_visual_line_test.go b/internal/review/document_visual_line_test.go new file mode 100644 index 0000000..5cb4bd5 --- /dev/null +++ b/internal/review/document_visual_line_test.go @@ -0,0 +1,260 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "reflect" + "strings" + "testing" + "time" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type fragmentTextReader struct { + caretTextReader + bounds map[atspi.ObjectID]atspi.Rectangle + err error +} + +func (reader fragmentTextReader) ReadDocumentCaret(ctx context.Context, ref atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + if reader.err != nil { + return atspi.DocumentCaretText{}, reader.err + } + text, err := reader.caretTextReader.ReadDocumentCaret(ctx, ref, offset, unit) + text.RawText, text.Bounds = text.Text, reader.bounds[ref.ID()] + return text, err +} + +func fragment_cursor(t *testing.T, boundary string) (*DocumentCursor, fragmentTextReader) { + t.Helper() + reader := fragmentTextReader{caretTextReader: caretTextReader{ + webID("/one"): "One ", webID("/two"): "two.", webID("/three"): "Three ", webID("/four"): "four.", webID("/after"): "Next paragraph", + }, bounds: make(map[atspi.ObjectID]atspi.Rectangle)} + for _, row := range []struct { + path string + x, y int32 + }{{"/one", 0, 10}, {"/two", 40, 10}, {"/three", 0, 30}, {"/four", 50, 30}, {"/after", 100, 30}} { + reader.bounds[webID(row.path)] = atspi.Rectangle{X: row.x, Y: row.y, Width: 30, Height: 18} + } + node := func(path, role string, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, "", role, "", "") + snapshot.BusName, snapshot.CharacterCount = webID(path).BusName, utf8.RuneCountInString(reader.caretTextReader[webID(path)]) + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + block := node("/paragraph", boundary, "/one", "/span", "/three", "/four") + span := node("/span", "section", "/two") + span.Snapshot.HTMLTag = "span" + if boundary == "pre" || boundary == "code" { + block.Snapshot.HTMLTag = boundary + } + if boundary == "entry" { + block.Snapshot.Editable = true + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "document web", "/paragraph", "/next"), block, + node("/one", "static"), span, node("/two", "static"), + node("/three", "static"), node("/four", "static"), node("/next", "paragraph", "/after"), node("/after", "static"), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(context.Background(), webID("/one")); err != nil { + t.Fatal(err) + } + return cursor, reader +} + +func TestDocumentFragmentLines(t *testing.T) { + cursor, reader := fragment_cursor(t, "paragraph") + ctx := context.Background() + for _, step := range []struct { + command DocumentCaretCommand + path, text string + offset int + }{ + {CaretDocumentStart, "/one", "One two.", 0}, + {CaretNextCharacter, "/one", "n", 1}, + {CaretNextLine, "/three", "Three four.", 0}, + {CaretPreviousLine, "/one", "One two.", 0}, + {CaretLineEnd, "/two", ".", 3}, + {CaretLineStart, "/one", "O", 0}, + {CaretNextLine, "/three", "Three four.", 0}, + {CaretNextLine, "/after", "Next paragraph", 0}, + {CaretPreviousLine, "/three", "Three four.", 0}, + } { + move, err := cursor.MoveCaret(ctx, reader, step.command) + if err != nil || !move.Moved || move.Text != step.text || move.Position.Object.ID() != webID(step.path) || move.Position.Offset != step.offset { + t.Fatalf("%s: %+v, %v; want %s:%d %q", step.command, move, err, step.path, step.offset, step.text) + } + if move.End > 0 && move.End > move.Position.Snapshot.CharacterCount { + t.Fatal("joined offset escaped native object") + } + } +} + +func TestDocumentFragmentSpacingAndPunctuation(t *testing.T) { + for _, test := range []struct { + first, second, want string + x int32 + }{ + {"One ", "two.", "One two.", 40}, + {"One", "two.", "One two.", 40}, + {"Hello", ",", "Hello,", 30}, + } { + cursor, reader := fragment_cursor(t, "paragraph") + reader.caretTextReader[webID("/one")] = test.first + reader.caretTextReader[webID("/two")] = test.second + bounds := reader.bounds[webID("/two")] + bounds.X = test.x + reader.bounds[webID("/two")] = bounds + // Range lengths come from the provider, just as in a native capture. + doc, _ := cursor.tree.Document(context.Background(), cursor.places[0].object) + var nodes []atspi.TreeNode + for _, node := range doc.Nodes { + if text, ok := reader.caretTextReader[node.Reference.ID()]; ok { + node.Snapshot.CharacterCount = utf8.RuneCountInString(text) + } + nodes = append(nodes, atspi.TreeNode{Snapshot: node.Snapshot, Children: node.Children}) + } + if err := cursor.tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + move, err := cursor.MoveCaret(context.Background(), reader, CaretDocumentStart) + if err != nil || move.Text != test.want { + t.Fatalf("fragments %q/%q: %+v, %v; want %q", test.first, test.second, move, err, test.want) + } + } +} + +type fragmentReadAllCapturer struct { + *readAllCapturer + fragmentTextReader +} + +func (capturer *fragmentReadAllCapturer) ReadDocumentCaret(ctx context.Context, ref atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + return capturer.fragmentTextReader.ReadDocumentCaret(ctx, ref, offset, unit) +} + +func TestReadAllFragmentLinesAndRemainder(t *testing.T) { + cursor, reader := fragment_cursor(t, "paragraph") + ctx := context.Background() + if _, err := cursor.MoveCaret(ctx, reader, CaretNextCharacter); err != nil { + t.Fatal(err) + } + capturer := &fragmentReadAllCapturer{readAllCapturer: &readAllCapturer{tree: cursor.tree}, fragmentTextReader: reader} + worker, _ := NewWorker(capturer, time.Second) + worker.SyncFocus(webID("/one")) + result := worker.readAll(ctx, cursor) + if result.Err != nil || len(result.ReadAllLines) != 3 { + t.Fatalf("read all: %+v", result) + } + for index, want := range []string{"ne two.", "Three four.", "Next paragraph"} { + if got := result.ReadAllLines[index].Contents[0].Text; got != want { + t.Fatalf("line %d: %q, want %q", index, got, want) + } + } + if cursor.places[0].offset != 1 { + t.Fatal("assembly moved the user's cursor") + } + result.ReadAllProgress(1) + request := <-worker.requests + followed, ok := worker.followReadAll(ctx, cursor, request) + if !ok { + t.Fatal("progress lost ownership") + } + move, err := followed.MoveCaret(ctx, reader, CaretNextLine) + if err != nil || move.Text != "Next paragraph" { + t.Fatalf("Down after progress: %+v, %v", move, err) + } +} + +func TestDocumentFragmentBoundaries(t *testing.T) { + for _, boundary := range []string{"heading", "link", "table cell", "pre", "code", "entry"} { + t.Run(boundary, func(t *testing.T) { + cursor, reader := fragment_cursor(t, boundary) + move, err := cursor.MoveCaret(context.Background(), reader, CaretDocumentStart) + want := "One two." + if boundary == "pre" || boundary == "code" || boundary == "entry" { + want = "One " + } + if boundary == "entry" { + want = "" + } + if err != nil || move.Text != want { + t.Fatalf("%s: %+v, %v; want %q", boundary, move, err, want) + } + }) + } +} + +func TestDocumentFragmentErrorsDoNotMoveCursor(t *testing.T) { + for _, failure := range []error{context.Canceled, atspi.ErrStaleObject} { + cursor, reader := fragment_cursor(t, "paragraph") + reader.err = failure + before := cursor.places[0] + _, err := cursor.MoveCaret(context.Background(), reader, CaretNextLine) + if !errors.Is(err, failure) || !reflect.DeepEqual(cursor.places[0], before) { + t.Fatalf("error %v: %v; changed cursor", failure, err) + } + } +} + +type wrappedFragmentReader struct{ fragmentTextReader } + +func (reader wrappedFragmentReader) ReadDocumentCaret(ctx context.Context, ref atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + text, err := reader.fragmentTextReader.ReadDocumentCaret(ctx, ref, offset, unit) + if ref.ID() == webID("/one") && offset >= 6 { + text.Bounds.Y = 30 + } + return text, err +} + +func TestDocumentFragmentLineAcrossWrappedObject(t *testing.T) { + cursor, base := fragment_cursor(t, "paragraph") + base.caretTextReader[webID("/one")] = "First\nSecond " + base.bounds[webID("/two")] = atspi.Rectangle{X: 60, Y: 30, Width: 30, Height: 18} + base.bounds[webID("/three")] = atspi.Rectangle{X: 0, Y: 50, Width: 30, Height: 18} + base.bounds[webID("/four")] = atspi.Rectangle{X: 50, Y: 50, Width: 30, Height: 18} + ref, _ := cursor.tree.Reference(webID("/one")) + doc, err := cursor.tree.Document(context.Background(), ref) + if err != nil { + t.Fatal(err) + } + nodes := make([]atspi.TreeNode, 0, len(doc.Nodes)) + for _, node := range doc.Nodes { + if node.Reference == ref { + node.Snapshot.CharacterCount = utf8.RuneCountInString(base.caretTextReader[webID("/one")]) + } + nodes = append(nodes, atspi.TreeNode{Snapshot: node.Snapshot, Children: node.Children}) + } + if err := cursor.tree.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + reader := wrappedFragmentReader{base} + for _, step := range []struct { + command DocumentCaretCommand + want string + }{ + {CaretDocumentStart, "First"}, {CaretNextLine, "Second two."}, + {CaretPreviousLine, "First"}, {CaretNextLine, "Second two."}, {CaretNextLine, "Three four."}, + } { + move, err := cursor.MoveCaret(context.Background(), reader, step.command) + if err != nil || strings.TrimSpace(move.Text) != step.want { + t.Fatalf("%s: %+v, %v; want %q", step.command, move, err, step.want) + } + } +} diff --git a/internal/review/document_word_spaces_test.go b/internal/review/document_word_spaces_test.go new file mode 100644 index 0000000..6ec9439 --- /dev/null +++ b/internal/review/document_word_spaces_test.go @@ -0,0 +1,78 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type blockCaretReader struct { + caretTextReader + calls, blocks int + malformed bool +} + +func (reader *blockCaretReader) ReadDocumentCaret(ctx context.Context, object atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + reader.calls++ + return reader.caretTextReader.ReadDocumentCaret(ctx, object, offset, unit) +} + +func (reader *blockCaretReader) ReadDocumentCharacters(_ context.Context, object atspi.ObjectReference, offset int) (atspi.DocumentCaretText, error) { + reader.calls++ + reader.blocks++ + runes := []rune(reader.caretTextReader[object.ID()]) + start := offset / 128 * 128 + end := min(len(runes), start+128) + raw := string(runes[start:end]) + if reader.malformed { + raw = "" + } + return atspi.DocumentCaretText{Start: start, End: end, RawText: raw, CharacterCount: len(runes)}, nil +} + +func TestDocumentWordSpacesUseBoundedBlocks(t *testing.T) { + values := caretTextReader{webID("/text"): "A" + strings.Repeat(" \t\n\u2003", 250) + "猫"} + cursor := newCaretTextCursor(t, values) + reader := &blockCaretReader{caretTextReader: values} + for _, step := range []struct { + command DocumentCaretCommand + text string + }{{CaretNextWord, "猫"}, {CaretPreviousWord, "猫"}, {CaretPreviousWord, "A \t\n\u2003"}} { + move, err := cursor.MoveCaret(context.Background(), reader, step.command) + // Native word providers include varying trailing whitespace. Retain + // their text and verify the actual requested word and Unicode offset. + if err != nil || !strings.HasPrefix(move.Text, strings.TrimSpace(step.text)) { + t.Fatalf("%s: %+v error=%v", step.command, move, err) + } + } + t.Logf("three word commands across 1000 whitespace characters: %d reads, %d blocks", reader.calls, reader.blocks) + if reader.blocks == 0 || reader.calls > 50 { + t.Fatalf("word traversal used %d reads (%d blocks)", reader.calls, reader.blocks) + } +} + +func TestDocumentCharacterMovementDoesNotReadBlocks(t *testing.T) { + values := caretTextReader{webID("/text"): "A B"} + cursor := newCaretTextCursor(t, values) + reader := &blockCaretReader{caretTextReader: values} + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextCharacter) + if err != nil || move.Text != " " || reader.blocks != 0 || reader.calls != 1 { + t.Fatalf("move=%+v error=%v calls=%d blocks=%d", move, err, reader.calls, reader.blocks) + } +} + +func TestDocumentWordMalformedBlockCannotSkipText(t *testing.T) { + values := caretTextReader{webID("/text"): "A B"} + cursor := newCaretTextCursor(t, values) + reader := &blockCaretReader{caretTextReader: values, malformed: true} + move, err := cursor.MoveCaret(context.Background(), reader, CaretNextWord) + if err != nil || move.Text != "B" || move.Position.Offset != 4 { + t.Fatalf("move=%+v error=%v", move, err) + } +} diff --git a/internal/review/document_worker.go b/internal/review/document_worker.go new file mode 100644 index 0000000..c19b6bb --- /dev/null +++ b/internal/review/document_worker.go @@ -0,0 +1,608 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// MoveDocument shares the bounded review FIFO, but owns an independent cursor. +func (worker *Worker) MoveDocument(target DocumentTarget, level int, backwards bool) error { + if !validDocumentTarget(target) || level < 0 || level > 6 || target != DocumentHeading && level != 0 { + return ErrInvalidDirection + } + select { + case worker.requests <- request{documentEpoch: worker.documentEpoch.Load(), target: target, backwards: backwards, level: level, queuedAt: time.Now()}: + return nil + default: + return ErrRequestQueueFull + } +} + +func (worker *Worker) moveDocument(ctx context.Context, cursor *DocumentCursor, target DocumentTarget, level int, backwards bool, epoch uint64) (Result, *DocumentCursor) { + result := Result{DocumentEpoch: epoch, DocumentTarget: target, DocumentBackwards: backwards, DocumentLevel: level, DocumentFocus: worker.focus()} + if !result.DocumentFocus.Valid() { + result.Err = ErrNoCurrent + return result, cursor + } + move := func() (moveErr error) { + attempt := DocumentAttempt{Focus: result.DocumentFocus, Before: cursor.diagnostic_state(), Stage: "focus"} + defer func() { result.record_document_attempt(cursor, attempt, moveErr) }() + if cursor == nil { + attempt.Recovery = "no-cursor" + return ErrNoCurrent + } + _, recovery, err := cursor.sync_focus(ctx, result.DocumentFocus) + attempt.Recovery, attempt.Synced = recovery, cursor.diagnostic_state() + if err != nil { + return err + } + attempt.Stage = "move" + move, err := cursor.Move(ctx, target, level, backwards) + result.DocumentPosition = move.Position + result.Moved = move.Moved + result.DocumentWrapped = move.Wrapped + return err + } + result.Err = move() + if !documentNeedsCapture(result.Err) { + return worker.placeDocumentWithRetry(ctx, cursor, result), cursor + } + // A bounded refresh plus one retry handles a second replacement without + // allowing a constantly mutating page to loop indefinitely. + result.CaptureReason = result.Err + result.DocumentDiagnostics.CaptureAttempts++ + captureContext, cancel := context.WithTimeout(ctx, worker.documentCaptureTimeout) + captureStarted := time.Now() + tree, err := worker.capturer.CaptureDocument(captureContext, result.DocumentFocus) + result.CaptureDuration = time.Since(captureStarted) + cancel() + if err != nil { + result.Err = err + return result, cursor + } + if tree == nil { + result.Err = errors.New("capture document tree: nil tree") + return result, cursor + } + recovered := worker.recoverCapturedDocumentFocus(cursor, tree, &result) + if cursor == nil || cursor.tree != tree { + result.DocumentDiagnostics.CursorRecreated = true + cursor, _ = NewDocumentCursor(tree) + } + if !recovered { + result.DocumentFocus = worker.focus() + } + result.Err = move() + if !result.Moved && documentNeedsCapture(result.Err) && + worker.CurrentDocumentResult(result) && worker.focus() == result.DocumentFocus { + // A second replacement can race the first capture. Retry once while + // the navigation has not moved, so the heading is not skipped. + result.DocumentDiagnostics.CaptureAttempts++ + retryContext, retryCancel := context.WithTimeout(ctx, worker.documentCaptureTimeout) + retryStarted := time.Now() + tree, err = worker.capturer.CaptureDocument(retryContext, result.DocumentFocus) + result.CaptureDuration += time.Since(retryStarted) + retryCancel() + if err == nil && tree != nil && worker.CurrentDocumentResult(result) && worker.focus() == result.DocumentFocus { + if cursor == nil || cursor.tree != tree { + result.DocumentDiagnostics.CursorRecreated = true + cursor, _ = NewDocumentCursor(tree) + } + result.Err = move() + } + } + return worker.placeDocumentWithRetry(ctx, cursor, result), cursor +} + +func (worker *Worker) jumpDocumentFragment(ctx context.Context, cursor *DocumentCursor, fragment string, epoch uint64) (Result, *DocumentCursor) { + result := Result{DocumentEpoch: epoch, DocumentFragment: true, DocumentFocus: worker.focus()} + if !result.DocumentFocus.Valid() { + result.Err = ErrNoCurrent + return result, cursor + } + captureContext, cancel := context.WithTimeout(ctx, worker.documentCaptureTimeout) + captureStarted := time.Now() + tree, err := worker.capturer.CaptureDocument(captureContext, result.DocumentFocus) + result.CaptureDuration = time.Since(captureStarted) + cancel() + if err != nil { + result.Err = err + return result, cursor + } + if tree == nil { + result.Err = errors.New("capture document tree: nil tree") + return result, cursor + } + cursor, err = NewDocumentCursor(tree) + if err != nil { + result.Err = err + return result, cursor + } + if _, err = cursor.SyncFocus(ctx, result.DocumentFocus); err != nil { + result.Err = err + return result, cursor + } + result.DocumentPosition, result.Moved, result.Err = cursor.JumpToFragment(ctx, fragment) + if result.Err == nil && result.Moved && worker.CurrentDocumentResult(result) && worker.focus() == result.DocumentFocus { + result = worker.placeDocumentWithRetry(ctx, cursor, result) + } + return result, cursor +} + +func (worker *Worker) placeDocumentWithRetry(ctx context.Context, cursor *DocumentCursor, result Result) Result { + place := func(result Result) Result { + if result.DocumentCaretCommand != 0 { + return worker.placeDocumentCaret(ctx, result) + } + return worker.placeDocument(ctx, cursor, result) + } + result = place(result) + if errors.Is(result.CaretErr, atspi.ErrDeadObject) { + // A native caret refusal can leave a valid virtual position. A provider + // confirming that the target no longer exists cannot: do not announce + // its cached label as a successful move, even if recapture fails. + result.Err, result.Moved = result.CaretErr, false + } + if !documentCaretNeedsRecapture(result.CaretErr) || !worker.CurrentDocumentResult(result) { + return result + } + // A semantic event can retire the captured tree between selecting a target + // and placing its native caret. Retry only the same target after one fresh + // capture; repeating the navigation command could skip to another target. + oldPosition := result.DocumentPosition + result.DocumentDiagnostics.CaptureAttempts++ + captureContext, cancel := context.WithTimeout(ctx, worker.documentCaptureTimeout) + captureStarted := time.Now() + tree, err := worker.capturer.CaptureDocument(captureContext, result.DocumentFocus) + result.CaptureDuration += time.Since(captureStarted) + cancel() + if err != nil || tree == nil || !worker.CurrentDocumentResult(result) { + return result + } + target, err := tree.Reference(oldPosition.Object.ID()) + if err != nil { + return result + } + owner, err := tree.DocumentContext(target) + if err != nil || owner.TopLevel.ID() != oldPosition.Document.ID() { + return result + } + snapshot, err := tree.Resolve(target) + if err != nil || snapshot.Role != oldPosition.Snapshot.Role || snapshot.HeadingLevel != oldPosition.Snapshot.HeadingLevel { + return result + } + result.DocumentPosition.Object = target + result.DocumentPosition.Document = owner.TopLevel + result.DocumentPosition.Snapshot = snapshot + result.Err, result.Moved = nil, true + result.CaretErr = nil + result = place(result) + if errors.Is(result.CaretErr, atspi.ErrDeadObject) { + result.Err, result.Moved = result.CaretErr, false + } + if result.Err == nil && result.CaretErr == nil && cursor != nil { + cursor.rebindPlace(tree, oldPosition, result.DocumentPosition) + } + return result +} + +func documentCaretNeedsRecapture(err error) bool { + return errors.Is(err, atspi.ErrObjectNotFound) || errors.Is(err, atspi.ErrStaleObject) || + errors.Is(err, atspi.ErrStaleSnapshot) || errors.Is(err, atspi.ErrDeadObject) +} + +func (worker *Worker) moveDocumentCaret(ctx context.Context, cursor *DocumentCursor, command DocumentCaretCommand, epoch uint64) (Result, *DocumentCursor) { + result := Result{DocumentEpoch: epoch, DocumentCaretCommand: command, DocumentFocus: worker.focus()} + if !result.DocumentFocus.Valid() { + result.Err = ErrNoCurrent + return result, cursor + } + reader, ok := worker.nativeCapturerFor(result.DocumentFocus).(DocumentCaretReader) + if !ok { + result.Err = errors.New("document caret reader unavailable") + return result, cursor + } + move := func() (moveErr error) { + attempt := DocumentAttempt{Focus: result.DocumentFocus, Before: cursor.diagnostic_state(), Stage: "focus"} + defer func() { result.record_document_attempt(cursor, attempt, moveErr) }() + if cursor == nil { + attempt.Recovery = "no-cursor" + return ErrNoCurrent + } + _, recovery, err := cursor.sync_focus(ctx, result.DocumentFocus) + attempt.Recovery, attempt.Synced = recovery, cursor.diagnostic_state() + if err != nil { + return err + } + attempt.Stage = "move" + // A word move can cross whitespace and several objects. Bound the + // whole navigation, not just each individual native text request. + navigationContext, cancel := context.WithTimeout(ctx, worker.captureTimeout) + defer cancel() + movement, err := cursor.MoveCaret(navigationContext, reader, command) + result.DocumentPosition = movement.Position + result.DocumentCaretText = movement.Text + result.DocumentCaretRawText = movement.RawText + result.DocumentCaretLine = movement.Line + result.DocumentTablePrefix, result.DocumentTableSuffix = movement.TablePrefix, movement.TableSuffix + result.DocumentTableRowHeader, result.DocumentTableColumnHeader = movement.TableRowHeader, movement.TableColumnHeader + result.DocumentPosition.Snapshot.Misspelled = movement.Misspelled + result.DocumentCaretStart, result.DocumentCaretEnd = movement.Start, movement.End + result.Moved = movement.Moved + if err == nil && movement.Moved { + context, contextErr := cursor.tree.DocumentContext(movement.Position.Object) + if contextErr != nil { + // ChatGPT can replace a text object between the successful + // caret read and this optional ancestor lookup. The captured + // position and text remain usable; retrying the command here + // would advance past the line the user requested. + if !errors.Is(contextErr, atspi.ErrStaleObject) && !errors.Is(contextErr, atspi.ErrObjectNotFound) && !errors.Is(contextErr, atspi.ErrStaleSnapshot) { + return contextErr + } + return nil + } + result.DocumentCaretContext = context.Ancestors + } + return err + } + result.Err = move() + if !documentNeedsCapture(result.Err) { + return worker.placeDocumentWithRetry(ctx, cursor, result), cursor + } + result.CaptureReason = result.Err + result.DocumentDiagnostics.CaptureAttempts++ + captureContext, cancel := context.WithTimeout(ctx, worker.documentCaptureTimeout) + captureStarted := time.Now() + tree, err := worker.capturer.CaptureDocument(captureContext, result.DocumentFocus) + result.CaptureDuration = time.Since(captureStarted) + cancel() + if err != nil { + result.Err = err + return result, cursor + } + if tree == nil { + result.Err = errors.New("capture document tree: nil tree") + return result, cursor + } + recovered := worker.recoverCapturedDocumentFocus(cursor, tree, &result) + if cursor == nil || cursor.tree != tree { + result.DocumentDiagnostics.CursorRecreated = true + cursor, _ = NewDocumentCursor(tree) + } + if !recovered { + result.DocumentFocus = worker.focus() + } + result.Err = move() + if result.Moved || !documentNeedsCapture(result.Err) || + !worker.CurrentDocumentResult(result) || worker.focus() != result.DocumentFocus { + return worker.placeDocumentWithRetry(ctx, cursor, result), cursor + } + // A dynamic page can replace the captured target between recapture and + // SyncFocus. Retry once only if the first attempt did not move the caret. + result.DocumentDiagnostics.CaptureAttempts++ + retryContext, retryCancel := context.WithTimeout(ctx, worker.documentCaptureTimeout) + retryStarted := time.Now() + tree, err = worker.capturer.CaptureDocument(retryContext, result.DocumentFocus) + result.CaptureDuration += time.Since(retryStarted) + retryCancel() + if err != nil || tree == nil || !worker.CurrentDocumentResult(result) || worker.focus() != result.DocumentFocus { + return result, cursor + } + if cursor == nil || cursor.tree != tree { + result.DocumentDiagnostics.CursorRecreated = true + cursor, _ = NewDocumentCursor(tree) + } + result.Err = move() + return worker.placeDocumentWithRetry(ctx, cursor, result), cursor +} + +func (worker *Worker) placeDocumentCaret(ctx context.Context, result Result) Result { + if result.Err != nil || !result.Moved || + !worker.CurrentDocumentResult(result) || worker.focus() != result.DocumentFocus { + return result + } + if result.DocumentCaretCommand == CaretReadLine { + return result + } + navigator, ok := worker.nativeCapturerFor(result.DocumentFocus).(interface { + SetDocumentCaretPosition(context.Context, atspi.ObjectReference, atspi.ObjectID, int) error + }) + if !ok { + return result + } + deadline, cancel := context.WithTimeout(ctx, worker.captureTimeout) + defer cancel() + nativeOffset := result.DocumentPosition.Offset + if named_link_label(result.DocumentPosition.Snapshot) != "" { + // The label's review offset has no relationship to the native badge + // or embedded-object text. Place only the link's native anchor. + nativeOffset = 0 + } + result.CaretErr = navigator.SetDocumentCaretPosition(deadline, result.DocumentPosition.Object, result.DocumentFocus, nativeOffset) + return result +} + +func (worker *Worker) activateDocumentCaret(ctx context.Context, cursor *DocumentCursor, epoch uint64) (Result, *DocumentCursor) { + result := Result{DocumentEpoch: epoch, DocumentActivate: true, DocumentFocus: worker.focus()} + if !result.DocumentFocus.Valid() { + result.Err = ErrNoCurrent + return result, cursor + } + target := atspi.ObjectReference{} + resolve := func() error { + if cursor == nil { + return ErrNoCurrent + } + if _, err := cursor.syncActionFocus(ctx, result.DocumentFocus); err != nil { + return err + } + var err error + target, err = cursor.ActivationTarget() + return err + } + result.Err = resolve() + if documentNeedsCapture(result.Err) { + cursor, result.Err = worker.refreshDocumentCursor(ctx, cursor, result.DocumentFocus) + if result.Err == nil { + result.Err = resolve() + } + } + if result.Err != nil { + return result, cursor + } + activator, ok := worker.nativeCapturerFor(result.DocumentFocus).(interface { + ActivateDocumentObject(context.Context, atspi.ObjectReference, atspi.ObjectID) error + }) + if !ok { + result.Err = errors.New("document activation unavailable") + return result, cursor + } + actionContext, cancel := context.WithTimeout(ctx, worker.captureTimeout) + defer cancel() + if !worker.CurrentDocumentResult(result) || worker.focus() != result.DocumentFocus { + result.Err = atspi.ErrStaleObject + return result, cursor + } + result.Err = activator.ActivateDocumentObject(actionContext, target, result.DocumentFocus) + if errors.Is(result.Err, atspi.ErrStaleObject) && worker.CurrentDocumentResult(result) && worker.focus() == result.DocumentFocus { + // ErrStaleObject is a failed preflight, before any native action ran. + // Refresh once, and retry only the identical target, never a new link. + originalTarget := target.ID() + cursor, result.Err = worker.refreshDocumentCursor(ctx, cursor, result.DocumentFocus) + if result.Err == nil { + result.Err = resolve() + } + if result.Err == nil && (target.ID() != originalTarget || !worker.CurrentDocumentResult(result) || worker.focus() != result.DocumentFocus) { + result.Err = atspi.ErrStaleObject + } + if result.Err == nil { + retryContext, retryCancel := context.WithTimeout(ctx, worker.captureTimeout) + defer retryCancel() + result.Err = activator.ActivateDocumentObject(retryContext, target, result.DocumentFocus) + } + } + return result, cursor +} + +// Navigation can recover by returning to native focus; an action cannot. Check +// the saved target first, before SyncFocus has a chance to replace a stale place. +func (cursor *DocumentCursor) syncActionFocus(ctx context.Context, focus atspi.ObjectID) (DocumentPosition, error) { + if len(cursor.places) > 0 { + saved := cursor.places[len(cursor.places)-1] + if saved.focus.ID() == focus || saved.object.ID() == focus { + if _, err := cursor.tree.Resolve(saved.object); err != nil { + return DocumentPosition{}, err + } + } + } + return cursor.SyncFocus(ctx, focus) +} + +// Refresh before an action, retaining the virtual position only within the same +// document and focus. Never substitute another link if the selected one vanished. +func (worker *Worker) refreshDocumentCursor(ctx context.Context, cursor *DocumentCursor, focus atspi.ObjectID) (*DocumentCursor, error) { + return worker.refresh_document_cursor(ctx, cursor, focus, false) +} + +// Read All is navigation: a missing text child can recover within the same +// captured tree using its generation-checked parent and sibling boundaries. +// Activation keeps the stricter refreshDocumentCursor path above. +func (worker *Worker) refresh_read_all_cursor(ctx context.Context, cursor *DocumentCursor, focus atspi.ObjectID) (*DocumentCursor, error) { + return worker.refresh_document_cursor(ctx, cursor, focus, true) +} + +func (worker *Worker) refresh_document_cursor(ctx context.Context, cursor *DocumentCursor, focus atspi.ObjectID, recoverNavigation bool) (*DocumentCursor, error) { + var saved documentPlace + if cursor != nil && len(cursor.places) > 0 { + saved = cursor.places[len(cursor.places)-1] + } + captureContext, cancel := context.WithTimeout(ctx, worker.documentCaptureTimeout) + defer cancel() + tree, err := worker.capturer.CaptureDocument(captureContext, focus) + if err != nil { + return cursor, err + } + if recoverNavigation && cursor != nil && cursor.tree == tree { + position, err := cursor.SyncFocus(ctx, focus) + if err == nil && saved.document.Valid() && (saved.focus.ID() == focus || saved.object.ID() == focus) && saved.document != position.Document { + return cursor, errors.New("read all: document changed") + } + return cursor, err + } + fresh, err := NewDocumentCursor(tree) + if err != nil { + return cursor, err + } + position, err := fresh.SyncFocus(ctx, focus) + if err != nil { + return cursor, err + } + if saved.document.Valid() && (saved.focus.ID() == focus || saved.object.ID() == focus) { + if saved.document.ID() != position.Document.ID() || + cursor.tree == tree && saved.document != position.Document { + return cursor, atspi.ErrStaleObject + } + target, err := tree.Reference(saved.object.ID()) + if err != nil { + return cursor, err + } + owner, err := tree.DocumentContext(target) + if err != nil || owner.TopLevel != position.Document { + return cursor, atspi.ErrStaleObject + } + place := &fresh.places[len(fresh.places)-1] + place.object, place.offset, place.origin = target, saved.offset, saved.origin + } + return fresh, nil +} + +func (worker *Worker) recoverCapturedDocumentFocus(cursor *DocumentCursor, tree *atspi.AccessibleTree, result *Result) bool { + if cursor == nil || len(cursor.places) == 0 { + return false + } + // The capture reason describes the old tree. Even a text or geometry + // refresh can discover a focus object removed while capture was pending. + // The fresh tree and unchanged document/focus ownership decide recovery. + if _, err := tree.Reference(result.DocumentFocus); !errors.Is(err, atspi.ErrObjectNotFound) { + return false + } + root, err := tree.Root() + if err != nil || root.ID() != cursor.places[len(cursor.places)-1].document.ID() || root.ID().BusName != result.DocumentFocus.BusName { + return false + } + if !worker.recoverDocumentFocus(result.DocumentFocus, root.ID(), result.DocumentEpoch) { + return false + } + // Losing the native anchor does not invalidate a virtual position elsewhere + // in the same generation. Rebind only the anchor so SyncFocus can retain + // the selected text or recover its surviving parent after this capture. + if cursor.tree == tree { + cursor.mu.Lock() + place := &cursor.places[len(cursor.places)-1] + if place.document == root && place.focus.ID() == result.DocumentFocus { + place.focus = root + } + cursor.mu.Unlock() + } + result.DocumentFocus = root.ID() + result.DocumentDiagnostics.FocusRecovered = true + return true +} + +func documentNeedsCapture(err error) bool { + return errors.Is(err, ErrNoCurrent) || errors.Is(err, atspi.ErrObjectNotFound) || + errors.Is(err, atspi.ErrStaleObject) || errors.Is(err, atspi.ErrDeadObject) || errors.Is(err, atspi.ErrIncompleteTree) || + errors.Is(err, atspi.ErrStaleText) || errors.Is(err, atspi.ErrStaleGeometry) || errors.Is(err, atspi.ErrStaleSnapshot) +} + +func (worker *Worker) placeDocument(ctx context.Context, cursor *DocumentCursor, result Result) Result { + if cursor != nil && result.Err == nil && result.Moved { + if owner, err := cursor.tree.DocumentContext(result.DocumentPosition.Object); err == nil { + result.DocumentCaretContext = owner.Ancestors + } + } + if !worker.CurrentDocumentResult(result) { + result.Err = atspi.ErrStaleObject + return result + } + navigator, ok := worker.nativeCapturerFor(result.DocumentFocus).(interface { + SetDocumentPosition(context.Context, atspi.ObjectReference, atspi.ObjectID) error + }) + if !ok || result.Err != nil || !result.Moved { + return result + } + if !result.DocumentPosition.Document.Valid() { + result.Err = atspi.ErrStaleObject + return result + } + focus := worker.focus() + if focus != result.DocumentFocus { + if cursor == nil { + result.Err = errors.New("document focus changed") + return result + } + reference, err := cursor.tree.Reference(focus) + if err != nil { + result.Err = err + return result + } + document, err := cursor.tree.DocumentContext(reference) + if err != nil { + result.Err = err + return result + } + if document.TopLevel != result.DocumentPosition.Document { + result.Err = errors.New("document focus changed") + return result + } + result.DocumentFocus = focus + } + if !focus.Valid() { + result.Err = atspi.ErrStaleObject + return result + } + deadline, cancel := context.WithTimeout(ctx, worker.captureTimeout) + defer cancel() + result.CaretErr = navigator.SetDocumentPosition(deadline, result.DocumentPosition.Object, focus) + if result.CaretErr == nil && worker.CurrentDocumentResult(result) { + result = worker.refreshDocumentSoundGeometry(deadline, cursor, result) + } + return result +} + +func (worker *Worker) refreshDocumentSoundGeometry(ctx context.Context, cursor *DocumentCursor, result Result) Result { + reader, ok := worker.nativeCapturerFor(result.DocumentFocus).(interface { + CaptureDocumentSoundGeometry(context.Context, atspi.ObjectReference, atspi.ObjectReference) ([2]atspi.SoundGeometry, error) + }) + if !ok { + return result + } + // Geometry belongs to this presentation, not the document's initial viewport. + // Failed refreshes must not reuse an old position after scrolling or resizing. + result.DocumentPosition.Snapshot.SoundGeometry = atspi.SoundGeometry{} + link := atspi.ObjectReference{} + if previous := result.DocumentPosition.LinkedHeading; previous != nil { + copy := *previous + copy.SoundGeometry = atspi.SoundGeometry{} + result.DocumentPosition.LinkedHeading = © + if cursor == nil { + result.DocumentSoundErr = atspi.ErrStaleObject + return result + } + var err error + link, err = cursor.tree.Reference(copy.ID()) + if err != nil { + result.DocumentSoundErr = err + return result + } + } + geometry, err := reader.CaptureDocumentSoundGeometry(ctx, result.DocumentPosition.Object, link) + result.DocumentSoundErr = err + if err == nil { + result.DocumentPosition.Snapshot.SoundGeometry = geometry[0] + if result.DocumentPosition.LinkedHeading != nil { + result.DocumentPosition.LinkedHeading.SoundGeometry = geometry[1] + } + } + return result +} diff --git a/internal/review/document_worker_test.go b/internal/review/document_worker_test.go new file mode 100644 index 0000000..6c93ec8 --- /dev/null +++ b/internal/review/document_worker_test.go @@ -0,0 +1,1086 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type documentPlacement struct { + position atspi.ObjectReference + focus atspi.ObjectID +} + +type boundaryNavigator struct { + *fakeCapturer + caretTextReader + position atspi.ObjectReference + focus atspi.ObjectID + offset int +} + +type refreshingCaretNavigator struct { + *readAllCapturer + caretTextReader + placements []int +} + +func (navigator *refreshingCaretNavigator) SetDocumentCaretPosition(_ context.Context, _ atspi.ObjectReference, _ atspi.ObjectID, offset int) error { + navigator.placements = append(navigator.placements, offset) + if len(navigator.placements) == 1 { + return atspi.ErrStaleSnapshot + } + return nil +} + +func TestWorkerRetriesNativeCaretPlacementWithoutRepeatingMovement(t *testing.T) { + text := caretTextReader{webID("/text"): "First line"} + cursor := newCaretTextCursor(t, text) + navigator := &refreshingCaretNavigator{readAllCapturer: &readAllCapturer{tree: cursor.tree}, caretTextReader: text} + worker, _ := NewWorker(navigator, time.Second) + worker.SyncFocus(webID("/text")) + result, _ := worker.moveDocumentCaret(context.Background(), cursor, CaretNextCharacter, 0) + if result.Err != nil || result.CaretErr != nil || result.DocumentCaretText != "i" || result.DocumentPosition.Offset != 1 || + len(navigator.placements) != 2 || navigator.placements[0] != 1 || navigator.placements[1] != 1 { + t.Fatalf("retry skipped or lost requested character: %+v, placements %v", result, navigator.placements) + } + next, _ := worker.moveDocumentCaret(context.Background(), cursor, CaretNextCharacter, 0) + if next.Err != nil || next.DocumentCaretText != "r" || next.DocumentPosition.Offset != 2 { + t.Fatalf("retry lost the saved position: %+v", next) + } +} + +func (navigator *boundaryNavigator) SetDocumentCaretPosition(_ context.Context, position atspi.ObjectReference, focus atspi.ObjectID, offset int) error { + navigator.position, navigator.focus, navigator.offset = position, focus, offset + return nil +} + +func TestDocumentTimeoutRetiresQueuedNavigation(t *testing.T) { + text := caretTextReader{webID("/text"): "First line", webID("/next"): "Last line"} + capturer := &boundaryNavigator{fakeCapturer: &fakeCapturer{calls: make(chan captureCall, 1)}, caretTextReader: text} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + worker.SyncFocus(webID("/text")) + if err := worker.MoveDocumentCaret(CaretNextLine); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + for range 8 { + if err := worker.MoveDocumentCaret(CaretNextLine); err != nil { + t.Fatal(err) + } + } + if err := worker.MoveDocument(DocumentHeading, 0, false); err != nil { + t.Fatal(err) + } + if err := worker.ActivateDocumentCaret(); err != nil { + t.Fatal(err) + } + call.result <- captureResult{err: context.DeadlineExceeded} + if result := waitResult(t, worker); !errors.Is(result.Err, context.DeadlineExceeded) { + t.Fatalf("initial result = %+v", result) + } + // A fresh command must recover without eight more failed captures, a + // heading move, or activation of a target selected before the timeout. + if err := worker.MoveDocumentCaret(CaretDocumentStart); err != nil { + t.Fatal(err) + } + call = <-capturer.calls + call.result <- captureResult{tree: newCaretTextCursor(t, text).tree} + result := waitResult(t, worker) + if result.Err != nil || !result.Moved || result.DocumentCaretCommand != CaretDocumentStart || result.DocumentCaretText != "First line" { + t.Fatalf("recovery result = %+v", result) + } +} + +func TestDocumentSuccessfulQueuedStepsRemainOrdered(t *testing.T) { + text := caretTextReader{webID("/text"): "First line", webID("/next"): "Last line"} + capturer := &boundaryNavigator{fakeCapturer: &fakeCapturer{calls: make(chan captureCall, 1)}, caretTextReader: text} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + worker.SyncFocus(webID("/text")) + if err := worker.MoveDocumentCaret(CaretNextCharacter); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + for range 2 { + if err := worker.MoveDocumentCaret(CaretNextCharacter); err != nil { + t.Fatal(err) + } + } + call.result <- captureResult{tree: newCaretTextCursor(t, text).tree} + for index, expected := range []string{"i", "r", "s"} { + result := waitResult(t, worker) + if result.Err != nil || !result.Moved || result.DocumentCaretText != expected || result.DocumentPosition.Offset != index+1 { + t.Fatalf("step %d = %+v", index, result) + } + } +} + +func TestDocumentOldTimeoutPreservesNewPageCommands(t *testing.T) { + text := caretTextReader{webID("/text"): "First line", webID("/next"): "Last line"} + capturer := &boundaryNavigator{fakeCapturer: &fakeCapturer{calls: make(chan captureCall, 1)}, caretTextReader: text} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + worker.SyncFocus(webID("/text")) + if err := worker.MoveDocumentCaret(CaretNextLine); err != nil { + t.Fatal(err) + } + oldCall := <-capturer.calls + worker.ResetDocument(webID("/text")) + if err := worker.MoveDocumentCaret(CaretDocumentStart); err != nil { + t.Fatal(err) + } + oldCall.result <- captureResult{err: context.DeadlineExceeded} + oldResult := waitResult(t, worker) + if worker.CurrentDocumentResult(oldResult) { + t.Fatal("old timeout retained current page ownership") + } + call := <-capturer.calls + call.result <- captureResult{tree: newCaretTextCursor(t, text).tree} + result := waitResult(t, worker) + if result.Err != nil || !result.Moved || result.DocumentCaretCommand != CaretDocumentStart || !worker.CurrentDocumentResult(result) { + t.Fatalf("new page result = %+v", result) + } +} + +func TestDocumentCaretMovePlacesNativeCaretForTabTraversal(t *testing.T) { + for _, command := range []DocumentCaretCommand{CaretNextLine, CaretPreviousLine, CaretDocumentStart, CaretDocumentEnd, CaretNextCharacter, CaretNextWord, CaretLineStart, CaretLineEnd} { + text := caretTextReader{webID("/text"): "First line", webID("/next"): "Last line"} + navigator := &boundaryNavigator{fakeCapturer: &fakeCapturer{}, caretTextReader: text} + worker, err := NewWorker(navigator, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/text")) + cursor := newCaretTextCursor(t, text) + if command == CaretDocumentStart || command == CaretPreviousLine { + if _, err := cursor.MoveCaret(context.Background(), text, CaretDocumentEnd); err != nil { + t.Fatal(err) + } + } + result, _ := worker.moveDocumentCaret(context.Background(), cursor, command, worker.documentEpoch.Load()) + if result.Err != nil || result.CaretErr != nil || !result.Moved || + navigator.position != result.DocumentPosition.Object || navigator.focus != webID("/text") || navigator.offset != result.DocumentPosition.Offset { + t.Fatalf("command %v: result=%+v, placement=%+v", command, result, navigator) + } + if (command == CaretNextLine || command == CaretPreviousLine || command == CaretDocumentStart || command == CaretDocumentEnd) && (result.DocumentCaretStart != 0 || result.DocumentCaretEnd != len(text[result.DocumentPosition.Object.ID()])) { + t.Fatalf("command %v: native text range = %d:%d", command, result.DocumentCaretStart, result.DocumentCaretEnd) + } + } +} + +type recordingDocumentActivator struct { + *fakeCapturer + target atspi.ObjectReference + focus atspi.ObjectID +} + +func (activator *recordingDocumentActivator) ActivateDocumentObject(_ context.Context, target atspi.ObjectReference, focus atspi.ObjectID) error { + activator.target, activator.focus = target, focus + return nil +} + +func TestDocumentActivationUsesBrowseCaretInsteadOfFocusedTopic(t *testing.T) { + node := func(path, role string, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, path, role, "", "") + snapshot.BusName = webID(path).BusName + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "document web", "/topic", "/new_posts"), + node("/topic", "link"), + node("/new_posts", "link", "/new_posts_text"), + node("/new_posts_text", "static"), + }) + if err != nil { + t.Fatal(err) + } + cursor, err := NewDocumentCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(context.Background(), webID("/topic")); err != nil { + t.Fatal(err) + } + staticRef, err := tree.Reference(webID("/new_posts_text")) + if err != nil { + t.Fatal(err) + } + cursor.places[len(cursor.places)-1].object = staticRef + cursor.places[len(cursor.places)-1].origin = CaretNavigation + activator := &recordingDocumentActivator{fakeCapturer: &fakeCapturer{}} + worker, err := NewWorker(activator, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/topic")) + result, _ := worker.activateDocumentCaret(context.Background(), cursor, 0) + if result.Err != nil || activator.target.ID() != webID("/new_posts") || activator.focus != webID("/topic") { + t.Fatalf("activation result=%+v target=%v focus=%v", result, activator.target.ID(), activator.focus) + } +} + +type waitingCaretReader struct { + *fakeCapturer + deadline time.Time +} + +type refreshingCaretReader struct { + *fakeCapturer + text caretTextReader + staleOnce bool +} + +type invalidatingCaretReader struct { + *fakeCapturer + text caretTextReader + tree *atspi.AccessibleTree +} + +func (reader *invalidatingCaretReader) ReadDocumentCaret(ctx context.Context, reference atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + result, err := reader.text.ReadDocumentCaret(ctx, reference, offset, unit) + reader.tree.Invalidate(reference.ID()) + return result, err +} + +func TestDocumentCaretSpeaksReadTextWhenAncestorDisappears(t *testing.T) { + text := caretTextReader{webID("/text"): "Alpha", webID("/next"): "Next"} + cursor := newCaretTextCursor(t, text) + reader := &invalidatingCaretReader{fakeCapturer: &fakeCapturer{}, text: text, tree: cursor.tree} + worker, err := NewWorker(reader, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/text")) + result, _ := worker.moveDocumentCaret(context.Background(), cursor, CaretNextCharacter, 0) + if result.Err != nil || !result.Moved || result.DocumentCaretText != "l" || result.DocumentPosition.Offset != 1 { + t.Fatalf("stale ancestor after caret read: %+v", result) + } +} + +func (reader *refreshingCaretReader) ReadDocumentCaret(ctx context.Context, reference atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + if reader.staleOnce { + reader.staleOnce = false + return atspi.DocumentCaretText{}, atspi.ErrStaleObject + } + return reader.text.ReadDocumentCaret(ctx, reference, offset, unit) +} + +func TestDocumentCaretRetriesStaleRecaptureWithoutSkipping(t *testing.T) { + text := caretTextReader{webID("/text"): "Alpha", webID("/next"): "Next"} + oldCursor := newCaretTextCursor(t, text) + oldCursor.tree.Invalidate(webID("/text")) + first := newCaretTextCursor(t, text).tree + fresh := newCaretTextCursor(t, text).tree + reader := &refreshingCaretReader{fakeCapturer: &fakeCapturer{calls: make(chan captureCall, 1)}, text: text, staleOnce: true} + worker, err := NewWorker(reader, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/text")) + done := make(chan Result, 1) + go func() { + result, _ := worker.moveDocumentCaret(context.Background(), oldCursor, CaretNextCharacter, 0) + done <- result + }() + initial := <-reader.calls + initial.result <- captureResult{tree: first} + retry := <-reader.calls + if retry.reviewFocus != webID("/text") { + t.Fatalf("retry focus = %v", retry.reviewFocus) + } + retry.result <- captureResult{tree: fresh} + result := <-done + if result.Err != nil || !result.Moved || result.DocumentCaretText != "l" || result.DocumentPosition.Offset != 1 { + t.Fatalf("stale recapture retry: %+v", result) + } +} + +func (reader *waitingCaretReader) ReadDocumentCaret(ctx context.Context, _ atspi.ObjectReference, _ int, _ atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + reader.deadline, _ = ctx.Deadline() + <-ctx.Done() + return atspi.DocumentCaretText{}, ctx.Err() +} + +func TestDocumentCaretNavigationDeadlinePreservesPosition(t *testing.T) { + text := caretTextReader{webID("/text"): "Alpha beta", webID("/next"): "Next"} + cursor := newCaretTextCursor(t, text) + reader := &waitingCaretReader{fakeCapturer: &fakeCapturer{}} + worker, err := NewWorker(reader, time.Millisecond) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/text")) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + result, _ := worker.moveDocumentCaret(ctx, cursor, CaretNextWord, 0) + parentDeadline, _ := ctx.Deadline() + if !errors.Is(result.Err, context.DeadlineExceeded) || result.Moved || !reader.deadline.Before(parentDeadline) { + t.Fatalf("navigation deadline: result %+v, deadline %v", result, reader.deadline) + } + move, err := cursor.MoveCaret(context.Background(), text, CaretNextCharacter) + if err != nil || move.Text != "l" || move.Position.Offset != 1 { + t.Fatalf("position changed after timeout: %+v, %v", move, err) + } +} + +func TestRecoverRemovedDocumentFocusStaysInActiveDocument(t *testing.T) { + _, cursor := webCursor(t) + if _, err := cursor.SyncFocus(context.Background(), webID("/first")); err != nil { + t.Fatal(err) + } + nodes := webNodes() + // Recapture of a dynamic page no longer contains the old caret object. + nodes[2].Children = []atspi.ObjectID{webID("/second")} + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{nodes[2], nodes[5]}) + if err != nil { + t.Fatal(err) + } + worker, err := NewWorker(&fakeCapturer{}, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/first")) + result := Result{DocumentFocus: webID("/first"), CaptureReason: atspi.ErrObjectNotFound} + if !worker.recoverCapturedDocumentFocus(cursor, tree, &result) || result.DocumentFocus != webID("/doc") || worker.focus() != webID("/doc") { + t.Fatalf("same-document recovery failed: %+v, focus %v", result, worker.focus()) + } + worker.SyncFocus(webID("/chrome")) + result.DocumentFocus = webID("/first") + if worker.recoverCapturedDocumentFocus(cursor, tree, &result) || worker.focus() != webID("/chrome") { + t.Fatal("recovery displaced browser chrome focus") + } + worker.SyncFocus(webID("/first")) + other := nodes[8] + other.Children = nil + otherTree, err := atspi.NewAccessibleTree(webID("/other"), []atspi.TreeNode{other}) + if err != nil { + t.Fatal(err) + } + if worker.recoverCapturedDocumentFocus(cursor, otherTree, &result) || worker.focus() != webID("/first") { + t.Fatal("recovery crossed to another document") + } +} + +func TestDocumentMoveRecoversAfterDynamicObjectRemoval(t *testing.T) { + oldTree, cursor := webCursor(t) + if _, err := cursor.SyncFocus(context.Background(), webID("/first")); err != nil { + t.Fatal(err) + } + nodes := webNodes() + nodes[2].Children = nodes[2].Children[1:] + withoutFirst := append(append([]atspi.TreeNode{}, nodes[:3]...), nodes[4:]...) + if err := oldTree.Replace(webID("/root"), withoutFirst); err != nil { + t.Fatal(err) + } + freshDocument := nodes[2] + freshDocument.Children = []atspi.ObjectID{webID("/second")} + freshTree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{freshDocument, nodes[5]}) + if err != nil { + t.Fatal(err) + } + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, err := NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/first")) + type moveResult struct { + result Result + } + done := make(chan moveResult, 1) + go func() { + result, _ := worker.moveDocument(context.Background(), cursor, DocumentHeading, 0, false, 0) + done <- moveResult{result: result} + }() + call := <-capturer.calls + if call.reviewFocus != webID("/first") { + t.Fatalf("capture anchor = %v", call.reviewFocus) + } + call.result <- captureResult{tree: freshTree} + result := (<-done).result + if result.Err != nil || !result.Moved || result.DocumentPosition.Object.ID() != webID("/second") || result.DocumentFocus != webID("/doc") { + t.Fatalf("document move after removal: %+v", result) + } +} + +func TestDocumentMoveRecoversFocusRemovedDuringTextRecapture(t *testing.T) { + tree, cursor := webCursor(t) + if _, err := cursor.SyncFocus(context.Background(), webID("/first")); err != nil { + t.Fatal(err) + } + // The initial failure describes stale text, but the ensuing capture can + // discover that the old focus has since been removed altogether. + tree.InvalidateText(webID("/first")) + nodes := webNodes() + nodes[2].Children = []atspi.ObjectID{webID("/second")} + fresh, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{nodes[2], nodes[5]}) + if err != nil { + t.Fatal(err) + } + capturer := &fakeCapturer{calls: make(chan captureCall, 2)} + worker, err := NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/first")) + done := make(chan Result, 1) + go func() { + result, _ := worker.moveDocument(context.Background(), cursor, DocumentHeading, 0, false, 0) + done <- result + }() + deadline := time.After(3 * time.Second) + for { + select { + case call := <-capturer.calls: + call.result <- captureResult{tree: fresh} + case result := <-done: + if result.Err != nil || !result.Moved || result.DocumentPosition.Object.ID() != webID("/second") || result.DocumentFocus != webID("/doc") { + t.Fatalf("focus removed during recapture: %+v", result) + } + return + case <-deadline: + t.Fatal("navigation did not finish") + } + } +} + +func TestDocumentMoveRetriesStaleRecaptureWithoutSkipping(t *testing.T) { + oldTree, cursor := webCursor(t) + if _, err := cursor.SyncFocus(context.Background(), webID("/first")); err != nil { + t.Fatal(err) + } + oldTree.Invalidate(webID("/first")) + first, _ := webCursor(t) + first.Invalidate(webID("/first")) + fresh, _ := webCursor(t) + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, err := NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/first")) + done := make(chan Result, 1) + go func() { + result, _ := worker.moveDocument(context.Background(), cursor, DocumentHeading, 0, false, 0) + done <- result + }() + initial := <-capturer.calls + initial.result <- captureResult{tree: first} + retry := <-capturer.calls + if retry.reviewFocus != webID("/first") { + t.Fatalf("retry focus = %v", retry.reviewFocus) + } + retry.result <- captureResult{tree: fresh} + result := <-done + if result.Err != nil || !result.Moved || result.DocumentPosition.Object.ID() != webID("/second") { + t.Fatalf("stale heading recapture retry: %+v", result) + } +} + +func TestDocumentMoveRetriesStaleSnapshotWithoutSkipping(t *testing.T) { + oldTree, cursor := webCursor(t) + if _, err := cursor.SyncFocus(context.Background(), webID("/first")); err != nil { + t.Fatal(err) + } + oldTree.InvalidateSnapshot(webID("/first")) + first, _ := webCursor(t) + first.InvalidateSnapshot(webID("/first")) + fresh, _ := webCursor(t) + capturer := &fakeCapturer{calls: make(chan captureCall, 2)} + worker, err := NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/first")) + done := make(chan Result, 1) + go func() { + result, _ := worker.moveDocument(context.Background(), cursor, DocumentHeading, 0, false, 0) + done <- result + }() + initial := <-capturer.calls + initial.result <- captureResult{tree: first} + retry := <-capturer.calls + if retry.reviewFocus != webID("/first") { + t.Fatalf("retry focus = %v", retry.reviewFocus) + } + retry.result <- captureResult{tree: fresh} + result := <-done + if result.Err != nil || !result.Moved || result.DocumentPosition.Object.ID() != webID("/second") { + t.Fatalf("stale snapshot recapture retry: %+v", result) + } +} + +func TestDocumentCaretRetriesStaleSnapshotWithoutSkipping(t *testing.T) { + text := caretTextReader{webID("/text"): "Alpha", webID("/next"): "Next"} + oldCursor := newCaretTextCursor(t, text) + oldCursor.tree.InvalidateSnapshot(webID("/text")) + first := newCaretTextCursor(t, text).tree + first.InvalidateSnapshot(webID("/text")) + fresh := newCaretTextCursor(t, text).tree + reader := &refreshingCaretReader{fakeCapturer: &fakeCapturer{calls: make(chan captureCall, 2)}, text: text} + worker, err := NewWorker(reader, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/text")) + done := make(chan Result, 1) + go func() { + result, _ := worker.moveDocumentCaret(context.Background(), oldCursor, CaretNextCharacter, 0) + done <- result + }() + initial := <-reader.calls + initial.result <- captureResult{tree: first} + retry := <-reader.calls + if retry.reviewFocus != webID("/text") { + t.Fatalf("retry focus = %v", retry.reviewFocus) + } + retry.result <- captureResult{tree: fresh} + result := <-done + if result.Err != nil || !result.Moved || result.DocumentCaretText != "l" || result.DocumentPosition.Offset != 1 { + t.Fatalf("stale snapshot caret retry: %+v", result) + } +} + +type fakeDocumentNavigator struct { + *fakeCapturer + calls chan documentPlacement + placementErr chan error +} + +func newFakeDocumentNavigator() *fakeDocumentNavigator { + return &fakeDocumentNavigator{ + fakeCapturer: &fakeCapturer{calls: make(chan captureCall, 1)}, + calls: make(chan documentPlacement, 1), + placementErr: make(chan error, 1), + } +} + +func TestWorkerJumpsToLoadedDocumentFragment(t *testing.T) { + node := func(path, name, role, id string, children ...string) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, name, role, "", "") + snapshot.BusName = webID(path).BusName + snapshot.ElementID = id + result := atspi.TreeNode{Snapshot: snapshot} + for _, child := range children { + result.Children = append(result.Children, webID(child)) + } + return result + } + tree, err := atspi.NewAccessibleTree(webID("/doc"), []atspi.TreeNode{ + node("/doc", "Forum", "document web", "", "/post"), + node("/post", "", "section", "p71", "/heading"), + node("/heading", "#71 User", "heading", "", "/permalink"), + node("/permalink", "#71", "link", ""), + }) + if err != nil { + t.Fatal(err) + } + navigator := newFakeDocumentNavigator() + worker, err := NewWorker(navigator, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/doc")) + results := make(chan Result, 1) + go func() { + result, _ := worker.jumpDocumentFragment(context.Background(), nil, "p71", worker.documentEpoch.Load()) + results <- result + }() + capture := <-navigator.fakeCapturer.calls + if capture.reviewFocus != webID("/doc") { + t.Fatalf("capture focus = %v", capture.reviewFocus) + } + capture.result <- captureResult{tree: tree} + placement := <-navigator.calls + if placement.position.ID() != webID("/permalink") || placement.focus != webID("/doc") { + t.Fatalf("fragment placement = %+v", placement) + } + result := <-results + if result.Err != nil || result.CaretErr != nil || !result.Moved || result.DocumentPosition.Snapshot.Name != "#71" { + t.Fatalf("fragment result = %+v", result) + } +} + +func (navigator *fakeDocumentNavigator) SetDocumentPosition(ctx context.Context, position atspi.ObjectReference, focus atspi.ObjectID) error { + call := documentPlacement{position: position, focus: focus} + select { + case navigator.calls <- call: + select { + case err := <-navigator.placementErr: + return err + default: + return nil + } + default: + return errors.New("unexpected duplicate document placement") + } +} + +func TestWorkerRetriesStaleDocumentCaretOnSameTarget(t *testing.T) { + for _, failure := range []error{atspi.ErrStaleObject, atspi.ErrObjectNotFound, atspi.ErrDeadObject} { + t.Run(failure.Error(), func(t *testing.T) { + tree, _ := webCursor(t) + navigator := newFakeDocumentNavigator() + worker, cancel := startWorker(t, navigator, time.Second) + defer worker.Stop(context.Background()) + defer cancel() + worker.SyncFocus(webID("/first")) + navigator.placementErr <- failure + if err := worker.MoveDocument(DocumentHeading, 0, false); err != nil { + t.Fatal(err) + } + initial := <-navigator.fakeCapturer.calls + initial.result <- captureResult{tree: tree} + first := <-navigator.calls + if first.position.ID() != webID("/second") { + t.Fatalf("first placement = %+v", first) + } + retry := <-navigator.fakeCapturer.calls + if retry.reviewFocus != webID("/first") { + t.Fatalf("retry focus = %v", retry.reviewFocus) + } + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + tree.Invalidate(root.ID()) + if err := tree.Replace(root.ID(), webNodes()); err != nil { + t.Fatal(err) + } + retry.result <- captureResult{tree: tree} + second := <-navigator.calls + if second.position.ID() != first.position.ID() || second.position == first.position { + t.Fatalf("retry must rebind same target: first=%+v second=%+v", first, second) + } + result := waitResult(t, worker) + if result.Err != nil || result.CaretErr != nil || result.DocumentPosition.Object != second.position { + t.Fatalf("retry result = %+v", result) + } + if err := worker.MoveDocument(DocumentHeading, 0, false); err != nil { + t.Fatal(err) + } + <-navigator.calls + next := waitResult(t, worker) + if next.Err != nil || next.CaretErr != nil || next.CaptureReason != nil || next.DocumentPosition.Object.ID() != webID("/first") { + t.Fatalf("next move after retry = %+v", next) + } + }) + } +} + +func TestWorkerRemovedEntryIsNotPresentedAndNextCommandRecovers(t *testing.T) { + tree, _ := webCursor(t) + nodes := webNodes() + for index := range nodes { + if nodes[index].Snapshot.Path == "/first" || nodes[index].Snapshot.Path == "/second" { + nodes[index].Snapshot.Role = "combo box" + nodes[index].Snapshot.Editable = true + nodes[index].Snapshot.Focusable = true + } + } + if err := tree.Replace(webID("/root"), nodes); err != nil { + t.Fatal(err) + } + navigator := newFakeDocumentNavigator() + worker, cancel := startWorker(t, navigator, time.Second) + defer worker.Stop(context.Background()) + defer cancel() + worker.SyncFocus(webID("/button")) + navigator.placementErr <- atspi.ErrDeadObject + if err := worker.MoveDocument(DocumentEntry, 0, true); err != nil { + t.Fatal(err) + } + initial := <-navigator.fakeCapturer.calls + initial.result <- captureResult{tree: tree} + first := <-navigator.calls + if first.position.ID() != webID("/second") { + t.Fatalf("initial entry target = %+v", first) + } + retry := <-navigator.fakeCapturer.calls + // The native adapter retires a confirmed missing target before recapture. + tree.Invalidate(webID("/second")) + retry.result <- captureResult{tree: tree} + result := waitResult(t, worker) + if result.Moved || !errors.Is(result.Err, atspi.ErrDeadObject) { + t.Fatalf("removed entry reported as a successful move: %+v", result) + } + if err := worker.MoveDocument(DocumentEntry, 0, true); err != nil { + t.Fatal(err) + } + placement := <-navigator.calls + if placement.position.ID() != webID("/first") { + t.Fatalf("next command revisited removed entry: %+v", placement) + } + next := waitResult(t, worker) + if next.Err != nil || next.CaretErr != nil || !next.Moved { + t.Fatalf("next entry navigation failed: %+v", next) + } +} + +func TestWorkerCaretRefusalKeepsVirtualMove(t *testing.T) { + _, cursor := webCursor(t) + navigator := newFakeDocumentNavigator() + worker, err := NewWorker(navigator, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/first")) + failure := errors.New("browser refused document caret") + navigator.placementErr <- failure + result, _ := worker.moveDocument(context.Background(), cursor, DocumentHeading, 0, false, worker.DocumentEpoch()) + if result.Err != nil || result.CaretErr != failure || !result.Moved || result.DocumentPosition.Object.ID() != webID("/second") { + t.Fatalf("ordinary caret refusal lost virtual reading position: %+v", result) + } + if len(navigator.fakeCapturer.calls) != 0 { + t.Fatal("ordinary caret refusal unnecessarily recaptured the document") + } +} + +func TestWorkerDocumentNavigation(t *testing.T) { + tree, _ := webCursor(t) + capturer := &fakeCapturer{calls: make(chan captureCall, 2)} + worker, cancel := startWorker(t, capturer, time.Second) + defer worker.Stop(context.Background()) + defer cancel() + worker.SyncFocus(webID("/first")) + if err := worker.MoveDocument(DocumentHeading, 0, false); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + if call.reviewFocus != webID("/first") { + t.Fatal("capture not scoped to focus") + } + call.result <- captureResult{tree: tree} + if r := waitResult(t, worker); r.Err != nil || !errors.Is(r.CaptureReason, ErrNoCurrent) || + !r.Moved || r.DocumentPosition.Object.ID() != webID("/second") { + t.Fatalf("heading: %+v", r) + } + for _, tc := range []struct { + target DocumentTarget + back bool + path string + moved bool + wrapped bool + }{ + {DocumentLink, false, "/link", true, false}, + {DocumentLink, false, "/link", true, true}, + {DocumentButton, false, "/button", true, false}, + {DocumentCheckBox, false, "/checkbox", true, false}, + {DocumentList, false, "/list", true, false}, + {DocumentSeparator, false, "/separator", true, false}, + {DocumentSeparator, false, "/separator", true, true}, + {DocumentHeading, true, "/second", true, false}, + {DocumentHeading, true, "/first", true, false}, + } { + worker.MoveDocument(tc.target, 0, tc.back) + if r := waitResult(t, worker); r.Err != nil || r.Moved != tc.moved || r.DocumentWrapped != tc.wrapped || + r.DocumentPosition.Object.ID() != webID(tc.path) { + t.Fatalf("navigation: %+v", r) + } + } + worker.SyncFocus(webID("/chrome")) + worker.MoveDocument(DocumentHeading, 0, false) + if r := waitResult(t, worker); !errors.Is(r.Err, atspi.ErrNotInDocument) { + t.Fatalf("chrome: %+v", r) + } + select { + case <-capturer.calls: + t.Fatal("unexpected recapture") + default: + } +} + +func TestWorkerDocumentLoadRetiresOutstandingResult(t *testing.T) { + tree, _ := webCursor(t) + capturer := &fakeCapturer{calls: make(chan captureCall, 2)} + worker, cancel := startWorker(t, capturer, time.Second) + defer worker.Stop(context.Background()) + defer cancel() + worker.SyncFocus(webID("/first")) + worker.MoveDocument(DocumentHeading, 0, false) + call := <-capturer.calls + worker.ResetDocument(webID("/first")) + call.result <- captureResult{tree: tree} + if result := waitResult(t, worker); worker.CurrentDocumentResult(result) { + t.Fatal("old page result accepted after same-path load") + } + worker.MoveDocument(DocumentHeading, 0, false) + select { + case call = <-capturer.calls: + call.result <- captureResult{tree: tree} + case <-time.After(time.Second): + t.Fatal("new page reused the old cursor instead of recapturing") + } + if result := waitResult(t, worker); !worker.CurrentDocumentResult(result) || result.Err != nil || result.DocumentPosition.Object.ID() != webID("/second") { + t.Fatalf("new page navigation = %+v", result) + } +} + +func TestWorkerDocumentCaptureUsesLatestFocus(t *testing.T) { + tree, _ := webCursor(t) + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer worker.Stop(context.Background()) + defer cancel() + worker.SyncFocus(webID("/first")) + worker.MoveDocument(DocumentHeading, 0, false) + call := <-capturer.calls + worker.SyncFocus(webID("/chrome")) + call.result <- captureResult{tree: tree} + r := waitResult(t, worker) + if r.DocumentFocus != webID("/chrome") || !errors.Is(r.Err, atspi.ErrNotInDocument) { + t.Fatalf("stale focus used: %+v", r) + } +} + +func TestWorkerDocumentRecapturePreservesPosition(t *testing.T) { + tree, _ := webCursor(t) + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer worker.Stop(context.Background()) + defer cancel() + worker.SyncFocus(webID("/first")) + worker.MoveDocument(DocumentHeading, 0, false) + call := <-capturer.calls + call.result <- captureResult{tree: tree} + waitResult(t, worker) + // Only a traversed branch requires recapture now. The hidden heading is + // between the current and requested positions; it cannot be skipped until + // its invalidated data has been refreshed. + tree.InvalidateText(webID("/hidden")) + worker.MoveDocument(DocumentHeading, 0, true) + call = <-capturer.calls + nodes := webNodes() + nodes[4].Geometry = atspi.Geometry{VisibilityKnown: true} + if err := tree.Replace(webID("/root"), nodes); err != nil { + t.Fatal(err) + } + call.result <- captureResult{tree: tree} + r := waitResult(t, worker) + if r.Err != nil || !errors.Is(r.CaptureReason, atspi.ErrStaleText) || !r.Moved || + r.DocumentWrapped || r.DocumentPosition.Object.ID() != webID("/first") { + t.Fatalf("recapture lost place: %+v", r) + } + diagnostics := r.DocumentDiagnostics + if diagnostics.CaptureAttempts != 1 || diagnostics.CursorRecreated || len(diagnostics.Attempts) != 2 { + t.Fatalf("recapture diagnostics = %+v", diagnostics) + } + failed, recovered := diagnostics.Attempts[0], diagnostics.Attempts[1] + if failed.Stage != "move" || failed.Recovery != "preserved" || failed.Error == "" || + recovered.Recovery != "preserved" || recovered.Error != "" || recovered.Before.Object != webID("/second") || + recovered.Synced.Object != webID("/second") || recovered.After.Object != webID("/first") { + t.Fatalf("recapture lost diagnostic history: %+v", diagnostics) + } +} + +func TestWorkerPlaceDocumentAcceptsSameDocumentFocusTransition(t *testing.T) { + _, cursor := webCursor(t) + ctx := context.Background() + _, err := cursor.SyncFocus(ctx, webID("/first")) + if err != nil { + t.Fatal(err) + } + move, err := cursor.Move(ctx, DocumentHeading, 2, false) + if err != nil || !move.Moved { + t.Fatalf("move: %+v err=%v", move, err) + } + worker, err := NewWorker(newFakeDocumentNavigator(), time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/button")) + result := worker.placeDocument(ctx, cursor, Result{ + DocumentTarget: DocumentHeading, + DocumentFocus: webID("/first"), + DocumentPosition: move.Position, + Moved: true, + }) + if result.Err != nil || result.CaretErr != nil { + t.Fatalf("same-document transition rejected: %+v", result) + } + if result.DocumentFocus != webID("/button") { + t.Fatalf("document focus = %v, want /button", result.DocumentFocus) + } + navigator, _ := worker.capturer.(*fakeDocumentNavigator) + select { + case call := <-navigator.calls: + if call.position != move.Position.Object || call.focus != webID("/button") { + t.Fatalf("placement = %+v", call) + } + default: + t.Fatal("document placement was not called") + } +} + +func TestWorkerPlaceDocumentRejectsCrossDocumentFocusTransition(t *testing.T) { + _, cursor := webCursor(t) + ctx := context.Background() + _, err := cursor.SyncFocus(ctx, webID("/first")) + if err != nil { + t.Fatal(err) + } + move, err := cursor.Move(ctx, DocumentHeading, 2, false) + if err != nil || !move.Moved { + t.Fatalf("move: %+v err=%v", move, err) + } + navigator := newFakeDocumentNavigator() + worker, err := NewWorker(navigator, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/other")) + result := worker.placeDocument(ctx, cursor, Result{ + DocumentTarget: DocumentHeading, + DocumentFocus: webID("/first"), + DocumentPosition: move.Position, + Moved: true, + }) + if result.Err == nil || result.Err.Error() != "document focus changed" { + t.Fatalf("cross-document transition accepted: %+v", result) + } + select { + case <-navigator.calls: + t.Fatal("cross-document placement was called") + default: + } +} + +func TestWorkerPlaceDocumentPreservesErrorResult(t *testing.T) { + _, cursor := webCursor(t) + navigator := newFakeDocumentNavigator() + worker, err := NewWorker(navigator, time.Second) + if err != nil { + t.Fatal(err) + } + result := Result{Err: context.Canceled, DocumentFocus: webID("/first"), Moved: true} + got := worker.placeDocument(context.Background(), cursor, result) + if !errors.Is(got.Err, context.Canceled) { + t.Fatalf("result error = %v, want canceled", got.Err) + } + select { + case <-navigator.calls: + t.Fatal("failed navigation placement was called") + default: + } +} + +func TestDocumentCaretKeepsOffsetAfterDocumentRefresh(t *testing.T) { + for _, kind := range []string{"semantics", "children"} { + t.Run(kind, func(t *testing.T) { + text := caretTextReader{webID("/text"): "First\nSecond\nThird", webID("/next"): "End"} + cursor := newCaretTextCursor(t, text) + navigator := &boundaryNavigator{fakeCapturer: &fakeCapturer{calls: make(chan captureCall, 1)}, caretTextReader: text} + worker, err := NewWorker(navigator, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(webID("/doc")) + ctx := context.Background() + for _, want := range []string{"First\n", "Second\n"} { + result, next := worker.moveDocumentCaret(ctx, cursor, CaretNextLine, worker.documentEpoch.Load()) + cursor = next + if result.Err != nil || result.DocumentCaretText != want { + t.Fatalf("initial navigation = %+v, want %q", result, want) + } + } + docRef, _ := cursor.tree.Reference(webID("/doc")) + doc, err := cursor.tree.Document(ctx, docRef) + if err != nil { + t.Fatal(err) + } + nodes := make([]atspi.TreeNode, 0, len(doc.Nodes)) + for _, node := range doc.Nodes { + nodes = append(nodes, atspi.TreeNode{Snapshot: node.Snapshot, Children: node.Children, Geometry: node.Geometry, Text: node.Text}) + } + var wantReason error = atspi.ErrStaleSnapshot + if kind == "children" { + cursor.tree.MarkChildrenChanged(webID("/doc")) + wantReason = nil + } else { + cursor.tree.InvalidateSnapshot(webID("/text")) + } + refresh := func() { + call := <-navigator.calls + err := cursor.tree.Replace(webID("/doc"), nodes) + call.result <- captureResult{tree: cursor.tree, err: err} + } + if kind != "children" { + go refresh() + } + result, _ := worker.moveDocumentCaret(ctx, cursor, CaretNextLine, worker.documentEpoch.Load()) + if result.Err != nil || !errors.Is(result.CaptureReason, wantReason) || result.DocumentCaretText != "Third" { + t.Fatalf("semantic refresh restarted or skipped reading: %+v", result) + } + if kind == "children" { + if result.DocumentDiagnostics.CaptureAttempts != 0 { + t.Fatal("local text movement recaptured unrelated child order") + } + go refresh() + result, _ = worker.moveDocumentCaret(ctx, cursor, CaretNextLine, worker.documentEpoch.Load()) + if result.Err != nil || !errors.Is(result.CaptureReason, atspi.ErrIncompleteTree) || result.DocumentCaretText != "End" { + t.Fatalf("crossing refreshed children lost position: %+v", result) + } + } + }) + } +} + +func TestDocumentWorkerUsesSeparateCaptureDeadline(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, err := NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.SetDocumentCaptureTimeout(15 * time.Second); err != nil { + t.Fatal(err) + } + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + if err := worker.SetDocumentCaptureTimeout(time.Second); err == nil { + t.Fatal("changed document capture deadline after start") + } + worker.SyncFocus(webID("/doc")) + if err := worker.MoveDocument(DocumentHeading, 0, false); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + deadline, ok := call.ctx.Deadline() + if !ok || time.Until(deadline) < 13*time.Second { + t.Fatalf("document capture deadline = %v, present = %t", deadline, ok) + } + // A shutdown must still cancel a capture with the larger budget. + if err := worker.Stop(context.Background()); err != nil { + t.Fatal(err) + } + if !errors.Is(call.ctx.Err(), context.Canceled) { + t.Fatalf("capture was not canceled: %v", call.ctx.Err()) + } +} diff --git a/internal/review/flat.go b/internal/review/flat.go new file mode 100644 index 0000000..8436be6 --- /dev/null +++ b/internal/review/flat.go @@ -0,0 +1,410 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "sort" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// FlatUnit describes sequential reading, independently of keyboard layout. +type FlatUnit int + +const ( + Line FlatUnit = iota + 1 + Word + Character + WindowStart + WindowEnd + WordAbove + WordBelow + LineEnd +) + +// FlatPosition is owned text at the review location. Offset counts Unicode +// code points in Object's AT-SPI text; synthetic accessible names have no +// offset. Bounds belong to the whole captured zone, never guessed characters. +type FlatPosition struct { + Text string + Object atspi.ObjectID + Offset int + HasOffset bool + Bounds atspi.Rectangle +} + +type flatLocation struct{ line, zone, character int } + +// FlatCursor is owned by the review worker. It rebuilds from one atomic owned +// window snapshot before every command, preserving an independent location by +// object and character offset when focus has not changed. No native queries or +// output calls occur here. Failed refreshes leave the previous location intact +// but return an error, so stale content is never presented as current. +type FlatCursor struct { + lines []flatLine + location flatLocation + focus atspi.ObjectID + tree *atspi.AccessibleTree + references map[atspi.ObjectID]atspi.ObjectReference + parents map[atspi.ObjectID]atspi.ObjectID + verticalTargetX int64 + hasVerticalTarget bool + started bool + completeness FlatCompleteness + warnedIncomplete bool +} + +func (cursor *FlatCursor) Refresh(ctx context.Context, tree *atspi.AccessibleTree, focus atspi.ObjectID) error { + if tree == nil { + return ErrNoCurrent + } + snapshot, err := tree.ReviewWindow(ctx, focus) + if err != nil { + return err + } + nodes := snapshot.Nodes + lines, completeness, err := build_flat_layout(ctx, nodes) + if err != nil { + return err + } + next := FlatCursor{lines: lines, focus: focus, tree: tree, references: snapshot.References, completeness: completeness, + parents: make(map[atspi.ObjectID]atspi.ObjectID, len(nodes))} + for _, n := range nodes { + for _, child := range n.Children { + next.parents[child] = n.Snapshot.ID() + } + } + // Exact identity takes priority over a displayed descendant of focus. + if !next.seek(focus, 0, false) { + if !next.seekDescendant(focus) { + next.seek_ancestor(focus) + } + } + for _, n := range nodes { + if n.Snapshot.ID() == focus && n.Text.CaretKnown { + next.seek(focus, n.Text.CaretOffset, true) + break + } + } + if cursor.focus == focus && cursor.tree == tree && len(cursor.lines) > 0 { + old := cursor.position(Character) + if cursor.references[old.Object] == next.references[old.Object] { + if next.seek(old.Object, old.Offset, old.HasOffset) { + next.verticalTargetX = cursor.verticalTargetX + next.hasVerticalTarget = cursor.hasVerticalTarget + } + } + } + next.started = cursor.started && cursor.focus == focus + next.warnedIncomplete = cursor.warnedIncomplete && cursor.focus == focus && cursor.tree == tree && cursor.completeness == completeness + *cursor = next + return nil +} + +// A focused leaf can have no displayed zone while its parent supplies the +// text. Choose only an actual ancestor zone, never a sibling or window title. +func (cursor *FlatCursor) seek_ancestor(object atspi.ObjectID) bool { + for id := cursor.parents[object]; id.Valid(); id = cursor.parents[id] { + if !cursor.parents[id].Valid() { + return false + } + if cursor.seek(id, 0, false) { + return true + } + } + return false +} + +func (cursor *FlatCursor) seekDescendant(object atspi.ObjectID) bool { + for li, line := range cursor.lines { + for zi, zone := range line.zones { + for id := cursor.parents[zone.object]; id.Valid(); id = cursor.parents[id] { + if id == object { + cursor.location = flatLocation{line: li, zone: zi} + return true + } + } + } + } + return false +} + +func (cursor *FlatCursor) seek(object atspi.ObjectID, offset int, hasOffset bool) bool { + for li, line := range cursor.lines { + for zi, zone := range line.zones { + if zone.object != object { + continue + } + if hasOffset && (!zone.hasOffset || offset < zone.start || offset >= zone.start+len(zone.runes)) { + continue + } + character := 0 + if hasOffset { + character = offset - zone.start + } else if !zone.hasOffset && offset >= 0 && offset < len(zone.runes) { + character = offset + } + cursor.location = flatLocation{li, zi, character} + return true + } + } + // End-of-line/text caret positions are blank, but still have an exact + // source offset. Prefer an actual character in a following range above. + if hasOffset { + for li, line := range cursor.lines { + for zi, zone := range line.zones { + if zone.object == object && zone.hasOffset && offset == zone.start+len(zone.runes) { + cursor.location = flatLocation{li, zi, len(zone.runes)} + return true + } + } + } + } + return false +} + +// Read moves by -1, 0, or +1 units and returns the resulting text. It crosses +// zone and line boundaries, but never wraps from the window's end to its start. +// A boundary returns moved=false and leaves the location unchanged. +func (cursor *FlatCursor) Read(unit FlatUnit, step int) (FlatPosition, bool, error) { + if unit < Line || unit > LineEnd || step < -1 || step > 1 || (unit > Character && step != 0) { + return FlatPosition{}, false, ErrInvalidDirection + } + if len(cursor.lines) == 0 { + return FlatPosition{}, false, ErrNoReviewContent + } + old := cursor.location + switch unit { + case WindowStart: + cursor.location = flatLocation{} + if cursor.location != old { + cursor.hasVerticalTarget = false + } + return cursor.position(Line), cursor.location != old, nil + case WindowEnd: + line := len(cursor.lines) - 1 + zone := len(cursor.lines[line].zones) - 1 + character := len(cursor.lines[line].zones[zone].runes) - 1 + cursor.location = flatLocation{line: line, zone: zone, character: character} + if cursor.location != old { + cursor.hasVerticalTarget = false + } + return cursor.position(Line), cursor.location != old, nil + case WordAbove: + if cursor.moveVertically(-1, cursor.verticalX()) { + return cursor.position(Word), true, nil + } + return cursor.position(Word), false, nil + case WordBelow: + if cursor.moveVertically(1, cursor.verticalX()) { + return cursor.position(Word), true, nil + } + return cursor.position(Word), false, nil + case LineEnd: + line := cursor.location.line + zone := len(cursor.lines[line].zones) - 1 + character := len(cursor.lines[line].zones[zone].runes) - 1 + cursor.location = flatLocation{line: line, zone: zone, character: character} + if cursor.location != old { + cursor.hasVerticalTarget = false + } + return cursor.position(Character), cursor.location != old, nil + } + if step != 0 { + switch unit { + case Line: + line := old.line + step + if line >= 0 && line < len(cursor.lines) { + cursor.location = flatLocation{line: line} + } + case Character: + cursor.advanceCharacter(step) + case Word: + cursor.advanceWord(step) + } + } + moved := cursor.location != old + if moved { + cursor.hasVerticalTarget = false + } + return cursor.position(unit), moved, nil +} + +func (cursor *FlatCursor) verticalX() int64 { + if !cursor.hasVerticalTarget { + cursor.verticalTargetX = characterCenterX(cursor.zone(), cursor.location.character) + cursor.hasVerticalTarget = true + } + return cursor.verticalTargetX +} + +func (cursor *FlatCursor) moveVertically(step int, targetX int64) bool { + destinationLine := cursor.location.line + step + if destinationLine < 0 || destinationLine >= len(cursor.lines) { + return false + } + zones := append([]flatZone(nil), cursor.lines[destinationLine].zones...) + sort.SliceStable(zones, func(i, j int) bool { return zones[i].bounds.X < zones[j].bounds.X }) + for _, zone := range zones { + for character := range zone.runes { + if characterRightX(zone, character) >= targetX { + cursor.location = flatLocation{line: destinationLine, zone: zoneIndexInLine(cursor.lines[destinationLine], zone), character: character} + return true + } + } + } + zone := zones[len(zones)-1] + cursor.location = flatLocation{line: destinationLine, zone: zoneIndexInLine(cursor.lines[destinationLine], zone), character: len(zone.runes) - 1} + return true +} + +func zoneIndexInLine(line flatLine, zone flatZone) int { + for index, candidate := range line.zones { + if candidate.object == zone.object && candidate.start == zone.start { + return index + } + } + return 0 +} + +func characterCenterX(zone flatZone, character int) int64 { + if len(zone.runes) == 0 { + return int64(zone.bounds.X) + } + return int64(zone.bounds.X) + int64(zone.bounds.Width)*int64(2*character+1)/(int64(2*len(zone.runes))) +} + +func characterRightX(zone flatZone, character int) int64 { + if len(zone.runes) == 0 { + return int64(zone.bounds.X) + } + return int64(zone.bounds.X) + int64(zone.bounds.Width)*int64(character+1)/int64(len(zone.runes)) +} + +func (cursor *FlatCursor) zone() flatZone { + return cursor.lines[cursor.location.line].zones[cursor.location.zone] +} + +func (cursor *FlatCursor) advanceZone(step int) bool { + next := cursor.location + next.zone += step + if next.zone < 0 { + next.line-- + if next.line < 0 { + return false + } + next.zone = len(cursor.lines[next.line].zones) - 1 + } else if next.zone >= len(cursor.lines[next.line].zones) { + next.line++ + if next.line >= len(cursor.lines) { + return false + } + next.zone = 0 + } + next.character = 0 + cursor.location = next + return true +} + +func (cursor *FlatCursor) advanceCharacter(step int) bool { + next := cursor.location.character + step + if next >= 0 && next < len(cursor.zone().runes) { + cursor.location.character = next + return true + } + if !cursor.advanceZone(step) { + return false + } + if step < 0 { + cursor.location.character = len(cursor.zone().runes) - 1 + } + return true +} + +func (cursor *FlatCursor) advanceWord(step int) { + old := cursor.location + zone := cursor.zone() + index := wordIndex(zone, old.character) + if next := index + step; next >= 0 && next < len(zone.words) { + cursor.location.character = zone.words[next][0] + return + } + for cursor.advanceZone(step) { + zone = cursor.zone() + if len(zone.words) == 0 { + if isBlankLineZone(zone) { + cursor.location.character = 0 + return + } + continue + } + index = 0 + if step < 0 { + index = len(zone.words) - 1 + } + cursor.location.character = zone.words[index][0] + return + } + cursor.location = old +} + +func isBlankLineZone(zone flatZone) bool { + if len(zone.runes) == 0 { + return false + } + for _, r := range zone.runes { + if r != '\n' && r != '\r' { + return false + } + } + return true +} + +func wordIndex(zone flatZone, character int) int { + for i, span := range zone.words { + if character < span[1] { + return i + } + } + return len(zone.words) - 1 +} + +func (cursor *FlatCursor) position(unit FlatUnit) FlatPosition { + zone := cursor.zone() + start, end := cursor.location.character, min(cursor.location.character+1, len(zone.runes)) + text := "" + switch unit { + case Line: + var parts []string + for _, z := range cursor.lines[cursor.location.line].zones { + parts = append(parts, z.text) + } + text = strings.Join(parts, " ") + case Word: + if index := wordIndex(zone, start); index >= 0 { + start, end = zone.words[index][0], zone.words[index][1] + } + } + if unit != Line { + text = string(zone.runes[start:end]) + } + return FlatPosition{Text: text, Object: zone.object, Offset: zone.start + start, + HasOffset: zone.hasOffset, Bounds: zone.bounds} +} diff --git a/internal/review/flat_browser_native_test.go b/internal/review/flat_browser_native_test.go new file mode 100644 index 0000000..c5503b8 --- /dev/null +++ b/internal/review/flat_browser_native_test.go @@ -0,0 +1,147 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestNativeBrowserChromeFlatReview(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_BROWSER") != "1" { + t.Skip("requires private browser session") + } + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + keys := func(chord string) { + t.Helper() + if out, err := exec.CommandContext(ctx, "xdotool", "key", "--clearmodifiers", chord).CombinedOutput(); err != nil { + t.Fatalf("keys: %v %s", err, out) + } + } + wait := func(match func(atspi.Event) bool) atspi.Event { + t.Helper() + for { + select { + case e := <-adapter.Events(): + if match(e) { + return e + } + case <-ctx.Done(): + t.Fatal("missing browser event: ", ctx.Err()) + return atspi.Event{} + } + } + } + capture := func(focus atspi.ObjectID) ([]flatLine, atspi.ReviewSnapshot) { + t.Helper() + tree, err := adapter.CaptureReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + snapshot, err := tree.ReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + lines, status, err := build_flat_layout(ctx, snapshot.Nodes) + if err != nil { + t.Fatal(err) + } + t.Logf("review lines=%d completeness=%+v", len(lines), status) + return lines, snapshot + } + contains := func(lines []flatLine, want string) bool { + for _, line := range lines { + for _, zone := range line.zones { + if strings.Contains(zone.text, want) { + return true + } + } + } + return false + } + keys("ctrl+l") + address := wait(func(e atspi.Event) bool { + return (e.Type == atspi.FocusEvent || e.Type == atspi.FocusedStateEvent && e.Detail1 != 0) && e.Source.Role == "entry" + }) + lines, snapshot := capture(address.Source.ID()) + for _, name := range []string{"Back", "Forward", "Reload", "New Tab"} { + if !contains(lines, name) { + t.Errorf("browser control missing from review: %q", name) + } + } + tabLabel := false + for _, line := range lines { + for _, zone := range line.zones { + tabLabel = tabLabel || zone.role == "page tab" && strings.Contains(zone.text, "Cthulhu Browser Probe") + } + } + if !tabLabel { + t.Error("tab's label missing beside its Close button") + } + for _, n := range snapshot.Nodes { + if n.Text.Issue != "" { + t.Logf("unresolved text object: role=%s issue=%s children=%d", n.Snapshot.Role, n.Text.Issue, len(n.Children)) + } + } + // Chrome currently returns zero character/range geometry for the address + // value. Do not substitute its accessible label for the missing URL. + for _, n := range snapshot.Nodes { + if n.Snapshot.ID() != address.Source.ID() { + continue + } + if !n.Text.Known && n.Text.Issue == "" { + t.Fatal("unavailable address text lost its diagnostic") + } + if n.Text.Issue != "" { + for _, line := range lines { + for _, zone := range line.zones { + if zone.object == address.Source.ID() { + t.Fatalf("address label substituted for unavailable URL: %+v", zone) + } + } + } + t.Logf("address value remains unavailable: %s", n.Text.Issue) + } else { + t.Logf("address value captured in %d spans", len(n.Text.Ranges)) + } + } + keys("F6") + wait(func(e atspi.Event) bool { + return (e.Type == atspi.FocusEvent || e.Type == atspi.FocusedStateEvent && e.Detail1 != 0) && e.Source.Role != "entry" + }) + unfocusedLines, unfocusedSnapshot := capture(address.Source.ID()) + for _, n := range unfocusedSnapshot.Nodes { + if n.Snapshot.ID() == address.Source.ID() && !n.Text.Known && n.Text.Issue == "" { + t.Fatal("unfocused address text lost its diagnostic") + } + } + if !contains(unfocusedLines, "Reload") { + t.Fatal("toolbar lost after leaving address bar") + } + keys("Escape") + keys("F10") + wait(func(e atspi.Event) bool { + return (e.Type == atspi.FocusEvent || e.Type == atspi.FocusedStateEvent && e.Detail1 != 0) && e.Source.Role == "button" + }) + keys("Down") + menu := wait(func(e atspi.Event) bool { return e.Type == atspi.WindowActivatedEvent && e.Source.Role == "menu" }) + lines, _ = capture(menu.Source.ID()) + if !contains(lines, "New tab") && !contains(lines, "New Tab") { + t.Fatal("popup menu entries missing from flat review") + } + keys("Escape") +} diff --git a/internal/review/flat_layout.go b/internal/review/flat_layout.go new file mode 100644 index 0000000..5a31d5f --- /dev/null +++ b/internal/review/flat_layout.go @@ -0,0 +1,337 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "sort" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +var ( + ErrNoReviewContent = errors.New("no visible content for flat review") + ErrLimitedReview = errors.New("visible text exceeds flat review capture limits") + ErrUnavailableReview = errors.New("visible review content is unavailable") +) + +// FlatCompleteness reports known omissions, rather than treating a partial +// layout as a complete representation of the window. +type FlatCompleteness struct { + OmittedObjects int + UnavailableSubtrees int +} + +func (status FlatCompleteness) Incomplete() bool { + return status.OmittedObjects != 0 || status.UnavailableSubtrees != 0 +} + +const ( + maxFlatZones = 16384 + maxFlatTextBytes = 1 << 20 +) + +type flatZone struct { + object atspi.ObjectID + parent atspi.ObjectID + role, parentRole string + text string + start int + hasOffset bool + bounds atspi.Rectangle + runes []rune + words [][2]int +} + +type flatLine struct{ zones []flatZone } + +// buildFlatLines uses native visual ranges, followed by stable screen order. +// Like Python's default geometric rule, line membership requires overlapping +// vertical extents and centres within five pixels. Compare to the first zone +// so a staircase of overlapping objects cannot merge separate text rows. +func buildFlatLines(ctx context.Context, nodes []atspi.TreeNode) ([]flatLine, error) { + lines, _, err := build_flat_layout(ctx, nodes) + return lines, err +} + +func build_flat_layout(ctx context.Context, nodes []atspi.TreeNode) ([]flatLine, FlatCompleteness, error) { + var status FlatCompleteness + parents, nodeClips, hidden := flat_node_visibility(nodes) + zones, err := collect_flat_zones(ctx, nodes, parents, nodeClips, hidden, &status) + if err != nil { + return nil, status, err + } + if len(zones) == 0 && status.Incomplete() { + for _, node := range nodes { + if node.Text.Limited && !hidden[node.Snapshot.ID()] { + return nil, status, ErrLimitedReview + } + } + return nil, status, ErrUnavailableReview + } + lines, err := arrange_flat_lines(ctx, nodes, zones) + return lines, status, err +} + +func sameFlatLine(a, b flatZone) bool { + if a.role == "scroll bar" || b.role == "scroll bar" { + return a.object == b.object + } + if a.parentRole == "menu bar" || b.parentRole == "menu bar" { + return a.parent == b.parent + } + ay, by := int64(a.bounds.Y), int64(b.bounds.Y) + ah, bh := int64(a.bounds.Height), int64(b.bounds.Height) + if max(ay, by) >= min(ay+ah, by+bh) { + return false + } + delta := (2*ay + ah) - (2*by + bh) + return delta >= -10 && delta <= 10 +} + +// flat_node_visibility follows parent clipping before collecting any text. +func flat_node_visibility(nodes []atspi.TreeNode) (map[atspi.ObjectID]atspi.Snapshot, map[atspi.ObjectID]atspi.Rectangle, map[atspi.ObjectID]bool) { + parents := make(map[atspi.ObjectID]atspi.Snapshot, len(nodes)) + clips := make(map[atspi.ObjectID]atspi.Rectangle, len(nodes)) + nodeClips := make(map[atspi.ObjectID]atspi.Rectangle, len(nodes)) + hidden := make(map[atspi.ObjectID]bool, len(nodes)) + for _, node := range nodes { + id := node.Snapshot.ID() + parent := parents[id].ID() + g := node.Geometry + hidden[id] = hidden[parent] || g.VisibilityKnown && (!g.Visible || !g.Showing) + clip := clips[parent] + nodeClip := clip + if g.BoundsKnown { + if clip.Valid() { + var ok bool + nodeClip, ok = clip.Intersection(g.Bounds) + if node.Snapshot.Role != "page tab" { + hidden[id] = hidden[id] || !ok + } + } else { + nodeClip = g.Bounds + } + } + nodeClips[id] = nodeClip + clips[id] = nodeClip + if node.Snapshot.Role == "page tab" && !hidden[id] { + // A tab header is not the viewport of its displayed page. + clips[id] = clip + } + for _, child := range node.Children { + parents[child] = node.Snapshot + } + } + return parents, nodeClips, hidden +} + +// collect_flat_zones walks children before parents to avoid repeating container +// names and text. Password contents and partly clipped native runs stay excluded. +func collect_flat_zones(ctx context.Context, nodes []atspi.TreeNode, parents map[atspi.ObjectID]atspi.Snapshot, nodeClips map[atspi.ObjectID]atspi.Rectangle, hidden map[atspi.ObjectID]bool, status *FlatCompleteness) ([]flatZone, error) { + var zones []flatZone + textBytes := 0 + hasContent := make(map[atspi.ObjectID]bool, len(nodes)) + labelContent := make(map[atspi.ObjectID]bool, len(nodes)) + // Reverse tree order allows container names to be suppressed when their + // children already supply displayed content. + for i := len(nodes) - 1; i >= 0; i-- { + if err := ctx.Err(); err != nil { + return nil, err + } + n := nodes[i] + id := n.Snapshot.ID() + parent := parents[id] + if hasContent[id] { + hasContent[parent.ID()] = true + } + if labelContent[id] && !flat_label_control(n.Snapshot.Role) { + labelContent[parent.ID()] = true + } + if hidden[id] { + continue + } + if n.ChildrenUnavailable { + status.UnavailableSubtrees++ + hasContent[parent.ID()] = true + } + if !n.Geometry.BoundsKnown { + continue + } + if n.Text.Limited || n.Text.Issue != "" { + status.OmittedObjects++ + hasContent[parent.ID()] = true + continue + } + base := flatZone{object: id, parent: parent.ID(), role: n.Snapshot.Role, parentRole: parent.Role, bounds: nodeClips[id]} + before := len(zones) + if n.Snapshot.Role != "password text" { + for _, r := range n.Text.Ranges { + // Some web providers expose the same visible run on a + // container and its text child. Keep the child's source offset + // and speak the displayed run only once. + duplicate := false + if hasContent[id] { + for _, displayed := range zones { + if displayed.text != r.Text { + continue + } + if _, overlaps := displayed.bounds.Intersection(r.Bounds); !overlaps { + continue + } + for ancestor := displayed.parent; ancestor.Valid(); ancestor = parents[ancestor].ID() { + if ancestor == id { + duplicate = true + break + } + } + if duplicate { + break + } + } + } + if duplicate { + continue + } + // Native capture already clips text by character. Never keep a + // partially clipped run from another provider by changing only + // its rectangle; its text could still contain offscreen letters. + if clipped, ok := r.Bounds.Intersection(nodeClips[id]); !ok || clipped != r.Bounds { + continue + } + textBytes += len(r.Text) + if textBytes > maxFlatTextBytes || len(zones) >= maxFlatZones { + return nil, ErrLimitedReview + } + z := base + z.text, z.start, z.hasOffset, z.bounds = r.Text, r.Start, true, r.Bounds + if len(zones) > before { + previous := &zones[len(zones)-1] + if previous.start+utf8.RuneCountInString(previous.text) == r.Start && sameFlatLine(*previous, z) { + previous.text += r.Text + left := min(previous.bounds.X, r.Bounds.X) + top := min(previous.bounds.Y, r.Bounds.Y) + right := max(int64(previous.bounds.X)+int64(previous.bounds.Width), int64(r.Bounds.X)+int64(r.Bounds.Width)) + bottom := max(int64(previous.bounds.Y)+int64(previous.bounds.Height), int64(r.Bounds.Y)+int64(r.Bounds.Height)) + previous.bounds = atspi.Rectangle{X: left, Y: top, Width: int32(right - int64(left)), Height: int32(bottom - int64(top))} + continue + } + } + zones = append(zones, z) + } + } + // An independently named child control (for example a tab's Close + // button) does not supply its parent's label. Ordinary text children + // still suppress that label, avoiding duplicate displayed text. + composite := n.Snapshot.Role == "page tab" || n.Snapshot.Role == "menu item" + needsName := !hasContent[id] || composite && !labelContent[id] + if len(zones) == before && needsName && !n.ChildrenUnavailable { + // Never derive review text from focus-speech Text, ValueText, or + // password contents. Names are synthetic and have no text offset. + base.text = n.Snapshot.Name + if base.text == "" { + switch n.Snapshot.Role { + case "entry", "text", "password text", "push button", "check box", "radio button", "toggle button", "combo box": + base.text = n.Snapshot.Role + } + } + if base.text != "" { + textBytes += len(base.text) + if textBytes > maxFlatTextBytes || len(zones) >= maxFlatZones { + return nil, ErrLimitedReview + } + zones = append(zones, base) + } + } + if len(zones) > before || hasContent[id] { + hasContent[parent.ID()] = true + } + if !flat_label_control(n.Snapshot.Role) && (len(zones) > before || labelContent[id]) { + labelContent[parent.ID()] = true + } + } + return zones, nil +} + +// Named child controls represent independent actions rather than their +// enclosing control's label. Text/label descendants retain normal deduplication. +func flat_label_control(role string) bool { + switch role { + case "button", "push button", "toggle button", "check box", "radio button", "page tab", + "menu item", "check menu item", "radio menu item": + return true + } + return false +} + +// arrange_flat_lines keeps stable provider order for geometry ties and computes +// Unicode word spans only after all bounded content has been collected. +func arrange_flat_lines(ctx context.Context, nodes []atspi.TreeNode, zones []flatZone) ([]flatLine, error) { + if len(zones) == 0 { + return nil, ErrNoReviewContent + } + // Restore tree order before stable geometry sorts (ties retain provider + // order). Ranges within each object retain increasing logical offsets. + order := make(map[atspi.ObjectID]int, len(nodes)) + for i, n := range nodes { + order[n.Snapshot.ID()] = i + } + sort.SliceStable(zones, func(i, j int) bool { + if zones[i].bounds.Y != zones[j].bounds.Y { + return zones[i].bounds.Y < zones[j].bounds.Y + } + if order[zones[i].object] != order[zones[j].object] { + return order[zones[i].object] < order[zones[j].object] + } + return zones[i].start < zones[j].start + }) + var lines []flatLine + for _, zone := range zones { + if err := ctx.Err(); err != nil { + return nil, err + } + if len(lines) == 0 || !sameFlatLine(lines[len(lines)-1].zones[0], zone) { + lines = append(lines, flatLine{}) + } + zone.runes = []rune(zone.text) + for start := 0; start < len(zone.runes); { + if unicode.IsSpace(zone.runes[start]) { + start++ + continue + } + end := start + 1 + for end < len(zone.runes) && !unicode.IsSpace(zone.runes[end]) { + end++ + } + for end < len(zone.runes) && unicode.IsSpace(zone.runes[end]) { + end++ + } + zone.words = append(zone.words, [2]int{start, end}) + start = end + } + line := &lines[len(lines)-1] + line.zones = append(line.zones, zone) + } + for i := range lines { + sort.SliceStable(lines[i].zones, func(a, b int) bool { return lines[i].zones[a].bounds.X < lines[i].zones[b].bounds.X }) + } + return lines, nil +} diff --git a/internal/review/flat_native_test.go b/internal/review/flat_native_test.go new file mode 100644 index 0000000..91bf02d --- /dev/null +++ b/internal/review/flat_native_test.go @@ -0,0 +1,312 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "fmt" + "os" + "os/exec" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestNativeFlatReview(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_FLAT") != "1" { + t.Skip("requires private Xvfb, D-Bus and GTK tree fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Error(err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + var focus atspi.ObjectID + pending := []atspi.ObjectReference{root} + for len(pending) > 0 { + ref := pending[len(pending)-1] + pending = pending[:len(pending)-1] + snapshot, err := tree.Resolve(ref) + if err != nil { + t.Fatal(err) + } + if snapshot.Name == "Review text probe" { + focus = snapshot.ID() + break + } + for child, ok, err := tree.FirstChild(ref); ok && err == nil; child, ok, err = tree.NextSibling(child) { + pending = append(pending, child) + } + } + if !focus.Valid() { + t.Fatal("review text fixture missing") + } + worker, err := NewWorker(adapter, 3*time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(focus) + read := func(unit FlatUnit, step int) Result { + t.Helper() + if err := worker.ReadFlat(unit, step); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + if result.Err != nil { + t.Fatal(result.Err) + } + return result + case <-ctx.Done(): + t.Fatal(ctx.Err()) + return Result{} + } + } + if result := read(Line, 0); result.FlatPosition.Text != "Café 猫" { + t.Fatalf("first native line: %q", result.FlatPosition.Text) + } + if result := read(Word, 1); strings.TrimSpace(result.FlatPosition.Text) != "猫" || result.FlatPosition.Offset != 5 { + t.Fatalf("native word: %#v", result.FlatPosition) + } + if result := read(Line, 1); result.FlatPosition.Text != "Second line" { + t.Fatalf("second native line: %q", result.FlatPosition.Text) + } + // The fixture acknowledges the mutation with its window title. Wait for + // invalidation on the adapter event stream, not an arbitrary delay. + if err := exec.CommandContext(ctx, "xdotool", "key", "t").Run(); err != nil { + t.Fatal(err) + } + for { + select { + case event := <-adapter.Events(): + if event.Source.ID() == focus && strings.HasPrefix(event.Type, "object:text-changed:") { + goto changed + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } +changed: + // Existing offset 7 now belongs to the first changed line. Review retains + // a location by source offset, not stale line index or text. + result := read(Line, 0) + if !strings.Contains(result.FlatPosition.Text, "Changed") && !strings.Contains(result.FlatPosition.Text, "New line") { + t.Fatalf("stale native content: %q", result.FlatPosition.Text) + } +} + +func TestNativeTerminalFlatReview(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_TERMINAL_FLAT") != "1" { + t.Skip("requires private Xvfb, D-Bus and VTE fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer func() { + stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second) + defer stopCancel() + if err := adapter.Stop(stopCtx); err != nil { + t.Error(err) + } + }() + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + var focus atspi.ObjectID + pending := []atspi.ObjectReference{root} + for len(pending) > 0 { + ref := pending[len(pending)-1] + pending = pending[:len(pending)-1] + snapshot, err := tree.Resolve(ref) + if err != nil { + t.Fatal(err) + } + if snapshot.Role == "terminal" { + focus = snapshot.ID() + break + } + for child, ok, err := tree.FirstChild(ref); ok && err == nil; child, ok, err = tree.NextSibling(child) { + pending = append(pending, child) + } + } + if !focus.Valid() { + t.Fatal("review text fixture missing") + } + worker, err := NewWorker(adapter, 3*time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.Start(ctx); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + worker.SyncFocus(focus) + read := func(unit FlatUnit, step int) Result { + t.Helper() + if err := worker.ReadFlat(unit, step); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + if result.Err != nil { + t.Fatal(result.Err) + } + return result + case <-ctx.Done(): + t.Fatal(ctx.Err()) + return Result{} + } + } + + switch os.Getenv("CTHULHU_VTE_MODE") { + case "nano": + if result := read(Line, 0); !strings.HasPrefix(result.FlatPosition.Text, "Row 00000 ") { + t.Fatalf("nano initial file line: %+v", result.FlatPosition) + } + for row := 1; row <= 30; row++ { + result := read(Line, 1) + if !strings.HasPrefix(result.FlatPosition.Text, fmt.Sprintf("Row %05d ", row)) { + t.Fatalf("nano row %d: %+v", row, result.FlatPosition) + } + if row == 30 && result.FlatPosition.Offset <= 4096 { + t.Fatalf("nano probe did not exceed old text limit: %+v", result.FlatPosition) + } + } + if result := read(Word, 1); strings.TrimSpace(result.FlatPosition.Text) != "00030" { + t.Fatalf("nano word: %+v", result.FlatPosition) + } + if result := read(Character, 0); result.FlatPosition.Text != "0" { + t.Fatalf("nano character: %+v", result.FlatPosition) + } + return + case "large": + if result := read(Line, 0); !strings.HasPrefix(result.FlatPosition.Text, "Row 49 ") || result.FlatPosition.Offset <= 4096 { + t.Fatalf("large terminal caret: %+v", result.FlatPosition) + } + read(WindowStart, 0) + for row := 0; row < 50; row++ { + step := 1 + if row == 0 { + step = 0 + } + result := read(Line, step) + if !strings.HasPrefix(result.FlatPosition.Text, fmt.Sprintf("Row %02d ", row)) || !result.FlatPosition.HasOffset { + t.Fatalf("large terminal row %d: %+v", row, result.FlatPosition) + } + } + if result := read(Character, 0); result.FlatPosition.Text != "R" || result.FlatPosition.Offset <= 4096 { + t.Fatalf("large terminal character: %+v", result.FlatPosition) + } + if result := read(Word, 1); strings.TrimSpace(result.FlatPosition.Text) != "49" || result.FlatPosition.Offset <= 4096 { + t.Fatalf("large terminal word: %+v", result.FlatPosition) + } + return + case "prompt": + if result := read(Line, 0); strings.TrimSpace(result.FlatPosition.Text) != "Café 猫>" { + t.Fatalf("prompt flat review: %+v", result.FlatPosition) + } + // Generate a fresh native focus event after the adapter has started. + // ReadFocusedText requires the GLib owner's current focus reference. + window := os.Getenv("CTHULHU_TREE_WINDOW") + if err := exec.CommandContext(ctx, "xdotool", "windowfocus", "0", "windowfocus", window).Run(); err != nil { + t.Fatal(err) + } + for { + select { + case event := <-adapter.Events(): + if event.Source.ID() == focus && event.Type == "object:state-changed:focused" && event.Detail1 == 1 { + goto focused + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + } + focused: + if err := worker.ReadAll(ctx); err != nil { + t.Fatal(err) + } + select { + case result := <-worker.Results(): + if result.Err != nil || len(result.ReadAllLines) != 1 || strings.TrimSpace(result.ReadAllLines[0].Contents[0].Text) != "Café 猫>" { + t.Fatalf("terminal prompt Say All: %+v", result) + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + return + } + + for _, tc := range []struct { + unit FlatUnit + step int + text string + mustMove bool + }{ + {WindowStart, 0, "Café 猫", false}, + {Line, 1, "", false}, + {Character, 0, "", false}, + {Line, 0, "", false}, + {Line, 1, "Second line", false}, + {Line, 1, "Third line", false}, + {Line, 1, "", false}, + {Word, 1, "", true}, + {Word, -1, "", true}, + {Line, -1, "Third line", false}, + {WindowEnd, 0, "", false}, + {Line, 1, "", false}, + {Character, 0, "", false}, + {WindowStart, 0, "Café 猫", false}, + {Word, 1, "猫", false}, + {Character, 0, "猫", false}, + } { + result := read(tc.unit, tc.step) + if strings.TrimSpace(result.FlatPosition.Text) != tc.text || !result.FlatPosition.HasOffset || (tc.mustMove && !result.Moved) { + t.Fatalf("unit=%v step=%d: %+v moved=%v, want %q with source offset", tc.unit, tc.step, result.FlatPosition, result.Moved, tc.text) + } + } +} diff --git a/internal/review/flat_pluma_native_test.go b/internal/review/flat_pluma_native_test.go new file mode 100644 index 0000000..09b563a --- /dev/null +++ b/internal/review/flat_pluma_native_test.go @@ -0,0 +1,81 @@ +package review + +import ( + "context" + "os" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// Run with a private Xvfb and D-Bus session, a visible Pluma window, and a +// short document containing "Alpha beta" on its first line. +func TestNativePageTabEditorFlatReview(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_PAGE_TAB_EDITOR") != "1" { + t.Skip("requires a private Pluma fixture") + } + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + adapter := atspi.New() + if err := adapter.Start(ctx); err != nil { + t.Fatal(err) + } + defer adapter.Stop(context.Background()) + tree, err := adapter.CaptureDesktop(ctx) + if err != nil { + t.Fatal(err) + } + root, err := tree.Root() + if err != nil { + t.Fatal(err) + } + var focus atspi.ObjectID + queue := []atspi.ObjectReference{root} + for len(queue) > 0 { + ref := queue[0] + queue = queue[1:] + snapshot, err := tree.Resolve(ref) + if err != nil { + t.Fatal(err) + } + if snapshot.ApplicationName == "pluma" && snapshot.Role == "text" { + geometry, err := tree.Geometry(ref) + if err != nil { + t.Fatal(err) + } + if geometry.Showing { + focus = snapshot.ID() + } + } + for child, ok, err := tree.FirstChild(ref); ok && err == nil; child, ok, err = tree.NextSibling(child) { + queue = append(queue, child) + } + } + if !focus.Valid() { + t.Fatal("visible Pluma editor not found") + } + reviewTree, err := adapter.CaptureReviewWindow(ctx, focus) + if err != nil { + t.Fatal(err) + } + cursor := &FlatCursor{} + if err := cursor.Refresh(ctx, reviewTree, focus); err != nil { + t.Fatal(err) + } + for _, tc := range []struct { + unit FlatUnit + step int + want string + }{ + {Word, 0, "Alpha"}, + {Character, 1, "l"}, + {Word, 1, "beta"}, + } { + position, _, err := cursor.Read(tc.unit, tc.step) + if err != nil || position.Object != focus || !position.HasOffset || strings.TrimSpace(position.Text) != tc.want { + t.Fatalf("unit=%v step=%d: position=%+v err=%v", tc.unit, tc.step, position, err) + } + } +} diff --git a/internal/review/flat_robustness_test.go b/internal/review/flat_robustness_test.go new file mode 100644 index 0000000..66b5a9c --- /dev/null +++ b/internal/review/flat_robustness_test.go @@ -0,0 +1,170 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestFlatReviewRetainsHealthyContentAndReportsOmissions(t *testing.T) { + for _, issue := range []atspi.VisibleText{ + {Limited: true, Issue: atspi.TextCharacterLimit}, + {Issue: atspi.TextProviderFailure}, + } { + bad := flatNode("/bad", "", 0, 30) + bad.Snapshot.Name = "Unavailable object name must not replace its text" + bad.Text = issue + good := flatNode("/good", "Readable content", 0, 0) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), flatTree(t, good, bad), objectID("/good")); err != nil { + t.Fatal(err) + } + position, _, err := cursor.Read(Line, 0) + if err != nil || position.Text != "Readable content" || cursor.completeness.OmittedObjects != 1 { + t.Fatalf("partial review = %+v, %+v, %v", position, cursor.completeness, err) + } + if _, moved, err := cursor.Read(Line, 1); err != nil || moved { + t.Fatalf("omitted object's name became content: moved=%v err=%v", moved, err) + } + } +} + +func TestFlatReviewReportsUnavailableChildrenWithoutDroppingParentText(t *testing.T) { + parent := flatNode("/parent", "Parent text", 0, 0) + parent.ChildrenUnavailable = true + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), flatTree(t, parent), parent.Snapshot.ID()); err != nil { + t.Fatal(err) + } + position, _, err := cursor.Read(Line, 0) + if err != nil || position.Text != "Parent text" || cursor.completeness.UnavailableSubtrees != 1 { + t.Fatalf("partial subtree = %+v, %+v, %v", position, cursor.completeness, err) + } +} + +func TestFlatReviewReportsUnavailableChildrenWithoutComponentBounds(t *testing.T) { + parent := node("/parent", "") + parent.Geometry = atspi.Geometry{VisibilityKnown: true, Visible: true, Showing: true} + parent.ChildrenUnavailable = true + good := flatNode("/good", "Readable", 0, 0) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), flatTree(t, parent, good), good.Snapshot.ID()); err != nil { + t.Fatal(err) + } + if cursor.completeness.UnavailableSubtrees != 1 { + t.Fatalf("missing component bounds hid a failed subtree: %+v", cursor.completeness) + } +} + +func TestFlatReviewAnchorsPrunedFocusAtDisplayedParent(t *testing.T) { + before := flatNode("/before", "Unrelated first line", 0, 0) + parent := flatNode("/parent", "Focused parent text", 0, 30) + leaf := node("/leaf", "") + parent.Children = []atspi.ObjectID{leaf.Snapshot.ID()} + root := flatNode("/window", "", 0, 0) + root.Text = atspi.VisibleText{} + root.Geometry.Bounds.Height = 100 + root.Snapshot.Role = "frame" + root.Children = []atspi.ObjectID{before.Snapshot.ID(), parent.Snapshot.ID()} + tree, err := atspi.NewAccessibleTree(root.Snapshot.ID(), []atspi.TreeNode{root, before, parent, leaf}) + if err != nil { + t.Fatal(err) + } + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, leaf.Snapshot.ID()); err != nil { + t.Fatal(err) + } + position, _, err := cursor.Read(Line, 0) + if err != nil || position.Object != parent.Snapshot.ID() || position.Text != "Focused parent text" { + t.Fatalf("pruned focus anchor = %+v, %v", position, err) + } +} + +func TestFlatWorkerWarnsOnceAndClearsRecoveredCompleteness(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + defer worker.Stop(context.Background()) + good := flatNode("/good", "Readable", 0, 0) + bad := flatNode("/bad", "Unavailable", 0, 30) + bad.Text = atspi.VisibleText{Limited: true} + tree := flatTree(t, good, bad) + worker.SyncFocus(good.Snapshot.ID()) + worker.ReadFlat(Line, 0) + call := <-capturer.calls + call.result <- captureResult{tree: tree} + for index := 0; index < 2; index++ { + if index != 0 { + worker.ReadFlat(Character, 0) + } + result := waitResult(t, worker) + if result.Err != nil || !result.FlatCompleteness.Incomplete() || result.FlatWarning != (index == 0) { + t.Fatalf("partial result %d: %+v", index, result) + } + } + bad = flatNode("/bad", "Recovered", 0, 30) + fresh := flatTree(t, good, bad) + snapshot, err := fresh.ReviewWindow(context.Background(), good.Snapshot.ID()) + if err != nil { + t.Fatal(err) + } + if err := tree.Replace(objectID("/window"), snapshot.Nodes); err != nil { + t.Fatal(err) + } + worker.ReadFlat(Line, 1) + result := waitResult(t, worker) + if result.Err != nil || result.FlatCompleteness.Incomplete() || result.FlatWarning || result.FlatPosition.Text != "Recovered" { + t.Fatalf("recovery result = %+v", result) + } +} + +func TestFlatReviewCompositeControlKeepsLabelBesideChildAction(t *testing.T) { + for _, role := range []string{"page tab", "menu item"} { + for _, withLabel := range []bool{false, true} { + t.Run(role+map[bool]string{false: " action only", true: " with text label"}[withLabel], func(t *testing.T) { + parent := flatNode("/parent", "", 0, 0) + parent.Snapshot.Role, parent.Snapshot.Name = role, "Primary label" + parent.Text = atspi.VisibleText{Known: true} + child := flatNode("/child", "", 150, 0) + child.Geometry.Bounds.Width = 20 + child.Snapshot.Role, child.Snapshot.Name = "button", "Close" + child.Text = atspi.VisibleText{} + parent.Children = []atspi.ObjectID{child.Snapshot.ID()} + nodes := []atspi.TreeNode{parent, child} + if withLabel { + label := flatNode("/label", "Primary label", 0, 0) + label.Snapshot.Role = "static" + label.Geometry.Bounds.Width = 100 + label.Text.Ranges[0].Bounds = label.Geometry.Bounds + parent.Children = append(parent.Children, label.Snapshot.ID()) + nodes[0] = parent + nodes = append(nodes, label) + } + lines, status, err := build_flat_layout(context.Background(), nodes) + if err != nil || status.Incomplete() { + t.Fatalf("layout: %+v %v", status, err) + } + names, actions := 0, 0 + for _, line := range lines { + for _, zone := range line.zones { + if zone.text == "Primary label" { + names++ + } + if zone.text == "Close" { + actions++ + } + } + } + if names != 1 || actions != 1 { + t.Fatalf("label count=%d action count=%d", names, actions) + } + }) + } + } +} diff --git a/internal/review/flat_test.go b/internal/review/flat_test.go new file mode 100644 index 0000000..ad0073f --- /dev/null +++ b/internal/review/flat_test.go @@ -0,0 +1,546 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "strings" + "testing" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func flatNode(path, text string, x, y int32) atspi.TreeNode { + n := node(path, "") + n.Geometry = atspi.Geometry{Bounds: atspi.Rectangle{X: x, Y: y, Width: 200, Height: 20}, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + n.Text = atspi.VisibleText{Known: true, Ranges: []atspi.TextRange{{Text: text, Start: 0, End: utf8.RuneCountInString(text), Bounds: n.Geometry.Bounds}}} + return n +} + +func flatTree(t *testing.T, nodes ...atspi.TreeNode) *atspi.AccessibleTree { + t.Helper() + root := node("/window", "Example Window") + root.Snapshot.Role = "frame" + root.Geometry = atspi.Geometry{Bounds: atspi.Rectangle{X: -500, Y: -500, Width: 2000, Height: 2000}, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + for _, n := range nodes { + root.Children = append(root.Children, n.Snapshot.ID()) + } + tree, err := atspi.NewAccessibleTree(objectID("/window"), append([]atspi.TreeNode{root}, nodes...)) + if err != nil { + t.Fatal(err) + } + return tree +} + +func TestFlatReviewSpeaksSharedHeadingTextOnce(t *testing.T) { + heading := flatNode("/heading", "Reading section", 0, 0) + heading.Snapshot.Role = "heading" + heading.Children = []atspi.ObjectID{objectID("/text")} + child := flatNode("/text", "Reading section", 0, 0) + child.Snapshot.Role = "static" + root := node("/window", "") + root.Snapshot.Role = "frame" + root.Geometry = heading.Geometry + root.Children = []atspi.ObjectID{objectID("/heading")} + tree, err := atspi.NewAccessibleTree(objectID("/window"), []atspi.TreeNode{root, heading, child}) + if err != nil { + t.Fatal(err) + } + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/heading")); err != nil { + t.Fatal(err) + } + position, _, err := cursor.Read(Line, 0) + if err != nil || position.Text != "Reading section" { + t.Fatalf("repeated heading text: position=%+v err=%v", position, err) + } +} + +func TestFlatReviewPageTabHeaderDoesNotClipPageContent(t *testing.T) { + frame := node("/window", "") + frame.Snapshot.Role = "frame" + frame.Geometry = atspi.Geometry{Bounds: atspi.Rectangle{Width: 300, Height: 200}, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + frame.Children = []atspi.ObjectID{objectID("/tab"), objectID("/hidden_tab")} + tab := node("/tab", "") + tab.Snapshot.Role = "page tab" + tab.Geometry = atspi.Geometry{Bounds: atspi.Rectangle{Width: 100, Height: 20}, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + tab.Children = []atspi.ObjectID{objectID("/editor")} + editor := flatNode("/editor", "Alpha beta", 0, 40) + editor.Snapshot.Role = "text" + hiddenTab := node("/hidden_tab", "") + hiddenTab.Snapshot.Role = "page tab" + hiddenTab.Geometry = atspi.Geometry{VisibilityKnown: true, Visible: true, Showing: false} + hiddenTab.Children = []atspi.ObjectID{objectID("/hidden_editor")} + hiddenEditor := flatNode("/hidden_editor", "Should stay hidden", 0, 80) + tree, err := atspi.NewAccessibleTree(objectID("/window"), []atspi.TreeNode{frame, tab, editor, hiddenTab, hiddenEditor}) + if err != nil { + t.Fatal(err) + } + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/editor")); err != nil { + t.Fatal(err) + } + for _, tc := range []struct { + unit FlatUnit + step int + text string + moved bool + }{ + {Word, 0, "Alpha ", false}, + {Character, 1, "l", true}, + {Word, 1, "beta", true}, + } { + position, moved, err := cursor.Read(tc.unit, tc.step) + if err != nil || position.Object != objectID("/editor") || position.Text != tc.text || moved != tc.moved { + t.Fatalf("unit=%v step=%d: position=%+v moved=%v err=%v", tc.unit, tc.step, position, moved, err) + } + } + if position, moved, err := cursor.Read(Line, 1); err != nil || moved || position.Object != objectID("/editor") { + t.Fatalf("hidden page entered review: position=%+v moved=%v err=%v", position, moved, err) + } +} + +func TestFlatReadingOrderAndUnicodeNavigation(t *testing.T) { + // Tree order deliberately differs from the screen order. + tree := flatTree(t, flatNode("/bottom", "next", 0, 40), flatNode("/right", "right", 250, 2), flatNode("/left", "é🙂 one", -100, 0)) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/left")); err != nil { + t.Fatal(err) + } + for _, tc := range []struct { + unit FlatUnit + step int + text string + offset int + moved bool + }{ + {Line, 0, "é🙂 one right", 0, false}, + {Character, 1, "🙂", 1, true}, + {Character, 1, " ", 2, true}, + {Word, 1, "one", 3, true}, + {Word, 1, "right", 0, true}, + {Word, 1, "next", 0, true}, + {Line, 1, "next", 0, false}, + {Character, -1, "t", 4, true}, + {Line, -1, "é🙂 one right", 4, false}, + } { + got, moved, err := cursor.Read(tc.unit, tc.step) + if err != nil || got.Text != tc.text || got.Offset != tc.offset || moved != tc.moved || !got.HasOffset { + t.Fatalf("unit=%d step=%d: %#v moved=%v err=%v", tc.unit, tc.step, got, moved, err) + } + } +} + +func TestFlatWindowStartAndEnd(t *testing.T) { + tree := flatTree(t, flatNode("/first", "first", 0, 0), flatNode("/last", "last", 0, 40)) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/last")); err != nil { + t.Fatal(err) + } + if got, moved, err := cursor.Read(WindowStart, 0); err != nil || !moved || got.Text != "first" { + t.Fatalf("start: %#v moved=%v err=%v", got, moved, err) + } + if got, moved, err := cursor.Read(WindowEnd, 0); err != nil || !moved || got.Text != "last" { + t.Fatalf("end: %#v moved=%v err=%v", got, moved, err) + } + if got, moved, err := cursor.Read(Character, 0); err != nil || moved || got.Text != "t" { + t.Fatalf("end character: %#v moved=%v err=%v", got, moved, err) + } +} + +func TestFlatVerticalWordsAndLineEnd(t *testing.T) { + bottom := flatNode("/bottom", "four", 100, 40) + firstTop := flatNode("/first", "one", 0, 0) + firstTop.Geometry.Bounds.Width = 100 + firstTop.Text.Ranges[0].Bounds.Width = 100 + secondTop := flatNode("/second", "two", 100, 0) + tree := flatTree(t, firstTop, secondTop, bottom) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/bottom")); err != nil { + t.Fatal(err) + } + if _, moved, err := cursor.Read(Character, 1); err != nil || !moved { + t.Fatalf("position character: moved=%v err=%v", moved, err) + } + got, moved, err := cursor.Read(WordAbove, 0) + if err != nil || !moved || got.Object != objectID("/second") || got.Text != "two" || got.Offset != 0 { + t.Fatalf("above: got=%+v moved=%v err=%v", got, moved, err) + } + got, moved, err = cursor.Read(WordBelow, 0) + if err != nil || !moved || got.Object != objectID("/bottom") || got.Text != "four" || got.Offset != 0 { + t.Fatalf("below: got=%+v moved=%v err=%v", got, moved, err) + } + got, moved, err = cursor.Read(LineEnd, 0) + if err != nil || !moved || got.Object != objectID("/bottom") || got.Text != "r" || got.Offset != 3 { + t.Fatalf("line end: got=%+v moved=%v err=%v", got, moved, err) + } + got, moved, err = cursor.Read(LineEnd, 0) + if err != nil || moved || got.Text != "r" || got.Offset != 3 { + t.Fatalf("line end repeat: got=%+v moved=%v err=%v", got, moved, err) + } + if _, _, err := cursor.Read(WindowStart, 0); err != nil { + t.Fatal(err) + } + got, moved, err = cursor.Read(WordAbove, 0) + if err != nil || moved || got.Text != "one" { + t.Fatalf("top boundary: got=%+v moved=%v err=%v", got, moved, err) + } +} + +func TestFlatVerticalMovementPreservesHorizontalTarget(t *testing.T) { + top := flatNode("/top", "abcd", 0, 0) + middle := flatNode("/middle", "ab", 0, 40) + bottom := flatNode("/bottom", "abcd", 0, 80) + for _, node := range []*atspi.TreeNode{&top, &middle, &bottom} { + node.Geometry.Bounds.Width = 100 + node.Text.Ranges[0].Bounds.Width = 100 + } + tree := flatTree(t, top, middle, bottom) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/top")); err != nil { + t.Fatal(err) + } + if _, moved, err := cursor.Read(Character, 1); err != nil || !moved { + t.Fatalf("position character: moved=%v err=%v", moved, err) + } + if _, moved, err := cursor.Read(WordBelow, 0); err != nil || !moved { + t.Fatalf("first below: moved=%v err=%v", moved, err) + } + // The worker refreshes the cursor before every request. The original + // horizontal target must survive that refresh for consecutive moves. + if err := cursor.Refresh(context.Background(), tree, objectID("/top")); err != nil { + t.Fatal(err) + } + if _, moved, err := cursor.Read(WordBelow, 0); err != nil || !moved { + t.Fatalf("second below: moved=%v err=%v", moved, err) + } + got, _, err := cursor.Read(Character, 0) + if err != nil || got.Object != objectID("/bottom") || got.Text != "b" || got.Offset != 1 { + t.Fatalf("preserved target: got=%+v err=%v", got, err) + } + for _, tc := range []struct { + unit FlatUnit + step int + object string + character string + }{ + {WordAbove, 0, "/middle", "a"}, + {WordAbove, 0, "/top", "b"}, + {LineEnd, 0, "/top", "d"}, + {WordBelow, 0, "/middle", "b"}, + {WordBelow, 0, "/bottom", "d"}, + {Character, -1, "/bottom", "c"}, + {WordAbove, 0, "/middle", "b"}, + {WordAbove, 0, "/top", "c"}, + } { + if _, _, err := cursor.Read(tc.unit, tc.step); err != nil { + t.Fatal(err) + } + got, _, err := cursor.Read(Character, 0) + if err != nil || got.Object != objectID(tc.object) || got.Text != tc.character { + t.Fatalf("unit %d: got=%+v err=%v", tc.unit, got, err) + } + } + if err := cursor.Refresh(context.Background(), tree, objectID("/bottom")); err != nil { + t.Fatal(err) + } + if _, _, err := cursor.Read(WordAbove, 0); err != nil { + t.Fatal(err) + } + got, _, err = cursor.Read(Character, 0) + if err != nil || got.Text != "a" { + t.Fatalf("changed focus retained old target: got=%+v err=%v", got, err) + } +} + +func TestFlatRefreshPreservesPositionAndHonorsChangedFocus(t *testing.T) { + tree := flatTree(t, flatNode("/a", "a", 0, 0), flatNode("/b", "b🙂", 0, 30)) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/a")); err != nil { + t.Fatal(err) + } + cursor.Read(Line, 1) + cursor.Read(Character, 1) + if err := cursor.Refresh(context.Background(), tree, objectID("/a")); err != nil { + t.Fatal(err) + } + got, _, _ := cursor.Read(Character, 0) + if got.Object != objectID("/b") || got.Text != "🙂" || got.Offset != 1 { + t.Fatalf("lost independent position: %#v", got) + } + tree.InvalidateText(objectID("/b")) + if err := cursor.Refresh(context.Background(), tree, objectID("/a")); !errors.Is(err, atspi.ErrStaleText) { + t.Fatal(err) + } + got, _, _ = cursor.Read(Character, 0) + if got.Text != "🙂" { + t.Fatal("failed refresh mutated position") + } + tree = flatTree(t, flatNode("/a", "a", 0, 0), flatNode("/b", "b🙂", 0, 30), flatNode("/c", "c", 0, 60)) + if err := cursor.Refresh(context.Background(), tree, objectID("/c")); err != nil { + t.Fatal(err) + } + got, _, _ = cursor.Read(Character, 0) + if got.Text != "c" { + t.Fatalf("changed focus ignored: %#v", got) + } +} + +func TestFlatSyntheticNamesHiddenAndPasswordText(t *testing.T) { + password := flatNode("/password", "secret", 0, 30) + password.Snapshot.Role = "password text" + password.Snapshot.Name = "Password" + hidden := node("/hidden", "Hidden content") + button := flatNode("/button", "unused", 0, 0) + button.Text = atspi.VisibleText{} + button.Snapshot.Name = "Save" + tree := flatTree(t, button, password, hidden) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/button")); err != nil { + t.Fatal(err) + } + got, _, _ := cursor.Read(Word, 0) + if got.Text != "Save" || got.HasOffset { + t.Fatalf("synthetic name: %#v", got) + } + got, _, _ = cursor.Read(Line, 1) + if got.Text != "Password" || got.HasOffset { + t.Fatalf("password: %#v", got) + } + if len(cursor.lines) != 2 { + t.Fatalf("hidden/container content leaked: %#v", cursor.lines) + } +} + +func TestFlatClusteringDoesNotChainRowsAndKeepsRTLLogicalText(t *testing.T) { + nodes := []atspi.TreeNode{flatNode("/a", "אבג", 0, 0), flatNode("/b", "b", 250, 5), flatNode("/c", "c", 500, 10)} + lines, err := buildFlatLines(context.Background(), nodes) + if err != nil || len(lines) != 2 || len(lines[0].zones) != 2 || lines[0].zones[0].text != "אבג" { + t.Fatalf("lines=%#v err=%v", lines, err) + } +} + +func TestFlatRejectsLimitedEmptyAndInvalidRequests(t *testing.T) { + limited := flatNode("/large", "x", 0, 0) + limited.Text = atspi.VisibleText{Limited: true} + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), flatTree(t, limited), objectID("/large")); !errors.Is(err, ErrLimitedReview) { + t.Fatal(err) + } + if _, _, err := cursor.Read(Line, 0); !errors.Is(err, ErrNoReviewContent) { + t.Fatal(err) + } + if _, _, err := cursor.Read(0, 0); !errors.Is(err, ErrInvalidDirection) { + t.Fatal(err) + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := buildFlatLines(ctx, []atspi.TreeNode{limited}); !errors.Is(err, context.Canceled) { + t.Fatal(err) + } +} + +func TestFlatWordWhitespaceAndCharacterBoundaries(t *testing.T) { + tree := flatTree(t, flatNode("/a", "one two", 0, 0), flatNode("/space", " ", 0, 30), flatNode("/b", "三", 0, 60)) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/a")); err != nil { + t.Fatal(err) + } + got, moved, _ := cursor.Read(Character, -1) + if moved || got.Text != "o" { + t.Fatalf("start boundary: %#v %v", got, moved) + } + for _, text := range []string{"two", "三"} { + got, moved, err := cursor.Read(Word, 1) + if err != nil || !moved || strings.TrimSpace(got.Text) != text { + t.Fatalf("word: %#v %v %v", got, moved, err) + } + } + got, moved, _ = cursor.Read(Word, 1) + if moved || got.Text != "三" { + t.Fatalf("end boundary: %#v %v", got, moved) + } + got, moved, _ = cursor.Read(Word, -1) + if !moved || got.Text != "two" { + t.Fatalf("previous word: %#v %v", got, moved) + } +} + +func TestFlatClippedCharacterRunsKeepWordsAndOffsetGaps(t *testing.T) { + n := flatNode("/a", "x", 0, 0) + n.Text.Ranges = []atspi.TextRange{ + {Start: 2, End: 3, Text: "猫", Bounds: atspi.Rectangle{X: 0, Y: 0, Width: 12, Height: 20}}, + {Start: 3, End: 4, Text: "a", Bounds: atspi.Rectangle{X: 12, Y: 0, Width: 10, Height: 20}}, + {Start: 7, End: 8, Text: "z", Bounds: atspi.Rectangle{X: 80, Y: 0, Width: 10, Height: 20}}, + } + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), flatTree(t, n), objectID("/a")); err != nil { + t.Fatal(err) + } + got, _, _ := cursor.Read(Line, 0) + if got.Text != "猫a z" || got.Offset != 2 { + t.Fatalf("fragmented line: %#v", got) + } + got, _, _ = cursor.Read(Word, 0) + if got.Text != "猫a" { + t.Fatalf("fragmented word: %#v", got) + } + got, _, _ = cursor.Read(Word, 1) + if got.Text != "z" || got.Offset != 7 { + t.Fatalf("offset gap lost: %#v", got) + } +} + +func TestFlatClipsSyntheticNamesAndSuppressesHiddenDescendants(t *testing.T) { + parent := flatNode("/parent", "unused", 0, 0) + parent.Text = atspi.VisibleText{} + parent.Snapshot.Name = "Container" + child := flatNode("/child", "unused", 150, 0) + child.Text = atspi.VisibleText{} + child.Snapshot.Name = "Button" + parent.Children = []atspi.ObjectID{child.Snapshot.ID()} + lines, err := buildFlatLines(context.Background(), []atspi.TreeNode{parent, child}) + if err != nil || len(lines) != 1 || len(lines[0].zones) != 1 || lines[0].zones[0].bounds.Width != 50 { + t.Fatalf("clipping: %#v %v", lines, err) + } + parent.Geometry = atspi.Geometry{VisibilityKnown: true} + if _, err := buildFlatLines(context.Background(), []atspi.TreeNode{parent, child}); !errors.Is(err, ErrNoReviewContent) { + t.Fatalf("hidden descendant: %v", err) + } +} + +func TestFlatCaretAndSyntheticCharacterPosition(t *testing.T) { + n := flatNode("/a", "ab🙂", 0, 0) + n.Text.CaretKnown, n.Text.CaretOffset = true, 2 + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), flatTree(t, n), objectID("/a")); err != nil { + t.Fatal(err) + } + got, _, _ := cursor.Read(Character, 0) + if got.Text != "🙂" || got.Offset != 2 { + t.Fatalf("caret: %#v", got) + } + cursor = &FlatCursor{} + n.Text.CaretOffset = 3 + if err := cursor.Refresh(context.Background(), flatTree(t, n), objectID("/a")); err != nil { + t.Fatal(err) + } + got, _, _ = cursor.Read(Character, 0) + if got.Text != "" || got.Offset != 3 { + t.Fatalf("end caret: %#v", got) + } + got, moved, _ := cursor.Read(Character, -1) + if !moved || got.Text != "🙂" { + t.Fatalf("before end caret: %#v", got) + } + n.Text = atspi.VisibleText{} + n.Snapshot.Name = "Save" + tree := flatTree(t, n) + cursor = &FlatCursor{} + for _, want := range []string{"a", "v", "e"} { + if err := cursor.Refresh(context.Background(), tree, objectID("/a")); err != nil { + t.Fatal(err) + } + got, moved, err := cursor.Read(Character, 1) + if err != nil || !moved || got.Text != want { + t.Fatalf("synthetic position: %#v %v", got, err) + } + } +} + +func TestFlatModelBoundsSyntheticText(t *testing.T) { + var nodes []atspi.TreeNode + for i := 0; i < 300; i++ { + n := flatNode("/a", "x", 0, int32(i*20)) + n.Text = atspi.VisibleText{} + n.Snapshot.Name = strings.Repeat("a", 4096) + nodes = append(nodes, n) + } + if _, err := buildFlatLines(context.Background(), nodes); !errors.Is(err, ErrLimitedReview) { + t.Fatal(err) + } +} + +func TestFlatDoesNotRestoreReusedObjectIdentity(t *testing.T) { + tree := flatTree(t, flatNode("/a", "Focus", 0, 0), flatNode("/b", "Original", 0, 30)) + cursor := &FlatCursor{} + if err := cursor.Refresh(context.Background(), tree, objectID("/a")); err != nil { + t.Fatal(err) + } + cursor.Read(Line, 1) + tree.Invalidate(objectID("/b")) + fresh := flatTree(t, flatNode("/a", "Focus", 0, 0), flatNode("/b", "Replacement", 0, 30)) + snapshot, err := fresh.ReviewWindow(context.Background(), objectID("/a")) + if err != nil { + t.Fatal(err) + } + if err := tree.Replace(objectID("/window"), snapshot.Nodes); err != nil { + t.Fatal(err) + } + if err := cursor.Refresh(context.Background(), tree, objectID("/a")); err != nil { + t.Fatal(err) + } + got, _, _ := cursor.Read(Line, 0) + if got.Text != "Focus" { + t.Fatalf("reused identity inherited position: %#v", got) + } +} + +func TestFlatBlankRowsAcrossReviewUnits(t *testing.T) { + n := flatNode("/terminal", "a", 0, 0) + n.Geometry.Bounds.Height = 80 + n.Text.Ranges = []atspi.TextRange{ + {Start: 0, End: 1, Text: "a", Bounds: atspi.Rectangle{Width: 20, Height: 20}}, + {Start: 2, End: 3, Text: "\n", Bounds: atspi.Rectangle{Y: 20, Width: 20, Height: 20}}, + {Start: 3, End: 4, Text: "b", Bounds: atspi.Rectangle{Y: 40, Width: 20, Height: 20}}, + {Start: 5, End: 6, Text: "\n", Bounds: atspi.Rectangle{Y: 60, Width: 20, Height: 20}}, + } + tree := flatTree(t, n) + cursor := &FlatCursor{} + for _, tc := range []struct { + unit FlatUnit + step int + text string + offset int + moved bool + }{ + {Line, 1, "\n", 2, true}, + {Character, 0, "\n", 2, false}, + {Line, 0, "\n", 2, false}, + {Line, 1, "b", 3, true}, + {Word, -1, "\n", 2, true}, + {Word, -1, "a", 0, true}, + {Word, 1, "\n", 2, true}, + {Word, 1, "b", 3, true}, + {WindowEnd, 0, "\n", 5, true}, + {Line, 1, "\n", 5, false}, + {WindowStart, 0, "a", 0, true}, + {Character, 1, "\n", 2, true}, + {Character, 1, "b", 3, true}, + } { + if err := cursor.Refresh(context.Background(), tree, n.Snapshot.ID()); err != nil { + t.Fatal(err) + } + got, moved, err := cursor.Read(tc.unit, tc.step) + if err != nil || got.Text != tc.text || got.Offset != tc.offset || moved != tc.moved { + t.Fatalf("%+v: got=%+v moved=%v err=%v", tc, got, moved, err) + } + } +} diff --git a/internal/review/flat_worker.go b/internal/review/flat_worker.go new file mode 100644 index 0000000..fc67a71 --- /dev/null +++ b/internal/review/flat_worker.go @@ -0,0 +1,139 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// SetFlatOrigin starts a new flat-review context at the browse caret without +// changing native focus. Once review begins, its cursor moves independently. +func (worker *Worker) SetFlatOrigin(object atspi.ObjectID, offset int) { + worker.stateMutex.Lock() + worker.flatOrigin, worker.flatOffset = object, offset + worker.stateMutex.Unlock() +} + +func (worker *Worker) flatStart() (atspi.ObjectID, int) { + worker.stateMutex.Lock() + defer worker.stateMutex.Unlock() + return worker.flatOrigin, worker.flatOffset +} + +// FlatSpeech controls the speech of a review result without moving its cursor. +type FlatSpeech uint8 + +const ( + FlatSpeak FlatSpeech = iota + FlatSpell + FlatPhonetic +) + +// ReadFlat queues sequential review on the same bounded FIFO as object review. +// Capacity is 16; overflow rejects the newest request and is reported to the +// caller. Results retain FIFO order in a 16-result queue; a stalled consumer +// blocks only this worker. Cancellation discards pending work and joins it. +func (worker *Worker) ReadFlat(unit FlatUnit, step int) error { + return worker.ReadFlatWithSpeech(unit, step, FlatSpeak) +} + +// ReadFlatWithSpeech retains presentation policy with its FIFO request, so a +// later press cannot change the speech of an earlier asynchronous result. +func (worker *Worker) ReadFlatWithSpeech(unit FlatUnit, step int, style FlatSpeech) error { + if unit < Line || unit > LineEnd || step < -1 || step > 1 || (unit > Character && step != 0) { + return ErrInvalidDirection + } + if style > FlatPhonetic || (style != FlatSpeak && (step != 0 || (unit != Word && unit != Character))) { + return ErrInvalidDirection + } + select { + case worker.requests <- request{documentEpoch: worker.documentEpoch.Load(), unit: unit, step: step, flatSpeech: style}: + return nil + default: + return ErrRequestQueueFull + } +} + +func (worker *Worker) readFlat(ctx context.Context, cursor *FlatCursor, tree *atspi.AccessibleTree, unit FlatUnit, step int) (Result, *atspi.AccessibleTree) { + focus := worker.focus() + result := Result{FlatUnit: unit, FlatStep: step, FlatFocus: focus} + if !focus.Valid() { + result.Err = ErrNoCurrent + return result, tree + } + fresh := false + if policy, ok := worker.capturer.(FreshReviewWindowCapturer); ok { + fresh = policy.FreshReviewWindow(focus) + } + var err error + if !fresh { + err = cursor.Refresh(ctx, tree, focus) + } + if fresh || errors.Is(err, ErrNoCurrent) || errors.Is(err, atspi.ErrObjectNotFound) || errors.Is(err, atspi.ErrStaleObject) || errors.Is(err, atspi.ErrIncompleteTree) || errors.Is(err, atspi.ErrStaleText) || errors.Is(err, atspi.ErrStaleGeometry) { + result.CaptureReason = err + timeout := worker.flatCaptureTimeout + if fresh { + timeout = min(timeout, 500*time.Millisecond) + } + captureContext, cancel := context.WithTimeout(ctx, timeout) + captureStarted := time.Now() + captured, captureErr := worker.capturer.CaptureReviewWindow(captureContext, focus) + result.CaptureDuration = time.Since(captureStarted) + cancel() + if captureErr != nil { + result.Err = captureErr + return result, tree + } + if captured == nil { + result.Err = errors.New("capture flat review tree: nil tree") + return result, tree + } + tree = captured + // Capture can outlive a focus transition. Use the newest identity and + // refresh only once: repeated invalidation cannot cause a retry loop. + result.FlatFocus = worker.focus() + err = cursor.Refresh(ctx, tree, result.FlatFocus) + } + if err != nil { + result.Err = err + return result, tree + } + if cursor.focus == focus && !cursor.started { + if origin, offset := worker.flatStart(); origin.Valid() { + if !cursor.seek(origin, offset, true) { + if !cursor.seek(origin, 0, false) { + if !cursor.seekDescendant(origin) { + cursor.seek_ancestor(origin) + } + } + } + } + cursor.started = true + } + result.FlatPosition, result.Moved, result.Err = cursor.Read(unit, step) + result.FlatCompleteness = cursor.completeness + if result.Err == nil && cursor.completeness.Incomplete() && !cursor.warnedIncomplete { + result.FlatWarning = true + cursor.warnedIncomplete = true + } + return result, tree +} diff --git a/internal/review/flat_worker_test.go b/internal/review/flat_worker_test.go new file mode 100644 index 0000000..23c7485 --- /dev/null +++ b/internal/review/flat_worker_test.go @@ -0,0 +1,265 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type freshFlatCapturer struct{ *fakeCapturer } + +func (*freshFlatCapturer) FreshReviewWindow(atspi.ObjectID) bool { return true } +func TestFlatWorkerFreshProviderPreservesCursor(t *testing.T) { + capturer := &freshFlatCapturer{&fakeCapturer{calls: make(chan captureCall, 1)}} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + defer worker.Stop(context.Background()) + worker.SyncFocus(objectID("/a")) + tree := flatTree(t, flatNode("/a", "alpha beta", 0, 0)) + for i, step := range []int{0, 1, 0} { + worker.ReadFlat(Word, step) + var call captureCall + select { + case call = <-capturer.calls: + case <-time.After(time.Second): + t.Fatal("command reused cached text") + } + if i == 2 { + fresh := flatTree(t, flatNode("/a", "omega zeta", 0, 0)) + snapshot, _ := fresh.ReviewWindow(context.Background(), objectID("/a")) + if err := tree.Replace(objectID("/window"), snapshot.Nodes); err != nil { + t.Fatal(err) + } + } + call.result <- captureResult{tree: tree} + got := waitResult(t, worker) + want := []string{"alpha ", "beta", "zeta"}[i] + if got.Err != nil || got.FlatPosition.Text != want { + t.Fatalf("cursor: %+v want=%s", got, want) + } + } +} +func TestFlatWorkerFreshProviderFailureDoesNotSpeakCachedText(t *testing.T) { + capturer := &freshFlatCapturer{&fakeCapturer{calls: make(chan captureCall, 1)}} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + defer worker.Stop(context.Background()) + worker.SyncFocus(objectID("/a")) + worker.ReadFlat(Line, 0) + call := <-capturer.calls + call.result <- captureResult{tree: flatTree(t, flatNode("/a", "secret old text", 0, 0))} + waitResult(t, worker) + worker.ReadFlat(Line, 0) + select { + case call = <-capturer.calls: + case <-time.After(time.Second): + t.Fatal("failed freshness policy reused cached text") + } + call.result <- captureResult{err: context.DeadlineExceeded} + result := waitResult(t, worker) + if !errors.Is(result.Err, context.DeadlineExceeded) || result.FlatPosition.Text != "" { + t.Fatalf("cached output: %+v", result) + } +} + +func TestFlatWorkerRecapturesOnceAndHonorsFocusDuringCapture(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + defer worker.Stop(context.Background()) + worker.SyncFocus(objectID("/a")) + if err := worker.ReadFlat(Line, 0); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + if call.reviewFocus != objectID("/a") { + t.Fatalf("review capture focus = %#v", call.reviewFocus) + } + worker.SyncFocus(objectID("/b")) + tree := flatTree(t, flatNode("/a", "First", 0, 0), flatNode("/b", "Second", 0, 30)) + call.result <- captureResult{tree: tree} + if result := waitResult(t, worker); result.Err != nil || result.FlatPosition.Text != "Second" { + t.Fatalf("result=%#v", result) + } + worker.ReadFlat(Line, -1) + if result := waitResult(t, worker); result.Err != nil || result.FlatPosition.Text != "First" { + t.Fatalf("result=%#v", result) + } + tree.InvalidateText(objectID("/a")) + worker.ReadFlat(Line, 0) + call = <-capturer.calls + // A provider that remains stale after one recapture must fail, not loop. + call.result <- captureResult{tree: tree} + if result := waitResult(t, worker); !errors.Is(result.Err, atspi.ErrStaleText) || result.FlatPosition.Text != "" { + t.Fatalf("result=%#v", result) + } + worker.ReadFlat(Line, 0) + call = <-capturer.calls + fresh := flatTree(t, flatNode("/a", "Refreshed", 0, 0), flatNode("/b", "Second", 0, 30)) + snapshot, err := fresh.ReviewWindow(context.Background(), objectID("/a")) + if err != nil { + t.Fatal(err) + } + if err := tree.Replace(objectID("/window"), snapshot.Nodes); err != nil { + t.Fatal(err) + } + call.result <- captureResult{tree: tree} + if result := waitResult(t, worker); result.Err != nil || result.FlatPosition.Text != "Refreshed" { + t.Fatalf("independent position lost: %#v", result) + } +} + +func TestFlatWorkerPreservesQueuedSpeechStyles(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + defer worker.Stop(context.Background()) + worker.SyncFocus(objectID("/a")) + for _, style := range []FlatSpeech{FlatSpeak, FlatSpell, FlatPhonetic} { + if err := worker.ReadFlatWithSpeech(Word, 0, style); err != nil { + t.Fatal(err) + } + } + call := <-capturer.calls + call.result <- captureResult{tree: flatTree(t, flatNode("/a", "book", 0, 0))} + for _, style := range []FlatSpeech{FlatSpeak, FlatSpell, FlatPhonetic} { + result := waitResult(t, worker) + if result.Err != nil || result.FlatSpeech != style || result.FlatPosition.Text != "book" { + t.Fatalf("queued style=%d result=%#v", style, result) + } + } +} + +func TestFlatWorkerStartsAtBrowsePositionThenMovesIndependently(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + defer worker.Stop(context.Background()) + worker.SyncFocus(objectID("/window")) + worker.SetFlatOrigin(objectID("/b"), 0) + if err := worker.ReadFlat(Line, 0); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + call.result <- captureResult{tree: flatTree(t, flatNode("/a", "First", 0, 0), flatNode("/b", "Second", 0, 30))} + if result := waitResult(t, worker); result.Err != nil || result.FlatPosition.Text != "Second" { + t.Fatalf("initial browse position: %+v", result) + } + worker.SetFlatOrigin(objectID("/a"), 0) + if err := worker.ReadFlat(Line, 0); err != nil { + t.Fatal(err) + } + if result := waitResult(t, worker); result.Err != nil || result.FlatPosition.Text != "Second" { + t.Fatalf("flat cursor followed later browse movement: %+v", result) + } +} + +func TestFlatWorkerCaptureCancellationAndQueueBounds(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + worker.SyncFocus(objectID("/a")) + worker.ReadFlat(Line, 0) + call := <-capturer.calls + for i := 0; i < requestCapacity; i++ { + if err := worker.ReadFlat(Word, 1); err != nil { + t.Fatal(err) + } + } + if err := worker.ReadFlat(Character, 1); !errors.Is(err, ErrRequestQueueFull) { + t.Fatal(err) + } + stopCtx, stopCancel := context.WithTimeout(context.Background(), time.Second) + defer stopCancel() + if err := worker.Stop(stopCtx); err != nil { + t.Fatal(err) + } + if !errors.Is(call.ctx.Err(), context.Canceled) { + t.Fatal("capture was not canceled") + } +} + +func TestFlatWorkerUsesSeparateCaptureDeadline(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, err := NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + if err := worker.SetFlatCaptureTimeout(10 * time.Second); err != nil { + t.Fatal(err) + } + if err := worker.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer worker.Stop(context.Background()) + if err := worker.SetFlatCaptureTimeout(time.Second); err == nil { + t.Fatal("changed flat review deadline while worker was running") + } + worker.SyncFocus(objectID("/a")) + if err := worker.ReadFlat(Line, 0); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + deadline, ok := call.ctx.Deadline() + if !ok || time.Until(deadline) < 8*time.Second { + t.Fatalf("flat review capture deadline = %v, present = %t", deadline, ok) + } + call.result <- captureResult{tree: flatTree(t, flatNode("/a", "Visible", 0, 0))} + if result := waitResult(t, worker); result.Err != nil || result.FlatPosition.Text != "Visible" { + t.Fatalf("flat review = %+v", result) + } +} + +func TestFlatWorkerAcceptsVerticalAndLineEndUnits(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + defer worker.Stop(context.Background()) + worker.SyncFocus(objectID("/bottom")) + for index, tc := range []struct { + unit FlatUnit + text string + }{ + {WordAbove, "first"}, + {WordBelow, "last"}, + {LineEnd, "t"}, + } { + if err := worker.ReadFlat(tc.unit, 0); err != nil { + t.Fatalf("unit %d: %v", tc.unit, err) + } + if index == 0 { + select { + case call := <-capturer.calls: + call.result <- captureResult{tree: flatTree(t, flatNode("/top", "first", 0, 0), flatNode("/bottom", "last", 0, 40))} + case <-time.After(time.Second): + t.Fatal("flat review capture did not start") + } + } + if result := waitResult(t, worker); result.Err != nil || result.FlatUnit != tc.unit || result.FlatPosition.Text != tc.text || !result.Moved { + t.Fatalf("unit %d: result=%+v", tc.unit, result) + } + } + if err := worker.ReadFlat(LineEnd, 1); !errors.Is(err, ErrInvalidDirection) { + t.Fatalf("line end step: %v", err) + } +} diff --git a/internal/review/interest.go b/internal/review/interest.go new file mode 100644 index 0000000..dbcf025 --- /dev/null +++ b/internal/review/interest.go @@ -0,0 +1,111 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// Interest belongs to the review worker. Zone bounds are provider coordinates; +// callers must resolve fresh source/window geometry before screen capture. +// A flat zone must never silently fall back to the larger object's bounds. +type Interest struct { + Offset int // -1 means use the native caret; virtual browser carets supply an offset. + Object atspi.ObjectID + Zone atspi.Rectangle + HasZone bool +} + +type interestMode uint8 + +const ( + implicitInterest interestMode = iota + objectInterest + flatInterest +) + +type interestReply struct { + interest Interest + err error +} +type interestRequest struct { + ctx context.Context + result chan interestReply +} + +// ObjectOfInterest is ordered with navigation, and never captures a tree. Call +// it on a worker. Explicit review wins over a virtual browser caret, then focus. +// Failed/stale explicit review returns an error instead of capturing focus. +func (worker *Worker) ObjectOfInterest(ctx context.Context) (Interest, error) { + if err := ctx.Err(); err != nil { + return Interest{}, err + } + worker.stateMutex.Lock() + done, started := worker.done, worker.started + worker.stateMutex.Unlock() + if !started { + return Interest{}, errors.New("review worker is not running") + } + select { + case <-done: + return Interest{}, ErrNoCurrent + default: + } + query := &interestRequest{ctx: ctx, result: make(chan interestReply, 1)} + select { + case worker.requests <- request{interest: query}: + case <-ctx.Done(): + return Interest{}, ctx.Err() + case <-done: + return Interest{}, ErrNoCurrent + } + select { + case reply := <-query.result: + return reply.interest, reply.err + case <-ctx.Done(): + return Interest{}, ctx.Err() + case <-done: + return Interest{}, ErrNoCurrent + } +} + +func resolve_interest(ctx context.Context, focus atspi.ObjectID, explicit interestMode, cursor *Cursor, flat *FlatCursor, flatTree *atspi.AccessibleTree, document *DocumentCursor) (Interest, error) { + if err := ctx.Err(); err != nil { + return Interest{}, err + } + if !focus.Valid() { + return Interest{}, ErrNoCurrent + } + switch explicit { + case objectInterest: + if cursor == nil { + return Interest{}, ErrNoCurrent + } + position, err := cursor.Current() + return Interest{Object: position.Current.ID(), Offset: -1}, err + case flatInterest: + if err := flat.Refresh(ctx, flatTree, focus); err != nil { + return Interest{}, err + } + position := flat.position(Character) + if !position.Bounds.Valid() { + return Interest{}, atspi.ErrStaleGeometry + } + return Interest{Object: position.Object, Offset: -1, Zone: position.Bounds, HasZone: true}, nil + } + if document != nil { + position, err := document.SyncFocus(ctx, focus) + if err == nil && position.Origin != NativeNavigation { + return Interest{Object: position.Object.ID(), Offset: position.Offset}, nil + } + if err != nil && !errors.Is(err, atspi.ErrNotInDocument) && !errors.Is(err, atspi.ErrObjectNotFound) { + return Interest{}, err + } + } + return Interest{Object: focus, Offset: -1}, nil +} diff --git a/internal/review/interest_test.go b/internal/review/interest_test.go new file mode 100644 index 0000000..559ff0f --- /dev/null +++ b/internal/review/interest_test.go @@ -0,0 +1,132 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +func TestObjectInterestIsOrderedAndPreservesExplicitReview(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + defer worker.Stop(context.Background()) + worker.SyncFocus(objectID("/first")) + ctx, stop := context.WithTimeout(context.Background(), time.Second) + defer stop() + got, err := worker.ObjectOfInterest(ctx) + if err != nil || got.Object != objectID("/first") { + t.Fatalf("focus interest: %+v %v", got, err) + } + worker.Move(NextSibling) + call := <-capturer.calls + replies := make(chan interestReply, 1) + go func() { interest, err := worker.ObjectOfInterest(ctx); replies <- interestReply{interest, err} }() + tree := newTree(t) + call.result <- captureResult{tree: tree} + if result := waitResult(t, worker); result.Err != nil { + t.Fatal(result.Err) + } + reply := <-replies + if reply.err != nil || reply.interest.Object != objectID("/second") { + t.Fatalf("explicit review snapped to focus: %+v", reply) + } + worker.SyncFocus(objectID("/grandchild")) + worker.SyncFocus(objectID("/first")) + got, err = worker.ObjectOfInterest(ctx) + if err != nil || got.Object != objectID("/first") { + t.Fatalf("away/back retained explicit review: %+v %v", got, err) + } + worker.SyncFocus(objectID("/grandchild")) + got, err = worker.ObjectOfInterest(ctx) + if err != nil || got.Object != objectID("/grandchild") { + t.Fatalf("changed focus: %+v %v", got, err) + } + worker.Move(Parent) + if result := waitResult(t, worker); result.Err != nil { + t.Fatal(result.Err) + } + tree.Invalidate(objectID("/second")) + if _, err = worker.ObjectOfInterest(ctx); err == nil { + t.Fatal("stale explicit interest fell back to focus") + } + worker.ClearFocus() + if _, err = worker.ObjectOfInterest(ctx); !errors.Is(err, ErrNoCurrent) { + t.Fatalf("clear focus: %v", err) + } +} + +func TestFlatInterestUsesZoneAndDoesNotRecapture(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + defer worker.Stop(context.Background()) + worker.SyncFocus(objectID("/b")) + worker.ReadFlat(Line, 0) + call := <-capturer.calls + tree := flatTree(t, flatNode("/a", "First", 0, 0), flatNode("/b", "Second", 0, 30)) + call.result <- captureResult{tree: tree} + waitResult(t, worker) + worker.ReadFlat(Line, -1) + position := waitResult(t, worker).FlatPosition + ctx, cancelQuery := context.WithTimeout(context.Background(), time.Second) + defer cancelQuery() + got, err := worker.ObjectOfInterest(ctx) + if err != nil || got.Object != objectID("/a") || !got.HasZone || got.Zone != position.Bounds { + t.Fatalf("zone: %+v %v", got, err) + } + tree.InvalidateGeometry(objectID("/a")) + if _, err = worker.ObjectOfInterest(ctx); !errors.Is(err, atspi.ErrStaleGeometry) { + t.Fatalf("stale zone: %v", err) + } + select { + case <-capturer.calls: + t.Fatal("interest recaptured a tree") + default: + } +} + +func TestInterestPrefersVirtualCaretThenExplicitReview(t *testing.T) { + ctx := context.Background() + reader := caretTextReader{webID("/text"): "First line", webID("/next"): "Last line"} + document := newCaretTextCursor(t, reader) + if _, err := document.SyncFocus(ctx, webID("/text")); err != nil { + t.Fatal(err) + } + if _, err := document.MoveCaret(ctx, reader, CaretNextLine); err != nil { + t.Fatal(err) + } + got, err := resolve_interest(ctx, webID("/text"), 0, nil, nil, nil, document) + if err != nil || got.Object != webID("/next") { + t.Fatalf("virtual caret: %+v %v", got, err) + } + cursor, _ := NewCursor(newTree(t)) + cursor.SyncFocus(objectID("/first")) + cursor.Move(NextSibling) + got, err = resolve_interest(ctx, webID("/text"), 1, cursor, nil, nil, document) + if err != nil || got.Object != objectID("/second") { + t.Fatalf("explicit precedence: %+v %v", got, err) + } +} + +func TestInterestCancelledAndStopped(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + ctx, stop := context.WithCancel(context.Background()) + stop() + if _, err := worker.ObjectOfInterest(ctx); !errors.Is(err, context.Canceled) { + t.Fatalf("cancel: %v", err) + } + cancel() + worker.Stop(context.Background()) + if _, err := worker.ObjectOfInterest(context.Background()); !errors.Is(err, ErrNoCurrent) { + t.Fatalf("stop: %v", err) + } +} diff --git a/internal/review/object_worker.go b/internal/review/object_worker.go new file mode 100644 index 0000000..5fe1c72 --- /dev/null +++ b/internal/review/object_worker.go @@ -0,0 +1,112 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "fmt" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type moveResult struct { + Result + cursor *Cursor +} + +func (worker *Worker) move(ctx context.Context, cursor *Cursor, direction Direction) moveResult { + var err error + cursor, err = worker.syncLatestFocus(ctx, cursor, true) + if err != nil { + return moveResult{Result: Result{Direction: direction, Err: err}, cursor: cursor} + } + if cursor == nil { + return moveResult{Result: Result{Direction: direction, Err: ErrNoCurrent}} + } + position, moved, err := cursor.Move(direction) + if err == nil { + return moveResult{Result: Result{Direction: direction, Position: position, Moved: moved}, cursor: cursor} + } + if !errors.Is(err, atspi.ErrStaleObject) && !errors.Is(err, atspi.ErrIncompleteTree) { + return moveResult{Result: Result{Direction: direction, Err: err}, cursor: cursor} + } + + // An incomplete child list needs recapture without abandoning an otherwise + // live independent review position. Stale objects still recover from focus. + var retained *Cursor + if errors.Is(err, atspi.ErrIncompleteTree) { + retained = cursor + } + recovered, recoveryErr := worker.captureCursor(ctx, retained) + if recoveryErr != nil { + return moveResult{Result: Result{Direction: direction, Err: recoveryErr}, cursor: retained} + } + if recovered == nil { + return moveResult{Result: Result{Direction: direction, Err: err}} + } + position, moved, err = recovered.Move(direction) + return moveResult{Result: Result{Direction: direction, Position: position, Moved: moved, Err: err}, cursor: recovered} +} + +func (worker *Worker) syncLatestFocus(ctx context.Context, cursor *Cursor, captureIfMissing bool) (*Cursor, error) { + focus := worker.focus() + if !focus.Valid() { + return cursor, nil + } + if cursor != nil { + _, currentErr := cursor.Current() + _, syncErr := cursor.SyncFocus(focus) + if syncErr == nil && !errors.Is(currentErr, atspi.ErrStaleObject) { + return cursor, nil + } + if syncErr != nil && !errors.Is(syncErr, atspi.ErrObjectNotFound) && !errors.Is(syncErr, atspi.ErrStaleObject) { + return cursor, syncErr + } + } + if !captureIfMissing && cursor == nil { + return nil, nil + } + + return worker.captureCursor(ctx, nil) +} + +func (worker *Worker) captureCursor(ctx context.Context, cursor *Cursor) (*Cursor, error) { + captureContext, cancelCapture := context.WithTimeout(ctx, worker.captureTimeout) + tree, err := worker.capturer.CaptureDesktop(captureContext) + cancelCapture() + if err != nil { + return nil, fmt.Errorf("capture object review tree: %w", err) + } + if tree == nil { + return nil, errors.New("capture object review tree: nil tree") + } + if cursor == nil || cursor.tree != tree { + cursor, err = NewCursor(tree) + if err != nil { + return nil, err + } + } + // Focus can change while capture is underway. Always synchronize to the + // newest identity after the capture returns. + focus := worker.focus() + if _, err := cursor.SyncFocus(focus); err != nil { + return nil, err + } + return cursor, nil +} diff --git a/internal/review/read_all.go b/internal/review/read_all.go new file mode 100644 index 0000000..4a8de0f --- /dev/null +++ b/internal/review/read_all.go @@ -0,0 +1,227 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "strings" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// Assemble from a private cursor: collecting speech must not move the user's +// browse position to the end before any of it has actually been spoken. +func (worker *Worker) readAll(ctx context.Context, cursor *DocumentCursor) Result { + result := Result{DocumentFocus: worker.focus()} + if !result.DocumentFocus.Valid() { + result.Err = ErrNoCurrent + return result + } + if cursor != nil { + cursor = &DocumentCursor{tree: cursor.tree, active: cursor.active, places: append([]documentPlace(nil), cursor.places...)} + var saved documentPlace + if len(cursor.places) > 0 { + saved = cursor.places[len(cursor.places)-1] + } + position, err := cursor.SyncFocus(ctx, result.DocumentFocus) + result.Err = err + if err == nil && saved.document.Valid() && (saved.focus.ID() == result.DocumentFocus || saved.object.ID() == result.DocumentFocus) && saved.document != position.Document { + result.Err = errors.New("read all: document changed") + return result + } + } else { + result.Err = ErrNoCurrent + } + if documentNeedsCapture(result.Err) { + cursor, result.Err = worker.refresh_read_all_cursor(ctx, cursor, result.DocumentFocus) + } + if documentNeedsCapture(result.Err) { + cursor, result.Err = worker.refresh_read_all_cursor(ctx, cursor, result.DocumentFocus) + } + if errors.Is(result.Err, atspi.ErrNotInDocument) { + if reader, ok := worker.nativeCapturerFor(result.DocumentFocus).(interface { + ReadFocusedText(context.Context, atspi.ObjectID) (atspi.DocumentContent, error) + }); ok { + deadline, cancel := context.WithTimeout(ctx, worker.captureTimeout) + defer cancel() + var content atspi.DocumentContent + content, result.Err = reader.ReadFocusedText(deadline, result.DocumentFocus) + if result.Err == nil { + result.ReadAllLines = focusedReadAllLines(content) + epoch := worker.documentEpoch.Load() + result.ReadAllProgress = func(index int) { + if index < 0 || index >= len(result.ReadAllLines) || content.Text == "" { + return + } + part := result.ReadAllLines[index].Contents[0] + part.Snapshot.Text = part.Text + position := DocumentPosition{Offset: part.Start, Snapshot: part.Snapshot} + select { + case worker.requests <- request{documentEpoch: epoch, readPosition: &position, readFocus: result.DocumentFocus}: + default: + } + } + } + } + return result + } + if result.Err != nil { + return result + } + reader, ok := worker.nativeCapturerFor(result.DocumentFocus).(DocumentCaretReader) + if !ok { + result.Err = errors.New("read all: document text reader unavailable") + return result + } + command := CaretReadLine + var previous DocumentPosition + var positions []DocumentPosition + epoch := worker.documentEpoch.Load() + result.ReadAllProgress = func(index int) { + if index < 0 || index >= len(positions) { + return + } + position := positions[index] + select { + case worker.requests <- request{documentEpoch: epoch, readPosition: &position, readTree: cursor.tree, readFocus: result.DocumentFocus}: + default: + } + } + bytes := 0 + var movement DocumentCaretMove + var err error + for { + if err := ctx.Err(); err != nil { + result.Err = err + return result + } + movement, cursor, err = worker.readAllMove(ctx, cursor, reader, command, result.DocumentFocus) + if err != nil { + result.Err = err + return result + } + if !movement.Moved { + return result + } + if command == CaretNextLine && movement.Position.Object == previous.Object && movement.Position.Offset <= previous.Offset { + result.Err = errors.New("read all: text provider did not advance") + return result + } + previous = movement.Position + movement.Position.Snapshot.Misspelled = movement.Misspelled + line := atspi.DocumentLine{Document: movement.Position.Document, Contents: []atspi.DocumentContent{{Snapshot: movement.Position.Snapshot, Text: movement.Text, RawText: movement.RawText}}} + owner, err := cursor.tree.DocumentContext(movement.Position.Object) + if err != nil { + if !documentNeedsCapture(err) { + result.Err = err + return result + } + refreshed, refreshErr := worker.refresh_read_all_cursor(ctx, cursor, result.DocumentFocus) + if refreshErr != nil { + result.Err = refreshErr + return result + } + cursor = refreshed + owner = atspi.DocumentContext{} + } else { + line.Context = owner.Ancestors + roles := map[string]bool{movement.Position.Snapshot.Role: true} + for _, ancestor := range owner.Ancestors { + if (ancestor.Role == "link" || ancestor.Role == "heading") && !roles[ancestor.Role] { + roles[ancestor.Role] = true + ancestor.Name = "" + line.Contents = append(line.Contents, atspi.DocumentContent{Snapshot: ancestor}) + } + } + } + bytes += len(movement.Text) + len(movement.Position.Snapshot.Name) + if bytes > 1<<20 || len(result.ReadAllLines) >= 32768 { + result.Err = errors.New("read all: document exceeds speech capture limit") + return result + } + result.ReadAllLines = append(result.ReadAllLines, line) + positions = append(positions, movement.Position) + command = CaretNextLine + } +} + +func (worker *Worker) readAllMove(ctx context.Context, cursor *DocumentCursor, reader DocumentCaretReader, command DocumentCaretCommand, focus atspi.ObjectID) (DocumentCaretMove, *DocumentCursor, error) { + deadline, cancel := context.WithTimeout(ctx, worker.captureTimeout) + movement, err := cursor.MoveCaret(deadline, reader, command) + cancel() + if err == nil || !documentNeedsCapture(err) { + return movement, cursor, err + } + cursor, refreshErr := worker.refresh_read_all_cursor(ctx, cursor, focus) + if refreshErr != nil { + return movement, cursor, refreshErr + } + deadline, cancel = context.WithTimeout(ctx, worker.captureTimeout) + defer cancel() + movement, err = cursor.MoveCaret(deadline, reader, command) + return movement, cursor, err +} + +func (worker *Worker) followReadAll(ctx context.Context, cursor *DocumentCursor, request request) (*DocumentCursor, bool) { + if !request.readPosition.Document.Valid() { + if setter, ok := worker.nativeCapturerFor(request.readFocus).(interface { + SetFocusedTextCaret(context.Context, atspi.ObjectID, int) error + }); ok { + deadline, cancel := context.WithTimeout(ctx, worker.captureTimeout) + defer cancel() + return cursor, setter.SetFocusedTextCaret(deadline, request.readFocus, request.readPosition.Offset) == nil + } + return cursor, false + } + if cursor == nil || cursor.tree != request.readTree { + cursor, _ = NewDocumentCursor(request.readTree) + } + if cursor == nil { + return nil, false + } + current, err := cursor.SyncFocus(ctx, request.readFocus) + position := request.readPosition + if err != nil || current.Document.ID() != position.Document.ID() { + return cursor, false + } + // A page can be recaptured while Say All is being assembled. Earlier + // lines retain references from the old tree, so bind the spoken object's + // identity to the tree that will receive the progress update. + object, err := cursor.tree.Reference(position.Object.ID()) + if err != nil { + return cursor, false + } + owner, err := cursor.tree.DocumentContext(object) + if err != nil || owner.TopLevel != current.Document { + return cursor, false + } + snapshot, err := cursor.tree.Resolve(object) + if err != nil || position.Offset < 0 || position.Offset > snapshot.CharacterCount { + return cursor, false + } + position.Document, position.Object, position.Snapshot = current.Document, object, snapshot + place := &cursor.places[len(cursor.places)-1] + place.object, place.offset, place.origin = object, position.Offset, CaretNavigation + return cursor, true +} + +func focusedReadAllLines(content atspi.DocumentContent) []atspi.DocumentLine { + if content.Text == "" { + return []atspi.DocumentLine{{Contents: []atspi.DocumentContent{content}}} + } + var lines []atspi.DocumentLine + offset := content.Start + for _, value := range strings.SplitAfter(content.Text, "\n") { + part := content + part.Start, part.End, part.Text = offset, offset+utf8.RuneCountInString(value), value + offset = part.End + if strings.TrimSpace(value) != "" { + lines = append(lines, atspi.DocumentLine{Contents: []atspi.DocumentContent{part}}) + } + } + return lines +} diff --git a/internal/review/read_all_test.go b/internal/review/read_all_test.go new file mode 100644 index 0000000..24e9b92 --- /dev/null +++ b/internal/review/read_all_test.go @@ -0,0 +1,218 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package review + +import ( + "context" + "errors" + "strings" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type readAllCapturer struct { + *fakeCapturer + caretTextReader + tree *atspi.AccessibleTree + nativePlacements int +} + +func (capturer *readAllCapturer) CaptureDocument(ctx context.Context, _ atspi.ObjectID) (*atspi.AccessibleTree, error) { + return capturer.tree, ctx.Err() +} + +type sequenceReadAllCapturer struct { + *fakeCapturer + caretTextReader + trees []*atspi.AccessibleTree + index int + invalidateTree *atspi.AccessibleTree + staleOnce bool + staleAt int + reads int + invalidateAfter bool +} + +func (capturer *sequenceReadAllCapturer) CaptureDocument(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) { + if capturer.index >= len(capturer.trees) { + return nil, errors.New("no more trees") + } + tree := capturer.trees[capturer.index] + capturer.index++ + return tree, nil +} + +func (capturer *sequenceReadAllCapturer) ReadDocumentCaret(ctx context.Context, reference atspi.ObjectReference, offset int, unit atspi.DocumentCaretUnit) (atspi.DocumentCaretText, error) { + capturer.reads++ + if capturer.staleOnce || capturer.staleAt == capturer.reads { + capturer.staleOnce = false + capturer.invalidateTree.InvalidateSnapshot(reference.ID()) + return atspi.DocumentCaretText{}, atspi.ErrStaleSnapshot + } + result, err := capturer.caretTextReader.ReadDocumentCaret(ctx, reference, offset, unit) + if capturer.invalidateAfter { + capturer.invalidateAfter = false + capturer.invalidateTree.InvalidateSnapshot(reference.ID()) + } + return result, err +} + +func TestReadAllProgressRebindsEarlierLineAfterRecapture(t *testing.T) { + text := caretTextReader{webID("/text"): "First\nSecond\n", webID("/next"): "Last"} + cursor := newCaretTextCursor(t, text) + fresh := newCaretTextCursor(t, text).tree + // Give the recaptured text a new generation, as happens when a provider + // removes and recreates the object while keeping its accessible path. + fresh.Invalidate(webID("/text")) + nodes := make([]atspi.TreeNode, 0, 3) + for _, path := range []string{"/doc", "/text", "/next"} { + snapshot := atspi.NewSnapshot(path, "", "static", "", "") + snapshot.BusName = webID(path).BusName + snapshot.CharacterCount = len([]rune(text[webID(path)])) + node := atspi.TreeNode{Snapshot: snapshot} + if path == "/doc" { + node.Snapshot.Role = "document web" + node.Children = []atspi.ObjectID{webID("/text"), webID("/next")} + } + nodes = append(nodes, node) + } + if err := fresh.Replace(webID("/doc"), nodes); err != nil { + t.Fatal(err) + } + capturer := &sequenceReadAllCapturer{ + caretTextReader: text, trees: []*atspi.AccessibleTree{fresh}, + invalidateTree: cursor.tree, staleAt: 2, + } + worker, _ := NewWorker(capturer, time.Second) + worker.SyncFocus(webID("/text")) + result := worker.readAll(context.Background(), cursor) + if result.Err != nil || len(result.ReadAllLines) < 2 { + t.Fatalf("read all after recapture: %+v", result) + } + result.ReadAllProgress(0) + request := <-worker.requests + if request.readTree != fresh { + t.Fatal("progress did not use recaptured tree") + } + followedCursor, followed := worker.followReadAll(context.Background(), cursor, request) + if !followed || followedCursor.places[len(followedCursor.places)-1].object != request.readPosition.Object { + t.Fatalf("first spoken line did not move the browse cursor after recapture: %+v", request.readPosition) + } + current, err := fresh.Reference(webID("/text")) + if err != nil || request.readPosition.Object != current { + t.Fatalf("spoken line did not rebind to the current object: %v, %v", request.readPosition.Object, err) + } +} + +func TestReadAllRetriesSecondStaleSnapshotCapture(t *testing.T) { + text := caretTextReader{webID("/text"): "First\nSecond\n", webID("/next"): "Last"} + stale := newCaretTextCursor(t, text).tree + stale.InvalidateSnapshot(webID("/text")) + fresh := newCaretTextCursor(t, text).tree + capturer := &sequenceReadAllCapturer{caretTextReader: text, trees: []*atspi.AccessibleTree{stale, fresh}} + worker, _ := NewWorker(capturer, time.Second) + worker.SyncFocus(webID("/text")) + cursor := newCaretTextCursor(t, text) + cursor.tree.InvalidateSnapshot(webID("/text")) + result := worker.readAll(context.Background(), cursor) + if result.Err != nil || len(result.ReadAllLines) == 0 { + t.Fatalf("read all after stale snapshot retry: %+v", result) + } +} + +func TestReadAllRetriesStaleLineMovementWithoutSkipping(t *testing.T) { + text := caretTextReader{webID("/text"): "First\nSecond\n", webID("/next"): "Last"} + cursor := newCaretTextCursor(t, text) + fresh := newCaretTextCursor(t, text).tree + secondFresh := newCaretTextCursor(t, text).tree + thirdFresh := newCaretTextCursor(t, text).tree + fourthFresh := newCaretTextCursor(t, text).tree + capturer := &sequenceReadAllCapturer{ + caretTextReader: text, + trees: []*atspi.AccessibleTree{fresh, secondFresh, thirdFresh, fourthFresh}, + invalidateTree: cursor.tree, + staleOnce: true, + } + worker, _ := NewWorker(capturer, time.Second) + worker.SyncFocus(webID("/text")) + result := worker.readAll(context.Background(), cursor) + if result.Err != nil || len(result.ReadAllLines) < 2 { + t.Fatalf("read all stale line movement retry: %+v", result) + } +} + +func TestReadAllContinuesWhenAncestorContextBecomesStale(t *testing.T) { + text := caretTextReader{webID("/text"): "First\nSecond\n", webID("/next"): "Last"} + cursor := newCaretTextCursor(t, text) + fresh := newCaretTextCursor(t, text).tree + capturer := &sequenceReadAllCapturer{ + caretTextReader: text, + trees: []*atspi.AccessibleTree{fresh, fresh}, + invalidateTree: cursor.tree, + invalidateAfter: true, + } + worker, _ := NewWorker(capturer, time.Second) + worker.SyncFocus(webID("/text")) + result := worker.readAll(context.Background(), cursor) + if result.Err != nil || len(result.ReadAllLines) < 2 { + t.Fatalf("read all stale ancestor context: %+v", result) + } +} + +func (capturer *readAllCapturer) SetDocumentCaretPosition(context.Context, atspi.ObjectReference, atspi.ObjectID, int) error { + capturer.nativePlacements++ + return nil +} + +func TestReadAllStartsAtUnicodeOffsetAndPreservesCursorUntilSpeech(t *testing.T) { + text := caretTextReader{webID("/text"): "Café 猫\nSecond line\n", webID("/next"): "Last line"} + cursor := newCaretTextCursor(t, text) + cursor.places[0].offset = 5 + reader := &readAllCapturer{caretTextReader: text, tree: cursor.tree} + worker, _ := NewWorker(reader, time.Second) + worker.SyncFocus(webID("/text")) + result := worker.readAll(context.Background(), cursor) + if result.Err != nil { + t.Fatal(result.Err) + } + var lines []string + for _, line := range result.ReadAllLines { + lines = append(lines, strings.TrimSpace(line.Contents[0].Text)) + } + if got := strings.Join(lines, "|"); got != "猫|Second line|Last line" { + t.Fatalf("read all = %q", got) + } + if cursor.places[0].offset != 5 || cursor.places[0].object.ID() != webID("/text") { + t.Fatal("capture advanced user's cursor before speech") + } + result.ReadAllProgress(1) + request := <-worker.requests + cursor, _ = worker.followReadAll(context.Background(), cursor, request) + if cursor.places[0].offset != 7 { + t.Fatalf("speech progress offset = %d", cursor.places[0].offset) + } + if reader.nativePlacements != 0 { + t.Fatalf("read-all progress moved the native caret %d times", reader.nativePlacements) + } + resumed := worker.readAll(context.Background(), cursor) + if resumed.Err != nil || strings.TrimSpace(resumed.ReadAllLines[0].Contents[0].Text) != "Second line" { + t.Fatalf("resumed = %+v", resumed) + } +} + +func TestReadAllCancellation(t *testing.T) { + text := caretTextReader{webID("/text"): "First", webID("/next"): "Last"} + cursor := newCaretTextCursor(t, text) + worker, _ := NewWorker(&readAllCapturer{caretTextReader: text, tree: cursor.tree}, time.Second) + worker.SyncFocus(webID("/text")) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + result := worker.readAll(ctx, cursor) + if !errors.Is(result.Err, context.Canceled) || len(result.ReadAllLines) != 0 { + t.Fatalf("canceled read all = %+v", result) + } +} diff --git a/internal/review/worker.go b/internal/review/worker.go new file mode 100644 index 0000000..64fbe97 --- /dev/null +++ b/internal/review/worker.go @@ -0,0 +1,401 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "fmt" + "sync" + "sync/atomic" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +const ( + requestCapacity = 16 + resultCapacity = 16 +) + +var ErrRequestQueueFull = errors.New("object review request queue is full") + +// Worker owns the runtime review cursor and every potentially blocking tree +// capture. Focus updates are coalesced to the newest identity. Navigation +// requests remain ordered. After a document timeout, queued document commands +// are retired so an unavailable provider cannot build a backlog of failures. +type Worker struct { + capturer TreeCapturer + captureTimeout time.Duration + flatCaptureTimeout time.Duration + documentCaptureTimeout time.Duration + + stateMutex sync.Mutex + latestFocus atspi.ObjectID + focusRevision uint64 + flatOrigin atspi.ObjectID + flatOffset int + started bool + cancel context.CancelFunc + done chan struct{} + + wakeFocus chan struct{} + requests chan request + results chan Result + lineSequence atomic.Uint64 + documentEpoch atomic.Uint64 + documentBraille atomic.Bool +} + +// SetDocumentBrailleEnabled avoids extra native line reads while braille is off. +func (worker *Worker) SetDocumentBrailleEnabled(enabled bool) { + worker.documentBraille.Store(enabled) +} + +// ResetDocument retires queued work and cursors for the previous page, even +// when the provider reuses accessible paths after navigation. +func (worker *Worker) ResetDocument(focus atspi.ObjectID) { + worker.stateMutex.Lock() + worker.latestFocus = focus + worker.focusRevision++ + worker.flatOrigin = atspi.ObjectID{} + worker.documentEpoch.Add(1) + worker.stateMutex.Unlock() + select { + case worker.wakeFocus <- struct{}{}: + default: + } +} + +func (worker *Worker) CurrentDocumentResult(result Result) bool { + return result.DocumentEpoch == worker.documentEpoch.Load() +} + +func (worker *Worker) DocumentEpoch() uint64 { return worker.documentEpoch.Load() } + +func NewWorker(capturer TreeCapturer, captureTimeout time.Duration) (*Worker, error) { + if capturer == nil { + return nil, errors.New("create object review worker: nil tree capturer") + } + if captureTimeout <= 0 { + return nil, errors.New("create object review worker: capture timeout must be positive") + } + return &Worker{ + capturer: capturer, + captureTimeout: captureTimeout, + flatCaptureTimeout: captureTimeout, + documentCaptureTimeout: captureTimeout, + wakeFocus: make(chan struct{}, 1), + requests: make(chan request, requestCapacity), + results: make(chan Result, resultCapacity), + }, nil +} + +// SetFlatCaptureTimeout gives viewport review its own capture budget. Call it +// before Start; ordinary object and document operations keep their deadline. +func (worker *Worker) SetFlatCaptureTimeout(timeout time.Duration) error { + if timeout <= 0 { + return errors.New("flat review capture timeout must be positive") + } + worker.stateMutex.Lock() + defer worker.stateMutex.Unlock() + if worker.started { + return errors.New("cannot change flat review capture timeout after start") + } + worker.flatCaptureTimeout = timeout + return nil +} + +// SetDocumentCaptureTimeout gives whole-document capture its own budget. +// Call before Start; native text, placement, and activation keep their short deadline. +func (worker *Worker) SetDocumentCaptureTimeout(timeout time.Duration) error { + if timeout <= 0 { + return errors.New("document capture timeout must be positive") + } + worker.stateMutex.Lock() + defer worker.stateMutex.Unlock() + if worker.started { + return errors.New("cannot change document capture timeout after start") + } + worker.documentCaptureTimeout = timeout + return nil +} + +func (worker *Worker) Results() <-chan Result { + return worker.results +} + +func (worker *Worker) Start(ctx context.Context) error { + if ctx == nil { + return errors.New("start object review worker: nil context") + } + if err := ctx.Err(); err != nil { + return err + } + worker.stateMutex.Lock() + defer worker.stateMutex.Unlock() + if worker.started { + return errors.New("object review worker already started") + } + workerContext, cancel := context.WithCancel(ctx) + worker.started = true + worker.cancel = cancel + worker.done = make(chan struct{}) + go worker.run(workerContext, worker.done) + return nil +} + +func (worker *Worker) Stop(ctx context.Context) error { + if ctx == nil { + return errors.New("stop object review worker: nil context") + } + worker.stateMutex.Lock() + cancel, done := worker.cancel, worker.done + worker.stateMutex.Unlock() + if done == nil { + return nil + } + cancel() + select { + case <-done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +// SyncFocus records the newest focused identity without waiting for capture. +// Invalid identities are ignored because some synthetic or shutdown events do +// not identify a live AT-SPI object. +func (worker *Worker) SyncFocus(focus atspi.ObjectID) { + if !focus.Valid() { + return + } + worker.stateMutex.Lock() + if worker.latestFocus != focus { + worker.focusRevision++ + worker.flatOrigin = atspi.ObjectID{} + } + worker.latestFocus = focus + worker.stateMutex.Unlock() + select { + case worker.wakeFocus <- struct{}{}: + default: + } +} + +// Recover a removed browse cursor only while it is still the current focus. +func (worker *Worker) recoverDocumentFocus(oldFocus, newFocus atspi.ObjectID, epoch uint64) bool { + worker.stateMutex.Lock() + defer worker.stateMutex.Unlock() + if worker.latestFocus != oldFocus || worker.documentEpoch.Load() != epoch { + return false + } + worker.latestFocus = newFocus + worker.focusRevision++ + return true +} + +// ClearFocus retires review ownership when the active window is deactivated +// or destroyed. Unlike SyncFocus, an invalid identity is meaningful here. +func (worker *Worker) ClearFocus() { + worker.stateMutex.Lock() + worker.latestFocus = atspi.ObjectID{} + worker.focusRevision++ + worker.flatOrigin = atspi.ObjectID{} + worker.documentEpoch.Add(1) + worker.stateMutex.Unlock() + select { + case worker.wakeFocus <- struct{}{}: + default: + } +} + +// Move queues a semantic navigation request without waiting for AT-SPI. +func (worker *Worker) Move(direction Direction) error { + if direction < Parent || direction > NextSibling { + return fmt.Errorf("%w: %d", ErrInvalidDirection, direction) + } + select { + case worker.requests <- request{direction: direction}: + return nil + default: + return ErrRequestQueueFull + } +} + +func (worker *Worker) run(ctx context.Context, done chan<- struct{}) { + defer close(done) + var cursor *Cursor + var document *DocumentCursor + var documentTextTree *atspi.AccessibleTree + var documentEpoch uint64 + var failedDocumentBefore time.Time + var interestFocus atspi.ObjectID + var interestRevision uint64 + explicitInterest := implicitInterest + flat := &FlatCursor{} + var flatTree *atspi.AccessibleTree + for { + // A ready request/result channel can win a select even after Stop. + // Do not drain queued work or start further captures during shutdown. + if ctx.Err() != nil { + return + } + select { + case <-ctx.Done(): + return + case <-worker.wakeFocus: + if next, err := worker.syncLatestFocus(ctx, cursor, false); err == nil { + cursor = next + } + case request := <-worker.requests: + worker.stateMutex.Lock() + focus, revision := worker.latestFocus, worker.focusRevision + worker.stateMutex.Unlock() + if revision != interestRevision || focus != interestFocus { + interestFocus, interestRevision, explicitInterest = focus, revision, implicitInterest + } + if epoch := worker.documentEpoch.Load(); epoch != documentEpoch { + document, documentTextTree = nil, nil + explicitInterest = implicitInterest + flat, flatTree = &FlatCursor{}, nil + documentEpoch = epoch + failedDocumentBefore = time.Time{} + } + if request.documentList != nil { + list, err := worker.listDocument(ctx, document, request.documentList) + request.documentList.result <- documentListReply{list, err} + continue + } + if request.interest != nil { + interest, err := resolve_interest(request.interest.ctx, interestFocus, explicitInterest, cursor, flat, flatTree, document) + worker.stateMutex.Lock() + currentFocus, currentRevision := worker.latestFocus, worker.focusRevision + worker.stateMutex.Unlock() + if currentFocus != interestFocus || currentRevision != interestRevision { + interest, err = Interest{}, ErrNoCurrent + } + if contextErr := request.interest.ctx.Err(); contextErr != nil { + interest, err = Interest{}, contextErr + } + request.interest.result <- interestReply{interest, err} + continue + } + if (request.currentLine || request.brailleRoute != nil || request.nativeCaret || request.readAll != nil || request.line || request.listSelection != nil || request.target != 0 || request.caretCommand != 0 || request.activate || request.fragment != "" || request.unit != 0) && request.documentEpoch != documentEpoch { + if request.brailleRoute != nil { + request.brailleRoute.done <- atspi.ErrStaleObject + } + continue + } + documentCommand := request.listSelection != nil || request.target != 0 || request.caretCommand != 0 || request.activate || request.fragment != "" + if documentCommand && request.queuedAt.Before(failedDocumentBefore) { + continue + } + var result Result + if request.currentLine { + result = worker.read_current_line(ctx, document, request.currentLineBrowse) + result.FlatSpeech = request.flatSpeech + } else if request.listSelection != nil { + result, document = worker.selectDocumentList(ctx, document, request.listSelection) + } else if request.brailleRoute != nil { + result = worker.route_document_braille(ctx, document, request) + } else if request.nativeCaret { + result, document = worker.syncDocumentCaret(ctx, document, request) + } else if request.readPosition != nil { + if request.documentEpoch != documentEpoch || request.readFocus != worker.focus() { + continue + } + var followed bool + document, followed = worker.followReadAll(ctx, document, request) + if !followed { + continue + } + result = Result{ReadAllPosition: true, DocumentFocus: request.readFocus, DocumentPosition: *request.readPosition} + } else if request.readAll != nil { + readContext, cancel := context.WithCancel(ctx) + stop := context.AfterFunc(request.readAll, cancel) + result = worker.readAll(readContext, document) + stop() + cancel() + result.ReadAllContext = request.readAll + } else if request.line { + result, documentTextTree = worker.readDocumentLine(ctx, documentTextTree, request.lineRequest, request.lineFocus, request.lineOffset) + result.Elapsed = time.Since(request.queuedAt) + } else if request.target != 0 { + result, document = worker.moveDocument(ctx, document, request.target, request.level, request.backwards, request.documentEpoch) + result.Elapsed = time.Since(request.queuedAt) + } else if request.caretCommand != 0 { + result, document = worker.moveDocumentCaret(ctx, document, request.caretCommand, request.documentEpoch) + result.Elapsed = time.Since(request.queuedAt) + } else if request.activate { + result, document = worker.activateDocumentCaret(ctx, document, request.documentEpoch) + result.Elapsed = time.Since(request.queuedAt) + } else if request.fragment != "" { + result, document = worker.jumpDocumentFragment(ctx, document, request.fragment, request.documentEpoch) + result.Elapsed = time.Since(request.queuedAt) + } else if request.unit != 0 { + result, flatTree = worker.readFlat(ctx, flat, flatTree, request.unit, request.step) + result.FlatSpeech = request.flatSpeech + } else { + movement := worker.move(ctx, cursor, request.direction) + cursor = movement.cursor + result = movement.Result + } + if result.Err == nil { + if request.unit != 0 { + explicitInterest = flatInterest + } else if request.direction != 0 { + explicitInterest = objectInterest + } else if request.brailleRoute != nil || request.listSelection != nil || request.target != 0 || request.caretCommand != 0 || request.nativeCaret || request.fragment != "" || request.readPosition != nil { + explicitInterest = implicitInterest + } + worker.stateMutex.Lock() + if worker.latestFocus != interestFocus || worker.focusRevision != interestRevision { + explicitInterest = implicitInterest + } + interestFocus, interestRevision = worker.latestFocus, worker.focusRevision + worker.stateMutex.Unlock() + } + result.DocumentEpoch = request.documentEpoch + if documentCommand && worker.CurrentDocumentResult(result) && errors.Is(result.Err, context.DeadlineExceeded) { + // Keys pressed while the provider was unavailable must not each + // start another full timeout. A command issued after this failure + // can try again; successful navigation keeps its ordered steps. + failedDocumentBefore = time.Now() + } + if request.brailleRoute != nil || request.listSelection != nil || request.target != 0 || request.caretCommand != 0 || request.fragment != "" { + result = worker.readDocumentBraille(ctx, result) + result.Elapsed = time.Since(request.queuedAt) + } + select { + case worker.results <- result: + case <-ctx.Done(): + return + } + } + } +} + +func (worker *Worker) focus() atspi.ObjectID { + worker.stateMutex.Lock() + defer worker.stateMutex.Unlock() + return worker.latestFocus +} + +func (worker *Worker) Focus() atspi.ObjectID { return worker.focus() } diff --git a/internal/review/worker_contract.go b/internal/review/worker_contract.go new file mode 100644 index 0000000..297ac72 --- /dev/null +++ b/internal/review/worker_contract.go @@ -0,0 +1,144 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +// TreeCapturer performs native AT-SPI capture. Worker is the only runtime +// caller so capture latency cannot block the event or command loops. +type TreeCapturer interface { + CaptureDesktop(context.Context) (*atspi.AccessibleTree, error) + CaptureReviewWindow(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) + CaptureDocument(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) + CaptureDocumentText(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) +} + +// Fresh providers cannot reuse text from a previous review command. +type FreshReviewWindowCapturer interface{ FreshReviewWindow(atspi.ObjectID) bool } + +// Resolve optional native operations without hiding the adapter's dynamic +// capabilities behind a capture router. Reserved provider IDs return nil. +type NativeCapturerResolver interface { + NativeCapturerFor(atspi.ObjectID) TreeCapturer +} + +func (worker *Worker) nativeCapturerFor(id atspi.ObjectID) TreeCapturer { + if resolver, ok := worker.capturer.(NativeCapturerResolver); ok { + return resolver.NativeCapturerFor(id) + } + return worker.capturer +} + +// Result describes one requested navigation step. A boundary has Moved false +// and no error; Position remains the current object in that case. +type Result struct { + CurrentLine bool + CurrentLineBrowse bool + ReadAllContext context.Context + ReadAllLines []atspi.DocumentLine + ReadAllProgress func(int) + ReadAllPosition bool + DocumentEpoch uint64 + DocumentDiagnostics DocumentDiagnostics + Elapsed time.Duration + CaptureDuration time.Duration + CaptureReason error + DocumentTarget DocumentTarget + DocumentCaretCommand DocumentCaretCommand + DocumentActivate bool + DocumentFragment bool + DocumentCaretText string + DocumentCaretRawText string + DocumentCaretLine *atspi.DocumentLine + DocumentTablePrefix string + DocumentTableSuffix string + + DocumentTableRowHeader, DocumentTableColumnHeader string + + DocumentCaretStart int + DocumentCaretEnd int + DocumentCaretContext []atspi.Snapshot + DocumentBrailleLine *atspi.DocumentCaretText + DocumentBrailleErr error + DocumentSoundErr error + DocumentBackwards bool + DocumentLevel int + DocumentWrapped bool + DocumentNativeCaret bool + DocumentBrailleRoute bool + DocumentPosition DocumentPosition + DocumentFocus atspi.ObjectID + Direction Direction + Position Position + Moved bool + Err error + CaretErr error + FlatUnit FlatUnit + FlatSpeech FlatSpeech + FlatStep int + FlatPosition FlatPosition + FlatFocus atspi.ObjectID + FlatCompleteness FlatCompleteness + FlatWarning bool + DocumentLine bool + DocumentLineRequest uint64 + DocumentLineData atspi.DocumentLine + DocumentLineFocus atspi.ObjectID + DocumentLineText string +} + +// request uses the existing ordered dispatch contract: native caret, Say All +// progress, Say All capture, document line, structural target, caret command, +// activation, fragment, flat unit, then object direction. Flags are deliberately +// retained; epoch and timeout retirement depend on their distinct combinations. +type request struct { + currentLine bool + currentLineBrowse bool + documentList *documentListRequest + listSelection *documentListSelection + brailleRoute *documentBrailleRequest + interest *interestRequest + nativeCaret bool + nativeCaretFocus atspi.ObjectID + nativeCaretOffset int + readAll context.Context + readPosition *DocumentPosition + readTree *atspi.AccessibleTree + readFocus atspi.ObjectID + documentEpoch uint64 + queuedAt time.Time + target DocumentTarget + caretCommand DocumentCaretCommand + activate bool + fragment string + backwards bool + level int + direction Direction + unit FlatUnit + flatSpeech FlatSpeech + step int + line bool + lineRequest uint64 + lineFocus atspi.ObjectID + lineOffset int +} diff --git a/internal/review/worker_test.go b/internal/review/worker_test.go new file mode 100644 index 0000000..0529044 --- /dev/null +++ b/internal/review/worker_test.go @@ -0,0 +1,405 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package review + +import ( + "context" + "errors" + "reflect" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/atspi" +) + +type captureCall struct { + ctx context.Context + reviewFocus atspi.ObjectID + result chan captureResult +} + +type captureResult struct { + tree *atspi.AccessibleTree + err error +} + +type fakeCapturer struct { + calls chan captureCall +} + +func (capturer *fakeCapturer) CaptureDesktop(ctx context.Context) (*atspi.AccessibleTree, error) { + return capturer.capture(ctx, atspi.ObjectID{}) +} + +func (capturer *fakeCapturer) CaptureReviewWindow(ctx context.Context, focus atspi.ObjectID) (*atspi.AccessibleTree, error) { + return capturer.capture(ctx, focus) +} + +func (capturer *fakeCapturer) CaptureDocument(ctx context.Context, focus atspi.ObjectID) (*atspi.AccessibleTree, error) { + return capturer.capture(ctx, focus) +} + +func (capturer *fakeCapturer) CaptureDocumentText(ctx context.Context, focus atspi.ObjectID) (*atspi.AccessibleTree, error) { + return capturer.capture(ctx, focus) +} + +func (capturer *fakeCapturer) capture(ctx context.Context, reviewFocus atspi.ObjectID) (*atspi.AccessibleTree, error) { + call := captureCall{ctx: ctx, reviewFocus: reviewFocus, result: make(chan captureResult, 1)} + capturer.calls <- call + select { + case result := <-call.result: + return result.tree, result.err + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +func startWorker(t *testing.T, capturer TreeCapturer, timeout time.Duration) (*Worker, context.CancelFunc) { + t.Helper() + worker, err := NewWorker(capturer, timeout) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithCancel(context.Background()) + if err := worker.Start(ctx); err != nil { + cancel() + t.Fatal(err) + } + return worker, cancel +} + +func waitResult(t *testing.T, worker *Worker) Result { + t.Helper() + select { + case result := <-worker.Results(): + return result + case <-time.After(time.Second): + t.Fatal("timed out waiting for object review result") + return Result{} + } +} + +func TestWorkerCaptureTimeoutDoesNotBlockCallers(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, 20*time.Millisecond) + defer cancel() + + worker.SyncFocus(objectID("/first")) + if err := worker.Move(NextSibling); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + select { + case <-call.ctx.Done(): + case <-time.After(time.Second): + t.Fatal("capture context did not time out") + } + result := waitResult(t, worker) + if !errors.Is(result.Err, context.DeadlineExceeded) { + t.Fatalf("result error = %v, want deadline exceeded", result.Err) + } +} + +func TestWorkerReadsDocumentLineFromTextCapture(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + + focus := objectID("/link") + request, err := worker.ReadDocumentLine(focus, 6) + if err != nil { + t.Fatal(err) + } + call := <-capturer.calls + if call.reviewFocus != focus { + t.Fatalf("capture focus = %#v", call.reviewFocus) + } + call.result <- captureResult{tree: documentLineTree(t)} + result := waitResult(t, worker) + if result.Err != nil || !result.DocumentLine || !result.Moved { + t.Fatalf("line result = %#v", result) + } + if result.DocumentLineFocus != focus { + t.Fatalf("result focus = %#v", result.DocumentLineFocus) + } + if result.DocumentLineRequest != request { + t.Fatalf("result request = %d, want %d", result.DocumentLineRequest, request) + } + var contents []string + for _, content := range result.DocumentLineData.Contents { + contents = append(contents, content.Text) + } + if !reflect.DeepEqual(contents, []string{"Read ", "the link"}) { + t.Fatalf("line contents = %#v", contents) + } +} + +func TestWorkerReusesDocumentTextCaptureForCaretLines(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 2)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + + focus := objectID("/link") + if _, err := worker.ReadDocumentLine(focus, 1); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + call.result <- captureResult{tree: documentLineTree(t)} + if result := waitResult(t, worker); result.Err != nil { + t.Fatalf("first line result = %#v", result) + } + + if _, err := worker.ReadDocumentLine(focus, 2); err != nil { + t.Fatal(err) + } + if result := waitResult(t, worker); result.Err != nil { + t.Fatalf("cached line result = %#v", result) + } + select { + case call := <-capturer.calls: + t.Fatalf("unexpected repeated document capture for %#v", call.reviewFocus) + case <-time.After(20 * time.Millisecond): + } +} + +func TestWorkerUsesNewestFocusAfterConcurrentCapture(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + + worker.SyncFocus(objectID("/first")) + if err := worker.Move(NextSibling); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + worker.SyncFocus(objectID("/second")) + call.result <- captureResult{tree: threeNodeTree(t)} + result := waitResult(t, worker) + if result.Err != nil || !result.Moved || result.Position.Current.Name != "Third" { + t.Fatalf("result = %#v, want move from newest focus to Third", result) + } +} + +func TestWorkerRecapturesAndRepairsStaleCursor(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 2)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + + firstTree := threeNodeTree(t) + worker.SyncFocus(objectID("/first")) + if err := worker.Move(NextSibling); err != nil { + t.Fatal(err) + } + firstCall := <-capturer.calls + firstCall.result <- captureResult{tree: firstTree} + if result := waitResult(t, worker); result.Err != nil || result.Position.Current.Name != "Second" { + t.Fatalf("initial result = %#v", result) + } + firstTree.Invalidate(objectID("/second")) + + if err := worker.Move(NextSibling); err != nil { + t.Fatal(err) + } + secondCall := <-capturer.calls + secondCall.result <- captureResult{tree: threeNodeTree(t)} + result := waitResult(t, worker) + if result.Err != nil || !result.Moved || result.Position.Current.Name != "Second" { + t.Fatalf("recovered result = %#v, want Second", result) + } +} + +func TestWorkerStopsCleanlyDuringCapture(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Minute) + worker.SyncFocus(objectID("/first")) + if err := worker.Move(NextSibling); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + cancel() + stopContext, stopCancel := context.WithTimeout(context.Background(), time.Second) + defer stopCancel() + if err := worker.Stop(stopContext); err != nil { + t.Fatal(err) + } + select { + case <-call.ctx.Done(): + default: + t.Fatal("shutdown did not cancel in-flight capture") + } +} + +func documentLineTree(t *testing.T) *atspi.AccessibleTree { + t.Helper() + baseNode := func(path, name, role string, children ...atspi.ObjectID) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, name, role, "", "") + snapshot.BusName = ":1.42" + return atspi.TreeNode{Snapshot: snapshot, Children: children} + } + lineText := func(path, role, text string, bounds atspi.Rectangle, caret bool) atspi.TreeNode { + snapshot := atspi.NewSnapshot(path, path, role, "", text) + snapshot.BusName = ":1.42" + geometry := atspi.Geometry{Bounds: bounds, BoundsKnown: true, VisibilityKnown: true, Visible: true, Showing: true} + visible := atspi.VisibleText{Known: true, Ranges: []atspi.TextRange{{ + Start: 0, End: len(text), Text: text, Bounds: bounds, + }}} + if caret { + visible.CaretKnown, visible.CaretOffset = true, 1 + } + return atspi.TreeNode{Snapshot: snapshot, Geometry: geometry, Text: visible} + } + tree, err := atspi.NewAccessibleTree(objectID("/root"), []atspi.TreeNode{ + baseNode("/root", "Window", "frame", objectID("/doc")), + baseNode("/doc", "Document", "document web", objectID("/text"), objectID("/link")), + lineText("/text", "static", "Read ", atspi.Rectangle{X: 0, Y: 100, Width: 50, Height: 20}, false), + lineText("/link", "link", "the link", atspi.Rectangle{X: 100, Y: 100, Width: 80, Height: 20}, false), + }) + if err != nil { + t.Fatal(err) + } + return tree +} + +func TestWorkerAcceptsConcurrentFocusUpdates(t *testing.T) { + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, cancel := startWorker(t, capturer, time.Second) + defer cancel() + var wait sync.WaitGroup + for index := 0; index < 20; index++ { + wait.Add(1) + go func() { + defer wait.Done() + worker.SyncFocus(objectID("/second")) + }() + } + wait.Wait() + if err := worker.Move(NextSibling); err != nil { + t.Fatal(err) + } + call := <-capturer.calls + call.result <- captureResult{tree: threeNodeTree(t)} + result := waitResult(t, worker) + if result.Err != nil || result.Position.Current.Name != "Third" { + t.Fatalf("result = %#v", result) + } +} + +func threeNodeTree(t *testing.T) *atspi.AccessibleTree { + t.Helper() + tree, err := atspi.NewAccessibleTree(objectID("/root"), []atspi.TreeNode{ + node("/root", "Window", objectID("/first"), objectID("/second"), objectID("/third")), + node("/first", "First"), + node("/second", "Second"), + node("/third", "Third"), + }) + if err != nil { + t.Fatal(err) + } + return tree +} + +func TestWorkerRecapturesIncompleteChildrenAtIndependentPosition(t *testing.T) { + for _, outcome := range []string{"added", "empty", "failure", "focus-changed", "invalidated-again"} { + t.Run(outcome, func(t *testing.T) { + tree := threeNodeTree(t) + cursor, err := NewCursor(tree) + if err != nil { + t.Fatal(err) + } + if _, err := cursor.SyncFocus(objectID("/first")); err != nil { + t.Fatal(err) + } + if _, _, err := cursor.Move(NextSibling); err != nil { + t.Fatal(err) + } + tree.InvalidateChildren(objectID("/second")) + capturer := &fakeCapturer{calls: make(chan captureCall, 1)} + worker, err := NewWorker(capturer, time.Second) + if err != nil { + t.Fatal(err) + } + worker.SyncFocus(objectID("/first")) + results := make(chan moveResult, 1) + go func() { results <- worker.move(context.Background(), cursor, FirstChild) }() + var call captureCall + select { + case call = <-capturer.calls: + case result := <-results: + t.Fatalf("navigation did not recapture: %#v", result) + case <-time.After(time.Second): + t.Fatal("capture did not start") + } + captureErr := errors.New("provider unavailable") + if outcome == "failure" { + call.result <- captureResult{err: captureErr} + } else { + nodes := []atspi.TreeNode{ + node("/root", "Window", objectID("/first"), objectID("/second")), + node("/first", "First"), + node("/second", "Second"), + } + if outcome != "empty" { + nodes[2].Children = []atspi.ObjectID{objectID("/added")} + nodes = append(nodes, node("/added", "Added")) + } + if err := tree.Replace(objectID("/root"), nodes); err != nil { + t.Fatal(err) + } + if outcome == "focus-changed" { + worker.SyncFocus(objectID("/root")) + } + if outcome == "invalidated-again" { + tree.InvalidateChildren(objectID("/second")) + } + call.result <- captureResult{tree: tree} + } + var result moveResult + select { + case result = <-results: + case <-time.After(2 * time.Second): + t.Fatal("navigation did not finish after one recapture") + } + switch outcome { + case "failure": + if !errors.Is(result.Err, captureErr) || result.cursor != cursor { + t.Fatalf("failed recovery = %#v", result) + } + position, err := cursor.Current() + if err != nil || position.Current.Name != "Second" { + t.Fatalf("lost review position: %#v %v", position, err) + } + case "invalidated-again": + if !errors.Is(result.Err, atspi.ErrIncompleteTree) { + t.Fatalf("repeated invalidation = %#v", result) + } + default: + want, moved := "Added", true + if outcome == "empty" { + want, moved = "Second", false + } + if outcome == "focus-changed" { + want = "First" + } + if result.Err != nil || result.Moved != moved || result.Position.Current.Name != want { + t.Fatalf("result = %#v, want %s moved=%v", result, want, moved) + } + } + }) + } +} diff --git a/internal/sessionbus/sessionbus.go b/internal/sessionbus/sessionbus.go new file mode 100644 index 0000000..ae7ee8c --- /dev/null +++ b/internal/sessionbus/sessionbus.go @@ -0,0 +1,61 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package sessionbus selects the same desktop session bus as GLib clients, +// including Python Cthulhu and I38lock, without changing the process environment. +package sessionbus + +/* +#cgo pkg-config: gio-2.0 +#include +*/ +import "C" + +import ( + "context" + "fmt" + "log/slog" + "time" + "unsafe" + + "github.com/godbus/dbus/v5" +) + +func sessionAddress() (string, error) { + var nativeError *C.GError + address := C.g_dbus_address_get_for_bus_sync(C.G_BUS_TYPE_SESSION, nil, &nativeError) + if nativeError != nil { + defer C.g_error_free(nativeError) + return "", fmt.Errorf("resolve desktop session bus: %s", C.GoString(nativeError.message)) + } + if address == nil { + return "", fmt.Errorf("resolve desktop session bus: no address") + } + defer C.g_free(C.gpointer(unsafe.Pointer(address))) + return C.GoString(address), nil +} + +// Connect uses GLib's session address discovery and godbus's private connection. +// Bus IDs let debug logs identify mismatched buses without exposing addresses. +func Connect(logger *slog.Logger, component string, options ...dbus.ConnOption) (*dbus.Conn, error) { + address, err := sessionAddress() + if err != nil { + return nil, err + } + connection, err := dbus.Connect(address, options...) + if err != nil { + return nil, err + } + if logger != nil && logger.Enabled(context.Background(), slog.LevelDebug) { + ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) + defer cancel() + var busID string + if err := connection.BusObject().CallWithContext(ctx, "org.freedesktop.DBus.GetId", 0).Store(&busID); err != nil { + logger.Debug("query session bus identity", "component", component, "error", err) + } else { + logger.Debug("connected to session bus", "component", component, "bus_id", busID) + } + } + return connection, nil +} diff --git a/internal/sessionbus/sessionbus_test.go b/internal/sessionbus/sessionbus_test.go new file mode 100644 index 0000000..2658b8d --- /dev/null +++ b/internal/sessionbus/sessionbus_test.go @@ -0,0 +1,107 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sessionbus + +import ( + "bufio" + "bytes" + "context" + "log/slog" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + + "github.com/godbus/dbus/v5" +) + +func TestSessionBusHelper(t *testing.T) { + expectedID := os.Getenv("CTHULHU_SESSIONBUS_EXPECTED_ID") + if expectedID == "" { + t.Skip("subprocess helper") + } + before, present := os.LookupEnv("DBUS_SESSION_BUS_ADDRESS") + var output bytes.Buffer + logger := slog.New(slog.NewJSONHandler(&output, &slog.HandlerOptions{Level: slog.LevelDebug})) + connection, err := Connect(logger, "test") + if err != nil { + t.Fatal(err) + } + defer connection.Close() + var busID string + if err := connection.BusObject().Call("org.freedesktop.DBus.GetId", 0).Store(&busID); err != nil { + t.Fatal(err) + } + if busID != expectedID { + t.Fatalf("selected bus %q, want %q", busID, expectedID) + } + if after, exists := os.LookupEnv("DBUS_SESSION_BUS_ADDRESS"); after != before || exists != present { + t.Fatal("session discovery changed process environment") + } + if !strings.Contains(output.String(), `"bus_id":"`+expectedID+`"`) { + t.Fatal("missing bus identity diagnostic") + } + if strings.Contains(output.String(), os.Getenv("XDG_RUNTIME_DIR")) { + t.Fatal("diagnostic exposes runtime directory") + } +} + +func TestNativeDesktopSessionBusDiscovery(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_DBUS_TEST") != "1" { + t.Skip("requires private session bus sockets") + } + startBus := func() (string, string, string) { + runtimeDirectory := t.TempDir() + process := exec.Command("dbus-daemon", "--session", "--nofork", "--address=unix:path="+filepath.Join(runtimeDirectory, "bus"), "--print-address=1") + stdout, err := process.StdoutPipe() + if err != nil { + t.Fatal(err) + } + if err := process.Start(); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { process.Process.Kill(); process.Wait() }) + address, err := bufio.NewReader(stdout).ReadString('\n') + if err != nil { + t.Fatal(err) + } + connection, err := dbus.Connect(strings.TrimSpace(address)) + if err != nil { + t.Fatal(err) + } + defer connection.Close() + var busID string + if err := connection.BusObject().CallWithContext(context.Background(), "org.freedesktop.DBus.GetId", 0).Store(&busID); err != nil { + t.Fatal(err) + } + return runtimeDirectory, strings.TrimSpace(address), busID + } + runtimeDirectory, _, runtimeID := startBus() + _, explicitAddress, explicitID := startBus() + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + for _, explicit := range []bool{false, true} { + expectedID := runtimeID + environment := make([]string, 0) + for _, value := range os.Environ() { + if !strings.HasPrefix(value, "DBUS_SESSION_BUS_ADDRESS=") && !strings.HasPrefix(value, "XDG_RUNTIME_DIR=") { + environment = append(environment, value) + } + } + if explicit { + environment = append(environment, "DBUS_SESSION_BUS_ADDRESS="+explicitAddress) + expectedID = explicitID + } + environment = append(environment, "XDG_RUNTIME_DIR="+runtimeDirectory, "CTHULHU_SESSIONBUS_EXPECTED_ID="+expectedID) + process := exec.Command(executable, "-test.run=^TestSessionBusHelper$", "-test.v") + process.Env = environment + if output, err := process.CombinedOutput(); err != nil { + t.Fatalf("explicit=%v: %v\n%s", explicit, err, output) + } + } +} diff --git a/internal/shortcutui/native.c b/internal/shortcutui/native.c new file mode 100644 index 0000000..62615fb --- /dev/null +++ b/internal/shortcutui/native.c @@ -0,0 +1,51 @@ +#include + +int shortcut_ui_open(const char *title, const char **groups, const char **labels, const char **keys, int count) { + if (!gtk_init_check(NULL, NULL)) return 0; + GtkWidget *dialog = gtk_dialog_new_with_buttons(title, NULL, GTK_DIALOG_MODAL, + "_Close", GTK_RESPONSE_CLOSE, NULL); + gtk_window_set_default_size(GTK_WINDOW(dialog), 900, 700); + GtkWidget *scrolled = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_set_vexpand(scrolled, TRUE); + gtk_widget_set_hexpand(scrolled, TRUE); + gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), scrolled); + GtkTreeStore *store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING); + GtkWidget *tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); + gtk_widget_set_can_focus(tree, TRUE); + atk_object_set_name(gtk_widget_get_accessible(tree), "Cthulhu shortcuts"); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), TRUE); + const char *headers[] = {"Function", "Key binding"}; + for (int column = 0; column < 2; column++) { + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn *view = gtk_tree_view_column_new_with_attributes(headers[column], renderer, + "text", column, NULL); + gtk_tree_view_column_set_sort_column_id(view, column); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree), view); + } + gtk_container_add(GTK_CONTAINER(scrolled), tree); + GtkTreeIter parent, child, first; + gboolean have_first = FALSE; + const char *previous = NULL; + for (int i = 0; i < count; i++) { + if (!previous || g_strcmp0(previous, groups[i]) != 0) { + gtk_tree_store_append(store, &parent, NULL); + gtk_tree_store_set(store, &parent, 0, groups[i], 1, "", -1); + previous = groups[i]; + } + gtk_tree_store_append(store, &child, &parent); + gtk_tree_store_set(store, &child, 0, labels[i], 1, keys[i], -1); + if (!have_first) { first = child; have_first = TRUE; } + } + gtk_tree_view_expand_all(GTK_TREE_VIEW(tree)); + gtk_widget_show_all(dialog); + if (have_first) { + GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &first); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(tree), path, NULL, FALSE); + gtk_tree_path_free(path); + } + gtk_widget_grab_focus(tree); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + g_object_unref(store); + return 1; +} diff --git a/internal/shortcutui/ui.go b/internal/shortcutui/ui.go new file mode 100644 index 0000000..5a861e0 --- /dev/null +++ b/internal/shortcutui/ui.go @@ -0,0 +1,55 @@ +package shortcutui + +/* +#cgo pkg-config: gtk+-3.0 +#include +int shortcut_ui_open(const char *title, const char **groups, const char **labels, const char **keys, int count); +*/ +import "C" + +import ( + "encoding/json" + "errors" + "io" + "runtime" + "unsafe" +) + +type Row struct { + Group string `json:"group"` + Label string `json:"label"` + Keys string `json:"keys"` +} + +type List struct { + Title string `json:"title"` + Rows []Row `json:"rows"` +} + +// Run displays one read-only, keyboard accessible shortcut list in a child process. +func Run(reader io.Reader) error { + var list List + if err := json.NewDecoder(io.LimitReader(reader, 1<<20)).Decode(&list); err != nil { + return err + } + if len(list.Rows) == 0 || len(list.Rows) > 512 { + return errors.New("invalid shortcut list") + } + runtime.LockOSThread() + defer runtime.UnlockOSThread() + title := C.CString(list.Title) + defer C.free(unsafe.Pointer(title)) + groups := make([]*C.char, len(list.Rows)) + labels := make([]*C.char, len(list.Rows)) + keys := make([]*C.char, len(list.Rows)) + for i, row := range list.Rows { + groups[i], labels[i], keys[i] = C.CString(row.Group), C.CString(row.Label), C.CString(row.Keys) + defer C.free(unsafe.Pointer(groups[i])) + defer C.free(unsafe.Pointer(labels[i])) + defer C.free(unsafe.Pointer(keys[i])) + } + if C.shortcut_ui_open(title, (**C.char)(unsafe.Pointer(&groups[0])), (**C.char)(unsafe.Pointer(&labels[0])), (**C.char)(unsafe.Pointer(&keys[0])), C.int(len(list.Rows))) == 0 { + return errors.New("could not open shortcut list window") + } + return nil +} diff --git a/internal/shortcutui/ui_native_test.go b/internal/shortcutui/ui_native_test.go new file mode 100644 index 0000000..68f4617 --- /dev/null +++ b/internal/shortcutui/ui_native_test.go @@ -0,0 +1,39 @@ +package shortcutui + +import ( + "os" + "os/exec" + "strings" + "testing" + "time" +) + +func TestNativeShortcutListOpensAndClosesFromKeyboard(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_X11") != "1" { + t.Skip("requires isolated X11 display") + } + finished := make(chan error, 1) + go func() { + deadline := time.Now().Add(4 * time.Second) + for time.Now().Before(deadline) { + if output, err := exec.Command("xdotool", "search", "--onlyvisible", "--name", "^Cthulhu Shortcut Test$").Output(); err == nil && len(strings.TrimSpace(string(output))) != 0 { + window := strings.Fields(string(output))[0] + if err := exec.Command("xdotool", "windowfocus", window).Run(); err != nil { + finished <- err + return + } + finished <- exec.Command("xdotool", "key", "Escape").Run() + return + } + time.Sleep(20 * time.Millisecond) + } + finished <- os.ErrDeadlineExceeded + }() + data := `{"title":"Cthulhu Shortcut Test","rows":[{"group":"Default","label":"Quit Cthulhu.","keys":"Cthulhu+q"}]}` + if err := Run(strings.NewReader(data)); err != nil { + t.Fatal(err) + } + if err := <-finished; err != nil { + t.Fatal(err) + } +} diff --git a/internal/sound/indentation.go b/internal/sound/indentation.go new file mode 100644 index 0000000..eed0991 --- /dev/null +++ b/internal/sound/indentation.go @@ -0,0 +1,25 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "strconv" + "strings" + "time" +) + +const indentationCuePrefix = "generated-indentation-tone:" + +func IndentationCueName(frequency int) string { return indentationCuePrefix + strconv.Itoa(frequency) } +func indentation_frequency(name string) (int, bool) { + if !strings.HasPrefix(name, indentationCuePrefix) { + return 0, false + } + frequency, err := strconv.Atoi(strings.TrimPrefix(name, indentationCuePrefix)) + return frequency, err == nil && frequency >= 100 && frequency <= 2750 +} +func indentation_tone_wav(frequency int) []byte { + return tone_wav(float64(frequency), 150*time.Millisecond, .7, 5*time.Millisecond) +} diff --git a/internal/sound/indentation_test.go b/internal/sound/indentation_test.go new file mode 100644 index 0000000..d715545 --- /dev/null +++ b/internal/sound/indentation_test.go @@ -0,0 +1,36 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "encoding/binary" + "log/slog" + "testing" +) + +func TestIndentationToneIsBoundedAndHonorsSoundPolicy(t *testing.T) { + service := New(slog.New(slog.DiscardHandler), nil, "default", .5) + for _, frequency := range []int{100, 200, 2750} { + name := IndentationCueName(frequency) + data, err := soundData("default", name) + if err != nil || len(data) != 44+3307*2 || binary.LittleEndian.Uint32(data[24:]) != 22050 { + t.Fatalf("indentation WAV: bytes %d, error %v", len(data), err) + } + if !service.cue_available(name) || !generated_tone(name) { + t.Fatal("generated indentation unavailable") + } + } + if _, err := soundData("default", IndentationCueName(2751)); err == nil { + t.Fatal("unbounded pitch accepted") + } + service.Configure(Configuration{Enabled: false, Theme: "default", Volume: .5}) + if service.cue_available(IndentationCueName(200)) { + t.Fatal("disabled sound played indentation") + } + service.Configure(Configuration{Enabled: true, Theme: "none", Volume: .5}) + if service.cue_available(IndentationCueName(200)) { + t.Fatal("None theme played indentation") + } +} diff --git a/internal/sound/player.go b/internal/sound/player.go new file mode 100644 index 0000000..710c9e6 --- /dev/null +++ b/internal/sound/player.go @@ -0,0 +1,110 @@ +package sound + +/* +#cgo pkg-config: gstreamer-1.0 +#include +#include +static GstElement *start_sound(const void *data, size_t length, double volume, double pan, const char *sink, GError **error) { + if (!gst_init_check(NULL, NULL, error)) return NULL; + gchar *description = g_strdup_printf("appsrc name=source ! wavparse ! audioconvert ! audioresample ! audiopanorama name=panorama ! volume name=volume ! %s", sink); + GError *parse_error = NULL; + GstElement *pipeline = gst_parse_launch(description, &parse_error); + g_free(description); + if (parse_error != NULL) { + if (pipeline) gst_object_unref(pipeline); + g_error_free(parse_error); + // audiopanorama is an optional GStreamer plugin. Preserve playback + // when it is unavailable; the typed cue remains safely centered. + description = g_strdup_printf("appsrc name=source ! wavparse ! audioconvert ! audioresample ! volume name=volume ! %s", sink); + pipeline = gst_parse_launch(description, error); + g_free(description); + if (*error != NULL) { if (pipeline) gst_object_unref(pipeline); return NULL; } + } + GstElement *source = gst_bin_get_by_name(GST_BIN(pipeline), "source"); + GstElement *gain = gst_bin_get_by_name(GST_BIN(pipeline), "volume"); + GstElement *panorama = gst_bin_get_by_name(GST_BIN(pipeline), "panorama"); + g_object_set(gain, "volume", volume, NULL); + if (panorama != NULL) g_object_set(panorama, "panorama", pan, NULL); + gst_object_unref(gain); + if (panorama != NULL) gst_object_unref(panorama); + GstBuffer *buffer = gst_buffer_new_allocate(NULL, length, NULL); + gst_buffer_fill(buffer, 0, data, length); + GstFlowReturn flow; + g_signal_emit_by_name(source, "push-buffer", buffer, &flow); + gst_buffer_unref(buffer); + g_signal_emit_by_name(source, "end-of-stream", &flow); + gst_object_unref(source); + if (gst_element_set_state(pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { + g_set_error_literal(error, g_quark_from_static_string("cthulhu-sound"), 1, "cannot start audio pipeline"); + gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); return NULL; + } + return pipeline; +} +static int poll_sound(GstElement *pipeline, GError **error) { + GstBus *bus = gst_element_get_bus(pipeline); + GstMessage *message = gst_bus_timed_pop_filtered(bus, 20 * GST_MSECOND, GST_MESSAGE_ERROR | GST_MESSAGE_EOS); + gst_object_unref(bus); + if (message == NULL) return 0; + int result = 1; + if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) { + gst_message_parse_error(message, error, NULL); result = -1; + } + gst_message_unref(message); return result; +} +static void stop_sound(GstElement *pipeline) { + gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); +} +*/ +import "C" + +import ( + "context" + "errors" + "fmt" + "unsafe" +) + +type Player interface { + Play(context.Context, []byte, float64, float64) error +} + +type NativePlayer struct{ Sink string } + +func (player NativePlayer) Play(ctx context.Context, data []byte, volume, pan float64) error { + if err := ctx.Err(); err != nil { + return err + } + if len(data) == 0 { + return errors.New("empty sound") + } + sink := map[string]string{"auto": "autoaudiosink", "pipewire": "pipewiresink", "pulse": "pulsesink", "alsa": "alsasink", "test": "fakesink"}[player.Sink] + if sink == "" { + return fmt.Errorf("unknown sound sink %q", player.Sink) + } + nativeSink := C.CString(sink) + defer C.free(unsafe.Pointer(nativeSink)) + var nativeErr *C.GError + pan = normalizedPan(pan) + pipeline := C.start_sound(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.double(volume), C.double(pan), nativeSink, &nativeErr) + if nativeErr != nil { + defer C.g_error_free(nativeErr) + return errors.New(C.GoString(nativeErr.message)) + } + if pipeline == nil { + return errors.New("cannot create sound pipeline") + } + defer C.stop_sound(pipeline) + for { + if err := ctx.Err(); err != nil { + return err + } + result := C.poll_sound(pipeline, &nativeErr) + if nativeErr != nil { + defer C.g_error_free(nativeErr) + return errors.New(C.GoString(nativeErr.message)) + } + if result > 0 { + return nil + } + } +} diff --git a/internal/sound/position.go b/internal/sound/position.go new file mode 100644 index 0000000..c19b8de --- /dev/null +++ b/internal/sound/position.go @@ -0,0 +1,33 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "math" + "strconv" + "strings" + "time" +) + +const positionCuePrefix = "generated-position-tone:" + +// PositionCueName encodes relative position: zero is first, one is last. +func PositionCueName(position float64) string { + return positionCuePrefix + strconv.FormatFloat(position, 'g', -1, 64) +} + +func set_position(cue string) (float64, bool) { + if !strings.HasPrefix(cue, positionCuePrefix) { + return 0, false + } + position, err := strconv.ParseFloat(strings.TrimPrefix(cue, positionCuePrefix), 64) + return position, err == nil && !math.IsNaN(position) && !math.IsInf(position, 0) && position >= 0 && position <= 1 +} + +func position_tone_wav(position float64) []byte { + // Two octaves distinguish the ends of a set. Smooth the edges of this + // short cue; the service supplies the user's volume and stereo position. + return tone_wav(220*math.Pow(4, position), 60*time.Millisecond, 0.5, 5*time.Millisecond) +} diff --git a/internal/sound/position_test.go b/internal/sound/position_test.go new file mode 100644 index 0000000..cf436ea --- /dev/null +++ b/internal/sound/position_test.go @@ -0,0 +1,98 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "context" + "encoding/binary" + "log/slog" + "testing" + "time" +) + +func TestPositionTonesDecodeAndRiseInPitch(t *testing.T) { + previousCrossings := 0 + for _, position := range []float64{0, 0.5, 1} { + data, err := soundData("default", PositionCueName(position)) + if err != nil { + t.Fatal(err) + } + if binary.LittleEndian.Uint32(data[24:]) != 22050 || binary.LittleEndian.Uint16(data[22:]) != 1 || len(data) != 44+1323*2 { + t.Fatal("position tone is not 60 ms mono PCM at 22050 Hz") + } + crossings := 0 + previousSample := int16(0) + for offset := 44; offset < len(data); offset += 2 { + sample := int16(binary.LittleEndian.Uint16(data[offset:])) + if previousSample < 0 && sample >= 0 { + crossings++ + } + previousSample = sample + } + if crossings <= previousCrossings { + t.Fatalf("pitch failed to rise at %g: %d cycles", position, crossings) + } + previousCrossings = crossings + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + err = (NativePlayer{Sink: "test"}).Play(ctx, data, 0.3, -0.5) + cancel() + if err != nil { + t.Fatal(err) + } + } + for _, value := range []string{"NaN", "+Inf", "-1", "1.1", "bad"} { + if _, err := soundData("default", positionCuePrefix+value); err == nil { + t.Fatalf("accepted position %s", value) + } + } +} + +func TestPositionSoundUsesObjectSoundPolicy(t *testing.T) { + player := &configurationPlayer{played: make(chan configuredPlayback, 8)} + service := New(slog.New(slog.DiscardHandler), player, "default", 0.3) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + if err := service.Stop(context.Background()); err != nil { + t.Error(err) + } + }) + cue := Cue{Name: PositionCueName(0.5), Pan: -0.5} + if !service.Enqueue(cue) { + t.Fatal("position cue was rejected") + } + select { + case playback := <-player.played: + if playback.volume != 0.3 || playback.pan != -0.5 { + t.Fatalf("position playback = %+v", playback) + } + case <-time.After(time.Second): + t.Fatal("position tone did not reach player") + } + service.mutex.Lock() + cached := len(service.cache) + service.mutex.Unlock() + if cached != 0 { + t.Fatal("continuous position values populated the sound cache") + } + for _, configuration := range []Configuration{ + {Enabled: false, Theme: "default", Volume: 0.3}, + {Enabled: true, Theme: "none", Volume: 0.3}, + {Enabled: true, Theme: "default", Volume: 0}, + } { + service.Configure(configuration) + if service.Available(cue.Name) || service.Enqueue(cue) { + t.Fatalf("position ignored policy: %+v", configuration) + } + if !service.Available(ProgressCueName(50)) { + t.Fatal("position policy affected progress tones") + } + } + service.Configure(Configuration{Enabled: true, Theme: "custom", Volume: 0.3}) + if !service.Available(cue.Name) { + t.Fatal("generated position requires a theme asset") + } +} diff --git a/internal/sound/progress.go b/internal/sound/progress.go new file mode 100644 index 0000000..df75078 --- /dev/null +++ b/internal/sound/progress.go @@ -0,0 +1,69 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "bytes" + "encoding/binary" + "math" + "strconv" + "strings" +) + +const progressCuePrefix = "generated-progress-tone:" + +func ProgressCueName(percentage float64) string { + return progressCuePrefix + strconv.FormatFloat(percentage, 'g', -1, 64) +} + +func progress_percentage(cue string) (float64, bool) { + if !strings.HasPrefix(cue, progressCuePrefix) { + return 0, false + } + percentage, err := strconv.ParseFloat(strings.TrimPrefix(cue, progressCuePrefix), 64) + return percentage, err == nil && !math.IsNaN(percentage) && !math.IsInf(percentage, 0) && percentage >= 0 && percentage <= 100 +} + +// Match NVDA's default ProgressBar event_valueChange and generateBeep: +// 110 * 2^(percentage/25) Hz, 40 ms padded to the next integer cycle, +// 44100 Hz stereo PCM, and a sine clipped after multiplying by two. +// NVDA passes frequency through a C float and defaults each channel to 50%. +// Reference: nvaccess/nvda a4a89720ccbf3973a0e1e50a76dd8bff38db3d15, +// source/NVDAObjects/behaviors.py and nvdaHelper/local/beeps.cpp. +func progress_tone_wav(percentage float64) []byte { + return nvda_tone_wav(110*math.Pow(2, percentage/25), 40) +} + +// nvda_tone_wav also supplies the capital-letter beep (2000 Hz, 50 ms). +func nvda_tone_wav(hz float64, milliseconds int) []byte { + const sampleRate = 44100 + frequency := float64(float32(hz)) + // sampleRate/hz is evaluated as a float in NVDA's C++ generator. + cycleLength := float64(float32(sampleRate) / float32(frequency)) + samplesPerCycle := int(cycleLength) + sampleCount := int((float64(milliseconds) / 1000) / (1.0 / sampleRate)) + sampleCount += samplesPerCycle - sampleCount%samplesPerCycle + dataSize := sampleCount * 4 + buffer := bytes.NewBuffer(make([]byte, 0, 44+dataSize)) + buffer.WriteString("RIFF") + _ = binary.Write(buffer, binary.LittleEndian, uint32(36+dataSize)) + buffer.WriteString("WAVEfmt ") + _ = binary.Write(buffer, binary.LittleEndian, uint32(16)) + _ = binary.Write(buffer, binary.LittleEndian, uint16(1)) + _ = binary.Write(buffer, binary.LittleEndian, uint16(2)) + _ = binary.Write(buffer, binary.LittleEndian, uint32(sampleRate)) + _ = binary.Write(buffer, binary.LittleEndian, uint32(sampleRate*4)) + _ = binary.Write(buffer, binary.LittleEndian, uint16(4)) + _ = binary.Write(buffer, binary.LittleEndian, uint16(16)) + buffer.WriteString("data") + _ = binary.Write(buffer, binary.LittleEndian, uint32(dataSize)) + sinFrequency := 2 * math.Pi / cycleLength + for sample := 0; sample < sampleCount; sample++ { + value := int16(min(1.0, max(-1.0, math.Sin(float64(sample%sampleRate)*sinFrequency)*2)) * 7000) + _ = binary.Write(buffer, binary.LittleEndian, value) + _ = binary.Write(buffer, binary.LittleEndian, value) + } + return buffer.Bytes() +} diff --git a/internal/sound/progress_test.go b/internal/sound/progress_test.go new file mode 100644 index 0000000..4a93c7d --- /dev/null +++ b/internal/sound/progress_test.go @@ -0,0 +1,185 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "bytes" + "context" + "crypto/sha256" + "encoding/binary" + "fmt" + "log/slog" + "testing" + "time" +) + +func TestProgressAudioMatchesNVDAGenerator(t *testing.T) { + // PCM digests from the unmodified generateBeep in the reference commit + // named in progress.go, compiled locally with a small output-only harness. + all := sha256.New() + for percentage := 0; percentage <= 100; percentage++ { + data := progress_tone_wav(float64(percentage)) + if binary.LittleEndian.Uint32(data[24:]) != 44100 || binary.LittleEndian.Uint16(data[22:]) != 2 { + t.Fatal("progress tone is not 44100 Hz stereo") + } + all.Write(data[44:]) + } + if got := fmt.Sprintf("%x", all.Sum(nil)); got != "ef56e46be365269af544e22d94eb1de7d171c5946d1dd5b168cc7e570c0a159f" { + t.Fatalf("0 through 100 percent PCM differs from NVDA: %s", got) + } + for percentage, digest := range map[float64]string{ + 12.5: "4fc87ad5310038ed281a4516e9431d5dc247b7ce75662e4fe51cb4d2ab616a36", + 50.25: "6b4a9a7d254686b2fb52ead07763ff596ccdcbdd30d5e9d4ce956df13cc1bdf5", + } { + if got := fmt.Sprintf("%x", sha256.Sum256(progress_tone_wav(percentage)[44:])); got != digest { + t.Fatalf("%g percent PCM differs from NVDA: %s", percentage, got) + } + } +} + +type progressPlayback struct { + context context.Context + data []byte +} + +type progressTestPlayer struct { + started chan progressPlayback + release chan struct{} +} + +func (player *progressTestPlayer) Play(ctx context.Context, data []byte, _, _ float64) error { + player.started <- progressPlayback{context: ctx, data: data} + select { + case <-ctx.Done(): + return ctx.Err() + case <-player.release: + return nil + } +} + +func new_progress_test_service(t *testing.T) (*Service, *progressTestPlayer) { + t.Helper() + player := &progressTestPlayer{started: make(chan progressPlayback, 16), release: make(chan struct{}, 16)} + service := New(slog.New(slog.DiscardHandler), player, "none", 0) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Error(err) + } + }) + return service, player +} + +func next_progress_playback(t *testing.T, player *progressTestPlayer) progressPlayback { + t.Helper() + select { + case playback := <-player.started: + return playback + case <-time.After(time.Second): + t.Fatal("sound did not start") + return progressPlayback{} + } +} + +func TestRapidProgressFinishesActiveToneAndPlaysLatestValue(t *testing.T) { + service, player := new_progress_test_service(t) + service.Enqueue(Cue{Name: ProgressCueName(0)}) + first := next_progress_playback(t, player) + for percentage := 1; percentage <= 100; percentage++ { + if !service.EnqueueBatch([]Cue{{Name: ProgressCueName(float64(percentage))}}) { + t.Fatal("rapid progress update rejected") + } + } + if err := first.context.Err(); err != nil { + t.Fatalf("rapid updates canceled the active progress tone: %v", err) + } + player.release <- struct{}{} + latest := next_progress_playback(t, player) + if !bytes.Equal(latest.data, progress_tone_wav(100)) { + t.Fatal("played an obsolete percentage instead of the latest value") + } +} + +func TestProgressPreservesActiveAndPendingRoleSounds(t *testing.T) { + service, player := new_progress_test_service(t) + service.mutex.Lock() + service.enabled, service.theme, service.volume = true, "default", 0.5 + service.available = map[string]bool{"button": true, "link": true} + service.mutex.Unlock() + service.EnqueueBatch([]Cue{{Name: "button"}, {Name: "link"}}) + first := next_progress_playback(t, player) + service.Enqueue(Cue{Name: ProgressCueName(100)}) + if err := first.context.Err(); err != nil { + t.Fatalf("progress interrupted a role sound: %v", err) + } + player.release <- struct{}{} + second := next_progress_playback(t, player) + want, err := load_sound("default", "link") + if err != nil || !bytes.Equal(second.data, want) { + t.Fatal("progress displaced a pending role sound") + } + player.release <- struct{}{} + if got := next_progress_playback(t, player); !bytes.Equal(got.data, progress_tone_wav(100)) { + t.Fatal("latest progress did not follow the role sounds") + } +} + +func TestProgressCancellationDiscardsPendingValue(t *testing.T) { + for _, action := range []string{"presentation", "configure", "stop"} { + t.Run(action, func(t *testing.T) { + service, player := new_progress_test_service(t) + service.Enqueue(Cue{Name: ProgressCueName(0)}) + first := next_progress_playback(t, player) + service.Enqueue(Cue{Name: ProgressCueName(100)}) + switch action { + case "presentation": + service.mutex.Lock() + service.enabled, service.available["button"] = true, true + service.theme = "default" + service.mutex.Unlock() + service.Enqueue(Cue{Name: "button"}) + case "configure": + service.Configure(Configuration{Theme: "none"}) + case "stop": + if err := service.Stop(context.Background()); err != nil { + t.Fatal(err) + } + } + if first.context.Err() == nil { + t.Fatal("active progress was not canceled") + } + service.mutex.Lock() + pending := service.pendingProgress + service.mutex.Unlock() + if pending != nil { + t.Fatal("obsolete progress remained pending") + } + }) + } +} + +func TestProgressSoundIsIndependentOfRoleSoundSettings(t *testing.T) { + service := New(nil, nil, "none", 0) + service.Configure(Configuration{Enabled: false, Theme: "none", Volume: 0}) + service.running = true + if service.Available("button") || !service.Available(ProgressCueName(50.25)) { + t.Fatal("progress tone availability follows role-sound policy") + } + if !service.Enqueue(Cue{Name: ProgressCueName(50.25)}) { + t.Fatal("progress tone rejected with role sounds disabled") + } + for _, value := range []string{"NaN", "+Inf", "-1", "101", "bad"} { + if service.Available(progressCuePrefix + value) { + t.Fatalf("invalid percentage %s available", value) + } + if _, err := soundData("none", progressCuePrefix+value); err == nil { + t.Fatalf("invalid percentage %s decoded", value) + } + } +} diff --git a/internal/sound/service.go b/internal/sound/service.go new file mode 100644 index 0000000..39f18d3 --- /dev/null +++ b/internal/sound/service.go @@ -0,0 +1,436 @@ +package sound + +import ( + "context" + "errors" + "fmt" + "io" + "log/slog" + "math" + "os" + "path/filepath" + "strings" + "sync" + "sync/atomic" + "time" + + bundled "git.stormux.org/storm/cthulhu/assets/sounds" +) + +const queueCapacity = 8 +const maxSoundBytes = 4 * 1024 * 1024 + +type Service struct { + stopMutex sync.Mutex + player Player + logger *slog.Logger + theme string + volume float64 + queue chan queuedCue + done chan struct{} + cancel context.CancelFunc + mutex sync.Mutex + running bool + enabled bool + stopPending bool + dropped atomic.Uint64 + cache map[string][]byte + available map[string]bool + generation uint64 + active context.CancelFunc + activeID uint64 + // The sound worker owns one pending progress value under mutex. Updates + // replace this slot without canceling playback or the role-sound queue. + pendingProgress *queuedCue + progressWake chan struct{} +} + +type queuedCue struct { + Cue + generation uint64 +} + +func New(logger *slog.Logger, player Player, theme string, volume float64) *Service { + return &Service{ + logger: logger, player: player, theme: theme, volume: volume, enabled: true, + queue: make(chan queuedCue, queueCapacity), cache: make(map[string][]byte), available: cueAvailability(theme), + progressWake: make(chan struct{}, 1), + } +} + +// Cue is immutable presentation data for one sound. Pan ranges from -1 (left) +// through 0 (center) to 1 (right). Cue names never encode placement metadata. +type Cue struct { + Name string + Pan float64 +} + +type Configuration struct { + Enabled bool + Sink string + Theme string + Volume float64 +} + +// Configure atomically changes playback without restarting the owned worker. +// Active and pending cues from the old policy are canceled. +func (service *Service) Configure(configuration Configuration) { + available := cueAvailability(configuration.Theme) + service.mutex.Lock() + defer service.mutex.Unlock() + service.generation++ + if service.active != nil { + service.active() + service.active = nil + } + service.discardPending() + service.enabled = configuration.Enabled && configuration.Theme != "none" && configuration.Volume > 0 + service.theme = configuration.Theme + service.volume = configuration.Volume + service.available = available + if player, ok := service.player.(NativePlayer); ok { + player.Sink = configuration.Sink + service.player = player + } +} + +// Available reports whether current policy permits a named cue and the +// configured theme contains it. It performs no filesystem I/O. +func (service *Service) Available(name string) bool { + service.mutex.Lock() + defer service.mutex.Unlock() + return service.running && service.cue_available(name) +} + +func (service *Service) Start(ctx context.Context) error { + service.mutex.Lock() + defer service.mutex.Unlock() + if service.done != nil { + return errors.New("sound service already started") + } + workerContext, cancel := context.WithCancel(ctx) + service.cancel = cancel + service.done = make(chan struct{}) + service.running = true + service.stopPending = false + go service.run(workerContext, service.done) + return nil +} + +func (service *Service) Enqueue(cue Cue) bool { + return service.EnqueueBatch([]Cue{cue}) +} + +// EnqueueBatch replaces the previous presentation, then plays its cues in +// order. Python Cthulhu interrupts on the first cue and appends later cues. +// A rejected batch leaves the current presentation alone so sound-only callers +// can retain speech when its cues are unavailable. A single progress cue instead +// replaces the pending percentage and lets the active sound finish. +func (service *Service) EnqueueBatch(cues []Cue) bool { + if len(cues) == 0 { + return true + } + service.mutex.Lock() + defer service.mutex.Unlock() + if !service.running { + return false + } + if len(cues) > cap(service.queue) { + service.dropped.Add(uint64(len(cues))) + return false + } + for _, cue := range cues { + if !service.cue_available(cue.Name) { + return false + } + } + if len(cues) == 1 { + if _, progress := progress_percentage(cues[0].Name); progress { + cue := cues[0] + cue.Pan = normalizedPan(cue.Pan) + service.pendingProgress = &queuedCue{Cue: cue, generation: service.generation} + select { + case service.progressWake <- struct{}{}: + default: + } + return true + } + } + service.generation++ + if service.active != nil { + service.active() + } + service.discardPending() + for _, cue := range cues { + cue.Pan = normalizedPan(cue.Pan) + service.queue <- queuedCue{Cue: cue, generation: service.generation} + } + return true +} + +// The caller holds mutex, excluding producers. The worker can still receive +// before acquiring mutex, so checking len and then receiving can deadlock. +func (service *Service) discardPending() { + service.pendingProgress = nil + for { + select { + case <-service.queue: + default: + return + } + } +} + +func (service *Service) run(ctx context.Context, done chan struct{}) { + defer close(done) + for { + cue, ok := service.next_cue(ctx) + if !ok { + return + } + if count := service.dropped.Swap(0); count != 0 { + service.logger.Warn("sound queue overflow", "dropped", count) + } + if err := service.playQueued(ctx, cue); err != nil && ctx.Err() == nil { + service.logger.Warn("play sound", "cue", cue.Name, "error", err) + } + } +} + +// Preserve the order of ordinary presentation cues before taking the newest +// progress value. progressWake is only a notification; mutex owns the slot. +func (service *Service) next_cue(ctx context.Context) (queuedCue, bool) { + for { + if ctx.Err() != nil { + return queuedCue{}, false + } + service.mutex.Lock() + select { + case cue := <-service.queue: + service.mutex.Unlock() + return cue, true + default: + } + pending := service.pendingProgress + service.pendingProgress = nil + service.mutex.Unlock() + if pending != nil { + return *pending, true + } + select { + case <-ctx.Done(): + return queuedCue{}, false + case cue := <-service.queue: + return cue, true + case <-service.progressWake: + } + } +} + +func (service *Service) playQueued(ctx context.Context, cue queuedCue) error { + service.mutex.Lock() + if cue.generation != service.generation || !service.running || !service.cue_available(cue.Name) { + service.mutex.Unlock() + return nil + } + player, theme, volume := service.player, service.theme, service.volume + if _, valid := progress_percentage(cue.Name); valid { + volume = 1 + } + cacheKey := theme + "\x00" + cue.Name + data, exists := service.cache[cacheKey] + service.activeID++ + activeID := service.activeID + playContext, cancel := context.WithTimeout(ctx, 3*time.Second) + service.active = cancel + service.mutex.Unlock() + defer func() { + cancel() + service.mutex.Lock() + if service.activeID == activeID { + service.active = nil + } + service.mutex.Unlock() + }() + if !exists { + var err error + data, err = soundData(theme, cue.Name) + if err != nil { + return err + } + service.mutex.Lock() + if !generated_tone(cue.Name) { + service.cache[cacheKey] = data + } + service.mutex.Unlock() + } + if err := playContext.Err(); err != nil { + return err + } + service.logger.Debug("playing object sound", "cue", cue.Name) + return player.Play(playContext, data, volume, normalizedPan(cue.Pan)) +} + +func (service *Service) play(ctx context.Context, cue Cue) error { + service.mutex.Lock() + player, theme, volume := service.player, service.theme, service.volume + if _, valid := progress_percentage(cue.Name); valid { + volume = 1 + } + cacheKey := theme + "\x00" + cue.Name + data, exists := service.cache[cacheKey] + service.mutex.Unlock() + if !exists { + var err error + data, err = soundData(theme, cue.Name) + if err != nil { + return err + } + service.mutex.Lock() + if !generated_tone(cue.Name) { + service.cache[cacheKey] = data + } + service.mutex.Unlock() + } + playContext, cancel := context.WithTimeout(ctx, 3*time.Second) + defer cancel() + return player.Play(playContext, data, volume, normalizedPan(cue.Pan)) +} + +func normalizedPan(pan float64) float64 { + if math.IsNaN(pan) || math.IsInf(pan, 0) || pan < -1 || pan > 1 { + return 0 + } + return pan +} + +var namedCues = []string{ + "start", "stop", "button", "checkbox_checked", "checkbox_mixed", "checkbox_unchecked", + "autocomplete", "combobox", "link", "link_visited", "radiobutton_checked", "radiobutton_unchecked", + "togglebutton_checked", "togglebutton_unchecked", "switch_on", "switch_off", "browse_mode", "focus_mode", +} + +func cueAvailability(theme string) map[string]bool { + available := make(map[string]bool, len(namedCues)) + for _, name := range namedCues { + if data, err := load_sound(theme, name); err == nil && len(data) <= maxSoundBytes { + available[name] = true + } + } + return available +} + +// Called under the service mutex. Progress output is controlled by its own +// output mode, independent of role-sound enablement, theme and volume. +func (service *Service) cue_available(name string) bool { + if _, valid := indentation_frequency(name); valid { + return service.enabled && service.theme != "none" && service.volume > 0 + } + if _, valid := progress_percentage(name); valid { + return true + } + if _, valid := set_position(name); valid { + return service.enabled && service.theme != "none" && service.volume > 0 + } + return service.enabled && service.available[name] +} + +func generated_tone(name string) bool { + _, indentation := indentation_frequency(name) + _, progress := progress_percentage(name) + _, position := set_position(name) + return progress || position || indentation +} + +func soundData(theme, cue string) ([]byte, error) { + if strings.HasPrefix(cue, indentationCuePrefix) { + frequency, valid := indentation_frequency(cue) + if !valid { + return nil, errors.New("invalid generated indentation tone") + } + return indentation_tone_wav(frequency), nil + } + if strings.HasPrefix(cue, positionCuePrefix) { + position, valid := set_position(cue) + if !valid { + return nil, errors.New("invalid generated position tone") + } + return position_tone_wav(position), nil + } + if strings.HasPrefix(cue, progressCuePrefix) { + percentage, valid := progress_percentage(cue) + if !valid { + return nil, errors.New("invalid generated progress tone") + } + return progress_tone_wav(percentage), nil + } + return load_sound(theme, cue) +} + +// Stop cancels any active cue, discards pending cues, and plays the stop cue +// with the caller's shutdown deadline. The sound service never owns speech. +func (service *Service) Stop(ctx context.Context) error { + service.stopMutex.Lock() + defer service.stopMutex.Unlock() + service.mutex.Lock() + if service.done == nil { + service.mutex.Unlock() + return nil + } + playStopCue := (service.running && service.enabled && service.available["stop"]) || service.stopPending + service.running = false + service.discardPending() + service.stopPending = true + done := service.done + if done != nil { + service.cancel() + } + service.mutex.Unlock() + if done != nil { + select { + case <-done: + case <-ctx.Done(): + return ctx.Err() + } + } + if playStopCue { + if err := service.play(ctx, Cue{Name: "stop"}); err != nil { + return err + } + } + service.mutex.Lock() + service.stopPending = false + service.done = nil + service.mutex.Unlock() + return nil +} + +func load_sound(theme, cue string) ([]byte, error) { + if filepath.Base(theme) != theme || theme == "." || theme == ".." || filepath.Base(cue) != cue || cue == "." || cue == ".." { + return nil, errors.New("invalid sound theme or cue name") + } + if theme == "default" { + return bundled.Default.ReadFile("default/" + cue + ".wav") + } + dataHome := os.Getenv("XDG_DATA_HOME") + if dataHome == "" { + home, err := os.UserHomeDir() + if err != nil { + return nil, err + } + dataHome = filepath.Join(home, ".local", "share") + } + file, err := os.Open(filepath.Join(dataHome, "cthulhu", "sounds", theme, cue+".wav")) + if err != nil { + return nil, err + } + defer file.Close() + data, err := io.ReadAll(io.LimitReader(file, maxSoundBytes+1)) + if err != nil { + return nil, err + } + if len(data) > maxSoundBytes { + return nil, fmt.Errorf("sound exceeds %d bytes", maxSoundBytes) + } + return data, nil +} diff --git a/internal/sound/service_test.go b/internal/sound/service_test.go new file mode 100644 index 0000000..e5595e1 --- /dev/null +++ b/internal/sound/service_test.go @@ -0,0 +1,628 @@ +package sound + +import ( + "bytes" + "context" + "errors" + "fmt" + "log/slog" + "os" + "path/filepath" + "sync" + "testing" + "time" +) + +func TestBundledSoundsDecodeInProcess(t *testing.T) { + if !cueAvailability("default")["autocomplete"] { + t.Fatal("default theme does not offer the autocomplete cue") + } + for _, cue := range []string{"start", "stop", "autocomplete", "button", "checkbox_checked", "checkbox_mixed", "checkbox_unchecked", "combobox", "link", "link_visited", "radiobutton_checked", "radiobutton_unchecked", "togglebutton_checked", "togglebutton_unchecked", "switch_on", "switch_off", "browse_mode", "focus_mode"} { + t.Run(cue, func(t *testing.T) { + data, err := load_sound("default", cue) + if err != nil { + t.Fatal(err) + } + // The first GStreamer initialization can exceed one second on a + // cold process even when the cue itself is short. + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := (NativePlayer{Sink: "test"}).Play(ctx, data, 0.5, 0); err != nil { + t.Fatal(err) + } + }) + } +} + +func TestGeneratedProgressSoundsDecodeInProcess(t *testing.T) { + for _, percentage := range []int{0, 50, 99, 100} { + data, err := soundData("default", fmt.Sprintf("generated-progress-tone:%d", percentage)) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) + err = (NativePlayer{Sink: "test"}).Play(ctx, data, 0.5, 0) + cancel() + if err != nil { + t.Fatalf("percentage %d: %v", percentage, err) + } + } + if _, err := soundData("default", "generated-progress-tone:101"); err == nil { + t.Fatal("accepted invalid generated progress tone") + } +} + +func TestBundledSoundPanDecodes(t *testing.T) { + data, err := load_sound("default", "button") + if err != nil { + t.Fatal(err) + } + for _, pan := range []float64{-1, 0, 0.35, 1} { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + err := (NativePlayer{Sink: "test"}).Play(ctx, data, 0.5, pan) + cancel() + if err != nil { + t.Fatalf("pan %v: %v", pan, err) + } + } +} + +func TestThemePathsAndSizeAreBounded(t *testing.T) { + t.Setenv("XDG_DATA_HOME", t.TempDir()) + for _, name := range []string{"..", "../other", "/tmp/other"} { + if _, err := load_sound(name, "start"); err == nil { + t.Fatalf("accepted theme %q", name) + } + if _, err := load_sound("default", name); err == nil { + t.Fatalf("accepted cue %q", name) + } + } + path := filepath.Join(os.Getenv("XDG_DATA_HOME"), "cthulhu", "sounds", "custom") + if err := os.MkdirAll(path, 0o700); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(path, "start.wav"), []byte("custom"), 0o600); err != nil { + t.Fatal(err) + } + data, err := load_sound("custom", "start") + if err != nil || string(data) != "custom" { + t.Fatalf("custom theme = %q, %v", data, err) + } + if err := os.WriteFile(filepath.Join(path, "start.wav"), make([]byte, maxSoundBytes+1), 0o600); err != nil { + t.Fatal(err) + } + if _, err := load_sound("custom", "start"); err == nil { + t.Fatal("accepted oversized sound") + } +} + +type blockingPlayer struct { + started chan struct{} + calls int +} + +func TestQueueReplacementDoesNotBlockConcurrentConsumer(t *testing.T) { + service := New(slog.New(slog.DiscardHandler), nil, "default", 0.5) + service.running = true + service.enabled = true + service.available = map[string]bool{"button": true} + ctx, cancel := context.WithCancel(context.Background()) + consumerDone := make(chan struct{}) + go func() { + defer close(consumerDone) + for { + if ctx.Err() != nil { + return + } + select { + case <-ctx.Done(): + return + case <-service.queue: + // The runtime receives before taking the playback mutex. + service.mutex.Lock() + service.mutex.Unlock() + } + } + }() + done := make(chan struct{}) + go func() { + defer close(done) + for range 100000 { + if ctx.Err() != nil { + return + } + service.Enqueue(Cue{Name: "button"}) + } + }() + select { + case <-done: + cancel() + <-consumerDone + case <-time.After(5 * time.Second): + cancel() + // Release a blocked drain so both test goroutines can be joined. + service.queue <- queuedCue{} + <-done + <-consumerDone + t.Fatal("queue replacement blocked while the consumer waited for the mutex") + } +} + +type interruptPlayer struct { + started chan struct{} + canceled chan struct{} + played chan []byte + once sync.Once +} + +func (player *interruptPlayer) Play(ctx context.Context, data []byte, _, _ float64) error { + first := false + player.once.Do(func() { first = true; close(player.started) }) + if first { + <-ctx.Done() + close(player.canceled) + return ctx.Err() + } + player.played <- data + return nil +} + +func TestNewPresentationInterruptsOldCueAndDiscardsPendingCues(t *testing.T) { + player := &interruptPlayer{started: make(chan struct{}), canceled: make(chan struct{}), played: make(chan []byte, 2)} + service := New(slog.New(slog.DiscardHandler), player, "default", 0.5) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + if !service.Enqueue(Cue{Name: "button"}) { + t.Fatal("initial cue rejected") + } + select { + case <-player.started: + case <-time.After(time.Second): + t.Fatal("initial cue did not start") + } + for range 20 { + if !service.Enqueue(Cue{Name: "link"}) { + t.Fatal("new link cue rejected") + } + } + select { + case <-player.canceled: + case <-time.After(time.Second): + t.Fatal("initial cue was not interrupted") + } + want, err := load_sound("default", "link") + if err != nil { + t.Fatal(err) + } + select { + case got := <-player.played: + if !bytes.Equal(got, want) { + t.Fatal("played stale cue instead of latest link") + } + case <-time.After(time.Second): + t.Fatal("latest link cue did not play") + } + if len(service.queue) != 0 { + t.Fatal("stale link cues remained queued") + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } +} + +type configuredPlayback struct { + volume float64 + pan float64 +} + +type configurationPlayer struct { + played chan configuredPlayback +} + +type reconfigurePlayer struct { + started chan struct{} + release chan struct{} + canceled chan struct{} + played chan struct{} + once sync.Once +} + +func (player *reconfigurePlayer) Play(ctx context.Context, _ []byte, _, _ float64) error { + first := false + player.once.Do(func() { + first = true + close(player.started) + }) + if first { + select { + case <-player.release: + case <-ctx.Done(): + close(player.canceled) + return ctx.Err() + } + return nil + } + player.played <- struct{}{} + return nil +} + +func (player *configurationPlayer) Play(_ context.Context, _ []byte, volume, pan float64) error { + player.played <- configuredPlayback{volume: volume, pan: pan} + return nil +} + +func TestCuePanIsValidatedAndPassedToPlayer(t *testing.T) { + player := &configurationPlayer{played: make(chan configuredPlayback, 2)} + service := New(slog.New(slog.DiscardHandler), player, "default", 0.5) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + service.Enqueue(Cue{Name: "button", Pan: 0.5}) + select { + case playback := <-player.played: + if playback.pan != 0.5 { + t.Fatalf("pan = %v, want 0.5", playback.pan) + } + case <-time.After(time.Second): + t.Fatal("panned cue was not played") + } + service.Enqueue(Cue{Name: "button", Pan: 2}) + select { + case playback := <-player.played: + if playback.pan != 0 { + t.Fatalf("invalid pan = %v, want centered", playback.pan) + } + case <-time.After(time.Second): + t.Fatal("invalid-pan cue was not played") + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } +} + +func TestCustomThemeCueSupportsPan(t *testing.T) { + dataHome := t.TempDir() + t.Setenv("XDG_DATA_HOME", dataHome) + path := filepath.Join(dataHome, "cthulhu", "sounds", "custom") + if err := os.MkdirAll(path, 0o700); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(path, "button.wav"), []byte("custom wav"), 0o600); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(path, "stop.wav"), []byte("custom stop"), 0o600); err != nil { + t.Fatal(err) + } + player := &configurationPlayer{played: make(chan configuredPlayback, 1)} + service := New(slog.New(slog.DiscardHandler), player, "custom", 0.5) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + if !service.Available("button") { + t.Fatal("custom theme cue was not available") + } + service.Enqueue(Cue{Name: "button", Pan: -1}) + select { + case playback := <-player.played: + if playback.pan != -1 { + t.Fatalf("custom cue pan = %v, want -1", playback.pan) + } + case <-time.After(time.Second): + t.Fatal("custom cue was not played") + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } +} + +func TestConfigureAppliesEnableAndVolumeToSubsequentCues(t *testing.T) { + player := &configurationPlayer{played: make(chan configuredPlayback, 2)} + service := New(slog.New(slog.DiscardHandler), player, "default", 0.5) + service.Configure(Configuration{Enabled: false, Sink: "auto", Theme: "default", Volume: 0.5}) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + service.Enqueue(Cue{Name: "button"}) + if len(service.queue) != 0 { + t.Fatal("disabled service queued a cue") + } + service.Configure(Configuration{Enabled: true, Sink: "pulse", Theme: "default", Volume: 0.8}) + service.Enqueue(Cue{Name: "button"}) + select { + case playback := <-player.played: + if playback.volume != 0.8 { + t.Fatalf("volume = %v, want 0.8", playback.volume) + } + case <-time.After(time.Second): + t.Fatal("configured cue was not played") + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } +} + +func TestConfigureCancelsActiveOldPolicyCue(t *testing.T) { + player := &reconfigurePlayer{started: make(chan struct{}), release: make(chan struct{}), canceled: make(chan struct{}), played: make(chan struct{}, 1)} + service := New(slog.New(slog.DiscardHandler), player, "default", 0.5) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + if !service.Enqueue(Cue{Name: "button"}) { + t.Fatal("first cue was not admitted") + } + select { + case <-player.started: + case <-time.After(time.Second): + t.Fatal("first cue did not start") + } + service.Configure(Configuration{Enabled: false, Theme: "default", Volume: 0.5}) + select { + case <-player.canceled: + case <-time.After(time.Second): + t.Fatal("active old-policy cue was not canceled") + } + select { + case <-player.played: + t.Fatal("old-policy pending cue played after reconfiguration") + case <-time.After(30 * time.Millisecond): + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } +} + +func TestCueBatchAdmissionIsAtomic(t *testing.T) { + player := &blockingPlayer{started: make(chan struct{})} + service := New(slog.New(slog.DiscardHandler), player, "default", 0.5) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + if !service.Enqueue(Cue{Name: "start"}) { + t.Fatal("blocking cue was not admitted") + } + select { + case <-player.started: + case <-time.After(time.Second): + t.Fatal("sound worker did not start") + } + batch := make([]Cue, queueCapacity+1) + for index := range batch { + batch[index] = Cue{Name: "button"} + } + if service.EnqueueBatch(batch) { + t.Fatal("oversized presentation batch was admitted") + } + if len(service.queue) != 0 { + t.Fatal("part of rejected presentation batch was queued") + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } +} + +func TestPartialCustomThemeStopsWithoutShutdownCue(t *testing.T) { + dataHome := t.TempDir() + t.Setenv("XDG_DATA_HOME", dataHome) + path := filepath.Join(dataHome, "cthulhu", "sounds", "partial") + if err := os.MkdirAll(path, 0o700); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(path, "button.wav"), []byte("button"), 0o600); err != nil { + t.Fatal(err) + } + service := New(slog.New(slog.DiscardHandler), &configurationPlayer{played: make(chan configuredPlayback, 1)}, "partial", 0.5) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } +} + +func (player *blockingPlayer) Play(ctx context.Context, _ []byte, _, _ float64) error { + player.calls++ + if player.calls == 1 { + close(player.started) + <-ctx.Done() + return ctx.Err() + } + return nil +} + +func TestSoundWorkerBoundsQueueAndStopsActiveCue(t *testing.T) { + player := &blockingPlayer{started: make(chan struct{})} + service := New(slog.New(slog.DiscardHandler), player, "default", 0.5) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + service.Enqueue(Cue{Name: "start"}) + select { + case <-player.started: + case <-time.After(time.Second): + t.Fatal("sound worker did not start") + } + batch := make([]Cue, queueCapacity+1) + for index := range batch { + batch[index] = Cue{Name: "button"} + } + service.EnqueueBatch(batch) + if service.dropped.Load() == 0 { + t.Fatal("overflow not counted") + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } + if player.calls != 2 { + t.Fatalf("played %d cues; expected active cue then stop", player.calls) + } + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } + if player.calls != 2 { + t.Fatal("repeated stop played another cue") + } +} + +func TestStopPlaysShutdownCueAfterOversizedPresentation(t *testing.T) { + stopData, err := load_sound("default", "stop") + if err != nil { + t.Fatal(err) + } + player := &queueBlockingPlayer{stopData: stopData, entered: make(chan struct{})} + service := New(slog.New(slog.DiscardHandler), player, "default", 0.5) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + service.Enqueue(Cue{Name: "button"}) + select { + case <-player.entered: + case <-time.After(time.Second): + t.Fatal("sound worker did not start") + } + batch := make([]Cue, queueCapacity+1) + for index := range batch { + batch[index] = Cue{Name: "button"} + } + service.EnqueueBatch(batch) + if service.dropped.Load() == 0 { + t.Fatal("oversized presentation was not dropped") + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } + if player.stopCalls != 1 { + t.Fatalf("played %d stop cues; expected 1", player.stopCalls) + } + if err := service.Stop(ctx); err != nil { + t.Fatal(err) + } + if player.stopCalls != 1 { + t.Fatalf("repeated stop played %d stop cues; expected no more", player.stopCalls) + } +} + +func TestStopTimeoutPreservesShutdownCueForRetry(t *testing.T) { + stopData, err := load_sound("default", "stop") + if err != nil { + t.Fatal(err) + } + player := &stagedStopPlayer{stopData: stopData, entered: make(chan struct{}), release: make(chan struct{})} + service := New(slog.New(slog.DiscardHandler), player, "default", 0.5) + if err := service.Start(context.Background()); err != nil { + t.Fatal(err) + } + service.Enqueue(Cue{Name: "button"}) + select { + case <-player.entered: + case <-time.After(time.Second): + t.Fatal("sound worker did not start") + } + + timeoutContext, cancelTimeout := context.WithTimeout(context.Background(), 10*time.Millisecond) + defer cancelTimeout() + if err := service.Stop(timeoutContext); !errors.Is(err, context.DeadlineExceeded) { + t.Fatalf("timed-out Stop error = %v; want deadline exceeded", err) + } + close(player.release) + + retryContext, cancelRetry := context.WithTimeout(context.Background(), time.Second) + defer cancelRetry() + if err := service.Stop(retryContext); err != nil { + t.Fatal(err) + } + if player.stopCalls != 1 { + t.Fatalf("played %d stop cues; expected 1 after retry", player.stopCalls) + } +} + +type stopCountingPlayer struct { + stopData []byte + stopCalls int +} + +type queueBlockingPlayer struct { + stopData []byte + entered chan struct{} + enterOnce sync.Once + stopCalls int +} + +func (player *queueBlockingPlayer) Play(ctx context.Context, data []byte, _, _ float64) error { + if bytes.Equal(data, player.stopData) { + player.stopCalls++ + return nil + } + player.enterOnce.Do(func() { close(player.entered) }) + <-ctx.Done() + return ctx.Err() +} + +func (player *stopCountingPlayer) Play(_ context.Context, data []byte, _, _ float64) error { + if bytes.Equal(data, player.stopData) { + player.stopCalls++ + } + return nil +} + +type stagedStopPlayer struct { + stopData []byte + entered chan struct{} + release chan struct{} + stopCalls int +} + +func (player *stagedStopPlayer) Play(_ context.Context, data []byte, _, _ float64) error { + if bytes.Equal(data, player.stopData) { + player.stopCalls++ + return nil + } + close(player.entered) + <-player.release + return nil +} + +func TestCancelledNativeSoundDoesNotStart(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if err := (NativePlayer{Sink: "test"}).Play(ctx, []byte("invalid"), 0.5, 0); !errors.Is(err, context.Canceled) { + t.Fatal(err) + } +} + +func TestLiveSound(t *testing.T) { + if os.Getenv("CTHULHU_LIVE_SOUND") != "1" { + t.Skip("explicit live audio test") + } + for _, cue := range []string{"start", "stop"} { + data, err := load_sound("default", cue) + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + err = (NativePlayer{Sink: "auto"}).Play(ctx, data, 0.5, 0) + cancel() + if err != nil { + t.Fatal(err) + } + } +} diff --git a/internal/sound/speech_beep.go b/internal/sound/speech_beep.go new file mode 100644 index 0000000..a549d13 --- /dev/null +++ b/internal/sound/speech_beep.go @@ -0,0 +1,35 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "context" + "time" +) + +var speechBeepWAV = tone_wav(440, 40*time.Millisecond, 0.35, 5*time.Millisecond) +var capitalBeepWAV = nvda_tone_wav(2000, 50) + +// SpeechBeep replaces an utterance, independently of role-sound enablement or +// theme availability. The speech worker owns its ordering and cancellation; +// sound preferences still supply the output sink and volume. +func (service *Service) SpeechBeep(ctx context.Context) error { + return service.play_speech_beep(ctx, speechBeepWAV) +} + +// CapitalBeep is ordered and canceled by the speech worker, just like speech. +// It uses sound volume and sink, independently of the role sound theme. +func (service *Service) CapitalBeep(ctx context.Context) error { + return service.play_speech_beep(ctx, capitalBeepWAV) +} + +func (service *Service) play_speech_beep(ctx context.Context, data []byte) error { + service.mutex.Lock() + player, volume := service.player, service.volume + service.mutex.Unlock() + beepContext, cancelBeep := context.WithTimeout(ctx, 3*time.Second) + defer cancelBeep() + return player.Play(beepContext, data, volume, 0) +} diff --git a/internal/sound/speech_beep_test.go b/internal/sound/speech_beep_test.go new file mode 100644 index 0000000..a15e2be --- /dev/null +++ b/internal/sound/speech_beep_test.go @@ -0,0 +1,51 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "context" + "crypto/sha256" + "encoding/binary" + "errors" + "fmt" + "log/slog" + "testing" + "time" +) + +func TestSpeechBeepDecodesWithRoleSoundsDisabled(t *testing.T) { + service := New(slog.New(slog.DiscardHandler), NativePlayer{Sink: "auto"}, "default", 0.5) + service.Configure(Configuration{Enabled: false, Theme: "none", Sink: "test", Volume: 0.4}) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + if err := service.SpeechBeep(ctx); err != nil { + t.Fatal(err) + } + canceled, cancelBeep := context.WithCancel(ctx) + cancelBeep() + if err := service.SpeechBeep(canceled); !errors.Is(err, context.Canceled) { + t.Fatalf("canceled beep = %v", err) + } +} + +func TestCapitalBeepMatchesNVDAAndDecodes(t *testing.T) { + // PCM from NVDA's C++ generateBeep(2000, 50, 50, 50), compiled separately. + if got := fmt.Sprintf("%x", sha256.Sum256(capitalBeepWAV[44:])); got != "3385e0c7e50f2b4abd8da47606999f27b651e999bcc04ba853e3a7338f469367" { + t.Fatalf("capital beep differs from NVDA: %s", got) + } + if binary.LittleEndian.Uint32(capitalBeepWAV[24:]) != 44100 || binary.LittleEndian.Uint16(capitalBeepWAV[22:]) != 2 { + t.Fatal("capital beep must be 44100 Hz stereo") + } + service := New(slog.New(slog.DiscardHandler), NativePlayer{Sink: "test"}, "none", 0.5) + service.Configure(Configuration{Enabled: false, Theme: "none", Sink: "test", Volume: 0.4}) + if err := service.CapitalBeep(context.Background()); err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if err := service.CapitalBeep(ctx); !errors.Is(err, context.Canceled) { + t.Fatalf("canceled capital beep: %v", err) + } +} diff --git a/internal/sound/tone.go b/internal/sound/tone.go new file mode 100644 index 0000000..60096a5 --- /dev/null +++ b/internal/sound/tone.go @@ -0,0 +1,45 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "bytes" + "encoding/binary" + "math" + "time" +) + +// tone_wav generates mono, 16-bit PCM at 22050 Hz for the existing Player. +// Callers supply a positive frequency/duration, amplitude in [0, 1], and a +// nonnegative edge ramp. A zero ramp preserves an unsmoothed sine tone. +// Playback volume, pan, queuing, and cancellation belong to the sound service. +func tone_wav(frequency float64, duration time.Duration, amplitude float64, ramp time.Duration) []byte { + const sampleRate = 22050 + sampleCount := int(float64(sampleRate) * duration.Seconds()) + rampSamples := int(float64(sampleRate) * ramp.Seconds()) + dataSize := sampleCount * 2 + buffer := bytes.NewBuffer(make([]byte, 0, 44+dataSize)) + buffer.WriteString("RIFF") + _ = binary.Write(buffer, binary.LittleEndian, uint32(36+dataSize)) + buffer.WriteString("WAVEfmt ") + _ = binary.Write(buffer, binary.LittleEndian, uint32(16)) + _ = binary.Write(buffer, binary.LittleEndian, uint16(1)) + _ = binary.Write(buffer, binary.LittleEndian, uint16(1)) + _ = binary.Write(buffer, binary.LittleEndian, uint32(sampleRate)) + _ = binary.Write(buffer, binary.LittleEndian, uint32(sampleRate*2)) + _ = binary.Write(buffer, binary.LittleEndian, uint16(2)) + _ = binary.Write(buffer, binary.LittleEndian, uint16(16)) + buffer.WriteString("data") + _ = binary.Write(buffer, binary.LittleEndian, uint32(dataSize)) + for sample := 0; sample < sampleCount; sample++ { + envelope := 1.0 + if rampSamples > 0 { + envelope = min(1.0, float64(min(sample, sampleCount-1-sample))/float64(rampSamples)) + } + value := int16(math.Sin(2*math.Pi*frequency*float64(sample)/sampleRate) * amplitude * envelope * math.MaxInt16) + _ = binary.Write(buffer, binary.LittleEndian, value) + } + return buffer.Bytes() +} diff --git a/internal/sound/tone_test.go b/internal/sound/tone_test.go new file mode 100644 index 0000000..a504c32 --- /dev/null +++ b/internal/sound/tone_test.go @@ -0,0 +1,19 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package sound + +import ( + "crypto/sha256" + "fmt" + "testing" +) + +func TestTonePreservesSpeechAudio(t *testing.T) { + // Preserve the accepted speech beep while progress audio follows NVDA. + const speechDigest = "2f0184d3deefce36901b9a940d5caefde08e15058898d20c398ad10ad1ce1b94" + if got := fmt.Sprintf("%x", sha256.Sum256(speechBeepWAV)); got != speechDigest { + t.Fatalf("speech beep audio changed: %s", got) + } +} diff --git a/internal/speech/address.go b/internal/speech/address.go new file mode 100644 index 0000000..5157b03 --- /dev/null +++ b/internal/speech/address.go @@ -0,0 +1,84 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "fmt" + "net" + "os" + "path/filepath" + "strconv" + "strings" +) + +type serverAddress struct { + network string + address string +} + +// DefaultSocketAddress follows the default used by the Python speechd client. +func DefaultSocketAddress() string { + runtimeDirectory := os.Getenv("XDG_RUNTIME_DIR") + if runtimeDirectory == "" { + runtimeDirectory = os.Getenv("XDG_CACHE_HOME") + } + if runtimeDirectory == "" { + cacheDirectory, err := os.UserCacheDir() + if err == nil { + runtimeDirectory = cacheDirectory + } + } + return filepath.Join(runtimeDirectory, "speech-dispatcher", "speechd.sock") +} + +// resolveServerAddress gives an explicit CLI socket priority over speechd's +// standard address variables. SPEECHD_SOCKET is the older Unix-only setting. +func resolveServerAddress(socket string) (serverAddress, error) { + if socket != "" { + return serverAddress{network: "unix", address: socket}, nil + } + if address := os.Getenv("SPEECHD_ADDRESS"); address != "" { + return parseServerAddress(address) + } + if socket := os.Getenv("SPEECHD_SOCKET"); socket != "" { + return serverAddress{network: "unix", address: socket}, nil + } + return serverAddress{network: "unix", address: DefaultSocketAddress()}, nil +} + +func parseServerAddress(address string) (serverAddress, error) { + method, value, _ := strings.Cut(address, ":") + switch method { + case "unix_socket": + if value == "" { + value = DefaultSocketAddress() + } + if !filepath.IsAbs(value) { + return serverAddress{}, fmt.Errorf("Speech Dispatcher Unix socket must be an absolute path: %q", value) + } + return serverAddress{network: "unix", address: value}, nil + case "inet_socket": + host, port := "127.0.0.1", 6560 + if value != "" { + parts := strings.Split(value, ":") + if len(parts) > 2 { + return serverAddress{}, fmt.Errorf("invalid Speech Dispatcher address %q", address) + } + if parts[0] != "" { + host = parts[0] + } + if len(parts) == 2 { + parsed, err := strconv.Atoi(parts[1]) + if err != nil || parsed < 1 || parsed > 65535 { + return serverAddress{}, fmt.Errorf("invalid Speech Dispatcher port in %q", address) + } + port = parsed + } + } + return serverAddress{network: "tcp4", address: net.JoinHostPort(host, strconv.Itoa(port))}, nil + default: + return serverAddress{}, fmt.Errorf("unsupported Speech Dispatcher address %q", address) + } +} diff --git a/internal/speech/address_test.go b/internal/speech/address_test.go new file mode 100644 index 0000000..56b91c1 --- /dev/null +++ b/internal/speech/address_test.go @@ -0,0 +1,100 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "context" + "net" + "path/filepath" + "strconv" + "testing" +) + +func TestResolveServerAddressPrecedence(t *testing.T) { + runtimeDirectory := t.TempDir() + cacheDirectory := t.TempDir() + t.Setenv("XDG_RUNTIME_DIR", runtimeDirectory) + t.Setenv("XDG_CACHE_HOME", cacheDirectory) + t.Setenv("SPEECHD_SOCKET", "/tmp/legacy-speech.sock") + t.Setenv("SPEECHD_ADDRESS", "unix_socket:/tmp/address-speech.sock") + + for _, test := range []struct { + name, override, speechAddress, legacySocket, runtimeDir, want string + }{ + {"explicit", "/tmp/explicit-speech.sock", "unix_socket:/tmp/address-speech.sock", "/tmp/legacy-speech.sock", runtimeDirectory, "/tmp/explicit-speech.sock"}, + {"address", "", "unix_socket:/tmp/address-speech.sock", "/tmp/legacy-speech.sock", runtimeDirectory, "/tmp/address-speech.sock"}, + {"legacy", "", "", "/tmp/legacy-speech.sock", runtimeDirectory, "/tmp/legacy-speech.sock"}, + {"runtime", "", "", "", runtimeDirectory, filepath.Join(runtimeDirectory, "speech-dispatcher", "speechd.sock")}, + {"cache", "", "", "", "", filepath.Join(cacheDirectory, "speech-dispatcher", "speechd.sock")}, + } { + t.Run(test.name, func(t *testing.T) { + t.Setenv("SPEECHD_ADDRESS", test.speechAddress) + t.Setenv("SPEECHD_SOCKET", test.legacySocket) + t.Setenv("XDG_RUNTIME_DIR", test.runtimeDir) + got, err := resolveServerAddress(test.override) + if err != nil || got.network != "unix" || got.address != test.want { + t.Fatalf("address = %+v, error = %v; want %q", got, err, test.want) + } + }) + } +} + +func TestParseServerAddress(t *testing.T) { + for _, test := range []struct { + input, network, address string + }{ + {"unix_socket:/tmp/speech.sock", "unix", "/tmp/speech.sock"}, + {"inet_socket", "tcp4", "127.0.0.1:6560"}, + {"inet_socket:localhost:6561", "tcp4", "localhost:6561"}, + } { + got, err := parseServerAddress(test.input) + if err != nil || got.network != test.network || got.address != test.address { + t.Fatalf("parse %q = %+v, %v", test.input, got, err) + } + } + for _, address := range []string{"invalid:/tmp/speech.sock", "unix_socket:relative.sock", "inet_socket:localhost:0", "inet_socket:localhost:bad"} { + if _, err := parseServerAddress(address); err == nil { + t.Fatalf("accepted invalid address %q", address) + } + } +} + +func TestClientAndDiscoveryHonorSpeechdAddress(t *testing.T) { + path, _ := newSettingsServer(t, func(command string) string { + if command == "LIST OUTPUT_MODULES" { + return "200-test\r\n200 OK\r\n" + } + return "" + }) + t.Setenv("SPEECHD_ADDRESS", "unix_socket:"+path) + t.Setenv("SPEECHD_SOCKET", "/tmp/absent-speech.sock") + client := New("") + defer client.Close(context.Background()) + if err := client.Connect(context.Background()); err != nil { + t.Fatal(err) + } + if _, err := Discover(context.Background(), ""); err != nil { + t.Fatal(err) + } +} + +func TestTCPAddressConnects(t *testing.T) { + listener, err := net.Listen("tcp4", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + defer listener.Close() + server := newSettingsServerListener(t, listener, nil) + port := listener.Addr().(*net.TCPAddr).Port + t.Setenv("SPEECHD_ADDRESS", "inet_socket:127.0.0.1:"+strconv.Itoa(port)) + client := New("") + defer client.Close(context.Background()) + if err := client.Connect(context.Background()); err != nil { + t.Fatal(err) + } + if !server.saw(1, "HISTORY GET CLIENT_ID") { + t.Fatal("speech client did not use the TCP server") + } +} diff --git a/internal/speech/autospawn.go b/internal/speech/autospawn.go new file mode 100644 index 0000000..c09341f --- /dev/null +++ b/internal/speech/autospawn.go @@ -0,0 +1,95 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "context" + "fmt" + "net" + "os" + "os/exec" + "strings" + "time" +) + +type serverDialer func(context.Context, string, string) (net.Conn, error) + +// Like Python speechd, try the existing server first, then ask the daemon to +// spawn according to its own configuration. Never start a local daemon for a +// remote TCP endpoint, and never stop a daemon owned by the session. +func connectWithAutospawn(ctx context.Context, endpoint serverAddress, dial serverDialer, spawn func(context.Context, serverAddress) error) (net.Conn, error) { + conn, err := dial(ctx, endpoint.network, endpoint.address) + if ctx.Err() != nil { + if conn != nil { + _ = conn.Close() + } + return nil, ctx.Err() + } + if err == nil { + return conn, err + } + if spawnErr := spawn(ctx, endpoint); spawnErr != nil { + return nil, fmt.Errorf("%w; autostart Speech Dispatcher: %v", err, spawnErr) + } + retryContext, cancel := context.WithTimeout(ctx, connectTimeout) + defer cancel() + for { + conn, err = dial(retryContext, endpoint.network, endpoint.address) + if err == nil { + return conn, nil + } + timer := time.NewTimer(50 * time.Millisecond) + select { + case <-retryContext.Done(): + timer.Stop() + return nil, fmt.Errorf("after Speech Dispatcher autostart: %w", err) + case <-timer.C: + } + } +} + +func spawnArguments(ctx context.Context, endpoint serverAddress) ([]string, error) { + args := []string{"--spawn"} + if endpoint.network == "unix" { + return append(args, "--communication-method", "unix_socket", "--socket-path", endpoint.address), nil + } + host, port, err := net.SplitHostPort(endpoint.address) + if err != nil { + return nil, err + } + addresses, err := net.DefaultResolver.LookupIPAddr(ctx, host) + if err != nil { + return nil, err + } + if len(addresses) == 0 { + return nil, fmt.Errorf("no addresses for %s", host) + } + for _, address := range addresses { + if !address.IP.IsLoopback() { + return nil, fmt.Errorf("cannot autostart a remote Speech Dispatcher at %s", host) + } + } + return append(args, "--communication-method", "inet_socket", "--port", port), nil +} + +func spawnServer(ctx context.Context, endpoint serverAddress) error { + spawnContext, cancel := context.WithTimeout(ctx, ioTimeout) + defer cancel() + args, err := spawnArguments(spawnContext, endpoint) + if err != nil { + return err + } + command := os.Getenv("SPEECHD_CMD") + if command == "" { + command = "speech-dispatcher" + } + process := exec.CommandContext(spawnContext, command, args...) + process.WaitDelay = 100 * time.Millisecond + output, err := process.CombinedOutput() + if err != nil { + return fmt.Errorf("%s --spawn: %w: %s", command, err, strings.TrimSpace(string(output))) + } + return nil +} diff --git a/internal/speech/autospawn_test.go b/internal/speech/autospawn_test.go new file mode 100644 index 0000000..ba192a4 --- /dev/null +++ b/internal/speech/autospawn_test.go @@ -0,0 +1,183 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "context" + "errors" + "fmt" + "net" + "os" + "os/exec" + "path/filepath" + "reflect" + "strconv" + "strings" + "syscall" + "testing" + "time" +) + +func TestColdSpeechConnectionAutostartsAndRetriesSelectedEndpoint(t *testing.T) { + for _, connectError := range []error{syscall.ENOENT, syscall.ECONNREFUSED} { + t.Run(connectError.Error(), func(t *testing.T) { + endpoint := serverAddress{network: "unix", address: "/tmp/selected-speech.sock"} + client, server := net.Pipe() + defer client.Close() + defer server.Close() + attempts, starts := 0, 0 + got, err := connectWithAutospawn(context.Background(), endpoint, func(_ context.Context, network, address string) (net.Conn, error) { + if network != endpoint.network || address != endpoint.address { + t.Fatal("connection address changed during autostart") + } + attempts++ + if attempts == 1 { + return nil, connectError + } + return client, nil + }, func(_ context.Context, selected serverAddress) error { + if selected != endpoint { + t.Fatal("spawn address differs from selected server") + } + starts++ + return nil + }) + if err != nil || got != client || attempts != 2 || starts != 1 { + t.Fatalf("connection = %v, %v; attempts %d, starts %d", got, err, attempts, starts) + } + }) + } +} + +func TestAutospawnKeepsRefusalAndCancellationErrors(t *testing.T) { + dial := func(context.Context, string, string) (net.Conn, error) { return nil, syscall.ECONNREFUSED } + starts := 0 + spawn := func(context.Context, serverAddress) error { starts++; return errors.New("autospawn disabled") } + _, err := connectWithAutospawn(context.Background(), serverAddress{}, dial, spawn) + if !errors.Is(err, syscall.ECONNREFUSED) || !strings.Contains(err.Error(), "autospawn disabled") || starts != 1 { + t.Fatalf("error = %v, starts = %d", err, starts) + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + _, _ = connectWithAutospawn(ctx, serverAddress{}, dial, spawn) + if starts != 1 { + t.Fatal("canceled connection started a daemon") + } + ctx, cancel = context.WithCancel(context.Background()) + _, err = connectWithAutospawn(ctx, serverAddress{}, func(ctx context.Context, _, _ string) (net.Conn, error) { + if ctx.Err() != nil { + return nil, ctx.Err() + } + return nil, syscall.ECONNREFUSED + }, func(context.Context, serverAddress) error { cancel(); return nil }) + if !errors.Is(err, context.Canceled) { + t.Fatalf("retry error = %v", err) + } +} + +func TestSpeechSpawnArgumentsPreserveEndpointAndRejectRemote(t *testing.T) { + for _, test := range []struct { + endpoint serverAddress + want []string + }{ + {serverAddress{"unix", "/tmp/custom.sock"}, []string{"--spawn", "--communication-method", "unix_socket", "--socket-path", "/tmp/custom.sock"}}, + {serverAddress{"tcp4", "127.0.0.1:6561"}, []string{"--spawn", "--communication-method", "inet_socket", "--port", "6561"}}, + } { + args, err := spawnArguments(context.Background(), test.endpoint) + if err != nil || !reflect.DeepEqual(args, test.want) { + t.Fatalf("arguments = %v, %v", args, err) + } + } + if _, err := spawnArguments(context.Background(), serverAddress{"tcp4", "192.0.2.1:6560"}); err == nil { + t.Fatal("remote server allowed local autospawn") + } +} + +func TestSpeechSpawnUsesConfiguredExecutableAndReportsRefusal(t *testing.T) { + path := filepath.Join(t.TempDir(), "fake-speech-dispatcher") + if err := os.WriteFile(path, []byte("#!/bin/sh\necho 'autospawn disabled by daemon' >&2\nexit 1\n"), 0700); err != nil { + t.Fatal(err) + } + t.Setenv("SPEECHD_CMD", path) + err := spawnServer(context.Background(), serverAddress{"unix", "/tmp/custom.sock"}) + if err == nil || !strings.Contains(err.Error(), "autospawn disabled by daemon") { + t.Fatalf("error = %v", err) + } +} + +func TestExistingSpeechServerDoesNotInvokeSpawn(t *testing.T) { + t.Setenv("SPEECHD_CMD", "/nonexistent/speech-dispatcher") + path, _ := newSettingsServer(t, func(string) string { return "" }) + client := New(path) + if err := client.Connect(context.Background()); err != nil { + t.Fatal(err) + } + defer client.Close(context.Background()) +} + +// Run against a separate dummy-output daemon, never the user's speech server. +func TestNativeSpeechDispatcherColdStart(t *testing.T) { + if os.Getenv("CTHULHU_NATIVE_SPEECH_STARTUP") != "1" { + t.Skip("requires isolated Speech Dispatcher startup") + } + if _, err := exec.LookPath("speech-dispatcher"); err != nil { + t.Fatal(err) + } + for _, staleSocket := range []bool{false, true} { + t.Run(fmt.Sprintf("stale-socket-%v", staleSocket), func(t *testing.T) { + directory, err := os.MkdirTemp("", "speech-start-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(directory) + configPath := filepath.Join(directory, "speechd.conf") + config := "LogLevel 0\nLogDir \"" + directory + "\"\nAddModule \"dummy\" \"sd_dummy\" \"\"\nDefaultModule dummy\nTimeout 1\n" + if err := os.WriteFile(configPath, []byte(config), 0600); err != nil { + t.Fatal(err) + } + pidPath := filepath.Join(directory, "speechd.pid") + wrapper := filepath.Join(directory, "spawn") + script := "#!/bin/sh\nexec speech-dispatcher --config-dir \"$CTHULHU_TEST_SPEECH_CONFIG\" --pid-file \"$CTHULHU_TEST_SPEECH_PID\" \"$@\"\n" + if err := os.WriteFile(wrapper, []byte(script), 0700); err != nil { + t.Fatal(err) + } + t.Setenv("CTHULHU_TEST_SPEECH_CONFIG", directory) + t.Setenv("CTHULHU_TEST_SPEECH_PID", pidPath) + t.Setenv("SPEECHD_CMD", wrapper) + t.Setenv("XDG_RUNTIME_DIR", directory) + t.Setenv("SPEECHD_ADDRESS", "") + t.Setenv("SPEECHD_SOCKET", "") + defer func() { + if data, err := os.ReadFile(pidPath); err == nil { + if pid, err := strconv.Atoi(strings.TrimSpace(string(data))); err == nil { + _ = syscall.Kill(pid, syscall.SIGTERM) + } + } + }() + socket := DefaultSocketAddress() + if staleSocket { + if err := os.MkdirAll(filepath.Dir(socket), 0700); err != nil { + t.Fatal(err) + } + listener, err := net.ListenUnix("unix", &net.UnixAddr{Name: socket, Net: "unix"}) + if err != nil { + t.Fatal(err) + } + listener.SetUnlinkOnClose(false) + listener.Close() + } + client := New("") + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + defer client.Close(context.Background()) + if err := client.Connect(ctx); err != nil { + t.Fatal(err) + } + if client.clientID <= 0 || client.cancelConn == nil { + t.Fatal("cold-start client did not initialize both channels") + } + }) + } +} diff --git a/internal/speech/catalog.go b/internal/speech/catalog.go new file mode 100644 index 0000000..8fa338c --- /dev/null +++ b/internal/speech/catalog.go @@ -0,0 +1,84 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "bufio" + "context" + "fmt" + "net" + "strings" +) + +type Voice struct{ Name, Language, Variant string } +type Catalog map[string][]Voice + +// Discover uses its own connection, so slow modules never hold up speech. +// The empty module selects the server default. +func Discover(ctx context.Context, socket string) (Catalog, error) { + endpoint, err := resolveServerAddress(socket) + if err != nil { + return nil, err + } + conn, err := (&net.Dialer{Timeout: connectTimeout}).DialContext(ctx, endpoint.network, endpoint.address) + if err != nil { + return nil, err + } + defer conn.Close() + client := &Client{conn: conn, reader: bufio.NewReader(conn), ioTimeout: ioTimeout} + query := func(command string) ([]string, error) { + finish, err := prepareIO(ctx, conn, ioTimeout) + if err != nil { + return nil, err + } + defer finish() + if _, err = conn.Write([]byte(command + "\r\n")); err != nil { + return nil, err + } + reply, err := client.readReply() + if err != nil { + return nil, err + } + if reply.code < 200 || reply.code >= 300 { + return nil, fmt.Errorf("voice discovery: %s", reply.text) + } + return reply.data, nil + } + modules, err := query("LIST OUTPUT_MODULES") + if err != nil { + return nil, err + } + catalog := Catalog{} + for _, module := range append([]string{""}, modules...) { + if strings.ContainsAny(module, "\r\n\x00") { + continue + } + if module != "" { + if err := client.sendCommand(ctx, []string{"SET", "SELF", "OUTPUT_MODULE", module}); err != nil { + continue + } + } + rows, err := query("LIST SYNTHESIS_VOICES") + if err != nil { + if ctx.Err() != nil { + return catalog, ctx.Err() + } + continue + } + catalog[module] = nil + for _, row := range rows { + fields := strings.Split(row, "\t") + if len(fields) < 2 { + continue + } + voice := Voice{Name: fields[0], Language: fields[1]} + if len(fields) > 2 { + voice.Variant = fields[2] + } + catalog[module] = append(catalog[module], voice) + } + } + return catalog, nil +} diff --git a/internal/speech/catalog_test.go b/internal/speech/catalog_test.go new file mode 100644 index 0000000..0e14f4e --- /dev/null +++ b/internal/speech/catalog_test.go @@ -0,0 +1,43 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "context" + "testing" +) + +func TestDiscoverVoicesAndOutputModule(t *testing.T) { + path, server := newSettingsServer(t, func(command string) string { + switch command { + case "LIST OUTPUT_MODULES": + return "200-test\r\n200 OK\r\n" + case "LIST SYNTHESIS_VOICES": + return "200-Test Voice\ten-US\tnone\r\n200 OK\r\n" + } + return "" + }) + catalog, err := Discover(context.Background(), path) + if err != nil { + t.Fatal(err) + } + for _, module := range []string{"", "test"} { + voices := catalog[module] + if len(voices) != 1 || voices[0].Name != "Test Voice" || voices[0].Language != "en-US" { + t.Fatalf("catalog=%+v", catalog) + } + } + if !server.saw(1, "SET SELF OUTPUT_MODULE test") { + t.Fatal("did not select module for discovery") + } + client := NewWithSettings(path, Settings{OutputModule: "test", SynthesisVoice: "Test Voice"}) + defer client.Close(context.Background()) + if err := client.Connect(context.Background()); err != nil { + t.Fatal(err) + } + if !server.saw(2, "SET SELF OUTPUT_MODULE test") || !server.saw(2, "SET SELF SYNTHESIS_VOICE Test Voice") { + t.Fatal("echo voice/module not configured") + } +} diff --git a/internal/speech/defaults.go b/internal/speech/defaults.go new file mode 100644 index 0000000..882d3d8 --- /dev/null +++ b/internal/speech/defaults.go @@ -0,0 +1,57 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "bufio" + "context" + "fmt" + "net" + "strconv" +) + +// ReadDefaults queries a fresh client, leaving the speaking client's settings +// alone. Unsupported or invalid fields stay nil so preferences can use sensible +// display values. The caller bounds the entire optional query with a deadline. +func ReadDefaults(ctx context.Context, socket string) (Settings, error) { + var defaults Settings + endpoint, err := resolveServerAddress(socket) + if err != nil { + return defaults, err + } + conn, err := (&net.Dialer{Timeout: connectTimeout}).DialContext(ctx, endpoint.network, endpoint.address) + if err != nil { + return defaults, err + } + defer conn.Close() + finish, err := prepareIO(ctx, conn, ioTimeout) + if err != nil { + return defaults, err + } + defer finish() + client := &Client{conn: conn, reader: bufio.NewReader(conn)} + for _, field := range []struct { + name string + target **int + }{ + {"RATE", &defaults.Rate}, {"PITCH", &defaults.Pitch}, {"VOLUME", &defaults.Volume}, + } { + if _, err := fmt.Fprintf(conn, "GET %s\r\n", field.name); err != nil { + return defaults, err + } + response, err := client.readReply() + if err != nil { + return defaults, err + } + if response.code < 200 || response.code >= 300 || len(response.data) != 1 { + continue + } + value, err := strconv.Atoi(response.data[0]) + if err == nil && value >= -100 && value <= 100 { + *field.target = &value + } + } + return defaults, nil +} diff --git a/internal/speech/defaults_test.go b/internal/speech/defaults_test.go new file mode 100644 index 0000000..546e139 --- /dev/null +++ b/internal/speech/defaults_test.go @@ -0,0 +1,66 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "context" + "testing" + "time" +) + +func TestReadDefaults(t *testing.T) { + path, server := newSettingsServer(t, func(command string) string { + switch command { + case "GET RATE": + return "200-20\r\n200 OK\r\n" + case "GET PITCH": + return "200--10\r\n200 OK\r\n" + case "GET VOLUME": + return "200-100\r\n200 OK\r\n" + } + return "" + }) + defaults, err := ReadDefaults(t.Context(), path) + if err != nil || defaults.Rate == nil || *defaults.Rate != 20 || + defaults.Pitch == nil || *defaults.Pitch != -10 || defaults.Volume == nil || *defaults.Volume != 100 { + t.Fatalf("defaults=%+v, err=%v", defaults, err) + } + for _, command := range []string{"SET SELF RATE 20", "SET SELF PITCH -10", "SET SELF VOLUME 100", "SPEAK"} { + if server.saw(1, command) { + t.Fatalf("query changed speech: %s", command) + } + } +} + +func TestReadDefaultsRejectsUnsupportedAndInvalidValues(t *testing.T) { + for _, response := range []string{"500 UNSUPPORTED\r\n", "200 OK\r\n", "200-invalid\r\n200 OK\r\n", + "200-101\r\n200 OK\r\n", "200-0\r\n200-1\r\n200 OK\r\n"} { + t.Run(response, func(t *testing.T) { + path, _ := newSettingsServer(t, func(string) string { return response }) + defaults, err := ReadDefaults(t.Context(), path) + if err != nil || defaults.Rate != nil || defaults.Pitch != nil || defaults.Volume != nil { + t.Fatalf("invalid defaults=%+v, err=%v", defaults, err) + } + }) + } +} + +func TestReadDefaultsRetainsPartialValuesAndHonorsDeadline(t *testing.T) { + path, _ := newSettingsServer(t, func(command string) string { + if command == "GET RATE" { + return "200-0\r\n200 OK\r\n" + } + if command == "GET PITCH" { + return "200-unfinished\r\n" + } + return "" + }) + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() + defaults, err := ReadDefaults(ctx, path) + if err == nil || defaults.Rate == nil || *defaults.Rate != 0 || defaults.Pitch != nil || defaults.Volume != nil { + t.Fatalf("partial defaults=%+v, err=%v", defaults, err) + } +} diff --git a/internal/speech/hardware.go b/internal/speech/hardware.go new file mode 100644 index 0000000..f68f390 --- /dev/null +++ b/internal/speech/hardware.go @@ -0,0 +1,163 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "context" + "errors" + "fmt" + "math" + "path/filepath" + "strings" + "sync" + "syscall" + "time" +) + +// Hardware ports Python Cthulhu's serial protocols. One owner serializes text +// and settings; cancellation retires a blocked write before sending Ctrl+X. +type Hardware struct { + mu sync.Mutex + ioMu sync.Mutex + fd int + synth string + generation uint64 +} + +type HardwareVoice struct{ Rate, Pitch, Volume *float64 } + +func NewHardware(device, synth string, baud int) (*Hardware, error) { + if !filepath.IsAbs(device) || strings.ContainsAny(device, "\x00\r\n") { + return nil, errors.New("hardware speech requires an explicit serial device path") + } + switch synth { + case "litetalk", "doubletalk", "tripletalk", "dectalk": + default: + return nil, errors.New("unsupported hardware speech synthesizer") + } + fd, err := open_serial(device, baud) + if err != nil { + return nil, err + } + return &Hardware{fd: fd, synth: synth}, nil +} + +func hardware_bytes(synth, text string, voice HardwareVoice) []byte { + data := []byte{} + for index, value := range []*float64{voice.Rate, voice.Pitch, voice.Volume} { + if value == nil { + continue + } + limit := 9.0 + if index == 0 { + limit = 99 + } + normalized := math.Max(0, math.Min(limit, *value)) / limit + if synth == "dectalk" { + minimum := []int{75, 50, 0}[index] + maximum := []int{650, 180, 100}[index] + command := []string{"ra", "dv ap", "vo"}[index] + data = fmt.Appendf(data, "[:%s %d]", command, int(math.RoundToEven(float64(minimum)+normalized*float64(maximum-minimum)))) + } else { + maximum := []int{9, 99, 9}[index] + command := []byte{'S', 'P', 'V'}[index] + data = fmt.Appendf(data, "\x01%d%c", int(math.RoundToEven(normalized*float64(maximum))), command) + } + } + // Devices accept ASCII. Strip control bytes and retain spacing just as + // Python's driver does. + for _, value := range text { + if value < 0x20 || value > 0x7e { + value = ' ' + } + data = append(data, byte(value)) + } + if synth == "dectalk" { + return append(data, 1) + } + return append(data, '\r') +} + +func (client *Hardware) Speak(ctx context.Context, text string, voice HardwareVoice) error { + if text == "" { + return errors.New("speech text is empty") + } + client.mu.Lock() + generation := client.generation + client.mu.Unlock() + client.ioMu.Lock() + defer client.ioMu.Unlock() + return client.write_serial(ctx, hardware_bytes(client.synth, text, voice), generation) +} + +func (client *Hardware) write_serial(ctx context.Context, data []byte, generation uint64) error { + ctx, cancel := context.WithTimeout(ctx, ioTimeout) + defer cancel() + for len(data) > 0 { + if err := ctx.Err(); err != nil { + return err + } + client.mu.Lock() + current := client.generation + client.mu.Unlock() + if generation != current { + return context.Canceled + } + if client.fd < 0 { + return errors.New("hardware speech is closed") + } + written, err := syscall.Write(client.fd, data[:min(256, len(data))]) + if written > 0 { + data = data[written:] + } + if err == syscall.EINTR { + continue + } + if err == syscall.EAGAIN || err == syscall.EWOULDBLOCK { + timer := time.NewTimer(5 * time.Millisecond) + select { + case <-ctx.Done(): + timer.Stop() + return ctx.Err() + case <-timer.C: + } + continue + } + if err != nil { + return fmt.Errorf("write hardware speech: %w", err) + } + if written == 0 { + return errors.New("serial write returned zero bytes") + } + } + return nil +} + +func (client *Hardware) Cancel(ctx context.Context) error { + client.mu.Lock() + client.generation++ + generation := client.generation + client.mu.Unlock() + client.ioMu.Lock() + defer client.ioMu.Unlock() + if client.fd < 0 { + return nil + } + if err := flush_serial(client.fd); err != nil { + return err + } + return client.write_serial(ctx, []byte{0x18}, generation) +} + +func (client *Hardware) Close(ctx context.Context) error { + result := client.Cancel(ctx) + client.ioMu.Lock() + defer client.ioMu.Unlock() + if client.fd >= 0 { + result = errors.Join(result, syscall.Close(client.fd)) + client.fd = -1 + } + return result +} diff --git a/internal/speech/hardware_test.go b/internal/speech/hardware_test.go new file mode 100644 index 0000000..f655a01 --- /dev/null +++ b/internal/speech/hardware_test.go @@ -0,0 +1,29 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import "testing" + +func TestHardwareProtocolsMatchPython(t *testing.T) { + rate, pitch, volume := 99.0, 9.0, 9.0 + voice := HardwareVoice{Rate: &rate, Pitch: &pitch, Volume: &volume} + for _, synth := range []string{"litetalk", "doubletalk", "tripletalk", "dectalk"} { + want := "\x019S\x0199P\x019VHello !\r" + if synth == "dectalk" { + want = "[:ra 650][:dv ap 180][:vo 100]Hello !\x01" + } + if got := string(hardware_bytes(synth, "Hello\n\x01é猫!", voice)); got != want { + t.Fatalf("%s: got %q, want %q", synth, got, want) + } + } + rate, pitch, volume = 0, 0, 0 + if got := string(hardware_bytes("dectalk", "Low", voice)); got != "[:ra 75][:dv ap 50][:vo 0]Low\x01" { + t.Fatal(got) + } + rate, pitch, volume = 49.5, 4.5, 4.5 + if got := string(hardware_bytes("litetalk", "Middle", voice)); got != "\x014S\x0150P\x014VMiddle\r" { + t.Fatal(got) + } +} diff --git a/internal/speech/locale_voices.go b/internal/speech/locale_voices.go new file mode 100644 index 0000000..e3a6596 --- /dev/null +++ b/internal/speech/locale_voices.go @@ -0,0 +1,49 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "os" + "sort" + "strings" +) + +// LocaleVoices prefers the current locale's exact dialect, then its base +// language. An unknown locale retains the catalog, matching quick settings. +func LocaleVoices(voices []Voice) []Voice { + locale := "" + for _, key := range []string{"LC_ALL", "LC_MESSAGES", "LANG"} { + if value := os.Getenv(key); value != "" { + locale = value + break + } + } + normalize := func(value string) string { + value = strings.Split(strings.Split(value, ".")[0], "@")[0] + return strings.ToLower(strings.ReplaceAll(value, "_", "-")) + } + locale = normalize(locale) + if locale == "" || locale == "c" || locale == "posix" { + locale = "en-us" + } + for _, language := range []string{locale, strings.SplitN(locale, "-", 2)[0]} { + var selected []Voice + for _, voice := range voices { + if normalize(voice.Language) == language { + selected = append(selected, voice) + } + } + if len(selected) == 0 { + continue + } + // A '+' in the synthesis name denotes an eSpeak variant; Variant + // is gender metadata and cannot identify the unmodified voice. + sort.SliceStable(selected, func(i, j int) bool { + return !strings.Contains(selected[i].Name, "+") && strings.Contains(selected[j].Name, "+") + }) + return selected + } + return voices +} diff --git a/internal/speech/read_all.go b/internal/speech/read_all.go new file mode 100644 index 0000000..66e4b83 --- /dev/null +++ b/internal/speech/read_all.go @@ -0,0 +1,79 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "context" + "errors" + "time" +) + +// SpeakAndWait uses SSIP BEGIN/END/CANCEL events, not the SPEAK queue +// acknowledgement, to pace continuous reading and report its current position. +// Protocol: https://github.com/brailcom/speechd/blob/master/doc/ssip.texi +func (client *Client) SpeakAndWait(ctx context.Context, text string, began func()) (result error) { + client.mutex.Lock() + defer client.mutex.Unlock() + if client.conn == nil { + return errors.New("speech client is not connected") + } + if err := client.sendCommand(ctx, []string{"SET", "SELF", "NOTIFICATION", "ALL", "on"}); err != nil { + return err + } + defer func() { + if client.conn != nil { + cleanup, cancel := context.WithTimeout(context.Background(), client.ioTimeout) + defer cancel() + if err := client.sendCommand(cleanup, []string{"SET", "SELF", "NOTIFICATION", "ALL", "off"}); err != nil { + result = errors.Join(result, err) + _ = client.conn.Close() + client.conn, client.reader = nil, nil + } + } + }() + if err := client.speak(ctx, text); err != nil { + return err + } + conn := client.conn + // A spoken line may take much longer than the command I/O timeout. + if err := conn.SetDeadline(time.Time{}); err != nil { + return err + } + done := make(chan struct{}) + stop := context.AfterFunc(ctx, func() { + defer close(done) + cleanup, cancel := context.WithTimeout(context.Background(), client.ioTimeout) + defer cancel() + _ = client.Cancel(cleanup) + // Allow the final cancellation notification to be drained, preserving + // the speaking connection for subsequent focus announcements. + _ = conn.SetReadDeadline(time.Now().Add(client.ioTimeout)) + }) + defer func() { + if !stop() { + <-done + } + }() + started := false + for { + event, err := readReply(client.reader) + if err != nil { + _ = conn.Close() + client.conn, client.reader = nil, nil + return errors.Join(ctx.Err(), err) + } + switch event.code { + case 701: + if !started && ctx.Err() == nil && began != nil { + began() + } + started = true + case 702: + return ctx.Err() + case 703: + return context.Canceled + } + } +} diff --git a/internal/speech/read_all_test.go b/internal/speech/read_all_test.go new file mode 100644 index 0000000..686745c --- /dev/null +++ b/internal/speech/read_all_test.go @@ -0,0 +1,84 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "bufio" + "context" + "errors" + "fmt" + "net" + "testing" + "time" +) + +func TestContinuousSpeechWaitsForEndAndSurvivesCancellation(t *testing.T) { + for _, interrupted := range []bool{false, true} { + t.Run(fmt.Sprint(interrupted), func(t *testing.T) { + conn, server := net.Pipe() + control, controlServer := net.Pipe() + client := connectedClient(conn) + client.cancelConn, client.cancelReader, client.clientID = control, bufio.NewReader(control), 42 + t.Cleanup(func() { server.Close(); controlServer.Close(); client.Close(context.Background()) }) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + began := make(chan struct{}, 1) + finished := make(chan error, 1) + go func() { finished <- client.SpeakAndWait(ctx, "First line", func() { began <- struct{}{} }) }() + server.SetDeadline(time.Now().Add(2 * time.Second)) + reader := bufio.NewReader(server) + if err := exchangeSSIP(reader, server, "SET SELF NOTIFICATION ALL on\r\n", "200 OK\r\n"); err != nil { + t.Fatal(err) + } + for _, want := range []string{"SPEAK\r\n", "First line\r\n", ".\r\n"} { + got, err := reader.ReadString('\n') + if err != nil || got != want { + t.Fatalf("speech block %q, %v; want %q", got, err, want) + } + } + fmt.Fprint(server, "230 OK\r\n225-1\r\n225 QUEUED\r\n") + select { + case <-began: + t.Fatal("queue acknowledgement advanced reading position") + case <-finished: + t.Fatal("queue acknowledgement completed speech") + default: + } + fmt.Fprint(server, "701-1\r\n701-42\r\n701 BEGIN\r\n") + select { + case <-began: + case <-time.After(time.Second): + t.Fatal("BEGIN did not update reading position") + } + if interrupted { + cancel() + controlServer.SetDeadline(time.Now().Add(time.Second)) + if err := exchangeSSIP(bufio.NewReader(controlServer), controlServer, "CANCEL 42\r\n", "200 OK\r\n"); err != nil { + t.Fatal(err) + } + fmt.Fprint(server, "703-1\r\n703-42\r\n703 CANCELED\r\n") + } else { + fmt.Fprint(server, "702-1\r\n702-42\r\n702 END\r\n") + } + if err := exchangeSSIP(reader, server, "SET SELF NOTIFICATION ALL off\r\n", "200 OK\r\n"); err != nil { + t.Fatal(err) + } + if err := <-finished; interrupted && !errors.Is(err, context.Canceled) || !interrupted && err != nil { + t.Fatalf("completion = %v", err) + } + // The cancellation notification must not become the next SPEAK reply. + go func() { finished <- client.Speak(context.Background(), "After") }() + for range 3 { + if _, err := reader.ReadString('\n'); err != nil { + t.Fatal(err) + } + } + fmt.Fprint(server, "230 OK\r\n225-2\r\n225 QUEUED\r\n") + if err := <-finished; err != nil { + t.Fatalf("speech after read all: %v", err) + } + }) + } +} diff --git a/internal/speech/serial_native.go b/internal/speech/serial_native.go new file mode 100644 index 0000000..8c24a4e --- /dev/null +++ b/internal/speech/serial_native.go @@ -0,0 +1,65 @@ +//go:build linux && cgo + +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +/* +#include +#include +#include +#include +#include + +static int cth_serial_open(const char *device, int baud) { + speed_t speed; + switch (baud) { + case 1200: speed = B1200; break; + case 2400: speed = B2400; break; + case 4800: speed = B4800; break; + case 9600: speed = B9600; break; + case 19200: speed = B19200; break; + case 38400: speed = B38400; break; + case 57600: speed = B57600; break; + case 115200: speed = B115200; break; + default: return -EINVAL; + } + int fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC); + if (fd < 0) return -errno; + struct termios attrs; + if (tcgetattr(fd, &attrs) < 0) { int error = errno; close(fd); return -error; } + cfmakeraw(&attrs); + attrs.c_cflag |= CLOCAL | CREAD; + attrs.c_cc[VMIN] = attrs.c_cc[VTIME] = 0; + if (cfsetispeed(&attrs, speed) < 0 || cfsetospeed(&attrs, speed) < 0 || + tcsetattr(fd, TCSANOW, &attrs) < 0) { int error = errno; close(fd); return -error; } + return fd; +} +static int cth_serial_flush(int fd) { return tcflush(fd, TCOFLUSH) < 0 ? errno : 0; } +*/ +import "C" + +import ( + "fmt" + "syscall" + "unsafe" +) + +func open_serial(device string, baud int) (int, error) { + value := C.CString(device) + defer C.free(unsafe.Pointer(value)) + fd := int(C.cth_serial_open(value, C.int(baud))) + if fd < 0 { + return -1, fmt.Errorf("open hardware speech device: %w", syscall.Errno(-fd)) + } + return fd, nil +} + +func flush_serial(fd int) error { + if code := C.cth_serial_flush(C.int(fd)); code != 0 { + return fmt.Errorf("flush hardware speech: %w", syscall.Errno(code)) + } + return nil +} diff --git a/internal/speech/serial_native_test.go b/internal/speech/serial_native_test.go new file mode 100644 index 0000000..c655993 --- /dev/null +++ b/internal/speech/serial_native_test.go @@ -0,0 +1,120 @@ +//go:build linux && cgo + +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "bytes" + "context" + "fmt" + "os" + "strings" + "syscall" + "testing" + "time" + "unsafe" +) + +func serial_fixture(t *testing.T) (*os.File, string) { + t.Helper() + fd, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NONBLOCK, 0600) + if err != nil { + t.Fatal(err) + } + master := os.NewFile(uintptr(fd), "serial-test") + t.Cleanup(func() { master.Close() }) + var unlocked int32 + var number uint32 + if _, _, code := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&unlocked))); code != 0 { + t.Fatal(code) + } + if _, _, code := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&number))); code != 0 { + t.Fatal(code) + } + return master, fmt.Sprintf("/dev/pts/%d", number) +} + +func TestHardwareSerialWritesCancelsAndCloses(t *testing.T) { + for _, synth := range []string{"litetalk", "doubletalk", "tripletalk", "dectalk"} { + t.Run(synth, func(t *testing.T) { + master, device := serial_fixture(t) + client, err := NewHardware(device, synth, 9600) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { client.Close(context.Background()) }) + if err := client.Speak(context.Background(), "Serial test", HardwareVoice{}); err != nil { + t.Fatal(err) + } + want := hardware_bytes(synth, "Serial test", HardwareVoice{}) + master.SetReadDeadline(time.Now().Add(time.Second)) + buffer := make([]byte, 256) + n, err := master.Read(buffer) + if err != nil || !bytes.Equal(buffer[:n], want) { + t.Fatalf("bytes=%q error=%v", buffer[:n], err) + } + if err := client.Cancel(context.Background()); err != nil { + t.Fatal(err) + } + n, err = master.Read(buffer) + if err != nil || !bytes.Equal(buffer[:n], []byte{0x18}) { + t.Fatalf("cancel=%q error=%v", buffer[:n], err) + } + if err := client.Close(context.Background()); err != nil { + t.Fatal(err) + } + if err := client.Speak(context.Background(), "Closed", HardwareVoice{}); err == nil { + t.Fatal("closed serial owner accepted speech") + } + }) + } + if client, err := NewHardware("/dev/null", "dectalk", 9600); err == nil { + client.Close(context.Background()) + t.Fatal("non-terminal device accepted") + } +} + +func TestHardwareCancellationRetiresBlockedSerialWrite(t *testing.T) { + _, device := serial_fixture(t) + client, err := NewHardware(device, "litetalk", 9600) + if err != nil { + t.Fatal(err) + } + defer client.Close(context.Background()) + done := make(chan error, 1) + go func() { done <- client.Speak(context.Background(), strings.Repeat("x", 1024*1024), HardwareVoice{}) }() + // Wait until the PTY output queue fills, then use the same cancellation + // path used by keyboard input. No reader drains that queue. + deadline := time.Now().Add(time.Second) + for { + client.mu.Lock() + locked := !client.ioMu.TryLock() + if !locked { + client.ioMu.Unlock() + } + client.mu.Unlock() + if locked { + break + } + if time.Now().After(deadline) { + t.Fatal("serial write did not start") + } + time.Sleep(time.Millisecond) + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := client.Cancel(ctx); err != nil { + t.Fatal(err) + } + select { + case err := <-done: + if err != context.Canceled { + t.Fatalf("blocked write: %v", err) + } + case <-ctx.Done(): + t.Fatal("cancellation did not release serial writer") + } +} diff --git a/internal/speech/serial_unavailable.go b/internal/speech/serial_unavailable.go new file mode 100644 index 0000000..f52e167 --- /dev/null +++ b/internal/speech/serial_unavailable.go @@ -0,0 +1,14 @@ +//go:build !linux || !cgo + +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import "errors" + +func open_serial(string, int) (int, error) { + return -1, errors.New("hardware speech requires Linux and cgo") +} +func flush_serial(int) error { return errors.New("hardware speech requires Linux and cgo") } diff --git a/internal/speech/settings_test.go b/internal/speech/settings_test.go new file mode 100644 index 0000000..580a547 --- /dev/null +++ b/internal/speech/settings_test.go @@ -0,0 +1,258 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speech + +import ( + "bufio" + "context" + "fmt" + "net" + "path/filepath" + "strings" + "sync" + "testing" + "time" +) + +// Each connection gets its own client ID and command history, allowing tests +// to detect settings sent to the old connection or cancellation of the wrong ID. +type settingsServer struct { + mu sync.Mutex + commands map[int][]string + connections []net.Conn + hook func(string) string +} + +func newSettingsServer(t *testing.T, hook func(string) string) (string, *settingsServer) { + t.Helper() + path := filepath.Join(t.TempDir(), "speech.sock") + listener, err := net.Listen("unix", path) + if err != nil { + t.Fatal(err) + } + return path, newSettingsServerListener(t, listener, hook) +} + +func newSettingsServerListener(t *testing.T, listener net.Listener, hook func(string) string) *settingsServer { + t.Helper() + server := &settingsServer{commands: make(map[int][]string), hook: hook} + var handlers sync.WaitGroup + accepted := make(chan struct{}) + go func() { + defer close(accepted) + for id := 1; ; id++ { + conn, err := listener.Accept() + if err != nil { + return + } + server.mu.Lock() + server.connections = append(server.connections, conn) + server.mu.Unlock() + handlers.Add(1) + go func(id int) { + defer handlers.Done() + defer conn.Close() + reader := bufio.NewReader(conn) + for { + line, err := reader.ReadString('\n') + if err != nil { + return + } + command := strings.TrimSpace(line) + server.mu.Lock() + server.commands[id] = append(server.commands[id], command) + server.mu.Unlock() + response := "200 OK\r\n" + if command == "HISTORY GET CLIENT_ID" { + response = fmt.Sprintf("245-%d\r\n245 OK\r\n", id) + } + if command == "SPEAK" { + for { + text, err := reader.ReadString('\n') + if err != nil { + return + } + if text == ".\r\n" { + break + } + } + response = "230 OK\r\n200 QUEUED\r\n" + } + if server.hook != nil { + if override := server.hook(command); override != "" { + response = override + } + } + if _, err := conn.Write([]byte(response)); err != nil { + return + } + } + }(id) + } + }() + t.Cleanup(func() { + listener.Close() + <-accepted + server.mu.Lock() + for _, conn := range server.connections { + conn.Close() + } + server.mu.Unlock() + handlers.Wait() + }) + return server +} + +func (server *settingsServer) saw(id int, command string) bool { + server.mu.Lock() + defer server.mu.Unlock() + for _, got := range server.commands[id] { + if got == command { + return true + } + } + return false +} + +func TestUpdateSettingsSwitchesSpeechAndCancellation(t *testing.T) { + path, server := newSettingsServer(t, nil) + rate := 20 + client := NewWithSettings(path, Settings{Rate: &rate}) + rate = 80 // The constructor must own its settings. + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + defer client.Close(ctx) + if err := client.Connect(ctx); err != nil { + t.Fatal(err) + } + if !server.saw(1, "SET SELF RATE 20") { + t.Fatal("constructor retained caller's rate pointer") + } + if err := client.UpdateSettings(ctx, Settings{Punctuation: "all"}); err != nil { + t.Fatal(err) + } + if err := client.Speak(ctx, "new settings"); err != nil { + t.Fatal(err) + } + if err := client.Cancel(ctx); err != nil { + t.Fatal(err) + } + if !server.saw(3, "SET SELF PUNCTUATION all") || !server.saw(3, "SPEAK") { + t.Fatal("new settings and speech did not use replacement connection") + } + if server.saw(3, "SET SELF RATE 20") || client.settings.Rate != nil { + t.Fatal("omitted rate did not return to fresh-connection defaults") + } + if !server.saw(2, "CANCEL 1") || !server.saw(4, "CANCEL 3") { + t.Fatal("cancellation did not follow the speaking connection") + } +} + +func TestUpdateSettingsRejectionPreservesActiveClient(t *testing.T) { + path, server := newSettingsServer(t, func(command string) string { + if command == "SET SELF PITCH 40" { + return "500 REJECTED\r\n" + } + return "" + }) + client := New(path) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + defer client.Close(ctx) + if err := client.Connect(ctx); err != nil { + t.Fatal(err) + } + rate, pitch := 25, 40 + if err := client.UpdateSettings(ctx, Settings{Rate: &rate, Pitch: &pitch}); err == nil { + t.Fatal("rejected update succeeded") + } + if err := client.Speak(ctx, "still speaking"); err != nil { + t.Fatal(err) + } + if server.saw(2, "CANCEL 1") || server.saw(1, "SET SELF RATE 25") || !server.saw(1, "SPEAK") { + t.Fatal("rejected candidate affected active speech") + } + if client.settings.Rate != nil { + t.Fatal("rejected settings were committed") + } + if err := client.Cancel(ctx); err != nil { + t.Fatal(err) + } +} + +func TestUpdateSettingsPreparationDoesNotBlockSpeechOrReviveClosedClient(t *testing.T) { + preparing, release := make(chan struct{}), make(chan struct{}) + var once sync.Once + unblock := func() { once.Do(func() { close(release) }) } + path, _ := newSettingsServer(t, func(command string) string { + if command == "SET SELF RATE 30" { + close(preparing) + <-release + } + return "" + }) + defer unblock() + client := New(path) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + defer client.Close(ctx) + if err := client.Connect(ctx); err != nil { + t.Fatal(err) + } + done := make(chan error, 1) + go func() { rate := 30; done <- client.UpdateSettings(ctx, Settings{Rate: &rate}) }() + select { + case <-preparing: + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + if err := client.UpdateSettings(ctx, Settings{}); err == nil || !strings.Contains(err.Error(), "already in progress") { + t.Fatalf("overlapping update = %v, want busy error", err) + } + if err := client.Speak(ctx, "while preparing"); err != nil { + t.Fatal(err) + } + if err := client.Cancel(ctx); err != nil { + t.Fatal(err) + } + if err := client.Close(ctx); err != nil { + t.Fatal(err) + } + unblock() + select { + case err := <-done: + if err == nil { + t.Fatal("update revived closed client") + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + if client.conn != nil || client.cancelConn != nil { + t.Fatal("closed client regained connections") + } +} + +func TestUpdateSettingsCanceledContext(t *testing.T) { + path, server := newSettingsServer(t, nil) + client := New(path) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + defer client.Close(ctx) + if err := client.Connect(ctx); err != nil { + t.Fatal(err) + } + canceled, stop := context.WithCancel(ctx) + stop() + if err := client.UpdateSettings(canceled, Settings{}); err == nil { + t.Fatal("canceled update succeeded") + } + if err := client.Speak(ctx, "unchanged"); err != nil { + t.Fatal(err) + } + if server.saw(2, "CANCEL 1") { + t.Fatal("canceled update interrupted speech") + } +} diff --git a/internal/speech/speech.go b/internal/speech/speech.go new file mode 100644 index 0000000..ef7c693 --- /dev/null +++ b/internal/speech/speech.go @@ -0,0 +1,471 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package speech + +import ( + "bufio" + "context" + "errors" + "fmt" + "net" + "strconv" + "strings" + "sync" + "time" + "unicode/utf8" +) + +const ( + connectTimeout = 2 * time.Second + ioTimeout = 5 * time.Second +) + +type Client struct { + socketAddress string + settings Settings + conn net.Conn + reader *bufio.Reader + cancelConn net.Conn + cancelReader *bufio.Reader + clientID int + ioTimeout time.Duration + mutex sync.Mutex + cancelMutex sync.Mutex + settingsMutex sync.Mutex +} + +type Settings struct { + OutputModule string + Rate *int + Pitch *int + Volume *int + Language string + SynthesisVoice string + Punctuation string + Capitalization string +} + +type reply struct { + code int + text string + data []string +} + +func New(socketAddress string) *Client { + return NewWithSettings(socketAddress, Settings{}) +} + +func NewWithSettings(socketAddress string, settings Settings) *Client { + return &Client{socketAddress: socketAddress, settings: cloneSettings(settings), ioTimeout: ioTimeout} +} + +func cloneSettings(settings Settings) Settings { + for _, value := range []**int{&settings.Rate, &settings.Pitch, &settings.Volume} { + if *value != nil { + copy := **value + *value = © + } + } + return settings +} + +// UpdateSettings replaces the complete speech configuration. A fresh pair of +// connections lets omitted settings regain server defaults and prevents a +// rejected SET command from leaving the active client partially configured. +// Preparation leaves Speak and Cancel available. Commit serializes with Speak, +// cancels the old client's queued speech, and switches the cancellation target. +// Only one update may prepare connections at a time; overlapping calls fail. +// Call this from a settings worker, never from the focus or input event path. +func (client *Client) UpdateSettings(ctx context.Context, settings Settings) error { + if !client.settingsMutex.TryLock() { + return errors.New("speech settings update already in progress") + } + defer client.settingsMutex.Unlock() + ctx, cancel := context.WithTimeout(ctx, ioTimeout) + defer cancel() + client.mutex.Lock() + original := client.conn + client.mutex.Unlock() + if original == nil { + return errors.New("speech client is not connected") + } + + candidate := NewWithSettings(client.socketAddress, settings) + defer candidate.Close(context.Background()) + if err := candidate.Connect(ctx); err != nil { + return fmt.Errorf("prepare speech settings: %w", err) + } + + client.mutex.Lock() + defer client.mutex.Unlock() + client.cancelMutex.Lock() + defer client.cancelMutex.Unlock() + if client.conn != original { + return errors.New("speech connection changed while preparing settings") + } + if err := ctx.Err(); err != nil { + return err + } + if err := client.sendCancelCommand(ctx, "CANCEL "+strconv.Itoa(client.clientID)); err != nil { + return fmt.Errorf("cancel speech before applying settings: %w", err) + } + + // Swap ownership so the deferred close releases only the retired pair. + client.conn, candidate.conn = candidate.conn, client.conn + client.reader, candidate.reader = candidate.reader, client.reader + client.cancelConn, candidate.cancelConn = candidate.cancelConn, client.cancelConn + client.cancelReader, candidate.cancelReader = candidate.cancelReader, client.cancelReader + client.clientID, candidate.clientID = candidate.clientID, client.clientID + client.settings = candidate.settings + return nil +} + +func (client *Client) Connect(ctx context.Context) error { + client.mutex.Lock() + defer client.mutex.Unlock() + client.cancelMutex.Lock() + defer client.cancelMutex.Unlock() + if client.conn != nil || client.cancelConn != nil { + return errors.New("speech client already connected") + } + + endpoint, err := resolveServerAddress(client.socketAddress) + if err != nil { + return err + } + dialer := net.Dialer{Timeout: connectTimeout} + conn, err := connectWithAutospawn(ctx, endpoint, dialer.DialContext, spawnServer) + if err != nil { + return fmt.Errorf("connect to Speech Dispatcher at %s: %w", endpoint.address, err) + } + cancelConn, err := dialer.DialContext(ctx, endpoint.network, endpoint.address) + if err != nil { + _ = conn.Close() + return fmt.Errorf("connect cancellation channel to Speech Dispatcher at %s: %w", endpoint.address, err) + } + client.conn = conn + client.reader = bufio.NewReader(conn) + client.cancelConn = cancelConn + client.cancelReader = bufio.NewReader(cancelConn) + if err := client.initialize(ctx); err != nil { + _ = conn.Close() + _ = cancelConn.Close() + client.conn, client.reader = nil, nil + client.cancelConn, client.cancelReader = nil, nil + client.clientID = 0 + return err + } + return nil +} + +// initialize runs with both connection locks held. Cancellation always targets +// the speaking connection's ID, never the separate control connection or ALL. +func (client *Client) initialize(ctx context.Context) error { + if err := client.applySettings(ctx); err != nil { + return err + } + finish, err := prepareIO(ctx, client.conn, client.ioTimeout) + if err != nil { + return err + } + defer finish() + if _, err := client.conn.Write([]byte("HISTORY GET CLIENT_ID\r\n")); err != nil { + return fmt.Errorf("request speech client ID: %w", err) + } + response, err := client.readReply() + if err != nil { + return err + } + if response.code != 245 || len(response.data) != 1 { + return fmt.Errorf("invalid Speech Dispatcher client ID reply: %d %s (expected code 245 and one ID)", response.code, response.text) + } + clientID, err := strconv.Atoi(response.data[0]) + if err != nil || clientID <= 0 { + return errors.New("invalid Speech Dispatcher client ID") + } + client.clientID = clientID + return client.sendCancelCommand(ctx, "SET SELF CLIENT_NAME cthulhu:cthulhu:cancel") +} + +func (client *Client) applySettings(ctx context.Context) error { + commands := [][]string{ + {"SET", "SELF", "CLIENT_NAME", "cthulhu:cthulhu:main"}, + {"SET", "SELF", "PRIORITY", "MESSAGE"}, + } + if client.settings.OutputModule != "" { + commands = append(commands, []string{"SET", "SELF", "OUTPUT_MODULE", client.settings.OutputModule}) + } + if client.settings.Punctuation != "" { + commands = append(commands, []string{"SET", "SELF", "PUNCTUATION", client.settings.Punctuation}) + } + if client.settings.Capitalization != "" { + commands = append(commands, []string{"SET", "SELF", "CAP_LET_RECOGN", client.settings.Capitalization}) + } + for _, setting := range []struct { + name string + value *int + }{ + {name: "RATE", value: client.settings.Rate}, + {name: "PITCH", value: client.settings.Pitch}, + {name: "VOLUME", value: client.settings.Volume}, + } { + if setting.value != nil { + commands = append(commands, []string{"SET", "SELF", setting.name, strconv.Itoa(*setting.value)}) + } + } + if client.settings.Language != "" { + commands = append(commands, []string{"SET", "SELF", "LANGUAGE", client.settings.Language}) + } + if client.settings.SynthesisVoice != "" { + commands = append(commands, []string{"SET", "SELF", "SYNTHESIS_VOICE", client.settings.SynthesisVoice}) + } + + for _, command := range commands { + if err := client.sendCommand(ctx, command); err != nil { + return fmt.Errorf("configure Speech Dispatcher %s: %w", command[2], err) + } + } + return nil +} + +func (client *Client) sendCommand(ctx context.Context, fields []string) error { + for _, field := range fields { + if strings.ContainsAny(field, "\r\n\x00") { + return errors.New("SSIP command contains a control character") + } + } + finish, err := prepareIO(ctx, client.conn, client.ioTimeout) + if err != nil { + return err + } + defer finish() + if _, err := client.conn.Write([]byte(strings.Join(fields, " ") + "\r\n")); err != nil { + return fmt.Errorf("send SSIP command: %w", err) + } + commandReply, err := client.readReply() + if err != nil { + return err + } + if commandReply.code < 200 || commandReply.code >= 300 { + return fmt.Errorf("SSIP command rejected with %d %s", commandReply.code, commandReply.text) + } + return nil +} + +func (client *Client) Speak(ctx context.Context, text string) (result error) { + client.mutex.Lock() + defer client.mutex.Unlock() + return client.speak(ctx, text) +} + +// SpeakCharacter gives the synthesizer a single character as a character, +// preserving repeated adjacent letters during caret and flat review. Spoken +// names such as "space" still use normal speech. +func (client *Client) SpeakCharacter(ctx context.Context, text string) error { + client.mutex.Lock() + defer client.mutex.Unlock() + if utf8.RuneCountInString(text) != 1 || strings.ContainsAny(text, "\r\n\x00") { + return client.speak(ctx, text) + } + if client.conn == nil { + return errors.New("speech client is not connected") + } + return client.sendCommand(ctx, []string{"CHAR", text}) +} + +func (client *Client) speak(ctx context.Context, text string) (result error) { + text, err := normalizeSpeakText(text) + if err != nil { + return err + } + + if client.conn == nil { + return errors.New("speech client is not connected") + } + finish, err := prepareIO(ctx, client.conn, client.ioTimeout) + if err != nil { + return err + } + defer finish() + + defer func() { + if result != nil { + // A partial exchange cannot safely be reused: a late reply could + // otherwise be mistaken for the next command's acknowledgment. + _ = client.conn.Close() + client.conn, client.reader = nil, nil + } + }() + // SSIP doubles a leading dot so it cannot terminate the speech block. + if strings.HasPrefix(text, ".") { + text = "." + text + } + request := "SPEAK\r\n" + text + "\r\n.\r\n" + if _, err := client.conn.Write([]byte(request)); err != nil { + return fmt.Errorf("send speech block: %w", err) + } + accepted, err := client.readReply() + if err != nil { + return err + } + if accepted.code != 230 { + return fmt.Errorf("speech block rejected with %d %s", accepted.code, accepted.text) + } + + queued, err := client.readReply() + if err != nil { + return err + } + if queued.code < 200 || queued.code >= 300 { + return fmt.Errorf("speech queue rejected with %d %s", queued.code, queued.text) + } + return nil +} + +func (client *Client) Cancel(ctx context.Context) error { + client.cancelMutex.Lock() + defer client.cancelMutex.Unlock() + return client.sendCancelCommand(ctx, "CANCEL "+strconv.Itoa(client.clientID)) +} + +func (client *Client) Close(context.Context) error { + client.mutex.Lock() + defer client.mutex.Unlock() + client.cancelMutex.Lock() + defer client.cancelMutex.Unlock() + conn := client.conn + client.conn = nil + client.reader = nil + cancelConn := client.cancelConn + client.cancelConn = nil + client.cancelReader = nil + client.clientID = 0 + + if conn == nil && cancelConn == nil { + return nil + } + + closeError := error(nil) + if conn != nil { + if err := conn.Close(); err != nil { + closeError = fmt.Errorf("close Speech Dispatcher connection: %w", err) + } + } + if cancelConn != nil { + if err := cancelConn.Close(); err != nil { + cancelError := fmt.Errorf("close Speech Dispatcher cancellation connection: %w", err) + closeError = errors.Join(closeError, cancelError) + } + } + return closeError +} + +// prepareIO makes cancellation interrupt blocked socket I/O. The cleanup waits +// for a started callback before the next operation can install its deadline. +func prepareIO(ctx context.Context, conn net.Conn, timeout time.Duration) (func(), error) { + if err := ctx.Err(); err != nil { + return nil, err + } + deadline := time.Now().Add(timeout) + if contextDeadline, ok := ctx.Deadline(); ok && contextDeadline.Before(deadline) { + deadline = contextDeadline + } + if err := conn.SetDeadline(deadline); err != nil { + return nil, fmt.Errorf("set Speech Dispatcher deadline: %w", err) + } + done := make(chan struct{}) + stop := context.AfterFunc(ctx, func() { + _ = conn.SetDeadline(time.Now()) + close(done) + }) + return func() { + if !stop() { + <-done + } + }, nil +} + +func (client *Client) readReply() (reply, error) { + for { + response, err := readReply(client.reader) + if err != nil || response.code < 700 || response.code >= 800 { + return response, err + } + } +} + +func (client *Client) sendCancelCommand(ctx context.Context, command string) (result error) { + if client.cancelConn == nil { + return errors.New("speech cancellation channel is not connected") + } + finish, err := prepareIO(ctx, client.cancelConn, client.ioTimeout) + if err != nil { + return err + } + defer finish() + defer func() { + if result != nil { + _ = client.cancelConn.Close() + client.cancelConn, client.cancelReader = nil, nil + } + }() + if _, err := client.cancelConn.Write([]byte(command + "\r\n")); err != nil { + return fmt.Errorf("send Speech Dispatcher cancellation command: %w", err) + } + cancelReply, err := readReply(client.cancelReader) + if err != nil { + return err + } + if cancelReply.code < 200 || cancelReply.code >= 300 { + return fmt.Errorf("Speech Dispatcher cancellation rejected with %d %s", cancelReply.code, cancelReply.text) + } + return nil +} + +func readReply(reader *bufio.Reader) (reply, error) { + var final reply + for { + line, err := reader.ReadString('\n') + if err != nil { + return final, fmt.Errorf("read Speech Dispatcher reply: %w", err) + } + line = strings.TrimRight(line, "\r\n") + if len(line) < 4 || line[3] != '-' && line[3] != ' ' { + return final, fmt.Errorf("invalid Speech Dispatcher reply %q", line) + } + code, err := strconv.Atoi(line[:3]) + if err != nil { + return final, fmt.Errorf("parse Speech Dispatcher reply %q: %w", line, err) + } + final.code = code + final.text = strings.TrimSpace(line[4:]) + if line[3] == ' ' { + return final, nil + } + final.data = append(final.data, final.text) + } +} + +func normalizeSpeakText(text string) (string, error) { + text = strings.ToValidUTF8(text, "�") + text = strings.Join(strings.Fields(text), " ") + if text == "" { + return "", errors.New("speech text is empty") + } + return text, nil +} diff --git a/internal/speech/speech_test.go b/internal/speech/speech_test.go new file mode 100644 index 0000000..9ac63b8 --- /dev/null +++ b/internal/speech/speech_test.go @@ -0,0 +1,471 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package speech + +import ( + "bufio" + "context" + "errors" + "fmt" + "net" + "strings" + "testing" + "time" +) + +func TestSpeakSendsSSIPAndAcceptsQueuedReply(t *testing.T) { + connection, done := startSSIPServer(t, func(reader *bufio.Reader) error { + request, err := reader.ReadString('\n') + if err != nil { + return err + } + if request != "SPEAK\r\n" { + return errors.New("missing SPEAK command") + } + text, err := reader.ReadString('\n') + if err != nil { + return err + } + if text != "Generic focus text\r\n" { + return fmt.Errorf("speech text = %q", text) + } + if terminator, err := reader.ReadString('\n'); err != nil || terminator != ".\r\n" { + if err != nil { + return err + } + return errors.New("invalid speech block terminator") + } + return nil + }, "230 OK RECEIVING DATA\r\n225-1\r\n225 OK MESSAGE QUEUED\r\n") + client := connectedClient(connection) + if err := client.Speak(context.Background(), "Generic focus text"); err != nil { + t.Fatalf("Speak: %v", err) + } + if err := client.Close(context.Background()); err != nil { + t.Fatalf("Close: %v", err) + } + select { + case err := <-done: + if err != nil { + t.Fatalf("SSIP server error: %v", err) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for fake SSIP server") + } +} + +func TestSpeakCharacterSendsEachRepeatedCharacter(t *testing.T) { + connection, server := net.Pipe() + client := connectedClient(connection) + defer client.Close(context.Background()) + defer server.Close() + done := make(chan error, 1) + characters := []string{"o", "o", "1", "1", "1", "l", "l"} + go func() { + reader := bufio.NewReader(server) + for _, character := range characters { + if err := exchangeSSIP(reader, server, "CHAR "+character+"\r\n", "225 OK MESSAGE QUEUED\r\n"); err != nil { + done <- err + return + } + } + done <- nil + }() + for _, character := range characters { + if err := client.SpeakCharacter(context.Background(), character); err != nil { + t.Fatal(err) + } + } + if err := <-done; err != nil { + t.Fatal(err) + } +} + +func TestCancelSendsSSIPCommand(t *testing.T) { + connection, done := startSSIPServer(t, func(reader *bufio.Reader) error { + request, err := reader.ReadString('\n') + if err != nil { + return err + } + if request != "CANCEL 42\r\n" { + return errors.New("unexpected cancel command") + } + return nil + }, "200 OK CANCELLED\r\n") + client := New("") + client.cancelConn = connection + client.cancelReader = bufio.NewReader(connection) + client.clientID = 42 + if err := client.Cancel(context.Background()); err != nil { + t.Fatalf("Cancel: %v", err) + } + if err := client.Close(context.Background()); err != nil { + t.Fatalf("Close: %v", err) + } + select { + case err := <-done: + if err != nil { + t.Fatalf("SSIP server error: %v", err) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for fake SSIP server") + } +} + +func TestApplySettingsSendsConfiguredSSIPCommands(t *testing.T) { + rate, pitch, volume := 52, 0, 40 + connection, serverConnection := net.Pipe() + client := connectedClient(connection) + client.settings = Settings{ + Rate: &rate, + Pitch: &pitch, + Volume: &volume, + Language: "en-US", + SynthesisVoice: "Generic Voice", + Punctuation: "some", + Capitalization: "spell", + } + expected := []string{ + "SET SELF CLIENT_NAME cthulhu:cthulhu:main\r\n", + "SET SELF PRIORITY MESSAGE\r\n", + "SET SELF PUNCTUATION some\r\n", + "SET SELF CAP_LET_RECOGN spell\r\n", + "SET SELF RATE 52\r\n", + "SET SELF PITCH 0\r\n", + "SET SELF VOLUME 40\r\n", + "SET SELF LANGUAGE en-US\r\n", + "SET SELF SYNTHESIS_VOICE Generic Voice\r\n", + } + done := make(chan error, 1) + go func() { + reader := bufio.NewReader(serverConnection) + for _, want := range expected { + got, err := reader.ReadString('\n') + if err != nil { + done <- err + return + } + if got != want { + done <- fmt.Errorf("SSIP command = %q, want %q", got, want) + return + } + if _, err := serverConnection.Write([]byte("200 OK\r\n")); err != nil { + done <- err + return + } + } + done <- nil + }() + t.Cleanup(func() { serverConnection.Close() }) + + if err := client.applySettings(context.Background()); err != nil { + t.Fatalf("applySettings: %v", err) + } + select { + case err := <-done: + if err != nil { + t.Fatal(err) + } + case <-time.After(time.Second): + t.Fatal("timed out waiting for configured SSIP commands") + } +} + +func TestNormalizeSpeakText(t *testing.T) { + for _, test := range []struct { + name, input, want string + }{ + {"line breaks", " Generic\r\nlabel ", "Generic label"}, + {"punctuation", ".", "."}, + {"tabs and spacing", "\tRoom 123\tA12\n", "Room 123 A12"}, + {"Unicode whitespace", "\u00a0Café\u2003猫\u2028text\u3000", "Café 猫 text"}, + {"combining characters", "\te\u0301 saveFile!\n", "e\u0301 saveFile!"}, + {"invalid UTF-8", "\x80bad\xfftext", "�bad�text"}, + {"empty", "", ""}, + {"whitespace only", " \r\n\t\u00a0\u2003", ""}, + } { + t.Run(test.name, func(t *testing.T) { + text, err := normalizeSpeakText(test.input) + if text != test.want || (err != nil) != (test.want == "") { + t.Fatalf("normalizeSpeakText(%q) = %q, %v; want %q", test.input, text, err, test.want) + } + if err != nil && err.Error() != "speech text is empty" { + t.Fatalf("empty speech error = %v", err) + } + }) + } +} + +func FuzzNormalizeSpeakTextPreservesOutput(f *testing.F) { + for _, text := range []string{"", " Generic\r\nlabel ", ".", "\tRoom 123 A12", "Café\u00a0猫\u2003text", "e\u0301 saveFile!", "\x80bad\xfftext", " \r\n\t\u00a0\u2003", "text\x00with\vcontrols"} { + f.Add(text) + } + f.Fuzz(func(t *testing.T, text string) { + // Retain the previous normalization pipeline as a behavior oracle. + expected := strings.ToValidUTF8(text, "�") + expected = strings.NewReplacer("\r", " ", "\n", " ").Replace(expected) + expected = strings.TrimSpace(strings.Join(strings.Fields(expected), " ")) + actual, err := normalizeSpeakText(text) + if actual != expected || (err != nil) != (expected == "") { + t.Fatalf("normalization changed for %q: got %q, %v; want %q", text, actual, err, expected) + } + }) +} + +func BenchmarkNormalizeSpeakText(b *testing.B) { + for _, sample := range []struct{ name, text string }{ + {"short", "Save button"}, + {"whitespace", " Example\r\nline\twith multiple spaces. "}, + } { + b.Run(sample.name, func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + if _, err := normalizeSpeakText(sample.text); err != nil { + b.Fatal(err) + } + } + }) + } +} + +func startSSIPServer( + t *testing.T, + readRequest func(*bufio.Reader) error, + reply string, +) (net.Conn, chan error) { + t.Helper() + clientConnection, serverConnection := net.Pipe() + done := make(chan error, 1) + + go func() { + defer serverConnection.Close() + reader := bufio.NewReader(serverConnection) + if err := readRequest(reader); err != nil { + done <- err + return + } + if _, err := serverConnection.Write([]byte(reply)); err != nil { + done <- err + return + } + done <- nil + }() + t.Cleanup(func() { + clientConnection.Close() + serverConnection.Close() + }) + return clientConnection, done +} + +func connectedClient(connection net.Conn) *Client { + client := New("") + client.conn = connection + client.reader = bufio.NewReader(connection) + return client +} + +func TestInitializeTargetsSpeakingConnection(t *testing.T) { + for _, test := range []struct { + name string + reply string + valid bool + }{ + {"valid", "245-42\r\n245 OK CLIENT ID SENT\r\n", true}, + {"missing", "245 OK\r\n", false}, + {"not numeric", "245-SELF\r\n245 OK\r\n", false}, + {"zero", "245-0\r\n245 OK\r\n", false}, + {"negative", "245--1\r\n245 OK\r\n", false}, + {"wrong code", "200-42\r\n200 OK\r\n", false}, + {"rejected", "500 UNKNOWN COMMAND\r\n", false}, + {"multiple", "245-42\r\n245-43\r\n245 OK\r\n", false}, + } { + t.Run(test.name, func(t *testing.T) { + mainConn, mainServer := net.Pipe() + controlConn, controlServer := net.Pipe() + client := connectedClient(mainConn) + client.cancelConn, client.cancelReader = controlConn, bufio.NewReader(controlConn) + t.Cleanup(func() { + mainServer.Close() + controlServer.Close() + client.Close(context.Background()) + }) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + done := make(chan error, 1) + go func() { + reader := bufio.NewReader(mainServer) + for _, exchange := range []struct{ command, reply string }{ + {"SET SELF CLIENT_NAME cthulhu:cthulhu:main\r\n", "200 OK\r\n"}, + {"SET SELF PRIORITY MESSAGE\r\n", "200 OK\r\n"}, + {"HISTORY GET CLIENT_ID\r\n", test.reply}, + } { + if err := exchangeSSIP(reader, mainServer, exchange.command, exchange.reply); err != nil { + done <- err + return + } + } + if test.valid { + reader = bufio.NewReader(controlServer) + for _, command := range []string{ + "SET SELF CLIENT_NAME cthulhu:cthulhu:cancel\r\n", + "CANCEL 42\r\n", + } { + if err := exchangeSSIP(reader, controlServer, command, "200 OK\r\n"); err != nil { + done <- err + return + } + } + } + done <- nil + }() + err := client.initialize(ctx) + if (err == nil) != test.valid { + t.Fatalf("initialize error = %v, valid = %v", err, test.valid) + } + if test.valid { + if err := client.Cancel(ctx); err != nil { + t.Fatal(err) + } + } + select { + case err := <-done: + if err != nil { + t.Fatal(err) + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + }) + } +} + +func exchangeSSIP(reader *bufio.Reader, conn net.Conn, command, reply string) error { + got, err := reader.ReadString('\n') + if err != nil { + return err + } + if got != command { + return fmt.Errorf("command = %q, want %q", got, command) + } + _, err = conn.Write([]byte(reply)) + return err +} + +func TestCancelWhileSpeakWaitsForReply(t *testing.T) { + mainConn, mainServer := net.Pipe() + controlConn, controlDone := startSSIPServer(t, func(reader *bufio.Reader) error { + got, err := reader.ReadString('\n') + if err == nil && got != "CANCEL 42\r\n" { + return fmt.Errorf("cancel = %q", got) + } + return err + }, "200 OK\r\n") + client := connectedClient(mainConn) + client.cancelConn, client.cancelReader, client.clientID = controlConn, bufio.NewReader(controlConn), 42 + t.Cleanup(func() { mainServer.Close(); client.Close(context.Background()) }) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + speakDone := make(chan error, 1) + go func() { speakDone <- client.Speak(ctx, "Generic text") }() + reader := bufio.NewReader(mainServer) + for range 3 { + if _, err := reader.ReadString('\n'); err != nil { + t.Fatal(err) + } + } + if err := client.Cancel(ctx); err != nil { + t.Fatalf("Cancel during SPEAK: %v", err) + } + if err := <-controlDone; err != nil { + t.Fatal(err) + } + cancel() + select { + case err := <-speakDone: + if err == nil { + t.Fatal("blocked Speak succeeded") + } + case <-time.After(time.Second): + t.Fatal("Speak ignored context cancellation") + } + if err := client.Speak(context.Background(), "Next"); err == nil { + t.Fatal("reused interrupted protocol exchange") + } +} + +func TestCancelContextAndFailedChannel(t *testing.T) { + conn, server := net.Pipe() + client := New("") + client.cancelConn, client.cancelReader, client.clientID = conn, bufio.NewReader(conn), 42 + t.Cleanup(func() { server.Close(); client.Close(context.Background()) }) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if err := client.Cancel(ctx); !errors.Is(err, context.Canceled) { + t.Fatalf("Cancel = %v", err) + } + ctx, cancel = context.WithCancel(context.Background()) + defer cancel() + done := make(chan error, 1) + go func() { done <- client.Cancel(ctx) }() + if _, err := bufio.NewReader(server).ReadString('\n'); err != nil { + t.Fatal(err) + } + cancel() + select { + case err := <-done: + if err == nil { + t.Fatal("Cancel succeeded without reply") + } + case <-time.After(time.Second): + t.Fatal("Cancel ignored context cancellation") + } + if err := client.Cancel(context.Background()); err == nil { + t.Fatal("reused failed control channel") + } +} + +func TestSpeakEscapesLeadingDots(t *testing.T) { + for _, text := range []string{".", "..", ".hidden", "ordinary"} { + t.Run(text, func(t *testing.T) { + wireText := text + if text[0] == '.' { + wireText = "." + text + } + conn, done := startSSIPServer(t, func(reader *bufio.Reader) error { + for _, want := range []string{"SPEAK\r\n", wireText + "\r\n", ".\r\n"} { + got, err := reader.ReadString('\n') + if err != nil { + return err + } + if got != want { + return fmt.Errorf("wire text = %q, want %q", got, want) + } + } + return nil + }, "230 OK RECEIVING DATA\r\n225-1\r\n225 OK MESSAGE QUEUED\r\n") + client := connectedClient(conn) + if err := client.Speak(context.Background(), text); err != nil { + t.Fatal(err) + } + if err := <-done; err != nil { + t.Fatal(err) + } + client.Close(context.Background()) + }) + } +} diff --git a/internal/speechhistoryui/native.c b/internal/speechhistoryui/native.c new file mode 100644 index 0000000..82f5d18 --- /dev/null +++ b/internal/speechhistoryui/native.c @@ -0,0 +1,221 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later +#include "native.h" +#include +#include + +enum { NONE, COPY, REMOVE, CLOSE, CLEAR }; +static GtkWidget *window, *filter, *tree, *text_view; +static GtkListStore *store; +static GtkTreeModel *filtered; +static GtkTreeSelection *selection; +static int action_code, monitor_mode, line_count; +static char *selected_cache; + +static void action(GtkButton *button, gpointer code) { + (void)button; + if (!action_code) action_code = GPOINTER_TO_INT(code); +} +static gboolean deleted(GtkWidget *widget, GdkEvent *event, gpointer data) { + (void)widget; (void)event; (void)data; + if (!action_code) action_code = CLOSE; + return TRUE; +} +static gboolean key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) { + (void)widget; (void)data; + if (event->keyval == GDK_KEY_Escape) { action_code = CLOSE; return TRUE; } + if (monitor_mode || !filter || !gtk_widget_has_focus(tree)) return FALSE; + if (event->keyval == GDK_KEY_BackSpace) { + const char *current = gtk_entry_get_text(GTK_ENTRY(filter)); + glong length = g_utf8_strlen(current, -1); + if (length > 0) { + char *shorter = g_utf8_substring(current, 0, length - 1); + gtk_entry_set_text(GTK_ENTRY(filter), shorter); + gtk_editable_set_position(GTK_EDITABLE(filter), -1); + g_free(shorter); + return TRUE; + } + return FALSE; + } + if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK | GDK_SUPER_MASK | GDK_META_MASK)) return FALSE; + gunichar ch = gdk_keyval_to_unicode(event->keyval); + if (!ch || !g_unichar_isprint(ch)) return FALSE; + char utf8[7] = {0}; + g_unichar_to_utf8(ch, utf8); + char *updated = g_strconcat(gtk_entry_get_text(GTK_ENTRY(filter)), utf8, NULL); + gtk_entry_set_text(GTK_ENTRY(filter), updated); + gtk_editable_set_position(GTK_EDITABLE(filter), -1); + gtk_widget_grab_focus(filter); + g_free(updated); + return TRUE; +} +static gboolean visible(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) { + (void)data; + char *query = g_strstrip(g_strdup(gtk_entry_get_text(GTK_ENTRY(filter)))); + if (!query[0]) { g_free(query); return TRUE; } + char *value = NULL; + gtk_tree_model_get(model, iter, 0, &value, -1); + char *folded_value = g_utf8_casefold(value ? value : "", -1); + char *folded_query = g_utf8_casefold(query, -1); + gboolean match = g_str_has_prefix(folded_value, folded_query); + g_free(value); g_free(query); g_free(folded_value); g_free(folded_query); + return match; +} +static void filter_changed(GtkEditable *editable, gpointer data) { + (void)editable; (void)data; + gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filtered)); + GtkTreeIter first; + if (gtk_tree_model_get_iter_first(filtered, &first)) { + GtkTreePath *path = gtk_tree_model_get_path(filtered, &first); + gtk_tree_selection_select_path(selection, path); + gtk_tree_path_free(path); + } else gtk_tree_selection_unselect_all(selection); +} +static GtkWidget *button(GtkWidget *box, const char *label, int code) { + GtkWidget *widget = gtk_button_new_with_label(label); + g_signal_connect(widget, "clicked", G_CALLBACK(action), GINT_TO_POINTER(code)); + gtk_box_pack_start(GTK_BOX(box), widget, FALSE, FALSE, 0); + return widget; +} +int history_init(int monitor) { + if (!gtk_init_check(NULL, NULL)) return 0; + monitor_mode = monitor; + line_count = 0; + g_set_application_name(monitor ? "Cthulhu Speech Monitor" : "Cthulhu Speech History"); + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), monitor ? "Speech Monitor - Cthulhu" : "Speech History - Cthulhu"); + gtk_window_set_default_size(GTK_WINDOW(window), monitor ? 900 : 700, monitor ? 320 : 420); + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + if (monitor) { + gtk_window_set_keep_above(GTK_WINDOW(window), TRUE); + gtk_window_set_focus_on_map(GTK_WINDOW(window), FALSE); + gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_UTILITY); + } else gtk_window_set_modal(GTK_WINDOW(window), TRUE); + g_signal_connect(window, "delete-event", G_CALLBACK(deleted), NULL); + g_signal_connect(window, "key-press-event", G_CALLBACK(key_press), NULL); + GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 8); + gtk_container_add(GTK_CONTAINER(window), box); + if (!monitor) { + GtkWidget *row = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + GtkWidget *label = gtk_label_new_with_mnemonic("_Filter:"); + filter = gtk_entry_new(); + gtk_widget_set_hexpand(filter, TRUE); + gtk_label_set_mnemonic_widget(GTK_LABEL(label), filter); + gtk_box_pack_start(GTK_BOX(row), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(row), filter, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(box), row, FALSE, FALSE, 0); + store = gtk_list_store_new(1, G_TYPE_STRING); + filtered = gtk_tree_model_filter_new(GTK_TREE_MODEL(store), NULL); + gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filtered), visible, NULL, NULL); + g_signal_connect(filter, "changed", G_CALLBACK(filter_changed), NULL); + } + GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_set_vexpand(scroll, TRUE); + gtk_box_pack_start(GTK_BOX(box), scroll, TRUE, TRUE, 0); + if (monitor) { + text_view = gtk_text_view_new(); + gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), FALSE); + gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text_view), FALSE); + gtk_widget_set_can_focus(text_view, FALSE); + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view), GTK_WRAP_WORD_CHAR); + AtkObject *accessible = gtk_widget_get_accessible(text_view); + if (accessible) atk_object_set_name(accessible, "Speech monitor output"); + gtk_container_add(GTK_CONTAINER(scroll), text_view); + } else { + tree = gtk_tree_view_new_with_model(filtered); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + g_object_set(renderer, "wrap-width", 640, "wrap-mode", PANGO_WRAP_WORD_CHAR, NULL); + GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("Spoken Text", renderer, "text", 0, NULL); + gtk_tree_view_column_set_expand(column, TRUE); + gtk_tree_view_column_set_resizable(column, TRUE); + gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column); + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + gtk_container_add(GTK_CONTAINER(scroll), tree); + } + GtkWidget *buttons = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8); + gtk_widget_set_halign(buttons, GTK_ALIGN_END); + gtk_box_pack_start(GTK_BOX(box), buttons, FALSE, FALSE, 0); + if (monitor) button(buttons, "Clear", CLEAR); + else { + button(buttons, "Copy to clipboard", COPY); + button(buttons, "Remove from history", REMOVE); + } + button(buttons, "Close", CLOSE); + gtk_widget_show_all(window); + if (!monitor) gtk_widget_grab_focus(filter); + return 1; +} +void history_set_items(char **items, int count, int selected) { + if (!store) return; + gtk_list_store_clear(store); + for (int i = 0; i < count; i++) { + GtkTreeIter iter; + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, items[i], -1); + } + if (count > 0) { + GtkTreePath *path = gtk_tree_path_new_from_indices(selected >= 0 && selected < count ? selected : 0, -1); + gtk_tree_selection_select_path(selection, path); + gtk_tree_path_free(path); + gtk_widget_grab_focus(tree); + } else gtk_widget_grab_focus(filter); +} +void history_append(const char *text) { + if (!text_view || !text) return; + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); + GtkTextIter end; + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_buffer_insert(buffer, &end, text, -1); + gtk_text_buffer_insert(buffer, &end, "\n", 1); + if (++line_count > 500) { + GtkTextIter start, cut; + gtk_text_buffer_get_start_iter(buffer, &start); + gtk_text_buffer_get_iter_at_line(buffer, &cut, line_count - 500); + gtk_text_buffer_delete(buffer, &start, &cut); + line_count = 500; + } + gtk_text_buffer_get_end_iter(buffer, &end); + GtkTextMark *mark = gtk_text_buffer_create_mark(buffer, NULL, &end, FALSE); + gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(text_view), mark); + gtk_text_buffer_delete_mark(buffer, mark); +} +void history_present(void) { if (window) gtk_window_present(GTK_WINDOW(window)); } +void history_iterate(void) { while (gtk_events_pending()) gtk_main_iteration(); } +int history_action(void) { int result = action_code; action_code = NONE; return result; } +const char *history_selected(void) { + GtkTreeIter iter; GtkTreeModel *model = NULL; + if (!selection || !gtk_tree_selection_get_selected(selection, &model, &iter)) return ""; + g_free(selected_cache); + gtk_tree_model_get(model, &iter, 0, &selected_cache, -1); + return selected_cache ? selected_cache : ""; +} +int history_selected_row(void) { + GtkTreeIter iter; GtkTreeModel *model = NULL; + if (!selection || !gtk_tree_selection_get_selected(selection, &model, &iter)) return 0; + GtkTreePath *path = gtk_tree_model_get_path(model, &iter); + int *indices = gtk_tree_path_get_indices(path); + int row = indices ? indices[0] : 0; + gtk_tree_path_free(path); + return row; +} +int history_copy(void) { + const char *text = history_selected(); + if (!text || !text[0]) return 0; + GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clipboard, text, -1); + gtk_clipboard_store(clipboard); + return 1; +} +void history_clear(void) { + if (!text_view) return; + gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)), "", 0); + line_count = 0; +} +void history_close(void) { + if (window) gtk_widget_destroy(window); + window = filter = tree = text_view = NULL; + store = NULL; filtered = NULL; selection = NULL; + g_free(selected_cache); selected_cache = NULL; +} diff --git a/internal/speechhistoryui/native.h b/internal/speechhistoryui/native.h new file mode 100644 index 0000000..66d1615 --- /dev/null +++ b/internal/speechhistoryui/native.h @@ -0,0 +1,14 @@ +#ifndef CTHULHU_SPEECH_HISTORY_UI_H +#define CTHULHU_SPEECH_HISTORY_UI_H +int history_init(int monitor); +void history_set_items(char **items, int count, int selected); +void history_append(const char *text); +void history_present(void); +void history_iterate(void); +int history_action(void); +const char *history_selected(void); +int history_selected_row(void); +int history_copy(void); +void history_clear(void); +void history_close(void); +#endif diff --git a/internal/speechhistoryui/ui.go b/internal/speechhistoryui/ui.go new file mode 100644 index 0000000..0f20886 --- /dev/null +++ b/internal/speechhistoryui/ui.go @@ -0,0 +1,151 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package speechhistoryui + +/* +#cgo pkg-config: gtk+-3.0 +#include +#include "native.h" +*/ +import "C" + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "io" + "runtime" + "time" + "unsafe" +) + +type Message struct { + Mode string `json:"mode,omitempty"` + Items []string `json:"items"` + Selected int `json:"selected,omitempty"` + Append string `json:"append,omitempty"` + Present bool `json:"present,omitempty"` + Close bool `json:"close,omitempty"` +} + +type Request struct { + Action string `json:"action"` + Selection string `json:"selection,omitempty"` + Row int `json:"row,omitempty"` +} + +// Run keeps GTK on one OS thread and exchanges bounded messages with Cthulhu. +func Run(ctx context.Context, input io.Reader, output io.Writer) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + updates := make(chan Message, 16) + readErrors := make(chan error, 1) + go func() { + scanner := bufio.NewScanner(input) + scanner.Buffer(make([]byte, 4096), 1024*1024) + for scanner.Scan() { + var update Message + if err := json.Unmarshal(scanner.Bytes(), &update); err != nil { + readErrors <- err + return + } + select { + case updates <- update: + case <-ctx.Done(): + return + } + } + readErrors <- scanner.Err() + }() + var initial Message + select { + case initial = <-updates: + case err := <-readErrors: + return err + case <-ctx.Done(): + return ctx.Err() + } + monitor := initial.Mode == "monitor" + mode := C.int(0) + if monitor { + mode = 1 + } + if C.history_init(mode) == 0 { + return errors.New("cannot open speech history on this display") + } + defer C.history_close() + if !monitor { + setItems(initial.Items, initial.Selected) + } + encoder := json.NewEncoder(output) + // AT-SPI requests are served by GTK's main context. A longer polling + // interval is paid once for every synchronous accessibility query, so a + // single arrow key can accumulate hundreds of milliseconds of delay. + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-readErrors: + return err + case update := <-updates: + if update.Close { + return nil + } + if update.Present { + C.history_present() + } + if update.Items != nil { + setItems(update.Items, update.Selected) + } + if update.Append != "" { + value := C.CString(update.Append) + C.history_append(value) + C.free(unsafe.Pointer(value)) + } + case <-ticker.C: + C.history_iterate() + switch C.history_action() { + case 1: + if C.history_copy() != 0 { + if err := encoder.Encode(Request{Action: "copy"}); err != nil { + return err + } + } else if err := encoder.Encode(Request{Action: "empty"}); err != nil { + return err + } + case 2: + if err := encoder.Encode(Request{Action: "remove", Selection: C.GoString(C.history_selected()), Row: int(C.history_selected_row())}); err != nil { + return err + } + case 3: + return nil + case 4: + C.history_clear() + } + } + } +} + +func setItems(items []string, selected int) { + values := make([]*C.char, len(items)) + for i, item := range items { + values[i] = C.CString(item) + } + defer func() { + for _, value := range values { + C.free(unsafe.Pointer(value)) + } + }() + if len(values) == 0 { + C.history_set_items(nil, 0, 0) + return + } + C.history_set_items((**C.char)(unsafe.Pointer(&values[0])), C.int(len(values)), C.int(selected)) +} diff --git a/internal/tentacle/bindings.go b/internal/tentacle/bindings.go new file mode 100644 index 0000000..7d8678d --- /dev/null +++ b/internal/tentacle/bindings.go @@ -0,0 +1,88 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import "git.stormux.org/storm/cthulhu/internal/input" + +// Binding proposes a default. It does not acquire a native grab. Scope follows +// the existing global/browse rule: neither may shadow the other in one layout. +type Binding struct { + Layout string `json:"layout"` + Scope string `json:"scope"` + Key string `json:"key"` +} + +type BindingStatus struct { + Command string + Suggested Binding + Bound bool + Conflict string // Existing command ID; empty when there is no conflict. +} + +func binding_layout(name string) input.KeyboardLayout { + if name == "desktop" { + return input.DesktopKeyboardLayout + } + return input.LaptopKeyboardLayout +} + +func validate_binding(binding Binding) error { + if (binding.Layout != "desktop" && binding.Layout != "laptop") || + (binding.Scope != "global" && binding.Scope != "browse") || len(binding.Key) > 128 { + return ErrProtocol + } + if _, err := input.ParseCommandChord(binding.Key); err != nil { + return ErrProtocol + } + return nil +} + +func (session *Session) Bindings() []BindingStatus { + session.mutex.Lock() + defer session.mutex.Unlock() + return append([]BindingStatus(nil), session.bindings...) +} + +// Caller holds manager.mutex, but no session lock. Revoked sessions immediately +// stop reserving chords even while their processes are still shutting down. +func (manager *Manager) occupied_bindings() map[input.KeyboardLayout]input.CommandBindings { + occupied := make(map[input.KeyboardLayout]input.CommandBindings) + for layout, bindings := range manager.coreBindings { + occupied[layout] = make(input.CommandBindings) + for chord, command := range bindings { + occupied[layout][chord] = command + } + } + for _, session := range manager.sessions { + session.mutex.Lock() + if session.state == Active { + for _, binding := range session.bindings { + if binding.Bound { + chord, _ := input.ParseCommandChord(binding.Suggested.Key) + occupied[binding_layout(binding.Suggested.Layout)][chord] = input.Command(binding.Command) + } + } + } + session.mutex.Unlock() + } + return occupied +} + +func resolve_bindings(identity string, commands []Command, occupied map[input.KeyboardLayout]input.CommandBindings) []BindingStatus { + var result []BindingStatus + for _, command := range commands { + commandID := "tentacle/" + identity + "/" + command.ID + for _, binding := range command.Bindings { + chord, _ := input.ParseCommandChord(binding.Key) + bindings := occupied[binding_layout(binding.Layout)] + previous := bindings[chord] + result = append(result, BindingStatus{Command: commandID, Suggested: binding, + Bound: previous == "", Conflict: string(previous)}) + if previous == "" { + bindings[chord] = input.Command(commandID) + } + } + } + return result +} diff --git a/internal/tentacle/containment.go b/internal/tentacle/containment.go new file mode 100644 index 0000000..89935cc --- /dev/null +++ b/internal/tentacle/containment.go @@ -0,0 +1,198 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "crypto/rand" + "errors" + "fmt" + "os" + "path/filepath" + "strconv" + "syscall" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +var ErrContainment = errors.New("tentacle resource containment failed") + +// ResourceBudget includes the child and all its descendants. Tasks counts +// kernel threads as well as processes. CPUQuota is microseconds per 100 ms, +// so 100000 allows one CPU, independent of the machine's number of CPUs. +type ResourceBudget struct { + CPUQuota int64 + MemoryBytes int64 + Tasks int64 +} + +type ResourceLimits struct { + PerSession ResourceBudget + Total ResourceBudget + CleanupTimeout time.Duration +} + +func DefaultResourceLimits() ResourceLimits { + return ResourceLimits{ + PerSession: ResourceBudget{CPUQuota: 25000, MemoryBytes: 256 << 20, Tasks: 64}, + Total: ResourceBudget{CPUQuota: 100000, MemoryBytes: 1 << 30, Tasks: 256}, + CleanupTimeout: 2 * time.Second, + } +} + +func (limits ResourceLimits) validate() error { + for _, budget := range []ResourceBudget{limits.PerSession, limits.Total} { + if budget.CPUQuota < 1000 || budget.MemoryBytes < 1<<20 || budget.Tasks < 1 { + return fmt.Errorf("%w: invalid resource budget", ErrContainment) + } + } + if limits.Total.CPUQuota < limits.PerSession.CPUQuota || + limits.Total.MemoryBytes < limits.PerSession.MemoryBytes || + limits.Total.Tasks < limits.PerSession.Tasks || limits.CleanupTimeout <= 0 { + return fmt.Errorf("%w: invalid aggregate budget or cleanup deadline", ErrContainment) + } + return nil +} + +// NewContainedManager creates a private subtree in an already delegated cgroup +// v2 parent with cpu, memory and pids enabled in cgroup.subtree_control. It never +// moves the host or changes the caller's parent. Setup may perform filesystem +// I/O and belongs on a lifecycle worker, never an input callback. +// +// There is no fallback when delegation, controllers, cgroup.kill or atomic +// cgroup placement are unavailable. This is resource containment for trusted +// local code, not a security sandbox against same-user cgroup modification, +// migration, privileged scheduling, or external service launches. +func NewContainedManager(limits Limits, overrides []input.BindingOverride, parent string, resources ResourceLimits) (*Manager, error) { + if err := resources.validate(); err != nil { + return nil, err + } + manager, err := NewManager(limits, overrides) + if err != nil { + return nil, err + } + if !filepath.IsAbs(parent) { + return nil, fmt.Errorf("%w: cgroup parent must be absolute", ErrContainment) + } + var stat syscall.Statfs_t + if err := syscall.Statfs(parent, &stat); err != nil || stat.Type != 0x63677270 { + return nil, fmt.Errorf("%w: parent is not a cgroup v2 filesystem", ErrContainment) + } + var identity [16]byte + if _, err := rand.Read(identity[:]); err != nil { + return nil, err + } + group, err := create_cgroup(filepath.Join(parent, fmt.Sprintf("cthulhu-tentacles-%x", identity)), resources.Total, limits.Processes) + if err != nil { + return nil, err + } + if err := write_control(group.path, "cgroup.subtree_control", "+cpu +memory +pids"); err != nil { + return nil, errors.Join(err, group.remove()) + } + manager.containment = &containment{group: group, limits: resources} + return manager, nil +} + +type containment struct { + group *cgroup + limits ResourceLimits +} + +type cgroup struct { + path string + file *os.File +} + +func write_control(path, name, value string) error { + // Do not create ordinary files if the kernel lacks a required controller. + file, err := os.OpenFile(filepath.Join(path, name), os.O_WRONLY, 0) + if err != nil { + return fmt.Errorf("%w: open %s: %w", ErrContainment, name, err) + } + _, writeError := file.WriteString(value) + return errors.Join(wrap_control_error(name, writeError), wrap_control_error(name, file.Close())) +} + +func wrap_control_error(name string, err error) error { + if err == nil { + return nil + } + return fmt.Errorf("%w: %s: %w", ErrContainment, name, err) +} + +func create_cgroup(path string, budget ResourceBudget, children int) (*cgroup, error) { + if err := os.Mkdir(path, 0700); err != nil { + return nil, fmt.Errorf("%w: create group: %w", ErrContainment, err) + } + group := &cgroup{path: path} + settings := []struct{ name, value string }{ + {"cpu.max", strconv.FormatInt(budget.CPUQuota, 10) + " 100000"}, + {"memory.max", strconv.FormatInt(budget.MemoryBytes, 10)}, + {"memory.swap.max", "0"}, + {"pids.max", strconv.FormatInt(budget.Tasks, 10)}, + {"cgroup.max.descendants", strconv.Itoa(children)}, + } + if children == 0 { + // If any task exhausts memory, retire the entire session, not an + // arbitrary worker while leaving a partially broken child alive. + settings = append(settings, struct{ name, value string }{"memory.oom.group", "1"}) + } + for _, setting := range settings { + if err := write_control(path, setting.name, setting.value); err != nil { + return nil, errors.Join(err, group.remove()) + } + } + // Check availability without issuing a kill before launch. Some kernels + // SIGKILL CLONE_INTO_CGROUP children entering a previously killed group. + killFile, err := os.OpenFile(filepath.Join(path, "cgroup.kill"), os.O_WRONLY, 0) + if err != nil { + return nil, errors.Join(wrap_control_error("open cgroup.kill", err), group.remove()) + } + if err := killFile.Close(); err != nil { + return nil, errors.Join(wrap_control_error("close cgroup.kill", err), group.remove()) + } + file, err := os.Open(path) + if err != nil { + return nil, errors.Join(wrap_control_error("open group", err), group.remove()) + } + group.file = file + return group, nil +} + +func (group *cgroup) remove() error { + if group.file != nil { + _ = group.file.Close() + group.file = nil + } + return wrap_control_error("remove group", os.Remove(group.path)) +} + +// kill_and_remove waits only during teardown. Successful removal proves the +// kernel no longer has live tasks in the group, including setsid descendants. +func (group *cgroup) kill_and_remove(timeout time.Duration) error { + defer func() { + if group.file != nil { + _ = group.file.Close() + group.file = nil + } + }() + if err := write_control(group.path, "cgroup.kill", "1"); err != nil { + return err + } + deadline := time.NewTimer(timeout) + defer deadline.Stop() + ticker := time.NewTicker(10 * time.Millisecond) + defer ticker.Stop() + for { + err := group.remove() + if err == nil || !errors.Is(err, syscall.EBUSY) { + return err + } + select { + case <-ticker.C: + case <-deadline.C: + return fmt.Errorf("%w: cleanup deadline expired", ErrContainment) + } + } +} diff --git a/internal/tentacle/containment_test.go b/internal/tentacle/containment_test.go new file mode 100644 index 0000000..0b9a06e --- /dev/null +++ b/internal/tentacle/containment_test.go @@ -0,0 +1,386 @@ +package tentacle + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "syscall" + "testing" + "time" +) + +func TestContainmentRejectsInvalidConfiguration(t *testing.T) { + for _, change := range []func(*ResourceLimits){ + func(limits *ResourceLimits) { limits.PerSession.CPUQuota = 0 }, + func(limits *ResourceLimits) { limits.PerSession.MemoryBytes = 0 }, + func(limits *ResourceLimits) { limits.PerSession.Tasks = 0 }, + func(limits *ResourceLimits) { limits.Total.CPUQuota = limits.PerSession.CPUQuota - 1 }, + func(limits *ResourceLimits) { limits.Total.MemoryBytes = limits.PerSession.MemoryBytes - 1 }, + func(limits *ResourceLimits) { limits.Total.Tasks = limits.PerSession.Tasks - 1 }, + func(limits *ResourceLimits) { limits.CleanupTimeout = 0 }, + } { + limits := DefaultResourceLimits() + change(&limits) + if _, err := NewContainedManager(DefaultLimits(), nil, t.TempDir(), limits); !errors.Is(err, ErrContainment) { + t.Fatalf("invalid budget accepted: %v", err) + } + } + // Ordinary directories must never be treated as working cgroup controllers. + parent := t.TempDir() + if _, err := NewContainedManager(DefaultLimits(), nil, parent, DefaultResourceLimits()); !errors.Is(err, ErrContainment) { + t.Fatalf("ordinary directory accepted: %v", err) + } + entries, err := os.ReadDir(parent) + if err != nil || len(entries) != 0 { + t.Fatalf("failed setup mutated ordinary parent: %v %v", entries, err) + } +} + +func contained_manager(t *testing.T, resources ResourceLimits) *Manager { + t.Helper() + parent := os.Getenv("CTHULHU_TENTACLE_CGROUP_PARENT") + if parent == "" { + t.Skip("set CTHULHU_TENTACLE_CGROUP_PARENT to an empty delegated cgroup v2 parent with cpu/memory/pids enabled") + } + limits := DefaultLimits() + limits.RequestTimeout = 4 * time.Second + manager, err := NewContainedManager(limits, nil, parent, resources) + if err != nil { + t.Fatal(err) // An explicitly requested native check must not silently skip. + } + groupPath := manager.containment.group.path + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := manager.Shutdown(ctx); err != nil { + t.Error(err) + } + if stats := manager.Stats(); stats != (Stats{}) { + t.Errorf("retained resources: %+v", stats) + } + if _, err := os.Stat(groupPath); !os.IsNotExist(err) { + t.Errorf("aggregate group remains: %v", err) + } + if err := manager.Shutdown(ctx); err != nil { + t.Errorf("repeated shutdown: %v", err) + } + }) + return manager +} + +func resource_peer(t *testing.T, manager *Manager, id string) *Session { + t.Helper() + python, err := exec.LookPath("python3") + if err != nil { + t.Fatal(err) + } + fixture, err := filepath.Abs("testdata/resource_peer.py") + if err != nil { + t.Fatal(err) + } + session, err := manager.Start(context.Background(), Spec{ID: id, Program: []string{python, "-I", "-u", fixture}}) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Ready()) + if state, err := session.Status(); state != Ready || err != nil { + t.Fatalf("resource peer %s: %v", state, err) + } + if err := session.Activate(); err != nil { + t.Fatal(err) + } + return session +} + +func resource_call(t *testing.T, session *Session, arguments string) Result { + t.Helper() + pending, err := session.Invoke(context.Background(), "echo", json.RawMessage(arguments)) + if err != nil { + t.Fatal(err) + } + return wait_result(t, pending) +} + +func read_control(t *testing.T, path, name string) string { + t.Helper() + data, err := os.ReadFile(filepath.Join(path, name)) + if err != nil { + t.Fatal(err) + } + return strings.TrimSpace(string(data)) +} + +func control_counter(t *testing.T, path, name, key string) int64 { + t.Helper() + for _, line := range strings.Split(read_control(t, path, name), "\n") { + fields := strings.Fields(line) + if len(fields) == 2 && fields[0] == key { + value, err := strconv.ParseInt(fields[1], 10, 64) + if err != nil { + t.Fatal(err) + } + return value + } + } + t.Fatalf("missing %s counter in %s", key, name) + return 0 +} + +func wait_control(t *testing.T, check func() bool) { + t.Helper() + deadline := time.NewTimer(4 * time.Second) + defer deadline.Stop() + ticker := time.NewTicker(10 * time.Millisecond) + defer ticker.Stop() + for !check() { + select { + case <-ticker.C: + case <-deadline.C: + t.Fatal("kernel resource condition was not observed") + } + } +} + +func TestNativeContainmentPlacementAndDetachedCleanup(t *testing.T) { + manager := contained_manager(t, DefaultResourceLimits()) + session := resource_peer(t, manager, "detaching") + groupPath := filepath.Join(manager.containment.group.path, session.Identity()) + for name, expected := range map[string]string{ + "cpu.max": "25000 100000", "memory.max": "268435456", "memory.swap.max": "0", + "pids.max": "64", "memory.oom.group": "1", "cgroup.max.descendants": "0", + } { + if actual := read_control(t, groupPath, name); actual != expected { + t.Fatalf("%s = %s, want %s", name, actual, expected) + } + } + result := resource_call(t, session, `{}`) + var location string + if result.Err != nil || json.Unmarshal(result.Value, &location) != nil || !strings.HasSuffix(location, "/"+session.Identity()) { + t.Fatalf("child ran outside its group: %+v", result) + } + result = resource_call(t, session, `{"action":"detach"}`) + var pid int + if result.Err != nil || json.Unmarshal(result.Value, &pid) != nil || pid <= 1 { + t.Fatalf("missing detached child: %+v", result) + } + if actual := read_control(t, fmt.Sprintf("/proc/%d", pid), "cgroup"); actual != location { + t.Fatalf("detached descendant escaped: %s", actual) + } + session.Disable() + wait_signal(t, session.Done()) + if state, err := session.Status(); state != Stopped || err != nil { + t.Fatalf("cleanup %s: %v", state, err) + } + if _, err := os.Stat(groupPath); !os.IsNotExist(err) { + t.Fatalf("session group survived Done: %v", err) + } + // Kernel exit can remove a task from its cgroup just before /proc shows Z. + wait_control(t, func() bool { + data, err := os.ReadFile(fmt.Sprintf("/proc/%d/stat", pid)) + if os.IsNotExist(err) { + return true + } + if err != nil { + t.Fatal(err) + } + _, tail, found := strings.Cut(string(data), ") ") + return found && strings.HasPrefix(tail, "Z ") + }) + // A new identity can reuse capacity after all descendants are gone. + resource_peer(t, manager, "detaching") +} + +func TestNativeContainmentExec(t *testing.T) { + manager := contained_manager(t, DefaultResourceLimits()) + group, err := create_cgroup(filepath.Join(manager.containment.group.path, "exec-proof"), DefaultResourceLimits().PerSession, 0) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := group.kill_and_remove(time.Second); err != nil { + t.Error(err) + } + }() + python, err := exec.LookPath("python3") + if err != nil { + t.Fatal(err) + } + fixture, err := filepath.Abs("testdata/resource_peer.py") + if err != nil { + t.Fatal(err) + } + command := exec.Command(python, "-I", "-u", fixture) + command.SysProcAttr = &syscall.SysProcAttr{UseCgroupFD: true, CgroupFD: int(group.file.Fd())} + command.Stdin = strings.NewReader(`{"id":"1","method":"initialize","params":{"protocol":{"major":1,"minor":0},"session":"test"}}` + "\n" + `{"method":"shutdown"}` + "\n") + output, err := command.CombinedOutput() + if err != nil || !strings.Contains(string(output), `"result"`) { + t.Fatalf("private fixture exec: %v: %s", err, output) + } +} + +func TestNativeContainmentTaskLimits(t *testing.T) { + resources := DefaultResourceLimits() + resources.PerSession.Tasks, resources.Total.Tasks = 8, 12 + manager := contained_manager(t, resources) + first := resource_peer(t, manager, "first") + second := resource_peer(t, manager, "second") + for _, session := range []*Session{first, second} { + if result := resource_call(t, session, `{"action":"tasks"}`); result.Err != nil { + t.Fatal(result.Err) + } + } + parent := manager.containment.group.path + if count := read_control(t, parent, "pids.current"); count != "12" { + t.Fatalf("aggregate task limit was not reached: %s", count) + } + if count := read_control(t, filepath.Join(parent, first.Identity()), "pids.current"); count != "8" { + t.Fatalf("session task limit was not reached: %s", count) + } + if control_counter(t, parent, "pids.events", "max") == 0 { + t.Fatal("kernel did not report task limit enforcement") + } +} + +func TestNativeContainmentMemoryLimits(t *testing.T) { + for _, aggregate := range []bool{false, true} { + t.Run(fmt.Sprintf("aggregate-%t", aggregate), func(t *testing.T) { + resources := DefaultResourceLimits() + resources.PerSession.MemoryBytes, resources.Total.MemoryBytes = 64<<20, 96<<20 + manager := contained_manager(t, resources) + first := resource_peer(t, manager, "first") + if aggregate { + second := resource_peer(t, manager, "second") + if result := resource_call(t, first, `{"action":"memory","bytes":50331648}`); result.Err != nil { + t.Fatal(result.Err) + } + // The kernel may select either session as the aggregate OOM victim. + resource_call(t, second, `{"action":"memory","bytes":50331648}`) + } else { + if result := resource_call(t, first, `{"action":"memory","bytes":100663296}`); result.Err == nil { + t.Fatal("allocation above session limit succeeded") + } + wait_signal(t, first.Done()) + } + wait_control(t, func() bool { + return control_counter(t, manager.containment.group.path, "memory.events", "oom_kill") > 0 + }) + }) + } +} + +func TestNativeContainmentCPUThrottling(t *testing.T) { + for _, aggregate := range []bool{false, true} { + t.Run(fmt.Sprintf("aggregate-%t", aggregate), func(t *testing.T) { + resources := DefaultResourceLimits() + if aggregate { + resources.PerSession.CPUQuota, resources.Total.CPUQuota = 50000, 50000 + } + manager := contained_manager(t, resources) + first := resource_peer(t, manager, "first") + path := filepath.Join(manager.containment.group.path, first.Identity()) + if aggregate { + second := resource_peer(t, manager, "second") + if result := resource_call(t, second, `{"action":"cpu"}`); result.Err != nil { + t.Fatal(result.Err) + } + path = manager.containment.group.path + } + if result := resource_call(t, first, `{"action":"cpu"}`); result.Err != nil { + t.Fatal(result.Err) + } + wait_control(t, func() bool { return control_counter(t, path, "cpu.stat", "nr_throttled") > 0 }) + }) + } +} + +func TestNativeContainmentFailedLaunchReleasesGroups(t *testing.T) { + manager := contained_manager(t, DefaultResourceLimits()) + session, err := manager.Start(context.Background(), Spec{ID: "missing", Program: []string{"/nonexistent/tentacle-fixture"}}) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Done()) + if state, err := session.Status(); state != Failed || err == nil { + t.Fatalf("missing executable %s: %v", state, err) + } + if _, err := os.Stat(filepath.Join(manager.containment.group.path, session.Identity())); !os.IsNotExist(err) { + t.Fatalf("failed launch leaked a group: %v", err) + } + resource_peer(t, manager, "missing") +} + +func TestNativeContainmentSDKRoundTrip(t *testing.T) { + for _, language := range []string{"go", "python"} { + t.Run(language, func(t *testing.T) { + manager := contained_manager(t, DefaultResourceLimits()) + program := sdk_program(t, language, filepath.Join(t.TempDir(), "cancelled")) + session, err := manager.Start(context.Background(), Spec{ID: "sdk", Program: program}) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Ready()) + if state, err := session.Status(); state != Ready || err != nil { + t.Fatalf("contained SDK startup %s: %v", state, err) + } + if err := session.Activate(); err != nil { + t.Fatal(err) + } + const arguments = `{"text":"é猫😀é"}` + if result := resource_call(t, session, arguments); result.Err != nil || string(result.Value) != arguments { + t.Fatalf("contained SDK round trip: %+v", result) + } + }) + } +} + +func TestNativeContainmentCleanupFailure(t *testing.T) { + manager := contained_manager(t, DefaultResourceLimits()) + session := resource_peer(t, manager, "cleanup-failure") + groupPath := filepath.Join(manager.containment.group.path, session.Identity()) + killPath := filepath.Join(groupPath, "cgroup.kill") + info, err := os.Stat(killPath) + if err != nil { + t.Fatal(err) + } + // This peer has no descendants. Remove kill-file access to exercise the + // real cleanup error; direct child termination still joins the pipe workers. + if err := os.Chmod(killPath, 0); err != nil { + t.Fatal(err) + } + defer func() { + if err := os.Chmod(killPath, info.Mode().Perm()); err != nil { + t.Error(err) + return + } + if err := (&cgroup{path: groupPath}).kill_and_remove(time.Second); err != nil { + t.Error(err) + return + } + // Only the fixture repairs its deliberately broken group; production + // requires supervisor recovery and never reclaims an uncertain slot. + manager.mutex.Lock() + delete(manager.sessions, session.spec.ID) + manager.cleanupError = nil + manager.mutex.Unlock() + }() + session.Disable() + wait_signal(t, session.Done()) + if state, err := session.Status(); state != Failed || !errors.Is(err, ErrContainment) { + t.Fatalf("failed cleanup reported %s: %v", state, err) + } + if manager.Stats().Processes != 1 { + t.Fatal("failed cleanup released admission capacity") + } + if _, err := manager.Start(context.Background(), child_spec(t, "blocked", "echo")); !errors.Is(err, ErrContainment) { + t.Fatalf("cleanup failure admitted a child: %v", err) + } + if err := manager.Shutdown(context.Background()); !errors.Is(err, ErrContainment) { + t.Fatalf("cleanup failure reported successful shutdown: %v", err) + } +} diff --git a/internal/tentacle/install.go b/internal/tentacle/install.go new file mode 100644 index 0000000..3c15c30 --- /dev/null +++ b/internal/tentacle/install.go @@ -0,0 +1,431 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "archive/tar" + "compress/gzip" + "context" + "crypto/sha256" + "debug/elf" + "encoding/hex" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path" + "path/filepath" + "runtime" + "slices" + "strings" + "time" + + "github.com/pelletier/go-toml/v2" +) + +const maxPackageBytes = 32 << 20 +const maxExpandedBytes = 64 << 20 + +func valid_digest(value string) bool { + decoded, err := hex.DecodeString(value) + return err == nil && len(decoded) == sha256.Size && value == strings.ToLower(value) +} + +func valid_revision(value string) bool { + decoded, err := hex.DecodeString(value) + return err == nil && (len(decoded) == 20 || len(decoded) == 32) && value == strings.ToLower(value) +} + +func artifact_url(value string) bool { + parsed, err := url.Parse(value) + return err == nil && parsed.Scheme == "https" && parsed.Hostname() != "" && parsed.User == nil && parsed.Opaque == "" && parsed.Fragment == "" && !strings.Contains(value, "#") && len(value) <= 2048 && metadata_text(value, true) +} + +func validate_releases(releases []Release) error { + if len(releases) > 16 { + return ErrLimit + } + seen := make(map[string]bool) + for _, release := range releases { + key := release.Platform + "/" + release.Architecture + if !metadata_id(release.Platform) || !metadata_id(release.Architecture) || !artifact_url(release.URL) || !valid_digest(release.SHA256) || seen[key] { + return errors.New("Invalid or duplicate package release metadata.") + } + seen[key] = true + } + return nil +} + +func PackageRoot(registryPath string) string { + return filepath.Join(filepath.Dir(registryPath), "tentacle-packages") +} + +func PackageID(repository Repository, localID string) string { + digest := sha256.Sum256([]byte(repository.URL + "\x00" + repository.ID + "\x00" + localID)) + return "pkg-" + hex.EncodeToString(digest[:]) +} + +// PreparedPackage owns unpublished files until the lifecycle owner persists its +// Entry. Once queued, the caller waits for that owner's decision before Discard; +// successful persistence calls Retain. Validation never runs package code. +type PreparedPackage struct { + Entry Entry + directory string +} + +func (prepared *PreparedPackage) Discard() error { + if prepared == nil || prepared.directory == "" { + return nil + } + err := os.RemoveAll(prepared.directory) + if err == nil { + prepared.directory = "" + } + return err +} + +func (prepared *PreparedPackage) Retain() { prepared.directory = "" } + +func PreparePackage(ctx context.Context, root string, repository Repository, localID string) (*PreparedPackage, error) { + return prepare_package(ctx, root, repository, localID, new_package_client()) +} + +func new_package_client() *http.Client { + return &http.Client{Timeout: 45 * time.Second, CheckRedirect: func(request *http.Request, via []*http.Request) error { + if len(via) >= 5 || !artifact_url(request.URL.String()) { + return errors.New("Package redirect must use HTTPS without credentials.") + } + return nil + }} +} + +func prepare_package(ctx context.Context, root string, repository Repository, localID string, client *http.Client) (_ *PreparedPackage, resultError error) { + if err := ValidateRepositories([]Repository{repository}); err != nil { + return nil, err + } + index := slices.IndexFunc(repository.Tentacles, func(value Manifest) bool { return value.ID == localID }) + if index < 0 { + return nil, errors.New("Tentacle is no longer listed in this repository.") + } + manifest := repository.Tentacles[index] + releaseIndex := slices.IndexFunc(manifest.Releases, func(value Release) bool { + return value.Platform == runtime.GOOS && value.Architecture == runtime.GOARCH + }) + if releaseIndex < 0 { + return nil, fmt.Errorf("No package is available for %s/%s. Refresh the repository after a release is published.", runtime.GOOS, runtime.GOARCH) + } + release := manifest.Releases[releaseIndex] + if !filepath.IsAbs(root) { + return nil, errors.New("Package root must be absolute.") + } + if err := os.MkdirAll(root, 0700); err != nil { + return nil, err + } + info, err := os.Lstat(root) + if err != nil || !info.IsDir() || info.Mode()&os.ModeSymlink != 0 { + return nil, errors.New("Package root must be a directory, not a symlink.") + } + stage, err := os.MkdirTemp(root, ".staging-") + if err != nil { + return nil, err + } + prepared := &PreparedPackage{directory: stage} + defer func() { + if resultError != nil { + _ = prepared.Discard() + } + }() + request, err := http.NewRequestWithContext(ctx, http.MethodGet, release.URL, nil) + if err != nil { + return nil, err + } + response, err := client.Do(request) + if err != nil { + return nil, errors.New("Package download failed; check the connection or retry.") + } + defer response.Body.Close() + if response.StatusCode != http.StatusOK { + return nil, errors.New("Package download failed; the server did not return a package.") + } + if response.ContentLength > maxPackageBytes { + return nil, ErrLimit + } + archive, err := os.CreateTemp(root, ".download-") + if err != nil { + return nil, err + } + defer os.Remove(archive.Name()) + defer archive.Close() + digest := sha256.New() + count, err := io.Copy(io.MultiWriter(archive, digest), io.LimitReader(response.Body, maxPackageBytes+1)) + if err != nil { + return nil, errors.New("Package download was interrupted.") + } + if count > maxPackageBytes { + return nil, ErrLimit + } + if hex.EncodeToString(digest.Sum(nil)) != release.SHA256 { + return nil, errors.New("Package checksum does not match the catalog; nothing was installed.") + } + if _, err := archive.Seek(0, io.SeekStart); err != nil { + return nil, err + } + if err := extract_package(ctx, archive, stage); err != nil { + return nil, err + } + data, err := read_registry(filepath.Join(stage, "tentacle.toml")) + if err != nil || data == nil { + return nil, errors.New("Package must contain a regular tentacle.toml.") + } + var packageManifest struct { + Manifest + Runtime string `toml:"runtime"` + Platforms []string `toml:"platforms"` + EntryPoint []string `toml:"entry-point"` + APIs []string `toml:"apis"` + Protocol struct { + Major int `toml:"major"` + Minor int `toml:"minor"` + } `toml:"protocol"` + } + if err := toml.Unmarshal(data, &packageManifest); err != nil { + return nil, errors.New("Package manifest is invalid TOML.") + } + if packageManifest.FormatVersion != manifest.FormatVersion || packageManifest.ID != manifest.ID || packageManifest.Version != manifest.Version || packageManifest.Name != manifest.Name || !slices.Equal(packageManifest.Capabilities, manifest.Capabilities) { + return nil, errors.New("Package identity, version or permissions disagree with the catalog; refresh the repository.") + } + if packageManifest.Runtime != "native" || !slices.Contains(packageManifest.Platforms, runtime.GOOS) || packageManifest.Protocol.Major != 1 || packageManifest.Protocol.Minor != 0 { + return nil, errors.New("Package runtime, platform or protocol is unsupported by this reader.") + } + presentation := slices.Contains(packageManifest.Capabilities, "presentation") + interactive := slices.Contains(packageManifest.Capabilities, "interaction") + readerSettings := slices.Contains(packageManifest.Capabilities, "reader-settings") + expectedAPIs := []string{"commands"} + if presentation { + expectedAPIs = append(expectedAPIs, "presentation") + } + if interactive { + expectedAPIs = append(expectedAPIs, "interaction") + } + if readerSettings { + expectedAPIs = append(expectedAPIs, "reader-settings") + } + if readerSettings && !interactive || interactive && !presentation || len(packageManifest.Capabilities) != len(expectedAPIs)-1 || !slices.Equal(packageManifest.APIs, expectedAPIs) { + return nil, errors.New("Package requires unsupported APIs or permissions.") + } + if len(packageManifest.EntryPoint) == 0 || len(packageManifest.EntryPoint) > 32 || !package_path(packageManifest.EntryPoint[0]) { + return nil, errors.New("Package entry point must be a relative file path inside the package.") + } + executable := filepath.Join(stage, filepath.FromSlash(packageManifest.EntryPoint[0])) + if err := validate_native_program(executable); err != nil { + return nil, err + } + if err := ctx.Err(); err != nil { + return nil, err + } + if err := filepath.WalkDir(stage, func(filename string, entry os.DirEntry, walkError error) error { + if walkError != nil { + return walkError + } + if entry.IsDir() { + return sync_directory(filename) + } + return nil + }); err != nil { + return nil, err + } + // Every installation gets a private immutable directory. Never overwrite an + // existing version; a crash before registry commit leaves only inert files. + final := filepath.Join(root, "package-"+strings.TrimPrefix(filepath.Base(stage), ".staging-")) + if err := os.Rename(stage, final); err != nil { + return nil, err + } + prepared.directory = final + program := slices.Clone(packageManifest.EntryPoint) + program[0] = filepath.Join(final, filepath.FromSlash(program[0])) + prepared.Entry = Entry{ID: PackageID(repository, localID), LocalID: localID, Name: manifest.Name, Version: manifest.Version, + Program: program, Directory: final, Presentation: presentation, Interaction: interactive, ReaderSettings: readerSettings, Repository: repository.URL, RepositoryID: repository.ID, + RepositoryRevision: repository.Revision, PackageDirectory: final, PackageSHA256: release.SHA256} + if err := ValidateEntries([]Entry{prepared.Entry}); err != nil { + return nil, err + } + if err := sync_directory(final); err != nil { + return nil, err + } + if err := sync_directory(root); err != nil { + return nil, err + } + return prepared, nil +} + +func package_path(filename string) bool { + return filename != "" && filename != "." && !strings.HasPrefix(filename, "/") && path.Clean(filename) == filename && filename != ".." && !strings.HasPrefix(filename, "../") && !strings.ContainsAny(filename, "\\\x00\r\n:") && len(filename) <= 4096 +} + +func extract_package(ctx context.Context, archive io.Reader, directory string) error { + compressed, err := gzip.NewReader(archive) + if err != nil { + return errors.New("Package must be a gzip tar archive.") + } + defer compressed.Close() + limited := &io.LimitedReader{R: compressed, N: maxExpandedBytes + 1} + reader := tar.NewReader(limited) + seen := make(map[string]bool) + for count := 0; ; count++ { + if err := ctx.Err(); err != nil { + return err + } + header, err := reader.Next() + if err == io.EOF { + break + } + if err != nil { + return errors.New("Invalid or oversized package archive.") + } + if count >= 1024 || header.Size < 0 || header.Size > maxExpandedBytes { + return ErrLimit + } + filename := strings.TrimSuffix(header.Name, "/") + if !package_path(filename) || seen[filename] { + return errors.New("Package contains unsafe or duplicate paths.") + } + seen[filename] = true + target := filepath.Join(directory, filepath.FromSlash(filename)) + switch header.Typeflag { + case tar.TypeDir: + if header.Size != 0 { + return errors.New("Invalid package directory.") + } + if err := os.MkdirAll(target, 0700); err != nil { + return err + } + case tar.TypeReg, tar.TypeRegA: + if err := os.MkdirAll(filepath.Dir(target), 0700); err != nil { + return err + } + mode := os.FileMode(0600) + if header.Mode&0111 != 0 { + mode = 0700 + } + file, err := os.OpenFile(target, os.O_WRONLY|os.O_CREATE|os.O_EXCL, mode) + if err != nil { + return errors.New("Package contains conflicting paths.") + } + _, copyError := io.CopyN(file, reader, header.Size) + syncError := file.Sync() + closeError := file.Close() + if err := errors.Join(copyError, syncError, closeError); err != nil { + return err + } + default: + return errors.New("Packages may contain only regular files and directories, without links or devices.") + } + } + // Read through the gzip trailer to detect corruption and expansion bombs. + if _, err := io.Copy(io.Discard, limited); err != nil { + return errors.New("Package compression is corrupt.") + } + if limited.N == 0 { + return ErrLimit + } + return nil +} + +func validate_native_program(filename string) error { + info, err := os.Stat(filename) + if err != nil || !info.Mode().IsRegular() || info.Mode()&0100 == 0 { + return errors.New("Package entry point is missing or not executable.") + } + binary, err := elf.Open(filename) + if err != nil { + return errors.New("Native package entry point must be an ELF executable.") + } + defer binary.Close() + machines := map[string]elf.Machine{"amd64": elf.EM_X86_64, "arm64": elf.EM_AARCH64, "386": elf.EM_386, "arm": elf.EM_ARM, "riscv64": elf.EM_RISCV, "ppc64": elf.EM_PPC64, "ppc64le": elf.EM_PPC64, "s390x": elf.EM_S390} + machine, supported := machines[runtime.GOARCH] + if !supported || binary.Machine != machine || (binary.Type != elf.ET_EXEC && binary.Type != elf.ET_DYN) { + return errors.New("Package executable does not match this platform and architecture.") + } + return nil +} + +func sync_directory(directory string) error { + file, err := os.Open(directory) + if err != nil { + return err + } + defer file.Close() + return file.Sync() +} + +// RemovePackage never deletes explicitly added local programs or paths outside +// the managed root. Call only after a saved removal and after the session joins. +func RemovePackage(root string, entry Entry) error { + directory := entry.PackageDirectory + if directory == "" { + return nil + } + rootInfo, rootError := os.Lstat(root) + if rootError != nil || !rootInfo.IsDir() || rootInfo.Mode()&os.ModeSymlink != 0 { + return errors.New("Managed package root is unsafe.") + } + if filepath.Dir(directory) != filepath.Clean(root) || !strings.HasPrefix(filepath.Base(directory), "package-") || filepath.Clean(directory) != directory { + return errors.New("Refusing to remove a package outside the managed directory.") + } + info, err := os.Lstat(directory) + if errors.Is(err, os.ErrNotExist) { + return nil + } + if err != nil || !info.IsDir() || info.Mode()&os.ModeSymlink != 0 { + return errors.New("Installed package directory is unsafe.") + } + if err := os.RemoveAll(directory); err != nil { + return err + } + return sync_directory(root) +} + +// RecoverPackages runs once, after a successful registry load, before accepting +// management requests. The registry is the commit point; orphaned directories +// from interrupted installs/removals contain no live selected code. +func RecoverPackages(root string, entries []Entry) error { + info, err := os.Lstat(root) + if errors.Is(err, os.ErrNotExist) { + return nil + } + if err != nil || !info.IsDir() || info.Mode()&os.ModeSymlink != 0 { + return errors.New("Managed package root is unsafe.") + } + retained := make(map[string]bool) + for _, entry := range entries { + for _, filename := range append([]string{entry.PackageDirectory, entry.Directory}, entry.Program...) { + relative, err := filepath.Rel(root, filename) + if err == nil && package_path(filepath.ToSlash(relative)) { + retained[strings.Split(filepath.ToSlash(relative), "/")[0]] = true + } + } + } + files, err := os.ReadDir(root) + if err != nil { + return err + } + for _, file := range files { + name := file.Name() + owned := false + for _, prefix := range []string{".staging-", ".download-", "package-"} { + if suffix, found := strings.CutPrefix(name, prefix); found && suffix != "" && len(suffix) <= 10 && !strings.ContainsFunc(suffix, func(value rune) bool { return value < '0' || value > '9' }) { + owned = true + } + } + if !owned || retained[name] || file.Type()&os.ModeSymlink != 0 { + continue + } + if err := os.RemoveAll(filepath.Join(root, name)); err != nil { + return err + } + } + return sync_directory(root) +} diff --git a/internal/tentacle/install_test.go b/internal/tentacle/install_test.go new file mode 100644 index 0000000..93df7dc --- /dev/null +++ b/internal/tentacle/install_test.go @@ -0,0 +1,442 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package tentacle + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "context" + "crypto/sha256" + "fmt" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" + "io" + "net/http" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" +) + +type packageTransport func(*http.Request) (*http.Response, error) + +func (transport packageTransport) RoundTrip(request *http.Request) (*http.Response, error) { + return transport(request) +} + +type archiveMember struct { + name string + data []byte + kind byte + mode int64 +} + +func package_archive(t *testing.T, members []archiveMember) []byte { + t.Helper() + var output bytes.Buffer + compressed := gzip.NewWriter(&output) + archive := tar.NewWriter(compressed) + for _, member := range members { + if member.kind == 0 { + member.kind = tar.TypeReg + } + header := &tar.Header{Name: member.name, Mode: member.mode, Size: int64(len(member.data)), Typeflag: member.kind} + if member.kind == tar.TypeSymlink || member.kind == tar.TypeLink { + header.Linkname = "../../outside" + } + if err := archive.WriteHeader(header); err != nil { + t.Fatal(err) + } + if _, err := archive.Write(member.data); err != nil { + t.Fatal(err) + } + } + if err := archive.Close(); err != nil { + t.Fatal(err) + } + if err := compressed.Close(); err != nil { + t.Fatal(err) + } + return output.Bytes() +} + +func package_manifest() string { + return "format-version=1\nid='echo'\nname='Echo'\nversion='0.1'\nruntime='native'\nplatforms=['linux']\nentry-point=['bin/echo']\napis=['commands','presentation']\ncapabilities=['presentation']\n[protocol]\nmajor=1\nminor=0\n" +} + +func package_fixture(t *testing.T, data []byte) (Repository, *http.Client) { + t.Helper() + digest := sha256.Sum256(data) + repository := Repository{URL: "https://example.org/team/tentacles", ID: "example.tentacles", Name: "Example", Revision: strings.Repeat("a", 40), + Tentacles: []Manifest{{FormatVersion: 1, ID: "echo", Name: "Echo", Version: "0.1", Capabilities: []string{"presentation"}, + Releases: []Release{{Platform: runtime.GOOS, Architecture: runtime.GOARCH, URL: "https://example.org/releases/echo.tar.gz", SHA256: fmt.Sprintf("%x", digest)}}}}} + client := &http.Client{Transport: packageTransport(func(request *http.Request) (*http.Response, error) { + if err := request.Context().Err(); err != nil { + return nil, err + } + return &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader(data)), ContentLength: int64(len(data)), Header: make(http.Header)}, nil + })} + return repository, client +} + +func native_members(t *testing.T) []archiveMember { + t.Helper() + filename, err := os.Executable() + if err != nil { + t.Fatal(err) + } + data, err := os.ReadFile(filename) + if err != nil { + t.Fatal(err) + } + return []archiveMember{{name: "tentacle.toml", data: []byte(package_manifest()), mode: 0644}, {name: "bin/echo", data: data, mode: 0755}} +} + +func TestPackageInstallPinsIdentityPermissionsAndSurvivesRestart(t *testing.T) { + data := package_archive(t, native_members(t)) + repository, client := package_fixture(t, data) + root := filepath.Join(t.TempDir(), "packages") + prepared, err := prepare_package(context.Background(), root, repository, "echo", client) + if err != nil { + t.Fatal(err) + } + defer prepared.Discard() + entry := prepared.Entry + if entry.Enabled || !entry.Presentation || entry.ID != PackageID(repository, "echo") || entry.RepositoryRevision != repository.Revision || entry.PackageSHA256 != repository.Tentacles[0].Releases[0].SHA256 || filepath.Dir(entry.Program[0]) != filepath.Join(entry.PackageDirectory, "bin") { + t.Fatal(entry) + } + other := repository + other.URL = "https://other.example.org/team/tentacles" + if PackageID(other, "echo") == entry.ID { + t.Fatal("different origins share identity") + } + registry := &Registry{Path: filepath.Join(t.TempDir(), "tentacles.toml")} + if _, err := registry.Load(); err != nil { + t.Fatal(err) + } + if err := registry.SaveState([]Entry{entry}, []Repository{repository}); err != nil { + t.Fatal(err) + } + prepared.Retain() + reopened := &Registry{Path: registry.Path} + entries, err := reopened.Load() + if err != nil || len(entries) != 1 || entries[0].PackageSHA256 != entry.PackageSHA256 { + t.Fatalf("restart %v %v", entries, err) + } + if err := RemovePackage(root, entries[0]); err != nil { + t.Fatal(err) + } + if _, err := os.Stat(entry.PackageDirectory); !os.IsNotExist(err) { + t.Fatal("package files retained", err) + } +} + +func TestPackageRejectsBadDownloadsAndManifestsWithoutFiles(t *testing.T) { + for _, problem := range []string{"digest", "status", "unsupported architecture", "version", "grant", "runtime", "protocol", "api", "entry traversal", "missing executable", "not executable", "not ELF", "cancelled", "corrupt gzip"} { + t.Run(problem, func(t *testing.T) { + members := native_members(t) + switch problem { + case "version": + members[0].data = []byte(strings.Replace(package_manifest(), "version='0.1'", "version='0.2'", 1)) + case "grant": + members[0].data = []byte(strings.Replace(package_manifest(), "capabilities=['presentation']", "capabilities=[]", 1)) + case "runtime": + members[0].data = []byte(strings.Replace(package_manifest(), "runtime='native'", "runtime='python'", 1)) + case "protocol": + members[0].data = []byte(strings.Replace(package_manifest(), "major=1", "major=2", 1)) + case "api": + members[0].data = []byte(strings.Replace(package_manifest(), "'commands','presentation'", "'commands','focused-text'", 1)) + case "entry traversal": + members[0].data = []byte(strings.Replace(package_manifest(), "bin/echo", "../echo", 1)) + case "missing executable": + members = members[:1] + case "not executable": + members[1].mode = 0644 + case "not ELF": + members[1].data = []byte("#!/bin/sh\nexit 0\n") + } + data := package_archive(t, members) + if problem == "corrupt gzip" { + data[len(data)-8] ^= 0xff + } + repository, client := package_fixture(t, data) + if problem == "digest" { + repository.Tentacles[0].Releases[0].SHA256 = strings.Repeat("0", 64) + } + if problem == "unsupported architecture" { + repository.Tentacles[0].Releases[0].Architecture = "unknown" + } + if problem == "status" { + client.Transport = packageTransport(func(*http.Request) (*http.Response, error) { + return &http.Response{StatusCode: 404, Body: io.NopCloser(strings.NewReader("missing"))}, nil + }) + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + if problem == "cancelled" { + cancel() + } + root := filepath.Join(t.TempDir(), "packages") + if prepared, err := prepare_package(ctx, root, repository, "echo", client); err == nil { + prepared.Discard() + t.Fatal("accepted", problem) + } + files, err := os.ReadDir(root) + if !os.IsNotExist(err) && err != nil { + t.Fatal(err) + } + if len(files) != 0 { + t.Fatal("failed install left files", files) + } + }) + } +} + +func TestPackageExtractionRejectsEscapesLinksConflictsAndExpansion(t *testing.T) { + cases := [][]archiveMember{ + {{name: "../outside", data: []byte("bad")}}, {{name: "/absolute", data: []byte("bad")}}, + {{name: "bin/link", kind: tar.TypeSymlink}}, {{name: "bin/link", kind: tar.TypeLink}}, + {{name: "device", kind: tar.TypeFifo}}, {{name: "same"}, {name: "same"}}, + {{name: "bin", data: []byte("file")}, {name: "bin/child"}}, + {{name: "bin\\escape"}}, {{name: "./relative"}}, + {{name: "huge", data: bytes.Repeat([]byte{0}, maxExpandedBytes+1)}}, + } + for index, members := range cases { + t.Run(fmt.Sprint(index), func(t *testing.T) { + if err := extract_package(context.Background(), bytes.NewReader(package_archive(t, members)), t.TempDir()); err == nil { + t.Fatal("unsafe archive accepted") + } + }) + } +} + +func TestPackageRemovalPreservesLocalFilesAndRejectsForeignDirectories(t *testing.T) { + root := t.TempDir() + outside := t.TempDir() + if err := RemovePackage(root, Entry{Program: []string{filepath.Join(outside, "local")}}); err != nil { + t.Fatal(err) + } + if err := RemovePackage(root, Entry{PackageDirectory: outside}); err == nil { + t.Fatal("outside path accepted") + } + link := filepath.Join(root, "package-link") + if err := os.Symlink(outside, link); err != nil { + t.Fatal(err) + } + if err := RemovePackage(root, Entry{PackageDirectory: link}); err == nil { + t.Fatal("symlink accepted") + } + if _, err := os.Stat(outside); err != nil { + t.Fatal("outside removed", err) + } +} + +func TestReleaseCatalogValidationAndDeepClone(t *testing.T) { + files := repository_files() + files["catalog.toml"] += "[[tentacles.releases]]\nplatform='linux'\narchitecture='amd64'\nurl='https://example.org/release.tar.gz'\nsha256='" + strings.Repeat("a", 64) + "'\n" + repository, err := read_repository_fixture(files) + if err != nil { + t.Fatal(err) + } + clone := CloneRepositories([]Repository{repository}) + clone[0].Tentacles[0].Releases[0].SHA256 = "changed" + clone[0].Tentacles[0].Capabilities[0] = "changed" + if repository.Tentacles[0].Releases[0].SHA256 == "changed" || repository.Tentacles[0].Capabilities[0] == "changed" { + t.Fatal("shared catalog storage") + } + for _, value := range []string{"http://example.org/archive", "https://Username@example.org/archive", "https://example.org/archive#fragment"} { + repository.Tentacles[0].Releases[0].URL = value + if ValidateRepositories([]Repository{repository}) == nil { + t.Fatal("unsafe URL accepted", value) + } + } +} + +func TestPackageRecoveryKeepsSelectedFilesAndLocalReferences(t *testing.T) { + root := t.TempDir() + for _, name := range []string{"package-123", "package-456", ".staging-789", "package-user", "package-321"} { + if err := os.Mkdir(filepath.Join(root, name), 0700); err != nil { + t.Fatal(err) + } + } + if err := os.WriteFile(filepath.Join(root, ".download-567"), []byte("partial"), 0600); err != nil { + t.Fatal(err) + } + entries := []Entry{{PackageDirectory: filepath.Join(root, "package-123")}, {Program: []string{filepath.Join(root, "package-321", "bin", "local")}}} + if err := RecoverPackages(root, entries); err != nil { + t.Fatal(err) + } + for _, name := range []string{"package-123", "package-user", "package-321"} { + if _, err := os.Stat(filepath.Join(root, name)); err != nil { + t.Fatal("selected/local files lost", err) + } + } + for _, name := range []string{"package-456", ".staging-789", ".download-567"} { + if _, err := os.Stat(filepath.Join(root, name)); !os.IsNotExist(err) { + t.Fatal("orphan retained", name, err) + } + } +} + +func TestPackageRedirectsRejectHTTPAndCredentials(t *testing.T) { + for _, location := range []string{"http://example.org/archive", "https://Username@example.org/archive"} { + t.Run(location, func(t *testing.T) { + client := new_package_client() + calls := 0 + client.Transport = packageTransport(func(request *http.Request) (*http.Response, error) { + calls++ + return &http.Response{StatusCode: 302, Header: http.Header{"Location": []string{location}}, Body: io.NopCloser(strings.NewReader("")), Request: request}, nil + }) + if response, err := client.Get("https://example.org/release"); err == nil { + response.Body.Close() + t.Fatal("unsafe redirect accepted") + } + if calls != 1 { + t.Fatal("followed unsafe redirect", calls) + } + }) + } +} + +func TestBuiltHelloWorldPackageThroughHost(t *testing.T) { + root := os.Getenv("CTHULHU_TENTACLE_RELEASE_ROOT") + if root == "" { + t.Skip("set CTHULHU_TENTACLE_RELEASE_ROOT to validate prepared release artifacts") + } + repository, err := read_repository("https://example.org/team/tentacles", strings.Repeat("a", 40), func(filename string) ([]byte, error) { return os.ReadFile(filepath.Join(root, filename)) }) + if err != nil { + t.Fatal(err) + } + var manifest Manifest + for _, value := range repository.Tentacles { + if value.ID == "hello-world" { + manifest = value + } + } + index := -1 + for item, release := range manifest.Releases { + if release.Architecture == runtime.GOARCH && release.Platform == runtime.GOOS { + index = item + } + } + if index < 0 { + t.Fatal("no release for host") + } + data, err := os.ReadFile(filepath.Join(root, "dist", "hello-world-"+manifest.Version+"-linux-"+runtime.GOARCH+".tar.gz")) + if err != nil { + t.Fatal(err) + } + client := new_package_client() + client.Transport = packageTransport(func(*http.Request) (*http.Response, error) { + return &http.Response{StatusCode: 200, Body: io.NopCloser(bytes.NewReader(data)), Header: make(http.Header)}, nil + }) + prepared, err := prepare_package(context.Background(), filepath.Join(t.TempDir(), "packages"), repository, "hello-world", client) + if err != nil { + t.Fatal(err) + } + defer prepared.Discard() + manager, err := NewManager(DefaultLimits(), nil) + if err != nil { + t.Fatal(err) + } + defer manager.Shutdown(context.Background()) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + session, err := manager.Start(ctx, prepared.Entry.Spec()) + if err != nil { + t.Fatal(err) + } + select { + case <-session.Ready(): + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } + if err := session.Activate(); err != nil { + t.Fatal(err) + } + pending, err := session.Invoke(ctx, "hello-world", nil) + if err != nil { + t.Fatal(err) + } + select { + case result := <-pending: + if result.Err != nil { + t.Fatal(result.Err) + } + presentation, err := tentaclewire.DecodePresentation(result.Value) + if err != nil || presentation.Speech != "Hello world!" || presentation.Braille != "Hello world!" || !presentation.Uninterruptible { + t.Fatal(presentation, err) + } + case <-ctx.Done(): + t.Fatal(ctx.Err()) + } +} + +func TestInstallInteractivePackageGrant(t *testing.T) { + members := native_members(t) + for index := range members { + if members[index].name == "tentacle.toml" { + members[index].data = []byte(strings.ReplaceAll(strings.ReplaceAll(package_manifest(), "apis=['commands','presentation']", "apis=['commands','presentation','interaction']"), "capabilities=['presentation']", "capabilities=['presentation','interaction']")) + } + } + data := package_archive(t, members) + repository, client := package_fixture(t, data) + repository.Tentacles[0].Capabilities = []string{"presentation", "interaction"} + prepared, err := prepare_package(context.Background(), t.TempDir(), repository, "echo", client) + if err != nil { + t.Fatal(err) + } + defer prepared.Discard() + if !prepared.Entry.Interaction || !prepared.Entry.Spec().Interaction || !prepared.Entry.Presentation { + t.Fatal(prepared.Entry) + } +} + +func TestInstallReaderSettingsPackageGrantAndDependencies(t *testing.T) { + for _, interactive := range []bool{true, false} { + t.Run(fmt.Sprintf("interaction=%t", interactive), func(t *testing.T) { + capabilities := "'presentation','reader-settings'" + apis := "'commands','presentation','reader-settings'" + granted := []string{"presentation", "reader-settings"} + if interactive { + capabilities = "'presentation','interaction','reader-settings'" + apis = "'commands','presentation','interaction','reader-settings'" + granted = []string{"presentation", "interaction", "reader-settings"} + } + members := native_members(t) + manifest := strings.ReplaceAll(package_manifest(), "apis=['commands','presentation']", "apis=["+apis+"]") + manifest = strings.ReplaceAll(manifest, "capabilities=['presentation']", "capabilities=["+capabilities+"]") + members[0].data = []byte(manifest) + repository, client := package_fixture(t, package_archive(t, members)) + repository.Tentacles[0].Capabilities = granted + prepared, err := prepare_package(t.Context(), t.TempDir(), repository, "echo", client) + if !interactive { + if err == nil { + prepared.Discard() + t.Fatal("reader settings installed without interaction permission") + } + return + } + if err != nil { + t.Fatal(err) + } + defer prepared.Discard() + if !prepared.Entry.ReaderSettings || !prepared.Entry.Spec().ReaderSettings { + t.Fatal("reader grant not carried into runtime spec") + } + registry := &Registry{Path: filepath.Join(t.TempDir(), "tentacles.toml")} + if _, err := registry.Load(); err != nil { + t.Fatal(err) + } + if err := registry.Save([]Entry{prepared.Entry}); err != nil { + t.Fatal(err) + } + loaded, err := (&Registry{Path: registry.Path}).Load() + if err != nil || len(loaded) != 1 || !loaded[0].ReaderSettings { + t.Fatal("reader grant lost across restart", loaded, err) + } + }) + } +} diff --git a/internal/tentacle/load_test.go b/internal/tentacle/load_test.go new file mode 100644 index 0000000..b24be7e --- /dev/null +++ b/internal/tentacle/load_test.go @@ -0,0 +1,114 @@ +package tentacle + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "os/exec" + "path/filepath" + "testing" +) + +func TestPythonPeerUsesSameContract(t *testing.T) { + python, err := exec.LookPath("python3") + if err != nil { + t.Skip("Python 3 not installed") + } + fixture, err := filepath.Abs("testdata/peer.py") + if err != nil { + t.Fatal(err) + } + manager := test_manager(t, DefaultLimits(), nil) + session, err := manager.Start(context.Background(), Spec{ID: "python", Program: []string{python, "-I", "-u", fixture}}) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Ready()) + if err := session.Activate(); err != nil { + t.Fatal(err) + } + arguments := json.RawMessage(`{"text":"é猫😀é","enabled":false,"count":0}`) + pending, err := session.Invoke(context.Background(), "echo", arguments) + if err != nil { + t.Fatal(err) + } + result := wait_result(t, pending) + var value struct { + Text string + Enabled bool + Count int + } + if result.Err != nil || json.Unmarshal(result.Value, &value) != nil || value.Text != "é猫😀é" || value.Enabled || value.Count != 0 { + t.Fatalf("Python round trip: %+v, error %v", value, result.Err) + } + if result.Session != session.Identity() { + t.Fatal("wrong session") + } +} + +func TestManyTentaclesHaveAggregateBoundAndIndependentProgress(t *testing.T) { + manager := test_manager(t, DefaultLimits(), nil) + sessions := make([]*Session, 0, 16) + // Keep one healthy peer alongside fifteen peers that never reply. + healthy := start_active(t, manager, "healthy", "echo") + for index := range 15 { + sessions = append(sessions, start_active(t, manager, fmt.Sprintf("blocked-%d", index), "timeout")) + } + for index := range 63 { + if _, err := sessions[index%len(sessions)].Invoke(context.Background(), "echo", nil); err != nil { + t.Fatal(err) + } + } + result, err := healthy.Invoke(context.Background(), "echo", json.RawMessage(`{"healthy":true}`)) + if err != nil { + t.Fatal(err) + } + if reply := wait_result(t, result); reply.Err != nil || string(reply.Value) != `{"healthy":true}` { + t.Fatalf("healthy peer stalled: %+v", reply) + } + if _, err := sessions[0].Invoke(context.Background(), "echo", nil); err != nil { + t.Fatal(err) + } + if _, err := healthy.Invoke(context.Background(), "echo", nil); !errors.Is(err, ErrBusy) { + t.Fatal("missing aggregate backpressure", err) + } + if stats := manager.Stats(); stats.Pending != 64 || stats.Processes != 16 { + t.Fatalf("%+v", stats) + } + for _, session := range sessions { + session.Disable() + } + result, err = healthy.Invoke(context.Background(), "echo", nil) + if err != nil { + t.Fatal(err) + } + if reply := wait_result(t, result); reply.Err != nil { + t.Fatal(reply.Err) + } +} + +func BenchmarkCommandRoundTrip(b *testing.B) { + for _, count := range []int{1, 8, 16} { + b.Run(fmt.Sprintf("processes-%d", count), func(b *testing.B) { + manager := test_manager(b, DefaultLimits(), nil) + sessions := make([]*Session, count) + for index := range count { + sessions[index] = start_active(b, manager, fmt.Sprintf("peer-%d", index), "echo") + } + arguments := json.RawMessage(`{"text":"sample"}`) + b.ReportAllocs() + b.ResetTimer() + for index := range b.N { + pending, err := sessions[index%count].Invoke(context.Background(), "echo", arguments) + if err != nil { + b.Fatal(err) + } + if result := <-pending; result.Err != nil { + b.Fatal(result.Err) + } + } + b.StopTimer() + }) + } +} diff --git a/internal/tentacle/local.go b/internal/tentacle/local.go new file mode 100644 index 0000000..cb625a6 --- /dev/null +++ b/internal/tentacle/local.go @@ -0,0 +1,68 @@ +package tentacle + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "syscall" +) + +// LoadLocalSpecs reads an explicit development launch list, not a manifest or +// installation catalog. It does not execute code or discover directories. +func LoadLocalSpecs(path string) ([]Spec, error) { + file, err := os.OpenFile(path, os.O_RDONLY|syscall.O_NONBLOCK, 0) + if err != nil { + return nil, err + } + defer file.Close() + info, err := file.Stat() + if err != nil { + return nil, err + } + if !info.Mode().IsRegular() { + return nil, fmt.Errorf("local tentacle list must be a regular file") + } + data, err := io.ReadAll(io.LimitReader(file, MaxFrameBytes+1)) + if err != nil { + return nil, err + } + if len(data) > MaxFrameBytes { + return nil, ErrLimit + } + if err := validate_json(data); err != nil { + return nil, err + } + var specs []Spec + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&specs); err != nil { + return nil, err + } + if len(specs) > DefaultLimits().Processes { + return nil, ErrLimit + } + seen := make(map[string]bool) + for _, spec := range specs { + if err := validate_spec(spec); err != nil { + return nil, err + } + if seen[spec.ID] { + return nil, fmt.Errorf("duplicate local tentacle ID") + } + seen[spec.ID] = true + } + return specs, nil +} + +// DelegatedParent reads an explicitly configured optional cgroup parent. +// It does not inspect init-system naming conventions or move the reader. +func DelegatedParent() (string, error) { + parent := os.Getenv("CTHULHU_TENTACLE_CGROUP_PARENT") + if !filepath.IsAbs(parent) || filepath.Clean(parent) != parent { + return "", fmt.Errorf("%w: configure CTHULHU_TENTACLE_CGROUP_PARENT with an absolute delegated cgroup v2 directory", ErrContainment) + } + return parent, nil +} diff --git a/internal/tentacle/local_test.go b/internal/tentacle/local_test.go new file mode 100644 index 0000000..736c047 --- /dev/null +++ b/internal/tentacle/local_test.go @@ -0,0 +1,45 @@ +package tentacle + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func TestDelegatedReaderParent(t *testing.T) { + for _, value := range []string{"", "relative", "/sys/fs/cgroup/../outside", "/sys/fs/cgroup/extensions"} { + t.Setenv("CTHULHU_TENTACLE_CGROUP_PARENT", value) + parent, err := DelegatedParent() + if value == "/sys/fs/cgroup/extensions" { + if err != nil || parent != value { + t.Fatalf("%q: %s %v", value, parent, err) + } + } else if err == nil { + t.Fatalf("accepted %q", value) + } + } +} + +func TestLocalLaunchListValidation(t *testing.T) { + path := filepath.Join(t.TempDir(), "tentacles.json") + for _, data := range []string{ + `[{"ID":"echo","Program":["/bin/true"]}]`, + `[{"ID":"echo","Program":["relative"]}]`, + `[{"ID":"echo","Program":["/bin/true"]},{"ID":"echo","Program":["/bin/true"]}]`, + strings.Repeat(" ", MaxFrameBytes+1), + `[{"ID":"echo","ID":"other","Program":["/bin/true"]}]`, + } { + if err := os.WriteFile(path, []byte(data), 0600); err != nil { + t.Fatal(err) + } + specs, err := LoadLocalSpecs(path) + valid := data == `[{"ID":"echo","Program":["/bin/true"]}]` + if (err == nil) != valid { + t.Fatalf("validation: %v", err) + } + if valid && len(specs) != 1 { + t.Fatal(specs) + } + } +} diff --git a/internal/tentacle/management.go b/internal/tentacle/management.go new file mode 100644 index 0000000..a7dfd77 --- /dev/null +++ b/internal/tentacle/management.go @@ -0,0 +1,27 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +// ManagementRequest is the internal Preferences contract. Mutations persist +// immediately, independently of the reader's speech/settings draft. +type ManagementRequest struct { + Action string // list, settings, add/update/remove/enable/disable/retry, repository-add/refresh/remove + ID string + Entry *Entry // Required only for add/update; ID must match. + URL string // Repository origin for repository-add/refresh/remove. +} + +type EntryStatus struct { + Entry Entry + State string // disabled, starting, active, stopping, failed, or suppressed + Message string // Core-owned text, never child diagnostics or returned data. + Shortcuts []string // Acknowledged native assignments, labelled by layout. +} + +type Snapshot struct { + Entries []EntryStatus + Message string + Suppressed bool + Repositories []Repository +} diff --git a/internal/tentacle/manager.go b/internal/tentacle/manager.go new file mode 100644 index 0000000..487938c --- /dev/null +++ b/internal/tentacle/manager.go @@ -0,0 +1,209 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "context" + "crypto/rand" + "encoding/hex" + "errors" + "os" + "path/filepath" + "strings" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +type Limits struct { + Processes int + Starting int + PendingPerProcess int + PendingTotal int + StartupTimeout time.Duration + RequestTimeout time.Duration + ShutdownTimeout time.Duration +} + +func DefaultLimits() Limits { + return Limits{Processes: 16, Starting: 2, PendingPerProcess: 8, PendingTotal: 64, + StartupTimeout: 3 * time.Second, RequestTimeout: 2 * time.Second, ShutdownTimeout: 250 * time.Millisecond} +} + +// Spec is a validated launch description, independent of package metadata. +// Program[0] must be absolute; arguments are never interpreted by a shell. +type Spec struct { + ID string + Program []string + Directory string + Presentation bool // Explicit local grant for command speech/braille results. + ReaderSettings bool // Declarative preferences, quick settings and speech overrides. + Interaction bool // Internal forms and explicit focused-item/clipboard exchanges. +} + +type Stats struct { + Processes int + Starting int + Pending int +} + +type Manager struct { + mutex sync.Mutex + limits Limits + sessions map[string]*Session + starting chan struct{} + pending chan struct{} + closed bool + coreBindings map[input.KeyboardLayout]input.CommandBindings + containment *containment + supervisorProgram []string + cleanupError error +} + +// NewSupervisedManager launches a private lifetime helper for each Tentacle. +// The default needs no administrator setup. An explicit cgroup parent (or the +// CTHULHU_TENTACLE_CGROUP_PARENT environment variable in auto mode) opts into +// kernel resource limits; a broken explicit configuration never falls back. +func NewSupervisedManager(program []string, parent string) (*Manager, error) { + if len(program) == 0 || !filepath.IsAbs(program[0]) { + return nil, errors.New("tentacle supervisor must be an absolute program") + } + if parent == "" || parent == "auto" { + parent = os.Getenv("CTHULHU_TENTACLE_CGROUP_PARENT") + } + var manager *Manager + var err error + if parent == "" { + manager, err = NewManager(DefaultLimits(), nil) + } else { + manager, err = NewContainedManager(DefaultLimits(), nil, parent, DefaultResourceLimits()) + } + if err == nil { + manager.supervisorProgram = append([]string(nil), program...) + } + return manager, err +} + +// NewManager is the plain process-group host for trusted protocol fixtures. +// Reader integration uses NewSupervisedManager to clean up detached descendants. +func NewManager(limits Limits, overrides []input.BindingOverride) (*Manager, error) { + if limits.Processes < 1 || limits.Starting < 1 || limits.Starting > limits.Processes || + limits.PendingPerProcess < 1 || limits.PendingTotal < limits.PendingPerProcess || + limits.StartupTimeout <= 0 || limits.RequestTimeout <= 0 || limits.ShutdownTimeout <= 0 { + return nil, errors.New("invalid tentacle host limits") + } + if err := input.ValidateBindingOverrides(overrides); err != nil { + return nil, err + } + coreBindings := make(map[input.KeyboardLayout]input.CommandBindings) + for _, layout := range []input.KeyboardLayout{input.DesktopKeyboardLayout, input.LaptopKeyboardLayout} { + bindings, err := input.ResolveCommandBindings(layout, true, overrides) + if err != nil { + return nil, err + } + coreBindings[layout] = bindings + } + return &Manager{limits: limits, sessions: make(map[string]*Session), coreBindings: coreBindings, + starting: make(chan struct{}, limits.Starting), pending: make(chan struct{}, limits.PendingTotal)}, nil +} + +// Start reserves capacity and returns immediately. Ready closes after the child +// has either staged a valid registration or failed; Done includes worker joins. +// Rejected admission starts no process and changes no desired enablement. +func (manager *Manager) Start(ctx context.Context, spec Spec) (*Session, error) { + if ctx == nil { + return nil, errors.New("nil tentacle context") + } + if err := ctx.Err(); err != nil { + return nil, err + } + if err := validate_spec(spec); err != nil { + return nil, err + } + manager.mutex.Lock() + defer manager.mutex.Unlock() + if manager.cleanupError != nil { + return nil, manager.cleanupError + } + if manager.closed { + return nil, ErrUnavailable + } + if len(manager.sessions) >= manager.limits.Processes || manager.sessions[spec.ID] != nil { + return nil, ErrBusy + } + select { + case manager.starting <- struct{}{}: + default: + return nil, ErrBusy + } + var identity [16]byte + if _, err := rand.Read(identity[:]); err != nil { + <-manager.starting + return nil, err + } + spec.Program = append([]string{}, spec.Program...) + sessionContext, cancel := context.WithCancel(ctx) + outputContext, revokeOutput := context.WithCancel(sessionContext) + session := &Session{manager: manager, spec: spec, identity: hex.EncodeToString(identity[:]), + outputContext: outputContext, revokeOutput: revokeOutput, + ctx: sessionContext, cancel: cancel, state: Starting, ready: make(chan struct{}), done: make(chan struct{}), + stop: make(chan struct{}), revoked: make(chan struct{}), outbound: make(chan outgoing, manager.limits.PendingPerProcess+2), + pending: make(map[string]*pendingCall)} + manager.sessions[spec.ID] = session + go session.run() + return session, nil +} + +func (manager *Manager) Stats() Stats { + manager.mutex.Lock() + defer manager.mutex.Unlock() + return Stats{Processes: len(manager.sessions), Starting: len(manager.starting), Pending: len(manager.pending)} +} + +// Shutdown may wait for children and is intended for the lifecycle worker. +// Disable itself is nonblocking and revokes dispatch before requesting exit. +func (manager *Manager) Shutdown(ctx context.Context) error { + manager.mutex.Lock() + manager.closed = true + sessions := make([]*Session, 0, len(manager.sessions)) + for _, session := range manager.sessions { + sessions = append(sessions, session) + session.Disable() + } + manager.mutex.Unlock() + for _, session := range sessions { + select { + case <-session.Done(): + case <-ctx.Done(): + return ctx.Err() + } + } + manager.mutex.Lock() + defer manager.mutex.Unlock() + if manager.cleanupError != nil { + return manager.cleanupError + } + if manager.containment != nil { + if err := manager.containment.group.remove(); err != nil { + manager.cleanupError = err + return err + } + manager.containment = nil + } + return nil +} + +func validate_spec(spec Spec) error { + if spec.ReaderSettings && !spec.Interaction || spec.Interaction && !spec.Presentation || !valid_id(spec.ID) || len(spec.Program) == 0 || len(spec.Program) > 32 || + !filepath.IsAbs(spec.Program[0]) || (spec.Directory != "" && !filepath.IsAbs(spec.Directory)) { + return errors.New("invalid local tentacle launch") + } + for _, argument := range append(append([]string{}, spec.Program...), spec.Directory) { + if len(argument) > 4096 || strings.ContainsRune(argument, 0) { + return errors.New("invalid local tentacle argument") + } + } + return nil +} diff --git a/internal/tentacle/page_store.go b/internal/tentacle/page_store.go new file mode 100644 index 0000000..10261c2 --- /dev/null +++ b/internal/tentacle/page_store.go @@ -0,0 +1,105 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "bytes" + "encoding/json" + "errors" + "os" + "path/filepath" + "syscall" + + "git.stormux.org/storm/cthulhu/internal/interaction" +) + +// PageValues contains only host-validated declarative preferences. Active speech +// overrides and quick-setting selections are deliberately never restored here. +type PageValues map[string]map[string]map[string]interaction.Value + +type PageStore struct { + Path string + original []byte + loaded bool +} + +func (store *PageStore) Load() (PageValues, error) { + store.loaded = false + data, err := read_registry(store.Path) + if err != nil { + return nil, err + } + values := PageValues{} + if data != nil { + if validate_json(data) != nil { + return nil, ErrProtocol + } + if err := json.Unmarshal(data, &values); err != nil || values == nil { + return nil, ErrProtocol + } + } + store.original, store.loaded = data, true + return values, nil +} + +func (store *PageStore) Save(values PageValues) error { + if !store.loaded { + return errors.New("tentacle preferences were not loaded successfully") + } + data, err := json.Marshal(values) + if err != nil { + return err + } + if len(data) > MaxFrameBytes { + return ErrLimit + } + directory := filepath.Dir(store.Path) + if err := os.MkdirAll(directory, 0700); err != nil { + return err + } + lock, err := os.OpenFile(store.Path+".lock", os.O_CREATE|os.O_RDWR|syscall.O_NOFOLLOW|syscall.O_NONBLOCK, 0600) + if err != nil { + return err + } + defer lock.Close() + if info, err := lock.Stat(); err != nil || !info.Mode().IsRegular() { + return errors.New("tentacle preferences lock must be a regular file") + } + if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil { + return errors.New("tentacle preferences are being edited") + } + defer syscall.Flock(int(lock.Fd()), syscall.LOCK_UN) + current, err := read_registry(store.Path) + if err != nil { + return err + } + if !bytes.Equal(current, store.original) || (current == nil) != (store.original == nil) { + return errors.New("tentacle preferences changed outside the reader") + } + file, err := os.CreateTemp(directory, ".tentacle-preferences-*") + if err != nil { + return err + } + defer os.Remove(file.Name()) + defer file.Close() + if _, err := file.Write(data); err != nil { + return err + } + if err := file.Sync(); err != nil { + return err + } + if err := file.Close(); err != nil { + return err + } + dir, err := os.Open(directory) + if err != nil { + return err + } + defer dir.Close() + if err := os.Rename(file.Name(), store.Path); err != nil { + return err + } + store.original = data + return dir.Sync() +} diff --git a/internal/tentacle/page_store_test.go b/internal/tentacle/page_store_test.go new file mode 100644 index 0000000..2298d05 --- /dev/null +++ b/internal/tentacle/page_store_test.go @@ -0,0 +1,73 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package tentacle + +import ( + "git.stormux.org/storm/cthulhu/internal/interaction" + "os" + "path/filepath" + "reflect" + "testing" +) + +func TestPageStoreAtomicPersistenceAndExternalEdits(t *testing.T) { + path := filepath.Join(t.TempDir(), "preferences.json") + store := &PageStore{Path: path} + values, err := store.Load() + if err != nil || len(values) != 0 { + t.Fatal(values, err) + } + if _, err := os.Stat(path); !os.IsNotExist(err) { + t.Fatal("load created a file") + } + values["probe"] = map[string]map[string]interaction.Value{"page": {"name": {Text: "Example"}}} + if err := store.Save(values); err != nil { + t.Fatal(err) + } + info, _ := os.Stat(path) + if info.Mode().Perm() != 0600 { + t.Fatal(info.Mode()) + } + other := &PageStore{Path: path} + loaded, err := other.Load() + if err != nil || !reflect.DeepEqual(loaded, values) { + t.Fatal(loaded, err) + } + loaded["probe"]["page"]["name"] = interaction.Value{Text: "Changed"} + if err := other.Save(loaded); err != nil { + t.Fatal(err) + } + if err := store.Save(values); err == nil { + t.Fatal("overwrote another editor") + } + after, err := (&PageStore{Path: path}).Load() + if err != nil || after["probe"]["page"]["name"].Text != "Changed" { + t.Fatal(after, err) + } +} +func TestPageStoreRejectsSymlinksMalformedAndUnloadedWrites(t *testing.T) { + directory := t.TempDir() + path := filepath.Join(directory, "preferences.json") + store := &PageStore{Path: path} + if store.Save(PageValues{}) == nil { + t.Fatal("saved without loading") + } + for _, data := range []string{`null`, `{"probe":{},"probe":{}}`, `{"probe":`, `[]`} { + if err := os.WriteFile(path, []byte(data), 0600); err != nil { + t.Fatal(err) + } + if _, err := store.Load(); err == nil { + t.Fatal("accepted", data) + } + if store.Save(PageValues{}) == nil { + t.Fatal("saved after a failed load") + } + } + link := filepath.Join(directory, "link") + if err := os.Symlink(path, link); err != nil { + t.Fatal(err) + } + if _, err := (&PageStore{Path: link}).Load(); err == nil { + t.Fatal("followed a symlink") + } +} diff --git a/internal/tentacle/process.go b/internal/tentacle/process.go new file mode 100644 index 0000000..0327647 --- /dev/null +++ b/internal/tentacle/process.go @@ -0,0 +1,344 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "bufio" + "encoding/json" + "errors" + "fmt" + "io" + "os" + "os/exec" + "path/filepath" + "sync" + "syscall" + "time" +) + +func (session *Session) run() { + var cleanupError error + starting := true + ready := func() { + if starting { + starting = false + <-session.manager.starting + close(session.ready) + } + } + defer func() { + session.cancel() + session.mutex.Lock() + if cleanupError != nil { + session.fail_locked(cleanupError) + // Even a requested disable must report incomplete containment. + session.state, session.failure = Failed, cleanupError + } else if session.state == Stopping { + session.state = Stopped + } else if session.state != Failed { + session.fail_locked(ErrExited) + } + session.mutex.Unlock() + session.callbacks.Wait() + // A retained status/session handle must not retain unsent argument text. + for len(session.outbound) != 0 { + <-session.outbound + } + ready() + session.manager.mutex.Lock() + if cleanupError != nil { + // Keep the admission slot and reject further starts. Do not claim + // capacity was reclaimed when owned processes may remain alive. + session.manager.cleanupError = cleanupError + } else { + delete(session.manager.sessions, session.spec.ID) + } + close(session.done) + session.manager.mutex.Unlock() + }() + select { + case <-session.stop: + return + case <-session.ctx.Done(): + session.fail(session.ctx.Err()) + return + default: + } + + // Use owned files instead of exec's copier goroutines. Closing our ends + // unblocks workers even when a descendant retains an inherited pipe. + var pipes []*os.File + defer func() { + for _, pipe := range pipes { + pipe.Close() + } + }() + newPipe := func() (*os.File, *os.File, error) { + reader, writer, err := os.Pipe() + if err == nil { + pipes = append(pipes, reader, writer) + } + return reader, writer, err + } + childInput, input, err := newPipe() + if err != nil { + session.fail(err) + return + } + output, childOutput, err := newPipe() + if err != nil { + session.fail(err) + return + } + diagnostics, childDiagnostics, err := newPipe() + if err != nil { + session.fail(err) + return + } + command := exec.Command(session.spec.Program[0], session.spec.Program[1:]...) + supervised := len(session.manager.supervisorProgram) != 0 + var lifetime, childLifetime, configuration, childConfiguration *os.File + if supervised { + childLifetime, lifetime, err = newPipe() + if err != nil { + session.fail(ErrSupervision) + return + } + childConfiguration, configuration, err = newPipe() + if err != nil { + session.fail(ErrSupervision) + return + } + program := session.manager.supervisorProgram + command = exec.Command(program[0], program[1:]...) + command.ExtraFiles = []*os.File{childLifetime, childConfiguration} + } else { + command.Dir = session.spec.Directory + } + command.Stdin, command.Stdout, command.Stderr = childInput, childOutput, childDiagnostics + command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + var group *cgroup + if containment := session.manager.containment; containment != nil { + group, err = create_cgroup(filepath.Join(containment.group.path, session.identity), containment.limits.PerSession, 0) + if err != nil { + session.fail(err) + return + } + defer func() { cleanupError = group.kill_and_remove(containment.limits.CleanupTimeout) }() + // clone3(CLONE_INTO_CGROUP) applies limits before the child executes. + // Moving an already-running PID would leave a fork/allocation race. + command.SysProcAttr.UseCgroupFD = true + command.SysProcAttr.CgroupFD = int(group.file.Fd()) + } + var waitError error + exited := make(chan struct{}) + err = command.Start() + if err == nil { + go func() { waitError = command.Wait(); close(exited) }() + } + + if err != nil { + // Do not retain the command line, environment or child-supplied text. + if group != nil { + var errno syscall.Errno + if errors.As(err, &errno) { + session.fail(fmt.Errorf("%w: child placement/exec: %w", ErrContainment, errno)) + } else { + session.fail(ErrContainment) + } + } else { + session.fail(ErrExited) + } + return + } + childInput.Close() + childOutput.Close() + childDiagnostics.Close() + var workers sync.WaitGroup + if supervised { + childLifetime.Close() + childConfiguration.Close() + workers.Add(1) + go func() { + defer workers.Done() + _ = json.NewEncoder(configuration).Encode(session.spec) + configuration.Close() + }() + } + workers.Add(3) + go func() { defer workers.Done(); session.write_requests(input) }() + go func() { defer workers.Done(); session.read_replies(output) }() + go func() { defer workers.Done(); session.drain_diagnostics(diagnostics) }() + defer func() { + session.cancel() + if supervised { + lifetime.Close() + configuration.Close() + } + if group != nil { + _ = write_control(group.path, "cgroup.kill", "1") + if command.Process != nil { + _ = command.Process.Kill() + } + } else if !supervised { + // Explicit trusted-fixture mode only; detached descendants escape. + _ = syscall.Kill(-command.Process.Pid, syscall.SIGKILL) + } + input.Close() + output.Close() + diagnostics.Close() + if supervised && group == nil { + select { + case <-exited: + if waitError != nil { + cleanupError = ErrSupervision + } + case <-time.After(DefaultResourceLimits().CleanupTimeout + time.Second): + cleanupError = ErrSupervision + _ = command.Process.Kill() + <-exited + } + } else { + <-exited + } + workers.Wait() + }() + + session.mutex.Lock() + var initialized <-chan Result + if session.state == Starting && session.ctx.Err() == nil { + apis := []string{"commands"} + if session.spec.Presentation { + apis = append(apis, "presentation") + } + if session.spec.Interaction { + apis = append(apis, "interaction") + } + if session.spec.ReaderSettings { + apis = append(apis, "reader-settings") + } + initialized, err = session.request_locked(session.ctx, "initialize", Initialization{ + Protocol: Version{Major: 1, Minor: 0}, Session: session.identity, + APIs: apis, Capabilities: apis, + }, session.manager.limits.StartupTimeout) + } else { + err = ErrUnavailable + } + session.mutex.Unlock() + if err != nil { + session.fail(err) + return + } + select { + case result := <-initialized: + if result.Err != nil { + session.fail(result.Err) + return + } + var registration Registration + if decode_strict(result.Value, ®istration) != nil || validate_registration(registration, session.identity) != nil { + session.fail(ErrProtocol) + return + } + for _, command := range registration.Commands { + if command.Reader && !session.spec.ReaderSettings || command.Presentation && !session.spec.Presentation || command.Interaction && (!command.Presentation || !session.spec.Interaction) { + session.fail(ErrProtocol) + return + } + } + if registration.Extensions != nil && !session.spec.ReaderSettings { + session.fail(ErrProtocol) + return + } + session.mutex.Lock() + if session.state == Starting && session.ctx.Err() == nil { + session.commands = registration.Commands + if registration.Extensions != nil { + session.extensions = *registration.Extensions + } + session.state = Ready + } + session.mutex.Unlock() + ready() + case <-session.ctx.Done(): + session.fail(session.ctx.Err()) + return + case <-exited: + session.fail(ErrExited) + return + case <-session.stop: + session.wait_shutdown(exited) + return + } + select { + case <-session.ctx.Done(): + session.fail(session.ctx.Err()) + case <-exited: + session.fail(ErrExited) + case <-session.stop: + session.wait_shutdown(exited) + } +} + +func (session *Session) wait_shutdown(exited <-chan struct{}) { + timer := time.NewTimer(session.manager.limits.ShutdownTimeout) + defer timer.Stop() + select { + case <-exited: + case <-timer.C: + case <-session.ctx.Done(): + } +} + +func (session *Session) write_requests(writer io.Writer) { + for { + select { + case <-session.ctx.Done(): + return + case item := <-session.outbound: + if item.id != "" { + session.mutex.Lock() + call := session.pending[item.id] + eligible := call != nil && call.ctx.Err() == nil + session.mutex.Unlock() + if !eligible { + continue + } + } + if _, err := writer.Write(item.frame); err != nil { + session.fail(ErrExited) + return + } + } + } +} + +func (session *Session) read_replies(reader io.Reader) { + buffer := bufio.NewReaderSize(reader, 4096) + for session.ctx.Err() == nil { + frame, err := read_frame(buffer) + if err != nil { + if err == io.EOF { + err = ErrExited + } + session.fail(err) + return + } + reply, err := decode_response(frame) + if err != nil { + session.fail(err) + return + } + session.accept_reply(reply) + } +} + +func (session *Session) drain_diagnostics(reader io.Reader) { + count, err := io.Copy(io.Discard, io.LimitReader(reader, MaxDiagnosticBytes+1)) + if count > MaxDiagnosticBytes { + session.fail(ErrLimit) + } else if err != nil && session.ctx.Err() == nil { + session.fail(ErrExited) + } +} diff --git a/internal/tentacle/protocol.go b/internal/tentacle/protocol.go new file mode 100644 index 0000000..6b0527e --- /dev/null +++ b/internal/tentacle/protocol.go @@ -0,0 +1,203 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package tentacle implements the experimental process host used by explicit +// local reader launches. Start and Invoke never wait for child pipe I/O. +package tentacle + +import ( + "bufio" + "bytes" + "encoding/json" + "errors" + "fmt" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" + "strings" +) + +const ( + MaxFrameBytes = tentaclewire.MaxFrameBytes // Excludes the mandatory newline. + MaxReaderArgumentBytes = 48 * 1024 + MaxArgumentBytes = 16 * 1024 + MaxCommands = 32 + MaxDiagnosticBytes = 64 * 1024 // Lifetime budget; diagnostics are discarded. +) + +var ( + ErrBusy = errors.New("tentacle host capacity exhausted") + ErrUnavailable = errors.New("tentacle is not active") + ErrDisabled = errors.New("tentacle disabled") + ErrProtocol = tentaclewire.ErrProtocol + ErrLimit = tentaclewire.ErrLimit + ErrExited = errors.New("tentacle process exited") +) + +type Version struct { + Major int `json:"major"` + Minor int `json:"minor"` +} + +type Command struct { + ID string `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + Bindings []Binding `json:"bindings,omitempty"` + Presentation bool `json:"presentation,omitempty"` + Interaction bool `json:"interaction,omitempty"` + Reader bool `json:"reader,omitempty"` + Settings bool `json:"settings,omitempty"` // Opens settings; never a continuation handler. +} + +type Initialization struct { + Protocol Version `json:"protocol"` + Session string `json:"session"` + APIs []string `json:"apis"` + Capabilities []string `json:"capabilities"` +} + +type Registration struct { + Protocol Version `json:"protocol"` + Session string `json:"session"` + Commands []Command `json:"commands"` + Extensions *tentaclewire.Extensions `json:"extensions,omitempty"` +} + +// RPCError retains the bounded remote message for a future accessible details +// view. Error deliberately omits child-supplied text from normal diagnostics. +type RPCError struct { + Code int `json:"code"` + Message string `json:"message"` +} + +func (failure *RPCError) Error() string { + return fmt.Sprintf("tentacle RPC error %d", failure.Code) +} + +type response struct { + JSONRPC string `json:"jsonrpc"` + ID string `json:"id"` + Result json.RawMessage `json:"result"` + Error *RPCError `json:"error"` +} + +type request struct { + JSONRPC string `json:"jsonrpc"` + ID string `json:"id,omitempty"` + Method string `json:"method"` + Params any `json:"params,omitempty"` +} + +func encode_request(id, method string, params any) ([]byte, error) { + data, err := json.Marshal(request{JSONRPC: "2.0", ID: id, Method: method, Params: params}) + if err != nil { + return nil, ErrProtocol + } + if len(data) > MaxFrameBytes { + return nil, ErrLimit + } + return append(data, '\n'), nil +} + +func read_frame(reader *bufio.Reader) ([]byte, error) { return tentaclewire.ReadFrame(reader) } +func validate_json(data []byte) error { return tentaclewire.ValidateJSON(data) } +func decode_strict(data []byte, target any) error { return tentaclewire.DecodeStrict(data, target) } + +func decode_response(data []byte) (response, error) { + var reply response + if err := decode_strict(data, &reply); err != nil { + return reply, err + } + // Presence matters: a null result is valid; a null error is not. + var fields map[string]json.RawMessage + _ = json.Unmarshal(data, &fields) + for key := range fields { + if key != "jsonrpc" && key != "id" && key != "result" && key != "error" { + return reply, ErrProtocol + } + } + _, hasResult := fields["result"] + _, hasError := fields["error"] + if reply.JSONRPC != "2.0" || reply.ID == "" || len(reply.ID) > 32 || hasResult == hasError || + (hasError && (reply.Error == nil || len(reply.Error.Message) > 1024)) { + return reply, ErrProtocol + } + if hasError { + var errorFields map[string]json.RawMessage + _ = json.Unmarshal(fields["error"], &errorFields) + if errorFields["code"] == nil || bytes.Equal(errorFields["code"], []byte("null")) || + errorFields["message"] == nil || bytes.Equal(errorFields["message"], []byte("null")) { + return reply, ErrProtocol + } + } + return reply, nil +} + +func valid_id(value string) bool { + if len(value) == 0 || len(value) > 128 || value[0] < 'a' || value[0] > 'z' { + return false + } + for _, char := range value { + if !(char >= 'a' && char <= 'z' || char >= '0' && char <= '9' || char == '-' || char == '.') { + return false + } + } + return true +} + +func validate_registration(registration Registration, session string) error { + if registration.Protocol != (Version{Major: 1, Minor: 0}) || registration.Session != session || + len(registration.Commands) == 0 || len(registration.Commands) > MaxCommands { + return ErrProtocol + } + seen := make(map[string]bool) + settings := false + for _, command := range registration.Commands { + if command.Reader && !command.Interaction || command.Settings && (!command.Interaction || settings) || command.Interaction && !command.Presentation || !valid_id(command.ID) || seen[command.ID] || strings.TrimSpace(command.Title) == "" || + len(command.Title) > 256 || len(command.Description) > 1024 { + return ErrProtocol + } + seen[command.ID] = true + settings = settings || command.Settings + if len(command.Bindings) > 4 { + return ErrLimit + } + for _, binding := range command.Bindings { + if err := validate_binding(binding); err != nil { + return err + } + } + } + if registration.Extensions != nil { + if err := tentaclewire.ValidateExtensions(*registration.Extensions); err != nil { + return err + } + for _, page := range registration.Extensions.Pages { + if !reader_command(registration.Commands, page.Command) { + return ErrProtocol + } + } + for _, setting := range registration.Extensions.QuickSettings { + if !reader_command(registration.Commands, setting.Command) { + return ErrProtocol + } + } + } + return nil +} + +func reader_command(commands []Command, id string) bool { + for _, command := range commands { + if command.ID == id { + return command.Reader && !command.Settings + } + } + return false +} + +func clone_commands(commands []Command) []Command { + result := append([]Command(nil), commands...) + for index := range result { + result[index].Bindings = append([]Binding(nil), result[index].Bindings...) + } + return result +} diff --git a/internal/tentacle/protocol_test.go b/internal/tentacle/protocol_test.go new file mode 100644 index 0000000..aacae74 --- /dev/null +++ b/internal/tentacle/protocol_test.go @@ -0,0 +1,95 @@ +package tentacle + +import ( + "bufio" + "bytes" + "errors" + "io" + "strings" + "testing" +) + +func TestFramingBoundsAndRequiresNewline(t *testing.T) { + for _, testCase := range []struct { + name string + input string + want error + }{ + {"valid", strings.Repeat("x", MaxFrameBytes) + "\n", nil}, + {"oversized", strings.Repeat("x", MaxFrameBytes+1) + "\n", ErrLimit}, + {"unterminated", `{}`, io.ErrUnexpectedEOF}, + {"empty", "", io.EOF}, + } { + t.Run(testCase.name, func(t *testing.T) { + _, err := read_frame(bufio.NewReaderSize(strings.NewReader(testCase.input), 32)) + if !errors.Is(err, testCase.want) { + t.Fatalf("got %v, want %v", err, testCase.want) + } + }) + } +} + +func TestResponseValidation(t *testing.T) { + for _, valid := range []string{ + `{"jsonrpc":"2.0","id":"1","result":null}`, + `{"jsonrpc":"2.0","id":"1","result":{"text":"é猫😀é"}}`, + `{"jsonrpc":"2.0","id":"1","error":{"code":-32601,"message":"Unknown method"}}`, + } { + if _, err := decode_response([]byte(valid)); err != nil { + t.Errorf("valid response rejected: %v", err) + } + } + for _, invalid := range []string{ + `[]`, `null`, `{}`, `{"jsonrpc":"2.0","id":"1"}`, + `{"jsonrpc":"2.0","id":"1","result":null,"error":null}`, + `{"jsonrpc":"2.0","id":"1","error":null}`, + `{"jsonrpc":"2.0","id":1,"result":null}`, + `{"jsonrpc":"1.0","id":"1","result":null}`, + `{"jsonrpc":"2.0","id":"1","id":"2","result":null}`, + `{"jsonrpc":"2.0","id":"1","result":{"x":0,"x":1}}`, + `{"jsonrpc":"2.0","id":"1","result":null,"extra":1}`, + `{"jsonrpc":"2.0","id":"1","error":{"message":"missing code"}}`, + `{"jsonrpc":"2.0","id":"1","error":{"code":null,"message":"null code"}}`, + `{"jsonrpc":"2.0","id":"1","error":{"code":1,"message":null}}`, + `{"jsonrpc":"2.0","id":"1","result":"` + string([]byte{0xff}) + `"}`, + `{"jsonrpc":"2.0","id":"1","result":` + strings.Repeat("[", 40) + "0" + strings.Repeat("]", 40) + `}`, + `{"jsonrpc":"2.0","id":"1","result":null} {}`, + } { + if _, err := decode_response([]byte(invalid)); err == nil { + t.Errorf("invalid response accepted: %q", invalid) + } + } + if strings.Contains((&RPCError{Code: 1, Message: "private text"}).Error(), "private") { + t.Fatal("remote text leaked through Error") + } +} + +func FuzzResponseDecoder(f *testing.F) { + f.Add([]byte(`{"jsonrpc":"2.0","id":"1","result":null}`)) + f.Add([]byte(`{"jsonrpc":"2.0","id":"1","error":{"code":1,"message":"bad"}}`)) + f.Fuzz(func(t *testing.T, data []byte) { + if len(data) > MaxFrameBytes { + t.Skip() + } + _, _ = decode_response(data) + _, _ = read_frame(bufio.NewReader(bytes.NewReader(data))) + }) +} + +func TestSettingsRegistrationRequiresOneInteractiveCommand(t *testing.T) { + command := Command{ID: "settings", Title: "Settings", Settings: true, Interaction: true, Presentation: true} + registration := Registration{Protocol: Version{Major: 1}, Session: "test", Commands: []Command{command}} + if err := validate_registration(registration, "test"); err != nil { + t.Fatal(err) + } + registration.Commands[0].Interaction = false + if err := validate_registration(registration, "test"); err == nil { + t.Fatal("accepted a settings handler without interaction") + } + registration.Commands[0] = command + command.ID = "other-settings" + registration.Commands = append(registration.Commands, command) + if err := validate_registration(registration, "test"); err == nil { + t.Fatal("accepted two settings entry points") + } +} diff --git a/internal/tentacle/reader_test.go b/internal/tentacle/reader_test.go new file mode 100644 index 0000000..6becc80 --- /dev/null +++ b/internal/tentacle/reader_test.go @@ -0,0 +1,111 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package tentacle + +import ( + "context" + "encoding/json" + "errors" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" + sdk "git.stormux.org/storm/cthulhu/sdk/go/tentacle" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func TestReaderSDKPeer(t *testing.T) { + if os.Getenv("CTHULHU_PRIVATE_READER_PEER") != "1" { + return + } + extension := sdk.Extensions{Pages: []sdk.PreferencePage{{ID: "probe", Title: "Reader probe", Command: "echo", Elements: []sdk.Element{{ID: "text", Label: "Example text", Kind: sdk.Entry}}, Values: map[string]sdk.Value{"text": {Text: "Initial"}}}}, QuickSettings: []sdk.QuickSetting{{ID: "probe", Label: "Probe choice", Command: "echo", Selected: "default", Options: []sdk.ListItem{{ID: "default", Label: "Default"}}}}} + echo := func(ctx context.Context, args json.RawMessage) (any, error) { return args, nil } + if err := sdk.ServeWithExtensions(os.Stdin, os.Stdout, []sdk.Command{{ID: "echo", Title: "Reader probe", Presentation: true, Interaction: true, Reader: true, Handle: echo}, {ID: "ordinary", Title: "Ordinary probe", Handle: echo}}, extension); err != nil { + os.Exit(1) + } + os.Exit(0) +} +func TestReaderSDKGrantsCopiesAndArgumentBounds(t *testing.T) { + t.Setenv("CTHULHU_PRIVATE_READER_PEER", "1") + for _, language := range []string{"go", "python"} { + for _, grant := range []bool{false, true} { + t.Run(language+"/"+map[bool]string{false: "denied", true: "granted"}[grant], func(t *testing.T) { + var program []string + if language == "go" { + executable, _ := os.Executable() + program = []string{executable, "-test.run=^TestReaderSDKPeer$"} + } else { + python, err := exec.LookPath("python3") + if err != nil { + t.Skip(err) + } + peer, err := filepath.Abs("testdata/sdk_reader_peer.py") + if err != nil { + t.Fatal(err) + } + program = []string{python, "-B", peer} + } + manager := test_manager(t, DefaultLimits(), nil) + session, err := manager.Start(t.Context(), Spec{ID: "probe", Program: program, Presentation: true, Interaction: true, ReaderSettings: grant}) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Ready()) + state, reason := session.Status() + if !grant { + if state == Ready { + t.Fatal("reader API accepted without grant") + } + return + } + if state != Ready { + t.Fatal(state, reason) + } + extensions := session.Extensions() + if len(extensions.Pages) != 1 || len(extensions.QuickSettings) != 1 { + t.Fatal(extensions) + } + extensions.Pages[0].Values["text"] = sdk.Value{Text: "Changed"} + extensions.Pages[0].Elements[0].Label = "Changed" + if session.Extensions().Pages[0].Values["text"].Text != "Initial" || session.Extensions().Pages[0].Elements[0].Label != "Example text" { + t.Fatal("registration shared mutable state") + } + if err := session.Activate(); err != nil { + t.Fatal(err) + } + argument := json.RawMessage(`{"text":"` + strings.Repeat("x", 24*1024) + `"}`) + replies, err := session.Invoke(t.Context(), "echo", argument) + if err != nil { + t.Fatal(err) + } + result := wait_result(t, replies) + if result.Err != nil || string(result.Value) != string(argument) { + t.Fatal("reader continuation did not round trip", result.Err) + } + if _, err := session.Invoke(t.Context(), "ordinary", argument); !errors.Is(err, ErrLimit) { + t.Fatal("ordinary command exceeded its original argument limit", err) + } + if _, err := session.Invoke(t.Context(), "echo", json.RawMessage(`"`+strings.Repeat("x", MaxReaderArgumentBytes)+`"`)); !errors.Is(err, ErrLimit) { + t.Fatal("reader limit not enforced", err) + } + }) + } + } +} +func TestReaderRegistrationRequiresDeclaredReaderCallbacks(t *testing.T) { + extension := tentaclewire.Extensions{QuickSettings: []tentaclewire.QuickSetting{{ID: "probe", Label: "Probe", Command: "apply", Selected: "default", Options: []sdk.ListItem{{ID: "default", Label: "Default"}}}}} + registration := Registration{Protocol: Version{Major: 1}, Session: "session", Commands: []Command{{ID: "apply", Title: "Apply", Presentation: true, Interaction: true, Reader: true}}, Extensions: &extension} + if err := validate_registration(registration, "session"); err != nil { + t.Fatal(err) + } + registration.Commands[0].Reader = false + if validate_registration(registration, "session") == nil { + t.Fatal("accepted an unprivileged extension callback") + } + registration.Commands[0].Reader = true + registration.Commands[0].Settings = true + if validate_registration(registration, "session") == nil { + t.Fatal("accepted a settings-form handler as a page callback") + } +} diff --git a/internal/tentacle/registry.go b/internal/tentacle/registry.go new file mode 100644 index 0000000..1550cb6 --- /dev/null +++ b/internal/tentacle/registry.go @@ -0,0 +1,246 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "bytes" + "errors" + "fmt" + "io" + "os" + "path/filepath" + "syscall" + + "github.com/pelletier/go-toml/v2" +) + +// Entry records an explicitly added local program or a verified package. +// Discovery never adds entries. Enablement is desired state; failures retain it. +type Entry struct { + ID string `toml:"id"` + Program []string `toml:"program"` + Directory string `toml:"directory,omitempty"` + Enabled bool `toml:"enabled"` + Presentation bool `toml:"presentation"` + ReaderSettings bool `toml:"reader-settings,omitempty"` + Interaction bool `toml:"interaction,omitempty"` + Repository string `toml:"repository,omitempty"` + RepositoryID string `toml:"repository-id,omitempty"` + LocalID string `toml:"local-id,omitempty"` + Name string `toml:"name,omitempty"` + Version string `toml:"package-version,omitempty"` + PackageDirectory string `toml:"package-directory,omitempty"` + PackageSHA256 string `toml:"package-sha256,omitempty"` + RepositoryRevision string `toml:"repository-revision,omitempty"` +} + +func (entry Entry) Spec() Spec { + return Spec{ID: entry.ID, Program: append([]string(nil), entry.Program...), Directory: entry.Directory, Presentation: entry.Presentation, Interaction: entry.Interaction, ReaderSettings: entry.ReaderSettings} +} + +type registryDocument struct { + Version int `toml:"version"` + Entries []Entry `toml:"tentacles"` + Repositories []Repository `toml:"repositories,omitempty"` +} + +// Registry is owned by the reader lifecycle worker, independently of profiles. +// Its optimistic revision prevents overwriting another editor's changes. +type Registry struct { + Path string + original []byte + loaded bool + repositories []Repository +} + +var ErrRegistrySync = errors.New("tentacle registry was replaced but its directory could not be synced") + +func RegistryPath(settingsPath string) string { + return filepath.Join(filepath.Dir(settingsPath), "tentacles.toml") +} + +func CloneEntries(entries []Entry) []Entry { + result := append([]Entry(nil), entries...) + for index := range result { + result[index].Program = append([]string(nil), result[index].Program...) + } + return result +} + +func ValidateEntries(entries []Entry) error { + if len(entries) > DefaultLimits().Processes { + return ErrLimit + } + seen := make(map[string]bool) + packageDirectories := make(map[string]bool) + for _, entry := range entries { + if err := validate_spec(entry.Spec()); err != nil { + return err + } + if entry.Repository != "" { + origin, err := RepositoryURL(entry.Repository) + if err != nil || origin != entry.Repository || !metadata_id(entry.RepositoryID) || !metadata_id(entry.LocalID) { + return errors.New("invalid installed tentacle source identity") + } + } else if entry.RepositoryID != "" || entry.LocalID != "" { + return errors.New("tentacle source identity requires a repository origin") + } + if !metadata_text(entry.Name, false) || !metadata_text(entry.Version, false) { + return errors.New("invalid installed tentacle display metadata") + } + if seen[entry.ID] { + return errors.New("duplicate tentacle ID") + } + if entry.PackageDirectory != "" { + relativeProgram, err := filepath.Rel(entry.PackageDirectory, entry.Program[0]) + if entry.Repository == "" || !filepath.IsAbs(entry.PackageDirectory) || + filepath.Clean(entry.PackageDirectory) != entry.PackageDirectory || entry.Directory != entry.PackageDirectory || + !valid_digest(entry.PackageSHA256) || !valid_revision(entry.RepositoryRevision) || + entry.ID != PackageID(Repository{URL: entry.Repository, ID: entry.RepositoryID}, entry.LocalID) || + err != nil || !package_path(filepath.ToSlash(relativeProgram)) || packageDirectories[entry.PackageDirectory] { + return errors.New("invalid installed package lock") + } + packageDirectories[entry.PackageDirectory] = true + } else if entry.PackageSHA256 != "" || entry.RepositoryRevision != "" { + return errors.New("package lock requires a package directory") + } + seen[entry.ID] = true + } + data, err := toml.Marshal(registryDocument{Version: 1, Entries: entries}) + if err == nil && len(data) > MaxFrameBytes { + return ErrLimit + } + return err +} + +func read_registry(path string) ([]byte, error) { + file, err := os.OpenFile(path, os.O_RDONLY|syscall.O_NONBLOCK|syscall.O_NOFOLLOW, 0) + if errors.Is(err, os.ErrNotExist) { + return nil, nil + } + if err != nil { + return nil, err + } + defer file.Close() + info, err := file.Stat() + if err != nil { + return nil, err + } + if !info.Mode().IsRegular() { + return nil, errors.New("tentacle registry must be a regular file") + } + data, err := io.ReadAll(io.LimitReader(file, MaxFrameBytes+1)) + if len(data) > MaxFrameBytes { + return nil, ErrLimit + } + return data, err +} + +func (registry *Registry) Load() ([]Entry, error) { + registry.loaded = false + data, err := read_registry(registry.Path) + if err != nil { + return nil, err + } + var document registryDocument + if data != nil { + decoder := toml.NewDecoder(bytes.NewReader(data)).DisallowUnknownFields() + if err := decoder.Decode(&document); err != nil { + return nil, err + } + if document.Version != 1 { + return nil, errors.New("unsupported tentacle registry version") + } + if err := ValidateEntries(document.Entries); err != nil { + return nil, err + } + if err := ValidateRepositories(document.Repositories); err != nil { + return nil, err + } + } + registry.original, registry.loaded = data, true + registry.repositories = CloneRepositories(document.Repositories) + return CloneEntries(document.Entries), nil +} + +// Save validates before touching disk, locks cooperating writers, and atomically +// replaces an owner-only file. A failed load can never be overwritten. +func (registry *Registry) Save(entries []Entry) error { + return registry.SaveState(entries, registry.repositories) +} + +func (registry *Registry) Repositories() []Repository { + return CloneRepositories(registry.repositories) +} + +func (registry *Registry) SaveState(entries []Entry, repositories []Repository) error { + if !registry.loaded { + return errors.New("tentacle registry has not been loaded successfully") + } + if err := ValidateEntries(entries); err != nil { + return err + } + if err := ValidateRepositories(repositories); err != nil { + return err + } + data, err := toml.Marshal(registryDocument{Version: 1, Entries: entries, Repositories: repositories}) + if err != nil { + return err + } + if len(data) > MaxFrameBytes { + return ErrLimit + } + directory := filepath.Dir(registry.Path) + if err := os.MkdirAll(directory, 0700); err != nil { + return err + } + lock, err := os.OpenFile(registry.Path+".lock", os.O_CREATE|os.O_RDWR|syscall.O_NOFOLLOW|syscall.O_NONBLOCK, 0600) + if err != nil { + return err + } + defer lock.Close() + if info, err := lock.Stat(); err != nil || !info.Mode().IsRegular() { + return errors.New("tentacle registry lock must be a regular file") + } + if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil { + return errors.New("tentacle registry is being edited") + } + defer syscall.Flock(int(lock.Fd()), syscall.LOCK_UN) + current, err := read_registry(registry.Path) + if err != nil { + return err + } + if !bytes.Equal(current, registry.original) || (current == nil) != (registry.original == nil) { + return errors.New("tentacle registry changed outside the reader; restart before editing") + } + temporary, err := os.CreateTemp(directory, ".tentacles-*.toml") + if err != nil { + return err + } + defer os.Remove(temporary.Name()) + defer temporary.Close() + if _, err := temporary.Write(data); err != nil { + return err + } + if err := temporary.Sync(); err != nil { + return err + } + if err := temporary.Close(); err != nil { + return err + } + dir, err := os.Open(directory) + if err != nil { + return err + } + defer dir.Close() + if err := os.Rename(temporary.Name(), registry.Path); err != nil { + return err + } + registry.original = data + registry.repositories = CloneRepositories(repositories) + if err := dir.Sync(); err != nil { + return fmt.Errorf("%w: %w", ErrRegistrySync, err) + } + return nil +} diff --git a/internal/tentacle/registry_test.go b/internal/tentacle/registry_test.go new file mode 100644 index 0000000..0822eb7 --- /dev/null +++ b/internal/tentacle/registry_test.go @@ -0,0 +1,105 @@ +package tentacle + +import ( + "bytes" + "os" + "path/filepath" + "reflect" + "strings" + "testing" +) + +func TestRegistryEmptyRoundTripAndConflict(t *testing.T) { + path := filepath.Join(t.TempDir(), "settings", "tentacles.toml") + registry := &Registry{Path: path} + entries, err := registry.Load() + if err != nil || len(entries) != 0 { + t.Fatalf("fresh registry: %v %v", entries, err) + } + if _, err := os.Stat(filepath.Dir(path)); !os.IsNotExist(err) { + t.Fatal("reading defaults created files") + } + entries = []Entry{{ID: "example", Program: []string{"/usr/bin/example", "literal $(data)"}, Enabled: true, Presentation: true}} + if err := registry.Save(entries); err != nil { + t.Fatal(err) + } + info, _ := os.Stat(path) + if info.Mode().Perm() != 0600 { + t.Fatalf("permissions: %v", info.Mode()) + } + other := &Registry{Path: path} + loaded, err := other.Load() + if err != nil || !reflect.DeepEqual(entries, loaded) { + t.Fatalf("round trip: %v %v", loaded, err) + } + entries[0].Enabled = false + if err := registry.Save(entries); err != nil { + t.Fatal(err) + } + before, _ := os.ReadFile(path) + if err := other.Save(nil); err == nil { + t.Fatal("stale writer replaced current registry") + } + after, _ := os.ReadFile(path) + if !bytes.Equal(before, after) { + t.Fatal("failed save changed file") + } + if err := registry.Save(nil); err != nil { + t.Fatal(err) + } + loaded, err = other.Load() + if err != nil || len(loaded) != 0 { + t.Fatalf("remove all: %v %v", loaded, err) + } +} + +func TestRegistryRejectsInvalidWithoutReplacement(t *testing.T) { + path := filepath.Join(t.TempDir(), "tentacles.toml") + for _, data := range []string{ + "", "version = 2\n", "version = 1\nunknown = true\n", + "version = 1\n[[tentacles]]\nid = 'relative'\nprogram = ['relative']\n", + "version = 1\n" + strings.Repeat("[[tentacles]]\nid = 'duplicate'\nprogram = ['/usr/bin/example']\n", 2), + strings.Repeat("x", MaxFrameBytes+1), + } { + if err := os.WriteFile(path, []byte(data), 0600); err != nil { + t.Fatal(err) + } + registry := &Registry{Path: path} + if _, err := registry.Load(); err == nil { + t.Fatalf("accepted invalid registry: %.80s", data) + } + if err := registry.Save(nil); err == nil { + t.Fatal("saved after failed load") + } + after, _ := os.ReadFile(path) + if string(after) != data { + t.Fatal("invalid registry overwritten") + } + } + link := path + ".link" + if err := os.Symlink(path, link); err != nil { + t.Fatal(err) + } + if _, err := (&Registry{Path: link}).Load(); err == nil { + t.Fatal("accepted symlink") + } +} + +func TestRegistryInteractionGrantRoundTrip(t *testing.T) { + registry := &Registry{Path: filepath.Join(t.TempDir(), "tentacles.toml")} + if _, err := registry.Load(); err != nil { + t.Fatal(err) + } + entry := Entry{ID: "wormhole", Program: []string{"/tmp/wormhole-tentacle"}, Enabled: true, Presentation: true, Interaction: true} + if err := registry.Save([]Entry{entry}); err != nil { + t.Fatal(err) + } + loaded, err := registry.Load() + if err != nil || len(loaded) != 1 || !loaded[0].Spec().Interaction { + t.Fatal(loaded, err) + } + entry.Presentation = false + if err := registry.Save([]Entry{entry}); err == nil { + t.Fatal("interaction without presentation accepted") + } +} diff --git a/internal/tentacle/repository.go b/internal/tentacle/repository.go new file mode 100644 index 0000000..009e090 --- /dev/null +++ b/internal/tentacle/repository.go @@ -0,0 +1,285 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "bytes" + "context" + "errors" + "fmt" + "net/url" + "os" + "os/exec" + "path" + "slices" + "strings" + "syscall" + "time" + "unicode" + + "github.com/pelletier/go-toml/v2" +) + +// Repository is a validated discovery snapshot, never an installed package. +// Catalog refresh does not run code or change installed versions or grants. +type Repository struct { + URL string `toml:"url"` + ID string `toml:"id"` + Name string `toml:"name"` + Description string `toml:"description"` + Revision string `toml:"revision"` + Tentacles []Manifest `toml:"tentacles"` +} + +// Manifest is cached discovery metadata. Releases describe immutable packages; +// launch permissions are read and validated again from the selected package. +type Manifest struct { + FormatVersion int `toml:"format-version"` + ID string `toml:"id"` + Name string `toml:"name"` + Description string `toml:"description"` + Version string `toml:"version"` + Releases []Release `toml:"releases,omitempty"` + Capabilities []string `toml:"capabilities,omitempty"` +} + +type Release struct { + Platform string `toml:"platform"` + Architecture string `toml:"architecture"` + URL string `toml:"url"` + SHA256 string `toml:"sha256"` +} + +func RepositoryURL(text string) (string, error) { + value, err := url.Parse(strings.TrimSpace(text)) + if err != nil || value.Scheme != "https" || value.Hostname() == "" || value.User != nil || value.ForceQuery || value.RawQuery != "" || strings.Contains(text, "#") || value.Opaque != "" { + return "", errors.New("Use an HTTPS Git repository URL without credentials, a query, or a fragment.") + } + // Preserve the server's repository path: ordinary Git hosting may require + // the .git suffix even when the display label omits it. + value.Path = strings.TrimRight(value.Path, "/") + if value.Path == "" || value.Path == "/" || path.Clean(value.Path) != value.Path || strings.ContainsAny(value.Path, "\\\x00\r\n") || len(text) > 2048 { + return "", errors.New("Use a URL with a valid Git repository path.") + } + value.Host = strings.ToLower(value.Host) + value.RawPath = "" + return value.String(), nil +} + +func RepositoryLabel(origin string) string { + value, err := url.Parse(origin) + if err != nil { + return origin + } + return strings.TrimSuffix(strings.Trim(value.Path, "/"), ".git") +} + +func CloneRepositories(repositories []Repository) []Repository { + result := slices.Clone(repositories) + for index := range result { + result[index].Tentacles = slices.Clone(result[index].Tentacles) + for item := range result[index].Tentacles { + result[index].Tentacles[item].Releases = slices.Clone(result[index].Tentacles[item].Releases) + result[index].Tentacles[item].Capabilities = slices.Clone(result[index].Tentacles[item].Capabilities) + } + } + return result +} + +func metadata_text(value string, required bool) bool { + return (!required || strings.TrimSpace(value) != "") && len(value) <= 4096 && !strings.ContainsFunc(value, func(character rune) bool { return unicode.IsControl(character) }) +} + +func metadata_id(value string) bool { + if len(value) == 0 || len(value) > 128 || value[0] < 'a' || value[0] > 'z' { + return false + } + for _, character := range value { + if !(character >= 'a' && character <= 'z' || character >= '0' && character <= '9' || character == '-' || character == '.') { + return false + } + } + return true +} + +func ValidateRepositories(repositories []Repository) error { + if len(repositories) > 32 { + return ErrLimit + } + seen := make(map[string]bool) + count := 0 + for _, repository := range repositories { + origin, err := RepositoryURL(repository.URL) + if err != nil || origin != repository.URL || seen[origin] || !metadata_id(repository.ID) || !metadata_text(repository.Name, true) || !metadata_text(repository.Description, false) || len(repository.Revision) != 40 && len(repository.Revision) != 64 { + return errors.New("invalid or duplicate tentacle repository metadata") + } + for _, character := range repository.Revision { + if !(character >= '0' && character <= '9' || character >= 'a' && character <= 'f') { + return errors.New("invalid repository revision") + } + } + seen[origin] = true + ids := make(map[string]bool) + for _, manifest := range repository.Tentacles { + count++ + if count > 256 { + return ErrLimit + } + if manifest.FormatVersion != 1 || !metadata_id(manifest.ID) || ids[manifest.ID] || !metadata_text(manifest.Name, true) || !metadata_text(manifest.Description, false) || !metadata_text(manifest.Version, true) { + return errors.New("invalid or duplicate tentacle manifest metadata") + } + ids[manifest.ID] = true + if len(manifest.Capabilities) > 16 { + return ErrLimit + } + capabilities := make(map[string]bool) + for _, capability := range manifest.Capabilities { + if !metadata_id(capability) || capabilities[capability] { + return errors.New("invalid or duplicate tentacle capability metadata") + } + capabilities[capability] = true + } + if err := validate_releases(manifest.Releases); err != nil { + return err + } + } + } + return nil +} + +// read_repository uses regular blobs from one immutable revision. Tests supply +// this reader directly; the public fetch path only permits HTTPS origins. +func read_repository(origin, revision string, read func(string) ([]byte, error)) (Repository, error) { + repository := Repository{URL: origin, Revision: revision} + var metadata struct { + FormatVersion int `toml:"format-version"` + ID string `toml:"id"` + Name string `toml:"name"` + Description string `toml:"description"` + } + var catalog struct { + FormatVersion int `toml:"format-version"` + Tentacles []struct { + ID string `toml:"id"` + Manifest string `toml:"manifest"` + Releases []Release `toml:"releases"` + } `toml:"tentacles"` + } + total := 0 + decode := func(filename string, value any) error { + data, err := read(filename) + if err != nil { + return fmt.Errorf("Cannot read %s from the repository.", filename) + } + total += len(data) + if total > MaxFrameBytes { + return ErrLimit + } + if err := toml.Unmarshal(data, value); err != nil { + return fmt.Errorf("Invalid TOML in %s.", filename) + } + return nil + } + if err := decode("repository.toml", &metadata); err != nil { + return repository, err + } + if metadata.FormatVersion != 1 { + return repository, errors.New("Unsupported repository.toml format-version; expected 1.") + } + repository.ID, repository.Name, repository.Description = metadata.ID, metadata.Name, metadata.Description + if err := decode("catalog.toml", &catalog); err != nil { + return repository, err + } + if catalog.FormatVersion != 1 { + return repository, errors.New("Unsupported catalog.toml format-version; expected 1.") + } + if len(catalog.Tentacles) > 256 { + return repository, ErrLimit + } + for _, item := range catalog.Tentacles { + parts := strings.Split(item.Manifest, "/") + if len(parts) != 2 || parts[0] == "" || parts[0] == "." || parts[0] == ".." || parts[1] != "tentacle.toml" || strings.ContainsAny(item.Manifest, "\\\x00\r\n:") || !metadata_text(item.Manifest, true) { + return repository, errors.New("Catalog manifests must be inside direct top-level tentacle folders.") + } + var manifest Manifest + if err := decode(item.Manifest, &manifest); err != nil { + return repository, err + } + if manifest.ID != item.ID { + return repository, errors.New("Catalog and manifest tentacle IDs do not match.") + } + // Release locations belong to the catalog, not to a package manifest. + manifest.Releases = slices.Clone(item.Releases) + repository.Tentacles = append(repository.Tentacles, manifest) + } + return repository, ValidateRepositories([]Repository{repository}) +} + +type boundedGitOutput struct{ bytes.Buffer } + +func (output *boundedGitOutput) Write(data []byte) (int, error) { + if output.Len()+len(data) > MaxFrameBytes { + return 0, ErrLimit + } + return output.Buffer.Write(data) +} + +func repository_git(ctx context.Context, directory string, arguments ...string) ([]byte, error) { + command := exec.CommandContext(ctx, "git", append([]string{"--literal-pathspecs", "-c", "core.hooksPath=/dev/null", "-c", "protocol.allow=never", "-c", "protocol.https.allow=always", "-c", "http.followRedirects=false", "-c", "credential.helper=", "-c", "gc.auto=0"}, arguments...)...) + command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} + command.Cancel = func() error { return syscall.Kill(-command.Process.Pid, syscall.SIGKILL) } + command.WaitDelay = time.Second + command.Dir = directory + for _, variable := range os.Environ() { + if !strings.HasPrefix(variable, "GIT_") && !strings.HasPrefix(variable, "HOME=") && !strings.HasPrefix(variable, "XDG_CONFIG_HOME=") { + command.Env = append(command.Env, variable) + } + } + command.Env = append(command.Env, "GIT_CONFIG_NOSYSTEM=1", "GIT_CONFIG_GLOBAL=/dev/null", "GIT_TERMINAL_PROMPT=0", "GIT_ASKPASS=/bin/false", "HOME="+directory, "XDG_CONFIG_HOME="+directory) + var output boundedGitOutput + command.Stdout = &output + // No repository-controlled diagnostic text enters Preferences or the reader. + if err := command.Run(); err != nil { + if ctx.Err() != nil { + return nil, ctx.Err() + } + return nil, errors.New("Git could not read this repository; check the URL and connection.") + } + return output.Bytes(), nil +} + +func FetchRepository(ctx context.Context, origin string) (Repository, error) { + origin, err := RepositoryURL(origin) + if err != nil { + return Repository{}, err + } + directory, err := os.MkdirTemp("", "cthulhu-repository-") + if err != nil { + return Repository{}, err + } + defer os.RemoveAll(directory) + if _, err := repository_git(ctx, directory, "init", "--bare", "--template="); err != nil { + return Repository{}, err + } + if _, err := repository_git(ctx, directory, "fetch", "--depth=1", "--no-tags", "--no-recurse-submodules", "--", origin, "HEAD"); err != nil { + return Repository{}, err + } + return read_git_repository(ctx, directory, origin) +} + +func read_git_repository(ctx context.Context, directory, origin string) (Repository, error) { + revision, err := repository_git(ctx, directory, "rev-parse", "--verify", "FETCH_HEAD^{commit}") + if err != nil { + return Repository{}, err + } + commit := strings.TrimSpace(string(revision)) + return read_repository(origin, commit, func(filename string) ([]byte, error) { + // Reject symlinks, trees and submodules before reading any metadata. + mode, err := repository_git(ctx, directory, "ls-tree", commit, "--", filename) + if err != nil || !(bytes.HasPrefix(mode, []byte("100644 blob ")) || bytes.HasPrefix(mode, []byte("100755 blob "))) { + return nil, errors.New("metadata must be a regular blob") + } + return repository_git(ctx, directory, "show", commit+":"+filename) + }) +} diff --git a/internal/tentacle/repository_test.go b/internal/tentacle/repository_test.go new file mode 100644 index 0000000..764a747 --- /dev/null +++ b/internal/tentacle/repository_test.go @@ -0,0 +1,177 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package tentacle + +import ( + "context" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func repository_files() map[string]string { + return map[string]string{ + "repository.toml": "format-version = 1\nid = 'example.tentacles'\nname = 'Example tentacles'\ndescription = 'Test catalog'\nmaintainer = 'Maintainer'\n", + "catalog.toml": "format-version = 1\n[[tentacles]]\nid = 'echo'\nmanifest = 'echo/tentacle.toml'\n", + "echo/tentacle.toml": "format-version = 1\nid = 'echo'\nname = 'Echo'\nversion = '0.1'\ndescription = 'An example'\ncapabilities = ['presentation']\n", + } +} +func read_repository_fixture(files map[string]string) (Repository, error) { + return read_repository("https://example.org/team/tentacles", strings.Repeat("a", 40), func(filename string) ([]byte, error) { + data, found := files[filename] + if !found { + return nil, os.ErrNotExist + } + return []byte(data), nil + }) +} +func TestRepositoryMetadataDiscoveryValidation(t *testing.T) { + repository, err := read_repository_fixture(repository_files()) + if err != nil || repository.ID != "example.tentacles" || len(repository.Tentacles) != 1 || repository.Tentacles[0].Name != "Echo" { + t.Fatalf("discovery: %+v %v", repository, err) + } + for _, problem := range []string{"missing root", "version", "missing manifest", "traversal", "nested", "mismatch", "duplicate", "oversized", "invalid id"} { + t.Run(problem, func(t *testing.T) { + files := repository_files() + switch problem { + case "missing root": + delete(files, "repository.toml") + case "version": + files["repository.toml"] = strings.Replace(files["repository.toml"], "format-version = 1", "format-version = 2", 1) + case "missing manifest": + delete(files, "echo/tentacle.toml") + case "traversal": + files["catalog.toml"] = strings.Replace(files["catalog.toml"], "echo/tentacle.toml", "../tentacle.toml", 1) + case "nested": + files["catalog.toml"] = strings.Replace(files["catalog.toml"], "echo/tentacle.toml", "a/b/tentacle.toml", 1) + case "mismatch": + files["echo/tentacle.toml"] = strings.Replace(files["echo/tentacle.toml"], "id = 'echo'", "id = 'different'", 1) + case "duplicate": + files["catalog.toml"] += "[[tentacles]]\nid='echo'\nmanifest='echo/tentacle.toml'\n" + case "oversized": + files["repository.toml"] += "#" + strings.Repeat("x", MaxFrameBytes) + case "invalid id": + files["echo/tentacle.toml"] = strings.Replace(files["echo/tentacle.toml"], "id = 'echo'", "id = 'Echo!'", 1) + } + if _, err := read_repository_fixture(files); err == nil { + t.Fatal("accepted invalid metadata") + } + }) + } +} +func TestRepositoryURLAndLabel(t *testing.T) { + origin, err := RepositoryURL(" https://EXAMPLE.org/team/tentacles.git/ ") + if err != nil || origin != "https://example.org/team/tentacles.git" || RepositoryLabel(origin) != "team/tentacles" { + t.Fatalf("URL %q %v", origin, err) + } + for _, origin := range []string{"file:///tmp/source", "http://example.org/team/repo", "ssh://example.org/team/repo", "https://Username@example.org/team/repo", "https://example.org/", "https://example.org/team/../repo", "https://example.org/team/repo?ref=main", "https://example.org/team/repo#ref", "https://example.org/team/%00repo"} { + if _, err := RepositoryURL(origin); err == nil { + t.Fatalf("accepted %q", origin) + } + } +} +func TestRepositorySnapshotPersistenceAndIsolation(t *testing.T) { + repository, err := read_repository_fixture(repository_files()) + if err != nil { + t.Fatal(err) + } + registry := &Registry{Path: filepath.Join(t.TempDir(), "tentacles.toml")} + entries, err := registry.Load() + if err != nil { + t.Fatal(err) + } + if err := registry.SaveState(entries, []Repository{repository}); err != nil { + t.Fatal(err) + } + reopened := &Registry{Path: registry.Path} + if _, err := reopened.Load(); err != nil { + t.Fatal(err) + } + cached := reopened.Repositories() + if len(cached) != 1 || cached[0].Tentacles[0].Name != "Echo" { + t.Fatal(cached) + } + cached[0].Tentacles[0].Name = "mutated" + if reopened.Repositories()[0].Tentacles[0].Name != "Echo" { + t.Fatal("shared snapshot storage") + } + if err := reopened.Save(nil); err != nil { + t.Fatal(err) + } + if _, err := registry.Load(); err != nil || len(registry.Repositories()) != 1 { + t.Fatalf("entry save dropped catalog: %v", err) + } +} +func TestRepositoryGitIgnoresInheritedConfigAndReadsBlobs(t *testing.T) { + directory := t.TempDir() + // A poisoned inherited config must not affect even Git initialization. + t.Setenv("GIT_CONFIG_COUNT", "1") + t.Setenv("GIT_CONFIG_KEY_0", "core.bare") + t.Setenv("GIT_CONFIG_VALUE_0", "invalid") + ctx := context.Background() + if _, err := repository_git(ctx, directory, "init", "--bare", "--template="); err != nil { + t.Fatal(err) + } + source := t.TempDir() + for name, data := range repository_files() { + filename := filepath.Join(source, name) + if err := os.MkdirAll(filepath.Dir(filename), 0700); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filename, []byte(data), 0600); err != nil { + t.Fatal(err) + } + } + // Populate a local test snapshot without enabling file transport in the + // production fetch path or contacting a real repository. + run := func(args ...string) string { + command := exec.Command("git", args...) + command.Dir = source + command.Env = []string{"PATH=" + os.Getenv("PATH"), "HOME=" + source, "GIT_CONFIG_NOSYSTEM=1", "GIT_CONFIG_GLOBAL=/dev/null", "GIT_AUTHOR_NAME=Maintainer", "GIT_AUTHOR_EMAIL=maintainer@example.invalid", "GIT_COMMITTER_NAME=Maintainer", "GIT_COMMITTER_EMAIL=maintainer@example.invalid"} + output, err := command.CombinedOutput() + if err != nil { + t.Fatalf("git: %s %v", output, err) + } + return strings.TrimSpace(string(output)) + } + run("init", "--template=") + run("add", ".") + run("commit", "-m", "Fixture") + setHead := func() { + t.Helper() + if err := os.WriteFile(filepath.Join(source, ".git", "FETCH_HEAD"), []byte(run("rev-parse", "HEAD")+"\n"), 0600); err != nil { + t.Fatal(err) + } + } + setHead() + repository, err := read_git_repository(ctx, source, "https://example.org/team/tentacles") + if err != nil || len(repository.Tentacles) != 1 { + t.Fatalf("Git discovery: %+v %v", repository, err) + } + revision := run("rev-parse", "HEAD") + data, err := repository_git(ctx, source, "show", revision+":repository.toml") + if err != nil || !strings.Contains(string(data), "example.tentacles") { + t.Fatalf("read blob: %s %v", data, err) + } + // A regular-looking root symlink must be rejected rather than interpreted + // as metadata, including when it references an otherwise valid file. + if err := os.Remove(filepath.Join(source, "repository.toml")); err != nil { + t.Fatal(err) + } + if err := os.Symlink("echo/tentacle.toml", filepath.Join(source, "repository.toml")); err != nil { + t.Fatal(err) + } + run("add", ".") + run("commit", "-m", "Symlink fixture") + setHead() + if _, err := read_git_repository(ctx, source, "https://example.org/team/tentacles"); err == nil { + t.Fatal("accepted symlink metadata") + } + cancelled, cancel := context.WithCancel(ctx) + cancel() + if _, err := repository_git(cancelled, source, "status"); err == nil { + t.Fatal("ignored cancellation") + } +} diff --git a/internal/tentacle/sdk_test.go b/internal/tentacle/sdk_test.go new file mode 100644 index 0000000..05ea778 --- /dev/null +++ b/internal/tentacle/sdk_test.go @@ -0,0 +1,252 @@ +package tentacle + +import ( + "context" + "encoding/json" + "errors" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "sync" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/tentaclewire" + sdk "git.stormux.org/storm/cthulhu/sdk/go/tentacle" +) + +func TestSDKChild(t *testing.T) { + if len(os.Args) < 3 || os.Args[len(os.Args)-2] != "sdk-child" { + return + } + cancelFile := os.Args[len(os.Args)-1] + started := make(chan struct{}) + var once sync.Once + commands := []sdk.Command{ + {ID: "echo", Title: "Echo", Handle: func(ctx context.Context, args json.RawMessage) (any, error) { return args, nil }}, + {ID: "fail", Title: "Fail", Handle: func(ctx context.Context, args json.RawMessage) (any, error) { panic("private handler details") }}, + {ID: "large", Title: "Large", Handle: func(ctx context.Context, args json.RawMessage) (any, error) { + return strings.Repeat("x", MaxFrameBytes), nil + }}, + {ID: "wait", Title: "Wait", Handle: func(ctx context.Context, args json.RawMessage) (any, error) { + once.Do(func() { close(started) }) + <-ctx.Done() + return nil, os.WriteFile(cancelFile, []byte("cancelled"), 0600) + }}, + {ID: "started", Title: "Started", Handle: func(ctx context.Context, args json.RawMessage) (any, error) { + select { + case <-started: + return true, nil + case <-ctx.Done(): + return nil, ctx.Err() + } + }}, + } + if filepath.Base(cancelFile) == "presentation" { + commands = append(commands, sdk.Command{ID: "present", Title: "Present", Presentation: true, + Handle: func(ctx context.Context, args json.RawMessage) (any, error) { + return sdk.Presentation{Speech: "Hello, é猫😀é", Braille: "Display é猫😀é", Uninterruptible: true}, nil + }}) + } + if sdk.Serve(os.Stdin, os.Stdout, commands) != nil { + os.Exit(1) + } + os.Exit(0) +} + +func sdk_program(t *testing.T, language, cancelFile string) []string { + t.Helper() + if language == "go" { + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + return []string{executable, "-test.run=^TestSDKChild$", "--", "sdk-child", cancelFile} + } + python, err := exec.LookPath("python3") + if err != nil { + t.Skip("Python 3 not installed") + } + peer, err := filepath.Abs("testdata/sdk_peer.py") + if err != nil { + t.Fatal(err) + } + return []string{python, "-B", peer, cancelFile} +} + +func TestSDKHostConformance(t *testing.T) { + for _, language := range []string{"go", "python"} { + for _, ending := range []string{"disable", "cancel"} { + t.Run(language+"/"+ending, func(t *testing.T) { + cancelFile := filepath.Join(t.TempDir(), "cancelled") + limits := DefaultLimits() + limits.RequestTimeout = 5 * time.Second + manager := test_manager(t, limits, nil) + session, err := manager.Start(context.Background(), Spec{ID: "sdk", Program: sdk_program(t, language, cancelFile)}) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Ready()) + if state, err := session.Status(); state != Ready || err != nil { + t.Fatalf("%s: %v", state, err) + } + if _, err := session.Invoke(context.Background(), "echo", nil); !errors.Is(err, ErrUnavailable) { + t.Fatal("preactivation dispatch", err) + } + if err := session.Activate(); err != nil { + t.Fatal(err) + } + invoke := func(command string, args json.RawMessage) Result { + t.Helper() + pending, err := session.Invoke(context.Background(), command, args) + if err != nil { + t.Fatal(err) + } + return wait_result(t, pending) + } + for _, raw := range []string{`{"text":"é猫😀é","nested":[true,null,42]}`, `null`, `[1,"two"]`} { + result := invoke("echo", json.RawMessage(raw)) + if result.Err != nil || string(result.Value) != raw || result.Session != session.Identity() { + t.Fatalf("round trip: %+v", result) + } + } + // Fill the default host window repeatedly. Responses can arrive + // out of order; each caller must receive its own arguments. + for round := 0; round < 20; round++ { + replies := make([]<-chan Result, 8) + for index := range replies { + args, _ := json.Marshal(map[string]int{"index": index}) + replies[index], err = session.Invoke(context.Background(), "echo", args) + if err != nil { + t.Fatal(err) + } + } + for index, reply := range replies { + result := wait_result(t, reply) + var value struct { + Index int `json:"index"` + } + if result.Err != nil || json.Unmarshal(result.Value, &value) != nil || value.Index != index { + t.Fatalf("correlation: %+v", result) + } + } + } + for _, command := range []string{"fail", "large"} { + result := invoke(command, nil) + var rpcError *RPCError + if !errors.As(result.Err, &rpcError) || rpcError.Code != -32603 || strings.Contains(rpcError.Message, "private") { + t.Fatalf("unsafe error: %+v", result) + } + } + if result := invoke("echo", nil); result.Err != nil { + t.Fatal("session failed after handler error", result.Err) + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + pending, err := session.Invoke(ctx, "wait", nil) + if err != nil { + t.Fatal(err) + } + if result := invoke("started", nil); result.Err != nil || string(result.Value) != "true" { + t.Fatal("concurrent handler failed", result) + } + if ending == "disable" { + session.Disable() + } else { + cancel() + } + if result := wait_result(t, pending); result.Err == nil { + t.Fatal("late success", result) + } + wait_signal(t, session.Done()) + if ending == "disable" { + if data, err := os.ReadFile(cancelFile); err != nil || string(data) != "cancelled" { + t.Fatalf("SDK did not cancel handler: %q, %v", data, err) + } + } + }) + } + } +} + +func TestSDKPresentationGrantAndRevocation(t *testing.T) { + for _, language := range []string{"go", "python"} { + for _, grant := range []bool{false, true} { + t.Run(language+"/grant="+strconv.FormatBool(grant), func(t *testing.T) { + manager := test_manager(t, DefaultLimits(), nil) + program := sdk_program(t, language, filepath.Join(t.TempDir(), "presentation")) + session, err := manager.Start(context.Background(), Spec{ID: "sdk", Program: program, Presentation: grant}) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Ready()) + state, err := session.Status() + if !grant { + if state != Failed || err == nil { + t.Fatal("ungranted presentation registration succeeded") + } + return + } + if state != Ready || err != nil { + t.Fatalf("%s: %v", state, err) + } + if err := session.Activate(); err != nil { + t.Fatal(err) + } + pending, err := session.Invoke(context.Background(), "present", nil) + if err != nil { + t.Fatal(err) + } + result := wait_result(t, pending) + value, err := tentaclewire.DecodePresentation(result.Value) + if result.Err != nil || err != nil || value.Speech != "Hello, é猫😀é" || value.Braille != "Display é猫😀é" || !value.Uninterruptible { + t.Fatalf("presentation: %+v, %v", result, err) + } + if session.OutputContext().Err() != nil { + t.Fatal("reply completion revoked output") + } + session.Disable() + if session.OutputContext().Err() == nil { + t.Fatal("disable left buffered output live") + } + }) + } + } +} + +func TestSDKRejectsInvalidHostMessages(t *testing.T) { + initialize := `{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"protocol":{"major":1,"minor":0},"session":"test","apis":["commands"],"capabilities":["commands"]}}` + "\n" + activate := `{"jsonrpc":"2.0","method":"initialized","params":{"session":"test"}}` + "\n" + invoke := `{"jsonrpc":"2.0","id":"2","method":"command.invoke","params":{"command":"echo","arguments":{}}}` + "\n" + cases := map[string]string{ + "before activation": initialize + invoke, + "wrong session": initialize + strings.Replace(activate, "test", "other", 1), + "null version": strings.Replace(initialize, `"minor":0`, `"minor":null`, 1), + "null ID": `{"jsonrpc":"2.0","id":null,"method":"shutdown"}` + "\n", + "wrong version": strings.Replace(initialize, `"major":1`, `"major":2`, 1), + "duplicate registration": initialize + initialize, + "duplicate request": initialize + activate + invoke + invoke, + "duplicate key": `{"jsonrpc":"2.0","jsonrpc":"2.0","method":"shutdown"}` + "\n", + "oversize": strings.Repeat("x", MaxFrameBytes+1) + "\n", + "unterminated": strings.TrimSuffix(initialize, "\n"), + } + for _, language := range []string{"go", "python"} { + for name, input := range cases { + t.Run(language+"/"+name, func(t *testing.T) { + program := sdk_program(t, language, filepath.Join(t.TempDir(), "cancelled")) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + command := exec.CommandContext(ctx, program[0], program[1:]...) + command.Stdin = strings.NewReader(input) + if err := command.Run(); err == nil { + t.Fatal("invalid input accepted") + } + if ctx.Err() != nil { + t.Fatal("SDK hung on invalid input") + } + }) + } + } +} diff --git a/internal/tentacle/session.go b/internal/tentacle/session.go new file mode 100644 index 0000000..87ab374 --- /dev/null +++ b/internal/tentacle/session.go @@ -0,0 +1,314 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "context" + "encoding/json" + "errors" + "strconv" + "sync" + "time" + + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type State string + +const ( + Starting State = "starting" + Ready State = "ready" + Active State = "active" + Stopping State = "stopping" + Stopped State = "stopped" + Failed State = "failed" +) + +// Result is never delivered to an output backend by this package. The future +// reader output owner must revalidate context, lock, mode and interruption state +// when consuming it, including a result already buffered before cancellation. +type Result struct { + Session string + ID string + Value json.RawMessage + Err error +} + +type pendingCall struct { + ctx context.Context + cancel context.CancelFunc + stopWatch func() bool + result chan Result +} + +type outgoing struct { + id string // Empty for lifecycle and cancellation notifications. + frame []byte +} + +type Session struct { + outputContext context.Context + revokeOutput context.CancelFunc + + mutex sync.Mutex + manager *Manager + spec Spec + identity string + ctx context.Context + cancel context.CancelFunc + state State + failure error + extensions tentaclewire.Extensions + commands []Command + bindings []BindingStatus + sequence uint64 + pending map[string]*pendingCall + outbound chan outgoing + ready chan struct{} + done chan struct{} + stop chan struct{} + revoked chan struct{} + callbacks sync.WaitGroup +} + +func (session *Session) Ready() <-chan struct{} { return session.ready } + +// Revoked closes as soon as dispatch is retired, before descendant cleanup. +func (session *Session) Revoked() <-chan struct{} { return session.revoked } +func (session *Session) Done() <-chan struct{} { return session.done } +func (session *Session) Identity() string { return session.identity } +func (session *Session) TentacleID() string { return session.spec.ID } + +// OutputContext expires synchronously on revocation, including after a reply +// has left the host's pending-call map. It never authorizes output by itself. +func (session *Session) OutputContext() context.Context { return session.outputContext } + +func (session *Session) Status() (State, error) { + session.mutex.Lock() + defer session.mutex.Unlock() + return session.state, session.failure +} + +// Extensions returns a private copy of the staged declarative registrations. +func (session *Session) Extensions() tentaclewire.Extensions { + session.mutex.Lock() + defer session.mutex.Unlock() + data, _ := json.Marshal(session.extensions) + var value tentaclewire.Extensions + _ = json.Unmarshal(data, &value) + return value +} + +// Commands returns a copy of staged or active registrations. A caller may +// inspect Ready registrations but must not dispatch them before Activate. +func (session *Session) Commands() []Command { + session.mutex.Lock() + defer session.mutex.Unlock() + return clone_commands(session.commands) +} + +// Activate is the host publication barrier. The reader stages acknowledged +// native bindings before calling it; there are no external service exports. +func (session *Session) Activate() error { + session.manager.mutex.Lock() + defer session.manager.mutex.Unlock() + occupied := session.manager.occupied_bindings() + session.mutex.Lock() + defer session.mutex.Unlock() + if session.state != Ready || session.ctx.Err() != nil { + return ErrUnavailable + } + if !session.notify_locked("initialized", struct { + Session string `json:"session"` + }{session.identity}) { + return ErrBusy + } + session.bindings = resolve_bindings(session.spec.ID, session.commands, occupied) + session.state = Active + return nil +} + +func (session *Session) Invoke(ctx context.Context, command string, arguments json.RawMessage) (<-chan Result, error) { + if ctx == nil { + return nil, errors.New("nil command context") + } + if err := ctx.Err(); err != nil { + return nil, err + } + if len(arguments) > MaxReaderArgumentBytes { + return nil, ErrLimit + } + if len(arguments) == 0 { + arguments = json.RawMessage(`{}`) + } + if err := validate_json(arguments); err != nil { + return nil, err + } + session.mutex.Lock() + defer session.mutex.Unlock() + if session.state != Active || session.ctx.Err() != nil { + return nil, ErrUnavailable + } + known := false + limit := MaxArgumentBytes + for _, registered := range session.commands { + if registered.ID == command { + known = true + if registered.Reader { + limit = MaxReaderArgumentBytes + } + } + } + if len(arguments) > limit { + return nil, ErrLimit + } + if !known { + return nil, ErrUnavailable + } + return session.request_locked(ctx, "command.invoke", struct { + Command string `json:"command"` + Arguments json.RawMessage `json:"arguments"` + }{command, arguments}, session.manager.limits.RequestTimeout) +} + +func (session *Session) request_locked(parent context.Context, method string, params any, timeout time.Duration) (<-chan Result, error) { + if len(session.pending) >= session.manager.limits.PendingPerProcess { + return nil, ErrBusy + } + select { + case session.manager.pending <- struct{}{}: + default: + return nil, ErrBusy + } + session.sequence++ + id := strconv.FormatUint(session.sequence, 10) + frame, err := encode_request(id, method, params) + if err != nil { + <-session.manager.pending + return nil, err + } + ctx, cancel := context.WithTimeout(parent, timeout) + call := &pendingCall{ctx: ctx, cancel: cancel, result: make(chan Result, 1)} + session.pending[id] = call + session.callbacks.Add(1) + call.stopWatch = context.AfterFunc(ctx, func() { + defer session.callbacks.Done() + session.cancel_call(id) + }) + select { + case session.outbound <- outgoing{id: id, frame: frame}: + return call.result, nil + default: + session.finish_locked(id, nil, ErrBusy) + return nil, ErrBusy + } +} + +func (session *Session) notify_locked(method string, params any) bool { + frame, err := encode_request("", method, params) + if err != nil { + return false + } + select { + case session.outbound <- outgoing{frame: frame}: + return true + default: + return false + } +} + +func (session *Session) finish_locked(id string, value json.RawMessage, err error) { + call := session.pending[id] + if call == nil { + return + } + delete(session.pending, id) + if call.stopWatch() { + session.callbacks.Done() + } + if contextError := call.ctx.Err(); contextError != nil && err == nil { + err = contextError + value = nil + } + call.cancel() + <-session.manager.pending + call.result <- Result{Session: session.identity, ID: id, Value: value, Err: err} + close(call.result) +} + +func (session *Session) cancel_call(id string) { + session.mutex.Lock() + defer session.mutex.Unlock() + call := session.pending[id] + if call == nil { + return + } + err := call.ctx.Err() + session.finish_locked(id, nil, err) + // Without a cancellation acknowledgment contract, a timed-out child could + // accumulate unlimited still-running work. Retire the whole session instead. + // Explicit cancellation follows the same conservative rule in this slice. + session.fail_locked(err) +} + +func (session *Session) accept_reply(reply response) { + session.mutex.Lock() + defer session.mutex.Unlock() + if session.state == Stopping || session.state == Stopped || session.state == Failed { + return + } + if session.pending[reply.ID] == nil { + // Unknown/duplicate responses are not allowed to keep a flood alive. + session.fail_locked(ErrProtocol) + return + } + var err error + if reply.Error != nil { + err = reply.Error + } + session.finish_locked(reply.ID, reply.Result, err) +} + +func (session *Session) fail_locked(err error) { + if session.state == Stopping || session.state == Stopped || session.state == Failed { + return + } + session.state, session.failure = Failed, err + close(session.revoked) + session.revokeOutput() + session.commands = nil + session.extensions = tentaclewire.Extensions{} + session.bindings = nil + for id := range session.pending { + session.finish_locked(id, nil, err) + } + session.cancel() +} + +func (session *Session) fail(err error) { + session.mutex.Lock() + defer session.mutex.Unlock() + session.fail_locked(err) +} + +// Disable revokes commands and retires replies synchronously; pipe shutdown and +// process cleanup happen on the supervisor. It is safe to call repeatedly. +func (session *Session) Disable() { + session.mutex.Lock() + defer session.mutex.Unlock() + if session.state == Stopping || session.state == Stopped || session.state == Failed { + return + } + session.state = Stopping + close(session.revoked) + session.revokeOutput() + session.commands = nil + session.extensions = tentaclewire.Extensions{} + session.bindings = nil + for id := range session.pending { + session.finish_locked(id, nil, ErrDisabled) + } + session.notify_locked("shutdown", nil) + close(session.stop) +} diff --git a/internal/tentacle/session_test.go b/internal/tentacle/session_test.go new file mode 100644 index 0000000..11241d6 --- /dev/null +++ b/internal/tentacle/session_test.go @@ -0,0 +1,599 @@ +package tentacle + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "fmt" + "os" + "os/exec" + "strconv" + "strings" + "sync" + "syscall" + "testing" + "time" + + "git.stormux.org/storm/cthulhu/internal/input" +) + +func test_manager(t testing.TB, limits Limits, overrides []input.BindingOverride) *Manager { + t.Helper() + manager, err := NewManager(limits, overrides) + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + if err := manager.Shutdown(ctx); err != nil { + t.Error(err) + } + if stats := manager.Stats(); stats != (Stats{}) { + t.Errorf("retained resources: %+v", stats) + } + }) + return manager +} + +func child_spec(t testing.TB, id, mode string) Spec { + t.Helper() + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + return Spec{ID: id, Program: []string{executable, "-test.run=^TestTentacleChild$", "--", "tentacle-child:" + mode}} +} + +func wait_signal(t testing.TB, signal <-chan struct{}) { + t.Helper() + select { + case <-signal: + case <-time.After(5 * time.Second): + t.Fatal("timed out waiting for child lifecycle") + } +} + +func start_ready(t testing.TB, manager *Manager, id, mode string) *Session { + t.Helper() + session, err := manager.Start(context.Background(), child_spec(t, id, mode)) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Ready()) + if state, err := session.Status(); state != Ready || err != nil { + t.Fatalf("state %s: %v", state, err) + } + return session +} + +func start_active(t testing.TB, manager *Manager, id, mode string) *Session { + t.Helper() + session := start_ready(t, manager, id, mode) + if err := session.Activate(); err != nil { + t.Fatal(err) + } + return session +} + +func wait_result(t testing.TB, result <-chan Result) Result { + t.Helper() + select { + case reply, ok := <-result: + if !ok { + t.Fatal("missing result") + } + return reply + case <-time.After(5 * time.Second): + t.Fatal("missing bounded result") + } + return Result{} +} + +func TestActivationAndUnicodeRoundTrip(t *testing.T) { + manager := test_manager(t, DefaultLimits(), nil) + session := start_ready(t, manager, "sample", "echo") + if _, err := session.Invoke(context.Background(), "echo", nil); !errors.Is(err, ErrUnavailable) { + t.Fatal(err) + } + commands := session.Commands() + commands[0].ID = "changed" + commands[0].Bindings[0].Key = "changed" + if session.Commands()[0].ID != "echo" || session.Commands()[0].Bindings[0].Key == "changed" { + t.Fatal("registration alias") + } + if err := session.Activate(); err != nil { + t.Fatal(err) + } + if err := session.Activate(); !errors.Is(err, ErrUnavailable) { + t.Fatal("double activation", err) + } + if _, err := session.Invoke(context.Background(), "unknown", nil); !errors.Is(err, ErrUnavailable) { + t.Fatal(err) + } + arguments := json.RawMessage(`{"text":"é猫😀é"}`) + pending, err := session.Invoke(context.Background(), "echo", arguments) + if err != nil { + t.Fatal(err) + } + result := wait_result(t, pending) + if result.Err != nil || string(result.Value) != string(arguments) || result.Session != session.Identity() { + t.Fatalf("%+v", result) + } + if _, open := <-pending; open { + t.Fatal("result channel not closed") + } + session.Disable() + if len(session.Commands()) != 0 || len(session.Bindings()) != 0 { + t.Fatal("disable did not revoke") + } + if _, err := session.Invoke(context.Background(), "echo", nil); !errors.Is(err, ErrUnavailable) { + t.Fatal(err) + } + wait_signal(t, session.Done()) + if state, err := session.Status(); state != Stopped || err != nil { + t.Fatalf("state %s: %v", state, err) + } + replacement := start_active(t, manager, "sample", "echo") + if replacement.Identity() == session.Identity() { + t.Fatal("session identity reused") + } +} + +func TestRepliesCorrelateOutOfOrder(t *testing.T) { + manager := test_manager(t, DefaultLimits(), nil) + session := start_active(t, manager, "sample", "reverse") + first, err := session.Invoke(context.Background(), "echo", json.RawMessage(`1`)) + if err != nil { + t.Fatal(err) + } + second, err := session.Invoke(context.Background(), "echo", json.RawMessage(`2`)) + if err != nil { + t.Fatal(err) + } + for index, pending := range []<-chan Result{first, second} { + result := wait_result(t, pending) + if result.Err != nil || string(result.Value) != strconv.Itoa(index+1) { + t.Fatalf("misrouted response: %+v", result) + } + } +} + +func TestDisabledStagingCannotPublish(t *testing.T) { + manager := test_manager(t, DefaultLimits(), nil) + session := start_ready(t, manager, "sample", "echo") + session.Disable() + if err := session.Activate(); !errors.Is(err, ErrUnavailable) { + t.Fatal("disabled staging published", err) + } + wait_signal(t, session.Done()) + if len(session.outbound) != 0 { + t.Fatal("cleanup retained unsent frames") + } +} + +func TestBadChildrenAreContained(t *testing.T) { + for _, mode := range []string{"malformed", "oversized", "stderr", "wrong-major", "wrong-session", "duplicate-command", "invalid-binding", "unknown-response", "hang-start"} { + t.Run(mode, func(t *testing.T) { + limits := DefaultLimits() + limits.StartupTimeout = 500 * time.Millisecond + manager := test_manager(t, limits, nil) + session, err := manager.Start(context.Background(), child_spec(t, "broken", mode)) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Done()) + if state, err := session.Status(); state != Failed || err == nil || len(session.Commands()) != 0 { + t.Fatalf("state %s: %v", state, err) + } + // Failure releases capacity for a healthy tentacle. + start_active(t, manager, "healthy", "echo") + }) + } +} + +func TestRequestFailureCancellationAndDisable(t *testing.T) { + for _, mode := range []string{"crash", "duplicate-reply", "timeout", "cancel", "disable", "blocked-input"} { + t.Run(mode, func(t *testing.T) { + limits := DefaultLimits() + limits.RequestTimeout = 150 * time.Millisecond + manager := test_manager(t, limits, nil) + session := start_active(t, manager, "sample", mode) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + pending, err := session.Invoke(ctx, "echo", json.RawMessage(`{"text":"sample"}`)) + if err != nil { + t.Fatal(err) + } + if mode == "cancel" { + cancel() + } + if mode == "disable" { + session.Disable() + } + result := wait_result(t, pending) + if mode != "duplicate-reply" && result.Err == nil { + t.Fatal("failed call succeeded") + } + if mode == "cancel" && !errors.Is(result.Err, context.Canceled) { + t.Fatal(result.Err) + } + if mode == "timeout" && !errors.Is(result.Err, context.DeadlineExceeded) { + t.Fatal(result.Err) + } + if mode == "disable" && !errors.Is(result.Err, ErrDisabled) { + t.Fatal(result.Err) + } + wait_signal(t, session.Done()) + if len(session.Commands()) != 0 { + t.Fatal("failure retained commands") + } + }) + } +} + +func TestAdmissionAndAggregatePendingLimits(t *testing.T) { + limits := DefaultLimits() + limits.Processes, limits.Starting, limits.PendingPerProcess, limits.PendingTotal = 2, 1, 2, 3 + manager := test_manager(t, limits, nil) + blocked, err := manager.Start(context.Background(), child_spec(t, "blocked", "hang-start")) + if err != nil { + t.Fatal(err) + } + if _, err := manager.Start(context.Background(), child_spec(t, "second", "echo")); !errors.Is(err, ErrBusy) { + t.Fatal("startup limit", err) + } + blocked.Disable() + wait_signal(t, blocked.Done()) + first := start_active(t, manager, "first", "timeout") + second := start_active(t, manager, "second", "timeout") + if _, err := manager.Start(context.Background(), child_spec(t, "third", "echo")); !errors.Is(err, ErrBusy) { + t.Fatal("process limit", err) + } + for range 2 { + if _, err := first.Invoke(context.Background(), "echo", nil); err != nil { + t.Fatal(err) + } + } + if _, err := first.Invoke(context.Background(), "echo", nil); !errors.Is(err, ErrBusy) { + t.Fatal("per-child limit", err) + } + if _, err := second.Invoke(context.Background(), "echo", nil); err != nil { + t.Fatal(err) + } + if _, err := second.Invoke(context.Background(), "echo", nil); !errors.Is(err, ErrBusy) { + t.Fatal("aggregate limit", err) + } + if stats := manager.Stats(); stats.Pending != 3 || stats.Processes != 2 { + t.Fatalf("%+v", stats) + } + first.Disable() + if stats := manager.Stats(); stats.Pending != 1 { + t.Fatalf("pending work not revoked: %+v", stats) + } +} + +func TestParentCancellationAndConcurrentShutdown(t *testing.T) { + manager := test_manager(t, DefaultLimits(), nil) + ctx, cancel := context.WithCancel(context.Background()) + session, err := manager.Start(ctx, child_spec(t, "sample", "echo")) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Ready()) + if err := session.Activate(); err != nil { + t.Fatal(err) + } + var workers sync.WaitGroup + for range 16 { + workers.Add(1) + go func() { + defer workers.Done() + _, _ = session.Invoke(context.Background(), "echo", nil) + session.Disable() + }() + } + cancel() + workers.Wait() + wait_signal(t, session.Done()) + if err := manager.Shutdown(context.Background()); err != nil { + t.Fatal(err) + } + if _, err := manager.Start(context.Background(), child_spec(t, "after-shutdown", "echo")); !errors.Is(err, ErrUnavailable) { + t.Fatal(err) + } +} + +func TestBlockedPipeCannotBlockSubmissionOrDisable(t *testing.T) { + limits := DefaultLimits() + limits.RequestTimeout = 10 * time.Second + manager := test_manager(t, limits, nil) + session := start_active(t, manager, "sample", "blocked-input") + arguments, err := json.Marshal(strings.Repeat("x", MaxArgumentBytes-2)) + if err != nil { + t.Fatal(err) + } + submitted := make(chan error, 1) + go func() { + for range limits.PendingPerProcess { + if _, err := session.Invoke(context.Background(), "echo", arguments); err != nil { + submitted <- err + return + } + } + session.Disable() + submitted <- nil + }() + select { + case err := <-submitted: + if err != nil { + t.Fatal(err) + } + case <-time.After(2 * time.Second): + t.Fatal("pipe backpressure blocked host submission or disable") + } + wait_signal(t, session.Done()) +} + +func TestLaunchValidationAndMissingExecutable(t *testing.T) { + manager := test_manager(t, DefaultLimits(), nil) + if _, err := manager.Start(nil, child_spec(t, "sample", "echo")); err == nil { + t.Fatal("nil context accepted") + } + ctx, cancel := context.WithCancel(context.Background()) + cancel() + if _, err := manager.Start(ctx, child_spec(t, "sample", "echo")); !errors.Is(err, context.Canceled) { + t.Fatal(err) + } + for _, spec := range []Spec{ + {ID: "../unsafe", Program: []string{"/bin/true"}}, + {ID: "sample", Program: []string{"relative"}}, + {ID: "sample", Program: []string{"/bin/true", "nul\x00argument"}}, + {ID: "sample", Program: []string{"/bin/true"}, Directory: "relative"}, + } { + if _, err := manager.Start(context.Background(), spec); err == nil { + t.Fatal("invalid launch accepted") + } + } + session, err := manager.Start(context.Background(), Spec{ID: "missing", Program: []string{t.TempDir() + "/missing"}}) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Done()) + if state, err := session.Status(); state != Failed || !errors.Is(err, ErrExited) { + t.Fatalf("%s: %v", state, err) + } + if stats := manager.Stats(); stats != (Stats{}) { + t.Fatalf("failed spawn retained resources: %+v", stats) + } +} + +func TestBindingConflictsLeaveCommandsAvailable(t *testing.T) { + manager := test_manager(t, DefaultLimits(), nil) + first := start_active(t, manager, "first", "echo") + bindings := first.Bindings() + if len(bindings) != 2 || bindings[0].Bound || bindings[0].Conflict != string(input.CycleSpeechMode) || !bindings[1].Bound { + t.Fatalf("core conflict: %+v", bindings) + } + second := start_active(t, manager, "second", "echo") + if bindings := second.Bindings(); bindings[1].Bound || bindings[1].Conflict != "tentacle/first/echo" { + t.Fatalf("tentacle conflict: %+v", bindings) + } + if len(second.Commands()) == 0 { + t.Fatal("unbound command disappeared") + } + first.Disable() + // No implicit rebinding of the existing second tentacle. + if second.Bindings()[1].Bound { + t.Fatal("silently rebound") + } + third := start_active(t, manager, "third", "echo") + if !third.Bindings()[1].Bound { + t.Fatal("revoked shortcut remains reserved") + } +} + +func TestBindingsRespectUserOverridesAndScopes(t *testing.T) { + manager := test_manager(t, DefaultLimits(), []input.BindingOverride{{ + Layout: input.DesktopKeyboardLayout, Scope: "global", Command: input.PresentTime, Keys: []string{"Cthulhu+Ctrl+F12"}, + }}) + session := start_active(t, manager, "sample", "echo") + if bindings := session.Bindings(); bindings[1].Bound || bindings[1].Conflict != string(input.PresentTime) { + t.Fatalf("user override conflict: %+v", bindings) + } + occupied := manager.occupied_bindings() + commands := []Command{{ID: "scoped", Bindings: []Binding{ + {Layout: "desktop", Scope: "global", Key: "h"}, + {Layout: "laptop", Scope: "global", Key: "Cthulhu+Ctrl+F12"}, + {Layout: "laptop", Scope: "browse", Key: "Ctrl+Cthulhu+F12"}, + }}} + bindings := resolve_bindings("scope", commands, occupied) + if bindings[0].Bound || !bindings[1].Bound || bindings[2].Bound { + t.Fatalf("scope/alias conflicts: %+v", bindings) + } +} + +// This is a private protocol fixture, not a public SDK or installable tentacle. +func TestTentacleChild(t *testing.T) { + mode, found := strings.CutPrefix(os.Args[len(os.Args)-1], "tentacle-child:") + if !found { + return + } + if mode == "descendant-chain" { + executable, _ := os.Executable() + child := exec.Command(executable, "-test.run=^TestTentacleChild$", "--", "tentacle-child:descendant") + child.SysProcAttr = &syscall.SysProcAttr{Setsid: true} + if child.Start() != nil { + os.Exit(8) + } + fmt.Fprintln(os.Stdout, child.Process.Pid) + os.Exit(0) + } + if mode == "descendant" { + <-time.After(time.Hour) + os.Exit(0) + } + reader := bufio.NewReader(os.Stdin) + encoder := json.NewEncoder(os.Stdout) + var heldID string + var heldValue json.RawMessage + for { + frame, err := read_frame(reader) + if err != nil { + os.Exit(0) + } + var message struct { + ID string `json:"id"` + Method string `json:"method"` + Params json.RawMessage `json:"params"` + } + if json.Unmarshal(frame, &message) != nil { + os.Exit(2) + } + reply := func(value any) { + _ = encoder.Encode(map[string]any{"jsonrpc": "2.0", "id": message.ID, "result": value}) + } + switch message.Method { + case "initialize": + switch mode { + case "hang-start": + continue + case "malformed": + fmt.Fprintln(os.Stdout, "not JSON") + continue + case "oversized": + fmt.Fprintln(os.Stdout, strings.Repeat("x", MaxFrameBytes+1)) + continue + case "stderr": + fmt.Fprint(os.Stderr, strings.Repeat("x", MaxDiagnosticBytes+1)) + continue + case "unknown-response": + _ = encoder.Encode(map[string]any{"jsonrpc": "2.0", "id": "999", "result": nil}) + continue + } + var initialization Initialization + _ = json.Unmarshal(message.Params, &initialization) + registration := Registration{Protocol: initialization.Protocol, Session: initialization.Session, Commands: []Command{{ + ID: "echo", Title: "Echo text", Description: "Private protocol fixture", Bindings: []Binding{ + {Layout: "desktop", Scope: "global", Key: "Cthulhu+S"}, + {Layout: "desktop", Scope: "global", Key: "Cthulhu+Ctrl+F12"}, + }, + }}} + switch mode { + case "wrong-major": + registration.Protocol.Major++ + case "wrong-session": + registration.Session = "wrong" + case "duplicate-command": + registration.Commands = append(registration.Commands, registration.Commands[0]) + case "invalid-binding": + registration.Commands[0].Bindings[0].Key = "not-a-key" + } + reply(registration) + case "initialized": + if mode == "exit-active" { + os.Exit(7) + } + if mode == "blocked-input" { + <-time.After(time.Hour) + } + case "command.invoke": + switch mode { + case "crash": + os.Exit(7) + case "timeout", "cancel", "disable": + continue + case "spawn", "spawn-detached", "spawn-chain": + executable, _ := os.Executable() + child := exec.Command(executable, "-test.run=^TestTentacleChild$", "--", "tentacle-child:descendant") + child.Stdout, child.Stderr = os.Stdout, os.Stderr + if mode == "spawn-detached" { + child.SysProcAttr = &syscall.SysProcAttr{Setsid: true} + } + if mode == "spawn-chain" { + child.Args[len(child.Args)-1] = "tentacle-child:descendant-chain" + child.Stdout = nil + output, err := child.StdoutPipe() + if err != nil || child.Start() != nil { + os.Exit(8) + } + var pid int + if _, err := fmt.Fscanln(output, &pid); err != nil { + os.Exit(8) + } + _ = child.Wait() + output.Close() + reply(pid) + continue + } + if child.Start() != nil { + os.Exit(8) + } + reply(child.Process.Pid) + continue + } + var params struct { + Arguments json.RawMessage `json:"arguments"` + } + _ = json.Unmarshal(message.Params, ¶ms) + if mode == "reverse" && heldID == "" { + heldID, heldValue = message.ID, params.Arguments + continue + } + reply(params.Arguments) + if mode == "reverse" { + _ = encoder.Encode(map[string]any{"jsonrpc": "2.0", "id": heldID, "result": heldValue}) + heldID, heldValue = "", nil + } + if mode == "duplicate-reply" { + reply(params.Arguments) + } + case "shutdown": + os.Exit(0) + default: + os.Exit(3) + } + } +} + +func TestDisableKillsGroupDescendantsAndJoinsPipes(t *testing.T) { + manager := test_manager(t, DefaultLimits(), nil) + session := start_active(t, manager, "sample", "spawn") + pending, err := session.Invoke(context.Background(), "echo", nil) + if err != nil { + t.Fatal(err) + } + result := wait_result(t, pending) + var pid int + if result.Err != nil || json.Unmarshal(result.Value, &pid) != nil || pid <= 1 { + t.Fatalf("bad descendant result: %+v", result) + } + session.Disable() + wait_signal(t, session.Done()) + // SIGKILL delivery/reaping is scheduled by the kernel; wait for /proc to + // report disappearance or zombie state, not an arbitrary sleep duration. + // A task that exits during ReadFile can return ESRCH rather than ENOENT. + deadline := time.NewTimer(2 * time.Second) + defer deadline.Stop() + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + for { + data, err := os.ReadFile("/proc/" + strconv.Itoa(pid) + "/stat") + if os.IsNotExist(err) || errors.Is(err, syscall.ESRCH) { + break + } + if err != nil { + t.Fatal(err) + } + _, tail, found := strings.Cut(string(data), ") ") + if found && strings.HasPrefix(tail, "Z ") { + break + } + select { + case <-ticker.C: + case <-deadline.C: + t.Fatal("owned descendant remained running") + } + } +} diff --git a/internal/tentacle/supervisor.go b/internal/tentacle/supervisor.go new file mode 100644 index 0000000..ec2cf78 --- /dev/null +++ b/internal/tentacle/supervisor.go @@ -0,0 +1,203 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "context" + "errors" + "fmt" + "io" + "os" + "os/exec" + "os/signal" + "path/filepath" + "runtime" + "strconv" + "strings" + "syscall" + "time" +) + +var ErrSupervision = errors.New("tentacle process supervision failed") + +// RunSupervisor is a private per-session helper. Descriptors 0..2 carry only +// the Tentacle protocol and diagnostics; 3 is a reader-owned lifetime pipe and +// 4 is a bounded Spec. The child never inherits either private descriptor. +// A separate subreaper keeps ownership of double-forked/setsid descendants +// without making the reader a subreaper for unrelated desktop helpers. +func RunSupervisor(ctx context.Context) error { + // ExtraFiles arrive in blocking mode. Register the private pipes with Go's + // poller so Close interrupts their readers on cancellation and child exit. + for _, descriptor := range []int{3, 4} { + syscall.CloseOnExec(descriptor) + if err := syscall.SetNonblock(descriptor, true); err != nil { + return fmt.Errorf("%w: private pipe: %w", ErrSupervision, err) + } + } + lifetime := os.NewFile(3, "tentacle-lifetime") + configuration := os.NewFile(4, "tentacle-spec") + if lifetime == nil || configuration == nil { + return ErrSupervision + } + defer configuration.Close() + // PR_SET_CHILD_SUBREAPER is a Linux facility independent of the init system. + if _, _, errno := syscall.Syscall6(syscall.SYS_PRCTL, 36, 1, 0, 0, 0, 0); errno != 0 { + lifetime.Close() + return fmt.Errorf("%w: subreaper: %w", ErrSupervision, errno) + } + ctx, cancel := context.WithCancel(ctx) + defer cancel() + readerDone := make(chan struct{}) + go func() { + defer close(readerDone) + _, _ = io.Copy(io.Discard, lifetime) + cancel() + }() + defer func() { lifetime.Close(); <-readerDone }() + // Closing this descriptor also interrupts a partial startup on termination. + stop := context.AfterFunc(ctx, func() { configuration.Close() }) + defer stop() + data, err := io.ReadAll(io.LimitReader(configuration, MaxFrameBytes+1)) + if err != nil || len(data) > MaxFrameBytes { + // No child exists yet. A partial configuration can result from startup + // cancellation. Protocol EOF fails registration, while a zero helper + // exit certifies cleanup and lets the host release its admission slot. + return nil + } + configuration.Close() + var spec Spec + if decode_strict(data, &spec) != nil || validate_spec(spec) != nil { + return nil + } + if ctx.Err() != nil { + return nil + } + // Pdeathsig follows the creating thread; retain it for the child lifetime. + runtime.LockOSThread() + defer runtime.UnlockOSThread() + command := exec.Command(spec.Program[0], spec.Program[1:]...) + command.Dir = spec.Directory + command.Stdin, command.Stdout, command.Stderr = os.Stdin, os.Stdout, os.Stderr + command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true, Pdeathsig: syscall.SIGKILL} + childSignals := make(chan os.Signal, 1) + signal.Notify(childSignals, syscall.SIGCHLD) + defer signal.Stop(childSignals) + if err := command.Start(); err != nil { + // No process was started. Protocol EOF reports the startup failure; + // successful cleanup keeps the manager available for a later retry. + return nil + } + exited := make(chan struct{}) + go func() { _ = command.Wait(); close(exited) }() + var supervisionError error +running: + for { + select { + case <-ctx.Done(): + break running + case <-exited: + break running + case <-childSignals: + // The subreaper owns orphaned descendants for the entire session, + // not just teardown. Only command.Wait may reap the main child. + supervisionError = reap_exited_supervised_children(command.Process.Pid) + if supervisionError != nil { + break running + } + } + } + _ = command.Process.Kill() + <-exited + return errors.Join(supervisionError, reap_supervised_children(DefaultResourceLimits().CleanupTimeout)) +} + +func supervised_children() ([]int, error) { + paths, err := filepath.Glob("/proc/self/task/*/children") + if err != nil || len(paths) == 0 { + return nil, ErrSupervision + } + var children []int + for _, path := range paths { + data, err := os.ReadFile(path) + if os.IsNotExist(err) || errors.Is(err, syscall.ESRCH) { // A runtime thread exited during the scan. + continue + } + if err != nil { + return nil, ErrSupervision + } + for _, value := range strings.Fields(string(data)) { + pid, err := strconv.Atoi(value) + if err != nil || pid <= 1 { + return nil, ErrSupervision + } + children = append(children, pid) + } + } + return children, nil +} + +func reap_exited_supervised_children(mainPID int) error { + children, err := supervised_children() + if err != nil { + return err + } + for _, childPID := range children { + if childPID == mainPID { + continue + } + for { + _, err := syscall.Wait4(childPID, nil, syscall.WNOHANG, nil) + if err == syscall.EINTR { + continue + } + if err != nil && err != syscall.ECHILD { + return fmt.Errorf("%w: reap exited descendant: %w", ErrSupervision, err) + } + break + } + } + return nil +} + +// Only this helper's children are killed. A child PID cannot be reused until +// it has been reaped, and no other goroutine calls Wait after command.Wait joins. +// Killing direct children adopts the next generation, including detached ones. +func reap_supervised_children(timeout time.Duration) error { + deadline := time.NewTimer(timeout) + defer deadline.Stop() + tick := time.NewTicker(5 * time.Millisecond) + defer tick.Stop() + for { + children, err := supervised_children() + if err != nil { + return err + } + for _, pid := range children { + if err := syscall.Kill(pid, syscall.SIGKILL); err != nil && err != syscall.ESRCH { + return fmt.Errorf("%w: terminate descendant: %w", ErrSupervision, err) + } + } + for { + var status syscall.WaitStatus + pid, err := syscall.Wait4(-1, &status, syscall.WNOHANG, nil) + if err == syscall.ECHILD { + return nil + } + if err == syscall.EINTR { + continue + } + if err != nil { + return fmt.Errorf("%w: reap descendant: %w", ErrSupervision, err) + } + if pid == 0 { + break + } + } + select { + case <-deadline.C: + return fmt.Errorf("%w: descendant cleanup deadline expired", ErrSupervision) + case <-tick.C: + } + } +} diff --git a/internal/tentacle/supervisor_test.go b/internal/tentacle/supervisor_test.go new file mode 100644 index 0000000..ab0f5d9 --- /dev/null +++ b/internal/tentacle/supervisor_test.go @@ -0,0 +1,226 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentacle + +import ( + "context" + "encoding/json" + "errors" + "os" + "os/exec" + "path/filepath" + "strconv" + "syscall" + "testing" + "time" +) + +func supervisor_program(t testing.TB) []string { + t.Helper() + executable, err := os.Executable() + if err != nil { + t.Fatal(err) + } + return []string{executable, "-test.run=^TestSupervisorHelper$", "--", "supervisor"} +} + +func supervised_manager(t testing.TB) *Manager { + t.Helper() + manager, err := NewSupervisedManager(supervisor_program(t), "auto") + if err != nil { + t.Fatal(err) + } + t.Cleanup(func() { + ctx, cancel := context.WithTimeout(context.Background(), 7*time.Second) + defer cancel() + if err := manager.Shutdown(ctx); err != nil { + t.Error(err) + } + if manager.Stats() != (Stats{}) { + t.Error(manager.Stats()) + } + }) + return manager +} + +func supervised_descendant(t testing.TB, session *Session) int { + t.Helper() + result, err := session.Invoke(context.Background(), "echo", nil) + if err != nil { + t.Fatal(err) + } + value := wait_result(t, result) + var pid int + if value.Err != nil || json.Unmarshal(value.Value, &pid) != nil || pid <= 1 { + t.Fatalf("descendant: %+v", value) + } + return pid +} + +func wait_supervised_reap(t *testing.T, pid int) { + t.Helper() + deadline := time.NewTimer(6 * time.Second) + defer deadline.Stop() + ticker := time.NewTicker(time.Millisecond) + defer ticker.Stop() + for { + if _, err := os.Stat("/proc/" + strconv.Itoa(pid)); os.IsNotExist(err) || errors.Is(err, syscall.ESRCH) { + return + } + select { + case <-deadline.C: + t.Fatalf("supervisor did not reap descendant %d", pid) + case <-ticker.C: + } + } +} + +func TestSupervisorHelper(t *testing.T) { + if os.Args[len(os.Args)-1] == "supervisor" { + if err := RunSupervisor(context.Background()); err != nil { + os.Exit(1) + } + os.Exit(0) + } + if len(os.Args) < 3 || os.Args[len(os.Args)-2] != "supervisor-owner" { + return + } + marker := os.Args[len(os.Args)-1] + manager, err := NewSupervisedManager(supervisor_program(t), "auto") + if err != nil { + t.Fatal(err) + } + session := start_active(t, manager, "sample", "spawn-chain") + pid := supervised_descendant(t, session) + if err := os.WriteFile(marker, []byte(strconv.Itoa(pid)), 0600); err != nil { + t.Fatal(err) + } + // Abrupt reader death: no Disable, Shutdown, deferred cleanup or signals. + os.Exit(0) +} + +func TestSupervisionWithoutInitToolsCleansDetachedDescendants(t *testing.T) { + t.Setenv("PATH", "") + t.Setenv("CTHULHU_TENTACLE_CGROUP_PARENT", "") + for _, mode := range []string{"spawn", "spawn-detached", "spawn-chain"} { + t.Run(mode, func(t *testing.T) { + manager := supervised_manager(t) + first := start_active(t, manager, "first", mode) + second := start_active(t, manager, "second", "spawn-detached") + pid := supervised_descendant(t, first) + other := supervised_descendant(t, second) + first.Disable() + wait_signal(t, first.Done()) + if state, err := first.Status(); state != Stopped || err != nil { + t.Fatalf("disable: %s %v", state, err) + } + wait_supervised_reap(t, pid) + if _, err := os.Stat("/proc/" + strconv.Itoa(other)); err != nil { + t.Fatal("another session was terminated", err) + } + second.Disable() + wait_signal(t, second.Done()) + wait_supervised_reap(t, other) + }) + } +} + +func TestSupervisionCleansDescendantsAfterReaderDeath(t *testing.T) { + t.Setenv("PATH", "") + t.Setenv("CTHULHU_TENTACLE_CGROUP_PARENT", "") + executable, _ := os.Executable() + marker := filepath.Join(t.TempDir(), "descendant") + ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + command := exec.CommandContext(ctx, executable, "-test.run=^TestSupervisorHelper$", "--", "supervisor-owner", marker) + if output, err := command.CombinedOutput(); err != nil { + t.Fatalf("owner: %v %s", err, output) + } + data, err := os.ReadFile(marker) + if err != nil { + t.Fatal(err) + } + pid, err := strconv.Atoi(string(data)) + if err != nil || pid <= 1 { + t.Fatal("invalid descendant marker") + } + wait_supervised_reap(t, pid) +} + +func TestSupervisionReapsExitedDescendantWhileSessionActive(t *testing.T) { + t.Setenv("CTHULHU_TENTACLE_CGROUP_PARENT", "") + manager := supervised_manager(t) + session := start_active(t, manager, "sample", "spawn-chain") + pid := supervised_descendant(t, session) + if err := syscall.Kill(pid, syscall.SIGKILL); err != nil { + t.Fatal(err) + } + wait_supervised_reap(t, pid) + if state, err := session.Status(); state != Active || err != nil { + t.Fatalf("descendant exit retired the live session: %s %v", state, err) + } + // A status flag alone does not prove the main child's protocol still works. + _ = supervised_descendant(t, session) +} + +func TestSupervisionMissingProgramReleasesCapacity(t *testing.T) { + t.Setenv("CTHULHU_TENTACLE_CGROUP_PARENT", "") + manager := supervised_manager(t) + spec := Spec{ID: "sample", Program: []string{filepath.Join(t.TempDir(), "missing")}} + session, err := manager.Start(context.Background(), spec) + if err != nil { + t.Fatal(err) + } + wait_signal(t, session.Done()) + if state, failure := session.Status(); state != Failed || failure == nil { + t.Fatal(state, failure) + } + healthy := start_active(t, manager, "sample", "echo") + healthy.Disable() + wait_signal(t, healthy.Done()) +} + +func TestSupervisionRejectsInvalidExplicitCgroupParent(t *testing.T) { + for _, parent := range []string{"relative", t.TempDir()} { + if _, err := NewSupervisedManager(supervisor_program(t), parent); !errors.Is(err, ErrContainment) { + t.Fatalf("silently ignored explicit parent %q: %v", parent, err) + } + } + t.Setenv("CTHULHU_TENTACLE_CGROUP_PARENT", t.TempDir()) + if _, err := NewSupervisedManager(supervisor_program(t), "auto"); !errors.Is(err, ErrContainment) { + t.Fatalf("silently ignored configured parent: %v", err) + } +} + +func TestSupervisionCancelledStartupReleasesCapacity(t *testing.T) { + t.Setenv("CTHULHU_TENTACLE_CGROUP_PARENT", "") + manager := supervised_manager(t) + session, err := manager.Start(context.Background(), child_spec(t, "sample", "hang-start")) + if err != nil { + t.Fatal(err) + } + wait_control(t, func() bool { + session.mutex.Lock() + defer session.mutex.Unlock() + return len(session.pending) > 0 + }) + session.Disable() + wait_signal(t, session.Done()) + if state, err := session.Status(); state != Stopped || err != nil { + t.Fatal(state, err) + } + healthy := start_active(t, manager, "sample", "echo") + healthy.Disable() + wait_signal(t, healthy.Done()) +} + +func TestSupervisionDetectsChildExitAfterActivation(t *testing.T) { + t.Setenv("CTHULHU_TENTACLE_CGROUP_PARENT", "") + manager := supervised_manager(t) + session := start_active(t, manager, "sample", "exit-active") + wait_signal(t, session.Done()) + if state, err := session.Status(); state != Failed || !errors.Is(err, ErrExited) { + t.Fatal(state, err) + } +} diff --git a/internal/tentacle/testdata/peer.py b/internal/tentacle/testdata/peer.py new file mode 100644 index 0000000..334c4c6 --- /dev/null +++ b/internal/tentacle/testdata/peer.py @@ -0,0 +1,26 @@ +"""Private independent wire fixture. Not an SDK or installable tentacle.""" + +import json +import sys + +active = False +for line in sys.stdin.buffer: + request = json.loads(line) + method = request["method"] + if method == "initialize": + initialization = request["params"] + result = { + "protocol": initialization["protocol"], + "session": initialization["session"], + "commands": [{"id": "echo", "title": "Echo text", "description": ""}], + } + elif method == "initialized": + active = True + continue + elif method == "shutdown": + break + elif method == "command.invoke" and active: + result = request["params"]["arguments"] + else: + sys.exit(2) + print(json.dumps({"jsonrpc": "2.0", "id": request["id"], "result": result}), flush=True) diff --git a/internal/tentacle/testdata/resource_peer.py b/internal/tentacle/testdata/resource_peer.py new file mode 100644 index 0000000..9aed62b --- /dev/null +++ b/internal/tentacle/testdata/resource_peer.py @@ -0,0 +1,63 @@ +"""Private cgroup fixture. Never run resource commands outside a bounded group.""" + +import json +import os +import time + + +allocations = [] +for line in iter(input, None): + message = json.loads(line) + method = message["method"] + if method == "initialize": + params = message["params"] + result = { + "protocol": params["protocol"], + "session": params["session"], + "commands": [{"id": "echo", "title": "Resource fixture", "description": ""}], + } + elif method == "initialized": + continue + elif method == "shutdown": + break + elif method == "command.invoke": + action = message["params"]["arguments"].get("action", "location") + if action == "detach": + childPid = os.fork() + if childPid == 0: + os.setsid() + time.sleep(300) + os._exit(0) + # Synchronize with the detach; inherited stdout stays open. + while os.getsid(childPid) != childPid: + time.sleep(0.001) + result = childPid + elif action == "tasks": + childPids = [] + for _ in range(96): + try: + childPid = os.fork() + except BlockingIOError: + break + if childPid == 0: + time.sleep(300) + os._exit(0) + childPids.append(childPid) + result = len(childPids) + elif action == "memory": + allocation = bytearray(message["params"]["arguments"]["bytes"]) + for offset in range(0, len(allocation), 4096): + allocation[offset] = 1 + allocations.append(allocation) + result = True + elif action == "cpu": + result = True + else: + with open("/proc/self/cgroup", encoding="ascii") as source: + result = source.read().strip() + else: + raise RuntimeError("Unexpected method") + print(json.dumps({"jsonrpc": "2.0", "id": message["id"], "result": result}), flush=True) + if method == "command.invoke" and action == "cpu": + while True: + pass diff --git a/internal/tentacle/testdata/sdk_peer.py b/internal/tentacle/testdata/sdk_peer.py new file mode 100644 index 0000000..f8128d1 --- /dev/null +++ b/internal/tentacle/testdata/sdk_peer.py @@ -0,0 +1,41 @@ +# Private conformance peer: author APIs only; no framing or lifecycle code. +import pathlib +import sys +import threading + +sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[3] / "sdk/python")) +from cthulhu_tentacle import Command, present, serve + +started = threading.Event() + + +def echo(cancelled, arguments): + return arguments + + +def fail(cancelled, arguments): + raise RuntimeError("private handler details") + + +def large(cancelled, arguments): + return "x" * 65536 + + +def wait(cancelled, arguments): + started.set() + cancelled.wait() + pathlib.Path(sys.argv[1]).write_text("cancelled") + + +def has_started(cancelled, arguments): + return started.wait(2) + + +commands = [Command("echo", "Echo", "", echo), Command("fail", "Fail", "", fail), + Command("large", "Large", "", large), Command("wait", "Wait", "", wait), + Command("started", "Started", "", has_started)] +if pathlib.Path(sys.argv[1]).name == "presentation": + commands.append(Command("present", "Present", "", + lambda cancelled, arguments: present(speech="Hello, é猫😀é", braille="Display é猫😀é", uninterruptible=True), + presentation=True)) +serve(commands) diff --git a/internal/tentacle/testdata/sdk_reader_peer.py b/internal/tentacle/testdata/sdk_reader_peer.py new file mode 100644 index 0000000..efc31a3 --- /dev/null +++ b/internal/tentacle/testdata/sdk_reader_peer.py @@ -0,0 +1,20 @@ +# Private reader-settings conformance peer; no backend or desktop access. +import pathlib +import sys + +sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[3] / "sdk/python")) +from cthulhu_tentacle import Command, serve + + +def echo(cancelled, arguments): + return arguments + + +extensions = {"pages": [{"id": "probe", "title": "Reader probe", "command": "echo", + "elements": [{"id": "text", "label": "Example text", "kind": 2}], + "values": {"text": {"text": "Initial"}}}], + "quick_settings": [{"id": "probe", "label": "Probe choice", "command": "echo", + "selected": "default", "options": [{"id": "default", "label": "Default"}]}]} +serve([Command("echo", "Reader probe", "Private fixture", echo, + presentation=True, interaction=True, reader=True), + Command("ordinary", "Ordinary probe", "Private fixture", echo)], extensions=extensions) diff --git a/internal/tentaclewire/interaction.go b/internal/tentaclewire/interaction.go new file mode 100644 index 0000000..89b9549 --- /dev/null +++ b/internal/tentaclewire/interaction.go @@ -0,0 +1,114 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentaclewire + +import ( + "bytes" + "encoding/json" + "unicode" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/interaction" +) + +// Interaction is an opt-in command result. The host runs forms outside the +// bounded RPC deadline and invokes Next with the submitted values. Poll is a +// registered command sampled once per second while the form remains open. +// A polling reply may announce a changed status or finish the form with Done. +type Interaction struct { + Presentation + Form *interaction.Form `json:"form,omitempty"` + Next string `json:"next,omitempty"` + Poll string `json:"poll,omitempty"` + Source string `json:"source,omitempty"` // "focus" or "clipboard", supplied to Next. + Clipboard *string `json:"clipboard,omitempty"` + Done bool `json:"done,omitempty"` + Reader *ReaderRequest `json:"reader,omitempty"` +} + +type Submission struct { + Activated string `json:"activated,omitempty"` + Values map[string]interaction.Value `json:"values,omitempty"` + Cancelled bool `json:"cancelled,omitempty"` + Item *Item `json:"item,omitempty"` + Error string `json:"error,omitempty"` + Reader *ReaderState `json:"reader,omitempty"` +} + +// Item is a single copied value, without accessible identities or native handles. +type Item struct { + Temporary bool `json:"-"` // Host-only ownership of materialized clipboard data. + Text string `json:"text,omitempty"` + Path string `json:"path,omitempty"` +} + +func DecodeInteraction(data []byte) (Interaction, error) { + var value Interaction + var fields map[string]json.RawMessage + if json.Unmarshal(data, &fields) != nil || fields == nil { + return value, ErrProtocol + } + for _, field := range fields { + if bytes.Equal(bytes.TrimSpace(field), []byte("null")) { + return value, ErrProtocol + } + } + if err := DecodeStrict(data, &value); err != nil { + return value, err + } + if value.Speech != "" || value.Braille != "" { + message, _ := json.Marshal(value.Presentation) + if _, err := DecodePresentation(message); err != nil { + return value, err + } + } else if value.Uninterruptible { + return value, ErrProtocol + } + if value.Clipboard != nil && (!utf8.ValidString(*value.Clipboard) || len(*value.Clipboard) > MaxPresentationBytes) { + return value, ErrLimit + } + if value.Source != "" && value.Source != "focus" && value.Source != "clipboard" { + return value, ErrProtocol + } + if value.Reader != nil { + if ValidateReaderRequest(*value.Reader) != nil || value.Form != nil || value.Source != "" || value.Poll != "" || value.Clipboard != nil || value.Done || value.Reader.Snapshot && value.Next == "" { + return value, ErrProtocol + } + } else if value.Form != nil { + for _, element := range value.Form.Elements { + if !validFormText(element.Label) || !validFormText(element.ID) { + return value, ErrProtocol + } + for _, item := range element.Items { + if !validFormText(item.Label) || !validFormText(item.ID) { + return value, ErrProtocol + } + } + } + if !validFormText(value.Form.Title) { + return value, ErrProtocol + } + if _, err := interaction.NewSession(*value.Form); err != nil { + return value, ErrProtocol + } + if value.Next == "" || value.Done || value.Source != "" { + return value, ErrProtocol + } + } else if value.Poll != "" || value.Next != "" && value.Source == "" || value.Source != "" && value.Next == "" { + return value, ErrProtocol + } + return value, nil +} + +func validFormText(text string) bool { + if !utf8.ValidString(text) { + return false + } + for _, r := range text { + if unicode.IsControl(r) { + return false + } + } + return true +} diff --git a/internal/tentaclewire/interaction_test.go b/internal/tentaclewire/interaction_test.go new file mode 100644 index 0000000..5a95704 --- /dev/null +++ b/internal/tentaclewire/interaction_test.go @@ -0,0 +1,57 @@ +package tentaclewire + +import ( + "encoding/json" + "git.stormux.org/storm/cthulhu/internal/interaction" + "strings" + "testing" +) + +func TestInteractionContract(t *testing.T) { + form := &interaction.Form{Title: "Wormhole menu", Elements: []interaction.Element{{ID: "choices", Label: "Options", Kind: interaction.List, Items: []interaction.Item{{ID: "send", Label: "Send focused item"}}}}} + for _, value := range []Interaction{ + {Form: form, Next: "choice"}, {Form: form, Next: "choice", Poll: "status"}, {Source: "focus", Next: "send"}, {Source: "clipboard", Next: "send"}, + {Presentation: Presentation{Speech: "Ready"}, Done: true}, {Done: true}, {}, + } { + data, _ := json.Marshal(value) + if _, err := DecodeInteraction(data); err != nil { + t.Fatalf("%s: %v", data, err) + } + } + for _, raw := range []string{`null`, ` null `, `{"form":null}`, `{"clipboard":null}`, `{"unknown":true}`, `{"source":"desktop","next":"send"}`, `{"source":"focus"}`, `{"next":"send"}`, `{"poll":"status"}`, `{"speech":"bad\u0000"}`, `{"uninterruptible":true}`} { + if _, err := DecodeInteraction([]byte(raw)); err == nil { + t.Fatal("accepted", raw) + } + } + for _, value := range []Interaction{{Form: form}, {Form: form, Next: "choice", Done: true}, {Form: form, Next: "choice", Source: "focus"}} { + data, _ := json.Marshal(value) + if _, err := DecodeInteraction(data); err == nil { + t.Fatal("accepted", string(data)) + } + } + copy := strings.Repeat("x", MaxPresentationBytes+1) + data, _ := json.Marshal(Interaction{Clipboard: ©}) + if _, err := DecodeInteraction(data); err == nil { + t.Fatal("accepted oversized clipboard write") + } + form.Title = "Bad\x1btitle" + data, _ = json.Marshal(Interaction{Form: form, Next: "choice"}) + if _, err := DecodeInteraction(data); err == nil { + t.Fatal("accepted control in title") + } +} +func TestInteractionGrantsRemainExplicit(t *testing.T) { + for _, apis := range [][]string{{"commands"}, {"commands", "presentation"}, {"commands", "presentation", "interaction"}} { + if !ValidAPIs(apis, apis) { + t.Fatal("rejected", apis) + } + } + for _, apis := range [][]string{{"commands", "interaction"}, {"commands", "presentation", "unknown"}, {"commands", "interaction", "presentation"}} { + if ValidAPIs(apis, apis) { + t.Fatal("accepted", apis) + } + } + if ValidAPIs([]string{"commands", "presentation", "interaction"}, []string{"commands", "presentation"}) { + t.Fatal("missing grant accepted") + } +} diff --git a/internal/tentaclewire/presentation.go b/internal/tentaclewire/presentation.go new file mode 100644 index 0000000..e8a388f --- /dev/null +++ b/internal/tentaclewire/presentation.go @@ -0,0 +1,73 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentaclewire + +import ( + "bytes" + "encoding/json" + "unicode" + "unicode/utf8" +) + +const MaxPresentationBytes = 8192 // Per channel, measured in UTF-8 bytes. + +// Presentation is a command result, never an unsolicited announcement. Empty +// channels are omitted; neither channel supplies positions or routing targets. +type Presentation struct { + Speech string `json:"speech,omitempty"` + Braille string `json:"braille,omitempty"` + Uninterruptible bool `json:"uninterruptible,omitempty"` +} + +func DecodePresentation(data []byte) (Presentation, error) { + var value Presentation + if err := DecodeStrict(data, &value); err != nil { + return value, err + } + var fields map[string]json.RawMessage + if json.Unmarshal(data, &fields) != nil || fields == nil || len(fields) == 0 { + return value, ErrProtocol + } + for _, field := range fields { + if bytes.Equal(field, []byte("null")) { + return value, ErrProtocol + } + } + if value.Speech == "" && value.Braille == "" { + return value, ErrProtocol + } + if value.Uninterruptible && value.Speech == "" { + return value, ErrProtocol + } + for _, text := range []string{value.Speech, value.Braille} { + if len(text) > MaxPresentationBytes { + return value, ErrLimit + } + if !utf8.ValidString(text) { + return value, ErrProtocol + } + for _, char := range text { + if unicode.IsControl(char) && char != '\n' && char != '\t' { + return value, ErrProtocol + } + } + } + return value, nil +} + +// The experimental optional API is additive to the command-only handshake. +func ValidAPIs(apis, capabilities []string) bool { + if len(apis) != len(capabilities) || len(apis) < 1 || len(apis) > 4 || apis[0] != "commands" { + return false + } + if len(apis) >= 2 && apis[1] != "presentation" || len(apis) >= 3 && apis[2] != "interaction" || len(apis) == 4 && apis[3] != "reader-settings" { + return false + } + for index := range apis { + if apis[index] != capabilities[index] { + return false + } + } + return true +} diff --git a/internal/tentaclewire/presentation_test.go b/internal/tentaclewire/presentation_test.go new file mode 100644 index 0000000..5bd5fa9 --- /dev/null +++ b/internal/tentaclewire/presentation_test.go @@ -0,0 +1,37 @@ +package tentaclewire + +import ( + "encoding/json" + "errors" + "strings" + "testing" +) + +func TestPresentationContract(t *testing.T) { + for _, value := range []Presentation{ + {Speech: "Hello, é猫😀é"}, {Braille: "é猫😀é"}, + {Speech: "Speech text", Braille: "Display text"}, + {Speech: "Hello world!", Braille: "Hello world!", Uninterruptible: true}, + {Speech: strings.Repeat("é", MaxPresentationBytes/2)}, + } { + data, _ := json.Marshal(value) + decoded, err := DecodePresentation(data) + if err != nil || decoded != value { + t.Fatalf("round trip: %+v, %v", decoded, err) + } + } + for _, data := range []string{`null`, `[]`, `{}`, `{"speech":null}`, `{"speech":42}`, + `{"speech":""}`, `{"speech":"hello","voice":"default"}`, `{"speech":"one","speech":"two"}`, + `{"braille":"bad\u0000text"}`, `{"speech":"bad\u001btext"}`, + `{"braille":"hello","uninterruptible":true}`, `{"uninterruptible":true}`, + `{"speech":"hello","uninterruptible":null}`, `{"speech":"hello","uninterruptible":"true"}`, + `{"speech":"hello","uninterruptible":true,"uninterruptible":false}`} { + if _, err := DecodePresentation([]byte(data)); !errors.Is(err, ErrProtocol) { + t.Fatalf("accepted %s: %v", data, err) + } + } + data, _ := json.Marshal(Presentation{Braille: strings.Repeat("é", MaxPresentationBytes/2+1)}) + if _, err := DecodePresentation(data); !errors.Is(err, ErrLimit) { + t.Fatal("UTF-8 byte bound", err) + } +} diff --git a/internal/tentaclewire/reader.go b/internal/tentaclewire/reader.go new file mode 100644 index 0000000..d559585 --- /dev/null +++ b/internal/tentaclewire/reader.go @@ -0,0 +1,247 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +package tentaclewire + +import ( + "encoding/json" + "errors" + "strings" + + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/speech" +) + +// SpeechConfiguration is a complete voice configuration, never arbitrary reader +// state. Enablement, interruption policy, input and unrelated preferences remain +// under the core's control. Nil voice parameters retain server/inherited defaults. +type SpeechConfiguration struct { + Server string `json:"server"` + Module string `json:"module"` + Device string `json:"device,omitempty"` + Baud int `json:"baud,omitempty"` + DefaultVoice config.Voice `json:"default_voice"` + UppercaseVoice config.Voice `json:"uppercase_voice"` + HyperlinkVoice config.Voice `json:"hyperlink_voice"` + SystemVoice config.Voice `json:"system_voice"` + RaisePitchForCapitals bool `json:"raise_pitch_for_capitals"` + BeepForCapitals bool `json:"beep_for_capitals"` + SayCapForCapitals bool `json:"say_cap_for_capitals"` + Punctuation int `json:"punctuation"` + CustomEcho bool `json:"custom_echo"` + CustomEchoServer bool `json:"custom_echo_server"` + EchoServer string `json:"echo_server,omitempty"` + EchoVoice config.Voice `json:"echo_voice"` + EchoForKey bool `json:"echo_for_key"` + EchoForCharacter bool `json:"echo_for_character"` + EchoForWord bool `json:"echo_for_word"` + EchoForSentence bool `json:"echo_for_sentence"` +} + +func SpeechFromSettings(settings config.Settings) SpeechConfiguration { + return SpeechConfiguration{ + Server: settings.SpeechServerFactory, Module: settings.SpeechOutputModule, + Device: settings.HardwareSpeechDevice, Baud: settings.HardwareSpeechBaudRate, + DefaultVoice: settings.DefaultVoice, UppercaseVoice: settings.UppercaseVoice, + HyperlinkVoice: settings.HyperlinkVoice, SystemVoice: settings.SystemVoice, + RaisePitchForCapitals: settings.RaisePitchForCapitals, + BeepForCapitals: settings.BeepForCapitals, SayCapForCapitals: settings.SayCapForCapitals, + Punctuation: settings.VerbalizePunctuationStyle, + CustomEcho: settings.UseCustomEchoVoice, CustomEchoServer: settings.UseCustomEchoSpeechServer, + EchoServer: settings.EchoSpeechServer, EchoVoice: settings.EchoVoice, + EchoForKey: settings.UseCustomEchoForKey, EchoForCharacter: settings.UseCustomEchoForCharacter, + EchoForWord: settings.UseCustomEchoForWord, EchoForSentence: settings.UseCustomEchoForSentence, + } +} + +func (value SpeechConfiguration) Apply(settings config.Settings) config.Settings { + settings.SpeechServerFactory, settings.SpeechOutputModule = value.Server, value.Module + settings.HardwareSpeechDevice, settings.HardwareSpeechBaudRate = value.Device, value.Baud + settings.DefaultVoice, settings.UppercaseVoice = value.DefaultVoice, value.UppercaseVoice + settings.HyperlinkVoice, settings.SystemVoice = value.HyperlinkVoice, value.SystemVoice + settings.RaisePitchForCapitals, settings.BeepForCapitals, settings.SayCapForCapitals = value.RaisePitchForCapitals, value.BeepForCapitals, value.SayCapForCapitals + settings.VerbalizePunctuationStyle = value.Punctuation + settings.UseCustomEchoVoice, settings.UseCustomEchoSpeechServer = value.CustomEcho, value.CustomEchoServer + settings.EchoSpeechServer, settings.EchoVoice = value.EchoServer, value.EchoVoice + settings.UseCustomEchoForKey, settings.UseCustomEchoForCharacter = value.EchoForKey, value.EchoForCharacter + settings.UseCustomEchoForWord, settings.UseCustomEchoForSentence = value.EchoForWord, value.EchoForSentence + return settings +} + +type PreferencePage struct { + ID string `json:"id"` + Title string `json:"title"` + Command string `json:"command"` + Load bool `json:"load,omitempty"` + Elements []interaction.Element `json:"elements"` + Values map[string]interaction.Value `json:"values"` +} + +type QuickSetting struct { + ID string `json:"id"` + Label string `json:"label"` + Command string `json:"command"` + Options []interaction.Item `json:"options"` + Selected string `json:"selected"` +} + +// Extensions are copied at registration/update. IDs are local to one session. +type Extensions struct { + Pages []PreferencePage `json:"pages,omitempty"` + QuickSettings []QuickSetting `json:"quick_settings,omitempty"` +} + +// ReaderRequest is serviced on the settings worker. Snapshot returns a copied +// state to Next; Module optionally requests that module's catalog. Mutations +// are atomic within this request and never persist the active speech override. +type ReaderRequest struct { + Snapshot bool `json:"snapshot,omitempty"` + Module string `json:"module,omitempty"` + Speech *SpeechConfiguration `json:"speech_configuration,omitempty"` + RestoreSpeech bool `json:"restore_speech,omitempty"` + Extensions *Extensions `json:"extensions,omitempty"` +} + +type ReaderState struct { + Speech SpeechConfiguration `json:"speech_configuration"` + DefaultSpeech SpeechConfiguration `json:"default_speech_configuration"` + Modules []string `json:"modules,omitempty"` + Voices []speech.Voice `json:"voices,omitempty"` + CatalogTruncated bool `json:"catalog_truncated,omitempty"` + Extensions Extensions `json:"extensions"` +} + +// ExtensionEvent handlers propose effects only. The host commits page values +// and quick selections after validating all proposals and applying core settings. +type ExtensionEvent struct { + Event string `json:"event"` + ID string `json:"id"` + Values map[string]interaction.Value `json:"values,omitempty"` + Selected string `json:"selected,omitempty"` + Reader ReaderState `json:"reader"` +} + +func valid_label(value string) bool { + return strings.TrimSpace(value) != "" && len(value) <= 256 && validFormText(value) +} + +func ValidExtensionID(value string) bool { + if len(value) == 0 || len(value) > 64 { + return false + } + for _, character := range value { + if !(character >= 'a' && character <= 'z' || character >= '0' && character <= '9' || character == '-' || character == '.') { + return false + } + } + return true +} + +func ValidateExtensions(value Extensions) error { + if len(value.Pages) > 4 || len(value.QuickSettings) > 8 { + return ErrLimit + } + ids := map[string]bool{} + for _, page := range value.Pages { + if !ValidExtensionID(page.ID) || ids[page.ID] || !valid_label(page.Title) || !ValidExtensionID(page.Command) { + return ErrProtocol + } + ids[page.ID] = true + if err := interaction.ValidatePreferences(interaction.Form{Title: page.Title, Elements: page.Elements}); err != nil { + return ErrProtocol + } + for _, element := range page.Elements { + if !ValidExtensionID(element.ID) || !valid_label(element.Label) || element.Kind == interaction.Button { + return ErrProtocol + } + for _, item := range element.Items { + if !ValidExtensionID(item.ID) || !valid_label(item.Label) { + return ErrProtocol + } + } + } + if err := ValidatePageValues(page, page.Values); err != nil { + return err + } + } + clear(ids) + for _, setting := range value.QuickSettings { + if !ValidExtensionID(setting.ID) || ids[setting.ID] || !valid_label(setting.Label) || !ValidExtensionID(setting.Command) || len(setting.Options) == 0 || len(setting.Options) > 64 { + return ErrProtocol + } + ids[setting.ID] = true + options := map[string]bool{} + selected := false + for _, option := range setting.Options { + if !ValidExtensionID(option.ID) || options[option.ID] || !valid_label(option.Label) { + return ErrProtocol + } + options[option.ID] = true + selected = selected || option.ID == setting.Selected && !option.Disabled + } + if !selected { + return ErrProtocol + } + } + data, err := json.Marshal(value) + if err != nil || len(data) > 32*1024 { + return ErrLimit + } + return nil +} + +func ValidatePageValues(page PreferencePage, values map[string]interaction.Value) error { + if len(values) != len(page.Elements) { + return errors.New("page values do not match its controls") + } + for _, element := range page.Elements { + value, found := values[element.ID] + if !found { + return ErrProtocol + } + switch element.Kind { + case interaction.Entry: + limit := element.MaxLength + if limit == 0 { + limit = 8192 + } + if !validFormText(value.Text) || len([]rune(value.Text)) > limit || value.Selected != "" || value.Checked || element.Required && strings.TrimSpace(value.Text) == "" { + return ErrProtocol + } + case interaction.CheckBox: + if value.Text != "" || value.Selected != "" { + return ErrProtocol + } + case interaction.List: + valid := false + for _, item := range element.Items { + valid = valid || item.ID == value.Selected && !item.Disabled + } + if !valid || value.Text != "" || value.Checked { + return ErrProtocol + } + default: + return ErrProtocol + } + } + return nil +} + +func ValidateReaderRequest(value ReaderRequest) error { + if value.Snapshot && (value.Speech != nil || value.RestoreSpeech || value.Extensions != nil) || value.Speech != nil && value.RestoreSpeech || value.Module != "" && !value.Snapshot || len(value.Module) > 256 || !validFormText(value.Module) { + return ErrProtocol + } + if !value.Snapshot && value.Speech == nil && !value.RestoreSpeech && value.Extensions == nil { + return ErrProtocol + } + if value.Speech != nil { + if err := config.Validate(value.Speech.Apply(config.DefaultSettings())); err != nil { + return err + } + } + if value.Extensions != nil { + return ValidateExtensions(*value.Extensions) + } + return nil +} diff --git a/internal/tentaclewire/reader_test.go b/internal/tentaclewire/reader_test.go new file mode 100644 index 0000000..41f668d --- /dev/null +++ b/internal/tentaclewire/reader_test.go @@ -0,0 +1,134 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package tentaclewire + +import ( + "encoding/json" + "fmt" + "git.stormux.org/storm/cthulhu/internal/config" + "git.stormux.org/storm/cthulhu/internal/interaction" + "math" + "reflect" + "testing" +) + +func reader_test_extensions() Extensions { + return Extensions{ + Pages: []PreferencePage{{ID: "options", Title: "Reader probe", Command: "apply", Elements: []interaction.Element{ + {ID: "text", Label: "Text", Kind: interaction.Entry, Required: true, MaxLength: 32}, + {ID: "enabled", Label: "Enabled", Kind: interaction.CheckBox}, + {ID: "choice", Label: "Choice", Kind: interaction.List, Items: []interaction.Item{{ID: "first", Label: "First"}, {ID: "second", Label: "Second", Disabled: true}}}, + }, Values: map[string]interaction.Value{"text": {Text: "Initial"}, "enabled": {}, "choice": {Selected: "first"}}}}, + QuickSettings: []QuickSetting{{ID: "choice", Label: "Probe choice", Command: "apply", Options: []interaction.Item{{ID: "default", Label: "Default"}, {ID: "custom", Label: "Custom"}}, Selected: "default"}}, + } +} + +func TestReaderPageCanDescribeSixCompleteVoiceConfigurations(t *testing.T) { + page := PreferencePage{ID: "voices", Title: "Voice configurations", Command: "apply", Values: map[string]interaction.Value{}} + for profile := 1; profile <= 6; profile++ { + for field := 1; field <= 24; field++ { + id := fmt.Sprintf("profile%d.field%d", profile, field) + page.Elements = append(page.Elements, interaction.Element{ID: id, Label: fmt.Sprintf("Profile %d setting %d", profile, field), Kind: interaction.Entry, MaxLength: 64}) + page.Values[id] = interaction.Value{Text: "Example"} + } + } + if err := ValidateExtensions(Extensions{Pages: []PreferencePage{page}}); err != nil { + t.Fatal(err) + } + if _, err := interaction.NewSession(interaction.Form{Title: page.Title, Elements: page.Elements}); err == nil { + t.Fatal("native page limit leaked into internal forms") + } + state := ReaderState{Extensions: Extensions{Pages: []PreferencePage{page}}, Speech: SpeechFromSettings(config.DefaultSettings()), DefaultSpeech: SpeechFromSettings(config.DefaultSettings())} + data, err := json.Marshal(ExtensionEvent{Event: "preferences.apply", ID: page.ID, Values: page.Values, Reader: state}) + if err != nil || len(data) > 48*1024 { + t.Fatal("six configurations exceed callback budget", len(data), err) + } +} +func TestReaderExtensionsRejectInvalidSchemasAndValues(t *testing.T) { + mutations := map[string]func(*Extensions){ + "duplicate page": func(v *Extensions) { v.Pages = append(v.Pages, v.Pages[0]) }, + "duplicate setting": func(v *Extensions) { v.QuickSettings = append(v.QuickSettings, v.QuickSettings[0]) }, + "duplicate control": func(v *Extensions) { v.Pages[0].Elements = append(v.Pages[0].Elements, v.Pages[0].Elements[0]) }, + "button": func(v *Extensions) { v.Pages[0].Elements[0].Kind = interaction.Button }, + "bad label": func(v *Extensions) { v.Pages[0].Title = "Probe\npage" }, + "bad identifier": func(v *Extensions) { v.Pages[0].ID = "../page" }, + "missing value": func(v *Extensions) { delete(v.Pages[0].Values, "text") }, + "extra value": func(v *Extensions) { v.Pages[0].Values["other"] = interaction.Value{} }, + "wrong value type": func(v *Extensions) { v.Pages[0].Values["enabled"] = interaction.Value{Text: "yes"} }, + "required": func(v *Extensions) { v.Pages[0].Values["text"] = interaction.Value{} }, + "oversized": func(v *Extensions) { + v.Pages[0].Values["text"] = interaction.Value{Text: "This string is longer than thirty-two characters"} + }, + "control character": func(v *Extensions) { v.Pages[0].Values["text"] = interaction.Value{Text: "bad\x1bvalue"} }, + "disabled choice": func(v *Extensions) { v.Pages[0].Values["choice"] = interaction.Value{Selected: "second"} }, + "unknown quick choice": func(v *Extensions) { v.QuickSettings[0].Selected = "missing" }, + "disabled quick choice": func(v *Extensions) { v.QuickSettings[0].Options[0].Disabled = true }, + } + if err := ValidateExtensions(reader_test_extensions()); err != nil { + t.Fatal(err) + } + for name, mutate := range mutations { + t.Run(name, func(t *testing.T) { + value := reader_test_extensions() + mutate(&value) + if ValidateExtensions(value) == nil { + t.Fatal("accepted invalid extension") + } + }) + } +} +func TestReaderSpeechConfigurationRoundTripAndIsolation(t *testing.T) { + settings := config.DefaultSettings() + rate, pitch, gain := 72.0, 6.2, 8.1 + settings.DefaultVoice = config.Voice{Rate: &rate, AveragePitch: &pitch, Gain: &gain, Family: &config.VoiceFamily{Name: "Example voice", Lang: "en", Dialect: "US", Variant: "sample"}} + settings.UppercaseVoice = config.Voice{AveragePitch: &pitch} + settings.HyperlinkVoice = config.Voice{Rate: &rate} + settings.SystemVoice = config.Voice{Gain: &gain} + settings.UseCustomEchoVoice = true + settings.EchoVoice = config.Voice{Rate: &rate} + base := config.DefaultSettings() + base.EnableSpeech = false + base.EnableBraille = true + result := SpeechFromSettings(settings).Apply(base) + if !reflect.DeepEqual(SpeechFromSettings(result), SpeechFromSettings(settings)) { + t.Fatal("voice settings lost") + } + if result.EnableSpeech || !result.EnableBraille || result.KeyboardLayout != base.KeyboardLayout { + t.Fatal("unrelated settings changed") + } + value := SpeechFromSettings(settings) + value.DefaultVoice.Rate = new(float64) + *value.DefaultVoice.Rate = math.NaN() + if ValidateReaderRequest(ReaderRequest{Speech: &value}) == nil { + t.Fatal("accepted NaN") + } +} +func TestReaderInteractionValidation(t *testing.T) { + for _, raw := range []string{ + `{"reader":{"snapshot":true},"next":"receive"}`, + `{"reader":{"restore_speech":true}}`, + `{"reader":{"extensions":{}}}`, + } { + if _, err := DecodeInteraction([]byte(raw)); err != nil { + t.Fatal(raw, err) + } + } + for _, raw := range []string{ + `{"reader":{"snapshot":true}}`, + `{"reader":{"snapshot":true,"restore_speech":true},"next":"receive"}`, + `{"reader":{"restore_speech":true},"clipboard":"value"}`, + `{"reader":{"restore_speech":true},"done":true}`, + `{"reader":{"module":"example"}}`, + `{"reader":{"restore_speech":true,"unknown":true}}`, + `{"reader":null}`, + } { + if _, err := DecodeInteraction([]byte(raw)); err == nil { + t.Fatal("accepted", raw) + } + } + value := reader_test_extensions() + data, _ := json.Marshal(Interaction{Reader: &ReaderRequest{Extensions: &value}}) + if _, err := DecodeInteraction(data); err != nil { + t.Fatal(err) + } +} diff --git a/internal/tentaclewire/wire.go b/internal/tentaclewire/wire.go new file mode 100644 index 0000000..7e2a186 --- /dev/null +++ b/internal/tentaclewire/wire.go @@ -0,0 +1,106 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package tentaclewire shares bounded framing between the host and Go SDK. +package tentaclewire + +import ( + "bufio" + "bytes" + "encoding/json" + "errors" + "io" + "unicode/utf8" +) + +const MaxFrameBytes = 64 * 1024 + +var ErrProtocol = errors.New("invalid tentacle protocol message") +var ErrLimit = errors.New("tentacle resource limit exceeded") + +// ReadFrame bounds allocation even when the child never writes a newline. +func ReadFrame(reader *bufio.Reader) ([]byte, error) { + var frame []byte + for { + part, err := reader.ReadSlice('\n') + if len(frame)+len(part) > MaxFrameBytes+1 { + return nil, ErrLimit + } + frame = append(frame, part...) + if err == nil { + return frame[:len(frame)-1], nil + } + if errors.Is(err, bufio.ErrBufferFull) { + continue + } + if errors.Is(err, io.EOF) && len(frame) != 0 { + return nil, io.ErrUnexpectedEOF + } + return nil, err + } +} + +// Reject duplicate keys and excessive nesting, including in command arguments +// and results. Different languages must not interpret the same frame differently. +func ValidateJSON(data []byte) error { + if !utf8.Valid(data) { + return ErrProtocol + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.UseNumber() + if err := validate_value(decoder, 0); err != nil { + return ErrProtocol + } + if _, err := decoder.Token(); err != io.EOF { + return ErrProtocol + } + return nil +} + +func validate_value(decoder *json.Decoder, depth int) error { + if depth > 32 { + return ErrLimit + } + token, err := decoder.Token() + if err != nil { + return err + } + delimiter, composite := token.(json.Delim) + if !composite { + return nil + } + if delimiter != '{' && delimiter != '[' { + return ErrProtocol + } + keys := map[string]bool{} + for decoder.More() { + if delimiter == '{' { + keyToken, err := decoder.Token() + if err != nil { + return err + } + key, ok := keyToken.(string) + if !ok || keys[key] { + return ErrProtocol + } + keys[key] = true + } + if err := validate_value(decoder, depth+1); err != nil { + return err + } + } + _, err = decoder.Token() + return err +} + +func DecodeStrict(data []byte, target any) error { + if err := ValidateJSON(data); err != nil { + return err + } + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(target); err != nil { + return ErrProtocol + } + return nil +} diff --git a/internal/version/build.go b/internal/version/build.go new file mode 100644 index 0000000..9434cc6 --- /dev/null +++ b/internal/version/build.go @@ -0,0 +1,43 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package version + +import ( + "runtime" + "runtime/debug" +) + +// Identity describes the executable itself, without consulting a checkout that +// may have changed since it was built. Missing VCS stamps remain explicit. +type Identity struct { + GoVersion string `json:"go_version"` + Revision string `json:"vcs_revision"` + Time string `json:"vcs_time"` + Modified string `json:"vcs_modified"` +} + +func RuntimeIdentity() Identity { + info, _ := debug.ReadBuildInfo() + return build_identity(info) +} + +func build_identity(info *debug.BuildInfo) Identity { + identity := Identity{GoVersion: runtime.Version(), Revision: "unknown", Time: "unknown", Modified: "unknown"} + if info == nil { + return identity + } + identity.GoVersion = info.GoVersion + for _, setting := range info.Settings { + switch setting.Key { + case "vcs.revision": + identity.Revision = setting.Value + case "vcs.time": + identity.Time = setting.Value + case "vcs.modified": + identity.Modified = setting.Value + } + } + return identity +} diff --git a/internal/version/build_test.go b/internal/version/build_test.go new file mode 100644 index 0000000..4531f7d --- /dev/null +++ b/internal/version/build_test.go @@ -0,0 +1,28 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package version + +import ( + "runtime/debug" + "testing" +) + +func TestBuildIdentityUsesEmbeddedSettings(t *testing.T) { + info := &debug.BuildInfo{GoVersion: "go1.24.0", Settings: []debug.BuildSetting{ + {Key: "vcs.revision", Value: "0123456789abcdef"}, + {Key: "vcs.time", Value: "2026-10-16T12:00:00Z"}, + {Key: "vcs.modified", Value: "true"}, + }} + identity := build_identity(info) + if identity != (Identity{"go1.24.0", "0123456789abcdef", "2026-10-16T12:00:00Z", "true"}) { + t.Fatalf("embedded build identity = %+v", identity) + } + for _, info := range []*debug.BuildInfo{nil, {GoVersion: "go1.24.0"}} { + identity := build_identity(info) + if identity.GoVersion == "" || identity.Revision != "unknown" || identity.Time != "unknown" || identity.Modified != "unknown" { + t.Fatalf("unstamped build falsely identified: %+v", identity) + } + } +} diff --git a/internal/version/version.go b/internal/version/version.go new file mode 100644 index 0000000..26e507a --- /dev/null +++ b/internal/version/version.go @@ -0,0 +1,43 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package version + +import "strings" + +const Name = "Cthulhu" + +const Version = "2026.10.24" +const Channel = "testing" + +var Build = Version + +func String() string { + return Name + " screen reader version " + Build + "-" + Channel +} + +func Details(atspiVersion, sessionType, sessionDesktop, wineVersion string) string { + details := String() + ", AT-SPI2 version: " + atspiVersion + session := strings.TrimSpace(sessionType + " " + sessionDesktop) + if session != "" { + details += ", Session: " + session + } + if wineVersion != "" { + details += ", wine-access " + wineVersion + } + return details +} diff --git a/internal/version/version_test.go b/internal/version/version_test.go new file mode 100644 index 0000000..6e543b0 --- /dev/null +++ b/internal/version/version_test.go @@ -0,0 +1,63 @@ +// Cthulhu screen reader. +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program. If not, see . + +package version + +import ( + "strings" + "testing" +) + +func TestStringIncludesBuild(t *testing.T) { + originalBuild := Build + Build = "test-build" + defer func() { Build = originalBuild }() + + if got, want := String(), "Cthulhu screen reader version test-build-"+Channel; got != want { + t.Fatalf("String() = %q, want %q", got, want) + } +} + +func TestStringUsesCurrentVersionByDefault(t *testing.T) { + if Build != Version { + t.Fatalf("Build = %q, want %q", Build, Version) + } + if got, want := String(), "Cthulhu screen reader version "+Version+"-"+Channel; got != want { + t.Fatalf("String() = %q, want %q", got, want) + } +} + +func TestDetailsIncludesATSPIAndSession(t *testing.T) { + got := Details("2.58.0", "x11", "GNOME", "") + want := "Cthulhu screen reader version " + Version + "-" + Channel + ", AT-SPI2 version: 2.58.0, Session: x11 GNOME" + if got != want { + t.Fatalf("Details() = %q, want %q", got, want) + } + if Details("2.58.0", " ", "", "") != strings.TrimSuffix(got, ", Session: x11 GNOME") { + t.Fatal("empty session information was included") + } +} + +func TestDetailsIncludesOptionalWineAccess(t *testing.T) { + base := Details("2.58.0", "x11", "GNOME", "") + if got := Details("2.58.0", "x11", "GNOME", "2026.10.24"); got != base+", wine-access 2026.10.24" { + t.Fatalf("Details() = %q", got) + } + if got := Details("2.58.0", "x11", "GNOME", ""); got != base { + t.Fatalf("missing helper changed details: %q", got) + } +} diff --git a/internal/webscripts/registry.go b/internal/webscripts/registry.go new file mode 100644 index 0000000..b56ff46 --- /dev/null +++ b/internal/webscripts/registry.go @@ -0,0 +1,72 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package webscripts owns application-specific web exceptions. It consumes +// copied semantics, never native accessibles, and does not depend on the reader. +package webscripts + +import "time" + +type Script uint8 + +const ( + Default Script = iota + Steam +) + +// MatchProcess uses the provider's verified process identity, not a page title +// or the ambiguous AT-SPI application name "Chromium". +func MatchProcess(processName string) Script { + if processName == "steamwebhelper" { + return Steam + } + return Default +} + +// Notification contains only the selected root identity and bounded content. +type Notification struct { + BusName, RootPath, Text string + WindowPath string +} + +type NotificationCandidate struct { + Role, Live, ContainerLive string +} + +func NotificationEvent(eventType string, detail int) bool { + return eventType == "object:text-changed:insert" || + eventType == "object:children-changed:add" || + eventType == "object:state-changed:showing" && detail != 0 +} + +func HandlesNotification(processName, eventType string, detail int, message *Notification) bool { + return MatchProcess(processName) == Steam && NotificationEvent(eventType, detail) && + message != nil && message.BusName != "" && message.RootPath != "" +} + +// Registry is owned by the reader's event loop. The loop owns its timer and +// presents completed messages using the shared speech/braille/history services. +type Registry struct { + steam steamNotifications +} + +func (registry *Registry) Receive(processName, eventType string, detail int, message *Notification, now time.Time) ([]string, bool) { + if !HandlesNotification(processName, eventType, detail, message) { + return nil, false + } + return registry.steam.queue(*message, now), true +} + +func (registry *Registry) Flush(now time.Time) []string { return registry.steam.flush(now) } +func (registry *Registry) Deadline() time.Time { return registry.steam.deadline() } +func (registry *Registry) Reset() { registry.steam = steamNotifications{} } + +// Retire removes delayed content whose accessible root has been destroyed. +func (registry *Registry) Retire(busName, rootPath string) { + for key, pending := range registry.steam.pending { + if key.busName == busName && (key.rootPath == rootPath || pending.windowPath == rootPath) { + delete(registry.steam.pending, key) + } + } +} diff --git a/internal/webscripts/steam.go b/internal/webscripts/steam.go new file mode 100644 index 0000000..3337d0b --- /dev/null +++ b/internal/webscripts/steam.go @@ -0,0 +1,200 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package webscripts + +import ( + "regexp" + "sort" + "strconv" + "strings" + "time" +) + +const steamNotificationDelay = 500 * time.Millisecond + +var steamRelativeTime = regexp.MustCompile(`(?i)^(?:just now|now|\d+\s+(?:second|minute|hour|day|week|month|year)s?\s+ago)$`) + +var steamShaderProgress = regexp.MustCompile(`^Processing Vulkan shaders \((\d{1,3})%\)$`) + +// ShaderProgress recognizes Steam's English shader status, which Chromium +// exposes as static text rather than an AT-SPI progress bar. Match the leaf +// only: containing sections repeat this text alongside dialog controls. +func ShaderProgress(processName, eventType, role, name string) (float64, bool) { + if MatchProcess(processName) != Steam || eventType != "object:property-change:accessible-name" || role != "static" { + return 0, false + } + match := steamShaderProgress.FindStringSubmatch(strings.TrimSpace(name)) + if match == nil { + return 0, false + } + percentage, err := strconv.Atoi(match[1]) + return float64(percentage), err == nil && percentage <= 100 +} + +// NotificationRoot mirrors Python's Steam root selection: notification/alert +// ancestors take precedence over inherited live-region attributes on a leaf. +// Candidates are ordered from the event source towards its application root. +func NotificationRoot(candidates []NotificationCandidate) int { + for index, candidate := range candidates { + if candidate.Role == "notification" || candidate.Role == "alert" { + return index + } + } + for index, candidate := range candidates { + if candidate.Live == "assertive" || candidate.Live == "polite" || + candidate.ContainerLive == "assertive" || candidate.ContainerLive == "polite" { + return index + } + } + return -1 +} + +type notificationKey struct{ busName, rootPath string } +type pendingNotification struct { + text string + windowPath string + timestampOnly bool + deadline time.Time +} +type completedNotification struct { + text string + at time.Time +} +type steamNotifications struct { + pending map[notificationKey]pendingNotification + last map[string]completedNotification +} + +func normalize(text string) string { + return strings.Join(strings.Fields(strings.ReplaceAll(text, "\ufffc", "")), " ") +} + +func contains(text, other string) bool { + text, other = strings.ToLower(text), strings.ToLower(other) + if len(other) < 4 { + return text == other + } + return strings.Contains(text, other) +} + +func appendTimestamp(text, timestamp string) string { + if strings.ContainsAny(text[len(text)-1:], ".!?") { + return text + " " + timestamp + } + return text + ". " + timestamp +} + +func (steam *steamNotifications) queue(message Notification, now time.Time) []string { + text := normalize(message.Text) + if text == "" { + return nil + } + if steam.pending == nil { + steam.pending = make(map[notificationKey]pendingNotification) + } + key := notificationKey{message.BusName, message.RootPath} + pending, exists := steam.pending[key] + timestamp := steamRelativeTime.MatchString(text) + var messages []string + if exists { + switch { + case text == pending.text: + return nil + case timestamp: + if pending.timestampOnly { + pending.text = text + } else { + pending.text = appendTimestamp(pending.text, text) + } + case pending.timestampOnly: + pending.text = appendTimestamp(text, pending.text) + pending.timestampOnly = false + case contains(text, pending.text): + pending.text = text + case contains(pending.text, text): + return nil + default: + pending.text = normalize(pending.text + " " + text) + } + } else { + // Bound outstanding roots without merging independent toasts. Finish + // the oldest root if a provider emits an excessive burst. + if len(steam.pending) >= 32 { + oldest := steam.orderedKeys()[0] + messages = steam.complete(oldest, now) + } + pending = pendingNotification{text: text, timestampOnly: timestamp} + } + // Bound accumulated fragments as well as each native capture. + characters := []rune(pending.text) + if len(characters) > 4096 { + pending.text = string(characters[:4096]) + } + pending.deadline = now.Add(steamNotificationDelay) + pending.windowPath = message.WindowPath + steam.pending[key] = pending + return messages +} + +func (steam *steamNotifications) orderedKeys() []notificationKey { + keys := make([]notificationKey, 0, len(steam.pending)) + for key := range steam.pending { + keys = append(keys, key) + } + sort.Slice(keys, func(first, second int) bool { + left, right := keys[first], keys[second] + if steam.pending[left].deadline.Equal(steam.pending[right].deadline) { + if left.busName == right.busName { + return left.rootPath < right.rootPath + } + return left.busName < right.busName + } + return steam.pending[left].deadline.Before(steam.pending[right].deadline) + }) + return keys +} + +func (steam *steamNotifications) complete(key notificationKey, now time.Time) []string { + pending := steam.pending[key] + delete(steam.pending, key) + if pending.timestampOnly { + return nil + } + last := steam.last[key.busName] + if last.text == pending.text && now.Sub(last.at) < time.Second { + return nil + } + if steam.last == nil { + steam.last = make(map[string]completedNotification) + } + for busName, completed := range steam.last { + if now.Sub(completed.at) >= time.Second { + delete(steam.last, busName) + } + } + if len(steam.last) >= 64 { + clear(steam.last) + } + steam.last[key.busName] = completedNotification{text: pending.text, at: now} + return []string{"Steam: " + pending.text} +} + +func (steam *steamNotifications) flush(now time.Time) []string { + var messages []string + for _, key := range steam.orderedKeys() { + if !steam.pending[key].deadline.After(now) { + messages = append(messages, steam.complete(key, now)...) + } + } + return messages +} + +func (steam *steamNotifications) deadline() time.Time { + keys := steam.orderedKeys() + if len(keys) == 0 { + return time.Time{} + } + return steam.pending[keys[0]].deadline +} diff --git a/internal/webscripts/steam_test.go b/internal/webscripts/steam_test.go new file mode 100644 index 0000000..0a02554 --- /dev/null +++ b/internal/webscripts/steam_test.go @@ -0,0 +1,147 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +package webscripts + +import ( + "reflect" + "testing" + "time" +) + +func TestSteamShaderProgress(t *testing.T) { + for _, step := range []struct { + process, eventType, role, name string + percentage float64 + valid bool + }{ + {"steamwebhelper", "object:property-change:accessible-name", "static", "Processing Vulkan shaders (0%)", 0, true}, + {"steamwebhelper", "object:property-change:accessible-name", "static", "Processing Vulkan shaders (37%)", 37, true}, + {"steamwebhelper", "object:property-change:accessible-name", "static", "Processing Vulkan shaders (100%)", 100, true}, + {"brave", "object:property-change:accessible-name", "static", "Processing Vulkan shaders (37%)", 0, false}, + {"Chromium", "object:property-change:accessible-name", "static", "Processing Vulkan shaders (37%)", 0, false}, + {"steamwebhelper", "object:property-change:accessible-name", "section", "Processing Vulkan shaders (37%) SKIP", 0, false}, + {"steamwebhelper", "object:state-changed:focused", "static", "Processing Vulkan shaders (37%)", 0, false}, + {"steamwebhelper", "object:property-change:accessible-name", "static", "Download (37%)", 0, false}, + {"steamwebhelper", "object:property-change:accessible-name", "static", "Processing Vulkan shaders (101%)", 0, false}, + {"steamwebhelper", "object:property-change:accessible-name", "static", "Processing Vulkan shaders (-1%)", 0, false}, + } { + percentage, valid := ShaderProgress(step.process, step.eventType, step.role, step.name) + if valid != step.valid || valid && percentage != step.percentage { + t.Fatalf("%+v: percentage=%g valid=%t", step, percentage, valid) + } + } +} + +func TestSteamNotificationMatchingAndRoot(t *testing.T) { + message := &Notification{BusName: ":1.42", RootPath: "/toast", Text: "Username is now online"} + for _, process := range []string{"Chromium", "chromium", "brave", "", "steamwebhelper.exe"} { + if HandlesNotification(process, "object:text-changed:insert", 0, message) { + t.Fatalf("enabled Steam for %q", process) + } + } + for _, event := range []struct { + typeName string + detail int + want bool + }{ + {"object:text-changed:insert", 0, true}, + {"object:children-changed:add", 0, true}, + {"object:state-changed:showing", 1, true}, + {"object:state-changed:showing", 0, false}, + {"object:state-changed:focused", 1, false}, + } { + if got := HandlesNotification("steamwebhelper", event.typeName, event.detail, message); got != event.want { + t.Fatalf("%s/%d: %t", event.typeName, event.detail, got) + } + } + candidates := []NotificationCandidate{{ContainerLive: "assertive"}, {Role: "alert"}} + if index := NotificationRoot(candidates); index != 1 { + t.Fatalf("selected live leaf instead of alert ancestor: %d", index) + } + if index := NotificationRoot([]NotificationCandidate{{Live: "off"}, {Live: "polite"}}); index != 1 { + t.Fatalf("live root = %d", index) + } + if index := NotificationRoot([]NotificationCandidate{{Live: "off"}}); index != -1 { + t.Fatalf("non-live root = %d", index) + } +} + +func TestSteamNotificationCoalescing(t *testing.T) { + for _, test := range []struct { + name string + fragments []string + want []string + }{ + {"fragments", []string{" Username ", "Playing: Example Game"}, []string{"Steam: Username Playing: Example Game"}}, + {"timestamp after", []string{"Username is now online", "2 minutes ago"}, []string{"Steam: Username is now online. 2 minutes ago"}}, + {"timestamp before", []string{"2 minutes ago", "Username is now online"}, []string{"Steam: Username is now online. 2 minutes ago"}}, + {"complete replaces fragment", []string{"Username", "Username is now online", "Username"}, []string{"Steam: Username is now online"}}, + {"repeated complete", []string{"Username is now online", "Username is now online"}, []string{"Steam: Username is now online"}}, + {"timestamp only", []string{"just now"}, nil}, + {"empty", []string{"", " \ufffc "}, nil}, + } { + t.Run(test.name, func(t *testing.T) { + var registry Registry + now := time.Unix(100, 0) + for _, text := range test.fragments { + messages, handled := registry.Receive("steamwebhelper", "object:text-changed:insert", 0, + &Notification{BusName: ":1.42", RootPath: "/toast", Text: text}, now) + if !handled || len(messages) != 0 { + t.Fatalf("fragment presented early: %q, handled %t", messages, handled) + } + } + if got := registry.Flush(now.Add(499 * time.Millisecond)); len(got) != 0 { + t.Fatalf("presented before deadline: %q", got) + } + if got := registry.Flush(now.Add(500 * time.Millisecond)); !reflect.DeepEqual(got, test.want) { + t.Fatalf("messages = %q, want %q", got, test.want) + } + if !registry.Deadline().IsZero() { + t.Fatal("completed timer still armed") + } + }) + } +} + +func TestSteamNotificationDeduplicationAndOwnership(t *testing.T) { + var registry Registry + now := time.Unix(100, 0) + queue := func(bus, root, text string, at time.Time) { + registry.Receive("steamwebhelper", "object:text-changed:insert", 0, + &Notification{BusName: bus, RootPath: root, Text: text, WindowPath: "/window"}, at) + } + queue(":1.42", "/first", "Username is now online", now) + if got := registry.Flush(now.Add(500 * time.Millisecond)); len(got) != 1 { + t.Fatalf("initial message: %q", got) + } + queue(":1.42", "/first", "Username is now online", now.Add(600*time.Millisecond)) + if got := registry.Flush(now.Add(1100 * time.Millisecond)); len(got) != 0 { + t.Fatalf("duplicate within one second: %q", got) + } + queue(":1.42", "/first", "Username is now online", now.Add(time.Second)) + if got := registry.Flush(now.Add(1500 * time.Millisecond)); len(got) != 1 { + t.Fatalf("new message after one second: %q", got) + } + queue(":1.42", "/first", "Username", now.Add(2*time.Second)) + queue(":1.42", "/second", "Playing: Example Game", now.Add(2*time.Second)) + queue(":1.43", "/first", "2 minutes ago", now.Add(2*time.Second)) + if got := registry.Flush(now.Add(2500 * time.Millisecond)); !reflect.DeepEqual(got, []string{"Steam: Username", "Steam: Playing: Example Game"}) { + t.Fatalf("independent roots combined: %q", got) + } + queue(":1.42", "/first", "retired message", now.Add(3*time.Second)) + registry.Retire(":1.43", "/window") + if registry.Deadline().IsZero() { + t.Fatal("other bus retired pending toast") + } + registry.Retire(":1.42", "/window") + if got := registry.Flush(now.Add(4 * time.Second)); len(got) != 0 { + t.Fatalf("destroyed window presented: %q", got) + } + queue(":1.42", "/first", "locked message", now) + registry.Reset() + if got := registry.Flush(now.Add(time.Second)); len(got) != 0 { + t.Fatalf("reset presented pending content: %q", got) + } +} diff --git a/internal/wine/diagnostics.go b/internal/wine/diagnostics.go new file mode 100644 index 0000000..cf29ed7 --- /dev/null +++ b/internal/wine/diagnostics.go @@ -0,0 +1,160 @@ +package wine + +import ( + "encoding/json" + "log/slog" + "strings" + "sync/atomic" + "time" +) + +const diagnosticLineLimit = 4096 + +// helperDiagnostics is written only by os/exec's stderr copier. It drains +// arbitrary Wine output without waiting for the log sink. Each helper gets a +// bounded line buffer, queue and rate window. After cmd.Wait, its logging +// worker drains the remaining records independently of process shutdown. +type helperDiagnostics struct { + lines chan string + done chan struct{} + partial []byte + overlong bool + window time.Time + seen map[string]bool + suppressed atomic.Uint64 +} + +func newHelperDiagnostics() *helperDiagnostics { + return &helperDiagnostics{ + lines: make(chan string, 64), done: make(chan struct{}), + seen: make(map[string]bool), + } +} + +func (output *helperDiagnostics) Write(data []byte) (int, error) { + for _, char := range data { + if char == '\n' { + if output.overlong { + output.suppressed.Add(1) + } else { + output.queueLine(string(output.partial)) + } + output.partial = output.partial[:0] + output.overlong = false + } else if !output.overlong { + if len(output.partial) == diagnosticLineLimit { + output.overlong = true + output.partial = output.partial[:0] + } else { + output.partial = append(output.partial, char) + } + } + } + return len(data), nil +} + +func (output *helperDiagnostics) queueLine(line string) { + line = strings.TrimSuffix(line, "\r") + // Do not mix arbitrary Wine/application stderr into reader diagnostics. + if !strings.HasPrefix(line, "wine-access: ") { + return + } + now := time.Now() + if now.Sub(output.window) >= 10*time.Second { + output.window = now + clear(output.seen) + } + if output.seen[line] || len(output.seen) >= 32 { + output.suppressed.Add(1) + return + } + output.seen[line] = true + select { + case output.lines <- strings.TrimPrefix(line, "wine-access: "): + default: + output.suppressed.Add(1) + } +} + +// finish is called after Wait has stopped the stderr copier, including its +// WaitDelay deadline. It never waits for a slow log sink during helper shutdown. +func (output *helperDiagnostics) finish() { + if output.overlong { + output.suppressed.Add(1) + } else if len(output.partial) != 0 { + output.queueLine(string(output.partial)) + } + close(output.lines) +} + +func (output *helperDiagnostics) logRecords(logger *slog.Logger) { + defer close(output.done) + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + reportSuppressed := func() { + if count := output.suppressed.Swap(0); count != 0 { + logger.Warn("Wine helper diagnostics suppressed", "count", count) + } + } + for { + select { + case line, open := <-output.lines: + if !open { + reportSuppressed() + return + } + logHelperRecord(logger, line) + case <-ticker.C: + reportSuppressed() + } + } +} + +func logHelperRecord(logger *slog.Logger, line string) { + if body, found := strings.CutPrefix(line, "identity "); found { + var identity struct { + Version string `json:"version"` + Revision string `json:"revision"` + Modified bool `json:"modified"` + } + if err := json.Unmarshal([]byte(body), &identity); err != nil || identity.Version == "" || identity.Revision == "" { + logger.Warn("Invalid Wine helper identity record") + return + } + logger.Info("Wine accessibility helper identity", "version", identity.Version, + "revision", identity.Revision, "modified", identity.Modified) + return + } + if body, found := strings.CutPrefix(line, "ready "); found { + var status struct { + Reader string `json:"reader"` + ControlsEnabled bool `json:"controls_enabled"` + Controller bool `json:"controller"` + Review bool `json:"review"` + MSAAWorker bool `json:"msaa_worker"` + WinEvents bool `json:"win_events"` + MenuHook bool `json:"menu_hook"` + InputHook bool `json:"input_hook"` + Host32Started bool `json:"host32_started"` + ControlPoll bool `json:"control_poll"` + } + if err := json.Unmarshal([]byte(body), &status); err != nil || status.Reader == "" { + logger.Warn("Invalid Wine helper initialization record") + return + } + logger.Info("Wine accessibility helper initialized", "reader", status.Reader, + "controls_enabled", status.ControlsEnabled, "controller", status.Controller, + "review", status.Review, "msaa_worker", status.MSAAWorker, + "win_events", status.WinEvents, "menu_hook", status.MenuHook, + "input_hook", status.InputHook, "host32_started", status.Host32Started, + "control_poll", status.ControlPoll) + return + } + if strings.HasPrefix(line, "reader event replies resumed after ") || + line == "another helper already owns this Wine desktop" || + line == "disabled by command-line options" { + logger.Info("Wine accessibility helper diagnostic", "diagnostic", line) + } else { + logger.Warn("Wine accessibility helper diagnostic", "diagnostic", line) + } +} diff --git a/internal/wine/diagnostics_test.go b/internal/wine/diagnostics_test.go new file mode 100644 index 0000000..f9b4968 --- /dev/null +++ b/internal/wine/diagnostics_test.go @@ -0,0 +1,167 @@ +package wine + +import ( + "bytes" + "context" + "encoding/json" + "log/slog" + "os" + "path/filepath" + "strings" + "testing" + "time" +) + +func TestHelperDiagnosticsHandlesSplitOversizedAndUnrelatedOutput(t *testing.T) { + var log bytes.Buffer + output := newHelperDiagnostics() + go output.logRecords(slog.New(slog.NewJSONHandler(&log, nil))) + for _, chunk := range []string{ + "unrelated application text\nwine-acc", "ess: identity {\"version\":\"2026.10.15\",", + "\"revision\":\"abc123\",\"modified\":true}\r\n", + "wine-access: " + strings.Repeat("private", diagnosticLineLimit) + "\n", + "wine-access: ready {broken}\n", + "wine-access: ready {\"reader\":\"org.example.Reader\",\"controls_enabled\":true,\"control_poll\":true}\n", + "wine-access: native input hook unavailable", + } { + if count, err := output.Write([]byte(chunk)); err != nil || count != len(chunk) { + t.Fatalf("stderr write = (%d, %v)", count, err) + } + } + output.finish() + <-output.done + text := log.String() + for _, want := range []string{ + `"version":"2026.10.15"`, `"revision":"abc123"`, `"modified":true`, + `"msg":"Wine accessibility helper initialized"`, `"control_poll":true`, + "Invalid Wine helper initialization record", "native input hook unavailable", + "Wine helper diagnostics suppressed", + } { + if !strings.Contains(text, want) { + t.Errorf("missing %q in %s", want, text) + } + } + for _, unwanted := range []string{"unrelated application text", "private", "{broken}"} { + if strings.Contains(text, unwanted) { + t.Errorf("unexpected output %q in log", unwanted) + } + } + for _, line := range strings.Split(strings.TrimSpace(text), "\n") { + if !json.Valid([]byte(line)) { + t.Errorf("invalid log record: %s", line) + } + } +} + +func TestHelperDiagnosticsBoundsFloodAndRecoversNextWindow(t *testing.T) { + var log bytes.Buffer + output := newHelperDiagnostics() + // With no consumer, writes must still finish after filling the queue. + for i := 0; i < 1000; i++ { + output.Write([]byte("wine-access: repeated failure\n")) + output.Write([]byte("wine-access: failure " + strings.Repeat("x", i) + "\n")) + } + if len(output.lines) > 32 { + t.Fatalf("diagnostic burst queued %d records", len(output.lines)) + } + output.window = time.Now().Add(-11 * time.Second) + output.Write([]byte("wine-access: reader event replies resumed after 2 failed calls\n")) + output.finish() + go output.logRecords(slog.New(slog.NewJSONHandler(&log, nil))) + <-output.done + if strings.Count(log.String(), `"diagnostic":"repeated failure"`) != 1 { + t.Fatalf("repeated failure was not coalesced: %s", log.String()) + } + if !strings.Contains(log.String(), "reader event replies resumed") || !strings.Contains(log.String(), `"count":1968`) { + t.Fatalf("missing recovery or suppression count: %s", log.String()) + } +} + +func TestManagerCapturesActualHelperDiagnosticsAndBoundsInheritedStderr(t *testing.T) { + root := t.TempDir() + helper := filepath.Join(root, "helper") + // Leave a descendant holding stderr after the helper exits. WaitDelay must + // retire the copier without waiting for the descendant. + script := "#!/bin/sh\necho 'wine-access: identity {\"version\":\"2026.10.15\",\"revision\":\"abc123\",\"modified\":false}' >&2\n" + + "echo 'wine-access: native menu hook unavailable (error 126)' >&2\n" + + "sleep 2 &\nexit 0\n" + if err := os.WriteFile(helper, []byte(script), 0700); err != nil { + t.Fatal(err) + } + handler := &channelLogHandler{records: make(chan slog.Record, 32)} + manager := &Manager{helper: helper, logger: slog.New(handler)} + child := &process{} + started := time.Now() + if err := manager.launch(child, prefix{path: root}, started); err != nil { + t.Fatal(err) + } + select { + case <-child.done: + case <-time.After(time.Second): + t.Fatal("inherited stderr kept helper shutdown waiting") + } + identity, diagnostic := false, false + deadline := time.After(time.Second) + for !identity || !diagnostic { + select { + case record := <-handler.records: + record.Attrs(func(attr slog.Attr) bool { + identity = identity || attr.Key == "revision" && attr.Value.String() == "abc123" + diagnostic = diagnostic || attr.Key == "diagnostic" && strings.Contains(attr.Value.String(), "native menu hook unavailable") + return true + }) + case <-deadline: + t.Fatal("helper diagnostics missing") + } + } +} + +func TestManagerExpectedStopIsNotAHelperFailure(t *testing.T) { + helper := filepath.Join(t.TempDir(), "helper") + if err := os.WriteFile(helper, []byte("#!/bin/sh\nexec sleep 30\n"), 0700); err != nil { + t.Fatal(err) + } + handler := &channelLogHandler{records: make(chan slog.Record, 32)} + manager := &Manager{helper: helper, logger: slog.New(handler)} + child := &process{} + if err := manager.launch(child, prefix{path: t.TempDir()}, time.Now()); err != nil { + t.Fatal(err) + } + stop(child) + for { + select { + case record := <-handler.records: + if record.Message != "Wine accessibility helper exited" { + continue + } + if record.Level != slog.LevelInfo { + t.Fatalf("expected stop logged as failure: %v", record) + } + return + default: + t.Fatal("missing helper exit record") + } + } +} + +type channelLogHandler struct { + records chan slog.Record + attrs []slog.Attr +} + +func (handler *channelLogHandler) Enabled(_ context.Context, level slog.Level) bool { + return level >= slog.LevelInfo +} + +func (handler *channelLogHandler) Handle(_ context.Context, record slog.Record) error { + record = record.Clone() + record.AddAttrs(handler.attrs...) + handler.records <- record + return nil +} + +func (handler *channelLogHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + return &channelLogHandler{records: handler.records, attrs: append(append([]slog.Attr{}, handler.attrs...), attrs...)} +} + +func (handler *channelLogHandler) WithGroup(string) slog.Handler { return handler } diff --git a/internal/wine/manager.go b/internal/wine/manager.go new file mode 100644 index 0000000..5e2f6d1 --- /dev/null +++ b/internal/wine/manager.go @@ -0,0 +1,355 @@ +// Package wine supervises the optional installed Wine Access accessibility +// helper. Native Wine objects stay in that process; Go receives D-Bus messages. +package wine + +import ( + "context" + "errors" + "log/slog" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "sync/atomic" + "syscall" + "time" +) + +const managedKey = "CTHULHU_WINE_ACCESS_MANAGED" + +type prefix struct { + path, loader string + environment map[string]string +} + +type process struct { + cmd *exec.Cmd + done chan struct{} + started time.Time + seen time.Time + failures int + next time.Time + stopping atomic.Bool +} + +type Manager struct { + logger *slog.Logger + helper string + procRoot string + cancel context.CancelFunc + done chan struct{} +} + +func New(logger *slog.Logger) *Manager { + if logger == nil { + logger = slog.New(slog.DiscardHandler) + } + return &Manager{logger: logger, helper: helperPath(), procRoot: "/proc"} +} + +func helperPath() string { + return findHelper([]string{ + filepath.Join(os.Getenv("HOME"), ".local", "libexec", "wine-access", "wine-access.exe"), + filepath.Join(os.Getenv("HOME"), ".local", "libexec", "cthulhu", "wine", "cthulhu-wine-access.exe"), + "/usr/local/libexec/wine-access/wine-access.exe", + "/usr/libexec/wine-access/wine-access.exe", + "/usr/libexec/cthulhu/wine/cthulhu-wine-access.exe", + }) +} + +func findHelper(candidates []string) string { + if path := os.Getenv("CTHULHU_WINE_ACCESS_HELPER"); executable(path) { + return path + } + for _, path := range candidates { + if executable(path) { + return path + } + } + for _, name := range []string{"wine-access.exe", "cthulhu-wine-access.exe"} { + if path, err := exec.LookPath(name); err == nil { + return path + } + } + return "" +} + +func executable(path string) bool { + if path == "" { + return false + } + info, err := os.Stat(path) + return err == nil && info.Mode().IsRegular() && info.Mode().Perm()&0111 != 0 +} + +func (manager *Manager) Start(ctx context.Context) error { + if manager.helper == "" { + manager.logger.Info("Wine accessibility helper unavailable") + return nil + } + if manager.cancel != nil { + return errors.New("Wine accessibility manager already started") + } + workerCtx, cancel := context.WithCancel(ctx) + manager.cancel = cancel + manager.done = make(chan struct{}) + go manager.run(workerCtx) + return nil +} + +func (manager *Manager) Stop(ctx context.Context) error { + if manager.cancel == nil { + return nil + } + manager.cancel() + select { + case <-manager.done: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +func (manager *Manager) run(ctx context.Context) { + defer close(manager.done) + active := make(map[string]*process) + ticker := time.NewTicker(2 * time.Second) + defer ticker.Stop() + manager.poll(active) + for { + select { + case <-ctx.Done(): + for _, child := range active { + stop(child) + } + return + case <-ticker.C: + manager.poll(active) + } + } +} + +func (manager *Manager) poll(active map[string]*process) { + now := time.Now() + discovered := discover(manager.procRoot, uint32(os.Getuid())) + for path, source := range discovered { + child := active[path] + if child == nil { + child = &process{} + active[path] = child + } + child.seen = now + if child.cmd != nil { + select { + case <-child.done: + if now.Sub(child.started) < 10*time.Second { + child.failures++ + } else { + child.failures = 0 + } + child.next = now.Add(backoff(child.failures)) + child.cmd = nil + default: + continue + } + } + if now.Before(child.next) { + continue + } + if err := manager.launch(child, source, now); err != nil { + child.failures++ + child.next = now.Add(backoff(child.failures)) + manager.logger.Warn("start Wine accessibility helper", "error", err) + } + } + for path, child := range active { + if _, found := discovered[path]; !found && now.Sub(child.seen) >= 10*time.Second { + stop(child) + delete(active, path) + } + } +} + +func backoff(failures int) time.Duration { + if failures > 6 { + failures = 6 + } + return time.Duration(1< \"$CTHULHU_TEST_WINE_OUTPUT\"\nexec sleep 30\n" + if err := os.WriteFile(helper, []byte(script), 0700); err != nil { + t.Fatal(err) + } + manager := &Manager{logger: slog.New(slog.DiscardHandler), helper: helper, procRoot: procRoot} + if err := manager.Start(context.Background()); err != nil { + t.Fatal(err) + } + defer manager.Stop(context.Background()) + deadline := time.Now().Add(time.Second) + var contents []byte + for time.Now().Before(deadline) { + contents, _ = os.ReadFile(output) + if len(contents) != 0 { + break + } + time.Sleep(10 * time.Millisecond) + } + if string(contents) != prefixPath+"\n1\n" { + t.Fatalf("helper environment = %q", contents) + } + stopCtx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + if err := manager.Stop(stopCtx); err != nil { + t.Fatal(err) + } +} + +func TestDiscoverSteamCompatPrefix(t *testing.T) { + root := t.TempDir() + loader := filepath.Join(root, "wine") + if err := os.WriteFile(loader, []byte("#!/bin/sh\n"), 0700); err != nil { + t.Fatal(err) + } + proc := filepath.Join(root, "200") + if err := os.Mkdir(proc, 0700); err != nil { + t.Fatal(err) + } + if err := os.Symlink(loader, filepath.Join(proc, "exe")); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(proc, "cmdline"), []byte("application.exe\x00"), 0600); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(proc, "environ"), []byte(strings.Join([]string{ + "STEAM_COMPAT_DATA_PATH=" + root, "WINELOADER=" + loader, ""}, "\x00")), 0600); err != nil { + t.Fatal(err) + } + got := discover(root, uint32(os.Getuid())) + selected := got[filepath.Join(root, "pfx")] + if selected.loader != loader { + t.Fatalf("Steam loader = %q, want %q", selected.loader, loader) + } +} + +func TestApplicationProcessExcludesWineServices(t *testing.T) { + for _, program := range []string{"services.exe", "winedevice.exe", "svchost.exe", "plugplay.exe", "rpcss.exe", "lsass.exe", "wineboot.exe", "winemenubuilder.exe"} { + if applicationProcess("C:\\windows\\system32\\" + strings.ToUpper(program) + "\x00") { + t.Errorf("Wine service %q counted as an application", program) + } + } + for _, test := range []struct { + commandLine string + want bool + }{ + {"", false}, + {"C:\\windows\\explorer.exe\x00/desktop\x00", false}, + {"C:\\windows\\explorer.exe\x00/DESKTOP=Default,1024x768\x00", false}, + {"C:\\windows\\explorer.exe\x00C:\\documents\x00", true}, + {"C:\\Program Files\\Application\\app.exe\x00/desktop\x00", true}, + {"C:\\windows\\system32\\notepad.exe\x00", true}, + {"/usr/bin/wine\x00application.exe\x00", true}, + } { + if got := applicationProcess(test.commandLine); got != test.want { + t.Errorf("applicationProcess(%q) = %v, want %v", test.commandLine, got, test.want) + } + } +} + +func TestManagerStopsHelperWhenOnlyWineServicesRemain(t *testing.T) { + root := t.TempDir() + proc := filepath.Join(root, "101") + if err := os.Mkdir(proc, 0700); err != nil { + t.Fatal(err) + } + loader := filepath.Join(root, "wine") + helper := filepath.Join(root, "helper") + for _, path := range []string{loader, helper} { + if err := os.WriteFile(path, []byte("#!/bin/sh\nexec sleep 30\n"), 0700); err != nil { + t.Fatal(err) + } + } + if err := os.Symlink(loader, filepath.Join(proc, "exe")); err != nil { + t.Fatal(err) + } + prefixPath := filepath.Join(root, "prefix") + if err := os.WriteFile(filepath.Join(proc, "environ"), []byte("WINEPREFIX="+prefixPath+"\x00"), 0600); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(filepath.Join(proc, "cmdline"), []byte("application.exe\x00"), 0600); err != nil { + t.Fatal(err) + } + manager := &Manager{logger: slog.New(slog.DiscardHandler), helper: helper, procRoot: root} + active := make(map[string]*process) + manager.poll(active) + child := active[prefixPath] + if child == nil || child.cmd == nil { + t.Fatal("application did not start a helper") + } + defer stop(child) + if err := os.WriteFile(filepath.Join(proc, "cmdline"), []byte("C:\\windows\\system32\\winedevice.exe\x00"), 0600); err != nil { + t.Fatal(err) + } + manager.poll(active) + if child.cmd == nil { + t.Fatal("helper stopped before the idle grace period") + } + child.seen = time.Now().Add(-11 * time.Second) + manager.poll(active) + if len(active) != 0 || child.cmd != nil { + t.Fatal("Wine service kept the helper alive after the idle grace period") + } + manager.poll(active) + if len(active) != 0 { + t.Fatal("Wine service restarted the helper") + } +} diff --git a/internal/wine/review_client.go b/internal/wine/review_client.go new file mode 100644 index 0000000..53bc2d1 --- /dev/null +++ b/internal/wine/review_client.go @@ -0,0 +1,91 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package wine + +import ( + "context" + "errors" + "git.stormux.org/storm/cthulhu/internal/atspi" + "github.com/godbus/dbus/v5" + "time" +) + +func (r *ReviewRegistry) Capture(parent context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { + if !IsReviewID(id) { + return nil, ErrReviewUnavailable + } + ctx, cancel := context.WithTimeout(parent, 500*time.Millisecond) + defer cancel() + select { + case r.captureGate <- struct{}{}: + defer func() { <-r.captureGate }() + case <-ctx.Done(): + return nil, ctx.Err() + } + for attempt := 0; attempt < 2; attempt++ { + r.mutex.Lock() + p := r.providers[id.BusName] + if p == nil || p.ctx.Err() != nil || p.notice.ID() != id { + r.mutex.Unlock() + return nil, ErrReviewUnavailable + } + notice, lifetime, connection, call := p.notice, p.ctx, r.service, r.captureCall + r.mutex.Unlock() + if connection == nil && call == nil { + return nil, ErrReviewUnavailable + } + callCtx, callCancel := context.WithCancel(ctx) + stop := context.AfterFunc(lifetime, callCancel) + var fields map[string]dbus.Variant + var err error + if call != nil { + fields, err = call(callCtx, id.BusName, notice.Path, notice) + } else { + reply := connection.Object(id.BusName, notice.Path).CallWithContext(callCtx, ReviewInterface+".CaptureWindow", 0, notice.Window, notice.Focus, notice.Revision) + err = reply.Err + if err == nil { + // Store rebuilds variants from their decoded Go values and loses + // tuple signatures. Validate the original owned reply body. + if len(reply.Body) != 1 { + err = ErrReviewInvalid + } else { + var ok bool + fields, ok = reply.Body[0].(map[string]dbus.Variant) + if !ok { + err = ErrReviewInvalid + } + } + } + } + stop() + callCancel() + if err != nil { + return nil, err + } + if ctx.Err() != nil { + return nil, ctx.Err() + } + snapshot, err := DecodeReviewSnapshot(fields) + if errors.Is(err, ErrReviewStale) && attempt == 0 { + continue + } + if err != nil { + return nil, err + } + if snapshot.Instance != notice.Instance || snapshot.Window != notice.Window || snapshot.Focus != notice.Focus || snapshot.Revision != notice.Revision || snapshot.Bounds != notice.Bounds { + return nil, ErrReviewStale + } + r.mutex.Lock() + if r.providers[id.BusName] != p || p.notice != notice || lifetime.Err() != nil { + r.mutex.Unlock() + return nil, ErrReviewStale + } + tree, _, err := ApplyReviewSnapshot(p.trees[notice.Window], snapshot, id.BusName) + if err == nil { + p.trees[notice.Window] = tree + } + r.mutex.Unlock() + return tree, err + } + return nil, ErrReviewStale +} diff --git a/internal/wine/review_protocol.go b/internal/wine/review_protocol.go new file mode 100644 index 0000000..a026f1e --- /dev/null +++ b/internal/wine/review_protocol.go @@ -0,0 +1,82 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package wine + +import ( + "encoding/hex" + "errors" + "strings" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "github.com/godbus/dbus/v5" +) + +const ReviewProtocolVersion uint32 = 1 +const ReviewObjectPath dbus.ObjectPath = "/org/stormux/Cthulhu1/WineReview" +const ReviewInterface = "org.stormux.Cthulhu1.WineReview" + +var ( + ErrReviewUnavailable = errors.New("Wine review unavailable") + ErrReviewStale = errors.New("Wine review source changed") + ErrReviewBusy = errors.New("Wine review capture busy") + ErrReviewLimited = errors.New("Wine review capture exceeds limits") + ErrReviewInvalid = errors.New("invalid Wine review snapshot") +) + +// Notices are copied by the registry. Sender and Path are supplied by actual +// registration, never by native payloads. The event loop owns their eligibility. +type ReviewFocusNotice struct { + Sender string + Path dbus.ObjectPath + Instance, Window, Focus string + Revision uint64 + Title, Role string + Protected bool + Bounds atspi.Rectangle +} +type ReviewRange struct { + Start, End, UTF16Start, UTF16End uint64 + Text string + Bounds atspi.Rectangle +} +type ReviewNode struct { + ID, Parent, Role, Name string + Protected, Visible, TextKnown, CaretKnown bool + Caret, CaretUTF16 uint64 + Bounds atspi.Rectangle + Ranges []ReviewRange +} +type ReviewSnapshot struct { + Version uint32 + Instance, Window, Focus string + Revision uint64 + Status string + Bounds atspi.Rectangle + Nodes []ReviewNode +} + +func ReviewID(sender, instance, window, node string) atspi.ObjectID { + encode := func(value string) string { return hex.EncodeToString([]byte(value)) } + return atspi.NewObjectID(sender, "/wine/"+encode(instance)+"/"+encode(window)+"/"+encode(node)) +} +func IsReviewID(id atspi.ObjectID) bool { + if !id.Valid() || !strings.HasPrefix(id.BusName, ":") { + return false + } + parts := strings.Split(id.Path, "/") + if len(parts) != 5 || parts[0] != "" || parts[1] != "wine" { + return false + } + for _, part := range parts[2:] { + if part == "" || len(part) > 512 { + return false + } + if _, err := hex.DecodeString(part); err != nil { + return false + } + } + return true +} +func (notice ReviewFocusNotice) ID() atspi.ObjectID { + return ReviewID(notice.Sender, notice.Instance, notice.Window, notice.Focus) +} diff --git a/internal/wine/review_registry.go b/internal/wine/review_registry.go new file mode 100644 index 0000000..9801abd --- /dev/null +++ b/internal/wine/review_registry.go @@ -0,0 +1,228 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package wine + +import ( + "context" + "errors" + "git.stormux.org/storm/cthulhu/internal/atspi" + "git.stormux.org/storm/cthulhu/internal/sessionbus" + "github.com/godbus/dbus/v5" + "log/slog" + "sort" + "strings" + "sync" +) + +type reviewProvider struct { + path dbus.ObjectPath + notice ReviewFocusNotice + ctx context.Context + cancel context.CancelFunc + trees map[string]*atspi.AccessibleTree +} +type ReviewRegistry struct { + logger *slog.Logger + mutex sync.Mutex + ctx context.Context + cancel context.CancelFunc + monitor, service *dbus.Conn + signals chan *dbus.Signal + done chan struct{} + changes chan struct{} + providers map[string]*reviewProvider + captureGate chan struct{} + captureCall func(context.Context, string, dbus.ObjectPath, ReviewFocusNotice) (map[string]dbus.Variant, error) +} + +func NewReviewRegistry(logger *slog.Logger) *ReviewRegistry { + return &ReviewRegistry{logger: logger, changes: make(chan struct{}, 1), providers: make(map[string]*reviewProvider), captureGate: make(chan struct{}, 1)} +} +func (r *ReviewRegistry) notify() { + select { + case r.changes <- struct{}{}: + default: + } +} +func (r *ReviewRegistry) Changes() <-chan struct{} { return r.changes } +func (r *ReviewRegistry) Start(ctx context.Context) error { + if ctx == nil { + return errors.New("Wine review requires a context") + } + conn, err := sessionbus.Connect(r.logger, "wine-review") + if err != nil { + return err + } + options := []dbus.MatchOption{dbus.WithMatchSender("org.freedesktop.DBus"), dbus.WithMatchInterface("org.freedesktop.DBus"), dbus.WithMatchMember("NameOwnerChanged")} + signals := make(chan *dbus.Signal, 64) + conn.Signal(signals) + if err = conn.AddMatchSignal(options...); err != nil { + conn.RemoveSignal(signals) + conn.Close() + return err + } + r.mutex.Lock() + if r.ctx != nil { + r.mutex.Unlock() + conn.RemoveSignal(signals) + conn.Close() + return errors.New("Wine review already started") + } + r.ctx, r.cancel = context.WithCancel(ctx) + r.monitor = conn + r.signals = signals + r.done = make(chan struct{}) + lifetime, done := r.ctx, r.done + r.mutex.Unlock() + go func() { + defer close(done) + for { + select { + case <-lifetime.Done(): + return + case <-conn.Context().Done(): + r.retireAll() + return + case signal := <-signals: + if signal != nil && len(signal.Body) == 3 { + name, ok := signal.Body[0].(string) + old, _ := signal.Body[1].(string) + next, _ := signal.Body[2].(string) + if ok && name == old && next == "" { + r.disappeared(name) + } + } + } + } + }() + return nil +} + +// The service connection is borrowed because native capture accepts only the +// current owner of Cthulhu's well-known name. Registry never closes it. +func (r *ReviewRegistry) BindWineReviewConnection(conn *dbus.Conn) { + r.mutex.Lock() + r.service = conn + if conn == nil { + for key, p := range r.providers { + p.cancel() + delete(r.providers, key) + } + } + r.notify() + r.mutex.Unlock() +} +func (r *ReviewRegistry) Stop(ctx context.Context) error { + r.mutex.Lock() + if r.cancel != nil { + r.cancel() + } + conn, signals, done := r.monitor, r.signals, r.done + for key, p := range r.providers { + p.cancel() + delete(r.providers, key) + } + r.ctx = nil + r.cancel = nil + r.monitor = nil + r.service = nil + r.signals = nil + r.done = nil + r.notify() + r.mutex.Unlock() + if conn != nil { + conn.RemoveSignal(signals) + conn.RemoveMatchSignal(dbus.WithMatchSender("org.freedesktop.DBus"), dbus.WithMatchInterface("org.freedesktop.DBus"), dbus.WithMatchMember("NameOwnerChanged")) + conn.Close() + } + if done != nil { + select { + case <-done: + case <-ctx.Done(): + return ctx.Err() + } + } + return nil +} +func (r *ReviewRegistry) RegisterProvider(sender string, path dbus.ObjectPath, version uint32) bool { + if !strings.HasPrefix(sender, ":") || !dbus.ObjectPath("/"+strings.ReplaceAll(sender[1:], ".", "/")).IsValid() || path != ReviewObjectPath || version != ReviewProtocolVersion { + return false + } + r.mutex.Lock() + defer r.mutex.Unlock() + if r.ctx == nil || r.ctx.Err() != nil { + return false + } + if old := r.providers[sender]; old != nil { + old.cancel() + } + ctx, cancel := context.WithCancel(r.ctx) + r.providers[sender] = &reviewProvider{path: path, ctx: ctx, cancel: cancel, trees: make(map[string]*atspi.AccessibleTree)} + r.notify() + return true +} +func (r *ReviewRegistry) PresentFocus(sender string, notice ReviewFocusNotice) bool { + if !reviewString(notice.Instance, 256, false) || !reviewString(notice.Window, 256, false) || !reviewString(notice.Focus, 256, false) || notice.Revision == 0 || !reviewString(notice.Title, 4096, true) || !reviewString(notice.Role, 4096, false) || !notice.Bounds.Valid() { + return false + } + r.mutex.Lock() + defer r.mutex.Unlock() + p := r.providers[sender] + if p == nil || p.ctx.Err() != nil { + return false + } + notice.Sender = sender + notice.Path = p.path + if p.notice == notice { + return true + } + if p.notice.Instance == notice.Instance && p.notice.Revision > notice.Revision { + return false + } + if p.notice.Instance != notice.Instance || p.notice.Window != notice.Window { + // Only the active native window can be captured. Retiring older + // windows bounds retained text and preserves the current tree's identity. + p.trees = make(map[string]*atspi.AccessibleTree) + } + p.cancel() + p.ctx, p.cancel = context.WithCancel(r.ctx) + p.notice = notice + r.notify() + return true +} +func (r *ReviewRegistry) Focuses() []ReviewFocusNotice { + r.mutex.Lock() + defer r.mutex.Unlock() + var notices []ReviewFocusNotice + for _, p := range r.providers { + if p.notice.Focus != "" && p.ctx.Err() == nil { + notices = append(notices, p.notice) + } + } + sort.Slice(notices, func(i, j int) bool { return notices[i].Sender < notices[j].Sender }) + return notices +} +func (r *ReviewRegistry) Current(id atspi.ObjectID) bool { + r.mutex.Lock() + defer r.mutex.Unlock() + p := r.providers[id.BusName] + return IsReviewID(id) && p != nil && p.ctx.Err() == nil && p.notice.ID() == id +} +func (r *ReviewRegistry) disappeared(sender string) { + r.mutex.Lock() + defer r.mutex.Unlock() + if p := r.providers[sender]; p != nil { + p.cancel() + delete(r.providers, sender) + r.notify() + } +} +func (r *ReviewRegistry) retireAll() { + r.mutex.Lock() + defer r.mutex.Unlock() + for sender, p := range r.providers { + p.cancel() + delete(r.providers, sender) + } + r.notify() +} diff --git a/internal/wine/review_registry_test.go b/internal/wine/review_registry_test.go new file mode 100644 index 0000000..6ead358 --- /dev/null +++ b/internal/wine/review_registry_test.go @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package wine + +import ( + "context" + "errors" + "fmt" + "git.stormux.org/storm/cthulhu/internal/atspi" + "github.com/godbus/dbus/v5" + "testing" + "time" +) + +func TestReviewRegistryRetiresInactiveWindowTrees(t *testing.T) { + r := readyReviewRegistry(t) + n := registerNotice(t, r, ":1.2") + r.captureCall = func(_ context.Context, _ string, _ dbus.ObjectPath, notice ReviewFocusNotice) (map[string]dbus.Variant, error) { + f := reviewWire() + f["window"] = dbus.MakeVariant(notice.Window) + f["revision"] = dbus.MakeVariant(notice.Revision) + nodes := f["nodes"].Value().([]map[string]dbus.Variant) + nodes[0]["id"] = dbus.MakeVariant(notice.Window) + for _, node := range nodes[1:] { + if node["parent"].Value() == "window" { + node["parent"] = dbus.MakeVariant(notice.Window) + } + } + return f, nil + } + for i := 1; i <= 32; i++ { + n.Window = fmt.Sprintf("window%d", i) + n.Revision = uint64(i) + if !r.PresentFocus(n.Sender, n) { + t.Fatal("focus rejected") + } + one, err := r.Capture(context.Background(), n.ID()) + if err != nil { + t.Fatal(err) + } + two, err := r.Capture(context.Background(), n.ID()) + if err != nil || one != two { + t.Fatal("active window tree is not stable") + } + if len(r.providers[n.Sender].trees) != 1 { + t.Fatalf("retained %d inactive trees", len(r.providers[n.Sender].trees)-1) + } + } +} + +func registryNotice(sender string) ReviewFocusNotice { + return ReviewFocusNotice{Sender: sender, Path: ReviewObjectPath, Instance: "helper-instance", Window: "window", Focus: "input", Revision: 1, Title: "same title", Role: "window", Bounds: atspi.Rectangle{X: 10, Y: 20, Width: 400, Height: 300}} +} +func readyReviewRegistry(t *testing.T) *ReviewRegistry { + t.Helper() + registry := NewReviewRegistry(nil) + // Unit tests substitute transport only; registration still requires lifecycle. + registry.ctx, registry.cancel = context.WithCancel(context.Background()) + t.Cleanup(func() { registry.Stop(context.Background()) }) + return registry +} +func registerNotice(t *testing.T, r *ReviewRegistry, sender string) ReviewFocusNotice { + t.Helper() + notice := registryNotice(sender) + if !r.RegisterProvider(sender, ReviewObjectPath, 1) || !r.PresentFocus(sender, notice) { + t.Fatal("registration rejected") + } + return notice +} +func TestReviewRegistryTwoProviders(t *testing.T) { + r := readyReviewRegistry(t) + one := registerNotice(t, r, ":1.2") + two := registerNotice(t, r, ":1.3") + if one.ID() == two.ID() || len(r.Focuses()) != 2 || !r.Current(one.ID()) || !r.Current(two.ID()) { + t.Fatal("providers collided") + } + if len(r.changes) != 1 { + t.Fatal("notifications are not coalesced") + } + if !r.RegisterProvider(one.Sender, ReviewObjectPath, 1) || r.Current(one.ID()) || len(r.Focuses()) != 1 { + t.Fatal("registration retained old lifetime") + } +} +func TestReviewRegistrySenderAssociation(t *testing.T) { + r := readyReviewRegistry(t) + n := registryNotice(":1.2") + if r.PresentFocus(n.Sender, n) || r.RegisterProvider("well.known", ReviewObjectPath, 1) || r.RegisterProvider(n.Sender, ReviewObjectPath, 2) || r.RegisterProvider(n.Sender, "/wrong", 1) { + t.Fatal("invalid provider accepted") + } + registerNotice(t, r, n.Sender) + n.Sender = ":1.99" + n.Path = "/forged" + if !r.PresentFocus(":1.2", n) { + t.Fatal("actual sender rejected") + } + got := r.Focuses()[0] + if got.Sender != ":1.2" || got.Path != ReviewObjectPath { + t.Fatal("payload forged destination") + } + n.Revision = 0 + if r.PresentFocus(":1.2", n) { + t.Fatal("invalid focus accepted") + } +} +func TestReviewRegistryProviderDisappears(t *testing.T) { + r := readyReviewRegistry(t) + n := registerNotice(t, r, ":1.2") + r.disappeared(n.Sender) + if r.Current(n.ID()) || len(r.Focuses()) != 0 { + t.Fatal("dead provider retained") + } + if _, err := r.Capture(context.Background(), n.ID()); !errors.Is(err, ErrReviewUnavailable) { + t.Fatal(err) + } +} +func TestReviewCaptureDeadlineAndStaleReply(t *testing.T) { + r := readyReviewRegistry(t) + n := registerNotice(t, r, ":1.2") + calls := 0 + r.captureCall = func(ctx context.Context, sender string, path dbus.ObjectPath, notice ReviewFocusNotice) (map[string]dbus.Variant, error) { + calls++ + fields := reviewWire() + if calls == 1 { + fields["status"] = dbus.MakeVariant("stale") + fields["nodes"] = dbus.MakeVariant([]map[string]dbus.Variant{}) + } + return fields, nil + } + tree, err := r.Capture(context.Background(), n.ID()) + if err != nil || tree == nil || calls != 2 { + t.Fatalf("stale retry: %v calls=%d", err, calls) + } + again, err := r.Capture(context.Background(), n.ID()) + if err != nil || again != tree { + t.Fatal("capture replaced live tree") + } + r.captureCall = func(ctx context.Context, _ string, _ dbus.ObjectPath, _ ReviewFocusNotice) (map[string]dbus.Variant, error) { + <-ctx.Done() + return nil, ctx.Err() + } + started := time.Now() + if _, err = r.Capture(context.Background(), n.ID()); err == nil || time.Since(started) > 750*time.Millisecond { + t.Fatalf("deadline: %v", err) + } + r.captureCall = func(context.Context, string, dbus.ObjectPath, ReviewFocusNotice) (map[string]dbus.Variant, error) { + f := reviewWire() + f["revision"] = dbus.MakeVariant(uint64(2)) + return f, nil + } + if _, err = r.Capture(context.Background(), n.ID()); !errors.Is(err, ErrReviewStale) { + t.Fatalf("wrong source: %v", err) + } +} +func TestReviewCaptureStopCancels(t *testing.T) { + r := readyReviewRegistry(t) + n := registerNotice(t, r, ":1.2") + entered := make(chan struct{}) + done := make(chan error, 1) + r.captureCall = func(ctx context.Context, _ string, _ dbus.ObjectPath, _ ReviewFocusNotice) (map[string]dbus.Variant, error) { + close(entered) + <-ctx.Done() + return nil, ctx.Err() + } + go func() { _, err := r.Capture(context.Background(), n.ID()); done <- err }() + <-entered + r.Stop(context.Background()) + select { + case err := <-done: + if err == nil { + t.Fatal("cancelled capture accepted") + } + case <-time.After(time.Second): + t.Fatal("stop blocked") + } +} diff --git a/internal/wine/review_snapshot.go b/internal/wine/review_snapshot.go new file mode 100644 index 0000000..e62fbca --- /dev/null +++ b/internal/wine/review_snapshot.go @@ -0,0 +1,331 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package wine + +import ( + "encoding/binary" + "fmt" + "reflect" + "strings" + "unicode/utf16" + "unicode/utf8" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "github.com/godbus/dbus/v5" +) + +const maxReviewSourceUnits uint64 = 1000000 + +func reviewString(value string, limit int, empty bool) bool { + return (empty || value != "") && len(value) <= limit && utf8.ValidString(value) && !strings.ContainsRune(value, 0) +} +func reviewField(fields map[string]dbus.Variant, key, signature string, destination any) error { + value, found := fields[key] + if !found || value.Signature().String() != signature { + return fmt.Errorf("%w: field %s signature %s (expected %s)", ErrReviewInvalid, key, value.Signature(), signature) + } + if !copyReviewValue(reflect.ValueOf(destination).Elem(), reflect.ValueOf(value.Value())) { + return fmt.Errorf("%w: field %s", ErrReviewInvalid, key) + } + return nil +} + +// D-Bus tuples arrive as []interface{}. Accept that representation and typed +// producer records, but never coerce a signed integer or a different wire type. +func copyReviewValue(dst, src reflect.Value) bool { + for src.IsValid() && src.Kind() == reflect.Interface { + src = src.Elem() + } + if !src.IsValid() { + return false + } + switch dst.Kind() { + case reflect.Struct: + if src.Kind() != reflect.Struct && src.Type() != reflect.TypeOf([]any{}) { + return false + } + n := src.Len + if src.Kind() == reflect.Struct { + n = src.NumField + } + if n() != dst.NumField() { + return false + } + for i := 0; i < dst.NumField(); i++ { + var field reflect.Value + if src.Kind() == reflect.Struct { + field = src.Field(i) + } else { + field = src.Index(i) + } + if !copyReviewValue(dst.Field(i), field) { + return false + } + } + return true + case reflect.Slice: + if src.Kind() != reflect.Slice || src.Len() > 256 { + return false + } + result := reflect.MakeSlice(dst.Type(), src.Len(), src.Len()) + for i := 0; i < src.Len(); i++ { + if !copyReviewValue(result.Index(i), src.Index(i)) { + return false + } + } + dst.Set(result) + return true + default: + if src.Type() != dst.Type() { + return false + } + dst.Set(src) + return true + } +} + +func copyReviewFields(fields map[string]dbus.Variant) map[string]dbus.Variant { + copy := make(map[string]dbus.Variant, len(fields)) + for key, value := range fields { + copy[key] = value + } + return copy +} +func DecodeReviewSnapshot(fields map[string]dbus.Variant) (ReviewSnapshot, error) { + var snapshot ReviewSnapshot + if len(fields) != 8 { + return ReviewSnapshot{}, ErrReviewInvalid + } + reads := []struct { + key, signature string + destination any + }{ + {"version", "u", &snapshot.Version}, {"instance", "s", &snapshot.Instance}, {"window", "s", &snapshot.Window}, + {"focus", "s", &snapshot.Focus}, {"revision", "t", &snapshot.Revision}, {"status", "s", &snapshot.Status}, {"bounds", "(iiii)", &snapshot.Bounds}, + } + for _, read := range reads { + if err := reviewField(fields, read.key, read.signature, read.destination); err != nil { + return ReviewSnapshot{}, err + } + } + var nodes []map[string]dbus.Variant + // Check the outer shape and count before copying nested records. + value, found := fields["nodes"] + if !found || value.Signature().String() != "aa{sv}" { + return ReviewSnapshot{}, ErrReviewInvalid + } + nodes, found = value.Value().([]map[string]dbus.Variant) + if !found || len(nodes) > 4096 { + return ReviewSnapshot{}, ErrReviewInvalid + } + canonical := copyReviewFields(fields) + canonical["bounds"] = dbus.MakeVariant(snapshot.Bounds) + canonicalNodes := make([]map[string]dbus.Variant, 0, len(nodes)) + for _, fields := range nodes { + if len(fields) != 12 { + return ReviewSnapshot{}, ErrReviewInvalid + } + var node ReviewNode + reads := []struct { + key, signature string + destination any + }{ + {"id", "s", &node.ID}, {"parent", "s", &node.Parent}, {"role", "s", &node.Role}, {"name", "s", &node.Name}, + {"protected", "b", &node.Protected}, {"visible", "b", &node.Visible}, {"text_known", "b", &node.TextKnown}, + {"caret_known", "b", &node.CaretKnown}, {"caret", "t", &node.Caret}, {"caret_utf16", "t", &node.CaretUTF16}, + {"bounds", "(iiii)", &node.Bounds}, {"ranges", "a(tttts(iiii))", &node.Ranges}, + } + for _, read := range reads { + if err := reviewField(fields, read.key, read.signature, read.destination); err != nil { + return ReviewSnapshot{}, err + } + } + snapshot.Nodes = append(snapshot.Nodes, node) + encoded := copyReviewFields(fields) + encoded["bounds"] = dbus.MakeVariant(node.Bounds) + encoded["ranges"] = dbus.MakeVariant(node.Ranges) + canonicalNodes = append(canonicalNodes, encoded) + } + if err := validateReviewSnapshot(snapshot); err != nil { + snapshot.Nodes = nil + return snapshot, err + } + // Exact D-Bus encoding catches metadata overhead after the independent + // record/text budgets bound the encoder's temporary allocation. + counter := reviewByteCounter{} + canonical["nodes"] = dbus.MakeVariant(canonicalNodes) + message := dbus.Message{Type: dbus.TypeMethodReply, Headers: map[dbus.HeaderField]dbus.Variant{ + dbus.FieldReplySerial: dbus.MakeVariant(uint32(1)), dbus.FieldSignature: dbus.MakeVariant(dbus.SignatureOf(fields)), + }, Body: []any{canonical}} + if err := message.EncodeTo(&counter, binary.LittleEndian); err != nil || counter.count > 2<<20 { + return ReviewSnapshot{}, ErrReviewInvalid + } + return snapshot, nil +} + +type reviewByteCounter struct{ count int } + +func (counter *reviewByteCounter) Write(data []byte) (int, error) { + counter.count += len(data) + return len(data), nil +} + +func validateReviewSnapshot(snapshot ReviewSnapshot) error { + if snapshot.Version != ReviewProtocolVersion || !reviewString(snapshot.Instance, 256, false) || + !reviewString(snapshot.Window, 256, false) || !reviewString(snapshot.Focus, 256, false) || snapshot.Revision == 0 || !snapshot.Bounds.Valid() || len(snapshot.Nodes) > 4096 { + return ErrReviewInvalid + } + switch snapshot.Status { + case "ok": + case "unavailable", "stale", "busy", "limited": + if len(snapshot.Nodes) != 0 { + return ErrReviewInvalid + } + switch snapshot.Status { + case "stale": + return ErrReviewStale + case "busy": + return ErrReviewBusy + case "limited": + return ErrReviewLimited + default: + return ErrReviewUnavailable + } + default: + return ErrReviewInvalid + } + if len(snapshot.Nodes) == 0 { + return ErrReviewInvalid + } + nodes := make(map[string]ReviewNode, len(snapshot.Nodes)) + textBytes, metadataFloor := 0, 256 + for _, node := range snapshot.Nodes { + if !reviewString(node.ID, 256, false) || !reviewString(node.Parent, 256, true) || !reviewString(node.Role, 4096, false) || + !reviewString(node.Name, 4096, true) || !node.Bounds.Valid() || len(node.Ranges) > 256 { + return ErrReviewInvalid + } + if _, exists := nodes[node.ID]; exists { + return ErrReviewInvalid + } + nodes[node.ID] = node + if node.Protected && (node.Name != "" || node.TextKnown || node.CaretKnown || len(node.Ranges) != 0 || node.Caret != 0 || node.CaretUTF16 != 0) { + return ErrReviewInvalid + } + if !node.Visible && (node.Name != "" || node.TextKnown || node.CaretKnown || len(node.Ranges) != 0) { + return ErrReviewInvalid + } + if !node.TextKnown && (len(node.Ranges) != 0 || node.CaretKnown) || !node.CaretKnown && (node.Caret != 0 || node.CaretUTF16 != 0) { + return ErrReviewInvalid + } + if node.Caret > maxReviewSourceUnits || node.CaretUTF16 > maxReviewSourceUnits || node.CaretUTF16 < node.Caret || node.CaretUTF16 > 2*node.Caret { + return ErrReviewInvalid + } + previous, nativePrevious, characters := uint64(0), uint64(0), uint64(0) + textBytes += len(node.Name) + metadataFloor += 200 + len(node.ID) + len(node.Parent) + len(node.Role) + len(node.Name) + for _, r := range node.Ranges { + if !utf8.ValidString(r.Text) || strings.ContainsAny(r.Text, "\x00\ufffc") || r.Start < previous || r.End <= r.Start || + r.UTF16Start < nativePrevious || r.UTF16End <= r.UTF16Start || r.End > maxReviewSourceUnits || r.UTF16End > maxReviewSourceUnits || + r.UTF16Start < r.Start || r.UTF16Start > 2*r.Start || r.UTF16End < r.End || r.UTF16End > 2*r.End { + return ErrReviewInvalid + } + count := uint64(utf8.RuneCountInString(r.Text)) + if count != r.End-r.Start || count > 4096 || uint64(len(utf16.Encode([]rune(r.Text)))) != r.UTF16End-r.UTF16Start { + return ErrReviewInvalid + } + if strings.ContainsAny(r.Text, "\r\n") && strings.Trim(r.Text, "\r\n") != "" { + return ErrReviewInvalid + } + if clipped, ok := r.Bounds.Intersection(node.Bounds); !ok || clipped != r.Bounds { + return ErrReviewInvalid + } + previous, nativePrevious = r.End, r.UTF16End + characters += count + textBytes += len(r.Text) + metadataFloor += 64 + len(r.Text) + } + if characters > 65536 || textBytes > 1<<20 || metadataFloor > 2<<20 { + return ErrReviewInvalid + } + } + root, exists := nodes[snapshot.Window] + if !exists || root.Parent != "" || (root.Role != "window" && root.Role != "dialog") || !root.Visible || root.Protected || root.Bounds != snapshot.Bounds { + return ErrReviewInvalid + } + if _, exists := nodes[snapshot.Focus]; !exists { + return ErrReviewInvalid + } + // Check each ancestry chain: this bounds depth and detects disconnected + // cycles, which a traversal starting only at the root would miss. + for id, node := range nodes { + if id == snapshot.Window { + continue + } + seen := map[string]bool{id: true} + for depth := 1; ; depth++ { + if depth > 64 { + return ErrReviewInvalid + } + parent, exists := nodes[node.Parent] + if !exists || seen[node.Parent] { + return ErrReviewInvalid + } + if clipped, ok := node.Bounds.Intersection(parent.Bounds); !ok || clipped != node.Bounds { + return ErrReviewInvalid + } + if parent.ID == snapshot.Window { + break + } + seen[parent.ID] = true + node = parent + } + } + return nil +} + +func ApplyReviewSnapshot(tree *atspi.AccessibleTree, snapshot ReviewSnapshot, sender string) (*atspi.AccessibleTree, atspi.ObjectID, error) { + if err := validateReviewSnapshot(snapshot); err != nil { + return nil, atspi.ObjectID{}, err + } + root := ReviewID(sender, snapshot.Instance, snapshot.Window, snapshot.Window) + if !IsReviewID(root) { + return nil, atspi.ObjectID{}, ErrReviewInvalid + } + nodes := make([]atspi.TreeNode, len(snapshot.Nodes)) + index := make(map[string]int, len(nodes)) + for i, node := range snapshot.Nodes { + id := ReviewID(sender, snapshot.Instance, snapshot.Window, node.ID) + index[node.ID] = i + role := node.Role + if node.Protected { + role = "password text" + } + geometry := atspi.Geometry{VisibilityKnown: true, Visible: node.Visible, Showing: node.Visible} + if node.Visible { + geometry.BoundsKnown = true + geometry.Bounds = node.Bounds + } + text := atspi.VisibleText{Known: node.TextKnown, CaretKnown: node.CaretKnown, CaretOffset: int(node.Caret)} + for _, r := range node.Ranges { + text.Ranges = append(text.Ranges, atspi.TextRange{Start: int(r.Start), End: int(r.End), Text: r.Text, Bounds: r.Bounds}) + } + nodes[i] = atspi.TreeNode{Snapshot: atspi.Snapshot{BusName: id.BusName, Path: id.Path, Name: node.Name, Role: role, + StatesKnown: true, Visible: node.Visible, Showing: node.Visible, Focused: node.ID == snapshot.Focus, Focusable: node.ID == snapshot.Focus}, Geometry: geometry, Text: text} + } + for _, node := range snapshot.Nodes { + if node.Parent != "" { + parent := index[node.Parent] + nodes[parent].Children = append(nodes[parent].Children, ReviewID(sender, snapshot.Instance, snapshot.Window, node.ID)) + } + } + var err error + if tree == nil { + tree, err = atspi.NewAccessibleTree(root, nodes) + } else { + err = tree.Replace(root, nodes) + } + if err != nil { + return nil, atspi.ObjectID{}, fmt.Errorf("%w: %v", ErrReviewInvalid, err) + } + return tree, ReviewID(sender, snapshot.Instance, snapshot.Window, snapshot.Focus), nil +} diff --git a/internal/wine/review_snapshot_test.go b/internal/wine/review_snapshot_test.go new file mode 100644 index 0000000..0bc7161 --- /dev/null +++ b/internal/wine/review_snapshot_test.go @@ -0,0 +1,352 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later +package wine + +import ( + "bytes" + "context" + "encoding/binary" + "errors" + "fmt" + "math" + "strings" + "testing" + + "git.stormux.org/storm/cthulhu/internal/atspi" + "github.com/godbus/dbus/v5" +) + +// These records describe the producer's wire contract independently of the +// decoder's types. This also exercises godbus struct-to-struct conversion. +type testWireRange struct { + Start, End, UTF16Start, UTF16End uint64 + Text string + Bounds atspi.Rectangle +} + +func reviewWireNode(id, parent, role, name string, bounds atspi.Rectangle, known bool, ranges ...testWireRange) map[string]dbus.Variant { + return map[string]dbus.Variant{ + "id": dbus.MakeVariant(id), "parent": dbus.MakeVariant(parent), "role": dbus.MakeVariant(role), "name": dbus.MakeVariant(name), + "protected": dbus.MakeVariant(false), "visible": dbus.MakeVariant(true), "bounds": dbus.MakeVariant(bounds), + "text_known": dbus.MakeVariant(known), "caret_known": dbus.MakeVariant(false), "caret": dbus.MakeVariant(uint64(0)), + "caret_utf16": dbus.MakeVariant(uint64(0)), "ranges": dbus.MakeVariant(ranges), + } +} +func reviewWire() map[string]dbus.Variant { + root := atspi.Rectangle{X: 10, Y: 20, Width: 400, Height: 300} + input := reviewWireNode("input", "window", "text", "", atspi.Rectangle{X: 20, Y: 40, Width: 200, Height: 30}, true, + testWireRange{0, 11, 0, 12, "😀alpha beta", atspi.Rectangle{X: 20, Y: 40, Width: 140, Height: 20}}) + input["caret_known"] = dbus.MakeVariant(true) + input["caret"] = dbus.MakeVariant(uint64(2)) + input["caret_utf16"] = dbus.MakeVariant(uint64(3)) + password := reviewWireNode("password", "window", "password text", "", atspi.Rectangle{X: 20, Y: 160, Width: 120, Height: 25}, false) + password["protected"] = dbus.MakeVariant(true) + nodes := []map[string]dbus.Variant{ + reviewWireNode("window", "", "window", "Review fixture", root, false), input, + reviewWireNode("output", "window", "text", "", atspi.Rectangle{X: 20, Y: 100, Width: 200, Height: 50}, true, + testWireRange{7, 11, 8, 12, "beta", atspi.Rectangle{X: 20, Y: 100, Width: 80, Height: 20}}), password, + reviewWireNode("button", "window", "push button", "Open & close", atspi.Rectangle{X: 20, Y: 210, Width: 120, Height: 25}, false), + } + return map[string]dbus.Variant{"version": dbus.MakeVariant(uint32(1)), "instance": dbus.MakeVariant("helper-instance"), + "window": dbus.MakeVariant("window"), "focus": dbus.MakeVariant("input"), "revision": dbus.MakeVariant(uint64(1)), + "status": dbus.MakeVariant("ok"), "bounds": dbus.MakeVariant(root), "nodes": dbus.MakeVariant(nodes)} +} +func wireNodes(fields map[string]dbus.Variant) []map[string]dbus.Variant { + return fields["nodes"].Value().([]map[string]dbus.Variant) +} + +func TestReviewSnapshotUnicodeAndStableTree(t *testing.T) { + fields := reviewWire() + snapshot, err := DecodeReviewSnapshot(fields) + if err != nil { + t.Fatal(err) + } + tree, focus, err := ApplyReviewSnapshot(nil, snapshot, ":1.20") + if err != nil { + t.Fatal(err) + } + if !focus.Valid() || !IsReviewID(focus) || !strings.HasPrefix(focus.Path, "/wine/") { + t.Fatalf("invalid Wine identity: %v", focus) + } + reference, err := tree.Reference(focus) + if err != nil { + t.Fatal(err) + } + visible, err := tree.VisibleText(reference) + if err != nil { + t.Fatal(err) + } + if !visible.CaretKnown || visible.CaretOffset != 2 || len(visible.Ranges) != 1 || visible.Ranges[0].End != 11 || visible.Ranges[0].Text != "😀alpha beta" { + t.Fatalf("bad Unicode capture: %+v", visible) + } + original := reference + input := wireNodes(fields)[1] + input["ranges"] = dbus.MakeVariant([]testWireRange{{0, 11, 0, 12, "😀omega zeta", atspi.Rectangle{X: 20, Y: 40, Width: 140, Height: 20}}}) + snapshot, err = DecodeReviewSnapshot(fields) + if err != nil { + t.Fatal(err) + } + updated, again, err := ApplyReviewSnapshot(tree, snapshot, ":1.20") + if err != nil { + t.Fatal(err) + } + if updated != tree || again != focus { + t.Fatal("text update replaced the owned tree or focus identity") + } + after, _ := tree.Reference(focus) + if after != original { + t.Fatal("text update retired a live generation") + } + visible, _ = tree.VisibleText(after) + if visible.Ranges[0].Text != "😀omega zeta" { + t.Fatal("tree retained old text") + } + // Removing and then reusing an identity must not revive its old reference. + nodes := wireNodes(fields) + fields["focus"] = dbus.MakeVariant("output") + fields["nodes"] = dbus.MakeVariant(append(append([]map[string]dbus.Variant{}, nodes[:1]...), nodes[2:]...)) + snapshot, err = DecodeReviewSnapshot(fields) + if err != nil { + t.Fatal(err) + } + if _, _, err = ApplyReviewSnapshot(tree, snapshot, ":1.20"); err != nil { + t.Fatal(err) + } + fields["nodes"] = dbus.MakeVariant(nodes) + fields["focus"] = dbus.MakeVariant("input") + snapshot, _ = DecodeReviewSnapshot(fields) + if _, _, err = ApplyReviewSnapshot(tree, snapshot, ":1.20"); err != nil { + t.Fatal(err) + } + after, _ = tree.Reference(focus) + if after == original { + t.Fatal("removed identity reused an old generation") + } + if _, err = tree.Resolve(original); !errors.Is(err, atspi.ErrStaleObject) { + t.Fatalf("removed reference stayed usable: %v", err) + } + // The unique sender is part of every owned identity. + _, other, err := ApplyReviewSnapshot(nil, snapshot, ":1.21") + if err != nil || other == focus { + t.Fatalf("providers collided: %v", err) + } + for _, id := range []atspi.ObjectID{atspi.NewObjectID(":1.20", "/wineish/a/b/c"), atspi.NewObjectID(":1.20", "/wine/x/y/z"), atspi.NewObjectID("org.test.App", focus.Path)} { + if IsReviewID(id) { + t.Fatalf("reserved namespace accepted invalid identity: %+v", id) + } + } +} + +func TestReviewSnapshotEmptyAnchor(t *testing.T) { + fields := reviewWire() + input := wireNodes(fields)[1] + input["ranges"] = dbus.MakeVariant([]testWireRange{}) + input["caret"] = dbus.MakeVariant(uint64(0)) + input["caret_utf16"] = dbus.MakeVariant(uint64(0)) + snapshot, err := DecodeReviewSnapshot(fields) + if err != nil { + t.Fatal(err) + } + tree, focus, err := ApplyReviewSnapshot(nil, snapshot, ":1.20") + if err != nil { + t.Fatal(err) + } + ref, err := tree.Reference(focus) + if err != nil { + t.Fatal(err) + } + text, err := tree.VisibleText(ref) + if err != nil || !text.Known || len(text.Ranges) != 0 { + t.Fatalf("empty anchor lost: %+v %v", text, err) + } + window, err := tree.ReviewWindow(context.Background(), focus) + if err != nil || len(window.Nodes) != 5 { + t.Fatalf("empty anchor hid output: %v", err) + } +} + +func TestReviewSnapshotProtectedContent(t *testing.T) { + fields := reviewWire() + fields["focus"] = dbus.MakeVariant("password") + snapshot, err := DecodeReviewSnapshot(fields) + if err != nil { + t.Fatal(err) + } + tree, focus, err := ApplyReviewSnapshot(nil, snapshot, ":1.20") + if err != nil { + t.Fatal(err) + } + ref, _ := tree.Reference(focus) + object, _ := tree.Resolve(ref) + text, _ := tree.VisibleText(ref) + if object.Role != "password text" || object.Name != "" || object.Text != "" || text.Known || len(text.Ranges) != 0 { + t.Fatalf("protected object exposed text: %+v %+v", object, text) + } + wireNodes(fields)[3]["name"] = dbus.MakeVariant("private-review-secret") + rejected, err := DecodeReviewSnapshot(fields) + if !errors.Is(err, ErrReviewInvalid) || len(rejected.Nodes) != 0 { + t.Fatal("protected name accepted") + } +} + +func TestReviewSnapshotRejectsInvalidPayload(t *testing.T) { + tests := map[string]func(map[string]dbus.Variant){ + "forged scalar signature": func(f map[string]dbus.Variant) { + f["revision"] = dbus.MakeVariantWithSignature(int64(1), dbus.ParseSignatureMust("t")) + }, + "forged tuple signature": func(f map[string]dbus.Variant) { + f["bounds"] = dbus.MakeVariantWithSignature([]int64{10, 20, 400, 300}, dbus.ParseSignatureMust("(iiii)")) + }, + "version": func(f map[string]dbus.Variant) { f["version"] = dbus.MakeVariant(uint32(2)) }, + "wrong scalar": func(f map[string]dbus.Variant) { f["revision"] = dbus.MakeVariant(int64(1)) }, + "missing key": func(f map[string]dbus.Variant) { delete(f, "focus") }, + "extra key": func(f map[string]dbus.Variant) { f["extra"] = dbus.MakeVariant("not part of version one") }, + "invalid utf8": func(f map[string]dbus.Variant) { f["instance"] = dbus.MakeVariant(string([]byte{255})) }, + "nul identity": func(f map[string]dbus.Variant) { f["instance"] = dbus.MakeVariant("a\x00b") }, + "identity bound": func(f map[string]dbus.Variant) { f["instance"] = dbus.MakeVariant(strings.Repeat("a", 257)) }, + "empty identity": func(f map[string]dbus.Variant) { f["instance"] = dbus.MakeVariant("") }, + "unknown status": func(f map[string]dbus.Variant) { f["status"] = dbus.MakeVariant("partial") }, + "nonok nodes": func(f map[string]dbus.Variant) { f["status"] = dbus.MakeVariant("limited") }, + "invalid bounds": func(f map[string]dbus.Variant) { f["bounds"] = dbus.MakeVariant(atspi.Rectangle{}) }, + "bounds shape": func(f map[string]dbus.Variant) { f["bounds"] = dbus.MakeVariant([]int32{1, 2, 3, 4}) }, + "nodes shape": func(f map[string]dbus.Variant) { f["nodes"] = dbus.MakeVariant([]string{"input"}) }, + "no nodes": func(f map[string]dbus.Variant) { f["nodes"] = dbus.MakeVariant([]map[string]dbus.Variant{}) }, + "duplicate": func(f map[string]dbus.Variant) { f["nodes"] = dbus.MakeVariant(append(wireNodes(f), wireNodes(f)[1])) }, + "orphan": func(f map[string]dbus.Variant) { wireNodes(f)[1]["parent"] = dbus.MakeVariant("missing") }, + "cycle": func(f map[string]dbus.Variant) { + wireNodes(f)[1]["parent"] = dbus.MakeVariant("output") + wireNodes(f)[2]["parent"] = dbus.MakeVariant("input") + }, + "missing focus": func(f map[string]dbus.Variant) { f["focus"] = dbus.MakeVariant("missing") }, + "root parent": func(f map[string]dbus.Variant) { wireNodes(f)[0]["parent"] = dbus.MakeVariant("input") }, + "root role": func(f map[string]dbus.Variant) { wireNodes(f)[0]["role"] = dbus.MakeVariant("text") }, + "node type": func(f map[string]dbus.Variant) { wireNodes(f)[1]["caret_known"] = dbus.MakeVariant(uint32(1)) }, + "node missing key": func(f map[string]dbus.Variant) { delete(wireNodes(f)[1], "ranges") }, + "caption bound": func(f map[string]dbus.Variant) { wireNodes(f)[4]["name"] = dbus.MakeVariant(strings.Repeat("a", 4097)) }, + "invisible text": func(f map[string]dbus.Variant) { wireNodes(f)[1]["visible"] = dbus.MakeVariant(false) }, + "unknown text with ranges": func(f map[string]dbus.Variant) { wireNodes(f)[1]["text_known"] = dbus.MakeVariant(false) }, + "unknown caret": func(f map[string]dbus.Variant) { wireNodes(f)[1]["caret_known"] = dbus.MakeVariant(false) }, + "caret overflow": func(f map[string]dbus.Variant) { wireNodes(f)[1]["caret"] = dbus.MakeVariant(uint64(math.MaxUint64)) }, + "ranges shape": func(f map[string]dbus.Variant) { wireNodes(f)[1]["ranges"] = dbus.MakeVariant([]string{"bad"}) }, + } + rangeCases := map[string]testWireRange{ + "rune count": {0, 5, 0, 5, "four", atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}}, + "offset overflow": {math.MaxUint64, 0, 0, 1, "a", atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}}, + "utf16 span": {0, 1, 0, 1, "😀", atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}}, + "native offset overflow": {0, 1, math.MaxUint64, 0, "a", atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}}, + "clipped range": {0, 1, 0, 1, "a", atspi.Rectangle{X: -1, Y: 40, Width: 80, Height: 20}}, + "mixed newline": {0, 2, 0, 2, "a\n", atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}}, + "line bound": {0, 4097, 0, 4097, strings.Repeat("a", 4097), atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}}, + } + for name, r := range rangeCases { + tests[name] = func(f map[string]dbus.Variant) { wireNodes(f)[1]["ranges"] = dbus.MakeVariant([]testWireRange{r}) } + } + tests["node bound"] = func(f map[string]dbus.Variant) { + nodes := wireNodes(f) + for len(nodes) < 4097 { + nodes = append(nodes, reviewWireNode(fmt.Sprintf("node_%d", len(nodes)), "window", "panel", "", atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}, false)) + } + f["nodes"] = dbus.MakeVariant(nodes) + } + tests["range bound"] = func(f map[string]dbus.Variant) { + ranges := make([]testWireRange, 257) + for i := range ranges { + ranges[i] = testWireRange{uint64(i), uint64(i + 1), uint64(i), uint64(i + 1), "a", atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}} + } + wireNodes(f)[1]["ranges"] = dbus.MakeVariant(ranges) + } + tests["control character bound"] = func(f map[string]dbus.Variant) { + ranges := make([]testWireRange, 17) + for i := range ranges { + s := uint64(i * 4096) + ranges[i] = testWireRange{s, s + 4096, s, s + 4096, strings.Repeat("a", 4096), atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}} + } + wireNodes(f)[1]["ranges"] = dbus.MakeVariant(ranges) + } + tests["depth bound"] = func(f map[string]dbus.Variant) { + nodes := wireNodes(f) + parent := "input" + for i := 0; i < 65; i++ { + id := strings.Repeat("d", i+1) + nodes = append(nodes, reviewWireNode(id, parent, "panel", "", atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}, false)) + parent = id + } + f["nodes"] = dbus.MakeVariant(nodes) + } + tests["window text bound"] = func(f map[string]dbus.Variant) { + nodes := wireNodes(f) + for n := 0; n < 17; n++ { + ranges := make([]testWireRange, 16) + for i := range ranges { + s := uint64(i * 4096) + ranges[i] = testWireRange{s, s + 4096, s, s + 4096, strings.Repeat("a", 4096), atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}} + } + nodes = append(nodes, reviewWireNode(fmt.Sprintf("large_%d", n), "window", "text", "", atspi.Rectangle{X: 20, Y: 40, Width: 200, Height: 30}, true, ranges...)) + } + f["nodes"] = dbus.MakeVariant(nodes) + } + tests["serialized bound"] = func(f map[string]dbus.Variant) { + nodes := wireNodes(f) + for n := 0; n < 128; n++ { + ranges := make([]testWireRange, 256) + for i := range ranges { + s := uint64(i) + ranges[i] = testWireRange{s, s + 1, s, s + 1, "a", atspi.Rectangle{X: 20, Y: 40, Width: 80, Height: 20}} + } + nodes = append(nodes, reviewWireNode(fmt.Sprintf("many_%d", n), "window", "text", "", atspi.Rectangle{X: 20, Y: 40, Width: 200, Height: 30}, true, ranges...)) + } + f["nodes"] = dbus.MakeVariant(nodes) + } + for name, mutate := range tests { + t.Run(name, func(t *testing.T) { + fields := reviewWire() + mutate(fields) + snapshot, err := DecodeReviewSnapshot(fields) + if !errors.Is(err, ErrReviewInvalid) || len(snapshot.Nodes) != 0 { + t.Fatalf("invalid payload accepted: nodes=%d err=%v", len(snapshot.Nodes), err) + } + }) + } +} + +func TestReviewSnapshotActualBusStructs(t *testing.T) { + fields := reviewWire() + message := dbus.Message{Type: dbus.TypeMethodReply, Headers: map[dbus.HeaderField]dbus.Variant{ + dbus.FieldReplySerial: dbus.MakeVariant(uint32(1)), dbus.FieldSignature: dbus.MakeVariant(dbus.SignatureOf(fields)), + }, Body: []any{fields}} + var wire bytes.Buffer + if err := message.EncodeTo(&wire, binary.LittleEndian); err != nil { + t.Fatal(err) + } + decoded, err := dbus.DecodeMessage(&wire) + if err != nil { + t.Fatal(err) + } + snapshot, err := DecodeReviewSnapshot(decoded.Body[0].(map[string]dbus.Variant)) + if err != nil { + t.Fatal(err) + } + tree, focus, err := ApplyReviewSnapshot(nil, snapshot, ":1.20") + if err != nil { + t.Fatal(err) + } + ref, _ := tree.Reference(focus) + text, _ := tree.VisibleText(ref) + if text.Ranges[0].Text != "😀alpha beta" { + t.Fatalf("actual bus structs lost text: %+v", text) + } +} + +func TestReviewSnapshotStatuses(t *testing.T) { + for status, want := range map[string]error{"unavailable": ErrReviewUnavailable, "stale": ErrReviewStale, "busy": ErrReviewBusy, "limited": ErrReviewLimited} { + t.Run(status, func(t *testing.T) { + fields := reviewWire() + fields["status"] = dbus.MakeVariant(status) + fields["nodes"] = dbus.MakeVariant([]map[string]dbus.Variant{}) + snapshot, err := DecodeReviewSnapshot(fields) + if !errors.Is(err, want) || len(snapshot.Nodes) != 0 { + t.Fatalf("status %s: %v", status, err) + } + }) + } +} diff --git a/internal/wine/version.go b/internal/wine/version.go new file mode 100644 index 0000000..f75920a --- /dev/null +++ b/internal/wine/version.go @@ -0,0 +1,40 @@ +package wine + +import ( + "debug/elf" + "path/filepath" + "time" +) + +// InstalledVersion reads the selected helper's embedded release without +// executing Wine. Older helpers without the metadata return an empty string. +// This describes the files on disk, which may differ from a running helper. +func InstalledVersion() string { + helper := helperPath() + if helper == "" { + return "" + } + // Resolve launcher symlinks before locating its adjacent Winelib sidecar. + helper, err := filepath.EvalSymlinks(helper) + if err != nil { + return "" + } + file, err := elf.Open(helper + ".so") + if err != nil { + return "" + } + defer file.Close() + section := file.Section(".wine_access.version") + if section == nil || section.Size != 11 || section.Flags&elf.SHF_COMPRESSED != 0 { + return "" + } + var data [11]byte + if _, err := section.ReadAt(data[:], 0); err != nil || data[10] != 0 { + return "" + } + release := string(data[:10]) + if _, err := time.Parse("2006.01.02", release); err != nil { + return "" + } + return release +} diff --git a/internal/wine/version_test.go b/internal/wine/version_test.go new file mode 100644 index 0000000..5ebf3d6 --- /dev/null +++ b/internal/wine/version_test.go @@ -0,0 +1,65 @@ +package wine + +import ( + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +func TestInstalledVersion(t *testing.T) { + root := t.TempDir() + helper := filepath.Join(root, "wine-access.exe") + // The launcher must never run, including for old helpers lacking metadata. + marker := filepath.Join(root, "executed") + if err := os.WriteFile(helper, []byte("#!/bin/sh\ntouch '"+marker+"'\nexit 99\n"), 0700); err != nil { + t.Fatal(err) + } + t.Setenv("CTHULHU_WINE_ACCESS_HELPER", helper) + for _, test := range []struct { + name, declaration, want string + }{ + {"current", `const char release[] = "2026.10.24";`, "2026.10.24"}, + {"old helper", `int unused;`, ""}, + {"invalid date", `const char release[] = "2026.99.99";`, ""}, + {"oversized", `const char release[] = "2026.10.24 extra";`, ""}, + {"unterminated", `const char release[11] = "2026.10.24x";`, ""}, + } { + t.Run(test.name, func(t *testing.T) { + source := "__attribute__((used, section(\".wine_access.version\")))\n" + test.declaration + if test.name == "old helper" { + source = test.declaration + } + command := exec.Command("cc", "-shared", "-fPIC", "-x", "c", "-o", helper+".so", "-") + command.Stdin = strings.NewReader(source) + if output, err := command.CombinedOutput(); err != nil { + t.Fatalf("compile helper metadata fixture: %v\n%s", err, output) + } + if got := InstalledVersion(); got != test.want { + t.Fatalf("InstalledVersion() = %q, want %q", got, test.want) + } + link := filepath.Join(t.TempDir(), "wine-access.exe") + if err := os.Symlink(helper, link); err != nil { + t.Fatal(err) + } + t.Setenv("CTHULHU_WINE_ACCESS_HELPER", link) + if got := InstalledVersion(); got != test.want { + t.Fatalf("symlink InstalledVersion() = %q, want %q", got, test.want) + } + }) + } + if _, err := os.Stat(marker); !os.IsNotExist(err) { + t.Fatalf("version detection executed the helper: %v", err) + } + if err := os.WriteFile(helper+".so", []byte("broken sidecar"), 0600); err != nil { + t.Fatal(err) + } + if got := InstalledVersion(); got != "" { + t.Fatalf("invalid ELF returned %q", got) + } + t.Setenv("CTHULHU_WINE_ACCESS_HELPER", "/usr/bin/true") + if got := InstalledVersion(); got != "" { + t.Fatalf("missing sidecar returned %q", got) + } +} diff --git a/meson.build b/meson.build deleted file mode 100644 index 7e465d1..0000000 --- a/meson.build +++ /dev/null @@ -1,156 +0,0 @@ -project('cthulhu', - version: '2026.09.09', - meson_version: '>= 1.0.0', -) - -python = import('python') -i18n = import('i18n') - -python_minimum_version = '3.9' -python3 = python.find_installation('python3', required: true) -if not python3.language_version().version_compare(f'>= @python_minimum_version@') - error(f'Python @python_minimum_version@ or newer is required.') -endif - -# Hard dependencies (checked via pkg-config) -dependency('atspi-2', version: '>= 2.52.0') -dependency('atk-bridge-2.0', version: '>= 2.26.0') -dependency('pygobject-3.0', version: '>= 3.18') - -# Hard Python module dependencies -gi_result = python.find_installation('python3', modules:['gi'], required: false) -if not gi_result.found() - error('gi (PyGObject) is required') -endif - -json_result = python.find_installation('python3', modules:['json'], required: false) -if not json_result.found() - error('json module is required') -endif - -pluggy_result = python.find_installation('python3', modules:['pluggy'], required: false) -if not pluggy_result.found() - error('pluggy module is required') -endif - -# End users might not have the Gtk development libraries installed, making pkg-config fail. -# Therefore, check this dependency via python. -gtk_major_version = '3' -gtk_minor_version = '0' -gtk_command = ' '.join([ - 'import gi; gi.require_version("Gtk", "3.0"); from gi.repository import Gtk;', - 'print(f"{Gtk.get_major_version()}.{Gtk.get_minor_version()}.{Gtk.get_micro_version()}");', - f'failed = Gtk.get_major_version() != @gtk_major_version@;', - 'exit(failed)' -]) -gtk_test = run_command(python3, '-c', gtk_command, check: false) -description = f'GTK @gtk_major_version@.@gtk_minor_version@' -version = gtk_test.stdout().strip() -if gtk_test.returncode() != 0 - error(f'@description@ failed (found @version@)') -endif - -# Optional python modules with their descriptions -optional_modules = { - 'brlapi': 'braille output', - 'louis': 'contracted braille', - 'speechd': 'speech output', - 'dasbus': 'D-Bus remote controller', - 'pywayland': 'Wayland shared workspace backend', - 'gi.repository.Wnck': 'mouse review', -} - -summary = {} - -wine_access_mode = get_option('wine-access') -wine_access_tools = { - 'cmake': find_program('cmake', required: false), - 'winegcc': find_program('winegcc', required: false), - 'wineg++': find_program('wineg++', required: false), - 'widl': find_program('widl', required: false), -} -wine_access_enabled = wine_access_mode != 'disabled' and host_machine.cpu_family() == 'x86_64' -foreach tool_name, tool : wine_access_tools - if not tool.found() - wine_access_enabled = false - if wine_access_mode == 'enabled' - error(f'-Dwine-access=enabled requires @tool_name@') - endif - endif -endforeach -if wine_access_mode == 'enabled' and host_machine.cpu_family() != 'x86_64' - error('-Dwine-access=enabled currently requires an x86_64 build host') -endif - -if wine_access_enabled - wine_access_outputs = custom_target( - 'wine-access-helper', - output: ['cthulhu-wine-access.exe', 'cthulhu-wine-access.exe.so'], - command: [ - find_program('bash'), - files('scripts/build-wine-access.sh'), - meson.current_source_dir() / 'wine-access', - meson.current_build_dir() / 'wine-access-build', - '@OUTPUT0@', - '@OUTPUT1@', - ], - depend_files: files( - 'scripts/build-wine-access.sh', - 'wine-access/CMakeLists.txt', - 'wine-access/main.cpp', - 'wine-access/nvdaController.idl', - 'wine-access/winelib-toolchain.cmake', - ), - build_by_default: true, - install: true, - install_dir: get_option('libexecdir') / 'cthulhu' / 'wine', - ) - summary += {'Wine accessibility': 'yes (Winelib x86_64 helper)'} -else - summary += {'Wine accessibility': 'no'} -endif -foreach module, description : optional_modules - result = python.find_installation('python3', modules:[module], required: false) - if result.found() - summary += {description: f'yes (found @module@)'} - else - summary += {description: f'no (missing @module@)'} - endif -endforeach - -# Optional synthesizer services -speech_output = [] -if python.find_installation('python3', modules:['speechd'], required: false).found() - speech_output += ['speechd'] -endif - -if speech_output.length() > 0 - summary += {'speech output': 'yes (found @0@)'.format(', '.join(speech_output))} -else - summary += {'speech output': 'no (missing speechd)'} -endif - -# Check for GStreamer -gstreamer_dep = dependency('gstreamer-1.0', required: false) -if gstreamer_dep.found() - summary += {'sound support': 'yes (found gstreamer)'} -else - summary += {'sound support': 'no (missing gstreamer)'} -endif - -# Update icon cache manually (desktop-neutral) - optional, ignore failures -gtk_update_icon_cache = find_program('gtk4-update-icon-cache', required: false) -if gtk_update_icon_cache.found() - meson.add_install_script('sh', '-c', - 'gtk4-update-icon-cache -q -t -f "$MESON_INSTALL_DESTDIR_PREFIX/' + get_option('datadir') / 'icons' / 'hicolor' + '" || echo "Icon cache update skipped"') -endif - -summary += {'Install dir': python.find_installation('python3').get_install_dir()} - -subdir('docs') -subdir('icons') -subdir('po') -subdir('sounds') -subdir('src') - -summary(summary) diff --git a/meson_options.txt b/meson_options.txt deleted file mode 100644 index ce21f81..0000000 --- a/meson_options.txt +++ /dev/null @@ -1,9 +0,0 @@ -option('plugin-system', type: 'boolean', value: true, description: 'Enable plugin system support') -option('d-bus-service', type: 'boolean', value: true, description: 'Enable D-Bus remote controller service') -option( - 'wine-access', - type: 'combo', - choices: ['auto', 'enabled', 'disabled'], - value: 'auto', - description: 'Build the Wine accessibility and NVDA Controller helper' -) diff --git a/po/.gitignore b/po/.gitignore deleted file mode 100644 index 81eef8e..0000000 --- a/po/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -*.gmo -*.mo -*.pot -Makefile -Makefile.in -Makefile.in.in -POTFILES -cat-id-tbl.c -messages -missing -notexist -po2tbl.sed -po2tbl.sed.in -remove-potcdate.sed -stamp-cat-id -stamp-it -stamp-po -Makevars.template -Rules-quot -boldquot.sed -en@boldquot.header -en@quot.header -insert-header.sin -quot.sed -remove-potcdate.sin diff --git a/po/ChangeLog b/po/ChangeLog deleted file mode 100644 index 0105f47..0000000 --- a/po/ChangeLog +++ /dev/null @@ -1,2405 +0,0 @@ -2009-04-01 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2009-03-16 Petr Kovar - - * cs.po: Updated Czech translation by Lucas Lommer. - -2009-03-15 Ani Peter - - * ml.po: Updating Malayalam Translations by Harivishnu - -2009-03-15 Nickolay V. Shmyrev - - * ru.po: Updated Russian translation. - -2009-03-15 Gabor Kelemen - - * hu.po: Translation updated. - -2009-03-14 Kenneth Nielsen - - * da.po: Updated Danish translation by Ask H. Larsen - -2009-03-14 Ani Peter - - * ml.po: Updated Malayalam Translations - -2009-03-11 Krishnababu K - - * te.po: Updated Telugu Translation. - -2009-03-10 Manoj Kumar Giri - - * or.po: Updated Oriya Translation. - -2009-03-10 I. Felix - - * ta.po: Tamil Translation updated - -2009-03-10 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2009-03-09 Milo Casagrande - - * it.po: Updated Italian translation by Luca Ferretti - -2009-03-09 Rajesh Ranjan - - * hi.po: Updated Hindi Translation. - -2009-03-08 Wadim Dziedzic - - * pl.po: Updated Polish translation - -2009-03-07 Mario Blättermann - - * de.po: Updated German translation by Simon Bienlein. - -2009-03-06 Milo Casagrande - - * it.po: Updated Italian translation by Luca Ferretti - -2009-03-01 Takeshi AIHANA - - * ja.po: Updated Japanese translation. - -2009-02-27 Og Maciel - - * pt_BR.po: Updated Brazilian Portuguese translation by - Tiago Melo Casal. - -2009-02-25 Og Maciel - - * pt_BR.po: Updated Brazilian Portuguese translation by - André Gondim. - -2009-02-25 Wouter Bolsterlee - - * nl.po: Updated Dutch translation by Wouter Bolsterlee. - -2009-02-24 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2009-02-24 Duarte Loreto - - * pt.po: Updated Portuguese translation by Rui Batista - . - -2009-02-23 Philip Withnall - - * en_GB.po: Updated British English translation. - -2009-02-23 Og Maciel - - * pt_BR.po: Updated Brazilian Portuguese translation by - André Gondim. - -2009-02-23 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2009-02-23 Theppitak Karoonboonyanan - - * th.po: Updated Thai traslation. - -2009-02-22 Baris Cicek - - * tr.po: Updated Turkish translation. - -2009-02-21 Jani Monoses - - * ro.po: Added Romanian translation - by Adi Roiban - and Lucian Adrian Grijincu - -2009-02-19 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2009-02-19 Gil Fcthulhuda - - * ca.po: Updated Catalan translation. - -2009-02-19 Inaki Larranaga Murgoitio - - * eu.po: Updated Basque translation. - -2009-02-19 Gabor Kelemen - - * hu.po: Translation updated. - -2009-02-18 Claude Paroz - - * fr.po: Updated French translation. - -2009-02-17 Gabor Kelemen - - * hu.po: Translation updated. - -2009-02-17 Tomasz Dominikowski - - * pl.po: Updated Polish translation - -2009-02-16 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2009-02-16 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2009-02-15 Kenneth Nielsen - - * da.po: Updated Danish translation by Kenneth Nielsen - -2009-02-14 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2009-02-14 Chao-Hsiung Liao - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2009-02-13 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2009-02-13 Theppitak Karoonboonyanan - - * th.po: Updated Thai traslation. - -2009-02-10 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2009-02-09 Gil Fcthulhuda - - * ca.po: Updated Catalan translation. - -2009-02-09 Jonh Wendell - - * pt_BR.po: Updated Brazilian Portuguese translation by Andre Gondim - and myself. - -2009-02-09 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2009-02-05 Mark Krapivner - - * he.po: Updated Hebrew translation. - -2009-02-01 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2009-01-31 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2009-01-30 Gil Fcthulhuda - - * ca.po: Updated Catalan translation. - -2009-01-30 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer. - -2009-01-29 Changwoo Ryu - - * ko.po: Updated Korean translation. - -2009-01-28 Willie Walker - - * po/*.po: - Fix for bug #569118 - Use C_() instead of Q_() with context - -2009-01-18 Duarte Loreto - - * pt.po: Updated Portuguese translation by Rui Batista. - -2009-01-18 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2009-01-13 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer. - -2009-01-12 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2009-01-04 Mark Krapivner - - * he.po: Add Hebrew translation. - * LINGUAS: Add Hebrew translation. - -2008-12-02 Gabor Kelemen - - * hu.po: Translation updated. - -2008-12-01 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2008-12-01 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer. - -2008-11-29 Inaki Larranaga Murgoitio - - * eu.po: Updated Basque translation. - -2008-11-21 Chao-Hsiung Liao - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2008-11-19 Jochen Skulj - - * de.po: Updated German translation by Simon Bienlein - -2008-11-19 Funda Wang - - * zh_CN.po: Updated zh_CN translation. - -2008-11-18 Funda Wang - - * zh_CN.po: Updated zh_CN translation. - -2008-11-14 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2008-10-21 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer. - -2008-10-19 Gil Fcthulhuda - - * ca.po: Updated Catalan translation. - -2008-10-06 Luca Ferretti - - * it.po: Updated Italian translation. - -2008-09-30 Og Maciel - - * pt_BR.po: Updated Brazilian Portuguese translation by Vladimir Melo. - -2008-09-22 Luca Ferretti - - * it.po: Updated Italian translation. - -2008-09-22 Kenneth Nielsen - - * da.po: Updated Danish translation by Kenneth Nielsen - -2008-09-21 Leonardo Ferreira Fontenelle - - * pt_BR.po: Fixed typos in Brazilian Portuguese translation by Tiago M. - Casal. - -2008-09-21 Nickolay V. Shmyrev - - * ru.po: Updated Russian translation. - -2008-09-21 Gabor Kelemen - - * hu.po: Translation corrected by Attila Hammer. - -2008-09-21 Petr Kovar - - * cs.po: Updated Czech translation by Lucas Lommer. - -2008-09-20 Luca Ferretti - - * it.po: Updated Italian translation. - -2008-09-20 Priit Laes - - * et.po: Translation updated by Ivar Smolin - -2008-09-18 Djihed Afifi - - * ar.po: Updated Arabic Translation by Youssef Chahibi. - -2008-09-17 I. Felix - - * ta.po: Tamil Translation updated - -2008-09-16 Gabor Kelemen - - * hu.po: Translation updated. - -2008-09-15 Djihed Afifi - - * ar.po: Updated Arabic Translation by Youssef Chahibi. - -2008-09-15 Wouter Bolsterlee - - * nl.po: Updated Dutch translation by Wouter Bolsterlee. - -2008-09-13 Leonardo Ferreira Fontenelle - - * pt_BR.po: Terminology fixes in Brazilian Portuguese translation. - -2008-09-12 Gabor Kelemen - - * hu.po: Translation updated. - -2008-09-11 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer. - -2008-09-10 Luca Ferretti - - * it.po: Updated Italian translation. - -2008-09-10 Claude Paroz - - * fr.po: Updated French translation by Bruno Brouard. - -2008-09-09 Leonardo Ferreira Fontenelle - - * pt_BR.po: Brazilian Portuguese translation updated by Michel - Recondo. - -2008-09-09 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2008-09-09 Rajesh Ranjan - - * hi.po: Hindi translation updated - -2008-09-08 Rajesh Ranjan - - * hi.po: Hindi translation updated - -2008-09-07 Duarte Loreto - - * pt.po: Updated Portuguese translation. - -2008-09-07 Baris Cicek - - * tr.po: Updated Turkish translation. - -2008-09-06 Philip Withnall - - * en_GB.po: Updated British English translation. - -2008-09-06 Takeshi AIHANA - - * ja.po: Updated Japanese translation. - -2008-09-04 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2008-09-04 Rajesh Ranjan - - * mai.po: Maithili Translation Added - -2008-09-04 I. Felix - - * ta.po: Tamil Translation updated by Tirumurthi Vasudevan - -2008-09-04 Tomasz Dominikowski - - * pl.po: Updated Polish translation - -2008-09-03 Tomasz Dominikowski - - * pl.po: Updated Polish translation - -2008-09-01 Leonardo Ferreira Fontenelle - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2008-08-31 Robert-André Mauchin - - * fr.po: Updated French translation. - -2008-08-29 Inaki Larranaga Murgoitio - - * eu.po: Updated Basque translation. - -2008-08-28 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2008-08-28 Timo Jyrinki - - * fi.po: Updated Finnish translation. - * ChangeLog: Fixed some indentations to proper tabs instead of spaces. - -2008-08-25 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martine. - -2008-08-25 Goran Rakic - - * LINGUAS, sr@latin.po, sr@Latn.po: Conversion from sr@Latn to sr@latin. - -2008-08-25 Priit Laes - - * et.po: Translation updated by Ivar Smolin. - -2008-08-23 Ignacio Casal Quinteiro - - * gl.po: Updated Galician translation. - -2008-08-23 Ignacio Casal Quinteiro - - * gl.po: Updated Galician translation. - -2008-08-23 Theppitak Karoonboonyanan - - * th.po: Updated Thai traslation. - -2008-08-23 Theppitak Karoonboonyanan - - * th.po: Updated Thai traslation. - -2008-08-23 Jochen Skulj - - * de.po: Updated German translation. - -2008-08-18 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2008-08-17 Theppitak Karoonboonyanan - - * th.po: Updated Thai traslation. - -2008-08-14 Duarte Loreto - - * pt.po: Updated Portuguese translation. - -2008-08-14 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2008-08-12 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2008-08-11 Ignacio Casal Quinteiro - - * gl.po: Updated Galician translation - -2008-08-10 Ignacio Casal Quinteiro - - * gl.po: Updated Galician translation - -2008-08-08 Ignacio Casal Quinteiro - - * gl.po: Updated Galician translation - -2008-08-6 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2008-08-04 Nickolay V. Shmyrev - - * ru.po: Updated Russian translation. - -2008-08-03 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2008-07-29 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2008-07-27 Leonardo Ferreira Fontenelle - - * pt_BR.po: Fixed translation of "lock" (by Vladimir Melo). - -2008-07-25 Jorge Gonzalez - - * es.po: Updated Spanish translation, fixed typo - -2008-07-24 Leonardo Ferreira Fontenelle - - * pt_BR.po: Terminology improvements by Vladimir Melo. - -2008-07-25 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2008-07-20 Ignacio Casal Quinteiro - - * gl.po: Updated Galician Translation. - -2008-07-19 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer. - -2008-07-14 Nickolay V. Shmyrev - - * ru.po: Updated Russian translation. Thanks to - Anatol Kamynin for a useful notes. - -2008-07-05 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2008-07-03 Yannig Marchegay - - * oc.po: Updated Occitan translation. - -2008-07-01 Kjartan Maraas - - * POTFILES.in: Add missing file. - * nb.po: Updated Norwegian bokmål translation. - -2008-06-26 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer and me, also merged updates from 2-22 branch. - -2008-06-11 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2008-06-11 Yannig Marchegay - - * oc.po: Updated Occitan translation. - -2008-06-07 Kjartan Maraas - - * POTFILES.in: Add missing file. - * nb.po: Updated Norwegian bokmål translation. - -2008-06-07 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - -2008-06-04 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2008-06-02 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2008-05-24 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer. - -2008-05-23 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - -2008-05-23 Kjartan Maraas - - * POTFILES.in: Add missing file. - * nb.po: Updated Norwegian bokmål translation. - -2008-05-22 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2008-05-19 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2008-05-09 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - -2008-05-06 Kjartan Maraas - - * POTFILES.in: Account for moving and changing stuff. - * nb.po: Updated Norwegian bokmål translation. - -2008-04-30 Gabor Kelemen - - * hu.po: Translation updated. - -2008-04-12 Jochen Skulj - - * de.po: Updated German translation. - -2008-04-03 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez. - -2008-04-02 Eskild Hustvedt - - * nn.po: Added Norwegian Nynorsk translation - -2008-03-12 Sunil Mohan Adapa - - * te.po: Added Telugu traslation done by - Krishna Babu K . - -2008-03-10 Kostas Papadimas - - * el.po: Updated Greek translation by Giannis Katsampipis - -2008-03-08 Kenneth Nielsen - - * da.po: Updated Danish translation - -2008-03-08 Takeshi AIHANA - - * ja.po: Updated Japanese translation. - -2008-03-06 Petr Kovar - - * cs.po: Updated Czech translation by Lucas Lommer - and Martin Sukany. - -2008-03-05 Ani Peter - - * ml.po: Updated Malayalam Translation - -2008-03-04 Vincent van Adrighem - - * nl.po: Translation updated. - -2008-03-03 Jorge Gonzalez - - * es.po: Updated Spanish translation - -2008-03-03 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2008-03-03 Philip Withnall - - * en_GB.po: Updated British English translation. - -2008-03-02 Gabor Kelemen - - * hu.po: Translation updated - -2008-03-02 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2008-02-28 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer - -2008-02-25 Leonardo Ferreira Fontenelle - - * pt_BR.po: Brazilian Portuguese translation updated by Tiago Melo - Casal and (a little) myself. - -2008-02-25 Gil Fcthulhuda - - * ca.po: Updated Catalan translation. - -2008-02-25 Vincent van Adrighem - - * nl.po: Translation updated. - -2008-02-24 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2008-02-23 Vincent van Adrighem - - * nl.po: Translation updated. - -2008-02-22 Jochen Skulj - - * de.po: Updated German translation. - -2008-02-22 Ilkka Tuohela - - * fi.po: Updated Finnish translation (bug #490774). - -2008-02-19 Nickolay V. Shmyrev - - * ru.po: Updated Russian translation. - -2008-02-19 Gabor Kelemen - - * hu.po: Translation updated by Attila Hammer - -2008-02-19 Theppitak Karoonboonyanan - - * th.po: Updated Thai traslation. - -2008-02-18 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2008-02-18 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2008-02-17 Vincent van Adrighem - - * nl.po: Translation updated. - -2008-02-17 Jovan Naumovski - - * mk.po: Updated Macedonian translation. - -2008-02-17 Nguyễn Thái Ngọc Duy - - * vi.po: Fixed "Tin nhẳn" - -2008-02-16 Claude Paroz - - * fr.po: Updated French translation by Robert-André Mauchin and Claude - Paroz. - -2008-02-15 Runa Bhattacharjee - - * kn.po: Added Kannada Translations by Shankar Prasad - * LINGUAS: Added Kannada (kn) to the List of Languages - -2008-02-14 Pawan Chitrakar - - * ne.po: Updated Nepali Translation. - -2008-02-14 Duarte Loreto - - * pt.po: Updated Portuguese translation. - -2008-02-13 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2008-02-13 Chao-Hsiung Liao - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2008-02-11 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2008-02-10 Duarte Loreto - - * pt.po: Updated Portuguese translation. - -2008-02-09 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2008-02-08 Luca Ferretti - - * it.po: Updated Italian translation. - -2008-02-08 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2008-02-08 Jochen Skulj - - * de.po: Updated German translation. - -2008-02-05 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez, fixes bug #511632 - -2008-02-02 Yannig Marchegay - - * oc.po: Updated Occitan translation. - -2008-01-31 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2008-01-29 Luca Ferretti - - * it.po: Updated Italian translation. - -2008-01-28 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2008-01-26 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2008-01-21 Kjartan Maraas - - * POTFILES.in: use constants.py.in here. - * nb.po: Updated Norwegian bokmål translation. - * POTFILES.skip: Add constants.py here since it's generated. - -2008-01-21 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2008-01-15 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2008-01-15 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2008-01-13 Andre Klapper - - * POTFILES.in: Fix src/louis/constants.py entry. - -2008-01-10 Luca Ferretti - - * it.po: Updated Italian translation. - -2008-01-05 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2008-01-03 Jorge Gonzalez - - * es.po: Updated Spanish translation - by Francisco Javier Dorado Martinez - -2008-01-02 Priit Laes - - * et.po: Translation updated by Ivar Smolin - -2007-12-31 Yannig Marchegay - - * oc.po: Updated Occitan translation. - -2007-12-31 Priit Laes - - * et.po: Translation updated by Ivar Smolin echo - -2007-12-31 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-12-18 Jorge Gonzalez - - * es.po: Updated Spanish translation - by Francisco Javier Dorado Martinez - -2007-12-17 Kjartan Maraas - - * POTFILES.in: Add mag.py. - * nb.po: Updated Norwegian bokmål translation. - -2007-12-15 Jorge Gonzalez - - * es.po: Updated Spanish translation - by Francisco Javier Dorado Martinez - -2007-12-12 Jorge Gonzalez - - * es.po: Updated Spanish translation - by Francisco Javier Dorado Martinez - -2007-12-10 Matej Urbančič - - * sl.po: Updated Slovenian Translation. - -2007-12-09 Changwoo Ryu - - * ko.po: Updated Korean translation. - -2007-12-01 Urbančič Matej - - * sl.po: Updated Slovenian translation. - -2007-11-28 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2007-11-27 Urbančič Matej - - * sl.po: Updated Slovenian translation. - -2007-11-26 Gabor Kelemen - - * hu.po: Translation updated by Kálmán Kéménczy - -2007-11-23 Matej Urbančič - - * sl.po: Updated Slovenian translation. - -2007-11-14 Ignacio Casal Quinteiro - - * gl.po: Updated Galician Translation. - -2007-11-13 Matej Urbančič - - * sl.po: Updated Slovenian Translation. - -2007-11-03 Leonardo Ferreira Fontenelle - - * pt_BR.po: Brazilian Portuguese translation updated by Tiago Melo - Casal. - -2007-11-02 Espen Stefansen - - * nb.po: Updated Norwegian Bokmål translation. - -2007-10-24 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-10-24 Willie Walker - - * POTFILES.in: Added gnome-mud. - -2007-10-23 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-10-23 Matej Urbančič - - * sl.po: Updated Slovenian translation. - -2007-10-21 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-10-19 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2007-10-16 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-10-04 Jorge Gonzalez - - * es.po: Updated Spanish translation - -2007-09-25 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2007-09-23 Gil Fcthulhuda - - * ca.po: Updated Catalan translation by Joan Duran. - -2007-09-18 Maxim Dziumanenko - - * uk.po: Update Ukrainian translation. - * ru.po: Fix some typos. - -2007-09-17 Gintautas Miliauskas - - * lt.po: Updated Lithuanian translation. - -2007-09-16 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-09-16 Gil Fcthulhuda - - * ca.po: Fixed a msgfmt error - -2007-09-16 Takeshi AIHANA - - * ja.po: Updated Japanese translation. - -2007-09-15 Gil Fcthulhuda - - * ca.po: Updated Catalan translation. - -2007-09-14 Laurent Dhima - - * sq.po: Added Albanian translation. - -2007-09-11 Duarte Loreto - - * pt.po: Updated Portuguese translation. - -2007-09-09 Anatoly Kamynin - - * ru.po: Updated Russian translation. - -2007-09-09 Raphael Higino - - * pt_BR.po: Updated Brazilian Portuguese translation - by Tiago Melo Casal . - -2007-09-09 Espen Stefansen - - * nb.po: Updated Norwegian bokmål translation. - -2007-09-09 Raphael Higino - - * pt_BR.po: Updated Brazilian Portuguese translation - by Tiago Melo Casal . - -2007-09-09 Kenneth Nielsen - - * da.po: Updated Danish translation - -2007-09-05 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2007-09-04 Raphael Higino - - * pt_BR.po: Updated Brazilian Portuguese translation - by Djavan Fagundes . - -2007-09-04 Jochen Skulj - - * de.po: Updated German translation. - -2007-09-02 Leonardo Ferreira Fontenelle - - * pt_BR.po: Brazilian Portuguese translatioin updated by Djavan - Fagundes and me. - -2007-09-01 Nikos Charonitakis - - * el.po: Updated Greek translation. - -2007-09-01 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-09-01 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-08-27 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2007-08-26 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-08-25 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-08-24 Jovan Naumovski - - * mk.po: Updated Macedonian translation. - -2007-08-23 Kenneth Nielsen - - * da.po: Updated Danish translation - -2007-08-21 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2007-08-20 Danishka Navin - - * si.po: Updated Sinhala translation by Danishka Navin. - * LINGUAS: Added entry 'si' (Sinhala). - -007-08-19 Leonardo Ferreira Fontenelle - - * pt_BR.po: Brazilian Portuguese translation updated by Djavan - Fagundes . - -2007-08-18 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-08-17 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2007-08-16 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-08-14 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-08-14 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2007-08-12 Jochen Skulj - - * de.po: Updated German translation. - -2007-08-11 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-08-09 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-08-06 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-08-03 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2007-07-26 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2007-07-21 Leonardo Ferreira Fontenelle - - * pt_BR.po: Brazilian Portuguese translation improved as part of bug - #456758. - -2007-06-20 Raivis Dejus - - * lv.po: Updated Latvian Translation. - -2007-07-19 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-07-16 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-07-16 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2007-07-09 I. Felix - - * ta.po: Added Tamil translation. - -2007-07-09 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado - Martinez - -2007-07-01 Nguyễn Thái Ngọc Duy - - * vi.po: Updated Vietnamese translation. - -2007-06-29 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2007-06-28 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2007-06-15 Jorge Gonzalez - - * es.po: Updated Spanish translation by Francisco Javier Dorado Martinez - -2007-06-13 Pema Geyleg - - * dz.po: Updated dzongkha translation. - -2007-06-05 Jakub Friedl - - * cs.po: Updated Czech translation - -2007-05-27 Jochen Skulj - - * de.po: Fixed bug #440530 - -2007-05-20 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-05-20 Jochen Skulj - - * de.po: Updated German translation - -2007-05-15 David Lodge - - * en_GB.po: Updated British English translation - -2007-05-15 Daniel Nylander - - * POTFILES.in: Added missing file and sorted the list. - -2007-04-27 David Lodge - - * en_GB.po: Updated British English translation - -2007-04-25 David Lodge - - * en_GB.po: Updated British English translation - -2007-04-25 David Lodge - - * en_GB.po: Updated British English translation - -2007-04-23 David Lodge - - * en_GB.po: Updated British English translation - -2007-04-22 Jorge Gonzalez - - * es.po: Updated Spanish translation - by Francisco Javier Dorado Martinez and me. - -2007-04-21 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-04-14 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-04-12 Daniel Nylander - - * sv.po: Updated Swedish translation. - * POTFILES.in: Added missing file. - -2007-03-25 Jochen Skulj - - * de.po: Updated German translation - -2007-03-19 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2007-03-16 Peter Bach - - * da.po: Updated Danish translation. - * LINGUAS: Added entry 'da' (danish). - -2007-03-14 David Lodge - - * en_GB.po: Updated English (British) translation - -2007-03-13 Josep Puigdemont i Casamajó - - * ca.po: Updated Catalan translation by - Gil Fcthulhuda . - -2007-03-11 Raphael Higino - - * pt_BR.po: Updated Brazilian Portuguese translation - by Og Maciel . - -2007-03-11 Gintautas Miliauskas - - * lt.po: Updated Lithuanian translation. - -2007-03-11 Josep Puigdemont i Casamajó - - * ca.po: Updated Catalan translation, merged from gnome-2-18. - -2007-03-10 Hendrik Richter - - * de.po: Updated German translation. - -2007-03-09 Hendrik Richter - - * de.po: Updated German translation, by - Jochen Skulj - -2007-03-07 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2007-03-06 Hendrik Richter - - * de.po: Updated German translation, by - Jochen Skulj - -2007-03-06 Nguyễn Thái Ngọc Duy - - * vi.po: Updated Vietnamese translation. - -2007-03-06 David Lodge - - * en_GB.po: Updated English (British) translation - -2007-03-05 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-03-05 Chao-Hsiung Liao - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2007-03-05 Gabor Kelemen - - * hu.po: Translation updated. - -2007-03-04 Duarte Loreto - - * pt.po: Updated Portuguese translation. - -2007-03-04 Luca Ferretti - - * it.po: Updated Italian translation. - -2007-03-04 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-03-04 Pema Geyleg - - * dz.po: Updated Dzongkha Translation. - -2007-03-04 Chao-Hsiung Liao - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2007-03-04 Stéphane Raimbault - - * fr.po: Updated French translation. - -2007-03-3 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-03-03 Changwoo Ryu - - * ko.po: Updated Korean translation. - -2007-03-01 Maxim Dziumanenko - - * uk.po: Update Ukrainian translation. - -2007-02-28 Djihed Afifi - - * ar.po: Updated Arabic Translation by . - -2007-02-28 Nickolay V. Shmyrev - - * ru.po: Updated Russian translation. - -2007-02-27 Gintautas Miliauskas - - * lt.po: Updated Lithuanian translation. - -2007-02-27 Hendrik Richter - - * de.po: Updated German translation, by - Jochen Skulj - -2007-02-26 Luca Ferretti - - * it.po: Updated Italian translation. - -2007-02-25 Changwoo Ryu - - * ko.po: Updated Korean translation. - -2007-02-24 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2007-02-23 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2007-02-22 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2007-02-22 Abel Cheung - - * zh_CN.po: Updated simplified Chinese translation on behalf of - Funda Wang. - -2007-02-20 Artur Flinta - - * pl.po: Updated Polish translation by GNOME PL Team. - -2007-02-20 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-02-19 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-02-16 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2007-02-16 Djihed Afifi - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2007-02-16 Djihed Afifi - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2007-02-16 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-02-14 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-02-13 Duarte Loreto - - * pt.po: Updated Portuguese translation. - -2007-02-09 Stéphane Raimbault - - * fr.po: Updated French translation by Jonathan Ernst. - -2007-02-9 Djihed Afifi - - * ar.po: Updated Arabic Translation by Khaled Hosny. - -2007-02-09 David Lodge - - * en_GB.po: Updated English (British) translation - -2007-02-8 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-02-07 Chao-Hsiung Liao - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2007-02-07 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-02-04 Stéphane Raimbault - - * fr.po: Updated French translation by Jonathan Ersnt. - -2007-02-04 Theppitak Karoonboonyanan - - * th.po: Updated Thai traslation by - Supranee Thirawatthanasuk . - -2007-02-01 Stéphane Raimbault - - * fr.po: Updated French translation by Robert-André Mauchin and - Stéphane Raimbault. - -2007-01-25 Josep Puigdemont i Casamajó - - * ca.po: Updated Catalan translation by - Gil Fcthulhuda . - -2007-01-24 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2007-01-23 David Lodge - - * en_GB.po: Updated English (British) translation - -2007-01-23 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-01-22 Luca Ferretti - - * it.po: Updated Italian translation. - -2007-01-17 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2007-01-16 Hendrik Richter - - * de.po: Updated German translation, fix #395587. - -2007-01-16 Jovan Naumovski - - * mk.po: Updated Macedonian translation. - -2007-01-13 Djihed Afifi - - * ar.po: Updated Arabic Translation by Mohamed Magdy. - -2007-01-12 Daniel Nylander - - * sv.po: Updated Swedish translation. - * POTFILES.in: Added missing files. - -2007-01-10 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-01-09 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2007-01-09 David Lodge - - * en_GB.po: Updated English (British) translation - -2007-01-3 Djihed Afifi - - * ar.po: Updated Arabic Translation by Djihed Afifi. - -2007-01-01 David Lodge - - * en_GB.po: Updated English (British) translation - -2006-12-29 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2006-12-27 Djihed Afifi - - * ar.po: Updated Arabic Translation. - -2006-12-26 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2006-12-24 Djihed Afifi - - * ar.po: Updated Arabic Translation. - -2006-12-22 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-12-21 Djihed Afifi - - * ar.po: Updated Arabic Translation. - -2006-12-18 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2006-12-18 Djihed Afifi - - * ar.po: Added Arabic Translation. - * LINGUAS: Added ar. - -2006-12-12 Jorge Sandín - - * es.po: Updated Spanish translation. - -2006-12-12 Matic Zgur - - * sl.po: Added Slovenian translation. - * LINGUAS: Added sl to the list of available languages. - -2006-12-11 Kjartan Maraas - - * POTFILES.in: Update this. - * nb.po: Updated Norwegian bokmål translation. - -2006-12-11 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-11-23 Daniel Nylander - - * sv.po: Swedish translation updated. - -2006-11-17 Gabor Kelemen - - * hu.po: Translation added. - -2006-11-05 Priit Laes - - * et.po: Translation updated by Ivar Smolin. - -2006-11-01 Priit Laes - - * et.po: Translation updated by Ivar Smolin. - -2006-11-01 Kjartan Maraas - - * POTFILES.in: Add encoding bits - * nb.po: Updated Norwegian bokmål translation. - -2006-10-22 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2006-10-20 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2006-10-19 Priit Laes - - * et.po: Translation updated by Ivar Smolin. - -2006-10-14 Priit Laes - - * et.po: Translation updated by Ivar Smolin. - -2006-10-14 Priit Laes - - * et.po: Translation updated by Ivar Smolin. - -2006-10-13 Priit Laes - - * et.po: Translation updated by Ivar Smolin. - -2006-10-11 Priit Laes - - * et.po: Translation updated by Ivar Smolin. - -2006-10-05 Priit Laes - - * et.po: Translation updated by Ivar Smolin. - -2006-10-01 Theppitak Karoonboonyanan - - * th.po: Added Thai traslation by - Supranee Thirawatthanasuk . - * LINGUAS: Added th (Thai). - -2006-09-25 Ignacio Casal Quinteiro - - * gl.po: Updated Galician Translation. - * LINGUAS: Added 'gl' entry - -2006-09-10 Priit Laes - - * et.po: Added Estonian Translation file - * LINGUAS: Added entry 'et' (Estonian) - -2006-09-06 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-09-06 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-09-06 Simos Xenitellis - - * el.po: Updated Greek translation. - -2006-09-06 Pema Geyleg - - * dz.po: Updated Dzongkha Translation - -2006-09-04 Baris Cicek - - * tr.po: Added Turkish Translation from Deniz Kocak - * LINGUAS: Added entry 'tr' (turkish) - -2006-09-03 Subhransu Behera - - * or.po: Updated Oriya Translation. - -2006-09-03 Hendrik Richter - - * de.po: Updated German translation. - -2006-09-02 Wouter Bolsterlee - - * nl.po: Translation updated by Wouter Bolsterlee. - -2006-08-31 Rajesh Ranjan - - * hi.po: Updated Hindi Translation. - -2006-09-01 Kjartan Maraas - - * po/LINGUAS: Add forgotten nb entry. - -2006-09-01 Jovan Naumovski - - * mk.po: Updated Macedonian translation. - -2006-08-31 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2006-08-31 Chao-Hsiung Liao - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2006-08-31 Alexander Shopov - - * bg.po: Updated Bulgarian translation by - Alexander Shopov - -2006-08-31 Jovan Naumovski - - * mk.po: Updated Macedonian translation. - -2006-08-30 Christophe Merlet - - * fr.po: Updated French translation from - Robert-André Mauchin - -2006-08-30 Rajesh Ranjan - - * hi.po: Updated Hindi Translation. - -2006-08-29 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation by Francisco Dorado. - -2006-08-29 Rajesh Ranjan - - * hi.po: Updated Hindi Translation. - -2006-08-29 Gintautas Miliauskas - - * lt.po: Updated Lithuanian translation. - -2006-08-28 Inaki Larranaga - - * eu.po: Added Basque translation. - * LINGUAS: Added "eu" (Basque) entry. - -2006-08-28 Ani Peter - - * ml.po: Added and Updated MAlayalm translation - * LINGUAS: Added Malayalam (ml) to the list of Languages - -2006-08-25 Duarte Loreto - - * pt.po: Updated Portuguese translation. - -2006-08-24 Vincent van Adrighem - - * nl.po: Translation updated. - -2006-08-24 Raivis Dejus - - * lv.po: Updated Latvian translation. - -2006-08-23 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2006-08-21 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2006-08-20 Subhransu Behera - - * or.po: Added and Updated Oriya Translation. - * LINGUAS: Added Oriya (or) to The List of Languages. - -2006-08-19 Vincent van Adrighem - - * nl.po: Translation updated by Tino Meinen. - -2006-08-17 Hendrik Brandt - - * de.po: Updated German translation. - -2006-08-17 Nikos Charonitakis - - * el.po: Updated Greek translation. - -2006-08-17 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2006-08-16 Daniel Nylander - - * sv.po: Updated Swedish translation. - -2006-08-16 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2008-08-16 Josep Puigdemont i Casamajó - - * ca.po: Updated Catalan translation by - Gil Fcthulhuda - -2006-08-14 Žygimantas Beručka - - * lt.po: Added Lithuanian translation. - * LINGUAS: Added "lt". - -2006-08-14 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-08-14 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2006-08-14 Nickolay V. Shmyrev - - * LINGUAS: - * ru.po: Added Russian translation. - -2006-08-13 Rahul Bhalerao - - * mr.po: Updated Marathi Translation - * LINGUAS: Added entry for Marathi(mr) - -2006-08-13 Changwoo Ryu - - * ko.po: Updated Korean translation. - -2006-08-12 Satoru SATOH - - * ja.po: Added Japanese translation. - -2006-08-12 Chao-Hsiung Liao - - * zh_HK.po: Updated Traditional Chinese translation(Hong Kong). - * zh_TW.po: Updated Traditional Chinese translation(Taiwan). - -2006-08-10 Jovan Naumovski - - * mk.po: Updated Macedonian translation. - -2006-08-10 Josep Puigdemont i Casamajó - - * ca.po: Added Catalan translation by - Gil Fcthulhuda - -2006-08-10 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-08-10 Guntupalli Karunakar - - * dz.po: Updated Dzongkha translation by - Dzongkhalinux team, DIT - -2006-08-09 Sigurd Gartmann - - * nb.po: Update Norwegian Bokmål translation. - -2006-08-09 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2006-08-09 Maxim Dziumanenko - - * uk.po: Update Ukrainian translation. - -2006-08-07 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-08-07 Changwoo Ryu - - * ko.po, LINGUAS: Added Korean translation. - -2006-08-06 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-08-06 Jovan Naumovski - - * mk.po: Updated Macedonian translation. - -2006-08-02 Jovan Naumovski - - * mk.po: Updated Macedonian translation. - -2006-07-31 Vincent van Adrighem - - * nl.po: Translation updated by Tino Meinen. - -2006-07-31 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-07-29 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-07-26 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-07-25 Nikos Charonitakis - - * el.po: Added Greek translation. - -2006-07-20 Francisco Javier F. Serrador - - * es.po: Updated SPanish translation. - -2006-07-20 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-07-19 Kjartan Maraas - - * nb.po: Updated Norwegian bokmål translation. - -2006-07-18 Guntupalli Karunakar - - * dz.po: Updated Dzongkha translation by - Dzongkhalinux team, DIT - -2006-07-18 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-07-17 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2006-07-17 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-07-14 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-07-14 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2006-07-09 Alexander Shopov - - * bg.po: Added Bulgarian translation by - Alexander Shopov - -2006-07-07 Ilkka Tuohela - - * fi.po: Updated Finnish translation. - -2006-07-03 Runa Bhattacharjee - - * bn_IN.po: Added Bengali India Translation. - -2006-07-02 Ilkka Tuohela - - * fi.po: Added Finnish translation. - -2006-06-30 Jovan Naumovski - - * mk.po: Added Macedonian Translation - -2006-06-30 Guntupalli Karunakar - - * dz.po: Added Dzongkha translation by Dzongkhalinux team. - -2006-06-29 Rajesh Ranjan - * hi.po: Updated Hindi Translation - -2006-06-29 Rajesh Ranjan - * hi.po: Added Hindi Translation - -2006-06-27 Runa Bhattacharjee - * bn.po: Added partial Bengali (bn) Translation. - -2006-06-27 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-06-26 Vincent van Adrighem - - * nl.po: Translation updated by Tino Meinen. - -2006-06-23 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-06-22 Rhys Jones - - * cy.po: Added Welsh translation. - -2006-06-22 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-06-21 I. Felix - - * ta.po: Added Tamil translation. - -2006-06-20 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-06-19 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-06-18 Francisco Javier F. Serrador - - * es.po: Actualización con las indicaciones de F. Dorado - -2006-06-16 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-06-16 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-06-14 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2006-06-14 Ankit Patel - - * gu.po: Updated Gujarati Translation. - -2006-05-27 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2006-05-26 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2006-04-17 Vincent van Adrighem - - * nl.po: Translation updated. - -2006-04-10 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2006-03-30 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2006-02-24 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2006-02-14 Clytie Siddall - - * vi.po: Updated Vietnamese translation. - -2006-02-09 Clytie Siddall - - * vi.po: Added Vietnamese translation. - -2006-01-16 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-12-31 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2005-12-26 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-12-21 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2005-12-10 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2005-11-19 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2005-11-17 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-10-19 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-10-17 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2005-10-11 Pawan Chitrakar - - * ne.po: Added Nepali Translation - -2005-10-06 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-09-23 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-09-06 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-08-31 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-08-28 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2005-08-19 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-08-16 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-08-13 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2005-08-13 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-08-08 Maxim Dziumanenko - - * uk.po: Added Ukrainian translation, - -2005-08-03 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-08-02 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-07-31 Adam Weinberger - - * POTFILES.in: Added missing file. - * en_CA.po: Updated Canadian English translation. - -2005-07-30 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-07-29 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-07-27 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-07-22 Adam Weinberger - - * POTFILE.in: Add missing files. - * en_CA.po: Updated Canadian English translation. - -2005-07-13 Hendrik Brandt - - * de.po: Updated German translation. - -2005-07-13 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation María Majadas - -2005-07-03 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-04-26 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation by María Majadas. - -2005-04-22 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation by María Majadas. - -2005-04-20 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-04-19 David Lodge - - * en_GB.po: Updated British English translation. - -2005-04-16 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-04-10 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation by Maria Majadas. - -2005-04-10 Raphael Higino - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2005-04-09 Hendrik Brandt - - * de.po: Updated German translation. - -2005-04-02 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-04-01 Steve Murphy - - * rw.po: Added Kinyarwanda translation. - -2005-04-01 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-04-01 Hendrik Brandt - - * de.po: Updated German translation. - -2005-03-31 Miloslav Trmac - - * cs.po: Updated Czech translation. - -2005-03-26 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-03-16 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2005-02-07 Christian Rose - - * .cvsignore: Added many entries. - -2005-02-03 Alessio Frusciante - - * it.po: Added Italian translation by - Aldo Giambelluca . - -2004-10-31 Vincent van Adrighem - - * nl.po: Translation updated by Taco Witte. - -2004-10-22 Hendrik Brandt - - * de.po: Updated German translation - -2004-10-18 Miloslav Trmac - - * cs.po: Updated Czech translation. - -2004-10-17 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2004-10-17 Raphael Higino - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2004-10-17 David Lodge - - * en_GB.po: Updated British English translation. - -2004-10-16 Danilo Šegan - - * sr.po, sr@Latn.po: Added Serbian translation. - - * POTFILES.in: Added src/cthulhu/metacity.py. - -2004-09-09 Ankit Patel - - * gu.po: Added Gujarati Translation. - -2004-09-07 David Lodge - - * en_GB.po: Updated British translation. - -2004-09-01 Estêvão Samuel Procópio - - * pt_BR.po: Updated Brazilian Portuguese translation. - -2004-08-31 Hendrik Brandt - - * de.po: Updated German translation - -2004-08-28 Miloslav Trmac - - * cs.po: Updated Czech translation. - -2004-08-28 Adam Weinberger - - * en_CA.po: Updated Canadian English translation. - -2004-08-28 Vincent van Adrighem - - * nl.po: Translation updated by Elros Cyriatan. - -2004-08-24 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2004-08-21 Francisco Javier F. Serrador - - * es.po: Updated Spanish translation. - -2004-07-02 Hendrik Brandt - - * de.po: Added german translation by - Hendrik Brandt . - -2004-06-28 Christophe Merlet - - * fr.po: Added French translation from - Cedric Corazza . - -2004-06-21 Gustavo Noronha Silva - - * pt_BR.po: translation update by - "Raphael Higino" - -2004-06-19 Vincent van Adrighem - - * nl.po: Translation added by Elros Cyriatan. - -2004-06-10 Gustavo Noronha Silva - - * pt_BR.po: added translation done by - "Raphael Higino" - -2004-06-07 Funda Wang - - * zh_CN.po: Added Simplified Chinese translation. - -2004-06-02 Gareth Owen - - * en_GB.po: Updated British English translation - -2004-05-31 Duarte Loreto - - * pt.po: Added Portuguese translation. - -2004-05-30 Adam Weinberger - - * en_CA.po: Added Canadian English translation. - -2004-05-29 Miloslav Trmac - - * cs.po: Added Czech translation. - -2004-05-27 Christian Rose - - * sv.po: Added Swedish translation. - * POTFILES.in: Added missing file and sorted. - -2004-05-19 Marc Mulcahy - - * Created. - diff --git a/po/LINGUAS b/po/LINGUAS deleted file mode 100644 index c9c2291..0000000 --- a/po/LINGUAS +++ /dev/null @@ -1,84 +0,0 @@ -# please keep this list sorted alphabetically -# -ab -an -ar -ast -be -bg -bn -bn_IN -bs -ca -ca@valencia -ckb -cs -cy -da -de -dz -el -en_CA -en_GB -eo -es -et -eu -fa -fi -fr -fur -ga -gl -gu -he -hi -hr -hu -id -is -it -ja -ka -kab -kk -kn -ko -lt -lv -mai -mk -ml -mr -ms -nb -ne -nl -nn -oc -or -pa -pl -pt -pt_BR -ro -ru -rw -si -sk -sl -sq -sr -sr@latin -sv -ta -te -tg -th -tr -ug -uk -vi -zh_CN -zh_HK -zh_TW diff --git a/po/Makevars b/po/Makevars deleted file mode 100644 index c0da25e..0000000 --- a/po/Makevars +++ /dev/null @@ -1,78 +0,0 @@ -# Makefile variables for PO directory in any package using GNU gettext. - -# Usually the message domain is the same as the package name. -DOMAIN = $(PACKAGE) - -# These two variables depend on the location of this directory. -subdir = po -top_builddir = .. - -# These options get passed to xgettext. -XGETTEXT_OPTIONS = --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 --keyword=g_dngettext:2,3 --add-comments - -# This is the copyright holder that gets inserted into the header of the -# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding -# package. (Note that the msgstr strings, extracted from the package's -# sources, belong to the copyright holder of the package.) Translators are -# expected to transfer the copyright for their translations to this person -# or entity, or to disclaim their copyright. The empty string stands for -# the public domain; in this case the translators are expected to disclaim -# their copyright. -COPYRIGHT_HOLDER = The Cthulhu Team. - -# This tells whether or not to prepend "GNU " prefix to the package -# name that gets inserted into the header of the $(DOMAIN).pot file. -# Possible values are "yes", "no", or empty. If it is empty, try to -# detect it automatically by scanning the files in $(top_srcdir) for -# "GNU packagename" string. -PACKAGE_GNU = no - -# This is the email address or URL to which the translators shall report -# bugs in the untranslated strings: -# - Strings which are not entire sentences, see the maintainer guidelines -# in the GNU gettext documentation, section 'Preparing Strings'. -# - Strings which use unclear terms or require additional context to be -# understood. -# - Strings which make invalid assumptions about notation of date, time or -# money. -# - Pluralisation problems. -# - Incorrect English spelling. -# - Incorrect formatting. -# It can be your email address, or a mailing list address where translators -# can write to without being subscribed, or the URL of a web page through -# which the translators can contact you. -MSGID_BUGS_ADDRESS = https://groups.io/g/stormux - -# This is the list of locale categories, beyond LC_MESSAGES, for which the -# message catalogs shall be used. It is usually empty. -EXTRA_LOCALE_CATEGORIES = - -# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' -# context. Possible values are "yes" and "no". Set this to yes if the -# package uses functions taking also a message context, like pgettext(), or -# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. -USE_MSGCTXT = yes - -# These options get passed to msgmerge. -# Useful options are in particular: -# --previous to keep previous msgids of translated messages, -# --quiet to reduce the verbosity. -MSGMERGE_OPTIONS = - -# These options get passed to msginit. -# If you want to disable line wrapping when writing PO files, add -# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and -# MSGINIT_OPTIONS. -MSGINIT_OPTIONS = - -# This tells whether or not to regenerate a PO file when $(DOMAIN).pot -# has changed. Possible values are "yes" and "no". Set this to no if -# the POT file is checked in the repository and the version control -# program ignores timestamps. -PO_DEPENDS_ON_POT = no - -# This tells whether or not to forcibly update $(DOMAIN).pot and -# regenerate PO files on "make dist". Possible values are "yes" and -# "no". Set this to no if the POT file and PO files are maintained -# externally. -DIST_DEPENDS_ON_UPDATE_PO = no diff --git a/po/POTFILES.in b/po/POTFILES.in deleted file mode 100644 index 9ba28c5..0000000 --- a/po/POTFILES.in +++ /dev/null @@ -1,18 +0,0 @@ -# List of source files containing translatable strings. -# Please keep this file sorted alphabetically. -src/cthulhu/braille_rolenames.py -src/cthulhu/brltablenames.py -src/cthulhu/chnames.py -src/cthulhu/cmdnames.py -src/cthulhu/colornames.py -src/cthulhu/guilabels.py -src/cthulhu/keynames.py -src/cthulhu/keybindings.py -src/cthulhu/mathsymbols.py -src/cthulhu/messages.py -src/cthulhu/object_properties.py -src/cthulhu/cthulhu-find.ui -src/cthulhu/cthulhu-setup.ui -src/cthulhu/phonnames.py -src/cthulhu/text_attribute_names.py -src/cthulhu/tutorialgenerator.py diff --git a/po/POTFILES.skip b/po/POTFILES.skip deleted file mode 100644 index c539602..0000000 --- a/po/POTFILES.skip +++ /dev/null @@ -1,3 +0,0 @@ -src/louis/constants.py -src/cthulhu/settings_manager.py -src/cthulhu/cthulhu_bin.py diff --git a/po/ab.po b/po/ab.po deleted file mode 100644 index bca8102..0000000 --- a/po/ab.po +++ /dev/null @@ -1,9207 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: cthulhu 48.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2026-01-02 10:46-0500\n" -"Last-Translator: Нанба Наала \n" -"Language-Team: Abkhazian \n" -"Language: ab\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-DamnedLies-Scope: partial\n" - -msgid "Cthulhu Screen Reader" -msgstr "" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "аамҭ." - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "арадио" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "абз" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "авто" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Арабтә аҩаӡара" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Валлиатә аҩаӡара 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Валлиатә аҩаӡар 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Британиатәи англиски аҩаӡара 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Британиатәи англиски аҩаӡара 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Англызбызшәа аҩаӡара 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Англызбызшәа аҩаӡара 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Венгриатәи 8- кәаԥкны иҟоу акомпиутер" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Венгриатәи аҩаӡара 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Венгриатәи аҩаӡара 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Бельгиа голландиатәи аҩаӡара 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "аҭаӡҩырартәра" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "насгьы" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "аиҟәыҭхага" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "еиҳаны" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "Азҵаара" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "агәҵәытә цәаҳәа" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "агәҵәытә цәаҳәа аиԥырҟьа аманы" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "аҟәша" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "аԥҵаҩы изин" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "Хыхьтәи аиндекс а" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "Хыхьтәи аиндекс ҩба" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "Хыхьтәи аиндекс хԥа" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "абзац" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "Хыхьтәи аиндекс акы" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "ақәыӷәӷәара змоу" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "Шьҭахьлатәи ақәыӷәӷәара змоу" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "ахҩа змоу" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "тильда змоу" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "умлиаут змоу" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "аикәагьежь змоу" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ае" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "Хыхьтәи аиндекс 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "Хыхьтәи аиндекс 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "Хыхьтәи аиндекс 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "Хыхьтәи аиндекс 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "Хыхьтәи аиндекс 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "Хыхьтәи аиндекс 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "Хыхьтәи аиндекс 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "Хыхьтәи аиндекс плиус" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "Хыхьтәи аиндекс минус" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "Хыхьтәи аиндекс иҟалоит" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "Хыхьтәи аиндекс ахыц аартра" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "Хыхьтәи аиндекс ахыц аркра" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "Хыхьтәи аиндекс n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Аԥшаара аиҿцәажәара аԥенџьыр аартра" - -#: src/cthulhu/cmdnames.py:118 -#, fuzzy -msgid "Show actions list" -msgstr "Анаҩстәи ахьӡынҵа ахь аиасра" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Аҭалара мамзар аҭыҵра азеиԥш хәаԥшра аҟынтә" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Браиль иркьаҿу ишрифт аҿакра, мамзар аҿыхра" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Арыдқәа рыҭҵаара арежим аҭалара.Шәақәыӷәӷәа escape уи арежим аҭыҵразы" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Иаҧхьааиуа аобиект ахь аиасра" - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Иалху атекст: %s" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "Абжьы ахкы ахышәарақәа" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr " Аамҭала ацәажәара аҿакра, мамзар аҿыхра" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Иаԥхьааиуа агәылаҵа ахь аиасра" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Агәылаҵа ахь аиасра" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Анаҩстәи агәылаҵа ахь аиасра" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Агәылаҵа ацҵара" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Хыхьтәи армаратәи" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "Ардыррақәа рыхьӡынҵа аҟынтә аҭыҵра" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Анаҩстәи асимвол ахь аиасра" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Иаҧхьааиуа асимвол ахь аиасра" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Анаҩстәи ажәа ахь аиасра" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Иаҧхьааиуа асимвол ахь аиасра" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Анаҩстәи ацәаҳәа ахь аиасра" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Иаҧхьааиуа ацәаҳәа ахь аиасра" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Афаил алагамҭахь аиасра" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Афаил анҵәамҭахь аиасра" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Ацәаҳәа алагамҭахь аиасра" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Ацәаҳәа анҵәамҭахь аиасра" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Анаҩстәи аобиект ахь аиасра" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Иаҧхьааиуа аобиект ахь аиасра" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Еилаҵоу ахырхарҭарбара арыдқәа рҿакра, мамзар рҿыхра" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Иаҧхьааиуа ацитатақәа раагара реизга ахь аиасра" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Анаҩстәи ацитатақәа реидкыла ахь аиасра" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Иаҧхьааиуа апытҟәыр ахь аиасра" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Анаҩстәи апытҟәыр ахь аиасра" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Иаҧхьааиуа апытҟәыр-бираҟ ахь аиасра" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Анаҩстәи апытҟәыр-бираҟ ахь аиасра" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Ақәыӷәӷәаразы иаҧхьааиуа аобиект ахь аиасра" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Ақәыӷәӷәаразы анаҩстәи аобиект ахь аиасра" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Иаҧхьааиуа ахьӡынҵа аҭыҧ ахь аиасра" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Анаҩстәи аҭыԥ ахьӡынҵа зцу ахь аиасра" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Аконтеинер алагамҭахь аиасра" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Аконтеинер анҵәамҭахь аиасра" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Иаҧхьааиуа аҭагалара аҭыҧ ахь аиасра" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Анаҩстәи аҭагалара ҭыԥ ахь аиасра" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Иаҧхьааиуа аҭыҧ аформа ахь аиасра" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Анаҩстәи аҭыҧ аформа ахь аиасра" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Иаҧхьааиуа ахы ахь аиасра" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Анаҩстәи ахы ахь аиасра" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Ахы аҩаӡара %d ахь аиасра " - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Анаҩстәи ахы %d аҩаӡара ахь аиасра" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "Иаҧхьааиуа аҭаӡҩыра ахь аиасра" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "Анаҩстәи аҭаӡҩыра ахь аиасра" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Иаҧхьааиуа аҧшранҵа ахь аиасра" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Анаҩстәи аԥшранҵа ахь аиасра" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Иаҧхьааиуа ахырхарҭа ахь аиасра" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Анаҩстәи ахырхарҭа ахь аиасра" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Иаҧхьааиуа идуу аобиект ахь аиасра" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Анаҩстәи идуу аобиект ахь аиасра" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Иаҧхьааиуа ахьӡынҵа ахь аиасра" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Анаҩстәи ахьӡынҵа ахь аиасра" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Иаҧхьааиуа ахьӡынҵа асимвол ахь аиасра" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Ахьӡынҵа анаҩстәи аелемент ахь аиасра" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Иаҧхьааиуа зҽызыҧсахуа аҵакыра ахь аиасра" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Анаҩстәи зҽызԥсахуа аобласть ахь аиасра " - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Аҵыхәтәантәи алаҳәара ззыҟаҵаз зҽызыҧсахуа аҵакыра ахь аиасра " - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "Еилаҵоу ахырхарҭарбара арыдқәа рҿакра, мамзар рҿыхра" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Иаҧхьааиуа абзац ахь аиасра" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Анаҩстәи абзац ахь аиасра" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Иаҧхьааиуа аиагага ахь аиасра" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Анаҩстәи аиагага ахь аиасра" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Иаҧхьааиуа аиҟәшага ахь аиасра" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Анаҩстәи аиҟәшага ахь аиасра" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Иаҧхьааиуа аҭаӡҩыра ахь аиасра" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Анаҩстәи аҭаӡҩыра ахь аиасра" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Ҵаҟатәи абларҭа ахь аиасра" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Аҭаӡҩыраҟны раԥхьатәи абларҭа ахь аиасра" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Аҭаӡҩыраҟны аҵыхәтәантәи абларҭа ахь аиасра" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Арымарахьтәи абларҭа ахь аиасра" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Арыӷьарахьтәи абларҭа ахь аиасра" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Хыхьтәи абларҭа ахь аиасра" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Иаҧхьааиуа изҭамаац азхьарԥш ахь аиасра" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Анаҩстәи изҭамаац азхьарԥш ахь аиасра" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Иаҧхьааиуа изҭаахьоу азхьарԥш ахь аиасра" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Анаҩстәи изҭаахьоу азхьарԥш ахь аиасра" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Аҿакра" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Автоматикалатәи афокус арежим, еилаҵоу ахырхарҭарбараан иаҿакхо" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Автоматикалатәи афокус арежим, ахырхагатә ахырхарҭарбараан иаҿакхо" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Автоматикалатәи афокус арежим, ахырхагатә ахырхарҭарбараан иаҿакхо" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Аԥыхра" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "Аиасра_" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Аҧшаара ахышәарақәа" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Аҭҵаара арежим аҟынтә аҭыҵра" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "аҟәша" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "Агәылаҵа ацҵара" - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "Аамҭеи аамҭарбеи" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "Азеиԥш хәаԥшра арежим аҭалара" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -#, fuzzy -msgid "Flat review contents" -msgstr "Аредакциа ззухо аҭаҵа" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Аекрантә диктор ахышәарақәа %s азы" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Еиҳарак" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Адаҟьа _раԥхьаӡа акәны ианҭагалоу автоматикла аԥхьара алагара" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Иркьаҿны" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "Армарахь" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "Арӷьарахь" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "амениу" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "аҵәаӷәара" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "Ахырхарҭақәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "Ахырхарҭақәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Ахархәара:" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "АХЬӠ" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Ари аԥшьы аверсиа" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "АФАИЛ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "Астатус ацәаҳәа ҧшааӡам" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "Хыхьтәи аиндекс %s" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "Аҭаӡҩыра аҟны акәӡам." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Аамҭалатәи аиҵаргыла ахы рыцқьоуп." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Аамҭалатәи ацәаҳәа ахы рыцқьоуп." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "иҭацәуп" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Азеиԥш хәаԥшра арежим аҭалара" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "ацитатаагара аидкыла аҟынтә аҭыҵра." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "аформа аҟынтә аҭыҵра" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "ахьӡынҵа аҟынтә аҭыҵра" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "апанель аҟынтә аҭыҵра" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "аҭаӡҩыра аҟынтә аҭыҵра" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Аҭҵаара арежим аҟынтә аҭыҵра" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "азхьарԥш" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Адуу аобиектқәа уаха ыҟаӡам" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "Иаҧхьааиуа асимвол ахь аиасра" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "ацитатақәа рыблоккәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "апытҟәырқәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "апытҟәыр-дыргакәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Адуу аобиектқәа уаха ыҟаӡам" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Узыгәҭасша аобиктқәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Аҭыԥқәа ахьӡынҵақәа рыцҵаны уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Аҭагаларҭақәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Аҭыԥ аформақәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "уаҳа ахқәа ыҟаӡам." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "Аҭаӡҩырақәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "уаҳа асахьақәа ыҟаӡам." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Ахырхарҭақәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Азхьарԥшқәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Ахьӡынҵакәа уаҳа иҟаӡам." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "ахьӡынҵа аелементқәа уаҳа ы.ҟаӡам" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "уаҳа зҽызыԥсахуа аганқәа ыҟаӡам" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "уаҳа абзацқәа ыҟаӡам." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Аиагагақәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Аиҟәшагақәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Аҭаӡҩырақәа уаҳа ыҟаӡам" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Шәахьымҭалац азхьарԥшқәа ыҟаӡам" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Уаҳа иҟаӡам шәызҭаахьоу азхьарԥшқәа" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "иаҿакуп" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Аекрантә диктор ахышәарақәа иеиҭаҿакуп" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Иалху атекст: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Иалху аныхуп." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Иалху еиҭашьақәыргылоуп." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Атекст алкааӡам." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Ашәагаа: %d, %d. Аҭыҧ: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Аҭбаара: %d. Аҳаракыра: %d. %d арымарахь. %d арыӷьарахь." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Ацәажәара аҿыхуп." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Ацәажәара аҿакуп." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "ирласны" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "имырццакӡакәа." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "аҩада." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "алада." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "абжьы рдуны." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "абжьы рхәыҷны." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "аиҵагыла %d" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Ацәажәара ахь анеира залшахом." - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Ацәажәара ахь анеира залшахом." - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Ацәажәара аҿакуп." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Ацәажәара ахь анеира залшахом." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Астатус ацәаҳәа ҧшааӡам" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "ацәаҳәа ҧшааӡам" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Еилаҵоу ахырхарҭарбара арыдқәа аҿыхуп." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Еилаҵоу ахырхарҭарбара арыдқәа аҿакуп." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Ацәаҳәа %(row)d, аиҵагыла %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Аҭаӡҩыра анҵәамҭа" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Абларҭа аҳәара" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Ацәаҳәа аҳәара" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Еиҧшӡам" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Аҭаӡҩыра аҟны акәӡам." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Аиҵагылақәа реишьҭагылашьа ҧсахуп" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Ацәаҳәақәа реишьҭагылашьа ҧсахуп" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "аиҵагыла %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "аиҵагыла %(index)d %(total)d аҟынтә" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Аиҵагыла алагамҭа." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Аиҵагыла анҵәамҭа ." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Иалкаауп аиҵагыла %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Иалхуп аиҵагылақәа %s аҟынтә %s аҟынӡа" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Аиҵагылақәа алкаара рымхуп %s аҟынтә %s аҟынӡа" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Аиҵагыла алкаар амхуп %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "ацәаҳәа %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "ацәаҳәа %(index)d %(total)d аҟынтә" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Ацәаҳәа алагамҭа." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Ацәаҳәа анҵәамҭа ." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Ацәаҳәа аныхуп." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Аҵыхәтәантәи ацәаҳәа аныхуп." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Ацәаҳәа ҭагалоуп." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Ацәаҳәа ҭагалоуп аҭаӡҩыра наҵәамҭаҟны." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Иалкаау ацәаҳәа %s" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Иалкаау ацәаҳәақәа %s аҟынтәи %s аҟынӡа" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Ацәаҳәақәа %s инаркны %s аҟынӡа ралкаара ықәгоуп" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Ацәаҳәа %s алкаара ықәгоуп" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H сааҭ, %M минуҭ и %S секунд" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H сааҭи %M минуҭи" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Иуникод %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "абжьажь" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Анҵәамҭаҟынтәи ацҵара." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Алагамҭаҟынтәи ацҵара. ." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 аелементқәа" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d баитк" -msgstr[1] "%d баитк" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Аҭыҵра %d ацитатаагара аидкыла аҟынтә." -msgstr[1] "Аҭыҵра %d ацитатаагара аидкыла аҟынтә." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Ахьӡынҵақәа %d рҟынтә аҭыҵра." -msgstr[1] "Ахьӡынҵақәа %d рҟынтә аҭыҵра." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Еилкаам ашәагаа змоу ахьӡынҵа" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Еилкаам ашәагаа змоу алента" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "Еилкаам ашәагаа змоу аҭаӡҩыра" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "аиагара" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d аҟны %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "аелемент %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "Аҩаӡара %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "уровень дерева %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "АҴЛА АҨАӠАРА %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "ахәҭаҷқәа %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "иҟоуп ахәҭаҷқәа %s аҟны" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "Аредакциа ззухо аҭыҧ ахьӡынҵа аманы" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "Аредакциа ззухо аҭаҵа" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "Гәҵәылатәи аҭаргьежьга цәаҳәа" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "амениу апытҟәыр" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "агәҵәытә" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Аҧшаара" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Аркра" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Аҧшаара" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Аԥенџьыр ақәцә" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Аԥенџьыр ақәцә" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Автоматикла алагамҭахь аиасра" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "_Ԥасаны аԥшаара" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Арегистр аҳасаб азура" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Ахышәарақәа:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "default:mm" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Аҧшьы" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Аилыркаа" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Ахархәара" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Аноутбук" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Аҭагалара" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Аиқәырхара абас еиԥш:" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Аныхра" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Аамҭеи аамҭарбеи" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Зегьы ирзаку" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Абжьы ахкы ахышәарақәа" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Ацәажәара аҿакра" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Зегьы" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Браиль икьаҿ_аҩра аҿакра" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Иласу ацҳамҭақәа рҿакра" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Иласу ацҳамҭақәа рхышәарақәа " - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Браиль" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Аныхра" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Аҿыхра" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Атекст аҟазшьарбагақәа" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Атекст аҟазшьарбагақәа" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "end" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : альфа, b : браво, c : чарли, d : дельта, e : ехо, f : фокстрот, g : " -"гольф, h : хотель, i : индия, j : джульет, k : кило, l : лима, m : майк, n : " -"ноябрь, o : оскар, p : папа, q : квебек, r : ромео, s : сиерра, t : танго, " -"u : униформа, v : виктор, w : виски, x : икс, y : янки, z : зулу, а : " -"анбан , б : бзоу, в :воуба, г :гагра, гь:гьаргь, гә :гәдиса, ӷ : " -"аӷа, ӷь :абӷьы ӷә:ӷәада д:даур, дә:дәрыԥшь , е:езыгә , ж:ажра, " -"жь:жьабна, жә: жәандрыԥшь , з:зыма ӡ:ӡыдакәара , ӡә: аӡәы, " -"и:игры , к:кындыӷ , кь:кьалашәыр , кә:кәтол, қ : ақды, " -"қь:қьамал , қә: қәабчара ҟ: ҟлыч , ҟь:адаҟьа, " -"ҟә:ҟәланырхәа ,л :лыхны , м:маҷара , н: нарҭ , о:отаԥ, " -"п:пицунда ,ԥ:ԥсоу , р:риҵа ,с:саид , т:тамышь , тә: тәанба " -"ҭ:ҭхьына, ҭә: аҭәа, у: уарча , ф : фатима , х:хамида , " -"хь:хьымса , хә:хәаԥ , ҳ: аҳа , ҳә: аҳәыҳә, ц:цандрыԥшь , цә: " -"ацә, ҵ:ҵабал, ҵә:аҵәа , ч:чаам , ҷ:ҷлоу , ҽ: аҽы ҿ:аҿы, " -"ш:шамел , шь:шьоудыд , шә :шәлиман ы:асы ҩ:ҩыԥсара џ: " -"аџыр , џь: џьырхәа , ь: арԥшгага дырга, ә: ахаргьежь дырга ." - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/an.po b/po/an.po deleted file mode 100644 index 2a35c0c..0000000 --- a/po/an.po +++ /dev/null @@ -1,9770 +0,0 @@ -# Aragonese translation for cthulhu. -# Copyright (C) 2012 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Jorge Pérez Pérez , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu gnome-3-6\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2014-11-04 20:04+0100\n" -"Last-Translator: Jorge Pérez Pérez \n" -"Language-Team: Aragonese \n" -"Language: an\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 1.6.10\n" - -msgid "Cthulhu Screen Reader" -msgstr "Lector de pantalla Cthulhu" - -#, fuzzy -msgid "screen;reader;accessibility;speech;braille;" -msgstr "lector de pantalla; fabla; braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "flc" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "lnz" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "dscrp" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "cv" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "sltcol" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "cabcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "fch" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ico" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "mar" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "pnldir" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "dibuixo" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "sltar" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "rlln" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "pnltr" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "cbcra" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "mrci" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etq" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "pnlslp" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "vnc" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "ellst" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "barmnu" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "elmnum" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "pnlo" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "slp" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblslp" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "contr" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnuem" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "brprog" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "mnuer" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "pnlr" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "Cabrn" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "brdesl" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "pnldesl" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sccn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprdr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "desl" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "pnldiv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "contador" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "brestbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cld" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "emd" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "btc" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "bdf" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "cs" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arb" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tblArb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "desc" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "Prt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "fns" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "Cab" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pDP" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "parra" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "ap" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "bEd" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "cEmp" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Checo grau 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Espanyol grau 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francés de Canadá grau 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francés de Francia grau 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letón grau 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holandés de Países Baixos grau 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Noruego grau 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Noruego grau 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Noruego grau 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Noruego grau 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polaco grau 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugués grau 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Sueco grau 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabe grau 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galés grau 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galés grau 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemán grau 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemán grau 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemán grau 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Anglés d'o Reino Uniu grau 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Anglés d'o Reino Uniu grau 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Anglés d'Estaus Unius grau 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Anglés d'Estaus Unius grau 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francés de Canadá grau 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francés de Francia grau 2" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Griego grau 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindú grau 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Hungaro d'ordinador de 8 puntos" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hungaro grau 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "Hungaro grau 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italián grau 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Holandés de Belchica grau 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espacio" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "linia nueva" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "Tabulador" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "Zarrar exclamación" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "Cometas" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "numero" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "por cient" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ampersand" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrofo" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "ubrir parentesi" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "zarrar parentesi" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterisco" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "mas" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "Coma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "guión" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punto" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dos puntos" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punto y coma" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "menor que" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "Igual" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "Mayor que" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "Zarrar interrogación" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "Arroba" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "Ubrir gafet" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "Contrabarra" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "Zarrar gafet" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "Circunflexo" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "Gión baixo" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "Accento grieu" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "Ubrir clau" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "Barra vertical" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "Zarrar clau" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "virgulilla" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espacio de no deseparación" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "Ubrir exclamación" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "Centavos" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "Libras" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "simbolo de moneda" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra vertical tallada" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "Sección" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "dieresi" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a superindiz" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "Ubrir cometas angulars" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "no lochico" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "guión" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "Rechistrau" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "sobrerayau" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "graus" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "mas u menos" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "ta lo quadrau" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "Ta lo cubo" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "Accento agudo" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "Micro" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "Paragrafo" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "Punto meyo" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "Apostrofo" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 superindid" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "Zarrar cometas angulars" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "Quart" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "Meyo" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tres quarts" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "Ubrir interrogación" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "A agudo" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "Mayus a grieu" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "Mayus a agudo" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "Mayus a circunflexo" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "Mayus a virgulilla" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "Mayus a dieresi" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "Mayus a aniello" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "Mayus ae" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "Mayus c CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "Mayus e grieu" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "Mayus e agudo" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "Mayus e circunflexo" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "Mayus e dieresi" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "Mayus i grieu" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "Mayus i agudo" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "Mayus i circunflexo" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "Mayus i dieresi" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "Mayus enye" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "Mayus o grieu" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "Mayus o agudo" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "Mayus o circunflexo" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "Mayus o virgulilla" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "Mayus o dieresi" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "Multiplicau por" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "Mayus o barra" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "Mayus u grieu" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "Mayus u agudo" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "Mayus u circunflexo" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "Mayus u dieresi" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Mayus y griega agudo" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "ZORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "beta" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grieu" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circunflexo" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a virgulilla" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a dieresi" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a aniello" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ae" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "Ce cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grieu" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e agudo" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circunflexo" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e dieresi" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grieu" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i agudo" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circunflexo" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i dieresi" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "enye" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grieu" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o agudo" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circunflexo" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o virgulilla" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o dieresi" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "dividiu por" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o barra" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u agudo" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grieu" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circunflexo" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u dieresi" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y griega agudo" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y griega dieresi" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Mayus y griega dieresi" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florín" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "Guión curto" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "Ubrir cometa simple cucha" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "Zarrar cometa simple" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "cometa inferior simple" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "Ubrir cometas" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "Zarrar cometas" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dople cometa inferior" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "cruz" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dople cruz" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "Vinyeta" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "Vinyeta trianglar" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "por milla" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prima" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "prima dople" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "prima dople" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "Guión de vinyeta" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euros" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marca rechistrada" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "Marca" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "Marca fuerte" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "viñeta marcada con x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "0 superindiz" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "4 superindiz" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "5 superindiz" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "6 superindiz" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "7 superindiz" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "8 superindiz" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "9 superindiz" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "más superindiz" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "menos superindiz" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "igual superindiz" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "ubrir parentesi superindiz" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "zarrar parentesi superindiz" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "elevau a n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "sub 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "sub 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "sub 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "sub 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "sub 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "sub 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "sub 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "sub 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "sub 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "sub 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "más subindiz" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "menos subindiz" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "igual subindiz" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "ubrir parentesi subindiz" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "zarrar parentesi subindiz" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "Quadrau negro" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "Diamant negro" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "caracter de substitución d'obchecto" - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "Posiciona lo puntero en l'elemento actual." - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "Preta con o botón cucho sobre l'elemento revisau." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "Fa clic cucho sobre l'elemento actual revisau." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Leye tot o documento." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "No se ye emplegando a revisión plana." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "Realiza la operación basica án soi?" - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "Realiza la operación detallada án soi?" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Leye a linia actual de revisión." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "Leyer linias vuedas" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "Va ta lo botón siguient." - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "Leye a barra d'estau." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "Leye a barra de titol." - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Ubre o dialogo de busca." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "Mira la siguient instancia d'una cadena." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "Mira la siguient instancia d'una cadena." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "Dentra y sale d'o modo de revisión." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "Mueve a revisión ta la posición final." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "Mover a revisión ta la posición inicial." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "Mueve a revisión ta la posición final." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "Mover a revisión ta lo prenzipio d'a linia anterior." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "Leye a linia actual de revisión." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "Letreya la linia actual de revisión." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "Letreya foneticament a linia actual de revisión." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "Mover a revisión ta lo prenzipio d'a linia siguient." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "Mueve a revisión ta l'anterior elemento u parola." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "Leye l'elemento u parola actual de revisión." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "Letreya l'elemento u parola actual de revisión." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "Letreya foneticament l'elemento u parola actual de revisión." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "Mueve a revisión ta lo siguient elemento u parola." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "Mueve a revisión ta la parola dencima d'a parola actual." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "Leye l'obchecto revisau actualment." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "Mueve a revisión ta la parola de debaixo d'a parola actual." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "Mueve a revisión ta lo caracter anterior." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "Leye o caracter revisau actualment." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "Leye foneticament o caracter actual de revisión." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "Leye o caracter unicode d'o caracter actual de revisión." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "Mueve a revisión ta lo caracter siguient." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "Mueve a revisión ta la fin d'a linia." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "Mueve a revisión ta lla cantonada inferior cucha." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copia o conteniu d'a revisión plana en o portafuellas." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "Adhibe o conteniu d'a revisión plana a lo portafuellas." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "Mueve a revisión ta la posición final." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Cambea entre leyer solament a celda actual u toda a ringlera." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "Leye os atributos asociaus a o caracter actual." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "Desplaza a linia braille enta la cucha." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "Desplaza a linia braille enta la dreita." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "Torna a l'obchecto con o foco de teclau." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "Activa u desactiva o braille contrayiu." - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "Procesa una tecla d'enrutau d'o cursor." - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "Marca lo prenzipio d'una selección de texto." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "Marca la final d'una selección de texto." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Dentra en modo d'aprendizache. Preta escape ta salir d'o modo de " -"aprendizache." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "Disminui a velocidat d'a fabla." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "Aumenta a velocidat d'a fabla." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "Disminui o ton d'a fabla." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "Aumenta o ton d'a fabla." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Aumenta a velocidat d'a fabla." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Disminui a velocidat d'a fabla." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Selecciona lo servidor de fabla que quiers." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Selecciona lo servidor de fabla que quiers." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "Disminui a velocidat d'a fabla." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "Aumenta a velocidat d'a fabla." - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "Configuración d'a mena de voz" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "Conmuta lo silencio d'a fabla." - -#: src/cthulhu/cmdnames.py:476 -#, fuzzy -msgid "Toggle speech verbosity level" -msgstr "Conmuta o libel d'información d'afabla." - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "Conmutar o modo de revisión d'o churi." - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Sale d'o lector de pantalla" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "Amuestra lo dialogo de configuración de preferencias." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "Amuestra lo dialogo de configuración de preferencias ta l'aplicación." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "Activa u desactiva a lectura d'o sangrau y la chustificación." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "Chira ta lo siguient libel de puntuación." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "Chira ta lo siguient libel d'eco de teclas." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "Chira ta lo siguient perfil d'opcions." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "Chira ta lo siguient estilo de capitalización." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "Chira ta lo siguient libel d'eco de teclas." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "Chira entre os libels de depuración en tiempo d'execución." - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "Marcador Án soi respective a la posición actual." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "Ir ta la ubicación d'o marcador anterior." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "Ir ta marcador." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "Ir ta la ubicación d'o siguient marcador." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "Adhibir marcador." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "Alzar marcadors." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "Conmutar o modo de revisión d'o churi." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "Amostrar a hora actual." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "Amostrar a calendata actual." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "Ninvia o siguient comando ta l'aplicación activa." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "Leyer y braille d'un mensache anterior d'una sala de chat." - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Conmutar si s'anuncia quan os nuestros amigos son tecleando." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Conmutar si se proporcionan historicos de mensaches de cada sala de chat." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"conmutar si se prefixan os mensaches d'a sala de chat con o nombre de la " -"sala de chat." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linia cucha" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linia dreita" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linia alto" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linia abaixo" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Desactivar" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Alto Cucha" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Abaixo a la cucha" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posición d'o cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Seis puntos" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Enrutau d'o cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Encieto d'o tallo" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Linia tallada" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "Presentar o zaguer mensache de notificación." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Presentar a lista de mensaches de notificación" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "Presentar o mensache anterior de notificación." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "Presentar o zaguer mensache de notificación." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Va ta lo siguient caracter." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "Va ta lo caracter anterior." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "Va ta la siguient parola." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "Va ta la parola anterior." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "Va ta la siguient linia." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "Va ta la linia anterior." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "Va ta lo prencipio d'o fichero." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "Va ta la final d'o fichero." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Va ta lo prencipio d'a linia." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "Va ta la fin d'a linia." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "Va ta lo siguient obchecto." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "Va ta l'anterior obchecto." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "Fa que se desplegue o quadro combinau actual." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Cambia entre a navegación nativa d'o cursor y a d'o lector de pantalla." - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "Abanzar a configuración de comportamiento d'a rechión activa." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "Establir o libel de comportamiento de rechions activas ta desenchegau." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "Revisar anuncio de rechión activa." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "Monitorizar rechions activas." - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "Mueve o foco enta u luen de l'actual posición d'o churi." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "Estableix a ringlera que s'ha d'emplegar como capiteras dinamicas." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "Limpia as capiteras dinamicas de columna." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "Estableix a columna que s'ha d'emplegar como capiteras dinamicas." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "Limpia as capiteras dinamicas de ringlera" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Presienta lo conteniu d'a linia de dentrada." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "Enchega u desenchega as teclas de navegación estructural." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "Va ta la cita anterior." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "Va ta la cita siguient." - -#: src/cthulhu/cmdnames.py:852 -#, fuzzy -msgid "Display a list of blockquotes" -msgstr "Amuestra un listau de bloques de cita." - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "Va ta lo botón anterior." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "Va ta lo botón siguient." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Amuestra un listau de botons." - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Va ta la caixeta anterior." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Va ta la caixeta siguient." - -#: src/cthulhu/cmdnames.py:870 -#, fuzzy -msgid "Display a list of check boxes" -msgstr "Amuestra un listau de caixetas de verificación." - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "Va t'o clicable anterior" - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "Va t'o clicable siguient." - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "Amuestra un listau de clicables" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "Va ta l'anterior quadro combinau." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Va ta lo siguient quadro combinau." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "Va ta la fin d'a linia." - -#: src/cthulhu/cmdnames.py:901 -#, fuzzy -msgid "Display a list of combo boxes" -msgstr "Amuestra un listau de listas desplegables." - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "Va ta l'anterior dentrada." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "Va ta la siguient dentrada." - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "Amuestra un listau de dentradas." - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "Va ta l'anterior campo de formulario." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "Va ta lo siguient campo de formulario." - -#: src/cthulhu/cmdnames.py:919 -#, fuzzy -msgid "Display a list of form fields" -msgstr "Amuestra un listau de campos de formulario." - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "Va ta l'anterior capitero." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "Va ta lo siguient capitero." - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "Amuestra un listau de capiters." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Va ta l'anterior capitero de libel %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Va ta lo siguient capitero de libel %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Amuestra un listau de capiters de libel %d." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "Va ta la tabla anterior." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "Va ta la tabla siguient." - -#: src/cthulhu/cmdnames.py:949 -#, fuzzy -msgid "Display a list of internal frames" -msgstr "Amuestra un listau de tablas." - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "Va t'a imachen anterior." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "Va t'a siguient imachen." - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "Amuestra un listau d'imachens" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "Va ta l'anterior marcador." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "Va ta lo siguient marcador." - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "Amuestra un listau de marcas." - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Va ta l'anterior obchecto gran." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Va ta lo siguient obchecto gran." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Amuestra un listau d'obchectos grans.." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "Va ta lo vinclo anterior." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "Va ta lo siguient vinclo." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Amuestra un listau de vinclos." - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "Va ta 'anterior lista." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "Va ta la siguient lista." - -#: src/cthulhu/cmdnames.py:1006 -#, fuzzy -msgid "Display a list of lists" -msgstr "Amuestra un listau de listas." - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Va ta l'anterior obchecto de lista." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Va ta lo siguient elemento de lista." - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "Amuestra un listau d'elementos de lista." - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "Va ta l'anterior rechión activa." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "Va ta la siguient rechión activa." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "Va ta la zaguera rechión activa que fació un anuncio." - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "Torna a l'obchecto con o foco de teclau." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "Torna a l'obchecto con o foco de teclau." - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "Enchega u desenchega as teclas de navegación estructural." - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "Va ta l'anterior paragrafo." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "Va ta lo siguient paragrafo." - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "Amuestra un listau de paragrafos." - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Va ta l'anterior botón de radio." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "Va ta lo siguient botón de radio." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "Amuestra un listau de botons de radio." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "Va ta l'anterior separador." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "Va ta lo siguient separador." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "Va ta la tabla anterior." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "Va ta la tabla siguient." - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "Amuestra un listau de tablas." - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "Va una celda enta baixo." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "Va ta la primera celda d'una tabla." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "Va ta la zaguera celda d'una tabla." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "Va una celda enta la cucha." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "Va una celda enta la dreita." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "Va una celda enta alto." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "Conmutar o modo de revisión d'o churi." - -#: src/cthulhu/cmdnames.py:1137 -#, fuzzy -msgid "Switch between browse mode and focus mode" -msgstr "Cambea entre o modo de navegación y o modo de foco." - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Activar o modo de foco pegalloso." - -#: src/cthulhu/cmdnames.py:1159 -#, fuzzy -msgid "Enable sticky browse mode" -msgstr "Activar o modo de foco pegalloso." - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "Va ta l'anterior vinclo sin visitar." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "Va ta lo siguient vinclo sin visitar." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "Amuestra un listau de vinclos sin visitar." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "Va ta l'anterior vinclo visitau." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "Va ta lo siguient vinclo visitau." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "Amuestra un listau de vinclos visitaus." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "azula Alicia" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "blanca antiga" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "auguamarina" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azula celest" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beis" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "negra" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "almendra blanquiada" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "azula" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "azula violeta" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "marrona" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "madera fuerte" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "azula cadet" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chocolate" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "coral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "azula aciano" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "seda de panizo" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "carmesí" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cian" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "azula escura" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "cian escura" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "barra d'oro escura" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "grisa escura" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verda escura" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "caqui escura" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "machenta escura" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "oliva verda escura" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "narancha escura" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "orquidia escura" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "roya escura" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmón escura" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "verda mar escura" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "azula pizarra escura" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "grisa pizarra escura" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turquesa escura" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violeta escura" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "rosa funda" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "azula ciel funda" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "grisa fosca" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "azula 'dodger '" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "ladriello de fuego" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "blanca de flors" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "verda selva" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fucsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "blanca totón" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "dorada" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "barra d'oro" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "grisa" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verda" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "amariella verda" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "verda melón" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "rosa calient" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "roya indica" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "anyil" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "marfil" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "caqui" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "espígol" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "espígol enroyau" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "verda tasca" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "gasa de limón" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "azula floixa" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "coral floixa" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "cian floixa" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "barra d'oro amariella floixa" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "grisa floixa" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "verda floixa" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "rosa floixa" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmón floixa" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "verda mar floixa" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "azula ciel floixa" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "grisa pizarra floixa" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "azula acero floixa" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "amariella floixa" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lima" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "verda lima" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "lin" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "machenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "marrona" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "auguamarina meya" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "azula meya" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orquidia meya" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "purpura meya" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "verda mar meya" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "azula pizarra meya" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "verda primavera meya" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turquesa meya" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "roya violeta meya" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "azula meya nueit" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "crema de pipireta" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rosa boirosa" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mocasín" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "blanca navalla" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "azula marina" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "encordadera viella" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliva" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "grisa oliva" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "narancha" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "narancha roya" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orquidia" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "barra d'oro esbufalida" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "verda esbufalida" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turquesa esbufalida" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "roya violeta esbufalida" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "batiu de papaya" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "soflo de cocón" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "perú" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "cirgüella" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "areniella azula" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purpura" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "roya" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "marrona rosa" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "azula reyal" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "marrona siella" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmón" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "arena marrona" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "verda mar" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "casca" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "siena" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "platiada" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "azula ciel" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "azula pizarra" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "grisa pizarra" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "nieu" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "verda primavera" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "azula acero" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "bronciada" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "verda azulada" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "cardo" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomate" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquesa" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violeta" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "trigo" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "blanca" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "blanca fumo" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "amariella" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "amariella verda" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Activar" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Modo de foco automatico entre a navegación estructural" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Modo de foco automatico entre a navegación de cursor" - -#: src/cthulhu/guilabels.py:96 -#, fuzzy -msgid "Automatic focus mode during native navigation" -msgstr "Modo de foco automatico entre a navegación de cursor" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punto _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punto _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Puntos 7 _y 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Cancelar" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Blincar ta" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Acceptar" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Dengún" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "Error d'ortografía" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Anunciar quan os suyos _amigos son tecleando" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Proporcionar historicos de mensaches especificos de cada sala de chat" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Leyer os mensaches de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Todas as ca_nals" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Todas as canals quan q_ualsiquier finestra de %s ye activa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Una canal nomás si la suya _finestra ye activa" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Leyer o nombre d'a sala de chat" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Activar o modo de distribución t'o conteniu" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "Dople clic" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triple clic" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizador predeterminau" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Cadena Actual" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Cadena de substitución" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Activar eco por _caracter" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Activar teclas _diacriticas" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Posición act_ual" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minima longaria d'o texto coincident:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opcions de busca" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Charrar _nomás que as linias cambiadas entre a busca" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Leyer os resultaus entre a _busca" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "Coma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Alcorce de teclau" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Predeterminau" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "modo d'escritura" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "Sección" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Alcorces Braille" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "Alzar marcadors." - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "Calendata y hora" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "Navegación por tablas" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "No asociau" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "Se ye salindo d'a revisión." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificau" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Escritorio" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificación" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Notificación" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferencias d'Cthulhu" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marcar en braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Presentar de no estar que" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Charrar" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Alzar perfil como conflicto" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflicto con o perfil d'usuario" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"O perfil %s ya existe.\n" -"Continar actualizando lo perfil existent con istos cambeos nuevos?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Cargar perfil d'usuario" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Ye a punto de cambiar o perfil activo. Si acaba de\n" -"fer cambeos en as suyas preferencias, istos se\n" -"perderán en a carga d'o perfil.\n" -"\n" -"Continar a carga d'o perfil descartando os cambeos anteriors?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Alzar perfil como" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nombre d'o _perfil:" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "Cargar perfil d'usuario" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Tot" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicación" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Finestra" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "Denguna" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Beluna" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "a _mayoría" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Linia" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Frase" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Bloque de cita" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Botón" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Lechenda" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Caixeta de verificación" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Clicable" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Lista desplegable" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descripción" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Capitero" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imachen" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiqueta" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Marca" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Libel" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Vinclo" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Elemento delista" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Obchecto" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragrafo" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Botón de radio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Paper" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Elemento trigau" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Estau" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Texto" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valor" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Bloques de cita." - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botons" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Caixetas de verificación" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Clicables" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Listas desplegables" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Dentradas" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Campos de formulario" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Capiters" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imachens" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Capiters de libel %d." - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Marcas" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Obchectos grans." - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Vinclos" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listas" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Elementos de lista" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragrafos" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Botons de radio." - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tablas" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Vinclos sin visitar" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Vinclos visitaus" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navegación por pachinas" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Empecipia a leyer automaticament una pachina quan ista se _carga por primera " -"vez" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"Empecipia a leyer automaticament una pachina quan ista se _carga por primera " -"vez" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Partir a fabla en trozos entre pausas" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "voz predeterminada %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Predeterminau" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hipervinclo" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Mayuscla" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Comprebación d'ortografía" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "_Error d'ortografía" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "_Sucherencia d'ortografía" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Presentar o _contexto d'error" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "Leyer as coordenadas d'as celdas en fuellas de calculo" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "_Anunciar a capitera d'una celda" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navegación por tablas" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "_Blincar celdas en blanco" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Leyer _celda" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Leyer as coordenadas d'una _celda" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Leyer _celdas dentro d'unatra celda" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nombre de l'atributo" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Controlar a navegación d'o cursor" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Activar a navegación estructural" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Breu" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Notificación" -msgstr[1] "Notificación" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Mayus" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "mayus cucha" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt cucha" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control cucha" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "mayus dreita" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt dreita" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control dreita" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta cucha" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta dreita" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "bloqueyo numerico" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "bloqueyo de mayusclas" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "bloqueyo de mayusclas" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "bloqueyo de desplazamiento" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "retroceso de pachina" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "abance de pachina" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tabulación cucha" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "borrar" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "enter" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "alto" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "abaixo" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "cucha" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "dreita" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super cucha" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super dreito" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "aduya" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "cambiar modo" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insertar" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "suprimir" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "inicio" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "Fin" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "prencipiar" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "Accento circunflexo" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "Aniello" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "barra" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "menos" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Ficar" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Bloqueyo_de_mayusclas" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_D" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_I" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Mayus" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "negreta" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "cursiva" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s subindiz" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s subindiz" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Aria de treballo " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "O contexto ye %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "flecha cucha" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "flecha cucha" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "flecha dreita" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "flecha cucha" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "flecha dreita" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "flecha dreita" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "flecha dreita" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "flecha cucha" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "flecha cucha" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "flecha dreita" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "Ubrir cometas" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dople cruz" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "Zarrar cometas" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dople cruz" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "Zarrar cometas" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "flecha enta la dreita" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "Flecha enta la dreita" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "menor que" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "Mayor que" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "Accento circunflexo" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "punto" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "aliniación vertical" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "Horizontal" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "Vuedo" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "Enchegada" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "Fin de ringlera" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "subíndiz" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "mas u menos" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "mas" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "Radiz quadrada" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "Radiz cubica" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "Radiz quadrada" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "infinito" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "alt dreita" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "sencillo" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "aliniación vertical" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "dividiu por" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "No igual que" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "no lochico" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "no lochico" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "adreza" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "prima dople" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "virgulilla" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "enye" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "enye" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "quasi igual que" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "quasi igual que" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "quasi igual que" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "quasi igual que" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "quasi igual que" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "quasi igual que" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "triple clic" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "quasi igual que" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "puesto esferent" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "No igual que" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "Igual" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "Igual" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "No igual que" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "No igual que" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "Vinyeta trianglar" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "Igual" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "No igual que" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "No igual que" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "vertical" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "No igual que" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "No igual que" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "Mayor que" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "sin Pretar" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "sub 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "a superindiz" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "selección-multiple" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "chustificación" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "selección-multiple" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "Radiz quadrada" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "Radiz quadrada" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "Radiz quadrada" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "Radiz quadrada" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "igual subindiz" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "Guión curto" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "más subindiz" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "menos subindiz" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "Radiz quadrada" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "Radiz quadrada" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "meta dreita" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "tabulación cucha" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "abaixo" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "Sección" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "verdadero" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "verdadero" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ordinal" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "Imachen" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "multi" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "normal" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "Zarrar cometa simple" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "Zarrar clau" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "no lochico" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "no lochico" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "prima dople" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "prima dople" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "adreza" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "prima dople" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "Menor u igual que" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "Mayor u igual que" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "aliniación vertical" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ubrir parentesi" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "zarrar parentesi" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "alt cucha" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "alt dreita" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "Ubrir clau" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "inferior" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "Ubrir cometas angulars" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "Zarrar cometas angulars" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "Punto meyo" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "Adreza de busca:" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "Radiz quadrada" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "Quadrau negro" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "Quadrau blanco" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "Diamant negro" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "Cerclo blanco" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "Cerclo negro" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "Vinyeta blanca" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "Quadrau negro" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "Gión baixo" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "aliniación vertical" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplicación" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "en blanco" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "negreta" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "marcador introduciu" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "S'han alzau os marcadors" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "os marcadors no se pueden guardar" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "No s'han trobau marcadors" - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "No s'han trobau marcadors" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Modo ninviar tecla enchegau." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "No se puet obtener pantalla d'a calculadera" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "Icono" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Estilo de capitalización establiu a icono." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "Dengún" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Estilo de capitalización establiu a dengún." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "Error d'ortografía" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Estilo de capitalización establiu a error d'ortografía." - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "O Gecko ye controlando o cursor." - -#: src/cthulhu/messages.py:170 -#, fuzzy -msgid "Cthulhu is controlling the caret." -msgstr "O Gecko ye controlando o cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Celda %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "Seleccionau" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "Deseleccionau" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Aprevenir l'emplego d'a opción" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Forzar l'emplego d'a opción" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCIÓN" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Os siguients argumentos no son validos: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Imprentar as aplicacions conoixidas que se son executando" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Cargar perfil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "No se pudo cargar o perfil: %s" - -#: src/cthulhu/messages.py:249 -#, fuzzy -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"No se puet enchegar o lector de pantalla porque no s'ha puesto connectar con " -"o escritorio." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "No s'ha puesto activar l'administradord'opcions. Se ye salindo." - -#: src/cthulhu/messages.py:259 -#, fuzzy -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Ya bi ha unatro proceso d'o lector de pantalla en execución ta ista sesión.\n" -"Executa \"cthulhu --replace\" ta substituir ixe proceso con unatro nuevo." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOMBRE" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Emplegar una carpeta alternativa t'as preferencias de l'usuario" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "Imprentar as aplicacions conoixidas que se son executando" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "" -"Substituir una instancia d'o lector de pantalla actualment en execución" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Ninviar a salida de depuración ta debug-AAAA-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Ninviar a salida de depuración ta un fichero especificau" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FICHERO" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Configurar as preferencias de l'usuario (versión de nomás texto)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" -"Configurar as preferencias de l'usuario (versión d'interficie grafica " -"d'usuario" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Informe d'errors a https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -#, fuzzy -msgid "Cut selection to clipboard." -msgstr "S'han copiau os contenius en o portafuellas." - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "Accento agudo" - -#: src/cthulhu/messages.py:337 -#, fuzzy -msgid "Copied selection to clipboard." -msgstr "S'han copiau os contenius en o portafuellas." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -#, fuzzy -msgid "Pasted contents from clipboard." -msgstr "S'han copiau os contenius en o portafuellas." - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "mas rapido." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "No anunciar quan os suyos amigos son tecleando." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anunciar quan os suyos amigos son tecleando." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Mensache d'a sala chat %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nueva pestanya de chat %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "No leyer o nombre d'a sala de chat." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "leyer o nombre d'a sala de chat." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "No proporcionar historicos de mensaches de cada sala de chat." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Proporcionar historicos de mensaches especificos de cada sala de chat." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "Indicador de selección" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "suprimir" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "insertar" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "verda floixa" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "_Sucherencia d'ortografía" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "Fin de tabla" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "No yes en una tabla." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "No trigau" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "O botón predeterminau ye %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "O botón predeterminau ye %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "O botón predeterminau ye %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "%s subindiz" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "%s superindiz" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "No yes en una tabla." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "tot o documento ha estau seleccionau" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "tot o documento ha estau seleccionau" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "documento seleccionau dende a posición d'o cursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "documento deseleccionau dende a posición d'o cursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "documento seleccionau dica la posición d'o cursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "documento deseleccionau dica la posición d'o cursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Capitera dinamica establida t'a ringlera %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Capitera dinamica de columna vuedada." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Ringlera de capitera dinamica establida t'a columna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Ringlera de capitera dinamica vuedada." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "Vuedo" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "No s'han trobau fichers." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "S'an adhibiu os contenius ta o portafuellas." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "S'han copiau os contenius en o portafuellas." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "No se ye emplegando a revisión plana." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Seye dentrando en a revisión." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Se ye salindo d'a revisión." - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "Mueve a revisión ta la parola dencima d'a parola actual." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "tien formula" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "Ubre o dialogo de busca." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "vinclo de mapa d'imachen" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "a tecla introducida ya ye asociada a %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tecla capturada: %s. Pulse Intro ta confirmar." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "A nueva tecla ye: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Alcorce de teclau eliminau. Preta enter ta confirmar." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "L'alcorce de teclau s'ha eliminau." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "Meter a tecla nueva" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "Tecla" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "Eco de teclau establiu a tecla." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Dengún" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "Eco de teclau establiu a dengún." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "Tecla y parola" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "Eco de teclau establiu a tecla y parola." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "Frase" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "Eco de teclau establiu a frase." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "Parola" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "Eco de teclau establiu a parola." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "Parola y frase" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "Eco de teclau establiu a parola y frase." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "Cerclo negro" - -#: src/cthulhu/messages.py:921 -#, fuzzy -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "tien Descripción luenga" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "Horizontal" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "Barra vertical" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "flecha dreita" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Se ye blincando ta la fin." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "altura d'a linia" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "ampersand" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "superrayau" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "Radiz quadrada" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "Radiz cubica" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "sub 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "a superindiz" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "sub 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "a superindiz" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "a superindiz" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "a superindiz" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "Enchegada" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "No ye accesible" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Desenchegada" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Lectura d'o sangrau y la chustificación desenchegada." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Enchegada" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Lectura d'o sangrau y la chustificación enchegada." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Modo d'aprendizache. Preta escape ta salir." - -#: src/cthulhu/messages.py:1201 -#, fuzzy -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Se ye dentrando en o modo d'aprendizache. Preta cualsiquier tecla ta sentir " -"a función d'ella. Ta veyer a documentación d'o lector de pantalla preta lo " -"F1. Ta obtener un listau d'os alcorces por defecto d'o lector de pantalla " -"preta lo F2. Ta obtener un listau d'os alcorces ta l'aplicación actual " -"preta lo F3. Ta salir d'o modo d'aprendizache preta la tecla d'escape." - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "Navegación por tablas" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Navegación por pachinas" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Navegación por tablas" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "Se ye salindo d'a revisión." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "_Sucherencia d'ortografía" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "Se ye deixando la tabla." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "linia seleccionada abaixo d'a posición d'o cursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "linia seleccionada alto d'a posición d'o cursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "linia deseleccionada abaixo d'a posición d'o cursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "linia deseleccionada alto d'a posición d'o cursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Se ye salindo d'o modo d'aprendizache." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "linia seleccionada dende l'encieto dica l'anterior posición d'o cursor" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "linia seleccionada dica la final dende l'anterior posición d'o cursor" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "vinclo" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "mesma pachina" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "mesmo puesto" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "puesto esferent" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s vinclo ta %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "vinco %s" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d vinclo visitau" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Emplega Flecha alto y Flecha abaixo ta navegar por a lista. Prete Escape ta " -"salir." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "S'han desactivau todas as rechions activas" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "s'ha restaurau o comportamiento de todas as rechions activas" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "Libel de comportamiento %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "Se ye establindo a rechión activa ta firme" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "Se ye establindo a rechión activa ta desactivada" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "Se ye establindo a rechión activa ta delicau" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "Se ye establindo a rechión activa ta ruda" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Monitorización de rechions activas desenchegada" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Monitorización de rechions activas enchegada" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "no s'alzó garra mensache d'actividat" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "O suporte de rechions activas ye desenchegau" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "No trobada" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "No se pudo trobar a posición actual." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "Desenchegau" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "Enchegau" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "mal escrita" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Parola mal escrita: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "O contexto ye %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Modo de navegación" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Modo de foco" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "T'activar o modo de foco preta %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Omodo de foco ye pegalloso." - -#: src/cthulhu/messages.py:1758 -#, fuzzy -msgid "Browse mode is sticky." -msgstr "Omodo de foco ye pegalloso." - -#: src/cthulhu/messages.py:1771 -#, fuzzy -msgid "Layout mode." -msgstr "Modo de foco" - -#: src/cthulhu/messages.py:1785 -#, fuzzy -msgid "Object mode." -msgstr "Obchecto" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Va ta lo siguient obchecto." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "No s'ha trobau obchecto debaixo d'o churi." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Conmutar o modo de revisión d'o churi." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Fabla enchegada." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Error: No s'ha puesto creyar a lista d'obchectos." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d por cient" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "Va ta la parola anterior." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "libel d'anidamiento %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "S'ha adhibiu un nuevo elemento" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Garra aplicación tien o foco." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Sin foco" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Garra aplicación tien o foco." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "No bi ha mas citas." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "No bi ha más botons." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "No bi ha más caixetas." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "No bi ha más obchectos grans." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "No bi ha mas clicables." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "No bi ha más quadros combinaus." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "No bi ha más dentradas." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "No bi ha mas campos de formulario." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "No bi ha mas capiters." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "No bi ha mas capiters de libel %d." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "No bi ha mas tablas." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "No bi ha mas imachens." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "No s'han trobau marcadors" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "No bi ha mas vinclos." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "No bi ha mas listas." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "No bi han mas elementos de listas." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "No bi ha mas rechions activas." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "No bi ha mas paragrafos." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "No bi ha mas botons de radio." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "No bi ha mas separadors." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "No bi ha mas tablas." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "No bi ha mas vinclos sin visitar." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "No bi ha mas vinclos visitaus." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "No trigau" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "No bi ha mas vinclos." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificación" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Fin" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Prenzipio" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Sin mensaches de notificación" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "Parola" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "Charrar cadenas con mayusclas y minusclas como _parolas" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "desenchegau" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "enchegau" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Cargando. Por favor, aspera." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Fin de la carga." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "S'ha rematau a carga de %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "pachina seleccionada dende a posición d'o cursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "pachina seleccionada dica la posición d'o cursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "pachina deseleccionada dende a posición d'o cursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "pachina deseleccionada dica la posición d'o cursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "Paragrafo seleccionau debaixo d'a posición d'o cursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragrafo seleccionau alto d'a posición d'o cursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "Paragrafo deseleccionau debaixo d'a posición d'o cursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragrafo deseleccionau alto d'a posición d'o cursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Ya tiens una instancia d'o dialogo de preferencias d'Cthulhu ubierta.\n" -"Zarra-la antis d'ubrir una nueva." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "Diapositiva %(position)d de %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Perfil establiu a %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "No s'han trobau perfils." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra de progreso %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Tot" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Libel de puntuación establiu a tot." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "A mayoría" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Libel de puntuación establiu a la mayoría." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Dengún" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Libel de puntuación establiu a dengún." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Belún" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Libel de puntuación establiu a belún." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Mirando" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Busca completa." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "S'han recargau as opcions d'o lector de pantalla." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "Elemento trigau" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "Ringlera borrada." - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Indicador de selección" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "Deseleccionau" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Fabla desenchegada." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Fabla enchegada." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "mas rapido." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "mas lento." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "mas alto." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "mas baixo." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "mas rapido." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Velocidat:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Vo_lumen:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "No bi ha servidors disponibles.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "No bi ha voces disponibles.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Fabla enchegada." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "a fabla no s'emplegará.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Libel d'información: breu" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Libel d'información: detallau" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "Puntos suspensivos" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Preferencias d'Cthulhu" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Modo ninviar tecla enchegau." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "a fabla no ye disponible." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "No trobada" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "No 'sha trobau a cadena" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "No 'sha trobau a cadena" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Teclas de navegación estructural desenchegadas." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Teclas de navegación estructural enchegadas." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "No trobau" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Ringlera %(row)d, columna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Fin de tabla" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Leyer celda" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Leyer ringlera" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "No uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "No yes en una tabla." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Columnas reordinadas" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Ringleras reordinadas" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "columna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "columna %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Fin d'a columna" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Prencipio d'a columna." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "Deseleccionau" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "Deseleccionau" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "ringlera %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "ringlera %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Prencipio de ringlera" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Fin de ringlera" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Ringlera borrada." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "A zaguera ringlera ha estau borrada." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Ringlera ficada." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "A ringlera ha estau ficada a la fin d'a tabla." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "Ringlera borrada." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "Deseleccionau" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "Seleccionau" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "Deseleccionau" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H horas, %M minutos y %S segundos." - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H horas y %M minutos." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Preferencias d'Cthulhu" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "espacio en blanco" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Se ye blincando ta la fin." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Se ye blincando ta lo prencipio." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elementos" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "A celda abarca %d ringlera" -msgstr[1] "A celda abarca %d ringleras" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d columna" -msgstr[1] " %d columnas" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "A celda abarca %d columna" -msgstr[1] "A celda abarca %d columnas" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d caracter masiau gran" -msgstr[1] "%d caracters masiau grans" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialogo)" -msgstr[1] "(%d dialogos)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d dialogo sin foco" -msgstr[1] "%d dialogos sin foco" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fichero trobau" -msgstr[1] "%d fichers trobaus" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulario" -msgstr[1] "%d formularios" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d capitero" -msgstr[1] "%d capiters" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elemento" -msgstr[1] "%d elementos" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Marca" -msgstr[1] "Marca" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d elemento trobau" -msgstr[1] "%d elementos trobaus" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "No bi ha mas citas." -msgstr[1] "No bi ha mas citas." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Se ye salindo d'a revisión." -msgstr[1] "Se ye salindo d'a revisión." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista con %d elemento" -msgstr[1] "Lista con %d elementos" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Lista con %d elemento" -msgstr[1] "Lista con %d elementos" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Valor" -msgstr[1] "Valor" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabla con %d ringlera" -msgstr[1] "tabla con %d ringleras" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d columna" -msgstr[1] "%d columnas" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tabla con %d ringlera" -msgstr[1] "tabla con %d ringleras" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d mensache.\n" -msgstr[1] "%d mensaches.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d por cient" -msgstr[1] "%d por cient" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "Ye leyiu %d por cient d'o documento" -msgstr[1] "Ye leyiu %d por cient d'o documento" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d caracter %(repeatChar)s" -msgstr[1] "%(count)d caracters %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d de %(total)d elemento seleccionau" -msgstr[1] "%(index)d de %(total)d elementos seleccionaus" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "S'ha trobau %d alcorce predeterminau d'o lector de pantalla." -msgstr[1] "S'han trobau %d alcorces predeterminaus d'o lector de pantalla." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"S'ha trobau %(count)d alcorce d'o lector de pantalla ta %(application)s." -msgstr[1] "" -"S'han trobau %(count)d alcorces d'o lector de pantalla ta %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espacio" -msgstr[1] "%d espacios" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulador" -msgstr[1] "%d tabuladors" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabla" -msgstr[1] "%d tablas" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabla con %d ringlera" -msgstr[1] "tabla con %d ringleras" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabla con %d ringlera" -msgstr[1] "tabla con %d ringleras" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabla con %d ringlera" -msgstr[1] "tabla con %d ringleras" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d vinclo sin visitar" -msgstr[1] "%d vinclos sin visitar" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d vinclo visitau" -msgstr[1] "%d vinclos visitaus" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "conmutar" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "sobre %(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "LIBEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "libel d'arbol %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "LIBEL D'ARBOL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "Zarrar interrogación" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "Va ta lo siguient quadro combinau." - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "editable" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "Parola" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "dos puntos" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "superrayau" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "adreza" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "Parola" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "sangrau" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "adreza" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "retroceso de pachina" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "Cometas" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "Activar o modo de distribución t'o conteniu" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s de libel %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "Horizontal" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "Barra vertical" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "Horizontal" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "aliniación vertical" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "Horizontal" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "aliniación vertical" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "cambiar modo" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Icono d'o panel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Notificación" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "meyo condensau" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Navegación por pachinas" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "Mirando" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d vinclo visitau" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "No bi ha más botons." - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "clicable" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "plegau" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "desplegau" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "tien Descripción luenga" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "Horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "marcau" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "desmarcau" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "enchegau" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "desenchegau" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "parcialment marcau" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "Pretau" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "sin Pretar" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "No trigau" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "Trigau" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "No trigau" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "No seleccionau" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visitau" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "sin visitar" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "Guambrau" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "nomás lectura" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "nomáslec" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "requiesto" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "selección-multiple" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "error d'ortografía" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "error d'ortografía" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Mirar" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Dialogo de busca d'o lector de pantalla>" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Zarrar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Mirar" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Mirar:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Mirar:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Parti d'_alto d'a finestra" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Parti d'alto d'a finestra" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Empecipiar en:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Blinco" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Mirar enta _zaga" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Adreza de busca:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Coincidir _mayusclas y minusclas" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Coincidir nomás que con a parola _entera" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Opcions de busca" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Predeterminau" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Mayuscla" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hipervinclo" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicación" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Finestra" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferencias d'Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "Ad_uya" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Aplicar" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Portatil" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Distribución d'o teclau" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Perfil activo:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Perfil inicial:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Cargar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "_Alzar como" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Perfils" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Presentar consellos" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Leyer l'obchecto debaixo d'o ch_uri." - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Churi" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Forma_to d'hora:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formato de cal_endata:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Calendata y hora" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "Leyer _tot" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Indicador Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Freqüencia (segundos):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Aplicación" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Actualizacions d'a barra de progreso" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "Activar a navegación estructural" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Leyer tot _por:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "Leyer tot _por:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Cheneral" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lumen:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Tono:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Velocidat:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persona:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "idioma" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "_Sintetizador de voz:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Sistema de _voz:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Mena de _voz:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -#, fuzzy -msgid "_Capitalization style:" -msgstr "Estilo de capitalización establiu a icono." - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Configuración d'a mena de voz" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Charrar cadenas con mayusclas y minusclas como _parolas" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Configuración global de voz" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Activar voz" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Estendillada" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Cantidat d'información" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Toda" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Libel de puntuación" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Charrar nomás que lo texto amostrau" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Leyer linias vuedas" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Leyer _sangrau y chustificación" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Leyer _as teclas d'acceso de l'obchecto" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Leyer a p_osición d'o fillo" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Leyer mensaches d'aprendizaje" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "Leyer as coordenadas d'una _celda" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -#, fuzzy -msgid "Announce block_quotes during navigation" -msgstr "Modo de foco automatico entre a navegación de cursor" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -#, fuzzy -msgid "Announce _lists during navigation" -msgstr "Activar a navegación estructural" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -#, fuzzy -msgid "Announce _tables during navigation" -msgstr "Activar a navegación estructural" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "Leyer as coordenadas d'una _celda" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -#, fuzzy -msgid "Announce _forms during navigation" -msgstr "Modo de foco automatico entre a navegación de cursor" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "Descripción" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Contexto charrau" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Activar _suporte Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Nombre de rols _abreviaus" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Desactivar o simbolo de _fin de linia" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tabla de contracción:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Activar Braille contraiiu" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Activar eco por _parolas" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Configuración de pantalla" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Dengún" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicador de selección" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicador d'hipervinclo" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "Configuración global de voz" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Activar _eco de teclas" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Activar teclas de _navegación" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "Activar teclas _modificaderas" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Activar teclas de _función" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "_Activar voz" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Activar teclas _modificaderas" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Activar teclas de _función" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Activar teclas d'_acción" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Activar teclas de _navegación" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Activar eco por _parolas" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Activar eco por _frases" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Eco de teclas" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Tecla(s) _modificaderas d'o lector de pantalla:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Alcorces de teclau" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Diccionario de pronuncia" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Dentrada _nueva" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Borrar" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronuncia" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Leyer _tot" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "No pas leyer _garra" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Reenchegar" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributos de texto" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mover ta la _fin" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mover un _abaixo" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mover un a_rriba" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mover ta lo _prencipio" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "Achustar os atributos seleccionaus" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicador Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributos de texto" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "baixo" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "idioma" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -#, fuzzy -msgid "Copy Results to _Clipboard" -msgstr "S'han copiau os contenius en o portafuellas." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : Ababol, b : Bardo, c : Calient, d : Dalla, e : Encorrer, f : Fartera, " -"g : Garrampa, h : Historia, i : Ibón, j : Jota, k : Kilo, l : Lifara, m : " -"Masar, n : Noviembre, o : Olivera, p : Pretar, q : Quefer, r : Royo, s : " -"Sequera, t : Teta, u : Universidat, v : Viello, w : Whisky, x : Xuto, y : " -"Yayo, z : Zapo" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "color de fondo" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "altura completa d'o fondo" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "fondo puntiau" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "adreza" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editable" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nombre d'a fuent" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "color de primer plano" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "primer plano puntiau" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efecto de fuent" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "sangrau" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "error" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "chustificación" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "idioma" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "marguin cucha" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "altura d'a linia" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "estilo de paragrafo" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixels por alto d'as linias" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixels por debaixo d'as linias" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixels dentro d'a linia" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "marguin dreita" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "prencipio" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "escala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "mida" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "estirar" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "tachau" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estilo" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decoración d'o texto" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotación d'o texto" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "texto guambrau" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "subrayau" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "aliniación vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "peso" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "modo expandiu" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "modo d'escritura" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "verdadero" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falso" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "dengún" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "gravar" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "membrete" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "resumen" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "superrayau" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "tachau" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "parpadeyo" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "negra" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "sencillo" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dople" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "baixo" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "caracter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "parola" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "deseparación" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "C-->D" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "D-->C" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "cucha" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "dreita" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centrau" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "sin chustificación" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "plena" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensau" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensau" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensau" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "meyo condensau" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "meyo expandiu" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expandiu" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra expandiu" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra expandiu" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "mayusclas chicotas" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "obliquo" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "cursiva" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "predeterminau" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "cuerpo d'o texto" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "capitero" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "en linia" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "subíndiz" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "superindiz" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "superior" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "texto superior" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "meyo" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "inferior" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "texto inferior" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "heredar" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "Cd-aB" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "DC-AB" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "AB-DC" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "AB-CD" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "BA-DC" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "BA-CD" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "CD" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "DC" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "AB" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "tachau" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "error d'ortografía" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Preta espacio ta conmutar." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Preta espacio ta desplegar y emplega flecha alto y flecha abaixo ta trigar " -"un elemento." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Preta Alt+f6 ta dar o foco a las finestras fillas." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "Ta mover ta los elementos, emplega las flechas u escribe ta mirar." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Ta ir ta los menús d'o sistema preta la tecla alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Emplega flecha alto u flecha abaixo ta trigar un elemento." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Ta plegar preta mayuscla y flecha cucha." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Ta desplegar preta mayuscla mas flecha dreita." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Ta activar preta enter." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Escriba un texto" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Emplega flecha cucha y flecha dreita ta veyer atras pestanyas." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Ta activar preta espacio." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Emplega flecha alto u flecha abaixo ta trigar una valor. U tecleya la valor " -"numerica que quiers." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Ta cambiar emplega las flechas." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Ta navegar preta flecha cucha u flecha dreita. Ta mover entre os elementos " -"preta flecha alto u flecha abaixo." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Ta dentrar en o submenú preta flecha dreita." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Ta baixar preta flecha cucha, ta puyar preta flecha dreita, t'o minimo preta " -"inicio y t'o maximo preta fin." diff --git a/po/ar.po b/po/ar.po deleted file mode 100644 index ebd22a9..0000000 --- a/po/ar.po +++ /dev/null @@ -1,10096 +0,0 @@ -# translation of cthulhu.HEAD.po to Arabic -# Copyright (C) 2004-2010 Cthulhu contributors -# This file is distributed under the same license as the Cthulhu package. -# -# Djihed Afifi , 2006. -# Khaled Hosny , 2006, 2007. -# Ahmad Farghal , 2007. -# Usama Akkad , 2008. -# Fatma Mehanna , 2010. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2010-04-06 18:55+0200\n" -"Last-Translator: \n" -"Language-Team: Arabic\n" -"Language: ar\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " -"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -"X-Poedit-Language: Arabic\n" - -msgid "Cthulhu Screen Reader" -msgstr "قارئ الشاشة Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "شاشة;قارئ;إمكانية الوصول;كلام;برايل;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "؟؟؟" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "تنبيه" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "انيم" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "سهم" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "رزنم" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "سنف" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "تسمية" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "خيار" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "حوار اختيار الألوان" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "رأس العمود" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "صندوق" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "دأت" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "أقن" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "إطار" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "وجّه" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "حوار" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "شباك الدلائل" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "HTML" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "رسم" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "حوار الملفات" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "فلر" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "فنت" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "جدول" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "لوح بلوري" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "صورة" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "إطار" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "عنوان" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "لوح طبقي" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "قائمة" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "عنصر قائمة" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "قائمة" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "شريط القوائم" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "عنصر قائمة" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "لوح الخيارات" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "لسن" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "جداول" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "شريط" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "ب.أ.د" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "قائمة منبثقة" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "عمود التقدم" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "زر" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "اختيار" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "عنصر زر راديو" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "لوحة جذرية" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "ترويسة السطر" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "لف" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "قسم" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "مفرق" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "مزلق" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "إنقسام" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "تدوير" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "حالة" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "جدول" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "خلية" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "نزع عنصر" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "عبارة" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "نص" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "زر" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "أدوات" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "تلميحة" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "شجر" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "جشجرة" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "مظهر" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "نفذ" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "رأسي" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "هامش" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "فقرة" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "تطق" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "آلي" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "تحرير" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "مضمّن" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "تشيكي بدون اختصارات" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "إسباني بدون اختصارات" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "الفرنسية الكندية باختصارات " - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "الفرنسية الفرنسية باختصارات" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "اللاتيفية بدون اختصارات " - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "الألمانية الهولندية بدون اختصارات" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "النرويجية الدرجة 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "النرويجية الدرجة 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "النرويجية الدرجة 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "النرويجية الدرجة 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "البولندية الدرجة 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "البرتغالية الدرجة 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "السويدية الدرجة 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "العربية الدرجة 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "الويلزية الدرجة 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "الويلزية الدرجة 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "الألمانية الدرجة 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "الألمانية الدرجة 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "الألمانية الدرجة 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "الإنكليزية م.م الدرجة 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "الإنكليزية م.م الدرجة 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "الإنكليزية و.م الدرجة 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "الإنكليزية و.م الدرجة 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "الفرنسية الكندية الدرجة 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "الفرنسية الفرنسية الدرجة 2" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "اليونانية الدرجة 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "الهندية الدرجة 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -#, fuzzy -msgid "Hungarian Grade 1" -msgstr "اللاتيفية بدون اختصارات " - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "اللاتيفية بدون اختصارات " - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "الإيطالية الدرجة 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "الألمانية البلجيكية الدرجة 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "فراغ" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "سطر جديد" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "لسان" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "تعجب" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "اقتباس" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "رقم" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "دولار" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "نسبة مئوية" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "و" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "حركة" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "قوس مفتوح" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "قوس مغلق" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "نجمة" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "زائد" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "فاصلة" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "خط فاصل" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "نقطة" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "شرطة" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "فاصلة" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "فاصلة منقوطة" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "أقل" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "يساوي" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "أعظم" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "سؤال" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "عند" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "قوس أيسر" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "شَّرطة معكوسة" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "قوس أيمن" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "مؤشر" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "تسطير" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "علامة" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "قوص أيسر" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "خط عامودي" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "قوص أيمن" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "حركة" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "مسافة للخلف" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "علامة تعجب مقلوبة" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "سنت" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "جنيه استرليني" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "علامة عملة" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "ين" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "خط عمودي منكسر" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "قسم" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "حقوق النسخ" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "قوس مزدوج أيسر" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "'لا' منطقي" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "بداية اقتباس" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "مسجل" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "خط افقي علوي" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "درجة" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "زائد أو ناقص" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "2 علوي" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "3 علوي" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -#, fuzzy -msgid "acute" -msgstr "a حاد" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "مو" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "علامة فقرة" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "نقطة وسطية" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "فاصلة" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 علوي" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "العدد الترتيبي" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "قوس مزدوج أيمن" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "ربع" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "نص" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "ثلاثة أرباع" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "علامة استفهام مقلوبة" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a حاد" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A شديد" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A حاد" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A علامة" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A تلدة" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A نقطتين" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A دائرة" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C سيدلا" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E شديد" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E حاد" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E علامة" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E نقطتين" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I شديد" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I حاد" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I علامة" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I نقطتين" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "اث" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N تلدة" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O شديد" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O حاد" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O علامة" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O تلدة" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O نقطتين" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "مضروب في" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O خط" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U شديد" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U حاد" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U علامة" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U نقطتين" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y حاد" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "ثورن" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s حاد" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "A شديد" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "E علامة" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "O تلدة" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "U نقطتين" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a حلقة" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c سيدلا" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e شديد" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e حاد" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e علامة" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e نقطتين" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i شديد" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i حاد" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i علامة" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i نقطتين" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "اث" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n تلدة" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o شديد" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o حاد" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o علامة" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o تلدة" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o نقطتين" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "مقسوم على" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o مخطط" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "ثورن" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "Y حاد" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u بعلامة" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "E علامة" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "U نقطتين" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "Y حاد" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "U نقطتين" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "U نقطتين" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "فلورين" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "خط فاصل" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "علامة إقتباس يسرى" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "علامة اقتباس احادية يمنى" - -#: src/cthulhu/chnames.py:593 -#, fuzzy -msgid "single low quote" -msgstr "علامة إقتباس يسرى" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "علامة إقتباس مزدوجة يسرى" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "علامة إقتباس مزدوجة يمنى" - -#: src/cthulhu/chnames.py:605 -#, fuzzy -msgid "double low quote" -msgstr "علامة إقتباس مزدوجة يسرى" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "علامة الصليب" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "رمز صليب مزدوج" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "نقطة غليظة" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "علامة مثلثية" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "في الألف" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "فتحة" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "فتحتين" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "فتحتين" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "خط" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "أورو" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "علامة تجارية" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "علامة موافقة" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "علامة صحيح شديدة" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "علامة x" - -#: src/cthulhu/chnames.py:672 -#, fuzzy -msgid "superscript 0" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:676 -#, fuzzy -msgid "superscript 4" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:680 -#, fuzzy -msgid "superscript 5" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:684 -#, fuzzy -msgid "superscript 6" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:688 -#, fuzzy -msgid "superscript 7" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:692 -#, fuzzy -msgid "superscript 8" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:696 -#, fuzzy -msgid "superscript 9" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:700 -#, fuzzy -msgid "superscript plus" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:704 -#, fuzzy -msgid "superscript minus" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:708 -#, fuzzy -msgid "superscript equals" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:720 -#, fuzzy -msgid "superscript n" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:724 -#, fuzzy -msgid "subscript 0" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:728 -#, fuzzy -msgid "subscript 1" -msgstr "1 علوي" - -#: src/cthulhu/chnames.py:732 -#, fuzzy -msgid "subscript 2" -msgstr "2 علوي" - -#: src/cthulhu/chnames.py:736 -#, fuzzy -msgid "subscript 3" -msgstr "3 علوي" - -#: src/cthulhu/chnames.py:740 -#, fuzzy -msgid "subscript 4" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:744 -#, fuzzy -msgid "subscript 5" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:748 -#, fuzzy -msgid "subscript 6" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:752 -#, fuzzy -msgid "subscript 7" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:756 -#, fuzzy -msgid "subscript 8" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:760 -#, fuzzy -msgid "subscript 9" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:764 -#, fuzzy -msgid "subscript plus" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:772 -#, fuzzy -msgid "subscript equals" -msgstr "a علوي" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "قوس مفتوح" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "قوس مغلق" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "مربع أسود" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "معين أسود" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "إلى الحرف التالي." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "يتكلم بمحتويات السطر." - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "أداء نقر الزر الأيسر على عنصر المراجعة المُسطح." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "أداء نقر الزر الأيمن على عنصر المراجعة المُسطح." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "عرض كامل للمستند" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "ينطق بخط المراجعة المسطحة الحالي." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "يؤدي عملية أين أنا الاساسية." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "يقوم بعملية أين أنا المفصّلة." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "ينطق بخط المراجعة المسطحة الحالي." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "تكلم بالأسطر الفارغة" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "عرض الزر الافتراضي" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "ينطق بشريط الحالة." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "ينطق بشريط العنوان." - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "لفتح مربع حوار الإيجاد الخاص بأوركا." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "عرض قائمة الإجراءات" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "للبحث عن المرة اللاحقة لعبارة." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "للبحث عن المرة السابقة لعبارة." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "دخول وخروج نمط المراجعة الثابتة." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "ينقل المراجعة المسطحة إلى الموقع النهائي." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "ينقل المراجعة المسطحة إلى الموقع الأولي." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "ينقل المراجعة المسطحة إلى الموقع النهائي." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "ينقل المراجعة المسطحة إلى بداية السطر السابق" - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "ينطق بخط المراجعة المسطحة الحالي." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "يهجأ خط المراجعة المسطحة الحالي." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "يهجأ خط المراجعة المسطحة الحالي صوتيا." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "ينقل المراجعة المسطحة إلى بداية السطر التالي." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "ينقل المراجعة المسطحة إلى الكلمة او العنصر السابق." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "ينطق بعنصر أو كلمة المراجعة المسطحة الحالية." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "يهجئ عنصر أو كلمة المراجعة المسطحة الحالية." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "يهجئ عنصر أو كلمة المراجعة المسطحة صوتيا." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "ينقل المراجعة المسطحة إلى الكلمة التالية." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "ينقل المراجعة المسطحة إلى الكلمة فوق الحالية." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "يقرأ بكائن المراجعة المسطحة الحالي." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "ينقل المراجعة المسطحة إلى الكلمة التي تحت الكلمة الحالية." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "ينقل المراجعة المسطحة إلى الحرف السابق." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "يقرأ بحرف المراجعة المسطحة." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "ينطق بحرف المراجعة المسطحة الحالي." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "يقرأ بحرف المراجعة المسطحة." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "ينقل المراجعة المسطحة إلى الحرف التالي." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "ينقل المراجعة المسطحة إلى نهاية الخط." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "ينقل المراجعة المسطحة إلى أسفل اليسار." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "ينطق بعنصر أو كلمة المراجعة المسطحة الحالية." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "ينطق بعنصر أو كلمة المراجعة المسطحة الحالية." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "ينقل المراجعة المسطحة إلى الموقع النهائي." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "يحدد ما إذا يجب قراءة خلية الجدول الحالي أو كامل الصف." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "يقرأ صفات الحرف الحالي." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "عرض البرايل الى اليسار." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "عرض البرايل الى اليمين." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "يرجع للكائن الذي يملك إشارات لوحة المفاتيح." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "_فعّل بريل متقلصة" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "يذهب لبداية السطر." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "يذهب لنهاية السطر." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "يدخل نمط التعلم. اضغط ESC للخروج." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "يخفض تردد الحديث." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "يزيد تردد الحديث." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "يخفض قوة الحديث." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "يزيد قوة الحديث." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "يزيد تردد الحديث." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "يخفض تردد الحديث." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "تحديد إعداد الكلام السابق" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "تحديد إعداد الكلام التالي" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "تقليل إعداد الكلام الحالي" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "زيادة إعداد الكلام الحالي" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "حفظ إعدادات الكلام" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "تفعيل/تعطيل اسكات القراءة." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "تبديل وضع السكون" - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "قارئ الشاشة و المكبّر أوركا" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "يظهر حوار الإعدادات." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "يظهر حوار إعدادات التطبيق." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "الكلام بالتصفيف و الت_نقيط" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "يدور لوضع التكبير التالي." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "يدور لوضع التكبير التالي." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "يدور لوضع التكبير التالي." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "يدور لوضع التكبير التالي." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "يدور لوضع التكبير التالي." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "يدير مستوى التنقيح عند التشغيل." - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "علامة الموقع بالنسبة للموقع الحالي." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "اذهب إلى علامة الموقع السابقة" - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "اذهب إلى علامة الموقع." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "اذهب إلى علامة الموقع التالية" - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "اضِف علامة موقع." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "احفظ علامات المواقع." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "يبدل وضع المراجعة بالفأرة." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "يمرر الأمر التالي إلى التطبيق الحالي." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "إنطق و ببرايل رسالة المحادثة السابقة." - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "تغيير إذا ما علينا الإعلان عندما يكتب أصدقائنا." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "تغيير ما إذا علينا توفير تاريخ غرفة المحادثة لرسائل مخصصة." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "تغيير ما إذا يجب بدأ رسالات المحاديثة باسم غرفة المحادثة." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "يسار خط" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "يمين خط" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "خط أعلى" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "خط أسفل" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "أعلى اليسار" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "النصف الأسفل" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "موقع المؤشّر" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "موقع المؤشّر" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "خط" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "يزيد مستوى التكبير." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "يزيد مستوى التكبير." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "يزيد مستوى التكبير." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "إلى الحرف التالي." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "إلى الحرف السابق." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "إلى الكلمة التالية." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "إلى الكلمة السابقة." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "إلى السطر التالي." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "إلى الكلمة السابق." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "يذهب لأعلى الملف." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "يذهب لأسفل الملف." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "يذهب لبداية السطر." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "يذهب لنهاية السطر." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "يذهب للكائن التالي." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "يذهب للكائن السابق." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "تؤدي إلى فتح صندوق الإختيار الحالي." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "تحول من تصفح المؤشر لجيكو أو أوركا." - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "إعدادات تهذيب متقدمة للمنطقة الحية." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "ضع مستوى التهذيب الافتراضي للمنطقة الحية على معطّل." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "راجع إعلانات المنطقة الحية." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "راقب المناطق الحية." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "حدد الصف المستعمل كترويسات أعمدة ديناميكية عند التكلم بخلايا كالك." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "يمسح رؤوس الاعمدة المتغيرة." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "حدد العمود المستعمل كترويسات صفوف ديناميكية عند التكلم بخلايا كالك." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "يمسح رؤوس الصفوف المتغيرة." - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "يتكلم بمحتويات السطر." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "فعل و عطل مفاتيح التصفح." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "إذهب إلى الإقتباس السابق." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "إذهب إلى الإقتباس التالي." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "يذهب للزر السابق." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "يذهب للزر التالي." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "عرض خيارات أخرى" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "يذهب لمربع الاختيار السابق." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "يذهب لمربع الإختيار التالي." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "إذهب إلى الجدول السابق." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "إذهب إلى الإقتباس التالي." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "يذهب لمربع تحرير و سرد السابق." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "يذهب لمربع تحرير و سرد التالي." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "محتوي h t m l" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "محتوي h t m l" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "يذهب للمُدخل السابق." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "يذهب للمُدخل التالي." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "إذهب إلى المجال السابق." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "إذهب إلى المجال التالي." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "إلى العنوان السابق." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "إلى العنوان التالي." - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "عرض خيارات أخرى" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "يذهب للترويسة السابقة عند المستوى %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "يذهب للترويسة التالية عند المستوى %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "لا عناوين أخرى عند المستوى %d." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "إذهب إلى الجدول السابق." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "إطار داخلي" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "إلى الكلمة السابق." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "إلى السطر التالي." - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "عرض خيارات أخرى" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "يذهب للمعْم السابق." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "يذهب للمعْلم التالي." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "الى الكائن الكبير التالي." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "إلى الكائن الكبير التالي." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "لا كائنات كبيرة أخرى." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "إلى الكلمة السابق." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "إلى السطر التالي." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "عرض خيارات أخرى" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "إلى القائمة السابقة." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "إلى القائمة التالية." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "الى عنصر القائمة السابق." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "الى عنصر القائمة التالي." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "يذهب للمنطقة الحية السابقة." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "يذهب للمنطقة الحية إلى الةسطر التالي." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "راجع إعلانات المنطقة الحية." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "الانتقال إلى الكائن الأصلي للكائن ذي تركيز المتصفح." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "الانتقال إلى الكائن الفرعي الأول للكائن ذي تركيز المتصفح." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "الانتقال إلى الشقيق التالي للكائن ذي تركيز المتصفح." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "الانتقال إلى الشقيق السابق للكائن ذي تركيز المتصفح." - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "يرجع للكائن الذي يملك إشارات لوحة المفاتيح." - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "فعل و عطل مفاتيح التصفح." - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "يذهب للفقرة السابقة." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "يذهب للفقرة التالية." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "يذهب لزر الراديو السابق." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "يذهب لزر الراديو التالي." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "لا أزرار راديو أخرى." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "يذهب للفقرة السابقة." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "يذهب للفقرة التالية." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "إذهب إلى الجدول السابق." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "إذهب إلى الإقتباس التالي." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "إلى الخلية نحو الأسفل." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "إلى الخلية الأولى في الجدول" - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "إلى الخلية الأخيرة في الجدول" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "إلى الخلية نحو اليسار." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "إلى الخلية نحو اليمين." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "إلى الخلية نحو الأعلى." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "يبدل وضع المراجعة بالفأرة." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "تفعيل _صدى المفاتيح" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "الى الوصلة غير المزارة السابقة." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "الى الوصلة غير المزارة التالية." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "لا روابط غير مزارة أخرى." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "إذهب إلى الرابط المزار السابق." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "إذهب إلى الرابط المزار التالي." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "لا روابط مزارة أخرى." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "ازرق مشبع" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "أسود" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "معين أسود" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "ازرق مشبع" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "ازرق مشبع" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "A شديد" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "اخضر مشبع" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "اخضر مشبع" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "احمر مشبع" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "اخضر مشبع" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "ازرق مشبع" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i شديد" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "أخضر باهت" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "غير مفعل" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "درجة" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "الهندية الدرجة 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "قوص أيمن" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "زر كنترول اليميني" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "قوس مغلق" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "قوص أيمن" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "قوس مغلق" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "قوس مغلق" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "زر alt اليميني" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "قوس مغلق" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "السوبر اليميني" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "قوس مغلق" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "سطر جديد" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "صورة" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "ازرق باهت" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "احمر مشبع" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "اخضر مشبع" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "شجر" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "ازرق مشبع" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s شاشة" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "ازرق باهت" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "ازرق باهت" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "زر" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "فراغ" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "فراغ" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "ملئ الشاشة" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "النقطة _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "النقطة _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "النقطة 7 _و 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "أيقونة." - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "لا شيء" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "تحقق املائي:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "أعلن عندما يكتب أ_صدقائك" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "يوفر تاريخ غرفة المحادثة ل_رسائل مخصصة" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "انطق بالرسائل من" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "كل ال_قنوات" - -#: src/cthulhu/guilabels.py:173 -#, fuzzy, python-format -msgid "All channels when an_y %s window is active" -msgstr "كل القنوات عندما تكون اي نافذة بدجن نشطة" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "قناة فقط إن كانت نافذتها نشطة" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "إ_نطق بإسم غرفة المحادثة" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -#, fuzzy -msgid "double click" -msgstr "(نقر مزدوج)" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -#, fuzzy -msgid "triple click" -msgstr "(نقر ثلاثي)" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "نظام النطق الإفتراضي" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "النص الحالي" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "النص المستبدل" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "تفعيل الصدى بال_كلمة" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "تفعيل مفاتيح ال_تصفح" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "الموقع ال_حالي" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "الطول الأقصى للنص المطابَق:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "جد خيارات" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "انطق بالأسطر الم_ختلفة فقط عند البحث" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "انطق بالنتائج عند ال_بحث" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "فاصلة" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "ارتباط المفتاح" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "افتراضي" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "نمط الكتابة" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "الإجراءات" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ارتباطات برايل" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "الإشارات المرجعية" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "تصفح الجدول" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "فك التقييد" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "دخول وخروج نمط المراجعة الثابتة." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "مُعدَّل" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_حاسوب مكتبي" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "اشعار %s" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "مستلم" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "اشعار %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "تفضيلات أوركا لـ %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "اكتب ببرايل" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "موجود إلا إذا" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "نطق" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "ال_كل" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "تطبيق" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "نافذة" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "_لا شيء" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "ب_عض" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "م_عظم" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "خط" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "جملة" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "اقتباس" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "زر" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "تسمية" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "مربع_خيار" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "صندوق مجموعة" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "a علوي" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "ترويس" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "إطار داخلي" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "صورة" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "علامة" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "علامة تجارية" - -#: src/cthulhu/guilabels.py:611 -#, fuzzy -msgctxt "structural navigation" -msgid "Level" -msgstr "المستوى %d" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "الوصلة" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "قائمة" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "عنصر قائمة" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "فقرة" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "زر راديو" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "مُنتقى" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "الحالة" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "نص" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "لا قطع أخرى." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "زر" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "مربع_خيار" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "صندوق مجموعة" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "ترويس" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "إطار داخلي" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "صورة" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "لا عناوين أخرى عند المستوى %d." - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "علامة تجارية" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "لا كائنات كبيرة أخرى." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "الوصلة" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "قائمة" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "عنصر قائمة" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "فقرة" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "زر راديو" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "جدول" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d من الوصلات غير المزارة" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d من الوصلات المزارة" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "تصفح الصفحة" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "ا_نطق بالصفحة آليا عند تحميلها أولا" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "ا_نطق بالصفحة آليا عند تحميلها أولا" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr " %s صوت افتراضي" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "افتراضي" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "وصله" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "حروف كبيرة" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "نظام النطق" - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "تحقق املائي:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "انطق بإحداثيات الخلية" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "اعلن عنوان ال_خلية" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "تصفح الجدول" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "تخطى الخلايا الفارغة" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "انطق خلية" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "ا_نطق باحداثيات الخلية" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "انطق بمقدار _توسع الخلية" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "اسم الصنف" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "استعمل تصفح المؤشر لأور_كا" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "فعل و عطل مفاتيح التصفح." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "سمة ال_صوت:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "سمة الصوت" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "م_لخّص" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "اشعار %s" -msgstr[1] "اشعار %s" -msgstr[2] "اشعار %s" -msgstr[3] "اشعار %s" -msgstr[4] "اشعار %s" -msgstr[5] "اشعار %s" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt_R" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "زر كنترول اليميني" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "زر التغيير اليساري" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "زر alt اليساري" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "زر كنترول اليميني" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "زر التغيير اليميني" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "زر alt اليميني" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "زر كنترول اليميني" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ميتا يساري" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "ميتا يميني" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "قفل الأرقام" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "تغيير الزر" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "تغيير الزر" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "إقفال اللف" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "صفحة أعلى" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "صفحة أسفل" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "اللسان الأيسر" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "مسافة للخلف" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "عودة" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "إدخال" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "فوق" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "تحت" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "يسار" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "يمين" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "السوبر اليساري" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "السوبر اليميني" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "قائمة" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "مساعدة" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "متعدد" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "تبديل الوضع" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "اهرب" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "أدرج" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "إحذف" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "المنزل" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "النهاية" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "ابدأ" - -#: src/cthulhu/keynames.py:276 -#, fuzzy -msgid "circumflex" -msgstr "E علامة" - -#: src/cthulhu/keynames.py:291 -#, fuzzy -msgid "ring" -msgstr "a حلقة" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "o مخطط" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "ناقص" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "أدرج" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "تغيير الزر" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "ممتاز" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "ميتا2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "سميك" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "مائل" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "a علوي" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "a علوي" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "مساحة عمل" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "السياق هو %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "قوس مفتوح" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "سهم" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "قوس مغلق" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "سهم" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "قوس مغلق" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "قوس مغلق" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "قوس مغلق" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "قوس مفتوح" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "قوس مفتوح" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "قوس مغلق" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "علامة إقتباس مزدوجة يسرى" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "رمز صليب مزدوج" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "علامة إقتباس مزدوجة يمنى" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "رمز صليب مزدوج" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "علامة إقتباس مزدوجة يمنى" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "سهم نحو اليمين" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "رأس سهم نحو اليمين" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "ناقص" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "أقل" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "أعظم" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "E علامة" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "نقطة" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "محاذاة عمودية" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "أفقي" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "إنهاء آلي" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "فارغ" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "تفعيل ال_حدود" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "نهاية الصف." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "فرع" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "زائد أو ناقص" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "زائد" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "ناقص" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "مفرق" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "جذر تربيعي" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "جذر ثلاثي" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "جذر تربيعي" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "متناسب" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "لانهاية" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "زر alt اليميني" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "مفرد" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "عمود ذي مستويات" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "محاذاة عمودية" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "مقسوم على" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "فاصل" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "غير معادل لـ" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "'لا' منطقي" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "'لا' منطقي" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "التوجه" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "إطار داخلي" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "فتحتين" - -#: src/cthulhu/mathsymbols.py:1512 -#, fuzzy -msgctxt "math symbol" -msgid "triple integral" -msgstr "فترة التحديث:" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -#, fuzzy -msgctxt "math symbol" -msgid "surface integral" -msgstr "فترة التحديث:" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "متناسب" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "ناقص" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "حركة" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n تلدة" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n تلدة" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "يساوي تقريبا" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "يساوي تقريبا" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "يساوي تقريبا" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "يساوي تقريبا" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "يساوي تقريبا" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "يساوي تقريبا" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "(نقر ثلاثي)" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "يساوي تقريبا" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "موقع مختلف" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "غير معادل لـ" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "يساوي" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "يساوي" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "غير معادل لـ" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "غير معادل لـ" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "علامة مثلثية" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "يساوي" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "غير معادل لـ" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "غير معادل لـ" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "عمودي" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "غير معادل لـ" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "غير معادل لـ" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "أعظم" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "غير مضغوط" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr " غير محددة" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "a علوي" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "a علوي" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "إنتقاء جماعي" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "محاذاة" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "إنتقاء جماعي" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "جذر تربيعي" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "جذر تربيعي" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "جذر تربيعي" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "جذر تربيعي" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "a علوي" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "خط فاصل" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "a علوي" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "a علوي" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "جذر تربيعي" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "جذر تربيعي" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "ميتا يميني" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "اللسان الأيسر" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "تحت" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "قسم" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "صحيح" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "صحيح" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "العدد الترتيبي" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "صورة" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "متعدد" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "إطار داخلي" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "عادي" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "علامة اقتباس احادية يمنى" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "قوص أيمن" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "مفرق" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "'لا' منطقي" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "'لا' منطقي" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "فتحتين" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "فتحتين" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "التوجه" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "فتحتين" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "أصغر من او يساوي" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "أكبر من او يساوي" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "محاذاة عمودية" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "قوس مفتوح" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "قوس مغلق" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "زر alt اليساري" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "زر alt اليميني" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "قوص أيسر" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "أسفل" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "قوس مزدوج أيسر" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "قوس مزدوج أيمن" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "نقطة وسطية" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "التوجه" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "جذر تربيعي" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "مربع أسود" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "مربع أبيض" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "معين أسود" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "دائرة بيضاء" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "دائرة سوداء" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "نقطة غليظة بيضاء" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "مربع أسود" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "تسطير" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "محاذاة عمودية" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "تطبيق" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "فارغ" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "سميك" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "تم إدخال علامة مرجعية" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "تم حفظ العلامات المرجعية " - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "لا يمكن حفظ العلامات المرجعية " - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "لا معالم." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "لا معالم." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "وضع التجاوز مفعل." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "تعذر جلب عارض الحاسبة" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "أيقونة" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "بلا" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "يتحكّم جيكو في المؤشر." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "يتحكّم أوركا بالمؤشر." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "الخلية %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "مُنتقى" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr " غير محددة" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "غير منتقى" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "امنع استخدام الخيار" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "أجبر على استخدام الخيار" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "اطبع التطبيقات المعروفة المشغلة" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "لا يمكن حفظ العلامات المرجعية " - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "استخدم دليلا بديلا لتفضيلات المستخدم" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "اطبع التطبيقات المعروفة المشغلة" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "استبدال مثيل Cthulhu قيد التشغيل حاليًا" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "اعرض رسالة المساعدة هذه" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "أعدّ تفضيلات المستخدم (النسخة النصية)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "أعدّ تفضيلات المستخدم (النسخة النصية)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "تقرير العلل لـ https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "a حاد" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "اسرع." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "لا تعلن عندما يكتب أصدقائك." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "أعلن عندما يكتب أصدقائك." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "رسال من غرفة المحادثة %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "لسان محادثة جديد %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "لا تتكلم باسم غرفة المحادثة." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "تكلم باسم غرفة المحادثة." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "لا توفر تاريخ غرفة المحادثة لرسائل مخصصة." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "يوفر تاريخ غرفة المحادثة لرسائل مخصصة." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "مؤشر الإنتقاء" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "إحذف" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "أدرج" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "سؤال" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "%d من الجداول" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "ليس في جدول." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr " غير محددة" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "الزر الإفتراضي هو %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "الزر الإفتراضي هو %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "الزر الإفتراضي هو %s" - -#: src/cthulhu/messages.py:518 -#, fuzzy, python-format -msgid " subscript %s" -msgstr "a علوي" - -#: src/cthulhu/messages.py:524 -#, fuzzy, python-format -msgid " superscript %s" -msgstr "a علوي" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "ليس في جدول." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "كامل المستند" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "كامل المستند" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "مستند مختار من مكان المؤشّر." - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "مستند ملغى اختياره من مكان المؤشّر" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "مستند مختار إلى مكان المؤشّر." - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "مستند ملغى اختياره إلى مكان المؤشّر" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "رأس العمود المتغير وضع للصف %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "تم مسح ترويسة عمود الجدول الديناميكية." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "تم تحديد ترويسة الصف للعمود %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "تم مسح ترويسة صف الجدول الديناميكية." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "فارغ" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f كيلوبايت" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f ميغابايت" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "لم يتم العثور على ملفات" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "دخول وخروج نمط المراجعة الثابتة." - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "دخول وخروج نمط المراجعة الثابتة." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "ينقل المراجعة المسطحة إلى الكلمة فوق الحالية." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "مراجعة مسطحة غير مقيدة" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "له وظيفة" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "حوار" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "قائمة منبثقة" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "المفتاح المدخل مرتبط مسبقا ب %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "تم ادخال مفتاح: %s. اضغط مفتاح الرجوع للتأكيد." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "المفتاح الجديد هو: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "حُذف ارتباط المفتاح. إضغط إدخال للتأكيد." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "حُذف ارتباط المفتاح." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "أدخل المفتاح الجديد" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "إلى الكلمة التالية." - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "لا شيء" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "إلى الكلمة التالية." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "إلى الكلمة التالية." - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "جملة" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "تفعيل الصدى بال_جملة" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "كلمة" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "إلى الكلمة التالية." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "تفعيل الصدى بال_جملة" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "دائرة سوداء" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "أفقي" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "خط عامودي" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "قوس مغلق" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "اللف للأسفل." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "علو السطر" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "و" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "فوق السطر" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "جذر تربيعي" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "جذر ثلاثي" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "لوح الجذر" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "لوح الجذر" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "لوح الجذر" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "a علوي" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "a علوي" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "a علوي" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "a علوي" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "a علوي" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "a علوي" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "جدول" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "جدول شجرة" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "مستحيل الوصول" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "أيحرر" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "الكلام بالتصفيف و الت_نقيط" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "تفعيل ال_حدود" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "الكلام بالتصفيف و الت_نقيط" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "نسق التعلم. اضغط ESC للخروج." - -#: src/cthulhu/messages.py:1201 -#, fuzzy -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "الدخول إلى نمط التعلم. اضغط أي زر لسماع وظيفته. للخروج اضغط على ESC." - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "رسوم متحركة" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "تصفح الصفحة" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "تصفح الجدول" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "تركنا الجدول." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "مستند مختار تحت مكان المؤشّر." - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "مستند مختار فوق مكان المؤشّر" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "مستند ملغى اختياره من تحت مكان المؤشّر." - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "مستند ملغى اختياره فوق مكان المؤشّر" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "الخروج من نمط التعلم." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "خط المحدد من البداية إلى الموضع السابق للمؤشر" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "خط المحدد للنهاية من الموضع السابق للمؤشر" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "وصلة" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "نفس الصفحة" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "نفس الموقع" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "موقع مختلف" - -#: src/cthulhu/messages.py:1531 -#, fuzzy, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%s وصلة لـ %s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s وصلة" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d من الوصلات المزارة" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "كل المناطق الحية موقفة" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "استعيدت مستويات التهذيب لكل المناطق الحية" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "مستوى التهذيب %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "إعداد المنطقة الحية كمؤكدة" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "بلا إعداد للمنطقة الحية" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "إعداد المنطقة الحية كمهذبة" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "إعداد المنطقة الحية كوقحة" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "مراقبة المناطق الحية متوقفة" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "مراقبة المناطق الحية تعمل" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "لم تحفظ اي رسالة حيّة" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "دعم المنطقة الحية متوقف" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "لم يتم العثور على ملفات" - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "الموقع ال_حالي" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "موقف" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "مشتغل" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "كلمة مهجأة خاطئا:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "كلمة مهجأة خاطئا:%s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "السياق هو %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "يذهب للكائن التالي." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "محسنات الفأرة معطلة." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "محسنات الفارة مفعلة." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "لا يوجد أطفال." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d نسبة مئوية" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "إلى الكلمة السابقة." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "مستوى التفريع %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "لا يوجد تطبيق نشط" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "لا تركيز" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "لا يوجد تطبيق نشط" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "لا قطع أخرى." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "لا أزرار أخرى." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "لا مربعات إختيار أخرى." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "لا كائنات كبيرة أخرى." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "لا جداول أخرى." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "لا مربعات تحرير و سرد أخرى." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "لا مدخلات أخرى." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "لا مجالات أخرى." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "لا عناوين أخرى." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "لا عناوين أخرى عند المستوى %d." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "إطار داخلي" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "لا جداول أخرى." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "لا معالم." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "لا قوائم أخرى." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "لا قوائم أخرى." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "لا عناصر قائمة أخرى." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "لا مناطق حية أخرى." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "لا فقرات أخرى." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "لا أزرار راديو أخرى." - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "لا فقرات أخرى." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "لا جداول أخرى." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "لا روابط غير مزارة أخرى." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "لا روابط مزارة أخرى." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "غير منتقى" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "ليس في جدول." - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "اشعار %s" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "الأ_سفل" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "_فوق:" - -#: src/cthulhu/messages.py:2013 -#, fuzzy -msgid "No notification messages" -msgstr "اشعار %s" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "كلمة" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "انطق بالنتائج عند ال_بحث" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "موقف" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "مشتغل" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "يجري التحميل. الرجاء الإنتظار." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "انتهى التحميل" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "انتهى تحميل %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "صفحة مختارة من مكان المؤشّر" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "صفحة مختارة إلى مكان المؤشّر" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "صفحة ملغى اختيارها من مكان المؤشّر" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "صفحة ملغى اختيارها إلى مكان المؤشّر" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "صفحة مختارة من مكان المؤشّر" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "صفحة مختارة من مكان المؤشّر" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "صفحة ملغى اختيارها من مكان المؤشّر" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "صفحة ملغى اختيارها من مكان المؤشّر" - -#: src/cthulhu/messages.py:2127 -#, fuzzy -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"يوجد حوار تفضيلات أوركا مفتوح مسبقا.\n" -"\n" -"رجاء اغلقة قبل فتح واحد جديد." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "لم يتم العثور على ملفات" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "عمود التقدم %d." - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "ال_كل" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "مستوى التنقيط" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "لا شيء" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "البحث." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "تم البحث." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "تم إعادة تحميل إعدادات Cthulhu." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "السياق هو %s" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "إحذف" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "مؤشر الإنتقاء" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "غير منتقى" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "تعطيل الكلام." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "تفعيل الكلام." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "اسرع." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "أبطأ." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "أعلى" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "أدنى." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "اسرع." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "معدل السرعة %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "طبقة الصوت %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "مستوى الصوت %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "وحدة Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "صوت Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "لا توجد وحدات Speech-dispatcher متاحة" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "لا توجد أصوات Speech-dispatcher متاحة" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "تم حفظ إعدادات الكلام" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "تعذر حفظ إعدادات الكلام" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "نقطة نقطة نقطة" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu يرحب بك." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "كثولو يتربص تحت الأمواج." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "تم تفعيل وضع السكون لـ %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "تم تعطيل وضع السكون لـ %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "الكلام غير متوفّر" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "لم يتم العثور على ملفات" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "الجملة غير موجودة" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "غير قادر على العثور على العبارة" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "مفاتيح التصفح معطلة." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "مفاتيح التصفح مفعلة." - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "لم يتم العثور على ملفات" - -#: src/cthulhu/messages.py:2380 -#, fuzzy, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "صف %d، عمود %d" - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "%d من الجداول" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "انطق خلية" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "انطق سطر" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "غير متسق" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "ليس في جدول." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "رأس العمود" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "عمود %d" - -#: src/cthulhu/messages.py:2420 -#, fuzzy, python-format -msgid "column %(index)d of %(total)d" -msgstr "العمود %d من %d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "أسفل العمود." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "أعلى العمود." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "غير منتقى" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "غير منتقى" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "صف %d" - -#: src/cthulhu/messages.py:2462 -#, fuzzy, python-format -msgid "row %(index)d of %(total)d" -msgstr "صف %d من %d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "بداية الصف." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "نهاية الصف." - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "إحذف" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -#, fuzzy -msgid "Row inserted." -msgstr "أدرج" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "يذهب لنهاية السطر." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "إحذف" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "غير منتقى" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "منتقى" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "غير منتقى" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu الإصدار %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "فراغ" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "اللف للأسفل." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "اللف للأعلى." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 عناصر" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, fuzzy, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "خلية تشمل %d صف" -msgstr[1] "خلية تشمل %d صف" -msgstr[2] "خلية تشمل %d صف" -msgstr[3] "خلية تشمل %d صف" -msgstr[4] "خلية تشمل %d صف" -msgstr[5] "خلية تشمل %d صف" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d من الأعمدة" -msgstr[1] "%d من الأعمدة" -msgstr[2] "%d من الأعمدة" -msgstr[3] "%d من الأعمدة" -msgstr[4] "%d من الأعمدة" -msgstr[5] "%d من الأعمدة" - -#: src/cthulhu/messages.py:2593 -#, fuzzy, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "خلية تشمل %d عمود" -msgstr[1] "خلية تشمل %d عمود" -msgstr[2] "خلية تشمل %d عمود" -msgstr[3] "خلية تشمل %d عمود" -msgstr[4] "خلية تشمل %d عمود" -msgstr[5] "خلية تشمل %d عمود" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(لا حوار)%0.s" -msgstr[1] "(حوار واحد)%0.s" -msgstr[2] "(حواران)%0.s" -msgstr[3] "(%d حوارات)" -msgstr[4] "(%d حوارا)" -msgstr[5] "(%d حوارا)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d من الحوارات بلا تركيز" -msgstr[1] "%d من الحوارات بلا تركيز" -msgstr[2] "%d من الحوارات بلا تركيز" -msgstr[3] "%d من الحوارات بلا تركيز" -msgstr[4] "%d من الحوارات بلا تركيز" -msgstr[5] "%d من الحوارات بلا تركيز" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d من البايتات" -msgstr[1] "%d من البايتات" -msgstr[2] "%d من البايتات" -msgstr[3] "%d من البايتات" -msgstr[4] "%d من البايتات" -msgstr[5] "%d من البايتات" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "عثر على %d من الملفات" -msgstr[1] "عثر على %d من الملفات" -msgstr[2] "عثر على %d من الملفات" -msgstr[3] "عثر على %d من الملفات" -msgstr[4] "عثر على %d من الملفات" -msgstr[5] "عثر على %d من الملفات" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d من الاستمارات" -msgstr[1] "%d من الاستمارات" -msgstr[2] "%d من الاستمارات" -msgstr[3] "%d من الاستمارات" -msgstr[4] "%d من الاستمارات" -msgstr[5] "%d من الاستمارات" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d من الترويسات" -msgstr[1] "%d من الترويسات" -msgstr[2] "%d من الترويسات" -msgstr[3] "%d من الترويسات" -msgstr[4] "%d من الترويسات" -msgstr[5] "%d من الترويسات" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d من العناصر" -msgstr[1] "%d من العناصر" -msgstr[2] "%d من العناصر" -msgstr[3] "%d من العناصر" -msgstr[4] "%d من العناصر" -msgstr[5] "%d من العناصر" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "لا معالم." -msgstr[1] "لا معالم." -msgstr[2] "لا معالم." -msgstr[3] "لا معالم." -msgstr[4] "لا معالم." -msgstr[5] "لا معالم." - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "عثر على %d من الملفات" -msgstr[1] "عثر على %d من الملفات" -msgstr[2] "عثر على %d من الملفات" -msgstr[3] "عثر على %d من الملفات" -msgstr[4] "عثر على %d من الملفات" -msgstr[5] "عثر على %d من الملفات" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "لا قطع أخرى." -msgstr[1] "لا قطع أخرى." -msgstr[2] "لا قطع أخرى." -msgstr[3] "لا قطع أخرى." -msgstr[4] "لا قطع أخرى." -msgstr[5] "لا قطع أخرى." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "تركنا الجدول." -msgstr[1] "تركنا الجدول." -msgstr[2] "تركنا الجدول." -msgstr[3] "تركنا الجدول." -msgstr[4] "تركنا الجدول." -msgstr[5] "تركنا الجدول." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "قائمة بـ %d من العناصر" -msgstr[1] "قائمة بـ %d من العناصر" -msgstr[2] "قائمة بـ %d من العناصر" -msgstr[3] "قائمة بـ %d من العناصر" -msgstr[4] "قائمة بـ %d من العناصر" -msgstr[5] "قائمة بـ %d من العناصر" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "قائمة بـ %d من العناصر" -msgstr[1] "قائمة بـ %d من العناصر" -msgstr[2] "قائمة بـ %d من العناصر" -msgstr[3] "قائمة بـ %d من العناصر" -msgstr[4] "قائمة بـ %d من العناصر" -msgstr[5] "قائمة بـ %d من العناصر" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "جدول بـ %d من الصفوف" -msgstr[1] "جدول بـ %d من الصفوف" -msgstr[2] "جدول بـ %d من الصفوف" -msgstr[3] "جدول بـ %d من الصفوف" -msgstr[4] "جدول بـ %d من الصفوف" -msgstr[5] "جدول بـ %d من الصفوف" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d من الأعمدة" -msgstr[1] "%d من الأعمدة" -msgstr[2] "%d من الأعمدة" -msgstr[3] "%d من الأعمدة" -msgstr[4] "%d من الأعمدة" -msgstr[5] "%d من الأعمدة" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "جدول بـ %d من الصفوف" -msgstr[1] "جدول بـ %d من الصفوف" -msgstr[2] "جدول بـ %d من الصفوف" -msgstr[3] "جدول بـ %d من الصفوف" -msgstr[4] "جدول بـ %d من الصفوف" -msgstr[5] "جدول بـ %d من الصفوف" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d نسبة مئوية" -msgstr[1] "%d نسبة مئوية" -msgstr[2] "%d نسبة مئوية" -msgstr[3] "%d نسبة مئوية" -msgstr[4] "%d نسبة مئوية" -msgstr[5] "%d نسبة مئوية" - -#: src/cthulhu/messages.py:2764 -#, fuzzy, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "تمت قراءة %d من المستند" -msgstr[1] "تمت قراءة %d من المستند" -msgstr[2] "تمت قراءة %d من المستند" -msgstr[3] "تمت قراءة %d من المستند" -msgstr[4] "تمت قراءة %d من المستند" -msgstr[5] "تمت قراءة %d من المستند" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "بكسلات" -msgstr[1] "بكسلات" -msgstr[2] "بكسلات" -msgstr[3] "بكسلات" -msgstr[4] "بكسلات" -msgstr[5] "بكسلات" - -#: src/cthulhu/messages.py:2777 -#, fuzzy, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] " %d %s من المحارف" -msgstr[1] " %d %s من المحارف" -msgstr[2] " %d %s من المحارف" -msgstr[3] " %d %s من المحارف" -msgstr[4] " %d %s من المحارف" -msgstr[5] " %d %s من المحارف" - -#: src/cthulhu/messages.py:2784 -#, fuzzy, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "تم اختيار %d من العناصر من %d" -msgstr[1] "تم اختيار %d من العناصر من %d" -msgstr[2] "تم اختيار %d من العناصر من %d" -msgstr[3] "تم اختيار %d من العناصر من %d" -msgstr[4] "تم اختيار %d من العناصر من %d" -msgstr[5] "تم اختيار %d من العناصر من %d" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d من الفراغات" -msgstr[1] "%d من الفراغات" -msgstr[2] "%d من الفراغات" -msgstr[3] "%d من الفراغات" -msgstr[4] "%d من الفراغات" -msgstr[5] "%d من الفراغات" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d من علامات الجدولة" -msgstr[1] "%d من علامات الجدولة" -msgstr[2] "%d من علامات الجدولة" -msgstr[3] "%d من علامات الجدولة" -msgstr[4] "%d من علامات الجدولة" -msgstr[5] "%d من علامات الجدولة" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d من الجداول" -msgstr[1] "%d من الجداول" -msgstr[2] "%d من الجداول" -msgstr[3] "%d من الجداول" -msgstr[4] "%d من الجداول" -msgstr[5] "%d من الجداول" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "جدول بـ %d من الصفوف" -msgstr[1] "جدول بـ %d من الصفوف" -msgstr[2] "جدول بـ %d من الصفوف" -msgstr[3] "جدول بـ %d من الصفوف" -msgstr[4] "جدول بـ %d من الصفوف" -msgstr[5] "جدول بـ %d من الصفوف" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "جدول بـ %d أسطر و %d أعمدة." -msgstr[1] "جدول بـ %d أسطر و %d أعمدة." -msgstr[2] "جدول بـ %d أسطر و %d أعمدة." -msgstr[3] "جدول بـ %d أسطر و %d أعمدة." -msgstr[4] "جدول بـ %d أسطر و %d أعمدة." -msgstr[5] "جدول بـ %d أسطر و %d أعمدة." - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "جدول بـ %d من الصفوف" -msgstr[1] "جدول بـ %d من الصفوف" -msgstr[2] "جدول بـ %d من الصفوف" -msgstr[3] "جدول بـ %d من الصفوف" -msgstr[4] "جدول بـ %d من الصفوف" -msgstr[5] "جدول بـ %d من الصفوف" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "ثوان" -msgstr[1] "ثوان" -msgstr[2] "ثوان" -msgstr[3] "ثوان" -msgstr[4] "ثوان" -msgstr[5] "ثوان" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d من الوصلات غير المزارة" -msgstr[1] "%d من الوصلات غير المزارة" -msgstr[2] "%d من الوصلات غير المزارة" -msgstr[3] "%d من الوصلات غير المزارة" -msgstr[4] "%d من الوصلات غير المزارة" -msgstr[5] "%d من الوصلات غير المزارة" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d من الوصلات المزارة" -msgstr[1] "%d من الوصلات المزارة" -msgstr[2] "%d من الوصلات المزارة" -msgstr[3] "%d من الوصلات المزارة" -msgstr[4] "%d من الوصلات المزارة" -msgstr[5] "%d من الوصلات المزارة" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "تنقل" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "المستوى %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "مستوى الشجرة %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "مستوى الشجرة %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "سؤال" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "صندوق مجموعة" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "محتوى html " - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "كلمة" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "فاصلة" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "فوق السطر" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "التوجه" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "فقرة" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "كلمة" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "البادئة" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "التوجه" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "قائمة ألسنة" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "اقتباس" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "محتوى html " - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "أفقي" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "خط عامودي" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "أفقي" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "محاذاة عمودية" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "أفقي" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "محاذاة عمودية" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "تبديل الوضع" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "لوحة الإيقونات" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "محتوى html " - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "رسوم متحركة" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "محتوى html " - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "رسوم متحركة" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "البحث." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d من الوصلات المزارة" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "زر تدوير" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "مغلق" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "مفتوح" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "أفقي" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "عمودي" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "مؤكّد" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "غير مؤكّد" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "مشتغل" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "موقف" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "دُقق جزئيا" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "مضغوط" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "غير مضغوط" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "غير منتقى" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "منتقى" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "غير منتقى" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "غير منتقى" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d من الوصلات المزارة" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d من الوصلات غير المزارة" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "غير مفعل" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "قراءة فقط" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "ق.فقط" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "مطلوب" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "إنتقاء جماعي" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "غير صالح" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "غير صالح" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "تثبت من تهجيئ الكلمات" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "تثبت من تهجيئ الكلمات" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "غير صالح" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "اجد" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "رأس العمود" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "أغلق" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "اجد" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "ا_بحث عن:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "ابحث عن:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_قمة النافذة" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "قمة النافذة" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "ابدأ من:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_لف حول النص" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "ابحث بصورة ع_كسية" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "التوجه" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_طابِق الحالة" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "طابِق ك_امل الكلمة فقط" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "جد خيارات" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "افتراضي" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "حروف كبيرة" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "وصله" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "تطبيق" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "نافذة" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "خيارات أوركا" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_حاسوب محمول" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "تخطيط لوحة المفاتيح" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "ابدأ من:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "ا_عرض التلميحات" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "انطق بالكائن تحت الفأرة" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "انطق ال_كل" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "مبيّن برايل" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "تطبيق" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "انطق بتحديث عمود التقدم" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "فعل و عطل مفاتيح التصفح." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "انطق الكل _بـ:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "انطق الكل _بـ:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_عرض العنصر:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "عام" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "ش_دة الصوت :" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "د_رجة:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_معدل:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_شخص:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "اللغة" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "مؤ_لف الكلام:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "نظام ال_كلام:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "إعدادات ال_صوت:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -#, fuzzy -msgid "_Capitalization style:" -msgstr "يدور لوضع التكبير التالي." - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "إعدادات ال_صوت:" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -#, fuzzy -msgid "Speak multicase strings as wor_ds" -msgstr "انطق بالنتائج عند ال_بحث" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "إعدادات ال_صوت:" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "تفعيل ال_كلام" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "ت_فصيلي" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "الاسهاب" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "ال_كل" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "مستوى التنقيط" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "تكلم بالأسطر الفارغة" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "الكلام بالتصفيف و الت_نقيط" - -#: src/cthulhu/cthulhu-setup.ui:1850 -#, fuzzy -msgid "Spea_k object mnemonics" -msgstr "انطق بالكائن تحت الفأرة" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "انطق بالرسائل من" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "ا_نطق باحداثيات الخلية" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "ا_نطق باحداثيات الخلية" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "التوجه" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "كلام" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "تفعيل _دعم بريل" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "أ_سماء وضائف مختصرة" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "عطل رمز _نهاية السطر" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "جدول ال_تقليص:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_فعّل بريل متقلصة" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "تفعيل الصدى بال_كلمة" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "عرض خيارات أخرى" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "_لا شيء" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "مؤشر الإنتقاء" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "مؤشر الروابط" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "تفعيل ال_مكبّرة" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "إعدادات ال_صوت:" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "براي" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "تفعيل _صدى المفاتيح" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "تفعيل مفاتيح ال_تصفح" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "تفعيل المفاتيح الم_غيّرة" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "تفعيل مفاتيح الوضائف" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "تفعيل ال_كلام" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "تفعيل المفاتيح الم_غيّرة" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "تفعيل مفاتيح الوضائف" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "تفعيل المفاتيح ال_سريعة" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "تفعيل مفاتيح ال_تصفح" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "تفعيل الصدى بال_كلمة" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "تفعيل الصدى بال_جملة" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "صدى المفتاح" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "الم_فاتيح المغيّرة لأوركا:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "المفاتيح المربوطة" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "قاموس النطق" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "م_دخل جديد" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "إح_ذف" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "التلفظ" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "انطق ال_كل" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "لا تنطق بشيء" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "أعد _ضبط" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "خصائص النص" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "انقل إلى أ_سفل" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "انقل إلى أ_سفل بواحد" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "انقل إلى أ_على بواحد" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "انقل إلى أ_على" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "" -"صفف الخصائص\n" -"المختارة" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "مبيّن برايل" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "خصائص النص" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "تفعيل مساعد الذكاء الاصطناعي" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "ال_مزود:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (محلي - مجاني)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "ملف مفتاح _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "مسار ملف مفتاح API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "الحصول على مفتاح _Claude API" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "افتح المتصفح للحصول على مفتاح Claude API وحفظه تلقائيًا" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "طلب تأكيد قبل إجراءات الذكاء الاصطناعي" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_نموذج Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "اسم النموذج لـ Ollama (مثل llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "نقطة نهاية Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "عنوان URL لنقطة نهاية Ollama API (مثل http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_جودة لقطة الشاشة:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "منخفض" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "متوسط" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "عالي" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "مساعد الذكاء الاصطناعي" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "رمز الل_غة:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "معامل ال_تحجيم:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "صورة بتدرج ال_رمادي" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_عكس الصورة" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "صورة _أبيض وأسود" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_عتبة الأبيض/الأسود:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_تحليل الألوان" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "نسخ النتائج إلى ال_حافظة" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -# This really should have arabic letters I think... -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "لون الخلفية" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "العلو الكامل للخلفية" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "تنقيط الخلفية" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "التوجه" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "أيحرر" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "اسم العائلة" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "اللون الأمامي" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "تنقيط الأمامي" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "تأثيرات الخط" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "البادئة" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "غير مرئي" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "محاذاة" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "اللغة" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "الهامش اليمين" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "علو السطر" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "أسلوب الفقرة" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "بكسلات فوق السطر" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "بكسلات تحت السطر" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "بكسلات في الإلتفاف" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "الهامش اليمين" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "ارتفاع" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "المقياس" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "الحجم" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "الامتداد" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "شطب" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "أسلوب" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "زخرفة النص" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "دوران النص" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "ظل النص" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "تسطير" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "التنوع" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "محاذاة عمودية" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "الوزن" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "نمط الالتفاف" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "نمط الكتابة" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "صحيح" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "خطئ" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "بلا" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "نحت" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "منمق" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "خارج السطر" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "فوق السطر" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "مشطوب" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "يغمز" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "أسود" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "مفرد" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "مزدوج" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "منخفض" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "محرف" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "كلمة" - -#: src/cthulhu/text_attribute_names.py:452 -#, fuzzy -msgctxt "textattr" -msgid "word char" -msgstr "محرف" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "يساري" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "يميني" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "يسار" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "يمين" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "مركز" - -#: src/cthulhu/text_attribute_names.py:493 -#, fuzzy -msgctxt "textattr" -msgid "no justification" -msgstr "محاذاة" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "ملئ" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "مكثف بشدة" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "مكثف زيادة" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "مكثف" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "شبه مكثف" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "عادي" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "شبه ممطوط" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "ممطوط" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "ممطوط زيادة" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ممطوط بشدة" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "أحرف صغيرة" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "منحني" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "مائل" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "إفتراضي" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "جسم النص" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "ترويسة" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "السطر الأساس" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "فرع" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "فائق" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "قمة" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "قمة النص" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "وسط" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "أسفل" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "أسفل النص" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "وارث" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "تثبت من تهجيئ الكلمات" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "اضغط مسطرة المسافات لتغيير حالة مربع الاختيار" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"اضغط مسطرة المسافات لإظهار الخيارات واستخدم الأسهم الرأسية لتحديد أحد العناصر" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "اضغط مفتاح القوائم زائد f6 لتنشيط النوافذ الفرعية" - -#: src/cthulhu/tutorialgenerator.py:290 -#, fuzzy -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"للتحرك بين العناصر استخدم الأسهم أو اكتب الأحرف الأولى من العنصر واضغط مفتاح " -"القوائم زائد f1 لتفعيل قائمة النظام" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "استخدم الأسهم الرأسية لتحديد أحد العناصر" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "اضغط مفتاح التبديل زائد السهم الأيسر للإخفاء" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "اضغط مفتاح التبديل زائد السهم الأيمن للإظهار" - -#: src/cthulhu/tutorialgenerator.py:397 -#, fuzzy -msgid "To activate press return." -msgstr "اضغط مسطرة المسافات للتفعيل " - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "اكتب نص" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "استخدم الأسهم الأفقية لعرض الصحائف الأخرى" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "اضغط مسطرة المسافات للتفعيل " - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"استخدم الأسهم الرأسية لاختيار أحد القيم أو قم بكتابة القيمة الرقمية التي " -"تفضلها" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "استخدم الأسهم للتغيير" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "استخدم الأسهم الأفقية للتحرك والأسهم الرأسية للاختيار" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "اضغط السهم الأيمن لتفعيل القائمة الفرعية" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"اضغط السهم الأيمن لخفض الصوت والسهم الأيسر لرفعه واضغط مفتاح البداية لأدنى " -"درجة ومفتاح النهاية لأعلى درجة" diff --git a/po/ast.po b/po/ast.po deleted file mode 100644 index 2af6630..0000000 --- a/po/ast.po +++ /dev/null @@ -1,9885 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2011-09-08 13:37+0100\n" -"Last-Translator: ivarela \n" -"Language-Team: Asturian \n" -"Language: ast\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1\n" -"X-Poedit-Language: Asturian\n" -"X-Poedit-SourceCharset: utf-8\n" - -msgid "Cthulhu Screen Reader" -msgstr "Llector de pantalla d'Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "flc" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "lnz" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "dscrp" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "cv" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "sltcol" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "cabcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "fch" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ico" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "mar" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "mrcd" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "pnldir" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "dibuxu" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "sltar" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "rlln" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "tpg" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "pnltr" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "cbcra" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "mrci" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etq" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "pnlslp" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "enllaz" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "ellst" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "brmnu" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "elmnum" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "pnlo" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "slp" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblslp" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "contr" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnuem" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "brprog" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "mnuer" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "pnlr" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "Cabfl" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "brdesl" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "pnldesl" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sccn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprdr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "desl" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "pnldiv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "cuntador" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "brestbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cld" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "emd" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "btc" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "bdh" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "csj" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arb" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tblArb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "desc" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "Prt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "vnt" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "Cab" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pDP" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "ap" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "bEd" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "cEmp" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Checu grau 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Español grau 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francés de Canadá grau 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francés de Francia grau 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letón grau 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holandés de Países Baxos grau 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Noruegu grau 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Noruegu grau 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Noruegu grau 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Noruegu grau 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polacu grau 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugués grau 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Suecu grau 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Árabe grau 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galés grau 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galés grau 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemán grau 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemán grau 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemán grau 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Inglés del Reinu Xuníu grau 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Inglés del Reinu Xuníu grau 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Inglés de EE.XX. grau 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Inglés de EE.XX. grau 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francés de Canadá grau 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francés de Francia grau 2" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Griegu grau 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindú grau 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -#, fuzzy -msgid "Hungarian Grade 1" -msgstr "Letón grau 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "Alemán grau 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italianu grau 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Holandés de Bélxica grau 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espaciu" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nueva llinia" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulación" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "esclamación" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "comines" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "númberu" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dólar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "porcentaxe" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "y" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apóstrofe" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "paréntesis esquierdu" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "paréntesis derechu" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asteriscu" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "más" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "coma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "guión" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "puntu" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dos puntos" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "puntu y coma" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "menor que" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "ye igual a" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "mayor que" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "entruga" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "arroba" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "abre corchete" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "barra invertida" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "pieslla corchete" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "circunflexu" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "sorrayáu" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "abre llave" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra vertical" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "pieslla llave" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espaciu non dixebrable" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "abre esclamación" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "céntimos" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "llibres" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "señal de moneda" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra cortada" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "seición" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diéresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a superíndiz" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "abre comines angulares" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "non lóxicu" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "guión" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "rexistráu" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "sobrolliñáu" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "graos" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "más o menos" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "2 superíndiz" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "3 superíndiz" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acentu" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "marca de párrafu" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "puntu centráu" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 superíndiz" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "zarra comines angulares" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "un cuartu" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "un mediu" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tres cuartos" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "abre interrogación" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a con tilde" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A CON TILDE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUNFLEXA" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A CON TILDE PLANA" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A CON DIÉRESIS" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A CON CÍRCULU" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E CON TILDE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUNFLEXA" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E CON DIÉRESIS" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I CON TILDE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUNFLEXA" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I CON DIÉRESIS" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "Ñ" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O CON TILDE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUNFLEXA" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O CON TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O CON DIÉRESIS" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "por" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O CON BARRA DIAGONAL" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U CON TILDE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUNFLEXA" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U CON DIÉRESIS" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y CON TILDE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "ZORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "beta" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circunflexa" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a con tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a con diéresis" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a con círculu" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e con tilde" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circunflexa" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e con diéresis" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i con tilde" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circunflexa" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i con diéresis" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "ñ" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o con tilde" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circunflexa" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o con tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o con diéresis" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "dividío por" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o con barra diagonal" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "zorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u con tilde" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circunflexa" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u con diéresis" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y con tilde" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y con diéresis" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y CON DIÉRESIS" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florín" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "guión altu" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "comina simple esquierda" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "comina simple drecha" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "comina inferior simple" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "comina duble esquierda" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "comina duble drecha" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "duble comina inferior" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "cruz" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "DUBLE CRUZ" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "asteriscu" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "viñeta triangular" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "por mil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prima" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "doble prima" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "doble prima" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "guión de viñeta" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marca rexistrada" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "marca" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "marca fuerte" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "viñeta marcada con x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "0 superíndiz" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "4 superíndiz" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "5 superíndiz" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "6 superíndiz" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "7 superíndiz" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "8 superíndiz" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "9 superíndiz" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "más superíndiz" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "menos superíndiz" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "igual superíndiz" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "abre paréntesis superíndiz" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "zarra paréntesis superíndice" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n superíndiz" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "0 subíndiz" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "1 subíndiz" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "2 subíndiz" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "3 subíndiz" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "4 subíndiz" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "5 subíndiz" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "6 subíndiz" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "7 subíndiz" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "8 subíndiz" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "9 subíndiz" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "más subíndiz" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "menos subíndiz" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "igual subíndiz" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "abre paréntesis subíndiz" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "zarra paréntesis subíndiz" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "cuadru prietu" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "rombu" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "Va al siguiente caráuter." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "Posiciona'l punteru nel elementu actual." - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "Calca col botón esquierdu sobro l'elementu revisáu." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "Calca col botón drechu sobro l'elementu revisáu." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Llee tol documentu." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "Llee la llinia actual de revisión." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "Fai la operación básica ¿au toi?" - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "Fai la operación detallada ¿aú toi?" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Llee la llinia actual de revisión." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "Indicar llinies en blancu" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "Va al siguiente botón." - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "Llee la barra d'estáu." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "Llee la barra de títulu." - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Abre'l diálogu de gueta d'Cthulhu." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "Gueta la siguiente instancia d'una cadena." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "Gueta la instancia anterior d'una cadena." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "Entra y sal del mou de revisión." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "Mueve la revisión a la posición final." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "Mover revisión a la posición inicial." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "Mueve la revisión a la posición final." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "Mover revisión al aniciu de la llinia anterior." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "Llee la llinia actual de revisión." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "Delletrea la llinia actual de revisión." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "Delletrea fonéticamente la llinia actual de revisión." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "Mueve la revisión al aniciu de la siguiente llinia." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "Mueve la revisión al anterior elementu o pallabra." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "Llee l'elementu o pallabra actual de revisión." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "Delletrea l'elementu o pallabra actual de revisión." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "Delletrea fonéticamente l'elementu o pallabra actual de revisión." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "Mueve la revisión al siguiente elementu o pallabra." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "Mueve la revisión a la pallabra encima de la pallabra actual." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "Llee l'oxetu revisáu anguaño." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "Mueve la revisión a la pallabra de debaxo de la pallabra actual." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "Mueve la revisión al caráuter anterior." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "Llee'l caráuter revisáu actualmente." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "Llee fonéticamente'l caráuter actual de revisión." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "Llee'l caráuter unicode del caráuter actual de revisión." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "Mueve la revisión al caráuter siguiente." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "Mueve la revisión al final de la llinia." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "Mueve la revisión a la esquina inferior esquierda." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "Llee l'elementu o pallabra actual de revisión." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "Llee l'elementu o pallabra actual de revisión." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "Mueve la revisión a la posición final." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Camuda ente leer namái la caxella actual o tola filera." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "Llee los atributos asociaos al caráuter actual." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "Desplaza la llinia braille a la esquierda." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "Desplaza la llinia braille a la drecha." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "Vuelve al oxetu col focu de tecláu." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "Activa o desactiva el braille contrayíu." - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "Procesa una tecla d'enrutáu del cursor." - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "Conseña'l aniciu d'una seleición de testu." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "Conseña'l final d'una seleición de testu." - -# Escape es hablado -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Entra en mou de deprendizax. Calca escape pa colar del mou de deprendizax." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "Amenorga la velocidá de la voz." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "Aumenta la velocidá de la voz." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "Amenorga'l tonu de la voz." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "Aumenta'l tonu de la voz." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Aumenta la velocidá de la voz." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Amenorga la velocidá de la voz." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Escueyi'l sirvidor de voz deseáu." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Escueyi'l sirvidor de voz deseáu." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "Amenorga la velocidá de la voz." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "Aumenta la velocidá de la voz." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "Conmuta'l silenciu de la voz." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "Conmutar el mou de revisión del mur." - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Llector de pantalla d'Cthulhu" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "Amuesa'l diálogu de configuración de preferencies." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "Amuesa'l diálogu de configuración de preferencies pa l'aplicación." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "Activa o desactiva la llectura del sangráu y la xustificación." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "Rota al siguiente nivel de puntuación." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "Rota al siguiente nivel d'ecu de tecles." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "Rota al siguiente nivel de puntuación." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "Rota al siguiente nivel de puntuación." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "Rota al siguiente nivel d'ecu de tecles." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "Rota ente los niveles de depuración en tiempu d'execución." - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "Marcador ¿Au toi? con respeutu a la posición actual." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "Va al llugar del marcador anterior." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "Dir a marcador." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "Va al llugar del siguiente marcador." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "Amestar marcador." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "Guardar marcadores." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "Conmutar el mou de revisión del mur." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "Hora actual." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "Data actual." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "Unvia'l siguiente comandu a l'aplicación activa." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "Lleer y braille d'un mensaxe anterior d'una sala de charra." - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Conmutar si s'anuncia cuando los nuesos collacios tan tecleando." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Conmutar si se proporcionen hestóricos de mensaxes de cada sala de charra." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"conmutar si se prefixen los mensaxes de la sala de charra col nome de la " -"sala de charra." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Llinia esquierda" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Llinia drecha" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Llinia arriba" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Llinia abaxo" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Conxelar" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Arriba esquierda" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "Metada inferior" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posición del cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Seis puntos" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Encaminamientu de cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Entamu del corte" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Llinia de corte" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "Presentar el caberu mensaxe de notificación." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Presentar la llista de mensaxes de notificación" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "Presentar el mensaxe de notificación anterior." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "Presentar el caberu mensaxe de notificación." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Va al siguiente caráuter." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "Va al caráuter anterior." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "Va a la siguiente pallabra." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "Va a la pallabra anterior." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "Va a la siguiente llinia." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "Va a la llinia anterior." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "Va al entamu del ficheru." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "Va al final del ficheru." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Va al entamu de la llinia." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "Va al final de la llinia." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "Va al siguiente oxetu." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "Va al anterior oxetu." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "Fai que s'espanda'l cuadru combináu actual." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "Camuda ente la navegación del cursor d'Cthulhu y la nativa de Gecko." - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "Adelanta la configuración de comportamientu de la rexón activa." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "" -"Fixa'l nivel predetermináu de comportamientu de les rexones actives a " -"desactiváu." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "Revisar anunciu de rexón activa." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "Monitorizar rexones actives." - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "Mueve'l focu haza o llonxe de l'actual posición del mur." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "" -"Afita la filera qu'usar como testeres dinámiques de columnes al dicir les " -"caxelles de cálculu." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "Llimpia les testeres dinámiques de columna." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"Afita la columna qu'usar como testeres dinámiques de filera pa usar al dicir " -"les caxelles de cálculu." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "Llimpia les testeres dinámiques de filera" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Presenta'l conteníu de la llinia d'entrada." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "Activa o desactiva les tecles de navegación estructural." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "Va a la anterior cita." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "Va a la siguiente cita." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "Va al botón anterior." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "Va al siguiente botón." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Amosar más opciones" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Va a la caxella anterior." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Va a la siguiente caxella." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "Va a la tabla anterior." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "Va a la siguiente tabla." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "Va al cuadru combináu anterior." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Va al siguiente cuadru combináu." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "contenedor h t m l" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "contenedor h t m l" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "Va a la entrada anterior." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "Va a la siguiente entrada." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "Va al anterior campu de formulariu." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "Va al siguiente campu de formulariu." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "Va al encabezáu anterior." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "Va al encabezáu siguiente." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Va al encabezáu anterior de nivel %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Va al siguiente encabezáu de nivel %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Nun hai más encabezados de nivel %d." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "Va a la tabla anterior." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "marcu internu" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "Va a la llinia anterior." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "Va a la siguiente llinia." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "Va al anterior puntu de referencia." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "Va al siguiente puntu de referencia." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Va al gran oxetu anterior." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Va al siguiente gran oxetu." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Nun hai más oxetos grandes." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "Va a la llinia anterior." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "Va a la siguiente llinia." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Amosar más opciones" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "Va a la llista anterior." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "Va a la siguiente llista." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Va al anterior elementu de llista." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Va al siguiente elementu de llista." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "Va a la anterior rexón activa." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "Va a la siguiente rexón activa." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "Va a la cabera rexón activa que fizo un anunciu." - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "" -"Imprenta información de depuración tocante al ancestru del oxetu col focu." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "Vuelve al oxetu col focu de tecláu." - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "Activa o desactiva les tecles de navegación estructural." - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "Va al párrafu anterior.." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "Va al siguiente párrafu." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Va al botón de radio anterior." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "Va al siguiente botón de radio." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "Nun hai más botones de radio." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "Va al separtador anterior." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "Va al separtador siguiente." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "Va a la tabla anterior." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "Va a la siguiente tabla." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "Va una caxella abaxo." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "Va a la primer caxella d'una tabla." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "Va a la cabera caxella d'una tabla." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "Va una caxella a la esquierda." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "Va una caxella a la drecha." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "Va una caxella arriba." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "Conmutar el mou de revisión del mur." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Activar _ecu de tecles" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "Va al anterior enllaz non visitáu." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "Va al siguiente enllaz non visitáu." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "Nun hai más enllaces non visitaos." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "Va al anterior enllaz visitáu." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "Va al siguiente enllaz visitáu." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "Nun hai más enllaces visitaos." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "Saturar azul" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "prieta" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "rombu" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "Saturar azul" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "Saturar azul" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "a grave" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "Saturar verde" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "Saturar verde" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "Saturar bermeyu" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "Saturar verde" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "Saturar azul" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i grave" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "Desaturar verde" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "solombreáu" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "graos" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "Hindú grau 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "pieslla llave" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "control drechu" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "paréntesis derechu" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "pieslla llave" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "paréntesis derechu" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "paréntesis derechu" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "alt drechu" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "paréntesis derechu" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "super drecha" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "flecha drecha" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "nueva llinia" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Imaxe" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "Desaturar azul" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "Saturar bermeyu" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "Saturar verde" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "fin" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "Saturar azul" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "pantalla %s" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "Desaturar azul" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "Desaturar azul" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "tabulación" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "espaciu en blancu" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "espaciu en blancu" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "Pantalla completa" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Puntu _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Puntu _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Puntos 7 _y 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Iconu" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Dengún" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "falta ortográfica" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Anunciar cuando los _collacios tan tecleando" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Apurrir hestóricos de mensaxes específicos de cada sala de charra" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Lleer los mensaxes de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Tolos ca_nales" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Toles canales cuando c_ualquier ventana de %s tea activa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Un canal namái si la to _ventana ta activa" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Lleer el nome de la sala de charra" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "duble pulsación" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triple pulsación" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizador predetermináu" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Cadena Actual" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Cadena de troquéu" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Activar ecu por _caráuter" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Activar tecles _diacrítiques" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Posición a_ctual" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Mínima llonxitú del testu coincidente:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opciones de gueta" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Falar _namái les llinies cambiaes durante la gueta" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Lleer los resultaos durante la _gueta" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "coma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Atayu de tecláu" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "Predetermináu" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "mou d'escritura" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "seición" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Atayos Braille" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "marcadores guardaos" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "Navegación por tables" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Non asociáu" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "Colando de la revisión plana." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "Camudáu" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Escritoriu" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificación" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Notificación %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferencies d'Cthulhu pa %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Conseñar en braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Presentar sacantes que" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Falar" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Guardar perfil como conflictu" - -#: src/cthulhu/guilabels.py:429 -#, fuzzy -msgid "User Profile Conflict!" -msgstr "Conflictu col perfil d'usuariu" - -#: src/cthulhu/guilabels.py:436 -#, fuzzy, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"El perfil %s yá existe.\n" -"¿Siguir anovando'l perfil existente con estos cambeos nuevos?" - -#: src/cthulhu/guilabels.py:446 -#, fuzzy -msgid "Load user profile" -msgstr "Cargar Perfil d'Usuariu" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Tas a piques de cambiar el perfil activu. Si acabes de\n" -"facer cambeos nes tos preferencies, estos van\n" -"perdese na carga del perfil.\n" -"\n" -"¿Continuar la carga del perfil descartando los cambeos anteriores?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Guardar perfil como" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nome del _perfil:" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "Cargar Perfil d'Usuariu" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Too" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicación" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Ventana" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Denguna" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Alguna" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "La _mayoría" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Llinia" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Frase" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "comines" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Botón" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "Descripción" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Caxella" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "cuadru combináu" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "n superíndiz" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Encabezáu" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Marcu Internu" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Imaxe" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiqueta" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "marca rexistrada" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "Enllaz" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "Llista" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "Elementu de llista" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Párrafu" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Botón de radio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "escoyíu" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "Estáu" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Testu" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Nun hai más cites." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botón" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Caxella" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "cuadru combináu" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "Encabezáu" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Marcu Internu" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Imaxe" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Nun hai más encabezados de nivel %d." - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "marca rexistrada" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Nun hai más oxetos grandes." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "Enllaz" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "Llista" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "Elementu de llista" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Párrafu" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Botón de radio" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabla" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d enllaz visitáu" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d enllaz visitáu" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navegación por páxines" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Comienza a lleer automáticamente una páxina cuando ésta se _carga per primer " -"vegada" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"Comienza a lleer automáticamente una páxina cuando ésta se _carga per primer " -"vegada" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Partir la voz en trozos ente pauses" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "voz predeterminada %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Predetermináu" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiperenllaz" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Mayúscula" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "Lleer les coordenaes de les caxelles en fueyes de cálculu" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "_Anunciar la testera d'una caxella" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navegación por tables" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Saltar caxelles en _blancu" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Lleer _caxella" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Lleer les coordenaes d'una _caxella" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Lleer _caxelles dientro d'otra caxella" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nome del atributu" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "Usar la navegación de cursor d'_Cthulhu" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "Activa o desactiva les tecles de navegación estructural." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Breve" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Notificación" -msgstr[1] "Notificación" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Mayús." - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "mayúscules esquierda" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt esquierdu" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control esquierdu" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "mayúscules drecha" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt drechu" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control drechu" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta esquierdu" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta drechu" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "bloquéu numbéricu" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "bloquéu mayúscules" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "bloquéu mayúscules" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "bloquéu desplazamientu" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "retrocesu de páxina" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "avance de páxina" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab esquierdu" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "retrocesu" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "intro" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "intro" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "arriba" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "abaxo" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "esquierda" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "drecha" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super esquierda" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super drecha" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menú" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "aida" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "camudar mou" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "inxertar" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "desaniciar" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "aniciu" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "fin" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "entamar" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circunflexu" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "círculu" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "diagonal" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "menos" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "inxertar" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Bloquéu_mayúscula" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_D" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_I" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Mayús" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "negrina" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "cursiva" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr " %s subíndiz" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr " %s subíndiz" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Estaya de trabayu " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "El contestu ye %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "flecha esquierda" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "flecha" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "flecha drecha" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "flecha" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "flecha drecha" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "flecha drecha" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "flecha drecha" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "flecha esquierda" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "flecha esquierda" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "flecha drecha" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "comina duble esquierda" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "DUBLE CRUZ" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "comina duble drecha" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "DUBLE CRUZ" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "comina duble drecha" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "flecha drecha" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "flecha apuntando haza la drecha" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "menor que" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "mayor que" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "circunflexu" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "puntu" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "alliniación vertical" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horizontal" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "autocompletáu" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "baleru" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "Activáu" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "Final de la filera." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "subíndiz" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "más o menos" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "más" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "separtador" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "raíz cúbica" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "Proporcional" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "infinito" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "alt drechu" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "cenciello" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "Panel solapáu" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "alliniación vertical" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "dividío por" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Separtador" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "non igual a" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "non lóxicu" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "non lóxicu" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "direición" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "marcu internu" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "doble prima" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "Proporcional" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "ñ" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "ñ" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "casi igual a" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "casi igual a" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "casi igual a" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "casi igual a" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "casi igual a" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "casi igual a" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "triple pulsación" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "casi igual a" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "sitiu distintu" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "non igual a" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "ye igual a" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "ye igual a" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "non igual a" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "non igual a" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "viñeta triangular" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "ye igual a" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "non igual a" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "non igual a" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "vertical" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "non igual a" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "non igual a" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "mayor que" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "non primíu" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "0 subíndiz" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "a superíndiz" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "multiEscoyeta" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "xustificación" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "multiEscoyeta" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "igual subíndiz" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "guión altu" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "más subíndiz" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "menos subíndiz" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "meta drechu" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "tab esquierdu" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "abaxo" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "seición" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "braero" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "braero" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ordinal" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "imaxe" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "multi" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "marcu internu" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "normal" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "comina simple drecha" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "pieslla llave" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "separtador" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "non lóxicu" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "non lóxicu" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "doble prima" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "doble prima" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "direición" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "doble prima" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "menor que o igual a" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "alliniación vertical" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "paréntesis esquierdu" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "paréntesis derechu" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "alt esquierdu" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "alt drechu" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "abre llave" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "inferior" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "abre comines angulares" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "zarra comines angulares" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "puntu centráu" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "cuadru prietu" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "cuadru blancu" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "rombu" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "círculu en blanco" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "círculu tacháu" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "viñeta erma" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "cuadru prietu" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "sorrayáu" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "alliniación vertical" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "aplicación" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "en blancu" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "negrina" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "marcador introducíu" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "marcadores guardaos" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "los marcadores nun pueden guardase" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "Nun s'atoparon puntos de referencia." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "Nun s'atoparon puntos de referencia." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Mou unviar tecla activáu." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Nun pudo obtenese la pantalla de la calculadora" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "iconu" - -#: src/cthulhu/messages.py:117 -#, fuzzy -msgid "Capitalization style set to icon." -msgstr "Nivel de puntuación afitáu a dengún." - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "dengún" - -#: src/cthulhu/messages.py:137 -#, fuzzy -msgid "Capitalization style set to none." -msgstr "Nivel de puntuación afitáu a dengún." - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "falta ortográfica" - -#: src/cthulhu/messages.py:157 -#, fuzzy -msgid "Capitalization style set to spell." -msgstr "El nivel de puntuación afitóse a too." - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "Gecko ta remanando'l cursor." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu ta remanando'l cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Caxella %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "escoyíu" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "non escoyíu" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Prevenir l'usu de la opción" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Forciar l'usu de la opción" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -#, fuzzy -msgid "The following are not valid: " -msgstr "Los siguientes argumentos nun son válidos: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Imprenta les aplicaciones conocíes que se tan executando" - -#: src/cthulhu/messages.py:237 -#, fuzzy -msgid "Load profile" -msgstr "Cargar Perfil d'Usuariu" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "los marcadores nun pueden guardase" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Usa un direutoriu alternativo pa les preferencies del usuariu" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "Imprenta les aplicaciones conocíes que se tan executando" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "Camudar una instancia d'Cthulhu anguaño n'execución" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "Amuesa esti mensaxe d'aida" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Unviar salida de depuración a debug-AAAA-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Unviar salida de depuración a un ficheru especificáu" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Configura les preferencies del usuariu (versión namái testu)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "Configura les preferencies del usuariu (versión namái testu)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Informe de fallos a https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "acentu" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "más rápidu." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Nun anunciar cuando sus collacios tan tecleando." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anunciar cuando los tos collacios tan tecleando." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Mensax de la sala charra %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nueva llingüeta de charra %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Nun lleer el nome de la sala de charra." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "lleer el nome de la sala de charra." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Nun apurrir hestóricos de mensaxes de cada sala de charra." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Apurrir hestóricos de mensaxes específicos de cada sala de charra." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "desaniciar" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "inxertar" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "entruga" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "Final de tabla" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "Nun ta nuna tabla." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "non escoyíu" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "El botón predetermináu ye %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "El botón predetermináu ye %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "El botón predetermináu ye %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " %s subíndiz" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " %s superíndiz" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "Nun ta nuna tabla." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "tol documentu escoyíu" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "tol documentu escoyíu" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "documentu escoyíu dende la posición del cursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "documentu deseleccionáu dende la posición del cursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "documentu escoyíu fasta la posición del cursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "documentu deseleicionáu fasta la posición del cursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Testera dinámica fixada pa la filera %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Testera dinámica de columna llimpiada." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Filera de testera dinámica afitada pa la columna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Filera de testera dinámica llimpiada." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "baleru" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Nun s'alcontraron ficheros." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "Entrando na revisión plana." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Entrando na revisión plana." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Colando de la revisión plana." - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "Mueve la revisión a la pallabra encima de la pallabra actual." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "tien fórmula" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "diálogu" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "menú emerxente" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "enllaz de mapa d'imaxe" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "La tecla introducida ya ta asociada a %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tecla capturada: %s. Calca Intro pa confirmar." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "La tecla nueva ye: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Atayu de tecláu desaniciáu. Calca intro pa confirmar." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "L'atayu de tecláu desanicióse." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "introduz la tecla nueva" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tecla" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "Ecu de teclau afitáu a tecla." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Dengún" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "Ecu de pallabra afitáu a dengún." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tecla y pallabra" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "Ecu de tecláu afitáu a tecla y pallabra." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "frase" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "Ecu de pallabra afitáu a frase." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "pallabra" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "Ecu de pallabra afitáu a pallabra." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "pallabra y frase" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "Ecu de tecláu afitáu a pallabra y frase." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "círculu tacháu" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "horizontal" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "barra vertical" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "flecha drecha" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Saltando al final." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "altor de la llinia" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "y" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "supralliñáu" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "raíz cuadrada" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "raíz cúbica" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "panel raigañu" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "panel raigañu" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "panel raigañu" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "0 subíndiz" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "a superíndiz" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "0 subíndiz" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "a superíndiz" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "a superíndiz" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "a superíndiz" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "tabla" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "tabla d'árbol" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "Nun ye accesible" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Desactiváu" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Llectura del sangráu y xustificación desactivada." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Activáu" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Llectura del sangráu y xustificación activada." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Mou deprendizax. Calca escape pa colar." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "animación" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Navegación por páxines" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Navegación por tables" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "Colando de la revisión plana." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "dexando la tabla." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "llinia escoyida abaxo de la posición del cursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "llinia escoyida arriba de la posición del cursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "llinia deseleicionada abaxo de la posición del cursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "llinia deseleicionada arriba de la posición del cursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Colando del mou de deprendizax." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "llinia escoyida dende l'aniciu fasta l'anterior posición del cursor" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "llinia escoyida fasta'l final dende l'anterior posición del cursor" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "enllaz" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "mesma páxina" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "mesmu sitiu" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "sitiu distintu" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s enllaz a %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "enllaz %s" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d enllaz visitáu" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Usa Flecha arriba y Flecha abaxo pa navegar pela llista. Calca Escape pa " -"colar." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Desactiváronse toles rexones actives" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "Restauróse'l comportamientu de toles rexones actives" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nivel de comportamientu %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "fixando rexón activa a firme" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "fixando rexón activa a desactivada" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "fixando rexón activa a educada" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "fixando rexón activa a grosera" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Monitorización de rexones actives desactivada" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Monitorización de rexones actives activada" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nun s'atroxó dengún mensaxe de xera" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "El sofitu de rexones actives ta desactiváu" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nun s'atopó" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Nun pudo atopase la posición actual." - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "desactiváu" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "activáu" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "mal escrita" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Pallabra mal escrita: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "El contestu ye %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -#, fuzzy -msgid "Focus mode" -msgstr "Mou de llistes d'atayos." - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -#, fuzzy -msgid "Layout mode." -msgstr "Mou de llistes d'atayos." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Va al siguiente oxetu." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Oxetu baxo'l mur («mouse over») non alcontráu." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Meyores del mur desactivaes." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Meyores del mur activaes." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d porcientu." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "Va a la pallabra anterior." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nivel d'anidamientu %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Amestóse un nuevu elementu" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Nenguna aplicación tien el focu." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Ensin focu" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nenguna aplicación tien el focu." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Nun hai más cites." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Nun hai más botones." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Nun hai más caxelles." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Nun hai más oxetos grandes." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Nun hai más tables." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Nun hai más cuadros combinaos." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Nun hai más entraes." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Nun hai más campos de formulariu." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Nun hai más encabezaos." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Nun hai más encabezados de nivel %d." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "marcu internu" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "Nun hai más tables." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nun s'atoparon puntos de referencia." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "Nun hai más llistes." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Nun hai más llistes." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Nun hai más elementos de llista." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Nun hai más rexones actives." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Nun hai más párrafos." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Nun hai más botones de radio." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Nun hai más separtadores." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Nun hai más tables." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Nun hai más enllaces non visitaos." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Nun hai más enllaces visitaos." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "non escoyíu" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "Nun ta nuna tabla." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificación" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Fondero" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Cimero" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Nun hai mensaxes de notificación" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "pallabra" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "Falar cadenes con mayúscules y minúscules como _pallabres" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "desactiváu" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "activáu" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Cargando. Por favor, espere." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Fin de la carga." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Fin de la carga de %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "páxina escoyida dende la posición del cursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "páxina escoyida fasta la posición del cursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "páxina deseleicionada dende la posición del cursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "páxina deseleicionada fasta la posición del cursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "párrafu escoyíu debaxo de la posición del cursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "párrafu escoyíu arriba de la posición del cursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "párrafu deseleicionáu debaxo de la posición del cursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "párrafu deseleicionáu arriba de la posición del cursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Yá tienes una instancia del diálogu de preferencies d'Cthulhu abierta.\n" -"Zárrala enantes d'abrir una nueva." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapositiva %(position)d de %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "Nun s'alcontraron ficheros." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra de progresu %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Too" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "El nivel de puntuación afitóse a too." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "La mayoría" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Nivel de puntuación afitáu a la mayoría." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Dengún" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Nivel de puntuación afitáu a dengún." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Dalgún" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Nivel de puntuación afitáu en dalgún." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Guetando." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Gueta completa." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Configuración d'usuariu d'Cthulhu recargada." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "El contestu ye %s" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "Fierla desaniciada." - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Escueyi la voz deseyada:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "non escoyíu" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Voz desactivada." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Voz activada." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "más rápidu." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "más sele." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "más altu." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "más baxu." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "más rápidu." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Velocidá:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "_Volume:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Nun hai sirvidores disponibles.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Nun hai voces disponibles.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Voz activada." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "La voz nun va usase.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " puntu puntu puntu" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Preferencies d'Cthulhu" - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu ta remanando'l cursor." - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Mou unviar tecla activáu." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "La voz nun ta disponible." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Nun s'atopó" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "Frase non atopada" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "cadena non atopada" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Tecles de navegación estructural desactivaes." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Tecles de navegación estructural activaes." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nun s'atopó" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Filera %(row)d, columna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Final de tabla" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Lleer caxella" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Lleer filera" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Non-uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Nun ta nuna tabla." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "Testera de Columna" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "columna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "columna %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Final de la columna." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Aniciu de la columna." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "non escoyíu" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "non escoyíu" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "filera %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "filera %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Entamu de la filera." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Final de la filera." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Fierla desaniciada." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Cabera filera desaniciada." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Fila inxertada." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Filera inxertada al final de la tabla." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "Fierla desaniciada." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "non escoyíu" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "escoyíu" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "non escoyíu" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H hores, %M minutos y %S segundos." - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H hores y %M minutos." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Preferencies d'Cthulhu pa %s" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "espaciu en blancu" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Saltando al final." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Saltando al entamu." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elementos" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "La celda abarca %d filera" -msgstr[1] "La celda abarca %d fileres" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d columna" -msgstr[1] " %d columnes" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "La celda abarca %d columna" -msgstr[1] "La celda abarca %d columnes" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d caráuter enforma grande" -msgstr[1] "%d carauteres enforma grandes" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d diálogu)" -msgstr[1] "(%d diálogos)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d diálogu ensin focu" -msgstr[1] "%d diálogos ensin focu" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ficheru encontrado" -msgstr[1] "%d ficheros alcontraos" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulariu" -msgstr[1] "%d formularios" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d encabezáu" -msgstr[1] "%d encabezaos" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elementu" -msgstr[1] "%d elementos" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Nun s'atoparon puntos de referencia." -msgstr[1] "Nun s'atoparon puntos de referencia." - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d ficheru encontrado" -msgstr[1] "%d ficheros alcontraos" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Nun hai más cites." -msgstr[1] "Nun hai más cites." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Colando de la revisión plana." -msgstr[1] "Colando de la revisión plana." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Llista con %d elementu" -msgstr[1] "Llista con %d elementos" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Llista con %d elementu" -msgstr[1] "Llista con %d elementos" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabla con %d filera" -msgstr[1] "tabla con %d fileres" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d columna" -msgstr[1] "%d columnes" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tabla con %d filera" -msgstr[1] "tabla con %d fileres" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d mensaxe.\n" -msgstr[1] "%d mensaxes.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d porcientu." -msgstr[1] "%d porcientu." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "lleíu %d por cientu del documentu" -msgstr[1] "lleíu %d por cientu del documentu" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "píxeles" -msgstr[1] "píxeles" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d caráuter %(repeatChar)s" -msgstr[1] "%(count)d carauteres %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d de %(total)d elementu esbilláu" -msgstr[1] "%(index)d de %(total)d elementos esbillaos" - -#: src/cthulhu/messages.py:2793 -#, fuzzy, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "S'alcontró %d atayu predetermináu d'Cthulhu." -msgstr[1] "S'alcontraron %d atayos predeterminaos d'Cthulhu." - -#: src/cthulhu/messages.py:2801 -#, fuzzy, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"S'alcontró %(count)d atayu d'Cthulhu pa l'aplicación %(application)s." -msgstr[1] "" -"S'alcontraron %(count)d atayos d'Cthulhu pa l'aplicación %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espaciu" -msgstr[1] "%d espacios" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulador" -msgstr[1] "%d tabuladores" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabla" -msgstr[1] "%d tables" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabla con %d filera" -msgstr[1] "tabla con %d fileres" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabla con %d filera" -msgstr[1] "tabla con %d fileres" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabla con %d filera" -msgstr[1] "tabla con %d fileres" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d enllaz visitáu" -msgstr[1] "%d enllaces no visitaos" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d enllaz visitáu" -msgstr[1] "%d enllaces visitaos" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "conmutar" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "sobro %(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nivel d'árbol %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVEL D'ÁRBOL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "entruga" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "cuadru combináu" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "contenedor h t m l" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "pallabra" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "dos puntos" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "supralliñáu" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "direición" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "párrafu" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "pallabra" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "sangráu" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "direición" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "llista de llingüetes" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "comines" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "contenedor h t m l" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "e%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivel %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "barra vertical" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "alliniación vertical" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "alliniación vertical" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "camudar mou" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Iconu del panel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "contenedor h t m l" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Animación" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "contenedor h t m l" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Animación" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "Guetando." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d enllaz visitáu" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "botón cuntador" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "contrayíu" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "espandíu" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "conseñáu" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "non conseñáu" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "activáu" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "desactiváu" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "parcialmente conseñáu" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "primíu" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "non primíu" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "non escoyíu" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "escoyíu" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "non escoyíu" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "non esbilláu" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d enllaz visitáu" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d enllaz visitáu" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "solombreáu" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "namái llectura" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "sólolec" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "requeríu" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "multiEscoyeta" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "non válidu" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "non válidu" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "falta ortográfica" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "falta ortográfica" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "non válidu" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Guetar" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "Llector de pantalla y magnificador" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "Zarrar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "Guetar" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Guetar:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Guetar:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Parte _superior de la ventana" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Parte superior de la ventana" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Entamar en:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Saltu" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Guetar haza a_trás" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "Direición de gueta:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Concasar con mayúscules" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Concasar namái cola pallabra _entera" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Opciones de gueta" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Predetermináu" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Mayúscula" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiperenllaz" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicación" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Ventana" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferencies d'Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Portátil" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "Distribución de tecláu" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Perfil activu:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Perfil d'entamu:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Carga" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -#, fuzzy -msgid "Save _As" -msgstr "Guardar perfil como" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -#, fuzzy -msgid "Profiles" -msgstr "Perfiles" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Presentar conseyos" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Lleer el oxetu debaxo del m_ur." - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Formatu d'_hora:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formatu de d_ata:" - -#: src/cthulhu/cthulhu-setup.ui:625 -#, fuzzy -msgid "Time and Date" -msgstr "Data y hora" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "Lleer _too" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Atayos Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frecuencia (seg):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Aplicación" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "Anovamientos de barres de progresu" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "Activa o desactiva les tecles de navegación estructural." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Lleer too _por:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "Lleer too _por:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Xeneral" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Volume:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Tonu:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Velocidá:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persona:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "llingua" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "_Sintetizador de voz:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Sistema de _voz:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Tipu de voz:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "Axustes de tipu de voz" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Falar cadenes con mayúscules y minúscules como _pallabres" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "Axustes globales de voz" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Activar voz" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Estendida" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "Cantidá d'información" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Toda" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "Nivel de puntuación" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Falar namái el testu que s'amuesa" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Indicar llinies en blancu" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Indicar _sangráu y xustificación" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Lleer _les tecles d'accesu del oxetu" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Indicar la p_osición del fíu" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Lleer mensaxes de deprendizax" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "Lleer les coordenaes d'una _caxella" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "Lleer les coordenaes d'una _caxella" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "Indicar la p_osición del fíu" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -#, fuzzy -msgid "Spoken Context" -msgstr "Contestu faláu" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Activar _sofitu Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Nome de roles _abreviaos" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Desactivar el símbolu de _fin de llinia" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tabla de contraición:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Activar Braille contrayíu" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Activar _berbesu" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "Axustes de pantalla" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Denguna" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "Indicador de seleición" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "Indicador d'hiperenllaz" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "Activar _magnificador" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Activar _ecu de tecles" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Activar tecles de _navegación" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "Activar tecles _modificadores" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Activar tecles de _función" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "_Activar voz" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Activar tecles _modificadores" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Activar tecles de _función" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Activar tecles d'_aición" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Activar tecles de _navegación" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Activar ecu por _pallabres" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Activar ecu por _frases" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Ecu de tecles" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Llector de pantalla y magnificador" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Atayos de tecláu" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "Diccionariu de pronunciación" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nueva entrada" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Desaniciar" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronunciación" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Lleer _too" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Lleer _dengún" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Restablecer" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "Atributos de testu" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mover al _final" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mover unu _abaxo" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mover unu a_rriba" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mover al _aniciu" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "" -"Axustar los atributos\n" -" seleicionados" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "Indicador Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributos de testu" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "baxo" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "llingua" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "Factor d'_escala:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alfa, b : bravo, c : charli, d : delta, e : ecu, f : foxtrot, g : golf, " -"h : hotel, i : india, j : yuliet, k : kilo, l : lima, m : maik, n : " -"novémber, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : úniform, v : victor, w : whisky, x : xray, y : yanki, z : zulú" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "color de fondu" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "altor completa del fondu" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "fondu punteáu" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direición" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editable" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nome de la fonte" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "color de primer planu" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "primer planu punteáu" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efeutu de fonte" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "sangráu" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "fallu" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "xustificación" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "llingua" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "marxe esquierdu" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "altor de la llinia" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "estilu de párrafu" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "píxeles per enriba de les llinies" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "píxeles per debaxo de les llinies" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "píxeles dientro de la llinia" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "marxe drechu" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "entamu" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "escala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "tamañu" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "estirar" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "tacháu" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estilu" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decoración del testu" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotación del testu" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "testu solombreáu" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "solliñáu" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variante" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "alliniación vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "anchu" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "mou espandíu" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "mou d'escritura" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "braero" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falso" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "dengún" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "grabar" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "membrete" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "resume" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "supralliñáu" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "tacháu" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "parpaguéu" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "prieta" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "cenciello" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "duble" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "baxo" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "caráuter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "pallabra" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "separtación" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "I-->D" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "D-->I" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "esquierda" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "drecha" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centráu" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "ensin xustificación" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "completa" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensáu" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "estra condensáu" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensáu" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensáu" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi espandíu" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "espandíu" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "estra espandíu" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra espandíu" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "mayúscules pequeñes" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblicuu" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "cursiva" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Predetermináu" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Cuerpu del testu" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Encabezáu" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "en llinia" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "subíndiz" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super índiz" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "superior" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "testu-superior" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "mediu" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "inferior" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "testu-inferior" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "heriedar" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "izde-arab" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "deiz-arab" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "arab-deiz" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "arab-izde" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "abar-deiz" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "abar-izde" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "izde" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "deiz" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "arab" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "tacháu" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "falta ortográfica" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Calca espaciu pa conmutar." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Calca espaciu pa espander y usa flecha arriba y flecha abaxo pa escoyer un " -"elementu." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Calca Alt+f6 pa dar el focu a les ventanes fíes." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "Pa movese a los elementos, usa les fleches o escribe pa gueta." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Pa dir a los menús del sistema calca la tecla alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Use flecha arriba o flecha abaxo pa escoyer un elementu." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Pa contrayer calca mayúscula y flecha esquierda." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Pa espander calca mayúscula más flecha drecha." - -#: src/cthulhu/tutorialgenerator.py:397 -#, fuzzy -msgid "To activate press return." -msgstr "P'activar calca espaciu." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Escribi un testu" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Usa flecha esquierda y flecha drecha pa ver otres llingüetes." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "P'activar calca espaciu." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Usa flecha arriba o flecha abaxo pa escoyer un valor. O teclea'l valor " -"numbéricu deseyáu." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Pa camudar usa les fleches." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Pa restolar calca flecha esquierda o flecha drecha. Pa movete ente los " -"elementos calca flecha arriba o flecha abaxo." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Pa entrar nel submenú calca flecha drecha." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Pa decrementar calca flecha esquierda, pa incrementar calca flecha drecha, " -"pal mínimu calca aniciu y pal máximu calca fin." diff --git a/po/be.po b/po/be.po deleted file mode 100644 index b1fcbe8..0000000 --- a/po/be.po +++ /dev/null @@ -1,9671 +0,0 @@ -# Kasia Bondarava , 2012. -# Ihar Hrachyshka , 2013, 2014. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-09-01 01:43+0300\n" -"Last-Translator: Yuras Shumovich \n" -"Language-Team: Belarusian \n" -"Language: be\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Poedit 3.3.2\n" -"X-Project-Style: gnome\n" - -msgid "Cthulhu Screen Reader" -msgstr "Чытач з экрана Cthulhu" - -#, fuzzy -msgid "screen;reader;accessibility;speech;braille;" -msgstr "чытач з экрана;экран;голас;маўленне;Брайль;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "сігн" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "анім" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "стрл" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "кал" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "плтн" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "загал" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "перакл" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "выбкол" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "загслуп" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "выпл" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "дат" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "знач" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "рамк" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "набор" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "дыял" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "абшкат" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "маляв" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "выбфайл" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "нап" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "шрф" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "форм" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "шклабш" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "загал" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "выяв" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "унрамк" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "цэт" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "абшплас" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "спас" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "спіс" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "элспіс" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "мн" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "стужмн" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "пнктмн" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "абшпар" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "стар" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "спіскарт" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "пнль" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "прль" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "выплмн" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "стпргр" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "кнп" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "кнпвыб" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "пнктвыбмен" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "галабш" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "загрдк" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "палпракр" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "абшпракр" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "пргф" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "падзял" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "паўз" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "абшпадз" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "пракр" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "стстан" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "табл" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "клет" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "пнктадчэпмн" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "тэрм" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "ткст" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "тмблкн" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "ппрыл" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "падк" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "іер" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "іертаб" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "нев" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "прпрагл" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "акн" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "заг" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "нкал" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "абзац" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "прагр" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "аўта" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "палпраў" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "убуд" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Чэшская, узровень 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Іспанская, узровень 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Французская (Канада), узровень 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Французская, узровень 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Латышская, узровень 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Галандская (Нідэрланды), узровень 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Нарвежская, узровень 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Нарвежская, узровень 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Нарвежская, узровень 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Нарвежская, узровень 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Польская, узровень 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Партугальская, узровень 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Шведская, узровень 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Арабская, узровень 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Уэльская, узровень 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Уэльская, узровень 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Нямецкая, узровень 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Нямецкая, узровень 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Нямецкая, узровень 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Англійская (Вялікабрытанія), узровень 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Англійская (Вялікабрытанія), узровень 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Англійская (ЗША), узровень 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Англійская (ЗША), узровень 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Французская (Канада), узровень 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Французская (Францыя), узровень 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Грэцкая, узровень 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Хіндзі, узровень 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Венгерская 8, кропкі для камп'ютара" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Венгерская, узровень 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Венгерская, узровень 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Італьянская, узровень 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Галандская (Бельгія), узровень 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "прабел" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "новы радок" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "табуляцыя" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "клічнік" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "двукоссе" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "рашотка" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "долар" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "працэнт" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "і" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "апостраф" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "левая дужка" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "правая дужка" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "зорка" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "плюс" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "коска" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "злучнік" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "кропка" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "скос" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "двукроп'е" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "кропка з коскай" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "менш" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "роўна" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "больш" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "пытальнік" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "смоўжык" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "левая квадратная дужка" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "адваротная касая рыса" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "правая квадратная дужка" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "стрэшка" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "падкрэсліванне" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "адваротны націск" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "левая фігурная дужка" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "вертыкальная лінія" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "правая фігурная дужка" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "тыльда" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "непадзельны прабел" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "перакулены клічнік" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "цэнты" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "фунты" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "знак валюты" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "іена" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "разарваная вертыкальная лінія" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "параграф" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "трэма" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "аўтарскае права" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "верхні індэкс лацінскай а" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "левае вуглавое двукоссе" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "лагічнае адмаўленне" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "злучок" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "зарэгістраваная марка" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "рыска над" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "градусы" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "плюс-мінус" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "верхні індэкс 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "верхні індэкс 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "націск" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "мю" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "знак абзаца" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "кропка ў цэнтры" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "седыль" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "верхні індэкс 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "парадкавы лічэбнік" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "правае вуглавое двукоссе" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "адна чацьвёртая" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "адна другая" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "тры чацьвёртыя" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "перакулены пытальнік" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "лацінская а з націскам" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "вялікая лацінская а з адваротным націскам" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "вялікая лацінская а з націскам" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "вялікая лацінская а з дашкам" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "вялікая лацінская а з тыльдай" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "вялікая лацінская а з умляўтам" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "вялікая лацінская а з кружком" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "вялікая лацінская ае" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "вялікая лацінская цэ з седылем" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "вялікая лацінская е з адваротным націскам" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "вялікая лацінская е з націскам" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "вялікая лацінская е з дашкам" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "вялікая лацінская е з умляўтам" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "вялікая лацінская і з адваротным націскам" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "вялікая лацінская і з націскам" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "вялікая лацінская і з дашкам" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "вялікая лацінская і з умляўтам" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "вялікая англасаксонская эт" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "вялікая лацінская эн з тыльдай" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "вялікая лацінская о з адваротным націскам" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "вялікая лацінская о з націскам" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "вялікая лацінская о з дашкам" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "вялікая лацінская о з тыльдай" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "вялікая лацінская о з умляўтам" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "памножыць" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "вялікая лацінская перакрэсленая о" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "вялікая лацінская у з адваротным націскам" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "вялікая лацінская у з націскам" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "вялікая лацінская у з дашкам" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "вялікая лацінская у з умляўтам" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "вялікая лацінская ігрык з націскам" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "вялікая англасаксонская торн" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "эсцэт" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "лацінская а з адваротным націскам" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "лацінская а з дашкам" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "лацінская а з тыльдай" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "лацінская а з умляўтам" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "лацінская а з кружком" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "лацінская ае" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "лацінская цэ з седылем" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "лацінская е з адваротным націскам" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "лацінская е з націскам" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "лацінская е з дашкам" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "лацінская е з умляўтам" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "лацінская і з адваротным націскам" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "лацінская і з націскам" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "лацінская і з дашкам" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "лацінская і з умляўтам" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "англасаксонская эт" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "лацінская эн з тыльдай" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "лацінская о з адваротным націскам" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "лацінская о з націскам" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "лацінская о з дашкам" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "лацінская о з тыльдай" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "лацінская о з умляўтам" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "падзяліць на" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "лацінская о перакрэсленая" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "лацінская торн" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "лацінская у з націскам" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "лацінская у з адваротным націскам" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "лацінская у з дашкам" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "лацінская у з умляўтам" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "лацінская ігрык з націскам" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "лацінская ігрык з умляўтам" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "вялікая лацінская ігрык з умляўтам" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "флорын" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "працяжнік" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "левае адзінкавае двукоссе" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "правае адзінкавае двукоссе" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "ніжняе адзінкавае двукоссе" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "левае двукоссе" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "правае двукоссе" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "ніжняе двукоссе" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "крыж" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "падвоены крыж" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "гузік" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "трохвугольны гузік" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "праміля" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "пункт" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "падвойны пункт" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "патройны пункт" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "еўра" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "гандлёвая марка" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "птушка" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "тоўстая птушка" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "пазнака-крыжык" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "верхні індэкс 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "верхні індэкс 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "верхні індэкс 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "верхні індэкс 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "верхні індэкс 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "верхні індэкс 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "верхні індэкс 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "верхні індэкс плюс" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "верхні індэкс мінус" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "верхні індэкс роўна" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "верхні індэкс левая дужка" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "верхні індэкс правая дужка" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "верхні індэкс лацінская эн" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "ніжні індэкс 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "ніжні індэкс 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "ніжні індэкс 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "ніжні індэкс 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "ніжні індэкс 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "ніжні індэкс 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "ніжні індэкс 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "ніжні індэкс 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "ніжні індэкс 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "ніжні індэкс 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "ніжні індэкс плюс" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "ніжні індэкс мінус" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "ніжні індэкс роўна" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "ніжні індэкс левая дужка" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "ніжні індэкс правая дужка" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "чорны квадрат" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "чорны ромб" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "Перайсці да наступнага знака." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "Скіроўвае паказальнік да бягучага элемента." - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "" -"Пстрыкае левай кнопкай мышы па бягучым элеменце ў рэжыме агульнага прагляду." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "" -"Пстрыкае правай кнопкай мышы па бягучым элеменце ў рэжыме агульнага прагляду." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Прамовіць увесь дакумент." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "Не ў рэжыме агульнага прагляду." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "Паведамляе пра бягучае месцазнаходжанне." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "Падрабязна паведамляе пра бягучае месцазнаходжанне." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Агучвае бягучы радок агульнага прагляду." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "Прамаўляць пустыя радкі" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Адкрывае дыялог пошуку." - -#: src/cthulhu/cmdnames.py:118 -#, fuzzy -msgid "Show actions list" -msgstr "Перайсці да наступнага спіса" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "Шукае наступнае ўжыванне ланцужка." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "Шукае папярэдняе ўжыванне ланцужка." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "Уваходзіць і выходзіць з рэжыму агульнага прагляду." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "Пераносіць агульны прагляд у пачатковую пазіцыю." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "Пераносіць агульны прагляд у канец." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "Пераносіць агульны прагляд у пачатак папярэдняга радка." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "Агучвае бягучы радок агульнага прагляду." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "Прамаўляе бягучы радок агульнага прагляду па літарах." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "Прамаўляе бягучы радок агульнага прагляду фанетычна." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "Пераносіць агульны прагляд у пачатак наступнага радка." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "Пераносіць агульны прагляд да папярэдняга элемента ці слова." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "Агучвае бягучы элемент ці слова агульнага прагляду." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "Прамаўляе бягучы элемент ці слова агульнага прагляду па літарах." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "Прамаўляе бягучы элемент ці слова агульнага прагляду фанетычна." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "Пераносіць агульны прагляд да наступнага элемента ці слова." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "Пераносіць агульны прагляд да слова над бягучым словам." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "Агучвае бягучы аб'ект агульнага прагляду." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "Пераносіць агульны прагляд да слова пад бягучым словам." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "Пераносіць агульны прагляд да папярэдняга знака." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "Агучвае бягучы знак агульнага прагляду." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "Прамаўляе бягучы знак агульнага прагляду фанетычна." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "Агучвае Унікод-значэнне бягучага знака агульнага прагляду." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "Пераносіць агульны прагляд да наступнага знака." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "Пераносіць агульны прагляд у канец лініі." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "Пераносіць агульны прагляд у ніжні левы кут." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "Капіруе змесціва з агульнага прагляду ў буфер абмену." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "Дадае змесціва агульнага прагляду да буфера абмену." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Агучвае толькі бягучую клетку ці ўвесь радок." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "Агучвае атрыбуты бягучага знака." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "Перасоўвае знакі на маніторы Брайля ўлева." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "Перасоўвае знакі на маніторы Брайля ўправа." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "Вяртае да аб'екта з фокусам клавіятуры." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "Уключае ці выключае Брайлеўскія скароты." - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "Праца з клавішай кіравання курсорам." - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "Пазначае пачатак вылучэння тэксту." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "Пазначае канец вылучэння тэксту." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Распачаць рэжым навучання. Націсніце клавішу Escape, каб выйсці." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "Запаволіць маўленне." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "Паскорыць маўленне." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "Панізіць тэмбр маўлення." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "Павысіць тэмбр маўлення." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Паскорыць маўленне." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Запаволіць маўленне." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Шукае папярэдняе ўжыванне ланцужка." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Абярыце сервер сінтэзу маўлення." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "Запаволіць маўленне." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "Паскорыць маўленне." - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "Налады тыпу голасу" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "Пераключыць чутнасць маўлення." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "Рэжым паведамлення пра месцазнаходжанне мышы." - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Выхад з чытача з экрана" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "Паказаць дыялог канфігурацыі настроек." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "Паказаць дыялог канфігурацыі настроек праграмы." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "Пераключыць агучванне водступаў і раўнавання." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "Наступны ўзровень агучвання пунктуацыі." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "Пераходзіць да наступнага профілю настроек." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "Пераходзіць да наступнага стылю ўстаўкі вялікіх літар." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "Наступны ўзровень агучвання клавіш." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "Пераключае ўзровень адладкі падчас працы." - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "" -"Паведаміць пра бягучае месцазнаходжанне ў дачыненні да абранай закладкі." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Перайсці да размяшчэння папярэдняй закладкі" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Перайсці да закладкі" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Перайсці да размяшчэння наступнай закладкі" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Дадаць закладку" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Захаваць закладкі" - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "Рэжым паведамлення пра месцазнаходжанне мышы." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "Паведаміць бягучы час." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "Паведаміць бягучую дату." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "Перадаваць наступныя загады непасрэдна дзейнай праграме." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "Агучыць і паказаць у Брайлі папярэдняе паведамленне з чату." - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Ці паведамляць, калі вашы суразмоўцы пішуць паведамленне." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Ці весці журнал размоў для кожнага чату." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "Ці агучваць назву пакоя перад чытаннем паведамленняў чату." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Радок улева" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Радок управа" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Радок уверх" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Радок уніз" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Замацаваць" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Верхні левы кут" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Ніжні левы кут" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Пазіцыя курсора" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Шэсць кропак" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Курсорнае кіраванне" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Пачаць выразанне" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Выразаць радок" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Агучыць апошняе апавяшчэнне" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Агучыць спіс апавяшчэнняў" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Агучыць папярэдняе апавяшчэнне" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Агучыць наступнае апавяшчэнне" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Перайсці да наступнага сімвала" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Перайсці да папярэдняга сімвала" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Перайсці да наступнага слова" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Перайсці да папярэдняга слова" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Перайсці на наступны радок" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Перайсці на папярэдні радок" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Перайсці ў пачатак файла" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Перайсці ў канец файла" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Перайсці ў пачатак радка" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Перайсці ў канец радка" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Перайсці да наступнага аб'екта" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Перайсці да папярэдняга аб'екта" - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "Разгарнуць бягучую графу з выплыўным спісам." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "Переключыцца паміж убудаванай навігацыяй і навігацыяй карэткай." - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "Прасунутыя налады працы з дынамічнымі рэгіёнамі." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "Адключыць нагадванне аб дынамічных рэгіёнах." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "Паўтарыць папярэднія паведамленні пра дынамічныя рэгіёны." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "Манітор дынамічных рэгіёнаў." - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "Перайсці да аб'екта, які актывуецца пры навядзенні курсора." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "" -"Наставіць радок, які будзе выкарыстоўвацца ў якасці дынамічнага загалоўка " -"слупкоў." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "Ачышчае часовы загаловак слупка." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"Наставіць слупок, які будзе выкарыстоўвацца ў якасці дынамічнага загалоўка " -"радкоў." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "Ачышчае часовы загаловак радка." - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Паказвае змест радка ўводу." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "Пераключае клавішы структурнай навігацыі." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Перайсці да папярэдняга блока цытавання" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Перайсці да наступнага блока цытавання" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Паказаць спіс блокаў цытавання" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Перайсці да папярэдняй кнопкі" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Перайсці да наступнай кнопкі" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Паказвае спіс кнопак." - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Перайсці да папярэдняга пераключальніка." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Перайсці да наступнага пераключальніка." - -#: src/cthulhu/cmdnames.py:870 -#, fuzzy -msgid "Display a list of check boxes" -msgstr "Паказвае спіс пераключальнікаў." - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "Перайсці да папярэдняй табліцы." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "Перайсці да наступнай табліцы." - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "Паказвае спіс табліц." - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "Перайсці да папярэдняй графы з выплыўным спісам." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Перайсці да наступнай графы з выплыўным спісам." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "Перайсці да канца радка." - -#: src/cthulhu/cmdnames.py:901 -#, fuzzy -msgid "Display a list of combo boxes" -msgstr "Паказвае спіс граф з выплыўнымі спісамі." - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "Перайсці да папярэдняга запісу." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "Перайсці да наступнага запісу." - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "Паказвае спіс элементаў." - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "Перайсці да папярэдняй графы формы." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "Перайсці да наступнай графы формы." - -#: src/cthulhu/cmdnames.py:919 -#, fuzzy -msgid "Display a list of form fields" -msgstr "Паказвае спіс граф формы." - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Перайсці да папярэдняга загалоўка" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Перайсці да наступнага загалоўка" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Паказаць спіс загалоўкаў" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Перайсці да папярэдняга загалоўка узроўню %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Перайсці да наступнага загалоўка узроўню %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Паказаць спіс загалоўкаў узроўню %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Перайсці да папярэдняй выявы" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Перайсці да наступнай выявы" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Паказаць спіс выяў" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "Перайсці да папярэдняга арыенціра." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "Перайсці да наступнага арыенціра." - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "Паказвае спіс арыенціраў." - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Перайсці да папярэдняга вялікага аб'екта." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Перайсці да наступнага вялікага аб'екта." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Паказвае спіс вялікіх аб'ектаў." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Перайсці да папярэдняй спасылкі" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Перайсці да наступнай спасылкі" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Паказаць спіс спасылак" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Перайсці да папярэдняга спіса" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Перайсці да наступнага спіса" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Паказаць спіс спісаў" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Перайсці да папярэдняга спіса элементаў." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Перайсці да наступнага спіса элементаў." - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "Паказвае спіс элементаў спіса." - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "Перайсці да папярэдняга дынамічнага рэгіёна." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "Перайсці да наступнага дынамічнага рэгіёна." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "" -"Перайсці да апошняга дынамічнага рэгіёна, ад якога атрымана паведамленне." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "Перайсці да папярэдняга абзаца." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "Перайсці да наступнага абзаца." - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "Паказвае спіс абзацаў." - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Перайсці да папярэдняй кнопкі выбару." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "Перайсці да наступнай кнопкі выбару." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "Паказвае спіс кнопак выбару." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "Перайсці да папярэдняга падзяляльніка." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "Перайсці да наступнага падзяляльніка." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "Перайсці да папярэдняй табліцы." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "Перайсці да наступнай табліцы." - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "Паказвае спіс табліц." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Перайсці на адну клетку ўніз" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Перайсці да першай клеткі ў табліцы" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Перайсці да апошняй клеткі ў табліцы" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Перайсці на адну клетку ўлева" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Перайсці на адну клетку ўправа" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Перайсці на адну клетку ўверх" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "Рэжым паведамлення пра месцазнаходжанне мышы." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Уключыць агучванне _клавіш" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "Перайсці да папярэдняй ненаведанай спасылкі." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "Перайсці да наступнай ненаведанай спасылкі." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "Паказвае спіс ненаведаных спасылак." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "Перайсці да папярэдняй наведанай спасылкі." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "Перайсці да наступнай наведанай спасылкі." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "Паказвае спіс наведаных спасылак." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "чорны" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "сіні" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "сіне-фіялетавы" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "карычневы" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "шартрэз" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "шакалад" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "карал" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "малінавы" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "цыянавы" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "цёмна-сіні" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "цёмна-цыянавы" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "цёмна-шэры" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "цёмна-зялёны" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "цёмна-аранжавы" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "цёмная архідэя" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "цёмна-чырвоны" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "цёмны ласось" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "цёмна-фіялетавы" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "насычаны ружовы" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "насычаны нябесна-блакітны" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "фуксія" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "залаты" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "шэры" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "зялёны" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "зялёна-жоўты" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "цёплы ружовы" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "індыйскі чырвоны" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "індыга" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "слановая косць" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "хакі" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "лаванда" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "ружаватая лаванда" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "лімонны шыфон" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "светла-сіні" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "светлы карал" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "светла-цыянавы" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "светла-шэры" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "светла-зялёны" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "светла-ружовы" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "светлы ласось" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "светлы нябесна-блакітны" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "светла-жоўты" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "лайм" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "лаймавы зялёны" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "лён" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "маджэнта" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "бураковы" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "аліўкавы" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "аранжавы" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "аранжава-чырвоны" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "архідэя" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "бледна-зялёны" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "ружовы" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "пурпурны" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "чырвоны" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "ласось" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "градусы" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "нябесна-блакітны" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "снег" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "бірузовы" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "чартапалох" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "тамат" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "фіялетавы" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "белы" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "дымчаты белы" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "жоўты" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "жоўта-зялёны" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Задзейнічаць" - -#: src/cthulhu/guilabels.py:63 -#, fuzzy -msgid "Automatic focus mode during structural navigation" -msgstr "_Уключыць структурную навігацыю" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Кропка _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Кропка _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "_Кропкі 7 і 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Скасаваць" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Пераскочыць" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Добра" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Значок" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Нічога" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "з палітарным вымаўленнем" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Паведамляць, калі ваш _суразмоўца піша паведамленне" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Весці журнал _размоў для кожнага чату" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Агучваць паведамленні для" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Усіх кан_алаў" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Усіх каналаў, калі актыўна лю_бое акно %s" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Канала, _акно якога актыўна" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Агучваць назву чату" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "падвойнае націсканне" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "патройнае націсканне" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Прадвызначаны сінтэзатар" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Дзейны радок" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Радок для замены" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Уключыць агучванне па знаках" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Уключыць клавішы д_ыякрытычных знакаў" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Б_ягучае месцазнаходжанне" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Мінімальная даўжыня адпаведнага тэксту:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Параметры пошуку" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Падчас пошуку агучваць толь_кі змененыя радкі" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Агучваць вынікі падчас _пошуку" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Каманда" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Прывязка клавішы" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Прадвызначаныя" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Дзеянні" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Прывязкі Брайля" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Закладкі" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Дата і час" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Вольныя" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Мадыфікавана" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "Персанальны _камп'ютар" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Налады чытання з экрана для %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Пазначаць у Брайле" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Актыўны апрача" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Прачытаць" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Захаваць профіль як канфліктны" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Канфлікт профілю карыстальніка!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Профіль %s ужо існуе.\n" -"Працягнуць абнаўленне наяўнага профілю гэтымі новымі зменамі?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Загрузіць профіль карыстальніка" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Вы збіраецеся змяніць дзейны профіль. Калі вы\n" -"толькі змянілі налады, яны будуць адкінуты\n" -"пры загрузцы профілю.\n" -"\n" -"Працягнуць загрузку профілю, адкінуўшы папярэднія змены?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Захаваць профіль як" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Назва профілю:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Выдаліць профіль карыстальніка" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Усе" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Праграма" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Акно" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Няма" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Некаторыя" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Большасць" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Радок" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Сказ" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Блок цытавання" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Кнопка" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Падказка" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Пераключальнік" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Графа з выплыўным спісам" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Апісанне" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Загаловак" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Выява" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Надпіс" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Арыенцір" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Узровень" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Спасылка" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Спіс" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Элемент спіса" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Аб'ект" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Абзац" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Кнопка выбару" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Роля" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Вылучаны элемент" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Стан" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Тэкст" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI-адрас" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Значэнне" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Блокі цытавання" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Кнопкі" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Пераключальнікі" - -#: src/cthulhu/guilabels.py:706 -#, fuzzy -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Табліцы" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Графы з выплыўнымі спісамі" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Элементы" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Графы формы" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Загалоўкі" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Загалоўкі %d узроўню" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Арыенціры" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Вялікія аб'екты" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Спасылкі" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Спісы" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Элементы спіса" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Абзацы" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Кнопкі выбару" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Табліцы" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Ненаведаныя спасылкі" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Наведаныя спасылкі" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Навігацыя па старонцы" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Аўтаматычна пачынаць агучваць старонку, калі яна _загружаецца першы раз" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"Аўтаматычна пачынаць агучваць старонку, калі яна _загружаецца першы раз" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Падзяляць тэкст на фр_азы паміж паўзамі" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s прадвызначаны голас" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Прадвызначаны" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Сеціўная спасылка" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Сістэма" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Вялікія літары" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Дыспетчар маўлення" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Праверка правапісу" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Агучваць памылкі _правапісу" - -#: src/cthulhu/guilabels.py:869 -#, fuzzy -msgid "Spell _suggestion" -msgstr "Пр_авапісная прапанова" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Паказваць _кантэкст памылкі" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "Агучваць каардынаты клетак табліцы" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Агучваць _загаловак клеткі" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Навігацыя па табліцы" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Прапускаць _пустыя клеткі" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Прачытаць _клетку" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Агучваць каардынаты _клетак" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Агучваць даўжыню _вялікіх клетак" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Назва атрыбута" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Настройка навігацыі карэткай" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "_Уключыць структурную навігацыю" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Сцісла" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d апавяшчэнне" -msgstr[1] "%d апавяшчэнні" -msgstr[2] "%d апавяшчэнняў" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "левы shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "левы alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "левы control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "правы shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "правы alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "правы control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "левы meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "правы meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "левы tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "уверх" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "уніз" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "улева" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "управа" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "левы super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "правы super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "меню" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "даведка" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "мульты" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "пераключальнік рэжыму" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "дашак" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "кружок" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "перакрэсліванне" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "мінус" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "_Правы Alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "_Левы Alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "паўтлусты %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "курсіўны" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr " ніжні індэкс %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr " ніжні індэкс %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Прастора працы " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "Кантэкст %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "стрэлка ўлева" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "стрэлка ўлева" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "стрэлка ўправа" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "стрэлка ўлева" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "стрэлка ўправа" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "стрэлка ўправа" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "стрэлка ўправа" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "стрэлка ўлева" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "стрэлка ўлева" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "стрэлка ўправа" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "левае двукоссе" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "падвоены крыж" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "правае двукоссе" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "падвоены крыж" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "правае двукоссе" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "стрэлка ўправа" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "стрэлка ўправа" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "мінус" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "менш" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "больш" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "дашак" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "кропка" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "вертыкальнае выраўноўванне" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "гарызантальна" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "пусты" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "Уключана" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "Канец радка." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "ніжні індэкс" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "плюс-мінус" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "плюс" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "мінус" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "квадратны корань" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "кубічны корань" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "квадратны корань" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "бясконцасць" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "правы alt" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "вугал" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "вертыкальнае выраўноўванне" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "падзяліць на" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "не роўна" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "лагічнае адмаўленне" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "лагічнае адмаўленне" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "напрамак" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "падвойны пункт" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "мінус" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "тыльда" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "лацінская эн з тыльдай" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "лацінская эн з тыльдай" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "прыкладна роўна" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "прыкладна роўна" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "прыкладна роўна" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "прыкладна роўна" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "прыкладна роўна" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "прыкладна роўна" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "патройная пстрычка" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "прыкладна роўна" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "іншая пляцоўка" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "не роўна" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "роўна" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "роўна" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "не роўна" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "не роўна" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "трохвугольны гузік" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "роўна" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "не роўна" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "не роўна" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "вертыкальна" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "не роўна" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "не роўна" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "больш" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "не націснута" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "ніжні індэкс 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "верхні індэкс лацінскай а" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "шматразовае вылучэнне" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "раўнаванне" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "шматразовае вылучэнне" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "квадратны корань" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "квадратны корань" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "квадратны корань" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "квадратны корань" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "ніжні індэкс роўна" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "працяжнік" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "ніжні індэкс плюс" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "ніжні індэкс мінус" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "квадратны корань" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "квадратны корань" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "правы meta" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "левы tab" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "уніз" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "параграф" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "праўда" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "праўда" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "парадкавы лічэбнік" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "мульці" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "звычайны" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "правае адзінкавае двукоссе" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "правая фігурная дужка" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "лагічнае адмаўленне" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "лагічнае адмаўленне" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "падвойны пункт" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "падвойны пункт" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "напрамак" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "падвойны пункт" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "менш ці роўна" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "больш ці роўна" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "вертыкальнае выраўноўванне" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "левая дужка" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "правая дужка" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "левы alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "правы alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "левая фігурная дужка" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "ніз" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "левае вуглавое двукоссе" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "правае вуглавое двукоссе" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "кропка ў цэнтры" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "Кірунак пошуку:" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "квадратны корань" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "чорны квадрат" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "белы квадрат" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "чорны ромб" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "белы ромб" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "чорны круг" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "белы кружок" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "чорны квадрат" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "падкрэсліванне" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "вертыкальнае выраўноўванне" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "праграма" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "пусты" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "паўтлусты" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "закладка ўведзена" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "закладкі захаваны" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "не ўдалося захаваць закладкі" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Закладак не знойдзена." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Закладка не знойдзена." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Рэжым прамой перадачы загадаў уключаны." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Не ўдалося знайсці дысплей калькулятара" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "з мецінамі" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Стыль устаўкі вялікіх літар - з мецінамі." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "без нічога" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Стыль устаўкі вялікіх літар - без нічога." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "з палітарным вымаўленнем" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Стыль устаўкі вялікіх літар - з палітарным вымаўленнем." - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "Карэткай кіруе Gecko." - -#: src/cthulhu/messages.py:170 -#, fuzzy -msgid "Cthulhu is controlling the caret." -msgstr "Карэткай кіруе Gecko." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Клетка %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s вылучана" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "знята вылучэнне з %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Забараніць выкарыстанне функцыі" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Прымусіць ужыць функцыю" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "ОПЦЫЯ" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Неабавязковыя аргументы" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Выкарыстанне: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Наступныя аргументы і опцыі хібныя: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Паказаць спіс вядомых дзейных праграм" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Загрузіць профіль" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Не ўдалося загрузіць профіль: %s" - -#: src/cthulhu/messages.py:249 -#, fuzzy -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Не ўдалося запусціць чытач з экрана, бо ён не здолеў злучыцца з працоўным " -"асяроддзем." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Не ўдалося актываваць кіраўнік настроек. Выхад." - -#: src/cthulhu/messages.py:259 -#, fuzzy -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"У гэтым сеансе ўжо запучшчаны іншы працэс для чытання з экрана.\n" -"Выканайце \"cthulhu --replace\", каб замяніць гэты працэс новым." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "НАЗВА" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Ужыць іншы каталог для налад карыстальніка" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "КАТАЛОГ" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Версія гэтай праграмы" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "Замяніць бягучую копію чытача з экрана" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Пасылаць адладачны вывад у debug-ГГГГ-ММ-ДД-ГГ:ХХ:СС.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Пасылаць адладачны вывад у вызначаны файл" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ФАЙЛ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Наставіць налады карыстальніка (тэкставая версія)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "Наставіць налады карыстальніка (тэкставая версія)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" -"Паведамляйце аб хібах у праграме на адрас: https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Вылучанае выразана ў буфер абмену." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "выразана" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Вылучанае скапіявана ў буфер абмену." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "скапиявана" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Змесціва ўстаўлена з буфера абмену." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "устаўлена" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Не паведамляць, калі ваш суразмоўца піша паведамленне." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "паведамляць, калі ваш суразмоўца піша паведамленне." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Паведамленне з чату %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Новая ўкладка чату %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Не агучваць назву чату." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "агучваць назву чату." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Не весці журнал размоў для кожнага чату." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Весці журнал размоў для кожнага чату." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "пачатак выдалення" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "канец выдалення" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "пачатак устаўкі" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "канец устаўкі" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "Канец табліцы" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "Няма ў табліцы." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "не абрана" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Прадвызначаная кнопка %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " ніжні індэкс %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " верхні індэкс %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "вылучаны ўвесь дакумент" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "вылучэне знята ва ўсім дакуменце" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "дакумент вылучаны ад пазіцыі курсора" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "вылучэне дакумента знята ад пазіцыі курсора" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "дакумент вылучаны да пазіцыі курсора" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "вылучэне дакумента знята да пазіцыі курсора" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Настаўлены часовы загаловак слупка для радка %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Часовы загаловак слупка ачышчаны." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Настаўлены часовы загаловак радка для слупка %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Часовы загаловак радка ачышчаны." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "пусты" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f кілабайтаў" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f мегабайтаў" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Файлы не знойдзены." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Змесціва дададзена да буфера абмену." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Змесціва скапіявана ў буфер абмену." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Не ў рэжыме агульнага прагляду." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Уваход у рэжым агульнага прагляду." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Выхад з рэжыму агульнага прагляду." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "утрымлівае формулу" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "Адкрывае дыялог пошуку." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "спасылка карты выявы" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Уведзеная клавіша ўжо выкарыстоўваецца для %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Націснута клавіша: %s. Націсніце Enter, каб пацвердзіць." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Новая клавіша: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Прывязка клавішы выдалена. Націсніце Enter, каб пацвердзіць." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Прывязка да клавішы выдалена." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "увядзіце новую клавішу" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "клавіша" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "Уключана агучванне клавіш." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Нічога" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "Агучванне клавіш выключана." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "клавіша і слова" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "Уключана агучванне клавіш і слоў." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "сказ" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "Уключана агучванне сказаў." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "слова" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "Уключана агучванне слоў." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "слова і сказ" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "Уключана агучванне слоў і сказаў." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "белы круг" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "гарызантальна" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "вертыкальная лінія" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "стрэлка ўправа" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Пераход у канец." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "вышыня радка" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "і" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "верхняе падкрэсліванне" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "квадратны корань з" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "кубічны корань" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "ніжні індэкс" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "верхні індэкс" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "ніжні індэкс 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "верхні індэкс лацінскай а" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "верхні індэкс лацінскай а" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "верхні індэкс лацінскай а" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "Уключана" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "недаступны" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Выключана" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Агучванне водступаў і выраўноўвання выключана." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Уключана" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Агучванне водступаў і выраўноўвання ўключана." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Рэжым навучання. Націсніце Escape, каб выйсці." - -#: src/cthulhu/messages.py:1201 -#, fuzzy -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Уключаны рэжым навучання. Націсніце любую клавішу, каб пачуць яе " -"прызначэнне. Каб праглядзець дакументацыю да чытача з экрана, націсніце F1. " -"Каб атрымаць спіс яго прадвызначаных клавіятурных скаротаў, націсніце F2. " -"Каб атрымаць спіс клавіятурных скаротаў для бягучай праграмы, націсніце F3. " -"Каб выйсці з рэжыму навучання, націсніце Escape." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "выхад з блока цытавання." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "выхад з падрабязнасцей." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "выхад са стужкі." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "выхад з формы." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "Навігацыя па табліцы" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Навігацыя па старонцы" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "выхад са спісу." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "выхад з панэлі." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "выхад з падказкі." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Навігацыя па табліцы" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "Выхад з рэжыму агульнага прагляду." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "Пр_авапісная прапанова" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "выхад з табліцы." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "вылучаны радок уніз ад пазіцыі курсора" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "вылучаны радок уверх ад пазіцыі курсора" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "нявылучаны радок уніз ад пазіцыі курсора" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "нявылучаны радок уверх ад пазіцыі курсора" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Выхад з рэжыму навучання." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "вылучаны радок ад пачатку да папярэдняй пазіцыі курсора" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "вылучаны радок ад папярэдняй пазіцыі курсора да канца" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "спасылка" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "гэтая ж старонка" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "гэты ж сайт" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "іншы сайт" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s спасылаецца на %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s спасылка" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "наведаная спасылка %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Для перамяшчэння па спісе выкарыстоўвайце стрэлкі ўверх і ўніз. Каб выйсці, " -"націсніце Escape." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Усе дынамічныя рэгіёны выключаны" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "узроўні ветлівасці дынамічных рэгіёнаў былі адноўлены" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "узровень ветлівасці %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "настройка ветлівага рэжыму дынамічнага рэгіёна: упарты" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "настройка ветлівага рэжыму дынамічнага рэгіёна: выключаны" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "настройка ветлівага рэжыму дынамічнага рэгіёна: ветлівы" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "настройка ветлівага рэжыму дынамічнага рэгіёна: грубы" - -#: src/cthulhu/messages.py:1624 -#, fuzzy -msgid "Live regions monitoring off" -msgstr "Манітор дынамічных рэгіёнаў выключаны." - -#: src/cthulhu/messages.py:1635 -#, fuzzy -msgid "Live regions monitoring on" -msgstr "Манітор дынамічных рэгіёнаў уключаны." - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "не захавана ніводнага дынамічнага паведамлення" - -#: src/cthulhu/messages.py:1649 -#, fuzzy -msgid "Live region support is off" -msgstr "Абслугоўванне дынамічнага рэгіёна выключана." - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Не знойдзена" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Не ўдалося знайсці бягучае месцазнаходжанне." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "выкл" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "укл" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "няправільна напісана" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Няправільна напісанае слова: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Кантэкст %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Рэжым агляду" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Рэжым фокусу" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Рэжым макета." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Рэжым аб'екта." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Аб'ект, які актывуецца пры навядзенні курсора, не знойдзены." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Агучванне " - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Маўленне ўключана." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Памылка: не ўдалося стварыць спіс аб'ектаў." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Узровень укладання %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Быў дададзены новы элемент" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Няма фокуса" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Няма праграм з фокусам." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Больш няма блокаў цытавання." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Больш няма кнопак." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Больш няма пераключальнікаў." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Больш няма вялікіх аб'ектаў." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Больш няма табліц." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Больш няма графаў з выплыўным спісам." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Больш няма запісаў." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Больш няма графаў формы." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Больш няма загалоўкаў." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Больш няма загалоўкаў %d узроўню." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Больш няма выяў." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Больш няма арыенціраў." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Больш няма спасылак." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Больш няма спісаў." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Больш няма спісаў элементаў." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Больш няма актыўных рэгіёнаў." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Больш няма абзацаў." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Больш няма кнопак выбару." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Больш няма падзяляльнікаў." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Больш няма табліц." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Больш няма ненаведаных спасылак." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Больш няма наведаных спасылак." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Няма вылучанага тэксту." - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "Больш няма спасылак." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Паведамленне" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Ніз" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Верх" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Няма нагадванняў" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Прамаўляць лікі як лічбы." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "слоў" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Прамаўляць лікі цалкам як словы." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "выключана" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "уключана" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Загрузка. Пачакайце." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Загрузка скончана." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Загрузка %s скончана." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Старонка мае %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "вылучаная старонка ад пазіцыі курсора" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "вылучаная старонка да пазіцыі курсора" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "нявылучаная старонка ад пазіцыі курсора" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "нявылучаная старонка да пазіцыі курсора" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "вылучаны абзац уніз ад пазіцыі курсора" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "вылучаны абзац уверх ад пазіцыі курсора" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "нявылучаны абзац уніз ад пазіцыі курсора" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "нявылучаны абзац уверх ад пазіцыі курсора" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Адно акно настроек Cthulhu ужо было адкрыта.\n" -"Закрыйце яго перад тым, як адкрываць новае." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "слайд %(position)d з %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Выбраны профіль %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Профілі не знойдзены." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Стужка прагрэсу %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Усё" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Узровень пунктуацыі - усё." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Большасць" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Узровень пунктуацыі - большасць." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Нічога" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Узровень пунктуацыі - нічога." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Часткова" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Узровень пунктуацыі - часткова." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Пошук." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Пошук закончаны." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Налады чытання з экрана перачытаныя." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Вылучаны тэкст: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Вылучэнне выдалена." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Вылучэнне адноўлена." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "З тэксту знята вылучэнне." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Памер: %d, %d. Размяшчэнне: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Шырыня: %d. Вышыня: %d. %d злева. %d зверху." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Маўленне выключана." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Маўленне ўключана." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "хутчэй." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "павольней." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "вышэй." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "ніжэй." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "грамчэй." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "цішэй." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Тэмп:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Гу_чнасць:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Дыспетчар маўлення" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Дыспетчар маўлення" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Няма даступных сервераў.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Няма даступных галасоў.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Маўленне ўключана." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "Маўленне не будзе выкарыстоўвацца.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " трохкроп'е" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Рэжым прамой перадачы загадаў уключаны." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Маўленне недаступна." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Не знойдзена" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Радок стану не знойдзены" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "ланцужок не знойдзены" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Клавішы структурнай навігацыі выключаны." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Клавішы структурнай навігацыі ўключаны." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Не знойдзена" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Радок %(row)d, слупок %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Канец табліцы" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Прачытаць клетку" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Прачытаць радок" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Не аднолькавыя" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Няма ў табліцы." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Слупкі пераўпарадкаваныя" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Радкі пераўпарадкаваныя" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "слупок %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "слупок %(index)d з %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Ніз слупка." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Верх слупка." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Слупок %s выбраны" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Вылучаны слупкі з %s па %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Знята вылучэнне са слупкоў з %s па %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Са слупка %s знята вылучэнне" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "радок %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "радок %(index)d з %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Пачатак радка." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Канец радка." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Радок выдалены." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Апошні радок выдалены." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Радок устаўлены." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Радок устаўлены ў канец табліцы." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Радок %s выбраны" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Вылучаны радкі з %s па %s" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Знята вылучэнне з радкоў з %s па %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "З радка %s знята вылучэнне" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "вылучаны" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "нявылучаны" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H гадзін, %M хвілін і %S секунд" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H гадзін і %M хвілін" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Унікод %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "адрабіць" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "паўтарыць" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "прагал" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Пераход у канец." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Пераход у пачатак." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 элементаў" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Клетка займае %d радок" -msgstr[1] "Клетка займае %d радкі" -msgstr[2] "Клетка займае %d радкоў" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d слупок" -msgstr[1] " %d слупкі" -msgstr[2] " %d слупкоў" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Клетка займае %d слупок" -msgstr[1] "Клетка займае %d слупкі" -msgstr[2] "Клетка займае %d слупкоў" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "занадта доўга, на %d знак" -msgstr[1] "занадта доўга, на %d знакі" -msgstr[2] "занадта доўга, на %d знакаў" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d дыялог)" -msgstr[1] "(%d дыялогі)" -msgstr[2] "(%d дыялогаў)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d неактыўны дыялог" -msgstr[1] "%d неактыўныя дыялогі" -msgstr[2] "%d неактыўных дыялогаў" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d байт" -msgstr[1] "%d байты" -msgstr[2] "%d байтаў" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "знойдзены %d файл" -msgstr[1] "знойдзена %d файлы" -msgstr[2] "знойдзена %d файлаў" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d форма" -msgstr[1] "%d формы" -msgstr[2] "%d формаў" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d загаловак" -msgstr[1] "%d загалоўкі" -msgstr[2] "%d загалоўкаў" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d элемент" -msgstr[1] "%d элементы" -msgstr[2] "%d элементаў" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d арыенцір" -msgstr[1] "%d арыенціры" -msgstr[2] "%d арыенціраў" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "знойдзены %d элемент" -msgstr[1] "знойдзена %d элементы" -msgstr[2] "знойдзена %d элементаў" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Выхад з %d блока цытавання." -msgstr[1] "Выхад з %d блокаў цытавання." -msgstr[2] "Выхад з %d блокаў цытавання." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Выхад з %d спіса." -msgstr[1] "Выхад з %d спісаў." -msgstr[2] "Выхад з %d спісаў." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Спіс з невядомым памерам" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Спіс з %d элементам" -msgstr[1] "Спіс з %d элементамі" -msgstr[2] "Спіс з %d элементамі" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Стужка з невядомым памерам" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Стужка з %d артыкулам" -msgstr[1] "Стужка з %d артыкуламі" -msgstr[2] "Стужка з %d артыкуламі" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Спіс апісання з %d элементам" -msgstr[1] "Спіс апісання з %d элементамі" -msgstr[2] "Спіс апісання з %d элементамі" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d значэнне" -msgstr[1] "%d значэнні" -msgstr[2] "%d значэнняў" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "матэматычная табліца з %d радком" -msgstr[1] "матэматычная табліца з %d радкамі" -msgstr[2] "матэматычная табліца з %d радкамі" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d слупок" -msgstr[1] "%d слупкі" -msgstr[2] "%d слупкоў" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "уложаная матэматычная табліца з %d радком" -msgstr[1] "уложаная матэматычная табліца з %d радкамі" -msgstr[2] "уложаная матэматычная табліца з %d радкамі" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d паведамленне.\n" -msgstr[1] "%d паведамленні.\n" -msgstr[2] "%d паведамленняў.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d працэнт." -msgstr[1] "%d працэнты." -msgstr[2] "%d працэнтаў." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "Прачытаны %d працэнт дакумента" -msgstr[1] "Прачытана %d працэнты дакумента" -msgstr[2] "Прачытана %d працэнтаў дакумента" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d піксель" -msgstr[1] "%d пікселі" -msgstr[2] "%d пікселяў" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d знак %(repeatChar)s" -msgstr[1] "%(count)d знакі %(repeatChar)s" -msgstr[2] "%(count)d знакаў %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "Вылучана %(index)d з %(total)d элемента" -msgstr[1] "Вылучана %(index)d з %(total)d элементаў" -msgstr[2] "Вылучана %(index)d з %(total)d элементаў" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Знойдзены %d прадвызначаны скарот для чытача з экрана." -msgstr[1] "Знойдзена %d прадвызначаныя скароты для чытача з экрана." -msgstr[2] "Знойдзена %d прадвызначаных скаротаў для чытача з экрана." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Знойдзены %(count)d скарот чытача з экрана для %(application)s." -msgstr[1] "Знойдзена %(count)d скароты чытача з экрана для %(application)s." -msgstr[2] "Знойдзена %(count)d скаротаў чытача з экрана для %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d прабел" -msgstr[1] "%d прабелы" -msgstr[2] "%d прабелаў" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d табуляцыя" -msgstr[1] "%d табуляцыі" -msgstr[2] "%d табуляцый" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d табліца" -msgstr[1] "%d табліцы" -msgstr[2] "%d табліц" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "табліца з невядомым памерам" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "табліца з %d слупком, колькасць радкоў невядома" -msgstr[1] "табліца з %d слупкамі, колькасць радкоў невядома" -msgstr[2] "табліца з %d слупкамі, колькасць радкоў невядома" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "табліца з %d радком, колькасць слупкоў невядома" -msgstr[1] "табліца з %d радкамі, колькасць слупкоў невядома" -msgstr[2] "табліца з %d радкамі, колькасць слупкоў невядома" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "табліца з %d радком" -msgstr[1] "табліца з %d радкамі" -msgstr[2] "табліца з %d радкамі" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d секунду таму" -msgstr[1] "%d секунды таму" -msgstr[2] "%d секунд таму" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d хвіліну таму" -msgstr[1] "%d хвіліны таму" -msgstr[2] "%d хвілін таму" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d гадзіну таму" -msgstr[1] "%d гадзіны таму" -msgstr[2] "%d гадзін таму" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d дзень таму" -msgstr[1] "%d дні таму" -msgstr[2] "%d дзён таму" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d ненаведаная спасылка" -msgstr[1] "%d ненаведаныя спасылкі" -msgstr[2] "%d ненаведаных спасылак" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d наведаная спасылка" -msgstr[1] "%d наведаныя спасылкі" -msgstr[2] "%d наведаных спасылак" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "пераключыць" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "на %(index)d з %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d з %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "элемент %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "УЗРОВЕНЬ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "узровень іерархіі %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "УЗРОВЕНЬ ІЕРАРХІІ %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "пытальнік" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "Перайсці да наступнай графы з выплыўным спісам." - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "папраўны" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "стужка" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "фігура" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "слова" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "двукроп'е" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "верхняе падкрэсліванне" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "напрамак" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "слова" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "гласарый" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "водступ" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "напрамак" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "page up" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "частка" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "двукоссе" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "заг%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s, узровень %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "гарызантальна" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "вертыкальная лінія" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "гарызантальны паўзунок" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "вертыкальны паўзунок" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "гарызантальны раздзяляльнік" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "вертыкальны раздзяляльнік" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "пераключальнік рэжыму" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Панэль значкоў" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "банер" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "інфармацыя" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "крыху сціснуты" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "навігацыя" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "рэгіён" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "пошук" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "наведаная спасылка" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "кнопка меню" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "згорнута" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "разгорнута" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "мае падрабязнае апісанне" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "гарызантальна" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "вертыкальна" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "уключана" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "не ўключана" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "укл" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "выкл" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "часткова ўключана" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "націснута" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "не націснута" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "не выбрана" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "выбрана" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "не выбрана" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "не выбрана" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "наведаная" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "ненаведаная" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "неактыўна" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "толькі для чытання" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "толькчыт" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "неабходна" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "шматразовае вылучэнне" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "правапіс" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "правапіс" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Знайсці" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Дыялогавае акенца пошуку чытача з экрана" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Закрыць" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "З_найсці" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Шукаць:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Шукаць:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Верх акна" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Верх акна" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Пачаць з:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Шукаць у цыкле" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "_Адваротны пошук" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Кірунак пошуку:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Улічваць рэгістр" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "_Шукаць толькі поўныя адпаведнікі" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Параметры:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Прадвызначаны" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Вялікія літары" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Сеціўная спасылка" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Сістэма" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Праграма" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Акно" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "Чытач з экрана Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Даведка" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Ужыць" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Ноўтбук" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Клавіятурная раскладка" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Дзейны _профіль:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Пачатковы профіль:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Загрузіць" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Захаваць _як" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Выдаліць" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Профілі" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Паказваць падказкі" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Агучваць аб'екты пад кур_сорам" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Мыш" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Фармат _часу:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Фармат дат_ы:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Час і дата" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "А_гучваць абнаўленні" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Паказваць абнаўленні _Брайлем" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Частата (сек):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Ужывацца да:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Абнаўленне стужкі прагрэсу" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "_Уключыць структурную навігацыю" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Чытаць усё п_а:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Чытаць усё" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Агульныя" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Гу_чнасць:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Тэ_мбр:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Тэмп:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Асоба:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Мова:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Сінтэза_тар маўлення:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Сістэма маўлення:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Тып _голасу:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Стыль для _вялікіх літар:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Налады тыпу голасу" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Чытаць паслоў_на ланцужкі з мяшаным рэгістрам" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Прамаўляць _лікі як лічбы" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Глабальныя налады голасу" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Голас" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Уключыць маўленне" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Пад_рабязна" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Падрабязнасць" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Усе" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Узровень пунктуацыі" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Прамаўляць толькі паказаны тэкст" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Агучваць пустыя радкі" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Агучваць _водступы і выраўноўванне" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Агуч_ваць мнеманічныя аб'екты" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Агучваць п_азіцыю нашчадка" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Агучваць вучэбныя паведамленні" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "Агучваць каардынаты _клетак" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -#, fuzzy -msgid "Announce _lists during navigation" -msgstr "_Уключыць структурную навігацыю" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -#, fuzzy -msgid "Announce _tables during navigation" -msgstr "_Уключыць структурную навігацыю" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "Агучваць каардынаты _клетак" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "Апісанне" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Моўны кантэкст" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Маўленне" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Уключыць _падтрымку Брайля" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Скарочаныя назвы роляў" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Выключыць знак _канца радка" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Табліца скарачэнняў:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Уключыць Брайлеўскія скароты" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Уключыць па_слоўнае агучванне" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Налады паказу" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Няма" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Індыкатар вылучэння" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Індыкатар сеціўнай спасылкі" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "П_рацягласць (сек):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "Глабальныя налады голасу" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Брайль" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Уключыць агучванне _клавіш" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Уключыць клавішы _навігацыі" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Уключыць агучванне клавіш _лічбаў" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Уключыць функц_ыянальныя клавішы" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "_Уключыць маўленне" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Уключыць клавішы-_мадыфікатары" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Уключыць функц_ыянальныя клавішы" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Уключыць клавішы дзе_янняў" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Уключыць клавішы _навігацыі" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Уключыць па_слоўнае агучванне" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Уключыць агучванне па ск_азах" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Агучванне" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "_Клавішы-мадыфікатары чытача з экрана:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Прывязкі клавіш" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Слоўнік вымаўленняў" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Новы запіс" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Выдаліць" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Вымаўленне" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Вымаўляць усё" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Нічога не вымаўляць" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Скінуць" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Атрыбуты тэксту" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Перамясціць у_ніз" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Перамясціць на адну ўні_з" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Перамясціць на адну ўв_ерх" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Перамясціць у_верх" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "Змяніць вылучаныя атрыбуты" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Індыкатар Брайля" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Атрыбуты тэксту" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "нізкае" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "_Мова:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "іена" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -#, fuzzy -msgid "Copy Results to _Clipboard" -msgstr "Змесціва скапіявана ў буфер абмену." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"а : аловак, б : бусел, в : вожык, г : гарбуз, д : драбіны, е : елка, ё : " -"ёгурт, ж : жыта, з : збан, і : імя, й : і кароткае, к : кавун, л : лыжка, " -"м : матыль, н : неба, о : опера, п : павук, р : рака, с : стужка, т : торба, " -"у : узор, ў : у кароткае, ф : фарба, х : хата, ц : цукар, ч : човен, ш : " -"шалік, ы : ы, ь: мяккі знак, ' : апостраф, э : экран, ю : юнак, я : язык" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "фонавы колер фона" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "поўная вышыня фона" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "гравіраванне фона" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "напрамак" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "папраўны" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "назва сям'і шрыфтоў" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "колер пярэдняга плана" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "гравіраванне пярэдняга плана" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "стыль шрыфту" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "водступ" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "памылка" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "нябачны" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "раўнаванне" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "мова" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "левае поле" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "вышыня радка" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "стыль абзаца" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "пікселяў над радкамі" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "пікселяў пад радкамі" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "пікселяў у пераносе" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "правае поле" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "узнятасць" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "маштаб" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "памер" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "расцягнутасць" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "закрэсліванне" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "стыль" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "аздабленне тэксту" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "паварот тэксту" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "цень тэксту" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "падкрэсліванне" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "варыянт" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "вертыкальнае выраўноўванне" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "вага" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "рэжым пераносу" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "рэжым напісання" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "праўда" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "мана" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "няма" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "гравіраваны" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "рэльефны" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "абрыс" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "верхняе падкрэсліванне" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "закрэслены" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "мігаціць" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "чорны" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "асобнае" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "падвойнае" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "нізкае" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "знак" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "слова" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "слова і знак" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr (злева направа)" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl (справа налева)" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "лева" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "права" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "сярэдзіна" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "без раўнавання" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "запаўненне" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "вельмі моцна сціснуты" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "вельмі сціснуты" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "сціснуты" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "крыху сціснуты" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "звычайны" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "крыху пашыраны" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "пашыраны" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "вельмі пашыраны" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "вельмі моцна пашыраны" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "малыя літары" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "нахілены" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "курсіўны" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Прадвызначаны" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Змест тэксту" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Загаловак" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "базавая лінія" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "ніжні індэкс" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "верхні індэкс" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "верх" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "верх тэксту" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "сярэдзіна" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "ніз" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "ніз тэксту" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "па спадчыне" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb (злева направа і зверху ўніз)" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb (справа налева і зверху ўніз)" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl (зверху ўніз і справа налева)" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr (зверху ўніз і злева направа)" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl (знізу ўверх і справа налева)" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr (знізу ўверх і злева направа)" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr (злева направа)" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl (справа налева)" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb (зверху ўніз)" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "суцэльны" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "правапіс" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Каб пераключыць, націсніце Прабел." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Націсніце Прабел, каб разгарнуць элемент, і выкарыстоўвайце клавішы ўверх і " -"ўніз, каб яго выбраць." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Націсніце Alt+F6 для пераходу ў вокны нашчадка." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "Каб перайсці да элемента, выкарыстоўвайце клавішы стрэлак ці пошук." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Каб перайсці ў сістэмнае меню, націсніце Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Каб абраць элемент, выкарыстоўвайце клавішы ўверх і ўніз." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Каб згарнуць, адначасова націсніце Shift і стрэлку ўлева." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Каб разгарнуць, адначасова націсніце Shift і стрэлку ўправа." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Каб задзейнічаць, націсніце Увод." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Увядзіце тэкст." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" -"Выкарыстоўвайце клавішы «стрэлка ўлева » або «стрэлка ўправа», каб " -"праглядзець іншыя ўкладкі." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Каб задзейнічаць, націсніце Прабел." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Выкарыстоўвайце клавішы «стрэлка ўверх» або «стрэлка ўніз», каб выбраць " -"значэнне. Ці ўпішыце неабходны лік." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Каб змяніць, выкарыстоўвайце клавішы са стрэлкамі." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Для перамяшчэння карыстайцеся стрэлкамі ўлева і ўправа. Каб выбраць " -"элементы, націсніце стрэлку ўніз або ўверх." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Каб увайсці ў падменю, націсніце стрэлку ўправа." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Каб паменшыць, націсніце стрэлку ўлева, каб павялічыць - стрэлку ўправа. Каб " -"выбраць мінімальнае значэнне націсніце Home, а для максімальнага - End." diff --git a/po/bg.po b/po/bg.po deleted file mode 100644 index 555ac6d..0000000 --- a/po/bg.po +++ /dev/null @@ -1,9234 +0,0 @@ -# Bulgarian translation of cthulhu po-file. -# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. -# Copyright (C) 2012, 2013, 2021, 2022 Free Software Foundation, Inc. -# Copyright (C) 2015 Zahari Yurukov -# This file is distributed under the same license as the cthulhu package. -# Alexander Shopov , 2006, 2007, 2008, 2009, 2010, 2011. -# Alexander Shopov , 2012, 2013, 2021, 2022. -# Damyan Ivanov , 2010, 2011. -# Krasimir Chonov , 2011. -# Zahari Yurukov , 2015. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2022-09-12 14:22+0200\n" -"Last-Translator: Alexander Shopov \n" -"Language-Team: Bulgarian \n" -"Language: bg\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu — екранен четец" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "екран;четец;достъпност;говор;брайл;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "пржд" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "анмц" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "стрл" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "клнд" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "плтн" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "зглв" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "потм" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "изцв" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "згкл" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "пщсп" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "рддт" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "икн" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "рмк" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "цфрб" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "длг" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "пнлп" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "рсвн" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "фл" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "плнт" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "шрфт" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "фрмл" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "стпнл" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "зглв" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "избр" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "врмк" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "еткт" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "отгпнл" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "врзк" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "спск" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "елсп" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "мю" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "лнмю" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "елмю" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "нсрпнл" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "тбстрн" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "сптбв" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "пнл" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "прл" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "измю" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "лнпрг" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "бт" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "рдбт" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "елрд" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "глпн" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "зрт" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "лнпр" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "прпнл" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "рздл" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "рздт" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "плзч" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "рзпнл" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "бтстр" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "лнсст" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "тблц" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "клтк" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "мюотк" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "трмн" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "ткст" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "првбт" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "лнинс" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "пдск" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "дрв" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "дрвтбл" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "нзн" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "вдчст" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "прзц" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "гклт" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "дклт" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "абз" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "пргр" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "автм" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "лнрдк" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "влжн" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "чешки, ниво 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "испански, ниво 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "френски в Канада, ниво 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "френски във Франция, ниво 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "латвийски, ниво 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "нидерландски, ниво 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "норвежки, ниво 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "норвежки, ниво 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "норвежки, ниво 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "норвежки, ниво 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "полски, ниво 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "португалски, ниво 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "шведски, ниво 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "арабски, ниво 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "уелски, ниво 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "уелски, ниво 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "немски, ниво 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "немски, ниво 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "немски, ниво 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "английски в ОК, ниво 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "английски в ОК, ниво 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "английски в САЩ, ниво 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "английски в САЩ, ниво 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "френски в Канада, ниво 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "френски във Франция, ниво 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "гръцки, ниво 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "хинди, ниво 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "унгарски, с 8 точки" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "унгарски, ниво 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "унгарски, ниво 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "италиански, ниво 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "нидерландски в Белгия, ниво 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "интервал" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "нов ред" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "табулация" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "удивителна" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "кавички" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "диез" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "долар" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "процент" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "амперсанд" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "апостроф" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "лява скоба" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "дясна скоба" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "звезда" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "плюс" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "запетая" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "тире" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "точка" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "наклонена черта" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "двоеточие" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "точка и запетая" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "по-малко" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "равно" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "по-голямо" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "въпросителна" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "кльомба" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "лява квадратна скоба" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "обратна наклонена черта" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "дясна квадратна скоба" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "колибка" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "долна черта" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "тежко ударение" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "лява фигурна скоба" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "вертикална черта" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "дясна фигурна скоба" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "тилда" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "непрекъсваем интервал" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "обърната удивителна" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "центове" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "лири" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "валута" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "йени" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "вертикална прекъсната черта" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "параграф" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "трема" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "авторски права" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "горен индекс а" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "леви френски кавички" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "логическо не" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "меко тире" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "регистрирана марка" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "горна черта" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "градуси" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "плюс или минус" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "горен индекс 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "горен индекс 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "остро ударение" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "мю" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "край на абзац" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "средна точка" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "седий" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "горен индекс 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "числително редно" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "десни френски кавички" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "четвъртина" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "половина" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "три четвърти" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "обърната въпросителна" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "малко а с остро ударение" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "главно а с тежко ударение" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "главно а с остро ударение" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "главно а с двойно ударение" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "главно а с тилда" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "главно а с преглас" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "главно а с кръгче" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "главен дифтонг а е" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "главно це със седий" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "Главно е с тежко ударение" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "главно е с остро ударение" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "главно е с двойно ударение" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "главно е с преглас" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "главно и с тежко ударение" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "главно и с остро ударение" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "главно и с двойно ударение" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "главно и с преглас" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "главно ет" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "главно ен с тилда" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "Главно о с тежко ударение" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "главно о с остро ударение" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "главно о с двойно ударение" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "главно о с тилда" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "главно о с преглас" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "умножение" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "главно о с черта" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "Главно у с тежко ударение" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "главно у с остро ударение" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "главно у с двойно ударение" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "главно у с преглас" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "главно игрек с остро ударение" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "главно торн" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "ес цет" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "малко а с тежко ударение" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "малко а с двойно ударение" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "малко а с тилда" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "малко а с преглас" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "малко а с кръгче" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "малък дифтонг а е" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "малко це със седий" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "малко е с тежко ударение" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "малко е с остро ударение" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "малко е с двойно ударение" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "малко е с преглас" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "малко и с тежко ударение" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "малко и с остро ударение" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "малко и с двойно ударение" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "малко и с преглас" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "малко ет" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "малко ен с тилда" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "малко о с тежко ударение" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "малко о с остро ударение" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "малко о с двойно ударение" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "главно о с тилда" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "малко о с преглас" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "деление" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "малко о с черта" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "малко торн" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "малко у с остро ударение" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "малко у с тежко ударение" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "малко у с двойно ударение" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "малко у с преглас" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "малко игрек с остро ударение" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "малко игрек с преглас" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "главно игрек с преглас" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "флорин" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "средно тире" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "лява единична кавичка" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "дясна единична кавичка" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "долна лява кавичка" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "леви двойни кавички" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "десни двойни кавички" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "долни двойни кавички" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "кама" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "двойна кама" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "водач" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "триъгълен водач" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "промил" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "прима" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "двойна прима" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "тройна прима" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "водач тире" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "евро" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "търговска марка" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "отметка" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "силна отметка" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "водач хикс" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "горен индекс 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "горен индекс 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "горен индекс 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "горен индекс 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "горен индекс 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "горен индекс 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "горен индекс 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "горен индекс плюс" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "горен индекс минус" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "горен индекс равно" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "горен индекс лява скоба" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "горен индекс дясна скоба" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "горен индекс ен" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "долен индекс 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "долен индекс 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "долен индекс 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "долен индекс 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "долен индекс 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "долен индекс 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "долен индекс 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "долен индекс 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "долен индекс 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "долен индекс 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "долен индекс плюс" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "долен индекс минус" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "долен индекс равно" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "долен индекс лява скоба" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "долен индекс дясна скоба" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "запълнен квадрат" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "запълнен ромб" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "заместващ знак" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Позициониране на показалеца върху текущия елемент" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Ляво щракване върху елемента от равнинния преглед" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Дясно щракване върху елемента от равнинния преглед" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Прочитане на целия документ" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Прочитане на целия прозорец в равнинен преглед" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Изпълнение на основна операция „Къде съм?“" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Изпълнение на разширена операция „Къде съм?“" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Прочитане на текущия избор" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Прочитане на информация за връзката" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Представяне на бутона по подразбиране" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Прочитане на лентата за състоянието" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Прочитане на лентата за заглавието" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Отваряне на диалоговия прозорец за търсене" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Покажи списък с действия" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Търсене на следващата поява на търсения низ" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Търсене на предишната поява на търсения низ" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Влизане и излизане от режим на равнинен преглед" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Преместване на равнинния преглед в края" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Преместване на равнинния преглед в началото" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Преместване на равнинния преглед в края" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Преместване на равнинния преглед в началото на предишния ред" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Прочитане на текущия ред в равнинния преглед" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Прочитане по букви на текущия ред в равнинния преглед" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Фонетично прочитане по букви на текущия ред в равнинния преглед" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Преместване на равнинния преглед в началото на следващия ред" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Преместване на равнинния преглед към предишния елемент или дума" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Прочитане на текущия елемент или дума в равнинния преглед" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Побуквено прочитане на текущия елемент или дума в равнинния преглед" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Фонетично побуквено прочитане на текущия елемент или дума в равнинния преглед" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Преместване на равнинния преглед към следващия елемент или дума" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Преместване на равнинния преглед към думата над текущата" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Прочитане на текущия обект в равнинния преглед" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Преместване на равнинния преглед към думата под текущата" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Преместване на равнинния преглед към предишния знак" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Прочитане на текущия знак в равнинния преглед" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Фонетично прочитане на текущия знак в равнинния преглед" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Прочитане на стойността по Уникод на текущия знак в равнинния преглед" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Преместване на равнинния преглед към следващия знак" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Преместване на равнинния преглед към края на реда" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Преместване на равнинния преглед надолу и наляво" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Копиране на съдържанието от равнинния преглед в буфера за обмен" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Добавяне на съдържанието от равнинния преглед към буфера за обмен" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Преместване на равнинния преглед в края" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Превключване дали да се прочита само текущата клетка или целия ред" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Прочитане на атрибутите свързани с текущия текстов знак" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Преместване на изгледа на брайловия екран наляво" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Преместване на изгледа на брайловия екран надясно" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Връщане към обекта с клавиатурния фокус" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Превключване на съкратен брайл" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Обработка на клавиш за позиция" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Отбелязване на начало на избран текст" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Отбелязване на край на избран текст" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Влизане в режим на обучение. За излизане от него натиснете клавиша „Escape“" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Намаляване на скоростта на гласа" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Увеличаване на скоростта на гласа" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Намаляване на височината на гласа" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Увеличаване на височината на гласа" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Увеличаване на силата на гласа" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Намаляване на силата на гласа" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Избери предишната настройка за говор" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Избери следващата настройка за говор" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Намали текущата настройка за говор" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Увеличи текущата настройка за говор" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Запази настройките за говор" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Превключване на заглушаването на речта" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Превключване на нивата на многословност на речта" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Превключи режим на заспиване" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Спиране на екранния четец" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Показване на диалоговия прозорец за настройка" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Показване на диалоговия прозорец за настройка за текущото приложение" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Превключване на прочитането на отстъпа и подравняването" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Към следващия начин за четене на числа" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Към следващата степен при прочитане на пунктуацията" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Към следващата степен на уведомяване при натискане на клавиш" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Към следващия профил от настройки" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Към следващия стил за подсказване на регистъра на буквите" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Към следващата степен на уведомяване при натискане на клавиш" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" -"Към следващото ниво на съобщенията за отстраняване на грешки по време на " -"работа" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Отбелязване на това положение спрямо текущото" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Към местоположението на предишната отметка" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Към отметка" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Към местоположението на следващата отметка" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Добавяне на отметка" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Запазване на отметките" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Превключване на режима на преглед с мишката" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Прочитане на часа" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Прочитане на датата" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Прочитане на размера и местоположението на текущия обект" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Предаване на следващата команда на текущото приложение" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Прочитане и показване на брайл на предишното съобщение в стаята" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" -"Превключване дали да има уведомяване, когато контактите пишат съобщение" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Превключване дали стаите за чата да са с отделни истории" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Превключване дали съобщенията да се предхождат от имената на стаите за чата" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Ред наляво" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Ред надясно" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Ред нагоре" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Ред надолу" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Застиване" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Горен ляв" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Долен ляв" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Позиция на курсора" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Шест точки" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Превъртане на курсора" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Начало на изрязване" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Изрязване на ред" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Повтаряне на последното съобщение" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Списък със съобщения" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Повтаряне на предишното съобщение" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Повтаряне на последното съобщение" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Към следващия знак" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Към предишния знак" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Към следващата дума" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Към предишната дума" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Към следващия ред" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Към предишния ред" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Към началото на файл" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Към края на файл" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Към началото на реда" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Към края на реда" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Към следващия обект" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Към предишния обект" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Разгъване на текущия падащ списък" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Превключване между придвижването с вградения курсор и виртуалния курсор на " -"екранния четец" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Увеличаване на вежливостта на живия район" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Стандартното ниво на вежливост на живите райони да е изключено" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Преглеждане на съобщенията от живите райони" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Наблюдение на живите райони" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" -"Преместване на фокуса към/от новопоявил се обект поради позициониране на " -"мишката" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Задаване на реда за използване като динамични заглавия на колоните" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Изчистване на реда за използване като динамични заглавия на колоните" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Задаване на колоната за използване като динамични заглавия на редовете" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" -"Изчистване на колоната за използване като динамични заглавия на редовете" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Прочитане на съдържанието на реда за въвеждане" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Включване на клавишите за придвижване по структурата" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Към предишния цитат в каре" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Към следващия цитат в каре" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Показване на списък с цитатите в каре" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Към предишния бутон" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Към следващия бутон" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Показване на списък с бутоните" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Към предишното поле за отметка" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Към следващото поле за отметка" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Показване на списък с полетата за отметка" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Към предишния елемент за щракане" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Към следващия елемент за щракане" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Показване на списък с елементите за щракане" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Към предишния падащ списък" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Към следващия падащ списък" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Към началото на контейнера" - -# TODO преместване -> към -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Към края на контейнера" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Показване на списък с падащите списъци" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Към предишното поле за писане" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Към следващото поле за писане" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Показване на списък с полетата за писане" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Към предишното поле от формуляр" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Към следващото поле от формуляр" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Показване на списък с полетата от формуляр" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Към предишното заглавие" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Към следващото заглавие" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Показване на списък със заглавията" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Към предишното заглавие от ниво %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Към следващото заглавие от ниво %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Показване на списък със заглавията от ниво %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Към предишната таблица" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Към следващата таблица" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Показване на списък с таблиците" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Към предишното изображение" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Към следващото изображение" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Показване на списък с изображенията" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Към предишния ориентир" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Към следващия ориентир" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Показване на списък с ориентирите" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Към предишния голям обект" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Към следващия голям обект" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Показване на списък с големите обекти" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Към предишната връзка" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Към следващата връзка" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Показване на списък с връзките" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Към предишния списък" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Към следващия списък" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Показване на списък със списъците" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Към предишния елемент от списък" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Към следващия елемент от списък" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Показване на списък с елементи от списъци" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Към предишния жив район" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Към следващия жив район" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Към последния жив район, изпратил уведомление" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Преминаване към родителя на обекта с фокус на навигатора." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Преминаване към първото дете на обекта с фокус на навигатора." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Преминаване към следващия събрат на обекта с фокус на навигатора." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Преминаване към предишния събрат на обекта с фокус на навигатора." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Връщане към обекта с клавиатурния фокус" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Включване на клавишите за придвижване по структурата" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Към предишния абзац" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Към следващия абзац" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Показване на списък с абзаците" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Към предишния радио бутон" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Към следващия радио бутон" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Показване на списък с радио бутоните" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Към предишния разделител" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Към следващия разделител" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Към предишната таблица" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Към следващата таблица" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Показване на списък с таблиците" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Една клетка надолу" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Към първата клетка в таблица" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Към последната клетка в таблица" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Една клетка наляво" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Една клетка надясно" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Една клетка нагоре" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Превключване на режима по подредба" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Превключване между режимите на фокус и на разглеждане" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Включване на лепкав режим на фокус" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Включване на лепкав режим на фокус" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Към предишната непосетена връзка" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Към следващата непосетена връзка" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Показване на списък с непосетените връзки" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Към предишната посетена връзка" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Към следващата посетена връзка" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Показване на списък с посетените връзки" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "много, много светло синьо" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "антично бяло" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "аквамарин" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "азурно" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "бежово" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "светло кафяво" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "черно" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "бланширано бадемено" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "синьо" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "виолетово синьо" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "кафяво" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "дървено кафяво" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "кадетово-синьо" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "резедаво" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "шоколадово-кафяво" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "коралово" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "метличино синьо" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "жълто като царевична коса" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "пурпурно" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "цианено" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "тъмно синьо" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "тъмно лилаво" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "тъмно златно" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "тъмно сиво" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "тъмно зелено" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "тъмно жълто-кафяво" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "тъмен фуксин" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "тъмно маслинено-зелено" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "тъмно оранжево" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "тъмно орхидеено" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "тъмно червено" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "тъмна сьомга" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "тъмно морско зелено" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "тъмно шистово синьо" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "тъмно шистово сиво" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "тъмно тюркоазено" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "тъмно виолетово" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "дълбоко розово" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "тъмно небесно синьо" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "замъглено сиво" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "богато синьо" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "тухлено" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "флорално бяло" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "горско-зелено" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "цикламено" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "много светло сиво" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "призрачно-бяло" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "златно" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "златисто" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "сиво" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "зелено" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "зелено-жълто" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "медена роса" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "горещо-розово" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "индианско-червено" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "индигово" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "слонова кост" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "кафяво-жълто" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "лавандулово" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "ръжено-лавандулово" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "тревно-зелено" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "лимонено-жълто" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "светло синьо" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "светъл корал" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "светъл циан" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "светло златисто-жълто" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "светло сиво" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "светло зелено" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "светло розово" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "светла сьомга" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "светло морско-зелено" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "светло небесно-синьо" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "светло шистово-сиво" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "светло стоманено-синьо" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "светло жълто" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "светло резедаво" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "резедаво-зелено" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "ленено" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "фуксин" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "кестеняво" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "среден аквамарин" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "средно синьо" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "средно орхидеено" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "средно лилаво" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "средно морско-зелено" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "средно шистово-синьо" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "средно пролетно-зелено" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "средно тюркоазено" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "средно виолетово-червено" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "среднощно-синьо" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "ментово-сметаново" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "мъглява роза" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "мокасиново" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "навахо бяло" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "морско-синьо" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "дантелено" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "маслинено-зелено" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "маслиново-бозаво" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "оранжево" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "оранжево-червено" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "орхидеено" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "бледо златисто" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "бледо зелено" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "бледо тюркоазено" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "бледо виолетово-червено" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "папаено" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "прасковено" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "перуанско" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "розово" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "лилаво-виолетово" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "бледо синьо" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "лилаво" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "червено" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "розово-кафяво" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "дълбоко-синьо" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "седлено-кафяво" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "сьомга" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "пясъчно-кафяво" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "морско-зелено" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "черупково-бяло" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "охра" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "сребърно" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "небесно-синьо" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "шистово-синьо" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "шистово-зелено" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "снежно" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "пролетно-зелено" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "стоманено-синьо" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "бронзово-кафяво" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "тъмно-зелено" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "магарешко-лилаво" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "доматено-червено" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "тюркоазено" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "виолетово" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "пшеничено" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "бяло" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "бял дим" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "жълто" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "жълто-зелено" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Активиране" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Автоматичен режим на фокус при придвижване по структура" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Автоматичен режим на фокус при придвижване с курсора" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Автоматичен режим на фокус при придвижване с курсора" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "_7-ма точка" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "_8-ма точка" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "7-ма _и 8-ма точки" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Отказ" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Към" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Добре" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Икона" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Никакво" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Указване на главни" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "_Уведомяване, когато контактите пишат съобщение." - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Стаите за _чата да са с отделни истории." - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Прочитане на съобщенията от" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "_Всички канали" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Всички канали, когато е активен _произволен прозорец на %s" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Канал, само ако прозорецът му е _активен" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Прочитане на името на стаята" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Включване на режим на екранна подредба за съдържанието" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "двукратно натискане" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "трикратно натискане" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Стандартен синтезатор" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Срещнат низ" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Низ за замяна" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Прочитане по _знаци" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Прочитане на диакрити_чните знаци" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Текущото местоположение" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Минимална дължина на текста, който съвпада:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Настройки на търсенето" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "При _съвпадение да се прочитат само променените редове" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Прочитане на резултатите при _намиране на съвпадение" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Команда" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Присвоени клавиши" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Стандартни" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Режим по подредба." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Действия" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Функции на брайловите клавиши" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Отметки" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Час и дата" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Режимът на преглед с мишката е включен." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "придвижване" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Режим по обекти." - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Без клавишна комбинация" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Излизане от режим на равнинен преглед." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Превключване на нивата на многословност на речта" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "основно съдържание" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Променена" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Настолен компютър" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Уведомяване" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Получено" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Уведомяване" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Настройки на Cthulhu за %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Отбелязване на брайл" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Прочитане, освен ако" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Прочитане" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Запазване като конфликтен профил" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Конфликт в потребителския профил!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Профилът %s вече съществува.\n" -"Да се продължи ли обновяването на съществуващия профил с промените?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Зареждане на потребителски профил" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Ще променяте активния профил. Ако сте\n" -"променяли настройките, те ще бъдат изтрити\n" -"при зареждането на модула.\n" -"\n" -"Да се зареди ли профила и да се забравят ли\n" -"промените?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Запазване като" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Име на профила:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Изтриване на потребителски профил" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Ще изтриете потребителския профил „%s“. Всички настройки записани в него ще " -"изчезнат. Искате ли да продължите?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "всички" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "програмата" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "прозореца" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "Ни_кои" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Н_якои" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Пов_ечето" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Ред" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Изречение" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Цитат" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Бутон" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Надпис" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Поле за отметка" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "За щракане" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Падащ списък" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Описание" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Заглавие" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "вмъкване" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Изображение" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Етикет" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Ориентир" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Ниво" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Връзка" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Списък" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Елемент от списък" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Обект" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Абзац" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Радио бутон" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Тип" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Избран елемент" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Състояние" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Текст" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "Адрес" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Стойност" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Цитати" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Бутони" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Полета за отметка" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "За щракане" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Падащи списъци" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Полета за писане" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Полета от формуляр" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Заглавия" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "вмъкване" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Изображения" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Заглавия от ниво %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Ориентири" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Големи обекти" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Връзки" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Списъци" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Елементи от списък" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Абзаци" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Радио бутони" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Таблици" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Непосетени връзки" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Посетени връзки" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Придвижване в страниците" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "_Автоматично прочитане на страницата при първоначално зареждане" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"_Автоматично прочитане на обобщение на страницата при първоначално зареждане" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "_Разделяне на речта на части между паузите" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Стандартният глас на %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Стандартен" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Хипервръзки" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Системни" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Главни" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Правописна проверка" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Грешно _изписано" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Предложение за _правопис" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Текущ _контекст на грешката" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Прочитане на координатите на клетката в електронната таблица" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Избраната област в електронната таблица винаги да се прочита" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Прочитане на _заглавните клетки" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Придвижване в таблици" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Прескачане на _празните клетки" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Прочитане на _клетка" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Прочитане на _координатите на клетките" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Прочитане на _обхвата на слетите клетки" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Име на атрибут" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Придвижване с _курсора на Cthulhu" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Включване на клавишите за _придвижване по структурата." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Тема на звуците:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Тема на звуците" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Съкратена" - -#: src/cthulhu/guilabels.py:953 -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Уведомяване" -msgstr[1] "Уведомяване" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "ляв shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "ляв alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ляв control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "десен shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "десен alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "десен control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ляв meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "десен meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "лява табулация" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "нагоре" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "надолу" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "наляво" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "надясно" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "ляв super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "десен super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "меню" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "десен Alt" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "помощ" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "мулти" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "смяна на режима" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "двойно ударение" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "кръгче" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "черта" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "минус" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "CapsLock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Десен Alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Ляв Alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "получер %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "курсив %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "получер курсив %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "индекс %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "получер индекс %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "готически %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s с черта" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "получер готически %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "безсерифен %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "безсерифен получер %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "серифен курсив %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "безсерифен получер курсив %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "равноширок %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "безточков %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "стрелка наляво" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "стрелка нагоре" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "стрелка надясно" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "стрелка надолу" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "стрелка наляво-надясно" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "стрелка нагоре-надолу" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "стрелка на северозапад" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "стрелка на североизток" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "стрелка на югоизток" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "стрелка с черта наляво" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "стрелка с черта нагоре" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "стрелка с черта надясно" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "стрелка с черта надолу" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "двойна стрелка наляво" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "двойна стрелка нагоре" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "двойна стрелка надясно" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "двойна стрелка надолу" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "двойна стрелка наляво-надясно" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "двойна стрелка нагоре надолу" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "двойна стрелка на северозапад" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "двойна стрелка на североизток" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "дойна стрелка на югоизток" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "двойна стрелка на югозапад" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "стрелка, сочеща надясно" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "стрелка без тяло надясно" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "минус" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "по-малко от" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "по-голямо от" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "двойно ударение" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "карон" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "кратко ударение" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "точка" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "двойна вертикална черта" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "хоризонтално многоточие" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "за всички" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "допълнение" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "частен диференциал" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "съществува" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "не съществува" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "празно множество" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "инкремент" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "набла" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "принадлежи на" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "не принадлежи на" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "малко елемент от" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "съдържа" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "не съдържа" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "малко съдържа" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "край на доказателството" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "произведение" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "копродукт" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "сума" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "минус-плюс" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "точка плюс" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "делено на" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "изваждане за множества" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "умножено по" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "пръстен" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "средна точка" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "корен квадратен" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "корен кубичен" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "корен четвърти" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "пропорционално на" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "безкрайност" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "десен ъгъл" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "ъгъл" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "измерен ъгъл" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "сферичен ъгъл" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "е множител на" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "не е множител на" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "успоредно на" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "не успоредно на" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "логическо и" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "логическо или" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "сечение" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "обединение" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "интеграл" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "двоен интеграл" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "троен интеграл" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "контурен интеграл" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "двоен контурен интеграл" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "троен контурен интеграл" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "интеграл по часовниковата стрелка" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "контурен интеграл по часовниковата стрелка" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "контурен интеграл обратно на часовниковата стрелка" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "затова" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "защото" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "отношение" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "пропорция" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "точка минус" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "разлика" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "геометрична пропорция" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "хомотетичен" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "тилда" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "обърната тилда" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "обърнато мързеливо S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "синусоида" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "кръгово произведение" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "не тилда" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "минус тилда" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "асимптотично равно на" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "не асимптотично равно на" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "приблизително равно на" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "приблизително, но не точно, равно на" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "различно от" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "почти равно на" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "не почти равно на" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "почти равно или равно на" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "тройна тилда" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "всичко равно на" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "равносилно на" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "геометрично равносилно на" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "разлика между" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "доближава границата" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "геометрично равно на" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "приблизително равно на или изображение на" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "изображение на или приблизително равно на" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "двоеточие равно" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "равно двоеточие" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "пръстен в равно на" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "пръстен над равно на" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "отговаря на" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "приблизителни оценки" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "с равни ъгли спрямо" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "звезда равно" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "делта равно" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "равно по дефиниция" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "измерено по" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "въпросителен равно на" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "не равно на" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "идентично на" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "неидентично на" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "стриктно равносилно на" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "по-малко или равно на" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "по-голямо или равно на" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "по-малко равно" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "по-голямо равно" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "по-малко, но не равно на" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "по-голямо, но не равно на" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "много по-малко от" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "много по-голямо от" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "между" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "неравносилно на" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "не по-малко от" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "не по-голямо" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "нито по-малко, нито равно на" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "нито по-голямо, нито равно на" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "по-малко или равносилно на" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "по-голямо или равносилно на" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "нито по-малко, нито равносилно на" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "нито по-голямо, нито равносилно на" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "по-малко или по-голямо" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "по-голямо или по-малко" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "нито по-малко, нито по-голямо" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "нито по-голямо, нито по-малко" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "предхожда" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "задминава" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "предхожда или е равно на" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "задминава или е равно на" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "предхожда или е равносилно на" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "задминава или е равносилно на" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "не предхожда" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "не задминава" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "подмножество от" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "надмножество на" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "не е подмножество от" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "не е надмножество на" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "подмножество или равно на" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "надмножество или равно на" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "нито подмножество, нито равно на" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "нито надмножество, нито равно на" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "подмножество, но не равно на" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "надмножество, но не равно на" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "мултимножество" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "умножаване на мултимножества" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "обединение на мултимножества" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "квадратен образ на" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "квадратен оригинал на" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "квадратен оригинал на или равно на" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "квадрат на или равно" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "квадратна шапка" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "квадратна чашка" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "плюс в кръг" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "минус в кръг" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "умножение в кръг" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "ограден знак за деление" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "оградена точка" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "пръстен в кръг" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "звездичка в кръг" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "равно в кръг" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "тире в кръг" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "плюс в квадрат" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "минус в квадрат" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "умножение в квадрат" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "точка в квадрат" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "дясно кабърче" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "ляво кабърче" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "долно кабърче" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "горно кабърче" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "твърдение" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "образци" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "истина" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "принуждава" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "двойно превъртяна тройна вертикална черта" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "двойно превъртяна двойна вертикална черта" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "не доказва" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "неистина" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "не принуждава" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "отрицателна двойно превъртяна двойна вертикална черта" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "предхожда по отношение" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "задминава по отношение" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "обикновена подгрупа" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "съдържа като обикновена подгрупа" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "обикновена подгрупа на или равно на" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "съдържа като обикновена подгрупа на или равно на" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "оригинал на" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "изображение на" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "множествена карта" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "ермитна конюгатна матрица" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "вмъкване" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "обратно или" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "не и" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "не или" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "десен ъгъл с дъга" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "десен триъгълник" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "диамант" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "точка" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "звезда" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "делител" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "папийонка" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "ляво полудиректно произведение с обикновен фактор" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "дясно полудиректно произведение с обикновен фактор" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "ляво полудиректно произведение" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "дясно полудиректно произведение" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "обърнато приблизително равно" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "къдраво логическо или" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "къдраво логическо и" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "двойно подмножество" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "двойно супермножество" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "двойно сечение" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "двойно обединение" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "вила" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "равно и успоредно на" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "по-малко с точка" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "по-голямо с точка" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "много по-малко от" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "много по-голямо от" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "по-малко, равно или по-голямо" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "по-голямо, равно или по-малко" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "по-малко или равно на" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "по-голямо или равно на" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "равно или предхожда" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "равно или задминава" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "не предхожда или е равно на" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "не задминава или е равно на" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "не е квадратно изображение на или равно на" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "не е оригинален квадрат или равно на" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "квадратно изображение на или не равно на" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "оригинален квадрат или не равно на" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "по-малко, но не е еквивалентно на" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "по-голямо, но не е еквивалентно на" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "предхожда, но не е еквивалентно на" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "задминава, но не е еквивалентно на" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "не е обикновена подгрупа на" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "не съдържа като обикновена подгрупа" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "не е обикновена подгрупа или равно на" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "не съдържа като обикновена подгрупа или равно на" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "вертикално многоточие" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "хоризонтално многоточие на средната линия" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "многоточие на десен горен диагонал" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "многоточие на десен долен диагонал" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "принадлежи на с дълга хоризонтална черта" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "принадлежи на с вертикална черта накрая на хоризонтална черта" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "малко принадлежи на с вертикална черта накрая на хоризонтална черта" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "принадлежи на с точка отгоре" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "принадлежи на с черта отгоре" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "малко принадлежи на с черта отгоре" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "принадлежи на с черта отдолу" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "принадлежи на с две хоризонтални черти" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "съдържа с дълга хоризонтална черта" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "съдържа с вертикална черта на края на хоризонтална черта" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "малко съдържа с вертикална черта на края на хоризонтална черта" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "съдържа с черта отгоре" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "малко съдържа с черта отгоре" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "членство при z-нотация" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "лява скоба за закръгляне нагоре" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "дясна скоба за закръгляне нагоре" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "лява скоба за закръгляне надолу" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "дясна скоба за закръгляне надолу" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "горна фигурна скоба" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "долна фигурна скоба" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "лява френска кавичка" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "дясна френска кавичка" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "точка в кръг" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "обединение с точка" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "обединение с плюс" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "квадратно сечение" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "квадратно обединение" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "черно квадратче" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "бяло квадратче" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "черно каро" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "бяло кръгче" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "черно кръгче" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "бял водач" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "малко, черно квадратче в средата" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s с долна черта" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s с наклонена черта" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s с вертикална черта" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "програма" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "празен ред" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "получер" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "посещаване на отметка" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "отметките са записани" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "отметките не бяха записани" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Не са открити ориентири." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Не са открити ориентири." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Режимът на пропускане е включен." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Не може да се получи областта за резултата на калкулатора" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "звук" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Подсказване на регистъра със звук." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "без" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Без подсказване на регистъра." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "„главно“" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Подсказване на регистъра с „главно“." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Приложението управлява курсора." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu управлява курсора." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Клетка %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "избрана е %s" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "избрани са %s до %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "без избиране на %s до %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "без избиране на %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Изключване на опция" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Включване на опция" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "ОПЦИЯ" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Незадължителни аргументи" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Употреба: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Следните аргументи не са правилни: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Извеждане на познатите стартирани програми" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Зареждане на профил" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Профилът не беше зареден: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Cthulhu не може да се стартира, защото не може да се свърже с работния " -"плот.Екранният четец не може да се стартира, защото не може да се свърже с " -"графичната среда." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Мениджърът за настройки не може да бъде активиран. Излизане." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"В тази сесия екранният четец вече е стартиран.\n" -"Може да го рестартирате със следната команда: „cthulhu --replace“." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "ИМЕ" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Използване на различна папка за потребителски настройки" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "ПАПКА" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Версията на програмата" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Замени текущо работещ екземпляр на Cthulhu" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Извеждане на това съобщение и спиране на програмата" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" -"Запазване на съобщенията за отстраняване на грешки във файл debug-ГГГГ-ММ-ДД-" -"ЧЧ:ММ:СС.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Запазване на съобщенията за отстраняване на грешки в указания файл" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ФАЙЛ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Задаване на настройки на Cthulhu (текстова версия)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Задаване на потребителски настройки (графична версия)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Докладвайте грешките на адрес: https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Избраното е изрязано в буфера за обмен." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "изрязано" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Избраното е копирано в буфера за обмен." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "копирано" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Съдържанието е поставено от буфера за обмен." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "поставено" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Без уведомяване, когато контактите пишат съобщение." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "Уведомяване, когато контактите пишат съобщение." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Съобщение от стая %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Нов подпрозорец за разговор %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Без прочитане на името на стаята." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "прочитане на името на стаята." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Стаите за чата да не са с отделни истории." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Стаите за чата да са с отделни истории." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "начало на триене" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "край на триене" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "начало на вмъкване" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "край на вмъкване" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "начало на маркирано" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "край на маркирано" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "край на предложение" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Край на контейнер." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Не е в контейнер." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "всички елементи са избрани" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Стандартният бутон е %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Бутонът по подразбиране е %s. Неактивен" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Стандартният бутон е %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " долен индекс %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " горен индекс %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Не е в таблица." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "избран е целият документ" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "целият документ не е избран" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "документът е избран след положението на курсора" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "документът не е избран след положението на курсора" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "документът е избран до положението на курсора" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "документът не е избран до положението на курсора" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Ред %d е зададен за заглавия на колоните" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Динамичните заглавия на колоните са изчистени." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Колона %s е зададена за заглавия на редовете" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Динамичните заглавия на редовете са изчистени." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "празен" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f килобайта" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f мегабайта" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Не са открити файлове." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Добавяне на съдържанието към буфера за обмен." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Съдържанието е копирано в буфера за обмен." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Не се използва равнинен преглед." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Влизане в режим на равнинен преглед." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Излизане от режим на равнинен преглед." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Преместване на равнинния преглед към думата над текущата" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Плосък преглед без ограничения" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "съдържа формула" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "отваряне на диалогов прозорец" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "отваряне на таблица" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "отваряне на списък" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "отваряне на списък" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "отваряне на дърво" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "връзка от карта към изображение" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Въведеният клавиш вече е присвоен на %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Въведен клавиш: „%s“. За да потвърдите, натиснете „Enter“." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Новият клавиш е: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Изтрита е клавишна комбинация. За да потвърдите, натиснете „Enter“." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Клавишната комбинация е премахната." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "въведете нов клавиш" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "по клавиши" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Прочитане по клавиши." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Никакво" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Без прочитане при писане." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "по клавиши и думи" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Прочитане по клавиши и думи." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "по изречения" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Прочитане по цели изречения." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "по думи" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Прочитане по цели думи." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "по думи и изречения" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Прочитане по думи и изречения." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Обградено в: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "актюерски знак" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "квадрат" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "кръг" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "знак за деление" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "радикал" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "закръглен квадрат" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "хоризонтална черта" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "вертикална черта" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "дясна диагонална черта" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "горна диагонална черта" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "стрелка на североизток" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "черта отдолу" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "черта отляво" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "черта отдясно" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "черта отгоре" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "фазов ъгъл" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "арабски факториел" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "и" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "начало на дроб" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "начало на дроб без черта" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "над" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "край на дроб" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "корен квадратен от" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "корен кубичен от" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "корен от" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "начало на корен" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "край на корен" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "долен индекс" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "горен индекс" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "преден долен индекс" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "преден горен индекс" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "индекс отдолу" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "индекс отгоре" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "край на таблица" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "край на вложена таблица" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "недостъпен" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Изключване" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Прочитането на отстъпа и подравняването е изключено." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Включване" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Прочитането на отстъпа и подравняването е включено." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Режим на обучение. За излизане от него натиснете клавиша „Escape“." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Влизане в режим на обучение. Натиснете произволен клавиш, за да чуете " -"неговата функция. За показване на документацията на екранния четец, " -"натиснете „F1“. За списък с клавишните команди на екранния четец по " -"подразбиране, натиснете „F2“. За списък с клавишните команди на екранния " -"четец за текущото приложение, натиснете „F3“. За да излезете от режима на " -"обучение, натиснете „Escape“." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "излизане от цитат в каре." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "излизане от допълнителна информация." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "напускане на актуализации." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "излизане от фигура." - -# напускане или излизане -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "напускане на формуляр." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "напускане на плакат." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "напускане на допълнително съдържание." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "напускане на информация." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "напускане на основно съдържание." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "напускана на навигация." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "напускане на район." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "напускане на търсене." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "напускане на списък." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "напускане на панел." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "напускане на таблица." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "напускане на подсказка." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "напускане на резюме." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "напускане на признание." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "напускане на послеслов." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "напускане на приложение." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "напускане на библиография." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "напускане на глава." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "напускане на издателско каре." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "напускане на извод." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "напускане на благодарност." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "напускане на благодарности." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "напускане на посвещение." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "напускане на бележки в края." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "напускане на епиграф." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "напускане на епилог." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "напускане на печатни грешки." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "напускане на пример." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "напускане на предговор." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "напускане на речник." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "напускане на индекс." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "напускане на въведение." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "напускане на списък със страници." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "напускане на част." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "напускане на предговор." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "напускане на пролог." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "напускане на изведен цитат." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "напускане на ВиО." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "напускане на предложение." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "напускане на съдържание." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "редът е избран след положението на курсора" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "редът е избран до положението на курсора" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "редът не е избран след положението на курсора" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "редът не е избран до положението на курсора" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Излизане от режима на обучение." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "редът е избран от началото до предишното положение на курсора" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "редът е избран след предишното положение на курсора до края" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "връзка" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "същата страница" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "същия сайт" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "различен сайт" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s е връзка към %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "връзка по %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "посетена връзка %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Използвайте стрелките нагоре и надолу за придвижване в списъка. Натиснете " -"клавиша „Escape“ за изход." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Всички живи райони са изключени" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "Нивата на учтивост на живите райони са възстановени" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "ниво на учтивост %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "задаване на нивото на живите райони на подкрепящо" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "изключване на живите райони" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "задаване на нивото на живите райони на учтиво" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "задаване на нивото на живите райони на грубо" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Наблюдението на живи райони е изключено" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Наблюдението на живи райони е включено" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "не са запазени живи съобщения" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Поддръжката на живи райони е изключена" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Не е открито" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Текущото местоположение не може да бъде открито." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "изключен" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "включен" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "правопис" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Грешно изписана дума: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Контекстът е %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Режим на разглеждане" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Режим на фокус" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Натиснете %s, за да преминете в режим на фокус." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Лепкав режим на фокус." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Лепкав режим на разглеждане." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Режим по подредба." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Режим по обекти." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Няма повече големи обекти." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Не е открит новопоявил се елемент." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Режимът на преглед с мишката е изключен." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Режимът на преглед с мишката е включен." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Грешка: списъкът с обекти не може да бъде създаден." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Няма деца." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Няма следващ." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d процент." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Към предишната дума" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Опростената навигация е включена." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Опростената навигация е изключена." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Ниво на вложеност %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Появил се е нов елемент" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Не са намерени действия за: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Няма фокус" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Няма програма на фокус." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Няма повече цитати в каре." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Няма повече бутони." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Няма повече полета за отметка." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Няма повече големи обекти." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Няма повече елементи за щракане." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Няма повече падащи списъци." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Няма повече полета за писане." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Няма повече полета от формуляр." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Няма повече заглавия." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Няма повече заглавия от ниво %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Няма повече таблици." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Няма повече изображения." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Не са открити ориентири." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Няма повече връзки." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Няма повече списъци." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Няма повече елементи в списъка." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Няма повече живи райони." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Няма повече абзаци." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Няма повече радио бутони." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Няма повече разделители." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Няма повече таблици." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Няма повече непосетени връзки." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Няма повече посетени връзки." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Няма избран текст." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Не е връзка." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Уведомяване" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Край" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Начало" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Няма съобщения" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "цифри" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Прочитане на числата по цифри." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "като думи" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Прочитане на числата като думи." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "изключен" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "включен" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Зареждане, изчакайте." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Зареждането приключи." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Зареждането на „%s“ приключи." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "В страницата има %s" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "страницата е избрана от положението на курсора" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "страницата е избрана до положението на курсора" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "страницата не е избрана от положението на курсора" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "страницата не е избрана до положението на курсора" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "абзацът е избран от положението на курсора" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "абзацът е избран до положението на курсора" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "абзацът не е избран от положението на курсора" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "абзацът не е избран до положението на курсора" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Вече е отворен прозорец с настройки на Cthulhu.\n" -"Затворете го, преди да отворите нов." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "кадър %(position)d от %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Зададен е профилът „%s“." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Не са открити профили." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Лента на напредъка %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Всички" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Прочитане на всички препинателни знаци." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Повечето" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Прочитане на повечето препинателни знаци." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Никои" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Без прочитане на препинателни знаци." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Някои" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Прочитане на някои препинателни знаци." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Търсене." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Търсенето завърши." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Настройките на Cthulhu са презаредени." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Избраният текст е: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Избраното е изтрито." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Избраното е възстановено." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Текстът не е избран." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Размер: %d, %d. Местоположение: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Широчина: %d. Височина: %d. %d наляво. %d отгоре." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Гласът е изключен." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Гласът е включен." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "по-бързо." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "по-бавно." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "по-високо." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "по-ниско." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "по-силно." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "по-тихо." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Скорост %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Височина на тона %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Сила на звука %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Модул на Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Глас на Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Няма налични модули на Speech-dispatcher" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Няма налични гласове на Speech-dispatcher" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Настройките за говор са запазени" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Настройките за говор не можаха да бъдат запазени" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Ниво на многословност: кратко" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Ниво на многословност: подробно" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "многоточие" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu ви приветства." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Ктулху дебне под вълните." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Режимът на заспиване е включен за %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Режим на заспиване изключен за %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Речевата функция не е налична." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Не е открито" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Лентата за състоянието не е открита" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "низът не е открит" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Клавишите за придвижване по структурата са изключени." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Клавишите за придвижване по структурата са включени." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Няма повече" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Ред %(row)d, колона %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Край на таблица" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Прочитане на клетка" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Прочитане на ред" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "нееднородна" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Не е в таблица." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Колоните са пренаредени" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Редовете са пренаредени" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "колона %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "колона %(index)d от %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Край на колона." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Начало на колона." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Колона %s е избрана" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Колони от %s до %s са избрани" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Колони от %s до %s не са избрани" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Колона %s не е избрана" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "%d-и ред" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "ред %(index)d от %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Начало на ред." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Край на ред." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Изтриване на ред." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Изтриване на последния ред." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Вмъкване на ред." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Добавяне на ред в края на таблицата." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Ред %s е избран" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Редове от %s до %s са избрани" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Редове от %s до %s не са избрани" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Ред %s не е избран" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "избрано" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "не е избрано" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H часа, %M минути и %S секунди." - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H часа и %M минути" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Уникод %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "отмяна" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "повтаряне" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu версия %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "празно място" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "След началото — от края." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "След края — от началото." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 елемента" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Клетката заема %d ред" -msgstr[1] "Клетката заема %d реда" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d колона" -msgstr[1] "%d колони" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Клетката заема %d колона" -msgstr[1] "Клетката заема %d колони" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "по-дълго с %d знак" -msgstr[1] "по-дълго с %d знака" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d диалог)" -msgstr[1] "(%d диалога)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d диалог без фокус" -msgstr[1] "%d диалога без фокус" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d байт" -msgstr[1] "%d байта" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Открит е %d файл" -msgstr[1] "Открити са %d файла" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d формуляр" -msgstr[1] "%d формуляра" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d заглавие" -msgstr[1] "%d заглавия" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d елемент" -msgstr[1] "%d елемента" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d ориентир" -msgstr[1] "%d ориентира" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "Открит е %d елемент" -msgstr[1] "Открити са %d елемента" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Излизане от %d цитат в каре." -msgstr[1] "Излизане от %d цитати в каре." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Излизане от %d списък." -msgstr[1] "Излизане от %d списъци." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Списък с неизвестен размер" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Списък с %d елемент" -msgstr[1] "Списък с %d елемента" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Актуализации с неизвестен размер" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Актуализация с %d статия" -msgstr[1] "Актуализация с %d статии" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Списък с описания с %d елемент" -msgstr[1] "Списък с описания с %d елемента" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d стойност" -msgstr[1] "%d стойности" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "математическа таблица с %d ред" -msgstr[1] "математическа таблица с %d реда" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d колона" -msgstr[1] "%d колони" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "вложена таблица с %d ред" -msgstr[1] "вложена таблица с %d реда" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d съобщение.\n" -msgstr[1] "%d съобщения.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d процент." -msgstr[1] "%d процента." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d процент от документа са прочетени" -msgstr[1] "%d процента от документа са прочетени" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d пиксел" -msgstr[1] "%d пиксела" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d знак %(repeatChar)s" -msgstr[1] "%(count)d знака %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "избран е %(index)d от %(total)d елемента" -msgstr[1] "избрани са %(index)d от %(total)d елемента" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Открита е %d клавишна комбинация на екранния четец." -msgstr[1] "Открита са %d клавишни комбинации на екранния четец" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Открита е %(count)d клавишна комбинация за %(application)s на екранния четец." -msgstr[1] "" -"Открити са %(count)d клавишни комбинации за %(application)s на екранния " -"четец." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d интервал" -msgstr[1] "%d интервала" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d табулация" -msgstr[1] "%d табулации" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d таблица" -msgstr[1] "%d таблици" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "таблица с неизвестен размер" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "таблица с %d колона, неизвестен брой редове" -msgstr[1] "таблица с %d колони, неизвестен брой редове" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "таблица с %d ред, неизвестен брой колони" -msgstr[1] "таблица с %d реда, неизвестен брой колони" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "таблица с %d ред" -msgstr[1] "таблица с %d реда" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "преди %d секунда" -msgstr[1] "преди %d секунди" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "преди %d минута" -msgstr[1] "преди %d минути" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "преди %d час" -msgstr[1] "преди %d часа" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "преди %d ден" -msgstr[1] "преди %d дни" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d непосетена връзка" -msgstr[1] "%d непосетени връзки" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d посетена връзка" -msgstr[1] "%d посетени връзки" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "превключване" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "върху %(index)d от %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d от %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "елемент %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "НИВО %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ниво в дървото %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "НИВО В ДЪРВОТО %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "допълнителна информация за %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "има допълнителна информация в %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "предложение" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "редактируем падащ списък" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "редактируемо съдържание" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "актуализации" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "фигура" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "резюме" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "признания" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "послеслов" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "приложение" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "библиографски запис" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "библиография" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "глава" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "издателско каре" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "извод" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "заглавна страница" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "благодарност" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "благодарности" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "посвещение" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "бележка в края" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "бележки в края" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "епиграф" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "епилог" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "печатни грешки" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "пример" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "предговор" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "речник" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "индекс" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "въведение" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "нова страница" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "списък със страници" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "част" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "предговор" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "пролог" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "изведен цитат" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "ВиО" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "субтитри" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "таблица на съдържанието" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "з%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s от ниво %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "хоризонтална лента за придвижване" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "вертикална лента за придвижване" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "хоризонтален плъзгач" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "вертикален плъзгач" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "хоризонталeн разделител" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "вертикалeн разделител" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "смяна" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Панел с икони" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "плакат" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "допълнително съдържание" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "информация" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "основно съдържание" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "придвижване" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "район" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "търсене" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "посетена връзка" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "бутон в меню" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "подредени възходящо" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "подредени низходящо" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "подредени" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "за натискане" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "свит" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "разгънат" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "има подробно описание" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "хоризонтален" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "вертикален" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "с отметка" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "без отметка" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "включен" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "изключен" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "частично отметнат" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "натиснат" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ненатиснат" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "неизбран" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "избран" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "неизбран" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "неизбрана" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "посетена" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "непосетена" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "посивено" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "само за четене" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "сзч" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "задължително" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "множествен избор" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "неправилен запис" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "неправилен" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "неправилно изписване" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "правопис" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "неправилна граматика" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "граматика" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Търсене" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Прозорец за търсене на екранния четец" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Затваряне" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Търсене" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Търсене на:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Търсене на:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Горната част на прозореца" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Горната част на прозореца" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Започване от:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_След края — от началото" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Търсене наза_д" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Посока на търсене:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Зачитане на малки/главни" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Търсене само на _цели думи" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Настройки:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Стандартен" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Главни" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Хипервръзки" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Системни" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Програма" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Прозорец" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Настройки на Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "Помо_щ" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Прилагане" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Лаптоп" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Клавиатурна подредба" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Активен профил:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Начален профил:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Зареждане" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Запазване _като" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "Пре_махване" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Профили" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Прочитане на подсказките" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Изговаряне на обекта под показалеца на _мишката" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Мишка" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Формат на _часа:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Формат на _датата:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Час и дата" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Прочитане на напредъка" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Напредък през _брайл" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Честота (сек.):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Прилагане към:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Звук при напредък" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Промени по лентата за прогреса" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Включване на клавишите за пре_въртане при „Прочитане на всичко“" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" -"Включване на клавишите за _придвижване по структурата при „Прочитане на " -"всичко“" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "_Прочитане на всичко по:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Обявяване на _цитатите в карe при „Прочитане на всичко“" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Обявяване на _списъците при „Прочитане на всичко“" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Обявяване на _таблиците при „Прочитане на всичко“" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Обявяване на _панелите при „Прочитане на всичко“" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Обявяване на _формулярите при „Прочитане на всичко“" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Обявяване на _ориентирите при „Прочитане на всичко“" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "_Прочитане на всичко" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Представяне на елемента:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Общи" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Сила на _звука:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "В_исочина:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "Скорос_т:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Човек:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Език:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Речев _синтезатор:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Речева _система:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Вид на гласа:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Подсказване на _регистъра:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Настройки на вида глас" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Прочитане на низовете със смесен регистър като отделни _думи" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Прочитане на числата по _цифри" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Глобални настройки на гласа" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Глас" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Вкл_ючване на речта" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Пови_шена" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Многословност" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Всичко" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Ниво на пунктуация" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Прочитане само на текста от екрана" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Прочитане на празните редове" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Про_читане на отместването по ред и подравняването" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Прочитане на м_немониката на обекта" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Прочитане на позицията на _дъщерния елемент" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Прочитане на обучителните съобщения" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Подробни системни съобщения" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Прочитане на _цветовете като имена" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Обявяване на _цитатите в каре при придвижване" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Обявяване на _списъците при придвижване" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Обявяване на _таблиците при придвижване" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Прочитане на _индикацията за сгрешена дума" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Обявяване на _формулярите при придвижване" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Уведомяване за _формулярите при придвижване" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Уведомяване за _формулярите при придвижване" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Прочитене на _описанието" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Четене на цели редове в _електронните таблици" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Четене на цели редове в таблиците в _документа" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Четене на цели редове в таблиците от _интерфейса" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Контекст при изговаряне" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Реч" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Включване на поддръжка на _брайл" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Съкратени имена на видовете графични обекти" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Изключване на знака за _край на ред" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Таблица на съкращенията:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Включване на съкратения брайл" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "_Разделяне на редовете" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Настройки на показването" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "Ня_ма" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Индикатор за маркиран текст" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Индикатор за хипервръзка" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Съобщения по _брайл" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Про_дължителност [сек.]:" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "_Изрично скриване на съобщенията" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "_Подробни съобщения" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Настройки на съобщенията по брайл" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Брайл" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "_Включване на прочитането на клавиши" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Включване на клавишите за _букви" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Включване на клавишите за _цифри" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Включване на клавишите за _пунктуация" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Включване на клавиша за _интервал" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Включване на _модификаторите на клавиши" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Включване на _функционалните клавиши" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Включване на де_йстващите клавиши" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Включване на клавишите за _придвижване" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Прочитане по _думи" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Прочитане по _изречения" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Прочитане" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "_Клавиши-модификаторни за екранния четец:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Функции на клавишите" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Речник за прочитане" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Нов елемент" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Изтриване" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Прочитане" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Прочитане на всичко" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Нищо да не се прочита" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Изчистване" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Атрибути на текста" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Преместване в _края" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Преместване надо_лу" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Преместване на_горе" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Преместване в _началото" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Промяна на избраните атрибути" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Брайлов индикатор" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Атрибути на текста" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Активирай AI асистента" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Доставчик:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Локален - Безплатен)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Файл с _API ключ:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Път до файла с API ключ" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Вземи _Claude API ключ" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Отваряне на браузър за получаване на Claude API ключ и автоматично запазване" -"Отвори браузъра за получаване на Claude API ключ и автоматично запазване" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Изисквай потвърждение преди AI действия" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Модел Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Име на модела за Ollama (напр. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Крайна точка на Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL на крайната точка на Ollama API (напр. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Качество на екранната снимка:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Ниско" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Средно" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Високо" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI асистент" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Езиков код:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Мащабен коефициент:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Изображение в _нива на сивото" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Обърни изображението" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Черно-бяло изображение" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Праг черно/бяло:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Анализирай цветовете" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Копирай резултатите в _буфера" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a: алфа, b: браво, c: чарли, d: делта, e: еко, f: фокстрот, g: голф, h: " -"хотъл, i: индия, j: джулиет, k: кило, l: лима, m: майк, n: новембър, o: " -"оскар, p: папа, q: куебек, r: ромио, s: сиера, t: танго, u: юниформ, v: " -"виктор, w: уиски, x: ексрей, y: янки, z: зулу" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "цвят на фона" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "пълна височина на фона" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "шарка на фона" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "посока" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "редактируем" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "име на фамилията" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "основен цвят" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "основна шарка" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "шрифтов ефект" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "отстъп" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "грешка" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "невидим" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "подравняване" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "език" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "ляво поле" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "височина на реда" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "стил на абзаца" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "пиксели преди реда" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "пиксели под реда" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "пиксели между редовете" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "дясно поле" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "издигане" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "мащаб" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "размер" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "разтягане" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "зачертаване" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "стил" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "декорации на текста" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "завъртане на текста" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "сянка на текста" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "подчертаване" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "вариант" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "вертикално подравняване" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "чернота" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "режим на пренасяне" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "посока на писане" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "истина" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "лъжа" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "без" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "гравирано" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "релефно" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "контурно" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "надчертано" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "зачертано" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "мигане" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "черна сянка" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "единично" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "двойно" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "ниско" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "след знак" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "след дума" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "след знак" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "надясно" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "наляво" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "отляво" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "отдясно" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "центриране" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "без подравняване" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "запълване" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "съвсем сбито" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "много сбито" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "сбито" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "полусбито" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "нормално" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "полуразширено" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "разширено" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "много разширено" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "съвсем разширено" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "малки главни" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "наклонено" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "курсив" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Стандартен" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Текст" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Заглавие" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "по реда" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "като долен индекс" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "като горен индекс" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "отгоре" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "над текста" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "по средата" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "отдолу" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "под текста" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "наследяване" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "ЛД-ГД" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "ДЛ-ГД" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "ГД-ДЛ" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "ГД-ЛД" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "ДГ-ДЛ" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "ДГ-ЛД" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "ЛД" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "ДЛ" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "ГД" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "непрекъснато" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "правопис" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "За превключване натиснете интервал." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "За разгъване натиснете интервал, за избор — стрелките нагоре и надолу." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "За фокусиране на дъщерните прозорци натиснете Alt+F6." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"За придвижване към елемент използвайте стрелките или автоматичното дописване." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "За придвижване към системните менюта използвайте Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "За избор на елемент използвайте стрелките нагоре и надолу." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "За свиване използвайте Shift+стрелка наляво." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "За разгъване използвайте Shift+стрелка надясно." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "За активиране натиснете Enter." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Въведете текст." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" -"За разглеждането на другите подпрозорци използвайте стрелките наляво и " -"надясно." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "За активиране натиснете интервал." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"За избор на стойност използвайте стрелките нагоре и надолу или просто " -"въведете число." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "За промяна използвайте стрелките." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"За придвижване използвайте стрелките наляво и надясно, за избор на елемент " -"използвайте стрелките нагоре и надолу." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "За влизане в подменю използвайте стрелка надясно." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"За намаляване използвайте стрелка наляво, за увеличаване — стрелка надясно, " -"за минимума — Home, за максимума — End." diff --git a/po/bn.po b/po/bn.po deleted file mode 100644 index b8567f1..0000000 --- a/po/bn.po +++ /dev/null @@ -1,9859 +0,0 @@ -# Translation of cthulhu to Bengali -# This file is distributed under the same license as the cthulhu package. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. -# Runa Bhattacharjee , 2006. -# Maruf Ovee , 2009. -# Israt Jahan , 2010. -# Sadia Afroz , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: bn\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2010-03-28 15:30+0600\n" -"Last-Translator: Sadia Afroz \n" -"Language-Team: Bengali \n" -"Language: bn\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.9.1\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "অর্কা স্ক্রীন রিডার / বিবর্ধন" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "ডায়াল" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "ফর্ম" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "ইংক" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "রেডিও" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "ঘূর্ণন" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "টার্ম" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Czech গ্রেড ১" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "স্প্যানিশ গ্রেড ১" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "কানাডা ফ্রেঞ্চ গ্রেড ২" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "ফ্রান্স ফ্রেঞ্চ গ্রেড ২" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "ল্যাটভিন গ্রেড ১" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "নেদারল্যান্ড ডাচ গ্রেড ১" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "নরওয়ে গ্রেড ০" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "নরওয়ে গ্রেড ১" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "নরওয়ে গ্রেড ২" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "নরওয়ে গ্রেড ৩" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "পলিশ গ্রেড ১" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "পুর্তগীজ গ্রেড ১" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "সুইডিশ গ্রেড ১" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "অ্যারাবিক গ্রেড ১" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "ওয়েলস গ্রেড ১" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "ওয়েলস গ্রেড ২" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "জার্মান গ্রেড ০" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "জার্মান গ্রেড ১" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "জার্মান গ্রেড ২" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "U.K. ইংরেজী গ্রেড ২" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "U.K. ইংরেজী গ্রেড ১" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "U.S. রেজী গ্রেড ১" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "U.S. Eরেজী গ্রেড ২" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "কানাডা ফ্রেঞ্চ গ্রেড ১" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "ফ্রান্স ফ্রেঞ্চ গ্রেড ২" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "গ্রীক গ্রেড ১" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "হিন্দী গ্রেড ১" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -#, fuzzy -msgid "Hungarian Grade 1" -msgstr "ল্যাটভিন গ্রেড ১" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "জার্মান গ্রেড ২" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "ইতালীয় গ্রেড ১" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "বেলজিয়াম ডাচ গ্রেড ১" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "ফাঁকাস্থান" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "নিউলাইন" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "ট্যাব" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "বিস্ময়" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "উদ্ধৃতি" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "mnubr" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "ডলার" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "শতকরা" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "এবং" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "চিহ্ন" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "বাম বন্ধনী" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "ডান বন্ধনী" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "স্টার" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "যোগ" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "কমা" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "ড্যাশ" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "বিন্দু" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "স্ল্যাশ" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "কোলন" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "সমিকোলন" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "কম" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "সমান" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "বেশী" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "প্রশ্ন" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "তে" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "বাম বন্ধনী" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "ব্যাকস্ল্যাশ" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "ডান বন্ধনী" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "ক্যারেট" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "নিম্নরেখাঙ্কিত" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "গুরুতর" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "বাম বক্রবন্ধনী" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "উল্লম্ব লাইন" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "ডান বক্রবন্ধনী" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "টিলডা" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "ব্রেক স্পেস নেই" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "উলটানো বিস্ময় পয়েন্ট" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "সেন্ট" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "পাউন্ড" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "মুদ্রা চীহ্ন" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "ইয়েন" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "বিকৃত বার" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "শাখা" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "আলাদা ভাবে উচ্চারণের পদ্ধতি" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "স্বত্বাধিকার" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "বামের দ্বিগুন কৌনিক বন্ধনী" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "যৌক্তিক না" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "সফ্ট হাইফেন" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "রেজিষ্ট্রীকৃত" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "ডিগ্রী" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "যোগ অথবা বিয়োগ" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "ঊর্ধ্বলিপি ২" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "ঊর্ধ্বলিপি ৩" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "সূক্ষ্ম" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "অনুচ্ছেদ মার্কার" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "মধ্য বিন্দু" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "ঊর্ধ্বলিপি ১" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "অবস্থানসূচক সংখ্যা" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "ডানের দ্বিগুন কৌনিক বন্ধনী" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "এক চতুর্থাংশ" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "অর্ধেক" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "তিন চতুর্থাংশ" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "উল্টানো প্রশ্নবোধক চীহ্ন" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a একিউট" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "বার" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s সার্প" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "গ্রেভ" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a সারকামফ্লেক্স" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "টিলডা" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a রিং" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c সেডিলা" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "গ্রেভ" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e একিউট" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e সারকামফ্লেক্স" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i গ্রেভ" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i একিউট" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i সারকামফ্লেক্স" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n টিল্ডা" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o গ্রেভ" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o একিউট" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o সারকামফ্লেক্স" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o টিল্ডা" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "এর দ্বারা ভাহ করা হয়েছে" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o স্ট্রোক" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "থর্ন" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u একিউট" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u গ্রেভ" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u সারকামফ্লেক্স" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y একিউট" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "ফ্লোরিন" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en ড্যাশ" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "বাম একক উদ্ধৃতি" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "ডানের একক উদ্ধৃতি" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "একক নিম্ন উদ্ধৃতি" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "বাম দ্বিগুন উদ্ধৃতি" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "ডান দ্বিগুন উদ্ধৃতি" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "দ্বিগুন নিম্ন উদ্ধৃতি" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "ড্যাগার" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "ডবল ড্যাগার" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "বুলেট" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "ত্রিকোনোমিতিক বুলেট" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "প্রতি মাইল" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "প্রাইম" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "ডবল প্রাইম" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "ডবল প্রাইম" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "হাইফেন বুলেট" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "ইউরো" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "ট্রেডমার্ক" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "পরীক্ষণ চীহ্ন" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "ভারী পরীক্ষণ চীহ্ন" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-আকৃতির বুলেট" - -#: src/cthulhu/chnames.py:672 -#, fuzzy -msgid "superscript 0" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:676 -#, fuzzy -msgid "superscript 4" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:680 -#, fuzzy -msgid "superscript 5" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:684 -#, fuzzy -msgid "superscript 6" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:688 -#, fuzzy -msgid "superscript 7" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:692 -#, fuzzy -msgid "superscript 8" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:696 -#, fuzzy -msgid "superscript 9" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:700 -#, fuzzy -msgid "superscript plus" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:704 -#, fuzzy -msgid "superscript minus" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:708 -#, fuzzy -msgid "superscript equals" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:720 -#, fuzzy -msgid "superscript n" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:724 -#, fuzzy -msgid "subscript 0" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:728 -#, fuzzy -msgid "subscript 1" -msgstr "ঊর্ধ্বলিপি ১" - -#: src/cthulhu/chnames.py:732 -#, fuzzy -msgid "subscript 2" -msgstr "ঊর্ধ্বলিপি ২" - -#: src/cthulhu/chnames.py:736 -#, fuzzy -msgid "subscript 3" -msgstr "ঊর্ধ্বলিপি ৩" - -#: src/cthulhu/chnames.py:740 -#, fuzzy -msgid "subscript 4" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:744 -#, fuzzy -msgid "subscript 5" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:748 -#, fuzzy -msgid "subscript 6" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:752 -#, fuzzy -msgid "subscript 7" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:756 -#, fuzzy -msgid "subscript 8" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:760 -#, fuzzy -msgid "subscript 9" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:764 -#, fuzzy -msgid "subscript plus" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:772 -#, fuzzy -msgid "subscript equals" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "বাম বন্ধনী" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "ডান বন্ধনী" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "কালো বর্গ" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "কালো ডায়মন্ড" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "পরবর্তী অক্ষরে যান।" - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "বর্তমান আইটেমে পয়েন্টার রাউট করা হয়" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "বর্তমান ফ্ল্যাট পাকদর্শন আইটেমে বাম ক্লিক করুন" - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "বর্তমান ফ্ল্যাট পাকদর্শন আইটেমে ডান ক্লিক করুন" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "সম্পূর্ণ নথিটি পড়া হবে।" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ লাইন পড়ুন" - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "প্রাথমিক where am I অপারেশন চালায়" - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "বিস্তারিত where am I অপারেশন চালায়" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ লাইন পড়ুন" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "ফাঁকা লাইন পড়ুন" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "পরবর্তী বোতামে যান।" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "অবস্থা বার পড়া হবে" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "শিরোনাম বার পড়া হবে।" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "অর্কা সন্ধান ডায়ালগ খুলুন।" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "একটি স্ট্রিং এর পরবর্তী নিদর্শনের জন্য সন্ধান করুন" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "একটি স্ট্রিং এর পূর্ববর্তী নিদর্শনের জন্য সন্ধান করুন" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "ফ্ল্যাট নিরীক্ষণ মোডে প্রবেশ করুন এবং বের হয়ে যান।" - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "শেষ অবস্থানে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "হোম অবস্থানে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "শেষ অবস্থানে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "পূর্ববর্তী লাইনের শুরুতে ফ্ল্যাট নিরীক্ষণ সরান" - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ লাইন পড়ুন" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ লাইন বানান করুন।" - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "ফোনেটিকালি বর্তমান ফ্ল্যাট নিরীক্ষণ লাইন বানান করুন" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "পরবর্তী লাইনের শুরুতে ফ্ল্যাট নিরীক্ষণ সরান" - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "পূর্ববর্তী আইটেম অথবা শব্দে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ আইটেম অথবা শব্দ পড়ুন।" - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ আইটেম অথবা শব্দ বানান করুন।" - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "ফোনেটিকালি বর্তমান ফ্ল্যাট নিরীক্ষণ আইটেম অথবা শব্দ বানান করুন।" - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "পরবর্তী আইটেম অথবা শব্দে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "বর্তমান শব্দের উপরের শব্দে ফ্ল্যাট নিরীক্ষণ সরান" - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ বস্তু পড়ুন।" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "বর্তমান শব্দের নিচের শব্দে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "পূর্ববর্তী অক্ষরে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ অক্ষর পড়ুন।" - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "ফোনেটিকালি বর্তমান ফ্ল্যাট নিরীক্ষণ অক্ষর পড়ুন।" - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ অক্ষর পড়ুন।" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "পরবর্তী অক্ষরে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "লাইনের শেষে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "নিচের বামে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ আইটেম অথবা শব্দ পড়ুন।" - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "বর্তমান ফ্ল্যাট নিরীক্ষণ আইটেম অথবা শব্দ পড়ুন।" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "শেষ অবস্থানে ফ্ল্যাট নিরীক্ষণ সরান।" - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "বর্তমান সারণি ঘর অথবা সম্পূর্ণ সারি পড়তে হবে কি না টগল করুন।" - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "বর্তমান টেক্সট অক্ষরের সাথে সংশ্লিষ্ট বৈশিষ্ট্য পড়ুন।" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "বামে ব্রেইল প্রদর্শন পেন করুন।" - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "ডানে ব্রেইল প্রদর্শন পেন করুন।" - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "কীবোর্ড ফোকাস সহ বস্তুতে ফিরে যাও।" - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "কন্ট্রাকটেড ব্রেইল চালু অথবা বন্ধ করুন।" - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "একটি কার্সর রাউটিং কী প্রসেস করো।" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "একটি টেক্সট নির্বাচনের শুরু চিহ্নীত করুন।" - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "একটি টেক্সট নির্বাচনের শেষ চিহ্নীত করুন।" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "শেখার মোডে প্রবেশ করুন। শেখার মোড থেকে বের হতে এসকেপ চাপুন।" - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "স্বরের মাত্রা কমান।" - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "স্বরের মাত্রা বাড়ান।" - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "স্বরের পিচ কমান।" - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "স্বরের পিচ বাড়ান।" - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "স্বরের মাত্রা বাড়ান।" - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "স্বরের মাত্রা কমান।" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "কাঙ্খিত স্বর সার্ভার নির্বাচন করুন:" - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "কাঙ্খিত স্বর সার্ভার নির্বাচন করুন:" - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "স্বরের মাত্রা কমান।" - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "স্বরের মাত্রা বাড়ান।" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "স্পীচের নিরবতা টোগল করা হয়" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "মাউস নিরীক্ষন মোড টগল করুন।" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "পছন্দসমূহ কনফিগারেশন ডায়ালগ প্রদর্শন করুন।" - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "অ্যাপ্লিকেশন পছন্দসমূহ কনফিগারেশন ডায়ালগ প্রদর্শন করুন।" - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "ইনডেনশন এবং জাস্টিফিকেশন পড়ুন (_i)" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "পরবর্তী বিবর্ধন অবস্থানে সাইকেল লরুন।" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "পরবর্তী বিবর্ধন অবস্থানে সাইকেল লরুন।" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "পরবর্তী বিবর্ধন অবস্থানে সাইকেল লরুন।" - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "পরবর্তী বিবর্ধন অবস্থানে সাইকেল লরুন।" - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "পরবর্তী বিবর্ধন অবস্থানে সাইকেল লরুন।" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "চালনার সময় ডিবাগ স্তর ঘুরান।" - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "বর্তমান অবস্থানের ভিত্তিতে where am I বুকমার্ক করুন" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "পূর্ববর্তী বুকমার্ক অবস্থানে যান।" - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "বুকমার্কে যান।" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "পরবর্তী বুকমার্ক অবস্থানে যান।" - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "বুকমার্ক যোগ করুন।" - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "বুকমার্ক সংরক্ষণ করুন।" - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "মাউস নিরীক্ষন মোড টগল করুন।" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "বর্তমান অ্যাপ্লিকেশনের পরবর্তী কমান্ড পাঠান।" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "একটি পূর্ববর্তী আড্ডার আসরের বার্তা পড়ুন এবং ব্রেইল করুন।" - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "যখন আমাদের বন্ধুরা টাইপ করবে তখন আমরা ঘোষনা করবো কি না তা টগল করুন" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"আমরা আড্ডার আসরের কোনো সুনির্দিষ্ট বার্তার ইতিহাস প্রদান করবো কি না সেটি টগল করুন।" - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"আড্ডার আসরের নামে আমরা আড্ডার আসরের বার্তা প্রিফিক্স করবো কি না সেটি টগল করুন।" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "বামের লাইন" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "ডানের লাইন" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "উপরের লাইন" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "নিচের লাইন" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "ফ্রীজ" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "শীর্ষ বাম" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "নীচের অর্ধেক" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "কার্সরের অবস্থান" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "ছয় বিন্দু" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "কার্সারের রাউটিং" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "কাটা আরম্ভ হয়েছে" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "লাইনটি কাটুন" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "পরবর্তী অক্ষরে যান।" - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "পূর্ববর্তী অক্ষরে যান।" - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "পরবর্তী শব্দে যান।" - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "পূর্ববর্তী শব্দে যান।" - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "পরবর্তী লাইনে যান।" - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "পূর্ববর্তী লাইনে যান।" - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "ফাইলের শীর্ষে যান।" - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "ফাইলের নিচে যান।" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "লাইনের শুরুতে যান।" - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "লাইনের শেষে যান।" - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "পরবর্তী বস্তুতে যান।" - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "পূর্ববর্তী বস্তুতে যান।" - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "বর্তমান কমবো বাক্সকে প্রসারিত করে।" - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "গ্যাকো ন্যাটিভ এবং অর্কা ক্যারেট ন্যাভিগেশনের মাঝে পরিবর্তম করা হয়।" - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "উচ্চপর্যায়ের লাইভ রিজিওন পোলাইটনেস সেটিং।" - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "ডিফল্ট লাইভ রিজিওন পোলাইটনেস লেভেল বন্ধ করে।" - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "লাইভ রিজিওন ঘোষনা রিভিউ করে।" - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "লাইভ এলাকা মনিটর করুন।" - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "বর্তমান মাউসের কাছে বা দূরের ফোকাসের মাঝে সরায়।" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "" -"ক্যালক ঘর নিয়ে কাজ করার সময় ডাইনামিক কলাম শীর্ষচরণ হিসেবে ব্যবহারের জন্য সারি " -"নিযুক্ত করুন।" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "ডাইনামিক কলাম শিরলেখ পরিস্কার করুন।" - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"ক্যালক ঘর নিয়ে কাজ করার সময় ডাইনামিক সারি শীর্ষচরণ হিসেবে ব্যবহারের জন্য কলাম " -"নিযুক্ত করুন।" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "ডাইনামিক সারি শিরলেখ পরিস্কার করুন।" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "ইনপুট লাইনের বিষয়বস্তু পড়ুন।" - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "কাঠামোগত ন্যাভিগেশন কী টগল করুন।" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "পূর্ববর্তী ব্লককোট যাবে।" - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "পরবর্তী ব্লককোট যাবে।" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "পূর্ববর্তী বোতামে যান।" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "পরবর্তী বোতামে যান।" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "আরো অপশন প্রদর্শন করা হবে" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "পূর্ববর্তী পরীক্ষন বাক্সে যান" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "পরবর্তী পরীক্ষন বাক্সে যান।" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "পূর্ববর্তী সারণিতে যান।" - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "পরবর্তী শিরোনামে যান।" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "পূর্ববর্তী কম্বো বাক্সে যান।" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "পরবর্তী কম্বো বাক্সে যান।" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l ধারক" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l ধারক" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "পূর্ববর্তী এন্ট্রিতে যান।" - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "পরবর্তী এন্ট্রিতে যান।" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "পূর্ববর্তী ফর্ম ক্ষেত্রে যান।" - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "পরবর্তী ফর্ম ক্ষেত্রে যান।" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "পূর্ববর্তী শিরোনামে যান।" - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "পরবর্তী শিরোনামে যান।" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "স্তর %d এর পূর্ববর্তী শিরোনামে যান।" - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "স্তর %d এর পরবর্তী শিরোনামে যান।" - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "স্তর %d এ আর কোনো শিরোনাম নেই।" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "পূর্ববর্তী সারণিতে যান।" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "অভ্যন্তরীণ কাঠামো" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "পূর্ববর্তী লাইনে যান।" - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "পরবর্তী লাইনে যান।" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "পূর্ববর্তী ল্যান্ডমার্কে যান।" - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "পরবর্তী ল্যান্ডমার্কে যান।" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "পূর্ববর্তী বড় বস্তুতে যান" - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "পরবর্তী বড় বস্তুতে যান" - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "আরো কোনো বড় বস্তু নেই।" - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "পূর্ববর্তী লাইনে যান।" - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "পরবর্তী লাইনে যান।" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "আরো অপশন প্রদর্শন করা হবে" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "পূর্ববর্তী তালিকায় যান।" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "পরবর্তী তালিকায় যান।" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "পূর্ববর্তী তালিকা আইটেমে যান।" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "পূর্ববর্তী তালিকা আইটেমে যান।" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "পূর্ববর্তী লাইভ এলাকায় যান।" - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "পরবর্তী লাইভ এলাকায় যান।" - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "লাইভ রিজিওন ঘোষনা রিভিউ করে।" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "ফোকাস সহ বস্তুর ধরণ সম্পর্কে ডিবাগ তথ্য মুদ্রণ করুন।" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "কীবোর্ড ফোকাস সহ বস্তুতে ফিরে যাও।" - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "কাঠামোগত ন্যাভিগেশন কী টগল করুন।" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "পূর্ববর্তী অনুচ্ছেদে যান।" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "পরবর্তী অনুচ্ছেদে যান।" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "পূর্ববর্তী রেডিও বোতামে যান।" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "পরবর্তী রেডিও বোতামে যান।" - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "আর কোনো রেডিও বোতাম নেই।" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "পূর্ববর্তী বিভাজকে যায়।" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "পরবর্তী বিভাজকে যায়।" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "পূর্ববর্তী সারণিতে যান।" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "পরবর্তী শিরোনামে যান।" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "নিচে এক ঘর যান।" - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "সারণির প্রথম কক্ষে যান।" - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "সারণির শেষ কক্ষে যান।" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "বামে এক ঘর যান।" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "ডানে এক ঘর যান।" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "উপরে এক ঘর যান।" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "মাউস নিরীক্ষন মোড টগল করুন।" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "কী ইকো সক্রিয় করুন (_k)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "পূর্ববর্তী অপ্রদর্শিত লিংকে যান।" - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "পরবর্তী অপ্রদর্শিত লিংকে যান।" - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "আর কোনো অপ্রদর্শিত লিংক নেই।" - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "পূর্ববর্তী প্রদর্শিত লিংকে যান।" - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "পরবর্তী প্রদর্শিত লিংকে যান।" - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "আর কোনো প্রদর্শিত লিংক নেই।" - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "স্যাচুরেট নীল" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "কালো" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "কালো ডায়মন্ড" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "স্যাচুরেট নীল" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "স্যাচুরেট নীল" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "গ্রেভ" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "স্যাচুরেট সবুজ" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "স্যাচুরেট সবুজ" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "স্যাচুরেট লাল" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "স্যাচুরেট সবুজ" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "স্যাচুরেট নীল" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i গ্রেভ" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "ডিস্যাচুরেট সবুজ" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "ধূসরিত" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "ডিগ্রী" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "হিন্দী গ্রেড ১" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "ডান বক্রবন্ধনী" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "ডানের control কী" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "ডান বন্ধনী" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "ডান বক্রবন্ধনী" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "ডান বন্ধনী" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "ডান বন্ধনী" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "ডানের alt কী" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "ডান বন্ধনী" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "ডানের সুপার" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "ডান তীর" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "নিউলাইন" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "চিত্র" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "ডিস্যাচুরেট নীল" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "স্যাচুরেট লাল" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "স্যাচুরেট সবুজ" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "শেষ" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "স্যাচুরেট নীল" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s পর্দা" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "ডিস্যাচুরেট নীল" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "ডিস্যাচুরেট নীল" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "ট্যাব" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "শূণ্য স্থান" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "শূণ্য স্থান" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "পর্দাজুড়ে প্রদর্শন" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "বিন্দু ৭ (_7)" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "বিন্দু ৮ (_8)" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "বিন্দু ৭ এবং ৮ (_d)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "আইকন" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "একটিও না" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "বানান" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "আপনার বন্ধুরা টাইপ করার সময় দেখান" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "আড্ডার আসরের সুনির্দিষ্ট বার্তা ইতিহাস প্রদান করে (_m)" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "বার্তা পড়া হবে" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "সব চ্যানেল (_n)" - -#: src/cthulhu/guilabels.py:173 -#, fuzzy, python-format -msgid "All channels when an_y %s window is active" -msgstr "যেকোনো পিদিন উইন্ডো সক্রিয় থাকার সময় সব চ্যানেল (_y)" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "A channel only if its _window is active" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "আড্ডার আসরের নাম বলুন (_S)" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -#, fuzzy -msgid "double click" -msgstr "(ডবল ক্লিক)" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -#, fuzzy -msgid "triple click" -msgstr "(তিন ক্লিক)" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "ডিফল্ট সিনথেসাইজার" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "আসল ষ্ট্রিং" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "প্রতিস্থাপন ষ্ট্রীং" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "শব্দ দ্বারা ইকো সক্রিয় করুন (_r)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "ন্যাভিগেশন কী সক্রিয় করুন (_d)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "বর্তমান অবস্থান (_u)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "মিলে যাওয়া টেক্সটের সর্বনিম্ন দৈর্ঘ্য" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "অপশন খুঁজুন" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "শুধু লাইন অনুসন্ধানের সময় বলে (_y)" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "খোঁজার সময় ফলাফল পড়ুন (_f)" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "কমা" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "কী বাইন্ডিং" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "ডিফল্ট" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "লেখার মোড" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "শাখা" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ব্রেইল বাইন্ডিং" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "বুকমার্কগুলো সংরক্ষণ করা হয়েছে" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "সারণি পরিক্রমন" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "সীমাবদ্ধ নয়" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "ফ্ল্যাট নিরীক্ষণ থেকে বের হোন।" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "পরিবর্তিত" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "ডেস্কটপ (_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "বিজ্ঞতি %s" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "বিজ্ঞতি %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s-এর জন্য অর্কা পছন্দসমূহ" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "ব্রেইলে চিহ্নিত করুন" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "উপস্থিত যদিওবা" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "বক্তব্য" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "সব" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "অ্যাপ্লিকেশন" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "উইন্ডো" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "একটিও না (_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "কয়েকটি (_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "সর্বোচ্চ (_o)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "লাইন" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "বাক্য" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "উদ্ধৃতি" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "বোতাম" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "শিরোনাম" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "কম্বো বাক্স" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "শিরোনাম" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "শিরোনাম" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "চিত্র" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "লেবেল" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "ট্রেডমার্ক" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "সংযোগ" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "তালিকা" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "অনুচ্ছেদ" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "নির্বাচিত" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "অবস্থা" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "লেখ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "আর কোনো ব্লককোট নেই।" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "বোতাম" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "কম্বো বাক্স" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "শিরোনাম" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "চিত্র" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "স্তর %d এ আর কোনো শিরোনাম নেই।" - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "ট্রেডমার্ক" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "আরো কোনো বড় বস্তু নেই।" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "সংযোগ" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "তালিকা" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "অনুচ্ছেদ" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "সারণী" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d অপরিদর্শিত লিংক" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d পরিদর্শিত লিংক" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "পৃষ্ঠা নেভিগেশন" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Automatically start speaking a page when it is first _loaded" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "Automatically start speaking a page when it is first _loaded" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Break speech into ch_unks between pauses" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s ডিফল্ট ভয়েস" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "পূর্বনির্ধারিত" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "হাইপারলিংক" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "বড়হাতের লেখা" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "স্বর ডিসপ্যাচার" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "স্প্রেডশীট ঘর স্থানাংক পড়ুন" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "ঘর শিরলেখ ঘোষনা করুন (_h)" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "সারণি পরিক্রমন" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "ফাঁকা ঘর বাদ দিন" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "কক্ষ পড়া হবে (_c)" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "ঘর স্থানাংক পড়ুন (_c)" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "বহুবিধ ঘর স্প্যান পড়ুন (_m)" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "বৈশিষ্ট্যের নাম" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "অর্কা ক্যারেট ন্যাভিগেশন ব্যবহার করুন (_O)" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "কাঠামোগত ন্যাভিগেশন কী টগল করুন।" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "সংক্ষিপ্ত (_f)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "কোনো গাস্টিফিকেশন নেই" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt_R" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "বামের control কী" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "বামের shift কী" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "বামের alt কী" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "বামের control কী" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "ডানের alt কী" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "ডানের alt কী" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "ডানের control কী" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "বামের tab কী" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "ডানের মেটা" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "বামের tab কী" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "ব্যাকস্পেস" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "ফেরত" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "প্রবেশ" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "up" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "বাম" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "ডান" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "বামের সুপার" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "ডানের সুপার" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "মেনু" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "সহায়তা" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "বহুবিধ" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "মোড সুইচ" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "এসকেপ" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "প্রবেশ" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "মুছে ফেলা" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "হোম" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "শেষ" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "আরম্ভ" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "সারকামফ্লেক্স" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "চক্র" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "স্ট্রোক" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "বিয়োগ" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "প্রবেশ" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "ক্যাপস_লক" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "সুপার" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "মেটা২" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "গাঢ়" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "তির্যক" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "কর্মপরিসর" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "কনটেক্সট %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "বাম তীর" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "তীর" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "ডান তীর" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "তীর" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "ডান তীর" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "ডান তীর" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "ডান তীর" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "বাম তীর" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "বাম তীর" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "ডান তীর" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "বাম দ্বিগুন উদ্ধৃতি" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "ডবল ড্যাগার" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "ডান দ্বিগুন উদ্ধৃতি" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "ডবল ড্যাগার" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "ডান দ্বিগুন উদ্ধৃতি" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "ডান-তীর" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "ডান-তীরের পয়েন্টিং অগ্রভাগ" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "বিয়োগ" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "কম" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "বেশী" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "সারকামফ্লেক্স" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "বিন্দু" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "উল্লম্ব প্রান্তিককরণ" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "অনুভূমিক" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "autocomplete" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "ফাঁকা" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "সক্রিয়কৃত (_d)" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "সারির শেষ।" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "বিষয়" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "যোগ অথবা বিয়োগ" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "যোগ" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "বিয়োগ" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "বিভাজক" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "ঘনমূল" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "আনুপাতিক" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "অসীমতা" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "ডানের alt কী" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "একক" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "স্তরকৃত পেন" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "উল্লম্ব প্রান্তিককরণ" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "এর দ্বারা ভাহ করা হয়েছে" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "বিভাজক" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "সমান নয়" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "যৌক্তিক না" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "যৌক্তিক না" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "দিকবিন্যাস" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "অভ্যন্তরীণ কাঠামো" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "ডবল প্রাইম" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "আনুপাতিক" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "বিয়োগ" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "টিলডা" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n টিল্ডা" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n টিল্ডা" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "প্রায়ই সমান" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "প্রায়ই সমান" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "প্রায়ই সমান" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "প্রায়ই সমান" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "প্রায়ই সমান" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "প্রায়ই সমান" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "টিলডা" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "প্রায়ই সমান" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "ভিন্ন সাইট" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "সমান নয়" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "সমান" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "সমান" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "সমান নয়" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "সমান নয়" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "ত্রিকোনোমিতিক বুলেট" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "সমান" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "সমান নয়" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "সমান নয়" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "উল্লম্ব লাইন" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "সমান নয়" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "সমান নয়" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "বেশী" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "চাপানো হয়নি" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "বহু-নির্বাচিত" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "রেখার উচ্চতা" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "বহু-নির্বাচিত" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "সমান" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "en ড্যাশ" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "যোগ অথবা বিয়োগ" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "ডানের মেটা" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "বামের tab কী" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "down" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "শাখা" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "সত্য" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "সত্য" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "অবস্থানসূচক সংখ্যা" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "চিত্র" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "বহুবিধ" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "অভ্যন্তরীণ কাঠামো" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "সাধারণ" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ডানের একক উদ্ধৃতি" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "ডান বক্রবন্ধনী" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "বিভাজক" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "যৌক্তিক না" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "যৌক্তিক না" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "ডবল প্রাইম" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "ডবল প্রাইম" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "দিকবিন্যাস" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "ডবল প্রাইম" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "এর থেকে ছোট অথবা সমান" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "এর থেকে বড় অথবা সমান" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "উল্লম্ব প্রান্তিককরণ" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "বাম বন্ধনী" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "ডান বন্ধনী" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "বামের alt কী" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "ডানের alt কী" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "বাম বক্রবন্ধনী" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "নিম্ন" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "বামের দ্বিগুন কৌনিক বন্ধনী" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "ডানের দ্বিগুন কৌনিক বন্ধনী" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "মধ্য বিন্দু" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "বর্গমূল" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "কালো বর্গ" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "সাদা বর্গ" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "কালো ডায়মন্ড" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "সাদা বৃত্ত" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "কানো বৃত্ত" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "সাদা বুলেট" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "কালো বর্গ" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "নিম্নরেখাঙ্কিত" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "উল্লম্ব প্রান্তিককরণ" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "অ্যাপ্লিকেশন" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "ফাঁকা" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "গাঢ়" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "বুকমার্ক প্রবেশ করানো হয়েছে" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "বুকমার্কগুলো সংরক্ষণ করা হয়েছে" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "বুকমার্কগুলো সংরক্ষণ করা যাবেনা" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "কোনো ল্যান্ডমার্ক পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "কোনো ল্যান্ডমার্ক পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "বাইপাস মোড সক্রিয় করা হয়েছে।" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "ক্যালকুলেটর দেখতে ব্যর্থ" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "icon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "একটিও না" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "বানান" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "গ্যাকো ক্যারেট নিয়ন্ত্রণ করছে।" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "অর্কা ক্যারেট নিয়ন্ত্রণ করছে" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "কক্ষ %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "অনির্বাচিত" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "অপশনের ব্যবহার রোধ করুন" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "অপশন ব্যবহার করতে বাধ্য করুন" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "পরিচিতি চলমান অ্যাপ্লিকেশন মুদ্রণ করুন" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "বুকমার্কগুলো সংরক্ষণ করা যাবেনা" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "ব্যবহারকারী পছন্দসমূহের জন্য বিকল্প ডিরেক্টরী ব্যবহার করুন" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "পরিচিতি চলমান অ্যাপ্লিকেশন মুদ্রণ করুন" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "Replace a currently running Cthulhu" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "এই সহায়ক বার্তাটি প্রদর্শন করুন" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Send debug output to the specified file" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "ব্যবহারকারীর পছন্দগুলো সেটআপ করুন (পাঠ সংস্করণ)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "ব্যবহারকারীর পছন্দগুলো সেটআপ করুন (পাঠ সংস্করণ)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "বাগ https://groups.io/g/stormux এ প্রতিবেদন করুন।" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "সূক্ষ্ম" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "দ্রুত।" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "আপনার বন্ধু টাইপ করার সময় জানানো হবে না।" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "আপনার বন্ধু টাইপ করার সময় জানানো হবে।" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "আড্ডার আসর %s এর বার্তা" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "নতুন আড্ডা ট্যাব %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "আড্ডার আসরের নাম বলবেন না।" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "আড্ডার আসরের নাম বলুন।" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "আড্ডার আসরের সুনির্দিষ্ট বার্তা ইতিহাস প্রদান করবেন না।" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "আড্ডার আসরের সুনির্দিষ্ট বার্তা ইতিহাস প্রদান করে।" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "মুছে ফেলা" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "প্রবেশ" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "প্রশ্ন" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "সারণির শেষ" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "সারণিতে নয়।" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "নির্বাচিত নয়" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "ডিফল্ট বোতাম %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "ডিফল্ট বোতাম %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "ডিফল্ট বোতাম %s" - -#: src/cthulhu/messages.py:518 -#, fuzzy, python-format -msgid " subscript %s" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/messages.py:524 -#, fuzzy, python-format -msgid " superscript %s" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "সারণিতে নয়।" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "সম্পূর্ণ নথি নির্বাচিত হয়েছে" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "সম্পূর্ণ নথি নির্বাচিত হয়েছে" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "কার্সরের অবস্থানে থেকে নথি নির্বাচন করা হয়েছে" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "কার্সরের অবস্থানে থেকে নথি অনির্বাচন করা হয়েছে" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "কার্সরের অবস্থানে নথি নির্বাচন করা হয়েছে" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "কার্সরের অবস্থানে নথি অনির্বাচন করা হয়েছে" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "সারি %d এর জন্য কলাম শিরলেখ নির্ধারণ করা হয়েছে" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "ডাইনামিক কলাম শিরলেখ পরিস্কার করা হয়েছে।" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "কলাম %s এর জন্য কলাম শিরলেখ নির্ধারণ করা হয়েছে" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "ডাইনামিক সারি শিরলেখ পরিস্কার করা হয়েছে।" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ফাঁকা" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f কিলোবাইট" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f মেগাবাইট" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "কোনো ফাইল পাওয়া পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "ফ্ল্যাট নিরীক্ষণে প্রবেশ করুন।" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "ফ্ল্যাট নিরীক্ষণে প্রবেশ করুন।" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "ফ্ল্যাট নিরীক্ষণ থেকে বের হোন।" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "বর্তমান শব্দের উপরের শব্দে ফ্ল্যাট নিরীক্ষণ সরান" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "সূত্র আছে" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "ডায়ালগ" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "পপআপ মেনু" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "চিত্র ম্যাপ লিংক" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "The key entered is already bound to %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Key captured: %s. Press enter to confirm." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "নতুন কী: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "কী বাইন্ডিং মুছে ফেলা হয়েছে। নিশ্চিত করতে এন্টার চাপুন।" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "কীবাইন্ডিং মুছে ফেলা হয়েছে" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "নতুন কী প্রবেশ করান" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "একটিও না" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "পরবর্তী শব্দে যান।" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "বাক্য" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "বাক্য দ্বারা ইকো সক্রিয় করুন (_s)" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "শব্দ" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "পরবর্তী শব্দে যান।" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "কানো বৃত্ত" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "অনুভূমিক" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "উল্লম্ব লাইন" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "ডান তীর" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "নিম্নে মোড়ানো হচ্ছে" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "রেখার উচ্চতা" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "এবং" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "ঊর্ধ্বরেখা" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "বর্গমূল" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "ঘনমূল" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "রুট পেন" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "রুট পেন" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "রুট পেন" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "ঊর্ধ্বলিপি a" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "সারণী" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "ট্রি সারণি" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "প" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "সক্রিয়কৃত (_d)" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "ইনডেনশন এবং জাস্টিফিকেশন পড়ুন (_i)" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "সক্রিয়কৃত (_d)" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "ইনডেনশন এবং জাস্টিফিকেশন পড়ুন (_i)" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "শেখার মোডে প্রবেশ করুন। বের হতে এসকেপ কী চাপুন।" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "অ্যানিমেশন" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "পৃষ্ঠা নেভিগেশন" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "সারণি পরিক্রমন" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "ফ্ল্যাট নিরীক্ষণ থেকে বের হোন।" - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "সারণিটি বাদ দিন।" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "কার্সর অবস্থানে থেকে নিচে লাইন নির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "কার্সর অবস্থানে থেকে উপরে লাইন নির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "কার্সর অবস্থানে থেকে নিচে লাইন অনির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "কার্সর অবস্থানে থেকে উপরে লাইন অনির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "শেখঅর মোড বন্ধ করা হচ্ছে।" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "পূর্বের কারসার অবস্থান হতে শুরু পর্যন্ত লাইন নির্বাচন করা হয়" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "পূর্বের কারসার অবস্থান হতে শেষ পর্যন্ত লাইন নির্বাচন করা হয়" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "লিংক" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "একই পৃষ্ঠা" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "একই সাইট" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "ভিন্ন সাইট" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s লিংক %(file)s তে" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s লিংক" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d পরিদর্শিত লিংক" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "লাইভ এলাকা বন্ধে নির্ধারণ করা হয়েছে" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "লাইভ এলাকার politeness মাত্রা পুনরুদ্ধার করা হয়েছে" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "politeness মাত্রা %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "লাইভ এলাকা assertive (এসার্টিভ) নির্ধারণ করা হচ্ছে" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "লাইভ এলাকা off (বন্ধ) নির্ধারণ করা হচ্ছে" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "লাইভ এলাকা polite (পোলিট) নির্ধারণ করা হচ্ছে" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "লাইভ এলাকা rudee (রিউড) নির্ধারণ করা হচ্ছে" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "লাইভ এলাকা সমর্থন বন্ধ করুন" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "লাইভ এলাকা সমর্থন চালু করুন" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "কোনো লাইভ বার্তা সংরক্ষিত নেই" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "লাইভ এলাকা সমর্থন বন্ধ করুন" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "কোনো ফাইল পাওয়া পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "বর্তমান অবস্থান খুঁজে পাওয়া যাচ্ছেনা।" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "বন্ধ" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "চালু" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "শব্দের ভুল বানান" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "শব্দের ভুল বানান: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "কনটেক্সট %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "পরবর্তী বস্তুতে যান।" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "বস্তুর উপরে মাউস পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "মাউস বর্ধিতকরণ নিস্ক্রিয় করা হয়েছে।" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "মাউস বর্ধিতকরণ সক্রিয় করা হয়েছে।" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d শতকরা।" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "পূর্ববর্তী শব্দে যান।" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "নেস্টিং স্তর %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "নতুন আইটেম যোগ হয়েছে" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "কোনো অ্যাপ্লিকেশন ফোকাস করা হয়নি।" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "কোনো ফোকাস নেই" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "কোনো অ্যাপ্লিকেশন ফোকাস করা হয়নি।" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "আর কোনো ব্লককোট নেই।" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "আর কোনো বোতাম নেই" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "আরো কোনো পরীক্ষন বাক্স নেই।" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "আরো কোনো বড় বস্তু নেই।" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "আর কোনো সারণি নেই।" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "আর কোনো কম্বো বাক্স নেই।" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "আর কোনো এন্ট্রি নেই।" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "আর কোনো ফর্ম ক্ষেত্র নেই।" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "আর কোনো শিরোনাম নেই" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "স্তর %d এ আর কোনো শিরোনাম নেই।" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "অভ্যন্তরীণ কাঠামো" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "আর কোনো সারণি নেই।" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "কোনো ল্যান্ডমার্ক পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "আর কোনো তালিকা নেই।" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "আর কোনো তালিকা নেই।" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "আর কোনো তালিকা আইটেম নেই।" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "আর কোনো লাইভ এলাকা নেই।" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "আর কোনো অনুচ্ছেদ নেই।" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "আর কোনো রেডিও বোতাম নেই।" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "আর কোনো বিভাজক নেই।" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "আর কোনো সারণি নেই।" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "আর কোনো অপ্রদর্শিত লিংক নেই।" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "আর কোনো প্রদর্শিত লিংক নেই।" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "নির্বাচিত নয়" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "সারণিতে নয়।" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "বিজ্ঞতি %s" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "নীচে: (_B)" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "উপরে: (_T)" - -#: src/cthulhu/messages.py:2013 -#, fuzzy -msgid "No notification messages" -msgstr "বিজ্ঞতি %s" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "শব্দ" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "মাল্টিকেস স্ট্রিং শব্দ হিসেবে পড়ুন" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "বন্ধ" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "চালু" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "লোডিং। অনুগ্রহ করে অপেক্ষা করুন।" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "লোড করা শেষ হয়েছে।" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s লোড করা শেষ হয়েছে।" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "কার্সর অবস্থান থেকে পৃষ্ঠা নির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "কার্সর অবস্থানে পৃষ্ঠা নির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "কার্সর অবস্থান থেকে পৃষ্ঠা অনির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "কার্সর অবস্থানে পৃষ্ঠা অনির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "কার্সর অবস্থান থেকে পৃষ্ঠা নির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "কার্সর অবস্থান থেকে পৃষ্ঠা নির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "কার্সর অবস্থান থেকে পৃষ্ঠা অনির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "কার্সর অবস্থান থেকে পৃষ্ঠা অনির্বাচিত করা হয়েছে" - -#: src/cthulhu/messages.py:2127 -#, fuzzy -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"আপনার ইতেমধ্যে অর্কা পছন্দ ডায়ালগের একটি দৃষ্টান্ত খোলা আছে।\n" -"\n" -"অনুগ্রহ করে অন্য একটি খোলার আগে এটি বন্ধ করুন।" - -#: src/cthulhu/messages.py:2132 -#, fuzzy, python-format -msgid "slide %(position)d of %(count)d" -msgstr "on %(index)d of %(total)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "কোনো ফাইল পাওয়া পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "অগ্রগতি বার %d।" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "সব" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr " যতিচিহ্ন স্তর" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "একটিও না" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "সন্ধান চলছে।" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "সন্ধান সম্পন্ন।" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "অর্কা ব্যবহারকারী সেটিংস পুনরায় লোড করা হয়েছে।" - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "কনটেক্সট %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "কাঙ্খিত ভয়েসটি নির্বাচন করুন:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "অনির্বাচিত" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "স্বর নিষ্ক্রিয় করা হয়েছে।" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "স্বর সক্রিয় করা হয়েছে।" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "দ্রুত।" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "ধীর" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "উচ্চতর।" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "নিম্নতর।" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "দ্রুত।" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "মাত্রা: (_R)" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "ভলিউম: (_l)" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "স্বর ডিসপ্যাচার" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "স্বর ডিসপ্যাচার" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "কোনো সার্ভার বিদ্যমান নেই।\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "কোনো ভয়েস বিদ্যমান নয়।\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "স্বর সক্রিয় করা হয়েছে।" - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "স্বর ব্যবহার করা হবেনা।\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " বিন্দু বিন্দু বিন্দু" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "অর্কা'র বৈশিষ্ট্য" - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "অর্কা ক্যারেট নিয়ন্ত্রণ করছে" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "বাইপাস মোড সক্রিয় করা হয়েছে।" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "স্বর বিদ্যমান নয়" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "কোনো ফাইল পাওয়া পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "স্ট্রিং পাওয়া যায়নি" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "স্ট্রিং পাওয়া যায়নি" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "কাঠামোগত ন্যাভিগেশন কী বন্ধ করুন।" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "কাঠামোগত ন্যাভিগেশন কী চালু করুন।" - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "কোনো ফাইল পাওয়া পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "সারি %(row)d, কলাম %(column)d।" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "সারণির শেষ" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "কক্ষ পড়া হবে " - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "সারি পড়া হবে " - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "একক-নয়" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "সারণিতে নয়।" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ColumnHeader" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "কলাম %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "column %(index)d of %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "স্তম্ভের নিচ" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "স্তম্ভের শীর্ষ" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "অনির্বাচিত" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "অনির্বাচিত" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "সারি %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "row %(index)d of %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "সারির শুরু।" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "সারির শেষ।" - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "মুছে ফেলা" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -#, fuzzy -msgid "Row inserted." -msgstr "প্রবেশ" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "লাইনের শেষে যান।" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "নির্বাচিত নয়" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "অনির্বাচিত" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "অনির্বাচিত" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "ইউনিকোড %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "%s-এর জন্য অর্কা পছন্দসমূহ" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "শূণ্য স্থান" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "নিম্নে মোড়ানো হচ্ছে" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "উপরে মোড়ানো হচ্ছে।" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "০ বার" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, fuzzy, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Cell spans %d rows" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d স্তম্ভ" - -#: src/cthulhu/messages.py:2593 -#, fuzzy, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Cell spans %d columns" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d অনেক দীর্ঘ্য অক্ষর" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d ডায়ালগ)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d ফোকাস বিহীন ডায়ালগ" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d বাইট" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ফাইল পাওয়া গেছে" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d ফর্ম" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d শিরোনাম" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d আইটেম" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "কোনো ল্যান্ডমার্ক পাওয়া যায়নি।" - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d ফাইল পাওয়া গেছে" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "আর কোনো ব্লককোট নেই।" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "ফ্ল্যাট নিরীক্ষণ থেকে বের হোন।" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d আইটেম সহ তালিকা" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "%d আইটেম সহ তালিকা" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] " %d সারি সহ সারণি" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d স্তম্ভ" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] " %d সারি সহ সারণি" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d শতকরা।" - -#: src/cthulhu/messages.py:2764 -#, fuzzy, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "নথির শতকরা %d পড়া হয়েছে" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "পিক্সেল" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s অক্ষর" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d of %(total)d আইটেম নির্বাচিত" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d ফাঁকা স্থান" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d ট্যাব" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d সারণি" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%(rows)d সারি এবং %(columns)d কলাম সহ সারণি।" - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] " %d সারি সহ সারণি" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "সেকেন্ড" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d অপরিদর্শিত লিংক" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d পরিদর্শিত লিংক" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "টগল" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "on %(index)d of %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d of %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "LEVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "tree level %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "প্রশ্ন" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "কম্বো বাক্স" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html বিষয়বস্তু" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "শব্দ" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "কোলন" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "ঊর্ধ্বরেখা" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "দিকবিন্যাস" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "অনুচ্ছেদ" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "শব্দ" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "ইনডেন্ট" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "দিকবিন্যাস" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "ট্যাব তালিকা" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "উদ্ধৃতি" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "html বিষয়বস্তু" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s স্তর %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "অনুভূমিক" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "উল্লম্ব লাইন" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "অনুভূমিক" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "উল্লম্ব প্রান্তিককরণ" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "অনুভূমিক" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "উল্লম্ব প্রান্তিককরণ" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "মোড সুইচ" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "আইকন প্যানেল" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "html বিষয়বস্তু" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "অ্যানিমেশন" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "html বিষয়বস্তু" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "অ্যানিমেশন" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "সন্ধান চলছে।" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d পরিদর্শিত লিংক" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "ঘূর্ণন বোতাম" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "সংকুচিত" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "প্রসারিত" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "অনুভূমিক" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "উল্লম্ব লাইন" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "পরীক্ষিত" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "পরীক্ষিত নয়" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "চালু" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "বন্ধ" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "আংশিক পরীক্ষিত" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "চাপা হয়েছে" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "চাপানো হয়নি" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "নির্বাচিত নয়" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "নির্বাচিত নয়" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "নির্বাচিত নয়" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d পরিদর্শিত লিংক" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d অপরিদর্শিত লিংক" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ধূসরিত" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "শুধুমাত্র পড়ার জন্য" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "rdonly" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "প্রয়োজন" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "বহু-নির্বাচিত" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "অকার্যকর" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "অকার্যকর" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "বানান" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "বানান" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "অকার্যকর" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "খুঁজুন" - -# ovee -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "স্ক্রীন রিডার এবং ম্যাগনিফায়ার" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "বন্ধ" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "খুঁজুন" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "অনুসন্ধান করুন: (_S)" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "অনুসন্ধান করুন:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "উইন্ডোর শীর্ষে (_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "উইন্ডোর শীর্ষ" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "এখান থেকে শুরু:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "চারদিকে মোড়ান (_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "পিছন দিকে অনুসন্ধান করুন (_b)" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "দিকবিন্যাস" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "সমন্বয় কেস (_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "শুধুমাত্র সম্পূর্ণ শব্দ মেলান (_e)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "অপশন খুঁজুন" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "ডিফল্ট" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "বড় ছাঁদের হরফ" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "হাইপারলিংক" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "অ্যাপ্লিকেশন" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "উইন্ডো" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "অর্কা'র বৈশিষ্ট্য" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "ল্যাপটপ (_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "কীবোর্ড বহির্বিন্যাস" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "এখান থেকে শুরু:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "বর্তমান টুলটিপস (_P)" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "মাউসের অভ্যন্তরের বস্তু পড়ুন (_u)" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "সব পড়া হবে (_S)" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "ব্রেইল বাইন্ডিং" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -#, fuzzy -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "ফ্রিকোয়েন্সী (সেকেন্ডে):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "অ্যাপ্লিকেশন" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "অগ্রগতি বার আপডেট" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "কাঠামোগত ন্যাভিগেশন কী টগল করুন।" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "যা দ্বারা সব বলা হবে: (_y)" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "যা দ্বারা সব বলা হবে: (_y)" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "সাধারণ" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "ভলিউম: (_l)" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "পিচ: (_t)" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "মাত্রা: (_R)" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "ব্যক্তি: (_P)" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "ভাষা" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "স্পীচ সিনথেসাইজার: (_z)" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "স্বর সিস্টেম: ( _s)" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "ভয়েস সেটিংস: (_V)" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "ভয়েস সেটিংস: (_V)" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "মাল্টিকেস স্ট্রিং শব্দ হিসেবে পড়ুন" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "ভয়েস সেটিংস: (_V)" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "স্বর সক্রিয় করুন (_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Ver_bose" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "ভার্বোসিটি" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "সমগ্র (_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr " যতিচিহ্ন স্তর" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "ফাঁকা লাইন পড়ুন" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "ইনডেনশন এবং জাস্টিফিকেশন পড়ুন (_i)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Spea_k object mnemonics" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "চাইল্ড অবস্থান বলা হয় (_o)" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "টিউটোরিয়াল বার্তা পড়ুন" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "ঘর স্থানাংক পড়ুন (_c)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "ঘর স্থানাংক পড়ুন (_c)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "চাইল্ড অবস্থান বলা হয় (_o)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "স্বর" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "ব্রেইল সমর্থন সক্রিয় করা হয়েছে (_s)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "সংক্ষিপ্ত রোলের নাম (_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Disable _end of line symbol" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Contraction _Table:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "সংকুচিত ব্রেইল সক্রিয় করুন (_E)" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "কিনারা সক্রিয় করুন" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "আরো অপশন প্রদর্শন করা হবে" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "একটিও না (_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "নির্বাচন নির্দেশক" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "হাইপারলিংক নির্দেশক" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "বিবর্ধন সক্রিয় করুন (_m)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ব্রেইল" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "কী ইকো সক্রিয় করুন (_k)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "ন্যাভিগেশন কী সক্রিয় করুন (_n)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "বিশেষক কী সক্রিয় করুন (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "ফাংশন কী সক্রিয় করুন (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "স্বর সক্রিয় করুন (_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "বিশেষক কী সক্রিয় করুন (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "ফাংশন কী সক্রিয় করুন (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "কাজের কর সক্রিয় করুন ৯_t)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "ন্যাভিগেশন কী সক্রিয় করুন (_n)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "শব্দ দ্বারা ইকো সক্রিয় করুন (_s)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "বাক্য দ্বারা ইকো সক্রিয় করুন (_s)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "কী ইকো" - -# ovee -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "স্ক্রীন রিডার এবং ম্যাগনিফায়ার" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "কী বাইন্ডিং" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "উচ্চারণ অভিধান" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "নতুন এন্ট্রি (_N)" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "মুছে ফেলা (_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "উচ্চারণ" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "সব পড়া হবে (_S)" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "কোনোটিই পড়া হবেনা (_n)" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "রিসেট (_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "লেখ বৈশিষ্ট্য" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "নিচে যান (_b)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "এক ধাপ নিচে নামুন (_d)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "এক ধাপ উপরে উঠুন (_u)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "উপরে যান (_b)" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "" -"নির্বাচিত বৈশিষ্ট্য\n" -"সমন্বয় করুন" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "ব্রেইল নির্দেশক" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "লেখ বৈশিষ্ট্য" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "সহকারী" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "নিম্ন" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "সহকারী" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "ভাষা" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "ইয়েন" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "স্কেল ফ্যাক্টর: (_f)" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "প্রেক্ষাপটের রং" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "প্রেক্ষাপটের সম্পূর্ণ উচ্চতা" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "প্রেক্ষাপট স্টিপল" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "দিকবিন্যাস" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "সম্পাদনারযোগ্য" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "পারিবারিক নাম" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "পুরোভূমি রং" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "পুরোভূমি স্টিপল" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "ফন্ট প্রভাব" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "ইনডেন্ট" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "ভুল" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "অদৃশ্য" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "রেখার উচ্চতা" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "ভাষা" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "বাম প্রান্ত" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "রেখার উচ্চতা" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "অনুচ্ছেদ শৈলী" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "লাইনের উপরের পিক্সেল" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "লাইনের নিচের পিক্সেল" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "মোড়ানোর ভিতরের পিক্সেল" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "ডান প্রান্ত" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "উঠা" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "স্কেল" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "আকার" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "প্রসারিত করুন" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "মাঝ বরাবর" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "শৈলী" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "টেক্সট অলঙ্করণ" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "টেক্সট ঘূর্ণন" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "টেক্সট ছায়া" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "নিম্নরেখা" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "ভ্যারিয়েন্ট" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "উল্লম্ব প্রান্তিককরণ" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "ওজন" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "মোড়ানো মোড" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "লেখার মোড" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "সত্য" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "মিথ্যা" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "একটিও না" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "খোদাই করা" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "এমবোস" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "সীমারেখা" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "ঊর্ধ্বরেখা" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "রেখা বরাবর" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "মিটিমিটি জ্বলা" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "কালো" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "একক" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "দ্বিগুন" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "নিম্ন" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "অক্ষর" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "শব্দ" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "অক্ষর" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "বাম" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "ডান" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "কেন্দ্র" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "কোনো গাস্টিফিকেশন নেই" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "পূরণ করা" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "অতিরিক্ত সংক্ষিপ্ত" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "অতিরিক্ত সংক্ষিপ্ত" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "সংক্ষিপ্ত" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "অর্ধ সংক্ষিপ্ত" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "সাধারণ" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "অর্ধ প্রসারিত" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "প্রসারিত" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "অতিরিক্ত প্রসারিত" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "অতি প্রসারিত" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "ছোট ক্যাপ" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "বাঁকানো" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "তির্যক" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "ডিফল্ট" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "টেক্সট বডি" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "শিরোনাম" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "বেসলাইন" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "বিষয়" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "সুপার" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "শীর্ষ" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "টেক্সট-শীর্ষ" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "মধ্য" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "নিম্ন" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "টেক্সট-বোতাম" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "ইনহেরিট" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "গাঢ়" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "বানান" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "টগল করার জন্য স্পেস চাপুন।" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"বর্ধিত করতে স্পেস চাপুন, এবং একটি আইটেম নির্বাচন করতে up এবং down ব্যবহার করুন।" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "চাইল্ড উইন্ডোতে ফোকাসের জন্য alt+f6 চাপুন।" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "আইটেমে যেতে, তীর চিহ্নিত কী বা অনুসন্ধান ব্যবহার করুন।" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "সিস্টেম মেনুর জন্য alt+f1 কী চাপুন।" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "একটি আইটেম নির্বাচন করতে up এবং down ব্যবহার করুন।" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "ভাঁজ হয়ে গুটানোর জন্য, শিফ্টের সাথে বাম চাপুন।" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "বর্ধিত করতে, শিফ্ট সহ ডান চাপুন।" - -#: src/cthulhu/tutorialgenerator.py:397 -#, fuzzy -msgid "To activate press return." -msgstr "সক্রিয় করতে স্পেস চাপুন।" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "টেক্সটে টাইপ করুন।" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "অন্য ট্যাব বাম এবং ডান ব্যবহার করুন।" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "সক্রিয় করতে স্পেস চাপুন।" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"মান নির্বাচন করতে up অথবা down তীর ব্যবহার করুন। অথবা কাঙ্খিত সংখ্যাসূচক মান টাইপ " -"করুন।" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "পরিবর্তন করতে তীর কী ব্যবহার করুন" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"ন্যাভিগেট করতে, বাম বা ডান তীর চিহ্নিত কী চাপুন। আইটেম সরাতে নিচের বা উপরের তীর " -"চিহ্নিত কী চাপুন।" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "সাব মেনু প্রবেশ করাতে, ডান তীর চাপুন।" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"কমাতে বাম তীর চিহ্ন, বাড়াতে ডান তীর চিহ্ন চাপুন। সর্বনিম্ন পেতে home চাপুন, এবং " -"সর্বোচ্চ পেতে end চাপুন।" diff --git a/po/bn_IN.po b/po/bn_IN.po deleted file mode 100644 index 616378b..0000000 --- a/po/bn_IN.po +++ /dev/null @@ -1,9379 +0,0 @@ -# translation of cthulhu.HEAD.pot to Bangl -# This file is distributed under the same license as the cthulhu package. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. -# Runa Bhattacharjee , 2006. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2006-06-27 13:08+0530\n" -"Last-Translator: Runa Bhattacharjee \n" -"Language-Team: Bangla \n" -"Language: bn_IN\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.9.1\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu'র বৈশিষ্ট্য" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -#, fuzzy -msgid "arw" -msgstr "সারি" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -#, fuzzy -msgid "icn" -msgstr "icon" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -#, fuzzy -msgid "lnk" -msgstr "ফাঁকা" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -#, fuzzy -msgid "cll" -msgstr "সেল" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -#, fuzzy -msgid "tre" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "space" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "newline" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "exclaim" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "quote" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "and" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrophe" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "left paren" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "right paren" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "star" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "comma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "dash" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "dot" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slash" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "colon" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semicolon" - -#: src/cthulhu/chnames.py:126 -#, fuzzy -msgid "less" -msgstr "less than" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "equals" - -#: src/cthulhu/chnames.py:134 -#, fuzzy -msgid "greater" -msgstr "greater than" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "question" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "left bracket" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "backslash" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "right bracket" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "caret" - -#: src/cthulhu/chnames.py:162 -#, fuzzy -msgid "underline" -msgstr "newline" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "left brace" - -#: src/cthulhu/chnames.py:174 -#, fuzzy -msgid "vertical bar" -msgstr "vertical line" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "right brace" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -#, fuzzy -msgid "cents" -msgstr "percent" - -#: src/cthulhu/chnames.py:199 -#, fuzzy -msgid "pounds" -msgstr "pound" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -#, fuzzy -msgid "section" -msgstr "question" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "left bracket" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -#, fuzzy -msgid "mu" -msgstr "mnu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "right bracket" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -#, fuzzy -msgid "a tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -#, fuzzy -msgid "n tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -#, fuzzy -msgid "o tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -#, fuzzy -msgid "o stroke" -msgstr "apostrophe" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "right alt" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -#, fuzzy -msgid "per mille" -msgstr "ব্রেইল" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "left paren" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "right paren" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "left paren" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "right paren" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "সম্পূর্ণ নথিটি পড়া হবে।" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "সম্পূর্ণ নথিটি পড়া হবে।" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "সম্পূর্ণ নথি নির্বাচিত হয়েছে" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "নীচে: (_B)" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "কার্সারের বৈশিষ্ট্য" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "অতিরিক্ত বিকল্প প্রদর্শন করা হবে" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "অতিরিক্ত বিকল্প প্রদর্শন করা হবে" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "right control" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "ধূসরিত" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "right brace" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "right control" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "right paren" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "right brace" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "right paren" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "right paren" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "right alt" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "right paren" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "newline" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "ধূসরিত" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "tab" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "শূণ্য স্থান" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "শূণ্য স্থান" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "শূণ্য (_N)" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "বানান পরীক্ষণ:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "comma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "ডিফল্ট" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "" - -#: src/cthulhu/guilabels.py:296 -#, fuzzy -msgid "Braille Bindings" -msgstr "ব্রেইল" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -#, fuzzy -msgid "Unbound" -msgstr "pound" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu'র বৈশিষ্ট্য" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -#, fuzzy -msgid "Speak" -msgstr "পড়া হবে " - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "সমগ্র (_A)" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "শূণ্য (_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "কয়েকটি (_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "quote" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "question" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "নির্বাচিত" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "quote" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "ডিফল্ট" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "হাইপার-লিঙ্ক" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "বড় ছাঁদের হরফ" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "বানান পরীক্ষণ:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "পড়া হবে " - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "lst" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "left control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "left shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "left alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "left control" - -#: src/cthulhu/keynames.py:72 -#, fuzzy -msgid "right shift" -msgstr "right alt" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "right alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "right control" - -#: src/cthulhu/keynames.py:84 -#, fuzzy -msgid "left meta" -msgstr "left tab" - -#: src/cthulhu/keynames.py:88 -#, fuzzy -msgid "right meta" -msgstr "right alt" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "space" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "left alt" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "right alt" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "left paren" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "right paren" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "and" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "apostrophe" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "left paren" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "right paren" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "right control" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "dot" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "vertical line" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "ফাঁকা" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "right alt" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "vertical line" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "question" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "equals" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "equals" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "equals" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -#, fuzzy -msgctxt "math symbol" -msgid "not less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "equals" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "right alt" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "left tab" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "right alt" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "right brace" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:2025 -#, fuzzy -msgctxt "math symbol" -msgid "very much less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:2028 -#, fuzzy -msgctxt "math symbol" -msgid "very much greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertical line" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "left paren" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "right paren" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "left alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "right alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "left brace" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "left brace" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "left bracket" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "right bracket" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "শূণ্য স্থান" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "শূণ্য স্থান" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "শূণ্য স্থান" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "vertical line" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "ফাঁকা" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "icon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -#, fuzzy -msgid "Set up user preferences (text version)" -msgstr "-t, --text-setup Set up user preferences (text version)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "-t, --text-setup Set up user preferences (text version)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "ত্রুটি ও অন্যান্য সমস্যা https://groups.io/g/stormux ঠিকানায় জমা দিন।" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "question" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "সম্পূর্ণ নথি নির্বাচিত হয়েছে" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "সম্পূর্ণ নথি নির্বাচিত হয়েছে" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ফাঁকা" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "শূণ্য (_N)" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "vertical line" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "and" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "underscore" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "tree level %d" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "icon" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "শব্দের ভুল বানান:" - -#: src/cthulhu/messages.py:1682 -#, fuzzy, python-format -msgid "Misspelled word: %s" -msgstr "শব্দের ভুল বানান: " - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "left paren" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "tree level %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "নীচে: (_B)" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "উপরে: (_T)" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:2051 -#, fuzzy -msgid "on" -msgstr "icon" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "সমগ্র (_A)" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "শূণ্য (_N)" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -#, fuzzy -msgid "Search complete." -msgstr "বানান পরীক্ষা সমাপ্ত।" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "মাত্রা: (_R)" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "কোনো সার্ভার উপলব্ধ নেই।\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "কোনো সার্ভার উপলব্ধ নেই।\n" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Cthulhu'র বৈশিষ্ট্য" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -#, fuzzy -msgid "Speak cell" -msgstr "পড়া হবে " - -#: src/cthulhu/messages.py:2394 -#, fuzzy -msgid "Speak row" -msgstr "পড়া হবে " - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "সম্পূর্ণ নথি নির্বাচিত হয়েছে" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:2521 -#, fuzzy -msgctxt "text" -msgid "unselected" -msgstr "নির্বাচিত" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu'র বৈশিষ্ট্য" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "শূণ্য স্থান" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "percent" -msgstr[1] "percent" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "পিক্সেল" -msgstr[1] "পিক্সেল" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "space" -msgstr[1] "space" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "tree level %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "question" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "colon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "quote" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, fuzzy, python-format -msgid "h%d" -msgstr "hdr" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "vertical line" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "vertical line" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "vertical line" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "সংকুচিত" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "প্রসারিত" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -#, fuzzy -msgid "vertical" -msgstr "vertical line" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "icon" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "নির্বাচিত" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ধূসরিত" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "নির্বাচিত" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "অবৈধ" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "অবৈধ" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "অবৈধ" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "বানান পরীক্ষা করুন" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "অবৈধ" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "ডিফল্ট" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "বড় ছাঁদের হরফ" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "হাইপার-লিঙ্ক" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu'র বৈশিষ্ট্য" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "পড়া হবে " - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "ব্রেইল" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "মাত্রা: (_R)" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "ব্যক্তি: (_P)" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "সমগ্র (_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "অতিরিক্ত বিকল্প প্রদর্শন করা হবে" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "শূণ্য (_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "হাইপার-লিঙ্ক" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ব্রেইল" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Bon Echo" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -#, fuzzy -msgid "_Speak all" -msgstr "পড়া হবে " - -#: src/cthulhu/cthulhu-setup.ui:3257 -#, fuzzy -msgid "Speak _none" -msgstr "পড়া হবে " - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "সারি" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "left paren" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "right paren" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "cale" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "newline" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "vertical line" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "ডানদিকে: (_R)" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "newline" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "সারি" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "trtbl" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "left alt" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "right alt" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "percent" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "semicolon" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "প্রসারিত" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "প্রসারিত" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "প্রসারিত" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "প্রসারিত" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "ডিফল্ট" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "newline" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "tip" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "নীচে: (_B)" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "tab" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "বানান পরীক্ষা করুন" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/bs.po b/po/bs.po deleted file mode 100644 index e535a45..0000000 --- a/po/bs.po +++ /dev/null @@ -1,9527 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: gnome-cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2015-03-10 15:23+0100\n" -"Last-Translator: Samir Ribic \n" -"Language-Team: Bosnian \n" -"Language: bs\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Launchpad-Export-Date: 2015-02-05 06:46+0000\n" -"X-Generator: Poedit 1.7.4\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu čitač ekrana" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "čitač ekrana;govor;brailleovo pismo;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrhsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "biraj" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitem" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "pojam" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "savjet" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "automatski" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Češki Nivo 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Španski Nivo 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanada Francuz čin 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francuski (Francuska) Nivo 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvijski Nivo 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Nizozemska Nizozemac čin 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norveški Nivo 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvežanin čin 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvežanin čin 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvežanin čin 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Poljak čin 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugalac čin 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Švedski Nivo 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arapski Nivo 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Velški Nivo 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Velški Nivo 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Njemački Nivo 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Njemački Nivo 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Njemački Nivo 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Engleski (U.K.) Nivo 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Engleski (U.K.) Nivo 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Engleski (SAD) Nivo 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Engleski (SAD) Nivo 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francuski (Kanada) Nivo 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francuski (Francuska) Nivo 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grčki Nivo 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi Nivo 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Mađarski osmotačkasti računar" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Mađarski stepen 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Mađarski stepen 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Talijanski Nivo 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgija Nizozemac čin 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "razmak" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nova linija" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "uzvičnik" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "navodnik" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "broj" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procenat" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ampersand" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "lijeva zagrada" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "desna zagrada" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "zvjezdica" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "zapeta" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "crta" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "tačka" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "kosa crta" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dvotačka" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "tačka-zarez" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "manje" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "jednako" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "veće" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "upitnik" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "et" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "lijeva uglasta" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "obrnuta kosa crta" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "desna uglasta" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "kvakica" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "donja crta" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "gravis" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "lijeva vitičasta" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertikalna crta" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "desna vitičasta" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "razmak" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "naopaki uzvičnik" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centi" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "funte" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "znak valute" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "slomljena vertikalna crta" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "odjeljak" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "autorska prava" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superskript a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "duplo manje" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logičko ne" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "meko hyphen" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrovano" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "makron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "stepeni" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superskript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "akcentovan" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mi" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "paragraf" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "srednja tačka" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "sjedila" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superskript 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "oridinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "duplo veće" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "jedna četvrtina" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "jedna polovina" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tri četvrtine" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "naopaki upitnik" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a akcentovano" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AKCENTOVANO" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDA" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A PRSTEN" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C SEDILA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AKCENTOVANO" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AKCENTOVANO" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "Đ" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDA" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AKCENTOVANO" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDA" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "puta" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O PREKRIŽENO" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AKCENTOVANO" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AKCENTOVANO" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "TORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s oštro" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilda" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a prsten" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c sjedila" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e akcentovano" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i akcentovano" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "đ" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilda" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o akcentovano" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilda" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "podjeljeno" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o prekriženo" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "torn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u akcentovano" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y akcentovano" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "ef" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "crtica" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "lijevi jednostruki navodnik" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "desni jednostruki navodnik" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "jednostruki donji navodnik" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "lijevi dupli navodnik" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "desni dupli navodnik" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "donji dupli navodnik" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "bodež" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dupli bodež" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "metak" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trokutasti metak" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prim" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "sekundum" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "trostruka tilda" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "hyphen metak" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "zaštitni znak" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "znak tačno" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "podebljani znak tačno" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "metak oblika x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "superskript 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "superskript 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "superskript 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "superskript 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "superskript 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "superskript 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "superskript 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "superskript plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "superskript minus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "superskript jednako" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "superskript lijeva zagrada" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "superskript desna zagrada" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "superskript n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "superskript 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "superskript 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "superskript 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "superskript 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "superskript 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "superskript 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "superskript 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "superskript 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "superskript 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "superskript plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "superskript minus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "superskript jednako" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "superskript lijeva zagrada" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "superskript desna zagrada" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "crni kvadrat" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "crni dijamant" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "karakter za promjenu objekta" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Pomjera pokazivač na trenutnu stavku." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Izvršava lijevi klik na trenutnoj stavci ravnog pregleda." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Izvršava desni klik na trenutnoj stavci ravnog pregleda." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Čita cijeli dokument." - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Ne koristim dvodimenzionalni pregled." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Izvršava osnovnu gdje sam ja operaciju." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Izvršava detaljnu gdje sam ja operaciju." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Čita trenutnu liniju ravnog pregleda." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Pričaj prazne linije" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Ide na sljedeću tipku." - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Čitat statusnu traku." - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Čita naslov." - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Otvara dijaloški prozor za pretragu." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Traži slijedeće pojavljivanje teksta." - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Traži predhodno pojavljivanje teksta." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Ulazi i izlazi iz ravnog pregleda." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Pomiče ravni pregleda na kraj." - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Pomiče ravni pregled na poečetni položaj." - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Pomiče ravni pregleda na kraj." - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Pomoiče ravni pregled na početak predhodne linije." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Čita trenutnu liniju ravnog pregleda." - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Speluje trenutnu liniju ravnog pregleda." - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Fonetski speluje trenutnu liniju ravnog pregleda." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Pomiče ravni pregled na početak iduće linije." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Pomiče ravni pregled na predhodnu stavku ili riječ." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Čita trenutnu stavku ili riječ ravnog pregleda." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Speluje trenutnu stavku ili riječ ravnog pregleda." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Fonetski speluje trentunu stavku ili riječ ravnog pregleda." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Pomiče ravni pregled na slijedeću stavku ili riječ." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Pomiče ravni pregled na riječ iznad trenutne riječi." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Čita trenutni objekat ravnog pregleda." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Pomiče ravni pregled na riječ ispid trenutne riječi." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Pomiče ravni pregled na predhodni karakter." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Čita trenutni karakter ravnog pregleda." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Fonetski čita karakter ravnog pregleda." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Čita unikod vrijednost karaktera ravnog pregleda." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Pomiče ravni pregled na idući karakter." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Pomiče ravni pregled na kraj linije." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Pomiče ravni pregled lijevo na dno." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Kopira sadržaj pod ravnim prikazom u međuspremnik." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Pridodaje sadržaj pod ravnim pregledom u međuspremnik." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Pomiče ravni pregleda na kraj." - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Mijenja da li da čita trenutnu ćeliju tabele ili cijeli red." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Čita atribute povezane sa trenutni karakterom." - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Pomiče brailleov ekran na lijevo." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Pomiče brailleov ekran na desno." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Vraća objekat sa tastaturnim fokusom." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Pali i gasi skraćenog braillea." - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Procesira identificiranje kursora." - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Označava početak tekstualne selekcije." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Označava kraj tekstualne selekcije." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Ulazi u način rada za učenje. Pritisnite escape izađete." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Smanjuje brzinu govora." - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Povećava brzinu govora." - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Smanjuje visinu govora." - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Povećava visinu govora." - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Povećava brzinu govora." - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Smanjuje brzinu govora." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Selektuj željeni govorni server." - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Selektuj željeni govorni server." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Smanjuje brzinu govora." - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Povećava brzinu govora." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Postavke vrste zvuka" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Prigušuje govor." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Mijenja opseg govora programa." - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Mjenja način rada sa pregledanjem mišem." - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Napušta čitač ekrana" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Prikazuje okvir za kofiguraciju opcija." - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Prikazuje okvir za konfiguraciju opcija aplikacije." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Mjenja poravnanje govora." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Mjenja izgovor interpunkcije na idući nivo." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Mjenja eho tipki na idući nivo." - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Prebacuje na sljedeć profil podešavanja." - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Prebacuje na naredni stil označavanja velikih i malih slova." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Mjenja eho tipki na idući nivo." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Mjenja nivo ispravljanja greški pri pokretanju." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Označava gdje sam ja sa poštivanjem trenutne pozicije." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Idi na lokaciju predhodne oznake." - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Idi na oznaku." - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Idi na lokaciju iduće oznake." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Dodaj oznaku." - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Sačuvaj oznaku." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Mjenja način rada sa pregledanjem mišem." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Prikazuje trenutno vrijeme." - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Prikazuje trenutni datum." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Propušta iduću komandu u trenutnoj aplikaciji." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Izgovori i ispiši brajovim pismom prethodnu poruku." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Upali ako oglašavamo kada naši prijatelji tipkaju." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Upali ako ponudimo specifičnu historiju poruka sobe za brbljanje." - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "Upali ako je prefiks sobe za brbljanje ime sobe za brbljanje." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Pomjeri Lijevo" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linija u desno" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Pomjeri Gore" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Pomjeri Dolje" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Zaustavi" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Gore lijevo" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Dolje lijevo" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Pozicija kursora" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Šest tačaka" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Preusmjeravanje kursora" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Započni Selekciju" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Izvrši Selekciju" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Šalje zadnju obavještajnu poruku." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Lista obavještajnih poruka." - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Šalje predhodnu obavještajnu poruku." - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Šalje zadnju obavještajnu poruku." - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Ide na idući karakter." - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Ide na predhodni karakter." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Ide na iduću riječ." - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Ide na predhodnu riječ." - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Ide na slijedeću liniju." - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Ide na predhodnu liniju." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Ide na vrh datoteke." - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Ide na dno datoteke." - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Ide na početak linije." - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Ide na kraj linije." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Ide na sljedeći objekat." - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Ide na predhodni objekat." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Prouzrokuje da trenutna kutija bude proširena." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Prebacuje između izvorne navigacije i navigacije ekranskim pokazivačem." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Opcije naprednog živog nivoa uljudnosti." - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Postavi standardni živi nivo uljudnosti na isključeno." - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Pregledaj obavještenja živih nivoa." - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Prati žive nivoe." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Mjenja fokus prema i od trenutnog prelaska miša." - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Postavite red koji će se koristiti kao dinamičko zaglavlje kolone." - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Čisti dinamičko zaglavlje kolona." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Postavite kolonu koja će se koristiti kao dinamičko zaglavlje reda." - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Čisti dinamičko zaglavlje redova." - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Prikaži sadržaj unosne linije." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Aktivira strukturalne nivgacijske tipke." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Ide na predhodni citat." - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Ide na sljedećei citat." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Prikazuje listu blokova citata." - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Ide na predhodnu tipku." - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Ide na sljedeću tipku." - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Prikazuje listu dugmadi." - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Ide na predhodnu kutiju za selekciju." - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Ide na sljedeću kutiju za selekciju." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Prikazuje spisak polja za potvrdu." - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Ide na prethodno što se moglo kliknuti." - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Ide na slijedeće što se može kliknuti." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Prikazuje listu objekata koji se mogu kliknuti." - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Ide na predhodnu kutiju." - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Ide na sljedeću kutiju." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Ide na kraj linije." - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Prikazuje listu prozorčića za izbor." - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Ide na predhodni unso." - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Ide na sljedeći unos." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Prikazuje spisak unosa." - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Ide na predhodno polje forme." - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Ide na sljedeće polje forme." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Prikazuje spisak polja formulara." - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Ide na predhodno zaglavlje." - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Ide na sljedeće zaglavalje." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Prikazuje spisak zaglavlja." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Ide na predhodno zaglavlje na nivou %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Ide na sljedeći zaglavlje na nivou %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Prikazuje spisak zaglavlja na %d nivou." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Ide na predhodnu tabelu." - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Ide na sljedeću tabelu." - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Prikazuje listu tabela." - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Ide na prethodnu sliku." - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Ide na slijedeću sliku." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Prikazuje listu slika." - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Ide na predhodni znak." - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Ide na sljedeći znak." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Prikazuje popis orijentira." - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Ide na predhodni veliki objekat." - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Ide na sljedeći veliki objekat." - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Prikazuje spisak velikih objekata." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Ide na prethodni link." - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Ide na slijedeći link." - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Prikazuje listu linkova." - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Ide na predhodnu listu." - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Ide na sljedeću listu." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Prikazuje spisak listi." - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Ide na predhodnu stavku liste." - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Ide na sljedeću stavku liste." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Prikazuje spisak stavki spiska." - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Ide na predhodni živi nivo." - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Ide na sljedeći živi nivio." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Ide na zadnji živi nivo koji je napravio obavijest." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Vraća objekat sa tastaturnim fokusom." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Vraća objekat sa tastaturnim fokusom." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Aktivira strukturalne nivgacijske tipke." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Ide na predhodni paragraf." - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Ide na sljedeći paragraf." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Prikazuje spisak paragrafa." - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Ide na predhodnu radio tipku." - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Ide na sljedeću radio tipku." - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Prikazuje spisak radio dugmadi." - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Ide na predhodni razdvajač." - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Ide na sljedeći razdvajač." - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Ide na predhodnu tabelu." - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Ide na sljedeću tabelu." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Prikazuje listu tabela." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Ide jednu ćeliju dolje." - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Ide do prvi ćelije u tabeli." - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Ide do zadnje ćelije u tabeli." - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Ide jednu ćeliju lijevo." - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Ide jednu ćeliju desno." - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Ide jednu ćeliju gore." - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Mjenja način rada sa pregledanjem mišem." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Mijenja između moda za pretragu i fokus." - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Omogućuje ljepljivi fokus mod." - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Omogućuje ljepljivi fokus mod." - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Ide na predhodnu neposjećenu vezu." - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Ide na sljedeću neposjećenu vezu." - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Prikazuje listu neposjećenih linkova." - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Ide na predhodnu posjećenu vezu." - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Ide na sljedeću posjećenu vezu." - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Prikazuje spisak posjećenih linkova." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "alis plava" - -#: src/cthulhu/colornames.py:44 -#, fuzzy -msgctxt "color name" -msgid "antique white" -msgstr "antikna bijela" - -#: src/cthulhu/colornames.py:49 -#, fuzzy -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarin" - -#: src/cthulhu/colornames.py:54 -#, fuzzy -msgctxt "color name" -msgid "azure" -msgstr "azurna" - -#: src/cthulhu/colornames.py:59 -#, fuzzy -msgctxt "color name" -msgid "beige" -msgstr "bež" - -#: src/cthulhu/colornames.py:64 -#, fuzzy -msgctxt "color name" -msgid "bisque" -msgstr "bisk" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "crno" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "blijedi badem" - -#: src/cthulhu/colornames.py:79 -#, fuzzy -msgctxt "color name" -msgid "blue" -msgstr "plava" - -#: src/cthulhu/colornames.py:84 -#, fuzzy -msgctxt "color name" -msgid "blue violet" -msgstr "plava violetna" - -#: src/cthulhu/colornames.py:89 -#, fuzzy -msgctxt "color name" -msgid "brown" -msgstr "smeđa" - -#: src/cthulhu/colornames.py:94 -#, fuzzy -msgctxt "color name" -msgid "burlywood" -msgstr "daska" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "kadet plava" - -#: src/cthulhu/colornames.py:104 -#, fuzzy -msgctxt "color name" -msgid "chartreuse" -msgstr "šartrez" - -#: src/cthulhu/colornames.py:109 -#, fuzzy -msgctxt "color name" -msgid "chocolate" -msgstr "čokolada" - -#: src/cthulhu/colornames.py:114 -#, fuzzy -msgctxt "color name" -msgid "coral" -msgstr "koralna" - -#: src/cthulhu/colornames.py:119 -#, fuzzy -msgctxt "color name" -msgid "cornflower blue" -msgstr "plavi različak" - -#: src/cthulhu/colornames.py:124 -#, fuzzy -msgctxt "color name" -msgid "cornsilk" -msgstr "kukuruznosvilena" - -#: src/cthulhu/colornames.py:129 -#, fuzzy -msgctxt "color name" -msgid "crimson" -msgstr "tamnocrvena" - -#: src/cthulhu/colornames.py:134 -#, fuzzy -msgctxt "color name" -msgid "cyan" -msgstr "cijan" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "tamnoplava" - -#: src/cthulhu/colornames.py:144 -#, fuzzy -msgctxt "color name" -msgid "dark cyan" -msgstr "tamna cijan" - -#: src/cthulhu/colornames.py:149 -#, fuzzy -msgctxt "color name" -msgid "dark goldenrod" -msgstr "tamnozlatna" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "tamnosiva" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "tamnozelena" - -#: src/cthulhu/colornames.py:164 -#, fuzzy -msgctxt "color name" -msgid "dark khaki" -msgstr "žutomrka" - -#: src/cthulhu/colornames.py:169 -#, fuzzy -msgctxt "color name" -msgid "dark magenta" -msgstr "tamnomagentna" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "tamna maslinasto-zelena" - -#: src/cthulhu/colornames.py:179 -#, fuzzy -msgctxt "color name" -msgid "dark orange" -msgstr "tamnonarandžasta" - -#: src/cthulhu/colornames.py:184 -#, fuzzy -msgctxt "color name" -msgid "dark orchid" -msgstr "tamna orhideja" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "tamnocrvena" - -#: src/cthulhu/colornames.py:194 -#, fuzzy -msgctxt "color name" -msgid "dark salmon" -msgstr "tamnoroza" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "tamna morsko-zelena" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "tamna škriljevca plava" - -#: src/cthulhu/colornames.py:209 -#, fuzzy -msgctxt "color name" -msgid "dark slate gray" -msgstr "tamna škriljevca siva" - -#: src/cthulhu/colornames.py:214 -#, fuzzy -msgctxt "color name" -msgid "dark turquoise" -msgstr "tamna tirkizna" - -#: src/cthulhu/colornames.py:219 -#, fuzzy -msgctxt "color name" -msgid "dark violet" -msgstr "tamnoljubičasta" - -#: src/cthulhu/colornames.py:224 -#, fuzzy -msgctxt "color name" -msgid "deep pink" -msgstr "duboka roza" - -#: src/cthulhu/colornames.py:229 -#, fuzzy -msgctxt "color name" -msgid "deep sky blue" -msgstr "duboka nebesko-plava" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "mat siva" - -#: src/cthulhu/colornames.py:239 -#, fuzzy -msgctxt "color name" -msgid "dodger blue" -msgstr "dodžer plava" - -#: src/cthulhu/colornames.py:244 -#, fuzzy -msgctxt "color name" -msgid "fire brick" -msgstr "boja cigle" - -#: src/cthulhu/colornames.py:249 -#, fuzzy -msgctxt "color name" -msgid "floral white" -msgstr "cvijetno-bijela" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "šumska zelena" - -#: src/cthulhu/colornames.py:259 -#, fuzzy -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksija" - -#: src/cthulhu/colornames.py:264 -#, fuzzy -msgctxt "color name" -msgid "gainsboro" -msgstr "gejnsboro" - -#: src/cthulhu/colornames.py:269 -#, fuzzy -msgctxt "color name" -msgid "ghost white" -msgstr "duh-bijela" - -#: src/cthulhu/colornames.py:274 -#, fuzzy -msgctxt "color name" -msgid "gold" -msgstr "zlatna" - -#: src/cthulhu/colornames.py:279 -#, fuzzy -msgctxt "color name" -msgid "goldenrod" -msgstr "zlatnoliva" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "siva" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "zelena" - -#: src/cthulhu/colornames.py:294 -#, fuzzy -msgctxt "color name" -msgid "green yellow" -msgstr "zelenožuta" - -#: src/cthulhu/colornames.py:299 -#, fuzzy -msgctxt "color name" -msgid "honeydew" -msgstr "medenorosna" - -#: src/cthulhu/colornames.py:304 -#, fuzzy -msgctxt "color name" -msgid "hot pink" -msgstr "vruća roza" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "indijska crvena" - -#: src/cthulhu/colornames.py:314 -#, fuzzy -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -#, fuzzy -msgctxt "color name" -msgid "ivory" -msgstr "slonovača" - -#: src/cthulhu/colornames.py:324 -#, fuzzy -msgctxt "color name" -msgid "khaki" -msgstr "žutomrka" - -#: src/cthulhu/colornames.py:329 -#, fuzzy -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -#, fuzzy -msgctxt "color name" -msgid "lavender blush" -msgstr "rumenilo lavande" - -#: src/cthulhu/colornames.py:339 -#, fuzzy -msgctxt "color name" -msgid "lawn green" -msgstr "travna zelena" - -#: src/cthulhu/colornames.py:344 -#, fuzzy -msgctxt "color name" -msgid "lemon chiffon" -msgstr "limun šifon" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "svijetloplava" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "svijetlokoralna" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "svijetlocijan" - -#: src/cthulhu/colornames.py:364 -#, fuzzy -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "svjetla zlatnožuta" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "svijetlosiva" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "svijetlozelena" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "svijetloroza" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "svijetloružičasta" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "svijetla morsko-zelena" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "svijetla nebesko-plava" - -#: src/cthulhu/colornames.py:399 -#, fuzzy -msgctxt "color name" -msgid "light slate gray" -msgstr "svijetla škriljevca siva" - -#: src/cthulhu/colornames.py:404 -#, fuzzy -msgctxt "color name" -msgid "light steel blue" -msgstr "svijetla čelično-plava" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "svijetložuta" - -#: src/cthulhu/colornames.py:414 -#, fuzzy -msgctxt "color name" -msgid "lime" -msgstr "fluoroscentna zelena" - -#: src/cthulhu/colornames.py:419 -#, fuzzy -msgctxt "color name" -msgid "lime green" -msgstr "drečavo zelena" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "platno" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -#, fuzzy -msgctxt "color name" -msgid "maroon" -msgstr "kestenjasta" - -#: src/cthulhu/colornames.py:439 -#, fuzzy -msgctxt "color name" -msgid "medium aquamarine" -msgstr "srednja akvamarin" - -#: src/cthulhu/colornames.py:444 -#, fuzzy -msgctxt "color name" -msgid "medium blue" -msgstr "srednje plava" - -#: src/cthulhu/colornames.py:449 -#, fuzzy -msgctxt "color name" -msgid "medium orchid" -msgstr "srednje boja orhideje" - -#: src/cthulhu/colornames.py:454 -#, fuzzy -msgctxt "color name" -msgid "medium purple" -msgstr "srednje ljubičasta" - -#: src/cthulhu/colornames.py:459 -#, fuzzy -msgctxt "color name" -msgid "medium sea green" -msgstr "srednje morskozelena" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "srednje škriljevca plava" - -#: src/cthulhu/colornames.py:469 -#, fuzzy -msgctxt "color name" -msgid "medium spring green" -msgstr "srednje proljetna zelena" - -#: src/cthulhu/colornames.py:474 -#, fuzzy -msgctxt "color name" -msgid "medium turquoise" -msgstr "srednje tirkizna" - -#: src/cthulhu/colornames.py:479 -#, fuzzy -msgctxt "color name" -msgid "medium violet red" -msgstr "srednje violetno crvena" - -#: src/cthulhu/colornames.py:484 -#, fuzzy -msgctxt "color name" -msgid "midnight blue" -msgstr "ponoćna plava" - -#: src/cthulhu/colornames.py:489 -#, fuzzy -msgctxt "color name" -msgid "mint cream" -msgstr "mint-kremasta" - -#: src/cthulhu/colornames.py:494 -#, fuzzy -msgctxt "color name" -msgid "misty rose" -msgstr "misty ružičasta" - -#: src/cthulhu/colornames.py:499 -#, fuzzy -msgctxt "color name" -msgid "moccasin" -msgstr "mokasina" - -#: src/cthulhu/colornames.py:504 -#, fuzzy -msgctxt "color name" -msgid "navajo white" -msgstr "navajo bijela" - -#: src/cthulhu/colornames.py:509 -#, fuzzy -msgctxt "color name" -msgid "navy" -msgstr "mornarsko plava" - -#: src/cthulhu/colornames.py:514 -#, fuzzy -msgctxt "color name" -msgid "old lace" -msgstr "stara čipka" - -#: src/cthulhu/colornames.py:519 -#, fuzzy -msgctxt "color name" -msgid "olive" -msgstr "maslinasta" - -#: src/cthulhu/colornames.py:524 -#, fuzzy -msgctxt "color name" -msgid "olive drab" -msgstr "maslinasto-siva" - -#: src/cthulhu/colornames.py:529 -#, fuzzy -msgctxt "color name" -msgid "orange" -msgstr "narandžasta" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "narandžasto-crvena" - -#: src/cthulhu/colornames.py:539 -#, fuzzy -msgctxt "color name" -msgid "orchid" -msgstr "orhidejska" - -#: src/cthulhu/colornames.py:544 -#, fuzzy -msgctxt "color name" -msgid "pale goldenrod" -msgstr "blijeda zlatna" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "blijeda zelena" - -#: src/cthulhu/colornames.py:554 -#, fuzzy -msgctxt "color name" -msgid "pale turquoise" -msgstr "blijeda tirkizna" - -#: src/cthulhu/colornames.py:559 -#, fuzzy -msgctxt "color name" -msgid "pale violet red" -msgstr "blijeda violetno-crvena" - -#: src/cthulhu/colornames.py:564 -#, fuzzy -msgctxt "color name" -msgid "papaya whip" -msgstr "papaja šlag" - -#: src/cthulhu/colornames.py:569 -#, fuzzy -msgctxt "color name" -msgid "peach puff" -msgstr "breskva šlag" - -#: src/cthulhu/colornames.py:574 -#, fuzzy -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -#, fuzzy -msgctxt "color name" -msgid "pink" -msgstr "roza" - -#: src/cthulhu/colornames.py:584 -#, fuzzy -msgctxt "color name" -msgid "plum" -msgstr "šljiva" - -#: src/cthulhu/colornames.py:589 -#, fuzzy -msgctxt "color name" -msgid "powder blue" -msgstr "puderasta plava" - -#: src/cthulhu/colornames.py:594 -#, fuzzy -msgctxt "color name" -msgid "purple" -msgstr "ljubičasta" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "crvena" - -#: src/cthulhu/colornames.py:604 -#, fuzzy -msgctxt "color name" -msgid "rosy brown" -msgstr "ružičasto-smeđa" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "kraljevska plava" - -#: src/cthulhu/colornames.py:614 -#, fuzzy -msgctxt "color name" -msgid "saddle brown" -msgstr "sedlo-smeđa" - -#: src/cthulhu/colornames.py:619 -#, fuzzy -msgctxt "color name" -msgid "salmon" -msgstr "blijeda roza" - -#: src/cthulhu/colornames.py:624 -#, fuzzy -msgctxt "color name" -msgid "sandy brown" -msgstr "pješčana smeđa" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "morska zelena" - -#: src/cthulhu/colornames.py:634 -#, fuzzy -msgctxt "color name" -msgid "seashell" -msgstr "školjka" - -#: src/cthulhu/colornames.py:639 -#, fuzzy -msgctxt "color name" -msgid "sienna" -msgstr "sijena" - -#: src/cthulhu/colornames.py:644 -#, fuzzy -msgctxt "color name" -msgid "silver" -msgstr "srebrena" - -#: src/cthulhu/colornames.py:649 -#, fuzzy -msgctxt "color name" -msgid "sky blue" -msgstr "nebeskoplava" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "škriljevca plava" - -#: src/cthulhu/colornames.py:659 -#, fuzzy -msgctxt "color name" -msgid "slate gray" -msgstr "škriljevca siva" - -#: src/cthulhu/colornames.py:664 -#, fuzzy -msgctxt "color name" -msgid "snow" -msgstr "snježna" - -#: src/cthulhu/colornames.py:669 -#, fuzzy -msgctxt "color name" -msgid "spring green" -msgstr "proljetna zelena" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "čelična plava" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "mrka" - -#: src/cthulhu/colornames.py:684 -#, fuzzy -msgctxt "color name" -msgid "teal" -msgstr "grogotovac" - -#: src/cthulhu/colornames.py:689 -#, fuzzy -msgctxt "color name" -msgid "thistle" -msgstr "čičak" - -#: src/cthulhu/colornames.py:694 -#, fuzzy -msgctxt "color name" -msgid "tomato" -msgstr "paradajz" - -#: src/cthulhu/colornames.py:699 -#, fuzzy -msgctxt "color name" -msgid "turquoise" -msgstr "tirkizna" - -#: src/cthulhu/colornames.py:704 -#, fuzzy -msgctxt "color name" -msgid "violet" -msgstr "ljubičasta" - -#: src/cthulhu/colornames.py:709 -#, fuzzy -msgctxt "color name" -msgid "wheat" -msgstr "žito" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "bijela" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "bijeli dim" - -#: src/cthulhu/colornames.py:724 -#, fuzzy -msgctxt "color name" -msgid "yellow" -msgstr "žuta" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "žutozelena" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktiviraj" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatski fokus tokom strukturne navigacije" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatski fokus tokom navigacije znakovima" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatski fokus tokom navigacije znakovima" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Tačka 7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Tačka 8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Tačka 7 i 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Odustani" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Skoči na" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_U redu" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Ništa" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "pravopis" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Pokaži kada tvoji prijatelji tipkaju" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Pokaži komleptnu historiju poruka sobe za brbljanje" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Forma govornih poruka" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Svi kanali" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Svi kanali kad je bilo koji %s prozor aktivan" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Samo aktivni kanal" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Izgovori ime sobe" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Omogući mod rasporeda za sadržaj" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dupli klik" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trostruki klik" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Standardni sintisajzer" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Stvarni string" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Zamjenski string" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Omogući eho karaktera" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Omogući oglašavanje mrtvih tipki" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Trenutna lokacija:" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimalna dužina usklađenog teksta:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opcije pretrage" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Samo čitaj izmjenjene linije tokom pronalaženja" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Čitaj rezultate tokom pronalaženja" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "zapeta" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Mapiranje tipki" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Podrazumijevano" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "način pisanja" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "odjeljak" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Brailleove obveze" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Sačuvaj oznaku." - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Vrijeme i datum" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Navigacija tabele" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Nedodjeljeno" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Izlazim iz ravnog pregleda." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificirano" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "Radna površina" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Obavijest" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Obavijest" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Postavke čitača ekrana za %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Oznaka u brailleu" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Prikaži osim" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Govor" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Snimi profil kao konflikt" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Konflikt korisničkih profila" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profil %s već postoji.\n" -"Nastaviti s ažuriranjem postojećeg profila novim promjenama?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Učitaj korisnički profil" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Planirate da promijenite aktivni profil. Ako\n" -"ste upravo napravili izmjene u podešavanja, one će\n" -"da se povuku pri učitavanju profila.\n" -"\n" -"Nastaviti učitavanje profila uz odbacivanje prethodne promjene?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Snimi profil kao" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Naziv _profila:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Učitaj korisnički profil" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Sve" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplikacija" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Prozor" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "Ništa" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Nešto" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Većina" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Linija" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Rečenica" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Blok citata" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Dugme" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Naslov" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Potvrdni okvir" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Može se kliknuti" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kombinirani okvir" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Opis" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Zaglavlje" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "interlacija" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Slika" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Oznaka" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Orijentir" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Razina" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Link" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Stavka liste" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekt" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragraf" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radio dugme" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Uloga" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Izabrana stavka" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stanje" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Tekst" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Vrijednost" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blokovi citata" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Dugmad" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Okviri za potvrdu" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Mogu se kliknuti" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kombinirani okviri" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Unosi" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Polja formulara" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Zaglavlja" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "interlacija" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Slike" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Zaglavlja na %d nivou." - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Orijentiri" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Veliki objekti" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Linkovi" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Stavke liste" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragrafi" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radio dugmad" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabele" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Neposjećeni linkova" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Posjećeni linkovi" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navigacija stranice" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Automatski počni čitanje stranice kada se prvi put pokrene" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Automatski počni čitanje stranice kada se prvi put pokrene" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Razdvoji govor u komade između pauza" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s standardni glas" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Podrazumijevano" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiperlink" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Velika slova" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Dispečer govora" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Provjera pravopisa" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Greška _pravopisa" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Pravopisne _sugestije" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Trenutni _kontekst greške" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Čitaj kordinate ćelije tabele" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Oglasi zaglavlje ćelije" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigacija tabele" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Preskoči prazne ćelije" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Čitaj ćeliju" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Čitaj kordinate ćelije" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Čitaj kordinate višestrukih ćelija" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Ime osobine" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Kako strelice pokreću tekstualni kursor oko HTML sadržaja" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Omogući _strukturnu navigaciju" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Kratko" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Obavijest" -msgstr[1] "Obavijest" -msgstr[2] "Obavijest" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Ctrl" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "lijevi shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "lijevi alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "desni kontrol" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "desni shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "desni alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "desni kontrol" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "lijevi meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "desni meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "lijevi tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "gore" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "dolje" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "lijevo" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "desno" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "lijevi super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "desni super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "meni" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "pomoć" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "promjena načina rada" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "umetni" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "briši" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "početak" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "kraj" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "počni" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "prsten" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "prekrižen" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Umetni" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Desni alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Lijevi alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Kontrol" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "podebljano %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "kurziv %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "Podebljani kurzivni %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "skriptni %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "podebljani skriptni %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktura %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "vertikalno-prekrižen %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "podebljano frakturni %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "bez-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif podebljano %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif kurziv %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif podebljano kurziv %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "monospace %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "bez tačaka %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "lijeva strijelica" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "lijeva strijelica" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "desna strijelica" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "ne-Te" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "desna strijelica" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "desna strijelica" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "desna strijelica" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "lijeva strijelica" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "lijeva strijelica" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "desna strijelica" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "lijevi dupli navodnik" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dupli bodež" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "desni dupli navodnik" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dupli bodež" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "desni dupli navodnik" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "strijelica na desno" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "strijelica na desno" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "ne manje od " - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "nije veće od" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "tačka" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "vertikalno poravnanje" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "središnja horizontalna trotačka" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "Za svaki" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "komplement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "parcijalni izvod" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "tu postoji" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "tu ne postoji" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "prazan skup" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "povećanje" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "element od" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "nije element od" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "mali element od" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "sadrži član" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "ne sadrži član" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "mali sadrži kao član" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "kraj dokaza" - -#: src/cthulhu/mathsymbols.py:1422 -#, fuzzy -msgctxt "math symbol" -msgid "product" -msgstr "n-arni proizvod" - -#: src/cthulhu/mathsymbols.py:1425 -#, fuzzy -msgctxt "math symbol" -msgid "coproduct" -msgstr "n-arni koprodukt" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "sub" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus ili plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "tačka plus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "dijeljenje (kroz)" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "skupovni minus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "zvjezdica operator" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "prsten operator" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "dugme operator" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "kvadratni korijen" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "kubni korijen" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "četvrti korijen" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcionalno" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "beskonačno" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "desni ugao" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "ugao" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "mjereni ugao" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sferni ugao" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "dijeli" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "nije djeljivo" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paralelno" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "nije paralelno" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "Logičko I" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logičko ILI" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "presjek" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unija" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "Dvojni integral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "trostruki integral" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "konturni integral" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "povtšinski integral" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "zapreminski integral" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral u pravcu kazaljke" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "konturni integral u pravcu kazaljke" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "konturni integral obrnuto od pravca kazaljke" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "stoga" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "zbog" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "omjer" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporcija" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "tačka minus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "preko" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometijska proporcija" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetija" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "obrnuta tilda" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "invertovani lijeni S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusoida" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "vjenačni proizvod" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "nije tilda" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minus tilda" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asimptotski jednako" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "nije asimptotski jednako" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "približno jednako" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "približno ali ne sasvim jednako" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ni približno ni sasvim jednako" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "skoro jednako" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "nije skoro jednako" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "skoro jednako ili jednako" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "trostruka tilda" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "sve jednako" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekvivalentno s" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrijski ekvivalentno s" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "razlika između" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "približno granici" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrijski jednako" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "približno jednako ili slika od" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "slika od ili približno jednako" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dvotačka jednako" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "jednako dvotačka" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "prsten u jednako" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "prsten jednako" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "odgovara sa" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "procjenjuje" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "jednakougaono s" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "zvjezdica jednako" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta jednako" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "jednako po definiciji" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "mjereno s " - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "upitno jednako" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "nije jednako" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identično" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "nije identično" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "striktno ekvivalentno sa " - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "manje ili jednako" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "veće ili jednako" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "manje iznad jednako" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "veće iznad jednako" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "manje od ali ne jednako" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "veće od ali ne jednako" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "mnogo manje od" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "mnogo veće od" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "između" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "nije ekvivalentno" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "ne manje od " - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "nije veće od" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "niti manje niti jednako" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "niti veće niti jednako" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "manje ili ekvivalentno" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "veće ili ekvivalentno" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ni manje ni ekvivalentno" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ni veće ni ekvivalentno" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "manje ili veće" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "veće ili manje" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ni manje ni veće" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ni veće ni manje" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "prethodi" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "prati" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "Prethodi ili jednako" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "prati ili jednako" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "prethodi ili ekvivalentno" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "prati ili ekvivalentno" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "ne prethodi" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ne prati" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "podskup od" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "nadskup od" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "nije podskup" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "nije nadskup" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "podskup ili jednako" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "nadskup ili jednako" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ni podskup ni jednako" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ni nadskup ni jednako" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "podskup od sa ne jednako" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "nadskup od sa ne jednako" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiset" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "množenje multisetova" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "unija multisetova" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "kvadratna slika od" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadratni original od" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "kvadratna slika ili jednako" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "kvadratni original ili jednako s" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "četvrtasti završetak" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadratni kap" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "zaokruženi plus" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "zaokruženi minus" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "zaokruženi puta" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "zaokružena kosa crta dijeljenja" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "zaokruženi operator tačke" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "zaokruženi operator prstena" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "zaokruženi operator zvjezdice" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "kružno jednako" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "kružna crtica" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "kvadratni plus" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "kvadratni minus" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "kvadratni puta" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "kvadratni operator tačke" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "desno Te" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "lijevo Te" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "ne-Te" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "Te" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "tvrdnja" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modeli" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "tačno" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "sile" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "trostruka vertikalna linija u stranu" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dvostruka vertikalna linija dvostruko desno u stranu" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "ne dokazuje" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "nije tačno" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "ne povlači" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "negirana dvostruka vertikalna linija dvostruko desno u stranu" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "prethodi pod relacijom" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "prati pod relacijom" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normalna podgrupa od" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "sadrži kao normalnu podgrupu" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normalna podgrupa od ili jednako s" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "sadrži kao normalna podgrupa ili jednako sa" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "Izvor od" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "slika od" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitska konjugacija matrica" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "interlacija" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "desni ugao s lukom" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "desni trougao" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "dijamant operator" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "tačka operator" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operator zvjezdica" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "dijeljenje puta" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "mašnica" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "lijevi normalni poludirektni faktor proizvod" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "desni normalni poludirektni faktor proizvod" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "lijevi poludirektni proizvod" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "desni poludirektni proizvod" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "obrnuta tilčda jednako" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "oblo logičko ili" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "oblo logičko i" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dvostruki podskup" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dvostruki nadskup" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dvostruki presjek" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dvostruka unija" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "trozubac" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "jednako i paralelno sa" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "manje s tačkom" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "veće s tačkom" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "mnogo manje od" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "mnogo veće od" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "manje od, jednako uili veće od" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "veće od, jednako ili manje od" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "jednako ili manje od" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "jednako ili veće od" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "jednako ili prethodi" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "jednako ili prati" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "ne prethodi ili jednak" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ne prati ili jednak" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "nije kvadratna slika ili jednako" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "nije kvadratni original ili jednak" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "kvadratna slika ili jednako" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "kvadratni original ili nije jednak" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "manje ali ne ekvivalentno" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "veće ali ne ekvivalentno" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "prethodi ali nije ekvivalentno sa" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "prati ali nije ekvivalento sa" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "nije normalna podgrupa od" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "ne sadrži kao normalna podgrupa" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "nije normalna podgrupa ili jednak sa" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "ne sadrži kao normalna podgrupa ili jednak" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertikalna trotačka" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "središnja horizontalna trotačka" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "gore desno dijagonalna trotačka" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "dolje desno dijagonalna trotačka" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "element od s dugim horizontalnim precrtanjem" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "element od s vertikalnom linijom na kraju horizontalnog precrtanja" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"mali element od s vertikalnom linijom na kraju horizontalnog precrtanja" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "element s tačkom izbad" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "element s crtom iznad" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "mali element s crtom iznad" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "element s crtom ispod" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "element s dvije horizontalne linije" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "sadrži s dugom horizontalnom linijom" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "sadrži sa vertikalnom linijom na kraju horizontalnog poteza" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "malo adrži sa vertikalnom linijom na kraju horizontalnog poteza" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "sadrži s nadlinijom" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "malo sadrži s nadlinijom" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "pripadnost z notacijskoj vreći" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "lijeva zagrada" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "desna zagrada" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "lijevi alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "desni alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "lijeva vitičasta" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "dno" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "duplo manje" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "duplo veće" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "kružna crtica" - -#: src/cthulhu/mathsymbols.py:2180 -#, fuzzy -msgctxt "math symbol" -msgid "union with dot" -msgstr "manje s tačkom" - -#: src/cthulhu/mathsymbols.py:2182 -#, fuzzy -msgctxt "math symbol" -msgid "union with plus" -msgstr "tačka plus" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "n-arni presjek" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "kvadratni kap" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "crni kvadrat" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "bijeli kvadrat" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "crni dijamant" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "bijeli krud" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "crni krug" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "bijeli metak" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "crni kvadrat" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "donja crta" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "vertikalno poravnanje" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "aplikacija" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "prazno" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "podebljano" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "oznaka unesena" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "oznake sačuvane" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "oznake ne mogu biti sačuvane" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nema više znakova." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Nema više znakova." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Premošteni način rada omogućen." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Onemogućen da prikaže kalkulator" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Stil označavanja velikih i malih slova postavljen na ikonu." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ništa" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Stil označavanja velikih i malih slova postavljen na ništa." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "pravopis" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Stil označavanja velikih i malih slova za izgovor." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Gecko kontroliše caret." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Gecko kontroliše caret." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Ćelija %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "selektovani" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "neselektovani" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Spriječi korištenje opcije" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Prisilno korištenje opcije" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCIJA" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Sljedeće nije važeće: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Printaj poznatu pokrenutu aplikaciju" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Čitanje profila" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profil se ne može učitati: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Ne mogu pokrenuti čitača ekrana jer se on ne može povezati s radnom " -"površinom." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Ne mogu aktivirati postavke menadžera. Izlazim." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Drugi čitač ekrana već radi u ovoj sesiji.\n" -"Pokreni \"cthulhu --replace\" za zamjenu procesa novim procesom." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "IME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Koristi alternativni direktorij za korisničke opcije" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Printaj poznatu pokrenutu aplikaciju" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Zamijeni trenutno pokrenutu instancu ovog čitača ekrana" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Pošalji izlaz ispravljanja greške u debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Pošalji izlaz ispravljanja greške u posebnu datoteku" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "DATOTEKA" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Postavi korisničke opcije (tekstualna verzija)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Postavi korisničke postavke (GUI verzija)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Izvještava bugove na https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Sadržaj je kopiran u međuspremnik." - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "akcentovan" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Sadržaj je kopiran u međuspremnik." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Sadržaj je kopiran u međuspremnik." - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "brže." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Nijemo objaviti kada tvoji prijatelji tipkaju." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "objavi kada tvoji prijatelji tipkaju." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Poruke iz sobe za brbljanje %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nova pločica za brbljanje %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Ne govori ime sobe za brbljanje." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "govori ime sobe za brbljanje." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Nemoj ponuditi specifičnu historiju poruka sobe za brbljanje." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Ponudi specifičnu historiju poruka sobe za brbljanje." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "Indikator izbora" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "briši" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "presjek" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "svijetlozelena" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "Pravopisne _sugestije" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Kraj tabele" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Nije u tabeli." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "nije selektovan" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Standardna tipka je %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Standardna tipka je %s" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Standardna tipka je %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subscript %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " superscript %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Nije u tabeli." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "čitav dokument selektovan" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "čitav dokument selektovan" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokument selektovan od pozicije kursora" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "dokument neselektovan od pozicije kursora" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokument slektovan do pozicije kursora" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "dokument neselektovan do pozicije kursora" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dinamičko zaglavlje kolone postavljeno na red %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dinamičko zaglavlje kolone očišćeno." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dinamičko zaglavlje reda postavljeno na kolonu %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dinamičko zaglavlje reda očišćeno." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "prazno" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobajta" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabajta" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Nisu pronađene datoteke." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Sadržaj je pridodan u međuspremnik." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Sadržaj je kopiran u međuspremnik." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Ne koristim dvodimenzionalni pregled." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Ulazim u ravnig pregled." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Izlazim iz ravnog pregleda." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Pomiče ravni pregled na riječ iznad trenutne riječi." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "ima formulu" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "Otvara dijaloški prozor za pretragu." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "slika mape veze" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Unesena tipka je već vezana sa %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tipka unesena: %s. Pritisni enter da potvrdiš." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Nova tipka je: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Veza tipke obrisana. Pritisni enter da potvrdiš." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Veza tipke je obrisana." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "unesi novu tipku" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tipka" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Ključni eho na tipku." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ništa" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Ključni eho na ništa." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tipka i riječ" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Ključni eho na tipku i riječ." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "rečenica" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Ključni eho na rečenicu." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "riječ" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Ključni eho na riječ." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "riječ i rečenica" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Ključni eho na riječ i rečenicu." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "crni krug" - -#: src/cthulhu/messages.py:921 -#, fuzzy -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "ima dug opis" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "horizontalno" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "vertikalna crta" - -#: src/cthulhu/messages.py:961 -#, fuzzy -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "dolje desno dijagonalna trotačka" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "desna strijelica" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Listam do dna." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "visina linije" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -#, fuzzy -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "mjereni ugao" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "ampersand" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "nadvučeno" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "kvadratni korijen" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "kubni korijen" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "superskript 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "superskript a" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "superskript 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "superskript a" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "superskript a" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "superskript a" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "Omogućeno" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "nedostupno" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Onemogućeno" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Govor poravnanja onemogućen." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Omogućeno" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Govor poravnanja omogućen." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Način rada za učenje. Pritisnite esacape da izađete." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Otvaram mod za učenje. Pritisni bilo koju tipku da čujete njegove funkcije. " -"Za prikaz dokumentacije za čitača, pritisni F1. Za dobavu liste zadanih " -"prečica, pritisnite F2. Za dobavu liste prečica za trenutni program, " -"pritisni F3. Za izlaz iz ovog moda, pritisni escape tipku." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "Navigacija tabele" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Navigacija stranice" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Navigacija tabele" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "Izlazim iz ravnog pregleda." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "Pravopisne _sugestije" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "napuštanje tabele." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "linija selektovana dole od pozicije kursora" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "linija selektovana gore od pozicije kursora" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "linija neslektovana dole od pozicije kursora" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "linija neselektovana gore od pozicije kursora" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Izlazim iz načina rada za učenje." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "linija selektovana od početka do predhodne pozicije kursora" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "linija selektovana do kraja od predhodne pozicije kursora" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "veza" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ista stranica" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ista web stranica" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "druga web stranica" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s veza prema %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s veza" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d posjećena veza" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Koristi Gore i Dole strijelicu da navigiras kroz listu. Pritisni Escape za " -"izlaz." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Svi živi regioni su ugašeni" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "nivo živih regiona vraćen" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nivo uljudnosti %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "postavljam živi region na izričan" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "postavljam živi region na ugašeno" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "postavljam živi region na klasičan" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "postavljam živi region na grub" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Praćenje živog nivoa je isključeno" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Praćenje živog nivoa je uključeno" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nema sačuvanih živih poruka" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Podrška živog nivoa je isključena" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nije pronađeno" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Ne mogu pronaći trenutnu lokaciju." - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "isključeno" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "uključeno" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "pogrešno spelovano" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Pogrešno spelovanje riječi: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Dodatak je %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Mod za pretraživanje" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Žižni mod" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Za omogućavanje fokus moda, pritisni %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Fokus mod je ljepljivi." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Fokus mod je ljepljivi." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Žižni mod" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objekt" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Ide na sljedeći objekat." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Objekat ispod miša nije pronađen." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Mjenja način rada sa pregledanjem mišem." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Govor omogućen." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Greška: Ne mogu da napravim spisak objekata." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -# translations. -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d posto." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Ide na predhodnu riječ." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nivo petlje %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Nova stavka je dodana" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Nijedna aplikacija trenutno nema fokus." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Bez fokusa" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nijedna aplikacija trenutno nema fokus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Nema više citata." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Nema više tipki." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Nema više kutija za selekciju." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Nema više velikih objekata." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Nema više onih koje se mogu kliknuti." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Nema više kutija." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Nema više unosa." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Nema više polja forme." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Nema više zaglavlja." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Nema više zaglavlja na nivou %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Nema više tabela." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Nema više slika." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nema više znakova." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Nema više linkova." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Nema više listi." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Nema više stavki liste." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Nema više Živih nivoa." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Nema vipe paragrafa." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Nema više radio tipki." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Nema više razdvajača." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Nema više tabela." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Nema više neposjećenih veza." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Nema više posjećenih veza." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "nije selektovan" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nema više linkova." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Obavijest" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Dno" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Vrh" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Nema obavještajnih poruka" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "riječ" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Pričaj višestruke stringove kao riječi" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "isključeno" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "uključeno" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Učitavam. Molimo sačekajte." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Učitavanje završeno." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Završeno učitavanje %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "stranica slektovana od pozicije kursora" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "stranica slektovana do pozicije kursora" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "stranica neselektovana od pozicije kursora" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "stranica neselektovana do pozicije kursora" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "paragraf selektovan dolje od pozicije kursora" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragraf selektovan gore od pozicije kursora" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "paragraf neselektovan dolje od pozicije kursora" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragraf neselektovan gore od pozicije kursora" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Vi ste već otvorili Cthulhu dijalog preferencija.\n" -"Zatvorite ga prije nego što otvorite novi." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "kliži %(position)d od %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil je postavljen na %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nisam pronašao profile." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Progresna traka %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Sve" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Nivo interpunkcije postavljen na sve." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Većina" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Nivo interpunkcije posavljen većinu." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ništa" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Nivo interpunkcije postavljen na ništa." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Nešto" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Nivo interpunkcije postavljen na nešto." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Tražim." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Pretraga završena." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Postavke čitača ekrana ponovno učitane." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "Izabrana stavka" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Red izbrisan." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Indikator izbora" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "neselektovani" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Govor onemogućen." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Govor omogućen." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "brže." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "sporije." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "veće." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "manje." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "brže." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "Protok:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Jačina:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Dispečer govora" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Dispečer govora" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nema mogućih servera." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nema mogućih glasova." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Govor omogućen." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Govor se neće koristiti." - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Nivo opširnosti: ukratko" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Nivo opširnosti: opširno" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Premošteni način rada omogućen." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Govor je nemoguć." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Nije pronađeno" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "string nije pronađen" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "string nije pronađen" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Strukturalne navigacijske tipke ugašene." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Strukturalne navigacijske tipke upaljene." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nije pronađen" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Red %(row)d, kolona %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Kraj tabele" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Govorna ćelija" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Govorni red" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Ne-uniformno" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Nije u tabeli." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Kolone reorganiziranje" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Redovi reorganizirani" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "kolona %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolona %(index)d od %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Dno kolone." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Vrh kolone." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "neselektovani" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "neselektovani" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "red %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "red %(index)d od %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Početak reda." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Kraj reda." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Red izbrisan." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Zadnji red izbrisan." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Red umetnut." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Red umetnut na kraj tabele." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "Red izbrisan." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "neselektovani" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "selektovani" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "neselektovani" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H sati, %M minuta and %S sekundi." - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H sati i %M minuta." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unikod %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "prazna linija" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Listam do dna." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Listam do vrha." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 stavki" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Opseg ćelija %d red" -msgstr[1] "Opseg ćelija %d reda" -msgstr[2] "Opseg ćelija %d redova" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d kolona" -msgstr[1] " %d kolone" -msgstr[2] " %d kolona" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Opseg ćelija %d kolona" -msgstr[1] "Opseg ćelija %d kolone" -msgstr[2] "Opseg Ćelija %d kolona" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d karakter predug" -msgstr[1] "%d karaktera preduga" -msgstr[2] "%d karaktera predugo" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dijalog)" -msgstr[1] "(%d dijaloga)" -msgstr[2] "(%d dijaloga)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d nefokusirani okvir" -msgstr[1] "%d nefokusirana okvira" -msgstr[2] "%d nefokusiranih okvira" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bajt" -msgstr[1] "%d bajta" -msgstr[2] "%d bajta" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Pronađeno %d datoteke" -msgstr[1] "Pronađene %d datoteke" -msgstr[2] "Pronađeno %d datoteka" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d forma" -msgstr[1] "%d forme" -msgstr[2] "%d formi" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d zaglavlje" -msgstr[1] "%d zaglavlja" -msgstr[2] "%d zaglavlja" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d stavka" -msgstr[1] "%d stavke" -msgstr[2] "%d stavki" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Orijentir" -msgstr[1] "Orijentir" -msgstr[2] "Orijentir" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "pronađena %d stavka" -msgstr[1] "pronađene %d stavke" -msgstr[2] "Pronašao sam %d stavki" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Nema više citata." -msgstr[1] "Nema više citata." -msgstr[2] "Nema više citata." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Izlazim iz ravnog pregleda." -msgstr[1] "Izlazim iz ravnog pregleda." -msgstr[2] "Izlazim iz ravnog pregleda." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista sa %d stavkom" -msgstr[1] "Lista sa %d stavke" -msgstr[2] "Lista sa %d stavki" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Lista sa %d stavkom" -msgstr[1] "Lista sa %d stavke" -msgstr[2] "Lista sa %d stavki" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Vrijednost" -msgstr[1] "Vrijednost" -msgstr[2] "Vrijednost" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabela sa %d redom" -msgstr[1] "tabela sa %d reda" -msgstr[2] "tabela sa %d redova" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d kolona" -msgstr[1] "%d kolone" -msgstr[2] "%d kolona" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tabela sa %d redom" -msgstr[1] "tabela sa %d reda" -msgstr[2] "tabela sa %d redova" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d poruka.\n" -msgstr[1] "%d poruke.\n" -msgstr[2] "%d poruka.\n" - -# translations. -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d posto." -msgstr[1] "%d posto." -msgstr[2] "%d posto." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d posto dokumenta pročitano" -msgstr[1] "%d posto dokumenta pročitano" -msgstr[2] "%d posto dokumenta pročitano" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s karakter" -msgstr[1] "%(count)d %(repeatChar)s karaktera" -msgstr[2] "%(count)d %(repeatChar)s karaktera" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d od %(total)d stavke selektovana" -msgstr[1] "%(index)d od %(total)d stavke selektovane" -msgstr[2] "%(index)d od %(total)d stavaki selektovano" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d podrazumijevana prečica čitača ekrana nađena." -msgstr[1] "%d podrazumijevane prečice čitača ekrana nađene." -msgstr[2] "%d podrazumijevanih prečica čitača ekrana nađeno." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d kratica čitača ekrana za %(application)s nađena." -msgstr[1] "%(count)d kratice čitača ekrana za %(application)s nađena." -msgstr[2] "%(count)d kratica čitača ekrana za %(application)s nađene." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d razmak" -msgstr[1] "%d razmaka" -msgstr[2] "%d razmaka" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d pločica" -msgstr[1] "%d pločice" -msgstr[2] "%d pločica" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabela" -msgstr[1] "%d tabele" -msgstr[2] "%d tabela" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabela sa %d redom" -msgstr[1] "tabela sa %d reda" -msgstr[2] "tabela sa %d redova" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabela sa %d redom" -msgstr[1] "tabela sa %d reda" -msgstr[2] "tabela sa %d redova" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabela sa %d redom" -msgstr[1] "tabela sa %d reda" -msgstr[2] "tabela sa %d redova" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d neposjećena veza" -msgstr[1] "%d neposjećene veze" -msgstr[2] "%d neposjećenih veza" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d posjećena veza" -msgstr[1] "%d posjećene veze" -msgstr[2] "%d posjećenih veza" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "zamijeni" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "na %(index)d od %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d od %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVO %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "dužina stabla %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "DUŽINA STABLA %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "upitnik" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "Ide na sljedeću kutiju." - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "uredivo" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -#, fuzzy -msgctxt "role" -msgid "acknowledgments" -msgstr "komplement" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "riječ" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "dvotačka" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "nadvučeno" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "smjer" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "riječ" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "uvučeno" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "presjek" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "page up" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "navodnik" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "Omogući mod rasporeda za sadržaj" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivo %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "horizontalno" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "vertikalna crta" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "horizontalno" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "vertikalno poravnanje" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "horizontalno" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "vertikalno poravnanje" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "promjena načina rada" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Panel ikona" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "komplement" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "omjer" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "polu zbijeno" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Navigacija stranice" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "Tražim." - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "%d posjećena veza" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "Nema više tipki." - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "može se kliknuti" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "skraćeno" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "produženo" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "ima dug opis" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontalno" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikalno" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "selektovano" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nije selektovano" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "uključeno" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "isključeno" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "djelimično selektovano" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "pritisnuto" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "nije pritisnuto" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "nije selektovan" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "selektovan" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "nije selektovan" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "nije selektovana" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "posjećeno" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "neposjećeno" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "sivo" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "samo za čitanje" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "rdonly" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "obavezno" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "više selekt" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "spelovanje" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "spelovanje" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Nađi" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Dijalog traženja čitača ekrana" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Zatvori" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Nađi" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "Traži:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Traži:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Vrh prozora" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Vrh prozora:" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Počni od:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Nastavi od početka nakon kraja" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Traži unazad" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Smijer traženja:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Uporedi mala i velika slova" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Upoređuj samo cijele riječi" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opcije pretrage" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Podrazumijevano" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Velika slova" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiperveza" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplikacija" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Prozor" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu čitač ekrana" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Pomoć" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Primijeni" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Raspored tastature" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktivni _profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Početni profil:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Učitaj" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Sačuvaj _kao" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profili" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Trenutni kratki opisi" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Pričaj objekat ispod miša" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Miš" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Format vremena:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Format datuma:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Vrijeme i datum" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Govori sve" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Brajev indikator" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frekvencija:" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplikacija" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Ažuriranje trake napretka" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Omogući _strukturnu navigaciju" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Reci sve po:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Reci sve po:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Opće" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Jačina:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Visina:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "Protok:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "Osoba:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "jezik" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Govorni sintisajzer:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Govorni sistem:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Vrsta glasa:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Stil označavanja velikih i malih slova postavljen na ikonu." - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Postavke vrste zvuka" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Pričaj višestruke stringove kao riječi" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Globalne postavke zvuka" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Glas" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Omogući govor" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Opširno" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Izražajnost" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "Sve" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Razina interpukcije" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Samo čitaj prikazani tekst" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Pričaj prazne linije" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Pričaj poravnanje" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Pričaj objekat mnemonički" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Pričaj položaj djeteta" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Pričaj poruke vodiča" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Čitaj kordinate ćelije" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Automatski fokus tokom navigacije znakovima" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Omogući _strukturnu navigaciju" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Omogući _strukturnu navigaciju" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Čitaj kordinate ćelije" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Automatski fokus tokom navigacije znakovima" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Opis" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Izgovoreni kontekst" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Govor" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Omogući Brailleovu podršku" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Skraćena imena uloga" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Onemogući simbol za kraj linije" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Skraćena Tabela:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Omogući skraćenog Braillea" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Omogući eho riječi" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Podešavanje prikaza" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Nijedna" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indikator izbora" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indikator Hiperveze" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Globalne postavke zvuka" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Omogući ključni eho" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Omogući navigacijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Omogući modifikacijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Omogući funkcijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Omogući govor" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Omogući modifikacijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Omogući funkcijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Omogući akcione tipke" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Omogući navigacijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Omogući eho riječi" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Omogući eho rečenice" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Ključni eho" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "_Modifikatorski taster čitača ekrana:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Veze tastera" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Rječnik izgovora" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Novi unos" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "Briši" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Izgovor" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Govori sve" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Pričaj ništa" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "Resetuj" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Tekstualni atributi" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Pomjeri na dno" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Pomjeri dolje jedan" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Pomjeri gore jedan" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Pomjeri na vrh" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Podesi izabrane atribute" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Brajev indikator" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Tekstualni atributi" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "nisko" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "jezik" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "jen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Sadržaj je kopiran u međuspremnik." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "pozadinska boja" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "pozadina pune visine" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "pozadinski stipple" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "smjer" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "uredivo" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "prezime" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "boja prednjeg plana" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "stipple prednjeg plana" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efekti fonta" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "uvučeno" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "greška" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "nevidljivo" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "poravnanje" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "jezik" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "lijeva margina" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "visina linije" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "stil paragrafa" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pikseli iznad linije" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pikseli ispod linije" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pikseli unutar omotača" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "desna margina" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "uzgon" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "razmjera" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "veličina" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "razvučeno" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "linija kroz" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "dekoracija teksta" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotacija teksta" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "sjena teksta" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "podvučeno" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "varijanta" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "vertikalno poravnanje" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "težina" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "način omotavanja" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "način pisanja" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "tačno" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "netačno" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ništa" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "graviranje" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "emboss" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "outline" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "nadvučeno" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "linija kroz" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "svjetlucanje" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "crno" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "jednostruki" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dvostruki" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "nisko" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "karakter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "riječ" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "riječ karakter" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "lijevo desno" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "desno lijevo" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "lijevo" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "desno" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "sredina" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "bez poravnanja" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "popuni" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra zbijeno" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra zbijeno" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "zbijeno" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "polu zbijeno" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normalno" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "polu prošireno" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "prošireno" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra prošireno" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra prošireno" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "mali caps" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "nakrivljeno" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kurziv" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Standardno" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Tijelo teksta" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Zaglavlje" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "bazna linija" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "vrh" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "tekst-vrh" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "sredina" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "dno" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "tekst-dno" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "naslijeđeno" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lijevo desno - vrh dno" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "desno lijevo - vrh dno" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "vrh dno - desno lijevo" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "vrh dno - lijevo desno" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "dno vrho - denso lijevo" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "dno vrh - lijevo desno" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lijevo desno" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "denso lijevo" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "vrh dno" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "solid" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "spelovanje" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Pritisni razmak da selektujes." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Pritisni razmak da proširiš i koristi strijelice gore i dole da selektuje " -"stavku." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Pritisni alt+f6 da daš fokus djete prozoru." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Da pomakneš stavku, koristi ili strijelice ili kucaj ispred pretraživanja." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Da dođeš do sistemskog menia pritisni alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Koristi strijlice gore i dole da selektujes stavku." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Da skratiš, pritisni shift i lijevo." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Da proširišm, pritisni shift i desno." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Za aktiviranje pritisni enter." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Ukucaj tekst." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Koristi lijevo i desno da vidiš druge pločice." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Da aktiviraš pritisni razmak." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Koristi strijelice gore ili dole da selektujes vrijednost. Ili kucaj željenu " -"numeričku vrijednost." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Koristi strijelica da promjeniš." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Da navigiraš pritisni lijevu ili desnu strijelicu. Da se krećeš kroz stavke " -"pritisni gornju ili donju strijelicu." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Da uđeš u pod meni, pritisni desnu strijelicu." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Da smanjis pritisni lijevu strijelicu, da povećaš pritisni desnu strijelicu. " -"Da ideš na minimum pritisni home, a za maksimum pritisni end." diff --git a/po/ca.po b/po/ca.po deleted file mode 100644 index 9feae4d..0000000 --- a/po/ca.po +++ /dev/null @@ -1,9245 +0,0 @@ -# Catalan translation of cthulhu -# Copyright © 2006, 2007, 2008 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# Gil Fcthulhuda , 2006-2020. -# Jordi Serratosa , 2012, 2017. -# Walter Garcia-Fontes , 2016. -# Xavi Ivars , 2018. -# Jordi Mas i Hernàndez , 2022 -# -# Per veure els símbols als quals s'ha de posar noms vegeu: -# https://www.fileformat.info/info/unicode/char/search.htm -# i introduïu el codi (00d7 per exemple) i ja us mostrarà el símbol -# informació sobre les live regions a: -# http://live.gnome.org/Cthulhu/Firefox/LiveRegions -msgid "" -msgstr "" -"Project-Id-Version: ca\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-09-11 13:18+0200\n" -"Last-Translator: Bàrbara Vidal \n" -"Language-Team: Catalan \n" -"Language: ca\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Lector de pantalla Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "pantalla;lector;accessibilitat;veu;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alerta" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "fletxa" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "lle" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "títol" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "qdv" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "selcolor" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "capcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "qc" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "edidat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icona" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "marc" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "mar" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "subfindir" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "dibuix" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "selfit" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "empl" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "selletra" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "subfincris" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "capçal" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "marcint" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etiq" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "subfincap" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "enllaç" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstele" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnú" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "barmnú" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "elemnú" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "subfinop" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pestpag" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "llistapes" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "qdr" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "contrasenya" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnúeme" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "barprog" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "bt" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "opció" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "eleopmnú" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "subfinarr" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "capfila" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "barrades" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "subfindes" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "secció" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "separa" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "selellis" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "subfindiv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "botógir" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "bares" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tau" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cel·la" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "elemnúdes" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "botócom" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "barei" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "consell" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arbre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tauar" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "desc" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "portvis" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "fin" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "cap" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "peu" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apli" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "autocom" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "baredi" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "incrustat" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Txec grau 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Castellà grau 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francès canadenc grau 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francès de França grau 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letó grau 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holandès d'Holanda grau 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Noruec grau 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Noruec grau 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Noruec grau 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Noruec grau 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polonès grau 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portuguès grau 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Suec grau 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Àrab grau 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Gal·lès grau 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Gal·lès grau 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemany grau 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemany grau 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemany grau 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Anglès de Regne Unit grau 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Anglès de Regne Unit grau 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Anglès d'Estats Units d'Amèrica grau 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Anglès d'Estats Units d'Amèrica grau 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francès de Canadà grau 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francès de França grau 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grec grau 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi grau 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ordinador hongarès de 8 punts" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hongarès grau 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Hongarès grau 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italià grau 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Holandès de Bèlgica grau 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espai" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "línia nova" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulador" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "exclamació" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "cita" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nombre" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dòlar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percentatge" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "i" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apòstrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "parèntesi esquerre" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "parèntesi dret" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterisc" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "més" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "coma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "traç" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punt" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra inclinada" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dos punts" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punt i coma" - -# El símbol < el llegeixo com a "menor " o "menor que", però la proposta anterior era "menys". -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "menor" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "igual" - -# També podria ser "major que" -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "major" - -# El símbol ? és un interrogant. La proposta anterior ho traduïa com a "pregunta" -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "interrogant" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "arrova" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "claudàtor esquerre" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "barra inversa" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "claudàtor dret" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "cursor" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "subratllat" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "obert" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "clau esquerra" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra vertical" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "clau dreta" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "titlla" - -# FIXME -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espai no separable" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "exclamació invertida" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cèntims" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "lliures" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "signe de moneda" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "ien" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra trencada" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "secció" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "dièresi" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superíndex a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "cometes baixes esquerres" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "no lògic" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "guionet" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrat" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "guionet alt" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "graus" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "més o menys" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superíndex 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superíndex 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "accent agut" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "marcador de paràgraf" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "punt volat" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "trenc" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superíndex 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "o elevada" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "cometes baixes dretes" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "un quart" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "un mig" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tres quartes parts" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "signe d'interrogació invertit" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a amb accent tancat" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A AMB ACCENT OBERT" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AMB ACCENT TANCAT" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A AMB ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A AMB TITLLA" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A AMB DIÈRESI" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A AMB CERCLE" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C TRENCADA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E AMB ACCENT OBERT" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AMB ACCENT TANCAT" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E AMB ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E AMB DIÈRESI" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I AMB ACCENT OBERT" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AMB ACCENT TANCAT" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I AMB ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I AMB DIÈRESI" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N AMB TITLLA" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O AMB ACCENT OBERT" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AMB ACCENT TANCAT" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O AMB ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O AMB TITLLA" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O AMB DIÈRESI" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "signe de multiplicació" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O BARRADA" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U AMB ACCENT OBERT" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AMB ACCENT TANCAT" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U AMB ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U AMB DIÈRESI" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AMB ACCENT TANCAT" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "eszet" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a amb accent obert" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a amb accent circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a amb titlla" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a amb dièresi" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a amb cercle" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c trencada" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e amb accent obert" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e amb accent tancat" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e amb accent circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e amb dièresi" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i amb accent obert" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i amb accent tancat" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i amb accent circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i amb dièresi" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n amb titlla" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o amb accent obert" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o amb accent tancat" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o amb accent circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o amb titlla" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o amb dièresi" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "divisió" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o barrada" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u amb accent obert" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u amb accent tancat" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u amb accent circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u amb dièresi" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y amb accent tancat" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y amb dièresi" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y AMB DIÈRESI" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florí" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "guió" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "marca de citació esquerra" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "marca de citació dreta" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "marca de citació baixa" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "cometes esquerres" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "cometes dretes" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "cometes baixes dobles" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "creu" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "creu doble" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "pic" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "pic triangular" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "tant per mil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prima" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "prima doble" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "prima triple" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "guió de pics" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marca registrada" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "marca de verificació" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "marca de verificació gruixuda" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "pic amb forma de x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "superíndex 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "superíndex 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "superíndex 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "superíndex 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "superíndex 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "superíndex 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "superíndex 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "superíndex signe positiu" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "superíndex signe negatiu" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "superíndex signe igual" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "superíndex parèntesi esquerre" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "superíndex parèntesi dret" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "superíndex n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "subíndex 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "subíndex 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "subíndex 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "subíndex 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "subíndex 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "subíndex 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "subíndex 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "subíndex 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "subíndex 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "subíndex 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "subíndex signe positiu" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "subíndex signe negatiu" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "subíndex signe igual" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "subíndex parèntesi esquerre" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "subíndex parèntesi dret" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "quadrat negre" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "diamant negre" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "caràcter de substitució d'objecte" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Mou el punter fins a l'element actiu" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Fa clic amb el botó esquerre a l'element actiu de la revisió plana" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Fa clic amb el botó dret a l'element actiu de la revisió plana" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Pronuncia el document sencer" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Pronuncia la finestra completa usant la revisió plana" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Fa l'operació bàsica d'on soc" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Fa l'operació detallada d'on soc" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Pronuncia el text seleccionat" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Pronuncia els detalls de l'enllaç" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Presenta el botó per defecte" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Presenta la barra d'estat" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Presenta la barra de títol" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Obre el diàleg de cerca" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Mostra la llista d'accions" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Cerca la següent instància d'una cadena" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Cerca les instàncies anteriors d'una cadena" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Entra i surt del mode de revisió plana" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Commuta la restricció de la revisió plana a l'objecte actiu" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Mou la revisió plana a la posició inicial" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Mou la revisió plana a l'última posició" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Mou la revisió plana al principi de la línia anterior" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Pronuncia la línia de revisió plana actual" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Lletreja la línia de revisió plana actual" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Lletreja amb codi fonètic la línia de revisió plana actual" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Mou la revisió plana a l'inici de la següent línia" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Mou la revisió plana a l'element o paraula anterior" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Pronuncia la paraula o element de la revisió plana actual" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Pronuncia la paraula o element de la revisió plana actual" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Pronuncia fonèticament la paraula o element de la revisió plana actual" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Mou la revisió plana al següent element o paraula" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Mou la revisió plana a la paraula de sobre de la paraula actual" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Pronuncia l'objecte de la revisió plana actual" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Mou la revisió plana a la paraula a sota de la paraula actual" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Mou la revisió plana al caràcter anterior" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Pronuncia el caràcter de l'actual revisió plana" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Pronuncia fonèticament el caràcter de l'actual revisió plana" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Pronuncia el valor Unicode del caràcter de la revisió plana actual" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Mou la revisió plana al següent caràcter" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Mou la revisió plana al final de línia" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Mou la revisió plana a baix de tot a l'esquerre" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copia el contingut de la revisió plana al porta-retalls" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Afegeix el contingut de la revisió plana actual al porta-retalls" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Mostra el contingut de la revisió plana" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Commuta entre llegir només la cel·la activa de la taula, o bé tota la fila" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Llegeix els atributs associats amb el caràcter del text actual" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Balanceja la visualització braille cap a l'esquerra" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Balanceja la visualització braille cap a la dreta" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Retorna a l'objecte amb el focus al teclat" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Activa o desactiva el braille contret" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Processa una tecla d'encaminament del cursor" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marca l'inici d'una selecció de text" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marca el final d'una selecció de text" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Entra al mode d'aprenentatge. Premeu la tecla d'escapament per a sortir-ne" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Disminueix la velocitat de pronunciació" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Incrementa la velocitat de pronunciació" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Disminueix el to de pronunciació" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Augmenta el to de la pronunciació" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Incrementa el volum de la veu" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Disminueix el volum de la veu" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Selecciona la configuració de veu anterior" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Selecciona la configuració de veu següent" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Disminueix la configuració de veu actual" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Augmenta la configuració de veu actual" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Desa la configuració de veu" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Commuta el silenci de la pronunciació" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Commuta el nivell de detall de la pronunciació" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Commuta el mode de suspensió" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Surt del lector de pantalla" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Mostra el diàleg de configuració de les preferències" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Mostra el diàleg de configuració de les preferències de l'aplicació" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Commuta la pronunciació del sagnat i la justificació" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Canvia l'estil de nombres parlats" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Canvia al nivell següent de pronunciació de la puntuació" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Canvia al sintetitzador de veu següent" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Canvia al perfil de configuració següent" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Canvia a l'estil de majúscules següent" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Canvia al nivell d'eco següent" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Canvia el nivell de depuració en temps d'execució" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Marca on soc respecte de la posició actual" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Ves a la ubicació del marcador anterior" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Ves al marcador" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Ves a la ubicació del marcador següent" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Afegeix un marcador" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Desa els marcadors" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Commuta al mode de revisió de ratolí" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Mostra l'hora actual" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Mostra la data actual" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Informa de la mida i localització de l'objecte actiu" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Passa l'ordre següent a l'aplicació actual" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Pronuncia i posa el braille de l'anterior missatge de la sala de xat" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Commuta si s'ha d'anunciar quan els nostres amics estiguin escrivint" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Commuta si es proporcionen historials de missatges específics per a les " -"sales de xat" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Commuta el posar un prefix amb el nom de la sala de xat en els missatges de " -"les sales de xat" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Línia esquerra" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Línia dreta" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Línia amunt" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Línia avall" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Congela" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "A dalt a l'esquerra" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "A baix a l'esquerra" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posició del cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Sis punts" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Encaminament del cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Inici de selecció" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Final de selecció" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Presenta l'últim missatge de notificació" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Presenta la llista de missatges de notificació" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Presenta el missatge de notificació anterior" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Presenta el missatge de notificació següent" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Ves al caràcter següent" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Ves al caràcter anterior" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Ves a la paraula següent" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Ves a la paraula anterior" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Ves a la línia següent" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Ves a la línia anterior" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Ves a dalt de tot de la fila" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Ves a baix de tot de la fila" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Ves a l'inici de la línia" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Ves al final de la línia" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Ves a l'objecte següent" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Ves a l'objecte anterior" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Fa que el quadre combinat actiu s'expandeixi" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Canvia entre la navegació de cursor nadiua i la del lector de pantalla" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Avança el paràmetre de la netedat de les regions dinàmiques" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Desactiva el nivell de la netedat de les regions dinàmiques" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Revisa els anunciaments de les regions dinàmiques" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Fes un seguiment de les regions dinàmiques" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Mou el focus a dins i fora d'on plana el ratolí actualment" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" -"Estableix quina fila s'ha d'utilitzar com a capçaleres de columna dinàmiques" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Neteja la capçalera de columna dinàmica" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" -"Estableix la columna que s'ha d'utilitzar com a capçaleres de fila dinàmiques" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Neteja les capçaleres de fila dinàmiques" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Presenta el contingut de la línia d'entrada" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Commuta les tecles de navegació estructural" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Ves a la cita en bloc anterior" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Ves a la cita en bloc següent" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Mostra una llista de cites en bloc" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Ves al botó anterior" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Ves al botó següent" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Mostra una llista de botons" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Ves a la casella de selecció anterior" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Ves a la casella de selecció següent" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Mostra una llista de caselles de selecció" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Ves a l'element clicable anterior" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Ves a l'element clicable següent" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Mostra una llista dels elements clicables" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Ves al quadre combinat anterior" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Ves al quadre combinat següent" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Ves a l'inici del contenidor" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Ves al final del contenidor" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Mostra una llista de quadres combinats" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Ves a l'entrada anterior" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Ves a l'entrada següent" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Mostra una llista d'entrades" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Ves al camp del formulari anterior" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Ves al camp del formulari següent" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Mostra una llista de camps de formulari" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Ves a la capçalera anterior" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Ves a la capçalera següent" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Mostra una llista de capçaleres" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Ves a la capçalera de nivell %d anterior" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Ves a la capçalera de nivell %d següent" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Mostra una llista de capçaleres de nivell %d" - -# He trobat traduccions com "marc intern" i com a "fotograma", però potser els internal frames fan referència a subfinestres filles (dins) d'una finestra principal. Ja que els marcs d'una web són "inline frames"... -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Ves al marc intern anterior" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Ves al marc intern següent" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Mostra una llista de marcs interns" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Ves a la imatge anterior" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Ves a la imatge següent" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Mostra una llista d'imatges" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Ves a la marca important anterior" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Ves a la marca important següent" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Mostra una llista de punts de referència" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Ves a l'objecte gran anterior" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Ves a l'objecte gran següent" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Mostra una llista d'objectes grans" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Va a l'enllaç anterior" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Va a l'enllaç següent" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Mostra una llista d'enllaços" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Ves a la llista anterior" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Ves a la llista següent" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Mostra una llista de llistes" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Ves a l'element de la llista anterior" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Ves a l'element de la llista següent" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Mostra una llista d'elements de llista" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Ves a la regió dinàmica anterior" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Ves a la regió dinàmica següent" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Ves a l'última regió dinàmica que ha fet un anunci" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Ves al pare de l'objecte que té el focus del navegador." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Ves al primer fill de l'objecte que té el focus del navegador." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Ves al germà següent de l'objecte que té el focus del navegador." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Ves al germà anterior de l'objecte que té el focus del navegador." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Fes clic a l'objecte que té el focus del navegador." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Commuta la navegació simplificada entre objectes." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Ves al paràgraf anterior" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Ves al paràgraf següent" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Mostra una llista de paràgrafs" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Ves al botó d'opció anterior" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Ves al botó d'opció següent" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Mostra una llista de botons d'opció" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Ves al separador anterior" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Ves al separador següent" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Ves a la taula anterior" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Ves a la taula següent" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Mostra una llista de taules" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Ves a la cel·la de sota" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Ves a la primera cel·la de la taula" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Ves a l'última cel·la de la taula" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Ves a la cel·la de l'esquerra" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Ves a la cel·la de la dreta" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Ves a la cel·la de sobre" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Commuta al mode de disposició" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Commuta entre el mode de navegació i el mode de focus" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Habilita el mode de focus enganxós" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Habilita el mode de navegació enganxós" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Ves a l'enllaç sense visitar anterior" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Ves a l'enllaç sense visitar següent" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Mostra una llista d'enllaços no visitats" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Ves a l'enllaç visitat anterior" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Ves a l'enllaç visitat següent" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Mostra una llista d'enllaços visitats" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "blau alice" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "blanc antic" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "aiguamarina" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "atzur" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beix" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "crema" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "negre" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "ametlla blanca" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blau" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "blau violeta" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "marró" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "marró burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "blau cadet" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "verd chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "xocolata" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "taronja coral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "blau cornflower" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "marró cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "vermell crimson" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cian" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "blau fosc" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "cian fosc" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "marró goldenrod fosc" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "gris fosc" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verd fosc" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "caqui fosc" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta fosc" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "verd oliva fosc" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "taronja fosc" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "porpra orquídia fosc" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "vermell fosc" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmó fosc" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "verd mar fosc" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "blau pissarra fosc" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "gris pissarra fosc" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turquesa fosc" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violeta fosc" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "rosa profund" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "blau cel profund" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "gris lleuger" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "blau dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "totxo foc" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "blanc floral" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "verd bosc" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fúcsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gris gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "blanc fantasma" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "or" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "marró goldenrod" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "gris" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verd" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "groc verd" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "blanc honeydew" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "rosa calent" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "vermell indi" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indi" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "marfil" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "caqui" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "blanc lavanda rubor" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "verd pradera" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "groc llimona gasa" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "blau clar" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "vermell coral clar" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "cian clar" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "groc goldenrod clar" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "gris clar" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "verd clar" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "rosa clar" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmó clar" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "verd mar clar" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "blau cel clar" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "gris pissarra clar" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "blau metàl·lic clar" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "groc clar" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "llima" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "verd llima" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "blanc lli" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "granat" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "verd aiguamarina mig" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "blau mitjà" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orquídia mig" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "porpra mitjà" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "verd mar mitjà" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "blau pissarra mitjà" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "verd primavera mig" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turquesa mitjà" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "vermell violeta mig" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "blau mitjanit" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "crema de menta" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rosa boirós" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "groc mocassí" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "blanc navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "marí" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "blanc oldlace" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliva" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "verd oliva monòton" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "taronja" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "vermell taronja" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orquídia" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "groc goldenrod pàl·lid" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "verd pàl·lid" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turquesa pàl·lid" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "vermell violeta pàl·lid" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "groc papaia whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "groc préssec puff" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "marró perú" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "pruna" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "blau pols" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "porpra" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "vermell" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "marró rossenc" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "blau reial" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "marró cadira de muntar" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmó" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "marró arenós" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "verd mar" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "petxina" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "plata" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "cel blau" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "blau pissarra" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "gris pissarra" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "neu" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "verd primavera" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "blau metàl·lic" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "canyella" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "xarxet" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "card" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomàquet" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquesa" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violeta" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "blat" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "blanc" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "blanc fumat" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "groc" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "verd groc" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Activa" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Mode de focus automàtic en la navegació estructural" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Mode de focus automàtic en la navegació de cursor" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Mode de focus automàtic durant la navegació nadiua" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punt _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punt _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Punts 7 _i 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Cancel·la" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Ves a" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_D'acord" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Icona" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Cap" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Pronuncia" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Anuncia quan els nostres _amics estiguin escrivint" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Proporciona historials de _missatges específics per les sales de xat" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Pronuncia els missatges de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Tots els ca_nals" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Tots els canals quan _qualsevol finestra de %s estigui activa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Un canal només si és de la _finestra activa" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Pronuncia el nom de la sala de xat" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Habilita el mode disposició per al contingut" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "doble clic" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triple clic" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetitzador predeterminat" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Frase" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Text explicatiu" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Habilita l'eco per _caràcter" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Habilita les tecles _diacrítiques sense espai" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Ubicació actual" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Mida mínima del text de coincidència:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opcions de cerca" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Pronuncia només les línies diferents durant la _cerca" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Pronuncia els resultats durant la _cerca" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Ordre" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Vinculació de tecla" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Per defecte" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Mode d'aprenentatge" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Accions" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Vinculacions de Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Marcadors" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Data i hora" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Mode de revisió de ratolí" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Navegador per objectes" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Detalls de l'objecte" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Sense vincle" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Revisió plana" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Nivell de detall de la pronunciació" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Continguts de la revisió plana" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificada" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Escriptori" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificacions" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Rebudes" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Presentació de notificacions" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferències de Cthulhu per a %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marca-ho en braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Present a menys que" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Pronuncia" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Desa el perfil com a conflictiu" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Hi ha un conflicte en el perfil d'usuari!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Ja existeix el perfil %s.\n" -"Voleu actualitzar-lo amb aquests canvis?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Carrega el perfil d'usuari" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Esteu a punt de canviar el perfil actiu. Si heu fet\n" -"canvis a les preferències es perdran en carregar\n" -"el perfil.\n" -"\n" -"Voleu continuar carregant el perfil obviant els canvis anteriors?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Desa el perfil com a" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nom del _perfil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Suprimeix el perfil d'usuari" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Esteu a punt de suprimir el perfil %s. Tots els paràmetres desats i no " -"desats en aquest perfil es perdran. Voleu continuar i suprimir aquest perfil " -"i tots els seus paràmetres associats?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Totes" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicació" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Finestra" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Cap" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Algu_ns" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "M_olts" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Línia" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Frase" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Cita en bloc" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Botó" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Títol" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Casella de selecció" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Clicable" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Quadre combinat" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descripció" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Encapçalament" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Marc intern" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imatge" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiqueta" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Punt de referència" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivell" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Enllaç" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Llista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Element de llista" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objecte" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paràgraf" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Botó d'opció" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rol" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Element seleccionat" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Estat" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valor" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Cites en bloc" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botons" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Caselles de selecció" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Clicables" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Quadres combinats" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entrades" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Camps de formulari" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Encapçalaments" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Marcs interns" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imatges" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Encapçalaments de nivell %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Punts de referència" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Objectes grans" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Enllaços" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Llistes" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Elements de llista" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paràgrafs" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Botons d'opció" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Taules" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Enllaços sense visitar" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Enllaços visitats" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navegació web" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Quan es _carregui la pàgina comença a pronunciar-la automàticament" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Resum _present d'una pàgina quan es carrega per primer cop" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Separa la pronunciació en _parts entre les pauses" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Veu predeterminada del %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Predeterminada" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Enllaç" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Majúscules" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Distribuïdor de pronunciació" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Comprovació de l'ortografia" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Pronuncia l'_error" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Pronuncia el _suggeriment" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Presenta el _context de l'error" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Pronuncia les coordenades de la cel·la del full de càlcul" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Pronuncia sempre el rang seleccionat del full de càlcul" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Anuncia la _capçalera de la cel·la" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navegació de taules" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Salta't les cel·les en _blanc" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Pronuncia la _cel·la" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Pronuncia les coordenades de la _cel·la" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Pronuncia les extensions _múltiples de cel·les" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nom de l'atribut" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Controla la navegació de cursor" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Habilita la navegació _estructural" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Tema de so:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Tema de so" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "In_forme" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d notificació" -msgstr[1] "%d notificacions" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Tecla majúscula" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Tecla alternativa dreta" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Tecla de control esquerre" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "majúscula esquerra" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alternativa esquerra" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control esquerre" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "majúscula dreta" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alternativa dreta" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control dreta" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta esquerra" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta dreta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "fixació de teclat numèric" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "fixació de majúscules" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "bloqueig de majúscules" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "bloqueig de moviment" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "pàgina amunt" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "pàgina avall" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tabulació esquerra" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "retrocés" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "retorn" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "retorn" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "amunt" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "avall" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "esquerra" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "dreta" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "súper esquerra" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "súper dreta" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menú" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Tecla d'alternativa gràfica" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ajuda" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multiplica" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "canvi de mode" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escapada" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "inserció" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "supressió" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "inici" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "fi" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "començament" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "cercle" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "barrada" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "menys" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Tecla d'inserció" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Bloqueig de majúscu_les" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alternativa dreta" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Súper" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alternativa esquerra" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Majúscula" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "negreta %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "cursiva %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "itàlica negreta %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "subíndex %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "subíndex negreta %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "double-struck %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "fraktur negreta %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif negreta %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif itàlica %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif itàlica negreta %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "espai simple %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s sense punt" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "fletxa esquerra" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "fletxa cap amunt" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "fletxa dreta" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "fletxa cap avall" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "fletxa dreta esquerra" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "fletxa cap amunt i cap avall" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "fletxa nord-oest" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "fletxa nord-est" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "fletxa sud-est" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "fletxa esquerra des de la barra" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "fletxa amunt des de barra" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "fletxa dreta des de la barra" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "fletxa avall des de barra" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "fletxa doble esquerra" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "fletxa doble cap amunt" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "fletxa doble dreta" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "fletxa doble cap avall" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "fletxa doble dreta esquerra" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "fletxa doble amunt i avall" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "fletxa doble a nord-oest" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "fletxa doble al nord-est" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "fletxa doble al sud-est" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "fletxa doble al sud-oest" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "fletxa que apunta cap a la dreta" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "punta de fletxa que apunta cap a la dreta" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "menys" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "més petit que" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "més gran que" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punt" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "línia vertical doble" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "el·lipsi horitzontal" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "per a tot" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "diferencial parcial" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "hi existeix" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "no hi existeix" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "conjunt buit" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "increment" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "element de" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "no és un element de" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "element petit de" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "conté com a membre" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "no conté com a mmbre" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "conté com a membre petit" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "final de la prova" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "producte" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproducte" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sumatòria" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "menys o més" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "més amb punt" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "barra de divisió" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "menys de conjunt" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operador asterisc" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operador d'anell" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operador punt" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "arrel quadrada" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "arrel cúbica" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "arrel quarta" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcional amb" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinit" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "angle dret" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "angle" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "angle mesurat" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "angle esfèric" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "divideix" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "no divideix" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paral·lel a" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "no paral·lel a" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "i lògic" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "o lògic" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersecció" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unió" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integral doble" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integral triple" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integra de contorn" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integral de superfície" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integral de volum" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral en sentit de les agulles del rellotge" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integral de contorn en sentit de les agulles del rellotge" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integral de contorn en sentit contrari a les agulles del rellotge" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "en conseqüència" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "perquè" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "divisió" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporció" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "menys amb punt" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "excés" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporció geomètrica" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotètic" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "titlla" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "titlla revertit" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "S invertida mandrosa" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "onada sinus" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "producte corona" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "no titlla" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "menys titlla" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asimptòticament igual a" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "no asimptòticament igual a" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "aproximadament igual a" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "aproximadament, però en realitat no igual a" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ni aproximadament ni en realitat igual a" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "gairebé igual a" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "no gairebé igual a" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "gairebé igual a o igual a" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "titlla triple" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "tot igual a" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "equivalent a" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geomètricament equivalent a" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "diferència entre" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "s'aproxima al límit" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geomètricament igual a" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "aproximadament igual a la imatge de" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "imatge de o aproximadament igual a" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dos punts igual a" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "igual dos punts" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "igual a amb anell a dins" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "anell igual a" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "correspon a" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estima" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "equiangular a" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "estrella igual" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta igual a" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "per definició igual a" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "mesurat per" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "interrogació igual a" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "diferent de" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "idèntic a" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "no idèntic a" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "estrictament equivalent a" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "més petit o igual a" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "més gran o igual a" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "més petit sobre igual a" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "més gran sobre igual a" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "més petit però no igual a" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "més gran però no igual a" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "molt més petit que" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "molt més gran que" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "entre" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "no equivalent a" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "no més petit que" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "no més gran que" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ni més petit que ni igual a" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ni més gran ni igual a" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "més petit o equivalent a" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "més gran o equivalent a" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ni més petit que ni equivalent a" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ni més gran ni equivalent a" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "més petit o més gran que" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "més gran o més petit que" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ni més petit que ni més gran que" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ni més gran que ni més petit que" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "precedeix" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "succeeix" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "precedeix o igual a" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "succeeix o igual a" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "precedeix o equivalent a" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "succeeix o equivalent a" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "no precedeix" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "no succeeix" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subconjunt de" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superconjunt de" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "no un subconjunt de" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "no a superconjunt de" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subconjunt de o igual a" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superconjunt de o igual a" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ni un subconjunt de ni igual a" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ni un superconjunt de ni igual a" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subconjunt de amb no igual a" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superconjunt de amb no igual a" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiconjunt" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiplicació de multiconjunt" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "unió de multiconjunt" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "imatge quadrada de" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "original quadrada de" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "imatge quadrada de o igual a" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "quadrat original de o igual a" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "tapa quadrada" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "copa quadrada" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "més encerclat" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "menys encerclat" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "producte encerclat" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "barra de divisió encerclada" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "producte de punt encerclat" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operador d'anell encerclat" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operador asterisc encerclat" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "igual encerclat" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "guió encerclat" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "més enquadrat" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "subíndex enquadrat" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "per enquadrat" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operador de punt enquadrat" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "tatxa dreta" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "tatxa esquerra" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "tatxa cap avall" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "tatxa cap amunt" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "asserció" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "models" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "cert" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "força" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "torniquet dreta de barra vertical triple" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "doble torniquet dreta de barra doble vertical" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "no prova" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "no cert" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "no força" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "torniquet dreta doble amb barra vertical doble negada" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "precedeix sota relació" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "succeeix sota relació" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "subgrup normal de" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "conté com a subgrup normal" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "subgrup normal de o igual a" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "conté com a subgrup normal de o igual a" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original de" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "imatge de" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matriu conjugada hermitiana" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalat" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "angle dret amb un arc" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triangle dret" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operador diamant" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operador punt" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operador estrella" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "divisió per" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "corbatí" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "producte semidirecte de factor normal esquerre" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "producte semidirecte de factor normal dret" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "producte semidirecte esquerre" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "producte semidirecte dret" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "titlla revertida igual" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "lògic corbat o" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "lògic corbat i" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "subconjunt doble" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "superconjunt doble" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "intersecció doble" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "unió doble" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "fcthulhu" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "igual i paral·lel a" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "més petit que amb punt" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "més gran que amb punt" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "molt més petit que" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "molt més gran que" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "més petit igual a o més gran que" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "més gran igual a o més petit que" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "igual o més petit que" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "igual o més gran que" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "igual a o precedeix" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "igual o succeeix" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "no precedeix o igual" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "no succeeix o igual" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "no imatge quadrada de o igual a" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "no quadrat original de o igual a" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "imatge quadrada de o no igual a" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "quadrat original de o no igual a" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "més petit però no equivalent a" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "més gran que però no equivalent a" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "precedeix però no equivalent a" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "succeeix però no equivalent a" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "no subgrup normal de" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "no conté com a subgrup normal" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "no subgrup normal de o igual a" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "no conté com a subgrup normal o igual" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "el·lipsi vertical" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "el·lipsi horitzontal de línia mitjana" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "el·lipsi diagonal cap amunt a la dreta" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "el·lipsi diagonal cap avall a la dreta" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "element de amb línia horitzontal llarga" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "element de amb barra vertical al final de la línia horitzontal" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "element de petit amb barra vertical al final de la línia horitzontal" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "element de amb un punt a sobre" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "element de amb una barra a sobre" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "element de petit amb barra a sobre" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "element de amb barra a sota" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "element de amb dues línies horitzontals" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "conté amb línia horitzontal llarga" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "conté amb barra vertical al final de la línia horitzontal" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "conté petit amb barra vertical al final de la línia horitzontal" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "conté amb barra a sobre" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "conté petit amb barra a sobre" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "afiliació bossa de notació z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "sostre esquerre" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "sostre dret" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "terra esquerre" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "terra dret" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "claudàtor superior" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "claudàtor inferior" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "parèntesi angular esquerre" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "parèntesi angular dret" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "punt encerclat" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "unió amb punt" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "unió amb més" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "intersecció quadrada" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "unió quadrada" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "quadrat negre" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "quadrat blanc" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "diamant negre" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "cercle blanc" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "cercle negre" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bala blanca" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "quadrat petit mitjà negre" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s amb subratllat" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s amb barra inclinada cap endavant" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s amb línia vertical" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplicació" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "buida" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "negreta" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "s'ha introduït el marcador" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "s'han desat els marcadors" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "no s'han pogut desar els marcadors" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "No s'ha trobat cap marcador." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Marcador no trobat." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "S'ha habilitat el mode d'omissió." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "No s'ha pogut obtenir la pantalla de la calculadora" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "icona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "S'ha establert l'estil de majúscules a icona." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "cap" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "S'ha establert l'estil de majúscules a cap." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "pronuncia" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "S'ha establert l'estil de majúscules a pronunciació." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "L'aplicació està controlant el cursor." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu està controlant el cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cel·la %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s seleccionada" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "S'ha seleccionat des de %s fins a %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "S'ha desseleccionat des de %s fins a %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "S'ha desseleccionat %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Evita l'ús de l'opció" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Força l'ús de l'opció" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCIÓ" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Arguments opcionals" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Ús: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Els següents no són vàlids: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Mostra les aplicacions que se sap que s'estan executant" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Carrega un perfil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "No s'ha pogut carregar el perfil: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"No es pot iniciar Cthulhu perquè no es pot connectar a l'escriptori.No es " -"pot iniciar el lector de pantalla perquè no es pot connectar a l'escriptori." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "No es pot activar el gestor de la configuració. Se surt." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Ja s'està executant un altre lector de pantalla en aquesta sessió.\n" -"Executeu «cthulhu --replace» per a reemplaçar l'altre procés en execució per " -"una instància nova." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOM" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Utilitza un directori alternatiu per a les preferències d'usuari" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIRECTORI" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versió d'aquesta aplicació" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Substitueix una instància de Cthulhu en execució" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Mostra aquest missatge d'ajuda i surt" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" -"Envia la informació de depuració al fitxer depuracio-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Envia la informació de depuració al fitxer especificat" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FITXER" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Configura les preferències de l'usuari (versió text)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Configura les preferències de l'usuari (versió gràfica)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Informeu d'errors a https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Retalla la selecció al porta-retalls." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "retalla" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "S'ha copiat la selecció al porta-retalls." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copiat" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "S'ha enganxat el contingut del porta-retalls." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "enganxat" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "No ho anunciïs quan els teus amics estiguin escrivint." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anuncia quan els teus amics estiguin escrivint." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Missatge de la sala de xat %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Pestanya nova de xat %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "No pronunciïs el nom de la sala de xat." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "pronuncia el nom de la sala de xat." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "No proporcionis missatges històrics específics per a les sales de xat." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Proporciona missatges històrics específics per a les sales de xat." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "inici de supressió" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "final de supressió" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "inici d'inserció" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "final d'inserció" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "inici del ressaltat" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "final del ressaltat" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "final del suggeriment" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Final del contenidor." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "No sou en un contenidor." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "tots els elements seleccionats" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "El botó predeterminat és %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "El botó predeterminat és %s. Ombrejat" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "No s'ha trobat el botó predeterminat" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subíndex %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " superíndex %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "No sou en una diàleg" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "seleccionat tot el document" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "s'ha desseleccionat tot el document" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "document seleccionat des de la posició del cursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "s'ha tret la selecció del document des de la posició del cursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "document seleccionat fins a la posició del cursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "s'ha tret la selecció del document fins a la posició del cursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "S'ha establert la capçalera de columna dinàmica per a la fila %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "S'ha netejat la capçalera de columna dinàmica." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "S'ha establert la capçalera de fila dinàmica per a la columna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "S'ha netejat la capçalera de fila dinàmica." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "buit" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "No s'ha trobat cap fitxer." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "S'ha afegit el contingut al porta-retalls." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "S'ha copiat el contingut al porta-retalls." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "No s'està utilitzant la revisió plana." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "S'està entrant a la revisió plana." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "S'està sortint de la revisió plana." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Revisió plana restringida a l'objecte actiu" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Revisió plana sense restriccions" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "conté una fórmula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "obre el diàleg" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "obre la graella" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "obre el quadre de llista" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "obre el menú" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "obre l'arbre" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "enllaç de mapa d'imatges" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "La tecla introduïda ja està vinculada a %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "S'ha capturat la tecla %s. Premeu retorn per a confirmar-la." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "La tecla nova és: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" -"S'ha suprimit la vinculació de tecla. Premeu retorn per a confirmar-ho." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "S'ha suprimit la vinculació de tecla." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "teclegeu la tecla nova" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "lletra" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "S'ha establert l'eco a la lletra." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Cap" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "S'ha establert que no hi haurà eco." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "lletra i paraula" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "S'ha establert l'eco a la lletra i al mot." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "frase" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "S'ha establert l'eco a l'oració." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "paraula" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "S'ha establert l'eco al mot." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "paraula i frase" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "S'ha establert l'eco al mot i a l'oració." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Envoltat per: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "un símbol actuarial" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "una caixa" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "un cercle" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "un signe de divisió llarg" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "un radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "una caixa arrodonida" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "una ratlla horitzontal" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "una ratlla vertical" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "una ratlla diagonal cap avall" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "una ratlla diagonal cap amunt" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "una fletxa nord-est" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "una línia al peu" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "una línia a l'esquerra" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "una línia a la dreta" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "una línia a la part superior" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "un angle fasor" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "un símbol factorial aràbic" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "i" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "inici de fracció" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "fracció sense barra, inici" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "dividit per" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "final de fracció" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "arrel quadrada de" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "arrel cúbica de" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "arrel de" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "inici d'arrel" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "final d'arrel" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subíndex" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "superíndex" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pre-subíndex" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pre-superíndex" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "text escrit a sota" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "text escrit a sobre" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "final de taula" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "final de taula imbricada" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessible" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Inhabilitat" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "S'ha inhabilitat la pronunciació del sagnat i la justificació." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Habilitat" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "S'ha habilitat la pronunciació del sagnat i la justificació." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Mode d'aprenentatge. Premeu la tecla d'escapament per a sortir." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"S'està entrant al mode d'aprenentatge. Premeu qualsevol tecla per a sentir-" -"ne la seva funció. Per a veure la documentació del lector de pantalla, " -"premeu F1. Per a obtenir la llista de dreceres per defecte del lector de " -"pantalla, premeu F2. Per a obtenir la llista de dreceres del lector de " -"pantalla per l'aplicació actual, premeu F3. Per a sortir del mode " -"d'aprenentatge premeu la tecla d'escapada." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "s'està sortint de la cita en bloc." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "s'està sortint dels detalls." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "s'està sortint del canal." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "s'està sortint de la figura." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "s'està sortint del formulari." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "s'està sortint del bàner." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "s'està sortint del contingut complementari." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "s'està sortint de la informació." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "s'està sortint del contingut principal." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "s'està sortint de la navegació." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "s'està sortint de la regió." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "s'està sortint de la cerca." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "s'està sortint de la llista." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "s'està sortint del quadre." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "s'està sortint de la taula." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "s'està sortint de l'indicador de funció." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "s'està sortint del resum." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "s'està sortint dels reconeixements." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "s'està sortint de l'epíleg." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "s'està sortint de l'apèndix." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "s'està sortint de la bibliografia." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "s'està sortint del capítol." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "s'està sortint del colofó." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "s'està sortint de la conclusió." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "s'està sortint del crèdit." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "s'està sortint dels crèdits." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "s'està sortint de la dedicatòria." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "s'està sortint de les notes finals." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "s'està sortint de l'epígraf." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "s'està sortint de l'epíleg." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "s'està sortint de l'errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "s'està sortint de l'exemple." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "s'està sortint del prefaci." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "s'està sortint del glossari." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "s'està sortint de l'índex." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "s'està sortint de la introducció." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "s'està sortint de la llista de pàgines." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "s'està sortint de la part." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "s'està sortint del pròleg." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "s'està sortint del pròleg." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "s'està sortint de la cita destacada." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "s'està sortint de les preguntes i respostes." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "s'està sortint del suggeriment." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "s'està sortint de la taula de continguts." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "seleccionada la línia per sota de la posició del cursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "seleccionada la línia per sobre de la posició del cursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "s'ha tret la selecció de la línia de sota la posició del cursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "s'ha tret la selecció de la línia per sobre de la posició del cursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "S'està sortint del mode d'aprenentatge." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" -"línia seleccionada des de l'inici fins a la posició on estava abans el cursor" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "línia seleccionada fins al final de la línia on estava abans el cursor" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "enllaç" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "la mateixa pàgina" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "el mateix lloc" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "lloc diferent" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s enllaça a %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "enllaç %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "enllaç %s visitat" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Utilitzeu les tecles cap amunt i cap avall per a navegar per la llista. " -"Premeu la tecla d'escapament per a sortir." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Desactiva totes les regions dinàmiques" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "s'han restaurat els nivells d'educació de les regions dinàmiques" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nivell d'educació %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "estableix la regió dinàmica a enèrgica" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "desactiva la regió dinàmica" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "estableix la regió dinàmica a educada" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "estableix la regió dinàmica a grollera" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "No s'està fent un seguiment de les regions dinàmiques" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "S'està fent un seguiment de les regions dinàmiques" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "no s'ha desat el missatge dinàmic" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Les regions dinàmiques estan desactivades" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "No s'ha trobat" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "No s'ha pogut determinar la ubicació actual." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "inactiu" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "actiu" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "paraula mal escrita" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Paraula mal escrita: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "El context és %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Mode de navegació" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Mode de focus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Per a habilitar el mode de focus premeu %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "El mode de focus és enganxós." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "El mode de navegació és enganxós." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Mode de disposició." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Mode d'objecte." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "S'ha mogut el punter a l'objecte." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "No s'ha trobat l'objecte on plana el ratolí." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "S'ha inhabilitat el mode de revisió de ratolí." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "S'ha habilitat el mode de revisió de ratolí." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "S'ha produït un error: no s'ha pogut crear una llista d'objectes." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "L'objecte actiu no té fills." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "L'objecte actiu no té germans següents." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "L'objecte actiu no té pare." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "L'objecte actiu no té germans anteriors." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "S'ha habilitat la navegació simplificada." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "S'ha inhabilitat la navegació simplificada." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nivell d'imbricació %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "S'ha afegit un element nou" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "No s'ha trobat cap acció a: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Sense focus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "No hi ha cap aplicació que tingui el focus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "No hi ha cap cita en bloc." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "No hi ha cap més botons." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "No hi ha cap més casella de selecció." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "No hi ha cap més objecte gran." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "No hi ha cap més element clicable." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "No hi ha cap més quadre combinat." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "No hi ha cap més entrada." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "No hi ha cap més entrada de formulari." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "No hi ha cap més capçalera." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "No hi ha cap més capçalera de nivell %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "No hi ha cap més marc intern." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "No hi ha cap més imatge." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "No s'ha trobat cap marca important." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "No hi ha cap més enllaç." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "No hi ha cap més llista." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "No hi ha cap més element de llista." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "No hi ha cap més regió dinàmica." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "No hi ha cap més paràgraf." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "No hi ha cap més botó d'opció." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "No hi ha cap més separador." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "No hi ha cap més taula." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "No hi ha cap més enllaç sense visitar." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "No hi ha cap més enllaç visitat." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "No hi ha un text seleccionat." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "No esteu sobre un enllaç." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificació" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "A baix de tot" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "A dalt de tot" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "No hi ha cap missatge de notificació" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "dígits" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Pronuncia els nombres com a dígits." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "paraules" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Pronuncia els nombres com paraules." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "inactiu" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "actiu" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "S'està carregant. Espereu." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "S'ha acabat de carregar." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "S'ha acabat de carregar el %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "La pàgina té %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "pàgina seleccionada des de la posició del cursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "pàgina seleccionada fins a la posició del cursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "s'ha tret la selecció de la pàgina des de la posició del cursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "s'ha tret la selecció fins a la posició del cursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "s'ha seleccionat el paràgraf des de la posició del cursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "s'ha seleccionat el paràgraf fins a la posició del cursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "s'ha tret la selecció del paràgraf des de la posició del cursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "s'ha tret la selecció del paràgraf fins a la posició del cursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Ja teniu obert el diàleg de preferències de l'Cthulhu.\n" -"Tanqueu-lo abans d'obrir-ne un altre." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapositiva %(position)d de %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "S'ha establert el perfil a %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "No s'ha trobat cap perfil." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra de progrés %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Totes" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "S'ha establert el nivell de pronunciació de la puntuació a totes." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "La majoria" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "S'ha establert el nivell de pronunciació de la puntuació a la majoria." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Cap" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "S'ha establert el nivell de pronunciació de la puntuació a cap." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Algunes" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "S'ha establert el nivell de pronunciació de la puntuació a algunes." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "S'està cercant." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "S'ha completat la cerca." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "S'han tornat a carregar els paràmetres de Cthulhu." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "El text seleccionat és: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "S'ha esborrat la selecció." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "S'ha restaurat la selecció." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Text ja no seleccionat." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Mida: %d, %d. Posició: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Amplada: %d. Alçada: %d. %d des de l'esquerra. %d des de dalt." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "S'ha inhabilitat la pronunciació." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "S'ha habilitat la pronunciació." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "més ràpid." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "més lent." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "més alt." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "més baix." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "més alt." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "més suau." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Velocitat %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "To %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volum %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Mòdul Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Veu Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "No hi ha mòduls Speech-dispatcher disponibles" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "No hi ha veus Speech-dispatcher disponibles" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "S'han desat els paràmetres de veu" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "No s'han pogut desar els paràmetres de veu" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Nivell de detall: breu" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Nivell de detall: detallat" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " punt punt punt" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu us dóna la benvinguda." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu aguaita sota les onades." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Mode de suspensió activat per a %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Mode de suspensió desactivat per a %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "La pronunciació no està disponible." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "No s'ha trobat" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "No s'ha trobat la barra d'estat" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "no s'ha trobat la cadena" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Les tecles de navegació estructural estan desactivades." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Les tecles de navegació estructural estan activades." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "No s'ha trobat" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Fila %(row)d, columna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Final de la taula" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Pronuncia la cel·la" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Pronuncia la fila" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "No uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "No sou en una taula." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "S'han reordenat les columnes" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "S'han reordenat les files" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "columna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "columna %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "A baix de tot de la columna." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "A dalt de tot de la columna." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "S'ha seleccionat la columna %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "S'han seleccionat les columnes entre %s i %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Columnes des de %s fins a %s desseleccionades" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "S'ha desseleccionat la columna %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "fila %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "fila %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Inici de la fila." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Final de la fila." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "S'ha suprimit la fila." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "S'ha suprimit l'última fila." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "S'ha inserit una fila." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "S'ha inserit una fila al final de la taula." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "S'ha seleccionat la fila %s" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "S'han seleccionat les files entre %s i %s" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "S'han desseleccionat les files entre %s i %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "S'ha desseleccionat la fila %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "seleccionat" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "desel" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H hores, %M minuts i %S segons" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H hores i %M minuts" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "desfés" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "refés" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versió %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "espai en blanc" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Continua la cerca des de baix." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Continua la cerca des de dalt." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elements" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "La cel·la s'expandeix %d fila" -msgstr[1] "La cel·la s'expandeix %d files" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d columna" -msgstr[1] " %d columnes" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "La cel·la s'expandeix %d columna" -msgstr[1] "La cel·la s'expandeix %d columnes" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d caràcter massa llarg" -msgstr[1] "%d caràcters massa llarg" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d diàleg)" -msgstr[1] "(%d diàlegs)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d diàleg sense focus" -msgstr[1] "%d diàlegs sense focus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fitxer trobat" -msgstr[1] "%d fitxers trobats" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulari" -msgstr[1] "%d formularis" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d encapçalament" -msgstr[1] "%d encapçalaments" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elements" -msgstr[1] "%d elements" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Punt de referència %d" -msgstr[1] "Punts de referència %d" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "S'ha trobat %d element" -msgstr[1] "S'han trobat %d elements" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "S'està sortint de %d cita en bloc." -msgstr[1] "S'està sortint de %d cites en bloc." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "S'està sortint de %d llista." -msgstr[1] "S'està sortint de %d llistes." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Llista de mida desconeguda" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Llista amb %d element" -msgstr[1] "Llista amb %d elements" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Canal de mida desconeguda" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Canal amb %d article" -msgstr[1] "Canal amb %d articles" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Llista de descripció amb %d terme" -msgstr[1] "Llista de descripció amb %d termes" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d valor" -msgstr[1] "%d valors" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "taula matemàtica amb %d fila" -msgstr[1] "taula matemàtica amb %d files" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d columna" -msgstr[1] "%d columnes" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "taula matemàtica imbricada amb %d fila" -msgstr[1] "taula matemàtica imbricada amb %d files" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d missatge.\n" -msgstr[1] "%d missatges.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d per cent." -msgstr[1] "%d per cent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "s'ha llegit l'%d per cent del document" -msgstr[1] "s'ha llegit el %d per cent del document" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d píxel" -msgstr[1] "%d píxels" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d caràcter %(repeatChar)s" -msgstr[1] "%(count)d caràcters %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "seleccionat %(index)d element de %(total)d" -msgstr[1] "seleccionats %(index)d elements de %(total)d" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "S'ha trobat %d drecera per defecte del lector de pantalla." -msgstr[1] "S'han trobat %d dreceres per defecte del lector de pantalla." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"S'ha trobat %(count)d drecera del lector de pantalla per a %(application)s." -msgstr[1] "" -"S'han trobat %(count)d dreceres del lector de pantalla per a %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espai" -msgstr[1] "%d espais" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulació" -msgstr[1] "%d tabulacions" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d taula" -msgstr[1] "%d taules" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "taula de mida desconeguda" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "taula amb %d columna, nombre de files desconegut" -msgstr[1] "taula amb %d columnes, nombre de files desconegut" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "taula amb %d fila, nombre de columnes desconegut" -msgstr[1] "taula amb %d files, nombre de columnes desconegut" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "taula amb %d fila" -msgstr[1] "taula amb %d files" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "fa %d segon" -msgstr[1] "fa %d segons" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "fa %d minut" -msgstr[1] "fa %d minuts" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "fa %d hora" -msgstr[1] "fa %d hores" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "fa %d dia" -msgstr[1] "fa %d dies" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d enllaç sense visitar" -msgstr[1] "%d enllaços sense visitar" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d enllaç visitat" -msgstr[1] "%d enllaços visitats" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "commuta" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "al %(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "element %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVELL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nivell de l'arbre %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVELL DE L'ARBRE %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detalls per a %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "té detalls a %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "suggeriment" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "quadre combinat editable" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "contingut editable" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "canal" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figura" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "resum" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "reconeixements" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "epíleg" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "apèndix" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "entrada de bibliografia" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografia" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "capítol" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colofó" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conclusió" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "portada" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "crèdit" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "crèdits" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedicatòria" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "nota final" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "notes finals" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epígraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epíleg" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "exemple" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "prefaci" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glossari" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "índex" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introducció" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "salt de pàgina" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "llista de pàgines" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "part" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "pròleg" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "pròleg" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "cita destacada" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Preguntes i respostes" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "subtítol" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "taula de continguts" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "c%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivell %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "barra de desplaçament horitzontal" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "barra de desplaçament vertical" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "lliscador horitzontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "lliscador vertical" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "separador horitzontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "separador vertical" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "commutador" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Icona del quadre" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "bàner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "contingut complementari" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informació" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "contingut principal" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navegació" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "regió" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "cerca" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "enllaç visitat" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "botó de menú" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "ordre ascendent" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "ordre descendent" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "ordenat" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "clicable" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "col·lapsat" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "expandit" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "té una descripció llarga" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horitzontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "verificat" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "no verificat" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "actiu" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "inactiu" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "verificat parcialment" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "premut" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "no premut" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "no seleccionat" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "seleccionat" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "no seleccionat" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "no seleccionada" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visitat" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "sense visitar" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ombrejat" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "només lectura" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "lectura" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "obligatori" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "selecció múltiple" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "entrada no vàlida" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "no vàlid" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ortografia no vàlida" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ortografia" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "gramàtica no vàlida" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramàtica" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Cerca" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Diàleg de cerca del lector de pantalla" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Tanca" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Cerca" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Cerca:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Cerca:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_A dalt de tot de la finestra" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "A dalt de tot de la finestra" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Inicia des de:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Ajusta" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Cerca _cap enrere" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Direcció de la cerca:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Coincideix les majúscules i minúscules" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Coincideix només la paraula s_encera" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opcions:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Predeterminat" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Majúscules" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Enllaç" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicació" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Finestra" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferències de Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "A_juda" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Aplica" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Portàtil" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Disposició del teclat" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Perfil actiu:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Perfil d'inici:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Carrega" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "_Anomena i desa" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Suprimeix" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Perfils" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Indicadors de funció _presents" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Pronuncia l'objecte sota el _punter" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Ratolí" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Format de l'_hora:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Format de _data:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Hora i data" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Pronuncia les actualitzacions" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Actualitzacions de _Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Freqüència (segons):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "S'aplica a:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Eme_t un to per a les actualitzacions" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Actualitzacions de la barra de progrés" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Habilita _rebobina i avanç ràpid a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Habilita la navegació e_structural a Pronuncia-ho tot" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Pronuncia-ho tot p_er:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Anuncia _cites en bloc a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Anuncia _llistes a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Anuncia t_aules a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Anuncia _quadres a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Anuncia _formularis a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Anuncia p_unts de referència a Pronuncia-ho tot" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Pronuncia-ho tot" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Presentació de l'element:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "General" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lum:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Veloci_tat:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Ràtio:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persona:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Idioma:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Sintetit_zador de pronunciació:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Sistema de pronunciació:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipus de _veu:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Estil de majús_cules:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Paràmetres del tipus de veu" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" -"Pronuncia les cadenes AmbMajúsculesIMinúscules com a _paraules separades" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Pronuncia els _nombres com a dígits" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Paràmetres de veu globals" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Veu" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Habilita la pronunciació" - -# "Verbós" ? (josep) -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Detallat" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Nivell de detall" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Tot" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Nivell de puntuació" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Pronuncia únicament el text que es mostra" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Pronuncia les línies en blanc" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Pronunc_ia el sagnat i la justificació" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Pronuncia els _mnemònics de l'objecte" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Pronuncia la p_osició filla" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Pronuncia els missatges del programa d'aprenentatge" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Els missatges de _sistema són detallats" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "_Pronuncia els colors com a noms" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Anuncia _cites en bloc durant la navegació" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Anuncia ll_istes durant la navegació" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Anuncia t_aules durant la navegació" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Pronuncia l'indicador de les paraules a_mb errors d'ortografia" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Anuncia _quadres durant la navegació" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Anuncia p_unts de referència durant la navegació" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Anuncia _formularis durant la navegació" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Pronuncia la d_escripció" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Pronuncia la línia completa als fu_lls de càlcul" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Pronuncia la línia completa a taules _document" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Pronuncia la línia completa a taules I_GU" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Context parlat" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Parla" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Habilita les funcion_s de Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Noms de rol _abreujats" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Inhabilita el símbol de _fi de línia" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Taula de contraccions:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Habilita el braille contret" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Habilita l'ajustament de _línies" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Paràmetres de visualització" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Cap" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicador de la selecció" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicador d'enllaç" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Habilita els _missatges flash" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "D_uració (segons):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Els missatges són _persistents" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Els missatges són _detallats" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Configuracions dels missatges flash" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Habilita l'eco de les _tecles" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Habilita les tecles _alfabètiques" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Habilita les tecles _numèriques" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Habilita les tecles de _puntuació" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Habilita l'e_spaiador" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Habilita el _modificador de tecles" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Habilita les tecles de _funcions" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Habili_ta les tecles d'acció" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Habilita les tecles de _navegació" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Habilita l'eco per _paraula" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Habilita l'eco per _frase" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Eco" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Tecles de _modificació del lector de pantalla:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Vinculacions de tecla" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Diccionari de pronunciació" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Entrada _nova" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Suprimeix" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronunciació" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Pronuncia-ho tot" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Pronuncia el _nom" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Reinicia" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributs del text" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mou-te al _fons" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mou-te una _avall" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mou-te una a_munt" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mou a _dalt de tot" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Ajusta els atributs seleccionats" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicador de Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributs del text" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Activa l'assistent d'IA" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Proveïdor:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Local - Gratuït)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Fitxer de clau _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Camí al fitxer de clau API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Obteniu la clau API de _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Obre el navegador per obtenir la clau API de Claude i desa-la automàticament" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Requereix confirmació abans de les accions d'IA" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Model Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nom del model per a Ollama (p. ex., llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Punt final d'Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" -"URL del punt final de l'API d'Ollama (p. ex., http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Qualitat de la captura de pantalla:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Baix" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Mitjà" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Alt" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Assistent d'IA" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Codi d'_idioma:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Factor d'_escala:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Imatge en escala de _grisos" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Inverteix la imatge" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Imatge en _blanc i negre" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Llindar de blanc/negre:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analitza els colors" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Copia els resultats al _porta-retalls" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : índia, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "color de fons" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "alçada total del fons" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "fons puntejat" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direcció" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editable" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nom de família" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "color del primer pla" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "primer pla puntejat" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efectes del tipus de lletra" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "sagnat" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "errada" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justificació" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "idioma" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "marge esquerre" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "alçada de línia" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "estil del paràgraf" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "píxels per sobre de les línies" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "píxels per sota de les línies" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "píxels dins les línies ajustades" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "marge dret" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "aixecat" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "escala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "mida" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "amplada" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "barrat" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decoració del text" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotació del text" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "ombra del text" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "subratllat" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "alineació vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "pes" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "mode d'ajustament" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "mode d'escriptura" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "cert" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "fals" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "cap" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "gravat" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "relleu" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "contorn" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "línia de sobre" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "barrat" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "parpelleig" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "negre" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "únic" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "doble" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "baix" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "caràcter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "paraula" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "caràcter de paraula" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "d'esquerra a dreta" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "de dreta a esquerra" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "esquerra" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "dreta" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centre" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "sense justificació" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "omple" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensada" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensada" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensada" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensada" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi expandida" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expandida" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra expandida" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra expandida" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "versaletes" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "obliqua" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "cursiva" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Predeterminat" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Cos del text" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Encapçalament" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "línia base" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "súper" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "dalt" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "text a dalt" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "mig" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "a baix" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "text a baix" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "heretat" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "d'esquerra a dreta, de dalt a baix" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "de dreta a esquerra, de dalt a baix" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "de dalt a baix, de dreta a esquerra" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "de dalt a baix, d'esquerra a dreta" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "de baix a dalt, de dreta a esquerra" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "de baix a dalt, d'esquerra a dreta" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "d'esquerra a dreta" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "de dreta a esquerra" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "de dalt a baix" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "sòlid" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "verificació ortogràfica" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Premeu la barra espaiadora per a commutar." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Premeu la barra espaiadora per a expandir i utilitzeu les tecles de cap " -"amunt i cap avall per a seleccionar un element." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Premeu Alternativa+F6 per a donar el focus a les finestres filles." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Per a moure's a elements, utilitzeu les tecles de cursor, o utilitzeu la " -"cerca automàtica en escriure." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" -"Per a accedir als menús del sistema premeu la combinació de tecles " -"alternativa+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" -"Utilitzeu les tecles de cap amunt i cap avall per a seleccionar un element." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Per a reduir, premeu majúscula i esquerra." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Per a expandir, premeu majúscula i dreta." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Per a activar-lo premeu la tecla de retorn." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Escriviu text." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Utilitzeu les tecles dreta i esquerra per a veure altres pestanyes." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Per a activar-lo premeu la barra espaiadora." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Utilitzeu les tecles de cap amunt o cap avall per a seleccionar un valor. O " -"teclegeu el valor numèric desitjat." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Utilitzeu les tecles de cursor per a canviar." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Per a navegar, premeu les tecles de fletxa cap a l'esquerra i cap a la " -"dreta. Per a moure-us a través dels elements premeu les tecles de cap amunt " -"o cap avall." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Per a entrar a un submenú, premeu la tecla de fletxa cap a la dreta." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Per a retrocedir premeu la tecla cap a l'esquerra, per a avançar premeu la " -"tecla cap a la dreta. Per a anar a l'inici premeu la tecla d'inici i per a " -"anar al final premeu la tecla de final." diff --git a/po/ca@valencia.po b/po/ca@valencia.po deleted file mode 100644 index 6932724..0000000 --- a/po/ca@valencia.po +++ /dev/null @@ -1,9254 +0,0 @@ -# Catalan translation of cthulhu -# Copyright © 2006, 2007, 2008 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# Gil Fcthulhuda , 2006-2014. -# Jordi Serratosa , 2012, 2017. -# Walter Garcia-Fontes , 2016. -# -# per veure els símbols als quals s'ha de posar noms vegeu: -# http://www.fileformat.info/info/unicode/char/search.htm -# i introduïu el codi (00d7 per exemple) i ja us mostrarà el símbol -# -# informació sobre les live regions a: -# http://live.gnome.org/Cthulhu/Firefox/LiveRegions -# -msgid "" -msgstr "" -"Project-Id-Version: ca\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2017-09-03 01:16+0200\n" -"Last-Translator: Xavi Ivars \n" -"Language-Team: Catalan \n" -"Language: ca-valencia\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 1.8.11\n" - -msgid "Cthulhu Screen Reader" -msgstr "Lector de pantalla Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "lector de pantalla;pronunciació;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alerta" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "fletxa" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "lle" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "títol" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "qdv" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "selcolor" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "capcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "qc" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "edidat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icona" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "marc" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "mar" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "subfindir" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "dibuix" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "selfit" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "empl" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "selletra" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "subfincris" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "capçal" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "marcint" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etiq" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "subfincap" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "enllaç" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstele" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnú" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "barmnú" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "elemnú" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "subfinop" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pestpag" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "llistapes" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "qdr" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "contrasenya" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnúeme" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "barprog" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "bt" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "opció" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "eleopmnú" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "subfinarr" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "capfila" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "barrades" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "subfindes" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "secció" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "separa" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "selellis" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "subfindiv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "botógir" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "bares" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tau" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cel·la" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "elemnúdes" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "botócom" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "barei" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "consell" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arbre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tauar" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "desc" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "portvis" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "fin" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "cap" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "peu" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apli" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "autocom" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "baredi" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "incrustat" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Txec grau 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Espanyol grau 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francés canadenc grau 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francés de França grau 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letó grau 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holandés d'Holanda grau 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Noruec grau 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Noruec grau 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Noruec grau 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Noruec grau 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polonés grau 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugués grau 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Suec grau 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Àrab grau 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Gal·lès grau 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Gal·lès grau 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemany grau 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemany grau 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemany grau 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Anglés de Regne Unit grau 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Anglés de Regne Unit grau 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Anglés d'Estats Units d'Amèrica grau 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Anglés d'Estats Units d'Amèrica grau 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francés de Canadà grau 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francés de França grau 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grec grau 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi grau 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ordinador hongarés de 8 punts" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hongarés grau 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Hongarés grau 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italià grau 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Holandés de Bèlgica grau 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espai" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "línia nova" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "pestanya" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "exclamació" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "cita" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nombre" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dòlar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percentatge" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "i" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apòstrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "parèntesi esquerre" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "tancar parèntesis" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterisc" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "més" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "coma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "traç" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punt" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra inclinada" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dos punts" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punt i coma" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "menys que" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "igual" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "més que" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "pregunta" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "arrova" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "claudàtor esquerre" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "barra invertida" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "claudàtor dret" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "cursor" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "subratllat" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "obert" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "clau esquerra" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra vertical" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "clau dreta" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "titlla" - -# FIXME -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espai dur" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "exclamació invertida" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cèntims" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "lliures" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "signe de moneda" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "ien" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra trencada" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "secció" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "dièresi" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superíndex a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "cometes baixes esquerres" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "no lògic" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "guionet" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrat" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "guionet alt" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "graus" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "més o menys" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superíndex 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superíndex 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "accent agut" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "micro" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "marcador de paràgraf" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "punt volat" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superíndex 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "o elevada" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "cometes baixes dretes" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "un quart" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "un mig" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tres quartes parts" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "signe d'interrogació invertit" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a aguda" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GREU" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AGUDA" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TITLLA" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A DIÈRESI" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A AMB CERCLE" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C TRENCADA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GREU" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AGUDA" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E DIÈRESI" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GREU" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AGUDA" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I DIÈRESI" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TITLLA" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GREU" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AGUDA" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TITLLA" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O DIÈRESI" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "signe de multiplicació" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O BARRADA" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GREU" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AGUDA" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U DIÈRESI" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AGUDA" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "eszet" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a greu" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a titlla" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a dièresi" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a amb cercle" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c trencada" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e greu" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e aguda" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e dièresi" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i greu" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i aguda" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i dièresi" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n titlla" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o greu" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o aguda" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o titlla" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o dièresi" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "divisió" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o barrada" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u aguda" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u greu" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u dièresi" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y aguda" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y dièresi" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y DIÈRESI" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "guió" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "marca de citació esquerra" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "marca de citació dreta" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "marca de citació baixa" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "cometes esquerres" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "cometes dretes" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "cometes baixes dobles" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "creu" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "creu doble" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "pic" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "pic triangular" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "tant per mil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prima" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "prima doble" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "prima triple" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "guió petit" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marca registrada" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "marca de verificació" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "marca de verificació gruixuda" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "pic en forma de x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "superíndex 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "superíndex 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "superíndex 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "superíndex 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "superíndex 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "superíndex 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "superíndex 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "superíndex signe positiu" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "superíndex signe negatiu" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "superíndex signe igual" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "superíndex parèntesi esquerre" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "superíndex parèntesi dret" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "superíndex n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "subíndex 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "subíndex 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "subíndex 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "subíndex 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "subíndex 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "subíndex 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "subíndex 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "subíndex 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "subíndex 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "subíndex 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "subíndex signe positiu" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "subíndex signe negatiu" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "subíndex signe igual" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "subíndex parèntesi esquerre" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "subíndex parèntesi dret" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "quadrat negre" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "diamant negre" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "caràcter de substitució d'objecte" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Mou el punter fins a l'element actual." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Fa clic amb el botó esquerre a l'element actual de la revisió plana." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Fa clic amb el botó dret a l'element actual de la revisió plana." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Pronuncia el document sencer." - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Pronuncia la finestra completa usant la revisió plana." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Fa l'operació bàsica d'on sóc." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Fa l'operació detallada d'on sóc." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Pronuncia la línia de revisió plana actual." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Pronuncia els detalls de l'enllaç." - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Vés al botó següent." - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Pronuncia la barra d'estat." - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Pronuncia la barra de títol." - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Obri el diàleg de busca." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Busca la següent instància d'una cadena." - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Busca les instàncies anteriors d'una cadena." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Entra i ix del mode de revisió plana." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Mou la revisió plana a l'última posició." - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Mou la revisió plana a la posició inicial." - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Mou la revisió plana a l'última posició." - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Mou la revisió plana al principi de la línia anterior." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Pronuncia la línia de revisió plana actual." - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Pronuncia la línia de revisió plana actual." - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Pronuncia fonèticament la línia de revisió plana actual." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Mou la revisió plana a l'inici de la següent línia." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Mou la revisió plana a l'element o paraula anterior." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Pronuncia la paraula o element de la revisió plana actual." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Pronuncia la paraula o element de la revisió plana actual." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Pronuncia fonèticament la paraula o element de la revisió plana actual." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Mou la revisió plana al següent element o paraula." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Mou la revisió plana a la paraula de sobre de la paraula actual." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Pronuncia l'objecte de la revisió plana actual." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Mou la revisió plana a la paraula a sota de la paraula actual." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Mou la revisió plana al caràcter anterior." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Pronuncia el caràcter de l'actual revisió plana." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Pronuncia fonèticament el caràcter de l'actual revisió plana." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Pronuncia el valor Unicode del caràcter de la revisió plana actual." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Mou la revisió plana al següent caràcter." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Mou la revisió plana al final de línia." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Mou la revisió plana a baix de tot a l'esquerre." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copia el contingut de la revisió plana al porta-retalls." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Afig el contingut de la revisió plana actual al porta-retalls." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Mou la revisió plana a l'última posició." - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Commuta entre llegir només la cel·la actual de la taula, o bé tota la fila." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Llig els atributs associats amb el caràcter del text actual." - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Balanceja la visualització braille cap a l'esquerra." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Balanceja la visualització braille cap a la dreta." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Retorna a l'objecte amb el focus al teclat." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Activa o desactiva el braille contret." - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Processa una tecla d'encaminament del cursor." - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marca l'inici d'una selecció de text." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marca el final d'una selecció de text." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Entra al mode d'aprenentatge. Premeu la tecla d'escapament per eixir-ne." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Disminueix la velocitat de pronunciació." - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Incrementa la velocitat de pronunciació." - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Disminueix el to de pronunciació." - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Augmenta el to de la pronunciació." - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Incrementa el volum de la veu." - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Disminueix el volum de la veu." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Seleccioneu el servidor de pronunciació desitjat." - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Seleccioneu el servidor de pronunciació desitjat." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Disminueix la velocitat de pronunciació." - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Incrementa la velocitat de pronunciació." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Paràmetres del tipus de veu" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Commuta el silenci de la pronunciació." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Commuta el nivell de detall de la pronunciació." - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Commuta al mode de revisió de ratolí." - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Ix del lector de pantalla" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Mostra el diàleg de configuració de les preferències." - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Mostra el diàleg de configuració de les preferències de l'aplicació." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Commuta la pronunciació del sagnat i la justificació." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Canvia l'estil de nombres parlats." - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Canvia al següent nivell de pronunciació de la puntuació." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Canvia al següent nivell d'eco." - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Canvia al perfil de configuració següent." - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Canvia a l'estil de majúscules següent." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Canvia al següent nivell d'eco." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Canvia el nivell de depuració en temps d'execució." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Marca on sóc respecte de la posició actual." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Vés a la ubicació del marcador anterior." - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Vés al marcador." - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Vés a la ubicació del marcador següent." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Afig un marcador." - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Guarda els marcadors." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Commuta al mode de revisió de ratolí." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Mostra l'hora actual." - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Mostra la data actual." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Passa l'orde següent a l'aplicació actual." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Pronuncia i posa el braille de l'anterior missatge de la sala de xat." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Commuta si s'ha d'anunciar quan els nostres amics estiguen escrivint." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Commuta si es proporcionen historials de missatges específics per a les " -"sales de xat." - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Commuta el posar un prefix amb el nom de la sala de xat en els missatges de " -"les sales de xat." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Línia esquerra" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Línia dreta" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Línia amunt" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Línia avall" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Congela" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "A dalt a l'esquerra" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "A baix a l'esquerra" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posició del cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Sis punts" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Encaminament del cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Inici de selecció" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Final de selecció" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Presenta l'últim missatge de notificació." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Presenta la llista de missatges de notificació" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Presenta el missatge de notificació anterior." - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Presenta l'últim missatge de notificació." - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Vés al caràcter següent." - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Vés al caràcter anterior." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Vés a la paraula següent." - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Vés a la paraula anterior." - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Vés a la línia següent." - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Vés a la línia anterior." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Vés a dalt de tot de la fila." - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Vés a baix de tot de la fila." - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Vés a l'inici de la línia." - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Vés al final de la línia." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Vés a l'objecte següent." - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Vés a l'objecte anterior." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Fa que el quadre combinat actual s'expandisca." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Canvia entre la navegació de cursor nadiua i la del lector de pantalla." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Avança el paràmetre de la netedat de les regions dinàmiques." - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Desactiva el nivell de la netedat de les regions dinàmiques." - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Revisa els anunciaments de les regions dinàmiques." - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Fes un seguiment de les regions dinàmiques." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Mou el focus a dins i fora d'on plana el ratolí actualment." - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" -"Estableix quina fila s'ha d'utilitzar com a capçaleres de columna dinàmiques." - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Neteja la capçalera de columna dinàmica." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" -"Estableix la columna que s'ha d'utilitzar com a capçaleres de fila " -"dinàmiques." - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Neteja les capçaleres de fila dinàmiques" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Presenta el contingut de la línia d'entrada." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Commuta les tecles de navegació estructural." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Vés a la cita en bloc anterior." - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Vés a la cita en bloc següent." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Mostra una llista de cites en bloc." - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Vés al botó anterior." - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Vés al botó següent." - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Mostra una llista de botons." - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Vés a la casella de selecció anterior." - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Vés a la casella de selecció següent." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Mostra una llista de caselles de selecció." - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Vés a l'element clicable anterior." - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Vés a l'element clicable següent." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Mostra una llista dels elements clicables." - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Vés al quadre combinat anterior." - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Vés al quadre combinat següent." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Vés a l'inici del contenidor." - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Vés al final del contenidor." - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Mostra una llista de quadres combinats." - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Vés a l'entrada anterior." - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Vés a l'entrada següent." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Mostra una llista d'entrades." - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Vés al camp del formulari anterior." - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Vés al camp del formulari següent." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Mostra una llista de camps de formulari." - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Vés a la capçalera anterior." - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Vés a la capçalera següent." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Mostra una llista de capçaleres." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Vés a la capçalera de nivell %d anterior." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Vés a la capçalera de nivell %d següent." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Mostra una llista de capçaleres de nivell %d." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Vés a la taula anterior." - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Vés a la taula següent." - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Mostra una llista de taules." - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Vés a la imatge anterior." - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Vés a la imatge següent." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Mostra una llista d'imatges." - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Vés a la marca important anterior." - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Vés a la marca important següent." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Mostra una llista de punts de referència." - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Vés a l'objecte gran anterior." - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Vés a l'objecte gran següent." - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Mostra una llista d'objectes grans." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Va a l'enllaç anterior." - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Va a l'enllaç següent." - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Mostra una llista d'enllaços." - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Vés a la llista anterior." - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Vés a la llista següent." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Mostra una llista de llistes." - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Vés a l'element de la llista anterior." - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Vés a l'element de la llista següent." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Mostra una llista d'elements de llista." - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Vés a la regió dinàmica anterior." - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Vés a la regió dinàmica següent." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Vés a l'última regió dinàmica que ha fet un anunci." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Retorna a l'objecte amb el focus al teclat." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Retorna a l'objecte amb el focus al teclat." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Commuta les tecles de navegació estructural." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Vés al paràgraf anterior." - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Vés al paràgraf següent." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Mostra una llista de paràgrafs." - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Vés al botó d'opció anterior." - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Vés al botó d'opció següent." - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Mostra una llista de botons d'opció." - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Vés al separador anterior." - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Vés al separador següent." - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Vés a la taula anterior." - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Vés a la taula següent." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Mostra una llista de taules." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Vés a la cel·la de sota." - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Vés a la primera cel·la de la taula." - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Vés a l'última cel·la de la taula." - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Vés a la cel·la de l'esquerra." - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Vés a la cel·la de la dreta." - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Vés a la cel·la de sobre." - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Commuta al mode de revisió de ratolí." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Commuta entre el mode de navegació i el mode de focus." - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Habilita el mode de focus enganxós." - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Habilita el mode de navegació enganxós." - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Vés a l'enllaç sense visitar anterior." - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Vés a l'enllaç sense visitar següent." - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Mostra una llista d'enllaços no visitats." - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Vés a l'enllaç visitat anterior." - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Vés a l'enllaç visitat següent." - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Mostra una llista d'enllaços visitats." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "blau alice" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "blanc antic" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "aigua de mar" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "atzurat" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beix" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "crema" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "negre" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "ametlla blanca" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blau" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "violeta blau" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "marró" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "marró burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "blau cadet" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "verd chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "xocolata" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "taronja coral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "blau cornflower" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "marró cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "roig crimson" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cian" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "blau fosc" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "cian fosc" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "marró goldenrod fosc" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "gris fosc" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verd fosc" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "caqui fosc" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta fosc" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "verd oliva fosc" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "taronja fosc" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "porpra orquídia fosc" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "roig fosc" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmó fosc" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "verd mar fosc" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "blau pissarra fosc" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "gris pissarra fosc" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turquesa fosc" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violeta fosc" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "rosa profund" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "blau cel profund" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "gris lleuger" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "blau dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "totxo foc" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "blanc floral" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "verd bosc" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fúcsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gris gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "blanc fantasma" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "or" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "marró goldenrod" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "gris" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verd" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "groc verd" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "blanc honeydew" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "rosa calent" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "roig indi" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indi" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "marfil" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "caqui" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "blanc lavanda rubor" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "verd pradera" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "groc llimona gasa" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "blau clar" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "roig coral clar" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "cian clar" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "groc goldenrod clar" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "gris clar" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "verd clar" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "rosa clar" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmó clar" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "verd mar clar" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "blau cel clar" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "gris pissarra clar" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "blau metàl·lic clar" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "groc clar" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "llima" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "verd llima" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "blanc lli" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "granat" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "verd aiguamarina mig" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "blau mitjà" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orquídia mig" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "porpra mitjà" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "verd mar mitjà" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "blau pissarra mitjà" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "verd primavera mig" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turquesa mitjà" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "roig violeta mig" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "blau mitjanit" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "crema de menta" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rosa boirós" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "groc mocassí" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "blanc navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "marí" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "blanc oldlace" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliva" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "verd oliva monòton" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "taronja" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "roig taronja" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orquídia" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "groc goldenrod pàl·lid" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "verd pàl·lid" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turquesa pàl·lid" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "roig violeta pàl·lid" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "groc papaia whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "groc bresquilla puff" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "marró perú" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "pruna" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "blau pols" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "porpra" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "roig" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "marró rossenc" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "blau reial" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "marró cadira de muntar" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmó" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "marró arenós" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "verd mar" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "petxina" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "plata" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "cel blau" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "blau pissarra" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "gris pissarra" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "neu" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "verd primavera" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "blau metàl·lic" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "canyella" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "xarxet" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "card" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomàquet" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquesa" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violeta" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "blat" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "blanc" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "blanc fumat" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "groc" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "verd groc" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Activa" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Mode de focus automàtic en la navegació estructural" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Mode de focus automàtic en la navegació de cursor" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Mode de focus automàtic en la navegació de cursor" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punt _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punt _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Punts 7 _i 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Cancel·la" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Vés a" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_D'acord" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Cap" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "pronuncia" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Anuncia quan els nostres _amics estiguen escrivint" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Proporciona historials de _missatges específics per les sales de xat" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Pronuncia els missatges de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Tots els ca_nals" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Tots els canals quan _qualsevol finestra de %s estiga activa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Un canal només si és de la _finestra activa" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Pronuncia el nom de la sala de xat" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Habilita el mode disposició per al contingut" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "doble clic" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triple clic" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetitzador predeterminat" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Frase" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Text explicatiu" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Habilita l'eco per _caràcter" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Habilita les tecles _diacrítiques sense espai" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Ubicació actual" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Mida mínima del text de coincidència:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opcions de busca" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Pronuncia només les línies diferents durant la _cerca" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Pronuncia els resultats durant la _cerca" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "coma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Vinculació de tecla" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Per defecte" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "mode d'escriptura" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "secció" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Vinculacions de Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Guarda els marcadors." - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Hora i data" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "S'ha habilitat el mode de revisió de ratolí." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navegació" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Sense vincle" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "S'està eixint de la revisió plana." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "contingut principal" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificada" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Escriptori" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificació" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Notificació" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferències del lector de pantalla per a %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marca-ho en braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Present a menys que" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Pronuncia" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Guarda el perfil com a conflictiu" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflicte en el perfil d'usuari" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Ja existeix el perfil %s.\n" -"Voleu actualitzar-lo amb estos canvis?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Carrega el perfil d'usuari" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Esteu a punt de canviar el perfil actiu. Si heu fet\n" -"canvis a les preferències es perdran en carregar\n" -"el perfil.\n" -"\n" -"Voleu continuar carregant el perfil obviant els canvis anteriors?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Guarda el perfil com a" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nom del _perfil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Carrega el perfil d'usuari" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Totes" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicació" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Finestra" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Cap" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Algu_ns" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "M_olts" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Línia" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Frase" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Cita en bloc" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Botó" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Títol" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Casella de selecció" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Clicable" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Quadre combinat" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descripció" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Encapçalament" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "intercalat" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imatge" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiqueta" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Punt de referència" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivell" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Enllaç" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Llista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Element de llista" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objecte" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paràgraf" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Botó d'opció" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rol" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Element seleccionat" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Estat" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valor" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Cites en bloc" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botons" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Caselles de selecció" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Clicables" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Quadres combinats" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entrades" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Camps de formulari" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Encapçalaments" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "intercalat" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imatges" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Encapçalaments de nivell %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Punts de referència" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Objectes grans" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Enllaços" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Llistes" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Elements de llista" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paràgrafs" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Botons d'opció" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Taules" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Enllaços sense visitar" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Enllaços visitats" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navegació web" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Quan es _carregui la pàgina comença a pronunciar-la automàticament" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Resum _present d'una pàgina quan es carrega per primer cop" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Separa la pronunciació en _parts entre les pauses" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Veu predeterminada del %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Predeterminada" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Enllaç" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Majúscules" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Distribuïdor de pronunciació." - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Comprovació de l'ortografia" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Pronuncia l'_error" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Pronuncia el _suggeriment" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Presenta el _context de l'error" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Pronuncia les coordenades de la cel·la dels fulls de càlcul" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Anuncia la _capçalera de la cel·la" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navegació de taules" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Salta't les cel·les en _blanc" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Pronuncia la _cel·la" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Pronuncia les coordenades de la _cel·la" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Pronuncia les extensions _múltiples de cel·les" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nom de l'atribut" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Controla la navegació de cursor" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Habilita la navegació _estructural" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "In_forme" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Notificació" -msgstr[1] "Notificació" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Tecla majúscula" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Tecla alternativa dreta" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Tecla de control esquerre" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "majúscula esquerra" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alternativa esquerra" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control esquerre" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "majúscula dreta" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alternativa dreta" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control dreta" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta esquerra" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta dreta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "fixació de teclat numèric" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "fixació de majúscules" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "fixació de majúscules" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "bloqueig de moviment" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "pàgina amunt" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "pàgina avall" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tabulació esquerra" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "retrocés" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "retorn" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "retorn" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "amunt" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "avall" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "esquerra" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "dreta" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "súper esquerra" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "súper dreta" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menú" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Tecla d'alternativa gràfica" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ajuda" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multiplica" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "canvi de mode" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escapada" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "inserció" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "supressió" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "inici" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "fi" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "començament" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "cercle" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "barrada" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "menys" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Tecla d'inserció" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Bloqueig de majúscu_les" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alternativa dreta" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Súper" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alternativa esquerra" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Majúscula" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "negreta %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "cursiva %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "itàlica negreta %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "subíndex %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "subíndex negreta %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "double-struck %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "fraktur negreta %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif negreta %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif itàlica %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif itàlica negreta %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "espai simple %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s sense punt" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "fletxa esquerra" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "fletxa cap amunt" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "fletxa dreta" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "fletxa cap avall" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "fletxa dreta esquerra" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "fletxa cap amunt i cap avall" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "fletxa nord-oest" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "fletxa nord-est" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "fletxa sud-est" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "fletxa esquerra des de la barra" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "fletxa amunt des de barra" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "fletxa dreta des de la barra" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "fletxa avall des de barra" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "fletxa doble esquerra" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "fletxa doble cap amunt" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "fletxa doble dreta" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "fletxa doble cap avall" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "fletxa doble dreta esquerra" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "fletxa doble amunt i avall" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "fletxa doble a nord-oest" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "fletxa doble al nord-est" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "fletxa doble al sud-est" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "fletxa doble al sud-oest" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "fletxa que apunta cap a la dreta" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "punta de fletxa que apunta cap a la dreta" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "menys" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "més petit que" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "més gran que" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punt" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "línia vertical doble" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "el·lipsi horitzontal" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "per a tot" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "diferencial parcial" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "hi existeix" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "no hi existeix" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "conjunt buit" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "increment" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "element de" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "no és un element de" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "element petit de" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "conté com a membre" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "no conté com a mmbre" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "conté com a membre petit" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "final de la prova" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "producte" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproducte" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sumatòria" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "menys o més" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "més amb punt" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "barra de divisió" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "menys de conjunt" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operador asterisc" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operador d'anell" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operador punt" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "arrel quadrada" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "arrel cúbica" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "arrel quarta" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcional amb" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinit" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "angle dret" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "angle" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "angle mesurat" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "angle esfèric" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "divideix" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "no divideix" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paral·lel a " - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "no paral·lel a" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "i lògic" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "o lògic" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersecció" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unió" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integral doble" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integral triple" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integra de contorn" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "Integral de superfície" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integral de volum" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral en sentit de les agulles del rellotge" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integral de contorn en sentit de les agulles del rellotge" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integral de contorn en sentit contrari a les agulles del rellotge" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "en conseqüència" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "perquè" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "divisió" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporció" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "menys amb punt" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "excés" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporció geomètrica" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotètic" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "titlla" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "titlla revertit" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "S mandrosa invertida" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "onada sinus" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "producte corona" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "no titlla" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "menys titlla" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asimptòticament igual a" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "no asimptòticament igual a" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "aproximadament igual a" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "aproximadament, però en realitat no igual a" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ni aproximadament ni en realitat igual a" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "gairebé igual a" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "no gairebé igual a" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "gairebé igual a o igual a" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "titlla triple" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "tot igual a" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "equivalent a" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geomètricament equivalent a" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "diferència entre" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "s'aproxima al límit" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geomètricament igual a" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "aproximadament igual a la imatge de" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "imatge d'o aproximadament igual a" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dos punts igual a" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "igual dos punts" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "igual a amb anell a dins" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "anell igual a" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "correspon a" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estima" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "equiangular a" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "estrella igual" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta igual a" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "per definició igual a" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "mesurat per" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "interrogació igual a" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "diferent de" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "idèntic a" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "no idèntic a" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "estrictament equivalent a" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "més petit o igual a" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "més gran o igual a" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "més petit sobre igual a" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "més gran sobre igual a" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "més petit però no igual a" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "més gran però no igual a" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "molt més petit que" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "molt més gran que" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "entre" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "no equivalent a" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "no més petit que" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "no més gran que" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ni més petit que ni igual a" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ni més gran ni igual a" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "més petit o equivalent a" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "més gran o equivalent a" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ni més petit que ni equivalent a" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ni més gran ni equivalent a" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "més petit o més gran que" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "més gran o més petit que" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ni més petit que ni més gran que" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ni més gran que ni més petit que" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "precedeix" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "succeeix" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "precedeix o igual a" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "succeeix o igual a" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "precedeix o equivalent a" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "succeeix o equivalent a" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "no precedeix" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "no succeeix" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subconjunt de" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superconjunt de" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "no un subconjunt de" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "no a superconjunt de" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subconjunt d'o igual a" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superconjunt d'o igual a" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ni un subconjunt de ni igual a" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ni un superconjunt de ni igual a" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subconjunt d'amb no igual a" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superconjunt d'amb no igual a" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiconjunt" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiplicació de multiconjunt" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "unió de multiconjunt" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "imatge quadrada de " - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "original quadrada de" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "imatge quadrada d'o igual a" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "quadrat original d'o igual a" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "tapa quadrada" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "copa quadrada" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "més encerclat" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "menys encerclat" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "producte encerclat" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "barra de divisió encerclada" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "producte de punt encerclat" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operador d'anell encerclat" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operador asterisc encerclat" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "igual encerclat" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "guió encerclat" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "més enquadrat" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "subíndex enquadrat" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "per enquadrat" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operador de punt enquadrat" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "tatxa dreta" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "tatxa esquerra" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "tatxa cap avall" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "tatxa cap amunt" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "asserció" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "models" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "cert" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "força" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "torniquet dreta de barra vertical triple" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "doble torniquet dreta de barra doble vertical" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "no prova" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "no cert" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "no força" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "torniquet dreta doble amb barra vertical doble negada" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "precedeix sota relació" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "succeeix sota relació" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "subgrup normal de" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "conté com a subgrup normal" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "subgrup normal d'o igual a" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "conté com a subgrup normal d'o igual a" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original de" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "imatge de" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matriu conjugada hermitiana" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalat" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "angle dret amb un arc" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triangle dret" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operador diamant" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operador punt" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operador estrella" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "divisió per" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "corbatí" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "producte semidirecte de factor normal esquerre" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "producte semidirecte de factor normal dret" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "producte semidirecte esquerre" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "producte semidirecte dret" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "titlla revertida igual" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "lògic corbat o" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "lògic corbat i" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "subconjunt doble" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "superconjunt doble" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "intersecció doble" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "unió doble" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "fcthulhu" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "igual i paral·lel a" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "més petit que amb punt" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "més gran que amb punt" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "molt més petit que" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "molt més gran que" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "més petit igual a o més gran que" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "més gran igual a o més petit que" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "igual o més petit que" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "igual o més gran que" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "igual a o precedeix" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "igual o succeeix" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "no precedeix o igual" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "no succeeix o igual" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "no imatge quadrada d'o igual a" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "no quadrat original d'o igual a" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "imatge quadrada d'o no igual a" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "quadrat original d'o no igual a" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "més petit però no equivalent a" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "més gran que però no equivalent a" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "precedeix però no equivalent a" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "succeeix però no equivalent a" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "no subgrup normal de" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "no conté com a subgrup normal" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "no subgrup normal d'o igual a" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "no conté com a subgrup normal o igual" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "el·lipsi vertical" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "el·lipsi horitzontal de línia mitjana" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "el·lipsi diagonal cap amunt a la dreta" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "el·lipsi diagonal cap avall a la dreta" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "element d'amb línia horitzontal llarga" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "element d'amb barra vertical al final de la línia horitzontal" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "element de petit amb barra vertical al final de la línia horitzontal" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "element d'amb un punt damunt" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "element d'amb una barra damunt" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "element de petit amb barra damunt" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "element d'amb barra a sota" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "element d'amb dues línies horitzontals" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "conté amb línia horitzontal llarga" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "conté amb barra vertical al final de la línia horitzontal" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "conté petit amb barra vertical al final de la línia horitzontal" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "conté amb barra damunt" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "conté petit amb barra damunt" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "afiliació bossa de notació z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "sostre esquerre" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "sostre dret" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "terra esquerre" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "terra dret" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "claudàtor superior" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "claudàtor inferior" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "parèntesi angular esquerre" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "parèntesi angular dret" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "punt encerclat" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "unió amb punt" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "unió amb més" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "intersecció quadrada" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "unió quadrada" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "quadrat negre" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "quadrat blanc" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "diamant negre" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "cercle blanc" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "cercle negre" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bala blanca" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "quadrat petit mitjà negre" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s amb subratllat" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s amb barra inclinada cap avant" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s amb línia vertical" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplicació" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "buida" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "negreta" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "s'ha introduït el marcador" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "s'han guardat els marcadors" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "no s'han pogut guardar els marcadors" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "No s'ha trobat cap marca important." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "No s'ha trobat cap marca important." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "S'ha habilitat el mode d'omissió." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "No s'ha pogut obtindre la pantalla de la calculadora" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "icona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "S'ha establit l'estil de majúscules a icona." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "cap" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "S'ha establit l'estil de majúscules a cap." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "pronuncia" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "S'ha establit l'estil de majúscules a pronunciació." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "L'aplicació està controlant el cursor." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "L'aplicació està controlant el cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cel·la %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "seleccionat" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "no seleccionat" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Evita l'ús de l'opció" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Força l'ús de l'opció" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCIÓ" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Arguments opcionals" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Ús:" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Els següents no són vàlids: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Mostra les aplicacions que se sap que s'estan executant" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Carrega un perfil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "No s'ha pogut carregar el perfil: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"No es pot iniciar el lector de pantalla perquè no es pot connectar a " -"l'escriptori." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "No es pot activar el gestor de la configuració. Se ix." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Ja s'està executant un altre lector de pantalla en esta sessió.\n" -"Executeu «cthulhu --replace» per reemplaçar l'altre procés en execució per " -"una instància nova." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOM" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Utilitza un directori alternatiu per a les preferències d'usuari" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIRECTORI" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Mostra les aplicacions que se sap que s'estan executant" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Reemplaça una instància del lector de pantalla en execució" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Mostra este missatge d'ajuda i ix" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" -"Envia la informació de depuració al fitxer depuracio-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Envia la informació de depuració al fitxer especificat" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FITXER" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Configura les preferències de l'usuari (versió text)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Configura les preferències de l'usuari (versió gràfica)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Informeu d'errors a https://groups.io/g/stormux" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Retalla la selecció al porta-retalls." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "retalla" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "S'ha copiat la selecció al porta-retalls." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copiat" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "S'ha enganxat el contingut del porta-retalls." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "enganxat" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "No ho anuncies quan els teus amics estiguen escrivint." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anuncia quan els teus amics estiguen escrivint." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Missatge de la sala de xat %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Pestanya nova de xat %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "No pronuncies el nom de la sala de xat." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "pronuncia el nom de la sala de xat." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "No proporcionis missatges històrics específics per a les sales de xat." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Proporciona missatges històrics específics per a les sales de xat." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "inici de fracció" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "final de fracció" - -#: src/cthulhu/messages.py:452 -#, fuzzy -msgctxt "content" -msgid "insertion start" -msgstr "inici de fracció" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "final de fracció" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "verd clar" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "Pronuncia el _suggeriment" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Final del contenidor." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "No sou en un contenidor." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "no seleccionat" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "El botó predeterminat és %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "El botó predeterminat és %s" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "El botó predeterminat és %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subíndex %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " superíndex %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "No sou en una taula." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "seleccionat tot el document" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "seleccionat tot el document" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "document seleccionat des de la posició del cursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "s'ha tret la selecció del document des de la posició del cursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "document seleccionat fins a la posició del cursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "s'ha tret la selecció del document fins a la posició del cursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "S'ha establit la capçalera de columna dinàmica per a la fila %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "S'ha netejat la capçalera de columna dinàmica." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "S'ha establit la capçalera de fila dinàmica per a la columna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "S'ha netejat la capçalera de fila dinàmica." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "buit" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "No s'ha trobat cap fitxer." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "S'ha afegit el contingut al porta-retalls." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "S'ha copiat el contingut al porta-retalls." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "No s'està utilitzant la revisió plana." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "S'està entrant a la revisió plana." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "S'està eixint de la revisió plana." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Mou la revisió plana a la paraula de sobre de la paraula actual." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "conté una fórmula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "Obri el diàleg de busca." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "llista de pàgines" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "enllaç de mapa d'imatges" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "La tecla introduïda ja està vinculada a %s." - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "S'ha capturat la tecla %s. Premeu retorn per confirmar-la." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "La tecla nova és: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "S'ha suprimit la vinculació de tecla. Premeu retorn per confirmar-ho." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "S'ha mogut la vinculació de tecla." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "teclegeu la clau nova" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "lletra" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "S'ha establit l'eco a la lletra." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Cap" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "S'ha establit que no hi haurà eco." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "lletra i paraula" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "S'ha establit l'eco a la lletra i paraula." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "frase" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "S'ha establit l'eco a la frase." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "paraula" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "S'ha establit l'eco a la paraula." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "paraula i frase" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "S'ha establit l'eco a la paraula i la frase." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Envoltat per: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "un símbol actuarial" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "una caixa" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "un cercle" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "un signe de divisió llarg" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "un radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "una caixa arrodonida" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "una ratlla horitzontal" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "una ratlla vertical" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "una ratlla diagonal cap avall" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "una ratlla diagonal cap amunt" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "una fletxa nord-est" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "una línia al peu" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "una línia a l'esquerra" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "una línia a la dreta" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "una línia a la part superior" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "un angle fasor" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "un símbol factorial aràbic" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "i" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "inici de fracció" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "fracció sense barra, inici" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "dividit per" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "final de fracció" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "arrel quadrada de" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "arrel cúbica de" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "arrel de" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "inici d'arrel" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "final d'arrel" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subíndex" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "superíndex" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pre-subíndex" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pre-superíndex" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "text escrit a sota" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "text escrit damunt" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "final de taula" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "final de taula imbricada" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessible" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Inhabilitat" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "S'ha inhabilitat la pronunciació del sagnat i la justificació." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Habilitat" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "S'ha habilitat la pronunciació del sagnat i la justificació." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Mode d'aprenentatge. Premeu la tecla d'escapament per eixir." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"S'està entrant al mode d'aprenentatge. Premeu qualsevol tecla per sentir-ne " -"la seua funció. Per veure la documentació del lector de pantalla, premeu F1. " -"Per obtindre la llista de dreceres per defecte del lector de pantalla, " -"premeu F2. Per obtindre la llista de dreceres del lector de pantalla per " -"l'aplicació actual, premeu F3. Per eixir del mode d'aprenentatge premeu la " -"tecla d'escapada." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "s'està eixint de la cita en bloc." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "s'està eixint de la taula." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "s'està eixint del canal." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "s'està eixint de la figura." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "s'està eixint del formulari." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "s'està eixint del bàner." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "s'està eixint del contingut complementari." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "s'està eixint de la informació." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "s'està eixint del contingut principal." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "s'està eixint de la navegació." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "s'està eixint de la regió." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "s'està eixint de la busca." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "s'està eixint de la llista." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "s'està eixint del quadre." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "s'està eixint de la taula." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "s'està eixint de la llista." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "s'està eixint del resum." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "s'està eixint dels reconeixements." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "s'està eixint de l'epíleg." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "s'està eixint de l'apèndix." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "s'està eixint de la bibliografia." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "s'està eixint del capítol." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "s'està eixint del colofó." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "s'està eixint de la conclusió." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "s'està eixint del crèdit." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "s'està eixint dels crèdits." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "s'està eixint de la dedicatòria." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "s'està eixint de les notes finals." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "s'està eixint de l'epígraf." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "s'està eixint de l'epíleg." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "s'està eixint de l'errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "s'està eixint de l'exemple." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "s'està eixint del prefaci." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "s'està eixint del glossari." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "s'està eixint de l'índex." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "s'està eixint de la introducció." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "s'està eixint de la llista de pàgines." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "s'està eixint de la part." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "s'està eixint del pròleg." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "s'està eixint del pròleg." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "s'està eixint de la cita destacada." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "s'està eixint de les preguntes i respostes." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "s'està eixint de la regió." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "s'està eixint de la taula de continguts." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "seleccionada la línia per sota de la posició del cursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "seleccionada la línia per sobre de la posició del cursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "s'ha tret la selecció de la línia de sota la posició del cursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "s'ha tret la selecció de la línia per sobre de la posició del cursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "S'està eixint del mode d'aprenentatge." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" -"línia seleccionada des de l'inici fins a la posició on estava abans el cursor" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "línia seleccionada fins al final de la línia on estava abans el cursor" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "enllaç" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "la mateixa pàgina" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "el mateix lloc" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "lloc diferent" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s enllaça a %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "enllaç %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "enllaç %s visitat" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Utilitzeu les tecles cap amunt i cap avall per navegar per la llista. Premeu " -"la tecla d'escapament per eixir." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Desactiva totes les regions dinàmiques" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "s'han restaurat els nivells d'educació de les regions dinàmiques" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nivell d'educació %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "estableix la regió dinàmica a enèrgica" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "desactiva la regió dinàmica" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "estableix la regió dinàmica a educada" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "estableix la regió dinàmica a grollera" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "No s'està fent un seguiment de les regions dinàmiques" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "S'està fent un seguiment de les regions dinàmiques" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "no s'ha guardat el missatge dinàmic" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Les regions dinàmiques estan desactivades" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "No s'ha trobat" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "No s'ha pogut determinar la ubicació actual." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "inactiu" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "actiu" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "paraula mal escrita" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Paraula mal escrita: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr " El context és %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Mode de navegació" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Mode de focus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Per habilitar el mode de focus premeu %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "El mode de focus és enganxós." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "El mode de navegació és enganxós." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Mode de focus" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objecte" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Vés a l'objecte següent." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "No s'ha trobat l'objecte on plana el ratolí." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "S'ha inhabilitat el mode de revisió de ratolí." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "S'ha habilitat el mode de revisió de ratolí." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "S'ha produït un error: no s'ha pogut crear una llista d'objectes." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d per cent." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Vés a la paraula anterior." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nivell d'imbricació %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "S'ha afegit un element nou" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "No hi ha cap aplicació que tinga el focus." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Sense focus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "No hi ha cap aplicació que tinga el focus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "No hi ha cap cita en bloc." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "No hi ha cap més botons." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "No hi ha cap més casella de selecció." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "No hi ha cap més objecte gran." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "No hi ha cap més element clicable." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "No hi ha cap més quadre combinat." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "No hi ha cap més entrada." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "No hi ha cap més entrada de formulari." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "No hi ha cap més capçalera." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "No hi ha cap més capçalera de nivell %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "No hi ha cap més taula." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "No hi ha cap més imatge." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "No s'ha trobat cap marca important." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "No hi ha cap més enllaç." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "No hi ha cap més llista." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "No hi ha cap més element de llista." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "No hi ha cap més regió dinàmica." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "No hi ha cap més paràgraf." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "No hi ha cap més botó d'opció." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "No hi ha cap més separador." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "No hi ha cap més taula." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "No hi ha cap més enllaç sense visitar." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "No hi ha cap més enllaç visitat." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "No hi ha un text seleccionat." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "No està sobre un enllaç." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificació" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "A baix de tot" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "A dalt de tot" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "No hi ha cap missatge de notificació" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "dígits" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Pronuncia els nombres com a dígits." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "paraules" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Pronuncia els nombres com paraules." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "inactiu" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "actiu" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "S'està carregant. Espereu." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "S'ha acabat de carregar." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "S'ha acabat de carregar el %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "La pàgina té %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "pàgina seleccionada des de la posició del cursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "pàgina seleccionada fins a la posició del cursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "s'ha tret la selecció de la pàgina des de la posició del cursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "s'ha tret la selecció fins a la posició del cursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "s'ha seleccionat el paràgraf des de la posició del cursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "s'ha seleccionat el paràgraf fins a la posició del cursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "s'ha tret la selecció del paràgraf des de la posició del cursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "s'ha tret la selecció del paràgraf fins a la posició del cursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Ja teniu obert el diàleg de preferències de l'Cthulhu.\n" -"Tanqueu-lo abans d'obrir-ne un altre." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapositiva %(position)d de %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "S'ha establit el perfil a %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "No s'ha trobat cap perfil." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra de progrés %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Totes" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "S'ha establit el nivell de pronunciació de la puntuació a totes." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "La majoria" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "S'ha establit el nivell de pronunciació de la puntuació a la majoria." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Cap" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "S'ha establit el nivell de pronunciació de la puntuació a cap." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Algunes" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "S'ha establit el nivell de pronunciació de la puntuació a algunes." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "S'està cercant." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "S'ha completat la busca." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "S'ha tornat a carregar la configuració del lector de pantalla." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "El text seleccionat és: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "S'ha esborrat la selecció." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "S'ha restaurat la selecció." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "no seleccionat" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "S'ha inhabilitat la pronunciació." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "S'ha habilitat la pronunciació." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "més ràpid." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "més lent." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "més alt." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "més baix." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "més alt." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "més suau." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Ràtio:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Vo_lum:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Distribuïdor de pronunciació." - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Distribuïdor de pronunciació." - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "No hi ha servidors disponibles." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "No hi ha veus disponibles." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "S'ha habilitat la pronunciació." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "No es farà servir la pronunciació." - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Nivell de detallat: breu" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Nivell de detallat: detallat" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " punt punt punt" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "S'ha habilitat el mode d'omissió." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "La pronunciació no està disponible." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "No s'ha trobat" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "no s'ha trobat la cadena" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "no s'ha trobat la cadena" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Les tecles de navegació estructural estan desactivades." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Les tecles de navegació estructural estan activades." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "No s'ha trobat" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Fila %(row)d, columna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Final de la taula" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Pronuncia la cel·la" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Pronuncia la fila" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "No uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "No sou en una taula." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "S'han reordenat les columnes" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "S'han reordenat les files" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "columna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "columna %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "A baix de tot de la columna." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "A dalt de tot de la columna." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "no seleccionat" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "no seleccionat" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "fila %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "fila %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Inici de la fila." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Final de la fila." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "S'ha suprimit la fila." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "S'ha suprimit l'última fila." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "S'ha inserit una fila." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "S'ha inserit una fila al final de la taula." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "S'ha suprimit la fila." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "no seleccionat" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "seleccionat" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "no seleccionat" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H hores, %M minuts i %S segons." - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H hores i %M minuts." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "desfés" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "refés" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "espai en blanc" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Continua la busca des de baix." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Continua la busca des de dalt." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elements" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "La cel·la s'expandeix %d fila" -msgstr[1] "La cel·la s'expandeix %d files" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d columna" -msgstr[1] "%d columnes" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "La cel·la s'expandeix %d columna" -msgstr[1] "La cel·la s'expandeix %d columnes" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d caràcter massa llarg" -msgstr[1] "%d caràcters massa llarg" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d diàleg)" -msgstr[1] "(%d diàlegs)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d diàleg sense focus" -msgstr[1] "%d diàlegs sense focus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fitxer trobat" -msgstr[1] "%d fitxers trobats" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulari" -msgstr[1] "%d formularis" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d encapçalament" -msgstr[1] "%d encapçalaments" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elements" -msgstr[1] "%d elements" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Punt de referència %d" -msgstr[1] "Punts de referència %d" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "S'ha trobat %d element" -msgstr[1] "S'han trobat %d elements" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "S'està eixint de %d cita en bloc." -msgstr[1] "S'està eixint de %d cites en bloc." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "S'està eixint de %d llista." -msgstr[1] "S'està eixint de %d llistes." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Llista amb %d element" -msgstr[1] "Llista amb %d elements" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Llista amb %d element" -msgstr[1] "Llista amb %d elements" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Valor" -msgstr[1] "Valor" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "taula matemàtica amb %d fila" -msgstr[1] "taula matemàtica amb %d files" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d columna" -msgstr[1] "%d columnes" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "taula matemàtica imbricada amb %d fila" -msgstr[1] "taula matemàtica imbricada amb %d files" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d missatge.\n" -msgstr[1] "%d missatges.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d per cent." -msgstr[1] "%d per cent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "s'ha llegit l'%d per cent del document" -msgstr[1] "s'ha llegit el %d per cent del document" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d píxel" -msgstr[1] "%d píxels" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] " %(count)d caràcter %(repeatChar)s" -msgstr[1] " %(count)d caràcters %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "seleccionat %(index)d element de %(total)d" -msgstr[1] "seleccionats %(index)d elements de %(total)d" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "S'ha trobat %d drecera per defecte del lector de pantalla." -msgstr[1] "S'han trobat %d dreceres per defecte del lector de pantalla." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"S'ha trobat %(count)d drecera del lector de pantalla per a %(application)s." -msgstr[1] "" -"S'han trobat %(count)d dreceres del lector de pantalla per a %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espai" -msgstr[1] "%d espais" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulació" -msgstr[1] "%d tabulacions" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d taula" -msgstr[1] "%d taules" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "taula de continguts" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "taula amb %d fila" -msgstr[1] "taula amb %d files" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "taula amb %d fila" -msgstr[1] "taula amb %d files" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "taula amb %d fila" -msgstr[1] "taula amb %d files" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d enllaç sense visitar" -msgstr[1] "%d enllaços sense visitar" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d enllaç visitat" -msgstr[1] "%d enllaços visitats" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "commuta" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "al %(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVELL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nivell de l'arbre %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVELL DE L'ARBRE %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "pregunta" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "quadre combinat editable" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "taula de continguts" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "canal" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figura" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "resum" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "reconeixements" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "epíleg" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "apèndix" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "entrada de bibliografia" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografia" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "capítol" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colofó" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conclusió" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "portada" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "crèdit" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "crèdits" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedicatòria" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "nota final" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "notes finals" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epígraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epíleg" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "exemple" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "prefaci" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glossari" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "índex" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introducció" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "salt de pàgina" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "llista de pàgines" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "part" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "pròleg" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "pròleg" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "cita destacada" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "preguntes i respostes" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "subtítol" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "taula de continguts" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "c%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivell %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "barra de desplaçament horitzontal" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "barra de desplaçament vertical" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "lliscador horitzontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "lliscador vertical" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "separador horitzontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "separador vertical" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "commutador" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Icona del quadre" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "bàner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "contingut complementari" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informació" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "contingut principal" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navegació" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "regió" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "busca" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "enllaç visitat" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "botó de menú" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "clicable" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "col·lapsat" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "expandit" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "té una descripció llarga" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horitzontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "verificat" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "no verificat" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "actiu" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "inactiu" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "verificat parcialment" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "premut" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "no premut" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "no seleccionat" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "seleccionat" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "no seleccionat" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "no seleccionada" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visitat" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "sense visitar" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ombrejat" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "només lectura" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "lectura" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "obligatori" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "selecció múltiple" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "entrada no vàlida" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "no vàlid" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ortografia no vàlida" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ortografia" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "gramàtica no vàlida" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramàtica" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Busca" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Diàleg de busca del lector de pantalla" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Tanca" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Cerca" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Cerca:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Busca:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_A dalt de tot de la finestra" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "A dalt de tot de la finestra" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Inicia des de:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Ajusta" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Busca _cap arrere" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Direcció de la busca:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Coincideix les majúscules i minúscules" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Coincideix només la paraula s_encera" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opcions de busca" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Predeterminat" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Majúscules" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Enllaç" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicació" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Finestra" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Lector de pantalla Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "A_juda" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Aplica" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Portàtil" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Disposició del teclat" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Perfil actiu:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Perfil d'inici:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Carrega" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "_Anomena i guarda" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Perfils" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Indicadors de funció _presents" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Pronuncia l'objecte sota el _punter" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Ratolí" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Format de l'_hora:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Format de _data:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Hora i data" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Pronuncia les actualitzacions" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Actualitzacions de _Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Freqüència (segons):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplicació" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Eme_t un to per les actualitzacions" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Actualitzacions de la barra de progrés" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Habilita _rebobina i avanç ràpid a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Habilita la navegació e_structural a Pronuncia-ho tot" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Pronuncia-ho tot p_er:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Anuncia _cites en bloc a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Anuncia _llistes a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Anuncia t_aules a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Anuncia _quadres a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Anuncia _formularis a Pronuncia-ho tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Anuncia p_unts de referència a Pronuncia-ho tot" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Pronuncia-ho tot" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "General" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lum:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Veloci_tat:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Ràtio:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persona:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "idioma" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Sintetit_zador de pronunciació:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Sistema de pronunciació:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipus de _veu:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Estil de majús_cules:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Paràmetres del tipus de veu" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" -"Pronuncia les cadenes AmbMajúsculesIMinúscules com a _paraules separades" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Pronuncia els _nombres com a dígits" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Paràmetres de veu globals" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Veu" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Habilita la pronunciació" - -# "Verbós" ? (josep) -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Detallat" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Nivell de detall" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Tot" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Nivell de puntuació" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Pronuncia únicament el text que es mostra" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Pronuncia les línies en blanc" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Pronunc_ia el sagnat i la justificació" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Pronuncia els _mnemònics de l'objecte" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Pronuncia la p_osició filla" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Pronuncia els missatges del programa d'aprenentatge" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Els missatges de _sistema són detallats" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "_Pronuncia els colors com a noms" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Anuncia _cites en bloc durant la navegació" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Anuncia ll_istes durant la navegació" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Anuncia t_aules durant la navegació" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Pronuncia l'indicador de les paraules a_mb errors d'ortografia" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Anuncia _quadres durant la navegació" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Anuncia p_unts de referència durant la navegació" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Anuncia _formularis durant la navegació" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Pronuncia la d_escripció" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Pronuncia la ĺínia completa als fu_lls de càlcul" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Pronuncia la línia completa a taules _document" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Pronuncia la línia completa a taules I_GU" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Context parlat" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Parla" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Habilita les funcion_s de Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Noms de rol _abreujats" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Inhabilita el símbol de _fi de línia" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Taula de contraccions:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Habilita el braille contret" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Habilita l'eco per _paraula" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Paràmetres de visualització" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Cap" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicador de la selecció" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicador d'enllaç" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Habilita els _missatges flash" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Duració del missat_ge (segons):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Els missatges són _persistents" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Els missatges són _detallats" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Configuracions dels missatges flash" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Habilita l'eco de les _tecles" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Habilita les tecles _alfabètiques" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Habilita les tecles _numèriques" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Habilita les tecles de _puntuació" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Habilita l'e_spaiador" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Habilita el _modificador de tecles" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Habilita les tecles de _funcions" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Habili_ta les tecles d'acció" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Habilita les tecles de _navegació" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Habilita l'eco per _paraula" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Habilita l'eco per _frase" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Eco de les tecles" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Tecles de _modificació del lector de pantalla:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Vinculacions de tecla" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Diccionari de pronunciació" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Entrada _nova" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Suprimeix" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronunciació" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Pronuncia-ho tot" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Pronuncia el _nom" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Reinicia" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributs del text" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mou-te al _fons" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mou-te una _avall" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mou-te una a_munt" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mou a _dalt de tot" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Ajusta els atributs seleccionats" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicador de Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributs del text" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "baix" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "idioma" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "ien" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "S'ha copiat el contingut al porta-retalls." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : índia, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "color de fons" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "alçària total del fons" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "fons puntejat" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direcció" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editable" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nom de família" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "color del primer pla" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "primer pla puntejat" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efectes del tipus de lletra" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "sagnat" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "errada" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justificació" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "idioma" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "marge esquerre" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "alçària de línia" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "estil del paràgraf" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "píxels per sobre de les línies" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "píxels per sota de les línies" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "píxels dins les línies ajustades" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "marge dret" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "aixecat" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "escala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "mida" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "amplària" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "barrat" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decoració del text" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotació del text" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "ombra del text" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "subratllat" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "alineació vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "pes" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "mode d'ajustament" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "mode d'escriptura" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "cert" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "fals" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "cap" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "gravat" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "relleu" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "contorn" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "línia de sobre" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "barrat" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "parpelleig" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "negre" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "únic" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "doble" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "baix" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "caràcter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "paraula" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "caràcter de paraula" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "d'esquerra a dreta" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "de dreta a esquerra" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "esquerra" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "dreta" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centre" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "sense justificació" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "omple" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensada" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensada" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensada" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensada" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi expandida" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expandida" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra expandida" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra expandida" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "versaletes" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "obliqua" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "cursiva" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Predeterminat" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Cos del text" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Encapçalament" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "línia base" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "súper" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "dalt" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "text a dalt" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "mig" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "a baix" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "text a baix" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "heretat" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "d'esquerra a dreta, de dalt a baix" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "de dreta a esquerra, de dalt a baix" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "de dalt a baix, de dreta a esquerra" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "de dalt a baix, d'esquerra a dreta" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "de baix a dalt, de dreta a esquerra" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "de baix a dalt, d'esquerra a dreta" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "d'esquerra a dreta" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "de dreta a esquerra" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "de dalt a baix" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "sòlid" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "verificació ortogràfica" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Premeu la barra espaiadora per commutar." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Premeu la barra espaiadora per expandir i utilitzeu les tecles de cap amunt " -"i cap avall per seleccionar un element." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Premeu Alternativa+F6 per donar el focus a les finestres filles." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Per moure's a elements, utilitzeu les tecles de cursor, o utilitzeu la busca " -"automàtica en escriure." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" -"Per accedir als menús del sistema premeu la combinació de tecles " -"alternativa+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" -"Utilitzeu les tecles de cap amunt i cap avall per seleccionar un element." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Per reduir, premeu majúscula i esquerra." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Per expandir, premeu majúscula i dreta." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Per activar-lo premeu la tecla de retorn." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Escriviu text." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Utilitzeu les tecles dreta i esquerra per veure altres pestanyes." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Per activar-lo premeu la barra espaiadora." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Utilitzeu les tecles de cap amunt o cap avall per seleccionar un valor. O " -"teclegeu el valor numèric desitjat." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Utilitzeu les tecles de cursor per canviar." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Per navegar, premeu les tecles de fletxa cap a l'esquerra i cap a la dreta. " -"Per moure-vos a través dels elements premeu les tecles de cap amunt o cap " -"avall." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Per entrar a un submenú, premeu la tecla de fletxa cap a la dreta." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Per retrocedir premeu la tecla cap a l'esquerra, per avançar premeu la tecla " -"cap a la dreta. Per anar a l'inici premeu la tecla d'inici i per anar al " -"final premeu la tecla de final." diff --git a/po/ckb.po b/po/ckb.po deleted file mode 100644 index 1c3d9fc..0000000 --- a/po/ckb.po +++ /dev/null @@ -1,9292 +0,0 @@ -# Kurdish (Sorani) translation for cthulhu -# Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020 -# This file is distributed under the same license as the cthulhu package. -# FIRST AUTHOR , 2020. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2020-05-05 00:44+0300\n" -"Last-Translator: Jwtiyar Nariman \n" -"Language-Team: Kurdish (Sorani) \n" -"Language: ckb\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Launchpad-Export-Date: 2020-05-04 21:32+0000\n" -"X-Generator: Poedit 2.3\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "خوێنەری پەردەی ئۆرکا" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "؟؟؟" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "کێشان" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "فۆرم" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "سەرەوە" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "وێنە" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "بەستەر" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "لیست" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "بەش" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "جیاکار" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "سوڕان" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "خشتە" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "خانە" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "تێرم" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "دەق" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "دوگمە" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "توڵا" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "درەخت" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "نەز" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "سەر" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "خوار" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "بەند" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "خۆکار" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Czech Grade 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "پلەی ئیسپانی ١" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "پلەی فەڕەنسی کەنەدی ٢" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "پلەی فەڕەنسی فەڕەنسی ٢" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "پلەی لاتیڤی ١" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "پلەی ئەڵمانی هؤلەندی ١" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "پلەی نەرویجی ٠" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "پلەی نەرویجی ١" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "پلەی نەرویجی ٢" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "پلەی نەرویجی ٣" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "پلەی پۆڵەندی ١" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "پلەی پرتوگالی ١" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "پلەی سویدی ١" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "پلەی عەرەبی ١" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "پلەی وێڵزی ١" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "پلەی وێڵزی ٢" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "پلەی ئەڵمانی ٠" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "پلەی ئەڵمانی ١" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "پلەی ئەڵمانی ٢" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "پلەی ئینگلیزی بەڕیتانی ٢" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "پلەی ئینگلیزی بەڕیتانی ١" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "پلەی ئینگلیزی ئەمریکی ١" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "پلەی ئینگلیزی ئەمریکی ٢" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "پلەی فەڕەنسی کەنەدی ١" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "پلەی فەڕەنسی فەڕەنسی ١" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "پلەی یۆنانی ١" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "پلەی هندی ١" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "کۆمپیوتەری هەنگاری ٨ خاڵی" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "پلەی هەنگاری ١" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "پلەی هەنگاری ١" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "پلەی ئیتاڵی ١" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "پلەی بەلجیکی ئەڵمانی ١" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "بۆشایی" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "دێڕێکی نوێ" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "بازدەر" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "سەرسوڕمان" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "دەقی وەرگیراو" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "ژمارە" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "دۆلار" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "ڕێژە" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "و" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "نیشانەی خاوەنیەتی" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "کەوانەی چەپ" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "کەوانەی ڕاست" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "ئەستێرە" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "زیادکردن" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "کۆما" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "بەندەک" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "خاڵ" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "لارەهێڵ" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "جووتخاڵ" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "نیمچەخاڵ" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "بچووکتر" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "یەکسان" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "گەورەتر" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "پرسیار" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "@" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "ئەستوونی چەپ" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "لارهێڵێ دوواوە" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "ئەستوونی ڕاست" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "دیارکەری سەرەوە" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "ژێرهێڵ" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "لاری ڕاست" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "توڵی ستوونی" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "لاری ڕاست" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "ناوەڕاستەهێڵ" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "هێمای سەرسوڕمانی هەڵگەڕاوە" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "سەند" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "پاوەندی ئیستەرلینی" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "هێمای دراو" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "یەن" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "توڵی شکاو" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "بەش" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "مافی لبەرگرتنەوە" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "نەخێری ژیربێژەکی" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "تۆمارکراو" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "هێلێسەرەوە" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "پلە" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "زیادکردن یا کەمکردن" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "ئەکیوت" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "نیو" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "دیارکەری بەند" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "خاڵی ناوەڕاست" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "جیاکەرەوە" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "چارەگ" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "نیوە" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "سێ چارەگ" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "هەڵگەڕاوەی هێمای پرسیار" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "ئەکیوت تیژ" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ئەکیوت" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A دووخاڵ" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "بازنەی A" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C سێدیلا" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ئەکیوت" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E دووخاڵ" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ئەکیوت" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ئەکیوت" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "چەندجارە" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O هێڵ" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ئەکیوت" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U دووخاڵ" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ئەکیوت" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "سۆرن" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s تیژ" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a دووخاڵ" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a بازنە" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e ئەکیوت" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e دووخاڵ" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i ئەکیوت" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i دووخاڵ" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o ئەکیوت" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o دووخاڵ" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "دابەشکراو بەسەر" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "سۆرن" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u ئەکیوت" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u دووخاڵ" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y ئەکیوت" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y دووخاڵ" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y دووخاڵ" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "فلۆرین" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "بەندەکی جیاکار" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "هێمای دەقی تاک چەپ" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "هێمای دەقی تاک ڕاست" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "هێمای دەقی تاک خوارەوە" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "هێمای دەقی دووانی چەپ" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "هێمای دەقی دووانی ڕاست" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "هێمای دەقی دووانی خوار" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "هێمای خەنجەر" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "هێمای دوو خەنجەر" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "خاڵی تێر" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "خاڵی سێگۆشە" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "بۆ هەر میلێک" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "پرایم" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "پرایمی دووانی" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "پرایمی سیانی" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "بەستهێڵ" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "یۆرۆ" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "هێمای بازرگانی" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "هێمای ڕاست" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "هێمای ڕاستی تێر" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "هێمای x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "سەرنووس ٠" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "سەرنووس ٤" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "سەرنووس ٥" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "سەرنووس ٦" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "سەرنووس ٧" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "سەرنووس ٨" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "سەرنووس ٩" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "سەرنووسی زیادکردن" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "سەرنووس لێدەرکردن" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "سەرنووس یەکسان" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "سەرنووسی کەوانەی چەپ" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "سەرنووسی کەوانەی راست" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "سەرنووسی n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "ژێرنووسی ٠" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "ژێرنووسی ١" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "ژێرنووسی ٢" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "ژێرنووسی ٣" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "ژێرنووسی ٤" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "ژێرنووسی ٥" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "ژێرنووسی ٦" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "ژێرنووسی ٧" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "ژێرنووسی ٨" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "ژێرنووسی ٩" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "ژێرنووسی زیاکردن" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "ژێرنووسی لێدەرکردن" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "ژێرنووسی یەکسان" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "ژێرنووسی کەوانەی چەپ" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "ژێرنووسی کەوانەی ڕاست" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "چوارگۆشەی ڕەش" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "ئەڵماسی ڕەش" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "نووسەی گۆرەڕی تەنەکان" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "هەموو بەڵگەنامەکان پیشاندەدات" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "هەموو بەڵگەنامەکان پیشاندەدات" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "پێشاندانی وردەکاری بەستەر." - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "بڕۆ بۆ دوگمەی داهاتوو." - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "پیشاندانی توڵی ئاگانامەکان." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "پیشاندانی توڵی ناونیشانەکان." - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "کردنەوەی پەنجەرەی دۆزینەوە." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "بڕۆ بۆ سەرەتایی هێڵ." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "بڕۆ بۆ سەرەتایی هێڵ." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "بڕۆ بۆ نووسەی پێشوو" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "بچۆ بۆ نووسەی داهاتوو." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "بڕۆ بۆ کۆتایی هێڵ." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "بڕۆ بۆ سەرەتایی هێڵ." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "بڕۆ بۆ کۆتایی هێڵ." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "بڕۆ بۆ تەنی پێشوو." - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "خوێنەری پەردەی ئۆرکا" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "بگەڕێوە بۆ شوێنی دڵخوازی پێشوو." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "بڕۆ بۆ دڵخوازەکان" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "بڕۆ بۆ شوێنی دڵخوازی داهاتوو." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "دڵخواز زیاد بکە." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "دڵخوازەکان پاشەکەوت بکە." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "کاتی ئێستا پێشکەش بکە." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "ڕؤژی ئێستا پێشکەش بکە." - -#: src/cthulhu/cmdnames.py:595 -#, fuzzy -msgid "Present size and location of current object" -msgstr "شوێن و قەبارەی ئێشتای تەن پێشکەش بکە" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "چەپی هێڵ" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "ڕاستی هێڵ" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "سەروی هێڵ" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "خواروی هێڵ" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "بەستن" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "سەرەوەی چەپ" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "خواروی چەپ" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "شوێنی دیاریکەر" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "شەش خاڵ" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "ئاراستەی جێنیشاندەر" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "دەستپێکردن بەبڕین" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "بڕینی هێڵ" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "بچۆ بۆ نووسەی داهاتوو." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "بڕۆ بۆ نووسەی پێشوو" - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "بڕۆ بۆ وشەی داهاتوو." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "بڕۆ بۆ وشەی پێشوو." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "بڕۆ بۆ سەرەوەی پەڕگە." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "بڕۆ بۆ خوارەوەی پەڕگە." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "بڕۆ بۆ سەرەتایی هێڵ." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "بڕۆ بۆ کۆتایی هێڵ." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "بڕؤ بۆ تەنی داهاتوو" - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "بڕۆ بۆ تەنی پێشوو." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "بڕۆ بۆ کۆتایی هێڵ." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "بڕۆ بۆ دوگمەی پێشوو." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "بڕۆ بۆ دوگمەی داهاتوو." - -#: src/cthulhu/cmdnames.py:852 -#, fuzzy -msgid "Display a list of blockquotes" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "بڕۆ بۆ دوگمەی پێشوو." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "بڕۆ بۆ دوگمەی داهاتوو." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "بڕۆ بۆ دوگمەی پێشوو." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "بچۆ بۆ نووسەی داهاتوو." - -#: src/cthulhu/cmdnames.py:870 -#, fuzzy -msgid "Display a list of check boxes" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "بڕۆ بۆ دوگمەی پێشوو." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "بڕۆ بۆ دوگمەی داهاتوو." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "بڕۆ بۆ سەرەتای کۆنتێنەر." - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "بڕۆ بۆ کۆتایی کۆنتێنەر." - -#: src/cthulhu/cmdnames.py:901 -#, fuzzy -msgid "Display a list of combo boxes" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "بڕۆ بۆ وشەی پێشوو." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "بڕۆ بۆ وشەی داهاتوو." - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "بڕۆ بۆ وشەی پێشوو." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "بڕۆ بۆ وشەی داهاتوو." - -#: src/cthulhu/cmdnames.py:919 -#, fuzzy -msgid "Display a list of form fields" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "بڕۆ بۆ نووسەی پێشوو" - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "بچۆ بۆ نووسەی داهاتوو." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:949 -#, fuzzy -msgid "Display a list of internal frames" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "بڕۆ بۆ تەنی پێشوو." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "بڕؤ بۆ تەنی داهاتوو" - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:1006 -#, fuzzy -msgid "Display a list of lists" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "بڕۆ بۆ نووسەی پێشوو" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "بچۆ بۆ نووسەی داهاتوو." - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "بڕۆ بۆ دوگمەی پێشوو." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "بڕۆ بۆ دوگمەی داهاتوو." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "بڕۆ بۆ نووسەی پێشوو" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "بچۆ بۆ نووسەی داهاتوو." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "بڕؤ بۆ هێڵی پێشوو." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "بڕۆ بۆ هێڵی داهاتوو." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "نیشاندانی لیستەی دوگمەکان." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_پاشگەزبوونەوە" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_باشە" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "هیج" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "کۆما" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "بنەڕەت" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "بەش" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "دڵخوازەکان پاشەکەوت بکە." - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "دەستکاریکراوە" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "خوێنەری پەردەی ئۆرکا" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "نەرمەواڵا" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "دوگمە" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "كورتەیەک" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "پارێزگا" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "یووئارئای" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "نرخ" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "به‌سته‌ره‌كان" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "لیستەکان" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "بنەڕەت" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "سیسته‌م" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "پێڕست" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "راستە" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "داوانامە" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "بڕۆ بۆ دڵخوازەکان" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "وێنۆچکە" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "شوێن و قەبارەی ئێشتای تەن پێشکەش بکە" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "هیج" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "بڕۆ بۆ وشەی داهاتوو." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "بڕۆ بۆ وشەی داهاتوو." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "ناچالاککراو" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "چالاككراو" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "بەستەر" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "ناکارا" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "بڕؤ بۆ تەنی داهاتوو" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "کەوانەی چەپ" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "بڕۆ بۆ وشەی پێشوو." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "خوارەوە" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "ناکارا" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "هیج" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "خوێنەری پەردەی ئۆرکا" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "نرخ" -msgstr[1] "نرخ" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d پیکسڵ" -msgstr[1] "%d پیکسڵ" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "ناکارا" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "هەڵەیە" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_داخستن" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_دۆزینەوە" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "بنەڕەت" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "سیسته‌م" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "نەرمەواڵا" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "خوێنەری پەردەی ئۆرکا" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_یارمەتی" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_جێبەجێکردن" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "پاشەکەوتکردن _وەک" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "ـسڕینەوە" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "مشک" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "نەرمەواڵا" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "گشتی" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_سڕینەوە" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "ئاستی نزم" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "یەن" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "راستە" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "ئاستی نزم" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "بنەڕەت" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/cs.po b/po/cs.po deleted file mode 100644 index 0820f10..0000000 --- a/po/cs.po +++ /dev/null @@ -1,9277 +0,0 @@ -# Czech translation of cthulhu. -# Copyright (C) 2004, 2008, 2009, 2010 the author(s) of cthulhu. -# This file is distributed under the same license as the cthulhu package. -# -# Miloslav Trmac , 2004. -# Jakub Friedl , 2007. -# Martin Sukany , 2008. -# Lucas Lommer , 2008, 2009, 2010, 2012 -# Petr Kovar , 2008. -# Marek Černocký , 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-09-14 14:52+0200\n" -"Last-Translator: Daniel Rusek \n" -"Language-Team: čeština \n" -"Language: cs\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Čtečka obrazovky Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "obrazovka;čtečka;přístupnost;řeč;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "výstr" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "šip" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "titl" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "zaškr" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "výbbarv" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "záhlsl" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "datm" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ikn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "plch" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "čís" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "adrpan" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "kres" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "výbsoub" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "výpl" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "písm" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "průhpan" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "nadp" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "obr" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "vnrám" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "pops" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "vrspan" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "odk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "sez" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "polsez" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "nab" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "nab" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "polnab" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "panvol" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "str" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "sezkrt" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "hesl" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "kontxnab" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "průb" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "tlač" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "skuppř" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "polskpř" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "horpan" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "záhlřád" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "posv" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "posvpan" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "odd" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "odděl" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "táhl" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "rozpan" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "čísl" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "stat" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tab" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "buň" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "odtrhnabpol" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "přep" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "nástrpan" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "strm" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "strmsez" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "nezn" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "výř" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "okn" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hlav" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pat" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "odst" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apl" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "lišupr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "vnřobj" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Čeština, Grade 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Španělština, Grade 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanadská francouzština, Grade 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francouzská francouzština, Grade 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Lotyština, Grade 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Nizozemská nizozemština, Grade 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norština, Grade 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norština, Grade 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norština, Grade 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norština, Grade 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polština, Grade 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugalština, Grade 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Švédština, Grade 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabština, Grade 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Velština, Grade 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Velština, Grade 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Němčina, Grade 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Němčina, Grade 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Němčina, Grade 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Britská angličtina, Grade 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Britská angličtina, Grade 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Americká angličtina, Grade 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Americká angličtina, Grade 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadská francouzština, Grade 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francouzská francouzština, Grade 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Řečtina, Grade 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindština, Grade 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Maďarština, 8bodové počítačové" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Maďarština, Grade 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Maďarština, Grade 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italština, Grade 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Vlámština, Grade 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "mezera" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nový řádek" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulátor" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "vykřičník" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "uvozovky" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "číslo" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "et" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "závorka" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "zavřít závorka" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "hvězdička" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "čárka" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "pomlčka" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "tečka" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "lomeno" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dvojtečka" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "středník" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "je menší než" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "je rovno" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "je větší než" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "otazník" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "zavináč" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "hranatá závorka" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "zpětné lomítko" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "zavřít hranatou závorku" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "stříška" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "podtržítko" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "obrácená čárka" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "složená závorka" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "svislá čára" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "zavřít složenou závorku" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "pevná mezera" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "obrácený vykřičník" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centů" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "liber" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "značka měny" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jenů" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "přerušená svislá čára" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "paragraf" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "rozlučník" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "horní index a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "francouzské uvozovky vpravo" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logická negace" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "podmíněný spojovník" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrováno" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "vodorovná čárka" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "stupňů" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus mínus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "horní index 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "horní index 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "čárka" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mikro" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "znak odstavce" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "tečka uprostřed" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "sedil" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "horní index 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "pořadový indikátor" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "francouzské uvozovky vlevo" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "čtvrtina" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "polovina" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tři čtvrtiny" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "obrácený otazník" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "dlouhé a" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A S TĚŽKÝM AKCENTEM" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "DLOUHÉ A" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A SE STŘÍŠKOU" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A S TILDOU" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "PŘEHLASOVANÉ A" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A S KROUŽKEM" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "LIGATURA AE" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C SEDIL" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E S TĚŽKÝM AKCENTEM" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "DLOUHÉ E" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E SE STŘÍŠKOU" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "PŘEHLASOVANÉ E" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I S TĚŽKÝM AKCENTEM" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "DLOUHÉ I" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I SE STŘÍŠKOU" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "PŘEHLASOVANÉ I" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETHA" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N S TILDOU" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O S TĚŽKÝM AKCENTEM" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "DLOUHÉ O" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O SE STŘÍŠKOU" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O S TILDOU" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "PŘEHLASOVANÉ O" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "krát" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "PŘEŠKRTNUTÉ O" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U S TĚŽKÝM AKCENTEM" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "DLOUHÉ U" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U SE STŘÍŠKOU" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "PŘEHLASOVANÉ U" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "DLOUHÉ Y" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "ostré s" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a s těžkým akcentem" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a se stříškou" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a s tildou" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "přehlasované a" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a s kroužkem" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ligatura ae" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c sedil" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e s těžkým akcentem" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "dlouhé e" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e se stříškou" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "přehlasované e" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i s těžkým akcentem" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "dlouhé i" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i se stříškou" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "přehlasované i" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "etha" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n s tildou" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o s těžkým akcentem" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "dlouhé o" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o se stříškou" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o s tildou" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "přehlasované o" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "děleno" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "přeškrtnuté o" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "dlouhé u" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u s těžkým akcentem" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u se stříškou" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "přehlasované u" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "dlouhé y" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "přehlasované y" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "PŘEHLASOVANÉ Y" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "krátký spojovník" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "jednoduché uvozovky vlevo" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "jednoduché uvozovky vpravo" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "jednoduché uvozovky dole" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "dvojité uvozovky vlevo" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "dvojité uvozovky vpravo" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dvojité uvozovky dole" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "kříž" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dvojitý kříž" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "odrážka" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trojúhelníková odrážka" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promile" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "minuta nebo stopa" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "sekunda nebo palec" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "tercie" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "odrážka s pomlčkou" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "ochranná známka" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "zatržítko" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "silné zatržítko" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "odrážka s křížkem" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "horní index 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "horní index 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "horní index 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "horní index 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "horní index 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "horní index 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "horní index 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "horní index plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "horní index mínus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "horní index rovná se" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "horní index levá závorka" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "horní index pravá závorka" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "horní index n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "dolní index 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "dolní index 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "dolní index 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "dolní index 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "dolní index 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "dolní index 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "dolní index 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "dolní index 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "dolní index 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "dolní index 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "dolní index plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "dolní index mínus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "dolní index rovná se" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "dolní index levá závorka" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "dolní index pravá závorka" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "čtvereček" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "kosočtverec" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "znak nahrazující objekt" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Přesunout ukazatel na aktuální položku" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Provést levé kliknutí myši na aktuální položce plošného náhledu" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Provést pravé kliknutí myši na aktuální položce plošného náhledu" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Přečíst celý dokument" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Přečíst celé okno v plošném náhledu" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Zběžně říct, kde se právě nacházíte" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Podrobně říct, kde se právě nacházíte" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Přečíst aktuální výběr" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Přečíst podrobnosti k odkazu" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Prezentovat výchozí tlačítko" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Prezentovat stavový řádek" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Prezentovat název okna" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Otevřít dialogové okno hledání" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Zobrazit seznam akcí" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Hledat následující výskyt řetězce" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Hledat předchozí výskyt řetězce" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Zapnout nebo vypnout režim plošného náhledu" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Přesunout plošný náhled na koncovou pozici" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Přesunout plošný náhled na počáteční pozici" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Přesunout plošný náhled na koncovou pozici" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Přesunout plošný náhled na začátek předcházejícího řádku" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Přečíst aktuální řádek v plošném náhledu" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Vyhláskovat aktuální řádek v plošném náhledu" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Foneticky vyhláskovat aktuální řádek v plošném náhledu" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Přesunout plošný náhled na začátek následujícího řádku" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Přesunout plošný náhled na předchozí položku nebo slovo" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Přečíst aktuální položku nebo slovo plošného náhledu" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Vyhláskovat aktuální položku nebo slovo plošného náhledu" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Foneticky vyhláskovat aktuální položku nebo slovo plošného náhledu" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Přesunout plošný náhled na následující položku nebo slovo" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Přesunout plošný náhled na slovo nad aktuálním slovem" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Přečíst aktuální objekt plošného náhledu" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Přesunout plošný náhled na slovo pod aktuálním slovem" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Přesunout plošný náhled na předchozí znak" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Přečíst aktuální znak plošného náhledu" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Foneticky přečíst aktuální znak plošného náhledu" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Přečíst hodnotu Unicode aktuálního znaku plošného náhledu" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Přesunout plošný náhled na následující znak" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Přesunout plošný náhled na konec řádku" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Přesunout plošný náhled vlevo dolů" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Zkopírovat obsah pod plošným náhledem do schránky" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Připojit obsah pod plošným náhledem do schránky" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Zobrazit obsah plošného náhledu" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Přepout mezi čtením celého řádku nebo aktuální buňky v tabulce" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Přečíst vlastnosti přiřazené aktuálnímu znaku" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Posunout braillský řádek doleva" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Posunout braillský řádek doprava" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Vrátit se na objekt s aktivní klávesnicí" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Vypnout nebo zapnout režim zkratkopisu braillského řádku" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Zpracovat klávesu přesunu kurzoru" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Označit začátek výběru textu" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Označit konec výběru textu" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Zapnout výukový režim. Zmáčknutím Escape jej ukončíte" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Zpomalit tempo řeči" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Zrychlit tempo řeči" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Snížit výšku hlasu řeči" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Zvýšit výšku hlasu řeči" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Zvýšit hlasitost řeči" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Snížit hlasitos řeči" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Vybrat předchozí nastavení řeči" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Vybrat další nastavení řeči" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Snížit aktuální nastavení řeči" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Zvýšit aktuální nastavení řeči" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Uložit nastavení řeči" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Zapnout nebo vypnout čtení" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Přepnout úroveň upovídanosti" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Přepnout režim spánku" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Ukončit čtečku obrazovky" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Zobrazit dialogové okno předvoleb" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Zobrazit dialogové okno předvoleb aplikace" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Přepnout čtení odsazení a zarovnání" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Změnit styl čtení čísel" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Přejít na další úroveň čtení interpunkce" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Přejít na další hlasový výstup" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Přejít na další profil s nastavením" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Přejít na další styl čtení velkých písmen" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Přejít na další úroveň oznamování kláves" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Přejít na další úroveň hlášení při ladění za běhu" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Označit záložkou, kde se nacházím respektující aktuální pozici" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Přejít na umístění podle předchozí záložky" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Přejít na záložku" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Přejít na umístění podle následující záložky" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Přidat záložku" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Uložit záložky" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Přepínout mezi režimy zkoumání myší" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Prezentovat informace o aktuálním čase" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Prezentovat informace o aktuálním datu" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Prezentovat velikost a pozici aktuálního objektu" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Předat následující příkaz do aktuální aplikace" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Přečíst a zobrazit na braillském řádku předchozí rychlou zprávu" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Přepnout, jestli je oznamováno, když píše náš kamarád" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Přepnout, jestli chcete poskytovat historii zpráv ke konkrétní místnosti" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Přepnout, jestli se má přidávat název diskuzní místnosti před rychlé zprávy" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Řádek vlevo" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Řádek vpravo" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Řádek nahoru" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Řádek dolů" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Zmrazit" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "vlevo nahoře" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "vlevo dole" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Pozice kurzoru" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Šest bodů" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Umisťování kurzoru" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Začít kopírování" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Dokončit kopírování" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Prezentovat poslední upozornění" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Prezentovat seznam upozornění" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Prezentovat předchozí upozornění" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Prezentovat následující upozornění" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Přejít na následující znak" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Přejít na předchozí znak" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Přejít na následující slovo" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Přejít na předchozí slovo" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Přejít na následující řádek" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Přejít na předchozí řádek" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Přejít na začátek souboru" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Přejít na konec souboru" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Přejít na začátek řádku" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Přejít na konec řádku" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Přejít na následující objekt" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Přejít na předchozí objekt" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Rozbalit aktuální rozbalovací seznam" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Přepnout mezi kurzorovou navigací čtečky obrazovky a nativní" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Rozšířená nastavení chování živé oblasti" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Nastavit výchozí chování živé oblasti na vypnuto" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Prohlížet oznámení živé oblasti" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Sledovat živé oblasti" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Přesunout zaměření na a z okna pod kurzorem myši" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Nastavit řádek, který se použije jako dynamické záhlaví sloupce" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Zrušit dynamické záhlaví sloupců" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Nastavit sloupec, který se použije jako dynamické záhlaví řádků" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Zrušit dynamické záhlaví řádků" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Prezentovat obsah vstupního řádku" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Zapnout nebo vypnout strukturální navigaci" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Přejít na předchozí citaci" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Přejít na následující citaci" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Zobrazit seznam citací" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Přejít na předchozí tlačítko" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Přejít na následující tlačítko" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Zobrazit seznam tlačítek" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Přejít na předchozí zaškrtávací políčko" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Přejít na následující zaškrtávací políčko" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Zobrazit seznam zaškrtávacích políček" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Přejít na předchozí kliknutelný prvek" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Přejít na následující kliknutelný prvek" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Zobrazit seznam kliknutelných prvků" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Přejít na předchozí rozbalovací seznam" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Přejít na následující rozbalovací seznam" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Přejít na začátek kontejneru" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Přejít na konec kontejneru" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Zobrazit seznam rozbalovacích seznamů" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Přejít na předchozí vstupní pole" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Přejít na následující vstupní pole" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Zobrazit seznam vstupních polí" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Přejít na předchozí formulářové pole" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "přejít na následující formulářové pole" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Zobrazit seznam formulářových polí" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Přejít na předchozí nadpis" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Přejít na následující nadpis" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Zobrazit seznam nadpisů" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Přejít na předchozí nadpis úrovně %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Přejít na následující nadpis úrovně %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Zobrazit seznam nadpisů úrovně %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Přejít na předchozí tabulku" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Přejít na následující tabulku" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Zobrazit seznam tabulek" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Přejít na předchozí obrázek" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Přejít na následující obrázek" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Zobrazit seznam obrázků" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Přejít na předchozí záchytný bod" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Přejít na následující záchytný bod" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Zobrazit seznam záchytných bodů" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Přejít na předchozí velký objekt" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Přejít na následující velký objekt" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Zobrazit seznam velkých objektů" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Přejít na předchozí odkaz" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Přejít na následující odkaz" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Zobrazit seznam odkazů" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Přejít na předchozí seznam" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Přejít na následující seznam" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Zobrazit seznam seznamů" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Přejít na předchozí položku seznamu" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Přejít na následující položku seznamu" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Zobrazit seznam položek seznamů" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Přejít na předchozí živou oblast" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Přejít na následující živou oblast" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Přejít na poslední živou oblast, která provedla oznámení" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Přejít na nadřazený objekt objektu s fokusem navigátoru." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Přejít na první potomek objektu s fokusem navigátoru." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Přejít na následujícího sourozence objektu s fokusem navigátoru." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Přejít na předchozího sourozence objektu s fokusem navigátoru." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Vrátit se na objekt s aktivní klávesnicí" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Přepnout zjednodušenou navigaci objektů." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Přejít na předchozí odstavec" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Přejít na následující odstavec" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Zobrazit seznam odstavců" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Přejít na předchozí skupinový přepínač" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Přejít na následující skupinový přepínač" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Zobrazit seznam skupinových přepínačů" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Přejít na předchozí oddělovač" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Přejít na následující oddělovač" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Přejít na předchozí tabulku" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Přejít na následující tabulku" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Zobrazit seznam tabulek" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Přejít o buňku níž" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Přejít na první buňku tabulky" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Přejít na poslední buňku tabulky" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Přejít o buňku vlevo" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Přejít o buňku vpravo" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Přejít o buňku výš" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Přepnout mezi situačním a objektovým režimem" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Přepnout mezi režimy procházení a zaměřování" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Zapnout přichytávání v režimu zaměřování" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Zapnout přichytávání v režimu procházení" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Přejít na předchozí nenavštívený odkaz" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Přejít na následující nenavštívený odkaz" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Zobrazit seznam nenavštívených odkazů" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Přejít na předchozí navštívený odkaz" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Přejít na následující navštívený odkaz" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Zobrazit seznam navštívených odkazů" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "ledově modrá" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antická bílá" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarínová" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azurová" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "béžová" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "hlinková" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "černá" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "mandlová" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "modrá" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "modro fialová" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "hnědá" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "plavá" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadetská modrošedá" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "čokoládová" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "korálová" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "chrpová" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "kukuřicová" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "karmínová" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "modrozelená" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "tmavá modrá" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "tmavá modrozelená" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "tmavá zlatohnědá" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "tmavá šedá" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "tmavá zelená" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "tmavá khaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "tmavá fuchsiová" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "tmavá olivově zelená" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "tmavá oranžová" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "tmavá orchideová fialová" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "tmavá červená" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "tmavá lososová" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "tmavá mořská zeleň" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "tmavá břidlicově modrá" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "tmavá břidlicově šedá" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "tmavá tyrkysová" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "tmavá fialová" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "sytá růžová" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "sytá blankytně modrá" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "tmavá šedá" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "jasně modrá" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "cihlová" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "emailová bílá" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "lesní zeleň" - -# fuchsia a magenta jsou synonyma pro stejnou barvu FFOOFF, pro nedostatek -# českých výrazů jsou oba výrazy přeloženy stejně -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsiová" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "našedlá" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "mlhavá bílá" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "zlatá" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "zlatohnědá" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "šedá" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "zelená" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "zeleno žlutá" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "medová" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "křiklavě růžová" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indiánská červená" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigová" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "slonová kost" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "levandulová" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "levandulově ruměná" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "trávově zelená" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "bledá citrónová" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "světlá modrá" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "světlá korálová" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "světlá modrozelená" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "světlá zlatožlutá" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "světlá šedá" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "světlá zelená" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "světlá růžová" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "světlá lososová" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "světlá mořská zeleň" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "světlá blankytně modrá" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "světlá břidlicově šedá" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "světlá ocelově modrá" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "světlá žlutá" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limetková" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limetkově zelená" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "režná" - -# fuchsia a magenta jsou synonyma pro stejnou barvu FFOOFF, pro nedostatek -# českých výrazů jsou oba výrazy přeloženy stejně -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "fuchsiová" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "vínová" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "střední akvamarínová" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "střední modrá" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "střední orchideová fialová" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "střední purpurová" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "střední mořská zeleň" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "střední břidlicově modrá" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "střední jarní zeleň" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "střední tyrkysová" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "fialovočervená" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "půlnoční modř" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "peprmintová" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "bledá červená" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokasínová" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "bledě oranžová" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "námořnická modř" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "tělová" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olivová" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "olivově šedá" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oranžová" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "oranžovo červená" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchideová fialová" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "bledá zlatohnědá" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "bledá zelená" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "bledá tyrkysová" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "starorůžová" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "krémová" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "broskvová" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "velbloudí hnědá" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "růžová" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "švestková" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "bledá modrá" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purpurová" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "červená" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "narůžovělá hnědá" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "královská modrá" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "sedlová hnědá" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "lososová" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "pískově hnědá" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "mořská zeleň" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "lasturová" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "siena" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "stříbřitá" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "blankytně modrá" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "břidlicově modrá" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "břidlicově šedá" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "sněhově bílá" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "jarní zeleň" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "ocelově modrá" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "usňová" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "kachní modř" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "bodláková" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "rajčatová" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "tyrkysová" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "fialová" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "obilná" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "bílá" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "kouřově bílá" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "žlutá" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "žluto zelená" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktivovat" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatický režim zaměřování při strukturální navigaci" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatický režim zaměřování při kurzorové navigaci" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatický režim zaměřování při nativní navigaci" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Bod _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Bod _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "_Body 7 a 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Zrušit" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Skočit na" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Budiž" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "ikona" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "nic" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "říct" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Oznámit, když _kamarád píše" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Poskytnout historii zpráv z konkrétní _místnosti" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Číst zprávy od" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Všech_ny kanály" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Všechn_y kanály, když je aktivní některé okno %s" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Pou_ze kanál, jehož okno je aktivní" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "Čí_st název diskuzní místnosti" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Zapne režim rozvržení pro obsah" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dvojité kliknutí" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trojité kliknutí" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Výchozí hlasový výstup" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Skutečný řetězec" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Nahradit řetězcem" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Oznamovat _znaky" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Oznamovat _diakritické klávesy" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Aktuálního místa" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimální délka nalezeného textu:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Možnosti vyhledávání" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "V průběhu vyhledává_ní číst jen změněné řádky" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Číst výs_ledky v průběhu vyhledávání" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Příkaz" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Klávesová zkratka" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Výchozí" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Režim učení" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Činnosti" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braillské klávesové zkratky" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Záložky" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Datum a čas" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Zkoumání myší" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Ovládání objektu" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Podrobnosti o objektu" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Nepoužito" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Plošný náhled" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Řeč a upovídanost" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Obsah plošného náhledu" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Změněno" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Stolní počítač" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Oznámení" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Přijato" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Prezentátor oznámení" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Předvolby Cthulhu pro %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Označit na braillském řádku" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Prezentovat kromě" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Říci" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Konflikt ukládání profilu jako" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Konflikt uživatelského profilu!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profil %s již existuje.\n" -"Pokračovat v aktualizaci stávajícího profilu s těmito novými změnami?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Načtení uživatelského profilu" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Hodláte změnit aktivní profil. Pokud jste teď udělali nějaké\n" -"změny ve svých předvolbách, budou při načtení profilu\n" -"zahozeny.\n" -"\n" -"Pokračovat v načítání profilu a zahození předchozích změn?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Uložení profilu jako" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Název _profilu:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Odstranění uživatelského profilu" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Chystáte se odstranit profil %s. Všechna neuložená nastavení a nastavení " -"uložená v tomto profilu budou ztracena. Chcete pokračovat a odstranit tento " -"profil a všechna související nastavení?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Všechny" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplikace" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Okno" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "Žád_ná" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Ně_která" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Většina" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Řádcích" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Větách" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Citace" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Tlačítko" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Titulek" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Zaškrtávací políčko" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Kliknutelný" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Rozbalovací seznam" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Popis" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Nadpis" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "je vloženo mezi" - -# fuchsia a magenta jsou synonyma pro stejnou barvu FFOOFF, pro nedostatek -# českých výrazů jsou oba výrazy přeloženy stejně -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Obrázek" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Popisek" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Záchytný bod" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Úroveň" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Odkaz" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Seznam" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Položka seznamu" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekt" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Odstavec" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Skupinový přepínač" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Účel" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Vybraná položka" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stav" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Hodnota" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Citace" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Tlačítka" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Zaškrtávací políčka" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Kliknutelné" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Rozbalovací seznamy" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Položky" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Pole formuláře" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Nadpisy" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "je vloženo mezi" - -# fuchsia a magenta jsou synonyma pro stejnou barvu FFOOFF, pro nedostatek -# českých výrazů jsou oba výrazy přeloženy stejně -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Obrázky" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Nadpisy úrovně %d." - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Záchytné body" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Velké objekty" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Odkazy" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Seznamy" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Položky seznamu" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Odstavce" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Skupinové přepínače" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabulky" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Nenavštívené odkazy" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Navštívené odkazy" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Pohyb po stránce" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Auto_maticky číst stránku po jejím prvním načtení" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Prezentovat souhrnné informace o stránce po jejím prvním načtení" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Rozdělovat projev na části pa_uzami" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "výchozí hlas %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Výchozí" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Odkaz" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Systém" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Velká písmena" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Dispečer hlasového výstupu" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Kontrola pravopisu" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "H_láskovat chyby" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Hlá_skovat doporučení" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Prezentovat _kontext chyby" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Číst souřadnice buněk v sešitě" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Vždy číst rozsah vybraných buněk v sešitě" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "O_znamovat záhlaví buňky" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigace v tabulce" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Přeskakovat prázdné _buňky" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Číst _buňku" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Čís_t souřadnice buňky" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Číst _sloučené buňky" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Název vlastnosti" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Ovládat pohyb kurzoru" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Povolit _strukturovanou navigaci" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Zvukový _motiv:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Zvukový motiv" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Stručný" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d oznámení" -msgstr[1] "%d oznámení" -msgstr[2] "%d oznámení" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "levý Shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "levý Alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "levý Control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "pravý Shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "pravý AltGR" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "pravý Control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "Levý alt" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "Pravý alt" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "levý tabulátor" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "enter" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "nahoru" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "dolů" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "vlevo" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "vpravo" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "levý Super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "pravý Super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "Menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "nápověda" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "více" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "přepínač režimu" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "stříška" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "kroužek" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "přeškrtnutí" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "mínus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "AltG_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s tučně" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s kurzívou" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s tučně kurzívou" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s indexem" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s tučným indexem" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s frakturou" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s s dvojitým obrysem" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s tučnou frakturou" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s bezpatkové" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s tučně bezpatkové" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s kurzívou bezpatkové" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s tučně kurzívou bezpatkové" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s s pevnou šířkou" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s bez tečky" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "šipka vlevo" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "šipka nahoru" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "šipka vpravo" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "šipka dolů" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "šipka vlevo-vpravo" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "šipka nahoru-dolů" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "šipka vlevo nahoru" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "šipka vpravo nahoru" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "šipka vpravo dolů" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "šipka vlevo od zarážky" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "šipka nahoru od zarážky" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "šipka vpravo od zarážky" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "šipka dolů od zarážky" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dvojitá šipka vlevo" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dvojitá šipka nahoru" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "jestliže" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dvojitá šipka dolů" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "když a jen když" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dvojitá šipka nahoru-dolů" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dvojitá šipka vlevo nahoru" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dvojitá šipka vpravo nahoru" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dvojitá šipka vpravo dolů" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dvojitá šipka vlevo dolů" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "šipka ukazující vpravo" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "hrot šipky ukazující vpravo" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "mínus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "je menší než" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "je větší než" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "stříška" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "kulatý háček" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "tečka" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "rovnoběžné s" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "tři tečky" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "pro každé" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "doplněk" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "parciální derivace" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "existuje" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "neexistuje" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "prázdná množina" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "přírůstek" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "je prvkem" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "není prvkem" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "malé je prvkem" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "obsahuje jako člen" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "neobsahuje jako člen" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "malé obsahuje jako člen" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "konec důkazu" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "součin" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "vedlejší součin" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "součet" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "plus mínus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus s tečkou" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "dělící lomítko" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "množinové mínus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "hvězdičkový operátor" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "kroužkový operátor" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "tečkový operátor" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "druhá odmocnina" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "třetí odmocnina" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "čtvrtá odmocnina" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "je úměrné" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "nekonečno" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "pravý úhel" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "úhel" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "měřený úhel" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sférický úhel" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "dělí" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "nedělí" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "je rovnoběžné" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "není rovnoběžné" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "a" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "nebo" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "průnik" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "sjednocení" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integrál" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dvojitý integrál" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "trojitý integrál" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "křivkový integrál" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "plošný integrál" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "objemový integrál" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integrál po směru hodinových ručiček" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integrál pro křivce orientované po směru hodinových ručiček" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integrál pro křivce orientované proti směru hodinových ručiček" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "proto" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "protože" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "ku" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "v poměru ku" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "mínus s tečkou" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "převyšuje" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "v geometrickém poměru ku" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "stejnolehlé s" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "je úměrné" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "obrácená tilda" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "obrácené líné S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusovka" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "svislá vlnovka" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "není úměrné" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "mínus vlnovka" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "je asymptoticky ekvivalentní" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "není asymptoticky ekvivalentní" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "je přibližně rovno" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "je přibližně, ale ne úplně přesně " - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "není ani přibližně ani úplně přesně" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "je téměř rovno" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "není téměr rovno" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "je téměr rovno nebo rovno" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "trojitá vlnovka" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "vše je rovno" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "je ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "je geometricky ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "rozdíl oproti" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "blíží se limitu" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "je geometricky rovno" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "je přibližně rovno nebo je obrazem" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "je obrazem nebo je přibližně rovno" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dvojtečka rovná se" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "rovná se dvojtečka" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "kroužek v rovná se" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "s kroužkem rovno" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "odpovídá" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "se odhaduje" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "má shodné úhly s" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "s hvězdičkou rovno" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "s deltou rovno" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "je podle definice rovno" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "měřeno podle" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "s otazníkem rovno" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "není rovno" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "je identické k" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "není identické k" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "je přesně ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "je menší nebo rovno" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "je větší nebo rovno" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "je menší nebo rovno" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "je větší nebo rovno" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "je menší a přitom není rovno" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "je větší a přitom není rovno" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "je mnohem menší" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "je mnohem větší" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "v rozmezí" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "není ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "není menší než" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "není větší než" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "není menší nebo rovno než" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "není větší nebo rovno než" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "je menší nebo ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "je větší nebo ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "není ani menší ani ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "není ani větší ani ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "je menší nebo větší než" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "je větší nebo menší než" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "není menší nebo větší než" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "není větší nebo menší než" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "je předchůdce" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "je následovník" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "je předchůdce nebo rovno" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "je následovník nebo rovno" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "je předchůdce nebo ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "je následovník nebo ekvivalentní k" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "není předchůdce" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "není následovník" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "je podmnožinou" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "je nadmnožinou" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "není podmnožinou" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "není nadmnožinou" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "je podmnožina nebo rovno" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "je nadmnožina nebo rovno" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "není podmnožina nebo rovno" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "není nadmnožina nebo rovno" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "je podmnožina a není rovno" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "je nadmnožina a není rovno" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multimnožina" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "násobení multimnožin" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "sjednocení multimnožin" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "je čtvercovým obrazem" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "je čtvercovým originálem" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "je čtvercovým obrazem nebo je rovno" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "je čtvercovým originálem nebo je rovno" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "čtvercová čepička" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "čtvercový šálek" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "logický součet" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "mínus v kroužku" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "krát v kroužku" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "lomítko v kroužku" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "tečkový operátor v kroužku" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "kruhový operátor v kroužku" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "logický součin" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "rovnítko v kroužku" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "spojovník v kroužku" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus ve čtverečku" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "mínus ve čtverečku" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "krát ve čtverečku" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "tečkový operátor ve čtverečku" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "připojeno zprava" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "připojeno zleva" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "připojeno zdola" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "připojeno shora" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "tvrzení" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modely" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "je pravda" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "vynucuje" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "trojitá svislá čára se vstupem vpravo" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dvojitá svislá čára s dvojitým vstupem vpravo" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "nedokazuje" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "není pravda" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "nevynucuje" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "negovaná dvojitá svislá čára s dvojitým vstupem vpravo" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "předchází ve vztahu" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "následuje ve vztahu" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "je normální podgrupa grupy" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "obsahuje jako normální podgrupu" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "je normální podgrupa nebo rovna" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "obsahuje jako normální podgrupu nebo je rovno" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "je originálem" - -# fuchsia a magenta jsou synonyma pro stejnou barvu FFOOFF, pro nedostatek -# českých výrazů jsou oba výrazy přeloženy stejně -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "je obrazem" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitovská transpozice matice" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "je vloženo mezi" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "exkluzivní disjunkce" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "pravý úhel s obloučkem" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "pravoúhlý trojúhelník" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "kosočtvercový operátor" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "tečkový operátor" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "hvězdičkový operátor" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "děleno krát" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "mašle" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "levý normální faktor polopřímého součinu" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "pravý normální faktor polopřímého součinu" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "levý polopřímý součin" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "pravý polopřímý součin" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "obrácená vlnovka rovno" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "zakřivené logické nebo" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "zakřivené logické a" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dvojitá podmnožina" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dvojitá nadmnožina" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dvojitý průnik" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dvojité sjednocení" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "vidle" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "je rovno nebo paralelní k" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "menší než s tečkou" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "větší než s tečkou" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "je mnohem nenší než" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "je mnohem větší než" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "je menší nebo rovno nebo větší než" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "je větší nebo rovno nebo menší než" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "je rovno nebo menší než" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "je rovno nebo větší než" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "je rovno nebo předchůdce" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "je rovno nebo následovník" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "není předchůdce nebo rovno" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "není následovník nebo rovno" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "není čtvercovým obrazem nebo je rovno" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "není čtvercovým originálem nebo je rovno" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "je čtvercovým obrazem nebo není rovno" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "je čtvercovým originálem nebo není rovno" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "je menší, ale není ekvivalentní" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "je větší, ale není ekvivalentní" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "je předchůdce, ale není ekvivalentní" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "je následovník, ale není ekvivalentní" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "není normální podgrupa grupy" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "neobsahuje jako normální podgrupu" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "není normální podgrupa nebo není rovna" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "neobsahuje jako normální podgrupu nebo není rovna" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "svislý výpustek" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "vodorovný výpustek uprostřed" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "úhlopříčný výpustek doprava nahoru" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "úhlopříčný výpustek doprava dolů" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "je prvkem s dlouhým vodorovným přeškrtnutím" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "je prvkem se svislou čárou na konci vodorovného přeškrtnutí" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "malé je prvkem se svislou čárou na konci vodorovného přeškrtnutí" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "je prvkem s tečkou nad" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "je prvkem s čárou nad" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "malé je prvkem s čárou nad" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "je prvkem s čárou pod" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "je prvkem s dvojitým vodorovným přeškrtnutím" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "obsahuje s dlouhým vodorovným přeškrtnutím" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "obsahuje se svislou čárou na konci vodorovného přeškrtnutí" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "malé obsahuje se svislou čárou na konci vodorovného přeškrtnutí" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "obsahuje s čárou nad" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "malé obsahuje s čárou nad" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z-notace" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "levý strop" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "pravý strop" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "levé dno" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "pravé dno" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "horní složená závorka" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "dolní složená závorka" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "levá lomená závorka" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "pravá lomená závorka" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "tečka v kroužku" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "sjednocení s tečkou s" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "sjednocení s plus s" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "hranatý průnik" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "hranaté sjednocení" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "černý čtvereček" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "bílý čtvereček" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "černý kosočtverec" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "bílý kruh" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "černý kruh" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bílá odrážka" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "středně velký černý čtvereček" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "podtržené %s" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "přeškrtnuté %s" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "svisle přeškrtnuté %s" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplikace" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "prázdný" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "tučné" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "vstup na záložku" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "záložky uloženy" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "není možno uložit záložky" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nebyly nalezeny žádné záložky." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Záložka nebyla nalezena." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Režim obcházení zapnut." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Nelze přistupovat k displeji kalkulačky" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Styl čtení velkých písmen je nastaven na ikona." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "nic" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Styl čtení velkých písmen je nastaven na nic." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "říct" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Styl čtení velkých písmen je nastaven na říct." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Pohyb kurzoru ovládá aplikace." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu ovládá kurzor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Buňka %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "vybrána buňka %s" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "vybrány buňky %s až %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "zrušen výběr buňek %s až %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "zrušen výběr buňky %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Zamezit použití volby" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Donutit k použití volby" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "VOLBA" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Volitelné argumenty" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Použití:" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Následující není platné: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Vypsat podporované běžící aplikace" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Načtení profilu" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profil není možno nahrát: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Nelze spustit Cthulhu, protože se nemůže připojit k pracovní ploše.Nelze " -"spustit čtečku obrazovky, protože není možné se napojit na prostředí " -"pracovní plochy" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Nelze aktivovat správu nastavení. Končí se." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"V tomto sezení již běží jiný proces čtečky obrazovky.\n" -"Spuštěním příkazu „cthulhu --replace“ tento proces nahradíte novým." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NÁZEV" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Použít alternativní adresář s uživatelskými předvolbami" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "ADRESÁŘ" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Verze této aplikace" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Nahradit aktuálně spuštěnou instanci Cthulhu" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Zobrazit tuto nápovědu a skončit" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Posílat výstup ladění do debug-RRRR-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Posílat výstup ladění do určeného souboru" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "SOUBOR" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Nastavit uživatelské předvolby (textová verze)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Nastavit uživatelské předvolby (grafická verze)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Chyby hlašte na https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Výběr byl vyjmut do schránky." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "vyjmuto" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Výběr byl zkopírován do schránky." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "zkopírováno" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Obsah schránky byl vložen." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "vloženo" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Neoznamovat, když kamarád píše." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "oznámit, když kamarád píše." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Rychlá zpráva z diskuzní místnosti %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nová karta diskuze - %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Načíst názvy diskuzních místností." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "číst název diskuzní místnosti." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Neposkytovat historii zvláštních zpráv zobrazených v místnosti" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Poskytuje historii zvláštních zpráv zobrazených v místnosti." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "začátek smazaného" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "konec smazaného" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "začátek vloženého" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "konec vloženého" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "začátek zvýrazněného" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "konec zvýrazněného" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "konec doporuční" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Konec kontejneru." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Není v kontejneru." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "vybrány všechy položky" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Výchozí tlačítko je %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Výchozí tlačítko je %s. Zašedlé" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Výchozí tlačítko nebylo nalezeno" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " dolní index %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " horní index %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Není v dialogovém okně" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "vybrán celý dokument" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "zrušen výběr celého dokumentu" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "vybráno od pozice kurzoru" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "zrušen výběr od pozice kurzoru" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "vybráno po pozici kurzoru" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "zrušen výběr po pozici kurzoru" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynamické záhlaví sloupce nastaveno na řádek %d." - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynamické záhlaví slupce vymazáno." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynamické záhlaví řádku nastaveno na sloupec %s." - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynamické záhlaví řádku vymazáno." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "prázdný" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobajtů" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabajtů" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Žádný soubor nenalezen" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Obsah přidán do schránky." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Obsah zkopírován do schránky." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Nepoužívá se plošný náhled." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Zapíná se plošný náhled." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Opouští se plošný náhled." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Přesunout plošný náhled na slovo nad aktuálním slovem" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Plochý přehled neomezený" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "obsahuje vzorec" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "otevře dialogové okno" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "otevře mřížku" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "otevře seznam" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "otevře nabídku" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "otevře strom" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "odkaz v obrázkové mapě" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Zadaná klávesová zkratka je již přiřazena k %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Klávesová zkratka %s zaznamenána. Pro potvrzení zmáčkněte Enter." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Nová klávesové zkratka je %s." - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Klávesová zkratka vymazána. Zmáčkněte Enter pro potvrzení." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Klávesová zkratka byla odebrána." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "zadejte novou klávesovou zkratku" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "klávesa" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Oznamování je nastavené na klávesu." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "nic" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Oznamování není nastavené na nic." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "klávesa a slovo" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Oznamování je nastavené na klávesu a slovo." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "věta" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Oznamování je nastavené na větu." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "slovo" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Oznamování je nastavené na slovo." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "slovo a věta" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Oznamování je nastavené na slovo a větu." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Uzavřeno: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "aktuárským symbolem" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "obdélníkem" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "kruhem" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "symbolem dlouhého dělení" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "odmocninou" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "zaobleným obdélníkem" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "vodorovným přeškrtnutím" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "svislým přeškrtnutím" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "úhlopříčným přeškrtnutím doprava dolů" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "úhlopříčným přeškrtnutím doprava nahoru" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "severovýchodní šipkou" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "čárou dole" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "čárou vlevo" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "čárou vpravo" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "čárou nahoře" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "fázorovým úhlem" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "arabským symbolem faktoriálu" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "a" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "začátek zlomku" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "začátek nad" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "lomeno" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "konec zlomku" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "druhá odmocnina z" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "třetí odmocnina z" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "mocnina z" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "začátek mocnicny" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "konec mocniny" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "dolní index" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "horní index" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "s předcházejícím dolním indexem" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "s předcházejícím horním indexem" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "výraz v dolním indexu" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "výraz v horním indexu" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "konec tabulky" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "konec vložené tabulky" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "nepřístupné" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Vypnuto" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Čtení odsazení a zarovnání je vypnuté." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Zapnuto" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Čtení odsazení a zarovnání je zapnuté." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Výukový režim. Zmáčknutím Escape jej ukončíte." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Vstupuje se do výukového režimu. Zmáčknutím libovolné klávesy si můžete " -"vyslechnout jeho funkce. Pro zobrazení dokumentace čtečky obrazovky " -"zmáčkněte F1. Pro získání seznamu výchozích klávesových zkratek čtečky " -"obrazovky zmáčkněte F2. Pro získání seznamu klávesových zkratek pro aktuální " -"aplikaci zmáčkněte F3. Výukový režim ukončíte zmáčknutím Esc." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "Opouští se citace." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "Opouští se podrobnosti." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "Opouští se seznam článků." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "Opouští se obrázek." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "Opouští se formulář." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "Opouští se cedule." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "Opouští se doplňkový obsah." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "Opouští se informace." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "Opouští se hlavní obsah." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "Opouští se navigace." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "Opouští se oblast." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "Opouští se hledání." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "Opouští se seznam." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "Opouští se panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "Opouští se tabulka." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "Opouští se vysvětlivka." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "Opouští se výtah." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "Opouští se poděkování." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "Opouští se dovětek." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "Opouští se dodatek." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "Opouští se odkazy." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "Opouští se kapitola." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "Opouští se tiráž." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "Opouští se závěr." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "Opouští se zdroj." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "Opouští se zdroje." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "Opouští se věnování." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "Opouští se závěrečné poznámky." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "Opouští se moto." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "Opouští se doslov." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "Opouští se opravy chyb." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "Opouští se příklad." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "Opouští se úvodní slovo." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "Opouští se slovníček." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "Opouští se rejstřík." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "Opouští se úvod." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "Opouští se seznam stránek." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "Opouští se část." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "Opouští se předmluva." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "Opouští se předehra." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "Opouští se upoutávka." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "Opouští se otázky a odpovědi." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "Opouští se doporučení." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "Opouští se obsah." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "řádka je označena dolů od kurzoru" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "řádka je označena nahoru od kurzoru" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "řádka není označena dolů od kurzoru" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "řádka není označena nahoru od kurzoru" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Vypíná se výukový režim" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "vybrán řádek od začátku k předchozí pozici kurzoru" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "vybrán řádek od předchozí pozice kurzoru do konce" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "odkaz" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "na této stránce" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "na tomto webu" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "na jiné stránce" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "odkaz %(uri)s na %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "odkaz %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "navštívený odkaz %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Použijte šipky nahoru a dolů pro pohyb v seznamu. Zmáčknutím Escape jej " -"vypnete." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Všechny živé oblasti jsou vypnuty" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "úroveň chování živých oblastí obnovena" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "úroveň chování %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "nastavení živé oblasti na důraznou" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "nastavení živé oblasti na vypnuto" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "nastavení živé oblasti na slušnou" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "nastavení živé oblast na hrubou" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Sledování živých oblastí je vypnuto" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Sledování živých oblastí je zapnuto" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "žádné aktivní zprávy nebyly uloženy" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Podpora živých oblastí je vypnuta" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nenalezeno" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Nelze nalézt aktuální umístění." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "vypnuto" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "zapnuto" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "překlep" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Nesprávně napsané slovo: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Kontext je %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Režim procházení" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Režim zaměřování" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Pro zapnutí režimu zaměřování zmáčkněte %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Režim zaměřování je přichytávací." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Režim procházení je přichytávací." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Situační režim." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objektový režim." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Ukazatel přesunut na objekt." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Nenalezen objekt pod kurzorem myši." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Zkoumání myší je zakázáno." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Zkoumání myší je povoleno." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Chyba: Nelze vytvořit seznam objektů." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Žádní potomci." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Žádné následující." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d procento." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Žádné předchozí." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Zjednodušená navigace zapnuta." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Zjednodušená navigace vypnuta." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Vnořená úroveň %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Byla přidána nová položka" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Žádné činnosti nebyly nalezeny na: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Nic není aktivní" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Žádná aplikace není aktivní." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Žádné další citace." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Žádná další tlačítka." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Žádné další zaškrtávací pole." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Žádné další velké objekty." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Žádný další kliknutelný." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Žádné další rozbalovací seznamy." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Žádné další vstupy." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Formulář nemá žádné další prvky." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Žádné další nadpisy." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Žádné další nadpisy úrovně %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Žádná další tabulka." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Žádná další obrázky." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Žádné záchytné body." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Žádné další odkazy." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Žádné další seznamy." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Žádné další položky seznamu." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Žádné další živé oblasti." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Žádné další odstavce." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Žádné další skupinové přepínače." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Žádné další oddělovače." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Žádná další tabulka." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Žádné další nenavštívené odkazy." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Žádné další navštívené odkazy." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Není vybrán žádný text." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nejedná se o odkaz." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Oznámení" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Konec" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Vrchol" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Žádné upozornění" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "číslice" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Číst čísla po číslicích." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "slova" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Číst čísla jako jedno slovo." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "vypnuto" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "zapnuto" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Načítá se, čekejte prosím." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Načítání dokončeno." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Dokončeno načítání %s" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Stránka má %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "vybrána strana od pozice kurzoru" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "vybrána strana po pozici kurzoru" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "zrušen výběr strany od pozice kurzoru" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "zrušen výběr strany po pozici kurzoru" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "vybrán odstavec dolů od pozice kurzoru" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "vybrán odstavec nahoru od pozice kurzoru" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "zrušen výběr odstavce dolů od pozice kurzoru" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "zrušen výběr odstavce nahoru od pozice kurzoru" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Dialogové okno s předvolbami programu Cthulhu je již otevřené.\n" -"Nejdříve jej prosím zavřete, chcete-li otevřít nové." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "promítaný snímek %(position)d z %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil nastavit na %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nenalezeny žádné profily." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Ukazatel průběhu ukazuje %d" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Všechna" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Úroveň interpunkce je nastavená na všechna." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Většinu" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Úroveň interpunkce je nastavená na většinu." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Žádná" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Úroveň interpunkce je nastavená na žádná." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Některá" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Úroveň interpunkce je nastavená na některá." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Hledá se" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Hledání dokončeno" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Nastavení Cthulhu byla znovu načtena." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Vybraný text je: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Výběr byl smazán." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Výběr byl obnoven." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Výběr textu byl zrušen." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Velikost: %d, %d. Pozice: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Šířka: %d. Výška: %d. %d zleva. %d shora." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Čtení vypnuto" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Čtení zapnuto" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "rychleji." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "pomaleji." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "vyšším tónem." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "hlubším tónem." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "hlasitěji." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "tišeji." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Rychlost %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Výška %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Hlasitost %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Modul Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Hlas Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nejsou k dispozici žádné moduly Speech-dispatcher" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nejsou k dispozici žádné hlasy Speech-dispatcher" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Nastavení řeči uloženo" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Nastavení řeči nelze uložit" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Úroveň upovídanosti: stručně" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Úroveň upovídanosti: podrobně" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " tři tečky" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu vás vítá." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu číhá pod vlnami." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Režim spánku povolen pro %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Režim spánku vypnut pro %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Hlasový výstup je nedostupný!" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Nenalezen" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Stavová lišta nebyla nalezena" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "Řetězec nebyl nalezen" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Strukturální navigace vypnuta." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Strukturální navigace zapnuta." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nenalezeno" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Řádek %(row)d, sloupec %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Konec tabulky" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Číst buňku" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Číst řádek" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Nepravidelná" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Není v tabulce" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Změnilo se pořadí sloupců" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Změnilo se pořadí řádků" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "sloupec %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "sloupec %(index)d z %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Spodek sloupce" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Vrchol sloupce." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Vybrán sloupec %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Vybrány sloupce %s až %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Zrušen výběr sloupců %s až %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Zrušen výběr slupce %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "řádek %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "řádek %(index)d z %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Začátek řádku" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Konec řádku" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Řádek smazán." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Poslední řádek smazán." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Řádek vložen." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Řádek vložen na konec tabulky." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Vybrán řádek %s" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Vybrány řádky %s až %s" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Zrušen výběr řádků %s až %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Zrušen výběr řádku %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "vybráno" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "zrušen výběr" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H hodin, %M minut a %S sekund" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H hodin a %M minut" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "%s v tabulce Unicode" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "vráceno zpět" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "provedeno znovu" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu verze %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "prázdné místo" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Vrací se dolů." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Vrací se nahoru." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 položek" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Buňka obsazuje %d řádek" -msgstr[1] "Buňka obsazuje %d řádky" -msgstr[2] "Buňka obsazuje %d řádků" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d sloupec" -msgstr[1] "%d sloupce" -msgstr[2] "%d sloupců" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Buňka obsazuje %d sloupec" -msgstr[1] "Buňka obsazuje %d sloupce" -msgstr[2] "Buňka obsazuje %d sloupců" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d znak je příliš dlouhý" -msgstr[1] "%d znaky jsou příliš dlouhé" -msgstr[2] "%d znaků je příliš dlouhých" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d okno)" -msgstr[1] "(%d okna)" -msgstr[2] "(%d oken)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d nezaměřený dialog" -msgstr[1] "%d nezaměřené dialogy" -msgstr[2] "%d nezaměřených dialogů" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bajt" -msgstr[1] "%d bajty" -msgstr[2] "%d bajtů" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Nalezen %d soubor" -msgstr[1] "Nalezeny %d soubory" -msgstr[2] "Nalezeno %d souborů" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulář" -msgstr[1] "%d formuláře" -msgstr[2] "%d formulářů" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d nadpis" -msgstr[1] "%d nadpisy" -msgstr[2] "%d nadpisů" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d položka" -msgstr[1] "%d položky" -msgstr[2] "%d položek" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d záchytný bod" -msgstr[1] "%d záchytné body" -msgstr[2] "%d záchytných bodů" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "Nalezena %d položka" -msgstr[1] "Nalezeny %d položky" -msgstr[2] "Nalezeno %d položek" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Opouští se %d citace." -msgstr[1] "Opouští se %d citace." -msgstr[2] "Opouští se %d citací." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Opouští se %d seznam." -msgstr[1] "Opouští se %d seznamy." -msgstr[2] "Opouští se %d seznamů." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Seznam o neznámé velikost" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Seznam má %d položku" -msgstr[1] "Seznam má %d položky" -msgstr[2] "Seznam má %d položek" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Seznam článků o neznámé velikosti" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Seznam o %d článku" -msgstr[1] "Seznam o %d článcích" -msgstr[2] "Seznam o %d článcích" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Seznam definic má %d položku" -msgstr[1] "Seznam definic má %d položky" -msgstr[2] "Seznam definic má %d položek" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d hodnota" -msgstr[1] "%d hodnoty" -msgstr[2] "%d hodnot" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "matematická tabulka s %d řádkem" -msgstr[1] "matematická tabulka se %d řádky" -msgstr[2] "matematická tabulka s %d řádky" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d sloupec" -msgstr[1] "%d sloupce" -msgstr[2] "%d sloupců" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "vložená matematická tabulka s %d řádkem" -msgstr[1] "vložená matematická tabulka se %d řádky" -msgstr[2] "vložená matematická tabulka s %d řádky" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d zpráva.\n" -msgstr[1] "%d zprávy.\n" -msgstr[2] "%d zpráv.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d procento." -msgstr[1] "%d procenta." -msgstr[2] "%d procent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "Načteno %d procento dokumentu" -msgstr[1] "Načtena %d procenta dokumentu" -msgstr[2] "Načteno %d procent dokumentu" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixely" -msgstr[2] "%d pixelů" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d znak %(repeatChar)s" -msgstr[1] "%(count)d znaky %(repeatChar)s" -msgstr[2] "%(count)d znaků %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "vybrána %(index)d z celkem %(total)d položky" -msgstr[1] "vybráno %(index)d ze %(total)d položek" -msgstr[2] "vybráno %(index)d z %(total)d položek" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Nalezena %d výchozí klávesová zkratka čtečky obrazovky." -msgstr[1] "Nalezeny %d výchozí klávesové zkratky čtečky obrazovky." -msgstr[2] "Nalezeno %d výchozích klávesových zkratek čtečky obrazovky." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Nalezena %(count)d klávesová zkratka čtečky obrazovky pro aplikaci " -"%(application)s." -msgstr[1] "" -"Nalezeny %(count)d klávesové zkratky čtečky obrazovky pro aplikaci " -"%(application)s." -msgstr[2] "" -"Nalezeno %(count)d klávesových zkratek čtečky obrazovky pro aplikaci " -"%(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d mezera" -msgstr[1] "%d mezery" -msgstr[2] "%d mezer" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulátor" -msgstr[1] "%d tabulátory" -msgstr[2] "%d tabulátorů" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabulka" -msgstr[1] "%d tabulky" -msgstr[2] "%d tabulek" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabulka o neznámé velikosti" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabulka o %d sloupci a neznámém počtu řádků" -msgstr[1] "tabulka o %d sloupcích a neznámém počtu řádků" -msgstr[2] "tabulka o %d sloupcích a neznámém počtu řádků" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabulka o %d řádku a nezném počtu sloupců" -msgstr[1] "tabulka o %d řádcích a nezném počtu sloupců" -msgstr[2] "tabulka o %d řádcích a nezném počtu sloupců" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabulka o %d řádku" -msgstr[1] "tabulka o %d řádcích" -msgstr[2] "tabulka o %d řádcích" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "před %d sekundou" -msgstr[1] "před %d sekundami" -msgstr[2] "před %d sekundami" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "před %d minutou" -msgstr[1] "před %d minutami" -msgstr[2] "před %d minutami" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "před %d hodinou" -msgstr[1] "před %d hodinami" -msgstr[2] "před %d hodinami" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "před %d dnem" -msgstr[1] "před %d dny" -msgstr[2] "před %d dny" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d nenavštívený odkaz" -msgstr[1] "%d nenavštívené odkazy" -msgstr[2] "%d nenavštívených odkazů" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d navštívený odkaz" -msgstr[1] "%d navštívené odkazy" -msgstr[2] "%d navštívených odkazů" - -# There is no 'toggle' string in gail package -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "přepnout" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "položka %(index)d z %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "položka %(index)d z %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "položka %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "ÚROVEŇ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "úroveň stromu %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "ÚROVEŇ STROMU %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "podrobnosti pro %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "má podrobnosti v %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "doporučení" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "upravitelný rozbalovací seznam" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "upravitelný obsah" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "seznam článků" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "obrázek" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "výtah" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "poděkování" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "dovětek" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "dodatek" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "odkaz" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "odkazy" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "kapitola" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "tiráž" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "závěr" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "desky" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "zdroj" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "zdroje" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "věnování" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "závěrečná poznámka" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "závěrečné poznámky" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "moto" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "doslov" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "opravy chyb" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "příklad" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "úvodní slovo" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "slovníček" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "rejstřík" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "úvod" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "zalomení stránky" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "seznam stránek" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "část" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "předmluva" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "předehra" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "upoutávka" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "otázky a odpovědi" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "podnadpis" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "obsah" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s úrovně %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "vodorovný posuvník" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "svislý posuvník" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "vodorovné táhlo" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "svislé táhlo" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "vodorovné rozdělení" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "svislé rozdělení" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "přepínač" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Lišta ikon" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "cedule" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "doplňkový obsah" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informace" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "hlavní obsah" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "ovládání" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "oblast" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "hledání" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "navštívený odkaz" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "tlačítko s nabídkou" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "seřazeno vzestupně" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "seřazeno sestupně" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "seřazeno" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "kliknutelný" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "sbaleno" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "rozbaleno" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "má dlouhý popis" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "vodorovně" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "svisle" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "zaškrtnuto" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nezaškrtnuto" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "zapnuto" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "vypnuto" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "částečně zaškrtnuto" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "zmáčknuto" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "nezmáčknuto" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "nevybrána" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "vybráno" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "nevybráno" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "nevybrána" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "navštíveno" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "nenavštíveno" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "nepřístupné" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "jen ke čtení" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "kčtení" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "vyžadováno" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "vícenásobný výběr" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "neplatný vstup" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "neplatné" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "pravopisná chyba" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "pravopis" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "gramatická chyba" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatika" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Najít" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Čtečky obrazovky – dialogové okno hledání" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Zavřít" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Najít" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Hledat:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Hledat:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Z_ačátek okna" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Začátku okna" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Začít od:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Přecházet přes _konec/začátek" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "H_ledat od konce k začátku" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Směr hledání:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Odpovídat velikostí pís_men" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Odpovídat jako c_elá slova" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Volby:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Výchozí" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Velká písmena" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Odkaz" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Systém" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplikace" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Okno" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Předvolby Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Nápověda" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Použít" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "Pře_nosný počítač" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Rozložení klávesnice" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktivní _profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Počáteční profil:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Načíst" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Uložit j_ako" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "Odst_ranit" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profily" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Prezentovat vysvětlivky" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Oznamovat objekt pod _ukazatelem" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Myš" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Formá_t času:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formát d_ata:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Čas a datum" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Čí_st průběh" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Zobrazovat průběh na _braillském řádku" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Četnost (v sekundách):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Použít na:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Pípat průběh" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Aktualizace ukazatele průběhu" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Povolit přeskakování zpět a vpřed při plynulém čtení" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Povolit _strukturovanou navigaci při plynulém čtení" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Pl_ynulé čtení po:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Při čtení všeho oznamovat _citace" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Při čtení všeho oznamovat _seznamy" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Při čtení všeho oznamovat _tabulky" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Při čtení všeho oznamovat _panely" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Při čtení všeho oznamovat _formuláře" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Při čtení všeho oznamovat záchytné _body" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Plynulé čtení" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Prezentace prvku:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Obecné" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "H_lasitost:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Výš_ka:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Tempo:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "Oso_ba:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Jazyk:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "_Hlasový výstup:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Řečový s_ystém:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Typ _hlasu:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Styl _velkých písmen:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Nastavení typu hlasu" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Číst pospojované slova jako je_dnotlivá" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Číst čís_la jako číslice" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Globální nastavení hlasu" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Hlas" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "P_ovolit čtení" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Výř_ečný" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Výřečnost" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "Vše_chna" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Úroveň interpunkce" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Číst pouze zobrazený text" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Číst prázdné řádky" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Číst od_sazení a zarovnání" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Číst _klávesové zkratky objektů" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Uvádět p_ořadová čísla položek" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Číst výukové zprávy" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Systémové zprávy jsou podrobné" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Číst _barvy jako názvy" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Při pohybu v dokumentu oznamovat _citace" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Při pohybu v dokumentu oznamovat _seznamy" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Při pohybu v dokumentu oznamovat _tabulky" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Ozna_movat označení pravopisně chybných slov" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Při pohybu v dokumentu oznamovat _panely" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Při pohybu v dokumentu oznamovat záchytné _body" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Při pohybu v dokumentu oznamovat _formuláře" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Číst pop_is" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Číst celé řádky tabulek v tabulkových kalkuláto_rech" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Číst celé řádky tabulek v _dokumentech" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Číst celé řádky tabulek v _uživatelském rozhraní" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Kontext čtení" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Řeč" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Zapnout podpo_ru braillských řádků" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Stručné názvy prvků" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Zakázat znak konc_e řádku" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tabulka zkratkopisu:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Zapnout zkratkopis u braillského řádku" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Povolit zalamování podle slo_v" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Nastavení zobrazení" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "Žád_ný" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indikátor výběru" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indikátor odkazu" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Povolit _bleskové zprávy" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "D_oba (v sekundách):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Z_právy jsou trvalé" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Zprávy jsou po_drobné" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Nastavení bleskových zpráv" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braillský řádek" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Oznamovat _klávesy" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Ozn_amovat klávesy s písmeny" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Oz_namovat klávesy s čísly" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Oznamovat klávesy s inter_punkčními znaménky" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Oznamovat _mezerník" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Oznamovat _modifikační klávesy" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Oznamovat _funkční klávesy" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Oznamova_t akční klávesy" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Oznamovat _kurzorové klávesy" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Oznamovat _slova" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Oznamovat _věty" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Oznamování" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "_Modifikační klávesy čtečky obrazovky:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Klávesové zkratky" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Slovník výslovnosti" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Nová po_ložka" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Vymazat" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Výslovnost" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Čí_st vše" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Nečíst nic" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "O_bnovit" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Vlastnosti textu" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "_Posunout úplně dolů" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Posunout o je_dno níž" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Pos_unout o jedno výš" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Posunou_t úplně nahoru" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Upravit vybranou vlastnost" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indikátor braillského řádku" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Vlastnosti textu" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Povolit AI asistenta" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Poskytovatel:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Místní - Zdarma)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Soubor _klíče API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Cesta k souboru klíče API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Získat _klíč API Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Otevřít prohlížeč pro získání klíče API Claude a automatické uložení" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Vyžadovat potvrzení před akcemi AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Model Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Název modelu pro Ollama (např. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Koncový bod Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL koncového bodu API Ollama (např. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Kvalita snímku obrazovky:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Nízká" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Střední" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Vysoká" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI asistent" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Kód _jazyka:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Faktor _měřítka:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Obraz ve stupních _šedi" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Invertovat obraz" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Černobílý obraz" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Práh černo-bílé:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analyzovat barvy" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Zkopírovat výsledky do _schránky" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : adam, b : božena, c : cyril, d : david, e : ema, f : františek, g : " -"gustav, h : hanka, i : irena, j : jiřina, k : kačka, l : lenka, m : martin, " -"n : norbert, o : otakar, p : pavel, r : radek, q : kvído, s : stanislav, t : " -"tomáš, v : vojtěch, w : waldemar, x : iks, y : ypsilon, z : zuzana, ě : e s " -"háčkem, š : šimon, č : čeněk, ř : řehole, ž : žito" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "barva pozadí" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "výška zbarvení pozadí" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "tupování barvou pozadí" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "orientace" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "upravitelnost" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "název rodiny písma" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "barva popředí" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "tupování barvou popředí" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efekt písma" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "odsazení" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "omyl" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "neviditelný" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "zarovnání" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "jazyk" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "levý okraj" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "výška řádky" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "styl odstavce" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixelů nad řádkou" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixelů pod řádkou" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixelů uvnitř zalomení" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "pravý okraj" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "zdvih" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "zvětšení" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "velikost" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "šířka" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "přeškrtnutí" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "styl" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "dekorace textu" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "otočení textu" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "stínování textu" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "podtržení" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "varianta" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "zarovnání na výšku" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "tloušťka" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "režim zalamování" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "režim zápisu" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "pravda" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "nepravda" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "žádný" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "rytina" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "reliéf" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "obrys" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "čára nad" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "přeškrtnuté" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "blikající" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "černé" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "jednoduché" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dvojité" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "pod" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "znak" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "slovo" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "znak slova" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "zleva doprava" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "zprava doleva" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "vlevo" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "vpravo" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "vycentrovat" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "bez zarovnání" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "blok" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "velmi zhuštěné" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "zhuštěnější" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "zhuštěné" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "částečné zhuštěné" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normální" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "částečné roztažené" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "roztažené" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "roztaženější" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "velmi roztažené" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "kapitálky" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "zkosené" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kurzíva" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Výchozí" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Vlastní text" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Nadpis" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "účaří" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "dolní index" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "horní index" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "nahoru" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "horní dotažnice" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "na střed" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "dolů" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "dolní dotažnice" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "zděděné" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lp-hd" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "pl-hd" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "hd-pl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "hd-lp" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "dh-pl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "dh-lp" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lp" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "pl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "hd" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "plné" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "kontrola pravopisu" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Zmáčkněte mezerník pro přepnutí" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Zmáčkněte mezerník pro rozbalení a použijte šipky nahoru a dolů k výběru " -"položky" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Zmáčkněte Alt+F6 pro předání zaměření podřízenému oknu." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Pokud se chcete na nějakou položku přesunout, použijte kurzorové klávesy se " -"šipkami nebo začněte psát název." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Pokud chcete zobrazit nabídku, zmáčkněte Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Použijte šipky nahoru a dolů k výběru položky." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Sbalíte zmáčknutím Shift a šipky vlevo." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Rozbalíte zmáčknutím Shift a šipky vpravo." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Pokud chcete aktivovat, zmáčkněte enter." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Vepište text." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Použijte šipky vlevo a vpravo pro prohlížení ostatních karet." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Pokud chcete aktivovat, zmáčkněte mezerník." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Použijte šipky nahoru a dolů k výběru hodnoty. Nebo napište požadovanou " -"číselnou hodnotu." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Pokud chcete provést změnu, použijte šipky." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"K navigaci slouží šipky vpravo a vlevo a pro přesun po položkách šipky " -"nahoru a dolů." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Ke vstupu do podnabídky slouží klávesa šipky vpravo." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Šipka vlevo snižuje, šipka vpravo zvyšuje. Minimum nastaví klávesa Home a " -"maximum klávesa End." diff --git a/po/cy.po b/po/cy.po deleted file mode 100644 index 754da64..0000000 --- a/po/cy.po +++ /dev/null @@ -1,9736 +0,0 @@ -# Cthulhu in Welsh. -# This file is distributed under the same license as the Cthulhu package. -# Rhys Jones , 2006. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2006-06-22 22:25-0000\n" -"Last-Translator: Rhys Jones \n" -"Language-Team: Welsh \n" -"Language: cy\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural= (n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != " -"11) ? 2 : 3;\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "Hoffterau Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -#, fuzzy -msgid "anim" -msgstr "animeiddiad" - -#: src/cthulhu/braille_rolenames.py:57 -#, fuzzy -msgid "arw" -msgstr "saeth" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cynf" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "blt" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "dewllw" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "pencol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dydd" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -#, fuzzy -msgid "icn" -msgstr "eicon" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "ffrf" - -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "deial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "ccy" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "tynnu" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "dwffl" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "llnw" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "cwrlgwdr" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "dlwdd" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "cwrlhn" - -#: src/cthulhu/braille_rolenames.py:154 -#, fuzzy -msgid "lnk" -msgstr "cyswllt" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "rhst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "eitmrh" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "dwsl" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "brdwsl" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "eitmddws" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "cwrlops" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "rhstbl" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "cfrnr" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "ndln" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "brcnnd" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btwm" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "eitdwsrdio" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "cwrlgwrdd" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "penrhs" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "brsgrl" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "cwrlsgrl" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "gwhndd" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "llthr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "cwrlhllt" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "trll" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "brstws" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -#, fuzzy -msgid "cll" -msgstr "cell" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "eitdwsrwyg" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "trfnll" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tstn" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "btwmtgl" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "baro" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "cmth" - -#: src/cthulhu/braille_rolenames.py:262 -#, fuzzy -msgid "tre" -msgstr "coeden" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tblcoed" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "anh" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "pthgol" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "ffnst" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "pen" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "trd" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "rha" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "awto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "barg" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "mew" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "bwlch" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "llinell newydd" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "ebychnod" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "dyfynnod" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "rhif" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "doler" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "canran" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "a" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "collnod" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "cromfach chwith" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "cromfach dde" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "seren" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plws" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "coma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "llinell doriad" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "dot" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slaes" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "colon" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semicolon" - -#: src/cthulhu/chnames.py:126 -#, fuzzy -msgid "less" -msgstr "llai na" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "hafalnod" - -#: src/cthulhu/chnames.py:134 -#, fuzzy -msgid "greater" -msgstr "mwy na" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "cwestiwn" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "braced chwith" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "slaes ôl" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "braced dde" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "caret" - -#: src/cthulhu/chnames.py:162 -#, fuzzy -msgid "underline" -msgstr "llinell newydd" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "bres chwith" - -#: src/cthulhu/chnames.py:174 -#, fuzzy -msgid "vertical bar" -msgstr "llinell fertigol" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "brês dde" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "Gweithfan " - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -#, fuzzy -msgid "cents" -msgstr "canran" - -#: src/cthulhu/chnames.py:199 -#, fuzzy -msgid "pounds" -msgstr "punt" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -#, fuzzy -msgid "broken bar" -msgstr "bar dewis" - -#: src/cthulhu/chnames.py:215 -#, fuzzy -msgid "section" -msgstr "cwestiwn" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "braced chwith" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -#, fuzzy -msgid "registered" -msgstr "Canolwyd" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -#, fuzzy -msgid "mu" -msgstr "dwsl" - -#: src/cthulhu/chnames.py:275 -#, fuzzy -msgid "paragraph marker" -msgstr "paragraff" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "Terfynell" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "braced dde" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -#, fuzzy -msgid "a tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -#, fuzzy -msgid "n tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -#, fuzzy -msgid "o tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -#, fuzzy -msgid "o stroke" -msgstr "collnod" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "llinell doriad" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "shift dde" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -#, fuzzy -msgid "per mille" -msgstr "Braille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -#, fuzzy -msgid "check mark" -msgstr "dewislen dicio" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "cromfach chwith" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "cromfach dde" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "cromfach chwith" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "cromfach dde" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "Yn gwneud clic chwith ar yr eitem adolygu gwastad cyfredol." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "Yn gwneud clic de ar yr eitem adolygu gwastad cyfredol." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Llefaru'r ddogfen gyfan." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "Llefaru'r llinell adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "Perfformio'r weithred 'ble ydw i'." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "Perfformio'r weithred 'ble ydw i'." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Llefaru'r llinell adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "bar statws" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "Cychwyn a gadael modd adolygu gwastad." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "Symud yr adolygu gwastad at y lleoliad gorffen." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "Symud yr adolygu gwastad at y lleoliad cartref." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "Symud yr adolygu gwastad at y lleoliad gorffen." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "Symud yr adolygu gwastad at gychwyn y llinell flaenorol." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "Llefaru'r llinell adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "Llefaru'r llinell adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "Llefaru'r llinell adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "Symud yr adolygu gwastad at gychwyn y llinell nesaf." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "Symud yr adolygu gwastad at yr eitem neu'r gair blaenorol." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "Llefaru'r eitem neu air adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "Llefaru'r eitem neu air adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "Llefaru'r eitem neu air adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "Symud yr adolygu gwastad at yr eitem neu'r gair nesaf." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "Symud yr adolygu gwastad at y gair uwchben y gair presennol." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "Llefaru'r gwrthrych adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "Symud yr adolygu gwastad at y gair islaw'r gair presennol." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "Symud yr adolygu gwastad at y nod blaenorol." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "Llefaru'r nod adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "Llefaru'r nod adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "Llefaru'r nod adolygu gwastad presennol." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "Symud yr adolygu gwastad at y nod nesaf." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "Symud yr adolygu gwastad i ddiwedd y llinell." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "Symud yr adolygu gwastad at y gornel waelod chwith." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "Symud yr adolygu gwastad at y lleoliad gorffen." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Toglu p'un ai i ddarllen dim ond y gell tabl presennol, neu'r rhes gyfan." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "Darllen y priodweddau sydd ynghlwm â'r nod testun presennol." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "Panio'r dangosydd braille i'r chwith." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "Panio'r dangosydd braille i'r dde." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "Dychwelyd at y gwrthrych gyda ffocws y bysellfwrdd." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "Symud yr adolygu gwastad at gychwyn y llinell nesaf." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"I fynd i mewn i'r modd dysgu. Gwasgwch y botwm escape i adael y modd dysgu." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "Lleihau cyflymder y lleferydd." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "Cynyddu cyflymder y lleferydd." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "Lleihau traw'r llais." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "Cynyddu traw'r llais." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Cynyddu cyflymder y lleferydd." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Lleihau cyflymder y lleferydd." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Dewiswch y gweinydd lleferydd." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Dewiswch y gweinydd lleferydd." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "Lleihau cyflymder y lleferydd." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "Cynyddu cyflymder y lleferydd." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "Toglu tewi'r lleferydd." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "Dangos y ddeialog cyflunio hoffterau." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "Dangos y ddeialog cyflunio hoffterau." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "Llefaru _mewnoli ac unioni" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "Syntheseiddydd _llais:" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "Newid i'r rheolwr cyflwyniad nesaf." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "Newid i'r rheolwr cyflwyniad nesaf." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "Cylchu'r lefel datnamu ar adeg rhedeg." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "_Gwaelod:" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "Gosodiadau'r Cyrchwr" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Symud yr adolygu gwastad at y nod nesaf." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "Symud yr adolygu gwastad at y nod blaenorol." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Symud yr adolygu gwastad at gychwyn y llinell nesaf." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "Symud yr adolygu gwastad i ddiwedd y llinell." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Llefaru cynnwys y llinell fewnbwn." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "Botwm Cyfeiriaduron" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "toglu botwm" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Dangos mwy o opsiynau" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "blwch ticio" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "blwch combo" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "cynhwysydd h t m l" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "cynhwysydd h t m l" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "ffrâm fewnol" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "ffrâm fewnol" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Dangos mwy o opsiynau" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr " Cyd-destun yw " - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr " Cyd-destun yw " - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "" -"Printio gwybodaeth datnamu am hynafiaeth y gwrthrych sydd ganddo ffocws" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "Dychwelyd at y gwrthrych gyda ffocws y bysellfwrdd." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "paragraff" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "botwm radio" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "botwm radio" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "gwahanydd" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "tabl coeden" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "tabl coeden" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "control dde" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "BotwmToglu" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Galluogi _adleisio bysellau" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "wedi cysgodi" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr " sgrin" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "brês dde" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "control dde" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "cromfach dde" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "brês dde" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "cromfach dde" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "cromfach dde" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "shift dde" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "cromfach dde" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "llinell newydd" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Delwedd" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "wedi cysgodi" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr " sgrin" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "tab" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "gofod gwag" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "gofod gwag" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Eicon" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Dim" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "Gwirio sillafu:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -#, fuzzy -msgid "Default Synthesizer" -msgstr "Syntheseiddydd _llais:" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "Galluogi adlais fesul _gair" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "Galluogi allweddi _gweithred" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "coma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "Rhagosodedig" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Gadael y modd dysgu." - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "Rhaglen" - -#: src/cthulhu/guilabels.py:296 -#, fuzzy -msgid "Braille Bindings" -msgstr "Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -#, fuzzy -msgid "Unbound" -msgstr "punt" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -#, fuzzy -msgid "_Desktop" -msgstr "EiconPenbwrdd" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Hoffterau Cthulhu" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -#, fuzzy -msgid "Speak" -msgstr "Llefaru" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "_Popeth" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "Rhaglen" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "Ffenestr" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "_Dim" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Rh_ai" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "M_wyafrif" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -#, fuzzy -msgid "Sentence" -msgstr "Canolwyd" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "dyfynnod" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Botwm" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "rhaglen" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "BlwchTicio" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "blwch combo" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "cwestiwn" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Pennyn" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "FfrâmFewnol" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Delwedd" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Label" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "Rhestr" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "EitemRhestr" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragraff" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "BotwmRadio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "wedi dewis" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Testun" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "dyfynnod" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botwm" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "BlwchTicio" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "blwch combo" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "FfrâmFewnol" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Delwedd" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "Rhestr" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "EitemRhestr" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragraff" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "BotwmRadio" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabl" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "Rhagosodedig" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Uwchgyswllt" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Llythrennau mawr" - -#: src/cthulhu/guilabels.py:852 -#, fuzzy -msgid "Speech Dispatcher" -msgstr "Lleferydd wedi'i analluogi." - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Gwirio sillafu:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "Llefaru'r _gell bresennol" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Brie_f" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Rhybudd" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "control chwith" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "shift chwith" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt chwith" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control chwith" - -#: src/cthulhu/keynames.py:72 -#, fuzzy -msgid "right shift" -msgstr "shift dde" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "shift dde" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control dde" - -#: src/cthulhu/keynames.py:84 -#, fuzzy -msgid "left meta" -msgstr "tab chwith" - -#: src/cthulhu/keynames.py:88 -#, fuzzy -msgid "right meta" -msgstr "shift dde" - -#: src/cthulhu/keynames.py:92 -#, fuzzy -msgid "num lock" -msgstr "Num_Lock" - -#: src/cthulhu/keynames.py:96 -#, fuzzy -msgid "caps lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keynames.py:105 -#, fuzzy -msgid "scroll lock" -msgstr "bar sgrolio" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -#, fuzzy -msgid "page up" -msgstr "tudalen" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -#, fuzzy -msgid "page down" -msgstr "tudalen" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab chwith" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "bwlch" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "Canolwyd" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "tudalen" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "alt chwith" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "shift dde" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "cromfach chwith" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "cromfach dde" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "dewislen" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "a" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "collnod" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Gweithfan " - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "cromfach chwith" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "saeth" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "cromfach dde" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "saeth" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "control dde" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "llai na" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "dot" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "llinell fertigol" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "awtogwblhau" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "gwag" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "plws" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "gwahanydd" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "Cyfraneddol" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "shift dde" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "cwarel â haenau" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "llinell fertigol" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Gwahanydd" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "cwestiwn" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "ffrâm fewnol" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "Cyfraneddol" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "hafalnod" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "hafalnod" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "hafalnod" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "llai na" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "llai na" - -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -#, fuzzy -msgctxt "math symbol" -msgid "not less than" -msgstr "llai na" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "heb ei wasgu" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "hafalnod" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "shift dde" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "tab chwith" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "heb ei wasgu" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "delwedd" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "ffrâm fewnol" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "shift dde" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "brês dde" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "gwahanydd" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "llai na" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:2025 -#, fuzzy -msgctxt "math symbol" -msgid "very much less than" -msgstr "llai na" - -#: src/cthulhu/mathsymbols.py:2028 -#, fuzzy -msgctxt "math symbol" -msgid "very much greater than" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "llai na" - -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "mwy na" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "llinell fertigol" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "cromfach chwith" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "cromfach dde" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "alt chwith" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "shift dde" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "bres chwith" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "bres chwith" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "braced chwith" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "braced dde" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "gofod gwag" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "gofod gwag" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "gofod gwag" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "llinell fertigol" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "rhaglen" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "gwag" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "Lleferydd wedi'i alluogi." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "eicon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, fuzzy, python-format -msgid "Cell %s" -msgstr "Cell" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "wedi dewis" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "dad-ddewiswyd" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -#, fuzzy -msgid "Set up user preferences (text version)" -msgstr "" -"-t, --text-setup Gosod hoffterau'r defnyddiwr (fersiwn destun)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "" -"-t, --text-setup Gosod hoffterau'r defnyddiwr (fersiwn destun)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Adroddwch namau at https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "cyflymach." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "cwestiwn" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "cynhwysydd h t m l" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "cynhwysydd h t m l" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "heb ei ddewis" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "yr holl ddogfen wedi'i dewis" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "yr holl ddogfen wedi'i dewis" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dogfen a ddewiswyd o safle'r cyrchwr" - -#: src/cthulhu/messages.py:554 -#, fuzzy -msgid "document unselected from cursor position" -msgstr "dogfen a ddewiswyd o safle'r cyrchwr" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dogfen a ddewiswyd hyd safle'r cyrchwr" - -#: src/cthulhu/messages.py:566 -#, fuzzy -msgid "document unselected to cursor position" -msgstr "dogfen a ddewiswyd hyd safle'r cyrchwr" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -#, fuzzy -msgid "Dynamic column header cleared." -msgstr "pennawd colofn" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "gwag" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "Cychwyn a gadael modd adolygu gwastad." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "Symud yr adolygu gwastad at y gair uwchben y gair presennol." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -#, fuzzy -msgid "has formula" -msgstr " ganddo fformiwla" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "deialog" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "naidlen" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, fuzzy, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Y broses osod ar ben. Gwasgwch Return i barhau." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -#, fuzzy -msgid "Key binding deleted. Press enter to confirm." -msgstr "Y broses osod ar ben. Gwasgwch Return i barhau." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "Dim" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "Canolwyd" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "Cyfrinair" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "llinell fertigol" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "a" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "cwarel gwraidd" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "cwarel gwraidd" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "cwarel gwraidd" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "tanlinell" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "tabl" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "tabl coeden" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "anhygyrch" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Tabl" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "Llefaru _mewnoli ac unioni" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Tabl" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "Llefaru _mewnoli ac unioni" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Y modd dysgu. Gwasgwch escape i'w adael." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "animeiddiad" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "llinell a ddewiswyd i lawr o safle'r cyrchwr" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "llinell a ddewiswyd i fyny o safle'r cyrchwr" - -#: src/cthulhu/messages.py:1484 -#, fuzzy -msgid "line unselected down from cursor position" -msgstr "llinell a ddewiswyd i lawr o safle'r cyrchwr" - -#: src/cthulhu/messages.py:1491 -#, fuzzy -msgid "line unselected up from cursor position" -msgstr "llinell a ddewiswyd i fyny o safle'r cyrchwr" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Gadael y modd dysgu." - -#: src/cthulhu/messages.py:1505 -#, fuzzy -msgid "line selected from start to previous cursor position" -msgstr "llinell a ddewiswyd i fyny o safle'r cyrchwr" - -#: src/cthulhu/messages.py:1511 -#, fuzzy -msgid "line selected to end from previous cursor position" -msgstr "llinell a ddewiswyd i lawr o safle'r cyrchwr" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "cyswllt" - -#: src/cthulhu/messages.py:1518 -#, fuzzy -msgid "same page" -msgstr "tudalen" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, fuzzy, python-format -msgid "%s link" -msgstr "cyswllt" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "lefel coeden %d" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "rhwygo bant" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "Dim" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "Gair wedi'i gamsillafu:" - -#: src/cthulhu/messages.py:1682 -#, fuzzy, python-format -msgid "Misspelled word: %s" -msgstr "Gair wedi ei gamsillafu:" - -#: src/cthulhu/messages.py:1687 -#, fuzzy, python-format -msgid "Context is %s" -msgstr " Cyd-destun yw " - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Lleferydd wedi'i analluogi." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Lleferydd wedi'i alluogi." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "cromfach chwith" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "lefel coeden %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Dim ffocws" - -#: src/cthulhu/messages.py:1867 -#, fuzzy -msgid "No application has focus." -msgstr "rhaglen" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "toglu botwm" - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "blwch ticio" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Dim lleisiau ar gael.\n" - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "blwch combo" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "ffrâm fewnol" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "eitem rhestr" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "paragraff" - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "botwm radio" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "gwahanydd" - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "tabl coeden" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "heb ei ddewis" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "Rhaglen" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "_Gwaelod:" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "_Top:" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "Cyfrinair" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -#, fuzzy -msgid "off" -msgstr "rhwygo bant" - -#: src/cthulhu/messages.py:2051 -#, fuzzy -msgid "on" -msgstr "Dim" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "tudalen a ddewiswyd o safle'r cyrchwr" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "tudalen a ddewiswyd hyd safle'r cyrchwr" - -#: src/cthulhu/messages.py:2089 -#, fuzzy -msgid "page unselected from cursor position" -msgstr "tudalen a ddewiswyd o safle'r cyrchwr" - -#: src/cthulhu/messages.py:2095 -#, fuzzy -msgid "page unselected to cursor position" -msgstr "tudalen a ddewiswyd hyd safle'r cyrchwr" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "tudalen a ddewiswyd o safle'r cyrchwr" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "tudalen a ddewiswyd o safle'r cyrchwr" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "tudalen a ddewiswyd o safle'r cyrchwr" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "tudalen a ddewiswyd o safle'r cyrchwr" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, fuzzy, python-format -msgid "Progress bar %d." -msgstr "bar cynnydd" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "_Popeth" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "Lefel Atalnodi" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "Dim" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -#, fuzzy -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Rhai" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -#, fuzzy -msgid "Search complete." -msgstr "Gwirio sillafu ar ben." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Gosodiadau defnyddiwr Cthulhu wedi eu hail-lwytho." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Dewiswch lais:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "dad-ddewiswyd" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Lleferydd wedi'i analluogi." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Lleferydd wedi'i alluogi." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "cyflymach." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "arafach." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "uwch." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "is." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "cyflymach." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Cyfradd:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "_Lefel sain:" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Dim gweinyddion ar gael.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Dim lleisiau ar gael.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Lleferydd wedi'i alluogi." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "Ni ddefnyddir lleferydd.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Hoffterau Cthulhu" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Lleferydd ddim ar gael." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "bar statws" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -#, fuzzy -msgid "Speak cell" -msgstr "Llefaru" - -#: src/cthulhu/messages.py:2394 -#, fuzzy -msgid "Speak row" -msgstr "Llefaru" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -#, fuzzy -msgid "Not in a table." -msgstr "Dim lleisiau ar gael.\n" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "PennawdColofn" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, fuzzy, python-format -msgid "column %d" -msgstr "pennawd colofn" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "dad-ddewiswyd" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "dad-ddewiswyd" - -#: src/cthulhu/messages.py:2458 -#, fuzzy, python-format -msgid "row %d" -msgstr "pennawd rhes" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "Symud yr adolygu gwastad i ddiwedd y llinell." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "heb ei ddewis" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "dad-ddewiswyd" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "wedi dewis" - -#: src/cthulhu/messages.py:2521 -#, fuzzy -msgctxt "text" -msgid "unselected" -msgstr "dad-ddewiswyd" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Hoffterau Cthulhu" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "gofod gwag" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -#, fuzzy -msgid "0 items" -msgstr "eitem rhestr" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "deialog" -msgstr[1] "deialog" -msgstr[2] "deialog" -msgstr[3] "deialog" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "eitem rhestr" -msgstr[1] "eitem rhestr" -msgstr[2] "eitem rhestr" -msgstr[3] "eitem rhestr" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "eitem rhestr" -msgstr[1] "eitem rhestr" -msgstr[2] "eitem rhestr" -msgstr[3] "eitem rhestr" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "canran" -msgstr[1] "canran" -msgstr[2] "canran" -msgstr[3] "canran" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "picseli" -msgstr[1] "picseli" -msgstr[2] "picseli" -msgstr[3] "picseli" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "bwlch" -msgstr[1] "bwlch" -msgstr[2] "bwlch" -msgstr[3] "bwlch" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "tabl" -msgstr[1] "tabl" -msgstr[2] "tabl" -msgstr[3] "tabl" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "toglu botwm" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, fuzzy, python-format -msgid "LEVEL %d" -msgstr "LEFEL COEDEN %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "lefel coeden %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "LEFEL COEDEN %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "cwestiwn" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "blwch combo" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "colon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "Rhaglen" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "paragraff" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "rhestr dabiau" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "dyfynnod" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, fuzzy, python-format -msgid "h%d" -msgstr "pen" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "bar sgrolio" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "bar sgrolio" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "llinell fertigol" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "llinell fertigol" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -#, fuzzy -msgid "Icon panel" -msgstr "cwarel opsiynau" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Animeiddiad" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Animeiddiad" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "botwm troelli" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "wedi ymgwympo" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "wedi'i ehangu" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -#, fuzzy -msgid "vertical" -msgstr "llinell fertigol" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "ticiwyd" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "heb ei dicio" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "Dim" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "rhwygo bant" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "heb ei dicio" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "gwasgwyd" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "heb ei wasgu" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "heb ei ddewis" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "wedi dewis" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "heb ei ddewis" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "heb ei ddewis" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "wedi cysgodi" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "dad-ddewiswyd" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "annilys" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "annilys" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "annilys" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "Gwirio Sillafu" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "annilys" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:166 -#, fuzzy -msgid "_Top of window" -msgstr "ffenestr" - -#: src/cthulhu/cthulhu-find.ui:175 -#, fuzzy -msgid "Top of window" -msgstr "ffenestr" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "CwarelOpsiwn" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Rhagosodedig" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Llythrennau mawr" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Uwchgyswllt" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Rhaglen" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Ffenestr" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Hoffterau Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "Llefaru" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Rhaglen" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "bar cynnydd" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Lefel sain:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Cywair:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Cyfradd:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Person:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Syntheseiddydd _llais:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_System leferydd:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "_Gosodiadau llais:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "_Gosodiadau llais:" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "_Gosodiadau llais:" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Galluogi lleferydd" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Amleiriog" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "Geiriogrwydd" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Popeth" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "Lefel Atalnodi" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Llefaru _mewnoli ac unioni" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -#, fuzzy -msgid "Spoken Context" -msgstr " Cyd-destun yw " - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Lleferydd" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Galluogi _cefnogaeth Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Enwau rôl wedi'u talfyrru" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Galluogi adlais fesul _gair" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "Dangos mwy o opsiynau" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "_Dim" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "Uwchgyswllt" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "Galluogi _chwyddwydr" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Galluogi _adleisio bysellau" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Galluogi allweddi _gweithred" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "Galluogi _allweddellau addasu" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Galluogi _bysellau swyddogaeth" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "_Galluogi lleferydd" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Galluogi _allweddellau addasu" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Galluogi _bysellau swyddogaeth" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Galluogi allweddi _gweithred" - -#: src/cthulhu/cthulhu-setup.ui:2909 -#, fuzzy -msgid "Enable _navigation keys" -msgstr "Galluogi _bysellau swyddogaeth" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Galluogi adlais fesul _gair" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "Galluogi adlais fesul _gair" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Adleisio Bysellau" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Galluogi _allweddellau addasu" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3204 -#, fuzzy -msgid "Pronunciation" -msgstr "Animeiddiad" - -#: src/cthulhu/cthulhu-setup.ui:3243 -#, fuzzy -msgid "_Speak all" -msgstr "Llefaru" - -#: src/cthulhu/cthulhu-setup.ui:3257 -#, fuzzy -msgid "Speak _none" -msgstr "Llefaru" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "Galluogi _monitor Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "Cynorthwyydd" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "rhes" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "Cynorthwyydd" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "_Ffactor graddfa:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "cwarel cyfeiriadur" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "tabl" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -#, fuzzy -msgctxt "textattr" -msgid "invisible" -msgstr "anhygyrch" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "cromfach chwith" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "paragraff" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "cromfach dde" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "cale" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "llinell newydd" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "llinell fertigol" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "_De:" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -#, fuzzy -msgctxt "textattr" -msgid "writing mode" -msgstr "Gadael y modd dysgu." - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "llinell newydd" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "cyswllt" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "rhes" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "Cyfrinair" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "llnw" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "tblcoed" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "alt chwith" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "shift dde" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "Canolwyd" - -#: src/cthulhu/text_attribute_names.py:493 -#, fuzzy -msgctxt "textattr" -msgid "no justification" -msgstr "Llefaru _mewnoli ac unioni" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "llenwad" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "semicolon" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "wedi'i ehangu" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "wedi'i ehangu" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "wedi'i ehangu" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "wedi'i ehangu" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "Rhagosodedig" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "Testun" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "Pennyn" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "llinell newydd" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "cmth" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "testun" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "_Gwaelod:" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "llnw" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "tab" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "Gwirio Sillafu" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -#, fuzzy -msgid "To get to the system menus press the alt+f1 key." -msgstr "I adael y modd dysgu, gwasgwch y botwm escape." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/da.po b/po/da.po deleted file mode 100644 index b4898f8..0000000 --- a/po/da.po +++ /dev/null @@ -1,9275 +0,0 @@ -# Danish translation of cthulhu -# Copyright (C) 2007-2018 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# Kenneth Nielsen , 2007-2017 -# scootergrisen, 2016, 2020. -# Ask Hjorth Larsen , 2018 -# Alan Mortensen , 2019-23. -# -# Konventioner: -# pixel -> pixel(s) (ikke skærmpunkt(er)) -# -# I oversættelsen af farver har jeg bevidst valgt at skrive lys grøn i stedet for lysegrøn, fordi det gør det nemmere og symmetrisk når der skal oversættes sådan noget som "pale green" at det så kan gøres til bleg grøn. Ligeledes har jeg undladt at tilføje "-farvet" på alle den ting som er opkaldt efter en blomst, et dyr eller tilsvarende idet jeg antager at farvekonteksten er implicit. -# -# I forbindelse med oversættelse af MathML ligninger har jeg lagt vægt på at de -# skal være nemme at forstå/visualisere. Det går nogle gange ud over -# sproget. F.eks. er "fraction start" ikke, som måske ville være pænere dansk, -# oversat til "start af brøk" men til "brøk start", med start og slut til -# sidst. Det er gjort for at det skal være nemmere at skelne hvornår man rent -# faktisk starter på det omtalte objekt. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-09-05 07:41+0200\n" -"Last-Translator: Alan Mortensen \n" -"Language-Team: Danish \n" -"Language: da\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.0.1\n" - -msgid "Cthulhu Screen Reader" -msgstr "Skærmlæseren Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "skærm;læser;tilgængelighed;tale;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "bskd" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "pil" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "lrd" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "blte" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "akf" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "frvlgr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "kolos" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "kmb" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ikon" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "ram" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "drejk" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "map" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "tegn" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "filv" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "udf" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "stv" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "glp" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "os" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "bld" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "inrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etk" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lagp" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstel" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnul" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuel" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "vap" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "sid" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "fblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "agk" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popm" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "statl" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "knp" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "radmnuel" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rodp" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rkos" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "rlbj" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "rlp" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sek" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "sept" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "skdr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "splp" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "snur" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statl" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tamnuel" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tek" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "skfkn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "vrkl" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "træ" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "ukn" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vsnom" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "vnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "shd" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "sfd" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "afsn" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "prg" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "regl" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "inl" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Tjekkisk niveau 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spansk niveau 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Fransk (Canada) niveau 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Fransk (Frankrig) niveau 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Lettisk niveau 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Hollandsk niveau 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norsk niveau 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norsk niveau 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norsk niveau 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norsk niveau 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polsk niveau 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugisisk niveau 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Svensk niveau 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabisk niveau 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Walisisk niveau 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Walisisk niveau 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Tysk niveau 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Tysk niveau 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Tysk niveau 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Engelsk (Storbritannien) niveau 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Engelsk (Storbritannien) niveau 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Engelsk (USA) niveau 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Engelsk (USA) niveau 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Fransk (Canada) niveau 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Fransk (Frankrig) niveau 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Græsk niveau 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi niveau 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ungarsk 8-punktscomputer" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Ungarsk niveau 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Ungarsk niveau 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiensk niveau 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgisk niveau 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "mellemrum" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "linjeskift" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulator" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "udråbstegn" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "citationstegn" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nummer" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "og" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "venstre parentes" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "højre parentes" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "stjerne" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "komma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "bindestreg" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punktum" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "skråstreg" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "kolon" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semikolon" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "mindre end" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "lig med" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "større end" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "spørgsmålstegn" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "snabel-a" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "venstre kantparentes" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "omvendt skråstreg" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "højre kantparentes" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "cirkumflekstegn" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "understreget" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "accent grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "venstre krøllet parentes" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "lodret streg" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "højre krøllet parentes" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "hårdt mellemrum" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "omvendt udråbstegn" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pund" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "valutasymbol" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "brudt streg" - -# scootergrisen: fra gennemlæsning: Ville nok bruge "afsnit" - det er det, tegnet angiver og ikke en paragraf i en lovtekst -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "paragraf" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diærese" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "ophavsret" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "hævet a" - -# scootergrisen: wikipedia: Afsluttende dobbel citations-vinkel -# scootergrisen: wikipedia: Begyndende dobbel citations-vinkel -# scootergrisen: wikipedia: ser desværre ud til at tegnet bruges omvendt på dansk (left bruges til højre på dansk) -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "dobbelt mindre end tegn" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logisk ikke" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "blød bindestreg" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registreret" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "grader" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "hævet 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "hævet 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "accent aigu" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "my" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "afsnitstegn" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "prik" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedille" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "hævet 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -# scootergrisen: wikipedia: Afsluttende dobbel citations-vinkel -# scootergrisen: wikipedia: Begyndende dobbel citations-vinkel -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "dobbelt større end tegn" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "en fjerdedel" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "en halv" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tre fjerdedele" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "omvendt spørgsmålstegn" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a accent aigu" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A ACCENT GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACCENT AIGU" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A OMLYD" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "Å" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "Æ" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLE" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E ACCENT GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACCENT AIGU" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E OMLYD" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I ACCENT GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACCENT AIGU" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I OMLYD" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O ACCENT GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACCENT AIGU" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O OMLYD" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "gange" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "Ø" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U ACCENT GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACCENT AIGU" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U OMLYD" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACCENT AIGU" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "dobbelt-s" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a accent grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a cirkumfleks" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a omlyd" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "å" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "æ" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedille" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e accent grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e accent aigu" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e cirkumfleks" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e omlyd" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i accent grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i accent aigu" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i cirkumfleks" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i omlyd" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o accent grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o accent aigu" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o cirkumfleks" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o omlyd" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "divideret med" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "ø" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u accent aigu" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u accent grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u cirkumfleks" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u omlyd" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y accent aigu" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y omlyd" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y OMLYD" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "N tankestreg" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "venstre enkelt citationstegn" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "højre enkelt citationstegn" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "enkelt lavt citationstegn" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "venstre dobbelt citationstegn" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "højre dobbelt citationstegn" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dobbelt lavt citationstegn" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "daggert" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dobbelt daggert" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "punkt" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trekantet punkt" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "mærke" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "dobbeltmærke" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "tredobbeltmærke" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "bindestregspunkt" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "varemærke" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "afkrydsningstegn" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "fed afkrydsningstegn" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "krydsformet punkt" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "hævet 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "hævet 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "hævet 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "hævet 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "hævet 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "hævet 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "hævet 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "hævet plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "hævet minus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "hævet lighedstegn" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "hævet venstre parentes" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "hævet højre parentes" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "hævet n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "sænket 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "sænket 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "sænket 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "sænket 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "sænket 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "sænket 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "sænket 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "sænket 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "sænket 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "sænket 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "sænket plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "sænket minus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "sænket lighedstegn" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "sænket venstre parentes" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "sænket højre parentes" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "sort firkant" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "sort diamant" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "objekterstatningstegn" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Guid markøren til det nuværende element" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Udfør venstreklik på det nuværende element i flad gennemgang" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Udfør højreklik på det nuværende element i flad gennemgang" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Oplæs hele dokumentet" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Oplæs hele vinduet vha. flad gennemgang" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Udfør den almindelige operation “hvor er jeg”" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Udfør den detaljerede operation “hvor er jeg”" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Oplæs den nuværende markering" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Oplæs linkdetaljer" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Oplæs og vis standardknappen" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Oplæs og vis statuslinjen" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Oplæs og vis titellinjen" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Åbn dialogen Find" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Vis handlingsliste" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Søg efter næste forekomst af en streng" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Søg efter tidligere forekomst af en streng" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Aktivér eller deaktivér tilstanden flad gennemgang" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" -"Slå begrænsning af flad gennemgang til det aktuelle objekt til eller fra" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Flyt flad gennemgang til begyndelsespositionen" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Flyt flad gennemgang til slutpositionen" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Flyt flad gennemgang til begyndelsen af den forrige linje" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Oplæs den nuværende linje i flad gennemgang" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Stav den nuværende linje i flad gennemgang" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Stav den nuværende linje i flad gennemgang fonetisk" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Flyt flad gennemgang til begyndelsen af den næste linje" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Flyt flad gennemgang til det forrige element eller ord" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Oplæs det nuværende element eller ord i flad gennemgang" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Stav det nuværende element eller ord i flad gennemgang" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Stav det nuværende element eller ord i flad gennemgang fonetisk" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Flyt flad gennemgang til det næste element eller ord" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Flyt flad gennemgang til ordet over det nuværende ord" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Oplæs det nuværende element i flad gennemgang" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Flyt flad gennemgang til ordet under det nuværende ord" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Flyt flad gennemgang til det forrige tegn" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Oplæs det nuværende tegn i flad gennemgang" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Oplæs det nuværende tegn i flad gennemgang fonetisk" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Oplæs unicodeværdien for det nuværende tegn i flad gennemgang" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Flyt flad gennemgang til det næste tegn" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Flyt flad gennemgang til slutningen af linjen" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Flyt flad gennemgang nederst til venstre" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Kopiér indholdet under flad gennemgang til udklipsholderen" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Tilføj indholdet under flad gennemgang til udklipsholderen" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Vis indholdet af flad gennemgang" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Vælg mellem kun at læse nuværende celle eller hele rækken" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Læs det nuværende tegns attributter" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Panorer punktskriftsdisplayet til venstre" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Panorer punktskriftsdisplayet til højre" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Vend tilbage til objekt med tastaturfokus" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Slå forkortet punktskrift til og fra" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Behandl en markørguidningstast" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Angiv begyndelsen af en tekstmarkering" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Angiv slutningen af en tekstmarkering" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Gå i tilstanden lær. Tryk på escape for at afslutte tilstanden lær" - -# jeg har skrevet med en af udviklerne for at prøve at finde ud af om de steder hvor der står speech -# om de altid bare skal oversættes til tale, eller om man bør bruge læse nogle steder (idet den jo -# nogle gange bruges til at læse tekst fra et dokument op med). Konklusionen var at der stort set alle -# steder skal bruges tale. Jeg knytter en tale^^ kommentar til de pågældende beskeder -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Sænk talehastigheden" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Hæv talehastigheden" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Sænk stemmens tonehøjde" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Hæv stemmens tonehøjde" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Hæv talelydstyrken" - -# jeg har skrevet med en af udviklerne for at prøve at finde ud af om de steder hvor der står speech -# om de altid bare skal oversættes til tale, eller om man bør bruge læse nogle steder (idet den jo -# nogle gange bruges til at læse tekst fra et dokument op med). Konklusionen var at der stort set alle -# steder skal bruges tale. Jeg knytter en tale^^ kommentar til de pågældende beskeder -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Sænk talelydstyrken" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Vælg forrige taleindstilling" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Vælg næste taleindstilling" - -# jeg har skrevet med en af udviklerne for at prøve at finde ud af om de steder hvor der står speech -# om de altid bare skal oversættes til tale, eller om man bør bruge læse nogle steder (idet den jo -# nogle gange bruges til at læse tekst fra et dokument op med). Konklusionen var at der stort set alle -# steder skal bruges tale. Jeg knytter en tale^^ kommentar til de pågældende beskeder -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Sænk den aktuelle taleindstilling" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Forøg den aktuelle taleindstilling" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Gem taleindstillinger" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Slå lyden fra tale til eller fra" - -# scootergrisen: fra gennemlæsning: detalje er vel ok - personligt foretrækker jeg detaljeringsgrad frem for uddybningsniveau (et ord som ikke har mange hits på google) -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Skift uddybningsniveau for tale" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Slå dvaletilstand til/fra" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Afslut skærmlæseren" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Vis indstillingsdialogen" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Vis indstillingsdialogen for et program" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Slå oplæsning af indrykning og justering til/fra" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Ændr stilen for tal som oplæses" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Skift til det næste niveau for oplæsning af tegnsætning" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Skift til den næste talesynthesizer" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Gå til den næste indstillingsprofil" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Gå til næste stil for ord med stort" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Gå til næste niveau for tasteekko" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Skift igennem fejlsøgningsniveauerne under kørsel" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Lav et bogmærke for hvor jeg er nu" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Gå til det forrige bogmærkes position" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Gå til bogmærke" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Gå til det næste bogmærkes position" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Tilføj bogmærke" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Gem bogmærker" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Tilstanden musegennemgang til/fra" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Præsenter aktuel klokkeslæt" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Præsenter aktuel dato" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Præsenter det nuværende objekts størrelse og placering" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" -"Videresend den næste kommando til det på nuværende tidspunkt aktive program" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Oplæs og vis med punktskrift en tidligere meddelelse fra chatrum" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Bekendtgør når vores venner skriver til/fra" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Chatrumsspecifik meddelelseshistorik til/fra" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "Foranstilling af navnet på chatrummet til meddelelserne til/fra" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linje venstre" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linje højre" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linje op" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linje ned" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Frys" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Øverst til venstre" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Nederste til venstre" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Markørposition" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Seks punkter" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Markørguidning" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Klip begynd" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Klip linje" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Præsenter seneste underretningsmeddelelse" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Præsenter underretningsmeddelelsesliste" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Præsenter forrige underretningsmeddelelse" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Præsenter næste underretningsmeddelelse" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Gå til næste tegn" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Gå til forrige tegn" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Gå til næste ord" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Gå til forrige ord" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Gå til næste linje" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Gå til forrige linje" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Gå til begyndelsen af filen" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Gå til slutningen af filen" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Gå til begyndelsen af linjen" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Gå til slutningen af linjen" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Gå til næste objekt" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Gå til forrige objekt" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Udvid den nuværende kombinationsboks" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Skift mellem den indbyggede og skærmlæserens markørnavigation" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Skift til næste høflighedsindstilling for liveområder" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Sæt standardhøflighedsniveau for liveområder til “fra”" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Gennemgå beskeder fra liveområder" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Overvåg liveområder" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Flyt fokus til og fra det nuværende museaktiverede element" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Sæt række som skal bruges som dynamisk kolonneoverskrift" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Ryd de dynamiske kolonneoverskrifter" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Sæt kolonne som skal bruges som dynamisk rækkeoverskrift" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Ryd de dynamiske rækkeoverskrifter" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Præsenter indholdet af indtastningsfeltet" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Taster til strukturel navigation til/fra" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Gå til forrige blokcitat" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Gå til næste blokcitat" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Vis en liste over blokcitater" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Gå til forrige knap" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Gå til næste knap" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Vis en liste over knapper" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Gå til forrige afkrydsningsboks" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Gå til næste afkrydsningsboks" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Vis en liste over afkrydsningsbokse" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Gå til forrige klikbare" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Gå til næste klikbare" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Vis en liste over klikbare" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Gå til forrige kombinationsboks" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Gå til næste kombinationsboks" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Gå til begyndelsen af beholderen" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Gå til slutningen af beholderen" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Vis en liste over kombinationsbokse" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Gå til forrige indtastningsfelt" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Gå til næste indtastningsfelt" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Vis en liste over indtastningsfelter" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Gå til forrige formularfelt" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Gå til næste formularfelt" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Vis en liste over formularfelter" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Gå til forrige overskrift" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Gå til næste overskrift" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Vis en liste over overskrifter" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Gå til forrige overskrift på niveau %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Gå til næste overskrift på niveau %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Vis en liste over overskrifter på niveau %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Gå til forrige interne ramme" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Gå til næste interne ramme" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Vis en liste over interne rammer" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Gå til forrige billede" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Gå til næste billede" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Vis en liste over billeder" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Gå til forrige kendemærke" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Gå til næste kendemærke" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Vis en liste over kendemærker" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Gå til forrige store objekt" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Gå til næste store objekt" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Vis en liste over store objekter" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Gå til forrige link" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Gå til næste link" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Vis en liste over links" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Gå til forrige liste" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Gå til næste liste" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Vis en liste over lister" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Gå til forrige listeelement" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Gå til næste listeelement" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Vis en liste over listeelementer" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Gå til forrige liveområde" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Gå til næste liveområde" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" -"Gå til den senest liveområde (live region) som fremkaldte en bekendtgørelse" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Gå til til objektets overelement med navigatorfokus." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Gå til til objektets første underelement med navigatorfokus." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Gå til til objektets næste sidestillede element med navigatorfokus." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Gå til til objektets forrige sidestillede element med navigatorfokus." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Klik på objektet med navigatorfokus." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Slå simplificeret objektnavigation til eller fra." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Gå til forrige afsnit" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Gå til næste afsnit" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Vis en liste over afsnit" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Gå til forrige radioknap" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Gå til næste radioknap" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Vis en liste over radioknapper" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Gå til forrige separator" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Gå til næste separator" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Gå til forrige tabel" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Gå til næste tabel" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Vis en liste over tabeller" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Gå en celle ned" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Gå til den første celle i en tabel" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Gå til den sidste celle i en tabel" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Gå en celle til venstre" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Gå en celle til højre" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Gå en celle op" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Layouttilstand til/fra" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Skift mellem gennemse- og fokustilstand" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Aktivér klæbende fokustilstand" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Aktivér klæbende gennemsetilstand" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Gå til forrige ubesøgte link" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Gå til næste ubesøgte link" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Vis en liste over ubesøgte links" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Gå til forrige besøgte link" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Gå til næste besøgte link" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Vis en liste over besøgte links" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "aliceblå" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antik hvid" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarin" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azurblå" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "biskuit" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "sort" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "blancheret mandel" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blå" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "blåviolet" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "brun" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "kraftig træ" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadetblå" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chokolade" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "kornblomstblå" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "majsgul" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "karminrød" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cyan" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "mørk blå" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "mørk cyan" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "mørk gyldenris" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "mørk grå" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "mørk grøn" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "mørk kaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "mørk magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "mørk olivengrøn" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "mørk orange" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "mørk orkidé" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "mørk rød" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "mørk laks" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "mørk havgrøn" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "mørk skifferblå" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "mørk skiffergrå" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "mørk turkis" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "mørk violet" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "dyb pink" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "dyb himmelblå" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "dæmpet grå" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodgerblå" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "murstensrød" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "blomsterhvid" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "skovgrøn" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "spøgelseshvid" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "guld" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "gyldenris" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "grå" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "grøn" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "grøngul" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "honningdug" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "varm pink" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indisk rød" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigoblå" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "elfenben" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "kaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavendel" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavendelrødmen" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "plænegrøn" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "citronchiffon" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "lys blå" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "lys koral" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "lys cyan" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "lys gyldenrisgul" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "lys grå" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "lys grøn" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "lys pink" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "lys laks" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "lys havgrøn" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "lys himmelblå" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "lys skiffergrå" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "lys stålblå" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "lys gul" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lime" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limegrøn" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linned" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "rødbrun" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "medium akvamarin" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "medium blå" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "medium orkidé" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "medium lilla" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "medium havgrøn" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "medium skifferblå" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "medium forårsgrøn" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "medium turkis" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "medium violetrød" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "midnatsblå" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "crememintgrøn" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "dugget rose" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokkasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajohvid" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "marineblå" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "gammel knipling" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olivengrøn" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "drap olivengrøn" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "orange" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "orangerød" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orkidé" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "svag gyldenris" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "svag grøn" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "svag turkis" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "svag violetrød" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "pisket papaya" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "ferskenkød" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "pink" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "blomme" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "pulverblå" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "lilla" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "rød" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rosenbrun" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "kongelig blå" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "saddelbrun" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "laks" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "sandet brun" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "havgrøn" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "strandskal" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "sølv" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "himmelblå" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "skifferblå" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "skiffergrå" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "sne" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "forårsgrøn" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "stålblå" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "solbrun" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "grønblå" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "tidsel" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomat" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turkis" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violet" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "hvede" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "hvid" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "hvid røg" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "gul" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "gulgrøn" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktivér" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatisk fokustilstand under strukturel navigation" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatisk fokustilstand under markørnavigation" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatisk fokustilstand under indbygget navigation" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punkt _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punkt _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Punkt 7 o_g 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "A_nnullér" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "Hop _til" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikon" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Intet" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Stav" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Bekendtgør når dine _venner skriver" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Giv _meddelelseshistorik som er chatrumsspecifik" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Oplæs meddelelser fra" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Alle ka_naler" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Alle kanaler når _blot et %s vindue er aktivt" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Kun én kanal, hvis dens _vindue er aktivt" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "Oplæ_s navnet på chatrummet" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Aktivér layouttilstand for indhold" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dobbeltklik" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "tredobbelt klik" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Standardsynthesizer" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Oprindelige streng" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Erstatningsstreng" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Aktivér _ekko et tegn ad gangen" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Aktivér _diakritiske taster som ikke optager plads" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "N_uværende placering" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimumslængde på fundne tekst:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Indstillinger for Find" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Oplæs kun _ændrede linjer under find" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Oplæs resultater under _find" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Kommando" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Tastebinding" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Standard" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Læringstilstand" - -# scootergrisen: fra gennemlæsning: Ville nok bruge "afsnit" - det er det, tegnet angiver og ikke en paragraf i en lovtekst -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Handlinger" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Punktskriftsbindinger" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Bogmærker" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Dato og klokkeslæt" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Musegennemgang" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Objektnavigation" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objektdetaljer" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Ubundne" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Flad gennemgang" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Tale og uddybning" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Indhold af flad gennemgang" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Ændret" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Stationær" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Underretninger" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Modtaget" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Underretningsvisning" - -# scootergrisen: vigtig titel på dialog til programspecifikke indstillinger - se også anden streng -# scootergrisen: Skærmlæserindstillinger for %s -# scootergrisen: Skærmlæserindstillinger til %s -# scootergrisen: Indstillinger for skærmlæser for %s -# scootergrisen: Indstillinger for skærmlæser til %s -# scootergrisen: Indstillinger for Skærmlæser for %s -# scootergrisen: Indstillinger for Skærmlæser til %s -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu-indstillinger for %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Mærk i punktskrift" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Præsenter med mindre" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Oplæs" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Gem profil som konflikt" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Konflikt ved brugerprofiler!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profilen %s findes allerede.\n" -"Vil du fortsætte med at opdatere den eksisterende profil med disse nye " -"ændringer?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Indlæs brugerprofil" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Du er ved at ændre den aktive profil. Hvis du netop\n" -"har foretaget ændringer i dine indstillinger, vil disse blive\n" -"forkastet ved profilindlæsning.\n" -"\n" -"Forsæt med at indlæse profil og forkast tidligere ændringer?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Gem profil som" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profilnavn:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Fjern brugerprofil" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Du er ved at fjerne profilen %s. Alle indstillinger, som ikke er gemt, og " -"indstillingerne gemt i denne profil vil gå tabt. Vil du fjerne denne profil " -"og alle tilhørende indstillinger?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Alle" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Program" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Vindue" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Ingen" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "No_gle" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Fleste" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "En linje ad gangen" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "En sætning ad gangen" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Blokcitat" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Knap" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Billedtekst" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Afkrydsningsfelt" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Klikbar" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kombinationsboks" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Beskrivelse" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Overskrift" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Intern ramme" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Billede" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiket" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Kendemærke" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Niveau" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Link" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Listeelement" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekt" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Afsnit" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radioknap" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rolle" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Valgte element" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Status" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Tekst" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Værdi" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blokcitater" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Knapper" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Afkrydsningsfelter" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Klikbare" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kombinationsbokse" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Indtastningsfelter" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Formularfelter" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Overskrifter" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Interne rammer" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Billeder" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Overskrifter på niveau %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Kendemærker" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Store objekter" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Links" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Lister" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Listeelementer" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Afsnit" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radioknapper" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabeller" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Ubesøgte links" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Besøgte links" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Sidenavigation" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Start automatisk oplæsning af side, når den først _indlæses" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Præsenter o_psummering af en side når den først indlæses" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Opdel tale i bidder _mellem pauser" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Standardstemme for %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Standard" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "System" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Store bogstaver" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Stavekontrol" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Stav _fejl" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Stav _forslag" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Præsenter fejlens kontekst" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Oplæs regnearkscellekoordinater" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Oplæs altid valgte regnearksområde" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Bekendtgør _celleoverskrift" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Tabelnavigation" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Spring _tomme celler over" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Oplæs _celle" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Oplæs _cellekoordinater" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Oplæs udstrækning over _flere celler" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Attributnavn" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Styr markørnavigation" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Aktivér _strukturel navigation" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Lyd_tema:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Lydtema" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Kortfatte_t" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d underretning" -msgstr[1] "%d underretninger" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Skift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "venstre skift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "venstre alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "venstre ctrl" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "højre skift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "højre alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "højre ctrl" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "venstre meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "højre meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "skift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "venstre tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "tilbagetast" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "retur" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "op" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "ned" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "venstre" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "højre" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "venstre super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "højre super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "help" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "tilstandsskift" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "cirkumfleks" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "skrå gennemstreg" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Højre Alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Venstre Alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Skift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "fed %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "kursiv %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "fed kursiv %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "skråskrift %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "fed skråskrift %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -# Jeg kunne ikke finde en officielt oversættelse af dette: http://en.wikipedia.org/wiki/Blackboard_bold. Forslag er velkomne. -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "dobbeltstreget %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "fed fraktur %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans serif fed %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans serif kursiv %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans serif fed kursiv %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "fast bredde %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s uden prik" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "pil venstre" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "pil op" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "pil højre" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "pil ned" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "pil venstre højre" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "pil op ned" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "pil nordvest" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "pil nordøst" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "pil sydøst" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "pil til venstre fra streg" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "pil op fra streg" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "pil til højre fra streg" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "pil ned fra streg" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dobbeltpil venstre" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dobbeltpil op" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dobbeltpil højre" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dobbeltpil ned" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dobbeltpil venstre højre" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dobbelt pil op ned" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "nordvest dobbeltpil" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "nordøst dobbeltpil" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "sydøst dobbeltpil" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "sydvest dobbeltpil" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "højrepegende pil" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "højrepegende pilehoved" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "mindre end" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "større end" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "cirkumfleks" - -# OK ifølge: https://da.wikipedia.org/wiki/Diakritiske_tegn -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -# Jeg har ikke kunnet finde finde nogen indslag til dette. Forslag er meget velkomne. -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "prik" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dobbelt lodret linje" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "vandret ellipse" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "for alle" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "komplement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "partielt differential" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "der findes" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "der findes ikke" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "tom mængde" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "forskel" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "tilhører ikke" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "tilhører ikke" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "lille tilhører" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "indeholder element" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "indeholder ikke element" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "lille indeholder element" - -# Man kunne have lavet sådan noget som: "Afslutning af bevis", men jeg tænkte at det virkede som en den korte form er mere den direkte oversættelse -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "slut på bevis" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produkt" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coprodukt" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sum" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus eller plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "prikplus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "divisionsstreg" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "mængdeminus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "stjerneoperator" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "ringoperator" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "prikoperator" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "kvadratrod" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "kubikrod" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "fjerde rod" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proportional med" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "uendelig" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "ret vinkel" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "vinkel" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "målt vinkel" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sfærisk vinkel" - -# Jeg tror dette er korrekt jvf: http://en.wikipedia.org/wiki/List_of_mathematical_symbols -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "går op i" - -# Jeg tror dette er korrekt jvf: http://en.wikipedia.org/wiki/List_of_mathematical_symbols -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "går ikke op i" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "parallel med" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "ikke parallel med" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logisk og" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logisk eller" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "fællesmængde" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "foreningsmængde" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dobbeltintegral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "tredobbeltintegral" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "konturintegral" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "overfladeintegral" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "rumintegral" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral med uret" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "konturintegral med uret" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "konturintegral mod uret" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "derfor" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "fordi" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "forhold" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "forhold" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "prikminus" - -# Jeg var reduceret til at gætte her, ud fra ordbogsoversættelsen af det generelle ord -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "overskydende" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrisk proportion" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetisk" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "omvendt tilde" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "omvendt dovent S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusbølge" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "kransprodukt" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "ikke tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minustilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptotisk lig med" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ikke asymptotisk lig med" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "tilnærmelsesvis lig med" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "tilnærmelsesvis men ikke faktisk lig med" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "hverken tilnærmelsesvis eller faktisk lig med" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "næsten lig med" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ikke næsten lig med" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "næsten lig med eller lig med" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "tredobbelt tilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "alle lig med" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrisk ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "forskel mellem" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "nærmer sig grænsen" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrisk lig med" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "tilnærmelsesvis lig med eller billedet af" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "billedet af eller tilnærmelsesvis lig med" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "kolon lig med" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "lig med kolon" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ring i lig med" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ring lig med" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "svarer til" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estimerer" - -# Puha, en equiangular triangle er en ligesidet trekant, men jeg er usikker på om det kan anvendes her -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "ækviangulær til" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "stjerne lig med" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta lig med" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "lig med per definition" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "målt af" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "spørgsmålstegn lig med" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "ikke lig med" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identisk med" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "ikke identisk med" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "strengt ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "mindre end eller lig med" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "større end eller lig med" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "mindre end eller lig med" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "større end eller lig med" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "mindre end men ikke lig med" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "større end men ikke lig med" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "meget mindre end" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "meget større end" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "mellem" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "ikke ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "ikke mindre end" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "ikke større end" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "hverken mindre end eller lig med" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "hverken større end eller lig med" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "mindre end eller ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "større end eller ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "hverken mindre end eller ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "hverken større end eller ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "mindre end eller større end" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "større end eller mindre end" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "hverken mindre end eller større end" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "hverken større end eller mindre end" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "kommer før" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "kommer efter" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "kommer før eller er lig med" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "kommer efter eller er lig med" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "kommer før eller er ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "kommer efter eller er ækvivalent med" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "kommer ikke før" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "kommer ikke efter" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "delmængde af" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "overmængde af" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "ikke en delmængde af" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "ikke en overmængde af" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "delmængde af eller lig med" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "overmængde af eller lig med" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "hverken en delmængde af eller lig med" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "hverken en overmængde af eller lig med" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "delmængde af med ikke lig med" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "overmængde af med ikke lig med" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multimængde" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multimængdemultiplikation" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "multimængdeforeningsmængde" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "kvadratbillede af" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadratoriginal af" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "kvadratbillede af eller lig med" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "kvadratoriginal af eller lig med" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "kvadrattop" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadratkop" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "cirklet plus" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "cirklet minus" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "cirklet gange" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "cirklet divisionsstreg" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "cirklet prikoperator" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "cirklet ringoperator" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "cirklet stjerneoperator" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "cirklet lig med" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "cirklet bindestreg" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "firkantplus" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "firkantminus" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "firkantgange" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "forkantprik" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "højrestift" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "venstrestift" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "nedadstift" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "opadstift" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "hævdelse" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modellerer" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "sand" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "tvinger" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "tredobbelt lodrette streger med korsbom" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dobbelt lodrette streger med korsbom" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "beviser ikke" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "ikke sand" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "tvinger ikke" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "negeret dobbelt lodrette streger med korsbom" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "kommer før ifølge relation" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "kommer efter ifølge relation" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normal undergruppe af" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "indeholder som normal undergruppe" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normal undergruppe af eller lig med" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "indeholder som normal undergruppe af eller er lig med" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original af" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "billede af" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "miltiafbildning" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitisk konjugeret matrix" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "indskyde" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "eksklusiv eller" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "ikke og" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "ikke eller" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ret vinkel med bue" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "retvinklet trekant" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "diamantoperator" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "prikoperator" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "stjernoperator" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "divisionsgange" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "butterfly" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "venstre normalfaktor halvdirekte produkt" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "højre normalfaktor halvdirekte produkt" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "venstre halvdirekte produkt" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "højre halvdirekte produkt" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "omvendt tilde lig med" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "buet logisk eller" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "buet logisk og" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dobbelt delmængde" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dobbelt overmængde" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dobbelt fællesmængde" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dobbelt foreningsmængde" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "høtyv" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "lig og parallel med" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "mindre end med prik" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "større end med prik" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "langt mindre end" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "langt større end" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "mindre end, lig med eller større end" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "større end, lig med eller mindre end" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "lig med eller mindre end" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "lig med eller større end" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "lig med eller kommer før" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "lig med eller kommer efter" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "kommer ikke før eller er lig med" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "kommer ikke efter eller er lig med" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "ikke kvadratbillede af eller lig med" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "ikke kvadratoriginal af eller lig med" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "kvadratbillede af eller ikke lig med" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "kvadratoriginal af eller ikke lig med" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "mindre end men ikke ækvivalent med" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "større end men ikke ækvivalent med" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "kommer før men er ikke lig med" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "kommer efter men er ikke lig med" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "ikke normal undergruppe af" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "inderholder ikke som normal undergruppe" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "ikke normal undergruppe af eller lig med" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "indeholder ikke som en normal undergruppe eller er lig med" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "lodrette prikker" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "midterlinjeprikker" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "opad til højre diagonalprikker" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "nedad til højre diagonalprikker" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "tilhører med lang vandret gennemstregning" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "tilhører med lodret streg for enden af vandret streg" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "lille tilhører med lodret streg for enden af vandret streg" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "tilhører med prik ovenover" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "tilhører med streg over" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "lille tilhører med streg over" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "tilhører med streg under" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "tilhører med to vandrette streger" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "indeholder med lang vandret gennemstregning" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "indeholder med lodret streg for enden af vandret streg" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "lille indeholder med lodret streg for enden af vandret streg" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "indeholder med streg over" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "lille indeholder med streg over" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "multimængdemedlemsskab i z-notation" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "venstre loft" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "højre loft" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "venstre gulv" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "højre gulv" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "øverst krøllet parentes" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "nederst krøllet parentes" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "venstre vinkelparantes" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "højre vinkelparantes" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "cirklet prik" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "foreningsmængde med prik" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "fællesmængde med plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "firkantet fællesmængde" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "firkantet foreningsmængde" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "sort firkant" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "hvid firkant" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "sort diamant" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "hvid cirkel" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "sort cirkel" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "hvidt punkt" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "sort mellemstor firkant" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s understreget" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s med skråstreg" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s med lodret linje" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "program" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "tom" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "fed" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "bogmærke oprettet" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "bogmærker gemt" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "bogmærker kunne ikke gemmes" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Ingen bogmærker fundet." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Bogmærke ikke fundet." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Videresendelsestilstand slået til." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Kan ikke få fat i lommeregnerens display" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Stil for ord med stort indstillet til ikon." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ingen" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Stil for ord med stort indstillet til ingen." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "stav" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Stil for ord med stort indstillet til stav." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Programmet styrer markøren." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu styrer markøren." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Celle %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s markeret" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s til %s markeret" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s til %s afmarkeret" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s afmarkeret" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Brug ikke tilvalg" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Gennemtving tilvalg" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "TILVALG" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Valgfrie argumenter" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Brug: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Følgende er ikke gyldige: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Udskriv de kørende programmer som er kendt" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Indlæs profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profilen kunne ikke blive indlæst: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Kan ikke starte Cthulhu, fordi der ikke kan oprettes forbindelse til " -"skrivebordet.Kan ikke åbne skærmlæseren idet programmet ikke kan forbinde " -"til skrivebordet." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Kunne ikke aktivere indstillingshåndteringen. Afslutter." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Der kører allerede en anden skærmlæserproces i denne session.\n" -"Kør “cthulhu --replace” for at erstatte den proces med en ny." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAVN" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Brug alternativ mappe til brugerindstillingerne" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "KATALOG" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Programmets version" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Erstat en aktuelt kørende forekomst af Cthulhu" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Vis denne hjælpemeddelelse og afslut" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Send fejlsøgningsinformation til debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Send fejlsøgningsinformation til den angivne fil" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FIL" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Opsætning af brugerindstillinger (tekstversion)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Opsætning af brugerindstillinger (grafisk version)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Indrapporter fejl til https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Klip markering til udklipsholderen." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "klip" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Kopierede markering til udklipsholderen." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopieret" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Indsatte indholdet fra udklipsholderen." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "indsatte" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Bekendtgør ikke når dine venner skriver." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "bekendtgør når dine venner skriver." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Besked fra chatrum %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nyt chatfaneblad %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Oplæs ikke navnet på chatrummet." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "oplæs navnet på chatrummet." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Giv ikke meddelelseshistorik som er chatrumsspecifik." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Giv meddelelseshistorik som er chatrumsspecifik." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "start på sletning" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "slut på sletning" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "start på indsættelse" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "slut på indsættelse" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "start på fremhævning" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "slut på fremhævning" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "slut på forslag" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Slutning af beholder." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Ikke i en beholder." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "alle elementer valgt" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Standardknappen er %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Standardknappen er %s. Inaktiv" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Standardknappen ikke fundet" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " sænket %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " hævet %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Ikke i en dialog" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "hele dokumentet markeret" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "hele dokumentet afmarkeret" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokument valgt fra markørposition" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "dokumentmarkering fjernet fra markørposition" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokument valgt indtil markørposition" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "dokumentmarkering fjernet indtil markørposition" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynamisk kolonneoverskrift sat for række %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynamisk kolonneoverskrift tømt." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynamisk rækkeoverskrift sat for kolonne %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynamisk rækkeoverskrift tømt." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "tom" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobyte" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabyte" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Ingen filer fundet." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Tilføjede indholdet til udklipsholderen." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Kopierede indholdet til udklipsholderen." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Bruger ikke flad gennemgang." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Går i flad gennemgang." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Forlader flad gennemgang." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Flad gennemgang begrænset til det nuværende objekt" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Ubegrænset flad gennemgang" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "har formel" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "åbner dialog" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "åbner gitter" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "åbner rulleliste" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "åbner menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "åbner træstruktur" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "billedkortlink" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Den opgivne tast er allerede bundet til %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tast bundet: %s. Tryk på enter for at bekræfte." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Den nye tast er: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Tastebinding slettet. Tryk på enter for at bekræfte." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Tastebindingen er blevet slettet." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "tryk på ny tast" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tast" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Ekko indstillet til tast." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Intet" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Ekko indstillet til intet." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tast og ord" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Ekko indstillet til tast og ord." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "sætning" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Ekko indstillet til sætning." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "ord" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Ekko indstillet til ord." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "ord og sætning" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Ekko indstillet til ord og sætning." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Indesluttet af: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "et aktuarsymbol" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "en firkant" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "en cirkel" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "et langt divisionstegn" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "et rodtegn" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "en afrundet firkant" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "en vandret gennemstregning" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "en lodret gennemstregning" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "en diagonalt nedadgående udstregning" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "en diagonalt opadgående udstregning" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "en nordøst pil" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "en linje nederst" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "en linje til venstre" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "en linje til højre" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "en linje øverst" - -# Phasor er på Engelsk en ordsammensmeltning af phase vector -# (https://en.wikipedia.org/wiki/Phasor). Jeg ved ikke om en lignende -# sammentrækning findes på dansk, så jeg har defor valgt at oversætte de -# usammentrukne ord. -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "en fasevektor" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "et arabisk fakultettegn" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "og" - -# Denne her ville på dansk være mere natulig som "start brøk", men det virker på -# næste streng som om start skal være der hvor brøken faktisk starter, derfor -# denne oversættelse -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "brøk start" - -# Denne her ville på dansk være mere natulig som "start ... brøk", men det virker som om start skal være der hvor brøken faktisk starter, derfor -# denne oversættelse -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "brøk uden streg start" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "over" - -# se kommentar til fraction start -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "brøk slut" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "kvadratrod af" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "kubikrod af" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "rod af" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "rod start" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "ord slut" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "sænket" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "hævet" - -# Det ved jeg virkelig ikke om der rent faktisk er nogen der kalder det. Men det -# bør tjene sit formål når man har vænnet sig til det. Hvis man rent faktisk -# kalder det noget andet (som jeg har glemt), retter jeg selvfølgelig til. - Kenneth -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "foranstillet sænket" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "foranstillet hævet" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "tekst under" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "tekst over" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "tabel slut" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "indlejret tabel slut" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "utilgængeligt" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Deaktiveret" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Oplæsning af indrykning og justering er deaktiveret." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Aktiveret" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Oplæsning af indrykning og justering er aktiveret." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Tilstanden lær. Tryk på escape for at afslutte." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Går i tilstanden lær. Tryk på en vilkårlig tast for at høre dens funktion. " -"Tryk på F1 for at vise skærmlæserens dokumentation. Tryk på F2 for at få en " -"liste over skærmlæserens standardgenveje. Tryk på F3 for at få en liste over " -"skærmlæserens genveje for det nuværende program. Tryk på escape for at " -"afslutte tilstanden lær." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "forlader blokcitat." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "forlader detaljer." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "forlader nyhedskilde." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "forlader figur." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "forlader formular." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "forlader banner." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "forlader supplerende indhold." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "forlader information." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "forlader hovedindhold." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "forlader navigation." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "forlader region." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "forlader søgning." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "forlader liste." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "forlader panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "forlader tabel." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "forlader værktøjstip." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "forlader resume." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "forlader anerkendelser." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "forlader efterskrift." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "forlader bilag." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "forlader litteraturliste." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "forlader kapitel." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "forlader kolofon." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "forlader konklusion." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "forlader medvirkende." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "forlader medvirkende." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "forlader tilegnelse." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "forlader slutnoter." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "forlader indskrift." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "forlader epilog." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "forlader errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "forlader eksempel." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "forlader forord." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "forlader ordliste." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "forlader indeks." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "forlader introduktion." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "forlader sideliste." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "forlader del." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "forlader forord." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "forlader prolog." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "forlader udtrækscitat." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "forlader SOS." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "forlader forslag." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "forlader indholdsfortegnelse." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "linje valgt ned fra markørposition" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "linje valgt op fra markørposition" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "linjemarkering fjernet fra markørposition og ned" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "linjemarkering fjernet fra markørposition og op" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Afslutter tilstanden lær." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "linje valgt fra start til tidligere markørposition" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "linje valgt til slutningen fra tidligere markørposition" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "link" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "samme side" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "samme websted" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "andet websted" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s link til %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s-link" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "besøgte %s-link" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Benyt pil op og pil ned til at flytte gennem listen. Tryk på escape for at " -"afslutte." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Alle liveområder slået fra" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "indstillinger for høflighedsniveau for liveområder gendannet" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "høflighedsniveau %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "indstiller aktiv region til “hævdende”" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "indstiller aktiv region til “fra”" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "indstiller aktiv region til “høflig”" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "indstiller aktiv region til “uhøflig”" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Overvågning af liveområder er slået fra" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Overvågning af liveområder er slået til" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "ingen aktive meddelelse gemt" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Understøttelse af liveområder er slået fra" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Ikke fundet" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Kunne ikke finde nuværende placering." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "fra" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "til" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "stavet forkert" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Stavefejl: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Sammenhængen er %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Gennemsetilstand" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Fokustilstand" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Tryk på %s for at aktivere fokustilstand." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Fokustilstand er klæbende." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Gennemsetilstand er klæbende." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Layouttilstand." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objekttilstand." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Markøren flyttet til objektet." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Museaktiveret objekt ikke fundet." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Tilstanden musegennemgang deaktiveret." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Tilstanden musegennemgang aktiveret." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Fejl: Kunne ikke oprette liste over objekter." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Ingen underelementer." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Intet næste element." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Intet overelement." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Intet forrige element." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Simplificeret navigation slået til." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Simplificeret navigation slået fra." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Indlejringsniveau %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Nyt element er blevet tilføjet" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Ingen handlinger fundet på: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Intet fokus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Intet program har fokus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Ikke flere blokcitater." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Ikke flere knapper." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Ikke flere afkrydsningsbokse." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Ikke flere store objekter." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Ikke flere klikbare." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Ikke flere kombinationsbokse." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Ikke flere indtastningsfelter." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Ikke flere indtastningsfelter." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Ikke flere overskrifter." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Ikke flere overskrifter på niveau %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Ikke flere interne rammer." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Ikke flere billeder." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Intet kendemærke fundet." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Ikke flere links." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Ikke flere lister." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Ikke flere listeelementer." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Ikke flere liveområder." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Ikke flere afsnit." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Ikke flere radioknapper." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Ikke flere separatorer." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Ikke flere tabeller." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Ikke flere ubesøgte links." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Ikke flere besøgte links." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Ingen markeret tekst." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Ikke på et link." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Underretning" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Nederst" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Øverst" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Ingen underretningsmeddelelser" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "cifre" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Oplæs tal som cifre." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "ord" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Oplæs tal som ord." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "fra" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "til" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Indlæser. Vent venligst." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Færdig med at indlæse." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Færdig med at indlæse %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Side har %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "side valgt fra markørposition" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "side valgt indtil markørposition" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "sidemarkering fjernet fra markørposition" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "sidemarkering fjernet indtil markørposition" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "afsnit valgt fra markørposition og ned" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "afsnit valgt fra markørposition og op" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "afsnitsmarkering fjernet fra markørposition og ned" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "afsnitsmarkering fjernet fra markørposition og op" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Du har allerede en instans af Cthulhu-indstillingsdialogen åben.\n" -"Luk den venligst ned før du starter en ny." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "dias %(position)d af %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil indstillet til %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Ingen profiler fundet." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Statuslinje %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Alle" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Niveau for tegnsætning indstillet til alle." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Fleste" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Niveau for tegnsætning indstillet til flest." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ingen" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Niveau for tegnsætning indstillet til ingen." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Nogle" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Niveau for tegnsætning indstillet til nogle." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Søger." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Søgning fuldført." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu-indstillinger genindlæst." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Markeret tekst er: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Markering slettet." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Markering gendannet." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Tekst afmarkeret." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Størrelse: %d, %d. Placering: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Bredde: %d. Højde: %d. %d fra venstre. %d fra oven." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Tale slået fra." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Tale slået til." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "hurtigere." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "langsommere." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "højere." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "lavere." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "højere." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "blødere." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Hastighed %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Tonehøjde %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Lydstyrke %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher-modul %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher-stemme %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Ingen Speech-dispatcher-moduler tilgængelige" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Ingen Speech-dispatcher-stemmer tilgængelige" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Taleindstillinger gemt" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Taleindstillinger kunne ikke gemmes" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Uddybningsniveau: kortfattet" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Uddybningsniveau: uddybet" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " prik prik prik" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu byder dig velkommen." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu lurer under bølgerne." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Dvaletilstand aktiveret for %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Dvaletilstand deaktiveret for %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Tale er ikke tilgængelig." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Ikke fundet" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Statuslinje ikke fundet" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "streng ikke fundet" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Taster til strukturel navigation er slået fra." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Taster til strukturel navigation er slået til." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Ikke fundet" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Række %(row)d, kolonne %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Slutning af tabel" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Oplæs celle" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Oplæs række" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Ikke ensartet" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Ikke i en tabel." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Kolonner flyttet om" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Rækker flyttet om" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "kolonne %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolonne %(index)d af %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Nederst i kolonne." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Øverst i kolonne." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Kolonne %s markeret" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Kolonne %s til %s markeret" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Kolonne %s til %s afmarkeret" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Kolonne %s afmarkeret" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "række %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "række %(index)d af %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Begyndelse af række." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Slutning på række." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Række slettet." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Sidste række slettet." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Række indsat." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Række tilføjet i slutningen af tabellen." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Række %s markeret" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Række %s til %s markeret" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Række %s til %s afmarkeret" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Række %s afmarkeret" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "markeret" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "afmarkeret" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H timer, %M minutter og %S sekunder" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H timer og %M minutter" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "fortryd" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "omgør" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu version %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "blanke tegn" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Fortsætter fra slutningen." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Fortsætter fra begyndelsen." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elementer" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Cellen spænder over %d række" -msgstr[1] "Cellen spænder over %d rækker" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d kolonne" -msgstr[1] " %d kolonner" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Cellen spænder over %d kolonne" -msgstr[1] "Cellen spænder over %d kolonner" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d tegn for lang" -msgstr[1] "%d tegn for lang" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialog)" -msgstr[1] "(%d dialoger)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d ufokuseret dialog" -msgstr[1] "%d ufokuserede dialoger" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fil fundet" -msgstr[1] "%d filer fundet" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formular" -msgstr[1] "%d formularer" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d overskrift" -msgstr[1] "%d overskrifter" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d element" -msgstr[1] "%d elementer" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d kendemærke" -msgstr[1] "%d kendemærker" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d element fundet" -msgstr[1] "%d elementer fundet" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Forlader %d blokcitat." -msgstr[1] "Forlader %d blokcitater." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Forlader %d liste." -msgstr[1] "Forlader %d lister." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Liste af ukendt størrelse" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Liste med %d element" -msgstr[1] "Liste med %d elementer" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Nyhedskilde af ukendt størrelse" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Nyhedskilde med %d artikel" -msgstr[1] "Nyhedskilde med %d artikler" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Beskrivelsesliste med %d term" -msgstr[1] "Beskrivelsesliste med %d termer" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d værdi" -msgstr[1] "%d værdier" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "matematiktabel med %d række" -msgstr[1] "matematiktabel med %d rækker" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d kolonne" -msgstr[1] "%d kolonner" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "indlejret matematiktabel med %d række" -msgstr[1] "indlejret matematiktabel med %d rækker" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d meddelelse\n" -msgstr[1] "%d meddelelser\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d procent." -msgstr[1] "%d procent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d procent af dokumentet læst" -msgstr[1] "%d procent af dokumentet læst" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixels" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s-tegn" -msgstr[1] "%(count)d %(repeatChar)s-tegn" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d af %(total)d element valgt" -msgstr[1] "%(index)d af %(total)d elementer valgt" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Fandt %d standardgenvej for skærmlæser." -msgstr[1] "Fandt %d standardgenveje for skærmlæser." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Fandt %(count)d genvej for skærmlæser til %(application)s." -msgstr[1] "Fandt %(count)d genveje for skærmlæser til %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d mellemrum" -msgstr[1] "%d mellemrum" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulatorstop" -msgstr[1] "%d tabulatorstop" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabel" -msgstr[1] "%d tabeller" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabel af ukendt størrelse" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabel med %d kolonne, antal rækker ukendt" -msgstr[1] "tabel med %d kolonner, antal rækker ukendt" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabel med %d række, antal kolonner ukendt" -msgstr[1] "tabel med %d rækker, antal kolonner ukendt" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabel med %d række" -msgstr[1] "tabel med %d rækker" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d sekund siden" -msgstr[1] "%d sekunder siden" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minut siden" -msgstr[1] "%d minutter siden" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d time siden" -msgstr[1] "%d timer siden" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d dag siden" -msgstr[1] "%d dage siden" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d ubesøgt link" -msgstr[1] "%d ubesøgte links" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d besøgt link" -msgstr[1] "%d besøgte links" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "slå til/fra" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "ved %(index)d af %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d af %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "element %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVEAU %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "træniveau %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TRÆNIVEAU %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detaljer for %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "har detaljer i %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "forslag" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "redigérbar kombinationsboks" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "redigerbart indhold" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "nyhedskilde" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figur" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "resume" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "anerkendelser" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "efterskrift" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "bilag" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "litteraturlisteelement" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "litteraturliste" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "kapitel" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "kolofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "konklusion" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "omslag" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "medvirkende" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "medvirkende" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "tilegnelse" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "slutnote" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "slutnoter" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "indskrift" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "eksempel" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "forord" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "ordliste" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "indeks" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introduktion" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "sideskift" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "sideliste" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "del" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "forord" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "udtrækscitat" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "SOS" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "undertitel" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "indholdsfortegnelse" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "o%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s niveau %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "vandret rullebjælke" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "lodret rullebjælke" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "vandret skyder" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "lodret skyder" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "vandret opdeler" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "lodret opdeler" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "kontakt" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Ikonpanel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "banner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "supplerende indhold" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "information" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "hovedindhold" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigation" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "region" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "søg" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "besøgt link" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "menuknap" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "sorteret stigende" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "sorteret faldende" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "sorteret" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klikbar" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "slået sammen" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "udvidet" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "har lang beskrivelse" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "vandret" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "lodret" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "tilvalgt" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "fravalgt" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "til" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "fra" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "delvist tilvalgt" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "trykket" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ikke trykket" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "ikke valgt" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "valgt" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ikke valgt" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "ikke valgt" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "besøgt" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "ubesøgt" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "inaktiveret" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "skrivebeskyttet" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "skrbesk" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "påkrævet" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "flervalgsliste" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "ugyldig indtastning" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "ugyldig" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ugyldig stavning" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "stavning" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "ugyldig grammatik" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "grammatik" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Find" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Skærmlæserens dialog Find" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Luk" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Søg" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "Søg _efter:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Søg efter:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Øverst i vindue" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Øverst i vindue" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Start fra:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Forfra når slutningen er nået" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Søg _baglæns" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Søgeretning:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Forskel på store/små _bogstaver" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Søg kun efter h_ele ord" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Indstillinger:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Standard" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Store bogstaver" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "System" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Program" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Vindue" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu-indstillinger" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Hjælp" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Anvend" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Bærbar" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Tastaturlayout" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Ak_tive profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Opstartsprofil:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Indlæs" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "_Gem som" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Fjern" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiler" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Præsenter _værktøjstips" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Oplæs objekt _under mus" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Mus" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Format for _klokkeslæt:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Format for _dato:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Klokkeslæt og dato" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Oplæs o_pdateringer" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Punktskrift ved opdateringer" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Interval (sek.):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Gælder for:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Bi_p ved opdateringer" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Opdateringer af statuslinjer" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Aktivér spo_l tilbage og spol fremad i Oplæs Alt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Aktivér _strukturel navigation i Oplæs Alt" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Oplæs A_lt:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Bekendtgør blok_citater i Oplæs Alt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Bekendtgør l_ister i Oplæs Alt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Bekendtgør _tabeller i Oplæs Alt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Bekendtgør _paneler i Oplæs Alt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Bekendtgør _formularer i Oplæs Alt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Bekendtgør kendem_ærker i Oplæs Alt" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Oplæs Alt" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Element_præsentation:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Generelt" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Lydstyrke:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Tonehøj_de:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "Hast_ighed:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "P_erson:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "Sp_rog:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Talesynthesi_zer:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Talesystem:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Stemmetype:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Stil _for ord med stort:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Indstillinger for stemmetype" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Oplæs strenge med en _blanding af store og små bogstaver som ord" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Oplæs tal som _cifre" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Globale indstillinger for stemme" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Stemme" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Aktivér _tale" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Uddybe_t" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Uddybningsniveau" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "All_e" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Tegnsætningsniveau" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Oplæs kun viste tekst" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Oplæs tomme linjer" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Oplæs _indrykning og justering" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Oplæs ob_jektets genvejstaster" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Oplæs placeringen af _underpunkt" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Oplæs vejledende meddelelser" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Systemmeddelelser er detaljerede" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Oplæs fa_rver som navne" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "_Bekendtgør blokcitater under navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "_Bekendtgør lister under navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "_Bekendtgør tabeller under navigation" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Oplæs markør for _stavefejl" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "_Bekendtgør paneler under navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "_Bekendtgør kendemærker under navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "_Bekendtgør formularer under navigation" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Oplæs _beskrivelse" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Oplæs hele rækker i _regneark" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Oplæs hele rækker i tabeller i _dokumenter" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Oplæs hele rækker i tabeller i _brugerflade" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Kontekst for oplæsning" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Tale" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Aktivér understøttelse af punktskrift" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Forkortede rollenavne" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Deaktivér _linjeafslutningstegn" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "For_kortelsestabel:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Aktivér forkortet _punktskrift" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Aktivér ombrydning af o_rd" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Indstillinger for displays" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Ingen" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indikator for markering" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indikator for hyperlink" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Aktivér øjebliks_meddelelser" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Varigh_ed (sek.):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Meddelelser er _vedvarende" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Meddelelser er _detaljerede" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Indstillinger for øjebliksmeddelelser" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Punktskrift" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Aktivér _tasteekko" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Aktivér a_lfabetiske taster" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Aktivér n_umeriske taster" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Aktivér te_gnsætningstaster" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Aktivér _mellemrum" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Aktivér _ændringstaster" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Aktivér _funktionstaster" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Aktivér handl_ingstaster" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Aktivér na_vigationstaster" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Aktivér _ekko et ord ad gangen" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Aktivér _ekko en sætning ad gangen" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Ekko" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "_Ændringstaster for skærmlæser:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Tastebindinger" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Udtaleordbog" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Ny _indtastning" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Slet" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Udtale" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Oplæs alt" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Oplæs _intet" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "N_ulstil" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Tekstattributter" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Flyt n_ederst" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Flyt én ne_d" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Flyt én o_p" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Flyt _øverst" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Tilpas valgte attribut" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indikator for punktskrift" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Tekstattributter" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Aktiver AI-assistent" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Udbyder:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokal - Gratis)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API-_nøglefil:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Sti til API-nøglefil" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Hent _Claude API-nøgle" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Åbn browser for at hente Claude API-nøgle og gem automatisk" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Kræv bekræftelse før AI-handlinger" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama-_model:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Modelnavn for Ollama (f.eks. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama-_slutpunkt:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API-slutpunkt-URL (f.eks. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Skærmbillede-_kvalitet:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Lav" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Medium" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Høj" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI-assistent" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Sprogkode:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Skaleringsfaktor:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Gråtonebillede" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Inverter billede" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Sort-hvid billede" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Sort/hvid-_tærskel:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analyser farver" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Kopier resultater til _udklipsholder" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu, æ : " -"ægir, ø : ødis, å : åse" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "baggrundsfarve" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "baggrund fuld højde" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "baggrunds“prikbillede”" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "retning" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "redigérbar" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "familienavn" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "forgrundsfarve" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "forgrunds“prikbillede”" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "skrifttypeeffekt" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indrykning" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "fejl" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "usynlig" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justering" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "sprog" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "venstre margen" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "linjehøjde" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "afsnitsstil" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixels over linjer" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixels under linjer" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixels inden i ombrydning" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "højre margen" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "hævning" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "skalering" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "størrelse" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "udstrækning" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "gennemstregning" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "tekstdekoration" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "tekstrotation" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "tekstskygge" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "understreget" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "lodret stilling" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "vægt" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "ombrydningstilstand" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "skrivetilstand" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "sand" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falsk" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ingen" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "indgravere" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "præge" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "omrids" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "overlinje" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "linje igennem" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "blink" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "sort" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "enkelt" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dobbelt" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "lav" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "tegn" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "ord" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "ordtegn" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "vth" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "htv" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "venstre" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "højre" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centreret" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "ingen justering" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "fyld ud" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra kondenseret" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "ekstra kondenseret" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "kondenseret" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "halvkondenseret" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "halvudvidet" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "udvidet" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "ekstra udvidet" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra udvidet" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "kapitæler" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "skrå" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kursiv" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Standard" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Tekstkrop" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Overskrift" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "basislinje" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sænket" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "hævet" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "øverst" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "tekst-øverst" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "midt" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "nederst" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "tekst-nederst" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "nedarv" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "vh-øn" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "hv-øn" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "øn-hv" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "øn-vh" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "nø-hv" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "nø-vh" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "vh" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "hv" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "øn" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "fuldt optegnet" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "stavning" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Tryk på mellemrumstast for at ændre tilstand." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Tryk på mellemrumstast for at udvide, og brug op og ned for at vælge et " -"element." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Tryk på alt+f6 for at give fokus til undervinduer." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Brug piletaster eller søg ved at påbegynde skrivning for at flytte til " -"elementer." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Tryk på alt+f1 for at få adgang til systemets menuer." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Brug op eller ned for at vælge et element." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Tryk på skift plus venstre for at folde sammen." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Tryk på skift plus højre for at folde ud." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Tryk på retur for at aktivere." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Skriv tekst." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Brug venstre og højre for at se andre faneblade." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Tryk på mellemrumstast for at aktivere." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Brug op eller ned pil for at vælge en værdi eller skriv den ønskede " -"numeriske værdi." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Brug piletaster for at ændre." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Tryk på venstre eller højre pil for at navigere. Tryk på op eller ned pil " -"for at gå igennem elementer." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Tryk på højre pil for at gå ind i undermenu." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Tryk på venstre pil for at formindske, tryk på højre pil for at forøge. Tryk " -"på home for at gå til minimum og tryk på end for at gå til maksimum." diff --git a/po/de.po b/po/de.po deleted file mode 100644 index a6d7060..0000000 --- a/po/de.po +++ /dev/null @@ -1,9292 +0,0 @@ -# German translation of cthulhu. -# Copyright (C) 2004 THE cthulhu'S COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# # -# # Manche Übersetzung erscheint vielleicht ungewöhnlich, ist aber -# # so wesentlich besser für die Sprachausgabe. -# # -# # Link - Link -# # Present - ausgeben (entweder Vorlesen oder in Braille anzeigen) -# # -# Hendrik Brandt , 2004-2006. -# Hendrik Richter , 2006, 2007. -# Jochen Skulj , 2007, 2008. -# Simon Bienlein , 2008-2013. -# Mario Blättermann , 2010-2011, 2013, 2016-2017. -# Wolfgang Stöggl , 2011-2013, 2015. -# Hendrik Knackstedt , 2012. -# Benjamin Steinwender , 2014. -# Christian Kirbach , 2009-2013, 2017. -# Tim Sabsch , 2018-2021, 2023. -# Philipp Kiemle , 2022-2023. -# Jürgen Benvenuti , 2022. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-29 20:13+0200\n" -"Last-Translator: Philipp Kiemle \n" -"Language-Team: German \n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.3.2\n" -"X-Project-Style: gnome\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu-Bildschirmleser" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "bildschirm;leser;barrierefreiheit;sprache;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "rmn" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "Einwahl" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "font" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "Formular" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "knpf" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "baum" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "kopf" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Tschechisch Grad 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spanisch Grad 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanada-Französisch Grad 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Frankreich-Französisch Grad 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Lettisch Grad 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Niederlande-Niederländisch Grad 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norwegisch Grad 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norwegisch Grad 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norwegisch Grad 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norwegisch Grad 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polnisch Grad 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugiesisch Grad 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Schwedisch Grad 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabisch Grad 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Walisisch Grad 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Walisisch Grad 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Deutsche Basisschrift" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Deutsche Vollschrift" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Deutsche Kurzschrift" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Britisches Englisch Kurzschrift" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Britisches Englisch Basisschrift" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "US-Englisch Basisschrift" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "US-Englisch Kurzschrift" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanada-Französisch Grad 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Frankreich-Französisch Grad 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Griechisch Grad 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi Grad 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ungarisch 8-Punkt-Rechner" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Ungarisch Grad 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Ungarisch Grad 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italienisch Grad 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgien-Niederländisch Grad 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "Leerzeichen" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "neue Zeile" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "Tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "Ausrufezeichen" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "Anführungszeichen" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "Nummer" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "Dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "Prozent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "und" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "Apostroph" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "runde Klammer auf" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "runde Klammer zu" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "Stern" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "Plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "Komma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "Bindestrich" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "Punkt" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "Schrägstrich" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "Doppelpunkt" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "Semikolon" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "kleiner als" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "gleich" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "größer als" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "Fragezeichen" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "eckige Klammer auf" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "umgekehrter Schrägstrich" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "eckige Klammer zu" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "hoch" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "Unterstrich" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "Gravis" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "geschweifte Klammer auf" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "Vertikale Linie" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "geschweifte Klammer zu" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "Tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "Geschütztes Leerzeichen" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "Einleitendes Ausrufezeichen" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "Cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "Pfund" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "Währungssymbol" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "Yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "Unterbrochene vertikale Linie" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "Abschnitt" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "Diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "Copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "hochgestelltes a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "einleitendes französisches Anführungszeichen" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "Logische Negation" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "Silbentrennungsstrich" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registriert" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "Macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "Grad" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "hoch zwei" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "hoch drei" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "Akut" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "my" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "Absatzzeichen" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "Mittelpunkt" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "Zedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "hoch 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "schließendes französisches Anführungszeichen" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "ein Viertel" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "ein Halb" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "Drei Viertel" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "Einleitendes Fragezeichen" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a Akut" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A Gravis" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A Akut" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A Zirkumflex" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A Tilde" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A Umlaut" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A Kreisakzent" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C Zedilla" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E Gravis" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E Akut" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E Zirkumflex" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E Umlaut" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I Gravis" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I Akut" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I Zircumflex" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N Tilde" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O Gravis" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O Akut" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O Zirkumflex" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O Tilde" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O Umlaut" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "multipliziert" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O Schrägstrich" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U Gravis" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U Akut" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U Zirkumflex" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U Umlaut" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y Akut" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "Eszett" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a Gravis" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a Zirkumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a Tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a Umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a Kreisakzent" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c Zedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e Gravis" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e Akut" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e Zirkumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e Umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i Gravis" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i Akut" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i Zirkumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i Umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n Tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o Gravis" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o Akut" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o Zirkumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o Tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o Umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "durch" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o Schrägstrich" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u akut" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u Gravis" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u Zirkumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u U+00a4" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y Akut" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y Umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "Florinzeichen" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "lang gezogener Bindestrich" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "Linkes einfaches Anführungszeichen" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "Rechtes einfaches Anführungszeichen" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "einfaches Anführungszeichen" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "linkes Anführungszeichen" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "rechtes Anführungszeichen" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "doppeltes Anführungszeichen" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "Kreuz" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "Doppelkreuz" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "Aufzählungspunkt" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "Aufzählungspfeil" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "Promille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "Minute" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "Sekunde" - -# https://de.wikipedia.org/wiki/Prime_%28Typografie%29 -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "Dreistrich" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "Aufzählungstrennstich" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "Euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "Trademark" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "Haken" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "fett gedruckter Haken" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "X-Aufzählungszeichen" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "hoch 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "hoch 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "hoch 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "hoch 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "hoch 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "hoch 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "hoch 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "hoch Pluszeichen" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "hoch Minuszeichen" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "hoch Gleichheitszeichen" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "hoch runde Klammer auf" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "hoch runde Klammer zu" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "hoch n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "tief 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "tief 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "tief 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "tief 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "tief 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "tief 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "tief 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "tief 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "tief 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "tief 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "tief Pluszeichen" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "tief Minuszeichen" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "tief Gleichheitszeichen" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "tief runde Klammer auf" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "tief runde Klammer zu" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "Schwarzes Quadrat" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "Schwarze Raute" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "Objektersetzungszeichen" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Den Zeiger auf das aktuelle Objekt setzen" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Einen Linksklick auf das aktuelle Objekt in der Übersicht ausführen" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Einen Rechtsklick auf das aktuelle Objekt in der Übersicht ausführen" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Das gesamte Dokument vorlesen" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Das gesamte Fenster in der Übersicht vorlesen" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Führt die einfache Lesezeichen Funktion aus" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Führt die detaillierte Lesezeichen Funktion aus" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Die aktuelle Auswahl vorlesen" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Details zum Link vorlesen" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Den Standardknopf ausgeben" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Statuszeile ausgeben" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Titelzeile ausgeben" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Suchdialog öffnen" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Aktionsliste anzeigen" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Nach dem nächsten Auftreten einer Zeichenkette suchen" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Nach dem vorherigen Auftreten einer Zeichenkette suchen" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Die Übersicht betreten und verlassen" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" -"Flache Ansicht auf aktuelles Objekt beschränken umschaltenEinschränken der " -"Übersicht auf das aktuelle Objekt ein- oder ausschalten" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Die Übersicht zur Ausgangsposition bewegen" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Die Übersicht zur letzten Position bewegen" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Die Übersicht zum Anfang der vorherigen Zeile bewegen" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Die aktuelle Zeile vorlesen" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Die aktuelle Zeile in der Übersicht buchstabieren" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Die aktuelle Zeile in der Übersicht phonetisch buchstabieren" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Die Übersicht zum Anfang der nächsten Zeile bewegen" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Die Übersicht zum vorherigen Eintrag oder Wort bewegen" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Den aktuellen Eintrag oder das aktuelle Wort in der Übersicht vorlesen" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" -"Den aktuellen Eintrag oder das aktuelle Wort in der Übersicht buchstabieren" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Den aktuellen Eintrag oder das aktuelle Wort in der Übersicht phonetisch " -"buchstabieren" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Die Übersicht zum nächsten Eintrag oder Wort bewegen" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Die Übersicht zum Wort, das über dem aktuellen liegt, bewegen" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Das aktuelle Objekt in der Übersicht vorlesen" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Die Übersicht zum Wort, das unter dem aktuellen liegt, bewegen" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Die Übersicht zum vorherigen Zeichen bewegen" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Das aktuelle Zeichen in der Übersicht vorlesen" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Das aktuelle Zeichen in der Übersicht phonetisch vorlesen" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Den Unicode-Wert des aktuellen Zeichens in der Übersicht vorlesen" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Die Übersicht zum nächsten Zeichen bewegen" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Die Übersicht zum Zeilenende bewegen" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Die Übersicht nach unten links bewegen" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Den Inhalt der Übersicht in die Zwischenablage kopieren" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Den Inhalt der Übersicht an die Zwischenablage anhängen" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Inhalte der Übersicht anzeigen" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Zwischen dem Lesen der aktuellen Tabellenzelle oder der gesamten Zeile " -"wechseln" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Die Attribute des aktuellen Textzeichens lesen" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Die Braille-Anzeige nach links setzen" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Die Braille-Anzeige nach rechts setzen" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Zum Objekt das den Fokus der Tastatur hat zurückkehren" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Die Kurzschriftübersetzung ein- und ausschalten" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Cursor-Routing ausführen" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Den Beginn der Markierung bestimmen" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Das Ende der Markierung bestimmen" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Startet den Lernmodus. Drücken Sie zum Verlassen des Lernmodus die Escape-" -"Taste" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Sprechtempo verlangsamen" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Sprechtempo erhöhen" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Die Stimmhöhe verringern" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Die Stimmhöhe erhöhen" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Die Sprachlautstärke erhöhen" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Die Sprachlautstärke verringern" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Vorherige Spracheinstellung auswählen" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Nächste Spracheinstellung auswählen" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Aktuelle Spracheinstellung verringern" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Aktuelle Spracheinstellung erhöhen" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Spracheinstellungen speichern" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Sprachausgabe ein-/ausschalten" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Umschalten der Ausführlichkeit" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Schlafmodus umschalten" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Den Bildschirmleser beenden" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Den Dialog zum Bearbeiten der Einstellungen anzeigen" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" -"Den Dialog zum Bearbeiten der Einstellungen für die aktuelle Anwendung " -"anzeigen" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Vorlesen von Einrückungen und Ausrichtung ein-/ausschalten" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Die Art und Weise ändern, wie Zahlen vorgelesen werden" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Zur nächsten Stufe der Sonderzeichenansage wechseln" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Zum nächsten Sprachsynthesizer wechseln" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Zum nächsten Einstellungsprofil wechseln" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Zum nächsten Großschreibungsstil wechseln" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Zur nächsten Stufe des Tastaturechos wechseln" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Den Fehlerüberprüfungsgrad zur Laufzeit anpassen" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Die aktuelle Position als Lesezeichen speichern" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Zum vorherigen Lesezeichenort bewegen" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Zum Lesezeichen bewegen" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Zum nächsten Lesezeichenort bewegen" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Lesezeichen hinzufügen" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Lesezeichen speichern" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Maus-Sprachauswertung ein-/ausschalten" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Aktuelle Uhrzeit ausgeben" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Aktuelles Datum ausgeben" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Aktuelle Größe und Ort des derzeitigen Objekts ausgeben" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Nächsten Befehl an das momentane Programm weiterleiten" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Eine vorhergehende Chat-Nachricht vorlesen und auf Braille ausgeben" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Das Ankündigen, wenn unsere Kontakte etwas eingeben, ein-/ausschalten" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Festlegen, ob Chatraum-bezogenen Nachrichtenverläufe bereitgestellt werden" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Festlegen, ob Nachrichten in Chat-Räumen mit deren Namen versehen werden" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linie Links" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linie Rechts" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linie Oben" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linie Unten" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Einfrieren" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Oben Links" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Unten Links" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Cursorposition" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "6 Punkt Braille" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Cursor-Routing" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Auswahl beginnen" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Text kopieren" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Letzte Benachrichtigung ausgeben" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Liste der Benachrichtigungen ausgeben" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Vorherige Benachrichtigung ausgeben" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Nächste Benachrichtigung ausgeben" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Zum nächsten Zeichen bewegen" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Zum vorherigen Zeichen bewegen" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Zum nächsten Wort bewegen" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Zum vorherigen Wort bewegen" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Zur nächsten Zeile bewegen" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Zur vorherigen Zeile bewegen" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Zum Anfang der Datei bewegen" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Zum Ende der Datei bewegen" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Zum Anfang der Zeile bewegen" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Zum Ende der Zeile bewegen" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Zum nächsten Objekt bewegen" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Zum vorherigen Objekt bewegen" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Kombiniertes Auswahlfeld ausklappen" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Zwischen der ursprünglichen und der Bildschirmleser-Navigation wechseln" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Erweiterte Höflichkeitseinstellungen für dynamische Bereiche" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" -"Standardmäßige Höflichkeitseinstellungen für dynamische Bereiche ausschalten" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Ankündigungen des dynamischen Bereiches erneut betrachten" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Dynamische Bereiche überwachen" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Den Fokus in das aktuelle Mouse-Over und zurückbewegen" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Diese Zeile für dynamische Spaltenüberschriften verwenden" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Die zugewiesenen Spaltenüberschriften löschen" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Diese Spalte für dynamische Zeilenüberschriften verwenden" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Die zugewiesene Zeilenüberschriften löschen" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Inhalt der Eingabezeile ausgeben" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Navigationstasten ein- oder ausschalten" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Zum vorherigen Zitat bewegen" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Zum nächsten Zitat bewegen" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Eine Liste von Zitatfeldern anzeigen" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Zum vorherigen Knopf bewegen" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Zum nächsten Knopf bewegen" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Eine Liste von Knöpfen anzeigen" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Zum vorherigen Ankreuzfeld bewegen" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Zum nächsten Ankreuzfeld bewegen" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Eine Liste von Ankreuzfeldern anzeigen" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Zum vorherigen Klickelement bewegen" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Zum nächsten Klickelement bewegen" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Eine Liste von Klick-Element anzeigen" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Zum vorherigen kombinierten Auswahlfeld bewegen" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Zum nächsten kombinierten Auswahlfeld bewegen" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Zum Anfang des Containers bewegen" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Zum Ende des Containers bewegen" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Eine Liste von Auswahlfeldern anzeigen" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Zum vorherigen Eingabefeld bewegen" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Zum nächsten Eingabefeld bewegen" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Eine Liste von Einträgen anzeigen" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Zum vorherigen Formularfeld bewegen" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Zum nächsten Formularfeld bewegen" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Eine Liste von Formularfeldern anzeigen" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Zur vorherigen Überschrift bewegen" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Zur nächsten Überschrift bewegen" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Eine Liste von Überschriften anzeigen" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Zur vorherigen Überschrift der Ebene %d bewegen" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Zur nächsten Überschrift der Ebene %d bewegen" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Eine Liste der Überschriften der Ebene %d anzeigen" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Zum vorherigen inneren Rahmen bewegen" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Zum nächsten inneren Rahmen bewegen" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Eine Liste von inneren Rahmen anzeigen" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Zum vorherigen Bild bewegen" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Zum nächsten Bild bewegen" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Eine Liste von Bildern anzeigen" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Zum vorherigen Orientierungspunkt bewegen" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Zum nächsten Orientierungspunkt bewegen" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Eine Liste von Orientierungspunkten anzeigen" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Zum vorherigen größeren Objekt bewegen" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Zum nächsten größeren Objekt bewegen" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Eine Liste von größeren Objekten anzeigen" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Zum vorherigen Link bewegen" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Zum nächsten Link bewegen" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Eine Liste von Links anzeigen" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Zur vorherigen Liste bewegen" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Zur nächsten Liste bewegen" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Eine Liste von Listen anzeigen" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Zum vorherigen Listeneintrag bewegen" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Zum nächsten Listeneintrag bewegen" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Eine Liste von Listenobjekten anzeigen" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Zum vorherigen dynamischen Bereich bewegen" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Zum nächsten dynamischen Bereich bewegen" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Zum letzten dynamischen Bereich springen, der eine Ankündigung ausgab" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Zum übergeordneten Element des Objekts mit Navigationsfokus bewegen." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Zum ersten Unterelement des Objekts mit Navigationsfokus bewegen." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" -"Zum nächsten Element ausgehend vom Objekt mit Navigationsfokus bewegen." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" -"Zum vorherigen Element ausgehend vom Objekt mit Navigationsfokus bewegen." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Auf das Objekt mit Navigationsfokus klicken." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Vereinfachte Objektnavigation ein- oder ausschalten." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Zum vorherigen Absatz bewegen" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Zum nächsten Absatz bewegen" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Eine Liste von Absätzen anzeigen" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Zum vorherigen Auswahlknopf bewegen" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Zum nächsten Auswahlknopf bewegen" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Eine Liste von Auswahlknöpfen anzeigen" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Zum vorherigen Trenner bewegen" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Zum nächsten Trenner bewegen" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Zur vorherigen Tabelle bewegen" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Zur nächsten Tabelle bewegen" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Eine Liste von Tabellen anzeigen" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Eine Zelle nach unten bewegen" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Zur ersten Zelle in einer Tabelle bewegen" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Zur letzten Zelle in einer Tabelle bewegen" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Eine Zelle nach links bewegen" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Eine Zelle nach rechts bewegen" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Eine Zelle nach oben bewegen" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Layout-Modus ein-/ausschalten" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Zwischen Stöbern-Modus und Fokus-Modus wechseln" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Dauerhaften Fokus-Modus aktivieren" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Dauerhaften Stöber-Modus aktivieren" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Zum vorherigen nicht besuchten Link bewegen" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Zum nächsten nicht besuchten Link bewegen" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Eine Liste nicht besuchter Links anzeigen" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Zum vorherigen besuchten Link bewegen" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Zum nächsten besuchten Link bewegen" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Eine Liste besuchter Links anzeigen" - -# http://www.code-knacker.de/farbnamen.htm -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "eisfarben" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "Antikweiß" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "Aquamarinblau" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "Himmelblau" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "Beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "Biskuit" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "Schwarz" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "Mandelweiß" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "Blau" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "Blauviolett" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "Braun" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "Gelbbraun" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "Kadettenblau" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "Hellgrün" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "Schokolade" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "Koralle" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "Kornblumenblau" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "Mais" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "Karmesinrot" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "Türkis" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "Dunkles Blau" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "Dunkeltürkis" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "dunkle Goldrutenfarbe" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "Dunkles Grau" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "Dunkles Grün" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "Dunkelkhaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "Dunkelmagenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "Dunkles Olivgrün" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "dunkles Orange" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "dunkle Orchidee" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "Dunkles Rot" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "dunkle Lachsfarbe" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "Dunkles Meeresgrün" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "Dunkles Schieferblau" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "dunkles Schiefergrau" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "Dunkeltürkis" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "Dunkelviolett" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "Tiefrosa" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "tiefes Himmelblau" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "Dunkelgrau" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "Persenningblau" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "Backstein" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "Blütenweiß" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "Waldgrün" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "Fuchsie" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "Gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "Geisterweiß" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "Gold" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "Goldrute" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "Grau" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "Grün" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "Grüngelb" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "Honigmelone" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "leuchtend Rosa" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "Indischrot" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "Indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "Elfenbein" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "staubfarben" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "Lavendel" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "Lavendelrosa" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "Rasengrün" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "Chiffongelb" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "Helles Blau" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "helles Korallenrot" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "Helles Zyan" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "helles Goldrutengelb" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "Helles Grau" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "Helles Grün" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "Helles Rosa" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "helle Lachsfarbe" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "Helles Meeresgrün" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "Helles Himmelblau" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "helles Schieferblau" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "helles Stahlblau" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "Helles Gelb" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "Limone" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "Limonengrün" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "Leinen" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "Magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "Kastanie" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "mittleres Aquamarin" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "mittleres Blau" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "mittlere Orchidee" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "mittleres Violett" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "mittleres Seegrün" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "Mittleres Schieferblau" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "mittleres Frühlingsgrün" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "mittlere Türkis" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "mittleres Violettrot" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "Mitternachtsblau" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "cremige Minze" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "Altrosa" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "Mokassin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "Navajoweiß" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "Marinenblau" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "alte Spitze" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "Olivgrün" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "Olivgraubraun" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "Orange" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "Orangerot" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "Orchidee" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "blasse Goldrutenfarbe" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "Blassgrün" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "Blasstürkis" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "blasses Violettrot" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "Papayacreme" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "Pfirsich" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "Peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "Rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "Pflaume" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "Taubenblau" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "Violett" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "Rot" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rosiges Braun" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "gesättigtes blau" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "Sattelbraun" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "lachsfarben" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "Sandbraun" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "Meeresblau" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "Muschel" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "Siennaerde" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "Silber" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "Himmelblau" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "Schieferblau" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "Schiefergrau" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "Schneeweiß" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "Frühlingsgrün" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "Stahlblau" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "hautfarben" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "Krickentengrün" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "Distel" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "Tomate" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "Türkis" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "Veilchen" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "Weizen" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "Weiß" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "rauchfarben" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "Gelb" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "Gelbgrün" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktivieren" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatischer Fokus-Modus während Strukturnavigation" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatischer Fokus-Modus während Caret-Navigation" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatischer Fokus-Modus während nativer Navigation" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punkt _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punkt _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Punkte 7 un_d 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "A_bbrechen" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Springen zu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ton" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Keine" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Buchstabieren" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Ankündigen, wenn unsere _Kontakte etwas eingeben" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Chatraum-bezogene _Nachrichtenverläufe bereitstellen" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Nachrichten vorlesen aus" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Alle Ka_näle" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Alle Kanäle, wenn ein _beliebiges %s-Fenster aktiv ist" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Einen Kanal nur, wenn dessen _Fenster aktiv ist" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "Chat Room-Name _vorlesen" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Layout-Modus aktivieren" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "Doppelklick" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "Dreifachklick" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Standardsynthesizer" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Aktuelle Zeichenkette" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Ersatzausdruck" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Zeichenweises Echo aktivie_ren" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "_Diakritische Tasten sprechen" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Akt_uelle Position" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimale Länge der Trefferübereinstimmung:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Suchoptionen" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "_Nur unterschiedliche Zeilen während der Suche vorlesen" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Treffer während der _Suche vorlesen" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Befehl" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Tastenkombination" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Vorgabe" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Lernmodus" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Aktionen" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braille-Belegung" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Lesezeichen" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Datum und Uhrzeit" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Maus-Sprachauswertung" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Objektnavigation" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objektdetails" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Nicht zugeordnet" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Übersicht" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Sprache und Ausführlichkeit" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Inhalte der Übersicht" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Geändert" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Desktop" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Benachrichtigungen" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Erhalten" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Benachrichtigungenausgabe" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu-Einstellungen für %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Markierung in Braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Ausgeben außer" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Vorlesen" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Profil als Konflikt speichern" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Konflikt mit Benutzerprofil!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Das Profil %s ist bereits vorhanden.\n" -"Soll das bestehende Profil mit den neuen Änderungen aktualisiert werden?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Benutzerprofil laden" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Das aktive Profil wird nun geändert. Wenn Sie soeben\n" -"Änderungen in Ihren Einstellungen vorgenommen haben, so\n" -"werden diese beim Laden eines Profils verloren gehen.\n" -"\n" -"Soll das Profil geladen und vorherige Änderungen verworfen werden?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Profil speichern unter" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profilname:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Benutzerprofil löschen" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Sie sind dabei, Profil %s zu löschen. All ungesicherten Einstellungen und " -"Einstellungen, die in diesem Profil gesichert sind, gehen dadurch verloren. " -"Möchten Sie fortfahren und dieses Profil und die damit verbundenen " -"Einstellungen löschen?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Alle" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Anwendung" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Fenster" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Keine" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Einige" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Die _meisten" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Zeile" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Satz" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Anführungszeichen" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Knopf" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Beschriftung" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Ankreuzfeld" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Klickbares Element" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kombiniertes Auswahlfeld" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Beschreibung" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Überschrift" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Innerer Rahmen" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Bild" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Bezeichnung" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Orientierungspunkt" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Ebene" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Link" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Listeneintrag" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekt" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Absatz" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Auswahlknopf" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rolle" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Ausgewähltes Objekt" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Status" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "Adresse" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Wert" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Anführungszeichen" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Knöpfe" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Ankreuzfelder" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Klickbare Elemente" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kombinierte Auswahlfelder" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Einträge" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Formularfelder" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Überschriften" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Innere Rahmen" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Bilder" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Überschriften der Ebene %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Orientierungspunkte" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Größere Objekte" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Links" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listen" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Listeneinträge" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Absätze" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Auswahlknöpfe" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabellen" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Nicht besuchte Links" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Besuchte Links" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Seitennavigation" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Vorlesen der Seite automatisch beim ersten _Laden starten" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Zusammenfassung einer Seite beim _ersten Laden ausgeben" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Sprache zwischen Pausen in einzelne _Blöcke aufteilen" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s Standardstimme" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Standard" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Links" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "System" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Großbuchstaben" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Rechtschreibprüfung" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Rechtschreib_fehler" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Rechtschreib_vorschlag" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Fehler_kontext ausgeben" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Zellenkoordinaten in Tabellenblättern vorlesen" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Immer den ausgewählten Tabellenblatt-Bereich vorlesen" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Zellenü_berschrift vorlesen" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Tabellennavigation" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "_Leere Zellen überspringen" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "_Zelle vorlesen" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "_Zellenkoordinaten vorlesen" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "_Zellenausdehnung vorlesen" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Attributname" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Caret-Navigation verwenden" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "_Strukturierte Navigation verwenden" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Klang_design:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Klangdesign" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Kurz" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d Benachrichtigung" -msgstr[1] "%d Benachrichtigungen" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Umschalt" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Strg" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "Umschalt links" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "Alt links" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "Steuerung links" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "Umschalt rechts" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "Alt rechts" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "Steuerung rechts" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "Metataste links" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "Metataste rechts" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "Nummernblock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "Feststelltaste" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "Feststelltaste" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "Bildlauf" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "Bild auf" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "Bild ab" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "Tab links" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "Löschen" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "Enter" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "Eingabe-Taste" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "hoch" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "runter" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "links" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "rechts" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "linke Metataste" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "rechte Metataste" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "Menü" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "Hilfe" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "Multi-Taste" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "Mode Switch-Taste" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "Escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "Einfügen" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "Löschen" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "Pos1" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "Ende" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "Begin-Taste" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "Zirkumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "Kreisakzent" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "Querstrich" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Einfügen" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Feststelltaste" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Strg" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Umschalt" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "fettes %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "kursives %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "fettes kursives %s" - -# https://de.wikipedia.org/wiki/Unicodeblock_Mathematische_alphanumerische_Symbole -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "Schreibschrift %s" - -# Beispiele: -# A fett gedruckt -# 1 fett gedruckt -# Vermeiden: z.B. »fett gedrucktes 8« -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s fett gedruckt" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "Fraktur %s" - -# http://de.wikipedia.org/wiki/Buchstabe_mit_Doppelstrich -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s mit Doppelstrich" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "Fraktur fett %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s ohne Serife" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "fettes %s ohne Serife" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "kursives %s ohne Serife" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "fettes kursives %s ohne Serife" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "dicktengleiches %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s ohne Punkt" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "Pfeil nach links" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "Pfeil nach oben" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "Pfeil nach rechts" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "Pfeil nach unten" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "Pfeil nach links und rechts" - -# https://de.wikipedia.org/wiki/Unicodeblock_Pfeile -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "Pfeil nach oben und unten" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "Pfeil nach Nordwesten" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "Pfeil nach Nordosten" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "Pfeil nach Südosten" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "Pfeil nach links von Querstrich" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "Pfeil nach oben von Querstrich" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "Pfeil nach rechts von Querstrich" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "Pfeil nach unten von Querstrich" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "Dicker Pfeil nach links" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "Dicker Pfeil nach oben" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "Dicker Pfeil nach rechts" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "Dicker Pfeil nach unten" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "Dicker Pfeil nach links und rechts" - -# https://de.wikipedia.org/wiki/Unicodeblock_Pfeile -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "Dicker Pfeil nach oben und unten" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "Dicker Pfeil nach Nordwesten" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "Dicker Pfeil nach Nordosten" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "Dicker Pfeil nach Südosten" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "Dicker Pfeil nach Südwesten" - -# https://de.wikipedia.org/wiki/Unicodeblock_Dingbats -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "Dicker Pfeil nach rechts mit breiter Spitze" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "Dreidimensionaler Pfeil nach rechts, oben weiß" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "Minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "kleiner als" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "größer als" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "Zirkumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "Hatschek" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "Breve" - -# https://de.wikipedia.org/wiki/Punkt_%28Oberzeichen%29 -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "Punkt" - -# https://de.wikipedia.org/wiki/Vertikaler_Doppelstrich -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "Doppelte vertikale Linie" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "waagerechte Auslassungspunkte" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "für alle" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "Komplement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "partielles Differential" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "existiert ein" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "existiert kein" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "leere Menge" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "Delta" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "Nabla" - -# Mengenlehre !? -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "Element aus" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "kein Element aus" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "kleines Element aus" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "enthält als Element" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "enthält nicht als Element" - -# https://de.wikipedia.org/wiki/Unicodeblock_Mathematische_Operatoren -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "kleines umgekehrtes Elementzeichen" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "Beweisende" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "Produkt" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "Koprodukt" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "Summe" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "Minus oder Plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "Plus mit Punkt" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "geteilt durch" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "Differenzmenge" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "mal" - -# z.B. bei Verkettung von Funktionen -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "in" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "Kreis-Operator" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "Quadratwurzel" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "Kubikwurzel" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "vierte Wurzel" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proportional zu" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "Unendlich" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "Rechter Winkel" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "Winkel" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "gemessener Winkel" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "Raumwinkel" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "teilt" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "teilt nicht" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "parallel zu" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "nicht parallel zu" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logisches Und" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logisches Oder" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "Schnittpunkt" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "Vereinigung" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "Integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "doppeltes Integral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "dreifaches Integral" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "Umrissintegral" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "Oberflächenintegral" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "Volumenintegral" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "rechtsläufiges Integral" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "rechtsläufiges Umrissintegral" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "linksläufiges Umrissintegral" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "folglich" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "weil" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "zu" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "Proportion" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "Minus mit Punkt" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "Exzess" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrische Proportion" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "Homothetiezeichen" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "Tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "umgekehrte Tilde" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "invertiertes stummes S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "Sinuswelle" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "Kranzprodukt" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "durchgestrichene Tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "Minus über Tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptotisch gleich zu" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "nicht asymptotisch gleich zu" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "ungefähr gleich zu" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "fast aber nicht wirklich gleich zu" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "nicht fast und nicht wirklich gleich zu" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "beinahe gleich zu" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "nicht beinahe gleich zu" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "beinahe gleich oder gleich zu" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "Dreifachtilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "alles gleich" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "äquivalent" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrisch äquivalent" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "Differenz zwischen" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "Grenzwertannäherung" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrisch gleich zu" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "ungefähr gleich oder Bild von" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "Bild oder ungefähr gleich" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "ist definiert als" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "Gleichheitszeichen mit nachfolgendem Doppelpunkt" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "Kreis im Gleichheitszeichen" - -# ungefähr gleich -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "Kreis über Gleichheitszeichen" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "entspricht" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "ist ungefähr" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "gleichwinklig" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "Gleichheitszeichen mit Stern" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "Gleichheitszeichen mit Delta" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "gleich nach Definition" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "gemessen nach" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "vielleicht gleich" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "ist nicht" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identisch zu" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "nicht identisch zu" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "streng äquivalent zu" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "kleiner oder gleich" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "größer oder gleich" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "kleiner oder gleich" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "größer oder gleich" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "kleiner als, aber nicht gleich" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "größer als, aber nicht gleich" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "viel kleiner als" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "viel größer als" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "zwischen" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "nicht äquivalent" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "nicht kleiner als" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "nicht größer als" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "weder weniger noch gleich" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "weder größer noch gleich" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "kleiner oder gleich" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "größer oder gleich" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "weder kleiner noch gleich" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "weder größer noch gleich" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "weniger oder größer als" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "größer oder kleiner als" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "weder weniger noch größer als" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "weder größer noch kleiner als" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "vorangehend" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "nachfolgend" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "vorangehend oder gleich" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "nachfolgend oder gleich" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "vorangehend oder äquivalent" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "nachfolgend oder äquivalent" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "nicht vorangehend" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "nicht nachfolgend" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "Teilmenge von" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "ist Obermenge von" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "keine Teilmenge von" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "keine Obermenge von" - -# https://de.wikipedia.org/wiki/Mengenlehre -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "Teilmenge von oder gleich" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "Obermenge oder gleich" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "weder Teilmenge von noch gleich" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "weder Obermenge noch gleich" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "Teilmenge mit ungleich" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "Obermenge mit ungleich" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "Multimenge" - -# https://de.wikipedia.org/wiki/Liste_mathematischer_Symbole -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "Vereinigung disjunkter Mengen" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "Multimengenvereinigung" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "viereckiges Bild" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "viereckiges Original" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "viereckiges Bild oder gleich" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "viereckiges Original oder gleich" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "nach unten geöffnetes Viereck" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "nach oben geöffnetes Viereck" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "eingekreistes Pluszeichen" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "eingekreistes Minuszeichen" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "eingekreistes Multiplikationszeichen" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "eingekreister Divisionsstrich" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "eingekreister Punktoperator" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "eingekreister Ringoperator" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "eingekreister Sternoperator" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "eingekreist gleich" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "eingekreister Gedankenstrich" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "eingerahmtes Plus" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "eingerahmtes Minus" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "eingerahmtes Multiplikationszeichen" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "eingerahmter Punktoperator" - -# https://de.wikipedia.org/w/index.php?title=Unicodeblock_Mathematische_Operatoren&stable=1 -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "ergibt" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "ergibt nicht" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "senkrecht von" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "senkrecht zu" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "Annahme" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "Modelle" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "wahr" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "erzwingen" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "dreifache vertikale Leiste mit rechtem Drehkreuz" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "doppelte vertikale Leiste mit doppeltem rechtem Drehkreuz" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "beweist nicht" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "nicht wahr" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "nicht erzwingen" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "negierte doppelte vertikale Leiste mit doppeltem rechten Drehkreuz" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "vorangehend in Relation" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "nachfolgend in Relation" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normale Untergruppe" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "als normale Untergruppe enthalten" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normale Untergruppe oder gleich" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "als normale Untergruppe enthalten oder gleich" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "Original" - -# https://de.wikipedia.org/wiki/Unicodeblock_Mathematische_Operatoren -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "Bild" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "Mehrfachzuordnung" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitesch konjugierte Matrix" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "einschalten" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "ausschließliches oder" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nicht-und" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "noch" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "rechtwinklig zu" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "rechtes Dreieck" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "Rautenoperator" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "Punkt Operator" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "Stern Operator" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "Divisionsanzahl" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "Schleife" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "linkes Normalfaktor halbdirektes Produkt" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "rechtes Normalfaktor halbdirektes Produkt" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "linkes halbdirektes Produkt" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "rechtes halbdirektes Produkt" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "umgekehrte Tilde gleich" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "geschweiftes logisches Oder" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "geschweiftes logisches Und" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "doppelte Teilmenge" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "doppelte Obermenge" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "doppelter Durchschnitt" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "doppelte Vereinigung" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "echter Durchschnitt" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "gleich und parallel" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "kleiner als mit Punkt" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "größer als mit Punkt" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "wesentlich kleiner als" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "wesentlich größer als" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "kleiner als, gleich oder größer als" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "größer als, gleich oder kleiner als" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "kleiner oder gleich" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "größer oder gleich" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "gleich oder vorangehend" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "gleich oder nachfolgend" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "weder vorangehend oder gleich" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "weder nachfolgend oder gleich" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "kein viereckiges Bild oder gleich" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "kein viereckiges Original oder gleich" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "viereckiges Bild oder ungleich" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "viereckiges Original oder ungleich" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "kleiner aber nicht gleich" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "größer aber nicht gleich" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "vorangehend, aber nicht äquivalent" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "nachfolgend, aber nicht äquivalent" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "keine normale Untergruppe" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "nicht als normale Untergruppe enthalten" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "keine normale Untergruppe oder gleich" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "nicht als normale Untergruppe enthalten oder gleich" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertikale Ellipse" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "Zentrierte horizontale Ellipse" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "Diagonale Ellipse, unten links nach oben rechts" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "Diagonale Ellipse, oben links nach unten rechts" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "Element mit langem horizontalen Strich" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "Element mit vertikalem Strich am Ende des horizontalen Strichs" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "kleines Element mit vertikalem Strich am Ende des horizontalen Strichs" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "Element mit Punkt oben" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "Element mit Überstrich" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "kleines Element mit Überstrich" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "Element mit Unterstrich" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "Element mit 2 horizontalen Strichen" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "umgekehrtes Elementzeichen mit langem horizontalen Strich" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" -"umgekehrtes Elementzeichen mit vertikalem Strich am Ende des horizontalen " -"Strichs" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"kleines umgekehrtes Elementzeichen mit vertikalem Strich am Ende des " -"horizontalen Strichs" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "umgekehrtes Elementzeichen mit Überstrich" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "kleines umgekehrtes Elementzeichen mit Überstrich" - -# Original verwendet -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z notation bag membership" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "linke Aufrundungsklammer" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "rechte Aufrundungsklammer" - -# Gaußklammer -# https://de.wikipedia.org/wiki/Unicodeblock_Verschiedene_technische_Zeichen -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "linke Abrundungsklammer" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "linke Abrundungsklammer" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "obere geschweifte Klammer" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "Untere geschweifte Klammer" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "linke Skalarproduktklammer" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "rechte Skalarproduktklammer" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "eingekreister Punkt" - -# https://de.wikipedia.org/wiki/Unicodeblock_Zus%C3%A4tzliche_Mathematische_Operatoren -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "Vereinigung mit Punkt" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "Vereinigung mit Plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "viereckige Schnittmenge" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "viereckige Vereinigung" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "Schwarzes Quadrat" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "Weißes Quadrat" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "Schwarze Raute" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "Weißer Kreis" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "Schwarzer Kreis" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "Weißer Aufzählungspunkt" - -# https://de.wikipedia.org/wiki/Unicodeblock_Geometrische_Formen -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "schwarzes kleines bis mittelgroßes Quadrat" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s mit Unterstrich" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s mit Schrägstrich" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s mit vertikaler Linie" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "Anwendung" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "leer" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "fett" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "Lesezeichen betreten" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "Lesezeichen gespeichert" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "Lesezeichen können nicht gespeichert werden" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Keine Lesezeichen gefunden." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Lesezeichen nicht gefunden." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Umgehungsmodus aktiviert." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Taschenrechneranzeige kann nicht ermittelt werden" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "Klangsymbol" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Großschreibungsstil auf Klangsymbol gesetzt." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "kein" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Großschreibungsstil auf nichts gesetzt." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "Buchstabieren" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Großschreibungsstil auf Buchstabieren gesetzt." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Navigationssteuerung erfolgt durch die Anwendung." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu steuert den Cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Zelle %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s ausgewählt" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s bis %s ausgewählt" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s bis %s nicht mehr ausgewählt" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s nicht mehr ausgewählt" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Verwendung der Option verhindern" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Verwendung der Option erzwingen" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPTION" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Optionale Argumente" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Aufruf: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Die folgenden sind nicht zulässig: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Bekannte Programme ausgeben" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Profil laden" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profil kann nicht geladen werden: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Cthulhu kann nicht gestartet werden, da keine Verbindung zum Desktop " -"hergestellt werden kann.Der Bildschirmleser kann nicht gestartet werden, da " -"keine Verbindung zur Arbeitsumgebung hergestellt werden kann." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" -"Einstellungsmanager konnte nicht aktiviert werden. Programm wird beendet." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Für diese Sitzung läuft bereits ein weiterer Bildschirmleser-Prozess.\n" -"Starten Sie \"cthulhu --replace\", um diesen Prozess durch einen neuen zu " -"ersetzen." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Anderes Verzeichnis für die Benutzereinstellungen verwenden" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "VERZEICHNIS" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Version dieser Anwendung" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Eine derzeit laufende Instanz von Cthulhu ersetzen" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Diese Nachricht anzeigen und beenden" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Fehlerdiagnose speichern unter debug-JJJJ-MM-TT-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Informationen zur Fehlerdiagnose in der angegebenen Datei speichern" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "DATEI" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Benutzereinstellungen einrichten (Textversion)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Benutzereinstellungen einrichten (Graphische Version)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Programmfehler an https://groups.io/g/stormux melden." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Auswahl wurde in Zwischenablage ausgeschnitten." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "ausschneiden" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Auswahl wurde in Zwischenablage kopiert." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopiert" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Inhalt wurde aus Zwischenablage eingefügt." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "eingefügt" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Nicht ankündigen, wenn unsere _Kontakte etwas eingeben." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "Ankündigen, wenn unsere Kontakte etwas eingeben." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Nachricht aus Chatraum %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Neuer Chat-Reiter %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Chatraum-Namen nicht vorlesen." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "Chatraum-Namen vorlesen." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Chatraum-bezogene Nachrichtenverläufe nicht bereitstellen." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Chatraum-bezogene Nachrichtenverläufe bereitstellen." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "Beginn Löschung" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "Löschung Ende" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "Beginn Einfügen" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "Einfügen Ende" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "Beginn Hervorhebung" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "Hervorhebung Ende" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "Vorschlag Ende" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Ende des Containers." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Nicht in einem Container." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "alle Elemente ausgewählt" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Standardknopf ist %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Standardknopf ist %s. Ausgegraut" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Standardknopf nicht gefunden" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " tiefgestellt %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " hochgestellt %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Nicht in einem Dialog" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "das gesamte Dokument ist ausgewählt" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "das gesamte Dokument ist nicht mehr ausgewählt" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "Dokument ab der Cursorposition ausgewählt" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "Dokument ab der Cursorposition nicht ausgewählt" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "Dokument bis zur Cursorposition ausgewählt" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "Dokument bis zur Cursorposition nicht ausgewählt" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Zeile %d für Spaltenüberschriften festgelegt" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Zugewiesene Spaltenüberschrift gelöscht." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Spalte %s für Zeilenüberschrift festgelegt" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Zugewiesene Spaltenüberschrift gelöscht." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "leer" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f Kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f Megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Keine Dateien gefunden." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Inhalt wurde an Zwischenablage angehängt." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Inhalt wurde in Zwischenablage kopiert." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Die Übersicht wird nicht verwendet." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Die Übersicht betreten." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Die Übersicht wird verlassen." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Übersicht auf das aktuelle Objekt eingeschränkt" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Übersicht uneingeschränkt" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "hat Formel" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "öffnet Dialog" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "öffnet Raster" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "öffnet Listenfeld" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "öffnet Menü" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "öffnet Baum" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "Image Map Link" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Die eingegebene Tastenkombination ist bereits %s zugeordnet" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" -"Aufgezeichnete Tastenkombination %s. Drücken Sie Eingabe, um zu bestätigen." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Die neue Tastenkombination ist: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" -"Tastenkombination wurde gelöscht. Drücken Sie Eingabe, um zu bestätigen." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Die Tastenkombination wurde gelöscht." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "Neue Tastenkombination eingeben" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "Taste" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Echo auf Taste gesetzt." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Keine" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Echo deaktiviert." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "Taste und Wort" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Echo auf Taste und Wort gesetzt." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "Satz" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Echo gesetzt auf Satz." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "Wort" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Echo gesetzt auf Wort." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "Wort und Satz" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Echo auf Wort und Satz gesetzt." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Umschlossen von: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "ein actuarial Symbol" - -# Dargestellt: -# https://developer.mozilla.org/en-US/docs/Web/MathML/Element/menclose -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "ein Rahmen" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "ein Kreis" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "ein langes Divisionszeichen" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "eine Wurzel" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "ein abgerundeter Rahmen" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "ein horizontaler Durchstrich" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "ein vertikaler Durchstrich" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "ein Diagonaldurchstrich nach unten" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "ein Diagonaldurchstrich nach oben" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "ein nordost Pfeil" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "eine Linie unten" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "eine Linie links" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "eine Linie rechts" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "eine Linie oben" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "ein Phasorwinkel" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "ein arabisches faktorielles Symbol" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "und" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "Beginn des Bruchs" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "Beginn des Bruchs ohne Querstrich" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "durch" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "Ende des Bruchs" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "Quadratwurzel aus" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "Kubikwurzel aus" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "Wurzel aus" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "Wurzelbeginn" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "Wurzelende" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "tief" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "hochgestellt" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "voran tiefgestellt" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "voran hochgestellt" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "darunter geschrieben" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "darüber geschrieben" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "Tabellenende" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "verschachteltes Tabellenende" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "unzugänglich" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Deaktiviert" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Ansage von Einrückung und Ausrichtung ausgeschaltet." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Aktiviert" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Ansage von Einrückung und Ausrichtung eingeschaltet." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Lernmodus. Drücken Sie zum Verlassen die Escape-Taste." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Der Lernmodus wird gestartet. Drücken Sie eine beliebige Taste, um dessen " -"Funktion zu hören. Um die Dokumentation des Bildschirmlesers anzuzeigen, " -"drücken Sie F1. Um eine Liste der vorgegebenen Tastenkombinationen für den " -"Bildschirmleser zu erhalten, drücken Sie F2. Um eine Liste der für eine " -"Anwendung vorgegebenen Tastenkombinationen zu erhalten, drücken Sie F3. Um " -"den Lernmodus zu beenden, drücken Sie die Escape-Taste." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "Zitat wird verlassen." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "Details werden verlassen." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "Artikelliste wird verlassen." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "Abbildung wird verlassen." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "Formular wird verlassen." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "Banner wird verlassen." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "Ergänzender Inhalt wird verlassen." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "Information wird verlassen." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "Hauptinhalt wird verlassen." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "Navigation wird verlassen." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "Bereich wird verlassen." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "Suche wird verlassen." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "Liste wird verlassen." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "Panel wird verlassen." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "Tabelle wird verlassen." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "Minihilfe wird verlassen." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "Zusammenfassung wird verlassen." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "Danksagungen werden verlassen." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "Nachwort wird verlassen." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "Anhang wird verlassen." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "Bibliografie wird verlassen." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "Kapitel wird verlassen." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "Schlussschrift wird verlassen." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "Schlussfolgerung wird verlassen." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "Danksagung wird verlassen." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "Danksagung wird verlassen." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "Widmung wird verlassen." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "Endnoten werden verlassen." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "Epigraph wird verlassen." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "Epilog wird verlassen." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "Errata werden verlassen." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "Beispiel wird verlassen." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "Vorwort wird verlassen." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "Glossar wird verlassen." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "Index wird verlassen." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "Einführung wird verlassen." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "Seitenliste wird verlassen." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "Teil wird verlassen." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "Einleitung wird verlassen." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "Prolog wird verlassen." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "Zitat wird verlassen." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "Fragen und Antworten werden verlassen." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "Vorschlag wird verlassen." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "Inhaltsverzeichnis wird verlassen." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "Zeile bis herunter zur Cursorposition markiert" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "Zeile bis herauf zur Cursorposition markiert" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "Zeile bis herunter zur Cursorposition nicht markiert" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "Zeile bis herauf zur Cursorposition nicht markiert" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Lernmodus wird verlassen." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "Zeile vom Anfang bis zur vorherigen Cursorposition markiert" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "Zeile von der vorherigen Cursorposition bis zum Ende markiert" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "Link" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "Die selbe Seite" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "Die selbe Website" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "Andere Website" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s Link auf %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s Link" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "Besuchter %s-Link" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Verwenden Sie Pfeil hoch und runter, um in der Liste zu navigieren. Drücken " -"Sie Escape zum Verlassen." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Alle dynamischen Bereiche ausgeschaltet" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "Höflichkeitseinstellungen für dynamische Bereiche wiederhergestellt" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "Höflichkeitsstufe %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "Dynamischer Bereich auf bestimmend eingestellt" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "Höflichkeitseinstellungen für den dynamischen Bereich ausgeschaltet" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "Dynamischer Bereich auf höflich eingestellt" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "Dynamischer Bereich auf unhöflich eingestellt" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Überwachung der dynamischen Bereiche ist ausgeschaltet" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Überwachung der dynamischen Bereiche ist eingeschaltet" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "Keine dynamischen Meldungen gespeichert" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Unterstützung für dynamische Bereiche ist ausgeschaltet" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nicht gefunden" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Aktuelle Position konnte nicht gefunden werden." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "aus" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "an" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "falsch geschrieben" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Falsch geschriebenes Wort: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Kontext ist %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Stöbern-Modus" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Fokus-Modus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Drücken Sie %s zum Aktivieren des Fokus-Modus." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Dauerhafter Fokus-Modus." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Dauerhafter Stöber-Modus." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Layout-Modus." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objekt-Modus." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Mauszeiger wurde zum Objekt bewegt." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Kein Mouse-Over Objekt gefunden." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Maus-Sprachauswertung ist deaktiviert." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Maus-Sprachauswertung ist aktiviert." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Fehler: Objektliste konnte nicht erstellt werden." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Keine Unterelemente." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Kein weiteres Element." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Kein übergeordnetes Element." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Kein vorheriges Element." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Vereinfachte Navigation aktiviert." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Vereinfachte Navigation deaktiviert." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Ebene %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Ein neues Objekt ist erschienen" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Keine Aktionen für %s gefunden" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Kein Fokus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Keine Anwendung besitzt den Fokus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Keine weiteren Zitate." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Keine weiteren Knöpfe." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Keine weiteren Ankreuzfelder." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Keine weiteren größeren Objekte." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Keine weiteren Klickelemente." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Keine weiteren kombinierten Auswahlfelder." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Keine weiteren Eingabefelder." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Keine weiteren Formularfelder." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Keine weiteren Überschriften." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Keine weiteren Überschriften der Ebene %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Keine weiteren inneren Rahmen." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Keine weiteren Bilder." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Keinen Orientierungspunkt gefunden." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Keine weiteren Links." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Keine weiteren Listen." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Keine weiteren Listeneinträge." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Keine weiteren dynamischen Bereiche." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Keine weiteren Absätze." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Keine weiteren Auswahlknöpfe." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Keine weiteren Trenner." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Keine weiteren Tabellen." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Keine weiteren nicht besuchten Links." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Keine weiteren besuchten Links." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Kein ausgewählter Text." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nicht in einem Link." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Benachrichtigung" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Unterste" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Oberste" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Keine Benachrichtigungen" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "Ziffern" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Zahlen ziffernweise vorlesen." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "Worte" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Zahlen als Wort vorlesen." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "aus" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "an" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Es wird geladen. Bitte warten." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Laden abgeschlossen." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Laden von %s abgeschlossen." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Seite hat %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "Seite ab der Cursorposition markiert" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "Seite bis zur Cursorposition markiert" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "Seite ab der Cursorposition nicht markiert" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "Seite bis zur Cursorposition nicht markiert" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "Abschnitt ab der Cursorposition markiert" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "Abschnitt oberhalb der Cursorposition markiert" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "Abschnitt ab der Cursorposition nicht mehr markiert" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "Abschnitt oberhalb der Cursorposition nicht mehr markiert" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Eine Instanz des Cthulhu-Eigenschaften-Dialoges ist bereits geöffnet.\n" -"Schließen Sie bitte diesen Dialog, bevor Sie einen neuen öffnen." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "Folie %(position)d von %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil wurde auf %s gesetzt." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Keine Profile gefunden." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Fortschrittsanzeige %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Alle" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Ansage der Sonderzeichen eingestellt auf alle." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Die meisten" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Ansage der Sonderzeichen eingestellt auf meiste." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Keine" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Ansage der Sonderzeichen auf keine gesetzt." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Einige" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Ansage der Sonderzeichen eingestellt auf einige." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Suche." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Suche abgeschlossen." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu-Einstellungen neu geladen." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Ausgewählter Text ist: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Auswahl gelöscht." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Auswahl wiederhergestellt." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Text ist nicht mehr ausgewählt." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Größe %d, %d. Ort: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Breite: %d. Höhe: %d. %d von links. %d von oben." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Sprachausgabe deaktiviert." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Sprachausgabe aktiviert." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "schneller." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "langsamer." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "höher." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "tiefer." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "lauter." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "weicher." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Geschwindigkeit %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Tonhöhe %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Lautstärke %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher-Modul %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher-Stimme %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Keine Speech-dispatcher-Module verfügbar" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Keine Speech-dispatcher-Stimmen verfügbar" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Spracheinstellungen gespeichert" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Spracheinstellungen konnten nicht gespeichert werden" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Ausführlichkeit: kurz" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Ausführlichkeit: gesprächig" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " Punkt Punkt Punkt" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu heißt Sie willkommen." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu lauert unter den Wellen." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Schlafmodus aktiviert für %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Schlafmodus für %s deaktiviert" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Sprachausgabe steht nicht zur Verfügung." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Nicht gefunden" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Statusleiste nicht gefunden" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "Zeichenkette nicht gefunden" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Navigationstasten ausgeschaltet." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Navigationstasten eingeschaltet." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nicht gefunden" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Zeile %(row)d, Spalte %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Tabellen Ende" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Zelle vorlesen" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Zeile vorlesen" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Nicht einheitlich" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Nicht in einer Tabelle." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Spalten wurden neu geordnet" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Zeilen wurden neu geordnet" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "Spalte %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "Spalte %(index)d von %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Unterer Rand der Spalte." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Oberer Rand der Spalte." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Spalte %s ausgewählt" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Spalten %s bis %s ausgewählt" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Spalten %s bis %s nicht mehr ausgewählt" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Spalte %s nicht mehr ausgewählt" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "Zeile %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "Zeile %(index)d von %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Zeilenanfang." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Zeilenende." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Zeile gelöscht." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Letzte Zeile gelöscht." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Zeile eingefügt." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Zeile am Ende der Tabelle eingefügt." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Zeile %s ausgewählt" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Zeilen %s bis %s ausgewählt" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Zeilen %s bis %s nicht mehr ausgewählt" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Zeile %s nicht mehr ausgewählt" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "ausgewählt" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "nicht ausgewählt" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H Stunden, %M Minuten und %S Sekunden" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H Stunden und %M Minuten" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "rückgängig" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "wiederholen" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu Version %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "Leerzeichen" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Nach unten springen." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Nach oben springen." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 Objekte" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Zelle erstreckt sich über %d Zeile" -msgstr[1] "Zelle erstreckt sich über %d Zeilen" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d Spalte" -msgstr[1] " %d Spalten" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Zelle erstreckt sich über %d Spalte" -msgstr[1] "Zelle erstreckt sich über %d Spalten" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d Zeichen zu viel" -msgstr[1] "%d Zeichen zu viel" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d Dialog)" -msgstr[1] "(%d Dialoge)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d Dialog ohne Fokus" -msgstr[1] "%d Dialoge ohne Fokus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d Byte" -msgstr[1] "%d Bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d Datei gefunden" -msgstr[1] "%d Dateien gefunden" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d Formular" -msgstr[1] "%d Formulare" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d Überschrift" -msgstr[1] "%d Überschriften" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d Objekt" -msgstr[1] "%d Objekte" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d Orientierungspunkt" -msgstr[1] "%d Orientierungspunkte" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d Objekt gefunden" -msgstr[1] "%d Objekte gefunden" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "%d Zitat wird verlassen." -msgstr[1] "%d Zitate werden verlassen." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "%d Liste wird verlassen." -msgstr[1] "%d Listen werden verlassen." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Liste mit unbekannter Objektanzahl" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Liste mit %d Eintrag" -msgstr[1] "Liste mit %d Einträgen" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Artikelliste mit unbekannter Artikelanzahl" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Artikelliste mit %d Artikel" -msgstr[1] "Artikelliste mit %d Artikeln" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Beschreibungsliste mit %d Eintrag" -msgstr[1] "Beschreibungsliste mit %d Einträgen" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d Wert" -msgstr[1] "%d Werte" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "Mathematische Tabelle mit %d Zeile" -msgstr[1] "Mathematische Tabelle mit %d Zeilen" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d Spalte" -msgstr[1] "%d Spalten" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "verschachtelte mathematische Tabelle mit %d Zeile" -msgstr[1] "verschachtelte mathematische Tabelle mit %d Zeilen" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d Nachricht.\n" -msgstr[1] "%d Nachrichten.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d Prozent." -msgstr[1] "%d Prozent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d Prozent des Dokumentes gelesen" -msgstr[1] "%d Prozent des Dokumentes gelesen" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d Pixel" -msgstr[1] "%d Pixel" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d mal das Zeichen %(repeatChar)s" -msgstr[1] "%(count)d mal das Zeichen %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d von %(total)d Objekt ausgewählt" -msgstr[1] "%(index)d von %(total)d Objekten ausgewählt" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d Bildschirmleser-Tastenkombination gefunden." -msgstr[1] "%d Bildschirmleser-Tastenkombinationen gefunden." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"%(count)d Bildschirmleser-Tastenkombination für %(application)s gefunden." -msgstr[1] "" -"%(count)d Bildschirmleser-Tastenkombinationen für %(application)s gefunden." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d Leerzeichen" -msgstr[1] "%d Leerzeichen" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d Tabulator" -msgstr[1] "%d Tabulatoren" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d Tabelle" -msgstr[1] "%d Tabellen" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "Tabelle mit unbekannter Dimension" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "Tabelle mit %d Spalte, Zeilenanzahl unbekannt" -msgstr[1] "Tabelle mit %d Spalten, Zeilenanzahl unbekannt" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "Tabelle mit %d Zeile, Spaltenanzahl unbekannt" -msgstr[1] "Tabelle mit %d Zeilen, Spaltenanzahl unbekannt" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "Tabelle mit %d Zeile" -msgstr[1] "Tabelle mit %d Zeilen" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "Vor %d Sekunde" -msgstr[1] "Vor %d Sekunden" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "Vor %d Minute" -msgstr[1] "Vor %d Minuten" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "Vor %d Stunde" -msgstr[1] "Vor %d Stunden" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "Vor %d Tag" -msgstr[1] "Vor %d Tagen" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d nicht besuchter Link" -msgstr[1] "%d nicht besuchte Links" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d besuchter Link" -msgstr[1] "%d besuchte Links" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "Umschalten" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "bei %(index)d von %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d von %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "Objekt %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "EBENE %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "Baumebene %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "BAUMEBENE %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "Details für %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "hat Details in %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "Vorschlag" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "Bearbeitbares Auswahlfeld" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "Bearbeitbarer Inhalt" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "Artikelliste" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "Abbildung" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "Zusammenfassung" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "Danksagungen" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "Nachwort" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "Anhang" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "Bibliografischer Eintrag" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "Bibliografie" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "Kapitel" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "Schlussschrift" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "Schlussfolgerung" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "Titelseite" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "Danksagung" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "Danksagungen" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "Widmung" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "Endnote" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "Endnoten" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "Epigraph" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "Epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "Errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "Beispiel" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "Vorwort" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "Glossar" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "Index" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "Einführung" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "Seitenumbruch" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "Seitenliste" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "Teil" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "Einleitung" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "Prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "Zitat" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Fragen und Antworten" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "Untertitel" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "Inhaltsverzeichnis" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s Ebene %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "Horizontale Bildlaufleiste" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "Vertikale Bildlaufleiste" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "Horizontaler Schieberegler" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "Vertikaler Schieberegler" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "Horizontaler Trenner" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "Vertikaler Trenner" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "Wechseln" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Symbolleiste" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "Banner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "Ergänzender Inhalt" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "Information" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "Hauptinhalt" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "Navigation" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "Bereich" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "Suchen" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "besuchter Link" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "Menüknopf" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "aufsteigend sortiert" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "absteigend sortiert" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "sortiert" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klickbar" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "eingeklappt" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "ausgeklappt" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "hat lange Beschreibung" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikal" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "ausgewählt" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nicht ausgewählt" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "an" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "aus" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "teilweise ausgewählt" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "gedrückt" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "nicht gedrückt" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "nicht ausgewählt" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "ausgewählt" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "nicht ausgewählt" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "nicht ausgewählt" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "besucht" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "nicht besucht" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ausgegraut" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "nur lesbar" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "nur lesbar" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "Eingabe erforderlich" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "Mehrfachauswahl" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "ungültiger Eintrag" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "ungültig" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "fehlerhafte Rechtschreibung" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "Rechtschreibung" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "fehlerhafte Grammatik" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "Grammatik" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Suchen" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Bildschirmleser Suchdialog" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "S_chließen" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "Suchen" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Suchen nach:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Suchen nach:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Anfang des Fensters" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Anfang des Fensters" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Beginnen bei:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Umbrechen" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "_Rückwärts suchen" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Suchrichtung:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Groß- und Kleinschreibung berücksichtigen" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Nur _vollständige Wörter berücksichtigen" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Optionen:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Vorgabe" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Großbuchstaben" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Link" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "System" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Anwendung" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Fenster" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu-Einstellungen" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Hilfe" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Anwenden" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Tastaturlayout" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktives _Profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profil beim Start:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Laden" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "_Speichern unter" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "Lö_schen" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profile" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Minihilfe ausgeben" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Objekt unter Ma_us vorlesen" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Maus" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Uhrzei_tformat:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "_Datumsformat:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Uhrzeit und Datum" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Sprach-Aktualisierungen" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Braille-Aktualisierungen" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frequenz (Sekunden):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Gilt für:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Klingel-Aktualisierungen" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Aktualisierungen von Fortschrittsanzeigen" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Schnelles Zurück- und Vorspulen in »Alles vorlesen« aktivieren" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "_Strukturierte Navigation bei »Alles vorlesen« verwenden" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Pause beim _Vorlesen:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "_Zitate in »Alles vorlesen« ankündigen" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Li_sten in »Alles vorlesen« ankündigen" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "_Tabellen in »Alles vorlesen« ankündigen" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "_Panels in »Alles vorlesen« ankündigen" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "_Formulare in »Alles vorlesen« ankündigen" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "_Orientierungspunkte in »Alles vorlesen« ankündigen" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Alles vorlesen" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Element_darstellung:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Allgemein" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Lautstärke:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Ton_höhe:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Geschwindigkeit:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Person:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Sprache:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Sprachs_ynthesizer:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Sprachsystem:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Stimm_typ:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Großschreibungsstil:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Typ der Sprachausgabe" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Zusammengesetzte _Wörter einzeln vorlesen" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "_Zahlen als Ziffern vorlesen" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Globale Sprachausgabe-Einstellungen" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Stimme" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Sprache _aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Aus_führlich" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Ausführlichkeit" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Alle" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Stufe der Sonderzeichenansage" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Nur angezeigten Text vorlesen" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Leerzeilen vorlesen" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "_Einrückungen und Ausrichtung vorlesen" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Menü_kürzelbuchstaben eines Objektes vorlesen" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Kind_position sprechen" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Benutzungshinweise vorlesen" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Systemmeldungen sind detailliert" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Farben als _Namen vorlesen" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "_Zitate während der Navigation ankündigen" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "_Listen während der Navigation ankündigen" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "_Tabellen während der Navigation ankündigen" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Anzeiger für _falsch geschriebenes Wort vorlesen" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "_Panels während der Navigation ankündigen" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "_Orientierungspunkte während der Navigation ankündigen" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "_Formulare während der Navigation ankündigen" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "_Beschreibung vorlesen" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Ganze Zeile in Tabellenblätte_rn vorlesen" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Ganze Zeile in _Dokument-Tabellen vorlesen" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Ganze Zeile in _GUI-Tabellen vorlesen" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Gesprochener Kontext" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Sprache" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Braille-_Unterstützung aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Abgekürzte Rollennamen" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Zeilen_ende-Symbol nicht anzeigen" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Kurzschrift_tabelle:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Blindenkurzschrift _aktivieren" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Zeilen_umbrüche aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Anzeigeeinstellungen" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Keine" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Auswahlindikator" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Link-Braillemarkierung" - -# Siehe Übersetzung von "Enable space? Enter y or n: " -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "_Meldungseinblendung aktivieren" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Dauer (Sekunden):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Meldungen sind _dauerhaft" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Meldungen sind deta_illiert" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Einstellungen für Meldungseinblendung" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Tastatur_echo aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "_Alphabetische Tasten aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "N_umerische Tasten aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Inter_punktionstasten aktivieren" - -# Siehe Übersetzung von "Enable space? Enter y or n: " -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "_Leertaste aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "_Modustasten aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "_Funktionstasten aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "_Aktionstasten aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "_Navigationstasten aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "_Wortweises Echo aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "_Satzweises Echo aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Echo" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Bildschirmleser-_Modustasten:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Tastenkombinationen" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Aussprachewörterbuch" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Neuer Eintrag" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Löschen" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Aussprache" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Alles vorlesen" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Nichts vorlesen" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Zurücksetzen" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Textattribute" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Nach _unten verschieben" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Eins nach u_nten verschieben" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Eins nach o_ben verschieben" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Nach _oben verschieben" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Ausgewähltes Attribut anpassen" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Braille-Indikator" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Textattribute" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "KI-Assistent aktivieren" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Anbieter:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokal - Kostenlos)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API-_Schlüsseldatei:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Pfad zur API-Schlüsseldatei" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "_Claude-API-Schlüssel abrufen" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Browser öffnen, um den Claude-API-Schlüssel abzurufen und automatisch zu " -"speichern" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Bestätigung vor KI-Aktionen erforderlich" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama-_Modell:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Modellname für Ollama (z.B. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama-_Endpunkt:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama-API-Endpunkt-URL (z.B. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Screenshot-_Qualität:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Niedrig" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Mittel" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Hoch" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "KI-Assistent" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Sprach_code:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Skalierungsfaktor:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Graustufenbild" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "Bild _invertieren" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Schwarz-Weiß-Bild" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Schwarz/Weiß-_Schwellenwert:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "Farben _analysieren" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Ergebnisse in _Zwischenablage kopieren" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : Anton, b : Berta, c : Cäsar, d : Dora, e : Emil, f : Friedrich, g : " -"Gustav, h : Heinrich, i : Ida, j : Julius, k : Kaufmann, l : Ludwig, m : " -"Martha, n : Nordpol, o : Otto, p : Paula, q : Quelle, r : Richard, s : " -"Siegfried, t : Theodor, u : Ulrich, v : Viktor, w : Wilhelm, x : Xantippe, " -"y : Ypsilon, z : Zeppelin, ä : Ärger, ö : Ökonom, ü : Übermut, ß : Eszett" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "Hintergrundfarbe" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "Hintergrund für die ganze Höhe" - -# CHECK: »stipple« -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "Gepunkteter Hintergrund" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "Textrichtung" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editierbar" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "Schriftartfamilie" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "Vordergrundfarbe" - -# CHECK: »stipple« -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "Gepunkteter Vordergrund" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "Schriftarteffekt" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "Einzug" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "Fehler" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "unsichtbar" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "Ausrichtung" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "Sprache" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "Linker Rand" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "Zeilenhöhe" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "Absatzstil" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "Pixel über Zeilen" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "Pixel unter Zeilen" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "Pixel innerhalb Umbruch" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "Rechter Rand" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "Anhebung" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "Skalierung" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "Größe" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "Dehnung" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "Durchgestrichen" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "Stil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "Textverzierung" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "Textdrehung" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "Textschattierung" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "Unterstrichen" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "Großbuchstabenstil" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "Vertikale Ausrichtung" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "Gewichtung" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "Umbruchmodus" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "Schreibmodus" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "wahr" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falsch" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "keiner" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "eingraviert" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "hochgeprägt" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "Umriss" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "Linie oberhalb" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "durchgestrichen" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "blinkend" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "schwarz" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "einfach" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "doppelt" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "tief" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "Zeichen" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "Wort" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "Wort Zeichen" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "links nach rechts" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rechts nach links" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "links" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "rechts" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "zentriert" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "Keine Ausrichtung" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "Blocksatz" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "sehr stark verdichtet" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "stark verdichtet" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "verdichtet" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "halb verdichtet" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "halb gedehnt" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "gedehnt" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "stark gedehnt" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "sehr stark gedehnt" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "kleine Großbuchstaben" - -# CHECK: Übersetzung »oblique« -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "abgeschrägt" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kursiv" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Vorgabe" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Textkörper" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Überschrift" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "Grundlinie" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "tiefgestellt" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "hochgestellt" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "oben" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "Text oben" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "Mitte" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "unten" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "Text unten" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "vererbt" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "links-rechts oben-unten" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rechts-links oben-unten" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "oben-unten rechts-links" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "oben-unten links-rechts" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "unten-oben rechts-links" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "unten-oben links-rechts" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "links-rechts" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rechts-links" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "oben-unten" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "Massiv" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "Rechtschreibung" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Leertaste zum Umschalten betätigen." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Leertaste zum Ausklappen betätigen und mit Hoch- und Runter-Taste Element " -"auswählen." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Alt+F6 betätigen, um untergeordnete Fenster zu fokussieren." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Um Objekte anzusteuern, können entweder die Pfeiltasten genutzt oder ein " -"Suchbegriff eingegeben werden." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Drücken Sie Alt+F1, um das Anwendungsmenü aufzurufen." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Hoch- und Runter-Taste zum Auswählen eines Elementes nutzen." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Zum Einklappen die Umschalttaste zusammen mit Links-Taste betätigen." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Zum Ausklappen die Umschalttaste zusammen mit Rechts-Taste betätigen." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Zum Aktivieren die Eingabetaste drücken." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Text eingeben." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Links- und Rechts-Taste zum Betrachten der anderen Reiter nutzen." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Zum Aktivieren die Leertaste betätigen." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Hoch- und Runter-Pfeiltasten zum Auswählen des Wertes wählen oder den " -"gewünschten numerischen Wert eingeben." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Pfeiltasten zum Ändern verwenden." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Links- und Rechts-Pfeiltasten zum Navigieren benutzen. Um sich durch die " -"Menüpunkte zu bewegen, Hoch- und Runter-Taste verwenden." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Um ein Untermenü zu betreten, Rechts-Pfeiltaste betätigen." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Zum Verringern Links-Pfeiltaste oder zum Erhöhen Rechts-Pfeiltaste benutzen. " -"Mit Pos1 wird zum Minimum und mit Ende zum Maximum gewechselt." diff --git a/po/dz.po b/po/dz.po deleted file mode 100644 index 789e8d7..0000000 --- a/po/dz.po +++ /dev/null @@ -1,9824 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.Dz\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2007-05-24 21:53+0530\n" -"Last-Translator: Tshewang Norbu \n" -"Language-Team: Dzongkha \n" -"Language: dz\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: Dzongkha\n" -"X-Poedit-Country: Bhutan\n" -"X-Poedit-SourceCharset: utf-8\n" -"Plural-Forms: nplurals=2; plural=(n!=1)\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "ཨོར་ཀ་གསལ་གཞི་ལྷག་བྱེད་/ཆེ་ཤེལ་" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "དྲན་བརྡ" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "བསྒུལ་བཟོ" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "མདའ་རྟགས" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "སི་ཨེ་ཨེལ།" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "སི་ཨེན་ཝི།" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "སི་པི་ཊི་ཨེན་" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "སི་ཨེཆ་ཀེ་" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "སི་ཨེལ་ཨར་སི་ཨེཆ་ཨེསི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "སི་ཨོ་ཨེལ་ཨེཆ་ཌི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "སི་བི་ཨོ།" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "ཌི་ཨེ་ཊི།" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ངོས་དཔར" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "ཨེཕ་ཨར་ཨེམ།" - -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "ཌ་ཡེལ།" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "ཌི་ཨེལ་ཇི།" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "ཌི་ཨའི་པི།" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "ཨེཆ་ཊི་ཨེམ་ཨེལ།" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "འབྲི་ནི།" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "ཨེཕ་སི་ཨེཆ་ཨེསི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "ཨེཕ་ཨེལ་ཨར།" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "ཨེཕ་ཨེན་ཊི།" - -#: src/cthulhu/braille_rolenames.py:124 -#, fuzzy -msgctxt "shortbraille" -msgid "form" -msgstr "འབྲི་ཤོག་" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "ཇི་པི་ཨེན།" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "ཨེཆ་ཌི་ཨེན་ཇི་" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "ཨའི་ཨེམ་ཇི།" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ཨེཕ་ཨར་ཨེམ" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "ཨེལ་བི་ཨེལ།" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "ཨེལ་ཝའི་ཨར་ཌི་པི་ཨེན།" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "སྣག་རྩི་" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "ཨེལ་ཨེསི་ཊི།" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "ཨེལ་ཨེསི་ཊི་ཨའི་ཊི་ཨེམ།" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "ཨེམ་ཨེན་ཡུ།" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "ཨེམ་ཨེན་ཡུ་བི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "ཨེམ་ཨེན་ཡུ་ཨའི་ཊི་ཨེམ།" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "ཨོ་པི་ཊི་ཨེན་པི་ཨེན།" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "པི་ཇི་ཊི" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "ཊི་བི་ཨེལ་ཨེསི་ཊི།" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "པི་ཨེན་ཨེལ།" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "པི་ཌབ་ལུ་ཌི།" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "པི་ཨོ་པི་ཨེམ་ཨེན་ཡུ།" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "པི་ཇི་བི་ཨེ་ཨར།" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "བི་ཊི་ཨེན།" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "རེ་ཌིའོ།" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "ཨར་ཌི་ཨེམ་ཨེན་ཡུ་ཨའི་ཊི་ཨེམ།" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "ཨར་ཊི་པི་ཨེན།" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "ཨར་ཌབ་ལུ་ཨེཆ་ཌི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "ཨེསི་སི་བི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "ཨེསི་སི་པི་ཨེན།" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "ཨེསི་སི་ཊི་ཨེན་" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "ཨེསི་ཨི་པི་ཨར་ཊི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "ཨེསི་ཨེལ་ཌི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "ཨེསི་པི་ཨེལ་ཊི་པི་ཨེན།" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "བསྒྱིར།" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "ཨེསི་ཊི་ཨེ་ཊི་བི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "ཊི་བི་ཨེལ།" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "སི་ཨེལ་ཨེལ" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "ཌི་ཨོ་ཨེམ་ཨེན་ཡུ་ཨའི་ཊི་ཨེམ།" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "ཊི་ཨི་ཨར་ཨེམ།" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "ཊི་ཨེགསི་ཊི།" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "ཊི་ཇི་ཨེལ་བི་ཊི་ཨེན།" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "ཊི་བི་ཨེ་ཨར།" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "ཊི་ཨའི་པི།" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "རྩ་འབྲེལ" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "ཊི་ཨར་ཊི་བི་ཨེལ།" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "ཡུ་ཨེན་ཀེ།" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "ཝི་ཌབ་ལུ་པི་ཨར་ཊི།" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "ཌབ་ལུ་ཨེན་ཌི།" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "ཨེཆ་ཌི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ཨེཕ་ཊི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "པི་ཨེ་ཨར་ཨེ།" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "ཨེ་པི་པི།" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "རང་བཞིན།" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "ཨི་ཌི་ཊི་བི་ཨར།" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "ཨི་ཨེམ་བི།" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "བར་སྣང་།" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "གྱལ་རིམ་གསརཔ།" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "ཨེབ་ལྡེ།" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "ཚོར་རྟགས།" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "འདྲེན་ཚིག" - -#: src/cthulhu/chnames.py:66 -#, fuzzy -msgid "number" -msgstr "སྤྱི་ཟླ་བཅུ་གཅིག་པ་" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "ཌོ་ལར།" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "བརྒྱ་ཆ།" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "དང་རྟགས།" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "འབྲེལ་སྒྲའི་རྟགས།" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "གཡོན་གྱི་གུག་ཤད། [" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "སྐར་རྟགས།" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "བསྡོམས་རྟགས།" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "ལྷོད་རྟགས།" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "འབྲེལ་རྟགས།" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "ཚག" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "གཡོ་ཤད།" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "ཀོ་ལཱན།" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "སེ་མི་ཀོ་ལཱན།" - -#: src/cthulhu/chnames.py:126 -#, fuzzy -msgid "less" -msgstr "ཉུང་རྟགས།" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "མཉམ་རྟགས།" - -#: src/cthulhu/chnames.py:134 -#, fuzzy -msgid "greater" -msgstr "མང་རྟགས།" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "དྲི་བ།" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "ལུ།" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "གཡོན་གྱི་གུག་ཤད། (" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "གཡོ་ཤད་ལོག་པ།" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "གཡས་ཀྱི་གུག་ཤད། )" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "ཀེ་རེཊི།" - -#: src/cthulhu/chnames.py:162 -#, fuzzy -msgid "underline" -msgstr "གྱལ་རིམ་གསརཔ།" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "གཡོན་གྱི་གུག་ཤད། {" - -#: src/cthulhu/chnames.py:174 -#, fuzzy -msgid "vertical bar" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "གཡས་ཀྱི་གུག་ཤད། }" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "སྣ་སྒྲ་ཅན་གྱི་རྟགས།" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "ལཱ་གི་ས་སྒོ།" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -#, fuzzy -msgid "cents" -msgstr "བརྒྱ་ཆ།" - -#: src/cthulhu/chnames.py:199 -#, fuzzy -msgid "pounds" -msgstr "པཱའུན།" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -#, fuzzy -msgid "broken bar" -msgstr "དཀར་ཆག་ཕྲ་རིང་།" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "དབྱེ་ཚན་" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "གཡོན་གྱི་གུག་ཤད། (" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -#, fuzzy -msgid "registered" -msgstr "དབུས་བསྒྲིགས།" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -#, fuzzy -msgid "plus or minus" -msgstr "བསྡོམས་རྟགས་ཕབ་རྟགས་" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -#, fuzzy -msgid "mu" -msgstr "ཨེམ་ཨེན་ཡུ།" - -#: src/cthulhu/chnames.py:275 -#, fuzzy -msgid "paragraph marker" -msgstr "དོན་མཚམས།" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "ཊར་མི་ནཱལ།" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "གཡས་ཀྱི་གུག་ཤད། )" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -#, fuzzy -msgid "a tilde" -msgstr "སྣ་སྒྲ་ཅན་གྱི་རྟགས།" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -#, fuzzy -msgid "n tilde" -msgstr "སྣ་སྒྲ་ཅན་གྱི་རྟགས།" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -#, fuzzy -msgid "o tilde" -msgstr "སྣ་སྒྲ་ཅན་གྱི་རྟགས།" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -#, fuzzy -msgid "divided by" -msgstr "བགོ་ནི་" - -#: src/cthulhu/chnames.py:539 -#, fuzzy -msgid "o stroke" -msgstr "འབྲེལ་སྒྲའི་རྟགས།" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "འབྲེལ་རྟགས།" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "གཡས་ཀྱི་སོར་ལྡེ།" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -#, fuzzy -msgid "per mille" -msgstr "འབུར་ཡིག" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -#, fuzzy -msgid "check mark" -msgstr "ཞིབ་དཔྱད་དཀར་ཆག" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "གཡོན་གྱི་གུག་ཤད། [" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "བསྡོམས་རྟགས་ཕབ་རྟགས་" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "གཡོན་གྱི་གུག་ཤད། [" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr " ཤུལ་མའི་ཡིག་འབྲུ་ནང་ལུ་ འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་རྣམ་གྲངས་ཚུ་ལུ་ གཡོན་གྱི་གཡེབ་གཏང་ལག་ལེན་འཐབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་རྣམ་གྲངས་ཚུ་ལུ་ གཡས་ཀྱི་གཡེབ་གཏང་ལག་ལེན་འཐབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "ཡིག་ཆ་ཧྲིལ་བུ་སླབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་གྱལ་རིམ་དེ་སླབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "ང་ག་ཏེ་ཨིན་ན་གི་ བཀོལ་སྤྱོད་ལགལེན་འཐབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "ང་ག་ཏེ་ཨིན་ན་གི་ བཀོལ་སྤྱོད་ལགལེན་འཐབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་གྱལ་རིམ་དེ་སླབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "གྲལ་ཐིག་སྟོངམ་ཚུ་ཁ་སླབ་" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "གནས་ཚད་ཕྲ་རིང་།" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "ཨོར་ཀ་འཚོལ་ནིའི་ཌའི་ལོག་འདི་ཁ་ཕྱེཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "ཡིག་རྒྱུན་ཅིག་གི་ ཤུལ་མའི་དུས་སྐབས་འདི་གི་དོན་ལུ་ འཚོལ་ཞིབ་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "ཡིག་རྒྱུན་ཅིག་གི་ ཧེ་མའི་དུས་སྐབས་འདི་གི་དོན་ལུ་འཚོལ་ཞིབ་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "ཕེ་ལེཊི་བསྐཡར་ཞིབ་ཐབས་ལམ་ནང་ འཛུལ་ཞུགས་དང་ ཕྱིར་འཐོན་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ རྫོགས་མཚམས་གནས་ས་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ཁྱིམ་གྱི་གནས་ས་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ རྫོགས་མཚམས་གནས་ས་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ཧེ་མའི་གྱལ་རིམ་གྱི་འགོ་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་གྱལ་རིམ་དེ་སླབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་གྱལ་རིམ་དེ་སླབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་གྱལ་རིམ་དེ་སླབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ཤུལ་མའི་་གྱལ་རིམ་གྱི་འགོ་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ཧེ་མའི་རྣམ་གྲངས་སམ་ མིང་ཚིག་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་ཀྱི་ རྣམ་གྲངས་སམ་ མིང་ཚིག་དེ་སླབ་་ཡང་ན་ ཡིག་སྡེབ་སླབ།" - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་ཀྱི་ རྣམ་གྲངས་སམ་ མིང་ཚིག་དེ་སླབ་་ཡང་ན་ ཡིག་སྡེབ་སླབ།" - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་ཀྱི་ རྣམ་གྲངས་སམ་ མིང་ཚིག་དེ་སླབ་་ཡང་ན་ ཡིག་སྡེབ་སླབ།" - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ཤུལ་མའི་རྣམ་གྲངས་སམ་ མིང་ཚིག་གི་ལྟག་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ད་ལྟོའི་མིང་ཚིག་གི་ལྟག་གི་ མིང་ཚིག་ལུ་སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་ཀྱི་དངོས་པོ་དེ་སླབ་ཨིན། " - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ད་ལྟོའི་མིང་ཚིག་གི་འོག་གི་ མིང་ཚིག་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ཧེ་མའི་ཡིག་འབྲུ་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་ཡིག་འབྲུ་དེ་སླབ་ཨིན། " - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་ཡིག་འབྲུ་དེ་སླབ་ཨིན། " - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "ད་ལྟོའི་ཕེ་ལེཊི་བསྐྱར་ཞིབ་ཡིག་འབྲུ་དེ་སླབ་ཨིན། " - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ཤུལ་མའི་ཡིག་འབྲུ་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ གྱལ་རིམ་རྫོགས་མཚམས་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ མཇུག་གི་གཡོན་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ རྫོགས་མཚམས་གནས་ས་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"ད་ལྟོའི་ཐིག་ཁྲམ་གྱི་ནང་ཐིག་རྐྱངམ་གཅིག་ ལྷག་ནི་ཨིན་ན་ ཡང་ན་ གྲལ་ཐིག་ཧྲིལ་བུ་ལྷག་ནི་ཨིན་ན་ སོར་སྟོན་" -"འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "ད་ལྟོའི་ཚིིག་ཡིག་གི་ཡིག་འབྲུ་དང་འབྲེལ་བ་ཡོད་པའི་ ཁྱད་ཆོས་ཚུ་ལྷགཔ་ཨིན།" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "འབུར་ཡིག་བཀྲམ་སྟོན་ གཡོན་ལུ་སེལཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "འབུར་ཡིག་བཀྲམ་སྟོན་གཡས་ལུ་སེལཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "ལྡེ་སྒྲོམ་ཆེད་དམིགས་ཡོད་པའི་དངོས་པོ་ལུ་ སླར་ལོགཔ་ཨིན།" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ཤུལ་མའི་་གྱལ་རིམ་གྱི་འགོ་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "ལྷབ་ནིའི་ཐབས་ལམ་ཐོ་བཀོད་འབདཝ་ཨིན། ལྷབ་ནིའི་ཐབས་ལམ་ ཕྱིར་འཐོན་འབད་ནི་ལུ་ ཐར་ལྡེ་མནན།" - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "ཁ་སླབ་ཀྱི་ཚད་མར་ཕབ་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "ཁ་སླབ་ཀྱི་ཚད་ཡར་འཕར་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "ཁ་སླབ་ཀྱི་སྟུག་ཚད་མར་ཕབ་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "ཁ་སླབ་ཀྱི་སྟུག་ཚད་ཡར་འཕར་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "ཁ་སླབ་ཀྱི་ཚད་ཡར་འཕར་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "ཁ་སླབ་ཀྱི་ཚད་མར་ཕབ་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "རེ་འདོད་ཅན་གྱི་ཁ་སླབ་སར་བར་སེལ་འཐུ་འབད།" - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "རེ་འདོད་ཅན་གྱི་ཁ་སླབ་སར་བར་སེལ་འཐུ་འབད།" - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "ཁ་སླབ་ཀྱི་ཚད་མར་ཕབ་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "ཁ་སླབ་ཀྱི་ཚད་ཡར་འཕར་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "ཁ་སླབ་སྒྲ་མེད་བཟོ་ནི་དེ་ སོར་སྟོན་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "དགའ་གདམ་རིམ་སྒྲིག་ཌའི་ལོག་ བཀྲམ་སྟོན་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "དགའ་གདམ་རིམ་སྒྲིག་ཌའི་ལོག་ བཀྲམ་སྟོན་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "འགོ་མཚམས་དང་ལྟེམས་བཅོས་སླབ།(_i)" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "གཞན་མི་མགུ་རྒྱན་གནས་རིམ་༡་པ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "ཁ་སླབ་སྒྲ་འཕྲུལ།(_z)" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "ཤུལ་མའི་གསལ་སྟོན་འཛིན་སྐྱོང་པ་ལུ་སོར་སྟོན་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "ཤུལ་མའི་གསལ་སྟོན་འཛིན་སྐྱོང་པ་ལུ་སོར་སྟོན་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "གཡོག་བཀོལ་བའི་སྐབས་ རྐྱེན་སེལ་གནས་རིམ་དེ་ བསྐྱར་འཁོར་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "ཧེ་མམ་གྱི་དངོས་པོ་ཆེ་བ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "གཞན་མི་དངོས་པོ་ཆེ་བ་ནང་ལུ་འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "ཧེ་མའི་ཁ་སླབ་ཁང་མིག་ཅིག་གི་ འཕྲིན་དོན་ཚུ་ ཁ་སླབ་སྟེ་ འབུར་ཡིག་ནང་སྟོན།" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"ང་བཅས་ཀྱིས་ ཡིག་ཐོག་ཁ་སླབ་ཁང་མིག་གི་འཕྲིན་དོན་ཚུ་ ཁ་སླབ་ཁང་མིག་གི་ མིང་དང་བཅསཔ་སྦེ་ སྔོན་ཚིག་བཀོད་" -"དགོཔ་ཨིན་ན་མེན་ སོར་སྟོན་འབད།" - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"ང་བཅས་ཀྱིས་ ཡིག་ཐོག་ཁ་སླབ་ཁང་མིག་གི་འཕྲིན་དོན་ཚུ་ ཁ་སླབ་ཁང་མིག་གི་ མིང་དང་བཅསཔ་སྦེ་ སྔོན་ཚིག་བཀོད་" -"དགོཔ་ཨིན་ན་མེན་ སོར་སྟོན་འབད།" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "གྲལ་ཐིག་གཡོན་" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "གྲལ་ཐིག་གཡས་" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "གྲལ་ཐིག་ཡར་" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "གྲལ་ཐིག་མར་" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "མགོའི་གཡོན་" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "མཇུག་གི་གཡས་" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "འོད་རྟགས་གནས་ས་" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "འོད་རྟགས་གནས་ས་" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "གྱལ" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr " ཤུལ་མའི་ཡིག་འབྲུ་ནང་ལུ་ འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr " ཧེ་མའི་ཡིག་འབྲུ་ནང་ལུ་འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "ཤུལ་མའི་མིང་ཚིག་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr " ཧེ་མའི་མིང་ཚིག་ནང་ལུ་ འགྱོཝ་་ཨིན། " - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "ཤུལ་མའི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "ཧེ་མམ་གྱི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ཤུལ་མའི་་གྱལ་རིམ་གྱི་འགོ་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ གྱལ་རིམ་རྫོགས་མཚམས་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "གཞན་མི་དངོས་པོ་ཆེ་བ་ནང་ལུ་འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "ཧེ་མམ་གྱི་དངོས་པོ་ཆེ་བ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "གེ་ཀོ་ཐོན་ས་དང་ཨོར་ཀ་ཀེ་རེཊི་འགྲུལ་བསྐྱོད་བར་ནང་གི་གློག་རྟ།" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "" -"ཀེལཀི་ནང་ཐིག་ཚུ་ཁ་སླབ་པའི་སྐབས་ ནུས་ཅན་ཀེར་ཐིག་མགོ་ཡིག་སྦེ་ ལག་ལེན་འཐབ་ནིའི་དོན་ལས་ གྲལ་ཐིག་འདི་" -"གཞི་སྒྲིག་འབད།" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "ནུས་ཅན་ཀེར་ཐིག་མགོ་ཡིག་བསལ་གཏང་ཡོདཔ།" - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"ཀེལི་ནང་ཐིག་ཚུ་ཁ་སླབ་པའི་སྐབས་ ནུས་ཅན་གྲལ་ཐིག་མགོ་ཡིག་སྦེ་ལག་ལེན་འཐབ་ནིའི་དོན་ལས་ ཀེར་ཐིག་འདི་གཞི་" -"སྒྲིག་འབད།" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "ནུས་ཅན་གྲལ་ཐིག་མགོ་ཡིག་ བསལ་གཏང་ཡོདཔ།" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "ཨིན་པུཊི་གྱལ་རིམ་གྱི་ནང་དོན་ཚུ་སླབ་ཨིན།" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "ཧེ་མམ་གྱི་ཐིག་ཁྲམ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "གཞན་མི་ཐིག་ཁྲམ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr " ཧེ་མའི་མིང་ཚིག་ནང་ལུ་ འགྱོཝ་་ཨིན། " - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "ཤུལ་མའི་མིང་ཚིག་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "གདམ་ཁ་མངམ་བཀྲམ་སྟོན་འབད།" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr " ཧེ་མའི་ཡིག་འབྲུ་ནང་ལུ་འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr " ཤུལ་མའི་ཡིག་འབྲུ་ནང་ལུ་ འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "ཧེ་མམ་གྱི་ཐིག་ཁྲམ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "གཞན་མི་ཐིག་ཁྲམ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr " ཧེ་མའི་མིང་ཚིག་ནང་ལུ་ འགྱོཝ་་ཨིན། " - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "ཤུལ་མའི་མིང་ཚིག་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "ཨེཆ་ ཊི་ ཨེམ་ ཨེལ་ འཛིན་སྣོད།" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "ཨེཆ་ ཊི་ ཨེམ་ ཨེལ་ འཛིན་སྣོད།" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr " ཧེ་མའི་མིང་ཚིག་ནང་ལུ་ འགྱོཝ་་ཨིན། " - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "ཤུལ་མའི་མིང་ཚིག་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr " ཧེ་མའི་མིང་ཚིག་ནང་ལུ་ འགྱོཝ་་ཨིན། " - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "ཤུལ་མའི་མིང་ཚིག་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "ཧེ་མམ་གྱི་མགུ་རྒྱན་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "མགུ་རྒྱན་གཞན་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "ཧེ་མམ་གྱི་མགུ་རྒྱན་ གནས་རིམ་༡་པ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "གཞན་མི་མགུ་རྒྱན་གནས་རིམ་༡་པ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "གནས་རིམ་འདི་ནང་་ལུ་མགུ་རྒྱན་མངམ་མེད། %d" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "ཧེ་མམ་གྱི་ཐིག་ཁྲམ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "ནང་འཁོད་གཞི་ཁྲམ།" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "ཧེ་མམ་གྱི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "ཤུལ་མའི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "ཧེ་མམ་གྱི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "ཤུལ་མའི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "ཧེ་མམ་གྱི་དངོས་པོ་ཆེ་བ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "གཞན་མི་དངོས་པོ་ཆེ་བ་ནང་ལུ་འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "དངོས་པོ་སྦོམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "ཧེ་མམ་གྱི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "ཤུལ་མའི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "གདམ་ཁ་མངམ་བཀྲམ་སྟོན་འབད།" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "ཧེ་མམ་གྱི་ཐོ་ཡིག་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "གཞན་མི་ཐོ་ཡིག་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "ཧེ་མམ་གྱི་རྣམ་གྲངས་ཐོ་ཡིག་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "གཞན་མི་རྣམ་གྲངས་ཐོ་ཡིག་ནང་ལུ་འགྱོཝ་ཨིན" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "ཧེ་མམ་གྱི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "ཤུལ་མའི་གྱལ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "" -"ཆེད་དམིགས་དང་བཅས་པའི་ དངོས་པོ་དེ་གི་རྒྱུད་པ་གི་སྐོར་ལས་ རྐྱེན་སེལ་གྱི་བརྡ་དོན་ དཔར་བསྐྲུན་འབདཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "ལྡེ་སྒྲོམ་ཆེད་དམིགས་ཡོད་པའི་དངོས་པོ་ལུ་ སླར་ལོགཔ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr " ཧེ་མའི་ཡིག་འབྲུ་ནང་ལུ་འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr " ཤུལ་མའི་ཡིག་འབྲུ་ནང་ལུ་ འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "ཧེ་མམ་གྱི་མགུ་རྒྱན་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "རེ་ཌིའོ་ཨེབ་རྟ།" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr " ཧེ་མའི་ཡིག་འབྲུ་ནང་ལུ་འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr " ཤུལ་མའི་ཡིག་འབྲུ་ནང་ལུ་ འགྱོཝ་ཨིན། " - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "ཧེ་མམ་གྱི་ཐིག་ཁྲམ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "གཞན་མི་ཐིག་ཁྲམ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "ནང་ཐིག་གཅིག་མར་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "ཐིག་ཁྲམ་ཅིག་ནང་ནང་ཐིག་དང་པ་ནང་་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "ཐིག་ཁྲམ་ཅིག་ནང་མཇུག་གི་ནང་ཐིག་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "ནང་ཐིག་གཅིག་གཡོན་ལུ་འགྱོཝ༌ཨིན།" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "ནང་ཐིག་གཅིག་གཡོས་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "ནང་ཐིག་གཅིག་ལྟག་ལུ་འགྱོཝ་ཨིན།་" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "སོར་སྟོན་ཨེབ་རྟ།" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "ལྡེ་མིག་བྲག་ཅ་ ལྕོགས་ཅན་བཟོ།(_k)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "ཧེ་མམ་གྱི་བལྟ་སྤྱོད་མ་འབད་བའི་འབྲོལ་ལམ་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "བལྟ་སྤྱོད་མ་འབད་བའི་འབྲེལ་ལམ་གཞན་མི་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "བལྟ་སྤྱོད་མ་འབད་བའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "ཧེ་མམ་གྱི་བལྟ་སྤྱོད་མ་འབད་མི་འབྲེལ་ལམ་ནང་ལུ་འགྱོཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "བལྟ་སྤྱོད་མ་འབད་མི་གཞན་མི་འབྲེལ་ལམ་ནང་ལུ་འགྱོ་ཝ་ཨིན།" - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "བལྟ་སྤྱོད་འབད་ཡོད་པའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "སྐྱ་ཐལ་ཅན།" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "རྒྱ་གར་" - -#: src/cthulhu/colornames.py:314 -#, fuzzy -msgctxt "color name" -msgid "indigo" -msgstr "རྒྱ་གར་" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "གཡས་ཀྱི་གུག་ཤད། }" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "གཡས་ཀྱི་ཚད་འཛིན།" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "གཡས་ཀྱི་གུག་ཤད། }" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "གཡས་ཀྱི་གདམ་ལྡེ།" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "གྱལ་རིམ་གསརཔ།" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "གཟུགས་བརྙན།" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "རྩ་འབྲེལ" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "གསལ་གཞ%s" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "ཊེང་གོ་" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "བར་སྟོང་དཀརཔོ།" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "བར་སྟོང་དཀརཔོ།" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "ངོས་དཔར།" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "ཅི་མེད།" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "སྡེབ་དཔྱད་:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -#, fuzzy -msgid "_Speak Chat Room name" -msgstr "ཁ་སླབ་ཁང་མིང་གི་མིང་སླབ།" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -#, fuzzy -msgid "Default Synthesizer" -msgstr "ཁ་སླབ་སྒྲ་འཕྲུལ།(_z)" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "བྲག་ཅ་མིང་ཚིག་ཐེོག་ལས་ ལྕོགས་ཅན་བཟོ།(_w)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "བྱ་བའི་ལྡེ་མིག་ཚུ་ ལྕོགས་ཅན་བཟོ།(_t)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "ད་ལྟོའི་གནས་ས་(_u)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -#, fuzzy -msgid "Find Options" -msgstr "ལས་འགན་" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "ལྷོད་རྟགས།" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "ལྡེ་མིག་བསྡམ་ཐག་" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "སྔོན་སྒྲིག" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "ལྷབ་ནིའི་ཐབས་ལམ་ཕྱིར་འཐོན་འབད།" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "དབྱེ་ཚན་" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "འབུར་ཡིག་བསྡམ་ཐག་ཚུ་" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -#, fuzzy -msgid "Unbound" -msgstr "པཱའུན།" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "ལེགས་བཅོས་འབད་ཡོདཔ་" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "ཌེཀསི་ཊོཔ་(_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "དཔར་བཤད་" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "ཨོར་ཀའི་དགའ་གདམ་ཚུ།" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -#, fuzzy -msgid "Speak" -msgstr "སླབ་ནིའི་གྱལ" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "ཆ་མཉམ།(_A)" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "གློག་རིམ།" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "སྒོ་སྒྲིག" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "ཅི་མེད།(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "དུམ་གྲ་ཅིག(_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "མང་ཤེོས།(_o)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "གྱལ" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "བརྗོད་ཚིག" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "འདྲེན་ཚིག" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "ཨེབ་རྟ།" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "དཔར་བཤད་" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "དཔྱད་སྒྲོམ།" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "བརྟག་སྒྲོམ།" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "དཔར་བཤད་" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "མགུ་རྒྱན་" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "ནང་འཁོད་གཞི་ཁྲམ།" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "གཟུགས་བརྙན།" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "ཁ་ཡིག" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -#, fuzzy -msgctxt "structural navigation" -msgid "Level" -msgstr "གནས་རིམ་%d" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "འབྲེལ་ལམ་" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "ཐོ་ཡིག" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ཐོ་ཡིག་རྣམ་གྲངས།" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "དོན་མཚམས།" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "རེ་ཌིའོ་ཨེབ་རྟ།" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "སེལ་འཐུ་འབད་ཡོདཔ།" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "གནས་ཚད་" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "ཚིག་ཡིག" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "འདྲེན་ཚིག" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "ཨེབ་རྟ།" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "དཔྱད་སྒྲོམ།" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "བརྟག་སྒྲོམ།" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "མགུ་རྒྱན་" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "ནང་འཁོད་གཞི་ཁྲམ།" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "གཟུགས་བརྙན།" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "གནས་རིམ་འདི་ནང་་ལུ་མགུ་རྒྱན་མངམ་མེད། %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "དངོས་པོ་སྦོམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "འབྲེལ་ལམ་" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "ཐོ་ཡིག" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ཐོ་ཡིག་རྣམ་གྲངས།" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "དོན་མཚམས།" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "རེ་ཌིའོ་ཨེབ་རྟ།" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "ཐིག་ཁྲམ།" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "བལྟ་སྤྱོད་མ་འབད་བའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "བལྟ་སྤྱོད་འབད་ཡོད་པའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "སྔོན་སྒྲིག" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "ཨའི་པར་ལིངཀ།" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "ཚུགས་ཡིག" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "བློ་ཡིག་གཏོང་་པ" - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "སྡེབ་དཔྱད་:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -#, fuzzy -msgid "Skip _blank cells" -msgstr "སླབ་ནིའི་ནང་ཐིག" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "སླབ་ནིའི་ནང་ཐིག" - -#: src/cthulhu/guilabels.py:909 -#, fuzzy -msgid "Speak _cell coordinates" -msgstr "སླབ་ནིའི་ནང་ཐིག" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "མདོར་བསྡུས།(_f)" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "སོར་ལྡེ་" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "གདམ་ལྡེ་ ཨར་ (_R)" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "གཡོན་གྱི་ཚད་འཛིན།" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "གཡེོན་གྱི་སོར་ལྡེ།" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "གཡོན་གྱི་གདམ་ལྡེ།" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "གཡོན་གྱི་ཚད་འཛིན།" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "གཡས་ཀྱི་སོར་ལྡེ།" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "གཡས་ཀྱི་གདམ་ལྡེ།" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "གཡས་ཀྱི་ཚད་འཛིན།" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "གཡོན་གྱི་མེ་ཊ།" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "གཡས་ཀྱི་མེ་ཊ།" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "ཨང་ལྡེ།" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "ཚུགས་ལྡེ།" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "ཚུགས་ལྡེ།" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "བཤུད་ལྡེ།" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "ཤོག་ལེབ་ཡར།" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "ཤོག་ལེབ་མར།" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "གཡོན་གྱི་མཆོང་ལྡེ།" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "བར་སྣང་།" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "དབུས་བསྒྲིགས།" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "ཤོག་ལེབ་མར།" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "གཡོན་གྱི་གདམ་ལྡེ།" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "གཡས་ཀྱི་གདམ་ལྡེ།" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "གཡོན་གྱི་གུག་ཤད། [" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "དཀར་ཆག" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -#, fuzzy -msgid "multi" -msgstr "དགུ་མཐའ་བརྐྱབ་" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "དང་རྟགས།" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "འབྲེལ་སྒྲའི་རྟགས།" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "ཕབ་རྟགས་" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "ཚུགས་ལྡེ།(_L)" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "གདམ་ལྡེ་ ཨར་ (_R)" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "ཡང་དག་" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "མེ་ཊ་༢" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "གདམ་ལྡེ་ ཨེལ་(_L)" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "ཚད་འཛིན་" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "སོར་ལྡེ་" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "རྒྱགས་པ་" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "ལཱ་གི་ས་སྒོ།" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "སྐབས་དོན་འདི་%s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "གཡོན་གྱི་གུག་ཤད། [" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "མདའ་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "མདའ་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "གཡས་ཀྱི་ཚད་འཛིན།" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "ཕབ་རྟགས་" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "ཉུང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "ཚག" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "རང་བཞིན་ཡོངས་སྒྲུབ།" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "སྟོངམ།" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "གྲལ་ཐིག་གི་མཇུག།" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "བསྡོམས་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "བསྡོམས་རྟགས་ཕབ་རྟགས་" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "དབྱེ་བྱེད།" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "ཆ་ཚད་ཅན།" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "གཡས་ཀྱི་གདམ་ལྡེ།" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "རིམ་བརྩེགས་པེན།" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "བགོ་ནི་" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "དབྱེ་བྱེད།" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "དབྱེ་ཚན་" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "ནང་འཁོད་གཞི་ཁྲམ།" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "ཆ་ཚད་ཅན།" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "ཕབ་རྟགས་" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "སྣ་སྒྲ་ཅན་གྱི་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "སྣ་སྒྲ་ཅན་གྱི་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "སྣ་སྒྲ་ཅན་གྱི་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "མཉམ་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "མཉམ་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "མཉམ་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "ཉུང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "ཉུང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -#, fuzzy -msgctxt "math symbol" -msgid "not less than" -msgstr "ཉུང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "མ་མནནམ།" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "དགུ་མཐའ་བརྐྱབ་" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -#, fuzzy -msgctxt "math symbol" -msgid "circled minus" -msgstr "བསྡོམས་རྟགས་ཕབ་རྟགས་" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "མཉམ་རྟགས།" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "བསྡོམས་རྟགས་ཕབ་རྟགས་" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "གཡས་ཀྱི་མེ་ཊ།" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "གཡོན་གྱི་མཆོང་ལྡེ།" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "དབྱེ་ཚན་" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "མ་མནནམ།" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "གཟུགས་བརྙན།" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "དགུ་མཐའ་བརྐྱབ་" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "ནང་འཁོད་གཞི་ཁྲམ།" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "གཅིག་མཚུགས་" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "གཡས་ཀྱི་གདམ་ལྡེ།" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "གཡས་ཀྱི་གུག་ཤད། }" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "དབྱེ་བྱེད།" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "ཉུང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:2025 -#, fuzzy -msgctxt "math symbol" -msgid "very much less than" -msgstr "ཉུང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:2028 -#, fuzzy -msgctxt "math symbol" -msgid "very much greater than" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "ཉུང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "མང་རྟགས།" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "གཡོན་གྱི་གུག་ཤད། [" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "གཡོན་གྱི་གདམ་ལྡེ།" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "གཡས་ཀྱི་གདམ་ལྡེ།" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "གཡོན་གྱི་གུག་ཤད། {" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "གཡོན་གྱི་གུག་ཤད། {" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "གཡོན་གྱི་གུག་ཤད། (" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "གཡས་ཀྱི་གུག་ཤད། )" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "བར་སྟོང་དཀརཔོ།" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "བར་སྟོང་དཀརཔོ།" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "བར་སྟོང་དཀརཔོ།" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "གློག་རིམ།" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "སྟོངམ།" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "རྒྱགས་པ་" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "ཡིག་སྣོད་ཚུ་མ་ཐོབ།" - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "ཡིག་རྒྱུན་འཚོལ་མ་ཐོབ་" - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "ཁ་སླབ་ལྕོགས་ཅན་བཟོ་ཡོད།" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ངོས་དཔར།" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "ཛེག་ཀོ་གི་ཀེ་རེཊི་ཚད་འཛིན་འབད་དོ།" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "ཨོར་ཀ་གིས་ཀེ་རེཊི་འདི་ཚད་འཛིན་འབད་དོ།" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "ནང་ཐིག་%s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "སེལ་འཐུ་འབད་ཡོདཔ།" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -#, fuzzy -msgid "Use alternate directory for user preferences" -msgstr "" -"-u, --user-prefs-dir=dirname ལག་ལེན་པའི་དགའ་གདམ་གྱི་དོན་ལུ་ ཐབས་གཞན་སྣོད་ཐོ་ལག་ལེན་འཐབ་" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -#, fuzzy -msgid "Set up user preferences (text version)" -msgstr "" -"-ཊི་, --ཚིག་ཡིག་གཞི་སྒྲིག ལག་ལེན་པའི་དགའ་གདམ་ཚུ་གཞི་སྒྲིག་འབད། (ཚིག་ཡིག་ཐོན་རིམ)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "" -"-ཊི་, --ཚིག་ཡིག་གཞི་སྒྲིག ལག་ལེན་པའི་དགའ་གདམ་ཚུ་གཞི་སྒྲིག་འབད། (ཚིག་ཡིག་ཐོན་རིམ)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "རྐྱེན་གྱི་སྙན་ཞུ་ཚུ་ https://groups.io/g/stormux ལུ་གཏང་།" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "མགྱོགས་མི།" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "ཁ་སླབ་ཁང་མིག་ནང་གི་འཕྲིན་དོན %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "ཁ་སླབ་ཁང་མིག་གི་མིང་མ་སླབ།" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "ཁ་སླབ་ཁང་མིང་གི་མིང་སླབ།" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "དབྱེ་ཚན་" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "དྲི་བ།" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "ཨེཆ་ ཊི་ ཨེམ་ ཨེལ་ འཛིན་སྣོད།" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "ཐིག་ཁྲམ་ནང་ལུ་མེན།" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "ཡིག་རྒྱུན་འཚོལ་མ་ཐོབ་" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "ཐིག་ཁྲམ་ནང་ལུ་མེན།" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "ཡིག་ཆ་ཧྲིལ་བུ་ སེལ་འཐུ་འབད་ཡོད།" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "ཡིག་ཆ་ཧྲིལ་བུ་ སེལ་འཐུ་འབད་ཡོད།" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ སེལ་འཐུ་འབད་ཡོད་པའི་ཡིག་ཆ།" - -#: src/cthulhu/messages.py:554 -#, fuzzy -msgid "document unselected from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ སེལ་འཐུ་འབད་ཡོད་པའི་ཡིག་ཆ།" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལུ་ སེལ་འཐུ་འབད་ཡོད་པའི་ཡིག་ཆ།" - -#: src/cthulhu/messages.py:566 -#, fuzzy -msgid "document unselected to cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལུ་ སེལ་འཐུ་འབད་ཡོད་པའི་ཡིག་ཆ།" - -#: src/cthulhu/messages.py:571 -#, fuzzy, python-format -msgid "Dynamic column header set for row %d" -msgstr "གྲལ་ཐིག་གི་དོན་ལུ་ གཞི་སྒྲིག་འབད་ཡོད་མི་ ནུས་ཅན་ཀེར་ཐིག་མགོ་ཡིག་" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "ནུས་ཅན་ཀེར་ཐིག་མགོ་ཡིག་བསལ་གཏང་ཡོདཔ།" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "ཀེར་ཐིག་ %s གི་དོན་ལུ་ གཞི་སྒྲིག་འབད་ཡོད་མི་ ནུས་ཅན་གྲལ་ཐིག་མགོ་ཡིག་" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "ནུས་ཅན་གྲལ་ཐིག་མགོ་ཡིག་ བསལ་གཏང་ཡོདཔ།" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "སྟོངམ།" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "ཡིག་སྣོད་ཚུ་མ་ཐོབ།" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "ཕེ་ལེཊི་བསྐཡར་ཞིབ་ཐབས་ལམ་ནང་ འཛུལ་ཞུགས་དང་ ཕྱིར་འཐོན་འབདཝ་ཨིན།" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ ད་ལྟོའི་མིང་ཚིག་གི་ལྟག་གི་ མིང་ཚིག་ལུ་སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "མན་ངག་ཡོད" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "ཌའི་ལོག" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "པོཔ་ཨཔ་དཀར་ཆག" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, fuzzy, python-format -msgid "The key entered is already bound to %s" -msgstr "ལྡེ་མིག་ཐོ་བཀོད་འབད་མི་འདི་གཅིག་པ་ཨིན་མས། ག་ཅི་ཡང་བསྒྱུར་བཅོས་མ་འབད་བས།" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "ལྡེ་མིག་འཛིན་བཟུང་འབད་ཡོདཔ་: %s ལོག་ལྡེ་འདི་ ངེས་དཔྱད་འབད་ནིའི་དོན་ལས་ ཨེབ།" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "ལྡེ་མིག་གསརཔ་འདི་: %s" - -#: src/cthulhu/messages.py:711 -#, fuzzy -msgid "Key binding deleted. Press enter to confirm." -msgstr "ལྡེ་མིག་འཛིན་བཟུང་འབད་ཡོདཔ་: %s ལོག་ལྡེ་འདི་ ངེས་དཔྱད་འབད་ནིའི་དོན་ལས་ ཨེབ།" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "ལྡེ་མིག་གསརཔ་ཐོ་བཀོད་འབད་" - -#: src/cthulhu/messages.py:735 -#, fuzzy -msgctxt "key echo" -msgid "key" -msgstr "ཝིསི་ཀི་" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "ཅི་མེད།" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "ཤུལ་མའི་མིང་ཚིག་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "བརྗོད་ཚིག" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "ཆོག་ཡིག" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "ཤུལ་མའི་མིང་ཚིག་ནང་འགྱོཝ་ཨིན།" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "དང་རྟགས།" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "རྩ་བའི་པེན།" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "རྩ་བའི་པེན།" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "རྩ་བའི་པེན།" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "གཤམ་ཐིག" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "ཐིག་ཁྲམ།" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "རྩ་འབྲེལ་ཐིག་ཁྲམ།" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "འཛུལ་སྤྱོད་འབད་མ་བཏུབ།" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "ཐིག་ཁྲམ།" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "འགོ་མཚམས་དང་ལྟེམས་བཅོས་སླབ།(_i)" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "ཐིག་ཁྲམ།" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "འགོ་མཚམས་དང་ལྟེམས་བཅོས་སླབ།(_i)" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "ལྷབ་ནིའི་ཐབས་ལམ། ཕྱིར་འཐོན་འབད་ནི་ལུ་ ཐར་ལྡེ་མནན།" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "བསྒུལ་བཟོ།" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་མར་ སེལ་འཐུ་འབད་ཡོད་པའི་གྱལ་རིམ།" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ཡར་ སེལ་འཐུ་འབད་ཡོད་པའི་གྱལ་རིམ།" - -#: src/cthulhu/messages.py:1484 -#, fuzzy -msgid "line unselected down from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་མར་ སེལ་འཐུ་འབད་ཡོད་པའི་གྱལ་རིམ།" - -#: src/cthulhu/messages.py:1491 -#, fuzzy -msgid "line unselected up from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ཡར་ སེལ་འཐུ་འབད་ཡོད་པའི་གྱལ་རིམ།" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "ལྷབ་ནིའི་ཐབས་ལམ་ཕྱིར་འཐོན་འབད་དོ།" - -#: src/cthulhu/messages.py:1505 -#, fuzzy -msgid "line selected from start to previous cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ཡར་ སེལ་འཐུ་འབད་ཡོད་པའི་གྱལ་རིམ།" - -#: src/cthulhu/messages.py:1511 -#, fuzzy -msgid "line selected to end from previous cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་མར་ སེལ་འཐུ་འབད་ཡོད་པའི་གྱལ་རིམ།" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "འབྲེལ་ལམ།" - -#: src/cthulhu/messages.py:1518 -#, fuzzy -msgid "same page" -msgstr "%s ཤོག་ལེབ།" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, fuzzy, python-format -msgid "%s link" -msgstr "འབྲེལ་ལམ།" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "བལྟ་སྤྱོད་འབད་ཡོད་པའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "རྩ་འབྲེལ་གནས་རིམ་%d།" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "ཡིག་སྣོད་ཚུ་མ་ཐོབ།" - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "ད་ལྟོའི་གནས་ས་(_u)" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "ཨོཕ" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "ཨཱོན" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "ཡིག་སྡེབ་འཛོལ་བའི་མིང་ཚིག་:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "སྡེབ་འཛོལ་ཡོད་པའི་མིང་ཚིག:%s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "སྐབས་དོན་འདི་%s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "དངོས་པོ་སྦོམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "ཁ་སླབ་ལྕོགས་མིན་བཟོ་ཡོད།" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "ཁ་སླབ་ལྕོགས་ཅན་བཟོ་ཡོད།" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr " %dབརྒྱ་ཆ།" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr " ཧེ་མའི་མིང་ཚིག་ནང་ལུ་ འགྱོཝ་་ཨིན། " - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "རྩ་འབྲེལ་གནས་རིམ་%d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "ཆེད་དམིགས་མེདཔ།" - -#: src/cthulhu/messages.py:1867 -#, fuzzy -msgid "No application has focus." -msgstr "གློག་རིམ།" - -#: src/cthulhu/messages.py:1872 -#, fuzzy -msgid "No more blockquotes." -msgstr "ཐིག་ཁྲམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "ཅངཀ་ཚུ་མེད།" - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "ཅངཀ་ཚུ་མེད།" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "དངོས་པོ་སྦོམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "ཐིག་ཁྲམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "ཐིག་ཁྲམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1903 -#, fuzzy -msgid "No more entries." -msgstr "ཐིག་ཁྲམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1908 -#, fuzzy -msgid "No more form fields." -msgstr "ཐོ་ཡིག་རྣམ་གྲངས་ཚུ་མངམ་མེདཝ" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "མགུ་རྒྱན་མེད།" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "གནས་རིམ་འདི་ནང་་ལུ་མགུ་རྒྱན་མངམ་མེད། %d" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "ནང་འཁོད་གཞི་ཁྲམ།" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "ཐིག་ཁྲམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1935 -#, fuzzy -msgid "No landmark found." -msgstr "ཡིག་སྣོད་ཚུ་མ་ཐོབ།" - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "ཐོ་ཡིག་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "ཐོ་ཡིག་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "ཐོ་ཡིག་རྣམ་གྲངས་ཚུ་མངམ་མེདཝ" - -#: src/cthulhu/messages.py:1957 -#, fuzzy -msgid "No more live regions." -msgstr "ཐོ་ཡིག་རྣམ་གྲངས་ཚུ་མངམ་མེདཝ" - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "མགུ་རྒྱན་མེད།" - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "མགུ་རྒྱན་མེད།" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "ཐོ་ཡིག་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "ཐིག་ཁྲམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "བལྟ་སྤྱོད་མ་འབད་བའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "བལྟ་སྤྱོད་འབད་ཡོད་པའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "ཐིག་ཁྲམ་ནང་ལུ་མེན།" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "དཔར་བཤད་" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "གཤམ་:(_B)" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "མགོ་:(_T)" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "ཆོག་ཡིག" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "ཨོཕ" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ཨཱོན" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "མངོན་གསལ་འབད་དོ། བསྒུག་གནང་།" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "མངོན་གསལ་འབད་བའི་སྒང་ཡོད་མི་འདི་མཇུག་བསྡུ་ཡོདཔ།" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "མངོན་གསལ་འབད་བའི་སྒང་ཡོད་མི་འདི་མཇུག་བསྡུ་ཡོདཔ%s.།" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ སེལ་འཐུ་འབད་ཡོད་པའི་ཤོག་ལེབ།" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལུ་ སེལ་འཐུ་འབད་ཡོད་པའི་ཤོག་ལེབ།" - -#: src/cthulhu/messages.py:2089 -#, fuzzy -msgid "page unselected from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ སེལ་འཐུ་འབད་ཡོད་པའི་ཤོག་ལེབ།" - -#: src/cthulhu/messages.py:2095 -#, fuzzy -msgid "page unselected to cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལུ་ སེལ་འཐུ་འབད་ཡོད་པའི་ཤོག་ལེབ།" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ སེལ་འཐུ་འབད་ཡོད་པའི་ཤོག་ལེབ།" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ སེལ་འཐུ་འབད་ཡོད་པའི་ཤོག་ལེབ།" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ སེལ་འཐུ་འབད་ཡོད་པའི་ཤོག་ལེབ།" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "འོད་རྟགས་གནས་ས་ལས་ སེལ་འཐུ་འབད་ཡོད་པའི་ཤོག་ལེབ།" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "ཡིག་སྣོད་ཚུ་མ་ཐོབ།" - -#: src/cthulhu/messages.py:2151 -#, fuzzy, python-format -msgid "Progress bar %d." -msgstr "ཡར་འཕེལ་ཕྲ་རིང་།" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "ཆ་མཉམ།(_A)" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "ཡིག་རྟགས་གནས་རིམ་l" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "ཅི་མེད།" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "འཚོལ་ཞིབ་འབད་དོ།" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "འཚོལ་ཞིབ་མཇུག་བསྡུ་ཡོད།" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "ཨོར་ཀ་ལག་ལེན་པའི་སྒྲིག་སྟངས་ སླར་མངོན་གསལ་འབད་ཡི།" - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "སྐབས་དོན་འདི་%s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "རེ་འདོད་ཅན་གྱི་སྐད་སེལ་འཐུ་འབད་:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "ཁ་སླབ་ལྕོགས་མིན་བཟོ་ཡོད།" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "ཁ་སླབ་ལྕོགས་ཅན་བཟོ་ཡོད།" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "མགྱོགས་མི།" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "ལྷོད་མི།" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "མཐོ་མི།" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "དམའ་མི།" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "མགྱོགས་མི།" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "ཚད་:(_R)" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "སྐད་ཤུགས་:(_l)" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "བློ་ཡིག་གཏོང་་པ" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "བློ་ཡིག་གཏོང་་པ" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "སར་བར་མི་འཐོབ་པས།\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "སྐད་མི་འཐོབ་པས།\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "ཁ་སླབ་ལྕོགས་ཅན་བཟོ་ཡོད།" - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "ཁ་སླབ་ལག་ལེན་མི་འཐབ།\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "ཚག་ ཚག་ ཚག" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "ཨོར་ཀའི་དགའ་གདམ་ཚུ།" - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "ཨོར་ཀ་གིས་ཀེ་རེཊི་འདི་ཚད་འཛིན་འབད་དོ།" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "ཁ་སླབ་མི་ཐོབ་པས།" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "ཡིག་སྣོད་ཚུ་མ་ཐོབ།" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "ཡིག་རྒྱུན་འཚོལ་མ་ཐོབ་" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "ཡིག་རྒྱུན་འཚོལ་མ་ཐོབ་" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "ཡིག་སྣོད་ཚུ་མ་ཐོབ།" - -#: src/cthulhu/messages.py:2380 -#, fuzzy, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "གྲལ་ཐིག་ %d, ཀེར་ཐིག་ %d།" - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "གྲལ་ཐིག་གི་མཇུག།" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "སླབ་ནིའི་ནང་ཐིག" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "སླབ་ནིའི་གྱལ" - -#: src/cthulhu/messages.py:2399 -#, fuzzy -msgid "Non-uniform" -msgstr "གཅིག་མཚུགས་" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "ཐིག་ཁྲམ་ནང་ལུ་མེན།" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ཀེར་ཐིག་མགོ་ཡིག" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "ཀེར་ཐིག་ %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "ཀེར་ཐིག་གི་གཤམ།" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "ཀེར་ཐིག་གི་མགོ།" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "གྲལ་ཐིག་ %d" - -#: src/cthulhu/messages.py:2462 -#, fuzzy, python-format -msgid "row %(index)d of %(total)d" -msgstr "གྲལ་ཐིག་ %d ལས་ %d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "འགོ་བཙུགས་ཡོད་པའི་སྒང་གི་གྱལ།" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "གྲལ་ཐིག་གི་མཇུག།" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "ཕེ་ལེཊི་བསྐྱར་ཞིབ་དེ་ གྱལ་རིམ་རྫོགས་མཚམས་ལུ་ སྤོ་བཤུད་འབདཝ་ཨིན། " - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "སེལ་འཐུ་འབད་ཡོདཔ།" - -#: src/cthulhu/messages.py:2521 -#, fuzzy -msgctxt "text" -msgid "unselected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "ཨོར་ཀ་འཚོལ་" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "བར་སྟོང་དཀརཔོ།" - -#: src/cthulhu/messages.py:2562 -#, fuzzy -msgid "Wrapping to bottom." -msgstr "མཇུག་ལུ་ལོག་མཚམས་བཟོ་དོ་" - -#: src/cthulhu/messages.py:2568 -#, fuzzy -msgid "Wrapping to top." -msgstr "མགོ་ལུ་ལོག་མཚམས་བཟོ་དོ་" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "༠ རྣམ་གྲངས་" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "ཀེར་ཐིག་%d" -msgstr[1] "ཀེར་ཐིག་ ཚུ%d" - -#: src/cthulhu/messages.py:2593 -#, fuzzy, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "ཀེར་ཐིག་%d" -msgstr[1] "ཀེར་ཐིག་ ཚུ%d" - -#: src/cthulhu/messages.py:2610 -#, fuzzy, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] " %d %s ཡིག་འབྲུ" -msgstr[1] " %d %s ཡིག་འབྲུ་ཚུ་" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "ཌའི་ལོག" -msgstr[1] "ཌའི་ལོག" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "ཡིག་སྣོད་ཐོབ་ཡོད%d" -msgstr[1] "ཡིག་སྣོད་ཚུ་ཐོབ་ཡོད%d" - -#: src/cthulhu/messages.py:2640 -#, fuzzy, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "འབྲི་ཤོག་" -msgstr[1] "འབྲི་ཤོག་" - -#: src/cthulhu/messages.py:2647 -#, fuzzy, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "མགུ་རྒྱན་" -msgstr[1] "མགུ་རྒྱན་" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] " རྣམ་གྲངས%d" -msgstr[1] "རྣམ་གྲངས་ཚུ %d" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "ཡིག་སྣོད་ཐོབ་ཡོད%d" -msgstr[1] "ཡིག་སྣོད་ཚུ་ཐོབ་ཡོད%d" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "ཐིག་ཁྲམ་བཞག་དོ།" -msgstr[1] "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "ཐིག་ཁྲམ་བཞག་དོ།" -msgstr[1] "ཐིག་ཁྲམ་བཞག་དོ།" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "ཐོ་ཡིག་རྣམ་གྲངས%d " -msgstr[1] "ཐོ་ཡིག་རྣམ་གྲངས་ཚུ་%d " - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "ཐོ་ཡིག་རྣམ་གྲངས%d " -msgstr[1] "ཐོ་ཡིག་རྣམ་གྲངས་ཚུ་%d " - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "%d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ་ཚུ།" -msgstr[1] "%d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ།" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "ཀེར་ཐིག་%d" -msgstr[1] "ཀེར་ཐིག་ ཚུ%d" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "%d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ་ཚུ།" -msgstr[1] "%d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ།" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] " %dབརྒྱ་ཆ།" -msgstr[1] " %dབརྒྱ་ཆ།" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "པིག་སེལ།" -msgstr[1] "པིག་སེལ།" - -#: src/cthulhu/messages.py:2777 -#, fuzzy, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] " %d %s ཡིག་འབྲུ" -msgstr[1] " %d %s ཡིག་འབྲུ་ཚུ་" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d བར་སྟོང་་" -msgstr[1] "%d བར་སྟོང་ཚུ་" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d མཆོང་ལྡེ" -msgstr[1] "%d མཆོང་ལྡེ་ཚུ་" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d མཆོང་ལྡེ" -msgstr[1] "%d མཆོང་ལྡེ་ཚུ་" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "%d གྲལ་ཐིག་དང་ %d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ།" -msgstr[1] "%d གྲལ་ཐིག་དང་ %d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ།" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%d གྲལ་ཐིག་དང་ %d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ།" -msgstr[1] "%d གྲལ་ཐིག་དང་ %d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ།" - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "%d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ་ཚུ།" -msgstr[1] "%d ཀེར་ཐིག་ཡོད་མི་ཐིག་ཁྲམ།" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, fuzzy, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "བལྟ་སྤྱོད་མ་འབད་བའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" -msgstr[1] "བལྟ་སྤྱོད་མ་འབད་བའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/messages.py:2892 -#, fuzzy, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "བལྟ་སྤྱོད་འབད་ཡོད་པའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" -msgstr[1] "བལྟ་སྤྱོད་འབད་ཡོད་པའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "སོར་སྟོན་ཨེབ་རྟ།" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, fuzzy, python-format -msgid "LEVEL %d" -msgstr "རྩ་འབྲེལ་གནས་རིམ་%d།" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "རྩ་འབྲེལ་གནས་རིམ་%d།" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "རྩ་འབྲེལ་གནས་རིམ་%d།" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "དྲི་བ།" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "བརྟག་སྒྲོམ།" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "ཨེཆ་ཊི་ཨེམ་ཨེལ་ ནང་དོན་" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "ཀོ་ལཱན།" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "དཔར་བཤད་" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "དོན་མཚམས།" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -#, fuzzy -msgctxt "role" -msgid "errata" -msgstr "སི་ར་" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "ལས་འགན་" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "ཨེབ་ལྡེ་ཐོ་ཡིག" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "འདྲེན་ཚིག" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "ཨེཆ་ཊི་ཨེམ་ཨེལ་ ནང་དོན་" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "བཤུད་ཕྲ།" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "བཤུད་ཕྲ།" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -#, fuzzy -msgid "Icon panel" -msgstr "གདམ་ཁའི་པེན།" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "ཨེཆ་ཊི་ཨེམ་ཨེལ་ ནང་དོན་" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "བསྒུལ་བཟོ།" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "ཨེཆ་ཊི་ཨེམ་ཨེལ་ ནང་དོན་" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "བསྒུལ་བཟོ།" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "འཚོལ་ཞིབ་འབད་དོ།" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "བལྟ་སྤྱོད་འབད་ཡོད་པའི་འབྲེལ་ལམ་ཚུ་མངམ་མེད།" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "བསྒྱིར་རྟ།" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "རམས་སོང་ཡོདཔ།" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "རྒྱ་བསྐྱེད་ཅན།" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -#, fuzzy -msgid "vertical" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "ཞིབ་དཔྱད་འབད་ཡོདཔ།" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "ཞིབ་དཔྱད་མ་འབདཝཝ" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "ཨཱོན" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "ཨོཕ" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "ཞིབ་དཔྱད་མ་འབདཝཝ" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "མནན་ཡོདཔ།" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "མ་མནནམ།" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "སེལ་འཐུ་འབད་ཡོདཔ།" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "སྐྱ་ཐལ་ཅན།" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "སེལ་འཐུ་མ་འབདཝ།" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "ནུས་མེད།" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "ནུས་མེད།" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "ནུས་མེད།" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "སྡེབ་དཔྱད་འབད།" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "ནུས་མེད།" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "འཚོལ་" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "ཨོར་ཀ་གསལ་གཞི་ལྷག་བྱེད་དང་ཆེ་ཤེལ།" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "ཁ་བསྡམ་" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "འཚོལ་" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "དོ་ལུ་འཚོལ་ཞིབ་འབད་ (_S)" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "དོན་ལུ་འཚོལ་ཞིབ་འབད་" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "སྒོ་སྒྲིག་གི་མགོ་(_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "སྒོ་སྒྲིག་གི་མགོ་" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "ལས་འགོ་བཙུགས་" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "མཐའ་སྐོར་ལོག་མཚམས་བཟོ་(_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "རྒྱབ་བསྐྱོད་འཚོལ་(_b)" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "དོན་ལུ་འཚོལ་ཞིབ་འབད་" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "ཡི་གུ་མཐུན་སྒྲིག་འབད་(_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "མིང་ཚིག་ཧྲིལ་བུ་རྐྱངམ་ཅིག་མཐུན་སྒྲིག་འབད་(_e)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "གདམ་ཁའི་པེན།" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "སྔོན་སྒྲིག" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "ཚུགས་ཡིག" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "ཨའི་པར་ལིངཀ།" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "གློག་རིམ།" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "སྒོ་སྒྲིག" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "ཨོར་ཀའི་དགའ་གདམ་ཚུ།" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "ལེཔ་ཊོཔ་(_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "ལྡེ་སྒྲོམ་སྒྲིག་བཀོད་" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "ལས་འགོ་བཙུགས་" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "འབུར་ཡིག་བསྡམ་ཐག་ཚུ་" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "གློག་རིམ།" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "ཡར་འཕེལ་ཕྲ་རིང་།" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "ཆ་མཉམ་སླབ B_y:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "ཆ་མཉམ་སླབ B_y:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "ཡོངས་ཁྱབ་" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "སྐད་ཤུགས་:(_l)" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "སྟུག་ཚད་:(_t)" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "ཚད་:(_R)" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "གང་ཟག་:(_P)" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "ཁ་སླབ་སྒྲ་འཕྲུལ།(_z)" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "ཁསླབ་རིམ་ལུགས།(_s)" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "སྐད་ཀྱི་སྒྲིག་སྟངས་:(_V)" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "སྐད་ཀྱི་སྒྲིག་སྟངས་:(_V)" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "སྐད་ཀྱི་སྒྲིག་སྟངས་:(_V)" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "ཁ་སླབ་ལྕོགས་ཅན་བཟོ།(_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "ཚིག་མང་།(_b)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "བརྡ་དོན་མང་བ།" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "ཆ་མཉམ།(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "ཡིག་རྟགས་གནས་རིམ་l" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "གྲལ་ཐིག་སྟོངམ་ཚུ་ཁ་སླབ་" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "འགོ་མཚམས་དང་ལྟེམས་བཅོས་སླབ།(_i)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "གྲལ་ཐིག་སྟོངམ་ཚུ་ཁ་སླབ་" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "ཁ་སླབ།" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "འབུར་ཡིག་གི་རྒྱབ་སྐྱོར་ ལྕོགས་ཅན་བཟོ།(_s)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "བཅུད་སྡུད་ལས་འགན་གྱི་མིང་།(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "བྲག་ཅ་མིང་ཚིག་ཐེོག་ལས་ ལྕོགས་ཅན་བཟོ།(_w)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "གདམ་ཁ་མངམ་བཀྲམ་སྟོན་འབད།" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "ཅི་མེད།(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "ཨའི་པར་ལིངཀ།" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "ཆེ་ཤེལ་ལྕོགས་ཅན་བཟོ།(_m)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "འབུར་ཡིག" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "ལྡེ་མིག་བྲག་ཅ་ ལྕོགས་ཅན་བཟོ།(_k)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "བྱ་བའི་ལྡེ་མིག་ཚུ་ ལྕོགས་ཅན་བཟོ།(_t)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "ལེགས་བཅོས་འབད་མིའི་ལྡེ་མིག་ ལྕོགས་ཅན་བཟོ།(_m)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "ལས་འགན་ལྡེ་མིག་ཚུ་ལྕོགས་ཅན་བཟོ།(_f)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "ཁ་སླབ་ལྕོགས་ཅན་བཟོ།(_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "ལེགས་བཅོས་འབད་མིའི་ལྡེ་མིག་ ལྕོགས་ཅན་བཟོ།(_m)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "ལས་འགན་ལྡེ་མིག་ཚུ་ལྕོགས་ཅན་བཟོ།(_f)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "བྱ་བའི་ལྡེ་མིག་ཚུ་ ལྕོགས་ཅན་བཟོ།(_t)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -#, fuzzy -msgid "Enable _navigation keys" -msgstr "ལས་འགན་ལྡེ་མིག་ཚུ་ལྕོགས་ཅན་བཟོ།(_f)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "བྲག་ཅ་མིང་ཚིག་ཐེོག་ལས་ ལྕོགས་ཅན་བཟོ།(_w)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "བྲག་ཅ་མིང་ཚིག་ཐེོག་ལས་ ལྕོགས་ཅན་བཟོ།(_w)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "ལྡེ་མིག་གི་བྲག་ཅ།" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "ཨོར་ཀ་ ལེགས་བཅོས་འབད་མི་ལྡེ་མིག་(ཚུ་):(_M)" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "ལྡེ་མིག་བསྡམ་ཐག་ཚུ་" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3204 -#, fuzzy -msgid "Pronunciation" -msgstr "ལས་འགན་" - -#: src/cthulhu/cthulhu-setup.ui:3243 -#, fuzzy -msgid "_Speak all" -msgstr "སླབ་ནིའི་ནང་ཐིག" - -#: src/cthulhu/cthulhu-setup.ui:3257 -#, fuzzy -msgid "Speak _none" -msgstr "སླབ་ནིའི་གྱལ" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -#, fuzzy -msgid "Move _down one" -msgstr "ནང་ཐིག་གཅིག་མར་འགྱོཝ་ཨིན།" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -#, fuzzy -msgid "Move _up one" -msgstr "ནང་ཐིག་གཅིག་ལྟག་ལུ་འགྱོཝ་ཨིན།་" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -#, fuzzy -msgid "Move to _top" -msgstr "ནང་ཐིག་ལུ་སྤོ་" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "འབུར་ཡིག་བསྡམ་ཐག་ཚུ་" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "ལས་རོགས།" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "གྲལ་ཐིག" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "ལས་རོགས།" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "མགུ་རྒྱན་" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "ཚད་འཇལ་ཆ་རྐྱེན་:(_f)" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : ཨཱལ་ཕ, b : བཱ་ར་འོ, c : ཅར་ལི d : ཌེལ་ཊ, e : བྲག་ཅ, f :ཕོགསི་ཊོཊི , g :རྒྱུག་རིལ, h : " -"བཟའ་ཁང་, i : རྒྱ་གར, j : ཇུ་ལིཊི, k : ཀི་ལོ l : ལི་མཱ m : ཁ་པར, n : སྤྱི་ཟླ་བཅུ་གཅིགཔ, " -"o :ཨོསི་ཀར, p : པ་པ q : ཀུས་བེཀ, r : རོ་མིའོ, s :སི་ར, t :ཊེང་གོ, u : གཅིག་མཚུངས, v : རྒྱལ་" -"ལམ, w : ཝིསི་ཀི, x : གློག་དཔར, y : ཡང་ཀི, z : ཛུ་ལུ" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "དབྱེ་ཚན་" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "ཐིག་ཁྲམ།" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -#, fuzzy -msgctxt "textattr" -msgid "invisible" -msgstr "འཛུལ་སྤྱོད་འབད་མ་བཏུབ།" - -#: src/cthulhu/text_attribute_names.py:156 -#, fuzzy -msgctxt "textattr" -msgid "justification" -msgstr "དཔར་བཤད་" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "གཡོན་གྱི་གུག་ཤད། [" - -#: src/cthulhu/text_attribute_names.py:176 -#, fuzzy -msgctxt "textattr" -msgid "line height" -msgstr "གྲལ་ཐིག་གཡས་" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "དོན་མཚམས།" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -#, fuzzy -msgctxt "textattr" -msgid "pixels below lines" -msgstr "གྲལ་ཐིག་སྟོངམ་ཚུ་ཁ་སླབ་" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "གཡས་ཀྱི་གུག་ཤད། ]" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "སི་ཨེ་ཨེལ་ཨི།" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -#, fuzzy -msgctxt "textattr" -msgid "strike through" -msgstr "སྦུག་འབྲེག་" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -#, fuzzy -msgctxt "textattr" -msgid "text rotation" -msgstr "ད་ལྟོའི་གནས་ས་(_u)" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "གྱལ་རིམ་གསརཔ།" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "ཀེར་ཕྲང་ཐིག" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "གྲལ་ཐིག་གཡས་" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -#, fuzzy -msgctxt "textattr" -msgid "writing mode" -msgstr "ལྷབ་ནིའི་ཐབས་ལམ་ཕྱིར་འཐོན་འབད་དོ།" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "གྱལ་རིམ་གསརཔ།" - -#: src/cthulhu/text_attribute_names.py:393 -#, fuzzy -msgctxt "textattr" -msgid "line through" -msgstr "སྦུག་འབྲེག་" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "འབྲེལ་ལམ།" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "གྲལ་ཐིག" - -#: src/cthulhu/text_attribute_names.py:435 -#, fuzzy -msgctxt "textattr" -msgid "char" -msgstr "ཅར་ལི་" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "ཆོག་ཡིག" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "ཨེཕ་ཨེལ་ཨར།" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "ཊི་ཨར་ཊི་བི་ཨེལ།" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "གཡོན་གྱི་གདམ་ལྡེ།" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "གཡས་ཀྱི་གདམ་ལྡེ།" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "དབུས་བསྒྲིགས།" - -#: src/cthulhu/text_attribute_names.py:493 -#, fuzzy -msgctxt "textattr" -msgid "no justification" -msgstr "འགོ་མཚམས་དང་ལྟེམས་བཅོས་སླབ།(_i)" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "བཀང་བྱེད།" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "སེ་མི་ཀོ་ལཱན།" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "རྒྱ་བསྐྱེད་ཅན།" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "རྒྱ་བསྐྱེད་ཅན།" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "རྒྱ་བསྐྱེད་ཅན།" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "རྒྱ་བསྐྱེད་ཅན།" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "སྔོན་སྒྲིག" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "ཚིག་ཡིག" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "མགུ་རྒྱན་" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "གྱལ་རིམ་གསརཔ།" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -#, fuzzy -msgctxt "textattr" -msgid "super" -msgstr "ཡང་དག་" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "བཀག་" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "ཚིག་ཡིག" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "གཤམ་:(_B)" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "ཨེཕ་ཨེལ་ཨར།" - -#: src/cthulhu/text_attribute_names.py:726 -#, fuzzy -msgctxt "textattr" -msgid "rl" -msgstr "ཚད་འཛིན་" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "ཨེབ་ལྡེ།" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "སྡེབ་དཔྱད་འབད།" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -#, fuzzy -msgid "To get to the system menus press the alt+f1 key." -msgstr "ལྷབ་ནིའི་ཐབས་ལམ་ཕྱིར་འཐོན་འབད་ནི་ལུ་ ཐར་ལྡེ་མནན།" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/el.po b/po/el.po deleted file mode 100644 index 96262e2..0000000 --- a/po/el.po +++ /dev/null @@ -1,9374 +0,0 @@ -# translation of cthulhu.HEAD.po to Greek -# Greek translation of el. -# Copyright (C) 2006 THE el'S COPYRIGHT HOLDER -# This file is distributed under the same license as the el package. -# nikos , 2006. -# Simos Xenitellis , 2006. -# Giannis Katsampirhs , 2008. -# Kostas Papadimas , 2008. -# Jennie Petoumenou , 2009. -# Marios Zindilis , 2011. -# Dimitris Spingos (Δημήτρης Σπίγγος) , 2012, 2013, 2014, 2015. -# Efstathios Iosifidis , 2013, 2016. -# Dimitris Maroulidis , 2019. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2020-08-08 18:56+0300\n" -"Last-Translator: Efstathios Iosifidis \n" -"Language-Team: Greek, Modern (1453-) \n" -"Language: el\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.3\n" -"X-Project-Style: gnome\n" - -msgid "Cthulhu Screen Reader" -msgstr "Αναγνώστης οθόνης Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "οθόνη;αναγνώστης;προσβασιμότητα;ομιλία;μπράιγ;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr ";;;" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "ειδπ" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "κινσχ" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "βλς" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "ημρλ" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "καμβ" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "λζντ" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "κτλγχ" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "επλγχρμ" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "κφλστλ" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "σνδσμ" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "επ.ημ" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "εικ" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "πλσ" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "καντράν" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "δλγ" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "τμπλκτλγ" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "σχεδίαση" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "επλγραμτσ" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "επλγαρχ" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "επλγραμ" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "μορφή" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "γλτμπλ" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "κφλδ" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "εικν" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "εσπλαίσ" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "ετκ" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "τμπλεπίπ" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "σνδ" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "λστ" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "αντκλστ" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "μν" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "εργμν" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "αντμν" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "τμπλεπλ" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "σλδ" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "λστστλθ" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "πνκεφγ" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "κδκ" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "αναδμν" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "μπρπρδ" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "κμπ" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "αντκμνrd" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "τμπrt" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "κφλδγρμ" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "γρμκλ" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "τμπλκλ" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "πργρ" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "δχρσ" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "μπρκλσ" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "δχρτμπλ" - -# -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "γρμκτστ" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "πνκ" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "κελ" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "ανκαπσμν" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "τρμτ" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "κειμ" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "κμπενλ" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "εργθ" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "συμβ" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "δνδ" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "πνκδεν" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "αγν" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "θρψ" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "παρθ" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "κφλ" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "υπσλ" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "παργ" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "εφ" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "αυτ" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "γρμπξ" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "ενσ" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Τσεχικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Ισπανικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Γαλλικός βαθμός 2 του Καναδά" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Γαλλικός βαθμός 2 της Γαλλίας" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Βαθμός 1 της Λετονίας" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Γερμανικός βαθμός 1 της Ολλανδίας" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Νορβηγικός βαθμός 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Νορβηγικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Νορβηγικός βαθμός 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Νορβηγικός βαθμός 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Πολωνικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Πορτογαλικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Σουηδικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Αραβικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Ουαλικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Ουαλικός βαθμός 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Γερμανικός βαθμός 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Γερμανικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Γερμανικός βαθμός 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Αγγλικά Ενωμένου Βασιλείου βαθμός 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Αγγλικά Ενωμένου Βασιλείου βαθμός 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Αγγλικά ΗΠΑ βαθμός 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Αγγλικά ΗΠΑ βαθμός 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Γαλλικά Καναδά βαθμός 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Γαλλικά Γαλλίας βαθμός 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Ελληνικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Ινδικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ουγγρικός υπολογιστής 8 κουκκίδων" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Βαθμός 1 Ουγγαρίας" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Βαθμός 1 Ουγγαρίας" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Ιταλικός βαθμός 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Γερμανικός βαθμός 1 του Βεγίου" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "διάστημα" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "νέα γραμμή" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "στηλοθέτης" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "θαυμαστικό" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "εισαγωγικό" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "αριθμός" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "δολάριο" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "ποσοστό" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "και" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "απόστροφος" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "αριστερή παρένθεση" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "δεξιά παρένθεση" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "αστερίσκος" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "συν" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "κόμμα" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "παύλα" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "τελεία" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "κάθετος" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "άνω-κάτω τελεία" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "ερωτηματικό ελληνικό (;)" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "μικρότερο" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "ίσον" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "μεγαλύτερο" - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-# -# -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-# -# -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "λατινικό ερωτηματικό" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "παπάκι" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "αριστερή αγκύλη" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "ανάποδη κάθετος" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "δεξιά αγκύλη" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "καρέτα" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "υπογραμμισμένο" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "δασεία" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "αριστερό άγκιστρο" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "κατακόρυφη μπάρα" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "δεξί άγκιστρο" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "περισπωμένη" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "διάστημα μη συμπτυσσόμενο" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "αντεστραμμένο θαυμαστικό" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "σεντς" - -# #-#-#-#-# gnome-icon-theme.HEAD.el.po (el) #-#-#-#-# -# 48x48/emblems/emblem-sound.icon.in.h:1 -# 48x48/emblems/emblem-sound.icon.in.h:1 -# 48x48/emblems/emblem-sound.icon.in.h:1 -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "λίρες" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "σύμβολο νομίσματος" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "ιαπωνικό γιεν" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "διακεκομμένη μπάρα" - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-# -# -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-# -# -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "παράγραφος" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "διαλυτικά" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "πνευματικά δικαιώματα" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "εκθέτης α" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "αριστερά διπλά εισαγωγικά" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "λογικό μη" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "ενωτικό" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "σήμα κατατεθέν" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "σημείο προφοράς μακρού" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "βαθμοί" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "συν πλην" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "εκθέτης 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "εκθέτης 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "οξεία" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "μι" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "επισήμανση παραγράφου" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "άνω τελεία" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "εκθέτης 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "αριθμητικό" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "δεξιά διπλά εισαγωγικά" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "ένα τέταρτο" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "ένα δεύτερο" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "τρία τέταρτα" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "αντεστραμμένο ερωτηματικό" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "α με δασεία" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "Α κεφαλαίο με δασεία" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "Α με οξεία" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "Α με circumflex" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "Α με περισπωμένη" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "Α με διαλυτικά" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "Α με κύκλο" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "Α Ε" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "Ε με δασεία" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "Ε με οξεία" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "Ε με circumflex" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "Ε με διαλυτικά" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "Ι με δασεία" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "Ι με οξεία" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "Ι με circumflex" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "Ι με διαλυτικά" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ΕΘ" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "Ν με περισπωμένη" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "Ο με δασεία" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "Ο με οξεία" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "Ο με circumflex" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "Ο με περισπωμένη" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "Ο με διαλυτικά" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "επί" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "Ο διαγραμμένο" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U με δασεία" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U με οξεία" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U με circumflex" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U με διαλυτικά" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Υ με οξεία" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "ΘΟΡΝ" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "ες τσετ" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "α με δασεία" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "α με circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "α με περισπωμένη" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "α με διαλυτικά" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "α με κύκλο" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c με cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "ε με δασεία" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "ε με οξεία" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "ε με circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "ε με διαλυτικά" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "ι με δασεία" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "ι με οξεία" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "ι με circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "ι με διαλυτικά" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "εθ" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "ν με περισπωμένη" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "ο με δασεία" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "ο με οξεία" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "ο με circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "ο με περισπωμένη" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "ο με διαλυτικά" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "δια" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "ο διαγραμμένο" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "θορν" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u με οξεία" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u με δασεία" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u με καρέτα" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u με διαλυτικά" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y με οξεία" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y με διαλυτικά" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Υ με διαλυτικά" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "φλορίνι" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "παύλα" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "αριστερό απλό εισαγωγικό" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "δεξιό απλό εισαγωγικό" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "χαμηλό απλό εισαγωγικό" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "αριστερό διπλό εισαγωγικό" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "δεξί διπλό εισαγωγικό" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "χαμηλό διπλό εισαγωγικό" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "σταυρός στίξης" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "διπλός σταυρός στίξης" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "κουκκίδα" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "τριγωνική κουκκίδα" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "τοις χιλίοις" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "πρώτα" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "δεύτερα" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "τριπλή οξεία" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "κουκκίδα με παύλα" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "ευρώ" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "εμπορικό σήμα" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "σύμβολο τσεκαρίσματος" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "έντονο σύμβολο τσεκαρίσματος" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "κουκκίδα σε σχήμα χ" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "εκθέτης 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "εκθέτης 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "εκθέτης 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "εκθέτης 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "εκθέτης 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "εκθέτης 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "εκθέτης 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "εκθέτης συν" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "εκθέτης μείον" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "εκθέτης ίσον" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "εκθέτης αριστερή παρένθεση" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "εκθέτης δεξιά παρένθεση" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "εκθέτης n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "δείκτης 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "δείκτης 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "δείκτης 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "δείκτης 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "δείκτης 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "δείκτης 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "δείκτης 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "δείκτης 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "δείκτης 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "δείκτης 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "δείκτης συν" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "δείκτης μείον" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "δείκτης ίσον" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "δείκτης αριστερή παρένθεση" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "δείκτης δεξιά παρένθεση" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "κουκκίδα μαύρο τετράγωνο" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "κουκκίδα μαύρο διαμάντι" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "χαρακτήρας αντικατάστασης αντικειμένου" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Μετακινεί το δείκτη στο τρέχον αντικείμενο." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" -"Πραγματοποιεί αριστερό κλικ στο τρέχον αντικείμενο επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" -"Πραγματοποιεί δεξί κλικ στο τρέχον αντικείμενο επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Εκφώνηση ολόκληρου του εγγράφου" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Εκφωνεί ολόκληρο το παράθυρο χρησιμοποιώντας επίπεδη προεπισκόπηση." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Εκτελεί τη βασική λειτουργία όπου βρίσκεστε." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Εκτελεί τη λεπτομερή λειτουργία όπου βρίσκεστε." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Εκφώνηση τρέχουσας επιλογής" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Εκφώνηση λεπτομερειών συνδέσμου" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Παρουσίαση του προεπιλεγμένου κουμπιού" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Εκφωνεί την μπάρα κατάστασης." - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Εκφωνεί το στηλοθέτη του τίτλου." - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Άνοιγμα διαλόγου εύρεσης" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Εμφάνιση λίστας ενεργειών" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Αναζητά την επόμενη διεργασία μιας συμβολοσειράς." - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Αναζητά την προηγούμενη διεργασία μιας συμβολοσειράς." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Εισάγει και τερματίζει τη λειτουργία επίπεδης προεπισκόπηση." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στην τελική περιοχή." - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στην αρχική τοποθεσία." - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στην τελική περιοχή." - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" -"Μετακινεί την επίπεδη προεπισκόπηση στην αρχή της προηγούμενης γραμμής." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Εκφωνεί την τρέχουσα γραμμή επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Συλλαβίζει την τρέχουσα γραμμή επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Συλλαβίζει φωνητικά την τρέχουσα γραμμή επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στην αρχή της επόμενης γραμμής." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" -"Μετακινεί την επίπεδη προεπισκόπηση στο προηγούμενο αντικείμενο ή λέξη." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Εκφωνεί το τρέχον αντικείμενο ή λέξη επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Συλλαβίζει το τρέχον αντικείμενο ή λέξη επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Συλλαβίζει φωνητικά το τρέχον αντικείμενο ή λέξη επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στο επόμενο αντικείμενο ή λέξη." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" -"Μετακινεί την επίπεδη προεπισκόπηση στη λέξη πάνω από την τρέχουσα λέξη." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Εκφωνεί το τρέχον αντικείμενο επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" -"Μετακινεί την επίπεδη προεπισκόπηση στη λέξη κάτω από την τρέχουσα λέξη." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στον προηγούμενο χαρακτήρα." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Εκφωνεί τον τρέχοντα χαρακτήρα επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Αναπαράγει φωνητικά τον τρέχοντα χαρακτήρα επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" -"Εκφωνεί την τιμή unicode του τρέχοντος χαρακτήρα επίπεδης προεπισκόπησης." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στον επόμενο χαρακτήρα." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στο τέλος της γραμμής." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στο τέλος αριστερά." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Αντιγράφει τα περιεχόμενα κάτω από επίπεδη προεπισκόπηση στο πρόχειρο." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Προσαρτά τα περιεχόμενα κάτω από επίπεδη προεπισκόπηση στο πρόχειρο." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Μετακινεί την επίπεδη προεπισκόπηση στην τελική περιοχή." - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Πραγματοποιεί εναλλαγή αν θα γίνεται ανάγνωση του τρέχοντος κελιού του " -"πίνακα ή ολόκληρης της γραμμής." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" -"Κάνει ανάγνωση των ιδιοτήτων που έχουν σχέση με τον τρέχοντα χαρακτήρα " -"κειμένου." - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Αλλαγή της προβολής του μπράιγ στα αριστερά." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Αλλαγή της προβολής του μπράιγ στα δεξιά." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Επιστρέφει στον αντικείμενο με εστίαση πληκτρολογίου." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Ενεργοποιεί και απενεργοποιεί τη συντετμημένη μπράιγ." - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Επεξεργάζεται τα πλήκτρα μετακίνησης δρομέα." - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Σημειώνει την αρχή του κειμένου που θα επιλεγεί." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Σημειώνει το τέλος του κειμένου που θα επιλεγεί." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Εισάγει την κατάσταση μάθησης. Πιέστε διαφυγή για να εξέλθετε από την " -"κατάσταση μάθησης." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Μείωση ρυθμού εκφώνησης." - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Αύξηση ρυθμού εκφώνησης." - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Μείωση βήματος εκφώνησης." - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Αύξηση βήματος εκφώνησης." - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Αύξηση έντασης της ομιλίας" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Μειώνει έντασης της ομιλίας" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Επιλογή προηγούμενης ρύθμισης ομιλίας" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Επιλογή επόμενης ρύθμισης ομιλίας" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Μείωση τρέχουσας ρύθμισης ομιλίας" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Αύξηση τρέχουσας ρύθμισης ομιλίας" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Αποθήκευση ρυθμίσεων ομιλίας" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Εναλλάσσει τη σίγαση της εκφώνησης." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Εναλλάσσει το επίπεδο περιφραστικότητας της ομιλίας." - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Εναλλαγή κατάστασης αναστολής" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Έξοδος από τον αναγνώστη οθόνης" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Εμφανίζει το διάλογο ρύθμισης των προτιμήσεων." - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Εμφανίζει το διάλογο ρύθμισης των προτιμήσεων των εφαρμογών." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Εναλλάσσει την εκφώνηση ή μη των εσοχών και της στοίχισης." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Αλλαγές στο στυλ της προφοράς του αριθμού." - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Προχωρά στο επόμενο επίπεδο εκφώνησης στίξης." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Προχωρά στο επόμενο επίπεδο εκφώνησης πληκτρολόγησης." - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Περιδιαβαίνει τo επόμενo προφίλ ρυθμίσεων." - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Προχωρά στο επόμενο στυλ κεφαλαίων." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Προχωρά στο επόμενο επίπεδο εκφώνησης πληκτρολόγησης." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Εναλλάσσει το επίπεδο αποσφαλμάτωσης κατά την εκτέλεση." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Σελιδοδείκτης πού σε σχέση με την τρέχουσα τοποθεσία." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Μετάβαση στην προηγούμενη τοποθεσία σελιδοδείκτη" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Μετάβαση στο σελιδοδείκτη" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Μετάβαση στην επόμενη τοποθεσία σελιδοδείκτη" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Προσθήκη σελιδοδείκτη" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Αποθήκευση σελιδοδεικτών" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Εναλλαγή της λειτουργίας προεπισκόπησης με το ποντίκι." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Παρουσίαση τρέχουσας ώρας" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Παρουσίαση τρέχουσας ημερομηνίας" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Αναφέρει πληροφορίες για το τρέχον αντικείμενο." - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Στέλνει την επόμενη εντολή στην τρέχουσα εφαρμογή." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Εκφώνηση και μπράιγ ενός προηγούμενου μηνύματος σε δωμάτιο συνομιλίας." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Επιλογή του αν θα ανακοινώνουμε ότι οι φίλοι μας πληκτρολογούν." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Επιλογή του αν θα παρέχουμε ξεχωριστό ιστορικό μηνυμάτων ανά δωμάτιο " -"συνομιλίας." - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Επιλογή του αν θα εισάγουμε ως πρόθεμα σε μηνύματα δωματίου συνομιλίας το " -"όνομα του δωματίου συνομιλίας." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Γραμμή αριστερά" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Γραμμή δεξιά" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Γραμμή πάνω" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Γραμμή κάτω" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Πάγωμα" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Αρχή αριστερά" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Κάτω αριστερά" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Τοποθεσία δρομέα" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Έξι κουκίδες" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Μετακίνηση δρομέα" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Αρχή αποκοπής" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Τέλος αποκοπής" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Παρουσίαση του τελευταίου μηνύματος ειδοποίησης." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Παρουσίαση λίστας μηνυμάτων ειδοποίησης" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Παρουσίαση προηγούμενου μηνύματος ειδοποίησης." - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Παρουσίαση του τελευταίου μηνύματος ειδοποίησης." - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Μετάβαση στον επόμενο χαρακτήρα" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Μετάβαση στον προηγούμενο χαρακτήρα" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Μετάβαση στην επόμενη λέξη" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Μετάβαση στην προηγούμενη λέξη" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Μετάβαση στην επόμενη γραμμή" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Μετάβαση στην προηγούμενη γραμμή" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Μετάβαση στην αρχή του αρχείου" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Μετάβαση στο τέλος του αρχείου" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Μετάβαση στην αρχή της γραμμής" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Μετάβαση στο τέλος της γραμμής" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Μετάβαση στο επόμενο αντικείμενο" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Μετάβαση στο προηγούμενο αντικείμενο" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Προκαλεί την εμφάνιση όλων των πολλαπλών επιλογών του πλαισίου." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Εναλλάσσει μεταξύ εγγενούς περιήγησης και περιήγησης δρομέα αναγνώστη οθόνης." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Προχωρημένη ρύθμιση ευγενικότητας ενεργής περιοχής." - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" -"Ρύθμιση προκαθορισμένου επιπέδου ευγενικότητας ενεργής περιοχής ως " -"απενεργοποιημένο." - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Προεπισκόπηση αναγγελίας ζωντανών περιοχών." - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Ζωντανές περιοχές παρακολούθησης οθόνης." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" -"Εστίαση στο αναδυόμενο αντικείμενο ή επιστροφή εστίασης στο αρχικό " -"αντικείμενο." - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Ρύθμιση της γραμμής για χρήση ως δυναμικής κεφαλίδας στήλης." - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Καθαρίζει τις δυναμικές επικεφαλίδες στήλης." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Ρύθμιση της στήλης για χρήση ως δυναμικής κεφαλίδας γραμμής." - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Καθαρισμός των δυναμικών επικεφαλίδων γραμμών" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Παρουσιάζει τα περιεχόμενα της γραμμής εισαγωγής." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Κάνει εναλλαγή στα πλήκτρα δομικής πλοήγησης." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Μετάβαση στην προηγούμενη ενότητα σε παράθεση" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Μεταβαίνει στην επόμενη ενότητα σε παράθεση." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Εμφανίζει μια λίστα μεγάλων παραθέσεων." - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Μεταβαίνει στο προηγούμενο κουμπί." - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Μεταβαίνει στο επόμενο κουμπί." - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Εμφανίζει μια λίστα κουμπιών." - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Μεταβαίνει στο προηγούμενο πλαίσιο επιλογής." - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Μεταβαίνει στο επόμενο πλαίσιο επιλογής." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Εμφανίζει μια λίστα πλαισίων επιλογής." - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Μεταβαίνει στο προηγούμενο επιλέξιμο." - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Μεταβαίνει στο επόμενο επιλέξιμο." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Εμφανίζει μια λίστα επιλέξιμων." - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Μεταβαίνει στο προηγούμενο πλαίσιο πολλαπλών επιλογών." - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Μεταβαίνει στο επόμενο πλαίσιο πολλαπλών επιλογών." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Μεταβαίνει στην αρχή του πλαισίου." - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Μεταβαίνει στο τέλος του πλαισίου." - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Εμφανίζει μια λίστα πλαισίων πολλαπλών επιλογών." - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Μεταβαίνει στην προηγούμενη καταχώριση." - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Μεταβαίνει στην επόμενη καταχώριση." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Εμφανίζει μια λίστα καταχωρίσεων." - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Μεταβαίνει στο προηγούμενο πεδίο μορφοποίησης." - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Μεταβαίνει στο επόμενο πεδίο μορφοποίησης." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Εμφανίζει μια λίστα πεδίων φόρμας." - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Μεταβαίνει στην προηγούμενη επικεφαλίδα." - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Μεταβαίνει στην επόμενη επικεφαλίδα." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Εμφανίζει μια λίστα κεφαλίδων." - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Μετάβαση στην προηγούμενη επικεφαλίδα επιπέδου %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Μετάβαση στην επόμενη επικεφαλίδα επιπέδου %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Εμφάνιση λίστας επικεφαλίδων επιπέδου %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Μετάβαση στον προηγούμενο πίνακα" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Μετάβαση στον επόμενο πίνακα" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Εμφάνιση λίστας πινάκων" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Μετάβαση στην προηγούμενη εικόνα" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Μετάβαση στην επόμενη εικόνα" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Εμφάνιση λίστας εικόνων" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Μετάβαση στο προηγούμενο ορόσημο" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Μετάβαση στο επόμενο ορόσημο" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Εμφάνιση λίστας οροσήμων" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Μετάβαση στο προηγούμενο μεγάλο αντικείμενο" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Μετάβαση στο επόμενο μεγάλο αντικείμενο" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Εμφάνιση λίστας με μεγάλα αντικείμενα" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Μετάβαση στον προηγούμενο σύνδεσμο" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Μετάβαση στον επόμενο σύνδεσμο" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Εμφάνιση λίστας συνδέσμων" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Μετάβαση στην προηγούμενη λίστα" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Μετάβαση στην επόμενη λίστα" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Εμφάνιση λίστας από λίστες" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Μετάβαση στην προηγούμενη λίστα αντικειμένων" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Μετάβαση στην επόμενη λίστα αντικειμένων" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Εμφανίζει έναν κατάλογο από στοιχεία λίστας." - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Μετάβαση στην προηγούμενη ενεργή περιοχή" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Μετάβαση στην επόμενη ενεργή περιοχή" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Μετάβαση στην τελευταία ενεργή περιοχή που έκανε μια ανακοίνωση." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Μετάβαση στο γονικό στοιχείο του αντικειμένου με εστίαση πλοηγού." -"Τυπώνει πληροφορίες αποσφαλμάτωσης για τον πρόγονο του εστιασμένου " -"αντικειμένου." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Μετάβαση στο πρώτο παιδί του αντικειμένου με εστίαση πλοηγού." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Μετάβαση στον επόμενο αδελφό του αντικειμένου με εστίαση πλοηγού." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Μετάβαση στον προηγούμενο αδελφό του αντικειμένου με εστίαση πλοηγού." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Επιστρέφει στον αντικείμενο με εστίαση πληκτρολογίου." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Κάνει εναλλαγή στα πλήκτρα δομικής πλοήγησης." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Μετάβαση στην προηγούμενη παράγραφο" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Μετάβαση στην επόμενη παράγραφο" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Εμφάνιση λίστας παραγράφων" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Μετάβαση στο προηγούμενο επιλέξιμο κουμπί" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Μετάβαση στο επόμενο επιλέξιμο κουμπί" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Εμφάνιση λίστας επιλέξιμων κουμπιών" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Μετάβαση στον προηγούμενο οριοθέτη" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Μετάβαση στον επόμενο οριοθέτη" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Μετάβαση στον προηγούμενο πίνακα" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Μετάβαση στον επόμενο πίνακα" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Εμφάνιση λίστας πινάκων" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Μετάβαση προς τα κάτω κατά ένα κελί" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Μετάβαση στο πρώτο κελί του πίνακα" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Μετάβαση στο τελευταίο κελί του πίνακα" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Μετάβαση αριστερά κατά ένα κελί" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Μετάβαση δεξιά κατά ένα κελί" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Μετάβαση προς τα πάνω κατά ένα κελί" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Εναλλαγή της λειτουργίας διάταξης." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Εναλλαγή μεταξύ λειτουργίας περιήγησης και λειτουργίας εστίασης." - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Ενεργοποιεί την κολλώδη λειτουργία εστίασης." - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Ενεργοποιεί την κολλώδη λειτουργία περιήγησης." - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Μετάβαση στον προηγούμενο σύνδεσμο που δεν έχει επισκεφθεί" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Μετάβαση στον επόμενο σύνδεσμο που δεν έχει επισκεφθεί" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Εμφάνιση λίστας με συνδέσμους που δεν έχει επισκεφθεί" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Μετάβαση στον προηγούμενο σύνδεσμο που έχει επισκεφθεί" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Μετάβαση στον επόμενο σύνδεσμο που έχει επισκεφθεί" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Εμφάνιση λίστας με συνδέσμους που έχει επισκεφθεί" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "γκριζογαλάζιο" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "παλαιωμένο λευκό" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "πρασινογαλάζιο" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "γαλάζιο (azure)" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "μπεζ" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "σκούρο κρεμ" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "μαύρο" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "ζαχαρί" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "γαλάζιο" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "γαλάζιο ιώδες" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "καστανό" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "καφέ του ξύλου" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "γαλανό του στρατού" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "φωτεινό κιτρινοπράσινο" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "σοκολατί" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "κοραλλί" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "μέτριο γαλανό" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "ασημί του καλαμποκιού" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "βαθύ κόκκινο" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "κυανό" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "σκούρο γαλάζιο" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "σκούρο κυανό" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "σκούρο χρυσοκίτρινο" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "σκούρο γκρίζο" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "σκούρο πράσινο" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "σκούρο χακί" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "σκούρο ματζέντα" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "σκούρο λαδοπράσινο" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "σκούρο πορτοκαλί" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "σκούρο ορχιδέας" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "σκούρο κόκκινο" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "σκούρο σολομού" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "σκούρο θαλασσοπράσινο" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "σκούρο τεφροκύανο" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "σκούρο γκρίζο σχιστόλιθου" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "σκούρο τιρκουάζ" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "σκούρο βιολετί" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "βαθύ ροζ" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "βαθύ γαλάζιο ουρανού" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "αμυδρό γκρίζο" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "σκούρο ηλεκτρικό γαλάζιο" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "κεραμιδί" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "λευκό των ανθών" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "πράσινο του δάσους" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "φούξια" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "γκρίζο ουρανί" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "λευκό φαντάσματος" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "χρυσαφί" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "χρυσοκίτρινο" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "γκρίζο" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "πράσινο" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "πρασινοκίτρινο" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "μελί δροσιά" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "καυτό ροζ" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "ινδικό κόκκινο" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "λουλακί" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "ελεφαντόδοτο" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "χακί" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "λεβάντα" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "κοκκίνισμα λεβάντας" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "πράσινο πρασιάς" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "τούλι λεμονιού" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "ανοιχτό γαλάζιο" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "ανοιχτό κοραλί" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "ανοιχτό κυανό" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "ανοιχτό χρυσοκίτρινο" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "ανοιχτό γκρίζο" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "ανοιχτό πράσινο" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "ανοιχτό ροζ" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "ανοιχτό σολομού" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "ανοιχτό θαλασσοπράσινο" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "ανοιχτό γαλάζιο ουρανού" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "ανοιχτό γκρίζο σχιστόλιθου" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "ανοιχτό γαλάζιο ατσαλιού" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "ανοιχτό κίτρινο" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "λαχανί" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "πράσινο λαχανί" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "σπαγγί" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "ματζέντα" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "καστανέρυθρο" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "μέτριο πρασινογαλάζιο" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "μέτριο γαλάζιο" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "μέτριο ορχιδέας" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "μέτριο πορφυρό" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "μέτριο θαλασσοπράσινο" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "μεσαίο τεφροκύανο" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "μεσαίο πράσινο της άνοιξης" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "μέτριο τιρκουάζ" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "μέτριο ιώδες κόκκινο" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "πολύ σκούρο γαλάζιο" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "κρεμ δυόσμου (βεραμάν)" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "θολό τριανταφυλλί" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "μόκα" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "άσπρο ναβάχο" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "γαλάζιο ναυτικού" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "εκρού" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "λαδί" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "πράσινο λαδί" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "πορτοκαλί" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "πορτοκαλοκόκκινο" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "ορχιδέα" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "αχνό χρυσοκίτρινο" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "αχνό πράσινο" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "αχνό τιρκουάζ" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "αχνό ιώδες κόκκινο" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "αχνό ροζ" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "αχνό ροδακινί" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "περού (ανοιχτό καφέ)" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "ροζ" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "δαμασκηνί" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "αχνό γαλάζιο" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "πορφυρό" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "κόκκινο" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "καφέ ροζ" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "έντονο γαλάζιο" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "βαθύ καφέ" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "σομόν" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "μπεζ της άμμου" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "θαλασσοπράσινο" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "κοχύλι" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "καφεκίτρινο (σιένα)" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "ασημί" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "ουρανί" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "τεφροκύανο" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "γκρίζο σχιστόλιθου" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "χιονί (έντονο λευκό)" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "πράσινο της άνοιξης" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "γαλάζιο του ατσαλιο" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "ώχρα" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "σκούρο κυανό (πετρόλ)" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "ανοιχτό βιολετί (σικλαμέν)" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "τοματί" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "τιρκουάζ" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "βιολετί" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "σταρένιο" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "άσπρο" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "λευκός καπνός" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "κίτρινο" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "κίτρινη οθόνη" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "Ε_νεργοποίηση" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Αυτόματη λειτουργία εστίασης κατά τη δομική πλοήγηση" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Αυτόματη λειτουργία εστίασης κατά την πλοήγηση δρομέα" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Αυτόματη λειτουργία εστίασης κατά την πλοήγηση δρομέα" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Τελεία _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Τελεία _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Τελείες 7 _και 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Ακύρωση" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Μετάβαση σε" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Εντάξει" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Εικονίδιο" - -# #-#-#-#-# nautilus.HEAD.el.po (el) #-#-#-#-# -# -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Καμία" - -# -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Ορθογραφικός έλεγχος" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Ανακοίνωση όταν πληκτρολογούν οι _φίλοι" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Δίνει ιστορικά ειδικού _μηνύματος του δωματίου συνομιλίας" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Εκφώνηση μηνυμάτων από" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Όλα τα κα_νάλια" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Όλα τα κανάλια όταν οποιο_δήποτε %s παράθυρο είναι ενεργό" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Ένα κανάλι μόνο αν το _παράθυρό του είναι ενεργό" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Εκφώνηση ονόματος δωματίου συνομιλίας" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Ενεργοποίηση λειτουργίας διάταξης για το περιεχόμενο" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "διπλό κλικ" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "τριπλό κλικ" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Προκαθορισμένος συνθέτης" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Ενεργή συμβολοσειρά" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Συμβολοσειρά αντικατάστασης" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Ενεργοποίηση ανακοίνωσης _χαρακτήρων" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Ενεργοποίηση για συνδυαζόμενα _διακριτικά σημεία" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Τρέχουσα τοποθεσία" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Ελάχιστο μήκος κειμένου που ταιριάζει:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Εύρεση επιλογών" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Εκφώνηση _μόνο των διαφοροποιημένων γραμμών κατά την αναζήτηση" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Εκφώνηση αποτελεσμάτων κατά τη διάρκεια της _αναζήτησης" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Εντολή" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Συνδυασμός πλήκτρων" - -# #-#-#-#-# gnome-system-tools.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Προεπιλογή" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Λειτουργίας διάταξης." - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-# -# -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-# -# -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Ενέργειες" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Συνδυασμοί μπράιγ" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Σελιδοδείκτες" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Ώρα και ημερομηνία" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Απενεργοποιήθηκε η προεπισκόπηση ποντικιού." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "πλοήγηση" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Λειτουργία αντικειμένου." - -# #-#-#-#-# gnome-icon-theme.HEAD.el.po (el) #-#-#-#-# -# 48x48/emblems/emblem-sound.icon.in.h:1 -# 48x48/emblems/emblem-sound.icon.in.h:1 -# 48x48/emblems/emblem-sound.icon.in.h:1 -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Χωρίς συνδυασμό" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Έξοδος από την επίπεδη προεπισκόπηση." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Εναλλάσσει το επίπεδο περιφραστικότητας της ομιλίας." - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "κύριο περιεχόμενο" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Τροποποιημένο" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Επιφάνεια εργασίας" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Ειδοποίηση" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Λήφθηκε" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Ειδοποίηση %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Προτιμήσεις Cthulhu για %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Σημείωση στο μπράιγ" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Χρήση του τρέχοντος εκτός κι αν" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Εκφώνηση" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Αποθήκευση προφίλ ως διένεξη" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Διένεξη προφίλ χρήστη!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Το προφίλ %s υπάρχει ήδη.\n" -"Να ενημερωθεί το υπάρχων προφίλ με αυτές τις νέες αλλαγές;" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Φόρτωση προφίλ χρήστη" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Πρόκειται να αλλάξετε το ενεργό προφίλ. Αν έχετε\n" -"μόλις κάνει αλλαγές στις προτιμήσεις σας, θα\n" -"χαθούν κατά τη φόρτωση του προφίλ.\n" -"\n" -"Συνέχεια φόρτωσης προφίλ αγνοώντας τις προηγούμενες αλλαγές;" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Αποθήκευση προφίλ ως" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Όνομα _προφίλ:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Αφαίρεση προφίλ χρήστη" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Πρόκειται να αφαιρέσετε το προφίλ %s. Όλες οι μη αποθηκευμένες αλλαγές και " -"ρυθμίσεις του προφίλ θα χαθούν. Θέλετε να συνεχίσετε με την αφαίρεση του " -"προφίλ και των σχετικών ρυθμίσεων;" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Όλα" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Εφαρμογή" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Παράθυρο" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Κανένα" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Κάποια" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Περισσότερα" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Γραμμή" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Πρόταση" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Μεγάλη παράθεση" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Κουμπί" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Λεζάντα" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Πλαίσιο επιλογής" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Επιλέξιμο" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Πλαίσιο πολλαπλών επιλογών" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Περιγραφή" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Kεφαλίδα" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "παρεμβάλλω" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Εικόνα" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Ετικέτα" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Ορόσημο" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Επίπεδο" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Σύνδεσμος" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Λίστα" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Στοιχείο λίστας" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Αντικείμενο" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Παράγραφος" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Ραδιοπλήκτρο" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Ρόλος" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Επιλεγμένο στοιχείο" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Κατάσταση" - -# #-#-#-#-# gtkhtml.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# balsa-el.po (balsa 0.9.3.1) #-#-#-#-## -# #-#-#-#-# bonobo-el.po (bonobo 0.34) #-#-#-#-## -# #-#-#-#-# gimp-script-fu-el.po (gimp-script-fu 1.0) #-#-#-#-## -# #-#-#-#-# gtkhtml-el.po (gtkhtml 0.8.1) #-#-#-#-## -# #-#-#-#-# gtop-el.po (gtop 1.0.9) #-#-#-#-## -# #-#-#-#-# guppi3-el.po (guppi3 1.0) #-#-#-#-## -# #-#-#-#-# nautilus-el.po (nautilus 0.8.3) #-#-#-#-## -# #-#-#-#-# sodipodi-el.po (sodipodi 0.25) #-#-#-#-## -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-## -# #-#-#-#-# achtung-el.po (achtung 0.99.0) #-#-#-#-## -# #-#-#-#-# gaim-el.po (gaim 0.48) #-#-#-#-## -# #-#-#-#-# screem-el.po (screem 1.0) #-#-#-#-## -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Κείμενο" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Τιμή" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Μεγάλες παραθέσεις" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Κουμπιά" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Πλαίσια επιλογής" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Επιλέξιμα" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Πλαίσια πολλαπλών επιλογών" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Καταχωρίσεις" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Πεδία φόρμας" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Kεφαλίδες" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "παρεμβάλλω" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Εικόνες" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Κεφαλίδες στο επίπεδο %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Ορόσημα" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Μεγάλα αντικείμενα" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Σύνδεσμοι" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Λίστες" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Στοιχεία λίστας" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Παράγραφοι" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Ραδιοπλήκτρα" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Πίνακες" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Ανεπίσκεπτοι σύνδεσμοι" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Αναγνωσμένοι σύνδεσμοι" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Πλοήγηση σελίδας" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Αυτόματη εκκίνηση εκφώνησης μια σελίδας όταν αρχίζει η _φόρτωσή της" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Παρουσίαση περίληψης της σελίδας κατά τη φόρτωση της" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Χρήση παύσεων για κατάτμηση της ομιλίας σε _τμήματα" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "προκαθορισμένη φωνή %s" - -# #-#-#-#-# gnome-system-tools.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Προεπιλογή" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Σύνδεσμος" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Σύστημα" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Κεφαλαία" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Ορθογραφικός έλεγχος" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Ορ_θογραφικός έλεγχος" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "_Υποδείξεις ορθογραφίας" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Παρόν πε_ριεχόμενο σφάλματος" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Εκφώνηση συντεταγμένων κελιών λογιστικών φύλλων" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Εκφώνηση πάντα των επιλεγμένων υπολογιστικών φύλλων" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Αναγγελία _επικεφαλίδας κελιού" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Πλοήγηση πίνακα" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Αγνόηση των κε_νών κελιών" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Εκφώνηση _κελιού" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Εκφώνηση συντεταγμένων _κελιών" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Εκφώνηση αναπτυγμάτων _πολλαπλών κελιών" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Όνομα γνωρίσματος" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Περιήγηση δρομέα ελέγχου" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Ενεργοποίηση _δομικής περιήγησης" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Θέμα ήχου:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Θέμα ήχου" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Σύντομη περιγραφή" - -#: src/cthulhu/guilabels.py:953 -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Ειδοποίηση" -msgstr[1] "Ειδοποίηση" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Ctrl" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "αριστερό shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "αριστερό alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "αριστερό control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "δεξιό shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "δεξιό alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "δεξιό control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "αριστερό meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "δεξιό meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "αριστερός στηλοθέτης" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "επιστροφή" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "πάνω" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "κάτω" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "αριστερά" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "δεξιά" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "αριστερό super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "δεξί super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "μενού" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "βοήθεια" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "αλλαγή λειτουργίας" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "κύκλος" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "κάθετος" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "μείον" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Πλήκτρο εισαγωγής" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "_Δεξί Alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "_Αριστερό Alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "έντονα %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "πλάγια %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "έντονα πλάγια %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "γραφή %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "έντονη γραφή %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "διπλή αποτύπωση %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "έντονα fraktur %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "χωρίς πατούρα %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "χωρίς πατούρα έντονα %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "χωρίς πατούρα πλάγια %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "χωρίς πατούρα έντονα πλάγια %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "σταθερού πλάτους %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "χωρίς κουκκίδα %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "αριστερό βέλος" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "επάνω βέλος" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "δεξιό βέλος" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "κάτω βέλος" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "αριστερό-δεξιό βέλος" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "πάνω-κάτω βέλος" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "βορειοδυτικό βέλος" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "βορειοανατολικό βέλος" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "νοτιοανατολικό βέλος" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "αριστερό βέλος από κάθετο" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "πάνω βέλος από κάθετο" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "δεξιό βέλος από κάθετο" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "κάτω βέλος από κάθετο" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "αριστερό διπλό βέλος" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "πάνω διπλό βέλος" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "δεξιό διπλό βέλος" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "κάτω διπλό βέλος" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "διπλό αριστερό-δεξιό βέλος" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "πάνω-κάτω διπλό βέλος" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "βορειοδυτικό διπλό βέλος" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "βορειοανατολικό διπλό βέλος" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "νοτιοανατολικό διπλό βέλος" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "νοτιοδυτικό διπλό βέλος" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "βέλος δεξιάς φοράς" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "αιχμή βέλους δεξιάς φοράς" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "μείον" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "μικρότερο από" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "μεγαλύτερο από" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "σιρκουμφλέξ" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "χάτσεκ" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "σημείο βραχέος" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "πάνω τελεία" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "διπλή κατακόρυφη γραμμή" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "οριζόντια έλλειψη" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "για κάθε" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "συμπληρωματικό" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "μερικό διαφορικό" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "υπάρχει τουλάχιστον ένα" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "δεν υπάρχει" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "κενό σύνολο" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "μεταβολή (δέλτα)" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "ανάδελτα" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "ανήκει στο" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "δεν ανήκει στο" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "μικρό ανήκει" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "περιλαμβάνει ως μέλος" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "δεν περιλαμβάνει ως μέλος" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "μικρό περιλαμβάνει ως μέλος" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "ὅπερ ἔδει δεῖξαι" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "γινόμενο" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "συνγινόμενο" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "άθροισμα" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "πλην ή συν" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "συν με τελεία" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "πλαγιοκάθετος διαίρεσης" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "διαφορά συνόλων" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "τελεστής αστερίσκος" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "τελεστής δακτυλίου" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "τελεστής κουκκίδας" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "τετραγωνική ρίζα" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "κυβική ρίζα" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "τέταρτη ρίζα" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "ανάλογο προς" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "άπειρο" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "ορθή γωνία" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "γωνία" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "μετρήσιμη γωνία" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "σφαιρική γωνία" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "διαιρεί (διαιρέτης)" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "δεν διαιρεί (δεν είναι διαιρέτης)" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "παράλληλο προς" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "μη παράλληλο προς" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "λογικό και" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "λογικό ή" - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-## -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-## -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "τομή" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "ένωση" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "ολοκλήρωμα" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "διπλό ολοκλήρωμα" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "τριπλό ολοκλήρωμα" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "επικαμπύλιο ολοκλήρωμα" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "επιφανειακό ολοκλήρωμα" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "ολοκλήρωμα όγκου" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "ολοκλήρωμα θετικής φοράς" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "ολοκλήρωμα περιγράμματος θετικής φοράς" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "ολοκλήρωμα περιγράμματος αρνητικής φοράς" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "συνεπώς" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "επειδή" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "λόγος" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "αναλογία" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "μείον με τελεία" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "περίσσεια" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "γεωμετρική αναλογία" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "ομοιόθετο" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "περισπωμένη" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "αντεστραμμένη περισπωμένη" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "κεκλιμένο αντίστροφο S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "ημιτονοειδές κύμα" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "γινόμενο στεφάνης (wreath)" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "χωρίς περισπωμένη" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "περισπωμένη με πλην από πάνω" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "ασυμπτωτικά ίσο με" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "όχι ασυμπτωτικά ίσο με" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "περίπου ίσο με" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "περίπου αλλά όχι ακριβώς ίσο με" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ούτε περίπου ούτε ακριβώς ίσο με" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "σχεδόν ίσο με" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "όχι σχεδόν ίσο με" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "σχεδόν ίσο ή ίσο με" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "τριπλή περισπωμένη" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "όλα ίσα με" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "γεωμετρικά ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "διαφορά μεταξύ" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "τείνει προς το όριο" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "γεωμετρικά ίσο με" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "περίπου ίσο με ή όμοιο του" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "όμοιο του ή περίπου ίσον με" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "άνω-κάτω τελεία ίσον" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "ίσον άνω-κάτω τελεία" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "δακτύλιος μέσα σε ίσον" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ίσον με δακτύλιο από πάνω" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "αντιστοιχεί με" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "υπολογίζεται" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "ισογώνιος με" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "ίσον με υπερκείμενο αστεράκι" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "ίσον με υπερκείμενο δέλτα" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "εξ ορισμού ίσο με" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "μετρημένο από" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "ζητούμενο ίσο με" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "όχι ίσο με" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "ταυτόσημο με" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "όχι ταυτόσημο με" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "γνήσια ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "μικρότερο από ή ίσο με" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "μεγαλύτερο από ή ίσο με" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "μικρότερο από ή ίσο με" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "μεγαλύτερο από ή ίσο με" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "μικρότερο από αλλά όχι ίσο με" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "μεγαλύτερο από αλλά όχι ίσο με" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "πολύ μικρότερο από" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "πολύ μεγαλύτερο από" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "μεταξύ" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "όχι ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "όχι μικρότερο από" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "όχι μεγαλύτερο από" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ούτε μικρότερο από ούτε ίσο με" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ούτε μεγαλύτερο από ούτε ίσο με" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "μικρότερο από ή ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "μεγαλύτερο από ή ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ούτε μικρότερο από ούτε ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ούτε μεγαλύτερο από ούτε ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "μικρότερο από ή μεγαλύτερο από" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "μεγαλύτερο από ή μικρότερο από" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ούτε μικρότερο από ούτε μεγαλύτερο από" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ούτε μεγαλύτερο από ούτε μικρότερο από" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "προηγείται" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "έπεται" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "προηγείται ή είναι ίσο με" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "έπεται ή είναι ίσο με" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "προηγείται ή είναι ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "έπεται ή είναι ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "δεν προηγείται" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "δεν έπεται" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "υποσύνολο του" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "υπερσύνολο του" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "όχι υποσύνολο του" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "όχι υπερσύνολο του" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "υποσύνολο του ή ίσο με" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "υπερσύνολο του ή ίσο με" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ούτε υποσύνολο ούτε ίσο με" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ούτε υπερσύνολο ούτε ίσο με" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "υποσύνολο και διάφορο του" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "υπερσύνολο και διάφορο του" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "πολυσύνολο" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "πολλαπλασιασμός πολυσυνόλου" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "ένωση πολυσυνόλου" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "τετραγωνική εικόνα του" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "πρωτότυπο τετραγώνου" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "τετραγωνική εικόνα του ή ίσον με" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "πρωτότυπο τετραγώνου ή ίσον με" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "τετράγωνο καπέλο" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "τετράγωνη κούπα" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "κυκλωμένο συν" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "κυκλωμένο πλην" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "κυκλωμένο επί" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "κυκλωμένη πλαγιοκάθετος διαίρεσης" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "κυκλωμένος τελεστής κουκκίδας" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "κυκλωμένος τελεστής δακτυλίου" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "κυκλωμένος τελεστής αστερίσκου" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "κυκλωμένο ίσον" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "κυκλωμένη παύλα" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "συν σε τετράγωνο" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "πλην σε τετράγωνο" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "επί σε τετράγωνο" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "τελεστής κουκκίδας σε τετράγωνο" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "δεξιό καρφί" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "αριστερό καρφί" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "καρφί προς τα κάτω" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "καρφί προς τα πάνω" - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-# -# -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-# -# -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "ισχυρισμός" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "προτυποποιεί" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "αληθές" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "υποχρεώνει" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "τριπλή κατακόρυφη γραμμή που τέμνεται από οριζόντια γραμμή από δεξιά" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" -"διπλές κατακόρυφες γραμμές που τέμνονται με διπλές οριζόντιες γραμμές από " -"δεξιά" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "δεν αποδεικνύει" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "όχι αληθές" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "δεν υποχρεώνει" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" -"απαγορευτικό με διπλές κατακόρυφες γραμμές που τέμνονται με διπλές " -"οριζόντιες γραμμές από δεξιά" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "προηγείται στη σχέση" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "έπεται στη σχέση" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "κανονική υποομάδα του" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "περιέχει ως κανονική υποομάδα" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "κανονική υποομάδα του ή ίσο με" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "περιέχει ως κανονική υποομάδα ή ίσο με" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "πρωτότυπο του" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "εικόνα του" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "πολλαπλή απεικόνιση" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "ερμιτιανός συζυγής πίνακας" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "παρεμβάλλω" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "αποκλειστική διάζευξη" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "όχι και" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "τελεστής όχι ή" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ορθή γωνία με τόξο" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "ορθογώνιο τρίγωνο" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "τελεστής ρόμβου" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "τελεστής κουκκίδας" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "τελεστής αστεριού" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "επί διαίρεσης" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "παπιγιόν" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "αριστερός κανονικός παράγοντας ημιευθέος γινομένου" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "δεξιός κανονικός παράγοντας ημιευθέος γινομένου" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "αριστερό ημιευθύ γινόμενο" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "δεξιό ημιευθύ γινόμενο" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "αντεστραμμένη περισπωμένη ίσον" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "κατσαρό λογικό ή" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "κατσαρό λογικό και" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "διπλό υποσύνολο" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "διπλό υπερσύνολο" - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-## -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-## -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "διπλή τομή" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "διπλή ένωση" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "δίκρανο" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "ίσο και παράλληλο με" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "μικρότερο από με κουκκίδα" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "μεγαλύτερο από με κουκκίδα" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "πάρα πολύ μικρότερο από" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "πάρα πολύ μεγαλύτερο από" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "μικρότερο από ίσο με ή μεγαλύτερο από" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "μεγαλύτερο από ίσο με ή μικρότερο από" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "ίσο με ή μικρότερο από" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "ίσο με ή μεγαλύτερο από" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "ίσο με ή προηγείται του" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "ίσο με ή έπεται του" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "δεν προηγείται ή είναι ίσο με" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "δεν έπεται ή είναι ίσο με" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "όχι τετραγωνική εικόνα ή ίσον με" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "όχι πρωτότυπο τετραγώνου ή ίσο με" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "τετραγωνική εικόνα του ή διάφορο του" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "πρωτότυπο τετραγώνου ή διάφορο του" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "μικρότερο από αλλά όχι ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "μεγαλύτερο από αλλά όχι ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "προηγείται αλλά όχι ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "έπεται αλλά όχι ισοδύναμο με" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "όχι κανονική υποομάδα του" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "δεν περιέχει ως κανονική υποομάδα" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "όχι κανονική υποομάδα του ή ίσο με" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "δεν περιέχει ως κανονική υποομάδα ή ίσον με" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "κατακόρυφη έλλειψη" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "μεσαία γραμμή οριζόντιας έλλειψης" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "προς τα επάνω δεξιά διαγώνια έλλειψη" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "προς τα κάτω δεξιά διαγώνια έλλειψη" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "σύμβολο ανήκει με μακριά οριζόντια μολυβιά" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "σύμβολο ανήκει με κατακόρυφη γραμμή στο άκρο της οριζόντιας μολυβιάς" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"μικρό σύμβολο ανήκει με κατακόρυφη γραμμή στο άκρο της οριζόντιας μολυβιάς" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "σύμβολο ανήκει με τελεία από πάνω" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "σύμβολο ανήκει με γραμμή από πάνω" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "πεζό σύμβολο ανήκει με γραμμή από πάνω" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "σύμβολο ανήκει με γραμμή από κάτω" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "σύμβολο ανήκει με δύο οριζόντιες μολυβιές" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "περιλαμβάνει με μακριά οριζόντια μολυβιά" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "περιλαμβάνει με κατακόρυφη γραμμή στην άκρη της οριζόντιας μολυβιάς" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"μικρό περιλαμβάνει με κατακόρυφη γραμμή στην άκρη της οριζόντιας μολυβιάς" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "περιλαμβάνει με γραμμή από πάνω" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "μικρό περιλαμβάνει με γραμμή από πάνω" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "σημειογραφία z μέλους πολυσυνόλου" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "αριστερή οροφή" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "δεξιά οροφή" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "αριστερό δάπεδο" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "δεξιό δάπεδο" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "πάνω άγκιστρο" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "κάτω άγκιστρο" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "αριστερή γωνιακή αγκύλη" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "δεξιά γωνιακή αγκύλη" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "κουκκίδα σε κύκλο" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "ένωση νι-συνόλου με κουκκίδα" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "ένωση νι-συνόλου με συν" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "τελεστής τομής τετραγώνου νι-συνόλου" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "τελεστής ένωσης τετραγώνου νι-συνόλου" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "μαύρο τετράγωνο" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "λευκό τετράγωνο" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "μαύρος ρόμβος" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "λευκός κύκλος" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "μαύρος κύκλος" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "λευκή τελεία" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "μικρό τετράγωνο με μαύρο εσωτερικό" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s με συνδυάσιμο στοιχείο μακρού από κάτω" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s με συνδυάσιμη υπέρθετη μακριά κάθετο" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s με συνδυάσιμη κατακόρυφη γραμμή" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "εφαρμογή" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "κενό" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "έντονα" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "ο σελιδοδείκτης έχει εισαχθεί" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "οι σελιδοδείκτες αποθηκεύτηκαν" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "δεν ήταν δυνατόν να αποθηκευτούν οι σελιδοδείκτες" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Δεν βρέθηκαν ορόσημα." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Δεν βρέθηκαν ορόσημα." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Η λειτουργία παράκαμψης ενεργοποιήθηκε." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Αδύνατη η εμφάνιση της οθόνης της αριθμομηχανής" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "εικονίδιο" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Το στυλ κεφαλαίων ορίστηκε σε εικονίδιο." - -# #-#-#-#-# nautilus.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "καμία" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Το στυλ κεφαλαίων ορίστηκε σε κανένα." - -# -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "ένα-ένα γράμμα" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Το στυλ κεφαλαίων ορίστηκε σε ένα-ένα γράμμα." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Η εφαρμογή ελέγχει τον δρομέα." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Το Cthulhu ελέγχει το δρομέα." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Κελί %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s επιλεγμένο" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s εώς %s επιλεγμένα" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s εώς %s μη επιλεγμένα" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s μη επιλεγμένο" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Να εμποδιστεί η χρήση της επιλογής" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Εξαναγκασμένη χρήση της επιλογής" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "ΕΠΙΛΟΓΗ" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Προαιρετικά ορίσματα" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Χρήση: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Τα ακόλουθα δεν είναι έγκυρα: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Εκτύπωση των γνωστών εκτελούμενων εφαρμογών" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Φόρτωση προφίλ" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Αδυναμία φόρτωσης του προφίλ: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Δεν είναι δυνατή η εκκίνηση του Cthulhu επειδή δεν μπορεί να συνδεθεί στην " -"επιφάνεια εργασίας.Αδύνατη η έναρξη του αναγνώστη οθόνης, λόγω αδυναμίας " -"σύνδεσης με την επιφάνεια εργασίας." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Αδύνατη η ενεργοποίηση του διαχειριστή ρυθμίσεων. Έξοδος." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Μια άλλη διεργασία αναγνώστη οθόνης εκτελείται ήδη σε αυτήν τη συνεδρία.\n" -"Εκτελέστε \"cthulhu --replace\" για να αντικαταστήσετε αυτήν τη διεργασία με " -"μια νέα." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "ΟΝΟΜΑ" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Χρήση εναλλακτικού καταλόγου για τις προτιμήσεις του χρήστη" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Εκτύπωση των γνωστών εκτελούμενων εφαρμογών" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" -"Αντικατάσταση μιας τρέχουσας εκτελούμενης παρουσίας του CthulhuΑντικατάσταση " -"ενός τρέχοντος εκτελούμενου στιγμιότυπου αυτού του αναγνώστη οθόνης" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Εμφάνιση αυτού του βοηθητικού μηνύματος και έξοδος" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" -"Αποστολή της εξόδου της αποσφαλμάτωσης στο debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Αποστολή της εξόδου της αποσφαλμάτωσης στο συγκεκριμένο αρχείο" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ΑΡΧΕΙΟ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Ρύθμιση των προτιμήσεων χρήστη (έκδοση με κείμενο)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Ρύθμιση των προτιμήσεων χρήστη (έκδοση GUI)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Αναφέρετε σφάλματα στο https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Αποκοπή επιλογής στο πρόχειρο." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "αποκοπή" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Αντιγράφτηκε η επιλογή στο πρόχειρο." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "αντιγράφηκε" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Επικολλημένα περιεχόμενα από το πρόχειρο." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "επικολλήθηκε" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Να μην ανακοινώνεται όταν πληκτρολογούν οι φίλοι." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "το ανακοινώνει όταν πληκτρολογούν οι φίλοι." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Μήνυμα από το δωμάτιο συνομιλίας %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Νέα καρτέλα %s για συνομιλία" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Να μη γίνεται εκφώνηση του ονόματος του δωματίου συνομιλίας." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "εκφώνηση ονόματος του δωματίου συνομιλίας." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Να μην παρέχονται ξεχωριστά ιστορικά για κάθε δωμάτιο συνομιλίας." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Να παρέχονται ξεχωριστά ιστορικά για κάθε δωμάτιο συνομιλίας." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "αρχή διαγραφής" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "τέλος διαγραφής" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "αρχή εισαγωγής" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "τέλος εισαγωγής" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "επισήμανση εκκίνησης" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "τέλος επισήμανσης" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "_Υποδείξεις ορθογραφίας" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Τέλος πλαισίου." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Όχι σε περιέκτη." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "όλα τα αντικείμενα επιλεγμένα" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Το προκαθορισμένο κουμπί είναι το %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Το προεπιλεγμένο κουμπί είναι %s. Γκριζαρισμένο" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Το προκαθορισμένο κουμπί είναι το %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " δείκτης %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " εκθέτης %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Όχι σε πίνακα." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "έχει επιλεγεί ολόκληρο το έγγραφο" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "ολόκληρο το έγγραφο μη επιλεγμένο" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "επιλέχτηκε το αρχείο από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "αποεπιλέχτηκε το αρχείο από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "επιλέχτηκε το αρχείο στην τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "αποεπιλέχτηκε το αρχείο στην τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Ρύθμιση της δυναμικής επικεφαλίδας στήλης για τη γραμμή %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Έχει απαλειφθεί η δυναμική επικεφαλίδα στήλης." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Ρύθμιση δυναμικής επικεφαλίδας γραμμής για τη στήλη %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Έχει απαλειφθεί η δυναμική κεφαλίδα γραμμής." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "κενό" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Δεν βρέθηκαν αρχεία." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Τα προσαρτημένα περιεχόμενα στο πρόχειρο." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Τα αντιγραμμένα περιεχόμενα στο πρόχειρο." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Να μη χρησιμοποιηθεί η επίπεδη προεπισκόπηση." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Είσοδος στην επίπεδη προεπισκόπηση." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Έξοδος από την επίπεδη προεπισκόπηση." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" -"Μετακινεί την επίπεδη προεπισκόπηση στη λέξη πάνω από την τρέχουσα λέξη." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Επίπεδη ανασκόπηση χωρίς περιορισμούς" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "έχει μαθηματικό τύπο" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "ανοίγει τον διάλογο εύρεσης" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "ανοίγει τον πίνακα" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "ανοίγει τη λίστα σελίδων" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "ανοίγει το μενού" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "ανοίγει το δέντρο" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "σύνδεσμος χάρτη εικόνας" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Το πλήκτρο που εισήχθηκε έχει ήδη δεσμευτεί στο %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Πλήκτρο που καταγράφηκε: %s. Πιέστε enter για να εφαρμοστεί." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Το νέο πλήκτρο είναι: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Διαγράφηκε ο συνδυασμός πλήκτρων. Πιέστε enter για να εφαρμοστεί." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Έχει διαγραφεί ο συνδυασμός πλήκτρων." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "εισάγετε νέο πλήκτρο" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "πλήκτρο" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Η ηχώ πλήκτρου ορίστηκε σε πλήκτρο." - -# #-#-#-#-# nautilus.HEAD.el.po (el) #-#-#-#-# -# -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Καμία" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Η ηχώ πλήκτρου ορίστηκε σε καμία." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "πλήκτρο και λέξη" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Η ηχώ πλήκτρου ορίστηκε σε πλήκτρο και λέξη." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "πρόταση" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Η ηχώ πλήκτρου ορίστηκε σε πρόταση." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "λέξη" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Η ηχώ πλήκτρου ορίστηκε σε λέξη." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "λέξη και πρόταση" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Η ηχώ πλήκτρου ορίστηκε σε λέξη και πρόταση." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Περικλείεται από: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "ένα αναλογιστικό σύμβολο" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "ένα πλαίσιο" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "ένας κύκλος" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "ένα μεγάλο σύμβολο διαίρεσης" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "ένα ριζικό" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "ένα στρογγυλεμένο πλαίσιο" - -# #-#-#-#-# gnome-terminal.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "μια οριζόντια γραμμή" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "μια κατακόρυφη γραμμή" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "μια κάτω διαγώνια γραμμή" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "μια πάνω διαγώνια γραμμή" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "ένα βορειοανατολικό βέλος" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "μια γραμμή στο τέλος" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "μια γραμμή στα αριστερά" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "μια γραμμή στα δεξιά" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "μια γραμμή επάνω" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "γωνία μιγαδικού διανύσματος" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "ένα αραβικό παραγοντικό σύμβολο" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "και" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "αρχή κλάσματος" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "κλάσμα χωρίς γραμμή, αρχή" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "πάνω από" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "τέλος κλάσματος" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "τετραγωνική ρίζα του" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "κυβική ρίζα του" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "ρίζα του" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "αρχή ρίζας" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "τέλος ρίζας" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "δείκτης" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "εκθέτης" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "αριστερός δείκτης" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "αριστερός εκθέτης" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "κάτω γραφή" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "πάνω γραφή" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "τέλος πίνακα" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "τέλος ένθετου πίνακα" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "μη προσπελάσιμο" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Απενεργοποιημένη" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Εκφώνηση εσοχών και στοίχισης απενεργοποιήθηκε." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Ενεργοποιημένη" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Εκφώνηση εσοχών και στοίχισης ενεργοποιήθηκε." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Κατάσταση εκμάθησης. Πιέστε escape για να εξέλθετε." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Εισαγωγή της κατάστασης μάθησης. Πιέστε οποιοδήποτε πλήκτρο για να ακούσετε " -"τη λειτουργία του. Για να δείτε την τεκμηρίωση του αναγνώστη οθόνης, πατήστε " -"F1. Για τη λήψη μιας λίστας των προεπιλεγμένων συντομεύσεων του αναγνώστη " -"οθόνης, πατήστε F2. Για να πάρετε μια λίστα των συντομεύσεων του αναγνώστη " -"οθόνης για την τρέχουσα εφαρμογή, πατήστε F3. Για να τερματίσετε την " -"κατάσταση εκμάθησης, πιέστε το πλήκτρο διαφυγής." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "έξοδος από την παράθεση." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "έξοδος από τον πίνακα." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "έξοδος από τη ροή." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "έξοδος από το σχήμα." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "έξοδος από τη φόρμα." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "έξοδος από την ειδοποίηση." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "έξοδος από το συμπληρωματικό περιεχόμενο." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "έξοδος από τις πληροφορίες." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "έξοδος από το κύριο περιεχόμενο." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "έξοδος από την πλοήγηση." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "έξοδος από την περιοχή." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "έξοδος από την αναζήτηση." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "έξοδος από τη λίστα." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "έξοδος από τον πίνακα." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "έξοδος από τον πίνακα." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "έξοδος από τη λίστα." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "έξοδος από την περίληψη." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "έξοδος από τις αναγνωρίσεις." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "έξοδος από τον επίλογο." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "έξοδος από το παράρτημα." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "έξοδος από τη βιβλιογραφία." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "έξοδος από το κεφάλαιο." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "έξοδος από το κολοφώνα." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "έξοδος από την περίληψη." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "έξοδος από τον τίτλο αναγνώρισης." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "έξοδος από τους τίτλους αναγνώρισης." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "έξοδος από την αφιέρωση." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "έξοδος από τις σημειώσεις τέλους." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "έξοδος από την επιγραφή." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "έξοδος από τον επίλογο." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "έξοδος από το παρόραμα." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "έξοδος από το παράδειγμα." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "έξοδος από τον πρόλογο." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "έξοδος από το γλωσσάρι." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "έξοδος από τον πίνακα περιεχομένων." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "έξοδος από την εισαγωγή." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "έξοδος από τη λίστα σελίδων." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "έξοδος από το τμήμα." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "έξοδος από την εισαγωγή." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "έξοδος από τον πρόλογο." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "έξοδος από την παράθεση." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "έξοδος από τις ερωταπαντήσεις." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "έξοδος από την περιοχή." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "έξοδος από τον πίνακα περιεχομένων." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "επιλέχτηκε η γραμμή κάτω από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "επιλέχτηκε η γραμμή πάνω από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "αποεπιλέχτηκε η γραμμή κάτω από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "αποεπιλέχτηκε η γραμμή πάνω από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Έξοδος από την κατάσταση εκμάθησης." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" -"επιλέχτηκε η γραμμή από την αρχή μέχρι την προηγούμενη τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" -"επιλέχτηκε η γραμμή από την προηγούμενη τοποθεσία του δρομέα μέχρι το τέλος" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "σύνδεσμος" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ίδια σελίδα" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ίδια ιστοσελίδα" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "διαφορετική ιστοσελίδα" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "Σύνδεσμος %(uri)s προς το %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "σύνδεσμος %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "αναγνωσμένος %s σύνδεσμος" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Χρησιμοποιήστε τα βέλη πάνω και κάτω για να περιηγηθείτε στη λίστα. Πατήστε " -"το Escape για έξοδο." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Ρύθμιση όλων των ζωντανών περιοχών ως απενεργοποιημένων" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "έγινε επαναφορά των επιπέδων ευγένειας των ζωντανών περιοχών" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "επίπεδο ευγένειας %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "ρύθμιση ζωντανής περιοχής ως αποφασιστικής" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "ρύθμιση ζωντανής περιοχής ως απενεργοποιημένης" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "ρύθμιση ζωντανής περιοχής ως ευγενικής" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "ρύθμιση ζωντανής περιοχής ως αγενούς" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Η παρακολούθηση οθόνης ζωντανών περιοχών είναι απενεργοποιημένη" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Η παρακολούθηση οθόνης ζωντανών περιοχών είναι ενεργοποιημένη" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "δεν αποθηκεύτηκε κανένα μήνυμα" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Η υποστήριξη ζωντανής περιοχής είναι απενεργοποιημένη" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Δεν βρέθηκε" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Δε βρέθηκε η τρέχουσα τοποθεσία." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "απενεργοποιημένο" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "ενεργοποιημένο" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "ανορθόγραφο" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Ανορθόγραφη λέξη: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Το συμφραζόμενο είναι το %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Λειτουργία περιήγησης" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Λειτουργίας εστίασης" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Για ενεργοποίηση της κατάστασης εστίασης πατήστε %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Η λειτουργίας εστίασης είναι κολλώδης." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Η λειτουργίας περιήγησης είναι κολλώδης." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Λειτουργίας διάταξης." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Λειτουργία αντικειμένου." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Δεν υπάρχουν άλλα μεγάλα αντικείμενα." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Δε βρέθηκε το αναδυόμενο αντικείμενο." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Ενεργοποιήθηκε η προεπισκόπηση ποντικιού." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Απενεργοποιήθηκε η προεπισκόπηση ποντικιού." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Σφάλμα: αδύνατη η δημιουργία λίστας αντικειμένων." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Δεν υπάρχουν παιδιά." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Δεν υπάρχει επόμενο." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d τοις εκατό." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Μετάβαση στην προηγούμενη λέξη" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Η απλοποιημένη πλοήγηση ενεργοποιήθηκε." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Η απλοποιημένη πλοήγηση απενεργοποιήθηκε." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Ένθεση %d επιπέδου" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Προστέθηκε νέο αντικείμενο" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Δεν βρέθηκαν ενέργειες στο: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Δεν υπάρχει εστίαση" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Καμία εφαρμογή δεν έχει εστιαστεί." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Δεν υπάρχουν άλλα εισαγωγικά." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Δεν υπάρχουν άλλα κουμπιά." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Δεν υπάρχουν άλλα πλαίσια επιλογής." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Δεν υπάρχουν άλλα μεγάλα αντικείμενα." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Δεν υπάρχουν άλλα επιλέξιμα." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Δεν υπάρχουν άλλα πλαίσια πολλαπλών επιλογών." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Δεν υπάρχουν άλλες καταχωρίσεις." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Δεν υπάρχουν άλλα πεδία μορφοποίησης." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Δεν υπάρχουν άλλες επικεφαλίδες." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Δεν υπάρχουν άλλες επικεφαλίδες στο επίπεδο %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Δεν υπάρχουν άλλοι πίνακες." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Δεν υπάρχουν άλλες εικόνες." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Δεν βρέθηκαν ορόσημα." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Δεν υπάρχουν περισσότεροι σύνδεσμοι." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Δεν υπάρχουν περισσότερες λίστες." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Δεν υπάρχουν άλλα αντικείμενα λιστών." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Δεν υπάρχουν άλλες ενεργές περιοχές." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Δεν υπάρχουν άλλες παράγραφοι." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Δεν υπάρχουν άλλα επιλέξιμα κουμπιά." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Δεν υπάρχουν άλλα διαχωριστικά." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Δεν υπάρχουν άλλοι πίνακες." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Δεν υπάρχουν άλλοι σύνδεσμοι που δεν επισκεφτήκατε." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Δεν υπάρχουν άλλοι σύνδεσμοι που έχετε επισκεφτεί." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Δεν έχει επιλεχθεί κείμενο." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Δεν είναι σύνδεσμος." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Ειδοποίηση" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Τέλος" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Αρχή" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Δεν υπάρχουν μηνύματα ειδοποίησης" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "ψηφία" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Εκφώνηση αριθμών ως ψηφία." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "λέξεις" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Εκφώνηση αριθμών ως λέξεις." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "απενεργοποιημένο" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ενεργοποιημένο" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Γίνεται φόρτωση. Παρακαλώ περιμένετε." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Έγινε επιτυχής φόρτωση." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Έγινε επιτυχής φόρτωση του %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Η σελίδα περιέχει %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "επιλέχτηκε η σελίδα από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "επιλέχτηκε η σελίδα στην τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "αποεπιλέχτηκε η σελίδα από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "αποεπιλέχτηκε η σελίδα στην τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "επιλέχτηκε η παράγραφος κάτω από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "επιλέχτηκε η παράγραφος πάνω από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "αποεπιλέχτηκε η παράγραφος κάτω από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "αποεπιλέχτηκε η παράγραφος πάνω από την τοποθεσία του δρομέα" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Έχετε ήδη ανοικτή μια διεργασία των προτιμήσεων του cthulhu.\n" -"Παρακαλώ τερματίστε την πριν ανοίξετε μία νέα διεργασία." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "διαφάνεια %(position)d από %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Το προφίλ ορίστηκε σε %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Δεν βρέθηκαν προφίλ." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Γραμμή προόδου %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Όλα" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Το επίπεδο εκφώνησης σημείων στίξης ορίστηκε σε όλα." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Τα περισσότερα" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Το επίπεδο εκφώνησης σημείων στίξης ορίσθηκε στα περισσότερα." - -# #-#-#-#-# nautilus.HEAD.el.po (el) #-#-#-#-# -# -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Κανένα" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Το επίπεδο εκφώνησης σημείων στίξης ορίσθηκε σε κανένα." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Μερικά" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Το επίπεδο εκφώνησης σημείων στίξης ορίσθηκε σε μερικά." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Αναζήτηση." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Η αναζήτηση ολοκληρώθηκε." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Οι ρυθμίσεις του Cthulhu επαναφορτώθηκαν." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Το επιλεγμένο κείμενο είναι: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Διαγράφηκε η επιλογή." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Επαναφέρθηκε η επιλογή." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "ανεπίλεκτο" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Μέγεθος: %d, %d. Τοποθεσία: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Πλάτος: %d. Ύψος: %d. %d από αριστερά. %d από πάνω." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Η εκφώνηση απενεργοποιήθηκε." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Η εκφώνηση ενεργοποιήθηκε." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "πιο γρήγορα." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "πιο αργά." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "ψηλότερα." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "χαμηλότερα." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "πιο δυνατά." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "πιο απαλά." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Ταχύτητα %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Τόνος %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Ένταση %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Μονάδα speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Φωνή speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Δεν υπάρχουν διαθέσιμα αρθρώματα Speech-dispatcher" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Δεν υπάρχουν διαθέσιμες φωνές Speech-dispatcher" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Οι ρυθμίσεις ομιλίας αποθηκεύτηκαν" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Δεν ήταν δυνατή η αποθήκευση των ρυθμίσεων ομιλίας" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Επίπεδο περιφραστικότητας: σύντομο" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Επίπεδο περιφραστικότητας: αναλυτικό" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " κουκκίδα κουκκίδα κουκκίδα" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Το Cthulhu σας καλωσορίζει." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Ο Κθούλου παραμονεύει κάτω από τα κύματα." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Η λειτουργία ύπνου ενεργοποιήθηκε για %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Κατάσταση αναστολής απενεργοποιήθηκε για %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Η εκφώνηση δεν είναι διαθέσιμη." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Δεν βρέθηκε" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Η μπάρα κατάστασης δεν βρέθηκε" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "η συμβολοσειρά δεν βρέθηκε" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Απενεργοποιημένα τα πλήκτρα δομικής πλοήγησης." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Ενεργοποιημένα τα πλήκτρα δομικής πλοήγησης." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Δεν βρέθηκε" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Γραμμή %(row)d, στήλη %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Τέλος πίνακα" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Εκφώνηση κελιού" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Εκφώνηση γραμμής" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Μη-ομοιόμορφος πίνακας" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Όχι σε πίνακα." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Αναδιάταξη στηλών" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Αναδιάταξη γραμμών" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "στήλη %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "στήλη %(index)d από %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Τέλος της στήλης." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Αρχή της στήλης." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Στήλη %s επιλεγμένη" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Στήλες %s εώς %s επιλεγμένες" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Στήλες %s εώς %s μη επιλεγμένες" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Στήλη %s μη επιλεγμένη" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "γραμμή %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "γραμμή %(index)d από %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Αρχή γραμμής." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Τέλος γραμμής." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Διαγράφτηκε γραμμή." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Διαγράφηκε η τελευταία γραμμή." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Γραμμή εισήχθη." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Γραμμή εισήχθη στο τέλος του πίνακα." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Σειρά %s επιλεγμένη" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Σειρές %s εώς %s επιλεγμένες" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Σειρές %s εώς %s μη επιλεγμένες" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Σειρά %s μη επιλεγμένη" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "επιλεγμένο" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "ανεπίλεκτο" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H ώρες, %M λεπτά και %S δευτερόλεπτα." - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H ώρες και %M λεπτά." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "αναίρεση" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "επανάληψη" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu έκδοση %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "κενός χαρακτήρας" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Αναδίπλωση προς τα κάτω." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Αναδίπλωση προς τα πάνω." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 αντικείμενα λίστας" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Το κελί αναπτύσσεται σε %d γραμμή" -msgstr[1] "Το κελί αναπτύσσεται σε %d γραμμές" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d στήλη" -msgstr[1] " %d στήλες" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Το κελί αναπτύσσεται σε %d στήλη" -msgstr[1] "Το κελί αναπτύσσεται σε %d στήλες" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d χαρακτήρας περισσότερος" -msgstr[1] "%d χαρακτήρες περισσότεροι" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d διάλογος)" -msgstr[1] "(%d διάλογοι)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d μη εστιασμένος διάλογος" -msgstr[1] "%d μη εστιασμένοι διάλογοι" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Βρέθηκαν το αρχείο %d" -msgstr[1] "Βρέθηκαν %d αρχεία" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d φόρμα" -msgstr[1] "%d φόρμες" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "επικεφαλίδα %d" -msgstr[1] "επικεφαλίδες %d" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "αντικείμενο %d" -msgstr[1] "αντικείμενα %d" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d ορόσημο" -msgstr[1] "%d ορόσημα" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "βρέθηκε %d στοιχείο" -msgstr[1] "βρέθηκαν %d στοιχεία" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Έξοδος από την %d παράθεση." -msgstr[1] "Έξοδος από τις %d παραθέσεις." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Έξοδος από την %d λίστα." -msgstr[1] "Έξοδος από τις %d λίστες." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Λίστα άγνωστου μεγέθους" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Λίστα με το αντικείμενο %d" -msgstr[1] "Λίστα με %d ντικείμενα" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Ροή άγνωστου μεγέθους" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Ροή με %d άρθρο" -msgstr[1] "Ροή με %d άρθρα" - -#: src/cthulhu/messages.py:2710 -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Λίστα με το αντικείμενο %d" -msgstr[1] "Λίστα με %d ντικείμενα" - -#: src/cthulhu/messages.py:2718 -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Τιμή" -msgstr[1] "Τιμή" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "μαθηματικός πίνακας με %d γραμμή" -msgstr[1] "μαθηματικός πίνακας με %d γραμμές" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d γραμμή" -msgstr[1] "%d γραμμές" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "ένθετος μαθηματικός πίνακας με %d γραμμή" -msgstr[1] "ένθετος μαθηματικός πίνακας με %d γραμμές" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d μήνυμα.\n" -msgstr[1] "%d μηνύματα.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d τοις εκατό." -msgstr[1] "%d τοις εκατό." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "Έχει αναγνωστεί το %d τοις εκατό του εγγράφου" -msgstr[1] "Έχει αναγνωστεί το %d τοις εκατό του εγγράφου" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d εικονοστοιχείο" -msgstr[1] "%d εικονοστοιχεία" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s χαρακτήρας" -msgstr[1] "%(count)d %(repeatChar)s χαρακτήρες" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d από %(total)d αντικείμενο έχει επιλεγεί" -msgstr[1] "%(index)d από %(total)d αντικείμενα έχουν επιλεγεί" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Βρέθηκε %d προεπιλεγμένη συντόμευση του αναγνώστη οθόνης." -msgstr[1] "Βρέθηκαν %d προεπιλεγμένες συντομεύσεις του αναγνώστη οθόνης." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Βρέθηκε %(count)d συντόμευση του αναγνώστη οθόνης για %(application)s." -msgstr[1] "" -"Βρέθηκαν %(count)d συντομεύσεις του αναγνώστη οθόνης για %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "διάστημα %d" -msgstr[1] "διαστήματα %d" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "στηλοθέτης %d" -msgstr[1] "στηλοθέτες %d" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "πίνακας %d" -msgstr[1] "πίνακες %d" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "πίνακας περιεχομένων" - -#: src/cthulhu/messages.py:2834 -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "πίνακας με %d γραμμή" -msgstr[1] "πίνακας με %d γραμμές" - -#: src/cthulhu/messages.py:2842 -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "πίνακας με %d γραμμή" -msgstr[1] "πίνακας με %d γραμμές" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "πίνακας με %d γραμμή" -msgstr[1] "πίνακας με %d γραμμές" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "πριν από %d δευτερόλεπτο" -msgstr[1] "πριν από %d δευτερόλεπτα" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "πριν από %d λεπτό" -msgstr[1] "πριν από %d λεπτά" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "πριν από %d ώρα" -msgstr[1] "πριν από %d ώρες" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "πριν από %d ημέρα" -msgstr[1] "πριν από %d ημέρες" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d μη αναγνωσμένος δεσμός" -msgstr[1] "%d μη αναγνωσμένοι δεσμοί" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d αναγνωσμένος δεσμός" -msgstr[1] "%d αναγνωσμένοι δεσμοί" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "εναλλαγή" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "στο %(index)d από %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d από %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "στοιχείο %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "Επίπεδο %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "επίπεδο δένδρου %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "ΕΠΙΠΕΔΟ ΔΕΝΔΡΟΥ %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "λεπτομέρειες για %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "έχει λεπτομέρειες στο %s" - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-# -# -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-# -# -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "λατινικό ερωτηματικό" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "επεξεργαζόμενο πλαίσιο πολλαπλών επιλογών" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "επεξεργάσιμο περιεχόμενο" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "ροή" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "σχήμα" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "περίληψη" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "ευχαριστίες" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "επίλογος" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "παράρτημα" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "καταχώρηση βιβλιογραφίας" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "βιβλιογραφία" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "κεφάλαιο" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "κολοφώνας" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "συμπέρασμα" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "κάλυμμα" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "αναγνώριση" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "αναγνωρίσεις" - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-## -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-## -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "αφιέρωση" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "υποσημείωση" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "υποσημειώσεις" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "επιγραφή" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "επίλογος" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "παρόραμα" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "παράδειγμα" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "πρόλογος" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "γλωσσάριο" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "πίνακας περιεχομένων" - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-## -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-## -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "εισαγωγή" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "αλλαγή σελίδας" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "λίστα σελίδων" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "μέρος" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "εισαγωγή" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "πρόλογος" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "παράθεση" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Ερωταπαντήσεις" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "υπότιτλος" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "πίνακας περιεχομένων" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s επίπεδο %(level)d" - -# #-#-#-#-# gnome-terminal.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "οριζόντια μπάρα κύλισης" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "κατακόρυφη μπάρα κύλισης" - -# #-#-#-#-# gnome-terminal.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "οριζόντιος ολισθητής" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "κατακόρυφος ολισθητής" - -# #-#-#-#-# gnome-terminal.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "οριζόντιος διαχωριστής" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "κατακόρυφος διαχωριστής" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "αλλαγή" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Πίνακας εικονιδίων" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "ειδοποίηση" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "συμπληρωματικό περιεχόμενο" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "πληροφορίες" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "κύριο περιεχόμενο" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "πλοήγηση" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "περιοχή" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "αναζήτηση" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "σύνδεσμο που έχει επισκεφθεί" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "πλήκτρο μενού" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "ταξινομημένο κατά αύξουσα σειρά" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "ταξινομημένο κατά φθίνουσα σειρά" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "ταξινομημένο" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "επιλέξιμο" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "συμπτυγμένο" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "αναπτυγμένο" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "έχει μεγάλη περιγραφή" - -# #-#-#-#-# gnome-terminal.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "οριζόντια" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "κατακόρυφα" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "επιλεγμένο" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "ανεπίλεκτο" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "ενεργοποιημένο" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "απενεργοποιημένο" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "μερικώς επιλεγμένο" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "πατημένο" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "απάτητο" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "δεν είναι επιλεγμένο" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "επιλεγμένο" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "δεν είναι επιλεγμένο" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "αποεπιλεγμένο" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "αναγνωσμένος" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "ανεπίσκεπτος" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "σε γκρι" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "μόνο ανάγνωση" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "αναγν" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "υποχρεωτικό" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "πολλαπλή επιλογή" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "λανθασμένη καταχώρηση" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "σφάλμα" - -# -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "λανθασμένη ορθογραφία" - -# -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ορθογραφία" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "γραμματικό σφάλμα" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "γραμματική" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Έυρεση" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Διάλογος εύρεσης αναγνώστη οθόνης" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Κλείσιμο" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "Εύ_ρεση" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Αναζήτηση για:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Αναζήτηση για:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Κορυφή του παραθύρου" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Κορυφή του παραθύρου" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Εκκίνηση από:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Αναδίπλωση γύρω" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Αναζήτηση προς τα _πίσω" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Κατεύθυνση αναζήτησης:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Ταίριασμα χαρακτήρα" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Ταίριασμα μόνο ο_λόκληρης της γραμμής" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Επιλογές:" - -# #-#-#-#-# gnome-system-tools.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Προεπιλεγμένο" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Κεφαλαία" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Σύνδεσμος" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Σύστημα" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Εφαρμογή" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Παράθυρο" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Προτιμήσεις Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Βοήθεια" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Εφαρμογή" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Φορητός" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Διάταξη πληκτρολογίου" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Ενεργό _προφίλ:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Προφίλ εκκίνησης:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Φόρτωση" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Αποθήκευση _ως" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Αφαίρεση" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Προφίλ" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Πα_ρόντα βοηθήματα εργαλείων" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Εκφώνηση του αντικειμένου κάτω από το _ποντίκι" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Ποντίκι" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Μορφή ώ_ρας:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Μορφή η_μερομηνίας:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Ώρα και ημερομηνία" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Εκ_φώνηση ενημερώσεων" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Ενημερώσεις _Μπράιγ" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Συχνότητα (sec):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Εφαρμογή σε:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Ηχητικό σήμα στις ενημερώσεις" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Ενημερώσεις γραμμής προόδου" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Ενεργοποίηση πισω_γυρίσματος και γρήγορης προώθησης στο Εκφώνηση όλων" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Ενεργοποίηση _δομικής περιήγησης στην Εκφώνηση όλων" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Να γίνει εκφώνηση α_νά:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Ανακοίνωση παρα_θέσεων στη λειτουργία Ανάγνωση Όλων" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Ανακοίνωση λι_στών στη λειτουργία Ανάγνωση Όλων" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Ανακοίνωση _πινάκων στη λειτουργία Ανάγνωση Όλων" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Ανακοίνωση π_λαισίων στη λειτουργία Ανάγνωση Όλων" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Ανακοίνωση _φορμών στη λειτουργία Ανάγνωση Όλων" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" -"Ανακοίνωση σημαντικών _αντικειμένων σελίδας στη λειτουργία Ανάγνωση Όλων" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Εκφώνηση όλων" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Παρουσίαση στοιχείου:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Γενικά" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Τόμος:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Βήμα:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Ρυθμός:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "Ά_τομο:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Γλώσσα:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Συν_θέτης εκφώνησης:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Σύστημα εκφώνησης:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Τύπος _ομιλίας:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Στυλ κε_φαλαίων:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Ρυθμίσεις τύπου ομιλίας" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" -"Να εκφωνούνται ως _λέξεις οι συμβολοσειρές που περιέχουν πεζά και κεφαλαία " -"μαζί" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Εκφώνηση αρι_θμών ως ψηφία" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Καθολικές ρυθμίσεις ομιλίας" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Ομιλία" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Ενεργοποίηση εκ_φώνησης" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Περιφραστικό" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Περιφραστικότητα" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "Ό_λα" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Επίπεδο σημείων στίξης" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Εκφώνηση μόνο του εμφανιζόμενου κειμένου" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Να εκφωνούνται οι κενές γραμμές" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "_Εσοχή εκφώνησης και στοίχιση" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Εκφώνηση των _μνημονικών τεχνασμάτων των αντικειμένων" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Εκφώνηση θέσης _θυγατρικού" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Εκφώνηση των μηνυμάτων των οδηγών εκμάθησης" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Τα μηνύματα _συστήματος είναι λεπτομερή" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Εκ_φώνηση χρωμάτων ως χρώματα" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Ανακοίνωση παρα_θέσεων κατά την πλοήγηση" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Ανακοίνωση _λιστών κατά την πλοήγηση" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Ανακοίνωση _πινάκων κατά την πλοήγηση" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Εκφώνηση ένδειξης της ανορ_θόγραφης λέξης" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Ανακοίνωση _πλαισίων κατά την πλοήγηση" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Ανακοίνωση σημαντικών _αντικειμένων σελίδας κατά την πλοήγηση" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Ανακοίνωση _φορμών κατά την πλοήγηση" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Εκφώνηση _περιγραφής" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Εκφώνηση ολόκληρης γραμμής σε λο_γιστικά φύλλα" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Εκφώνηση ολόκληρης γραμμής σε πίνακες _εγγράφων" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Εκφώνηση ολόκληρης γραμμής σε πίνακες _διεπαφών" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Προφορικά συμφραζόμενα" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Εκφώνηση" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Ενεργοποίηση _υποστήριξης Μπράιγ" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Συ_ντόμευση ονομάτων ρόλων" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Απενεργοποίηση του συμβόλου _τέλους γραμμής" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Πίνακας συστολής:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Ενεργοποίηση συμ_βατού Μπράιγ" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Ενεργοποίηση αναδίπλωσης λέ_ξεων" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Ρυθμίσεις οθόνης" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Καμία" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Ένδειξη επιλογών" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Ένδειξη συνδέσμων" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Ενεργοποίηση στιγμιαίων _μηνυμάτων" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Διάρκεια (δευτ):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Τα μηνύματα είναι μόν_ιμα" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Τα μηνύματα είναι λ_επτομερή" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Ρυθμίσεις στιγμιαίων μηνυμάτων" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Μπράιγ" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Ενεργοποίηση πλήκτρ_ου echo" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Ενεργοποίηση αλ_φαβητικών πλήκτρων" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Ενεργοποίηση _αριθμητικών πλήκτρων" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Ενεργοποίηση πλήκτρων _στίξης" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Ενεργοποίηση _κενών" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Ενεργοποίηση π_λήκτρων μεγεθυντή" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Ενεργοποίηση πλήκτρων _συναρτήσεων" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Ενεργοποίηση πλήκτρων ε_νέργειας" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Ενεργοποίηση πλήκτρων _πλοήγησης" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Ενεργοποίηση echo ανά λέ_ξη" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Ενεργοποίηση echo ανά π_ρόταση" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Πλήκτρο echo" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Πλήκτρα _τροποποιητή του αναγνώστη οθόνης:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Συνδυασμοί πλήκτρων" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Λεξικό προφοράς" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Νέα εισαγωγή" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Διαγραφή" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Προφορά" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Εκ_φώνηση όλων" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Χωρίς εκφώνηση" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Επαναφορά" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Ιδιότητες κειμένου" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Μετακίνηση στο _τέλος" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Μετακίνηση μια γραμμή _κάτω" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Μετακίνηση μια γραμμή _πάνω" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Μετακίνηση στην κο_ρυφή" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Προσαρμογή επιλεγμένων ιδιοτητών" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Ένδειξη Μπράιγ" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Χαρακτηριστικά κειμένου" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Ενεργοποίηση βοηθού AI" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Πάροχος:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Τοπικά - Δωρεάν)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Αρχείο _κλειδιού API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Διαδρομή προς το αρχείο κλειδιού API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Λήψη κλειδιού API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Άνοιγμα προγράμματος περιήγησης για λήψη κλειδιού API Claude και αυτόματη αποθήκευση" -"Άνοιξε τον περιηγητή για να λάβεις το κλειδί API Claude και να το " -"αποθηκεύσεις αυτόματα" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Απαιτείται επιβεβαίωση πριν από ενέργειες AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Μοντέλο Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Όνομα μοντέλου για Ollama (π.χ. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Τελικό σημείο Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL τελικού σημείου API Ollama (π.χ. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Ποιότητα στιγμιότυπου:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Χαμηλή" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Μεσαία" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Υψηλή" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Βοηθός AI" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Κωδικός _γλώσσας:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Συντελεστής _κλίμακας:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Εικόνα _κλίμακας του γκρι" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Αντιστροφή εικόνας" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Εικόνα _ασπρόμαυρη" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Κατώφλι ασπρόμαυρου:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Ανάλυση χρωμάτων" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Αντιγραφή αποτελεσμάτων στο _πρόχειρο" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"α : άλφα, β : βύρων, γ : γάτα, δ : δόξα, ε : ερμής, ζ : ζεύς, η : ηρώ, θ : " -"θεά, ι : ίσκιος, κ : κενό, λ : λάμα, μ : μέλι, ν : ναός, ξ : ξέρξης, ο : " -"οσμή, π : πέτρος, ρ : ρήγας, σ : σοφός, τ : τίγρης, υ : ύμνος, φ : φωφώ, χ : " -"χαρά, ψ : ψυχή, ω : ωμέγα" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "χρώμα φόντου" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "πλήρες ύψος φόντου" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "διάστικτο φόντο" - -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# gnome-libs-el.po (gnome-libs 1.2.12) #-#-#-#-# -# #-#-#-#-# libgda-el.po (gnome-db 0.0.91) #-#-#-#-## -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-## -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "κατεύθυνση" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "επεξεργάσιμο" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "όνομα οικογένειας γραμματοσειράς" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "χρώμα προσκηνίου" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "διάστικτο προσκήνιο" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "εφέ γραμματοσειράς" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "εσοχή" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "λάθος" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "αόρατο" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "στοίχιση" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "γλώσσα" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "αριστερό περιθώριο" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "διάστιχο" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "στυλ παραγράφου" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixel πάνω από γραμμές" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixel κάτω από γραμμές" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixel εντός παραγράφου" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "δεξί περιθώριο" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "ύψωση" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "κλιμάκωση" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "μέγεθος" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "τέντωμα" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "επιγράμμιση" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "στυλ" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "διακόσμηση κειμένου" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "περιστροφή κειμένου" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "σκίαση κειμένου" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "υπογράμμιση" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "παραλλαγή" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "κατακόρυφη ευθυγράμμιση" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "βάρος" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "αναδίπλωση" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "γραφή" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "αληθές" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "ψευδές" - -# #-#-#-#-# nautilus.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "κανένα" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "χαραγμένο" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "ανάγλυφο" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "περίγραμμα" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "επιγράμμιση" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "μεσογράμμιση" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "αναβοσβήσιμο" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "μαύρη" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "απλή" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "διπλή" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "χαμηλά" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "χαρακτήρας" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "λέξη" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "χαρακτήρας λέξης" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "α-δ" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "δ-α" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "αριστερά" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "δεξιά" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "κέντρο" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "χωρίς" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "πλήρης" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "υπερσυνεπτυγμένα" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "έξτρα συνεπτυγμένα" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "συνεπτυγμένα" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "ημισυνεπτυγμένα" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "κανονικά" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "ημιαναπτυγμένα" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "αναπτυγμένα" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "έξτρα αναπτυγμένα" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ύπεραναπτυγμένα" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "μικρά κεφαλαία" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "λοξά" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "πλάγια" - -# #-#-#-#-# gnome-system-tools.HEAD.el.po (el) #-#-#-#-# -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Προεπιλεγμένο" - -# #-#-#-#-# gtkhtml.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# libgnomeui.HEAD.el.po (el) #-#-#-#-# -# #-#-#-#-# balsa-el.po (balsa 0.9.3.1) #-#-#-#-## -# #-#-#-#-# bonobo-el.po (bonobo 0.34) #-#-#-#-## -# #-#-#-#-# gimp-script-fu-el.po (gimp-script-fu 1.0) #-#-#-#-## -# #-#-#-#-# gtkhtml-el.po (gtkhtml 0.8.1) #-#-#-#-## -# #-#-#-#-# gtop-el.po (gtop 1.0.9) #-#-#-#-## -# #-#-#-#-# guppi3-el.po (guppi3 1.0) #-#-#-#-## -# #-#-#-#-# nautilus-el.po (nautilus 0.8.3) #-#-#-#-## -# #-#-#-#-# sodipodi-el.po (sodipodi 0.25) #-#-#-#-## -# #-#-#-#-# toutdoux-el.po (toutdoux 1.0) #-#-#-#-## -# #-#-#-#-# achtung-el.po (achtung 0.99.0) #-#-#-#-## -# #-#-#-#-# gaim-el.po (gaim 0.48) #-#-#-#-## -# #-#-#-#-# screem-el.po (screem 1.0) #-#-#-#-## -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Σώμα κειμένου" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Επικεφαλίδα" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "βάση" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "δείκτης" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "εκθέτης" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "ανώτατο σημείο" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "ανώτατο σημείο κειμένου" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "μέσο" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "κατώτατο σημείο" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "κατώτατο σημείο κειμένου" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "κληρονομείται" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "συμπαγής" - -# -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "ορθογραφία" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Πατήστε διάστημα για εναλλαγή." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Πατήστε διάστημα για να εμφανίσετε τις επιλογές, και τα βέλη πάνω και κάτω " -"για να επιλέξετε." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Πατήστε alt+f6 για να εστιάσετε στα θυγατρικά παράθυρα." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Για να μετακινήσετε αντικείμενα, χρησιμοποιήστε τα βέλη, ή ξεκινήστε να " -"πληκτρολογείτε για να γίνει αναζήτηση." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Για να ανοίξετε τα μενού του συστήματος πατήστε alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Χρησιμοποιήστε τα βέλη πάνω και κάτω για να επιλέξετε." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Για σύμπτυξη, πατήστε shift και αριστερά." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Για ανάπτυξη, πατήστε shift και δεξιά." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Πατήστε Enter για να το ενεργοποιήσετε." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Πληκτρολογήστε κείμενο." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" -"Χρησιμοποιήστε το αριστερά και δεξιά για να προβάλετε τις άλλες καρτέλες." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Πατήστε διάστημα για να το ενεργοποιήσετε." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Χρησιμοποιήστε τα βέλη πάνω και κάτω για να επιλέξετε τιμή. Εναλλακτικά, " -"πληκτρολογήστε την επιθυμητή αριθμητική τιμή." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Για αλλαγή, χρησιμοποιήστε τα βέλη." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Χρησιμοποιήστε το δεξί ή το αριστερό βέλος για περιήγηση. Για μετακίνηση από " -"το ένα αντικείμενο στο επόμενο, χρησιμοποιήστε τα βέλη πάνω και κάτω." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Για να εισέλθετε στο υπομενού, πατήστε το δεξί βέλος." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Πιέστε το αριστερό βέλος για μείωση, πιέστε το δεξί βέλος για αύξηση. Για το " -"ελάχιστο πατήστε home και για το μέγιστο end." diff --git a/po/en_CA.po b/po/en_CA.po deleted file mode 100644 index 545130d..0000000 --- a/po/en_CA.po +++ /dev/null @@ -1,9578 +0,0 @@ -# English/Canada translation of cthulhu. -# Copyright (C) 2004-2006 Adam Weinberger and the GNOME Foundation -# This file is distributed under the same licence as the cthulhu package. -# Adam Weinberger , 2004, 2005, 2006. -# -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2005-08-31 14:20-0400\n" -"Last-Translator: Adam Weinberger \n" -"Language-Team: Canadian English \n" -"Language: en_CA\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "Cthulhu Screen Reader" -msgstr "" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -#, fuzzy -msgid "anim" -msgstr "animation" - -#: src/cthulhu/braille_rolenames.py:57 -#, fuzzy -msgid "arw" -msgstr "arrow" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -#, fuzzy -msgid "icn" -msgstr "icon" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -#, fuzzy -msgid "lnk" -msgstr "link" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -#, fuzzy -msgid "cll" -msgstr "cell" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -#, fuzzy -msgid "tre" -msgstr "tree" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "space" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "newline" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "quote" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "number" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "and" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "left paren" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "right paren" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "star" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "comma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "dash" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "dot" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slash" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "colon" - -#: src/cthulhu/chnames.py:122 -#, fuzzy -msgid "semicolon" -msgstr "colon" - -#: src/cthulhu/chnames.py:126 -#, fuzzy -msgid "less" -msgstr "less than" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "" - -#: src/cthulhu/chnames.py:134 -#, fuzzy -msgid "greater" -msgstr "greater than" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "question" - -#: src/cthulhu/chnames.py:142 -#, fuzzy -msgid "at" -msgstr "dat" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "left bracket" - -#: src/cthulhu/chnames.py:150 -#, fuzzy -msgid "backslash" -msgstr "slash" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "right bracket" - -#: src/cthulhu/chnames.py:158 -#, fuzzy -msgid "caret" -msgstr "cale" - -#: src/cthulhu/chnames.py:162 -#, fuzzy -msgid "underline" -msgstr "newline" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "left brace" - -#: src/cthulhu/chnames.py:174 -#, fuzzy -msgid "vertical bar" -msgstr "tool bar" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "right brace" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -#, fuzzy -msgid "tilde" -msgstr "table" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "space" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -#, fuzzy -msgid "cents" -msgstr "percent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -#, fuzzy -msgid "broken bar" -msgstr "menu bar" - -#: src/cthulhu/chnames.py:215 -#, fuzzy -msgid "section" -msgstr "question" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "left bracket" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -#, fuzzy -msgid "mu" -msgstr "mnu" - -#: src/cthulhu/chnames.py:275 -#, fuzzy -msgid "paragraph marker" -msgstr "paragraph" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "Terminal" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "right bracket" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -#, fuzzy -msgid "one half" -msgstr "one tab" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -#, fuzzy -msgid "a tilde" -msgstr "table" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -#, fuzzy -msgid "n tilde" -msgstr "table" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -#, fuzzy -msgid "o tilde" -msgstr "table" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "right bracket" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -#, fuzzy -msgid "per mille" -msgstr "Filler" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -#, fuzzy -msgid "check mark" -msgstr "check menu" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "left paren" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "right paren" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "left paren" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "right paren" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "Performs left click on current flat review item." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "Performs right click on current flat review item." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Speaks entire document." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "Speaks the current flat review line." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "Performs the \"Where Am I\" operation." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "Performs the \"Where Am I\" operation." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Speaks the current flat review line." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "status bar" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "Enters and exits flat review mode." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "Moves flat review to the end position." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "Moves flat review to the home position." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "Moves flat review to the end position." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "Moves flat review to the beginning of the previous line." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "Speaks the current flat review line." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "Speaks the current flat review line." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "Speaks the current flat review line." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "Moves flat review to the beginning of the next line." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "Moves flat review to the previous item or word." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "Speaks the current flat review item or word." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "Speaks the current flat review item or word." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "Speaks the current flat review item or word." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "Moves flat review to the next item or word." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "Moves flat review to the word above the current word." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "Speaks the current flat review object." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "Moves flat review to the word below the current word." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "Moves flat review to the previous character." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "Speaks the current flat review character." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "Speaks the current flat review character." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "Speaks the current flat review character." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "Moves flat review to the next character." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "Moves flat review to the end of the line." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "Moves flat review to the bottom left." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "Moves flat review to the end position." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Toggles whether to read just the current table cell or the whole row." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "Pans the braille display to the left." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "Pans the braille display to the right." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "Returns to object with keyboard focus." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "Moves flat review to the beginning of the next line." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Enters learn mode. Press escape to exit learn mode." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "Decreases the speech rate." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "Increases the speech rate." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "Decreases the speech rate." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "Increases the speech rate." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Increases the speech rate." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Decreases the speech rate." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Select desired speech server." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Select desired speech server." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "Decreases the speech rate." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "Increases the speech rate." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "Switches to the next presentation manager." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "Switches to the next presentation manager." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "Cycles the debug level at run time." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Moves flat review to the next character." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "Moves flat review to the previous character." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Moves flat review to the beginning of the next line." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "Moves flat review to the end of the line." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Speaks the current flat review line." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "toggle button" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "toggle button" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "check box" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "combo box" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "HTML container" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "HTML container" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "internal frame" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "internal frame" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "list item" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "Prints debug information about the ancestry of the object with focus" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "Returns to object with keyboard focus." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "paragraph" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "radio button" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "radio button" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "separator" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "tree table" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "tree table" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "right bracket" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "ToggleButton" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "grayed" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "right brace" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "right bracket" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "right paren" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "right brace" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "right paren" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "right paren" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "right bracket" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "right paren" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "newline" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Image" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "grayed" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "tab" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "white space" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "white space" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Icon" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "Use key echo? Enter y or n: " - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "comma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Exiting learn mode." - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "Application" - -#: src/cthulhu/guilabels.py:296 -#, fuzzy -msgid "Braille Bindings" -msgstr "Filler" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -#, fuzzy -msgid "_Desktop" -msgstr "DesktopIcon" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "lbl" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "Application" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "Window" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "quote" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Button" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "application" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "combo box" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "question" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Header" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Image" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Label" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "List" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragraph" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "selected" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "quote" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Button" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "combo box" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Image" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "List" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragraph" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Table" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "link" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "percent" - -#: src/cthulhu/guilabels.py:852 -#, fuzzy -msgid "Speech Dispatcher" -msgstr "Speech is unavailable." - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alert" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "left tab" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "left shift" - -#: src/cthulhu/keynames.py:64 -#, fuzzy -msgid "left alt" -msgstr "left tab" - -#: src/cthulhu/keynames.py:68 -#, fuzzy -msgid "left control" -msgstr "left tab" - -#: src/cthulhu/keynames.py:72 -#, fuzzy -msgid "right shift" -msgstr "right bracket" - -#: src/cthulhu/keynames.py:76 -#, fuzzy -msgid "right alt" -msgstr "right bracket" - -#: src/cthulhu/keynames.py:80 -#, fuzzy -msgid "right control" -msgstr "right bracket" - -#: src/cthulhu/keynames.py:84 -#, fuzzy -msgid "left meta" -msgstr "left tab" - -#: src/cthulhu/keynames.py:88 -#, fuzzy -msgid "right meta" -msgstr "right bracket" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -#, fuzzy -msgid "scroll lock" -msgstr "scroll bar" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -#, fuzzy -msgid "page up" -msgstr "page" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -#, fuzzy -msgid "page down" -msgstr "page" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "space" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "page" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "left tab" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "right bracket" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "left paren" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "right paren" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "and" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "space" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "left paren" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "arrow" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "right paren" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "arrow" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "right bracket" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "dot" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "autocomplete" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "separator" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "option pane" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "right bracket" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "layered pane" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Separator" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "question" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "internal frame" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "option pane" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "table" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "table" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "table" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -#, fuzzy -msgctxt "math symbol" -msgid "not less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "not pressed" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "right bracket" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "left tab" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "not pressed" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "image" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "internal frame" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "right bracket" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "right brace" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "separator" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:2025 -#, fuzzy -msgctxt "math symbol" -msgid "very much less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:2028 -#, fuzzy -msgctxt "math symbol" -msgid "very much greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "left paren" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "right paren" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "left tab" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "right bracket" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "left brace" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "left brace" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "left bracket" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "right bracket" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "white space" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "white space" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "white space" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "application" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "blank" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "Speech is unavailable." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "icon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, fuzzy, python-format -msgid "Cell %s" -msgstr "Cell" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "selected" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "selected" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "faster." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "question" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "HTML container" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "HTML container" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "not selected" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -#, fuzzy -msgid "entire document selected" -msgstr "not selected" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "not selected" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -#, fuzzy -msgid "Dynamic column header cleared." -msgstr "column header" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "Enters and exits flat review mode." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "Moves flat review to the word above the current word." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "dialogue" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "popup menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "Password" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "No page to read." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "and" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "root pane" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "root pane" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "root pane" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "table" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "tree table" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessible" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Table" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Table" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Learn mode. Press escape to exit." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "animation" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "Reading web page failed." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "Reading web page failed." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Exiting learn mode." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "link" - -#: src/cthulhu/messages.py:1518 -#, fuzzy -msgid "same page" -msgstr "page" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, fuzzy, python-format -msgid "%s link" -msgstr "link" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "tree level %d" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "tear off" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "icon" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Speech is unavailable." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Speech is unavailable." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "No page to read." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "tree level %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "No focus" - -#: src/cthulhu/messages.py:1867 -#, fuzzy -msgid "No application has focus." -msgstr "application" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "toggle button" - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "check box" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "No voices available.\n" - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "combo box" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "internal frame" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "list item" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "paragraph" - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "radio button" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "separator" - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "tree table" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "not selected" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "Application" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "ToolTip" - -#: src/cthulhu/messages.py:2013 -#, fuzzy -msgid "No notification messages" -msgstr " instant message" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "Password" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -#, fuzzy -msgid "off" -msgstr "tear off" - -#: src/cthulhu/messages.py:2051 -#, fuzzy -msgid "on" -msgstr "icon" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, fuzzy, python-format -msgid "Progress bar %d." -msgstr "progress bar" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "lbl" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -#, fuzzy -msgid "Search complete." -msgstr "autocomplete" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Select desired voice." - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "selected" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -#, fuzzy -msgid "Speech disabled." -msgstr "Speech is unavailable." - -#: src/cthulhu/messages.py:2258 -#, fuzzy -msgid "Speech enabled." -msgstr "Speech is unavailable." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "faster." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "slower." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -#, fuzzy -msgid "lower." -msgstr "slower." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "faster." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "No servers available.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "No voices available.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Speech is unavailable." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "Speech will not be used.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Speech is unavailable." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "status bar" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -#, fuzzy -msgid "Not in a table." -msgstr "No voices available.\n" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ColumnHeader" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, fuzzy, python-format -msgid "column %d" -msgstr "column header" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "selected" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "selected" - -#: src/cthulhu/messages.py:2458 -#, fuzzy, python-format -msgid "row %d" -msgstr "row header" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "Moves flat review to the end of the line." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "not selected" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "selected" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "selected" - -#: src/cthulhu/messages.py:2521 -#, fuzzy -msgctxt "text" -msgid "unselected" -msgstr "selected" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "white space" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -#, fuzzy -msgid "0 items" -msgstr "list item" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "dialogue" -msgstr[1] "dialogue" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "list item" -msgstr[1] "list item" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "list item" -msgstr[1] "list item" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "percent" -msgstr[1] "percent" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "plus" -msgstr[1] "plus" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "space" -msgstr[1] "space" - -#: src/cthulhu/messages.py:2813 -#, fuzzy, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "one tab" -msgstr[1] "one tab" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "table" -msgstr[1] "table" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "toggle button" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, fuzzy, python-format -msgid "LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "tree level %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "question" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "combo box" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "colon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "Application" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "paragraph" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -#, fuzzy -msgctxt "role" -msgid "page break" -msgstr "No page to read." - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "tab list" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "quote" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, fuzzy, python-format -msgid "h%d" -msgstr "hdr" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "scroll bar" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "scroll bar" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -#, fuzzy -msgid "Icon panel" -msgstr "option pane" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Animation" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Animation" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "spin button" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "collapsed" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "expanded" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "checked" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "not checked" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "icon" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "tear off" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "not checked" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "pressed" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "not pressed" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "selected" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "grayed" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "selected" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "invalid" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "invalid" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "invalid" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "CheckMenu" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "invalid" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:166 -#, fuzzy -msgid "_Top of window" -msgstr "window" - -#: src/cthulhu/cthulhu-find.ui:175 -#, fuzzy -msgid "Top of window" -msgstr "window" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "OptionPane" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:46 -#, fuzzy -msgid "Uppercase" -msgstr "percent" - -#: src/cthulhu/cthulhu-setup.ui:49 -#, fuzzy -msgid "Hyperlink" -msgstr "link" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Application" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Window" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Filler" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Application" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "progress bar" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2187 -#, fuzzy -msgid "Enable Braille _support" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "link" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -#, fuzzy -msgid "Braille" -msgstr "Filler" - -#: src/cthulhu/cthulhu-setup.ui:2780 -#, fuzzy -msgid "Enable _key echo" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2864 -#, fuzzy -msgid "Enable _modifier keys" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2879 -#, fuzzy -msgid "Enable _function keys" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2894 -#, fuzzy -msgid "Enable ac_tion keys" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2909 -#, fuzzy -msgid "Enable _navigation keys" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2965 -#, fuzzy -msgid "Enable echo by _word" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "font chooser" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3204 -#, fuzzy -msgid "Pronunciation" -msgstr "Animation" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "Use key echo? Enter y or n: " - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "arrow" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "directory pane" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "table" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -#, fuzzy -msgctxt "textattr" -msgid "invisible" -msgstr "inaccessible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "left paren" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "paragraph" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "right paren" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "cale" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "newline" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -#, fuzzy -msgctxt "textattr" -msgid "writing mode" -msgstr "Exiting learn mode." - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "newline" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "link" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "arrow" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "Password" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "trtbl" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "left tab" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "right bracket" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "percent" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "filler" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "colon" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "expanded" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "expanded" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "expanded" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "expanded" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "Text" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "Header" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "newline" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "tip" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "text" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "tab" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "CheckMenu" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -#, fuzzy -msgid "To get to the system menus press the alt+f1 key." -msgstr "To exit learn mode, press the escape key." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/en_GB.po b/po/en_GB.po deleted file mode 100644 index 2d0a8b5..0000000 --- a/po/en_GB.po +++ /dev/null @@ -1,9203 +0,0 @@ -# English (British) translation. -# Copyright (C) 2004 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same licence as the cthulhu package. -# Gareth Owen , 2004. -# Philip Withnall , 2010. -# Zander Brown , 2020. -# Bruce Cowan , 2009-2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-12-06 13:18+0000\n" -"Last-Translator: Bruce Cowan \n" -"Language-Team: English - United Kingdom \n" -"Language: en_GB\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Gtranslator 45.3\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu Screen Reader" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "screen reader;speech;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Czech Grade 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spanish Grade 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Canada French Grade 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "France French Grade 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvian Grade 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Netherlands Dutch Grade 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norwegian Grade 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norwegian Grade 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norwegian Grade 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norwegian Grade 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polish Grade 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portuguese Grade 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Swedish Grade 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabic Grade 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Welsh Grade 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Welsh Grade 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "German Grade 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "German Grade 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "German Grade 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "U.K. English Grade 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "U.K. English Grade 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "U.S. English Grade 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "U.S. English Grade 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Canada French Grade 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "France French Grade 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Greek Grade 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi Grade 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Hungarian 8 dot computer" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hungarian Grade 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Hungarian Grade 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italian Grade 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgium Dutch Grade 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "space" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "newline" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "exclaim" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "quote" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "number" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "and" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrophe" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "left bracket" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "right bracket" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "star" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "comma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "dash" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "full stop" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slash" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "colon" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semicolon" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "less" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "equals" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "greater" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "question" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "left square bracket" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "backslash" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "right square bracket" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "caret" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "underline" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "left brace" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertical bar" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "right brace" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "no break space" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "inverted exclamation mark" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cents" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pounds" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "currency sign" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "broken bar" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "section" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "left double angle bracket" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logical not" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "soft hyphen" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registered" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "degrees" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus or minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superscript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superscript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acute" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "paragraph marker" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "middle dot" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superscript 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "right double angle bracket" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "one quarter" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "one half" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "three quarters" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "inverted question mark" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "times" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "divided by" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "left single quote" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "right single quote" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "single low quote" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "left double quote" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "right double quote" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "double low quote" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "dagger" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "double dagger" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "bullet" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "triangular bullet" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prime" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "double prime" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "triple prime" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "hyphen bullet" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "trademark" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "tick mark" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "heavy tick mark" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-shaped bullet" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "superscript 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "superscript 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "superscript 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "superscript 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "superscript 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "superscript 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "superscript 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "superscript plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "superscript minus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "superscript equals" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "superscript left bracket" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "superscript right bracket" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "superscript n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "subscript 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "subscript 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "subscript 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "subscript 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "subscript 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "subscript 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "subscript 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "subscript 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "subscript 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "subscript 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "subscript plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "subscript minus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "subscript equals" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "subscript left bracket" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "subscript right bracket" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "black square" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "black diamond" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "object replacement character" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Route the pointer to the current item" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Perform left click on current flat review item" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Perform right click on current flat review item" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Speak entire document" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Speak entire window using flat review" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Perform the basic Where Am I operation" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Perform the detailed Where Am I operation" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Speak the current selection" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Speak link details" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Present the default button" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Present the status bar" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Present the title bar" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Open the Find dialogue" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Show actions menu" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Search for the next instance of a string" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Search for the previous instance of a string" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Enter and exit flat review mode" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Toggle restricting flat review to the current object" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Move flat review to the home position" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Move flat review to the end position" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Move flat review to the beginning of the previous line" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Speak the current flat review line" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Spell the current flat review line" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Phonetically spell the current flat review line" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Move flat review to the beginning of the next line" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Move flat review to the previous item or word" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Speak the current flat review item or word" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Spell the current flat review item or word" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Phonetically spell the current flat review item or word" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Move flat review to the next item or word" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Move flat review to the word above the current word" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Speak the current flat review object" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Move flat review to the word below the current word" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Move flat review to the previous character" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Speak the current flat review character" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Phonetically speak the current flat review character" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Speak unicode value of the current flat review character" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Move flat review to the next character" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Move flat review to the end of the line" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Move flat review to the bottom left" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copy the contents under flat review to the clipboard" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Append the contents under flat review to the clipboard" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Show flat review contents" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Toggle whether to read just the current table cell or the whole row" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Read the attributes associated with the current text character" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Pan the braille display to the left" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Pan the braille display to the right" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Return to object with keyboard focus" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Turn contracted braille on and off" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Process a cursor routing key" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Mark the beginning of a text selection" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Mark the end of a text selection" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Enter learn mode. Press escape to exit learn mode" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Decrease the speech rate" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Increase the speech rate" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Decrease the speech pitch" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Increase the speech pitch" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Increase the speech volume" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Decrease the speech volume" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Search for the previous instance of a string" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Cycle to the next speech synthesiser" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Decrease the speech rate" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Increase the speech rate" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Voice Type Settings" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Toggle the silencing of speech" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Toggle speech verbosity level" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Toggle layout mode" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Quit the screen reader" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Display the preferences configuration dialogue" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Display the application preferences configuration dialogue" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Toggle the speaking of indentation and justification" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Change spoken number style" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Cycle to the next speaking of punctuation level" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Cycle to the next speech synthesiser" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Cycle to the next settings profile" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Cycle to the next capitalisation style" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Cycle to the next key echo level" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Cycle the debug level at run time" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Bookmark where am I with respect to current position" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Go to previous bookmark location" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Go to bookmark" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Go to next bookmark location" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Add bookmark" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Save bookmarks" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Toggle mouse review mode" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Present current time" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Present current date" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Present size and location of current object" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Pass the next command on to the current application" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Speak and braille a previous chat room message" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Toggle whether we announce when our buddies are typing" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Toggle whether we provide chat room specific message histories" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Toggle whether we prefix chat room messages with the name of the chat room" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Line Left" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Line Right" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Line Up" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Line Down" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Freeze" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Top Left" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Bottom Left" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Cursor Position" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Six Dots" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Cursor Routing" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Cut Begin" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Cut Line" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Present last notification message" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Present notification messages list" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Present previous notification message" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Present next notification message" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Go to next character" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Go to previous character" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Go to next word" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Go to previous word" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Go to next line" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Go to previous line" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Go to the top of the file" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Go to the bottom of the file" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Go to the beginning of the line" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Go to the end of the line" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Go to the next object" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Go to the previous object" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Cause the current combo box to be expanded" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Switch between native and screen-reader caret navigation" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Advance live region politeness setting" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Set default live region politeness level to off" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Review live region announcement" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitor live regions" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Move focus into and away from the current mouse over" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Set the row to use as dynamic column headers" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Clear the dynamic column headers" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Set the column to use as dynamic row headers" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Clear the dynamic row headers" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Present the contents of the input line" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Toggle structural navigation keys" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Go to previous blockquote" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Go to next blockquote" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Display a list of blockquotes" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Go to previous button" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Go to next button" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Display a list of buttons" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Go to previous check box" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Go to next check box" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Display a list of check boxes" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Go to previous clickable" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Go to next clickable" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Display a list of clickables" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Go to previous combo box" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Go to next combo box" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Go to start of container" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Go to end of container" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Display a list of combo boxes" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Go to previous entry" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Go to next entry" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Display a list of entries" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Go to previous form field" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Go to next form field" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Display a list of form fields" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Go to previous heading" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Go to next heading" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Display a list of headings" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Go to previous heading at level %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Go to next heading at level %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Display a list of headings at level %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Go to previous internal frame" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Go to next internal frame" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Display a list of internal frames" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Go to previous image" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Go to next image" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Display a list of images" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Go to previous landmark" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Go to next landmark" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Display a list of landmarks" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Go to previous large object" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Go to next large object" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Display a list of large objects" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Go to previous link" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Go to next link" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Display a list of links" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Go to previous list" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Go to next list" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Display a list of lists" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Go to previous list item" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Go to next list item" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Display a list of list items" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Go to previous live region" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Go to next live region" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Go to the last live region which made an announcement" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Go to the parent of the object with navigator focus." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Go to the first child of the object with navigator focus." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Go to the next sibling of the object with navigator focus." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Go to the previous sibling of the object with navigator focus." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Click on the object with navigator focus." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Toggle simplified object navigation." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Go to previous paragraph" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Go to next paragraph" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Display a list of paragraphs" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Go to previous radio button" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Go to next radio button" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Display a list of radio buttons" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Go to previous separator" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Go to next separator" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Go to previous table" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Go to next table" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Display a list of tables" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Go down one cell" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Go to the first cell in a table" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Go to the last cell in a table" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Go left one cell" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Go right one cell" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Go up one cell" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Toggle layout mode" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Switch between browse mode and focus mode" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Enable sticky focus mode" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Enable sticky browse mode" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Go to previous unvisited link" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Go to next unvisited link" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Display a list of unvisited links" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Go to previous visited link" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Go to next visited link" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Display a list of visited links" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "alice blue" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antique white" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "aquamarine" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azure" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "black" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "blanched diamond" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blue" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "blue violet" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "brown" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "cadet blue" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chocolate" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "coral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "cornflower blue" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "crimson" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cyan" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "dark blue" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "dark cyan" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "dark goldenrod" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "dark grey" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "dark green" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "dark khaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "dark magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "dark olive green" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "dark orange" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "dark orchid" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "dark red" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "dark salmon" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "dark sea green" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "dark slate blue" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "dark slate grey" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "dark turquoise" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "dark violet" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "deep pink" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "deep sky blue" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "dim grey" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodger blue" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "fire brick" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "floral white" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "forest green" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "ghost white" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "gold" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "goldenrod" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "grey" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "green" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "green yellow" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "honeydew" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "hot pink" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indian red" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "ivory" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavender" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavender blush" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "lawn green" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "lemon chiffon" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "light blue" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "light coral" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "light cyan" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "light goldenrod yellow" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "light grey" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "light green" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "light pink" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "light salmon" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "light sea green" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "light sky blue" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "light slate grey" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "light steel blue" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "light yellow" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lime" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "lime green" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linen" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "maroon" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "medium aquamarine" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "medium blue" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "medium orchid" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "medium purple" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "medium sea green" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "medium slate blue" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "medium spring green" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "medium turquoise" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "medium violet red" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "midnight blue" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "mint cream" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "misty rose" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "moccasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajo white" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "navy" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "old lace" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olive" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "olive drab" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "orange" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "orange red" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchid" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "pale goldenrod" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "pale green" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "pale turquoise" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "pale violet red" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "peach puff" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "pink" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "plum" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "powder blue" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purple" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "red" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rosy brown" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "royal blue" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "saddle brown" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmon" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "sandy brown" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "sea green" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "seashell" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "silver" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "sky blue" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "slate blue" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "slate grey" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "snow" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "spring green" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "steel blue" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "tan" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "teal" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "thistle" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomato" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquoise" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violet" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "wheat" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "white" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "white smoke" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "yellow" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "yellow green" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Activate" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatic focus mode during structural navigation" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatic focus mode during caret navigation" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatic focus mode during native navigation" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Dot _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Dot _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Dots 7 an_d 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Cancel" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Jump to" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Icon" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "None" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Spell" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Announce when your _buddies are typing" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Provide chat room-specific _message histories" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Speak messages from" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "All cha_nnels" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "All channels when an_y %s window is active" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "A channel only if its _window is active" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Speak Chat Room name" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Enable layout mode for content" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "double click" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triple click" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Default Synthesiser" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Actual String" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Replacement String" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Enable echo by cha_racter" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Enable non-spacing _diacritical keys" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "C_urrent location" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimum length of matched text:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Find Options" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Onl_y speak changed lines during find" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Speak results during _find" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Command" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Key Binding" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Default" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Learn mode" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Actions" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braille Bindings" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Bookmarks" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Date and time" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Mouse review" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Object navigation" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Object details" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Unbound" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Flat review" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Speech and verbosity" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Flat review contents" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modified" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Desktop" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notifications" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Received" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Notification presenter" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu Preferences for %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Mark in braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Present Unless" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Speak" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Save Profile As Conflict" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "User Profile Conflict!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Load user profile" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Save Profile As" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profile Name:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Remove user profile" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "All" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Application" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Window" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_None" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "So_me" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "M_ost" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Line" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Sentence" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Blockquote" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Button" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Caption" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Tick Box" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Clickable" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Combo Box" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Description" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Heading" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Internal Frame" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Image" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Label" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Landmark" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Level" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Link" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "List" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "List Item" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Object" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragraph" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radio Button" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Role" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Selected Item" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "State" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Value" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blockquotes" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Buttons" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Tick Boxes" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Clickables" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Combo Boxes" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entries" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Form Fields" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Headings" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Internal Frames" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Images" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Headings at Level %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Landmarks" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Large Objects" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Links" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Lists" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "List Items" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragraphs" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radio Buttons" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tables" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Unvisited Links" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Visited Links" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Page Navigation" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Automatically start speaking a page when it is first _loaded" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Present summary of a page when it is first loaded" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Break speech into ch_unks between pauses" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s default voice" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Default" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "System" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Uppercase" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Spell Check" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Spell _error" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Spell _suggestion" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Present _context of error" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Speak spreadsheet cell coordinates" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Always speak selected spreadsheet range" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Announce cell _header" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Table Navigation" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Skip _blank cells" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Speak _cell" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Speak _cell co-ordinates" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Speak _multiple cell spans" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Attribute Name" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Control caret navigation" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Enable _structural navigation" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Sound _theme:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Sound Theme" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Brie_f" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d notification" -msgstr[1] "%d notifications" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "left shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "left alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "left control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "right shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "right alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "right control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "left meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "right meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "up" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "left" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "right" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "left super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "right super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "help" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "mode switch" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "stroke" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "bold %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "italic %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "bold italic %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "script %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "bold script %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "double-struck %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "bold fraktur %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif bold %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif italic %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif bold italic %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "monospace %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "dotless %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "left arrow" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "up arrow" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "right arrow" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "down arrow" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "left right arrow" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "up down arrow" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "north west arrow" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "north east arrow" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "south east arrow" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "left arrow from bar" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "up arrow from bar" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "right arrow from bar" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "down arrow from bar" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "left double arrow" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "up double arrow" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "right double arrow" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "down double arrow" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "left right double arrow" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "up down double arrow" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "north west double arrow" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "north east double arrow" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "south east double arrow" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "south west double arrow" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "right-pointing arrow" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "right-pointing arrowhead" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "less than" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "greater than" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "dot" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "double vertical line" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horizontal ellipsis" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "for all" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "partial differential" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "there exists" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "there does not exist" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "empty set" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "increment" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nable" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "element of" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "not an element of" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "small element of" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "contains as a member" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "does not contain as a member" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "small contains as a member" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "end of proof" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "product" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproduct" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sum" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus or plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "dot plus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "division slash" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "set minus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "asterisk operator" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "ring operator" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "bullet operator" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "cube root" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "fourth root" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proportional to" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinity" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "right angle" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "angle" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "measured angle" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "spherical angle" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "divides" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "does not divide" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "parallel to" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "not parallel to" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logical and" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logical or" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersection" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "union" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "double integral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "triple integral" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "contour integral" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "surface interval" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "volume integral" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "clockwise integral" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "clockwise contour integral" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "anticlockwise contour integral" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "therefore" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "because" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "ratio" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proportion" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "dot minus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "excess" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometric proportion" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homothetic" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "reversed tilde" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "inverted lazy S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sine wave" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "wreath product" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "not tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minus tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptotically equal to" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "not asymptotically equal to" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "approximately equal to" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "approximately but not actually equal to" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "neither approximately nor actually equal to" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "almost equal to" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "not almost equal to" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "almost equal or equal to" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "triple tilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "all equal to" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "equivalent to" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrically equivalent to" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "difference between" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "approaches the limit" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrically equal to" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "approximately equal to or the image of" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "image of or approximately equal to" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "colon equals" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "equals colon" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ring in equal to" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ring equal to" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "corresponds to" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estimates" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "equiangular to" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "star equals" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta equal to" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "equal to by definition" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "measured by" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "questioned equal to" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "not equal to" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identical to" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "not identical to" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "strictly equivalent to" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "less than over equal to" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "greater than over equal to" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "less than but not equal to" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "greater than but not equal to" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "much less than" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "much greater than" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "between" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "not equivalent to" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "not less than" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "not greater than" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "neither less than nor equal to" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "neither greater than nor equal to" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "less than or equivalent to" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "greater than or equivalent to" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "neither less than nor equivalent to" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "neither greater than nor equivalent to" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "less than or greater than" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "greater than or less than" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "neither less than nor greater than" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "neither greater than nor less than" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "precedes" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "succeeds" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "precedes or equal to" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "succeeds or equal to" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "precedes or equivalent to" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "succeeds or equivalent to" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "does not precede" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "does not succeed" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subset of" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superset of" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "not a subset of" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "not a superset of" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subset of or equal to" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superset of or equal to" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "neither a subset of nor equal to" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "neither a superset of nor equal to" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subset of with not equal to" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superset of with not equal to" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiset" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiset multiplication" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "multiset union" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "square image of" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "square original of" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "square image of or equal to" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "square original of or equal to" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "square cap" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "square cup" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "circled plus" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "circled minus" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "circled times" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "circled division slash" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "circled dot operator" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "circled ring operator" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "circled asterisk operator" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "circled equals" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "circled dash" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "squared plus" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "squared minus" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "squared times" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "squared dot operator" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "right tack" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "left tack" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "down tack" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "up tack" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "assertion" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "models" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "forces" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "triple vertical bar right turnstile" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "double vertical bar double right turnstile" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "does not prove" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "not true" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "does not force" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "negated double vertical bar double right turnstile" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "precedes under relation" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "succeeds under relation" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normal subgroup of" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "contains as normal subgroup" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normal subgroup of or equal to" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "contains as normal subgroup of or equal to" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original of" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "image of" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimap" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitian conjugate matrix" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalate" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "right angle with arc" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "right triangle" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "diamond operator" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "dot operator" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "star operator" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "division times" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "bowtie" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "left normal factor semidirect product" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "right normal factor semidirect product" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "left semidirect product" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "right semidirect product" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "reversed tilde equals" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "curly logical or" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "curly logical and" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "double subset" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "double superset" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "double intersection" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "double union" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "pitchfork" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "equal and parallel to" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "less than with dot" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "greater than with dot" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "very much less than" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "very much greater than" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "less than equal to or greater than" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "greater than equal to or less than" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "equal to or less than" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "equal to or greater than" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "equal to or precedes" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "equal to or succeeds" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "does not precede or equal" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "does not succeed or equal" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "not square image of or equal to" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "not square original of or equal to" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "square image of or not equal to" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "square original of or not equal to" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "less than but not equivalent to" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "greater than but not equivalent to" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "precedes but not equivalent to" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "succeeds but not equivalent to" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "not normal subgroup of" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "does not contain as normal subgroup" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "not normal subgroup of or equal to" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "does not contain as normal subgroup or equal" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertical ellipsis" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "midline horizontal ellipsis" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "up right diagonal ellipsis" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "down right diagonal ellipsis" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "element of with long horizontal stroke" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "element of with vertical bar at end of horizontal stroke" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "small element of with vertical bar at end of horizontal stroke" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "element of with dot above" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "element of with overbar" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "small element of with overbar" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "element of with underbar" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "element of with two horizontal strokes" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "contains with long horizontal stroke" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "contains with vertical bar at end of horizontal stroke" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "small contains with vertical bar at end of horizontal stroke" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "contains with overbar" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "small contains with overbar" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z notation bag membership" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "left ceiling" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "right ceiling" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "left floor" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "right floor" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "top brace" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "bottom brace" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "left angle bracket" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "right angle bracket" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "circled dot" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "union with dot" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "union with plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "square intersection" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "square union" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "black square" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "white square" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "black diamond" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "white circle" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "black circle" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "white bullet" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "black medium small square" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s with underline" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s with slash" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s with vertical line" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "application" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "blank" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "bold" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "bookmark entered" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "bookmarks saved" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "bookmarks could not be saved" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "No bookmarks found." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Bookmark not found." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Bypass mode enabled." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Unable to get calculator display" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "icon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Capitalisation style set to icon." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "none" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Capitalisation style set to none." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "spell" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Capitalisation style set to spell." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "The application is controlling the caret." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "The application is controlling the caret." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cell %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s selected" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s to %s selected" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s to %s unselected" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s unselected" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Prevent use of option" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Force use of option" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPTION" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Optional arguments" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Usage: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "The following are not valid: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Print the known running applications" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Load profile" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profile could not be loaded: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Cannot start the screen reader because it cannot connect to the Desktop." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Could not activate the settings manager. Exiting." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Another screen reader process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Use alternate directory for user preferences" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Version of this application" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Replace a currently running instance of this screen reader" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Show this help message and exit" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Send debug output to the specified file" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FILE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Set up user preferences (text version)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Set up user preferences (GUI version)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Report bugs to https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Cut selection to clipboard." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "cut" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Copied selection to clipboard." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copied" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Pasted contents from clipboard." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "pasted" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Do not announce when your buddies are typing." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "announce when your buddies are typing." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Message from chat room %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "New chat tab %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Do not speak chat room name." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "speak chat room name." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Do not provide chat room-specific message histories." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Provide chat room-specific message histories." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "deletion start" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "deletion end" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "insertion start" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "insertion end" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "highlight start" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "highlight end" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "suggestion end" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "End of container." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Not in a container." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "all items selected" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Default button is %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Default button is %s. Greyed" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Default button not found" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subscript %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " superscript %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Not in a dialogue" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "entire document selected" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "entire document unselected" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "document selected from cursor position" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "document unselected from cursor position" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "document selected to cursor position" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "document unselected to cursor position" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynamic column header set for row %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynamic column header cleared." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynamic row header set for column %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynamic row header cleared." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "empty" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "No files found." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Appended contents to clipboard." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Copied contents to clipboard." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Not using flat review." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Entering flat review." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Leaving flat review." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Flat review restricted to the current object" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Flat review unrestricted" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "has formula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "opens dialogue" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "opens grid" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "opens listbox" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "opens menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "opens tree" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "image map link" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "The key entered is already bound to %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Key captured: %s. Press enter to confirm." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "The new key is: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Key binding deleted. Press enter to confirm." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "The keybinding has been removed." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "enter new key" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "key" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Echo set to key." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "None" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Echo set to None." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "key and word" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Echo set to key and word." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "sentence" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Echo set to sentence." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "word" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Echo set to word." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "word and sentence" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Echo set to word and sentence." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Enclosed by: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "an actuarial symbol" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "a box" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "a circle" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "a long division sign" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "a radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "a rounded box" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "a horizontal strike" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "a vertical strike" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "a down diagonal strike" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "an up diagonal strike" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "a northeast arrow" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "a line at the bottom" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "a line on the left" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "a line on the right" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "a line at the top" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "a phasor angle" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "an arabic factorial symbol" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "and" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "fraction start" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "fraction without bar, start" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "over" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "fraction end" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "square root of" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "cube root of" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "root of" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "root start" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "root end" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subscript" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "superscript" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pre-subscript" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pre-superscript" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "underscript" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "overscript" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "table end" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "nested table end" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessible" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Disabled" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Speaking of indentation and justification disabled." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Enabled" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Speaking of indentation and justification enabled." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Learn mode. Press escape to exit." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Entering learn mode. Press any key to hear its function. To view the " -"screen reader’s documentation, press F1. To get a list of the screen " -"reader’s default shortcuts, press F2. To get a list of the screen reader’s " -"shortcuts for the current application, press F3. To exit learn mode, press " -"the escape key." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "leaving blockquote." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "leaving details." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "leaving feed." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "leaving figure." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "leaving form." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "leaving banner." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "leaving complementary content." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "leaving information." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "leaving main content." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "leaving navigation." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "leaving region." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "leaving search." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "leaving list." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "leaving panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "leaving tooltip." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "leaving abstract." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "leaving acknowledgments." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "leaving afterword." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "leaving appendix." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "leaving bibliography." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "leaving chapter." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "leaving colophon." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "leaving conclusion." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "leaving credit." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "leaving credits." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "leaving dedication." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "leaving endnotes." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "leaving epigraph." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "leaving epilogue." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "leaving errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "leaving example." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "leaving foreword." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "leaving glossary." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "leaving index." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "leaving introduction." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "leaving page list." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "leaving part." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "leaving preface." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "leaving prologue." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "leaving pullquote." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "leaving QNA." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "leaving suggestion." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "leaving table of contents." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "line selected down from cursor position" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "line selected up from cursor position" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "line unselected down from cursor position" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "line unselected up from cursor position" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Exiting learn mode." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "line selected from start to previous cursor position" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "line selected to end from previous cursor position" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "link" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "same page" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "same site" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "different site" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s link to %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s link" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "visited %s link" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "Use Up and Down Arrows to navigate the list. Press Escape to exit." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "All live regions set to off" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "live regions politeness levels restored" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "politeness level %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "setting live region to assertive" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "setting live region to off" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "setting live region to polite" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "setting live region to rude" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Live regions monitoring off" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Live regions monitoring on" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "no live message saved" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Live region support is off" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Not found" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Could not find current location." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "off" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "on" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "misspelt" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Misspelt word: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Context is %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Browse mode" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Focus mode" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "To enable focus mode press %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Focus mode is sticky." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Browse mode is sticky." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Layout mode." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Object mode." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Pointer moved to object." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Mouse over object not found." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Mouse review disabled." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Mouse review enabled." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Error: Could not create list of objects." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "No children." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "No next." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "No parent." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "No previous." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Simplified navigation enabled." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Simplified navigation disabled." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nesting level %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "New item has been added" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "No actions found on: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "No focus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "No application has focus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "No more blockquotes." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "No more buttons." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "No more tick boxes." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "No more large objects." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "No more clickables." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "No more combo boxes." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "No more entries." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "No more form fields." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "No more headings." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "No more headings at level %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "No more internal frames." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "No more images." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "No more links." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "No more lists." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "No more list items." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "No more live regions." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "No more paragraphs." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "No more radio buttons." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "No more separators." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "No more tables." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "No more unvisited links." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "No more visited links." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "No selected text." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Not on a link." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notification" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Bottom" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Top" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "No notification messages" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "digits" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Speak numbers as digits." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "words" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Speak numbers as words." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "off" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "on" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Loading. Please wait." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Finished loading." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Finished loading %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Page has %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "page selected from cursor position" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "page selected to cursor position" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "page unselected from cursor position" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "page unselected to cursor position" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "paragraph selected down from cursor position" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragraph selected up from cursor position" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "paragraph unselected down from cursor position" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragraph unselected up from cursor position" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"You already have an instance of an Cthulhu preferences dialogue open.\n" -"Please close it before opening a new one." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "slide %(position)d of %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profile set to %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "No profiles found." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Progress bar %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "All" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Punctuation level set to all." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Most" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Punctuation level set to most." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "None" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Punctuation level set to none." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Some" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Punctuation level set to some." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Searching." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Search complete." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Screen reader settings reloaded." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Selected text is: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Selection deleted." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Selection restored." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Text unselected." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Size: %d, %d. Location: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Width: %d. Height: %d. %d from left. %d from top." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Speech disabled." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Speech enabled." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "faster." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "slower." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "higher." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "lower." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "louder." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "softer." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Rate %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Pitch %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volume %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher module %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher voice %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "No servers available." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "No voices available." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Speech enabled." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Speech will not be used." - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Verbosity level: brief" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Verbosity level: verbose" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu Preferences" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu lurks beneath the waves." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Sleep mode enabled for %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Sleep mode disabled for %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Speech is unavailable." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Not found" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Status bar not found" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "string not found" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Structural navigation keys off." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Structural navigation keys on." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Not found" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Row %(row)d, column %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "End of table" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Speak cell" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Speak row" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Non-uniform" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Not in a table." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Columns reordered" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Rows reordered" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "column %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "column %(index)d of %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Bottom of column." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Top of column." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Column %s selected" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Columns %s to %s selected" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Columns %s to %s unselected" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Column %s unselected" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "row %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "row %(index)d of %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Beginning of row." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "End of row." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Row deleted." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Last row deleted." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Row inserted." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Row inserted at the end of the table." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Row %s selected" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Rows %s to %s selected" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Rows %s to %s unselected" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Row %s unselected" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "selected" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "unselected" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H hours, %M minutes and %S seconds" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H hours and %M minutes" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "undo" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "redo" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu version %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "white space" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Wrapping to bottom." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Wrapping to top." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 items" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Cell spans %d row" -msgstr[1] "Cell spans %d rows" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d column" -msgstr[1] " %d columns" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Cell spans %d column" -msgstr[1] "Cell spans %d columns" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d character too long" -msgstr[1] "%d characters too long" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialogue)" -msgstr[1] "(%d dialogues)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d unfocused dialogue" -msgstr[1] "%d unfocused dialogues" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d file found" -msgstr[1] "%d files found" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d form" -msgstr[1] "%d forms" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d heading" -msgstr[1] "%d headings" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d item" -msgstr[1] "%d items" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d landmark" -msgstr[1] "%d landmarks" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d item found" -msgstr[1] "%d items found" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Leaving %d blockquote." -msgstr[1] "Leaving %d blockquotes." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Leaving %d list." -msgstr[1] "Leaving %d lists." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "List of unknown size" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "List with %d item" -msgstr[1] "List with %d items" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Feed of unknown size" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Feed with %d article" -msgstr[1] "Feed with %d articles" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Description list with %d term" -msgstr[1] "Description list with %d terms" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d value" -msgstr[1] "%d values" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "math table with %d row" -msgstr[1] "math table with %d rows" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d column" -msgstr[1] "%d columns" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "nested math table with %d row" -msgstr[1] "nested math table with %d rows" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d message.\n" -msgstr[1] "%d messages.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d percent." -msgstr[1] "%d percent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d percent of document read" -msgstr[1] "%d percent of document read" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixels" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s character" -msgstr[1] "%(count)d %(repeatChar)s characters" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d of %(total)d item selected" -msgstr[1] "%(index)d of %(total)d items selected" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d Screen reader default shortcut found." -msgstr[1] "%d Screen reader default shortcuts found." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d Screen reader shortcut for %(application)s found." -msgstr[1] "%(count)d Screen reader shortcuts for %(application)s found." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d space" -msgstr[1] "%d spaces" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tab" -msgstr[1] "%d tabs" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d table" -msgstr[1] "%d tables" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "table of unknown size" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "table with %d column, row count unknown" -msgstr[1] "table with %d columns, row count unknown" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "table with %d row, column count unknown" -msgstr[1] "table with %d rows, column count unknown" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "table with %d row" -msgstr[1] "table with %d rows" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d second ago" -msgstr[1] "%d seconds ago" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minute ago" -msgstr[1] "%d minutes ago" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d hour ago" -msgstr[1] "%d hours ago" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d day ago" -msgstr[1] "%d days ago" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d unvisited link" -msgstr[1] "%d unvisited links" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d visited link" -msgstr[1] "%d visited links" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "toggle" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "on %(index)d of %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d of %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "item %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "LEVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "tree level %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "details for %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "has details in %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "suggestion" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "editable combo box" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "editable content" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "feed" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figure" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "abstract" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "acknowledgments" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "afterword" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "appendix" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "bibliography entry" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliography" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "chapter" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colophon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conclusion" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "cover" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "credit" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "credits" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedication" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "endnote" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "endnotes" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraph" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilogue" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "example" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "foreword" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glossary" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "index" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introduction" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "page break" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "page list" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "part" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "preface" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prologue" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "pullquote" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "QNA" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "subtitle" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "table of contents" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s level %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "horizontal scroll bar" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "vertical scroll bar" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "horizontal slider" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "vertical slider" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "horizontal splitter" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "vertical splitter" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "switch" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Icon panel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "banner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "complementary content" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "information" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "main content" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigation" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "region" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "search" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "visited link" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "menu button" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "sorted ascending" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "sorted descending" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "sorted" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "clickable" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "collapsed" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "expanded" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "has long description" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "ticked" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "not ticked" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "on" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "off" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "partially ticked" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "pressed" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "not pressed" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "selected" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visited" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "unvisited" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "greyed" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "read-only" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "rdonly" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "required" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "multi-select" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "invalid entry" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "invalid" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "invalid spelling" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "spelling" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "invalid grammar" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "grammar" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Find" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Screen Reader Find Dialogue" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Close" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Find" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Search for:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Search for:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Top of window" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Top of window" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Start from:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Wrap around" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Search _backwards" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Search direction:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Match case" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Match _entire word only" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Options:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Default" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Uppercase" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "System" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Application" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Window" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu Preferences" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Help" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Apply" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Keyboard Layout" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Active _Profile:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Start-up Profile:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Load" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Save _As" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Remove" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiles" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Present tooltips" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Speak object under mo_use" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Mouse" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Time format:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Dat_e format:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Time and Date" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Speak updates" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Braille updates" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frequency (secs):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Applies to:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Bee_p updates" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Progress Bar Updates" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Enable _rewind and fast forward in Say All" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Enable _structural navigation in Say All" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Say All B_y:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Announce block_quotes in Say All" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Announce li_sts in Say All" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Announce _tables in Say All" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Announce _panels in Say All" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Announce _forms in Say All" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Announce land_marks in Say All" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Say All" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Element _presentation:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "General" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lume:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Pi_tch:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Rate:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Person:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Language:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Speech s_ynthesiser:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Speech _system:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Voice type:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Capitalization style:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Voice Type Settings" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Speak multicase strings as wor_ds" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Speak _numbers as digits" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Global Voice Settings" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voice" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Enable speech" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Ver_bose" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Verbosity" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_All" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Punctuation Level" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Only speak displayed text" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Speak blank lines" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Speak _indentation and justification" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Spea_k object mnemonics" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Speak child p_osition" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Speak tutorial messages" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_System messages are detailed" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "S_peak colours as names" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Announce block_quotes during navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Announce _lists during navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Announce _tables during navigation" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Speak _misspelt-word indicator" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Announce _panels during navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Announce land_marks during navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Announce _forms during navigation" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Speak _description" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Speak full row in sp_readsheets" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Speak full row in _document tables" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Speak full row in _GUI tables" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Spoken Context" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Speech" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Enable Braille _support" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Abbreviated role names" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Disable _end of line symbol" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Contraction _Table:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Enable Contracted Braille" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Enable _word wrap" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Display Settings" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_None" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Selection Indicator" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hyperlink Indicator" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Enable flash _messages" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "D_uration (secs):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Messages are _persistent" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Messages are _detailed" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Flash Message Settings" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Enable _key echo" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Enable _alphabetic keys" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Enable n_umeric keys" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Enable _punctuation keys" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Enable _space" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Enable _modifier keys" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Enable _function keys" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Enable ac_tion keys" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Enable _navigation keys" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Enable echo by _word" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Enable echo by _sentence" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Echo" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Screen Reader _Modifier Key(s):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Key Bindings" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Pronunciation Dictionary" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_New entry" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Delete" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronunciation" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Speak all" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Speak _none" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Reset" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Text attributes" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Move to _bottom" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Move _down one" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Move _up one" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Move to _top" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Adjust selected attribute" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Braille Indicator" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Text Attributes" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Assistant" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Provider:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Local - Free)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API _Key File:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Path to API key file" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Get _Claude API Key" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Open browser to get Claude API key and save automatically" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Require confirmation before AI actions" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _Model:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Model name for Ollama (e.g., llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _Endpoint:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Screenshot _Quality:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "row" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Medium" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "High" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Assistant" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Language:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Scale _factor:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Greyscale Image" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Invert Image" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Black and White Image" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Black/White _Threshold:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analyse Colours" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Copied contents to clipboard." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "SCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "background colour" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "background full height" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "background stipple" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direction" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editable" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "family name" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "foreground colour" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "foreground stipple" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "font effect" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indent" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "mistake" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justification" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "language" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "left margin" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "line height" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "paragraph style" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixels above lines" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixels below lines" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixels inside wrap" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "right margin" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "rise" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "scale" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "size" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "stretch" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "strike through" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "style" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "text decoration" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "text rotation" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "text shadow" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "underline" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "vertical align" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "weight" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "wrap mode" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "writing mode" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "none" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "engrave" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "emboss" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "outline" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "overline" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "line through" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "blink" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "black" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "single" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "double" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "low" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "char" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "word" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "word char" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "left" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "right" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centre" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "no justification" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "fill" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra-condensed" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra-condensed" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensed" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi-condensed" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi-expanded" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expanded" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra-expanded" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra-expanded" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "small caps" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblique" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "italic" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Default" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Text body" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Heading" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "baseline" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "top" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "text-top" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "middle" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "bottom" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "text-bottom" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "inherit" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "solid" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "spelling" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Press space to toggle." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "Press space to expand, and use up and down to select an item." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Press Alt+F6 to give focus to child windows." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "To move to items, use either the arrow keys or type-ahead searching." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "To get to the system menus press the Alt+F1 key." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Use up and down to select an item." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "To collapse, press shift plus left." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "To expand, press shift plus right." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "To activate press return." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Type in text." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Use left and right to view other tabs." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "To activate press space." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Use up or down arrow to select value, or type in the desired numerical value." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Use arrow keys to change." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"To navigate, press the left or right arrows. To move through items press the " -"up or down arrows." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "To enter a sub-menu, press the right arrow." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"To decrease, press the left arrow; to increase, press the right arrow. To go " -"to minimum press home, and for maximum press end." diff --git a/po/eo.po b/po/eo.po deleted file mode 100644 index 1100c04..0000000 --- a/po/eo.po +++ /dev/null @@ -1,9922 +0,0 @@ -# Esperanto translation for gnome-cthulhu. -# Copyright (C) 2010 Free Software Foundation, Inc. -# This file is distributed under the same license as the gnome-cthulhu package. -# Michael MORONI < >, 2011. -# Nicolas MAIA < >, 2015 -# Kristjan SCHMIDT , 2010-2023. -# -msgid "" -msgstr "" -"Project-Id-Version: gnome-cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-09-15 20:08+0200\n" -"Last-Translator: Kristjan SCHMIDT \n" -"Language-Team: Esperanto \n" -"Language: eo\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.2.2\n" -"X-Project-Style: gnome\n" - -msgid "Cthulhu Screen Reader" -msgstr "Ekranlegilo Orko" - -#, fuzzy -msgid "screen;reader;accessibility;speech;braille;" -msgstr "ekranlegilo;parolo;brajlo;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "diskelektilo" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "desegni" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "formularo" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuer" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pvt" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbrt" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuer" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tkt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "ibret" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arb" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "nek" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ppied" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apl" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "aŭto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "redbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "enk" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Ĉeĥa unuagrade" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Hispana unuagrade" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Franca kiel en Kanado duagrade" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Franca kiel en Francio duagrade" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latva unuagrade" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Nederlanda kiel en Nederlando unuagrade" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvega nulagrade" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvega unuagrade" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvega duagrade" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvega triagrade" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Pola unuagrade" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugala unuagrade" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Sveda unuagrade" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Araba unuagrade" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Kimra unuagrade" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Kimra duagrade" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Germana nulagrade" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Germana unuagrade" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Germana duagrade" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Angla kiel en Britio duagrade" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Angla kiel en Britio unuagrade" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Angla kiel en Usono unuagrade" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Angla kiel en Usono duagrade" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Franca kiel en Kanado unuagrade" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Franca kiel en Francio unuagrade" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Greka unuagrade" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindia unuagrade" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Hungara 8-punkta komputilo" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hungara unuagrade" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Hungara duagrade" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Itala unuagrade" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgio nederlanda klaso 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "spaco" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nova lineo" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "langeto" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "krisigno" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "citilo" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "numero" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolaro" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "elcento" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "kaj" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrofo" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "maldekstra krampo" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "dekstra krampo" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "stelo" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "komo" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "haltostreko" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punkto" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "oblikvo" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dupunkto" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punktokomo" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "malpli-signo" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "egalsigno" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "pli-signo" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "demando" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "heliko" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "maldekstra kvadrata krampo" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "deklivo" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "dekstra kvadrata krampo" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "ĉapelo" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "substreko" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "maldekstra korno" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "maldekstra kurba krampo" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertikala streko" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "dekstra kurba krampo" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tildo" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "nerompebla spaceto" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "inversa krisigno" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cendoj" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pundoj" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "valutsigno" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "eno" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "rompita stango" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "sekcio" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "kopirajto" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superskribo a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "maldekstra duobla angula krampo" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logika neo" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "mola streketo" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "makrono" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "gradoj" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus-minus-signo" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superskribo 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superskribo 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "dekstra korno" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "muo" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "alinea markilo" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "meza punkto" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "subhoko" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superskribo 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "dekstra duobla angula krampo" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "kvarono" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "duono" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tri kvaronoj" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "inversa demandosigno" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a dekstra korno" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A MALDEKTRA KORNO" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A DEKSTRA KORNO" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRKUMFLEKSO" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDO" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAŬTO" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RINGO" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILO" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E MALDEKTRA KORNO" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E DEKSTRA KORNO" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRKUMFLEKSO" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAŬTO" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I MALDEKTRA KORNO" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I DEKSTRA KORNO" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRKUMFLEKSO" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAŬTO" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDO" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O MALDEKTRA KORNO" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O DEKSTRA KORNO" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRKUMFLEKSO" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDO" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAŬTO" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "oble" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "STREKO-O" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U MALDEKTRA KORNO" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U DEKSTRA KORNO" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRKUMFLEKSO" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAŬTO" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y DEKSTRA KORNO" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a maldekstra korno" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a cirkumflekso" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tildo" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaŭto" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "ringo" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilo" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e maldekstra korno" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e dekstra korno" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e cirkumflekso" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaŭto" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i maldekstra korno" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i dekstra korno" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i cirkumflekso" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaŭto" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tildo" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o maldekstra korno" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o dekstra korno" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o cirkumflekso" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tildo" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaŭto" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "dividita de" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "streko-o" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u dekstra korno" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u maldekstra korno" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u cirkumflekso" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaŭto" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y dekstra korno" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaŭto" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAŬTO" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florino" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "haltostreko" - -#: src/cthulhu/chnames.py:584 -#, fuzzy -msgid "left single quote" -msgstr "unuope" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "unuope" - -#: src/cthulhu/chnames.py:593 -#, fuzzy -msgid "single low quote" -msgstr "unuope" - -#: src/cthulhu/chnames.py:597 -#, fuzzy -msgid "left double quote" -msgstr "duoble" - -#: src/cthulhu/chnames.py:601 -#, fuzzy -msgid "right double quote" -msgstr "duoble" - -#: src/cthulhu/chnames.py:605 -#, fuzzy -msgid "double low quote" -msgstr "duoble" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "duobla obeluso" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "bulmarko" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "triangula bulmarko" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "elmilo" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -#, fuzzy -msgid "double prime" -msgstr "duoble" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "triobla alklako" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "steketa bulmarko" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "eŭro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "registrita marko" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "marko" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "peza marko" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "superskribo 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "superskribo 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "superskribo 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "superskribo 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "superskribo 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "superskribo 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "superskribo 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "superskribo plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "superskribo minus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "superskribo egalas" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "maldekstra krampo" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "dekstra krampo" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "superskribo n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "subskribo 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "subskribo 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "subskribo 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "subskribo 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "subskribo 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "subskribo 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "subskribo 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "subskribo 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "subskribo 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "subskribo 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "subskribo plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "subskribo minus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "subskribo egalas" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "subskribo maldekstra gepatro" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "subskribo dekstra gepatro" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "nigra kvadrato" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "nigra diamanto" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "objektan anstataŭan karakteron" - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "Krei novan eron en la nuna komponanto" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Faru maldekstran klakon sur nuna ebena revizia objekto" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Faru dekstran klakon sur nuna ebena revizia objekto" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Paroli tutan dokumenton" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Paroli tutan fenestron uzante ebenan revizion" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Fari la bazan operacion \"Kie mi estas\"" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Fari la detalan operacion \"Kie mi estas\"" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Paroli la nunan elekton" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "Detaloj" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "Defaŭlta butono estas %s" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "Montri la statbreton" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "Sen titolo" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Ekranlegila serĉdialogo" - -#: src/cthulhu/cmdnames.py:118 -#, fuzzy -msgid "Show actions list" -msgstr "Montri menuon de agoj" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "Serĉi sekvan okazon de la nuna serĉĉeno" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "Serĉi antaŭan okazon de la nuna serĉĉeno" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "Eniri kaj eliri platan revizian reĝimon" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Ŝalti limigi platan revizion al la nuna objekto" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Movi platan revizion al la hejma pozicio" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Parolu la nunan ebenan revizian linion" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Literumi la nunan platan revizian linion" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Fonetike literumi la nunan platan revizian linion" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Paroli la nunan ebenan recenzon aŭ vorton" - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "Laŭtlegi la aktualan vicon." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "Laŭtlegi la aktualan vicon." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "Laŭtlegi la aktualan vicon." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "Laŭtlegi la aktualan vicon." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "Laŭtlegi la aktualan vicon." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "Laŭtlegi la aktualan vicon." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "Brajla (maldekstra mano, invertita dikfingro)" - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "Brajla (dekstra mano, invertita dikfingro)" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "_Rapido:" - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "_Rapido:" - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "Parolado" - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "Parolado" - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Parolado" - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Parolado" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Serĉi antaŭan okazon de la nuna serĉĉeno" - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Elektu voĉlegadan sistemon:" - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "_Rapido:" - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "_Rapido:" - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "Ĝeneralaj voĉ-agordoj" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "baskuligi" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "Angla (dividi/multobligi alternigas la aranĝon)" - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Ekranlegilo enŝaltite." - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "eniris legosignon" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Aldoni legosignon" - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "konservis legosignon" - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "_Mastrumu AI-moduson" - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "tempo relativa je alia tempo" - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "Dato" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Ne anonci kiam viaj amikoj skribas." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Lineo maldekstre" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Lineo dekstre" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Lineo supre" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Lineo malsupre" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Fiksi" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Supre maldekstre" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Malsupre maldekstre" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Kursoropozicio" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "6 punktoj" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "Montrilo" - -#: src/cthulhu/cmdnames.py:696 -#, fuzzy -msgid "Cut Begin" -msgstr "eltondi" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "Linio" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "lasta mesaĝo estis ripetita por %d fojoj" - -#: src/cthulhu/cmdnames.py:711 -#, fuzzy -msgid "Present notification messages list" -msgstr "_Listo pri la ĉeestantaj unuoj..." - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "Montri la antaŭan mesaĝon" - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "Montri la sekvan mesaĝon" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Signara _kodoprezento" - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "vorto" - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "_Sekva" - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "Supre" - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "Malsupre" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Iri al la komenco de la mesaĝo" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Iri al la fino de la linio" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Iri al la sekva objekto" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Iri al la antaŭa objekto" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Malplenigi la dinamikajn vicokapojn" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "_Sekva" - -#: src/cthulhu/cmdnames.py:852 -#, fuzzy -msgid "Display a list of blockquotes" -msgstr "_Ekrano" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "Butono" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Montri fenestrajn butonojn nur per teksto" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Elektobutono" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Elektobutono" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "_Antaŭa" - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "_Ekrano" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Iri al la sekva kombokesto" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "Komenco" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Iri al fino de ujo" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "Montri" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "_Antaŭa" - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "Titoloj" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "_Sekva" - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "Montri" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "_Sekva" - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "_Ekrano" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Grandaj objektoj" - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "_Sekva" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Ligiloj" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "_Sekva" - -#: src/cthulhu/cmdnames.py:1006 -#, fuzzy -msgid "Display a list of lists" -msgstr "Listoj" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Listero" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Listero" - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "Listeroj" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Alklaku la objekton kun navigila fokuso." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "_Antaŭa" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "Paragrafoj" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Radiobutono" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "Radiobutono" - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "Radiobutonoj" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "_Sekva" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "_Antaŭa" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "_Iri al" - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "Tabeloj" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "Movi la elektitajn kapojn sube per unu vico" - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "Tabela ĉelo" - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "Tabela ĉelo" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Iri dekstren unu ĉelon" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "Movi la elektitajn kapojn supre per unu vico" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "Angla (dividi/multobligi alternigas la aranĝon)" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Ŝalti/malŝalti tajpmontrilan navigadon" - -#: src/cthulhu/cmdnames.py:1159 -#, fuzzy -msgid "Enable sticky browse mode" -msgstr "Ŝalti/malŝalti tajpmontrilan navigadon" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Iri al sekva nevizitita ligilo" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Iri al antaŭa nevizitita ligilo" - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "_Vizitita ligilo:" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "_Bluo:" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antikva blanka" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "flavgriza" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "nigra" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blua" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "blua violeta" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "bruna" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadeta blua" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "ĉokolada" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -#, fuzzy -msgctxt "color name" -msgid "cornflower blue" -msgstr "blua" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cejana" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "malhelblua" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "malhela cejana" - -#: src/cthulhu/colornames.py:149 -#, fuzzy -msgctxt "color name" -msgid "dark goldenrod" -msgstr "malhela oranĝkolora" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "malhela griza" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "malhela verda" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "malhela kakia" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "malhela magento" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "malhela olivverda" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "malhela oranĝkolora" - -#: src/cthulhu/colornames.py:184 -#, fuzzy -msgctxt "color name" -msgid "dark orchid" -msgstr "malhela oranĝkolora" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "malhela ruĝa" - -#: src/cthulhu/colornames.py:194 -#, fuzzy -msgctxt "color name" -msgid "dark salmon" -msgstr "malhela salmokolora" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "malhela marverda" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "malhela ardezbluo" - -#: src/cthulhu/colornames.py:209 -#, fuzzy -msgctxt "color name" -msgid "dark slate gray" -msgstr "malhelega griza" - -#: src/cthulhu/colornames.py:214 -#, fuzzy -msgctxt "color name" -msgid "dark turquoise" -msgstr "malhela oranĝkolora" - -#: src/cthulhu/colornames.py:219 -#, fuzzy -msgctxt "color name" -msgid "dark violet" -msgstr "blua violeta" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "profunde rozkolora" - -#: src/cthulhu/colornames.py:229 -#, fuzzy -msgctxt "color name" -msgid "deep sky blue" -msgstr "ĉiela blua #2" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "malklara griza" - -#: src/cthulhu/colornames.py:239 -#, fuzzy -msgctxt "color name" -msgid "dodger blue" -msgstr "blua" - -#: src/cthulhu/colornames.py:244 -#, fuzzy -msgctxt "color name" -msgid "fire brick" -msgstr "Pafĉesigo" - -#: src/cthulhu/colornames.py:249 -#, fuzzy -msgctxt "color name" -msgid "floral white" -msgstr "_Blanko" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "Arbaro" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -#, fuzzy -msgctxt "color name" -msgid "ghost white" -msgstr "_Blanko" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "ora" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "griza" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verda" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "verda flava" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -#, fuzzy -msgctxt "color name" -msgid "hot pink" -msgstr "rozkolora" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "hindia ruĝa" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -#, fuzzy -msgctxt "color name" -msgid "ivory" -msgstr "Eburo" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "kakia" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -#, fuzzy -msgctxt "color name" -msgid "lawn green" -msgstr "_Verdo:" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "helblua" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "bruneta" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "helcejana" - -#: src/cthulhu/colornames.py:364 -#, fuzzy -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "helflava" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "griza" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "helverda" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "rozkolora" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "heloranĝa" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "helverda" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "helblua" - -#: src/cthulhu/colornames.py:399 -#, fuzzy -msgctxt "color name" -msgid "light slate gray" -msgstr "griza" - -#: src/cthulhu/colornames.py:404 -#, fuzzy -msgctxt "color name" -msgid "light steel blue" -msgstr "helblua" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "helflava" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limonverda" - -#: src/cthulhu/colornames.py:419 -#, fuzzy -msgctxt "color name" -msgid "lime green" -msgstr "limonverda" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "nova lineo" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "malva" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -#, fuzzy -msgctxt "color name" -msgid "medium aquamarine" -msgstr "Meza" - -#: src/cthulhu/colornames.py:444 -#, fuzzy -msgctxt "color name" -msgid "medium blue" -msgstr "Meza" - -#: src/cthulhu/colornames.py:449 -#, fuzzy -msgctxt "color name" -msgid "medium orchid" -msgstr "Meza" - -#: src/cthulhu/colornames.py:454 -#, fuzzy -msgctxt "color name" -msgid "medium purple" -msgstr "Meza" - -#: src/cthulhu/colornames.py:459 -#, fuzzy -msgctxt "color name" -msgid "medium sea green" -msgstr "verda" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "blua" - -#: src/cthulhu/colornames.py:469 -#, fuzzy -msgctxt "color name" -msgid "medium spring green" -msgstr "verda" - -#: src/cthulhu/colornames.py:474 -#, fuzzy -msgctxt "color name" -msgid "medium turquoise" -msgstr "Meza" - -#: src/cthulhu/colornames.py:479 -#, fuzzy -msgctxt "color name" -msgid "medium violet red" -msgstr "ruĝa" - -#: src/cthulhu/colornames.py:484 -#, fuzzy -msgctxt "color name" -msgid "midnight blue" -msgstr "Meznokto" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -#, fuzzy -msgctxt "color name" -msgid "navajo white" -msgstr "_Blanko" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "marblua" - -#: src/cthulhu/colornames.py:514 -#, fuzzy -msgctxt "color name" -msgid "old lace" -msgstr "Malnova tjurka" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oranĝkolora" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "ruĝ-oranĝa" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "pala verda" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "pala violruĝa" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rozkolora" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "pulvorblua" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purpura" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "ruĝa" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rozbruna" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "reĝa bluo" - -#: src/cthulhu/colornames.py:614 -#, fuzzy -msgctxt "color name" -msgid "saddle brown" -msgstr "bruna" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -#, fuzzy -msgctxt "color name" -msgid "sandy brown" -msgstr "bruna" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "verda" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "arĝenta" - -#: src/cthulhu/colornames.py:649 -#, fuzzy -msgctxt "color name" -msgid "sky blue" -msgstr "ĉiela blua #2" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "_Bluo:" - -#: src/cthulhu/colornames.py:659 -#, fuzzy -msgctxt "color name" -msgid "slate gray" -msgstr "griza" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "negâ" - -#: src/cthulhu/colornames.py:669 -#, fuzzy -msgctxt "color name" -msgid "spring green" -msgstr "_Verdo:" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "Ŝtalo" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "btn" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomato" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -#, fuzzy -msgctxt "color name" -msgid "violet" -msgstr "blua violeta" - -#: src/cthulhu/colornames.py:709 -#, fuzzy -msgctxt "color name" -msgid "wheat" -msgstr "Tritiko" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "blanka" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "_Blanko" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "flava" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "verda flava" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktivigi" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punkto _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punkto _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Nuligi" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Salti al" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "B_one" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Bildsimbolo" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Neniu" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Literumado" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Anonci kiam _amikoj skribas" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Voĉlegi mesaĝojn de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Ĉiuj ka_anloj" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Voĉlegi la nomon de la babilejo" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Ebligu aranĝan reĝimon por enhavo" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "duobla alklako" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triobla alklako" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Defaŭlta sintezilo" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Aktuala ĉeno" - -#: src/cthulhu/guilabels.py:227 -#, fuzzy -msgid "Replacement String" -msgstr "ĉeno ne trovita" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "N_una loko" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Serĉagordoj" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Komando" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Klavkombinoj" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Defaŭlte" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Reĝimo" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Agoj" - -#: src/cthulhu/guilabels.py:296 -#, fuzzy -msgid "Braille Bindings" -msgstr "Klavkombinoj" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Preferaĵoj" - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "Dato kaj horo" - -#: src/cthulhu/guilabels.py:310 -#, fuzzy -msgid "Mouse review" -msgstr "Muso" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "navigado" - -#: src/cthulhu/guilabels.py:321 -#, fuzzy -msgid "Object details" -msgstr "Objektdetaloj" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Sendepende" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "Recenzo" - -#: src/cthulhu/guilabels.py:341 -#, fuzzy -msgid "Speech and verbosity" -msgstr "Parolado" - -#: src/cthulhu/guilabels.py:352 -#, fuzzy -msgid "Flat review contents" -msgstr "_Enhavoj" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modifite" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Labortablo" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Sciigoj" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Ricevita" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Atentigo" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Ekranligilaj agordoj por %s" - -#: src/cthulhu/guilabels.py:396 -#, fuzzy -msgid "Mark in braille" -msgstr "Brajlo" - -#: src/cthulhu/guilabels.py:408 -#, fuzzy -msgid "Present Unless" -msgstr "Ĉeestantaj unuoj" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Diri" - -#: src/cthulhu/guilabels.py:422 -#, fuzzy -msgid "Save Profile As Conflict" -msgstr "Konservi koloran _profilon" - -#: src/cthulhu/guilabels.py:429 -#, fuzzy -msgid "User Profile Conflict!" -msgstr "Uzanto:" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profilo %s jam ekzistas.\n" -"Ĉu daŭre ĝisdatigi la ekzistantan profilon kun ĉi tiuj novaj ŝanĝoj?" - -#: src/cthulhu/guilabels.py:446 -#, fuzzy -msgid "Load user profile" -msgstr "Ŝar_gi" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Vi estas ŝanĝonta la aktivan profilon. Se vi\n" -"ĵus faris ŝanĝojn en viaj preferoj, ili perdiĝos\n" -"dum profilŝarĝo.\n" -"\n" -"Ĉu daŭre ŝargi profilon forĵeti antaŭajn ŝanĝojn?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Konservi profilon kiel" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profilnomo:" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "Fo_rigi" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Ĉiuj" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplikaĵo" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Fenestro" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Neniu" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Kelkaj" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Plej multaj" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Linio" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Frazo" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Butono" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Elektobutono" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Alklakebla" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Elektobutono" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Priskribo" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Titolo" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Interna eraro." - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Bildo" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etikedo" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Registrita marko" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivelo" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Ligilo" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Listo" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Listero" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekto" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragrafo" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radiobutono" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rolo" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Elektita ero" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stato" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Teksto" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valoro" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Butonoj" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Elektobutono" - -#: src/cthulhu/guilabels.py:706 -#, fuzzy -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Tabeloj" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -#, fuzzy -msgctxt "structural navigation" -msgid "Entries" -msgstr "_Protokoleroj" - -#: src/cthulhu/guilabels.py:721 -#, fuzzy -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Montri kampojn" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Titoloj" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Interna eraro." - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Bildoj" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "NIVELO %d" - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Registrita marko" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Grandaj objektoj" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Ligiloj" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listoj" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Listeroj" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragrafoj" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radiobutonoj" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabeloj" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Ligiloj" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "vizitite" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Paĝa foliumado" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, fuzzy, python-format -msgid "%s default voice" -msgstr "Implicita (%s)" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Defaŭlte" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Ligilo" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistemo" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Majuskle" - -#: src/cthulhu/guilabels.py:852 -#, fuzzy -msgid "Speech Dispatcher" -msgstr "Parolado" - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Enteksta literumada kontrolo" - -#: src/cthulhu/guilabels.py:862 -#, fuzzy -msgid "Spell _error" -msgstr "literumado" - -#: src/cthulhu/guilabels.py:869 -#, fuzzy -msgid "Spell _suggestion" -msgstr "literumado" - -#: src/cthulhu/guilabels.py:874 -#, fuzzy -msgid "Present _context of error" -msgstr "Ĉeestantaj unuoj" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -#, fuzzy -msgid "Announce cell _header" -msgstr "Kapo" - -#: src/cthulhu/guilabels.py:896 -#, fuzzy -msgid "Table Navigation" -msgstr "_Tabelo…" - -#: src/cthulhu/guilabels.py:900 -#, fuzzy -msgid "Skip _blank cells" -msgstr "malplene" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "Ĉ_elo…" - -#: src/cthulhu/guilabels.py:909 -#, fuzzy -msgid "Speak _cell coordinates" -msgstr "Eraraj mapaj koordinatoj." - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -#, fuzzy -msgid "Attribute Name" -msgstr "Atribui mesaĝon" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "navigado" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "Strukturoj por kosmoŝipo" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -#, fuzzy -msgid "Brie_f" -msgstr "_F#" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d atentigo" -msgstr[1] "%d atentigoj" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Majuskliga klavo" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Stirklavo" - -#: src/cthulhu/keynames.py:60 -#, fuzzy -msgid "left shift" -msgstr "Maldekstra Shift" - -#: src/cthulhu/keynames.py:64 -#, fuzzy -msgid "left alt" -msgstr "Maldekstra Alt" - -#: src/cthulhu/keynames.py:68 -#, fuzzy -msgid "left control" -msgstr "Stirklavo" - -#: src/cthulhu/keynames.py:72 -#, fuzzy -msgid "right shift" -msgstr "Dekstra Shift" - -#: src/cthulhu/keynames.py:76 -#, fuzzy -msgid "right alt" -msgstr "Dekstra Alt" - -#: src/cthulhu/keynames.py:80 -#, fuzzy -msgid "right control" -msgstr "Stirklavo" - -#: src/cthulhu/keynames.py:84 -#, fuzzy -msgid "left meta" -msgstr "Maldekstra Ctrl kiel Meta" - -#: src/cthulhu/keynames.py:88 -#, fuzzy -msgid "right meta" -msgstr "dekstre" - -#: src/cthulhu/keynames.py:92 -#, fuzzy -msgid "num lock" -msgstr "Num Lock" - -#: src/cthulhu/keynames.py:96 -#, fuzzy -msgid "caps lock" -msgstr "Caps Lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "Caps Lock alternigas Shift Lock (influante ĉiujn klavojn)" - -#: src/cthulhu/keynames.py:105 -#, fuzzy -msgid "scroll lock" -msgstr "Ruluma Baskulo" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -#, fuzzy -msgid "page up" -msgstr "Paĝa _agordo…" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -#, fuzzy -msgid "page down" -msgstr "malsupre" - -#: src/cthulhu/keynames.py:145 -#, fuzzy -msgid "left tab" -msgstr "langeto" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "Igi Caps Lock kroman Retroklavon" - -#: src/cthulhu/keynames.py:157 -#, fuzzy -msgid "return" -msgstr "Por enŝalti premu la enigklavon." - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "Enigu URLon ĉi tie" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "supre" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "malsupre" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "maldekstre" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "dekstre" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "Maldekstra superklavo" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "Dekstra superklavo" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menuo" - -#: src/cthulhu/keynames.py:209 -#, fuzzy -msgid "Alt Gr" -msgstr "gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "helpo" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -#, fuzzy -msgid "mode switch" -msgstr "ŝaltilo" - -#: src/cthulhu/keynames.py:225 -#, fuzzy -msgid "escape" -msgstr "Forkuro" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "enigi" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "forigi" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "hejmo" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "fino" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "komenco" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "cirkumflekso" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ringo" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "oblikvo" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Enmeti" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -#, fuzzy -msgid "Caps_Lock" -msgstr "Caps Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Stirklavo" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Majuskliga klavo" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "dike %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "kursive %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "kursive %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "Estas neeble legi la skripton '%s'." - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "Estas neeble legi la skripton '%s'." - -#: src/cthulhu/mathsymbols.py:1184 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s — %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "duoble" - -#: src/cthulhu/mathsymbols.py:1204 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "dike %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s — %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "dike %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "kursive %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Egallarĝa teksto" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s — %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "" -"Por malpliigi premu maldekstran sagon, por pliigi premu dekstran sagon. Por " -"iri al minimumo premu hejmon, kaj por maksimumo premu finon." - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "Sago" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "dekstra sago" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "malsupren sago" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "maldekstra dekstra sago" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "supren malsupren sago" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "nordokcidenta sago" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "nordorienta sago" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "sudorienta sago" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "supren sago de stango" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "dekstra sago de stango" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "maldekstra duobla sago" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "supren duobla sago" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dekstra duobla sago" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "malsupren duobla sago" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "Plenigi (maldekstre de dekstre)" - -#: src/cthulhu/mathsymbols.py:1321 -#, fuzzy -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "Uzu supren kaj malsupren por elekti eron." - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "Sago" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "Dekstra Ctrl+dekstra Shift" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "Malpli ol" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "pli granda ol" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "cirkumflekso" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punkto" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "%s kun vertikala linio" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "_Horizontale:" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "por ĉiuj" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -#, fuzzy -msgctxt "math symbol" -msgid "there exists" -msgstr "ekzistas" - -#: src/cthulhu/mathsymbols.py:1389 -#, fuzzy -msgctxt "math symbol" -msgid "there does not exist" -msgstr "ne ekzistas" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "malplene" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla simbolo" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -#, fuzzy -msgctxt "math symbol" -msgid "small element of" -msgstr "Eta mirindaĵo" - -#: src/cthulhu/mathsymbols.py:1410 -#, fuzzy -msgctxt "math symbol" -msgid "contains as a member" -msgstr "Membro" - -#: src/cthulhu/mathsymbols.py:1413 -#, fuzzy -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "ne entenas" - -#: src/cthulhu/mathsymbols.py:1416 -#, fuzzy -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "Membro" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "fino" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produkto" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "kunprodukto" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sum" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus aŭ plus" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "punkto" - -#: src/cthulhu/mathsymbols.py:1440 -#, fuzzy -msgctxt "math symbol" -msgid "division slash" -msgstr "oblikvo" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "Servil-operatoro: %s" - -#: src/cthulhu/mathsymbols.py:1449 -#, fuzzy -msgctxt "math symbol" -msgid "ring operator" -msgstr "ringo" - -#: src/cthulhu/mathsymbols.py:1452 -#, fuzzy -msgctxt "math symbol" -msgid "bullet operator" -msgstr "Mesaĝo el operatoro de la gastiga komputilo" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "kvadrata kuniĝo" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "kvara" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "dekstra angula krampo" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "Angulo:" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "mezurita per" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "Angulo:" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -#, fuzzy -msgctxt "math symbol" -msgid "does not divide" -msgstr "ne komencas per" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "logika neo" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "logika neo" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersekciĝo" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "kuniĝo" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "duobla integralo" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "triobla integralo" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "surfaca integralo" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -#, fuzzy -msgctxt "math symbol" -msgid "therefore" -msgstr "tial" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "ĉar" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "proporcio" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "punkto" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tildo" - -#: src/cthulhu/mathsymbols.py:1560 -#, fuzzy -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "a tildo" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "renversita maldiligenta S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -#, fuzzy -msgctxt "math symbol" -msgid "wreath product" -msgstr "produkto" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "a tildo" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "a tildo" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1587 -#, fuzzy -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "triobla alklako" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "_Optimigi (Diferenco)" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "alproksimiĝas al la limo" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1623 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1626 -#, fuzzy -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "egalsigno" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "egalsigno" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "respondas al" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "taksoj" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "triangula bulmarko" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "stelo" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delto egala al" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "egala al per difino" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "mezurita per" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identa al" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "ne identa al" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "estas malpli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "estas pli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "estas malpli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "estas pli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "estas malpli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "estas pli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "pli malgranda ol" - -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "pli granda ol" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "inter" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -#, fuzzy -msgctxt "math symbol" -msgid "not less than" -msgstr "pli malgranda ol" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "pli granda ol" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "estas malpli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "estas pli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "estas malpli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "estas pli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "malpli ol aŭ pli granda ol" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "pli granda ol aŭ malpli ol" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "ne entenas" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ne entenas" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "super" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "kuniĝo kun punkto" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "kvadrata intersekco" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadrata originalo de" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1815 -#, fuzzy -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "kvadrata kuniĝo" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadrata kuniĝo" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -#, fuzzy -msgctxt "math symbol" -msgid "circled plus" -msgstr "rondigita punkto" - -#: src/cthulhu/mathsymbols.py:1827 -#, fuzzy -msgctxt "math symbol" -msgid "circled minus" -msgstr "rondigita punkto" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -#, fuzzy -msgctxt "math symbol" -msgid "circled times" -msgstr "rondigita punkto" - -#: src/cthulhu/mathsymbols.py:1833 -#, fuzzy -msgctxt "math symbol" -msgid "circled division slash" -msgstr "rondigita punkto" - -#: src/cthulhu/mathsymbols.py:1836 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "rondigita punkto" - -#: src/cthulhu/mathsymbols.py:1839 -#, fuzzy -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "rondigita punkto" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "cirkulita asterisko operatoro" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "egalsigno" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "haltostreko" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "aldona tempo ĉiuj" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "kvadrata punkto operatoro" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "_Malsupre" - -#: src/cthulhu/mathsymbols.py:1872 -#, fuzzy -msgctxt "math symbol" -msgid "up tack" -msgstr "_Supre" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "vere" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -#, fuzzy -msgctxt "math symbol" -msgid "does not prove" -msgstr "ne ekzistas" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "vere" - -#: src/cthulhu/mathsymbols.py:1899 -#, fuzzy -msgctxt "math symbol" -msgid "does not force" -msgstr "ne ekzistas" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -#, fuzzy -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "formiĝanta" - -#: src/cthulhu/mathsymbols.py:1908 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "formiĝanta" - -#: src/cthulhu/mathsymbols.py:1911 -#, fuzzy -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" -"normal\n" -"normal " - -#: src/cthulhu/mathsymbols.py:1914 -#, fuzzy -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "entenas" - -#: src/cthulhu/mathsymbols.py:1917 -#, fuzzy -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "originalo de" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "_Neniu bildo" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "nek" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "dekstra angula krampo" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "dekstra triangulo" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "diamanta funkciigisto" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "punkta operatoro" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "stelo" - -#: src/cthulhu/mathsymbols.py:1974 -#, fuzzy -msgctxt "math symbol" -msgid "division times" -msgstr "aldona tempo ĉiuj" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -#, fuzzy -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "produkto" - -#: src/cthulhu/mathsymbols.py:1989 -#, fuzzy -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "produkto" - -#: src/cthulhu/mathsymbols.py:1992 -#, fuzzy -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "a tildo" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "logika neo" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "logika neo" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "duoble" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "duoble" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "duobla intersekco" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "duobla kuniĝo" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "forko" - -#: src/cthulhu/mathsymbols.py:2016 -#, fuzzy -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "pli malgranda ol" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "pli granda ol" - -#: src/cthulhu/mathsymbols.py:2025 -#, fuzzy -msgctxt "math symbol" -msgid "very much less than" -msgstr "pli malgranda ol" - -#: src/cthulhu/mathsymbols.py:2028 -#, fuzzy -msgctxt "math symbol" -msgid "very much greater than" -msgstr "pli granda ol" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "estas malpli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "estas malpli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "estas malpli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "estas pli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:2043 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2046 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2049 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2052 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2058 -#, fuzzy -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2064 -#, fuzzy -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "estas malpli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "estas pli granda ol aŭ egale al" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -#, fuzzy -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" -"normal\n" -"normal " - -#: src/cthulhu/mathsymbols.py:2082 -#, fuzzy -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "ne entenas" - -#: src/cthulhu/mathsymbols.py:2085 -#, fuzzy -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "ne egala al" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertikala elipso" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "mezlinia horizontala elipso" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "elemento de kun punkto supre" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -#, fuzzy -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "nigra mezgranda kvadrato" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -#, fuzzy -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "entenas" - -#: src/cthulhu/mathsymbols.py:2142 -#, fuzzy -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "malgrandaj ĉapoj" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "maldekstra plafono" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "dekstra plafono" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "maldekstra planko" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "dekstra planko" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "supra krampo" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "malsupra krampo" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "maldekstra angula krampo" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "dekstra angula krampo" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "rondigita punkto" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "kuniĝo kun punkto" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "kuniĝo kun pluso" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "kvadrata intersekco" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "kvadrata kuniĝo" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "nigra kvadrato" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "blanka kvadrato" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "nigra diamanto" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "blanka cirklo" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "nigra cirklo" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "blanka kuglo" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "nigra mezgranda kvadrato" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s kun substreko" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s kun oblikvo" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s kun vertikala linio" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplikaĵo" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "malplene" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "dike" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "eniris legosignon" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "konservis legosignon" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "ne eblas konservi legosignon" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Neniuj legosignoj trovitaj." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Legomarko ne trovita." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Preterpasa reĝimo ebligita." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "piktogramo" - -#: src/cthulhu/messages.py:117 -#, fuzzy -msgid "Capitalization style set to icon." -msgstr "BONE. Normala stilo estas ebligita." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "neniu" - -#: src/cthulhu/messages.py:137 -#, fuzzy -msgid "Capitalization style set to none." -msgstr "BONE. Normala stilo estas ebligita." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "literumado" - -#: src/cthulhu/messages.py:157 -#, fuzzy -msgid "Capitalization style set to spell." -msgstr "BONE. Normala stilo estas ebligita." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "La aplikaĵo kontrolas la signon." - -#: src/cthulhu/messages.py:170 -#, fuzzy -msgid "Cthulhu is controlling the caret." -msgstr "La aplikaĵo kontrolas la signon." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Ĉelo %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s elektita" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s neelektita" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Malhelpi uzon de opcio" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Devigi uzon de opcio" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCIO" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Nedevigataj argumentoj" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Uzo: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Ŝargi profilon" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Ne eblis ŝargi profilon: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Ne eblis aktivigi la agord-administrilon. Elirante." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOMO" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DOSIERUJO" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versio de ĉi tiu aplikaĵo" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Montri ĉi tiun helpmesaĝon kaj eliri" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "DOSIERO" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Raporti cimojn al https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Tranĉis elekton al tondujo." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "eltondi" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Kopiis elekton al tondujo." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopiita" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Algluis enhavon de tondujo." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Ne anonci kiam viaj amikoj skribas." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anonci kiam viaj amikoj skribas." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Mesaĝo de babilejo %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nova babileja langeto %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Ne voĉlegi la nomon de la babilejo." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "voĉlegi la nomon de la babilejo." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "Komenco" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "Marki la elektitajn mesaĝojn por forigado" - -#: src/cthulhu/messages.py:452 -#, fuzzy -msgctxt "content" -msgid "insertion start" -msgstr "je la komenco" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "fino" - -#: src/cthulhu/messages.py:462 -#, fuzzy -msgctxt "content" -msgid "highlight start" -msgstr "Komenco" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "Emfazi _citojn kun" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "fino" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Fino de ujo." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "Sendi atendajn erojn en ĉiuj kontoj" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Defaŭlta butono estas %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Defaŭlta butono estas %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "Defaŭlta butono estas %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "subskribo %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "superskribo %s" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "Fermu fenestron" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "tuta dokumento elektita" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "tuta dokumento elektita" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokumento elektita al la pozicio de la kursoro" - -#: src/cthulhu/messages.py:566 -#, fuzzy -msgid "document unselected to cursor position" -msgstr "Kursoropozicio" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "malplene" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Neniu dosiero trovita." - -#: src/cthulhu/messages.py:611 -#, fuzzy -msgid "Appended contents to clipboard." -msgstr "_Enhavoj" - -#: src/cthulhu/messages.py:619 -#, fuzzy -msgid "Copied contents to clipboard." -msgstr "_Enhavoj" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "Recenzo" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "Recenzo" - -#: src/cthulhu/messages.py:641 -#, fuzzy -msgid "Leaving flat review." -msgstr "Recenzo" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -#, fuzzy -msgid "Flat review unrestricted" -msgstr "Recenzo" - -#: src/cthulhu/messages.py:661 -#, fuzzy -msgid "has formula" -msgstr "Havas ambasadon" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "Malfermas dialogon por elekti la dosierujon al kiu vi volas iri" - -#: src/cthulhu/messages.py:669 -#, fuzzy -msgid "opens grid" -msgstr "_Krado" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "menuo" - -#: src/cthulhu/messages.py:683 -#, fuzzy -msgid "opens tree" -msgstr "Arbeca vido" - -#: src/cthulhu/messages.py:690 -#, fuzzy -msgid "image map link" -msgstr "_Neniu bildo" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "La nova klavo estas: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -#, fuzzy -msgid "The keybinding has been removed." -msgstr "Dosiero “%s” estas forigita." - -#: src/cthulhu/messages.py:721 -#, fuzzy -msgid "enter new key" -msgstr "Enigu novan pasvorton por la atestila datumbazo" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "ŝlosilo" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "Difini daton" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Neniu" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "Neniu" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "klavo kaj vorto" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "klavo kaj vorto" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "frazo" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "Frazo" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "vorto" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "vorto" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "vorto kaj frazo" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "vorto kaj frazo" - -#: src/cthulhu/messages.py:889 -#, fuzzy, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "['attachment','attaching','attached','enclosed','aldonaĵo','aldonis','aldonas','aldonos','aldoni','aldonus']" - -#: src/cthulhu/messages.py:897 -#, fuzzy -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "Simbolo" - -#: src/cthulhu/messages.py:905 -#, fuzzy -msgctxt "math enclosure" -msgid "a box" -msgstr "_Poŝtujo:" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "Cirklo" - -#: src/cthulhu/messages.py:921 -#, fuzzy -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "tro longa" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -#, fuzzy -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "Grupigi laŭ _ujo" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "_Horizontale:" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "_Vertikale:" - -#: src/cthulhu/messages.py:961 -#, fuzzy -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "Lineo malsupre" - -#: src/cthulhu/messages.py:969 -#, fuzzy -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "Lineo supre" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "Sago" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Linio" - -#: src/cthulhu/messages.py:993 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "Lineo maldekstre" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "Lineo dekstre" - -#: src/cthulhu/messages.py:1009 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "Supre" - -#: src/cthulhu/messages.py:1017 -#, fuzzy -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "Angulo:" - -#: src/cthulhu/messages.py:1026 -#, fuzzy -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "Simbolo" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "kaj" - -#: src/cthulhu/messages.py:1044 -#, fuzzy -msgid "fraction start" -msgstr "je la komenco" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "super" - -#: src/cthulhu/messages.py:1065 -#, fuzzy -msgid "fraction end" -msgstr "fino" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "kvadrata kuniĝo" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "je la komenco" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "fino" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "Malalta skribo" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "alta skribo" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "Malalta skribo" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "alta skribo" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "malalta skribo" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "_Tabelo…" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "fino" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Elŝaltite" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Enŝaltite" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1249 -#, fuzzy -msgctxt "role" -msgid "leaving complementary content." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "navigado" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "Piktogrampanelo" - -#: src/cthulhu/messages.py:1292 -#, fuzzy -msgid "leaving table." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "konkludo" - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr " Ekzemplo pri interbatalo 1" - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "glosaro" - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "indekso" - -#: src/cthulhu/messages.py:1416 -#, fuzzy -msgctxt "role" -msgid "leaving introduction." -msgstr "enkonduko" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "_Tabelo…" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -#, fuzzy -msgid "Exiting learn mode." -msgstr "Ne eblis aktivigi la agord-administrilon. Elirante." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ligilo" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "sama paĝo" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "sama retejo" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "malsama retejo" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s ligas al %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s-ligilo" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "_Vizitita ligilo:" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "Nivelo: %s.
" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -#, fuzzy -msgid "no live message saved" -msgstr "Konservite" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Ne trovite" - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "Serĉi sekvan okazon de la nuna serĉĉeno" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "elŝaltite" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "enŝaltite" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "misliterumite" - -#: src/cthulhu/messages.py:1682 -#, fuzzy, python-format -msgid "Misspelled word: %s" -msgstr "Malatenti misliterumitan vorton" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Kunteksto estas %s" - -#: src/cthulhu/messages.py:1702 -#, fuzzy -msgid "Browse mode" -msgstr "_Foliumu..." - -#: src/cthulhu/messages.py:1717 -#, fuzzy -msgid "Focus mode" -msgstr "Reĝimo" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -#, fuzzy -msgid "Focus mode is sticky." -msgstr "Reĝimo" - -#: src/cthulhu/messages.py:1758 -#, fuzzy -msgid "Browse mode is sticky." -msgstr "_Foliumu..." - -#: src/cthulhu/messages.py:1771 -#, fuzzy -msgid "Layout mode." -msgstr "Reĝimo" - -#: src/cthulhu/messages.py:1785 -#, fuzzy -msgid "Object mode." -msgstr "Objekto" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Musmontrilo" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Muso" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Muso" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -#, fuzzy -msgid "No children." -msgstr "Serĉante idojn de kolekto…" - -#: src/cthulhu/messages.py:1822 -#, fuzzy -msgid "No next." -msgstr "_Sekva" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "Neniu respondo aŭ gepatro" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "_Antaŭa" - -#: src/cthulhu/messages.py:1837 -#, fuzzy -msgid "Simplified navigation enabled." -msgstr "Simpligite" - -#: src/cthulhu/messages.py:1842 -#, fuzzy -msgid "Simplified navigation disabled." -msgstr "Simpligite" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "NIVELO %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Trovis rendevuon en la kalendaro “%s”" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Sen fokuso" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Neniu aplikaĵo havas fokuson." - -#: src/cthulhu/messages.py:1872 -#, fuzzy -msgid "No more blockquotes." -msgstr "Pli…" - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "Pli…" - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "Elektobutono" - -#: src/cthulhu/messages.py:1888 -#, fuzzy -msgid "No more large objects." -msgstr "Grandaj objektoj" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Pli…" - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "Pli…" - -#: src/cthulhu/messages.py:1903 -#, fuzzy -msgid "No more entries." -msgstr "_Protokoleroj" - -#: src/cthulhu/messages.py:1908 -#, fuzzy -msgid "No more form fields." -msgstr "Montri kampojn" - -#: src/cthulhu/messages.py:1913 -#, fuzzy -msgid "No more headings." -msgstr "Titoloj" - -#: src/cthulhu/messages.py:1919 -#, fuzzy, python-format -msgid "No more headings at level %d." -msgstr "NIVELO %d" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "Pli…" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "Pli…" - -#: src/cthulhu/messages.py:1935 -#, fuzzy -msgid "No landmark found." -msgstr "Ne trovite" - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "Ligiloj" - -#: src/cthulhu/messages.py:1945 -#, fuzzy -msgid "No more lists." -msgstr "Pli…" - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "Listeroj" - -#: src/cthulhu/messages.py:1957 -#, fuzzy -msgid "No more live regions." -msgstr "Pli…" - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "Paragrafoj" - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "Radiobutonoj" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "Pli…" - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "Tabeloj" - -#: src/cthulhu/messages.py:1982 -#, fuzzy -msgid "No more unvisited links." -msgstr "Ligiloj" - -#: src/cthulhu/messages.py:1987 -#, fuzzy -msgid "No more visited links." -msgstr "vizitite" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Neniu teksto estas elektita." - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "_Ligilo…" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Atentigo" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Malsupre" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Supre" - -#: src/cthulhu/messages.py:2013 -#, fuzzy -msgid "No notification messages" -msgstr "Atentigo" - -#: src/cthulhu/messages.py:2020 -#, fuzzy -msgctxt "number style" -msgid "digits" -msgstr "Ciferklavaro ĉiam enigas ciferojn (kiel en macOS)" - -#: src/cthulhu/messages.py:2027 -#, fuzzy -msgid "Speak numbers as digits." -msgstr "Voĉlegi _numerojn kiel ciferoj" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "vortoj" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Voĉlegi numerojn kiel vortoj." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "elŝaltite" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "enŝaltite" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Ŝarĝante. Bonvole atendu." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Ŝarĝado finis." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Ŝarĝado de %s finis." - -#: src/cthulhu/messages.py:2071 -#, fuzzy, python-format -msgid "Page has %s." -msgstr "“%s” havas nevalidan strukturon" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -#, fuzzy -msgid "page selected to cursor position" -msgstr "Kursoropozicio" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -#, fuzzy -msgid "page unselected to cursor position" -msgstr "Kursoropozicio" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, fuzzy, python-format -msgid "Profile set to %s." -msgstr "%s estas agordita je 'for' moduso." - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "Profiloj" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Plenumskalo %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Ĉiuj" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "La apriora nivelo de lerteco por IA estas agordita je '%s'." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Plej multe" - -#: src/cthulhu/messages.py:2175 -#, fuzzy -msgid "Punctuation level set to most." -msgstr "La apriora nivelo de lerteco por IA estas agordita je '%s'." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Neniu" - -#: src/cthulhu/messages.py:2187 -#, fuzzy -msgid "Punctuation level set to none." -msgstr "La apriora nivelo de lerteco por IA estas agordita je '%s'." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Iom" - -#: src/cthulhu/messages.py:2199 -#, fuzzy -msgid "Punctuation level set to some." -msgstr "La apriora nivelo de lerteco por IA estas agordita je '%s'." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Serĉante." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Serĉado finis." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Ekranlegilo Orko" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Elektita teksto estas: %s" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "Forigita" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "_Elekto" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "neelektite" - -#: src/cthulhu/messages.py:2244 -#, fuzzy, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Lokiĝo: (%d, %d) [%d]" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -#, fuzzy -msgid "Speech disabled." -msgstr "Elŝaltite" - -#: src/cthulhu/messages.py:2258 -#, fuzzy -msgid "Speech enabled." -msgstr "Enŝaltite" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "pli rapide." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "pli malrapide." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "pli alte." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "pli malalte." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "pli laŭte." - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "pli rapide." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Rapido:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "_Sonforteco:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Parolado" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Parolado" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Neniuj serviloj disponeblas.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Neniuj voĉoj disponeblas.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Enŝaltite" - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "ne eblas konservi legosignon" - -#: src/cthulhu/messages.py:2310 -#, fuzzy -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "_Nivelo:" - -#: src/cthulhu/messages.py:2317 -#, fuzzy -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "_Nivelo:" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " punkto punkto punkto" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Preterpasa reĝimo ebligita." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -#, fuzzy -msgid "Speech is unavailable." -msgstr "Parolado" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Ne trovite" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "Montri la statbreton" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "ĉeno ne trovita" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -#, fuzzy -msgid "Structural navigation keys on." -msgstr "Strukturoj por kosmoŝipo" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Ne trovite" - -#: src/cthulhu/messages.py:2380 -#, fuzzy, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Movi elektitajn kolumn-nomojn supren per unu vico" - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "_Tabelo…" - -#: src/cthulhu/messages.py:2389 -#, fuzzy -msgid "Speak cell" -msgstr "Ĉ_elo…" - -#: src/cthulhu/messages.py:2394 -#, fuzzy -msgid "Speak row" -msgstr "_Vico" - -#: src/cthulhu/messages.py:2399 -#, fuzzy -msgid "Non-uniform" -msgstr "neniu kongruo" - -#: src/cthulhu/messages.py:2404 -#, fuzzy -msgid "Not in a table." -msgstr "_Tabelo…" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "Kolumnoj sur ĉiu vico" - -#: src/cthulhu/messages.py:2412 -#, fuzzy -msgid "Rows reordered" -msgstr " Vicoj " - -#: src/cthulhu/messages.py:2416 -#, fuzzy, python-format -msgid "column %d" -msgstr "Kolumno" - -#: src/cthulhu/messages.py:2420 -#, fuzzy, python-format -msgid "column %(index)d of %(total)d" -msgstr "Enspezo: %d Elspezo: %d" - -#: src/cthulhu/messages.py:2425 -#, fuzzy -msgid "Bottom of column." -msgstr "Kolumno" - -#: src/cthulhu/messages.py:2430 -#, fuzzy -msgid "Top of column." -msgstr "Kolumno" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "Aranĝi kolumno_jn…" - -#: src/cthulhu/messages.py:2442 -#, fuzzy, python-format -msgid "Columns %s through %s selected" -msgstr "%s tra %s asignis taskon al vi:" - -#: src/cthulhu/messages.py:2449 -#, fuzzy, python-format -msgid "Columns %s through %s unselected" -msgstr "%s tra %s asignis taskon al vi:" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "Aranĝi kolumno_jn…" - -#: src/cthulhu/messages.py:2458 -#, fuzzy, python-format -msgid "row %d" -msgstr "_Vico" - -#: src/cthulhu/messages.py:2462 -#, fuzzy, python-format -msgid "row %(index)d of %(total)d" -msgstr "Enspezo: %d Elspezo: %d" - -#: src/cthulhu/messages.py:2467 -#, fuzzy -msgid "Beginning of row." -msgstr "Iri al la komenco de la mesaĝo" - -#: src/cthulhu/messages.py:2472 -#, fuzzy -msgid "End of row." -msgstr "fino" - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "Forigita" - -#: src/cthulhu/messages.py:2480 -#, fuzzy -msgid "Last row deleted." -msgstr "_Lasta:" - -#: src/cthulhu/messages.py:2484 -#, fuzzy -msgid "Row inserted." -msgstr "_Vico" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "Vico" - -#: src/cthulhu/messages.py:2501 -#, fuzzy, python-format -msgid "Rows %s through %s selected" -msgstr "%s tra %s asignis taskon al vi:" - -#: src/cthulhu/messages.py:2508 -#, fuzzy, python-format -msgid "Rows %s through %s unselected" -msgstr "%s tra %s nuligis la sekvan kunsidon:" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "Vica am_plekso:" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "elektite" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "neelektite" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "Hodiaŭ %H:%M" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unikodo %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "malfari" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "refari" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -#, fuzzy -msgid "white space" -msgstr "spaco" - -#: src/cthulhu/messages.py:2562 -#, fuzzy -msgid "Wrapping to bottom." -msgstr "Malsupre" - -#: src/cthulhu/messages.py:2568 -#, fuzzy -msgid "Wrapping to top." -msgstr "Supre" - -#: src/cthulhu/messages.py:2573 -#, fuzzy -msgid "0 items" -msgstr "{0}" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Ĉelo ampleksas %d vicon" -msgstr[1] "Ĉelo ampleksas %d vicojn" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "Kolumno" -msgstr[1] "Kolumnoj sur ĉiu vico" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, fuzzy, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "tro longa" -msgstr[1] "tro longa" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialogo)" -msgstr[1] "(%d dialogoj)" - -#: src/cthulhu/messages.py:2624 -#, fuzzy, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "(%d dialogo)" -msgstr[1] "(%d dialogoj)" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, fuzzy, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "trovis %d elementon" -msgstr[1] "Neniu dosiero trovita." - -#: src/cthulhu/messages.py:2640 -#, fuzzy, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "formularo" -msgstr[1] "%d × %d" - -#: src/cthulhu/messages.py:2647 -#, fuzzy, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "Titolo" -msgstr[1] "Titoloj" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elemento" -msgstr[1] "%d elementoj" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d × %d" -msgstr[1] "%d × %d" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "trovis %d elementon" -msgstr[1] "trovis %d elementojn" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Forlaso de loka ludo estas la fino de la ludo mem!" -msgstr[1] "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "_Forigi la notoliston" -msgstr[1] "Forlaso de loka ludo estas la fino de la ludo mem!" - -#: src/cthulhu/messages.py:2688 -#, fuzzy -msgid "List of unknown size" -msgstr "_Grando:" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d elemento" -msgstr[1] "%d elementoj" - -#: src/cthulhu/messages.py:2700 -#, fuzzy -msgid "Feed of unknown size" -msgstr "_Grando:" - -#: src/cthulhu/messages.py:2704 -#, fuzzy, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "%d × %d" -msgstr[1] "%d × %d" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Priskribolisto" -msgstr[1] "Priskribolisto" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "_Valoro:" -msgstr[1] "Valoroj" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, fuzzy, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "Kolumno" -msgstr[1] "Kolumnoj sur ĉiu vico" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d mesaĝo.\n" -msgstr[1] "%d mesaĝoj.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d elcento." -msgstr[1] "%d elcentoj." - -#: src/cthulhu/messages.py:2764 -#, fuzzy, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d elcento." -msgstr[1] "%d elcento." - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d bildero" -msgstr[1] "%d bilderoj" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "spaco" -msgstr[1] "%d × %d" - -#: src/cthulhu/messages.py:2813 -#, fuzzy, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "langeto" -msgstr[1] "Ebligu la langetojn de la raportoj pri la stato" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "_Tabelo…" -msgstr[1] "Tabeloj" - -#: src/cthulhu/messages.py:2829 -#, fuzzy -msgid "table of unknown size" -msgstr "Nekonato" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "_Tabelo…" -msgstr[1] " Vicoj " - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "antaŭ %d sekundo" -msgstr[1] "antaŭ %d sekundoj" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "antaŭ %d minuto" -msgstr[1] "antaŭ %d minutoj" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "antaŭ %d horo" -msgstr[1] "antaŭ %d horoj" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "antaŭ %d tago" -msgstr[1] "antaŭ %d tagoj" - -#: src/cthulhu/messages.py:2884 -#, fuzzy, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "nevizitite" -msgstr[1] "Ligiloj" - -#: src/cthulhu/messages.py:2892 -#, fuzzy, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "_Vizitita ligilo:" -msgstr[1] "vizitite" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "baskuligi" - -#: src/cthulhu/object_properties.py:46 -#, fuzzy, python-format -msgid "on %(index)d of %(total)d" -msgstr "Enspezo: %d Elspezo: %d" - -#: src/cthulhu/object_properties.py:51 -#, fuzzy, python-format -msgid "%(index)d of %(total)d" -msgstr "Enspezo: %d Elspezo: %d" - -#: src/cthulhu/object_properties.py:60 -#, fuzzy, python-format -msgid "item %(index)d" -msgstr "indekso" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVELO %d" - -#: src/cthulhu/object_properties.py:76 -#, fuzzy, python-format -msgid "tree level %d" -msgstr "NIVELO %d" - -#: src/cthulhu/object_properties.py:80 -#, fuzzy, python-format -msgid "TREE LEVEL %d" -msgstr "NIVELO %d" - -#: src/cthulhu/object_properties.py:94 -#, fuzzy, python-format -msgid "details for %s" -msgstr "Detaloj" - -#: src/cthulhu/object_properties.py:109 -#, fuzzy, python-format -msgid "has details in %s" -msgstr "Detaloj" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "demando" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "redakteble" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "redakteble" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -#, fuzzy -msgctxt "role" -msgid "abstract" -msgstr "Kvar-nivela klavo kun abstraktaj apartigiloj" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "vorto" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "apendico" - -#: src/cthulhu/object_properties.py:173 -#, fuzzy -msgctxt "role" -msgid "bibliography entry" -msgstr "Tekstenigo por enigi daton" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "dupunkto" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "konkludo" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "kovrilo" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -#, fuzzy -msgctxt "role" -msgid "credits" -msgstr "" -"Aisano\n" -"Eliovir\n" -"Kim RIBEIRO\n" -"Leo ARIAS\n" -"Matt PEPERELL\n" -"Michael MORONI\n" -"Patrick (Petriko) OUDEJANS\n" -"Serge LEBLANC\n" -"Simon TITE\n" -"Yekrats\n" -"chops\n" -"maku\n" -"trio\n" -"Kristjan SCHMIDT\n" -"Daniel PUENTES\n" -"Carmen Bianca BAKKER \n" -"Tirifto " - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "dediĉo" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -#, fuzzy -msgctxt "role" -msgid "example" -msgstr " Ekzemplo pri interbatalo 1" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "vorto" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosaro" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "indekso" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "enkonduko" - -#: src/cthulhu/object_properties.py:287 -#, fuzzy -msgctxt "role" -msgid "page break" -msgstr "nerompebla spaceto" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "Paĝo…" - -#: src/cthulhu/object_properties.py:299 -#, fuzzy -msgctxt "role" -msgid "part" -msgstr "Aranĝi parton kiel HTML" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "citilo" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "_Tabelo…" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, fuzzy, python-format -msgid "%(role)s level %(level)d" -msgstr "Nivelo: %s.
" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "_Horizontale:" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "vertikala streko" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "_Horizontale:" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "_Vertikale:" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "_Horizontale:" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "_Vertikale:" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "ŝaltilo" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Piktogrampanelo" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "Laboristoj: Kontentaj" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informo" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "enhavo de bildo" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigado" - -#: src/cthulhu/object_properties.py:460 -#, fuzzy -msgctxt "role" -msgid "region" -msgstr "Monda regiono" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "serĉo" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "vizitita ligilo" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "menubutono" - -#: src/cthulhu/object_properties.py:484 -#, fuzzy -msgid "sorted ascending" -msgstr "(Kreskanta)" - -#: src/cthulhu/object_properties.py:488 -#, fuzzy -msgid "sorted descending" -msgstr "(Malkreskanta)" - -#: src/cthulhu/object_properties.py:493 -#, fuzzy -msgid "sorted" -msgstr "Ne ordigita" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "alklakebla" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -#, fuzzy -msgid "expanded" -msgstr "ege vastigita" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "havas longan priskribon" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontale" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikale" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "" -"Evolucio serĉis agordojn por enporti el la sekvaj aplikaĵoj: Pine, Netscape, " -"Elm, iCalendar, KMail. Neniuj enporteblaj agordoj trovitaj. Se vi ŝatus " -"reprovi, bonvolu alklaki la “Reen”-butonon." - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "" -"Evolucio serĉis agordojn por enporti el la sekvaj aplikaĵoj: Pine, Netscape, " -"Elm, iCalendar, KMail. Neniuj enporteblaj agordoj trovitaj. Se vi ŝatus " -"reprovi, bonvolu alklaki la “Reen”-butonon." - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "enŝaltite" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "elŝaltite" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "parte subskribita per GPG" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "premita" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ne premita" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "ne elektita" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "elektite" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ne elektite" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "ne elektite" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "vizitite" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "nevizitite" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "nurlege" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -#, fuzzy -msgid "required" -msgstr "Necesas almenaŭ unu alestanto." - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "_Elekti..." - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "nevalide" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "nevalide" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "nevalida literumado" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "literumado" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "nevalide" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Serĉi" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Ekranlegila serĉdialogo" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Fermi" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Serĉi" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Serĉi por:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Serĉi por:" - -#: src/cthulhu/cthulhu-find.ui:166 -#, fuzzy -msgid "_Top of window" -msgstr "Supre" - -#: src/cthulhu/cthulhu-find.ui:175 -#, fuzzy -msgid "Top of window" -msgstr "Supre" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -#, fuzzy -msgid "Start from:" -msgstr "Eble ni ne povas startigi ĝin de ĉi tie." - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Ĉ_irkaŭflui" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Serĉi _malantaŭen" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Serĉ-direkton:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Uskleca kongruo" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Kongrui nur _tutan vorton" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opcioj:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Defaŭlte" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Majuskle" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Ligilo" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistemo" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplikaĵo" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Fenestro" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "Ekranlegilo Orko" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Helpo" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Apliki" - -#: src/cthulhu/cthulhu-setup.ui:272 -#, fuzzy -msgid "_Laptop" -msgstr "Tekokomputilo Acer" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Klavararanĝo" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktiva _profilo:" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "Startigo" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "Ŝar_gi" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Konservi _kiel" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "Fo_rigi" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiloj" - -#: src/cthulhu/cthulhu-setup.ui:479 -#, fuzzy -msgid "_Present tooltips" -msgstr "Ĉeestantaj unuoj" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Muso" - -#: src/cthulhu/cthulhu-setup.ui:552 -#, fuzzy -msgid "_Time format:" -msgstr "Tempoaranĝo:" - -#: src/cthulhu/cthulhu-setup.ui:569 -#, fuzzy -msgid "Dat_e format:" -msgstr "_Aranĝi kiel…" - -#: src/cthulhu/cthulhu-setup.ui:625 -#, fuzzy -msgid "Time and Date" -msgstr "Dato kaj horo" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "_Brajlo-ĝisdatigoj" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Brajlo-ĝisdatigoj" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -#, fuzzy -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "?mins/secs:%02dm %02ds" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Aplikaĵo" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -#, fuzzy -msgid "Bee_p updates" -msgstr "" -"

Priskribo:

\n" -"\n" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Progresbretaj ĝisdatigoj" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -#, fuzzy -msgid "Say All B_y:" -msgstr "%B %Y" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -#, fuzzy -msgid "Announce _tables in Say All" -msgstr "Diri ĉion" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -#, fuzzy -msgid "Announce _panels in Say All" -msgstr "Diri ĉion" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -#, fuzzy -msgid "Announce _forms in Say All" -msgstr "Diri ĉion" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Diri ĉion" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Ĝenerale" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Sonforteco:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "In_terpaŝo:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Rapido:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persono:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Lingvo:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -#, fuzzy -msgid "Speech synthesi_zer:" -msgstr "Parolado" - -#: src/cthulhu/cthulhu-setup.ui:1371 -#, fuzzy -msgid "Speech _system:" -msgstr "Parolado" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "Voĉo" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -#, fuzzy -msgid "_Capitalization style:" -msgstr "Kapitaligo" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "Ĝeneralaj voĉ-agordoj" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Voĉlegi _numerojn kiel ciferoj" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Ĝeneralaj voĉ-agordoj" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voĉo" - -#: src/cthulhu/cthulhu-setup.ui:1577 -#, fuzzy -msgid "_Enable speech" -msgstr "Parolado" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -#, fuzzy -msgid "Ver_bose" -msgstr "Ver_tikala bazo:" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "Ĉi_o" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "Nivelo" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -#, fuzzy -msgid "Only speak displayed text" -msgstr "Nur _teksto" - -#: src/cthulhu/cthulhu-setup.ui:1819 -#, fuzzy -msgid "Speak blank lines" -msgstr "" -"Horizontalaj\n" -"linioj" - -#: src/cthulhu/cthulhu-setup.ui:1835 -#, fuzzy -msgid "Speak _indentation and justification" -msgstr "Voĉlegi _priskribon" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -#, fuzzy -msgid "Speak tutorial messages" -msgstr "Voĉlegi mesaĝojn de" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -#, fuzzy -msgid "_System messages are detailed" -msgstr "Detala erar-mesaĝo:" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "_Voĉlegi kolorojn per la nomoj" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "Malatenti misliterumitan vorton" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Voĉlegi _priskribon" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -#, fuzzy -msgid "Spoken Context" -msgstr "Kunteksto estas %s" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Parolado" - -#: src/cthulhu/cthulhu-setup.ui:2187 -#, fuzzy -msgid "Enable Braille _support" -msgstr "Brajlo" - -#: src/cthulhu/cthulhu-setup.ui:2230 -#, fuzzy -msgid "_Abbreviated role names" -msgstr "Rolo" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -#, fuzzy -msgid "Contraction _Table:" -msgstr "_Tabelo…" - -#: src/cthulhu/cthulhu-setup.ui:2300 -#, fuzzy -msgid "_Enable Contracted Braille" -msgstr "Brajlo" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "vorto" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Ekran-agordoj" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Neniu" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "_Elekto" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "Ligilo" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "Ŝalti D-Bus-mesaĝojn." - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -#, fuzzy -msgid "D_uration (secs):" -msgstr "Sat_ureco" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -#, fuzzy -msgid "Messages are _persistent" -msgstr "Mesaĝoj al" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -#, fuzzy -msgid "Messages are _detailed" -msgstr "Detala erar-mesaĝo:" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "_Agordoj" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Brajlo" - -#: src/cthulhu/cthulhu-setup.ui:2780 -#, fuzzy -msgid "Enable _key echo" -msgstr "ŝlosilo" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Enŝalti _spacon" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Angla (UK, Dvorako, kun interpunkcio de UK)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Enŝalti _spacon" - -#: src/cthulhu/cthulhu-setup.ui:2864 -#, fuzzy -msgid "Enable _modifier keys" -msgstr "Enŝalti _spacon" - -#: src/cthulhu/cthulhu-setup.ui:2879 -#, fuzzy -msgid "Enable _function keys" -msgstr "Ŝalti aŭtomatajn kontaktojn" - -#: src/cthulhu/cthulhu-setup.ui:2894 -#, fuzzy -msgid "Enable ac_tion keys" -msgstr "Aldoni _agon" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Ebligi _navigajn klavojn" - -#: src/cthulhu/cthulhu-setup.ui:2965 -#, fuzzy -msgid "Enable echo by _word" -msgstr "Enŝalti _spacon" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "Frazo" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Ekranlegila(j) _modifo-klavo(j):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Klavkombinoj" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "Prononco" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nova enigo" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Forigi" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Prononco" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Voĉlegi ĉion" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Voĉlegi _nenion" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Reagordi" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Tekstaj atributoj" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -#, fuzzy -msgid "Move to _bottom" -msgstr "Movi la elektitajn kapojn al subo" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -#, fuzzy -msgid "Move _down one" -msgstr "Movi malsupren" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -#, fuzzy -msgid "Move _up one" -msgstr "Movi supren" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -#, fuzzy -msgid "Move to _top" -msgstr "Movi la elektitajn kapojn al supro" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "Atribui mesaĝon" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "Brajlo" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Tekstaj atributoj" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "malalte" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "_Lingvo:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "eno" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -#, fuzzy -msgid "Copy Results to _Clipboard" -msgstr "_Enhavoj" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "fonkoloro" - -#: src/cthulhu/text_attribute_names.py:76 -#, fuzzy -msgctxt "textattr" -msgid "background full height" -msgstr "fono plena alteco" - -#: src/cthulhu/text_attribute_names.py:83 -#, fuzzy -msgctxt "textattr" -msgid "background stipple" -msgstr "fona punkto" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direkto" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "redakteble" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "familia nomo" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "malfona koloro" - -#: src/cthulhu/text_attribute_names.py:117 -#, fuzzy -msgctxt "textattr" -msgid "foreground stipple" -msgstr "malfono" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "tiparo-efekto" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "krommarĝeno" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "eraro" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "nevideble" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "lingvo" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "maldekstra marĝeno" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "linia alteco" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "alinea stilo" - -#: src/cthulhu/text_attribute_names.py:193 -#, fuzzy -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" -"Horizontalaj\n" -"linioj" - -#: src/cthulhu/text_attribute_names.py:200 -#, fuzzy -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" -"Horizontalaj\n" -"linioj" - -#: src/cthulhu/text_attribute_names.py:208 -#, fuzzy -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "Rastrumeroj" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "dekstra marĝeno" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "skalo" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "grando" - -#: src/cthulhu/text_attribute_names.py:243 -#, fuzzy -msgctxt "textattr" -msgid "stretch" -msgstr "streĉi" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stilo" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "teksta dekoracio" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotacio de teksto" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "teksta ombro" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "substreko" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variaĵo" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "glatigi sojlon" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:316 -#, fuzzy -msgctxt "textattr" -msgid "wrap mode" -msgstr "reĝimo de ĉirkaŭfluo" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "skriba reĝimo" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "vere" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "neniu" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -#, fuzzy -msgctxt "textattr" -msgid "line through" -msgstr "linio tra" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "nigra" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "unuope" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "duoble" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "malalte" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "signo" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "vorto" - -#: src/cthulhu/text_attribute_names.py:452 -#, fuzzy -msgctxt "textattr" -msgid "word char" -msgstr "signo" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "maldekstre al dekstre" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "dekstre al maldekstre" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "maldekstre" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "dekstre" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centre" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "plenigi" - -#: src/cthulhu/text_attribute_names.py:507 -#, fuzzy -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ege vastigita" - -#: src/cthulhu/text_attribute_names.py:514 -#, fuzzy -msgctxt "textattr" -msgid "extra condensed" -msgstr "aldona tempo ĉiuj" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normale" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "ege vastigita" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "ege vastigita" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "ege vastigita" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ege vastigita" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "malgrandaj ĉapoj" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblikva" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kursive" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Defaŭlte" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Teksta korpo" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Titolo" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "bazlinio" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "supre" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "teksto sube" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "meze" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "malsupre" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "teksto malsupre" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "heredis" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "maldekstre-dekstre supre-malsupre" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "dekstre-maldekstre supre-malsupre" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "supre-malsupre dekstre-maldekstre" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "supre-malsupre maldekstre-dekstre" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "malsupre-supre dekstre-maldekstre" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "malsupre-supre maldekstre-dekstre" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "maldekstre-dekstre" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "dekstre-maldekstre" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "supre-malsupre" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "solide" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "literumado" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Premu spacon por ŝanĝi." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Premu spacon por pligrandigi, kaj uzu supren kaj malsupren por elekti eron." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Premu alt+f6 por fokusigi idajn fenestrojn." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "Por movi al eroj, uzu aŭ la sagoklavojn aŭ tajpu antaŭen serĉadon." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Por atingi la sistemajn menuojn premu la klavon alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Uzu supren kaj malsupren por elekti eron." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Por kolapsi, premu majusklon plus maldekstren." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Por pligrandigi, premu majusklon plus dekstren." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Por enŝalti premu la enigklavon." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Enigi tekston." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Uzi la maldekstran kaj dekstran klavon por rigardi aliajn langetojn." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Por enŝalti premi spacon." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Uzu supren aŭ malsupren por elekti valoron. Aŭ tajpu la deziratan nombran " -"valoron." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Uzi sagklavojn por ŝanĝi." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Por navigi, premu maldekstran aŭ dekstran sagon. Por movi tra eroj premu " -"supren aŭ malsupren sagon." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Por eniri la submenuon, premu la dekstran sagon." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Por malpliigi premu maldekstran sagon, por pliigi premu dekstran sagon. Por " -"iri al minimumo premu hejmon, kaj por maksimumo premu finon." diff --git a/po/es.po b/po/es.po deleted file mode 100644 index 99fb9a7..0000000 --- a/po/es.po +++ /dev/null @@ -1,9254 +0,0 @@ -# translation of cthulhu.HEAD.po to Español -# Traducción de Cthulhu al Español -# This file is distributed under the same license as the CTHULHU package. -# Copyright (C) 2005 GNOME Foundation. -# -# Francisco Javier F. Serrador , 2004, 2006. -# Maria Majadas , 2005. -# Jorge González , 2007, 2008, 2010, 2011. -# -# -# Miguel Rodríguez Núñez , 2015. -# -# Francisco Javier Dorado Martínez , 2007-2022. -# Daniel Mustieles , 2022-2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-09 12:42+0200\n" -"Last-Translator: Daniel Mustieles \n" -"Language-Team: Spanish - Spain \n" -"Language: es_ES\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"X-Generator: Gtranslator 45.alpha0\n" - -msgid "Cthulhu Screen Reader" -msgstr "Lector de pantalla Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "lector;pantalla;accesibilidad;voz;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "flc" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "lnz" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "dscrp" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "cv" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "sltcol" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "cabcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "fch" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ico" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "mar" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "mrcd" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "pnldir" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "dibujo" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "sltar" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "rlln" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "tpg" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "pnltr" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "cbcra" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "mrci" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etq" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "pnlslp" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "enlace" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "ellst" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "brmnu" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "elmnum" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "pnlo" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "slp" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblslp" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "contr" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnuem" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "brprog" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "mnuer" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "pnlr" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "Cabfl" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "brdesl" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "pnldesl" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sccn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprdr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "desl" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "pnldiv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "contador" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "brestbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cld" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "emd" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "btc" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "bdh" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "csj" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arb" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tblArb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "desc" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "Prt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "vnt" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "Cab" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pDP" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "parra" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "ap" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "bEd" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "cEmp" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Checo grado 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Español grado 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francés de Canadá grado 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francés de Francia grado 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letón grado 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holandés de Países Bajos grado 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Noruego grado 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Noruego grado 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Noruego grado 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Noruego grado 2" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polaco grado 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugués grado 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Sueco grado 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Árabe grado 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galés grado 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galés grado 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemán grado 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemán grado 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemán grado 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Inglés del Reino Unido grado 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Inglés del Reino Unido grado 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Inglés de Estados Unidos grado 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Inglés de Estados Unidos grado 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francés de Canadá grado 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francés de Francia grado 2" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Griego grado 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindú grado 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Húngaro 8 punto ordenador" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Húngaro grado 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Húngaro grado 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiano grado 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Holandés de Bélgica grado 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espacio" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "línea nueva" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "exclamación" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "comillas" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "número" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dólar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "porciento" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ampersand" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apóstrofo" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "abre paréntesis" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "cierra paréntesis" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterisco" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "más" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "coma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "guión" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punto" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dos puntos" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punto y coma" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "menor" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "igual" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "mayor" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "interrogación" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "arroba" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "abre corchete" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "barra invertida" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "cierra corchete" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "circunflejo" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "subrayado" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "abre llave" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra vertical" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "cierra llave" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "virgulilla" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espacio de no separación" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "abre exclamación" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centavos" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "libras" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "símbolo de moneda" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra vertical cortada" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "sección" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diéresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a sobrescrita" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "abre comillas angulares" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "no lógico" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "guión" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrado" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "sobrerayado" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "grados" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "más o menos" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "2 superíndice" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "3 superíndice" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acento" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "marca de párrafo" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "punto centrado" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 superíndice" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "cierra comillas angulares" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "un cuarto" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "un medio" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tres cuartos" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "abre interrogación" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a con tilde" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A CON TILDE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUNFLEJA" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A CON TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A CON DIÉRESIS" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A CON ANILLO" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E CON TILDE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUNFLEJA" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E CON DIÉRESIS" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I CON TILDE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUNFLEJA" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I CON DIÉRESIS" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "Ñ" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O CON TILDE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUNFLEJA" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O CON TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O CON DIÉRESIS" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "por" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O CON BARRA DIAGONAL" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U CON TILDE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUNFLEJA" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U CON DIÉRESIS" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y CON TILDE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "ZORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "beta" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circunfleja" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a con tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a con diéresis" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a con anillo" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e con tilde" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circunfleja" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e con diéresis" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i con tilde" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circunfleja" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i con diéresis" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "ñ" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o con tilde" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circunfleja" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o con tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o con diéresis" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "dividido por" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o con barra diagonal" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "zorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u con tilde" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circunfleja" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u con diéresis" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y con tilde" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y con diéresis" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y CON DIÉRESIS" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florín" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "guión alto" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "abre comilla simple" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "abre comilla simple" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "comilla inferior simple" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "abre comilla doble" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "cierra comilla doble" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "doble comilla inferior" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "cruz" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "DOBLE CRUZ" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "viñeta" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "viñeta triangular" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "por milla" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "primo" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "primo doble" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "triple primo" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "guión de viñeta" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marca registrada" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "marca" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "marca fuerte" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "viñeta marcada con x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "0 superíndice" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "4 superíndice" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "5 superíndice" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "6 superíndice" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "7 superíndice" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "8 superíndice" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "9 speríndice" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "más superíndice" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "menos superíndice" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "igual superíndice" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "abre paréntesis superíndice" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "cierra paréntesis superíndice" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n superíndice" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "0 subíndice" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "1 subíndice" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "2 subíndice" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "3 subíndice" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "4 subíndice" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "5 subíndice" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "6 subíndice" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "7 subíndice" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "8 subíndice" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "9 subíndice" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "más subíndice" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "menos subíndice" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "igual subíndice" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "abre paréntesis subíndice" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "cierra paréntesis subíndice" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "cuadrado tachado" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "rombo" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "carácter de reemplazo de objeto" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Posicionar el puntero en el elemento actual" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Pulsar con el botón izquierdo sobre el elemento revisado" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Pulsar con el botón derecho sobre el elemento revisado" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Hablar todo el documento" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Hablar la ventana completa usando la revisión" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Realizar la operación básica ¿Dónde estoy?" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Realizar la operación detallada ¿Dónde estoy?" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Hablar la selección actual" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Hablar los detalles del enlace" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Hablar el botón predeterminado" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Hablar la barra de estado" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Hablar la barra de título" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Abrir el diálogo de búsqueda" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Mostrar lista de acciones" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Buscar la siguiente instancia de una cadena" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Buscar la instancia anterior de una cadena" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Entrar y salir del modo de revisión" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Conmutar la restricción de la revisión para el objeto actual" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Mover la revisión a la posición inicial" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Mover la revisión a la posición final" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Mover la revisión al comienzo de la línea anterior" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Hablar la línea actual de revisión" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Deletrear la línea actual de revisión" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Deletrear fonéticamente la línea actual de revisión" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Mover la revisión al comienzo de la siguiente línea" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Mover la revisión al anterior elemento o palabra" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Hablar el elemento o palabra actual de revisión" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Deletrear el elemento o palabra actual de revisión" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Deletrear fonéticamente el elemento o palabra actual de revisión" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Mover la revisión al siguiente elemento o palabra" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Mover la revisión a la palabra encima de la palabra actual" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Hablar el objeto revisado actualmente" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Mover la revisión a la palabra de debajo de la palabra actual" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Mover la revisión al carácter anterior" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Hablar el carácter revisado actualmente" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Hablar fonéticamente el carácter actual de revisión" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Hablar el carácter Unicode del carácter actual de revisión" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Mover la revisión al carácter siguiente" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Mover la revisión al final de la línea" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Mover la revisión a la esquina inferior izquierda" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copiar el contenido en revisión al portapapeles" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Añadir el contenido de revisión al portapapeles" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Mover el contenido de la revisión" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Conmutar entre leer sólo la celda actual o toda la fila" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Leer los atributos asociados al carácter actual" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Desplazar la línea braille a la izquierda" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Desplazar la línea braille a la derecha" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Volver al objeto con el foco de teclado" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Activar o desactivar el braille contraído" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Procesar una tecla de enrutado del cursor" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marcar el comienzo de una selección de texto" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marcar el final de una selección de texto" - -# Escape es hablado -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Entrar en modo de aprendizaje. Pulse escape para salir del modo de " -"aprendizaje" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Disminuir la velocidad de la voz" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Aumentar la velocidad de la voz" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Disminuir el tono de la voz" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Aumentar el tono de la voz" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Aumentar el volumen de la voz" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Disminuir el volumen de la voz" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Seleccionar el ajuste de voz anterior" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Seleccionar el siguiente ajuste de voz" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Disminuir el ajuste de voz actual" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Aumentar el ajuste de voz actual" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Guardar ajustes de voz" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Conmuta el silencio de la voz" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Conmutar el nivel de detalle de la voz" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Conmutar modo de suspensión" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Salir del lector de pantalla" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Mostrar el diálogo de configuración de preferencias" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Mostrar el diálogo de configuración de preferencias para la aplicación" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Conmutar el habla del sangrado y la justificación" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Cambiar el estilo de número hablado" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Cambiar al siguiente nivel de hablada de puntuación" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Cambiar al siguiente sintetizador de voz" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Cambiar al siguiente perfil de configuración" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Cambiar al siguiente estilo de capitalización" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Cambiar al siguiente nivel de eco de teclas" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Cambiar entre los niveles de depuración en tiempo de ejecución" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Marcador ¿Dónde estoy? con respecto a la posición actual" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Ir a la ubicación del marcador anterior" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Ir a marcador" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Ir a la ubicación del siguiente marcador" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Añadir marcador" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Guardar marcadores" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Conmutar el modo de revisión del ratón" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Presentar la hora actual" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Presentar la fecha actual" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Informar acerca del tamaño y la ubicación del objeto actual" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Enviar el siguiente comando a la aplicación activa" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Hablar y braille de un mensaje anterior de una sala de chat" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Conmutar si se anuncia cuando nuestros amigos están tecleando" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Conmutar si se proporcionan históricos de mensajes de cada sala de chat" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Conmutar si se prefijan los mensajes de la sala de chat con el nombre de la " -"sala de chat" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Línea izquierda" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Línea derecha" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Línea arriba" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Línea abajo" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Desactivar" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Arriba Izquierda" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Abajo a la izquierda" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posición del cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Seis puntos" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Enrutado del cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Inicio del corte" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Línea cortada" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Presentar el último mensaje de notificación" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Presentar la lista de mensajes de notificación" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Presentar el mensaje anterior de notificación" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Presentar el siguiente mensaje de notificación" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Ir al siguiente carácter" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Ir al carácter anterior" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Ir a la siguiente palabra" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Ir a la palabra anterior" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Ir a la siguiente línea" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Ir a la línea anterior" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Ir al principio del archivo" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Ir al final del archivo" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Ir al comienzo de la línea" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Ir al final de la línea" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Ir al siguiente objeto" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Ir al anterior objeto" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Hacer que se expanda el cuadro combinado actual" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Cambiar entre la navegación del cursor del lector de pantalla y la nativa de " -"Gecko" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Adelantar la configuración de comportamiento de la región activa" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" -"Establecer el nivel predeterminado de comportamiento de las regiones activas " -"a desactivado" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Revisar anuncio de región activa" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitorizar regiones activas" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Mover el foco hacia o lejos del actual posición del ratón" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Establecer la fila que usar como cabeceras dinámicas de columnas" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Limpiar las cabeceras dinámicas de columna" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Establecer la columna que usar como cabeceras dinámicas de fila" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Limpiar las cabeceras dinámicas de fila" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Presentar el contenido de la línea de entrada" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Conmutar las teclas de navegación estructural" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Ir a la cita anterior" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Ir a la siguiente cita" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Mostrar una lista de citas" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Ir al botón anterior" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Ir al siguiente botón" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Mostrar una lista de botones" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Ir a la casilla anterior" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Ir a la siguiente casilla" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Mostrar una lista de casillas" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Ir al anterior elemento que se puede pulsar" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Ir al siguiente elemento que se puede pulsar" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Mostrar una lista de elementos que se pueden pulsar" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Ir al cuadro combinado anterior" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Ir al siguiente cuadro combinado" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Ir al principio del contenedor" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Ir al final del contenedor" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Mostrar una lista de cuadros combinados" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Ir a la entrada anterior" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Ir a la siguiente entrada" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Mostrar una lista de entradas" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Ir al campo de formulario anterior" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Ir al siguiente campo de formulario" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Mostrar una lista de campos de formulario" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Ir al encabezado anterior" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Ir al siguiente encabezado" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Mostrar una lista de encabezados" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Ir al encabezado anterior de nivel %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Ir al siguiente encabezado de nivel %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Mostrar una lista de encabezados de nivel %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Ir al marco interno anterior" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Ir al siguiente marco interno" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Mostrar una lista de marcos internos" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Ir a la imagen anterior" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Ir a la siguiente imagen" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Mostrar una lista de imágenes" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Ir al anterior punto de referencia" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Ir al siguiente punto de referencia" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Mostrar una lista de puntos de referencia" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Ir al objeto grande anterior" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Ir al siguiente objeto grande" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Mostrar una lista de objetos grandes" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Ir al enlace anterior" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Ir al siguiente enlace" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Mostrar una lista de enlaces" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Ir a la lista anterior" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Ir a la siguiente lista" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Mostrar una lista de listas" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Ir al anterior elemento de lista" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Ir al siguiente elemento de lista" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Mostrar una lista de elementos de lista" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Ir a la anterior región activa" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Ir a la siguiente región activa" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Ir a la última región activa que hizo un anuncio" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Ir al padre del objeto con el foco del navegador" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Ir al primer hijo del objeto con el foco del navegador." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Ir al siguiente hermano del objeto con el foco del navegador." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Ir al hermano anterior del objeto con el foco del navegador." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Pulsar sobre el objeto con el foco del navegador" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Conmutar navegación de objetos simplificada" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Ir al párrafo anterior." - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Ir al siguiente párrafo" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Mostrar una lista de párrafos" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Ir al anterior botón de radio" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Ir al siguiente botón de radio" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Mostrar una lista de botones de radio" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Ir al anterior separador" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Ir al siguiente separador" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Ir a la anterior tabla" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Ir a la siguiente tabla" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Mostrar una lista de tablas" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Ir una celda abajo" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Ir a la primera celda de una tabla" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Ir a la última celda de una tabla" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Ir una celda a la izquierda" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Ir una celda a la derecha" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Ir una celda arriba" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Conmutar el modo de distribución" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Cambiar entre modo navegación y modo foco" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Activar el modo de foco pegajoso" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Activar el modo de navegación pegajoso" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Ir al anterior enlace no visitado" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Ir al siguiente enlace no visitado" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Mostrar una lista de enlaces no visitados" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Ir al anterior enlace visitado" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Ir al siguiente enlace visitado" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Mostrar una lista de enlaces visitados" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "alice blue" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antique white" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "aquamarine" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azure" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "black" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "blanched almond" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "azul" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "azul violeta" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "marrón" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "cadet blue" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chocolate" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "coral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "cornflower blue" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "crimson" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cyan" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "azul oscuro" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "dark cyan" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "dark goldenrod" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "dark gray" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verde oscuro" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "dark khaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "dark magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "dark olive green" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "dark orange" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "dark orchid" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "dark red" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "dark salmon" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "dark sea green" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "dark slate blue" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "dark slate gray" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "dark turquoise" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "dark violet" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "deep pink" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "deep sky blue" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "dim gray" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodger blue" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "fire brick" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "floral white" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "forest green" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "ghost white" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "gold" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "goldenrod" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "gray" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "green" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "green yellow" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "honeydew" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "hot pink" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indian red" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "ivory" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavender" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavender blush" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "lawn green" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "lemon chiffon" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "light blue" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "light coral" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "light cyan" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "light goldenrod yellow" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "light gray" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "light green" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "light pink" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "light salmon" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "light sea green" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "light sky blue" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "light slate gray" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "light steel blue" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "light yellow" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lime" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "lime green" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linen" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "maroon" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "medium aquamarine" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "medium blue" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "medium orchid" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "medium purple" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "medium sea green" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "medium slate blue" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "medium spring green" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "medium turquoise" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "medium violet red" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "midnight blue" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "mint cream" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "misty rose" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "moccasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajo white" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "navy" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "old lace" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olive" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "olive drab" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "orange" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "orange red" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchid" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "pale goldenrod" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "pale green" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "pale turquoise" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "pale violet red" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "peach puff" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "pink" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "plum" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "powder blue" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purple" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "red" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rosy brown" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "royal blue" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "saddle brown" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmon" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "sandy brown" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "sea green" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "seashell" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "silver" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "sky blue" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "slate blue" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "slate gray" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "snow" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "spring green" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "steel blue" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "tan" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "teal" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "thistle" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomato" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquoise" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violet" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "wheat" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "white" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "white smoke" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "yellow" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "yellow green" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "Activar" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Modo de foco automático durante la navegación estructural" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Modo de foco automático durante la navegación de cursor" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Modo de foco automático durante la navegación de cursor" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punto _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punto _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Puntos 7 _y 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Cancelar" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Saltar a" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Aceptar" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Icono" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Ninguno" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Deletrear" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Anunciar cuando sus _amigos están tecleando" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Proporcionar históricos de mensajes específicos de cada sala de chat" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Hablar los mensajes de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Todos los ca_nales" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Todos los canales cuando c_ualquier ventana de %s está activa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Un canal sólo si su _ventana está activa" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Hablar el nombre de la sala de chat" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Activar el modo de distribución para el contenido" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "doble pulsación" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triple pulsación" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizador predeterminado" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Cadena Actual" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Cadena de reemplazo" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Activar eco por _carácter" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Activar teclas _diacríticas" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Posición a_ctual" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Mínima longitud del texto coincidente:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opciones de búsqueda" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Hablar _solamente las líneas cambiadas durante la búsqueda" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Hablar los resultados durante la _búsqueda" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Comando" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Atajo de teclado" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Predeterminado" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Modo aprendizaje" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Acciones" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Atajos Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Marcadores" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Fecha y hora" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Revisión del ratón" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Navegación de objeto" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Detalles del objeto" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "No asociado" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Revisión" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Voz y nivel de detalle" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Contenido de la revisión" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificado" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Escritorio" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificaciones" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Recibido" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Presentador de notificaciones" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferencias de Cthulhu para %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marcar en braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Presentar a menos que" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Hablar" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Guardar perfil como conflicto" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflicto con el perfil de usuario" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"El perfil %s ya existe.\n" -"¿Continuar actualizando el perfil existente con estos cambios nuevos?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Cargar perfil de usuario" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Está a punto de cambiar el perfil activo. Si acaba de\n" -"hacer cambios en sus preferencias, estos se\n" -"perderán en la carga del perfil.\n" -"\n" -"¿Continuar la carga del perfil descartando los cambios anteriores?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Guardar perfil como" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nombre del _perfil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Quitar perfil de usuario" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Va a quitar el perfil de usuario %s. Se perderán todos los cambios, " -"guardados o no. ¿Quiere continuar con la eliminación de este perfil y toda " -"su configuración asociada?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Todo" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicación" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Ventana" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Ninguna" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Alguna" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "La _mayoría" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Línea" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Frase" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Cita" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Botón" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Leyenda" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Casilla" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Se puede pulsar" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Cuadro combinado" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descripción" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Encabezado" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Marco Interno" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imagen" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiqueta" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Punto de referencia" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivel" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Enlace" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Elemento de lista" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objeto" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Párrafo" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Botón de radio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rol" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Elemento seleccionado" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Estado" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Texto" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valor" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Citas" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botones" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Casillas" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Se puede pulsar" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Cuadros combinados" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entradas" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Campos de un formulario" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Encabezados" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Marcos Internos" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imágenes" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Encabezados de nivel %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Puntos de referencia" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Objetos grandes" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Enlaces" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listas" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Elementos de lista" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Párrafos" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Botones de radio" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tablas" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Enlaces no visitados" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Enlaces visitados" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navegación por páginas" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Comienza a hablar automáticamente una página cuando ésta se _carga por " -"primera vez" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Mostrar un resumen de una página cuando ésta se _carga por primera vez" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Partir la voz en trozos entre pausas" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "voz predeterminada %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Predeterminada" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiperenlace" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Mayúscula" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Revisor ortográfico" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "_Error ortográfico" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "_Sugerencia ortográfica" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Mostrar el _contexto del error" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Hablar las coordenadas de las celdas en hojas de cálculo" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Hablar siempre el rango seleccionado de la hoja de cálculo" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "_Anunciar la cabecera de una celda" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navegación por tablas" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Saltar celdas en _blanco" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Hablar _celda" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Hablar las coordenadas de una _celda" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Hablar _celdas dentro de otra celda" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nombre del atributo" - -# Notas: -# Añadir una nota -# -# Comentarios extraídos: -# Translators: Gecko native caret navigation is where Firefox itself controls -# how the arrow keys move the caret around HTML content. It's often broken, so -# Cthulhu needs to provide its own support. As such, Cthulhu offers the user the -# ability to switch between the Firefox mode and the Cthulhu mode. This is the -# label of a checkbox in which users can indicate their default preference. -# -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Controlar la navegación del cursor" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Activar la navegación e_structural" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Tema de sonido:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Tema de sonido" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Breve" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d notificación" -msgstr[1] "%d notificaciones" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Mayús" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "mayúsculas izquierda" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt izquierdo" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control izquierdo" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "mayúsculas derecha" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt derecho" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control derecho" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta izquierdo" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta derecho" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "bloqueo numérico" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "bloqueo mayúsculas" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "bloqueo mayúsculas" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "bloqueo desplazamiento" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "retroceso de página" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "avance de página" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab izquierdo" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "retroceso" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "intro" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "intro" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "arriba" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "abajo" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "izquierda" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "derecha" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super izquierda" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super derecha" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menú" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ayuda" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "cambiar modo" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insertar" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "suprimir" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "inicio" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "fin" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "comenzar" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circunflejo" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "círculo" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "diagonal" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "menos" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insertar" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Bloqueo_mayúscula" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_D" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_I" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Mayús" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s negrita" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s cursiva" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s negrita cursiva" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "cursiva %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "cursiva negrita %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s fraktur" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s doble struck" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s negrita fraktur" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s sans-serif" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s sans-serif negrita" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s sans-serif cursiva" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s sans-serif negrita cursiva" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "monoespaciado %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s sin punto" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "flecha izquierda" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "flecha arriba" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "flecha derecha" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "flecha abajo" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "flecha izquierda derecha" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "flecha arriba abajo" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "flecha noroeste" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "flecha noreste" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "flecha sureste" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "flecha izquierda desde la barra" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "flecha hacia arriba desde la barra" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "flecha derecha desde la barra" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "flecha hacia abajo desde la barra" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "flecha izquierda doble" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "flecha arriba doble" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "flecha derecha doble" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "flecha abajo doble" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "flecha doble que apunta a la izquierda y derecha" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "flecha doble arriba abajo" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "flecha noroeste doble" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "flecha noreste doble" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "flecha sureste doble" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "flecha doble con orientación sudoeste" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "flecha apuntando a la derecha" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "flecha apuntando hacia la derecha" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "menor que" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "mayor que" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circunflejo" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "gancho" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punto" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "línea vertical doble" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "elipsis horizontal" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "para todo" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complemento" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "derivada parcial" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "existe" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "no exixte" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "conjunto vacío" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "delta" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "pertenece" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "no pertenece" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "elemento de, símbolo pequeño" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "existe al menos un elemento" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "no existe al menos un elemento" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "está contenido en, símbolo pequeño" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "fin de prueba" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "producto" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproducto" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sumatorio" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "más o menos" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "por más" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "barra de división" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "diferencia de conjuntos" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operador asterisko" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "función compuesta" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operador bullet" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "raíz cuadrada" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "raíz cúbica" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "raíz cuarta" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcional a" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinito" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "ángulo derecho" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "ángulo" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "ángulo medido" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "ángulo esférico" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "dividido por" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "no divide a" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paralelo a" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "no paralelo a" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "Y lógico" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "OR lógico" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersección" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unión" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integral doble" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integral triple" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integral de contorno" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integral de superficie" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integral de volumen" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral en sentido de las agujas del reloj" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integral de contorno en sentido de las agujas del reloj" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integral de contorno en sentido contrario de las agujas del reloj" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "por lo tanto" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "porque" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "razón" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporción" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "por menos" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "exceso esférico" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporción geométrica" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotético" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "virgulilla" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "virgulilla invertida" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "s invertida y tumbada" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "onda sinusoidal" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "producto en corona" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "virgulilla negada" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "menos virgulilla" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asintóticamente igual a" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "no asintóticamente igual a" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "casi igual que" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "aproximadamente pero actualmente no igual a" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "no se aproxima ni es igual a" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "casi igual a" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "casi no igual a" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "casi igual o igual a" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "triple virgulilla" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "todo igual a" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "equivalente a" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geométricamente equivalente a" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "diferencia entre" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "se acerca al límite" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geométricamente igual a" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "aproximadamente igual o la imagen de" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "imagen de o aproximadamente igual a " - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dos puntos igual" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "igual dos puntos" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "anillo en igual a" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "anillo igual a" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "corresponde a" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estimado" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "de igual ángulo a" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "estrella igual" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta igual a" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "igual por definición" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "medido por" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "interrrogante igual a" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "no igual a" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "idéntico a" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "no idéntico a" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "estrictamente equivalente a" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "menor que o igual a " - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "menor que o igual a " - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "mayor que o igual a" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "menor que pero no igual a" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "mayor que pero no igual a" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "mucho menor que" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "mucho mayor que" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "entre" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "no equivalente a" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "no menor que" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "no mayor que" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ni menor ni igual a" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ni mayor ni igual a" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "menor que o equivalente a" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "mayor que o equivalente a" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ni menor ni equivalente a" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ni mayor ni equivalente a" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "menor que o mayor que" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "mayor que o menor que" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ni menor ni mayor que" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ni mayor ni menor que" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "precede" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "sucede" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "precede o igual a " - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "sucede o igual a " - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "precede o equivalente a" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "sucede o equivalente a" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "no precede" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "no sucede" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subconjunto de" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superconjunto de" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "no es subconjunto de" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "no es superconjunto de" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subconjunto de o igual a " - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superconjunto de o igual a " - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "no es un subconjunto de, ni igual a" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "no es un superconjunto de, ni igual a " - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subconjunto de, y no igual a" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superconjunto de, y no igual a" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "múltiples conjuntos" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiplicación de múltiples conjuntos" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "unión de múltiples conjuntos" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "cuadrado de la imagen de" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "cuadrado original de" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "cuadrado de la imagen de, o igual a" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "cuadrado de o igual a" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "cuadrado boca abajo" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "cuadrado boca arriba" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "suma en un círculo" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "resta en un círculo" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "producto en un círculo" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "barra de división en un círculo" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "operador punto en un círculo" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operador anillo en un círculo" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operador asterisco en un círculo" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "símbolo igual en un círculo" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "guión alto en un círculo" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "símbolo más en un cuadrado" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "símbolo menos en un cuadrado" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "símbolo por en un cuadrado" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "símbolo operador punto en un cuadrado" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "es probable de, por la derecha" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "es probable de, por la izquierda" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "es verdadero" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "elemento más bajo" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "aserción" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modelos" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "verdadero" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "fuerza" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "triple barra vertical con inserción por la derecha" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "doble barra vertical con insercción por la derecha" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "no prueba" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "no verdadero" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "no fuerza" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "doble barra vertical con insercción doble negada por la derecha" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "precede bajo relación" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "sucede bajo relación" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "subgrupo normal de" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "contiene un subgrupo normal" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "subgrupo normal de o igual a" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "contenido como un subgrupo normal de o igual a" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original de" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "imagen de" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matriz conjugada hermitiana" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalado" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "operación o exclusiva" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "operación y negada" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "o negada" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ángulo derecho con arco" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triángulo derecho" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operador diamante" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operador punto" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operador estrella" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "sucesivas divisiones" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "pajarita" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "factor normal por la izquierda del producto semidirecto" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "factor normal por la derecha del producto semidirecto" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "producto semidirecto por la izquierda" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "producto semidirecto por la derecha" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "virgulilla invertida igual" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "símbolo or lógico curvado" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "símbolo y lógico curvado" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "subconjunto doble" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "superconjunto doble" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "intersección doble" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "unión doble" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "tridente boca abajo" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "igual y paralelo a" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "menor que con punto" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "mayor que con punto" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "mucho menor que" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "mucho mayor que" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "menor que, igual a, o más grande que" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "mayor que, igual a, o menor que" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "igual o menor que" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "igual o mayor que" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "igual a o precede" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "igual a o sucede" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "no precede o igual" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "no sucede o igual" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "no es un cuadrado de imagen de, o igual a" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "no es cuadrado original de o igual a" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "cuadrado de imagen de, o no igual a" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "cuadrado original de o no igual a" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "menor que pero no equivalente a" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "mayor que pero no equivalente a" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "precede pero no equivalente a" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "sucede pero no equivalente a" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "no es un subgrupo normal de" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "no está contenido como subgrupo normal" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "no es un subgrupo normal de o igual a" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "no está contenido como subgrupo normal o igual" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "elipsis vertical" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "puntos suspensivos a media línea" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "puntos suspensivos en diagonal arriba derecha" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "puntos suspensivos en diagonal abajo derecha" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "elemento de, con barra horizontal larga" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "elemento de, con barra vertical y en su tope una barra horizontal" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"elemento de, con barra vertical y en su tope una barra horizontal, símbolo " -"pequeño" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "elemento de, con un punto encima" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "elemento de, con una barra encima" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "elemento de, con una barra encima, símbolo pequeño" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "elemento de, con una barra debajo" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "elemento de, con dos barras horizontales" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "que contiene, con una barra horizontal larga" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "que contiene, con barra vertical con una barra horizontal en su tope" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"que contiene, con barra vertical y una barra horizontal en su tope, símbolo " -"pequeño" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "que contiene, con barra encima" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "que contiene, con barra encima, símbolo pequeño" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "notación z, miembro de bolsa" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "tope izquierdo" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "tope derecho" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "piso izquierda" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "piso derecha" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "llave superior" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "llave inferior" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "abre corchete" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "cierra corchete" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "punto en un círculo" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "unión con punto" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "unión por símbolo de más" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "intersección cuadrado" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "unión cuadrado" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "cuadrado negro" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "cuadrado en blanco" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "rombo negro" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "círculo en blanco" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "círculo negro" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "viñeta blanca" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "cuadrado pequeño mediano negro" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s con subrayado" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s con barra" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s con alineación vertical" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplicación" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "en blanco" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "negrita" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "marcador introducido" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "marcadores guardados" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "los marcadores no se pueden guardar" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "No se encontraron marcadores." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Marcador no encontrado" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Modo enviar tecla activado." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "No se pudo obtener la pantalla de la calculadora" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "icono" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Estilo de capitalización establecido a icono." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ninguno" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Estilo de capitalización establecido a ninguno." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "deletrear" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Estilo de capitalización establecido a deletrear." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "La aplicación está controlando el cursor." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu está controlando el cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Celda %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s seleccionada" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "Seleccionado de %s a %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "No seleccionado de %s a %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s no seleccionada" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Prevenir el uso de la opción" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Forzar el uso de la opción" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCIÓN" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Argumentos opcionales" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Uso:" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Los siguientes argumentos no son válidos: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Imprimir las aplicaciones conocidas que se están ejecutando" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Cargar perfil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "No se pudo cargar el perfil: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"No se puede iniciar Cthulhu porque no se puede conectar al escritorio.No se " -"puede iniciar el lector de pantalla porque no se puede conectar al " -"Escritorio." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "No se pudo activar el gestor de configuración. Saliendo." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Ya hay otro proceso del lector de pantalla en ejecución para esta sesión.\n" -"Ejecute «cthulhu --replace» para reemplazar el proceso existente con uno " -"nuevo." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOMBRE" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Usar una carpeta alternativa para las preferencias del usuario" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versión de esta aplicación" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" -"Reemplazar una instancia de Cthulhu actualmente en ejecuciónReemplazar una " -"instancia del lector de pantalla actualmente en ejecución" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Mostrar este mensaje de ayuda y salir" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Enviar salida de depuración a debug-AAAA-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Enviar salida de depuración a un archivo especificado" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ARCHIVO" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Configurar las preferencias del usuario (versión sólo texto)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Configurar las preferencias del usuario (versión IGU)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Informe de errores a https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Selección cortada al portapapeles." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "cortado" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Selección copiada al portapapeles." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copiado" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Contenidos pegados del portapapeles." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "pegado" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "No anunciar cuando sus amigos están tecleando." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anunciar cuando sus amigos están tecleando." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Mensaje de la sala de chat %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nueva pestaña de chat %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "No hablar el nombre de la sala de chat." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "hablar el nombre de la sala de chat." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "No proporcionar históricos de mensajes de cada sala de chat." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Proporcionar históricos de mensajes específicos de cada sala de chat." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "inicio de eliminación" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "fin de la eliminación" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "inicio de inserción" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "fin de inserción" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "inicio de resaltado" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "fin de resaltado" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "fin de sugerencia" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Final del contenedor." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "No está en un contenedor." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "todos los elementos seleccionados" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "El botón predeterminado es %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "El botón predeterminado es %s. Desactivado" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Botón predeterminado no encontrado" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " %s subíndice" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "%s superíndice" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "No está en un diálogo." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "todo el documento seleccionado" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "todo el documento no seleccionado" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "documento seleccionado desde la posición del cursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "documento deseleccionado desde la posición del cursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "documento seleccionado hasta la posición del cursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "documento deseleccionado hasta la posición del cursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Cabecera dinámica establecida para la fila %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Cabecera dinámica de columna borrada." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Fila de cabecera dinámica establecida para la columna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Fila de cabecera dinámica borrada." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "vacía" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "No se encontraron archivos." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Contenido añadido al portapapeles." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Contenidos copiados al portapapeles." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "No se está usando la revisión." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Entrando en la revisión." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Saliendo de la revisión." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Revisión restringida al objeto actual" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Revisión no restringida" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "tiene fórmula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "abre el diálogo" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "abre la rejilla" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "abre la lista" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "abre el menú" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "abre el árbol" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "enlace de mapa de imágen" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "La tecla introducida ya está asociada a %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tecla capturada: %s. Pulse Intro para confirmar." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "La tecla nueva es: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Atajo de teclado eliminado. Pulse intro para confirmar." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "El atajo de teclado se ha eliminado." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "introduzca la tecla nueva" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tecla" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Eco establecido a tecla." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ninguna" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Eco establecido a ninguno." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tecla y palabra" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Eco establecido a tecla y palabra." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "frase" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Eco establecido a frase." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "palabra" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Eco establecido a palabra." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "palabra y frase" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Eco establecido a palabra y frase." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Encerrado por: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "un símbolo actuarial" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "una caja" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "un círculo" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "un signo de división larga" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "un radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "una caja redondeada" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "una barra horizontal" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "una barra vertical" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "barra en diagonal abajo derecha" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "barra diagonal hacia arriba" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "flecha nordeste" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "una línea al fondo" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "una línea a la izquierda" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "una línea a la derecha" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "una línea encima" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "un ángulo fasor" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "un símbolo factorial arábico" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "símbolo «y» lógico" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "inicio de fracción" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "fracción sin barra, inicio" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "sobre" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "fin de fracción" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "raíz cuadrada de" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "raíz cúbica de" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "raíz de" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "inicio raíz" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "fin raíz" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subíndice" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "superíndice" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "subíndice previo a la base" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "sobrescritura previa a la base" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "escritura inferior" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "sobrescritura de la base" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "fin de tabla" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "fin de tabla anidada" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "No es accesible" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Desactivada" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Habla del sangrado y justificación desactivada." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Activada" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Habla del sangrado y justificación activada." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Modo de aprendizaje. Pulse escape para salir." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Entrando en modo aprendizaje. Pulse cualquier tecla para oír su función. " -"Para ver la documentación del lector de pantalla, pulse F1. Para obtener una " -"lista de los atajos del lector de pantalla, puse F2. Para obtener una lista " -"de los atajos del lector de pantalla para la aplicación actual, pulse F3. " -"Para salir del modo aprendizaje, pulse la tecla Esc." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "saliendo de la cita." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "saliendo de los detalles." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "saliendo del proveedor." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "saliendo de la figura." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "saliendo del formulario." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "saliendo del banner." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "saliendo del contenido complementario." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "saliendo de la información." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "saliendo del contenido principal." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "saliendo de la navegación." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "saliendo de la región." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "saliendo de la búsqueda." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "saliendo de la lista." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "saliendo del panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "saliendo de la tabla." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "saliendo del consejo." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "saliendo del resumen." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "saliendo de los agradecimientos." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "saliendo del posfijo." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "saliendo del apéndice." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "saliendo de la bibliografía." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "saliendo del capítulo." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "saliendo del colofón." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "saliendo de la conclusión." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "saliendo del reconocimiento." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "saliendo de los créditos." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "saliendo de la dedicatoria." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "saliendo de las notas finales." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "saliendo del epígrafe." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "saliendo del epílogo." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "saliendo de la errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "saliendo del ejemplo." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "saliendo del prefacio." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "saliendo del glosario." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "saliendo del índice." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "saliendo de la introducción." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "saliendo de la lista de páginas." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "saliendo de la parte." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "saliendo del prefacio." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "saliendo del prólogo." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "saliendo del sumario." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "saliendo de preguntas y respuestas." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "saliendo de la sugerencia." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "saliendo de la tabla de contenidos." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "línea seleccionada abajo de la posición del cursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "línea seleccionada arriba de la posición del cursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "línea deseleccionada abajo de la posición del cursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "línea deseleccionada arriba de la posición del cursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Saliendo del modo de aprendizaje." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" -"línea seleccionada desde el inicio hasta la anterior posición del cursor" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" -"línea seleccionada hasta el final desde la anterior posición del cursor" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "enlace" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "misma página" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "mismo sitio" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "sitio diferente" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s enlace a %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "enlace %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "enlace %s visitado" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Use Flecha arriba y Flecha abajo para navegar la lista. Presione Escape para " -"salir." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Se han desactivado todas las regiones activas" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "se ha restaurado el comportamiento de todas las regiones activas" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nivel de comportamiento %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "estableciendo región activa a firme" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "estableciendo región activa a desactivada" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "estableciendo región activa a educada" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "estableciendo región activa a grosera" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Monitorización de regiones activas desactivada" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Monitorización de regiones activas activada" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "no se guardó ningún mensaje de actividad" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "El soporte de regiones activas está desactivado" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "No encontrada" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "No se pudo encontrar la posición actual." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "desactivado" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "activado" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "mal escrita" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Palabra mal escrita: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "El contexto es %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Modo navegación" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Modo foco" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Para activar el modo de foco pulse %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "El modo de foco es pegajoso." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "El modo de navegación es pegajoso." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Modo distribución." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Modo de objeto." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Puntero movido al objeto." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Objeto bajo el ratón («mouse over») no encontrado." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Revisión del ratón desactivada." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Revisión del ratón activada." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Error: no se pudo crear la lista de objetos." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "No hay hijos." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "No hay elemento siguiente." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "No tiene padre." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "No hay elemento anterior." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Navegación simplificada activada." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Navegación simplificada desactivada." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nivel de anidamiento %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Se ha añadido un nuevo elemento" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "No se han encontrado acciones en: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Sin foco" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Ninguna aplicación tiene el foco." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "No hay más citas." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "No hay más botones." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "No hay más casillas." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "No hay más objetos grandes." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "No hay más elementos que se puedan pulsar." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "No hay más cuadros combinados." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "No hay más entradas." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "No hay más campos de formulario." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "No hay más encabezados." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "No hay más encabezados de nivel %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "No hay más marcos internos." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "No hay más imágenes." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "No se encontraron puntos de referencia." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "No hay más enlaces." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "No hay más listas." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "No hay más elementos de lista." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "No hay más regiones activas." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "No hay más párrafos." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "No hay más botones de radio." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "No hay más separadores." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "No hay más tablas." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "No hay más enlaces no visitados." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "No hay más enlaces visitados." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "No hay texto seleccionado." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "No está en un enlace." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificación" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Final" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Principio" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Sin mensajes de notificación" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "dígitos" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Hablar números como dígitos." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "palabras" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Hablar números como palabras." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "desactivado" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "activado" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Cargando. Por favor, espere." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Fin de la carga." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Fin de la carga de %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "La página tiene %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "página seleccionada desde la posición del cursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "página seleccionada hasta la posición del cursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "página deseleccionada desde la posición del cursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "página deseleccionada hasta la posición del cursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "párrafo seleccionado debajo de la posición del cursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "párrafo seleccionado arriba de la posición del cursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "párrafo deseleccionado debajo de la posición del cursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "párrafo deseleccionado arriba de la posición del cursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Ya tiene una instancia del diálogo de preferencias de Cthulhu abierta.\n" -"Ciérrela antes de abrir una nueva." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapositiva %(position)d de %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Perfil establecido a %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "No se encontraron perfiles." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra de progreso %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Todo" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Nivel de puntuación establecido a todo." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "La mayoría" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Nivel de puntuación establecido a la mayoría." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nada" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Nivel de puntuación establecido a ninguno." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Alguna" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Nivel de puntuación establecido a alguno." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Buscando." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Búsqueda completa." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Configuración de Cthulhu recargada." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "El texto seleccionado es: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Selección eliminada." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Selección restaurada." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Texto no seleccionado." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Tamaño: %d, %d. Ubicación: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Anchura: %d. Altura: %d. %d de izquierda. %d desde arriba." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Habla desactivada." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Habla activada." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "más rápido." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "más lento." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "más alto." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "más bajo." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "más fuerte." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "más suave." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Velocidad %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Tono %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volumen %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Módulo de Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Voz de Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "No hay módulos de Speech-dispatcher disponibles" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "No hay voces de Speech-dispatcher disponibles" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Ajustes de voz guardados" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "No se pudieron guardar los ajustes de voz" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Nivel de detalle: breve" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Nivel de detalle: detallado" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "punto punto punto" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu le da la bienvenida." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu acecha bajo las olas." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Modo de suspensión activado para %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Modo de suspensión desactivado para %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "La voz no está disponible." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "No encontrada" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Barra de estado no encontrada" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "cadena no encontrada" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Teclas de navegación estructural desactivadas." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Teclas de navegación estructural activadas." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "No encontrado" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Fila %(row)d, columna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Final de tabla" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Hablar celda" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Hablar fila" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "No-uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "No está en una tabla." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Columnas reordenadas" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Filas reordenadas" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "columna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "columna %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Final de la columna." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Inicio de la columna." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Columna %s seleccionada" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Columnas %s a %s seleccionadas" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Columnas %s a %s no seleccionadas" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Columna %s no seleccionada" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "fila %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "fila %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Comienzo de la fila." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Final de la fila." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Fila eliminada." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Última fila eliminada." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Fila insertada." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Fila insertada al final de la tabla." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Fila %s seleccionada" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Filas %s a %s seleccionadas" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Filas %s a %s no seleccionadas" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Fila %s no seleccionada" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "seleccionado" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "no seleccionado" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H horas, %M minutos y %S segundos" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H horas y %M minutos" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "deshacer" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "rehacer" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Versión %s de Cthulhu." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "espacio en blanco" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Saltando al final." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Saltando al principio." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elementos" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Celda abarca %d fila" -msgstr[1] "Celda abarca %d filas" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d columna" -msgstr[1] " %d columnas" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Celda abarca %d columnas" -msgstr[1] "Celda abarca %d columnas" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d carácter demasiado largo" -msgstr[1] "%d caracteres demasiado largo" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d diálogo)" -msgstr[1] "(%d diálogos)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d diálogo sin foco" -msgstr[1] "%d diálogos sin foco" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d archivo encontrado" -msgstr[1] "%d archivos encontrados" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulario" -msgstr[1] "%d formularios" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d encabezado" -msgstr[1] "%d encabezados" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elemento" -msgstr[1] "%d elementos" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d punto de referencia" -msgstr[1] "%d puntos de referencia" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d elemento encontrado" -msgstr[1] "%d elementos encontrados" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Saliendo de %d cita." -msgstr[1] "Saliendo de %d citas." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Saliendo de %d lista." -msgstr[1] "Saliendo de %d listas." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Lista de tamaño desconocido" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista con %d elemento" -msgstr[1] "Lista con %d elementos" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Proveedor de tamaño desconocido" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Proveedor con %d artículo" -msgstr[1] "Proveedor con %d artículos" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Lista de descripciones con %d término" -msgstr[1] "Lista de descripciones con %d términos" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d valor" -msgstr[1] "%d valores" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabla matemática con %d fila" -msgstr[1] "tabla matemática con %d filas" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d columna" -msgstr[1] "%d columnas" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tabla matemática anidada con %d filas" -msgstr[1] "tabla matemática anidada con %d filas" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d mensaje.\n" -msgstr[1] "%d mensajes.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d porciento." -msgstr[1] "%d porciento." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "leído %d por ciento del documento" -msgstr[1] "leído %d por ciento del documento" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d píxel" -msgstr[1] "%d píxeles" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d carácter %(repeatChar)s" -msgstr[1] "%(count)d caracteres %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d de %(total)d elemento seleccionado" -msgstr[1] "%(index)d de %(total)d elementos seleccionados" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Se encontró %d atajo predeterminado del lector de pantalla." -msgstr[1] "Se encontraron %d atajos predeterminados del lector de pantalla." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Se encontró %(count)d atajo del lector de pantalla para la aplicación " -"%(application)s." -msgstr[1] "" -"Se encontraron %(count)d atajos del lector de pantalla para la aplicación " -"%(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espacio" -msgstr[1] "%d espacios" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulador" -msgstr[1] "%d tabuladores" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabla" -msgstr[1] "%d tablas" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabla de tamaño desconocido" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabla con %d columna, número de filas desconocido" -msgstr[1] "tabla con %d columnas, número de filas desconocido" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabla con %d fila, número de columnas desconocido" -msgstr[1] "tabla con %d filas, número de columnas desconocido" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabla con %d fila" -msgstr[1] "tabla con %d filas" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "hace %d segundo" -msgstr[1] "hace %d segundos" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "hace %d minuto" -msgstr[1] "hace %d minutos" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "hace %d hora" -msgstr[1] "hace %d horas" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "Hace %d día" -msgstr[1] "hace %d días" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d enlace no visitado" -msgstr[1] "%d enlaces no visitados" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d enlace visitado" -msgstr[1] "%d enlaces visitados" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "conmutar" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "sobre %(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "elemento %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nivel de árbol %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVEL DE ÁRBOL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detalles para %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "tiene detalles en %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "sugerencia" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "cuadro combinado editable" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "contenido editable" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "proveedor" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figura" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "resumen" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "agradecimientos" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "posfijo" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "apéndice" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "entrada de la bibliografía" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografía" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "capítulo" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colofón" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conclusión" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "cubierta" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "reconocimiento" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "créditos" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedicatoria" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "nota final" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "notas finales" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epígrafe" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epílogo" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "ejemplo" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "prefacio" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosario" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "índice" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introducción" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "salto de página" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "lista de páginas" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "parte" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "prefacio" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prólogo" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "sumario" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Preguntas y respuestas" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "subtítulo" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "tabla de contenidos" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "e%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivel %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "barra de desplazamiento horizontal" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "barra de desplazamiento vertical" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "deslizador horizontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "deslizador vertical" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "separador horizontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "separador vertical" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "interruptor" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Icono del panel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "banner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "contenido adicional" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "información" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "contenido principal" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navegación" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "región" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "búsqueda" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "enlace visitado" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "botón del menú" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "ordenada de manera ascendente" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "ordenada de manera descendente" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "ordenada" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "se puede pulsar" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "contraído" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "expandido" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "tiene una descripción larga" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "marcada" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "no marcada" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "activado" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "desactivado" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "marcada parcialmente" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "pulsado" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "no pulsado" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "no seleccionado" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "seleccionado" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "no seleccionado" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "no seleccionado" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visitado" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "no visitado" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "sombreado" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "sólo lectura" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "sólolec" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "requerido" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "selección-múltiple" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "entrada no válida" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "no válido" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "falta ortográfica" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ortografía" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "gramática no válida" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramática" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Buscar" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Diálogo de búsqueda del lector de pantalla" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Cerrar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Buscar" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Buscar:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Buscar:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Parte _superior de la ventana" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Parte superior de la ventana" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Empezar en:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Salto" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Buscar hacia a_trás" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Dirección de búsqueda:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Coincidir con mayúsculas" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Coincidir sólo con la palabra _entera" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opciones:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Predeterminado" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Mayúscula" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiperenlace" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicación" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Ventana" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferencias de Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Ayuda" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Aplicar" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Portátil" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Distribución de teclado" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Perfil activo:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Perfil inicial:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Cargar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Guardar _como" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Quitar" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Perfiles" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Presentar consejos" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Hablar el objeto debajo del ra_tón." - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Ratón" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Formato de _hora:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formato de f_echa:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Fecha y hora" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Hablar actualizaciones" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Actualizaciones en _Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frecuencia (segs):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplica a:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "So_nar actualizaciones" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Actualizaciones de barras de progreso" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Activar _ir hacia atrás y avance rápido en Hablar todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Activar la navegación e_structural en Hablar todo" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Hablar todo _por:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Anunciar _citas en Hablar todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Anunciar lis_tas en Hablar todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Anunciar _tablas en Hablar todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Anunciar _paneles en Hablar todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Anunciar _formularios en Hablar todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Anunciar puntos de _referencia en Hablar todo" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Hablar todo" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Presentación del elemento:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "General" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Volumen:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Tono:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Velocidad:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persona:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Idioma:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "_Sintetizador de voz:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Sistema de _voz:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipo de _voz:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Estilo de _capitalización:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Configuración del tipo de voz" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Hablar cadenas con mayúsculas y minúsculas como _palabras" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Hablar núme_ros como dígitos" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Configuración global de voz" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Activar Habla" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Extendida" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Cantidad de información" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Toda" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr ">Nivel de puntuación" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Hablar solamente el texto mostrado" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Hablar líneas en blanco" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Hablar _sangrado y justificación" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Hablar _las teclas de acceso del objeto" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Hablar la p_osición del hijo" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Hablar mensajes de aprendizaje" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Los mensajes del _sistema son detallados" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Ha_blar colores como nombres" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Anunciar _citas durante la navegación" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Anunciar _listas durante la navegación" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Anunciar _tablas durante la navegación" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Hablar el indicador de palabra _mal escrita" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Anunciar _paneles durante la navegación" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Anunciar puntos de _referencia durante la navegación" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Anunciar _formularios durante la navegación" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Hablar _descripción" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Hablar fila completa en _hojas de cálculo" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Hablar fila completa en tablas del _documento" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Hablar fila completa en tablas de la _IGU" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Contexto hablado" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Hablar" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Activar _soporte Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Nombre de roles _abreviados" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Desactivar el símbolo de _fin de línea" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tabla de contracción:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Activar Braille contraído" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Activar ajuste de _palabras" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Configuración de pantalla" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Ninguno" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicador de selección" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicador de hiperenlace" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Activar _mensajes temporales" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "D_uración (segs):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Los mensajes son _persistentes" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Los mensajes son _detallados" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Configuración de mensajes temporales" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Activar _eco de teclas" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Activar teclas _alfabéticas" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Activar teclas _numéricas" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Activar teclas de p_untuación" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Activar _espacio" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Activar teclas _modificadoras" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Activar teclas de _función" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Activar teclas de _acción" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Activar teclas de _navegación" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Activar eco por _palabras" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Activar eco por _frases" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Eco" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Teclas _modificadoras del lector de pantalla:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Atajos de teclado" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Diccionario de pronunciación" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Entrada _nueva" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Eliminar" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronunciación" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Hablar _todo" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_No hablar nada" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Restablecer" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributos de texto" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mover al _final" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mover uno _abajo" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mover uno a_rriba" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mover al _principio" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Ajustar el atributo seleccionado" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicador Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributos de texto" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Activar asistente de IA" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Proveedor:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Local - Gratis)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Archivo de clave _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Ruta al archivo de clave API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Obtener clave API de _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Abrir el navegador para obtener la clave API de Claude y guardarla " -"automáticamente" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Requerir confirmación antes de acciones de IA" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Modelo Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nombre del modelo para Ollama (p. ej., llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Punto de acceso Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" -"URL del punto de acceso API de Ollama (p. ej., http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Calidad de captura de pantalla:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Bajo" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Medio" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Alto" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Asistente de IA" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Código de _idioma:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Factor de _escala:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Imagen en escala de _grises" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Invertir imagen" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Imagen en _blanco y negro" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Umbral blanco/negro:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analizar colores" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Copiar resultados al _portapapeles" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alfa, b : bravo, c : charli, d : delta, e : eco, f : foxtrot, g : golf, " -"h : hotel, i : india, j : yuliet, k : kilo, l : lima, m : maik, n : " -"novémber, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : úniform, v : victor, w : whisky, x : xray, y : yanki, z : zulú" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "color de fondo" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "altura completa del fondo" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "fondo punteado" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "dirección" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editable" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nombre de la tipografía" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "color de primer plano" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "primer plano puenteado" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efecto de tipografía" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "sangrado" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "error" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justificación" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "idioma" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "margen izquierdo" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "altura de la línea" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "estilo de párrafo" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "píxeles por encima de las líneas" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "píxeles por debajo de las líneas" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "píxeles dentro de la línea" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "margen derecho" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "comienzo" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "escala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "tamaño" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "estirar" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "tachado" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estilo" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decoración del texto" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotación del texto" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "texto sombreado" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "subrayado" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variante" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "alineación vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "anchura" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "modo expandido" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "modo de escritura" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "verdadero" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falso" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ninguno" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "grabar" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "membrete" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "resumen" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "suprarayado" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "tachado" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "parpadeo" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "negra" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "sencillo" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "doble" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "bajo" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "carácter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "palabra" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "separación" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "I-->D" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "D-->I" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "izquierda" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "derecha" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centrado" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "sin justificación" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "completa" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensado" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensado" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensado" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensado" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi expandido" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expandido" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra expandido" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra expandido" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "mayúsculas pequeñas" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblicuo" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "cursiva" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Predeterminado" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Cuerpo del texto" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Encabezado" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "en línea" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "subíndice" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super índice" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "superior" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "texto-superior" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "medio" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "inferior" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "texto-inferior" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "heredar" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "izde-arab" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "deiz-arab" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "arab-deiz" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "arab-izde" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "abar-deiz" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "abar-izde" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "izde" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "deiz" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "arab" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "tachado" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "falta ortográfica" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Pulse espacio para conmutar." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Pulse espacio para expandir y use flecha arriba y flecha abajo para " -"seleccionar un elemento." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Pulse Alt+f6 para dar el foco a las ventanas hijas." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "Para moverse a los elementos, use las flechas o escriba para búsqueda." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Para ir a los menús del sistema pulse la tecla alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Use flecha arriba o flecha abajo para seleccionar un elemento." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Para contraer pulse mayúscula y flecha izquierda." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Para expandir pulse mayúscula más flecha derecha." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Para activar pulse Intro." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Escriba un texto." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Use flecha izquierda y flecha derecha para ver otras pestañas." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Para activar pulse espacio." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Use flecha arriba o flecha abajo para seleccionar un valor. O teclee el " -"valor numérico que desee." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Para cambiar use las flechas." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Para navegar pulse flecha izquierda o flecha derecha. Para moverse entre los " -"elementos pulse flecha arriba o flecha abajo." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Para entrar en el submenú pulse flecha derecha." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Para decrementar pulse flecha izquierda, para incrementar pulse flecha " -"derecha, para el mínimo pulse inicio y para el máximo pulse fin." diff --git a/po/et.po b/po/et.po deleted file mode 100644 index 6666f1e..0000000 --- a/po/et.po +++ /dev/null @@ -1,9658 +0,0 @@ -# Cthulhu eesti keele tõlge. -# Estonian translation of Cthulhu. -# -# Copyright (C) 2006-2008, The Gnome Project. -# This file is distributed under the same license as the cthulhu package. -# -# Ivar Smolin , 2006-2008. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2010-10-06 18:31+0300\n" -"Last-Translator: Ivar Smolin \n" -"Language-Team: Estonian \n" -"Language: et\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu ekraanilugeja ja luup" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -#, fuzzy -msgid "alrt" -msgstr "katus" - -#: src/cthulhu/braille_rolenames.py:54 -#, fuzzy -msgid "anim" -msgstr "animatsioon" - -#: src/cthulhu/braille_rolenames.py:57 -#, fuzzy -msgid "arw" -msgstr "nool" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -#, fuzzy -msgid "icn" -msgstr "ikoon" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "dialoog" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -#, fuzzy -msgctxt "shortbraille" -msgid "form" -msgstr "%d vorm" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -#, fuzzy -msgid "cll" -msgstr "lahter" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -#, fuzzy -msgid "tre" -msgstr "puu" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "tühik" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "reavahetus" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulaator" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "hüüumärk" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "jutumärk" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "protsent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostroof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "vasak sulg" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "parem sulg" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "tärn" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "pluss" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "koma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "mõttekriips" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punkt" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "kaldkriips" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "koolon" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semikoolon" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "võrdusmärk" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "küsimärk" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "vasak nurksulg" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "langkriips" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "parem nurksulg" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "katus" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "alakriips" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "graavis" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "vasak loogiline sulg" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "püstkriips" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "parem loogiline sulg" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "murdmatu tühik" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "paragrahv" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -#, fuzzy -msgid "diaeresis" -msgstr "kraadi" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "autoriõigus" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "kraadi" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "kuubis" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -#, fuzzy -msgid "acute" -msgstr "tühik" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "müü" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "keskpunkt" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "üks neljandik" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "üks kahendik" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "kolm neljandikku" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promilli" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -#, fuzzy -msgid "superscript 0" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:676 -#, fuzzy -msgid "superscript 4" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:680 -#, fuzzy -msgid "superscript 5" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:684 -#, fuzzy -msgid "superscript 6" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:688 -#, fuzzy -msgid "superscript 7" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:692 -#, fuzzy -msgid "superscript 8" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:696 -#, fuzzy -msgid "superscript 9" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:700 -#, fuzzy -msgid "superscript plus" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:704 -#, fuzzy -msgid "superscript minus" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:708 -#, fuzzy -msgid "superscript equals" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:720 -#, fuzzy -msgid "superscript n" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:724 -#, fuzzy -msgid "subscript 0" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:728 -#, fuzzy -msgid "subscript 1" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:732 -#, fuzzy -msgid "subscript 2" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:736 -#, fuzzy -msgid "subscript 3" -msgstr "kuubis" - -#: src/cthulhu/chnames.py:740 -#, fuzzy -msgid "subscript 4" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:744 -#, fuzzy -msgid "subscript 5" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:748 -#, fuzzy -msgid "subscript 6" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:752 -#, fuzzy -msgid "subscript 7" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:756 -#, fuzzy -msgid "subscript 8" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:760 -#, fuzzy -msgid "subscript 9" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:764 -#, fuzzy -msgid "subscript plus" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:772 -#, fuzzy -msgid "subscript equals" -msgstr "ruudus" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "vasak sulg" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "parem sulg" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "kogu dokument on valitud" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "kogu dokument on valitud" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "olekuriba" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "olekuriba" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Õppimisrežiim. Väljumiseks vajuta escape." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Eelistatava kõnesüsteemi valimine:" - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Eelistatava kõnesüsteemi valimine:" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "Eelistuste määramise dialoogi kuvamine." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "Rakenduse eelistuste määramise dialoogi kuvamine." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "Kõnesün_tesaator:" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "järjehoidja on salvestatud" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -#, fuzzy -msgid "Freeze" -msgstr "Puu" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "Ekraani alumisel poolel" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "Kursori suurus:" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "Kohandatud _suurus" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "Suuri objekte rohkem ei ole." - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "_Navigatsiooniklahvid on lubatud" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Kuva rohkem valikuid" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Rohkem märkeruute ei ole." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Rohkem märkeruute ei ole." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "Rohkem valikukaste ei ole." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Rohkem valikukaste ei ole." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l konteiner" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l konteiner" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "Rohkem vormivälju ei ole." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "Rohkem vormivälju ei ole." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "Rohkem päiseid ei ole." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "Rohkem päiseid ei ole." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Rohkem %d. taseme päiseid ei ole." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Rohkem %d. taseme päiseid ei ole." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Rohkem %d. taseme päiseid ei ole." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Suuri objekte rohkem ei ole." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Suuri objekte rohkem ei ole." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Suuri objekte rohkem ei ole." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "Külastatud viitasid rohkem ei ole." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Kuva rohkem valikuid" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "Rohkem loetelusid ei ole." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Rohkem loetelupunkte ei ole." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Rohkem loetelupunkte ei ole." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "Rohkem lõike ei ole." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "Rohkem raadionuppe ei ole." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "raadionupp" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "Rohkem tabeleid ei ole." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "Rohkem tabeleid ei ole." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "parem control" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "_Klahvi kaja on lubatud" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "Külastamata viitasid rohkem ei ole." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "Külastamata viitasid rohkem ei ole." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "Külastamata viitasid rohkem ei ole." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "Külastatud viitasid rohkem ei ole." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "Külastatud viitasid rohkem ei ole." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "Külastatud viitasid rohkem ei ole." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "tühi" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "kraadi" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "parem loogiline sulg" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "parem control" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "parem sulg" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "parem loogiline sulg" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "parem sulg" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "parem sulg" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "parem alt" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "parem sulg" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "parem sulg" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "nool paremale" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "reavahetus" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Pilt" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "sekundi järel" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "kraadi" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "tabulaator" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "Täisekraan" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikoon" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Puudub" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "Õigekirjakontroll" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Vaikimisi süntesaator" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Tegelik string" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Asendusstring" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "_Klahvi kaja on lubatud" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "_Navigatsiooniklahvid on lubatud" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "koma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Kiirklahv" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "Vaikimisi" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Õppimisvaatest väljumine." - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "paragrahv" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "järjehoidja on salvestatud" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "_Navigatsiooniklahvid on lubatud" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Töölauaarvuti" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Rakendus" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Rakendus" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "lahter" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "Rakendus" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "Aken" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "_Puudub" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "jutumärk" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Nupp" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "rakendus" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "MärkeRuut" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "ruudus" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Päis" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Pilt" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Silt" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "Loetelu" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "%d kirjega nimekiri" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Lõik" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "RaadioNupp" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "valitud" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Tekst" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "jutumärk" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Nupp" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "MärkeRuut" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "Päis" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Pilt" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Rohkem %d. taseme päiseid ei ole." - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Suuri objekte rohkem ei ole." - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "Loetelu" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Lõik" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "RaadioNupp" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabel" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d külastamata viit" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d külastatud viit" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "Vaikimisi" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hüperviit" - -#: src/cthulhu/guilabels.py:844 -#, fuzzy -msgctxt "VoiceType" -msgid "System" -msgstr "term" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "protsent" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "_Navigatsiooniklahvid on lubatud" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Rakendus" -msgstr[1] "Rakendus" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "lahter" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "vasak control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "vasak shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "vasak alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "vasak control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "parem shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "parem alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "parem control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "vasak meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "parem meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "vasak tab" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "tühik" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "Üldine" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "page down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "vasak alt" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "parem alt" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "vasak sulg" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "parem sulg" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menüü" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -#, fuzzy -msgid "mode switch" -msgstr "MenüüKirje" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -#, fuzzy -msgid "insert" -msgstr "Loetelu" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -#, fuzzy -msgid "delete" -msgstr "_Kustuta" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "sekundi järel" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -#, fuzzy -msgid "ring" -msgstr "parem alt" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "puu" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "miinus" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "Loetelu" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "vigane" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "ruudus" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "ruudus" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Tööala " - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "nool vasakule" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "nool" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "nool paremale" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "nool" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "nool paremale" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "nool paremale" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "nool paremale" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "nool vasakule" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "nool vasakule" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "nool paremale" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "nool vasakule" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "nool vasakule" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "nool paremale" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "nool paremale" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "nool paremale" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "nool paremale" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "miinus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "punkt" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "püstkriips" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "rõhtne" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "automaatlõpetamine" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "tühi" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "Äär_is on lubatud" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "pluss" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "miinus" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "eraldaja" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "Proportsionaalne" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "parem alt" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "kihiline paan" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "püstkriips" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Eraldaja" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "paragrahv" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "Uuendatakse iga" - -#: src/cthulhu/mathsymbols.py:1512 -#, fuzzy -msgctxt "math symbol" -msgid "triple integral" -msgstr "Uuendatakse iga" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -#, fuzzy -msgctxt "math symbol" -msgid "surface integral" -msgstr "Uuendatakse iga" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "Proportsionaalne" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "miinus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "võrdusmärk" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "võrdusmärk" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "võrdusmärk" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "püstine" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "vajutamata" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "ruudus" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "ruudus" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "ruudus" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "paragrahv" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "ruudus" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "ruudus" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "ruudus" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "parem meta" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "vasak tab" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "page down" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "paragrahv" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "puu" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "puu" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "pilt" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "Üldine" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "parem alt" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "parem loogiline sulg" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "eraldaja" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "vasak sulg" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "paragrahv" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "püstkriips" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "vasak sulg" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "parem sulg" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "vasak alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "parem alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "vasak loogiline sulg" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "_All:" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "vasak nurksulg" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "parem nurksulg" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "keskpunkt" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "alakriips" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "püstkriips" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "rakendus" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "tühi" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "järjehoidja on salvestatud" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "järjehoidjaid pole võimalik salvestada" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "järjehoidja on salvestatud" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ikoon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "Puudub" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "Õigekirjakontroll" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, fuzzy, python-format -msgid "Cell %s" -msgstr "Lahter" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "valitud" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "valitud" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Valiku vältimine" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Valiku jõuga pealesurumine" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "järjehoidjaid pole võimalik salvestada" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Kasutaja eelistuste jaoks alternatiivse kataloogi kasutamine" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "Asendusstring" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "Selle abiteabe näitamine" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Kasutajate eelistuste seadmine (tekstiversioon)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "Kasutajate eelistuste seadmine (tekstiversioon)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Vigadest palun teatada aadressil https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "tühik" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "kiirem." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, fuzzy, python-format -msgid "Message from chat room %s" -msgstr "Sõnum jututoast " - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "_Kustuta" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "Loetelu" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "küsimärk" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "%d tabel" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "h t m l konteiner" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "valitud" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, fuzzy, python-format -msgid " subscript %s" -msgstr "ruudus" - -#: src/cthulhu/messages.py:524 -#, fuzzy, python-format -msgid " superscript %s" -msgstr "ruudus" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "kogu dokument on valitud" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "kogu dokument on valitud" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "tühi" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Ühtki faili ei leitud." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "dialoog" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "hüpikmenüü" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "_Klahvi kaja on lubatud" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "Puudub" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "_Klahvi kaja on lubatud" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "valitud" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "_Klahvi kaja on lubatud" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "Parool" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "_Klahvi kaja on lubatud" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "rõhtne" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "püstkriips" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "nool paremale" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "sekundi järel" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "alakriips" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "ruudus" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "ruudus" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "ruudus" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "ruudus" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "alakriips" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "ruudus" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "tabel" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Tabel" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Äär_is on lubatud" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Õppimisrežiim. Väljumiseks vajuta escape." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "animatsioon" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "_Navigatsiooniklahvid on lubatud" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Õppimisrežiimist väljumine." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "viit" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d külastatud viit" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "Ühtki faili ei leitud." - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "soffice" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "page down" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "Probleemne sõna:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Probleemne sõna: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Suuri objekte rohkem ei ole." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Luup on keelatud." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Luup on lubatud." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d protsenti." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Rohkem nuppe ei ole." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Rohkem märkeruute ei ole." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Suuri objekte rohkem ei ole." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Rohkem tabeleid ei ole." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Rohkem valikukaste ei ole." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Rohkem kirjeid ei ole." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Rohkem vormivälju ei ole." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Rohkem päiseid ei ole." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Rohkem %d. taseme päiseid ei ole." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "Rohkem tabeleid ei ole." - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "Rohkem tabeleid ei ole." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "Rohkem loetelusid ei ole." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Rohkem loetelusid ei ole." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Rohkem loetelupunkte ei ole." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Rohkem lõike ei ole." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Rohkem raadionuppe ei ole." - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "Rohkem lõike ei ole." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Rohkem tabeleid ei ole." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Külastamata viitasid rohkem ei ole." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Külastatud viitasid rohkem ei ole." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "valimata" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "Külastatud viitasid rohkem ei ole." - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "Rakendus" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "_All:" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "_Üleval:" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "Parool" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "Ühtki faili ei leitud." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Edenemisriba %d." - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "lahter" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "Puudub" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu kasutajasätted on uuesti laaditud." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "_Kustuta" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Eelistatava hääle valimine:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "valimata" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Kõne keelatud." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Kõne lubatud." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "kiirem." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "aeglasem." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "kõrgem." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "madalam." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "kiirem." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Va_ljus:" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Servereid pole saadaval.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Hääli pole saadaval.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Kõne lubatud." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "Kõne ei kasutata.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " punkt punkt punkt" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Cthulhu eelistused" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Kõne pole saadaval." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Ühtki faili ei leitud." - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "olekuriba" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "Ühtki faili ei leitud." - -#: src/cthulhu/messages.py:2380 -#, fuzzy, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Rida %d, veerg %d." - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "%d tabel" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "VeeruPäis" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "veerg %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "valitud" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "valitud" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "rida %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "_Kustuta" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -#, fuzzy -msgid "Row inserted." -msgstr "Loetelu" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "_Kustuta" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "valitud" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "valitud" - -#: src/cthulhu/messages.py:2521 -#, fuzzy -msgctxt "text" -msgid "unselected" -msgstr "valitud" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu eelistused" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 kirjet" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d veerg" -msgstr[1] "%d veergu" - -#: src/cthulhu/messages.py:2593 -#, fuzzy, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "%d veerg" -msgstr[1] "%d veergu" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialoog)" -msgstr[1] "(%d dialoogi)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "leiti %d fail" -msgstr[1] "leiti %d faili" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d vorm" -msgstr[1] "%d vormi" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "MenüüKirje" -msgstr[1] "MenüüKirje" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "leiti %d fail" -msgstr[1] "leiti %d faili" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d kirjega nimekiri" -msgstr[1] "%d kirjega nimekiri" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "%d kirjega nimekiri" -msgstr[1] "%d kirjega nimekiri" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d veerg" -msgstr[1] "%d veergu" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, fuzzy, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d tühik" -msgstr[1] "%d tühikut" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d protsenti." -msgstr[1] "%d protsenti." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d tühik" -msgstr[1] "%d tühikut" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulaator" -msgstr[1] "%d tabulaatorit" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabel" -msgstr[1] "%d tabelit" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d külastamata viit" -msgstr[1] "%d külastamata viita" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d külastatud viit" -msgstr[1] "%d külastatud viita" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "TASE %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "küsimärk" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "tabel" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "h t m l konteiner" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "Parool" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "koolon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "alakriips" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "paragrahv" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "lõik" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "Parool" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "Loetelu" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "paragrahv" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "page up" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "jutumärk" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "h t m l konteiner" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "rõhtne" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "püstkriips" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "rõhtne" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "püstkriips" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "rõhtne" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "püstkriips" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "MenüüKirje" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Ikoonipaneel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "h t m l konteiner" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Animatsioon" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "h t m l konteiner" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Animatsioon" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d külastatud viit" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "nupp" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "ahendatud" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "laiendatud" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "rõhtne" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "püstine" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "märgitud" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "märkimata" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "page down" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "soffice" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "osaliselt märgitud" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "vajutatud" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "vajutamata" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "valimata" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "valitud" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "valimata" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "valimata" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d külastatud viit" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d külastamata viit" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -#, fuzzy -msgctxt "text" -msgid "rdonly" -msgstr "page down" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "vigane" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "vigane" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "Õigekirjakontroll" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "Õigekirjakontroll" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "vigane" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "Ekraanilugeja ja luup" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -#, fuzzy -msgid "Search for:" -msgstr "Eraldaja" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "paragrahv" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "rakendus" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Vaikimisi" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hüperviit" - -#: src/cthulhu/cthulhu-setup.ui:52 -#, fuzzy -msgid "System" -msgstr "term" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Rakendus" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Aken" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu eelistused" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Sülearvuti" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "Klaviatuuripaigutus" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Rakendus" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "edenemisriba" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "_Navigatsiooniklahvid on lubatud" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Üldine" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Va_ljus:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Isik:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Kõnesün_tesaator:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Kõ_nesüsteem:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "_Hääle sätted:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "_Hääle sätted:" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "_Hääle sätted:" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Kõne on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "Hääldus" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Kõne" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Braille _tugi on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Äär_is on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "Kuva rohkem valikuid" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "_Puudub" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "Valiku näidik" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "Hüperviida näidik" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "_Luup on lubatud" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "_Klahvi kaja on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "_Navigatsiooniklahvid on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "_Muuteklahvid on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "_Funktsiooniklahvid on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "_Kõne on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "_Muuteklahvid on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "_Funktsiooniklahvid on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "_Navigatsiooniklahvid on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "_Klahvi kaja on lubatud" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Klahvi kaja" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Ekraanilugeja ja luup" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "Häälduste sõnaraamat" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Uus kirje" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Kustuta" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Hääldus" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "kursiiv" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "Braille näidik" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "Assistent" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "madalam." - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "Assistent" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "sekundi järel" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "Suu_rendusaste:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "paragrahv" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "tabel" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -#, fuzzy -msgctxt "textattr" -msgid "foreground color" -msgstr "Äärise värvus:" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -#, fuzzy -msgctxt "textattr" -msgid "font effect" -msgstr "valimata" - -#: src/cthulhu/text_attribute_names.py:132 -#, fuzzy -msgctxt "textattr" -msgid "indent" -msgstr "Loetelu" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -#, fuzzy -msgctxt "textattr" -msgid "justification" -msgstr "paragrahv" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "vasak sulg" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "lõigu laad" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "parem sulg" - -#: src/cthulhu/text_attribute_names.py:221 -#, fuzzy -msgctxt "textattr" -msgid "rise" -msgstr "Loetelu" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "kalender" - -#: src/cthulhu/text_attribute_names.py:234 -#, fuzzy -msgctxt "textattr" -msgid "size" -msgstr "liugur" - -#: src/cthulhu/text_attribute_names.py:243 -#, fuzzy -msgctxt "textattr" -msgid "stretch" -msgstr "puu" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -#, fuzzy -msgctxt "textattr" -msgid "style" -msgstr "tilde" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "alakriips" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "püstkriips" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "parem alt" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -#, fuzzy -msgctxt "textattr" -msgid "writing mode" -msgstr "Õppimisrežiimist väljumine." - -#: src/cthulhu/text_attribute_names.py:341 -#, fuzzy -msgctxt "textattr" -msgid "true" -msgstr "puu" - -#: src/cthulhu/text_attribute_names.py:349 -#, fuzzy -msgctxt "textattr" -msgid "false" -msgstr "kiirem." - -#: src/cthulhu/text_attribute_names.py:358 -#, fuzzy -msgctxt "textattr" -msgid "none" -msgstr "Puudub" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -#, fuzzy -msgctxt "textattr" -msgid "outline" -msgstr "alakriips" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "alakriips" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "viit" - -#: src/cthulhu/text_attribute_names.py:407 -#, fuzzy -msgctxt "textattr" -msgid "black" -msgstr "tühi" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "madalam." - -#: src/cthulhu/text_attribute_names.py:435 -#, fuzzy -msgctxt "textattr" -msgid "char" -msgstr "katus" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "Parool" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "puu" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "vasak alt" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "parem alt" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "Üldine" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -#, fuzzy -msgctxt "textattr" -msgid "extra condensed" -msgstr "laiendatud" - -#: src/cthulhu/text_attribute_names.py:521 -#, fuzzy -msgctxt "textattr" -msgid "condensed" -msgstr "sekundi järel" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "sekundi järel" - -#: src/cthulhu/text_attribute_names.py:535 -#, fuzzy -msgctxt "textattr" -msgid "normal" -msgstr "Üldine" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "laiendatud" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "laiendatud" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "laiendatud" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "laiendatud" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -#, fuzzy -msgctxt "textattr" -msgid "italic" -msgstr "vigane" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "Vaikimisi" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "Tekst" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "Päis" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "reavahetus" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -#, fuzzy -msgctxt "textattr" -msgid "super" -msgstr "vasak sulg" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "_Sülearvuti" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "tekst" - -#: src/cthulhu/text_attribute_names.py:648 -#, fuzzy -msgctxt "textattr" -msgid "middle" -msgstr "keskpunkt" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "_All:" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -#, fuzzy -msgctxt "textattr" -msgid "inherit" -msgstr "Loetelu" - -#: src/cthulhu/text_attribute_names.py:677 -#, fuzzy -msgctxt "textattr" -msgid "lr-tb" -msgstr "katus" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -#, fuzzy -msgctxt "textattr" -msgid "tb-rl" -msgstr "tabel" - -#: src/cthulhu/text_attribute_names.py:698 -#, fuzzy -msgctxt "textattr" -msgid "tb-lr" -msgstr "tabel" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "katus" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "tabulaator" - -#: src/cthulhu/text_attribute_names.py:738 -#, fuzzy -msgctxt "textattr" -msgid "solid" -msgstr "liugur" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "Õigekirjakontroll" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -#, fuzzy -msgid "To get to the system menus press the alt+f1 key." -msgstr "Õppimisrežiimist väljumiseks vajuta escape klahvi." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/eu.po b/po/eu.po deleted file mode 100644 index 4d1dded..0000000 --- a/po/eu.po +++ /dev/null @@ -1,9216 +0,0 @@ -# Basque translation of cthulhu. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# -# Iñaki Larrañaga Murgoitio , 2008, 2009, 2010, 2011. -# Iñaki Larrañaga Murgoitio , 2012, 2013, 2014, 2015. -# Asier Sarasua Garmendia , 2019, 2020, 2021, 2022, 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-13 10:00+0100\n" -"Last-Translator: Asier Sarasua Garmendia \n" -"Language-Team: Basque \n" -"Language: eu\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu pantaila-irakurlea" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "pantaila;irakurlea;irisgarritasuna;mintzamena;braillea;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "gzia" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "egut" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "Oihl" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "Epgr" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "kt-l" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "kol-auk" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "zt-goib" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "konb" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "data" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "Ikn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "mrk" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "markatu" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "elk-k" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dirp" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "mrrzk" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "ftx-auk" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "bttz" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "ltr-t" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "inprimakia" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "png" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "iznb" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "irud" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "brn-m" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "Etk" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "gruz-p" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "estk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "zrrnd" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "zrrnd-e" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuel" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "aukpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "orr" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tbzrr" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "psh" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "lstrmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "bt" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "aukbt" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "aukmnel" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "errpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "errn-goib" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "korrbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "korrpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "skz" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "brzle" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "Grdtzl" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "ztpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "birbt" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "egbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "taul" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "glxka" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "mnbrzel" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tst" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "txndbt" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "trsnbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "argb" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "zuh" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "zuhtl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "ezez" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "leihtl" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "leiho" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "Goib" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "Orroin" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "pargr" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apl" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "kapts" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Txekiera 1. maila" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Gaztelania 1. maila" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanadako frantsesa 2. maila" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Frantziako frantsesa 2. maila" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letoniera 1. maila" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Herbeherako nederlandera 1. maila" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvegiera 0. maila" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvegiera 1. maila" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvegiera 2. maila" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvegiera 3. maila" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Poloniera 1. maila" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugesa 1. maila" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Suediera 1. maila" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabiera 1. maila" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galesera 1. maila" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galesera 2. maila" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemana 0. maila" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemana 1. maila" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemana 2. maila" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "EBko ingelesa 2. maila" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "EBko ingelesa 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "AEB Ingeleseko 1. maila" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "AEB Ingeleseko 2. maila" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadako frantsesa 1. maila" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Frantziako frantsesa 1. maila" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Greziera 1. maila" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindiera 1. maila" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Hungariera 8 puntu ordenagailua" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hungariera 1. maila" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Hungariera 2. maila" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiera 1. maila" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgikako nederlandera 1. maila" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "zuriunea" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "lerro berria" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulazioa" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "harridura-marka" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "komatxo bikoitza" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "traola" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolarraren ikurra" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "ehunekoaren ikurra" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "eta" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrofea" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "ezker-parentesia" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "eskuin-parentesia" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "izartxoa" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus zeinua" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "koma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "marratxoa" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "puntua" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "bi puntu" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "puntu eta koma" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "txikiago ikurra" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "berdin ikurra" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "handiago ikurra" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "galdera-marka" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "a bildua" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "ezker-kortxetea" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "alderantzizko barra" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "eskuin-kortxetea" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "azentu zirkunflexua" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "azpimarra" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "azentu kamutsa" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "ezker-giltza" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra bertikala" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "eskuin-giltza" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tileta" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "ez hautsi zuriunea" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "hasierako harridura-marka" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "zentimoaren ikurra" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "libera esterlinaren ikurra" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "monetaren ikurra" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yenaren ikurra" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra bertikal etena" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "sekzio-marka" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "dieresia" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyrightaren ikurra" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a goi-indizea" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "ezkerreko komatxo angeluarrak" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "ez logikoaren ikurra" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "marratxoa" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "marka erregistratuaren R ikurra" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "goi-marra" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "graduaren ikurra" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus-minus ikurra" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "2 goi-indizea" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "3 goi-indizea" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "zorrotza" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "paragrafo-marka" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "erdiko puntua" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "zedila" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 goi-indizea" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinala" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "eskuineko komatxo angeluarrak" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "laurden bat" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "erdi bat" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "hiru laurden" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "hasierako galdera-marka" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a zorrotza" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A KAMUTSA" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ZORROTZA" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A ZIRKUNFLEXUA" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILETDUNA" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A DIERESIDUNA" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A ERAZTUNDUNA" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "ZE HAUTSIA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E KAMUTSA" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ZORROTZA" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E ZIRKUNFLEXUA" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E DIERESIDUNA" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I KAMUTSA" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ZORROTZA" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I ZIRKUNFLEXUA" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I DIERESIDUNA" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILETDUNA" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O KAMUTSA" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ZORROTZA" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O ZIRKUNFLEXUA" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILETDUNA" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O DIERESIDUNA" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "biderketaren ikurra" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O BARRADUNA" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U KAMUTSA" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ZORROTZA" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U ZIRKUNFLEXUA" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U DIERESIDUNA" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ZORROTZA" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "eszett" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a kamutsa" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a zirkunflexua" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tiletduna" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a dieresiduna" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a eraztunduna" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "ze hautsia" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e kamutsa" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e zorrotza" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e zirkunflexua" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e dieresiduna" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i kamutsa" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i zorrotza" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i zirkunflexua" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i dieresiduna" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tiletduna" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o kamutsa" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o zorrotza" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o zirkunflexua" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tiletduna" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o dieresiduna" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "zatiketaren ikurra" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o barraduna" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u zorrotza" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u kamutsa" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u zirkunflexua" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u dieresiduna" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y zorrotza" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y dieresiduna" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y DIERESIDUNA" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florinaren ikurra" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "marra motza" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "ezkerreko komatxo bakuna" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "eskuineko komatxo bakuna" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "komatxo bakun baxua" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "ezkerreko komatxo bikoitza" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "eskuineko komatxo bikoitzak" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "komatxo bikoitz baxua" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "gurutzea" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "gurutze bikoitza" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "buleta" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "bulet triangeluarra" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "milakoaren ikurra" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "lehena ikurra" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "bigarrena ikurra" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "hirugarrena ikurra" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "marratxo-buleta" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euroaren ikurra" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marka erregistratuaren TM ikurra" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "kontrol-marka" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "kontrol-marka lodia" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-formako buleta" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "0 goi-indizea" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "4 goi-indizea" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "5 goi-indizea" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "6 goi-indizea" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "7 goi-indizea" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "8 goi-indizea" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "9 goi-indizea" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "plus goi-indizea" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "minus goi-indizea" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "berdin goi-indizea" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "goi-indizeko ezker-parentesia" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "goi-indizeko eskuin-parentesia" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "goi-indizeko n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "azpi-indizeko 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "azpi-indizeko 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "azpi-indizeko 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "azpi-indizeko 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "azpi-indizeko 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "azpi-indizeko 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "azpi-indizeko 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "azpi-indizeko 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "azpi-indizeko 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "azpi-indizeko 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "azpi-indizeko plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "azpi-indizeko minus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "azpi-indizeko berdin" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "azpi-indizeko ezker-parentesia" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "azpi-indizeko eskuin-parentesia" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "karratu beltza" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "erronbo beltza" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "objektuaren ordezko karakterea" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Bideratu erakuslea uneko elementura" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Ezker-klika egin berrrikuspen laueko uneko elementuan" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Eskuin-klika egin berrrikuspen laueko uneko elementuan" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Irakurri dokumentu osoa" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Irakurri leiho osoa berrrikuspen laua erabilita" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Gauzatu 'Non nago' oinarrizko eragiketa" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Gauzatu 'Non nago' eragiketa xehatua" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Irakurri uneko hautapena" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Irakurri estekaren xehetasunak" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Aurkeztu botoi lehenetsia" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Aurkeztu egoera-barra" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Aurkeztu titulu-barra" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Ireki 'Bilatu' elkarrizketa-koadroa" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Erakutsi ekintzen menua" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Bilatu kate baten hurrengo agerpena" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Bilatu kate baten aurreko agerpena" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Sartu eta irten berrikuspen lauko modutik" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Txandakatu berrikuspen laua uneko objektuari mugatzea" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Eraman berrrikuspen laua leiho-hasierara" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Eraman berrrikuspen laua leiho-amaierara" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Eraman berrrikuspen laua aurreko lerroaren hasierara" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Irakurri berrrikuspen lauko uneko lerroa" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Letreiatu berrrikuspen lauko uneko berrikuspen-lerroa" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Fonetikoki letreiatu berrrikuspen lauko uneko berrikuspen-lerroa" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Eraman berrrikuspen laua hurrengo lerroaren hasierara" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Eraman berrrikuspen laua aurreko elementu edo hitzera" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Irakurri berrrikuspen lauko uneko berrikuspen-elementu edo hitza" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Letreiatu berrrikuspen lauko uneko berrikuspen-elementu edo hitza" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Fonetikoki letreiatu berrrikuspen lauko uneko berrikuspen-elementu edo hitza" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Eraman berrrikuspen laua hurrengo elementu edo hitzera" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Eraman berrrikuspen laua uneko hitzaren gaineko hitzera" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Irakurri berrrikuspen lauko uneko objektua" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Eraman berrrikuspen laua uneko hitzaren azpiko hitzera" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Eraman berrrikuspen laua aurreko karakterera" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Irakurri berrrikuspen lauko uneko berrikuspen-karakterea" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" -"Fonetikoki berrrikuspen berrrikuspen lauko uneko berrikuspen-karakterea" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Irakurri berrrikuspen lauko berrikuspen-karakterearen unicode balioa" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Eraman berrrikuspen laua hurrengo karakterera" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Eraman berrrikuspen laua lerroaren amaierara" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Eraman berrrikuspen laua behera ezkerrera" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Kopiatu berrrikuspen lauko edukiak arbelean" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Erantsi berrrikuspen lauko edukiak arbelari" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Erakutsi edukiak berrrikuspen lauan" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Txandakatu taulako uneko gelaxka soilik ala errenkada osoa irakurriko den" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Irakurri uneko testu-karaktereari lotutako atributuak" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Eraman braille-gailua ezkerrera" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Eraman braille-gailua eskuinera" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Itzuli teklatu-fokua duen objektura" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Gaitu eta desgaitu uzkurtutako braille-a" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Prozesatu kursorea bideratzeko tekla bat" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Markatu testu-hautapen baten hasiera" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Markatu testu-hautapen baten amaiera" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Sartu ikasteko moduan. Sakatu Esc ikasteko modutik irteteko" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Moteldu ahots-abiadura" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Azkartu ahots-abiadura" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Jaitsi ahots-tonua" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Igo ahots-tonua" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Igo ahots-bolumena" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Jaitsi ahots-bolumena" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Bilatu kate baten aurreko agerpena" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Joan hurrengo ahots-sintetizatzailera" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Moteldu ahots-abiadura" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Azkartu ahots-abiadura" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Ahots motaren ezarpenak" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Txandakatu ahotsa isiltzea" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Txandakatu ahotsaren xehetasun-maila" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Txandakatu diseinu modua" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Irten pantaila-irakurletik" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Bistaratu hobespenak konfiguratzeko elkarrizketa-koadroa" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Bistaratu aplikazioaren hobespenak konfiguratzeko elkarrizketa-koadroa" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Txandakatu kosken eta justifikazioen irakurtzea" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Aldatu irakurritako zenbakien estiloa" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Joan hurrengo puntuazio-mailara irakurtzera" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Joan hurrengo ahots-sintetizatzailera" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Joan hurrengo ezarpen-profilera" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Joan hurrengo maiuskula-estilora" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Joan teklen hurrengo oihartzun-mailara" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Begiztatu exekuzio-garaiko arazketa-maila" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "egin uneko posizioarekiko dudan posizioaren laster-marka" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Joan aurreko laster-markaren kokapenera" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Joan laster-markara" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Joan hurrengo laster-markaren kokapenera" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Gehitu laster-marka" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Gorde laster-markak" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Aktibatu/desaktibatu saguaren berrikuspen modua" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Aurkeztu uneko ordua" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Aurkeztu uneko data" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Aurkeztu uneko objektuaren tamaina eta kokalekua" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Pasatu hurrengo komandoa uneko aplikazioari" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Irakurri eta jarri braillez berriketa-gelako aurreko mezua" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Aktibatu/desaktibatu zure lagunek idatzitakoen jakinarazpenak" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Txandakatu berriketa-gelako mezuen historia eskainiko den ala ez" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Tandakatu berriketa-gelako mezuen aurretik gelaren izena jarriko den ala ez" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Ezkerrean" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Eskuinean" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Goian" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Behean" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Izoztu" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Goian ezkerrean" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Behean ezkerrean" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Kurtsorearen posizioan" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Sei puntu" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Kurtsorearen bideraketa" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Ebaketa-hasiera" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Ebaki lerroa" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Aurkeztu azken jakinarazpen-mezua" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Aurkeztu jakinarazpen-mezuen zerrenda" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Aurkeztu aurreko jakinarazpen-mezua" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Aurkeztu hurrengo jakinarazpen-mezua" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Joan hurrengo karakterera" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Joan aurreko karakterera" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Joan hurrengo hitzera" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Joan aurreko hitzera" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Joan hurrengo lerrora" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Joan aurreko lerrora" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Joan fitxategiaren goiko aldera" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Joan fitxategiaren beheko aldera" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Joan lerroaren hasierara" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Joan lerroaren amaierara" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Joan hurrengo objektura" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Joan aurreko objektura" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Hedatu uneko konbinazio-koadroa" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Txandakatu jatorrizko eta pantaila-irakurlearen kurtsore-nabigazioa" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Eskualde aktiboaren adeitasunaren ezarpen aurreratuak" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Desaktibatu eskualde aktiboaren adeitasunaren maila lehenetsia" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Berrikusi eskualde aktiboaren jakinarazpenak" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitorizatu eskualde aktiboak" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Eraman fokua saguaren uneko posiziora eta kanpora" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Ezarri errenkada zutabeen goiburu dinamiko gisa erabiltzeko" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Garbitu zutabe-goiburu dinamikoak" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Ezarri errenkaden goiburu dinamiko gisa erabiliko den zutabea" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Garbitu errenkada-goiburu dinamikoak" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Aurkeztu sarrerako lerroaren edukiak" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Aktibatu/desaktibatu egiturazko nabigazioaren teklak" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Joan aurreko aipu-blokera" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Joan hurrengo aipu-blokera" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Bistaratu akipu-blokeen zerrenda bat" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Joan aurreko botoira" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Joan hurrengo botoira" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Bistaratu botoien zerrenda bat" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Joan aurreko kontrol-laukira" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Joan hurrengo kontrol-laukira" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Bistaratu kontrol-laukien zerrenda bat" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Joan aurreko klikagarrira" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Joan hurrengo klikagarrira" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Bistaratu klikagarrien zerrenda bat" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Joan aurreko konbinazio-koadrora" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Joan hurrengo konbinazio-koadrora" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Joan edukiontziaren hasierara" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Joan edukiontziaren amaierara" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Bistaratu konbinazio-koadroen zerrenda bat" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Joan aurreko sarrerara" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Joan hurrengo sarrerara" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Bistaratu sarreren zerrenda bat" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Joan aurreko inprimaki-eremura" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Joan hurrengo inprimaki-eremura" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Bistaratu inprimaki-eremuen zerrenda bat" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Joan aurreko izenburura" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Joan hurrengo izenburura" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Bistaratu izenburuen zerrenda bat" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Joan %d mailako aurreko izenburura" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Joan %d mailako hurrengo izenburura" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Bistaratu %d mailako izenburuen zerrenda bat" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Joan aurreko barneko markora" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Joan hurrengo barneko markora" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Bistaratu barneko markoen zerrenda bat" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Joan aurreko irudira" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Joan hurrengo irudira" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Bistaratu irudien zerrenda bat" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Joan aurreko erreferentzia-puntura" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Joan hurrengo erreferentzia-puntura" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Bistaratu erreferentzia-puntuen zerrenda bat" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Joan aurreko objektu handira" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Joan hurrengo objektu handira" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Bistaratu objektu handien zerrenda bat" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Joan aurreko estekara" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Joan hurrengo estekara" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Bistaratu esteken zerrenda bat" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Joan aurreko zerrendara" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Joan hurrengo zerrendara" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Bistaratu zerrenden zerrenda bat" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Joan aurreko zerrenda-elementura" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Joan hurrengo zerrenda-elementura" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Bistaratu zerrenda-elementuen zerrenda bat" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Joan aurreako eskualde aktibora" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Joan hurrengo eskualde aktibora" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Joan iragarpen bat egin duen azken eskualde aktibora" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Joan nabigazio-fokua duen objektuaren gurasora." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Joan nabigazio-fokua duen objektuaren lehen haurrera." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Joan nabigazio-fokua duen objektuaren hurrengo anaira." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Joan nabigazio-fokua duen objektuaren aurreko anaira." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Egin klik nabigazio-fokua duen objektuan." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Txandakatu objektu-nabigazio sinplifikatua." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Joan aurreko paragrafora" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Joan hurrengo paragrafora" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Bistaratu paragrafoen zerrenda bat" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Joan aurreko aukera-botoira" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Joan hurrengo aukera-botoira" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Bistaratu aukera-botoien zerrenda bat" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Joan aurreko bereizlera" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Joan hurrengo bereizlera" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Joan aurreko taulara" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Joan hurrengo taulara" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Bistaratu taulen zerrenda bat" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Joan gelaxka bat behera" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Joan taula bateko lehen gelaxkara" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Joan taula bateko azken gelaxkara" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Joan gelaxka bat ezkerrera" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Joan gelaxka bat eskuinera" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Joan gelaxka bat gora" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Txandakatu diseinu modua" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Txandakatu arakatze modua eta fokuratze modua" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Gaitu fokuratze modu itsaskorra" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Gaitu arakatze modu itsaskorra" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Joan bisitatu gabeko aurreko estekara" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Joan bisitatu gabeko hurrengo estekara" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Bistaratu bisitatu gabeko esteken zerrenda bat" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Joan bisitatutako aurreko estekara" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Joan bisitatutako hurrengo estekara" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Bistaratu bisitatutako esteken zerrenda bat" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "alizia urdina" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "zuri zaharra" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "urdin-berdea" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "urdin argia" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beixa" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "itsaski-krema" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "beltza" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "almendra zuria" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "urdina" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "urdin bioleta" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "marroia" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "harea marroia" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "urdin kadetea" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "kartusia" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "txokolatea" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "korala" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "artalore urdina" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "arto-seta" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "karmesia" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cyana" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "urdin iluna" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "cyana iluna" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "lasto horia iluna" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "gris iluna" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "berde iluna" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "kaki iluna" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta iluna" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "oliba berde iluna" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "laranja iluna" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "orkidea iluna" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "gorri iluna" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "izokin iluna" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "itsaso ilun berdea" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "arbel urdin iluna" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "arbel gris iluna" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turkesa iluna" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "bioleta iluna" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "arrosa sakona" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "zeru urdin sakona" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "grisa oso iluna" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "urdin artifiziala" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "gorri adreilua" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "zuri loretsua" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "baso berdea" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro grisa" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "aintza zuria" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "urrea" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "lasto horia" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "grisa" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "berdea" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "berde horia" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "ezti-ihintza" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "arrosa beroa" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "gorri indioa" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigoa" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "bolia" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "kakia" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "izpilikua" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "izpiliku gorritua" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "soropil berdea" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "satin limoia" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "urdin argia" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "koral argia" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "cyan argia" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "lasto hori argia" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "grisa argia" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "berde argia" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "arrosa argia" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "izokin argia" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "itsaso berde argia" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "zeru urdin argia" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "arbel argia" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "altzairu urdin argia" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "hori argia" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limoia" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "lima berdea" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "lihoa" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "marroi gorrixka" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "tarteko itsasoko ura" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "tarteko urdina" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "tarteko orkidea" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "tarteko morea" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "tarteko itsaso berdea" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "arbel urdin ertaina" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "tarteko udaberri berdea" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "tarteko turkesa" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "tarteko bioleta gorria" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "gauerdiko urdina" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "mentazko izozkia" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "arrosa lausoa" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokasina" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "zuri navajoa" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "itsasoko urdina" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "lokarri zaharra" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliba" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "oliba itzalia" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "laranja" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "laranja gorria" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orkidea" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "lasto hori zurbila" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "berde zurbila" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turkesa zurbila" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "bioleta gorri zurbila" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaia-irabiakia" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "melokotoia" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "arrosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "arana" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "urdin hautsa" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purpura" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "gorria" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "marroi arrosa" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "errege-urdina" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "narru marroia" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "izokina" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "hondar marroia" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "itsaso berdea" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "itsas-oskola" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "zilarra" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "zeru urdina" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "arbel urdina" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "arbel grisa" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "elurra" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "udaberri berdea" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "altzairu urdina" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "marroiska" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "anila" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "kardua" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomatea" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turkesa" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "bioleta" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "garia" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "zuria" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "ke zuria" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "horia" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "horia berdea" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktibatu" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Fokuaren modu automatikoa egitura-nabigazioan" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Fokuaren modu automatikoa kurtsore-nabigazioan" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Fokuaren modu automatikoa jatorrizko nabigazioan" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "_7. botoia" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "_8. botoia" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "7. _eta 8. botoiak" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Utzi" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Jauzi hona" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Ados" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikonoa" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Bat ere ez" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Ortografia" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Jakinarazi zure _lagunek idazten dutenean" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Eman berriketa-gelako mezuen historia" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Irakurri hemengo mezuak" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Kanal _denak" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Kanal guztiak _edozein %s leiho aktibo badago" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Kanal bat (bere _leihoa soilik badago aktibo)" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Irakurri berriketa-gelaren izena" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Gaitu diseinuaren modua edukiarentzako" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "klik bikoitza" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "klik hirukoitza" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizatzaile lehenetsia" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Uneko katea" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Ordezteko erabiliko den katea" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Gaitu oihartzuna _karaktere arabera" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Gaitu tarterik gabeko tekla _diakritikoak" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Uneko kokapena" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Bat datorren testuaren gutxieneko luzera:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Bilaketa-aukerak" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Irakurri _soilik aldatutako lerroak bilaketa egin bitartean" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Irakurri emaitzak _bilaketa egin bitartean" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Komandoa" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Laster-tekla" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Lehenetsia" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Ikasteko modua" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Ekintzak" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braille-gailuko laster-botoiak" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Laster-markak" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Data eta ordua" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Saguaren berrikuspena" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Objektu-nabigazioa" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objektuaren xehetasunak" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Lotu gabea" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Berrikuspen laua" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Ahotsa eta xehetasunak" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Berrikuspen lauko edukiak" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Aldatze-data" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Mahaigainekoa" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Jakinarazpenak" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Jaso da" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Jakinarazpenen aurkezlea" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhuren hobespenak %s(e)rako" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Markatu braillez" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Adierazi, hauek ez badira" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Esan" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Gorde profila gatazkatsu gisa" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Gatazka erabiltzailearen profilean!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"%s profila badago lehendik ere.\n" -"Lehendik dagoen profila aldaketa berriekin eguneratzen jarraitu?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Kargatu erabiltzailearen profila" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Profil aktiboa aldatzera zoaz. Aldaketak zure hobespenetan\n" -"bakarrik egin badituzu, jaregin egingo da profila kargatzean.\n" -"\n" -"Profila kargatzen jarraitzea nahi duzu aurreko aldaketak baztertuz?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Gorde profila honela" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profilaren izena:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Kendu erabiltzaile-profila" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"%s profila kentzera zoaz. Gorde gabeko eta profil honetako ezarpen guztiak " -"galduko dira. Jarraitu nahi duzu eta profil hau eta hari lotutako ezarpen " -"guztiak kendu nahi dituzu?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Denak" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplikazioa" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Leihoa" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Bat ere ez" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Batzuk" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Gehienak" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Lerroa" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Esaldia" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Aipu-blokea" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Botoia" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Epigrafea" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Kontrol-koadroa" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Klikagarria" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Konbinazio-koadroa" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Azalpena" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Izenburua" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Barneko markoa" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Irudia" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiketa" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Erreferentzia-puntua" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Maila" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Esteka" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Zerrenda" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Zerrendako elementua" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objektua" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragrafoa" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Aukera-botoia" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Funtzioa" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Hautatutako elementua" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Egoera" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Testua" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URIa" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Balioa" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Aipu-blokeak" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botoiak" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Kontrol-koadroak" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Klikagarriak" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Konbinazio-koadroak" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Sarrerak" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Inprimakiaren eremuak" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Izenburuak" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Barneko markoak" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Irudiak" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "%d mailako izenburuak" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Erreferentzia-puntuak" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Objektu handiak" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Estekak" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Zerrendak" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Zerrendako elementuak" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragrafoak" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Aukera-botoiak" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Taulak" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Bisitatu gabeko estekak" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Bisitatutako estekak" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Orri-nabigazioa" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Hasi automatikoki irakurtzen, orria lehenengoz _kargatzean" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Au_rkeztu orriaren laburpena lehenengoz kargatzean" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Zatitu irakurketa _pusketatan pausen artean" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s ahots lehenetsia" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Lehenetsia" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiperesteka" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Maiuskulak" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Zuzentzaile ortografikoa" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Errore _ortografikoak" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Zuzenketaren _iradokizunak" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Aurkeztu errorearen _testuingurua" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Irakurri kalkulu-orrietako gelaxken koordenatuak" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Beti irakurri hautatutako kalkulu-orriaren barrutia" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Gelaxken _goiburuak irakurri behar dituen ala ez adierazten du" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Taula-nabigazioa" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Gelaxka _hutsak saltatu behar dituen adierazten du" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Irakurri _gelaxka" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Irakurri _gelaxken koordenatuak" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Irakurri _gelaxka anitzeko gelaxken tamaina" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Atributuaren izena" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Kontrolatu kurtsore-nabigazioa" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Gaitu _egitura-nabigazioa" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Soinu _gaia:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Soinu gaia" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Laburra" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Jakinarazpen %d" -msgstr[1] "%d jakinarazpen" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Ctrl" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "ezkerreko Shift tekla" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "ezkerreko Alt tekla" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ezkerreko Kontrol tekla" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "eskuineko Shift tekla" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "eskuineko Alt tekla" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "eskuineko Kontrol tekla" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ezkerreko Meta tekla" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "eskuineko Meta tekla" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "zenbakien blokeoaren tekla" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "maiuskulen blokeoaren tekla" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift tekla" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "Blok Korr tekla" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "Orria Gora tekla" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "Orria Behera tekla" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "ezkerreko Tab tekla" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "atzera-tekla" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "itzuli tekla" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "sartu tekla" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "gora" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "behera" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "ezkerrera" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "eskuinera" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "ezker-super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "eskuin-super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menua" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "laguntza" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "anitza" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "modu aldaketa" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "ihes" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "txertatu" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "ezabatu" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "hasiera" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "amaiera" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "hasiera" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "zirkunflexua" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "eraztunduna" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "barraduna" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Txertatu" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "_Blok maius" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Maius" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "lodia %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "etzana %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "lodi etzana %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "script-a %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "lodi script-a %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "double-struck %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "fraktur lodia %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif lodia %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif etzana %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif lodi etzana %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "tarte bakarrekoa %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "punturik gabekoa %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "ezkerrerako gezia" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "gorako gezia" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "eskuinerako gezia" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "beherako gezia" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "ezker eskuinerako gezia" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "gora beherako gezia" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "ipar mendebalderako gezia" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "ipar ekialderako gezia" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "hego ekialderako gezia" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "ezkerrerako gezia barratik" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "gorako gezia barratik" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "eskuinerako gezia barratik" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "beherako gezia barratik" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "ezkerreko" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "gorako gezi bikoitza" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "eskuinerako gezi bikoitza" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "beherako gezi bikoitza" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "ezker eskuinerako gezi bikoitza" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "gora beherako gezi bikoitza" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "ipar mendebalderako gezi bikoitza" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "ipar ekialderako gezi bikoitza" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "hego ekialderako gezi bikoitza" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "hego mendebalderako gezi bikoitza" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "eskuinerantz zuzendutako gezia" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "eskuinerantz zuzendutako geziburua" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "hau baino txikiagoa" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "hau baino handiagoa" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "zirkunflexua" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "puntua" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "lerro bertikal bikoitza" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "elipsi horizontala" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "denentzat" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "osagarria" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "diferentzial partziala" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "badago" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "ez dago" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "multzo hutsa" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "gehikuntza" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "elementua" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "elementua ez" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "elementu txikia" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "kide gisa dauka" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "ez dauka kide gisa" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "txikiak kide gisa dauka" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "probaren amaiera" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produktua" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koproduktua" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "batuketa" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus edo plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "puntu plusa" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "zatiketa-barra" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "ezarri minus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "asterisko eragilea" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "eraztun eragilea" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "bulet eragilea" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "erro karratua" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "erro kubikoa" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "laugarren erroa" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proportzionala" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinitua" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "eskuineko angelua" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "angelua" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "neurtutako angelua" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "angelu esferikoa" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "zatitzen du" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "ez du zatitzen" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paraleloa" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "ez paraleloa" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "eta logikoa" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "edo logikoa" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "ebakidura" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "batuketa" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integrala" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integral bikoitza" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integral hirukoitza" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "lerro-integrala" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "gainazal-integrala" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "bolumen-integrala" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integrala erlojuaren noranzkoan" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "lerro-integrala erlojuaren noranzkoan" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "lerro-integrala erlojuaren noranzkoaren aurka" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "hortaz" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "arrazoia" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "erlazioa" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proportzioa" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "puntu minusa" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "soberakoa" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proportzio geometrikoa" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetikoa" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tileta" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "alderantzikatutako tileta" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "alderantzikatutako S alferra" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinu uhina" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "koroa-produktua" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "tiletik ez" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minus tileta" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asintotikoki berdina" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "asintotikoki ez berdina" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "gutxi gora-behera berdina" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "gutxi gora-behera berdina baina ez berdina" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ez gutxi gora-behera ez zehazki berdina" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "ia berdina" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ez ia berdina" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "ia berdina edo berdina" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "tilet hirukoitza" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "dena berdina" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "baliokidea" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrikoki baliokidea" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "bien arteko ezberdintasuna" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "mugara hurbiltzen" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrikoki berdina" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "gutxi gora-behera berdina edo haren irudia" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "haren irudia edo gutxi gora-behera berdina" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "bi puntu berdina" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "berdina bi puntu" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "berdina eraztunarekin" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "eraztuna berdina" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "dagokiona" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "haztatua" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "angelukidea" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "izarra berdina" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta berdina" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "berdina definizio bidez" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "honekin neurtua" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "galdera-ikurra berdina" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "ez berdina" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "berdin-berdina" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "ez berdin-berdina" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "hertsiki baliokidea" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "txikiagoa edo berdina" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "handiagoa edo berdina" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "txikiagoa eta berdina" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "handiagoa eta berdina" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "txikiagoa baina ez berdina" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "handiagoa baina ez berdina" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "hau baino askoz gutxiago" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "hau baino askoz handiago" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "artean" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "ez baliokidea" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "ez gutxiago" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "ez handiago" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ez txikiagoa ez berdina" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ez handiagoa ez berdina" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "txikiagoa edo baliokidea" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "handiagoa edo baliokidea" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ez txikiagoa ez baliokidea" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ez handiagoa ez baliokidea" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "txikiagoa edo handiagoa" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "handiagoa edo txikiagoa" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ez txikiagoa ez handiagoa" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ez handiagoa ez txikiagoa" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "aurrekoa" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "atzekoa" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "aurrekoa edo berdina" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "atzekoa edo berdina" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "aurrekoa edo baliokidea" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "atzekoa edo baliokidea" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "ez aurrekoa" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ez atzekoa" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "azpimultzoa" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "goimultzoa" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "ez azpimultzoa" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "ez goimultzoa" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "azpimultzoa edo berdina" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "goimultzoa edo berdina" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ez azpimultzoa ez berdina" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ez goimultzoa ez berdina" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "azpimultzoa eta ez berdina" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "goimultzoa eta ez berdina" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multzoanitza" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multzoanitz biderketa" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "multzoanitz batuketa" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "irudi karratua" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "jatorrizko karratua" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "irudi karratua edo berdina" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "jatorrizko karratua edo berdina" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "txano karratua" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "kopa karratua" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "plus zirkuluan" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "minus zirkuluan" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "ixa zirkuluan" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "zatiketa barra zirkuluan" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "puntu biderkatzailea zirkuluan" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "eraztuna zirkuluan" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "asteriskoa zirkuluan" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "berdina zirkuluan" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "marratxoa zirkuluan" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus karratuan" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "minus karratuan" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "ixa karratuan" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "puntu biderkatzailea karratuan" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "eskuinerako tatxeta" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "ezkerrerako tatxeta" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "beherako tatxeta" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "gorako tatxeta" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "baieztapena" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "ereduak" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "egia" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "behartzen du" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "barra bertikal hirukoitza eskuineko torniketea" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "barra bertikal bikoitza eskuineko tornikete bikoitza" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "ez du probatzen" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "ez egia" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "ez du behartzen" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "barra bertikal bikoitza eskuineko tornikete bikoitza ukatua" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "aurrekoa erlazio azpian" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "atzekoa erlazio azpian" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "azpitalde normala" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "azpitalde normal modura dauka" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "azpitalde normala edo berdina" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "azpitalde normal modura dauka edo berdina" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "jatorrizkoa" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "irudia" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multi-mapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matrize konjugatu hermitikoa" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "tartekatu" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "eskuineko angelua arkuarekin" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "eskuineko triangelua" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "diamante eragilea" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "puntu eragilea" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "izar eragilea" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "zatiketa jarraiak" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "begizta" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "ezkerreko faktore normaleko erdizuzeneko biderkadura" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "eskuineko faktore normaleko erdizuzeneko biderkadura" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "ezkerreko erdizuzeneko biderkadura" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "eskuineko erdizuzeneko biderkadura" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "alderantzikatutako tileta berdina" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "edo logiko kiribila" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "eta logiko kiribila" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "azpimultzo bikoitza" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "goimultzo bikoitza" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "ebaketa bikoitza" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "batuketa bikoitza" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "sardea" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "berdina eta paraleloa" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "txikiagoa puntuarekin" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "handiagoa puntuarekin" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "askoz txikiagoa" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "askoz handiagoa" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "txikiagoa berdina edo handiagoa" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "handiagoa berdina edo txikiagoa" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "berdina edo txikiagoa" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "berdina edo handiagoa" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "berdina edo aurrekoa" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "berdina edo atzekoa" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "ez aurrekoa edo berdina" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ez atzekoa edo berdina" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "ez irudi karratua edo berdina" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "ez jatorrizko karratua edo berdina" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "irudi karratua edo ez berdina" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "jatorrizko karratua edo ez berdina" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "txikiagoa baina ez baliokidea" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "handiagoa baina ez baliokidea" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "aurrekoa baina ez baliokidea" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "atzekoa baina ez baliokidea" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "ez azpitalde normala" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "ez dauka azpitalde normal modura" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "ez azpitalde normala edo berdina" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "ez dauka azpitalde normal modura edo berdina" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "elipsi bertikala" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "erdiko marrako elipsi horizontala" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "goiko eskuineko zeharkako elipsia" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "beheko eskuineko zeharkako elipsia" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "elementua barra horizontal luzearekin" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "elementua barra bertikalarekin amaieran edo barra horizontala" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "elementu txikia barra bertikalarekin amaieran edo barra horizontala" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "elementua goiko puntuarekin" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "elementua gaineko barrarekin" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "elementu txikia gaineko barrarekin" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "elementua azpiko barrarekin" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "elementua bi barra horizontalekin" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "dauka barra horizontal luzearekin" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "dauka barra bertikalarekin amaieran edo barra horizontala" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "dauka txikia barra bertikalarekin amaieran edo barra horizontalarekin" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "dauka gaineko barrarekin" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "dauka txikia gaineko barrarekin" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z notazio poltsaren kidea" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ezkerreko sabaia" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "eskuineko sabaia" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "ezkerreko zorua" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "eskuineko zorua" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "goiko giltza" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "beheko giltza" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "ezkerreko kortxete angeluarra" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "eskuineko kortxete angeluarra" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "puntua zirkuluan" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "batuketa puntuarekin" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "batuketa plusarekin" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "ebakidura karratua" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "batuketa karratua" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "karratu beltza" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "karratu zuria" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "erronbo beltza" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "zirkulu zuria" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "zirkulu beltza" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bulet zuria" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "erdiko karratu beltz txikia" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s azpimarrarekin" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s barrarekin" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s lerro bertikalarekin" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplikazioa" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "hutsik" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "lodia" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "laster-marka sartu da" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "laster-marka gorde da" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "laster-markak ezin izan dira gorde" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Ez da laster-markarik aurkitu." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Ez da laster-marka aurkitu." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Tekla bidaltzeko modua gaituta." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Ezin da kalkulagailuaren pantaila lortu" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "tonua" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Hizki maiuskulen estiloa tonu gisa ezarrita." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "bat ere ez" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Hizki maiuskulen estiloa 'bat ere ez' gisa ezarrita." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "letreiatu" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Hizki maiuskulen estiloa letreiatzeko ezarrita." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Aplikazioak kontrolatzen du kurtsorea." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Aplikazioak kontrolatzen du kurtsorea." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "%s gelaxka" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s hautatu da" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s eta %s artean hautatu da" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s eta %s artean desautatu da" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s desautatu da" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Saihestu aukera erabiltzea" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Derrigortu aukera erabiltzea" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "AUKERA" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Aukerako argumentuak" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Erabilera: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Honako aukera edo argumentuak ez dira baliozkoak: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Erakutsi exekutatzen ari diren aplikazio ezagunak" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Kargatu profila" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Ezin izan da profila kargatu: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Ezin da pantaila-irakurlea abiarazi ezin duelako Mahaigainarekin konektatu." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Ezin izan da ezarpenen kudeatzailea aktibatu. Irteten." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Pantaila-irakurlearen beste prozesu bat jadanik exekutatzen ari da saio " -"honetan.\n" -"Exekutatu \"cthulhu --replace\" komandoa prozesu hura berriarekin ordezteko." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "IZENA" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Erabili ordezko direktorioa erabiltzailearen hobespenentzako" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Aplikazio honen bertsioa" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Ordeztu unean exekutatzen ari den pantaila-irakurlea" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Erakutsi laguntza-mezu hau eta irten" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Bidali arazketako irteera hona: debug-UUUU-HH-EE-OO:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Bidali arazketako irteera zehaztutako fitxategira" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FITXATEGIA" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Konfiguratu erabiltzailearen hobespenak (testu-bertsioa)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Konfiguratu erabiltzailearen hobespenak (GUI bertsioa)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Bidali arazoen berri hona: https://groups.io/g/stormux" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Ebaki hautapena arbelera" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "ebaki" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Hautapena arbelera kopiatu da." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopiatua" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Itsatsi edukiak arbeletik" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "itsatsia" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Ez jakinarazi zure lagunek idazten dutenean." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "jakinarazi zure lagunek idazten dutenean." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "%s berriketa-gelako mezua" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "%s berriketa-fitxa berria" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Ez irakurri berriketa-gelaren izena." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "irakurri berriketa-gelaren izena." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Ez eman berriketa-gelako mezuen historia." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Eman berriketa-gelako mezuen historia." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "ezabaketaren hasiera" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "ezabaketaren amaiera" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "txertaketaren hasiera" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "txertaketaren amaiera" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "nabarmentzearen hasiera" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "nabarmentzearen amaiera" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "iradokizunaren amaiera" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Edukiontziaren amaiera." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Ez dago edukiontzi batean." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "elementu guztiak hautatuta" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Botoi lehenetsia %s da." - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Botoi lehenetsia %s da Indargabetuta" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Ez da botoi lehenetsia aurkitu" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " azpiindizeko %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " goi-indizeko %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Ez da elkarrizketa-koadroa" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "dokumentu osoa hautatu da" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "dokumentu osoa desautatu da" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokumentua hautatu da, kurtsorearen posiziotik aurrera" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "dokumentua desautatu da, kurtsorearen posiziotik aurrera" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokumentua hautatu da, kurtsorearen posizioraino" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "dokumentua desautatu da, kurtsorearen posizioraino" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Zutabe-goiburu dinamikoa %d. errenkadarentzat ezarri da" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Zutabe-goiburu dinamikoa garbitu da." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Errenkada-goiburu dinamikoa ezarri da %s zutabearentzat" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Errenkada-goiburu dinamikoa garbitu da." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "hutsik" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobyte" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabyte" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Ez da fitxategirik aurkitu." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Edukia arbelari erantsita." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Edukia arbelean kopiatuta." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Ez da berrrikuspen laua erabiltzen ari." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Berrikuspen lauan sartzen da." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Berrikuspen lautik ateratzen da." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Berrikuspen laua uneko objektuari mugatua" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Mugarik gabeko berrikuspen laua" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "formula du" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "elkarrizketa-koadroa irekitzen du" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "sareta irekitzen du" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "zerrenda-koadroa irekitzen du" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "menua irekitzen du" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "zuhaitza irekitzen du" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "irudi-maparen esteka" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Sartutako tekla jadanik '%s'(r)ekin lotuta dago" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Kapturatutako tekla: %s. Sakatu Enter berresteko." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Hau da tekla-konbinazio berria: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Tekla-konbinazioa ezabatu da. Sakatu Enter berresteko." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Tekla-konbinazioa ezabatu egin da." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "sartu tekla-konbinazio berria" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tekla" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Oihartzuna 'Tekla' gisa ezarri da." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Bat ere ez" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Oihartzuna 'Bat ere ez' gisa ezarri da." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tekla eta hitza" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Oihartzuna 'Tekla eta hitza' gisa ezarri da." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "esaldia" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Oihartzuna 'Esaldia' gisa ezarri da." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "hitza" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Oihartzuna 'Hitza' gisa ezarri da." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "hitza eta esaldia" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Oihartzuna 'Hitza eta esaldia' gisa ezarri da." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Inguratzailea: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "ikur aktuarioa" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "kutxa bat" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "zirkulu bat" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "zatiketa-ikur luzea" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "erradikal bat" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "kutxa biribildua" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "marra horizontala" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "marra bertikala" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "zeharkako beheranzko marra" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "zeharkako goranzko marra" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "ipar-ekialderako gezia" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "lerroa behean" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "lerroa ezkerrean" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "lerroa eskuinean" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "lerroa goian" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "fasore angelua" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "arabiar ikur faktoriala" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "eta" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "zatikiaren hasiera" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "zatikia barrarik gabe, hasiera" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "gainean" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "zatikiaren amaiera" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "erro karratua" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "erro kubikoa" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "erroa" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "erroaren hasiera" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "erroaren amaiera" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "azpiindizea" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "goi-indizea" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "azpiindize aurrekoa" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "goi-indize aurrekoa" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "azpiidazkia" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "goiidazkia" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "taularen amaiera" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "habiaratutako taularen amaiera" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "irakurtezina" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Desgaituta" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Koskak eta justifikazioen irakurketa desgaituta." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Gaituta" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Irakurri koskak eta justifikazioak" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Ikasteko modua. Irteteko, sakatu Esc tekla." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Ikasteko modua aktibatzen. Sakatu tekla bat haren funtzioa entzuteko. " -"Pantaila-irakurlearen dokumentazioa ikusteko sakatu F1. Pantaila-" -"irakurlearen lasterbide lehenetsiak lortzeko, sakatu F2. Pantaila-" -"irakurlearen lasterbideen zerrenda uneko aplikazioarentzako lortzeko, sakatu " -"F3. Ikasteko modutik irteteko, sakatu Ihes tekla." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "aipu-blokea uzten." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "xehetasunak uzten." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "jarioa uzten." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "irudia uzten." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "inprimakia uzten." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "iragarkia uzten." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "eduki osagarria uzten." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "informazioa uzten." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "eduki nagusia uzten." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "nabigazioa uzten." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "eskualdea uzten." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "bilaketa uzten." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "zerrenda uzten." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "panela uzten." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "taulatik irteten." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "argibidea uzten." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "laburpena uzten." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "aitortzak uzten." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "hitzostea uzten." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "eranskina uzten." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "bibliografia uzten." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "kapitulua uzten." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "azken oharra uzten." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "ondorioa uzten." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "kreditua uzten." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "kredituak uzten." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "eskaintza uzten." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "amaiera-oharrak uzten." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "epigrafea uzten." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "epilogoa uzten." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "huts-zerrenda uzten." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "adibidea uzten." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "hitzaurrea uzten." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "glosarioa uzten." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "indizea uzten." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "sarrera uzten." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "orrialde-zerrenda uzten." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "atala uzten." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "aitzinsolasa uzten." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "prologoa uzten." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "erauzitako aipua uzten." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "galde-erantzunak uzten." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "iradokizuna uzten." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "edukien aurkibidea uzten." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "lerroa hautatu da kurtsorearen posiziotik aurrera" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "lerroa hautatu da kurtsorearen posiziotik atzera" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "lerroa desautatu da kurtsorearen posiziotik aurrera" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "lerroa desautatu da kurtsorearen posiziotik atzera" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Ikasteko modua desaktibatzen." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "lerroa hasieratik hautatu da kurtsorearen aurreko posizioraino" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "lerroa amaieraraino hautatu da kurtsorearen aurreko posiziotik" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "esteka" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "orri bera" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "gune bera" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "beste gune bat" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s esteka %(file)s(e)ra" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s esteka" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "bisitatutako %s esteka" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Erabili gorako eta beherako geziak zerrendan nabigatzeko. Sakatu Esc tekla " -"irtetzeko." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Eskualde aktibo guztiak desaktibatu dira" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "eskualde aktiboen adeitasun mailak berrezarri dira" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "%s adeitasun maila" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "eskualde aktiboa kementsura ezartzen" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "eskualde aktiboa desaktibatu gisa ezartzen" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "eskualde aktiboa adeitsura ezartzen" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "eskualde aktiboa adeigabera ezartzen" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Eskualde aktiboaren monitorizazioa desaktibatuta" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Eskualde aktiboaren monitorizazioa aktibatuta" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "ez da aktibitatearen mezurik gorde" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Eskualde aktiboaren euskarria desaktibatuta dago" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Ez da aurkitu" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Ezin izan da uneko kokapena aurkitu." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "desaktibatuta" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "-" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "gaizki idatzia dago" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Hitza gaizki idatzia dago: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Hau da testuingurua: %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Arakatzearen modua" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Fokuaren modua" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Fokuaren modua gaitzeko sakatu %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Fokuaren modua finkoa da." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Arakatze modua itsaskorra da." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Diseinuaren modua." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objektuen modua." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Erakuslea objektura eraman da." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Ez da objektuaren gaineko sagurik aurkitu." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Saguaren berrikuspen modua desgaitu da." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Saguaren berrikuspen modua gaitu da." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Errorea: ezin izan da objektuen zerrenda sortu." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Haurrik ez." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Hurrengorik ez." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Gurasorik ez." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Aurrekorik ez." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Nabigazio sinplifikatua gaitu da." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Nabigazio sinplifikatua desgaitu da." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "%d habiaratze-maila" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Elementu berria gehitu da" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Ez da ekintzarik aurkitu hemen: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Fokurik ez" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Aplikazio batek ere ez du fokurik." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Ez dago aipu-bloke gehiago." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Ez dago botoi gehiago." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Ez dago kontrol-koadro gehiago." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Ez dago objektu handi gehiago." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Ez dago klikagarri gehiago." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Ez dago konbinazio-koadro gehiago." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Ez dago sarrera gehiago." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Inprimakian ez dago eremu gehiago." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Ez dago izenburu gehiago." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Ez dago izenburu gehiago %d. mailan." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Ez dago barneko marko gehiagorik." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Ez dago irudi gehiago." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Ez da erreferentzia-punturik aurkitu." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Ez dago esteka gehiago." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Ez dago zerrenda gehiago." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Ez dago zerrendako elementu gehiago." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Ez dago eskualde aktibo gehiago." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Ez dago paragrafo gehiago." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Ez dago aukera-botoi gehiago." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Ez dago bereizle gehiago." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Ez dago taula gehiago." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Ez dago bisitatu gabeko esteka gehiago." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Ez dago bisitatutako esteka gehiago." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Ez dago testurik hautatuta." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Ez dago esteka batean." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Jakinarazpena" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Behean" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Goian" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Ez dago jakinarazpeneko mezurik" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "digituak" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Esan zenbakiak digitu eran" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "hitzak" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Esan zenbakiak hitz eran" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "desaktibatuta" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "-" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Kargatzen ari da. Itxaron." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Kargatzen bukatu du." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s kargatzen bukatu du." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Orrialdeak %s dauka." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "orria hautatu da, kurtsorearen posiziotik aurrera" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "orria hautatu da, kurtsorearen posizioraino" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "orria desautatu da, kurtsorearen posiziotik aurrera" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "orria desautatu da, kurtsorearen posizioraino" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "paragrafoa hautatu da, kurtsorearen posiziotik beherantz" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragrafoa hautatu da, kurtsorearen posiziotik gorantz" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "paragrafoa desautatu da, kurtsorearen posiziotik beherantz" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragrafoa desautatu da, kurtsorearen posiziotik gorantz" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Cthulhu-ren hobespenen elkarrizketa-koadro bat jadanik irekita dago.\n" -"Itxi ezazu hori berri bat ireki aurretik." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "%(position)d / %(count)d diapositiba" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profila %s gisa ezarri da." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Ez da profilik aurkitu." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "%d. aurrerapen-barra." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Denak" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Puntuazioen maila Denak moduan ezarrita." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Gehienak" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Puntuazioen maila Gehienak moduan ezarrita." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Bat ere ez" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Puntuazioen maila 'Bat ere ez' moduan ezarrita." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Batzuk" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Puntuazioen maila Batzuk moduan ezarrita." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Bilaketa." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Bilatu osorik." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Pantaila-irakurlearen ezarpenak berriro kargatu dira." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Hautatutako testua honakoa da: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Hautapena ezabatu da." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Hautapena berregin da." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Testua desautatu da." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Tamaina: %d, %d. Kokapena: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Zabalera: %d. Altuera: %d. %d ezkerretik. %d goitik." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Ahotsa desgaitu da." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Ahotsa gaitu da." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "bizkorrago." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "motelago." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "tonu altuagoa." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "tonu baxuagoa." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "altuago." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "leunago." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Abiadura %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Tonua %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Bolumena %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher modulua %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher ahotsa %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Ahotsa ez dago erabilgarri." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Ahotsa ez dago erabilgarri." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Ahotsa gaitu da." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "laster-markak ezin izan dira gorde" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Xehetasun-maila: laburra" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Xehetasun-maila: xehea" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " puntu puntu puntu" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu-k ongietorri ematen dizu." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu olatuen azpian ezkutatzen da." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Lo modua gaituta %s(e)rako" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Lo modua desgaituta %s(r)entzat" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Ahotsa ez dago erabilgarri." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Ez da aurkitu" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Egoera-barra ez da aurkitu" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "ez da katea aurkitu" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Egitura-nabigazioaren teklak desaktibatuak daude." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Egitura-nabigazioaren teklak aktibatuak daude." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Ez da aurkitu" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "%(row)d. errenkada, %(column)d. zutabea." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Taularen amaiera" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Irakurri gelaxka" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Irakurri errenkada" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Ez da uniformea" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Ez dago taula batean." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Zutabeak berriro ordenatuta" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Errenkadak berriro ordenatuta" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "%d. zutabea" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "%(index)d. / %(total)d zutabea" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Zutabe-amaiera." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Zutabe-hasiera." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "%s zutabea hautatu da" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "%s eta %s arteko zutabeak hautatu dira" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "%s eta %s arteko zutabeak desautatu dira" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "%s zutabea desautatu da" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "%d. errenkada" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "%(index)d / %(total)d errenkada" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Errenkada-hasiera" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Errenkada-amaiera." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Errenkada ezabatuta." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Azken errenkada ezabatuta." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Errenkada txertatuta." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Errenkada taularen amaieran txertatuta." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "%s errenkada hautatuta" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "%s eta %s arteko errenkadak hautatu dira" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "%s eta %s arteko errenkadak desautatu dira" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "%s errenkada desautatu da" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "hautatuta" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "desautatuta" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H ordu, %M minutu eta %S segundo" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H ordu eta %M minutu" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicodea %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "desegin" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "berregin" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu %s bertsioa." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "zuriuneak" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Behetik jarraitzen." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Goitik jarraitzen." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elementu" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Gelaxkak errenkada %d hartzen du" -msgstr[1] "Gelaxkak %d errenkada hartzen ditu" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " Zutabe %d" -msgstr[1] " %d zutabe" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Gelaxkak zutabe %d hartzen du" -msgstr[1] "Gelaxkak %d zutabe hartzen ditu" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "Karaktere %d luzeegi" -msgstr[1] "%d karaktere luzeegi" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(Elkarrizketa-koadro %d)" -msgstr[1] "(%d elkarrizketa-koadro)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "Fokurik gabeko elkarrizketa-koadro %d" -msgstr[1] "Fokurik gabeko %d elkarrizketa-koadro" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "Byte %d" -msgstr[1] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Fitxategi %d aurkitu da" -msgstr[1] "%d fitxategi aurkitu dira" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "Inprimaki %d" -msgstr[1] "%d inprimaki" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "Izenburu %d" -msgstr[1] "%d izenburu" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "Elementu %d" -msgstr[1] "%d elementu" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Erreferentzia-puntu %d" -msgstr[1] "%d erreferentzia-puntu" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "Elementu %d aurkitu da" -msgstr[1] "%d elementu aurkitu dira" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Aipu-bloke %d uzten." -msgstr[1] "%d aipu-bloke uzten." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Zerrenda %d uzten." -msgstr[1] "%d zerrenda uzten." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Tamaina ezezaguneko zerrenda" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Elementu %d duen zerrenda" -msgstr[1] "%d elementu dituen zerrenda" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Tamaina ezezaguneko jarioa" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Artikulu %d duen jarioa" -msgstr[1] "%d artikulu dituen jarioa" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Termino %d duen deskribapen-zerrena" -msgstr[1] "%d termino dituen deskribapen-zerrenda" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Balio %d" -msgstr[1] "%d balio" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "Errenkada %d duen matematika-taula" -msgstr[1] "%d errenkada dituen matematika-taula" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "Zutabe %d" -msgstr[1] "%d zutabe" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "%d errenkada duen matematika-taula habiaratua" -msgstr[1] "%d errenkada dituen matematika-taula habiaratua" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "Mezu %d.\n" -msgstr[1] "%d mezu.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "Ehuneko %d." -msgstr[1] "Ehuneko %d." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "Dokumentuaren ehuneko %d irakurri da" -msgstr[1] "Dokumentuaren ehuneko %d irakurri da" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixel" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "Karaktere %(count)d: %(repeatChar)s" -msgstr[1] "%(count)d karaktere: %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d / %(total)d elementu hautatuta" -msgstr[1] "%(index)d / %(total)d elementu hautatuta" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Pantaila-irakurlearen lasterbide lehenetsi %d aurkituta." -msgstr[1] "Pantaila-irakurlearen %d lasterbide lehenetsi aurkituta." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Pantaila-irakurlearen lasterbide %(count)d aurkituta " -"%(application)s(r)entzako." -msgstr[1] "" -"Pantaila-irakurlearen %(count)d lasterbide aurkituta " -"%(application)s(r)entzako." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "zuriune %d" -msgstr[1] "%d zuriune" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "tabulazio %d" -msgstr[1] "%d tabulazio" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "taula %d" -msgstr[1] "%d taula" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tamaina ezezaguneko taula" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "zutabe %d duen taula, errenkada kopuru ezezaguna" -msgstr[1] "%d zutabe dituen taula, errenkada kopuru ezezaguna" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "errenkada %d duen taula, zutabe kopuru ezezaguna" -msgstr[1] "%d errenkada dituen taula, zutabe kopuru ezezaguna" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "errenkada %d duen taula" -msgstr[1] "%d errenkada dituen taula" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "duela segundo %d" -msgstr[1] "duela %d segundo" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "duela minutu %d" -msgstr[1] "duela %d minutu" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "duela ordu %d" -msgstr[1] "duela %d ordu" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "duela egun %d" -msgstr[1] "duela %d egun" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "Bisitatu gabeko esteka %d" -msgstr[1] "Bisitatu gabeko %d esteka" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "Bisitatutako esteka %d" -msgstr[1] "Bisitatutako %d esteka" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "txandakatu" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(index)d / %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d / %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "%(index)d elementua" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "%d MAILA" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "%d zuhaitz-maila" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "%d ZUHAITZ-MAILA" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "%s elementuaren xehetasunak" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "%s(e)n ditu xehetasunak" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "iradokizuna" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "konbinazio-koadro editagarria" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "eduki editagarriak" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "Iturria" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "irudia" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "laburpena" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "aitortzak" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "hitzostea" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "eranskina" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "bibliografia-sarrera" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografia" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "kapitulua" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "azken oharra" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "ondorioa" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "azala" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "kreditua" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "kredituak" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "eskaintza" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "amaierako oharra" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "amaierako oharrak" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigrafea" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilogoa" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "huts-zerrenda" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "adibidea" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "hitzaurrea" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosarioa" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "Indizea" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "sarrera" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "orrialde-jauzia" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "orrialde-zerrenda" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "atala" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "aitzinsolasa" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prologoa" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "erauzitako aipua" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "galde-erantzunak" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "azpititulua" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "edukien aurkibidea" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "i%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s %(level)d. maila" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "korritze-barra horizontala" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "korritze-barra bertikala" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "graduatzaile horizontala" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "graduatzaile bertikala" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "zatitzaile horizontala" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "zatitzaile bertikala" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "txandakatzailea" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Ikono-panela" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "iragarkia" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "eduki osagarria" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informazioa" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "eduki nagusia" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "nabigazioa" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "eskualdea" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "bilaketa" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "bisitatutako esteka" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "menuaren botoia" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "gorantz ordenatuta" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "beherantz ordenatuta" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "ordenatuta" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klikagarria" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "tolestuta" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "hedatuta" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "azalpen luzea du" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontala" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "bertikala" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "gaituta" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "desgaituta" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "-" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "desaktibatuta" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "partzialki gaituta" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "sakatuta" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "sakatu gabea" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "hautatu gabea" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "hautatuta" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "hautatu gabea" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "hautatu gabea" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "bisitatuta" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "bisitatu gabe" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "grisez markatua" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "irakurtzeko soilik" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "iraksoili" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "beharrezkoa" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "hautapen anizkoitza" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "baliogabeko sarrera" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "baliogabea" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "baliogabeko ortografia" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "akats ortografikoa" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "baliogabeko gramatika" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatika" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Bilatu" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Pantaila-irakurlearen 'Bilatu' elkarrizketa-koadroa" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "It_xi" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "A_urkitu" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Bilatu hau:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Bilatu hau:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Leihoaren _goialdea" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Leihoaren goialdea" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Hasi hemendik:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Bilaketa jarraitua" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Bilatu _atzerantz" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Bilaketaren norabidea:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Maiuskula/minuskula" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "_Hitz osoak soilik" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Aukerak:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Lehenetsia" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Maiuskulak" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiperesteka" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplikazioa" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Leihoa" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu pantaila-irakurlea" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Laguntza" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Aplikatu" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Eramangarria" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Teklatuaren diseinua" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Profil aktiboa:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Hasierako profila:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Kargatu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Gorde _honela" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Kendu" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profilak" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Adierazi argibideak" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Irakurri saguaren azpiko _objektua" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Sagua" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Orduaren formatua:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "_Dataren formatua:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Ordua eta data" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Esan eguneratzeak" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Braille eguneratzeak" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Maiztasuna (seg.):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Honi aplikatua:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Bee_p eguneratzeak" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Aurrerapen-barraren eguneratzeak" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Gaitu _atzera joatea eta aurrera azkar joatea 'Esan dena' aukeran" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Gaitu _egiturazko nabigazioa 'Esan dena' aukeran" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Esan dena honen _arabera:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Iragarri aipu-_blokeak 'Esan dena' aukeran" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Iragarri _zerrendak 'Esan dena' aukeran" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Iragarri _taulak 'Esan dena' aukeran" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Iragarri _panelak 'Esan dena' aukeran" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Iragarri _inprimakiak 'Esan dena' aukeran" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Iragarri erreferentzia-puntuak 'Esan dena' aukeran" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Esan dena" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Elementuaren _aurkezpena:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Orokorra" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Bo_lumena:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "To_nua:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Maiztasuna:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Pertsona:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Hizkuntza:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Ahots-sinteti_zatzailea:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Ahots-s_istema:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Ahots mota:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Maiuskulen estiloa:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Ahots motaren ezarpenak" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Irakurri Maiuskulak dituzten kateak _hitz gisa" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Esan _zenbakiak digitu eran" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Ahots orokorraren ezarpenak" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Ahotsa" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Gaitu ahotsa" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Xehatua" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Xehetasun-maila" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Denak" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Puntuazio-maila" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Soilik bistaratutako testua irakurri" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Irakurri lerro hutsak" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Irakurri _koskak eta justifikazioak" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "I_rakurri objektu mnemoteknikoak" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Irakurri haurraren _posizioa" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Irakurri tutoretzako mezuak" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Sistema-mezuak xeheak dira" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "I_rakurri koloreak izen modura" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Iragarri aipu-_blokeak nabigazioan" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Iragarri _zerrendak nabigazioan" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Iragarri _taulak nabigazioan" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Irakurri gaizki idatzitako _hitzen adierazlea" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Iragarri _panelak nabigazioan" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Iragarri e_rreferentzia-puntuak nabigazioan" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Iragarri _inprimakiak nabigazioan" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Irakurri _deskribapena" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Irakurri errenkada osoa _kalkulu-orrietan" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Irakurri errenkada osoa _dokumentu-tauletan" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Irakurri errenkada osoa _GUI tauletan" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Irakurketaren testuingurua" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Ahotsa" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Gaitu braille-_euskarria" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Rol-izen laburtuak" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Desgaitu lerro amaierako ikurra" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Uzkurduraren _taula:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Gaitu uzkurtutako Braille" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Gaitu hitzen e_gokitzea" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Pantailaren ezarpenak" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Bat ere ez" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Hautapenaren adierazlea" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hiperestekaren adierazlea" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Gaitu _mezu keinukariak" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "I_raupena (seg):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Mezuak _iraunkorrak dira" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Mezuak _xeheak dira" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Mezu keinukarien ezarpenak" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braillea" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Gaitu _teklen oihartzuna" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Gaitu tekla _alfabetikoak" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Gaitu _zenbakizko teklak" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Gaitu _puntuazio-teklak" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Gaitu _zuriunea" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Gaitu tekla _aldatzaileak" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Gaitu _funtzio-teklak" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Gaitu e_kintza-teklak" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Gaitu _nabigazio-teklak" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Gaitu _hitzen oihartzuna" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Gaitu oihartzuna _sententzien arabera" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Oihartzuna" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Pantaila-irakurlearen tekla _aldatzailea(k):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Laster-teklak" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Ahoskeraren hiztegia" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Sarrera berria" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "Ez_abatu" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Ahoskera" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Irakurri dena" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Bat ere _ez irakurri" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Berrezarri" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Testuaren atributuak" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mugitu b_eheraino" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mugitu bat _behera" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mugitu bat _gora" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mugitu g_oraino" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Doitu hautatutako atributua" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Braille-adierazlea" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Testuaren atributuak" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Gaitu AI laguntzailea" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Hornitzailea:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokala - Doakoa)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API _gako fitxategia:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "API gako fitxategiaren bidea" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Lortu _Claude API gakoa" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Ireki nabigatzailea Claude API gakoa lortzeko eta automatikoki gordetzeko" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Berrespena eskatu AI ekintzen aurretik" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _eredua:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Ollama-ren eredu izena (adib., llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _amaiera-puntua:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API amaiera-puntuaren URLa (adib., http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Pantaila-argazkiaren _kalitatea:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "baxua" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Ertaina" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Altua" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI laguntzailea" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Hizkuntza:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "yenaren ikurra" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Eskala faktorea:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Gris-eskalako irudia" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Alderantzikatu irudia" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Zuri-beltza irudia" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Zuri/beltz _ataria:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Aztertu koloreak" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Edukia arbelean kopiatuta." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : Arga, b : Bidasoa, c : Corella, d : Deba, e : Errobi, f : Funes, g : " -"Gorbeia, h : Hernani, i : Ibaizabal, j : Jaizkibel, k : Karrantza, l : " -"Leitzaran, m : Mendaur, n : Nerbioi, o : Oka, p : Pagoeta, q : Queiles, r : " -"Rivabellosa, s : Saioa, t : Toloño, u : Urola, v : Villanueva, w : " -"Washington, x : Xabier, y : Yemen, z : Zaraitzu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "atzeko planoaren kolorea" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "atzeko planoaren altuera osoa" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "atzeko planoa puntukatua" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "norabidea" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editagarria" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "letra-familia" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "aurreko planoaren kolorea" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "aurreko planoa puntukatua" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "letra-efektua" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "koska" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "gaizki idatzita" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "ikusezina" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justifikazioa" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "hizkuntza" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "ezkerreko marjina" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "lerroaren altuera" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "paragrafo-estiloa" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "lerroen gaineko pixelak" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "lerroen azpiko pixelak" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "egokitzearen barruko pixelak" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "eskuineko marjina" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "goratu" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "eskala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "tamaina" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "tiratu" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "marratu" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estiloa" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "testuaren dekorazioa" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "testuaren biraketa" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "testuaren itzala" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "azpimarra" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "aldagaia" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "lerrokatze-bertikala" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "pisua" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "egokitze modua" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "idazketa modua" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "egia" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "faltsua" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "bat ere ez" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "grabatu" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "bozeldu" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "eskema" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "goimarra" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "marratua" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "keinuka" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "beltza" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "bakuna" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "bikoitza" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "baxua" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "karakterea" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "hitza" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "hitz-karakterea" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ezk->esk" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "esk->ezk" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "ezkerrera" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "eskuinera" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "zentratuta" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "justifikaziorik gabe" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "betegarria" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra-estutua" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "estra-estutua" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "estutua" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "erdi-estutua" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normala" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "erdi-hedatua" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "hedatuta" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "estra-hedatua" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra-hedatua" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "maiuskula txikiak" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "zeiharra" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "etzana" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Lehenetsia" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Testuaren gorputza" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Izenburua" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "oinarri-lerroa" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "azpindizea" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "goi-indizea" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "goian" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "testua goian" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "erdian" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "behean" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "testua behean" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "heredatua" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "ezkesk-goibehe" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "eskezk-goibehe" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "goibehe-eskezk" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "goibehe-ezkesk" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "behegoi-eskezk" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "behegoi-ezkesk" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "ezkesk" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "eskezk" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "goibehe" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "lisoa" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "akats ortografikoa" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Sakatu zuriunea txandakatzeko." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Sakatu zuriunea hedatzeko, eta erabili gora eta behera teklak elementu bat " -"hautatzeko." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Sakatu Alt+F6 teklak fokua leiho umeei emateko." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Elementuak lekuz aldatzeko, erabili teklatuko geziak, edo idatzi bilatzeko." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Sistemako menuak lortzeko, sakatu Alt+F1 teklak." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Erabili gora eta behera geziak elementu bat hautatzeko." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Sakatu Maius+Ezkerrera tolesteko." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Sakatu Maius+Eskuinera hedatzeko." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Sakatu Sartu aktibatzeko." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Idatzi testuan." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Erabili ezkerrera eta eskuinera beste fitxak ikusteko." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Sakatu zuriunea aktibatzeko." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Erabili gorako edo beherako gezia balioa hautatzeko. Edo idatzi nahi den " -"zenbakizko balioa." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Erabili teklatuko geziak aldatzeko." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Nabigatzeko, sakatu ezkerrerako edo eskuinerako gezia. Elementuen artean " -"nabigatzeko, sakatu gorako edo beherako gezia." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Sakatu eskuinera gezia azpimenuan sartzeko." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Sakatu ezkerrerako gezia txikiagotzeko, eskuinerako gezia handiagotzeko. " -"Sakatu Hometekla minimora joateko, eta End maximora joateko." diff --git a/po/fa.po b/po/fa.po deleted file mode 100644 index 5c75044..0000000 --- a/po/fa.po +++ /dev/null @@ -1,9139 +0,0 @@ -# Persian translation for cthulhu. -# Copyright (C) 2022 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Danial Behzadi , 2022-2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-10-23 15:17+0330\n" -"Last-Translator: Danial Behzadi \n" -"Language-Team: Persian \n" -"Language: fa\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.4\n" - -msgid "Cthulhu Screen Reader" -msgstr "صفحه‌خوان اورکا" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "؟؟؟" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "شماره‌گیری" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "زبان نشانه‌گذاری فرامتن" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "ترسیم" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "فرم" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "رادیویی" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "چکی سطح ۱" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "اسپانیایی سطح ۱" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "فرانسوی کانادا سطح ۲" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "فرانسوی فرانسه سطح ۲" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "نروژی سطح ۰" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "نروژی سطح ۱" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "نروژی سطح ۲" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "نروژی سطح ۳" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "لهستانی سطح ۱" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "پرتغالی سطح ۱" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "سوئدی سطح ۱" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "عربی سطح ۱" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "آلمانی سطح ۰" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "آلمانی سطح ۱" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "آلمانی سطح ۲" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "انگلیسی بریتانیایی سطح ۲" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "انگلیسی بریتانیایی سطح ۱" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "انگلیسی آمریکایی سطح ۱" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "انگلیسی آمریکایی سطح ۲" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "فرانسوی کانادا سطح ۱" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "فرانسوی فرانسه سطح ۱" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "یونانی سطح ۱" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "هندی سطح ۱" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "مجاری سطح ۱" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "مجاری سطح ۲" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "ایتالیایی سطح ۱" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "آلمانی بلژیکی سطح ۱" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "فاصله" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "خط جدید" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "جهش" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "نقل‌قول" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "شماره" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "دلار" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "درصد" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "و" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "آپاستروف" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "پرانتز چپ" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "پرانتز راست" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "ستاره" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "مثبت" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "کاما" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "خط تیره" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "نقطه" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "اسلش" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "دونقطه" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "نقطه‌ویرگول" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "کوچک‌تر" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "مساوی" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "بزرگ‌تر" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "پرسش" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "در" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "قلاب چپ" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "اسلش معکوس" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "قلاب راست" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "هشتی" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "زیرخط" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "گور" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "آکولاد چپ" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "خط عمودی" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "آکولاد راست" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "مد" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "فاصلهٔ نشکن" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "علامت تعجب معکوس" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "سنت" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "پوند" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "علامت ارز" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "ین" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "خط شکسته" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "بخش" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "حق رونوشت" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a بالانویس" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "نات منطقی" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "خط ربط نرم" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "ثبت شده" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "درجه" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "مثبت یا منفی" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "۲ بالانویس" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "۳ بالانویس" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "حاده" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "مو" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "علامت‌گذار بند" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "نقطهٔ میانی" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "۱ بالانویس" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ترتیبی" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "یک‌چهارم" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "یک‌دوم" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "سه‌چهارم" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "علامت سوال معکوس" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "گور" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "ضرب در" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "تقسیم بر" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "فلورین" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "خنجر" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "خنجر جفت" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "گلوله" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "گلولهٔ سه‌گوش" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "بر مایل" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "گلوله خط نرم" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "یورو" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "علامت ثبت شده" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "تیک" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "تیک قوی" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "گلوله ضربدری" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "۰ بالانویس" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "۴ بالانویس" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "۵ بالانویس" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "۶ بالانویس" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "۷ بالانویس" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "۸ بالانویس" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "۹ بالانویس" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "مثبت بالانویس" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "منفی بالانویس" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "مساوی بالانویس" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "پرانتز چپ بالانویس" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "پرانتز راست بالانویس" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n بالانویس" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "۰ پایین‌نویس" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "۱ پایین‌نویس" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "۲ پایین‌نویس" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "۳ پایین‌نویس" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "۴ پایین‌نویس" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "۵ پایین‌نویس" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "۶ پایین‌نویس" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "۷ پایین‌نویس" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "۸ پایین‌نویس" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "۹ پایین‌نویس" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "مثبت پایین‌نویس" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "منفی پایین‌نویس" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "مساوی پایین‌نویس" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "مربع سیاه" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "الماس سیاه" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "کل پرونده را بخوان" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "با بازنگری ساده کل پنجره را بخوان" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "تنظیمات گونهٔ صدا" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "رفتن به مکان نشانک پیشین" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "رفتن به نشانک" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "رفتن به مکان نشانک بعدی" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "افزودن نشانک" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "ذخیرهٔ نشانک‌ها" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "موقعیت مکان‌نما" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "آبی آلیس" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "سفید آنتیک" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "سیاه" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "آبی" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "بنفش آبی" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "قهوه‌ای" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "شکلاتی" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "فیروزه‌ای" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "آبی تیره" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "فیروزه‌ای تیره" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "خاکستری تیره" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "سبز تیره" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "خاکی تیره" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "زیتونی تیره" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "نارنجی تیره" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "قرمز تیره" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "بنفش تیره" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "صورتی عمیق" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "آبی آسمانی عمیق" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "آجری آتشسن" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "سبز جنگلی" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "ارغوانی" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "سفید روحی" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "طلایی" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "خاکستری" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "سبز" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "زرد سبز" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "صورتی دلغ" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "قرمز هندی" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "عاجی" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "خامی" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "اسطخودوسی" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "آبی روشن" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "فیروزه‌ای روشن" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "خاکستری روشن" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "سبز روشن" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "صورتی روشن" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "سالمونی روشن" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "سبز دریایی روشن" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "آبی آسمانی روشن" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "آبی فولادی روشن" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "زرد روشن" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "لیمویی" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "سبز لیمویی" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "سرخ" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "آبی متوسّط" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "بنفش متوسّط" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "سبز دریایی متوسّط" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "سبز بهاری متوسّط" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "قرمز بنفش متوسّط" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "آبی نیمه‌شب" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "کرم نعنایی" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "سفید ناواهو" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "دریایی" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "زیتونی" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "نارنجی" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "قرمز نارنجی" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "سبز رنگ‌پریده" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "قرمز بنفش رنگ‌پریده" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "صورتی" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "آبی پودری" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "بنفش" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "قرمز" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "آبی سلطنتی" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "سالمونی" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "قهوه‌ای شنی" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "سبز دریایی" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "نقره‌ای" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "آبی آسمانی" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "برفی" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "سبز بهاری" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "آبی فولادی" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "برنزی" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "بنفش" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "گندمی" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "سفید" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "دودی سفید" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "زرد" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "سبز زرد" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_فعّال‌سازی" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_لغو" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_پرش به" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_تأیید" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "نقشک" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "هیچ" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "نوشتار" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "دوبار کلیک" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "سه‌بار کلیک" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "گزینه‌های یافتن" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "فرمان" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "پیش‌گزیده" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "کنش‌ها" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "نشانک‌ها" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "پیمایش شی" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "تغییریافته" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_میزکار" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "آگاهی‌ها" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "دریافت شد" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "همه" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "برنامه" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "پنجره‌" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_هیچ‌کدام" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "خط" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "نقل نقول" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "دکمه" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "عنوان" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "کادر" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "قابل کلیک" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "جعبهٔ ترکیبی" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "شرح" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "عنوان" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "قاب درونی" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "برچسب" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "نشانه" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "سطح" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "پیوند" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "فهرست" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "مورد سیاهه" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "شئ" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "پاراگراف" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "دکمهٔ رادویی" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "نقش" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "مورد گزیده" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "وضعیت" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "متن" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "آدرس اینترنتی" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "مقدار" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "نقل قول‌ها" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "دکمه‌ها" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "کادرها" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "کلیک‌پذیرها" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "جعبه‌های ترکیبی" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "ورودی‌ها" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "زمینه‌های فرم" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "عنوان‌ها" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "قاب‌های درونی" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "تصاویر" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "عنوان‌های با سطح %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "نشانه‌ها" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "اشیای بزرگ" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "پیوندها" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "سیاهه‌ها" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "موارد سیاهه" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "بند" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "دکمه‌های رادیویی" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "جدول‌ها" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "پیوندهای دیده نشده" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "پیوندهای دیده شده" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "پیش‌گزیده" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "ابرپیوند" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "سامانه" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "حروف بزرگ" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "بررسی نوشتار" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "پویش جدول" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d آگاهی" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "تبدیل" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "دگرساز" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "واپایش" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "پایین" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "چپ" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "راست" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "فهرست" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "پایان" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "منها" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "درج" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "سوپر" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "مهار" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "تبدیل" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s پر" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s کج" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s کج پر" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s کدنوشته" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s کدنوشتهٔ پر" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s شکسته" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s دوخط دار" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s شکستهٔ پر" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s بدون سریف" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s بدون سریف پر" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s بدون سریف کج" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s بدون سریف کج پر" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s تک‌عرض" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s بی‌نقطه" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "پیکان چپ" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "پیکان بالا" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "پیکان راست" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "پیکان پایین" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "پیکان راست پایین" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "پیکان پایین بالا" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "پیکان شمال غربی" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "پیکان شمال شرقی" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "پیکان جنوب شرقی" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "پیکان چپ از نوار" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "پیکان بالا از نوار" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "پیکان راست از نوار" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "پیکان پایین از نوار" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "جفت پیکان چپ" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "جفت پیکان بالا" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "جفت پیکان راست" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "جفت پیکان پایین" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "جفت پیکان راست چپ" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "جفت پیکان پایین بالا" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "جفت پیکان شمال غربی" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "جفت پیکان شمال شرقی" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "جفت پیکان جنوب شرقی" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "جفت پیکان جنوب غربی" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "پیکان رو به راست" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "سر پیکان رو به راست" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "منها" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "کوچک‌تر از" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "بزرگ‌تر از" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "نقطه" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "دو خط عمودی" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "بیضی افقی" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "برای همه" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "متمّم" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "دیفرانسیل جزیی" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "وجود دارد" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "وجود ندارد" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "مجموعهٔ خالی" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "افزایش" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "مجموع" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "مثبت منها" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "تقسیم" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "ریشهٔ مربّع" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "ریشهٔ مکعّب" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "ریشهٔ چهارم" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "بی‌نهایت" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "زاویهٔ قائمه" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "زاویه" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "و منطقی" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "یای منطقی" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "اجتماع" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "انتگرال" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "انتگرال دوگانه" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "انتگرال سگانه" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "انتگرال کانتور" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "انتگرال سطح" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "انتگرال حجم" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "انتگرال ساعتگرد" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "انتگرال پادساعتگرد" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "انتگرال کانتور پادساعتگرد" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "نسبت" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "مد" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "درست" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "نادرست" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "زیرمجموعهٔ دوگانه" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "فرامجموعهٔ دوگانه" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "اجتماع دوگانه" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "برنامه" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "هیج نشانکی پیدا نشد." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "نقشک" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "هیچ" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "نوشتار" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s گزیده" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s تا %s گزیده شد" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s تا %s گزیده نشد" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s گزیده نشد" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "نگارش این برنامه" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FILE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "برش" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "رونوشت شد" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "جایگذاشته شد" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "آغاز حذف" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "پایان حذف" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "آغاز درج" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "پایان درج" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "آغاز برجسته سازی" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "پایان برجسته سازی" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "پایان پیشنهاد" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "خالی" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "کلید" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "هیچ‌کدام" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "کلید و واژه" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "جمله" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "واژه" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "واژه و جمله" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "پایان جدول" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "پایان جدول تودرتو" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "از کار افتاده" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "فعال شده" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "پیوند" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "پیدا نشد" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "خاموش" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "حالت تمرکز" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "آگاهی" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "پایین" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "بالا" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "رقم‌ها" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "واژّ‌ها" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "خاموش" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "همه" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "بیش‌تر" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "هیچ‌کدام" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "برخی" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "صفحه‌خوان اورکا" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_نرخ:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "_حجم:" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "سطح پرگویی: خلاصه" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "سطح پرگویی: پرگو" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "پیدا نشد" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "پیدا نشد" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "گزیده شد" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "گزیده نشد" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "%s یونی‌کد" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "برگردان" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "انجام دوباره" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "فضای خالی" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "پیچش به پایین." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "پیچش به بالا." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "۰ مورد" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d ستون" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d نویسه بیش از حد طولانی" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d گفت‌وگو)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d گفت‌وگوی بدون تمرکز" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d بایت" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d پرونده پیدا شد" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d فرم" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d عنوان" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d مورد" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d نشانه" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d مورد پیدا شد" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "ترک %d نقل‌قول." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "ترک %d سیاهه." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "سیاهه‌ای با اندازهٔ ناعلوم" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "سیاهه‌ای با %d مورد" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "خوراکی با اندازهٔ نامعلوم" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "خوراکی با %d مقاله" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "سیاههٔ شرحی با %d عبارت" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d مقدار" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "جدول ریاضی با %d ردیف" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d ردیف" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "جدول ریاضی تودرتو با %d ردیف" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d پیام.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d درصد." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d درصد از سند خوانده شد" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d پیکسل" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d نویسهٔ %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d از %(total)d مورد گزیده شد" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d میان‌بر پیش‌گزیدهٔ صفحه‌خوان پیدا شد." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d میان‌بر صفحه‌خوان برای %(application)s پیدا شد." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d فاصله" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d جهش" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d جدول" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "جدولی با اندازهٔ نامعلوم" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "جدولی با %d ستون، شمار ردیف‌ها نامعلوم" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "جدولی با %d ردیف، شمار ستون‌ها نامعلوم" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "جدولی با %d ردیف" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d ثانیه پیش" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d دقیقه پیش" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d ساعت پیش" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d روز پیش" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d پیوند دیده نشده" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d پیوند دیده شده" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "تغییر وضعیت" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "در %(index)d از %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d از %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "مورد %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "سطح %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "سطح درخت %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "سطح درخت %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "جزییات %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "جزییاتی در %s دارد" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "جعبهٔ بازشوندهٔ ویرایش‌پذیر" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "محتوای ویرایش‌پذیر" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "خوراک" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "خلاصه" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "قدردانی‌ها" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "خاتمه" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "پیوست" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "ورودی کتابشناسی" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "کتابشناسی" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "فصل" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "نتیجه‌گیری" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "جلد" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "اعتبار" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "اعتبارها" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "اهدا" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "پی‌نوشت" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "پی‌نوشت‌ها" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "پایان‌نامه" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "غلط‌نامه" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "مثال" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "پیش‌گفتار" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "واژه‌نامه" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "نمایه" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "مقدمه" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "شکست صفحه" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "سیاههٔ صفحه‌ها" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "بخش" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "پیش‌درامد" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "دیباچه" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "پرسش و پاسخ" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "زیرعنان" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "جدول محتویات" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "س%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s سطح %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "نوار لغزش افقی" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "نوار لغزش عمودی" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "سرندهٔ افقی" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "سرندهٔ عمودی" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "جداساز افقی" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "جداساز عمودی" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "کلید" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "تابلوی نقشک" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "بیرق" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "محتوی تکمیلی" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "اطّلاعات" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "محتوای اصلی" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "ناوبری" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "ناحیه" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "جست‌وجو" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "پیوند دیده شده" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "دکمهٔ فهرست" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "صعودی مرتّب شده" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "نزولی مرتّب شده" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "مرتّب شده" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "قابل کلیک" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "جمع شده" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "گسترده" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "توضیحات بلندی دارد" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "افقی" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "عمودی" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "بررسی شد" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "بررسی نشد" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "خاموش" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "تقریبی بررسی شد" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "فشرده شده" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "فشرده نشده" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "ناگزیده" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "گزیده شد" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ناگزیده" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "ناگزیده" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "دیده شده" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "دیده نشده" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "خاکستری شده" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "فقط خواندنی" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "فقط‌خواندنی" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "لازم" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "چندگزینشی" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "ورودی نامعتبر" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "نامعتبر" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "نوشتار نامعتبر" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "نوشتار" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "نگارش نامعتبر" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "نگارش" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "یافتن" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "گفت‌وگوی یافتن صفحه‌خوان" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_بستن" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_یافتن" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_جست‌وجو برای:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "جست‌وجو برای:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_بالای پنجره" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "بالای پنجره" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "آغاز از:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_دور زدن" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "جست‌وجو به _عقب" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "جهت جست‌وجو:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_تطبیق بزرگی و کوچکی" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "فقط تطبیق _تمام واژه" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "گزینه‌ها:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "پیش‌گزیده" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "حروف بزرگ" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "ابرپیوند" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "سامانه" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "برنامه" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "پنجره‌" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "صفحه‌خوان اورکا" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_راهنما" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_اِعمال" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_لپ‌تاپ" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "چیدمان صفحه‌کلید" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_نمایهٔ فعّال:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "نمایهٔ آغاز:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_بار کردن" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "ذخیره به _شکل" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_‌حذف" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "نمایه‌ها" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_ارائه ایمای ابزار" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "گفتن اشیای زیر _موشی" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "موشی" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "قالب _زمان:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "_قالب تاریخ:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "تاریخ و زمان" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "به‌روز رسانی‌های _گفتنی" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "به‌روز رسانی‌های _بریلی" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "۱۰" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "بسامد (ثانیه):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "اعمال به:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "به‌روز رسانی‌های بو_قی" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "به‌روز رسانی‌های نوار پیشرفت" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "به کار انداختن _پس‌روی و پیش‌روی سریع در گفتن همه" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "به کار انداختن پیمایش _ساختاری در گفتن همه" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "گفتن همه به _دست:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "اعلام نقل‌_قول‌ها در گفتن همه" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "اعلام _سیاهه‌ها در گفتن همه" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "اعلام _جدول‌ها در گفتن همه" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "اعلام _تابلوها در گفتن همه" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "اعلام _فرم‌ها در گفتن همه" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "اعلام _نشانه‌ها در گفتن همه" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "گفتن همه" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "عمومی" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_حجم:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_تن:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_نرخ:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_شخص:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_زبان:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "_تجزیه‌گر گفتار:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_سامانهٔ گفتار:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_گونهٔ صدا:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "سبک _بزرگ کردن حروف:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "تنظیمات گونهٔ صدا" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "گفتن رشته‌های چندحالته به شکل _واژه" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "گفتن _عددها به شکل رقم" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "تنظیمات صدای جهانی" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "صدا" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_به کار انداختن گفتار" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_پرگو" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "پرگویی" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_همه" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "سطح نشانه‌گذاری" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "فقط گفتنمتن نمایشی" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "گفتن خط‌های خالی" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "گفتن تورفتگی‌ها و ترازها" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "گفتن _موقعیت فرزند" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "گفتن پیام‌های خودآموز" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "پیام‌های _سامانه‌ای با جزییاتند" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "گفتن _رنگ‌ها با نام" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "اعلام نقل‌_قول‌ها در طول پیمایش" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "اعلام _سیاهه‌ها در طول پیمایش" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "اعلام _جدول‌ها در طول پیمایش" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "گفتن نشانگر _اشتباه نوشتاری" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "اعلام _تابلوها در طول پیمایش" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "اعلام _نشانه‌ها در طول پیمایش" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "اعلام _فرم‌ها در طول پیمایش" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "گفتن _شرح" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "گفتن ردیف کامل در _برگه‌های گسترده" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "گفتن ردیف کامل در جدول‌های _سند" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "گفتن ردیف کامل در جدول‌های _میانا" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "بافتار گویشی" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "گفتار" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "به کار انپداختن _پشتیبانی بریل" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "نام نقش‌های _کوتاه شده" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "از کار انداختن نماد پایان _خط" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_جدول اختصار:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_به کار انداختن بریل مختصر" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "به کار انداختن شکستن _واژه" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "تنظیمات نمایشگر" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_هیچ‌کدام" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "نشانگر گزینش" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "نشانگر ابرپیوند" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "به کار انداختن _پیام‌های آنی" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_طول (ثانیه):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "پیام‌ها _ماندگارند" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "پیام‌ها با_جزییاتند" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "تنظمیات پیام آنی" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "بریل" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "به کار انداختن پژواک _کلید" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "به کار انداختن کلیدهای _الفبایی" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "به کار انداختن کلیدهای _عددی" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "به کار انداختن کلیدهای _نشنانه‌گذاری" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "به کار انداختن _فاصله" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "به کار انداختن کلیدهای اصلاح_گر" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "به کار انداختن کلیدهای _تابع" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "به کارانداختن کلیدهای _کنش" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "به کار انداختن کلیدهای _پیمایش" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "به کار انداختن پژواک با _واژه" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "به کار انداختن پژواک با _جمله" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "پژواک" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "کلید(های) _تغییردهندهٔ صفحه‌خوان:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "ترکیب کلیدها" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "واژه‌نامهٔ تلفّظ" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_ورودی جدید" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_حذف" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "تلفّظ" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_گفتن همه" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "گفتن _هیچ" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_بازنشانی" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "ویژگی‌های متن" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "جابه‌جایی به _کف" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "جابه‌جایی به _پایین" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "جابه‌جایی به _بالا" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "جابه‌جایی به _سطح" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "تنظیم ویژگی گزیده" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "نشانگر بریل" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "ویژگی‌های متن" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "_زبان:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "ین" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "رنگ پس‌زمینه" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "بلندای کامل پس‌زمینه" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "پایهٔ پس‌زمینه" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "جهت" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "ویرایش‌پذیر" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "نام خانوادگی" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "رنگ پیش‌زمینه" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "پایهٔ پیش‌زمینه" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "جلوهٔ قلم" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "تو رفتگی" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "اشتباه" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "نامریی" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "هم‌ترازی" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "زبان" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "حاشیهٔ چپ" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "بلندای خط" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "سبک بند" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "پیکسل بالای خط‌ها" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "پیکسل زیر خط‌ها" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "پیشکل داخل پیچش" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "حاشیهٔ راست" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "بالا بردن" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "مقیاس" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "اندازه" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "کشیده" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "خط‌خورده" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "سبک" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "تزیینات متن" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "چرخش متن" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "سایهٔ متن" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "زیرخط" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "دگرگونه" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "جا گذاری عمودی" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "وزن" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "حالت پیچاندن" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "حالت نوشتن" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "درست" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "نادرست" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "هیچ" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "سیاه" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "دو برابر" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "واژه" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "چپ به راست" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "راست به چپ" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "چپ" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "راست" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "مرکز" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "بدون هم‌ترازی" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "پر کردن" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "معمولی" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "گسترده" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "پیش‌گزیده" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "عنوان" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "نوشتار" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "فاصله را برای تغییر حالت بزنید." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"برای گشایش فاصله را زده و برای گزینش مورد از بالا و پایین استفاده کنید." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "دگرساز+F6 را برای دادن تمرکز به پنجرهٔ فرزند بزنید." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "برای جابه‌جایی موارد از کلیدهای جهت‌دار یا جست‌وجو با نوشتن استفاده کنید." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "برای دریافت فهرست‌های سیستم کلید تعویض+تابع۱ را بفشارید." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "استفاده از بالا و پایین برای انتخاب یک گزینه." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "برای پراکنش، شیفت و چپ را بفشارید." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "برای گسترش، شیفت و راست را بفشارید." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "برای فعال‌سازی بازگشت را بفشارید." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "نوشتن در متن." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "استفاده از چپ و راست برای نمایش زبانه‌های دیگر." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "برای فعال‌سازی کلید فاصله را بفشارید." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"از کلیدهای جهتی بالا یا پایین برای انتخاب مقدار استفاده کنید. یا مقدار " -"دلخواه عددیتان را بنویسید." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "برای تغییر از کلیدهای جهتی استفاده کنید." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"برای ناوبری، کلید جهت‌های راست و چپ را بفشارید. برای حرکت میان گزینه‌ها، " -"کلیدهای بالا یا پایین را بفشارید." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "برای ورود به زیرمنو، کلید جهت راست را فشار دهید." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"برای کاهش کلید جهت چپ را فشار دهید، برای افزایش کلید جهت راست را فشار دهید. " -"برای حداقل کلید خانه و برای حداکثر کلید پایان را فشار دهید." diff --git a/po/fi.po b/po/fi.po deleted file mode 100644 index 23303bf..0000000 --- a/po/fi.po +++ /dev/null @@ -1,9489 +0,0 @@ -# Finnish messages for cthulhu. -# Copyright (C) 2006-2009 Ilkka Tuohela, Timo Jyrinki. -# Suomennos: https://l10n.gnome.org/teams/fi/ -# -# Gnome 2012-03 Finnish translation sprint participants: -# -# Ilkka Tuohela , 2006-2009. -# Timo Jyrinki , 2008. -# Tommi Vainikainen , 2010. -# Lasse Liehu , 2014. -# Jiri Grönroos , 2011, 2012, 2013, 2014. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-17 22:23+0300\n" -"Last-Translator: Jiri Grönroos \n" -"Language-Team: suomi \n" -"Language: fi\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-POT-Import-Date: 2012-03-05 14:45:41+0000\n" -"X-Generator: Poedit 3.3.2\n" -"X-Poedit-Bookmarks: 814,-1,-1,-1,-1,-1,-1,-1,-1,-1\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu-näytönlukija" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "näyttö;lukija;saavutettavuus;puhe;pistekirjoitus;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "hlts" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "nli" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "kng" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "ots" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "vlr" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "värval" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "srkots" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "yhd" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "pvm" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "kvk" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "khs" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "nmrlv" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "vli" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "hkmpn" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "prt" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "tdval" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "tyt" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "krj" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "kvk" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "lspn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "ots" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "kv" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "skh" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "nmm" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "krpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstkht" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "val" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "valkplk" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "valkht" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "valpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "vlt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "srklst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "sal" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "pnhvlk" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "edpal" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "pnk" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "vpk" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "vevk" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "jrpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rvots" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "vrtplk" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "vrp" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "osio" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "ertn" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "lku" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "jpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "krt" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "tlplk" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tlk" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "solu" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "irrvalkht" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "pte" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "vpnk" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tklplk" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "vhj" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "puu" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "puutlu" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "tnt" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "nkm" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "ikn" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "ots" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "avt" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "kpl" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "sov" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "mknplk" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "upt" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Tsekki taso 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Espanja taso 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanadan ranska taso 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Ranska taso 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvia taso 2" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Hollannin hollanti taso 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norja taso 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norja taso 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norja taso 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norja taso 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Puola taso 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugali taso 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Ruotsi taso 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabia taso 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Iiri taso 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Iiri taso 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Saksa taso 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Saksa taso 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Saksa taso 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Brittienglanti taso 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Brittienglanti taso 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Amerikanenglanti taso 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Amerikanenglanti taso 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadan ranska taso 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Ranska taso 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Kreikka taso 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi taso 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Unkari, 8 pistettä, tietokone" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Unkari taso 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Unkari taso 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italia taso 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgian hollanti taso 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "välilyönti" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "rivinvaihto" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "sarkain" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "huuto" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "lainaus" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "numero" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollari" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "prosentti" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ja" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "heittomerkki" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "vasen sulku" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "oikea sulku" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "tähti" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "pilkku" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "viiva" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "piste" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "kautta" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "kaksoispiste" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "puolipiste" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "pienempi kuin" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "yhtäsuuri" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "suurempi kuin" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "kysymys" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "vasen hakasulku" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "kenoviiva" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "oikea hakasulku" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "kohdistin" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "alaviiva" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "takahipsu" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "vasen aaltosulku" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "pystyviiva" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "oikea aaltosulku" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "ei-katkaiseva väli" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "huutomerkki ylösalaisin" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "sentti" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "punta" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "valuuttamerkki" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jeni" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "katkaistu palkki" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "pykälä" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "tekijänoikeudet" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "yläindeksi a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "vasen kaksoishakasulku" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "looginen ei" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "pehmeä väliviiva" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "rekisteröity" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "yläviiva" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "astetta" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus-miinus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "yläindeksi 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "yläindeksi 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "akuutti" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "kappalemerkki" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "keskipiste" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "yläindeksi 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "järjestysnumero" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "oikea kaksoishakasulku" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "neljäsosa" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "puolikas" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "kolme neljäsosaa" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "kysymysmerkki ylösalaisin" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a akuutti" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVIS" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A HIPSU" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A SIRKUMFLEKSI" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "Ä" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "RUOTSALAINEN O" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVIS" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AKUUTTI" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E SIRKUMFLEKSI" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVIS" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AKUUTTI" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I SIRKUMFLEKSI" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVIS" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AKUUTTI" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O SIRKUMFLEKSI" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "Ö" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "kertaa" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "NORJALAINEN Ö" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVIS" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AKUUTTI" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U SIRKUMFLEKSI" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AKUUTTI" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "suhuässä" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a gravis" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a sirkumfleksi" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "ä" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "ruotsalainen å" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e gravis" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e akuutti" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e sirkumfleksi" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e-umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i gravis" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i akuutti" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i sirkumfleksi" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o gravis" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o akuutti" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o sirkumfleksi" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "ö" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "jaettuna" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "norjalainen ö" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u gravis" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u akuutti" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u sirkumfleksi" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y akuutti" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "floriini" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "pitkä viiva" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "yksinkertainen vasen lainausmerkki" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "yksinkertainen oikea lainausmerkki" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "yksinkertainen alalainausmerkki" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "kaksinkertainen vasen lainausmerkki" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "kaksinkertainen oikea ainausmerkki" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "kaksinkertainen alalainausmerkki" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "risti" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "kaksoisristi" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "luettelomerkki" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "kolmikulmainen luettelomerkki" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "hipsu" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "kaksoishipsu" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "kolmoishipsu" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "luotiviiva" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "tavaramerkki" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "rastimerkki" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "raskas rastimerkki" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-muotoinen luettelomerkki" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "yläindeksi 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "yläindeksi 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "yläindeksi 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "yläindeksi 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "yläindeksi 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "yläindeksi 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "yläindeksi 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "yläindeksi plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "yläindeksi miinus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "yläindeksi yhtä kuin" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "yläindeksi vasen sulku" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "yläindeksi oikea sulku" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "yläindeksi n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "alaindeksi 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "alaindeksi 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "alaindeksi 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "alaindeksi 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "alaindeksi 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "alaindeksi 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "alaindeksi 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "alaindeksi 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "alaindeksi 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "alaindeksi 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "alaindeksi plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "alaindeksi miinus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "alaindeksi yhtä kuin" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "alaindeksi vasen sulku" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "alaindeksi oikea sulku" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "musta neliö" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "musta timantti" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "rakenneosio-objektin sijaismerkki" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Siirrä kohdistin tämänhetkiseen kohtaan" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Suorita vasen napsautus nykyiselle tasatun tarkastelun kohdalle" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Suorita oikea napsautus nykyiselle tasatun tarkastelun kohdalle" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Puhu koko asiakirja" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Puhu koko ikkuna käyttäen tasattua tarkastelua" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Suorita perustason Missä olen -toiminto" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Suorita tarkempi Missä olen -toiminto" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Puhu nykyinen valinta" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Puhuu linkin yksityiskohdat" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Esitä oletuspainike" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Lue tilarivi" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Lue otsikkorivi" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Avaa hakuikkuna" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Näytä toimintolista" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Etsi merkkijonon seuraava esiintymä" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Etsi merkkijonon edellinen esiintymä" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Ota käyttöön tai pois tasatun tarkastelun tila" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Siirrä tasattu tarkastelu loppusijaintiin" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Siirrä tasattu tarkastelu kotisijaintiin" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Siirrä tasattu tarkastelu loppusijaintiin" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Siirrä tasattu tarkastelu edellisen rivin alkuun" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Puhu nykyisen tasatun tarkastelun rivi" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Tavaa nykyinen tasatun tarkastelun rivi" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Lausu foneettisesti nykyisen tasatun tarkastelun rivi" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Siirrä tasattu tarkastelu seuraavan rivin alkuun" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Siirrä tasattu tarkastelu edelliseen kohtaan tai sanaan" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Puhu nykyisen tasatun tarkastelun kohde tai sana" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Tavaa nykyisen tasatun tarkastelun kohta tai sana" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Lausu foneettisesti nykyisen tasatun tarkastelun kohta tai sana" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Siirrä tasattu tarkastelu seuraavaan kohtaan tai sanaan" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Siirrä tasattu tarkastelu nykyisen sanan yllä olevaan sanaan" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Puhu nykyinen tasatun tarkastelun kohde" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Siirrä tasattu tarkastelu nykyisen sanan alla olevaan sanaan" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Siirrä tasattu tarkastelu edelliseen merkkiin" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Puhu valittu tasatun tarkastelun merkki" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Puhu foneettisesti valitun tasatun tarkastelun merkki" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Puhu valitun tasatun tarkastelun merkin Unicode-arvo" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Siirrä tasattu tarkastelu seuraavaan merkkiin" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Siirrä tasattu tarkastelu rivin loppuun" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Siirrä tasattu tarkastelu alimpaan vasemmalle" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Kopioi leikepöydälle nykyisen tasatun tarkastelun kohdan sisältö" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Lisää leikepöydän jatkeeksi nykyisen tasatun tarkastelun sisältö" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Siirrä tasattu tarkastelu loppusijaintiin" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Luetaanko vain nykyinen taulukon solu vai koko rivi" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Lue tekstin ulkoasuun liittyvät ominaisuudet" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Siirrä pistenäyttöä vasemmalle" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Siirrä pistenäyttöä oikealle" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Palaa kohteeseen, jolla on näppäimistön kohdistus" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Ota lyhennetty pistekirjoitus käyttöön tai pois päältä" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Käsittele kursorin reitityspainike" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Merkitse tekstivalinnan alkukohta" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Merkitse tekstivalinnan loppukohta" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Siirry oppimistilaan. Sulje oppimistila painamalla Escape-näppäintä" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Hidasta puhetta" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Nopeuta puhetta" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Madalla puheen korkeutta" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Nosta puheen korkeutta" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Nosta puheen äänenvoimakkuutta" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Vähennä puheen äänenvoimakkuutta" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Valitse edellinen puhe­asetus" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Valitse seuraava puhe­asetus" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Pienennä nykyistä puhe­asetusta" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Suurenna nykyistä puhe­asetusta" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Tallenna puhe­asetukset" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Vaihtele puheen vaimennusta" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Vaihda puheen yksityiskohtaisuuden tasoa" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Vaihda lepotila" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Lopeta näytönlukija" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Näytä asetusten määrittelyikkuna" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Näytä sovelluksen asetusikkuna" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Ota käyttöön tai pois sisennyksen ja tasauksen puhuminen" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Vaihda numeroiden puhumistapaa" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Vaihda seuraavaan välimerkkien puhumistasoon" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Vaihda seuraavaan näppäinten kaiutustasoon" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Vaihda seuraavaan asetusprofiiliin" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Vaihda seuraavaan isojen kirjainten ilmoitustapaan" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Vaihda seuraavaan näppäinten kaiutustasoon" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Vaihda vianetsinnän tasoa suoritusaikana" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Tee kirjanmerkki siitä, missä olen suhteessa nykyiseen kohtaan" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Siirry edelliseen kirjanmerkkiin" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Siirry kirjanmerkkiin" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Siirry seuraavaan kirjanmerkkiin" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Lisää kirjanmerkki" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Tallenna kirjanmerkit" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Ota käyttöön hiiriosoittimella puhuttaminen" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Näytä nykyinen aika" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Näytä nykyinen päiväys" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Esitä valitun kohteen koko ja sijainti" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Välitä seuraava komento eteenpäin valitulle sovellukselle" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Lausu ja näytä pistekirjoituksena edellinen keskusteluhuoneen viesti" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Määrittää kerrotaanko kun tuttavat kirjoittavat" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Määrittää tarjotaanko keskusteluhuonekohtainen viestihistoria" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "Liitetäänkö keskusteluhuoneen viestien alkuun huoneen nimi vai ei" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Rivi vasemmalle" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Rivi oikealle" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Rivi ylös" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Rivi alas" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Jäädytä" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Vasemmalla ylhäällä" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Vasemmalla alhaalla" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Kohdistimen sijainti" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Kuusipiste" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Kursorin reititys" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Aloita leikkaus" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Leikkaa rivi" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Esitä viimeisin ilmoitusviesti" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Esitä ilmoitusviestien lista" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Esitä edellinen ilmoitusviesti" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Esitä viimeisin ilmoitusviesti" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Siirry seuraavaan merkkiin" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Siirry edelliseen merkkiin" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Siirry seuraavaan sanaan" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Siirry edelliseen sanaan" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Siirry seuraavalle riville" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Siirry edelliselle riville" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Siirry tiedoston alkuun" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Siirry tiedoston loppuun" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Siirry rivin alkuun" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Siirry rivin loppuun" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Siirry seuraavaan rakenneosioon" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Siirry edelliseen rakenneosioon" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Saa tämänhetkisen valintalaatikon laajenemaan" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Vaihda Gecko-ohjelmien oman ja Cthulhun kohdistimella navigoinnin välillä" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Kasvata aktiivisen alueen kohteliaisuustasoa" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Aseta aktiivisten alueiden kohteliaisuustason oletus pois päältä" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Tarkista aktiivisen alueen ilmoitus" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Tarkkaile aktiivisia alueita" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Siirrä kohdistus nykyiseen hiirenkohtaan ja sieltä pois" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Aseta dynaamisia sarakkeiden otsakkeita käyttävä rivi" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Tyhjennä dynaamiset sarakkeiden otsakkeet" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Aseta dynaamisia rivien otsakkeita käyttävä sarake" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Tyhjennä dynaamiset rivien otsakkeet" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Esitä tekstikentän sisältö" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Vaihtele rakenteellisen navigoinnin näppäimiä" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Siirry edelliseen lainauslohkoon" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Siirry seuraavaan lainauslohkoon" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Näytä lista lainauslohkoista" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Siirry edelliseen painikkeeseen" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Siirry seuraavaan painikkeeseen" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Näytä lista painikkeista" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Siirry edelliseen valintaruutuun" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Siirry seuraavaan valintaruutuun" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Näytä valintaruutujen luettelo" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Siirry edelliseen napsautettavaan" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Siirry seuraavaan napsautettavaan" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Näytä lista napsautettavista" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Siirtyy edelliseen valintalaatikkoon" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Siirry seuraavaan valintalaatikkoon" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Siirry rakenneosion alkuun" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Siirry rakenneosion loppuun" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Näytä valintalaatikoiden lista" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Siirry edelliseen kohtaan" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Siirry seuraavaan kohtaan" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Näytä kohtien lista" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Siirry edelliseen lomakkeen kenttään" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Siirry seuraavaan lomakkeen kenttään" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Näytä luettelo lomakekentistä" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Siirry edelliseen otsakkeeseen" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Siirry seuraavaan otsakkeeseen" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Näytä luettelo otsakkeista" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Siirry edelliseen otsakkeeseen tasolla %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Siirry seuraavaan otsakkeeseen tasolla %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Näytä lista tason %d otsikoista" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Siirry edelliseen taulukkoon" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Siirry seuraavaan taulukkoon" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Näytä lista taulukoista" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Siirry edelliseen kuvaan" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Siirry seuraavaan kuvaan" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Näytä luettelo kuvista" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Siirry edelliseen maamerkkiin" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Siirry seuraavaan maamerkkiin" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Näytä lista maamerkeistä" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Siirry edelliseen isoon rakenneosio kohteeseen" - -# Korjattu dokumenttirakennekontekstin takia myös muita yhtenäiseksi -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Siirry seuraavaan isoon rakenneosioon" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Esitä lista isoista rakenneosioista" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Siirry edelliseen linkkiin" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Siirry seuraavaan linkkiin" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Näytä luettelo linkeistä" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Siirry edelliseen luetteloon" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Siirry seuraavaan luetteloon" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Näytä luettelo luetteloista" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Siirry edelliseen luettelon kohtaan" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Siirry seuraavaan luettelon kohtaan" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Näytä lista luettelokohteista" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Siirry edelliseen aktiiviseen alueeseen" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Siirry seuraavaan aktiiviseen alueeseen" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Siirry viimeisimpään ilmoituksen sisältävään aktiiviseen alueeseen" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Siirry navigaattorin kohdistuksen kohteen ylätasolle." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Siirry navigaattorin kohdistuksen kohteen ensimmäiseen alitasoon." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Siirry navigaattorin kohdistuksen kohteen seuraavaan sisarukseen." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Siirry navigaattorin kohdistuksen kohteen edelliseen sisarukseen." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Palaa kohteeseen, jolla on näppäimistön kohdistus" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Vaihtele rakenteellisen navigoinnin näppäimiä" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Siirry edelliseen kappaleeseen" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Siirry seuraavaan kappaleeseen" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Näytä lista kappaleista" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Siirry edelliseen valitsinpainikkeeseen" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Siirry seuraavaan valitsinpainikkeeseen" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Näytä lista valitsinpainikkeista" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Siirry edelliseen erottimeen" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Siirry seuraavaan erottimeen" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Siirry edelliseen taulukkoon" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Siirry seuraavaan taulukkoon" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Näytä lista taulukoista" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Siirry yksi solu alas" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Siirry taulukon ensimmäiseen soluun" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Siirry taulukon viimeiseen soluun" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Siirry yksi solu vasemmalle" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Siirry yksi solu oikealle" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Siirry yksi solu ylös" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Käytä rivitystilaa" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Vaihda selaustilan ja vuorovaikutustilan välillä" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Ota käyttöön jatkuva vuorovaikutustila" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Ota käyttöön jatkuva selaustila" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Siirry edelliseen vierailemattomaan linkkiin" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Siirry seuraavaan vierailemattomaan linkkiin" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Näytä lista linkeistä, joissa ei ole vierailtu" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Siirry edelliseen vierailtuun linkkiin" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Siirry seuraavaan vierailtuun linkkiin" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Näytä lista vierailluista linkeistä" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "alice sininen" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antiikki valkoinen" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamariini" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azure" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "äyriäiskeitto" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "musta" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "vaalennettu manteli" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "sininen" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "sininen violetti" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "ruskea" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadetti sininen" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "keltaisen vihreä" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "suklaa" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koralli" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "ruiskaunokinsininen" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "maissi" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "karmiininpunainen" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "syaani" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "tumma sininen" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "tumma syaani" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "tumma kultainenruskea" - -# Dark gray arvot (a9a9a9) ei ole luetteloitu suomeksi, mutta lähin suomalainen, jota ei ole käytössä muissa listoissa (8B8680). Kielellisesti loogisempi kuin suora käännös. Kts. https://fi.qaz.wiki/wiki/List_of_colors:_G%E2%80%93M ja https://en.wikipedia.org/wiki/Web_colors#X11_color_names sekä https://sv.wikipedia.org/wiki/X11-f%C3%A4rger -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "keskiharmaa" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "tumma vihreä" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "tumma khaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "tumma magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "tumma oliivinvihreä" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "tumma oranssi" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "tumma orkidea" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "tumma punainen" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "tumma lohi" - -# Nimen käännös löytyy tuossa muodossa https://fi.qaz.wiki/wiki/X11_color_names mutta olisiko ymmärrettävämpi muodossa "tumma meren vihreä"? -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "tummanmeren vihreä" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "tumma liuskekivi sininen" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "tumma liuskekivi harmaa" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "tumma turkoosi" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "tumma violetti" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "syvä vaaleanpunainen" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "syvä taivaansininen" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "himmeä harmaa" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodger sininen" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "tulenkestävä tiili" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "kukka valkoinen" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "metsänvihreä" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "ghost white" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "kulta" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "goldenrod" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "harmaa" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "vihreä" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "vihreä keltainen" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "hunajakastetta" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "kuuma pinkki" - -# Värilista suomeksi https://fi.qaz.wiki/wiki/Lists_of_colors -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "intian punainen" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "norsunluu" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "laventeli" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "laventeli poskipuna" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "nurmikko vihreä" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "sitruuna sifonki" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "vaalea sininen" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "kevyt koralli" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "vaalea syaani" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "vaalea kultainenruskea" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "vaalea harmaa" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "vaaleanvihreä" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "vaalea pinkki" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "kevyt lohi" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "vaalea merivihreä" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "vaalea taivaansininen" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "vaalea liuskekivi harmaa" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "vaalea teräs sininen" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "vaalea keltainen" - -# Ristiriita lähteiden määritelmien välillä, pieni sävyero rgb:ssä https://en.wikipedia.org/wiki/Web_colors#X11_color_names https://fi.qaz.wiki/wiki/List_of_colors:_G%E2%80%93M -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lime" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limen vihreä" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "liinavaatteiden valkoinen" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "kastanjanruskea" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -# Epäilen lähteessä käännösvirhettä. Haulla "keskininen" saa 26000 tulosta ja "keskipitkä sininen" vain 500. Käytetty ensimmäistä. https://fi.qaz.wiki/wiki/X11_color_names -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "keskisininen" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -# Epäilen lähteessä käännösvirhettä. Haulla "keskivioletti" saa 5000 tulosta ja "keskipitkä vuoletti" vain 250. Käytetty ensimmäistä. https://fi.qaz.wiki/wiki/X11_color_names -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "keskivioletti" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "medium violetti punainen" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "yönsininen" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "minttu kerma" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokkasiini" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajo valkoinen" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "laivastonsininen" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "vanha pitsi" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliivi" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "oliivinvihreä" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oranssi" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "oranssinpunainen" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orkidea" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "vaalea goldenrod" - -# Käytetty omaa käännöstä, sillä lähteessä light green ja pale green on sama käännös (vaalenavihreä). https://fi.qaz.wiki/wiki/X11_color_names -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "kalpeanvihreä" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "vaalea turkoosi" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "vaalean violetti punainen" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaija-piiska" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "pinkki" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "luumu" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "puuterinsininen" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "patriarkka (violetti)" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "punainen" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "kuninkaallisen sininen" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "satula ruskea" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "lohi" - -# Käytetty omaa käännöstä, lähteessä sävyä ei ole käännetty https://fi.qaz.wiki/wiki/X11_color_names -#: src/cthulhu/colornames.py:624 -#, fuzzy -msgctxt "color name" -msgid "sandy brown" -msgstr "hiekanruskea" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "meren vihreä" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "kotilo" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "hopea" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "taivaansininen" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "liuskekivi sininen" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "liuskekivi harmaa" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "lumi" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "keväänvihreä" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "terässininen" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "tan ruskea" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "sinivihreä" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "ohdake" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomaatti" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turkoosi" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violetti" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "vehnä" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "valkoinen" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "viljelty valkoinen" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "keltainen" - -# https://fi.qaz.wiki/wiki/List_of_colors:_N%E2%80%93Z -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "keltainen-vihreä" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktivoi" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automaattinen kohdistus rakenteellisessa navigoinnissa" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automaattinen vuorovaikutustila kohdistimella navigoinnin aikana" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automaattinen kohdennustila ohjelman omassa navigaatiossa" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Piste _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Piste _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Pisteet 7 _ja 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Peru" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Siirry" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Äänimerkki" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Ei mitään" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Puhu isot" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "_Kerro kun tuttavat kirjoittavat" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Tarjoa keskusteluhuonekohtainen viestihistoria" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Puhu viestit lähteestä" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Kaikki _kanavat" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Kaikki kanavat, kun mikä tahan_sa %s-ikkuna on aktiivinen" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Kanava vain jos sen _ikkuna on aktiivinen" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Lausu keskusteluhuoneen nimi" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Käytä rivitystilaa sisällölle" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "kaksoisnapsautus" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "kolmoisnapsautus" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Oletus-_syntetisaattori" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Alkuperäinen merkkijono" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Korvaava merkkijono" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Ota _merkkien kaiutus käyttöön" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Ota tilattomat _korostusmerkit käyttöön" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Nykyinen sijainti" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Täsmätyn tekstin vähimmäispituus:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Haun valinnat" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Lausu vain _muuttuneet rivit haun aikana" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Lausu tulokset haun _aikana" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Komento" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Pikanäppäin" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Oletus" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Rivitystila." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Toiminnot" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Pistekirjoitusnäppäinten toiminnot" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Kirjanmerkit" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Aika ja päiväys" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Hiiriosoittimella puhuttaminen käytössä." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navigointi" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Rakenneosioiden tila." - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Määrittelemätön" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Poistutaan tasatun tarkastelun tilasta." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Vaihda puheen yksityiskohtaisuuden tasoa" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "pää-sisältö" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Muokattu" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Työpöytä" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Ilmoitukset" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Vastaanotettu" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Ilmoitusten esittäjä" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu-asetukset sovellukselle %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Merkitse pistekirjoituksella" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Puhu, jollei arvo ole" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Puhu" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Tallenna profiili ristiriitaisena" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Käyttäjäprofiilin ristiriita!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profiili %s on jo olemassa.\n" -"Jatketaanko olemassa olevan profiilin päivitystä näillä uusilla muutoksilla?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Lataa käyttäjäprofiili" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Olet vaihtamassa aktiivista profiilia. Mikäli olet juuri muokannut " -"asetuksia, muutokset menetetään profiilin latauksen yhteydessä. \n" -"Jatketaanko profiilin lataamista poistamalla edelliset muutokset?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Tallenna profiili nimellä" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profiilin nimi:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Poista käyttäjäprofiili" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Olet aikeissa poistaa profiilin %s. Kaikki tallentamattomat muutokset ja " -"profiiliin tallennetut asetukset katoavat. Haluatko jatkaa ja poistaa " -"profiilin sekä kaikki siihen liittyvät asetukset?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Kaikki" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Sovellus" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Ikkuna" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Ei mitään" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Osittain" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Yleisimmät" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Rivi" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Virke" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Lainauslohko" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Painike" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Taulukon otsikko" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Valintaruutu" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Napsautettava" - -# Perustuen toisen käännöksen antamaan kontekstiin (radio buttons, check boxes..) -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Valintalaatikko" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Kuvaus" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Otsikko" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Kuva" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Tunniste" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Maamerkki" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Taso" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Linkki" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Luettelo" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Luettelokohta" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Rakenneosio" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Kappale" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Valitsinpainike" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rooli" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Valittu kohta" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Tila" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Teksti" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "Osoite" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Arvo" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Lainauslohkoja" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Painikkeet" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Valintaruudut" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Napsautettavat" - -# Perustuen toisen käännöksen antamaan kontekstiin (radio buttons, check boxes..) -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Valintalaatikot" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Merkinnät" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Lomakekentät" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Otsikot" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Kuvat" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Otsikot tasolla %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Maamerkit" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Isot rakenneosiokohteet" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Linkit" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Luettelot" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Luettelokohteet" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Kappaleet" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Valitsinpainikkeita" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Taulukot" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Vierailemattomat linkit" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Vieraillut linkit" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Sivulla navigointi" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Aloita sivun puhuminen automaattisesti, kun se _ladataan" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Esitä sivun yhteenveto, kun se ladataan ensimmäisen kerran" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Katkaise puhe tauotettuihin _paloihin" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s oletusääni" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Oletus" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlinkki" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Järjestelmä" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Isot kirjaimet" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Puheentuottaja" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Oikeinkirjoituksen tarkistus" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Kirjoitus_virhe" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Tavaa _ehdotus" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Puhu virheen asiayhteys" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Lausu taulukon solun koordinaatit" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Puhu aina koko valittu alue taulukosta" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Lausu solun _otsake" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Taulukossa navigointi" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Ohita _tyhjät solut" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Puhu _solu" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Puhu solun koordinaatit" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Puhu _useita soluja kattavat solut" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Ominaisuuden nimi" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Hallitse kohdistimella navigointia" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Käytä _rakenteellista navigointia" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Ääni_teema:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Ääniteema" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Su_ppea" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d ilmoitus" -msgstr[1] "%d ilmoitusta" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Vaihto" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Cntrol" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "vasen vaihto" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "vasen alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "vasen control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "oikea vaihto" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "oikea alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "oikea control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "vasen meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "oikea meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "vaihtonäppäimen lukitus" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "sivu ylös" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "sivu alas" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "vasen sarkain" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "askelpalautin" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "rivinvaihto" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "ylös" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "alas" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "vasen" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "oikea" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "vasen super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "oikea super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "valikko" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ohje" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "tilanvaihto" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "lisää" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "poista" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "kotiin" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "loppuun" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "alkuun" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "sirkumfleksi" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ympyrä" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "poikkiviivaus" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "miinus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Lisää" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Vaihto" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "lihavoitu %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "kursiivi %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "korostettu kursivoitu %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "merkki %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "lihavoitu merkki %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktuura %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "korostettu fraktuura %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "korostettu sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif kursiivi %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif-kirjasimen lihavoitu kursivoitu %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "tasaleveys %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "pisteetön %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "nuoli vasen" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "nuoli ylös" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "nuoli oikealle" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "nuoli alas" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "nuoli oikealle ja vasemmalle" - -#: src/cthulhu/mathsymbols.py:1282 -#, fuzzy -msgctxt "math symbol" -msgid "up down arrow" -msgstr "nuoli ylös ja alas" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "nuoli ylös vasemmalle" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "nuoli ylös oikealle" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "nuoli alas oikealle" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "nuoli vasemmalle seinästä" - -#: src/cthulhu/mathsymbols.py:1297 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "nuoli ylos lattiasta" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "nuoli oikealle seinästä" - -#: src/cthulhu/mathsymbols.py:1303 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "nuoli alas katosta" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "vasemmalle osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "ylös osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "oikealle osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "alas osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "vasemmalle ja oikealle osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1321 -#, fuzzy -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "ylös ja alas osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1324 -#, fuzzy -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "ylös vasemmalle osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1327 -#, fuzzy -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "ylös oikealle osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1330 -#, fuzzy -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "alas oikealle osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1333 -#, fuzzy -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "alas vasemmalle osoittava kaksoisnuoli" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "nuoli oikealle" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "nuolenkärki oikealle" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "miinus" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "pienempi kuin" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "suurempi kuin" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "sirkumfleksi" - -# http://jkorpela.fi/merkkien-nimet.html -#: src/cthulhu/mathsymbols.py:1359 -#, fuzzy -msgctxt "math symbol" -msgid "háček" -msgstr "hattutarke" - -# http://www.ling.helsinki.fi/filt/info/mes2/merkkien-nimet.html ja http://jkorpela.fi/merkkien-nimet.html -#: src/cthulhu/mathsymbols.py:1363 -#, fuzzy -msgctxt "math symbol" -msgid "breve" -msgstr "lyhyysmerkki" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "piste" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "kaksoispystyviiva" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "vaakaellipsi (kolme pistettä)" - -#: src/cthulhu/mathsymbols.py:1377 -#, fuzzy -msgctxt "math symbol" -msgid "for all" -msgstr "kaikkikvanttori" - -# http://jkorpela.fi/merkkien-nimet.html -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "komplementti" - -#: src/cthulhu/mathsymbols.py:1383 -#, fuzzy -msgctxt "math symbol" -msgid "partial differential" -msgstr "osittaisderivaatta" - -#: src/cthulhu/mathsymbols.py:1386 -#, fuzzy -msgctxt "math symbol" -msgid "there exists" -msgstr "olemassaolokvanttori" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "tyhjä" - -#: src/cthulhu/mathsymbols.py:1395 -#, fuzzy -msgctxt "math symbol" -msgid "increment" -msgstr "delta" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla-kolmio" - -#: src/cthulhu/mathsymbols.py:1401 -#, fuzzy -msgctxt "math symbol" -msgid "element of" -msgstr "joukkoon kuulumisen merkki" - -#: src/cthulhu/mathsymbols.py:1404 -#, fuzzy -msgctxt "math symbol" -msgid "not an element of" -msgstr "joukkoon kuulumattomuuden merkki" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -# http://jkorpela.fi/merkkien-nimet.html vaihtoehtoinen käännös ymmärrettävämpi kuin "käänteinen kuulumismerkki" -#: src/cthulhu/mathsymbols.py:1410 -#, fuzzy -msgctxt "math symbol" -msgid "contains as a member" -msgstr "alkion sisältämisen merkki" - -# http://jkorpela.fi/merkkien-nimet.html käytetty loogisen parin "alkion sisältämisen merkki" kontekstia, jotta käännös yhtenevä; vaihtoehtoinen käännös ymmärrettävämpi kuin "käänteinen kuulumattomuusmerkki" -#: src/cthulhu/mathsymbols.py:1413 -#, fuzzy -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "alkion sisältämättömyyden merkki" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "todistuksen loppu" - -#: src/cthulhu/mathsymbols.py:1422 -#, fuzzy -msgctxt "math symbol" -msgid "product" -msgstr "tulo" - -#: src/cthulhu/mathsymbols.py:1425 -#, fuzzy -msgctxt "math symbol" -msgid "coproduct" -msgstr "kotulo" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "summan merkki" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "miinus tai plus" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "piste-plus" - -#: src/cthulhu/mathsymbols.py:1440 -#, fuzzy -msgctxt "math symbol" -msgid "division slash" -msgstr "jakoviiva" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "joukkomiinus" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "asteriskioperaattori" - -#: src/cthulhu/mathsymbols.py:1449 -#, fuzzy -msgctxt "math symbol" -msgid "ring operator" -msgstr "pallo-operaattori" - -#: src/cthulhu/mathsymbols.py:1452 -#, fuzzy -msgctxt "math symbol" -msgid "bullet operator" -msgstr "pallo-operaattori" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "neliöjuuri" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "kuutiojuuri" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "neljäs juuri" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "verrannollinen" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "ääretön" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "suora kulma" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "kulmamerkki" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "kulma" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "kaarellinen kulma" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "pystyviiva jakomerkki" - -#: src/cthulhu/mathsymbols.py:1485 -#, fuzzy -msgctxt "math symbol" -msgid "does not divide" -msgstr "jaottomuusmerkki" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "yhdensuuntaisuus" - -# http://jkorpela.fi/merkkien-nimet.html oma käännös loogisesta esimerkeistä (yhtensuuntaisuusmerkki, jaottomuusmerkki) -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "yhdensuunnattomuusmerkki" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "looginen ja" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "looginen tai" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "monikkoleikkaus" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -#, fuzzy -msgctxt "math symbol" -msgid "union" -msgstr "monikkounioni" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "integraali" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "kaksoisintegraali" - -#: src/cthulhu/mathsymbols.py:1512 -#, fuzzy -msgctxt "math symbol" -msgid "triple integral" -msgstr "kolmoisintegraali" - -#: src/cthulhu/mathsymbols.py:1515 -#, fuzzy -msgctxt "math symbol" -msgid "contour integral" -msgstr "käyräintegraali" - -#: src/cthulhu/mathsymbols.py:1518 -#, fuzzy -msgctxt "math symbol" -msgid "surface integral" -msgstr "pintaintegraali" - -# ei lähdettä, oma käännös käyttäen loogisia esimerkkejä (pintaintegraali: kaksi integraali, kaksi ulottuvuutta -> kolme integraalia merkissä viittaa tilavuuteen, tuskin määrään tai massaan) -#: src/cthulhu/mathsymbols.py:1521 -#, fuzzy -msgctxt "math symbol" -msgid "volume integral" -msgstr "tilavuusintegraali" - -#: src/cthulhu/mathsymbols.py:1524 -#, fuzzy -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "myötäpäiväinen integraali" - -#: src/cthulhu/mathsymbols.py:1527 -#, fuzzy -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "myötäpäiväinen käyräintegraali" - -#: src/cthulhu/mathsymbols.py:1530 -#, fuzzy -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "vastapäiväinen käyräintegraali" - -# Lähde joillekin erikoismerkeille http://jkorpela.fi/kielenopas/4.14.html sekä http://jkorpela.fi/merkkien-nimet.html -#: src/cthulhu/mathsymbols.py:1533 -#, fuzzy -msgctxt "math symbol" -msgid "therefore" -msgstr "koska-merkki" - -#: src/cthulhu/mathsymbols.py:1536 -#, fuzzy -msgctxt "math symbol" -msgid "because" -msgstr "koska-merkki" - -#: src/cthulhu/mathsymbols.py:1539 -#, fuzzy -msgctxt "math symbol" -msgid "ratio" -msgstr "siis-merkki" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "piste-miinus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -#, fuzzy -msgctxt "math symbol" -msgid "homothetic" -msgstr "homoteettisuusmerkki" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -#, fuzzy -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "käännetty tilde" - -# Lähde http://jkorpela.fi/merkkien-nimet.html huomauttaa epäselvästä merkityksestä -#: src/cthulhu/mathsymbols.py:1563 -#, fuzzy -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "ylösalainen laiska s" - -#: src/cthulhu/mathsymbols.py:1566 -#, fuzzy -msgctxt "math symbol" -msgid "sine wave" -msgstr "siniaalto" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptoottisuusmerkki" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "yhtenevyysmerkki" - -#: src/cthulhu/mathsymbols.py:1587 -#, fuzzy -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "likimäärin mutta ei tasan yhtä suuri kuin" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "likimain yhtäsuuri kuin" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ei miltei yhtä suuri" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "lähes tai tasan yhtä suuri kuin" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "kaikki yhtä suuria kuin" - -#: src/cthulhu/mathsymbols.py:1608 -#, fuzzy -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekvivalenssimerkki" - -#: src/cthulhu/mathsymbols.py:1611 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrinen ekvivalenssin merkki" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "eromerkki" - -#: src/cthulhu/mathsymbols.py:1617 -#, fuzzy -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "raja-arvon lähestymisen merkki" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrisen yhtäläisyyden merkki" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "kaksoispiste ja yhtäsuuri" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "yhtäsuuri ja kaksoispiste" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -#, fuzzy -msgctxt "math symbol" -msgid "estimates" -msgstr "vastaavuusmerkki" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "samakulmaisuusmerkki" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "yhtäsuuri ja tähti päällä" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta-yhtäläisyysmerkki" - -#: src/cthulhu/mathsymbols.py:1656 -#, fuzzy -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "määritelmällisen yhtäläisyyden merkki" - -#: src/cthulhu/mathsymbols.py:1659 -#, fuzzy -msgctxt "math symbol" -msgid "measured by" -msgstr "mittausperusteen merkki" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "erisuuri kuin" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "on identtisesti" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "pienempi tai yhtäsuuri kuin" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "suurempi tai yhtäsuuri kuin" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "yhtäläisyysmerkin yläpuolella oleva oleva pienempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "yhtäläisyysmerkin yläpuolella oleva suurempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "pienempi eikä yhtä suuri kuin -merkki" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "suurempi eikä yhtä suuri kuin -merkki" - -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "paljon pienempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "paljon suurempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:1701 -#, fuzzy -msgctxt "math symbol" -msgid "between" -msgstr "välissä-merkki" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "ei suurempi kuin" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ei pienempi tai yhtäsuuri kuin" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "pienempi kuin tai ekvivalentti -merkki" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "suurempi kuin tai ekvivalentti -merkki" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "pienempi tai suurempi kuin" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "suurempi tai pienempi kuin" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ei pienempi tai suurempi kuin" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ei suurempi tai pienempi kuin" - -#: src/cthulhu/mathsymbols.py:1743 -#, fuzzy -msgctxt "math symbol" -msgid "precedes" -msgstr "edeltää-merkki" - -#: src/cthulhu/mathsymbols.py:1746 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds" -msgstr "seuraa-merkki" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "ei edellä -merkki" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ei seuraa -merkki" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "osajoukko" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "ylijoukko" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -#, fuzzy -msgctxt "math symbol" -msgid "circled plus" -msgstr "ympyrässä oleva plusmerkki" - -#: src/cthulhu/mathsymbols.py:1827 -#, fuzzy -msgctxt "math symbol" -msgid "circled minus" -msgstr "ympyrässä oleva miinusmerkki" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -#, fuzzy -msgctxt "math symbol" -msgid "circled times" -msgstr "ympyrässä oleva kertomerkki" - -#: src/cthulhu/mathsymbols.py:1833 -#, fuzzy -msgctxt "math symbol" -msgid "circled division slash" -msgstr "ympyrässä oleva jakoviiva" - -#: src/cthulhu/mathsymbols.py:1836 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "ympyrässä oleva pisteoperaattori" - -#: src/cthulhu/mathsymbols.py:1839 -#, fuzzy -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "ympyrässä oleva pallo-operaattori" - -#: src/cthulhu/mathsymbols.py:1842 -#, fuzzy -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "ympyrässä oleva asteriskioperaattori" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "ympyrässä oleva yhtäläisyysmerkki" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "ympyröity vaakaviiva" - -# oma käännös perustuen loogisiin esimerkkeihin ("ympyrässä oleva... ") -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "neliössä oleva plusmerkki" - -# oma käännös perustuen loogisiin esimerkkeihin ("ympyrässä oleva... ") -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "neliössä oleva miinusmerkki" - -# oma käännös perustuen loogisiin esimerkkeihin ("ympyrässä oleva... ") -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "neliössä oleva kertomerkki" - -# oma käännös perustuen loogisiin esimerkkeihin ("ympyrässä oleva... ") -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "neliössä oleva pisteoperaattori" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "oikealle osoittava nupi" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "vasemmalle osoittava nupi" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "alas osoittava nupi" - -#: src/cthulhu/mathsymbols.py:1872 -#, fuzzy -msgctxt "math symbol" -msgid "up tack" -msgstr "ylös osoittava nupi" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "assertion merkki" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "tosi" - -#: src/cthulhu/mathsymbols.py:1884 -#, fuzzy -msgctxt "math symbol" -msgid "forces" -msgstr "pakottaa-merkki" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -#, fuzzy -msgctxt "math symbol" -msgid "does not prove" -msgstr "ei todista -merkki" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "epätosi" - -#: src/cthulhu/mathsymbols.py:1899 -#, fuzzy -msgctxt "math symbol" -msgid "does not force" -msgstr "ei pakota -merkki" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -#, fuzzy -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normaali aliryhmä -relaation merkki" - -#: src/cthulhu/mathsymbols.py:1914 -#, fuzzy -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "normaalina aliryhmänä sisältämisen merkki" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -#, fuzzy -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermiten konjugaatiomatriisi" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "oikea kolmio" - -#: src/cthulhu/mathsymbols.py:1965 -#, fuzzy -msgctxt "math symbol" -msgid "diamond operator" -msgstr "timanttioperaattori" - -#: src/cthulhu/mathsymbols.py:1968 -#, fuzzy -msgctxt "math symbol" -msgid "dot operator" -msgstr "pisteoperaattori" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "tähtioperaattori" - -#: src/cthulhu/mathsymbols.py:1974 -#, fuzzy -msgctxt "math symbol" -msgid "division times" -msgstr "jakoviiva-kertomerkki" - -#: src/cthulhu/mathsymbols.py:1977 -#, fuzzy -msgctxt "math symbol" -msgid "bowtie" -msgstr "rusetti" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "kaareva tai-merkki" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "kaareva ja-merkki" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "kaksoisosajoukkomerkki" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "kaksoisylijoukkomerkki" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "kaksoisleikkaus" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "kaksoisunioni" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -#, fuzzy -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "yhtäläisyys- ja yhdensuuntaisuusmerkki" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "pisteellinen pienempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "pisteellinen suurempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "pienempi, kuin yhtä suuri tai suurempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "suurempi, yhtä suuri tai pienempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "yhtä suuri tai pienempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "yhtä suuri tai suurempi kuin -merkki" - -#: src/cthulhu/mathsymbols.py:2043 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "on yhtäläinen tai edeltää" - -#: src/cthulhu/mathsymbols.py:2046 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "on yhtäläinen tai seuraa" - -#: src/cthulhu/mathsymbols.py:2049 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "ei edellä eikä ole yhtäläinen" - -#: src/cthulhu/mathsymbols.py:2052 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ei seuraa eikä ole yhtäläinen" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "pienempi kuin eikä ekvivalentti -merkki" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "suurempi kuin eikä ekvivalentti -merkki" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "pystyellipsi (kolme pistettä)" - -#: src/cthulhu/mathsymbols.py:2094 -#, fuzzy -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "rivinkeskinen ellipsi" - -#: src/cthulhu/mathsymbols.py:2097 -#, fuzzy -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "nouseva ellipsi" - -#: src/cthulhu/mathsymbols.py:2100 -#, fuzzy -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "laskeva ellipsi" - -#: src/cthulhu/mathsymbols.py:2103 -#, fuzzy -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "poikkiviivallinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2107 -#, fuzzy -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "pystyviivaan päättyvällä poikkiviivalla varustettu kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2111 -#, fuzzy -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"pieni pystyviivaan päättyvällä poikkiviivalla varustettu kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2114 -#, fuzzy -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "yläpisteellinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2117 -#, fuzzy -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "yläviivallinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2120 -#, fuzzy -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "pieni yläviivallinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2123 -#, fuzzy -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "alaviivallinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2126 -#, fuzzy -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "kaksoispoikkiviivallinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2129 -#, fuzzy -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "poikkiviivallinen käänteinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2132 -#, fuzzy -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" -"pystyviivaan päättyvällä poikkiviivalla varustettu käänteinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2136 -#, fuzzy -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"pieni pystyviivaan päättyvällä poikkiviivalla varustettu käänteinen " -"kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2139 -#, fuzzy -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "yläviivallinen käänteinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2142 -#, fuzzy -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "pieni yläviivallinen käänteinen kuulumismerkki" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "vasen kattofunktio alku" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "oikea kattofunktio loppu" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "vasen kattofunktio alku" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "oikea kattofunktio loppu" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "yläkaarisulku" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "alakaarisulku" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "alkukulmasulku" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "loppukulmasulku" - -# http://jkorpela.fi/merkkien-nimet.html -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "monikollinen ympyrässä oleva pisteoperaattori" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "musta neliö" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "valkoinen neliö" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "musta timantti" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "valkoinen ympyrä" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "musta ympyrä" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "valkoinen pieni ympyrä" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "musta pieni neliö" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s-merkki alaviivalla" - -#: src/cthulhu/mathsymbols.py:2225 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s jakoviivalla" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s-merkki pystyviivalla" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "sovellus" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "tyhjä" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "korostettu" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "kirjanmerkki syötetty" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "kirjanmerkit tallennettu" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "kirjanmerkkejä ei voitu tallentaa" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Kirjanmerkkejä ei löytynyt." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Kirjanmerkkiä ei löytynyt." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Ohitustila käytössä." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Laskimen näyttöä ei voitu avata" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "äänimerkki" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Kapiteelityyliksi asetettu äänimerkki." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ei mitään" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Kapiteelityyliksi asetettu ei mitään." - -# Kontekstina ison kirjaimen ilmoittaminen -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "puhu isot" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Kapiteelityyliksi asetettu lausu isot." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Sovellus ohjaa kohdistinta." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu hallitsee kohdistinta." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Solu %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s valittu" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s - %s valittu" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "Alkaen %s ja päättyen %s valitsematta" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s ei valittu" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Estää valitsimen käytön" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Pakota valitsimen käyttö" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "VALITSIN" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Valinnaiset asetukset" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Käyttö: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Seuraavat valitsimet ovat virheellisiä: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Tulostaa tunnetut suoritettavana olevat sovellukset" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Lataa profiili" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profiilin lataus epäonnistui: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Cthulhua ei voi käynnistää, koska se ei voi muodostaa yhteyttä " -"työpöytään.Näytönlukijan käynnistys epäonnistui, koska se ei voinut " -"muodostaa yhteyttä työpöytään." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Virhe aktivoitaessa asetustenhallintaa. Lopetetaan." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Toinen näytönlukijan prosessi on jo käynnissä tässä istunnossa.\n" -"Suorita “cthulhu --replace” korvataksesi kyseisen prosessin uudella " -"prosessilla." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NIMI" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Käytä muuta kansiota käyttäjäasetuksille" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "HAKEMISTO" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Tämän sovelluksen versio" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Korvaa käynnissä oleva Cthulhu-instanssi" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Näytä tämä ohjeviesti ja poistu" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Lähetä vianetsintä viestiä tiedostoon debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Lähetä vianetsintätekstit annettuun tiedostoon" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "TIEDOSTO" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Määrittele käyttäjän asetukset (tekstiversio)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Määrittele käyttäjän asetukset (graafisen käyttöliittymän versio)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" -"Ilmoita vioista sähköpostitse osoitteeseen https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Leikkaa valinta leikepöydälle." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "leikkaa" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Kopioitu valinta leikepöydälle." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopioitu" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Liitetty sisältö leikepöydältä." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "liitetty" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Älä kerro kun tuttavat kirjoittavat." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "kerro kun tuttavat kirjoittavat." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Viesti keskusteluhuoneesta %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Uusi keskusteluvälilehti %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Älä lausu keskusteluhuoneen nimiä." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "lausu keskusteluhuoneen nimi." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Älä tarjoa keskusteluhuonekohtaisia viestihistorioita." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Tarjoa keskusteluhuonekohtaiset viestihistoriat." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "poiston alku" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "poiston loppu" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "lisäyksen alku" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "lisäyksen loppu" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "korostuksen alku" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "korostuksen loppu" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "ehdotuksen loppu" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Rakenneosion loppu." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Ei rakenneosiossa." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "kaikki tietueet valittu" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Oletuspainike on %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Oletuspainike on %s" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Oletuspainike on %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " alaindeksi %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " yläindeksi %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Ei taulukossa." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "koko asiakirja valittu" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "koko asiakirjan valinta poistettu" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "asiakirja avattu kohdistimen sijainnista alkaen" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "asiakirjan valinta peruttu kohdistimen sijainnista alkaen" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "asiakirja valittu kohdistimen sijaintiin saakka" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "asiakirjan valinta peruttu kohdistimen sijaintiin saakka" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynaaminen sarakkeen otsikko asetettu riville %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynaaminen sarakkeen otsikko tyhjennetty." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynaaminen rivin otsikko asetettu sarakkeelle %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynaaminen rivin otsikko tyhjennetty." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "tyhjä" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilotavua" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megatavua" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Tiedostoja ei löytynyt." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Lisätty sisältö leikepöydälle." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Kopioitu sisältö leikepöydälle." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Ei käytetä tasatun tarkastelun tilaa." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Otetaan käyttöön tasatun tarkastelun tila." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Poistutaan tasatun tarkastelun tilasta." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Siirrä tasattu tarkastelu nykyisen sanan yllä olevaan sanaan" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Tasotarkastelu rajoittamaton" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "sisältää kaavan" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "avaa dialogi-ikkunan" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "avaa ruudukon" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "avaa listalaatikon" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "avaa valikon" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "avaa hierarkiapuun" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "kuvakarttalinkki" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Annettu näppäin on jo sidottu komentoon %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Näppäin kaapattu: %s. Vahvista painamalla Enteriä." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Uusi näppäin on: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Näppäinsidos poistettu. Vahvista painamalla Enteriä." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Näppäinsidos on poistettu." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "syötä uusi näppäin" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "näppäin" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Kaiutus asetettu näppäimelle." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ei mitään" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Kaiutus asetettu ei millekään." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "näppäin ja sana" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Kaiutus asetettu näppäimelle ja sanalle." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "virke" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Kaiutus käytössä virkkeissä." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "sana" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Kaiutustaso asetettu sanaan." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "sana ja virke" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Kaiutus asetettu sanaan ja virkkeeseen." - -#: src/cthulhu/messages.py:889 -#, fuzzy, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Ympäröity käyttäen: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "ympyrä" - -#: src/cthulhu/messages.py:921 -#, fuzzy -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "jakokulman merkki" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "vaakaviiva yli" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "pystyviiva" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "koillis-nuoli" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "viiva alla" - -#: src/cthulhu/messages.py:993 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "pystyviiva vasemmalla" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "pystyviiva oikealla" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "ja" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "murtoluku alkaa" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "murtoluvun osa, ilman jakoviivaa, alkaa" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "jakoviiva" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "murtoluvun loppu" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "neliöjuuri luvusta" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "kuutiojuuri" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "juuri luvulle" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "juuren alku" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "juuren loppu" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "alaindeksi" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "yläindeksi" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "esi-alaindeksi" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "esi-yläindeksi" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "alle merkitty" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "ylle merkitty" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "taulukon loppu" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "sisäkkäisen taulukon loppu" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "ei saatavilla" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Pois käytöstä" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Puhutaan ilmoittamatta sisennyksiä ja tasauksia." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Käytössä" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Puhutaan ilmoittaen sisennykset ja tasaukset." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Oppimistila. Sulje painamalla Escape-näppäintä." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Aloitetaan oppimistila. Paina mitä tahansa näppäintä kuullaksesi sen " -"toiminnan. Saadaksesi esiin ruudunlukijan dokumentaation, paina F1. " -"Saadaksesi listan ruudunlukijan oletus pikanäppäimistä, paina F2. Saadaksesi " -"listan ruudunlukijan oikoteistä nykyisessä ohjelmassa, paina F3. " -"Poistuaksesi oppimistilasta, paina escape-näppäintä." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "poistutaan lainauslohkosta." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "poistutaan yksityiskohdista." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "poistuu syötteestä." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "poistuu kuviosta." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "poistutaan lomakkeesta." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "poistuu bannerista." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "poistuu täydentävästä sisällöstä." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "poistuu tiedonannosta." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "poistuu pääsisällöstä." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "poistuu navigoinnista." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "poistuu alueelta." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "poistuu hausta." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "poistutaan listasta." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "poistutaan taulusta." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "poistutaan taulukosta." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "poistutaan työkaluvihjeestä." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "poistuu lyhennelmästä." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "poistuu kiitos-osiosta." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "poistuu jälkikirjoituksesta." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "poistuu liitteistä." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "poistuu lähdeluettelosta." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "poistuu kappaleesta." - -# Epäsuorakäännös: vanhahtavan ilmauksen merkitys -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "poistuu teostiedoista." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "poistuu yhteenvedosta." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "poistuu lopputekstistä." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "poistuu lopputeksteistä." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "poistuu omistuskirjoituksesta." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "poistuu loppuviitteistä." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "poistuu omistuskirjoituksista." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "poistuu jälkipuheesta." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "poistuu painovirheluettelosta." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "poistuu esimerkistä." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "poistuu esipuheesta." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "poistuu asiasanastosta." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "poistuu hakemistosta." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "poistuu esittelystä." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "poistuu sivulistauksesta." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "poistuu osiosta." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "poistuu johdannosta." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "poistuu esipuheesta." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "poistuu nostetusta lainauksesta." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "poistuu kysymys-vastaus-osiosta." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "poistuu ehdotuksesta." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "poistuu sisällysluettelosta." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "rivi valittu kohdistimen sijainnista alkaen" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "rivi valittu kohdistimen sijaintiin saakka" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "rivin valinta peruttu kohdistimen sijainnista alkaen" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "rivin valinta peruttu kohdistimen sijaintiin saakka" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Suljetaan oppimistila." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "rivi valittu rivin alusta kohdistinta edeltävään sijaintiin saakka" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "rivi valittu rivin loppuun kohdistimen sijainnista alkaen" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "linkki" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "sama sivu" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "sama sivusto" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "eri sivusto" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s linkki kohteeseen %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s-linkki" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "%s vierailtu linkki" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Paina ylös- ja alas-näppäimiä liikkuaksesi luettelossa. Paina Escape " -"poistuaksesi." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Kaikki aktiiviset alueet poistettu käytöstä" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "aktiivisten alueiden kohteliaisuustasot palautettu" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "kohteliaisuustaso %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "asetetaan aktiivinen alue vakuuttavaksi" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "asetetaan aktiivinen alue pois päältä" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "asetetaan aktiivinen alue kohteliaaksi" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "asetetaan aktiivinen alue epäkohteliaaksi" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Aktiivisten alueiden tarkkailu on pois päältä" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Aktiivisten alueiden tarkkailu on päällä" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "aktiivisia viestejä ei ole tallennettu" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Aktiiviset alueet eivät ole käytössä" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Ei löytynyt" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Nykyistä sijaintia ei voitu selvittää." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "pois" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "päällä" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "väärinkirjoitettu" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Väärinkirjoitettu sana: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Konteksti on %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Selaustila" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Vuorovaikutustila" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Aktivoi vuorovaikutustila painamalla %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Jatkuva vuorovaikutustila." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Jatkuva selaustila." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Rivitystila." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Rakenneosioiden tila." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Ei lisää isoja rakenneosioita." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Hiiren kohdalla olevaa kohdetta ei löydy." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Hiiriosoittimella puhuttaminen pois käytöstä." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Hiiriosoittimella puhuttaminen käytössä." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Virhe: Luetteloa rakenneosioista ei voitu luoda." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Ei lapsia." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d prosentti." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Siirry edelliseen sanaan" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Syvyystaso %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Uusi kohta on lisätty" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Millään sovelluksella ei ole kohdistusta." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Ei kohdistusta" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Millään sovelluksella ei ole kohdistusta." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Ei lisää lainattuja lohkoja." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Ei lisää nappeja." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Ei lisää valintaruutuja." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Ei lisää isoja rakenneosioita." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Ei lisää napsautettavia." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Ei lisää valintalaatikkoita." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Ei lisää kohtia." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Ei lisää lomakkeen kenttiä." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Ei lisää otsakkeita." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Ei lisää tason %d otsakkeita." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Ei lisää tauluja." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Ei enempää kuvia." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Maamerkkiä ei löytynyt." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Ei lisää linkkejä." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Ei lisää luetteloita." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Ei lisää listan kohtia." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Ei enempää aktiivisia alueita." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Ei lisää kappaleita." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Ei enää valitsinpainikkeita." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Ei lisää erottimia." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Ei lisää tauluja." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Ei lisää vierailemattomia linkkejä." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Ei lisää vierailtuja linkkejä." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Ei valittua tekstiä." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Ei linkillä." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Ilmoitus" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Alaosa" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Yläosa" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Ei ilmoitusviestejä" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "yksittäin" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Lausu numerot yksittäin." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "lukusanoina" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Lausu numerot lukusanoina." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "pois päältä" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "päällä" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Ladataan, odota." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Lataus valmistui." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Kohteen %s lataus valmistui." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Sivulla on %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "sivu valittu kohdistimen sijainnista saakka" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "sivu valittu kohdistimen sijaintiin saakka" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "sivun valinta peruttu kohdistimen sijainnista saakka" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "sivun valinta peruttu kohdistimen sijaintiin saakka" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "kappale valittu kohdistimen sijainnista alkaen" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "kappale valittu kohdistimen sijainnista ylöspäin" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "kappaleen valinta peruttu kohdistimen sijainnista alkaen" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "kappaleen valinta peruttu kohdistimen sijainnista ylöspäin" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Olet jo avannut Cthulhun asetusikkunan.\n" -"Sulje se ennen uuden ikkunan avaamista." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "dia %(position)d/%(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profiiliksi asetettu %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Profiileja ei löytynyt." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Edistymispalkki %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Kaikki" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Painotustaso asetettu kaikkiin." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Useimmat" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Painotustaso asetettu useimpiin." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ei mitään" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Painotustaso asetettu ei mihinkään." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Jotkut" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Painotustaso asetettu joihinkin." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Etsitään." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Haku valmistui." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu-asetukset ladattu uudelleen." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Valittu teksti on: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Valinta poistettu." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Valinta palautettu." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "ei valittu" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Koko %d, %d. Sijainti %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Leveys: %d. Korkeus: %d. %d vasemmalta. %d ylhäältä." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Puhe pois käytöstä." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Puhe käytössä." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "nopeammin." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "hitaammin." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "korkeampi." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "matalampi." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "kovempaa." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "pehmeämmin." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Nopeus %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Sävelkorkeus %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Äänenvoimakkuus %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher-moduuli %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher-ääni %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Ei käytettävissä olevia Speech-dispatcher-moduuleja" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Ei käytettävissä olevia Speech-dispatcher-ääniä" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Puhe­asetukset tallennettu" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Puhe­asetuksia ei voitu tallentaa" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Yksityiskohtaisuustaso: suppea" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Yksityiskohtaisuustaso: laaja" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " piste piste piste" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu toivottaa sinut tervetulleeksi." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu vaanii aaltojen alla." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Lepotila käytössä sovellukselle %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Lepotila poistettu käytöstä sovellukselle %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Puhe ei ole käytettävissä." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Ei löytynyt" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Tilariviä ei löytynyt" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "merkkijonoa ei löydy" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Rakenteelliset navigointinäppäimet pois käytöstä." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Rakenteelliset navigointinäppäimet käytössä." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Ei löytynyt" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Rivi %(row)d, sarake %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Taulukon loppu" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Puhu solu" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Puhu rivi" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Epäyhtenäinen" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Ei taulukossa." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Sarakkeet järjestetty uudelleen" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Rivit järjestetty uudelleen" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "sarake %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "sarake %(index)d %(total)d sarakkesta" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Sarakkeen alin." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Sarakkeen ylin." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Sarake %s valittu" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Sarakkeet %s - %s valittu" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Sarakkeiden %s - %s valinnat poistettu" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Sarake %s ei valittuna" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "rivi %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "rivi %(index)d %(total)d rivistä" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Rivin alku." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Rivin loppu." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Rivi poistettu." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Viimeinen rivi poistettu." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Rivi lisätty." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Rivi lisätty taulukon loppuun." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Rivi %s valittu" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Rivit %s - %s valittu" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Rivien %s - %s valinnat poistettu" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Rivi %s ei valittuna" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "valittu" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "ei valittu" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H tuntia, %M minuuttia ja %S sekuntia" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H tuntia ja %M minuuttia" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "kumoa" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "tee uudelleen" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versio %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "tyhjä tila" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Siirrytään alas." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Siirrytään ylös." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "nolla kohtaa" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Solu, jonka koko on %d rivi" -msgstr[1] "Solu, jonka koko on %d riviä" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d sarake" -msgstr[1] " %d saraketta" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Solu, jonka koko on %d sarake" -msgstr[1] "Solu, jonka koko on %d saraketta" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d merkin liian pitkä" -msgstr[1] "%d merkkiä liian pitkä" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d ikkuna)" -msgstr[1] "(%d ikkunaa)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d kohdistamaton valintaikkuna" -msgstr[1] "%d kohdistamatonta valintaikkunaa" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d tavu" -msgstr[1] "%d tavua" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "löytyi %d tiedosto" -msgstr[1] "löytyi %d tiedostoa" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d lomake" -msgstr[1] "%d lomaketta" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d otsake" -msgstr[1] "%d otsaketta" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d kohta" -msgstr[1] "%d kohtaa" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d maamerkki" -msgstr[1] "%d maamerkkiä" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d kohde löytyi" -msgstr[1] "%d kohdetta löytyi" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Poistutaan %d lainauslohkosta." -msgstr[1] "Poistutaan %d lainauslohkosta." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Poistutaan %d listasta." -msgstr[1] "Poistutaan %d listasta." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Luettelossa %d kohta" -msgstr[1] "Luettelossa %d kohtaa" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Luettelossa %d kohta" -msgstr[1] "Luettelossa %d kohtaa" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d arvo" -msgstr[1] "%d arvoa" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "laskentataulukko, jossa %d rivi" -msgstr[1] "laskentataulukko, jossa %d riviä" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d sarake" -msgstr[1] "%d saraketta" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "sisäkkäinen laskentataulukko, jossa %d rivi" -msgstr[1] "sisäkkäinen laskentataulukko, jossa %d riviä" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d viesti.\n" -msgstr[1] "%d viestiä.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d prosentti." -msgstr[1] "%d prosenttia." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d prosentti asiakirjasta luettu" -msgstr[1] "%d prosenttia asiakirjasta luettu" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pikseli" -msgstr[1] "%d pikseliä" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s merkki" -msgstr[1] "%(count)d %(repeatChar)s merkkiä" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d %(total)d kohteesta valittu" -msgstr[1] "%(index)d %(total)d kohteesta valittu" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Löytyi %d näytönlukijan oletuspikanäppäin." -msgstr[1] "Löytyi %d näytönlukijan oletuspikanäppäintä." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Sovellukselle %(application)s löytyi %(count)d näytönlukijan pikanäppäin." -msgstr[1] "" -"Sovellukselle %(application)s löytyi %(count)d näytönlukijan pikanäppäintä." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d väli" -msgstr[1] "%d väliä" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d sarkain" -msgstr[1] "%d sarkainta" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d taulukko" -msgstr[1] "%d taulukkoa" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "taulukko, jonka koko on tuntematon" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "taulukko, jossa %d sarake, rivimäärä tuntematon" -msgstr[1] "taulukko, jossa %d saraketta, rivimäärä tuntematon" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "taulukko, jossa %d rivi, sarakemäärä tuntematon" -msgstr[1] "taulukko, jossa %d riviä, sarakemäärä tuntematon" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "taulukko, jossa %d rivi" -msgstr[1] "taulukko, jossa %d riviä" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d sekunti sitten" -msgstr[1] "%d sekuntia sitten" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minuutti sitten" -msgstr[1] "%d minuuttia sitten" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d tunti sitten" -msgstr[1] "%d tuntia sitten" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d päivä sitten" -msgstr[1] "%d päivää sitten" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d vierailematon linkki" -msgstr[1] "%d vierailtua linkkiä" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d vierailtu linkki" -msgstr[1] "%d vierailtua linkkiä" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "vipupainike" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "kohdassa %(index)d %(total)d kohteesta" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d kaikkiaan %(total)d kohteesta" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "TASO %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "puun taso %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "PUUN TASO %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "yksityiskohtia kohteesta %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "yksityiskohtia on kohteessa %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "ehdotus" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "valintalaatikko" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "muokattava sisältö" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "syöte" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "kuvio" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "lyhennelmä" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "kiitos-osio" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "jälkipuhe" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "liitteet" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "lähdeviite" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "lähteet" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "luku" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "teostiedot" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "yhteenveto" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "etusivu" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "lopputeksti" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "lopputekstit" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "omistuskirjoitus" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "loppuviite" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "loppuviitteet" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "omistuskirjoitus" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "jälkipuhe" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "painovirheluettelo" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "esimerkki" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "esipuhe" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "sanasto" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "hakemisto" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "esittely" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "sivunvaihto" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "sivulista" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "osio" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "johdanto" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "esipuhe" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "nostettu lainaus" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Kysymys-ja-Vastaus" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "alaotsikko" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "sisällysluettelo" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s taso %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "vaakatason vierityspalkki" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "pystysuuntainen vierityspalkki" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "vaakatason liukusäädin" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "pystysuuntainen liukusäädin" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "vaakatason erottaja" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "pystysuunnan erotin" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "valintakytkin" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Kuvakepaneeli" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "banneri" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "täydentävä sisältö" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "tieto" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "pää-sisältö" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigointi" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "alue" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "etsi" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "vierailtu linkki" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "valikkopainike" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "järjestetty nousevasti" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "järjestetty laskevasti" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "järjestetty" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "napsautettava" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "supistettu" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "laajennettu" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "pitkä kuvaus" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "vaaka" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "pysty" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "merkitty" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "ei merkitty" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "päällä" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "pois päältä" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "osittain merkitty" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "painettu" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ei painettu" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "ei valittu" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "valittu" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ei valittu" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "ei valittu" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "vierailtu" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "vierailematon" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "harmaa" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "vain luku" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "luku" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "vaadittu" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "monivalinta" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "sopimaton syöte" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "virheellinen" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "oikeinkirjoitusvirhe" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "oikeinkirjoitus" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "syötteen rakenne virheellinen" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "rakenne" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Etsi" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Näytönlukijan hakuikkuna" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Sulje" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Etsi" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Etsi:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Etsi:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Ikkunan _yläosasta" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Ikkunan yläreunasta" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Alkukohta:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Jatka _alusta" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Etsi _taaksepäin" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Haun suunta:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Täsmää _kirjainkoko" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Täsmää vain _koko sanat" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Valinnat:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Oletus" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Isot kirjaimet" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlinkki" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Järjestelmä" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Sovellus" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Ikkuna" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu-asetukset" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Ohje" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Toteuta" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Kannettava" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Näppäimistön asettelu" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktiivinen _profiili:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Käynnistysprofiili:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Lataa" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Tallenna _nimellä" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Poista" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiilit" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Näkyvät vinkit" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Puhu _kohde hiiren alla" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Hiiri" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Ajan muoto:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Päivä_yksen muoto:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Aika ja päiväys" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Puhu päivitykset" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Braille-päivitykset" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Taajuus (sekuntia):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Tämä kohdistuu seuraaviin:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Piippaa päivitykset" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Edistymispalkin päivitykset" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Ota käyttöön takaisin_kelaus ja eteenpäin hyppäys Sano kaikki -tilassa" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Käytä _rakenteellista navigointia Lausu kaikki -tilassa" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Lausu kaikki er_otellen seuraavasti:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Ilmoita lainauslohkosta Sano kaikki -tilassa" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Ilmoita l_istoista Sano kaikki -tilassa" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Ilmoita _taulukoista Sano kaikki -tilassa" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Ilmoita t_auluista Sano kaikki -tilassa" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Ilmoita _lomakkeista Sano kaikki -tilassa" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Ilmoita maa_merkeistä Sano kaikki -tilassa" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Lausu kaikki" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Elementin _esitys:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Yleiset" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Voimakkuus:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Kor_keus:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Nopeus:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Henkilö:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Kieli:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Puhe_syntetisaattori:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Puhe_järjestelmä:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Äänen tyyppi:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Ison alkukirjaimen tyyli:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Äänen tyypin asetukset" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Lausu yhteenkirjoitetut sanat _sanoina" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Lausu _numerot yksittäin" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Yleiset ääniasetukset" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Ääni" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Ota _puhe käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Yksityiskohtainen" - -# Muutettu, koska muissa kontekstin kanssa ongelmia - yhdenmukaistettu -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Yksityiskohtaisuus" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "K_aikki" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Välimerkkien taso" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Puhu vain näytetty teksti" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Puhu tyhjät rivit" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Puhu _sisennykset ja tasaukset" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Puhu _kohteen oikotiet" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Puhu lapsen s_ijainti" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Puhu esittelyviestit" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Järjestelmäviestit ovat yksityiskohtaisia" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "P_uhu väreistä nimillä" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Ilmoita lainausl_ohkoista navigoitaessa" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Ilmoita _listoista navigoitaessa" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Ilmoita _taulukoista navigoitaessa" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Puhu _väärinkirjoitetun sanan ilmoitus" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Ilmoita t_auluista navigaation aikana" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Ilmoita maa_merkeistä navigaation aikana" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Ilmoita lo_makkeista navigoitaessa" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Puhu _kuvaus" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Puhu täydet rivit _laskentataulukoissa" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Puhu täydet rivit _asiakirjojen taulukoissa" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Puhu täydet rivit _käyttöliittymien taulukoissa" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Puhuttu asiayhteys" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Puhe" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Ota Braille-_tuki käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Lyhennetyt roolien nimet" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Poista rivin _loppumerkki käytöstä" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Lyhennys_taulu:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Käytä lyhennettyä braillea" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Ota käyttöön _sanojen rajoitus näytön sisään" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Näytä lisää valintoja" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Ei mitään" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Valinnan ilmaisin" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hyperlinkin ilmaisin" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Ota vilautettavat tiedotteet käyttöön" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Kesto (sekuntia):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Viestit ovat _pysyviä" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Viestit ovat _yksityiskohtaisia" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Vilautettavien tiedotteiden asetukset" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Ota näppäinten _kaiutus käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Ota _kirjainnäppäimet käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Ota _numeronäppäimet käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Ota _välimerkkinäppäimet käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Ota _tila käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Ota _muokkainnäppäimet käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Ota _funktionäppäimet käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Ota _toimintonäppäimet käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Ota _navigointinäppäimet käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Ota _sanojen kaiutus käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Ota _virkkeen kaiutus käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Kaiutus" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Näytönlukijan _muokkainnäppäimet:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Pikanäppäimet" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Äännesanakirja" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Uusi kohta" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Poista" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Ääntämisasu" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Puhu kaikki" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Älä puhu mitään" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Nollaa" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Tekstin ominaisuudet" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Siirry alimmaiseen" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Siirrä alas" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Siirry yksi ylös" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Siirrä ylimmäiseen" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Säädä valittua ominaisuutta" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Braille-ilmaisin" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Tekstin ominaisuudet" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Ota tekoälyavustaja käyttöön" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Palveluntarjoaja:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Paikallinen - Ilmainen)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API-_avaintiedosto:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Polku API-avaintiedostoon" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Hae _Claude API-avain" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Avaa selain Claude API-avaimen hakemiseksi ja tallenna automaattisesti" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Vaadi vahvistus ennen tekoälytoimintoja" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama-_malli:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Ollaman mallin nimi (esim. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama-_päätepiste:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API -päätepisteen URL (esim. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Kuvakaappauksen _laatu:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Matala" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Keskitaso" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Korkea" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Tekoälyavustaja" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Kielikoodi:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Skaalauskerroin:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Harmaasävykuva" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Käännä kuva" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Mustavalkoinen kuva" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Mustavalko-_kynnys:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analysoi värit" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Kopioi tulokset _leikepöydälle" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : aarne, b : bertta, c : celcius, d : daavid, e : eemeli, f : faarao, g : " -"gideon, h : heikki, i : iivari, j : jussi, k : kalle, l : lauri, m : matti, " -"n : niilo, o : otto, p : paavo, q : kuu, r : risto, s : sakari, t : tyyne, " -"u : urho, v : vihtori, w : wiski, x : äksä, y : yrjö, z : tseta, å : åke, " -"ä : äiti, ö : öljy" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "taustaväri" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "taustakuvan täysi korkeus" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "taustan kuviopeite" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "suunta" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "muokattavissa" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "fonttiperheen nimi" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "edustaväri" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "edustan kuviopeite" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "fontin efekti" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "sisennys" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "virhe" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "näkymätön" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "tasaus" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "kieli" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "vasen marginaali" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "rivin korkeus" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "kappaleen tyyli" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pikseleitä rivin yläpuolella" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pikseleitä rivien alapuolella" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pikseleitä rivityksen sisällä" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "oikea marginaali" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "nosta" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "mittakaava" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "koko" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "venytys" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "yliviivaus" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "tyyli" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "tekstin korostus" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "tekstin kierto" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "tekstin varjo" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "alleviivaus" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "vaihtoehto" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "pystytasaus" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "paino" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "tasaustila" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "kirjoitustila" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "tosi" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "epätosi" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ei mitään" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "kaiverrettu" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "korkokuva" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "ääriviiva" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "yliviivaus" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "rivinyliviivaus" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "vilkkuva" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "musta" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "yksinkertainen" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "kaksinkertainen" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "matala" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "merkki" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "sana" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "kirjainmerkki" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "vasen" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "oikea" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "keskitetty" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "ei tasattu" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "täytetty" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "erityisen tiivistetty" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "paljon tiivistetty" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "tiivistetty" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "vähän tiivistetty" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "tavallinen" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "vähän laajennettu" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "laajennettu" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "paljon laajennettu" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "hyvin paljon laajennettu" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "pienet suuraakkoset" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "kallistettu" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kursiivi" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Oletus" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Tekstin runko" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Otsake" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "peruslinja" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "alaviite" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "yläviite" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "ylä" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "tekstin-yläosa" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "keskellä" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "alhaalla" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "tekstin-alaosa" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "peri" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "kiinteä" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "oikeinkirjoitus" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Paina välilyöntiä vaihtaaksesi asetusta." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "Paina välilyöntiä laajentaaksesi, ja ylös/alas valitaksesi kohteen." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Paina Alt+F6 siirtääksesi kohdistuksen lapsi-ikkunoille." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "Siirrä kohteita nuolinäppäimillä tai jatka kirjoittamista." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Avaa järjestelmävalikot näppäinyhdistelmällä Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Paina ylös tai alas valitaksesi kohteen." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Supistaaksesi paina vaihto + vasemmalle." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Laajentaaksesi paina vaihto + oikealle." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Paina Enter aktivoidaksesi." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Kirjoita tekstiä." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Paina vasen- tai oikea-nuolinäppäintä nähdäksesi muut välilehdet." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Paina välilyöntiä aktivoidaksesi." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Paina ylös- tai alas-nuolinäppäintä valitaksesi arvon, tai kirjoita haluttu " -"numeerinen arvo." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Käytä nuolinäppäimiä muuttaaksesi." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Paina vasen- tai oikea-nuolinäppäintä siirtyäksesi. Siirtyäksesi kohteissa " -"paina ylös- tai alas-nuolinäppäintä." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Paina nuolinäppäintä oikealle siirtyäksesi alavalikkoon." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Vähentääksesi paina vasen-nuolinäppäintä, lisätäksesi oikea-nuolinäppäintä. " -"Pienimpään arvoon pääset painamalla Home-näppäintä, ja suurimpaan painamalla " -"End-näppäintä." diff --git a/po/fr.po b/po/fr.po deleted file mode 100644 index c487069..0000000 --- a/po/fr.po +++ /dev/null @@ -1,9264 +0,0 @@ -# French translation of cthulhu. -# Copyright (C) 2004-2022 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# -# Cédric Corazza , 2004. -# Robert-André Mauchin , 2006-2008. -# Stéphane Raimbault , 2007. -# Pierre Lemaire , 2008. -# Laurent Coudeur , 2009-2010. -# Bruno Brouard , 2011-2013. -# Julien Hardelin , 2011, 2015. -# Frédéric Wang , 2015. -# Alain Lojewski , 2017. -# Guillaume Bernard , 2019-2023. -# Julien Humbert , 2020. -# Claude Paroz , 2008-2022. -# Charles Monzat , 2018-2021. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-10-23 17:52+0200\n" -"Last-Translator: Guillaume Bernard \n" -"Language-Team: GNOME French Team \n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Lecteur d’écran Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "lecteur;écran;accessibilité;parole;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "flch" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "étiq" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "coch" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "selcoul" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "têtecol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "lstd" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icon" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "cadr" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "vlt" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "dess" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "selfi" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "remp" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "pol" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "panver" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "tête" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "cadrint" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "étiq" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "vltcouch" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lien" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "élémlst" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "barmnu" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "élémmnu" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "vltopt" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "ong" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "lstong" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "tdb" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pass" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnuctxt" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "barprog" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "bout" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "boutrad" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "élemrad" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "vltrac" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "têtelig" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "bardéf" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "vltdéf" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "glis" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "vltpar" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "boutrégl" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "barétat" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "mnudét" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "boutbsc" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "barout" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "bul" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arbr" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tabarb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "inc" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "fen" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "fen" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "tête" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pdp" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "baredt" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Tchèque degré 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Espagnol degré 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Français canadien degré 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Français degré 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Lituanien degré 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Néerlandais degré 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvégien degré 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvégien degré 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvégien degré 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvégien degré 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polonais degré 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugais degré 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Suédois degré 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabe degré 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Gallois degré 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Gallois degré 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Allemand degré 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Allemand degré 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Allemand degré 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Anglais britannique degré 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Anglais britannique degré 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Anglais américain degré 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Anglais américain degré 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Français canadien degré 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Français degré 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grec degré 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi degré 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Hongrois ordinateur 8 points" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hongrois degré 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Hongrois degré 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italien degré 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Néerlandais belge degré 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espace" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nouvelle ligne" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulation" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "point d’exclamation" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "guillemet" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "dièse" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "pour cent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "et" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrophe" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "parenthèse ouvrante" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "parenthèse fermante" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "astérisque" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "virgule" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "tiret" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "point" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barre oblique" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "deux-points" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "point-virgule" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "inférieur à" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "égal à" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "supérieur à" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "point d’interrogation" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "arobase" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "crochet ouvrant" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "barre oblique inverse" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "crochet fermant" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "circonflexe" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "soulignement" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "accent grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "accolade ouvrante" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barre verticale" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "accolade fermante" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espace insécable" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "point d’exclamation inversé" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cents" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "livre" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "signe monétaire" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barre verticale discontinue" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "paragraphe" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "tréma" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "ordinal féminin" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "guillemet français ouvrant" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "négation logique" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "trait d’union conditionnel" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "marque déposée" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "degrés" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus ou moins" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "carré" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "cube" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "accent aigu" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "pied de mouche" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "point médian" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cédille" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "exposant 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal masculin" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "guillemet français fermant" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "un quart" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "un demi" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "trois quarts" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "point d’interrogation inversé" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a accent aigu" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A ACCENT GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACCENT AIGU" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A ACCENT CIRCONFLEXE" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A TRÉMA" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A ROND EN CHEF" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E collées" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CÉDILLE" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E ACCENT GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACCENT AIGU" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E ACCENT CIRCONFLEXE" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E TRÉMA" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I ACCENT GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACCENT AIGU" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I ACCENT CIRCONFLEXE" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I TRÉMA" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O ACCENT GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACCENT AIGU" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O ACCENT CIRCONFLEXE" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O TRÉMA" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "fois" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O BARRÉ" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U ACCENT GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACCENT AIGU" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U ACCENT CIRCONFLEXE" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U TRÉMA" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACCENT AIGU" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "eszett" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a accent grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a accent circonflexe" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a tréma" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a rond en chef" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e collées" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cédille" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e accent grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e accent aigu" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e accent circonflexe" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e tréma" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i accent grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i accent aigu" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i accent circonflexe" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i tréma" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o accent grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o accent aigu" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o accent circonflexe" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o tréma" - -# obélus -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "divisé par" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o barré" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u accent aigu" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u accent grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u accent circonflexe" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u tréma" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y accent aigu" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y tréma" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y TRÉMA" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "tiret cadratin" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "guillemet simple ouvrant" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "guillemet simple fermant" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "guillemet bas simple" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "guillemet double ouvrant" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "guillemet double fermant" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "guillemet bas double" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "obèle" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "double obèle" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "puce" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "puce triangulaire" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "pour mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prime" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "double prime" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "triple prime" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "tiret" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marque déposée" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "signe de vérification" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "gros signe de vérification" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "puce en forme de x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "exposant 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "exposant 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "exposant 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "exposant 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "exposant 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "exposant 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "exposant 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "plus en exposant" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "moins en exposant" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "égal en exposant" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "parenthèse gauche en exposant" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "parenthèse droite en exposant" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "exposant n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "indice 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "indice 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "indice 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "indice 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "indice 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "indice 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "indice 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "indice 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "indice 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "indice 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "plus en indice" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "moins en indice" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "égal en indice" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "parenthèse gauche en indice" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "parenthèse droite en indice" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "carré noir" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "losange noir" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "caractère de remplacement d’objet" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Placer le pointeur sur l’élément actuel" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Effectuer un clic gauche sur l’élément où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Effectuer un clic droit sur l’élément où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Lire le document entier" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Lire la fenêtre entière avec le curseur de balayage" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Effectuer l’opération « Où suis-je ? » de base" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Effectuer l’opération « Où suis-je ? » détaillée" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Lire la sélection actuelle" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Lire les détails du lien" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Présenter le bouton par défaut" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Présenter la barre d’état" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Présenter la barre de titre" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Ouvrir la fenêtre de recherche" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Afficher la liste des actions" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Rechercher la prochaine occurrence d’une chaîne" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Rechercher l’occurrence précédente d’une chaîne" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Activer et désactiver le mode curseur de balayage" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" -"Basculer la restriction de la revue à plat à l'objet actuelActiver ou " -"désactiver la restriction du curseur de balayage à l’objet courant" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Déplacer le curseur de balayage au début de l’écran" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Déplacer le curseur de balayage à la fin de l’écran" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Déplacer le curseur de balayage au début de la ligne précédente" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Lire la ligne actuelle où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Épeler la ligne où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Épeler phonétiquement la ligne où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Déplacer le curseur de balayage au début de la ligne suivante" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Déplacer le curseur de balayage à l’élément ou mot précédent" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Lire l’élément ou le mot actuel où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Épeler l’élément ou le mot actuel où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Épeler phonétiquement l’élément ou le mot actuel où est le curseur de " -"balayage" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Déplacer le curseur de balayage au prochain élément ou mot" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Déplacer le curseur de balayage au-dessus du mot actuel" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Lire l’objet actuel où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Déplacer le curseur de balayage en dessous du mot actuel" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Déplacer le curseur de balayage au caractère précédent" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Lire le caractère où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Lire phonétiquement le caractère où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Lire la valeur Unicode du caractère où est le curseur de balayage" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Déplacer le curseur de balayage au caractère suivant" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Déplacer le curseur de balayage à la fin de la ligne" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Déplacer le curseur de balayage en bas à gauche" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copier le texte où est le curseur de balayage vers le presse-papiers" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" -"Ajouter le texte où est le curseur de balayage à la fin du presse-papiers" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Afficher les contenus du curseur de balayage" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Déterminer s’il faut lire uniquement la cellule actuelle du tableau ou la " -"ligne entière" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Lire les attributs associés avec le caractère de texte actuel" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Décaler l’afficheur braille vers la gauche" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Décaler l’afficheur braille vers la droite" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Revenir à l’objet possédant le focus du clavier" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Activer ou désactiver le braille abrégé" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Traiter une touche de routage du curseur" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marquer le début d’une sélection de texte" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marquer la fin d’une sélection de texte" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Activer le mode d’apprentissage. Appuyez sur Échap pour quitter ce mode" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Diminuer le rythme de lecture" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Augmenter le rythme de lecture" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Diminuer la hauteur de la voix" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Augmenter la hauteur de la voix" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Augmenter le volume de lecture" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Diminuer le volume de lecture" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Sélectionner le paramètre de parole précédent" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Sélectionner le paramètre de parole suivant" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Diminuer le paramètre de parole actuel" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Augmenter le paramètre de parole actuel" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Enregistrer les paramètres de parole" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Activer ou désactiver l’amortissement du son à la lecture" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Activer ou désactiver le niveau de verbosité de la voix" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Basculer le mode veille" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Quitter le lecteur d’écran" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Afficher la boîte de dialogue de configuration des préférences" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" -"Afficher la boîte de dialogue de configuration des préférences de " -"l’application" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" -"Activer ou désactiver la lecture de l’indentation et de la justification" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Modifier le style de lecture des nombres" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Activer le niveau de lecture de ponctuation suivant" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Passer au synthétiseur vocal suivant" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Activer le profil de paramètres suivant" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Activer le style de lecture des majuscules suivant" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Activer le niveau d’écho des touches suivant" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Afficher successivement les niveaux de débogage à l’exécution" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Placer un signet à l’endroit où je suis actuellement" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Aller à l’emplacement du signet précédent" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Aller au signet" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Aller à l’emplacement du signet suivant" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Ajouter un signet" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Enregistrer les signets" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Activer ou désactiver le mode lecture sous la souris" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Présenter l’heure actuelle" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Présenter la date actuelle" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Présenter la taille et la position de l’objet courant" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Transmettre la commande suivante à l’application actuelle" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" -"Lire et afficher le braille pour le message précédent du salon de discussion" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Indiquer s’il faut annoncer que les contacts saisissent un message" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Indiquer s’il faut donner les historiques de messages par salon de discussion" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Indiquer s’il faut faire précéder les messages par le nom du salon de " -"discussion" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Ligne à gauche" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Ligne à droite" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Ligne en haut" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Ligne en bas" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Geler" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "En haut à gauche" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "En bas à gauche" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Position du curseur" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Six points" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Routage du curseur" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Début couper" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Couper ligne" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Présenter le dernier message de notification" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Présenter la liste des messages de notification" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Présenter le message de notification précédent" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Présenter le message de notification suivant" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Aller au caractère suivant" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Aller au caractère précédent" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Aller au mot suivant" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Aller au mot précédent" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Aller à la ligne suivante" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Aller à la ligne précédente" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Aller au début du fichier" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Aller à la fin du fichier" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Aller au début de la ligne" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Aller à la fin de la ligne" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Aller à l’objet suivant" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Aller à l’objet précédent" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Provoquer le déroulement de la liste déroulante actuelle" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Basculer entre le mode de navigation au curseur natif et celui du lecteur " -"d’écran" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Avancer le paramètre de politesse de zone dynamique" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Définir le niveau de politesse de zone dynamique par défaut à aucun" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Revoir les annonces des zones dynamiques" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Surveiller les zones dynamiques" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" -"Déplacer le focus dans ou hors de l’objet survolé par le pointeur de la " -"souris" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Définir la ligne à utiliser comme en-têtes dynamiques de colonne" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Effacer les en-têtes dynamiques de colonne" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Définir la colonne à utiliser comme en-têtes dynamiques de ligne" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Effacer les en-têtes dynamiques de ligne" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Présenter le contenu de la ligne de saisie" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Activer ou désactiver les touches de navigation par structure" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Aller au bloc de citation précédent" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Aller au bloc de citation suivant" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Afficher la liste des blocs de citation" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Aller au bouton précédent" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Aller au bouton suivant" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Afficher une liste des boutons" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Aller à la case à cocher précédente" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Aller à la case à cocher suivante" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Afficher une liste des cases à cocher" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Aller à l’élément cliquable précédent" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Aller à l’élément cliquable suivant" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Afficher une liste des éléments cliquables" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Aller à la liste déroulante précédente" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Aller à la liste déroulante suivante" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Aller au début du conteneur" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Aller à la fin du conteneur" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Afficher une liste des listes déroulantes" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Aller à la zone de saisie précédente" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Aller à la zone de saisie suivante" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Afficher une liste des zones de saisie" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Aller au champ de formulaire précédent" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Aller au champ de formulaire suivant" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Afficher une liste des champs de formulaire" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Aller à l’en-tête précédent" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Aller à l’en-tête suivant" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Afficher une liste des en-têtes" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Aller à l’en-tête de niveau %d précédent" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Aller à l’en-tête de niveau %d suivant" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Afficher une liste des en-têtes de niveau %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Revenir au cadre interne précédent" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Aller au cadre interne suivant" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Afficher une liste des cadres internes" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Aller à l’image précédente" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Aller à l’image suivante" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Afficher une liste des images" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Aller au point de repère précédent" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Aller au point de repère suivant" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Afficher une liste des points de repère" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Revenir à l’objet important précédent" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Aller vers le prochain objet important" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Afficher une liste des objets importants" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Revenir au lien précédent" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Aller au lien suivant" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Afficher une liste des liens" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Revenir à la liste précédente" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Aller à la liste suivante" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Afficher une liste des listes" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Revenir à l’élément de liste précédent" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Aller à l’élément de liste suivant" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Afficher une liste des éléments de liste" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Revenir à la zone dynamique précédente" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Aller à la zone dynamique suivante" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Revenir à la dernière zone dynamique qui a effectué une annonce" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Aller au parent de l’objet possédant le focus de navigation." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Aller au premier enfant de l’objet possédant le focus de navigation." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" -"Aller à l’objet frère suivant l’objet possédant le focus de navigation." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" -"Aller à l’objet frère précédent l’objet possédant le focus de navigation." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Cliquer sur l’objet possédant le focus de navigation." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Activer ou désactiver la navigation dans les objets." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Revenir au paragraphe précédent" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Aller au paragraphe suivant" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Afficher une liste des paragraphes" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Revenir au bouton radio précédent" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Aller au bouton radio suivant" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Afficher une liste des boutons radio" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Revenir au séparateur précédent" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Aller au séparateur suivant" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Revenir au tableau précédent" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Aller au tableau suivant" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Afficher une liste des tableaux" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Se déplacer d’une cellule vers le bas" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Aller à la première cellule d’un tableau" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Aller à la dernière cellule d’un tableau" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Se déplacer d’une cellule vers la gauche" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Se déplacer d’une cellule vers la droite" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Se déplacer d’une cellule vers le haut" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Basculer le mode mise en page" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Basculer entre le mode navigation et le mode focus" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Activer le mode focus permanent" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Activer le mode navigation permanent" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Revenir au lien non visité précédent" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Aller au prochain lien non visité" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Afficher une liste des liens non visités" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Revenir au lien visité précédent" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Aller au prochain lien visité" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Afficher une liste des liens visités" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "bleu alice" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "blanc antique" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "aigue-marine" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azur" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "noir" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "amande mondée" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "bleu" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "bleu violet" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "brun" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "bleu cadet" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chocolat" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "corail" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "bleu vif" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "cramoisi" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cyan" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "bleu foncé" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "cyan foncé" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "jaune paille foncé" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "gris foncé" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "vert foncé" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "kaki foncé" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta foncé" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "vert olive sombre" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "orange foncé" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "orchidée foncé" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "rouge foncé" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "saumon foncé" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "vert océan foncé" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "bleu ardoise foncé" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "gris ardoise foncé" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turquoise foncé" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violet foncé" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "rose profond" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "bleu ciel profond" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "gris rabattu" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "bleu dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "rouge brique" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "blanc floral" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "vert forêt" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gris gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "blanc spectral" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "or" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "jaune paille" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "gris" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "vert" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "vert jaune" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "miellat" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "rose passion" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "rouge indien" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "ivoire" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "brun kaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "bleu lavande" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "blanc lavande" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "vert prairie" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "beige citron soie" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "bleu clair" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "corail clair" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "cyan clair" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "jaune paille clair" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "gris clair" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "vert clair" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "rose clair" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "saumon clair" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "vert océan clair" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "bleu ciel clair" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "gris ardoise clair" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "bleu acier clair" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "jaune clair" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "vert citron" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "vert citron foncé" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "tissu de lin" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "bordeaux" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "aigue-marine moyen" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "bleu moyen" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orchidée moyen" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "pourpre moyen" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "vert océan moyen" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "bleu ardoise moyen" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "vert printemps moyen" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turquoise moyen" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "rouge violet" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "bleu nuit" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "blanc menthe" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rose brumeux" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mocassin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "blanc navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "bleu marine" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "blanc dentelle" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "jaune olive" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "vert olive" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "orange" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "rouge orange" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchidée" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "jaune paille pâle" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "vert pâle" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turquoise pâle" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "rouge-violet pâle" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "beige papaye" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "beige pêche" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "brun pérou" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rose" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "prune" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "bleu poudre" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "pourpre" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "rouge" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "brun rosé" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "bleu roi" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "cuir" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "saumon" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "brun sable" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "vert océan" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "coquillage" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "terre de Sienne" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "gris argent" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "bleu ciel" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "bleu ardoise" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "gris ardoise" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "blanc neigeux" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "vert printemps" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "bleu acier" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "brun roux" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "sarcelle" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "chardon" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "rouge tomate" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquoise" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "parme" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "blé" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "blanc" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "blanc fumée" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "jaune" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "vert jaunâtre" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Activer" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Mode focus automatique durant la navigation par structure" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Mode focus automatique durant la navigation au curseur" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Mode focus automatique durant la navigation native" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Point _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Point _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Points 7 e_t 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "A_nnuler" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Sauter vers" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Valider" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Icône" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Aucun" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Annoncer" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Indique si vos con_tacts saisissent un message" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Donner les historiques de _messages par salon de discussion." - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Lire les messages provenant de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Tous les ca_naux" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Tous les canaux quand n’im_porte quelle fenêtre %s est active" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Un canal uniquement si sa _fenêtre est active" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Lire le nom du salon de discussion" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Activer le mode disposition pour le contenu" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "double-clic" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triple-clic" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Synthétiseur par défaut" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Chaîne réelle" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Chaîne de remplacement" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Active_r l’écho par caractère" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Activer les touches _diacritiques de non-espacement" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Emplacement a_ctuel" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Longueur minimale du texte correspondant :" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Options de recherche" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Lire _uniquement les lignes changées durant la recherche" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Lire les résultats durant la _recherche" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Commande" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Raccourci" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Par défaut" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Mode d’apprentissage" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Actions" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Raccourcis Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Signets" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Date et heure" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Mode lecture sous la souris" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Navigation dans les objets" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Détails des objets" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Non liée" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Curseur de balayage" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Verbosité de la voix" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Contenus du curseur de balayage" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modifié" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Bureau" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notifications" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Reçu" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Présentateur de notification" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Préférences de Cthulhu pour %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marquer en braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Prononcé sauf si" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "À lire" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Enregistrer le profil comme « en conflit »" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflit de profil utilisateur !" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Le profil %s existe déjà.\n" -"Faut-il continuer de mettre à jour le profil existant avec ces nouvelles " -"modifications ?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Chargement du profil utilisateur" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Vous êtes sur le point de modifier le profil actif. Si vous\n" -"avez simplement modifié certaines préférences, elles seront\n" -"perdues au chargement du profil.\n" -"\n" -"Faut-il charger le profil, ce qui annulera les modifications récentes ?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Enregistrer le profil sous" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nom du _profil :" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Suppression du profil utilisateur" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Vous êtes sur le point de supprimer le profile %s. Tous les paramètres non " -"enregistrés et enregistrés dans ce profil seront perdus. Voulez-vous " -"vraiment continuer et supprimer ce profil et tous les paramètres associés ?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Toutes" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Application" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Fenêtre" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Aucun" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Quelques" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "La plupar_t" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Ligne" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Phrase" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Bloc de citation" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Bouton" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Légende" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Case à cocher" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Élément cliquable" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Liste déroulante" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Description" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "En-tête" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Cadre interne" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Image" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Étiquette" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Point de repère" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Niveau" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Lien" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Élément de liste" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objet" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragraphe" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Bouton radio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rôle" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Élément sélectionné" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "État" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Texte" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valeur" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blocs de citation" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Boutons" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Cases à cocher" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Éléments cliquables" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Listes déroulantes" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Zones de saisie" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Champs de formulaire" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "En-têtes" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Cadres internes" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Images" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "En-têtes de niveau %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Points de repère" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Objets importants" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Liens" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listes" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Éléments de liste" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragraphes" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Boutons radio" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tableaux" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Liens non visités" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Liens visités" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navigation à travers la page" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Démarrer automatiquement la lecture d’une page dès qu’elle est _chargée pour " -"la première fois" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"_Présente le résumé d’une page lorsqu’elle est chargée pour la première fois" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Couper la synthèse vocale en morcea_ux entre les pauses" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "voix par défaut %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Par défaut" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlien" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Système" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Majuscule" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Correction orthographique" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Épeler l’_erreur" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Épeler la _suggestion" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Présenter le _contexte d’erreur" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Lire les coordonnées des cellules du classeur" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Toujours lire les plages de classeur sélectionnées" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Annoncer les _en-têtes de cellule" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigation à travers les tableaux" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Ignorer les lignes _vides" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Lire la _cellule" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Lire les coordonnées des _cellules" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Lire l’éten_due des cellules chevauchant plusieurs lignes/colonnes" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nom d’attribut" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Contrôler la navigation au curseur" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Activer la navigation par structure" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Thème sonore :" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Thème sonore" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Court" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d notification" -msgstr[1] "%d notifications" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Majuscule" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Contrôle" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "maj gauche" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt gauche" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "contrôle gauche" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "maj droit" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt droit" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "contrôle droit" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "méta gauche" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "méta droit" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "verr. num." - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "verr. maj." - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "verr. maj." - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "arrêt défil." - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page préc." - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page suiv." - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab gauche" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "retour arrière" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "entrée" - -# en france le nom des deux touches est confondu (return = celle sous backspace, -# enter celle sur le pavé numérique). -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "entrée" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "haut" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "bas" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "gauche" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "droite" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "touche Super gauche" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "touche Super droite" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "aide" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "changement de mode" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "échap" - -# Plutôt que inser ou inser. qui poseraient des problèmes de prononciation -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "supprimer" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "origine" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "fin" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "début" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "accent circonflexe" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "rond en chef" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "barré" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "moins" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insertion" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Verr. _maj." - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_D" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_G" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Majuscule" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s gras" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s italique" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s italique gras" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s script" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s script gras" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s gothique" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s double-trait" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s gothique gras" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s sans-sérif" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s sans-sérif gras" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s sans-sérif italique" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s sans-sérif italique gras" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s monospace" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s sans point" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "flèche vers la gauche" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "flèche vers le haut" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "flèche vers la droite" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "flèche vers le bas" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "flèche bidirectionnelle horizontale" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "flèche bidirectionnelle verticale" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "flèche vers le nord-ouest" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "flèche vers le nord-est" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "flèche vers le sud-est" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "flèche à talon vers la gauche" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "flèche à talon vers le haut" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "flèche à talon vers la droite" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "flèche à talon vers le bas" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "double flèche vers la gauche" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "double flèche vers le haut" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "double flèche vers la droite" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "double flèche vers le bas" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "double flèche bidirectionnelle horizontale" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "double flèche bidirectionnelle verticale" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "double flèche vers le nord-ouest" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "double flèche vers le nord-est" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "double flèche vers le sud-est" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "double flèche vers le sud-ouest" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "flèche vers la droite" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "pointe de flèche vers la droite" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "moins" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "plus petit que" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "plus grand que" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circonflexe" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "hatchek" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "brève" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "point" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "double ligne verticale" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "trois points horizontaux" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "pour tous" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complément" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "dérivée partielle" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "il existe" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "il n’existe pas" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "ensemble vide" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "incrément" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "appartient à" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "n’appartient pas à" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "petit appartient à" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "contient comme élément" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "ne contient pas comme élément" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "petit contient comme élément" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "ce qu’il fallait démontrer" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produit" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproduit" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "somme" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "moins ou plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus pointé" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "barre oblique de division" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "différence d’ensembles" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "opérateur astérisque" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "opérateur rond" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "opérateur puce" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "racine carrée" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "racine cubique" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "racine quatrième" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proportionnel à" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infini" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "angle droit" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "angle" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "angle mesuré" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "angle sphérique" - -# obélus -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "est un diviseur de" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "n’est pas un diviseur de" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "parallèle à" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "n’est pas parallèle à" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "et logique" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "ou logique" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersection" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "union" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "intégrale" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "intégrale double" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "intégrale triple" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "intégrale de contour" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "intégrale de surface" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "intégrale de volume" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "intégrale dans le sens horaire" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "intégrale de contour dans le sens horaire" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "intégrale de contour dans le sens antihoraire" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "par conséquent" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "parce que" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "rapport" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proportion" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "moins pointé" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "excès" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proportion géométrique" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homothétique" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "tilde renversé" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "S couché renversé" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusoïde" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "produit couronne" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "non tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "moins tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptotiquement égal à" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "non asymptotiquement égal à" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "approximativement égal à" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "approximativement mais non strictement égal à" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ni approximativement ni strictement égal à" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "presque égal à" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "non presque égal à" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "presque égal ou égal à" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "triple tilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "entièrement égal à" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "équivalent à" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "géométriquement équivalent à" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "différence entre" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "tend vers la limite" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "géométriquement égal à" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "approximativement égal à ou image de" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "image de ou approximativement égal à" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "deux-points égal" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "égal deux-points" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "rond dans égal" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "égal avec rond en chef" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "correspond à" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estime" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "équiangulaire à" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "égal avec étoile en chef" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "égal delta" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "égal par définition à" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "mesuré par" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "égalité en doute" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "pas égal à" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identique à" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "non identique à" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "strictement équivalent à" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "inférieur ou égal à" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "supérieur ou égal à" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "plus petit que par-dessus égal à" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "plus grand que par-dessus égal à" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "plus petit mais pas égal à" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "plus grand mais pas égal à" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "beaucoup plus petit que" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "beaucoup plus grand que" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "entre" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "non équivalent à" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "pas plus petit que" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "pas plus grand que" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ni plus petit ni égal à" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ni plus grand ni égal à" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "plus petit ou équivalent à" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "plus grand ou équivalent à" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ni plus petit ni équivalent à" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ni plus grand ni équivalent à" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "plus petit ou plus grand que" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "plus grand ou plus petit que" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ni plus petit ni plus grand que" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ni plus grand ni plus petit que" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "précède" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "suit" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "précède ou est égal à" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "suit ou est égal à" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "précède ou est équivalent à" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "suit ou est équivalent à" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "ne précède pas" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ne suit pas" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "sous-ensemble de" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "sur-ensemble de" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "pas un sous-ensemble de" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "pas un sur-ensemble de" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "sous-ensemble ou égal à" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "sur-ensemble ou égal à" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ni un sous-ensemble ni égal à" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ni un sur-ensemble ni égal à" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "sous-ensemble mais pas égal à" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "sur-ensemble mais pas égal à" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiensemble" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiplication de multiensemble" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "union de multiensemble" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "image carrée de" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "original carré de" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "image carrée ou égal à" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "original carré ou égal à" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "intersection carrée" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "union carrée" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "plus cerclé" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "moins cerclé" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "multiplié par cerclé" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "barre oblique de division cerclée" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "opérateur point cerclé" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "opérateur rond cerclé" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "opérateur astérisque cerclé" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "égal cerclé" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "tiret cerclé" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus encadré" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "moins encadré" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "multiplié par encadré" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "opérateur point encadré" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "taquet droit" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "taquet gauche" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "taquet vers le bas" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "taquet vers le haut" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "assertion" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modélise" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "vrai" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "oblige" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "barre verticale triple avec tourniquet à droite" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "barre verticale double avec tourniquet à droite double" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "ne prouve pas" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "pas vrai" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "n’oblige pas" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "non-barre verticale double avec tourniquet à droite double" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "précède sous relation" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "suit sous relation" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "sous-groupe normal de" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "contient comme sous-groupe normal" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "sous-groupe normal ou égal à" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "contient comme sous-groupe normal ou égal à" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original de" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "image de" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multijection" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matrice hermitienne conjuguée" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercale" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "ou exclusif" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "non et" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "non ou" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "angle droit avec arc" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triangle rectangle" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "opérateur losange" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "opérateur point" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "opérateur étoile" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "divisé multiplié" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "nœud papillon" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "produit semi-direct à gauche de facteur normal" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "produit semi-direct à droite de facteur normal" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "produit semi-direct à gauche" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "produit semi-direct à droite" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "moins tilde renversé" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "ou logique recourbé" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "et logique recourbé" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "sous-ensemble double" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "sur-ensemble double" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "intersection double" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "union double" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "fourche" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "égal et parallèle à" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "plus petit que pointé" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "plus grand que pointé" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "considérablement plus petit que" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "considérablement plus grand que" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "plus petit ou égal ou plus grand que" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "plus grand ou égal ou plus petit que" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "égal ou plus petit que" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "égal ou plus grand que" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "égal ou précède" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "égal ou suit" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "ni précédant ni égal à" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ni suivant ni égal à" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "ni image carrée ni égal à" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "ni original carré ni égal à" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "image carrée ou différent de" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "original carré ou différent de" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "plus petit mais non équivalent à" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "plus grand mais non équivalent à" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "précédant mais non équivalant à" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "suivant mais non équivalent à" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "pas un sous-groupe normal de" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "ne contient pas comme sous-groupe normal" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "ni sous-groupe normal ni égal à" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "ni égal ni contenant comme sous-groupe normal" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "trois points suspendus" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "trois points médians" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "trois points diagonaux vers le coin haut à droite" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "trois points diagonaux vers le coin bas à droite" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "appartient à avec long trait horizontal" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "appartient à avec barre verticale au bout du trait horizontal" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "petit appartient à avec barre verticale au bout du trait horizontal" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "appartient à avec point en chef" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "appartient à avec trait en chef" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "petit appartient à avec trait en chef" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "appartient à avec trait souscrit" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "appartient à avec deux traits horizontaux" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "contient avec long trait horizontal" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "contient avec barre verticale au bout du trait horizontal" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "petit contient avec barre verticale au bout du trait horizontal" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "contient avec trait en chef" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "petit contient avec trait en chef" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "appartient à un sac en notation z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "plafond à gauche" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "plafond à droite" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "plancher à gauche" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "plancher à droite" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "accolade supérieure" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "accolade inférieure" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "chevron ouvrant" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "chevron fermant" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "cercle pointé" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "union pointé" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "union avec plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "intersection carrée" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "union carrée" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "carré noir" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "carré blanc" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "losange noir" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "cercle blanc" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "cercle noir" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "petit cercle blanc" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "carré noir moyen" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s avec soulignement" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s avec barre oblique" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s avec ligne verticale" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "application" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "vide" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "gras" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "signet repéré" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "signets enregistrés" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "les signets ne peuvent être enregistrés" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Aucun signet trouvé." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Signet non trouvé." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Mode de contournement activé." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Impossible d’obtenir l’affichage de la calculatrice" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "icône" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Style de lecture des majuscules défini à icône." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "aucun" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Style de lecture des majuscules défini à aucun." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "annonce" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Style de lecture des majuscules défini à annonce." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "L’application contrôle le curseur." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu contrôle le curseur." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cellule %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s sélectionnée" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "De %s à %s sélectionnées" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "De %s à %s désélectionnées" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s désélectionnée" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Empêche l’utilisation de l’option" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Force l’utilisation de l’option" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPTION" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Paramètres facultatifs" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Utilisation : " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Ce qui suit n’est pas valide : " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Affiche les applications lancées connues" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Charge le profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Le profil n’a pas pu être chargé : %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Impossible de démarrer Cthulhu car il ne peut pas se connecter au " -"bureau.Impossible de démarrer le lecteur d’écran parce qu’il ne peut se " -"connecter au bureau." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Impossible d’activer le gestionnaire de paramètres. Sortie." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Une autre instance du lecteur d’écran est déjà lancée pour cette session.\n" -"Lancez « cthulhu --replace » pour remplacer ce processus par un nouveau." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOM" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Utilise un répertoire alternatif pour les préférences des utilisateurs" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "RÉPERTOIRE" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Version de cette application" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Remplacer une instance de Cthulhu en cours d'exécution" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Montrer ce message d’aide et quitter" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Envoie la sortie de débogage dans debug-AAAA-MM-JJ-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Envoie la sortie de débogage dans le fichier indiqué" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FICHIER" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Définit les préférences utilisateur (mode texte)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Définit les préférences utilisateur (mode graphique)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Rapportez les bogues à https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Sélection coupée vers le presse-papiers." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "coupé" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Sélection copiée dans le presse-papiers." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copié" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Contenu collé à partir du presse-papiers." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "collé" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Ne pas annoncer lorsque les contacts saisissent un message." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "Annoncer lorsque les contacts saisissent un message." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Message du salon de discussion %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nouvel onglet de discussion %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Ne pas lire le nom du salon de discussion." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "lire le nom du salon de discussion." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Ne pas donner les historiques de messages par salon de discussion." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Donner les historiques de messages par salon de discussion." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "début de suppression" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "fin de suppression" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "début d’insertion" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "fin d’insertion" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "début de mise en évidence" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "fin de mise en évidence" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "fin de suggestion" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Fin du conteneur." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Pas dans un conteneur." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "tous les éléments sélectionnés" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Le bouton par défaut est %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Le bouton par défaut est %s. Grisé" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Bouton par défaut non trouvé" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " indice %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " exposant %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Pas dans une boîte de dialogue" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "document entier sélectionné" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "document entier désélectionné" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "document sélectionné depuis la position du curseur" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "document désélectionné depuis la position du curseur" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "document sélectionné jusqu’à la position du curseur" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "document désélectionné jusqu’à la position du curseur" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "En-tête dynamique de colonne défini pour la ligne %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "En-tête dynamique de colonne effacé." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "En-tête dynamique de ligne défini pour la colonne %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "En-tête dynamique de ligne effacé." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "vide" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilooctets" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f mégaoctets" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Aucun fichier trouvé." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Contenu ajouté à la fin du presse-papiers." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Contenu ajouté au presse-papiers." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Curseur de balayage non utilisé." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Activation du curseur de balayage." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Désactivation du curseur de balayage." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Curseur de balayage restreint à l’objet courant" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Curseur de balayage non restreint" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "contient une formule" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "ouvre une boîte de dialogue" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "ouvre une grille" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "ouvre une liste à choix" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "ouvre un menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "ouvre une arborescence" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "lien d’image à zones cliquables" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "La touche saisie est déjà liée à %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Touche capturée : %s. Appuyez sur Entrée pour confirmer." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "La nouvelle touche est : %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Raccourci supprimé. Appuyez sur Entrée pour confirmer." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Le raccourci a été enlevé." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "saisissez une nouvelle touche" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "touche" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Écho défini par touche." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Aucun" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Écho défini à aucun." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "touche et mot" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Écho défini à touche et mot." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "phrase" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Écho défini par phrase." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "mot" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Écho défini par mot." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "mot et phrase" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Écho défini à mot et phrase." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Entouré par : %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "un symbole actuariel" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "une boîte" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "un cercle" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "un symbole de division longue" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "un radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "une boîte arrondie" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "une barre horizontale" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "une barre verticale" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "une barre diagonale vers le bas" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "une barre diagonale vers le haut" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "une flèche vers le nord-est" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "une ligne en bas" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "une ligne à gauche" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "une ligne à droite" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "une ligne en haut" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "un angle de phase" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "un symbole de factorielle arabe" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "et" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "début de fraction" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "début de fraction sans barre" - -# SunGloss -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "divisé par" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "fin de fraction" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "racine carrée de" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "racine cubique de" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "racine de" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "début de racine" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "fin de racine" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "indice" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "exposant" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pré-indice" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pré-exposant" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "indice souscrit" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "indice suscrit" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "fin de tableau" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "fin de tableau imbriqué" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessible" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Désactivée" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Lecture de l’indentation et de la justification désactivée." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Activée" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Lecture de l’indentation et de la justification activée." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Mode d’apprentissage. Appuyez sur Échap pour quitter." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Mode d’apprentissage activé. Appuyez sur une touche pour entendre sa " -"fonction. Pour afficher la documentation du lecteur d’écran, appuyez sur F1. " -"Pour obtenir la liste des raccourcis clavier par défaut du lecteur d’écran, " -"appuyez sur F2. Pour obtenir la liste des raccourcis clavier du lecteur " -"d’écran pour l’application actuelle, appuyez sur F3. Pour quitter le mode " -"d’apprentissage, appuyez sur Échap." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "sortie du bloc de citation." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "sortie des détails." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "sortie du flux." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "sortie de la figure." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "sortie du formulaire." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "sortie de la bannière." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "sortie du contenu complémentaire." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "sortie de l’information." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "sortie du contenu principal." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "sortie de la navigation." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "sortie de la région." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "sortie de la recherche." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "sortie de la liste." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "sortie du panneau." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "sortie du tableau." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "sortie de l’infobulle." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "sortie du résumé." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "sortie des remerciements." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "sortie de la postface." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "sortie de l’annexe." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "sortie de la bibliographie." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "sortie du chapitre." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "sortie du colophon." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "sortie de la conclusion." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "sortie du crédit." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "sortie des crédits." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "sortie de la dédicace." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "sortie des notes finales." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "sortie de l’épigraphe." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "sortie de l’épilogue." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "sortie des errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "sortie de l’exemple." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "sortie de l’avant-propos." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "sortie du glossaire." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "sortie de l’index." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "sortie de l’introduction." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "sortie de la liste des pages." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "sortie de la partie." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "sortie de la préface." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "sortie du prologue." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "sortie de la mise en exergue." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "sortie de la FAQ." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "sortie de la suggestion." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "sortie de la table des matières." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "ligne sélectionnée au-dessous de la position du curseur" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "ligne sélectionnée au-dessus de la position du curseur" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "ligne désélectionnée au-dessous de la position du curseur" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "ligne désélectionnée au-dessus de la position du curseur" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Fin du mode d’apprentissage." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "ligne sélectionnée du début jusqu’à la position précédente du curseur" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "ligne sélectionnée de la position précédente du curseur jusqu’à la fin" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "lien" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "page identique" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "site identique" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "site différent" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "lien %(uri)s vers %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "lien %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "lien %s visité" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Utilisez les flèches haut et bas pour parcourir la liste. Appuyez sur Échap " -"pour quitter." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Toutes les zones dynamiques sont définies à « désactivé »" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "niveaux de politesse des zones dynamiques restaurés" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "niveau de politesse %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "définition de la zone dynamique à « affirmative »" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "définition de la zone dynamique à « désactivée »" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "définition de la zone dynamique à « polie »" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "définition de la zone dynamique à « péremptoire »" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Surveillance des zones dynamiques désactivée" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Surveillance des zones dynamiques activée" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "aucun message dynamique enregistré" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "La prise en charge des zones dynamiques est désactivée" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Non trouvé" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Impossible de trouver l’emplacement actuel." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "désactivé" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "activé" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "mal orthographié" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Mot mal orthographié : %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Le contexte est %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Mode navigation" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Mode focus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Pour activer le mode focus appuyez sur %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Le mode focus est permanent." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Le mode navigation est permanent." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Mode mise en page" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Mode objet" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Pointeur déplacé sur l’objet" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "L’objet généré par le survol du pointeur n’a pas été trouvé." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Mode lecture sous la souris désactivé." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Mode lecture sous la souris activé." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Erreur : impossible de créer la liste des objets." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Aucun enfant." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Aucun suivant." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Aucun parent." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Aucun précédent." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Navigation simplifiée activée." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Navigation simplifiée désactivée." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Niveau d’imbrication %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Un nouvel objet a été ajouté" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Aucune action trouvée sur : %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Aucun focus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Aucune application n’est active." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Plus aucun bloc de citation." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Plus aucun bouton." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Plus aucune case à cocher." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Plus aucun objet important." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Plus aucun élément cliquable." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Plus aucune liste déroulante." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Plus aucune zone de saisie." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Plus aucun champ de formulaire." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Plus aucun en-tête." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Plus aucun en-tête au niveau %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Plus aucun cadre interne." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Plus aucune image." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Il n’y a aucun point de repère." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Plus aucun lien." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Plus aucune liste." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Plus aucun élément de liste." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Plus aucune zone dynamique." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Plus aucun paragraphe." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Plus aucun bouton radio." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Plus aucun séparateur." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Plus aucun tableau." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Plus aucun lien non visité." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Plus aucun lien visité." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Pas de texte sélectionné." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Pas sur un lien." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notification" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Bas" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Haut" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Aucun message de notification" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "chiffres" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Lire les nombres comme des chiffres." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "mots" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Lire les nombres comme des mots." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "désactivé" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "activé" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Chargement en cours. Veuillez patienter." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Chargement terminé." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Chargement de %s terminé." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "La page possède %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "page sélectionnée depuis la position du curseur" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "page sélectionnée jusqu’à la position du curseur" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "page désélectionnée depuis la position du curseur" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "page désélectionnée jusqu’à la position du curseur" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "paragraphe sélectionné vers le bas depuis la position du curseur" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragraphe sélectionné vers le haut depuis la position du curseur" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "paragraphe désélectionné vers le bas depuis la position du curseur" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragraphe désélectionné vers le haut depuis la position du curseur" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Vous avez déjà ouvert une boîte de dialogue des préférences d’Cthulhu.\n" -"Veuillez la fermer avant d’en ouvrir une nouvelle." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapositive %(position)d sur %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil défini à %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Aucun profil trouvé." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barre de progression %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Tous" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Niveau de ponctuation défini à tous." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "La plupart" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Niveau de ponctuation défini à la plupart." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Aucun" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Niveau de ponctuation défini à aucun." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Quelques" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Niveau de ponctuation défini à quelques." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Recherche." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Recherche terminée." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Paramètres de Cthulhu rechargés." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Le texte sélectionné est : %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "La sélection a été supprimée." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "La sélection a été restaurée." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Texte désélectionné" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Taille : %d, %d. Position : %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Largeur : %d. Hauteur : %d. %d de la gauche. %d du haut." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Synthèse vocale désactivée." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Synthèse vocale activée." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "plus rapide." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "moins rapide." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "plus haut." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "moins haut." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "plus fort." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "moins fort." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Débit %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Hauteur %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volume %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Module Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Voix Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Aucun module Speech-dispatcher disponible" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Aucune voix Speech-dispatcher disponible" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Paramètres de parole enregistrés" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Les paramètres de parole n'ont pas pu être enregistrés" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Niveau de verbosité : court" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Niveau de verbosité : bavard" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " points de suspension" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu vous souhaite la bienvenue." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu guette sous les vagues." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Mode veille activé pour %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Mode veille désactivé pour %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "La synthèse vocale n’est pas disponible." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Non trouvée" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Barre d’état non trouvée" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "chaîne non trouvée" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Touches de navigation par structure désactivées." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Touches de navigation par structure activées." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Non trouvé" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Ligne %(row)d, colonne %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Fin du tableau" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Lire la cellule" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Lire la ligne" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Non uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Pas dans un tableau." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Colonnes réordonnées" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Lignes réordonnées" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "colonne %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "colonne %(index)d sur %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Bas de la colonne." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Haut de la colonne." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Colonne %s sélectionnée" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Colonnes %s à %s sélectionnées" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Colonnes %s à %s désélectionnées" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Colonne %s désélectionnée" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "ligne %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "ligne %(index)d sur %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Début de la ligne." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Fin de la ligne." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Ligne supprimée." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Dernière ligne supprimée." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Ligne ajoutée." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Ligne ajoutée à la fin du tableau." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Ligne %s sélectionnée" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Lignes %s à %s sélectionnées" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Lignes %s à %s désélectionnées" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Ligne %s désélectionnée" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "sélectionné" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "non sélectionné" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H heures, %M minutes et %S secondes" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H heures et %M minutes" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "annuler" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "rétablir" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu version %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "blanc" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Poursuivre d’en bas." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Poursuivre d’en haut." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 élément" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "La cellule s’étend sur %d ligne" -msgstr[1] "La cellule s’étend sur %d lignes" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d colonne" -msgstr[1] "%d colonnes" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "La cellule s’étend sur %d colonne" -msgstr[1] "La cellule s’étend sur %d colonnes" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "Trop long de %d caractère" -msgstr[1] "Trop long de %d caractères" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d boîte de dialogue)" -msgstr[1] "(%d boîtes de dialogue)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d boîte de dialogue sans focus" -msgstr[1] "%d boîtes de dialogue sans focus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d octet" -msgstr[1] "%d octets" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fichier trouvé" -msgstr[1] "%d fichiers trouvés" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulaire" -msgstr[1] "%d formulaires" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d en-tête" -msgstr[1] "%d en-têtes" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d élément" -msgstr[1] "%d éléments" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d point de repère" -msgstr[1] "%d points de repère" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d élément trouvé" -msgstr[1] "%d éléments trouvés" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Sortie de %d bloc de citation." -msgstr[1] "Sortie de %d blocs de citation." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Sortie de %d liste." -msgstr[1] "Sortie de %d listes." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Liste de taille inconnue" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Liste à %d élément" -msgstr[1] "Liste à %d éléments" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Flux de taille inconnue" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Flux contenant %d article" -msgstr[1] "Flux contenant %d articles" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Liste descriptive à %d élément" -msgstr[1] "Liste descriptive à %d éléments" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d valeur" -msgstr[1] "%d valeurs" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tableau mathématique avec %d ligne" -msgstr[1] "tableau mathématique avec %d lignes" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d colonne" -msgstr[1] "%d colonnes" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tableau mathématique imbriqué avec %d ligne" -msgstr[1] "tableau mathématique imbriqué avec %d lignes" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d message.\n" -msgstr[1] "%d messages.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d pour cent." -msgstr[1] "%d pour cent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d pour cent du document lu" -msgstr[1] "%d pour cent du document lu" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixels" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s caractère" -msgstr[1] "%(count)d %(repeatChar)s caractères" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d sur %(total)d élément sélectionné" -msgstr[1] "%(index)d sur %(total)d éléments sélectionnés" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d raccourci par défaut du lecteur d’écran trouvé." -msgstr[1] "%d raccourcis par défaut du lecteur d’écran trouvés." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d raccourci du lecteur d’écran pour %(application)s trouvé." -msgstr[1] "" -"%(count)d raccourcis du lecteur d’écran pour %(application)s trouvés." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espace" -msgstr[1] "%d espaces" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulation" -msgstr[1] "%d tabulations" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tableau" -msgstr[1] "%d tableaux" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tableau de taille inconnue" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tableau avec %d colonne, nombre de lignes inconnu" -msgstr[1] "tableau avec %d colonnes, nombre de lignes inconnu" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tableau avec %d ligne, nombre de colonnes inconnu" -msgstr[1] "tableau avec %d lignes, nombre de colonnes inconnu" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tableau avec %d ligne" -msgstr[1] "tableau avec %d lignes" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "il y a %d seconde" -msgstr[1] "il y a %d secondes" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "il y a %d minute" -msgstr[1] "il y a %d minutes" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "il y a %d heure" -msgstr[1] "il y a %d heures" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "il y a %d jour" -msgstr[1] "il y a %d jours" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d lien non visité" -msgstr[1] "%d liens non visités" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d lien visité" -msgstr[1] "%d liens visités" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "bouton à deux états" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "sur %(index)d sur %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d sur %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "élément %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVEAU %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "niveau d’arborescence %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVEAU DE L’ARBORESCENCE %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "détails pour %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "des détails sont dans %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "suggestion" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "liste déroulante modifiable" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "contenu modifiable" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "flux" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figure" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "résumé" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "remerciements" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "postface" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "annexe" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "entrée bibliographique" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliographie" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "chapitre" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colophon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conclusion" - -# SunGloss -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "couverture" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "crédit" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "crédits" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dédicace" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "note finale" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "notes finales" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "épigraphe" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "épilogue" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "exemple" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "avant-propos" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glossaire" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "index" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introduction" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "saut de page" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "liste des pages" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "partie" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "préface" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prologue" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "mise en exergue" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "FAQ" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "sous-titre" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "table des matières" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s niveau %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "barre de défilement horizontale" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "barre de défilement verticale" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "curseur horizontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "curseur vertical" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "séparateur horizontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "séparateur vertical" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "bouton bascule" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Volet d’icônes" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "bannière" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "contenu complémentaire" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "information" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "contenu principal" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigation" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "région" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "recherche" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "lien visité" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "bouton de menu" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "trié dans l’ordre croissant" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "trié dans l’ordre décroissant" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "trié" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "cliquable" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "réduit" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "étendu" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "a une description longue" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "cochée" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "non cochée" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "activé" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "désactivé" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "partiellement cochée" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "pressé" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "non pressé" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "non sélectionné" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "sélectionné" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "non sélectionné" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "non sélectionnée" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visité" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "non visité" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "grisé" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "lecture seule" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "lectseule" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "requis" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "sélection multiple" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "saisie non valable" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "non valable" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "mauvaise orthographe" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "orthographe" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "faute grammaticale" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "grammaire" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Recherche" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Boîte de dialogue de recherche du lecteur d’écran" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Fermer" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Rechercher" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "Re_chercher :" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Rechercher :" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Haut de la fenêtre" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Haut de la fenêtre" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Démarrer depuis :" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Recherche _circulaire" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Recherche en _arrière" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Sens de la recherche :" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Respecter la casse" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Mots _entiers seulement" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Options :" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Par défaut" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Majuscule" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlien" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Système" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Application" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Fenêtre" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Préférences de Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "Aid_e" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Appliquer" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "Ordinateur _portable" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Agencement du clavier" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Profil actif :" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profil au démarrage :" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Charger" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Enregistrer _sous" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Supprimer" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profils" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Présentation des infobulles" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Lire l’objet sous la so_uris" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Souris" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Forma_t de l’heure :" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Format d_e la date :" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Heure et date" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Lire les mi_ses à jour" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Suivi des mises à jour en _braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Fréquence (sec) :" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "S’applique à :" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Suivi des mises à jour par bi_p" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Mises à jour des barres de progression" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Activer le _retour et l’avance rapide en mode tout lire" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Activer la navigation par structure en mode tout lire" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "To_ut lire par :" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Annoncer les _blocs de citation dans Tout lire" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Annoncer les li_stes dans Tout lire" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Annoncer les _tableaux dans Tout lire" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Annoncer les _panneaux dans Tout lire" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Annoncer les _formulaires dans Tout lire" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Annoncer les points de _repère dans Tout lire" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Tout lire" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Présentation des éléments :" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Général" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Volume :" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Hau_teur :" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "Dé_bit :" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Personne :" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Langue :" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "S_ynthétiseur vocal :" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Système de _synthèse vocale :" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Type de _voix :" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Style de le_cture des majuscules :" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Paramètres pour le type de voix" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Lire les chaînes à casse mélangée comme des _mots" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Lire les _nombres comme des chiffres" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Paramètres globaux pour la voix" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voix" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Activer la synthèse vocale" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Ver_beux" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Verbosité" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Tout" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Niveau de ponctuation" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Ne lire que le texte affiché" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Lire les lignes vides" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Lire l’_indentation et la justification" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Lire le ra_ccourci des objets" - -# Proposé par un formateur hypra.fr -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Lire le _rang d’un élément dans une liste" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Lire les messages du tutoriel" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Les messages _systèmes sont détaillés" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Lire les _couleurs selon leur nom" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Annoncer les _blocs de citation durant la navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Annoncer les _listes durant la navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Annoncer les _tableaux durant la navigation" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Lire l’indicateur de mot _mal orthographié" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Annoncer les _panneaux durant la navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Annoncer les points de _repère durant la navigation" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Annoncer les _formulaires durant la navigation" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Lire la _description" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Li_re la ligne complète dans les tableurs" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Lire la ligne complète dans les tableaux de _documents" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Lire la li_gne complète dans les tableaux d’interface" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Contexte parlé" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Synthèse vocale" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Activer la _prise en charge du braille" - -# Proposé par un formateur hypra.fr -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Descriptions des objets _abrégés" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Désactiver le symbole _fin de ligne" - -# manque contexte, peut ête en lien avec contracted Braille, d'où abréviation -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tableau d’abréviation :" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Activer le braille abrégé" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Activer la césure par _mot" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Paramètres d’affichage" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Aucun" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicateur de sélection" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicateur d’hyperlien" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Activer les _messages flash" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Durée (sec) :" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Les messages sont _persistants" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Les messages sont _détaillés" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Paramètres des messages flash" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Activer l’é_cho des touches" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Activer les touches _alphabétiques" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Activer les touches n_umériques" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Activer les touches de _ponctuation" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Activer l’e_space" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Activer les touches de _modification" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Activer les touches de _fonction" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Activer les touches d’_action" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Activer les touches de _navigation" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Activer l’écho par _mot" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Activer l’écho par _phrase" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Écho" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Touche(s) de _modification du lecteur d’écran :" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Raccourcis clavier" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Dictionnaire de prononciation" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nouvelle zone de saisie" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Supprimer" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Prononciation" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Tout lire " - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Ne _rien lire" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Réinitialiser" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Attributs de texte" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Déplacer tout en ba_s" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Déplacer vers le _bas" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Déplacer vers le _haut" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Déplacer tout en hau_t" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Ajuster l’attribut sélectionné" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicateur de braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Attributs de texte" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Activer l'assistant IA" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Fournisseur :" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Local - Gratuit)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Fichier de clé _API :" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Chemin vers le fichier de clé API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Obtenir la clé API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Ouvrir le navigateur pour obtenir la clé API Claude et l'enregistrer " -"automatiquement" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Demander confirmation avant les actions IA" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Modèle Ollama :" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nom du modèle pour Ollama (ex. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Point d'accès Ollama :" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL du point d'accès API Ollama (ex. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Qualité de capture d'écran :" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Bas" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Moyen" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Élevé" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Assistant IA" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Code de _langue :" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Facteur d'é_chelle :" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Image en niveaux de _gris" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Inverser l'image" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Image en _noir et blanc" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Seuil noir/blanc :" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analyser les couleurs" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Copier les résultats dans le _presse-papiers" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliett, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : x-ray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "couleur d’arrière-plan" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "hauteur complète de l’arrière-plan" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "arrière-plan grisé" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direction" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "modifiable" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "famille" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "couleur d’avant-plan" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "avant-plan grisé" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "effet de police" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indentation" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "erreur" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justification" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "langue" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "marge de gauche" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "hauteur de ligne" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "Style de paragraphe" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixels au-dessus des lignes" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixels au-dessous des lignes" - -# selon la traduction de gtk+ (po-properties) : « Pixels à l'intérieur de la coupure » -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixels entre les lignes d’un paragraphe" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "marge de droite" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "élévation" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "échelle" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "taille" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "étendu" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "barré" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "style" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "décoration du texte" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotation du texte" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "ombre du texte" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "soulignement" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variante" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "alignement vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "graisse" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "mode de césure" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "mode d’écriture" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "vrai" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "faux" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "aucun" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "empreinte" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "relief" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "contour" - -# SunGloss -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "ligne au-dessus" - -# SunGloss -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "ligne à travers" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "clignotant" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "noir" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "simple" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "double" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "bas" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "caractère" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "mot" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "mot puis caractère" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "gvd" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "dvg" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "gauche" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "droite" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centre" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "sans justification" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "justifié" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "super condensé" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "très condensé" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensé" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi-condensé" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi-étendu" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "étendu" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "très étendu" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "super étendu" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "petites majuscules" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblique" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "italique" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Par défaut" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Corps de texte" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "En-têtes" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "sur la ligne de base" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "en indice" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "en exposant" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "en haut" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "aligné en haut" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "au milieu" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "en bas" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "aligné en bas" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "hérité" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "gd-hb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "dg-hb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "hb-dg" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "hb-gd" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bh-dg" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bh-gd" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "gd" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "dg" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "hb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "continu" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "orthographe" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Appuyez sur espace pour changer d’état." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Appuyez sur espace pour développer, et utiliser haut et bas pour " -"sélectionner un élément." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Appuyez sur Alt+F6 pour donner le focus aux fenêtres filles." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Utilisez les touches fléchées ou saisissez des lettres pour vous déplacer " -"d’un élément à l’autre." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Pour atteindre les menus du système, appuyez sur les touches Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Utilisez les flèches haut et bas pour sélectionner un élément." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Pour réduire la branche, appuyez sur Maj et gauche." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Pour déplier la branche, appuyez sur Maj et droite." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Pour activer, appuyez sur la touche Entrée." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Saisissez du texte." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" -"Utilisez les flèches gauche et droite pour afficher les autres onglets." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Pour activer appuyez sur Espace." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Utilisez les flèches haut et bas pour choisir une valeur. Ou saisissez la " -"valeur numérique désirée." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Utilisez les flèches pour changer." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Pour naviguer, appuyez sur les flèches gauche et droite. Pour vous déplacer " -"à travers les éléments, appuyez sur les flèches haut ou bas." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Pour entrer dans le sous-menu, appuyez sur la flèche droite." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Pour diminuer appuyez sur la flèche gauche, pour augmenter sur la flèche " -"droite. Pour le minimum appuyez sur Origine et pour le maximum sur Fin." diff --git a/po/fur.po b/po/fur.po deleted file mode 100644 index 615f74f..0000000 --- a/po/fur.po +++ /dev/null @@ -1,9194 +0,0 @@ -# Friulian translation for cthulhu. -# Copyright (C) 2016 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Fabio Tomat , 2016. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2017-08-23 17:44+0200\n" -"Last-Translator: Fabio Tomat \n" -"Language-Team: Friulian \n" -"Language: fur\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.3\n" - -msgid "Cthulhu Screen Reader" -msgstr "" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "fre" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "selcol" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "intcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cmb" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ico" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "cur" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "cuad" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlc" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "ricd" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "dis" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "selfile" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "jem" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "selcar" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "mod" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "rictr" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "int" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "curin" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etic" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "ricniv" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "col" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "vôslst" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnù" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "sbrmnù" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "vôsmnù" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "ricopz" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "sch" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "lstsch" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnùcomp" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "sbrava" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "vôsmnùrad" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "riclid" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "sbrscr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "ricscr" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sez" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "scor" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "ricdiv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "sbrsta" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tst" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "btncom" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "sbrstr" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "sugj" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arb" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tabarb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "nocogn" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "bar" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "int" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "sbrmod" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "incor" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Cec grât 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spagnûl grât 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francês canadês grât 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francês francês grât 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Leton grât 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Olandês de Olande grât 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvegjês grât 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvegjês grât 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvegjês grât 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvegjês grât 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polac grât 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portughês grât 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Svedês grât 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arap grât 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galês grât 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galês grât 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Todesc grât 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Todesc grât 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Todesc grât 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Inglês britanic grât 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Inglês britanic grât 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Inglês american grât 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Inglês american grât 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francês canadês grât 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francês francês grât 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grêc grât 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi grât 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ongjarês computer a 8 ponts" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Ongjarês grât 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "Ongjarês grât 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Talian grât 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Olandês belgjic grât 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "spazi" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "gnove rie" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulazion" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "pont esclamatîf" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "virgulutis" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percentuâl" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "parentesi vierte" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "parentesi sierade" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterisc" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plui" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "virgule" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "tratut" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "pont" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "sbare" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "doi ponts" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "pont e virgule" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "minôr" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "uguâl" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "maiôr" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "pont interogatîf" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "caiut" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "parentesi cuadre vierte" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "sbare contrarie" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "parentesi cuadre sierade" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "circonflès" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "sotlineadure" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "acent grivi" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "parentesi a grafe vierte" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "sbare verticâl" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "parentesi a grafe sierade" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "spazi no separabil" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "pont esclamatîf invertît" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "sterlinis" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "segn di valude" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "sezion" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "dieresi" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "simbul di dirit d'autôr" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "virgulutis doplis a çampe" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "no logjic" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "simbul di marche regjistrade" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "grâts" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plui o mancul" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acût" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "simbul di paragraf" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "pont centrâl" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilie" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordenâl" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "virgulutis doplis a diestre" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "un cuart" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "un mieç" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "trê cuarts" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "pont interogatîf invertît" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Mostre plui opzions" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Mostre plui opzions" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "virgule" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "sezion" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "sezion" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "pont interogatîf" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "(%d dialic)" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d par cent." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d colone" -msgstr[1] " %d colonis" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialic)" -msgstr[1] "(%d dialics)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d file cjatât" -msgstr[1] "%d file cjatâts" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d element" -msgstr[1] "%d elements" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d colone" -msgstr[1] "%d colonis" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d messaç.\n" -msgstr[1] "%d messaçs.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d par cent." -msgstr[1] "%d par cent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixel" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d spazi" -msgstr[1] "%d spazis" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "pont interogatîf" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "doi ponts" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "virgulutis" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicadôr braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atribûts di test" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Frache spazi par comutâ." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "Frache spazi par pandi e dopre sù e jù par selezionâ une vôs." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Frache alt+F6 par dâ il focus ai barcons fîs." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Par spostâsi su une vôs, dopre i tascj frece o la ricercje incrementâl." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Par otignî i menù di sisteme frache i tascj alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Dopre sù e jù par selezionâ une vôs." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Par colassâ, frache maiusc plui çampe." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Par pandi, frache maiusc plui drete." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Par ativâ frache invie." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Scrîf dal test." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Dopre drete e çampe par viodi lis altris schedis." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Par ativâ frache spazi." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Doprâ la frece sù o jù par selezionâ il valôr o scrîf il valôr numeric " -"desiderât." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Dopre lis frecis par cambiâ" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Par navigâ, frache la frece a çampe o a drete. Par movisi tra lis vôs, " -"frache lis frecis sù o jù." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Par jentrâ intun sot-menù, frache la frece a drete." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Par diminuî frache la frece a çampe, par aumentâ frache la frece a drete. " -"Par lâ al minim frache inizi e pal massim frache Fin." diff --git a/po/ga.po b/po/ga.po deleted file mode 100644 index 3dafb72..0000000 --- a/po/ga.po +++ /dev/null @@ -1,9279 +0,0 @@ -# Irish translations for cthulhu package. -# Copyright (C) 2009 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# Seán de Búrca , 2009. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2009-08-22 08:05-0600\n" -"Last-Translator: Seán de Búrca \n" -"Language-Team: Irish \n" -"Language: ga\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=5; plural=n==1 ? 0 : (n%10==1 || n%10==2) ? 1 : " -"(n%10>=3 && n%10<= 6) ? 2 : ((n%10>=7 && n%10<=9) || n==10) ? 3 : 4;\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "Léitheoir Scáileáin agus Formhéadaitheoir Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "scáileán %s" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Roghanna Aimsithe" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Sainroghanna Cthulhu do %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "fíor" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "fíor" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "neamhní" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "scáileán %s" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Seol tuairiscí faoi fhabhtanna chuig https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "nasc %(uri)s le %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "nasc %s" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "nasc %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "soffice" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "oscail" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "ró %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Sainroghanna Cthulhu do %s" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 mír" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "LEIBHÉAL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "c%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Painéal deilbhíní" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "nasc %s" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "oscail" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "soffice" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "inléite amháin" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "riachtanach" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "Léitheoir Scáileáin agus Formhéadaitheoir Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Roghanna Aimsithe" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Bon Echo" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Léitheoir Scáileáin agus Formhéadaitheoir Cthulhu" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "méid" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stíl" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "fíor" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "bréagach" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "neamhní" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/gl.po b/po/gl.po deleted file mode 100644 index 9fd2e81..0000000 --- a/po/gl.po +++ /dev/null @@ -1,9239 +0,0 @@ -# This file is distributed under the same license as the cthulhu package. -# Copyright (C) 2010 Fran Diéguez -# Proxecto Trasno - Adaptación do software libre á lingua galega: Se desexas -# colaborar connosco, podes atopar máis información en http://www.trasno.net -# -# Ignacio Casal Quinteiro , 2006. -# Ignacio Casal Quinteiro , 2007, 2008. -# Ignacio Casal Quinteiro , 2008. -# Francisco Diéguez , 2009. -# Antón Méixome , 2009. -# Antón Méixome , 2010. -# Leandro Regueiro , 2012. -# Fran Diéguez , 2010-2022. -# Fran Dieguez , 2010-2022. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu-master-po-gl-70969.merged\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-09-03 20:55+0200\n" -"Last-Translator: Fran Dieguez \n" -"Language-Team: Galician \n" -"Language: gl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.3.2\n" -"X-Project-Style: gnome\n" -"X-DL-Team: gl\n" -"X-DL-Module: cthulhu\n" -"X-DL-Branch: master\n" -"X-DL-Domain: po\n" -"X-DL-State: Translating\n" - -msgid "Cthulhu Screen Reader" -msgstr "Lector da pantalla Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "pantalla;lector;accesibilidade;fala;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "frch" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "lnz" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "lnd" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "cv" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "sltcor" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "cabcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "mrc" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "mrcd" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "pnldir" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "debuxo" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "sltrf" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "rch" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "slc" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "cbcr" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "imx" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "mrci" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etq" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "pnlcp" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lgzn" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "elmtl" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "brmnu" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "eltmnu" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "pnlopc" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pxn" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "ltsp" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnuem" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "barpg" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "mnueltrad" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "pnlr" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "cafla" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "brdes" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "pndes" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sccn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprdr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "desl" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "pndiv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "xiratorio" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "brestd" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tab" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cla" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "eltomnudesp" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "btncnm" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "brfr" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "sux" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "rbr" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tbrb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "desc" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vrprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "vnt" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "cbc" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pdp" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apl" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "bredi" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "inc" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Checo grao 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Español grao 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francés de Canadá grao 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francés de Francia grao 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letón grao 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holandés de Países Baixos grao 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Noruego grao 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Noruego grao 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Noruego grao 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Noruego grao 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polaco grao 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugués grao 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Sueco grao 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Árabe grao 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galés grao 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galés grao 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemán grao 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemán grao 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemán grao 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Inglés do Reino Unido grao 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Inglés do Reino Unido grao 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Inglés dos Estados Unidos grao 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Inglés dos Estados Unidos grao 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francés de Canadá grao 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francés de Francia grao 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grego grao 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindú grao 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Computador de 8 puntos húngaro" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Húngaro grao 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Húngaro grao 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiano grao 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Holandés de Bélxica grao 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espazo" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nova liña" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulador" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "exclamación" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "comiñas" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "cardinal" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dólar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "por cento" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "e" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apóstrofo" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "paréntese esquerda" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "paréntese dereita" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterisco" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "máis" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "coma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "trazo" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punto" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dous puntos" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punto e coma" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "menor que" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "igual a" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "maior que" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "interrogación" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "arroba" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "paréntese esquerda" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "barra invertida" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "paréntese dereita" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "acento circunflexo" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "subliñar" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "chave esquerda" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra vertical" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "chave dereita" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "til" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espazo insecábel" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "signo de exclamación inicial" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "céntimos" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "libras" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "signo de moeda" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "ien" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra vertical partida" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "sección" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diérese" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "dereitos de copia" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a superíndice" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "comiñas compostas angulares á esquerda" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "non lóxico" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "guión" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "marca rexistrada" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "graos" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "máis ou menos" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "2 superíndice" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "3 superíndice" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "agudo" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "micron" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "signo de parágrafo" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "punto centrado" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 superíndice" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "comiñas compostas angulares á dereita" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "un cuarto" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "metade" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tres cuartos" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "signo de interrogación inicial" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a con acento agudo" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A CON ACENTO GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A CON ACENTO AGUDO" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CON ACENTO CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A CON TIL" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A CON DIÉRESE" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A CON CÍRCULO" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "LIGADURA AE" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CON CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E CON ACENTO GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E CON ACENTO AGUDO" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CON ACENTO CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E CON DIÉRESE" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I CON ACENTO GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I CON ACENTO AGUDO" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CON ACENTO CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I CON DIÉRESE" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "LIGADURA DE" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "EÑE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O CON ACENTO GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O CON ACENTO AGUDO" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CON ACENTO CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O CON TIL" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O CON DIÉRESE" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "signo de multiplicación" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O CON RAIA" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U CON ACENTO GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U CON ACENTO AGUDO" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CON ACENTO CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U CON DIÉRESE" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y GREGO" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "ZORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "beta" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a con acento grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a con acento circunflexo" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a con til" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a con diérese" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a con círculo" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ligadura ae" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c con cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e con acento grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e con acento agudo" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e con acento circunflexo" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e con diérese" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i con acento grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i con acento agudo" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i con acento circunflexo" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i con diérese" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "ligadura de" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "eñe" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o con acento grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o con acento agudo" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o con acento circunflexo" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o con til" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o con diérese" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "signo de división" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o con raia" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "zorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u con acento agudo" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u con acento grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u con acento circunflexo" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u con diérese" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y grego con acento agudo" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y grego con diérese" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y GREGO CON DIÉRESE" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florín" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "guión" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "comiña simple esquerda" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "comiña simple dereita" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "comiña simple inferior" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "comiñas compostas á esquerda" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "comiñas compostas á dereita" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "comiñas dobres inferiores" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "cruz" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "cruz dobre" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "signo de viñeta" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "signo de viñeta triangular" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "por mil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "primo" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "primo dobre" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "triple primo" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "signo de viñeta con raia" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marca rexistrada" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "marca de verificación" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "marca de verificación forte" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "signo de viñeta con forma de x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "superíndice 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "superíndice 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "superíndice 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "superíndice 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "superíndice 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "superíndice 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "superíndice 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "superíndice máis" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "superíndice menos" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "superíndice igual" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "superíndice paréntese esquerdo" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "superíndice paréntese dereito" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "superíndice n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "subíndice 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "subíndice 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "subíndice 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "subíndice 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "subíndice 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "subíndice 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "subíndice 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "subíndice 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "subíndice 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "subíndice 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "subíndice máis" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "subíndice menos" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "subíndice igual" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "subíndice paréntese esquerdo" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "subíndice paréntese dereito" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "cadrado negro" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "diamante negro" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "carácter de substitución do obxecto" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Encamiña o punteiro ao elemento actual" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" -"Efectúa un clic co botón esquerdo sobre o elemento de revisión plana actual" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" -"Efectúa un clic co botón dereito sobre o elemento plano de revisión actual" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Le todo o documento" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Le a xanela enteira usando unha revisión plana" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Realiza a operación básica «onde estou»" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Realiza a operación detallada «onde estou»" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Le a selección actual" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Ler os detalles da ligazón" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Presentar o botón predeterminado" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Presentar a barra de estado" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Presentar a barra de título" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Abre o diálogo Buscar" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Mostrar o menú de accións" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Busca a seguinte instancia dunha cadea" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Busca a instancia anterior dunha cadea" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Entra e sae do modo de revisión plana" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Trocar a restrición da revisión planta do obxecto actual" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Move a revisión plana á posición inicial" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Move a revisión plana á posición final" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Move a revisión plana ao comezo da liña anterior" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Le a liña actual de revisión plana" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Deletrea a liña actual de revisión" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Deletrea foneticamente a liña actual de revisión" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Move a revisión plana ao comezo da liña seguinte" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Move a revisión plana ao elemento ou palabra anterior" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Le o elemento ou palabra actual da revisión plana" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Deletrea a palabra ou o elemento actual da revisión plana" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Deletrea foneticamente o elemento ou palabra actual de revisión" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Move a revisión plana ao elemento ou palabra seguinte" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Move a revisión plana á palabra por enriba da palabra actual" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Le o obxecto actual da revisión plana" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Move a revisión plana á palabra por debaixo da palabra actual" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Move a revisión plana ao carácter anterior" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Le o carácter actual da revisión plana" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Le foneticamente o carácter actual de revisión plana" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Fala o valor unicode do carácter da revisión plana actual" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Move a revisión plana ao seguinte carácter" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Move a revisión plana ao final da liña" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Move a revisión plana á parte inferior esquerda" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copia os contidos baixo a revisión plana ao portapapeis" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Engade os contidos baixo a revisión plana ao portapapeis" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Mostrar os contidos da revisión plana" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Alterna entre se se le só a cela da táboa actual ou a fila completa" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Le os atributos asociados ao carácter de texto actual" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Move lentamente a pantalla de braille á esquerda" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Move lentamente a pantalla de braille á dereita" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Volve ao obxecto co foco de teclado" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Conmuta entre un braille compactado activado ou desactivado" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Procesa unha tecla de camiño de cursor" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marca o comezo dunha selección de texto" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marca o fin dunha selección de texto" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Entra en modo de aprendizaxe. Prema a tecla Esc para saír do modo de " -"aprendizaxe" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Diminúe a velocidade da voz" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Incrementa a velocidade da voz" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Diminúe o ton da voz" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Incrementa o ton da voz" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Incrementa o volume da voz" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Diminúe o volume da voz" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Busca a instancia anterior dunha cadea" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Rotar ao seguinte sintetizador de fala" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Diminúe a velocidade da voz" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Incrementa a velocidade da voz" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Preferencias do tipo de voz" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Alterna o silenciamento da voz" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Troca o nivel de detalle da fala" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Cambiar o modo de disposición" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Sae do lector de pantalla" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Mostra o diálogo de configuración das preferencias" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Mostra o diálogo de configuración das preferencias da aplicación" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Alterna a redacción da indentación e xustificación" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Cambia o estilo dos número lidos" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Cambia ao seguinte nivel de redacción da puntuación" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Rotar ao seguinte sintetizador de fala" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Cambia ao seguinte perfil de preferencias" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Cambia ao seguinte estilo de capitalización" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Cambia á seguinte clave de redacción de chaves" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Rota entre os niveles de depuración en tempo de execución" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Marcador «onde estou?» con respecto á posición actual" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Ir á localización do marcador anterior" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Ir a marcador" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Ir á localización do seguinte marcador" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Engadir marcador" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Gardar marcadores" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Cambiar o modo de revisión do rato" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Presenta a hora actual" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Presenta a data actual" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Tamaño e localización neste momento do obxecto actual" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Envía a seguinte orde á aplicación activa" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Ler e ler en braille unha mensaxe anterior dunha sala de conversas" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Conmutar se se anuncia cando os nosos amigos están tecleando" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Alternar se se fornecen historiais de mensaxes de cada sala de conversas" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Alternar entre se prefixar as mensaxes da sala de conversas co nome da sala " -"de conversas" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Liña á esquerda" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Liña á dereita" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Liña arriba" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Liña abaixo" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Conxelación" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Arriba á esquerda" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Abaixo á esquerda" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posición do cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Seis puntos" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Encamiñamento do cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Comezo de corte" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Liña de corte" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Mostrar a última mensaxe de notificación" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Mostrar a lista de mensaxes de notificación" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Mostrar a anterior mensaxe de notificación" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Presentar o seguinte mensaxe de notificación" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Vai ao carácter seguinte" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Vai ao carácter anterior" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Vai á seguinte palabra" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Vai á palabra anterior" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Vai á seguinte liña" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Vai á liña anterior" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Vai ao principio do ficheiro" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Vai ao final do ficheiro" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Vai ao comezo da liña" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Vai ao final da liña" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Vai ao seguinte obxecto" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Vai ao anterior obxecto" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Fai que se expanda o cadro combinado actual" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Cambia entre navegación nativa e a navegación por cursor" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Avanza a configuración de comportamento da área activa" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" -"Definir o nivel predeterminado de comportamento das áreas activas a " -"desactivado" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Revisar anuncio de área activa" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitorizar áreas activas" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Mover o foco contra ou lonxe respecto da posición actual do rato" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Definir a fila que se usará como cabeceiras dinámicas de columna" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Limpa as cabeceiras dinámicas de columna" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Definir a fila que se usará como cabeceiras dinámicas de columna" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Limpa as cabeceiras dinámicas de fila" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Mostra o contido da liña de entrada" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Alterna entre teclas estruturais de navegación" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Vai á cita anterior" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Vai á seguinte cita" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Mostra unha lista dos bloques de citas" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Vai ao botón anterior" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Vai ao seguinte botón" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Mostra unha lista de botóns" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Vai á caixa anterior" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Vai á seguinte caixa" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Mostra unha lista de caixas de verificación" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Vai ao clicábel anterior" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Vai ao seguinte clicábel" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Mostra unha lista dos clicábeis" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Vai á caixa de combinación anterior" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Vai á seguinte caixa de combinación" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Vai ao principio do contedor" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Vai ao final do contedor" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Mostra unha lista de caixas de combinación" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Vai á entrada anterior" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Vai á seguinte entrada" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Mostra unha lista de entradas" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Vai ao campo de formulario anterior" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Vai ao seguinte campo de formulario" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Mostra unha lista de campos de formulario" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Vai á cabeceira anterior" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Vai á cabeceira seguinte" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Mostra unha lista de cabeceiras" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Vai á cabeceira anterior no nivel %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Vai á cabeceira seguinte no nivel %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Mostra unha lista de cabeceiras do nivel %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Ir ao marco interno anterior" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Ir ao seguinte marco interno" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Mostra unha lista de marcos internos" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Vai á imaxe anterior" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Vai á seguinte imaxe" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Mostra unha lista de imaxes" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Vai ao anterior punto de referencia" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Vai ao seguinte punto de referencia" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Mostra unha lista de puntos de referencia" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Vai ao anterior obxecto grande" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Vai ao seguinte obxecto grande" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Mostra unha lista do obxectos grandes" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Vai á ligazón anterior" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Vai á seguinte ligazón" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Mostra unha lista de ligazóns" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Vai á lista anterior" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Vai á seguinte lista" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Mostra unha lista de listas" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Vai ao anterior elemento de lista" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Vai ao seguinte elemento de lista" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Mostra unha lista de elementos en lista" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Vai á anterior área activa" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Vai á seguinte área activa" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Vai á última rexión que fixo un anuncio" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Ir ao pai do obxecto co foco de navegación." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Ir ao primeiro fillo do obxecto co foco de navegación." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Ir ao seguinte irmán do obxecto co foco de navegación." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Ir ao anterior irmán do obxecto co foco de navegación." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Premer o obxecto co foco de navegación." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Trocar a navegación de obxectos simplificada." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Vai ao parágrafo anterior" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Vai ao seguinte parágrafo" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Mostra unha lista de parágrafos" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Vai ao botón de radio anterior" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Vai ao seguinte botón de radio" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Mostra unha lista de botóns de opción" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Vai ao anterior separador" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Vai ao seguinte separador" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Vai á táboa anterior" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Vai á seguinte táboa" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Mostra unha lista de táboas" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Vai abaixo unha cela" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Vai á primeira cela dunha táboa" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Vai á última cela dunha táboa" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Vai á esquerda unha cela" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Vai á dereita unha cela" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Vai arriba unha cela" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Cambiar o modo de disposición" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Cambia entre o modo de exploración e de enfoque" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Activa o modo de enfoque fixo" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Activa o modo de enfoque fixo" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Vai á anterior ligazón non visitada" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Vai á seguinte ligazón non visitada" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Mostra unha lista de ligazóns non visitadas" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Vai á anterior ligazón visitada" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Vai á seguinte ligazón visitada" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Mostra unha lista de ligazóns visitadas" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "azul alicia" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "branco antigo" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "auga mariña" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azure" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beis" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "negro" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "améndoa branqueada" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "azul" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "violeta azul" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "marrón" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "gris cadete" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chocolate" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "coral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "azul aciano" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "seda de millo" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "carmesí" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cian" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "azul escuro" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "cian escuro" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "ouro vivo" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "gris escuro" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verde escuro" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "caqui escuro" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "maxenta escuro" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "verde oliva escuro" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "laranza escuro" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "orquídea escuro" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "vermello escuro" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmón escuro" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "verde mar escuro" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "azul pizarra escuro" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "gris pizarra escuro" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turquesa esscuro" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violeta escuro" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "rosa profundo" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "azul ceo profundo" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "gris escuro" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "azul dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "ladrillo en llamas" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "branco floral" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "verde bosque" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fucsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "branco fantasma" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "ouro" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "vara de ouro" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "gris" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verde" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "amarelo verde" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "gotas de mel" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "rosa quente" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "vermello índio" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "índigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "marfíl" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "caqui" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "rubor de lavanda" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "verde céspede" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "chiffon de limón" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "azul claro" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "coral claro" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "cian claro" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "amarelo gotas de ouro claro" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "gris claro" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "verde claro" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "rosa claro" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmón claro" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "verde mar claro" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "azul ceo claro" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "gris pizarra claro" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "azul aceiro claro" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "amarelo claro" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lima" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "verde lima" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "liño" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "maxenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "granate" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "auga marina medio" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "azul medio" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orquídea medio" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "púrpura medio" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "verde mar medio" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "azul pizarra medio" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "verde primavera medio" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "tuquesa medio" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "vermello violeta medio" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "azul medianoite" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "crema menta" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rosa brumosa" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mocasín" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "branco navaxo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "mariña" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "encaixe antigo" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliva" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "verde oliva" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "laranxa" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "vermello laranxa" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orquídea" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "gotas de ouro pálido" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "verde pálido" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "tuquesa pálido" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "vermello violeta pálido" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "masa follada de melocotón" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "ameixa" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "azul po" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "púrpura" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "vermello" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "marrón rosado" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "azul real" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "marrón cadeira" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmón" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "marrón area" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "verde mar" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "cuncha" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "prata" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "azul ceo" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "azul lousa" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "gris lousa" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "neve" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "verde primavera" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "azul prateado" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "bronceado" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "cerceta" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "cardo" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomate" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquesa" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violeta" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "trigo" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "branco" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "branco fume" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "amarelo" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "verde amarelo" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Activar" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Modo de enfoque automático na navegación estructural" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Modo de enfoque automático na navegación con cursor" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Modo de enfoque automático na navegación nativa" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punto _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punto _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Puntos 7 _e 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Cancelar" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Ir a" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Aceptar" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Icona" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Ningunha" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Deletrear" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Anunciar cando os seus _amigos están tecleando" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Fornecer historiais de _mensaxes específicas de cada sala de conversas" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Ler as mensaxes de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Todas as ca_nles" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Todas as canles _cando calquera xanela de %s está activa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Unha canle só se a súa _xanela está activa" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Ler o nome da sala de conversas" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Activar o modo de distribución para o contido" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "duplo clic" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triplo clic" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizador predeterminado" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Cadea actual" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Cadea de substitución" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Activar o eco por _carácter" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Activar as teclas _diacríticas sen e" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Localización act_ual" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Lonxitude mínima do texto coincidente:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opcións de Buscar" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Ler _só as liñas modificadas durante a busca" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Ler os resultados _durante a busca" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Orde" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Combinación de teclas" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Predeterminado" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Modo de aprendizaxe" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Accións" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Combinacións de teclas braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Marcadores" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Data e hora" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Revisión de rato" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Navegación de obxecto" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Detalles do obxecto" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Non asociado" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Revisión plana" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Fala e verbosidade" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Contidos da revisión plana" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificado" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Escritorio" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificacións" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Recibido" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Presentador de notificación" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferencias de Cthulhu para %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marcar en braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Presentar a menos que" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Falar" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Gardar o perfil como conflito" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflito no perfil de usuario!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"O perfil %s xa existe.\n" -"Desexa continuar a actualización do perfil existente con estes novos cambios?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Cargar perfil de usuario" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Está a piques de cambiar o perfil activo. Se acaba\n" -"de facer cambios nas súas preferencias, eliminaranse\n" -"cando se cargue o perfil.\n" -"\n" -"Desexa continuar a carga rexeitando os cambios anteriores?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Gardar perfil como" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nome do _perfil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Eliminar o perfil de usuario" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Está a piques de eliminar o perfil %s. Todas as preferencias gardadas e sen " -"gardar neste perfil perderanse. Ten certeza que quere continuar e eliminar " -"este perfil e todas as preferencias relacionadas?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Todo" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicación" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Xanela" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Ningún" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Algunha" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Maior parte" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Liña" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Frase" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Bloque de cita" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Botón" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Título" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Caixa de verificación" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Clicábel" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Caixa de combinación" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descrición" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Cabeceira" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Marco interno" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imaxe" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiqueta" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Puntos de referencia" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivel" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Ligazón" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Elemento en lista" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Obxecto" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Parágrafo" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Botón de opción" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rol" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Elemento seleccionado" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Estado" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Texto" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valor" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Bloques de citas" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botóns" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Caixas de verificación" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Clicábel" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Caixas de combinación" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entradas" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Campos de formulario" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Cabeceiras" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Marcos internos" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imaxe" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Cabeceiras no nivel %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Puntos de referencia" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Obxectos grandes" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Ligazóns" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listas" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Elementos en lista" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Parágrafos" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Botóns de opción" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Táboas" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Ligazóns non visitadas" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Ligazóns visitadas" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navegación de páxina" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Comeza automaticamente a locución dunha páxina cando se car_ga por vez " -"primeira" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Presentar un resumo da páxina cando se carga por primeira vez" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Partir o discurso en ana_cos entre pausas" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Voz predeterminada %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Predeterminado" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Ligazón" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Maiúsculas" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Sistema de voz" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Revisión ortográfica" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "_Erro de ortografía" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "_Suxestión de ortografía" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "_Contexto presente do erro" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Ler as coordenadas da cela de folla de cálculo" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Ler sempre o rango seleccionado na folla de cálculo" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Anunciar a _cabeceira de cela" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navegación de táboa" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Saltar as celas en _branco" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Ler _cela" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Ler as coordenadas de _cela" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Ler _múltiplas expansións de cela" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nome do atributo" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Usar a navegación por cursor" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Activar a navegación _estructural" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Tema de son:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Tema de son" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Bre_ve" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d notificación" -msgstr[1] "%d notificacións" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Maiús" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "tecla Maiús esquerda" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "tecla Alt esquerda" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "tecla Ctrl esquerda" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "tecla Maiús dereita" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "tecla Alt dereita" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "tecla Ctrl dereita" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "tecla Meta esquerda" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "tecla Meta dereita" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "tecla Bloq Num" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "tecla Bloq Maiús" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "bloqueo de maiúsculas" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "tecla Bloq Despr" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "retroceso de páxina" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "avance de páxina" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tabulador esquerdo" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "retroceso" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "retorno" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "intro" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "arriba" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "abaixo" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "esquerda" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "dereita" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super esquerda" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super dereita" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menú" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "axuda" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "cambiar modo" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "inserir" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "eliminar" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "inicio" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "fin" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "comezar" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circunflexo" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "a con círculo" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "barra diagonal" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "menos" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Inserir" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Bloq_Maiús" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_E" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Maiús" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s negriña" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s cursiva" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s negriña cursiva" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s subíndice" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s subíndice negriña" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "struck duplo %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "fraktur negra %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s sans-serifa" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s sans-serifa negriña" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s sans-serifa cursiva" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s sans-serifa negriña cursiva" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s monospaciada" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s sen puntos" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "frecha á esquerda" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "frecha arriba" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "frecha á dereita" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "frecha abaixo" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "frecha á dereita e esquerda" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "frecha arriba e abaixo" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "frecha ao noroeste" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "frecha ao noreste" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "frecha ao sureste" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "frecha á esquerda desde barra" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "frecha arriba desde barra" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "frecha á dereita desde barra" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "frecha abaixo desde barra" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dupla frecha á esquerda" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dupla frecha arriba" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dupla frecha á dereita" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dupla frecha abaixo" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dupla frecha á dereita e esquerda" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dupla frecha arriba e abaixo" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dupla frecha ao noroeste" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dupla frecha ao noreste" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dupla frecha ao sureste" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dupla frecha ao suroeste" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "frecha apuntando á dereita" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "frecha apuntando á dereita" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "menor que" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "maior que" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circunflexo" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "gancho" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punto" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "liña vertical dupla" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "elipse horizontal" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "para todo" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complemento" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "diferencial parcial" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "existe" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "non existe" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "conxunto baleiro" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "incremento" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "elemento de" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "non é un elemento de" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "elemento pequeno de" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "contido como un membro" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "non contido como un membro" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "pequeno contido como un membro" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "fin da proba" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "producto" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproduto" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sumatorio" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "menos ou máis" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "punto máis" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "barra de división" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "diferenza de conxuntos" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operador de asterisco" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operador de anel" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operador bullet" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "raíz cadrada" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "raíz cúbica" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "raíz cuarta" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcional a" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinito" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "ángulo recto" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "ángulo" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "ángulo medido" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "ángulo esférico" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "divide" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "non divide" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paralelo a" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "non paralelo a" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "lóxico e" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "lóxico ou" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersección" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unión" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dobre integral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "triple integral" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integral de contorno" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integral de superficie" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integral de volume" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral no sentido da agulla do reloxo" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integral de contorno no sentido da agulla do reloxo" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integral de contorno no sentido contrario da agulla do reloxo" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "polo tanto" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "porque" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "taxa" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporción" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "punto menos" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "excede" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporción xeométrica" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotético" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "tilde invertida" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "S vaga invertida" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "onda sinoidal" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "producto corona" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "non tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "menos tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asintoticamente igual a" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "asintoticamente non igual a" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "aproximadamente igual a" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "aproximadamente pero non realmente igual a" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "nin aproximadamente nin realmente igual a" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "case igual a" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "case non igual a" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "case igual ou igual a" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "triple tilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "todo igual a" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "equivalente a" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "xeometricamente equivalente a" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "diferencia entre" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "aproxímase ao límite" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "xeometricamente igual a" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "aproximadamente igual a ou a imaxe de" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "imaxe de ou aproximadamente igual a" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dous puntos igual" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "igual dous puntos" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "anel en igual a" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "anel igual a" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "corresponde a" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estimado" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "equiangular a" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "estrela igual a" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta igual a" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "igual a por definición" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "medido por" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "igual cuestinado a" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "non igual a" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "idéntico a" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "non idéntico a" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "estritamente igual a" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "menos que ou igual a" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "maior a ou igual a" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "menos que sobre igual a" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "maior que sobre igual a" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "menor que pero non igual a" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "maior que pero non igual a" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "moito menos que" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "moito maior que" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "entre" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "non equivalente a" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "non menos que" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "non maior que" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "nin menor que nin igual a" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "nin maior que ou igual a" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "menor que ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "maior que ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "nin menor que nin equivalente a" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "nin maoir que nin equivalente a" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "menor que ou maior que" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "maior que ou menor que" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "nin menor que nin maior que" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "nin maior que nin menor que" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "precede" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "sucede" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "precede ou igual a" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "segue ou igual a" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "precede ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "segue ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "non precede" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "non segue" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subconxunto de" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superconxunto de" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "non e un subconxunto de" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "non é un superconxunto de" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subconxunto de ou igual a" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superconxunto de ou igual a" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "nin un subconxunto nin igual a" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "nin un superconxunto de nin igual a" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subconxunto de con non igual a" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superconxunto de con non igual a" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiconxunto" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiplicación multiconxunto" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "unión multiconxunto" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "imaxe cadrada de" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "orixinal cadrada de" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "imaxe cadrada de ou igual a" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "orixinal cadrada de ou igual a" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "cadrado boca abaixo" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "cadrado boca arriba" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "mais dentro de círculo" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "menos dentro de círculo" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "cruz dentro de círculo" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "barra de división dentro de círculo" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "operador punto dentro de círculo" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operador de anel dentro de círculo" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operador de asterisco dentro de círculo" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "igual en círculo" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "barra dentro de círculo" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "mais dentro de cadrado" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "menos dentro de cadrado" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "cruz dentro de cadrado" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operador punto dentro de cadrado" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "dirección dereita" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "dirección esquerda" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "dirección abaixo" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "dirección arriba" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "aserción" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modelos" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "verdadeiro" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "forza" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "triple barra vertical con inserción pola dereita" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dupla barra vertical con inserción pola derecha" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "non proba" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "non verdadeiro" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "non forza" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "dupla barra vertical negada con inserción dobre pola derecha" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "precede baixo relación" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "sucede baixo relación" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "subgrupo normal de" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "contén un subgrupo normal" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "subgrupo normal de ou igual a" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "contén como subgrupo normal de ou igual a" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "orixinal de" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "imaxe de" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matriz conxugada hermitiana" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalar" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ángulo dereito con arco" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triángulo dereito" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operador diamante" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operador punto" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operador estrela" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "cruz division" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "paxariña" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "dupla barra vertical negada con inserción dobre pola esquerda" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "factor normal pola dereita do producto semidirecto" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "producto semidirecto esquerdo" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "producto semidirecto dereito" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "igual tilde inverso" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "or lóxico curvo" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "and lóxico curvo" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "subconxunto dobre" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "superconxunto dobre" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "intersección dobre" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "unión dobre" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "fcthulhu" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "igual e paralelo a" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "menor que con punto" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "maior que con punto" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "moito menos que" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "moito maior que" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "menor que igual a ou maior que" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "maior que igual a ou menor que" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "igual a ou menor que" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "igual a ou maior que" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "igual a ou precede" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "igual a ou sucede a" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "non precede ou igual" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "non sucede ou igual" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "non é unha imaxe cadrada de ou igual a" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "non é orixinal cadrado de ou igual a" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "imaxe cadrada ou non igual a" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "cadrado orixinal de ou non igual a" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "menor que pero non equivalente a" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "maior que pero non equivalente a" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "precede pero non equivalente a" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "sucede pero non equivalente a" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "non é un subgrupo normal de" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "non contido como un subgrupo normal" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "non é un subgrupo normal de ou igual a" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "non contido como un subgrupo normal ou igual a" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "elipse vertical" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "elipse horzontal no medio da liña" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "elipse diagonal arriba dereita" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "elipse diagonal abaixo dereita" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "elemento de con raia horizontal larga" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "elemento de con barra vercial ao final de raia horizontal" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "elemento de con barra vertical pequeno ao final de barra horizontal" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "elemento de con punto enriba" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "elemento de con barra superior" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "elemento de con barra superior pequeno" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "elemento de con barra inferior" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "elemento de con dúas barras horizontais" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "elemento de con raia horizontal larga" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "contén" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"que contén, con barra vertical e unha barra horizontal no seu tope, símbolo " -"pequeno" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "contén con barra superior" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "contén con barra superior pequeno" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "notación z de membresia" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "tope esquerdo" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "tope dereito" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "piso esquerda" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "piso dereita" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "piso inferior" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "chave inferior" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "abre corchete" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "pecha corchete" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "punto nun círculo" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "unión con punto" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "unión con símbolo de máis" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "intersección cadrado" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "unión cadrado" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "cadrado negro" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "cadrado branco" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "diamante negro" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "círculo branco" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "círculo negro" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "viñeta branca" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "cadrado pequeno medio negro" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s con subliñado" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s con barra" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s con liña vertical" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplicación" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "en branco" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "negra" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "marcador introducido" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "marcadores gardados" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "non foi posíbel gardar os marcadores" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Non se atoparon marcadores." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Non se atopou o marcador." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Modo enviar tecla activado." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Non foi posíbel obter a pantalla da calculadora" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "icona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Estilo de capitalización estabelecido á icona." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ningún" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Estilo de capitalización estabelecido a ningún." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "corrección ortográfica" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Estilo de capitalización estabelecido á corrección ortográfica." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "A aplicación está controlando o cursor." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "A aplicación está controlando o cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cela %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s seleccionada" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s ate %s seleccionadas" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s ate %s deseleccionadas" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s seleccionada" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Prever o uso da opción" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Forzar o uso da opción" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCIÓN" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Argumentos opcionais" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Uso: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Os seguintes non son válidos: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Imprime as aplicacións coñecidas que se están executando" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Cargar perfil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Non foi posíbel cargar o perfil: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Non é posíbel iniciar o lector de pantalla porque non se pode conectar co " -"Escritorio." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Non é posíbel activar o xestor de configuracións. Saíndo." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Xa se está executando outro proceso do lector de pantalla nesta sesión.\n" -"Execute «cthulhu --replace» para substituír dito proceso con un novo." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Usa un cartafol alternativo para as preferencias do usuario" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versión desta aplicación" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" -"Substitúe a instancia actualmente en execución desde lector de pantalla" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Mostra esta mensaxe de axuda e saír" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Enviar a saída de depuración debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Enviar a depuración da saída ao ao ficheiro especificado" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FICHEIRO" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Configura as preferencias do usuario (versión en texto)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Configura as preferencias do usuario (versión GUI)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Informe de fallos a https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Selección cortada ao portapapeis." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "cortar" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Selección copiada ao portapapeis." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copiada" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Contidos pegados desde o portapapeis." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "pegado" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Non anunciar cando os seus amigos están tecleando." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anunciar cando os seus amigos están tecleando." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Mensaxe da sala de conversas %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nova lapela de conversa %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Non ler o nome da sala de conversas." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "ler o nome da sala de conversas." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Non fornecer historiais de mensaxes de cada sala de conversas." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Fornecer historiais de mensaxes específicas de cada sala de conversas." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "inicio da eliminación" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "final de eliminación" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "inicio da inserción" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "final de inserción" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "realzar inicio" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "final do realce" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "final da suxestión" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Fin do contenedor." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Non está nun contenedor." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "todos os elementos seleccionados" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "O botón predeterminado é %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Os botóns predeterminados son %s. Agrisado" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Non se atopou o botón predeterminado" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subíndice %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " superíndice %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Non está nun diálogo" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "seleccionouse todo o documento" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "documento completo deseleccionado" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "documento seleccionado a partir da posición do cursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "documento deseleccionado a partir da posición do cursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "documento seleccionado até a posición do cursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "documento deseleccionado até a posición do cursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Cabeceira dinámica fixada para a fila %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Limpouse a cabeceira dinámica de columna." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Definiuse a cabeceira dinámica de fila para a columna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Limpouse a cabeceira dinámica de fila." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "baleira" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Non se atopou ningún ficheiro." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Contidos engadidos ao portapapeis." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Contidos copiados ao portapapeis." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Non se está usando a revisión plana." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Entrando no modo de revisión plana." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Deixando a revisión plana." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "A revisión plana está restrinxida ao obxecto actual" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Revisión plana sen restrición" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "ten fórmula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "abre un diálogo" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "abre a grade" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "abre unha caixa de lista" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "abre un menú" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "abre o árbore" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "ligazón de mapa de imaxe" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "A tecla introducida xa está asociada a %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Capturouse a tecla: %s. Prema Intro para confirmar." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "A nova tecla é: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Atallo de teclado eliminado. Prema intro para confirmar." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Retirouse o atallo de teclado." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "introduza unha nova tecla" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "chave" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Eco estabelecido á tecla." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ningunha" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Eco estabelecido a Ningún." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "chave e palabra" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Eco estabelecido a tecla e palabra." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "frase" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Eco estabelecido a frase." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "palabra" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Eco estabelecido a palabra." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "palabra e sentenza" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Eco estabelecido a palabra e frase." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Pechado por: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "un símbolo actuarial" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "unha caixa" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "un círculo" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "un símbolo de división longa" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "un radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "unha caixa redondeada" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "unha barra en diagonal abaixo dereita" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "unha barra vertical" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "unha barra diagonal abaixo" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "unha barra diagonal arriba" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "unha barra ao noreste" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "unha liña ao fondo" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "unha liña á esquerda" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "unha liña á dereita" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "unha liña arriba" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "un ángulo fasor" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "un símbolo factorial arábico" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "e" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "inicio de fracción" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "fracción sen barra, inicio" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "sobre" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "final de fracción" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "raíz cadrada de" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "raíz cúbica de" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "raíz de" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "inicio de raíz" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "final de raíz" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subíndice" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "superíndice" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pre-subíndice" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pre-superíndice" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "subíndice" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "sobreíndice" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "final de táboa" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "final de táboa anidada" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccesíbel" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Desactivado" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Redacción das sangrías e xustificación desactivada." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Activada" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Redacción das sangrías e xustificación activada." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Modo de aprendizaxe. Prema a tecla Esc para saír." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Entrar no modo de aprendizaxe. Prema F1 para ver a documentación do lector " -"de pantalla. Para obter unha lista de atallos predefinidos do lector de " -"pantalla, prema F2. Para obter unha lista dos atallos do lector de pantalla " -"para a aplicación actual, prema F3. Para saír do modo de aprendizaxe, prema " -"a tecla Esc." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "saíndo do bloque de cita." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "deixando detalles." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "saíndo do fornecedor." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "saíndo da figura." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "saíndo do formulario." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "saíndo do banner." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "saíndo do contido complementario." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "saíndo da información." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "saíndo do contido principal." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "saíndo do navegación." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "saíndo da rexión." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "saíndo da busca." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "saíndo da lista." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "saíndo do panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "saíndo da táboa." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "saíndo do consello." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "saíndo do resumo." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "saíndo dos agradementos." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "saíndo do posfixo." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "saíndo do apéndice." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "saíndo da bibliografía." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "saíndo do capítulo." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "saíndo do colofón." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "saíndo da conclusión." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "saíndo do recoñecemento." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "saíndo dos créditos." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "saíndo da dedicación." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "saíndo das notas finais." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "saíndo do epígrafe." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "saíndo do epílogo." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "saíndo da errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "saíndo do exemplo." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "saíndo do prefacio." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "saíndo do glosario." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "saíndo do índice." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "saíndo da introdución." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "saíndo da lista de páxinas." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "saíndo da parte." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "saíndo do prefacio." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "saíndo do prólogo." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "saíndo do sumario." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "saíndo das preguntas e respostas." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "deixando suxestión." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "saíndo da táboa de contidos." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "liña seleccionada cara a abaixo desde a posición do cursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "liña seleccionada cara a arriba desde a posición do cursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "liña deseleccionada cara a abaixo desde a posición do cursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "liña deseleccionada cara a arriba desde a posición do cursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Saíndo do modo de aprendizaxe." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "liña seleccionada desde o inicio até a anterior posición do cursor" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "liña seleccionada até o final desde a posición do cursor" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ligazón" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "mesma páxina" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "mesmo sitio" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "sitio diferente" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s ligazóns a %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "ligazón %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "ligazón %s visitada" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Use as frechas Arriba e Abaixo para navegar pola lista. Prema escape para " -"saír." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Desactiváronse todas as rexións activas" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "restaurouse o comportamento de todas as rexións activas" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nivel de comportamento %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "configurando rexión activa e firme" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "configurando rexión activa a desactivada" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "configurando rexión activa e educada" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "configurando rexión activa e groseira" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Monitorización de áreas activas desactivado" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Monitorización de áreas activas activado" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "non se gardou ningunha mensaxe de actividade" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "A capacidade de áreas activas está desactivada" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Non atopado" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Non foi posíbel atopar a localización actual." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "desactivado" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "activado" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "palabra mal escrita" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Palabra mal escrita: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "O contexto é %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Modo de navegación" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Modo de enfoque" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Para activar o modo de enfocado prema %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "O modo de enfoque é fixo." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "O modo de navegación é fixo." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Modo de disposición." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Modo obxecto." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "O punteiro moveuse ao obxecto." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "O rato sobre o obxecto non atopado." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Revisión de rato desactivada." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Revisión de rato activada." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Erro: non é posíbel crear a lista de obxectos." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Non ten fillos." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Non hai seguinte." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Non hai pai." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Non hai anterior." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Activouse a navegación simplificada." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Desactivouse a navegación simplificada." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nivel de aniñamento %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Acaba de se engadir un elemento novo" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Non se atoparon accións en: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Non hai foco" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Ningunha aplicación ten o foco." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Non hai máis citas." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Non hai máis botóns." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Non hai máis caixas." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Non hai máis obxectos grandes." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Non hai máis clicábeis." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Non hai máis caixas de combinación." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Non hai máis entradas." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Non hai máis campos de formulario." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Non hai máis cabeceiras." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Non hai máis cabeceiras no nivel %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Non hai máis marcos internos." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Non hai máis imaxes." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Non se atoparon puntos de referencia." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Non hai máis ligazóns." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Non hai máis listas." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Non hai máis elementos de lista." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Non hai máis áreas activas." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Non hai máis parágrafos." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Non hai máis botóns de radio." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Non hai máis separadores." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Non hai máis táboas." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Non hai máis ligazóns non visitadas." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Non hai máis ligazóns visitadas." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Non se seleccionou ningún texto." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Non está nunha ligazón." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificación" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Abaixo" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Arriba" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Non hai mensaxes de notificación" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "díxitos" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Ler os números como díxitos." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "palabras" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Ler os números como palabras." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "desactivado" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "activado" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Cargando. Agarde." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Finalizou a carga." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Finalizou a carga de %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "A páxina ten %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "páxina seleccionada a partir da posición do cursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "páxina seleccionada até a posición do cursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "páxina deseleccionada a partir da posición do cursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "páxina deseleccionada até a posición do cursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "parágrafo seleccionado a partir da posición do cursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "parágrafo seleccionado a partir da posición do cursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "parágrafo deseleccionado a partir da posición do cursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "páxina deseleccionada a partir da posición do cursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Xa ten unha instancia do diálogo de preferencias de Cthulhu aberta.\n" -"Péchea antes de abrir unha nova." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "desprazar %(position)d de %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Perfil estabelecido a %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Non se atopou ningún perfil." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra de progreso %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Todas" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Nivel de puntuación estabelecido a todos." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "A maior parte" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Nivel de puntuación estabelecido á maioría." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ningunha" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Nivel de puntuación estabelecido a ningún." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Algunha" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Nivel de puntuación estabelecido a algúns." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Buscando." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Rematou a busca." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Recargáronse as configuracións de usuario do lector de pantalla." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "O texto seleccionado é: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Eliminouse a selección." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Selección restaurada." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Texto non seleccionado." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Tamaño: %d, %d. Localización: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Ancho: %d. Alto: %d. %d desde a esquerda. %d desde arriba." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Voz desactivada." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Voz activada." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "máis rápido." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "máis lento." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "máis alto." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "máis baixo." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "máis forte." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "máis suave." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Velocidade %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Ton %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volume %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Módulo de Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Voz de Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "A voz non está dispoñíbel." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "A voz non está dispoñíbel." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Voz activada." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "non foi posíbel gardar os marcadores" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Nivel de detalle: curto" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Nivel de detalle: detallado" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " punto punto punto" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu dálle a benvida." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu agocha baixo as ondas." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Modo suspensión activado para %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Modo de suspensión desactivado para %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "A voz non está dispoñíbel." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Non atopado" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Non se atopou a barra de estado" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "non se atopou a cadea" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "As teclas de navegación estrutural están desactivadas." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "As teclas de navegación estrutural están activadas." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Non atopado" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Fila %(row)d, columna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Fin de táboa" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Ler cela" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Ler fila" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Non uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Non está nunha táboa." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Columnas reordenadas" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Filas reordenadas" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "columna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "columna %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Final da columna." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Principio da columna." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Columna %s seleccionada" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Columnas %s ate %s seleccionadas" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Columnas %s ate %s deseleccionadas" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Columna %s deseleccionada" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "fila %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "fila %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Comezo da fila." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Fin da fila." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Fila eliminada." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Última fila eliminada." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Fila inserida." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Rila inserida ao final da táboa." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Fila %s seleccionada" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Filas %s ate %s seleccionadas" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Filas %s ate %s deseleccionadas" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Fila %s deseleccionada" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "seleccionado" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "non seleccionado" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H horas, %M minutos e %S segundos" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H horas e %M minutos" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "desfacer" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "refacer" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Versión de Cthulhu %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "espazo en branco" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Saltando ao final." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Saltando ao principio." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elementos" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "A cela expándese en %d fila" -msgstr[1] "A cela expándese en %d filas" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d columna" -msgstr[1] " %d columnas" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "A cela expándese en %d columnas" -msgstr[1] "A cela expándese en %d columnas" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d carácter demasiado longo" -msgstr[1] "%d carácteres demasiado longos" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d diálogo)" -msgstr[1] "(%d diálogos)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d diálogo sen foco" -msgstr[1] "%d diálogos sen foco" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ficheiro atopado" -msgstr[1] "%d ficheiros atopados" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulario" -msgstr[1] "%d formularios" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d cabeceira" -msgstr[1] "%d cabeceiras" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elemento" -msgstr[1] "%d elementos" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d punto de referencia" -msgstr[1] "%d puntos de referencia" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d elemento atopado" -msgstr[1] "%d elementos atopados" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Deixando %d bloque de cita." -msgstr[1] "Deixando %d bloques de cita." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Deixando %d lista." -msgstr[1] "Deixando %d listas." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Lista de tamaño descoñecido" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista con %d elemento" -msgstr[1] "Lista con %d elementos" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Fornecedor de tamaño descoñecido" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Fornecedor con %d artigo" -msgstr[1] "Fornecedor con %d artigos" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Lista de descricións con %d termo" -msgstr[1] "Lista de descricións con %d termos" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d valor" -msgstr[1] "%d valores" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "táboa matemática con %d fila" -msgstr[1] "táboa matemática con %d filas" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d columna" -msgstr[1] "%d columnas" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "táboa matemática aniñada con %d fila" -msgstr[1] "táboa matemática aniñada con %d filas" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d mensaxe.\n" -msgstr[1] "%d mensaxes.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d por cento." -msgstr[1] "%d por cento." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "lido %d por cento do documento" -msgstr[1] "lido %d por cento do documento" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d píxel" -msgstr[1] "%d píxeles" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s carácter" -msgstr[1] "%(count)d %(repeatChar)s caracteres" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d de %(total)d elemento seleccionado" -msgstr[1] "%(index)d de %(total)d elementos seleccionados" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Atopouse %d atallo predeterminado do lector de pantalla." -msgstr[1] "Atopáronse %d atallos predeterminados do lector de pantalla." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Atopouse %(count)d atallo do lector de pantalla para %(application)s." -msgstr[1] "" -"Atopáronse %(count)d atallos de lector de pantalla para %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espazo" -msgstr[1] "%d espazo" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulación" -msgstr[1] "%d tabulacións" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d táboa" -msgstr[1] "%d táboas" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "táboa de tamaño descoñecido" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "táboa con %d columna, contía de filas descoñecida" -msgstr[1] "táboa con %d columnas, contía de filas descoñecida" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "táboa con %d fila, contía de columnas descoñecida" -msgstr[1] "táboa con %d filas, contía de columnas descoñecida" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "táboa con %d fila" -msgstr[1] "táboa con %d filas" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "Hai %d segundo" -msgstr[1] "Hai %d segundos" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "Hai %d minuto" -msgstr[1] "Hai %d minutos" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "Hai %d hora" -msgstr[1] "Hai %d horas" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "Hai %d día" -msgstr[1] "Hai %d días" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d ligazón non visitada" -msgstr[1] "%d ligazóns non visitadas" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d ligazón visitada" -msgstr[1] "%d ligazóns visitadas" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "conmutar" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "sobre o %(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "elemento %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nivel de árbore %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVEL DE ÁRBORE %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detalles para %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "ten detalles en %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "suxestión" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "caixa de comprobación editábel" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "contidos editábeis" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "fornecedor" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figura" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "resumo" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "agradecementos" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "posfixo" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "apéndice" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "entrada da bibliografía" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografía" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "capítulo" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colofón" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conclusión" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "portada" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "crédito" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "créditos" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "adicación" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "nota final" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "notas finais" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epígrafe" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epílogo" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "exemplo" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "prefacio" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosario" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "índice" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introdución" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "salto de páxina" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "lista de páxinas" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "parte" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "prefacio" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prólogo" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "sumario" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Preguntas e respostas" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "subtítulo" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "táboa de contidos" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivel %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "barra de desprazamento horizontal" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "barra de desprazamento vertical" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "deslizador horizontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "deslizador vertical" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "separador horizontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "separador vertical" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "cambiar modo" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Panel de iconas" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "banner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "contido complementario" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "información" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "contido principal" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navegación" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "rexión" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "buscar" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "ligazón visitada" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "botón de menú" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "ordeado ascendente" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "ordeado descendente" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "ordeado" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "clicábel" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "contraído" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "expandido" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "ten unha descrición longa" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "marcada" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "desmarcada" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "activado" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "desactivado" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "parcialmente marcada" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "premido" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "non premido" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "non seleccionado" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "seleccionado" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "non seleccionado" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "non seleccionado" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visitada" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "non visitada" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "agrisado" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "só lectura" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "sólect" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "requerido" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "selección múltipla" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "entrada non válida" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "non válido" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "falta ortográfica" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ortografía" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "gramática non válida" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramática" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Buscar" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Diálogo de buscar do Lector de pantalla" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Pechar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Buscar" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "Bu_scar por:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Buscar por:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Parte su_perior da xanela" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Parte superior da xanela" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Comezar en:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Dar a volta" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "_Buscar cara a atrás" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Dirección de busca:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Diferenciar _maiúsculas de minúsculas" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Coincidir só coa palabra compl_eta" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opcións:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Predeterminado" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Maiúsculas" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Ligazón" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicación" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Xanela" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Lector da pantalla Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Axuda" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Aplicar" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "Portáti_l" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Disposición do teclado" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Activar _perfil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Perfil de inicio:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Cargar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Gardar _como" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Eliminar" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Perfiles" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Mostrar indicacións" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Ler o obxecto debaixo do ra_to" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Rato" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Formato da _hora:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formato da d_ata:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Data e hora" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Ler _actualizacións" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Actualizacións de _braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frecuencia (segs):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplica a:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Emitir _son coas anovacións" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Actualizacións da barra de progreso" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Activar _rebobinar e ir cara adiante en Decir todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Activar a navegación _estructural en Decir todo" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Ler todo po_r:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Anunciar _citas en Ler todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Anunciar _listas en Ler todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Anunciar _táboas en Ler todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Anunciar _paneis en Ler todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Anunciar _formularios en Ler todo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Anunciar puntos de _referencia en Ler todo" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Ler todo" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Presentación do elemento:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Xeral" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lume:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Ton:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Velocidade:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persoa:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Idioma:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "_Sintetizador de voz:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Sistema de _voz:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipo de _voz:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Estilo de _capitalización:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Preferencias do tipo de voz" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Ler as ca_deas con caixa alta e baixa como como palabras" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Ler os _números como díxitos" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Preferencias globais da voz" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Activar a voz" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Detallada" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Verbalización" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Todo" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Nivel de puntuación" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Ler só o texto mostrado" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Ler as liñas en branco" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Ler a _sangría e a xustificación" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Ler os re_cursos mnemotécnicos do obxecto" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Ler a _posición filla" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Ler as mensaxes de tutorial" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "O _sistema de mensaxes é detallado" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Le_r as cores dos nomes" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Modo _citas durante a navegación" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Anunciar _listas durante a navegación" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Modo _táboas durante a navegación" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Ler o indicador de _palabra mal escrita" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Modo _paneis durante a navegación" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Anunciar _puntos de referencia durante a navegación" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Anunciar _formularios durante a navegación" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Falar _descrición" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Ler a fila completa nas follas de _cálculo" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Ler a fila completa nas tábos dos _documentos" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Ler a fila completa nas táboas da _interface" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Contexto falado" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Activar a _compatibilidade de Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Nome _abreviado dos roles" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Desactivar o símbolo de _fin de liña" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Táboa de contracción:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Activar Braille contraído" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Activar o axustes de _palabras" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Mostrar preferencias" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Ningún" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicador de selección" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicador de hiperligazón" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Activar _mensaxes flash" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Duración (segundos):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "As mensaxes son _persistentes" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "As mensaxes son _detalladas" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Preferencias para os mensaxes flash" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Activar o eco de _teclado" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Activar as teclas _alfabéticas" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Activar as teclas _numéricas" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Activar as teclas de _puntuación" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "_Activar o espacio" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Activar as teclas _modificadoras" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Activar as teclas de _función" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Activar as teclas de a_cción" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Activar as teclas de _navegación" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Activar o eco por _palabra" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Activar o eco por _frases" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Eco" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Tecla(s) _modificadora(s) do lector de pantalla:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Combinacións de teclas" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Dicionario de puntuación" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nova entrada" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Eliminar" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronunciación" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Ler _todo" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Ler _ningún" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Restabelecer" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributos de texto" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mover ao _final" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mover un _abaixo" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mover _un arriba" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mover ao _principio" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Axustar o atributo seleccionado" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicador de Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributos de texto" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Activar asistente de IA" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Provedor:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Local - Gratuíto)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Ficheiro de _chave API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Ruta ao ficheiro de chave API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Obter _chave API de Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Abrir o navegador para obter a chave API de Claude e gardar automaticamente" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Requirir confirmación antes das accións de IA" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Modelo Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nome do modelo para Ollama (p. ex., llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Punto final Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL do punto final da API Ollama (p. ex., http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Calidade da captura de pantalla:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "baixo" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Media" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Alta" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Asistente de IA" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Idioma:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "ien" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Factor de _escala:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Imaxe en escala de _grises" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Inverter imaxe" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Imaxe en _branco e negro" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Limiar de branco/negro:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analizar cores" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Contidos copiados ao portapapeis." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "cor de fondo" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "altura completa do fondo" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "fondo punteado" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "dirección" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editábel" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nome da familia" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "cor de primeiro plano" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "primeiro plano punteado" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efecto do tipo de letra" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "sangría" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "erro" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisíbel" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "xustificación" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "idioma" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "marxe esquerda" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "altura da liña" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "estilo do parágrafo" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "píxeles por riba das liñas" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "píxeles por debaixo das liñas" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "píxeles dentro da liña" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "marxe dereita" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "comezo" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "escala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "tamaño" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "estirar" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "riscado" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estilo" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decoración do texto" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotación do texto" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "texto sombreado" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "subliñado" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variante" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "aliñamento vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "largura" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "modo de axuste" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "modo de escritura" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "verdadeiro" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falso" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ningún" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "gravar" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "membrete" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "contorna" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "liña enriba" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "riscado" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "intermitencia" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "negra" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "sinxelo" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dobre" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "baixo" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "carácter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "palabra" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "carácter de palabra" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "E a D" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "D a E" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "esquerda" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "dereita" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centrado" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "sen xustificación" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "encher" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultracondensado" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extracondensado" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensado" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semicondensado" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semiexpandido" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expandido" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extraexpandido" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultraexpandido" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "maiúsculas pequenas" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblicuo" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "cursiva" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Predeterminado" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Corpo do texto" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Cabeceira" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "en liña" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "subíndice" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "superíndice" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "superior" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "texto-superior" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "medio" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "inferior" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "texto-inferior" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "herdar" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "esde-arab" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "dees-arab" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "arab-dees" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "arab-esde" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "abar-dees" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "abar-esde" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "esde" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "dees" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "arab" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "sólido" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "verificación ortográfica" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Prema espazo para alternar." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Prema espazo para expandir e use arriba e abaixo para seleccionar un " -"elemento." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Prema alt+f6 para dar o foco ás xanelas fillas." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Para ir aos elementos, use ben as frechas ou teclee a continuación para " -"busca." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Para ir aos menús do sistema prema a tecla Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Usar arriba e abaixo para seleccionar un elemento." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Para contraer, prema maiús máis esquerda." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Para expandir, prema maiús máis dereita." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Para activar prema intro." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Escriba no texto." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Usar esquerda e dereita para ver outras lapelas." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Para activar prema espazo." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Usar as frechas arriba e abaixo para seleccionar o valor. Ou teclee o valor " -"numérico desexado." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Usar as frechas para cambiar." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Para navegar prema frecha esquerda ou frecha dereita. Para moverse entre os " -"elementos prema frecha arriba ou frecha abaixo." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Para entrar no submenú prema frecha dereita." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Para decrementar prema frecha esquerda, para incrementar prema frecha " -"dereita, para mínimo prema inicio e para o máximo prema fin." diff --git a/po/gu.po b/po/gu.po deleted file mode 100644 index c4f2799..0000000 --- a/po/gu.po +++ /dev/null @@ -1,9892 +0,0 @@ -# translation of cthulhu.HEAD.gu.po to Gujarati -# translation of cthulhu.HEAD.po to Gujarati -# This file is distributed under the same license as the PACKAGE package. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. -# Ankit Patel , 2004. -# Ankit Patel , 2006. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD.gu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2006-08-14 13:18+0530\n" -"Last-Translator: Ankit Patel \n" -"Language-Team: Gujarati \n" -"Language: gu\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.9.1\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu સ્ક્રીન વાંચક અને વિસ્તૃતકારક" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -#, fuzzy -msgid "alrt" -msgstr "ચેતવણી" - -#: src/cthulhu/braille_rolenames.py:54 -#, fuzzy -msgid "anim" -msgstr "Anim" - -#: src/cthulhu/braille_rolenames.py:57 -#, fuzzy -msgid "arw" -msgstr "તીર" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -#, fuzzy -msgid "cptn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -#, fuzzy -msgid "icn" -msgstr "ચિહ્ન" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "ડાયલ" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "દોરો" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -#, fuzzy -msgctxt "shortbraille" -msgid "form" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -#, fuzzy -msgid "ifrm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -#, fuzzy -msgid "lnk" -msgstr "કડી" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "રેડિયો" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -#, fuzzy -msgid "sctn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "ફેરવો" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -#, fuzzy -msgid "cll" -msgstr "ખાનું" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -#, fuzzy -msgid "tre" -msgstr "ટ્રી" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "જગ્યા" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "નવીલીટી" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "ટેબ" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "ઉદ્ગાર" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "ક્વોટ" - -#: src/cthulhu/chnames.py:66 -#, fuzzy -msgid "number" -msgstr "mnubr" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "ડોલર" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "ટકા" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "અને" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "અવતરણ" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "તારો" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "વત્તા" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "અલ્પવિરામ" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "ડેશ" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "ટપકું" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "સ્લેશ" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "કોલન" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "સેમીકોલન" - -#: src/cthulhu/chnames.py:126 -#, fuzzy -msgid "less" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "બરાબર" - -#: src/cthulhu/chnames.py:134 -#, fuzzy -msgid "greater" -msgstr "કરતાં મોટું" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "પ્રશ્ન" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "એટ" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "બેકસ્લેશ" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "કેરેટ" - -#: src/cthulhu/chnames.py:162 -#, fuzzy -msgid "underline" -msgstr "નવીલીટી" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -#, fuzzy -msgid "grave" -msgstr "રાખોડી" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/chnames.py:174 -#, fuzzy -msgid "vertical bar" -msgstr "ઊભી લીટી" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "ટીલ્ડા" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "જગ્યા" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -#, fuzzy -msgid "cents" -msgstr "ટકા" - -#: src/cthulhu/chnames.py:199 -#, fuzzy -msgid "pounds" -msgstr "પાઉન્ડ" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -#, fuzzy -msgid "broken bar" -msgstr "મેનુ પટ્ટી" - -#: src/cthulhu/chnames.py:215 -#, fuzzy -msgid "section" -msgstr "પ્રશ્ન" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -#, fuzzy -msgid "registered" -msgstr "કેન્દ્રિય" - -#: src/cthulhu/chnames.py:247 -#, fuzzy -msgid "macron" -msgstr "ચિહ્ન" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -#, fuzzy -msgid "acute" -msgstr "auto" - -#: src/cthulhu/chnames.py:271 -#, fuzzy -msgid "mu" -msgstr "mnu" - -#: src/cthulhu/chnames.py:275 -#, fuzzy -msgid "paragraph marker" -msgstr "ફકરો" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -#, fuzzy -msgid "cedilla" -msgstr "ખાનું" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "ડાયલ" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -#, fuzzy -msgid "times" -msgstr "ટીલ્ડા" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -#, fuzzy -msgid "a grave" -msgstr "રાખોડી" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -#, fuzzy -msgid "a tilde" -msgstr "ટીલ્ડા" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -#, fuzzy -msgid "c cedilla" -msgstr "ખાનું" - -#: src/cthulhu/chnames.py:475 -#, fuzzy -msgid "e grave" -msgstr "રાખોડી" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -#, fuzzy -msgid "i grave" -msgstr "રાખોડી" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -#, fuzzy -msgid "n tilde" -msgstr "ટીલ્ડા" - -#: src/cthulhu/chnames.py:515 -#, fuzzy -msgid "o grave" -msgstr "રાખોડી" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -#, fuzzy -msgid "o tilde" -msgstr "ટીલ્ડા" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -#, fuzzy -msgid "o stroke" -msgstr "અવતરણ" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -#, fuzzy -msgid "u grave" -msgstr "રાખોડી" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -#, fuzzy -msgid "florin" -msgstr "flr" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "ડેશ" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "જમણું shift" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -#, fuzzy -msgid "dagger" -msgstr "પાનું" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -#, fuzzy -msgid "per mille" -msgstr "બ્રેઈલી" - -#: src/cthulhu/chnames.py:629 -#, fuzzy -msgid "prime" -msgstr "ચોકઠું" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -#, fuzzy -msgid "check mark" -msgstr "ચકાસણી વસ્તુ" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "સપાટ રીવ્યુને આગળના અક્ષરે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "ઈનપુટ વાક્યના સમાવિષ્ટો બોલે છે." - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "વર્તમાન સપાટ રીવ્યુ વસ્તુ પર ડાબું ક્લિક કરે છે." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "વર્તમાન સપાટ રીવ્યુ વસ્તુ પર જમણું ક્લિક કરે છે." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "વર્તમાન દસ્તાવેજ બોલે છે." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "વર્તમાન સપાટ રીવ્યુ લીટી બોલે છે." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "હું ક્યાં છું પ્રક્રિયા કરે છે." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "હું ક્યાં છું પ્રક્રિયા કરે છે." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "વર્તમાન સપાટ રીવ્યુ લીટી બોલે છે." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "ટોગલ બટન" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "પરિસ્થિતિ પટ્ટી" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "પરિસ્થિતિ પટ્ટી" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "આગળના રજૂઆતક વ્યવસ્થાપક પર ફેરવે છે." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "આગળના રજૂઆતક વ્યવસ્થાપક પર ફેરવે છે." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "સપાટ રીવ્યુ સ્થિતિમાં દાખલ થાય અને બહાર નીકળે." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "સપાટ રીવ્યુને અંતિમ સ્થાને ખસેડે છે." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "સપાટ રીવ્યુને ઘર સ્થિતિએ ખસેડે છે." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "સપાટ રીવ્યુને અંતિમ સ્થાને ખસેડે છે." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "સપાટ રીવ્યુને પહેલાંની લીટીની શરૂઆતમાં ખસેડે છે." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "વર્તમાન સપાટ રીવ્યુ લીટી બોલે છે." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "વર્તમાન સપાટ રીવ્યુ લીટી બોલે છે." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "વર્તમાન સપાટ રીવ્યુ લીટી બોલે છે." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "સપાટ રીવ્યુને આગળની લીટીની શરૂઆતમાં ખસેડે છે." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "સપાટ રીવ્યુને પહેલાંની વસ્તુ અથવા શબ્દ પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "વર્તમાન સપાટ રીવ્યુ વસ્તુ અથવા શબ્દ કહે છે અથવા જોડણી બોલે છે." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "વર્તમાન સપાટ રીવ્યુ વસ્તુ અથવા શબ્દ કહે છે અથવા જોડણી બોલે છે." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "વર્તમાન સપાટ રીવ્યુ વસ્તુ અથવા શબ્દ કહે છે અથવા જોડણી બોલે છે." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "સપાટ રીવ્યુને આગળની વસ્તુ અથવા શબ્દ પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "સપાટ રીવ્યુને વર્તમાન શબ્દની ઉપરના શબ્દ પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "વર્તમાન સપાટ રીવ્યુ ઓબ્જેક્ટ બોલે છે." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "સપાટ રીવ્યુને વર્તમાન શબ્દની નીચેના શબ્દે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "વર્તમાન સપાટ રીવ્યુ અક્ષર બોલે છે." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "વર્તમાન સપાટ રીવ્યુ અક્ષર બોલે છે." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "વર્તમાન સપાટ રીવ્યુ અક્ષર બોલે છે." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "સપાટ રીવ્યુને આગળના અક્ષરે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "સપાટ રીવ્યુને લીટીના અંતે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "સપાટ રીવ્યુને તળિયે ડાબે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "વર્તમાન સપાટ રીવ્યુ વસ્તુ અથવા શબ્દ કહે છે અથવા જોડણી બોલે છે." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "વર્તમાન સપાટ રીવ્યુ વસ્તુ અથવા શબ્દ કહે છે અથવા જોડણી બોલે છે." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "સપાટ રીવ્યુને અંતિમ સ્થાને ખસેડે છે." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "શું ખાલી વર્તમાન કોષ્ટક ખાનું અથવા આખી હરોળ વાંચવી તે બદલે છે." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "વર્તમાન લખાણ અક્ષર સાથે સંકળાયેલ લક્ષણને વાંચે છે." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "ડાબી બાજુએ બ્રેઈલી ડિસ્પ્લે ગોઠવે છે." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "જમણી બાજુએ બ્રેઈલી ડિસ્પ્લે ગોઠવે છે." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "કીબોર્ડ ફોકસ સાથે ઓબ્જેક્ટ આપે છે." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "સપાટ રીવ્યુને આગળની લીટીની શરૂઆતમાં ખસેડે છે." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "સપાટ રીવ્યુને લીટીના અંતે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"શીખવાની સ્થિતિમાં દાખલ થાય છે. શીખવાની સ્થિતિમાંથી બહાર નીકળવા માટે એસ્કેપ દબાવો." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "બોલી દર ઘટાડે છે." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "બોલી દર વધારે છે." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "બોલી પીચ ઘટાડે છે." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "બોલી પીચ વધારે છે." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "બોલી દર વધારે છે." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "બોલી દર ઘટાડે છે." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "જરૂરી બોલી સર્વર પસંદ કરો." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "જરૂરી બોલી સર્વર પસંદ કરો." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "બોલી દર ઘટાડે છે." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "બોલી દર વધારે છે." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "બોલીને શાંત કરવાનું બદલે છે." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "પસંદગીઓ રૂપરેખાંકન સંવાદન દર્શાવે છે." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "પસંદગીઓ રૂપરેખાંકન સંવાદન દર્શાવે છે." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "હાંસિયાથી અંતર અને ગોઠવણી બોલો (_i)" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "બોલી સિન્થેસાઈઝર (_z):" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "ડિબગ સ્તરને રન ટાઈમે ફેરવે છે." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "વર્તમાન સપાટ રીવ્યુ ઓબ્જેક્ટ બોલે છે." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "પહેલાંનો સંવાદ કક્ષ સંદેશો બોલે અને બ્રેઈલ કરે છે." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "બદલો કે શું આપણે સંવાદ કક્ષ સંદેશાઓને સંવાદ કક્ષ સાથે પૂર્વગ આપીએ." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "બદલો કે શું આપણે સંવાદ કક્ષ સંદેશાઓને સંવાદ કક્ષ સાથે પૂર્વગ આપીએ." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -#, fuzzy -msgid "Freeze" -msgstr "ટ્રી" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "તળિયું (_B):" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "વૈવિધ્યપૂર્ણ માપ (_e)" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "વૈવિધ્યપૂર્ણ માપ (_e)" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "સપાટ રીવ્યુને આગળના અક્ષરે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "ટોગલ બટન" - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "સપાટ રીવ્યુને પહેલાંની વસ્તુ અથવા શબ્દ પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "સપાટ રીવ્યુને લીટીના અંતે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "ઈનપુટ વાક્યના સમાવિષ્ટો બોલે છે." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "સપાટ રીવ્યુને આગળની લીટીની શરૂઆતમાં ખસેડે છે." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "સપાટ રીવ્યુને લીટીના અંતે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "સ્તંભ હેડર" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "ઈનપુટ વાક્યના સમાવિષ્ટો બોલે છે." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "ટોગલ બટન" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "ટોગલ બટન" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "વધુ વિકલ્પો દર્શાવો" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "ચકાસણી બોક્સ" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "કમ્બો બોક્સ" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l સમાવનાર" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l સમાવનાર" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "સપાટ રીવ્યુને પહેલાંની વસ્તુ અથવા શબ્દ પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "સપાટ રીવ્યુને પહેલાંની વસ્તુ અથવા શબ્દ પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "સપાટ રીવ્યુને પહેલાંની વસ્તુ અથવા શબ્દ પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "રેડિયો બટન" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "ટ્રી સ્તર %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "આંતરિક ચોકઠું" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "સપાટ રીવ્યુને આગળના અક્ષરે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "વર્તમાન સપાટ રીવ્યુ ઓબ્જેક્ટ બોલે છે." - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "વધુ વિકલ્પો દર્શાવો" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "ઓબ્જેક્ટોની જરૂરીયાત વિશે ડિબગ જાણકારીને ફોકસ સાથે છાપે છે" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "કીબોર્ડ ફોકસ સાથે ઓબ્જેક્ટ આપે છે." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "ફકરો" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "રેડિયો બટન" - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "રેડિયો બટન" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "સપાટ રીવ્યુને પહેલાંના અક્ષર પર ખસેડે છે." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "સપાટ રીવ્યુને આગળના અક્ષરે ખસેડે છે." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "જમણું control" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "ToggleButton" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "કી ઈકો સક્રિય કરો (_k)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "ડિરેક્ટરીઓ બટન" - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "કોરું" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "રાખોડી" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "રાખોડી" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "રાખોડી" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "જમણું control" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "જમણું alt" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "નવીલીટી" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "ચિત્ર" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "અને" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr " સ્ક્રીન" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "ટેબ" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "સફેદ જગ્યા" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "સફેદ જગ્યા" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr " સ્ક્રીન" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "ચિહ્ન" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "કંઈ નહિં" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "જોડણી ચકાસણી:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -#, fuzzy -msgid "_Speak Chat Room name" -msgstr "સંવાદ કક્ષ નામ બોલે છે." - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -#, fuzzy -msgid "Default Synthesizer" -msgstr "બોલી સિન્થેસાઈઝર (_z):" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "શબ્દ અનુસાર ઈકો સક્રિય કરો (_w)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "અલ્પવિરામ" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "મૂળભૂત" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "શીખવાની સ્થિતિમાંથી બહાર નીકળે છે." - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "પ્રશ્ન" - -#: src/cthulhu/guilabels.py:296 -#, fuzzy -msgid "Braille Bindings" -msgstr "બ્રેઈલી" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -#, fuzzy -msgid "Unbound" -msgstr "પાઉન્ડ" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "સપાટ રીવ્યુ સ્થિતિમાં દાખલ થાય અને બહાર નીકળે." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -#, fuzzy -msgid "_Desktop" -msgstr "DesktopIcon" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "હાંસિયાથી અંતર અને ગોઠવણી બોલો (_i)" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu પસંદગીઓ" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -#, fuzzy -msgid "Speak" -msgstr "બોલો " - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "બધા (_A)" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "કાર્યક્રમ" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "વિન્ડો" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "કંઈ નહિં (_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "અમુક (_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "મોટા ભાગનું (_o)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -#, fuzzy -msgid "Sentence" -msgstr "કેન્દ્રિય" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "ક્વોટ" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "બટન" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "કાર્યક્રમ" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "કમ્બો બોક્સ" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "કાર્યક્રમ" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "હેડર" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "ચિત્ર" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "લેબલ" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "કડી" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "યાદી" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "ફકરો" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "પસંદ કરાયેલ" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "StatusBar" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "લખાણ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "ક્વોટ" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "બટન" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "કમ્બો બોક્સ" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "હેડર" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "ચિત્ર" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "ટ્રી સ્તર %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "કડી" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "યાદી" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "ફકરો" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "કોષ્ટક" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "મૂળભૂત" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "હાયપરલીંક" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "ઉપરનો કિસ્સો" - -#: src/cthulhu/guilabels.py:852 -#, fuzzy -msgid "Speech Dispatcher" -msgstr "બોલી નિષ્ક્રિય કરાયેલ." - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "જોડણી ચકાસણી:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "બોલો " - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "સંક્ષિપ્ત (_f)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "હાંસિયાથી અંતર અને ગોઠવણી બોલો (_i)" -msgstr[1] "હાંસિયાથી અંતર અને ગોઠવણી બોલો (_i)" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "ચેતવણી" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "ડાબું control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "ડાબું shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "ડાબું alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ડાબું control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "જમણું shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "જમણું alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "જમણું control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ડાબી મેટા" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "જમણી મેટા" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "નંબર તાળું" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "કેપીટલ તાળું" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "કેપીટલ તાળું" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "સરકાવવાને તાળું" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "પાનું ઉપર" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "પાનું નીચે" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "ડાબી tab" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "જગ્યા" - -#: src/cthulhu/keynames.py:157 -#, fuzzy -msgid "return" -msgstr "rtpn" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "કેન્દ્રિય" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "પાનું નીચે" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "ડાબું alt" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "જમણું alt" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "મેનુ" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -#, fuzzy -msgid "escape" -msgstr "scpn" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -#, fuzzy -msgid "insert" -msgstr "seprtr" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -#, fuzzy -msgid "delete" -msgstr "પસંદ કરાયેલ" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -#, fuzzy -msgid "home" -msgstr "અમુક (_m)" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "અને" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -#, fuzzy -msgid "ring" -msgstr "જમણું alt" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "અવતરણ" - -#: src/cthulhu/keynames.py:305 -#, fuzzy -msgid "minus" -msgstr "mnu" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "seprtr" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -#, fuzzy -msgid "Alt_R" -msgstr "ચેતવણી" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -#, fuzzy -msgid "Alt_L" -msgstr "ચેતવણી" - -#: src/cthulhu/keybindings.py:188 -#, fuzzy -msgid "Ctrl" -msgstr "trtbl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "colhdr" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "અયોગ્ય" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "કામ કરવાની જગ્યા " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "તીર" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "તીર" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "જમણું control" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "જમણું control" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "mnu" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "ટપકું" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "ઊભી લીટી" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "સમપ્રમાણ" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "આપોઆપ પૂર્ણ" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "ખાલી" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "વત્તા" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "mnu" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "વિભાજક" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "સમપ્રમાણ" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "જમણું alt" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "ફેરવો" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "સ્તરવાળી તકતી" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "ઊભી લીટી" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "વિભાજક" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "ડિરેક્ટરી તકતી" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "આંતરિક ચોકઠું" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "સમપ્રમાણ" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "mnu" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "ટીલ્ડા" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "ટીલ્ડા" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "ટીલ્ડા" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "ટીલ્ડા" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "બરાબર" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "બરાબર" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "બરાબર" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "ઊભી લીટી" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "દબાયેલ નથી" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "પસંદ કરાયેલ નથી" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "જગ્યા" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "પસંદ નહિં થયેલ" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "પસંદ નહિં થયેલ" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "બરાબર" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "ડેશ" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "જમણી મેટા" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "ડાબી tab" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "પાનું નીચે" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "પ્રશ્ન" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "ટ્રી" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "ટ્રી" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ડાયલ" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "ચિત્ર" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "આંતરિક ચોકઠું" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "જમણું shift" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "વિભાજક" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "ડિરેક્ટરી તકતી" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "કરતાં ઓછુ" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "કરતાં મોટું" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "ઊભી લીટી" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "ડાબું alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "જમણું alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "તળિયું (_B):" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "સફેદ જગ્યા" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "સફેદ જગ્યા" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "સફેદ જગ્યા" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "નવીલીટી" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "ઊભી લીટી" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "કાર્યક્રમ" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "કોરું" - -#: src/cthulhu/messages.py:51 -#, fuzzy -msgid "bold" -msgstr "colhdr" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "બોલી સક્રિય કરાયેલ." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ચિહ્ન" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "કંઈ નહિં" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "ફેરવો" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, fuzzy, python-format -msgid "Cell %s" -msgstr "ખાનું" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "પસંદ કરાયેલ" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "પસંદ કરાયેલ નથી" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "પસંદ નહિં થયેલ" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "-?, --help આ મદદ સંદેશો બતાવે છે" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -#, fuzzy -msgid "Set up user preferences (text version)" -msgstr "-t, --text-setup વપરાશકર્તા પસંદગીઓ સુયોજિત કરે છે (લખાણ આવૃત્તિ)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "-t, --text-setup વપરાશકર્તા પસંદગીઓ સુયોજિત કરે છે (લખાણ આવૃત્તિ)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "https://groups.io/g/stormux ને ભૂલોનો અહેવાલ આપો." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "auto" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "ઝડપી." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, fuzzy, python-format -msgid "Message from chat room %s" -msgstr "સંવાદ કક્ષમાંથી સંદેશો " - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "સંવાદ કક્ષ નામ બોલશો નહિં." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "સંવાદ કક્ષ નામ બોલે છે." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "પસંદ કરાયેલ" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "seprtr" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "પ્રશ્ન" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "કોષ્ટક" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "કોઈ અવાજો ઉપલબ્ધ નથી.\n" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "પસંદ કરાયેલ નથી" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "કોઈ અવાજો ઉપલબ્ધ નથી.\n" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "વર્તમાન દસ્તાવેજ પસંદ થયેલ છે" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "વર્તમાન દસ્તાવેજ પસંદ થયેલ છે" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "કર્સર સ્થાનમાંથી પસંદ કરાયેલ દસ્તાવેજ" - -#: src/cthulhu/messages.py:554 -#, fuzzy -msgid "document unselected from cursor position" -msgstr "કર્સર સ્થાનમાંથી પસંદ કરાયેલ દસ્તાવેજ" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "કર્સર સ્થાને પસંદ કરાયેલ દસ્તાવેજ" - -#: src/cthulhu/messages.py:566 -#, fuzzy -msgid "document unselected to cursor position" -msgstr "કર્સર સ્થાને પસંદ કરાયેલ દસ્તાવેજ" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -#, fuzzy -msgid "Dynamic column header cleared." -msgstr "સ્તંભ હેડર" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ખાલી" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "સપાટ રીવ્યુ સ્થિતિમાં દાખલ થાય અને બહાર નીકળે." - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "સપાટ રીવ્યુ સ્થિતિમાં દાખલ થાય અને બહાર નીકળે." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "સપાટ રીવ્યુને વર્તમાન શબ્દની ઉપરના શબ્દ પર ખસેડે છે." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -#, fuzzy -msgid "has formula" -msgstr " ને સૂત્ર છે" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "સંવાદ" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "પોપઅપ મેનુ" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, fuzzy, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "સુયોજન પૂર્ણ. ચાલુ રાખવા માટે Return દબાવો." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -#, fuzzy -msgid "Key binding deleted. Press enter to confirm." -msgstr "સુયોજન પૂર્ણ. ચાલુ રાખવા માટે Return દબાવો." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "કંઈ નહિં" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "કેન્દ્રિય" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "શબ્દ અનુસાર ઈકો સક્રિય કરો (_w)" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "પાસવર્ડ" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "સફેદ જગ્યા" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "સમપ્રમાણ" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "ઊભી લીટી" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "અને" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "નવીલીટી" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "રુટ તકતી" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "રુટ તકતી" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "રુટ તકતી" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "જગ્યા" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "નીચે લીટી" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "કોષ્ટક" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "અસુલભ" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "કોષ્ટક" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "હાંસિયાથી અંતર અને ગોઠવણી બોલો (_i)" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "શબ્દ અનુસાર ઈકો સક્રિય કરો (_w)" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "હાંસિયાથી અંતર અને ગોઠવણી બોલો (_i)" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "શીખવાની સ્થિતિ. બહાર નીકળવા માટે એસ્કેપ દબાવો." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "એનીમેશન" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "કર્સર સ્થાન નીચે પસંદ કરાયેલ વાક્ય" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "કર્સર સ્થાન ઉપર પસંદ કરાયેલ વાક્ય" - -#: src/cthulhu/messages.py:1484 -#, fuzzy -msgid "line unselected down from cursor position" -msgstr "કર્સર સ્થાન નીચે પસંદ કરાયેલ વાક્ય" - -#: src/cthulhu/messages.py:1491 -#, fuzzy -msgid "line unselected up from cursor position" -msgstr "કર્સર સ્થાન ઉપર પસંદ કરાયેલ વાક્ય" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "શીખવાની સ્થિતિમાંથી બહાર નીકળી રહ્યા છીએ." - -#: src/cthulhu/messages.py:1505 -#, fuzzy -msgid "line selected from start to previous cursor position" -msgstr "કર્સર સ્થાન ઉપર પસંદ કરાયેલ વાક્ય" - -#: src/cthulhu/messages.py:1511 -#, fuzzy -msgid "line selected to end from previous cursor position" -msgstr "કર્સર સ્થાન નીચે પસંદ કરાયેલ વાક્ય" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "કડી" - -#: src/cthulhu/messages.py:1518 -#, fuzzy -msgid "same page" -msgstr "પાનું" - -#: src/cthulhu/messages.py:1522 -#, fuzzy -msgid "same site" -msgstr "મેનુ વસ્તુ" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, fuzzy, python-format -msgid "%s link" -msgstr "કડી" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "કડી" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "ટ્રી સ્તર %d" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr " બંધ" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr " ચાલુ" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "ખોટી જોડણીવાળો શબ્દ:" - -#: src/cthulhu/messages.py:1682 -#, fuzzy, python-format -msgid "Misspelled word: %s" -msgstr "ખોટી જોડણીવાળા શબ્દો: " - -#: src/cthulhu/messages.py:1687 -#, fuzzy, python-format -msgid "Context is %s" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "વિસ્તારક" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "વિસ્તારક" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "ટકા" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "સપાટ રીવ્યુને પહેલાંની વસ્તુ અથવા શબ્દ પર ખસેડે છે." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "ટ્રી સ્તર %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "કાર્યક્રમ" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "કોઈ ફોકસ નથી" - -#: src/cthulhu/messages.py:1867 -#, fuzzy -msgid "No application has focus." -msgstr "કાર્યક્રમ" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "ટોગલ બટન" - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "ચકાસણી બોક્સ" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "કમ્બો બોક્સ" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "આંતરિક ચોકઠું" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "યાદી વસ્તુ" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "ફકરો" - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "રેડિયો બટન" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "ફકરો" - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "ટ્રી કોષ્ટક" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "પસંદ કરાયેલ નથી" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "કોઈ અવાજો ઉપલબ્ધ નથી.\n" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "હાંસિયાથી અંતર અને ગોઠવણી બોલો (_i)" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "તળિયું (_B):" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "ટોચ (_T):" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "પાસવર્ડ" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -#, fuzzy -msgid "off" -msgstr " બંધ" - -#: src/cthulhu/messages.py:2051 -#, fuzzy -msgid "on" -msgstr " ચાલુ" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "કર્સર સ્થાનમાંથી પસંદ થયેલ પાનું" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "કર્સર સ્થાને પસંદ થયેલ પાનું" - -#: src/cthulhu/messages.py:2089 -#, fuzzy -msgid "page unselected from cursor position" -msgstr "કર્સર સ્થાનમાંથી પસંદ થયેલ પાનું" - -#: src/cthulhu/messages.py:2095 -#, fuzzy -msgid "page unselected to cursor position" -msgstr "કર્સર સ્થાને પસંદ થયેલ પાનું" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "કર્સર સ્થાનમાંથી પસંદ થયેલ પાનું" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "કર્સર સ્થાનમાંથી પસંદ થયેલ પાનું" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "કર્સર સ્થાનમાંથી પસંદ થયેલ પાનું" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "કર્સર સ્થાનમાંથી પસંદ થયેલ પાનું" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, fuzzy, python-format -msgid "Progress bar %d." -msgstr "પ્રગતિદર્શક પટ્ટી" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "બધા (_A)" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "વિરામ સ્તર" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "કંઈ નહિં" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -#, fuzzy -msgid "Search complete." -msgstr "જોડણી ચકાસણી સમાપ્ત." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu વપરાશકર્તા સુયોજનો પુનઃલવાયેલ." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr " સંદર્ભ આ છે " - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "જરૂરી અવાજ પસંદ કરો:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "પસંદ નહિં થયેલ" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "બોલી નિષ્ક્રિય કરાયેલ." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "બોલી સક્રિય કરાયેલ." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "ઝડપી." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "ધીમું." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "ઊંચુ." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "નીચું." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "ઝડપી." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "દર (_R):" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "અવાજ (_l):" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "બોલી નિષ્ક્રિય કરાયેલ." - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "બોલી નિષ્ક્રિય કરાયેલ." - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "કોઈ સર્વરો ઉપલબ્ધ નથી.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "કોઈ અવાજો ઉપલબ્ધ નથી.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "બોલી સક્રિય કરાયેલ." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "બોલી વપરાશે નહિં.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " ટપકું ટપકું ટપકું" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Cthulhu પસંદગીઓ" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "બોલી સક્રિય કરાયેલ." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "બોલી ઉપલબ્ધ નથી." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "પરિસ્થિતિ પટ્ટી" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "કોષ્ટક" - -#: src/cthulhu/messages.py:2389 -#, fuzzy -msgid "Speak cell" -msgstr "બોલો " - -#: src/cthulhu/messages.py:2394 -#, fuzzy -msgid "Speak row" -msgstr "બોલો " - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -#, fuzzy -msgid "Not in a table." -msgstr "કોઈ અવાજો ઉપલબ્ધ નથી.\n" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ColumnHeader" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, fuzzy, python-format -msgid "column %d" -msgstr "સ્તંભ હેડર" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "પસંદ નહિં થયેલ" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "પસંદ નહિં થયેલ" - -#: src/cthulhu/messages.py:2458 -#, fuzzy, python-format -msgid "row %d" -msgstr "હરોળ" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "પસંદ કરાયેલ" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -#, fuzzy -msgid "Row inserted." -msgstr "seprtr" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "સપાટ રીવ્યુને લીટીના અંતે ખસેડે છે." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "પસંદ કરાયેલ નથી" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "પસંદ નહિં થયેલ" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "પસંદ કરાયેલ" - -#: src/cthulhu/messages.py:2521 -#, fuzzy -msgctxt "text" -msgid "unselected" -msgstr "પસંદ નહિં થયેલ" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu પસંદગીઓ" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "સફેદ જગ્યા" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -#, fuzzy -msgid "0 items" -msgstr "યાદી વસ્તુ" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "સ્તંભ હેડર" -msgstr[1] "સ્તંભ હેડર" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "સંવાદ" -msgstr[1] "સંવાદ" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, fuzzy, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "frm" -msgstr[1] "frm" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "યાદી વસ્તુ" -msgstr[1] "યાદી વસ્તુ" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "યાદી વસ્તુ" -msgstr[1] "યાદી વસ્તુ" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "યાદી વસ્તુ" -msgstr[1] "યાદી વસ્તુ" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "યાદી વસ્તુ" -msgstr[1] "યાદી વસ્તુ" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "ટકા" -msgstr[1] "ટકા" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "પિક્સેલો" -msgstr[1] "પિક્સેલો" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, fuzzy, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "પસંદ કરાયેલ નથી" -msgstr[1] "પસંદ કરાયેલ નથી" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "જગ્યા" -msgstr[1] "જગ્યા" - -#: src/cthulhu/messages.py:2813 -#, fuzzy, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "ટેબ" -msgstr[1] "ટેબ" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "કોષ્ટક" -msgstr[1] "કોષ્ટક" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "સેમીકોલન" -msgstr[1] "સેમીકોલન" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "ટોગલ બટન" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, fuzzy, python-format -msgid "LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ટ્રી સ્તર %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "પ્રશ્ન" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "કમ્બો બોક્સ" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "h t m l સમાવનાર" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "પાસવર્ડ" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "કોલન" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "નવીલીટી" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "ડિરેક્ટરી તકતી" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "ફકરો" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "પાસવર્ડ" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "ડિરેક્ટરી તકતી" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "ટેબ યાદી" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "ક્વોટ" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "h t m l સમાવનાર" - -#: src/cthulhu/object_properties.py:344 -#, fuzzy, python-format -msgid "h%d" -msgstr "hdr" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "સમપ્રમાણ" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "ઊભી લીટી" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "સમપ્રમાણ" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "ઊભી લીટી" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "સમપ્રમાણ" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "ઊભી લીટી" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -#, fuzzy -msgid "Icon panel" -msgstr "વિકલ્પ તકતી" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "h t m l સમાવનાર" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "એનીમેશન" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "h t m l સમાવનાર" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "એનીમેશન" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "કડી" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "ફેરવો બટન" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "સંકુચિત" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "વિસ્તૃત" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -#, fuzzy -msgid "horizontal" -msgstr "સમપ્રમાણ" - -#: src/cthulhu/object_properties.py:519 -#, fuzzy -msgid "vertical" -msgstr "ઊભી લીટી" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "ચકાસાયેલ" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "ચકાસાયેલ નથી" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr " ચાલુ" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr " બંધ" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "ચકાસાયેલ નથી" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "દબાયેલ" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "દબાયેલ નથી" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "પસંદ કરાયેલ નથી" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "પસંદ કરાયેલ" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "પસંદ કરાયેલ નથી" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "પસંદ કરાયેલ નથી" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "અસુલભ" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "અસુલભ" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "રાખોડી" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "પસંદ નહિં થયેલ" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "અયોગ્ય" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "અયોગ્ય" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "ફેરવો" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "ફેરવો" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "અયોગ્ય" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -#, fuzzy -msgid "Find" -msgstr "વિન્ડો" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "Cthulhu સ્ક્રીન વાંચક અને વિસ્તૃતકારક" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "વિન્ડો" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -#, fuzzy -msgid "Search for:" -msgstr "વિભાજક" - -#: src/cthulhu/cthulhu-find.ui:166 -#, fuzzy -msgid "_Top of window" -msgstr "વિન્ડો" - -#: src/cthulhu/cthulhu-find.ui:175 -#, fuzzy -msgid "Top of window" -msgstr "વિન્ડો" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "ડિરેક્ટરી તકતી" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "OptionPane" - -#: src/cthulhu/cthulhu-setup.ui:43 -#, fuzzy -msgid "Default" -msgstr "મૂળભૂત" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "ઉપરનો કિસ્સો" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "હાયપરલીંક" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "કાર્યક્રમ" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "વિન્ડો" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu પસંદગીઓ" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -#, fuzzy -msgid "_Laptop" -msgstr "app" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "બોલો " - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "બ્રેઈલી" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "કાર્યક્રમ" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "પ્રગતિદર્શક પટ્ટી" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "અવાજ (_l):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "પીચ (_t):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "દર (_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "વ્યક્તિ (_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "બોલી સિન્થેસાઈઝર (_z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "બોલી સિસ્ટમ (_s):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "અવાજ સુયોજનો (_V):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "અવાજ સુયોજનો (_V):" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "અવાજ સુયોજનો (_V):" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "બોલી સક્રિય કરો (_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "વર્બોઝ (_b)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "વર્બોઝીટી" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "બધા (_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "વિરામ સ્તર" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "હાંસિયાથી અંતર અને ગોઠવણી બોલો (_i)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "પ્રગતિદર્શક પટ્ટી" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "બોલો " - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "બોલી" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "બ્રેઈલી આધાર સક્રિય કરો (_s)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "ટૂંકાવેલ ભૂમિકા નામો (_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "શબ્દ અનુસાર ઈકો સક્રિય કરો (_w)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "વધુ વિકલ્પો દર્શાવો" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "કંઈ નહિં (_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "હાયપરલીંક" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "વિસ્તારક સક્રિય કરો (_m)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "બ્રેઈલી" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "કી ઈકો સક્રિય કરો (_k)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "સુધારક કીઓ સક્રિય કરો (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "બોલી સક્રિય કરો (_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "સુધારક કીઓ સક્રિય કરો (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "ક્રિયા કીઓ સક્રિય કરો (_t)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -#, fuzzy -msgid "Enable _navigation keys" -msgstr "વિધેય કીઓ સક્રિય કરો (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "શબ્દ અનુસાર ઈકો સક્રિય કરો (_w)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "શબ્દ અનુસાર ઈકો સક્રિય કરો (_w)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "કી ઈકો" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "સુધારક કીઓ સક્રિય કરો (_m)" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "વિરામ સ્તર" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -#, fuzzy -msgid "_Delete" -msgstr "પસંદ કરાયેલ" - -#: src/cthulhu/cthulhu-setup.ui:3204 -#, fuzzy -msgid "Pronunciation" -msgstr "એનીમેશન" - -#: src/cthulhu/cthulhu-setup.ui:3243 -#, fuzzy -msgid "_Speak all" -msgstr "બોલો " - -#: src/cthulhu/cthulhu-setup.ui:3257 -#, fuzzy -msgid "Speak _none" -msgstr "બોલો " - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "બ્રેઈલી" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "મદદનીશ" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "હરોળ" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "મદદનીશ" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "અને" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "માપદંડ અવયવ (_f):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "ડિરેક્ટરી તકતી" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "કોષ્ટક" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -#, fuzzy -msgctxt "textattr" -msgid "font effect" -msgstr "પસંદ કરાયેલ નથી" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -#, fuzzy -msgctxt "textattr" -msgid "invisible" -msgstr "અસુલભ" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "ડાબો કૌંસ" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "ફકરો" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "જમણો કૌંસ" - -#: src/cthulhu/text_attribute_names.py:221 -#, fuzzy -msgctxt "textattr" -msgid "rise" -msgstr "સંક્ષિપ્ત (_f)" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "cale" - -#: src/cthulhu/text_attribute_names.py:234 -#, fuzzy -msgctxt "textattr" -msgid "size" -msgstr "માપ (_z):" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -#, fuzzy -msgctxt "textattr" -msgid "style" -msgstr "ટીલ્ડા" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "નવીલીટી" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "ઊભી લીટી" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "જમણું (_R):" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -#, fuzzy -msgctxt "textattr" -msgid "writing mode" -msgstr "શીખવાની સ્થિતિમાંથી બહાર નીકળી રહ્યા છીએ." - -#: src/cthulhu/text_attribute_names.py:341 -#, fuzzy -msgctxt "textattr" -msgid "true" -msgstr "ટ્રી" - -#: src/cthulhu/text_attribute_names.py:349 -#, fuzzy -msgctxt "textattr" -msgid "false" -msgstr "ઝડપી." - -#: src/cthulhu/text_attribute_names.py:358 -#, fuzzy -msgctxt "textattr" -msgid "none" -msgstr "કંઈ નહિં" - -#: src/cthulhu/text_attribute_names.py:365 -#, fuzzy -msgctxt "textattr" -msgid "engrave" -msgstr "રાખોડી" - -#: src/cthulhu/text_attribute_names.py:372 -#, fuzzy -msgctxt "textattr" -msgid "emboss" -msgstr "emb" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "નવીલીટી" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "કડી" - -#: src/cthulhu/text_attribute_names.py:407 -#, fuzzy -msgctxt "textattr" -msgid "black" -msgstr "કોરું" - -#: src/cthulhu/text_attribute_names.py:414 -#, fuzzy -msgctxt "textattr" -msgid "single" -msgstr "ફેરવો" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "હરોળ" - -#: src/cthulhu/text_attribute_names.py:435 -#, fuzzy -msgctxt "textattr" -msgid "char" -msgstr "કેરેટ" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "પાસવર્ડ" - -#: src/cthulhu/text_attribute_names.py:452 -#, fuzzy -msgctxt "textattr" -msgid "word char" -msgstr "કેરેટ" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "trtbl" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "ડાબું alt" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "જમણું alt" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "કેન્દ્રિય" - -#: src/cthulhu/text_attribute_names.py:493 -#, fuzzy -msgctxt "textattr" -msgid "no justification" -msgstr "હાંસિયાથી અંતર અને ગોઠવણી બોલો (_i)" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "ભરનાર" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -#, fuzzy -msgctxt "textattr" -msgid "extra condensed" -msgstr "વિસ્તૃત" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "સેમીકોલન" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "વિસ્તૃત" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "વિસ્તૃત" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "વિસ્તૃત" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "વિસ્તૃત" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -#, fuzzy -msgctxt "textattr" -msgid "italic" -msgstr "અયોગ્ય" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "મૂળભૂત" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "લખાણ" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "હેડર" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "નવીલીટી" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -#, fuzzy -msgctxt "textattr" -msgid "super" -msgstr "જગ્યા" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "tip" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "લખાણ" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "તળિયું (_B):" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -#, fuzzy -msgctxt "textattr" -msgid "lr-tb" -msgstr "ચેતવણી" - -#: src/cthulhu/text_attribute_names.py:684 -#, fuzzy -msgctxt "textattr" -msgid "rl-tb" -msgstr "trtbl" - -#: src/cthulhu/text_attribute_names.py:691 -#, fuzzy -msgctxt "textattr" -msgid "tb-rl" -msgstr "tbl" - -#: src/cthulhu/text_attribute_names.py:698 -#, fuzzy -msgctxt "textattr" -msgid "tb-lr" -msgstr "tbl" - -#: src/cthulhu/text_attribute_names.py:705 -#, fuzzy -msgctxt "textattr" -msgid "bt-rl" -msgstr "trtbl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "ટેબ" - -#: src/cthulhu/text_attribute_names.py:738 -#, fuzzy -msgctxt "textattr" -msgid "solid" -msgstr "સરકપટ્ટી" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "ફેરવો" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -#, fuzzy -msgid "To get to the system menus press the alt+f1 key." -msgstr "શીખવાની સ્થિતિમાંથી બહાર નીકળવા માટે, એસ્કેપ કી દબાવો." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/he.po b/po/he.po deleted file mode 100644 index bb0dd8c..0000000 --- a/po/he.po +++ /dev/null @@ -1,9324 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: \n" -"Last-Translator: Yaron Shahrabani \n" -"Language-Team: \n" -"Language: he\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n==2 ? 1 : n>10 && n%10==0 ? " -"2 : 3);\n" -"X-Generator: Poedit 3.4.1\n" - -msgid "Cthulhu Screen Reader" -msgstr "מקריא המסך Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "מסך;קורא;נגישות;דיבור;ברייל;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "טופס" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "כתרת" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "תמנ" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "מסגר" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "תות" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "חלשכב" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "קשר" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "רשמ" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "פרטאחר" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "תפר" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "סרתפר" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "פרטתפרט" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "צ'כית דרגה 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "ספרדית דרגה 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "צרפתית קנדית דרגה 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "צרפתית דרגה 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "לטבית דרגה 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "הולנדית דרגה 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "נורבגית דרגה 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "נורבגית דרגה 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "נורבגית דרגה 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "נורבגית דרגה 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "פולנית דרגה 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "פורטוגזית דרגה 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "שוודית דרגה 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "ערבית דרגה 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "וולשית דרגה 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "וולשית דרגה 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "גרמנית דרגה 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "גרמנית דרגה 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "גרמנית דרגה 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "אנגלית בריטית דרגה 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "אנגלית בריטית דרגה 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "אנגלית אמריקנית דרגה 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "אנגלית אמריקנית דרגה 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "צרפתית קנדית דרגה 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "צרפתית דרגה 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "יוונית דרגה 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "הינדית דרגה 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "מחשב 8 נקודות הונגרי" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "הונגרית דרגה 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "הונגרית דרגה 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "איטלקית דרגה 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "הולנדית בלגית דרגה 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "רווח" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "שורה חדשה" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "טאב" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "סימן קריאה" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "ציטטה" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "מספר" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "דולר" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "אחוז" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "אמפרסנד" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "אפוסטרוף" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "סוגריים שמאליים" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "סוגריים ימניים" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "כוכבית" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "פלוס" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "פסיק" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "פיסוק, קו מפרי" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "נקודה" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "לוכסן" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "נקודתיים" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "נקודה פסיק" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "קטן מ" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "שווה" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "גדול מ" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "סימן שאלה" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "כרוכית" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "סוגריים מרובעים שמאליים" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "לוכסן הפוך" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "סוגריים מרובעים ימניים" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "קו תחתי" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "הטעמה משנית" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "סוגריים מסולסלים שמאליים" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "קו אנכי" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "סוגריים מסולסלים ימניים" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "טילדה" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "רווח קשיח" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "סימן קריאה הפוך" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "סנטים" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "פאונדים" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "סימן מטבע" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "ין" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "קו שבור" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "סעיף" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "דיאריסיס" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "זכויות יוצרים" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "‫a בכתב עילי" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "לא לוגי" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "מקף רך" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "סימן רשום" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "מקרון" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "מעלות" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "פלוס מינוס" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "שתיים בכתב עילי" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "שלוש בכתב עילי" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "הטעמה עילית" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "מו" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "סמן פסקה" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "נקודה אמצעית" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "סדיליה" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "אחד בכתב עילי" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "סודר" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "רבע" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "חצי" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "שלושה רבעים" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "סימן שאלה בפוך" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a הטעמה עילית" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A הטעמה משנית" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A הטעמה עילית" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A גג" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A טילדה" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A אומלאוט" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A טבעת" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C סדיליה" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E הטעמה משנית" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E הטעמה עילית" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E גג" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E אומלאוט" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I הטעמה משנית" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I הטעמה עילית" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I גג" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I אומלאוט" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "אד׳ (גדולה)" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N טילדה" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O הטעמה עילית" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O הטעמה משנית" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O גג" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O טילדה" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O אומלאוט" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "כפל" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "o מלוכסן" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U הטעמה עילית" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U הטעמה משנית" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U גג" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U אומלאוט" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y הטעמה עילית" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "ת׳ורן (גדולה)" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a טילדה" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a אומלאוט" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a טבעת" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c סדיליה" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e הטעמה משנית" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "a הטעמה עילית" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e גג" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e אומלאוט" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i הטעמה משנית" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i הטעמה עילית" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i גג" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i אומלאוט" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "אד׳ (קטנה)" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n טילדה" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o הטעמה עילית" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o הטעמה משנית" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o גג" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o טילדה" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o אומלאוט" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "לחלק ב־" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o מלוכסן" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "ת׳ורן (קטנה)" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u הטעמה משנית" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u הטעמה עילית" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u גג" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u אומלאוט" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y הטעמה עילית" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y אומלאוט" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y אומלאוט" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "פלורין" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "קו מפריד" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "מירכה שמאלית בודדת" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "מירכה ימנית בודדת" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "מירכה תחתונה בודדת" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "מירכאות כפולות שמאליות" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "מירכאות כפולות ימניות" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "מירכאות כפולות תחתונות" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "פגיון" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "פגיון כפול" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "תבליט" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "תבליט משולש" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "למייל" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "תג" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "תגיים" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "שלושה תגים" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "אירו" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "סימן מסחר" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "סימון חיובי" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "סימון עבה חיובי" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "תבליט בצורת איקס" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "אפס בכתב עילי" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "ארבע בכתב עילי" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "חמש בכתב עילי" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "שש בכתב עילי" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "שבע בכתב עילי" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "שמונה בכתב עילי" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "תשע בכתב עילי" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "פלוס בכתב עילי" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "מינוס בכתב עילי" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "שווה בכתב עילי" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "סוגריים שמאליים בכתב עילי" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "סוגריים ימניים בכתב עילי" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n בכתב עילי" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "0 בכתב תחתון" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "1 בכתב תחתון" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "2 בכתב תחתון" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "3 בכתב תחתון" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "4 בכתב תחתון" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "5 בכתב תחתון" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "6 בכתב תחתון" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "7 בכתב תחתון" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "8 בכתב תחתון" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "9 בכתב תחתון" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "פלוס בכתב תחתון" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "מינוס בכתב תחתון" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "שווה בכתב תחתון" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "סוגריים שמאליים בכתב תחתון" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "סוגריים ימניים בכתב תחתון" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "ריבוע שחור" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "יהלום שחור" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "עובר לתו הבא." - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "הפניית הסמן לפריט הנוכחי" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "ביצוע לחיצת עכבר שמאלית על פריט משטח הסקירה." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "ביצוע לחיצת עכבר ימנית על פריט משטח הסקירה." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "הקראת המסמך כולו" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "אומר את שורת משטח הסקירה הנוכחית." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "מבצע את פקודת איפה אני הבסיסית." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "מבצע את פקודת איפה אני בצורה מפורטת." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "הקראת הבחירה הנוכחית" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "הקראת פרטי קישור" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "הצגת כפתור ברירת המחדל" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "הצגת שורת המצב" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "הצגת שורת הכותרת" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "פתיחת חלונית האיתור" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "הצג רשימת פעולות" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "חיפוש אחר מופע המחרוזת הבא" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "חיפוש אחר מופע המחרוזת הקודם" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "כניסה ויציאה ממצב סקירה שטוחה" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "מעביר את משטח הסקירה למיקום הסופי." - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "העברת סקירה שטוחה למקום הבית" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "העברת סקירה שטוחה למקום הסיום" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "העברת הסקירה השטוחה לתחילת השורה הקודמת" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "הקראת שורת הסקירה השטוחה הנוכחית" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "איות שורת הסקירה השטוחה הנוכחית" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "איית באופן פונטי את משטח הסקירה הנוכחי." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "מעביר את משטח הסקירה לתחילת השורה הבאה." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "מעביר את משטח הסקירה למילה או לפריט הקודם." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "אומר את הפריט או המילה שנמצאים במשטח הסקירה." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "מאיית את הפריט או המילה שנמצאים במשטח הסקירה." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "מאיית באופן פונטי את הפריט או המילה שנמצאים במשטח הסקירה." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "מעביר את משטח הסקירה לפריט או למילה הבאה." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "מעביר את משטח הסקירה למילה מעל המילה הנוכחית." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "אומר את האובייקט הנמצא כרגע במשטח הסקירה." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "מעביר את משטח הסקירה למילה מתחת למילה הנוכחית." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "מעביר את משטח הסקירה לתו הקודם." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "אומר את התו הנמצא במשטח הסקירה." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "אומר באופן פונטי את התו הנמצא במשטח הסקירה" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "אומר את התו הנמצא במשטח הסקירה." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "מעביר את משטח הסקירה לתו הבא." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "מעביר את משטח הסקירה לסוף השורה." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "מעביר את משטח הסקירה לאזור התחתון משמאל." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "אומר את הפריט או המילה שנמצאים במשטח הסקירה." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "אומר את הפריט או המילה שנמצאים במשטח הסקירה." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "מעביר את משטח הסקירה למיקום הסופי." - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "מחליף בין לקרוא פשוט תא מהטבלה הנוכחית או את השורה השלמה." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "הקראת המאפיינים שקשורים לתו הטקסט הנוכחי" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "הרחב את תצוגת הברייל בצד ימין." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "הרחב את תצוגת הברייל בצד ימין." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "חזרה לעצם עם מיקוד מקלדת" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "_הפעל ברייל מקוצר" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "עיבוד מפתח ניווט סמן" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "סימון תחילת בחירת הטקסט" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "סימון סוף בחירת הטקסט" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "כניסה למצב למידה. לחיצה על escape תצא ממצב למידה" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "הפחתת קצב הדיבור" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "הגברת קצב הדיבור" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "הגבהת צליל קצב הדיבור" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "הנמכת צליל קצב הדיבור" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "הגברת קצב הדיבור" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "הפחתת קצב הדיבור" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "בחר את הגדרת הדיבור הקודמת" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "בחר את הגדרת הדיבור הבאה" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "הקטן את הגדרת הדיבור הנוכחית" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "הגדל את הגדרת הדיבור הנוכחית" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "שמור הגדרות דיבור" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "החלפת מצב השתקת הקראה" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "החלפת רמת פירוט הקראה" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "החלף מצב שינה" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "יציאה ממקריא המסך" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "הצגת חלונית הגדרות ההעדפה" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "הצגת חלונית הגדרות ההעדפה של היישום" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "אמור את ההזחה ואת הכיוון." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "החלפת סגנון המספר המוקרא" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "מעבר בלולאה למעבד הדיבור הבא" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "סימון המקום שלי בהתחשב במקום הנוכחי" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "מעבר למיקום הקודם בסימניות" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "מעבר לסימנייה" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "מעבר למיקום הבא בסימניות" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "הוספת סימנייה" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "שמירת סימניות" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "הצגת השעה הנוכחית" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "הצגת התאריך הנוכחי" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "הצגת גודל ומקום העצם הנוכחי" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "העברת הפקודה הבאה קדימה ליישום הנוכחי" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "הקראה ויצירת ברייל של ההודעה האחרונה בחדר הצ׳אט" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "לא להודיעה כאשר החברים שלך מקלידים." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "קו שמאל" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "קו ימין" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "שורה למעלה" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "שורה למטה" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "הקפאה" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "צד שמאל למעלה" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "משמאל למטה" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "מיקום הסמן" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "שש נקודות" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "הזזת סמן" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "התחלת העתקה" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "העתקת שורה" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "הצגת הודעת ההתראה הבאה" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "מעבר לתו הבא" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "מעבר לתו הקודם" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "מעבר למילה הבאה" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "מעבר למילה הקודמת" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "מעבר לשורה הבאה" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "מעבר לשורה הקודמת" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "מעבר לראש הקובץ" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "מעבר לסוף הקובץ" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "מעבר לתחילת השורה" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "מעבר לסוף השורה" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "מעבר לעצם הבא" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "מעבר לעצם הקודם" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "מעקב אחר אזורים חיים" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "הצגת תוכן שורת הקלט" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "הפעלת מקשי ניווט מובנים" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "מעבר לציטטה הקודמת" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "מעבר לציטטה הבאה" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "הצגת רשימת ציטטות" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "מעבר לכפתור קודם" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "מעבר לכפתור הבא" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "הצגת רשימת כפתורים" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "מעבר לתיבת הסימון הקודמת" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "מעבר לתיבת הסימון הבאה" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "הצגת רשימת תיבות סימון" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "מעבר ללחיץ הקודם" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "מעבר ללחיץ הבא" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "הצגת רשימת פריטים לחיצים" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "מעבר לתיבה המשולבת הקודמת" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "מעבר לתיבה המשולבת הבאה" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "מעבר לתחילת הפריט המכיל" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "מעבר לסוף העצם המכיל" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "הצגת רשימת תיבות בחירה" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "מעבר לרשומה הקודמת" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "מעבר לרשומה הבאה" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "הצגת רשימת רשומות" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "מעבר לשדה הקודם בטופס" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "מעבר לשדה הבא בטופס" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "הצגת רשימות שדות טופס" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "מעבר לכותרת הקודמת" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "מעבר לכותרת הבאה" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "הצגת רשימת כותרות" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "מעבר לכותרת הקודמת ברמה %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "מעבר לכותרת הבאה ברמה %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "הצגת רשימת כותרות ברמה %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "מעבר למסגרת הפנימית הקודמת" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "מעבר למסגרת הפנימית הבאה" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "הצגת רשימת מסגרות פנימיות" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "מעבר לתמונה הקודמת" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "מעבר לתמונה הבאה" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "הצגת רשימת תמונות" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "עובר לעוגן הקודם." - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "עובר לעוגן הבא." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "מעבר לעצם הגדול הקודם" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "מעבר לעצם הגדול הבא" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "הצגת רשימה של עצמים גדולים" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "מעבר לקישור הקודם" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "מעבר לקישור הבא" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "הצגת רשימת קישורים" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "מעבר לרשימה הקודמת" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "מעבר לרשימה הבאה" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "הצגת רשימת רשימות" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "מעבר לפריט הקודם ברשימה" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "מעבר לפריט הבא ברשימה" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "הצגת רשימת פריטי רשימה" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "מעבר לאזור החי הקודם" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "מעבר לאזור החי הבא" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "מעבר לאזור האחרון שהכריז הכרזה" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "מעבר להורה העצם שהניווט ממוקד עליו." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "מעבר לצאצא הראשון של העצם עם מיקוד הנווט." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "עבור לאח הבא של האובייקט עם מיקוד הניווט." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "עבור לאח הקודם של האובייקט עם מיקוד הניווט." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "מחליף מצב ניווט עצמים פשוט." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "לעבור לפסקה הקודמת" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "לעבור לפסקה הבאה" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "הצגת רשימת פסקאות" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "לעבור ללחצן הבחירה הקודם" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "לעבור ללחצן הבחירה הבא" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "להציג רשימה של כפתורי בחירה" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "לעבור למפריד הקודם" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "לעבור למפריד הבא" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "לעבור לטבלה הקודמת" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "לעבור לטבלה הבאה" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "הצגת רשימת טבלאות" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "לרדת תא אחד למטה" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "לעבור לתא הראשון בטבלה" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "לעבור לתא האחרון בטבלה" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "לעבור תא אחד שמאלה" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "לעבור תא אחד ימינה" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "לעלות תא אחד למעלה" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "החלפת מצב פריסה" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "החלפה בין מצב עיון למצב מיקוד" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "להפעיל מצב מיקוד דביק" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "הפעלת מצב דפדוף דביק" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "לעבור לקישור הקודם שטרם ביקרת בו" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "לעבור לקישור הבא שטרם ביקרת בו" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "להציג רשימה של קישורים שטרם ביקרת בהם" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "מעבר לקישור הקודם שכבר ביקרת בו" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "מעבר לקישור הבא שכבר ביקרת בו" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "הצגת רשימת קישורים בהם ביקרת" - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "ספוג כחול" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "לבן עתיק" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "בז׳" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "שחור" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "חום" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "ספוג כחול" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "שארטרוז" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "שוקולד" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "כחול כהה" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "ציאן כהה" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "אפור כהה" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "ירוק כהה" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "חאקי כהה" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "מג׳נטה כהה" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "ירוק זית כהה" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "כתום כהה" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "אדום כהה" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "ספוג ירוק" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "ספוג כחול" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "טורקיז כהה" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "ורוד עמוק" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "אפור מעומעם" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "לבן פרחוני" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "ירוק יער" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "פוקסיה" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "זהב" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "אפור" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "ירוק" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "צהוב ירוק" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "ורוד עז" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "אדום אינדיאני" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "שנהב" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "חאקי" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "לבנדר" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "ירוק מדשאה" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "כחול בהיר" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "ציאן בהיר" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "אפור בהיר" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "ירוק בהיר" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "ורוד בהיר" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "סלמון בהיר" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "כחול שמיים בהיר" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "צהוב בהיר" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "ליים" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "ירוק ליים" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "דו־קווי" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "מג׳נטה" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "ספוג כחול" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "קרם מנטה" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "זית" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "כתום" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "כתום אדום" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "ירוק חיוור" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "טורקיז חיוור" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "ורוד" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "שזיף" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "סגול" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "אדום" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "כחול מלכותי" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "ירוק ים" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "ספוג כחול" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "כחול מתכתי" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "עגבנייה" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "טורקיז" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "חיטה" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "לבן" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "עשן לבן" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "צהוב" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "צהוב ירוק" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "ה_פעלה" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "מצב מיקוד אוטומטי במהלך ניווט מבני" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "מצב מיקוד אוטומטית במהלך ניווט סמן" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "מצב מיקוד אוטומטית במהלך ניווט טבעי" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "נקודה _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "נקודה _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "נקודות 7 _ו־8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_ביטול" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "ל_קפוץ אל" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_אישור" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "סמל" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "ללא" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "הקראה" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "להודיע כאשר _חברים שלך מקלידים" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "דבר הודעות מ" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "כל הערו_צים" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "ערוץ רק אם החלון שלו _פעיל" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_דבר את שם החדר" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "הפעלת מצב פריסה לתוכן" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "לחיצה כפולה" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "לחיצה משולשת" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "סינתסייזר ברירת המחדל" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "מחרוז מקורית" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "מחרוזת מוחלפת" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "הפעל אמירת מקשים לפי ת_ו" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "הפעל מקשי _תנועה" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "מיקום נ_וכחי" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "אורך מינימלי של התאמת טקסט:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "אפשרויות חיפוש" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "לה_קריא רק שורות שהשתנו במהלך איתור" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "הקראת תוצאות במהלך _איתור" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "פקודה" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "מקשי קיצור" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "בררת מחדל" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "מידע נוסף" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "פעולות" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "תבניות ברייל" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "סימניות" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "תאריך ושעה" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "סקירת עכבר" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "ניווט עצמים" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "פרטי עצם" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "ללא מקש" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "סקירה שטוחה" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "הקראה ופירוט" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "תוכן סקירה שטוחה" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "נערך" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_פריסה שולחנית" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "התראות" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "התקבל" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "מציג התראות" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "העדפות Cthulhu עבור %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "סימון בברייל" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "נוכח אלא אם כן" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "דיבור" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "שמירת פרופיל כסתירה" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "סתירה בפרופיל המשתמש!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"הפרופיל %s כבר קיים.\n" -"להמשיך לעדכן את הפרופיל הקיים עם השינויים החדשים האלה?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "טעינת פרופיל משתמש" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"פעולה זו תשנה את הפרופיל הפעיל. אם ערכת\n" -"שינויים בהעדפות שלך, הן תושמטנה\n" -"עם טעינת הפרופיל.\n" -"\n" -"להמשיך לטעון את הפרופיל ולהתעלם מהשינויים הקודמים?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "שמירת פרופיל בשם" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "שם ה_פרופיל:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "הסרת פרופיל משתמש" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"פעולה זו תסיר את הפרופיל %s. כל ההגדרות שלא נשמרו והגדרות שנשמרו בפרופיל הזה " -"תאבדנה. להמשיך להסיר את הפרופיל ואת כל ההגדרות שקשורות אליו?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "כולם" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "יישום" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "חלון" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_ללא" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "חל_קי" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "ה_רוב" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "שורה" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "משפט" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "ציטטה" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "כפתור" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "כותרת" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "תיבת סימון" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "לחיץ" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "תיבת בחירה" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "תיאור" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "כותרת ראשית" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "מסגרת פנימית" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "תמונה" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "תווית" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "רמה" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "קישור" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "רשימה" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "פריט ברשימה" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "עצם" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "פסקה" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "כפתור בחירה" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "תפקיד" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "פריט שנבחר" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "מצב" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "טקסט" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "ערך" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "ציטטות" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "כפתורים" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "תיבות סימון" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "לחיצים" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "תיבות בחירה" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "רשומות" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "שדות טופס" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "כותרות ראשיות" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "מסגרות פנימיות" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "תמונות" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "כותרות ברמה %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "פריטים גדולים" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "קישורים" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "רשימות" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "פריטים ברשימה" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "פסקאות" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "כפתורי בחירה" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "טבלאות" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "קישורים בהם טרם ביקרת" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "קישורים בהם ביקרת" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "ניווט בעמודים" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "להתחיל להקריא עמוד אוטומטית עם טעינתו ה_ראשונה" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "התחל אוטומטית להקריא את העמוד בטעינה הראשונה שלו." - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "קול ברירת המחדל %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "ברירת מחדל" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "קישור" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "מערך" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "אותיות רישיות" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "משלח הקראה" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "בדיקת איות" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "הקראת _שגיאה" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "הקראת ה_צעה" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "הצגת ה_קשר השגיאה" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "הקראת נקודות ציון של תא בגיליון נתונים" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "הכרזה על _כותרת התא" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "ניווט בטבלה" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "דלג על תאים _ריקים" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "הקראת _תא" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "הקראת _נקודות הציון של התא" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "שם המאפיין" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "שליטה בניווט הסמן" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "הפעלת ניווט מ_בני" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_ערכת צלילים:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "ערכת צלילים" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "קצ_ר" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "התראה %d" -msgstr[1] "%d התראות" -msgstr[2] "%d התראות" -msgstr[3] "%d התראות" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "שיפט" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "אלט" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "קונטרול" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "shift שמאלי" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt שמאלי" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control שמאלי" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "shift ימני" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt ימני" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control ימני" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "נעילת shift" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab שמאלי" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "אנטר" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "למעלה" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "למטה" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "שמאלה" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "ימינה" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "תפריט" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "עזרה" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "החלפת מצב" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "התחלה" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "טבעת" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "מינוס" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s מודגש" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s נטוי" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s ברוחב אחיד" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "חץ שמאלה" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "חץ למעלה" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "חץ ימינה" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "חץ למטה" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "חץ ימינה שמאלה" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "חץ למעלה למטה" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "חץ צפון־מערב" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "חץ צפון־מזרח" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "חץ לדרום מערב" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "חץ שמאלה עם בסיס" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "חץ למעלה עם בסיס" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "חץ ימינה מקו (ממופה אל)" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "חץ למטה עם בסיס" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "חץ כפול שמאלה" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "חץ כפול למעלה" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "חץ ימינה כפול" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "חץ כפול למטה" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "חץ ימינה שמאלה כפול" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "חץ כפול למעלה למטה" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "חץ כפול לצפון מערב" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "חץ כפול לצפון־מזרח" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "חץ כפול לדרום־מזרח" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "חץ כפול לדרום־מערב" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "חץ מצביע ימינה" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "ראש עץ מצביע ימינה" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "מינוס" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "קטן מ" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "גדול מ" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "גג" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "וי קטן" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "ברווה" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "נקודה" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "קו אנכי כפול" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "השמטה אופקית" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "קבוצה ריקה" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "סוף ההוכחה" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "סכום" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "מינוס פלוס" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "נקודה פלוס" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "לוכסן חלוקה" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "אינסוף" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "זווית ימנית" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "זווית" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "זווית ספרית" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "לא מתחלק" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "מקביל ל־" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "וגם לוגי" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "או לוגי" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "חיתוך" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "איחוד" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "אינטגרל" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "אינטגרל כפול" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "אינטגרל משולש" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "אינטגרל משטחי" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "לפיכך" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "כיוון" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "יחס" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "פרופורציה" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "נקודה מינוס" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "פרופורציה גאומטרית" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "טילדה" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "טילדה הפוכה" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "‫S הפוכה עצלה" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "גל סינוס" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "לא טילדה" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "מינוס טילדה" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "טילדה משולשת" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "הבדל בין" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "טבעת בתוך שווה" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "טבעת שווה" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "לא שווה ל" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "זהה ל־" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "לא זהה ל" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "לא קטן מאשר" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "לא גדול מאשר" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "לא קטן או שווה ל־" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "לא גדול או שווה ל־" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "קטן מאשר או שווה ל־" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "גדול מאשר או שווה ל־" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "לא קטן מאשר או שווה ל־" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "לא גדול מאשר או שווה ל־" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "קטן מאשר או גדול מאשר" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "גודל מאשר או קטן מאשר" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "לא קטן ולא גדול מאשר" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "לא גדול או קטן מאשר" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "שכפול רב־קבוצה" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "סעיף" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "לא אמת" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "או בלעדי" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "לא וגם" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "זווית ימנית עם קשת" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "משולש ימני" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "כפול" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "סעיף" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "כפול" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "השמטה אנכית" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "חץ ימני" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "למטה" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "ריבוע שחור" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "ריבוע לבן" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "יהלום שחור" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "עיגול לבן" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "עיגול שחור" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "ריבוע בינוני-קטן שחור" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s עם קו תחתי" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s עם לוכסן" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s עם קו אנכי" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "יישום" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "ריק" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "הדגשה" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "הוכנסה סימנייה" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "הסימנייה נשמרה" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "לא ניתן לשמור את הסימניות" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "לא נמצאו סימניות." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "לא נמצאה סימנייה." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "מצב מעקף מופעל." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "לא ניתן להציג את המחשבון" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "סמל" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "סגנון רישיות הוגדל לסמל." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ללא" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "סגנון רישיות הוגדר לבלי." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "הקראה" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "סגנון רישיות הוגדר לאיות." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "היישום שולט בסמן הטקסט." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu שולט בסמן." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "תא %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "נבחר" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr " לא נבחר" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "נבחרו %s עד %s" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "בחירה בוטלה" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Prevent use of option" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Force use of option" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "אפשרות" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "ארגומנטים כרשות" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "שימוש: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "הבאים אינם תקפים: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "הצג רשימה של יישומים ידועים" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "טעינת פרופיל" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "אי אפשר לטעון את הפרופיל: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"לא ניתן להפעיל את Cthulhu כי לא ניתן להתחבר לשולחן העבודה.לא ניתן להפעיל את " -"מקריא המסך כיוון שאין לו אפשרות להתחבר לשולחן העבודה." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "לא ניתן להפעיל את מנהל ההגדרות. התוכנית תיסגר." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"תהליך קורא מסך אחר כבר פועל בהפעלה הזאת.\n" -"יש להריץ את הפקודה „cthulhu --replace” כדי להחליף את התהליך הזה באחד חדש." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "שם" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Use alternate directory for user preferences" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "תיקייה" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "גרסת היישום" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "החלף מופע של Cthulhu הפועל כעת" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "הצגת הודעת העזרה הזאת ולצאת" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "שליחת פלט ניפוי שגיאות אל debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "שליחת פלט ניפוי שגיאות לקובץ מסוים" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "קובץ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Set up user preferences (text version)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "הגדרת העדפות משתמש (גרסה חזותית)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Report bugs to https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "גזירת הבחירה ללוח הגזירים." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "גזירה" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "הבחירה הועתקה ללוח הגזירים." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "מועתק" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "הודבק תוכן מלוח הגזירים." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "הודבק" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "לא להודיעה כאשר החברים שלך מקלידים." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "הודעה כאשר החברים שלך מקלידים." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "הודעה מחדר הצ'ט %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "לשונית צ'ט חדשה %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "לא להקריא שם חדר צ׳אט." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "הקראת שם חדר צ׳אט." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "לא לספק היסטוריות הודעות לחדרי צ׳אט מסוימים." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "אספקת היסטוריות הודעות לחדרי צ׳אט מסוימים." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "תחילת מחיקה" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "סיום מחיקה" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "תחילת הוספה" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "סיום הוספה" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "תחילת הדגשה" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "סיום הדגשה" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "סיום הצעה" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "סוף פריט תכולה." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "לא בתוך פריט תכולה." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "כל הפריטים נבחרו" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "כפתור ברירת המחדל הוא %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "כפתור ברירת המחדל הוא %s. מוחשך" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "כפתור ברירת המחדל לא נמצא" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " %s בכתב תחתי" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " %s בכתב עילי" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "לא בחלונית" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "כל המסמך נבחר" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "בוטלה הבחירה בכל המסמך" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "המסמך נבחר ממקום הסמן" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "בחירת המסמך ממקום הסמן בוטלה" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "המסמך נבחר למקום הסמן" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "הבחירה במסמך בוטלה עד למקום הסמן" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "כותרת עמודות דינמית הוגדרה לשורה %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "כותרת עמודה דינמית פונתה." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "כותרת שורה דינמית הוגדרה לעמודה %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "כותרת שורה דינמית פונתה." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ריק" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "‫%.2f קילובתים" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "‫%.2f מגהבתים" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "לא נמצאו קבצים." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "התוכן נוסף ללוח הגזירים." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "התוכן הועתק ללוח הגזירים." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "אין שימוש בסקירה שטוחה." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "כניסה לסקירה שטוחה." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "מעביר את משטח הסקירה למילה מעל המילה הנוכחית." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "סקירה שטוחה ללא הגבלה" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "מכיל נוסחה" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "פותח חלונית" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "פותח רשת" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "פותח תיבת רשימה" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "פותח תפריט" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "פותח עץ" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "קישור למיפוי תמונה" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "מקש הקיצור שהוקלד כבר מקושר לפעולה %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "המקש הנקלט: %s. לחץ על enter כדי לאשר." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "המקש החדש הוא: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "קיצור המקשים נמחק. לחץ על enter כדי לאשר." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "קיצור המקשים הוסר." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "הקלד שילוב מקשים חדש" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "מפתח" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "ההד הוגדר למקש." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "ללא" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "ההד הוגדר לכלום." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "מפתח ומילה" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "ההד הוגדר למקש ולמילה." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "משפט" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "ההד הוגדר למשפט." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "מילה" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "ההד הוגדר למילה." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "מילה ומשפט" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "ההד הוגדר למילה ולמשפט." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "תחום ב־: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "ריבוע" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "עיגול" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "סימן חילוק ארוך" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "ריבוע מעוגל" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "אופקי" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "יישור אנכי" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "חץ לצפון־מזרח" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "שורה בחתית" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "שורה מימין" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "וגם" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "תחילת שבר" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "שבר ללא קו שבר, התחלה" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "סוף שבר" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "שורש ריבועי של" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "שורש שלישי של" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "שורש של" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "התחלת שורש" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "סוף שורש" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "כתב תחתי" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "כת עילי" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "טרום כתב תחתי" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "טרום כתב עילי" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "סוף טבלה" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "סוף טבלה מקוננת" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "לא נגיש" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "מושבת" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "אמור את ההזחה ואת הכיוון." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "פעיל" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "אמור את ההזחה ואת הכיוון." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "מצב למידה. escape ליציאה." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "ניווט בעמודים" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "עוזב את הטבלה." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "יוצא ממצב למידה." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "השורה נבחרה מתחילת מיקום האחרון של הסמן" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "השורה נבחרה לסוף מהמיקום האחרון של הסמן" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "קישור" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "אותו דף" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "אותו האתר" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "אתר אחר" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "קישור %(uri)s ל־%(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "קישור %s" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "‏%d קישורים שנלחצו" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "רמת נימוס %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "לא נמצא" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "לא ניתן זהות את המיקום הנוכחי." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "כבוי" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "פעיל" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "שגיאת כתיב" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "שגיאת כתיב: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "ההקשר הוא %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "מצב עיון" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "מצב מיקוד" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "כדי להפעיל מצב מיקוד יש ללחוץ על %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "מצב המיקוד דביק." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "מצב העיון דביק." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "מצב פריסה." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "מצב עצמים." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "הסמן עבר לפריט." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "עכבר על גבי עצם לא נמצא." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "סקירת עכבר הושבתה." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "סקירת עכבר הופעלה." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "שגיאה: לא ניתן ליצור רשימה של עצמים." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "אין צאצאים." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "אין הבא." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "אין הורה." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "אין פריט קודם." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "הופעל ניווט מפושט." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "הושבת ניווט מפושט." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "רמת קינון %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "לא נוסף אף פריט" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "לא נמצאו פעולות עבור: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "אין מיקוד" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "אין יישום במיקוד." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "אין יותר ציטטות." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "אין עוד כפתורים." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "אין יותר תיבות סימון." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "אין יותר פריטים גדולים." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "אין עוד פריטים לחיצים." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "אין עוד תיבות משולבות." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "אין יותר רשומות." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "אין עוד שדות בטופס." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "אין עוד כותרות." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "אין עוד כותרות ברמה %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "אין עוד מסגרות פנימיות." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "אין עוד תמונות." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "אין עוד קישורים." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "אין עוד רשימות." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "אין עוד פריטים ברשימה." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "אין עוד אזורים חיים." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "אין יותר פסקאות." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "אין עוד לחצן בחירה." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "אין יותר מפרידים." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "אין עוד טבלאות." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "אין עוד קישורים שלא ביקרת בהם." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "אין עוד קישורים שביקרת בהם." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "לא נבחר טקסט." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "לא בקישור." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "התראה" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "תחתית" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "ראש" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "אין הודעות התראה" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "ספרות" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "להגיד מספרים כספרות." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "מילים" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "להקריא מספרים כמילים." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "כבוי" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "פעיל" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "טוען. נא להמתין." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "טעינה הסתיימה." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "טעינת %s הסתיימה." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "בעמוד יש %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "העמוד נבחר ממקום הסמן" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "העמוד נבחר למקום הסמן" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "בחירת העמוד בוטלה ממקום הסמן" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "בחירת העמוד בוטלה למקום הסמן" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "השורה נבחרה לסוף מהמיקום האחרון של הסמן" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "השורה נבחרה לסוף מהמיקום האחרון של הסמן " - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "השורה נבחרה לסוף מהמיקום האחרון של הסמן " - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "השורה נבחרה לסוף מהמיקום האחרון של הסמן " - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"חלון העדפות של Cthulhu אחד כבר פעיל.\n" -"\n" -"נא לסגור אותו לפני פתיחת אחד חדש." - -#: src/cthulhu/messages.py:2132 -#, fuzzy, python-format -msgid "slide %(position)d of %(count)d" -msgstr "עמודה %(index)d מתוך %(total)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "הפרופיל הוגדר לכדי %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "לא נמצא פרופיל." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "פס התקדמות %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "הכול" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "רמת פיסוק" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "הכי הרבה" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "רמת הפיסוק הוגדרה למרבית." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "ללא" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "רמת הפיסוק הוגדרה לכלום." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "חלקי" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "רמת הפיסוק הוגדרה לחלקית." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "מחפש." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "החיפוש הושלם." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "הגדרות Cthulhu נטענו מחדש." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "הטקסט הנבחר הוא: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "הבחירה נמחקה." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "הבחירה שוחזרה." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "בחירת הטקסט בוטלה." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "גודל: %d, %d. מיקום: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "רוחב: %d. גובה: %d. %d משמאל. %d מלמעלה." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "הדיבור מכובה." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "הדיבור מופעל." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "מהיר יותר." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "לאט יותר." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "גבוה יותר." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "נמוך יותר." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "בקול רם יותר." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "רך יותר." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "קצב %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "גובה צליל %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "עוצמת קול %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "מודול Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "קול Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "אין מודולי Speech-dispatcher זמינים" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "אין קולות Speech-dispatcher זמינים" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "הגדרות דיבור נשמרו" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "לא ניתן לשמור את הגדרות הדיבור" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "רמת פירוט: מתומצת" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "רמת פירוט: מפורט" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " נקודה נקודה נקודה" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu מברך אותך." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "קת'ולו אורב מתחת לגלים." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "מצב שינה מופעל עבור %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "מצב שינה מושבת עבור %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "דיבור אינו זמין." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "לא נמצא" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "לא נמצאה שורת מצב" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "מחרוזת החיפוש לא נמצאה" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "מקשי ניווט מבניים מושבתים." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "מקשי ניווט מבניים פעילים." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "לא נמצא" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "שורה %(row)d, עמודה %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "סוף הטבלה" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "הקראת תא" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "הקראת שורה" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "לא אחיד" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "לא טבלה." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "העמודות סודרו מחדש" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "השורות סודרו מחדש" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "עמודה %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "עמודה %(index)d מתוך %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "תחתית עמודה." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "ראש עמודה." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "נבחרה העמודה %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "נבחרו עמודות %s עד %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "בוטלה בחירת עמודות %s עד %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "בוטלה בחירת העמודה %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "שורה %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "שורה %(index)d מתוך %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "התחלת שורה." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "סוף השורה." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "שורה נמחקה." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "השורה האחרונה נמחקה." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "נוספה שורה." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "נוספה שורה בסוף הטבלה." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "השורה %s נבחרה" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "שורות %s עד %s נבחרו" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "בוטלה בחירת שורות %s עד %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "בוטלה בחירת השורה %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "נבחר" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "בחירה בוטלה" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H שעות, %M דקות ו־%S שניות" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "‫%H שעות ו־%M דקות" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "יוניקוד %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "ביטול" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "שחזור" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu גרסה %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "רווח לבן" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "גלישה למטה." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "גלישה למעלה." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 פריטים" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "התא מתפרס על שורה (%d)" -msgstr[1] "התא מתפרס על שתי (%d) שורות" -msgstr[2] "התא מתפרס על %d שורות" -msgstr[3] "התא מתפרס על %d שורות" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " עמודה %d" -msgstr[1] " שתי (%d) עמודות" -msgstr[2] " %d עמודות" -msgstr[3] " %d עמודות" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "התא מתפרס על עמודה (%d)" -msgstr[1] "התא מתפרס על שתי (%d) עמודות" -msgstr[2] "התא מתפרס על %d עמודות" -msgstr[3] "התא מתפרס על %d עמודות" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "תו (%d) יותר מדי" -msgstr[1] "שני (%d) תווים יותר מדי" -msgstr[2] "%d תווים יותר מדי" -msgstr[3] "%d תווים יותר מדי" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(חלונית אחת - %d)" -msgstr[1] "(שתי - %d חלוניות)" -msgstr[2] "(%d חלוניות)" -msgstr[3] "(%d חלוניות)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "בית %d" -msgstr[1] "‫%d בתים" -msgstr[2] "‫%d בתים" -msgstr[3] "‫%d בתים" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "נמצא קובץ %d" -msgstr[1] "נמצאו %d קבצים" -msgstr[2] "נמצאו %d קבצים" -msgstr[3] "נמצאו %d קבצים" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "טופס %d" -msgstr[1] "‫%d טפסים" -msgstr[2] "‏%d טפסים" -msgstr[3] "‏%d טפסים" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "כותרת ‏%d" -msgstr[1] "‏%d כותרות" -msgstr[2] "‏%d כותרות" -msgstr[3] "‏%d כותרות" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "פריט %d" -msgstr[1] "‫%d פריטים" -msgstr[2] "‫%d פריטים" -msgstr[3] "‫%d פריטים" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "נמצא פריט (%d)" -msgstr[1] "נמצאו שני (%d) פריטים" -msgstr[2] "נמצאו %d פריטים" -msgstr[3] "נמצאו %d פריטים" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "עוזב את הטבלה." -msgstr[1] "עוזב את הטבלה." -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "עוזב את הטבלה." -msgstr[1] "עוזב את הטבלה." -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "רשימה בגודל לא ידוע" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "רשימה עם פריט %d" -msgstr[1] "רשימה עם %d פריטים" -msgstr[2] "רשימה עם %d פריטים" -msgstr[3] "רשימה עם %d פריטים" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "ערוץ עדכונים בגודל לא ידוע" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "ערוץ עדכונים עם כתבה (%d)" -msgstr[1] "ערוץ עדכונים עם שתי (%d) כתבות" -msgstr[2] "ערוץ עדכונים עם %d כתבות" -msgstr[3] "ערוץ עדכונים עם %d כתבות" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "רשימת תיאורים עם ביטוי אחד (%d)" -msgstr[1] "רשימת תיאורים עם שני (%d) ביטויים" -msgstr[2] "רשימת תיאורים עם %d ביטויים" -msgstr[3] "רשימת תיאורים עם %d ביטויים" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "ערך אחד (%d)" -msgstr[1] "שני (%d) ערכים" -msgstr[2] "%d ערכים" -msgstr[3] "%d ערכים" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "טבלה מתמטית עם שורה אחת (%d)" -msgstr[1] "טבלה מתמטית עם שתי (%d) שורות" -msgstr[2] "טבלה מתמטית עם %d שורות" -msgstr[3] "טבלה מתמטית עם %d שורות" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "עמודה %d" -msgstr[1] "‫%d עמודות" -msgstr[2] "‫%d עמודות" -msgstr[3] "‫%d עמודות" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "טבלה מתמטית מקוננת עם שורה אחת (%d)" -msgstr[1] "טבלה מתמטית מקוננת עם שתי (%d) שורות" -msgstr[2] "טבלה מתמטית מקוננת עם %d שורות" -msgstr[3] "טבלה מתמטית מקוננת עם %d שורות" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "הודעה אחת (%d).\n" -msgstr[1] "שתי (%d) הודעות.\n" -msgstr[2] "%d הודעות.\n" -msgstr[3] "%d הודעות.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "אחוז %d." -msgstr[1] "‏%d אחוז." -msgstr[2] "‏%d אחוז." -msgstr[3] "‏%d אחוז." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d מהמסמך נקרא" -msgstr[1] "%d מהמסמך נקראו" -msgstr[2] "%d מהמסמך נקראו" -msgstr[3] "%d מהמסמך נקראו" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "פיקסל %d" -msgstr[1] "‫%d פיקסלים" -msgstr[2] "‫%d פיקסלים" -msgstr[3] "‫%d פיקסלים" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "תו %(repeatChar)s %(count)d" -msgstr[1] "‫%(count)d תווי %(repeatChar)s" -msgstr[2] "‫%(count)d תווי %(repeatChar)s" -msgstr[3] "‫%(count)d תווי %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "‫%(index)d מתוך ‏‏%(total)d פריטים נבחר" -msgstr[1] "‏%(index)d מתוך ‏‏%(total)d פריטים נבחרו" -msgstr[2] "‏%(index)d מתוך ‏‏%(total)d פריטים נבחרו" -msgstr[3] "‏%(index)d מתוך ‏‏%(total)d פריטים נבחר" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "רווח %d" -msgstr[1] "‏%d רווחים" -msgstr[2] "‏%d רווחים" -msgstr[3] "‏%d רווחים" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "לשונית אחת (%d)" -msgstr[1] "שתי (%d) לשוניות" -msgstr[2] "%d לשוניות" -msgstr[3] "%d לשוניות" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "טבלה %d" -msgstr[1] "‫%d טבלאות" -msgstr[2] "‫%d טבלאות" -msgstr[3] "‫%d טבלאות" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "טבלה בגודל לא ידוע" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "טבלה עם עמודה אחת (%d), כמות השורות לא ידועה" -msgstr[1] "טבלה עם שתי (%d) עמודות, כמות השורות לא ידועה" -msgstr[2] "טבלה עם %d עמודות, כמות השורות לא ידועה" -msgstr[3] "טבלה עם %d עמודות, כמות השורות לא ידועה" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "טבלה עם שורה אחת (%d), כמות העמודות לא ידועה" -msgstr[1] "טבלה עם שתי (%d) שורות, כמות העמודות לא ידועה" -msgstr[2] "טבלה עם %d שורות, כמות העמודות לא ידועה" -msgstr[3] "טבלה עם %d שורות, כמות העמודות לא ידועה" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "טבלה עם שורה (%d)" -msgstr[1] "טבלה עם שתי (%d) שורות" -msgstr[2] "טבלה עם %d שורות" -msgstr[3] "טבלה עם %d שורות" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "לפני שנייה (%d)" -msgstr[1] "לפני שתי (%d) שניות" -msgstr[2] "לפני %d שניות" -msgstr[3] "לפני %d שניות" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "לפני דקה (%d)" -msgstr[1] "לפני שתי (%d) דקות" -msgstr[2] "לפני %d דקות" -msgstr[3] "לפני %d דקות" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "לפני שעה (%d)" -msgstr[1] "לפני שעתיים (%d)" -msgstr[2] "לפני %d שעות" -msgstr[3] "לפני %d שעות" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "אתמול (%d)" -msgstr[1] "שלשום (%d)" -msgstr[2] "לפני %d יום" -msgstr[3] "לפני %d ימים" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "קישור ‏‏%d שלא נלחץ" -msgstr[1] "‏‏%d קישורים שלא נלחצו" -msgstr[2] "‏‏%d קישורים שלא נלחצו" -msgstr[3] "‏‏%d קישורים שלא נלחצו" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "קישור ‏%d שנלחץ" -msgstr[1] "‏%d קישורים שנלחצו" -msgstr[2] "‏%d קישורים שנלחצו" -msgstr[3] "‏%d קישורים שנלחצו" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "מתג" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "פריט %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "רמה %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "דרגת עץ %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "דרגת עץ %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "פרטים על %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "הצעה" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "תיבה משולבת שזמינה לעריכה" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "תוכן זמין לעריכה" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "ערוץ עדכונים" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "אפילוג" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "נספח" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "רשומת ביבליוגרפיה" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "ביבליוגרפיה" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "פרק" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "קולופון" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "מסקנה" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "כריכה" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "הוקרה" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "הוקרות" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "הקדשה" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "אפיגרף" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "אפילוג" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "אראטה" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "דוגמה" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "הקדמה" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "מונחון" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "מפתח" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "היכרות" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "מעבר עמוד" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "רשימת עמודים" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "הקדמה" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "פרולוג" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "כתובית" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "תוכן עניינים" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s ברמה %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "פס גלילה אופקי" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "פס גלילה אנכי" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "מחוון גלילה אופקי" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "מחוון גלילה אנכי" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "מפצל אופקי" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "מפצל אנכי" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "בורר" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "סמל בלוח" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "כרזה" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "תוכן משלים" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "מידע" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "תוכן ראשי" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "ניווט" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "אזור" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "חיפוש" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "קישור בו ביקרת" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "כפתור תפריט" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "מסודר בסדר עולה" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "מסודר בסדר יורד" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "מסודר" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "לחיץ" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "מכווץ" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "מורחב" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "יש לו תיאור ארוך" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "אופקי" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "אנכי" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "מסומנת" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "לא מסומנת" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "פעיל" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "כבוי" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "מסומנת חלקית" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "לחוץ" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "לא לחוץ" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "לא נבחר" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "נבחר" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "לא נבחר" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "לא נבחר" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "בוקר" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "לא בוקר" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "מוחשך" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "לקריאה בלבד" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "לקריאה בלבד" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "נדרש" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "בחירת מגוון" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "רשומה שגויה" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "שגוי" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "איות שגוי" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "איות" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "דקדוק שגוי" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "דקדוק" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "מצא" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "חלונית איתור מקריא מסך" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_סגירה" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_איתור" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "‏_חיפוש אחר:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "חיפוש אחר:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_ראש החלון" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "ראש החלון החלון" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "התחלה מ־:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_גלוש מסביב" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "חפש _אחורה" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "כיוון החיפוש:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "הת_אם רשיות" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "התאם מילים _שלמות בלבד" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "אפשרויות:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "בררת מחדל" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "אותיות רישיות" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "קישור" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "מערכת" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "יישום" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "חלון" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "העדפות Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "ע_זרה" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "ה_חלה" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_פריסה ניידת" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "פריסת מקלדת" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_פרופיל פעיל:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "פרופיל פתיחה:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_טעינה" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "_שמירה בשם" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "ה_סרה" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "פרופילים" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_הצג רמזים צצים" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "להגיד את הפריט ש_תחת סמן העכבר" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "עכבר" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "תבנית _זמן:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "תבנית ת_אריך:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "שעה ותאריך" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "הקראת _עדכונים" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_עדכונים בברייל" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "תדירות (שניות):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "חל על:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_צפצוף על עדכונים" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "עדכוני פסי התקדמות" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "הפעל מקשי _תנועה" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "דבר ל_פי:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "הכרזה על _רשימות בזמן הניווט" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "להקריא הכול" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_הצגת רכיב:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "כללי" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "עוצמת _קול:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "גובה צ_ליל:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_קצב:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_אישיות:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_שפה:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "מסנ_תז דיבור:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_מערכת דיבור:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "סוג _קול:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_סגנון הגדלת אותיות:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "הגדרות סוג קול" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "הקראת מילים עם _רישיות מעורבבות כמילים" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "הקראת מ_ספרים כספרות" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "הגדרות קול גלובלי" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "קול" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "ה_פעלת דיבור" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "מ_פורט" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "רמת פירוט" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_מלאה" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "רמת פיסוק" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "להקריא רק טקסט שמוצג" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "דבר שורות ריקות" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "להגיד את הה_זחה ואת היישור" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "להקריא את מקום ה_צאצא" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "הקראת הודעות הסבר" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "הודעות המערכת מ_פורטות" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "הקראת _צבעים כשמות" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "הכרזה על _רשימות בזמן הניווט" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "הכרזה על _טבלאות בזמן הניווט" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "הכרזה על _לוחות בזמן הניווט" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "הכרזה על _צורות בזמן הניווט" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "הקראת ה_תיאור" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "הקראת השורה במלואה ב_גיליונות נתונים" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "הקראת השורה במלואה בטבלאות במ_סמכים" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "הקראת השורה במלואה בטבלאות במ_נשק המשתמש" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "הקשר מוקרא" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "דיבור" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "הפעל _תמיכה בברייל" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "שמות תפקידים _מקוצרים" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "בטל את סימן _סוף השורה" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_טבלת קיצורים:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "ה_פעלת ברייל מקוצר" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "הפעלת _גלישת שורות" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "הגדרות תצוגה" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_ללא" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "מחוון ברירה" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "מחוון קישורים" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "הפעלת הודעות מה_בהבות" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "מ_שך (שניות):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "ההודעות מ_קובעות" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "ההודעות מ_פורטות" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "הגדרות הודעות מהבהבות" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ברייל" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "הפעלת הקראת _מקשים" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "הפעל מקשים _אלפבתיים" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "הפעלת מקשים _נומריים" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "הפעלת מקשי _פיסוק" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "הפעלת _רווח" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "הפעלת מקשי ה_חלפה ‎(alt,shift,...)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "הפעלת מקשי _פונקציות" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "הפעלת מקשי פעו_לות" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "הפעלת מקשי _ניווט" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "הפעלת הד לפי _מילה" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "הפעלת הד לפי _משפט" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "הד" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "מקשי _שינוי של Cthulhu:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "קיצורי מקשים" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "מילון הגייה" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "רשומה _חדשה" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_מחיקה" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "הגייה" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "לה_קריא הכול" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_איפוס" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "מאפייני טקסט" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "להוריד ל_תחתית" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "להוריד אחד למ_טה" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "להעלות אחד למ_עלה" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "להעלות ל_ראש" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "התאמת המאפיין הנבחר" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "מחוון ברייל" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "מאפייני טקסט" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "הפעל עוזר AI" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_ספק:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (מקומי - חינם)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "קובץ מפתח _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "נתיב לקובץ מפתח API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "קבל מפתח API של _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "פתח דפדפן כדי לקבל מפתח API של Claude ולשמור אוטומטית" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "דרוש אישור לפני פעולות AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_מודל Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "שם המודל עבור Ollama (לדוגמה llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_נקודת קצה Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "כתובת URL של נקודת קצה API של Ollama (למשל, http://192.168.1.100:11434)" -"כתובת URL של נקודת קצה API של Ollama (לדוגמה http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_איכות צילום מסך:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "נמוך" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "בינוני" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "גבוה" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "עוזר AI" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "קוד _שפה:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "מקדם _קנה מידה:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "תמונה ב_גווני אפור" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_הפוך תמונה" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "תמונה ב_שחור-לבן" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_סף שחור/לבן:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_נתח צבעים" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "העתק תוצאות ל_לוח" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"א : אלף , ב : בועז , ג : גימל , ד : דוד , ה : הגר , ו : וו , ז : זאב , ח : " -"חוה , ט : טיח , י : יונה , כ : כרמל , ל : לאה , מ : משה , נ : נשר , ס : " -"סמך , ע : עין , פ : פסל , צ : ציפור , ק : קורח , ר : רות , ש : שמיר , ת : תלם" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "צבע רקע" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "גובה מלא של הרקע" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "סעיף" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "ניתן לעריכה" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "שם משפחה" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "צבע חזית" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "אפקטי גופן" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "הזחה" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "טעות" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "בלתי נראה" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "כיוון הטקסט" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "שפה" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "גובה שורה" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "סגנון פסקה" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "פיקסלים מעל שורות" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "פיקסלים מתחת לשורות" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "הגבהה" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "קנה מידה" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "גודל" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "מתיחה" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "קו חוצה" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "סגנון" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "קישוט טקסט" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "סיבוב טקסט" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "צללית טקסט" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "קו תחתי" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "הגוון" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "יישור אנכי" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "משקל" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "מצב גלישה" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "מצב כתיבה" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "אמת" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "שרק" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ללא" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "קו חוצה" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "הבהוב" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "שחור" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "אחד" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "כפול" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "נמוך" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "מילה" - -#: src/cthulhu/text_attribute_names.py:452 -#, fuzzy -msgctxt "textattr" -msgid "word char" -msgstr "מילה" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "שמאל לימין" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "ימין לשמאל" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "שמאל" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "ימין" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "ממורכז" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "ללא כיוון" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "מילוי" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "מורחב" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "נטוי" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "ברירת מחדל" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "גוף הטקסט" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "כותרת" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "קו בסיס" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "תחתי" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "עילי" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "עליון" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "אמצעי" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "למטה" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "ירושה" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "הדגשה" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "איות" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "רווח להחלפת מצב." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "יש ללחוץ על רווח להרחבה ולהשתמש בלמעלה ולמטה כדי לבחור פריט." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "יש ללחוץ על alt+f6 כדי להעביר את המיקוד לחלונות הצאצאיים." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "כדי להעביר פריטים, להשתמש או במקשי החצים או להקליד טרום חיפוש." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "כדי להגיע לתפריטי המערכת יש ללחוץ על הצירוף alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "כדי לצמצם יש ללחוץ על Shift עם שמאלה." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "כדי להרחיב יש ללחוץ על Shift עם ימינה." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "‫Enter להפעלה." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "נא להקליד טקסט." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "יש להשתמש בשמאלה וימינה כדי לצפות בלשוניות אחרות." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "רווח להפעלה." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "מקשי החצים משמשים לשינוי." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"כדי לנווט, יש ללחוץ על החץ שמאלה או ימינה. כדי לעבור בין פריטים יש ללחוץ על " -"החץ למעלה או למטה." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "כדי להיכנס לתת־תפריט, יש ללחוץ על החץ ימינה." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/hi.po b/po/hi.po deleted file mode 100644 index 56b3ae3..0000000 --- a/po/hi.po +++ /dev/null @@ -1,9834 +0,0 @@ -# translation of cthulhu.HEAD.po to Hindi -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# -# Rajesh Ranjan , 2008, 2009. -# chandankumar , 2013. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2013-03-21 15:38+0000\n" -"Last-Translator: chandankumar \n" -"Language-Team: Hindi \n" -"Language: hi\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n" -"\n" -"\n" -"\n" -"X-Generator: Lokalize 1.5\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu स्क्रीन वाचक" - -#, fuzzy -msgid "screen;reader;accessibility;speech;braille;" -msgstr "स्क्रीन रीडर;भाषण;ब्रेल;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "दिनांक" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "डॉयल" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "आरेख बनायें" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "फ़ॉर्म" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "लिंक " - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "रेडियो" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "स्लाइडर" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "स्पिन" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "मद" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "संकेत" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "अनुच्छेद" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "स्वचालित" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "चेक ग्रेड 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "स्पेनी ग्रेड 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "कनाडा फ्रांसीसी ग्रेड 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "फ्रांस फ्रांसीसी ग्रेड 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "लातवियाई ग्रेड 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "नीदरलैंड्स डच ग्रेड 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "नॉर्वेजियाई ग्रेड 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "नॉर्वेजियाई ग्रेड 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "नॉर्वेजियाई ग्रेड 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "नॉर्वेजियाई ग्रेड 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "पोलिश ग्रेड 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "पुर्तगाली ग्रेड 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "स्वीडिश ग्रेड 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "अरबी ग्रेड 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "वेल्श ग्रेड 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "वेल्श ग्रेड 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "जर्मन ग्रेड 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "जर्मन ग्रेड 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "जर्मन ग्रेड 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "यू के अंग्रेज़ी ग्रेड 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "यू के अंग्रेज़ी 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "यू एस अंग्रेज़ी ग्रेड 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "यू S अंग्रेज़ी ग्रेड 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "कनाडा फ्रांसीसी ग्रेड 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "फ्रांस फ्रांसीसी ग्रेड 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "यूनानी ग्रेड 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "हिन्दी ग्रेड 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "हङ्गेरियाई 8 डॉट कंप्यूटर" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "हंगेरियाई ग्रेड 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "हंगेरियाई ग्रेड 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "इतालवी ग्रेड 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "बेल्जियम डच ग्रेड 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "स्थान" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "न्यूलाइन" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "टैब" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "विस्मयादिबोधक" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "उद्धरण" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "संख्या" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "डॉलर" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "प्रतिशत" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "और" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "वर्णलोप का चिह्न" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "बायां पैरन" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "दायां पैरन" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "तारा" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "जोड़" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "विराम चिह्न" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "डैश" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "डॉट" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "स्लैश" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "कॉलन" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "अर्द्ध विराम" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "कम" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "समान होते है" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "से बड़ा" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "प्रश्न" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "एट" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "बायां कोष्ठ" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "बैकस्लैश" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "दायां कोष्ठ" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "हंसपद" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "रेखांकित" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "ग्रेव" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "बायां ब्रेस" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "लंबवत पट्टी" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "दायां कोष्ठक" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "टिल्डे" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "कोई बैकस्पेस नहीं" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "उल्टा विस्मयादिबोधक बिंदु" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "सेंट" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "पाउंड" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "मुद्रा चिह्न" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "येन" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "टूटी पट्टी" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "खंड" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "कापीराइट" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "सुपरस्क्रिप्ट a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "बायाँ दोहरा कोण कोष्ठक" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "तार्किक नहीं" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "सॉफ्ट योजक" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "पंजीकृत" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "मैक्रोन" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "कोण" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "जोड़ या ऋण" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "सुपरस्क्रिप्ट 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "सुपरस्क्रिप्ट 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "अधि" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "म्यू" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "अनुच्छेद चिह्नक" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "बिचला डॉट" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "सेडिला" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "सुपरस्क्रिप्ट 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "आर्डिनल" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "दायाँ दोहरा कोण कोष्ठक" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "एक चौथाई" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "आधा" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "तीन चौथाई" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "उल्टा प्रश्न चिह्न" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a अधि" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A टिल्डे" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A रिंग" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C सेडिला" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "बार" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O स्ट्रोक" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "इससे विभाजित" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "बायाँ एकल उद्धरण" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "दायाँ एकल उद्धरण" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "एकल निम्न उद्धरण" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "बायाँ दोहरा उद्धरण" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "दायाँ दोहरा उद्धरण" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "दोहरा निम्न उद्धरण" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "डैगर" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "दोहरा डैगर" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "बुलेट" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "त्रिभुज बुलेट" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "प्राइम" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "दोहरा प्राइम" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "दोहरा प्राइम" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "योजन बुलेट" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "ट्रेडमार्क" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "जाँच चिह्न" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "भारी जाँच चिह्न" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-आकार के बुलेट" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "सुपरस्क्रिप्ट 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "सुपरस्क्रिप्ट 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "सुपरस्क्रिप्ट 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "सुपरस्क्रिप्ट 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "सुपरस्क्रिप्ट 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "सुपरस्क्रिप्ट 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "सुपरस्क्रिप्ट 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "सुपरस्क्रिप्ट प्लस" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "सुपरस्क्रिप्ट माइनस" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "सुपरस्क्रिप्ट बराबर है" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "सुपरस्क्रिप्ट बाएँ कोष्ठक" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "सुपरस्क्रिप्ट दाएँ कोष्ठक" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "सुपरस्क्रिप्ट n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "सबस्क्रिप्टॅ 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "सबस्क्रिप्टॅ 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "सबस्क्रिप्टॅ 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "सबस्क्रिप्टॅ 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "सबस्क्रिप्टॅ 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "सबस्क्रिप्टॅ 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "सबस्क्रिप्टॅ 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "सबस्क्रिप्टॅ 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "सबस्क्रिप्टॅ 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "सबस्क्रिप्टॅ 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "सबस्क्रिप्टॅ प्लस" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "सबस्क्रिप्टॅ माइनस" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "सबस्क्रिप्टॅ बराबर" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "सब्स्क्रिप्ट बायां पैरन" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "सब्स्क्रिप्ट दायां पैरन" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "काला वर्ग" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "काला हीरक" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "अगले वर्ण पर जाता है." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "वर्तमान अइटम के सूचक को दर्शाता हैं" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "मौजूदा फ्लैट रिव्यू मद पर बायें क्लिक करें" - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "मौजूदा फ्लैट रिव्यू मद पर दांयें क्लिक करें" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "पूर्ण दस्तावेज के बारे में बतायें" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "फ्लैट समीक्षा का प्रयोग नहीं हो." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "आधारभूत जहां मैं ऑपरेशन निष्पादित करता है." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "विस्तृत जहां मैं ऑपरेशन निष्पादित करता है." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "मौजूदा समतल रिव्यू पंक्ति के बारे में बोलता है" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "खाली पंक्ति बोलें" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "पिछले बटन पर जाता है." - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "स्थिति पट्टी बोलता है" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "शीर्षक पट्टी बोलता है" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Cthulhu खोज संवाद खोलें." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "स्ट्रिंग के अगले उदाहरण में खोजें" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "स्ट्रिंग के पिछले उदाहरण में खोजें" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "समतल रिव्यू मोड डालता व बाहर निकलता है." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "अंत स्थिति में समतल रिव्यू खिसकाता है." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "होम स्थिति में समतल रिव्यू खिसकाता है." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "अंत स्थिति में समतल रिव्यू खिसकाता है." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "पिछले पंक्ति के शुरू में फ्लैट रिव्यू खिसकाता है." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "मौजूदा समतल रिव्यू पंक्ति के बारे में बोलता है" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "वर्तमान फ्लैट समीक्षा लाइन बोलें" - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "ध्वन्यात्मकतापूर्वक मौजूदा फ्लैट समीक्षा लाइन लिखे." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "अगले पंक्ति के शुरू में समतल रिव्यू खिसकाता है." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "पिछला मद या शब्द में समतल रिव्यू खिसकायें." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "मौजूदा समतल रिव्यू मद या शब्द बोलता है." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "मौजूदा समतल रिव्यू मद या शब्द बोलता है." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "ध्वन्यात्मकतापूर्वक मौजूदा समतल रिव्यू मद या शब्द लिखे गए हैं." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "अगले मद या शब्द में फ्लैट रिव्यू खिसकाता है." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "मौजूदा शब्द के ऊपर समतल रिव्यू ले जायें." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "मौजूदा समतल रिव्यू के बारे में बोलें" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "मौजूदा शब्द के नीचे में समतल रिव्यू ले जायें." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "पिछले संप्रतीक में समतल रिव्यू ले जायें." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "मौजूदा समतल रिव्यू संप्रतीक के बारे में बोलें." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "ध्वन्यात्मकतापूर्वक मौजूदा फ्लैट समीक्षा वर्ण बोलता है." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "मौजूदा फ्लैट समीक्षा वर्ण का यूनिकोड मान बोलती है." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "अगले संप्रतीक में समतल रिव्यू ले जायें" - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "पंक्ति के अंत में फ्लैट रिव्यू खिसकाता है." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "नीचे बायीं ओऱ फ्लैट समीक्षा खिसकाएं" - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "फ्लैट की समीक्षा के तहत सामग्री क्लिपबोर्ड करने के लिए प्रतिलिपि बनाता है." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "फ्लैट समीक्षा के तहत क्लिपबोर्ड करने के लिए सामग्री को जोड़ देती है." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "अंत स्थिति में समतल रिव्यू खिसकाता है." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "टॉगल करता है कि क्या सिर्फ मौजूदा सारणी सेल या पूरी पंक्ति को पढ़ना है" - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "मौजूदा पाठ संप्रतीक के साथ जुड़ा गुण पढ़ें" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "बायीं ओर ब्रेल डिस्प्ले पैन करता है." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "दाहिनी ओर ब्रेल डिस्प्ले पैन करता है." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "कीबोर्ड फोकस के साथ वस्तु लौटाएं." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "संकुचित ब्रैल को चालू या बंद करें" - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "कर्सर अनुमार्गण कुंजी प्रबंध करें" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "एक पाठ चयन की प्रारम्भ को दर्शाता है." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "एक पाठ चयन की अंत में दर्शाता है." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "सीखना मोड दें. सीखना मोड से बाहर निकलने के लिए escape दबाएं." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "स्पीच दर घटाता है." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "स्पीच दर बढ़ाता है." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "स्पीच पिच घटाता है." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "भाषण पिच बढाता है." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "स्पीच दर बढ़ाता है." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "स्पीच दर घटाता है." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "इच्छित भाषण सर्वर चुनें." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "इच्छित भाषण सर्वर चुनें." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "स्पीच दर घटाता है." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "स्पीच दर बढ़ाता है." - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "वॉयस प्रकार सेटिंग्स" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "भाषण के मौनीकरण टॉगल करें" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "टॉगल करें माउस समीक्षा मोड." - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Cthulhu स्क्रीन वाचक" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "वरीयता विन्यास संवाद प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "अनुप्रयोग वरीयता विन्यास संवाद दिखाएँ." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "इंडेंटेशन और औचित्य के भाष को टॉगल करें." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "विराम चिह्न के स्तर के पास बोलने के लिए चक्र." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "अगले महत्वपूर्ण गूंज स्तर तक चक्र." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "अगले सेटिंग्स प्रोफाइल की चक्र." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "अगले पूंजीकरण शैली के लिए चक्र." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "अगले महत्वपूर्ण गूंज स्तर तक चक्र." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "रन टाइम पर डिबग स्तर चक्रीय करता है" - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "बुकमार्क करें जहां मैं मौजूदा स्थिति के संबंध के साथ हूँ." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "पिछले पुस्तचिह्न स्थान पर जाएँ." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "पुस्तचिह्न में जाएँ." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "अगले पुस्तचिह्न स्थान पर जाएँ." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "पुस्तचिह्न जोड़ें." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "पुस्तचिह्न सहेजें." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "टॉगल करें माउस समीक्षा मोड." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "वर्तमान मौजूदा समय ." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "वर्तमान मौजूदा दिनांक." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "मौजूदा अनुप्रयोग पर से अगले आदेश गुजरता है." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "पिछले चैट रूम संदेश के बारे में बोलें व ब्रेल करें" - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "टॉगल करें जब हम घोषणा करते है कि आपके बड्डीस टाइप कर रहे हैं." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "टॉगल करें जब आप चैट रूम में विशेष संदेश इतिहास प्रदान करते हैं." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "टॉगल करें कि क्या हमें चैट रूम संदेश को चैट रूम के नाम से उपसर्ग करना है." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "पंक्ति बायां" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "पंक्ति दाहिना" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "पंक्ति ऊपर" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "पंक्ति नीचे" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "स्थिर करें" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "ऊपरी बायाँ " - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "निचला बायाँ " - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "कर्सर स्थिति" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "छह बिन्दुएँ" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "कर्सर अनुमार्गण" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "कटौती शुरू करें " - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "लाइन कट" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr " वर्तमान अंतिम अधिसूचना संदेश." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "वर्तमान सूचना संदेश सूची" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "वर्तमान पिछले अधिसूचना संदेश." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr " वर्तमान अंतिम अधिसूचना संदेश." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "अगले वर्ण पर जाता है." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "पिछले वर्ण पर जाता है." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "अगले शब्द पर जाता है." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "पिछले शब्द पर जाता है." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "अगली पंक्ति में जाता है." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "पिछली पंक्ति में जाता है." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "फाइल के ऊपर में जाता है." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "फाइल के नीचे जाता है." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "पंक्ति के आरंभ में जाता है." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "पंक्ति के अंत में जाता है." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "अगली वस्तु पर जाता है." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "पिछली वस्तु पर जाता है." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "वर्तमान कॉम्बो बॉक्स का विस्तार होने का कारण बनता है." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "गेक्को देशी और ओर्का कैरट नेविगेशन के बीच स्विच करता हैं" - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "अग्रिम जीवित क्षेत्र सभ्यता सेटिंग" - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "डिफ़ॉल्ट जीवित क्षेत्र सभ्यता स्तर को दूर करने के लिए सेट करें." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "जीवित क्षेत्र की घोषणा की समीक्षा करें." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "मॉनीटर जीवंत क्षेत्र." - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "में और वर्तमान माउस से दूर पर ध्यान केंद्रित करता है." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "गतिशील स्तंभ शीर्ष लेखों के रूप में उपयोग करने के लिए पंक्ति निर्धारित करें." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "गतिशील स्तंभ शीर्ष लेखों को साफ करता है." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "गतिशील पंक्ति हेडर के रूप में उपयोग करने के लिए स्तंभ निर्धारित करें." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "गतिशील पंक्ति शीर्षिका साफ करें" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "इनपुट लाइन की सामग्री प्रस्तुत है." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "टॉगल करें संरचनात्मक नेविगेशन चाबियाँ." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "पिछले ब्लॉककोट को जाता है." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "अगले ब्लॉककोट को जाता है." - -#: src/cthulhu/cmdnames.py:852 -#, fuzzy -msgid "Display a list of blockquotes" -msgstr "ब्लॉक उद्धरण चिह्नों की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "पिछले बटन पर जाता है." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "पिछले बटन पर जाता है." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "बटन की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "पिछले जाँच पेटी पर जाता है." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "अगले जाँच पेटी पर जाता है." - -#: src/cthulhu/cmdnames.py:870 -#, fuzzy -msgid "Display a list of check boxes" -msgstr "चेक बॉक्स की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "पिछले तालिका में जाता है." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "अगले तालिका में जाता है." - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "तालिकाओं की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "पिछले कोंबो पेटी पर जाता है." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "अगले जाँच पेटी पर जाता है." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l समाहितकर्ता" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l समाहितकर्ता" - -#: src/cthulhu/cmdnames.py:901 -#, fuzzy -msgid "Display a list of combo boxes" -msgstr "कॉम्बो बक्सों की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "पिछली प्रविष्टि पर जाता है." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "अगली प्रविष्टि पर जाता है." - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "प्रविष्टियों की सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "पिछले फॉर्म क्षेत्र में जाता है." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "अगले फॉर्म क्षेत्र में जाता है." - -#: src/cthulhu/cmdnames.py:919 -#, fuzzy -msgid "Display a list of form fields" -msgstr "प्रपत्र फ़ील्ड की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "पिछले शीर्षक पर जाता है." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "अगले शीर्षक पर जाता है." - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "शीर्षकों की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "स्तर %d पर पिछले शीर्षक के लिए चला जाता है." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "स्तर %d पर पिछले शीर्षक के लिए चला जाता है." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "स्तर %d पर शीर्षकों की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "पिछले तालिका में जाता है." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/cmdnames.py:949 -#, fuzzy -msgid "Display a list of internal frames" -msgstr "तालिकाओं की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "पिछली पंक्ति में जाता है." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "अगली पंक्ति में जाता है." - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "तालिकाओं की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "पिछले लैंडमार्क पर जाता है" - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "अगले शीर्षक पर जाता है." - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "लिंक की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "पिछले बड़े वस्तु पर जाता है." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "अगले बड़ी वस्तु के लिए चला जाता है." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "बड़ी वस्तुओं की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "पिछली पंक्ति में जाता है." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "अगली पंक्ति में जाता है." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "लिंक की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "पिछली सूची पर जाता है." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "अगले सूची पर जाता है." - -#: src/cthulhu/cmdnames.py:1006 -#, fuzzy -msgid "Display a list of lists" -msgstr "सूची की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "पिछले सूची मद में जाता है." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "अगले सूची मद में जाता है." - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "सूची आइटम्स की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "पिछली जीवंत क्षेत्र में जाएँ" - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "अगले जीवंत क्षेत्र में जाता है." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "पिछला लाइव क्षेत्र है जो एक घोषणा के लिए चला जाता है." - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "डिबग के बारे में का वस्तु के साथ." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "कीबोर्ड फोकस के साथ वस्तु लौटाएं." - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "टॉगल करें संरचनात्मक नेविगेशन चाबियाँ." - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "पिछले अनुच्छेद में जाता है." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "अगले अनुच्छेद में जाता है." - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "पैराग्राफ की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "पिछले रेडियो बटन में जाता है." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "अगले रेडियो बटन में जाता है." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "Displays a list of radio buttons." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "पिछले विभाजक के लिए चला जाता है." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "अगले विभाजक के लिए चला जाता है." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "पिछले तालिका में जाता है." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "अगले तालिका में जाता है." - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "तालिकाओं की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "एक कोष्ठ नीचे जाता है." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "एक तालिका में पहले सेल करने के लिए चला जाता है." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "तालिका में अंतिम कोष्ठक पर जाता है." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "एक कोष्ठ बाएँ जाता है" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "एक कोष्ठ दाएँ जाते है" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "एक कोष्ठ ऊपर जाता है." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "टॉगल करें माउस समीक्षा मोड." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "कुंजी इको सक्षम करें (_k)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "अगले न देखे गए कड़ी पर जाएँ." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "अगले नहीं देखे देखे गए कड़ी पर जाएँ." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "भ्रमण किये लिंक की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "पिछले घूमे कड़ी पर जाता है." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "अगले घूमे कड़ी पर जाता है." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "दौरा लिंक की एक सूची प्रदर्शित करता है." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "संतृप्त नीला" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "काला" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "काला हीरक" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "संतृप्त नीला" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "संतृप्त नीला" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "a grave" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "संतृप्त हरा" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "संतृप्त हरा" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "संतृप्त लाल" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "संतृप्त हरा" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "संतृप्त नीला" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i grave" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "विसंतृप्त हरा" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "ग्रे" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "कोण" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "हिन्दी ग्रेड 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "दायां कोष्ठक" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "दायां कंट्रोल" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "दायां पैरन" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "दायां कोष्ठक" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "दायां पैरन" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "दायां पैरन" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "दायां आल्ट" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "दायां पैरन" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "दायाँ सुपर" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "दायाँ तीर " - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "न्यूलाइन" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "छवि" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "विसंतृप्त नीला" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "संतृप्त लाल" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "संतृप्त हरा" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "tre" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "संतृप्त नीला" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s स्क्रीन" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "विसंतृप्त नीला" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "विसंतृप्त नीला" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "btn" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "खाली स्थान" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "खाली स्थान" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "पूर्ण स्क्रीन" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "सक्रिय करें (_A)" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Dot _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Dot _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Dots 7 और 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "प्रतीक" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "कुछ नहीं" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "वर्तनी " - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "घोषणा करें जब आपके बड्डीस टाइप कर रहे हैं (_b)" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "कमरे विशिष्ट संदेश इतिहास चैट प्रदान करें (_m)" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "इससे संदेश बोलें" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "सभी चैनल" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "सभी चैनल जब कोई %s खिड़की सक्रिय है (_y)" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "एक चैनल अगर केवल इसका विंडो सक्रिय है" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "बोलें चैट कमरा नाम" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "डबल क्लिक" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "तिबारा क्लिक" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "तयशुदा सिंथेसाइज़र" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "वास्तविक स्ट्रिंग" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "बदला स्ट्रिंग" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "शब्द से इको सक्रिय करें (_r)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "संचरण कुंजी सक्रिय करें (_d)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "वर्तमान स्थान (_u)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "मिलान पाठ का न्यूनतम लंबाई:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "ढूंढें विकल्प" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "केवल खोजने के दौरान बदलें हुए लाइनों के बारें में बात करें (_y)" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "खोजने के दौरान परिणाम बोलो (_f)" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "विराम चिह्न" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "कुंजी बाइंडिंग" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "डिफ़ॉल्ट" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "लेखन मोड" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "खंड" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ब्रेल बाइंडिंग" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "पुस्तचिह्न सहेजें." - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "तारीख़ और समय" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "तालिका नेविगेशन" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "असीमित" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "फ्लैट समीक्षा छोड़कर." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "परिवर्धित" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "डेस्कटॉप (_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "अधिसूचना" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "अधिसूचना" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "ओरका वरीयताएं %s के लिये" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "ब्रेल में चिह्नित" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "अभी बेकार" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "बोलें" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "संघर्ष के रूप में प्रोफ़ाइल सहेजें" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "उपयोगकर्ता प्रोफ़ाइल संघर्ष!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"प्रोफ़ाइल% s पहले से ही मौजूद है.\n" -"इन नए परिवर्तनों के साथ मौजूदा प्रोफाइल की अद्यतन जारी?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "लोड करें उपयोगकर्ता प्रोफ़ाइल" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"आप सक्रिय प्रोफ़ाइल बदलने के बारे में हैं.यदि आप \n" -"सिर्फ अपनी वरीयताओं में परिवर्तन कर दिया है,\n" -" वे प्रोफाइल लोड पर गिरा दिया जाएगा.\n" -"\n" -"जारी प्रोफाइल छोड़ना सम्मिलित पिछले परिवर्तन लोड हो रहा है?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "के रूप में प्रोफ़ाइल सहेजें" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "प्रोफ़ाइल नामः (_P)" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "लोड करें उपयोगकर्ता प्रोफ़ाइल" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "सभी" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "विंडो" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "कुछ नहीं (_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "कुछ (_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "सर्वाधिक (_o)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "पंक्ति" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "वाक्य" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "ब्लॉककोट " - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "बटन" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "शीर्षक" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "चेक बक्सा" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "कॉम्बो बक्सा" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "वर्णन" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "शीर्षक" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "छवि" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "लेबल" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "ट्रेडमार्क" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "स्तर" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "लिंक " - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "सूची" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr " सूची मद" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "वस्तु" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "पैराग्राफ" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "रेडियो बटन" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "भूमिका" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "चयनित वस्तु" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "स्थिति" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "पाठ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "मान" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "ब्लॉक उद्धरण" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "बटन्स" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "जाँच पेटी" - -#: src/cthulhu/guilabels.py:706 -#, fuzzy -msgctxt "structural navigation" -msgid "Clickables" -msgstr "तालिकाएँ" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "कोंबो बाक्स" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "प्रविष्टियाँ" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "फ़ॉर्म क्षेत्र" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "शीर्षक " - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "छवि" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "स्तर %d पर शीर्षक" - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "ट्रेडमार्क" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "बड़ी वस्तुओं" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "लिंक्स" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "सूचियाँ" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "सूची मद" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "अनुच्छेद " - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "रेडियो बटन " - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "तालिकाएँ" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "अनदेखी कड़ियाँ " - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr " देखी कड़ियाँ" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "पृष्ठ नेविगेशन" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"स्वचालित रूप से एक पृष्ठ भाषी जब यह पहली बार लोड किया जाता है प्रारंभ करता हैं (_l)" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"स्वचालित रूप से एक पृष्ठ भाषी जब यह पहली बार लोड किया जाता है प्रारंभ करता हैं (_l)" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "विराम के बीच खंड में भाषण तोड़ो (_u)" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s तयशुदा आवाज" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "डिफ़ॉल्ट" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "हाइपरकड़ी" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "तंत्र" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "अपरकेस" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "भाषण डिस्पैचर" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "स्प्रैडशीट सेल निर्देशांक के बारें में बतायें " - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "कोष्ठ शीर्षिका घोषित करें" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "तालिका नेविगेशन" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "खाली कोष्ठ छोड़ें" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "बोलें सेल (_c)" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "सेल निर्देशांक बोलें" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "कई सेल स्पेन के बारे में बोलें (_m)" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "विशेषता नाम" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "ओरका हंसपद नेविगेशन का प्रयोग करें" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "टॉगल करें संरचनात्मक नेविगेशन चाबियाँ." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "संक्षिप्त (_f)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "अधिसूचना" -msgstr[1] "अधिसूचना" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "शिफ्ट" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "ऑल्ट" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "नियंत्रण" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "बायां शिफ्ट" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "बायां आल्ट" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "बायां कंट्रोल" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "दायां शिफ्ट" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "दायां आल्ट" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "दायां कंट्रोल" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "बायां मेटा" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "दायां मेटा" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "न्यूम लॉक" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "कैप्स लॉक" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "कैप्स लॉक" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "पृष्ठ ऊपर" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "पृष्ठ नीचे" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "बैकस्पेस" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "लौटाएँ" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "एंटर" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "ऊपर" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "नीचे" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "बायाँ" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "दायाँ" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "बायाँ सुपर" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "दायाँ सुपर" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "मेन्यू" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "मदद" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "बहु" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "मोड स्विच करें" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "एस्केप" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "घुसाएँ" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "मिटाएं" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "घर" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "अंत" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "शुरू करें" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "a परिवेष्टक" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "बज रहा हैं " - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "स्ट्रोक" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "ऋण" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "घुसाएँ" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "कैप्स बंद करें (_L)" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "सुपर" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "कंट्रोल" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "शिफ्ट" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "गाढ़ा" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "तिरछा" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr " सबस्क्रिप्टॅ %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr " सबस्क्रिप्टॅ %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "कार्यस्थान" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "संदर्भ है %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "बायाँ तीर " - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "तीर" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "दायाँ तीर " - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "तीर" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "दायाँ तीर " - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "दायाँ तीर " - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "दायाँ तीर " - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "बायाँ तीर " - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "बायाँ तीर " - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "दायाँ तीर " - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "बायाँ दोहरा उद्धरण" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "दोहरा डैगर" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "दायाँ दोहरा उद्धरण" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "दोहरा डैगर" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "दायाँ दोहरा उद्धरण" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "दाएँ ओर इशारा करते तीर" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "दाएँ ओर इंगित एरोहेड" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "ऋण" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "कम" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "से बड़ा" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "a परिवेष्टक" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "डॉट" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "लंबवत लॉगिन" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "क्षैतिज" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "स्वतः-पूर्ण" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "खाली" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "सक्षम" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "पंक्ति का अंत" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "उप" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "जोड़ या ऋण" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "जोड़" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "ऋण" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "विभाजक" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "घनमूल" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "समानुपातिक" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "अनंत" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "दायां आल्ट" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "एकल" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "स्तरित फलक" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "लंबवत लॉगिन" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "इससे विभाजित" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "विभाजक" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "इसके बराबर नहीं" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "तार्किक नहीं" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "तार्किक नहीं" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "दिशा" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "दोहरा प्राइम" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "समानुपातिक" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "ऋण" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "टिल्डे" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "लगभग इसके बराबर" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "लगभग इसके बराबर" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "लगभग इसके बराबर" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "लगभग इसके बराबर" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "लगभग इसके बराबर" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "लगभग इसके बराबर" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "तिबारा क्लिक" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "लगभग इसके बराबर" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "भिन्न साइट" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "इसके बराबर नहीं" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "समान होते है" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "समान होते है" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "इसके बराबर नहीं" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "इसके बराबर नहीं" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "त्रिभुज बुलेट" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "समान होते है" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "इसके बराबर नहीं" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "इसके बराबर नहीं" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "लंबवत" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "इसके बराबर नहीं" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "इसके बराबर नहीं" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "से बड़ा" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "नहीं दबाया गया" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "नहीं चयनित" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "सबस्क्रिप्टॅ 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "सुपरस्क्रिप्ट a" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "बहुल चयन" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "समायोजन" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "बहुल चयन" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "सबस्क्रिप्टॅ बराबर" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "en dash" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "सबस्क्रिप्टॅ प्लस" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "सबस्क्रिप्टॅ माइनस" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "दायां मेटा" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "left tab" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "नीचे" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "खंड" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "सही" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "सही" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "आर्डिनल" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "छवि" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "बहु" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "सामान्य" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "दायाँ एकल उद्धरण" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "दायां कोष्ठक" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "विभाजक" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "तार्किक नहीं" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "तार्किक नहीं" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "दोहरा प्राइम" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "दोहरा प्राइम" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "दिशा" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "दोहरा प्राइम" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "इससे कम या बराबर" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "से अधिक अथवा समान" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "लंबवत लॉगिन" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "बायां पैरन" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "दायां पैरन" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "बायां आल्ट" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "दायां आल्ट" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "बायां ब्रेस" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "नीचे" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "बायाँ दोहरा कोण कोष्ठक" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "दायाँ दोहरा कोण कोष्ठक" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "बिचला डॉट" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "खोजने की दिशा:" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "काला वर्ग" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "सफेद वर्ग" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "काला हीरक" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "सफेद वृत्त" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "काला वृत्त" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "सफेद बुलेट" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "काला वर्ग" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "रेखांकित" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "लंबवत लॉगिन" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "अनुप्रयोग " - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "खाली" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "गाढ़ा" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "पुस्तचिह्न दाखिल" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "पुस्तचिह्न सहेजा गया" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "पुस्तचिह्न सहेजा नहीं जा सका" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "कोई लैंडमार्क नहीं मिला" - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "कोई लैंडमार्क नहीं मिला" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "बाइपास मोड सक्षम." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "कैलकुलेटर प्रदर्शन प्राप्त करने में असमर्थ" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "प्रतीक" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "कैपिटलाइज़ेशन स्टाइल आइकन के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "कुछ नहीं" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "कैपिटलाइज़ेशन शैली कोई नहीं करने के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "वर्तनी " - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "कैपिटलाइज़ेशन शैली बोलने के लिये सेट करें" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "गेको हंसपद नियंत्रित कर रहा है." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "ओरका हंसपद नियंत्रित कर रहा है." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "कोष्ठक %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "चयनित" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "नहीं चयनित" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "अचयनित" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "विकल्प का प्रयोग रोकें" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "विकल्प के प्रयोग के लिए बाध्य करें" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "विकल्प" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "निम्नलिखित मान्य नहीं हैं:" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "ज्ञात चल रहे आवेदन मुद्रित करें" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "प्रोफ़ाइल लोड करें" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "प्रोफ़ाइल लोड नहीं किया जा सकता है:%s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "ओर्का प्रारंभ नहीं कर सकते क्योंकि यह डेस्कटॉप कनेक्ट नहीं हो पाया." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -#, fuzzy -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"एक और ओर्का प्रक्रिया पहले से ही इस सत्र के लिए चल रहा है.\n" -"प्रक्रिया की जगह एक नया से बदलने के लिए \"cthulhu --replace\" चलायें" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "नाम" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "उपयोगकर्ता वरीयताओं के लिए वैकल्पिक निर्देशिका का प्रयोग करें" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "ज्ञात चल रहे आवेदन मुद्रित करें" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "वर्तमान में चल रहे ओर्का को बदलें" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "इस मदद संदेश को दिखाएं" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "debug-YYYY-MM-DD-HH:MM:SS.out डिबग आउटपुट भेजें" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "निर्दिष्ट फ़ाइल डिबग आउटपुट भेजें" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "फ़ाइल " - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "सेट अप उपयोक्ता पाठ संस्करण" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "सेट अप उपयोक्ता पाठ संस्करण" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "https://groups.io/g/stormux में बग रिपोर्ट करें." - -#: src/cthulhu/messages.py:325 -#, fuzzy -msgid "Cut selection to clipboard." -msgstr "क्लिपबोर्ड पर सामग्री की नकल लें" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "अधि" - -#: src/cthulhu/messages.py:337 -#, fuzzy -msgid "Copied selection to clipboard." -msgstr "क्लिपबोर्ड पर सामग्री की नकल लें" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -#, fuzzy -msgid "Pasted contents from clipboard." -msgstr "क्लिपबोर्ड पर सामग्री की नकल लें" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "तेज." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "जब आपके बड्डीस टाइप कर रहे हैं की घोषणा नहीं करें" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "जब आपके बड्डीस टाइप कर रहे हैं की घोषणा करें" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "चैट कक्ष %s की ओर से संदेश" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "नया चैट टैब %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "चैट रूम नाम के बारे में मत बोलें." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "चैट रूम नाम के बारे में बोलें" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "कमरे विशिष्ट संदेश इतिहास चैट प्रदान नहीं करता है." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "कमरे विशिष्ट संदेश इतिहास चैट प्रदान करता है." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "चयनक संकेतक" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "मिटाएं" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "घुसाएँ" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "प्रश्न" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "तालिका के अंत में" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "सारणी में नहीं" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "नहीं चयनित" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "तयशुदा बटन %s है" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "तयशुदा बटन %s है" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "तयशुदा बटन %s है" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " सबस्क्रिप्टॅ %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " सुपरस्क्रिप्ट %s" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "सारणी में नहीं" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "पूर्ण दस्तावेज चयनित" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "पूर्ण दस्तावेज चयनित" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "कर्सर स्थिति से दस्तावेज चयनित" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "यनित से" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "कर्सर स्थिति से दस्तावेज चयनित" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "कर्सर स्थिति से दस्तावेज अचयनित" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "पंक्ति %d के लिए गतिशील स्तंभ हैडर सेट है" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "गतिशील कॉलम हेडर साफ किया." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "कॉलम %s के लिए गतिशील पंक्ति हेडर साफ किया." - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "गतिशील पंक्ति हेडर साफ किया." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "खाली" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f किलोबाइट" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f मेटाबेगाइट" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "कोई फाइल नहीं पाया गया." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "क्लिपबोर्ड पर संलग्न सामग्री" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "क्लिपबोर्ड पर सामग्री की नकल लें" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "फ्लैट समीक्षा का प्रयोग नहीं हो." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "फ्लैट समीक्षा में प्रवेश कर रहा है." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "फ्लैट समीक्षा छोड़कर." - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "मौजूदा शब्द के ऊपर समतल रिव्यू ले जायें." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "सूत्र रखता है" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "संवाद" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "पॉपअप मेन्यू" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "छवि मैप लिंक" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "कुंजी प्रविष्ट पहले से ही% s करने के लिए बाध्य किया जाता है" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "कुंजी कैप्चर्ड: %s. पुष्टि के लिए enter दबाएं." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "नयी कुंजी है: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "कुंजी बाइंडिंग नष्ट कर दिया. पुष्टि करने के लिए एंटर दबाएं." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "कीबाइंडिंग को हटा दिया गया है." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "नयी कुंजी दाखिल करें" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "कुंजी" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "प्रमुख गूंज कुंजी के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "कुछ नहीं" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "कुंजी गूंज कोई नहीं करने के लिए सेट है." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "कुंजी और शब्द" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "कुंजी गूंज कुंजी और शब्द के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "वाक्य" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "कुंजी गूंज वाक्य के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "शब्द" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "कुंजी गूंज शब्द के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "शब्द और वाक्य" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "कुंजी गूंज शब्द और वाक्य के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "काला वृत्त" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "क्षैतिज" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "लंबवत पट्टी" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "दायाँ तीर " - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "नीचे तक लपेट." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "पंक्ति ऊँचाई" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "और" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "ऊपर रेखांकित" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "वर्गमूल" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "घनमूल" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "रूट फलक" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "रूट फलक" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "रूट फलक" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "सबस्क्रिप्टॅ 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "सुपरस्क्रिप्ट a" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "सबस्क्रिप्टॅ 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "सुपरस्क्रिप्ट a" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "सुपरस्क्रिप्ट a" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "सुपरस्क्रिप्ट a" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "सारणी" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "ट्री-तालिका" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "अभिगम्य" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "अक्षम" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "खरोज और औचित्य विकलांग की बात हो रही है." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "सक्षम" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "खरोज और औचित्य सक्षम की बात हो रही है." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "सीखें मोड. निकलने के लिये एस्केप दबायें." - -#: src/cthulhu/messages.py:1201 -#, fuzzy -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"सीखने के मोड में प्रवेश कर रहा है. प्रेस किसी भी कुंजी को अपने कार्य में सुना है.ओर्का डिफ़ॉल्ट " -"शॉर्टकट की एक सूची प्राप्त करने के लिए, 1 दबाएँ.मौजूदा अनुप्रयोग के लिए ओर्का शॉर्टकट की " -"एक सूची प्राप्त करने के लिए, 2 दबाएँ. ओर्का प्रलेखन देखने के लिए, F1 दबाएँ.सीखने के मोड से " -"बाहर निकलने के लिए, Escape कुंजी दबाएं." - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "एनीमेशन" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "पृष्ठ नेविगेशन" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "तालिका नेविगेशन" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "फ्लैट समीक्षा छोड़कर." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "सारणी छोड़ रहा है." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "कर्सर स्थिति से नीचे पंक्ति चयनित" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "कर्सर स्थिति से पंक्ति चयनित" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "लाइन कर्सर स्थिति से नीचे अचयनित" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "लाइन कर्सर स्थिति से अचयनित" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "सीखें मोड से निकल रहा है." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "शुरू से पिछली कर्सर स्थिति पंक्ति चयनित" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "लाइन को पिछली कर्सर स्थिति से समाप्त करने के लिए चयनित" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "लिंक " - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "समान पृष्ठ" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "समान साइच" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "भिन्न साइट" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s कड़ी %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s कड़ी" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d देखा गया लिंक " - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"ऊपर और नीचे तीर का उपयोग करने के लिए सूची पर नेविगेट. बाहर निकलने के एस्केप दबाएं." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "सभी जीवित क्षेत्रों से दूर करने के लिए सेट" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "जीवित क्षेत्रों सभ्यता स्तर बहाल " - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "सभ्यता स्तर %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "मुखर जीवित क्षेत्र की स्थापना" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "बंद करने के लिए जीवित क्षेत्र की स्थापना" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "विनम्र जीवित क्षेत्र की स्थापना" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "अशिष्ट जीवित क्षेत्र की स्थापना" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "जीवंत क्षेत्र मॉनिटर बंद" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "जीवंत क्षेत्र मॉनिटर चालू" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "कोई जीवित संदेश नहीं सहेजा गया" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "लाइव क्षेत्र समर्थन बंद है" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "नहीं मिला" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "वर्तमान स्थान नहीं मिल सका." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "बंद" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "में" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "गलत वर्तनी" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "गलत वर्तनी वाला शब्द: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "संदर्भ है %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -#, fuzzy -msgid "Object mode." -msgstr "वस्तु" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "अगली वस्तु पर जाता है." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "वस्तु पर माउस नहीं मिला." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "माउस अक्षम." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "माउस संवर्द्धन सक्षम." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "त्रुटि: वस्तुओं की सूची बनाने के लिए नहीं किया जा सका." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d प्रतिशत. " - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "पिछले शब्द पर जाता है." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "नेस्टिंग स्तर %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "नया आइटम जोड़ दिया गया है" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "कोई अनुप्रयोग फोकस में नहीं" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "कोई फ़ोकस नहीं" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "कोई अनुप्रयोग फोकस में नहीं" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "कोई ब्लॉक उद्धरण चिह्नों नहीं" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "और अधिक बटन नहीं." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "कोई जाँच पेटी नहीं." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "कोई अधिक बड़ी वस्तुओं नहीं." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "और तालिका नहीं." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "कोई अधिक कोंबो बाक्स नहीं." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "और अधिक प्रविष्टि नहीं." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "और अधिक फ़ॉर्म क्षेत्र नहीं" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "कोई शीर्ष नहीं" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "स्तर %d में कोई अधिक शीर्षकों नहीं" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "और तालिका नहीं." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "कोई लैंडमार्क नहीं मिला" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "कोई अधिक लिंक नहीं." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "कोई अधिक सूची नहीं" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "और अधिक सूची मद नहीं." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "और जीवंत क्षेत्र नहीं" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "और अधिक अनुच्छेद नहीं." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "और रेजियो बटन नहीं है." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "कोई और अधिक विभाजक नहीं." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "और तालिका नहीं." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "कोई नहीं भेजा गया लिंक नहीं." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "और अधिक देखा गया लिंक नहीं." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "नहीं चयनित" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "कोई अधिक लिंक नहीं." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "अधिसूचना" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "नीचे" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "ऊपर" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "कोई सूचना संदेश नहीं" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "शब्द" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "शब्दों के रूप में बहु मामले स्ट्रिंग्स बोलें (_d)" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "बंद" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "में" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "लोड हो रहा है कृपया इंतजार करें." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "लोड पूर्ण." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "लोड पूर्ण %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "कर्सर स्थिति से पृष्ठ चयनित" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "कर्सर स्थिति से पृष्ठ चयनित" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "पृष्ठ कर्सर स्थिति से अचयनित." - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "पृष्ठ कर्सर स्थिति से अचयनित" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "कर्सर स्थिति से नीचे चयनित अनुच्छेद" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "कर्सर स्थिति से चयनित अनुच्छेद" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "कर्सर स्थिति से नीचे अचयनित अनुच्छेद" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "कर्सर स्थिति से अचयनित अनुच्छेद" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"आप पहले से ही एक ओर्का वरीयताओं खुले संवाद का एक उदाहरण है. \n" -"कृपया यह एक नया एक खोलने से पहले बंद कर दें." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "स्लाइड %(position)d %(count)d का" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "प्रोफ़ाइल %s में नियत है." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "कोई प्रोफ़ाइल नहीं पाया गया." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "प्रगति पट्टी %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "सभी" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "विराम चिह्न स्तर सभी के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "अत्यधिक" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "विराम चिह्न स्तर सबसे करने के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "कुछ नहीं" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "विराम चिह्न स्तर कोई नहीं करने के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "कोई" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "विराम चिह्न स्तर कोई के लिए निर्धारित किया है." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "खोज रहा है." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "खोज पूर्ण हुआ." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu उपयोक्ता जमावट फिर लोड की गई." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "चयनित वस्तु" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "पंक्ति हटा दी गई है." - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "चयनक संकेतक" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "अचयनित" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "भाषण निष्क्रिय." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "भाषण सक्रिय करें." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "तेज." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "धीमा." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "उच्चतर." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "निचला." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "तेज." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "दरः (_R)" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "आयतन (_l):" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "भाषण डिस्पैचर" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "भाषण डिस्पैचर" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "कोई सर्वर उपलब्ध नहीं.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "कोई ध्वनि उपलब्ध नहीं.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "भाषण सक्रिय करें." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "भाषण प्रयुक्त नहीं होगा.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "ओरका संस्करण %s." - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "ओरका हंसपद नियंत्रित कर रहा है." - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "बाइपास मोड सक्षम." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "भाषण है अनुपलब्ध." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "नहीं मिला" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "स्ट्रिंग नहीं मिला" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "स्ट्रिंग नहीं मिला" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "सरंचनात्मक संचरण बंद" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "सरंचनात्मक संचरण चालू" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "नहीं मिला" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "पंक्ति %(row)d, स्तंभ %(column)d. " - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "तालिका के अंत में" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "सेल से बोलो" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "पंंक्त बोलें ि" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "समरूप" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "सारणी में नहीं" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "स्तंभ पुनःनिर्दिष्ट" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr " पंक्तियाँ पुनःनिर्दिष्ट" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "कॉलम %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "स्तम्भ %(index)d %(total)d का" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "कॉलम के नीचे" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "कालम का शीर्ष" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "अचयनित" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "अचयनित" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "पंक्ति %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr " पंक्तियाँ %(index)d %(total)d का" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "पंक्ति की शुरूआत" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "पंक्ति का अंत" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "पंक्ति हटा दी गई है." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "अंतिम पंक्ति नष्ट कर दिया." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "पंक्ति सम्मिलित किया." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "पंक्ति तालिका के अंत में सम्मिलित किया." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "पंक्ति हटा दी गई है." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "अचयनित" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "चयनित" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "अचयनित" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H घंटा, %M मिनट और %S सेकण्ड." - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H घंटा और %M मिनट." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr " यूनिकोड %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "ओरका संस्करण %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "खाली स्थान" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "नीचे तक लपेट." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "ऊपर तक लपेट." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 मद" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "सेल स्पेन %d पंक्तियाँ" -msgstr[1] "सेल स्पेन %d पंक्तियाँ" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d स्तम्भ" -msgstr[1] " %d स्तम्भ" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "सेल स्पेन %d स्तम्भ" -msgstr[1] "सेल स्पेन %d स्तम्भ" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d वर्ण बहुत लंबा है." -msgstr[1] "%d वर्ण बहुत लंबा है." - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d संवाद)" -msgstr[1] "(%d संवाद)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d अनफोकस्ड संवाद" -msgstr[1] "%d अनफोकस्ड संवाद" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d बाइट" -msgstr[1] "%d बाइट" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d फाइल मिली" -msgstr[1] "%d फाइल मिली" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d फ़ॉर्म" -msgstr[1] "%d फ़ॉर्म" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d शीर्षक" -msgstr[1] "%d शीर्षक" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d वस्तु" -msgstr[1] "%d वस्तु" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "कोई लैंडमार्क नहीं मिला" -msgstr[1] "कोई लैंडमार्क नहीं मिला" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d मद मिली" -msgstr[1] "%d मद मिली" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "कोई ब्लॉक उद्धरण चिह्नों नहीं" -msgstr[1] "कोई ब्लॉक उद्धरण चिह्नों नहीं" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "फ्लैट समीक्षा छोड़कर." -msgstr[1] "फ्लैट समीक्षा छोड़कर." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "सूची के साथ %d मद" -msgstr[1] "सूची के साथ %d मद" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "सूची के साथ %d मद" -msgstr[1] "सूची के साथ %d मद" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "मान" -msgstr[1] "मान" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "तालिका के साथ %d पंक्ति" -msgstr[1] "तालिका के साथ %d पंक्ति" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d स्तम्भ" -msgstr[1] "%d स्तम्भ" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "तालिका के साथ %d पंक्ति" -msgstr[1] "तालिका के साथ %d पंक्ति" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d संदेश.\n" -msgstr[1] "%d संदेश.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d प्रतिशत. " -msgstr[1] "%d प्रतिशत." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d प्रतिशत का दस्तावेज़ पढ़ें" -msgstr[1] "%d प्रतिशत का दस्तावेज़ पढ़ें" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "पिक्सेल्स" -msgstr[1] "पिक्सेल्स" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s अक्षर" -msgstr[1] "%(count)d %(repeatChar)s अक्षर" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d of %(total)d मद चयनित" -msgstr[1] "%(index)d of %(total)d मद चयनित" - -#: src/cthulhu/messages.py:2793 -#, fuzzy, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d ओर्का डिफ़ॉल्ट शॉर्टकट पाया." -msgstr[1] "%d ओर्का डिफ़ॉल्ट शॉर्टकट पाया." - -#: src/cthulhu/messages.py:2801 -#, fuzzy, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d ओर्का शॉर्टकट पाया %(application)s के लिए" -msgstr[1] "%(count)d ओर्का शॉर्टकट पाया %(application)s के लिए" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d स्थान" -msgstr[1] "%d स्थान" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d टैब" -msgstr[1] "%d टैब" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d तालिका" -msgstr[1] "%d तालिकाएँ" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "तालिका के साथ %d पंक्ति" -msgstr[1] "तालिका के साथ %d पंक्ति" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%d पंक्ति और %d कॉलम के साथ सारणी." -msgstr[1] "%d पंक्ति और %d कॉलम के साथ सारणी." - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "तालिका के साथ %d पंक्ति" -msgstr[1] "तालिका के साथ %d पंक्ति" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "सेकण्ड" -msgstr[1] "सेकण्ड" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%dन घूमा लिंक" -msgstr[1] "%d न घूमा लिंक" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d देखा गया लिंक " -msgstr[1] "%d देखा गया लिंक " - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "टॉगल करें" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "on %(index)d %(total)d का" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d %(total)d का" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "स्तर %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ट्री स्तर %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "तरू स्तर %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "प्रश्न" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "अगले जाँच पेटी पर जाता है." - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html सामग्री" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "शब्द" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "कॉलन" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "ऊपर रेखांकित" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "दिशा" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "अनुच्छेद" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "शब्द" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "हाशिया" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "दिशा" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "टैब सूची" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "उद्धरण" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "html सामग्री" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s level %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "क्षैतिज" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "लंबवत पट्टी" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "क्षैतिज" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "लंबवत लॉगिन" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "क्षैतिज" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "लंबवत लॉगिन" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "मोड स्विच करें" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "प्रतीक पटल" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "html सामग्री" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "एनीमेशन" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "html सामग्री" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "एनीमेशन" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "खोज रहा है." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d देखा गया लिंक " - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "स्पिन बटन" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "गिर गया" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "विस्तारित" - -#: src/cthulhu/object_properties.py:511 -#, fuzzy -msgid "has long description" -msgstr "वर्णन" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "क्षैतिज" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "लंबवत" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "जांचा गया" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "नहीं जांचा गया" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "में" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "बंद" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "आंशिक जांचा गया" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "दबाया गया" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "नहीं दबाया गया" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "नहीं चयनित" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "चयनित" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "नहीं चयनित" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "नहीं चयनित" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "देखा गया" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "अनदेखी" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ग्रे" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "केवल पठनीय" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "rdonly" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "जरूरी" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "बहुल चयन" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "वर्तनी" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "वर्तनी" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "ढूंढें" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "स्क्रीन वाचक" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "बंद करें" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "ढूंढें" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "के लिए खोजें (_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "के लिए ढूंढें:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "विंडो का शीर्ष (_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "विंडो का शीर्ष" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "इससे आरंभ:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "चारो ओर लपेटें (_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "पीछे से ढूंढें (_b)" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "खोजने की दिशा:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "मिलान स्थिति (_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "केवल पूर्ण शब्द जोड़ मिलाएं (_e)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "ढूंढें विकल्प" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "डिफ़ॉल्ट" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "अपरकेस" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "हाइपरकड़ी" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "तंत्र" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "विंडो" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu वरीयताएं" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "लैपटॉप (_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "कुंजीपट ख़ाका" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "सक्रिय प्रोफाइल: (_P)" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "आरंभ प्रोफ़ाइलः" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "लोड करें (_L)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -#, fuzzy -msgid "Save _As" -msgstr "के रूप में प्रोफ़ाइल सहेजें" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "प्रोफ़ाइल" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "मौजूदा टूलटिप" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Speak object under mo_use" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "माउस" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "समय प्रारूप: (_T)" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "दिनांक स्वरूप: (_e)" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "तारीख़ और समय" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "बोलें सभी" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "ब्रेल संकेतक" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "आवृत्ति (secs):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "अनुप्रयोग" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "प्रगति बार अद्यतन" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "टॉगल करें संरचनात्मक नेविगेशन चाबियाँ." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "सभी कहते हैं: (_y)" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "सभी कहते हैं: (_y)" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "सामान्य" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "आयतन (_l):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "पिच (_t):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "दरः (_R)" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "व्यक्ति (_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "भाषा" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "भाषण संश्लेषक (_z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "भाषण सिस्टम (_s):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "वॉयस प्रकार (_V):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -#, fuzzy -msgid "_Capitalization style:" -msgstr "कैपिटलाइज़ेशन स्टाइल आइकन के लिए निर्धारित किया है." - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "वॉयस प्रकार सेटिंग्स" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "शब्दों के रूप में बहु मामले स्ट्रिंग्स बोलें (_d)" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "वैश्विक आवाज सेटिंग्स" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "आवाज़" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "सक्षम वाणी (_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "बर्बोस (_b)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "बर्बोसिटी" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "सभी (_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "विराम चिह्न स्तर " - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "केवल प्रदर्शित पाठ बोलें" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "खाली पंक्ति बोलें" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "हाशिया व संरेखण बोलें (_i)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "वस्तु के स्मरणोकारी बोलें (_k)" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "बच्चे की स्थिति बोलें" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "ट्यूटोरियल संदेश से बोलो" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "सेल निर्देशांक बोलें" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "सेल निर्देशांक बोलें" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "वर्णन" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "बोलचाल प्रसंग" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "भाषण" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "ब्रेल मॉनिटर सक्षम करें (_s)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "संक्षिप्तीकृत भूमिका नाम (_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "पंक्ति संकेत का अंत निष्क्रिय करें (_e)" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "संकुचन तालिका:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "संकुचित ब्रैल सक्षम करें" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "शब्द से इको सक्रिय करें (_w)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "प्रकटन विन्यास" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "कुछ नहीं (_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "चयनक संकेतक" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "हाइपरलिंक संकेतक" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "सक्षम आवर्धक (_m)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "वैश्विक आवाज सेटिंग्स" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ब्रेल" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "कुंजी इको सक्षम करें (_k)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "संचरण कुंजी सक्रिय करें (_n)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "रूपांतरक कुंजी सक्रिय करें (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "फंक्शन कुंजी सक्रिय करें (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "सक्षम वाणी (_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "रूपांतरक कुंजी सक्रिय करें (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "फंक्शन कुंजी सक्रिय करें (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "क्रिया कुंजी सक्रिय करें (_t)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "संचरण कुंजी सक्रिय करें (_n)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "शब्द से इको सक्रिय करें (_w)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "वाक्य द्वारा प्रतिध्वनि सक्षम करें" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "कुंजी इको" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Cthulhu रूपांतरक कुंजी (_M):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "की बाइंडिंग" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "उच्चारण शब्दकोश" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "नई प्रविष्टि" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "मिटाएँ (_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "उच्चारण" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "बोलें सभी" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "बोलें कुछ नहीं" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "रिसेट करें (_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "टेक्स्ट् ऐट्रिब्यूट्स" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "नीच खिसकें" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "एक नीचे जाएँ" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "एक ऊपर जाएँ" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "ऊपर खिसकें" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "चयनित विशेषताओं समायोजित" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "ब्रेल संकेतक" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "टेक्स्ट् ऐट्रिब्यूट्स" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "सहायक" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "निम्न" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "सहायक" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "भाषा" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "येन" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "मापक कारक (_f):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -#, fuzzy -msgid "Copy Results to _Clipboard" -msgstr "क्लिपबोर्ड पर सामग्री की नकल लें" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "पृष्ठभूमि रंग" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "पृष्ठभूमि पर्ण ऊंचाई" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "पृष्ठभूमि स्टिपल" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "दिशा" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "संपादनयोग्य" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "फरिवार नाम" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "अग्रभूमि रंग" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "अग्रभूमि स्टिपल" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "फॉन्ट प्रभाव" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "हाशिया" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "गलती" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "अदृश्य" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "समायोजन" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "भाषा" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "बायाँ हाशिया" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "पंक्ति ऊँचाई" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "अनुच्छेद शैली" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "पिक्सेल्स पंक्तियां पर" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "पिक्सेल्स पंक्तियां के नीचे" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "पिक्सेल लपेट के अंदर" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "दायाँ हाशिया" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "बढ़ाएँ" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "स्केल" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "आकार" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "खींचें" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "आर पार काटें" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "शैली" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "पाठ सजावट" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "पाठ घुमाव" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "पाठ छाया" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "रेखांकित" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "चर" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "लंबवत लॉगिन" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "भार" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "लपेट विधि" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "लेखन मोड" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "सही" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "गलत" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "कुछ नहीं" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "पच्चीकारी" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "उभार कर लिखें" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "रूपरेखा" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "ऊपर रेखांकित" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "लकीर के जरिए" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "ब्लिंक" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "काला" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "एकल" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "डबल" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "निम्न" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "चार" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "शब्द" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "शब्द चार" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "बायाँ" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "दायाँ" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "बीच में" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "no justification" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "भरें" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "बहुत संघनित" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "अति संघन" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "सघन" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "अर्ध कंडेन्स" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "सामान्य" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "अर्द्ध विस्तारित" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "विस्तारित" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "अति विस्तारित" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "अल्ट्रा विस्तारित" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "छोटा कैप्स" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "तिर्यक" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "तिरछा" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "डिफ़ॉल्ट" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "पाठ शरीर" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "शीर्षक" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "बेसलाइन" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "उप" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "सुपर" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "ऊपर" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "पाठ ऊपर" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "बिचला" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "नीचे" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "पाठ नीचे" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "विरासत में मिला" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "ठोस" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "वर्तनी" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "दबाएँ स्थान को टॉगल करें." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"विस्तार करने के लिए, और का उपयोग करें और नीचे एक आइटम का चयन करने के लिए पस्पेस दवाएं" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "चाइल्ड विंडो पर ध्यान केंद्रित करने के लिए Alt + F6 दवाएँ " - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "आइटम के लिए ले जाने के लिए, या तो तीर कुंजी या प्रकार आगे खोज का उपयोग करें." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "प्रणाली मेनू के लिए Alt + F1 कुंजी दबाएँ." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "ऊपर और नीचे का प्रयोग करें एक आइटम का चयन करने के लिए." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "पतन करने के लिए, शिफ्ट प्लस बाएं दबाएँ." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "विस्तार करने के लिए, शिफ्ट प्लस दाएँ दबाएँ." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "वापस सक्रिय करने के लिए दबाएँ" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "पाठ में टाइप करें" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "उपयोग बायाँ और दायाँ अन्य टैब देखने के लिए." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "स्थान सक्रिय करने के लिए दबाएँ" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "का प्रयोग करें या नीचे तीर मान का चयन. या वांछित संख्यात्मक मूल्य में प्रकार." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "तीर कुंजियों का उपयोग बदलने के लिए." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"नेविगेट करने के लिए, छोड़ दिया है या सही तीर दबाएँ.मदों के माध्यम से स्थानांतरित प्रेस या " -"नीचे तीर." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "उप मेनू में प्रवेश करने के लिए, दाएँ तीर दबाएँ." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"प्रेस बाएँ तीर को कम करने के लिए, प्रेस सही तीर बढ़ाने.न्यूनतम प्रेस घर के लिए जाना है, और " -"अधिकतम प्रेस अंत के लिए." diff --git a/po/hr.po b/po/hr.po deleted file mode 100644 index 1831506..0000000 --- a/po/hr.po +++ /dev/null @@ -1,9279 +0,0 @@ -# Croatian translation for gnome-cthulhu -# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 -# This file is distributed under the same license as the gnome-cthulhu package. -# FIRST AUTHOR , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: gnome-cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2019-09-26 22:11+0100\n" -"Last-Translator: yvonimir stanecic \n" -"Language-Team: Croatian \n" -"Language: hr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Launchpad-Export-Date: 2016-09-15 12:40+0000\n" -"X-Generator: Poedit 1.6.10\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu čitač zaslona" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "čitač zaslona;govor;brajica;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "upoz." - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim." - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "v.strel." - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal." - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "plat." - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "natp." - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "pot.okv." - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "izb.boj." - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "zag.stup." - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "odab.okv." - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat." - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "iko." - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "okv." - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "bir." - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dij." - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "o.dir." - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "crt." - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "izb.datot." - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "pun." - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fon." - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "obraz." - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "proz.o." - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "nasl." - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "slik." - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "unu.okv." - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "ozn." - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "sloj.p." - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "l." - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "pop." - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "sta.pop." - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "izb." - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "t.izb." - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "sta.izb." - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "o.mog." - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "str.kar." - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "pop.kar." - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "plo." - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "zap." - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "isk.izb." - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "t.nap." - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "g." - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rad.sta.izb." - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "kor.p." - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "zag.r." - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "kliz.t." - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "kliz.o." - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "pogl." - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "rast." - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "kliz." - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "o.odv." - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "rot." - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "stat.t." - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tabl." - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "ćel." - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "otk.izb." - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term." - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "teks." - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "g.preb." - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "alat.t." - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "alat.sav." - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "stab." - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tab.stab." - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "nep." - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "poj.pog." - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "pro." - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "zag." - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pod." - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "odl." - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "aplik." - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "automatski" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "t.uređ." - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "ugr." - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Češki standardna brajica" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Španjolski standardna brajica" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francuski Kanada kratkopis" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francuski Francuska kratkopis" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvijski standardna brajica" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Nizozemska Nizozemski standardna brajica" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norveški stupanj 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norveški standardna brajica" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norveški kratkopis" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norveški stupanj 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Poljski standardna brajica" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugalski standardna brajica" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Švedski standardna brajica" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arapski standardna brajica" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Velški standardna brajica" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Velški kratkopis" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Njemački stupanj 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Njemački standardna brajica" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Njemački kratkopis" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Britanski engleski kratkopis" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Britanski engleski standardna brajica" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Američki engleski standardna brajica" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Američki engleski kratkopis" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadski francuski standardna brajica" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francuska francuski standardna brajica" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grčki standardna brajica" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindski standardna brajica" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Mađarski 8-točkasta kompjutorska" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Mađarski standardna brajica" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Mađarski standardna brajica" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Talijanski standardna brajica" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgija nizozemski standardna brajica" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "razmak" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "novi redak" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulator" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "uskličnik" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "navodnik" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "broj" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "posto" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "i" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "izostavnik" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "lijeva zagrada" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "desna zagrada" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "zvjezdica" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "zarez" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "povlaka" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "točka" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "kosa crta" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dvotočka" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "točka zarez" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "manje" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "jednako" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "veće" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "upitnik" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "pri" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "lijeva uglata" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "obrnuta kosa crta" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "desna uglata" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "znak za umetanje" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "potcrtano" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "akcent" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "lijeva vitičasta" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "okomita crta" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "desna vitičasta" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "razmak bez prekida" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "obrnuti uskličnik" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centi" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "funti" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "znak za valutu" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "isprekidana crta" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "odlomak" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "autorska prava" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "eksponent a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "otvoreni navodnici" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logično ne" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "meka crtica" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registracija" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "makron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "stupnjeva" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus ili minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "eksponent 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "eksponent 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "akut" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "oznaka odlomka" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "srednja točka" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedila" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "eksponent 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "redni broj" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "zatvoreni navodnici" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "jedna četvrtina" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "jedna polovina" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tri četvrtine" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "obrnuti upitnik" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a akute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAV" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AKUT" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDA" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAV" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AKUT" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAV" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AKUT" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDA" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAV" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AKUT" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDA" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "puta" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O POTEZ" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAV" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AKUT" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AKUT" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "BODLJA" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s oštro" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grav" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a cirkumfleks" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilda" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedila" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grav" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e akut" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e cirkumfleks" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grav" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i akut" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i cirkumfleks" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilda" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grav" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o akut" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o cirkumfleks" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilda" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "podijeljeno sa" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o potez" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "bodlja" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u akut" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grav" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u cirkumfleks" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y akut" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en crtica" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "lijevi jednostruki navodnik" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "desni jednostruki navodnik" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "jednostruki spušteni navodnik" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "lijevi dvostruki navodnik" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "desni dvostruki navodnik" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dvostruki spušteni navodnik" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "bodež" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dvostruki bodež" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "kružić" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trokutasti kružić" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promili" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "glavni" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "dvostruki glavni" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "trostruka crta" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "Crtica kružić" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "proizvođač" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "kvačica" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "teška kvačica" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-uobličeni kružić" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "eksponent 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "eksponent 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "eksponent 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "eksponent 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "eksponent 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "eksponent 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "eksponent 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "eksponent plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "eksponent minus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "eksponent jednako" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "eksponent lijeva zagrada" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "eksponent desna zagrada" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "eksponent n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "indeks 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "indeks 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "indeks 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "indeks 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "indeks 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "indeks 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "indeks 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "indeks 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "indeks 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "indeks 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "indeks plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "indeks minus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "indeks jednako" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "indeks lijeva zagrada" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "indeks desna zagrada" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "crni kvadrat" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "crni dijamant" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "znak zamjene objekta" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Usmjerava pokazivač na trenutnu stavku." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Vrši lijevi klik na trenutnu stavku fiksnog prikaza." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Vrši desni klik na trenutnu stavku fiksnog prikaza." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Izgovara cijeli dokument." - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Izgovara cijeli prozor koristeći pregled ekrana." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Izvršava osnovnu operaciju Gdje Sam." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Izvršava detaljnu operaciju Gdje Sam." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Izgovara trenutno označeno." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "izgovara detalje o poveznici." - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Prikaži zadani gumb" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Izgovara statusnu traku." - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Izgovara naslovnu traku." - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Otvara dijalog traženja." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Traži sljedeću pojavu niza znakova." - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Traži prethodnu pojavu niza znakova." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Ulazi i izlazi iz načina fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Premiješta fiksni pregled na krajnji položaj." - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Premiješta fiksni pregled na početni položaj." - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Premiješta fiksni pregled na krajnji položaj." - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Premiješta fiksni pregled na početak prethodnog retka." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Izgovara trenutni redak fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Slovka trenutni redak fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Fonetski slovka trenutni redak fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Premiješta fiksni pregled na početak sljedećeg retka." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Premiješta fiksni pregled na prethodnu stavku ili riječ." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Izgovara trenutnu stavku ili riječ fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Slovka trenutnu stavku ili riječ fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Fonetski slovka trenutnu stavku ili riječ fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Premiješta fiksni pregled na sljedeću stavku ili riječ." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Premiješta fiksni pregled na riječ iznad trenutne riječi." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Izgovara trenutni objekt fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Premiješta fiksni pregled na riječ ispod trenutne riječi." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Premiješta fiksni pregled na prethodni znak." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Izgovara trenutni znak fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Fonetski izgovara trenutni znak fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Izgovara unicode vrijednost za trenutni znak fiksnog pregleda." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Premiješta fiksni pregled na sljedeći znak." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Premiješta fiksni pregled na kraj retka." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Premiješta fiksni pregled dolje lijevo." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Kopira sadržaj pod fiksnim pregledom u međuspremnik." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Dodaje sadržaj pod fiksnim pregledom u međuspremnik." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Premiješta fiksni pregled na krajnji položaj." - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Naizmjence uključuje da li će se čitati samo trenutna ćelija tablice ili " -"cijeli red." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Čita atribute povezane s trenutnim znakom teksta." - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Pomiče brajični prikaz u lijevo." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Pomiče brajični prikaz u desno." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Vraća na objekt sa tipkovničkim fokusom." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Uključuje ili isključuje brajicu na kratkopisu." - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Procesuira tipku za usmjerenje kursora." - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Označava početak odabira teksta." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Označava kraj odabira teksta." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Ulazi u način učenja. Pritisnite tipku Escape za izlaz iz načina učenja." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Smanjuje brzinu govora." - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Povećava brzinu govora." - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Smanjuje visinu govora." - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Povećava visinu govora." - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Povečava glasnoću govora." - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Smanjuje glasnoću govora." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Traži prethodnu pojavu niza znakova." - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Prebacuje na sljedeći profil postavki." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Izgovara trenutno označeno." - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Izgovara trenutno označeno." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Postavke za vrstu glasa" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Naizmjence uključuje utišavanje govora." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Mijenja razinu opširnosti govora." - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Naizmjence uključi način pregleda miša." - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Zatvara čitač zaslona" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Prikazuje dijalog podešavanja postavki." - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Prikazuje dijalog podešavanja postavki za aplikaciju." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Mijenja izgovor uvlaka i poravnanja." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Mijenja stil izgovora brojeva." - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Prebacuje na sljedeću razinu izgovora interpunkcije." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Prebacuje na sljedeću razinu odjeka tipkovnice." - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Prebacuje na sljedeći profil postavki." - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Prebacuje na sljedeći način pisanja velikih slova." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Prebacuje na sljedeću razinu odjeka tipkovnice." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Prebacuje razinu uklanjanja pogrešaka u trenutku izvođenja." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Oznaka za Gdje sam s obzirom na trenutni položaj." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Idi na prethodno mjesto oznake." - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Idi na oznaku." - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Idi na sljedeće mjesto oznake." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Dodaj oznaku." - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Spremi oznake." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Naizmjence uključi način pregleda miša." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Sadašnje trenutno vrijeme." - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Sadašnji tekući datum." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Predočuje veličinu i položaj trenutnog objekta." - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Prosljeđuje sljedeću naredbu trenutnoj aplikaciji." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Izgovori i prikaži na brajici prethodnu poruku u sobi za čavrljanje." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" -"Naizmjence uključi hoćemo li najavljivati kada naši prijatelji tipkaju." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Naizmjence uključi hoćemo li pružati povijesti poruka za navedene sobe za " -"čavrljanje." - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Naizmjence uključi hoćemo li staviti prefiks sa nazivom sobe za čavrljanje " -"uz poruke u sobama za čavrljanje." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Redak lijevo" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Redak desno" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Redak gore" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Redak dolje" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Zamrzni se" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Gore lijevo" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Dolje lijevo" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Položaj pokazivača" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Šest točkica" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Usmjeravanje kursora" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Početak rezanja" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Izreži redak" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Prikaži zadnju poruku obavijesti." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Prikaži popis poruka obavijesti" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Prikaži prethodnu poruku obavijesti." - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Prikaži zadnju poruku obavijesti." - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Ide na sljedeći znak." - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Ide na prethodni znak." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Ide na sljedeću riječ." - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Ide na prethodnu riječ." - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Ide na sljedeći redak." - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Ide na prethodni redak." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Ide na početak datoteke." - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Ide na kraj datoteke." - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Ide na početak retka." - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Ide na kraj retka." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Ide na sljedeći objekt." - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Ide na prethodni objekt." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Izaziva trenutni odabirni okvir da se proširi." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Prebacuje između prirodnog i čitač-zaslona kretanja sistemskog kursora." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Unaprijedi postavku uglađenosti žive regije." - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Postavi zadanu razinu postavke uglađenosti žive regije na isključeno." - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Pregledaj najavu žive regije." - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Očitaj žive regije." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Premiješta fokus na i dalje od trenutnog objekta oko kojeg kruži miš." - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Postavi redak koji se koristi kao dinamička zaglavlja stupca." - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Briše dinamička zaglavlja stupca." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Postavi stupac koji se koristi kao dinamička zaglavlja redova." - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Briše dinamička zaglavlja redaka" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Prikazuje sadržaj polja za unos." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Naizmjence uključuje tipke strukturne navigacije." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Ide na prethodni citat." - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Ide na sljedeći citat." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Prikazuje popis citata." - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Ide na prethodni gumb." - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Ide na sljedeći gumb." - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Prikazuje popis gumbi." - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Ide na prethodni potvrdni okvir." - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Ide na sljedeći potvrdni okvir." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Prikazuje popis potvrdnih okvira." - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Ide na prethodni klikajući objekt." - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Ide na sljedeći klikajući objekt." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Prikazuje popis klikajućih objekata." - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Ide na prethodni odabirni okvir." - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Ide na sljedeći odabirni okvir." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Premješta na početak sadrživača." - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Premješta na kraj sadrživača." - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Prikazuje popis odabirnih okvira." - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Ide na prethodno polje za unos." - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Ide na sljedeće polje za unos." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Prikazuje popis polja za unos." - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Ide na prethodno polje obrasca." - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Ide na sljedeće polje obrasca." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Prikazuje popis polja obrasca." - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Ide na prethodni naslov." - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Ide na sljedeći naslov." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Prikazuje popis naslova." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Ide na prethodni naslov na %d razini." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Ide na sljedeći naslov na %d razini." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Prikazuje popis naslova na %d razini." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Ide na prethodnu tablicu." - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Ide na sljedeću tablicu." - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Prikazuje popis tablica." - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Ide na prethodnu sliku." - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Ide na sljedeću sliku." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Prikazuje popis slika." - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Ide na prethodni orijentir." - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Ide na sljedeći orijentir." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Prikazuje popis orijentira." - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Ide na prethodni veliki objekt." - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Ide na sljedeći veliki objekt." - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Prikazuje popis velikih objekata." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Ide na prethodnu poveznicu." - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Ide na sljedeću poveznicu." - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Prikazuje popis poveznica." - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Ide na prethodni popis." - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Ide na sljedeći popis." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Prikazuje popis popisa." - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Ide na prethodni popisni element." - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Ide na sljedeći popisni element." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Prikazuje popis popisnih elemenata." - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Ide na prethodnu živu regiju." - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Ide na sljedeću živu regiju." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Ide na zadnju najavljenu živu regiju." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Idi na roditelja objekta s fokusom navigatora." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Idi na prvo dijete objekta s fokusom navigatora." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Idi na sljedećeg brata objekta s fokusom navigatora." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Idi na prethodnog brata objekta s fokusom navigatora." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Vraća na objekt sa tipkovničkim fokusom." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Naizmjence uključuje tipke strukturne navigacije." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Ide na prethodni odlomak." - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Ide na sljedeći odlomak." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Prikazuje popis odlomaka." - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Ide na prethodni radio gumb." - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Ide na sljedeći radio gumb." - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Prikazuje listu radio gumbi." - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Ide na prethodni rastavljač." - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Ide na sljedeći rastavljač." - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Ide na prethodnu tablicu." - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Ide na sljedeću tablicu." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Prikazuje popis tablica." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Ide za jednu ćeliju dolje." - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Ide na prvu ćeliju u tablici." - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Ide na zadnju ćeliju u tablici." - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Ide za jednu ćeliju ulijevo." - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Ide za jednu ćeliju udesno." - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Ide za jednu ćeliju gore." - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Uključuje ili isključuje način pregleda." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Prebacuje između načina surfanja i načina fokusa." - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Omogućuje ljepljivi način fokusa." - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Omogućuje ljepljivi način pregleda." - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Ide na prethodni neposjećenu poveznicu." - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Ide na sljedeći neposjeću poveznicu." - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Prikazuje popis neposjećenih poveznica." - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Ide na prethodni posjećenu poveznicu." - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Ide na sljedeći posjećenu poveznicu." - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Prikazuje popis posjećenih poveznica." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "blijedo plava" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "starinski bijela" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarin" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "nebesko modrilo" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "bež boja" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "crna" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "blijedi badem" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "plava" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "plavo ljubičasta" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "smeđa" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadet plava" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "čokolada" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koralj" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "različak plava" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "svilenasta" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "tamnocrvena" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cijan" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "tamno plava" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "tamnocijan" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "tamno zlatni štap" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "tamno siva" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "tamno zelena" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "tamno žutomrka" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "tamno magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "tamno maslinasto zelena" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "tamnonarančasta" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "tamno orhideja" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "tamno crvena" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "tamno losos" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "tamno zeleno more" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "tamno plava škriljevca" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "tamno sive boje škriljevca" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "tamno tirkizna" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "tamno ljubičasta" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "duboko ružičasta" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "duboko plavo nebo" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "Dim siva" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "Dodger plava" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "vatrostalna opeka" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "cvjetno bijela" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "šumsko zelena" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksija" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "sablasno bijela" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "zlatna" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "zlatni štap" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "siva" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "zelena" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "zeleno žuta" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "medljika" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "vruće ružičasta" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "Indijski crvena" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "bjelokosti" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "žutomrka boja" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavanda rumenilo" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "zeleni travnjak" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "limun šifona" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "svjetlo plava" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "Svjetli koralj" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "svijetlo cijan" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "svjetlo žuto zlatni štap" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "svjetlo siva" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "svjetlo zelena" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "svjetlo ružičasta" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "Svjetli losos" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "svjetlo zeleno more" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "svijetlo plavo nebo" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "Svjetlo siva škriljevca" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "svijetlo plavi čelik" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "svijetlo žuta" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limeta" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limeta zelena" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "lan" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "kestenjasta" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "srednja Aquamarine" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "srednje plava" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "srednja orhideja" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "srednje ljubičasta" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "srednje zeleno more" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "srednje plava škriljevca" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "srednje zeleno proljeće" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "srednje tirkizna" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "srednje ljubičasto crvena" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "ponočno plava" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "krem" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "maglovita ruža" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "moccasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajo bijela" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "pomorska sila" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "stara čipka" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "maslinasta" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "maslinasto sivilo" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "narančasta" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "narančasto crvena" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orhideja" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "blijedi zlatni štap" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "blijedo zelena" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "blijedo tirkizna" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "blijedo ljubičasto crvena" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya bič" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "breskve lisnato" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "ružičasta" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "tamnoljubičasta" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "plavi prah" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "ljubičasta" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "crvena" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "ružičasto smeđa" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "kraljevska plava" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "sedlasto smeđa" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "losos" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "pješčano smeđa" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "morsko zelena" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "školjka" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "oker" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "srebrna" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "nebesko plava" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "škriljavo plava" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "škriljavo siva" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "snježna" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "proljetno zelena" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "čelično plava" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "tan" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "grogotovac" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "čičak" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "rajčica" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "tirkizna" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "ljubičasta" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "pšenica" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "bijela" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "bijeli dim" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "žuta" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "žuto zelena" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktiviraj" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Način automatskog fokusa tijekom strukturne navigacije" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Način automatskog fokusa tijekom navigacije sistemskim kursorom" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Način automatskog fokusa tijekom navigacije sistemskim kursorom" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Točkica _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Točkica _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Točkice 7 _i 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Odustani" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Skoči na" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_U redu" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Nijedna" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "slovkanje" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Najavi kada moji _prijatelji tipkaju" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Pružanje povijesti _poruka za određene sobe za čavrljanje" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Izgovori poruke od strane" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Svih ka_nala" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Svih kanala kada je _bilo koji %s prozor aktivan" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Samo kanala ako je njegov p_rozor aktivan" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "K_aži ime sobe za čavrljanje" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Omogući način izgleda za sadržaj" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dvostruki klik" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trostruki klik" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Zadana govorna jedinica" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Aktualan niz znakova" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Zamjenski niz znakova" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Omogući odjek _znakova" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Omogući _dijakritičke tipke bez razmaka" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Trenutna lokacija" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Najmanja duljina usklađenog teksta:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Mogućnosti traženja" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Govori s_amo promijenjene retke tijekom traženja" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Govori _rezultate tijekom traženja" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "zarez" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Prečac tipkovnice" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Zadan" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Način izgleda" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "odlomak" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Brajični vezovi" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Spremi oznake." - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Vrijeme i datum" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Pregled mišem je omogućen" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "kretanje" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objektni način" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Nevezano" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Napuštanje fiksnog pregleda." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "glavni sadržaj" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Promijenjeno" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Stolno računalo" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Obavijest" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Primljeno" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Obavijest" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Postavke čitača zaslona za %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Obilježi na brajici" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Prikaži osim ako" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Govori" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Spremi profil kao sukob" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Sukob u korisničkom profilu!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profil %s već postoji.\n" -"Nastaviti ažuriranje postojećeg profila s ovim novim promjenama?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Učitaj korisnički profil" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Spremate se mijenjati aktivni profil. Ako ste\n" -"upravo napravili promjene u vašim postavkama, iste će\n" -"biti ispuštene pri učitavanju profila.\n" -"\n" -"Nastavi učitavanje profila odbacujući prethodne promjene?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Spremi profil kao" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Naziv _profila:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Ukloni korisnički profil" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Upravo ćete izbrisati profil %s. Sve nespremljene postavke, te postavke koje " -"su spremljene u ovom profilu bit će izgubljene. Jeste li sigurni da želite " -"izbrisati ovaj profil sa svim pripadajućim postavkama?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Sve" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplikacija" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Prozor" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Nijedan" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Ne_što" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Većina" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Redak" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Rečenica" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Citat" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Tipka" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Natpis" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Potvrdni okvir" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Može se pritisnuti" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Odabirni okvir" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Opis" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Zaglavlje" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Slika" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Oznaka" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Orijentir" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Razina" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Poveznica" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Popis" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Popisni element" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekt" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Odlomak" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radio gumb" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Uloga" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Odabrana stavka" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stanje" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Tekst" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Vrijednost" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Citati" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Gumbi" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Potvrdni okviri" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Klikajući elementi" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Odabirni okviri" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Polja za unos" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Polja obrasca" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Naslovi" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Slike" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Naslovi na razini %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Orijentiri" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Veliki objekti" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Poveznice" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Popisi" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Popisni elementi" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Odlomci" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radio gumbi" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tablice" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Neposjećeni linkovi" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Posjećene poveznice" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navigacija kroz stranicu" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Automatski počni izgovarati stranicu kada je prvi put _učitana" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Izgovara broj elemenata na stranici kada se ista prvi put učita" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Prelomi govor u _komade između pauza" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Zadani glas %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Zadan" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Poveznica" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sustav" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Velika slova" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Provjera pravopisa" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Pravopisna po_greška" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Prijed_log pravopisa" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Prikaži _kontekst pogreške" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Izgovori koordinate ćelija u proračunskoj tablici" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Uvijek izgovaraj raspon označenih ćelija u tablici" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Najavi _zaglavlje ćelije" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigacija kroz tablicu" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Preskoči _prazne ćelije" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Izgovori _ćeliju" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Izgovori koordinate _ćelije" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Izgovori raspone _višestrukih ćelija" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Naziv svojstva" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Kontrola navigacije znaka za umetanje" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Omogući _strukturnu navigaciju" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Zvučna _tema:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Zvučna tema" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Skraćen_o" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Obavijest" -msgstr[1] "Obavijest" -msgstr[2] "Obavijest" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Ctrl" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "lijevi shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "lijevi alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "lijevi control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "desni shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "desni alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "desni control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "lijeva meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "desna meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "numerički blok" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "velika slova" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "klizni blok" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "stranica gore" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "stranica dolje" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "lijevi tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "povratno brisanje" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "kraj retka" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "gore" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "dolje" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "lijevo" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "desno" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "lijeva super tipka" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "desna super tipka" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "izbornik" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "pomoć" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "prebacivač načina" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "izlaz" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "umetanje" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "izbriši" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "početak" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "kraj" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "počni" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "cirkumfleks" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "prsten" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "potez" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Velika_slova" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Desni_Alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Lijevi_Alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "podebljano %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "ukošeno %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "Podebljano kurziv %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "skripta %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "podebljano pismo %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "dvostruko precrtano %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "podebljano fraktur %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif podebljani%s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif ukošeni%s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif ukošeni i podebljani %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "monospace %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "bez točkica%s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "strelica lijevo" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "strelica prema gore" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "strelica desno" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "strelica prema dolje" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "strelica lijevo desno" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "strelica gore dolje" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "strelica prema gore lijevo" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "strelica prema gore desno" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "strelica prema dolje desno" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "lijeva trakasta strelica" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "trakasta strelica prema ogre" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "trakasta strelica prema desno" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "Trakasta strelica prema dolje" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "Lijeva dvostruka strelica" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "Dvostruka strelica prema gore" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "Dvostruka strelica prema desno" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dvostruka strelica prema dolje" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dvostruka strelica lijevo desno" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dvostruka strelica gore dolje" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "sjeverozapadna dvostruka strelica" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "sjeveroistočna dvostruka strelica" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "jugoistočna dvostruka strelica" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "jugozapadna dvostruka strelica" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "strelica pokazuje u desno" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "vrh strelice pokazuje u desno" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "manje od" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "veće od" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "cirkumfleks" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "kvačica" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "Brevis" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "točka" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dvostruka okomita crta" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "tri točke" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "za svaki" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "komplement skupa" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "parcijalna derivacija" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "postoji" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "ne postoji" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "prazan skup" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "delta" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "gradijan" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "element skupa" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "nije element skupa" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "mali element skupa" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "sadrži" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "ne sadrži" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "sadrži simbol manjih dimenzija" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "kraj dokaza" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "Proizvod:" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koprodukt" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "suma" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "plus ili minus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus s točkicom" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "korijen" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "korijen kocka" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "beskrajnost" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "Desni kut" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "Kut" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "Presjek" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "Unija" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "Omjer" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "gotovo jednako" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "nije jednako" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "manje od ili jednako" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "veće od ili jednako" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "Četvrtasti završetak" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "Model" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "točno" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "Original" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "Slika" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "XOR" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "manje od ili jednako" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "veće od ili jednako" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "crni kvadrat" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "bijeli kvadrat" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "crni dijamant" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "bijeli krug" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "crni krug" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bijeli kružić" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplikacija" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "prazno" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "podebljano" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "oznaka unesena" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "oznake spremljene" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "nije moguće spremiti oznake" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nije pronađen orijentir." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Nije pronađen orijentir." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Način zaobilaska je omogućen." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Nije moguće dobiti zaslon kalkulatora" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Način izgovora velikih slova je postavljen na ikonu." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "nijedan" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Način izgovora velikih slova je postavljen na ništa." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "slovkanje" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Način izgovora velikih slova je postavljen na slovkanje." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Čitač zaslona kontrolira znak za umetanje." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Ćelija %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s odabrano" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s nije odabrano" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Spriječi korištenje opcije" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Prisili korištenje mogućnosti" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "MOGUĆNOSTI" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Upotreba: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Sljedeće ne vrijedi: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Ispiši poznate pokrenute aplikacije" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Učitaj profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Nije moguće učitati profil: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Čitač zaslona se ne može pokrenuti, jer se isti ne može povezati sa " -"grafičkim sučeljem." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Nije se moglo aktivirati upravitelja postavki. Izlazak." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Drugi je proces čitača zaslona pokrenut za ovo radno okruženje.\n" -"Izvršite “cthulhu --replace” kako biste ga zamijenili novim." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAZIV" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Koristi alternativni direktorij za korisničke postavke" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Ispiši poznate pokrenute aplikacije" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Zamijeni trenutno pokrenuti primjerak ovog čitača zaslona" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" -"Pošalji izlazne informacije za uklanjanje grešaka na debug-YYYY-MM-DD-" -"HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Pošalji izlazne informacije za uklanjanje grešaka u navedenu datoteku" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "DATOTEKA" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Namještanje korisničkih postavki (tekstualna inačica)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Namještanje korisničkih postavki (GUI inačica)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Prijavite greške na https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Nemoj najaviti kada moji prijatelji tipkaju." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "Najavi kada moji prijatelji tipkaju." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Poruka iz sobe za čavrljanje %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nova kartica čavrljanja %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Ne govori ime sobe za čavrljanje." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "Govori ime sobe za čavrljanje." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Ne pružaj povijesti _poruka za određene sobe za čavrljanje." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Pružaj povijesti _poruka za određene sobe za čavrljanje." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "Pokazatelj odabira" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "izbriši" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "Presjek" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "svjetlo zelena" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "Prijed_log pravopisa" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "kraj sadrživača." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Nije u sadrživaču." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "Sve su stavke označene" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Zadani gumb je %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Zadani gumb je %s" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Zadani gumb je %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " indeks %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " eksponent %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Nije u tablici." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "Odabran je cijeli dokument" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "Odabir za cijeli dokument je poništen" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "Dokument je odabran od položaja pokazivača" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "Dokument nije odabran od položaja pokazivača" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "Dokument je odabran do položaja pokazivača" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "Dokument nije odabran do položaja pokazivača" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dinamičko zaglavlje stupca postavljeno je za red %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dinamičko zaglavlje stupca je pročišćeno." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dinamičko zaglavlje reda postavljeno je za stupac %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dinamičko zaglavlje reda je pročišćeno." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "prazno" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobajta" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabajta" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Datoteke nisu pronađene." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Sadržaj dodan u međuspremnik." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Sadržaj kopiran u međuspremnik." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Ne koristi se fiksni pregled." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Ulaz u fiksni pregled." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Napuštanje fiksnog pregleda." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Premiješta fiksni pregled na riječ iznad trenutne riječi." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Ravni pregled neograničen" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "sadrži formulu" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "Otvara dijalog traženja." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "popis stranica" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "poveznica mape slike" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Unešena tipka je već povezana sa %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Snimljena tipka: %s. Pritisnite enter za potvrdu." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Nova tipka je: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Prečac tipkovnice je obrisan. Pritisnite enter za potvrdu." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Prečac tipkovnice je uklonjen." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "Unesite novu tipku" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tipke" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Odjek tipki postavljen je na tipke." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nijedna" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Odjek tipki postavljen je na ništa." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tipke i riječi" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Odjek tipki postavljen je na tipke i riječi." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "rečenice" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Odjek tipki postavljen je na rečenice." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "riječ" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Odjek tipki postavljen je na riječi." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "riječi i rečenice" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Odjek tipki postavljen je na riječi i rečenice." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "Poštanski pretinac" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "Krug" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "i" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "Iznad" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "korijen" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "korijen kocka" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "KORIJEN" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "indeks 0" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "eksponent a" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "Kraj tablice" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "nepristupačno" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Onemogućeno" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Izgovor uvlaka i poravnanja je onemogućen." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Omogućeno" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Izgovor uvlaka i poravnanja je omogućen." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Način učenja. Pritisnite escape za izlaz." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Ulazim u način učenja. Pritisnite bilo koju tipku da biste čuli njenu " -"funkciju. Kako biste pročitali pomoč čitača zaslona, pritisnite F1. Kako " -"biste dobili informacije o podrazumjevanim tipkovničkim prečacima čitača " -"zaslona, pritisnite F2. Kako biste dobili informacije o prečacima čitača " -"ekrana koji važe za trenutni program, pritisnite F3. Za izlaz iz načina " -"učenja, pritisnite escape." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "napuštanje citata." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "Napuštanje tablice." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "napuštanje feeda." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "napuštanje sheme." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "napuštanje obrasca." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "napuštanje banera." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "Napuštanje informacije." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "napuštanje glavnog sadržaja." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "napuštanje navigacije." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "napuštanje regije." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "napuštanje pretrage." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "napuštanje spiska." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "napuštanje panela." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "Napuštanje tablice." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "napuštanje spiska." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "Napuštanje sažetka." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "Napuštanje zahvala." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "Napuštanje poslijeslovlja." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "napuštanje priloga." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "napuštanje popisa literature." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "napuštanje poglavlja." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "izlazak iz stupca." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "napuštanje zaključka." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "Napuštanje zahvale." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "Napuštanje poglavlja \"zahvale\"." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "Napuštanje posvete." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "napuštanje krajnjih bilješki." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "napuštanje epigrafa." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "napuštanje epiloga." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "napuštanje ispravaka pogrešaka." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "napuštanje primjera." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "napuštanje predgovora." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "napuštanje pojmovnika." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "napuštanje kazala." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "napuštanje spiska stranica." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "napuštanje dijela." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "napuštanje predgovora." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "Napuštanje prologa." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "napuštanje navoda." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "NapuštanjeQNA." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "napuštanje regije." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "Napuštanje sadržaja" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "Odabran redak prema dolje od položaja pokazivača" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "Odabran redak prema gore od položaja pokazivača" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "Nije odabran redak prema dolje od položaja pokazivača" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "Nije odabran redak prema gore od položaja pokazivača" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Izlazim iz način učenja." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "Redak je odabran od početka do prethodnog položaja pokazivača" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "Redak je odabran do kraja od prethodnog položaja pokazivača" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "poveznica" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "na ovoj stranici" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "na istom mjestu" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "drugačije mjesto" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s poveznica na %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "poveznica %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Koristite strelicu gore i dolje za pomicanje kroz popis. Pritisnite Escape " -"za izlaz." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Sve žive regije su postavljene na isključeno" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "Razine uglađenosti živih regija su vraćene" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "Razina uglađenosti %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "postavljanje žive regije na pouzdano" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "postavljanje žive regije na isključeno" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "postavljanje žive regije na uglađeno" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "postavljanje žive regije na snažno" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Očitavanje živih regija je isključeno" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Očitavanje živih regija je uključeno" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "Živa poruka nije spremljena" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Podrška za žive regije je isključena" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nije pronađeno" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Ne mogu pronaći trenutnu lokaciju." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "isključen" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "uključen" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "pogrešno" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Pogrešno napisana riječ: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Kontekst je %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Način surfanja" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Način fokusa" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Za omogućavanje načina fokusa fokusa, pritisnite %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Način fokusa je ljepljiv." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Način pregleda je ljepljiv." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Način izgleda" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objektni način" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Ide na sljedeći objekt." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Objekt iznad miša nije pronađen." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "pregled mišem je isključen" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Pregled mišem je omogućen" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Greška: nije moguće stvoriti popis objekata." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Nema djece." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d posto." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Ide na prethodnu riječ." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "razina gniježđenja %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Nova stavka je dodana" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Nijedna aplikacija nije fokusirana." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Nema fokusa" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nijedna aplikacija nije fokusirana." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Nema više citata." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Nema više gumbi." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Nema više potvrdnih okvira." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Nema više velikih objekata." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Nema više klikajućih objekata." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Nema više odabirnih okvira." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Nema više polja za unos." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Nema više polja obrasca." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Nema više naslova." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Nema više naslova na razini %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Nema više tablica." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Nema više slika." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nije pronađen orijentir." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Nema više poveznica." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Nema više popisa." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Nema više popisnih elemenata." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Nema više živih regija." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Nema više odlomaka." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Nema više radio gumbi." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Nema više rastavljača." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Nema više tablica." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Nema više neposjećenih poveznica." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Nema više posjećenih poveznica." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Obavijest" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Dno" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Vrh" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Nema poruka obavijesti" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "isključen" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "uključen" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Učitava se. Molim pričekajte." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Učitavanje završeno." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Završeno je učitavanje za %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "Stranica je odabrana od položaja pokazivača" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "Stranica je odabrana do položaja pokazivača" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "Stranica nije odabrana od položaja pokazivača" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "Stranica nije odabrana do položaja pokazivača" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "Odlomak je odabran prema dolje od položaja pokazivača" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "Odlomak je odabran prema gore od položaja pokazivača" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "Odlomak nije odabran prema dolje od položaja pokazivača" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "Odlomak nije odabran prema gore od položaja pokazivača" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Već imate otvoren primjerak dijaloga Cthulhu postavki.\n" -"Molimo zatvorite ga prije otvaranja novog." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "slajd %(position)d od %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil je postavljen na %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Profili nisu pronađeni." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Traka napredovanja %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Sve" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Razina interpunkcije postavljena je na sve." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Većina" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Razina interpunkcije postavljena je na većinu." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nijedna" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Razina interpunkcije postavljena je na ništa." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Nešto" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Razina interpunkcije postavljena je na nešto." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Traženje." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Traženje završeno." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu čitač zaslona" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "nije odabrano" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Širina: %d. Visina: %d. %d od lijeve strane. %d od vrha." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Govor je onemogućen." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Govor je omogućen." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "brže." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "sporije." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "više." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "dublje." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "Glasnije" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "Tiše" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Frekvencija:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Visina %s" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "G_lasnoća:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Govor je nedostupan." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Govor je nedostupan." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Govor je omogućen." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "nije moguće spremiti oznake" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Razina opširnosti: kratko" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Razina opširnosti: opširno" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " tri točkice" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu vas pozdravlja." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu vreba ispod valova." - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Način zaobilaska je omogućen." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Način mirovanja onemogućen za %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Govor je nedostupan." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Nije pronađeno" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Niz nije pronađen" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "Niz nije pronađen" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Tipke strukturne navigacije su isključene." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Tipke strukturne navigacije su uključene." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nije pronađeno" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Redak %(row)d, stupac %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Kraj tablice" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Govori ćeliju" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Govori redak" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Nejednolika" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Nije u tablici." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Stupci su preraspoređeni" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Redovi su preraspoređeni" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "stupac %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "stupac %(index)d od %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Dno stupca." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Vrh stupca." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Stupac %s označen" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Stupci %s do %s su označeni" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "stupci %s do %s nisu označeni" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Stupac %s Nije označen" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "redak %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "red %(index)d od %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Početak reda." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Kraj reda." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Redak je obrisan." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Zadnji red je obrisan." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Redak je umetnut." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Redak je umetnut na kraju tablice." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Redak %s označen" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Redci %s do %s su označeni" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Redci %s do %s nisu označeni" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Redak %s nije označen" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "odabrano" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "nije odabrano" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H sati, %M minuta i %S sekundi." - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H sati i %M minuta." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Junikod %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "poništi" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "ponovi" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "nevidljivi znak" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Prijelaz na dno." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Prijelaz na vrh." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 stavki" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Rasponi ćelija %d redak" -msgstr[1] "Rasponi ćelija %d redka" -msgstr[2] "Rasponi ćelija %d redaka" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d stupac" -msgstr[1] " %d stupca" -msgstr[2] " %d stupaca" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Rasponi ćelija %d stupac" -msgstr[1] "Rasponi ćelija %d stupca" -msgstr[2] "Rasponi ćelija %d stupaca" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d znak je predugačak" -msgstr[1] "%d znaka je predugačko" -msgstr[2] "%d znakova je predugačko" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dijalog)" -msgstr[1] "(%d dijaloga)" -msgstr[2] "(%d dijaloga)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d nefokusirani dijalog" -msgstr[1] "%d nefokusirana dijaloga" -msgstr[2] "%d nefokusiranih dijaloga" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bajt" -msgstr[1] "%d bajta" -msgstr[2] "%d bajtova" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "pronađena %d datoteka" -msgstr[1] "pronađene %d datoteke" -msgstr[2] "pronađeno %d datoteka" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d obrazac" -msgstr[1] "%d obrazca" -msgstr[2] "%d obrazaca" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d naslov" -msgstr[1] "%d naslova" -msgstr[2] "%d naslova" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d stavka" -msgstr[1] "%d stavke" -msgstr[2] "%d stavaka" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d orjentir" -msgstr[1] "%d orjentira" -msgstr[2] "%d orjentira" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "pronađena %d stavka" -msgstr[1] "pronađene %d stavke" -msgstr[2] "pronađeno %d stavaka" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "napuštam %d citat." -msgstr[1] "napuštam %d citate." -msgstr[2] "napuštam %d citate." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Napuštam %d popis" -msgstr[1] "napuštam %d popisa." -msgstr[2] "napuštam %d popisa." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "popis od %d stavke" -msgstr[1] "popis od %d stavke" -msgstr[2] "popis od %d stavaka" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "popis od %d stavke" -msgstr[1] "popis od %d stavke" -msgstr[2] "popis od %d stavaka" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Vrijednost" -msgstr[1] "Vrijednost" -msgstr[2] "Vrijednost" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "Matematička tablica s %d retkom" -msgstr[1] "matematička tablica sa %d redaka" -msgstr[2] "Matematička tablica sa %d redaka" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d stupac" -msgstr[1] "%d stupca" -msgstr[2] "%d stupaca" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "Ugrađena matematička tablica s %d retkom" -msgstr[1] "ugrađena matematička tablica s %d redaka" -msgstr[2] "ugrađena matematička tablica sa %d redaka" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d poruka.\n" -msgstr[1] "%d poruke.\n" -msgstr[2] "%d poruka.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d posto." -msgstr[1] "%d posto." -msgstr[2] "%d posto." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d posto pročitanog dokumenta" -msgstr[1] "%d posto pročitanog dokumenta" -msgstr[2] "%d posto pročitanog dokumenta" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d piksel" -msgstr[1] "%d piksela" -msgstr[2] "%d piksela" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s znak" -msgstr[1] "%(count)d %(repeatChar)s znaka" -msgstr[2] "%(count)d %(repeatChar)s znakova" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d od %(total)d stavke odabrano" -msgstr[1] "%(index)d od %(total)d stavka odabrano" -msgstr[2] "%(index)d od %(total)d stavka odabrano" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Pronađen %d zadani prečac čitača zaslona." -msgstr[1] "Pronađena %d zadana prečaca čitača zaslona." -msgstr[2] "Pronađeno %d zadanih prečaca čitača zaslona." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Pronađen %(count)d prečac čitača zaslona za %(application)s." -msgstr[1] "Pronađena %(count)d prečaca čitača zaslona za %(application)s." -msgstr[2] "Pronađea %(count)d prečaca čitača zaslona za %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d razmak" -msgstr[1] "%d razmaka" -msgstr[2] "%d razmaka" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulator" -msgstr[1] "%d tabulatora" -msgstr[2] "%d tabulatora" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tablica" -msgstr[1] "%d tablice" -msgstr[2] "%d tablica" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "sadržaj" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tablica od %d redka" -msgstr[1] "tablica od %d redka" -msgstr[2] "tablica od %d redaka" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tablica od %d redka" -msgstr[1] "tablica od %d redka" -msgstr[2] "tablica od %d redaka" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tablica od %d redka" -msgstr[1] "tablica od %d redka" -msgstr[2] "tablica od %d redaka" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d neposjećena poveznica" -msgstr[1] "%d neposjećene poveznice" -msgstr[2] "%d neposjećenih poveznica" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d posjećena poveznica" -msgstr[1] "%d posjećene poveznice" -msgstr[2] "%d posjećenih poveznica" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "naizmjence uključi" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "na %(index)d od %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d od %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "RAZINA %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "razina stabla %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "RAZINA STABLA %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "upitnik" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "uređivajući odabirni okvir" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "za uređivanje" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "feed" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "ilustracija" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "sažetak" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "Zahvale" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "pogovor" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "Dodatak" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "upis u popisu literature" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "Popis literature" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "poglavlje" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "dvotočka" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "zaključak" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "korica" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "zahvala" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "zahvale" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "posveta" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "rubna bilješka" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "rubne bilješke" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "greške" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "primjer" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "predgovor" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "pojmovnik" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "kazalo" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "uvod" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "prijelom stranice" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "popis stranica" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "dio" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "uvod" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "navodnik" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "PIO" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "titl" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "sadržaj" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "n%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s razina %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "vodoravna traka prelistavanja" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "okomita traka prelistavanja" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "vodoravni klizač" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "Okomiti klizač" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "vodoravni razdjelnik" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "okomiti razdjelnik" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "preklopnik" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Ploča ikona" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "baner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "komplementaran sadržaj" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informacija" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "glavni sadržaj" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "kretanje" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "regija" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "pretraga" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "Posjećena veza" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "gumb izbornika" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klikajući" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "skupljeno" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "prošireno" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "sadrži dugi opis" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "vodoravno" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "okomito" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "označen" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nije označen" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "Uključeno" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "isključeno" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "djelomično označen" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "pritisnuta" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "nije pritisnut" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "nije odabran" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "odabrano" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "nije odabran" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "nije odabran" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "posjećen" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "neposjećen" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "neupotrebljivo" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "samo za čitanje" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "samo.čit." - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "potrebno" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "višestruki odabir" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "nepravilan unos" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "nepr" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "Pogrešno napisano" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "P.Gr" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "nepravilno gramatički" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "slovn." - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Pronađi" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Dijalog čitača zaslona za traženje" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Zatvori" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Pretraži" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Pretraži za:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Traži ovo:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Vrh prozora" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Vrh prozora" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Počni od:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Omotaj oko" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Traži _unatrag" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Smjer pretrage:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Traži velika i mala slova" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Traži samo _cijelu riječ" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Mogućnosti traženja" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Zadan" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Velika slova" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Poveznica" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sustav" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplikacija" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Prozor" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu čitač zaslona" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Pomoć" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Primijeni" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Prijenosno računalo" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Raspored tipkovnice" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktivni _profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profil pri pokretanju:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Učitaj" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Spremi _kao" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Ukloni" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profili" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Prikaži alatne savjetnike" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Izgovori objekt ispod _miša" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Miš" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Oblik _vremena:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Format _datuma:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Vrijeme i datum" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Izgovaraj postotke" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_prikaži postotke na brajičnom retku" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Učestalost (u sekundama):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplikacija" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_pišti pri obnavljanju napretka" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Aktualizacije trake napredovanja" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Omogući _premotavanje u naprijed i u nazad pri čitanju svega" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Omogući _strukturnu navigaciju prilikom čitanja svega" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Reci sve _po:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Čitaj _citate pri čitanju svega" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Izgovaraj _popise pri čitanju svega" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Izgovaraj _tablice u načinu čitaj sve" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Izgovaraj _panele u načinu čitaj sve" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Izgovaraj _obrasce u načinu čitaj sve" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Izvještavaj o orjentirima u načinu č_itaj sve" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Čitaj sve" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Prezentacija elementa:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Općenito" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "G_lasnoća:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Visina:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Frekvencija:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Osoba:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Jezik:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Govorna _jedinica:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Sustav govora:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Vrsta _glasa:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_način izvještavanja o velikim slovima:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Postavke za vrstu glasa" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Izgovaraj _riječi s kombinacijama velikih i malih slova" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Izgovaraj _brojeve kao znamenke" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Globalne postavke glasa" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Glas" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Omogući govor" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Op_širno" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Opširnost" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Sve" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Razina interpunkcije" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Govori samo prikazani tekst" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Govori prazne retke" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Govori uvlake i poravnanje" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Govori _mnemotehniku objekta" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Govori unutrašnji polo_žaj" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Govori _učiteljske poruke" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Poruke sustava su detaljne" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Izgovaraj _boje kao imena" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "izgovaraj _citate prilikom kretanja" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Izgovaraj_popise prilikom kretanja" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Izvještavaj o _tablicama prilikom kretanja" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Izgovaraj pokazatelj o _krivo napisanoj riječi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Izgovaraj _panele prilikom kretanja" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "izvještavaj o _orjentirima prilikom kretanja" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "izgovaraj _obrazce prilikom kretanja" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "izgovaraj _opis" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Izgovaraj potpuni redak u _proračunskim tablicama" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Izgovaraj potpuni redak u _tablicama dokumenata" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Izgovaraj potpuni redak u _GUI tablicama" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Izgovoreni kontekst" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Govor" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Omogući po_dršku za brajicu" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "S_kraćeni nazivi uloga" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Onemogući simbol za kra_j retka" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tablica kratkopisa:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Omogući brajični kratkopis" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Omogući prelamanje retka" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Postavke prikaza" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Nijedan" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Pokazatelj odabira" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Pokazatelj poveznica" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Uključi _brze poruke" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_dužina poruke (u sekundama):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "poruke su _postojane" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "poruke su _detaljne" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Postavke brzih poruka" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Brajica" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Omogući odjek _tipkovnice" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Omogući _abecedne tipke" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Omogući n_umeričke tipke" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Omogući _interpunkcijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Omogući _razmaknicu" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Omogući tipke _modifikatora" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Omogući _funkcijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Omogući ak_cijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Omogući _navigacijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Omogući odjek _riječi" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Omogući odjek _rečenica" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Odjek tipkovnice" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Tipka ili tipke _modifikatora za čitač zaslona:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Prečai tipkovnice" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Rječnik izgovaranja" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Novi upis" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Obriši" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Izgovor" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Govori sve" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Ne govori _ništa" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Vrati izvorno" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Tekstovna svojstva" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Pomakni na _kraj" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Pomakni za jedan _dolje" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Pomakni za jedan _gore" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Pomakni na _početak" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Prilagodi odabrane atribute" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Brajični pokazatelj" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Tekstovna svojstva" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Pružatelj:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokalno - Besplatno)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Datoteka API _ključa:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Putanja do datoteke API ključa" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Dohvati _Claude API ključ" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Otvori preglednik za dobivanje Claude API ključa i automatski spremi" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Zahtijevaj potvrdu prije AI radnji" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _model:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Naziv modela za Ollama (npr. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _krajnja točka:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL krajnje točke Ollama API (npr. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Kvaliteta snimke zaslona:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "nisko" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Srednja" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Visoka" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Jezik:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Slika u sivim tonovima" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Invertiraj sliku" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Crno-bijela slika" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Prag crno/bijelo:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analiziraj boje" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Sadržaj kopiran u međuspremnik." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alan, b : biokovo, c : cavtat, č : čakovec, ć : ćilipi, d : dubrovnik, " -"đ : đakovo, e : europa, f : frankopan, g : gospić, h : hrvatska, i : istra, " -"j : jadran, k : karlovac, l : lika, m : mostar, n : novska, o : osijek, p : " -"pula, q : quorum, r : rijeka, s : split, š : šibenik, t : trogir, u : učka, " -"v : vukovar, w : dvostrukove, x : iks, y : ipsilon, z : zagreb, ž : županja" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "boja pozadine" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "puna visina pozadine" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "uzorak pozadine" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "smjer" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "za uređivanje" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "naziv podrijetla" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "boja slova" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "uzorak slova" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efekt slova" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "uvlaka" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "greška" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "nevidljivo" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "poravnanje" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "jezik" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "lijevi rub" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "širina retka" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "stil odlomka" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pikseli iznad redaka" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pikseli ispod redaka" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pikseli unutar prijeloma" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "desni rub" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "dizanje" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "skala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "veličina" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "rastezanje" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "precrtano" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "dekoracija teksta" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "zakretanje teksta" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "sjena teksta" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "potcrtano" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "varijanta" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "okomito poravnanje" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "težina" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "način prijeloma" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "način pisanja" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "točno" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "nijedan" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "ugravirati" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "izbočeno" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "obris" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "nadvlaka" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "precrtavanje" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "treptanje" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "crna" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "jednostruki" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dvostruki" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "nisko" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "char" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "riječ" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "riječ znak" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "lijevo" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "desno" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centrirano" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "bez poravnanja" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "popunjeno" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra kondenzirano" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "posebno kondenzirano" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "kondenzirano" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "polu kondenzirano" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normalno" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "polu prošireno" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "prošireno" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "posebno prošireno" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra prošireno" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "mala slova" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "nakrivljeno" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kurziv" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Zadan" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Tijelo teksta" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Zaglavlje" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "osnovica" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "gore" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "tekst gore" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "sredina" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "dolje" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "tekst dolje" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "nasljeđe" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "solidno" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "pravopis" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Pritisnite razmaknicu za mijenjanje." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Pritisnite razmak za proširenje, i koristite strelice gore i dolje za odabir " -"stavke." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Pritisnite alt+f6 da biste fokusirali unutrašnje prozore." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Za pomicanje po stavkama, koristite strelice na tipkovnici ili tipkajte za " -"pretragu." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Za ulazak u izbornike sustava, pritisnite tipkovni prečac alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Rabite strelice gore i dolje za odabir stavke." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Za skupljanje, pritisnite shift plus strelicu lijevo." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Za proširivanje, pritisnite shift plus strelicu desno." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Za aktivaciju, pritisnite enter." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Upišite tekst." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Rabite strelice lijevo i desno da biste pregledali ostale kartice." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Za aktivaciju, pritisnite razmak." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Rabite strelicu gore ili dolje da biste odabrali vrijednost. Ili, upišite " -"željenu numeričku vrijednost." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Rabite strelice na tipkovnici za mijenjanje." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Za navigaciju rabite strelice lijevo ili desno. Za kretanje kroz stavke " -"pritisnite strelicu gore ili dolje." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Za ulaz u podizbornik pritisnite strelicu desno." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Za smanjivanje pritisnite strelicu lijevo, a da biste povečali pritisnite " -"strelicu desno. Da biste došli na minimum pritisnite home, a za maksimum " -"pritisnite end." diff --git a/po/hu.po b/po/hu.po deleted file mode 100644 index 09484a0..0000000 --- a/po/hu.po +++ /dev/null @@ -1,9348 +0,0 @@ -# Hungarian translation for cthulhu. -# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# -# Kálmán Kéménczy , 2006, 2007. -# Gabor Kelemen , 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017. -# Attila Hammer , 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2022, 2023. -# Balázs Úr , 2013, 2014, 2018, 2019, 2020. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-08 17:45+0200\n" -"Last-Translator: Attila Hammer \n" -"Language-Team: Hungarian \n" -"Language: hu\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.3\n" - -# Megjegyzés: Mivel mindenhol régóta Gáborral egyeztetve az Cthulhu nevet magyarosan Orkaként írjuk a fordításban, így a fordítást megváltoztattam Orka képernyőolvasóra az Cthulhu képernyőolvasó helyett. -msgid "Cthulhu Screen Reader" -msgstr "Orka képernyőolvasó" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "képernyő;olvasó;akadálymentesítés;beszéd;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "figyelmeztetés" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "nyíl" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "npt" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "vsz" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "feli" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "jn" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "szvl" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "ofl" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "klm" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dtszm" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ikon" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "krt" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "tárcsázás" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "pbp" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "kat" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "rajz" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fvl" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "kit" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "btk" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "űrlap" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "üvg" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "cmsr" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "kép" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "bkrt" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "cmk" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "rtgat" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "hv" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lne" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnü" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnüsor" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnülm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optat" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "lf" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "lplst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "jsz" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "fugmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "fmj" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "gb" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "vgb" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "vgelm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "gyat" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "sfl" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "gs" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "gat" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "szksz" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "elv" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "cs" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "oat" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "lgb" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "át" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cella" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "lvmnüe" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "szm" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "kpgb" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "et" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "bsg" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "fa" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "fatbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "ism" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "nmz" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "abl" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "fl" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "llc" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "bek" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "alk" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "szsv" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "bkmp" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Cseh" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spanyol" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanadai francia 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francia" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Litván 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holland 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvég 1" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvég 2" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvég 3" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvég 4" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Lengyel" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugál" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Svéd" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arab" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Walesi 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Walesi 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Német 1" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Német 2" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Német 3" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Angol 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Angol 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Amerikai angol 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Amerikai angol 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadai francia 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francia" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Görög 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindu" - -# Megjegyzés: ez a sztring a magyar számítógépes braille táblát jelöli, a fordítás meg fog jelenni az Orka grafikus beállító párbeszédablak braille lapján a fordítási tábla kombinált listamezőben -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Magyar (számítógépes)" - -# Megjegyzés: ez a sztring a magyar irodalmi braille táblát jelöli, a fordítás meg fog jelenni az Orka grafikus beállító párbeszédablak braille lapján a fordítási tábla kombinált listamezőben -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Magyar (irodalmi)" - -# Megjegyzés: ez a sztring a magyar rövid írású braille táblát jelöli, a fordítás meg fog jelenni az Orka grafikus beállító párbeszédablak braille lapján a fordítási tábla kombinált listamezőben -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Magyar (rövid írás)" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Olasz" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgiumi német 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "szóköz" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "új sor" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "felkiáltójel" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "idézőjel" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "kettős kereszt" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollár" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "százalék" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "és" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "aposztróf" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "Bal zárójel" - -# Ez nem hiba! Szükség volt a módosításra, mivel az új Espeak már a kisbetűs #szavak előtti számokat sorszámneveknek nézi akkor, ha a számok után pont #van. Ez csak a GNOME-speech drivernél okoz problémát például az olyan #mondatrészeknél, mint pl. a 2009. december 29. (szerda). Ha a balzárójel #szöveg kis b betűvel kerülne kiküldésre, a december 29 helyett december #huszonkilencedik hangozna el. -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "Jobb zárójel" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "csillag" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plusz" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "vessző" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "mínusz" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "pont" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "per" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "kettőspont" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "pontosvessző" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "kisebb" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "egyenlő" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "nagyobb" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "kérdőjel" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "kukac" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "nyitó szögletes" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "bekszles" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "záró szögletes" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "fölfelényíl" - -# Felhasználói kérés volt a változtatás, megszokták az emberkék a régi #beszédszintetizátor által kimondott szöveget. :-):-) -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "aláhúzás" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "tompa ékezet" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "kezdő kapcsos" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "függőleges vonal" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "vég kapcsos" - -# Szintén ilyen kérés. :-):-) -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -# Szintén ilyen kérés. :-):-) -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "szóköz" - -# A nem törhető szóköz túl hosszú lenne a kimondásnál. -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "fordított felkiáltójel" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "font" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "pénznem jel" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "csővezeték" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "szakasz" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "fok" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright-jel" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "felső index a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "belső bal idézőjel" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logikai nem" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "lágy kötőjel" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "bejegyzettvédjegy-jel" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "felülvonás" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "fok" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "pluszminusz" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "felső index 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "felső index 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "á" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mű" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "bekezdésjelző" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "középső pont" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cédille" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "felső index 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "sorszám" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "belső jobb idézőjel" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "negyed" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "fél" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "háromnegyed" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "fordított kérdőjel" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "á" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A tompa ékezettel" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "Á" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A kúpos ékezettel" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A hullámjellel" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "umlautos A" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A körrel" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "AE ligatúra" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C cédille jellel" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E tompa ékezettel" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "É" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E kúpos ékezettel" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "umlautos E" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I tompa ékezettel" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "Í" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I kúpos ékezettel" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "umlautos I" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N hullámjellel" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O tompa ékezettel" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "Ó" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O kúpos ékezettel" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O hullámjellel" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "Ö" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "szor" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "áthúzott O" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U tompa ékezettel" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "Ú" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U kúpos ékezettel" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "Ü" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ékezettel" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "scharf s" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a tompa ékezettel" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a kúpos ékezettel" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a hullámjellel" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "umlautos a" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a körrel" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ae ligatúra" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cédille jellel" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e tompa ékezettel" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "é" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e kúpos ékezettel" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "umlautos e" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i tompa ékezettel" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "í" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i kúpos ékezettel" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "umlautos i" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n hullámjellel" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o tompa ékezettel" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "ó" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o kúpos ékezettel" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o hullámjellel" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "ö" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "osztva" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "áthúzott o" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "ú" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u tompa ékezettel" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "y kúpos ékezettel" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "ü" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y ékezettel" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "umlautos y" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "umlautos Y" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "függvény" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "Gondolatjel" - -# Szintén a sorszámnevek miatt kellett a kezdőbetűt megváltoztatni. Pl. az #ubuntu.hu honlapon a cikkek dátumánál ha kisbetűvel került kimondásra a #gondolatjel szó a GNOME-Speech drivernél, a dátum nap része sorszámnévként #hangzott el. -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "bal oldali idézőjel" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "jobb oldali idézőjel" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "idézőjel" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "idézőjel" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "idézőjel" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "idézőjel" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "kereszt" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "kettős kereszt" - -# Megjegyzés: felhasználói kérésre lett megváltoztatva, más képernyőolvasók # például ezt a sztringet küldik ki a webböngészők használata esetén erre a -# szimbólumra. Ha nem gond, maradjon. -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "listajel" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "háromszög listajel" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "ezrelék" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "aposztróf" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "dupla aposztróf" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "hármas ikerprím" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "kötőjel listajel" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euró" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "védjegy" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "pipa" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "vastag pipa" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x formájú listajel" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "felső index 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "felső index 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "felső index 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "felső index 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "felső index 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "felső index 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "felső index 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "felső index plusz" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "felső index mínusz" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "felső index egyenlő" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "felső index bal zárójel" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "felső index jobb zárójel" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n-edik hatvány" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "alsó index 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "alsó index 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "alsó index 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "alsó index 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "alsó index 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "alsó index 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "alsó index 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "alsó index 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "alsó index 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "alsó index 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "alsó index plusz" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "alsó index mínusz" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "alsó index egyenlő" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "alsó index bal zárójel" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "alsó index jobb zárójel" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "fekete négyzet" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "fekete káró" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "objektumot helyettesítő karakter" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "A mutató átirányítása az aktuális elemhez." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Bal kattintást végez azon az elemen, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Jobb kattintást végez azon az elemen, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Felolvassa az egész dokumentumot." - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Felolvassa a teljes ablakot az egyszerű áttekintés használatával." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Végrehajtja a hol vagyok műveletet." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" -"Végrehajtja a hol vagyok műveletet, de részletesebb információt kapunk." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Kimondja a jelenleg kijelölt objektumot." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Kimondja a hivatkozás részleteit." - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Kimondja és megjeleníti a Braille-kijelzőn az alapértelmezett gombot" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Kimondja és megjeleníti a Braille-kijelzőn az állapotsort." - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Kimondja és megjeleníti a Braille-kijelzőn a címsort." - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "A keresés párbeszédablak megnyitása." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Műveletek listájának megjelenítése" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "A karakterlánc következő előfordulását keresi." - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "A karakterlánc előző előfordulását keresi." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Belép az egyszerű áttekintés módba, majd kilép belőle." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Be- vagy kikapcsolja az egyszerű áttekintés korlátozását" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Az egyszerű áttekintést a kezdő pozícióra mozgatja." - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Az egyszerű áttekintést a záró pozícióra mozgatja." - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Az egyszerű áttekintést az előző sor elejére mozgatja." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Kimondja azt a sort, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Lebetűzi az aktuális sort, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" -"Fonetikusan lebetűzi az aktuális sort, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Az egyszerű áttekintést a következő sor elejére mozgatja." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Az egyszerű áttekintést az előző szóra vagy elemre mozgatja." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Kimondja azt az elemet vagy szót, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Lebetűzi azt az elemet vagy szót, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Fonetikusan lebetűzi azt az elemet vagy szót, ahol az egyszerű áttekintés " -"áll." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Az egyszerű áttekintést a következő elemre vagy szóra mozgatja." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Az egyszerű áttekintést a jelenlegi szó fölötti szóra mozgatja." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Kimondja azt az objektumot, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Az egyszerű áttekintést a jelenlegi szó alatti szóra mozgatja." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Az egyszerű áttekintést az előző karakterre mozgatja." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Kimondja azt a karaktert, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" -"Fonetikusan lebetűzi az aktuális karaktert, ahol az egyszerű áttekintés áll." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" -"Kimondja annak a karakternek az unicode kódját, ahol az egyszerű áttekintés " -"áll." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Az egyszerű áttekintést a következő karakterre mozgatja." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Az egyszerű áttekintést a sor végére mozgatja." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Az egyszerű áttekintést a bal alsó sarokba mozgatja." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Az egyszerű áttekintés tartalmát a vágólapra másolja." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "A vágólaphoz fűzi az egyszerű áttekintés tartalmát." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Az egyszerű áttekintés tartalmának megjelenítése" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Vált a jelenlegi táblázatcella és az egész sor felolvasása között." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Felolvassa a jelenlegi szöveges karakterhez társított attribútumokat." - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "A braille képernyőt balra görgeti." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "A braille képernyőt jobbra görgeti." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Visszaadja a billentyűzetfókusszal rendelkező objektumot." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Be- vagy kikapcsolja az irodalmi braille támogatást." - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Feldolgozza a kurzorirányító billentyűhöz társított eseményt." - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Kijelöli a kijelölés kezdetét." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Kijelöli a kijelölés végét." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Belép a tanulási módba. Az Esc megnyomásával kiléphet belőle." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Csökkenti a beszéd sebességét." - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Növeli a beszéd sebességét." - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Csökkenti a beszéd hangmagasságát." - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Növeli a beszéd hangmagasságát." - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Növeli a beszéd hangerejét." - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Csökkenti a beszéd hangerejét." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Előző beszédbeállítás kiválasztása" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Következő beszédbeállítás kiválasztása" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Jelenlegi beszédbeállítás csökkentése" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Jelenlegi beszédbeállítás növelése" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Beszédbeállítások mentése" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Átváltja a beszéd némítását." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Átváltja a beszéd részletességi szintjét." - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Alvó mód váltása" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Kilépés a képernyőolvasóból." - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Megjeleníti a beállító párbeszédablakot." - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Megjeleníti az alkalmazásbeállító párbeszédablakot." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Be- vagy kikapcsolja a behúzás és igazítás felolvasását" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Megváltoztatja a kimondott szám stílusát." - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Váltás a következő központozási szintre." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Váltás a következő beszédszintetizátorra" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Váltás a következő beállítási profilra." - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Váltás a következő nagybetű stílusra." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Váltás a következő billentyűvisszhang-szintre." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Futás közben váltás a hibakeresési szintek között." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Információt ad a könyvjelző helyzetéről." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Ugrás az előző könyvjelzőhöz." - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Ugrás a könyvjelzőhöz." - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Ugrás a következő könyvjelzőhöz." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Könyvjelző hozzáadása." - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Könyvjelzők mentése." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Be- vagy kikapcsolja az áttekintés egérrel módot." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Kimondja vagy Braille kijelzőre írja az aktuális időt." - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Kimondja vagy Braille kijelzőre írja az aktuális dátumot." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" -"Kimondja vagy Braille kijelzőre írja a jelenlegi objektum méretét és helyét." - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "A következő billentyűparancs átadása az aktuális alkalmazásnak." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Az előző csevegő csatorna üzenetének kimondása és braille kiírása." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Be- vagy kikapcsolja a partnerek gépelésének bejelentését." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "A csatorna nevének a csevegőüzenetek elé szúrása be/ki." - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "A csatorna nevének a csevegőüzenetek elé szúrása be/ki." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Sor balra" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Sor jobbra" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Sor fel" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Sor le" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Fagyasztás" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Balra fent" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Görgetés balra" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Kurzorpozíció" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Hat pontos" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Kurzorirány" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Kijelölés kezdete" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Kijelölés vége" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Utolsó értesítés megjelenítése." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Értesítések listájának megjelenítése" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Előző értesítés megjelenítése." - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "A következő értesítés megjelenítése." - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Ugrás a következő karakterre." - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Ugrás az előző karakterre." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Ugrás a következő szóra." - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Ugrás az előző szóra." - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Ugrás a következő sorra." - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Ugrás az előző sorra." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Ugrás a fájl elejére." - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Ugrás a fájl végére." - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "A sor elejére ugrás a dokumentumban." - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "A sor végére ugrás a dokumentumban." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Ugrás a következő objektumra." - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Ugrás az előző objektumra." - -# megjegyzés: ezt az üzenetet javítottam Balázs javaslatára, maradjon így ha lehetséges. -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Az aktuális kombinált listamezőt szétnyitja." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Váltás a beépített vagy a képernyőolvasó mutatónavigációja között." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Élő régiók udvariassági beállításának módosítása." - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" -"Az élő régió alapértelmezett udvariassági szintjének beállítása kikapcsoltra." - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Élő régió áttekintése" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "élő régiók megjelenítése." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" -"A fókuszt az egérmutatónál felbukkanó objektumra, vagy arról elmozgatja." - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" -"Beállítja a dinamikus oszlopfejlécekként használandó sort a táblázat " -"celláinak felolvasásakor." - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Törli a dinamikus oszlopfejléceket." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" -"Beállítja a dinamikus sorfejlécekként használandó oszlopot a táblázat " -"celláinak felolvasásakor." - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Törli a dinamikus sor fejléceket." - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Megjeleníti a beviteli sor tartalmát." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Be- vagy kikapcsolja a strukturált navigációs billentyűket." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Ugrás az előző idézetblokkra." - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Ugrás a következő idézetblokkra." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Idézetblokkok listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Ugrás az előző gombra." - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Ugrás a következő gombra." - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "A gombok listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Ugrás az előző jelölőnégyzetre." - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Ugrás a következő jelölőnégyzetre." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "A jelölőnégyzetek listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Ugrás az előző kattintható elemre." - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Ugrás a következő kattintható elemre." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Kattintható elemek listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Ugrás az előző kombinált listamezőre." - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Ugrás a következő kombinált listamezőre." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Ugrás az elemblokk elejére." - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Ugrás az elemblokk végére." - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Kombinált listamezők listájának megjelenítése." - -# fixme: lehet hogy ez beviteli mező? -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Ugrás az előző szerkesztőmezőre." - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Ugrás a következő szerkesztőmezőre." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Szerkesztőmezők listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Ugrás az előző űrlapmezőre." - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Ugrás a következő űrlapmezőre." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Űrlapmezők listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Ugrás az előző címsorra." - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Ugrás a következő címsorra." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Címsorok listájának megjelenítése." - -# fixme: az orka nem ismeri a sorszámneveket, ez hiba! mondjuk más se... -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Ugrás az előző %d. szintű címsorra." - -# Itt már használhatunk pontot, mivel az Espeak ilyenkor sorszámnévként küldi ki a címsor számot. -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Ugrás a következő %d. szintű címsorra." - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "%d. szintű címsorok listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Ugrás az előző belső keretre." - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Ugrás a következő belső keretre." - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Keretek listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Ugrás az előző képre." - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Ugrás a következő képre." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Képek listájának megjelenítése." - -# fixme: szebb szó nincs erre? -# Nem tudtam előcsalogatni, egyelőre maradjon. -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Ugrás az előző jelölőre." - -# FixMe: Mi erről a véleményed? Ha akarod javítsd. -# fixme: ronda. de jó ötletem nincs -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Ugrás a következő jelölőre." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "A jelölők listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Ugrás az előző nagy objektumra." - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Ugrás a következő nagy objektumra." - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Nagy objektumok listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Ugrás az előző hivatkozásra." - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Ugrás a következő hivatkozásra." - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Hivatkozások listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Ugrás az előző listára." - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Ugrás a következő listára." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Listák listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Ugrás az előző listaelemre." - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Ugrás a következő listaelemre." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Listaelemek listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Ugrás az előző élő régióra." - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Ugrás a következő élő régióra." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Ugrás az utolsó élő régióra, amely információt közölt." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Ugrás az objektum szülőjére a navigátor fókuszával." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Ugrás az objektum első gyermekére a navigátor fókuszával." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Ugrás az objektum következő testvérobjektumára a navigátor fókuszával." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Ugrás az objektum következő testvérobjektumára a navigátor fókuszával." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Kattintás az objektum navigátor fókuszában levő objektumon." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Be- vagy kikapcsolja az egyszerűsített objektum navigációs módot." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Ugrás az előző bekezdésre." - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Ugrás a következő bekezdésre." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Bekezdések listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Ugrás az előző választógombra." - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Ugrás a következő választógombra." - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Választógombok listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Ugrás az előző elválasztóra." - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Ugrás a következő elválasztóra." - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Ugrás az előző táblázatra." - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Ugrás a következő táblázatra." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Táblázatok listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Ugrás egy cellát lefelé." - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Ugrás a táblázat első cellájára." - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Ugrás a táblázat utolsó cellájára." - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Ugrás egy cellát balra." - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Ugrás egy cellát jobbra." - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Ugrás egy cellát felfelé." - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Be- vagy kikapcsolja az elrendezés módot." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Váltás a fókuszmód és a böngészőmód között." - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "A rögzített fókuszmód engedélyezése." - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "A rögzített böngészőmód engedélyezése." - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Ugrás az előző nem látogatott hivatkozásra." - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Ugrás a következő nem látogatott hivatkozásra." - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "A nem látogatott hivatkozások listájának megjelenítése." - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Ugrás az előző meglátogatott hivatkozásra." - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Ugrás a következő meglátogatott hivatkozásra." - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Meglátogatott hivatkozások listájának megjelenítése." - -# megjegyzés: erre a színre nincs jobb ötletem, lehet, hogy a sima kék jobb lenne -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "Alízkék" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antik fehér" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarin" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azúrkék" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "bézs" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "krémszín" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "fekete" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "mandulazöld" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "kék" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "violakék" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "barna" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadétkék" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "halványsárga" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "csokoládé" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "korallpiros" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "búzavirágkék" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "kárminvörös" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "ciánkék" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "sötétkék" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "sötétcián" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "sötét aranyrúd" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "sötétszürke" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "sötétzöld" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "sötét keki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "sötét magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "sötét olívazöld" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "sötét narancs" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "sötét orchidea" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "sötétvörös" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "sötét lazac" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "sötét tengerzöld" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "sötét palakék" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "sötét palaszürke" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "sötét türkiz" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "sötét viola" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "mély rózsaszín" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "mély égkék" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "halvány szürke" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "svindler kék" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "téglavörös" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "virágos fehér" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "erdőzöld" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fukszia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "szellem fehér" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "arany" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "aranyrúd" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "szürke" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "zöld" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "sárgászöld" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "mézharmat" - -# megjegyzés: lehet, hogy a sima rózsaszín elnevezés jobb lenne. -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "forró rózsaszín" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indiai vörös" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigó" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "elefántcsont" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "keki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "levendulakék" - -# megjegyzés: ezt a fordítást lehet, hogy át kell írni. -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "levendula pír" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "gyepzöld" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "citrom műselyem" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "világoskék" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "világos korall" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "világos cián" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "világos aranyrúd sárga" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "világosszürke" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "világoszöld" - -# Ez nem hiba! Szükség volt a módosításra, mivel az új Espeak már a kisbetűs #szavak előtti számokat sorszámneveknek nézi akkor, ha a számok után pont #van. Ez csak a GNOME-speech drivernél okoz problémát például az olyan #mondatrészeknél, mint pl. a 2009. december 29. (szerda). Ha a balzárójel #szöveg kis b betűvel kerülne kiküldésre, a december 29 helyett december #huszonkilencedik hangozna el. -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "világos rózsaszín" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "világos lazac" - -# Ez nem hiba! Szükség volt a módosításra, mivel az új Espeak már a kisbetűs #szavak előtti számokat sorszámneveknek nézi akkor, ha a számok után pont #van. Ez csak a GNOME-speech drivernél okoz problémát például az olyan #mondatrészeknél, mint pl. a 2009. december 29. (szerda). Ha a balzárójel #szöveg kis b betűvel kerülne kiküldésre, a december 29 helyett december #huszonkilencedik hangozna el. -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "világos tengerzöld" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "világos égkék" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "világos palaszürke" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "világos acélkék" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "világossárga" - -# megjegyzés: nem tudom, hogy valójában létezik-e lime szín, a színszótárban limezöld zöld szerepel. -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "világoszöld" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limezöld" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "len" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "gesztenyebarna" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "közepes akvamarin" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "közepes kék" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "közepes orchidea" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "közepes lila" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "közepes tengerzöld" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "közepes palakék" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "közepes tavaszi zöld" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "közepes türkizkék" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "közepes violavörös" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "éjkék" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "mentakrém" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rózsaszín" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokaszin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajo fehér" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "tengerészkék" - -# megjegyzés: erre a sztringre nincs jobb ötletem. -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "régi csipke" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olíva" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "olajbarna" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "narancssárga" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "sötét narancs" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchidea" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "halvány arany" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "halványzöld" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "halvány türkiz" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "halvány violavörös" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "őszibarack" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rózsaszín" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "szilva" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "por kék" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "lila" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "piros" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rózsás barna" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "királykék" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "nyeregbarna" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "lazac" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "homokbarna" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "tengerzöld" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "kagyló" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "vörösesbarna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "ezüst" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "égszínkék" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "palakék" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "palaszürke" - -# megjegyzés: szószerint havazást jelent, de színnévként inkább hófehérként fordítottam -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "hófehér" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "tavaszi zöld" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "acélkék" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "sárgásbarna" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "sötét türkiz" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "bogáncs" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "paradicsom" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "türkizkék" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "viola" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "búza" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "fehér" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "füstfehér" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "sárga" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "sárgászöld" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktiválás" - -# megjegyzés: Talán a "A fókuszmód automatikus bekapcsolása navigálás közben" megnevezés jobb lenne -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" -"A fókuszmód automatikus bekapcsolása a strukturált navigáció használatakor" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "A fókuszmód automatikus bekapcsolása a mutatónavigáció használatakor" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "A fókuszmód automatikus bekapcsolása a natív navigáció használatakor" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "_7. pont" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "_8. pont" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "7. é_s 8. pont" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "Mé_gse" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Ugrás ide" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Hang ikon" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Nincs" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "betűzés" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Értesítés, amikor a _partnerek gépelnek" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "A csevegőszoba ü_zenetelőzményeinek megjelenítése" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Üzenetek kimondása" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Minden _csatorna" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Min_den csatorna, ha bármely %s ablak aktív" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Csak az a csatorna, amely _ablaka aktív" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Csevegőszoba nevének felolvasása" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Az elrendezésmód engedélyezése a tartalom megjelenítésekor" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "(Kétszer gyorsan megnyomva)" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "(Háromszor gyorsan megnyomva)" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Alapértelmezett beszédszintetizátor" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Tényleges karakterlánc" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Helyettesítő szó" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Karakt_erenkénti visszhang engedélyezése" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Nem helykitöltő _mellékjelek kimondásának engedélyezése" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Jelenlegi hely" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "A keresett szöveg minimális hossza:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Keresési feltételek" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "_Csak a megváltozott sorok felolvasása a keresés során" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "_Keresés eredményének felolvasása" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "parancs" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Billentyűtársítás" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Alapértelmezett" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Tanulómód" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Műveletek" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braille társítások" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Könyvjelző" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Dátum és idő" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Áttekintés egérrel" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Objektum navigáció" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objektum részletei" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Nincs kiosztva" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Egyszerű áttekintés" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Beszéd és bőbeszédűség" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Az egyszerű áttekintés tartalma" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Módosítva" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "As_ztali" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Értesítés" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Érkezett" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Értesítés megjelenítő" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu beállításai ehhez: %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Braille kijelzés" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Csak ha nem" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Felolvasás" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Menti az ütköző profilt?" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "A felhasználói profil ütközik!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"A(z) %s profil már létezik.\n" -"Az új változtatásokkal folytatja a létező profil frissítését?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Felhasználói profil betöltése" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Arra készül, hogy megváltoztassa az aktív profilt.\n" -"Ha változtatásokat hajtott végre az Orka beállításainál, ezek el fognak " -"veszni az új profil betöltésekor.\n" -"\n" -"Folytatja a profil betöltését, elvetve a korábbi változtatásokat?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Profil mentése másként" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profil neve:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Felhasználói profil eltávolítása" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"A(z) %s felhasználói profil eltávolítására készül. Az összes el nem mentett " -"beállítás és a profilban elmentett összes beállítás el fog veszni. Szeretné " -"folytatni és eltávolítani ezt a profilt és az összes hozzá kapcsolódó " -"beállítást?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Mindent" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Alkalmazás" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Ablak" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Nincs" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Né_hány" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Legtöbb" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Sor" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Mondat" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Idézetblokk" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Gomb" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Felirat" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Jelölőnégyzet" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Kattintható elem" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kombinált listamező" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Leírás" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Címsor" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Keretek listája" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Kép" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Címke" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Jelölő" - -# Megjegyzés: Ez az üzenet akkor jelenik meg, ha a felhasználó a címsorokat listáztatja. Szándékosan írtam hosszabb oszlopnevet -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Címsorszint száma" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Hivatkozás" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Listaelem" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objektum" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Bekezdés" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Választógomb" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Vezérlőelem" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Kiválasztott elem" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Állapot" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Szöveg" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Érték" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Idézetblokkok listája" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Gombok listája" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Jelölőnégyzetek listája" - -# Megjegyzés: itt szándékosan hosszabb fordítást adtam meg, mivel ez a sztring a párbeszédablak címét jelöli. -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Kattintható elemek listája" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kombinált listamezők listája" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Szerkesztőmezők listája" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Űrlapmezők listája" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Címsorok listája" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Keretek listája" - -# megjegyzés: ezt a sztringet szándékosan hosszabban fordítottam, ez lesz a lista párbeszédablak címe -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Képek listája" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "%d. szintű címsorok listája" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Jelölők listája" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Nagy objektumok listája" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Hivatkozások listája" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listák listája" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Listaelemek listája" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Bekezdések listája" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Választógombok listája" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Táblázatok listája" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Nem látogatott hivatkozások listája" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Meglátogatott hivatkozások listája" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Oldalnavigáció" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "A weblap automatikus felolvasása, amint befejeződött a _letöltése" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Öss_zefoglaló megjelenítése egy lap első betöltésekor" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "A beszéd megállítása s_züneteknél" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s alapértelmezett hang" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Alapértelmezett" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiperlink" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Rendszer" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Nagybetűk" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Helyesírás-ellenőrzés" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "A _hibás szó betűzése" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "_Javítási javaslat betűzése" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "A hiba szöveg_környezetének felolvasása" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Munkafüzet cellakoordinátáinak felolvasása" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Mindig a teljes kijelölt cella_tartomány felolvasása" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "C_ellafejléc felolvasása" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Táblázatnavigáció" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Üres _cellák kihagyása" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "_Cella felolvasása" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Cella_koordináták felolvasása" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Cella _kiterjedésének felolvasása" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Attribútumnév" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Mutatónavigáció irányítása" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "_Strukturált navigáció engedélyezése" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Hang_téma:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Hangtéma" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Tömör" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d Értesítés" -msgstr[1] "%d Értesítés" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -# Megjegyzés: gondolom itt a kiejtés szerinti alakot kell írni. -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Kontrol" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "bal shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "bal alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "bal ctrl" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "jobb shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "jobb alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "jobb ctrl" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "bal meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "jobb meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "nagybetű zár" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "nagybetű zár" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "bal tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "bekszpész" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "enter" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "fel" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "le" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "balra" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "jobbra" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "bal startgomb" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "jobb startgomb" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menü" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Jobb Alt" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "súgó" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "szorzás" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "módváltó" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "iszkép" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "inzert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "del" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "hóm" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "hóm" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "a kúpos ékezettel" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "a körrel" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "áthúzott o" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "mínusz" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "inzert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Nagybetű zár" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Jobb Alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Startgomb" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Bal Alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "félkövér %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "dőlt %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "Félkövér dőlt %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "alsó index %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "félkövér alsó index %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktúr %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "duplán áthúzott %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "félkövér fraktúr %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "talpatlan %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "talpatlan félkövér %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "talpatlan dőlt %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "talpatlan félkövér dőlt %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "rögzített szélességű %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "pont nélküli %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "balra nyíl" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "felfelé nyíl" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "jobbra nyíl" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "lefelé nyíl" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "balra-jobbra nyíl" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "felfelé-lefelé nyíl" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "északnyugat felé mutató nyíl" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "északkelet felé mutató nyíl" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "délkelet felé mutató nyíl" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "egy sávból induló balra nyíl" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "egy sávból induló felfelé nyíl" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "egy sávból induló jobbra nyíl" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "egy sávból induló lefelé nyíl" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dupla balra nyíl" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dupla felfelé nyíl" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dupla jobbra nyíl" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dupla lefelé nyíl" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dupla balra-jobbra nyíl" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dupla Fel-le nyíl" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "északnyugat felé mutató dupla nyíl" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "északkelet felé mutató dupla nyíl" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "délkelet felé mutató dupla nyíl" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "délnyugat felé mutató dupla nyíl" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "jobbra mutató nyíl" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "jobbra mutató nyílhegy" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "mínusz" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "kisebb" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "nagyobb" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "kúpos ékezet" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "hacsek" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "pont" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dupla függőleges vonal" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "vízszintes ellipszis" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "minden" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "komplemens" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "parciális differenciális" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "létezik" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "nem létezik" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "üres halmaz" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "növekmény" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "eleme" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "nem eleme" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "kis eleme jel" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "tagként tartalmazza" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "tagként nem tartalmazza" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "kis tagként tartalmazza jel" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "bizonyítás vége" - -# megjegyzés: matematikai szimbólumként nem tudom, miként fordíthatnánk ezt a jelet -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produktum" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koproduktum" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "összeg" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minuszplusz" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "pontozott plusz" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "osztásjel" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "halmaz mínusz" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "csillag operátor" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "gyűrű operátor" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "pont operátor" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "négyzetgyök" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "köbgyök" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "negyedik gyök" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "aránylik ehhez" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "végtelen" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "derékszög" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "szög" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "mért szög" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "gömbszög" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "osztója" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "nem osztója" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "párhuzamos" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "nem párhuzamos" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logikai és" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logikai vagy" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "metszet" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unió" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integrál" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dupla integráljel" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "hármas integráljel" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "kontúr integrál" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "felületi integrál" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "térfogati integrál" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "óramutató járásával megegyező integrál" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "óramutató járásával megegyező kontúr integrál" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "óramutató járásával ellentétes kontúr integrál" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "azért" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "mert" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "arány" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "arány" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "pontozott mínusz" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "többlet" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometriai aránya" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetikus" - -# Szintén ilyen kérés. :-):-) -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "fordított tilde" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "fordított lusta S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "szinuszhullám" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "koszorúszorzat" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "nem tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "mínusz tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "aszimptotikusan egyenlő" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "nem aszimptotikusan egyenlő" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "nagyjából egyenlő" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "megközelítőleg, de valójában nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "sem megközelítőleg, sem ténylegesen nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "megközelítőleg egyenlő" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "szinte nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "közel azonos vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "háromszoros tilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "teljesen egyenlő" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "egyenértékű" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometriailag egyenértékű" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "közötti különbség" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "megközelíti a határértéket" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometriailag egyenlő" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "a kép körülbelül egyenlő" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "a kép nagyjából azonos" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "kettőspont egyenlő" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "egyenlő kettőspont" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "gyűrű az egyenlőben" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "gyűrű egyenlő" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "megfelel" - -# Megjegyzés: ebben nem vagyok biztos -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "becslés" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "egyenlő szögű" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "csillag egyenlő" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta egyenlő" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "a definíció szerint egyenlő" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "mérve" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "nem biztos, hogy egyenlő" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "azonos" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "nem azonos" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "szigorúan egyenértékű" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "kisebb vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "nagyobb vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "kisebb az egyenlőségjel fölött" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "nagyobb az egyenlőségjel fölött" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "kisebb, de nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "nagyobb, de nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "sokkal kisebb, mint" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "sokkal nagyobb, mint" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "között" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "nem egyenértékű" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "nem kisebb, mint" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "nem nagyobb, mint" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "se nem kisebb, se nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "se nem nagyobb, se nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "kisebb vagy egyenértékű" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "nagyobb vagy egyenértékű" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "nem kevesebb és nem egyenértékű" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "nem nagyobb mint és nem egyenértékű" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "kisebb vagy nagyobb, mint" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "nagyobb vagy kisebb, mint" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "nem kisebb és nem nagyobb mint" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "nem nagyobb és nem kevesebb mint" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "megelőzi" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "követi" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "megelőzi vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "követi vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "megelőzi vagy egyenértékű" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "követi vagy ekvivalens" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "nem előzi meg" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "nem követi" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "részhalmaza" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "halmaza" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "nem egy részhalmaza" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "nem a halmaza" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "részhalmaza vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "halmaza vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "nem egy részhalmaza és nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "nem halmaza és nem egyenlő" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "részhalmaza, nem egyenlő jellel" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "halmaza, nem egyenlő jellel" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "többszörös" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "többszörös szorzás" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "többszörös unió" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "négyzet képe" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "négyzet eredetije" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "négyzet képe vagy egyenlő ezzel:" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "négyzet eredetije vagy egyenlő ezzel:" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "négyzetes sapka" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "négyzetes alj" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "bekarikázott plusz" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "bekarikázott mínusz" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "bekarikázott szorzás" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "bekarikázott osztás" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "bekarikázott pont operátor" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "bekarikázott gyűrű operátor" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "bekarikázott csillag operátor" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "bekarikázott egyenlőségjel" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "bekarikázott mínusz" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "pluszjel négyzetben" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "mínuszjel négyzetben" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "szorzásjel négyzetben" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "pont operátor négyzetben" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "jobbra nyíl" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "balra nyíl" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "lefelé nyíl" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "felfelé nyíl" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "kijelentés" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modellezi" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "igaz" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "kényszeríti" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "háromszoros függőleges vonal jobboldali forgókereszttel" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "kettős függőleges vonal dupla jobboldali forgókereszttel" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "nem bizonyítja" - -# megjegyzés: használhatjuk esetleg a hamis fordítást is, nem tudom, hogy a matematikai terminológiában a hamis vagy a nem igaz az elfogadott -e -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "nem igaz" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "nem kényszeríti" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "negált kettős függőleges vonal dupla jobboldali forgókereszttel" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "megelőzi a relációban" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "követi a relációban" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normál alcsoportja" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "normál alcsoportként tartalmazza" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normál alcsoportja vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "normál alcsoportként tartalmazza vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "eredetije" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "képe" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "többértékű leképezés" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "Hermite-féle konjugált mátrix" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "beékelődés" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "derékszög ívvel" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "jobb háromszög" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "gyémánt operátor" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "pont operátor" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "csillag operátor" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "osztásszorzás" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "természetes összekapcsolás" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "bal oldali féldirekt szorzat" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "jobb oldali féldirekt szorzat" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "bal oldali féldirekt szorzat" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "jobb oldali féldirekt szorzat" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "fordított hullámvonal alakú egyenlőségjel" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "ívelt logikai vagy" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "ívelt logikai és" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "duplán részhalmaza" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "duplán halmaza" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dupla metszet" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dupla unió" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "vasvilla" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "egyenlő és párhuzamos ezzel:" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "kisebb mint, ponttal" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "nagyobb mint, ponttal" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "nagyon sokkal kisebb, mint" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "nagyon sokkal nagyobb, mint" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "kisebb mint egyenlő, vagy nagyobb mint" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "nagyobb mint egyenlő, vagy kisebb mint" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "egyenlő, vagy kisebb mint" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "egyenlő, vagy nagyobb mint" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "egyenlő, vagy megelőzi" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "egyenlő, vagy követi" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "nem előzi meg, vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "nem követi, vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "nem négyzetes képe, vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "nem négyzetes eredetije, vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "négyzetes képe, vagy nem egyenlő" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "négyzetes eredetije, vagy nem egyenlő" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "kisebb, de nem azonos ezzel:" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "nagyobb, de nem azonos ezzel:" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "megelőzi, de nem azonos ezzel:" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "követi, de nem ekvivalens ezzel:" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "nem normál alcsoportja ennek:" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "nem tartalmazza normál alcsoportként" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "nem normál alcsoportja, vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "nem tartalmazza normál alcsoportként, vagy egyenlő" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "függőleges három pont" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "középvonali vízszintes három pont" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "felfelé mutató jobb átlós három pont" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "lefelé mutató jobb átlós három pont" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "eleme, hosszú vízszintes vonallal" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "eleme, függőleges vonallal a vízszintes vonal végén" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "kis eleme, függőleges vonallal a vízszintes vonal végén" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "eleme, fölötte ponttal" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "eleme, felülvonással" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "kis eleme, felülvonással" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "eleme, aláhúzással" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "eleme, két vízszintes vonallal" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "tartalmazza, hosszú vízszintes vonallal" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "tartalmazza, függőleges vonallal a vízszintes vonal végén" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "kis tartalmazza, függőleges vonallal a vízszintes vonal végén" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "tartalmazza, felülvonással" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "kis tartalmazza, felülvonással" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z jelölési csoport tagság" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "bal felső egészrész" - -# Ez nem hiba! Szükség volt a módosításra, mivel az új Espeak már a kisbetűs #szavak előtti számokat sorszámneveknek nézi akkor, ha a számok után pont #van. Ez csak a GNOME-speech drivernél okoz problémát például az olyan #mondatrészeknél, mint pl. a 2009. december 29. (szerda). Ha a balzárójel #szöveg kis b betűvel kerülne kiküldésre, a december 29 helyett december #huszonkilencedik hangozna el. -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "jobb felső egészrész" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "bal alsó egészrész" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "jobb alsó egészrész" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "felső zárójel" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "alsó zárójel" - -# Megjegyzés: Meg kellene néznetek, vizuálisan hogy néz ki ez a jel, lehet, hogy a vizuális alak alapján kellene jobb fordítást kitalálni -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "balra mutató zárójel" - -# Megjegyzés: Meg kellene néznetek, vizuálisan hogy néz ki ez a jel, lehet, hogy a vizuális alak alapján kellene jobb fordítást kitalálni -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "jobbra mutató zárójel" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "bekarikázott pont operátor" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "unió ponttal" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "unió plusz jellel" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "Vonalak metszéspontja" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "négyzet alakú unió" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "fekete négyzet" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "üres négyzet" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "fekete káró" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "üres kör" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "fekete kör" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "üres listajel" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "közepesen fekete kis négyzet" - -# Felhasználói kérés volt a változtatás, megszokták az emberkék a régi #beszédszintetizátor által kimondott szöveget. :-):-) -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s aláhúzva" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s osztva" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s Függőleges elválasztóvonallal" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "alkalmazás" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "üres" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "félkövér" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "könyvjelző hozzáadása" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "könyvjelzők mentése" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "a könyvjelzők nincsenek mentve" - -# Fixme: Mi erről a véleményed? Ha akarod javítsd. -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nem találhatók könyvjelzők." - -# Fixme: Mi erről a véleményed? Ha akarod javítsd. -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Nemtalálható könyvjelző." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Átugró mód engedélyezve." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "A számológép képernyője nem érhető el" - -# Megjegyzés: szószerinti fordításban ez valóban ikon, viszont ha ez a betűstílus van kiválasztva, nagybetűs szöveg esetén a beszédmotor hangjelzést ad. -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "hangjelzés" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "A nagybetű stílus hangjelzésre állítva." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "nincs" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "A nagybetű stílus nincsre állítva." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "betűzés" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "A nagybetű stílus betűzésre állítva." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Az alkalmazás vezérli a mutatót." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "A Cthulhu vezérli a kurzort." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cella: %s" - -# Megjegyzés: nem akartam hozzá tenni a lefordított sztringhez a szokásos „A(z)” részt, mivel hosszú lenne a beszéd kimenet. -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s kijelölve" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s oszloptól %s sorig kijelölve" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s oszloptól %s sorig nincs kijelölve" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s nincs kijelölve" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "A kapcsoló használatának megakadályozása" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Kapcsoló használatának kikényszerítése" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "KAPCSOLÓ" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Opcionális kapcsolók" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Használat: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "A következő argumentumok érvénytelenek: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Az ismert futó alkalmazások kiírása" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Profil betöltése" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "A következő profil nem tölthető be: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"A Cthulhu nem indítható el, mert nem tud csatlakozni az asztalhoz.A " -"képernyőolvasó nem tudott elindulni, mivel nem tud kapcsolódni az asztali " -"környezethez" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "A beállításkezelőt nem lehetett aktiválni. Kilépés." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Már fut egy képernyőolvasó ebben a munkamenetben.\n" -"Futtassa az „cthulhu --replace” parancsot az aktuális Orka folyamat " -"lecseréléséhez." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NÉV" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Alternatív könyvtár használata a felhasználói beállításokhoz" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "KÖNYVTÁR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Az alkalmazás verziójának kiírása" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Jelenleg futó Cthulhu példány cseréje" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Megjeleníti a súgóképernyőt, majd kilép." - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" -"A hibakövetési információk mentése a debug-ÉÉÉÉ-HH-NN-OO:PP:MM.out fájlba" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "A hibakövetési információk mentése a megadott fájlba" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FÁJL" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Felhasználói beállítások (szöveges változat)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Felhasználói beállítások (grafikus változat)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "A hibákat az https://groups.io/g/stormux levelezőlistán jelezheti." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "A kijelölt tartalom a vágólapra mozgatva." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "kivágás" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "A kijelölt tartalom a vágólapra másolva." - -# Megjegyzés: a rövid vágólap művelet üzenetet szándékosan fordítottam így. -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "másolás" - -# Megjegyzés: ezt az üzenetet szándékosan fordítottam így, mivel a tartalmak beillesztve a vágólapról üzenet értelmetlen lett volna. -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "A tartalom beillesztve a vágólapról." - -# Megjegyzés: ezt a rövid vágólap művelet jelző üzenetet szándékosan fordítottam így, mivel a többi képernyőolvasó is ilyen formában használja ezt a vágólap művelet jelző üzenetet. -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "beillesztés" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Nincs értesítés, ha a partnerek gépelnek." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "Értesítés, ha a partnerek gépelnek." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Üzenet ezen csevegőszobából: %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Új csevegőlap: %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Ne mondja ki a csevegőszoba nevét." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "Csevegőszoba nevének kimondása." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Ne jelenítse meg a csevegőszoba üzenetelőzményeit." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "A csevegőszoba üzenetelőzményeinek megjelenítése." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "törlés kezdete" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "törlés vége" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "beszúrás kezdete" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "beszúrás vége" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "kiemelés kezdete" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "kiemelés vége" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "javaslat vége" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Elemblokk vége." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Nem egy elemblokkon áll." - -# Megjegyzés: nem akartam hozzá tenni a lefordított sztringhez a szokásos „A(z)” részt, mivel hosszú lenne a beszéd kimenet. -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "Minden elem kijelölve" - -# Megjegyzés: az eredeti üzenet hibás volt, egy párbeszédablaknak nem alapértelmezett billentyűje, hanem alapértelmezett gombja van, ezt mondja ki az Orka -# ha a felhasználó kéri. -# Most úgy fordítottam ezt az üzenetet, hogy %s az alapértelmezett gomb, de megváltoztathatod szükség esetén a következő formára is: -# Az alapértelmezett gomb: %s -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "%s az alapértelmezett gomb" - -# Megjegyzés: az eredeti üzenet hibás volt, egy párbeszédablaknak nem alapértelmezett billentyűje, hanem alapértelmezett gombja van, ezt mondja ki az Orka -# ha a felhasználó kéri. -# Most úgy fordítottam ezt az üzenetet, hogy %s az alapértelmezett gomb, de megváltoztathatod szükség esetén a következő formára is: -# Az alapértelmezett gomb: %s -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "%s az alapértelmezett gomb. Nem érhető el" - -# Megjegyzés: az eredeti üzenet hibás volt, egy párbeszédablaknak nem alapértelmezett billentyűje, hanem alapértelmezett gombja van, ezt mondja ki az Orka -# ha a felhasználó kéri. -# Most úgy fordítottam ezt az üzenetet, hogy %s az alapértelmezett gomb, de megváltoztathatod szükség esetén a következő formára is: -# Az alapértelmezett gomb: %s -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Az alapértelmezett gomb nem található" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "alsó index %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "felső index %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Nem egy párbeszédablakban van" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "az egész dokumentum kijelölve" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "az egész dokumentum nincs kijelölve" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "a dokumentum kijelölve a kurzorpozíciótól" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "a dokumentum kijelölése megszüntetve a kurzorpozíciótól" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "a dokumentum kijelölve a kurzorpozícióig" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "A dokumentum nincs kijelölve a kurzorpozícióig" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dinamikus oszlopfejléc beállítva a következő sorhoz: %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "A dinamikus oszlopfejléc törölve lett." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dinamikus sorfejléc beállítva a következő oszlophoz: %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "A dinamikus sorfejléc törölve lett." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "üres" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobájt" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabájt" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Nem találhatók fájlok." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Az egyszerű áttekintés tartalma hozzáfűzve a vágólaphoz." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Az egyszerű áttekintés tartalma a vágólapra másolva." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Az egyszerű áttekintés nem használható." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Belépés az egyszerű áttekintés módba." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Kilépés az egyszerű áttekintés módból." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Az egyszerű áttekintés az aktuális objektumra korlátozva" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Az egyszerű áttekintés korlátlan" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "képletet tartalmaz" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "megnyitja a párbeszédablakot" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "megnyitja a rácsot" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "megnyitja a listadobozt" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "megnyitja a menüt" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "megnyitja a fanézetet" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "kép hivatkozás" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "A megadott billentyű már ehhez van kötve: %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Billentyűütés: %s. A megerősítéshez nyomja meg az Entert." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Az új billentyű: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "A billentyűtársítás törölve. A megerősítéshez nyomja meg az Entert." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "A billentyűtársítás törölve." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "üsse le az új billentyűt" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "karakterek" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "A billentyűvisszhang karakterenkéntire állítva." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nincs" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "A billentyűvisszhang nincsre állítva." - -# Megjegyzés: ha tudsz jobb üzenetet, nyugodtan átírhatod a fordítást. -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "karakterek és szavak" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "A billentyűvisszhang karakterek és szavakra állítva." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "mondatok" - -# Szintén a word szó ezt jelenti. Ha a felhasználó lenyomja például ez esetben a szóköz billentyűt, az Orka kimondja az utoljára begépelt szót. -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "A billentyűvisszhang mondatonkéntire állítva." - -# Itt a word szó szavankénti visszhangot jelent, nem egy szót. -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "szavak" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "A billentyűvisszhang szavankéntire állítva." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "szavak és mondatok" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "A billentyűvisszhang szavak és mondatokra állítva." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "%s által körbezárt" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "biztosításmatematikai szimbólum" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "egy doboz" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "egy kör" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "egy hosszú osztás jel" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "egy gyökjel" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "egy lekerekített doboz" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "vízszintesen áthúzott" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "függőlegesen áthúzott" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "egy lefelé mutató átlós áthúzás" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "egy felfelé mutató átlós áthúzás" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "egy északnyugat felé mutató nyíl" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "egy vonal alján" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "egy vonalat a bal oldalán" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "egy vonal jobb oldalán" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "egy vonal tetején" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "egy fázisvektor szöge" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "egy arab faktoros szimbólum" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "és" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "tört kezdete" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "törtvonal nélküli tört kezdete" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "felette" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "tört vége" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "Négyzetgyöke" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "Köbgyöke" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "gyöke" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "gyök kezdete" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "gyök vége" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "alsó indexe" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "felső indexe" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "bal alsó indexe" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "bal felső indexe" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "szöveg alatti indexe" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "szöveg feletti indexe" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "Táblázat vége" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "beágyazott táblázat vége" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "elérhetetlen" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Letiltva" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Behúzás és igazítás felolvasása letiltva." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Engedélyezve" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Behúzás és igazítás felolvasása engedélyezve." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Tanulómód. Kilépéshez nyomja meg az Esc billentyűt." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Belépés a tanulómódba. Nyomjon meg egy billentyűt a funkciójának " -"meghallgatásához. A képernyőolvasó általános billentyűparancsainak " -"listájának megjelenítéséhez nyomja le az F2, a használt alkalmazástól függő " -"képernyőolvasó parancsok listájának megjelenítéséhez az F3 billentyűt. A " -"dokumentáció megjelenítéséhez nyomja meg az F1 billentyűt. Ha ki szeretne " -"lépni a tanulómódból, nyomja meg az ESC billentyűt." - -# Megjegyzés: szó szerinti fordításban idézetblokk elhagyása lenne az üzenet, de szerintem az idézetblokk vége jobb (hasonló lesz az üzenet a listák végének bejelentésekor és a táblázat végének bejelentésekor). -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "idézetblokk vége." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "részletek vége." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "cikklista vége." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "Ábra vége." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "űrlap vége." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "Főcím vége." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "Kiegészítő tartalom vége." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "információ vége." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "Fő tartalom vége." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "navigáció vége." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "speciális terület vége." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "keresés vége." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "lista vége." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "panel vége." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "táblázat vége." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "buborék súgó vége." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "kivonat vége." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "Elismerések vége." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "Utószó vége." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "függelék vége." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "Irodalomjegyzék vége." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "Fejezet vége." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "Kolofon vége." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "Következtetés vége." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "Köszönet vége." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "Köszönet vége." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "Dedikáció vége." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "végjegyzet vége." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "felirat vége." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "Epilógus vége." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "Hibajegyzék vége." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "Példa vége." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "Előszó vége." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "Szószedet vége." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "tárgymutató vége." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "Bevezetés vége." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "oldallista vége." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "Rész vége." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "Előszó vége." - -# Megjegyzés: szó szerinti fordításban idézetblokk elhagyása lenne az üzenet, de szerintem az idézetblokk vége jobb (hasonló lesz az üzenet a listák végének bejelentésekor és a táblázat végének bejelentésekor). -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "Prológus vége." - -# Megjegyzés: szó szerinti fordításban idézetblokk elhagyása lenne az üzenet, de szerintem az idézetblokk vége jobb (hasonló lesz az üzenet a listák végének bejelentésekor és a táblázat végének bejelentésekor). -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "Idézőjel vége." - -# Megjegyzés: erre végképp nincs jobb ötletem. -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "GYIK vége." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "javaslat vége." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "Tartalomjegyzék vége." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "a kurzorpozíció alatti sor kijelölve" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "a kurzorpozíció feletti sor kijelölve" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "a kurzorpozíció alatti sor kijelölése megszüntetve" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "a kurzorpozíció feletti sor kijelölése megszüntetve" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Kilépés a tanulómódból." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "a sor kijelölve a kurzorpozíciótól a sor elejéig" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "a sor kijelölve a kurzorpozíciótól a sor végéig" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "hivatkozás" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "azonos lap" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "azonos oldal" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "különböző oldal" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s hivatkozás erre a fájlra: %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s hivatkozás" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "meglátogatott %s hivatkozás" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"A listában való navigációhoz használja a felfelé és lefelé nyilakat, a " -"kilépéshez pedig az Escape billentyűt." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Az összes élő régió kikapcsolása" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "az élő régiók udvariassági szintje visszaállítva" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "%s udvariassági szint" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "élő régió beállítása nyersre" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "élő régiók kikapcsolva" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "élő régió beállítása udvariasra" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "élő régió beállítása durvára" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Az élő régiók figyelése kikapcsolva" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Az élő régiók figyelése bekapcsolva" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "Nincs helyi elmentett üzenet" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Az élő régiók támogatása kikapcsolva" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nem található" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Nem állapítható meg a jelenlegi hely." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "kikapcsolva" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "bekapcsolva" - -# Szintén a sorszámnevek kezelése miatt kellett a változtatás. Csak a #kimondásra van hatással. -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "Hibásan írt szó" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Elgépelt szó: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Kontextusa: %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Böngésző mód bekapcsolva" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Fókuszmód bekapcsolva" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "A fókuszmód bekapcsolásához nyomja meg a(z) %s billentyűkombinációt." - -# Megjegyzés: szándékosan hosszabb sztringet adtam meg a fordításban, ha nincs jobb ötlet, maradjon ez. -# Ez a parancs a képernyőolvasót fókuszmódban tartja, így az űrlapok kezelésekor nem kell minden esetben módot váltani. -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Rögzített fókuszmód bekapcsolva." - -# Megjegyzés: szándékosan hosszabb sztringet adtam meg a fordításban, ha nincs jobb ötlet, maradjon ez. -# Ez a parancs a képernyőolvasót fókuszmódban tartja, így az űrlapok kezelésekor nem kell minden esetben módot váltani. -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Rögzített böngészőmód bekapcsolva." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Elrendezés mód." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objektum mód." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "A mutató átirányítva az aktuális elemre." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "A felbukkanó objektum nem található." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Az áttekintés egérrel mód letiltva." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Az áttekintés egérrel mód engedélyezve." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Hiba: a kért objektumok listája nem hozható létre." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Nincs gyermek objektum." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Nincs következő objektum." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Nincs szülő objektum." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Nincs korábbi objektum." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Az egyszerűsített navigációs mód engedélyezve." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Az egyszerűsített navigációs mód letiltva." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "%d. fa szint" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Az új elem hozzáadva." - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Nem találhatók műveletek a következőn: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Nincs fókusz" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nincs kijelölt alkalmazás." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Nincs több idézetblokk." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Nincs több gomb." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Nincs több jelölőnégyzet." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Nincs több nagy objektum." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Nincs több kattintható elem." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Nincs több kombinált listamező." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Nincs több szerkesztőmező." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Nincs több űrlapmező." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Nincs több címsor." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Nincs több %d. szintű címsor." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Nincs több belső keret." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Nincs több kép." - -# Fixme: Mi erről a véleményed? Ha akarod javítsd. -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nincs több jelölő." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Nincs több hivatkozás." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Nincs több lista." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Nincs több listaelem." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Nincs több élő régió." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Nincs több bekezdés." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Nincs több választógomb." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Nincs több elválasztó." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Nincs több táblázat." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Nincs több nem látogatott hivatkozás." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Nincs több látogatott hivatkozás." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Nincs kijelölt szöveg." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nem egy hivatkozáson áll." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Értesítés" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Vissza a lista aljára." - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Vissza a lista tetejére" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Nincsenek értesítések" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "Számjegyenként" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Számok kimondása számjegyenként." - -# Itt a words szó azt jelöli, hogy a számok hagyományos alakban lesznek kimondva, a 123 pl. százhuszonhárom üzenettel magyar beszédszintetizátor esetén. -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "hagyományos alak" - -# Megjegyzés: ha erre a beállításra kapcsol ideiglenesen a felhasználó, a számok kimondása a hagyományos formátumban történik, nem külön számjegyenként. Jó példa erre a 123 szám, ilyenkor a magyar beszédszintetizátor százhuszonhárom üzenetet mond. -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Számok kimondása a hagyományos alakban." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "kikapcsolva" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "bekapcsolva" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Betöltés, kis türelmet." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "A betöltés befejeződött." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s betöltése befejeződött." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "A lap tartalma %s" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "az oldal kijelölve a kurzorpozíciótól" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "az oldal kijelölve a kurzorpozícióig" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "az oldal kijelölése megszüntetve a kurzorpozíciótól" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "az oldal kijelölése megszüntetve a kurzorpozícióig" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "a bekezdés kijelölve a kurzorpozíciótól" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "a kurzorpozíció feletti bekezdés kijelölve" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "a bekezdés kijelölése megszüntetve a kurzorpozíciótól" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "a kurzorpozíció feletti bekezdés kijelölése megszüntetve" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Egy Orka beállítások párbeszédablak már nyitva van.\n" -"Zárja be a párbeszédablakot egy új megnyitása előtt." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "%(position)d. dia, összesen %(count)d." - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "A profil beállítva a következőre: %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nem találhatók profilok." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "folyamatjelző: %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Mindent" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "A központozási szint mindre állítva." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Legtöbb" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "A központozási szint legtöbbre állítva." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nincs" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "A központozási szint nincsre állítva." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Néhány" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "A központozási szint néhányra állítva." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Keresés." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "A keresés befejeződött." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu beállítások újratöltve." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "A kijelölt szöveg: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "A kijelölt tartalom törölve." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "A kijelölt tartalom visszaállítva." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Nincs kijelölve" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Méret: %d, %d. Hely: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Szélesség: %d. Magasság: %d. %d balról. %d fentről." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Beszéd letiltva." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Beszéd engedélyezve." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "gyorsabb." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "lassabb." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "magasabb." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "mélyebb." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "Hangosabb." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "Halkabb." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Sebesség: %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Hangmagasság: %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Hangerő: %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher modul: %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher hang: %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nincs elérhető Speech-dispatcher modul" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nincs elérhető Speech-dispatcher hang" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Beszédbeállítások mentve" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "A beszédbeállítások nem menthetők" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Részletességi szint: tömör" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Részletességi szint: részletes" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " pont pont pont" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "A Cthulhu üdvözli." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu a hullámok alatt rejtőzik." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Alvó mód bekapcsolva ehhez: %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Alvó mód kikapcsolva ehhez: %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "A beszéd nem érhető el." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Nem található" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Nem található állapotsor" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "a karakterlánc nem található" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Strukturált navigációs billentyűk kikapcsolva." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Strukturált navigációs billentyűk engedélyezve." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nincs több" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "%(row)d. sor, %(column)d. oszlop" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Táblázat vége" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Cella felolvasása" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Sor felolvasása" - -# fixme: szintén táblázat navigáció. -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Nem egységes" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Itt nincs táblázat." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "A táblázat oszlopai újrarendezve" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "A táblázat sorai újrarendezve" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "%d. oszlop" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "%(index)d. oszlop, %(total)d oszlopból." - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Ez az alsó sor." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Ez az első sor." - -# Megjegyzés: nem akartam hozzá tenni a lefordított sztringhez a szokásos „A(z)” részt, mivel hosszú lenne a beszéd kimenet. -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "%s oszlop kijelölve" - -# Megjegyzés: nem akartam hozzá tenni a lefordított sztringhez a szokásos „A(z)” részt, mivel hosszú lenne a beszéd kimenet. -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "%s oszloptól %s oszlopig kijelölve" - -# Megjegyzés: nem akartam hozzá tenni a lefordított sztringhez a szokásos „A(z)” részt, mivel hosszú lenne a beszéd kimenet. -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "%s oszloptól %s oszlopig nincs kijelölve" - -# Megjegyzés: nem akartam hozzá tenni a lefordított sztringhez a szokásos „A(z)” részt, mivel hosszú lenne a beszéd kimenet. -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "%s oszlop nincs kijelölve" - -# Szintén a sorszámnév kezelés miatt kellett változtatni. -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "%d. sor" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "%(index)d. sor, %(total)d sorból." - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Ez az első oszlop." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Ez az utolsó oszlop." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "A sor törölve." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Az utolsó sor törölve." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "A sor beszúrva." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "A sor beszúrva a táblázat végére." - -# Megjegyzés: nem akartam hozzá tenni a lefordított sztringhez a szokásos „A(z)” részt, mivel hosszú lenne a beszéd kimenet. -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "%s sor kijelölve" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "%s sortól %s sorig kijelölve" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "%s sortól %s sorig nincs kijelölve" - -# Megjegyzés: nem akartam hozzá tenni a lefordított sztringhez a szokásos „A(z)” részt, mivel hosszú lenne a beszéd kimenet. -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "%s sor nincs kijelölve" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "kijelölve" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "Nincs kijelölve" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%-H óra %-M perc, %-S másodperc." - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%-H óra %-M perc." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "visszavonás" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "ismétlés" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu verzió: %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "üreshely" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Vissza a lap aljára." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Vissza a lap tetejére." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elem" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "A cella %d sor magas" -msgstr[1] "A cella %d sor magas" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d oszloppal" -msgstr[1] "%d oszloppal" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "A cella %d oszlop széles" -msgstr[1] "A cella %d oszlop széles" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "Túl sok karaktert írt be (%d karaktert)" -msgstr[1] "Túl sok karaktert írt be (%d karaktert)" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d párbeszédablak)" -msgstr[1] "(%d párbeszédablak)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d nem fókuszált párbeszédablak" -msgstr[1] "%d nem fókuszált párbeszédablak" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bájt" -msgstr[1] "%d bájt" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fájl található" -msgstr[1] "%d fájl található" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d űrlap" -msgstr[1] "%d űrlap" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d címsor" -msgstr[1] "%d címsor" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elem" -msgstr[1] "%d elem" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d jelölő" -msgstr[1] "%d jelölő" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d elem található" -msgstr[1] "%d elem található" - -# Megjegyzés: szó szerinti fordításban idézetblokk elhagyása lenne az üzenet, de szerintem az idézetblokk vége jobb (hasonló lesz az üzenet a listák végének bejelentésekor és a táblázat végének bejelentésekor). -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "%d idézetblokk vége." -msgstr[1] "%d idézetblokk vége." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "%d lista vége." -msgstr[1] "%d lista vége." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Ismeretlen elemszámú lista" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d elemű lista" -msgstr[1] "%d elemű lista" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Ismeretlen számú hírforrás" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "%d cikket tartalmazó hírcsatorna" -msgstr[1] "%d cikket tartalmazó hírcsatorna" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Leírások listája %d kifejezéssel" -msgstr[1] "Leírások listája %d kifejezéssel" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d érték" -msgstr[1] "%d érték" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "Matematikai táblázat %d sorral" -msgstr[1] "Matematikai táblázat %d sorral" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d oszloppal" -msgstr[1] "%d oszloppal" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "beágyazott matematikai táblázat %d sorral" -msgstr[1] "beágyazott matematikai táblázat %d sorral" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d értesítés.\n" -msgstr[1] "%d értesítés.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d százalék." -msgstr[1] "%d százalék." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "a dokumentum %d százaléka beolvasva" -msgstr[1] "a dokumentum %d százaléka beolvasva" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d képpont" -msgstr[1] "%d képpont" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s karakter" -msgstr[1] "%(count)d %(repeatChar)s karakter" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d elem kijelölve, %(total)d elemből." -msgstr[1] "%(index)d elem kijelölve, %(total)d elemből." - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d alapértelmezett képernyőolvasó billentyűparancs található." -msgstr[1] "%d alapértelmezett képernyőolvasó billentyűparancs található." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"%(count)d képernyőolvasó billentyűparancs található a(z) %(application)s " -"alkalmazáshoz." -msgstr[1] "" -"%(count)d képernyőolvasó billentyűparancs található a(z) %(application)s " -"alkalmazáshoz." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d szóköz" -msgstr[1] "%d szóköz" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulátor" -msgstr[1] "%d tabulátor" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d táblázat" -msgstr[1] "%d táblázat" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "Ismeretlen méretű táblázat" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "Ismeretlen sorszámú táblázat, %d oszloppal" -msgstr[1] "Ismeretlen sorszámú táblázat, %d oszloppal" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "Táblázat %d sorral, ismeretlen számú oszloppal" -msgstr[1] "Táblázat %d sorral, ismeretlen számú oszloppal" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "Táblázat %d sorral" -msgstr[1] "Táblázat %d sorral" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d másodperce" -msgstr[1] "%d másodperce" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d perce" -msgstr[1] "%d perce" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d órával ezelőtt" -msgstr[1] "%d órája" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d napja" -msgstr[1] "%d napja" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d nem látogatott hivatkozás" -msgstr[1] "%d nem látogatott hivatkozás" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d meglátogatott hivatkozás" -msgstr[1] "%d meglátogatott hivatkozás" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "kapcsológomb" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(index)d. elem, összesen %(total)d." - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d per %(total)d." - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "%(index)d elem" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "%d. SZINT" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "%d. fa szint" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "%d. FA SZINT" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "%s részletei" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "részletei vannak ebben: %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "javaslat" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "kombinált szerkesztőmező" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "szerkeszthető tartalom" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "cikklista" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "ábra" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "kivonat" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "Elismerések" - -# Itt a word szó szavankénti visszhangot jelent, nem egy szót. -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "Utószó" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "függelék" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "Irodalomjegyzék-bejegyzés" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "Irodalomjegyzék" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "Fejezet" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "Kolofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "Következtetés" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "Borító" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "Köszönet" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "Köszönet" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "Dedikáció" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "Végjegyzet" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "végjegyzet" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "Felirat" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "Epilógus" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "Hibajegyzék" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "példa" - -# Itt a word szó szavankénti visszhangot jelent, nem egy szót. -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "Előszó" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "szószedet" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "tárgymutató" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "bevezetés" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "Oldaltörés" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "Oldallista" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "Rész" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "előszó" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "Prológus" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "idézőjel" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "GYIK" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "Alcím" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "Tartalomjegyzék" - -# Megjegyzés: ezt véletlenül korábban elgépeltem, h%d a helyes msgstr érték -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(level)d. %(role)s szint" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "Vízszintes görgetősáv" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "Függőleges görgetősáv" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "vízszintes csúszka" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "Függőleges csúszka" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "vízszintes felosztó elem" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "függőleges felosztó elem" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "kapcsoló" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Ikonpanel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "fejléc" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "Kiegészítő tartalom" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "Információk" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "Fő tartalom" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigáció" - -# megjegyzés: ez lehetne talán „speciális terület” vagy „speciális navigációs terület” a fordítói magyarázat alapján, nem vagyok biztos benne -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "Speciális terület" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "Keresés" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "meglátogatott hivatkozás" - -# Megjegyzés: ezt a vezérlőelemet a Windows alatt elérhető képernyőolvasók menügombnak hívják, nálunk is maradjon így. Az üzenet csak a beszédszintetizátor által van kimondva, és csak a Braille-kijelzőn jelenik meg. -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "menügomb" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "Növekvő rendezés" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "Csökkenő rendezés" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "rendezve" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "Kattintható elem" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "összecsukott" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "kiterjesztett" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "van hosszú leírása" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "vízszintes" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "függőleges" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "bejelölve" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nincs bejelölve" - -# Megjegyzés: itt jobb a hosszabb „bekapcsolva” üzenet. -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "bekapcsolva" - -# Megjegyzés: Itt jobb a hosszabb „kikapcsolva” üzenet. -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "kikapcsolva" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "részben bejelölve" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "lenyomva" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "nincs lenyomva" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "nincs kiválasztva" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "kiválasztott" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "nincs kiválasztva" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "Nincs kijelölve" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "meglátogatott hivatkozás" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "nem látogatott hivatkozás" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "letiltott" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "írásvédett" - -# Ez itt azt jelenti, ha a felhasználó egy olyan szerkesztőmezőben van, ami nem szerkeszthető, #tehát nem szövegtörzs. -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "írsvd" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "szükséges" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "többválasztós" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "érvénytelen bejegyzés" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "érvénytelen" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "helyesírási hiba" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "elgépelés" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "nyelvhelyességi hiba" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "nyelvi hiba" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Keresés" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Képernyőolvasó keresés párbeszédablaka" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Bezárás" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Keresés" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Keresés:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Keresés erre:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Ablak teteje" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Ablak teteje" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Kezdés:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Kö_rbe" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Keresés _visszafelé" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Keresés iránya:" - -# Megjegyzés: a keresésnél kiegészítettem ennek a jelölőnégyzetnek a #feliratát -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Kis- és _nagybetűk megkülönböztetése" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Csak _teljes szóra" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Keresési feltételek" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Alapértelmezett" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Nagybetűkké" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiperlink" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Rendszer" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Alkalmazás" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Ablak" - -# Megjegyzés: Mivel mindenhol régóta Gáborral egyeztetve az Cthulhu nevet magyarosan Orkaként írjuk a fordításban, így a fordítást megváltoztattam Orka képernyőolvasóra az Cthulhu képernyőolvasó helyett. -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu beállításai" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Súgó" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Alkalmaz" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Billentyűzetkiosztás" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Aktív profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Kezdeti profil:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Betöltés" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Mentés máskén_t" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Eltávolítás" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profilok" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Buboréksúgók megjele_nítése" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Az e_gér alatti objektum felolvasása" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Egér" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "I_dőformátum:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Dá_tumformátum:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Idő és dátum" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Folyamatjelző frissítésének kimondása" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Folyamatjelző frissítésének megjelenítése a _Braille-kijelzőn" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Gyakoriság másodpercben:" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Alkalmazás" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Hangjelzés a folyamatjelző frissülésekor" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Folyamatjelző frissítési beállításai" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Elő_re- és visszatekerés engedélyezése a felolvasás közben" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Strukturált navigáció engedélyezése a _felolvasás közben" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "_Kimondás:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "_Idézetblokkok bejelentése felolvasás közben" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "_Listák bejelentése felolvasás közben" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "_Táblázatok bejelentése felolvasás közben" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "_Panelek bejelentése felolvasás közben" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "ű_rlapok bejelentése felolvasás közben" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "_Jelölők bejelentése felolvasás közben" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Felolvasási beállítások" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Elem _megjelenítése:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Általános" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Hange_rő:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Hangmaga_sság:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "Se_besség:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "Személ_y:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "Nyel_v" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Beszédszintetizát_or:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Beszé_drendszer:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Hangtípus:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Nagybetű jelzési stílus:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Hangtípusok beállításai" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Több NagyBetűt tartalmazó kifejezések _szavankénti felolvasása" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "_Számok kimondása számjegyenként" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Globális hangbeállítások" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Hang" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Beszéd _engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Rés_zletes" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Részletesség" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Mindent" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Központozás szintje" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Csak a képernyőn megjelenő szöveg kimondása" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Üres sorok felolvasása" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Be_húzás és igazítás felolvasása" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Gy_orsbillentyűk felolvasása" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "P_ozícióadatok kimondásának engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Oktatói üzenetek kimondásának engedélyezése" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Részletes rendszerüzenetek engedélyezése" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "A színek kimondása szín_nevekkel" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "_Idézetblokkok bejelentése navigálás közben" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "_Listák bejelentése navigálás közben" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "_Táblázatok bejelentése navigálás közben" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "A _hibásan írt szó jelzés felolvasása" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "_Panelek bejelentése navigálás közben" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "_Jelölők bejelentése navigálás közben" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Ű_rlapok bejelentése navigálás közben" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "_Leírás felolvasása" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "A teljes sor kimondása a _táblázatkezelőkben" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "A teljes sor kimondása a _dokumentum táblázatokban" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "A teljes sor kimondása a _grafikus táblázatokban" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Kimondott szövegkörnyezet" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Beszéd" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Braille támogatá_s engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Rövidített szerepnevek" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "A _sorvég jel szimbólum letiltása" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Fordítási _tábla:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "I_rodalmi braille támogatás engedélyezése" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "_Szótörés engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Megjelenítés beállításai" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Nincs" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Kiválasztásjelző" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hivatkozásjelző" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "_Frissülő üzenetek engedélyezése" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Ü_zenet megjelenítés időtartama másodpercben:" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Üzenetek _megtartása" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "_Részletes üzenetek engedélyezése" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Frissülő üzenetek beállításai" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Billentyű_visszhang engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "_Alfabetikus billentyűk engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "_Számbillentyűk engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "_Írásjelek engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "A szókö_z billentyű engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "_Módosítóbillentyűk engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "_Funkcióbillentyűk engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Művele_tbillentyűk engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Navigá_ciós billentyűk engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Szava_nkénti visszhang engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Mon_datonkénti visszhang engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Billentyűvisszhang" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Képernyőolvasó _módosítóbillentyűk:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Billentyűtársítások" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Kiejtési szótár" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Új _bejegyzés" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Törlés" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Kiejtés" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Minden felolvasása" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Felolvasás _némítása" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Visszaállítás" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Szövegattribútumok" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Az aljá_ra" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Eggyel _lejjebb" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Eggyel _feljebb" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "A _tetejére" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" -"Kiválasztott attribútum\n" -"beállítása" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Braille-kiválasztás jelző" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Szövegattribútumok" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "MI asszisztens engedélyezése" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Szolgáltató:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Helyi - Ingyenes)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API _kulcsfájl:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Az API kulcsfájl útvonala" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "_Claude API kulcs beszerzése" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Nyissa meg a böngészőt a Claude API kulcs lekéréséhez és automatikus " -"mentéséhez" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Megerősítés kérése MI műveletek előtt" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _modell:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Modell neve az Ollama számára (pl. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _végpont:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API végpont URL (pl. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Képernyőkép _minősége:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Alacsony" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Közepes" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Magas" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "MI asszisztens" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Nyelvkód:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Méretezési tényező:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Szürkeárnyalatos kép" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "Kép _invertálása" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Fekete-fehér kép" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Fekete/fehér _küszöb:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "Színek _elemzése" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Eredmények másolása _vágólapra" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : aladár, á : ádám, b : béla, c : cecil, d : dénes, e : elemér, é : éva, " -"f : ferenc, g : gábor, h : hugó, i : ilona, í : ilona hosszú, j : józsef, " -"k : károly, l : lászló, m : márton, n: nándor, o : olga, ó : olga hosszú, " -"ö : ödön, ő : ödön hosszú, ü : ürmös, ű : ürmös hosszú, p : péter, q : " -"kvelle, r : róbert, s : sándor, t : tamás, u : ubul, ú : ubul hosszú, v : " -"vilmos, w : dupla vilmos, x : xénia, y : ipszilon, z : zoltán" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "háttérszín" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "háttér teljes magassága" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "háttérárnyalás" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "szövegirány" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "szerkeszthető" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "betűkészlet" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "előtérszín" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "előtérárnyalás" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "betűkészlethatás" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "behúzás" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "Hiba" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "láthatatlan" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "igazítás" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "nyelv" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "bal margó távolsága" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "sormagasság" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "bekezdés stílusa" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "képpontok száma a sorok felett" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "képpontok száma a sorok alatt" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "Képpontok a sortörésen belül" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "jobb oldali margó távolsága" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "emelés" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "méretezés" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "méret" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "nyújtás" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "áthúzás" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stílus" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "szövegdekoráció" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "szöveg elforgatása" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "szöveg árnyékolása" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "aláhúzás" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "változat" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "függőleges igazítás" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "vastagság" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "tördelés módja" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "írási mód" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "Igen" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "Nem" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "nincs" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "nyelv" - -# Fixme: Ezt inkább hagytam ahogy van. -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "alacsony" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "dupla" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "aláhúzás" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "áthúzás" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "villogás" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "fekete" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "szimpla" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dupla" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "alacsony" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "karakter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "szó" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "szó karakter" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "balról jobbra" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "jobbról balra" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "balra zárt" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "jobbra zárt" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "középre zárt" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "nincs igazítás" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "sorkizárt" - -# fixme: erre kitalálni hogy mi ez és máshol mire fordul -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra sűrű" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra sűrű" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "sűrű" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "félig sűrű" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normál" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "félig kiterjesztett" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "kiterjesztett" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra kiterjesztett" - -# fixme: idáig, ez mind ugyanahhoz tartozott -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra kiterjesztett" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "kis kapitális" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "ferde" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "dőlt" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Alapértelmezett" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Szövegtörzs" - -# Fixme: vagy lehet hogy szöveg törzs? -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Címsor" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "Alapvonal" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "Alsó" - -# fixme: gyanús ez nekem... -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "szuper" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "felső" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "szöveg felett" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "középre" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "alulra" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "szöveg alatt" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "öröklött" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "balról jobbra, fentről le" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "jobbról balra, fentről le" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "fentről le, jobbról balra" - -# fixme: Fogalmam sincs milyen attribútum érték ez, az írási mód állítja elő (http://www.w3.org/TR/2001/WD-css3-text-20010517/). -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "fentről le, balról jobbra" - -# Fixme: szintén ugyanaz, mint az előzőnél. -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "lentről fel, jobbról balra" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "lentről fel, balról jobbra" - -# Fixme: szintén az írási mód egyik lehetséges értéke. -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "balról jobbra" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "jobbról balra" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "fentről lefelé" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "vastag" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "betűtévesztés" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Az állapot megváltoztatásához nyomja meg a szóköz billentyűt." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"A legördítéshez használja a szóköz, az elemeken való navigáláshoz a fel- és " -"le nyíl billentyűket." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Az ablakok közötti váltáshoz használja az Alt+F6 billentyűkombinációt." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Az elemeken való navigáláshoz használja a nyíl billentyűket, vagy írjon be " -"néhány karaktert a kereséshez." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "A rendszermenük eléréséhez nyomja meg az Alt+F1 billentyűkombinációt." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Egy elem kijelöléséhez használja a fel- és le nyíl billentyűket." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" -"A fanézet összecsukásához használja a Shift+bal nyíl billentyűkombinációt." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" -"A fanézet kiterjesztéséhez használja a Shift+jobbra nyíl " -"billentyűkombinációt." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Aktiválásához nyomja meg az enter billentyűt." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Gépelje be a kért információt, vagy módosítsa a meglévőt." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" -"A lapfülek közötti váltáshoz használja a balra- és jobbra nyíl billentyűket." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Aktiválásához nyomja meg a szóköz billentyűt." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Az érték megadásához használja a felfelé és lefelé nyílbillentyűket, vagy " -"gépelje be az értéket." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "A kijelölés módosításához használja a nyíl billentyűket." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"A főmenük között a balra- és jobbra nyíl billentyűk segítségével léptethet. " -"A menüelemeken való navigációhoz használja a fel- és le nyíl billentyűket." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Az almenü megnyitásához használja a jobbra nyíl billentyűt." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Az érték csökkentéséhez használja a balra nyíl, növeléséhez a jobbra nyíl " -"billentyűt. A legkisebb értékre ugráshoz használja a Home, a legnagyobb " -"értékre ugráshoz pedig az End billentyűt." diff --git a/po/id.po b/po/id.po deleted file mode 100644 index c9ace35..0000000 --- a/po/id.po +++ /dev/null @@ -1,9165 +0,0 @@ -# Indonesian translation for cthulhu. -# Copyright (C) 2011 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Andika Triwidada , 2011-2017, 2023. -# Kukuh Syafaat , 2018-2023. -# Sucipto , 2020. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu gnome-45\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-09-07 13:54+0700\n" -"Last-Translator: Andika Triwidada \n" -"Language-Team: Indonesian \n" -"Language: id\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Pembaca Layar Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "layar;pembaca;aksesibilitas;ucapan;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Ceko Tingkat 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spanyol Tingkat 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Perancis Kanada Tingkat 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Perancis Perancis Tingkat 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvia Tingkat 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Belanda Nederlan Tingkat 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norwegia Tingkat 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norwegia Tingkat 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norwegia Tingkat 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norwegia Tingkat 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polandia Tingkat 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugis Tingkat 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Swedia Tingkat 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arab Tingkat 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Welsh Tingkat 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Welsh Tingkat 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Jerman Tingkat 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Jerman Tingkat 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Jerman Tingkat 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Inggris Britania Tingkat 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Inggris Britania Tingkat 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Inggris Amerika Tingkat 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Inggris Amerika Tingkat 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Perancis Kanada Tingkat 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Perancis Perancis Tingkat 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Yunani Tingkat 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi Tingkat 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Komputer dot 8 Hungaria" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hungaria Tingkat 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Hungaria Tingkat 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italia Tingkat 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belanda Belgia Tingkat 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "spasi" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "ganti baris" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "tanda seru" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "tanda kutip" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nomor" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "persen" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "dan" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "tanda petik tunggal" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "kurung buka" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "kurung tutup" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "bintang" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "tambah" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "koma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "tanda hubung" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "titik" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "garis miring" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "titik dua" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "titik koma" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "kurang dari" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "sama dengan" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "lebih dari" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "tanda tanya" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "pada" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "kurung siku kiri" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "backslash" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "kurung siku kanan" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "karet" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "garis bawah" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "back tick" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "kurawal kiri" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "garis tegak" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "kurawal kanan" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "spasi tak putus" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "tanda seru terbalik" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "sen" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "poundsterling" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "tanda mata uang" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "pipa" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "bagian" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "hak cipta" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a superskrip" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "tanda kurang dari berganda" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "tanda not lojik" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "tanda pisah" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "merk terdaftar" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "derajat" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus atau minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "2 superskrip" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "3 superskrip" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acute" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "penanda paragraf" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "titik di tengah" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 superskrip" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "tanda lebih dari berganda" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "seperempat" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "setengah" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tiga perempat" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "tanda tanya terjungkir" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "kali" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "dibagi" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "strip" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "tanda petik tunggal buka" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "tanda petik tunggal tutup" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "tanda petik ganda bawah" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "tanda petik ganda buka" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "tanda petik ganda bawah" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "tanda petik ganda bawah" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "simbol belati" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "simbol belati ganda" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "bulet" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "bulet segi tiga" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prime" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "prime ganda" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "prime triple" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "bulet penyambung" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "merk dagang" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "tanda contreng" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "contreng tebal" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "bulet bentuk x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "0 superskrip" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "4 superskrip" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "5 superskrip" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "6 superskrip" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "7 superskrip" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "8 superskrip" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "9 superskrip" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "plus superskrip" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "minus superskrip" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "sama dengan superskrip" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "kurung kiri superskrip" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "kurung kanan superskrip" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n superskrip" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "0 subskrip" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "1 subskrip" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "2 subskrip" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "3 subskrip" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "4 subskrip" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "5 subskrip" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "6 subskrip" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "7 subskrip" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "8 subskrip" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "9 subskrip" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "plus subskrip" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "minus subskrip" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "sama dengan subskrip" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "kurung kiri subskrip" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "kurung kanan subskrip" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "bujur sangkar hitam" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "berlian hitam" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "karakter penggantian objek" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Arahkan penunjuk ke butir kini" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Lakukan klik kiri pada butir tinjau rata kini" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Lakukan klik kanan pada butir tinjau rata kini" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Ucapkan seluruh isi dokumen" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Ucapkan seluruh jendela menggunakan tinjau rata kini" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Laksanakan operasi dasar saya ada dimana" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Laksanakan operasi terrinci saya ada dimana" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Ucapkan pilihan saat ini" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Ucapkan detail tautan" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Sajikan tombol baku" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Sajikan bilah status" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Sajikan bilah judul" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Buka dialog Cari" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Tampilkan daftar tindakan" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Temukan kemunculan string pencarian selanjutnya" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Temukan kemunculan string pencarian sebelumnya" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Masuk dan keluar mode tinjau rata" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Jungkitkan tinjau rata ke objek saat ini" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Pindahkan tinjau rata ke posisi rumah" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Pindahkan tinjau rata ke posisi akhir" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Pindahkan tinjau rata ke awal baris sebelumnya" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Ucapkan baris tinjau rata kini" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Eja baris tinjau rata kini" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Eja secara fonetik baris tinjau rata kini" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Pindahkan tinjau rata ke awal baris berikutnya" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Pindahkan tinjau rata ke butir atau kata sebelumnya" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Ucapkan tinjau rata butir atau kata kini" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Eja tinjau rata butir atau kata kini" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Eja secara fonetik tinjau rata butir atau kata kini" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Pindahkan tinjau rate ke butir atau kata selanjutnya" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Pindahkan tinjau rata ke kata di atas kata ini" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Ucapkan objek tinjau rata kini" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Pindahkan tinjau rata ke kata di bawah kata ini" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Pindahkan tinjau rata ke karakter sebelumnya" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Ucapkan karakter tinjau rata kini" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Ucapkan secara fonetik karakter tinjau rata kini" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Ucapkan nilai unicode karakter tinjau rata kini" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Pindahkan tinjau rata ke karakter berikutnya" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Pindahkan tinjau rata ke ujung baris" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Pindahkan tinjau rata ke kiri bawah" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Salin isi di bawah tinjau rata ke papan klip" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Tambahkan isi di bawah tinjau rata ke papan klip" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Tampilkan konten tinjau rata" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Menjungkit apakah membaca hanya sel tabel kini atau seluruh baris" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Membaca atribut yang terkait dengan karakter teks kini" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Geser tampilan braille ini ke kiri" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Geser tampilan braille ini ke kanan" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Kembali ke objek yang memiliki fokus papan tik" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Nyalakan dan matikan braille terkontraksi" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Memroses tombol pengaturan route kursor" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Tandai awal pilihan teks" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Tandai akhir pilihan teks" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Masuk ke mode belajar. Tekan escape untuk keluar dari mode belajar" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Turunkan laju ucapan" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Naikkan laju ucapan" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Turunkan pitch ucapan" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Naikkan pitch ucapan" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Memperkeras suara" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Memelankan suara" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Pilih pengaturan ucapan sebelumnya" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Pilih pengaturan ucapan berikutnya" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Kurangi pengaturan ucapan saat ini" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Tingkatkan pengaturan ucapan saat ini" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Simpan pengaturan ucapan" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Jungkitkan pembisuan ucapan" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Jungkitkan aras kerincian ucapan" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Alihkan mode tidur" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Keluar dari pembaca layar" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Tampilkan dialog konfigurasi preferensi" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Tampilkan dialog konfigurasi preferensi aplikasi" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Jungkitkan pengucapan indentasi dan perataan" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Mengubah gaya nomor yang diucapkan" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Memutar ke tingkat pengucapan tanda baca selanjutnya" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Memutar ke tingkat pensintesa ucapan selanjutnya" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Memutar ke profil pengaturan selanjutnya" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Memutar ke gaya kapitalisasi selanjutnya" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Memutar ke tingkat gaung tombol selanjutnya" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Memutar tingkat awakutu saat runtime" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Tandai taut dimana saya saat ini relatif terhadap posisi kini" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Ke lokasi penanda taut sebelumnya" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Ke penanda taut" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Ke lokasi penanda taut selanjutnya" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Tambah penanda taut" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Simpan penanda taut" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Jungkitkan mode tinjau tetikus" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Sajikan waktu saat ini" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Sajikan tanggal saat ini" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Ukuran sekarang dan lokasi objek saat ini" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Mengangsurkan perintah selanjutnya ke aplikasi kini" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Ucapkan dan braille pesan ruang obrolan sebelumnya" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Menjungkitkan apakah mengumumkan ketika lawan kita sedang mengetik" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Menjungkitkan apakah menyediakan riwayat pesan spesifik ruang obrolan" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Menjungkitkan apakah pesan ruang obrolan diberi awalan nama ruang obrolan" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Baris Kiri" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Baris Kanan" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Baris Naik" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Baris Turun" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Bekukan" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Kiri Atas" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Kiri Bawah" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posisi Kursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Enam Titik" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Routing Kursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Mulai Potong" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Potong Baris" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Sajikan pesan pemberitahuan terakhir" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Sajikan daftar pesan pemberitahuan" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Sajikan pesan pemberitahuan sebelumnya" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Sajikan pesan pemberitahuan selanjutnya" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Ke karakter selanjutnya" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Ke karakter sebelumnya" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Ke kata selanjutnya" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Ke kata sebelumnya" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Ke baris berikutnya" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Ke baris sebelumnya" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Ke puncak berkas" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Ke dasar berkas" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Ke awal baris" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Ke akhir baris" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Ke objek selanjutnya" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Ke objek sebelumnya" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Menyebabkan kotak kombo saat ini dikembangkan" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Bertukar antara navigasi karet native dan pembaca layar" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Tingkatkan pengaturan kesopanan wilayah aktif" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Tata kesopanan wilayah aktif baku ke mati" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Tinjau pengumuman wilayah aktif" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Pantau wilayah aktif" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Pindahkan fokus ke dalam dan menjauh dari tetikus lewat kini" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Menata baris yang dipakai sebagai tajuk kolom dinamis" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Bersihkan tajuk kolom dinamis" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Menata kolom yang dipakai sebagai tajuk baris dinamis" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Bersihkan tajuk baris dinamis" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Menyajikan isi baris masukan" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Jungkitkan tombol navigasi struktural" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Ke kutipan blok sebelumnya" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Ke kutipan blok selanjutnya" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Tampilkan daftar kutipan blok" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Ke tombol sebelumnya" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Ke tombol selanjutnya" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Tampilkan daftar tombol" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Ke kotak contreng sebelumnya" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Ke kotak contreng selanjutnya" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Tampilkan daftar kotak contreng" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Ke elemen yang dapat diklik sebelumnya" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Ke elemen yang dapat diklik selanjutnya" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Tampilkan daftar yang dapat diklik" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Ke kotak kombo sebelumnya" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Ke kotak kombo selanjutnya" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Pergi ke awal wadah" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Pergi ke akhir wadah" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Tampilkan daftar kotak kombo" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Ke entri sebelumnya" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Ke entri selanjutnya" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Tampilkan daftar entri" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Ke ruas formulir sebelumnya" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Ke ruas formulir selanjutnya" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Tampilkan daftar ruas formulir" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Ke heading sebelumnya" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Ke heading selanjutnya" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Tampilkan daftar heading" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Ke heading sebelumnya pada tingkat %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Ke heading selanjutnya pada tingkat %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Tampilkand daftar heading pada tingkat %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Ke bingkai internal sebelumnya" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Ke bingkai internal selanjutnya" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Tampilkan daftar bingkai internal" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Ke citra sebelumnya" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Ke citra berikutnya" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Tampilkan daftar citra" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Ke landmark sebelumnya" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Ke landmark selanjutnya" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Tampilkan daftar landmark" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Ke objek besar sebelumnya" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Ke objek besar selanjutnya" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Tampilkan daftar objek besar" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Ke taut sebelumnya" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Ke taut berikutnya" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Tampilkan daftar taut" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Ke daftar sebelumnya" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Ke daftar selanjutnya" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Tampilkan daftar dari daftar" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Ke butir daftar sebelumnya" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Ke butir daftar selanjutnya" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Tampilkan daftar dari butir daftar" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Ke wilayah aktif sebelumnya" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Ke wilayah aktif selanjutnya" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Ke wilayah aktif terakhir yang membuat pengumuman" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Pergi ke induk objek dengan fokus navigator." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Pergi ke anak pertama objek dengan fokus navigator." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Pergi ke yang sejajar berikutnya dari objek dengan fokus navigator." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Pergi ke yang sejajar sebelumnya dari objek dengan fokus navigator." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Klik pada objek yang memiliki fokus navigator." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Jungkitkan navigasi objek yang disederhanakan." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Ke paragraf sebelumnya" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Ke paragraf selanjutnya" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Tampilkan daftar paragraf" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Ke tombol radio sebelumnya" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Ke tombol radio selanjutnya" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Tampilkan daftar tombol radio" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Ke pemisah sebelumnya" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Ke pemisah selanjutnya" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Ke tabel sebelumnya" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Ke tabel selanjutnya" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Tampilkan daftar tabel" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Ke bawah satu sel" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Ke sel pertama dalam tabel" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Ke sel terakhir dalam tabel" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Ke kiri satu sel" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Ke kanan satu sel" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Ke atas satu sel" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Jungkitkan mode tata letak" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Bertukar antara mode ramban dan mode fokus" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Fungsikan mode fokus lengket" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Fungsikan mode ramban lengket" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Ke taut sebelumnya yang belum dikunjungi" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Ke taut senlajutnya yang belum dikunjungi" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Tampilkan daftar taut yang belum dikunjungi" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Ke taut sebelumnya yang telah dikunjungi" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Ke taut selanjutnya yang telah dikunjungi" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Tampilkan daftar taut yang telah dikunjungi" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "biru alice" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "putih antik" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "aquamarine" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azure" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "hitam" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "putih almond" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "biru" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "biru" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "coklat" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "biru kadet" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "coklat" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "biru bunga jagung" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "ungu" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cyan" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "biru gelap" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "cyan gelap" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "goldenrod gelap" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "kelabu gelap" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "hijau gelap" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "khaki gelap" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta gelap" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "hijau zaitun gelap" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "oranye gelap" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "anggrek gelap" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "merah gelap" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmon gelap" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "hijau laut gelap" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "biru batu gelap" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "abu-abu batu gelap" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turquoise gelap" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "ungu gelap" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "merah jambu dalam" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "biru langit dalam" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "kelabu redup" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "biru dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "bata api" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "putih bunga" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "hijau hutan" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "putih hantu" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "emas" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "goldenrod" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "kelabu" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "hijau" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "kuning hijau" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "honeydew" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "merah jambu panas" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "merah indian" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "ivory" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavender" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavender kemerahan" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "hijau rumput halaman" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "lemon chiffon" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "biru terang" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "koral terang" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "cyan terang" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "kuning terang goldenrod" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "kelabu terang" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "hijau terang" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "pink terang" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmon terang" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "hijau laut terang" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "biru langit terang" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "kelabu batu terang" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "biru baja terang" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "kuning terang" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limau" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "hijau limau" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linen" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "marun" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "aquamarine sedang" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "biru sedang" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "anggrek sedang" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "ungu sedang" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "hijau laut sedang" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "biru batu sedang" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "hijau semi sedang" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turquoise sedang" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "merah ungu sedang" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "biru tengah malam" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "krim mint" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "mawar berkabut" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "putih navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "navy" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "renda lama" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "zaitun" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "zaitun lumpur" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oranye" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "oranye merah" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "anggrek" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "goldenrod pucat" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "hijau pucat" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turquoise pucat" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "merah ungu pucat" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "cambuk pepaya" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "isapan persik" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "pink" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "prem" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "biru bubuk" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "ungu" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "merah" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "coklat cerah" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "biru royal" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "coklat pelana" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmon" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "coklat pasir" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "hijau laut" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "kerang" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "perak" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "biru langit" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "biru batu" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "abu-abu batu" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "salju" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "hijau semi" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "biru baja" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "sawo matang" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "teal" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "ungu thistle" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomat" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquoise" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "ungu" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "gandum" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "putih" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "asap putih" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "kuning" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "hijau kuning" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktifkan" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Mode fokus otomatis selama navigasi struktural" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Mode fokus otomatis selama navigasi karet" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Mode fokus otomatis selama navigasi asli" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Dot _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Dot _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Dot 7 _dan 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Batal" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Lompat ke" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikon" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Nihil" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Pengejaan" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Umumkan ketika _lawan Anda sedang mengetik" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Sediakan riwayat pesan _spesifik ruang obrolan" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Ucapkan pesan dari" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Semua ka_nal" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Semua kanal ketika sebaran_g jendela %s aktif" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Suatu kanal hanya bila _jendelanya aktif" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Ucapkan nama Ruang Obrolan" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Fungsikan mode tata letak bagi isi" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "klik ganda" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "klik tiga kali" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Synthesizer Baku" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "String Sebenarnya" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "String Pengganti" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Aktifkan gema per hu_ruf" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Fungsikan tombol _diakritis bukan spasi" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Lokasi k_ini" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Panjang minimum dari teks yang cocok:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opsi Pencarian" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Han_ya ucapkan baris yang diubah selama pencarian" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Ucapkan hasil selaman pen_carian" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Perintah" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Pengikatan Tombol" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Baku" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Mode belajar" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Aksi" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Pengikatan Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Markah" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Tanggal dan waktu" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Tinjauan tetikus" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Navigasi objek" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Rincian objek" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Bebas" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Tinjau rata" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Ucapan dan tingkat rincian" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Konten tinjau rata" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Diubah" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Desktop" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Pemberitahuan" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Diterima" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Penyaji pemberitahuan" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferensi Cthulhu untuk %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Tandai dalam Braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Ada Kecuali" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Bicara" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Simpan Profil Sebagai Konflik" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Konflik Profil Pengguna!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profil %s sebelumnya telah ada.\n" -"Terus memutakhirkan profile yang ada dengan perubahan-perubahan baru ini?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Muat profil pengguna" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Anda akan mengubah profil aktif. Bila Anda\n" -"baru membuat perubahan dalam preferensi Anda,\n" -"mereka akan dibuang saat profil dimuat.\n" -"\n" -"Lanjutkan memuat profil membuang perubahan sebelumnya?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Simpan Profil Sebagai" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nama _Profil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Hapus profil pengguna" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Anda akan menghapus profil %s. Semua pengaturan yang belum disimpan dan " -"pengaturan yang disimpan di profil ini akan hilang. Apakah Anda ingin " -"melanjutkan dan menghapus profil ini dan semua pengaturan terkait?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Semua" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplikasi" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Jendela" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Nihil" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Sebagia_n" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Kebanyak_an" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Garis" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Kalimat" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Kutip blok" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Tombol" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Kapsi" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Kotak Contreng" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Dapat Diklik" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kotak Kombo" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Deskripsi" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Heading" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Bingkai Internal" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Gambar" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Label" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Landmark" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Tingkat" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Taut" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Daftar" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Butir Daftar" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objek" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragraf" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Tombol Radio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Peran" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Butir Yang Dipilih" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Keadaan" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Teks" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Nilai" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blok Kutipan" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Tombol" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Kotak Contreng" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Dapat Diklik" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kotak Kombo" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entri" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Ruas Formulir" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Judul" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Bingkai Internal" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Citra" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Judul pada Tingkat %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Landmark" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Objek Besar" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Taut" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Daftar" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Butir Daftar" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragraf" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Tombol Radio" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabel" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Taut Yang Belum Dikunjungi" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Taut Yang Telah Dikunjungi" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navigasi Halaman" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Otomatis mulai bacakan suatu ha_laman ketika pertama dimuat" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Tam_pilkan ringkasan suatu halaman ketika awal termuat" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Pecah _ucapan-ucapan ke dalam potongan antara jeda" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "suara baku %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Baku" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Huruf besar" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Periksa Ejaan" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Salah _eja" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "_Saran ejaan" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Sajikan _konteks kesalahan" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Ucapkan koordinat sel lembar kerja" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Selalu ucapkan rentang lembar kerja yang dipilih" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Umumkan _tajuk sel" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigasi Tabel" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "A_baikan sel kosong" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "U_capkan sel" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "U_capkan koordinat sel" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "_Ucapkan bentangan sel berganda" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nama Atribut" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Kendalikan navigasi karet" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Fungsikan navigasi _struktural" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Tema suara:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Tema suara" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Singka_t" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d pemberitahuan" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Kontrol" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "shift kiri" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt kiri" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control kiri" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "shift kanan" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt kanan" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control kanan" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta kiri" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta kanan" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab kiri" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "naik" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "turun" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "kiri" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "kanan" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super kiri" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super kanan" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "bantuan" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "penukar mode" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "stroke" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_Kn" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_Kr" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s tebal" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s miring" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s tebal miring" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s skrip" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s tebal skrip" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s fraktur" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s struck-ganda" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s fraktur tebal" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s sans serif" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s sans serif tebal" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s sans serif miring" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s sans serif tebal miring" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "monospace %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s tidak bertitik" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "panah ke kiri" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "panah naik" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "panah ke kanan" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "panah turun" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "panah kiri kanan" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "panah naik turun" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "panah barat laut" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "panah timur laut" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "panah tenggara" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "panah ke kiri dari batang" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "panah naik dari batang" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "panah ke kanan dari batang" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "panah turun dari batang" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "panah ganda ke kiri" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "panah ganda naik" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "panah ganda ke kanan" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "panah ganda turun" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "panah ganda kiri kanan" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "panah ganda naik turun" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "panah ganda barat laut" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "panah ganda timur laut" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "panah ganda tenggara" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "panah ganda barat daya" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "panah ke kanan" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "kepala panah arah kanan" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "kurang dari" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "lebih dari" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "titik" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "garis tegak ganda" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "elipsis horisontal" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "untuk semua" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "komplemen" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "diferensial parsial" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "ada" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "tidak ada" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "set kosong" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "kenaikan" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "elemen dari" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "bukan elemen dari" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "elemen kecil dari" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "berisi sebagai anggota" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "tidak berisi anggota" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "kecil berisi sebagai anggota" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "akhir bukti" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produk" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koproduk" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "jumlah" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus atau plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "titik plus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "garis miring pembagian" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "setel minus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operator asterisk" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operator cincin" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operator bulet" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "akar kuadrat" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "akar pangkat tiga" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "akar pangkat empat" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "sebanding dengan" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "tak hingga" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "sudut kanan" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "sudut" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "sudut terukur" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sudut bulat" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "memisah" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "tidak memisah" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "sejajar dengan" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "tidak sejajar dengan" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "tanda and lojik" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "tanda or lojik" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "perpotongan" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "union" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integral ganda" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integral rangkap tiga" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integral kontur" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integral permukaan" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integral volume" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral searah jarum jam" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integral kontur searah jarum jam" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integral kontur berlawanan arah jarum jam" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "maka" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "karena" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "rasio" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporsi" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "titik minus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "kelebihan" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporsi geometris" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetik" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "tilde terbalik" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "S malas terbalik" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "gelombang sinus" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "produk rangkaian" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "bukan tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minus tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "secara asimtot sama dengan" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "tidak secara asimtot sama dengan" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "kira-kira sama dengan" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "kira-kira tetapi tidak sebenarnya sama dengan" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "tidak kira-kira atau sebenarnya dengan" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "hampir sama dengan" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "tidak hampir sama dengan" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "hampir sama dengan atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "tilde rangkap tiga" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "semua sama dengan" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "secara geometris ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "perbedaan antara" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "mendekati batas" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "secara geometris sama dengan" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "kira-kira sama dengan atau gambar dari" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "gambar dari atau kira-kira sama dengan" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "titik dua sama dengan" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "sama dengan titik dua" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "cincin dalam sama dengan" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "cincin sama dengan" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "sesuai dengan" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estimasi" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "sudut sama dengan" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "bintang sama dengan" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta sama dengan" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "sama dengan menurut definisi" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "diukur dengan" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "tanda tanya sama dengan" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "tak sama dengan" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identik dengan" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "tidak identik dengan" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "ekuivalen ketat dengan" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "kurang dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "lebih dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "kurang dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "lebih dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "kurang dari tapi tidak sama dengan" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "lebih dari tapi tidak sama dengan" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "jauh kurang dari" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "jauh lebih dari" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "antara" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "tidak ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "tidak kurang dari" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "tidak lebih dari" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "tidak kurang dari maupun sama dengan" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "tidak lebih dari maupun sama dengan" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "kurang dari atau ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "lebih dari atau ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "tidak kurang dari maupun ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "tidak lebih dari maupun ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "kurang dari atau lebih dari" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "lebih dari atau kurang dari" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "tidak kurang maupun lebih dari" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "tidak lebih dari maupun kurang dari" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "mendahului" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "mengikuti" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "mendahului atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "mengikuti atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "mendahului atau ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "mengikuti atau ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "tidak mendahului" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "tidak mengikuti" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subset dari" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superset dari" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "bukan subset dari" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "bukan superset dari" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subset dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superset dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "bukan subset maupun sama dengan" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "bukan superset maupun sama dengan" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subset dari dengan tidak sama dengan" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superset dari dengan tidak sama dengan" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiset" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "perbanyakan multiset" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "union multiset" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "gambar bujur sangkar dari" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "asli bujur sangkar dari" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "gambar bujur sangkar dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "asli bujur sangkar dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "tutup bujur sangkar" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "cangkir bujur sangkar" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "tambah dilingkari" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "minus dilingkari" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "kali dilingkari" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "garis miring dilingkari" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "operator titik dilingkari" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operator cincin dilingkari" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operator bintang dilingkari" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "sama dengan dilingkari" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "tanda hubung dilingkari" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "tambah dalam bujur sangkar" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "minus dalam bujur sangkar" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "kali dalam bujur sangkar" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operator titik dalam bujur sangkar" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "paku kanan" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "paku kiri" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "paku bawah" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "paku atas" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "asersi" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "model" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "benar" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "memaksa" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "garis vertikal triple dengan lengan kanan" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "garis vertikal ganda dengan dua lengan kanan" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "tidak membuktikan" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "tidak benar" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "tidak memaksa" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "negasi garis vertikal ganda dengan lengan kanan ganda" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "mendahului di bawah relasi" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "melanjutkan di bawah relasi" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "subgrup normal dari" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "berisi sebagai normal subgrup" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "subgrup normal dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "berisi sebagai subgrup normal dari atausama dengan" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "asli dari" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "gambar dari" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimap" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matriks konjugasi hermit" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalate" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "sudut kanan dengan busur" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "segitiga kanan" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operator permata" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operator titik" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operator bintang" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "kali pembagian" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "dasi kupu-kupu" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "faktor normal kiri semilangsung produk" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "faktor normal kanan semilangsung produk" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "produk semilangsung kiri" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "produk semilangsung kanan" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "tilde terbalik sama dengan" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "ikal logis atau" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "ikal logis dan" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "subset ganda" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "superset ganda" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "perpotongan ganda" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "union ganda" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "trisula" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "sama dan sejajar dengan" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "kurang dari dengan titik" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "lebih dari dengan titik" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "sangat kurang dari" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "sangat lebih dari" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "kurang dari sama dengan atau lebih dari" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "lebih dari sama dengan atau kurang dari" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "kurang dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "sama atau lebih dari" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "sama dengan atau mendahului" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "sama dengan atau mengikuti" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "tidak mendahului atau sama" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "tidak mengikuti atau sama" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "tidak gambar kotak dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "tidak asli kotak dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "citra bujur sangkar dari atau tidak sama dengan" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "bujur sangkar asli dari atau tidak sama dengan" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "kurang dari tapi tidak ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "lebih dari tapi tidak ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "mendahului tapi tidak ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "mengikuti tapi tidak ekuivalen dengan" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "bukan subgrup normal dari" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "tidak memuat sebagai subgrup normal" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "bukan subgrup normal dari atau sama dengan" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "tidak berisi sebagai subgrup normal atau sama dengan" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "elipsis vertikal" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "elipsis horisontal tengah garis" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "elipsis diagonal kanan naik" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "elipsis diagonal kanan turun" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "elemen dari dengan coret horizontal" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "elemen dari dengan garis vertikal pada akhir coret horizontal" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "elemen kecil dari dengan garis vertikal pada akhir coret horizontal" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "elemen dari dengan titik di atas" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "elemen dari dengan garis atas" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "kecil elemen dari dengan garis atas" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "elemen dari dengan garis bawah" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "elemen dari dengan dua coretan" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "berisi dengan coret horizontal panjang" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "berisi dengan garis vertikal pada akhir coret horizontal" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "kecil berisi dengan garis vertikal pada akhir coret horizontal" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "berisi dengan garis atas" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "kecil berisi dengan garis atas" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "keanggotaan tas notasi z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "langit-langit kiri" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "langit-langit kanan" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "lantai kiri" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "lantai kanan" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "kurawal atas" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "kurawal bawah" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "kurung sudut kiri" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "kurung sudut kanan" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "titik dilingkari" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "union dengan titik" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "union dengan plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "perpotongan bujur sangkar" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "union bujur sangkar" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "bujur sangkar hitam" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "bujur sangkar putih" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "berlian hitam" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "lingkaran putih" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "lingkaran hitam" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bulet putih" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "bujur sangkar hitam berukuran sedang" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s dengan garis bawah" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s dengan garis miring" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s dengan garis vertikal" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplikasi" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "kosong" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "tebal" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "penanda taut dimasukkan" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "penanda taut disimpan" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "penanda taut tak dapat disimpan" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Tak ditemukan markah." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Markah tidak ditemukan." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Mode bypass difungsikan." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Tak bisa mendapat tampilan kalkulator" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Gaya kapitalisasi diatur ke ikon." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "nihil" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Gaya kapitalisasi diatur ke tiada." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "pengejaan" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Gaya kapitalisasi diatur ke pengejaan." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Aplikasi sedang mengendalikan karet." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu mengendalikan tanda sisipan." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Sel %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s dipilih" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s sampai %s dipilih" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s sampai %s tak dipilih" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s tak dipilih" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Cegah penggunaan opsi" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Paksakan penggunaan opsi" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPSI" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Argumen opsional" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Cara Pakai: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Yang berikut tak valid: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Cetak daftar aplikasi berjalan yang dikenal" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Muat profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profil tak bisa dimuat: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "Tidak dapat memulai Cthulhu karena tidak dapat terhubung ke Desktop." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Tak bisa mengaktifkan manajer pengaturan. Keluar." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Proses pembaca layar lain tengah berjalan untuk sesi ini.\n" -"Jalankan \"cthulhu --replace\" untuk menggantikan proses tersebut dengan " -"yang baru." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAMA" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Gunakan direktori alternatif untuk preferensi pengguna" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versi aplikasi ini" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Ganti instans Cthulhu yang sedang berjalan" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Tampilkan pesan bantuan ini dan keluar" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Kirim keluaran debug ke debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Kirim keluaran debug ke berkas yang dinyatakan" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "BERKAS" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Atur preferensi pengguna (versi teks)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Atur preferensi pengguna (versi GUI)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Laporkan kutu ke https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Potong pilihan ke papan klip." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "potong" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Salin pilihan ke papan klip." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "tersalin" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Tertempel konten dari papan klip." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "tertempel" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Jangan umumkan ketika lawan Anda sedang mengetik." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "umumkan ketika lawan Anda sedang mengetik." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Pesan dari ruang obrolan %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Tab obrolan baru %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Jangan ucapkan nama ruang obrolan." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "ucapkan nama ruang obrolan." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Jangan sediakan riwayat pesan spesifik ruang obrolan." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Sediakan riwayat pesan spesifik ruang obrolan." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "awal penghapusan" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "akhir penghapusan" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "awal penyisipan" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "akhir penyisipan" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "awal penyorotan" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "akhir penyorotan" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "akhir saran" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Akhir wadah." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Bukan dalam wadah." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "semua butir dipilih" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Tombol baku adalah %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Tombol baku adalah %s. Kelabu" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Tombol baku tidak ditemukan" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subskrip %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " superskrip %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Bukan dalam dialog" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "seluruh dokumen dipilih" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "seluruh dokumen tak dipilih" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokumen dipilih dari posisi kursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "dokumen tak dipilih dari posisi kursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokumen dipilih sampai posisi kursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "dokumen tak dipilih sampai posisi kursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Tajuk kolom dinamis ditata bagi baris %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Tajuk kolom dinamis dibersihkan." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Tajuk baris dinamis ditata bagi kolom %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Tajuk baris dinamis dibersihkan." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "kosong" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobyte" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabyte" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Tak ada berkas yang ditemukan." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Tambahkan isi ke papan klip." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Salin isi ke papan klip." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Tak memakai tinjau rata." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Memasuki tinjau rata." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Meninggalkan tinjau rata." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Tinjau rata dibatasi ke objek saat ini" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Tinjau rata tak terbatas" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "punya rumus" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "membuka dialog" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "membuka kisi" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "membuka daftar kotak" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "membuka menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "membuka pohon" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "taut peta gambar" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Tombol yang dimasukkan sebelumnya sudah terikat ke %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tombol yang ditangkap: %s. Tekan enter untuk konfirmasi." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Tombol baru adalah: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Pengikatan tombol dihapus. Tekan enter untuk konfirmasi." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Pengikatan tombol telah dihapus." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "ketikkan tombol baru" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tombol" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Gaung tombol ditata ke tombol." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Tak ada" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Gaung tombol ditata ke Nihil." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tombol dan kata" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Gaung tombol ditata ke tombol dan kata." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "kalimat" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Gaung tombol ditata ke kalimat." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "kata" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Gaung tombol ditata ke kata." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "kata dan kalimat" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Gaung tombol ditata ke kata dan kalimat." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Diapit oleh: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "suatu simbol aktuaria" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "suatu kotak" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "suatu lingkaran" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "suatu tanda pembagian panjang" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "suatu radikal" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "kotak berpojok lengkung" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "sebuah coret horisontal" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "sebuah coret vertikal" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "sebuah coret diagonal turun" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "sebuah coret diagonal naik" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "suatu panah timur Laut" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "suatu garis di dasar" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "suatu garis di kiri" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "suatu garis di kanan" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "suatu garis di puncak" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "suatu sudut fasor" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "suatu simbol faktorial arab" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "dan" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "awal fraksi" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "fraksi tanpa garis, mulai" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "dibagi" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "akhir fraksi" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "akar kuadrat dari" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "akar pangkat tiga dari" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "akar dari" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "mulai akar" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "akhir akar" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subskrip" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "superskrip" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pra-subskrip" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pra-superskrip" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "underscript" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "overscript" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "akhir tabel" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "akhir tabel bersarang" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "tak bisa diakses" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Dinonaktifkan" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Pengucapan indentasi dan perataan dimatikan." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Difungsikan" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Pengucapan indentasi dan perataan difungsikan." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Mode belajar. Tekan escape untuk keluar." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Masuk mode belajar. Tekan sebarang tombol untuk mendengar fungsinya. Untuk " -"menilik dokumentasi pembaca layar, tekan F1. Untuk memperoleh daftar dari " -"pintasan baku pembaca layar, tekan F2. Untuk memperoleh daftar pintasan " -"pembaca layar bagi aplikasi kini, tekan F3. Untuk keluar mode belajar, tekan " -"tombol escape." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "meninggalkan kutip blok." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "meninggalkan detail." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "meninggalkan asupan." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "meninggalkan gambar." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "meninggalkan formulir." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "meninggalkan banner." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "meninggalkan konten pelengkap." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "meninggalkan informasi." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "meninggalkan konten utama." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "meninggalkan navigasi." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "meninggalkan wilayah." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "meninggalkan pencarian." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "meninggalkan daftar." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "meninggalkan panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "meninggalkan tabel." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "meninggalkan tooltip." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "meninggalkan abstrak." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "meninggalkan pengakuan." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "meninggalkan kata penutup." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "meninggalkan lampiran." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "meninggalkan bibliografi." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "meninggalkan bab." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "meninggalkan tanda penerbit." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "meninggalkan kesimpulan." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "meninggalkan penghargaan." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "meninggalkan penghargaan." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "meninggalkan dedikasi." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "meninggalkan catatan akhir." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "meninggalkan prasasti." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "meninggalkan epilog." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "meninggalkan ralat." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "meninggalkan contoh." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "meninggalkan kata pengantar." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "meninggalkan glosari." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "meninggalkan indeks." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "meninggalkan perkenalan." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "meninggalkan daftar halaman." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "meninggalkan bagian." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "meninggalkan pendahuluan." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "meninggalkan prolog." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "meninggalkan kutipan tarik." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "meninggalkan tanya-jawab." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "meninggalkan saran." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "meninggalkan daftar isi." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "baris dipilih ke bawah dari posisi kursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "baris dipilih ke atas dari posisi kursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "baris tak dipilih ke bawah dari posisi kursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "baris tak dipilih ke atas dari posisi kursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Keluar dari mode belajar." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "baris dipilih dari awal dari posisi kursor sebelumnya" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "baris dipilih sampai akhir dari posisi kursor sebelumnya" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "taut" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "laman yang sama" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "situs yang sama" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "situs lain" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s menaut ke %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "taut %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "%s tautan telah dikunjungi" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Pakai Panah Naik dan Turun untuk menavigasi daftar. Tekan Escape untuk " -"keluar." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Semua wilayah aktif dimatikan" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "tingkat kesopanan wilayah aktif dikembalikan" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "aras kesopanan %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "menata wilayah aktif menjadi asertif" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "menata wilayah aktif menjadi mati" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "menata wilayah aktif menjadi sopan" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "menata wilayah aktif menjadi kasar" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Pemantauan wilayah aktif mati" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Pemantauan wilayah aktif menyala" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "tidak ada pesan aktif yang disimpan" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Dukungan wilayah aktif mati" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Tak ditemukan" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Tidak dapat menemukan lokasi kini." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "mati" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "nyala" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "salah eja" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Kata salah eja: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Konteksnya %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Mode ramban" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Mode fokus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Untuk memfungsikan mode fokus tekan %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Mode fokus lengket." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Mode ramban lengket." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Mode tata letak." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Mode objek." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Penunjuk dipindah ke objek." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Objek tetikus lewat tak ditemukan." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Tinjauan tetikus tidak difungsikan." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Tinjauan tetikus difungsikan." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Galat: Tak bisa membuat daftar objek." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Tidak ada anak." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Tidak ada selanjutnya." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Tidak ada induk." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Tidak ada sebelumnya." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Navigasi yang disederhanakan difungsikan." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Navigasi yang disederhanakan dinonaktifkan." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Bersarang tingkat %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Butir baru telah ditambahkan" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Tak ada aksi yang ditemukan pada: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Tak ada fokus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Tak ada aplikasi yang memiliki fokus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Tak ada blok kutipan lagi." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Tak ada tombol lagi." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Tak ada kotak contreng lagi." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Tak ada objek besar lagi." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Tak ada yang dapat diklik lagi." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Tak ada kotak kombo lagi." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Tak ada entri lagi." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Tak ada ruas formulir lagi." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Tak ada heading lagi." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Tak ada heading lagi pada tingkat %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Tak ada bingkai internal lagi." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Tak ada citra lagi." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Tak ditemukan landmark." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Tak ada taut lagi." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Tak ada daftar lagi." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Tak ada butir daftar lagi." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Tak ada wilayah aktif lagi." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Tak ada paragraf lagi." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Tak ada tombol radio lagi." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Tak ada pemisah lagi." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Tak ada tabel lagi." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Tak ada taut yang belum dikunjungi lagi." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Tak ada taut yang telah dikunjungi lagi." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Tak ada teks yang dipilih." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Tak ada di tautan." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Pemberitahuan" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Dasar" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Puncak" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Tak ada pesan pemberitahuan" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "digit" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Ucapkan nomor sebagai digit." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "kata-kata" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Ucapkan nomor sebagai kata-kata." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "mati" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "nyala" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Memuat. Harap tunggu." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Selesai memuat." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Selesai memuat %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Halaman memiliki %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "halaman dipilih dari posisi kursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "halaman dipilih sampai posisi kursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "halaman tak dipilih dari posisi kursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "halaman tak dipilih sampai posisi kursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "paragraf dipilih ke bawah dari posisi kursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragraf dipilih ke atas dari posisi kursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "paragraf tak dipilih ke bawah dari posisi kursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragraf tak dipilih ke atas dari posisi kursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Anda telah memiliki satu instansi dialog preferensi Cthulhu yang terbuka.\n" -"Harap tutup itu sebelum membuka yang baru." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "salindia %(position)d dari %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil ditata ke %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Tak ada profil yang ditemukan." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Bilah kemajuan %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Semua" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Tingkat tanda baca ditata ke semua." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Kebanyakan" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Tingkat tanda baca ditata ke kebanyakan." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Tak ada" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Tingkat tanda baca ditata ke nihil." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Beberapa" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Tingkat tanda baca ditata ke sebagian." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Mencari." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Pencarian telah komplit." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Pengaturan Cthulhu dimuat ulang." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Teks yang dipilih: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Pilihan dihapus." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Pilihan dipulihkan." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Teks tak dipilih." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Ukuran: %d, %d. Lokasi: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Lebar: %d. Tinggi: %d. %d dari kiri. %d dari atas." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Ucapan dimatikan." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Ucapan difungsikan." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "lebih cepat." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "lebih lambat." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "lebih tinggi." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "lebih rendah." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "lebih keras." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "lebih lembut." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Kecepatan %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Nada %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volume %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Modul Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Suara Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Tidak ada modul Speech-dispatcher yang tersedia" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Tidak ada suara Speech-dispatcher yang tersedia" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Pengaturan ucapan disimpan" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Pengaturan ucapan tidak dapat disimpan" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Tingkat kecerewetan: ringkas" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Tingkat kecerewetan: rinci" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " titik titik titik" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu menyambut Anda." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu mengintai di bawah ombak." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Mode tidur diaktifkan untuk %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Mode tidur dinonaktifkan untuk %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Pengucapan tak tersedia." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Tak ditemukan" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Bilah status tidak ditemukan" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "string tak ditemukan" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Tombol navigasi struktural mati." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Tombol navigasi struktural menyala." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Tak ditemukan" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Baris %(row)d, kolom %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Akhir tabel" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Ucapkan sel" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Ucapkan baris" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Tak seragam" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Bukan dalam tabel." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Kolom diatur ulang" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Baris diatur ulang" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "kolom %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolom %(index)d dari %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Dasar kolom." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Puncak kolom." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Kolom %s dipilih" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Kolom %s sampai %s dipilih" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Kolom %s sampai %s tak dipilih" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Kolom %s tak dipilih" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "baris %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "baris %(index)d dari %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Awal baris." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Akhir baris." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Baris dihapus." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Baris terakhir dihapus." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Baris disisipkan." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Baris disisipkan di akhir tabel." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Baris %s dipilih" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Baris %s sampai %s dipilih" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Baris %s sampai %s tak dipilih" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Baris %s tak dipilih" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "dipilih" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "tak dipilih" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H jam, %M menit dan %S detik" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H jam dan %M menit" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "batalkan" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "jadi lagi" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versi %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "white space" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Melipat ke dasar." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Melipat ke puncak." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 butir" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Sel mencakup %d kolom" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d kolom" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Sel melingkupi %d kolom" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d karakter terlalu panjang" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialog)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d dialog belum fokus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d berkas ditemukan" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulir" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d tajuk" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d butir" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d landmark" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d butir ditemukan" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Meninggalkan %d kutip blok." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Meninggalkan %d daftar." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Daftar dengan ukuran yang tidak diketahui" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Senarai dengan %d butir" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Asupan dengan ukuran yang tidak diketahui" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Asupan dengan artikel %d" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Daftar deskripsi dengan %d istilah" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d nilai" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabel mat dengan %d baris" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d kolom" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tabel mat bersarang dengan %d baris" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d pesan.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d persen." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d persen dari dokumen telah dibaca" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d piksel" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s karakter" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d dari %(total)d butir dipilih" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d pintasan baku pembaca layar ditemukan." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d pintasan pembaca layar bagi %(application)s ditemukan." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d spasi" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tab" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabel" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabel dengan ukuran yang tidak diketahui" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabel dengan %d kolom, jumlah baris tidak diketahui" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabel dengan baris %d, jumlah kolom tidak diketahui" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabel dengan %d baris" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d detik yang lalu" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d menit yang lalu" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d jam yang lalu" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d hari yang lalu" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d taut belum dikunjungi" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d taut telah dikunjungi" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "jungkit" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "pada %(index)d dari %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d dari %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "butir %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "TINGKAT %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "pohon tingkat %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "POHON TINGKAT %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detail untuk %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "memiliki detail di %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "saran" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "kotak kombo yang dapat diubah" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "konten yang dapat disunting" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "asupan" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "gambar" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "abstrak" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "penghargaan" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "kata penutup" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "lampiran" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "entri bibliografi" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografi" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "bab" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "tanda penerbit" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "kesimpulan" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "sampul" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "penghargaan" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "penghargaan" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "persembahan" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "catatan akhir" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "catatan akhir" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "prasasti" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "ralat" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "contoh" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "kata pengantar" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosari" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "indeks" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "perkenalan" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "putus halaman" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "daftar halaman" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "bagian" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "pendahuluan" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "kutip tarik" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "tanya jawab" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "sub judul" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "daftar isi" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s tingkat %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "bilah gulung horisontal" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "bilah gulung vertikal" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "penggeser horisontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "penggeser vertikal" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "pemisah horisontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "pemisah vertikal" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "tukar" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Panel ikon" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "spanduk" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "konten pelengkap" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informasi" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "konten utama" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigasi" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "region" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "cari" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "tautan yang dikunjungi" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "tombol menu" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "diurutkan naik" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "diurutkan turun" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "diurutkan" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "dapat diklik" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "diringkaskan" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "dikembangkan" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "punya deskripsi panjang" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horisontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikal" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "dicontreng" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "tak dicontreng" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "nyala" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "mati" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "dicontreng sebagian" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "ditekan" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "tak ditekan" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "tak dipilih" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "dipilih" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "tak dipilih" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "tak dipilih" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "telah dikunjungi" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "belum dikunjungi" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "dijadikan kelabu" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "hanya baca" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "bacasaja" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "diperlukan" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "pilih multi" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "entri tidak valid" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "tidak valid" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ejaan tidak valid" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "pengejaan" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "tata bahasa tidak valid" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "tata bahasa" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Cari" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Dialog Cari Pembaca Layar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Tutup" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Cari" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Mencari:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Mencari:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Puncak jendela" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Puncak jendela" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Mulai dari:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Putar balik" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Cari _mundur" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Arah pencarian:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Cocok _huruf besar kecil" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Cocokkan s_eluruhan kata" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opsi:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Baku" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Huruf besar" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplikasi" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Jendela" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferensi Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Bantuan" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "Ter_apkan" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Tata Letak Papan Tik" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Profil Aktif:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profil Awal Mula:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Muat" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Simpan Seb_agai" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Hapus" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profil" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Sajikan toolti_p" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Ucapkan objek di bawah tetik_us" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Tetikus" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Format wak_tu:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Format ta_nggal:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Tanggal dan Waktu" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Ucapkan _semua pembaruan" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Pembaruan _Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frekuensi (detik):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Berlaku untuk:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Bunyi tit _pembaruan" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Pemutakhiran Batang Kemajuan" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Fungsikan mu_ndur dan maju cepat dalam Ucapkan Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Fungsikan navigasi _struktural dalam Ucapkan Semua" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Ucapkan Semua _Menurut:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Umumkan _kutip blok dalam Ucapkan Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Umumkan _daftar dalam Ucapkan Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Umumkan _tabel dalam Ucapkan Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Umumkan _panel dalam Ucapkan Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Umumkan _formulir dalam Ucapkan Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Umumkan land_mark dalam Ucapkan Semua" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Ucapkan Semua" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Presentasi Elemen:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Umum" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lume:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Pi_tch:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Laju:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Orang:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Bahasa:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Synthesi_zer ucapan:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Sistem ucapan:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipe _suara:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Gaya _kapitalisasi:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Pengaturan Tipe Suara" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Ucapkan string multi huruf besar kecil sebagai _kata-kata" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Ucapkan _nomor sebagai digit" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Pengaturan Suara Global" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Suara" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Fungsik_an ucapan" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Te_rrinci" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Tingkat rincian" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "Semu_a" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Tingkat Tanda Baca" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Ucapkan teks yang ditampilkan saja" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Ucapkan baris kosong" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Ucapkan _indentasi dan perataan" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Ucapkan mnemonik obje_k" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Ucapkan p_osisi anak" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Ucapkan pesan tutorial" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Pesan _sistem didetailkan" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Uca_pkan nama warna" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Umumkan _kutip blok selama navigasi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Umumkan _daftar selama navigasi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Umumlan _tabel selama navigasi" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Ucapkan i_ndikator salah-eja kata" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Umumkan _panel selama navigasi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Umumkan land_mark selama navigasi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Umumkan _formulir selama navigasi" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Ucapkan _deskripsi" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Ucapkan baris penuh pada sp_readsheets" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Ucapkan baris penuh pada tabel _dokumen" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Ucapkan baris penuh pada tabel _GUI" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Konteks Yang Diucapkan" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Bicara" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "_Aktifkan dukungan Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "N_ama-nama peran yang disingkat" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Nonaktifkan simbol _akhir baris" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tabel Kontraksi:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Aktifkan Braille Terkontraksi" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Fungsikan lipat _kata" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Pengaturan Tampilan" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Nihil" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indikator Pilihan" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indikator Hyperlink" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Fungsikan _pesan flash" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "D_urasi (detik):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Pesan bersifat teta_p" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Pesan bersifat _detail" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Pengaturan Pesan Kilat" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Fungsi_kan gaung tombol" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Fungsikan tombol _alfabet" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Fungsikan tombol n_umerik" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Fungsikan tombol _tanda baca" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Fungsikan _spasi" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Fungsikan to_mbol pengubah" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Fungsikan tombol _fungsi" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Fungsikan _tombol aksi" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Fungsikan tombol _navigasi" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Fungsikan gema per _kata" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Fungsikan gema per kali_mat" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Gema" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "To_mbol Pengubah Pembaca Layar:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Pengikatan Tombol" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Kamus Ejaan" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "E_ntri baru" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Hapus" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pengucapan" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Ucapkan _semua" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Tak ucapkan apapu_n" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Reset" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atribut teks" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Pindahkan ke _dasar" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Pindahkan ke _bawah" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Pindahkan ke _atas" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Pindahkan ke _puncak" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Setel atribut yang dipilih" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indikator Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atribut Teks" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Aktifkan Asisten AI" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Penyedia:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokal - Gratis)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "File _Kunci API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Jalur ke file kunci API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Dapatkan Kunci API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Buka browser untuk mendapatkan kunci API Claude dan simpan secara otomatis" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Memerlukan konfirmasi sebelum tindakan AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Model Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nama model untuk Ollama (misal, llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Endpoint Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL endpoint API Ollama (misal, http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Kualitas Tangkapan Layar:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Rendah" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Sedang" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Tinggi" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Asisten AI" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Kode _Bahasa:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Faktor _Skala:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Gambar _Skala Abu-abu" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Balikkan Gambar" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Gambar _Hitam Putih" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Ambang Batas Hitam/Putih:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analisis Warna" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Salin Hasil ke _Papan Klip" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "warna latar" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "latar belakang ketinggian penuh" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "latar belakang bintik-bintik" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "arah" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "dapat disunting" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nama famili" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "warna depan" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "latar depan titik-titik" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efek fonta" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indentasi" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "kesalahan" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "tak nampak" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "perataan" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "bahasa" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "marjin kiri" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "tinggi baris" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "gaya paragraf" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "piksel di atas baris" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "piksel di bawah baris" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "piksel dalam lipatan" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "marjin kanan" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "naik" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "skala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "ukuran" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "regangan" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "dicoret" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "gaya" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "dekorasi teks" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotasi teks" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "bayangan teks" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "digarisbawahi" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "varian" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "perataan vertikal" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "bobot" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "mode lipat" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "mode menulis" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "tak ada" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "gravir" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "ukir timbul" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "garis luar" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "overline" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "_salurkan melalui" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "berkedip" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "hitam" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "tunggal" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "ganda" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "rendah" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "karakter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "kata" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "kata karakter" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "kiri" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "kanan" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "tengah" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "tanpa rataan" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "isi" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "termampat ultra" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "ekstra dimampatkan" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "dimampatkan" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "agak dimampatkan" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "agak terkembang" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "dikembangkan" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "terkembang ekstra" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "terkembang ultra" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "huruf kecil" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "miring" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "miring" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Baku" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Tubuh teks" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Judul" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "garis basis" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "puncak" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "teks-puncak" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "tengah" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "dasar" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "teks-dasar" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "mewarisi" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "padat" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "pengejaan" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Tekan spasi untuk menjungkit." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Tekan spasi untuk mengembangkan, dan gunakan naik dan turun untuk memilih " -"suatu butir." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Tekan alt+f6 untuk memberikan fokus ke jendela anak." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "Untuk memindah butir, pakai tombol panah atau pencarian type ahead." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Untuk menuju menu sistem tekan tombol alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Pakai naik dan turun untuk memilih suatu butir." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Untuk meringkaskan, tekan shift dan kiri." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Untuk mengembangkan, tekan shift dan kanan." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Tekan return untuk mengaktifkan." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Ketikkan teks." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Pakai kiri dan kanan untuk melihat tab lain." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Tekan spasi untuk mengaktifkan." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Pakai panah atas atau bawah untuk memilih nilai. Atau ketikkan nilai numerik " -"yang dikehendaki." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Pakai tombol panah untuk mengubah." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Untuk menavigasi, tekan panah kiri atau kanan. Untuk bergerak melalui butir-" -"butir tekan panah atas atau bawah." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Untuk memasuki sub menu, tekan panah kanan." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Untuk menurunkan tekan panah kiri, untuk menaikkan tekan panah kanan. Untuk " -"ke minimum tekan home, dan untuk maksimum tekan end." diff --git a/po/is.po b/po/is.po deleted file mode 100644 index 4c634ae..0000000 --- a/po/is.po +++ /dev/null @@ -1,9555 +0,0 @@ -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# -# Sveinn í Felli , 2015. -msgid "" -msgstr "" -"Project-Id-Version: \n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2015-04-24 14:09+0000\n" -"Last-Translator: Sveinn í Felli \n" -"Language-Team: Icelandic \n" -"Language: is\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Lokalize 1.5\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu skjálestur" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "aðv" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "hreyfim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "ör" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "dagatl" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "skýr" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "hringja" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "sskgl" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -#, fuzzy -msgid "draw" -msgstr "jafntefli" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -#, fuzzy -msgctxt "shortbraille" -msgid "form" -msgstr "eyðublað" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "lyklo" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -#, fuzzy -msgid "spin" -msgstr "snúningur" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -#, fuzzy -msgid "term" -msgstr "annað" - -#: src/cthulhu/braille_rolenames.py:250 -#, fuzzy -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -#, fuzzy -msgid "tip" -msgstr "ábending" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "sjálfvirkt" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindí, stig 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "Ítalska, stig 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Ítalska, stig 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgísk hollenska, stig 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "bil" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nýlína" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "dálklykill" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "upphrópun" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "tilvitnun" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "númer" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollari" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "prósent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "og" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "úrfellingarmerki" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "vinstri svigi" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "hægri svigi" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "stjarna" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plús" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "komma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "strik" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punktur" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "skástrik" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "tvípunktur" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semíkomma" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "minna" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "jafnt og" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "meira" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "spurning" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "hjá" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "vinstri hornklofi" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "öfugt skástrik" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "hægri hornklofi" - -#: src/cthulhu/chnames.py:158 -#, fuzzy -msgid "caret" -msgstr "innskotsmerki (caret)" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "undirstrikað" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "vinstri slaufusvigi" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "lóðrétt pípa" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "hægri slaufusvigi" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "órjúfanlegt bil" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "viðsnúið upphrópunarmerki" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "sent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pund" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "gjaldmiðilstákn" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "hluti" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "höfundarréttur" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "skráð vörumerki" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "gráður" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plús eða mínus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mjú" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "málsgreinarmerki" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "raðtölur" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "einn fjórði" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "helmingur" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "þrír fjórðu" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "spurningamerki á hvolfi" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "sinnum" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -#, fuzzy -msgid "bullet" -msgstr "áherslumerki" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -#, fuzzy -msgid "euro" -msgstr "evra" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "vörumerki" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "hakmerki" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Cthulhu skjálestur" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "Fara í bókamerki." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "Fara í bókamerki." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "Bæta við bókamerki." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "Vista bókamerki." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Til vinstri í línu" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Til hægri í línu" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Upp um línu" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Niður um línu" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Frysta" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Efst til vinstri" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Neðst til vinstri" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Staðsetning bendils" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "Stillingar skjás" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "Stillingar skjás" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Stillingar skjás" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "textasnúningur" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -#, fuzzy -msgctxt "color name" -msgid "aquamarine" -msgstr "aquamarine" - -#: src/cthulhu/colornames.py:54 -#, fuzzy -msgctxt "color name" -msgid "azure" -msgstr "azor" - -#: src/cthulhu/colornames.py:59 -#, fuzzy -msgctxt "color name" -msgid "beige" -msgstr "beyki" - -#: src/cthulhu/colornames.py:64 -#, fuzzy -msgctxt "color name" -msgid "bisque" -msgstr "súpa" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "svart" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -#, fuzzy -msgctxt "color name" -msgid "blue" -msgstr "blár" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -#, fuzzy -msgctxt "color name" -msgid "brown" -msgstr "brúnn" - -#: src/cthulhu/colornames.py:94 -#, fuzzy -msgctxt "color name" -msgid "burlywood" -msgstr "spónarviður" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -#, fuzzy -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -#, fuzzy -msgctxt "color name" -msgid "chocolate" -msgstr "súkkulaði" - -#: src/cthulhu/colornames.py:114 -#, fuzzy -msgctxt "color name" -msgid "coral" -msgstr "kórall" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -#, fuzzy -msgctxt "color name" -msgid "cornsilk" -msgstr "kornsilki" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -#, fuzzy -msgctxt "color name" -msgid "cyan" -msgstr "blágrænn (cyan)" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -#, fuzzy -msgctxt "color name" -msgid "fuchsia" -msgstr "dökkbleikt" - -#: src/cthulhu/colornames.py:264 -#, fuzzy -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -#, fuzzy -msgctxt "color name" -msgid "gold" -msgstr "gull" - -#: src/cthulhu/colornames.py:279 -#, fuzzy -msgctxt "color name" -msgid "goldenrod" -msgstr "ljósgylltur" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "grátt" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "grænn" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -#, fuzzy -msgctxt "color name" -msgid "honeydew" -msgstr "hunangsdögg" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -#, fuzzy -msgctxt "color name" -msgid "ivory" -msgstr "fílabein" - -#: src/cthulhu/colornames.py:324 -#, fuzzy -msgctxt "color name" -msgid "khaki" -msgstr "kakí" - -#: src/cthulhu/colornames.py:329 -#, fuzzy -msgctxt "color name" -msgid "lavender" -msgstr "lavender" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -#, fuzzy -msgctxt "color name" -msgid "lime" -msgstr "Tími" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "lín" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "blárautt (magenta)" - -#: src/cthulhu/colornames.py:434 -#, fuzzy -msgctxt "color name" -msgid "maroon" -msgstr "ljósbrúnt" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -#, fuzzy -msgctxt "color name" -msgid "moccasin" -msgstr "mokkasín" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -#, fuzzy -msgctxt "color name" -msgid "navy" -msgstr "dökkblátt" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -#, fuzzy -msgctxt "color name" -msgid "olive" -msgstr "ólífugrænt" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -#, fuzzy -msgctxt "color name" -msgid "orange" -msgstr "appelsínugulur" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -#, fuzzy -msgctxt "color name" -msgid "orchid" -msgstr "orkídea" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -#, fuzzy -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -#, fuzzy -msgctxt "color name" -msgid "pink" -msgstr "bleikur" - -#: src/cthulhu/colornames.py:584 -#, fuzzy -msgctxt "color name" -msgid "plum" -msgstr "plóma" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -#, fuzzy -msgctxt "color name" -msgid "purple" -msgstr "fjólublár" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "rauður" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -#, fuzzy -msgctxt "color name" -msgid "salmon" -msgstr "laxrauður" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -#, fuzzy -msgctxt "color name" -msgid "seashell" -msgstr "sjóskel" - -#: src/cthulhu/colornames.py:639 -#, fuzzy -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -#, fuzzy -msgctxt "color name" -msgid "silver" -msgstr "silfur" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -#, fuzzy -msgctxt "color name" -msgid "snow" -msgstr "snjór" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "brúnka" - -#: src/cthulhu/colornames.py:684 -#, fuzzy -msgctxt "color name" -msgid "teal" -msgstr "djúp-blágrænt" - -#: src/cthulhu/colornames.py:689 -#, fuzzy -msgctxt "color name" -msgid "thistle" -msgstr "þistill" - -#: src/cthulhu/colornames.py:694 -#, fuzzy -msgctxt "color name" -msgid "tomato" -msgstr "tómatur" - -#: src/cthulhu/colornames.py:699 -#, fuzzy -msgctxt "color name" -msgid "turquoise" -msgstr "túrkís" - -#: src/cthulhu/colornames.py:704 -#, fuzzy -msgctxt "color name" -msgid "violet" -msgstr "fjólublár" - -#: src/cthulhu/colornames.py:709 -#, fuzzy -msgctxt "color name" -msgid "wheat" -msgstr "hveiti" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "hvítur" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "" - -#: src/cthulhu/colornames.py:724 -#, fuzzy -msgctxt "color name" -msgid "yellow" -msgstr "gulur" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -#, fuzzy -msgid "_Activate" -msgstr "_Virkja" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Hætta við" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Hoppa í" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "Í _lagi" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Ekkert" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "stafsetning" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -#, fuzzy -msgid "double click" -msgstr "tvísmellt" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "komma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "Sjálfgefið" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "skrifhamur" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "hluti" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "Vista bókamerki." - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "Tími og dagsetning" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "Breytt" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -#, fuzzy -msgid "_Desktop" -msgstr "Skjá_borð" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Tilkynning" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Tilkynning" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Tala" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Allt" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Forrit" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Gluggi" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "_Ekkert" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Su_mt" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Fl_est" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Lína" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Setning" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Inndregin tilvitnun" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Hnappur" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "Skýringatexti" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Hakreitur" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Fjölvalsreitur" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "Lýsing" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Fyrirsögn" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Mynd" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Merki" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -#, fuzzy -msgctxt "structural navigation" -msgid "Level" -msgstr "Stig" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "Tengill" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "Listi" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "" - -#: src/cthulhu/guilabels.py:635 -#, fuzzy -msgctxt "structural navigation" -msgid "Object" -msgstr "Hlutur" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Málsgrein" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Hægri hnappur" - -#: src/cthulhu/guilabels.py:654 -#, fuzzy -msgctxt "structural navigation" -msgid "Role" -msgstr "Hlutverk" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "Staða" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Texti" - -#: src/cthulhu/guilabels.py:679 -#, fuzzy -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -#, fuzzy -msgctxt "structural navigation" -msgid "Value" -msgstr "Gildi" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Hnappar" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -#, fuzzy -msgctxt "structural navigation" -msgid "Entries" -msgstr "Færslur" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "Fyrirsagnir" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Myndir" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "Tenglar" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listar" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Málsgreinar" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Töflur" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Sjálfgefið" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Tengill" - -#: src/cthulhu/guilabels.py:844 -#, fuzzy -msgctxt "VoiceType" -msgid "System" -msgstr "Kerfi" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Hástafa" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Stafsetningarleiðrétting" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "S_tutt" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Tilkynning" -msgstr[1] "Tilkynning" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "Stýring" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -#, fuzzy -msgid "page up" -msgstr "Síða upp" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -#, fuzzy -msgid "page down" -msgstr "Síða niður" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "Hopa (backspace)" - -#: src/cthulhu/keynames.py:157 -#, fuzzy -msgid "return" -msgstr "til baka" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "færa inn" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "upp" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "niður" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "vinstri" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "hægri" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "valmynd" - -#: src/cthulhu/keynames.py:209 -#, fuzzy -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "hjálp" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -#, fuzzy -msgid "escape" -msgstr "sleppa" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -#, fuzzy -msgid "insert" -msgstr "setja inn" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -#, fuzzy -msgid "delete" -msgstr "eyða" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -#, fuzzy -msgid "home" -msgstr "heim" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "endir" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "byrja" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "hringur" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "útlína" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "mínus" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "Setja inn" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -#, fuzzy -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -#, fuzzy -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -#, fuzzy -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "vinstri ör" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "vinstri ör" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "hægri ör" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "vinstri ör" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "hægri ör" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "hægri ör" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "hægri ör" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "vinstri ör" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "vinstri ör" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "hægri ör" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "vinstri ör" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "vinstri ör" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "hægri ör" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "hægri ör" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "hægri ör" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "hægri ör" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "minna" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "meira" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "punktur" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "lóðrétt jöfnun" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "lárétt" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "tómt mengi" - -#: src/cthulhu/mathsymbols.py:1395 -#, fuzzy -msgctxt "math symbol" -msgid "increment" -msgstr "hækka" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "kvaðratrót" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "ferningsrót" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "hlutfallslegt við" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "óendanlegt" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "Hægra horn:" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "horn" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "deilar" - -#: src/cthulhu/mathsymbols.py:1485 -#, fuzzy -msgctxt "math symbol" -msgid "does not divide" -msgstr "deilist ekki" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "samhliða" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "Röklegt OG" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "Röklegt EÐA" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "Skörun" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -#, fuzzy -msgctxt "math symbol" -msgid "union" -msgstr "Sameina" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "heill" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -#, fuzzy -msgctxt "math symbol" -msgid "ratio" -msgstr "Hlutfall" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "um það bil jafnt og" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "næstum jafnt og" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "ekki jafnt og" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "eins og" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "minna en eða jafnt og" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "stærra en eða jafnt og" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -#, fuzzy -msgctxt "math symbol" -msgid "between" -msgstr "á milli" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "Ferningslaga endi" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "satt" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -#, fuzzy -msgctxt "math symbol" -msgid "xor" -msgstr "XOR" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "samasem eða minni en" - -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "samasem eða stærra en" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "vinstri svigi" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "hægri svigi" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "vinstri svigi" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "hægri svigi" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "vinstri slaufusvigi" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "neðst" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "vinstri hornklofi" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "hægri hornklofi" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "Skörun" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "kvaðratrót" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "áherslumerki" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "undirstrikað" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "lóðrétt jöfnun" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "forrit" - -#: src/cthulhu/messages.py:48 -#, fuzzy -msgid "blank" -msgstr "tómt" - -#: src/cthulhu/messages.py:51 -#, fuzzy -msgid "bold" -msgstr "feitletrað" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "Fara í bókamerki." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "strengur fannst ekki" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "táknmynd" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "ekkert" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "stafsetning" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "valið" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "valið" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -#, fuzzy -msgid "OPTION" -msgstr "VALKOSTUR" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -#, fuzzy -msgid "NAME" -msgstr "NAFN" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -#, fuzzy -msgid "FILE" -msgstr "SKRÁ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "eyða" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "Skörun" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "spurning" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "ekki valið" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "strengur fannst ekki" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "ekki valið" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -#, fuzzy -msgid "empty" -msgstr "tómt" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "(%d gluggi)" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -#, fuzzy -msgctxt "key echo" -msgid "key" -msgstr "lykill" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "Ekkert" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "orð" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "lárétt" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "lóðrétt pípa" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "hægri ör" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "línuhæð" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "og" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "yfirstrikað" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "kvaðratrót" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "ferningsrót" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "Lýsing" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "Lýsing" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "Lýsing" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "Virkt" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Óvirkt" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Virkt" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "Inndregin tilvitnun" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -#, fuzzy -msgid "link" -msgstr "tengill" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "heimsótt" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "Fannst ekki" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "óvirkt" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "virkt" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -#, fuzzy -msgid "Object mode." -msgstr "Hlutur" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d prósent." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Ekki virkt" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "ekki valið" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "Tilkynning" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "Neðst" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "Efst" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "orð" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -#, fuzzy -msgid "off" -msgstr "óvirkt" - -#: src/cthulhu/messages.py:2051 -#, fuzzy -msgid "on" -msgstr "virkt" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "Allt" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ekkert" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -#, fuzzy -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Eitthvað" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu skjálestur" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "ekki valið" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Fannst ekki" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "strengur fannst ekki" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "strengur fannst ekki" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "Fannst ekki" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "ekki valið" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "ekki valið" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "ekki valið" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "ekki valið" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "valið" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d gluggi)" -msgstr[1] "(%d gluggar)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d atriði" -msgstr[1] "%d atriði" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "vörumerki" -msgstr[1] "vörumerki" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Gildi" -msgstr[1] "Gildi" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d prósent." -msgstr[1] "%d prósent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "víxla" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "spurning" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "breytanlegt" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "breytanlegt" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "orð" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "tvípunktur" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "yfirstrikað" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "stefna" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "orð" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "draga inn" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "Skörun" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "Síða upp" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "tilvitnun" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, fuzzy, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "lárétt" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "lóðrétt pípa" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "lárétt" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "lóðrétt jöfnun" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "lárétt" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "lóðrétt jöfnun" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Hlutfall" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "hálfþjappað" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "forrit" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "heimsótt" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -#, fuzzy -msgid "expanded" -msgstr "víkkað" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "lárétt" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "lóðrétt" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "merkt" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "ekki merkt" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "virkt" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "óvirkt" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "ýtt er á lykil" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "ekki valið" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "valið" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "ekki valið" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "ekki valið" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "heimsótt" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -#, fuzzy -msgctxt "text" -msgid "read only" -msgstr "skrifvarið" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "stafsetning" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "stafsetning" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Finna" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "_Loka" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "_Leita" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Leita að:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Leita að:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Efs_t í glugga" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Te_xtaskrið í kringum" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Leita afturá_bak" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Hástafsnæ_mt" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Máta einungis h_eil orð" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Skýringatexti" - -#: src/cthulhu/cthulhu-setup.ui:43 -#, fuzzy -msgid "Default" -msgstr "Sjálfgefið" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Hástafa" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Tengill" - -#: src/cthulhu/cthulhu-setup.ui:52 -#, fuzzy -msgid "System" -msgstr "Kerfi" - -#: src/cthulhu/cthulhu-setup.ui:80 -#, fuzzy -msgid "Application" -msgstr "Forrit" - -#: src/cthulhu/cthulhu-setup.ui:83 -#, fuzzy -msgid "Window" -msgstr "Gluggi" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "Cthulhu skjálestur" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -#, fuzzy -msgid "_Help" -msgstr "_Hjálp" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -#, fuzzy -msgid "_Apply" -msgstr "Virkj_a" - -#: src/cthulhu/cthulhu-setup.ui:272 -#, fuzzy -msgid "_Laptop" -msgstr "Fartö_lva" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "Lyklaborð" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -#, fuzzy -msgid "_Load" -msgstr "Á_lag" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -#, fuzzy -msgid "Save _As" -msgstr "Vist_a sem" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -#, fuzzy -msgid "Profiles" -msgstr "Snið" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -#, fuzzy -msgid "Mouse" -msgstr "Mús" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -#, fuzzy -msgid "Time and Date" -msgstr "Tími og dagsetning" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Braille blindraletur" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -#, fuzzy -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Tíðni (sek):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Forrit" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -#, fuzzy -msgid "General" -msgstr "Almennt" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -#, fuzzy -msgid "_Person:" -msgstr "_Einstaklingur:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "tungumál" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -#, fuzzy -msgid "Voice" -msgstr "Rödd" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -#, fuzzy -msgid "_All" -msgstr "_Allt" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "Lýsing" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Tal" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "Stillingar skjás" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "_Ekkert" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille blindraletur" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "órjúfanlegt bil" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3094 -#, fuzzy -msgid "Key Bindings" -msgstr "Lyklabindingar" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -#, fuzzy -msgid "_Delete" -msgstr "_Eyða" - -#: src/cthulhu/cthulhu-setup.ui:3204 -#, fuzzy -msgid "Pronunciation" -msgstr "Framburður:" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -#, fuzzy -msgid "_Reset" -msgstr "_Núllstilla" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "Eiginleikar texta" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "Eiginleikar texta" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Eigindi texta" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "lítill" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "tungumál" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -#, fuzzy -msgctxt "textattr" -msgid "background color" -msgstr "bakgrunnslitur" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "stefna" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "breytanlegt" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -#, fuzzy -msgctxt "textattr" -msgid "indent" -msgstr "draga inn" - -#: src/cthulhu/text_attribute_names.py:138 -#, fuzzy -msgctxt "textattr" -msgid "mistake" -msgstr "mistök" - -#: src/cthulhu/text_attribute_names.py:149 -#, fuzzy -msgctxt "textattr" -msgid "invisible" -msgstr "ósýnilegt" - -#: src/cthulhu/text_attribute_names.py:156 -#, fuzzy -msgctxt "textattr" -msgid "justification" -msgstr "textajöfnun" - -#: src/cthulhu/text_attribute_names.py:163 -#, fuzzy -msgctxt "textattr" -msgid "language" -msgstr "tungumál" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "vinstri spássía" - -#: src/cthulhu/text_attribute_names.py:176 -#, fuzzy -msgctxt "textattr" -msgid "line height" -msgstr "línuhæð" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "málsgreinarstíll" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "hægri spássía" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "skali" - -#: src/cthulhu/text_attribute_names.py:234 -#, fuzzy -msgctxt "textattr" -msgid "size" -msgstr "stærð" - -#: src/cthulhu/text_attribute_names.py:243 -#, fuzzy -msgctxt "textattr" -msgid "stretch" -msgstr "teygt" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -#, fuzzy -msgctxt "textattr" -msgid "style" -msgstr "stíll" - -#: src/cthulhu/text_attribute_names.py:265 -#, fuzzy -msgctxt "textattr" -msgid "text decoration" -msgstr "textaskreyting" - -#: src/cthulhu/text_attribute_names.py:274 -#, fuzzy -msgctxt "textattr" -msgid "text rotation" -msgstr "textasnúningur" - -#: src/cthulhu/text_attribute_names.py:281 -#, fuzzy -msgctxt "textattr" -msgid "text shadow" -msgstr "textaskuggi" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "undirstrikað" - -#: src/cthulhu/text_attribute_names.py:295 -#, fuzzy -msgctxt "textattr" -msgid "variant" -msgstr "tilbrigði" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "lóðrétt jöfnun" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "þykkt" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -#, fuzzy -msgctxt "textattr" -msgid "writing mode" -msgstr "skrifhamur" - -#: src/cthulhu/text_attribute_names.py:341 -#, fuzzy -msgctxt "textattr" -msgid "true" -msgstr "satt" - -#: src/cthulhu/text_attribute_names.py:349 -#, fuzzy -msgctxt "textattr" -msgid "false" -msgstr "ósatt" - -#: src/cthulhu/text_attribute_names.py:358 -#, fuzzy -msgctxt "textattr" -msgid "none" -msgstr "ekkert" - -#: src/cthulhu/text_attribute_names.py:365 -#, fuzzy -msgctxt "textattr" -msgid "engrave" -msgstr "ígrafið" - -#: src/cthulhu/text_attribute_names.py:372 -#, fuzzy -msgctxt "textattr" -msgid "emboss" -msgstr "upphleypt" - -#: src/cthulhu/text_attribute_names.py:379 -#, fuzzy -msgctxt "textattr" -msgid "outline" -msgstr "línuteikna" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "yfirstrikað" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "blikk" - -#: src/cthulhu/text_attribute_names.py:407 -#, fuzzy -msgctxt "textattr" -msgid "black" -msgstr "svart" - -#: src/cthulhu/text_attribute_names.py:414 -#, fuzzy -msgctxt "textattr" -msgid "single" -msgstr "single" - -#: src/cthulhu/text_attribute_names.py:421 -#, fuzzy -msgctxt "textattr" -msgid "double" -msgstr "double" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "lítill" - -#: src/cthulhu/text_attribute_names.py:435 -#, fuzzy -msgctxt "textattr" -msgid "char" -msgstr "staf" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "orð" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "vinstri" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "hægri" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "Miðjað" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "engin hliðjöfnun" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "fylling" - -#: src/cthulhu/text_attribute_names.py:507 -#, fuzzy -msgctxt "textattr" -msgid "ultra condensed" -msgstr "mjög mikið þjappað" - -#: src/cthulhu/text_attribute_names.py:514 -#, fuzzy -msgctxt "textattr" -msgid "extra condensed" -msgstr "mikið þjappað" - -#: src/cthulhu/text_attribute_names.py:521 -#, fuzzy -msgctxt "textattr" -msgid "condensed" -msgstr "þjappað" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "hálfþjappað" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "venjulegt" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "hálfvíkkað" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "víkkað" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "mikið víkkað" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "mjög mikið víkkað" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -#, fuzzy -msgctxt "textattr" -msgid "oblique" -msgstr "hallandi" - -#: src/cthulhu/text_attribute_names.py:584 -#, fuzzy -msgctxt "textattr" -msgid "italic" -msgstr "skáletrað" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "Sjálfgefið" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "Meginmál texta" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "Fyrirsögn" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "efst" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "miðju" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "neðst" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -#, fuzzy -msgctxt "textattr" -msgid "solid" -msgstr "gegnheilt" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "stafsetning" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Settu hér inn texta." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/it.po b/po/it.po deleted file mode 100644 index 255448c..0000000 --- a/po/it.po +++ /dev/null @@ -1,9392 +0,0 @@ -# Italian translation for Cthulhu -# Copyright (C) 2005 Sun Microsystems Inc. -# Copyright (C) 2009-2013, 2014, 2015, 2017, 2018, 2019, 2020, 2021, 2022 Free Software Foundation, Inc. -# This file is distributed under the same license as the Cthulhu package. -# Aldo "Xoen" Giambelluca , 2005. -# -# -# magnify vs zoom -# -# bookmark -# per evitare confusioni con altri tipi di segnalibro -# (web browser, posizioni...) qui in cthulhu lo traduco -# come contrassegno -# speak -# leggere -# Collegamenti utili per i simboli matematici: -# -# http://images4.wikia.nocookie.net/formalmethods/images/3/3d/Zglossary.pdf -# http://terrymarris.tripod.com/TheZTutorial.pdf -# http://www.access2science.com/latex/Binary.html -# http://www.orion.it/~alf/docbook/iso-amsb.html -# -# Luca Ferretti , 2006, 2007. 2008, 2009, 2010, 2011, 2012, 2013. -# Milo Casagrande , 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022. -# Gianvito Cavasoli , 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-05-11 12:43+0200\n" -"Last-Translator: Gianvito Cavasoli \n" -"Language-Team: Italian \n" -"Language: it\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"X-Generator: Gtranslator 42.0\n" - -msgid "Cthulhu Screen Reader" -msgstr "Lettore schermo Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "lettore;schermo;accessibilità;voce;braille;" - -# Nota gigante del traduttore -# I messaggi che provengono da rolenames.py sono i nomi dei widget e dei ruoli -# che questi possono avere. Parte di ciò è già stato tradotto in ATK, per cui -# si cercherà di tenere le due traduzioni in sincro. -# -# Tenere presente che in Cthulhu abbiamo cose tipo: -# -# ROLE_INVALID --> braille corto: ??? -# --> braille lungo: Non valido (in maiuscolo per scelta) -# --> letto: non valido -# -# I braille corti debbono essere univoci e sotto i tre caratteri... -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "fre" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -# abbastanza breve in italiano da non necessitare abbreviazione -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "tel" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "did" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "spu" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "selcol" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "intcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cmb" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ico" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "cor" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "qua" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "riqd" - -# NOTA in ATK è ROLE_DOCUMENT_FRAME, anche in cthulhu, ma viene usato HTML pane... -# condiviso con ROLE_HTML_CONTAINER -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "dis" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "selfile" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "rie" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "selcar" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "mod" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "riqtr" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "int" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "corint" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etic" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "riqliv" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "coll" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "eln" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "voceln" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "barmnu" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "vocmnu" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "riqopz" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "sch" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "elsch" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mencomp" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "barava" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "pls" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "vocmnurad" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "riqrad" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "intrig" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "brscr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "rqscr" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sez" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "scor" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "riqdiv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "plssel" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "barsta" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "vocmnusta" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tst" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "plscom" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "barstr" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "sugg" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "alb" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tabalb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "scon" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "arvis" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "fin" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "int" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pie" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "barmod" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "incor" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Ceco grado 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spagnolo grado 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francese canadese grado 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francese francese grado 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Lettone grado 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Olandese olandese grado 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvegese grado 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvegese grado 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvegese grado 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvegese grado 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polacco grado 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portoghese grado 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Svedese grado 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabo grado 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Gallese grado 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Gallese grado 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Tedesco grado 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Tedesco grado 2" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Tedesco grado 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Inglese britannico grado 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Inglese britannico grado 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Inglese americano grado 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Inglese americano grado 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francese canadese grado 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francese francese grado 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Greco grado 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Indi grado 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ungherese computer a 8 punti" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Ungherese grado 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Ungherese grado 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiano grado 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Olandese belga grado 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "spazio" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "a capo" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulazione" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "punto esclamativo" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "virgolette" - -# o cancelletto ????? -# -# in inglese # è usato come numero, non in italiano... -# -# -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "cancelletto" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollaro" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percentuale" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "e commerciale" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrofo" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "parentesi sinistra" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "parentesi destra" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterisco" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "più" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "virgola" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "trattino" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punto" - -# visto che è "spoken" devo tradurre -# slesc ? -# ???? O appare anche sui braille? -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slash" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "due punti" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punto e virgola" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "minore" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "uguale" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "maggiore" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "punto interrogativo" - -# chiocciolina? a commerciale? at? -Luca -# -# -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "chiocciola" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "parentesi quadra sinistra" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "slash inversa" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "parentesi quadra destra" - -# Traduzione da GarzantiLinguistica.it -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "segno di omissione" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "sottolineatura" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "accento grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "parentesi graffa sinistra" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra verticale" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "parentesi graffa destra" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -# http://www.liberliber.it/biblioteca/w/world_wide_web_consortium/specifiche_html40/html/sgml/entities.html -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "spazio non separabile" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "punto esclamativo invertito" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "sterline" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "segno di valuta" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -# preso (questo e altri a seguire) da -# -# http://www.liberliber.it/biblioteca/w/world_wide_web_consortium/specifiche_html40/html/sgml/entities.html -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra spezzata" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "sezione" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "dieresi" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "simbolo di diritto d'autore" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "indicatore ordinale femminile" - -# visto che le usiamo nella UI e viene letto, -# metto virgolette invece di caporale, visto -# che la cosa è nota solo a gente di un certo livello -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "virgolette doppie sinistre" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "no logico" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "trattino" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "simbolo di marchio registrato" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "segno di vocale lunga" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "gradi" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "più o meno" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "esponente 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "esponente 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acuto" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mi" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "simbolo di paragrafo" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "punto centrale" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cediglia" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "esponente 1" - -# primo -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "indicatore ordinale maschile" - -# cfr altro commento per caporali -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "virgolette doppie destre" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "frazione un quarto" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "frazione un mezzo" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "frazione tre quarti" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "punto interrogativo capovolto" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a latina minuscola con accento acuto" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A latina maiuscola con accento grave" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A latina maiuscola con accento acuto" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A latina maiuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A latina maiuscola con tilde" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A latina maiuscola con dieresi" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A latina maiuscola con anello sopra" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "AE latina maiuscola" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C latina maiuscola con cediglia" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E latina maiuscola con accento grave" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E latina maiuscola con accento acuto" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E latina maiuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E latina maiuscola con dieresi" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I latina maiuscola con accento grave" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I latina maiuscola con accento acuto" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I latina maiuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I latina maiuscola con dieresi" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH latina maiuscola" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N latina maiuscola con tilde" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O latina maiuscola con accento grave" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O latina maiuscola con acento acuto" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O latina maiuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O latina maiuscola con tilde" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O latina maiuscola con dieresi" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "segno di moltiplicazione" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O latina maiuscola sbarrata" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U latina maiuscola con accento grave" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U latina maiuscola con accento acuto" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U latina maiuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U latina maiuscola con dieresi" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y latina maiuscola con accento acuto" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN latina maiuscola" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "sharp s latina minuscola" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a latina minuscola con accento grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a latina minuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a latina minuscola con accento grave" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a latina minuscola con dieresi" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a latina minuscola con anello sopra" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ae latina minuscola" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c latina minuscola con cediglia" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e latina minuscola con accento grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e latina minuscola con accento acuto" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e latina minuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e latina minuscola con dieresi" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i latina minuscola con accento grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i latina minuscola con accento acuto" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i latina minuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i latina minuscola con dieresi" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth latina minuscola" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n latina minuscola con tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o latina minuscola con accento grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o latina minuscola con accento acuto" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o latina minuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o latina minuscola con tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o latina minuscola con dieresi" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "diviso" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o latina minuscola barrata" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn latino minuscolo" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u latina minuscola non accento acuto" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u latina minuscola con accento grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u latina minuscola con accento circonflesso" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u latina minuscola con dieresi" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y latina minuscola con accento acuto" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y latina minuscola con dieresi" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y latina maiuscola con dieresi" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "f minuscola latina con gancio" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash (linea)" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "virgoletta singola sinistra" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "virgoletta singola destra" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "virgoletta singola bassa" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "virgolette doppie sinistra" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "virgolette doppie destra" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "virgolette doppie basse" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "spada" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "doppia spada" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "bullet" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "bullet triangolare" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "segno per mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "primo (minuti)" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "doppio primo (secondi)" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "triplo primo" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "bullet trattino" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "segno marchio registrato" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "segno di spunta" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "segno di spunta pesante" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "bullet a forma di x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "esponente 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "esponente 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "esponente 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "esponente 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "esponente 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "esponente 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "esponente 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "esponente più" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "esponente meno" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "esponente uguale" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "esponente parentesi sinistra" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "esponente parentesi destra" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "esponente n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "0 sottoscritto" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "1 sottoscritto" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "2 sottoscritto" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "3 sottoscritto" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "4 sottoscritto" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "5 sottoscritto" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "6 sottoscritto" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "7 sottoscritto" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "8 sottoscritto" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "9 sottoscritto" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "più sottoscritto" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "meno sottoscritto" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "uguale sottoscritto" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "parentesi sinistra sottoscritta" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "parentesi destra sottoscritta" - -# RESEARCH -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "quadrato nero" - -# RESEARCH -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "rombo nero" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "carattere sostitutivo di oggetto" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Indirizza il puntatore all'oggetto corrente" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Esegue un clic sinistro sull'attuale elemento in revisione piatta" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Esegue un clic destro sull'attuale elemento in revisione piatta" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Legge l'intero documento" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Legge tutta la finestra in revisione piatta" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Esegue l'operazione \"dove mi trovo\" di base" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Esegue l'operazione \"dove mi trovo\" dettagliata" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Legge la selezione attuale" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Legge i dettagli del collegamento" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Presenta il pulsante predefinito" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Presenta la barra di stato" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Presenta la barra del titolo" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Apre la finestra Trova" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Mostra elenco azioni" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Cerca l'istanza successiva di una stringa" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Cerca l'istanza precedente di una stringa" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Entra ed esce dalla modalità revisione piatta" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Commuta restrizione revisione piatta all'oggetto corrente" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Sposta la revisione piatta alla posizione iniziale" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Sposta la revisione piatta alla posizione finale" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Sposta la revisione piatta all'inizio della riga precedente" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Legge l'attuale riga in revisione piatta" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Legge lettera per lettera l'attuale riga in revisione piatta" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" -"Legge lettera per lettera e foneticamente l'attuale riga in revisione piatta." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Sposta la revisione piatta all'inizio della riga successiva" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Sposta la revisione piatta alla voce o parola precedente" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Legge l'attuale elemento o parola in revisione piatta" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" -"Legge lettera per lettera l'attuale elemento o parola in revisione piatta" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Legge lettera per lettera e foneticamente l'attuale elemento o parola in " -"revisione piatta" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Sposta la revisione piatta alla voce o parola successiva" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Sposta la revisione piatta alla parola sopra l'attuale parola" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Legge l'attuale oggetto in revisione piatta" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Sposta la revisione piatta alla parola sotto l'attuale parola" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Sposta la revisione piatta al carattere precedente" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Legge l'attuale carattere in revisione piatta" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Legge foneticamente l'attuale carattere in revisione piatta" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Legge il valore unicode del carattere attualmente in revisione piatta" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Sposta la revisione piatta al carattere successivo" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Sposta la revisione piatta al termine della riga" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Sposta la revisione piatta in basso a sinistra" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copia negli appunti il contenuto in revisione piatta" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Accoda agli appunti il contenuto in revisione piatta" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Mostra contenuto della revisione piatta" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Passa dalla lettura della cella di tabella corrente a quella della intera " -"riga e viceversa" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Legge gli attributi associati con il carattere di testo attuale" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Scorre il display braille verso sinistra" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Scorre il display braille verso destra" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Ritorna all'oggetto con il focus da tastiera" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Attiva e disattiva il braille contratto" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Elabora un tasto di indirizzamento del cursore" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Contrassegna l'inizio di una selezione di testo" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Contrassegna la fine di una selezione di testo" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Entra nella modalità apprendimento: premere ESC per uscire dalla modalità " -"apprendimento" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Diminuisce la velocità di lettura" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Incrementa la velocità di lettura" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Diminuisce la tonalità di lettura" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Incrementa la tonalità di lettura" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Incrementa il volume di lettura" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Diminuisce il volume di lettura" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Seleziona impostazione voce precedente" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Seleziona impostazione voce successiva" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Diminuisci impostazione voce corrente" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Aumenta impostazione voce corrente" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Salva impostazioni voce" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Attiva/Disattiva il silenzio del parlato" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Attiva/Disattiva il livello di verbosità del parlato" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Attiva/disattiva modalità sospensione" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Esce dal lettore di schermo" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Visualizza il dialogo di configurazione delle preferenze" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" -"Visualizza il dialogo di configurazione delle preferenze dell'applicazione" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Attiva/Disattiva la lettura di rientri e allineamento" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Cambia lo stile di lettura dei numeri" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" -"Passa ciclicamente al successivo livello di lettura della punteggiatura" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Passa al sintetizzatore vocale successivo" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Passa ciclicamente al successivo profilo di impostazioni" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Passa ciclicamente al successivo stile di utilizzo delle maiuscole" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Passa ciclicamente al successivo livello di eco tasti" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Passa ciclicamente da un livello di debug a un altro a runtime" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Contrassegna \"dove mi trovo\" rispetto alla posizione attuale" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Va alla precedente posizione contrassegnata" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Va al contrassegno" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Va alla successiva posizione contrassegnata" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Aggiunge un contrassegno" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Salva i contrassegni" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Attiva/Disattiva la modalità revisione mouse" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Presenta l'ora corrente" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Presenta la data corrente" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Presenta la dimensione e la posizione dell'oggetto corrente" - -# -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Passa al comando successivo sull'applicazione corrente" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Legge e mette su braille un precedente messaggio del canale di chat" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Controlla se annunciare quando i propri conoscenti stanno digitando" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Controlla se è possibile fornire cronologie di messaggi specifici del canale " -"di chat" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Controlla se mettere oppure no il nome del canale di conversazione come " -"prefisso dei messaggi dal canale stesso" - -# RESEARCH -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Riga a sinistra" - -# RESEARCH -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Riga a destra" - -# RESEARCH -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Riga su" - -# RESEARCH -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Riga giù" - -# RESEARCH -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Blocca" - -# RESEARCH -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Superiore sinistro" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Inferiore sinistro" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posizione cursore" - -# RESEARCH -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Sei punti" - -# RESEARCH -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Instradamento cursore" - -# RESEARCH -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Inizio taglio" - -# RESEARCH -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Taglia riga" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Presenta l'ultimo messaggio di notifica" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Presenta l'elenco dei messaggi di notifica" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Presenta il precedente messaggio di notifica" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Presenta il prossimo messaggio di notifica" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Va al carattere successivo" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Va al carattere precedente" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Va alla parola successiva" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Va alla parola precedente" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Va alla riga successiva" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Va alla riga precedente" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Va all'inizio del file" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Va alla fine del file" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Va all'inizio della riga" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Va alla fine della riga" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Va all'oggetto successivo" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Va all'oggetto precedente" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Causa l'espansione della casella combinata corrente" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Passa tra la navigazione nativa e quella con cursore di inserimento testo " -"del lettore di schermo" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Impostazioni avanzate di cortesia per regioni attive" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" -"Imposta il livello predefinito di cortesia delle regioni attive a disattivato" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Controlla gli annunci delle regioni attive" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitoraggio delle regioni attive" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Sposta il focus all'interno e all'esterno del mouse over corrente" - -# spero che sia giusta.... -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Imposta la riga da usare come intestazioni di colonna dinamiche" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Pulisce le intestazioni di colonna dinamiche" - -# spero che sia giusta... -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Imposta la colonna da usare come intestazioni di riga dinamiche" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Pulisce le intestazioni di riga dinamiche" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Presenta il contenuto della riga di input" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Attiva/Disattiva i tasti di navigazione per struttura" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Va al precedente blocco di citazione" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Va al successivo blocco di citazione" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Visualizza un elenco di blocchi di citazione" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Va al pulsante precedente" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Va al pulsante successivo" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Visualizza un elenco di pulsanti" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Va alla casella di spunta precedente" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Va alla casella di spunta successiva" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Visualizza un elenco di caselle di spunta" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Va all'elemento con clic precedente" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Va all'elemento con clic successivo" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Visualizza un elenco di elementi con clic" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Va alla casella combinata precedente" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Va alla casella combinata successiva" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Va all'inizio del contenitore" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Va alla fine del contenitore" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Visualizza un elenco di caselle combinate" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Va alla voce precedente" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Va alla voce successiva" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Visualizza un elenco di voci" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Va al campo modulo precedente" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Va al campo modulo successivo" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Visualizza un elenco di campi modulo" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Va all'intestazione precedente" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Va all'intestazione successiva" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Visualizza un elenco di intestazioni" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Va all'intestazione di livello %d precedente" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Va all'intestazione di livello %d successiva" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Visualizza un elenco di intestazione di livello %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Vai al frame interno precedente" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Vai al frame interno successivo" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Visualizza un elenco di frame interni" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Va all'immagine precedente" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Va all'immagine successiva" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Visualizza un elenco di immagini" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Va al punto di riferimento precedente" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Va al punto di riferimento successivo" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Visualizza un elenco di punti di riferimento" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Va all'oggetto esteso precedente" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Va all'oggetto esteso successivo" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Visualizza un elenco di oggetti estesi" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Va al collegamento precedente" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Va alla collegamento successivo" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Visualizza un elenco di collegamenti" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Va all'elenco precedente" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Va all'elenco successivo" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Visualizza un elenco di elenchi" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Va alla voce di elenco precedente" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Va alla voce di elenco successiva" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Visualizza un elenco di voci elenco" - -# live region: sezione della pagina web che si aggiorna senza refresh -# (spiegato in altro commento) -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Va alla regione attiva precedente" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Va alla regione attiva successiva" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Va all'ultima regione attiva che ha fatto un annuncio" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Vai al genitore dell'oggetto con il focus del navigatore." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Vai al primo figlio dell'oggetto con il focus del navigatore." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Vai al fratello successivo dell'oggetto con il focus del navigatore." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Vai al fratello precedente dell'oggetto con il focus del navigatore." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Clicca sull'oggetto con focus del navigatore." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Commuta navigazione oggetti semplificata." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Va al paragrafo precedente" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Va al paragrafo successivo" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Visualizza un elenco di paragrafi" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Va al pulsante radio precedente" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Va al pulsante radio successivo" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Visualizza un elenco di pulsanti radio" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Va al separatore precedente" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Va al separatore successivo" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Va alla tabella precedente" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Va alla tabella successiva" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Visualizza un elenco di tabelle" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Va una cella in basso" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Va alla prima cella in una tabella" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Va all'ultima cella in una tabella" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Va una cella a sinistra" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Va una cella a destra" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Va una cella in alto" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Attiva/Disattiva la modalità disposizione" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Passa tra modalità navigazione e focus" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Abilita la modalità focus adesivo" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Abilita la modalità navigazione adesiva" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Va al precedente collegamento non visitato" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Va al successivo collegamento non visitato" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Visualizza un elenco di collegamenti non visitati" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Va al precedente collegamento visitato" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Va al successivo collegamento visitato" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Visualizza un elenco di collegamenti visitati" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "blu alice" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "bianco antico" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "acquamarina" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azzurro" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -# (ndt) un marrone chiaro -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "nero" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "mandorla scottata" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blu" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "blu violetto" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "marrone" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "marrone legno" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "blu cadetto" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "verde pallido" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "cioccolato" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "corallo" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "blu fiordaliso" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "seta di mais" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "cremisi" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "ciano" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "blu scuro" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "ciano scuro" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "dorato scuro" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "grigio scuro" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verde scuro" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "cachi scuro" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta scuro" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "verde oliva scuro" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "arancione scuro" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "orchidea scuro" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "rosso scuro" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmone scuro" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "verde mare scuro" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "blu ardesia scuro" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "ardesia scuro" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turchese scuro" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violetto scuro" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "rosa intenso" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "blu cielo intenso" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "grigio tenue" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "blu dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "rosso mattone" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "bianco fiore" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "verde foresta" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fucsia" - -# (ndt) è un grigio chiaro, ma pare non esista una reale controparte italiana -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "bianco fantasma" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "oro" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "dorato" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "grigio" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verde" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "verde giallo" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "verde melone" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "rosa caldo" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "rosso indiano" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indaco" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "avorio" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "cachi" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavanda rosa chiaro" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "verde prato" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "limone leggero" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "blu chiaro" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "corallo chiaro" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "ciano chiaro" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "giallo dorato chiaro" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "grigio chiaro" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "verde chiaro" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "rosa chiaro" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmone chiaro" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "verde acqua chiaro" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "blu cielo chiaro" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "ardesia chiaro" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "blu acciaio chiaro" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "giallo chiaro" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "verdognolo" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "verde lime" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "lino" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "rosso granata" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "acquamarina medio" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "blu medio" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orchidea medio" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "viola medio" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "verde mare medio" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "blu ardesia medio" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "verde primavera medio" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turchese medio" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "rosso violetto medio" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "blu notte" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "verde primavera pastello" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rosa bagnata" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mocassino" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "bianco navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "blu marino" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "pizzo antico" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliva" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "verde militare" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "arancione" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "arancio rosso" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchidea" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "dorato tenue" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "verde tenue" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turchese tenue" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "violetto rosso tenue" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "frullato di papaya" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "nuvola di pesca" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "perù" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "prugna" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "celeste" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "viola" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "rosso" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "marrone rosa" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "blu reale" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "marrone sella" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmone" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "marrone sabbia" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "verde mare" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "conchiglia" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "terra di Siena" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "argento" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "blu cielo" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "blu ardesia" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "ardesia" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "neve" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "verde primavera" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "blu acciaio" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "marrone chiaro" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "foglia di tè" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "cardo" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "pomodoro" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turchese" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violetto" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "grano" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "bianco" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "bianco fumo" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "giallo" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "verde giallo" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Attiva" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Modalità focus automatica durante la navigazione strutturale" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" -"Modalità focus automatica durante la navigazione con cursore di inserimento " -"testo" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Modalità focus automatica durante la navigazione nativa" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Dot _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Dot _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "_Dot 7 e 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "A_nnulla" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "V_ai a" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Icona" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Nessuno" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Ortografia" - -# controllare acceleratore -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Annunciare quando i propri conoscenti stanno _digitando" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Fornire cronologie dei _messaggi specifici dei canali di chat" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Leggere i messaggi da" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Tutti i ca_nali" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Tutti i canali quando una _qualsiasi finestra di %s è attiva" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Un canale solo se la sua _finestra è attiva" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Leggere il nome del canale di chat" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Abilitare modalità disposizione per il contenuto" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "doppio clic" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triplo clic" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizzatore predefinito" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Stringa reale" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Stringa sostituita" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Abilitare l'eco sul c_arattere" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Abilitare i tasti _diacritici non spaziatura" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Posizione att_uale" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Lunghezza minima del testo corrispondente:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opzioni di ricerca" - -# FIXME, non mi pare molto chiaro a giudicare dal commento... -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Leggere _solo le righe cambiate durante la ricerca" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Leggere i _risultati durante la ricerca" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Comando" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Associazione tasti" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Predefinito" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Modalità disposizione." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Azioni" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Associazioni Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Segnalibri" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Ora e data" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Modalità revisione mouse abilitata." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navigazione" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Modalità oggetto." - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Non associati" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Uscito dalla revisione piatta." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Attiva/Disattiva il livello di verbosità del parlato" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "contenuto principale" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificato" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Desktop" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notifica" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Ricevuto" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Notifica" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferenze di Cthulhu per %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Contrassegnare in braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Presenta a meno che" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Leggere" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Salva profilo come conflitto" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflitto profilo utente" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Esiste già il profilo %s.\n" -"Continuare aggiornando il profilo esistente con queste nuove modifiche?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Carica profilo utente" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Si sta per cambiare il profilo attivo. Nel caso\n" -"in cui si siano appena apportate modifiche alle\n" -"proprie preferenze, queste verranno scartate al\n" -"caricamento del profilo.\n" -"\n" -"Contuare caricando il profilo e scartando i\n" -"cambiamenti precedenti?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Salva profilo come" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nome del _profilo:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Rimuovi profilo utente" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Si sta per rimuovere il profilo %s. Tutte le impostazioni non salvate e " -"salvate in questo profilo andranno perse. Continuare e rimuovere questo " -"profilo e tutte le relative impostazioni?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Tutti" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Applicazione" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Finestra" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Nessuno" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Qualcuno" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Parecchi" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Riga" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Sentenza" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Blocco di citazione" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Pulsante" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Didascalia" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Casella di spunta" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Elemento con clic" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Casella combinata" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descrizione" - -# come da traduzione oo.o -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Intestazione" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "intercalate" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Immagine" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etichetta" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Punto di riferimento" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Livello" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Collegamento" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Elenco" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Voce elenco" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Oggetto" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragrafo" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Pulsante radio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Ruolo" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Elemento selezionato" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stato" - -# come da traduzione oo.o -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Testo" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valore" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blocchi di citazione" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Pulsanti" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Caselle di spunta" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Elementi con clic" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Caselle combinate" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Voci" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Campi modulo" - -# come da traduzione oo.o -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Intestazioni" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "intercalate" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Immagini" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Intestazione di livello %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Punti di riferimento" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Oggetti estesi" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Collegamenti" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Elenchi" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Voci elenco" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragrafi" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Pulsanti radio" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabelle" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Collegamenti non visitati" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Collegamenti visitati" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navigazione di pagina" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Avviare automaticamente la _lettura di una pagina al primo caricamento" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "Avviare automaticamente la _lettura di una pagina al primo caricamento" - -# FIXME!!! BOH! -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Dividere il parlato in pezzi tra le pa_use" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Voce predefinita per %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Predefinita" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Collegamento ipertestuale" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Lettere maiuscole" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Controllo ortografico" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Scandire _errore" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Scandire _suggerimento" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "_Contesto corrente dell'errore" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Leggere le coordinate della cella del foglio di calcolo" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Leggere sempre l'intervallo selezionato del foglio di calcolo" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Annunciare le _intestazioni di cella" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigazione di tabella" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Omettere le celle _vuote" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Leggere la c_ella" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Leggere le coordinate di _cella" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Leggere le occupazioni di celle _multiple" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nome attributo" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Controllare la navigazione con cursore" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Abilitare navigazione _strutturale" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Tema sonoro:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Tema sonoro" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "C_onciso" - -#: src/cthulhu/guilabels.py:953 -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Notifica" -msgstr[1] "Notifica" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Maiusc" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "maiuscolo sinistro" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt sinistro" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control sinistro" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "maiuscolo destro" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt destro" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control destro" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta sinistro" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta destro" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "blocca num" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "blocca maiuscole" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "blocca maiuscole" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "blocca scorrimento" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "pagina su" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "pagina giù" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab sinistro" - -# come da traduzione IBM -# hmmmmmm -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "spazio di ritorno" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "invio" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "invio" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "su" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "giù" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "sinistra" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "destra" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super sinistro" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super destro" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menù" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "aiuto" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -# leggi la NdT appena 3 messaggi sopra -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "cambio modo" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "esc" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "ins" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "canc" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "fine" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "inizio" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "cinconflesso" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "anello" - -# FIXME!!!!! non è sicuro -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "barra" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "meno" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Ins" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Bloc_Maiusc" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_D" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_S" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Maiusc" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s grassetto" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s corsivo" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s grassetto corsivo" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s ornato" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s grassetto ornato" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s fraktur" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s grassetto da lavagna" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s grassetto fraktur" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s sans-serif" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s sans-serif grassetto" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s sans-serif corsivo" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s sans-serif grassetto corsivo" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s spaziatura fissa" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s senza puntino" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "freccia a sinistra" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "freccia in su" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "freccia a destra" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "freccia in giù" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "freccia sinistra-destra" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "freccia su-giù" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "freccia in su verso sinistra" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "freccia in su verso destra" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "freccia in giù verso destra" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "freccia a sinistra da barra" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "freccia in su da barra" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "freccia a destra da barra" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "freccia in giù da barra" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "doppia freccia a sinistra" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "doppia freccia in su" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "doppia freccia a destra" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "doppia freccia in giù" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "doppia freccia sinistra-destra" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "doppia freccia su-giù" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "doppia freccia in su verso sinistra" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "doppia freccia in su verso destra" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "doppia freccia in giù verso destra" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "doppia freccia in giù verso sinistra" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "freccia che punta a destra" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "punta di freccia che punta a destra" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "meno" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "minore di" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "maggiore di" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "cinconflesso" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "antiflesso" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punto" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "doppia linea verticale" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "ellissi orizzontale" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "per ogni" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complemento" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "derivata parziale" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "esiste" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "non esiste" - -# riferita a cella di foglio di calcolo -Luca -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "insieme vuoto" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "delta" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "appartiene" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "non appartiene" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "appartiene piccolo" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "contiene" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "non contiene" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "contiene piccolo" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "fine dimostrazione" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produttoria" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "co-produttoria" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sommatoria" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "meno o più" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "punto più" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "divisione" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "differenza insiemistica" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "asterisco" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operatore di composizione" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operatore pallino" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "radice quadrata" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "radice cubica" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "radice quarta" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporzionale a" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinito" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "angolo retto" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "angolo" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "angolo misurato" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "angolo sferico" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "divide" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "non divide" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "parallelo a" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "non parallelo a" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "congiunzione logica" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "disgiunzione logica" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersezione" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unione" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integrale" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integrale doppio" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integrale triplo" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integrale curvilineo" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integrale di superficie" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integrale di volume" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integrale in senso orario" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integrale di contorno in senso orario" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integrale di contorno in senso antiorario" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "quindi" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "poiché" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "rapporto" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporzione" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "punto meno" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "eccede" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporzione geometrica" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "omotètico" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "tilde inversa" - -# (ndt) simbolo matematico, quello non invertito indica porporzionalità, questo non ho idea -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "S lazy invertita" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "onda sinusoidale" - -# https://it.wikipedia.org/wiki/Prodotto_intrecciato -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "prodotto intrecciato" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "tilde negata" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "meno tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asintoticamente uguale a" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "non asintoticamente uguale a" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "circa uguale a" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "circa ma non esattamente uguale a" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "né circa uguale né esattamente uguale a" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "quasi uguale a" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "non quasi uguale a" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "quasi uguale o uguale a" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "tripla tilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "tutto uguale a" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "equivalente a" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometricamente equivalente a" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "differenza tra" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "tende al limite" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometricamente uguale a" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "circa uguale a oppure l'immagine di" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "immagine di oppure circa uguale a" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "due punti uguale" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "uguale due punti" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "operatore di composizione dentro uguale a" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "operatore di composizione uguale a" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "corrisponde a" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "stima" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "equiangolare a" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "stella uguale" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta uguale a" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "uguale a per definizione" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "misurato da" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "uguale a con punto di domanda" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "non uguale a" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identico a" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "non identico a" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "strettamente equivalente a" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "minore di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "maggiore di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "minore di sopra uguale a" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "maggiore di sopra uguale a" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "minore di ma non uguale a" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "maggiore di ma non uguale a" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "molto minore di" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "molto maggiore di" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "tra" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "non equivalente a" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "non minore di" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "non maggiore di" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "né minore di né uguale a" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "né maggiore di né uguale a" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "minore di oppure equivalente a" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "maggiore di oppure equivalente a" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "né minore di né equivalente a" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "né maggiore di né equivalente a" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "minore di oppure maggiore di" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "maggiore di oppure minore di" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "né minore di né maggiore di" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "né maggiore di né minore di" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "minore" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "maggiore" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "minore oppure uguale a" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "maggiore oppure uguale a" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "minore oppure equivalente a" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "maggiore oppure equivalente a" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "non minore" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "non maggiore" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "sotto-insieme di" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "sopra-insieme di" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "non un sotto-insieme di" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "non un sopra-insieme di" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "sotto-insieme di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "sopra-insieme di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "né sotto-insieme di né uguale a" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "né sopra-insieme di né uguale a" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "sotto-insieme di con non uguale a" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "sopra-insieme di con non uguale a" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multi-insieme" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "moltiplicazione di multi-insieme" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "unione di multi-insieme" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "sotto-insieme quadrato di" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "sopra-insieme quadrato di" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "sotto-insieme quadrato di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "sopra-insieme quadrato di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "intersezione quadrata" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "unione quadrata" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "più cerchiato" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "meno cerchiato" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "prodotto cerchiato" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "diviso cerchiato" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "operatore punto cerchiato" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operatore di composizione cerchiato" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operatore asterisco cerchiato" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "operatore uguale cerchiato" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "trattino cerchiato" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "più dentro un quadrato" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "meno dentro un quadrato" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "prodotto dentro un quadrato" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operatore punto dentro un quadrato" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "punta destra" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "punta sinistra" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "punta verso il basso" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "punta su" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "asserzione" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modella" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "vero" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "forza" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "tripla barra verticale turnstile destro" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "doppia barra verticale doppio turnstile destro" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "non prova" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "non è vero" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "non forza" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "doppia barra verticale negata doppio turnstile destro" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "minore con relazione" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "maggiore con relazione" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "sotto-gruppo normale di" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "contiene come sotto-gruppo normale" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "sotto-gruppo normale di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "contiene come sotto-gruppo normale di oppure uguale a" - -# primo -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "originale di" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "immagine di" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multi-mappa" - -# https://it.wikipedia.org/wiki/Matrice_hermitiana -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matrice auto-aggiunta coniugata" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalate" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "angolo retto con arco" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triangolo retto" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operatore diamante" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operatore punto" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operatore stella" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "diviso per" - -# (ndt) a quanto pare indica un “join” -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "unione" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "fattore prodotto semi-diretto sinistro normale" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "fattore prodotto semi-diretto destro normale" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "prodotto semi-diretto sinistro" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "prodotto semi-diretto destro" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "simile invertito" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "disgiunzione logica curvata" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "congiunzione logica curvata" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "sotto-insieme doppio" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "sopra-insieme doppio" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "intersezione doppia" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "unione doppia" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "forcone impossibile" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "uguale e parallelo a" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "minore di con punto" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "maggiore di con punto" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "molto minore di" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "molto maggiore di" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "minore di o uguale a oppure maggiore di" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "maggiore di o uguale a oppure minore di" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "uguale a oppure minore di" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "uguale a oppure maggiore di" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "uguale a oppure minore" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "uguale a oppure maggiore" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "non minore oppure uguale" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "non maggiore oppure uguale" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "non sotto-insieme quadrato di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "non sopra-insieme quadrato di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "sotto-insieme quadrato di oppure non uguale a" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "sopra-insieme quadrato di oppure non uguale a" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "minore di ma non equivalente a" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "maggiore di ma non equivalente a" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "minore ma non equivalente a" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "maggiore ma non equivalente a" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "non sotto-gruppo normale di" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "non contiene come sotto-gruppo normale" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "non sotto-gruppo normale di oppure uguale a" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "non contiene come sotto-gruppo normale oppure uguale" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "ellissi verticale" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "ellissi orizzontale a mezza via" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "ellissi diagonale su destra" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "ellisse diagonale giù destra" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "appartiene a con lungo segno orizzontale" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "appartiene a con barra verticale al termine del segno orizzontale" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"appartiene a piccolo con barra verticale al termine del segno orizzontale" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "appartiene a con punto sovrastante" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "appartiene a con barra sovrastante" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "appartiene a piccolo con barra sovrastante" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "appartiene a con barra sottostante" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "appartiene a con due segni orizzontali" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "contiene con lungo segno orizzontale" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "contiene con barra verticale al termine del segno orizzontale" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "contiene piccolo con barra verticale al termine del segno orizzontale" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "contiene con barra sovrastante" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "contiene piccolo con barra sovrastante" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "appartiene in notazione Z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "parte intera superiore sinistra" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "parte intera superiore destra" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "parte intera sinistra" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "parte intera destra" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "parentesi graffa superiore" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "parentesi graffa inferiore" - -# visto che le usiamo nella UI e viene letto, -# metto virgolette invece di caporale, visto -# che la cosa è nota solo a gente di un certo livello -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "parentesi angolata sinistra" - -# cfr altro commento per caporali -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "parentesi angolata destra" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "punto cerchiato" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "unione con punto" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "unione con più" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "intersezione quadrata" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "unione quadrata" - -# RESEARCH -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "quadrato nero" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "quadrato bianco" - -# RESEARCH -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "rombo nero" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "cerchio bianco" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "cerchio nero" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bullet bianco" - -# RESEARCH -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "piccolo quadrato medio nero" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s con sottolineatura" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s con barra obliqua" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s con linea verticale" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "applicazione" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "vuota" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "grassetto" - -# per evitare confusione con quelli del browser -# si è tradotto "contrassegno" quelli specifici di Cthulhu -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "contrassegno inserito" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "contrassegni salvati" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "impossibile salvare i contrassegni" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nessun punto di riferimento trovato." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Nessun punto di riferimento trovato." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Modalità bypass abilitata." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Impossibile ottenere il display della calcolatrice" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "icona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Stile di capitalizzazione impostato a \"icona\"." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "nessuno" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Stile di capitalizzazione impostato a \"nessuno\"." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "ortografia" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Stile di capitalizzazione impostato a \"ortografia\"." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "L'applicazione sta controllando il cursore d'inserimento." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu sta controllando il cursore." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cella %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s selezionata" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "selezionate da %s a %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "non selezionate da %s a %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s non selezionata" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Previene l'uso dell'opzione" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Forza l'uso dell'opzione" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPZIONE" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Argomenti opzionali" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Uso: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "I seguenti elementi non sono validi: " - -# GNOME-2-24 -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Stampa le applicazioni note in esecuzione" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Carica profilo" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Il profilo non può essere caricato: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Impossibile avviare Cthulhu perché non riesce a connettersi al " -"desktop.Impossibile avviare il lettore di schermo perché non è possibile " -"stabilire un collegamento col desktop." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Impossibile attivare il gestore delle impostazioni. Uscita." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Un altro processo del lettore di schermo è già in esecuzione in questa " -"sessione.\n" -"Eseguire «cthulhu --replace» per sostituirlo con uno nuovo." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Usa una directory alternativa per le preferenze utente" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -# GNOME-2-24 -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versione di questa applicazione" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" -"Sostituisci un'istanza di Cthulhu attualmente in esecuzioneSostituisce il " -"processo del lettore di schermo attualmente in esecuzione" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Mostra questo messaggio d'aiuto ed esce" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Invia l'output di debug a debug-AAAA-MM-GG-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Invia l'output di debug al file specificato" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FILE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Imposta le preferenze utente (versione testo)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Imposta le preferenze utente (versione grafica)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Segnalare i bug a https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Selezione tagliata negli appunti." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "tagliata" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Selezione copiata negli appunti." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copiata" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Contenuto incollato dagli appunti." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "incollato" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Non annuncia quando i propri conoscenti stanno digitando." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "annuncia quando i propri conoscenti stanno digitando." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Messaggio dal canale di chat %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nuova scheda chat %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Non leggere il nome del canale di chat." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "leggere il nome del canale di chat." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Non fornisce cronologie di messaggi specifici dei canali di chat." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Fornisce cronologie di messaggi specifici dei canali di chat." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "inizio rimozione" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "termine rimozione" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "inizio inserzione" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "termine inserzione" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "inizio evidenziazione" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "termine evidenziazione" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "termine suggerimento" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Fine del contenitore." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Non in un contenitore." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "selezionati tutti gli elementi" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Il pulsante predefinito è %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Il pulsante predefinito è %s. Disattivato" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Il pulsante predefinito è %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " %s sottoscritti" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " esponente %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Non in una tabella." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "intero documento selezionato" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "intero documento non selezionato" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "documento selezionato dalla posizione del cursore" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "documento deselezionato dalla posizione del cursore" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "documento selezionato fino alla posizione del cursore" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "documento deselezionato fino alla posizione del cursore" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Intestazione di colonna dinamica impostata per la riga %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Intestazione di colonna dinamica pulita." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Intestazione di riga dinamica impostata per la colonna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Impostazione di riga dinamica pulita." - -# riferita a cella di foglio di calcolo -Luca -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "vuota" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobyte" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabyte" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Nessun file trovato." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Contenuto accodato negli appunti." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Contenuto copiato negli appunti." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Revisione piatta non utilizzata." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Ingresso nella revisione piatta." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Uscito dalla revisione piatta." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Sposta la revisione piatta alla parola sopra l'attuale parola" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Revisione piatta senza restrizioni" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "contiene una formula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "apre una finestra di dialogo" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "apre una griglia" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "apre un elenco" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "apre un menù" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "apre un albero" - -# lasciare image map??!!?? -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "collegamento mappa immagine" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Il tasto inserito è già associato a %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tasto catturato: %s. Premere invio per confermare." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Il nuovo tasto è: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Associazione di tasti eliminata. Premere invio per confermare." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "L'associazione di tasti è stata rimossa." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "inserire il nuovo tasto" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tasto" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Eco impostato a tasto." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nessuno" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Eco impostato a nessuno." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tasto e parola" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Eco impostato a tasto e parola." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "sentenza" - -# controllare acceleratore -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Eco impostato a frase." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "parola" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Eco impostato a parola." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "parola e sentenza" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Eco impostato a parola e frase." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Racchiuso da: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "un simbolo attuario" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "un riquadro" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "un cerchio" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "un simbolo di divisione lunga" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "un radicale" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "un riquadro arrotondato" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "un tratto orizzontale" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "un tratto verticale" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "un tratto diagonale verso l'alto" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "un tratto diagonale verso il basso" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "una freccia in su verso destra" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "una linea in basso" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "una linea sulla sinistra" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "una linea sulla destra" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "una linea in alto" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "un fasore" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "un simbolo fattoriale arabo" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "e" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "inizio frazione" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "frazione senza barra, inizio" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "su" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "termine frazione" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "radice quadrata di" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "radice cubica di" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "radice di" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "inizio radice" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "termine radice" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "apice" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "pedice" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pre-apice" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pre-pedice" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "sotto-scritto" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "sovra-scritto" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "termine tabella" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "termine tabella annidata" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessibile" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Disabilitata" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Lettura rientri e allineamento disabilitata." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Abilitata" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Lettura rientri e allineamento abilitata." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Modalità apprendimento. Premere ESC per uscire." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Ingresso nella modalità apprendimento. Premere un tasto qualsiasi per " -"ascoltare la sua funzione. Per la documentazione di Lettore schermo, premere " -"F1. Per l'elenco delle scorciatoie predefinite di Lettore schermo, premere " -"F2. Per l'elenco delle scorciatoie associate all'applicazione corrente, " -"premere F3. Per uscire dalla modalità apprendimento, premere ESC." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "usciti dal blocco di citazione." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "usciti dai dettagli." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "usciti dal feed." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "usciti dal'immagine." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "usciti dal modulo." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "usciti dal banner." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "usciti dal contenuto complementare." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "usciti dalle informazioni." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "usciti dal contenuto principale." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "usciti dalla navigazione." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "usciti dalla regione." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "usciti dalla ricerca." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "usciti dall'elenco." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "usciti dal pannello." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "usciti dalla tabella." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "usciti dal suggerimento." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "usciti dall'astratto." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "usciti dai riconoscimenti." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "usciti dalla postfazione." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "usciti dall'appendice." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "usciti dalla bibliografia." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "usciti dal capitolo." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "usciti dal colofóne." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "usciti dalla conclusione." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "usciti dal riconoscimento." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "usciti dai riconoscimenti." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "usciti dalla dedica." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "usciti dalle note finali." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "usciti dall'inscrizione." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "usciti dall'epilogo." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "usciti dall'errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "usciti dall'esempio." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "usciti dalla prefazione." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "usciti dal glossario." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "usciti dall'indice." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "usciti dall'introduzione." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "usciti dall'elenco pagina." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "usciti dalla parte." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "usciti dalla prefazione." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "usciti dal prologo." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "usciti dall'inserto." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "usciti dal botta e risposta." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "usciti dal suggerimento." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "usciti dal sommario." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "riga selezionata verso il basso dalla posizione del cursore" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "riga selezionata verso l'alto dalla posizione del cursore" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "riga deselezionata verso il basso dalla posizione del cursore" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "riga deselezionata verso l'alto dalla posizione del cursore" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Uscito dalla modalità apprendimento." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" -"riga selezionata dall'inizio fino alla posizione precedente del cursore" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "riga selezionata fino alla fine dalla posizione precedente del cursore" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "collegamento" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "stessa pagina" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "stesso sito" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "differente sito" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "collegamento %(uri)s a %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "collegamento %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "collegamento %s visitato" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Premere Freccia su e Freccia giù per spostarsi nell'elenco. Premere ESC per " -"uscire." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Impostate tutte le regioni attive a disattivate" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "ripristinati i livelli di cortesia delle regioni attive" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "livello di cortesia %s" - -# assertive speech --> discorso concreto -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "impostazione della regione attiva a concreta" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "impostazione della regione attiva a disattivata" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "impostazione della regione attiva a cortese" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "impostazione della regione attiva a scortese" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Monitoraggio regioni attive disattivo" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Monitoraggio regioni attive attivo" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nessun messaggio attivo salvato" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Il supporto alle regioni attive è disattivato" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Non trovata" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Impossibile trovare la posizione corrente." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "non attivo" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "attivo" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "scritta male" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Parola scritta male: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Il contesto è %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Modalità navigazione" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Modalità focus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Per abilitare la modalità focus premere %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Modalità focus adesiva." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Modalità navigazione adesiva." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Modalità disposizione." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Modalità oggetto." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Nessun altro oggetto esteso." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Oggetto mouse over non trovato." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Modalità revisione mouse disabilitata." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Modalità revisione mouse abilitata." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Errore: impossibile creare l'elenco di oggetti." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Nessun figlio." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Nessun successivo." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d percento." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Va alla parola precedente" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Navigazione semplificata abilitata." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Navigazione semplificata disabilitata." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Livello di annidamento %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "È stato aggiunto un nuovo elemento" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Nessuna azione trovata su: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Nessun focus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nessuna applicazione ha il focus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Nessun altro blocco di citazione." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Nessun altro pulsante." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Nessuna altra casella di spunta." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Nessun altro oggetto esteso." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Nessun altro elemento con clic." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Nessuna altra casella combinata." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Nessuna altra casella di testo." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Nessun altro campo di modulo." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Nessuna altra intestazione." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Nessuna altra intestazione di livello %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Nessuna altra tabella." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Nessuna altra immagine." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nessun punto di riferimento trovato." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Nessun altro collegamento." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Nessun altro elenco." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Nessuna altra voce di elenco." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Nessuna altra regione attiva." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Nessun altro paragrafo." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Nessun altro pulsante radio." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Nessun altro separatore." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Nessuna altra tabella." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Nessun altro collegamento non visitato." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Nessun altro collegamento visitato." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Nessun testo selezionato." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Non su un collegamento." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notifica" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "In fondo" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "In cima" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Nessun messaggio di notifica" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "cifre" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Legge i numeri come cifre." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "parole" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Legge i numeri come parole." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "non attivo" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "attivo" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Caricamento. Attendere." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Caricamento completato." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Caricamento di %s completato." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "La pagina ha %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "pagina selezionata dalla posizione del cursore" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "pagina selezionata fino alla posizione del cursore" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "pagina deselezionata dalla posizione del cursore" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "pagina deselezionata fino alla posizione del cursore" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "paragrafo selezionato verso il basso dalla posizione del cursore" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragrafo selezionato verso l'alto dalla posizione del cursore" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "paragrafo deselezionato verso il basso dalla posizione del cursore" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragrafo deselezionato verso l'alto dalla posizione del cursore" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Risulta già aperta una istanza del dialogo di preferenze di Cthulhu.\n" -"Chiudere quella esistente prima di aprirne una nuova." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapositiva %(position)d di %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profilo impostato a %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nessun profilo trovato." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra di avanzamento %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Tutti" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Livello di punteggiatura impostato a \"tutti\"." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Parecchi" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Livello di punteggiatura impostato a \"parecchi\"." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nessuno" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Livello di punteggiatura impostato a \"nessuno\"." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Qualcuno" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Livello di punteggiatura impostato a \"qualcuno\"." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Ricerca in corso." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Ricerca completata." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Impostazioni di Cthulhu ricaricate." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Il testo selezionato è: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Selezione eliminata." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Selezione ripristinata." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Testo non selezionato." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Dimensione: %d, %d. Posizione: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Larghezza: %d. Altezza: %d. %d da sinistra, %d dall'alto." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Sintesi vocale disabilitata." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Sintesi vocale abilitata." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "più veloce." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "più lento." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "più alto." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "più basso." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "più alto." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "più debole." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Velocità %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Altezza %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volume %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Modulo speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Voce speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nessun modulo Speech-dispatcher disponibile" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nessuna voce Speech-dispatcher disponibile" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Impostazioni voce salvate" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Impossibile salvare le impostazioni voce" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Livello verbosità: conciso" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Livello verbosità: prolisso" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " puntini di sospensione" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu ti dà il benvenuto." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu si nasconde sotto le onde." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Modalità sospensione abilitata per %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Modalità di sospensione disattivata per %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "La sintesi vocale non è disponibile." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Non trovata" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Barra di stato non trovata" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "stringa non trovata" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Tasti di navigazione per struttura non attivi." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Tasti di navigazione per struttura attivi." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Non trovato" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Riga %(row)d, colonna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Fine della tabella" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Leggi cella" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Leggi riga" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Non uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Non in una tabella." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Colonne riordinate" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Righe riordinate" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "colonna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "colonna %(index)d di %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Fine della colonna." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Inizio della colonna." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Selezionata colonna %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Selezionate colonne da %s a %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Colonne da %s a %s non selezionate" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Colonna %s non selezionata" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "riga %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "riga %(index)d di %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Inizio della riga." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Fine della riga." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Eliminata una riga." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Eliminata l'ultima riga." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Inserita una riga." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Inserita una riga alla fine della tabella." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Selezionata riga %s" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Selezionate righe da %s a %s" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Righe da %s a %s non selezionate" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Riga %s non selezionata" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "selezionato" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "non selezionato" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H ore, %M minuti e %S secondi" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H ore e %M minuti" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "annulla" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "ripeti" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versione %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "spazio bianco" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Ricominciato dal fondo." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Ricominciato dall'inizio." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elementi" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "La cella occupa %d riga" -msgstr[1] "La cella occupa %d righe" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d colonna" -msgstr[1] " %d colonne" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "La cella occupa %d colonna" -msgstr[1] "La cella occupa %d colonne" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d carattere in eccesso" -msgstr[1] "%d caratteri in eccesso" - -# GNOME-2-24 -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialogo)" -msgstr[1] "(%d dialoghi)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d dialogo senza focus" -msgstr[1] "%d dialoghi senza focus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d file trovato" -msgstr[1] "%d file trovati" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d modulo" -msgstr[1] "%d moduli" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d intestazione" -msgstr[1] "%d intestazioni" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elemento" -msgstr[1] "%d elementi" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d punto di riferimento" -msgstr[1] "%d punti di riferimento" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d elemento trovato" -msgstr[1] "%d elementi trovati" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Usciti da %d blocco di citazione." -msgstr[1] "Usciti da %d blocchi di citazione." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Usciti da %d elenco." -msgstr[1] "Usciti da %d elenchi." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Elenco di dimensioni sconosciute" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Elenco con %d voce" -msgstr[1] "Elenco con %d voci" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Feed di dimensioni sconosciute" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Feed con %d articolo" -msgstr[1] "Feed con %d articoli" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Elenco descrizioni con %d termine" -msgstr[1] "Elenco descrizioni con %d termini" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d valore" -msgstr[1] "%d valori" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabella matematica con %d riga" -msgstr[1] "tabella matematica con %d righe" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d colonna" -msgstr[1] "%d colonne" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tabella matematica annidata con %d riga" -msgstr[1] "tabella matematica annidata con %d righe" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d messaggio.\n" -msgstr[1] "%d messaggi.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d percento." -msgstr[1] "%d percento." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "documento letto all'%d per cento" -msgstr[1] "documento letto al %d per cento" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixel" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d carattere %(repeatChar)s" -msgstr[1] "%(count)d caratteri %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d elemento su %(total)d selezionato" -msgstr[1] "%(index)d elementi su %(total)d selezionati" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Trovata %d scorciatoia predefinita di Lettore schermo." -msgstr[1] "Trovate %d scorciatoie predefinite di Lettore schermo." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Trovata %(count)d scorciatoia di Lettore schermo per %(application)s." -msgstr[1] "" -"Trovate %(count)d scorciatoie di Lettore schermo per %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d spazio" -msgstr[1] "%d spazi" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulazione" -msgstr[1] "%d tabulazioni" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabella" -msgstr[1] "%d tabelle" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabella di dimensioni sconosciute" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabella con %d colonna, conteggio delle righe sconosciuto" -msgstr[1] "tabella con %d colonne, conteggio delle righe sconosciuto" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabella con %d riga, conteggio delle colonne sconosciuto" -msgstr[1] "tabella con %d righe, conteggio delle colonne sconosciute" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabella con %d riga" -msgstr[1] "tabella con %d righe" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d secondo fa" -msgstr[1] "%d secondi fa" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minuto fa" -msgstr[1] "%d minuti fa" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d ora fa" -msgstr[1] "%d ore fa" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d giorno fa" -msgstr[1] "%d giorni fa" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d collegamento non visitato" -msgstr[1] "%d collegamenti non visitati" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d collegamento visitato" -msgstr[1] "%d collegamenti visitati" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "commuta" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "su %(index)d di %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d di %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "oggetto %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "LIVELLO %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "livello albero %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "LIVELLO ALBERO %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "dettagli per %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "ha dettagli in %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "suggerimento" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "casella combinata modificabile" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "contenuto modificabile" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "feed" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "immagine" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "astratto" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "riconoscimenti" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "postfazione" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "appendice" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "voce bibliografica" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografia" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "capitolo" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colofóne" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conclusione" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "copertina" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "riconoscimento" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "riconoscimenti" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedica" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "nota finale" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "note finali" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "inscrizione" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilogo" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "esempio" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "prefazione" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glossario" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "indice" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introduzione" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "interruzione pagina" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "elenco pagina" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "parte" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "prefazione" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prologo" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "inserto" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Botta e risposta" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "sottotitolo" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "sommario" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s livello %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "barra di scorrimento orizzontale" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "barra di scorrimento verticale" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "controllo scorrevole orizzontale" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "controllo scorrevole verticale" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "divisore orizzontale" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "divisore verticale" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "selettore" - -# se non ho letto male il codice, è il nome -# comune per una GtkIconView -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Pannello icone" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "banner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "contenuto complementare" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informazioni" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "contenuto principale" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigazione" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "regione" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "ricerca" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "collegamento visitato" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "pulsante menù" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "ordine ascendente" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "ordine discendente" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "ordinata" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "elemento con clic" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "contratto" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "espanso" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "ha descrizione lunga" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "orizzontale" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "verticale" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "spuntata" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "non spuntata" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "attivo" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "non attivo" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "parzialmente spuntata" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "premuto" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "non premuto" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "non selezionato" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "selezionato" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "non selezionato" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "non selezionata" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visitato" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "non visitato" - -# parafrasi, in originale riferito allo stato dei widget -Luca -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "non disponibile" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "sola lettura" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "sololet" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "richiesto" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "selezione multipla" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "voce non valida" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "non valido" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ortografia non valida" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ortografia" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "grammatica non valida" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "grammatica" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Trova" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Finestra ricerca di Lettore schermo" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Chiudi" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "Tr_ova" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "Ric_erca:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Ricerca:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Inizio della _finestra" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Inizio della finestra" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Iniziare da:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Alla fine _ricomincia" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Cerca all'in_dietro" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Direzione ricerca:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Maiuscole/Minuscole" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Solo parole _intere" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opzioni:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Predefinite" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Lettere maiuscole" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Collegamento ipertestuale" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "System" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Applicazione" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Finestra" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferenze di Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "A_iuto" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "A_pplica" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Disposizione tastiera" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Profilo attivo:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profilo di avvio:" - -# FIXME: acceleratore non provato -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "Cari_ca" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Sa_lva come" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Rimuovi" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profili" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "P_resentare i suggerimenti" - -# controllare acceleratore -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Leggere l'oggetto sotto il mo_use" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Mouse" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Formato dell'_ora:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formato d_ella data:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Ora e data" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Le_ggi aggiornamenti" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Aggiornamenti in _braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frequenza (secondi):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Si applica a:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Suono per gli aggiornamenti" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Aggiornamenti barre di avanzamento" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Abilitare indietro e avanti _veloce in Pronuncia tutto" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Abilitare navigazione _strutturale in Pronuncia tutto" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Pro_nuncia tutto per:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Annunciare i _blocchi di citazione con «Pronuncia tutto»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Annunciare gli _elenchi con «Pronuncia tutto»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Annunciare le _tabelle con «Pronuncia tutto»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Annunciare i _pannelli con «Pronuncia tutto»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Annunciare i _moduli con «Pronuncia tutto»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Annunciare i punti di _riferimento con «Pronuncia tutto»" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Pronuncia tutto" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Presentazione elemento:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Generali" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lume:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Tonalità:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Velocità:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persona:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Lingua:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Sinteti_zzatore di sintesi vocale:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Sistema di sintesi vocale:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipo di _voce:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Stile di capitali_zzazione:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Impostazioni tipo di voce" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Leggere le stringhe tipo _wiki come parole" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Leggere i numeri come ci_fre" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Impostazioni globali voce" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voce" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Abilitar_e la sintesi vocale" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "P_rolisso" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Prolissità" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Tutti" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Livello punteggiatura" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Legge solo il testo mostrato" - -# manca l'acceleratore :-( -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Leggere le righe in bianco" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Le_ggere i rientri e la giustificazione" - -# non sono sicuro, sarebbe da provare in pratica -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Leggere gli acceleratori degli _oggetti" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Leggere la p_osizione del figlio" - -# -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Leggere i messaggi di suggerimenti d'uso" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Messaggi di sistema dettagliati" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Leggere i colori come _nomi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Annunciare i _blocchi di citazione durante la navigazione" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Annunciare gli _elenchi durante la navigazione" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Annunciare le _tabelle durante la navigazione" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Leggere l'indicatore di parole _errate" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Annunciare i _pannelli durante la navigazione" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Annunciare i punti di _riferimento durante la navigazione" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Annunciare i _moduli durante la navigazione" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Leggere la _descrizione" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Leggere la _riga intera nei fogli di calcolo" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Leggere la riga intera delle _tabelle nei documenti" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Leggere la ri_ga intera nelle tabelle dell'interfaccia grafica" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Contresto parlato" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Sintesi vocale" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Abilitare il _supporto Braille" - -# Ad esempio dial invece di dialogo e così via. -# Ciò significa anche che i nomi abbreviati definiti altrove debbono -# essere univoci :-| -Luca -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Nomi di ruolo abbre_viati" - -# controllare acceleratore -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Disabilitare i simboli di _fine riga" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tavola delle abbreviazioni:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Abilitare il braille co_ntratto" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Abilitare a capo auto_matico" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Impostazioni monitor" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Nessuno" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicatore di selezione" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicatore di collegamento ipertestuale" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Abilitare messaggi _transitori" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Durata (secondi):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "I messaggi sono _permanenti" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "I messaggi sono _dettagliati" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Impostazioni messaggi transitori" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Abilitare l'eco sui _tasti" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Abilitare i tasti _alfabetici" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Abilitare i tasti _numerici" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Abilitare i tasti di _punteggiatura" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Abilitare lo _spazio" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Abilitare i tasti _modificatori" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Abilitare i tasti _funzione" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Abilitare i tasti di a_zione" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Abilitare i tasti di na_vigazione" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Abilitare l'_eco sulla parola" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Abilitare l'_eco sulla frase" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Eco" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Tasti _modificatori di Lettore schermo:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Associazioni di tasti" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Dizionari di pronuncia" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nuova voce" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "Eli_mina" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronuncia" - -# pulsante in scheda attibuti di testo -# non è detto sia visibile... -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Leggi tutto" - -# pulsante in scheda attributi di testo -# non è detto sia visibile. -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Non leggere" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "A_zzera" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Attributi di testo" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Muovi in _fondo" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Muovi _giù di uno" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Muovi _su di uno" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Muovi in _alto" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Regola attributo selezionato" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicatore braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Attributi di testo" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Abilita assistente IA" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Fornitore:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Locale - Gratuito)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "File chiave _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Percorso del file chiave API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Ottieni chiave API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Apri il browser per ottenere la chiave API Claude e salva automaticamente" -"Apri il browser per ottenere la chiave API di Claude e salvarla " -"automaticamente" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Richiedi conferma prima delle azioni IA" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Modello Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nome del modello per Ollama (es. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Endpoint Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL endpoint API Ollama (es. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Qualità screenshot:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Basso" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Medio" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Alto" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Assistente IA" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Codice _lingua:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Fattore di _scala:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Immagine in scala di _grigi" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Inverti immagine" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Immagine in _bianco e nero" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Soglia bianco/nero:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analizza colori" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Copia risultati negli _appunti" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : Ancona, b : Bari, c : Catania, d : Domodossola, e : Empoli, f : Firenze, " -"g : Genova, h : hotel, i : Imola, j : jolly, k : kursaal, l : Livorno, m : " -"Milano, n : Napoli, o : Otranto, p : Palermo, q : Quarto, r : Roma, s : " -"Savona, t : Torino, u : Udine, v : Venezia, w : Washington, x : xilofono, " -"y : yogurt: z : Zara" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "colore di sfondo" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "altezza piena sfondo" - -# non sono convinto, ma... -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "retinatura sfondo" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direzione" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "modificabile" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nome della famiglia" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "colore del primo piano" - -# non sono convinto, ma... -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "retinatura primo piano" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "effetto tipo di carattere" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "rientro" - -# errore in GTK+ è usato nei dialoghi -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "sbaglio" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisibile" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "allineamento" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "lingua" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "margine sinistro" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "altezza riga" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "stile del paragrafo" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixel sopra la riga" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixel sotto la riga" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixel tra a capo" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "margine destro" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "elevazione" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "scala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "dimensione" - -# non sono sicuro sia la traduzione corretta in tipografia -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "estensione" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "barrato" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stile" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decorazione testo" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotazione testo" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "ombra testo" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "sottolineatura" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variante" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "allineamento verticale" - -# http://en.it.open-tran.eu/suggest/weight -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "spessore" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "modalità a capo" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "modalità di scrittura" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "vero" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falso" - -# 4 a 1 vince il femminile -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "nessuna" - -# come da OO.o writer -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "incavato" - -# come da OO.o writer -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "in rilievo" - -# come da traduzione OO.o -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "contorno" - -# Nella UI c'è solo sottolineato e barrato -# metto sovralineato per la proprietà transitiva delle traduzioni :) -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "sovralineato" - -# Milo -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "linea attraverso" - -# come da traduzione oo.o -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "lampeggiante" - -# La proprietà "text-shadow" prevede due valori: -# * none -# * black -# Nella UI appare come ombreggiato, uso tale termine -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "ombreggiato" - -# da controllare su oo.o -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "singola" - -# da controllare su oo.o -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "doppia" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "bassa" - -# da controllare su oo.o -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "carattere" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "parola" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "carattere parola" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "sin-des" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "des-sin" - -# allineamento -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "a destra" - -# allineamento -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "a sinistra" - -# allineamento -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centrato" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "nessun allineamento" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "giustificato" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensato" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensato" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensato" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensato" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normale" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi espanso" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "espanso" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra espanso" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra espanso" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "maiuscoletto" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "obliquo" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "corsivo" - -# come da traduzione oo.o -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Standard" - -# come da traduzione oo.o -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Corpo testo" - -# come da traduzione oo.o -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Intestazione" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "linea di base" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sotto" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "sopra" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "alto" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "testo-alto" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "medio" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "basso" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "testo-basso" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "ereditato" - -# uso le iniziali di sinistra, destra, alto, basso -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "sd-ab" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "ds-ab" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "ab-ds" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "ab-sb" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "ba-ds" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "ba-sd" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "sd" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "ds" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "ab" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "pieno" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "ortografia" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Premere spazio per attivare/disattivare." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Premere spazio per espandere e usare su e giù per selezionare una voce." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Premere Alt+F6 per dare il focus alle finestre figlie." - -# http://en.wikipedia.org/wiki/Typeahead -# http://www.mozilla.org/access/type-ahead/ -# (thanks to Milo Casagrande) -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Per spostarsi su una voce, usare i tasti freccia oppure la ricerca " -"incrementale." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Per ottenere i menù di sistema premere i tasti alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Usare su e giù per selezionare una voce." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Per ridurre, premere maiusc più sinistra." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Per espandere, premere maiusc più destra." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Per attivare premere Invio." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Digitare del testo." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Usare destra e sinistra per visualizzare le altre schede." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Per attivare premere spazio." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Usare freccia su o giù per selezionare il valore oppure digicare il valore " -"numerico desiderato." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Usare i tasti freccia per cambiare." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Per spostarsi, premere le frecce sinistra o destra. Per muoversi tra le " -"voci, premere le frecce su o giù." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Per entrare in un sottomenù, premere la freccia destra." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Per decrementare premere la freccia sinistra, per incrementare premere la " -"freccia destra. Per andare al minimo premere home, per il massimo premere " -"fine." diff --git a/po/ja.po b/po/ja.po deleted file mode 100644 index 537b355..0000000 --- a/po/ja.po +++ /dev/null @@ -1,9827 +0,0 @@ -# cthulhu ja.po. -# Copyright (C) 2006-2011 THE Cthulhu'S COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Satoru SATOH , 2006. -# Takeshi AIHANA , 2006-2009. -# Jiro MATSUZAWA , 2010, 2011. -# Takayuki KUSANO , 2010. -# Takayoshi OKANO , 2011. -# -# 翻訳する際の諸注意: -# 1. 原則的に UI の翻訳のみ -# 2. 読み上げの対象となる文字列は訳さない (日本語の音声ファイルが提供されていない間) -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu gnome-3-0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2012-01-01 23:26+0900\n" -"Last-Translator: Jiro Matsuzawa \n" -"Language-Team: Japanese \n" -"Language: ja\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu スクリーンリーダー" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "スクリーン;リーダー;アクセシビリティ;音声;点字;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "チェコ語 (1級)" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "スペイン語 (1級)" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "カナダ系フランス語 (2級)" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "フランス系フランス語 (2級)" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "ラトビア語 (1級)" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "オランダ系オランダ語 (1級)" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "ノルウェー語 (0級)" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "ノルウェー語 (1級)" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "ノルウェー語 (2級)" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "ノルウェー語 (3級)" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "ポーランド語 (1級)" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "ポルトガル語 (1級)" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "スウェーデン語 (1級)" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "アラビア語 (1級)" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "ウェールズ語 (1級)" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "ウェールズ語 (2級)" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "ドイツ語 (0級)" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "ドイツ語 (1級)" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "ドイツ語 (2級)" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "イギリス系英語 (2級)" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "イギリス系英語 (1級)" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "アメリカ系英語 (1級)" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "アメリカ系英語 (2級)" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "カナダ系フランス語 (1級)" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "フランス系フランス語 (1級)" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "ギリシア語 (1級)" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "ヒンディー語 (1級)" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -#, fuzzy -msgid "Hungarian Grade 1" -msgstr "ラトビア語 (1級)" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "ドイツ語 (2級)" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "イタリア語 (1級)" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "ベルギー系オランダ語 (1級)" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "space" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "newline" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "exclaim" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "quote" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "number" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "and" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrophe" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "left paren" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "right paren" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "star" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "comma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "dash" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "dot" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slash" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "colon" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semicolon" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "less" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "equals" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "greater" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "question" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "left bracket" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "backslash" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "right bracket" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "caret" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "underline" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "left brace" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertical bar" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "right brace" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "no break space" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "inverted exclamation point" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cents" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pounds" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "currency sign" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "broken bar" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "section" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "left double angle bracket" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logical not" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "soft hyphen" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registered" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "degrees" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus or minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superscript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superscript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acute" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "paragraph marker" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "middle dot" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superscript 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "right double angle bracket" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "one fourth" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "one half" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "three fourths" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "inverted question mark" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "times" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "divided by" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "left single quote" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "right single quote" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "single low quote" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "left double quote" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "right double quote" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "double low quote" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "dagger" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "double dagger" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "bullet" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "triangular bullet" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prime" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "double prime" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "double prime" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "hyphen bullet" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "trademark" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "check mark" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "heavy check mark" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-shaped bullet" - -#: src/cthulhu/chnames.py:672 -#, fuzzy -msgid "superscript 0" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:676 -#, fuzzy -msgid "superscript 4" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:680 -#, fuzzy -msgid "superscript 5" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:684 -#, fuzzy -msgid "superscript 6" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:688 -#, fuzzy -msgid "superscript 7" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:692 -#, fuzzy -msgid "superscript 8" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:696 -#, fuzzy -msgid "superscript 9" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:700 -#, fuzzy -msgid "superscript plus" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:704 -#, fuzzy -msgid "superscript minus" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:708 -#, fuzzy -msgid "superscript equals" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:720 -#, fuzzy -msgid "superscript n" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:724 -#, fuzzy -msgid "subscript 0" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:728 -#, fuzzy -msgid "subscript 1" -msgstr "superscript 1" - -#: src/cthulhu/chnames.py:732 -#, fuzzy -msgid "subscript 2" -msgstr "superscript 2" - -#: src/cthulhu/chnames.py:736 -#, fuzzy -msgid "subscript 3" -msgstr "superscript 3" - -#: src/cthulhu/chnames.py:740 -#, fuzzy -msgid "subscript 4" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:744 -#, fuzzy -msgid "subscript 5" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:748 -#, fuzzy -msgid "subscript 6" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:752 -#, fuzzy -msgid "subscript 7" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:756 -#, fuzzy -msgid "subscript 8" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:760 -#, fuzzy -msgid "subscript 9" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:764 -#, fuzzy -msgid "subscript plus" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:772 -#, fuzzy -msgid "subscript equals" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "left paren" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "right paren" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "black square" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "black diamond" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "Goes to next character." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "ポインターを現在選択されている項目へ移動する" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "読み上げる単語の上で左クリックする" - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "読み上げる単語の上で右クリックする" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "文書全体を読み上げる" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "現在のフラット・レビューにある行を読み上げる" - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "操作している場所を読み上げる (簡易)" - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "操作している場所を読み上げる (詳細)" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "現在のフラット・レビューにある行を読み上げる" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "空行を読み上げる" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "デフォルトボタンを提示" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "ステータスバーを読み上げ" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "タイトルバーを読み上げ" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Cthulhu の検索ダイアログを開く" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "アクションリストを表示" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "文字列が次に現れる場所を検索する" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "文字列が前に現れる場所を検索する" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "フラット・レビューのモードを ON/OFF する" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "フラットレビューを現在のオブジェクトに制限を切り替え" - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "ホーム・ポジションにフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "終端にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "前の行の先頭にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "現在のフラット・レビューにある行を読み上げる" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "現在のフラット・レビューにある行のつづりを読み上げる" - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "現在のフラット・レビューにある行のつづりを発音どおり読み上げる" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "次の行の先頭にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "前のアイテムまたは単語にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "現在のフラット・レビューにあるアイテムまたは単語を読み上げる" - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "現在のフラット・レビューにあるアイテムまたは単語のつづりを読み上げる" - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"現在のフラット・レビューにあるアイテムまたは単語のつづりを発音どおり読み上げ" -"る" - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "次のアイテムまたは単語にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "現在の単語の上にある語句にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "現在のフラット・レビューにあるオブジェクトを読み上げる" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "現在の単語の下にある語句にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "前の文字にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "現在のフラット・レビューにある文字を読み上げる" - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "現在のフラット・レビューにある文字を発音どおり読み上げる" - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "現在のフラット・レビューにある文字のUnicode値を読み上げる" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "次の文字にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "行末にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "左下にフラット・レビューを移動する" - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "現在のフラット・レビューにあるアイテムまたは単語を読み上げる" - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "現在のフラット・レビューにあるアイテムまたは単語を読み上げる" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "フラットレビューの内容を表示" - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "表中のセルだけを読み上げるか行全体を読み上げるかを切り替える" - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "現在の文字列に付与されている属性を読み上げる" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "点字モニターを左側にずらす" - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "点字モニターを右側にずらす" - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "キーボードのフォーカスを持つオブジェクトを返す" - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "短縮形点字の ON/OFF を切り替える" - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "Cursor Routingキーを処理する" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "選択したテキストの先頭をマークする" - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "選択したテキストの末尾をマークする" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "学習モードに入る (Esc 押下で終了する)" - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "読み上げの速度を下げる" - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "読み上げの速度を上げる" - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "音の高さを下げる" - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "音の高さを上げる" - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "読み上げの速度を上げる" - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "読み上げの速度を下げる" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "前の音声設定を選択" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "次の音声設定を選択" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "現在の音声設定を下げる" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "現在の音声設定を上げる" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "音声設定を保存" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "ミュートの ON/OFF を切り替える" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "スリープモードを切り替え" - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Cthulhu スクリーンリーダーと拡大鏡" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "設定ダイアログを表示する" - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "アプリケーションの設定ダイアログを表示する" - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "字下げと行端揃えを読み上げを切り替える。" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "次の位置を拡大する" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "次の音声合成エンジンに切り替え" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "次の位置を拡大する" - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "次の位置を拡大する" - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "次の位置を拡大する" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "実行時にデバッグ・レベルを調整できるようにする" - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "指定したブックマークと現在位置との関係を取得する" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "前のブックマークがある位置へ移動する" - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "ブックマークへ移動する" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "次のブックマークがある位置へ移動する" - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "ブックマークを追加する" - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "ブックマークを保存する" - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "マウスのレビュー・モードを切り替える" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "現在のアプリに次のコマンドを引き渡す" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "Speak and braille a previous chat room message." - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Toggle whether we announce when our buddies are typing." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Toggle whether we provide chat room specific message histories." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Toggle whether we prefix chat room messages with the name of the chat room." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Line Left" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Line Right" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Line Up" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Line Down" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Freeze" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Top Left" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "下半分" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Cursor Position" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Six Dots" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Cursor Routing" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Cut Begin" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Cut Line" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "拡大レベルを上げる" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "拡大レベルを上げる" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "次の通知メッセージを読み上げ" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Goes to next character." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "Goes to previous character." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "Goes to next word." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "Goes to previous word." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "Goes to next line." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "Goes to previous line." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "Goes to the top of the file." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "Goes to the bottom of the file." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Goes to the beginning of the line." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "Goes to the end of the line." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "Goes to the next object." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "Goes to the previous object." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "Causes the current combo box to be expanded." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "Switches between Gecko native and Cthulhu caret navigation." - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "Advance live region politeness setting." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "Set default live region politeness level to off." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "Review live region announcement." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "Monitor live regions." - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "Moves focus into and away from the current mouse over." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "Set the row to use as dynamic column headers when speaking calc cells." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "Clears the dynamic column headers." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"Set the column to use as dynamic row headers to use when speaking calc cells." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "Clears the dynamic row headers" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Speaks the contents of the input line." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "Toggles structural navigation keys." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "Goes to previous blockquote." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "Goes to next blockquote." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "前のボタンに移動" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "次のボタンに移動" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Display more options" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Goes to previous check box." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Goes to next check box." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "Goes to previous table." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "Goes to next table." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "Goes to previous combo box." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Goes to next combo box." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l container" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l container" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "Goes to previous entry." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "Goes to next entry." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "前のフォームフィールドに移動" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "次のフォームフィールドに移動" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "前の見出しに移動" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "次の見出しに移動" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Goes to previous heading at level %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Goes to next heading at level %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "No more headings at level %d." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "前の内部フレームに移動" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "次の内部フレームに移動" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "内部フレームの一覧を表示" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "Goes to previous line." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "Goes to next line." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "Goes to previous landmark." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "Goes to next landmark." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Goes to previous large object." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Goes to next large object." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "No more large objects." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "前のリンクに移動" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "次のリンクに移動" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Display more options" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "Goes to previous list." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "Goes to next list." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Goes to previous list item." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Goes to next list item." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "Goes to previous live region." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "Goes to next live region." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "Review live region announcement." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "ナビゲーターフォーカスのあるオブジェクトの親に移動します。" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "ナビゲーターフォーカスのあるオブジェクトの最初の子に移動します。" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "ナビゲーターフォーカスのあるオブジェクトの次の兄弟に移動します。" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "ナビゲーターフォーカスのあるオブジェクトの前の兄弟に移動します。" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "ナビゲーターフォーカスのあるオブジェクトをクリック。" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "簡易オブジェクトナビゲーションを切り替え。" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "Goes to previous paragraph." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "Goes to next paragraph." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Goes to previous radio button." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "Goes to next radio button." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "No more radio buttons." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "Goes to previous separator." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "Goes to next separator." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "Goes to previous table." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "Goes to next table." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "Goes down one cell." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "Goes to the first cell in a table." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "Goes to the last cell in a table." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "Goes left one cell." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "Goes right one cell." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "Goes up one cell." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "マウスのレビュー・モードを切り替える" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "キーエコーを有効にする(_K)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "Goes to previous unvisited link." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "Goes to next unvisited link." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "No more unvisited links." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "Goes to previous visited link." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "Goes to next visited link." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "No more visited links." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "青の彩度を増やす" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "black" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "black diamond" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "青の彩度を増やす" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "青の彩度を増やす" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "a grave" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "緑の彩度を増やす" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "緑の彩度を増やす" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "赤の彩度を増やす" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "緑の彩度を増やす" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "青の彩度を増やす" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i grave" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "緑の彩度を減らす" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "無効" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "degrees" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "ヒンディー語 (1級)" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "right brace" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "right control" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "right paren" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "right brace" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "right paren" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "right paren" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "right alt" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "right paren" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "right super" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "right arrow" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "newline" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "画像" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "青の彩度を減らす" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "赤の彩度を増やす" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "緑の彩度を増やす" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "tre" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "青の彩度を増やす" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s screen" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "青の彩度を減らす" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "青の彩度を減らす" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "btn" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "white space" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "white space" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "フルスクリーン" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "7の点(_7)" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "8の点(_8)" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "7と8の点(_D)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "アイコン" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "なし" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "spelling" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Announce when your _buddies are typing" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Provide chat room specific _message histories" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Speak messages from" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "すべてのチャンネル(_N)" - -#: src/cthulhu/guilabels.py:173 -#, fuzzy, python-format -msgid "All channels when an_y %s window is active" -msgstr "All channels when an_y Pidgin window is active" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "A channel only if its _window is active" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "チャット部屋の名前を読み上げる(_S)" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -#, fuzzy -msgid "double click" -msgstr "(ダブル・クリック)" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -#, fuzzy -msgid "triple click" -msgstr "(トリプル・クリック)" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "デフォルトのシンセサイザー" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "実際の文字列" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "置き換える文字列" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "文字毎にキーエコーを返す(_R)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "間隔のない発音区別キーを有効にする(_D)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "現在の位置(_U)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "パターン・マッチする文字列の長さ (最小値):" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "検索オプション" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "検索中に変更された行だけ読み上げる(_Y)" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "検索中にその結果を読み上げる(_F)" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "comma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "キーの割り当て" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "Default" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "writing mode" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "アクション" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "点字のキー割り当て" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "ブックマーク" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "表のナビゲーション" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "割り当てられていないもの" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "Leaving flat review." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "修飾キー付き" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "デスクトップ型(_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notification %s" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "受信" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Notification %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s 用の Cthulhu の設定" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "点字" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "例外" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "読み上げ" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -#, fuzzy -msgid "User Profile Conflict!" -msgstr "点字の表示方法" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "すべて" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "アプリケーション" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "ウィンドウ" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "なし(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "いくつか(_M)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "ほとんど(_O)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "一行" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "文章" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "quote" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "ボタン" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "タイトル" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "チェックボックス" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "combo box" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "superscript a" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "ヘディング" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "内部にあるフレーム" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "画像" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "ラベル" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "trademark" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "リンク" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "リスト" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "リストの項目" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "段落" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "ラジオ・ボタン" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "selected" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "Status" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "テキスト" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "No more blockquotes." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "ボタン" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "チェックボックス" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "combo box" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "ヘディング" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "内部にあるフレーム" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "画像" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "No more headings at level %d." - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "trademark" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "No more large objects." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "リンク" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "リスト" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "リストの項目" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "段落" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "ラジオ・ボタン" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "表" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d unvisited link" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d visited link" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "ページのナビゲーション" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "初めてロードしたらページの読み上げを自動的に開始する(_L)" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "初めてロードしたらページの読み上げを自動的に開始する(_L)" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "文の区切りで読み上げを中断する(_U)" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s デフォルトの音声" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "デフォルト" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "ハイパーリンク" - -#: src/cthulhu/guilabels.py:844 -#, fuzzy -msgctxt "VoiceType" -msgid "System" -msgstr "term" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "大文字" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "読み上げディスパッチャー" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "Speak spread sheet cell coordinates" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "セルのヘッダーを読み上げる(_H)" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "表のナビゲーション" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "空のセルは読み飛ばす(_B)" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "セルを読み上げる(_C)" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "セルの位置を読み上げる(_C)" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "セルの個数を読み上げる(_M)" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "属性の名前" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "Cthulhu のキャレット式ナビゲーションを使用する(_O)" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "Toggles structural navigation keys." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "サウンドテーマ(_T):" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "サウンドテーマ" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "簡潔にする(_F)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Notification %s" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt_R" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "Ctrl" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "left shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "left alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "left control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "right shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "right alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "right control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "left meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "right meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "up" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "left" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "right" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "left super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "right super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "help" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "mode switch" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "stroke" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "bold" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "italic" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Workspace " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "Context is %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "left arrow" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "arrow" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "right arrow" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "arrow" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "right arrow" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "right arrow" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "right arrow" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "left arrow" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "left arrow" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "right arrow" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "left double quote" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "double dagger" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "right double quote" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "double dagger" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "right double quote" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "right-pointing arrow" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "right-pointing arrowhead" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "less" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "greater" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "dot" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "vertical align" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horizontal" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "autocomplete" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "empty" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "有効にする(_D)" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "End of row." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "sub" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "plus or minus" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "separator" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "cube root" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "プロポーショナル" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "infinity" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "right alt" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "single" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "layered pane" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "vertical align" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "divided by" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "セパレーター" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "not equal to" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "direction" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "internal frame" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "プロポーショナル" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "almost equal to" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "almost equal to" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "almost equal to" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "almost equal to" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "almost equal to" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "almost equal to" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "(トリプル・クリック)" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "almost equal to" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "different site" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "not equal to" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "equals" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "equals" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "not equal to" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "not equal to" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "triangular bullet" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "equals" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "not equal to" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "not equal to" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "vertical" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "not equal to" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "not equal to" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "greater" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "not pressed" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "multi-select" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "justification" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "multi-select" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "en dash" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "right meta" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "left tab" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "down" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "section" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ordinal" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "image" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "multi" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "internal frame" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "normal" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "right single quote" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "right brace" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "separator" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "direction" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertical align" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "left paren" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "right paren" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "left alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "right alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "left brace" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "bottom" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "left double angle bracket" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "right double angle bracket" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "middle dot" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "square root" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "black square" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "white square" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "black diamond" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "white circle" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "black circle" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "white bullet" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "black square" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "underline" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "vertical align" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "application" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "blank" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "bold" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "ブックマークを追加しました" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "ブックマーク・オブジェクトを保存しました" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "ブックマーク・オブジェクトを保存できませんでした" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Bypass mode enabled." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Unable to get calculator display" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "icon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "none" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "spelling" - -#: src/cthulhu/messages.py:157 -#, fuzzy -msgid "Capitalization style set to spell." -msgstr "句読点の読み上げ" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "Gecko is controlling the caret." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu is controlling the caret." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cell %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "selected" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "unselected" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "利用しないオプションを指定する" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "利用するオプションを指定する" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "実行中のアプリの一覧を表示する" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "ブックマーク・オブジェクトを保存できませんでした" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "ユーザー設定のフォルダーを指定する" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "実行中のアプリの一覧を表示する" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "現在実行中の Cthulhu インスタンスを置き換え" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "このヘルプを表示する" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "debug-YYYY-MM-DD-HH:MM:SS.outにデバッグ情報を出力する" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "指定したファイルにデバッグ情報を出力する" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "ユーザーの設定を変更する (端末から)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "ユーザーの設定を変更する (端末から)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "バグの報告は https://groups.io/g/stormux まで" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "acute" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "faster." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Do not announce when your buddies are typing." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "announce when your buddies are typing." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Message from chat room %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "New chat tab %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Do not speak chat room name." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "speak chat room name." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Do not provide chat room specific message histories." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Provide chat room specific message histories." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "delete" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "insert" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "question" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "End of table" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "Not in a table." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "not selected" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Default button is %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Default button is %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "Default button is %s" - -#: src/cthulhu/messages.py:518 -#, fuzzy, python-format -msgid " subscript %s" -msgstr "superscript a" - -#: src/cthulhu/messages.py:524 -#, fuzzy, python-format -msgid " superscript %s" -msgstr "superscript a" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "Not in a table." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "entire document selected" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "entire document selected" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "document selected from cursor position" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "document unselected from cursor position" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "document selected to cursor position" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "document unselected to cursor position" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynamic column header set for row %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynamic column header cleared." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynamic row header set for column %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynamic row header cleared." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "empty" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "No files found." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "Entering flat review." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Entering flat review." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Leaving flat review." - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "現在の単語の上にある語句にフラット・レビューを移動する" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "フラットレビュー制限なし" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "has formula" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "dialog" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "popup menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "image map link" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "押下したキーは既に %s に割り当てられています" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "キーを取得しました: %s (確認のため Enter キーを押下してください)" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "新しいキーは: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "キー・バインドを削除しました (確認のため Enter キーを押下してください)" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "キー・バインドが削除されています" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "新しいキーの入力" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "Goes to next word." - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "なし" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "Goes to next word." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "Goes to next word." - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "文章" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "段落毎にキーエコーを返す。" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "word" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "Goes to next word." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "段落毎にキーエコーを返す。" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "black circle" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "horizontal" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "vertical bar" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "right arrow" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Wrapping to bottom." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "line height" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "and" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "overline" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "square root" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "cube root" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "root pane" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "root pane" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "root pane" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "table" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "tree table" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessible" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "ダイアル" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "字下げと行端揃えを読み上げません。" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "字下げと行端揃えを読み上げます。" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "学習モード (Esc 押下で終了する)" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "animation" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "ページのナビゲーション" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "表のナビゲーション" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "Leaving flat review." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "leaving table." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "line selected down from cursor position" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "line selected up from cursor position" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "line unselected down from cursor position" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "line unselected up from cursor position" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Exiting learn mode." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "line selected from start to previous cursor position" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "line selected to end from previous cursor position" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "link" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "same page" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "same site" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "different site" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s link to %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s link" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d visited link" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "All live regions set to off" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "live regions politeness levels restored" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "politeness level %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "setting live region to assertive" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "setting live region to off" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "setting live region to polite" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "setting live region to rude" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Live regions monitoring off" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Live regions monitoring on" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "no live message saved" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Live region support is off" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "No focus" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Could not find current location." - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "off" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "on" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "misspelled" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Misspelled word: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Context is %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Goes to the next object." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Mouse over object not found." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Mouse enhancements disabled." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Mouse enhancements enabled." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "子がありません。" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d percent." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "Goes to previous word." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nesting level %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "New item has been added" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "フォーカスを持つアプリケーションがありません。" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "No focus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "フォーカスを持つアプリケーションがありません。" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "No more blockquotes." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "No more buttons." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "No more check boxes." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "No more large objects." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "No more tables." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "No more combo boxes." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "No more entries." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "No more form fields." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "No more headings." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "No more headings at level %d." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "internal frame" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "No more tables." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "No more lists." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "No more lists." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "No more list items." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "No more live regions." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "No more paragraphs." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "No more radio buttons." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "No more separators." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "No more tables." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "No more unvisited links." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "No more visited links." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "not selected" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "Not in a table." - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "Notification %s" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "下端" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "上端" - -#: src/cthulhu/messages.py:2013 -#, fuzzy -msgid "No notification messages" -msgstr "Notification %s" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "word" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "大/小文字を含む文字列を単語として読み上げる(_D)" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "off" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "on" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Loading. Please wait." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Finished loading." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Finished loading %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "page selected from cursor position" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "page selected to cursor position" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "page unselected from cursor position" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "page unselected to cursor position" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "paragraph selected down from cursor position" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragraph selected up from cursor position" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "paragraph unselected down from cursor position" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragraph unselected up from cursor position" - -#: src/cthulhu/messages.py:2127 -#, fuzzy -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"既に Cthulhu の設定ダイアログを開いています。\n" -"\n" -"新しい設定を開く前に古いダイアログを閉じてください。" - -#: src/cthulhu/messages.py:2132 -#, fuzzy, python-format -msgid "slide %(position)d of %(count)d" -msgstr "on %(index)d of %(total)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "No files found." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Progress bar %d." - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "すべて" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "句読点の読み上げ" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "ほとんど" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "なし" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "いくつか" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Searching." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Search complete." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu 設定を再読み込みしました。" - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "Context is %s" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "delete" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "音声の種類を選択してください:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "unselected" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Speech disabled." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Speech enabled." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "faster." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "slower." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "higher." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "lower." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "faster." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "速度 %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "ピッチ %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "音量 %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher モジュール %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher 音声 %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "利用可能な Speech-dispatcher モジュールがありません" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "利用可能な Speech-dispatcher 音声がありません" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "音声設定を保存しました" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "音声設定を保存できませんでした" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu へようこそ。" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "クトゥルフは波の下に潜んでいます。" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "%s のスリープモードを有効にしました" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "%s のスリープモードを無効にしました" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "読み上げは利用できません。" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "No focus" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "Phrase not found" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "string not found" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Structural navigation keys off." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Structural navigation keys on." - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "No focus" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Row %(row)d, column %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "End of table" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Speak cell" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Speak row" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Non-uniform" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Not in a table." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "項目のヘッダー" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "column %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "column %(index)d of %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Bottom of column." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Top of column." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "unselected" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "unselected" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "row %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "row %(index)d of %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Beginning of row." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "End of row." - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "delete" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -#, fuzzy -msgid "Row inserted." -msgstr "insert" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "Goes to the end of the line." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "delete" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "unselected" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "selected" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "unselected" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu バージョン %s。" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "white space" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Wrapping to bottom." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Wrapping to top." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 items" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, fuzzy, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Cell spans %d rows" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d column" - -#: src/cthulhu/messages.py:2593 -#, fuzzy, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Cell spans %d columns" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d character too long" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d 個のダイアログ)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d unfocused dialog" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d file found" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d form" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d heading" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d item" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "No landmark found." - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d file found" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "No more blockquotes." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Leaving flat review." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "List with %d item" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "List with %d item" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "Table with %d row" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d column" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "Table with %d row" - -#: src/cthulhu/messages.py:2753 -#, fuzzy, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d space" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d percent." - -#: src/cthulhu/messages.py:2764 -#, fuzzy, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d percent of document read" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "ピクセル" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s character" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d of %(total)d item selected" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d space" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tab" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d table" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "Table with %d row" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "table with %(rows)d rows and %(columns)d columns." - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "Table with %d row" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d unvisited link" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d visited link" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "toggle" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "on %(index)d of %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d of %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "レベル %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "tree level %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "ツリーのレベル %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "question" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "combo box" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html content" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "word" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "colon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "overline" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "direction" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "paragraph" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "word" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "indent" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "direction" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "tab list" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "quote" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "html content" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s level %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "vertical bar" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "vertical align" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "vertical align" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "mode switch" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Icon panel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "html content" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "アニメーション" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "html content" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "アニメーション" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "Searching." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d visited link" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "spin button" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "畳んだ状態" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "展開した状態" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "checked" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "not checked" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "on" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "off" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "partically not checked" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "pressed" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "not pressed" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "selected" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d visited link" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d unvisited link" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "無効" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "read only" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "rdonly" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "required" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "multi-select" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "invalid" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "invalid" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "spelling" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "spelling" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "invalid" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "検索" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "スクリーンリーダーと拡大鏡" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "閉じる" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "検索" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "検索する語句(_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "検索する語句:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "ウィンドウのトップ(_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "ウィンドウのトップ" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "検索の開始:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "折り返しも対象にする(_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "降順で検索する(_B)" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "検索を開始する場所:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "大小文字を区別する(_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "単語全体と一致するものだけ(_E)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "検索オプション" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Default" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Uppercase" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/cthulhu-setup.ui:52 -#, fuzzy -msgid "System" -msgstr "term" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "アプリケーション" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "ウィンドウ" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu の設定" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "ラップトップ型(_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "キーボードの種類" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "検索の開始:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -#, fuzzy -msgid "Profiles" -msgstr "明るさ" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "ツールチップを有効にする(_P)" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "ポインターが指しているオブジェクトを読み上げる(_U)" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -#, fuzzy -msgid "Time and Date" -msgstr "点字の表示方法" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "すべて読み上げる(_S)" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "点字のキー割り当て" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -#, fuzzy -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "頻度 (秒)" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "アプリケーション" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "プログレスバーの更新" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "Toggles structural navigation keys." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "読み上げの単位(_Y):" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "読み上げの単位(_Y):" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "要素の表示(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "全般" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "音量(_L):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "音声の高さ(_T):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "読み上げの速度(_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "音声の人物(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "language" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "読み上げシンセサイザー(_Z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "読み上げシステム(_S):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "音声の設定(_V):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "複数のモニターの設定" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "大/小文字を含む文字列を単語として読み上げる(_D)" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "複数のモニターの設定" - -#: src/cthulhu/cthulhu-setup.ui:1561 -#, fuzzy -msgid "Voice" -msgstr "soffice" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "読み上げを有効にする(_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "冗長にする(_B)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "冗長の度合い" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "すべて(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "句読点の読み上げ" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "空行を読み上げる" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "字下げと行端揃えを読み上げる(_I)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "オブジェクトのショートカットキーを読み上げる(_K)" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "子の位置を読み上げる(_O)" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "チュートリアルのメッセージを読み上げる" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "セルの位置を読み上げる(_C)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "セルの位置を読み上げる(_C)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "子の位置を読み上げる(_O)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -#, fuzzy -msgid "Spoken Context" -msgstr "コントラスト" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "読み上げ" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "点字をサポートする(_S)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "ロールの名前を省略する(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "行末の記号を無効にする(_E)" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "短縮テーブル(_T):" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "短縮形の点字を有効にする(_E)" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "境界を有効にする(_D)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "複数のモニターの設定" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "なし(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "選択範囲の表示" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "ハイパーリンクの表示" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "拡大鏡を有効にする(_M)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "点字" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "キーエコーを有効にする(_K)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "ナビゲーション・キーを有効にする(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "修飾キーも対象にする(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "ファンクション・キーも対象にする(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "読み上げを有効にする(_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "修飾キーも対象にする(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "ファンクション・キーも対象にする(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "アクション・キーも有効にする(_T)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "ナビゲーション・キーを有効にする(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "単語毎にキーエコーを返す(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "段落毎にキーエコーを返す(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "キーエコー" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Cthulhu の修飾キー(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "キーの割り当て" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "発音用の辞書" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "追加(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "削除(_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "発音" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "すべて読み上げる(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "読み上げない(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "リセット(_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "文字の属性" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "最後へ(_B)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "下げる(_D)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "上げる(_U)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "先頭へ(_T)" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "" -"選択した属性\n" -"の調整" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "点字の表示方法" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "文字の属性" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "AI アシスタントを有効にする" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "プロバイダー(_P):" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (ローカル - 無料)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "APIキーファイル(_K):" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "APIキーファイルへのパス" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "_Claude API キーを取得" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "ブラウザを開いて Claude API キーを取得し、自動的に保存します" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "AI アクションの前に確認を要求" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama モデル(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Ollama のモデル名(例: llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama エンドポイント(_E):" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API エンドポイント URL(例: http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "スクリーンショット品質(_Q):" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "低" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "中" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "高" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI アシスタント" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "言語コード(_L):" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "倍率(_S):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "グレースケール画像(_G)" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "画像を反転(_I)" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "白黒画像(_B)" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "白黒しきい値(_T):" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "色を分析(_A)" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "結果をクリップボードにコピー(_C)" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "background color" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "background full height" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "background stipple" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direction" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editable" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "family name" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "foreground color" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "foreground stipple" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "font effect" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indent" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "mistake" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justification" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "language" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "left margin" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "line height" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "paragraph style" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixels above lines" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixels below lines" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixels inside wrap" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "right margin" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "rise" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "scale" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "size" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "stretch" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "strike through" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "style" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "text decoration" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "text rotation" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "text shadow" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "underline" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "vertical align" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "weight" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "wrap mode" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "writing mode" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "none" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "engrave" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "emboss" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "outline" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "overline" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "line through" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "blink" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "black" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "single" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "double" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "low" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "char" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "word" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "word char" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "left" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "right" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "center" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "no justification" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "fill" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensed" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensed" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensed" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensed" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi expanded" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expanded" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra expanded" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra expanded" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "small caps" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblique" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "italic" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Default" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Text body" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Heading" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "baseline" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "top" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "text-top" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "middle" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "bottom" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "text-bottom" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "inherit" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "solid" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "spelling" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Press space to toggle." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "Press space to expand, and use up and down to select an item." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Press alt+f6 to give focus to child windows." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "To move to items, use either the arrow keys or type ahead searching." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "To get to the system menus press the alt+f1 key." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Use up and down to select an item." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "To collapse, press shift plus left." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "To expand, press shift plus right." - -#: src/cthulhu/tutorialgenerator.py:397 -#, fuzzy -msgid "To activate press return." -msgstr "To activate press space." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Type in text." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Use left and right to view other tabs." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "To activate press space." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Use up or down arrow to select value. Or type in the desired numerical value." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Use arrow keys to change." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "To enter sub menu, press right arrow." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." diff --git a/po/ka.po b/po/ka.po deleted file mode 100644 index ce26f2d..0000000 --- a/po/ka.po +++ /dev/null @@ -1,9172 +0,0 @@ -# Georgian translation for cthulhu. -# Copyright (C) 2023 cthulhu authors -# This file is distributed under the same license as the cthulhu package. -# Ekaterine Papava , 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2024-04-13 03:05+0200\n" -"Last-Translator: Ekaterine Papava \n" -"Language-Team: Georgian <(nothing)>\n" -"Language: ka\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu - ეკრანის მკითხველი" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "ეკრანი;მკითხველი;ხელმისაწვდომობა;მეტყველება;ბრაილი;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "გფრთ" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "ანიმ" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "ისრ" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "კალ" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "ტილო" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "აღწრ" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "თოლია" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "ფრამრ" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "სვტთვსრთ" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "კბო" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "თრღ" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ხტლ" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "კდრ" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "დარეკვა" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "ფნჯრ" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "ჰტმლ" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "ხატვა" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "ფლარჩ" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "შმვსბ" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "ფნტ" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "ფორმა" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "მინა" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "თვი" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "სრთ" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "შდკდრ" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "ჭდე" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "შრპან" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "ბმული" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "სია" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "სისელ" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "მნუ" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "მნუზლ" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "მნუპნქ" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "პრმპნ" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "გვჩნ" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "გვჩნსია" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "პნლ" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "პრლ" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "მხტმნუ" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "პგზლ" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "ღლკ" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "რადიო" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "რდმნუპნქტ" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "სწყპნ" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "მწკრვს" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "ჩოჩია" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "ჩჩზლ" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "სქც" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "გმყფ" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "ჩოჩია" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "გყფპნლ" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "ტრლღლ" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "სტზლ" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "ცხრლ" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "უჯრდ" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "გმმპნქტ" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "პირობები" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "ტქსტ" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "გდსრთვ" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "ხლსწზლ" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "მნშნ" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "ხე" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "ხისცხრლ" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "უცნ" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "ხედი" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "ფნჯრ" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "თვსრთ" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ბლსრთ" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "პარა" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "აპი" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "ავტომატური" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "რდქზლ" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "ჩშნბლ" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "ჩეხური დონე 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "ესპანური დონე 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "კანადური ფრანგული დონე 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "ფრანგული ფრანგული დონე 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "ლატვიური დონე 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "ნიდერლანდების დანიური დონე 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "ნორვეგიული დონე 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "ნორვეგიული დონე 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "ნორვეგიული დონე 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "ნორვეგიული დონე 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "პოლონური დონე 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "პორტუგალიური დონე 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "შვედური დონე 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "არაბული დონე 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "ვალიური დონე 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "ვალიური დონე 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "გერმანული დონე 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "გერმანული დონე 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "გერმანული დონე 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "U.K. ინგლისური დონე 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "U.K. ინგლისური დონე 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "U.K. ინგლისური დონე 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "U.K. ინგლისური დონე 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "კანადური ფრანგული დონე 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "ფრანგული ფრანგული დონე 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "ბერძნული დონე 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "ჰინდი დონე 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "უნგრული 8 წერტილიანი კომპიუტერი" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "უნგრული დონე 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "უნგრული დონე 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "იტალიური დონე 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "ბელგიური დანიური დონე 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "ადგილი" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "ახალი ხაზი" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "ჩანართი" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "ძახილის ნიშანი" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "ბრჭყალი" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "ნომერი" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "დოლარი" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "პროცენტი" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "და" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "აპოსტროფი" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "გამხსნელი ფრჩხილი" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "დამხურავი ფრჩხლი" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "ვარსკვლავი" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "პლუსი" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "მძიმე" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "ტირე" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "წერტილი" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "დახრილი ხაზი" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "ორი წერტილი" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "წერტილმძიმე" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "ნაკლები" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "უდრის" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "მეტი" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "კითხვა" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "დრო" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "გამხსნელი კვადრატული ფრჩხილი" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "უკანა დახრილი ხაზი" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "დამხურავი კვადრატული ფრჩხილი" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "კარეტა" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "ხაზგასმული" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "უკუღმა ძახილის ნიშანი" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "მარცხენა ფიგურული ფრჩხილი" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "ვერტიკალური ხაზი" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "მარჯვენა ფიგურული ფრჩხილი" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "ტილდა" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "არაგადატანადი გამოტოვება" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "ამოყირავებული ძახილის ნიშანი" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "ცენტი" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "ფუნტი" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "ვალუტა" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "იენი" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "გაფუჭებული ზოლი" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "სექცია" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "ტრემა" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "უფლებები" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "ზედა a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "მარცხენა ორმაგი კუთხოვანი ფრჩხილი" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "ლოგიკური არა" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "ტირე" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "რეგისტრირებულია" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "ზედა ხაზი" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "გრადუსი" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "პლუს-მინუსი" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "ზედა 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "ზედა 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "მაგარი" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "მიუ" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "პარაგრაფის ნიშანი" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "შუა წერტილი" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "სედილა" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "ზედა 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ორდინალი" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "მარჯვენა ორმაგი კუთხოვანი ფრჩხილი" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "ერთი მეოთხედი" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "ნახევარი" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "სამი მეოთხედი" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "ამობრუნებული კითხვის ნიშანი" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "მაგარი ა" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "მაგარი დიდი ა" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "ა ძახილის ნიშნით" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "ა თავსახურით" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "დიდი ა ტილდით" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "დიდი ა უმლაუტით" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "დიდი ა რგოლით" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "აე" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "ცე სედილით" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "მაგარი დიდი ე" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "მაგარი ე" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "ე თავსახურით" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "დიდი ე უმლაუტით" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "მაგარი დიდი ი" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "ი ძახილის ნიშნით" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "ი თავსახურით" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "დიდი ი უმლაუტით" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ზე" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "დიდი ნ ტილდით" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "მაგარი დიდი ო" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "ო ძახილის ნიშნით" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "ო თავსახურით" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "ო ტილდით" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "ო უმლაუტით" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "რამდენჯერ" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "გადახაზული დიდი ო" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "მაგარი დიდი ა" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "უ ძახილის ნიშნით" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "უ თავსახურით" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "დიდი უ უმლაუტით" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "იგრეკი ძახილის ნიშნით" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "თორნი" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "გერმანული ს" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "მაგარი პატარა ა" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "პატარა ა თავსახურით" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "პატარა ა ტილდით" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "პატარა ა უმლაუტით" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "პატარა ა რგოლით" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "აე პატარა" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "პატარა ცე სედილით" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "მაგარი პატარა ე" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "მაგარი პატარა ე" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "პატარა ე თავსახურით" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "პატარა ე უმლაუტით" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "მაგარი პატარა ი" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "პატარა ი ძახილის ნიშნით" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "პატარა ი თავსახურით" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "პატარა ი უმლაუტით" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "პატარა ზე" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "პატარა ნ ტილდით" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "მაგარი პატარა ო" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "პატარა ო ძახილის ნიშნით" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "პატარა ო თავსახურით" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "პატარა ო ტილდით" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "პატარა ო უმლაუტით" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "გაყოფილი" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "პატარა გადახაზული ო" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "პატარა თორნი" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "პატარა უ ძახილის ნიშნით" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "მაგარი პატარა უ" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "პატარა უ თავსახურით" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "პატარა უ უმლაუტით" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "პატარა იგრეკი ძახილის ნიშნით" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "პატარა იგრეკი უმლაუტით" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "დიდი იგრეკი უმლაუტით" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "ფლორინი" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "დიდი ტირე" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "მარცხნენა ერთმაგი ბრჭყალი" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "მარჯვენა ერთმაგი ბრჭყალი" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "ერთი დაბალი ბრჭყალი" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "მარცხენა ორმაგი ბრჭყალი" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "მარჯვენა ორმაგი ბრჭყალი" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "ორმაგი ქვედა ბრჭყალი" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "ხანჯალი" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "ორმაგი ხანჯალი" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "ტყვია" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "სამკუთხედი ტყვია" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "პრომილი" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "პრიმა" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "ორმაგი პრიმა" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "სამმაგი პრიმა" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "გამოტოვება-ტირე" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "ევრო" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "სავაჭრო ნიშანი" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "თოლია" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "დიდი თოლიის ნიშანი" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-ის ფორმის ტყვია" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "ზედა 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "ზედა 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "ზედა 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "ზედა 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "ზედა 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "ზედა 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "ზედა 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "ზედა პლუსი" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "ზედა მინუსი" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "ზედა უდრისი" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "ზედა მარცხენა ფრჩხილი" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "ზედა მარჯვენა ფრჩხილი" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "ზედა პატარა ნ" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "ქვედა 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "ქვედა 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "ქვედა 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "ქვედა 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "ქვედა 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "ქვედა 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "ქვედა 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "ქვედა 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "ქვედა 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "ქვედა 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "ქვედა პლუსი" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "ქვედა მინუსი" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "ქვდა ტოლობა" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "ქვედა მარცხენა ფრჩხილი" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "ქვედა მარჯვენა ფრჩხილი" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "შავი კვადრატი" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "შავი ალმასი" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "ობიექტის ჩანაცვლების სიმბოლო" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "მაჩვენებლის მიმდინარე ელემენტზე გადამისამართება" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "მარცხენა წკაპი მიმდინარე ბრტყელი გადახედვის ელემენტზე" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "მარჯვენა წკაპი მიმდინარე ბრტყელი გადახედვის ელემენტზე" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "მთელი დოკუმენტის თქმა" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "მთელი ფანჯრის თქმა ბრტყელი გადახედვით" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "საბაზისო სად ვარ ოპერაციის ჩატარება" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "დეტალური სად ვარ ოპერაციის ჩატარება" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "ამჟამად მონიშნულის თქმა" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "ბმულის დეტალების თქმა" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "ნაგულისხმევი ღილაკის თქმა" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "სტატუსის ზოლის თქმა" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "სათაურის ზოლის თქმა" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "ძებნის ფანჯრის გახსნა" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "ქმედებების მენიუს ჩვენება" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "საძებნი სტრიქონის შემდეგი კვალი" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "საძებნი სტრიქონის წინა კვალი" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "ბრტყელი გადახედვის რეჟიმში შესვლა/გამოსვლა" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "ბრტყელი გადახედვის მიმდინარე ობიექტზე შეზღუდვის გადართვა" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "ბრტყელი გადახედვის საწყის მდებარეობაზე გადატანა" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "ბრტყელი გადახედვის საბოლოო მდებარეობაზე გადატანა" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "ბრტყელი გადახედვის წინა ხაზის დასაწყისში გადატანა" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "მიმდინარე ბრტყელი გადახედვის ხაზის წარმოთქმა" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "მიმდინარე ბრტყელი გადახედვის ხაზის დამარცვლა" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "მიმდინარე ბრტყელი გადახედვის ხაზის ფონეტიკური დამარცვლა" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "ბრტყელი გადახედვის შემდეგი ხაზის დასაწყისში გადატანა" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "ბრტყელი გადახედვის წინა ელემენტზე ან სიტყვაზე გადატანა" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "მიმდინარე ბრტყელი გადახედვის ელემენტის ან სიტყვის წარმოთქმა" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "მიმდინარე ბრტყელი გადახედვის ელემენტის ან სიტყვის დამარცვლა" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "მიმდინარე ბრტყელი გადახედვის ელემენტის ან სიტყვის ფონეტიკური დამარცვლა" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "ბრტყელი გადახედვის შემდეგ ელემენტზე ან სიტყვაზე გადატანა" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "ბრტყელი გადახედვის მიმდინარე სიტყვის ზედა სიტყვაზე გადატანა" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "მიმდინარე ბრტყელი გადახედვის ობიექტის წარმოთქმა" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "ბრტყელი გადახედვის მიმდინარე სიტყვის ქვედა სიტყვაზე გადატანა" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "ბრტყელი გადახედვის წინა სიმბოლოზე გადატანა" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "მიმდინარე ბრტყელი გადახედვის სიმბოლოს წარმოთქმა" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "მიმდინარე ბრტყელი გადახედვის სიმბოლოს ფონეტიკური წარმოთქმა" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "მიმდინარე ბრტყელი გადახედვის სიმბოლოს უნიკოდის მნიშვნელობის წარმოთქმა" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "ბრტყელი გადახედვის შემდეგ სიმბოლოზე გადატანა" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "ბრტყელი გადახედვის ხაზის ბოლოში გადატანა" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "ბრტყელი გადახედვის ქვემოთ მარცხნივ გადატანა" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "ბრტყელი გადახედვის ქვეშ არსებული შემცველობის ბუფერში კოპირება" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" -"ბრტყელი გადახედვის ქვეშ არსებული შემცველობის ბუფერის შემცველობისთვის ბოლოში " -"მიწერა" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "ბრტყელი გადახედვის შემცველობის ჩვენება" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"გადართვა, წაკითხული იქნება მხოლოდ მიმდინარე ცხრილის უჯრედი, თუ მთლიანი " -"მწკრივი" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "მიმდინარე ტექსტურ სიმბოლოსთან ასოცირებული ატრიბუტების წაკითხვა" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "ბრეილის ეკრანზე მარცხნივ გადაადგილება" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "ბრეილის ეკრანზე მარჯვნივ გადაადგილება" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "ობიექტზე დაბრუნება კლავიატურის ფოკუსით" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "შემოკლებული ბრაილის ჩართვა და გამორთვა" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "კურსორის მართვის ღილაკის დამუშავება" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "ტექსტის მონიშვნის დასაწყისის დასმა" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "ტექსტის მონიშვნის ბოლოს დასმა" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"სწავლის რეჟიმზე გადასვლა. სწავლის რეჟიმიდან გამოსასვლელად დააწექით ღილაკს " -"Esc" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "საუბრის სიჩქარის დაწევა" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "საუბრის სიჩქარის აწევა" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "საუბრის ტონის დაწევა" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "საუბრის ტონის აწევა" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "საუბრის ხმის აწევა" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "საუბრის ხმის დაწევა" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "საძებნი სტრიქონის წინა კვალი" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "შემდეგ საუბრის სინთეზატორზე გადასვლა" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "საუბრის სიჩქარის დაწევა" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "საუბრის სიჩქარის აწევა" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "ხმის ტიპის მორგება" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "საუბრის დადუმების გადართვა" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "საუბრის დიაგნოსტიკური შეტყობინებების დონის გადართვა" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "განლაგების რეჟიმის გადართვა" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "ეკრანის მკითხველიდან გასვლა" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "პარამეტრების მორგების ფანჯრის ჩვენება" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "აპლიკაციის პარამეტრების მორგების ფანჯრის ჩვენება" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "შეწევისა და სწორებების წარმოთქმის გადართვა" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "ნათქვამი რიცხვის სტილის შეცვლა" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "პუნქტუაციის გამოთქმის შემდეგ დონეზე გადასვლა" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "შემდეგ საუბრის სინთეზატორზე გადასვლა" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "შემდეგ პარამეტრების პროფილზე გდასვლა" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "შემდეგ სიმბოლოების რეგისტრის შეცვლის სტილზე გადასვლა" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "ღილაკების ექოს შემდეგ დონეზე გადასვლა" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "გამართვის დონის შეცვლა გაშვებულობის დროს" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "ჩანიშვნა, სად ვარ მიმდინარე მდებარეობასთან შედარებით" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "წინა სანიშნის მდებარეობაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "სანიშნზე გადასვლა" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "შემდეგი სანიშნის მდებარეობაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "სანიშნის დამატება" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "სანიშნების შენახვა" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "თაგუნას გადახედვის რეჟიმის გადართვა" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "მიმდინარე დროის ჩვენება" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "მიმდინარე თარიღის ჩვენება" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "მიმდინარე ობიექტის ზომისა და მდებარეობის ჩვენება" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "მიმდინარე აპლიკაციისთვის შემდეგი ბრძანების გადაცემა" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "წინა ჩატის ოთახის შეტყობინების წარმოთქმა და ბრაილი" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "ვუცხადებთ თუ არა ჩვენს მეგობრებს, რომ ჩვენ ვკრეფთ" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "ჩატის ოთახის სპეციფიკური შეტყობინების ისტორიების მიწოდების გადართვა" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"გადართვა, თუ ჩატის ოთახის შეტყობინებებს პრეფიქსად იგივე ოთახის სახელი აქვთ" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "ხაზი მარცხნივ" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "ხაზი მარჯვნივ" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "ხაზი მაღლა" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "ხაზი დაბლა" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "დამაგრება" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "ზედა მარცხენა" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "ქვედა მარცხენა" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "კურსორის პოზიცია" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "ექვსი წერტილი" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "კურსორული მართვა" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "ამოჭრის დასაწყისი" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "ხაზის ამოჭრა" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "ბოლო შეტყობინების ტექსტის ჩვენება" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "შეტყობინებების ტექსტის ჩამონათვლის ჩვენება" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "წინა შეტყობინების ტექსტის ჩვენება" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "შემდეგი გაფრთხილების შეტყობინების ტქმა" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "შემდეგ სიმბოლოზე გადასვლა" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "წინა სიმბოლოზე გადასვლა" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "შემდეგ სიტყვაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "წინა სიტყვაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "შემდეგ ხაზზე გადასვლა" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "წინა ხაზზე გადასვლა" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "ფაილის დასაწყისში გადასვლა" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "ფაილის ბოლოში გადასვლა" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "ხაზის დასაწყისში გადასვლა" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "ხაზის ბოლოში გადასვლა" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "შემდეგ ობიექტზე გადასვლა" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "წინა ობიექტზე გადასვლა" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "მიმდინარე ჩამოსაშლელის ჩამოშლა" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "საკუთარ და ეკრანის წამკითხველის კარეტით ნავიგაციას შორის გადართვა" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "დამატებითი ცოცხალი რეგიონის ზრდილობის პარამეტრი" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "ნაგულისხმევი ცოცხალი რეგიონის ზრდილობის დონის გამორთულზე დაყენება" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "ცოცხალი რეგიონის გამოცხადების გადახედვა" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "ცოცხალი რეგიონების მონიტორინგი" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "ფოკუსის გადატანა და მოცილება მიმდინარე თაგუნასთან" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "მწკრივის დაყენება დინამიკური სვეტის თავსართებად გამოსაყენებლად" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "დინამიკური სვეტის თავსართების გასუფთავება" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "სვეტის დაყენება დინამიკური მწკრივის თავსართებად გამოსაყენებლად" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "დინამიკური მწკრივის თავსართების გასუფთავება" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "შეყვანის ხაზის შემცველობის გამოტანა" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "სტრუქტურული ნავიგაციის ღილაკების გადართვა" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "წინა ციტატის ბლოკზე დაბრუნება" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "შემდეგ ციტატის ბლოკზე გადასვლა" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "ციტატის ბლოკების სიის გამოტანა" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "წინა ღილაკზე გადასვლა" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "შემდეგ ღილაკზე გადასვლა" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "ღილაკების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "წინა ჩამრთველზე გადასვლა" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "შემდეგ ჩამრთველზე გადასვლა" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "ჩამრთველების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "წინა დაწკაპუნებადზე გადასვლა" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "შემდეგ დაწკაპუნებადზე გადასვლა" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "დაწკაპუნებადების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "წინა ჩამოშლად სიაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "შემდეგ ჩამოშლად სიაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "კონტეინერის დასაწყისში გადასვლა" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "კონტეინერის ბოლოში გადასვლა" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "ჩამოშლადი სიების ჩამონათვლის ჩვენება" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "წინა ელემენტზე გადასვლა" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "შემდეგ ელემენტზე გადასვლა" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "ელემენტების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "წინა ფორმის ველზე გადასვლა" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "შემდეგ ფორმის ველზე გადასვლა" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "ფორმის ველების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "წინა მიმართულებაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "შემდეგ მიმართულებაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "მიმართულებების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "წინა %d დონის სათაურზე გადასვლა" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "შემდეგ %d დონის სათაურზე გადასვლა" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "სათაურის სიის ჩვენება დონეზე %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "წინა შიდა ჩარჩოზე გადასვლა" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "შემდეგ შიდა ჩარჩოზე გადასვლა" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "შიდა ჩარჩოების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "წინა გამოსახულებაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "შემდეგ გამოსახულებაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "გამოსახულებების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "წინა ორიენტირზე გადასვლა" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "შემდეგ ორიენტირზე გადასვლა" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "ორიენტირების ჩამონათვლის ჩვენება" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "წინა დიდ ობიექტზე გადასვლა" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "შემდეგ დიდ ობიექტზე გადასვლა" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "დიდი ობიექტების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "წინა ბმულზე გადასვლა" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "შემდეგ ბმულზე გადასვლა" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "ბმულების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "წინა სიაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "შემდეგ სიაზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "სიების ჩამონათვლის ჩვენება" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "წინა სიის ელემენტზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "შემდეგ სიის ელემენტზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "სიის ელემენტების ჩამონათვლის ჩვენება" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "წინა ცოცხალ რეგიონზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "შემდეგ ცოცხალ რეგიონზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "განცხადების გამკეთებელ უკანასკნელ ცოცხალ რეგიონზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "ნავიგატორის ფოკუსის მქონე ობიექტის მშობელზე გადასვლა." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "ნავიგატორი ფოკუსის მქონე ობიექტის პირველ შვილზე გადასვლა." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "ნავიგატორის ფოკუსის მქონე ობიექტის შემდეგ დაზე გადასვლა." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "ნავიგატორის ფოკუსის მქონე ობიექტის წინა დაზე გადასვლა." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "დააწკაპუნეთ ნავიგატორის ფოკუსის მქონე ობიექტზე." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "გამარტივებული ობიექტის ნავიგაციის გადართვა." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "წინა პარაგრაფზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "შემდეგ პარაგრაფზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "პარაგრაფების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "წინა რადიო ღილაკზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "შემდეგ რადიო ღილაკზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "ყველა რადიო ღილაკის სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "წინა გამყოფზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "შემდეგ გამყოფზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "წინა ცხრილზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "შემდეგ ცხრილზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "ცხრილების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "ერთი უჯრედით დაბლა გადასვლა" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "ცხრილის პირველ უჯრედზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "ცხრილის ბოლო უჯრედზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "ერთი უჯრედით მარცხნივ გადასვლა" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "ერთი უჯრედით მარჯვნივ გადასვლა" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "ერთი უჯრედით ზემოთ გადასვლა" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "განლაგების რეჟიმის გადართვა" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "დათვალიერებისა და ფოკუსის რეჟიმებს შორის გადართვა" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "წებოვანი ფოკუსის რეჟიმის ჩართვა" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "წებოვანი დათვალიერების რეჟიმი" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "წინა უნახავ ბმულზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "შემდეგ უნახავ ბმულზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "უნახავი ბმულების სიის ჩვენება" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "წინა უკვე ნანახ ბმულზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "შემდეგ უკვე ნანახ ბმულზე გადასვლა" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "უკვე ნანახი ბმულების სიის ჩვენება" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "ღია-ცისფერი" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "ანტიკური თეთრი" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "აკვამარინული" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "ლაჟვარდისფერი" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "ბეჟი" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "ბისკი" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "შავი" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "ძალიან ღია ყავისფერი" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "ლურჯი" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "ლურჯი იისფერი" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "ყავისფერი" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "მოყვითალო-ყავისფერი" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "ნაცრისფერ-ლურჯი" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "ბაცი მწვანე" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "შოკოლადი" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "მარჯნისფერი" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "ღიღილოსფერი" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "ღია ყვითელი" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "მეწამული" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "ცისფერი" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "მუქი ლურჯი" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "მუქი ცისფერი" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "მუქი ოქროსფერი" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "მუქი ნაცრისფერი" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "მუქი მწვანე" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "მუქი ხაკისფერი" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "მუქი ალისფერი" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "მუქი ზეთისხილისფერი მწვანე" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "მუქი ნარინჯისფერი" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "მუქი სოსანისფერი" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "მუქი წითელი" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "მუქი ნარინჯისფერ-ვარდისფერი" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "მუქი ზღვისფერი მწვანე" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "მუქი ფიქლისფერი ლურჯი" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "მუქი ფიქლისფერი ნაცრისფერი" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "მუქი ფირუზისფერი" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "მუქი იისფერი" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "ღრმა ვარდისფერი" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "ღრმა ცისფერი" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "მუქი ნაცრისფერი" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "დამცავი ლურჯი" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "ცეცხლის აგურისფერი" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "ყვავილის თეთრი" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "ტყის მწვანე" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "ფუქსიისფერი" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "ღია ნაცრისფერ-იისფერი" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "ნისლიანი თეთრი" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "ოქროსფერი" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "ოქროსფერი" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "ნაცრისფერი" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "მწვანე" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "მომწვანო ყვითელი" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "თეთრი მუსკატის ნესვი" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "კაშკაშა ვარდისფერი" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "ინდური წითელი" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "ინდიგო" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "სპილოს ძვლის ფერი" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "ხაკისფერი" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "ღია ლილისფერი" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "ღია ლილისფერი" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "გაზონისფერი მწვანე" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "ლიმონისფერი-კრემისფერი" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "ღია ლურჯი" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "ღია მარჯნისფერი" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "ღია ცისფერი" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "ღია ოქროსფერი მწვანე" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "ღია ნაცრისფერი" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "ღია მწვანე" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "ღია ვარდისფერი" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "ღია ნარინჯისფერ-ვარდისფერი" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "ღია ზღვისფერი მწვანე" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "ღია ცისფერი ლურჯი" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "ღია ფიქლისფერი ნაცრისფერი" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "ღია ფოლადის ლურჯი" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "ღია ყვითელი" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "ლაიმი" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "ლაიმის მწვანე" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "სელისფერი" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "ალისფერი" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "ბორდოსფერი" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "საშუალო აკვამარინული" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "საშუალო ლურჯი" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "საშუალო სოსანისფერი" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "საშუალო იისფერი" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "საშუალო ზღვისფერი მწვანე" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "საშუალო ფიქლისფერი ლურჯი" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "საშუალო გაზაფხულის მწვანე" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "საშუალო ფირუზისფერი" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "საშუალო იისფერი წითელი" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "შუაღამის ლურჯი" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "პიტნის კრემი" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "ნისლიანი ვარდი" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "მოკასინი" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "ნავაიო თეთრი" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "მუქი ლურჯი" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "ძველი მაქმანი" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "ზეთისხილი" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "ნაზი ზეთისხილისფერი" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "ნარინჯისფერი" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "ნარინჯისფერი წითელი" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "ორქიდეა" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "მკრთალი ოქროსფერი" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "ღია მწვანე" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "მკრთალი ფირუზისფერი" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "მკრთალი იისფერი წითელი" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "პაპაიას გაქცევა" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "ატმისფერი" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "პერუ" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "ვარდისფერი" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "ქლიავისფერი" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "ფხვნილი ლურჯი" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "იისფერი" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "წითელი" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "ვარდისფერ-ყავისფერი" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "სამეფო ლურჯი" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "ძველი ტყავისფერი" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "ორაგული" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "ქვიშისფერი" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "ზღვისფერი მწვანე" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "ზღვის ქაფისფერი" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "სიენისფერი" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "ვერცხლისფერი" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "ცისფერი" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "ფიქლისფერი ლურჯი" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "ფიქლისფერი ნაცრისფერი" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "თოვლი" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "გაზაფხულის მწვანე" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "ფოლადის ლურჯი" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "tan" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "მომწვანო ლურჯი" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "ნარშავი" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "პომიდორი" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "ფირუზისფერი" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "იისფერი" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "ხორბალი" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "თეთრი" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "თეთრი კვამლი" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "ყვითელი" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "ყვითელი მწვანე" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_აქტივაცია" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "ავტომატური ფოკუსის რეჟიმი სტრუქტურული ნავიგაციისას" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "ავტომატური ფოკუსის რეჟიმი კარეტით ნავიგაციისას" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "ავტომატური ფოკუსის რეჟიმი საკუთარი ნავიგაციისას" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "წერტილი_7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "წერტილი_8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "წერტილები 7 _და 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_გაუქმება" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_გადასვლა" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_დიახ" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "_ხატულა" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "არც_ერთი" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "მართლწერა" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "გამოქვეყნება, როცა მეგობარი კრეფს" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "ჩატის ოთახის შეტყობინების _ისტორიების მოწოდება" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "შეტყობინებების წამოთქმა წყაროდან" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "_ყველა არხი" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "ყველა არხიდან, როცა _ნებისმიერ %s ფანჯარა აქტიურია" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "არხი, მხოლოდ, თუ მისი ფან_ჯარა აქტიურია" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_სასაუბრო ოთახის სახელის წარმოთქმა" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "განლაგების რეჟიმის ჩართვა შემცველობისთვის" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "ორმაგი წკაპი" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "სამმაგი წკაპი" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "ნაგულისხმევი სინთეზატორი" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "მიმდინარე სტრიქონი" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "ჩასანაცვლებელი სტრიქონი" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "პიპინი _სიმბოლოების მიხედვით" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "არაგამოტოვების _დიაკრიტიკული ღილაკების ჩართვა" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_მიმდინარე მდებარეობა" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "ტექსტის დამთხვევის მინიმალური სიგრძე:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "ძებნის მორგება" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "ძებნისას, _მხოლოდ, შეცვლილი ხაზების წარმოთქმა" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "შედეგების წარმოთქმა ძ_ებნისას" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "ბრძანება" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "ღილაკის მიბმა" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "ნაგულისხმევი" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "სწავლის რეჟიმი" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "ქმედებები" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ბრაილის მიბმები" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "სანიშნეები" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "თარიღი და დრო" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "თაგუნას გადახედვა" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "ობიექტის ნავიგაცია" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "ობიექტის დეტალები" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "მითითებული არაა" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "ბრტყელი გადახედვა" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "საუბარი და გამართვა" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "ბრტყელი გადახედვის შემცველობა" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "შეცვლილია" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_სამუშაო მაგიდა" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "გაფრთხილებები" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "მიღებულია" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "გაფრთხილებების წარმომდგენი" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu-ს პარამეტრები %s-სთვის" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "მონიშვნა ბრაილში" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "წარმოდგენა, სანამ" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "ლაპარაკი" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "პროფილის, როგორც კონფლიქტის შენახვა" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "მომხმარებლის პროფილის კონფლიქტი!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"პროფილი %s უკვე არსებობს.\n" -"გავაგრძელო არსებული პროფილის განახლება ამ ცვლილებებით?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "მომხმარებლის პროფილის ჩატვირთვა" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"აპირებთ, აქტიური პროფილი შეცვალოთ.\n" -"თუ ცვლილებები პარამეტრებში ახლახან შეიტანეთ,\n" -"ისინი დაიკარგება პროფილის ჩატვირთვისას.\n" -"\n" -"გავაგრძელო პროფილის ჩატვირთვა და მოვაცილო წინა ცვლილებები?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "პროფილის შენახვა, როგორც" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "პროფილის _სახელი:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "მომხმარებლის პროფილის წაშლა" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"აპირებთ, წაშალოთ პროფილი %s. ყველა შეუნახავი პარამეტრი და პარამეტრი, რომელიც " -"ამ პროფილში შეინახეთ, დაიკარგება. გნებავთ, გააგრძელოთ და წაშალოთ ეს პროფილი " -"და მისი პარამეტრები?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "ყველა" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "აპლიკაცია" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "ფანჯარა" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "არ_ცერთი" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_ზოგი" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_უმეტესი" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "ხაზი" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "წინადადება" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "ციტატის ბლოკი" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "ღილაკი" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "წარწერა" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "ჩამრთველი" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "დაწკაპუნებადი" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "ჩამოშლადი სია" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "აღწერა" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "სათაური" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "შიდა ჩარჩო" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "გამოსახულება" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "ჭდე" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "ორიენტირი" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "დონე" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Ბმული" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "სია" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "სიის პუნქტი" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "ობიექტი" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "პარაგრაფი" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "რადიო ღილაკი" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "როლი" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "მონიშნული ელემენტი" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "State" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "ტექსტი" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "მნიშვნელობა" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "ბლოკბრჭყალები" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "ღილაკები" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "ჩასართველები" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "დაწკაპუნებადები" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "ჩამოშლადი სიები" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "ჩანაწერები" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "ფორმის ველები" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "სათაურები" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "შიდა ჩარჩოები" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "გამოსახულებები" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "სათაურები დონეზე %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "ორიენტირები" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "დიდი ობიექტები" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "ბმულები" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "სიები" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "ელემენტების სია" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "პარაგრაფები" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "რადიო ღილაკები" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "ცხრილებ" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "უნახავი ბმულები" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "უკვე ნანახი ბმულები" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "გვერდის ნავიგაცია" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "გვერდის წარმოთქმის ავტომატური დაწყება მისი პირველი ჩ_ატვირთვისას" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "გვერდის შეჯამების წარმოდგენა, როცა ის _პირველად ჩაიტვირთება" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "საუბრის დახლეჩა ნაწილებად პა_უზებს შორის" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s ნაგულისხმევი ხმა" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "ნაგულისხმევი" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "ჰიპერბმული" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "სისტემა" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "დიდი სიმბოლოები" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "საუბრის დისპეტჩერი" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "მართლწერის შემოწმება" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "მართლწერის _შეცდომა" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "მართლწერის _მინიშნება" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "შე_ცდომის კონტექსტის წარმოდგენა" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "ელცხრილის უჯრედის კოორდინატების წარმოთქმა" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "მონიშნული ელცხრილის შუალედის ყოველთვის წარმოთქმა" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "უჯრედის _თავსართის გამოცადება" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "ცხრილის ნავიგაცია" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "ცარიელი _უჯრედების გამოტოვება" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "_უჯრედის წარმოთქმა" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "_უჯრედის კოორდინატების წარმოთქმა" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "_მრავალი უჯრედის ზომის წარმოთქმა" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "ატრიბუტის სახელი" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "კარეტის ნავიგაციის ონტროლი" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "სტრუქტურული _ნავიგაციის ჩართვა" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "ხმის _თემა:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "ხმის თემა" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_მოკლე" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d გაფრთხილება" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "წანაცვლება" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "კონტროლი" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "მარცხენა Shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "მარცხენა Alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "მარცხენა Ctrl" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "მარჯვენა Shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "მარჯვენა Alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "მარჯვენა Ctrl" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "მარცხენა meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "მარჯვენა meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "up" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "მარცხნივ" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "მარჯვენა" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "left super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "right super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "მენიუ" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "დახმარება" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "mode switch" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "დასასრული" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "stroke" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "ჩამატება" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "წანაცვლება" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "სქელი %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "კურსივი %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "სქელი კურსივი %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "სკრიპტი %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "სქელი სკრიპტი %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "სქლად-გადახაზული %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "ორმაგად გადახაზული %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "სქლად-გადახაზული %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif სქელი %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif კურსივი %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif სქელი კურსივი %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "ერთსიგანიანი %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "უწერტილო %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "მარცხენა ისარი" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "ზედა ისარი" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "მარჯვენა ისარი" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "ქვედა ისარი" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "მარცხეენა მარჯვენა ისარი" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "ზემოთ-ქვემოთ ისარი" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "ჩრდილო-დასავლეთი ისარი" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "ჩრდილო-აღმოსავლეთი ისარი" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "სამხრეთ-აღმოსავლეთი ისარი" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "მარცხენა ისარი პანელიდან" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "ზედა ისარი პანელიდან" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "მარჯვენა ისარი პანელიდან" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "ქვემოთ ისარი პანელიდან" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "მარცხენა ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "ზედა ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "მარჯვენა ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "ქვედა ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "მარცხნივ-მარჯვნივ ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "ზემოთ-ქვემოთ ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "ჩრდილო-დასავლეთი ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "ჩრდილო-აღმოსავლეთი ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "სამხრეთ-აღმოსავლეთი ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "სამხრეთ-დასავლეთი ორმაგი ისარი" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "მარჯვნივ-მაჩვენებელი ისარი" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "მარჯვნივ-მაჩვენებელი ისრის-თავი" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "ნაკლები, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "მეტი ვიდრე" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "ჰაჩეკი" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "ბრები" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "წერტილი" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "ორმაგი ვერტიკალური ხაზი" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "ჰორიზონტალური მრავალწერტილი" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "ყველასთვის" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "დამატება" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "ნაწილობრივი დიფერენციალი" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "არსებობს" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "არ არსებობს" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "ცარიელი სიმრავლე" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "გაზრდა" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "ნაბლა" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "ელემენტია" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "არაა ელემენტი" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "მცირე ელემენტია" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "შეიცავს, როგორც წევრს" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "არ შეიცავს, როგორც წევრს" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "მცირე შეიცავს, როგორც წევრს" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "მტკიცების დასასრული" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "პროდუქტი" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "თანაპროდუქტი" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "ჯამი" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "პლუს-მინუსი" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "წერტილთან არ-მიბმული პლუსი" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "გაყოფის დახრილი ხაზი" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "სიმრავლეების სხვაობა" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "ვარსკვლავის ოპერატორი" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "რგოლი ოპერატორი" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "ოპერატორი სქელი წერტილი" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "კვადრატული ფესვი" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "კუბური ფესვი" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "მეოთხე ხარისხის ფესვი" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "პროპორციულია" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "უსასრულობა" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "მარჯვენა კუთხე" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "კუთხე" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "გაზომილი კუთხე" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "სფერული კუთხე" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "ყოფს" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "არ ყოფს" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "პარალელურია" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "პარალელური არაა" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "ლოგიკური და" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "ლოგიკური ან" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "კვეთა" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "გაერთიანება" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "ინტეგრალი" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "ორმაგი ინტეგრალი" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "სამმაგი ინტეგრალი" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "კონტურის ინტეგრალი" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "ზედაპირული ინტეგრალი" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "მოცულობითი ინტეგრალი" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "საათის ისრის მიმართულებით ინტეგრალი" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "საათის ისრის მიმართულებით კონტურის ნტეგრალი" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "საათის ისრის მიმართულებით საწინააღმდეგო კონტურის ნტეგრალი" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "აქედან გამომდინარე" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "იმიტომ, რომ" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "მასშტაბი" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "პროპორცია" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "წერტილი მინუს" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "ზედმეტი" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "გეომეტრიული პროპორცია" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "ჰომოთეტიკური" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "ტილდა" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "შებრუნებული ტილდა" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "მწოლიარე S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "სინუსოიდალური ტალღა" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "wreath product" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "ტილდა არაა" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "მინუს ტილდა" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "ასიმპტოტურად უდრის" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ასიმპტოტურად არ უდრის" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "დაახლოებით უდრის" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "დაახლოებით არ უდრის" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "არც დაახლოებით, არც ზუსტად უდრის" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "თითქმის უდრის" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "თითქმის არ უდროს" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "თითქმის ან ტოლია" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "სამმაგი ტილდა" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "ყველა ტოლია" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ეკვივალენტურია" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "გეომეტრიულად ეკვივალენტურია" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "სხვაობები შორის" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "უახლოვდება ზღვარს" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "გეომეტრიულად უდრის" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "დაახლოებით უდრის ან ასლია" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "ასლია ან დაახლოებით უდრის" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "ორიწერტილი უდრის" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "ტოლობა ორიწერტილი" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "წრე ტოლობაში" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "წრე უდრის" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "შეესაბამება" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "უტოლდება" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "ტოლგვერდაა" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "ვარსკვლავი უდრის" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "დელტა უდრის" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "აღწერის მიხედვით უდრის" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "გაზომილია" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "შეიძლება, უდრიდეს" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "არ უდრის" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "იდენტური" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "არაა იდენტური" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "ზუსტად ეკვივალენტურია" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "ნაკლები ან ტოლია" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "მეტია ან ტოლია" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "ნაკლები ვიდრე ზემოდან ტოლია" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "მეტი ან ზემოდან ტოლია" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "ნაკლებია, მაგრამ ტოლი არაა" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "მეტია, მაგრამ ტოლი არაა" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "გაცილებით ნაკლები, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "გაცილებით მეტი, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "მითითებულ დროის შუალედში" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "არ უდრის" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "არა ნაკლები, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "არა მეტი, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "არც ნაკლებია, არც ტოლია, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "არც მეტია, არც ტოლია, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "ნაკლები ან ტოლი, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "მეტი ან ტოლი, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "არც ნაკლები, არც ტოლი, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "არც მეტი, არც ტოლი, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "ნაკლები, ან ტოლი, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "მეტი ან ნაკლები, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "არც ნაკლები, არც მეტი, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "არც მეტი, არც ნაკლები, ვიდრე" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "ჩამორჩება" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "წინ უსწრებს" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "ჩამორჩება ან უდრის" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "წინ უსწრებს ან უდრის" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "ჩამორჩება ან ეკვივალენტურია" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "წინ უსწრებს ეკვივალენტურია" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "არ ჩამორჩება" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "წინ არ უსწრებს" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "ქვესეტია" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "სუპერსეტია" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "ქვესეტი არაა" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "სუპერსეტი არაა" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "ქვესეტია ან უდრის" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "სუპერსეტია ან უდრის" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "არც ქვესეტია, არც უდრის" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "არც სუპერსეტია, არც უდრის" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "ქვესეტია, რომელიც არ უდრის" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "სუპერსეტია, რომელიც არ უდრის" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "მულტისიმრავლე" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "მულტისიმრავლის გამრავლება" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "მულტისიმრავლის შეერთება" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "კვადრატული ასლი" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "კვადრატული ორიგინალი" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "კვადრატული ასლია ან ტოლია" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "კვადრატული ორიგინალია ან ტოლია" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "ოთხკუთხედი თავსახური" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "ოთხკუთხედი ჭიქა" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "პლუსი წრეში" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "მინუსი წრეში" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "გამრავლების ნიშანი წრეში" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "გაყოფის დახრილი ხაზი წრეში" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "წერტილის ოპერატორი წრეში" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "რგოლი ოპერატორი წრეში" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "ძახილის ნიშნის ოპერატორი წრეში" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "ტოლობის ნიშანი წრეში" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "ტირე წრეში" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "პლუსი კვადრატში" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "მინუსი კვადრატში" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "გამრავლების ნიშანი კვადრატში" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "წერტილის ოპერატორი კვადრატში" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "ღილაკი მარჯვნივ" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "ღილაკი მარცხნივ" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "ღილაკი ქვემოთ" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "ღილაკი ზემოთ" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "დამტკიცება" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "მოდელები" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "სიმართლე" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "ძალები" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "მარჯვენა გადაჯვარედინება სამმაგი ვერტიკალური ხაზით" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "ორმაგი მარჯვენა ჯვარედი ორმაგი ვერტიკალური ხაზით" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "არ ამტკიცებს" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "არა-ჭეშმარიტი" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "არ ამტკიცებს" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "უარყოფილი ორმაგი მარჯვენა ჯვარედი ორმაგი ვერტიკალური ხაზით" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "წინ უსწრებს ურთიერთობის ძალაში" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "მიჰყვება ურთიერთობის ძალაში" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "ნორმალური ქვეჯგუფი" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "შეიცავს, როგორც ნორმალურ ქვეჯგუფს" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "ნორმალურ ქვეჯგუფი ან უდრის" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "შეიცავს, როგორც ნორმალურ ქვეჯგუფს ან უდრის" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "ორიგინალი" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "გამოსახულება" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "მულტირუკა" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "ერმიტული შეუღლებული მატრიცა" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "ინტერკალირება" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "არ-ან" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "და-არა" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "ან-არა" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "მარჯვენა კუთხე რკალით" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "მართხკუთხა სამკუთხედი" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "ოპერატორი რომბი" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "წერტილის ოპერატორი" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "ვარკსვლავის ოპერატორი" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "გაყოფა გამრავლება" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "ჰალსტუხი პეპელა" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "ნახევრადპირდაპირი წარმოებული მარცხენა ნორმალური მამრავლით" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "ნახევრადპირდაპირი წარმოებული მარჯვენა ნორმალური მამრავლით" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "მარცხენა ნახევრადპირდაპირი წარმოებული" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "მარჯვენა ნახევრადპირდაპირი წარმოებული" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "შებრუნებული ტილდა უდრის" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "ხვეული ლოგიკური ან" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "ხვეული ლოგიკური და" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "ორმაგი ქვესიმრავლე" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "ორმაგი ზესიმრავლე" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "ორმაგი კვეთა" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "ორმაგი გაერთიანება" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "ჩანგალი" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "ტოლი ან პარალელურია" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "ნაკლებია, ვიდრე წერტილით" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "მეტია, ვიდრე წერტილით" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "გაცილებით ნაკლები, ვიდრე" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "გაცილებით მეტი, ვიდრე" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "ნაკლებია, ტოლია ან მეტია" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "მეტია, ტოლია ან ნაკლებია" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "ტოლია ან ნაკლებია" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "ტოლია ან მეტია" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "ტოლია ან ჩამორჩება" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "ტოლია ან უსწრებს" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "არ ჩამორჩება ან ტოლია" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "არ უსწრებს ან ტოლია" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "არა კვადრატული გამოსახულება ან უდრის" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "რა კვადრატული ორიგინალი ან უდრის" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "კვადრატული გამოსახულება ან არ უდრის" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "კვადრატული ორიგინალი და არ უდრის" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "ნაკლებია, მაგრამ არა ეკვივალენტური" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "მეტია, მაგრამ არა ეკვივალენტური" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "ჩამორჩება, მაგრამ ეკვივალენტური არაა" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "უსწრებს, მაგრამ ეკვივალენტური არაა" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "არ წარმოადგენ ნორმალურ ქვეჯგუფს" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "არ შეიცავს, როგორც ნორმალურ ქვეჯგუფს" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "არაა ნორმალურ ქვეჯგუფი ან უდრის" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "არ შეიცავს, როგორც ნორმალურ ქვეჯგუფს ან უდრის" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "ვერტიკალური მრავალწერტილი" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "თარაზული შუა მრავალწერტილი" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "ზედა მარჯვენა დიაგონალური მრავალწერტილი" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "ქვედა მარჯვენა დიაგონალური მრავალწერტილი" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "ელემენტი გრძელი ჰორიზონტალური გადახაზვით" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "ელემენტი ვერტიკალური ხაზით ჰორიზონტალური გადახაზვის ბოლოში" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"ჰორიზონტალური გადახაზვის ბოლოში არსებული ვერტიკალური ხაზის პატარა ელემენტი" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "ელემენტი თავზე წერტილით" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "ელემენტი თავზე ხაზით" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "პატარა ელემენტი თავზე ხაზით" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "ელემენტი ხაზით ქვეშ" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "ელემენტი ორი ჰორიზონტალური გადახაზვით" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "შეიცავს გრძელი ჰორიზონტალური გადახაზვით" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "შეიცავს ვერტიკალური ხაზით ჰორიზონტალური გადახაზვის ბოლოში" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"პატარა შეიცავს ჰორიზონტალური გაახაზვის ბოლოში არსებული ვერტიკალური ხაზით" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "შეიცავს თავზე ხაზით" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "პატარა შეიცავს თავზე ხაზით" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "კალათის წევრობის Z ნოტაცია" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "მარცხენა ჭერი" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "მარჯვენა ჭერი" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "მარცხენა იატაკი" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "მარჯვენა იატაკი" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "ზედა ფრჩხილი" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "ქვედა ფრჩხილი" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "მარცხენა კუთხოვანი ფრჩხილი" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "მარჯვენა კუთხოვანი ფრჩხილი" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "წერტილი წრეში" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "გაერთიანება წერტილით" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "გაერთიანება პლუსით" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "ოთხკუთხედი კვეთა" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "ოთხკუთხედი გაერთიანება" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "შავი კვადრატი" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "თეთრი კვადრატი" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "შავი ალმასი" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "თეთრი წრე" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "შავი წრე" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "თეთრი ტყვია" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "შავი საშუალო პატარა კვადრატი" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s ხაზგასმით" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s დახრილი ხაზით" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s შვეული ხაზით" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "პროგრამა" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "ცარიელი" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "სქელი" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "სანიშნი შეყვანილია" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "სანიშნი შენახულია" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "სანიშნის შენახვა შეუძლებელია" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "სანიშნეების გარეშე." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "სანიშნი ვერ ვიპოვე." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "გატარების რეჟიმი ჩართულია." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "კალკულატორის ეკრანის მიღება შეუძლებელია" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ხატულა" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "დიდი ასოების სტილი დაყენებულია ხატულაზე." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "არა" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "დიდი ასოების სტილი დაყენებულია არაფერზე." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "მართლწერა" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "დიდი ასოების წარმოთქმა." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "კარეტას აპლიკაცია აკონტროლებს." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "კარეტას აპლიკაცია აკონტროლებს." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "უჯრედი %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "მონიშნულია \"%s\"" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "მონიშნულია %s-დან %s-მდე" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "მონიშვნა მოხსნილია %s-დან %s-მდე" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s მონიშვნა გაუქმდა" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "პარამეტრის გამოყენების აკრძალვა" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "პარამეტრის ნაძალადევი გამოყენება" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "პარამეტრი" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "არასავალდებულო არგუმენტები" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "გამოყენება: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "შემდეგი არასწორია: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "ცნობილი გაშვებული აპლიკაციების გამოტანა" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "პროფილის ჩატვირთვა" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "პროფილის ჩატვირთვა შეუძლებელია: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"ეკრანის წამკითხველის გაშვება შეუძლებელია, რადგან ის ეკრანს ვერ მიუერთდა." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "პარამეტრების მმართველის გააქტიურება შეუძლებელია. გასვლა." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"ამ სესიისთვის უკვე გაშვებულია სხვა ეკრანის წამკითხველი.\n" -"გაუშვით \"cthulhu --replace\", რომ პროცესი ახლით ჩაანაცვლოთ." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "სახელი" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "ალტერნატიული საქაღალდის გამოყენება მომხმარებლის პარამეტრებისთვის" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "საქაღალდე" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "ამ აპლიკაციის ვერსია" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "ამჟამად გაშვებული ამ ეკრანის წამკითხველის ჩანაცვლება" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "ამ დახმარების შეტყობინების ჩვენება და გასვლა" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "გამართვის ინფორმაციის ჩაწერა ფაილში debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "გამართვის შეტყობინებების გაგზავნა მითითებულ ფაილში" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FILE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "მომხმარებლის პარამეტრების მორგება (ტექსტური ვერსია)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "მომხმარებლის პარამეტრების მორგება (გრაფიკული ვერსია)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "შეცდომების შესახებ მოიწერეთ https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "მონიშნული ბუფერში ამოიჭრა." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "ამოჭრა" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "მონიშნული ბუფერში დაკოპირდა." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "კოპირებულია" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "გაცვლის ბუფერიდან ჩასმული." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "ჩასმულია" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "არ გამოაქვეყნო, როცა მეგობარი კრეფს." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "გამოქვეყნება, როცა მეგობარი კრეფს." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "შეტყობინება ჩატის ოთახიდან %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "ახალი ჩატის ჩანართი %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "არ წარმოთქვა სასაუბრო ოთახის სახელი." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "სასაუბრო ოთახის სახელის წარმოთქმა." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "ჩატის ოთახის სპეციფიკური შეტყობინების ისტორიების მიწოდების გამორთვა." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "ჩატის ოთახის სპეციფიკური შეტყობინების ისტორიების მიწოდების ჩართვა." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "წაშლის დასაწყისი" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "წაშლის დასასრული" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "ჩასმის დასაწყისი" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "ჩასმის დასასრული" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "გამოკვეთის დასაწყისი" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "გამოკვეთის დასასრული" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "მინიშნების დასასრული" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "კონტეინერის დასასრული." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "კონტეინერი არაა." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "ყველა ელემენტი მონიშნულია" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "ნაგულისხმევი ღილაკია %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "ნაგულისხმევი ღილაკია %s. ნაცრისფერია" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "ნაგულისხმევი ღილაკი ვერ ვიპოვე" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " ქვესკრიპტი %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " ზესკრიპტი %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "ფანჯარაში არაა" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "მონიშნულია მთლიანი დოკუმენტი" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "მთლიანი დოკუმენტის მონიშვნა მოხსნილია" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "კურსორის პოზიციიდან მონიშნული დოკუმენტი" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "კურსორის პოზიციიდან მონიშვნამოხსნილი დოკუმენტი" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "კურსორის პოზიციამდე მონიშნული დოკუმენტი" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "კურსორის პოზიციამდე მონიშვნამოხსნილი დოკუმენტი" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "დინამიკური სვეტის თავსართი დაყენებულია მწკრივისთვის %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "დინამიკური სვეტის თავსართი გასუფთავდა." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "დინამიკური მწკრივის თავსართი დაყენებულია სვეტისთვის %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "დინამიკური მწკრივის თავსართი გასუფთავდა." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ცარიელია" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f კილობაიტი" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f მეგაბაიტი" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "ფაილები ვერ მოიძებნა." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "მიეწერა გაცვლის ბუფერის შმცველობას." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "შემცველობა დაკოპირდა გაცვლის ბუფერში." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "არ ვიყენებ ბრტყელ მიმოხილვას." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "შევდივარ ბრტყელ მიმოხილვაში." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "გავდივარ ბრტყელი მიმოხილვიდან." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "მიმდინარე ობიექტზე შეზღუდული ბრტყელი გადახედვა" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "ბრტყელი მიმოხილვა შეუზღუდავია" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "აქვს ფორმულა" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "ხსნის დიალოგს" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "ხსნის ბადეს" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "ხსნის სიას" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "ხსნის მენიუს" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "ხსნის ხეს" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "გამოსახულების რუკის ბმული" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "შეყვანილი ღილაკი უკვე მიბმულია %s-ზე" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "ჩაჭერილი ღილაკი: %s. დასადასტურებლად დააჭირეთ Enter-ს." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "ახალი ღილაკია: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "ღილაკის მიმაგრება წაიშალა. დასადასტურებლად დააჭირეთ ღილაკს Enter." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "ღილაკის მიმაგრება წაიშალა." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "შეიყვანეთ ახალი ღილაკი" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "გასაღები" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "ექო დაყენებულია ღილაკზე." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "არც_ერთი" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "ექო დაყენებულია არაფერზე." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "გასაღები და სიტყვა" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "ექო დაყენებულია ღილაკზე და სიტყვაზე." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "წინადადება" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "ექო დაყენებულია წინადადებაზე." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "სიტყვა" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "ექო დაყენებულია სიტყვაზე." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "სიტყვა და წინადადება" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "ექო დაყენებულია სიტყვაზე და წინადადებაზე." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "ჩასულია: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "მიმდინარე სიმბოლო" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "ყუთი" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "წრეწირი" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "გრძელი გაყოფის ნიშანი" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "რადიკალი" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "მომრგვალებული ყუთი" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "ჰორიზონტალური გადასმა" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "შვეული გადასმა" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "ქვედა დიაგონალური გადასმა" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "ზედა დიაგონალური გადასმა" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "ჩრდილო-აღმოსავლეთის ისარი" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "ხაზი ბოლოში" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "ხაზი მარცხნივ" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "ხაზი მარჯვნივ" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "ხაზი ზემოთ" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "ფაზური კუთხე" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "არაბული ფაქტორიალის სიმბოლო" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "და" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "დახრილი ხაზის დასაწყსი" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "დახრლი ხაზი ხაზის დასაწყისის გარეშე" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "ზემოთ" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "დახრილი ხაზის დასასრული" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "კვადრატული ფესვი" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "კუბური ფესვი" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "ფესვი" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "ფესვის დასაწყისი" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "ფესვის დასასრული" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "ქვესკრიპტი" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "ზესკრიპტი" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "ქვედა-ინდექსამდელი" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "ზედა-ინდექსამდელი" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "ქვესკრიპტი" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "ზესკრიპტი" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "ცხრილის დასასრული" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "ჩალაგებული ცხრილის დასასრული" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "მიუწვდომელი" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "გამორთულია" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "შეწევის და სწორებების წარმოთქმა გათიშულია." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "ჩართულია" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "შეწევის და სწორებების წარმოთქმა ჩართულია." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "სწავლის რეჟიმი. გამოსასვლელად დააწექით ღილაკს Esc." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"მიმდინარეობს სწავლის რეჟიმში გადასვლა. დააწექით ნებისმიერ ღილაკს, რომ მისი " -"ფუნქცია გაიგოთ. იმისათვის, რომ ნახოთ ეკრანის წამკითხველის დოკუმენტაცია, " -"დააწექით ღილაკს F1. იმისათვის, რომ ნახოთ ეკრანის წამკითხველის ნაგულისხმევი " -"მალსახმობები, დააწექით ღილაკს F2. იმისათვის, რომ მიიღოთ ეკრანის წამკითხველის " -"მალსახმობების სია მიმდინარე აპლიკაციისთვის, დააწექით ღილაკს F3. სწავლის " -"რეჟიმიდან გასასვლელად დააწექით ღილაკს Esc." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "ციტატის ბლოკიდან გასვლა." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "დეტალებიდან გასვლა." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "ლენტიდან გასვლა." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "ფიგურიდან გასვლა." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "ფორმიდან გასვლა." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "ბანერიდან გასვლა." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "შემცვლელი შემცველობიდან გასვლა." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "ინფორმაციიდან გასვლა." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "მთავარი შემცველობიდან გასვლა." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "ნავიგაციიდან გასვლა." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "რეგიონიდან გასვლა." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "ძებიდან გასვლა." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "სიიდან გასვლა." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "პანელიდან გასვლა." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "ცხრილიდან გასვლა." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "მინიშნებიდან გასვლა." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "აბსტრაქტიდან გასვლა." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "დადასტურებიდან გასვლა." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "ბოლოსიტყვიდან გასვლა." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "დანართიდან გასვლა." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "ბიბლიოგრაფიდან გასვლა." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "თავიდან გასვლა." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "კოლოფონიდან გასვლა." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "დასკვნიდან გასვლა." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "ხსენებდან გასვლა." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "ხსენებიდან გასვლა." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "მიძღვნიდან გასვლა." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "ბოლოსართებიდან გასვლა." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "ეპიგრაფიდან გასვლა." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "ეპილოგიდან გასვლა." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "მორჩენილი შეცდომებიდან გასვლა." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "მაგალითიდან გასვლა." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "წინასიტყვაობიდან გასვლა." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "სარჩევიდან გასვლა." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "ინდექსიდან გასვლა." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "შესავალიდან გასვლა." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "გვერდების სიიდან გასვლა." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "ნაწილიდან გასვლა." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "შესავალიდან გასვლა." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "პროლოგიდან გასვლა." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "ციტატიდან გასვლა." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "კდპ-დან გასვლა." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "მინიშნებიდან გასვლა." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "სარჩევიდან გასვლა." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "მონიშნულია ხაზი კურსორის მდებარეობის დაბლა" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "მონიშნულია ხაზი კურსორის მდებარეობის მაღლა" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "მონიშვნა მოხსნილია ხაზზე კურსორის დაბლა" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "მონიშვნა მოხსნილია ხაზზე კურსორის მაღლა" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "სწავლის რეჟიმიდან გასვლა." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "ხაზი მონიშნულია წინა კურსორის მდებარეობის დასაწყისიდან" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "ხაზი მონიშნულია წინა კურსორის მდებარეობის დასასრულიდან" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ბმული" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "იგივე გვერდი" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "იგივე საიტი" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "სხვა საიტი" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s მიბმულია ფაილზე %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s ბმული" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "გახსნილი %s ბმული" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"გამოიყენეთ ზემოთ და ქვემოთ ისრები სიაში სასიარულოდ. გასასვლელად დააწექით " -"ღილაკს Escape." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "ყველა ცოცხალი რეგიონი გამორთულია" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "ცოცხალი რეგიონების ზრდილობის დონეები აღდგენილია" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "ზრდილობის დონე %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "ცოცხალი რეგიონის დაყენება ცვლილებებზე" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "ცოცხალი რეგიონის დაყენება გამორთულზე" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "ცოცხალი რეგიონის დაყენება ზრდილობიანზე" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "ცოცხალი რეგიონის დაყენება უხეშზე" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "ცოცხალი რეგიონების მონიტორინგი გამორთულია" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "ცოცხალი რეგიონების მონიტორინგი ჩართულია" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "ცოცხალი შეტყობინება არ შენახულია" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "ცოცხალი რეგიონის მხარდაჭერა გამორთულა" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "ნაპოვნი არაა" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "ვერ ვიპოვე მიმდინარე მდებარეობა." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "გამორთული" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "ჩართული" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "არასწორი მართლწერა" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "არასწორად დაწერილი სიტყვა: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "კონტექსტია %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "დათვალიერების რეჟიმი" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "კონცენტრაციის რეჟიმი" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "ფოკუსის რეჟიმის ჩასართავად დააწექით %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "ფოკუსის რეჟიმი წებოვანია." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "დათვალიერების რეჟიმი წებოვანია." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "განლაგების რეჟიმი." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "ობიექტის რეჟიმი." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "კურსორი გადატანილია ობიექტთან." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "თაგუნაგადატარებული ობიექტი არ არსებობს." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "თაგუნას გადახედვა გათიშულია." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "თაგუნას გადახედვა ჩართულია." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "შეცდომა: ობიექტების სიის შექმნა შეუძლებელია." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "შვილების გარეშე." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "შემდეგის გარეშე." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "მშობლის გარეშე." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "წინას გარეშე." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "გამარტივებული ნავიგაცია ჩართულია." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "გამარტივებული ნავიგაცია გამორთულია." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "ჩადგმის დონეა %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "დამატებულია ახალი ელემენტები" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "ქმედება არ არსებობს: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "ფოკუსის გარეშე" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "ფოკუსის მქონე აპლიკაციის გარეშე." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "ბლოკბრჭყალების გარეშე." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "მეტი ღილაკი აღარაა." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "მეტი ჩამრთველი აღარაა." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "მეტი დიდი ობიექტი აღარაა." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "მეტი დაწკაპუნებადები აღარაა." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "მეტი ჩამოშლადი სია აღარაა." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "მეტი ჩანაწერი აღარაა." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "მეტი ფორმის ველი აღარაა." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "მეტი სათაური აღარაა." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "ვერ ვიპოვე მეტი სათაური დონეზე %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "შიდა კადრები მეტი აღარაა." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "მეტი გამოსახულება აღარაა." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "ორიენტირის გარეშე." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "მეტი ბმული აღარაა." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "მეტი სია აღარაა." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "მეტი სიის ელემენტი აღარაა." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "მეტი ცოცხალი რეგიონის გარეშე." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "მეტი პარაგრაფი აღარაა." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "მეტი რადიო ღილაკი აღარაა." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "მეტი გამყოფი აღარაა." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "მეტი ცხრილი აღარაა." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "მეტი უნახავი ბმული აღარაა." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "მეტი ნანახი ბმული აღარაა." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "მეტი მონიშნული ბმული აღარაა." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "ბმულს არ წარმოადგენს." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "შეტყობინება" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "ბოლოში" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "ზემოთ" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "გაფრთხილების შეტყობინებების გარეშე" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "ციფრები" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "რიცხვების ციფრებად წარმოთქმა." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "სიტყვა" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "რიცხვების სიტყვებად წარმოთქმა." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "გამორთული" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ჩართული" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "იტვირთება. გთხოვთ, მოითმინოთ." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "ჩატვირთვა დასრულდა." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s-ის ჩატვირთვა დასრულდა." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "გვერდს აქვს %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "გვერდი მონიშნულია კურსორის მდებარეობიდან" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "გვერდი მონიშნულია კურსორის მდებარეობამდე" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "გვერდის მონიშვნა მოხსნილია კურსორის მდებარეობიდან" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "გვერდის მონიშვნა მოხსნილია კურსორის მდებარეობამდე" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "პარაგრაფი მონიშნულია ქვემოთ კურსორის მდებარეობიდან" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "პარაგრაფი მონიშნულია ზემოთ კურსორის მდებარეობიდან" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "პარაგრაფის მონიშვნა მოხსნილია ქვემოთ კურსორის მდებარეობიდან" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "პარაგრაფის მონიშვნა მოხსნილია ზემოთ კურსორის მდებარეობიდან" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"თქვენ უკვე გაქვთ Cthulhu-ის მორგების ფანჯრის გაშვებული ასლი.\n" -"დახურეთ ის, სანამ ახალს გახსნიდეთ." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "სლაიდი %(position)d %(count)d-დან" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "პროფილი დაყენებულია მნიშვნელობაზე %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "პროფილები ვერ მოიძებნა." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "მიმდინარეობის პანელი %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "ყველა" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "პუნქტუაციის დონე დაყენებულია ყველაზე." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "თითქმის ყველა" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "პუნქტუაციის დონე დაყენებულია თითქმის ყველაზე." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "არც_ერთი" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "პუნქტუაციის დონე დაყენებულია არც-ერთზე." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "ზოგი" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "პუნქტუაციის დონე დაყენებულია ზოგიერთზე." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "ძებნა." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "ძებნა დასრულდა." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "ეკრანის მკითხველის პარამეტრები თავიდან ჩაიტვირთა." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "მონიშნული ტექსტია: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "მონიშნული წაიშალა." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "მონიშნული აღდგენილია." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "ტექსტის მონიშვნა გაუქმდა." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "ზომა: %d, %d. მდებარეობა: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "სიგანე: %d. სიმაღლე: %d. %d მარცხნიდან. %d ზემოდან." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "საუბარი გამორთულია." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "საუბარი ჩართულია." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "უფროსწრაფად." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "უფრონელა." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "უფრომაღლა." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "უფროდაბლა." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "უფროხმამაღლა." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "უფრორბილად." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "სიჩქარე %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "სიმაღლე %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "ხმის სიმაღლე %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher მოდული %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher ხმა %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "საუბარი მიუწვდომელია." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "საუბარი მიუწვდომელია." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "საუბარი ჩართულია." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "სანიშნის შენახვა შეუძლებელია" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "დიაგნოსტიკური შეტყობინებების დონე: მოკლე" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "დიაგნოსტიკური შეტყობინებების დონე: ყველა" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " წერტილი წერტილი წერტილი" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu გესალმებათ." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu იმალება ტალღების ქვეშ." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "ძილის რეჟიმი ჩართულია %s-სთვის" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "ძილის რეჟიმი გამორთულია %s-სთვის" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "საუბარი მიუწვდომელია." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "ნაპოვნი არაა" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "სტატუსის ზოლი ვერ ვიპოვე" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "სტრიქონი ვერ ვიპოვე" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "სტრუქტურული ნავიგაციის ღილაკები გამორთულია." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "სტრუქტურული ნავიგაციის ღილაკები ჩართულია." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "ნაპოვნი არაა" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "მწკრივი %(row)d, სვეტი %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "ცხრილის დასასრული" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "უჯრედის წარმოთქმა" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "ახლა წარმოთქმა" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "არაერთგვაროვანი" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "ცხრილი არაა." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "სვეტები გადაადგილებულია" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "მწკრივები გადაადგილებულია" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "სვეტი %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "სვეტი %(index)d %(total)d-დან" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "სვეტის ბოლო." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "სვეტის თავი." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "მონიშნულია სვეტი %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "მონიშნულია სვეტები %s-დან %s-მდე" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "მონიშვნა მოხსნილია სვეტებიდან %s-%s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "სვეტის %s მონიშვნა გაუქმდა" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "მწკრივი %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "მწკრივი %(index)d %(total)d-დან" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "მწკრივის დასაწყისი." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "მწკრივის დასასრული." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "მწკრივი წაიშალა." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "ბოლო მწკრივი წაიშალა." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "მწკრივი ჩასმულია." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "წკრივი დაემატა ცხრილის ბოლოში." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "მწკრივი %s მოინიშნა" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "მონიშნულია მწკრივები %s-დან %s-მდე" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "გაუქმდა მონიშვნა მწკრივებისთვის %s-დან %s-მდე" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "მწკრივის %s მონიშვნა გაუქმდა" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "მონიშნული" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "მოუნიშნავი" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H საათი, %M წუთი და %S წამი" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H საათი და %M წუთი" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "უნიკოდი %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "გაუქმება" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "გამეორება" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu ვერსია %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "თეთრი გამოტოვება" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "გადატანა ბოლოსკენ." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "გადატანა თავისკენ." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 ელემენტი" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "უჯრედი %d მწკრივს იკავებს" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d სვეტი" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "უჯრედი %d სვეტს იკავებს" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d სიმბოლო მეტისმეტად ბევრია" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d დიალოგი)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d ფოკუსის არმქონე ფანჯარა" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d ბაიტი" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "ნაპოვნია %d ფაილი" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d ფორმა" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d მიმართულება" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d ელემენტი" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d ორიენტირი" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "ნაპოვნია %d ელემენტი" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "%d ციტატის ბლოკიდან გასვლა." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "%d სიიდან გასვლა." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "უცნობი ზომის სია" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "სია %d ელემენტით" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "უცნობი ზომის ელტა" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "ლენტა %d სტატიით" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "აღწერების სია %d ელემენტით" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d მნიშვნელობა" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "მათემატიკის ცხრილი %d მწკრივით" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d სვეტი" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "ერთმანეთში ჩალაგებული მათემატიკის ცხრილი %d მწკრივით" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d შეტყობინება.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d პროცენტი." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "დოკუმენტის %d პროცენტი წაკითხულია" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d პიქსელი" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s სიმბოლო" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "მონიშნულია %(index)d ელემენტი %(total)d-დან" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "აღმოჩენილია %d ეკრანის წამკითხველის ნაგულისხმევი მალსახმობი." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"აღმოჩენილია %(count)d ეკრანის წამკითხველის მალსახმობი აპლიკაციისთვის " -"%(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d გამოტოვება" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d ტაბულაცია" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d ცხრილი" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "უცნობი ზომის ცხრილი" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "ცხრილი %d სვეტით. მწკრივების რიცხვი უცნობია" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "ცხრილი %d მწკრივით. სვეტების რიცხვი უცნობია" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "ცხრილი %d მწკრივით" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d წამის წინ" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d წუთის წინ" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d საათის წინ" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d დღის წინ" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d უხილავი ბმული" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d გახსნილი ბმული" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "toggle" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(index)d-ზე %(total)d-დან" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d %(total)d-დან" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "%(index)d-ე ელემენტი" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "დონე %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ხის დონე %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "ხის დონე %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "დეტალები %s-სთვის" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "აქვს დეტალები %s-ში" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "მინიშნება" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "ჩასწორებადი ჩამოშლადი სია" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "ჩასწრებადი შემცველობა" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "ლენტა" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "სურათი" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "ანოტაცია" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "მადლობების სია" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "ბოლოსიტყვა" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "დანართი" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "ბიბლიოგრაფიის ჩანაწერი" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "ბიბლიოგრაფია" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "თავი" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "კოლოფონი" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "დასკვნა" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "ყდა" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "კრედიტი" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "კრედიტები" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "მიძღვნა" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "ბოლოსართის" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "ბოლოსართები" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "ეპიგრაფია" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "ეპილოგი" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "მორჩენილი შეცდომები" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "მაგალითი" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "წინასტყვაობა" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "სარჩევი" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "ინდექსი" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "შესავალი" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "გვერდის გახლეჩა" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "გვერდების სია" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "ნაწილი" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "შესავალი" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "პროლოგი" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "ციტატა" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "კდპ" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "ქვესათაური" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "Სარჩევი" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "სათ%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s დონე %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "თარაზული ჩოჩია" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "შვეული ჩოჩია" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "თარაზული სლაიდერი" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "შვეული სლაიდერი" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "თარაზული გამყოფი" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "შვეული გამყოფი" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "გადართვა" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "ხატულის პანელი" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "ბანერი" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "შემცვლელი შემცველობა" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "ინფორმაცია" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "მთავარი შემცველობა" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "ნავიგაცია" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "region" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "ძებნა" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "გახსნილი ბმული" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "მენიუს ღილაკი" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "დალაგებულია ზრდადობით" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "დალაგებულია კლებადობით" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "დალაგებულია" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "დაწკაპუნებადი" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "აკეცილი" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "გაფართოებული" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "აქვს გრძელი აღწერა" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "ჰორიზონტალური" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "ვერტიკალური" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "ჩართულია" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "შემოწმებული არაა" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "ჩართული" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "გამორთული" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "ნაწილობრივ ჩართული" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "დაწოლილი" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "არ არის დაჭერილი" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "მოუნიშნავი" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "მონიშნული" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "მოუნიშნავი" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "მოუნიშნავი" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "ნამყოფი" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "უნახავი" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "განაცრისფრებული" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "მხოლოდ კითხვისთვის" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "მხოლოდ-წასაკითხად" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "აუცილებელია" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "მრავალი მონიშნული" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "არასწორი ჩანაწერი" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "მცდარი" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "არასწორი მართლწერა" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "მართლწერა" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "არასწორი გრამატიკა" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "გრამატიკა" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "ძიება" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "ეკრანის წამკითხველის ძებნის დიალოგი" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_დახურვა" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_ძებნა" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_ძებნა:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "ძებნა:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_ფანჯრის ზედა ნაწილი" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "ფანჯრის ზედა ნაწილი" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "დაწყების ადგილი:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_სიტყვების გადატანა" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "_უკან ძებნა" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "ძებნის მიმართულება:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_დიდი და პატარა ასოების სხვაობა" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "_მხოლოდ მთლიანი სიტყვის დამთხვევა" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "პარამეტრები:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "ნაგულისხმევი" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "დიდი სიმბოლოები" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "ჰიპერბმული" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "სისტემა" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "აპლიკაცია" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "ფანჯარა" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu - ეკრანის მკითხველი" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_დახმარება" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_გადატარება" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_ლეპტოპი" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "კლავიატურის განლაგება" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "აქტიური _პროფილი:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "გაშვებისას ჩასატვირთი პროფილი:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_ჩატვირთვა" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "_შენახვა, როგორც" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_წაშლა" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "პროფილები" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_მიმდინარე მინიშნებები" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "თაგუნას _ქვეშ მყოფი ობიექტის წარმოთქმა" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "თაგუნა" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_დროის ფორმატი:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "_თარიღის ფორმატი:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "თარიღი და დრო" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "განახლებების _წარმოთქმა" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "ბრაილის _განახლებები" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "სიხშირე (წმ):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "ეხება:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "განახლებების _პიპინი" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "მიმდინარეობის პანელის განახლებები" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "_გადახვევის და სწრაფად დაკვრის ჩართვა ყველაფრის წარმოთქმისას" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "სტრუქტურული _ნავიგაციის ჩართვა ყველაფრის წარმოთქმისას" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "ყველაფრის თ_ქმა:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "_ციტატის ბლოკების გამოცხადება ყველაფრის წარმოთქმისას" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "_სიების გამოცხადება ყველაფრის წარმოთქმისას" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "ც_ხრილების გამოცხადება ყველაფრის წარმოთქმისას" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "_პანელების გამოცხადება ყველაფრის წარმოთქმისას" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "_ფორმების გამოცხადება ყველაფრის წარმოთქმისას" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "_ორიენტირების გამოცხადება ყველაფრის წარმოთქმისას" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "ყველაფრის თქმა" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "ელემენტის _პრეზენტაცია:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "მთავარი" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_ხმის სიმაღლე:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_ტონი:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_სიჩქარე:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_პიროვნება:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "ე_ნა:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "საუბრის სინ_თესატორი:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "საუბრის _სისტემა:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_ხმის ტიპი:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_რეგისტრის სტილი:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "ხმის ტიპის მორგება" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "მრავალრეგისტრიანი სტრიქონების _სიტყვებად წარმოთქმა" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "რიცხვების ციფრებად _წარმოთქმა" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "გლობალურ ხმის პარამეტრები" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "ხმა" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_საუბრის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_მეტი შეტყობინება" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "გამოტანილი შეტყობინებების რაოდენობა" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_ყველა" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "პუნქტუაციის დონე" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "მხოლოდ ნაჩვენები ტექსტის წაკითხვა" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "ცარიელი ხაზების წარმოთქმა" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "შეწევისა და მტკიცებების წარმოთქმა" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "ობიექტის მნემონიკის _წარმოთქმა" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "შვილის _მდებარეობის წარმოთქმა" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "სახელმძღვანელოს შეტყობინებების წარმოთქმა" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_სისტემური შეტყობინებები დეტალურია" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "_ფერის სახელების წარმოთქმა" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "ციტატის ბლოკების გამოცხადება ნავიგაციის_ას" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "_სიების გამოცხადება ნავიგაციისას" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "_ცხრილების გამოცხადება ნავიგაციისას" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "_არასწორად დაწერილი სიტყვის მაჩვენებლის წარმოთქმა" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "_პანელების გამოცხადება ნავიგაციისას" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "_ორიენტრირების გამოცხადება ნავიგაციისას" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "_ფორმების გამოცხადება ნავიგაციისას" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "_აღწერის წარმოთქმა" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "სრული მწკრივის წარმოთქმა ელცხ_რილებში" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "სრული მწკრივის წარმოთქმა _დოკუმენტის ცხრილებში" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "სრული მწკრივის წარმოთქმა ინტე_რფეისის ცხრილებში" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "წარმოთქმული შემცველობა" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "საუბარი" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "_ბრაილის მხარდაჭერის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "როლების _აბრევიატურები" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "_ხაზის ბოლოს სიმბოლოს გამორთვა" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "შემოკლებების _ცხრილი:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "შ_ემოკლებული ბრაილის ჩართვა" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "სიტყვების _გადატანის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "ეკრანის მორგება" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "არ_ცერთი" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "მონიშვნის მაჩვენებელი" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "ჰიპერბმულის მაჩვენებელი" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "_სწრაფი შეტყობინებების ჩართვა" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_ხანგრძლივობა (წმ):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "შეტყობინებები _მუდმივია" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "_სისტემური შეტყობინებები დეტალურია" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "სწრაფი შეტყობინებების მორგება" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ბრაილური" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "ღილაკ_ის ექოს ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "_ანბანის ასოების პიპინის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "რიცხვების ღი_ლაკების პიპინის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "_პუნქტუაციის ღილაკების პინის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "გამოტოვები_ს ღილაკის პიპინის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "_მოდიფიკატორი ღილაკების პიპინის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "_ფუნქციური ღილაკების პიპინის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "ქმედები_ს ღილაკების პიპინის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "_ნავიგაციის ღილაკების პიპინის ჩართვა" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "პიპინი სიტყ_ვების მიხედვით" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "პიპინი _წინადადებების მიხედვით" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "ექო" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "ეკრანის მკითხველის _მოდიფიკატორი ღილაკები:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "კლავიატურის ბმები" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "გამოთქმის ლექსიკონი" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_ახალი ჩანაწერი" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_წაშლა" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "გამოთქმა" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_ყველას წარმოთქმა" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_არაფრის წარმოთქმა" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_საწყისი მნიშვნელობებზე დაბრუნება" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "ტექსტის ატრიბუტები" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "_ბოლოში ჩამოტანა" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "_ერთით დაბლა ჩატანა" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "ერთით _მაღლა ატანა" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "_თავში ატანა" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "მონიშნული ატრიბუტის მორგება" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "ბრაილის ინდიკატორი" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "ტექსტის ატრიბუტები" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "ჩართეთ AI ასისტენტი" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_მომწოდებელი:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (ადგილობრივი - უფასო)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API _გასაღების ფაილი:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "გზა API გასაღების ფაილამდე" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "_Claude API გასაღების მიღება" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "გახსენით ბრაუზერი Claude API გასაღების მისაღებად და ავტომატურად შესანახად" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "მოითხოვეთ დადასტურება AI მოქმედებების წინ" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _მოდელი:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "მოდელის სახელი Ollama-სთვის (მაგ., llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _საბოლოო წერტილი:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API საბოლოო წერტილის URL (მაგ., http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "ეკრანის სურათის _ხარისხი:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "დაბალი" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "საშუალო" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "მაღალი" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI ასისტენტი" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "ე_ნა:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "იენი" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_მასშტაბის ფაქტორი:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_ნაცრისფერი გამოსახულება" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "გამოსახულების _ინვერტირება" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_შავ-თეთრი გამოსახულება" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "შავი/თეთრის _ზღვარი:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "ფერების _ანალიზი" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "შემცველობა დაკოპირდა გაცვლის ბუფერში." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a: ალფა, b : ბრავო, c: ჩარლი, d: დელტა, e: ექო, f: ფოქსტროტი, g: გოლფი, h: " -"ჰოტელი, i: ინდია, j: ჯულიეტა,k: კილო, l: ლიმა, m: მაიკი, n: ნოემბერი, o: " -"ოსკარი,p: პაპა, q: ქვებეკი, r: რომეო, s: სიერა, t: ტანგო, u: უნიფორმა, v: " -"ვიქტორი, w: ვისკი,x: იქსრეი, y: იანკი, z: ზულუ" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "ფონის ფერი" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "ფონის სრული სიმაღლე" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "ფონის სურათი" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "მიმართულება" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "ჩასწორებადი" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "საოჯახო სახელი" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "წინა პლანის ფერი" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "წინა პლანის სურათი" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "ფონტის ეფექტი" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "შეწევა" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "შეცდომა" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "უხილავი" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "შევსება" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "ენა" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "მარცხენა ზღვარი" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "ხაზის სიმაღლე" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "პარაგრაფის სტილი" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "პიქსელი ხაზის ზემოთ" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "პიქსელი ხაზის ქვემოთ" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "პიქსელი გადატანის შიგნით" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "მარჯვენა ზღვარი" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "აწევა" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "სასწორი" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "ზომა" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "გაწელვა" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "ხაზის გადასმა" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "სტილი" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "ტექსტის დეკორაცია" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "ტექსტის შებრუნება" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "ტექსტის ჩრდილი" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "ხაზგასმული" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "ვერტიკალური სწორება" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "წონა" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "გადატანის რეჟიმი" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "წერის რეჟიმი" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "სიმართლე" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "მცდარი" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "არა" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "ამოტვიფვრა" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "ამოტვიფრვა" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "კონტური" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "ხაზზემოდანგადასმული" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "გადახაზული" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "ციმციმი" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "შავი" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "ერთი" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "ორმაგი" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "დაბალი" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "სიმბ" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "სიტყვა" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "სიტყვით სიმბოლოთი" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "მარცხნიდან მარჯვნივ" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "მარჯვნიდან მარცხნივ" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "მარცხნივ" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "მარჯვენა" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "center" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "სწორების გარეშე" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "შევსება" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ულტრა შესქელებული" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "ექსტრა შესქელებული" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "შესქელებული" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "ნახევრად-შესქელებული" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "ნორმალური" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "ნახევრად-გაფართოებული" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "გაფართოებული" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "ექსტრა გაფართოებული" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ულტრა გაფართოებული" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "დაპატარავებული დიდი ასოები" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "ირიბი" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "დახრილი" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "ნაგულისხმევი" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "ტექსტის სხეული" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "სათაური" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "baseline" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "ქვე" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "ზე" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "მწვერვალი" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "ტექსტის-ზემოთ" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "შუა" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "ბოლოში" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "ტექსტის-ქვემოთ" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "მემკვიდრეობით" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "მარცხ-მარჯვ-ზემო-ქვემო" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "მარჯვ-მარცხ-ზემო-ქვემო" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "ზემო-ქვემო-მარჯვ-მარცხ" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "ზემო-ქვემო-მარცხ-მარჯვ" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "ქვემო-ზემო-მარჯვ-მარცხ" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "ზემო-ქვემო-მარცხ-მარჯვ" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "მარცხ-მარჯვ" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "მარჯვ-მარცხ" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "ზემო-ქვემო" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "მყარი" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "მართლწერა" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "ჰარე გადასართველად." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "ჰარე გასაშლელად. ზემოთ და ქვემოთ ისრები ელემენტის მოსანიშნად." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Alt+F6 ფოკუსის შვილი ფანჯრებისთვის მისაცემად." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"ელემენტების გადასატანად, ან ისრის ღილაკები გამოიყენეთ, ან აკრიფეთ, რას ეძებთ." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "სისტემურ მენიუში შესასვლელად დააწექით ღილაკს Alt+F11." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "ელემენტის მოსანიშნად გამოიყენეთ ზემოთ და ქვემოთ ღილაკები." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "ჩამოსაშლელად, დააწექით Shift+მარცხნივ." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "ასაკეცად, დააწექით Shift+მარჯვნივ." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "გასააქტიურებლად დააწექით Enter." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "ჩაწერეთ ტექსტი." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "გამოიყენეთ მარჯვნივ და მარცხივ ღილაკები სხვა ჩანართების სანახავად." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "გასააქტიურებლად დააწექით ჰარეს." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"გამოიყენეთ ზემოთ და ქვემოთ ისრები მნიშვნელობის მოსანიშნად. ან აკრიფეთ " -"სასურველი რიცხვითი მნიშვნელობა." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "შესაცვლელად გამოიყენეთ ისრის ღილაკები." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"ნავიგაციისთვის მარცხენა და მარჯვენა ისრები გამოიყენეთ. ელემენტებს შორის " -"სამოძრაოდ ზემოთ და ქვემოთ ისრის ღილაკები დაგჭირდებათ." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "ქვემენიუში შესასვლელად დააწექით მარჯვენა ისარს." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"შესამცირებლად დააწექით მარცხენა ისარს. გასაზრდელად კი მარჯვენას. მინიმუმზე " -"გადასასვლელად ღილაკი Home, მაქსიმუმზე კი End." diff --git a/po/kab.po b/po/kab.po deleted file mode 100644 index 0b12d5a..0000000 --- a/po/kab.po +++ /dev/null @@ -1,9179 +0,0 @@ -# Kabyle translation for cthulhu. -# Copyright (C) 2021 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Selyan Slimane AMIRI , 2021. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2021-11-24 07:27+0100\n" -"Last-Translator: Slimane Selyan Amiri \n" -"Language-Team: Kabyle \n" -"Language: kab_DZ\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 3.0\n" - -msgid "Cthulhu Screen Reader" -msgstr "" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "suneɣ" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "tallunt" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "iccer" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "Amḍan" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "afmiḍi" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "tigezmi" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Rnu tacreṭ" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Geler" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Uksawen ɣer zelmaḍ" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Uksar ɣer zelmaḍ" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "anili" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "Azewwaɣ iḥemqen" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "azegzaw" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "Azegzaw imceɛlel" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "ačinawi" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "azeggwaɣ" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Sefsex" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Ali ɣer" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_IH" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Tignit" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Ulac" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Asusru" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Anezḍay" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Amezwer" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "tigezmi" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "Rnu tacreṭ" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "asnirem" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Yettwabeddel" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "Ta_narit" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Ilɣa" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Ilɣa" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Akkw" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Asnas" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Fenêtre" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Izirig" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Tafyir" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Iḥder n tnebdurt" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Taqfalt" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Tawaṭṭfa" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Taxxamt n ṛcem" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Aglam" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Azwel" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Tugna" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Aglam" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Aglam n temnaḍt" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Aswir" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Aseɣwen" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Rnu ta&ɣawsa" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Taseddart" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Tamlilt" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Aɣrem" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Texte" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Azal" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Tiqfalin" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Izwal" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Tugniwin" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Iseɣwan" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Tibdarint" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Tiseddarin" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tifelwiyin" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Amezwer" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Anagraw" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Asenqad n tira" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Ilɣa" -msgstr[1] "Ilɣa" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Contrôles" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "tuɣalin" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "id iguran" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "Tallelt" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "Kkes" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "Aẓayet" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "tagara" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Inser" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Gedha" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "daw" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "Yugar" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "afaris" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "aẓar uzmir 2" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "afmiḍi" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "ur yegdi ara" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "ddaw neɣ yegda" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "Yugar neɣ yegda" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "gar" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "idetti" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "zur" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "Ulac ifuyla i yettwafen" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ulac" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "ISEM" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Lqem n wesnas-agi" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "AFAYLU" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Ulac ifuyla i yettwafen" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ulac" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Yensa" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Yermed" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "aseɣwen" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Ur yettwaf ara" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "yensa" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "ɣef" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Ilɣa" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Bas" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Afella" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "awalen" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "yensa" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ɣef" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Akkw" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ulac" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "yettwafren" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Ur yettwaf ara" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Ur yettwaf ara" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "yettwafren" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "ssefsu" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d uferdis" -msgstr[1] "%d yiferdisen" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Azal" -msgstr[1] "Azal" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d n upiksil" -msgstr[1] "%d n ipiksilen" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "Efk-d rray" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "amedya" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "aduzwel" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "asnirem" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "anadi" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "ɣef" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "yensa" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "yettwafren" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Nadi" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Mdel" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Nadi ɣef :" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Tixtiṛiyin:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Amezwer" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Anagraw" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Asnas" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Fenêtre" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "Ta_llalt" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Sekles _am" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Kkes" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Taɣerdayt" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Amatu" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Tutlayt:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Taɣect" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Parole" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Paramètres d'affichage" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Kkes" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Wennez" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Imyerren n weḍris" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "_Tutlayt:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "tagara" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "taille" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "idetti" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "ucciḍ" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ulac" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "iman-is" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "double" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "asekkil" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "id iguran" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "amagnu" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "uknan" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Amezwer" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Tafekka n uḍris" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Azwel" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/kk.po b/po/kk.po deleted file mode 100644 index cdee5b4..0000000 --- a/po/kk.po +++ /dev/null @@ -1,9131 +0,0 @@ -# Kazakh translation for cthulhu. -# Copyright (C) 2016 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Baurzhan Muftakhidinov , 2016-2021. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu gnome-3-22\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-19 13:06+0600\n" -"Last-Translator: Baurzhan Muftakhidinov \n" -"Language-Team: Kazakh \n" -"Language: kk\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu экраннан оқитын қолданбасы" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "ауыстырғыш" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "бос аралық" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "пайыз" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "жұлдыз" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "дефис" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "иена" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "санат" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "тіркелген" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "ортасындағы нүкте" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "крест" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "маркер" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "промилле" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "штрих" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "еуро" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "белгі" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Экраннан оқитын қолданбадан шығу" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Алдыңғы бетбелгі орнына өту" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Бетбелгіге өту" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Келесі бетбелгі орнына өту" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Бетбелгіні қосу" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Бетбелгілерді сақтау" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Жоғары сол жақта" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Төменгі сол жақта" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Курсор орны" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Батырмалар тізімін көрсету" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Тақырыптамалар тізімін көрсету" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Суреттер тізімін көрсету" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Сілтемелер тізімін көрсету" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "қара" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "көк" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "шоколад" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "көгілдір" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "алтын" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "сұр" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "жасыл" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "ашық жасыл" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "қызылкүрең" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "қою көк" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "қызғылт-сары" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "қызғылт" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "күлгін" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "қызыл" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "қар" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "қызанақ" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "ақ" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "сары" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "Ба_с тарту" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "Ө_ту" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_ОК" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Таңбаша" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Жоқ" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Команда" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Стандартты" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Әрекеттер" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Бетбелгілер" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Өзгертілген" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Хабарламалар" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Барлығы" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Қолданба" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Терезе" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "Еш_нәрсе" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Сызық" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Батырма" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Жазба" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Жалауша" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Тізімі бар өріс" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Сипаттамасы" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Тақырыптама" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Сурет" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Жазу" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Деңгей" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Сілтеме" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Тізім" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Объект" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Абзац" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Ролі" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Күйі" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Мәтін" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Мәні" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Батырмалар" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Құсбелгілер" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Суреттер" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Сілтемелер" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Тізімдер" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Кестелер" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Стандартты" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Гиперсілтеме" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Жүйе" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d хабарлама" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Басқару элементі" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "жоғары" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "төмен" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "солға" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "оңға" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "сақина" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "кем" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "үлкен" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "барлығы үшін" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "бос көптік" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "дәлелдеудің соңы" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "көбейтінді" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "қосынды" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "кубтық түбір" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "төртінші дәрежелі түбір" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "шексіздік" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "бұрыш" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "бөледі" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "қиылысу" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "бірігу" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "интеграл" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "үлкен немесе тең" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "ақиқат" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "оң жақ үшбұрышы" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "ақ шеңбер" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "қара шеңбер" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ешнәрсе" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "АТЫ" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "БУМА" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Осы бағдарламасының нұсқасы" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ФАЙЛ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "бос" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ешнәрсе" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Сөндірулі" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Іске қосулы" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "сілтеме" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s сілтеме" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Алдыңғысы жоқ." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Ескерту" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Төменнен" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Жоғарыдан" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Профильдер табылмады." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Барлығы" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Жоқ" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu экраннан оқитын қолданбасы" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Мәтін таңдалмаған." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Жолдың басы." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Жолдың соңы." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Жол өшірілді." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Соңғы жол өшірілді." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Жол кірістірілді." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Жол кестенің соңына кірістірілді." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "таңдалған" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "таңдалмаған" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H сағат, %M минут және %S секунд" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H сағат және %M минут" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Юникод %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "болдырмау" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "қайталау" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "бос аралық" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 элемент" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d баған" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d сұхбат)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d байт" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d файл табылды" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d форма" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d тақырыптама" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d нәрсе" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d мәні" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d баған" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d хабарлама.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d пайыз." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d пиксель" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "горизонталды айналдыру жолағы" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "вертикалды айналдыру жолағы" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "горизонталды слайдер" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "вертикалды слайдер" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Таңбашалар панелі" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "ақпарат" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "іздеу" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "қаралған сілтеме" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "мәзір батырмасы" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "сұрыпталған" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "горизонталды" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "таңдалмаған" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "жарамсыз" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Табу" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Жабу" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Табу" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Нені іздеу керек:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Нені іздеу керек:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Соңына жеткенде басына өту" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "К_ері іздеу" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Регистрді ескеру" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Сө_зді тек толығымен сәйкестендіру" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Опциялар:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Стандартты" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Гиперсілтеме" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Жүйе" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Қолданба" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Терезе" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "Cthulhu экраннан оқитын қолданбасы" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Көмек" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "Іске _асыру" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Пернетақта жаймасы" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "Жү_ктеу" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Қала_йша сақтау" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "Ө_шіру" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Профильдер" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Тышқан" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Жиілігі (сек):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Жалпы" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Тіл:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Дауыс" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "Б_арлығы" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Экран баптаулары" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Жоқ" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Брайль" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Пернелер жарлықтары" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "Ө_шіру" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Айтылым" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Тастау" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Мәтін атрибуттары" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Таңдалған атрибутты реттеу" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Брайль индикаторы" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Мәтіндік атрибуттар" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "_Тіл:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "иена" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "фон түсі" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "бағыты" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "қате" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "жасырын" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "тіл" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "нұсқасы" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ешнәрсе" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "қара" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "солға" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "оңға" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "қалыпты" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "курсив" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Стандартты" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Тақырыптама" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/kn.po b/po/kn.po deleted file mode 100644 index ea06c16..0000000 --- a/po/kn.po +++ /dev/null @@ -1,9905 +0,0 @@ -# translation of cthulhu.HEAD.po to Kannada -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# -# Shankar Prasad , 2008. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2008-02-12 15:21+0530\n" -"Last-Translator: Shankar Prasad \n" -"Language-Team: Kannada \n" -"Language: kn\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: KBabel 1.11.4\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "ಆದ್ಯತೆಗಳು" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -#, fuzzy -msgctxt "shortbraille" -msgid "form" -msgstr "ಫಾರ್ಮ್" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -#, fuzzy -msgid "Czech Grade 1" -msgstr "1" - -#: src/cthulhu/brltablenames.py:45 -#, fuzzy -msgid "Spanish Grade 1" -msgstr "ಸ್ಪ್ಯಾನಿಷ್ 1" - -#: src/cthulhu/brltablenames.py:49 -#, fuzzy -msgid "Canada French Grade 2" -msgstr "ಕೆನಡ ಫ್ರೆಂಚ್ 2" - -#: src/cthulhu/brltablenames.py:53 -#, fuzzy -msgid "France French Grade 2" -msgstr "ಫ್ರಾನ್ಸ್‍ ಫ್ರೆಂಚ್ 2" - -#: src/cthulhu/brltablenames.py:57 -#, fuzzy -msgid "Latvian Grade 1" -msgstr "1" - -#: src/cthulhu/brltablenames.py:61 -#, fuzzy -msgid "Netherlands Dutch Grade 1" -msgstr "ನೆದರ್ಲ್ಯಾಂಡ್ಸ್‍ 1" - -#: src/cthulhu/brltablenames.py:65 -#, fuzzy -msgid "Norwegian Grade 0" -msgstr "೦" - -#: src/cthulhu/brltablenames.py:69 -#, fuzzy -msgid "Norwegian Grade 1" -msgstr "1" - -#: src/cthulhu/brltablenames.py:73 -#, fuzzy -msgid "Norwegian Grade 2" -msgstr "2" - -#: src/cthulhu/brltablenames.py:77 -#, fuzzy -msgid "Norwegian Grade 3" -msgstr "3" - -#: src/cthulhu/brltablenames.py:81 -#, fuzzy -msgid "Polish Grade 1" -msgstr "1" - -#: src/cthulhu/brltablenames.py:85 -#, fuzzy -msgid "Portuguese Grade 1" -msgstr "1" - -#: src/cthulhu/brltablenames.py:89 -#, fuzzy -msgid "Swedish Grade 1" -msgstr "ಸ್ವೀಡಿಶ್ 1" - -#: src/cthulhu/brltablenames.py:93 -#, fuzzy -msgid "Arabic Grade 1" -msgstr "ಅರೇಬಿಕ್ 1" - -#: src/cthulhu/brltablenames.py:97 -#, fuzzy -msgid "Welsh Grade 1" -msgstr "1" - -#: src/cthulhu/brltablenames.py:101 -#, fuzzy -msgid "Welsh Grade 2" -msgstr "2" - -#: src/cthulhu/brltablenames.py:105 -#, fuzzy -msgid "German Grade 0" -msgstr "ಜರ್ಮನ್ ೦" - -#: src/cthulhu/brltablenames.py:109 -#, fuzzy -msgid "German Grade 1" -msgstr "ಜರ್ಮನ್ 1" - -#: src/cthulhu/brltablenames.py:113 -#, fuzzy -msgid "German Grade 2" -msgstr "ಜರ್ಮನ್ 2" - -#: src/cthulhu/brltablenames.py:117 -#, fuzzy -msgid "U.K. English Grade 2" -msgstr "U K 2" - -#: src/cthulhu/brltablenames.py:121 -#, fuzzy -msgid "U.K. English Grade 1" -msgstr "U K 1" - -#: src/cthulhu/brltablenames.py:125 -#, fuzzy -msgid "U.S. English Grade 1" -msgstr "U S 1" - -#: src/cthulhu/brltablenames.py:129 -#, fuzzy -msgid "U.S. English Grade 2" -msgstr "U S 2" - -#: src/cthulhu/brltablenames.py:133 -#, fuzzy -msgid "Canada French Grade 1" -msgstr "ಕೆನಡ ಫ್ರೆಂಚ್ 1" - -#: src/cthulhu/brltablenames.py:137 -#, fuzzy -msgid "France French Grade 1" -msgstr "ಫ್ರಾನ್ಸ್‍ ಫ್ರೆಂಚ್ 2" - -#: src/cthulhu/brltablenames.py:141 -#, fuzzy -msgid "Greek Grade 1" -msgstr "ಗ್ರೀಕ್ 1" - -#: src/cthulhu/brltablenames.py:145 -#, fuzzy -msgid "Hindi Grade 1" -msgstr "ಹಿಂದಿ 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -#, fuzzy -msgid "Hungarian Grade 1" -msgstr "1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "ಜರ್ಮನ್ 2" - -#: src/cthulhu/brltablenames.py:161 -#, fuzzy -msgid "Italian Grade 1" -msgstr "1" - -#: src/cthulhu/brltablenames.py:165 -#, fuzzy -msgid "Belgium Dutch Grade 1" -msgstr "ಬೆಲ್ಜಿಯಮ್ 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -#, fuzzy -msgid "space" -msgstr "ಖಾಲಿ ಜಾಗ" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "ಟ್ಯಾಬ್" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "" - -#: src/cthulhu/chnames.py:66 -#, fuzzy -msgid "number" -msgstr "ಸಂಖ್ಯೆ" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "" - -#: src/cthulhu/chnames.py:86 -#, fuzzy -msgid "left paren" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/chnames.py:90 -#, fuzzy -msgid "right paren" -msgstr "ರೈಟ್" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "" - -#: src/cthulhu/chnames.py:106 -#, fuzzy -msgid "dash" -msgstr "ಡ್ಯಾಶ್" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "" - -#: src/cthulhu/chnames.py:146 -#, fuzzy -msgid "left bracket" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "" - -#: src/cthulhu/chnames.py:154 -#, fuzzy -msgid "right bracket" -msgstr "ರೈಟ್" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -#, fuzzy -msgid "left brace" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "" - -#: src/cthulhu/chnames.py:178 -#, fuzzy -msgid "right brace" -msgstr "ರೈಟ್" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -#, fuzzy -msgid "section" -msgstr "ವಿಭಾಗ" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -#, fuzzy -msgid "superscript 2" -msgstr "2" - -#: src/cthulhu/chnames.py:263 -#, fuzzy -msgid "superscript 3" -msgstr "3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -#, fuzzy -msgid "acute" -msgstr "e" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "" - -#: src/cthulhu/chnames.py:275 -#, fuzzy -msgid "paragraph marker" -msgstr "ಪ್ಯಾರಾಗ್ರಾಫ್" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -#, fuzzy -msgid "superscript 1" -msgstr "1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "ರೈಟ್" - -#: src/cthulhu/chnames.py:299 -#, fuzzy -msgid "one fourth" -msgstr "ನಾಲ್ಕನೆಯ" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -#, fuzzy -msgid "three fourths" -msgstr "ಮೂರು" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -#, fuzzy -msgid "e grave" -msgstr "e" - -#: src/cthulhu/chnames.py:479 -#, fuzzy -msgid "e acute" -msgstr "e" - -#: src/cthulhu/chnames.py:483 -#, fuzzy -msgid "e circumflex" -msgstr "e" - -#: src/cthulhu/chnames.py:487 -#, fuzzy -msgid "e umlaut" -msgstr "e" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -#, fuzzy -msgid "n tilde" -msgstr "n" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -#, fuzzy -msgid "y acute" -msgstr "y" - -#: src/cthulhu/chnames.py:567 -#, fuzzy -msgid "y umlaut" -msgstr "y" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "ಡ್ಯಾಶ್" - -#: src/cthulhu/chnames.py:584 -#, fuzzy -msgid "left single quote" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "ರೈಟ್" - -#: src/cthulhu/chnames.py:593 -#, fuzzy -msgid "single low quote" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/chnames.py:597 -#, fuzzy -msgid "left double quote" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/chnames.py:601 -#, fuzzy -msgid "right double quote" -msgstr "ರೈಟ್" - -#: src/cthulhu/chnames.py:605 -#, fuzzy -msgid "double low quote" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -#, fuzzy -msgid "superscript 0" -msgstr "2" - -#: src/cthulhu/chnames.py:676 -#, fuzzy -msgid "superscript 4" -msgstr "2" - -#: src/cthulhu/chnames.py:680 -#, fuzzy -msgid "superscript 5" -msgstr "2" - -#: src/cthulhu/chnames.py:684 -#, fuzzy -msgid "superscript 6" -msgstr "2" - -#: src/cthulhu/chnames.py:688 -#, fuzzy -msgid "superscript 7" -msgstr "2" - -#: src/cthulhu/chnames.py:692 -#, fuzzy -msgid "superscript 8" -msgstr "2" - -#: src/cthulhu/chnames.py:696 -#, fuzzy -msgid "superscript 9" -msgstr "2" - -#: src/cthulhu/chnames.py:700 -#, fuzzy -msgid "superscript plus" -msgstr "2" - -#: src/cthulhu/chnames.py:704 -#, fuzzy -msgid "superscript minus" -msgstr "2" - -#: src/cthulhu/chnames.py:708 -#, fuzzy -msgid "superscript equals" -msgstr "2" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "2" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "2" - -#: src/cthulhu/chnames.py:720 -#, fuzzy -msgid "superscript n" -msgstr "2" - -#: src/cthulhu/chnames.py:724 -#, fuzzy -msgid "subscript 0" -msgstr "2" - -#: src/cthulhu/chnames.py:728 -#, fuzzy -msgid "subscript 1" -msgstr "1" - -#: src/cthulhu/chnames.py:732 -#, fuzzy -msgid "subscript 2" -msgstr "2" - -#: src/cthulhu/chnames.py:736 -#, fuzzy -msgid "subscript 3" -msgstr "3" - -#: src/cthulhu/chnames.py:740 -#, fuzzy -msgid "subscript 4" -msgstr "2" - -#: src/cthulhu/chnames.py:744 -#, fuzzy -msgid "subscript 5" -msgstr "2" - -#: src/cthulhu/chnames.py:748 -#, fuzzy -msgid "subscript 6" -msgstr "2" - -#: src/cthulhu/chnames.py:752 -#, fuzzy -msgid "subscript 7" -msgstr "2" - -#: src/cthulhu/chnames.py:756 -#, fuzzy -msgid "subscript 8" -msgstr "2" - -#: src/cthulhu/chnames.py:760 -#, fuzzy -msgid "subscript 9" -msgstr "2" - -#: src/cthulhu/chnames.py:764 -#, fuzzy -msgid "subscript plus" -msgstr "2" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "2" - -#: src/cthulhu/chnames.py:772 -#, fuzzy -msgid "subscript equals" -msgstr "2" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "ರೈಟ್" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "ಲೆಫ್ಟ್‍ ಕ್ಲಿಕ್ ನಲ್ಲಿ ಅಂಶ." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "ರೈಟ್ ಕ್ಲಿಕ್ ನಲ್ಲಿ ಅಂಶ." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "am I." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "am I." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "ಸ್ಥಿತಿ ಪಟ್ಟಿ" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "ಸ್ಥಿತಿ ಪಟ್ಟಿ" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "ಪತ್ತೆ ಹಚ್ಚು." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "ಹುಡುಕಾಟಗಳು ಗೆ ವಾಕ್ಯ." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "ಹುಡುಕಾಟಗಳು ಗೆ ವಾಕ್ಯ." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "ಎಂಡ್." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "ಹೋಮ್." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "ಎಂಡ್." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "ಎಂಡ್." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "ಎಂಡ್." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "ಎಂಡ್." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "ಲೆಫ್ಟ್‍." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "ಅಂಶ." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "ಎಂಡ್." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "ನೊಂದಿಗೆ." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "ಬ್ರೈಲ್ ಲೆಫ್ಟ್‍." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "ಬ್ರೈಲ್ ರೈಟ್." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "ನೊಂದಿಗೆ ಕೀಲಿಮಣೆ." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "ಎಸ್ಕೇಪ್." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "ಆರಿಸು." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "ಆರಿಸು." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "ಶೀರ್ಷಿಕೆ ಮಟ್ಟ." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "ಬುಕ್-ಮಾರ್ಕ್ am I ನೊಂದಿಗೆ." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "ಫಾರ್ಮ್." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "ಸೇರಿಸು." - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "ಸೇರಿಸು." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "ಉಳಿಸು." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "ಮಾತನಾಡು ಬ್ರೈಲ್ ಸಂದೇಶ." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "ನೊಂದಿಗೆ." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "ನೊಂದಿಗೆ." - -#: src/cthulhu/cmdnames.py:642 -#, fuzzy -msgid "Line Left" -msgstr "ಸಾಲು ಲೆಫ್ಟ್‍" - -#: src/cthulhu/cmdnames.py:647 -#, fuzzy -msgid "Line Right" -msgstr "ಸಾಲು ರೈಟ್" - -#: src/cthulhu/cmdnames.py:652 -#, fuzzy -msgid "Line Up" -msgstr "ಸಾಲು ಅಪ್" - -#: src/cthulhu/cmdnames.py:657 -#, fuzzy -msgid "Line Down" -msgstr "ಸಾಲು ಡೌನ್" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -#, fuzzy -msgid "Top Left" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "ರೈಟ್" - -#: src/cthulhu/cmdnames.py:677 -#, fuzzy -msgid "Cursor Position" -msgstr "ಸ್ಥಾನ" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "ಸ್ಥಾನ" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "ಸಾಲು" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "ಫಾರ್ಮ್." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "ಫಾರ್ಮ್." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "ಎಂಡ್." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "ಎಂಡ್." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "ವಿಸ್ತರಿಸಲಾದ." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ ಮಟ್ಟ." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ ಮಟ್ಟ." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "ಅವಲೋಕಿಸು." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "ಗೆ " - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "ಗೆ " - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "ಗೆ " - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "ನಲ್ಲಿ." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "ಪ್ರದರ್ಶಕ ಆಯ್ಕೆಗಳು" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "ಶೀರ್ಷಿಕೆ." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "ಶೀರ್ಷಿಕೆ." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "ಫಾರ್ಮ್." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "ಫಾರ್ಮ್." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "m" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "m" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "ಫಾರ್ಮ್." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "ಫಾರ್ಮ್." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "ಶೀರ್ಷಿಕೆ." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "ಶೀರ್ಷಿಕೆ." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "ಶೀರ್ಷಿಕೆ ಮಟ್ಟ." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "ಶೀರ್ಷಿಕೆ ಮಟ್ಟ." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "ಇಲ್ಲ ಮಟ್ಟ." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "ಒಳಗಿನ ಚೌಕಟ್ಟು" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "ಶೀರ್ಷಿಕೆ." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "ಪ್ರದರ್ಶಕ ಆಯ್ಕೆಗಳು" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "ಪಟ್ಟಿ ಅಂಶ." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "ಪಟ್ಟಿ ಅಂಶ." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "ಕೊನೆಯ." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "ಕೊನೆಯ." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "ಅವಲೋಕಿಸು." - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "ನೊಂದಿಗೆ ಕೀಲಿಮಣೆ." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "ನೊಂದಿಗೆ ಕೀಲಿಮಣೆ." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "ಶೀರ್ಷಿಕೆ." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "ಶೀರ್ಷಿಕೆ." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "ಶೀರ್ಷಿಕೆ." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "ರೇಡಿಯೋ ಗುಂಡಿ" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "ಡೌನ್." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "ಮೊದಲ ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "ಕೊನೆಯ ಟೇಬಲ್." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "ಲೆಫ್ಟ್‍." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "ರೈಟ್." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "ಅಪ್." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "ಹೊರಳುಗುಂಡಿ" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "ಪಟ್ಟಿ ಅಂಶ." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "ಹಿಂದಿ 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "ರೈಟ್" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "ರೈಟ್ ಕಂಟ್ರೋಲ್" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "ರೈಟ್" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "ರೈಟ್" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "ರೈಟ್" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "ರೈಟ್" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "ರೈಟ್ ಆಲ್ಟ್‍" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "ರೈಟ್" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "ಚಿತ್ರ" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "tre" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s ತೆರೆ" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "ಟ್ಯಾಬ್" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "ಖಾಲಿ ಜಾಗ" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "ಖಾಲಿ ಜಾಗ" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "ಸಂಪೂರ್ಣ ತೆರೆ" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -#, fuzzy -msgid "Dot _7" -msgstr "ಚುಕ್ಕೆ 7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -#, fuzzy -msgid "Dot _8" -msgstr "ಚುಕ್ಕೆ 8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -#, fuzzy -msgid "Dots 7 an_d 8" -msgstr "ಚುಕ್ಕೆಗಳು 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "ಚಿಹ್ನೆ" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "ಯಾವುದೂ ಇಲ್ಲ" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "ಕಾಗುಣಿತ ಪರೀಕ್ಷಣೆ:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -#, fuzzy -msgid "Speak messages from" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/guilabels.py:168 -#, fuzzy -msgid "All cha_nnels" -msgstr "ಎಲ್ಲಾ" - -#: src/cthulhu/guilabels.py:173 -#, fuzzy, python-format -msgid "All channels when an_y %s window is active" -msgstr "ಎಲ್ಲಾ y ಸಕ್ರಿಯ" - -#: src/cthulhu/guilabels.py:178 -#, fuzzy -msgid "A channel only if its _window is active" -msgstr "A ಸಕ್ರಿಯ" - -#: src/cthulhu/guilabels.py:182 -#, fuzzy -msgid "_Speak Chat Room name" -msgstr "ಮಾತನಾಡು ಕೋಣೆ" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -#, fuzzy -msgid "Default Synthesizer" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -#, fuzzy -msgid "Replacement String" -msgstr "ಬದಲಾವಣೆ" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -#, fuzzy -msgid "C_urrent location" -msgstr "C" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -#, fuzzy -msgid "Find Options" -msgstr "ಪತ್ತೆ ಹಚ್ಚು ಆಯ್ಕೆಗಳು" - -#: src/cthulhu/guilabels.py:259 -#, fuzzy -msgid "Onl_y speak changed lines during find" -msgstr "y" - -#: src/cthulhu/guilabels.py:265 -#, fuzzy -msgid "Speak results during _find" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "" - -#: src/cthulhu/guilabels.py:275 -#, fuzzy -msgid "Key Binding" -msgstr "ಕೀಲಿ" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "ವಿಭಾಗ" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "ಉಳಿಸು." - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "ಪಟ್ಟಿ" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "ಮಾರ್ಪಡಿಸಲಾದ" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "ಗಣಕತೆರೆ(_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "ಸೂಚನೆ %s" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "ಸೂಚನೆ %s" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "ಆದ್ಯತೆಗಳು ಗೆ" - -#: src/cthulhu/guilabels.py:396 -#, fuzzy -msgid "Mark in braille" -msgstr "ಬ್ರೈಲ್" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "ಎಲ್ಲಾ(_A)" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "ಅನ್ವಯ" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "ವಿಂಡೊ" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "ಯಾವುದೂ ಇಲ್ಲ(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -#, fuzzy -msgid "M_ost" -msgstr "M" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "ಸಾಲು" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "ಗುಂಡಿ" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "ಶೀರ್ಷಿಕೆ" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "ಗುರುತು ಪೆಟ್ಟಿಗೆ" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "ಕಾಂಬೋ ಪೆಟ್ಟಿಗೆ" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "ಶೀರ್ಷಿಕೆ" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "ಶೀರ್ಷಿಕೆ" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "ಒಳಗಿನಚೌಕಟ್ಟು" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "ಚಿತ್ರ" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "ಲೇಬಲ್" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -#, fuzzy -msgctxt "structural navigation" -msgid "Level" -msgstr "ಮಟ್ಟ" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "ಕೊಂಡಿ" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "ಪಟ್ಟಿ" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ಅಂಶಪಟ್ಟಿ" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "ಪ್ಯಾರಾಗ್ರಾಫ್" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "ರೇಡಿಯೋ ಗುಂಡಿ" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "ಸ್ಥಿತಿ" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "ಪಠ್ಯ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "ಗುಂಡಿ" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "ಗುರುತು ಪೆಟ್ಟಿಗೆ" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "ಕಾಂಬೋ ಪೆಟ್ಟಿಗೆ" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "ಶೀರ್ಷಿಕೆ" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "ಒಳಗಿನಚೌಕಟ್ಟು" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "ಚಿತ್ರ" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "ಇಲ್ಲ ಮಟ್ಟ." - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "ಕೊಂಡಿ" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "ಪಟ್ಟಿ" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ಅಂಶಪಟ್ಟಿ" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "ಪ್ಯಾರಾಗ್ರಾಫ್" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "ರೇಡಿಯೋ ಗುಂಡಿ" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "ಟೇಬಲ್" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/guilabels.py:801 -#, fuzzy -msgid "Page Navigation" -msgstr "ಪುಟ" - -#: src/cthulhu/guilabels.py:807 -#, fuzzy -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "ಆರಂಭ ಪುಟ ಮೊದಲ" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "ಆರಂಭ ಪುಟ ಮೊದಲ" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, fuzzy, python-format -msgid "%s default voice" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "ಹೈಪರ್-ಲಿಂಕ್" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "ಕಾಗುಣಿತ ಪರೀಕ್ಷಣೆ:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -#, fuzzy -msgid "Table Navigation" -msgstr "ಪಟ್ಟಿ" - -#: src/cthulhu/guilabels.py:900 -#, fuzzy -msgid "Skip _blank cells" -msgstr "ಉಪೇಕ್ಷಿಸು" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/guilabels.py:909 -#, fuzzy -msgid "Speak _cell coordinates" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/guilabels.py:914 -#, fuzzy -msgid "Speak _multiple cell spans" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/guilabels.py:918 -#, fuzzy -msgid "Attribute Name" -msgstr "ಹೆಸರು" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "ಪುಟ" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "ಸೂಚನೆ %s" -msgstr[1] "ಸೂಚನೆ %s" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt_R" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "ಲೆಫ್ಟ್‍ ಕಂಟ್ರೋಲ್" - -#: src/cthulhu/keynames.py:60 -#, fuzzy -msgid "left shift" -msgstr "ಲೆಫ್ಟ್‍ ಶಿಫ್ಟ್‍" - -#: src/cthulhu/keynames.py:64 -#, fuzzy -msgid "left alt" -msgstr "ಲೆಫ್ಟ್‍ ಆಲ್ಟ್‍" - -#: src/cthulhu/keynames.py:68 -#, fuzzy -msgid "left control" -msgstr "ಲೆಫ್ಟ್‍ ಕಂಟ್ರೋಲ್" - -#: src/cthulhu/keynames.py:72 -#, fuzzy -msgid "right shift" -msgstr "ರೈಟ್ ಶಿಫ್ಟ್‍" - -#: src/cthulhu/keynames.py:76 -#, fuzzy -msgid "right alt" -msgstr "ರೈಟ್ ಆಲ್ಟ್‍" - -#: src/cthulhu/keynames.py:80 -#, fuzzy -msgid "right control" -msgstr "ರೈಟ್ ಕಂಟ್ರೋಲ್" - -#: src/cthulhu/keynames.py:84 -#, fuzzy -msgid "left meta" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/keynames.py:88 -#, fuzzy -msgid "right meta" -msgstr "ರೈಟ್" - -#: src/cthulhu/keynames.py:92 -#, fuzzy -msgid "num lock" -msgstr "ನಮ್ ಲಾಕ್" - -#: src/cthulhu/keynames.py:96 -#, fuzzy -msgid "caps lock" -msgstr "ಕಾಪ್ಸ್‍ ಲಾಕ್" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "ಕಾಪ್ಸ್‍ ಲಾಕ್" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "ಖಾಲಿ ಜಾಗ" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "page down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "ಲೆಫ್ಟ್‍ ಆಲ್ಟ್‍" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "ರೈಟ್ ಆಲ್ಟ್‍" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "ರೈಟ್" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "ಮೆನು" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -#, fuzzy -msgid "delete" -msgstr "ಅಳಿಸಿ ಹಾಕು(_D)" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "wnd" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -#, fuzzy -msgid "circumflex" -msgstr "e" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "2" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "ಸನ್ನಿವೇಶ " - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "ಬಾಣದ ಗುರುತು" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "ಬಾಣದ ಗುರುತು" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "e" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "dat" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "ಸ್ವಯಂಪೂರ್ಣಗೊಳಿಕೆ" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "ಖಾಲಿ" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "ಕೊನೆ." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "ವಿಭಜಕ" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "ರೈಟ್ ಆಲ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "ಪದರುಳ್ಳ ಫಲಕ" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "ವಿಭಜಕ" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "ವಿಭಾಗ" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "ಒಳಗಿನ ಚೌಕಟ್ಟು" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "ಅಪ್ಡೇಟ್:" - -#: src/cthulhu/mathsymbols.py:1512 -#, fuzzy -msgctxt "math symbol" -msgid "triple integral" -msgstr "ಅಪ್ಡೇಟ್:" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -#, fuzzy -msgctxt "math symbol" -msgid "surface integral" -msgstr "ಅಪ್ಡೇಟ್:" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "n" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "n" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "ಬೇರೆ ತಾಣ" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "2" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "ಡ್ಯಾಶ್" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "left tab" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "ವಿಭಾಗ" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "ಆರಿಸದೆ ಇರುವ" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "ಚಿತ್ರ" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "ಒಳಗಿನ ಚೌಕಟ್ಟು" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "ವಿಭಜಕ" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "ಲೆಫ್ಟ್‍ ಆಲ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "ರೈಟ್ ಆಲ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "ರೈಟ್" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "ಖಾಲಿ ಜಾಗ" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "ಖಾಲಿ ಜಾಗ" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "ಖಾಲಿ ಜಾಗ" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "ಅನ್ವಯ" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "ಶಕ್ತಗೊಂಡ." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ಚಿಹ್ನೆ" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr " ." - -#: src/cthulhu/messages.py:170 -#, fuzzy -msgid "Cthulhu is controlling the caret." -msgstr " ." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "ಸೆಲ್ %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "ಅಂಶ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:193 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "ಅಂಶ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:203 -#, fuzzy -msgid "Prevent use of option" -msgstr "ಆಯ್ಕೆ" - -#: src/cthulhu/messages.py:207 -#, fuzzy -msgid "Force use of option" -msgstr "ಒತ್ತಾಯಿಸು ಆಯ್ಕೆ" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -#, fuzzy -msgid "Use alternate directory for user preferences" -msgstr "ಗೆ" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "ಈ ಸಹಾಯ ಸಂದೇಶವನ್ನು ತೋರಿಸು" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -#, fuzzy -msgid "Set up user preferences (text version)" -msgstr "ಅಪ್" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "ಅಪ್" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "e" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, fuzzy, python-format -msgid "Message from chat room %s" -msgstr "ಸಂದೇಶ" - -#: src/cthulhu/messages.py:385 -#, fuzzy, python-format -msgid "New chat tab %s" -msgstr "ಹೊಸ ಟ್ಯಾಬ್" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "ವಿಭಾಗ" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "m" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ ಗುಂಡಿಯು %s ಆಗಿದೆ" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ ಗುಂಡಿಯು %s ಆಗಿದೆ" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ ಗುಂಡಿಯು %s ಆಗಿದೆ" - -#: src/cthulhu/messages.py:518 -#, fuzzy, python-format -msgid " subscript %s" -msgstr "2" - -#: src/cthulhu/messages.py:524 -#, fuzzy, python-format -msgid " superscript %s" -msgstr "2" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:535 -#, fuzzy -msgid "entire document selected" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:548 -#, fuzzy -msgid "document selected from cursor position" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:554 -#, fuzzy -msgid "document unselected from cursor position" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:560 -#, fuzzy -msgid "document selected to cursor position" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:566 -#, fuzzy -msgid "document unselected to cursor position" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:571 -#, fuzzy, python-format -msgid "Dynamic column header set for row %d" -msgstr "ಗೆ " - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, fuzzy, python-format -msgid "Dynamic row header set for column %s" -msgstr "ಗೆ" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ಖಾಲಿ" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f ಕಿಲೋಬೈಟ್‍ಗಳು" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f ಮೆಗಾಬೈಟ್‍ಗಳು" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "ಯಾವುದೆ ಕಡತ ಪತ್ತೆಯಾಗಿಲ್ಲ." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "ಪುಟಿಕೆ ಮೆನು" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, fuzzy, python-format -msgid "The key entered is already bound to %s" -msgstr " " - -#: src/cthulhu/messages.py:701 -#, fuzzy, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "ಕೀಲಿ ನಮೂದಿಸು." - -#: src/cthulhu/messages.py:706 -#, fuzzy, python-format -msgid "The new key is: %s" -msgstr " " - -#: src/cthulhu/messages.py:711 -#, fuzzy -msgid "Key binding deleted. Press enter to confirm." -msgstr "ಕೀಲಿ ನಮೂದಿಸು." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -#, fuzzy -msgid "enter new key" -msgstr "ನಮೂದಿಸು" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "ಯಾವುದೂ ಇಲ್ಲ" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "ಸಾಲು" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "ಗುಪ್ತಪದ" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "e" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "wnd" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "ಮೂಲ ಫಲಕ" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "ಮೂಲ ಫಲಕ" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "ಮೂಲ ಫಲಕ" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "2" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "2" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "2" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "2" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "2" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "2" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "ಟೇಬಲ್" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "ಟ್ರೀ ಟೇಬಲ್" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "ಟೇಬಲ್" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/messages.py:1192 -#, fuzzy -msgid "Learn mode. Press escape to exit." -msgstr "ಎಸ್ಕೇಪ್." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "ಅನಿಮೇಶನ್" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "ಪುಟ" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1292 -#, fuzzy -msgid "leaving table." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "ಪಟ್ಟಿ" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:1471 -#, fuzzy -msgid "line selected down from cursor position" -msgstr "ಆರಿಸಲಾದ ಡೌನ್" - -#: src/cthulhu/messages.py:1477 -#, fuzzy -msgid "line selected up from cursor position" -msgstr "ಆರಿಸಲಾದ ಅಪ್" - -#: src/cthulhu/messages.py:1484 -#, fuzzy -msgid "line unselected down from cursor position" -msgstr "ಆರಿಸಲಾದ ಡೌನ್" - -#: src/cthulhu/messages.py:1491 -#, fuzzy -msgid "line unselected up from cursor position" -msgstr "ಆರಿಸಲಾದ ಅಪ್" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -#, fuzzy -msgid "line selected from start to previous cursor position" -msgstr "ಆರಿಸಲಾದ ಅಪ್" - -#: src/cthulhu/messages.py:1511 -#, fuzzy -msgid "line selected to end from previous cursor position" -msgstr "ಆರಿಸಲಾದ ಡೌನ್" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ಕೊಂಡಿ" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ಅದೆ ಪುಟ" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ಅದೆ ತಾಣ" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "ಬೇರೆ ತಾಣ" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s ಕೊಂಡಿ" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -#, fuzzy -msgid "All live regions set to off" -msgstr "ಎಲ್ಲಾ" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "ಮಟ್ಟ" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -#, fuzzy -msgid "Live regions monitoring on" -msgstr "ನಲ್ಲಿ" - -#: src/cthulhu/messages.py:1642 -#, fuzzy -msgid "no live message saved" -msgstr "ಸಂದೇಶ" - -#: src/cthulhu/messages.py:1649 -#, fuzzy -msgid "Live region support is off" -msgstr " " - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "ಯಾವುದೆ ಕಡತ ಪತ್ತೆಯಾಗಿಲ್ಲ." - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "C" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "ಆಫ್" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "ಆನ್" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "ಕಾಗುಣಿತ ತಪ್ಪಾದ ಪದ:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, fuzzy, python-format -msgid "Context is %s" -msgstr "ಸನ್ನಿವೇಶ " - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "ಮೌಸ್ ಅಶಕ್ತಗೊಂಡ." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "ಮೌಸ್ ಶಕ್ತಗೊಂಡ." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "ಪಟ್ಟಿ." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "ಮಟ್ಟ" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1863 -#, fuzzy -msgid "No focus" -msgstr "ಇಲ್ಲ" - -#: src/cthulhu/messages.py:1867 -#, fuzzy -msgid "No application has focus." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1872 -#, fuzzy -msgid "No more blockquotes." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1888 -#, fuzzy -msgid "No more large objects." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1903 -#, fuzzy -msgid "No more entries." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1908 -#, fuzzy -msgid "No more form fields." -msgstr "ಇಲ್ಲ ಫಾರ್ಮ್." - -#: src/cthulhu/messages.py:1913 -#, fuzzy -msgid "No more headings." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1919 -#, fuzzy, python-format -msgid "No more headings at level %d." -msgstr "ಇಲ್ಲ ಮಟ್ಟ." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "ಒಳಗಿನ ಚೌಕಟ್ಟು" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1935 -#, fuzzy -msgid "No landmark found." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1945 -#, fuzzy -msgid "No more lists." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "ಇಲ್ಲ ಪಟ್ಟಿ ಅಂಶಗಳು." - -#: src/cthulhu/messages.py:1957 -#, fuzzy -msgid "No more live regions." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1982 -#, fuzzy -msgid "No more unvisited links." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1987 -#, fuzzy -msgid "No more visited links." -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "ಆರಿಸದೆ ಇರುವ" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "ಸೂಚನೆ %s" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "ಕೆಳಗಿನ(_B):" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "ಉಪಕರಣ ಸಲಹೆ" - -#: src/cthulhu/messages.py:2013 -#, fuzzy -msgid "No notification messages" -msgstr "ಸೂಚನೆ %s" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "ಗುಪ್ತಪದ" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "ಆಫ್" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ಆನ್" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ. ದಯವಿಟ್ಟು ಕಾಯಿರಿ." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -#, fuzzy -msgid "page selected from cursor position" -msgstr "ಪುಟ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2083 -#, fuzzy -msgid "page selected to cursor position" -msgstr "ಪುಟ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2089 -#, fuzzy -msgid "page unselected from cursor position" -msgstr "ಪುಟ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2095 -#, fuzzy -msgid "page unselected to cursor position" -msgstr "ಪುಟ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "ಪುಟ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "ಪುಟ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "ಪುಟ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "ಪುಟ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2127 -#, fuzzy -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "n ಮೊದಲು." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "ಯಾವುದೆ ಕಡತ ಪತ್ತೆಯಾಗಿಲ್ಲ." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "ಎಲ್ಲಾ(_A)" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr " ಮಟ್ಟ" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "ಯಾವುದೂ ಇಲ್ಲ" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "ಹುಡುಕಲಾಗುತ್ತಿದೆ." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "ಹುಡುಕುವುದು ಪೂರ್ಣಗೊಂಡಿದೆ." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr " ." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "ಸನ್ನಿವೇಶ " - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "ಆರಿಸು:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "ಆರಿಸದೆ ಇರುವ" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -#, fuzzy -msgid "Speech disabled." -msgstr "ಅಶಕ್ತಗೊಂಡ." - -#: src/cthulhu/messages.py:2258 -#, fuzzy -msgid "Speech enabled." -msgstr "ಶಕ್ತಗೊಂಡ." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "ದರ(_R):" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "ಕಾಲಂ %d" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "ಇಲ್ಲ ಲಭ್ಯವಿರುವ n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "ಇಲ್ಲ ಲಭ್ಯವಿರುವ n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "ಶಕ್ತಗೊಂಡ." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "ಆದ್ಯತೆಗಳು" - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr " ." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -#, fuzzy -msgid "Speech is unavailable." -msgstr " ಲಭ್ಯವಿಲ್ಲದ." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "ಯಾವುದೆ ಕಡತ ಪತ್ತೆಯಾಗಿಲ್ಲ." - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "ವಾಕ್ಯ" - -#: src/cthulhu/messages.py:2353 -#, fuzzy -msgid "string not found" -msgstr "ವಾಕ್ಯ" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -#, fuzzy -msgid "Structural navigation keys on." -msgstr "ನಲ್ಲಿ." - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "ಯಾವುದೆ ಕಡತ ಪತ್ತೆಯಾಗಿಲ್ಲ." - -#: src/cthulhu/messages.py:2380 -#, fuzzy, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "ಪಂಕ್ತಿ." - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "ಟೇಬಲ್" - -#: src/cthulhu/messages.py:2389 -#, fuzzy -msgid "Speak cell" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/messages.py:2394 -#, fuzzy -msgid "Speak row" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -#, fuzzy -msgid "Not in a table." -msgstr "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ಕಾಲಂಹೆಡರ್" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "ಕಾಲಂ %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "ಆರಿಸದೆ ಇರುವ" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "ಆರಿಸದೆ ಇರುವ" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "ಸಾಲು %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -#, fuzzy -msgid "End of row." -msgstr "ಕೊನೆ." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "ಎಂಡ್." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "ಆರಿಸದೆ ಇರುವ" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "ಆರಿಸದೆ ಇರುವ" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "ಆದ್ಯತೆಗಳು ಗೆ" - -#: src/cthulhu/messages.py:2556 -#, fuzzy -msgid "white space" -msgstr "ಖಾಲಿ ಜಾಗ" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 ಅಂಶಗಳು" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "ಪಂಕ್ತಿ." -msgstr[1] "ಪಂಕ್ತಿ." - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d ಬೈಟ್" -msgstr[1] "%d ಬೈಟ್‍ಗಳು" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ಕಡತ ಪತ್ತೆಯಾಗಿದೆ" -msgstr[1] "%d ಕಡತಗಳು ಪತ್ತೆಯಾಗಿದೆ" - -#: src/cthulhu/messages.py:2640 -#, fuzzy, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "ಫಾರ್ಮ್" -msgstr[1] "ಫಾರ್ಮ್" - -#: src/cthulhu/messages.py:2647 -#, fuzzy, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "ಶೀರ್ಷಿಕೆ" -msgstr[1] "ಶೀರ್ಷಿಕೆ" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d ಅಂಶ" -msgstr[1] "%d ಅಂಶಗಳು" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "ಇಲ್ಲ." -msgstr[1] "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d ಕಡತ ಪತ್ತೆಯಾಗಿದೆ" -msgstr[1] "%d ಕಡತಗಳು ಪತ್ತೆಯಾಗಿದೆ" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "ಇಲ್ಲ." -msgstr[1] "ಇಲ್ಲ." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "ಟೇಬಲ್." -msgstr[1] "ಟೇಬಲ್." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "ಪಟ್ಟಿ ನೊಂದಿಗೆ ಅಂಶ" -msgstr[1] "ಪಟ್ಟಿ ನೊಂದಿಗೆ ಅಂಶ" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "ಪಟ್ಟಿ ನೊಂದಿಗೆ ಅಂಶ" -msgstr[1] "ಪಟ್ಟಿ ನೊಂದಿಗೆ ಅಂಶ" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "ಪಟ್ಟಿ ನೊಂದಿಗೆ" -msgstr[1] "ಪಟ್ಟಿ ನೊಂದಿಗೆ" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "ಪಟ್ಟಿ ನೊಂದಿಗೆ" -msgstr[1] "ಪಟ್ಟಿ ನೊಂದಿಗೆ" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, fuzzy, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "ಅಂಶ ಆರಿಸಲಾದ" -msgstr[1] "ಅಂಶ ಆರಿಸಲಾದ" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "ಖಾಲಿ ಜಾಗ" -msgstr[1] "ಖಾಲಿ ಜಾಗ" - -#: src/cthulhu/messages.py:2813 -#, fuzzy, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "ಟ್ಯಾಬ್" -msgstr[1] "ಟ್ಯಾಬ್" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "ಟೇಬಲ್" -msgstr[1] "ಟೇಬಲ್" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "ಟೇಬಲ್ ನೊಂದಿಗೆ." -msgstr[1] "ಟೇಬಲ್ ನೊಂದಿಗೆ." - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "ಟೇಬಲ್ ನೊಂದಿಗೆ." -msgstr[1] "ಟೇಬಲ್ ನೊಂದಿಗೆ." - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "ಪಟ್ಟಿ ನೊಂದಿಗೆ" -msgstr[1] "ಪಟ್ಟಿ ನೊಂದಿಗೆ" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "ಸೆಕೆಂಡುಗಳು" -msgstr[1] "ಸೆಕೆಂಡುಗಳು" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "ಹೊರಳು ಗುಂಡಿ" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "LEVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, fuzzy, python-format -msgid "tree level %d" -msgstr "ಮಟ್ಟ" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "ವಿಭಾಗ" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "ಕಾಂಬೋ ಪೆಟ್ಟಿಗೆ" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "ವಿಭಾಗ" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "ಪ್ಯಾರಾಗ್ರಾಫ್" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "ಕ್ರಿಯೆ" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "ಟ್ಯಾಬ್ ಪಟ್ಟಿ" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "ಚಲನ ಪಟ್ಟಿ" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "ಚಲನ ಪಟ್ಟಿ" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "ಚಿಹ್ನೆ ಫಲಕ" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "ಅನಿಮೇಶನ್" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "ಅನಿಮೇಶನ್" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "ಹುಡುಕಲಾಗುತ್ತಿದೆ." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "ಇಲ್ಲ." - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "ತಿರುಗು ಗುಂಡಿ" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -#, fuzzy -msgid "expanded" -msgstr "ವಿಸ್ತರಿಸಲಾದ" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "ಪರೀಕ್ಷಿಸಲಾದ" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "ಪರೀಕ್ಷಿಸಲಾದ" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "ಆನ್" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "ಆಫ್" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "ಪರೀಕ್ಷಿಸಲಾದ" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ಪರೀಕ್ಷಿಸಲಾದ" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "ಆರಿಸದೆ ಇರುವ" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "ಆರಿಸಲಾದ" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "ಆರಿಸದೆ ಇರುವ" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "ಅಮಾನ್ಯ" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "ಅಮಾನ್ಯ" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "ಅಮಾನ್ಯ" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "ಕಾಗುಣಿತವನ್ನು ಪರೀಕ್ಷಿಸು" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "ಅಮಾನ್ಯ" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "ಪತ್ತೆ ಹಚ್ಚು" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "ಮುಚ್ಚು" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "ಪತ್ತೆ ಹಚ್ಚು" - -#: src/cthulhu/cthulhu-find.ui:85 -#, fuzzy -msgid "_Search for:" -msgstr "ಹುಡುಕು ಗೆ:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -#, fuzzy -msgid "Search for:" -msgstr "ಹುಡುಕು ಗೆ:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -#, fuzzy -msgid "Start from:" -msgstr "ಆರಂಭ:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "ಆವರಿಕೆ(_Wrap) ಮಾಡು" - -#: src/cthulhu/cthulhu-find.ui:242 -#, fuzzy -msgid "Search _backwards" -msgstr "ಹುಡುಕು" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "ಹುಡುಕು ಗೆ:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "ಕೇಸನ್ನು ಸರಿಹೊಂದಿಸು(_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "ಕೇವಲ ಸಂಪೂರ್ಣ ಪದಕ್ಕಾಗಿ ಮಾತ್ರ ಹುಡುಕು (_e)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "ಪತ್ತೆ ಹಚ್ಚು ಆಯ್ಕೆಗಳು" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "ಹೈಪರ್-ಲಿಂಕ್" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "ಅನ್ವಯ" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "ವಿಂಡೊ" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "ಆದ್ಯತೆಗಳು" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr " ಕೀಲಿಮಣೆ ವಿನ್ಯಾಸ" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "ಆರಂಭ:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "ಮಾತನಾಡು" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "ಅನ್ವಯ" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "ಮಾತನಾಡು" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "ನಲ್ಲಿ." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -#, fuzzy -msgid "Say All B_y:" -msgstr "ಎಲ್ಲಾ B y:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "ಎಲ್ಲಾ B y:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -#, fuzzy -msgid "General" -msgstr "ಸಾಮಾನ್ಯ" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "ದರ(_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "ಧ್ವನಿ:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "ಧ್ವನಿ:" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -#, fuzzy -msgid "Speak multicase strings as wor_ds" -msgstr "ಮಾತನಾಡು" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "ಧ್ವನಿ:" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -#, fuzzy -msgid "_Enable speech" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "ಎಲ್ಲಾ(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr " ಮಟ್ಟ" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -#, fuzzy -msgid "Speak blank lines" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/cthulhu-setup.ui:1835 -#, fuzzy -msgid "Speak _indentation and justification" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -#, fuzzy -msgid "Speak tutorial messages" -msgstr "ಮಾತನಾಡು" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "ಮಾತನಾಡು" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "ಮಾತನಾಡು" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "ಮಾತನಾಡು ಯಾವುದೂ ಇಲ್ಲ" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2187 -#, fuzzy -msgid "Enable Braille _support" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -#, fuzzy -msgid "Contraction _Table:" -msgstr "ಪಟ್ಟಿ:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -#, fuzzy -msgid "_Enable Contracted Braille" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "ಪ್ರದರ್ಶಕ ಆಯ್ಕೆಗಳು" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "ಯಾವುದೂ ಇಲ್ಲ(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "ಹೈಪರ್-ಲಿಂಕ್" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2780 -#, fuzzy -msgid "Enable _key echo" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "ಶಕ್ತಗೊಳಿಸು ಕ್ರಿಯೆ" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2864 -#, fuzzy -msgid "Enable _modifier keys" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2879 -#, fuzzy -msgid "Enable _function keys" -msgstr "ಶಕ್ತಗೊಳಿಸು ಕ್ರಿಯೆ" - -#: src/cthulhu/cthulhu-setup.ui:2894 -#, fuzzy -msgid "Enable ac_tion keys" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2909 -#, fuzzy -msgid "Enable _navigation keys" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2965 -#, fuzzy -msgid "Enable echo by _word" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "ಶಕ್ತಗೊಳಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "ಕೀಲಿ" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "ಕೀಲಿ:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -#, fuzzy -msgid "Key Bindings" -msgstr "ಕೀಲಿ" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr " ಶಬ್ಧಕೋಶ" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "ಹೊಸ ನಮೂದು(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "ಅಳಿಸಿ ಹಾಕು(_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -#, fuzzy -msgid "_Speak all" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/cthulhu-setup.ui:3257 -#, fuzzy -msgid "Speak _none" -msgstr "ಮಾತನಾಡು ಯಾವುದೂ ಇಲ್ಲ" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "ಮರುಹೊಂದಿಸು(_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "ಪಠ್ಯ" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -#, fuzzy -msgid "Move to _bottom" -msgstr "ವರ್ಗಾಯಿಸು" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -#, fuzzy -msgid "Move _down one" -msgstr "ವರ್ಗಾಯಿಸು ಡೌನ್" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -#, fuzzy -msgid "Move _up one" -msgstr "ವರ್ಗಾಯಿಸು ಅಪ್" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -#, fuzzy -msgid "Move to _top" -msgstr "ವರ್ಗಾಯಿಸು" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr " ಆರಿಸಲಾದ" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "ಆಯ್ಕೆ ಬ್ರೈಲ್" - -#: src/cthulhu/cthulhu-setup.ui:3549 -#, fuzzy -msgid "Text Attributes" -msgstr "ಪಠ್ಯ" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "ಸಹಾಯಕ" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "ಸಹಾಯಕ" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "ಶೀರ್ಷಿಕೆ" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -#, fuzzy -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "e m n y" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "ವಿಭಾಗ" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "ಟೇಬಲ್" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -#, fuzzy -msgctxt "textattr" -msgid "foreground color" -msgstr "ಬಣ್ಣ:" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -#, fuzzy -msgctxt "textattr" -msgid "justification" -msgstr "ಸೂಚನೆ %s" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "ಲೆಫ್ಟ್‍" - -#: src/cthulhu/text_attribute_names.py:176 -#, fuzzy -msgctxt "textattr" -msgid "line height" -msgstr "ಸಾಲು ರೈಟ್" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "ಪ್ಯಾರಾಗ್ರಾಫ್" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -#, fuzzy -msgctxt "textattr" -msgid "pixels below lines" -msgstr "ಮಾತನಾಡು" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "ರೈಟ್" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "cale" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -#, fuzzy -msgctxt "textattr" -msgid "text rotation" -msgstr "C" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "ಸಾಲು ರೈಟ್" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -#, fuzzy -msgctxt "textattr" -msgid "engrave" -msgstr "e" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "ಕೊಂಡಿ" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "ಗುಪ್ತಪದ" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "trtbl" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "ಲೆಫ್ಟ್‍ ಆಲ್ಟ್‍" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "ರೈಟ್ ಆಲ್ಟ್‍" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:493 -#, fuzzy -msgctxt "textattr" -msgid "no justification" -msgstr "ಸೂಚನೆ %s" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "ತುಂಬಿಸುವವ" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -#, fuzzy -msgctxt "textattr" -msgid "condensed" -msgstr "ಸೆಕೆಂಡುಗಳು" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "ಸೆಕೆಂಡುಗಳು" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "ವಿಸ್ತರಿಸಲಾದ" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "ವಿಸ್ತರಿಸಲಾದ" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "ವಿಸ್ತರಿಸಲಾದ" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ವಿಸ್ತರಿಸಲಾದ" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "ಪೂರ್ವನಿಯೋಜಿತ" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "ಪಠ್ಯ" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "ಶೀರ್ಷಿಕೆ" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "ನಿಲ್ಲಿಸು" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "ಪಠ್ಯ" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "ಕೆಳಗಿನ(_B):" - -#: src/cthulhu/text_attribute_names.py:662 -#, fuzzy -msgctxt "textattr" -msgid "text-bottom" -msgstr "ವರ್ಗಾಯಿಸು" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:726 -#, fuzzy -msgctxt "textattr" -msgid "rl" -msgstr "Ctrl" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "ಟ್ಯಾಬ್" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "ಕಾಗುಣಿತವನ್ನು ಪರೀಕ್ಷಿಸು" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/ko.po b/po/ko.po deleted file mode 100644 index c5ee358..0000000 --- a/po/ko.po +++ /dev/null @@ -1,9893 +0,0 @@ -# This file is distributed under the same license as the cthulhu package. -# Changwoo Ryu , 2006, 2007, 2009. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2009-01-29 19:31+0900\n" -"Last-Translator: Changwoo Ryu \n" -"Language-Team: GNOME Korea \n" -"Language: ko\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu 화면 낭독기" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "화면;리더;접근성;음성;점자;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -#, fuzzy -msgid "alrt" -msgstr "경보" - -#: src/cthulhu/braille_rolenames.py:54 -#, fuzzy -msgid "anim" -msgstr "애니메이션" - -#: src/cthulhu/braille_rolenames.py:57 -#, fuzzy -msgid "arw" -msgstr "화살표" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "달력" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "캔버스" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "캡션" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "체크" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "색 고르기" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "열 헤더" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "콤보 상자" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "날짜 편집" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -#, fuzzy -msgid "icn" -msgstr "바탕화면 아이콘" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "프레임" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "대화 상자" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "디렉토리 창" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "HTML" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "그리기 영역" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "파일 고르기" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "채움" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "글꼴 고르기" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "글래스 창" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "머리말" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "그림" - -#: src/cthulhu/braille_rolenames.py:145 -#, fuzzy -msgid "ifrm" -msgstr "프레임" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "레이블" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "레이어 창" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "링크" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "목록" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "목록 항목" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "메뉴" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "메뉴 모음" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "메뉴 항목" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "옵션 창" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "탭 목록" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "패널" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "열쇠글" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "팝업 메뉴" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "진행률 표시줄" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "단추" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "라디오" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "라디오 메뉴 항목" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "최상위 창" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "행 헤더" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "스크롤 막대" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "스크롤 창" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "섹션" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "구분선" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "슬라이더" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "나누기 창" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "스핀 단추" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "상태 표시줄" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "테이블" - -#: src/cthulhu/braille_rolenames.py:235 -#, fuzzy -msgid "cll" -msgstr "셀" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "떼어내기 메뉴 항목" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "터미널" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "텍스트" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "토글 단추" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "도구 모음" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "풍선 도움말" - -#: src/cthulhu/braille_rolenames.py:262 -#, fuzzy -msgid "tre" -msgstr "트리" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "트리 테이블" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "알 수 없음" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "뷰포트" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "창" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "헤더" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "꼬리말" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "문단" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "프로그램" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "자동" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "편집 막대" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "내장" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "스페이스" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "줄바꿈" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "탭" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "느낌표" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "따옴표" - -#: src/cthulhu/chnames.py:66 -#, fuzzy -msgid "number" -msgstr "메뉴 모음" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "달러" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "퍼센트" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "앤드" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "아포스트로피" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "왼쪽 괄호" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "오른쪽 괄호" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "별표" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "더하기" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "쉼표" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "대시" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "점" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "슬래쉬" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "콜론" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "세미콜론" - -#: src/cthulhu/chnames.py:126 -#, fuzzy -msgid "less" -msgstr "더 작음" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "등호" - -#: src/cthulhu/chnames.py:134 -#, fuzzy -msgid "greater" -msgstr "더 큼" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "물음" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "애트" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "왼쪽 대괄호" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "백슬래쉬" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "오른쪽 대괄호" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "캐럿" - -#: src/cthulhu/chnames.py:162 -#, fuzzy -msgid "underline" -msgstr "줄바꿈" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -#, fuzzy -msgid "grave" -msgstr "비활성화" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "왼쪽 중괄호" - -#: src/cthulhu/chnames.py:174 -#, fuzzy -msgid "vertical bar" -msgstr "세로줄" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "오른쪽 중괄호" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "물결" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "스페이스" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -#, fuzzy -msgid "cents" -msgstr "퍼센트" - -#: src/cthulhu/chnames.py:199 -#, fuzzy -msgid "pounds" -msgstr "파운드" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -#, fuzzy -msgid "broken bar" -msgstr "메뉴 모음" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "섹션" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "왼쪽 대괄호" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -#, fuzzy -msgid "registered" -msgstr "가운데" - -#: src/cthulhu/chnames.py:247 -#, fuzzy -msgid "macron" -msgstr "바탕화면 아이콘" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -#, fuzzy -msgid "plus or minus" -msgstr "더하기 빼기" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -#, fuzzy -msgid "mu" -msgstr "메뉴" - -#: src/cthulhu/chnames.py:275 -#, fuzzy -msgid "paragraph marker" -msgstr "문단" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -#, fuzzy -msgid "cedilla" -msgstr "셀" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "다이얼" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "오른쪽 대괄호" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -#, fuzzy -msgid "times" -msgstr "물결" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -#, fuzzy -msgid "a grave" -msgstr "비활성화" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -#, fuzzy -msgid "a tilde" -msgstr "물결" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -#, fuzzy -msgid "a ring" -msgstr "찾는 중입니다." - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -#, fuzzy -msgid "c cedilla" -msgstr "셀" - -#: src/cthulhu/chnames.py:475 -#, fuzzy -msgid "e grave" -msgstr "비활성화" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -#, fuzzy -msgid "i grave" -msgstr "비활성화" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -#, fuzzy -msgid "n tilde" -msgstr "물결" - -#: src/cthulhu/chnames.py:515 -#, fuzzy -msgid "o grave" -msgstr "비활성화" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -#, fuzzy -msgid "o tilde" -msgstr "물결" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -#, fuzzy -msgid "divided by" -msgstr "나누기" - -#: src/cthulhu/chnames.py:539 -#, fuzzy -msgid "o stroke" -msgstr "아포스트로피" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -#, fuzzy -msgid "u grave" -msgstr "비활성화" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -#, fuzzy -msgid "florin" -msgstr "채움" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "대시" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "오른쪽 쉬프트" - -#: src/cthulhu/chnames.py:593 -#, fuzzy -msgid "single low quote" -msgstr "오른쪽 쉬프트" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -#, fuzzy -msgid "dagger" -msgstr "페이지" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -#, fuzzy -msgid "bullet" -msgstr "줄리엣" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -#, fuzzy -msgid "per mille" -msgstr "점자" - -#: src/cthulhu/chnames.py:629 -#, fuzzy -msgid "prime" -msgstr "로미오" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -#, fuzzy -msgid "check mark" -msgstr "체크 항목" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -#, fuzzy -msgid "superscript minus" -msgstr "더하기 빼기" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "왼쪽 괄호" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "오른쪽 괄호" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "더하기 빼기" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "왼쪽 괄호" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "오른쪽 괄호" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "플랫 리뷰를 다음 문자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "현재 플랫 리뷰 항목에 왼쪽 마우스 단추를 누르십시오." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "현재 플랫 리뷰 항목에 오른쪽 마우스 단추를 누르십시오." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "전체 문서를 음성으로 말합니다." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "현재 플랫 리뷰 줄을 말합니다." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "현재 위치 동작을 수행합니다." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "현재 위치 동작을 수행합니다." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "현재 플랫 리뷰 줄을 말합니다." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "빈 줄 말하기" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "기본 버튼 표시" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "상태 표시줄 읽기" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "제목 표시줄 읽기" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "오르카 찾기 대화 상자를 엽니다." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "작업 목록 표시" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "다음에 나오는 문자열을 찾습니다." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "이전에 나오는 문자열을 찾습니다." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "플랫 리뷰 모드를 들어가고 나갑니다." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "현재 개체로 평면 검토 제한 전환" - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "플랫 리뷰를 홈 위치로 옮깁니다." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "플랫 리뷰를 끝 위치로 옮깁니다." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "플랫 리뷰를 이전 줄의 처음으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "현재 플랫 리뷰 줄을 말합니다." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "현재 플랫 리뷰 줄을 말합니다." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "현재 플랫 리뷰 줄을 말합니다." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "플랫 리뷰를 다음 줄의 처음으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "현재의 플랫 리뷰 항목 혹은 단어를 말하거나 철자를 말합니다." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "현재의 플랫 리뷰 항목 혹은 단어를 말하거나 철자를 말합니다." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "현재의 플랫 리뷰 항목 혹은 단어를 말하거나 철자를 말합니다." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "플랫 리뷰를 다음 항목 혹은 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "플랫 리뷰를 현재 단어의 위에 있는 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "현재의 플랫 리뷰 오브젝트를 말합니다." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "플랫 리뷰를 현재 단어의 아래에 있는 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "플랫 리뷰를 이전 글자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "현재 플랫 리뷰 문자를 말합니다." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "현재 플랫 리뷰 문자를 말합니다." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "현재 플랫 리뷰 문자를 말합니다." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "플랫 리뷰를 다음 문자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "플랫 리뷰를 줄의 끝으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "플랫 리뷰를 아래 왼쪽으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "현재의 플랫 리뷰 항목 혹은 단어를 말하거나 철자를 말합니다." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "현재의 플랫 리뷰 항목 혹은 단어를 말하거나 철자를 말합니다." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "평면 검토 내용 표시" - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "현재 테이블 셀 혹은 전체 행을 읽을 지 여부를 토글합니다." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "현재 텍스트 문자와 관련된 속성을 읽습니다." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "점자 표시를 왼쪽으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "점자 표시를 오른쪽으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "키보드 포커스가 있는 오브젝트로 돌아갑니다." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "플랫 리뷰를 다음 줄의 처음으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "플랫 리뷰를 줄의 끝으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "학습 모드를 끝냅니다. Esc를 누르면 학습 모드를 끝냅니다." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "음성 속도를 낮춥니다." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "음성 속도를 높입니다." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "음성 높이를 낮춥니다." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "음성 높이를 높입니다." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "음성 속도를 높입니다." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "음성 속도를 낮춥니다." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "이전 음성 설정 선택" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "다음 음성 설정 선택" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "현재 음성 설정 감소" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "현재 음성 설정 증가" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "음성 설정 저장" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "음성 묵음을 토글합니다." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "절전 모드 전환" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "기본 설정 대화 상자를 표시합니다." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "기본 설정 대화 상자를 표시합니다." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "들여쓰기 및 맞춤을 말하기(_I)" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "다음에 나오는 문자열을 찾습니다." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "다음 음성 합성기로 전환" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "다음에 나오는 문자열을 찾습니다." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "다음에 나오는 문자열을 찾습니다." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "다음에 나오는 문자열을 찾습니다." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "실행 중에 디버깅 단계를 차례대로 조절합니다." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "현재의 플랫 리뷰 오브젝트를 말합니다." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "이전의 채팅 방 메시지를 말하고 점자로 표현." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "채팅 방 메세지 앞에 채팅 방 이름을 붙일 지 토글합니다." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "채팅 방 메시지 앞에 채팅 방 이름을 붙일 지 토글합니다." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "줄 왼쪽" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "줄 오른쪽" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "줄 위" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "줄 아래" - -#: src/cthulhu/cmdnames.py:662 -#, fuzzy -msgid "Freeze" -msgstr "트리" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "위 왼쪽" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "아래(_B):" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "커서 위치" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "커서 위치" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "링크" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "다음 알림 메시지 읽기" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "플랫 리뷰를 다음 문자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "플랫 리뷰를 이전 글자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "플랫 리뷰를 다음 문자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr " 문맥은 " - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "플랫 리뷰를 줄의 끝으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "입력하는 줄의 내용을 말합니다." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "플랫 리뷰를 다음 줄의 처음으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "플랫 리뷰를 줄의 끝으로 옮깁니다." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "현재의 플랫 리뷰 오브젝트를 말합니다." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "목록 항목" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "calc 셀을 말할 때 해당 행을 동적인 열 헤더로 사용하도록 합니다." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "동적인 열 헤더 비움." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "calc 셀을 말할 때 해당 열을 동적인 행 헤더로 사용하도록 합니다." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "동적인 열 헤더 비움." - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "입력하는 줄의 내용을 말합니다." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "펑션 키 사용(_F)" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "청크가 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "이전 버튼으로 이동" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "다음 버튼으로 이동" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "옵션 더 자세히 표시" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "플랫 리뷰를 이전 글자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "플랫 리뷰를 다음 문자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "플랫 리뷰를 이전 글자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "플랫 리뷰를 다음 문자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr " 문맥은 " - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "HTML 컨테이너" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "HTML 컨테이너" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr " 문맥은 " - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "이전 양식 필드로 이동" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "다음 양식 필드로 이동" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "이전 제목으로 이동" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "다음 제목으로 이동" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "이전 내부 프레임으로 이동" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "다음 내부 프레임으로 이동" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "내부 프레임 목록 표시" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr " 문맥은 " - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "플랫 리뷰를 이전 글자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "플랫 리뷰를 다음 문자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "현재의 플랫 리뷰 오브젝트를 말합니다." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "이전 링크로 이동" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "다음 링크로 이동" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "옵션 더 자세히 표시" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr " 문맥은 " - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr " 문맥은 " - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr " 문맥은 " - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "탐색기 초점이 있는 개체의 부모로 이동합니다." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "탐색기 초점이 있는 개체의 첫 번째 자식으로 이동합니다." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "탐색기 초점이 있는 개체의 다음 형제로 이동합니다." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "탐색기 초점이 있는 개체의 이전 형제로 이동합니다." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "탐색기 포커스가 있는 개체를 클릭합니다." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "간소화된 개체 탐색을 전환합니다." - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "플랫 리뷰를 이전 글자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "플랫 리뷰를 다음 문자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "플랫 리뷰를 이전 글자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "플랫 리뷰를 다음 문자로 옮깁니다." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr " 문맥은 " - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "셀로 이동" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "셀로 이동" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "셀로 이동" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "셀로 이동" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "토글 단추" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "키 반향음 사용(_K)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "트리 테이블" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "빈칸" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "트리 테이블" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "트리 테이블" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "비활성화" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "트리 테이블" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "비활성화" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "비활성화" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "인디아" - -#: src/cthulhu/colornames.py:314 -#, fuzzy -msgctxt "color name" -msgid "indigo" -msgstr "인디아" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "오른쪽 중괄호" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "오른쪽 컨트롤" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "오른쪽 괄호" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "오른쪽 중괄호" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "오른쪽 괄호" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "오른쪽 괄호" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "오른쪽 알트" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "오른쪽 괄호" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "오른쪽 괄호" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "줄바꿈" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "그림" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "트리 테이블" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "앤드" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "트리 테이블" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr " 화면" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "트리 테이블" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "트리 테이블" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "탱고" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "공백" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "공백" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr " 화면" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "아이콘" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "없음" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "맞춤법 검사:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -#, fuzzy -msgid "_Speak Chat Room name" -msgstr "채팅 방 이름 말하기." - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -#, fuzzy -msgid "Default Synthesizer" -msgstr "음성 합성기(_Z):" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "단어 단위로 반향음(_W)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "펑션 키 사용(_F)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "현재 위치(_U)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -#, fuzzy -msgid "Find Options" -msgstr "함수" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "쉼표" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "키 바인딩" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "기본값" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "학습 모드를 끝냅니다." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "작업" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "점자 바인딩" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "북마크" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "펑션 키 사용(_F)" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -#, fuzzy -msgid "Unbound" -msgstr "파운드" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "바뀜" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "데스크탑(_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "섹션" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "수신됨" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -#, fuzzy -msgid "Speak" -msgstr "말하기: " - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "모두(_A)" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "프로그램" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "창" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "없음(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "일부(_M)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "대부분(_O)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -#, fuzzy -msgid "Line" -msgstr "링크" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -#, fuzzy -msgid "Sentence" -msgstr "가운데" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "따옴표" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "단추" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "캡션" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "체크 상자" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "콤보 상자" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "캡션" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "머리말" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "내부 프레임" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "그림" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "레이블" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -#, fuzzy -msgctxt "structural navigation" -msgid "Level" -msgstr "트리 단계 %d" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "링크" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "목록" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "목록 항목" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "문단" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "라디오 단추" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "선택함" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "상태" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "텍스트" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "청크가 더 이상 없습니다." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "단추" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "체크 상자" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "콤보 상자" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "머리말" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "내부 프레임" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "그림" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "링크" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "목록" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "목록 항목" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "문단" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "라디오 단추" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "테이블" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "기본값" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "하이퍼링크" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "대문자" - -#: src/cthulhu/guilabels.py:852 -#, fuzzy -msgid "Speech Dispatcher" -msgstr "음성 사용하지 않음." - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "맞춤법 검사:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "빈 줄 말하기" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -#, fuzzy -msgid "Skip _blank cells" -msgstr "빈 줄 말하기" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "말하기: " - -#: src/cthulhu/guilabels.py:909 -#, fuzzy -msgid "Speak _cell coordinates" -msgstr "빈 줄 말하기" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "펑션 키 사용(_F)" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "소리 테마(_T):" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "소리 테마" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "간단히(_F)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "들여쓰기 및 맞춤을 말하기(_I)" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "쉬프트" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "오른쪽 알트" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "왼쪽 컨트롤" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "왼쪽 쉬프트" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "왼쪽 알트" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "왼쪽 컨트롤" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "오른쪽 쉬프트" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "오른쪽 알트" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "오른쪽 컨트롤" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "왼쪽 메타" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "오른쪽 메타" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "넘버락" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "캡스락" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "캡스락" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "스크롤락" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "페이지업" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "페이지다운" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "왼쪽 탭" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "스페이스" - -#: src/cthulhu/keynames.py:157 -#, fuzzy -msgid "return" -msgstr "더 큼" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "가운데" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "켬 " - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "왼쪽 알트" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "오른쪽 알트" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "왼쪽 괄호" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "오른쪽 괄호" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "메뉴" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -#, fuzzy -msgid "help" -msgstr "옐프" - -#: src/cthulhu/keynames.py:217 -#, fuzzy -msgid "multi" -msgstr "곱하기" - -#: src/cthulhu/keynames.py:221 -#, fuzzy -msgid "mode switch" -msgstr "메뉴 항목" - -#: src/cthulhu/keynames.py:225 -#, fuzzy -msgid "escape" -msgstr "스크롤 창" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -#, fuzzy -msgid "insert" -msgstr "구분선" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -#, fuzzy -msgid "delete" -msgstr "선택함" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -#, fuzzy -msgid "home" -msgstr "일부(_M)" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "앤드" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -#, fuzzy -msgid "ring" -msgstr "찾는 중입니다." - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "아포스트로피" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "빼기" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "구분선" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "캡스락" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "오른쪽 알트" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "수퍼" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "메타2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "왼쪽 알트" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "컨트롤" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "쉬프트" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "진하게" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "잘못됨" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "작업 공간" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr " 문맥은 " - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "왼쪽 괄호" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "화살표" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "오른쪽 괄호" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "화살표" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "오른쪽 컨트롤" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "왼쪽 대괄호" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "오른쪽 대괄호" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "오른쪽 대괄호" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "오른쪽 컨트롤" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "오른쪽 컨트롤" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "빼기" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "점" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "세로줄" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "비례" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "자동 완성" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "비었음" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "더하기 빼기" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "더하기" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "빼기" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "구분선" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "비례" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "오른쪽 알트" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "링크" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "레이어 창" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "세로줄" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "나누기" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "구분선" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "섹션" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "내부 프레임" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "비례" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "빼기" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "물결" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "물결" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "물결" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "물결" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "등호" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "등호" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "등호" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "세로줄" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "안 누름" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "선택 안 함" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "수퍼" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "선택 해제함" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "섹션" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "선택 해제함" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "등호" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "대시" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "더하기 빼기" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "오른쪽 메타" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "왼쪽 탭" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "켬 " - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "섹션" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "트리" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "트리" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "다이얼" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "그림" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "곱하기" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "내부 프레임" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "다이얼" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "오른쪽 쉬프트" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "오른쪽 중괄호" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "구분선" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "왼쪽 괄호" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "섹션" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "더 작음" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "더 큼" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "세로줄" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "왼쪽 괄호" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "오른쪽 괄호" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "왼쪽 알트" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "오른쪽 알트" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "왼쪽 중괄호" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "아래(_B):" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "왼쪽 대괄호" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "오른쪽 대괄호" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "공백" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "공백" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "공백" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "줄바꿈" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "세로줄" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "프로그램" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "빈칸" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "진하게" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "파일을 찾을 수 없습니다." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "파일을 찾을 수 없습니다." - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "음성 사용." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "바탕화면 아이콘" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "없음" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "스핀 단추" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, fuzzy, python-format -msgid "Cell %s" -msgstr "셀 " - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "선택함" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "선택 안 함" - -#: src/cthulhu/messages.py:193 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "선택 안 함" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "선택 해제함" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -#, fuzzy -msgid "Use alternate directory for user preferences" -msgstr "" -"-u, --user-prefs-dir=<디렉토리이름> 사용자 기본 설정에 다른 디렉토리 사용" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "-?, --help 이 도움말을 표시합니다" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -#, fuzzy -msgid "Set up user preferences (text version)" -msgstr "" -"-t, --text-setup 사용자 기본 설정을 설정합니다 (텍스트 버전)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "" -"-t, --text-setup 사용자 기본 설정을 설정합니다 (텍스트 버전)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "문제점을 https://groups.io/g/stormux로 알려주십시오." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "더 빨리." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, fuzzy, python-format -msgid "Message from chat room %s" -msgstr "다음 채팅 방에서 메세지: " - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "채팅 방 이름 말하지 않기." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "채팅 방 이름 말하기." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "선택함" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "구분선" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "물음" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "HTML 컨테이너" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "선택 안 함" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "문자열이 없습니다" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "전체 문서 선택" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "전체 문서 선택" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "커서 위치에서 문서 선택" - -#: src/cthulhu/messages.py:554 -#, fuzzy -msgid "document unselected from cursor position" -msgstr "커서 위치에서 문서 선택" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "선택한 문서에서 커서 위치" - -#: src/cthulhu/messages.py:566 -#, fuzzy -msgid "document unselected to cursor position" -msgstr "선택한 문서에서 커서 위치" - -#: src/cthulhu/messages.py:571 -#, fuzzy, python-format -msgid "Dynamic column header set for row %d" -msgstr "다음 행에 동적인 열 헤더 설정: " - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "동적인 열 헤더 비움." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "%s 열에 동적인 행 헤더 설정" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "동적인 행 헤더 비움." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "비었음" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "파일을 찾을 수 없습니다." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "플랫 리뷰 모드를 들어가고 나갑니다." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "플랫 리뷰를 현재 단어의 위에 있는 단어로 옮깁니다." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "평면 검토 무제한" - -#: src/cthulhu/messages.py:661 -#, fuzzy -msgid "has formula" -msgstr " 수식이 있습니다 " - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "대화 상자" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "팝업 메뉴" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, fuzzy, python-format -msgid "The key entered is already bound to %s" -msgstr "입력한 키가 같습니다. 바꾸지 않습니다." - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "키 잡기: %s. 계속하려면 리턴을 누르십시오." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "새 키는: %s" - -#: src/cthulhu/messages.py:711 -#, fuzzy -msgid "Key binding deleted. Press enter to confirm." -msgstr "키 잡기: %s. 계속하려면 리턴을 누르십시오." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "새 키 입력" - -#: src/cthulhu/messages.py:735 -#, fuzzy -msgctxt "key echo" -msgid "key" -msgstr "위스키" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "없음" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "가운데" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "단어 단위로 반향음(_W)" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "열쇠글" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "공백" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "비례" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "세로줄" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "맨 아래로 넘어감" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "줄 오른쪽" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "앤드" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "줄바꿈" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "최상위 창" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "최상위 창" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "최상위 창" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "수퍼" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "밑줄" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "테이블" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "트리 테이블" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "접근할 수 없음" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "테이블" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "들여쓰기 및 맞춤을 말하기(_I)" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "단어 단위로 반향음(_W)" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "들여쓰기 및 맞춤을 말하기(_I)" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "학습 모드. 끝내려면 Esc 키를 누르십시오." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "애니메이션" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "펑션 키 사용(_F)" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "선택한 줄에서 커서 위치" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "커서 위치에서 줄 선택" - -#: src/cthulhu/messages.py:1484 -#, fuzzy -msgid "line unselected down from cursor position" -msgstr "선택한 줄에서 커서 위치" - -#: src/cthulhu/messages.py:1491 -#, fuzzy -msgid "line unselected up from cursor position" -msgstr "커서 위치에서 줄 선택" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "학습 모드를 끝냅니다." - -#: src/cthulhu/messages.py:1505 -#, fuzzy -msgid "line selected from start to previous cursor position" -msgstr "커서 위치에서 줄 선택" - -#: src/cthulhu/messages.py:1511 -#, fuzzy -msgid "line selected to end from previous cursor position" -msgstr "선택한 줄에서 커서 위치" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "링크" - -#: src/cthulhu/messages.py:1518 -#, fuzzy -msgid "same page" -msgstr "%s 페이지" - -#: src/cthulhu/messages.py:1522 -#, fuzzy -msgid "same site" -msgstr "메뉴 항목" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, fuzzy, python-format -msgid "%s link" -msgstr "바로가기" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "트리 단계 %d" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "파일을 찾을 수 없습니다." - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "현재 위치(_U)" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "끔 " - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "켬 " - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "철자가 틀린 단어:" - -#: src/cthulhu/messages.py:1682 -#, fuzzy, python-format -msgid "Misspelled word: %s" -msgstr "철자가 틀린 단어: " - -#: src/cthulhu/messages.py:1687 -#, fuzzy, python-format -msgid "Context is %s" -msgstr " 문맥은 " - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "현재의 플랫 리뷰 오브젝트를 말합니다." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "돋보기" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "돋보기" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "자식이 없습니다." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%s 퍼센트" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "플랫 리뷰를 이전 항목 혹은 이전 단어로 옮깁니다." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "트리 단계 %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "프로그램" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "포커스 없음" - -#: src/cthulhu/messages.py:1867 -#, fuzzy -msgid "No application has focus." -msgstr "프로그램" - -#: src/cthulhu/messages.py:1872 -#, fuzzy -msgid "No more blockquotes." -msgstr "청크가 더 이상 없습니다." - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "청크가 더 이상 없습니다." - -#: src/cthulhu/messages.py:1888 -#, fuzzy -msgid "No more large objects." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "청크가 더 이상 없습니다." - -#: src/cthulhu/messages.py:1903 -#, fuzzy -msgid "No more entries." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1908 -#, fuzzy -msgid "No more form fields." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1919 -#, fuzzy, python-format -msgid "No more headings at level %d." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "내부 프레임" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1935 -#, fuzzy -msgid "No landmark found." -msgstr "파일을 찾을 수 없습니다." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1945 -#, fuzzy -msgid "No more lists." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "목록 항목" - -#: src/cthulhu/messages.py:1957 -#, fuzzy -msgid "No more live regions." -msgstr "목록 항목" - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1982 -#, fuzzy -msgid "No more unvisited links." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1987 -#, fuzzy -msgid "No more visited links." -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "선택 안 함" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "섹션" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "아래(_B):" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "위(_T):" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "열쇠글" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "끔 " - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "켬 " - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "읽어들이는 중입니다. 잠시 기다리십시오." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "읽어들이기를 마쳤습니다." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s 읽어들이기를 마쳤습니다." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "선택한 페이지에서 커서 위치" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "커서 위치에서 페이지 선택한" - -#: src/cthulhu/messages.py:2089 -#, fuzzy -msgid "page unselected from cursor position" -msgstr "선택한 페이지에서 커서 위치" - -#: src/cthulhu/messages.py:2095 -#, fuzzy -msgid "page unselected to cursor position" -msgstr "커서 위치에서 페이지 선택한" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "선택한 페이지에서 커서 위치" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "선택한 페이지에서 커서 위치" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "선택한 페이지에서 커서 위치" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "선택한 페이지에서 커서 위치" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "파일을 찾을 수 없습니다." - -#: src/cthulhu/messages.py:2151 -#, fuzzy, python-format -msgid "Progress bar %d." -msgstr "진행률 표시줄" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "모두(_A)" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "문장 부호 단계" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "없음" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "찾는 중입니다." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "찾기가 끝났습니다." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu 설정이 다시 로드되었습니다." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr " 문맥은 " - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "사용할 음성 선택:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "선택 해제함" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "음성 사용하지 않음." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "음성 사용." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "더 빨리." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "더 느리게." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "더 높게." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "더 낮게." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "더 빨리." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "속도 %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "음높이 %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "음량 %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher 모듈 %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher 음성 %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "사용 가능한 Speech-dispatcher 모듈이 없습니다" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "사용 가능한 Speech-dispatcher 음성이 없습니다" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "음성 설정이 저장되었습니다" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "음성 설정을 저장할 수 없습니다" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " 점 점 점" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu가 환영합니다." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "크툴루가 파도 아래에 잠복해 있습니다." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "%s에 대해 절전 모드가 활성화되었습니다" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "%s에 대한 절전 모드가 비활성화되었습니다" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "음성을 사용할 수 없습니다." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "파일을 찾을 수 없습니다." - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "문자열이 없습니다" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "문자열이 없습니다" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "파일을 찾을 수 없습니다." - -#: src/cthulhu/messages.py:2380 -#, fuzzy, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "행 %d, 열 %d" - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "테이블" - -#: src/cthulhu/messages.py:2389 -#, fuzzy -msgid "Speak cell" -msgstr "말하기: " - -#: src/cthulhu/messages.py:2394 -#, fuzzy -msgid "Speak row" -msgstr "말하기: " - -#: src/cthulhu/messages.py:2399 -#, fuzzy -msgid "Non-uniform" -msgstr "유니폼" - -#: src/cthulhu/messages.py:2404 -#, fuzzy -msgid "Not in a table." -msgstr "테이블 나가기." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "열 헤더" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "열 %d" - -#: src/cthulhu/messages.py:2420 -#, fuzzy, python-format -msgid "column %(index)d of %(total)d" -msgstr "열 %d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "선택 해제함" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "선택 해제함" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "행 %d" - -#: src/cthulhu/messages.py:2462 -#, fuzzy, python-format -msgid "row %(index)d of %(total)d" -msgstr "행 %d, 전체 %d개" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "선택함" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -#, fuzzy -msgid "Row inserted." -msgstr "구분선" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "플랫 리뷰를 줄의 끝으로 옮깁니다." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "선택 안 함" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "선택 해제함" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "선택함" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "선택 해제함" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu 버전 %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "공백" - -#: src/cthulhu/messages.py:2562 -#, fuzzy -msgid "Wrapping to bottom." -msgstr "맨 아래로 넘어감" - -#: src/cthulhu/messages.py:2568 -#, fuzzy -msgid "Wrapping to top." -msgstr "맨 위로 넘어감" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 항목" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, fuzzy, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "테이블, 행이 %d개 열이 %d개." - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "행 %d, 열 %d" - -#: src/cthulhu/messages.py:2593 -#, fuzzy, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "테이블, 행이 %d개 열이 %d개." - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "대화 상자" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" - -#: src/cthulhu/messages.py:2633 -#, fuzzy, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] " 파일을 찾았습니다." - -#: src/cthulhu/messages.py:2640 -#, fuzzy, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "폼" - -#: src/cthulhu/messages.py:2647 -#, fuzzy, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "머리말" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "0 항목" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "파일을 찾을 수 없습니다." - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] " 파일을 찾았습니다." - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "청크가 더 이상 없습니다." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "테이블 나가기." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "목록 항목" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "목록 항목" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "테이블, 행이 %d개 열이 %d개." - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, fuzzy, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "행 %d, 열 %d" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "테이블, 행이 %d개 열이 %d개." - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%s 퍼센트" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] " 픽셀" - -#: src/cthulhu/messages.py:2777 -#, fuzzy, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] " %d %s 문자 " - -#: src/cthulhu/messages.py:2784 -#, fuzzy, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "선택 안 함" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d 스페이스 " - -#: src/cthulhu/messages.py:2813 -#, fuzzy, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d 탭 " - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "테이블" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "테이블, 행이 %d개 열이 %d개." - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "테이블, 행이 %d개 열이 %d개." - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "테이블, 행이 %d개 열이 %d개." - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "섹션" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "토글 단추" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, fuzzy, python-format -msgid "LEVEL %d" -msgstr "트리 단계 %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "트리 단계 %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "트리 단계 %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "물음" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "콤보 상자" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "HTML내용" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "열쇠글" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "콜론" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "줄바꿈" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "섹션" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "문단" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -#, fuzzy -msgctxt "role" -msgid "errata" -msgstr "시에라" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "열쇠글" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "찾기" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "섹션" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "탭 목록" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "따옴표" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "HTML내용" - -#: src/cthulhu/object_properties.py:344 -#, fuzzy, python-format -msgid "h%d" -msgstr "헤더" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "비례" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "세로줄" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "비례" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "세로줄" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "비례" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "세로줄" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "메뉴 항목" - -#: src/cthulhu/object_properties.py:415 -#, fuzzy -msgid "Icon panel" -msgstr "옵션 창" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "HTML내용" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "애니메이션" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "HTML내용" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "애니메이션" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "찾는 중입니다." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "머리말이 더 이상 없습니다." - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "스핀 단추" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "접힘" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "확장" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -#, fuzzy -msgid "horizontal" -msgstr "비례" - -#: src/cthulhu/object_properties.py:519 -#, fuzzy -msgid "vertical" -msgstr "세로줄" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "표시됨" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "표시 안 함" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "켬 " - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "끔 " - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "표시 안 함" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "누름" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "안 누름" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "선택 안 함" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "라디오 단추" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "선택 안 함" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "선택 안 함" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "접근할 수 없음" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "접근할 수 없음" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "비활성화" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -#, fuzzy -msgctxt "text" -msgid "rdonly" -msgstr "다이얼" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -#, fuzzy -msgid "required" -msgstr "가운데" - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "선택 해제함" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "잘못됨" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "잘못됨" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "스핀 단추" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "스핀 단추" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "잘못됨" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "찾기" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "오르카 스크린 읽기 및 돋보기" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "닫기" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "찾기" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "찾을 대상(_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "찾을 대상:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "창 위(_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "창 위" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "시작할 곳:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "끝까지 찾으면 넘어가기(_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "거꾸로 찾기(_B)" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "섹션" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "대소문자 구별(_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "전체 단어가 맞을 때만(_E)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "함수" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "기본값" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "대문자" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "하이퍼링크" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "프로그램" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "창" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "오르카 기본 설정" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "노트북(_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "키보드 배치" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "시작할 곳:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "말하기: " - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "점자 바인딩" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "프로그램" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "진행률 표시줄" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "펑션 키 사용(_F)" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "요소 표시(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "일반" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "볼륨(_L):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "음 높이(_T):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "속도(_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "사람(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "음성 합성기(_Z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "음성 시스템(_S):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "음성 설정(_V):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "음성 설정(_V):" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "음성 설정(_V):" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "음성 사용(_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "자세히 말하기(_B)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "자세히 말하기" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "모두(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "문장 부호 단계" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "빈 줄 말하기" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "들여쓰기 및 맞춤을 말하기(_I)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "빈 줄 말하기" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "빈 줄 말하기" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "말하기: " - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "음성" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "점자 지원(_S)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "역할 이름 줄임말(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "단어 단위로 반향음(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "옵션 더 자세히 표시" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "없음(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "하이퍼링크" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "돋보기 사용(_M)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "점자" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "키 반향음 사용(_K)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "펑션 키 사용(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "조합 키 사용(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "펑션 키 사용(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "음성 사용(_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "조합 키 사용(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "펑션 키 사용(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "동작 키 사용(_T)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -#, fuzzy -msgid "Enable _navigation keys" -msgstr "펑션 키 사용(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "단어 단위로 반향음(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "단어 단위로 반향음(_W)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "키 반향" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "오르카 조합 키(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "키 바인딩" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "문장 부호 단계" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -#, fuzzy -msgid "_Delete" -msgstr "선택함" - -#: src/cthulhu/cthulhu-setup.ui:3204 -#, fuzzy -msgid "Pronunciation" -msgstr "함수" - -#: src/cthulhu/cthulhu-setup.ui:3243 -#, fuzzy -msgid "_Speak all" -msgstr "말하기: " - -#: src/cthulhu/cthulhu-setup.ui:3257 -#, fuzzy -msgid "Speak _none" -msgstr "말하기: " - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -#, fuzzy -msgid "Move _down one" -msgstr "셀로 이동" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -#, fuzzy -msgid "Move to _top" -msgstr "셀로 이동" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "점자 상태 정보 사용(_M)" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "AI 어시스턴트 활성화" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "제공자(_P):" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (로컬 - 무료)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API 키 파일(_K):" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "API 키 파일 경로" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "_Claude API 키 가져오기" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "브라우저를 열어 Claude API 키를 가져와 자동으로 저장합니다" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "AI 작업 전 확인 필요" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama 모델(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Ollama 모델 이름(예: llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama 엔드포인트(_E):" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API 엔드포인트 URL(예: http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "스크린샷 품질(_Q):" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "낮음" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "중간" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "높음" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI 어시스턴트" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "언어 코드(_L):" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "배율(_S):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "그레이스케일 이미지(_G)" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "이미지 반전(_I)" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "흑백 이미지(_B)" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "흑백 임계값(_T):" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "색상 분석(_A)" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "결과를 클립보드에 복사(_C)" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "섹션" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "테이블" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -#, fuzzy -msgctxt "textattr" -msgid "font effect" -msgstr "선택 안 함" - -#: src/cthulhu/text_attribute_names.py:132 -#, fuzzy -msgctxt "textattr" -msgid "indent" -msgstr "찾기" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -#, fuzzy -msgctxt "textattr" -msgid "invisible" -msgstr "접근할 수 없음" - -#: src/cthulhu/text_attribute_names.py:156 -#, fuzzy -msgctxt "textattr" -msgid "justification" -msgstr "섹션" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "왼쪽 괄호" - -#: src/cthulhu/text_attribute_names.py:176 -#, fuzzy -msgctxt "textattr" -msgid "line height" -msgstr "줄 오른쪽" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "문단" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -#, fuzzy -msgctxt "textattr" -msgid "pixels below lines" -msgstr "빈 줄 말하기" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "오른쪽 괄호" - -#: src/cthulhu/text_attribute_names.py:221 -#, fuzzy -msgctxt "textattr" -msgid "rise" -msgstr "로미오" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "달력 행사" - -#: src/cthulhu/text_attribute_names.py:234 -#, fuzzy -msgctxt "textattr" -msgid "size" -msgstr "크기(_Z):" - -#: src/cthulhu/text_attribute_names.py:243 -#, fuzzy -msgctxt "textattr" -msgid "stretch" -msgstr "옵션 창" - -#: src/cthulhu/text_attribute_names.py:251 -#, fuzzy -msgctxt "textattr" -msgid "strike through" -msgstr "취소선" - -#: src/cthulhu/text_attribute_names.py:258 -#, fuzzy -msgctxt "textattr" -msgid "style" -msgstr "물결" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -#, fuzzy -msgctxt "textattr" -msgid "text rotation" -msgstr "현재 위치(_U)" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "줄바꿈" - -#: src/cthulhu/text_attribute_names.py:295 -#, fuzzy -msgctxt "textattr" -msgid "variant" -msgstr "찾는 중입니다." - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "세로줄" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "줄 오른쪽" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -#, fuzzy -msgctxt "textattr" -msgid "writing mode" -msgstr "학습 모드를 끝냅니다." - -#: src/cthulhu/text_attribute_names.py:341 -#, fuzzy -msgctxt "textattr" -msgid "true" -msgstr "트리" - -#: src/cthulhu/text_attribute_names.py:349 -#, fuzzy -msgctxt "textattr" -msgid "false" -msgstr "더 빨리." - -#: src/cthulhu/text_attribute_names.py:358 -#, fuzzy -msgctxt "textattr" -msgid "none" -msgstr "없음" - -#: src/cthulhu/text_attribute_names.py:365 -#, fuzzy -msgctxt "textattr" -msgid "engrave" -msgstr "비활성화" - -#: src/cthulhu/text_attribute_names.py:372 -#, fuzzy -msgctxt "textattr" -msgid "emboss" -msgstr "내장" - -#: src/cthulhu/text_attribute_names.py:379 -#, fuzzy -msgctxt "textattr" -msgid "outline" -msgstr "줄바꿈" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "줄바꿈" - -#: src/cthulhu/text_attribute_names.py:393 -#, fuzzy -msgctxt "textattr" -msgid "line through" -msgstr "취소선" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "바로가기" - -#: src/cthulhu/text_attribute_names.py:407 -#, fuzzy -msgctxt "textattr" -msgid "black" -msgstr "빈칸" - -#: src/cthulhu/text_attribute_names.py:414 -#, fuzzy -msgctxt "textattr" -msgid "single" -msgstr "링크" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "더 낮게." - -#: src/cthulhu/text_attribute_names.py:435 -#, fuzzy -msgctxt "textattr" -msgid "char" -msgstr "찰리" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "열쇠글" - -#: src/cthulhu/text_attribute_names.py:452 -#, fuzzy -msgctxt "textattr" -msgid "word char" -msgstr "찰리" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "채움" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "트리 테이블" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "왼쪽 알트" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "오른쪽 알트" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "퍼센트" - -#: src/cthulhu/text_attribute_names.py:493 -#, fuzzy -msgctxt "textattr" -msgid "no justification" -msgstr "들여쓰기 및 맞춤을 말하기(_I)" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "채움" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -#, fuzzy -msgctxt "textattr" -msgid "extra condensed" -msgstr "확장" - -#: src/cthulhu/text_attribute_names.py:521 -#, fuzzy -msgctxt "textattr" -msgid "condensed" -msgstr "섹션" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "섹션" - -#: src/cthulhu/text_attribute_names.py:535 -#, fuzzy -msgctxt "textattr" -msgid "normal" -msgstr "다이얼" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "확장" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "확장" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "확장" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "확장" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -#, fuzzy -msgctxt "textattr" -msgid "italic" -msgstr "잘못됨" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "기본값" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "텍스트" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "머리말" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "줄바꿈" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -#, fuzzy -msgctxt "textattr" -msgid "super" -msgstr "수퍼" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "중지" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "텍스트" - -#: src/cthulhu/text_attribute_names.py:648 -#, fuzzy -msgctxt "textattr" -msgid "middle" -msgstr "마이크" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "아래(_B):" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -#, fuzzy -msgctxt "textattr" -msgid "inherit" -msgstr "기가헤르츠" - -#: src/cthulhu/text_attribute_names.py:677 -#, fuzzy -msgctxt "textattr" -msgid "lr-tb" -msgstr "경보" - -#: src/cthulhu/text_attribute_names.py:684 -#, fuzzy -msgctxt "textattr" -msgid "rl-tb" -msgstr "트리 테이블" - -#: src/cthulhu/text_attribute_names.py:691 -#, fuzzy -msgctxt "textattr" -msgid "tb-rl" -msgstr "테이블" - -#: src/cthulhu/text_attribute_names.py:698 -#, fuzzy -msgctxt "textattr" -msgid "tb-lr" -msgstr "테이블" - -#: src/cthulhu/text_attribute_names.py:705 -#, fuzzy -msgctxt "textattr" -msgid "bt-rl" -msgstr "컨트롤" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "채움" - -#: src/cthulhu/text_attribute_names.py:726 -#, fuzzy -msgctxt "textattr" -msgid "rl" -msgstr "컨트롤" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "탭" - -#: src/cthulhu/text_attribute_names.py:738 -#, fuzzy -msgctxt "textattr" -msgid "solid" -msgstr "슬라이더" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "스핀 단추" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/lt.po b/po/lt.po deleted file mode 100644 index 67c6ed9..0000000 --- a/po/lt.po +++ /dev/null @@ -1,9260 +0,0 @@ -# translation of lt.po to Lithuanian -# Lithuanian translation of cthulhu. -# Copyright (C) 2006, 2007 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# -# -# Žygimantas Beručka , 2006. -# Gintautas Miliauskas , 2006, 2007. -# Romas Mazeika , 2007. -# Aurimas Černius , 2013-2022. -# -msgid "" -msgstr "" -"Project-Id-Version: lt\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-15 22:23+0300\n" -"Last-Translator: Aurimas Černius \n" -"Language-Team: Lietuvių \n" -"Language: lt\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"(n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu ekrano skaityklė" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "ekrano skaityklė;kalba;brailio raštas;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "įspj" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "rod" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "drb" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "žml" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "splvpar" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "stlpant" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "išs" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "pktg" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "rėm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "skambinti" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "aplp" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "pieš" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "rinkp" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "skt" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "šrfp" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "forma" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "stkp" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "antršt" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "pav" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "vrėm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "eti" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "slkspo" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "nrd" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "srš" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "sršel" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnuju" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuelm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "parpol" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pslk" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "krtsrš" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "skd" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "slpt" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "iškmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pžngj" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "myg" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "žymak" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "žymel" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "šknpo" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "eilant" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "slnkj" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "slnkpo" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "skcj" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "skrtuk" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "slnk" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "prskpo" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "sukt" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "būsj" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "lnt" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "lang" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "atkbmnuel" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tkst" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "prjgmyg" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "įrank" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "pšk" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "med" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "mdžlnt" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "než" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "rodn" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "lng" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "antr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "por" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "prog" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "redj" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "įtrp" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Čekų lygis 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Ispanų lygis 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanados prancūzų lygis 1" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Kanados prancūzų lygis 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvių lygis 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Olandijos olandų lygis 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvegų lygis 1" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvegų lygis 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvegų lygis 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvegų lygis 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Lenkų lygis 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugalų lygis 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Švedų lygis 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabų lygis 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Velsiečių lygis 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Velsiečių lygis 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Vokiečių lygis 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Vokiečių lygis 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Vokiečių lygis 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "JK anglų lygis 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "JK anglų lygis 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "JAV anglų lygis 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "JAV anglų lygis 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanados prancūzų lygis 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Prancūzijos prancūzų lygis 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Graikų lygis 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi lygis 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Vengriškas 8 taškų kompiuteris" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Vengrų lygis 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Vengrų lygis 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italų lygis 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgijos olandų lygis 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "tarpas" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nauja eilutė" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabuliacija" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "šauktukas" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "citata" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "grotelės" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "doleris" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procentas" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ir" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrofas" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "kairysis skliaustelis" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "dešinysis skliaustelis" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "žvaigždutė" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plius" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "kablelis" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "brūkšnelis" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "taškas" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "dešininis brūkšnys" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dvitaškis" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "kabliataškis" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "mažiau nei" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "lygu" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "daugiau nei" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "klaustukas" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "eta" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "kairysis skliaustas" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "kairinis brūkšnys" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "dešinysis skliaustas" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "stogelio ženklas" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "pabraukimas" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "kairinis kirtis" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "kairysis riestinis skliaustas" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertikalus brūkšnelis" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "dešinysis riestinis skliaustas" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tildė" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "nepertraukiamas tarpas" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "apverstas šauktukas" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centai" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "svaras" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "valiutos simbolis" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jena" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "perlaužtas vertikalus brūkšnelis" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "sekcija" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "su brūkšniu" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "autorinės teisės" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "viršutinis indeksas" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "kairysis dvigubas kampinis skliaustas" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "loginis ne" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "kėlimo brūkšnelis" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registruotas" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "brūkšnelis" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "laipsniai" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plius minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "pakelta kvadratu" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "pakelta kubu" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "su dešininiu kirčiu" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "miu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "paragrafo žymuo" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "vidurinis taškas" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "sedilė" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "pakelta pirmuoju" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "laipsnio simbolis" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "dešinysis dvigubas kampinis skliaustas" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "ketvirtis" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "pusė" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "trys ketvirčiai" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "apverstas klaustukas" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a su dešininiu kirčiu" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A SU KAIRINIU KIRČIU" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A SU DEŠININIU KIRČIU" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A SU STOGELIU" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A SU TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A SU UMLIAUTU" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A SU ŽIEDU" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C SU SEDILE" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E SU KAIRINIU KIRCIU" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E SU DEŠININIU KIRČIU" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E SU STOGELIU" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E SU UMLIAUTU" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I SU KAIRINIU KIRČIU" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I SU DEŠININIU KIRČIU" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I SU STOGELIU" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I SU UMLIAUTU" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N SU TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O SU KAIRINIU KIRČIU" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O SU DEŠININIU KIRČIU" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O SU STOGELIU" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O SU TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O SU UMLIAUTU" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "padauginta iš" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "PERBRAUKTA O" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U SU KAIRINIU KIRČIU" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U SU DEŠININIU KIRČIU" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U SU STOGELIU" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U SU UMLIAUTU" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y SU DEŠININIU KIRČIU" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "SPYGLYS" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s su grotelėmis" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a su kairiniu kirčiu" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a su stogeliu" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a su tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a su umliautu" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a su skrituliuku" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c su sedile" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e su kairiniu kirčiu" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e su dešininiu kirčiu" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e su stogeliu" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e su umliautu" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i su kairiniu kirčiu" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i su dešininiu kirčiu" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i su stogeliu" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i su umliautu" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n su tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o su kairiniu kirčiu" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o su dešininiu kirčiu" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o su stogeliu" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o su tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o su umliautu" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "padalinta iš" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "perbraukta o" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "spyglys" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u su dešininiu kirčiu" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u su kairiniu kirčiu" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u su stogeliu" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u su umliautu" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y su dešininiu kirčiu" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y su umliautu" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y SU UMLIAUTU" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florinas" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "brūkšnelis" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "kairioji vienguba kabutė" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "dešinioji vienguba kabutė" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "kairioji vienguba kabutė" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "kairiosios kabutės" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "dešiniosios kabutės" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dviguba kairioji kabutė" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "durklas" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dvigubas durklas" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "ženklelis" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trikampio formos ženklelis" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promilė" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "štrich" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "štrich štrich" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "triguba štrich" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "brūkšnelio formos ženklelis" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euras" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "prekinis ženklas" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "varnelės formos ženklelis" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "pastorintas varnelės formos ženklelis" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "kryželio formos ženklelis" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "viršutinis indeksas 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "viršutinis indeksas 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "viršutinis indeksas 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "viršutinis indeksas 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "viršutinis indeksas 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "viršutinis indeksas 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "viršutinis indeksas 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "viršutinis indeksas pliusas" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "viršutinis indeksas minusas" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "viršutinis indeksas lygybė" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "viršutinis indeksas skliaustų pradžia" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "viršutinis indeksas skliaustų pabaiga" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "viršutinis indeksas n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "apatinis indeksas 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "apatinis indeksas 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "apatinis indeksas 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "apatinis indeksas 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "apatinis indeksas 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "apatinis indeksas 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "apatinis indeksas 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "apatinis indeksas 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "apatinis indeksas 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "apatinis indeksas 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "apatinis indeksas pliusas" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "apatinis indeksas minusas" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "apatinis indeksas lygybė" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "apatinis indeksas skliaustų pradžia" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "apatinis indeksas skliaustų pabaiga" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "užpildytas kvadratinis ženklelis" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "užpildytas rombo formos ženklelis" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "objekto pakaitinis simbolis" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Perkelti žymeklį į dabartinį elementą" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Spustelti kairiu mygtuku ant esamo plokščio peržiūros įrašo" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Spustelti dešiniu mygtuku ant esamo plokščio peržiūros įrašo" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Garsiai perskaityti visą dokumentą" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Perskaityti visą langą naudojant plokščia peržiūrą" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Atlikti bendrinę operaciją „kur aš esu“" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Atlikti detalią operaciją „kur aš esu“" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Perskaityti dabartinį žymėjimą" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Perskaityti saito informaciją" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Perskaityti numatytąjį mygtuką" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Perskaityti būsenos juostą" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Perskaityti pavadinimo juostą" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Atverti paieškos dialogą" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Rodyti veiksmų meniu" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Ieškoti kito eilutės pasikartojimo" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Ieškoti ankstesnio eilutės pasikartojimo" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Įeiti ar išeiti iš paprastos peržiūros veiksenos" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Perkelti paprastą peržiūrą į dabartinį objektą" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Perkelti paprastą peržiūrą į pradžios padėtį" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Perkelti paprastą peržiūrą į pabaigos padėtį" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Perkelti paprastą peržiūrą į praeitos eilutės pradžią" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Perskaityti dabartinę paprastos peržiūros eilutę" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Pažodžiui perskaityti dabartinę paprastos peržiūros eilutę" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Fonetiškai perskaityti dabartinę paprastos peržiūros eilutę" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Perkelti paprastą peržiūrą į kitos eilutės pradžią" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Perkelti paprastą peržiūrą į praeitą elementą ar žodį" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Perskaityti dabartinį paprastos peržiūros elementą ar žodį" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Perskaityti dabartinį paprastos peržiūros elementą ar žodį" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Fonetiškai perskaityti dabartinį paprastos peržiūros elementą ar žodį" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Perkelti paprastą peržiūrą į kitą elementą ar žodį" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Perkelti paprastą peržiūrą į žodį virš dabartinio žodžio" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Perskaityti dabartinį paprastos peržiūros objektą" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Perkelti paprastą peržiūrą į žodį žemiau dabartinio žodžio" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Perkelti paprastą peržiūrą prie ankstesnio simbolio" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Perskaityti dabartinį paprastos peržiūros simbolį" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Fonetiškai perskaityti dabartinį paprastos peržiūros simbolį" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Perskaityti dabartinio paprastos peržiūros simbolio unikodo vertę" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Perkelti paprastą peržiūrą prie kito simbolio" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Perkelti paprastą peržiūrą į eilutės pabaigą" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Perkelti paprastą peržiūrą į apatinį kairį kampą" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Nukopijuoti paprastos peržiūros įrašą į iškarpinę" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Pridėti paprastos peržiūros įrašą į iškarpinę" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Perkelti paprastą peržiūrą" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Perjungia, ar skaityti tik esamą lentelės langelį, ar visą eilutę" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Perskaityti požymius susietus su esamu teksto simboliu" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Paslinkti brailio ekraną į kairę" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Paslinkti brailio ekraną į dešinę" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Grįžti prie objekto sufokusuoto klaviatūra" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Įjungti ar išjungti nustatytą brailio ekraną" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Apdoroti žymiklio perkėlimo klavišą" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Paženklinti teksto žymėjimo pradžią" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Paženklinti teksto žymėjimo pabaigą" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Pradėti mokymosi režimą. Norėdami išeiti iš mokymo režimo paspauskite escape" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Sulėtinti kalbėjimą" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Pagreitinti kalbėjimą" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Pažeminti kalbėjimo toną" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Paaukštinti kalbėjimo toną" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Pagarsinti kalbėjimą" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Patylinti kalbėjimą" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Ieškoti ankstesnio eilutės pasikartojimo" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Cikliškai pereiti prie kito klavišo pakartojimo lygio" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Sulėtinti kalbėjimą" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Pagreitinti kalbėjimą" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Balso tipo nustatymai" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Įjungti/nutildyti kalbėjimą" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Perjungti kalbos išsamumo lygį" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Perjungti išdėstymo veikseną" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Išjungti ekrano skaityklę" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Parodyti nuostatų konfigūravimo dialogą" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Parodyti programos nuostatų konfigūravimo dialogą" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Perjungti įtraukų ir lygiavimų skaitymą" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Keisti pasakomų skaičių stilių" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Pereiti prie kito skyrybos skaitymo lygio" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Cikliškai pereiti prie kito klavišo pakartojimo lygio" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Pereiti prie kito nustatymų profilio.ž" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Pereiti prie kito didžiųjų raidžių stiliaus" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Pereiti prie kito klavišo pakartojimo lygio" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Pereiti prie kito derinimo lygio vykdymo metu" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Pažymėti vietą, kur dabar esu, dabartinės pozicijos atžvilgiu" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Eiti į ankstesnės gairės vietą" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Eiti prie gairės" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Eiti prie kitos gairės vietos" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Įdėti gairę" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Išsaugoti gaires" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Perjungti pelės peržiūros veikseną" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Pateikti dabartinį laiką" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Pateikti dabartinę datą" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Pateikti dabartinio objekto dydį ir vietą" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Perduoti kitą komandą dabartinei programai" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Perskaityti ir parodyti Brailiu ankstesnį pokalbių kambario pranešimą" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Perjungti, ar mes pranešame, kai mūsų draugai rašo" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Perjungti, ar teikiamos pokalbių kambario specifinės pranešimų istorijos" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Perjungti, ar pokalbių kambario pranešimų pradžioje paminimas pokalbio " -"kambario pavadinimas" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Eilutė kairėn" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Eilutė dešinėn" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Eilutė aukštyn" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Eilutė žemyn" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Sustabdyti" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Viršuje kairėje" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Apačioje kairėje" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Žymiklio pozicija" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Šeši taškai" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Žymiklio perstūmimas" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Pradėti kirpimą" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Baigti žymėjimą" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Pateikti paskutinį pranešimą" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Parodyti pranešimų sąrašą" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Pateikti ankstesnį pranešimą" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Perskaityti paskutinį pranešimą" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Eiti prie kito simbolio" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Eiti prie ankstesnio simbolio" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Eiti prie kito žodžio" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Eiti prie ankstesnio žodžio" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Eiti į kitą eilutę" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Eiti į ankstesnę eilutę" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Eiti į failo pradžią" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Eiti į failo pabaigą" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Eiti į eilutės pradžią" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Eiti į eilutės pabaigą" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Eiti prie kito objekto" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Eiti prie ankstesnio objekto" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Išplėsti pasirenkamų reikšmių sąrašą" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Perjungti tarp įprastinio ir ekrano-skaityklės žymiklio judėjimo" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Sudėtingesnis tiesioginės srities mandagumo nustatymas" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Išjungti numatytą tiesioginė srities mandagumo lygį" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Patikrinti tiesioginės srities pranešimą" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Stebėti tiesiogines sritis" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Pašalinti aktyvumą nuo elemento po pele" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Nustatyti eilutę, kurią naudoti kaip dinamines stulpelių antraštes" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Išvalo dinamines stulpelių antraštes" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Nustatyti stulpelį, kurį naudoti kaip dinamines eilučių antraštes" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Išvalyti dinamines eilučių antraštes" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Pateikti įvesties eilutės turinį" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Perjungti judėjimo pagal struktūrą klavišus" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Eiti prie ankstesnio citatos bloko" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Eiti prie kito citatos bloko" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Parodyti citatų blokų sąrašą" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Eiti prie ankstesnio mygtuko" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Eiti prie kito mygtuko" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Parodyti mygtukų sąrašą" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Eiti prie kito žymimojo langelio" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Eiti prie kito kito žymimojo langelio" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Parodyti žymimųjų langelių sąrašą" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Eiti prie ankstesnio spaudžiamo elemento" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Eiti prie kito spaudžiamo elemento" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Parodyti spaudžiamų elementų sąrašą" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Eiti prie ankstesnio pasirinkimo lauko" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Eiti prie kito pasirinkimo lauko" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Eiti į konteinerio pradžią" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Eiti į konteinerio pabaigą" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Parodyti pasirinkimo sąrašų sąrašą" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Eiti prie ankstesnio įvedimo lauko" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Eiti prie kito įvedimo lauko" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Parodyti įvedimo laukų sąrašą" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Eiti prie ankstesnio formos laukelio" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Eiti prie kito formos laukelio" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Parodyti formos laukų sąrašą" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Eiti prie ankstesnės antraštės" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Eiti prie kitos antraštės" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Parodyti antraščių sąrašą" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Eiti prie ankstesnės %d lygio antraštės" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Eiti prie kitos %d lygio antraštės" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Parodyti %d lygmens antraštes" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Eiti prie ankstesnio vidinio rėmelio" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Eiti prie kitos vidinio rėmelio" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Parodyti vidinių rėmelių sąrašą" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Eiti prie ankstesnio paveikslėlio" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Eiti prie kito paveikslėlio" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Parodyti paveikslėlių sąrašą" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Eiti į ankstesnę žymę" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Eiti į kitą žymę" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Parodyti žymių sąrašą" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Eiti prie ankstesnio stambaus objekto" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Eiti prie kito stambaus objekto" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Parodyti didelių objektų sąrašą" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Eiti prie ankstesnio saito" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Eiti prie kito saito" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Parodyti saitų sąrašą" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Eiti prie ankstesnio sąrašo" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Eiti prie kito sąrašo" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Parodyti sąrašų sąrašą" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Eiti prie ankstesnio sąrašo elemento" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Eiti prie kito sąrašo elemento" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Parodyti sąrašo elementų sąrašą" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Eiti į ankstesnę tiesioginę sritį" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Eiti į kitą tiesioginę sritį" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Eiti į paskutinę tiesioginę sritį, atlikusią pranešimą" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Judėjimo fokusu eiti į tėvinį objektą." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Judėjimo fokusu eiti į vaikinį objektą." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Judėjimo fokusu eiti į kitą gretimą objektą." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Judėjimo fokusu eiti į ankstesnį gretimą objektą." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Spausti klaviatūra sufokusuotą objektą" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Perjungti paprastą judėjimą per objektus." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Eiti į ankstesnę pastraipą" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Eiti į kitą pastraipą" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Parodyti pastraipų sąrašą" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Eiti prie ankstesnio radijo mygtuko" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Eiti prie kito radijo mygtuko" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Parodyti radijo mygtukų sąrašą" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Eiti prie ankstesnio skirtuko" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Eiti prie kito skirtuko" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Eiti prie ankstesnės lentelės" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Eiti prie kitos lentelės" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Parodyti lentelių sąrašą" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Eiti vienu langeliu žemyn" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Eiti į pirmąjį lentelės langelį" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Eiti į paskutinįjį lentelės langelį" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Eiti vienu langeliu kairėn" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Eiti vienu langeliu dešinėn" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Eiti vienu langeliu aukštyn" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Perjungti išdėstymo veikseną" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Perjungti tarp naršymo ir fokusavimo veiksenų" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Įjungti kibaus fokuso veikseną" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Įjungti kibaus naršymo veikseną" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Eiti prie ankstesnės neaplankytos nuorodos" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Eiti prie kitos neaplankytos nuorodos" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Parodyti neaplankytų nuorodų sąrašą" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Eiti prie ankstesnės aplankytos nuorodos" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Eiti prie kitos aplankytos nuorodos" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Parodyti neaplankytų nuorodų sąrašą" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "alice blue" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antique white" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "aquamarine" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azure" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "juoda" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "blanched almond" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "mėlyna" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "mėlynai violetinė" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "ruda" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "cadet blue" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "šokoladinė" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koralo" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "cornflower blue" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "crimson" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "žydra" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "tamsiai mėlyna" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "tamsiai žydra" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "dark goldenrod" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "tamsiai pilka" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "tamsiai žalia" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "tamsi chaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "tamsiai violetinė" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "tamsi aliejinė žalia" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "tamsiai oranžinė" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "dark orchid" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "tamsiai raudona" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "dark salmon" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "dark sea green" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "dark slate blue" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "dark slate gray" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "dark turquoise" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "tamsiai violetinė" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "deep pink" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "deep sky blue" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "blyški pilka" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodger blue" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "fire brick" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "floral white" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "forest green" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "ghost white" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "auksinė" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "goldenrod" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "pilka" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "žalia" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "žalsvai geltona" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "honeydew" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "hot pink" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indian red" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "ivory" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "chaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavender" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavender blush" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "lawn green" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "lemon chiffon" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "šviesiai mėlyna" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "šviesi koralo" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "šviesiai žydra" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "light goldenrod yellow" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "šviesiai pilka" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "šviesiai žalia" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "šviesiai rožinė" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "light salmon" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "light sea green" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "light sky blue" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "light slate gray" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "light steel blue" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "light yellow" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lime" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "lime green" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linen" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "violetinė" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "bordo" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "medium aquamarine" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "medium blue" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "medium orchid" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "medium purple" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "medium sea green" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "medium slate blue" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "medium spring green" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "medium turquoise" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "medium violet red" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "midnight blue" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "mint cream" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "misty rose" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "moccasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajo white" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "navy" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "old lace" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olive" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "olive drab" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oranžinė" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "raudonai oranžinė" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchid" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "pale goldenrod" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "pale green" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "pale turquoise" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "pale violet red" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "peach puff" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rožinė" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "plum" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "powder blue" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purpurinė" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "raudona" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rožinė ruda" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "royal blue" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "saddle brown" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmon" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "sandy brown" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "sea green" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "seashell" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "sidabrinė" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "sky blue" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "slate blue" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "slate gray" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "snow" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "spring green" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "steel blue" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "tan" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "teal" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "thistle" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomato" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquoise" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violetinė" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "wheat" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "balta" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "white smoke" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "geltona" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "gelsvai žalia" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktyvuoti" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatinio fokuso veiksena struktūriniame judėjime" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatinio fokuso veiksena judant klaviatūros žymikliu" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatinio fokuso veiksena judant žymikliu" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "_7 taškas" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "_8 taškas" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "7 i_r 8 taškai" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Atsisakyti" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Pereiti prie" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Gerai" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Piktograma" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Nėra" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Perskaityti paraidžiui" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Pranešti, kai jūsų _draugai rašo" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Pateikti pokalbių kambarių specifines _pranešimų istorijas" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Sakyti pranešimus iš" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Visi _kanalai" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Visi kanalai, kai _bet kuris %s langas yra aktyvus" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Kanalas tik jei jo _langas aktyvus" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Skaityti pokalbių kambario pavadinimą" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Įjungti išdėstymo veikseną turiniui" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dvigubas paspaudimas" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trigubas paspaudimas" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintezatorius pagal nutylėjimą" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Tikroji eilutė" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Pakeičiančioji eilutė" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Įjungti _simbolių atkartojimą" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Įjungti ne tarpų _diakritinius klavišus" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Esama vieta" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Mažiausias atitikimo tekstui ilgis:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Paieškos parametrai" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Paieškos metu garsiai skaityti tik pakeistas eilutes" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Garsiai perskaityti rezultatus paieškos metu" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Komanda" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Klavišo priskyrimas" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Numatytasis" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Mokymosi veiksena" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Veiksmai" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Brailio priskyrimai" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Gairės" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Data ir laikas" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Pelės peržiūra" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Judėjimas objektais" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objekto informacija" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Neribotas" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Paprasta peržiūra" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Kalba ir išsamumas" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Paprastos peržiūros turinys" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Pakeistas" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Darbalaukis" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Pranešimai" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Gauta" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Pranešimų perskaitymas" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu nuostatos %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Pažymėti brailiu" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Nenaudojama, kai" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Garsiai skaityti" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Išsaugoti profilį kaip konfliktą" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Naudotojo profilio konfliktas!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profilis %s jau yra.\n" -"Tęsti atnaujinant esamą profilį su šiais pakeitimais?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Įkelti naudotojo profilį" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Jūs ruošiatės pakeisti aktyvų profilį. Jei jūs\n" -"kątik atlikote pakeitimus savo nuostatose, jie bus\n" -"atšaukti profilio įkėlimo metu.\n" -"\n" -"Tęsti profilio įkėlimą nepaisant ankstensių pakeitimų?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Išsaugoti profilį kaip" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profilio pavadinimas:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Pašalinti naudotojo profilį" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Tuoj pašalinsite profilį %s. Visi neįrašyti bei šiame profilyje įrašyti " -"nustatymai bus prarasti. Ar norite tęsti ir pašalinti šį profilį bei visus " -"susijusius nustatymus?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Visos" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Programa" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Langas" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Nėra" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Kai kurie" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Dauguma" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Eilutė" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Sakinys" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Citatos blokas" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Mygtukas" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Antraštė" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Žymimasis langelis" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Spaudžiamas elementas" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Pasirinkimo sąrašas" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Aprašymas" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Antraštė" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Vidinis rėmelis" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Paveikslėlis" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiketė" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Žymelė" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Lygmuo" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Nuoroda" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Sąrašas" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Sąrašo elementas" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objektas" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Pastraipa" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radijo mygtukas" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rolė" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Pasirinktas elementas" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Būsena" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Tekstas" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Vertė" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Citatų blokai" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Mygtukai" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Žymimieji langeliai" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Spaudžiami elementai" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Pasirinkimo sąrašai" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Įrašai" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Formos laukai" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Antraštės" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Vidiniai rėmeliai" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Paveikslėliai" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "%d lygmens antraštės" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Žymelės" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Dideli objektai" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Nuorodos" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Sąrašai" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Sąrašo elementai" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Pastraipos" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radijo mygtukai" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Lentelės" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Neaplankytos nuorodos" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Aplankytos nuorodos" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Puslapio navigacija" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Automatiškai pradėti garsiai skaityti puslapį, kai jis pirmą kartą įkrautas" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Pateikti puslapio santrauką, kai jis pirmą kartą įkeliamas" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Skaidyti kalbą į _dalis tarp pauzių" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s numatytasis balsas" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Numatytasis" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hipersaitas" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Didžiosiomis" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Rašybos tikrinimas" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Rašybos _klaida" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Rašybos _pasiūlymas" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Pateikti _klaidos kontekstą" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Pasakyti langelio koordinates skaičiuoklėje" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Visada pasakyti skaičiuoklės pažymėtą sritį" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Paskelbti langelio antraštę" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Lentelės navigacija" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Praleisti tuščius langelius" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Perskaityti _langelį" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Garsiai perskaityti langelio koordinates" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Garsiai perskaityti langelio dydį" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Požymio pavadinimas" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Naudoti navigaciją žymikliu" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Įjungti navigaciją pagal struktūrą" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Garso _tema:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Garso tema" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Trumpas" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d pranešimas" -msgstr[1] "%d pranešimai" -msgstr[2] "%d pranešimų" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Lyg2" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Valdymas" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "kairysis shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "kairysis alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "kairysis control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "dešinysis shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "dešinysis alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "dešinysis control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "kairysis meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "dešinysis meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "lyg2 lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "kairysis tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "grįžimo klavišas" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "įvedimo klavišas" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "įvedimo klavišas" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "aukštyn" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "žemyn" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "aukštyn" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "dešinėn" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "aukštesnysis kairėn" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "aukštesnysis dešinėn" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "meniu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "pagalba" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "dauginti" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "veiksenos perjungimas" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "išėjimo klavišas" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "įterpti" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "trinti" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "pradžia" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "pabaiga" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "pradėti" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "su stogeliu" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "su skrituliuku" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "perbraukta" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Įterpti" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "_Didž" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "pusjuodis %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "kursyvas %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "pusjuodis kursyvas %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "indeksas %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "pusjuodis indeksas %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "kaligrafinis %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "tuščiaviduris %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "pusjuodis kaligrafinis %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "be užraitų %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "be užraitų pusjuodis %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "be užraitų kursyvas %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "be užraitų pusjuodis kursyvas %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "lygiaplotis %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "be taškų %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "rodyklė į kairę" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "rodyklė aukštyn" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "rodyklė į dešinę" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "rodyklė žemyn" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "rodyklė į abi puses" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "rodyklė aukštyn ir žemyn" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "rodyklė į šiaurės vakarus" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "rodyklė į šiaurės rytus" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "rodyklė į pietryčius" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "rodyklė į kairę iš stulpelio" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "rodyklė aukštyn iš stulpelio" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "rodyklė į dešinę iš stulpelio" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "rodyklė žemyn iš stulpelio" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dviguba rodyklė į kairę" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dviguba rodyklė aukštyn" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dviguba rodyklė į dešinę" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dviguba rodyklė žemyn" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dviguba rodyklė į abi puses" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dviguba rodyklė aukštyn ir žemyn" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dviguba rodyklė į šiaurės vakarus" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dviguba rodyklė į šiaurės rytus" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dviguba rodyklė į pietryčius" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dviguba rodyklė į pietvakarius" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "rodyklė į dešinę" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "trikampės dešininė rodyklė" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "mažiau nei" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "daugiau nei" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "stogelis" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "paukščiukas" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "paukščiukas" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "taškas" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dviguba vertikali linija" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horizontali elipsė" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "visiems" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "papildinys" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "dalinis diferencialas" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "kur yra" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "kur nėra" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "tuščia aibė" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "padidinti" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "sudėtinė dalis" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "ne sudėtinė dalis" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "maža dalis" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "turi kaip narį" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "neturi kaip nario" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "mažas turi kaip narį" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "įrodymo pabaiga" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "sankirta" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "sąjunga" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "suma" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "plius minus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "taškas plius" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "dalyba trupmena" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "aibės minus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "žvaigždutė" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "funkcinė kompozicija" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "išvestinė" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "kvadratinė šaknis" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "kubinė šaknis" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "ketvirto laipsnio šaknis" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcinga" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "begalybė" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "dešinysis kampas" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "kampas" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "matuojamas kampas" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sferinis kampas" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "dalinasi iš" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "nesidalina iš" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "lygiagretu" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "nelygiagretu" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "loginis ir" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "loginis arba" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "sankirta" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "sąjunga" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integralas" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dvigubas integralas" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "trigubas integralas" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "kontūro integralas" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "paviršiaus integralas" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "tūrio integralas" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integralas pagal laikrodžio rodyklę" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "kontūro pagal laikrodžio rodyklę integralas" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "kontūro prieš laikrodžio rodyklę integralas" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "todėl" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "kadangi" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "santykis" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporcija" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "taškas minus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "viršija" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrinė progresija" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homogeninė" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tildė" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "atvirkštinė tildė" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "invertuota nenori S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinuso banga" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "grupė" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "ne tildė" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minus tildė" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "beveik lygus" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ne beveik lygus" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "apytiksliai lygus" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "apytiksliai bet ne tiksliai lygus" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "nei apytiksliai, nei visiškai lygus" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "beveik lygus" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ne beveik lygus" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "beveik arba visiškai lygus" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "triguba tildė" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "visi lygūs" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekvivalentu" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometriškai ekvivalentu" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "skirtumas" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "artėja prie ribos" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometriškai lygus" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "apytiksliai lygus arba atvaizdis" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "atvaizdis apytiksliai lygaus" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "priskyrimas" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "atvirkštinis priskyrimas" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "lygu funkcinė kompozicija" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "lygu su funkcine kompozicija" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "atitinka" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "įvertis" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "lygiakampiai" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "žvaigždutė lygu" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta lygu" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "lygu pagal apibrėžimą" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "išmatuojama pagal" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "galbūt lygu" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "nelygu" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identiška" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "neidentiška" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "griežtai lygu" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "mažiau arba lygu" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "daugiau arba lygu" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "mažiau virš lygu" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "daugiau virš lygu" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "mažiau bet nelygu" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "daugiau bet nelygu" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "daug mažiau" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "daug daugiau" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "tarp" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "neekvivalentu" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "nemažiau" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "nedaugiau" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ne mažiau ar lygu" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ne daugiau ar lygu" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "mažiau ar ekvivalentu" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "daugiau ar ekvivalentu" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ne mažiau ar ekvivalentu" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ne daugiau ar ekvivalentu" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "mažiau arba daugiau" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "daugiau arba mažiau" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ne mažiau ar daugiau" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ne daugiau ar mažiau" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "yra prieš" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "yra po" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "yra prieš arba lygus" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "yra po arba lygus" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "yra prieš arba ekvivalentus" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "yra po arba ekvivalentus" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "nėra prieš" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "nėra po" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "poaibis" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "viršaibis" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "ne poaibis" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "ne viršaibis" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "poaibis arba lygu" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "viršaibis arba lygu" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ne poaibis arba lygu" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ne viršaibis arba lygu" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "poaibis bet nelygu" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "viršaibis bet ne lygu" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multi-aibė" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multi-aibių sandauga" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "multi-aibių sąjunga" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "kvadratinis atvaizdis" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadratinė kilmė" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "kvadratinis atvaizdis arba lygu" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "kvadratinė kilmė arba lygu" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "kvadratinė sankirta" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadratinė sąjunga" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "apvestas plius" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "apvestas minus" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "apvesta daugyba" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "apvesta dalyba" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "apvestas taškas" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "apvestas žiedas" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "apvesta žvaigždutė" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "apvesta lygybė" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "apvestas brūkšnelis" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plius kvadrate" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "minus kvadrate" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "daugyba kvadrate" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "taškas kvadrate" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "dešinė išvada" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "kairė išvada" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "apatinė išvada" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "viršutinė išvada" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "užtikrinimas" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modelis" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "teigiama" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "reiškia" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "trigubo brūkšnio išvadą" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dvigubo brūkšnio reiškia" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "neįrodo" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "neigiama" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "nereiškia" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "paneigta dvigubo brūkšnio reiškia" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "prieš su sąlyga" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "po su sąlyga" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normalus pogrupis" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "susideda iš normalaus pogrupio" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normalus pogrupis arba lygu" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "susideda iš normalaus pogrupio arba lygu" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "originalas" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "atvaizdis" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "daugybinis ryšys" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitinės konjunkcijos matrica" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "įterpimas" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "dešinysis kampas su arka" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "dešinysis trikampis" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "deimanto operacija" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "taško operatorius" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "žvaigždės operatorius" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "dalybos operatorius" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "varlytė" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "pusiau tiesioginio produkto kairinė normalė" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "pusiau tiesioginio produkto dešininė normalė" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "kairysis pusiau tiesioginis produktas" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "dešinysis pusiau tiesioginis produktas" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "atvirkštinė tildė lygu" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "riestinis loginis arba" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "riestinis loginis ir" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dvigubas poaibis" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dvigubas viršaibis" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dviguba sankirta" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dviguba sąjunga" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "šakutė" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "lygu ir lygiagretu" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "mažiau su tašku" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "daugiau su tašku" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "labai daug mažiau" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "labai daug daugiau" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "mažiau ar lygu arba daugiau" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "daugiau ar lygu arba mažiau" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "lygu arba mažiau" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "lygu arba daugiau" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "lygu arba prieš" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "lygu arba po" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "ne prieš arba lygu" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ne po arba lygu" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "ne kvadratinis atvaizdis arba lygu" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "ne kvadratinis originalas arba lygu" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "kvadratinis atvaizdis arba nelygu" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "kvadratinis originalas arba nelygu" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "mažiau, bet neekvivalentu" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "daugiau, bet neekvivalentu" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "prieš, bet neekvivalentu" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "po, bet neekvivalentu" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "ne normalus pogrupis" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "neturi normalaus pogrupio" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "ne normalus pogrupis arba lygu" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "neturi normalaus pogrupio arba lygu" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertikali elipsė" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "vidurinė horizontali elipsė" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "įstriža elipsė aukštyn" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "įstriža elipsė žemyn" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "elementas su ilgu horizontaliu perbraukimu" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "elementas su vertikaliu brūkšneliu ant perbraukimo" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "mažas elementas su vertikalius brūkšneliu ant perbraukimo" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "elementas su tašku virš" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "elementus su brūkšneliu virš" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "mažas elementas su brūkšneliu virš" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "elementas su brūkšneliu po" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "elementas su dviem horizontaliais brūkšniais" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "turi su ilgu horizontaliu brūkšniu" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "turi su vertikaliu brūkšneliu ant perbraukimo" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "mažas turi su vertikalius brūkšneliu ant horizontalaus perbraukimo" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "turi su brūkšneliu virš" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "mažas turi su brūkšneliu virš" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z notacijos narys" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "viršutinė riba iš dešinės" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "viršutinė riba iš kairės" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "apatinė riba iš dešinės" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "apatinė riba iš kairės" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "riestiniai skliaustai viršuje" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "riestiniai skliaustai apačioje" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "mažiau skliaustai" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "daugiau skliaustai" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "apvestas taškas" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "sąjunga su tašku" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "sąjunga su pliusu" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "kvadratinė sankirta" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "kvadratinė sąjunga" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "juodas kvadratas" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "baltas kvadratas" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "juodas rombas" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "baltas skritulys" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "juodas skritulys" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "baltas punktas" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "juodas vidutinio dydžio kvadratas" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s su pabraukimu" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s su pasviruoju brūkšneliu" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s su vertikalia linija" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "programa" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "tuščia" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "paryškinta" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "žymelė įvesta" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "žymelė išsaugota" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "žymelės išsaugoti nepavyko" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nėra gairių." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Gairė nerasta." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Praleidimo veiksena įjungta." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Nepavyksta gauti skaičiuotuvo vaizduoklio" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "piktograma" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Skyrybos lygis nustatytas į piktogramą." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "joks" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Skyrybos lygis nustatytas į jokį." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "tarti" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Skyrybos lygis nustatytas į tarimo." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Programa valdo žymiklį." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Programa valdo žymiklį." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Langelis %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "Pažymėtas %s" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "Pažymėta nuo %s iki %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "Nuimtas pažymėjimas nuo %s iki %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "Pažymėjimas nuimtas nuo %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Drausti naudoti parametrą" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Priverstinai naudoti parametrą" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "PARAMETRAS" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Nebūtini parametrai" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Naudojimas: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Šie yra netinkami: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Spausdinti žinomas veikiančias programas" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Įkelti profilį" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Nepavyko įkelti profilio: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Nepavyko paleisti ekrano skaityklės, kadangi ji negali prisijungti prie " -"darbalaukio." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Nepavyko aktyvuoti nustatymų tvarkytuvės. Išeinama." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Kitas ekrano skaityklės procesas jau veikia šiame seanse.\n" -"Paleiskite „cthulhu --replace“ tam procesui pakeisti nauju." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "VARDAS" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Naudoti atskirą katalogą naudotojo nuostatoms" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "KAT" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Šios programos versija" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Pakeisti jau veikiančią ekrano skaityklę" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Parodyti šį pagalbos pranešimą ir išeiti" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Siųsti derinimo išvestį į debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Siųsti derinimo išvestį į specifinį failą" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FAILAS" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Nustatyti naudotojo nuostatas (tektinė versija)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Nustatyti naudotojo nuostatas (grafinė versija)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Praneškite apie klaida adresu https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Žymėjimas iškirptas į iškarpinę." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "iškirpti" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Žymėjimas nukopijuotas į iškarpinę." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "nukopijuotas" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Įdėtas iškarpinės turinys." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "įdėtas" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Nepranešti, kai jūsų draugai rašo." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "pranešti, kai jūsų draugai rašo." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Žinutė iš pokalbių kambario %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nauja pokalbių kortelė %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Neskaityti pokalbių kambario pavadinimo." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "skaityti pokalbių kambario pavadinimą." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Nepateikti pokalbių kambarių specifines pranešimų istorijų." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Pateikti pokalbių kambarių specifines pranešimų istorijas." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "trynimo pradžia" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "trynimo pabaiga" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "įterpimo pradžia" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "įterpimo pabaiga" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "žymėjimo pradžia" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "žymėjimo pabaiga" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "pasiūlymo pabaiga" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Konteinerio pabaiga." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Ne konteineryje." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "pažymėti visi elementai" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Mygtukas pagal nutylėjimą yra %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Numatytasis mygtukas yra %s. Pilkas" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Numatytasis mygtukas nerastas" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " apatinis indeksas %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " viršutinis indeksas %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Ne dialoge" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "pasirinktas visas dokumentas" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "panaikintas pažymėjimas visame dokumente" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokumentas pasirinktas nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "dokumento žymėjimas pašalintas nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokumentas pasirinktas iki žymiklio pozicijos" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "dokumento žymėjimas pašalintas iki žymiklio pozicijos" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dinaminė stulpelio antraštė nustatyta eilutei %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dinaminė stulpelio antraštė išvalyta." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dinaminė eilutės antraštė nustatyta stulpeliui %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dinaminė eilutės antraštė išvalyta." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "tuščia" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobaitai" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabaitai" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Failų nerasta." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Į iškarpinę pridėtas turinys." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Į iškarpinę nukopijuojas turinys." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Nenaudojama paprastos peržiūros veiksena." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Įeinama į paprastos peržiūros veikseną." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Baigiama plokščia peržiūra." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Paprasta peržiūra apribota dabartiniu objektu" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Paprasta peržiūra neribota" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "su formule" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "atveria dialogą" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "atveria tinklelį" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "atveria sąrašą" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "atveria meniu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "atveria medį" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "paveikslėlio saitas" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Įvestas klavišas jau susietas su %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Klavišas įrašytas: %s. Patvirtinimui spauskite Enter." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Naujas klavišas yra: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Klavišo susiejimas ištrintas. Patvirtinimui spauskite Enter." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Klavišo susiejimas buvo pašalintas." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "įveskite naują klavišą" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "klavišui" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Aidas, nustatytas klavišui." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nėra" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Aidas nustatytas į jokį." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "klavišui ir žodžiui" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Aidas nustatytas klavišui ir žodžiui." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "sakinys" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Aidas nustatytas į sakinį." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "žodis" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Aidas nustatytas į žodį." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "žodžiui ir sakiniui" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Aidas nustatytas žodžiui ir sakiniui." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Aprėžta: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "aktuarialo simbolis" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "dėžutė" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "apskritimas" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "ilgos dalybos simbolis" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "radikalas" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "užapvalinta dėžutė" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "horizontalus perbraukimas" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "vertikalus perbraukimas" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "įstrižas perbraukimas žemyn" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "įstrižas perbraukimas aukštyn" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "rodyklė į šiaurės rytus" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "linija apačioje" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "linija kairėje" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "linija dešinėje" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "linija viršuje" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "fazės kampas" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "arabiškas faktorialo simbolis" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "ir" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "trupmenos pradžia" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "trupmena be linijos, pradžia" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "daliklis" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "trupmenos pabaiga" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "kvadratinė šaknis" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "kubinė šaknis" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "šaknis" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "šaknies pradžia" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "šaknies pabaiga" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "apatinis indeksas" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "viršutinis indeksas" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "apatinis indeksas priekyje" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "viršutinis indeksas priekyje" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "indeksas po apačia" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "indeksas virš" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "lentelės pabaiga" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "vidinės lentelės pabaiga" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "neprieinama" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Išjungtas" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Įtraukų ir lygiuočių skaitymas išjungtas." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Įjungtas" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Įtraukų ir lygiuočių skaitymas įjungtas." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Mokymosi režimas. Norėdami išeiti paspauskite grįžties klavišą." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Pradedama mokymosi veiksena. Norėdami išgirsti jos funkciją paspauskite bet " -"kurį klavišą. Ekrano skaityklės dokumentacijai peržiūrėti, spauskite F1. " -"Ekrano skaityklės trumpinių sąrašui gauti, paspauskite F2. Ekrano skaityklės " -"trumpiniams dabartinei programai gauti, spauskite F3. Išėjimui iš mokymosi " -"režimo, paspauskite grįžimo klavišą." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "išeinama iš citatos." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "išėjimo informacija." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "išeinama iš srauto." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "išeinama iš brėžinio." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "išeinama iš formos." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "išeinama iš reklamjuostės." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "išeinama iš papildomo turinio." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "išeinama iš informacijos." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "išeinama iš pagrindinio turinio." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "išeinama iš navigacijos." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "išeinama iš regiono." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "išeinama iš paieškos." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "išeinama iš sąrašo." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "išeinama iš skydelio." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "išeinama iš lentelės." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "išeinama iš patarimo." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "išeinama iš santraukos." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "išeinama iš padėkų." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "išeinama iš baigiamojo žodžio." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "išeinama iš priedo." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "išeinama iš šaltinių sąrašo." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "išeinama iš skyriaus." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "išeinama iš leidimo informacijos." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "išeinama iš išvadų." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "išeinama iš nuopelno." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "išeinama iš nuopelnų." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "išeinama iš dedikacijos." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "išeinama iš galutinių išnašų." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "išeinama iš įžangos." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "išeinama iš epilogo." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "išeinama iš klaidų taisymų." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "išeinama iš pavyzdžio." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "išeinama iš pratarmės." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "išeinama iš žodyno." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "išeinama iš rodyklės." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "išeinama iš įvado." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "išeinama iš puslapių sąrašo." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "išeinama iš dalies." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "išeinama iš autoriaus žodžio." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "išeinama iš prologo." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "išeinama iš citatos." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "išeinama iš klausimų ir atsakymų." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "išėjimo pasiūlymas." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "išeinama iš pagrindinio turinio." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "eilutė pasirinkta žemyn nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "eilutė pasirinkta aukštyn nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "eilutės žymėjimas pašalintas nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "eilutės žymėjimas pašalintas aukštyn nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Išjungiamas mokymosi režimas." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "eilutė pažymėta iki pradžios nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "eilutė pažymėta iki pabaigos nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "nuoroda" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "tas pats puslapis" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ta pati svetainė" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "kita svetainė" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s saisto su %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s nuoroda" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "aplankyta %s nuoroda" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Naudokite rodykles aukštyn ir žemyn vaikščiojimui sąraše. Spauskite išeiti " -"išėjimui." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Visi tiesioginiai regionai išjungti" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "tiesioginių regionų mandagumo lygiai atstatyti" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "mandagumo lygis %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "tiesioginis regionas nustatomas į kategorišką" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "išjungiamas tiesioginis regionas" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "tiesioginis regionas nustatomas į mandagų" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "tiesioginis regionas nustatomas į šiurkštų" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Tiesioginės srities stebėjimas išjungtas" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Tiesioginės srities stebėjimas įjungtas" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "joks tiesioginis pranešimas neišsaugotas" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Tiesioginės srities palaikymas išjungtas" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nerasta" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Nepavyko rasti dabartinės vietos." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "išjungta" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "įjungta" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "netaisyklingas žodis" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Neteisingai parašytas žodis: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Kontekstas yra %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Naršymo veiksena" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Fokuso veiksena" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Fokuso veiksenai įjungti spauskite %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Kimbanti fokuso veiksena." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Kimbanti naršymo veiksena." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Išdėstymo veiksena." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objekto veiksena." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Žymeklis perkeltas prie objekto." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Nerastas objektas po pele." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Pelės peržiūra išjungta." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Pelės peržiūra įjungta." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Klaida: nepavyko sukurti objektų sąrašo." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Nėra vaikų." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Nėra teksto." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Nėra tėvo." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Nėra ankstesnio." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Įjungta supaprastintas judėjimas." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Supaprastintas judėjimas išjungtas." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Pošakių lygis %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Pridėtas naujas elementas" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Nerasta veiksmų: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Nėra fokusavimo" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nepasirinkta nei viena programa." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Daugiau citatų blokų nėra." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Daugiau mygtukų nėra." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Daugiau žymimųjų langelių nėra." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Daugiau didelių objektų nėra." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Daugiau spaudžiamų elementų nėra." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Daugiau pasirinkimo laukų nėra." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Daugiau įvedimo laukų nėra." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Daugiau anketos laukų nėra." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Daugiau antraščių nėra." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Medžio lygyje %d daugiau antraščių nėra." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Daugiau vidinių rėmelių nėra." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Daugiau paveikslėlių nėra." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Sričių nerasta." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Daugiau nuorodų nėra." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Daugiau sąrašų nėra." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Daugiau sąrašo elementų nėra." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Daugiau tiesioginių sričių nėra." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Daugiau pastraipų nėra." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Daugiau radijo mygtukų nėra." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Daugiau skirtukų nėra." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Daugiau lentelių nėra." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Daugiau neaplankytų nuorodų nėra." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Daugiau aplankytų nuorodų nėra." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Nėra pažymėto teksto." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nėra nuoroda." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Pranešimas" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Apačia" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Viršus" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Nėra pranešimų" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "skaitmenys" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Pasakyti skaičius kaip skaitmenis." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "žodžiai" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Pasakyti skaičius kaip žodžius." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "išjungta" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "įjungta" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Įkeliama. Prašome palaukti." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Įkėlimas baigtas." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s įkėlimas baigtas." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Puslapyje yra %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "puslapis pasirinktas nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "puslapis pasirinktas iki žymiklio pozicijos" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "puslapio žymėjimas pašalintas nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "puslapio žymėjimas pašalintas iki žymiklio pozicijos" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "pastraipa pažymėta žemyn nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "pastraipa pažymėta aukštyn nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "pastraipos žymėjimas pašalintas žemyn nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "pastraipos žymėjimas pašalintas aukštyn nuo žymiklio pozicijos" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Jūs jau turite atvertą Cthulhu nuostatų dialogą.\n" -"Užverkite jį prieš atverdami naują." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "paslinkti %(position)d per %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profilis nustatytas į %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nerasta profilių." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Pažangos juosta %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Visi" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Skyrybos lygis nustatytas į visus." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Dauguma" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Skyrybos lygis nustatytas į dažną." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nėra" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Skyrybos lygis nustatytas į jokį." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Kai kurie" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Skyrybos lygis nustatytas į dalinį." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Ieškoma." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Paieška baigta." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Ekrano skaityklės naudotojo nustatymai įkelti iš naujo." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Pažymėtas tekstas yra: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Žymėjimas ištrintas." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Žymėjimas grąžintas." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Tekstas atžymėtas." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Dydis: %d, %d. Vieta: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Plotis: %d. Aukštis: %d. %d iš kairės. %d nuo viršaus." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Kalbėjimas išjungtas." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Kalbėjimas įjungtas." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "greičiau." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "lėčiau." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "aukščiau." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "žemiau." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "garsiau." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "tyliau." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Greitis %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Aukštis %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Garsumas %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher modulis %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher balsas %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nėra prieinamų serverių." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nėra prieinamų balsų." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Kalbėjimas įjungtas." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Kalbėjimas nebus naudojamas." - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Išsamumo lygis: trumpas" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Išsamumo lygis: išsamus" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " taškas taškas taškas" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu sveikina jus." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu tyko po bangomis." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Miego režimas įjungtas %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Miego režimas išjungtas %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Kalbėjimas neprieinamas." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Nerasta" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Būsenos juosta nerasta" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "seka nerasta" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Struktūrinės navigacijos klavišai išjungti." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Struktūrinės navigacijos klavišai įjungti." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nerasta" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Eilutė %(row)d, stulpelis %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Lentelė pabaiga" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Garsiai perskaityti langelį" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Garsiai perskaityti eilutę" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Nevienalytis" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Ne lentelėje." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Stulpeliai perrikiuoti" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Eilutės perrikiuotos" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "stulpelis %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "stulpelis %(index)d iš %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Stulpelio apačia." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Stulpelio viršus." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Pažymėtas stulpelis %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Pažymėti stulpeliai nuo %s iki %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Panaikintas pažymėjimas stulpeliams nuo %s iki %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Panaikintas stulpelio %s pažymėjimas" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "eilutė %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "eilutė %(index)d iš %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Eilutės pradžia." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Eilutės pabaiga." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Eilutė ištrinta." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Paskutinė eilutė ištrinta." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Eilutė įterpta." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Eilutė įterpta į lentelės pabaigą." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Eilutė %s pažymėta" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Eilutės nuo %s iki %s pažymėtos" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Panaikintas pažymėjimas eilutėms nuo %s iki %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Panaikintas pažymėjimas eilutei %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "pažymėtas" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "pažymėjimas nuimtas" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H valandų, %M minučių ir %S sekundžių" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H valandų ir %M minučių" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unikodas %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "atšaukti" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "pakartoti" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versija %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "tarpai" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Einama iki apačios." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Einama iki viršaus." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 įrašų" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Langelis iš %d eilutės" -msgstr[1] "Langelis iš %d eilučių" -msgstr[2] "Langelis iš %d eilučių" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d stulpelis" -msgstr[1] " %d stulpeliai" -msgstr[2] " %d stulpelių" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Langelis iš %d stulpelio" -msgstr[1] "Langelis iš %d stulpelių" -msgstr[2] "Langelis iš %d stulpelių" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d simboliu per ilga" -msgstr[1] "%d simboliais per ilga" -msgstr[2] "%d simbolių per ilga" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialogas)" -msgstr[1] "(%d dialogai)" -msgstr[2] "(%d dialogų)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d neaktyvus dialogas" -msgstr[1] "%d neaktyvūs dialogai" -msgstr[2] "%d neaktyvių dialogų" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d baitas" -msgstr[1] "%d baitai" -msgstr[2] "%d baitų" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Rastas %d failas" -msgstr[1] "Rasti %d failai" -msgstr[2] "Rasta %d failų" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d forma" -msgstr[1] "%d formos" -msgstr[2] "%d formų" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d antraštė" -msgstr[1] "%d antraštės" -msgstr[2] "%d antraščių" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d elementas" -msgstr[1] "%d elementai" -msgstr[2] "%d elementų" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d žymelė" -msgstr[1] "%d žymelės" -msgstr[2] "%d žymelių" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "Rastas %d elementas" -msgstr[1] "Rasti %d elementai" -msgstr[2] "Rasta %d elementų" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Išeinama iš %d citatos bloko." -msgstr[1] "Išeinama iš %d citatų blokų." -msgstr[2] "Išeinama iš %d citatų blokų." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Išeinama iš %d sąrašo." -msgstr[1] "Išeinama iš %d sąrašų." -msgstr[2] "Išeinama iš %d sąrašų." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Nežinomo dydžio sąrašas" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Sąrašas su %d elementu" -msgstr[1] "Sąrašas su %d elementais" -msgstr[2] "Sąrašas su %d elementų" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Nežinomo dydžio sklaidos kanalas" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Sklaidos kanalas su %d straipsniu" -msgstr[1] "Sklaidos kanalas su %d straipsniais" -msgstr[2] "Sklaidos kanalas su %d straipsnių" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Aprašymų sąrašas su %d terminu" -msgstr[1] "Aprašymų sąrašas su %d terminais" -msgstr[2] "Aprašymų sąrašas su %d terminų" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d vertė" -msgstr[1] "%d vertės" -msgstr[2] "%d verčių" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "matematinė lentelė iš %d eilutės" -msgstr[1] "matematinė lentelė iš %d eilučių" -msgstr[2] "matematinė lentelė iš %d eilučių" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d stulpelis" -msgstr[1] "%d stulpeliai" -msgstr[2] "%d stulpelių" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "vidinė matematinė lentelė iš %d eilutės" -msgstr[1] "vidinė matematinė lentelė iš %d eilučių" -msgstr[2] "vidinė matematinė lentelė iš %d eilučių" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d pranešimas.\n" -msgstr[1] "%d pranešimai.\n" -msgstr[2] "%d pranešimų.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d procentas." -msgstr[1] "%d procentai." -msgstr[2] "%d procentų." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "perskaitytas %d procentas dokumento" -msgstr[1] "perskaityti %d procentai dokumento" -msgstr[2] "perskaityta %d procentų dokumento" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pikselis" -msgstr[1] "%d pikseliai" -msgstr[2] "%d pikselių" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s simbolį" -msgstr[1] "%(count)d %(repeatChar)s simbolius" -msgstr[2] "%(count)d %(repeatChar)s simbolių" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "Pasirinktas %(index)d elementas iš %(total)d" -msgstr[1] "Pasirinkti %(index)d elementas iš %(total)d" -msgstr[2] "Pasirinkta %(index)d elementas iš %(total)d" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Rastas %d ekrano skaityklės numatytasis trumpinys." -msgstr[1] "Rasti %d ekrano skaityklės numatytieji trumpiniai." -msgstr[2] "Rasta %d ekrano skaityklės numatytųjų trumpinių." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Rastas %(count)d ekrano skaityklės trumpinys %(application)s." -msgstr[1] "Rasti %(count)d ekrano skaityklės trumpiniai %(application)s." -msgstr[2] "Rasta %(count)d ekrano skaityklės trumpinių %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d tarpas" -msgstr[1] "%d tarpai" -msgstr[2] "%d tarpų" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabuliatorius" -msgstr[1] "%d tabuliatoriai" -msgstr[2] "%d tabuliatorių" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d lentelė" -msgstr[1] "%d lentelės" -msgstr[2] "%d lentelių" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "nežinomo dydžio lentelė" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "lentelė su %d stulpeliu, eilučių skaičius nežinomas" -msgstr[1] "lentelė su %d stulpeliais, eilučių skaičius nežinomas" -msgstr[2] "lentelė su %d stulpelių, eilučių skaičius nežinomas" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "lentelė su %d eilute, stulpelių skaičius nežinomas" -msgstr[1] "lentelė su %d eilutėmis, stulpelių skaičius nežinomas" -msgstr[2] "lentelė su %d eilučių, stulpelių skaičius nežinomas" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "lentelė iš %d eilutės" -msgstr[1] "lentelė iš %d eilučių" -msgstr[2] "lentelė iš %d eilučių" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "prieš %d sekundę" -msgstr[1] "prieš %d sekundes" -msgstr[2] "prieš %d sekundžių" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "prieš %d minutę" -msgstr[1] "prieš %d minutes" -msgstr[2] "prieš %d minučių" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "prieš %d valandą" -msgstr[1] "prieš %d valandas" -msgstr[2] "prieš %d valandų" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "prieš %d dieną" -msgstr[1] "prieš %d dienas" -msgstr[2] "prieš %d dienų" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d neaplankyta nuoroda" -msgstr[1] "%d neaplankytos nuorodos" -msgstr[2] "%d neaplankytų nuorodų" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d aplankyta nuoroda" -msgstr[1] "%d aplankytos nuorodos" -msgstr[2] "%d aplankytų nuorodų" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "perjungti" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(index)d iš %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d iš %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "elementas %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "MEDŽIO LYGIS %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "medžio lygis %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "MEDŽIO LYGIS %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "%s informacija" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "informacija elemente %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "pasiūlymas" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "redaguojamas iššokantis sąrašas" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "redaguojamas turinys" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "srautas" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "brėžinys" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "santrauka" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "padėkos" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "baigiamasis žodis" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "priedas" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "bibliografijos įrašas" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografija" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "skyrius" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "leidimo informacija" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "išvada" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "viršelis" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "nuopelnas" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "nuopelnai" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedikacija" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "pabaigos išnaša" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "pabaigos išnašos" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "įžanga" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilogas" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "klaidų taisymai" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "pavyzdys" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "pratarmė" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "žodynas" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "rodyklė" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "įvadas" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "puslapio pabaiga" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "puslapių sąrašas" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "dalis" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "autoriaus žodis" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prologas" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "citata" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "klausimai ir atsakymai" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "subtitrai" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "turinys" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "a%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s lygis %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "horizontali slinkties juosta" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "vertikali slinkties juosta" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "horizontalus slankiklis" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "vertikalus slankiklis" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "horizontalus padalijimas" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "vertikalus padalijimas" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "perjungimas" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Piktogramų skydelis" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "reklamjuostė" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "papildomas turinys" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informacija" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "pagrindinis turinys" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "judėjimas" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "regionas" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "paieška" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "aplankyta nuoroda" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "meniu mygtukas" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "rikiuota didėjimo tvarka" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "rikiuota mažėjimo tvarka" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "rikiuota" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "spaudžiamas" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "sutraukta" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "išplėsta" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "turi ilgą aprašymą" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontaliai" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikaliai" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "pažymėta" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nepažymėta" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "įjungta" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "išjungta" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "dalinai pažymėta" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "paspausta" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "nepaspausta" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "nepasirinkta" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "pažymėta" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "nepasirinkta" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "nepažymėta" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "aplankyta" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "neaplankyta" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "papilkintas" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "tik skaitymui" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "nerašo" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "būtinas" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "multi-pažymėjimas" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "netinkama įvestis" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "netinkama" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "netaisyklinga rašyba" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "rašyba" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "netaisyklinga gramatika" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatika" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Rasti" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Ekrano skaityklė paieškos dialogas" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Užverti" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Rasti" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Ieškoti:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Ieškoti:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Lango _viršus" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Lango viršus" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Pradėti nuo:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Priėjus pabaigą pradėti nuo pradžių" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Ieškoti _atgal" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Paieškos kryptis:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Skirti didžiąsias ir mažąsias raides" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Tik _ištisi žodžiai" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Parametrai:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Numatytasis" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Didžiosiomis" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Nuoroda" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Programa" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Langas" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu ekrano skaityklė" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Žinynas" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "Prit_aikyti" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Nešiojamasis kompiuteris" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Klaviatūros išdėstymas" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktyvus _profilis:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Pradžios profilis:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Įkelti" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Įrašyti t_aip" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Pašalinti" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiliai" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Rodyti paaiškinimus" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Sakyti objektą po pele" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Pelė" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Laiko formatas:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "_Datos formatas:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Data ir laikas" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Pasakyti atnaujinimus" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Brailio atnaujinimai" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Dažnis (sekundėmis):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Taikoma:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Pyptelėti atnaujinimus" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Eigos juosto atnaujinimai" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Įjungti _grįžimą ir greitą prasukimą visko sakyme" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Įjungti navigaciją pagal _struktūrą visko sakyme" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Garsiai skaityti viską _po:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Pranešti apie citatų _blokus pasakant viską" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Pranešti apie _sąrašus pasakant viską" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Pranešti apie lenteles pasakant viską" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Pranešti apie sk_ydelius pasakant viską" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Pranešti apie _formas pasakant viską" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Pranešti apie _žymeles pasakant viską" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Pasakyti viską" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Elemento _pateikimas:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Bendra" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Ga_rsumas:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Aukš_tumas:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Dažnis:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Asmuo:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Kalba:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Kalbėjimo sinte_zatorius:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Kalbėjimo _sistema:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Balso tipas:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Didžiųjų raidžių stilius:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Balso tipo nustatymai" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Perskaityti skirtingo dydžio eilutes kaip _žodžius" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Pasakyti _skaičius kaip skaitmenis" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Bendrieji balso nustatymai" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Balsas" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Į_jungti kalbėjimą" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Iš_samus" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Išsamumas" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Visos" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Skyrybos lygis" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Sakyti tik rodomą tekstą" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Skaityti tuščias eilutes" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Garsiai skaityt_i įtraukas ir lygiuotes" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Sakyti objektų mnemonikas" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Sakyti vaiko _padėtį" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Perskaityti mokymosi pranešimus" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Sistemos pranešimai yra detalizuojami" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "_Pasakyti spalvas kaip pavadinimus" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Navigacijos metu pranešti apie citatų _blokus" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Navigacijos metu pranešti apie _sąrašus" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Navigacijos metu pranešti apie _lenteles" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Garsiai perskaityti _neteisingai parašyto žodžio indikatorių" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Navigacijos metu pranešti apie sk_ydelius" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Navigacijos metu pranešti apie _žymeles" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Navigacijos metu pranešti apie _formas" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Pasakyti _aprašymą" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Pasakyti visą eilutę s_kaičiuoklėse" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Pasakyti visą eilutę _dokumentų lentelėse" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Pasakyti visą eilutę sąsajos lentelėse" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Tariamas kontekstas" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Kalbėjimas" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Įjungti brailio _palaikymą" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Sutrumpinti vaidmenų pavadinimai" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Išjungti _eilutės pabaigos simbolį" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Sutraukimo _lentelė:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Įjungti sutrauktą brailį" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Įjungti ž_odžių laužymą" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Rodyti nustatymus" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Nėra" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Pažymėjimo indikatorius" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hipersaito indikatorius" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Įjungti _pranešimus" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Trukmė (sekundėmis):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Pranešimai yra _nuolatiniai" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Pranešimai yra _detalizuoti" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Pranešimų nuostatos" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Brailis" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Įjungti _klavišų aidą" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Įjungti _abėcėlės klavišus" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Įjungti _skaitmenų klavišus" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Įjungti s_kyrybos klavišus" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Įjungti _tarpą" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Įjungti _modifikuojančius klavišus" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Įjungti _funkcijų klavišus" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Įjungti _veiksmų klavišus" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Įjungti _judėjimo klavišus" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Įjungti ž_odžių atkartojimą" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Įjungti s_akinių atkartojimą" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Aidas" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Ekrano skaityklės _modifikuojantys klavišai:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Klavišų priskyrimai" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Tarimo žodynas" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "-Naujas įrašas" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Ištrinti" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Tarimas" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Garsiai skaityti viską" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Garsiai neskaityti nieko" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Atstatyti" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Teksto atributai" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Perkelti į _apačią" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Perkelti vienu žemiau" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Perkelti vienu aukščiau" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Perkelti į _viršų" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Pakoreguoti pasirinktą atributą" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Brailio indikatorius" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Teksto požymiai" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Įjungti AI asistentą" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Teikėjas:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Vietinis - Nemokamas)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API _rakto failas:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Kelias į API rakto failą" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Gauti _Claude API raktą" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Atidaryti naršyklę Claude API raktui gauti ir automatiškai išsaugoti" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Reikalauti patvirtinimo prieš AI veiksmus" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _modelis:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Modelio pavadinimas Ollama (pvz., llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _galinis taškas:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API galinio taško URL (pvz., http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Ekrano nuotraukos _kokybė:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "žemiau" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Vidutinė" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Aukšta" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI asistentas" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Kalba:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "jena" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Mastelio koeficientas:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Pilkų tonų vaizdas" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Invertuoti vaizdą" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Juodai balta nuotrauka" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Juodai/baltai _riba:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analizuoti spalvas" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Į iškarpinę nukopijuojas turinys." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "fono spalva" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "fono visas aukštis" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "fono taškavimas" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "kryptis" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "redaguojamas" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "šeimos pavadinimas" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "priekinio plano spalva" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "priekinio plano taškavimas" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "šrifto efektas" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "įtrauka" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "klaida" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "nematomas" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "lygiuotė" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "kalba" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "kairė paraštė" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "eilutės aukštis" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "pastraipos stilius" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pikseliai virš eilučių" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pikseliai žemiau eilučių" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pikseliai laužyme" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "dešinė paraštė" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "pakeltas" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "skalė" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "dydis" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "ištempimas" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "perbraukimas" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stilius" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "teksto spalvinimas" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "teksto pasukimas" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "teksto šešėlis" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "pabraukimas" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variantas" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "vertikali lygiuotė" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "svoris" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "laužymo veiksena" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "rašymo veiksena" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "teigiama" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "neigiama" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "nėra" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "graviruotas" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "uždėtas" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "apibrėžtas" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "po linija" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "per liniją" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "blyksi" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "juodas" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "viengubas" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dvigubas" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "žemiau" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "simbolis" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "žodis" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "žodžio simbolis" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "deš" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "kair" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "kairinė" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "dešininė" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centrinė" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "jokios lygiuotės" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "užpildymas" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ypač suspaustas" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "ypač suspaustas" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "suspaustas" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "pusiau suspaustas" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "įprastinis" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "pusiau išplėstas" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "išplėstas" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "labai išplėstas" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ypač išplėstas" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "mažosios raidės" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "įstrižas" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "pasviręs" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Numatytasis" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Teksto pagrindas" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Antraštė" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "pagrindinė eilutė" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "apatinis indeksas" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "viršutinis indeksas" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "viršuje" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "teksto viršus" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "viduryje" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "apačioje" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "teksto apačia" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "paveldi" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "kd-va" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "dk-va" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "va-dk" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "va-kd" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "av-dk" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "kd" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "dk" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "va" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "paryškintas" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "rašyba" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Spauskite tarpą perjungimui." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "Spauskite tarpą išplėtimui ir naudokite žemyn elemento pažymėjimui." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Spauskite alt+f6 vaikiniams langams aktyvuoti." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Perėjimui prie elementų naudokite arba rodyklių klavišus, arba paiešką " -"rašant." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Sisteminiam meniu gauti spauskite alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Elementui pažymėti naudokite žemyn ir aukštyn." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Sutraukimui spauskite shift ir į kairę." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Sutraukimui spauskite shift ir į dešinę." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Aktyvavimui spauskite grįžimo klavišą." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Įveskite tekstą." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Naudokite klavišus į kairę ir dešinę kitoms kortelėms parodyti." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Aktyvavimui spauskite tarpą." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Reikšmei pažymėti naudokite rodykles aukštyn ir žemyn. Arba įveskite " -"pageidaujamą skaitinę reikšmę." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Naudokite rodyklių klavišus pakeitimui." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Vaikščiojimui, spauskite rodykles į kairę ir dešinę. Judėjimui per " -"elementus, spauskite rodykles aukštyn ir žemyn." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Įėjimui į po-meniu , spauskite rodyklę į dešinę." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Sumažinimui, spauskite rodyklę į kairę, padidinimui, spauskite rodyklę į " -"dešinę. Mažiausiam spauskite pradžios, didžiausiam - pabaigos klavišą." diff --git a/po/lv.po b/po/lv.po deleted file mode 100644 index 526b5c3..0000000 --- a/po/lv.po +++ /dev/null @@ -1,9260 +0,0 @@ -# translation of lv.po to Latvian -# translation of cthulhu.HEAD.lv.po to -# Copyright (C) 2007 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# -# -# Raivis Dejus , 2006, 2007. -# Edgars Kodorāns , 2007. -# Rūdofls Mazurs , 2011, 2012, 2013, 2014, 2016, 2017, 2018, 2019, 2021, 2022. -msgid "" -msgstr "" -"Project-Id-Version: lv\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2022-09-11 22:27+0300\n" -"Last-Translator: Rūdolfs Mazurs \n" -"Language-Team: Latvian \n" -"Language: lv\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : " -"2);\n" -"X-Generator: Lokalize 21.12.3\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu ekrāna lasītājs" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "ekrāna lasītājs;runa;Brails;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "trauksme" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "bulta" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "aud" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "rpan" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "atks" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "krizv" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "kgalv" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "kbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ikona" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "rām" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "zvan" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "digs" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "zīmēt" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fizv" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "aizp" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fts" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "forma" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "stpan" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "galv" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "att" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "rām" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "eti" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "slpan" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "Saite" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "sar" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "sarelem" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "izv" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "izvjla" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "izvlieta" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "iespan" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tabsar" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pan" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "par" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "izlizv" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "attjla" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "pga" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "radizvlieta" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "span" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rgalv" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "rjla" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "rpan" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "rpan" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "atdal" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "slnis" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "sadpan" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "rotēt" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "stjos" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tla" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "šūna" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "pizvlieta" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "ppoga" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "rjla" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "paraugs" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "koks" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "ktbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "nms" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "sklda" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "lgs" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "gvn" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "kjn" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "redja" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "ieg" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Čehu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spāņu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanādas franču 2. pakāpes" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francijas franču 2. pakāpes" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvijas 1. pakāpes" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Nīderlandes holandiešu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvēģu 0. pakāpes" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvēģu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvēģu 2. pakāpes" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvēģu 3. pakāpes" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Poļu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugāļu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Zviedru 1. pakāpes" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arābu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Velsiešu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Velsiešu 2. pakāpes" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Vācu 0. pakāpes" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Vācu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Vācu 2. pakāpes" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Britu angļu 2. pakāpes" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Britu angļu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "ASV angļu 2. pakāpes" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "ASV angļu 2. pakāpes" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanādas franču 1. pakāpes" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francijas franču 1. pakāpes" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grieķu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ungāru 8 punktu dators" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Ungāru 1. pakāpes" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Ungāru 2. pakāpes" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Itāliešu 1. pakāpes" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Beļģijas holandiešu 1. pakāpes" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "atstarpe" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "jauna rinda" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulācija" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "izsaukums" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "pēdiņas" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "izlaide" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolārs" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procenti" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "un" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrofs" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "kreisā iekava" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "labā iekava" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "zvaigznīte" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "pluss" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "komats" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "domu zīme" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punkts" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slīpsvītra" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "kols" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semikols" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "mazāk" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "vienāds" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "vairāk" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "jautājums" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "@" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "kreisā kvadrātiekava" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "atpakaļslīpsvītra" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "labā kvadrātiekava" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "simbols" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "pasvītrots" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "gravis" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "kreisā figūriekava" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertikāla josla" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "labā figūriekava" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "bezatdalīšanas atstarpe" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "apgriezta izsaukuma zīme" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centi" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "mārciņa" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "valūtas zīme" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jēna" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "pārlauzta svītra" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "paragrāfs" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "umlauts" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "autortiesības" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "augšraksts" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "stūrainās atvērējpēdiņas" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "loģiskais nē" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "nosacījuma pārnesumzīme" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "Reģistrēts" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "garumzīme" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "grādi" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus vai mīnus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "augšraksts 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "augšraksts 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "akūts" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mī" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "paragrāfa simbols" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "punkts pa vidu" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "sediļa" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "augšraksts 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "kārtas simbols" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "stūrainās aizvērējpēdiņas" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "viena ceturdaļa" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "viena puse" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "trīs ceturdaļas" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "apgriezta jautājuma zīme" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a akūts" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVIS" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AKŪTS" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A JUMTIŅŠ" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUTS" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A APLIS" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C SEDIĻA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVIS" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AKŪTS" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E JUMTIŅŠ" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUTS" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVIS" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AKŪTS" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I JUMTIŅŠ" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUTS" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVIS" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AKŪTS" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O JUMTIŅŠ" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUTS" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "reizes" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O SVĪTRA" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVIS" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AKŪTS" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U JUMTIŅŠ" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUTS" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AKŪTS" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "ss ligatūŗa" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a gravis" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a jumtiņš" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlauts" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a aplis" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c sediļa" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e gravis" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e akūts" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e jumtiņš" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlauts" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i gravis" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i akūts" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i jumtiņš" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlauts" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o gravis" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o akūts" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o jumtiņš" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlauts" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "sadalīts pēc" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o svītra" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u akūts" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u gravis" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u jumtiņš" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlauts" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y akūts" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlauts" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUTS" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "domu zīme" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "kreisais shift" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "labais shift" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "atverošās vienpēdiņas" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "kreisās dubultpēdiņas" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "labās dubultpēdiņas" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "atverošās pēdiņas" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "Duncis" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dubult duncis" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "aizzīme" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trīsstūrveida aizzīme" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mile" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prim" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "dubults prim" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "trīskāršs prim" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "savienojuma aizzīme" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "eiro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "prečzīme" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "atzīmēt rūtiņu" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "pārbaudīt atzīmēto rūtiņu" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-veida aizzīme" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "augšraksts 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "augšraksts 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "augšraksts 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "augšraksts 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "augšraksts 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "augšraksts 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "augšraksts 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "augšraksts plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "augšraksts mīnuss" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "augšraksts vienāds ar" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "augšraksts atverošā iekava" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "augšraksts aizverošā iekava" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "augšraksts n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "apakšraksts 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "apakšraksts 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "apakšraksts 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "apakšraksts 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "apakšraksts 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "apakšraksts 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "apakšraksts 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "apakšraksts 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "apakšraksts 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "apakšraksts 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "apakšraksts plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "apakšraksts mīnuss" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "apakšraksts vienāds ar" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "apakšraksts atverošā iekava" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "apakšraksts aizverošā iekava" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "melns kvadrāts" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "melns rombs" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "objekta aizvietošanas rakstzīme" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Novietot rādītāju uz pašreizējā priekšmeta" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Izpildīt kreiso klikšķi uz pašreizējā vienotā pārskata objekta" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Izpildīt labo klikšķi uz pašreizējā vienotā pārskata objekta" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Izrunāt visu dokumentu" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Izrunāt visu logu, izmantojot plakanu pārskatu" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Izpildīt vienkāršo “kur es atrodos” darbību" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Izpildīt detalizēto “kur es atrodos” darbību" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Izrunāt esošo atlasi" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Izrunāt informāciju par saiti" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Parādīt noklusējuma pogu" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Izrunāt stāvokļa joslu" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Izrunāt virsraksta joslu" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Atvērt meklētāja logu" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Iet uz nākamo sarakstu" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Meklēt nākamo daļu no virknes" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Meklēt iepriekšējo daļu no virknes" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Ienākt un iziet no vienotā pārskata" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Virzīt vienoto pārskatu uz beigu novietojumu" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Virzīt vienoto pārskatu uz māju novietojumu" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Virzīt vienoto pārskatu uz beigu novietojumu" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Virzīt vienoto pārskatu uz iepriekšējās rindas sākumu" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Izrunāt esošo vienotā pārskatā rindu" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Nosaukt pa burtiem esošo vienotā pārskatā rindu" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Fonētiski nosaukt pa burtiem esošo vienotā pārskatā rindu" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Virzīt vienoto pārskatu uz nākamās rindas sākumu" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Virzīt vienoto pārskatu uz iepriekšējo lietu vai vārdu" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Izrunāt esošā pārskata lietu vai vārdu" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Nosaukt pa burtiem esošā pārskata lietu vai vārdu" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Fonētiski izrunāt pa burtiem vai pārbaudīt esošā pārskata lietu vai vārdu" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Virzīt vienoto pārskatu uz nākamo lietu vai vārdu" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Virzīt vienoto pārskatu uz vārdu, kas ir virs esošā vārda" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Izrunāt esošā pārskata objektu" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Virzīt vienoto pārskatu uz vārdu, kas ir zem esošā vārda" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Virzīt vienoto pārskatu uz iepriekšējo simbolu" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Izrunāt esošo vienoto pārskata simbolu" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Fonētiski izrunāt esošo vienoto pārskata simbolu" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Izrunāt unikoda vērtību esošā vienotā pārskata simbolam" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Virzīt vienotu pārskatu uz nākamo simbolu" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Virzīt vienoto pārskatu uz rindas beigām" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Virzīt vienotu pārskatu uz apakšu pa kreisi" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Kopēt saturu zem vienotā pārskata starpliktuvē" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Pievienot saturu zem vienotā pārskata starpliktuvē" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Virzīt vienoto pārskatu uz beigu novietojumu" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Pārslēgt uz tikai esošās tabulas šūnu vai visu rindu lasīšanu" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Lasīt atribūtus saistītos ar esošo teksta simbolu" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Pagriezt braila displeju pa kreisi" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Pagriezt braila displeju pa labi" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Atgriezt pie objekta ar tastatūras fokusu" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Ieslēgt un izslēdz kontrakcijas Brailu" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Apstrādāt kursora novietošanas taustiņu" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marķēt teksta atlases sākumu" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marķēt teksta atlases beigas" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Ienākt mācīšanās režīmā. Nospiediet atsoli, lai izietu no mācīšanās režīma" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Samazināt izrunas ātrumu" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Palielināt izrunas ātrumu" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Samazināt izrunas placi" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Palielināt izrunas placi" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Palielināt izrunas skaļumu" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Samazināt izrunas skaļumu" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Meklēt iepriekšējo daļu no virknes" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Izvēlieties vēlamo izrunas serveri." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Samazināt izrunas ātrumu" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Palielināt izrunas ātrumu" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Balss tipa iestatījumi" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Pārslēgt izrunas klusēšanu" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Pārslēgt runas detalizētības līmeni" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Pārslēgt izkārtojuma režīmu" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Iziet no ekrāna lasītāja" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Rādīt izvēles konfigurācijas logu" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Rādīt aplikāciju izvēles konfigurācijas dialogu" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Pārslēgt atkāpes un izlīdzināšanas izrunāšanu" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Mainīt skaitļu izrunāšanas stilu" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Iet cauri uz nākamo interpunkcijas izrunāšanas līmeni" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Iet cauri uz nākamo taustiņa atbalss līmeni" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Iet cauri uz nākamo iestatījumu profilu" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Iet cauri uz nākamo burtu reģistru stilu" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Iet cauri uz nākamo taustiņa atbalss līmeni" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Iet cauri atkļūdošanas līmeņiem izpildes laikā" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Ielikt grāmatzīmē “kur es esmu” attiecībā pret pašreizējo novietojumu" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Iet uz iepriekšējo grāmatzīmes vietu" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Iet uz grāmatzīmi" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Iet uz nākamo grāmatzīmes vietu" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Pievienot grāmatzīmi" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Saglabāt grāmatzīmes" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Pārslēgt peles pārskata režīmu" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Rāda pašreizējo laiku" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Rāda pašreizējo datumu" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Pašreizējā objekta izmērs un atrašanās vieta šajā brīdī" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Padot nākamo komandu uz pašreizējo lietotni" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Izrunāt un pārveidot brailā čata istabas ziņojumu" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Pārslēgt, vai paziņot, kad biedri raksta" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Pārslēgt vai mēs pieliekam tērzēšanas istabas ziņojumiem tērzēšanas istabas " -"nosaukumu" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Pārslēgt vai mēs pieliekam čata istabas ziņojumiem čata istabas nosaukumu" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Pa kreisi" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Pa labi" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Uz augšu" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Uz leju" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Iesalt" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Augšā pa kreisi" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Apakšā pa kreisi" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Kursora virzienā" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Seši punkti" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Kursora maršrutēšana" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Kopēšanas sākums" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Kopēšanas beigas" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Parādīt pēdējo paziņojumu" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Parādīt paziņojumu sarakstu" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Parādīt iepriekšējo paziņojumu" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Parādīt pēdējo paziņojumu" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Iet uz nākamo simbolu" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Iet uz iepriekšējo simbolu" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Iet uz nākamo lietu vai vārdu" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Iet uz iepriekšējo lietu vai vārdu" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Iet uz nākamo rindu" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Iet uz iepriekšējo rindu" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Iet uz datnes augšpusi" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Iet uz datnes apakšu" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Iet uz rindas sākumu" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Iet uz rindas beigām" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Iet uz nākamo objektu" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Iet uz iepriekšējo objektu" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Liek pašreizējam kombinētajam lodziņam izvērsties" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Pārslēgt starp vietējo un ekrāna lasītāja kursora navigāciju" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Turpināt dzīvo apgabalu pieklājības iestatīšanu" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Iestatīt noklusēto dzīvā apgabala pieklājību uz izslēgts" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Pārskatīt dzīvo apgabalu paziņojumus" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitora dzīvie apgabali" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Pārvietot fokusu uz un no objekta, virs kura ir pele" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Iestatīt lietojamo rindu kā dinamisku kolonnas galveni" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Attīrīt dinamiskās kolonnas galveni" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Iestatīt lietojamo kolonnu kā dinamisku rindas galveni" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Attīrīt dinamiskās rindas galveni" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Rādīt ievades rindas saturu" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Pārslēgt strukturālās pārvietošanās taustiņus" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Iet uz iepriekšējo bloka citātu" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Iet uz nākamo bloka citātu" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Rādīt bloka citātu sarakstu" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Iet uz iepriekšējo pogu" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Iet uz nākamo pogu" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Rādīt pogu sarakstu" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Iet uz iepriekšējo atzīmes rūtiņu" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Iet uz nākamo atzīmes rūtiņu" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Rādīt atzīmes rūtiņu sarakstu" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Iet uz iepriekšējo klikšķināmo" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Iet uz nākamo klikšķināmo" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Rādīt sarakstu ar klikšķināmajiem" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Iet uz iepriekšējo kombinēto lodziņu" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Iet uz nākamo kombinēto lodziņu" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Iet uz konteinera sākumu" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Iet uz konteinera beigām" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Rādīt kombinēto lodziņu sarakstu" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Iet uz iepriekšējo ierakstu" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Iet uz nākamo ierakstu" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Rādīt ierakstu sarakstu" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Iet uz iepriekšējo formas lauku" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Iet uz nākamo formas lauku" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Rādīt formu lauku sarakstu" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Iet uz iepriekšējo virsrakstu" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Iet uz nākamo virsrakstu" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Rādīt galveņu sarakstu" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Iet uz iepriekšējo %d. līmeņa virsrakstu" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Iet uz nākamo %d. līmeņa virsrakstu" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Rādīt galveņu sarakstu %d līmenī" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Iet uz iepriekšējo tabulu" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Iet uz nākamo tabulu" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Rādīt tabulu sarakstu" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Iet uz iepriekšējo attēlu" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Iet uz nākamo attēlu" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Rādīt attēlu sarakstu" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Iet uz iepriekšējo orientieri" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Iet uz nākamo orientieri" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Rādīt orientieru sarakstu" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Iet uz iepriekšējā pārskata objektu" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Iet uz esošā pārskata objektu" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Rādīt lielu objektu sarakstu" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Iet uz iepriekšējo saiti" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Iet uz nākamo saiti" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Rādīt saišu sarakstu" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Iet uz iepriekšējo sarakstu" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Iet uz nākamo sarakstu" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Rādīt sarakstu sarakstu" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Iet uz iepriekšējo saraksta vienību" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Iet uz nākamo saraksta vienību" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Rādīt sarakta vienumu sarakstu" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Iet uz iepriekšējo dzīvo apgabalu" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Iet uz nākamo dzīvo apgabalu" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Iet uz pēdējo dzīvo apgabalu, kurā ir veikts paziņojums" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Pāriet uz objekta ar navigatora fokusu vecāku." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Pāriet uz objekta ar navigatora fokusu pirmo bērnu." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Pāriet uz objekta ar navigatora fokusu nākamo brāli/māsu." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Pāriet uz objekta ar navigatora fokusu iepriekšējo brāli/māsu." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Atgriezt pie objekta ar tastatūras fokusu" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Pārslēgt strukturālās pārvietošanās taustiņus" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Iet uz iepriekšējo rindkopu" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Iet uz nākamo rindkopu" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Rādīt rindkopu sarakstu" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Iet uz iepriekšējo radio pogu" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Iet uz nākamo radio pogu" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Rādīt radio pogu sarakstu" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Iet uz iepriekšējo atdalītāju" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Iet uz nākamo atdalītāju" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Iet uz iepriekšējo tabulu" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Iet uz nākamo tabulu" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Rādīt tabulu sarakstu" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Iet uz apakšējo šūnu" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Iet uz pirmo šūnu tabulā" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Iet uz pēdējo šūnu tabulā" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Iet uz kreiso šūnu" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Iet uz labo šūnu" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Iet uz augšējo šūnu" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Pārslēgt izkārtojuma režīmu" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Pārslēgties starp pārlūkošanas režīmu un fokusa režīmu" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Ieslēgt lipīgā fokusa režīmu" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Ieslēgt lipīgo pārlūkošanas režīmu" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Iet uz iepriekšējo neapmeklēto saiti" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Iet uz nākamo neapmeklēto saiti" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Rādīt neapmeklēto saišu sarakstu" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Iet uz iepriekšējo apmeklēto saiti" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Iet uz nākamo apmeklēto saiti" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Rādīt apmeklēto saišu sarakstu" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "leduszils" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antīks balts" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarīns" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "debeszils" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "bēšs" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "krēmzupas" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "melns" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "mandeļkrāsa" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "zils" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "zili volets" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "brūns" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "parketbrūns" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadetu zils" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "šartrēzzaļš" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "šokolādes" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koraļļu" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "rudzupuķes zils" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "kukurūzas" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "tumšsarkans" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "ciāna" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "tumši zils" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "tumši ciāna" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "tumši zeltains" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "tumši pelēks" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "tumši zaļš" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "tumši haki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "tumši fuksīns" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "tumši olīvzaļš" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "tumši oranžs" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "tumšas orhidejas" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "tumši sarkans" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "tumši laša krāsa" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "tumši jūras zaļš" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "tumši šīfera zils" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "tumši šīfera pelēks" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "tumši tirkīza" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "tumši violets" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "tumši rozā" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "tumši debeszils" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "blāvi pelēks" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodger zils" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "ķieģeļsarkans" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "ziedu balts" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "meža zaļš" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksija" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "ļoti gaiši pelēks" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "spoku balts" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "zelta" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "zeltains" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "pelēks" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "zaļš" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "zaļi dzeltens" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "melones" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "karsti rozā" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indiāņu sarkans" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "ziloņkaula" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "haki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavandas sarkans" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "mauriņa zaļš" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "citronu šifons" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "gaiši zils" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "gaiši koraļļu" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "gaiši ciāns" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "gaiši zeltaini dzeltens" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "gaiši pelēks" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "gaiši zaļš" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "gaiši rozā" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "gaiši laša krāsas" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "gaiši jūras zaļš" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "gaiši debeszils" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "gaiši šīfera pelēks" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "gaiši tērauda zils" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "gaiši dzeltens" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "laima" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "laima zaļš" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "lins" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "fuksīns" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "kastaņbrūns" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "vidēji akvamarīns" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "vidēji zils" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "vidējas orhidejas" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "vidēji purpura" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "vidēji jūras zaļš" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "vidēji šīfera zils" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "vidēji pavasara zaļš" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "vidēji tirkīza" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "vidēji violeti sarkans" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "pusnakts zils" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "piparmētru krēma" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "miglaini rožains" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokasīns" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navaho balts" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "tumšzils" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "vecu mežģīņu" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olīva" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "tumši olīvu" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oranžs" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "oranži sarkans" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "jas" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "blāvi zeltains" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "blāvi zaļš" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "blāvi tirkīza" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "blāvi violeti sarkans" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "blāvi oranžs" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "gaiši persiku" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rozā" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "plūmju" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "pulverzils" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purpura" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "sarkans" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rožaini brūns" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "tumši zils" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "sedlu brūns" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "laša krāsas" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "smilšaini brūns" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "jūras zaļš" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "gliemežvāks" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sjēna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "sudraba" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "debeszils" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "šīfera zils" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "šīfera pelēks" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "sniegs" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "pavasara zaļš" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "tēraudzils" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "dzeltenbrūns" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "pelēkciāna" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "gaiši violets" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomātu" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "tirkīza" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violets" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "kviešu" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "balts" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "baltu dūmu" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "dzeltens" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "dzelteni zaļš" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktivizēt" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automātiskais fokusēšanas režīms struktūras navigācijas laikā" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automātiskais fokusēšanas režīms kursora navigācijas laikā" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automātiskais fokusēšanas režīms vietējā navigācijas laikā" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "_7 punkti" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "_8 punkti" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "7 un 8 _punkti" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "At_celt" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "Pārle_kt uz" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Labi" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikona" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Nekas" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Pareizrakstība" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Paziņot, kad tavi _draugi raksta" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Dot tērzēšanas istabai specifisku ziņoju_mu vēsturi" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Lasīt ziņojumus no" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Visi ka_nāli" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Visi kanāli, kas kā_ds %s logs ir aktīvs" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Kanāls tikai tad, ja _logs ir aktīvs" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "Izrunāt tērzēšanas i_stabas nosaukumu" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Ieslēgt izkārtojuma režīmu saturam" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dubultklikšķis" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trīskāršs klikšķis" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Noklusētais sintezators" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Pati virkne" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Aizvietojošā virkne" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Ieslēgt atbalsi pa _rakstzīmēm" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Aktivēt ne-atstarpes _diakritiskos taustiņus" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Pašreizējā atrašanās vieta" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimālais sakrītošā teksta garums:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Meklēšanas opcijas" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Iz_runāt tikai mainītās rindas meklēšanas laikā" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Izrunāt rezultātus _meklēšanas laikā" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Komanda" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Atslēgas Saistījums" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Noklusējuma" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Izkārtojuma režīms." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "paragrāfs" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braille Bindings" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Saglabāt grāmatzīmes" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Laiks un datums" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Peles pārskats ieslēgts." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navigācija" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objektu režīms." - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Nav saistīti" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Pamet vienoto pārskatu." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Pārslēgt runas detalizētības līmeni" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "galvenais saturs" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificēts" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_DarbaVirsmas" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Paziņojums" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Saņemts" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Paziņojums" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu iestatījumi priekš %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marķēt Brailā" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Parādīt, ja vien" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Runā" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Saglabāt profilu kā konfliktu" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Lietotāja profila konflikts!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profils %s jau eksistē.\n" -"Turpināt esošā profila atjaunināšanu ar šīm izmaiņām?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Ielādēt lietotāja profilu" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Tiks mainīts aktīvais profils. Ja esat tikko\n" -"veicis izmaiņas iestatījumos, tās tiks atmestas\n" -"pēc profila ielādēšanas.\n" -"\n" -"Turpināt ielādēt profilu un atmest iepriekšējās izmaiņas?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Saglabāt profilu kā" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profila nosaukums:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Izņemt lietotāja profilu" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Jūs grasāties izņemt profilu %s. Visi nesaglabātie iestatījumi un šajā " -"profilā saglabātie iestatījumi pazudīs. Vai vēlaties turpināt un izņemt šo " -"profilu un visus ar to saistītos iestatījumus?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Viss" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Lietotne" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Logs" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Nekādas" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Da_žs" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Pā_rsvarā" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Rinda" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Teikums" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Bloka citāts" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Poga" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Paraksts" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Atzīmes rūtiņa" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Klikšķināms" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kombinētais lodziņš" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Apraksts" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Virsraksts" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Iekšējais rāmis" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Attēls" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiķete" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Orientieris" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Līmenis" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Saite" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Saraksts" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Saraksta vienums" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekts" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Rindkopa" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radio poga" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Loma" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Izvēlētais vienums" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stāvoklis" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Teksts" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Vērtība" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Bloka citāts" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Pogas" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Atzīmes rūtiņas" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Klikšķināmie" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kombinētie lodziņi" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Ieraksti" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Formu lauki" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Virsraksti" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Iekšējie rāmji" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Attēli" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Virsraksti līmenī %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Orientieri" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Lieli objekti" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Saites" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Saraksti" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Saraksta vienumi" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Rindkopas" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radio pogas" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabulas" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Neapmeklētās saites" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Apmeklētās saites" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Pārvietošanās lapā" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Automātiski sākt _lapas runāšanu, kad tā ir pirmo reizi ielādējusies." - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Pasniegt lapas kopsavilkumu, kad tā ir pirmo reizi ielādējusies." - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Sadalīt r_unu fragmentos starp pauzēm" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s noklusēta balss" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Noklusētā" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hipersaite" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistēma" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Lielie burti" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Runas dispečers" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Pareizrakstības pārbaude" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Pareizrakstības _kļūda" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Pareizrak_stības ieteikums" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Rādīt kļūdas _kontekstu" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Izrunāt izklājlapas šūnas koordinātas" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Vienmēr izrunāt atlasīto izklājlapas diapazonu" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Pateikt sūnas _galveni" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Pārvietošanās tabulā" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Izlaist _tukšās šūnas" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "I_zrunāt šūnu" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Izrunāt šūnas koordinātas" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Izrunāt vairāku šūnu savienoju_mus" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Atribūta nosaukums" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Kontrolēt navigāciju ar kursoru" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Aktivēt _strukturālo navigāciju" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Skaņu _tēma:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Skaņu tēma" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Īs_s" - -#: src/cthulhu/guilabels.py:953 -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Paziņojums" -msgstr[1] "Paziņojums" -msgstr[2] "Paziņojums" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Šift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Kontrol" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "kreisais shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "kreisais alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "kreisā kontrole" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "labais shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "labais alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "labā kontrole" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "kreisie meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "labie meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "ciparslēdzis" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "reģistra slēdzis" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift slēdzis" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "ritslēdzis" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "lapa augšup" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "lapa lejup" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "kreisā tabulācija" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "atpakaļatkāpe " - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "ievadīšanas taustiņš" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "ievadīšanas taustiņš" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "augšup" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "lejup" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "pa kreisi" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "pa labi" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "kreisais super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "labais super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "izvēlne" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "palīdzība" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "daudz" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "režīma slēdzis" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "atsoļa taustiņš" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "ievietot" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "dzēst" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "mājas" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "beigas" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "sākums" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "jumtiņš" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "aplis" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "svītra" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "mīnus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Burtslēgs" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_K" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "treknraksts %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "slīpraksts %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "trekns slīpraksts %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "raksts %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "trekns raksts %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "faktūra %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "dubulta svītra %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "trekna faktūra %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "bezrēdzes %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "bezrēdzes treknraksts %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "bezrēdzes slīpraksts %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "bezrēdzes trekns slīpraksts %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "vienplatuma %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "bez punkta %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "bulta pa kreisi" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "bulta uz augšu" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "bulta pa labi" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "bulta uz leju" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "kreisā-labā bulta" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "augšup–lejup bulta" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "bulta uz augšu pa kreisi" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "bulta uz augšu pa labi" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "bulta uz leju pa labi" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "bulta pa kreisi ar svītru" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "bulta uz augšu ar svītru" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "bulta pa labi ar svītru" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "bulta uz leju ar svītru" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dubulta bulta pa kreisi" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dubulta bulta uz augšu" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dubulta bulta pa labi" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dubulta bulta uz leju" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dubulta bulta pa labi un pa kreisi" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dubulta bulta uz augšu un uz leju" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dubulta bulta uz augšu pa kreisi" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dubulta bulta uz augšu pa labi" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dubulta bulta uz leju pa labi" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dubulta bulta uz leju pa kreisi" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "pa labi vērsta bulta" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "pa labi vērsts bultas uzgalis" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "mīnus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "mazāks par" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "lielāks par" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "jumtiņš" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "apgrieztais jumtiņš" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "īsuma zīme" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punkts" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dubulta vertikāla līnija" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horizontāla daudzpunkte" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "visiem" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "papildinājums" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "parciālais diferenciālis" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "eksistē" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "neeksistē" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "tukša kopa" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "palielinājums" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "pieder" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "nepieder" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "maz pieder" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "satur" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "nesatur" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "mazs satur" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "pierādījuma beigas" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "Reizinājums" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koreizinājums" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "summa" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "mīnus pluss" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "punkts pluss" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "dalīšanas šķērssvītra" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "kopu mīnus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "zvaigznītes operators" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "apļa operators" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "punkta operators" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "kvadrātsakne" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "kubsakne" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "ceturtās pakāpes sakne" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcionāls ar" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "bezgalība" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "taisns leņķis" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "leņķis" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "mērīts leņķis" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sfērisks leņķis" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "dala" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "nedala" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paralēls ar" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "nav paralēls ar" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "loģiskais un" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "loģiskais vai" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "šķēlums" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "apvienojums" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integrālis" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dubultais integrālis" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "trīskāršais integrālis" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "kontūrintegrālis" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "virsmas integrālis" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "tilpuma integrālis" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "pulksteņrādītāja virziena integrālis" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "pulksteņrādītāja virziena kontūrintegrālis" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "pretēji pulksteņrādītāja virziena kontūrintegrālis" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "tāpēc" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "jo" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "attiecība" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporcija" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "punkts mīnus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "pārpalikums" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "ģeometriska proporcija" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotētisks " - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "apgrieztā tilde" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "apgriezts slinkais S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusa vilnis" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "vainaga reizinājums" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "nav tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "mīnus tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asimptotiski vienāds ar" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "nav asimptotiski vienāds ar" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "apmēram vienāds ar" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "apmēram vienāds ar bet nav vienāds ar" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ne aptuveni un ne faktiski vienāds ar" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "gandrīz vienāds ar" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "nav gandrīz vienāds ar" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "gandrīz vienāds vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "trīskārša tilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "viss vienāds ar" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "ģeometriski ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "starpība starp" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "tuvojas limitam" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "ģeometriski vienāds ar" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "aptuveni vienāds ar attēlojumu" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "attēlojums aptuveni vienādam" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "kols vienāds ar" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "vienāds ar kols" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "aplis iekš vienāds ar" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "aplis virs vienāds ar" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "atbilst" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "novērtē" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "vienādleņķu ar" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "zvaigzne virs vienāds ar" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta virs vienāds ar" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "pēc definīcijas vienāds ar" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "mērīts ar" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "varbūt vienāds ar" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "nav vienāds ar" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identisks ar" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "nav identisks ar" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "strikti ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "mazāks vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "lielāks vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "mazāks par virs vienāds ar" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "lielāks par virs vienāds ar" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "mazāks par bet nav vienāds ar" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "lielāks par bet nav vienāds ar" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "daudz mazāks par" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "daudz lielāks par" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "starp" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "nav ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "nav mazāks par" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "nav lielāks par" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "nav mazāks par vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "nav lielāks par vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "mazāks par vai ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "lielāks par vai ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "nav mazāks par nedz ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "nav lielāks par nedz ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "mazāks par vai lielāks par" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "lielāks par vai mazāks par" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ne mazāks par nedz lielāks par" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ne lielāks par nedz mazāks par" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "ir pirms" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "ir pēc" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "ir pirms vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "ir pēc vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "ir pirms vai ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "ir pēc vai ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "nav pirms" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "nav pēc" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "ir apakškopa" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "ir virskopa" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "nav apakškopa" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "nav virskopa" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "ir apakškopa vai vienāda ar" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "ir virskopa vai vienāda ar" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "nav apakškopa nedz vienāda ar" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "nav virskopa nedz vienāda ar" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "ir apakškopa bet nav vienāda ar" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "ir virskopa bet nav vienāda ar" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multikopa" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multikopas reizinājums" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "multikopas apvienojums" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "kvadrāta attēlojums no" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadrāta oriģināls no" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "kvadrāta attēlojums vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "kvadrāta oriģināls vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "kvadrātveida cepure" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadrātveida kauss" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "apvilkts pluss" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "apvilkts mīnus" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "apvilkta reizināšana" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "apvilkta dalīšanas šķērssvītra" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "apvilkts punkta operators" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "apvilkts riņķa operators" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "apvilkts zvaigznītes operators" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "apvilkta vienādības zīme" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "apvilkta domu zīme" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus kvadrātā" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "mīnuss kvadrātā" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "reizināšana kvadrātā" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "punkta operators kvadrātā" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "labais kniedes simbols" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "kreisais kniedes simbols" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "lejupvērstais kniedes simbols" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "augšupvērstais kniedes simbols" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "pieņēmums" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modelē" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "patiess" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "forsē" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "trīskārša vertikālā josla ar labo turniketu" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dubultā vertikālā josla ar dubulto labo turniketu" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "nepierāda" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "nav patiess" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "neforsē" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "noliegtā dubultā vertikālā josla ar dubulto labo turniketu" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "priekšā attiecībā" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "seko attiecībā" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normāla apakšgrupa" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "satur kā normālu apakšgrupu" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normāla apakšgrupa vai vienāda ar" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "satur normālu apakšgrupu vai vienāda ar" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "oriģināls no" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "attēlojums" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multiattēlojums" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermīta konjugētā matrica" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "ievietot" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "izslēdzošais vai" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "ne-un" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "ne-vai" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "taisns leņķis ar loku" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "taisnleņķa trīsstūris" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "romba operators" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "punkta operators" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "zvaigznes operators" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "dalīt reizināt" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "tauriņš" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "kreisais normālā faktora pustiešais reizinājums" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "labais normālā faktora pustiešais reizinājums" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "kreisais pustiešais reizinājums" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "labais pustiešais reizinājums" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "apgrieztas tildes vienādība" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "liekts loģiskais vai" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "liekts loģiskais un" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dubulta apakškopa" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dubulta virskopa" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dubults šķēlums" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dubults apvienojums" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "dakša" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "vienāda un paralēla ar" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "mazāks par ar punktu" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "lielāks par ar punktu" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "ļoti daudz mazāks par" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "ļoti daudz lielāks par" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "mazāks par vienāds ar vai lielāks par" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "lielāks par vienāds ar vai mazāks par" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "vienāds ar vai mazāks par" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "vienāds ar vai lielāks par" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "vienāds ar vai ir pirms" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "vienāds ar vai ir pēc" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "nav pirms vai vienāds" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "nav pēc vai vienāds" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "nav kvadrāta attēlojums vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "nav kvadrāta oriģināls vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "kvadrāta attēlojums vai nav vienāds ar" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "kvadrāta oriģināls vai nav vienāds ar" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "mazāks par bet nav ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "lielāks par bet nav ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "ir pirms bet nav ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "ir pēc bet nav ekvivalents ar" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "nav normāla apakšgrupa" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "nesatur kā normālu apakšgrupu" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "nav normāla apakšgrupa vai vienāda ar" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "nesatur kā normālu apakšgrupu vai vienāds ar" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertikāla daudzpunkte" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "vidēja horizontāla daudzpunkte" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "daudzpunkte diagonāli uz augšu pa labi" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "daudzpunkte diagonāli uz augšu pa kreisi" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "pieder ar garu horizontālu svītru" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "pieder ar vertikālu svītru horizontālas svītras beigās" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "mazs pieder ar vertikālu svītru horizontālas svītras beigās" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "pieder ar punktu virs" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "pieder ar svītru virs" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "mazs pieder ar svītru virs" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "pieder ar svītru zem" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "pieder ar divām horizontālām svītrām" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "satur ar garu horizontālu svītru" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "satur ar vertikālu svītru horizontālas svītras beigās" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "mazs satur ar vertikālu svītru horizontālas svītras beigās" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "satur ar svītru virs" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "mazs satur ar svītru virs" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z notācijas maisa piederība" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "kreisie griesti" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "labie griesti" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "kreisā grīda" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "labā grīda" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "augšējā figūriekava" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "apakšējā figūriekava" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "kreisā stūra iekava" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "labā stūra iekava" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "apvilkts punkts" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "apvienojums ar punktu" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "apvienojums ar plusu" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "kvadrāta šķēlums" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "kvadrāta apvienojums" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "melns kvadrāts" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "balts kvadrāts" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "melns rombs" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "balts aplis" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "melns aplis" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "balta aizzīme" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "melns vidēji mazs kvadrāts" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s par pasvītrojumu" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s ar slīpsvītru" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s ar vertikālu līniju" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "lietotne" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "tukšs" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "treknraksts" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "grāmatzīme ievadīta" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "grāmatzīmes saglabātas" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "grāmatzīmes nevarēja saglabāt" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nav atrastu orientieru." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Nav atrastu orientieru." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Apiešanas režīms aktivēts." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Nevar saņemt kalkulatora displeju" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Burtu reģistra stils, ko iestatīt ikonām." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "nekāds" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Burtu reģistra stils, ko iestatīt nekam." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "pareizrakstība" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Burtu reģistra stils, ko iestatīt pareizrakstībai." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Lietotne kontrolē kursoru." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Lietotne kontrolē kursoru." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "%s šūna" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s atlasīts" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "no %s līdz %s atlasīts" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "no %s līdz %s atlase atcelta" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s atlase atcelta" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Novērts opcijas izmantošanu" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Piespiest opcijas izmantošanu" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCIJA" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Neobligāti parametri" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Lietošana: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Sekojošie nav derīgi: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Drukāt zināmās palaistās lietotnes" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Ielādēt profilu" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Nevarēja ielādēt profilu — %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "Nevar palaist ekrāna lasītāju, jo nevar sazināties ar darbvirsmu." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Neizdevās aktivizēt iestatījumu pārvaldnieku. Iziet." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Vēl viens ekrāna lasītāja process jau darbojas šajā sesijā.\n" -"Palaid “cthulhu --replace”, lai aizvietotu to procesu ar jaunu." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOSAUKUMS" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Izmantot citu mapi lietotāja iestatījumiem" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Šīs lietotnes versija" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Aizstāj pašlaik palaisto ekrāna lasītāja instanci" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Rādīt šo palīdzības ziņojumu un iziet" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Nosūtīt atkļūdošanas izvadi uz debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Sūtīt atkļūdošanas izvadi uz norādīto datni" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "DATNE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Iestatīt lietotāja iestatījumus (teksta versija)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Iestatīt lietotāja iestatījumus (grafiskā versija)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Ziņojiet par kļūdām uz https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Izgriezt atlasīto uz starpliktuvi." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "izgriezt" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Kopēja atlasi uz starpliktuvi." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopēts" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Ielīmēja saturu no starpliktuves." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "ielīmēts" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Nepaziņot, kad tavi draugi raksta." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "paziņot, kad tavi draugi raksta." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Ziņojums no čata istabas %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Jauna tērzēšanas cilne %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Neizrunāt čata istabas nosaukumu." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "izrunāt čata istabas nosaukumu." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Nedot tērzēšanas istabai specifisku ziņojumu vēsturi." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Dot tērzēšanas istabai specifisku ziņojumu vēsturi." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "dzēšanas sākums" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "dzēšanas beigas" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "ievietošanas sākums" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "ievietošanas beigas" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "izcelšanas sākums" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "izcelšanas beigas" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "ieteikuma beigas" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Konteinera beigas." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Nav konteinerī." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "visi vienumi atlasīti" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Noklusētā poga ir %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Noklusējuma poga ir %s. Pelēka" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Noklusētā poga ir %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " apakšraksts %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " augšraksts %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Nav pieejams tabulā." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "atlasīts viss dokuments" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "visa dokumenta atlase atcelta" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokuments atlasīts no kursora atrašanās vietas" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "dokumentam atcelta atlase no kursora vietas" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokuments atlasīts līdz kursora atrašanās vietai" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "dokumentam atcelta atlase līdz kursora vietai" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dinamiskā kolonnas galvene iestatīta rindai %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dinamiski nodzēst kolonnas galveni." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dinamiski iestatīt rindas galveni %s kolonnai" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dinamiski nodzēst rindas galveni." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "tukšs" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobaiti" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabaiti" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Neviena datne nav atrasta." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Pievieno saturu starpliktuvei." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Kopē saturu uz starpliktuvi." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Neizmanto vienoto pārskatu." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Ieiet vienotajā pārskatā." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Pamet vienoto pārskatu." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Virzīt vienoto pārskatu uz vārdu, kas ir virs esošā vārda" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Plakanais pārskats neierobežots" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "ir formula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "atver dialoglodziņu" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "atver režģi" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "atver sarakstu kasti" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "atver izvēlni" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "atver koku" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "attēla kartes saite" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Ievadītais taustiņš jau ir sasaistīts ar %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Taustiņš notverts: %s. Nospiediet “ievadīšana”, lai apstiprinātu." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Jaunais taustiņš ir: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" -"Taustiņu sasaiste dzēsta. Spiediet ievadīšanas taustiņu, lai apstiprinātu." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Taustiņu sasaiste ir izņemta." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "ievadiet jaunu taustiņu" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "taustiņš" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Atbalss iestatīts uz taustiņa." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nekas" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Atbalss iestatīts uz neko." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "taustiņš un vārds" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Atbalss iestatīts uz taustiņa un vārda." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "teikums" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Atbalss iestatīts uz teikuma." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "vārds" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Atbalss iestatīts uz vārda." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "vārds un teikums" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Atbalss iestatīts uz vārda un teikuma." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Ietvēra: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "aktuārais simbols" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "kaste" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "aplis" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "garā dalīšanas zīme" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "sakne" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "noapaļota kaste" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "horizontāla svītra" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "vertikāla svītra" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "uz leju vērsta diagonāla svītra" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "uz augšu vērsta diagonāla svītra" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "bulta uz augšu pa kreisi" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "līnija apakšā" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "līnija pa kreisi" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "līnija pa labi" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "līnija augšpusē" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "vektora leņķis" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "arābu daļas simbols" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "un" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "daļskaitļa sākums" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "daļskaitļa bez svītras, sākums" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "virs" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "daļskaitļa beigas" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "kvadrātsakne" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "kubsakne" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "sakne" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "saknes sākums" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "saknes beigas" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "apakšraksts" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "augšraksts" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pirms apakšraksta" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pirms augšraksta" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "novietots zem" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "novietots virs" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "tabulas beigas" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "ligzdotas tabulas beigas" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "nepieejams" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Izslēgts" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Izslēgta atkāpju un izlīdzinājumu izrunāšana." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Ieslēgts" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Ieslēgta atkāpju un izlīdzinājumu izrunāšana." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Mācīšanās režīms. Nospiediet atsoli, lai izietu." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Ieiet mācīšanās režīmā. Spiediet jebkuru taustiņu, lai uzzinātu tās " -"funkciju. Lai skatītu ekrāna lasītāja dokumentāciju, spiediet F1. Lai " -"saņemtu sarakstu ar ekrāna lasītāja noklusējuma īsceļiem, spiediet F2. Lai " -"saņemtu sarakstu ar ekrāna lasītāja saīsnēm šai lietotnei, spiediet F3. Lai " -"izietu no apmācības režīma, spiediet atsoļa taustiņu (Esc)." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "pamet bloka citātu." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "pamet detalizēto informāciju." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "pamet plūsmu." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "pamet ilustrāciju." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "pamet formu." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "pamet karoga joslu." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "pamet papildinājuma saturu." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "pamet informāciju." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "pamet galveno saturu." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "pamet navigāciju." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "pamet reģionu." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "pamet meklēšanu." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "pamet sarakstu." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "pamet paneli." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "pamet tabulu." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "pamet paskaidri." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "pamet anotāciju." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "pamet atzinības." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "pamet pēcvārdu." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "pamet pielikumu." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "pamet bibliogrāfiju." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "pamet nodaļu." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "pamet izdošanas ziņas." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "pamet secinājumus." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "pamet autoru." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "pamet autorus." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "pamet vēlējumu." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "pamet beigu vēres." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "pamet epigrāfu." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "pamet epilogu." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "pamet kļūdas." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "pamet piemēru." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "pamet pēcvārdu." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "pamet glosāriju." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "pamet rādītāju." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "pamet ievadu." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "pamet lappušu sarakstu." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "pamet daļu." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "pamet priekšvārdu." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "pamet prologu." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "pamest izceltu citātu." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "pamet jautājumus un atbildes." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "pamet piedāvājumu." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "pamet satura rādītāju." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "rinda atlasīta zem kursora" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "rinda atlasīta virs kursora " - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "rindai atcelta atlase zem kursora" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "rindai atcelta atlase virs kursora" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Iziet no mācīšanās režīma." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "rinda atlasīta no sākuma līdz iepriekšējās kursora vietas" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "rinda atlasīta līdz beigām no iepriekšējās kursora vietas" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "saite" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "tā pati lapa" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "tā pati vietne" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "cita vietne" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s saite uz %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s saite" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "apmeklēta %s saite" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Izmantojiet augšup vai lejup bultas, lai pārvietotos pa sarakstu. Spiediet " -"atsoļa taustiņu, lai izietu." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Visi dzīvie apgabali ir izslēgti" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "atjaunoti dzīvo apgabalu līmeņi" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "pieklājības līmenis %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "iestata dzīvo apgabalu uz uzstājīgu" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "iestatīt dzīvo apgabalu uz izslēgtu" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "iestatīt dzīvo apgabalu uz pieklājīgu" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "iestatīt dzīvo apgabalu uz rupju" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Dzīvo apgabalu pārraudzība izslēgta" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Dzīvo apgabalu pārraudzība ieslēgta" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nav saglabāts dzīvais ziņojums" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Dzīvo apgabalu atbalsts ir izslēgts." - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nav atrasts" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Nevarēja atrast pašreizējo atrašanās vietu." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "izslēgts" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "ieslēgts" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "nepareizi uzrakstīts" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Nepareizi uzrakstīts vārds: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Konteksts ir %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Pārlūkošanas režīms" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Fokusēšanās režīms" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Lai ieslēgtu fokusu, spiediet %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Fokusēšanās režīms ir lipīgs." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Pārlūkošanas režīms ir lipīgs." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Izkārtojuma režīms." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objektu režīms." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Nav vairāk lielu objektu." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Pele virs objekta nav atrasta." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Peles pārskats izslēgts." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Peles pārskats ieslēgts." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Kļūda — nevarēja izveidot objektu sarakstu." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Nav bērnu." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Nav nākamā." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d procents." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Iet uz iepriekšējo lietu vai vārdu" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Vienkāršotā navigācija iespējota." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Vienkāršotā navigācija atspējota." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Koka līmenis %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Tika pievienots jauns vienums" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Nav atrasta darbību uz: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Bez fokusa" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Neviena lietotne nav fokusā." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Vairs nav bloka citātu." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Vairs nav pogu." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Vairs nav atzīmes rūtiņu." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Nav vairāk lielu objektu." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Nav vairāk klikšķināmo." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Vairs nav kombinēto lodziņu." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Vairs nav ierakstu." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Formas lauku nav." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Nav vairāk virsrakstu." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Nav vairāk virsrakstu līmenī %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Nav vairāk tabulu." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Nav vairāk attēlu." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nav atrastu orientieru." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Vairs nav saišu." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Sarakstu nav." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Saraksta vienumu vairs nav." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Vairs nav dzīvo apgabalu." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Vairs nav rindkopu." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Vairs nav radio pogu." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Vairs nav atdalītāju." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Nav vairāk tabulu." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Neapmeklētu saišu nav." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Apmeklētu saišu nav." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Nav atlasīts teksts." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nav uz saites." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Paziņojums" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Apakša" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Augša" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Nav paziņojumu" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "cipari" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Izrunāt skaitļus kā ciparus." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "vārdi" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Izrunāt skaitļus kā vārdus." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "izslēgts" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ieslēgts" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Ielādējas. Lūdzu gaidiet." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Ielāde beigsies." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Ielāde beigsies %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Lapā ir %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "lapa atlasīta no kursora" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "lapa atlasīta līdz kursoram" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "lapai atcelta atlase no kursora" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "lapai atcelta atlase līdz kursora vietai" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "rindkopa atlasīta zem kursora" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "rindkopa atlasīta virs kursora" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "rindkopai ir atcelta atlase zem kursora" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "rindkopai ir atcelta izvēle virs kursora" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Jau ir atvērts Cthulhu iestatījumu dialoglodziņš.\n" -"Lūdzu, aizveriet to, lai atvērtu jaunu." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "slaids %(position)d no %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profils ir iestatīts uz %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nav atrastu profilu." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Progresa josla %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Visas" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Interpunkcijas izrunāšanas līmenis iestatīts uz visām." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Vairums" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Interpunkcijas izrunāšanas līmenis iestatīts uz vairumu." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nekādas" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Interpunkcijas izrunāšanas līmenis iestatīts uz nekādām." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Dažas" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Interpunkcijas izrunāšanas līmenis iestatīts uz dažām." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Meklēšana." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Meklēšana pabeigta." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Pārlādēti ekrāna lasītāja iestatījumi." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Atlasītais teksts ir: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Atlase ir izdzēsta." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Atlase ir atjaunota." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Teksta atlase atcelta." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Izmērs: %d, %d. Lokācija: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Platums: %d. Augstums: %d. %d no kreisās. %d no augšas." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Izruna izslēgta." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Izruna ieslēgta." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "ātrāk." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "lēnāk." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "augstāk." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "zemāk." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "skaļāk." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "maigāk." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Ātrums %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Augstums %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Skaļums %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher modulis %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher balss %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nav pieejamu serveru." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nav pieejamu balsu." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Izruna ieslēgta." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Izruna netiks lietota." - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Detalizētības līmenis: īsi" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Detalizētības līmenis: plaši" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "punkts punkts punkts" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu jūs sveicina." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu slēpjas zem viļņiem." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Miega režīms iespējots priekš %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Miega režīms atspējots priekš %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Izruna nav pieejama." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Nav atrasts" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Statusa josla nav atrasta" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "meklējamais vārds nav atrasts" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Strukturālās pārvietošanās taustiņi izslēgti." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Strukturālās pārvietošanās taustiņi ieslēgti." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nav atrasts" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Rinda %(row)d, kolonna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Tabulas beigas" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "izrunāt šūnu" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "izrunāt rindu" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Ne-vienveidīgs" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Nav pieejams tabulā." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Pārkārtotas kolonnas" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Pārkārtotas rindas" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "kolonna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolonna %(index)d no %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Kolonnas apakšā." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Kolonnas augšā." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Kolonna %s atlasīta" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Kolonnas no %s līdz %s atlasītas" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Kolonnu no %s līdz %s atlase atcelta" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Kolonnas %s atlase atcelta" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "rinda %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "rinda %(index)d no %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Rindas sākumā." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Rindas beigās." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Rinda dzēsta." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Pēdējā rinda dzēsta." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Rinda ievietota." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Rinda ievietota tabulas beigās." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Rinda %s atlasīta" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Rindas no %s līdz %s atlasītas" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Rindu no %s līdz %s atlase atcelta" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Rindas %s atlase atcelta" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "atlasīts" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "atlase atcelta" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H stundas, %M minūtes un %S sekundes" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H stundas un %M minūtes" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unikods %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "atsaukt" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "atatsaukt" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versija %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "tīrā atstarpe" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Apliec līdz apakšai." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Apliec līdz augšai." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 vienumi" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Šūna apvieno %d rindu" -msgstr[1] "Šūna apvieno %d rindas" -msgstr[2] "Šūna apvieno %d rindu" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d kolonna" -msgstr[1] " %d kolonnas" -msgstr[2] " %d kolonnu" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Šūna apvieno %d kolonnu" -msgstr[1] "Šūna apvieno %d kolonnas" -msgstr[2] "Šūna apvieno %d kolonnu" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d rakstzīme par garu" -msgstr[1] "%d rakstzīmes par garu" -msgstr[2] "%d rakstzīmes par garu" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialogs)" -msgstr[1] "(%d dialogi)" -msgstr[2] "(%d dialogi)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d nefokusēts dialoglodziņš" -msgstr[1] "%d nefokusēti dialoglodziņi" -msgstr[2] "%d nefokusēti dialoglodziņi" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d baits" -msgstr[1] "%d baiti" -msgstr[2] "%d baitu" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "atrasta %d datne" -msgstr[1] "atrastas %d datnes" -msgstr[2] "atrastas %d datnes" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d forma" -msgstr[1] "%d formas" -msgstr[2] "%d formu" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d galvene" -msgstr[1] "%d galvenes" -msgstr[2] "%d galvenes" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d vienums" -msgstr[1] "%d vienumi" -msgstr[2] "%d vienumu" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d orientieris" -msgstr[1] "%d orientieri" -msgstr[2] "%d orientieru" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "atrasts %d vienums" -msgstr[1] "atrasti %d vienumi" -msgstr[2] "atrasti %d vienumi" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Pamet %d bloka citātu." -msgstr[1] "Pamet %d bloka citātus." -msgstr[2] "Pamet %d bloka citātus." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Pamet %d sarakstu." -msgstr[1] "Pamet %d sarakstus." -msgstr[2] "Pamet %d sarakstu." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Saraksts ar nezināmu izmēru" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Saraksts ar %d vienumu" -msgstr[1] "Saraksts ar %d vienumiem" -msgstr[2] "Saraksts ar %d vienumiem" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Plūsma ar nezināmu izmēru" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Plūsma ar %d rakstu" -msgstr[1] "Plūsma ar %d rakstiem" -msgstr[2] "Plūsma ar %d rakstiem" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Aprakstu saraksts ar %d termu" -msgstr[1] "Aprakstu saraksts ar %d termiem" -msgstr[2] "Aprakstu saraksts ar %d termiem" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d vērtība" -msgstr[1] "%d vērtības" -msgstr[2] "%d vērtību" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "matemātikas tabula ar %d rindu" -msgstr[1] "matemātikas tabula ar %d rindām" -msgstr[2] "matemātikas tabula ar %d rindām" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d kolonna" -msgstr[1] "%d kolonnas" -msgstr[2] "%d kolonnu" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "ligzdota tabula ar %d rindu" -msgstr[1] "ligzdota tabula ar %d rindām" -msgstr[2] "ligzdota tabula ar %d rindām" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d ziņojums.\n" -msgstr[1] "%d ziņojumi.\n" -msgstr[2] "%d ziņojumi.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d procents." -msgstr[1] "%d procenti." -msgstr[2] "%d procenti." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d procents no dokumenta izlasīts" -msgstr[1] "%d procenti no dokumenta izlasīti" -msgstr[2] "%d procenti no dokumenta izlasīti" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pikselis" -msgstr[1] "%d pikseļi" -msgstr[2] "%d pikseļu" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s rakstzīme" -msgstr[1] "%(count)d %(repeatChar)s rakstzīmes" -msgstr[2] "%(count)d %(repeatChar)s rakstzīmes" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "atlasīts %(index)d no %(total)d vienuma" -msgstr[1] "atlasīti %(index)d no %(total)d vienumiem" -msgstr[2] "atlasīti %(index)d no %(total)d vienumiem" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Atrasts %d ekrāna lasītāja noklusējuma īsceļš." -msgstr[1] "Atrasti %d ekrāna lasītāja noklusējuma īsceļi." -msgstr[2] "Atrasti %d ekrāna lasītāja noklusējuma īsceļu." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Atrasts %(count)d ekrāna lasītāja īsceļš lietotnei %(application)s." -msgstr[1] "Atrasti %(count)d ekrāna lasītāja īsceļi lietotnei %(application)s." -msgstr[2] "Atrasti %(count)d ekrāna lasītāja īsceļi lietotnei %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d atstarpe" -msgstr[1] "%d atstarpes" -msgstr[2] "%d atstarpes" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulācija" -msgstr[1] "%d tabulācijas" -msgstr[2] "%d tabulāciju" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabulācija" -msgstr[1] "%d tabulācijas" -msgstr[2] "%d tabulācija" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabula ar nezināmu izmēru" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabula ar %d kolonnu, rindu skaits nav zināms" -msgstr[1] "tabula ar %d kolonnām, rindu skaits nav zināms" -msgstr[2] "tabula ar %d kolonnām, rindu skaits nav zināms" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabula ar %d rindu, kolonnu skaits nav zināms" -msgstr[1] "tabula ar %d rindām, kolonnu skaits nav zināms" -msgstr[2] "tabula ar %d rindām, kolonnu skaits nav zināms" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabula ar %d rindām" -msgstr[1] "tabula ar %d rindām" -msgstr[2] "tabula ar %d rindām" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "pirms %d sekundes" -msgstr[1] "pirms %d sekundēm" -msgstr[2] "pirms %d sekundes" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "pirms %d minūtes" -msgstr[1] "pirms %d minūtēm" -msgstr[2] "pirms %d minūtes" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "pirms %d stundas" -msgstr[1] "pirms %d stundām" -msgstr[2] "pirms %d stundas" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "pirms %d dienas" -msgstr[1] "pirms %d dienām" -msgstr[2] "pirms %d dienas" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d neapmeklēta saite" -msgstr[1] "%d neapmeklēta saites" -msgstr[2] "%d neapmeklētu saišu" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d apmeklēta saite" -msgstr[1] "%d apmeklētas saites" -msgstr[2] "%d apmeklētas saites" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "pārslēgt" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "uz %(index)d no %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d no %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "vienums %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "LĪMENIS %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "koka līmenis %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "KOKA LĪMENIS %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "informācija par %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "ir informācija iekš %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "ieteikums" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "rediģējams kombinētais lodziņš" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "rediģējams saturs" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "plūsma" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "ilustrācija" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "anotācija" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "atzinības" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "pēcvārds" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "pielikums" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "bibliogrāfijas ieraksts" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliogrāfija" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "nodaļa" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "izdošanas ziņas" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "secinājums" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "vāks" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "autors" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "autori" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "veltījums" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "beigu vēre" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "beigu vēres" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigrāfs" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilogs" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "kļūdas" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "piemērs" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "priekšvārds" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosārijs" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "rādītājs" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "ievads" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "lappuses atdalītājs" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "lappušu sarakts" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "daļa" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "priekšvārds" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prologs" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "izcelts citāts" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "jautājumi un atbildes" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "apakšvirsraksts" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "satura rādītājs" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s līmenis %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "horizontāla ritjosla" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "vertikāla ritjosla" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "horizontāls slīdnis" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "vertikāls slīdnis" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "horizontāls atdalītājs" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "vertikāls atdalītājs" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "slēdzis" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Ikonu panelis" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "karoga josla" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "papildinājuma saturs" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informācija" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "galvenais saturs" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigācija" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "reģions" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "meklēšana" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "apmeklēta saite" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "izvēlnes poga" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "kārtot augoši" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "kārtot dilstoši" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "sakārtots" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klikšķināms" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "sakļauts" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "paplašināts" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "ir garš apraksts" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontāls" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikāls" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "atzīmēta" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nav atzīmēta" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "ieslēgts" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "izslēgts" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "daļēji atzīmēts" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "piespiests" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "nav piespiests" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "nav atlasīts" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "atlasīts" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "nav atlasīts" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "nav atlasīts" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "apmeklēta" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "neapmeklēta" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ēnots" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "tikai lasāms" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "tikailas" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "nepieciešams" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "vairāku atlase" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "nederīgs ieraksts" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "nederīgs" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "nederīga pareizrakstība" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "pareizrakstība" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "nederīga gramatika" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatika" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Meklēt" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Ekrāna lasītāja meklēšanas dialogs" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Aizvērt" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Meklēt" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Meklēt:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Meklēt:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Augšā no logs" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Loga augšā" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Sākt no:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Riņķot" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Meklēt _pretējā virzienā" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Meklēšanas virziens:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Atbilst reģistrjūtība" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Atbilst tikai _viss vārds" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opcijas:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Noklusētais" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Augšējais reģistrs" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hipersaite" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistēma" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplikācija" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Logs" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu ekrāna lasītājs" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Palīdzība" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Pielietot" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Portatīvs" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Tastatūras izkārtojums" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktīvais _profils:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Palaišanās profils:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "Ie_lādēt" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "S_aglabāt kā" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Izņemt" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profili" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Parādīt paskaidrnes" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Izrunāt objekt_us zem peles" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Pele" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Laika formā_ts:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Datuma _formāts:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Laiks un datums" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Izrunāt atjauninājumu_s" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Rādīt _Brailā atjauninājumus" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Biežums (sek):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Attiecas uz:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Pīkstēt atjauninājumus" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Progresa joslas atjauninājumi" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Ieslēgt _attīšanu un ātro patīšanu iekš “Teikt visu”" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Ieslēgt _strukturālo navigāciju iekš ”Teikt visu“" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "_Teikt visu pa:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Paziņot bloka _citātus iekš “Teikt visu”" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Paziņot _sarakstus iekš “Teikt visu”" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Paziņot _tabulas iekš “Teikt visu”" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Paziņot _paneļus iekš “Teikt visu”" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Paziņot _formas iekš “Teikt visu”" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Paziņot _orientierus iekš “Teikt visu”" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Teikt visu" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Elementa _prezentācija:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Vispārējs" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Ska_ļums:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Pla_cis:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Temps:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persona:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "Va_loda:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Izrunas sinte_zētājs:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Izrunas _sistēma:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Balss _veids:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Lielo burtu stils:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Balss tipa iestatījumi" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Izrunāt dažādu reģistru virknes kā vār_dus" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Izru_nāt skaitļus kā ciparus" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Globālie balss iestatījumi" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Balss" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Ieslēgt izrunu" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Daudz_vārdīgs" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Detalizētība" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Viss" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Interpunkcijas līmenis" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Izrunāt tikai attēloto tekstu" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Izrunāt tukšās rindas" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Izrunāt _atkāpi un izlīdzinājumu" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Runas obje_kta mnemonika" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Izrunāt bērna n_ovietojumu" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Izrunāt mācību ziņojumus" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Sistēmas ziņojumi ir detalizēti" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "_Izrunāt krāsas kā nosaukumus" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Paziņot bloka _citātus navigācijas laikā" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Paziņot _sarakstus navigācijas laikā" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Paziņot _tabulas navigācijas laikā" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Izrunāt nepareizi uzrakstītu vārdu indikatoru" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Paziņot _paneļus navigācijas laikā" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Paziņot orientierus navigācijas laikā" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Paziņot _formas navigācijas laikā" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Izrunāt _aprakstu" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Iz_runāt pilnas rindas izklājlapās" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Izrunāt pilnas rindas _dokumentu tabulās" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Izrunāt pilnas rindas _GUI tabulās" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Izrunātā konteksts" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Izruna" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Ieslēgt braila _atbalstu" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Saīsināti lomu nosaukumi" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "D_eaktivēt rindas beigas simbolu" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Kontrakcijas _tabula:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Aktivēt kontrakcijas Brailu" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Ieslēgt _vārdu aplaušanu" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Attēlošanas iestatījumi" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Nekādi" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Atlases indikators" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hipersaites indikators" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Ieslēgt uzplaiksnījuma ziņoju_mus" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Ilg_ums (sekundēs):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Ziņojumi ir _pastāvīgi" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Ziņojumi ir _detalizēti" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Uzplaiksnījuma ziņojumu iestatījumi" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Brails" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Ieslēgt _taustiņu atbalsi" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Ieslēgt _alfabētiskos taustiņus" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Ieslēgt skaitliskos ta_ustiņus" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Ieslēgt inter_punkcijas taustiņus" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Ie_slēgt atstarpi" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Ieslēgt _pārveidotājtaustiņus" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Ieslēgt _funkcijas taustiņus" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Ieslēgt dar_bības taustiņus" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Ieslēgt _pārvietošanās taustiņus" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Ieslēgt _vārda atbalsi" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Ie_slēgt teikumu atbalsi" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Atbalss" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Ekrāna lasītāja _modifikatora taustiņš(-i):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Atslēga Sasaistes " - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Izrunas vārdnīca" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Jau_ns ieraksts" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Dzēst" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Izruna" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Izrunāt vi_su" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Neteikt _neko" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Pārstatīt" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Teksta atribūti" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Pārvietot uz _apakšu" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Pārvietot _lejup" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Pārvietot augš_up" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Pārvie_tot uz virspusi" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Pielāgot izvēlēto atribūtu" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Braila indikators" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Teksta atribūti" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Iespējot AI palīgu" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Pakalpojumu sniedzējs:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokāls - Bezmaksas)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API _atslēgas fails:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Ceļš uz API atslēgas failu" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Iegūt _Claude API atslēgu" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Atvērt pārlūku, lai iegūtu Claude API atslēgu un automātiski saglabātu" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Pieprasīt apstiprinājumu pirms AI darbībām" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _modelis:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Modeļa nosaukums Ollama (piem., llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _galapunkts:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API galapunkta URL (piem., http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Ekrānuzņēmuma _kvalitāte:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "zemāk" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Vidēja" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Augsta" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI palīgs" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Va_loda:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "jēna" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Mērogu koeficients:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Pelēktoņu attēls" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Invertēt attēlu" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Melnbalts attēls" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Melns/balts _slieksnis:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analizēt krāsas" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Kopē saturu uz starpliktuvi." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "fona krāsa" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "fona pilns augstums" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "fona punktēšana" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "virziens" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "rediģējams" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "uzvārds" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "priekšplāna krāsa" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "priekšplāna punktēšana" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "fonta efekts" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "atkāpe" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "kļūda" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "neredzams" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "izlīdzinājums" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "valoda" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "kreisā mala" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "rindas augstums" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "rindkopas stils" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pikseļi virs rindiņām" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pikseļi zem rindiņām" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pikseļu iekšpus aplaušanas" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "labā mala" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "pacelt" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "mērogs" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "izmērs" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "izvērsums" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "pārsvītrojums" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stils" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "teksta noformējums" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "teksta rotācija" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "teksta ēna" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "pasvītrots" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variants" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "vertikāla līdzināšana" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "svars" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "aplaušanas režīms" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "rakstīšanas režīms" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "patiess" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "aplams" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "nekāds" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "iegravēts" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "izkalt" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "kontūra" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "virssvītra" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "pārsvītrot" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "mirgot" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "melns" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "viens" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dubults" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "zemāk" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "rakstz" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "vārds" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "vārda rakstz" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "pa kreisi" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "pa labi" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "vidū" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "bez izlīdzināšanas" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "aizpildīt" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ļoti saspiests" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "vēl saspiests" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "saspiests" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "nedaudz saspiests" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normāls" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "nedaudz izvērsts" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "izvērsts" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "vēl izvērsts" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ļoti izvērsts" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "samazināti lielie burti" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "slīps" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "slīpraksts" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Noklusētais" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Pamatteksts" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Virsraksts" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "bāzes līnija" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "zem" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "virs" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "teksta augša" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "vidus" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "apakša" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "teksta apakša" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "mantots" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "vienlaidus" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "pareizrakstība" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Nospiediet atstarpi, lai pārslēgu." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Nospiediet atstarpi, lai izvērstu; un bultiņas uz augšu un leju, lai " -"izvēlētos vienumu." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Spiediet alt+f6, lai dotu fokusu bērna logiem." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Lai pārvietotu vienumus, izvelieties vai nu bultu taustiņus, vai rakstiet " -"meklējot." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Lai saņemtu sistēmas izvēlnes, spiediet alt+f1 taustiņu." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Lietojiet bultiņas uz augšu un leju, lai izvēlētos vienumu." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Lai sakļautu, spiediet pārslēgšanas un kreisās bultiņas taustiņu." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Lai izvērstu, spiediet pārslēgšanas un labās bultiņas taustiņu." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Lai aktivētu, spiediet “Enter”" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Ievadiet tekstu." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" -"Izmantojiet kreiso un labo bultiņu taustiņus, lai skatītu citas cilnes." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Lai aktivētu, spiediet atstarpes taustiņu." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Lietojiet bultiņas uz augšu vai leju, lai izvēlētos vērību. Vai ievadiet " -"vēlamo skaitlisko vērtību." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Izmantojiet bultiņu taustiņus, lai mainītu." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Lai pārvietotos, spiediet kreiso vai labo bultiņu taustiņus. Lai pārvietotos " -"cauri vienumiem, spiediet uz augšu vai uz leju bultiņu taustiņus." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Lai ieietu apakšizvēlnē, spiediet labās bultiņas taustiņu." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Lai samazinātu, spiediet kreiso bultiņu; lai palielinātu, spiediet labo " -"bultiņu. Lai ietu uz minimumu, spiediet mājas taustiņu, lai ietu uz " -"maksimumu, spiediet beigu taustiņu." diff --git a/po/mai.po b/po/mai.po deleted file mode 100644 index b6c8ba3..0000000 --- a/po/mai.po +++ /dev/null @@ -1,9576 +0,0 @@ -# translation of cthulhu.HEAD.po to Maithili -# Copyright (C) 2006 The GNOME Foundation -# This file is distributed under the same license as the PACKAGE package. -# BOSS GNU/Linux , 2008. -msgid "" -msgstr "" -"Project-Id-Version: gedit.HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2008-01-25 13:49+0530\n" -"Last-Translator: Sangeeta Kumari\n" -"Language-Team: \n" -"Language: mai\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n" -"\n" -"\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu स्क्रीन पाठक / आवर्द्धक" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "दिनांक" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "आरेख बनाबू" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "लिंक " - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "रेडियो" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "स्लाइडर" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "स्पिन" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "मद" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "संकेत" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "अनुच्छेद" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "ऑटो" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "स्थान" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "न्यूलाइन" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "टैब" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "विस्मयादिबोधक" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "उद्धरण" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "डॉलर" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "प्रतिशत" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "आओर" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "वर्णलोप क' चिह्न" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "बामाँ पैरन" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "दहिन्ना पैरन" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "तारा" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "जोड़" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "विराम चिह्न" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "डैश" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "डॉट" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "स्लैश" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "कॉलन" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "अर्द्ध विराम" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "बराबर" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "प्रश्न" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "एट" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "बामाँ कोष्ठ" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "बैकस्लैश" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "दहिन्ना कोष्ठ" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "हँसपद" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "रेखांकित करू" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "ग्रेव" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "बामाँ ब्रेस" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "दहिन्ना ब्रेस" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "टिल्डे" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "बैकस्पेस" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "खंड" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "बामाँ पैरन" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "दहिन्ना पैरन" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "बामाँ पैरन" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "दहिन्ना पैरन" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "मोजुदा फ्लैट रिव्यू मद पर बामाँ क्लिक करू " - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "मोजुदा फ्लैट रिव्यू मद पर दहिन्ना क्लिक करू " - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "पूर्ण दस्ताबेज क' संबंधमे बताउ" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "मोजुदा समतल रिव्यू पँक्ति क' संबंधमे बाजैत अछि" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "मोजुदा समतल रिव्यू पँक्ति क' संबंधमे बाजैत अछि" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "खाली पँक्ति बाजू" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "प्रस्थिति बार" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Cthulhu खोज समाद खोलू." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "स्ट्रिंग क' अगिला उदाहरणमे खोजू" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "स्ट्रिंग क' पछिला उदाहरणमे खोजू" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "समतल रिव्यू मोड प्रविष्ट करैत आ बाहर निकलैत अछि." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "अंत स्थितिमे समतल रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "होम स्थितिमे समतल रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "अंत स्थितिमे समतल रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "पछिला पँक्ति क' शुरूमे फ्लैट रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "मोजुदा समतल रिव्यू पँक्ति क' संबंधमे बाजैत अछि" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "मोजुदा समतल रिव्यू पँक्ति क' संबंधमे बाजैत अछि" - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "मोजुदा समतल रिव्यू पँक्ति क' संबंधमे बाजैत अछि" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "अगिला पँक्ति क' शुरूमे समतल रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "पछिला मद अथवा शब्दमे समतल रिव्यू घसकाबू." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "मोजुदा समतल रिव्यू पँक्ति क' संबंधमे बाजैत अछि" - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "मोजुदा समतल रिव्यू पँक्ति क' संबंधमे बाजैत अछि" - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "मोजुदा समतल रिव्यू पँक्ति क' संबंधमे बाजैत अछि" - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "अगिला मद अथवा शब्दमे फ्लैट रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "मोजुदा शब्द क' उप्पर समतल रिव्यू लए जाउ." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "मोजुदा समतल रिव्यू क' संबंधमे बाजू" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "मोजुदा शब्द क' नीच्चाँमे समतल रिव्यू लए जाउ." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "पछिला संप्रतीकमे समतल रिव्यू लए जाउ." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "मोजुदा समतल रिव्यू संप्रतीक क' संबंधमे बाजू." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "मोजुदा समतल रिव्यू संप्रतीक क' संबंधमे बाजू." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "मोजुदा समतल रिव्यू संप्रतीक क' संबंधमे बाजू." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "अगिला संप्रतीकमे समतल रिव्यू लए जाउ" - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "पँक्ति क' अंतमे फ्लैट रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "नीच्चाँ बामाँ तरफ फ्लैट समीक्षा घसकाबू" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "अंत स्थितिमे समतल रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "टॉगल करैत अछि जे की सिर्फ मोजुदा सारणी सेल अथवा सौंसे पंक्तिकेँ पढ़नाइ अछि" - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "मोजुदा पाठ संप्रतीक क' सँग जुटल गुण पढ़ू" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "बामाँ तरफ ब्रेल डिस्प्ले पैन करैत अछि." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "दहिन्ना तरफ ब्रेल डिस्प्ले पैन करैत अछि." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "कीबोर्ड फोकस क' सँग वस्तु घुराबू." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "अगिला पँक्ति क' शुरूमे समतल रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "सीखनाइ मोड दिअ'. सीखनाइ मोड सँ बाहर निकलब क' लेल escape दाबू." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "स्पीच दर घटबैत अछि." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "स्पीच दर बढ़बैत अछि." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "स्पीच पिच घटबैत अछि." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "भाषण पिच बढबैत अछि." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "स्पीच दर बढ़बैत अछि." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "स्पीच दर घटबैत अछि." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "इच्छित भाषण सर्वर चुनू." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "इच्छित भाषण सर्वर चुनू." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "स्पीच दर घटबैत अछि." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "स्पीच दर बढ़बैत अछि." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "भाषण क' मौनीकरण टॉगल करू " - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "वरीयता विन्यास समाद प्रदर्शित करैत अछि." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "वरीयता विन्यास समाद प्रदर्शित करैत अछि." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "हाशिया आ संरेखण बाजू (_i)" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "भाषण संश्लेषक (_z):" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "रन टाइम पर डिबग स्तर चक्रीय करैत अछि" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "पछिला चैट रूम संदेश क' संबंधमे बाजू आ ब्रेल करू " - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "टॉगल करू जे की हमरा चैट रूम संदेशकेँ चैट रूम क' नाम सँ उपसर्ग कएनाइ अछि." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "टॉगल करू जे की हमरा चैट रूम संदेशकेँ चैट रूम क' नाम सँ उपसर्ग कएनाइ अछि." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "पँक्ति बामाँ" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "पँक्ति दहिन्ना" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "पँक्ति उप्पर" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "पँक्ति नीच्चाँ" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "उप्पर बामाँ" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "नीच्चाँ दहिन्ना" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "कर्सर स्थिति" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "कर्सर स्थिति" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "पंक्ति" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "अगिला संप्रतीकमे समतल रिव्यू लए जाउ" - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "पछिला संप्रतीकमे समतल रिव्यू लए जाउ." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "अगिला पँक्ति क' शुरूमे समतल रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "पँक्ति क' अंतमे फ्लैट रिव्यू घसकाबैत अछि." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "" -"गतिशील कॉलम हेडर क' रूपमे प्रयोग क' लेल पँक्ति सेट करू जखन कैल्क सेल बाजल जाए रहल हुए." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "गतिशील कॉलम हेडर साफ कएलक." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"गतिशील पँक्ति हेडर क' रूपमे प्रयोग क' लेल कॉलम सेट करू ओए समय प्रयोग क' लेल जखन कैल्क सेल " -"बाजल जाए रहल हुए." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "गतिशील पँक्ति हेडर साफ कएलक." - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "इनपुट फाइल क' सामग्री क' संबंधमे बतबैत अछि." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "निर्देशिका बटन" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "टॉगल बटन" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "बेसी विकल्प प्रदर्शित करू " - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "जाँच पेटी" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "कॉम्बो बक्सा" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l समाहितकर्ता" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l समाहितकर्ता" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "कोनो शीर्ष नहि" - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "कोनो शीर्ष नहि" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "बेसी विकल्प प्रदर्शित करू " - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "सूची मद" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "कीबोर्ड फोकस क' सँग वस्तु घुराबू." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "कीबोर्ड फोकस क' सँग वस्तु घुराबू." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "पैराग्राफ" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "रेडियो बटन" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "रेडियो बटन" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "विभाजक" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "ट्री-तालिका" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "ट्री-तालिका" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "सेलमे घसकाबू" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "सेलमे घसकाबू" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "सेलमे घसकाबू" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "टॉगल बटन" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "कुँजी इको सक्षम करू (_k)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "ग्रे" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "हरिअर (_G):" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "दहिन्ना ब्रेस" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "दहिन्ना कंट्रोल" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "दहिन्ना पैरन" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "दहिन्ना ब्रेस" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "दहिन्ना पैरन" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "दहिन्ना पैरन" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "दहिन्ना आल्ट" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "दहिन्ना पैरन" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "न्यूलाइन" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "चित्र" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "अंत" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "टैब" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "खाली स्थान" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "खाली स्थान" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "पूर्ण स्क्रीन" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "चिह्न" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "किछु नहि" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "शब्द सँ इको सक्रिय करू (_w)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "क्रिया कुँजी सक्रिय करू (_t)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "वर्तमान स्थान (_u)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "विराम चिह्न" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "कुँजी बाइंडिंग" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "मूलभूत" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "सीखब मोड सँ निकलि रहल अछि." - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "खंड" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ब्रेल बाइंडिंग" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "रूपांतरित" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "डेस्कटॉप (_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "कैप्शन" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "सभ (_A)" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "विंडो" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "किछु नहि (_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "किछु (_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "सर्वाधिक (_o)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "पंक्ति" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "उद्धरण" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "बटन" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "अनुशीर्षक" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "जाँच पेटी" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "कॉम्बो बक्सा" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "कैप्शन" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "शीर्षक" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "चित्र" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "लेबल" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "लिंक" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "सूची" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "सूची मद" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "अनुच्छेद" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "रेडियो बटन" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "चयनित" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "स्थिति" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "पाठ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "उद्धरण" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "बटन" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "जाँच पेटी" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "कॉम्बो बक्सा" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "शीर्षक" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "चित्र" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "लिंक" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "सूची" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "सूची मद" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "अनुच्छेद" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "रेडियो बटन" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "सारणी" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "मूलभूत" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "हाइपरलिंक" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "पैघ अक्षर" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "मोजुदा सेल क' संबंधमे बाजू (_c)" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "संक्षिप्त (_f)" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt_R" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "बामाँ कँट्रोल" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "बामाँ शिफ्ट" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "बामाँ आल्ट" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "बामाँ कँट्रोल" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "दहिन्ना शिफ्ट" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "दहिन्ना आल्ट" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "दहिन्ना कंट्रोल" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "बामाँमेटा" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "दहिन्ना मेटा" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "न्यूम लॉक" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "कैप्स लॉक" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "कैप्स लॉक" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "पृष्ठ उप्पर" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "पृष्ठ नीच्चाँ" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "बैकस्पेस" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "एंटर" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "उप्पर" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "नीच्चाँ" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "बायाँ" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "दायाँ" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "मेनू" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "मदद" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "एस्केप" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "मेटाबू" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "घर" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "अंत" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "वर्णलोप क' चिह्न" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "ऋण" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "कैप्स बन्न करू (_L)" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "सुपर" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "गाढ़ा" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "कार्यस्थान" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "बामाँ पैरन" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "तीर" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "दहिन्ना पैरन" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "तीर" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "दहिन्ना कंट्रोल" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "ऋण" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "डॉट" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "स्वतः-पूर्ण" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "खाली" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "जोड़" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "ऋण" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "विभाजक" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "आनुपातिक" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "दहिन्ना आल्ट" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "स्तरित फलक" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "विभाजक" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "खंड" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "आनुपातिक" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "ऋण" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "टिल्डे" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "टिल्डे" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "टिल्डे" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "बराबर" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "बराबर" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "बराबर" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "नहि दबाओल गेल " - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "बराबर" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "दहिन्ना मेटा" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "left tab" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "नीच्चाँ" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "खंड" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "नहि दबाओल गेल " - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "छवि" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "दहिन्ना आल्ट" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "दहिन्ना ब्रेस" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "विभाजक" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "बामाँ पैरन" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "दहिन्ना पैरन" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "बामाँ आल्ट" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "दहिन्ना आल्ट" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "बामाँ ब्रेस" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "बामाँ ब्रेस" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "बामाँ कोष्ठ" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "दहिन्ना कोष्ठ" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "खाली स्थान" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "खाली स्थान" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "खाली स्थान" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "रेखांकित करू" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "खाली" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "गाढ़ा" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "कोनो फाइल नहि पाओल गेल." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "स्ट्रिंग नहि भेटल" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "चिह्न" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "चयनित" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "चयनित" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "https://groups.io/g/stormuxमे बग रिपोर्ट करू ." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "तेज." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "चैट रूम नाम क' संबंधमे नहि बाजू." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "चैट रूम नाम क' संबंधमे बाजू" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "मेटाबू" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "खंड" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "प्रश्न" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "h t m l समाहितकर्ता" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "h t m l समाहितकर्ता" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "नहि चयनित" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "स्ट्रिंग नहि भेटल" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "पूर्ण दस्ताबेज चयनित" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "पूर्ण दस्ताबेज चयनित" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "कर्सर स्थिति सँ दस्ताबेज चयनित" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "कर्सर स्थिति सँ दस्ताबेज चयनित" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "गतिशील कॉलम हेडर साफ कएलक." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "कॉलम %s क' लेल गतिशील पँक्ति हेडर साफ कएलक." - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "गतिशील पँक्ति हेडर साफ कएलक." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "खाली" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "कोनो फाइल नहि पाओल गेल." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "समतल रिव्यू मोड प्रविष्ट करैत आ बाहर निकलैत अछि." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "मोजुदा शब्द क' उप्पर समतल रिव्यू लए जाउ." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "समाद" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "पॉपअप मेनू " - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "कुँजी कैप्चर्ड: %s. पुष्टि क' लेल enter दाबू." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "नवीन कुँजी अछि %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "नवीन कुँजी दाखिल करू " - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "किछु नहि" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "केंद्रित" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "कूटशब्द" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "आओर" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "रूट फलक" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "रूट फलक" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "रूट फलक" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "रेखांकित करू" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "तालिका" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "ट्री-तालिका" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "अभिगम्य" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "सारणी" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "हाशिया आ संरेखण बाजू (_i)" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "सारणी" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "हाशिया आ संरेखण बाजू (_i)" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "सीखब मोड. निकलबाक लेल एस्केप दाबू." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "एनीमेशन" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "कर्सर स्थिति सँ नीच्चाँ पँक्ति चयनित" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "कर्सर स्थिति सँ पँक्ति चयनित" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "सीखब मोड सँ निकलि रहल अछि." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "लिंक " - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "कोनो फाइल नहि पाओल गेल." - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "वर्तमान स्थान (_u)" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "पर" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "गलत वर्तनी बला शब्द:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "भाषण निष्क्रिय." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "भाषण सक्रिय करू ." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "बामाँ पैरन" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "कोनो फ़ोकस नहि" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "कोनो शीर्ष नहि" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "कोनो शीर्ष नहि" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "आन्तरिक रूपरेखा" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "कोनो शीर्ष नहि" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "कोनो शीर्ष नहि" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "कोनो शीर्ष नहि" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "नहि चयनित" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "कैप्शन" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "नीच्चाँ (_B):" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "उप्पर (_T):" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "कूटशब्द" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "पर" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "कर्सर स्थिति सँ पृष्ठ चयनित" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "कर्सर स्थिति सँ पृष्ठ चयनित" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "कर्सर स्थिति सँ पृष्ठ चयनित" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "कर्सर स्थिति सँ पृष्ठ चयनित" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "कर्सर स्थिति सँ पृष्ठ चयनित" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "कर्सर स्थिति सँ पृष्ठ चयनित" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "कोनो फाइल नहि पाओल गेल." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "सभ (_A)" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "विराम स्तर" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "किछु नहि" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "खोजि रहल अछि." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "खोज पूर्ण भेल." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu प्रयोक्ता जमावट फिनु लोड कएल गेल." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "इच्छित आवाज चुनू:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "नहि चयनित" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "भाषण निष्क्रिय." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "भाषण सक्रिय करू ." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "तेज." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "धीमा." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "उच्चतर." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "निचुलका." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "तेज." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "दरः (_R)" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "आयतन (_l):" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "कोनो सर्वर उपलब्ध नहि.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "कोनो ध्वनि उपलब्ध नहि.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "भाषण सक्रिय करू ." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "भाषण प्रयुक्त नहि हएताह \n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Cthulhu वरीयतासभ " - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "भाषण अछि अनुपलब्ध." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "कोनो फाइल नहि पाओल गेल." - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "स्ट्रिंग नहि भेटल" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "स्ट्रिंग नहि भेटल" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "कोनो फाइल नहि पाओल गेल." - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "कॉलम हेडर" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "कॉलम %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "नहि चयनित" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "नहि चयनित" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "पँक्ति %d" - -#: src/cthulhu/messages.py:2462 -#, fuzzy, python-format -msgid "row %(index)d of %(total)d" -msgstr "%d पँक्ति %d क'" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "मेटाबू" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "पँक्ति क' अंतमे फ्लैट रिव्यू घसकाबैत अछि." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "नहि चयनित" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "नहि चयनित" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu वरीयतासभ " - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "खाली स्थान" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 मद" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "कॉलम %d" -msgstr[1] "कॉलम %d" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d बाइट" -msgstr[1] "%d बाइट" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d फाइल भेटल" -msgstr[1] "%d फाइल भेटल" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d फाइल भेटल" -msgstr[1] "%d फाइल भेटल" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "सारणी छोड़ि रहल अछि." -msgstr[1] "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "सारणी छोड़ि रहल अछि." -msgstr[1] "सारणी छोड़ि रहल अछि." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "%d पँक्ति आओर %d कॉलम क' सँग सारणी." -msgstr[1] "%d पँक्ति आओर %d कॉलम क' सँग सारणी." - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "पिक्सेल्स" -msgstr[1] "पिक्सेल्स" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "%d पँक्ति आओर %d कॉलम क' सँग सारणी." -msgstr[1] "%d पँक्ति आओर %d कॉलम क' सँग सारणी." - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%d पँक्ति आओर %d कॉलम क' सँग सारणी." -msgstr[1] "%d पँक्ति आओर %d कॉलम क' सँग सारणी." - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "%d पँक्ति आओर %d कॉलम क' सँग सारणी." -msgstr[1] "%d पँक्ति आओर %d कॉलम क' सँग सारणी." - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "सकेण्ड" -msgstr[1] "सकेण्ड" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ट्री स्तर %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "ट्री स्तर %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "प्रश्न" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "कॉम्बो बक्सा" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html सामग्री" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "कॉलन" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "खंड" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "पैराग्राफ" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "फंक्शन" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "टैब सूची" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "उद्धरण" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "html सामग्री" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "स्क्रॉल पट्टी" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "स्क्रॉल पट्टी" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "html सामग्री" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "एनीमेशन" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "html सामग्री" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "एनीमेशन" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "खोजि रहल अछि." - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "स्पिन बटन" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "गिरि गेल " - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "विस्तारित" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "जाँचल गेल " - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "नहि जाँचल गेल " - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "पर" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "नहि जाँचल गेल " - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "दबाओल गेल " - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "नहि दबाओल गेल " - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "नहि चयनित" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "नहि चयनित" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ग्रे" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "वर्तनी जाँचू " - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "खोजू" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "Cthulhu स्क्रीन पाठक आ आवर्द्धक" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "बन्न करू" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "खोजू" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "लेल खोजू (_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "एकरा लेल खोज:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "विंडो क' शीर्ष (_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "विंडो क' शीर्ष" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "एकरासँ आरंभ:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "चारोकात लपेटू (_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "पाछाँ सँ खोजू (_b)" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "एकरा लेल खोज:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "अक्षर मिलाबू (_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "केवल पूर्ण शब्द जोड़ मिलाबू (_e)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "विकल्प फलक" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "मूलभूत" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "पैघ अक्षर" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "हाइपरलिंक" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "विंडो" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu वरीयतासभ " - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "लैपटॉप (_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "कीबोर्ड लेआउट" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "एकरासँ आरंभ:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "ब्रेल बाइंडिंग" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "अनुप्रयोग" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "प्रगति पट्टी" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "सामान्य" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "आयतन (_l):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "पिच (_t):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "दरः (_R)" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "व्यक्ति (_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "भाषण संश्लेषक (_z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "भाषण सिस्टम (_s):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "ध्वनि जमावट (_V):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "ध्वनि जमावट (_V):" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "ध्वनि जमावट (_V):" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "सक्षम वाणी (_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "बर्बोस (_b)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "बर्बोसिटी" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "सभ (_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "विराम स्तर" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "खाली पँक्ति बाजू" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "हाशिया आ संरेखण बाजू (_i)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "खाली पँक्ति बाजू" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "भाषण" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "ब्रेल मॉनिटर सक्षम करू (_s)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "संक्षिप्तीकृत भूमिका नाम (_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "शब्द सँ इको सक्रिय करू (_w)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "बेसी विकल्प प्रदर्शित करू " - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "किछु नहि (_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "हाइपरलिंक" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "सक्षम आवर्धक (_m)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ब्रेल" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "कुँजी इको सक्षम करू (_k)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "क्रिया कुँजी सक्रिय करू (_t)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "रूपांतरक कुँजी सक्रिय करू (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "फंक्शन कुँजी सक्रिय करू (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "सक्षम वाणी (_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "रूपांतरक कुँजी सक्रिय करू (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "फंक्शन कुँजी सक्रिय करू (_f)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "क्रिया कुँजी सक्रिय करू (_t)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "शब्द सँ इको सक्रिय करू (_w)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "कुँजी इको" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Cthulhu रूपांतरक कुँजी (_M):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "क' बाइंडिंग" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "मेटाबू (_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "रिसेट करू (_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "ब्रेल बाइंडिंग" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "सहायक" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "सहायक" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "अंत" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "मापक कारक (_f):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:493 -#, fuzzy -msgctxt "textattr" -msgid "no justification" -msgstr "हाशिया आ संरेखण बाजू (_i)" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "वर्तनी जाँचू " - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/meson.build b/po/meson.build deleted file mode 100644 index 94bb642..0000000 --- a/po/meson.build +++ /dev/null @@ -1,6 +0,0 @@ -i18n.gettext('cthulhu', - args: [ - '--default-domain=cthulhu', - '--from-code=UTF-8', - ] -) \ No newline at end of file diff --git a/po/mk.po b/po/mk.po deleted file mode 100644 index 27a7b2e..0000000 --- a/po/mk.po +++ /dev/null @@ -1,9888 +0,0 @@ -# translation of cthulhu.HEAD.mk.po to Macedonian -# Copyright (C) 2007 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# -# Jovan Naumovski , 2006, 2007, 2008. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD.mk\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2011-12-26 22:45+0100\n" -"Last-Translator: Jovan N\n" -"Language-Team: Macedonian \n" -"Language: mk\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural= n==1 || n%10==1 ? 0 : 1\n" -"X-Generator: KBabel 1.11.4\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu читач на екранот" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "аним" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "стрл" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "кал" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "плтн" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "глв" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "пчк" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "изббј" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "загклн" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "кпо" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "дат" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "икн" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "рам" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "бирај" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "длг" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "мзд" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "црт" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "издттк" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "ппн" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "изфнт" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "форма" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "сткл" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "зглв" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "сл" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "врам" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "озн" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "спсс" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "врс" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "лст" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "прлст" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "мен" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "мнлент" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "пмн" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "пвроп" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "лтбл" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "пнл" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "лоз" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "скокмн" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "леннп" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "коп" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "радио" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "прдрдмн" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "гпвр" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "зрд" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "лздв" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "ппрдв" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "одд" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "разд" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "лиз" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "ппвр" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "вкоп" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "статл" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "тбл" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "ќел" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "опмн" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "терм" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "ткс" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "кмен" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "ленал" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "сов" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "дрв" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "тдрв" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "неп" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "глед" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "проз" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "загл" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "подн" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "пара" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "апл" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "автд" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "лзур" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "вкмп" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Чешки, степен 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Шпански, степен 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Канадски француски, степен 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Француски, степен 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Латвиски, степен 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Холандски, степен 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Норвешки, степен 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Норвешки, степен 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Норвешки, степен 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Норвешки, степен 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Полски, степен 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Португалски, степен 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Шведски, степен 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Арапски, степен 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Велшки, степен 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Велшки, степен 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Германски, степен 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Германски, степен 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Германски, степен 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Британски англиски, степен 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Британски англиски, степен 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Англиски (САД), степен 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Англиски (САД), степен 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Канадски француски, степен 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Француски, степен 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Грчки, степен 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Хинди, степен 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -#, fuzzy -msgid "Hungarian Grade 1" -msgstr "Латвиски, степен 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "Германски, степен 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Италијански, степен 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Белгиски холандски, степен 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "простор" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "нова линија" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "табулатор" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "извичник" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "наводник" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "број" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "долар" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "процент" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "амперсанд" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "апостроф" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "лева голема заграда" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "десна голема заграда" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "ѕвездичка" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "плус" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "запирка" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "црта" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "точка" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "коса црта" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "две точки" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "точка-запирка" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "помало од" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "еднакво" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "поголемо од" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "прашалник" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "ет" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "лева средна заграда" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "коса црта" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "десна средна заграда" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "каре" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "подвлечено" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "цртичка" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "лева мала заграда" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "вертикална црта" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "десна мала заграда" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "тилда" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "неразделив простор" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "обратен извичник" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "центи" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "фунти" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "знак за валута" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "јен" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "прекината црта" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "оддел" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "дијареза" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "авторски права" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "а во горен индекс" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "лева средна аглеста заграда" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "логичко не" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "а со капа" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "регистрирано" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "макрон" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "степени" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "плус или минус" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "2 во горен индекс" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "3 во горен индекс" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "со акутен акцент" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "ми" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "ознака за параграф" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "средна точка" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "цедила" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 во горен индекс" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "реден број" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "десна средна аглеста заграда" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "една четвртина" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "една половина" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "три четвртини" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "превртен прашалник" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "а со акутен акцент" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "А СО АПОСТРОФ" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "А СО АКУТЕН АКЦЕНТ" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "А СО КАПА" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "А СО ТИЛДА" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "А УМЛАУТ" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "А СО КРУГЧЕ" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C ЦЕДИЛА" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "Е СО ЦРТИЧКА" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "Е СО АКУТЕН АКЦЕНТ" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "Е СО КАПА" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "Е УМЛАУТ" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I СО ЦРТИЧКА" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I СО АКУТЕН АКЦЕНТ" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I СО КАПА" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I УМЛАУТ" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ЕД" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "Н ТИЛДА" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "О СО ЦРТА" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "О СО АКУТЕН АКЦЕНТ" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "О СО КАПА" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "О СО ТИЛДА" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "О УМЛАУТ" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "знак за множење" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "О ПРЕЦРТАНО" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "У СО ЦРТИЧКА" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "У СО АКУТЕН АКЦЕНТ" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "У СО КАПА" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "У УМЛАУТ" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y СО АКУТЕН АКЦЕНТ" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "ТОРН" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "остро s" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "цртичка" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a со капа" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "тилда" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "а умлаут" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "кругче" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c цедила" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e со цртичка" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "е со акутен акцент" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "е со капа" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "е умлаут" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i со цртичка" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "и со акутен акцент" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "и со капа" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "и умлаут" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "ед" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n со тилда" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o со цртичка" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o со акутен акцент" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "о со капа" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o со тилда" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "о умлаут" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "поделено со" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "о прецртано" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "торн" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u со акуен акцент" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u со цртичка" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u со капа" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u умлаут" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y со акутен акцент" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y умлаут" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y УМЛАУТ" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "флорин" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "n црта" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "еден лев наводник" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "еден десен наводник" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "еден долен наводник" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "двоен лев наводник" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "десен двоен наводник" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "двоен долен наводник" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "обелос" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "двоен обелос" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "копче" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "тројна точка" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "на милја" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "прост" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "двоен прост" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "двоен прост" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "точка-цртичка" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "евро" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "заштитен знак" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "ознака за чекирање" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "јака ознака за чекирање" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x точка за набројување" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "0 во горен индекс" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "4 во горен индекс" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "5 во горен индекс" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "6 во горен индекс" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "7 во горен индекс" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "8 во горен индекс" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "9 во горен индекс" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "плус во горен индекс" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "минус во горен индекс" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "еднакво во горен индекс" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "лева средна заграда во горен индекс" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "десна средна заграда во горен индекс" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n во горен индекс" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "0 во долен индекс" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "1 во долен индекс" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "2 во долен индекс" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "3 во долен индекс" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "4 во долен индекс" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "5 во долен индекс" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "6 во долен индекс" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "7 во долен индекс" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "8 во долен индекс" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "9 во долен индекс" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "плус во долен индекс" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "минус во долен индекс" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "еднакво во долен индекс" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "лева средна заграда во долен индекс" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "десн средна заграда во долен индекс" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "црн квадрат" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "црн дијамант" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "Оди до следниот знак" - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "Ја насочува стрелката кон тековниот предмет" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "Извршува лев клик на тековниот предмет од прегледот со рамнини." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "Извршува десен клик на тековниот предмет од прегледот со рамнини." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Го изговара целиот документ." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "Ја изговара тековната линија на рамниот преглед." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "Ја извршува „каде сум“ операцијата." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "Ја извршува деталната „каде сум“ операција." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Ја изговара тековната линија на рамниот преглед." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "Изговарај ги празните линии" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "Оди на следното копче." - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "Ја изговара статусната лента." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "Ја изговара насловната лента." - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Го отвора дијалог прозорецот за барање на Cthulhu." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "Бара претходен пример од низата." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "Го бара претходниот примерок на знаковна низа." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "Влегува и излегува од режим на рамен преглед." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "Го поместува рамниот преглед до крајната позиција." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "Го поместува рамниот преглед до почетната позиција." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "Го поместува рамниот преглед до крајната позиција." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "Го поместува рамниот преглед до почетокот на претходната линија" - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "Ја изговара тековната линија на рамниот преглед." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "Ја изговара тековната линија на рамниот преглед." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "Ја изговара тековната линија на рамниот преглед." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "Го поместува рамниот преглед до почетокот на следната линија." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "Го поместува рамниот преглед до претходниот предмет или збор." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "Го изговара тековниот предмет или збор на рамниот преглед." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "Го изговара тековниот предмет или збор на рамниот преглед." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "Го изговара тековниот предмет или збор на рамниот преглед." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "Го поместува рамниот преглед до следниот збор или предмет." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "Го поместува рамниот преглед до над тековниот збор." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "Го изговара тековниот предмет од рамниот преглед." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "Го поместува рамниот преглед под тековниот збор." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "Го поместува рамниот преглед до претходниот знак.7" - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "Го изговара тековниот знак од рамниот преглед." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "Го изговара тековниот знак." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "Ја изговара уникод вредноста на тековниот знак на рамниот преглед." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "Го поместува рамниот преглед до следниот знак." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "Го поместува рамниот преглед до крајот на линијата." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "Го поместува рамниот преглед лево на дното." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "Го изговара тековниот предмет или збор на рамниот преглед." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "Го изговара тековниот предмет или збор на рамниот преглед." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "Го поместува рамниот преглед до крајната позиција." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Менува дали ќе се чита само тековната ќелија од табелата или целиот ред." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "Ги чита атрибутите назначени за тековниот текстуален знак." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "Го поместува брајовиот екран кон лево." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "Го поместува брајовиот екран кон десно." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "Го враќа на предметот со фокус на тастатурата." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "Го исклучува/исклучува скратениот брајов приказ." - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "Го обработува копчето за насочување на стрелка." - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "Го означува почетокот на изборот на текст." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "Го означува крајот на изборот на текст." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Влегува во режим на учење. Притиснете escape за да излезете од режимот на " -"учење." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "Го намалува интензитетот на говор." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "Го намалува интензитетот на говор." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "Ја намалува висината на говорот." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "Ја зголемува висината на говорот." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Го намалува интензитетот на говор." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Го намалува интензитетот на говор." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Одберете го посакуваниот сервер за говор." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Одберете го посакуваниот сервер за говор." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "Го намалува интензитетот на говор." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "Го намалува интензитетот на говор." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "Го активира замолчувањето на гласот." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "Пушта/исклучува режим на преглед на глушецот." - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Cthulhu читач на екранот" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "Ги прикажува преференциите на конфигурациониот дијалог." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "Ги прикажува преференциите на конфигурациониот дијалог." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "Го пушта/исклучува изговарањето на поместувањето и подредувањето." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "Се менува на следното ниво на изговарање на интерпункциски знаци." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "Се менува на следното ниво на ехо копчиња." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "Се менува на следното ниво на изговарање на интерпункциски знаци." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "Се менува на следното ниво на изговарање на интерпункциски знаци." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "Се менува на следното ниво на ехо копчиња." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "Кружи низ нивоата на дебагирање при извршување." - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "Обележи каде сум во однос на тековната позиција." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "Оди до локацијата на претходниот обележувач." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "Оди на обележувачот." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "Оди до локацијата на следниот обележувач." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "Додај обележувач." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "Зачувај ги обележувачите." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "Пушта/исклучува режим на преглед на глушецот." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "Прикажи го моменталното време." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "Прикажи го тековниот датум." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "Ја проследува следната команда на тековната апликација." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "" -"Изговори ја и прикажи ја на брајов монитор претходната порака од собата за " -"разговор." - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Исклучи/вклучи најава за тоа дека некој пријател пишува" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Исклучи/вклучи овозможување на истории за пораки од дадени соби" - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Смени дали името на собата се става како префикс на пораките од собата за " -"разговор." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Линија лево" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Линија десно" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Линија горе" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Линија долу" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Замрзни" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Горе-лево" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "Долна половина" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Позиција на стрелката" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Шест точки" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Насочување на стрелка" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Почнување на копирање" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Копирање на линија" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "Прикажи ја последната порака за известување." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Прикажи режим со листа на пораки за известување." - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "Прикажи ја претходната порака за известување." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "Прикажи ја последната порака за известување." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Оди до следниот знак" - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "Оди до претходниот знак" - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "Оди до следниот збор." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "Оди до претходниот збор." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "Оди до следната линија." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "Оди до претходната линија." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "Оди врвот на датотеката." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "Оди до дното на датотеката." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Оди на почетокот на линијата." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "Оди на крајот на линијата." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "Оди до следниот објект." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "Оди до претходниот објект." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "Предизвикува проширување на комбинираното поле." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "Switches between Gecko native and Cthulhu caret navigation." - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "Напредно поставување на учтивоста на живиот регион." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "Исклучи го стандардното ниво на учтивост на живиот регион." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "Обнови ја најавата за живи региони." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "Надгледувај ги живите региони." - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "" -"Го носи фокусот во и надвор од тековниот предмет над кој се наоѓа стрелката." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "" -"Постави го редот за користење како динамички заглавија на колоните при " -"изговарање на ќелиите на табеларната пресметка." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "Ги чисти динамичките заглавја на колоните." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"Постави ја колоната за користење како динамички заглавија на редовите при " -"изговарање на ќелиите на табеларната пресметка." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "Ги чисти динамичните заглавја на редовите" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Ја изговара содржината во линијата за влезни податоци." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "Ги вклучува структурните навигациски копчиња." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "Оди до претходниот блок." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "Оди до следниот блок." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "Оди на претходното копче." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "Оди на следното копче." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Прикажи повеќе опции" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Оди на претходното поле за чекирање." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Оди на следното поле за чекирање." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "Оди до претходната табела." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "Оди до следната табела." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "Оди на претходното комбо поле." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Оди на следното комбо поле." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l контејнер" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l контејнер" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "Оди до претходниот запис." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "Оди до следниот запис." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "Оди до претходното поле во формата." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "Оди до следното поле во формата." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "Оди до претходното заглавије." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "Оди до следното заглавије." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Оди до предходното заглавје на нивото %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Оди до следното заглавје на нивото %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Нема повеќе заглавија на нивото %d." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "Оди до претходната табела." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "внатрешна рамка" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "Оди до претходната линија." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "Оди до следната линија." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "Оди до претходното обележје." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "Оди до следното обележје." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Оди до претходниот голем објект." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Оди до следниот голем објект." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Нема повеќе големи објекти." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "Оди до претходната линија." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "Оди до следната линија." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Прикажи повеќе опции" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "Оди до претходната листа." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "Оди до следната листа." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Оди до претходниот предмет од листата." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Оди до следниот предмет на листата." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "Оди до претходниот жив регион." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "Оди до следниот жив регион." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "Оди до последниот жив регион кој даде најава." - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "Печати информации за дебагирање за потеклото на објектот во фокус." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "Го враќа на предметот со фокус на тастатурата." - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "Ги вклучува структурните навигациски копчиња." - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "Оди до претходниот параграф." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "Оди до следниот параграф." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Оди до следното кружно копче." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "Оди до претходното кружно копче." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "Нема повеќе кружни копчиња." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "Оди до претходниот разделник." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "Оди до следниот разделник." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "Оди до претходната табела." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "Оди до следната табела." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "Оди една ќелија подолу." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "Оди до првата ќелија во табелата." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "Оди до последната ќелија во табелата." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "Оди лево за една ќелија." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "Оди десно за една ќелија." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "Оди горе за една ќелија." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "Пушта/исклучува режим на преглед на глушецот." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Активирај ехо на _копчињата" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "Оди до претходната непосетена врска." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "Оди до следната непосетена врска." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "Нема повеќе непосетени врски." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "Оди до претходната посетена врска." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "Оди до следната посетена врска" - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "Нема повеќе посетени врски." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "Сатурирана сина" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "црно" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "црн дијамант" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "Сатурирана сина" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "Сатурирана сина" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "цртичка" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "Сатурирана зелена" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "Сатурирана зелена" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "Сатурирана црвена" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "Сатурирана зелена" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "Сатурирана сина" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i со цртичка" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "Десатурирана зелена" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "засивено" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "степени" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "Хинди, степен 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "десна мала заграда" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "десна контрола" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "десна голема заграда" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "десна мала заграда" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "десна голема заграда" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "десна голема заграда" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "десен alt" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "десна голема заграда" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "десен супер" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "десна стрелка" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "нова линија" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Слика" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "Десатурирана сина" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "Сатурирана црвена" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "Сатурирана зелена" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "end" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "Сатурирана сина" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s екран" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "Десатурирана сина" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "Десатурирана сина" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "табулатор" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "празен простор" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "празен простор" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "На цел екран" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "_7 точки" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "_8 точки" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Dots 7 an_d 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Икона" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Најниско" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "Проверка на правопис:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Најава кога Вашите _пријатели пишуваат" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Овозможи истории за одредени _пораки од соби за разговор" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Прочитај ги пораките од" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Сите кан_али" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Сите канали кога би_ло кој прозорец од %s е активен" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Канал, само ако неговиот _прозорец е активен" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Изговори го името на собата за разговор" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "двоен клик" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "троен клик" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Стандарден синтисајзер" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Вистинската низа" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Низа за замена" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Овозможи ехо _знак по знак" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Овозможи најава на „мртви“ копчиња" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Т_ековна локација" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Минимална должина на совпаднатиот текст:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Опции за барање" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Избовори ги _само променетите линии при барање" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Изговори ги резултатите при _барање" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "запирка" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Поврзување на копче" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "Стандардно" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Излегува од режимот на учење." - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "оддел" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Брајови поврзувања" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "обележувачите се зачувани" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "Навигација на табели" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Неповрзано" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "Оставам рамен преглед." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "Изменето" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Работна површина" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Известување" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Известување %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Преференции за Cthulhu за %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Означи во брајова азбука" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Присутно, освен" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Зборува" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Зачувај го профилот како конфликт" - -#: src/cthulhu/guilabels.py:429 -#, fuzzy -msgid "User Profile Conflict!" -msgstr "Конфликт на профилот на корисникот!" - -#: src/cthulhu/guilabels.py:436 -#, fuzzy, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Профилот %s веќе постои.\n" -"Да продолжам со ажурирање на постоечкиот профил со овие нови промени?" - -#: src/cthulhu/guilabels.py:446 -#, fuzzy -msgid "Load user profile" -msgstr "Вчитај кориснички профил" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Ќе го смените профилот кој веќе е активен. Ако\n" -"имате направено промени во Вашите преференци, тие нема\n" -"да се зачуваат при вчитување на профилот.\n" -"\n" -"Да продолжам со вчитување на профилот без да ги зачувам промените?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Зачувај го профилот како" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Име на _профил:" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "Вчитај кориснички профил" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Сите" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Апликациј" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Прозорец" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Ништо" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Не_кои" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "П_овеќето" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Линија" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Реченица" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "наводник" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Копче" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "Глава" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "ПолеЗаЧекирање" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "комбинирано поле" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "n во горен индекс" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Заглавие" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Внатрешна рамка" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Слика" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Ознака" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "заштитен знак" - -#: src/cthulhu/guilabels.py:611 -#, fuzzy -msgctxt "structural navigation" -msgid "Level" -msgstr "ниво %d" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "Врска" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "Листа" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ПредметОдЛиста" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Параграф" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "РадиоКопче" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "избрано" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "Статус" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Текст" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Нема повеќе парчиња." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Копче" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "ПолеЗаЧекирање" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "комбинирано поле" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "Заглавие" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Внатрешна рамка" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Слика" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Нема повеќе заглавија на нивото %d." - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "заштитен знак" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Нема повеќе големи објекти." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "Врска" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "Листа" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ПредметОдЛиста" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Параграф" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "РадиоКопче" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Табела" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d непосетена врска" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d посетена врска" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Навигација на страницата" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Автоматски започни да ја читаш страницата кога е за прв пат _вчитана" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "Автоматски започни да ја читаш страницата кога е за прв пат _вчитана" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Раздели го говорот на пар_чиња помеѓу паузите" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s стандарден глас" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Стандардно" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Хиперврска" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Систем" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Големи букви" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Диспачер за говор" - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Проверка на правопис:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "Изговори ги координатите на табеларната пресметка" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Најави го _заглавието на ќелиите" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Навигација на табели" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Прескокни ги _празните ќелии" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Изговори ја _ќелијата" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Изговори ги координатите на _ќелијата" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Изговори _повеќе опсези на ќелии" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Име на атрибут" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "Користи ја навигацијата со каре на _Cthulhu" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "Ги вклучува структурните навигациски копчиња." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Кратк_о" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Известување" -msgstr[1] "Известување" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "лев shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "лев alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "лева контрола" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "десен shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "десен alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "десна контрола" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "лев alt" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "десен alt" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "заклучено движење" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "страница погоре" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "страница подолу" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "лев табулатор" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "ентер" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "ентер" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "горе" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "надолу" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "лево" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "десно" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "лев супер" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "десен супер" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "мени" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "помош" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "мулти" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "менувач на режим" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "почеток" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "со капа" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "кругче" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "прецртано" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "минус" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Супер" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "задебелено" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "закосено" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr " %s во долен индекс" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr " %s во долен индекс" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Работен простор " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "Содржината е %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "лева стрелка" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "стрелка" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "десна стрелка" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "стрелка" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "десна стрелка" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "десна стрелка" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "десна стрелка" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "лева стрелка" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "лева стрелка" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "десна стрелка" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "двоен лев наводник" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "двоен обелос" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "десен двоен наводник" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "двоен обелос" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "десен двоен наводник" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "стрелка насочена надесно" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "стрелка што покажува надесно" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "минус" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "помало од" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "поголемо од" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "со капа" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "точка" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "вертикално порамнување" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "хоризонтално" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "автоматско довршување" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "празно" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "Овозможено" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "Крај на ред." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "индекс" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "плус или минус" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "плус" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "минус" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "разделувач" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "кубен корен" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "Пропорционално" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "бесконечност" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "десен alt" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "единечно" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "стаклена повшина со слоеви" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "вертикално порамнување" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "поделено со" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Разделувач" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "не е еднакво со" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "логичко не" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "логичко не" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "насока" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "внатрешна рамка" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "двоен прост" - -#: src/cthulhu/mathsymbols.py:1512 -#, fuzzy -msgctxt "math symbol" -msgid "triple integral" -msgstr "Интервал на ажурирање:" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -#, fuzzy -msgctxt "math symbol" -msgid "surface integral" -msgstr "Интервал на ажурирање:" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "Пропорционално" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "минус" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "тилда" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n со тилда" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n со тилда" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "скоро еднакво со" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "скоро еднакво со" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "скоро еднакво со" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "скоро еднакво со" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "скоро еднакво со" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "скоро еднакво со" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "троен клик" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "скоро еднакво со" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "различно место" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "не е еднакво со" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "еднакво" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "еднакво" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "не е еднакво со" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "не е еднакво со" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "тројна точка" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "еднакво" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "не е еднакво со" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "не е еднакво со" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "вертикално" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "не е еднакво со" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "не е еднакво со" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "поголемо од" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "не е притиснато" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr " не е избрано" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "0 во долен индекс" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "а во горен индекс" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "со повеќе избирања" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "подредување" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "со повеќе избирања" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "еднакво во долен индекс" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "n црта" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "плус во долен индекс" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "минус во долен индекс" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "десен alt" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "лев табулатор" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "надолу" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "оддел" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "реден број" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "слика" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "мулти" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "внатрешна рамка" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "нормално" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "еден десен наводник" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "десна мала заграда" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "разделувач" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "логичко не" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "логичко не" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "двоен прост" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "двоен прост" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "насока" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "двоен прост" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "помалоили еднакво на" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "поголемо или еднакво на" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "вертикално порамнување" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "лева голема заграда" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "десна голема заграда" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "лев alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "десен alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "лева мала заграда" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "дно" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "лева средна аглеста заграда" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "десна средна аглеста заграда" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "средна точка" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "квадратен корен" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "црн квадрат" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "бел квадрат" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "црн дијамант" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "бел круг" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "црн круг" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "бело копче" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "црн квадрат" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "подвлечено" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "вертикално порамнување" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "апликација" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "празно" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "задебелено" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "внесен е обележувач" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "обележувачите се зачувани" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "обележувачите не може да се зачуваат" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "Не е пронајдено обележје." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "Не е пронајдено обележје." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Режимот за премин е пуштен." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Не можев да го добијам приказот за калкулатор" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "икона" - -#: src/cthulhu/messages.py:117 -#, fuzzy -msgid "Capitalization style set to icon." -msgstr "Нивото на интерпункција е поставено на најниско." - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "ништо" - -#: src/cthulhu/messages.py:137 -#, fuzzy -msgid "Capitalization style set to none." -msgstr "Нивото на интерпункција е поставено на најниско." - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "правопис" - -#: src/cthulhu/messages.py:157 -#, fuzzy -msgid "Capitalization style set to spell." -msgstr "Нивото на интерпункција е поставено на највисоко." - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "Gecko го контролира карето." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu го контролира карето." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Ќелија %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "избрано" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr " не е избрано" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "не е избрано" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Спречи ја употребата на оваа опција" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Присили користење на опција" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -#, fuzzy -msgid "The following are not valid: " -msgstr "Следните аргументи не се валидни:" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Испечати ги познатите апликации кои се извршуваат" - -#: src/cthulhu/messages.py:237 -#, fuzzy -msgid "Load profile" -msgstr "Вчитај кориснички профил" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "обележувачите не може да се зачуваат" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Користи алтернативен диркеториум за корисничките преференции" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "Испечати ги познатите апликации кои се извршуваат" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "Замени ја Cthulhu која тековно се извршува" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "Покажи ја оваа порака со помош" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" -"Испрати излезни податоци за дебагирање во debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Испрати излезни податоци за во одредената датотека" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Постави ги преференциите на корисникот (текстуална верзија)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "Постави ги преференциите на корисникот (текстуална верзија)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Пријавете бубачки на https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "со акутен акцент" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "побрзо." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Не најавувај кога пријателите пишуваат." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "најава кога Вашите пријатели пишуваат" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Порака од собата за разговор %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Ново јазиче за разговор %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Не го изговарај името на собата за разговор." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "изговори го името на собата за разговор." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Не овозможувај истории од соби за разговор за одредени пораки." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Овозможи истории од соби за разговор за одредени пораки." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "delete" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "insert" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "прашалник" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "Крај на табелата" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "Не е во табела." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr " не е избрано" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Стандардното копче е %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Стандардното копче е %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "Стандардното копче е %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " %s во долен индекс" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " %s во горен индекс" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "Не е во табела." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "целиот документ е избран" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "целиот документ е избран" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "документ избран од позицијата на стрелката" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "поништен избор на документ од позицијата на стрелката" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "документ избран на позицијата на стрелката" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "поништен избор на документ до позицијата на стрелката" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Динамичко заглавие на редот поставен на редот %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Динамичкото заглавие на колоната е исчистено." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Динамичко заглавие на редот поставен на колона %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Динамичкото заглавие на редот е креирано." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "празно" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f килобајти" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f мегабајти" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Не се пронајдени датотеки." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "Влегувам во рамен преглед." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Влегувам во рамен преглед." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Оставам рамен преглед." - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "Го поместува рамниот преглед до над тековниот збор." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "има формула" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "дијалог" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "скокачко мени" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "врска кон слика со мапа" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Внесеното копче е веќе назначено за %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Добиено копче: %s. Притиснете ентер за да потврдите." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Новото копче е: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Кратекната е избришана. Притиснете за да потврдите." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Кратенката беше отстранета." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "внесете ново копче" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "коче" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "Поставено е ехо за копчето." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "ништо" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "Ехото за копчето е исклучено." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "копче или збор" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "Постави ехо на копче за за копче или збор." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "реченица" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "Постави ехо на копче за реченица." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "збор" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "Ехото е поставено на зборови." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "збор и реченица" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "Ехо на копчето е поставено за збор и реченица." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "црн круг" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "хоризонтално" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "вертикална црта" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "десна стрелка" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Постави на дното." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "висина на линија" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "амперсанд" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "подвлечено" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "квадратен корен" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "кубен корен" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "главна површина" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "главна површина" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "главна површина" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "0 во долен индекс" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "а во горен индекс" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "0 во долен индекс" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "а во горен индекс" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "а во горен индекс" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "а во горен индекс" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "табела" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "Табела на дрво" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "непристапно" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Оневозможено" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Изговарањето на поместувањето и подредувањето е исклучено." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Овозможено" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Изговарањето на поместувањето и подредувањето е активирано." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Режим на учење. Притиснете escape за излез." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "анимација" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Навигација на страницата" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Навигација на табели" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "Оставам рамен преглед." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "ја напуштам табелата." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "линија избрана долу од позицијата на стрелката" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "линија избрана горе од позицијата на стрелката" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "поништен избор на линија од позицијата на стрелката" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "поништен избор на линија до позицијата на стрелката" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Излегувам од режимот на учење." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "линија избрана од почетокот до претходната позиција на стрелката" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "линија избрана до крајот од претходната позиција на стрелката" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "врска" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "иста страница" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "исто место" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "различно место" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s врска до %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s врска" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d посетена врска" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Користете ги стрелките нагоре и надолу за навигација низ листата. Притиснете " -"на Escape за излез." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Сите живи региони се исклучени" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "нивоата на учтивост на живите региони се вратени" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "ниво на учтивост %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "го поставувам регионот на „самоуверен“" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "исклучување на живите региони" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "го поставувам регионот на „учтиво“" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "го поставувам регионот на „неучтиво“" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Надгледаувањето на живите региони е исклучено" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Надгледувањето на живите региони е приклучено" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "нема зачувани живи региони" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Поддршката за живи региони е исклучена" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Не е пронајдено" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Не можев да ја најдам тековната локација." - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "исклучено" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "приклучено" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "грешен правопис" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Зборови со грешен правопис: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Содржината е %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -#, fuzzy -msgid "Focus mode" -msgstr "Режим на листа на кратенки." - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -#, fuzzy -msgid "Layout mode." -msgstr "Режим на листа на кратенки." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Оди до следниот објект." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Не е пронајден објект над стрелката од глушецот." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Оневозможени се земените на глувчето." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Овозможена е замената на глувчето." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d процент." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "Оди до претходниот збор." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Вгнездено ниво %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Додаден е нов предмет" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Ниедна апликација нема фокус." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Нема фокус" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Ниедна апликација нема фокус." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Нема повеќе парчиња." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Нема повеќе копчиња." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Нема веќе полиња за чекирање." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Нема повеќе големи објекти." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Нема повеќе табели." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Нема веќе комбо полиња." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Нема повеќе записи." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Нема повеќе полиња за форми." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Нема повеќе заглавија." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Нема повеќе заглавија на нивото %d." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "внатрешна рамка" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "Нема повеќе табели." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Не е пронајдено обележје." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "Нема повеќе листи." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Нема повеќе листи." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Нема повеќе предмети од листи." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Нема повеќе живи региони." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Нема повеќе параграфи." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Нема повеќе кружни копчиња." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Нема веќе разделници." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Нема повеќе табели." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Нема повеќе непосетени врски." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Нема повеќе посетени врски." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "не е избрано" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "Не е во табела." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Известување" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Дно" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Врв" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Нема пораки за известување" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "збор" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "Изговори ги низите со мешани мали-големи букви како з_борови" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "исклучено" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "приклучено" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Вчитувам. Ве молам, почекајте." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Завршив со вчитување." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Завршив со вчитување на %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "страница избрана од позицијата на стрелката" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "страница избрана на позицијата на стрелката" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "поништен избор на страница од позицијата на стрелката" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "поништен избор на страница до позицијата на стрелката" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "параграф избран надолу од позицијата на стрелката" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "параграф избран над позицијата на стрелката" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "избор на параграф поништен надолу од позицијата на стрелката" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "избор на параграф поништен над позицијата на стрелката" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Веќе имате еден отворен дијалог од преференциите на Cthulhu.\n" -"\n" -"Затворете го пред да отворите нов." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "слајд %(position)d од %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "Не се пронајдени датотеки." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Лента на напредок %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Највисоко" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Нивото на интерпункција е поставено на највисоко." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Повеќето" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Нивото на интерпункција е поставено на највисоко." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Најниско" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Нивото на интерпункција е поставено на најниско." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Некои" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Нивото на интерпункција е поставено на средно." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Барам." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Пребарувањето е завршето." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Поставувањата на корисникот за Cthulhu се одново вчитани." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "Содржината е %s" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "Редот е избришан." - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Одберете го посакуваниот глас:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "не е избрано" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Говорот е исклучен." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Говорот е пуштен." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "побрзо." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "побавно." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "повисоко." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "пониско." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "побрзо." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Стапка:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Јачина на зв_ук:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Диспачер за говор" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Диспачер за говор" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Нема достапни сервери.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Нема достапни гласови.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Говорот е пуштен." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "Говорот нема да се употребува.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " три точки" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Преференции за Cthulhu" - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu го контролира карето." - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Режимот за премин е пуштен." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Говорот е недостапен." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Не е пронајдено" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "Фразата не е пронајдена" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "низата не е пронајдена" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Копчињата за структурна навигација се исклучени." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Копчињата за структурна навигација се вклучени." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Не е пронајдена" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Ред %(row)d, колона %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Крај на табелата" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Изговори ја ќелијата" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Изговори го редот" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Неуниформно" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Не е во табела." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ЗаглавиеНаКолона" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "колона %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "колона %(index)d од %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Дно на колона." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Врв на колона." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "не е избрано" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "не е избрано" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "ред %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "ред %(index)d од %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Почеток на ред." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Крај на ред." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Редот е избришан." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Избришан е последниот ред." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Вметнат е ред." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Вметнат е ред на крајот на табелата." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "Редот е избришан." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "не е избрано" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "избрано" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "не е избрано" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H часа, %M минути и %S секунди." - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H часа и %M минути." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Уникод %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Преференции за Cthulhu за %s" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "празен простор" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Постави на дното." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Постави на врвот." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 предмети" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Ќелијата се протега на %d ред" -msgstr[1] "Ќелијата се протега на %d редови" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d колона" -msgstr[1] "%d колони" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Ќелијата се протега на %d колона" -msgstr[1] "Ќелијата се протега на %d колони" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "е %d знак над дозволеното" -msgstr[1] "е %d знаци над дозволеното" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d дијалог)" -msgstr[1] "(%d дијалози)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d нефокусиран дијалог" -msgstr[1] "%d нефокусирани дијалози" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d бајт" -msgstr[1] "%d бајти" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "пронајдена е %d датотека" -msgstr[1] "пронајдени се %d датотеки" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d форма" -msgstr[1] "%d форми" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d заглавие" -msgstr[1] "%d заглавија" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d предмет" -msgstr[1] "%d предмети" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Не е пронајдено обележје." -msgstr[1] "Не е пронајдено обележје." - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "пронајдена е %d датотека" -msgstr[1] "пронајдени се %d датотеки" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Нема повеќе парчиња." -msgstr[1] "Нема повеќе парчиња." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Оставам рамен преглед." -msgstr[1] "Оставам рамен преглед." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Листа со %d предмет." -msgstr[1] "Листа со %d предмети." - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Листа со %d предмет." -msgstr[1] "Листа со %d предмети." - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "табела со %d ред" -msgstr[1] "табела со %d редови" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d колона" -msgstr[1] "%d колони" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "табела со %d ред" -msgstr[1] "табела со %d редови" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d порака.\n" -msgstr[1] "%d пораки.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d процент." -msgstr[1] "%d проценти." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "прочитани е %d процент од документот" -msgstr[1] "прочитани се %d проценти од документот" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "пиксели" -msgstr[1] "пиксели" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s знак" -msgstr[1] "%(count)d %(repeatChar)s знаци" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d од %(total)d избран предмет" -msgstr[1] "%(index)d од %(total)d избрани предмети" - -#: src/cthulhu/messages.py:2793 -#, fuzzy, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Пронајдена е %d стандардна кратенка за Cthulhu." -msgstr[1] "Пронајдени се %d стандардни кратенки за Cthulhu." - -#: src/cthulhu/messages.py:2801 -#, fuzzy, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Пронајдена е %(count)d Cthulhu кратенка за %(application)s." -msgstr[1] "Пронајдени се %(count)d Cthulhu кратенки за %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d празен простор" -msgstr[1] "%d празни простори" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d табулатор" -msgstr[1] "%d табулатори" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d табела" -msgstr[1] "%d табели" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "табела со %d ред" -msgstr[1] "табела со %d редови" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "табела со %d редови и %d колони." -msgstr[1] "табела со %d редови и %d колони." - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "табела со %d ред" -msgstr[1] "табела со %d редови" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d непосетена врска" -msgstr[1] "%d непосетени врски" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d посетена врска" -msgstr[1] "%d посетени врски" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "смени" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "на %(index)d од %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d од %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "НИВО %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ниво на дрвото %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "НИВО НА ДРВОТО %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "прашалник" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "комбинирано поле" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html содржина" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "збор" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "две точки" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "подвлечено" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "насока" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "параграф" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "збор" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "поместување" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "насока" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "листа на табулатори" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "наводник" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "html содржина" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s ниво %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "хоризонтално" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "вертикална црта" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "хоризонтално" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "вертикално порамнување" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "хоризонтално" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "вертикално порамнување" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "менувач на режим" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Панел за икони" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "html содржина" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Анимација" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "html содржина" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Анимација" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "Барам." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d посетена врска" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "вртачко копче" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "спуштено" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "проширено" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "хоризонтално" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "вертикално" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "чекирано" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "не е чекирано" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "приклучено" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "исклучено" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "делумно чекирано" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "притиснато" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "не е притиснато" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "не е избрано" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "избрано" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "не е избрано" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "не е избрано" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d посетена врска" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d непосетена врска" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "засивено" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "само за читање" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "само за читање" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "потребно" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "со повеќе избирања" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "невалидно" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "невалидно" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "правопис" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "правопис" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "невалидно" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Најди" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "Читач на екран" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "Затвори" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "Најди" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Барај за:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Барај за:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Врвот од прозорецот" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "На врвот на прозорецот" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Започни од:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Постави се околу" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Барај _наназад" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "Насока на пребарување:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Разликувај мали-големи букви" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Прави само совпаѓања на _цел збор" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Опции за барање" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Стандардно" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Големи букви" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Хиперврска" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Систем" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Апликација" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Прозорец" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Преференции за Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Лаптоп" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "Распоред на тастатурата" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Активен _профил:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Почетен профил:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Вчитај" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -#, fuzzy -msgid "Save _As" -msgstr "Зачувај го профилот како" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -#, fuzzy -msgid "Profiles" -msgstr "Профили" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Присутни балончиња со совет" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Изговарај го објектот под стрелката на глу_шецот" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Формат на _време:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Формат на да_тум:" - -#: src/cthulhu/cthulhu-setup.ui:625 -#, fuzzy -msgid "Time and Date" -msgstr "Време и датум" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "_Изговори сѐ" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Брајови поврзувања" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Фреквенција (секунди):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Апликација" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "Ажурирања на лентата за напредок" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "Ги вклучува структурните навигациски копчиња." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Изговори сѐ по:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "Изговори сѐ по:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Општо" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Јачина на зв_ук:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Вис_ина на звук:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Стапка:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Личност:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "јазик" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Синтисај_зер за говор:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Систем за говор:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Тип на _глас:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "Поставувања за тип на говор" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Изговори ги низите со мешани мали-големи букви како з_борови" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "Глобални поставувања за приказ" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Глас" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Овозможи говор" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Тек_стуално" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "Текстуалност" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Сѐ" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "Ниво на интерпункција" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Изговарај го само прикажаниот текст" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Изговарај ги празните линии" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "_Скратување и поедноставување на говорот" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Из_говарај ги мнемониците на објектите" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Изговарај ја п_озицијата на детето" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Прочитај ги пораките од упатството" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "Изговори ги координатите на _ќелијата" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "Изговори ги координатите на _ќелијата" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "Изговарај ја п_озицијата на детето" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -#, fuzzy -msgid "Spoken Context" -msgstr "Контекст за изговарање" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Говор" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Овозможи _поддршка за брајова помош" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Скратени имиња на дејство" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Оневозможи го симболот за _крај на линија" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Табела за собирање:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Овозможи скратени брајови знаци" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Активирај ехо по _збор" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "Поставувања за приказ" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Ништо" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "Индикатор на избор" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "Индикатор на хиперврски" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "Овозможи _зголемувач" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Брајов" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Активирај ехо на _копчињата" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Овозможи копчиња за _навигација" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "Овозможи ги _модификаторските копчиња" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Овозможи копчиња за _функции" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "_Овозможи говор" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Овозможи ги _модификаторските копчиња" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Овозможи копчиња за _функции" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Овозможи ги копчињата за деј_ство" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Овозможи копчиња за _навигација" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Активирај ехо по _збор" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Активирај ехо по _реченица" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Ехо на копчињата" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "_Модификаторско копче/копчиња на Cthulhu:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Поврзувања на копчиња" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "Речник за изговор" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Нов запис" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Избриши" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Изговор" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Изговори сѐ" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Не изговарај _ништо" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Ресетирај" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "Атрибути на текст" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Помести на _дното" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Помести на_долу за едно" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Помести за едно _нагоре" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Помести на _врвот" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "" -"Прилагоди ги избраните\n" -"атрибути" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "Брајов индикатор" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Атрибути на текст" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "Помошник" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "ниско" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "Помошник" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "јазик" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "јен" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "Фактор на намалување:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "боја на позадина" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "целосна висина на позадина" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "гравирање на позадина" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "насока" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "уредувачко" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "име на фамилија" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "боја на текст" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "гравирање на текст" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "ефект на фонтот" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "поместување" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "грешка" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "невидливо" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "подредување" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "јазик" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "лева маргина" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "висина на линија" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "стил на параграф" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "пиксели над линиите" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "пиксели над линиите" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "пиксели во преминот" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "десна маргина" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "покачување" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "размер" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "големина" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "истегнување" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "прецртување" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "стил" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "декорација на текст" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "ротација на текст" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "сенка на текст" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "подвлечено" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "варијанта" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "вертикално порамнување" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "тежина" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "режим на премин во нов ред" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "режим на пишување" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ништо" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "изгравирано" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "испакнато" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "со контура" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "подвлечено" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "прецртување" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "треперење" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "црно" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "единечно" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "двојно" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "ниско" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "знак" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "збор" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "збор за премин" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "лкд" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "дкл" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "лево" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "десно" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "центар" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "без порамнување" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "пополни" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "многу стеснати" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "екстра збиено" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "збиено" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "полузбиено" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "нормално" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "полупроширено" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "проширено" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "екстра проширено" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ултра проширено" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "мали големи букви" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "коси" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "закосено" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Стандардно" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Тело на текст" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Заглавие" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "основна линија" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "индекс" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "супер" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "врв" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "врв на текст" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "средина" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "дно" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "дно на текст" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "наследи" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "цврсто" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "правопис" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Притиснете на space за да смените" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Притиснете на space за проширување и користете ги стрелките нагоре и надолу " -"за избирање на предмет." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Притиснете на alt+f6 за давање на фокус на прозорците деца." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"За поместување до предметите користете ги стрелките или почнете со пишување." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "За одење до менијата на системот притиснете alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Користете ги стрелките нагоре и надолу за избирање на предмет." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "За собирање притиснете на shift и на стрелката налево." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "За спуштање притиснете на shift и на стрелката надесно." - -#: src/cthulhu/tutorialgenerator.py:397 -#, fuzzy -msgid "To activate press return." -msgstr "За активирање притиснете на space." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Напишете текст." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Користете ги стрелките лево и десно за преглед на другите јазичиња." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "За активирање притиснете на space." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Користете ги стрелките нагоре и надолу за избирање на вредност. Може и да ја " -"напишете посакуваната нумеричка вредност." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Користи ги стрелките за менување." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"За навигација, притиснете на стрелките лево или десно. За движење низ " -"предметите притиснете копчињата нагоре или надолу." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "За влегување во подмени притиснете на стрелката надесно." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"За намалување притиснете налево, за зголемување надесно. За минимум " -"притиснете на home, за максимум end." diff --git a/po/ml.po b/po/ml.po deleted file mode 100644 index d33d6fd..0000000 --- a/po/ml.po +++ /dev/null @@ -1,9796 +0,0 @@ -# translation of cthulhu.HEAD.ml.po to -# translation of cthulhu.gnome-2-22.ml.po to -# This file is distributed under the same license as the PACKAGE package. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. -# Ani Peter , 2006, 2008. -# Hari|ഹരി Vishnu | വിഷ്ണു , 2009 -# Anish A , 2013. -# mshameers , 2013. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD.ml\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2017-08-21 02:17+0530\n" -"Last-Translator: Anish Sheela \n" -"Language-Team: smc\n" -"Language: ml\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.1\n" -"X-Project-Style: gnome\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "സ്ക്രീന്‍ വായന അവസാനിപ്പിക്കാം." - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "2" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "റേഡിയോ" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "സ്പിന്‍" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "ടിപ്പ്" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "ഖണ്ഡിക" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "ഓട്ടോ" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "ചെക്ക് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "സ്പാനിഷ് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "കാനഡാ ഫ്രെഞ്ച് ഗ്രേഡ് 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "ഫ്രാന്‍സ് ഫ്രെഞ്ച് ഗ്രേഡ് 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "ലാറ്റ്‌വിയന്‍ ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "നെഥര്‍ലാന്‍ഡ് ഡച്ച് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "നോര്‍വീജിയന്‍ ഗ്രേഡ് 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "നോര്‍വീജിയന്‍ ഗ്രേഡ് 1 " - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "നോര്‍വീജിയന്‍ ഗ്രേഡ് 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "നോര്‍വീജിയന്‍ ഗ്രേഡ് 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "പോളിഷ് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "പോര്‍ച്ച്യുഗീസ് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "സ്വീഡിഷ് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "അറബിക് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "വെല്‍ഷ് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "വെല്‍ഷ് ഗ്രേഡ് 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "ജെര്‍മന്‍ ഗ്രേഡ് 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "ജെര്‍മന്‍ ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "ജെര്‍മന്‍ ഗ്രേഡ് 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "യു.കെ ഇംഗ്ലീഷ് ഗ്രേഡ് 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "യു.കെ ഇംഗ്ലീഷ് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "യു.എസ് ഇംഗ്ലീഷ് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "യു.എസ് ഇംഗ്ലീഷ് ഗ്രേഡ് 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "കാനഡാ ഫ്രെഞ്ച് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "ഫ്രാന്‍സ് ഫ്രെഞ്ച് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "ഗ്രീക്ക് ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "ഹിന്ദി ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "ഹംഗേറിയന്‍ 8 കുത്ത് കമ്പ്യൂട്ടര്‍" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "ഹംഗേറിയന്‍ ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "ഹംഗേറിയന്‍ ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "ഇറ്റാലിയന്‍ ഗ്രേഡ് 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "ബെല്‍ജിയം ഡച്ച് ഗ്രേഡ് 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "space" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "ന്യൂലൈന്‍" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "ടാബ്" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "എക്സ്‌ക്ലെയിം (! എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "കോട്ട്സ് " - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "നംബര്‍" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "ഡോളര്‍ ($)" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "ശതമാനം (%)" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ആന്‍ഡ് (&)" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "അപ്പോസ്ട്രോഫി (')" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "ഇടത് പരാന്‍ഥെസിസ് ('(')" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "വലത് പരാന്‍ഥെസിസ് (')')" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "സ്റ്റാര്‍ (*)" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "പ്ലസ് (+)" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "കോമാ (,)" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "ഡാഷ് (-)" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "കുത്ത് (.)" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "സ്ലാഷ് (/)" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "കോളന്‍ (:)" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "സെമികോളന്‍ (;)" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "കുറവ് (< എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "സമം (= എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "കൂടിയ (> എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "ചോദ്യം (? എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "അറ്റ് ദി റേറ്റ് (@ എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "ഇടത് ബ്രാക്കറ്റ് ([ എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "ബാക്ക്സ്ലാഷ്" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "വലത് ബ്രാക്കറ്റ് (] എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "കാരറ്റ് (^)" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "അടിവര (_)" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "ഗ്രേവ്(`എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "ഇടത് ബ്രെയിസ് ({)" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr " എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "വലത് ബ്രെയിസ് (})" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "ടിള്‍ഡ് (~)" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "മുറിയാത്ത സ്പേസ്" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "തിരിച്ചുള്ള എക്സ്‌ക്ലമേഷന്‍ പോയിന്റ് (¡)" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "സെന്റ്സ് (¢)" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "പൊണ്ട്സ് (£)" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "കറന്‍സിയുടെ ചിഹ്നം (¤)" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "യെന്‍" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "വിടവുള്ള ബാര്‍ (¦ എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "വിഭാഗം" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "പകര്‍പ്പവകാശം" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "സൂപര്‍സ്ക്രിപ്ട് a ('ª' (U+00aa) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "ഇടത് ഡബിള്‍ ആങ്കിള്‍ ബ്രാക്കെറ്റ് (<< (U+00ab) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "ലോജിക്കല്‍ നോട്ട് ('¬' (U+00ac) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "സോഫ്ട് ഹൈഫെന്‍ ('­' (U+00ad) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "രജിസ്ടേര്‍ഡ് (® എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "മാക്രോണ്‍ (¯ എന്ന ചിഹ്നം)" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "ഡിഗ്രീസ്" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "പ്ലസ് അല്ലെങ്കില്‍ മൈനസ്" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "സൂപ്പര്‍സ്ക്രിപ്റ്റ് 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "സൂപ്പര്‍സ്ക്രിപ്റ്റ് 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acute" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "ഖണ്ഡിക അടയാളപ്പെടുത്തുന്ന ചിഹ്നം " - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "നടുക്കുള്ള കുത്ത്" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "സെഡില്ല" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "സൂപ്പര്‍സ്ക്രിപ്റ്റ് 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ഓര്‍ഡിനല്‍ " - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "വലത് ഡബിള്‍ ആങ്കിള്‍ ബ്രാക്കെറ്റ് (>> (U+00bb) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "കാല്‍ഭാഗം" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "പകുതിഭാഗം" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "മൂന്നില്‍ ഒന്നു്" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "ഇന്‍ വര്‍ട്ടഡ് പ്രശ്ന ചിഹ്നം ('¿' (U+00bf) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "എത്ര തവണ " - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "÷" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "ഫ്ലോറിന്‍ (ƒ)" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "'" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "'" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "," - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "ഇടത് ഡബിള്‍ ക്വോട്ട് ( '“' (U+201c) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "വലത് ഡബിള്‍ ക്വോട്ട് ( '”' (U+201d) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "„" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "ഡാഗ്ഗര്‍ (†)" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "‡" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "•" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "ത്രികോണ ബുള്ളറ്റ് ('‣' (U+2023) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "പെര്‍ മില്ലി ( '‰' (U+2030) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "പ്രൈം (′)" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "ഡബിള്‍ പ്രൈം ( '″' (U+2033) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "ഡബിള്‍ പ്രൈം ( '″' (U+2033) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "ഹൈഫെന്‍ ബുള്ളെറ്റ് ( '⁃' (U+2043) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr " യൂറോ ( '€' (U+20ac) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "ട്രേഡ്മാര്‍ക്ക് ( '™' (U+2122) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "ചെക്ക് മാര്‍ക്ക് (✓)" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr " ('✔' (U+2714) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-രീതിയിലുള്ള ബുള്ളെറ്റ് ( 'x' (U+2717) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "സൂപര്‍സ്ക്രിപ്ട് 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "സൂപര്‍സ്ക്രിപ്ട് 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "സൂപര്‍സ്ക്രിപ്ട് 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "സൂപര്‍സ്ക്രിപ്ട് 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "സൂപര്‍സ്ക്രിപ്ട് 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "സൂപര്‍സ്ക്രിപ്ട് 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "സൂപര്‍സ്ക്രിപ്ട് 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "സൂപര്‍സ്ക്രിപ്ട് +" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "സൂപര്‍സ്ക്രിപ്ട് -" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "സൂപര്‍സ്ക്രിപ്ട് =" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "സൂപര്‍സ്ക്രിപ്ട് (" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "സൂപര്‍സ്ക്രിപ്ട് )" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "സൂപര്‍സ്ക്രിപ്ട് n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "സബ്സ്ക്രിപ്റ്റ് 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "സബ്സ്ക്രിപ്റ്റ് 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "സബ്സ്ക്രിപ്റ്റ് 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "സബ്സ്ക്രിപ്റ്റ് 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "സബ്സ്ക്രിപ്റ്റ് 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "സബ്സ്ക്രിപ്റ്റ് 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "സബ്സ്ക്രിപ്റ്റ് 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "സബ്സ്ക്രിപ്റ്റ് 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "സബ്സ്ക്രിപ്റ്റ് 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "സബ്സ്ക്രിപ്റ്റ് 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "സബ്സ്ക്രിപ്റ്റ് +" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "സബ്സ്ക്രിപ്റ്റ് -" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "സബ്സ്ക്രിപ്റ്റ് =" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "സബ്സ്ക്രിപ്ട് (" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "സബ്സ്ക്രിപ്ട് )" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "കറുത്ത സമചതുരം ( '■' (U+25a0) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "കറുത്ത ഡയമണ്ഡ് ( '◆' (U+25c6) എന്ന അക്ഷരം)" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "അടുത്ത അക്ഷരത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "ചൂണ്ടുകോല്‍ നിലവിലെ വസ്‌തുവിലേക്ക് വഴിമാറ്റപ്പെടും" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "നിലവിലെ ഫ്ളാറ്റ് റിവ്യു വസ്തുവില്‍ ലെഫ്റ്റ് ക്ലിക്ക് ചെയ്യപ്പെടും." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "നിലവിലെ ഫ്ളാറ്റ് റിവ്യു വസ്തുവില്‍ റൈറ്റ് ക്ലിക്ക് ചെയ്യപ്പെടും." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "മുഴുവന്‍ രേഖ സംസാരിക്കുന്നു" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു വരി പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "ലളിതമായ ഞാന്‍ എവിടെ എന്ന പ്രവര്‍ത്തനം ചെയ്യപ്പെടും." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "വിസ്‌തരിച്ചു ഞാന്‍ എവിടെ എന്ന പ്രവര്‍ത്തനം ചെയ്യപ്പെടും." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു വരി പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "ഒഴിഞ്ഞ വരികള്‍ പറയുക" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "അടുത്ത ബട്ടനിലേക്ക് പോകുന്നു" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "സ്ഥിതി ബാര്‍ സംസാരിക്കുന്നു" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "ടൈറ്റില്‍ ബാര്‍ സംസാരിക്കുന്നു" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "ഓര്‍ക്ക തിരയല്‍ ഡയലോഗ് തുറക്കുന്നു." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "ഒരു സ്റ്റ്രിങ്ങിന്റെ അടുത്ത ഇന്‍സ്റ്റെന്‍സിനു തിരയുന്നു." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "ഒരു സ്റ്റ്രിങ്ങിന്റെ പ്രീവിയസ് ഇന്‍സ്റ്റെന്‍സിനു തിരയുന്നു." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "ഫ്ലാറ്റ് റിവ്യുയിലേക്ക് പ്രവേശിക്കുകയോ പുറത്തുവരികയോ ചെയ്യും." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "ഫ്ലാറ്റ് റിവ്യു അവസാനത്തേക്ക് നീക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "ഫ്ലാറ്റ് റിവ്യു ഹോം സ്ഥാനത്തേക്ക് നീക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "ഫ്ലാറ്റ് റിവ്യു അവസാനത്തേക്ക് നീക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "ഫ്ലാറ്റ് റിവ്യു മുന്നത്തെ വരിയിലെ ആദ്യത്തേക്ക് നീക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു വരി പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു വരി അക്ഷരാനുസൃതമായി പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു വരി ഉച്ചാരണപ്രകാരം പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "ഫ്ലാറ്റ് റിവ്യു അടുത്ത വരിയിലെ ആദ്യത്തേക്ക് നീക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "ഫ്ലാറ്റ് റിവ്യു കഴിഞ്ഞ വസ്തുവിലേക്കോ വാക്കിലേക്കോ നീക്കുപ്പെടും." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു വസ്തുവിനെയോ വാക്കിനേയോ പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു വസ്തുവിനെയോ വാക്കിനേയോ അക്ഷരാനുസൃതമായി പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു വസ്തുവിനെയോ വാക്കിനേയോ ഉച്ചാരണപ്രകാരം പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "ഫ്ലാറ്റ് റിവ്യു അടുത്ത വസ്തുവിലേക്കോ വാക്കിലേക്കോ നീക്കുപ്പെടും." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "ഫ്ലാറ്റ് റിവ്യു നിലവിലെ വാക്കിന്റെ മുകളിലെ വാക്കിലേക്ക് നീക്കുപ്പെടും." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു വസ്തു പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "ഫ്ലാറ്റ് റിവ്യു നിലവിലെ വാക്കിന്റെ താ​​ഴത്തേ വാക്കിലേക്ക് നീക്കുപ്പെടും." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "ഫ്ലാറ്റ് റിവ്യു ക​​ഴിഞ്ഞ അക്ഷരത്തിലേക്ക് നീക്കുപ്പെടും." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു അക്ഷരം പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു അക്ഷരം ഉച്ചാരണപ്രകാരം പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "നിലവിലെ ഫ്ലാറ്റ് റിവ്യു അക്ഷരത്തിന്റെ യൂണികോഡ് മൂല്യാങ്കം പറയപ്പെടും." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "ഫ്ലാറ്റ് റിവ്യു അടുത്ത അക്ഷരത്തിലേക്ക് നീക്കുപ്പെടും." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "ഫ്ലാറ്റ് റിവ്യു വരിയുടെ ആവസാനത്തേക്ക് നീക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "ഫ്ലാറ്റ് റിവ്യു താഴെ ഇടതിലേക്ക് നീക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "നിലവില്‍ ഫ്ലാറ്റ് റിവ്യുവിനു കീ​ഴിലുള്ള വസ്തുക്കളെ ക്ലിപ്ബോര്‍ടിലേക്ക് പകര്‍ത്തപ്പെടും." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "നിലവില്‍ ഫ്ലാറ്റ് റിവ്യുവിനു കീ​ഴിലുള്ള വസ്തുക്കളെ ക്ലിപ്ബോര്‍ടിലേക്ക് കൂട്ടിച്ചേര്‍ക്കുപ്പെടും." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "ഫ്ലാറ്റ് റിവ്യു അവസാനത്തേക്ക് നീക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "നിലവിലെ പട്ടികയിലെ അറയോ മുഴുവന്‍ വരിയോ പറയിപ്പിക്കാം." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "നിലവിലെ വാചകത്തിലെ അക്ഷരങ്ങളുടെ പ്രകൃതിയെക്കുറിച്ച വായിക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "പ്രദര്‍ശിപ്പിച്ചിരിക്കുന്ന ബ്രയിലി ഇടതിലേക്ക് തിരിക്കും." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "പ്രദര്‍ശിപ്പിച്ചിരിക്കുന്ന ബ്രയിലി വലതിലേക്ക് തിരിക്കും." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "കീബോര്‍ഡ് ശ്രദ്ധക്കുന്ന വസ്തുവിലേക്ക് തിരിച്ചെത്തും." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "ചുരുക്കുപ്പെട്ട ബ്രയിലി തുടങ്ങുകയോ അവസാനിപ്പിക്കുകയോ ചെയ്യാം." - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "ചുണ്ടുകോല്‍ വഴിമാറ്റും കീ " - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "ടെക്സ്റ്റ് തെരഞ്ഞെടുക്കലിന്റെ തുടക്കം അടയാളപ്പെടുത്തുന്നു." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "ടെക്സ്റ്റ് തെരഞ്ഞെടുക്കലിന്റെ ഒടുക്കം അടയാളപ്പെടുത്തുന്നു." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "പഠന മോഡിലേക്ക് പ്രവേശിക്കപ്പെടും. പഠന മോഡ് അവസാനിപ്പിക്കാന്‍ എസ്കേപ് അമര്‍ത്തുക." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "സംസാര വേഗം കുറയ്ക്കുക." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "സംസാര വേഗം കൂട്ടുക." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "സംസാര ആവൃത്തി കുറയ്ക്കുക." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "സംസാര ആവൃത്തി കൂട്ടുക." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "സംസാര വേഗം കൂട്ടുക." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "സംസാര വേഗം കുറയ്ക്കുക." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "ഒരു സ്റ്റ്രിങ്ങിന്റെ പ്രീവിയസ് ഇന്‍സ്റ്റെന്‍സിനു തിരയുന്നു." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "ചിട്ടപ്പെടുത്തിയ രൂപരേഖ ആവൃത്തിയില്‍ അടുത്തതിലേക്ക് പോകപ്പടും." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "സംസാര വേഗം കുറയ്ക്കുക." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "സംസാര വേഗം കൂട്ടുക." - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "ശബ്ദ തരം ക്രമീകരണങ്ങള്‍: (_V)" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "സംസാരിപ്പിക്കുന്നത് നിര്‍ത്തുകയോ തുടങ്ങുകയോ ചെയ്യും." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "മൌസ് അവലോകന മോഡിലേക്ക്..." - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "സ്ക്രീന്‍ വായന അവസാനിപ്പിക്കാം." - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "ഓര്‍ക്ക പ്രവര്‍ത്തനം അഭിരുചിക്കനുസ്രിതമായി മാറ്റാവുന്ന ___ പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "ആപ്ലികേഷനുകളുടെ പ്രവര്‍ത്തനം അഭിരുചിക്കനുസ്രിതമായി മാറ്റാവുന്ന ___ പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "ചിഹ്നങ്ങള്‍ പറയുന്ന ആവൃത്തിയില്‍ അടുത്തതിലേക്ക് പോകപ്പടും." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "കീ എകോ ഘട്ടങ്ങളുടെ ആവൃത്തിയില്‍ അടുത്തതിലേക്ക് പോകപ്പടും." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "ചിട്ടപ്പെടുത്തിയ രൂപരേഖ ആവൃത്തിയില്‍ അടുത്തതിലേക്ക് പോകപ്പടും." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "വല്യക്ഷര ശൈലി ആവൃത്തിയില്‍ അടുത്തതിലേക്ക് പോകപ്പടും." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "കീ എകോ ഘട്ടങ്ങളുടെ ആവൃത്തിയില്‍ അടുത്തതിലേക്ക് പോകപ്പടും." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "നിലവിലെ എന്റെ അവസ്ത ഞാന്‍ എവിടെ എന്നതുമായി ബന്ധപ്പെടുത്തി ഓര്‍മക്കുറിപ്പി ചേര്‍ക്കുക." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "കഴിഞ്ഞ ഓര്‍മക്കുറിപ്പ് സ്ഥലത്തേക്ക് പോകാം." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "ഓര്‍മക്കുറിപ്പിലേക്ക് പോവുക." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "അടുത്ത ഓര്‍മക്കുറിപ്പ് സ്ഥലത്തേക്ക് പോകാം." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "ഓര്‍മക്കുറിപ്പ് ചേര്‍ക്കുക" - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "ഓര്‍മക്കുറിപ്പ് സംരക്ഷിക്കുക." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "മൌസ് അവലോകന മോഡിലേക്ക്..." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "നിലവിലെ സമയം അവതരിപ്പിക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "നിലവിലെ തിയതി അവതരിപ്പിക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "നിലവിലെ ആപ്ലികേഷനിലേക്ക് അടുത്ത കമാന്റ്റ് കെടുക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "സുഹ്രുത്തുകള്‍ ടൈപ്പ്‌ ചെയ്യുബോള്‍ അറിയിക്കുണമോ വേണ്ടയോ." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "ഇടത്തേക്കുള്ള വരി" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "വലത്തേക്കുള്ള വരി" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "മുകളിലേക്കുള്ള വരി" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "താഴേക്കുള്ള വരി" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "നിര്‍ത്തി വെക്കുക" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "മുകളില്‍ ഇടത്" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "താഴെ ഇടത്" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "കര്‍സറിന്റെ സ്ഥാനം" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "ആറ് കുത്ത്" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "കര്‍സറിന്റെ പാത" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "മുറിക്കാന്‍ തുടങ്ങുക" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "വരി മുറിക്കുക" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "അവസാന സന്ദേശം അവതരിപ്പിക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "സന്ദേശ പട്ടിക അവതരിപ്പിക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "മുന്‍പുള്ള സന്ദേശം അവതരിപ്പിക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "അവസാന സന്ദേശം അവതരിപ്പിക്കപ്പെടും." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "അടുത്ത അക്ഷരത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "മുന്‍പുള്ള അക്ഷരത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "അടുത്ത വാക്കിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "മുന്‍പുള്ള വാക്കിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "അടുത്ത വരിയിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "മുന്‍പുള്ള വരിയിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "ഫയലിന്റെ ശിഖരത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "ഫയലിന്റെ അടിയിത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "വരിയുടെ തുടക്കത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "വരിയുടെ അവസാനത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "അടുത്ത വസ്തുവിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "കഴിഞ്ഞ വസ്തുവിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "നിലവിലെ കോബോ ബോക്സ് വിപുലീകരിക്കാന്‍ കാരണമാകും." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "തത്സമയ പ്രദേശത്തിന്റെ " - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "ആദിയിലുള്ള തത്സമയ പ്രദേശം നിരീക്ഷണ ഘട്ടം നിര്‍ത്തിവെക്കാം." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "തത്സമയ പ്രദേശ അറിയിപ്പുകള്‍ അവലോകന ചെയ്യാം." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "തത്സമയ പ്രദേശം നിരീക്ഷിക്കാം നിരീക്ഷിക്കാതിരിക്കാം. " - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "നിലവിലെ മൌസ് ഓവരില്‍ നിന്നും ശ്രദ്ധ അടുപ്പിക്കുകയോ അകറ്റുകയോ ചെയ്യാം." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "കോളം തലവാചക നിര നീക്കുപ്പെടും." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "കോളം തലവാചക നിര നീക്കുപ്പെടും." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "നിര തലവാചക കോളം നീക്കുപ്പെടും" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "നിര തലവാചക കോളം നീക്കുപ്പെടും" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "ഇന്‍പുട്ട് വരിയില്‍ അടങ്ങിയിട്ടുള്ള വസ്‌തുകളെ അവതരിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "മുന്‍പുള്ള ബ്ളാക്ക് ക്വോട്ടിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "അടുത്ത ബ്ളാക്ക് ക്വോട്ടിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:852 -#, fuzzy -msgid "Display a list of blockquotes" -msgstr "ബ്ളാക്ക് ക്വോട്ടുകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "മുന്‍പുള്ള ബട്ടനിലേക്ക് പോകുന്നു" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "അടുത്ത ബട്ടനിലേക്ക് പോകുന്നു" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "ബട്ടനുകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "മുന്‍പുള്ള ചെക് ബോക്സിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "അടുത്ത ചെക് ബോക്സിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:870 -#, fuzzy -msgid "Display a list of check boxes" -msgstr "ചെക് ബോക്സുകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "മുന്‍പുള്ള പട്ടികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "അടുത്ത പട്ടികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "പട്ടികകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "മുന്‍പുള്ള കോബോ ബോക്സിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "അടുത്ത കോബോ ബോക്സിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "ഫയലിന്റെ ശിഖരത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "വരിയുടെ അവസാനത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:901 -#, fuzzy -msgid "Display a list of combo boxes" -msgstr "കോബോ ബോക്സുകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "കഴിഞ്ഞ രേഖപ്പെടുത്തിയതിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "അടുത്ത രേഖപ്പെടുത്തിയതിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "രേഖപ്പെടുത്തുലുകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "മുന്‍പുള്ള വാക്കിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "അടുത്ത വാക്കിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:919 -#, fuzzy -msgid "Display a list of form fields" -msgstr "രേഖപ്പെടുത്തുലുകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "മുന്‍പുള്ള തലക്കെട്ടിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "അടുത്ത തലക്കെട്ടിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "തലക്കെട്ടുകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "ഘട്ടം %d എന്ന കഴിഞ്ഞ തലക്കെട്ടിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "ഘട്ടം %d എന്ന അടുത്ത തലക്കെട്ടിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "ഘട്ടം %d എന്ന തലക്കെട്ടുകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "മുന്‍പുള്ള പട്ടികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "അടുത്ത പട്ടികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:949 -#, fuzzy -msgid "Display a list of internal frames" -msgstr "പട്ടികകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "മുന്‍പുള്ള വരിയിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "അടുത്ത വരിയിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "പട്ടികകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "മുന്‍പുള്ള അതിരടയാളത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "അടുത്ത അതിരടയാളത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "കണ്ണികളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "മുന്‍പുള്ള വലിയ യുക്താനുസൃതമായ അക്ഷര കുട്ടത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "അടുത്ത വലിയ യുക്താനുസൃതമായ അക്ഷര കുട്ടത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr " അക്ഷര കുട്ടങ്ങളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "മുന്‍പുള്ള വരിയിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "അടുത്ത വരിയിലേയ്ക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "കണ്ണികളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "മുന്‍പുള്ള പട്ടികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "അടുത്ത പട്ടികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1006 -#, fuzzy -msgid "Display a list of lists" -msgstr "പട്ടികകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "മുന്‍പുള്ള പട്ടിക വിഷയത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "അടുത്ത പട്ടിക വിഷയത്തിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "പട്ടിക വിഷയങ്ങളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "മുന്‍പുള്ള തത്സമയ പ്രദേശത്തേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "അടുത്ത തത്സമയ പ്രദേശത്തേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "തത്സമയ പ്രദേശത്ത് അവസാനം അറിയിപ്പ് വന്നിടത്തേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "കീബോര്‍ഡ് ശ്രദ്ധക്കുന്ന വസ്തുവിലേക്ക് തിരിച്ചെത്തും." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "കീബോര്‍ഡ് ശ്രദ്ധക്കുന്ന വസ്തുവിലേക്ക് തിരിച്ചെത്തും." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "മുന്‍പുള്ള ഖണ്‌ഡികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "അടുത്ത ഖണ്‌ഡികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "ഖണ്‌ഡികകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "മുന്‍പുള്ള റേഡിയോ ബട്ടണിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "അടുത്ത റേഡിയോ ബട്ടനിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "റേഡിയോ ബട്ടനുകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "മുന്‍പുള്ള വേര്‍തിരിവിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "അടുത്ത വേര്‍തിരിവിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "മുന്‍പുള്ള പട്ടികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "അടുത്ത പട്ടികയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "പട്ടികകളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "ഒരു അറ താഴെ പോകും." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "പട്ടികയുടെ ആദ്യ അറയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "പട്ടികയുടെ അവസാന അറയിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "ഒരു അറ ഇടതിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "ഒരു അറ വലതിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "ഒരു അറ മുകളിലേക്ക് പോകും." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "മൌസ് അവലോകന മോഡിലേക്ക്..." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "കീ എഖോ പ്രവര്‍ത്തന സജ്ജമാക്കുക" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "മുന്‍പുള്ള സന്ദര്‍ശിക്കാത്ത കണ്ണിയിലേക്ക് പോകും. " - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "അടുത്ത സന്ദര്‍ശിക്കാത്ത കണ്ണിയിലേക്ക് പോകും. " - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "സന്ദര്‍ശിക്കാത്ത കണ്ണികളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "മുന്‍പുള്ള സന്ദര്‍ശിച്ച കണ്ണിയിലേക്ക് പോകും. " - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "അടുത്ത സന്ദര്‍ശിച്ച കണ്ണിയിലേക്ക് പോകും. " - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "സന്ദര്‍ശിച്ച കണ്ണികളുടെ പട്ടിക പ്രദര്‍ശിപ്പിക്കും." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "കറുപ്പ്" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "കറുത്ത ഡയമണ്ഡ് ( '◆' (U+25c6) എന്ന അക്ഷരം)" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "a grave" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i grave" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "ചാര നിറം" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "ഡിഗ്രീസ്" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "ഹിന്ദി ഗ്രേഡ് 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "വലത് ബ്രെയിസ് (})" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "വലത് കണ്‍ട്രോള്‍" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "വലത് പരാന്‍ഥെസിസ് (')')" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "വലത് ബ്രെയിസ് (})" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "വലത് പരാന്‍ഥെസിസ് (')')" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "വലത് പരാന്‍ഥെസിസ് (')')" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "വലത് ആള്‍ട്ട്" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "വലത് പരാന്‍ഥെസിസ് (')')" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "വലത് സൂപ്പര്‍" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "വലത് ആരോ" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "ന്യൂലൈന്‍" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "ഇമേജ്" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "tre" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s സ്ക്രീന്‍" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "btn" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "ശുന്യസ്ഥാനം" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "ശുന്യസ്ഥാനം" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "പൂര്‍ണ്ണമായി സ്ക്രീനില്‍ കാണുക" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_സജീവമാക്കുക" - -#: src/cthulhu/guilabels.py:63 -#, fuzzy -msgid "Automatic focus mode during structural navigation" -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -#, fuzzy -msgid "Automatic focus mode during native navigation" -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "കുത്ത് _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "കുത്ത് _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "കുത്തുകള്‍ 7 _ഉം 8ഉം" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "റദ്ദാക്കുക (_C)" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_ഏങ്ങോട്ട് പോകണം" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "-ഒകെ" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "ഒന്നുമില്ല" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "അക്ഷരതെറ്റ്" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "എല്ലാ ചാ_നലുകളും " - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_ചാറ്റ് മുറിയുടെ പേര് പറയുക" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "ഇരട്ട ക്ലിക്ക്" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "മൂന്ന് ക്ലിക്ക്" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "സ്വതവേയുള്ള സിന്‍ഥസൈസര്‍" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "ശരിക്കുള്ള വാചകം" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "മാറ്റിയ വാചകം" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "അ_ക്ഷരം പ്രതി പറയുക" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "നി_ലവിലെ സ്ഥലം" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "കോമാ (,)" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "കീ ബന്ധങ്ങള്‍" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "സാധാരണ" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "എഴുത്ത് മോഡ്" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "വിഭാഗം" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "ഓര്‍മക്കുറിപ്പ് സംരക്ഷിക്കുക." - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "സമയവും തീയതിയും" - -#: src/cthulhu/guilabels.py:310 -#, fuzzy -msgid "Mouse review" -msgstr "പറയുന്നത് വീണ്ടും തുടങ്ങുന്നു." - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "ആനിമേഷന്‍" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "അണ്‍ബൌണ്ട്" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -#, fuzzy -msgid "Flat review contents" -msgstr "എച്ടിഎംഎല്‍ ഉള്ളടക്കം" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "പരിഷ്കരിച്ചത്" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_ഡസ്ക്ടോപ്പ്" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "അറിയിപ്പ്" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "അറിയിപ്പ്" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s-നുള്ള ഓര്‍ക്കാ മുന്‍ഗണനകള്‍" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "ബ്രൈലിയില്‍ അടയാളപ്പെടുത്തുക" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "സംസാരിക്കുക" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "ഉപയോക്താവിന്റെ പ്രൊഫൈല്‍ എടുക്കുക" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "പ്രൊഫൈല്‍ ഇങ്ങനെ സൂക്ഷിക്കുക" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_പ്രൊഫൈലിന്റെ പേരു്:" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "ഉപയോക്താവിന്റെ പ്രൊഫൈല്‍ എടുക്കുക" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "എല്ലാം" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "പ്രയോഗം" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "ജാലകം" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "ഒന്നുമില്ല (_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "ചിലത് (_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "മി_ക്കവാറും" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "വരി" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "വാചകം" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "കോട്ട്സ് " - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "ബട്ടണ്‍" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "തലക്കെട്ട്" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "ചെക്ക് ബോക്സ്" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "ക്ളിക്ക് ചെയ്യാവുന്നത്" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "കോംപോ ബോക്സ്" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "വിവരണം" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "തലക്കെട്ട് " - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "ഇന്റേര്‍ണല്‍ ഫ്രെയിം" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "ഇമേജ്" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "ലേബല്‍" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "ട്രേഡ്മാര്‍ക്ക് ( '™' (U+2122) എന്ന അക്ഷരം)" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "ലവല്‍" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "ലിങ്ക്" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "ലിസ്റ്റ്" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "ഒബ്ജക്ട്" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "ഖണ്ടിക" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "റേഡിയോ ബട്ടണ്‍" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "വേഷം" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "തിരഞ്ഞെടുത്തവ" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "അവസ്ഥ" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "പദാവലി" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "മൂല്യം" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "കോട്ട്സ് " - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "ബട്ടണ്‍" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "ചെക്ക് ബോക്സ്" - -#: src/cthulhu/guilabels.py:706 -#, fuzzy -msgctxt "structural navigation" -msgid "Clickables" -msgstr "ടേബിള്‍" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "കോംപോ ബോക്സ്" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "തലക്കെട്ട്" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "ഇന്റേര്‍ണല്‍ ഫ്രെയിം" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "ചിത്രങ്ങള്‍" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "ട്രേഡ്മാര്‍ക്ക് ( '™' (U+2122) എന്ന അക്ഷരം)" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "ലിങ്ക്" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "പട്ടികകൾ" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "ഖണ്ഡിക" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "ടേബിള്‍" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "ചെറുതായി നിര്‍ത്തുമ്പോള്‍ സംസാരത്തെ മു_റിക്കുക" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s സ്വതവേയുള്ള ശബ്ദം" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "സാധാരണ" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "കണ്ണി" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "സിസ്റ്റം" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "വലിയ അക്ഷരം" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "സ്പീച്ച് ഡിസ്പാച്ചര്‍" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "_കളം സംസാരിക്കുക" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "സവിഷേതയുടെ പേരു്" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "ചെറു_താക്കി" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "അറിയിപ്പ്" -msgstr[1] "അറിയിപ്പ്" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "ഷിഫ്ട്" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "ഇടത് ഷിഫ്ട്" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "ഇടത് ആള്‍ട്ട്" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ഇടത് കണ്‍ട്രോള്‍" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "വലത് ഷിഫ്ട്" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "വലത് ആള്‍ട്ട്" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "വലത് കണ്‍ട്രോള്‍" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ഇടത് മെറ്റാ" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "വലത് മെറ്റാ" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "ഇടത് ടാബ്" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "മുകളില്‍" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "ഇടത്ത്" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "വലത്ത്" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "ഇടത് സൂപ്പര്‍" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "വലത് സൂപ്പര്‍" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "മെനു" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "സഹായം" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "മോഡ് സ്വിച്ച്" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "stroke" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "മൈനസ് (-)" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "സൂപ്പര്‍" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "ഷിഫ്ട്" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "ബോള്‍ഡാക്കുക" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "ഇറ്റാലിക്ക് (ചരിഞ്ഞു്‌)" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr " സബ്സ്ക്രിപ്റ്റ് %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr " സബ്സ്ക്രിപ്റ്റ് %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "പണിയിടം" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s ആണ് സാഹചര്യം" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "ഇടത് ആരോ" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "ആരോ" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "വലത് ആരോ" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "ആരോ" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "വലത് ആരോ" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "വലത് ആരോ" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "വലത് ആരോ" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "ഇടത് ആരോ" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "ഇടത് ആരോ" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "വലത് ആരോ" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "ഇടത് ഡബിള്‍ ക്വോട്ട് ( '“' (U+201c) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "‡" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "വലത് ഡബിള്‍ ക്വോട്ട് ( '”' (U+201d) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "‡" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "വലത് ഡബിള്‍ ക്വോട്ട് ( '”' (U+201d) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr " വലത് ആരോ ( '➔' (U+2794) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "വലത് ആരോഹെഡ്" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "മൈനസ് (-)" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "കുറവ് (< എന്ന ചിഹ്നം)" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "കൂടിയ (> എന്ന ചിഹ്നം)" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "കുത്ത് (.)" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "തിരസ്ചീനമായി നിര്‍ത്തുക" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "തിരശ്ചീനമായത്" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "സ്വയം പൂര്‍ത്തിയാക്കല്‍" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "കാലി" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "ടേബിള്‍" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "നിരയുടെ അവസാനം." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "പ്ലസ് അല്ലെങ്കില്‍ മൈനസ്" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "പ്ലസ് (+)" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "മൈനസ് (-)" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "വിടവടയാളം" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "ക്യൂബ് റൂട്ട് ('∛' (U+221b) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr " ( '∞' (U+221e) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "വലത് ആള്‍ട്ട്" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "ഒറ്റ" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "തിരസ്ചീനമായി നിര്‍ത്തുക" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "÷" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Separator" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "നോട്ട് ഐക്വല്‍ ടു ( '≠' (U+2260) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "ലോജിക്കല്‍ നോട്ട് ('¬' (U+00ac) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "ലോജിക്കല്‍ നോട്ട് ('¬' (U+00ac) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "വാക്യ ദിശ" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "ഇന്റേര്‍ണല്‍ ഫ്രെയിം" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "ഡബിള്‍ പ്രൈം ( '″' (U+2033) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "മൈനസ് (-)" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "ടിള്‍ഡ് (~)" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "ശരാശരി സമം ( '≈' (U+2248) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ശരാശരി സമം ( '≈' (U+2248) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "ശരാശരി സമം ( '≈' (U+2248) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "ശരാശരി സമം ( '≈' (U+2248) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ശരാശരി സമം ( '≈' (U+2248) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "ശരാശരി സമം ( '≈' (U+2248) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "മൂന്ന് ക്ലിക്ക്" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "ശരാശരി സമം ( '≈' (U+2248) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "മറ്റൊരു സൈറ്റ്" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "നോട്ട് ഐക്വല്‍ ടു ( '≠' (U+2260) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "സമം (= എന്ന ചിഹ്നം)" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "സമം (= എന്ന ചിഹ്നം)" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "നോട്ട് ഐക്വല്‍ ടു ( '≠' (U+2260) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "നോട്ട് ഐക്വല്‍ ടു ( '≠' (U+2260) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "ത്രികോണ ബുള്ളറ്റ് ('‣' (U+2023) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "സമം (= എന്ന ചിഹ്നം)" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "നോട്ട് ഐക്വല്‍ ടു ( '≠' (U+2260) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "നോട്ട് ഐക്വല്‍ ടു ( '≠' (U+2260) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "നേരെയുള്ളവ" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "നോട്ട് ഐക്വല്‍ ടു ( '≠' (U+2260) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "നോട്ട് ഐക്വല്‍ ടു ( '≠' (U+2260) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "കൂടിയ (> എന്ന ചിഹ്നം)" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "അമര്‍ത്താത്തവ" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "തിരഞ്ഞെടുത്തിട്ടില്ലാത്തത്" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "സബ്സ്ക്രിപ്റ്റ് 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "സൂപര്‍സ്ക്രിപ്ട് a ('ª' (U+00aa) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "അനവധി വസ്തുക്കള്‍ തിരഞ്ഞെടുക്കുവാന്‍ സാധ്യമായത്" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "ജസ്റ്റിഫിക്കേഷന്‍" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "അനവധി വസ്തുക്കള്‍ തിരഞ്ഞെടുക്കുവാന്‍ സാധ്യമായത്" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "സബ്സ്ക്രിപ്റ്റ് =" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "en dash" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "സബ്സ്ക്രിപ്റ്റ് +" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "സബ്സ്ക്രിപ്റ്റ് -" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "വലത് മെറ്റാ" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "ഇടത് ടാബ്" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "down" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "വിഭാഗം" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ഓര്‍ഡിനല്‍ " - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "ഇമേജ്" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "multi" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "ഇന്റേര്‍ണല്‍ ഫ്രെയിം" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "സാധാരണ" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "'" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "വലത് ബ്രെയിസ് (})" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "വിടവടയാളം" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "ലോജിക്കല്‍ നോട്ട് ('¬' (U+00ac) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "ലോജിക്കല്‍ നോട്ട് ('¬' (U+00ac) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "ഡബിള്‍ പ്രൈം ( '″' (U+2033) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "ഡബിള്‍ പ്രൈം ( '″' (U+2033) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "വാക്യ ദിശ" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "ഡബിള്‍ പ്രൈം ( '″' (U+2033) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "ലെസ് ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≤' (U+2264)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "ഗ്രേറ്റര്‍ ദാന്‍ ഓര്‍ ഐക്വല്‍ ടു ( '≥' (U+2265)എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "തിരസ്ചീനമായി നിര്‍ത്തുക" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ഇടത് പരാന്‍ഥെസിസ് ('(')" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "വലത് പരാന്‍ഥെസിസ് (')')" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "ഇടത് ആള്‍ട്ട്" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "വലത് ആള്‍ട്ട്" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "ഇടത് ബ്രെയിസ് ({)" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "താഴെ" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "ഇടത് ഡബിള്‍ ആങ്കിള്‍ ബ്രാക്കെറ്റ് (<< (U+00ab) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "വലത് ഡബിള്‍ ആങ്കിള്‍ ബ്രാക്കെറ്റ് (>> (U+00bb) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "നടുക്കുള്ള കുത്ത്" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "തെരച്ചില്‍ ദിശ:" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "കറുത്ത സമചതുരം ( '■' (U+25a0) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr " വെളുത്ത സമചതുരം ( '□' (U+25a1) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "കറുത്ത ഡയമണ്ഡ് ( '◆' (U+25c6) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "വെളുത്ത വൃത്തം ('○' (U+25cb) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr " കറുത്ത വൃത്തം ( '●' (U+25cf) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "വെളുത്ത ബുള്ളെറ്റ് ( '◦' (U+25e6) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "കറുത്ത സമചതുരം ( '■' (U+25a0) എന്ന അക്ഷരം)" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "അടിവര (_)" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "തിരസ്ചീനമായി നിര്‍ത്തുക" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "പ്രയോഗം" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "ശുന്യം" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "ബോള്‍ഡാക്കുക" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "ഓര്‍മ്മക്കുറിപ്പ് ചേര്‍ത്തിരിക്കുന്നു" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "ഓര്‍മ്മക്കുറിപ്പുകള്‍ സൂക്ഷിച്ചിരിക്കുന്നു" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "ഓര്‍മ്മക്കുറിപ്പുകള്‍ സൂക്ഷിക്കുവാന്‍ സാധ്യമായില്ല" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "ഇനി അതിരടയാളങ്ങളില്ല." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "ഇനി അതിരടയാളങ്ങളില്ല." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "ഗണനി ഡിസ്പ്ലേ കിട്ടിയില്ല" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ചിഹ്നം" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "ഒന്നുമില്ല " - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "അക്ഷരതെറ്റ്" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "സെല്‍ %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "തിരഞ്ഞെടുത്തവ " - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "തിരഞ്ഞെടുക്കാത്തവ " - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPTION" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "ഓര്‍മ്മക്കുറിപ്പുകള്‍ സൂക്ഷിക്കുവാന്‍ സാധ്യമായില്ല" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "സഹായത്തിനുള്ള ഈ സന്ദേശം കാണിക്കുക" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FILE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "ഉപയോക്താവ്‌ അഭിരുചി തിര‍‍ഞ്ഞെടുക്കുക ( വാക്യ പതിപ്പ് )" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "ഉപയോക്താവ്‌ അഭിരുചി തിര‍‍ഞ്ഞെടുക്കുക ( വാക്യ പതിപ്പ് )" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "https://groups.io/g/stormux ബഗുകള്‍ റിപോര്‍ട്ട് ചെയ്യുക." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "acute" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -#, fuzzy -msgid "Pasted contents from clipboard." -msgstr "നിലവില്‍ ഫ്ലാറ്റ് റിവ്യുവിനു കീ​ഴിലുള്ള വസ്തുക്കളെ ക്ലിപ്ബോര്‍ടിലേക്ക് പകര്‍ത്തപ്പെടും." - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "കൂടുതല്‍ എളുപത്തില്‍" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "%s ചാറ്റ് മുറിയില്‍ നിന്നുമുളള സന്ദേശം" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "പുതിയ ചാറ്റ് ടാബ് %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "ചാറ്റ് മുറിയുടെ പേര് പറയുവാന്‍ പാടില്ല." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "ചാറ്റ് മുറിയുടെ പേര് പറയുക." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "തെരഞ്ഞെടുക്കല്‍ സൂചന" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "നിര നീക്കി." - -#: src/cthulhu/messages.py:452 -#, fuzzy -msgctxt "content" -msgid "insertion start" -msgstr "റൂട്ട് പെയിന്‍" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "വാക്യ ദിശ" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "വലത് പരാന്‍ഥെസിസ് (')')" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "ചോദ്യം (? എന്ന ചിഹ്നം)" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "ടേബിളിന്റെ അവസാനം" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "ഒരു ടേബിളിലല്ല." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "തിരഞ്ഞെടുത്തിട്ടില്ലാത്തത് " - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "സ്വതവേയുള്ള ബട്ടണ്‍ %s ആകുന്നു" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "സ്വതവേയുള്ള ബട്ടണ്‍ %s ആകുന്നു" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "സ്വതവേയുള്ള ബട്ടണ്‍ %s ആകുന്നു" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " സബ്സ്ക്രിപ്റ്റ് %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " സൂപര്‍സ്ക്രിപ്ട് %s" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "ഒരു ടേബിളിലല്ല." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "തിരഞ്ഞെടുത്തിട്ടില്ലാത്തത് " - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും തിരഞ്ഞെടുത്ത രേഖ" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും തിരഞ്ഞെടുക്കാത്ത രേഖ" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയിലേക്ക് തിരഞ്ഞെടുത്ത രേഖ" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയിലേക്ക് തിരഞ്ഞെടുക്കാത്ത രേഖ" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "കാലി" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f കിലോബൈറ്റുകള്‍" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f മെഗാബൈറ്റുകള്‍" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "ഫയലുകള്‍‍ ലഭ്യമായില്ല." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "ഫ്ലാറ്റ് റിവ്യു നിലവിലെ വാക്കിന്റെ മുകളിലെ വാക്കിലേക്ക് നീക്കുപ്പെടും." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "ഫോര്‍മുലാ ഉണ്ട്" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "ഓര്‍ക്ക തിരയല്‍ ഡയലോഗ് തുറക്കുന്നു." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -#, fuzzy -msgid "opens listbox" -msgstr "ടാബ് ലിസ്റ്റ്" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "ഇപ്പോള്‍ തന്ന കീ %s ന് കൊടുത്തതാണ്" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "കീ ലഭ്യമാക്കിയിരിക്കുന്നു: %s. ഉറപ്പ് വരുത്തുന്നതിനായി enter അമര്‍ത്തുക." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "പുതിയ കീ: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "കീ ബൈന്‍ഡിങ് നീക്കം ചെയ്തിരിക്കുന്നു. ഉറപ്പ് വരുത്തുന്നതിനായി enter അമര്‍ത്തുക." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "കീ ബൈന്‍ഡിങ് നീക്കം ചെയ്തിരിക്കുന്നു." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "പുതിയ കീ നല്‍കുക" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "ഒന്നുമില്ല" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "അടുത്ത വാക്കിലേക്ക് പോകും." - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "വാചകം" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "_വാക്യം വെച്ച് പറയുക" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "വാക്ക്" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "അടുത്ത വാക്കിലേക്ക് പോകും." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr " കറുത്ത വൃത്തം ( '●' (U+25cf) എന്ന അക്ഷരം)" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "തിരശ്ചീനമായത്" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr " എന്ന ചിഹ്നം)" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "വലത് ആരോ" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "താഴോട്ട് പോകല്‍." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "വരിയുടെ ഉയരം" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "ആന്‍ഡ് (&)" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "മുകള്‍വര" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "സ്ക്വേര്‍ റൂട്ട് ( '√' (U+221a) എന്ന അക്ഷരം)" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "ക്യൂബ് റൂട്ട് ('∛' (U+221b) എന്ന അക്ഷരം)" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "റൂട്ട് പെയിന്‍" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "റൂട്ട് പെയിന്‍" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "റൂട്ട് പെയിന്‍" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "സബ്സ്ക്രിപ്റ്റ് 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "സൂപര്‍സ്ക്രിപ്ട് a ('ª' (U+00aa) എന്ന അക്ഷരം)" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "സബ്സ്ക്രിപ്റ്റ് 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "സൂപര്‍സ്ക്രിപ്ട് a ('ª' (U+00aa) എന്ന അക്ഷരം)" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "സൂപര്‍സ്ക്രിപ്ട് a ('ª' (U+00aa) എന്ന അക്ഷരം)" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "സൂപര്‍സ്ക്രിപ്ട് a ('ª' (U+00aa) എന്ന അക്ഷരം)" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "ടേബിള്‍" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "ട്രീ ടേബിള്‍" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "ലഭ്യമാകാത്തത്" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "പ്രവര്‍ത്തനരഹിതമാക്കി" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "പ്രവര്‍ത്തന സജ്ജമാക്കിയിരിക്കുന്നു" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "ആനിമേഷന്‍" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും താഴേക്ക തിരഞ്ഞെടുത്ത വരി" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും മുകളിലേക്ക് തിരഞ്ഞെടുത്ത വരി" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും താഴേക്ക തിരഞ്ഞെടുക്കാത്ത വരി" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും മുകളിലേക്ക് തിരഞ്ഞെടുക്കാത്ത വരി" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "തുടക്കം മുതല്‍ മുമ്പുള്ള കര്‍സറിന്‍റെ സൂചിക വരെ തിരഞ്ഞെടുത്ത വരി" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും അവസാനം വരെ തിരഞ്ഞെടുത്ത വരി" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ലിങ്ക്" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ഒരേ താള്‍" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ഒരേ സൈറ്റ്" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "മറ്റൊരു സൈറ്റ്" - -#: src/cthulhu/messages.py:1531 -#, fuzzy, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%s എന്ന ലിങ്ക് %s-ലേക്ക് നയിക്കുന്നു" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s ലിങ്ക്" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "സന്ദര്‍ശിച്ച %d കണ്ണി" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "മുകള്‍, താഴെ ആരോ കീ ഉപയോഗിച്ച് പട്ടിക നോക്കുക. എസ്കേപ്പ് ഉപയോഗിച്ച് പുറത്ത് കടക്കാം." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "എല്ലാ തത്സമയ പ്രദേശവും നിര്‍ത്തുന്നു" - -#: src/cthulhu/messages.py:1564 -#, fuzzy -msgid "live regions politeness levels restored" -msgstr "തത്സമയ പ്രദേശത്തിന്റെ " - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -#, fuzzy -msgid "setting live region to assertive" -msgstr "തത്സമയ പ്രദേശം ഉറപ്പിക്കുന്നു" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "തത്സമയ പ്രദേശം അറിയിപ്പുകള്‍ നിര്‍ത്തുന്നു" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "തത്സമയ പ്രദേശം അറിയിപ്പുകള്‍ മയപ്പെടുത്തുന്നു" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "തത്സമയ പ്രദേശം അറിയിപ്പുകള്‍ കാര്‍ക്കശ്യപ്പെടുത്തുന്നു" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "തത്സമയ പ്രദേശങ്ങളുടെ നിരീക്ഷ​ണം നിര്‍ത്തുന്നു" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "തത്സമയ പ്രദേശങ്ങളുടെ നിരീക്ഷ​ണം തുടങ്ങുന്നു" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "ഒരു തത്സമയ സന്ദേശവും സൂക്ഷിക്കില്ല" - -#: src/cthulhu/messages.py:1649 -#, fuzzy -msgid "Live region support is off" -msgstr "തത്സമയ പ്രദേശം " - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "കണ്ടെത്തിയില്ല" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "നിലവിലെ സ്ഥലം കണ്ടെത്താനായില്ല." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "ഓഫ്" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "ഓണ്‍" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "അക്ഷരത്തെറ്റുളള വാക്ക്:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "അക്ഷരത്തെറ്റുളള വാക്ക്: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "%s ആണ് സാഹചര്യം" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -#, fuzzy -msgid "Object mode." -msgstr "ഒബ്ജക്ട്" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "അടുത്ത വസ്തുവിലേക്ക് പോകും." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "മൌസ് ഓവര്‍ വസ്തു കണ്ടെത്താനായില്ല." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "മൌസ് അവലോകന മോഡിലേക്ക്..." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "പറയുന്നത് വീണ്ടും തുടങ്ങുന്നു." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "പിശക്‌: വസ്തുക്കളുടെ പട്ടിക തയ്യാറാക്കാനായില്ല." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d ശതമാനം." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "മുന്‍പുള്ള വാക്കിലേക്ക് പോകും." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "ഒരു പ്രയോഗത്തിനും ഫോക്കസ് ഇല്ല" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "ഒന്നിലും ശ്രദ്ധയില്ല" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "ഒരു പ്രയോഗത്തിനും ഫോക്കസ് ഇല്ല" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "ഇനി ബ്ളോക് ക്വാട്ടുകളില്ല." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "ഇനി ബട്ടനുകളില്ല" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "ഇനി ചെക്-ബോക്സുകളില്ല." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "ഇനി വലിയ വസ്തുക്കളില്ല." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "ഇനി ടേബിളുകളില്ല." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "ഇനി കോംബൊ-ബോക്സുകളില്ല." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "ഇനി എന്‍ട്രികളില്ല." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "ഇനി തലക്കെട്ടുകളില്ല." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "ഘട്ടം %d എന്ന തലക്കെട്ടുകള്‍ ഇനിയില്ല." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "ഇനി ടേബിളുകളില്ല." - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "ഇനി ടേബിളുകളില്ല." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "ഇനി അതിരടയാളങ്ങളില്ല." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "ഇനി കണ്ണികളില്ല." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "ഇനി പട്ടികകളില്ല." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "ഇനി തത്സമയ പ്രദേശങ്ങള്‍ ഇല്ല." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "ഇനി പാരഗ്രാഫുകളില്ല." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "ഇനി റേഡിയോ ബട്ടനുകളില്ല" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "ഇനി വേര്‍തിരിവുകളില്ല." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "ഇനി ടേബിളുകളില്ല." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "ഇനി സന്ദര്‍ശിക്കാത്ത കണ്ണികളില്ല." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "ഇനി സന്ദര്‍ശിച്ച കണ്ണികളില്ല." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "തിരഞ്ഞെടുത്തിട്ടില്ലാത്തത് " - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "ഇനി കണ്ണികളില്ല." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "അറിയിപ്പ്" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "താഴെ" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "മുകളില്‍" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "അറിയിപ്പു് സന്ദേശങ്ങള്‍ ഒന്നുമില്ല" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "വാക്ക്" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "ഓഫ് ചെയ്തിരിക്കുന്നു" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ഓണ്‍ ചെയ്തിരിക്കുന്നു" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "ലഭ്യമാക്കുന്നു. ദയവായി കാത്തിരിക്കുക." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "ലഭ്യമാക്കി കഴിഞ്ഞു." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും തിരഞ്ഞെടുത്ത വരി" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയിലേക്ക് തിരഞ്ഞെടുത്ത പേജ്" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും തിരഞ്ഞെടുക്കാത്ത താളിന്റെ ഭഗം" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയിലേക്ക് തിരഞ്ഞെടുക്കാത്ത താളിന്റെ ഭഗം" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും തിരഞ്ഞെടുത്ത ഖണ്ഡിക" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും തിരഞ്ഞെടുത്ത ഖണ്ഡിക" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും തിരഞ്ഞെടുക്കാത്ത ഖണ്ഡിക" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "കര്‍സറിന്‍റെ സൂചികയില്‍ നിന്നും തിരഞ്ഞെടുക്കാത്ത ഖണ്ഡിക" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"നിങ്ങള്‍ ഓര്‍ക്ക അഭിരുചി ഡയലോഗ് മുമ്പേ തന്നെ തുറന്നിരിക്കുന്നു. ദയവായി അത് അവസാനിപ്പിച്ച ശേ‍ഷം " -"പുതിയത് തുറക്കുക." - -#: src/cthulhu/messages.py:2132 -#, fuzzy, python-format -msgid "slide %(position)d of %(count)d" -msgstr "%(count)d പുറങ്ങളില്‍ %(position)d ത്തെ പുറം." - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "പ്രോഫൈല്‍ %s എന്നാക്കുന്നു." - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "പ്രോഫൈലുകള്‍ ലഭ്യമായില്ല." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "പുരോഗതി സൂചിക %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "എല്ലാം" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "നിര്‍ത്തടയാളനില എല്ലാം എന്നാക്കുന്ന." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "മിക്കവാറും" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "നിര്‍ത്തടയാളനില മിക്കവാറും എന്നാക്കുന്ന." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "ഒന്നുമില്ല" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "നിര്‍ത്തടയാളനില ഒന്നുമില്ല എന്നാക്കുന്ന." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "ചിലതു്" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "നിര്‍ത്തടയാളനില ചിലതു് എന്നാക്കുന്ന." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "തിരയുന്നു." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "തിരച്ചില്‍ പൂര്‍ത്തിയായിരിക്കുന്നു." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu യൂസര്‍ ക്രമീകരണങ്ങള്‍ വീണ്ടും ലോഡ് ചെയ്തിരിക്കുന്നു." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "തിരഞ്ഞെടുത്തവ" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "നിര നീക്കി." - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "തെരഞ്ഞെടുക്കല്‍ സൂചന" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "തിരഞ്ഞെടുക്കാത്തവ " - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "പറയുന്നത് താത്കാലികമായി നിര്‍ത്തുന്നു." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "പറയുന്നത് വീണ്ടും തുടങ്ങുന്നു." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "കൂടുതല്‍ എളുപത്തില്‍" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "കൂടുതല്‍ പതുക്കെ" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "കൂടുതല്‍ മുകളിലേക്ക്" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "കൂടുതല്‍ താഴേക്ക്" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "കൂടുതല്‍ എളുപത്തില്‍" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_റേറ്റ്:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "ശബ്ദം:(_l)" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "സ്പീച്ച് ഡിസ്പാച്ചര്‍" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "സ്പീച്ച് ഡിസ്പാച്ചര്‍" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "സംഭാഷണം ലഭ്യമല്ല." - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "സംഭാഷണം ലഭ്യമല്ല." - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "പറയുന്നത് വീണ്ടും തുടങ്ങുന്നു." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "ഓര്‍മ്മക്കുറിപ്പുകള്‍ സൂക്ഷിക്കുവാന്‍ സാധ്യമായില്ല" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "കുത്ത് കുത്ത് കുത്ത് " - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "സംഭാഷണം ലഭ്യമല്ല." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "കണ്ടെത്തിയില്ല" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "സ്റ്റ്രിങ്ങ് കണ്ടെത്താനായില്ല" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "സ്റ്റ്രിങ്ങ് കണ്ടെത്താനായില്ല" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "കണ്ടെത്തിയില്ല" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "നിര %(row)d, വരി %(column)d." - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "ടേബിളിന്റെ അവസാനം" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "കളം സംസാരിക്കുക" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "നിര സംസാരിക്കുക" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "സമാനമല്ല" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "ഒരു ടേബിളിലല്ല." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "കോളങ്ങള്‍ പുനഃക്രമീകരിച്ചു" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "നിരകള്‍ പുനഃക്രമീകരിച്ചു" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "നിര %d" - -#: src/cthulhu/messages.py:2420 -#, fuzzy, python-format -msgid "column %(index)d of %(total)d" -msgstr "കോളം %d, %d-ഇല്‍ നിന്നും" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "കോളത്തിന്റെ അടിത്തട്ട്." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "കോളത്തിന്റെ ആരംഭം." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "തിരഞ്ഞെടുക്കാത്തവ " - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "തിരഞ്ഞെടുക്കാത്തവ " - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "വരി %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "%(total)d നിരകളില്‍ %(index)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "നിരയുടെ തുടക്കം." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "നിരയുടെ അവസാനം." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "നിര നീക്കി." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "അവസാം വരി നീക്കി." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "നിര ചേര്‍ത്തു." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "പട്ടികയുടെ അവസാനം നിര ചേര്‍ത്തു." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "നിര നീക്കി." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "തിരഞ്ഞെടുക്കാത്തവ " - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "തിരഞ്ഞെടുത്തവ " - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "തിരഞ്ഞെടുക്കാത്തവ " - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H മണിക്കൂറുക, %M നിമിഷങ്ങള്‍ പിന്നെ %S " - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H മണിക്കൂറുക പിന്നെ %M നിമിഷങ്ങളും." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "യൂണികോഡ് മൂല്യാങ്കം %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "ശുന്യസ്ഥാനം" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "താഴോട്ട് പോകല്‍." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "മുകളിലേക്ക് പോകല്‍." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 വസ്തുക്കള്‍" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, fuzzy, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "അറ " -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "വരി %d, നിര %d" -msgstr[1] "വരി %d, നിര %d" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d അക്ഷരം വളരെ വലുത്" -msgstr[1] "%d അക്ഷരങ്ങള്‍ വളരെ വലുത്" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d ഡയലോഗ്)" -msgstr[1] "(%d ഡയലോഗുകള്‍)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d ശ്രദ്ധയില്ലാത്ത ഡയലോഗ്" -msgstr[1] "%d ശ്രദ്ധയില്ലാത്ത ഡയലോഗുകള്‍" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d ബൈറ്റ്" -msgstr[1] "%d ബൈറ്റുകള്‍" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ഫയല്‍ ലഭ്യമായി" -msgstr[1] "%d ഫയലുകള്‍ ലഭ്യമായി" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d ഫോറം" -msgstr[1] "%d ഫോറമുകള്‍" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d തലക്കെട്ട്" -msgstr[1] "%d തലക്കെട്ടുകള്‍" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d വസ്തു" -msgstr[1] "%d വസ്തുക്കള്‍" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "ട്രേഡ്മാര്‍ക്ക് ( '™' (U+2122) എന്ന അക്ഷരം)" -msgstr[1] "ട്രേഡ്മാര്‍ക്ക് ( '™' (U+2122) എന്ന അക്ഷരം)" - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d ഫയല്‍ ലഭ്യമായി" -msgstr[1] "%d ഫയലുകള്‍ ലഭ്യമായി" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "ഇനി ബ്ളോക് ക്വാട്ടുകളില്ല." -msgstr[1] "ഇനി ബ്ളോക് ക്വാട്ടുകളില്ല." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." -msgstr[1] "ടേബിളില്‍ നിന്നും പുറത്ത് കടക്കുന്നു." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d വസ്തുവുള്ള പട്ടിക" -msgstr[1] "%d വസ്തുക്കളുള്ള പട്ടിക" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "%d വസ്തുവുള്ള പട്ടിക" -msgstr[1] "%d വസ്തുക്കളുള്ള പട്ടിക" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "മൂല്യം" -msgstr[1] "മൂല്യം" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "%d വരി ഉള്ള പട്ടിക" -msgstr[1] "%d വരികള്‍ ഉള്ള പട്ടിക" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d നിര" -msgstr[1] "%d നിരകള്‍" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "%d വരി ഉള്ള പട്ടിക" -msgstr[1] "%d വരികള്‍ ഉള്ള പട്ടിക" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d സന്ദേശം.\n" -msgstr[1] "%d സന്ദേശങ്ങള്‍.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d ശതമാനം." -msgstr[1] "%d ശതമാനം." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "രേഖ വായനയുടെ %d ശതമാനം" -msgstr[1] "രേഖ വായനയുടെ %d ശതമാനം" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "പിക്സല്‍സ്" -msgstr[1] "പിക്സല്‍സ്" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s അക്ഷരം" -msgstr[1] "%(count)d %(repeatChar)s അക്ഷരങ്ങള്‍" - -#: src/cthulhu/messages.py:2784 -#, fuzzy, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%d വസ്തു തിരഞ്ഞെടുത്തു, മൊത്തം %d" -msgstr[1] "%d വസ്തുക്കള്‍ തിരഞ്ഞെടുത്തു, മൊത്തം %d" - -#: src/cthulhu/messages.py:2793 -#, fuzzy, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d സ്വതവേയുള്ള ഓര്‍ക്ക കുറുക്കുവഴി കണ്ടെത്തി." -msgstr[1] "%d സ്വതവേയുള്ള ഓര്‍ക്ക കുറുക്കുവഴികള്‍ കണ്ടെത്തി." - -#: src/cthulhu/messages.py:2801 -#, fuzzy, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%s ന് ഓര്‍ക്ക കുറുക്കുവഴികളില്ല." -msgstr[1] "%s ന് ഓര്‍ക്ക കുറുക്കുവഴികളില്ല." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d ശുന്യസ്ഥാനം" -msgstr[1] "%d ശുന്യസ്ഥാനം" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d ടാബ്" -msgstr[1] "%d ടാബ്" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d ടേബിള്‍" -msgstr[1] " ടേബിളുകള്‍ %d" - -#: src/cthulhu/messages.py:2829 -#, fuzzy -msgid "table of unknown size" -msgstr "എച്ടിഎംഎല്‍ ഉള്ളടക്കം" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "%d വരി ഉള്ള പട്ടിക" -msgstr[1] "%d വരികള്‍ ഉള്ള പട്ടിക" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%d വരി ഉള്ള പട്ടിക" -msgstr[1] "%d വരികള്‍ ഉള്ള പട്ടിക" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "%d വരി ഉള്ള പട്ടിക" -msgstr[1] "%d വരികള്‍ ഉള്ള പട്ടിക" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "സന്ദര്‍ശിക്കാത്ത %d കണ്ണി" -msgstr[1] "സന്ദര്‍ശിക്കാത്ത %d കണ്ണികള്‍" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "സന്ദര്‍ശിച്ച %d കണ്ണി" -msgstr[1] "സന്ദര്‍ശിച്ച %d കണ്ണികള്‍" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "ടോഗ്ള്‍" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(total)d ലില്‍ %(index)d നില്ക്കുന്നു" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(total)d ലില്‍ %(index)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "ലെവല്‍ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ട്രീ നില %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "ട്രീ ലവല്‍ %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "ചോദ്യം (? എന്ന ചിഹ്നം)" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "അടുത്ത കോബോ ബോക്സിലേക്ക് പോകും." - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "എച്ടിഎംഎല്‍ ഉള്ളടക്കം" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "വാക്ക്" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "കോളന്‍ (:)" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "മുകള്‍വര" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "വാക്യ ദിശ" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "ഖണ്ഡിക" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "വാക്ക്" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "ഇണ്ടെന്റ്" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "വാക്യ ദിശ" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "ടാബ് ലിസ്റ്റ്" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "കോട്ട്സ് " - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "എച്ടിഎംഎല്‍ ഉള്ളടക്കം" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s level %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "തിരശ്ചീനമായത്" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr " എന്ന ചിഹ്നം)" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "തിരശ്ചീനമായത്" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "തിരസ്ചീനമായി നിര്‍ത്തുക" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "തിരശ്ചീനമായത്" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "തിരസ്ചീനമായി നിര്‍ത്തുക" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "മോഡ് സ്വിച്ച്" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "പ്രതിരൂപത്തിനുള്ള പാനല്‍" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "എച്ടിഎംഎല്‍ ഉള്ളടക്കം" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "ആനിമേഷന്‍" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "എച്ടിഎംഎല്‍ ഉള്ളടക്കം" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "ആനിമേഷന്‍" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "തിരയുന്നു." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "സന്ദര്‍ശിച്ച %d കണ്ണി" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "സ്പിന്‍ ബട്ടണ്‍" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "കുറച്ചു കാണിക്കുക" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "നീട്ടം കൂട്ടിയത്‌" - -#: src/cthulhu/object_properties.py:511 -#, fuzzy -msgid "has long description" -msgstr "തലക്കെട്ട്" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "തിരശ്ചീനമായത്" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "നേരെയുള്ളവ" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "തിരഞ്ഞെടുത്തവ" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "തിരഞ്ഞെടുക്കാത്തവ" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "ഓണ്‍ ചെയ്തിരിക്കുന്നു" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "ഓഫ് ചെയ്തിരിക്കുന്നു" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "പകുതി തെരഞ്ഞെടുത്തവ" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "അമര്‍ത്തിയവ" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "അമര്‍ത്താത്തവ" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "തിരഞ്ഞെടുത്തിട്ടില്ലാത്തത് " - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "തിരഞ്ഞെടുത്തവ" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "തിരഞ്ഞെടുത്തിട്ടില്ലാത്തത് " - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "തിരഞ്ഞെടുത്തിട്ടില്ലാത്തത് " - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "സന്ദര്‍ശിച്ച" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "സന്ദര്‍ശിക്കാത്ത" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ഗ്രേ ആക്കിയിരിക്കുന്നത്" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "വായന മാത്രം" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "rdonly" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "ആവശ്യമാണു്‌" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "അനവധി വസ്തുക്കള്‍ തിരഞ്ഞെടുക്കുവാന്‍ സാധ്യമായത്" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "അസാധുവായ" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "അസാധു" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "അക്ഷരതെറ്റ്" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "അക്ഷരതെറ്റ്" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "അസാധുവായ" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "കണ്ടുപിടിക്കുക" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "സ്ക്രീന്‍ വായനക്കാരന്‍ തിരയല്‍ ഡയലോഗ്" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_അടയ്ക്കുക" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_കണ്ടുപിടിക്കുക" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "ഇതു് _തെരയുക:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "ഇതു് തെരയുക:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "ജാലകത്തിന്റെ _മുകള്‍ഭാഗം " - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "ജാലകത്തിന്റെ മുകള്‍ഭാഗം" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "തുടങ്ങേണ്ടത്:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "ചുറ്റും _ഒതുക്കുക" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "_പുറകോട്ട് തെരയുക" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "തെരച്ചില്‍ ദിശ:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "വലിയചെറിയക്ഷരവ്യത്യാസം _കണക്കിലെടുക്കുക (ഇംഗ്ലീഷിന് മാത്രം)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "വാക്ക് _പൂര്‍ണ്ണമായുണ്ടെങ്കില്‍ മാത്രം" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "തലക്കെട്ട്" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "സാധാരണ" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "വലിയ അക്ഷരം" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "കണ്ണി" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "സിസ്റ്റം" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "പ്രയോഗം" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "ജാലകം" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_സഹായം" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "കംപ്യൂട്ടറില്‍ സൂക്ഷിക്കുക (_A)" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_ലാപ്ടോപ്പ്" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "കീബോര്‍ഡ് വിന്യാസം" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "സജീവ _പ്രൊഫൈല്‍:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "തുടങ്ങും പ്രെഫൈല്‍" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_ലോഡ്" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "പേരു് മാറ്റി‌ സൂക്ഷിയ്ക്കുക (_A)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "പ്രൊഫൈലുകള്‍" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_ഉള്ള സൂചനകള്‍" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "_മൌസിനടിയിലെ കാര്യം പറയുക" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "മൌസ്" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_സമയ രീതി:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "_തിയതി രീതി:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "സമയവും തീയതിയും" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "എല്ലാം _പറയു" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "ബ്രൈലി സൂചന" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "തരംഗദൈര്‍ഘ്യം (നിമിഷങ്ങള്‍)" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "പ്രയോഗം" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "പുരോഗതി കാണിക്കുന്ന ബാറിന്റെ പുതുക്കിയ വിവരങ്ങള്‍" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "സാധാരണ" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "ശബ്ദം:(_l)" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_റേറ്റ്:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "വ്യക്തി: (_P)" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "ഭാഷ" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "സംസാര _സിസ്റ്റം:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "ശബ്ദ തരം: (_V)" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -#, fuzzy -msgid "_Capitalization style:" -msgstr "വല്യക്ഷര ശൈലി ആവൃത്തിയില്‍ അടുത്തതിലേക്ക് പോകപ്പടും." - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "ശബ്ദ തരം ക്രമീകരണങ്ങള്‍: (_V)" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "ആഗോള ശബ്ദ ക്രമീകരണങ്ങള്‍: (_V)" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "ശബ്ദം" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "സംസാരം _ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "വെര്‍ബോസ് (_b)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "വെര്‍ബോസിറ്റി" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "എല്ലാം (_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "ഉച്ചാരണ നില" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "കാണുന്നത് മാത്രം പറയുക" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "ഒഴിഞ്ഞ വരികള്‍ പറയുക" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "ടൂട്ടോറിയല്‍ സന്ദേശങ്ങള്‍ പറയുക" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "ഒഴിഞ്ഞ വരികള്‍ പറയുക" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -#, fuzzy -msgid "Announce _lists during navigation" -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -#, fuzzy -msgid "Announce _tables during navigation" -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "തലക്കെട്ട്" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "പറയപ്പെട്ട സന്ദര്‍ഭം" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "സംഭാഷണം" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "ബ്രൈലി _പിന്‍തുണ ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "സംഗ്രഹിച്ച ജോലി നാമം(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "വരിയുടെ അവസാനം എന്ന അടയാളം ദുര്‍ബലപ്പെടുത്തുക" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "_വാക്ക് വെച്ച് പറയുക" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "ഡിസ്‌പ്ലെ ക്രമീകരണങ്ങള്‍" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_ഒന്നുമില്ല" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "തെരഞ്ഞെടുക്കല്‍ സൂചന" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "കണ്ണി സൂചന" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "ആഗോള ശബ്ദ ക്രമീകരണങ്ങള്‍: (_V)" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ബ്രെയിലി" - -#: src/cthulhu/cthulhu-setup.ui:2780 -#, fuzzy -msgid "Enable _key echo" -msgstr "കീ എഖോ പ്രവര്‍ത്തന സജ്ജമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "_മോഡിഫയര്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "_ഫങ്ഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "സംസാരം _ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "_മോഡിഫയര്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "_ഫങ്ഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "_പ്രവര്‍ത്തന കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "_നാവിഗേഷന്‍ കീകള്‍ ലഭ്യമാക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "_വാക്ക് വെച്ച് പറയുക" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "_വാക്യം വെച്ച് പറയുക" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "കീ പറയല്‍" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "ഓര്‍ക്ക മോഡിഫയര്‍ കീകള്‍:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "കീ ബന്ധങ്ങള്‍" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "ഉച്ചാരണ നിഘണ്ടു" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_പുതിയ എന്‍ട്രി" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_നീക്കം ചെയ്യുക" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "ഉച്ചാരണം" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "എല്ലാം _പറയു" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_ഒന്നും പറയണ്ട" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_വീണ്ടും ക്രമികരിക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "ടെക്സ്റ്റ് സവിശേഷതകള്‍" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "_താഴേക്ക് നീങ്ങുക" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "ഒന്ന് _താഴേക്ക് നീക്കുക" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "ഒന്ന് _മുകളിലേക്ക് നീക്കുക" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "_മുകളിലേക്ക് നീങ്ങുക" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "തെരഞ്ഞെടുത്ത സവിശേഷതകള്‍ ക്രമീകരിക്കുക" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "ബ്രൈലി സൂചന" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "ടെക്സ്റ്റ് സവിശേഷതകള്‍" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "താഴ്‌ന്ന" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "ഭാഷ" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "യെന്‍" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "പശ്ചാത്തല നിറം" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "പശ്ചാത്തല മുഴുവന്‍ ഉയരം" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "വാക്യ ദിശ" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "മാറ്റാവുന്നത്" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "അക്ഷര കുടുംബ നാമം" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "പൂര്‍വ്വതല നിറം" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "ലിപി പ്രതീതി " - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "ഇണ്ടെന്റ്" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "തെറ്റ്" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "കാണാനാവാത്തത്" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "ജസ്റ്റിഫിക്കേഷന്‍" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "ഭാഷ" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "ഇടത് മാര്‍ജിന്‍" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "വരിയുടെ ഉയരം" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "പാരഗ്രാഫ് രീതി" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "വരിയുടെ മുകളിലെ പിക്സലുകള്‍" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "വരിയുടെ താഴത്തെ പിക്സലുകള്‍" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "ആവരണത്തിനുള്ളിലെ പിക്സലുകള്‍" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "വലത് മാര്‍ജിന്‍" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "താഴ്-വരിയില്‍ നിന്നുള്ള ഉയരം" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "അക്ഷരങ്ങളുടെ സ്കേല്‍" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "പദാവലി വലിപ്പം" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "നീട്ടി വലിക്കല്‍" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "രീതി" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "വചന ചമയം" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "വചന നിഴല്‍" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "അടിവര" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "തിരസ്ചീനമായി നിര്‍ത്തുക" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "തൂക്കം" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "ആവരണ മോഡ്" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "എഴുത്ത് മോഡ്" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ഒന്നുമില്ല " - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "എന്‍ഗ്രേവ്" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "എംബോസ്" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "പുറംവര" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "മുകള്‍വര" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "ബ്ലിങ്ക്" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "കറുപ്പ്" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "ഒറ്റ" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "ഇരട്ട" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "താഴ്‌ന്ന" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "അക്ഷരം" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "വാക്ക്" - -#: src/cthulhu/text_attribute_names.py:452 -#, fuzzy -msgctxt "textattr" -msgid "word char" -msgstr "വാക്ക് അക്ഷരം" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "ഇടത്" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "വലത്" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "നടുക്ക്" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "ജസ്റ്റിഫിക്കേഷനില്ല" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "ഫില്‍" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "അത്യധികമായി നീട്ടം കുറച്ച്" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "അതിരുകടന്ന നീട്ടം കുറച്ച്" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "നീട്ടം കുറച്ച്" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "നീട്ടം പകുതി കുറച്ച്" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "സാധാരണ" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "നീട്ടം പകുതി കൂട്ടി" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "നീട്ടം കൂട്ടി" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "അതിരുകടന്ന വിപുലീകരിച്ച" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "അത്യധികമായി വിപുലീകരിച്ച" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "വളഞ്ഞ" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "ഇറ്റാലിക്ക് (ചരിഞ്ഞു്‌)" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "സാധാരണ" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "ടെക്സ്റ്റ് ഭാഗം" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "തലക്കെട്ട് " - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "അടിസ്ഥാന വരി" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "സൂപ്പര്‍" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "മുകള്‍" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "ടെക്സ്റ്റ് - മുകള്‍" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "നടുക്കുളള" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "താഴെ" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "ടെക്സ്റ്റ് -താഴെ" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "inherit" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "സോളിഡ്" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "അക്ഷരതെറ്റ്" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"വിപുലീകരിക്കാന്‍ സ്പേസ് അമര്‍ത്തുക, പിന്നെ അപ്പു് ഉം ഡൌണ് ഉം ഉപയോഗിച്ച് ഒരു വസ്തു തിരഞ്ഞെടുക്കുക." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "ചെറിയ വിന്‍ഡോകളിലേക്ക് ശ്രദ്ധ കൊടുക്കാന്‍ alt+f6 അമര്‍ത്തുക." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "സിസ്റ്റത്തിലെ മെനുകള്‍ എടുക്കാന്‍ alt+f1 അമര്‍ത്തുക." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "അപ്പ് പിന്നെ ഡൌണ്‍ കീ ഉപയോഗിച്ച് ഒരു വസ്തു തിരഞ്ഞെടുക്കുക." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "ചുരുക്കുന്നതിനായി ഷിഫ്റ്റും ലെഫ്റ്റും കീ അമര്‍ത്തുക." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "വിപുലീകരിക്കാന്‍ ഷിഫ്റ്റും റൈറ്റും കീ അമര്‍ത്തുക." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "പ്രയോഗക്ഷമമാക്കാന്‍ റിട്ടേണ്‍ അമര്‍ത്തുക." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "വാചകം ടൈപ്പ് ചെയ്യുക." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "ലെഫ്റ്റും റൈറ്റും കീകളുപയോഗിച്ച് മറ്റു് ടാബുകള്‍ കാണാം." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "പ്രയോഗക്ഷമമാക്കാന്‍ സ്പേസ് അമര്‍ത്തുക." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"അപ്പ് പിന്നെ ഡൌണ്‍ കീ ഉപയോഗിച്ച് ഒരു മൂല്യം തിരഞ്ഞെടുക്കുക. അല്ലെങ്കില്‍ ആഗ്രഹിക്കുന്ന സംഖ്യ ടൈപ്പ് " -"ചെയ്യുക." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "ആരോ കീകളുപയോഗിച്ച് മാറ്റുക." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"പരതുന്നതിനായി ലെഫ്റ്റോ റൈറ്റോ കീകളുപയോഗിക്കുക. വസ്തുവിലൂടെ പോകാന്‍ അപ്പ് അല്ലെങ്കില്‍ ഡൌണ്‍ " -"അമര്ത്തുക." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "സബ് മെനുവില്‍ കടക്കാന്‍ റൈറ്റ് ആരോ അമര്‍ത്തുക." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"കുറക്കുന്നതിനായി ലെഫ്റ്റ് അരോ അമര്‍ത്തുക, കൂട്ടുന്നതിനായി റൈറ്റ് അരോ അമര്‍ത്തുക. ഏറ്റവും കുറഞ്ഞതിലേക്ക് " -"പോകാന്‍ ഹോം അമര്‍ത്തുക, പരമാവധിയിലേക്ക് പോകാന്‍ എന്റ് അമര്‍ത്തുക." diff --git a/po/mr.po b/po/mr.po deleted file mode 100644 index 9869b3c..0000000 --- a/po/mr.po +++ /dev/null @@ -1,9586 +0,0 @@ -# translation of mr.po to Marathi -# This file is distributed under the same license as the PACKAGE package. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. -# Rahul Bhalerao , 2006. -# -msgid "" -msgstr "" -"Project-Id-Version: mr\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2006-08-13 17:37+0530\n" -"Last-Translator: Rahul Bhalerao \n" -"Language-Team: Marathi\n" -"Language: mr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.9.1\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "वर्धक भिंग" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -#, fuzzy -msgid "anim" -msgstr "ऍनिमेशन" - -#: src/cthulhu/braille_rolenames.py:57 -#, fuzzy -msgid "arw" -msgstr "बाण" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -#, fuzzy -msgid "icn" -msgstr "icon" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "डायल" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "काढा" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -#, fuzzy -msgid "lnk" -msgstr "दुवा" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "रेडिओ" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -#, fuzzy -msgid "cll" -msgstr "रकाना" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -#, fuzzy -msgid "tre" -msgstr "वृक्ष" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "स्पेस" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "नवीओळ" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "टॅब" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "चकित" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "अवतरण" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "डॉलर" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "टक्के" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "आणि" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrophe" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "डावा मधुकंस" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "तारा" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "अधिक" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "स्वल्पविराम" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "डॅश" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "बिंदू" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slash" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "विसर्ग" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "अर्धविराम" - -#: src/cthulhu/chnames.py:126 -#, fuzzy -msgid "less" -msgstr "पेक्षा कमी" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "बरोबर" - -#: src/cthulhu/chnames.py:134 -#, fuzzy -msgid "greater" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "प्रश्न" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "डावा कंस" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "backslash" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "उजवा कंस" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "कॅरेट" - -#: src/cthulhu/chnames.py:162 -#, fuzzy -msgid "underline" -msgstr "नवीओळ" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "left brace" - -#: src/cthulhu/chnames.py:174 -#, fuzzy -msgid "vertical bar" -msgstr "उभी रेषा" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "right brace" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "कार्यस्थळ" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -#, fuzzy -msgid "cents" -msgstr "टक्के" - -#: src/cthulhu/chnames.py:199 -#, fuzzy -msgid "pounds" -msgstr "पौंड" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -#, fuzzy -msgid "broken bar" -msgstr "मेनू पट्टी" - -#: src/cthulhu/chnames.py:215 -#, fuzzy -msgid "section" -msgstr "प्रश्न" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "डावा कंस" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -#, fuzzy -msgid "registered" -msgstr "केंद्रीय" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -#, fuzzy -msgid "mu" -msgstr "mnu" - -#: src/cthulhu/chnames.py:275 -#, fuzzy -msgid "paragraph marker" -msgstr "परिच्छेद" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "टर्मिनल" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "उजवा कंस" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -#, fuzzy -msgid "a tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -#, fuzzy -msgid "n tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -#, fuzzy -msgid "o tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -#, fuzzy -msgid "o stroke" -msgstr "apostrophe" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "डॅश" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "उजवा शिफ्ट" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -#, fuzzy -msgid "per mille" -msgstr "ब्रैल" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -#, fuzzy -msgid "check mark" -msgstr "check menu" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "डावा मधुकंस" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "डावा मधुकंस" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "क्लिक् वर." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "क्लिक् वर." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "am I." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "am I." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "status bar" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "क्लिक् वर." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "क्लिक् वर." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "क्लिक् वर." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "क्लिक् वर." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "क्लिक् वर." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "क्लिक् वर." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "दाबा." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "भाष्य सिंथेसाइजर(_z):" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "a." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "उलटवा चाा." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "उलटवा चाा." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "तळ:" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "चाा." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "निर्देशिका बटन" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "बटन उलटे करा" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "अधिक प्रदर्शन पर्याय" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "check box" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "combo box" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l container" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l container" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "internal frame" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "internal frame" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "अधिक प्रदर्शन पर्याय" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr " संदर्भ आहे " - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr " संदर्भ आहे " - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "चाा" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "परिच्छेद" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "रेडिओ बटन" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "रेडिओ बटन" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "विभाजक" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "tree table" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "tree table" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "उजवा control" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "ToggleButton" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "कार्यान्वित" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "करडे" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr " स्क्रीन" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "right brace" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "उजवा control" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "right brace" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "उजवा alt" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "नवीओळ" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "प्रतिमा" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "करडे" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr " स्क्रीन" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "टॅब" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "पांढरा स्पेस" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "पांढरा स्पेस" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "चिन्ह" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "काहीच नाही" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "स्पेलचेक:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -#, fuzzy -msgid "Default Synthesizer" -msgstr "भाष्य सिंथेसाइजर(_z):" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "कार्यान्वित" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "कार्यान्वित" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "स्वल्पविराम" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "मुलभूत" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "अनुप्रयोग" - -#: src/cthulhu/guilabels.py:296 -#, fuzzy -msgid "Braille Bindings" -msgstr "ब्रैल" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -#, fuzzy -msgid "Unbound" -msgstr "पौंड" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -#, fuzzy -msgid "_Desktop" -msgstr "DesktopIcon" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu प्राधान्यता" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -#, fuzzy -msgid "Speak" -msgstr "बोला" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "सर्व(_A)" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "खिडकी" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "काहीच नाही(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "काही(_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "सर्वाधिक(_o)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -#, fuzzy -msgid "Sentence" -msgstr "केंद्रीय" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "अवतरण" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "बटन" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "अनुप्रयोग" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "combo box" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "प्रश्न" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "शिर्षक" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "प्रतिमा" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "लेबल" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "यादी" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "परिच्छेद" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "निवडले" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "पाठ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "अवतरण" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "बटन" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "combo box" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "प्रतिमा" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "यादी" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "परिच्छेद" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "तक्ता" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "मुलभूत" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "हायपरलिंक" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "मोठी लिपी" - -#: src/cthulhu/guilabels.py:852 -#, fuzzy -msgid "Speech Dispatcher" -msgstr "भाष्य अकार्यान्वित." - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "स्पेलचेक:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "बोला" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "सतर्क" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "डावा control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "डावा शिफ्ट" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "डावा alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "डावा control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "उजवा शिफ्ट" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "उजवा alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "उजवा control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "डावा मेटा" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "उजवा मेटा" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "स्पेस" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "केंद्रीय" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "page down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "डावा alt" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "उजवा alt" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "डावा मधुकंस" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "मेनू" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "आणि" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "apostrophe" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "कार्यस्थळ" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "डावा मधुकंस" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "बाण" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "बाण" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "उजवा control" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "पेक्षा कमी" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "बिंदू" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "उभी रेषा" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "autocomplete" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "रिकामा" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "अधिक" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "विभाजक" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "प्रमाणीय" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "उजवा alt" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "layered pane" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "उभी रेषा" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "विभाजक" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "प्रश्न" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "internal frame" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "प्रमाणीय" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "बरोबर" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "बरोबर" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "बरोबर" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "पेक्षा कमी" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "पेक्षा कमी" - -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -#, fuzzy -msgctxt "math symbol" -msgid "not less than" -msgstr "पेक्षा कमी" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "दाबले नाही" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "बरोबर" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "उजवा मेटा" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "left tab" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "दाबले नाही" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "प्रतिमा" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "internal frame" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "उजवा alt" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "right brace" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "विभाजक" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "पेक्षा कमी" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:2025 -#, fuzzy -msgctxt "math symbol" -msgid "very much less than" -msgstr "पेक्षा कमी" - -#: src/cthulhu/mathsymbols.py:2028 -#, fuzzy -msgctxt "math symbol" -msgid "very much greater than" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "पेक्षा कमी" - -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "पेक्षा अधिक" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "उभी रेषा" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "डावा मधुकंस" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "डावा alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "उजवा alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "left brace" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "left brace" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "डावा कंस" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "उजवा कंस" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "पांढरा स्पेस" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "पांढरा स्पेस" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "पांढरा स्पेस" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "उभी रेषा" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "कोरा" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "भाष्य कार्यान्वित." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "icon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, fuzzy, python-format -msgid "Cell %s" -msgstr "रकाना" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "निवडले" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "न निवडलेले" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -#, fuzzy -msgid "Set up user preferences (text version)" -msgstr "-t, --text-setup उपयोक्ता प्राधान्यता निर्धारित करा(पाठ आवृत्ती)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "-t, --text-setup उपयोक्ता प्राधान्यता निर्धारित करा(पाठ आवृत्ती)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "त्रुटी अहवाल येथे द्या https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "वेगवान" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "प्रश्न" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "h t m l container" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "h t m l container" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "निवडले नाही" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "निवडले नाही" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -#, fuzzy -msgid "Dynamic column header cleared." -msgstr "column header" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "रिकामा" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "संवाद" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "पॉपअप मेनू" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, fuzzy, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "दाबा." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -#, fuzzy -msgid "Key binding deleted. Press enter to confirm." -msgstr "दाबा." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "काहीच नाही" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "केंद्रीय" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "गुप्तशब्द" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "उभी रेषा" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "आणि" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "root pane" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "root pane" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "root pane" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "underscore" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "तक्ता" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "tree table" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessible" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "तक्ता" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "तक्ता" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -#, fuzzy -msgid "Learn mode. Press escape to exit." -msgstr "दाबा." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "ऍनिमेशन" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "दुवा" - -#: src/cthulhu/messages.py:1518 -#, fuzzy -msgid "same page" -msgstr "पान" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, fuzzy, python-format -msgid "%s link" -msgstr "दुवा" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "वृक्ष स्तर %d" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr " बंद" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr " सुरू" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "स्पेलिंग चुकलेले शब्द:" - -#: src/cthulhu/messages.py:1682 -#, fuzzy, python-format -msgid "Misspelled word: %s" -msgstr "स्पेलिंग चुकलेले शब्द:" - -#: src/cthulhu/messages.py:1687 -#, fuzzy, python-format -msgid "Context is %s" -msgstr " संदर्भ आहे " - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "भाष्य अकार्यान्वित." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "भाष्य कार्यान्वित." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "डावा मधुकंस" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "वृक्ष स्तर %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "प्रकाशझोत नाही" - -#: src/cthulhu/messages.py:1867 -#, fuzzy -msgid "No application has focus." -msgstr "अनुप्रयोग" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "बटन उलटे करा" - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "check box" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "नाही" - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "combo box" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "internal frame" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "यादी बाब" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "परिच्छेद" - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "रेडिओ बटन" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "विभाजक" - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "tree table" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "निवडले नाही" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "अनुप्रयोग" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "तळ:" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "टॉप:" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "गुप्तशब्द" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -#, fuzzy -msgid "off" -msgstr " बंद" - -#: src/cthulhu/messages.py:2051 -#, fuzzy -msgid "on" -msgstr " सुरू" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, fuzzy, python-format -msgid "Progress bar %d." -msgstr "प्रगती पट्टी" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "सर्व(_A)" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "काहीच नाही" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -#, fuzzy -msgid "Search complete." -msgstr "आहे." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "न निवडलेले" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "भाष्य अकार्यान्वित." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "भाष्य कार्यान्वित." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "वेगवान" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "मंद." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "उंच." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "खाली." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "वेगवान" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "दर:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "आवाज(_l):" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "नाही" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "नाही" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "भाष्य कार्यान्वित." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "भाष्य" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Cthulhu प्राधान्यता" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "भाष्य उपलब्ध नाही." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "status bar" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -#, fuzzy -msgid "Speak cell" -msgstr "बोला" - -#: src/cthulhu/messages.py:2394 -#, fuzzy -msgid "Speak row" -msgstr "बोला" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -#, fuzzy -msgid "Not in a table." -msgstr "नाही" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ColumnHeader" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, fuzzy, python-format -msgid "column %d" -msgstr "column header" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "न निवडलेले" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "न निवडलेले" - -#: src/cthulhu/messages.py:2458 -#, fuzzy, python-format -msgid "row %d" -msgstr "row header" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "चाा." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "निवडले नाही" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "न निवडलेले" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "निवडले" - -#: src/cthulhu/messages.py:2521 -#, fuzzy -msgctxt "text" -msgid "unselected" -msgstr "न निवडलेले" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu प्राधान्यता" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "पांढरा स्पेस" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -#, fuzzy -msgid "0 items" -msgstr "यादी बाब" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "संवाद" -msgstr[1] "संवाद" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "यादी बाब" -msgstr[1] "यादी बाब" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "यादी बाब" -msgstr[1] "यादी बाब" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "टक्के" -msgstr[1] "टक्के" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "बिंदू" -msgstr[1] "बिंदू" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "स्पेस" -msgstr[1] "स्पेस" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "तक्ता" -msgstr[1] "तक्ता" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "बटन उलटे करा" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, fuzzy, python-format -msgid "LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "वृक्ष स्तर %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "प्रश्न" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "combo box" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "विसर्ग" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "अनुप्रयोग" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "परिच्छेद" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "टॅब यादी" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "अवतरण" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, fuzzy, python-format -msgid "h%d" -msgstr "hdr" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "scroll bar" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "scroll bar" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "उभी रेषा" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "उभी रेषा" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -#, fuzzy -msgid "Icon panel" -msgstr "पर्याय पेन" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "ऍनिमेशन" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "ऍनिमेशन" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "spin button" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "कोसळलेले" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "विस्तारित" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -#, fuzzy -msgid "vertical" -msgstr "उभी रेषा" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "तपासले" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "तपासले नाही" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr " सुरू" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr " बंद" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "तपासले नाही" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "दाबले" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "दाबले नाही" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "निवडले नाही" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "निवडले" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "निवडले नाही" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "निवडले नाही" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "करडे" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "न निवडलेले" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "स्पेलिंग तपासा" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "वर्धक भिंग" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:166 -#, fuzzy -msgid "_Top of window" -msgstr "खिडकी" - -#: src/cthulhu/cthulhu-find.ui:175 -#, fuzzy -msgid "Top of window" -msgstr "खिडकी" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "OptionPane" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "मुलभूत" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "मोठी लिपी" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "हायपरलिंक" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "खिडकी" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu प्राधान्यता" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "बोला" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "ब्रैल" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "अनुप्रयोग" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "प्रगती पट्टी" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "आवाज(_l):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Pi_tch:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "दर:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "व्यक्ती:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "भाष्य सिंथेसाइजर(_z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "भाष्य प्रणाली(_s):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "भाष्य कार्यान्वित करा" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Ver_bose" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "सर्व(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -#, fuzzy -msgid "Spoken Context" -msgstr " संदर्भ आहे " - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "भाष्य" - -#: src/cthulhu/cthulhu-setup.ui:2187 -#, fuzzy -msgid "Enable Braille _support" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "अधिक प्रदर्शन पर्याय" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "काहीच नाही(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "हायपरलिंक" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "कार्यान्वित" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ब्रैल" - -#: src/cthulhu/cthulhu-setup.ui:2780 -#, fuzzy -msgid "Enable _key echo" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "भाष्य कार्यान्वित करा" - -#: src/cthulhu/cthulhu-setup.ui:2864 -#, fuzzy -msgid "Enable _modifier keys" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2879 -#, fuzzy -msgid "Enable _function keys" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2894 -#, fuzzy -msgid "Enable ac_tion keys" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2909 -#, fuzzy -msgid "Enable _navigation keys" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2965 -#, fuzzy -msgid "Enable echo by _word" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "किल्ली इको" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3204 -#, fuzzy -msgid "Pronunciation" -msgstr "ऍनिमेशन" - -#: src/cthulhu/cthulhu-setup.ui:3243 -#, fuzzy -msgid "_Speak all" -msgstr "बोला" - -#: src/cthulhu/cthulhu-setup.ui:3257 -#, fuzzy -msgid "Speak _none" -msgstr "बोला" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "कार्यान्वित" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "सहाय्यक" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "रांग" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "सहाय्यक" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "निर्देशिका पेन" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "तक्ता" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -#, fuzzy -msgctxt "textattr" -msgid "invisible" -msgstr "inaccessible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "डावा मधुकंस" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "परिच्छेद" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "उजवा मधुकंस" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "cale" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "नवीओळ" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "उभी रेषा" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "उजवी:" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "नवीओळ" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "दुवा" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "रांग" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "गुप्तशब्द" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "trtbl" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "डावा alt" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "उजवा alt" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "केंद्रीय" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "filler" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "अर्धविराम" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "विस्तारित" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "विस्तारित" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "विस्तारित" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "विस्तारित" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "मुलभूत" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "पाठ" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "शिर्षक" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "नवीओळ" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "tip" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "पाठ" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "तळ:" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "flr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "टॅब" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "स्पेलिंग तपासा" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -#, fuzzy -msgid "To get to the system menus press the alt+f1 key." -msgstr "प्रति." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/ms.po b/po/ms.po deleted file mode 100644 index 2a4aa55..0000000 --- a/po/ms.po +++ /dev/null @@ -1,9160 +0,0 @@ -# Malay translation for cthulhu. -# Copyright (C) 2010 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Ahmed Noor Kader Mustajir Md Eusoff , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2020-01-24 23:26+0800\n" -"Last-Translator: abuyop \n" -"Language-Team: Malay \n" -"Language: ms\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 2.0.6\n" - -msgid "Cthulhu Screen Reader" -msgstr "Pembaca skrin Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "skrin;pembaca;kebolehcapaian;pertuturan;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dail" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "lukis" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "borang" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "paut" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "putar" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "pere" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Czech Gred 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spanish Gred 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "French Canada Gred 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "French French Gred 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvian Gred 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Netherlands Dutch Gred 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norwegian Gred 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norwegian Gred 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norwegian Gred 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norwegian Gred 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polish Gred 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portuguese Gred 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Swedish Gred 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arab Gred 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Welsh Gred 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Welsh Gred 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "German Gred 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "German Gred 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "German Gred 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "U.K. English Gred 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "U.K. English Gred 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "U.S. English Gred 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "U.S. English Gred 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Canada French Gred 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "France French Gred 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Greek Gred 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi Gred 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Komputer 8 titik Hungary" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hungary Gred 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Hungary Gred 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italian Gred 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgium Dutch Gred 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "jarak" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "barisbaru" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "tanda soal" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "petikan" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nombor" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "peratus" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "dan" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "koma atas" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "paren kiri" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "paren kanan" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "bintang" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "tambah" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "koma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "sengkang" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "dot" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "miring" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "titik bertindih" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "koma bertitik" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "kurang" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "sama dengan" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "lebih besar" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "soalan" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "pada" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "kurung kiri" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "backslash" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "kurung kanan" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "karet" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "garis bawah" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "tanda dakap kiri" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "palang menegak" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "tanda dakap kanan" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "tiada jarak hentian" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "tanda seruan terbalik" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "sen" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pound" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "tanda mata wang" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "palang putus" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "bahagian" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "hakcipta" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superskrip a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "kurung ganda bersudut kiri" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logikal not" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "sengkang lembut" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "berdaftar" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "makron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "darjah" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "tambah atau tolak" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superskrip 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superskrip 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acute" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "penanda perenggan" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "titik tengah" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "sedila" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superskrip 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "kurung ganda bersudut kanan" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "satu per empat" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "setengah" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tiga suku" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "tanda soal terbalik" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "times" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROK" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "dibahagi dengan" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "kiri tunggal kutipan" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "kanan tunggal kutipan" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "tunggal rendah kutipan" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "kiri kutipan ganda" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "kanan ganda kutipan" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "ganda rendah kutipan" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "pisau belati" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "belati ganda" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "bullet" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "bullet segitiga" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prima" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "prima berganda" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "prime ganda tiga" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "bullet sengkang" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "cap dagang" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "tanda semak" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "tanda semak tebal" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "bullet bentuk-x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "superskrip 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "superskrip 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "superskrip 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "superskrip 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "superskrip 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "superskrip 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "superskrip 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "superskrip tambah" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "superskrip tolak" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "superskrip sama dengan" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "superskrip paren kiri" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "superskrip paren kanan" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "superskrip n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "subskrip 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "subskrip 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "subskrip 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "subskrip 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "subskrip 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "subskrip 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "subskrip 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "subskrip 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "subskrip 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "subskrip 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "subskrip tambah" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "subskrip tolak" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "subskrip sama dengan" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "subskrip paren kiri" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "subskrip paren kanan" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "persegi hitam" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "berlian hitam" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "aksara pengganti objek" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Hala penuding ke item semasa." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Lakukan klik kiri pada item ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Lakukan klik kanan pada item ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Baca seluruh dokumen." - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Sebut keseluruhan tetingkap menggunakan ulasan rata." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Lakukan yang asas ketika saya operasikan." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Lakukan yang terperinci ketika saya operasikan." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Sebut pemilihan semasa." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Sebut perincian pautan." - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Pergi ke butang berikutnya." - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Berbicara dalam status bar." - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Berbicara tajuk bar." - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Buka dialog Cari." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Tunjukkan senarai tindakan" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Cari untuk seterusnya dari string." - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Mencari dahulu string." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Masuk dan keluar mod datar ulasan." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Alih ulasan rata ke kedudukan akhir." - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Bergerak datar penelaahan untuk kedudukan rumah." - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Alih ulasan rata ke kedudukan akhir." - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Bergerak datar meninjau ke awal baris sebelumnya." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Berbicara dalam garis datar ulasan saat ini." - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Mengeja baris ulasan saat ini datar." - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Eja secara sebutan baris ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Alih ulasan rata ke permulaan baris berikutnya." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Alih ulasan rata ke item atau perkataan terdahulu." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Sebut item atau perkataan ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Eja item atau perkataan ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Eja secara sebutan bagi item atau perkataan ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Alih ulasan rata ke item atau perkataan berikutnya." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Alih ulasan rata ke perkataan di atas perkataan semasa." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Sebut objek ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Alih ulasan rata ke perkataan di bawah perkataan semasa." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Alih ulasan rata ke aksara terdahulu." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Sebut aksara ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Tutur secara sebutan bagi aksara ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Sebut nilai unikod bagi aksara ulasan rata semasa." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Alih ulasan rata ke aksara berikutnya." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Alih ulasan rata ke penghujung baris." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Alih ulasan rata ke bahagian kiri bawah." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Salin kandungan di bawah ulasan rata ke dalam papan keratan." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Tambah kandungan di bawah ulasan ke dalam papan keratan." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Alih ulasan rata ke kedudukan akhir." - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Togol sama ada hendak baca sel jadual semasa atau keseluruhan baris." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Baca atribut yang berkaitan dengan aksara teks semasa." - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Lata paparan braille ke kiri." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Lata paparan braille ke kanan." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Kembalikan objek dengan fokus papan kekunci." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Hidup atau matikan braille terkecut." - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Proseskan kekunci penghalaan kursor." - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Tanda permulaan pemilihan teks." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Tanda penghujung pemilihan teks." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Masuk mod belajar. Tekan escape untuk keluar dari mod belajar." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Rendahkan kadar pertuturan." - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Tingkatkan kadar pertuturan." - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Rendahkan pic pertuturan." - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Tingkatkan pic pertuturan." - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Tingkatkan volum pertuturan." - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Rendahkan volum pertuturan." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Mencari dahulu string." - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Kitar ke profil tetapan berikutnya." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Sebut pemilihan semasa." - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Sebut pemilihan semasa." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Tetapan Jenis Suara" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Togol kesenyapan pertuturan." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Togol aras kejelaan pertuturan." - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Togol mod ulasan tetikus." - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Keluar dari pembaca skrin" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Papar dialog konfigurasi keutamaan." - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Papar dialog konfigurasi keutamaan aplikasi." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Togol pertuturan pengensotan dan sama birai." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Ubah gaya nombor yang disebut." - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Kitar ke aras tanda baca pertuturan berikutnya." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Kitar ke aras gema kekunci berikutnya." - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Kitar ke profil tetapan berikutnya." - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Kitar ke gaya huruf besar berikutnya." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Kitar ke aras gema kekunci berikutnya." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Kitar aras nyahpepijat pada masa jalan." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Tanda buku yang mana dikaitkan dengan posisi semasa." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Pergi ke lokasi tanda buku terdahulu." - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Pergi ke tanda buku." - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Pergi ke lokasi tanda buku berikutnya." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Tambah tanda buku." - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Simpan tanda buku." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Togol mod ulasan tetikus." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Hadirkan masa semasa." - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Hadirkan tarikh semasa." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Hadrikan saiz dan lokasi objek semasa." - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Lepaskan perintah berikutnya ke aplikasi semasa." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Sebut dan braille mesej bilik sembang terdahulu." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Togol sama ada umumkan bila rakan sedang menaip." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Togol sama ada sediakan sejarah mesej tertentu bagi bilik sembang." - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Togol sama ada perlu awalkan mesej bilik sembang dengan nama bilik sembang." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Jalur Kiri" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Jalur Kanan" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Jalur Atas" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Jalur Bawah" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Kaku" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Puncak Kiri" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Kiri Bawah" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Kedudukan Kursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Enam Dot" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Penghalaan Kursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Memotong Mula" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Memotong baris" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Hadirkan mesej pemberitahuan terakhir." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Hadirkan senarai mesej pemberitahuan" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Hadirkan mesej pemberitahuan terdahulu." - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Hadirkan mesej pemberitahuan terakhir." - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Pergi ke aksara berikutnya." - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Pergi ke aksara terdahulu." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Pergi ke perkataan berikutnya." - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Pergi ke perkataan terdahulu." - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Pergi ke baris berikutnya." - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Pergi ke baris terdahulu." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Pergi ke atas bahagian teratas fail." - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Pergi ke bahagian terbawah fail." - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Pergi ke permulaan baris." - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Pergi ke penghujung baris." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Pergi ke objek berikutnya." - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Pergi ke objek terdahulu." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Menyebabkan kotak kombo semasa akan dikembangkan." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Tukar antara navigasi karet tabii dengan pembaca-skrin." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Tetapan kesopanan kawasan langsung lanjutan." - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Matikan aras kesopanan kawasan langsung lalai." - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Ulas pengumuman kawasan langsung." - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Pantau kawasan langsung." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Alih fokus ke dalam dan keluar dari tetikus atas semasa." - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Tetapkan baris yang digunakan sebagai pengepala lajur dinamik." - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Kosongkan pengepala lajur dinamik." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Tetapkan lajur yang digunakan sebagai pengepala baris dinamik." - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Koosngkan pengepala baris dinamik" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Hadirkan kandungan ke baris input." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Togol kekunci navigasi berstruktur." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Pergi ke petikan blok terdahulu." - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Pergi ke petikan blok berikutnya." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Papar satu senarai ruang petikan." - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Pergi ke butang terdahulu." - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Pergi ke butang berikutnya." - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Papar satu senarai butang." - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Pergi ke kotak tanda terdahulu." - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Pergi ke kotak tanda berikutnya." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Papar satu senarai kotak tanda." - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Pergi ke boleh klik terdahulu." - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Pergi ke boleh klik berikutnya." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Papar atau senarai boleh klik." - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Pergi ke kotak kombo terdahulu." - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Pergi ke kotak kombo berikutnya." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Pergi ke permulaan bekas." - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Pergi ke penghujung bekas." - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Papar satu senarai kotak kombo." - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Pergi ke masukan terdahulu." - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Pergi ke masukan berikutnya." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Papar satu senarai masukan." - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Pergi ke medan borang terdahulu." - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Pergi ke medan borang berikutnya." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Papar satu senarai medan borang." - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Pergi ke kepala terdahulu." - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Pergi ke kepala berikutnya." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Papar satu senarai kepala." - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Pergi ke tajuk sebelumnya di tahap %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Pergi ke tajuk seterusnya di tahap %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Paparkan senarai tajuk di tahap %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Pergi ke jadual terdahulu." - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Pergi ke jadual berikutnya." - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Papar satu senarai jadual." - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Pergi ke imej terdahulu." - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Pergi ke imej berikutnya." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Papar satu senarai imej." - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Pergi ke mercu tanda terdahulu." - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Pergi ke mercu tanda berikutnya." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Papar satu senarai mercu tanda." - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Pergi ke objek besar terdahulu." - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Pergi ke objek besar berikutnya." - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Papar satu senarai objek besar." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Pergi ke pautan terdahulu." - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Pergi ke pautan berikutnya." - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Papar satu senarai pautan." - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Pergi ke senarai terdahulu." - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Pergi ke senarai berikutnya." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Papar satu senarai bagi senarai." - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Pergi ke item senarai terdahulu." - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Pergi ke item senarai berikutnya." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Papar satu senarai bagi item senarai." - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Pergi ke kawasan langsung terdahulu." - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Pergi ke kawasan langsung berikutnya." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Pergi ke kawasan langsung terakhir yang membuat pengumuman." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Kembalikan objek dengan fokus papan kekunci." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Pergi ke anak pertama objek dengan fokus navigator." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Pergi ke adik-beradik seterusnya objek dengan fokus navigator." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Pergi ke adik-beradik sebelumnya objek dengan fokus navigator." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Kembalikan objek dengan fokus papan kekunci." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Togol kekunci navigasi berstruktur." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Pergi ke perenggan terdahulu." - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Pergi ke perenggan berikutnya." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Papar senarai perenggan." - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Pergi ke butang radio terdahulu." - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Pergi ke butang radio berikutnya." - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Papar senarai butang radio." - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Pergi ke pemisah terdahulu." - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Pergi ke pemisah berikutnya." - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Pergi ke jadual terdahulu." - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Pergi ke jadual berikutnya." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Papar satu senarai jadual." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Pergi ke bawah satu sel." - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Pergi ke sel pertama dalam jadual." - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Pergi ke sel terakhir dalam jadual." - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Pergi ke kiri satu sel." - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Pergi ke kanan satu sel." - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Pergi ke atas satu sel." - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Togol mod bentangan." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Tukar antara mod layar dengan mod fokus." - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Benarkan mod fokus melekat." - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Benarkan mod layar lekat." - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Pergi ke pautan tidak dilawati terdahulu." - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Pergi ke pautan tidak dilawati berikutnya." - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Papar senarai pautan tidak dilawat." - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Pergi ke pautan dilawati terdahulu." - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Pergi ke pautan dilawati berikutnya." - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Papar satu senarai pautan dilawat." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "biru alice" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "putih antik" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "hijau laut" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "biru langit" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "kuning air" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisk" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "hitam" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "badam pucat" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "biru" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "lembayung biru" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "perang" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "biru kadet" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "coklat" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "karang" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "biru bunga jagung" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "bulu jagung" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "merah lembayung" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "sian" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "biru gelap" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "sian gelap" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "rod emas gelap" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "kelabu gelap" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "hijau gelap" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "khaki gelap" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta gelap" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "hijau zaitun gelap" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "jingga gelap" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "anggerik gelap" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "merah gelap" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmon gelap" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "hijau laut gelap" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "biru loh gelap" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "kelabu loh gelap" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "firus gelap" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "lembayung gelap" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "merah jambu gelap" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "biru langit gelap" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "kelabu malap" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "biru dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "bata api" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "putih bunga" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "hijau hutan" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "putih hantu" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "emas" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "rod emas" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "kelabu" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "hijau" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "kuning hijau" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "tembikai susu" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "merah jambu panas" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "merah india" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "gading" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavender" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "merah lavender" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "hijau laman rumput" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "sifon lemon" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "biru cair" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "karang cair" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "cyan cair" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "kuning rod emas cair" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "kelabu cair" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "hijau cair" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "merah jambu cair" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmon cair" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "hijau laut cair" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "biru langit cair" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "kelabu loh cair" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "biru keluli cair" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "kuning cair" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limau" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "hijau limau" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linen" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "merah manggis" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "hijau laut sederhana" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "biru sederhana" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "anggerik sederhana" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "ungu sederhana" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "hijau laut sederhana" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "biru loh sederhana" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "hijau musim panas" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "firus sederhana" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "merah lembayung sederhana" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "biru tengah malam" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "krim mint" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "ros berkabus" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "putih navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "biru kelasi" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "renda lama" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "zaitun" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "hijau keabu-abuan" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "jingga" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "merah jingga" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "anggerik" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "rod emas pucat" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "hijau pucat" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "firus pucat" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "merah lembayung pucat" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "libasan betik" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "puf peach" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "merah jambu" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "plum" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "biru serbuk" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "ungu" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "merah" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "coklat kemerahan" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "biru diraja" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "coklat pelana" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmon" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "coklat berpasir" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "hijau laut" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "cangkerang laut" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "perak" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "biru langit" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "biru loh" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "kelabu loh" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "salji" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "hijau musim panas" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "biru keluli" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "sawo matang" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "teal" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "tisel" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomato" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "firus" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "lembayung" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "gandum" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "putih" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "asap putih" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "kuning" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "hijau kuning" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktifkan" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Mod fokus automatik ketika navigasi berstruktur" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Mod fokus automatik ketika navigasi karet" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Mod fokus automatik ketika navigasi karet" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Dot _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Dot _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Dots 7 da_n 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Batal" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Lompat ke" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikon" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Tiada" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "ejaan" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Mengumumkan ketika _rakan anda menaip" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Sediakan sejarah _mesej tertentu bagi bilik sembang" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Bercakap mesej dari" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Semua Salu_ran" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Semua saluran bila _mana-mana %s tetingkap aktif" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Satu saluran sahaja jika _tetingkapnya aktif" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Bercakap Nama Bilik Sembang" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Benarkan mod bentangan untuk kandungan" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dwi klik" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "klik tripel" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Pensintesis lalai" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Rentetan Sebenar" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Rentetan pengganti" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Benarkan gema dengan _aksara" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Benarkan kekunci _diakritikal bukan-jarak" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Lokasi S_emasa" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Panjang minumum bagi teks yang dipadankan:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opsyen Carian" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Han_ya sebut baris yang berubah semasa mencari" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Tutur keputusan semasa men_cari" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "koma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Pengikatan Kekunci" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Lalai" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Mod bentangan." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "bahagian" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Pengikatan Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Simpan tanda buku." - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Waktu dan Tarikh" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Ulasan tetikus dibenarkan." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navigasi" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Mod objek." - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Tidak diikat" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Meninggalkan ulasan rata." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Pertuturan dan kepanjangan" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "kandungan utama" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Diubah suai" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Atas Meja" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Pemberitahuan" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Diterima" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Pemberitahuan" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Keutamaan Cthulhu untuk %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Tanda dalam braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Hadirkan Sekiranya" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Bercakap" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Simpan Profil Sebagai Konflik" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Profil Pengguna Berkonflik!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profil %s sudah wujud.\n" -"Terus kemaskini profil sedia ada dengan perubahan baru ini?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Muat profil pengguna" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Anda akan ubahkan profil aktif. Jika anda\n" -"telah lakukan perubahan dalam keutamaan anda, ia\n" -"akan dilepaskan bila profil dimuatkan.\n" -"\n" -"Teruskan memuatkan profil akan buang perubahan terdahulu?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Simpan Profil Sebagai" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nama _Profil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Buang profil pengguna" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Anda akan membuang profil %s. Semua tetapan tak tersimpan dan tetapan " -"tersimpan dalam profil ini akan hilang. Anda mahu terus dan buang profil ini " -"dan semua tetapan berkaitan?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Semua" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplikasi" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Tetingkap" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Tiada" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "B_eberapa" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "K_ebanyakan" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Baris" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Ayat" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Petikan blok" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Butang" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Kapsyen" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Kotak Tanda" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Boleh Klik" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kotak Kombo" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Keterangan" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Pengepala" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "selit" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imej" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Label" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Mercu Tanda" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Aras" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Pautan" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Senarai" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Item Senarai" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objek" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Perenggan" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Butang Radio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Peranan" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Item Terpilih" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Keadaan" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Teks" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Nilai" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Petikan blok" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Butang" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Kotak Tanda" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Boleh Klik" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kotak Kombo" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Masukan" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Medan Borang" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Pengepala" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "selit" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imej" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Pengepala pada Aras %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Mercu Tanda" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Objek Besar" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Pautan" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Senarai" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Item Senarai" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Perenggan" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Butang Radio" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Jadual" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Pautan Tidak Dilawati" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Pautan Dilawati" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navigasi Laman" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Mula sebutkan halaman secara automatik bila ia mula di_muatkan" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Persembahkan ringkasan halaman bila ia mula-mula dimuatkan" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Pisahkan pertuturan kepada _cebisan antara jeda" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s suara lalai" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Lalai" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiper-pautan" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Huruf Besar" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Penampal Pertuturan" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Semak Ejaan" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "_Ralat ejaan" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "_Cadangan ejaan" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Hadirkan _kandungan ralat" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Sebut koordinat sel hamparan" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Sentiasa sebut julat hamparan terpilih" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Umumkan pen_gepala sel" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigasi Jadual" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Langkau sel k_osong" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Sebut _sel" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Sebut koordinat _sel" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Sebut regang sel _berbilang" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nama Attribute" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Kawal navigasi karet" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Benarkan navigasi _struktur" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Tema bunyi:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Tema Bunyi" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "R_ingkas" - -#: src/cthulhu/guilabels.py:953 -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Pemberitahuan" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "shift kiri" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt kiri" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control kiri" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "shift kanan" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt kanan" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control kanan" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta kiri" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta kanan" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "kunci skrol" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "mukasurat atas" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "mukasurat bawah" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab kiri" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "atas" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "bawah" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "kiri" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "kanan" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "kiri super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "kanan super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "bantuan" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "pelbagai" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "tukar mod" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "padam" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "rumah" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "akhir" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "bermula" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "cirkumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "stroke" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "tolak" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Sisip" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Caps_Lock" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s tebal" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s condong" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s tebal condong" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "skrip %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "skrip tebal %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "dwi-struck %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "fraktur tebal %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif tebal %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif condong %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif tebal condong %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "monospace %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "tanpa titik %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "anak panah kiri" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "anak panah atas" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "anak panah kanan" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "anak panah bawah" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "anak panah kiri kanan" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "anak panah atas bawah" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "anak panah barat daya" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "anak panah timur laut" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "anak panah tenggara" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "anak panah kiri dari palang" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "anak panah atas dari palang" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "anak panah kanan dari palang" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "anak panah bawah dari palang" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "anak panah dubel kiri" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "anak panah dubel atas" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "anak panah dubel kanan" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "anak panah dubel bawah" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "anak panah dubel kanan kiri" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "anak panah dubel atas bawah" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "anak panah dubel barat daya" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "anak panah dubel timur laut" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "anak panah dubel tenggara" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "anak panah dubel timur laut" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "anak panah menuju-kanan" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "kepala anak panah menujuk-kanan" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "tolak" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "kurang dari" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "lebih dari" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "cirkumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "bref" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "titik" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "garis menegak dubel" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "elipsis mengufuk" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "untuk semua" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "pelengkap" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "beza separa" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "ia wujud" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "ia tidak wujud" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "set kosong" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "tokokan" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "unsur" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "bukan unsur" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "unsur kecil" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "terkandung sebagai ahli" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "tidak terkandung sebagai ahli" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "terkandung kecil sebagai ahli" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "penghujung pruf" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produk" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "kohasil darab" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "hasil tambah" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "tolak atau tambah" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "titik tambah" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "miring pembahagi" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "set tolak" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operator asterik" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operator gelang" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operator bullet" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "punca kuasa" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "punca kuasa tiga" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "punca kuasa empat" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "berkadaran" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "ketidakhinggaan" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "sudut kanan" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "sudut" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "sudut terukur" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sudut bersfera" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "pembahagi" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "tidak dibahagi" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "selari dengan" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "tidak selari dengan" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logikal and" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logikal or" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "persilangan" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "kesatuan" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "kamiran" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "kamiran ganda dua" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "kamiran ganda tiga" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "kamiran kontur" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "kamiran permukaan" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "kamiran isipadu" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "kamiran ikut jam" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "kamiran kontur ikut jam" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "kamiran kontur lawan jam" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "oleh itu" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "kerana" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "nisbah" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "kadaran" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "titik tolak" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "lebihan" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "kadaran geometrik" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetik" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "tilde songsang" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "s malas songsang" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "gelombang sinus" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "produk lingkaran" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "bukan tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "tilde tolak" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "sama secara asimptot" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "tidak sama secara asimptot" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "sama secara lebih kurang" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "tidak sebenarnya sama secara lebih kurang" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "tidak sama dan sebenarnya sama secara lebih kurang" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "hampir sama" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "tidak hampir sama" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "hampir sama atau sama" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "tilde ganda tiga" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "semua sama" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "menyamai" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "meyamai secara geometri" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "berbeza diantara" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "menghampiri had" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "sama secara geometri" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "sama lebih kurang atau imej bagi" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "imej bagi atau sama lebih kurang" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "sama titik bertindin" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "titik bertindih sama" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "gelang masuk sama" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "gelang sama" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "berkaitan dengan" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "dianggar" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "sama-sudut" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "sama bintang" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "sama delta" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "sama mengikut takrifan" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "diukur oleh" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "sama bersoalan" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "tidak sama" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "serupa dengan" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "tidak serupa dengan" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "benar-benar sama" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "kurang dari atau sama" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "lebih besar atau sama" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "kurang dari sama" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "lebih besar dari sama" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "kurang tetapi tidak sama" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "lebih dari tetapi tidak sama" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "agak kurang dari" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "agak lebih dari" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "diantara" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "tidak sama" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "tidak kurang dari" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "tidak lebih dari" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "bukan kurang dari atau sama" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "bukan lebih dari atau sama" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "kurang dari atau sama" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "lebih dari atau sama" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "bukan kurang dari bukan sama" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "bukan lebih dari bukan sama" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "kurang dari atau lebih dari" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "lebih dari atau kurang dari" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "bukan kurang dari bukan lebih dari" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "bukan lebih dari bukan kurang dari" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "sebelumnya" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "selepasnya" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "sebelum atau sama" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "selepas atau sama" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "sebelumnya atau sama" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "selepasnya atau sama" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "tidak sebelumnya" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "tidak selepasnya" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subset dari" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superset dari" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "bukan subset dari" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "bukan superset dari" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subset atau sama" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superset atau sama" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "bukan subset dari bukan sama" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "bukan super set dari bukan sama" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subset dengan bukan sama" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superset dengan bukan sama" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiset" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "pendaraban multiset" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "kesatuan multiset" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "imej petak" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "asal petak" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "imej petak atau sama" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "asal petak atau sama" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "cap petak" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "cup petak" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "tambah berbulat" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "tolak berbulat" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "darab berbulat" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "miring bahagi berbulat" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "operator titik berbulat" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operator gelang berbulat" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operator asterik berbulat" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "sama berbulat" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "sempang berbulat" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "tambah berkotak" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "tolak berkotak" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "darab berkotak" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operator titik berkotak" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "tack kanan" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "tack kiri" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "tack bawah" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "tack atas" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "penegasan" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "model" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "benar" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "paksa" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "lawang putar kanan palang menegak ganda tiga" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "lawang putar kanan ganda dua palang menegak ganda dua" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "tidak terbukti" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "tidak benar" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "tidak paksa" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "lawang putar kanan ganda dua palang menegak ganda dua dinafikan" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "sebelumnya dibawah hubungan" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "selepasnya dibawah hubungan" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "subkumpulan biasa" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "terkandung sebagai subkumpulan biasa" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "subkumpulan biasa atau sama" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "terkandungan sebagai subkumpulan biasa atau sama" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "asal dari" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "imej bagi" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "peta berbilang" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matrik konjugat hermit" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "selit" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "sudut kanan dengan lengkung" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "segitiga kanan" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operator daiman" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operator titik" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operator bintang" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "darab bahagi" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "bowtie" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "produk semi-arah faktor biasa kiri" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "produk semi-arah faktor biasa kanan" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "produk semi-arah kiri" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "produk semi-arah kanan" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "sama tilde sonsang" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "or logikal keriting" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "and logikal keriting" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "subset ganda dua" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "superset ganda dua" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "persilangan ganda dua" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "kesatuan ganda dua" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "serampang" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "sama dan selari" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "kurang dari dengan titik" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "lebih dari dengan titik" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "sangat kurang dari" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "sangat lebih dari" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "kurang dari sama atau lebih dari" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "lebih dari sama atau kurang dari" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "sama dengan atau kurang dari" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "sama atau lebih besar dari" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "sama atau sebelumnya" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "sama atau selepasnya" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "tidak sebelumnya atau sama" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "tidak selepasnya atau sama" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "tidak imej petak atau sama" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "tidak asal petak atau sama" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "imej petak atau tidak sama" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "asal petak atau tidak sama" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "kurang dari tetapi tidak sama" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "lebih dari tetapi tidak sama" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "sebelumnya tetapi tidak sama" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "selepasnya tetapi tidak sama" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "bukan subkumpulan biasa" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "tidak terkandung sebagai subkumpulan biasa" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "bukan subkumpulan biasa atau sama" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "tidak terkandung sebagai subkumpulan biasa atau sama" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "elipsis menegak" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "elipsis mengufuk garis-tengah" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "elipsis pepenjuru kanan atas" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "elipsis pepenjuru kanan bawah" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "unsur dengan lejang mengufuk panjang" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "unsur dengan palang menegak dipenghujung lejang mengufuk" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "unsur kecil dengan palang menegak dipenhujung lejang mengufuk" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "unsur dengan titik di atas" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "unsur dengan palang atas" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "unsur kecil dengan palang atas" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "unsur dengan palang bawah" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "unsur dengan dua lejang mengufuk" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "terkandung dengan lejang mengufuk panjang" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "terkandung dengan palang menegak dipenghujung lejang mengufuk" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "terkandung kecil dengan palang menegak dipenghujung lejang mengufuk" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "terkandung dengan palang atas" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "terkandung kecil dengan palang atas" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "keahlian beg catatan z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "siling kiri" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "siling kanan" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "lantai kiri" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "lantai kanan" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "kurung atas" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "kurung bawah" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "kurung sudut kiri" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "kurung sudut kanan" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "titik membulat" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "kesatuan dengan titik" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "kesatuan dengan tambah" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "persilangan persegi" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "kesatuan persegi" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "persegi hitam" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "persegi putih" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "berlian hitam" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "bulatan putih" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "bulatan hitam" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bullet putih" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "persegi kecil sederhana hitam" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s dengan garis bawah" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s dengan miring" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s dengan garis menegak" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplikasi" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "kosong" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "tebal" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "tanda buku dimasukkan" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "tanda buku disimpan" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "tanda buku tidak dapat disimpan" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Tiada mercu tanda ditemui." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Tiada mercu tanda ditemui." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Mod pintas dibenarkan." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Tidak boleh dapatkan paparan kalkulator" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Gaya huruf besar ditetapkan pada ikon." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "tiada" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Gaya huruf besar ditetapkan kepada tiada." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "ejaan" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Set gaya huruf besar ditetakan kepada ejaan." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Aplikasi mengawal karet." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Aplikasi mengawal karet." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Sel %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s terpilih" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s menerusi %s terpilih" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s menerusi %s tidak terpilih" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s tidak terpilih" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Halang penggunaan pilihan" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Paksa penggunaan pilihan" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "PILIHAN" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Argumen pilihan" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Penggunaan: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Yang berikut adalah tidak sah: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Papar aplikasi berjalan yang diketahui" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Muat profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profil tidak dapat dimuatkan: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Tidak dapat mulakan pembaca skrin kerana ia tidak dapat bersambung dengan " -"Desktop." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Tidak dapat aktifkan pengurus tetapan. Keluar." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Proses pembaca skrin yang lain sudah berjalan untuk sesi ini.\n" -"Jalankan “cthulhu --replace” untuk gantikan proses dengan yang baharu." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAMA" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Guna direktori alternatif bagi keutamaan pengguna" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Papar aplikasi berjalan yang diketahui" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Ganti kejadian berjalan semasa bagi pembaca skrin ini" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Tunjukkan mesej bantuan ini dan keluar" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Hantar output nyahpepijat ke debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Hantar output nyahpepijat ke fail yang ditentukan" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FAIL" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Tetapkan keutamaan pengguna (versi teks)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Persediaan keutamaan pengguna (versi GUI)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Lapor pepijat ke https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Potong pemilihan ke papan keratan." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "potong" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Pemilihan disalin ke dalam papan keratan." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "disalin" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Kandungan ditampal dari papan keratan." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "ditampal" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Jangan umumkan ketika rakan anda sedang menaip." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "mengumumkan ketika rakan anda menaip." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Mesej dari bilik sembang %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Tab sembang baharu %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Jangan sebut nama bilik sembang." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "bercakap nama bilik sembang." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Jangan memberikan ruang chat sejarah mesej tertentu." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Sediakan sejarah _mesej tertentu bagi bilik sembang." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "mula pemadaman" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "tamat pemadaman" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "mula penyisipan" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "tamat penyisipan" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "mula sorot" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "tamat sorot" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "tamat cadangan" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Penghujung bekas." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Bukan dalam bekas." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "semua item terpilih" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Butang lalai ialah %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Butang lalai ialah %s. Kelabu" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Butang lalai ialah %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subskrip %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " superskrip %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Tiada dalam jadual." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "keseluruhan dokumen dipilih" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "keseluruhan dokumen dinyahpilih" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokumen terpilih dari kedudukan kursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "dokumen tidak terpilih dari kedudukan kursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokumen terpilih ke kedudukan kursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "dokumen tidak terpilih ke kedudukan kursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Pengepala baris dinamik ditetapkan untuk baris %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Pengepala lajur dinamik dikosongkan." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Pengepala baris dinamik ditetapkan untuk lajur %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Pengepala baris dinamik dikosongkan." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "kosong" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobait" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabait" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Tiada fail dijumpai." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Tambah kandungan ke dalam papan keratan." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Salin kandungan ke dalam papan keratan." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Tidak menggunakan ulasan rata." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Memasuki ulasan rata." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Meninggalkan ulasan rata." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Alih ulasan rata ke perkataan di atas perkataan semasa." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Semakan rata tidak terhad" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "ada formula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "dialog buka" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "grid buka" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "kotak senarai buka" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "menu buka" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "pepohon buka" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "pautan peta imej" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Kekunci yang dimasukkan sudahpun diikat dengan %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Kekunci ditangkap: %s. Tekan enter untuk sahkan." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Kunci baru adalah: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Pengikatan kekunci dipadam. Tekan enter untuk sahkan." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Pengikatan kekunci telah dibuang." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "masukkan kunci baru" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "kekunci" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Gema kekunci ditetapkan pada kekunci." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Tiada" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Gema kekunci ditetapkan menjadi Tiada." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "kekunci dan perkataan" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Gema kekunci ditetapkan ke kekunci dan perkataan." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "ayat" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Gema kekunci ditetapkan pada ayat." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "perkataan" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Gema kekunci ditetapkan ke perkataan." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "perkataan dan ayat" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Gema kekunci ditetapkan ke perkataan dan ayat." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Dikurung oleh: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "satu simbol aktuarial" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "satu kotak" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "satu bulatan" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "tanda pembahagi panjang" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "satu radikal" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "satu kotak membulat" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "satu lejang mengufuk" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "satu lejang menegak" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "satu lejang pepenjuru ke bawah" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "satu lejang pepenjuru ke atas" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "anak panah timur laut" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "satu garis di bahagian bawah" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "satu garis di bahagian kiri" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "satu garis di bahagian kanan" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "satu garis di bahagian atas" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "satu sudut pemfasa" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "satu simbol faktorial arab" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "dan" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "mula pecahan" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "pecahan tanpa palang, mula" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "di atas" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "penghujung pecahan" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "punca kuasa dua" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "kuasa tiga bagi" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "punca kuasa" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "punca kuasa mula" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "punca kuasa penghujung" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subskrip" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "superskrip" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pra-subskrip" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pra-superskrip" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "underscript" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "overscript" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "penghujung jadual" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "penghujung jadual tersarang" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "tidak boleh capai" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Dilumpuhkan" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Pertuturan bagi pengensotan dan sama birai dilumpuhkan." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Dibenarkan" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Pertuturan bagi pengensotan dan sama birai dibenarkan." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Mod belajar. Tekan escape untuk keluar." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Memasuki mod belajar. Tekan mana-mana kekunci untuk mendengar fungsinya. " -"Untuk melihat dokumentasi pembaca skrin, tekan F1. Untuk mendapatkan senarai " -"pintasan lalai pembaca skrin, tekan F2. Untuk mendapatkan senarai pintasan " -"pembaca skrin untuk aplikasi semasa, tekan F3. Untuk keluar dari mod " -"belajar, tekan kekunci escape." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "biarkan petikan blok." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "biarkan perincian." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "meninggalkan suapan." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "meninggalkan rajah." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "meninggalkan borang." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "meninggalkan sepanduk." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "meninggalkan kandungan pelengkap." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "meninggalkan maklumat." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "meninggalkan kandungan utama." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "meninggalkan navigasi." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "meninggalkan kawasan." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "meinggalkan gelintar." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "meninggalkan senarai." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "meninggalkan panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "meninggalkan jadual." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "meninggalkan senarai." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "meninggalkan abstrak." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "meninggalkan perakuan." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "meninggalkan kata hujungan." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "meninggalkan apendiks." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "meninggalkan bibliografi." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "meninggalkan bab." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "meninggalkan kolofon." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "meninggalkan kesimpulan." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "meninggalkan penghargaan." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "meninggalkan penghargaan." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "meninggalkan dedikasi." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "meninggalkan nota akhir." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "meninggalkan efigraf." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "meninggalkan epilog." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "meninggalkan ralat." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "meninggalkan contoh." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "meninggalkan pendahuluan." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "meninggalkan glosari." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "meninggalkan indeks." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "meninggalkan pengenalan." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "meninggalkan senarai halaman." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "meninggalkan bahagian." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "meninggalkan prakata." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "meninggalkan prolog." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "meninggalkan pullquote." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "meninggalkan soal jawab." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "biarkan cadangan." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "meninggalkan senarai kandungan." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "baris terpilih bawah dari kedudukan kursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "baris terpilih atas dari kedudukan kursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "barid tidak terpilih bawah dari kedudukan kursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "baris tidak terpilih atas dari kedudukan kursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Keluar dari mod belajar." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "baris terpilih dari mula ke kedudukan kursor terdahulu" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "baris terpilih ke penghujung dari kedudukan kursor terdahulu" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "pautan" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "mukasurat sama" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "halaman sama" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "laman berbeza" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s dipautkan kepada %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s pautan" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "%s pautan dilawati" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Guna Anak Panah Atas dan Bawah untuk navigasi senarai. Tekan Escape untuk " -"keluar." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Semua kawasan langsung dimatikan" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "aras kesopanan kawasan langsung dipulihkan" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "politeness level %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "menetapkan kawasan langsung kepada desak" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "matikan kawasan langsung" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "menetapkan kawasan langsung kepada sopan" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "menetapkan kawasan langsung kepada kasar" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Marikan pemantauan kawasan langsung" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Hidupkan pemantauan kawasan langsung" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "tiada mesej langsung disimpan" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Sokongan kawasan langsung dimatikan" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Tidak ditemui" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Tidak dapat mencari lokasi semasa." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "mati" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "hidup" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "silap eja" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Perkaataan yang salah eja:% s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Konteks ialah %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Mod layar" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Mod fokus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Untuk benarkan mod fokus tekan %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Mod fokus adalah melekat." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Mod layar adalah melekat." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Mod bentangan." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Mod objek." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Pergi ke objek berikutnya." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Tetikus atas objek tidak ditemui." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Ulasan tetikus dilumpuhkan." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Ulasan tetikus dibenarkan." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Ralat: Tidak dapat cipta senarai objek." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Tiada anak." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Tiada seterusnya." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d peratus." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Pergi ke perkataan terdahulu." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Navigasi ringkas didayakan." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Navigasi ringkas dilumpuhkan." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Aras tersarang %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Item baharu telah ditambah" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Tiada tindakan ditemui pada: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Tidak fokus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Tiada aplikasi mempunyai fokus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Tiada lagi petikan blok." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Tiada lagi butang." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Tiada lagi kotak tanda." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Tiada lagi objek besar." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Tiada lagi boleh klik." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Tiada lagi kotak kombo." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Tiada lagi masukan." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Tiada lagi medan borang." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Tiada lagi pengepala." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Tiada lagi pengepala pada aras %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Tiada lagi jadual." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Tiada lagi imej." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Tiada mercu tanda ditemui." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Tiada lagi pautan." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Tiada lagi senarai." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Tiada lagi item senarai." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Tiada lagi kawasan langsung." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Tiada lagi perenggan." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Tiada lagi butang radio." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Tiada lagi pemisah." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Tiada lagi jadual." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Tiada lagi pautan tidak dilawati." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Tiada lagi pautan yang dilawati." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Tiada teks terpilih." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Bukan berada pada pautan." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Pemberitahuan" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Bawah" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Atas" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Tiada mesej pemberitahuan" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "digit" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Sebut nombor sebagai digit." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "perkataan" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Sebut nombor sebagai perkataan." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "mati" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "hidup" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Memuatkan. Sila tunggu." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Selesai memuatkan." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Selesai memuatkan %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Halaman mempunyai %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "halaman terpilih dari kedudukan kursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "halaman terpilih ke kedudukan kursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "halaman tidak terpilih dari kedudukan kursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "halaman tidak terpilih ke kedudukan kursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "perenggan terpilih di bawah kedudukan kursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "perenggan terpilih di atas dari kedudukan kursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "perenggan tidak terpilih di bawah kedudukan kursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "perenggan tidak terpilih di atas dari kedudukan kursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Anda sudah membuka satu dialog keutamaan Cthulhu.\n" -"Sila tutup ia sebelum membuka yang baharu." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "slaid %(position)d dari %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil ditetapkan ke %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Tiada profil ditemui." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Bar kemajuan %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Semua" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Aras tanda baca ditetapkan pada semua." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Kebanyakan" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Aras tanda baca ditetapkan pada kebanyakan." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Tiada" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Aras tanda baca ditetapkan pada tiada." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Beberapa" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Aras tanda baca ditetapkan pada beberapa." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Mencari." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Carian tamat." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Pembaca skrin Cthulhu" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Teks terpilih ialah: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Pemilihan dipadamkan." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Pemilihan dipulihkan." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "tidak dipilih" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Saiz: %d. %d. Lokasi: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Lebar: %d. Tinggi: %d. %d dari kiri. %d dari atas." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Percakapan dimatikan." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Percakapan dihidupkan." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "lebih cepat." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "lebih lambat." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "lebih tinggi." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "lebih bawah." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "lebih kuat." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "lebih perlahan." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Kadar %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Nada %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Kelantangan %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Modul Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Suara Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Tiada pelayan tersedia." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Tiada pelayan tersedia." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Percakapan dihidupkan." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "tanda buku tidak dapat disimpan" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Arah kejelaan: ringkas" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Aras kejelaan: berjela" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu mengalu-alukan anda." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu mengintai di bawah ombak." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Mod tidur didayakan untuk %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Mod tidur dilumpuhkan untuk %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Pertuturan tidak disediakan." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Tidak ditemui" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "string tidak dijumpai" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "string tidak dijumpai" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Kekunci navigasi berstruktur dimatikan." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Kekunci navigasi berstruktur dihidupkan." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Tidak ditemui" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Baris %(row)d, lajur %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Penghujung jadual" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Sebut sel" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Sebut baris" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Tidak-seragam" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Tiada dalam jadual." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Lajur ditertib semula" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Baris ditertib semula" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "lajur %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "lajur %(index)d dari %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Bawah lajur." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Atas lajur." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Lajur %s dipilih" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Lajur %s menerusi %s dipilih" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Lajur %s menerusi %s tidak dipilih" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Lajur %s tidak terpilih" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "baris %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "baris %(index)d dari %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Permulaan baris." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Penghujung baris." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Baris dipadam." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Baris terakhir dipadam." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Baris disisip." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Baris disisip pada hujung jadual." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Baris %s dipilih" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Baris %s menerusi %s dipilih" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Baris %s menerusi %s tidak dipilih" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Baris %s tidak dipilih" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "dipilih" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "tidak dipilih" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H jam, %M minit dan %S saat." - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H jam dan %M minit." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "buat asal" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "buat semula" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versi %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "ruangan putih" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Bungkus ke bawah." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Bungkus ke atas." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 item" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Sel meregang %d baris" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d lajur" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Sel meregang %d lajur" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d aksara terlalu panjang" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialog)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d dialog tidak berfokus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bait" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fail ditemui" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d borang" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d pengepala" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d item" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d mercu tanda" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d item ditemui" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Biarkan %d petikan blok." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Biarkan %d senarai." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Senarai saiz tidak diketahui" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Senarai dengan %d item" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Suapan saiz tidak diketahui" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Suapan dengan %d artikel" - -#: src/cthulhu/messages.py:2710 -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Senarai dengan %d item" - -#: src/cthulhu/messages.py:2718 -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Nilai" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "jadual matematik dengan %d baris" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d lajur" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "jadual matematik tersarang dengan %d baris" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d mesej.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d peratus." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d peratus dokumen dibaca" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d piksel" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s aksara" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d dari %(total)d item dipilih" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d pintasan Pembaca skrin lalai ditemui." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d pintasan Pembaca skrin untuk %(application)s ditemui." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d space" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tab" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d jadual" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "senarai kandungan" - -#: src/cthulhu/messages.py:2834 -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "jadual dengan %d baris" - -#: src/cthulhu/messages.py:2842 -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "jadual dengan %d baris" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "jadual dengan %d baris" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d saat yang lalu" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minit yang lalu" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d jam yang lalu" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d hari yang lalu" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d pautan tidak dilawati" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d pautan dilawati" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "beralih" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "pada %(index)d dari %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d dari %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "item %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "PERINGKAT %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "aras pepohon %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "ARAS PEPOHON %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "perincian untuk %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "mempunyai perincian dalam %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "cadangan" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "kotak kombo boleh sunting" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "kandungan boleh sunting" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "suapan" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "rajah" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "abstrak" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "perakuan" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "kata hujungan" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "apendiks" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "masukan bibiliografi" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografi" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "bab" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "kolofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "kesimpulan" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "muka hadapan" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "penghargaan" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "penghargaan" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedikasi" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "nota akhir" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "nota akhir" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "efigraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "ralat" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "contoh" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "pendahuluan" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosari" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "indeks" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "pengenalan" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "hentian halaman" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "senarai halaman" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "bahagian" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "prakata" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "pullqoute" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "SDJ" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "sarikata" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "senarai kandungan" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s aras %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "palang tatal mengufuk" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "palang tatal menegak" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "pelungsur mengufuk" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "pelungsur menegak" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "pemisah mengufuk" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "pemisah menegak" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "suis" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Panel Ikon" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "sepanduk" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "kandungan pelengkap" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "maklumat" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "kandungan utama" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigasi" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "wilayah" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "gelintar" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "pautan dilawati" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "butang menu" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "diisih menaik" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "diisih menurun" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "diisih" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "boleh klik" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "dikuncup" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "dikembang" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "mempunyai keterangan panjang" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "melintang" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "menegak" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "ditanda" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "tidak ditanda" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "hidup" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "mati" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "ditanda separa" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "ditekan" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "tidak ditekan" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "tidak dipilih" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "dipilih" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "tidak dipilih" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "tidak dipilih" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "dilawati" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "tidak dilawati" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "dikelabukan" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "baca sahaja" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "rdonly" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "diperlukan" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "pilih-berbilang" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "masukan tidak sah" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "tidak sah" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ejaan tidak sah" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ejaan" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "tatabahasa tidak sah" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "tatabahasa" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Cari" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Dialog Cari Pembaca Skrin" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Tutup" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Cari" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Gelintar untuk:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Mencari:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Atas tetingkap" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Atas tetingkap" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Mula dari:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Balut keliling" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Gelintar _mengundur" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Arah gelintar:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Padan kata" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Padankan _keseluruhan kata sahaja" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opsyen Carian" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Lalai" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Huruf Besar" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiper-pautan" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplikasi" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Tetingkap" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Pembaca skrin Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Bantuan" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Laksana" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Bentangan Papan Kekunci" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Profil Aktif:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profil Permulaan:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Muat" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Simp_an Sebagai" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "B_uang" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profil" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Hadirkan tip alat" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Sebut objek di bawah penuding t_etikus" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Tetikus" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Format waktu:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Format ta_rikh:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Waktu dan Tarikh" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Tutur kemaskini" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Kemaskini _Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frekuensi (saat):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplikasi" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Kemaskini bee_p" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Palang Kemajuan Dikemaskini" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Benarkan _mandir dan maju pantas dalam Sebut Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Benarkan navigasi ber_struktur dalam Sebut Semua" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Sebut Semua _Ikut:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Umum _petikan blok dalam Sebut Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Umum se_narai dalam Sebut Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Umum _jadual dalam Sebut Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Umum _panel dalam Sebut Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Umum _borang dalam Sebut Semua" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Umum mer_cu tanda dalam Sebut Semua" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Sebut Semua" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Pembentangan elemen:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Am" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lum:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Pi_c:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Penarafan:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Individu:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Bahasa:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "P_ensintesis pertuturan:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Sistem _percakapan:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Jenis _suara:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Gaya _huruf besar:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Tetapan Jenis Suara" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Sebut rentetan kata-berbilang sebagai perk_ataan" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Sebut _nombor sebagai digit" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Tetapan Suara Sejagat" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Suara" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Benarkan pertuturan" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Ber_jela" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Kejelaan" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Semua" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Aras Tanda Baca" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Hanya sebut teks yang dipaparkan" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Sebut baris kosong" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Sebut p_engensotan dan sama birai" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Seb_ut objek mnemonik" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Sebut ke_dudukan anak" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Sebut mesej tutorial" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Mesej _sistem adalah terperinci" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Se_but warna sebagai nama" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Umum _petikan blok ketika navigasi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Umum _senarai ketika navigasi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Sebut _jadual ketika navigasi" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Sebut penunjuk perkataan tersilap-eja" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Umum _panel ketika navigasi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Umum mer_cu tanda ketika navigasi" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Umum b_orang ketika navigasi" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Sebut _keterangan" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Sebut baris penuh dalam ha_mparan" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Tutur baris penuh dalam jadual _dokumen" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Tutur baris penuh dalam jadual _GUI" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Konteks Disebut" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Percakapan" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Benarkan _sokongan Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Nama peranan _singkatan" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Lumpuhkan simbol _akhir baris" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Jadual _Dikecutkan:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Benarkan Braille Dikecutkan" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Benarkan balut _kata" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Tetapan Paparan" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Tiada" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Penunjuk Pemilihan" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Penunjuk Hiper-pautan" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Benarkan _mesej berdenyar" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Tempoh mese_j (saat):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Mesej adalah _tekal" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Mesej adalah te_rperinci" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Tetapan Mesej Denyar" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Benarkan gema _kekunci" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Benarkan kekunci _abjad" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Benarkan kekunci n_umerik" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Benarkan kekunci _tanda baca" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Benarkan _jarak" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Benarkan kekunci pen_gubahsuai" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Benarkan kekunci _fungsi" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Benarkan kekunci tin_dakan" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Benarkan kekunci _navigasi" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Benarkan gema dengan per_kataan" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Benarkan gema dengan _ayat" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Gema Kekunci" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Kekunci Pen_gubahsuai Pembaca Skrin:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Pengikatan Kekunci" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Kamus Sebutan" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Masukan _baharu" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Padam" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Sebutan" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Sebut semua" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Jangan sebut" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "Teta_p Semula" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atribut teks" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Alih ke _bawah" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Alih satu ke bawah" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Alih satu ke atas" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Alih ke _atas" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Laras atribut terpilih" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Penunjuk Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atribut Teks" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Dayakan Pembantu AI" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Pembekal:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Tempatan - Percuma)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Fail _Kunci API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Laluan ke fail kunci API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Dapatkan _Kunci API Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Buka pelayar untuk mendapatkan kunci API Claude dan simpan secara automatik" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Memerlukan pengesahan sebelum tindakan AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Model Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nama model untuk Ollama (cth., llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Titik akhir Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL titik akhir API Ollama (cth., http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Kualiti tangkapan skrin:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "rendah" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Sederhana" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Tinggi" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Pembantu AI" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Bahasa:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Faktor Skala:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Imej _Skala Kelabu" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Songsangkan Imej" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Imej _Hitam dan Putih" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Ambang Hitam/Putih:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analisis Warna" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Salin kandungan ke dalam papan keratan." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "warna latar belakang" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "tinggi penuh latar belakang" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "percikan latar belakang" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "arah" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "diedit" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nama keluarga" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "warna latar depan" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "percikan latar hadapan" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efek fon" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "ensot" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "kesilapan" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "halimunan" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "sama birai" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "bahasa" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "margin kiri" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "ketinggian baris" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "gaya perenggan" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "piksel di atas baris" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "piksel di bawah baris" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "piksel dalam balutan" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "jidar kanan" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "naik" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "skala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "saiz" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "meregang" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "coret tembus" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "gaya" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "dekorasi teks" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "putaran teks" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "bayangan teks" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "menggaris" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variasi" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "jajar menegak" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "berat" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "mod balut" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "mod tulis" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "betul" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "salah" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "tiada" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "ukir" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "cetak timbul" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "garis luar" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "atas garis" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "garis terus" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "berkelip" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "hitam" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "tunggal" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dubel" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "rendah" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "char" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "perkataan" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "aks perkataan" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "kiri" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "kanan" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "tengah" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "tiada justifikasi" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "penuhi" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra padat" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "tambah padat" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "padat" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "separa padat" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "separa kembang" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "dikembang" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "tambah kembang" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra kembang" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "huruf kecil" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblik" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "condong" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Lalai" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Badan teks" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Pengepala" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "garis dasar" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "atas" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "atas-teks" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "tengah" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "bawah" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "bawah-teks" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "warisi" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "tegar" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "ejaan" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Tekan kekunci space untuk togol." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Tekan kekunci space untuk kembangkan, dan guna atas dan bawah untuk pilih " -"item." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Tekan alt+f6 untuk berikan folus ke tetingkap anak." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Untuk alihkan item, guna sama ada kekunci anak panah atau taip untuk " -"menggelintar." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Untuk dapatkan menu sistem tekan kekunci alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Guna atas dan bawah untuk memilih item." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Untuk kuncupkan, tekan kekunci shift dan kiri." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Untuk kembangkan, tekan kekunci shift dan kanan." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Untuk aktifkan tekan return." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Taip dalam teks." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Guna kiri dan kanan untuk lihat tab lain." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Untuk aktifkan tekan kekunci space." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Guna anak panah atas atau bawah untuk pilih nilai. Atau taip nilai numerik " -"yang dikehendaki." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Guna kekunci anak panah untuk ubah." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Untuk navigasi, tekan anak panah kiri atau kanan, Untuk gerak melalui item " -"tekan anak panah atau atau bawah." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Untuk masukkan sub-menu, tekan anak panah kanan." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Untuk kurangkan tekan anak panah kiri, untuk tingkatkan tekan anak panah " -"kanan. Untuk terus ke minimum tekan home, untuk terus ke maksimum tekan end." diff --git a/po/nb.po b/po/nb.po deleted file mode 100644 index d743bde..0000000 --- a/po/nb.po +++ /dev/null @@ -1,9256 +0,0 @@ -# Norwegian bokmål translation of cthulhu. -# Copyright (C) 2003-2004 Free Software Foundation, Inc. -# Sigurd Gartmann , 2003-2006. -# Kjartan Maraas , 2003-2021. -# Sigurd Gartmann , 2007. -# -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu 4.0\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2021-05-11 13:04+0200\n" -"Last-Translator: Kjartan Maraas \n" -"Language-Team: Norwegian bokmål \n" -"Language: nb\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu skjermleser" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "skjerm;leser;tilgjengelighet;tale;blindeskrift;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrm" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "pil" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "ram" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "akb" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "frgvlg" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "kolov" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "kbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ikn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "skive" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "map" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "tegn" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fil" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "fll" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "skr" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "skjema" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "glf" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "tptkst" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "bld" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etk" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lagf" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnke" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstop" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mny" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnyl" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnel" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "alter" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "sdt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "aflst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "prd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "oppspr" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "frdvs" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "knp" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnyopf" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "hvdf" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "radov" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "rull" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "rulf" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "del" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "sep" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "glid" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltf" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "snkn" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statl" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tamnyopf" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tks" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "bryter" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "verl" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "vtp" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "ukj" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vomr" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "vnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "top" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "bun" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "avsn" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "prg" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "redl" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "inp" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Tsjekkisk grad 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spansk grad 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanadisk fransk grad 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Fransk grad 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvisk grad 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Hollandsk grad 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norsk grad 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norsk grad 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norsk grad 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norsk grad 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polsk grad 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugisisk grad 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Svensk grad 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabisk grad 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Walisisk grad 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Walisisk grad 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Tysk grad 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Tysk grad 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Tysk grad 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Britisk engelsk grad 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Britisk engelsk grad 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Amerikansk engelsk grad 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Amerikansk engelsk grad 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadisk fransk grad 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Fransk fransk grad 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Gresk grad 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi grad 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ungarsk 8 punkt datamaskin" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Ungarsk første grad" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Ungarsk første grad" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiensk grad 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgisk hollandsk grad 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "mellomrom" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "ny linje" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "utropstegn" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "sitattegn" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nummer" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "prosent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "og" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "venstre parantes" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "høyre parantes" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "stjerne" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "pluss" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "komma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "bindestrek" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punktum" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "skråstrek" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "kolon" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semikolon" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "mindre" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "er lik" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "større" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "spørsmålstegn" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "krøllalfa" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "venstre hakeparentes" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "omvendt skråstrek" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "høyre hakeparentes" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "sirkumfleks" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "understrek" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "venstre krøllparentes" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertikal linje" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "høyre krøllparentes" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "mellomrom uten bryting av linje" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "omvendt utropstegn" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pund" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "valutategn" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "brutt stolpe" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "del" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "opphavsrett" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superskript a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "venstre dobbel hakeparentes" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logisk ikke" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "myk bindestrek" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrert" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "grader" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "pluss eller minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superskript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "akutt" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "my" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "avsnittsmarkør" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "midtstilt punkt" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedille" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superskript 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "høyre dobbel hakeparentes" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "en fjerdedel" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "en halv" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tre fjerdedeler" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "omvendt spørsmålstegn" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a akutt" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVIS" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AKUTT" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A SIRKUMFLEKS" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A TREMA" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "Å" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "Æ" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLE" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVIS" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AKUTT" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E SIRKUMFLEKS" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E TREMA" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVIS" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AKUTT" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I SIRKUMFLEKS" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I TREMA" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVIS" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AKUTT" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O SIRKUMFLEKS" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O TREMA" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "ganger" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "Ø" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVIS" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AKUTT" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U SIRKUMFLEKS" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U TREMA" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AKUTT" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "skarp s" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a gravis" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a cirkumfleks" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a trema" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "å" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "æ" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedille" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e gravis" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e akutt" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e cirkumfleks" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e trema" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i gravis" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i akutt" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i cirkumfleks" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i trema" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o gravis" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o akutt" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o cirkumfleks" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o trema" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "delt på" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "ø" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u akutt" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u gravis" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u cirkumfleks" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u trema" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y akutt" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y trema" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y TREMA" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "bindestrek" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "venstre enkelt sitattegn" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "høyre enkelt sitattegn" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "enkelt lavt sitattegn" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "venstre dobbelt sitattegn" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "høyre dobbelt sitattegn" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dobbelt lavt sitattegn" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "kors" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dobbeltkors" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "kulepunkt" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trekantet kulepunkt" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "primtall" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "dobbelt primtall" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "trippelt primtall" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "bindestrekkulepunkt" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "varemerke" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "avkrysningsmerke" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "tungt avkryssingsmerke" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-formet kulepunkt" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "superskript 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "superskript 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "superskript 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "superskript 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "superskript 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "superskript 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "superskript 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "superskript pluss" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "superskript minus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "superskript er lik" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "superskript venstre parantes" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "superskript høyre parantes" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "superskript n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "subskript 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "subskript 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "subskript 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "subskript 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "subskript 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "subskript 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "subskript 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "subskript 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "subskript 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "subskript 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "subskript pluss" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "subskript minus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "subskript er lik" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "subskript venstre parantes" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "subskript høyre parantes" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "sort firkant" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "sort diamant" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "tegn for erstatning av objekt" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Flytt pekeren til aktiv oppføring" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Utfør venstreklikk på gjeldende oppføring i flat visning." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Utfør høyreklikk på gjeldene oppføring i flat visning." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Les opp hele dokumentet" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Les opp hele vinduet i flat visning" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Utfør grunnleggende «hvor er jeg»-operasjon" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Utfør detaljert versjon av «hvor er jeg»-operasjonen" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Les opp gjeldende utvalg" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Les detaljer om lenke" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Presenter standardknappen" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Les opp statuslinjen" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Les opp tittellinjen" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Åpne dialog for søk" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Vis handlingsliste" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Søk etter neste instans av en streng" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Søk etter forrige instans av en streng" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Gå inn i og ut av flat visningsmodus" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Flytt flat visning til sluttposisjonen" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Flytt flat visning til hjemposisjonen" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Flytt flat visning til sluttposisjonen" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Flytt flat visning til begynnelsen av forrige linje" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Les opp den gjeldende linjen i flat visning" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Stav den gjeldende linjen i flat visning" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Stav fonetisk aktiv linje i flat visning" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Flytt flat visning til begynnelsen av neste linje" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Flytt flat visning til forrige oppføring eller ord" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" -"Les opp den gjeldende oppføringen eller det gjeldende ordet i flat visning" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Stav den gjeldende oppføringen eller det ordet i flat visning" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Stav fonetisk gjeldende oppføring eller ord i flat visning" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Flytt flat visning til den neste oppføringen eller ordet" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Flytt flat visning til ordet over gjeldende ord" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Les opp det gjeldende flatvisningsobjektet" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Flytt flat visning til ordet under det gjeldende ordet" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Flytt flat visning til forrige tegn" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Les opp det gjeldende tegnet fra flat visning" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Les opp fonetisk det gjeldende tegnet fra flat visning" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Les opp unicode-verdien for det gjeldende tegnet fra flat visning" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Flytt flat visning til neste tegn" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Flytt flat visning til enden av linjen" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Flytt flat visning til nederst til venstre" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Kopier innholdet i flat visning til utklippstavlen" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Legg til innhold i flat visning til utklippstavlen" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Flytt flat visning til sluttposisjonen" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Velg om gjeldende celle i tabellen skal leses, eller hele raden" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Les attributtene tilordnet det gjeldende tekstlige tegnet" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Forskyver braillevisningen til venstre" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Forskyver braillevisningen til høyre" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Returner til objektet med tastaturfokus" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Slår av/på sammentrukket blindeskrift" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Prosesser en tast for markørrute" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marker starten av en tekstmarkering" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marker slutten på en tekstmarkering" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Gå inn i læringsmodus. Trykk escape for å gå ut igjen" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Begrens talehastigheten" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Øker talehastigheten" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Senk stemmens tonehøyde" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Øk stemmens tonehøyde" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Øk volumet for tale" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Senk volumet for tale" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Velg forrige taleinnstilling" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Velg neste taleinnstilling" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Reduser gjeldende taleinnstilling" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Øk gjeldende taleinnstilling" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Lagre taleinnstillinger" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Slå av og på lyd for opplesning" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Bytter detaljnivå for tale" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Veksle hvilemodus" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Avslutt skjermleser" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Vis vindu for konfigurasjon av brukervalg" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Vis brukervalgdialogen for programmet" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Slå av/på opplesing av tekstindentering og tekstjustering" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Bytt til neste uttale av tegnsettingsnivå" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Bytt til neste nivå for tasteekko" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Bytt til neste innstillingsprofil" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Bytt til neste tegnsettingsnivå" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Bytt til neste nivå for tasteekko" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Bytt feilsøkingsnivå ved kjøring" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Lag bokmerke for plassering i forhold til nåværende posisjon" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Gå til forrige bokmerkelokasjon" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Gå til bokmerke" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Gå til neste bokmerkelokasjon" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Legg til bokmerke" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Lagre bokmerke" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Slår av/på forbedringsmodus for mus" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Vis klokkeslett" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Vis dato" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Vis størrelse og lokasjon for aktivt objekt" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Send neste kommando videre til aktivt program" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Les opp og braille en tidligere samtaleromsmelding" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Slå av varsling om venner skriver" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Slå av/på hvorvidt hvert praterom skal ha egen meldingshistorikk" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Slå av/på om navnet på samtalerom skal legges til begynnelsen av hver " -"meldingstekst" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linje venstre" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linje høyre" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linje opp" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linje ned" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Frys" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Øverst til venstre" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Nederst til venstre" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Markørposisjon" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Seks punkter" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Markørruting" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Start klipp ut" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Klipp ut linje" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Vis siste varslingsmelding" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Vis liste med varslingsmeldinger" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Vis forrige varslingsmelding" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Vis siste varslingsmelding" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Gå til neste tegn" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Gå til forrige tegn" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Gå til neste ord" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Gå til forrige ord" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Gå til neste linje" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Gå til forrige linje" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Gå til starten av filen" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Gå til slutten av filen" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Gå til begynnelsen av linjen" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Gå til slutten av linjen" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Gå til neste objekt" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Gå til forrige objekt" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Utvider aktiv kombinasjonsboks" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Bytt mellom innebygget markørnavigering og markørnavigering med skjermleser" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Øk innstilling for høflighet for levende region" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Sett forvalgt høflighetsnivå for levende region til av" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Gjennomgå annonsering fra levende region" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Overvåk levende regioner" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Flytt fokus inn i og bort fra aktiv musposisjon" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Sett rad som skal brukes som dynamiske kolonneoverskrifter" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Tøm dynamiske kolonneoverskrifter" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Sett kolonnen som brukes til dynamiske radtopptekster" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Tøm dynamiske radoverskrifter" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Presenter innholdet av innskrivingsfeltet" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Slå av/på navigasjonstaster for struktur" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Gå til forrige blokksitat" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Gå til neste blokksitat" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Vis en liste med blokksitater" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Gå til forrige knapp" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Gå til neste knapp" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Vis en liste med knapper" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Gå til forrige avkrysningsboks" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Gå til neste avkrysningsboks" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Vis en liste med avkrysningsbokser" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Gå til forrige klikkbare" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Gå til neste klikkbare" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Vis en liste med klikkbare" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Gå til forrige komboboks" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Gå til neste komboboks" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Gå til starten av kontaineren" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Gå til slutten av kontaineren" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Vis en liste med kombinasjonsbokser" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Gå til forrige oppføring" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Gå til neste oppføring" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Vis en liste med oppføringer" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Gå til forrige felt i skjema" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Gå til neste felt i skjema" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Vis en liste med skjemafelter" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Gå til forrige overskrift" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Gå til neste overskrift" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Vis en liste med overskrifter" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Gå til forrige overskrift med nivå %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Gå til neste overskrift med nivå %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Vis en liste med overskrifter på nivå %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Gå til forrige tabell" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Gå til neste tabell" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Vis en liste med tabeller" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Gå til forrige bilde" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Gå til neste bilde" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Vis en liste med bilder" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Gå til forrige landemerke" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Gå til neste landemerke" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Vis en liste med landemerker" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Gå til forrige store objekt" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Gå til neste store objekt" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Vis en liste med store objekter" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Gå til forrige lenke" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Gå til neste lenke" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Vis en liste med lenker" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Gå til forrige liste" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Gå til neste liste" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Vis en liste med lister" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Gå til forrige listeoppføring" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Gå til neste lenkeoppføring" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Vis en liste med listeoppføringer" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Gå til forrige levende region" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Gå til neste levende region" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Gå til siste levende region som gjorde en annonsering" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Gå til forelderen til objektet med navigatørfokus." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Gå til det første barnet til objektet med navigatørfokus." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Gå til neste søsken til objektet med navigatørfokus." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Gå til forrige søsken til objektet med navigatørfokus." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Returner til objektet med tastaturfokus" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Slå av/på navigasjonstaster for struktur" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Gå til forrige avsnitt" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Gå til neste avsnitt" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Vis en liste med avsnitt" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Gå til forrige radioknapp" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Gå til neste radioknapp" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Vis en liste med radioknapper" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Gå til forrige skilletegn" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Gå til neste skilletegn" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Gå til forrige tabell" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Gå til neste tabell" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Vis en liste med tabeller" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Gå ned en celle" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Gå til den første cellen i en tabell" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Gå til den siste cellen i en tabell" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Gå en celle til venstre" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Gå en celle til høyre" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Gå en celle opp" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Slår av/på utformingsmodus" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Bytt mellom utforskermodus og fokusmodus" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Slå på varig fokusmodus" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Slår på varig utforskingsmodus" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Gå til forrige ubesøkte lenke" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Gå til neste ubesøkte lenke" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Vis en liste med ubesøkte lenker" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Gå til forrige besøkte lenke" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Gå til neste besøkte lenke" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Vis en liste med besøkte lenker" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "alice blå" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antikkhvit" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarin" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "asurblå" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "lys brun" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "sort" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "forvellet mandel" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blå" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "blåfiolett" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "brun" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "storskog" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadettblå" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "sjokolade" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "korall" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "kornblomstblå" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "maissilke" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "blodrød" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "grønnblå" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "mørk blå" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "mørk grønnblå" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "mørk oker" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "mørk grå" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "mørk grønn" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "mørk khaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "mørk magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "mørk olivengrønn" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "mørk oransje" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "mørk orkide" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "mørk rød" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "mørk laks" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "mørk sjøgrønn" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "mørk skiferblå" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "mørk skifergrå" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "mørk turkis" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "mørk fiolett" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "dyp rosa" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "dyp himmelblå" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "uklar grå" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodger blå" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "flammemurstein" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "blomsterhvit" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "skoggrønn" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "spøkelseshvit" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "gull" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "oker" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "grå" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "grønn" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "grønngul" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "honningdugg" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "varm rosa" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indianerrød" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "elfenben" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavendel" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "rødmende lavendel" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "gressgrønn" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "sitronsjiffong" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "lys blå" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "lys korall" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "lys blågrønn" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "lys okergul" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "lys grå" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "lys grønn" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "lys rosa" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "lys laks" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "lys sjøgrønn" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "lys himmelblå" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "lys skifergrå" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "lys stålblå" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "lys gul" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lime" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limegrønn" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "lin" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "rødbrun" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "middels akvamarin" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "middels blå" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "middels orkide" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "middels lilla" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "middels sjøgrønn" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "middels skiferblå" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "middels vårgrønn" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "middels turkis" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "middels fiolettrød" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "midnattblå" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "myntekrem" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "tåkete rose" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokkasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajohvit" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "marine" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "gamle blonder" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliven" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "trist oliven" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oransje" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "oransjerød" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orkide" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "blek oker" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "blek grønn" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "blek turkis" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "blek fiolettrød" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "peach puff" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "plomme" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "pudderblå" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "lilla" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "rød" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rosebrun" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "kongeblå" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "sadelbrun" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "laks" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "sandbrun" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "sjøgrønn" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "sjell" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "sølv" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "himmelblå" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "skiferblå" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "skifergrå" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "snø" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "vårgrønn" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "stålblå" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "gulbrun" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "blågrønn" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "tistel" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomat" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turkis" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "fiolett" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "hvete" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "hvit" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "hvit røyk" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "gul" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "gulgrønn" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktiver" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatisk fokusmodus under strukturell navigering" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatisk fokusmodus ved markørbevegelse" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatisk fokusmodus ved markørbevegelse" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punkt _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punkt _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Punkter 7 o_g 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "A_vbryt" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Gå til" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikon" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Ingen" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Stav" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Si i fra når dine _venner skriver" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Tilby prateromsspesifikke _meldingshistorikker" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Les meldinger fra" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Alle ka_naler" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Alle kanaler når eth_vert %s-vindu er aktivt" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "En kanal kun hvis _vinduet er aktivt" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "Le_s opp navn på samtalerom" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Slå på utformingsmodus for innhold" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dobbeltklikk" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trippelklikk" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Forvalgt synthesizer" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Faktisk streng" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Erstatningsstreng" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Slå på ekko per _tegn" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Slå på _diakritiske tegn uten avstand" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "N_åværende lokasjon" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minste lengde på tekst med treff:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Alternativer for søk" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Uttal k_un endrede linjer under søk" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Uttal resultater under _søk" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Kommando" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Tastaturbinding" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Forvalg" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Utformingsmodus." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Handlinger" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braille-bindinger" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Bokmerker" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Tid og dato" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Forbedringsmodus for mus slått på." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navigering" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objektmodus." - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Ikke bundet" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Forlater flat visningsmodus." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Bytter detaljnivå for tale" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "hovedinnhold" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Endret" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Skrivebord" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Varsling" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Mottatt" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Varsling" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu-innstillinger for %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marker i blindeskrift" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Tilstede med mindre" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Snakk" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Lagre profil som konflikt" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Konflikt i brukerprofil!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profil %s eksisterer allerede.\n" -"Fortsett med å oppdatere eksisterende profil med disse nye endringene?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Last brukerprofil" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Du er i ferd med å endre aktiv profil. Hvis du\n" -"akkurat har gjort endringer i brukervalg vil\n" -"disse bli forkastet ved lasting av profil.\n" -"\n" -"Fortsett med å laste profil og forkaste tidligere endringer?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Lagre profil som" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Navn på _profil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Fjern brukerprofil" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Du er i ferd med å fjerne profil %s. Alle innstillinger som ikke er lagret " -"eller som er lagret i denne profilen vil gå tapt. Vil du fortsette med å " -"fjerne denne profilen og alle dens relaterte innstillinger?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Alle" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Program" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Vindu" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "I_ngen" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Noen" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "M_est" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Linje" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Setning" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Blokksitat" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Knapp" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Bildetekst" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Avkrysningsboks" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Klikkbar" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kombinasjonsboks" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Beskrivelse" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Overskrift" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Bilde" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etikett" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Landemerke" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivå" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Lenke" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Listeoppføring" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekt" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Avsnitt" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radioknapp" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rolle" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Valgt oppføring" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Tilstand" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "tekst" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "Adresse" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Verdi" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blokksitater" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Knapper" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Avkrysningsbokser" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Klikkbare" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kombinasjonsbokser" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Oppføringer" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Skjemafelter" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Overskrifter" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Bilder" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Overskrifter på nivå %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Landemerker" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Store objekter" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Lenker" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Lister" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Listeoppføringer" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Avsnitt" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radioknapper" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabeller" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Lenker som ikke er besøkt" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Besøkte lenker" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Sidenavigering" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Start uttale av en side automatisk når den _lastes første gang" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Presenter et sammendrag av en side når den lastes første gang" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Bryt tale inn i biter mellom pa_user" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s forvalgt stemme" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Forvalgt" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlenke" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "System" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Store bokstaver" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Taleutsender" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Stavekontroll" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Stavef_eil" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Forslag til _staving" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Vis _kontekst for feilen" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Uttal cellekoordinater i regneark" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Annonser celle_topptekst" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Tabellnavigasjon" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Hopp over tomme ce_ller" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Les _celle" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Uttal _cellekoordinater" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Uttal _flere celleområder" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Navn på attributt" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Kontroller markørnavigering" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Slår av/på strukturell navigering" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Lyd_tema:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Lydtema" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Kort" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Varsling" -msgstr[1] "Varsling" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "venstre shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "venstre alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "venstre ctrl" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "høyre shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "høyre alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "høyre kontroll" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "venstre meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "høyre meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "venstre tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "slett" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "retur" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "linjeskift" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "opp" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "ned" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "venstre" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "høyre" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "venstre super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "høyre super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "meny" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "hjelp" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "bytte av modus" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "sett inn" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "slett" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "hjem" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "slutt" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "start" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "cirkumfleks" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "skråstrek" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Sett inn" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "uthevet %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "kursiv %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "uthevet kursiv %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr " skript %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "uthevet skript %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif uthevet %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif kursiv %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif uthevet kursiv %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "enhetlig %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "dotless %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "venstre pil" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "pil opp" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "høyre pil" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "pil ned" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "venstre / høyre pil" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "opp / ned pil" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "nordvest pil" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "nordøst pil" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "sydøst pil" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "venstre pil fra stolpe" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "pil opp fra stolpe" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "høyre pil fra stolpe" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "pil ned fra stolpe" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dobbel venstre pil" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dobbel pil opp" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dobbel pil høyre" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dobbel pil ned" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dobbel pil venstre høyre" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dobbel pil opp ned" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dobbel pil nordvest" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dobbel pil nordøst" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dobbel pil sydøst" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dobbel pil sydvest" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "pil som peker til høyre" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "høyrepekende pilhode" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "mindre enn" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "større enn" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "cirkumfleks" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punktum" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dobbel vertikal linje" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horisontal ellipse" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "for alle" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "komplement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "eksisterer" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "eksisterer ikke" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "tomt sett" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "element av" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "ikke et element av" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "lite element av" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "inneholder som et medlem" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "inneholder ikke som et medlem" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "slutt på bevis" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produkt" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koprodukt" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sum" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus eller pluss" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "dot pluss" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "delingsskråstrek" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "sett minus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "kvadratrot" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "kubikkrot" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "fjerde kvadratrot" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporsjonal til" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "uendelig" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "høyre vinkel" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "vinkel" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "målt vinkel" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sfærisk vinkel" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "deler" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "deler ikke" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paralell til" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "ikke paralell til" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logisk og" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logisk eller" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "skjæringspunkt" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "union" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dobbelt integral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "derfor" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "fordi" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "forholdstall" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporsjon" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "dot minus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "overflod" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrisk proporsjon" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusbølge" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "ikke tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minus tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptotisk lik" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ikke asymptotisk lik" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "tilnærmet lik til" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "tilnærmet men ikke faktisk lik til" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "nesten lik" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ikke nesten lik til" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "nesten lik eller lik til" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "trippel tilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "helt lik" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekvivalent til" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrisk ekvivalent til" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "forskjell mellom" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "nærmer seg grensen" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrisk lik til" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "kolon er lik" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "er lik kolon" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ikke lik" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ikke lik" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "korresponderer til" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estimerer" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "vinkelmessig lik" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "stjerne lik" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta lik" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "lik per definisjon" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "målt av" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "ikke lik" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identisk til" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "ikke identisk til" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "strengt ekvivalent til" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "mindre enn eller lik til" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "større enn eller lik til" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "mindre enn over lik" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "større enn over lik" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "mindre enn men ikke lik til" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "større enn men ikke lik til" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "mye mindre enn" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "mye større enn" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "mellom" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "ikke ekvivalent til" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "ikke mindre enn" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "ikke større enn" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "hverken mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "hverken større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "mindre enn eller ekvivalent til" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "større enn eller ekvivalent til" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "hverken mindre enn eller ekvivalent til" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "hverken større enn eller ekvivalent til" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "mindre enn eller større enn" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "større enn eller mindre enn" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "hverken mindre enn eller større enn" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "hverken større enn eller mindre enn" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "forutgår" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "etterfølger" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "forutgår eller lik" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "etterfølger eller lik" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "forutgår eller ekvivalent" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "etterfølger eller ekvivalent til" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "forutgår ikke" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "etterfølger ikke" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subsett av" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "supersett av" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "ikke et subsett av" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "ikke et supersett av" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subsett av eller lik" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "supersett av eller lik" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "hverken subsett av eller lik" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "hverken supersett av eller lik" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subsett av med ikke lik" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "supersett av med ikke lik" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multisett" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "flervalg" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "kvadratroten" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadratroten" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "kvadratroten" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadratroten" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "subskript er lik" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "bindestrek" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "subskript pluss" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "subskript minus" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "kvadratroten" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "kvadratroten" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "høyre meta" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "venstre tab" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "ned" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "påstand" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modellerer" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "sann" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "tvinger" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "beviser ikke" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "ikke sann" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original av" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "bilde av" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "multi" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "ikke og" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "ikke eller" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "høyre vinkel med bue" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "høyre triangel" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "logisk ikke" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "logisk ikke" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dobbelt subsett" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dobbelt supersett" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dobbelt skjæringspunkt" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dobbel union" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "lik og parallell til" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "mindre enn med dot" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "større enn med dot" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "meget mindre enn" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "meget større enn" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "mindre enn lik eller større enn" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "større enn eller mindre enn" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "lik eller mindre enn" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "lik eller større enn" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "mindre enn men ikke ekvivalent til" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "større enn men ikke ekvivalent til" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "forutgår men er ikke ekvivalent til" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "etterfølger men er ikke ekvivalent til" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "ikke normal undergruppe av" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertikal ellipse" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "venstre tak" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "høyre tak" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "venstre alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "høyre alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "venstre krøllparentes" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "bunn" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "venstre dobbel hakeparentes" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "høyre dobbel hakeparentes" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "bindestrek" - -#: src/cthulhu/mathsymbols.py:2180 -#, fuzzy -msgctxt "math symbol" -msgid "union with dot" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:2182 -#, fuzzy -msgctxt "math symbol" -msgid "union with plus" -msgstr "pluss" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "Søkeretning:" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "kvadratroten" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "sort firkant" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "hvit firkant" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "sort diamant" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "hvit sirkel" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "sort sirkel" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "hvitt kulepunkt" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "sort middels liten firkant" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s med understrek" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s med vertikal linje" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "program" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "blank" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "uthevet" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "bokmerke skrevet inn" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "bokmerker lagret" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "bokmerket kunne ikke bli lagret" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Ingen landemerker funnet." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Ingen landemerker funnet." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Send tastaturkommandoer til applikasjon." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Kan ikke hente kalkulatorvisning" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Stil for tegnsettingsnivå satt til ikon." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ingen" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Stil for tegnsettingsnivå satt til ingen." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "staving" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Tegnsettingsnivå satt til staving." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Programmet styrer markøren." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu kontrollerer markøren." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Celle %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s valgt" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s til og med %s valgt" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "Fjernet utvalg for %s til og med %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "Fjernet utvalg for %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Hindre bruk av et alternativ" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Tvungen bruk av valg" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "ALTERNATIV" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Valgfrie argumenter" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Bruk:" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Følgende er ikke gyldige: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Skriv ut kjente kjørende programmer" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Last profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profilen kunne ikke lastes: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "Kan ikke starte Cthulhu fordi den ikke kan koble til skrivebordet." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Kunne ikke aktivere innstillingshåndterer. Avslutter." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"En annen skjermleserprosess kjører allerede for denne økten.\n" -"Kjør «cthulhu --replace» for å erstatte den prosessen med en ny." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAVN" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Bruk alternativ katalog for brukervalg" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "KATALOG" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versjon av dette programmet" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Erstatt en kjørende forekomst av Cthulhu" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Vis denne hjelpeteksten og avslutt" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Send feilsøkingsdata til debug-YYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Send feilsøkingsinformasjon til oppgitt fil" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FIL" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Sett brukervalg (tekstversjon)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Sett brukervalg (GUI-versjon)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Rapporter feil til https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Klippet ut innhold til utklippstavlen." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "klippet ut" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Kopierte innhold til utklippstavlen." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopierte" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Limte inn innhold fra utklippstavlen." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "limte inn" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Ikke annonser når dine venner skriver." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "annonser når dine venner skriver." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Melding fra samtalerom %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Ny pratefane %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Ikke les opp samtaleromnavn." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "Les opp samtaleromnavn." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Ikke vis prateromspesifikk meldingshistorikk." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Vis prateromspesifikk meldingshistorikk." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "start på sletting" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "slutt på sletting" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "start på innsetting" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "slutt på innsetting" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "start på utheving" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "slutt på utheving" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "slutt på forslag" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Slutt på kontainer." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Ikke i en kontainer." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "alle oppføringer valgt" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Forvalgt knapp er %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Forvalgt knapp er %s" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Forvalgt knapp er %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subskript %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " superskript %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Ikke i en tabell." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "hele dokumentet valgt" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "fjernet utvalg for hele dokumentet" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokument valgt fra markørposisjon" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "dokument valgt bort fra markørposisjon" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokument valgt til markørposisjon" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "dokument valgt bort til markørposisjon" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynamisk kolonneoverskrift satt for rad %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynamisk kolonneoverskrift tømt." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynamisk radoverskrift satt for kolonne %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynamisk radoverskrift tømt." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "tom" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Ingen filer funnet." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "La til innholdet på utklippstavlen." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Kopierte innhold til utklippstavlen." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Bruker ikke flat visning." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Går inn i flat visningsmodus." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Forlater flat visningsmodus." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Flytt flat visning til ordet over gjeldende ord" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Flat gjennomgang ubegrenset" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "har formel" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "åpner dialog" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "åpner rutenett" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "åpner listeboks" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "åpner meny" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "åpner tre" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "bildekartlenke" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Tasten som ble oppgitt er allerede bundet til %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tast fanget: %s. Trykk linjeskift for å bekrefte." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Den nye tasten er: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Tastaturbinding slettet. Trykk linjeskift for å bekrefte." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Tastaturbindingen ble fjernet." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "oppgi ny tast" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tast" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Tasteekko satt til tast." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ingen" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Tasteekko satt til ingen." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tast og ord" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Tasteekko satt til tast og ord." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "setning" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Tasteekko satt til setning." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "ord" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Tasteekko satt til ord." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "ord og setning" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Tasteekko satt til ord og setning." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Omsluttet av: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "en boks" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "en sirkel" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "et langt deletegn" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "en avrundet boks" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "en horisontal gjennomstreking" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "vertikal gjennomstreking" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "diagonal gjennomstreking" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "en nordøst pil" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "en linje nederst" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "en linje til venstre" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "en linje til høyre" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "en linje øverst" - -#: src/cthulhu/messages.py:1017 -#, fuzzy -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "målt vinkel" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "og" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "start på brøk" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "over" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "slutt på brøk" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "kvadratroten av" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "kubikkroten av" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "roten av" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subskript" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "superskript" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pre-subskript" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pre-superskript" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "underskript" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "overskript" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "slutt på tabell" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "slutt på nøstet tabell" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "utilgjengelig" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Slått av" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Leser ikke opp tekstindentering og tekstjustering." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Slått på" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Les opp tekstindentering og tekstjustering." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Læringsmodus. Trykk escape for å gå ut av det." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Går inn i læringsmodus. Trykk en knapp for å høre hva den brukes til. Trykk " -"F1 for å vise dokumentasjonen for skjermleser. Trykk F2 for å få en liste " -"med skjermleserens forvalgte snarveier. Trykk F3 for å få en liste med " -"skjermleserens snarveier for aktivt program. Trykk esc for å avslutte " -"læremodus." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "forlater blokksitat." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "forlater detaljer." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "forlater strøm." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "forlater figur." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "forlater skjema." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "forlater banner." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "forlater komplementært innhold." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "forlater informasjon." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "forlater hovedinnhold." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "forlater navigering." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "forlater region." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "forlater søk." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "forlater liste." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "forlater panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "forlater verktøytips." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "forlater abstrakt." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "forlater bekreftelser." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "forlater etterord." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "forlater appendiks." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "forlater bibliografi." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "forlater kapittel." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "forlater kolofon." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "forlater konklusjon." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "forlater omtale." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "forlater omtaler." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "forlater navigering." - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "forlater banner." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "forlater søk." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "forlater epilog." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "forlater eksempel." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "forlater forord." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "forlater ordliste." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "forlater indeks." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "forlater innledning." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "forlater sideliste." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "forlater del." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "forlater forord." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "forlater prolog." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "forlater blokksitat." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "forlater skjema." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "forlater forslag." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "forlater innholdsfortegnelse." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "linje valgt ned fra markørposisjon" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "linje valgt opp fra markørposisjon" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "linje valgt bort ned fra markørposisjon" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "linje valgt bort opp fra markørposisjon" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Går ut av læringsmodus." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "linje valgt fra start til forrige markørposisjon" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "linje valgt til slutt fra forrige markørposisjon" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "lenke" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "samme side" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "samme nettsted" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "annet nettsted" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s lenker til %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s-lenke" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "besøkte %s-lenke" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Bruk opp og ned pilene for å navigere i listen. Trykk Escape for å avslutte." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Alle levende regioner satt til av" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "nivå for høflighet for levende regioner gjenopprettet" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "høflighetsnivå %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "setter levende region til påståelig" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "setter levende region til av" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "setter levende region til høflig" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "setter levende region til uhøflig" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Overvåking av levende regioner slått av" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Overvåking av levende regioner slått på" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "ingen levende melding lagret" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Støtte for levende regioner er slått av" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Ikke funnet" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Kunne ikke finne nåværende lokasjon." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "av" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "på" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "feilstavet" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Feilstavet ord: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Konteksten er %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Utforskermodus" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Fokusmodus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Trykk %s for å slå på fokusmodus." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Fokusmodus blir husket." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Utforskermodus blir husket." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Utformingsmodus." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objektmodus." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Ingen flere store objekter." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Mus over objekt ikke funnet." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Forbedringsmodus for mus slått av." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Forbedringsmodus for mus slått på." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Feil: Kunne ikke lage liste med objekter." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Ingen barn." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d prosent." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Gå til forrige ord" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nøstenivå %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Ny oppføring er lagt til" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Ingen programmer har fokus." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Ingen fokus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Ingen programmer har fokus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Det finnes ikke flere blokksitater." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Ingen flere knapper." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Ingen flere avkrysningsbokser." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Ingen flere store objekter." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Ingen flere klikkbare." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Ingen flere kombobokser." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Ingen flere oppføringer." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Det finnes ikke flere felt i skjema." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Ingen flere topptekster." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Ingen flere overskrifter på nivå %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Ingen flere tabeller." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Ingen flere bilder." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Ingen landemerker funnet." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Ingen flere lenker." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Det finnes ingen flere lister." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Det finnes ingen flere oppføringer i listen." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Det finnes ikke flere levende regioner." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Ingen flere avsnitt." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Ingen flere radioknapper." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Ingen flere skilletegn." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Ingen flere tabeller." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Det finnes ingen flere ubesøkte lenker." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Det finnes ingen flere besøkte lenker." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Ingen tekst valgt." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Ikke på en lenke." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Varsling" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Bunn" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Topp" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Ingen varslingsmeldinger" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "siffer" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Les opp tall som siffer." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "ord" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Les opp tall som ord." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "av" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "på" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Laster. Vennligst vent." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Fullført lasting." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Fullført lasting av %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Siden har %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "side valgt fra markørposisjon" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "side valgt til markørposisjon" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "side valgt bort fra markørposisjon" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "side valgt bort til markørposisjon" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "avsnitt valgt ned fra markørposisjon" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "avsnitt valgt opp fra markørposisjon" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "avsnitt valgt bort ned fra markørposisjon" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "avsnitt valgt bort opp fra markørposisjon" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Du har allerede en brukervalgdialog for Cthulhu åpent.\n" -"\n" -"Lukk denne før du åpner en ny." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "lysbilde %(position)d av %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil satt til %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Ingen profiler funnet." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Fremdriftsviser %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Alle" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Tegnsettingsnivå satt til alle." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Mesteparten" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Tegnsettingsnivå satt til mesteparten." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ingen" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Tegnsettingsnivå satt til ingen." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Noe" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Tegnsettingsnivå satt til litt." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Søker." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Søk fullført." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu-innstillinger lastet inn på nytt." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Valgt tekst er: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Utvalg slettet." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Utvalg gjenopprettet." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "ikke valgt" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Størrelse: %d, %d. Lokasjon: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Bredde: %d. Høyde: %d. %d fra venstre. %d fra toppen." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Opplesning slått av." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Opplesning slått på." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "raskere." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "saktere." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "høyere." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "lavere." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "høyere." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "mykere." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Hastighet %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Tonehøyde %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volum %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher-modul %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher-stemme %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Ingen Speech-dispatcher-moduler tilgjengelige" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Ingen Speech-dispatcher-stemmer tilgjengelige" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Taleinnstillinger lagret" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Taleinnstillinger kunne ikke lagres" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Detaljnivå: kort" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Detaljnivå: utfyllende" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " prikk prikk prikk" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu ønsker deg velkommen." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu lurer under bølgene." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Hvilemodus aktivert for %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Hvilemodus deaktivert for %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Opplesning er utilgjengelig." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Ikke funnet" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Fant ikke statuslinje" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "streng ikke funnet" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Strukturelle navigasjonstaster er slått av." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Strukturelle navigasjonstaster er slått på." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Ikke funnet" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Rad %(row)d, kolonne %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Slutt på tabell" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Les celle" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Les rad" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Ikke-uniform" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Ikke i en tabell." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Kolonner sortert" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Rader sortert" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "kolonne %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolonne %(index)d av %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Bunnen på kolonnen." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Toppen på kolonnen." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Kolonne %s valgt" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Kolonner %s til og med %s valgt" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Fjernet utvalg for kolonne %s til og med %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Fjernet utvalg for kolonne %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "rad %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "rad %(index)d av %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Begynnelse av rad." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Slutten av rad." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Rad slettet." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Siste rad slettet." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Rad satt inn." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Rad satt inn ved slutten av tabellen." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Rad %s valgt" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Rad %s til og med %s valgt" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Fjernet utvalg for rad %s til og med %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Fjernet utvalg for rad %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "valgt" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "ikke valgt" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H timer, %M minutter og %S sekunder" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H timer og %M minutter" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "angre" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "gjør om" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versjon %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "mellomrom" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Går rundt til bunnen." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Går rundt til toppen." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 oppføringer" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Cellen går over %d rad" -msgstr[1] "Cellen går over %d rader" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d kolonne" -msgstr[1] " %d kolonner" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Cellen går over %d kolonne" -msgstr[1] "Cellen går over %d kolonner" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d tegn for lang" -msgstr[1] "%d tegn for lang" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialog)" -msgstr[1] "(%d dialoger)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d dialog uten fokus" -msgstr[1] "%d dialoger uten fokus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fil funnet" -msgstr[1] "%d filer funnet" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d skjema" -msgstr[1] "%d skjema" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d overskrift" -msgstr[1] "%d overskrifter" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d oppføring" -msgstr[1] "%d oppføringer" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d landemerke" -msgstr[1] "%d landemerker" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d oppføring funnet" -msgstr[1] "%d oppføringer funnet" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Forlater %d blokksitat." -msgstr[1] "Forlater %d blokksitater." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Forlater %d liste." -msgstr[1] "Forlater %d lister." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Liste med %d oppføring" -msgstr[1] "Liste med %d oppføringer" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Liste med %d oppføring" -msgstr[1] "Liste med %d oppføringer" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Verdi" -msgstr[1] "Verdi" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "matematisk tabell med %d rad" -msgstr[1] "matematisk tabell med %d rader" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d kolonne" -msgstr[1] "%d kolonner" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "nøstet matematisk tabell med %d rad" -msgstr[1] "nøstet matematisk tabell med %d rader" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d melding.\n" -msgstr[1] "%d meldinger.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d prosent." -msgstr[1] "%d prosent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d prosent av dokumentet er lest" -msgstr[1] "%d prosent av dokumentet er lest" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d piksel" -msgstr[1] "%d piksler" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] " %(count)d %(repeatChar)s tegn" -msgstr[1] " %(count)d %(repeatChar)s tegn" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d av %(total)d oppføring valgt" -msgstr[1] "%(index)d av %(total)d oppføringer valgt" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d forvalgt snarvei for skjermleser funnet." -msgstr[1] "%d forvalgte snarveier for skjermleser funnet." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d skjermleser-snarvei for %(application)s funnet." -msgstr[1] "%(count)d skjermleser-snarveier for %(application)s funnet." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d mellomrom" -msgstr[1] "%d mellomrom" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulator" -msgstr[1] "%d tabulatorer" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabell" -msgstr[1] "%d tabeller" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "innholdsfortegnelse" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabell med %d rad" -msgstr[1] "tabell med %d rader" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabell med %d rad" -msgstr[1] "tabell med %d rader" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabell med %d rad" -msgstr[1] "tabell med %d rader" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d lenke som ikke er besøkt" -msgstr[1] "%d lenker som ikke er besøkt" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d besøkt lenke" -msgstr[1] "%d besøkte lenker" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "bryter" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "ved %(index)d av %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d av %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVÅ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "trenivå %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TRENIVÅ %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detaljer for %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "har detaljer i %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "forslag" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "redigerbar komboboks" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "redigerbart innhold" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "strøm" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figur" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "abstrakt" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "etterord" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "appendiks" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "bibliografioppføring" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografi" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "kapittel" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "kolofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "konklusjon" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "omslag" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "retning" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "eksempel" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "forord" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "ordliste" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "indeks" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "innledning" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "sideskift" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "sideliste" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "del" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "forord" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "sitattegn" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "undertittel" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "innholdsfortegnelse" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivå %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "horisontalt rullefelt" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "vertikalt rullefelt" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "horisontalt rullefelt" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "vertikalt rullefelt" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "horisontal delelinje" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "vertikal delelinje" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "bytt" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Ikonpanel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "banner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "komplementært innhold" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informasjon" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "hovedinnhold" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigering" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "region" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "søk" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "besøkt lenke" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "menyknapp" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "sortert stigende" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "sortert synkende" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "sortert" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klikkbar" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "sammenslått" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "utvidet" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "har lang beskrivelse" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horisontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikal" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "merket av" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "ikke merket av" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "på" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "av" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "delvis merket av" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "trykket" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ikke trykket" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "ikke valgt" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "valgt" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ikke valgt" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "ikke valgt" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "besøkt" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "ikke besøkt" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "grået ut" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "skrivebeskyttet" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "skrivebeskyttet" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "krevet" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "flervalg" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "ugyldig oppføring" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "ugyldig" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ugyldig staving" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "staving" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "ugyldig gramatikk" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatikk" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Finn" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Søkedialog for skjermleser" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Lukk" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Finn" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Søk etter:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Søk etter:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Toppen av vinduet" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Toppen av vinduet" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Start fra:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Bryt" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Søk _bakover" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Søkeretning:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Treff på små/store bokstaver" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Treff kun på h_ele ord" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Alternativer:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Forvalg" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Store bokstaver" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlenke" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "System" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Program" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Vindu" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu-innstillinger" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Hjelp" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Bruk" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Bærbar" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Tastaturutforming" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktiv _profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Oppstartsprofil:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Last" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Lagre _som" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "Fje_rn" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiler" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Vis verktøytips" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Les objektet under m_usen" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Mus" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Tidformat:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Dato_format:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Tid og dato" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Les oppdateringer" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Oppdateringer for _blindeskrift" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frekvens (sekunder):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Brukes på:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Oppdateringer for fremdriftsviser" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Slå på strukturell navigering i Si alt" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Si alt e_tter:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Les opp alt" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Element_presentasjon:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Generelt" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lum:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Tone_høyde" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Rate:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Person:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Språk" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Opplesningssynthesi_zer:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Opplesnings_system:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Stemmetype:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Stil for tegnsetting:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Stemmetypeinnstillinger" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Uttal strenger med blanding av store og små bokstaver som or_d" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Les opp _nummer som sifre" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Globale stemmeinnstillinger" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Stemme" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Slå på opplesning" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Ekstra informasjon" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Detaljgrad" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Alle" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Tegnsettingsnivå" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Uttal kun vist tekst" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Tal tomme linjer" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Les opp tekst_indentering og tekstjustering" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Les hurtigtast for obje_kt" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Uttal underp_osisjon" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Les hjelpmeldinger" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Systemmeldinger er detaljerte" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Uttal _farger som navn" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Annonser blokk_sitater under navigering" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Annonser _lister under navigering" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Annonser _tabeller under navigering" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Indikator for uttale av _feilstavede ord" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Annonser _paneler under navigering" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Annonser lande_merker under navigering" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Annonser _skjema under navigering" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Uttal _beskrivelse" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Uttal full rad i _regneark" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Uttal full rad i _dokumenttabeller" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Uttal full rad i _GUI-tabeller" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Uttalt kontekst" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Tale" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Slå på braille_støtte" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Forkortedde rollenavn" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Slå av symbol _for slutt på linjen" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Sammentrekkings_tabell:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Slå på sammentrukket Braille" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Slå på _ordbryting" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Innstillinger for skjerm" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "I_ngen" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indikator for utvalg" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indikator for hyperlenke" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Slå på korte _meldinger" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Varighet (sekunder):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Meldinger er _persistente" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Meldinger er _detaljerte" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Innstillinger for korte meldinger" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Slå på taste_ekko" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Slå på _alfabetiske taster" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Slå på _numeriske taster" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Slå på _taster for tegnsetting" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "_Slå på mellomrom" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Slå på _modifiseringstaster" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Slå på _funksjonstaster" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Slå på _aksjonstaster" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Slå på _navigasjonstaster" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Slå på _ordekko" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Slå på _setningsekko" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Ekko" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "E_ndringstast(er) for skjermleser:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Tastaturbindinger" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Ordbok for uttale" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Ny oppføring" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Slett" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Uttale" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Si alt" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Ikke s_nakk" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Nullstill" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Tekstattributter" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Flytt til _bunn" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Flytt en ne_d" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Flytt en _opp" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Flytt til _toppen" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Juster valgt attributt" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indikator for blindeskrift" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Tekstattributter" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Aktiver AI-assistent" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Leverandør:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokal - Gratis)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API-_nøkkelfil:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Sti til API-nøkkelfil" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Hent _Claude API-nøkkel" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Åpne nettleser for å hente Claude API-nøkkel og lagre automatisk" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Krev bekreftelse før AI-handlinger" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama-_modell:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Modellnavn for Ollama (f.eks. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama-_endepunkt:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API-endepunkt-URL (f.eks. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Skjermbilde_kvalitet:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Lav" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Medium" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Høy" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI-assistent" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Språkkode:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Skaleringsfaktor:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Gråtonebilde" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Inverter bilde" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Svart-hvitt bilde" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Svart/hvitt-_terskel:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analyser farger" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Kopier resultater til _utklippstavle" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"\"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"\"\n" -"\"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"\"\n" -"\"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : " -"tango, \"\n" -"\"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu, æ : " -"ærlig, ø : østen, å : åse" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "bakgrunnsfarge" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "bakgrunn full høyde" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "bakgrunn stiplet" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "retning" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "redigerbar" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "familienavn" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "forgrunnsfarge" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "forgrunn stiplet" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "effekt for skrift" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "innrykk" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "feil" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "usynlig" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justering" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "språk" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "venstre marg" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "linjehøyde" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "stil for avsnitt" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "piksler over linjer" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "piksler under linjer" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "piksler i bryting" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "høyre marg" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "hev" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "skalering" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "størrelse" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "strekk" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "gjennomstreking" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "tekstdekorasjon" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "tekstrotasjon" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "tekstskygge" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "understrek" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "vertikal justering" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "vekt" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "brytningsmodus" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "skrivemodus" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "sann" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "usann" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ingen" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "graver" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "uthev" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "omriss" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "overstrek" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "gjennomstrek" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "blink" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "sort" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "enkel" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dobbel" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "lav" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "tegn" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "ord" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "ordtegn" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "venstre" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "høyre" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "senter" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "ingen justering" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "fyll" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultratett" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "ekstra sammentrukket" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "sammentrukket" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "litt sammentrukket" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "delvis utvidet" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "utvidet" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "ekstra utvidet" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultrautvidet" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "kapitéler" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "skråstilt" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kursiv" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Forvalg" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "tekstkropp" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Overskrift" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "grunnlinje" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "topp" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "tekst-øverst" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "midt" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "bunn" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "tekst-nederst" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "arv" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "helfylt" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "staving" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Trykk mellomrom for å bytte." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Trykk mellomrom for å utvide og bruk opp og ned for å velge en oppføring." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Trykk alt+f6 for å gi fokus til undervinduer." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "Bruk piltaster for å gå til oppføringer eller skriv for å søke." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Trykk alt+f1 for å gå til systemmenyen." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Bruk opp og ned for å velge en oppføring." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Trykk shift og venstre for å slå sammen." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Trykk shift og høyre for å utvide." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Trykk linjeskift for å aktivere." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Skriv inn tekst." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Bruk venstre og høyre for å vise andre faner." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Trykk mellomrom for å aktivere." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Bruk pil opp eller ned for å velge en verdi. Eller skrif inn ønsket numerisk " -"verdi." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Bruk piltaster for å endre." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Trykk venstre eller høyre pil for å navigere. For å gå gjennom oppføringer " -"trykk pil opp eller ned." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Trykk høyre pil for å gå inn i undermeny." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Trykk pil til venstre for å minske, og pil til høyre for å øke. For å gå til " -"laveste verdi trykk home og trykk end for høyeste verdi." diff --git a/po/ne.po b/po/ne.po deleted file mode 100644 index f3652d1..0000000 --- a/po/ne.po +++ /dev/null @@ -1,9312 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: Gnome Nepali Translation Project\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2022-09-11 05:59+0545\n" -"Last-Translator: Pawan Chitrakar \n" -"Language-Team: Nepali Translation Team \n" -"Language: ne\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.0.1\n" - -msgid "Cthulhu Screen Reader" -msgstr "ओर्का दृष्टि वाचक" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "दृष्टि वाचक; वाचन;ब्रेल;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "डायल" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "पातो" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "चोप्लनु" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "रेखाङ्कन गर" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "फारम" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "लिङ्क" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "सुची" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "सुची सामाग्री" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "मेनु" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "मेनु सामाग्री" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "टाँक" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "रेडियो" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "विभाजक" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "सु लुली" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "चेक तह १" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "स्पेनिस श्रेणी १" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "क्यानाडेली फ्रेन्च श्रेणी २" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "फ्रान्सेली श्रेणी २" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "लाट्भेयाली श्रेणी १" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "नेदर्ल्याणडेली श्रेणी १" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "नर्बेजीयाली श्रेणी ०" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "नर्बेजीयाली श्रेणी १" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "नर्बेजीयाली श्रेणी २" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "नर्बेजीयाली श्रेणी ३" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "पोल्याण्डेली श्रेणी १" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "पुर्तगाली श्रेणी १" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "स्वीडेने ली श्रेणी १" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "अरबी श्रेणी १" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "वेल्स श्रेणी १" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "वेल्स श्रेणी २" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "जर्मनी श्रेणी ०" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "जर्मनी श्रेणी १" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "जर्मनी श्रेणी २" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "बेलायती अङ्ग्रेजी श्रेणी २" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "बेलायती अङ्ग्रेजी श्रेणी १" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "अमेरिकी अङ्ग्रेजी श्रेणी १" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "अमेरिकी अङ्ग्रेजी श्रेणी २" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "क्यानाडेली फ्रान्सेली श्रेणी १" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "फ्रान्सेली श्रेणी १" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "ग्रिक श्रेणी १Greek Grade 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "हिन्दी श्रेणी १" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "हङ्गेरीयाली ८ थोप्ले कल्पयन्त्र" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "हङ्गेरीयाली श्रेणी १" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "हङ्गेरीयाली श्रेणी २" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "इटाली श्रेणी १" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "बेल्जीयम डच श्रेणी १" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "space" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "नयाँ पङ्ति" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "ट्याब" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "विस्मय चिन्ह" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "जोडी उद्धरण" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "सङ्ख्या" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "डलर" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "प्रतिशत" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "and" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "उद्धरण" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "देब्रे कोष्ठ" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "दाहिने कोष्ठ" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "तारा" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "जोड" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "अल्प विराम" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "ड्यास" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "थोप्लो" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slash" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "विराम" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "अर्ध विराम" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "भन्दा सानो" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "बराबर" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "भन्दा ठूलो" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "प्रश्न चिन्ह" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "देब्रे ठूलो कोष्ठ" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "backslash" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "दाहिने ठूलो कोष्ठ" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "caret" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "अधोरेखाङ्कित" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "देब्रे मझौला कोष्ठ" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "ठाडो धर्को" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "दाहिने मझौला कोष्ठ" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "उस्तै " - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "अटुट खाली" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "उल्टो विस्मय चिन्ह" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cents" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pounds" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "मुद्रा चिन्ह" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "येन" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "विच्छेद पट्टी" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "खण्ड" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diaeresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "प्रतिलिपि" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "देब्रे दोबर कोण" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "तार्किक छैन" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "सानो हाईफन" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "दर्ता" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "डिग्री" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "जोड वा घटाउ" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superscript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superscript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "न्यून" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "अनुच्छेद चिनो" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "माझको थोप्लो" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superscript 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "दाहिने दोब्बर कोण" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "एक चौथाइ" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "आधा" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "तीन चोथाई" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "उल्टो प्रश्न चिन्ह" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "times" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "divided by" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "देब्रे एकल उद्धरण" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "दाहिने एकल उद्धरण" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "एकल उद्धरण" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "देब्रे जोडी उद्धरण" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "दाहिने जोडी उद्धरण" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "जोडी उद्धरण" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "भाला" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "जोडी भाला" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "गोली" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "त्रीकोणीय गोली" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "प्रमुख" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "जोडी प्रमुख" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "तीन अभाज्य" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "हाईफन गोली" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "निसान छाप" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "ठीक चिनो" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "मोटो टिक चिनो" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "कैँची आकारको गोली" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "टाउकोमा ०" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "टाउकोमा ४" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "टाउकोमा ५" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "टाउकोमा ६" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "टाउकोमा ७" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "टाउकोमा ८" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "टाउकोमा ९" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "टाउकोमा जोड" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "टाउकोमा घटाउ" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "टाउकोमा बराबर" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "टाउकोमा देब्रे कोष्ठ" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "टाउकोमा दाहिने कोष्ठ" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "टाउकोमा n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "पैतालोमा ०" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "पैतालोमा १" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "पैतालोमा २" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "पैतालोमा ३" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "पैतालोमा ४" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "पैतालोमा ५" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "पैतालोमा ६" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "पैतालोमा ७" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "पैतालोमा ८" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "पैतालोमा ९" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "पैतालोमा जोड" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "पैतालोमा घटाउ" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "पैतालोमा बराबर" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "पैतालोमा देब्रे कोष्ठ" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "पैतालोमा दाहिने कोष्ठ" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "कालो वर्ग" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "कालो हिरा" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "वस्तु प्रतिस्थापन वर्ण" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "हालको वस्तुमा सूचक राउट गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "हालको समतल पुनरावलोकन वस्तुमा बायाँ क्लिक गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "हालको समतल पुनरावलोकन वस्तुमा दायाँ क्लिक गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "पुरै कागजात बोल्नुहोस्" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "समतल पुनरावलोकन प्रयोग गरेर पूरै सञ्झ्याल बाचन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "मैले सञ्चालन गरेको ठाउँमा आधारभूत कार्य गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "म कहाँ छु सञ्चालन को विस्तृत कार्य गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "हालको चयन वाचन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "लिङ्क विवरण वाचन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "स्थितिपट्टी बोल्नुहोस्" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "शीर्षकपट्टी बोल्नुहोस्" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "खोज्ने संवाद खोल्नुहोस्" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "अर्को सूचीमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "खोजी स्ट्रिङको पछिल्‍‌लो घटना फेला पार्नुहोस्" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "खोजी स्ट्रिङको अघिल्लो घटना फेला पार्नुहोस्" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "समतल पुनरावलोकन मोड प्रविष्ट गर्नुहोस् र अन्त्य गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "समतल पुनरावलोकनलाई अन्त्य स्थितिमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "समतल पुनरावलोकनलाई गृह स्थितिमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "समतल पुनरावलोकनलाई अन्त्य स्थितिमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "समतल पुनरावलोकनलाई अघिल्लो रेखाको सुरुआतमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "हालको समतल पुनरावलोकन पङ्ति बाचन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "हालको समतल पुनरावलोकन पङ्तिको हिज्जे बताउँछ" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "हालको समतल पुनरावलोकन पङ्तिको हिज्जे स्वर बताउँछ" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "समतल पुनरावलोकनलाई पछिल्लो लाइनरको सुरुमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "समतल पुनरावलोकनलाई अघिल्लो वस्तु वा शब्दमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "हालको समतल पुनरावलोकन वस्तु वा शब्द बाचन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "हालको समतल पुनरावलोकन वस्तु वा शब्द हिज्जे जाच्नुहोस्" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "हालको समतल पुनरावलोकन वस्तु वा शब्दको हिज्जे स्वर बताउँछ" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "समतल पुनरावलोकनलाई पछिल्लो वस्तु वा शब्दमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "समतल पुनरावलोकनलाई हालको शब्द माथिको शब्दमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "हालको समतल पुनरावलोकन वस्तु बाचन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "समतल पुनरावलोकनलाई हालको शब्द तलको शब्दमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "समतल पुनरावलोकनलाई अघिल्लो वर्णमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "हालको समतल पुनरावलोकन क्यारेक्टर बाचन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "हालको समतल पुनरावलोकन वर्ण बाचन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "हालको समतल पुनरावलोकन वर्ण युनिकोड मान बाचन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "समतल पुनरावलोकनलाई पछिल्लो वर्णमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "समतल पुनरावलोकनलाई रेखाको अन्त्यमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "समतल पुनरावलोकन लाई तल बायाँ तिर सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "समतल पुनरावलोकन अन्तर्गतका सामाग्री क्लिपबोर्डमा प्रतिलिपि बनाउनुहोस्" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "क्लिपबोर्डमा समतल पुनरावलोकन अन्तर्गत सामग्रीहरू थप्नुहोस्" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "समतल पुनरावलोकनलाई अन्त्य स्थितिमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "हालको तालिका कक्ष मात्र पढ्ने वा पूरै पङ्क्ति पढ्ने टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "हालको पाठ वर्णसँग सम्बन्धित विशेषताहरू पढ्नुहोस्" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "अन्धलिपि प्रदर्शन बायाँ तिर प्यान गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "दाँयामा ब्रेल प्रदर्शन प्यान गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "कुञ्जीपाटीमा केन्द्रीयता दिँदै वस्तुमा फर्कन्छ ।" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "_संक्षेपित ब्रेललाई सक्षम बनाउ ।" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "कर्सर Routing" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "पाठ चयनको सुरुआतमा चिनो लगाउनुहोस्" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "पाठ चयनको अन्त्यमा चिनो लगाउनुहोस्" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "सिकाई मुद्रामा जान्छ । यस मुद्राबाट बाहिरिन escape दबाउनु होस् ।" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "बाचन दर घटाउनुहोस्" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "बाचन दर बढाउनुहोस्" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "बाचन पिच घटाउनुहोस्" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "बाचन पिच बढाउनुहोस्" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "वाचन भोल्युम बढाउनुहोस्" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "वाचन भोल्युम घटाउनुहोस्" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "खोजी स्ट्रिङको अघिल्लो घटना फेला पार्नुहोस्" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "चाहेको वाचन सर्बरको चयन गर्नु होस् । " - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "बाचन दर घटाउनुहोस्" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "बाचन दर बढाउनुहोस्" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "आवाज किसिम अनुकूलता" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "वाचन तह टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "बाचन भर्बोसिटी स्तर टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "सजावट मोड टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "दृष्टि वाचक अन्त्य गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "प्राथमिकता कन्फिगरेसन संवाद प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "अनुप्रयोग प्राथमिकता कन्फिगरेसन संवाद प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "इन्डेन्टेसन र स्पष्टीकरण को वाचन टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "बोलिने नम्बर शैली परिवर्तन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "अर्को चिन्ह वाचन तहमा घुम्छ ।" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "पछिल्लो कुञ्जी प्रतिध्वनि तहमा परिचक्र गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "पछिल्लो सेटिङ प्रोफाइलमा चक्र लगाउनुहोस्" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Capitalization शैली हिज्जेमा कायम गरियो ।" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "पछिल्लो कुञ्जी प्रतिध्वनि तहमा परिचक्र गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "चालु समयमा त्रुटि सच्याउने तह लाई परिक्रमण गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "चालू स्थानको आधारमा म कहाँ छु भन्ने चिनो" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "अघिल्लो पुस्तकचिनो स्थानमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "पुस्तकचिनो जानुहोस्" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "अर्को पुस्तकचिनो स्थानमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "पुस्तकचिनो थप्नुहोस्" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "पुस्तकचिनोहरू बचत गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "माउस समीक्षा मोड टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "हालको समय" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "हालको मिति" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "हालको वस्तुको साइज र स्थान" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "अघिल्लो आदेश वर्तमान अनुप्रयोगलाई दिन्छ ।" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "अघिल्लो कुराकानी कोठा सन्देश वाचन गर्नुहोस् र अन्धलिपि गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "हाम्रा साथीहरूले टाइप गर्दा हामीले घोषणा गरेका छौं या छैनौं टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "यदी हामीले उपलब्ध गराएको गफगाफ कोठा विशेष सन्देश इतिहास छ भने साटो फेरो गर ।" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "गफगाफ कोठा सन्देश पूर्व कायम गरिएको गफगाफ कोठाको नाम सित साटो फेरो गर" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "देब्रे पङ्ति" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "दाहिने पङ्ति" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "माथिल्लो पङ्ति" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "तल्लो पङ्ति" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "जम्नु" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "माथि देब्रे " - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "वायाँ फेद" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "कर्सर स्थान" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "छ थोप्ले" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "कर्सर Routing" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "कटाई थालनी" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "पङ्ति कटाई" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "अन्तिम सूचना सन्देश प्रस्तुत गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "सूचना सन्देश सुची उपलब्ध गराउ ।" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "अघिल्लो सूचना सन्देश प्रस्तुत गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "अन्तिम सूचना सन्देश प्रस्तुत गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "अर्को वर्णमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "अघिल्लो वर्णमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "अर्को शब्द जानुहोस्" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "अघिल्लो शब्दमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "अर्को पङ्क्तिमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "अघिल्लो पङ्तिमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "फाइलको माथितिर जानुहोस्" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "फाइलको तलतिर जानुहोस्" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "पङ्क्तिको सुरुआतमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "पङ्क्तिको अन्त्यमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "अर्को वस्तुमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "अघिल्लो वस्तुमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "चालू कम्बो बाकसलाई फैलिएको रूपमा ले जाने छ ।" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "नेटिभ र दृष्टिवाचक caret नेभिगेसन बीचमा स्विच गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "उन्नत जीवन्त क्षेत्रको नम्रता सेटिङ" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "पूर्वनिर्धारित जीवन्त क्षेत्र नम्रता तह बन्द मा सेट गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "जीवन्त क्षेत्रको घोषणाको समिक्षा गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "जीवन्त क्षेत्रको अनुगमन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "फोकसलाई हालको माउस बाट माथि र बाहिर सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "गतिशील स्तम्भ हेडरको रूपमा प्रयोग गर्न पङ्क्ति सेट गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "गतिशिल स्तम्भ हेडर खाली गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "गतिशिल पङ्क्ति हेडरको रूपमा प्रयोग गर्न स्तम्भ सेट गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "गतिशिल पङ्क्ति हेडर खाली गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "आगत रेखाको सामाग्री प्रस्तुत गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "संरचनागत नेभिगेसन कुञ्जीहरू टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "अघिल्लो उद्धरणमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "अर्को उद्धरणमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "बन्द गरिएको उद्धरणको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "अघिल्लो बटनमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "अर्को बटनमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "बटनको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "अघिल्लो जाँच बाकसमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "अर्को जाँच बाकसमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "जाँच बाकसहरूको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "अघिल्लो क्लिक योग्यमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "अर्को क्लिक योग्यमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "क्लिक गर्न सकिने सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "अघिल्लो कम्बो बाकसमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "अर्को कम्बो बाकसमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "कन्टेनरको सुरुमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "कन्टेनरको अन्त्यमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "कम्बो बाकसहरूको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "अघिल्लो प्रविष्टिमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "अर्को प्रविष्टिमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "प्रविष्टिहरूको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "अघिल्लो फारम फाँटमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "अर्को फारम फाँटमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "फारम फाँटहरूको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "अघिल्लो शिर्षकमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "अर्को शिर्षकमा सार्नुहोस्" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "हेडरको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "अघिल्लो शीर्षक तह %d मा जानुहोस्" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "अर्को शीर्षक तह %d मा जानुहोस्" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "तह %d मा शीर्षकहरूको सुची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "अघिल्लो तालिकामा जानुहोस्" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "अर्को तालिका जानुहोस्" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "तालिकाको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "अघिल्लो छविमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "अर्को छविमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "छविहरूको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "अघिल्लो ल्यान्डमार्कमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "अर्को ल्यान्डमार्कमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "ल्यान्डमार्कको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "अघिल्लो ठूलो वस्तुमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "अर्को ठूलो वस्तुमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "ठूलो वस्तुको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "अघिल्लो लिङ्कमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "अर्को लिङ्कमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "लिङ्कहरूको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "अघिल्लो सूचीमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "अर्को सूचीमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "सूचीको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "अघिल्लो वस्तु सूचीमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "अर्को वस्तु सूचीमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "सूची वस्तुको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "अघिल्लो जीवन्त क्षेत्रमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "पछिल्लो जीवन्त क्षेत्रमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "घोषणा गरेको अन्तिम जीवन्त क्षेत्रमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "कुञ्जीपाटीमा केन्द्रीयता दिँदै वस्तुमा फर्कन्छ ।" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "संरचनागत नेभिगेसन कुञ्जीहरू टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "अघिल्लो अनुच्छेद जानुहोस्" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "अर्को अनुच्छेद जानुहोस्" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "अनुच्छेदहरूको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "अघिल्लो रेडियो बटन जानुहो्स" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "अर्को रेडियो बटन जानुहो्स" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "रेडियो बटनको सुची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "अघिल्लो विभाजक जानुहोस्" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "अर्को विभाजक जानुहोस्" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "अघिल्लो तालिकामा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "अर्को तालिका जानुहोस्" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "तालिकाको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "एउटा कक्ष तल जानुहोस्" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "तालिकाको पहिलो कक्षमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "तालिकाको अन्तिम कक्षमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "एउटा कक्ष बाँया जानुहोस्" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "एउटा कक्ष माथि जानुहोस्" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "एक कक्ष माथि जानुहोस्" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "सजावट मोड टगल गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "उघार्ने मुद्रा र केन्द्रीयता मुद्रामा हेरफेर हुन्छ ।" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "टाँसिने फोकस मोड सक्षम पार्नुहोस्" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "टाँसिने ब्राउज मोड सक्षम पार्नुहोस्" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "अघिल्लो नहेरेको लिङ्कमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "अर्को नहेरेको लिङ्कमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "नहेरिएको लिङ्कको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "अघिल्लो हेरेको लिङ्कमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "अर्को हेरेको लिङ्कमा जानुहोस्" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "हेरिएको लिङ्कको सूची प्रदर्शन गर्नुहोस्" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "अलिस नीलो" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "चम्किलो सेतो" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "जल समुद्री" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azure" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "कालो" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "blanched almond" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "नीलो" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "निलो इन्द्रेणी" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "खैरो" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "बलिउड" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "क्याडेट नीलो" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "कलेजी" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "मुगा" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "मकैफुलेनीलो" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "रेसमी" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "गाढा कलेजी" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "हल्का कलेजी" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "गाढा नीलो" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "गाढा रातो" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "गाढा पहेलो चट्टानी" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "गाढा खैरो" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "गाढा हरियो" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "गाढा खागी" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "गाढा magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "गाढा जैतुन" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "गाढा सुन्तला" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "गाढा ओर्किड" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "गाढा रातो" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "गाढा साल्मनी" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "गाढा समुद्री" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "गाढा पाटी नीलो" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "गाढा पाटीखैरो" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "गाढा turquoise" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "गाढआ इन्द्रेणी" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "गाढा पहेलो" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "आकाशे गाढा नीलो" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "मलिन खैरो" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "डोजर नीलो" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "इटा" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "पिठे सेतो" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "जङ्गली हरियो" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "अबिरे" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "भुत सेतो" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "सुनौलो" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "सुनोलो चट्टान" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "खैरो रङ्गिन " - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "हरियो" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "निलो पहेँलो" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "मह" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "तातो बेसारे" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "भारतीय रातो" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "इन्द्रेणी" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "गाढा गुलाबी" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "खागी" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "उजाड" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "चिल्लो उजाड" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "चउरे हरियो" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "हल्का कागति" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "हल्का निलो " - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "हल्का मुगा" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "हल्का कलेजी" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "हल्का सुनौलो पहेँलो" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "हल्का खैरो" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "हल्का हरियो" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "हल्का बेसारे" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "हल्का साल्मनी" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "हल्का समुद्रीहरियो" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "हल्का आकाशेनीलो" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "हल्का पाटीखैरो" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "हल्का इस्पाती नीलो" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "हल्का पहेँलो" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "कागती" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "कागती हरियो" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "रेखिय" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "गम्भिर" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "मध्यम जल समुद्री" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "मध्यम निलो" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "मध्यम आर्किड" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "मध्यम प्याजी" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "मध्यम समुद्रीहरियो" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "मध्यम पाटी निलो" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "मध्यम बसन्त हरियो" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "मध्यम turquoise" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "मध्यम इन्द्रेणी रातो " - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "मध्य रात निलो" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "दुधिलो" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "गुलाबी रहस्य" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "moccasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navaj सेतो" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "समुन्द्री नीलो" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "पुरानो फिता" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "जैतुन" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "कडा जैतुन" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "सुन्तला" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "सुन्तला रातो" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "ओर्किड" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "सुनौलो पहेलो " - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "पहेलो हरियो" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "हल्कापहेलो" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "पहेलो इन्द्रेणी" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "मेवा" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "आरु" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "पेरु" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "बेसारे" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "गाढा बेसारे" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "धुले नीलो" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "बैजनी" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "रातो" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "खैरो गुलाबी" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "राजकिय नीलो" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "खरानी खैरो" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "साल्मनी" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "बालुवा खैरो" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "समुद्री हरियो" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "सङ्खे सेतो" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "चाँदी" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "आकाशेनीलो" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "पाटी नीलो" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "पाटी" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "बरफी" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "बसन्त हरियो" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "त्रिब्र नीलो" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "अलकत्रे" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "गाढा नीलो" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "thistle" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "गोलभेंडा" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquoise" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "इन्द्रेणी" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "गहुँगोरो" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "सेतो" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "सेतो धुवाँ" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "पहेँलो" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "पहेँलो निलो" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_सक्रिय बनाउ" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "संरचना विचरणमा स्वचालित केन्द्रीयता" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "caret को गति अनुसार स्वचालित केन्द्रीयता मुद्रा" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "caret को गति अनुसार स्वचालित केन्द्रीयता मुद्रा" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "थोप्लो _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "थोप्लो _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "थोप्लो 7 र 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_रद्द" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_जाउ " - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_हो" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "प्रतिमा" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "केही छैन" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "हिज्जे" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "तपाइका _buddies ले टङ्कण गरेको बताउ ।" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "गफगाफ कोठा विशेष _सन्देश इतिहास उपलब्ध गराउ ।" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "सन्देश बताउ मार्फत " - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "सबै च्यानेल" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "सबै च्यानेलहरू जब एउटा _y %s विन्डो सक्रिय हुँदा " - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "यदि सन्झ्याल सक्रिय छ भने एउटा च्यानल मात्रै " - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_गफगाफ कोठाको नाम बताउ" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "सामाग्रीका लागि रूपरेखालाई सक्षम बनाउ ।" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "दुई पटक किटिक्क" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "तीन पटक किटिक्क" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "निर्धारित संश्लेषक" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "वास्तविक पदावली" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "प्रतिस्थापन पदावली" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "वर्ण प्रतिध्वनि सक्षम बनाउ ।" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "नसर्ने _diacritical कुञ्जी सक्षम बनाउ ।" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "चालू स्थान " - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "जोडा मिलाएका पाठको न्यूनतम लम्बाइ " - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "विकल्प फेला पार ।" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "खोजी गर्दा फेरिएका पङ्ति मात्रै बताउ ।" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "खोजी गर्दा नतिजा बताउ ।" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "आदेश" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "कुञ्जी बन्धन" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "निर्धारित कुञ्जीवद्धता" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "रूपरेखा मुद्रा" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "खण्ड" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ब्रेल नाता" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "पुस्तकचिनोहरू बचत गर्नुहोस्" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "समय र मिति" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "माउस समीक्षा सक्षम पारियो ।" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "नेभिगेशन" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "वस्तु मुद्रा" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "अनुबद्ध" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "पुर्ण समीक्षा छोड्दै छु ।" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "बाचन भर्बोसिटी स्तर टगल गर्नुहोस्" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "मुख्य सामग्री" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "परिवर्तित कुञ्जीवद्धता" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "डेस्कटप" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notification" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Notification" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s का लागि दृष्टि वाचकप्राथमिकता " - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "ब्रेलमा चिनो लगाउ ।" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "अन्यथा देखाउ" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "वाचन गर" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "पार्श्वचित्रलाई विवादास्पद रूपमा नै बचत गर्नु होस् ।" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "उपभोक्ताको पार्श्वचित्र विवादास्पद छ ।" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"पार्श्वचित्र %s पहिले देखि नै छ ।\n" -"यी नया परिवर्तनका साथ हालको पार्श्वचित्र अद्यावधि करणलाई निरन्तरता दिनु होस् ।" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "उपभोक्ताको पार्श्वचित्रलाई बहन गर ।" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"तपाइ सक्रिय पार्श्वचित्र परिवर्तन गर्दै हुनु हुन्छ । \n" -"यदी आफ्नो प्राथमिकता भर् खरै परिवर्तन गरिएको हो भने, \n" -"यीनैहरू पार्श्वचित्र बहनमा खसालिने छन् । \n" -"\n" -"विगतका परिवर्तनलाई बेवास्ता गर्दै पार्श्वचित्र बहनको कार्य जारी राख्ने हो?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "पार्श्वचित्रलाई यस रूपमा बचत गर ।" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_पार्श्वचित्रको नाम" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "प्रयोगकर्ता प्रोफाईल हटाउनुहोस्" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"तपाईं प्रोफाइल %s हटाउदै हुनुहुन्छ। यस प्रोफाइलमा बचत गरिएका सबै सेटिंग्स हराउनेछ। के " -"तपाईं जारी राख्न र यो प्रोफाइल र सबै सम्बन्धित सेटिहरू हटाउन चाहनुहुन्छ?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "सबै" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "सन्झ्याल" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_None" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "मलाई देखाउ ।" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "प्राय" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "पङ्ति" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "वाक्य" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "हिस्सा उद्धरण" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "टाँक" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "शिर्षक" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "चेक बाकस" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "किटिक्क गर्ने" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "कम्बो बाकस" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "विवरण" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "शिर्षक" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "प्रतिच्छेदन गरिएको" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "तस्विर" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "निसानी" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Landmark" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "निसानी" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "लिङ्क" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "सुची" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "सुची सामाग्री" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "वस्तुObject" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "अनुच्छेद" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "रेडियो टाँक" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "भुमिका" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "चयनीत सामाग्रीहरू" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "अवस्था" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "पाट" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "मान" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "हिस्सा उद्धरणहरू" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "टाँकहरू" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "चेकबाकसहरू" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "किटिक्क " - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "कम्बो बाकसहरू" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "प्रविष्टी" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "फारम क्षेत्र" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "शिर्षकहरू" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "प्रतिच्छेदन गरिएको" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "तश्विरहरू" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "%d तहको शिर्षक" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Landmarks" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "बृहत् वस्तु" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "लिङ्कहरू" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "सुचीहरू" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "सुची सामाग्री" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "अनुच्छेदहरू" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "रेडियो टाँकहरू" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "तालिका " - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "नहेरेको लिङ्क" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "हेरेको लिङ्क" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "पृष्ठ विचरण" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "पहिलो पल्ट बहन हुँदा स्वतः पृष्ठ वाचन गर । " - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "पहिलो पल्ट बहन हुँदा स्वतः पृष्ठ वाचन गर" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "वाचन विच्छेद गर ch_unks विश्रामको बीचमा" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s निर्धारित आवाज" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "निर्धारित" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "प्रणाली" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "माथिल्लो स्वरूप" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "वाचन प्रेषक" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Spell Check" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Spell _error" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Spell _suggestion" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "त्रुटीको वर्तमान सन्दर्भ " - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "कोशीका स्थान बताउ ।" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "जहिले पनि चयनित स्प्रेडसिट दायरा बोल्नुहोस्" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "कोशीका शीर्षक बताउ" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "तालिका विचरण" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "खाली कोशीका छोडी देउ ।" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "कोशीका बताउ ।" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "कोशीका स्थान बताउ ।" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "बहु कोशीका लम्बाइ बताउ ।" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "विशेषताहरूको नाम" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "दृष्टिवाचकCaret विचरणको प्रयोग गर ।" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "बनोट विचरण सक्षम बनाउ ।" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "छोटकरी" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Notification" -msgstr[1] "Notification" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "देब्रे shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "देब्रे alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "देब्रे control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "दाहिने shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "दाहिने alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "दाहिने control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "देब्रे meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "दाहिने meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "शिफ्ट ताल्चा लगाउनुहोस्:" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "माथिल्लो पृष्ठ" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "तल्लो पृष्ठ" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "देब्रे tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "माथि" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "तल" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "देब्रे" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "दाहिने" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "देब्रे super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "दाहिने super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "मेनु" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "सहयोग" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "बहू" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "मुद्रा चाबी" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "गृह" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "अन्त" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "थालनी" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "औँठी" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "धाप" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "घटाउ" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "दाहिने Alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "देब्रे Alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "बाक्लो %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "छड्के %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "बाक्लो छड्के %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "स्क्रिप्ट %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "बाक्लो स्क्रिप्ट %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "दोब्बर प्रहार %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "बाक्लो fraktur %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "सान्स सेरिफ %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "बाक्लो सान्स सेरिफ %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "छड्के सान्स सेरिफ %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "बाक्लो छड्के सान्स सेरिफ %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "मोनोस्पेस %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "थोप्लोरहित %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "बायाँ बाँण" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "माथि बाँण" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "दायाँ बाँण" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "तल फर्केको बाँण" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "बायाँ-दायाँ बाँण" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "माथि-तल बाँण" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "उत्तर पश्चिम बाँण" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "उत्तर पूर्व बाँण" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "दक्षिण पूर्व बाँण" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "बायाँ बाँण " - -#: src/cthulhu/mathsymbols.py:1297 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "बायाँ बाँण " - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "पट्टीबाट तल बाँण" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "पट्टीबाट तल बाँण" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "देब्रे दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "माथि-दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "दायाँ दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "तल-दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "बायाँ-दायाँ दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "माथि-तल-दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "उत्तर पश्चिम दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "उत्तर पूर्व दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "दक्षिण पूर्व दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "दक्षिण पश्चिम दोब्बर बाँण" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "दायाँ बाँण " - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "दायाँ बाँण " - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "घटाउ" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "भन्दा सानो छ" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "भन्दा ठूलो छ" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "थोप्लो" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "दोब्बर ठाडो रेखा" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "तेर्सो इलिप्सिस" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "सबैमा" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "पूरक" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "आंशिक अन्तर" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "त्यहा अवस्थित छ" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "त्यहा अवस्थित छैन" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "खाली सेट" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "बढोत्तरी(∆)" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "नाब्ला (∇)" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "तत्त्व को हो " - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "तत्त्व को होईन (∉)" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "सानो तत्त्व (∊)" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "सदस्य समावेश" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "सदस्य समावेश नगर्नुहोस्" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "सानो सदस्य समावेश" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "प्रमाण अन्त्य" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "वस्तु" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "सह- उत्पादन" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "जम्मा" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "जोड वा घटाउ" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "थोप्लो-प्लस" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "विभाजन स्ल्यास ( / )" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "घटाउ सेट गर्नुहोस्" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "तारा चिह्न (*) सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "चक्र सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "गोली चिन्ह सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "वर्गमूल" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "घन रूट" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "चौथो रूट" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "समानुपातिक" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "अनन्त" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "दाहिने कोण" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "कोण" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "कोण नापिएको" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "गोलाकार कोण" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "भाग गर्नुहोस्" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "भाग नगर्नुहोस्" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "समानान्तर" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "समानान्तर छैन" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "तार्किक र (AND)" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "तार्किक वा (OR)" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "पारस्परिक बिन्दु " - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "युनियन" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "अभिन्न" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "दोब्बर अभिन्न" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "तीन पटक अभिन्न" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "समोच्च अभिन्न" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "सतह अभिन्न" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "आयतन अभिन्न" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "घडी को सुइ अनुसार अभिन्न" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "घडी को सुइ अनुसार समोच्च अभिन्न" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "घडी को सुइ उल्तो समोच्च अभिन्न" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "त्यस कारण" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "किनभने" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "अनुपात" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "अनुपात" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "थोप्लो घटाउ" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "अधिक" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "ज्यामितिय अनुपात" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "होमोथेटिक" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "टिल्ड" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "टिल्ड" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "उल्टाइयो \"S\" (tilde)" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "साईन तरङ्ग" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "उत्पादन माला " - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "टिल्ड होइन" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "घटाउ टिल्ड" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "लगभग बराबर" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "लगभग बराबर " - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "न लगभग न थ्याक्कै बराबर " - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "झन्दै बराबर" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "लगभग बराबर छैन" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "लगभग बराबर वा बराबर" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "तीनपटक टिल्ड" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "सबै बराबर" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "बराबरी" - -#: src/cthulhu/mathsymbols.py:1611 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "बराबरी" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "बीच भिन्नता" - -#: src/cthulhu/mathsymbols.py:1617 -#, fuzzy -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "यसमा सिमित: " - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1623 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "लगभग बराबर " - -#: src/cthulhu/mathsymbols.py:1626 -#, fuzzy -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "लगभग बराबर" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "विराम चिन्ह बराबर" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "बराबर बिराम" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "यससँग संगत गर्दछ" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "लगभग" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "त्रीकोणीय गोली" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "बराबर" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "डेल्टा बराबर" - -#: src/cthulhu/mathsymbols.py:1656 -#, fuzzy -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "यसद्वारा मापन गरिएको" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "पहिचायक देखाउनुहोस्" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "पहिचायक देखाउनुहोस्" - -#: src/cthulhu/mathsymbols.py:1674 -#, fuzzy -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "बराबरी" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "कम वा बराबर" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "बराबर बा बढि" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "कम वा बराबर" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "बराबर बा बढि" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "कम तर बराबर नहुने" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "बराबर बा बढि" - -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "भन्दा सानो छ" - -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "भन्दा ठूलो छ" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "बीचमा" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "बराबरी" - -#: src/cthulhu/mathsymbols.py:1707 -#, fuzzy -msgctxt "math symbol" -msgid "not less than" -msgstr "भन्दा सानो छ" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "भन्दा ठूलो छ" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "कम वा बराबर" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "न लगभग न थ्याक्कै बराबर " - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "कम वा बराबर" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "बराबर बा बढि" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "घटी वा बराबर" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "बढी वा बराबर" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "भन्दा ठूलो छ" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "भन्दा ठूलो छ" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "घटी वा बराबर" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "बढी वा बराबर" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "अघि आउने" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "पछि आउने" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "बराबर वा अघि आउने" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "बराबर वा पछि आउने" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "यससँग अगाडि वा बराबर हुन्छ" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "पछि आउने" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "अगाडि छैन" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "सफल हुँदैन" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "सबसेट" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "डबल सुपरसेट" - -#: src/cthulhu/mathsymbols.py:1773 -#, fuzzy -msgctxt "math symbol" -msgid "not a subset of" -msgstr "सबसेट" - -#: src/cthulhu/mathsymbols.py:1776 -#, fuzzy -msgctxt "math symbol" -msgid "not a superset of" -msgstr "डबल सुपरसेट" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "सबसेट" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "न लगभग न थ्याक्कै बराबर " - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "न लगभग न थ्याक्कै बराबर " - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "सबसेट" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "यससँग बराबर छ" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "बहु चयन " - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "गुणन" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "युनियन" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "छवि वर्ग" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "मुल को वर्ग" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "छवि वर्ग" - -#: src/cthulhu/mathsymbols.py:1815 -#, fuzzy -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "मुल को वर्ग" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "क्याप शैली:" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "चतुर्भुज" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -#, fuzzy -msgctxt "math symbol" -msgid "circled plus" -msgstr "थोप्लो को गोलाकार" - -#: src/cthulhu/mathsymbols.py:1827 -#, fuzzy -msgctxt "math symbol" -msgid "circled minus" -msgstr "थोप्लो को गोलाकार" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -#, fuzzy -msgctxt "math symbol" -msgid "circled times" -msgstr "times" - -#: src/cthulhu/mathsymbols.py:1833 -#, fuzzy -msgctxt "math symbol" -msgid "circled division slash" -msgstr "विभाजन स्ल्यास ( / )" - -#: src/cthulhu/mathsymbols.py:1836 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "थोप्लो सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1839 -#, fuzzy -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "चक्र सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1842 -#, fuzzy -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "तारा चिह्न (*) सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "थोप्लो को गोलाकार" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "थोप्लो को गोलाकार" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "जोड" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "घटाउ" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "times" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "थोप्लो सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "बायाँ टाँका" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "बायाँ टाँका" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "तल टाँका" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "बायाँ टाँका" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "दाबी गर्नुहोस्" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "नमूनाहरू" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "सत्य" - -#: src/cthulhu/mathsymbols.py:1884 -#, fuzzy -msgctxt "math symbol" -msgid "forces" -msgstr "" -"डेटाबेसमा डेटिभरेसन डेटिङ हुने हो कि छैन भनेर जाँच गर्न दिनहरूमा अन्तराल। 0 बलहरू कुनै पनि " -"समय क्रल गर्दै, -1 यसलाई अशुद्ध बन्द भएपछि मात्र बलियो बनाउँछ, र -2 यसलाई पूर्ण रूपमा " -"अक्षम पार्दछ।" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "प्रमाणित गर्दैन" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "सत्य होइन" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "जोड गर्दैन" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "सम्बन्ध अन्तर्गत पूर्वावद छ" - -#: src/cthulhu/mathsymbols.py:1908 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "पछि आउने" - -#: src/cthulhu/mathsymbols.py:1911 -#, fuzzy -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "सामान्य उपसमूहको रूपमा समाविष्ट गर्दछ" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "सामान्य उपसमूहको रूपमा समाविष्ट गर्दछ" - -#: src/cthulhu/mathsymbols.py:1917 -#, fuzzy -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "सामान्य उपसमूहको रूपमा समाविष्ट गर्दछ" - -#: src/cthulhu/mathsymbols.py:1920 -#, fuzzy -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "सामान्य उपसमूहको रूपमा समाविष्ट गर्दछ" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "मुल को " - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "छवि " - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "बहू" - -#: src/cthulhu/mathsymbols.py:1932 -#, fuzzy -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "म्याट्रिक्सको कन्जुगेट ट्रान्सपोज (एडजोईन्ट)" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "प्रतिच्छेदन गरिएको" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "एक्स ओ आर" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "NAND" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "NOR" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "वृताम्श को साथ दायाँ कोण" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "दाँया त्रिकोण" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "हिरा सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "थोप्लो सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "तारा सञ्चालक" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "विभाजन पटक" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -#, fuzzy -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "वस्तु" - -#: src/cthulhu/mathsymbols.py:1989 -#, fuzzy -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "वस्तु" - -#: src/cthulhu/mathsymbols.py:1992 -#, fuzzy -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "टिल्ड" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "तार्किक छैन" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "तार्किक छैन" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "डबल सबसेट" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "डबल सुपरसेट" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "दोहोरो प्रतिच्छेदन" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "डबल युनियन" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "बराबर र समानान्तर" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "भन्दा सानो छ" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "भन्दा ठूलो छ" - -#: src/cthulhu/mathsymbols.py:2025 -#, fuzzy -msgctxt "math symbol" -msgid "very much less than" -msgstr "भन्दा सानो छ" - -#: src/cthulhu/mathsymbols.py:2028 -#, fuzzy -msgctxt "math symbol" -msgid "very much greater than" -msgstr "भन्दा ठूलो छ" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "कम तर बराबर नहुने" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "बराबर बा बढि" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "बराबर बा घटि" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "बराबर बा बढि" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "बराबर वा अघि आउने" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "बराबर वा पछि आउने" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "अगाडि वा बराबर छैन" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "सफल वा बराबर छैन" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "छवि वर्ग" - -#: src/cthulhu/mathsymbols.py:2058 -#, fuzzy -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "मुल को वर्ग" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "छवि वर्ग" - -#: src/cthulhu/mathsymbols.py:2064 -#, fuzzy -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "मुल को वर्ग" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "कम वा बराबर" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "बराबर बा बढि" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "अगाडि छ तर यससँग बराबर छैन" - -#: src/cthulhu/mathsymbols.py:2076 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "पछि आउने" - -#: src/cthulhu/mathsymbols.py:2079 -#, fuzzy -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "सामान्य उपसमूहको रूपमा समाविष्ट गर्दछ" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "सामान्य उपसमूह को रूपमा समाहित छैन" - -#: src/cthulhu/mathsymbols.py:2085 -#, fuzzy -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "सामान्य उपसमूह को रूपमा समाहित छैन" - -#: src/cthulhu/mathsymbols.py:2088 -#, fuzzy -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "सामान्य उपसमूह को रूपमा समाहित छैन" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "तेर्सो इलिप्सिस" - -#: src/cthulhu/mathsymbols.py:2094 -#, fuzzy -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "तेर्सो इलिप्सिस" - -#: src/cthulhu/mathsymbols.py:2097 -#, fuzzy -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "माथि विकर्ण काटिएको" - -#: src/cthulhu/mathsymbols.py:2100 -#, fuzzy -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "तल विकर्ण काटिएको" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "माथि थोप्ला भएको तत्व" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "अधिपण्डासँग तत्व" - -#: src/cthulhu/mathsymbols.py:2120 -#, fuzzy -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "सानो तत्त्व (∊)" - -#: src/cthulhu/mathsymbols.py:2123 -#, fuzzy -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "तत्त्व को होईन (∉)" - -#: src/cthulhu/mathsymbols.py:2126 -#, fuzzy -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "दुई तेर्सो भेक्टरहरूको कुण्डलिकरण गणना गर्नुहोस्" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "अधिपण्डासँग समाविष्ट गर्दछ" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "अधिपण्डासँग समाविष्ट गर्दछ" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "बायाँ निम्न पूर्ण सङ्ख्या" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "दायाँ निम्न पूर्ण सङ्ख्या" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "बायाँ उच्च पूर्ण सङ्ख्या" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "बायाँ उच्च पूर्ण सङ्ख्या" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "माथिल्लो कोष्ठ" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "तल्लो कोष्ठ" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "देब्रे दोब्बर कोण कोष्ठ" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "दाहिने दोब्बर कोण कोष्ठ" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "थोप्लो को गोलाकार" - -#: src/cthulhu/mathsymbols.py:2180 -#, fuzzy -msgctxt "math symbol" -msgid "union with dot" -msgstr "थोप्लो" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "युनियन जोड" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "पारस्परिक बिन्दु " - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "युनियन वर्ग" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "कालो वर्ग" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "सेतोवर्ग" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "कालो हिरा" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "वृत्त" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "कालो वृत्त" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "सेतो गोली चिन्ह" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "कालो मध्यम सानो वर्ग" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "अधोरेखा संग %s" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "स्ल्याससँग %s" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "ठाडो रेखा भएको %s" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "रित्तो" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "मोटो" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "चिनो लगाइयो ।" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "चिनो बचत गरियो ।" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "चिनो बचत गर्न सकिएन ।" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "कुनै कित्ता पाइ एन ।" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "कुनै कित्ता पाइ एन ।" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "उप मार्ग सक्षम छ ।" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "क्याल्कुलेटर पटल भेट्टाउन सकिएन ।" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "प्रतिमा" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Capitalization शैली प्रतिमामा कायम गरियो ।" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "none" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Capitalization शैली कुनैमा कायम गरिएको छैन ।" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "हिज्जे" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Capitalization शैली हिज्जेमा कायम गरियो ।" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "केरेटलाई अनुप्रयोगले नियन्त्रण गरेको छ ।" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "केरेटलाई अनुप्रयोगले नियन्त्रण गरेको छ ।" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "कोशीका %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "“%s” चयन गरियो" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "“%s” देखि “%s” चयन गरियो" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "“%s” देखि “%s” चयन हटाइयो" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s चयन हट्यो ।" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "विकल्पको प्रयोगबाट बचौं ।" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "विकल्पको जबरजस्ती प्रयोग ।" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "विकल्प" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "वैकल्पिक तर्कहरू" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "उपयोग: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "तलका कुराहरू मान्य छैनन् ।" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "ज्ञात चालू अनुप्रयोग छाप्नु होस् ।" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "पार्श्वचित्रको बहन ।" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "पार्श्वचित्र बहन गर्न सकिएन: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "डेस्कटपमा जोड्न न सकिएकोले दृष्टिवाचकलाई सुरु गर्न सकिएन ।" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "अनुकूलता व्यबस्थापकलाई सक्रिय बनाउन सकिएन ।Exiting." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"अर्को स्क्रीन रिडर प्रक्रिया पहिले नै यस सत्रको लागि चालु छ।\n" -"त्यो प्रक्रियालाई नयाँसँग बदल्न \"cthulhu --replace\" चलाउनुहोस्।" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "नाम" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "उपभोक्ताको प्राथमिकताको लागी अलग घर्राको प्रयोग गर्नु होस् ।" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "यो अनुप्रयोगको स‌सकरण" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "हाल चालू दृष्टिवाचकलाई प्रतिस्थापन गर्नु होस् ।" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "यो मद्दत सन्देश देखाउनुहोस् र बाहिरिनुस्" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "खान तलासी प्रतिफल खानतलासी-YYYY-MM-DD-HH:MM:SS मा पठाउ ।" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "खानतलासी प्रतिवेदन प्रतिफल फाइलमा पठाउ ।" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "फाइल" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "उपभोक्ताको प्राथमिकता अनुकूलता मिलाउनु होस् ।" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "उपभोक्ता प्राथमिकता पातो संस्करणको मिलान ।" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "उडुस पाएमा https://groups.io/g/stormux मा जानकारी दिनु होस् ।" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "चयन गरिएको पाठ क्लिपबोर्डमा काट्नुहोस्" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "काट्नुहोस्" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "क्लिपबोर्डमा प्रतिलिपि गर्नुहोस्" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "प्रतिलिपि" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "क्लिपबोर्डको सामाग्रीहरू टाँस्नुहोस" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "टासिएको" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "टङ्कण गरिरहँदा केही नबताउ ।" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "तपाइका बडीले टाइप गरेको बताउ" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "गफगाफ कोठा %s को सन्देश ।" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "नया गफगाफ tab %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "गफगाफ कोठाको नाम नभन ।" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "गफगाफ कोठाको नाम बताउ ।" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "गफगाफ कोठा विशेष सन्देश इतिहास नदेखाउ " - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "गफगाफ कोठा विशेष इतिहासहरू उपलब्ध गराउ ।" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "मेट्न सुरु" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "मेट्न समाप्त" - -#: src/cthulhu/messages.py:452 -#, fuzzy -msgctxt "content" -msgid "insertion start" -msgstr "भागबण्डा शुरु" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "घुसाइने अन्त्य" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "हाइलाइट सुरुआत" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "हाइलाइट अन्त्य" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "सुझाव अन्त्य" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "कन्टेनरको अन्त्यमा जानुहोस्" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "कन्टेनरममा नभएको" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "सबै वस्तुहरू चयन गरियो" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "निर्धारित टाँक %s हो ।" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "निर्धारित टाँक %s हो ।" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "निर्धारित टाँक %s हो ।" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " पैतालोमा %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " टाउकोमा %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Not in a table." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "पुरै कागजात चयन गरियो" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "पुरै कागजात चयन हटाइयो" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "कर्सर रहेको स्थानबाट कागजातको चयन ।" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "कर्सरको स्थानदेखिका कागजातको चयन हट्यो ।" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "कर्सरको स्थानसम्म कागजात चय नित ।" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "कर्सरको स्थानसम्मको कागजातको चयन हट्यो ।" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "हरफ %d का लागि गति सिल महल शीर्षक कायम गर ।" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "गति सिल महल शीर्षक मेटियो ।" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "महल%s का लागि गति सिल हरफ शीर्षक कायम गरियो " - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "गति सिल हरफ शीर्षक मेटियो ।" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "empty" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "कुनै फाइल पाइ एन ।" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "क्लिपपाठीमा सामाग्रीहरू थपियो ।" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "क्लिपपाठीमा सामाग्रीहरूको प्रतिलिपि राखियो ।" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "पुर्ण समीक्षा प्रयोग भएको छैन ।" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "पुर्ण समीक्षा प्रवेश गर्दै छु ।" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "पुर्ण समीक्षा छोड्दै छु ।" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "समतल पुनरावलोकनलाई हालको शब्द माथिको शब्दमा सार्नुहोस्" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "सूत्र छ ।" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "सम्वाद खोल्नुहोस्" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "ग्रिड खोल्नुहोस्" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "सुची बाकस खोल्नुहोस्" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "मेनु खोल्नुहोस्" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "ट्रि खोल्नुहोस्" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "तस्विर नक्सा लिङ्क" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "यो कुञ्जी पहिले देखिने %s सित बाँधिएको छ ।" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "कुञ्जी समातियो: %s यकिन गर्न enter दबाउनु होस् । " - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "नया कुञ्जी : %s हो ।" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "कुञ्जी बन्धन मेटियो ।" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "कुञ्जी बन्धन हटाइयो ।" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "नया कुञ्जी प्रविष्टि गर्नु होस ।" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "कुञ्जी" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "कुञ्जी प्रतिध्वनि सेट" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "None" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "कुनैपनि होइनमा प्रतिध्वनि सेट गरियो" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "कुञ्जी र शब्द ।" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "कुञ्जी र शब्दमा प्रतिध्वनि सेट ।" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "वाक्य" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "वाक्य प्रतिध्वनि सेट" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "शब्द" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "शब्दमा प्रतिध्वनि सेट ।" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "शब्द र वाक्य " - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "शब्द र वाक्य मा प्रतिध्वनि सेट ।" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "यसद्वारा संलग्न गरियो: %s" - -#: src/cthulhu/messages.py:897 -#, fuzzy -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "प्रतिक:" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "बाकस" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "वृत्त" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "लामो विभाजन चिन्ह" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "मौलिक" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "कुना घेरिएको बाकस" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "तेर्सो काटिएको" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "ठाडो काटिएको" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "तल विकर्ण काटिएको" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "माथि विकर्ण काटिएको" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "उत्तर पूर्व बाँण" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "तलको रेखा" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "देब्रे रेखा" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "दाहिने रेखा" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "माथि रेखा" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "एउटा छड्के कोण" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "अरबी फ्याक्टोरियल चिन्ह" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "र" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "भागबण्डा शुरु" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "पट्टी बिनाको भागबण्डा शुरु" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "कामुनि" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "भागबण्डा अन्त्य" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "को वर्गमूल" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "घन रूट" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "वर्गमूल" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "वर्गमूल सुारु" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "वर्गमूल अन्त्य" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "सबस्क्रिप्ट" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "सुपरस्क्रिप्ट" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "पूर्व-सबस्क्रिप्ट" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "पूर्व-सुपरस्क्रिप्ट" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "मुनिस्क्रिप्ट" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "माथि स्क्रिप्ट" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "तालिकाको समाप्ति" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "भित्रि तालिकाको समाप्ति" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessible" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "असक्षम" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "indentation र पुस्ट्याई वाचन असक्षम बनाइयो ।" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "सक्षम बनाइयो ।" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "indentation र पुस्ट्याई वाचन सक्षम बनाइयो ।" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "सिकाई मुद्रा । बाहिरिन escape दबाउनु होला ।" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"सिक्ने मोड प्रविष्टि गर्दैछ । यसको कार्य सुन्न कुनै कुञ्जी थिच्नुहोस् । दृश्य वाचकको " -"मिसिलिकरण हेर्न, F1 थिच्नुहोस् । पर्दा वाचकको पूर्वनिर्धारित सर्टकटको सूची प्राप्त गर्न, " -"F2 थिच्नुहोस् । हालको अनुप्रयोगका लागि स्क्रिन रिडरको सर्टकटको सूची प्राप्त गर्न, F3 " -"थिच्नुहोस् । सिक्ने मोड अन्त्य गर्न, इस्केप कुञ्जी थिच्नुहोस् ।" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "बाक्लो उद्धरण बाहिर" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "विबरण छोडियो" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "फिड छोडियो" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "चित्र छोडियो" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "फारम छोडियो" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "ब्यानर छोडियो" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "पूरक सामाग्रि छोडियो" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "सुचना छोडियो" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "मुख्य सामग्री छोडियो" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "नेभिगेसन छोडियो" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "क्षेत्र छोडियो" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "खोज छोडियो" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "सुची छोडियो ।" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "प्यानल छोडियो" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "तालिका छोडियो ।" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "औजारटिप छोडियो" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "संक्षेप छोडियो" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "स्विकार्य छोडियो" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "पछिको शब्द छोडियो" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "अन्तमा थपिएको खण्ड छोडियो" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "ग्रन्थसूची छोडियो" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "अध्याय छोडियो" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "कोलोफोन" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "निष्कर्ष छोडियो" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "श्रेय छोडियो" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "श्रयहरू छोडियो ।" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "समर्पण छोहियो" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "अन्तिम टिप्पणीहरू छोडियो" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "इपिग्राफ छाडियो" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "विबरण छोडियो" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "चित्र छोडियो" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "उद्धाहरण छोडियो" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "पूर्वावोरुति छोडियो" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "शब्दकोश छोडियो" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "अनुक्रमणिका छोड्दै।" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "परिचय छोडियो" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "पृष्ठ सूची छोडियो" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "भाग छोडियो" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "भूमिका छोडियो" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "विबरण छोडियो" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "बाक्लो उद्धरण बाहिर" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "प्रश्नोत्तर छोडियो ।" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "सुझाव छोडियो" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "पृष्ठ तालिका छोडियो ।" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "कर्सरको स्थानबाट तलका पङ्ति चय नित ।" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "कर्सरको स्थानबाट माथिका पङ्ति चय नित ।" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "कर्सरको स्थानबाट तलका पङ्तिको चयन हट्यो ।" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "कर्सरको स्थानबाट माथिका पङ्तिको चयन हट्यो ।" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "सिकाई मुद्राबाट बाहिरिदैं छु ।" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "पङ्तिको सुरु देखि कर्सरको अघिल्लो स्थानसम्म चय नित ।" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "कर्सरको अघिल्लो स्थानबाट पङ्तिको अन्तसम्म चय नित ।" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "लिङ्क" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "उही पृष्ठ" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "उही स्थान " - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "फरक स्थान" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s लिङ्क %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s लिङ्क" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "हेरेको %s लिङ्क:" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "सुचीमा विचरण गर्न तल वा माथि वाण र बहिर्गमन गर्न Escape दबाउनु होस् ।" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "सबै जीवन्त क्षेत्र बन्द कायम गरिएको ।" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "जीवन्त क्षेत्रको नम्रता तह पुनः जीवित ।" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "नम्रता तह %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "जीवन्त क्षेत्रलाई कडाइमा अनुकूलित" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "जीवन्त क्षेत्रको अनुकूलता बन्द ।" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "जीवन्त क्षेत्रलाई नम्रतामा अनुकूलित" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "जीवन्त क्षेत्रलाई गालीमा अनुकूलित" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "जीवन्त क्षेत्रको अनुगमन हुँदैन ।" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "जीवन्त क्षेत्रको अनुगमन हुन्छ ।" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "जीवन्त सन्देश बचत गरिएको छैन ।" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "जीवन्त क्षेत्र समर्थन छैन ।" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Not found" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "चालू स्थान पाइ एन ।" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "बन्द" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "सुरु" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "गल्ती हिज्जे " - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "हिज्जे गल्ती शब्द : %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "सन्दर्भ %s हो ।" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "उघार्ने मुद्रा" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "केन्द्रीयता मुद्रा" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "केन्द्रीयता मुद्रालाई सक्षम बनाउन %s लाई दबाउनु होस् ।" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "केन्द्रीयता मुद्रा टाँसिने स्वभावको छ ।" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "ब्राउजज मुद्रा टाँसिने स्वभावको छ ।" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "रूपरेखा मुद्रा" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "वस्तु मुद्रा" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "अरू ठूला वस्तुहरू छैनन् ।" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "सुलसुलेको तल वस्तु पाइ एन ।" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "माउस समीक्षा अक्षम पारियो ।" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "माउस समीक्षा सक्षम पारियो ।" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "त्रुटी: वस्तुको सुची सिर्जना गर्न सकिएन ।" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d प्रतिशत" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "अघिल्लो शब्दमा जानुहोस्" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "शाखा तह %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "नया सामाग्री थपिएका छन् ।" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "कुनै पनि अनुप्रयोगमा केन्द्रित छैन ।" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "केन्द्रित छैन" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "कुनै पनि अनुप्रयोगमा केन्द्रित छैन ।" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "अरू ब्लक उद्धरण छैनन् ।" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "अरू टाँक छैनन् । " - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "अरू चेक कोठा छैनन् ।" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "अरू ठूला वस्तुहरू छैनन् ।" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "अरू किटिक्क स्थान छैनन् ।" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "अरू कम्बो बाकस छैनन् ।" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "अरू प्रविष्टिहरू छैनन् ।" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "अरू भर्ने फाराम छैनन् ।" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "अरू शीर्षकहरू छैनन् ।" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "%d तहमा अरू शीर्षकहरू छैनन् ।" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "अरू तालिकाहरू छैनन् ।" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "तश्विरहरू छैनन् ।" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "कुनै कित्ता पाइ एन ।" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "लिङ्क छैनन् ।" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "अरू सुचीहरू छैनन् ।" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "अरू सुची सामाग्रीहरू छैनन् ।" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "अरू जीवन्त क्षेत्रहरू छैनन् ।" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "अरू अनुच्छेदहरू छैनन् ।" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "अरू रेडियो टाँकहरू छैनन् ।" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "अरू विभाजकहरू छैनन् ।" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "अरू तालिकाहरू छैनन् ।" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "अरू नहेरिएका लिङ्कहरू छैनन् ।" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "अरू हेरिएका लिङ्कहरू छैनन् ।" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "पाठ छानिएको छैन" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "लिङ्क होईन ।." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notification" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "पुछार" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "माथि" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "अरू सूचना सन्देशहरू छैनन् ।" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "संख्याहरु" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "सङ्ख्याहरू अङ्कमा बताउँछ" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "शब्दहरू" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "सङ्ख्याहरू शब्दमा बताउँछ" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "बन्द छ" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "खुल्ला छ" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "पर्खनु होस् है, बहन गर्दै छु" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "बहन कार्य सकियो ।" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s को बहन सकियो ।." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "पृष्ठमा %s छ" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "कर्सरको स्थानदेखि पृष्ठ चय नित ।" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "कर्सरको स्थानसम्म पृष्ठ चय नित ।" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "कर्सरको स्थानदेखि पृष्ठको चयन हट्यो ।" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "कर्सरको स्थानसम्म पृष्ठको चयन हट्यो ।" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "कर्सरको स्थानबाट तलको अनुच्छेद चय नित ।" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "कर्सरको स्थानबाट माथिको अनुच्छेद चय नित ।" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "कर्सरको स्थानबाट तलको अनुच्छेदको चयन हट्यो ।" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "कर्सरको स्थानबाट माथिको अनुच्छेदको चयन हट्यो ।" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"तपाइले ओर्का प्राथमिकता पातो पहिले नै खोली सक्नु भएको छ । \n" -"नया खोल्नु अघि यसलाई बन्द गर्नु होस् ।" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "सु लुली %(count)d मध्ये %(position)d मा छ । " - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "पार्श्वचित्रलाई %s मा कायम गरियो ।" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "कुनै पार्श्वचित्र पाइ एन ।" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "प्रगति पट्टी %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "सबै" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "चिन्ह तह सबै मा कायम गरियो ।" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "धेरै जसो " - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "चिन्ह तह धेरै जसो मा कायम गरियो ।" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "None" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "चिन्ह तह कुनै मा पनि कायम गरिएन ।" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "केही" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "चिन्ह तह केही मा कायम गरियो ।" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "खोज्दै छु ।" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "खोजी कार्य सकियो ।" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "दृष्टिवाचकअनुकूलता फेरी बहन गरियो ।" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "चयन गरियको पाठ “%s”" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "चयन गरिएको मेटियो" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "चयन गरिएको पुःन स्थापना गरियो" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "पाठ चयन गरिएको छैन ।" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "आकार: %d, %d. स्थान: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "चौदाई: %d. उचाई: %d. बाँयाबाट %d . दाँयाबाट%d ." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "वाचन अयोग्य बनाइयो ।" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "वाचन सक्षम बनाउ ।" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "तीव्र" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "सुस्त " - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "उच्च" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "निम्न" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "चर्को" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "मधुरो" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_दर" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "आयतन:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "वाचन प्रेषक" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "वाचन प्रेषक" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "सर्बर उपलब्ध छैन । " - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "No voices available." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "वाचन सक्षम बनाउ ।" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "वाचनको प्रयोग गरिँदैन ।" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "चर्को तह: शारांस" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "चर्को तह: वाचन" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " थोप्लो थोप्लो थोप्लो" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "उप मार्ग सक्षम छ ।" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "वाचन उपलब्ध छैन ।" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "फेला परेन" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "स्थितिपट्टी फेला परेन " - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "पदावली पाई एन ।" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "बनोट विचरण कुञ्जी बन्द ।" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "बनोट विचरण कुञ्जी खुल्यो ।" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Not found" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "हरफ %(row)d, महल %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "तालिकाको समाप्ति" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "कोशीका बताउ ।" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "हरफ बताउ ।" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Non-uniform" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Not in a table." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "पुनः मिलाईएका महलहरू" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "पुनः मिलाइएका हरफहरू" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "महल %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "महल %(total)d मध्ये %(index)d " - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "महलको पुछार" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "महलको सिरान" - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "सतम्भ “%s” चयन गरियो" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "सतम्भ “%s” देखि “%s” चयन गरियो" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "सतम्भ “%s” देखि “%s” चयन हटाइयो" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "सतम्भ “%s” चयन हटाइयो" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "हरफ %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "हरफ %(total)d मध्ये %(index)d " - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "हरफको सुरुवात" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "हरफको समाप्ति ।" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "हरफ मेटियो ।" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "अन्तिम हरफ मेटियो ।" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "हरफ थपियो" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "तालिकाको पुछारमा हरफ थपियो ।" - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "हरफ “%s” चयन गरियो" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "हरफ “%s” देखि “%s” चयन गरियो" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "हरफ “%s” देखि “%s” चयन हटाइयो" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "हरफ “%s” चयन हटाइयो" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "चय नित " - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "चयन हट्यो ।" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H घण्टा, %M मिनेट र %S सेकेन्ड" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H घण्टा र %M मिनेट" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "युनिकोड %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "पुर्वस्थितिमा फर्काउनुहोस्" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "रिडू गर्नुहोस्" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "सेतो ठाउँ" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "पुछारमा बिटो मारिदैं छ ।" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "सिरानमा बिटो मारिदैं छ ।" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 सामाग्री" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "कोशीका वृद्धि %d हरफ" -msgstr[1] "कोशीका वृद्धि %d हरफहरू" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d स्तम्भ" -msgstr[1] " %d स्तम्भहरू" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "कोशीका वृद्धि %d महल" -msgstr[1] "कोशीका वृद्धि %d महलहरू" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d वर्णहरू, धेरै लामो" -msgstr[1] "%d characters too long" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d पातो)" -msgstr[1] "(%d पातोहरू)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d केन्द्रित नभएको पातो" -msgstr[1] "%d unfocused dialogs" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d फाइल पाइयो" -msgstr[1] "%d files found" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d फाराम" -msgstr[1] "%d forms" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d शीर्षक" -msgstr[1] "%d headings" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d सामाग्री" -msgstr[1] "%d सामाग्रीहरू" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d जमीनको सिमा प्रतिक" -msgstr[1] "%d जमीनको सिमा प्रतिकहरू" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d सामाग्री पाइयो" -msgstr[1] "%d सामाग्रीहरू पाइयो" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "%d बाक्लो उद्धरण बाहिर" -msgstr[1] "%d बाक्लो उद्धरणहरू बाहिर" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "%d सूची छोड्दैछ ।" -msgstr[1] "%d सूचीहरु छोड्दैछ ।" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "फाइल साइज: अज्ञात" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "List with %d item" -msgstr[1] "List with %d items" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "फाइल साइज: अज्ञात" - -#: src/cthulhu/messages.py:2704 -#, fuzzy, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "फिड:" -msgstr[1] "फिड:" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "वर्णन शब्द" -msgstr[1] "वर्णन सूची" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "मान अनुसार" -msgstr[1] "मानहरू" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "%d हरफ भएको गणित तालिका" -msgstr[1] "%d हरफहरू भएको गणित तालिका" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d महल" -msgstr[1] "%d columns" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "%d पङ्क्तिसँग नेस्ट गरिएको गणित तालिका" -msgstr[1] "%d पङ्क्तिहारुसँग नेस्ट गरिएको गणित तालिका" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d सन्देश \n" -msgstr[1] "%d सन्देशहरू \n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d प्रतिशत" -msgstr[1] "%d प्रतिशत" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d प्रतिशत कागजात पढियो ।" -msgstr[1] "%d percent of document read" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d पिक्सेल" -msgstr[1] "%d पिक्सेलहरू" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s वर्ण" -msgstr[1] "%(count)d %(repeatChar)s वर्णहरू" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(total)d मध्ये %(index)d सामाग्री चय नित ।" -msgstr[1] "%(total)d मध्ये %(index)d सामाग्रीहरू चय नित ।" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "दृष्टिवाचकको निर्धारित द्रुत मार्ग %d पाइयो ।" -msgstr[1] "%d Cthulhu default shortcuts found." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d %(application)s का लागि दृष्टिवाचक द्रुत मार्ग पाइयो ।" -msgstr[1] "%(count)d %(application)s हरुका लागि दृष्टिवाचक द्रुत मार्ग पाइयो ।" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d स्थान" -msgstr[1] "%d spaces" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d ट्याब" -msgstr[1] "%d tabs" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d तालिका" -msgstr[1] "%d tables" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "अज्ञात तालिका साइज" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "%d स्तम्भ भएको तालिका, अज्ञात पङ्क्ति गणना" -msgstr[1] "%d स्तम्भहरू भएको तालिका, अज्ञात पङ्क्ति गणना" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%d पङ्क्तिसँग तालिका, स्तम्भ गणना अज्ञात" -msgstr[1] "%d पङ्क्तिहरूसँग तालिका, स्तम्भ गणना अज्ञात" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "%d हरफ भएको तालिका" -msgstr[1] "table with %d rows" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d नहेरेको लिङ्क" -msgstr[1] "%d unvisited links" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d हेरेको लिङ्क" -msgstr[1] "%d visited links" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "उल्टनू" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(total)d मध्ये %(index)d मा" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(total)d मध्ये %(index)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "वस्तु %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "तह %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "वृक्ष तह %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "वृक्ष तह %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "%s का लागि विस्तृत विवरण" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "%s का विस्तृत विवरण" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "सुझाव" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "सम्पादनयोग्य कम्बो बाकस" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "सम्पादन योग्य सामाग्रि" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "फिड" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "चित्र" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "संक्षेप" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "स्विकार्य" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "पछिको शब्द" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "अन्तमा थपिएको खण्ड" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "ग्रन्थसूची प्रविष्टि" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "सन्दर्भसूची" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "अध्याय" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "कोलोफोन" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "निष्कर्ष" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "आवरण" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "श्रेय" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "श्रेयहरू" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "समर्पण" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "अन्तिम टिप्पणी" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "अन्तिम टिप्पणीहरू" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "इपिग्राफ" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "उदाहरण" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "पूर्वावोरुति" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "शब्दकोश" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "अनुक्रमणिका" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "परिचय" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "पृष्ठ विच्छेद" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "पृष्ठ सूची" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "भाग" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "भूमिका" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "उद्धरण" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "प्रश्नोत्तर" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "उपशीर्षक" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "विषयसूची" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s तह %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "तेर्सो स्क्रोलपट्टी" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "ठाडो स्क्रोलपट्टी" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "तेर्सो स्लाइडर" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "ठाडो स्लाइडर" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "तेर्सो विभाजक" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "ठाडो विभाजक" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "स्विच" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "प्रतिमा समूह " - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "ब्यानर" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "पूरक सामाग्रि" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "सूचना" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "मुख्य सामग्री" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "नेभिगेशन" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "क्षेत्र" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "खोजी गर्नुहोस्" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "हेरेको लिङ्क" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "मेनु बटन" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "बढ्दोक्रमबद्ध" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "घट्दो क्रमबद्ध" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "क्रमबद्ध गरियो" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "किटिक्क गर्ने" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "साँगुरिएको" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "फैलिएको " - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "लामो विवरण युक्त ।" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "तेर्सो" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "ठाडो" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "टिक छ" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "टिक छैन" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "खोल्नुहोस्" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "off" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "आंशिक टिक लागेको" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "दबाइएको" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "नदबाएको" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "न रोजेको रेडियो टाँक" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "चय नित रेडियो टाँक" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "न रोजेको रेडियो टाँक" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "not selected" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "हेरेको" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "नहेरेको" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "खैरो रङ्गिन " - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "पढ्न मात्रै मिल्ने " - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "पढ्न मात्रै मिल्ने " - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "आवश्यक" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "बहु चयन " - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "अवैध प्रविष्टि" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "अवैध" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "अवैध हिज्जे" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "हिज्जे" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "अवैध व्याकरण" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "व्याकरण त्रुटि" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "फेला पार" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "दृष्टि वाचकको खोजी पातो ।" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Close" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Find" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_फेला पार" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "के खोज्ने?" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_सन्झ्यालको सिरान" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "सन्झ्यालको सिरान" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "सुरु गर्ने" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_बिटो मार्ने " - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "पछाडि पनि खोज्ने ।" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "खोजी दिशा ।" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_वर्ण मिलान" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "पूर्ण शब्द खोज्ने ।" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "विकल्पहरू:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "निर्धारित" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "माथिल्लो वर्ण" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "प्रणाली" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "अनुप्रयोग" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "सन्झ्याल" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "ओर्का दृष्टि वाचक" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_सहयोग" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_लागू" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "ल्याकटप" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "कुञ्जीपाटी रूपरेखा" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "सक्रिय पार्श्वचित्र:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "आरम्भ पार्श्वचित्र" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "बहन" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "यस रूपमा बचत गर ।" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_हटाउनुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "पार्श्वचित्र" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Present औजार टिपोट" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "mo_use मा वस्तु बताउ ।" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "सुलसुले" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "समय ढाँचा" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Dat_e स्वरूप" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "समय र मिति" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "बाचन अद्यावधिक गर्नुहोस्" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "ब्रेल अद्यावधिक गर्नुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "१०" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "आवृति (secs):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "लागू गर्दछ" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "विप अद्यावधिक गर्नुहोस्" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "प्रगति पट्टीको अद्यावधि करण" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "सबै भन्नुहोस् मा रिवाइन्ड र छिटो अगाडि सक्षम पार्नुहोस्" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "सबै भन्नुहोस् मा संरचना नेभिगेसन सक्षम पार्नुहोस्" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "सबै बताउ:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "सबै भन्नुहोस् मा बाक्लो उद्धरण घोषणा गर्नुहोस्" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "सबै भन्नुहोस् मा सूची घोषणा गर्नुहोस्" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "सबै भन्नुहोस् मा तालिका घोषणा गर्नुहोस्" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "सबै भन्नुहोस् मा प्यानल घोषणा गर्नुहोस्" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "सबै भन्नुहोस् मा फारम घोषणा गर्नुहोस्" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "सबै भन्नुहोस् मा स्थलगत घोषणा गर्नुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "सबै बताउ" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "सामान्य" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "आयतन:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Pi_tch:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_दर" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_व्यक्ति" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "भाषा:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "वाचन संश्लेषक:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "वाचन प्रणाली" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_आवाजको किसिम" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "ठूलो वर्णशैली:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "आवाज किसिम अनुकूलता" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "बहू वर्ण संवेदन सिल पदावलीलाई शब्द जस्तै गरी बताउ ।" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "सङ्ख्याहरू अङ्कमा बोल्नुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "साझा आवाज अनुकूलता" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "आवाज" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "वाचन सक्षम बनाउ ।" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Ver_bose" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "गति" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_सबै" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "चिन्ह तह" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "प्रदर्शित पाठमात्र बताउ ।" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "रित्तो पङ्ति बताउ ।" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "_indentation र पुस्ट्याई बताउ ।" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "वस्तुको mnemonics बताउ ।" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "सन्तानको स्थान बताउ ।" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "पाठ्य सन्देश बताउ ।" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "प्रणाली सन्देश विस्तार गरिएको छ" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "नामको रूपमा रङहरू बोल्नुहोस्" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "नेभिगेसन गर्दा बाक्लो उद्धरण घोषणा गर्नुहोस्" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "नेभिगेसन गर्दा सूची घोषणा गर्नुहोस्" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "नेभिगेसन गर्दा तालिका घोषणा गर्नुहोस्" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "गलत हिज्जे भएको शब्द सूचक वाचन गर्नुहोस्" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "नेभिगेसन गर्दा प्यानल घोषणा गर्नुहोस्" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "नेभिगेसन गर्दा ल्यान्डमार्क घोषणा गर्नुहोस्" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "नेभिगेसन गर्दा फारम घोषणा गर्नुहोस्" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "बर्णन बोल्नुहोस्" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "स्प्रेडसिटमा पूरै पङ्क्ति बोल्नुहोस्" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "कागजात तालिकामा पूरा पङ्क्ति बोल्नुहोस्" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "GUI तालिकामा पूरा पङ्क्ति बाचन गर्नुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "भनिएको सन्दर्भ ।" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "वाचन " - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "ब्रेलको समर्थनलाई सक्षम बनाउ ।" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_संक्षेपित भूमिका नाम" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "लाइन प्रतिमाको अन्त्य अक्षम पार्नुहोस्" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "संक्षेपित तालिका" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_संक्षेपित ब्रेललाई सक्षम बनाउ ।" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "शब्द बेराइ सक्षम पार्नुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "अनुकूलता देखाउ" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_None" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "चयन सूचक" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hyperlink सूचक" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "फ्ल्यास सन्देश सक्षम पार्नुहोस्" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "अवधि (सेकेन्ड):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "सन्देश स्थायी छ" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "सन्देश बिबरण गरियो" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "फ्ल्यास सन्देश सेटिङ" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ब्रेल" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "कुञ्जी प्रतिध्वनि सक्षम बनाउ ।" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "वर्णानुक्रम कुञ्जीहरू सक्षम पार्नुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "सङ्ख्यात्मक कुञ्जीहरू सक्षम पार्नुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "विराम चिन्ह कुञ्जीहरू सक्षम पार्नुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "स्थान सक्षम" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "परिवर्तित कुञ्जीलाई सक्षम बनाउ ।" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "function कुञ्जीलाई सक्षम बनाउ ।" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "कार्य कुञ्जीलाई सक्षम बनाउ ।" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "विचरण कुञ्जीलाई सक्षम बनाउ ।" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "शब्द वाचन सक्षम बनाउ ।" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "वाक्य वाचन सक्षम बनाउ ।" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "प्रतिध्वनि" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "दृष्टिवाचकपरिवर्तित कुञ्जी:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "कुञ्जी बन्धन" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "उच्चारण ढुकुटी" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "नया प्रविष्टि" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "मेटाउ" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "उच्चारण" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_सबै बताउ ।" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "नबताउ ।" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_पुनः मिलाउ" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "पाठको गुण" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "पुछारमा जाउ ।" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "१ तल सर ।" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "१ माथि सर " - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "सिरानमा जाउ " - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "चयन गरिएको विशेषता समायोजन गर्नुहोस्" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "ब्रेल सूचक" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "पाठका विशेषताहरू" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "न्यून" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "भाषा:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "येन" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "क्लिपपाठीमा सामाग्रीहरूको प्रतिलिपि राखियो ।" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : अल्फा, b : ब्राभो, c : चार्ली, d : डेल्टा, e : एको, f : फक्स्ट्रस्ट्, g : गल्फ, h : " -"होटेल, i : ईन्डिया, j : जुलियट, k : किलो, l : लीमा, m : माईक, n : नोभेम्बर, o : " -"ओस्कार, p : पापा, q : क्युबेक, r : रोमियो, s : सिएरा, t : ट्यान्गो, u : युनिफम, v : " -"भिक्टर, w : विस्की, x : एक्स-रे, y : याङ्की, z : जुलु" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "पृष्ठभूमि रङ्ग" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "पृष्ठभूमि पूर्ण उचाल" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "पृष्ठभूमि धर्को" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "दिशा" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "सम्पादन योग्य" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "परिवारको नाम " - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "अग्रभूमि रङ्ग" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "अग्रभूमि धर्को" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "वर्णाकृति प्रभाव" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indent" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "त्रुटि" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "अदृश्य" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "पुस्ट्याइ" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "भाषा" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "देब्रे किनारा" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "पङ्ति उचाइ" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "अनुच्छेद शैली" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "पङ्ति माथि pixels " - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "पङ्ति तल pixels " - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "बिटो भित्रको pixels " - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "दाहिने किनारा" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "उँचो" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "नाप" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "आकार" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "तन्किएको" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "काटिएको" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "शैली" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "पाठको सजावट" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "पाठको घुमाई" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "छाया पाठ" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "अधोरेखाङ्कित" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "आयाम" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "ठाडो प्रतिबद्ध" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "भार" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "बिटो मुद्रा" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "लेखन मुद्रा" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "सत्य" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "झूटो" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "none" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "गाडा" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "emboss" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "बाह्य रेखा" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "भित्रि रेखा" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "रेखाबाट" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "चम्किनु" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "कालो" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "एकल" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "दोब्बर" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "न्यून" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "वर्ण" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "शब्द" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "शब्द वर्ण" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "देब्रे" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "दाहिने" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "केन्द्र" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "कुनै पुस्ट्याई छैन ।" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "भरी" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "अति नै खाँदिएको" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "अतिरिक्त खाँदिएको " - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "खाँदिएको " - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "अर्ध खाँदिएको " - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "अर्ध फैलिएको" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "फैलिएको" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "अतिरिक्त फैलिएको" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "अति नै फैलिएको" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "सानो वर्ण" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblique" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "कोल्टे" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "निर्धारित" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "पृष्ठभाग" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "शीर्षक" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "आधार पङ्ति" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "उप" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "माथि" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "सिरान" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "पाठको सिरान" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "मध्य" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "पुछार" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "पाठको पुछार" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "बंशानुकृथ" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "ठोस" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "हिज्जे" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "उल्टाउन space दबाउ ।" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "फैलाउन space दबाउ, र कुनै सामाग्री चयन गर्न तल वा माथि वाण चलाउ ।" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "सन्तान सन्झ्याल चयन गर्न alt+f6 दबाउ ।" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "सामाग्रीमा सर्न, या त वाण कुञ्जी अथवा अगाडि खोजी टङ्कण गर्नु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "प्रणाली मेनु पाउन alt+f1 कुञ्जी दबाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "कुनै सामाग्री चयन गर्न तल वा माथि वाण कुञ्जी चलाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "पट्याउनका लागि shift plus left दबाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "फैलाउनका लागि shift plus right दबाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "सक्रिय गर्न Enter दबाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "पाठमा टङ्कण गर्नु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "अरू tabs हेर्न देब्रे र दाहिने वाण दबाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "सक्रिय गर्न space दबाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "मानको चयन गर्न तल वा माथि वाण चलाउनु होस् अथवा चाहेको मान टङ्कण गर्नु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "परिवर्तन गर्नका लागि वाण कुञ्जी चलाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "विचरण गर्न देब्रे वा दाहिने वाण चलाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "उप मेनुमा जान, दाहिने वाण चलाउनु होस् ।" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"घटाउन देब्रे वाण, बढाउन दाहिने वाण दबाउनु होस् । न्युनतममा जान home र अधिकतममा जान " -"end लाई दबाउनु होस् ।" diff --git a/po/nl.po b/po/nl.po deleted file mode 100644 index e79e1f5..0000000 --- a/po/nl.po +++ /dev/null @@ -1,9355 +0,0 @@ -# Dutch translation for cthulhu -# -# This file is distributed under the same license as the cthulhu package. -# -# Speak - Spreken/Lezen/Oplezen -# combo box - keuzemenu -# Say All - alles uitspreken -# enable - aanzetten -# -# Tino Meinen 2006. -# Vincent van Adrighem , 2006. -# Wouter Bolsterlee , 2006, 2008–2009, 2011. -# Hannie Dumoleyn , 2011, 2016. -# Redmar , 2011, 2014. -# Justin van Steijn , 2016, 2017. -# Nathan Follens , 2017-2022. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2022-12-19 19:37+0100\n" -"Last-Translator: Nathan Follens \n" -"Language-Team: Dutch \n" -"Language: nl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Launchpad-Export-Date: 2014-03-17 08:36+0000\n" -"X-Generator: Poedit 3.2.2\n" - -# vergrootglas/loep -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu schermlezer" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "scherm;lezer;toegankelijkheid;spraak;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "att" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "pijl" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "bschr" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "sel" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "klrkzr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "klmttl" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "klst" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "pic" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "map" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "teken" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "bkzr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "vlr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "lt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "kop" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "afb" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "glgdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnublk" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optpnl" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "vgblk" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "knp" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "kzrnd" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "kzmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "hfdpnl" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rttl" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "schfblk" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sect" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "schdng" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "scknp" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "gedpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "drav" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statblk" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cel" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "afsmnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tkst" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "sklknp" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "wblk" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "boom" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "bmtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "onb" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "blikvld" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "vns" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "kop" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "voet" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "alinea" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "toe" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "bwblk" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "inb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Tsjechisch klasse 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spaans klasse 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Canadees Frans klasse 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Frans klasse 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Lets klasse 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Nederlands klasse 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Noors klasse 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Noors klasse 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Noors klasse 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Noors klasse 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Pools klasse 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugees klasse 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Zweeds klasse 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabisch klasse 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Welsh klasse 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Welsh klasse 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Duits klasse 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Duits klasse 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Duits klasse 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Brits Engels klasse 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Brits Engels klasse 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Amerikaans Engels klasse 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Amerikaans Engels klasse 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Canadees Frans klasse 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Frans klasse 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grieks klasse 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi klasse 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Hongaarse 8-punt computer" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Hongaars klasse 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Hongaars klasse 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiaans klasse 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Vlaams klasse 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "spatie" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nieuwe regel" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "uitroepteken" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "aanhalingsteken" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "getal" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "en" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -# teken ( -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "linker haakje" - -# teken ) -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "rechter haakje" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "ster" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "komma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "streepje" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punt" - -# schrap/schuine schrap -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "schuine streep" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dubbele punt" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punt komma" - -# minder dan -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "kleiner dan" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "is gelijk" - -# meer dan -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "groter dan" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "vraag" - -# at/apestaart -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "apenstaart" - -# teken [ -# vierkante/rechte haak -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "rechte haak openen" - -# schuine streep/terugschrap (itt platte schrap) -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "backslash" - -# teken ] -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "rechte haak sluiten" - -# teken ^ -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "dakje" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "laag streepje" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "accent grave" - -# teken { -# haakje open -# accolade/paragraaf -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "linker accolade" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "verticale balk" - -# teken } -# haakje sluiten -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "rechter accolade" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "harde spatie" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "omgekeerd uitroepteken" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pond" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "valutasymbool" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "verticaal streepje" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "paragraaf" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "trema" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "linker dubbele driehoekige haak" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logische niet" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "koppelteken" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "geregistreerd" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "graden" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plusminus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superscript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superscript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "nadruk" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "alineamarkering" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "gecentreerde punt" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedille" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superscript 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "mannelijke rangtelwoord (Spaans)" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "rechter dubbele driehoekige haak" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "kwart" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "half" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "driekwart" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "omgekeerd vraagteken" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a accent aigu" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A ACCENT GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACCENT AIGU" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A CORONA" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLE" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E ACCENT GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACCENT AIGU" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I ACCENT GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACCENT AIGU" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O ACCENT GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACCENT AIGU" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "maal-teken" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O DOORHAAL" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U ACCENT GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACCENT AIGU" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U ACCENT CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACCENT AIGU" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "ringel-s" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a accent grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a accent circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a corona" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e accent grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e accent aigu" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e accent circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i accent grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i accent aigu" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i accent circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o accent grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o accent aigu" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o accent circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "gedeeld door" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o doorhaal" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u accent aigu" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u accent grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u accent circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y accent aigu" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "gulden" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "kort streepje" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "linker enkel aanhalingsteken" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "rechter enkel aanhalingsteken" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "linker dubbel aanhalingsteken" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "rechter dubbel aanhalingsteken" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dubbele apostrof" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "obelisk" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dubbele obelisk" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "rond opsommingsteken" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "driehoekig opsommingsteken" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "priem" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "dubbele priem" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "drievoudige tilde" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "streepjesopsommingsteken" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "t m" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "vinkje" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "dik vinkje" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-vormig opsommingsteken" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "superscript 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "superscript 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "superscript 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "superscript 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "superscript 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "superscript 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "superscript 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "superscript plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "superscript min" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "superscript is-teken" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "superscript haakje openen" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "superscript haakje sluiten" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "superscript n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "subscript 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "subscript 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "subscript 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "subscript 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "subscript 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "subscript 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "subscript 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "subscript 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "subscript 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "subscript 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "subscript plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "subscript min" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "subscript is-teken" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "subscript haakje openen" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "subscript haakje sluiten" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "zwart vierkantje" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "zwarte ruit" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "objectvervangingsteken" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Muisaanwijzer automatisch op het huidige item plaatsen" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Klik met linker muisknop op het huidige flat review item uitvoeren" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Klik met rechter muisknop op het huidige flat review item uitvoeren" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Hele document oplezen" - -# Ik weet niet hoe ik flat review moet vertalen. Heb het zo gelaten. -# Hannie -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Hele document oplezen met behulp van flat review" - -# voert uit/voert de bewerking uit/geeft -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Standaard waar-ben-ik-bewerking uitvoeren" - -# voert uit/voert de bewerking uit/geeft -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Gedetailleerde waar-ben-ik-bewerking uitvoeren" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Huidige selectie oplezen" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Verwijzingsdetails oplezen" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "De standaardknop presenteren" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Statusbalk voorlezen" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Titelbalk voorlezen" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Zoekvenster openen" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Actielijst weergeven" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Naar de volgende plaats waar de tekenreeks voorkomt zoeken" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Naar de vorige plaats waar de tekenreeks voorkomt zoeken" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Flat review modus starten en stoppen" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Platte weergave beperken tot huidig object omschakelen" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Flat review naar het begin verplaatsen" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Flat review naar het einde verplaatsen" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Flat review naar het begin van de vorige regel verplaatsen" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Huidige flat review regel oplezen" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Huidige flat review regel spellen" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Huidige flat review regel fonetisch spellen" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Flat review naar het begin van de volgende regel verplaatsen" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Flat review naar het vorige item of woord verplaatsen" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Huidig flat review item of woord oplezen" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Huidig flat review item of woord spellen" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Huidig flat review item of woord fonetisch spellen" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Flat review naar het volgende item of woord verplaatsen" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Flat review naar het woord boven het huidige woord verplaatsen" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Huidig flat review object oplezen" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Flat review naar het woord onder het huidige woord verplaatsen" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Flat review naar het vorige teken verplaatsen" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Huidig flat review teken oplezen" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Huidig flat review teken fonetisch oplezen" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Unicode-waarde van het huidige flat review teken oplezen" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Flat review naar het volgende teken verplaatsen" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Flat review naar het einde van de regel verplaatsen" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Flat review naar linksonder verplaatsen" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Inhoud van de flat review naar het klembord kopiëren" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Inhoud van de flat review aan het klembord toevoegen" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Platte weergave-inhoud tonen" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Schakelen tussen oplezen van slechts de huidige cel of de hele rij" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Eigenschappen van het huidige teken lezen" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Brailleweergave naar links schuiven" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Brailleweergave naar rechts schuiven" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Terug naar object met invoeraandacht" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Braille-kortschrift aan of uitzetten" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Tekeninstelling voor toets aanmaken" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Beginpunt van een tekstselectie aangeven" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Eindpunt van een tekstselectie aangeven" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Leermodus starten. Druk op de esc-toets om de leermodus te beëindigen" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Spraaksnelheid verlagen" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Spraaksnelheid verhogen" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Spraakhoogte verlagen" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Spraakhoogte verhogen" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Spraakvolume verhogen" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Spraakvolume verlagen" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Vorige spraakinstelling selecteren" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Volgende spraakinstelling selecteren" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Huidige spraakinstelling verlagen" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Huidige spraakinstelling verhogen" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Spraakinstellingen opslaan" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Spreken aan of uitzetten" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Schakelen tussen spraakdetailniveau's" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Slaapstand in-/uitschakelen" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Schermlezer afsluiten" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Voorkeurendialoogvenster weergeven" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Toepassingsvoorkeurendialoogvenster weergeven" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Schakelen tussen het oplezen van inspringen en uitlijnen" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "De manier waarop cijfers worden uitgesproken wijzigen" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Naar het volgende interpunctieuitspraakniveau gaan" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Naar volgende spraaksynthesizer schakelen" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Naar het volgende instellingenprofiel gaan" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Naar de volgende hoofdletterstijl gaan" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Naar het volgende toetsuitspraakniveau gaan" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Door debugniveaus bladeren tijdens uitvoeren" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Relatieve bladwijzer ten opzichte van de huidige positie" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Ga naar vorige bladwijzerlocatie" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Naar bladwijzer springen" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Naar volgende bladwijzer springen" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Bladwijzer toevoegen" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Bladwijzers opslaan" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Muisoverzichtmodus aan of uitzetten" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Geef de huidige tijd" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Geef de huidige datum" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Grootte en locatie van het huidige object weergeven" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Volgende opdracht aan de huidige toepassing geven" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Voorgaand bericht in een chatruimte oplezen en in braille tonen" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Aangeven of we aankondigen wanneer onze vrienden aan het typen zijn" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Aangeven of we berichtengeschiedenis per chatruimte aanbieden" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Aangeven of berichten in de chatruimte voorafgegaan worden door de naam van " -"de chatruimte" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Regel naar links" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Regel naar rechts" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Regel omhoog" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Regel omlaag" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Vastzetten" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Linksboven" - -# onderkant/onder -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Linksonder" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Cursorpositie" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Zes punten" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Cursor-routing" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Begin knippen" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Regel knippen" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Laatste notificatiebericht presenteren" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Lijst met notificatieberichten tonen" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Voorgaand notificatiebericht presenteren" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Volgende melding voorlezen" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Ga naar het volgende teken" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Ga naar het vorige teken" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Ga naar het volgende woord" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Ga naar het vorige woord" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Ga naar de volgende regel" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Ga naar de vorige regel" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Ga naar het begin van het bestand" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Ga naar het einde van het bestand" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Ga naar het begin van de regel" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Ga naar het einde van de regel" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Ga naar het volgende object" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Ga naar het vorige object" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Klapt het keuzemenu uit" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Wisselt tussen eigen en schermlezer caret-navigatie" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Geavanceerde live-regio beleefdheidsinstelling" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Standaard live-regio beleefdheidsinstelling uitzetten" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Live-regio's aankondigingen nakijken" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Live-regio's in de gaten houden" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" -"Focus verplaatsen naar de toepassing waar de muis zich boven bevindt of " -"terugkeren" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Rij die als dynamische kolomkopteksten gebruikt moet worden instellen" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Dynamische kolomkopteksten wissen" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Kolom die als dynamische rijkopteksten gebruikt moet worden instellen" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Dynamische rijkopteksten wissen" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Inhoud van de invoerregel presenteren" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Structurele navigatietoetsen aan of uitzetten" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Naar vorig citaat gaan" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Naar volgend citaat gaan" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Lijst van citaten tonen" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Naar vorige knop gaan" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Naar volgende knop gaan" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Lijst van knoppen tonen" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Naar vorig selectievakje gaan" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Naar volgend selectievakje gaan" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Lijst van selectievakjes tonen" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Naar vorig klikbaar element gaan" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Naar volgend klikbaar element gaan" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Lijst van klikbare elementen tonen" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Naar vorig keuzemenu gaan" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Naar volgend keuzemenu gaan" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Naar begin van de container gaan" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Naar einde van de container gaan" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Lijst van keuzemenu's tonen" - -# Ik veronderstel dat een 'entry' geen veld voor tekstinvoer is. - Nathan -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Naar vorig item gaan" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Naar volgend item gaan" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Lijst van items tonen" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Naar vorig veld gaan" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Naar volgend veld gaan" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Lijst van velden tonen" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Naar vorige koptekst gaan" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Naar volgende koptekst gaan" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Lijst van kopteksten tonen" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Naar vorige koptekst op niveau %d gaan" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Naar volgende koptekst op niveau %d gaan" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Lijst van kopteksten op niveau %d tonen" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Naar vorig intern frame gaan" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Naar volgend intern frame gaan" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Lijst met interne frames weergeven" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Naar vorige afbeelding gaan" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Naar volgende afbeelding gaan" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Lijst van afbeeldingen tonen" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Naar vorige mijlpaal gaan" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Naar volgende mijlpaal gaan" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Lijst van mijlpalen tonen" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Naar vorig groot object gaan" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Naar volgend groot object gaan" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Lijst van grote objecten tonen" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Naar vorige koppeling gaan" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Naar volgende koppeling gaan" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Lijst van koppelingen tonen" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Naar vorige lijst gaan" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Naar volgende lijst gaan" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Lijst van lijsten tonen" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Naar vorig lijstitem gaan" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Naar volgend lijstitem gaan" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Lijst van lijstitems tonen" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Naar vorige live-regio gaan" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Naar volgende live-regio gaan" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Naar laatste live-regio die een melding gaf gaan" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Ga naar het bovenliggende object van het object met navigatorfocus." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Ga naar het eerste onderliggende object van het object met navigatorfocus." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Ga naar het volgende broer/zus-object van het object met navigatorfocus." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Ga naar het vorige broer/zus-object van het object met navigatorfocus." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Klikken op het object met navigatorfocus." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Vereenvoudigde objectnavigatie omschakelen." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Naar vorige alinea gaan" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Naar volgende alinea gaan" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Lijst van alinea's tonen" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Naar vorig keuzerondje gaan" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Naar volgend keuzerondje gaan" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Lijst van keuzerondjes tonen" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Naar vorig scheidingsteken gaan" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Naar volgend scheidingsteken gaan" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Naar vorige tabel gaan" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Naar volgende tabel gaan" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Lijst van tabellen tonen" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Één cel naar beneden gaan" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Naar de eerste cel in een tabel gaan" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Naar de laatste cel in een tabel gaan" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Één cel naar links gaan" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Één cel naar rechts gaan" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Één cel naar boven gaan" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Layoutmodus aan of uitzetten" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Wisselen tussen bladermodus en focusmodus" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Kleverige focusmodus aanzetten" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Kleverige bladermodus aanzetten" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Naar vorige niet-bezochte verwijzing gaan" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Naar volgende niet-bezochte verwijzing gaan" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Lijst van niet-bezochte verwijzingen tonen" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Naar vorige bezochte verwijzing gaan" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Naar volgende bezochte verwijzing gaan" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Lijst van bezochte verwijzingen tonen" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "aliceblauw" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antiek wit" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "aquamarijn" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azuur" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "zwart" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "amandel" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blauw" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "blauw violet" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "bruin" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadetblauw" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "groen" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chocolade" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koraal" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "korenbloemblauw" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "vermiljoen" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cyaan" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "donkerblauw" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "donkercyaan" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "donkerguldenroede" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "donkergrijs" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "donkergroen" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "donkerkhaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "donkermagenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "donkerolijfgroen" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "donkeroranje" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "donker orchidee" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "donkerrood" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "donkerzalm" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "donker zeegroen" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "donkerleiblauw" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "donkerleigrijs" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "donkerturkoois" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "donkerviolet" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "dieproze" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "diep hemelsblauw" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "dimgrijs" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodgerblauw" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "vuurvaste baksteen" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "fluweelwit" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "bosgroen" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "geestwit" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "goud" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "guldenroede" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "grijs" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "groen" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "groengeel" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "honingdauw" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "acaciaroze" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indisch rood" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "ivoor" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavendel" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavendelblush" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "grasgroen" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "citroenchiffon" - -# teken } -# haakje sluiten -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "lichtblauw" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "lichtkoraal" - -# teken ) -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "lichtcyaan" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "lichtguldenroedegeel" - -# teken } -# haakje sluiten -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "lichtgrijs" - -# teken ) -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "lichtgroen" - -# teken ) -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "lichtroze" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "lichtzalm" - -# teken ) -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "lichtzeegroen" - -# teken ) -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "lichthemelsblauw" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "lichtleigrijs" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "lichtstaalblauw" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "lichtgeel" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limoen" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limoengroen" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linnen" - -# meervoud is hier beter? -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "kastanjebruin" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "midden aquamarijn" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "middenblauw" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "midden orchidee" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "middenpaars" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "middenzeegroen" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "middenleiblauw" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "midlentegroen" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "middenturkoois" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "middenvioletrood" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "midnachtsblauw" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "mint" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "mistigroze" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "moccasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajo wit" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "marine" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "kant" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olijf" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "olijfgrijs" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oranje" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "oranjerood" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchidee" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "lichtguldenroede" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "bleekgroen" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "lichtturkoois" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "lichtvioletrood" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "perzik puff" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "roos" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "pruim" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "poederblauw" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "paars" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "rood" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rozig bruin" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "koninklijk blauw" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "zadelbruin" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "zalm" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "zandbruin" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "zeegroen" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "schelp" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "zilver" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "hemelsblauw" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "leiblauw" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "leigrijs" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "sneeuw" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "lentegroen" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "staalblauw" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "bruin" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "groenblauw" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "distel" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomaatrood" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turkoois" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violet" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "tarwe" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "wit" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "witte rook" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "geel" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "geelgroen" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Activeren" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatische focusmodus tijdens structurele navigatie" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatische focus-modus tijdens caret-navigatie" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatische focusmodus tijdens caret-navigatie" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punt _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punt _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Punten 7 _en 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Annuleren" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Spring naar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Ok" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Pictogram" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Uitgezet" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Spell" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Melden wanneer uw _vrienden aan het typen zijn" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "_Berichtengeschiedenis per chatruimte aanzetten" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Lees berichten op van" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Alle ka_nalen" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Alle kanalen waar _enig %s venster actief is" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Een kanaal alleen als het _venster actief is" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Naam van chatruimte uitspreken" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Schakelt layoutmodus in voor inhoud" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dubbelklik" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "driemaal klikken" - -# stemsynthesizer -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Standaard synthesizer" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Eigenlijke tekst" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Vervanging" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Uitspreken pe_r teken" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Activeer non-spatiërende diakritische toetsen" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Huidige locatie" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimumlengte van overeenkomende tekst:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Zoekopties" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Alleen ge_wijzigde regels uitspreken tijden zoekactie" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Resultaten uitspreken _tijdens zoekactie" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Opdracht" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Sneltoetsen" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Standaard" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Layoutmodus." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Acties" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braille-koppelingen" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Bladwijzers" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Tijd en datum" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Muisoverzichtmodus aangezet." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navigatie" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objectmodus." - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Ongebonden" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Beëindigen van flat review." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Schakelen tussen spraakdetailniveau's" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "belangrijkste inhoud" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Aangepast" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Bureaublad" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificatie" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Ontvangen" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Notificatie" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu-voorkeuren voor %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Markering in braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Weergeven tenzij" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Spreken" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Profiel opslaan als conflict" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflict in gebruikersprofiel!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profiel %s bestaat al.\n" -"Wilt u doorgaan met het bijwerken van het bestaande profiel met deze nieuwe " -"wijzigingen?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Gebruikersprofiel laden" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"U staat op het punt het actieve profiel te wijzigen. Als u\n" -"zojuist wijzigingen heeft aangebracht in uw voorkeuren \n" -"zullen deze verloren gaan bij het laden van het profiel.\n" -"\n" -"Wilt u doorgaan met het laden van het profiel en \n" -"vorige wijzigingen verloren laten gaan?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Profiel opslaan als" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profielnaam:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Gebruikersprofiel verwijderen" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"U staat op het punt het profiel %s te verwijderen. Alle niet-opgeslagen " -"instellingen evenals instellingen opgeslagen in dit profiel zullen verloren " -"gaan. Weet u zeker dat u wilt verdergaan en dit profiel en alle daaraan " -"gekoppelde instellingen verwijderen?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Alle" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Toepassing" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Venster" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Geen" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Enkele" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Meeste" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Regel" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Zin" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Aanhalingsteken" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Knop" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Bijschrift" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Selectievakje" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Klikbaar" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Keuzemenu" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Omschrijving" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Koptekst" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "intercalate" - -# meervoud is hier beter? -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Afbeelding" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Label" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Mijlpaal" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Niveau" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Link" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lijst" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Lijstobject" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Object" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Alinea" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Keuzerondje" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rol" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Geselecteerd item" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Status" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Tekst" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Waarde" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Aanhalingstekens" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Knoppen" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Selectievakjes" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Klikbare elementen" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Keuzemenu's" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entries" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Formulieren" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Koptekst" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "intercalate" - -# meervoud is hier beter? -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Afbeeldingen" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Kopteksten op niveau %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Mijlpalen" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Grote objecten" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Links" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Lijsten" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Lijstobjecten" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Alinea" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Keuzerondjes" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabellen" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Niet-bezochte links" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Bezochte links" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Paginanavigatie" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Pagina automatisch oplezen wanneer deze voor het _eerst geladen wordt" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"_Samenvatting van een pagina geven wanneer deze voor het eerst geladen wordt" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "In stukken _uitspreken met pauzes" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s standaard stem" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Standaard" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Systeem" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Hoofdletter" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Spellingscontrole" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Spellings_fout" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Spellings_suggestie" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Huidige _context van fout" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Cel-coördinaten van rekenblad oplezen" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Het geselecteerde rekenbladbereik altijd oplezen" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Cel_kop uitspreken" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Tabelnavigatie" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "_Lege cellen overslaan" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "_Cel uitspreken" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "_Celcoördinaten uitspreken" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Celspanne _uitspreken" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Attribuutnaam" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Caretnavigatie kiezen" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "_Structurele navigatie aanzetten" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Geluids_thema:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Geluidsthema" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Kort" - -#: src/cthulhu/guilabels.py:953 -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Notificatie" -msgstr[1] "Notificatie" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "linker shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "linker alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "linker control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "rechter shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "rechter alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "rechter control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "linker meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "rechter meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "linker tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -# meer dan -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "omhoog" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "omlaag" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "links" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "rechts" - -# teken ( -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "linker super" - -# teken ) -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "rechter super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "hulp" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "modus-wisselaar" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "dakje" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "cirkeltje" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "doorstreept" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -# dit is geen waarschuwing -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "vet %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "cursief %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "vet cursief %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "script %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "vetgedrukt script %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "dubbel-doorgehaald %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "vet fraktur %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif vet %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif cursief %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif vet cursief %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "monospace %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "puntloos %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "pijl naar links" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "pijl naar boven" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "pijl naar rechts" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "pijl naar beneden" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "pijl naar links en rechts" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "pijl naar boven en beneden" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "pijl naar noordwesten" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "pijl naar noordoosten" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "pijl naar zuidoosten" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "pijl naar links vanuit streep" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "pijl naar boven vanuit streep" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "pijl naar rechts vanuit streep" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "pijl naar beneden vanuit streep" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dubbele pijl naar links" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dubbele pijl naar boven" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dubbele pijl naar rechts" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dubbele pijl naar beneden" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dubbele pijl naar links en rechts" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dubbele pijl naar boven en beneden" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dubbele pijl naar noordwesten" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dubbele pijl naar noordoosten" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dubbele pijl naar zuidoosten" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dubbele pijl naar zuidwesten" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "pijltje naar rechts" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "pijlpunt naar rechts" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "min" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "minder dan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "meer dan" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "dakje" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punt" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dubbele verticale lijn" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horizontale ellips" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "voor alle" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "partiële differentiaal" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "er bestaat een" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "er bestaat geen" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "lege set" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "toename" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "element van" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "geen element van" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "klein element van" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "bevat als lid" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "bevat niet als lid" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "klein bevat als lid" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "einde van bewijs" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "product" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproduct" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sommatie" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "min of plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "punt plus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "divisieslash" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "set min" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "sterretje-operator" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "ring operator" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "bullet oeprator" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "vierkantswortel" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "derdemachtswortel" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "vierdemachtswortel" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proportioneel met" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "oneindig" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "rechte hoek" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "hoek" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "gemeten hoek" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sferische hoek" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "gedeeld door" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "is niet deelbaar" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "parallel met" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "niet parallel aan" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logische en" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logische of" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "doorsnede" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unie" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integraal" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dubbele integraal" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "drievoudige integraal" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "kringintegraal" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "oppervlakteintegraal" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "volumeintegraal" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integraal in negatieve zin" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "kringintegraal in negatieve zin" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "kringintegraal in positieve zin" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "dus" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "want" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "ratio" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proportie" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "dot min" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "teveel" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrische verhouding" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homothetisch" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "omgekeerde tilde" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "omgekeerde liggende S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusgolf" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "kransproduct" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "niet-tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "min-tilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptotisch gelijk aan" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "niet asymptotisch gelijk aan" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "ongeveer gelijk aan" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "ongeveer maar niet echt gelijk aan" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ongeveer noch echt gelijk aan" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "bijna gelijk aan" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "niet bijna gelijk aan" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "bijna gelijk of gelijk aan" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "drievoudige tilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "alles gelijk aan" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "gelijkwaardig aan" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrisch gelijkwaardig aan" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "verschil tussen" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "nadert de limiet" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrisch gelijk aan" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "ongeveer gelijk aan of het beeld van" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "beeld van of ongeveer gelijk aan" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dubbelepunt gelijk aan" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "gelijk aan dubbelepunt" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ring in gelijk aan" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ring gelijk aan" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "komt overeen met" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "schat" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "gelijkhoekig aan" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "ster gelijk aan" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta gelijk aan" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "gelijk aan per definitie" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "gemeten door" - -# minder dan -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "gevraagd gelijk aan" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "niet gelijk aan" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identiek aan" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "niet identiek aan" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "strikt gelijkwaardig aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "kleiner dan of gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "groter dan of gelijk aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "minder dan gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "meer dan gelijk aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "kleiner dan maar niet gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "groter dan maar niet gelijk aan" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "veel kleiner dan" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "veel groter dan" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "tussen" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "niet gelijkwaardig aan" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "niet minder dan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "niet groter dan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "kleiner dan noch gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "groter dan noch gelijk aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "kleiner dan of gelijkwaardig aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "groter dan of gelijkwaardig aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "kleiner dan noch gelijkwaardig aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "groter dan noch gelijkwaardig aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "kleiner dan of groter dan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "groter dan of kleiner dan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "kleiner dan noch groter dan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "groter dan noch kleiner dan" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "gaat vooraf aan" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "volgt op" - -# minder dan -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "voorafgaand of gelijk aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "volgend op of gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "gaat vooraf of is gelijkwaardig aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "volgend op of gelijkwaardig aan" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "gaat niet vooraf aan" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "volgt niet op" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subset van" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superset van" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "geen subset van" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "geen superset van" - -# minder dan -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subset van of gelijk aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superset van of gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "subset van noch gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "superset van noch gelijk aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subset van met niet gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superset van met niet gelijk aan" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiset" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiset vermenigvuldiging" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "multiset-unie" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "vierkant beeld van" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "vierkant origineel van" - -# meer dan -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "vierkant beeld van of gelijk aan" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "vierkant origineel van of gelijk aan" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "vierkante cap" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "vierkante cup" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "omcirkelde plus" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "omcirkelde min" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "omcirkelde maal" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "omcirkeld deelteken" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "omcirkelde punt operator" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "omcirkelde ronde operator" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "omcirkelde sterretje-operator" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "omcirkelde gelijk aan" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "omcirkeld streepje" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "vierkante plus" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "vierkante min" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "vierkante maal" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "vierkante punt operator" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "rechter tab" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "linker tab" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "tab naar beneden" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "tab naar boven" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "stelling" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modelleert" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "waar" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "dwingt" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "drie verticale streepjes met streepje naar rechts" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dubbele verticale streep met dubbel streepje naar rechts" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "bewijst niet" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "niet waar" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "dwingt niet" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" -"dubbel verticaal streepje met dubbel doorgestreept streepje naar rechts" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "voorafgaand aan onder relatie" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "volgend op onder relatie" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normale subgroep van" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "bevat als normale subgroep" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normale subgroep van of gelijk aan" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "bevat als normale subgroep van of gelijk aan" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "origineel van" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "afbeelding van" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimap" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitische conjuncte matrix" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalate" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "exclusieve disjunctie" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "niet en" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "noch" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "rechte hoek met boog" - -# teken } -# haakje sluiten -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "rechte driehoek" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "diamond" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "punt" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "ster operator" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "gedeeld door keer" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "horizontale zandloper" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "links normaal factor semidirect product" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "rechts normaal factor semidirect product" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "links semidirect product" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "rechts semidirect product" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "omgekeerde tilde gelijk aan" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "gekromde logische of" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "gekromde logische en" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dubbele subset" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dubbele superset" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dubbele doorsnede" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dubbele unie" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "mestvork" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "gelijk en parallel aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "kleiner dan met punt" - -# meer dan -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "groter dan met punt" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "erg veel kleiner dan" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "erg veel groter dan" - -# minder dan -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "kleiner dan gelijk aan of groter dan" - -# meer dan -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "groter dan gelijk aan of kleiner dan" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "gelijk aan of kleiner dan" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "gelijk aan of groter dan" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "gelijk of voorafgaand aan" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "gelijk aan of volgend op" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "niet voorafgaand of gelijk aan" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "niet volgend op of gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "geen vierkant beeld van of gelijk aan" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "niet vierkant origineel van of gelijk aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "vierkant beeld van of niet gelijk aan" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "vierkant origineel van maar niet gelijk aan" - -# minder dan -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "kleiner dan maar niet gelijkwaardig aan" - -# meer dan -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "groter dan maar niet gelijkwaardig aan" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "gaar vooraf maar is niet equivalent aan" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "volgt op maar is niet equivalent aan" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "geen normale subgroep van" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "bevat niet als normale subgroep" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "geen normale subgroep van of gelijk aan" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "bevat niet als normale subgroep of gelijk aan" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "verticale ellips" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "horizontale ellips in het midden" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "diagonale ellips richting rechtsboven" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "diagonale ellips richting rechtsonder" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "element van met lange horizontale doorhaalstreep" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" -"element van met verticaal streepje aan het einde van horizontale " -"doorhaalstreep" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"klein element van met verticaal streepje aan het einde van verticale " -"doorhaalstreep" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "element van met punt erboven" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "element van met streepje erboven" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "klein element van met streepje erboven" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "element van met streepje eronder" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "element van met dubbele horizontale doorhaalstreep" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "bevat met lange horizontale doorhaalstreep" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" -"bevat met verticaal streepje aan het eind van horizontale doorhaalstreep" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"klein bevat met verticaal streepje aan het eind van horizontale " -"doorhaalstreep" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "bevat met streepje erboven" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "klein bevat met streepje erboven" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z-notatie tas-lidmaatschap" - -# teken ( -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "linker ceiling" - -# teken ) -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "rechter ceiling" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "linker entier" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "rechter entier" - -# teken { -# haakje open -# accolade/paragraaf -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "accolade boven" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "accolade beneden" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "linker driehoekige haak" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "rechter driehoekige haak" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "omcirkelde punt" - -# minder dan -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "u met punt" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "u met plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "vierkante doorsnede" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "vierkante vereniging" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "zwart vierkantje" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "wit vierkantje" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "zwarte ruit" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "witte cirkel" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "zwarte cirkel" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "wit rond opsommingsteken" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "zwart medium klein vierkantje" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s met laag streepje" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s met slash" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s met verticale lijn" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "toepassing" - -# blanko/leeg -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "leeg" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "vet" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "opgegeven bladwijzer" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "bladwijzers opgeslagen" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "kan bladwijzers niet opslaan" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Geen mijlpaal gevonden." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Geen mijlpaal gevonden." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Bypass-modus aangezet." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Kon rekenmachine-weergave niet verkrijgen" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "pictogram" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Hoofdletterstijl is nu pictogram." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "geen" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Hoofdletterstijl is nu geen." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "spell" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Hoofdletterstijl ingesteld op spell." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "De toepassing beheert de caret." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu bestuurt de cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cel %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s geselecteerd" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s tot en met %s geselecteerd" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s tot en met %s niet geselecteerd" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s niet geselecteerd" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Gebruik van optie voorkomen" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Gebruik van optie forceren" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPTIE" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Optionele argumenten" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Gebruik: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "De volgende argumenten zijn ongeldig: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Momenteel actieve toepassingen tonen" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Profiel laden" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profiel kon niet geladen worden: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Kan Cthulhu niet starten omdat het geen verbinding kan maken met het " -"bureaublad.Kan de schermlezer niet starten omdat deze niet kan verbinden met " -"het bureaublad." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Kan niet starten door een fout in de voorkeuren." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Er is al een ander schermlezerproces actief voor deze sessie.\n" -"Voer “cthulhu --replace” uit om dat proces te vervangen." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Alternatieve map gebruiken voor gebruikersvoorkeuren" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "MAP" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versie van deze toepassing" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Een momenteel draaiende instantie van Cthulhu vervangen" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Dit hulpbericht tonen en verlaten" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Stuur debug-output naar debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Stuur debuginformatie naar het gespecificeerde bestand" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "BESTAND" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Gebruikersvoorkeuren (tekstversie)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Stel gebruikersvoorkeuren in (GUI-versie)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Rapporteer fouten bij https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Selectie is naar het klembord geknipt." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "knippen" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Selectie is naar het klembord gekopieerd." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "gekopieerd" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Inhoud uit het klembord geplakt." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "geplakt" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Niet melden wanneer uw vrienden aan het typen zijn." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "melden wanneer uw vrienden aan het typen zijn." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Bericht in chatruimte %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nieuw chat-tabblad %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Naam van chatruimte niet uitspreken." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "naam van chatruimte uitspreken." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Gespreksgeschiedenis per chatruimte niet aanzetten." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Gespreksgeschiedenis per chatruimte aanzetten." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "start verwijdering" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "einde verwijdering" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "start invoeging" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "einde invoeging" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "start markering" - -# teken ) -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "einde markering" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "einde suggestie" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Einde container." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Niet in een container." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "alle items geselecteerd" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Standaardknop is %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Standaardknop is %s. Gedimd" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Standaardknop is %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subscript %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " superscript %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Niet in een tabel." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "gehele document geselecteerd" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "gehele document niet geselecteerd" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "document geselecteerd vanaf cursorpositie" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "documentselectie ongedaan gemaakt vanaf cursorpositie" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "document geselecteerd tot aan cursorpositie" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "documentselectie ongedaan gemaakt tot cursorpositie" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynamische kolomkopteksten ingesteld voor rij %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynamische kolomkopteksten gewist." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynamische rijkopteksten ingesteld voor kolom %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynamische rijkopteksten gewist." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "leeg" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Geen bestanden gevonden." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "De inhoud is aan het klembord toegevoegd." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "De inhoud is naar het klembord gekopieerd." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Flat review is niet actief." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Starten van flat review." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Beëindigen van flat review." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Flat review naar het woord boven het huidige woord verplaatsen" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Platte weergave onbeperkt" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "bevat formule" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "opent dialoogvenster" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "opent raster" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "opent lijstbox" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "opent menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "opent boom" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "image-map link" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "De ingegeven toets is reeds gebonden aan %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Toets %s ontvangen. Druk op Enter om te bevestigen." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "De nieuwe sneltoets is: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Toetskoppeling gewist. Druk op Enter om te bevestigen." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Sneltoets is verwijderd." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "geef een nieuwe sneltoets in" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "toets" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Uitspraak ingesteld op toets." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Uitgezet" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Uitspraak uitgezet." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "toets en woord" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Uitspraak ingesteld op toets en woord." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "zin" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Uitspraak ingesteld op zin." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "woord" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Uitspraak ingesteld op woord." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "woord en zin" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Uitspraak ingesteld op woord en zin." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Omsloten door: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "een actuarisch teken" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "een doos" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "een cirkel" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "een lange breukstreep" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "een wortel" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "een afgeronde doos" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "een horizontale doorhaalstreep" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "een verticale doorhaalstreep" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "een diagonale doorhaalstreep naar beneden" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "een diagonale doorhaalstreep naar boven" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "een pijl naar noordoosten" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "een lijn aan de onderkant" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "een lijn aan de linkerkant" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "een lijn aan de rechterkant" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "een lijn aan de bovenkant" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "een fasor-hoek" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "een arabisch faculteit-symbool" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "en" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "start breuk" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "breuk zonder streep, start" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "boven" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "einde breuk" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "tweedemachtswortel van" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "derdemachtswortel van" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "wortel van" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "begin van wortel" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "einde van wortel" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subscript" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "superscript" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "voor subscript" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "voor superscript" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "onderschrift" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "bovenschrift" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "einde van tabel" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "einde van ingesloten tabel" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "ontoegankelijk" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Uitgezet" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Uitspreken van inspringen en uitlijning uitgezet." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Aangezet" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Uitspreken van inspringen en uitlijning aangezet." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Leermodus. Druk op de esc-toets om te verlaten." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Leermodus geactiveerd. Druk op een toets om de functie van die toets te " -"horen. Druk op F1 voor de documentatie van de schermlezer. Druk op F2 voor " -"een lijst van de standaard sneltoetsen van de schermlezer. Druk op F3 voor " -"een lijst van de standaard sneltoetsen voor de huidige toepassing. Druk op " -"escape om de leermodus af te sluiten." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "citaat verlaten." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "details verlaten." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "feed verlaten." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "figuur verlaten." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "formulier verlaten." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "banner verlaten." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "aanvullende inhoud verlaten." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "informatie verlaten." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "belangrijkste inhoud verlaten." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "navigatie verlaten." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "regio verlaten." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "zoeken verlaten." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "lijst verlaten." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "paneel verlaten." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "tabel verlaten." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "tip verlaten." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "abstract verlaten." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "dankwoord verlaten." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "nawoord verlaten." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "appendix verlaten." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "bibliografie verlaten." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "hoofdstuk verlaten." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "colofon verlaten." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "besluit verlaten." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "generiek verlaten." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "generiek verlaten." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "toewijding verlaten." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "eindnoten verlaten." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "epigraaf verlaten." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "epiloog verlaten." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "errata verlaten." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "voorbeeld verlaten." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "voorwoord verlaten." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "woordenlijst verlaten." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "index verlaten." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "inleiding verlaten." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "paginalijst verlaten." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "deel verlaten." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "voorwoord verlaten." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "proloog verlaten." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "pullcitaat verlaten." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "vraag en antwoord verlaten." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "suggestie verlaten." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "inhoudsopgave verlaten." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "regel geselecteerd vanaf cursorpositie" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "regel geselecteerd tot aan cursorpositie" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "regel niet geselecteerd vanaf de muispositie" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "regel niet geselecteerd tot de muispositie" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Leermodus wordt afgesloten." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "regel geselecteerd vanaf begin tot vorige cursorpositie" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "regel geselecteerd vanaf vorige cursorpositie tot einde" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "link" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "zelfde pagina" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "zelfde site" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "andere site" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s verwijst naar %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s link" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "bezochte %s-verwijzing" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Gebruik de pijltjestoetsen naar boven en beneden on door de lijst te " -"navigeren. Druk op Escape om af te sluiten." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Alle live-regio's uitgezet" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "niveau live-regio's hersteld" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "beleefdheidsniveau %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "live-regio op assertief gezet" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "live-regio uitgezet" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "live-regio op voorzichtig gezet" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "live-regio op aggressief gezet" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Live-regio afhandeling staat uit" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Live-regio afhandeling staat aan" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "geen live-bericht opgeslagen" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Live-regio ondersteuning staat uit" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Niet gevonden" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Kon huidige locatie niet vinden." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "uit" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "aan" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "verkeerd gespeld" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Verkeerd gespeld woord: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Context is %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Bladermodus" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Focus-modus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Druk op %s om focus-modus aan te zetten." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Focus-modus is kleverig." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Bladermodus is kleverig." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Layoutmodus." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objectmodus." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Geen grote objecten meer." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Muis bevindt zich niet boven object." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Muisoverzichtmodus uitgezet." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Muisoverzichtmodus aangezet." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Fout: Kon geen lijst van objecten aanmaken." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Geen onderliggende elementen." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Geen volgende." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d procent." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Ga naar het vorige woord" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Vereenvoudigde navigatie ingeschakeld." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Vereenvoudigde navigatie uitgeschakeld." - -# vertakking/boomniveau/vertakkingsniveau -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Vertakkingsniveau %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Een nieuw item is toegevoegd" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Geen acties gevonden op: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Geen focus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Geen toepassing die de focus heeft." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Geen citaten meer." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Geen knoppen meer." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Geen selectievakjes meer." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Geen grote objecten meer." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Geen klikbare elementen meer." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Geen keuzemenu's meer." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Geen invoervelden meer." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Geen velden meer." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Geen verdere kopteksten." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Geen verdere kopteksten op niveau %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Geen tabellen meer." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Geen afbeeldingen meer." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Geen mijlpaal gevonden." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Geen links meer." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Geen lijsten meer." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Geen lijst-items meer." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Geen live-regio's meer." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Geen paragrafen meer." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Geen keuzerondjes meer." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Geen scheidingstekens meer." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Geen tabellen meer." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Geen niet-bezochte verwijzingen meer." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Geen bezochte verwijzingen meer." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Geen geselecteerde tekst." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Niet op een verwijzing." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificatie" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Einde" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Begin" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Geen notificatieberichten" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "getallen" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Nummers als getallen uitspreken." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "woorden" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Nummers als woorden uitspreken." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "uit" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "aan" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Bezig met laden. Even geduld alstublieft." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Klaar met laden." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Klaar met laden van %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Pagina heeft %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "pagina geselecteerd vanaf cursorpositie" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "pagina geselecteerd tot aan cursorpositie" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "paginaselectie ongedaan gemaakt vanaf cursorpositie" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "paginaselectie ongedaan gemaakt naar cursorpositie toe" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "alinea geselecteerd vanaf de cursorpositie" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "alinea boven de cursorpositie geselecteerd" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "alineaselectie ongedaan gemaakt vanaf de cursorpositie" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "alineaselectie ongedaan gemaakt boven de cursorpositie" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Er is al een Cthulhu-voorkeurenvenster geopend.\n" -"Sluit deze voordat u een nieuw venster te opent." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "dia %(position)d van %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profiel ingesteld op %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Geen profielen gevonden." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Voortgangsbalk %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Alle" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Interpunctieniveau ingesteld op alle." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Meeste" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Interpunctienivau ingesteld op meeste." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Geen" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Interpunctieniveau ingesteld op geen." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Enkele" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Interpunctieniveau ingesteld op enkele." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Zoeken." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Zoeken voltooid." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu-instellingen herladen." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "De geselecteerde tekst is: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Selectie verwijderd." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Selectie hersteld." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Tekst niet geselecteerd." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Grootte: %d, %d. Locatie: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Breedte: %d. Hoogte: %d. %d van de linkerkant. %d van de bovenkant." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Oplezen uitgezet." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Oplezen aangezet." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "sneller." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "langzamer." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "hoger." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "lager." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "luider." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "zachter." - -# snelhied/frequentie -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Snelheid %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Toonhoogte %s" - -# volume geluidssterkte -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volume %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher-module %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher-stem %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Geen Speech-dispatcher modules beschikbaar" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Geen Speech-dispatcher stemmen beschikbaar" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Spraakinstellingen opgeslagen" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Spraakinstellingen konden niet worden opgeslagen" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Detailniveau: beknopt" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Detailniveau: gedetaillerd" - -# punt punt punt/drie punten -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " punt punt punt" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu heet u welkom." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu loert onder de golven." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Slaapmodus ingeschakeld voor %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Slaapstand uitgeschakeld voor %s" - -# zie ook: speech is not available -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Spraak is niet beschikbaar." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Niet gevonden" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Statusbalk niet gevonden" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "tekenreeks niet gevonden" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Structurele navigatietoetsen uitgezet." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Structurele navigatietoetsen aangezet." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Niet gevonden" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Rij %(row)d, kolom %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Einde tabel" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Cel uitspreken" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Rij uitspreken" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Niet-uniform" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Niet in een tabel." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Volgorde kolommen aangepast" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Volgorde rijen aangepast" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "kolom %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolom %(index)d van %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Onderkant van kolom." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Bovenkant van kolom." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Kolom %s geselecteerd" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Kolommen %s tot en met %s geselecteerd" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Kolommen %s tot en met %s niet geselecteerd" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Kolom %s niet geselecteerd" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "rij %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "rij %(index)d van %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Begin van rij." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Einde van rij." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Rij verwijderd." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Laatste rij verwijderd." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Rij ingevoegd." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Rij toegevoegd aan het eind van de tabel." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Rij %s geselecteerd" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Rijen %s tot en met %s geselecteerd" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Rijen %s tot en met %s niet geselecteerd" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Rij %s niet geselecteerd" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "geselecteerd" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "niet geselecteerd" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H uur, %M minuten en %S seconden" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H uur en %M minuten" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "ongedaan maken" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "opnieuw" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versie %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "witruimte" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Vanaf onderzijde voortzetten." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Vanaf bovenzijde voortzetten." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 items" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Cel beslaat %d rij" -msgstr[1] "Cel beslaat %d rijen" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d kolom" -msgstr[1] " %d kolommen" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Cel beslaat %d kolom" -msgstr[1] "Cel beslaat %d kolommen" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d teken te lang" -msgstr[1] "%d tekens te lang" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialoogvenster)" -msgstr[1] "(%d dialoogvensters)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d dialoogvenster zonder focus" -msgstr[1] "%d dialoogvensters zonder focus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d bestand gevonden" -msgstr[1] "%d bestanden gevonden" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulier" -msgstr[1] "%d formulieren" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d koptekst" -msgstr[1] "%d kopteksten" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d item" -msgstr[1] "%d items" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d mijlpaal" -msgstr[1] "%d mijlpalen" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d item gevonden" -msgstr[1] "%d items gevonden" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "%d citaat verlaten." -msgstr[1] "%d citaten verlaten." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "%d lijst verlaten." -msgstr[1] "%d lijsten verlaten." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Lijst van onbekende grootte" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lijst met %d item" -msgstr[1] "Lijst met %d items" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Feed van onbekende grootte" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Feed met %d artikel" -msgstr[1] "Feed met %d artikels" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Definitielijst met %d term" -msgstr[1] "Definitielijst met %d termen" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d waarde" -msgstr[1] "%d waarden" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "wiskundetabel met %d rij" -msgstr[1] "wiskundetabel met %d rijen" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "Tabel met %d kolom" -msgstr[1] "Tabel met %d kolommen" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "geneste wiskundetabel met %d rij" -msgstr[1] "geneste wiskundetabel met %d rijen" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d bericht.\n" -msgstr[1] "%d berichten.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d procent." -msgstr[1] "%d procent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d procent van document gelezen" -msgstr[1] "%d procent van document gelezen" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d beeldpunt" -msgstr[1] "%d beeldpunten" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s teken" -msgstr[1] "%(count)d %(repeatChar)s tekens" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d van %(total)d item geselecteerd" -msgstr[1] "%(index)d van %(total)d items geselecteerd" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d Standaard schermlezer-snelkoppeling gevonden." -msgstr[1] "%d Standaard schermlezer-snelkoppelingen gevonden." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d Schermlezer-snelkoppeling voor %(application)s gevonden." -msgstr[1] "" -"%(count)d Schermlezer-snelkoppelingen voor %(application)s gevonden." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d spatie" -msgstr[1] "%d spaties" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tab" -msgstr[1] "%d tabs" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabel" -msgstr[1] "%d tabellen" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabel van onbekende grootte" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabel met %d kolom, aantal rijen onbekend" -msgstr[1] "tabel met %d kolommen, aantal rijen onbekend" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabel met %d rij, aantal kolommen onbekend" -msgstr[1] "tabel met %d rijen, aantal kolommen onbekend" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabel met %d rij" -msgstr[1] "tabel met %d rijen" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d seconde geleden" -msgstr[1] "%d seconden geleden" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minuut geleden" -msgstr[1] "%d minuten geleden" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d uur geleden" -msgstr[1] "%d uren geleden" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d dag geleden" -msgstr[1] "%d dagen geleden" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d niet-bezochte verwijzing" -msgstr[1] "%d niet-bezochte verwijzingen" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d bezochte verwijzing" -msgstr[1] "%d bezochte verwijzingen" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "omschakelen" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "op %(index)d van %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d van %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "item %(index)d" - -# wordt dit uitgesproken? -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVEAU %d" - -# vertakking/boomniveau/vertakkingsniveau -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "vertakking %d" - -# wordt dit uitgesproken? -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "VERTAKKING %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "details voor %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "heeft details in %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "suggestie" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "bewerkbaar keuzemenu" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "bewerkbare inhoud" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "feed" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figuur" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "abstract" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "dankwoord" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "nawoord" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "appendix" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "bibliografie-item" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografie" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "hoofdstuk" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "besluit" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "hoes" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "generiek" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "generieken" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "toewijding" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "eindnoot" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "eindnoten" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraaf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epiloog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "voorbeeld" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "voorwoord" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "woordenlijst" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "index" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "inleiding" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "pagina-einde" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "paginalijst" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "deel" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "voorwoord" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "proloog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "pullcitaat" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Vraag en antwoord" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "ondertitel" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "inhoudsopgave" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s niveau %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "horizontale scollbalk" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "verticale scrollbalk" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "horizontale schuif" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "verticale schuif" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "horizontale splitter" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "verticale splitter" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "wisselaar" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Pictogrammenpaneel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "banner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "aanvullende inhoud" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informatie" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "belangrijkste inhoud" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigatie" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "regio" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "zoeken" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "bezochte verwijzing" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "menuknop" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "oplopend gesorteerd" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "aflopend gesorteerd" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "gesorteerd" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klikbaar" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "ingevouwen" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "uitgevouwen" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "heeft lange beschrijving" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontaal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "verticaal" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "aangevinkt" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "niet aangevinkt" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "aan" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "uit" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "gedeeltelijk aangevinkt" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "ingedrukt" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "niet ingedrukt" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "niet geselecteerd" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "geselecteerd" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "niet geselecteerd" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "niet geselecteerd" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "bezocht" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "niet bezocht" - -# grijs (houdt het zo kort mogelijk, uitgegrijsd is te lang) -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "grijs" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "alleen-lezen" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "alleen-lezen" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "verplicht" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "multi-selecteren" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "ongeldige invoer" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "ongeldig" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ongeldige spelling" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "spelling" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "ongeldige grammatica" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "grammatica" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Zoeken" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Schermlezer zoekvenster" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Sluiten" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Zoeken" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Zoeken naar:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Zoeken naar:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Bovenkant van venster" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Bovenkant van venster" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Start bij:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Doorgaan na documenteinde" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "_Achteruit zoeken" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Zoekrichting:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Hoofdlettergevoelig" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "_Enkel complete woorden" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opties:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Standaard" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Hoofdletter" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Systeem" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Toepassing" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Venster" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu-voorkeuren" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Hulp" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Toepassen" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Toetsenbordindeling" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Actieve _profiel:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profiel bij opstarten:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Laden" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Opslaan _als" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "Ve_rwijderen" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profielen" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Zwevende aanwijzingen _tonen" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Object onder muisaanwijzer oplezen" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Muis" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Tijdsweergave:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Datumw_eergave:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Tijd en datum" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Updates uits_preken" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Braille-updates" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frequentie (seconden):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Van toepassing op:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Maak geluid bij _voortgang" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Voortgangsbalk-updates" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "_Terug- en vooruitspoelen aanzetten in Alles uitspreken" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "_Structurele navigatie aanzetten in Alles uitspreken" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Alles _uitspreken per:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "_Citaten aankondigen in Alles uitspreken" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Lij_sten aankondigen in Alles uitspreken" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "_Tabellen aankondigen in Alles uitspreken" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "_Panelen aankondigen in Alles uitspreken" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "_Formulieren aankondigen in Alles uitspreken" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "_Mijlpalen aankondigen in Alles uitspreken" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Alles uitspreken" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Element_presentatie:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Algemeen" - -# volume geluidssterkte -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Geluidsvolume:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Toonhoogte:" - -# snelhied/frequentie -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Snelheid:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persoon:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "Taa_l:" - -# stemsynthesizer -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Spraaks_ynthesizer:" - -# stemsysteem/stem -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Spraaksysteem:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Stemtype:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Hoofdletterstijl:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Stemtype-instellingen" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" -"_Woorden met meerdere hoofd- en kleine letters als onafhankelijke woorden " -"oplezen" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "_Nummers als getallen uitspreken" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Algemene steminstellingen" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Stem" - -# hier is 'aanzetten' beter vind ik (tino) -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Oplezen aanzetten" - -# uitvoerig/uitgebreid -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Uitvoerig" - -# uitvoerigheid/uitgebreidheid -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Uitvoerigheid" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Alles" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Leestekensniveau" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Alleen weergegeven tekst uitspreken" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Blanco regels oplezen" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "I_nspringruimte en uitlijnen oplezen" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Spreek objectafkortingen uit" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Sub-positie _oplezen" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Tutorial-berichten oplezen" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Systeemberichten zijn uitgebreid" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "_Kleuren als namen uitspreken" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "_Citaten aankondigen tijdens navigatie" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "_Lijsten aankondigen tijdens navigatie" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "_Tabellen aankondigen tijdens navigatie" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Indicator _onjuist gespeld woord uitspreken" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "_Panelen aankondigen tijdens navigatie" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "_Mijlpalen aankondigen tijdens navigatie" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "_Formulieren aankondigen tijdens navigatie" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Omschrijving ui_tspreken" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Volledige rij in sp_readsheets uitspreken" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Volledige rij in _documenttabellen uitspreken" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Volledige rij in _GUI-tabellen uitspreken" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Gesproken context" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Spraak" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "_Brailleondersteuning gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Afgekorte rolnamen" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "_Einderegel-symbool uitzetten" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Kortschrift_tabel:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Braille-kortschrift aanzetten" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Regela_fbreking aanzetten" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Instellingen weergeven" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Geen" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Selectie-indicator" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hyperlink-indicator" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Flits_berichten aanzetten" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Tijdsd_uur (sec):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Berichten _blijven staan" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Berichten zijn _uitgebreid" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Instellingen van flitsberichten" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "_Toetsuitspraak gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "_Alfabetische toetsen gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "_Numerieke toetsen gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "_Interpunctietoetsen gebruiken" - -# hier is 'aanzetten' beter vind ik (tino) -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "_Spatie aanzetten" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "_Controletoetsen gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "_Functietoetsen gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Actietoetsen _gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "_Navigatietoetsen gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Uitspraak per _woord gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Uitspraak per _zin gebruiken" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Toetsecho" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Schermlezer _modificatietoets(en):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Sneltoetsen" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Uitspraak-woordenboek" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nieuw item" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "Ver_wijderen" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Uitspraak" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Alles oplezen" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Niets oplezen" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Terugzetten" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Tekst-attributen" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Naar ben_eden verplaatsen" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Één naar _beneden" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Één naar bo_ven" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Naar b_oven verplaatsen" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Geselecteerd attribuut aanpassen" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Braille-indicator" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Tekst-attributen" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "AI-assistent inschakelen" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Provider:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokaal - Gratis)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API-_sleutelbestand:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Pad naar API-sleutelbestand" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "_Claude API-sleutel ophalen" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Browser openen om Claude API-sleutel op te halen en automatisch op te slaan" -"Browser openen om Claude API-sleutel op te halen en automatisch op te slaan" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Bevestiging vereisen voor AI-acties" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama-_model:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Modelnaam voor Ollama (bijv. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama-_eindpunt:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API-eindpunt-URL (bijv. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Screenshot-_kwaliteit:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Laag" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Gemiddeld" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Hoog" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI-assistent" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Taalcode:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Schaalfactor:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Grijswaardenafbeelding" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "Afbeelding _inverteren" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Zwart-witafbeelding" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Zwart/wit-_drempel:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "Kleuren _analyseren" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Resultaten naar _klembord kopiëren" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : anton, b : bernard, c : cornelis, d : dirk, e : eduard, f : ferdinand, " -"g : gerard, h : hendrik, i : izaak, j : johannes, k : karel, l : lodewijk, " -"m : maria, n : nico, o : otto, p : pieter, q : quirinus, r : rudolf, s : " -"simon, t : tinus, u : utrecht, v : victor, w : willem, x : xantippe, y : " -"ypsilon, z : zacharias" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "achtergrondkleur" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "achtergrondkleur volle hoogte" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "gestippelde achtergrond" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "richting" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "bewerkbaar" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "lettertypenaam" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "voorgrondkleur" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "gestippelde voorgrond" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "tekeneffect" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "inspringen" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "fout" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "onzichtbaar" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "uitlijning" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "taal" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "linker kantlijn" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "regelhoogte" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "paragraafstijl" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixels boven de regels" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixels onder de regels" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "beeldpunten tussen twee regels" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "rechter kantlijn" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "verhoog" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "schaal" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "grootte" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "uitrekking" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "doorstrepen" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stijl" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "tekstdecoratie" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "draairichting tekst" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "tekstschaduw" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "onderstreept" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "verticaal uitlijnen" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "gewicht" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "omloopmodus" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "schrijfrichting" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "waar" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "onwaar" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "geen" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "graveren" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "reliëf" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "omlijnen" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "bovenstreep" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "doorstreept" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "knipperend" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "zwart" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "enkel" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dubbel" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "laag" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "teken" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "woord" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "woordteken" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "links" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "rechts" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "midden" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "geen uitlijning" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "vullend" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra-condensed" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra-condensed" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensed" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi-condensed" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normaal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi-expanded" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expanded" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra-expanded" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra-expanded" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "kleine hoofdletter" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "schuin" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "cursief" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Standaard" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Tekstblok" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Koptekst" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "grondlijn" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "onderlijn" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "bovenlijn" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "bovenaan" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "tekst-boven" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "midden" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "onder" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "tekst-onder" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "overerving" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "vast" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "spelling" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Druk op spatie om te schakelen." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Druk op spatie om uit te breiden en gebruik pijl omhoog en omlaag om een " -"item te selecteren." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Druk Alt+F6 om focus te wisselen naar achterliggende vensters." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Om naar andere items te bewegen kunt u de pijltjestoetsen gebruiken of " -"vooruit zoeken selecteren." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Druk op Alt+F1 om naar het systeemmenu te gaan." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Gebruik de pijlen omhoog en omlaag om een item te selecteren." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Druk op Shift+Links om in te klappen." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Druk op Shift+Rechts om uit te vouwen." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Druk op enter om te activeren." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Voer tekst in." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Gebruik de pijlen links en rechts om andere tabs te bekijken." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Druk op spatie om te activeren." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Gebruik de pijlen omhoog en omlaag om een waarde te selecteren. Of toets de " -"gewenste numerieke waarde in." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Gebruik de pijltjestoetsen om te veranderen." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Druk op de pijlen links of rechts om te navigeren. Gebruik de pijlen omhoog " -"en omlaag om door de items de bladeren." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Druk op de rechter pijl om het submenu te openen." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Druk op de linker pijl om te verlagen en de rechter pijl om te verhogen. " -"Druk op Home om naar het minimum te gaan en op End om naar het maximum te " -"gaan." diff --git a/po/nn.po b/po/nn.po deleted file mode 100644 index 94a9ce5..0000000 --- a/po/nn.po +++ /dev/null @@ -1,9932 +0,0 @@ -# Norwegian translation of cthulhu. -# Copyright (C) 2003-2008 Free Software Foundation, Inc. -# Sigurd Gartmann , 2003-2006. -# Kjartan Maraas , 2003-2008. -# Sigurd Gartmann , 2007. -# Eskild Hustvedt , 2008 -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2008-04-02 14:20+0200\n" -"Last-Translator: Eskild Hustvedt \n" -"Language-Team: Norwegian Nynorsk \n" -"Language: nn\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu skjermlesar og forstørringsglas" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrm" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "pil" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "ram" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "akb" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "frgvlg" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "kolov" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "kbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ikn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "skive" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "map" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "teikn" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fil" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "fll" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "skr" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "skjema" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "glf" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "tptkst" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "bld" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etk" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lagf" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnke" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstop" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mny" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnyl" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnel" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "alter" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "sdt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "aflst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "prd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "oppspr" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "frdvs" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "knp" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnyopf" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "hvdf" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "radov" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "rull" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "rulf" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "del" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "sep" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "glid" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltf" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "snkn" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statl" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tamnyopf" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tks" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "bryter" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "verl" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "vtp" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "ukj" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vomr" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "vnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "top" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "bun" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "avsn" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "prg" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "redl" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "inp" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "mellomrom" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "ny linje" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "utropsteikn" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "sitatteikn" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nummer" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "prosent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "og" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "venstre parantes" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "høgre parantes" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "stjerne" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "pluss" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "komma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "bindestrek" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punktum" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "skråstrek" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "kolon" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semikolon" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "mindre" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "er lik" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "større" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "spørjeteikn" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "krøllalfa" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "venstre hakeparentes" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "omvendt skråstrek" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "høgre hakeparentes" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "sirkumfleks" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "understrek" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "venstre krøllparentes" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertikal linje" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "høgre krøllparentes" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "mellomrom" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pund" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "del" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "venstre hakeparentes" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logisk ikkje" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrert" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "grader" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "pluss eller minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superskript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -#, fuzzy -msgid "acute" -msgstr "a akutt" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "my" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "avsnittsmarkør" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "ring" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "høgre hakeparentes" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "ein fjerdedel" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "ein halv" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tre fjerdedeler" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a akutt" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVIS" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AKUTT" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "Å" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "Æ" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLE" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVIS" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AKUTT" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVIS" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AKUTT" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVIS" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AKUTT" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "gonger" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "Ø" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVIS" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AKUTT" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRKUMFLEKS" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AKUTT" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a gravis" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a cirkumfleks" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "å" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "æ" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedille" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e gravis" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e akutt" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e cirkumfleks" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i gravis" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i akutt" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i cirkumfleks" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o gravis" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o akutt" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o cirkumfleks" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "delt på" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "ø" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u akutt" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u gravis" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u cirkumfleks" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y akutt" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -#, fuzzy -msgid "florin" -msgstr "fll" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "bindestrek" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "høgre shift" - -#: src/cthulhu/chnames.py:593 -#, fuzzy -msgid "single low quote" -msgstr "høgre shift" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -#, fuzzy -msgid "dagger" -msgstr "dolk" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "kulepunkt" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "(trippelklikk)" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "avkrysningsmerke" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -#, fuzzy -msgid "superscript 0" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:676 -#, fuzzy -msgid "superscript 4" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:680 -#, fuzzy -msgid "superscript 5" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:684 -#, fuzzy -msgid "superscript 6" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:688 -#, fuzzy -msgid "superscript 7" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:692 -#, fuzzy -msgid "superscript 8" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:696 -#, fuzzy -msgid "superscript 9" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:700 -#, fuzzy -msgid "superscript plus" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:704 -#, fuzzy -msgid "superscript minus" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:708 -#, fuzzy -msgid "superscript equals" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:720 -#, fuzzy -msgid "superscript n" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:724 -#, fuzzy -msgid "subscript 0" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:728 -#, fuzzy -msgid "subscript 1" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:732 -#, fuzzy -msgid "subscript 2" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:736 -#, fuzzy -msgid "subscript 3" -msgstr "superskript 3" - -#: src/cthulhu/chnames.py:740 -#, fuzzy -msgid "subscript 4" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:744 -#, fuzzy -msgid "subscript 5" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:748 -#, fuzzy -msgid "subscript 6" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:752 -#, fuzzy -msgid "subscript 7" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:756 -#, fuzzy -msgid "subscript 8" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:760 -#, fuzzy -msgid "subscript 9" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:764 -#, fuzzy -msgid "subscript plus" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:772 -#, fuzzy -msgid "subscript equals" -msgstr "superskript 2" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "venstre parantes" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "høgre parantes" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "svart diamant" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "Flytter til neste teikn." - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "Utfører venstreklikk på gjeldende oppføring i flat vising." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "Utfører høgreklikk på gjeldene oppføring i flat vising." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Lesar opp heile dokumentet." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "Lesar opp den gjeldende linja i flat vising." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "Køyrer grunnleggjande versjon av «hvor er jeg»-operasjonen." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "Køyrer detaljert versjon av «hvor er jeg»-operasjonen." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Lesar opp den gjeldende linja i flat vising." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "Tal tomme linjer" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "Uttaler teksten i statuslinja." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "Uttaler teksten i tittelfeltet." - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Opnar dialog for søk i Cthulhu." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "Søkjer etter neste instans av ein streng." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "Søkjer etter førre instans av ein streng." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "Går inn i og ut av flat visingsmodus." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "Flytter flat vising til endposisjonen." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "Flytter flat vising til hjemposisjonen." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "Flytter flat vising til endposisjonen." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "Flytter flat vising til byrjinga av førre linje." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "Lesar opp den gjeldende linja i flat vising." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "Lesar opp den gjeldende linja i flat vising." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "Stavar fonetisk Lesar opp aktiv linje i flat vising." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "Flytter flat vising til byrjinga av neste linje." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "Flytter flat vising til førre oppføring eller ord." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "" -"Lesar opp eller stavar den gjeldende oppføringa eller det gjeldende ordet i " -"flat vising." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "" -"Lesar opp eller stavar den gjeldende oppføringa eller det gjeldende ordet i " -"flat vising." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Lesar opp eller stavar den gjeldende oppføringa eller det gjeldende ordet i " -"flat vising." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "Flytter flat vising til den neste oppføringa eller det neste ordet." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "Flytter flat vising til ordet over gjeldende ord." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "Lesar opp det gjeldende flatvisingsobjektet." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "Flytter flat vising til ordet under det gjeldende ordet." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "Flytter flat vising til førre teikn." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "Lesar opp det gjeldende teikna frå flat vising." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "Lesar opp det gjeldende teikna frå flat vising." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "Lesar opp det gjeldende teikna frå flat vising." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "Flytter flat vising til neste teikn." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "Flytter flat vising til enden av linja." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "Flytter flat vising nedst til venstre." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "" -"Lesar opp eller stavar den gjeldende oppføringa eller det gjeldende ordet i " -"flat vising." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "" -"Lesar opp eller stavar den gjeldende oppføringa eller det gjeldende ordet i " -"flat vising." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "Flytter flat vising til endposisjonen." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Les berre gjeldende tabellcelle eller heile raden." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "Lesar attributtane tilordnet det gjeldende tekstlige teikna." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "Forskyver braillevisinga til venstre." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "Forskyver braillevisinga til høgre." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "Returnerer til objektet med tastaturfokus." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "Flytter flat vising til byrjinga av neste linje." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Går inn i læringsmodus. Trykk escape for å gå ut av det att." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "Begrenser lesehastigheten." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "Aukar lesehastigheten." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "Begrenser stemmens tonestorleik." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "Aukar stemmens tonestorleik." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Aukar lesehastigheten." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Begrenser lesehastigheten." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Vel den foretrukkede opplesningstenaren." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Vel den foretrukkede opplesningstenaren." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "Begrenser lesehastigheten." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "Aukar lesehastigheten." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "Slår av og på lyd for opplesning." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "Slår av/på forbedringar for mus." - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "Viser innstillingsvindauget." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "Viser programmet sitt innstillingsvindauge." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "Les opp tekst_indentering og tekstjustering" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "Byter til neste posisjon for forstørringsglaset." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "Byter til neste posisjon for forstørringsglaset." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "Byter til neste posisjon for forstørringsglaset." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "Byter til neste posisjon for forstørringsglaset." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "Byter til neste posisjon for forstørringsglaset." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "Gå til førre bokmerkelokasjon." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "Gå til bokmerke." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "Gå til neste bokmerkelokasjon." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "Legg til bokmerke." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "Lagra bokmerke." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "Slår av/på forbedringar for mus." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "Les opp og braille ein tidlegare samtaleromsmelding." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Om namnet på samtalerom skal leggjes til byrjinga av kvar meldingstekst." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Om namnet på samtalerom skal leggjes til byrjinga av kvar meldingstekst." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linje venstre" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linje høgre" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linje opp" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linje ned" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Øverst til venstre" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "Nedste halvdel" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Markørposisjon" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "Markørposisjon" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "Linje" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Flytter til neste teikn." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "Flytter til førre teikn." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "Flytter til neste ord." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "Flytter til førre ord." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "Flytter til neste linje." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "Flytter til førre linje." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "Går til starten av fila." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "Går til slutten av fila." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Flytter flat vising til byrjinga av neste linje." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "Går til starten av fila." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "Går til neste objekt." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "Går til førre objekt." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "Det finst ikkje fleire levende regioner." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "" -"Set rad som skal brukast som dynamiske kolonneoverskrifter når innhald i " -"reknearkceller uttales." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "Dynamisk kolonneoverskrift tømt." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"Set kolonnen som brukast som dynamiske radtopptekstar når innhald i " -"reknearkceller uttales." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "Dynamisk kolonneoverskrift tømt." - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Lesar opp innhaldet av innskrivingsfeltet." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "Strukturelle navigasjonstastar er slått på." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "Går til førre blokksitat." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "Går til neste blokksitat." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "Flytter til førre ord." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "Flytter til neste ord." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Vis fleire alternativ" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Flytter til førre teikn." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Flytter til neste teikn." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "Går til førre tabell." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "Går til neste tabell." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "Flytter til førre ord." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Går til neste felt i skjema." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l-felt" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l-felt" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "Flytter til førre ord." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "Flytter til neste ord." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "Går til førre felt i skjema." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "Går til neste felt i skjema." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "Går til førre overskrift." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "Går til neste overskrift." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Går til førre overskrift på nivå 1." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Går til neste overskrift på nivå 1." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Inga fleire overskrifter på nivå %d." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "Går til førre tabell." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "intern ramme" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "Flytter til førre linje." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "Flytter til neste linje." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "Går til førre landemerke." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "Går til neste landemerke." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Går til førre store objekt." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Går til neste store objekt." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Inga fleire store objekt." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "Flytter til førre linje." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "Flytter til neste linje." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Vis fleire alternativ" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "Går til førre liste." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "Går til førre liste." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Går til førre listeoppføring." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Går til neste lenkjeoppføring." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "Går til førre levende region." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "Går til neste levende region." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "Returnerer til objektet med tastaturfokus." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "Returnerer til objektet med tastaturfokus." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "Flytter til førre teikn." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "Flytter til neste teikn." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Går til førre overskrift." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "radioknapp" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "Flytter til førre teikn." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "Flytter til neste teikn." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "Går til førre tabell." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "Går til neste tabell." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "Går ned ei celle." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "Går til den første cella i ein tabell." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "Går til den siste cella i ein tabell." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "Går ei celle til venstre." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "Går ei celle til høgre." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "Går ei celle opp." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "Slår av/på forbedringar for mus." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Slå på taste_ekko" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "Går til førre ubesøkte lenkja." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "Går til neste ubesøkte lenkja." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "Det finst inga fleire ubesøkte lenkjer." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "Går til førre besøkte lenkja." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "Går til neste besøkte lenkja." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "Det finst inga fleire besøkte lenkjer." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "tretabell" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "svart diamant" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "tretabell" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "tretabell" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "a gravis" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "tretabell" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i gravis" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "grået ut" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "grader" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "høgre krøllparentes" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "høgre kontroll" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "høgre parantes" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "høgre krøllparentes" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "høgre parantes" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "høgre parantes" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "høgre alt" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "høgre parantes" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "ny linje" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Bilete" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "tretabell" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "tre" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "tretabell" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s-skjerm" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "tretabell" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "tretabell" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "tab" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "mellomrom" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "mellomrom" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "Full skjerm" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikon" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Inga" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "Stavekontroll:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Les meldingar frå" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Alle ka_naler" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -#, fuzzy -msgid "_Speak Chat Room name" -msgstr "Les opp samtaleromnamn." - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -#, fuzzy -msgid "double click" -msgstr "(dobbeltklikk)" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -#, fuzzy -msgid "triple click" -msgstr "(trippelklikk)" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Forvald synthesizer" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Faktisk streng" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Erstatningsstreng" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "Slå på _ordekko" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "Slå på _navigasjonstastar" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "N_overande stad" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minste lengde på tekst med treff:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Alternativ for søk" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "komma" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Tastaturbinding" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "Forval" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Går ut av læringsmodus." - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "del" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braille-bindingar" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "bokmerke lagra" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "Tabellnavigasjon" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "Endra" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Skrivebord" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "caption" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Innstillingar for Cthulhu for %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marker i blindeskrift" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Tilstades med mindre" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Snakk" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "_Alle" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "Program" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "Vindauge" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "I_ngen" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Nokon" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "M_est" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Linje" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Setning" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "sitatteikn" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Knapp" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "Caption" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Avkrysningsboks" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "kombinasjonsboks" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "caption" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Topptekst" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Intern ramme" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Bilete" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Etikett" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -#, fuzzy -msgctxt "structural navigation" -msgid "Level" -msgstr "nivå %d" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "Lenkja" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "Listeoppføring" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Avsnitt" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radioknapp" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "vald" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "Status" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Tekst" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Det finst ikkje fleire blokksitater." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Knapp" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Avkrysningsboks" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "kombinasjonsboks" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "Topptekst" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Intern ramme" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Bilete" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Inga fleire overskrifter på nivå %d." - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Inga fleire store objekt." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "Lenkja" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "Listeoppføring" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Avsnitt" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radioknapp" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabell" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d lenkja som ikkje er besøkt" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d besøkt lenkje" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Sidenavigering" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s forvald stemme" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "Forval" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlenkja" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Store bokstavar" - -#: src/cthulhu/guilabels.py:852 -#, fuzzy -msgid "Speech Dispatcher" -msgstr "Opplesning slått av." - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Stavekontroll:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "Tal _cellekoordinater" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Tabellnavigasjon" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Hopp over tomme ce_ller" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "Uttal celle" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Tal _cellekoordinater" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Namn på attributt" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "Sidenavigering" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "Slå på _navigasjonstastar" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Kort" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt_R" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "venstre kontroll" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "venstre shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "venstre alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "venstre kontroll" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "høgre shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "høgre alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "høgre kontroll" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "venstre meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "høgre meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "venstre tab" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "mellomrom" - -#: src/cthulhu/keynames.py:157 -#, fuzzy -msgid "return" -msgstr "større" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "Sentrert" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "page down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "venstre alt" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "høgre alt" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "venstre parantes" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "høgre parantes" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "meny" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -#, fuzzy -msgid "delete" -msgstr "_Slett" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "og" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -#, fuzzy -msgid "circumflex" -msgstr "a cirkumfleks" - -#: src/cthulhu/keynames.py:291 -#, fuzzy -msgid "ring" -msgstr "å" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "ø" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "uthevet" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "superskript 2" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Skrivebord " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr " Samanhengen er %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "venstre parantes" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "pil" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "høgre parantes" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "pil" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "pil som peikar til høgre" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "venstre hakeparentes" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "høgre hakeparentes" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "høgre hakeparentes" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "pil som peikar til høgre" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "pil som peikar til høgre" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "mindre" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "større" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "a cirkumfleks" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "punktum" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horisontal" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "autofullføring" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "tom" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "Slutten av rad." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "pluss eller minus" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "pluss" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "separator" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "Proporsjonal" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "uendeleg" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "høgre alt" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "lagfelt" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "delt på" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Separator" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "logisk ikkje" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "logisk ikkje" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "del" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "intern ramme" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "Oppdateringsintervall:" - -#: src/cthulhu/mathsymbols.py:1512 -#, fuzzy -msgctxt "math symbol" -msgid "triple integral" -msgstr "Oppdateringsintervall:" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -#, fuzzy -msgctxt "math symbol" -msgid "surface integral" -msgstr "Oppdateringsintervall:" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "Proporsjonal" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "a tilde" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "anna nettsted" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "er lik" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "er lik" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "er lik" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "vertikal" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "ikkje lik" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "større" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "ikkje trykket" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ikkje vald" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "superskript 2" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "fleirval" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "fleirval" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "er lik" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "bindestrek" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "pluss eller minus" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "høgre meta" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "venstre tab" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "del" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "ikkje trykket" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ring" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "bilete" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "intern ramme" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "høgre shift" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "høgre krøllparentes" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "separator" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "logisk ikkje" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "logisk ikkje" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "(dobbeltklikk)" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "mindre enn eller lik" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "større enn eller lik" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertikal" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "venstre parantes" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "høgre parantes" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "venstre alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "høgre alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "venstre krøllparentes" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "venstre krøllparentes" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "venstre hakeparentes" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "høgre hakeparentes" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "kvadratrota" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "svart sirkel" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "kvit firkant" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "svart diamant" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "kvit sirkel" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "svart sirkel" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "kvitt kulepunkt" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "understrek" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "program" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "blank" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "uthevet" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "bokmerke skrivne inn" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "bokmerke lagra" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "bokmerket kunne ikkje verta lagra" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "Inga landemerker funne." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "Inga landemerker funne." - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "Opplesning slått på." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ikon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "Gecko styrer markøren." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu styrer markøren." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Celle %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "vald" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%d av %d oppføring vald" - -#: src/cthulhu/messages.py:193 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%d av %d oppføring vald" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "ikke vald" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "bokmerket kunne ikkje verta lagra" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "Vis denne hjelpeteksten" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Set innstillingar (tekstversjon)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "Set innstillingar (tekstversjon)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Rapportar feil til https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "a akutt" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "raskere." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Melding frå samtalerom %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Ny pratefane %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Ikkje les opp samtaleromnamn." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "Les opp samtaleromnamn." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "del" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "spørjeteikn" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "h t m l-felt" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "Ikkje i ein tabell." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "ikkje vald" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Forvald knapp er %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Forvald knapp er %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "Forvald knapp er %s" - -#: src/cthulhu/messages.py:518 -#, fuzzy, python-format -msgid " subscript %s" -msgstr "superskript 2" - -#: src/cthulhu/messages.py:524 -#, fuzzy, python-format -msgid " superscript %s" -msgstr "superskript 2" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "Ikkje i ein tabell." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "heile dokumentet vald" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "heile dokumentet vald" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokument vald frå markørposisjon" - -#: src/cthulhu/messages.py:554 -#, fuzzy -msgid "document unselected from cursor position" -msgstr "dokument vald frå markørposisjon" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokument vald til markørposisjon" - -#: src/cthulhu/messages.py:566 -#, fuzzy -msgid "document unselected to cursor position" -msgstr "dokument vald til markørposisjon" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynamisk kolonneoverskrift sett for rad %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynamisk kolonneoverskrift tømt." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynamisk radoverskrift sett for kolonne %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynamisk radoverskrift tømt." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "tom" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Inga filer funne." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "Går inn i og ut av flat visingsmodus." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "Flytter flat vising til ordet over gjeldende ord." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "har formel" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "dialog" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "oppsprettmeny" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, fuzzy, python-format -msgid "The key entered is already bound to %s" -msgstr "Tasten som vart oppgjeven er den same. Inga endring." - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tast fanga: %s. Trykk enter for å stadfesta." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Den nye tasten er: %s" - -#: src/cthulhu/messages.py:711 -#, fuzzy -msgid "Key binding deleted. Press enter to confirm." -msgstr "Tast fanga: %s. Trykk enter for å stadfesta." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Tastaturbindinga vart fjerna." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "oppgje ny tast" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "Inga" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "Flytter til neste ord." - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "Setning" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "Passord" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "Flytter til neste ord." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "svart sirkel" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "horisontal" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "vertikal linje" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Går rundt til botnen." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "og" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "kvadratrota" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "kvadratrota" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "hovudfelt" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "hovudfelt" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "hovudfelt" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "superskript 2" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "superskript 2" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "superskript 2" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "superskript 2" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "superskript 2" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "superskript 2" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "tabell" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "tretabell" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "utilgjengeleg" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Tabell" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "Les opp tekst_indentering og tekstjustering" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Slå på _kant" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "Les opp tekst_indentering og tekstjustering" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Læringsmodus. Trykk escape for å gå ut av det." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "animasjon" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Sidenavigering" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Tabellnavigasjon" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "forlater tabell." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "linje vald ned frå markørposisjon" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "linje vald opp frå markørposisjon" - -#: src/cthulhu/messages.py:1484 -#, fuzzy -msgid "line unselected down from cursor position" -msgstr "linje vald ned frå markørposisjon" - -#: src/cthulhu/messages.py:1491 -#, fuzzy -msgid "line unselected up from cursor position" -msgstr "linje vald opp frå markørposisjon" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Går ut av læringsmodus." - -#: src/cthulhu/messages.py:1505 -#, fuzzy -msgid "line selected from start to previous cursor position" -msgstr "linje vald opp frå markørposisjon" - -#: src/cthulhu/messages.py:1511 -#, fuzzy -msgid "line selected to end from previous cursor position" -msgstr "linje vald ned frå markørposisjon" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "lenkja" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "same side" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "same nettsted" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "anna nettsted" - -#: src/cthulhu/messages.py:1531 -#, fuzzy, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%s lenkjer til %s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s-lenke" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d besøkt lenkje" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "høflighetsnivå %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Støtte for levende regioner er slått av" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "Inga filer funne." - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "N_overande stad" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "av" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "på" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "Feilstavet ord:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Feilstavet ord: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr " Samanhengen er %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Går til neste objekt." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Slår av/på forbedringar for mus." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Forstørrelsesglass aktivert" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d prosent." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "Flytter til førre ord." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nøstenivå %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Inga program har fokus." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Inga fokus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Inga program har fokus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Det finst ikkje fleire blokksitater." - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "Det finst inga fleire lister." - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "Det finst ikkje fleire blokksitater." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Inga fleire store objekt." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Inga fleire tabellar." - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "Det finst ikkje fleire blokksitater." - -#: src/cthulhu/messages.py:1903 -#, fuzzy -msgid "No more entries." -msgstr "Inga fleire tabellar." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Det finst ikkje fleire felt i skjema." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Inga fleire topptekstar." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Inga fleire overskrifter på nivå %d." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "intern ramme" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "Inga fleire tabellar." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Inga landemerker funne." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "Det finst inga fleire lister." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Det finst inga fleire lister." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Det finst inga fleire oppføringar i listen." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Det finst ikkje fleire levende regioner." - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "Inga fleire topptekstar." - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "Inga fleire topptekstar." - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "Det finst inga fleire lister." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Inga fleire tabellar." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Det finst inga fleire ubesøkte lenkjer." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Det finst inga fleire besøkte lenkjer." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "ikkje vald" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "Ikkje i ein tabell." - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "caption" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "_Botn:" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "_Topp:" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "Passord" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "Les meldingar frå" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "av" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "på" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Lastar. Vent." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Fullført lasting." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Fullført lasting av %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "side vald frå markørposisjon" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "side vald til markørposisjon" - -#: src/cthulhu/messages.py:2089 -#, fuzzy -msgid "page unselected from cursor position" -msgstr "side vald frå markørposisjon" - -#: src/cthulhu/messages.py:2095 -#, fuzzy -msgid "page unselected to cursor position" -msgstr "side vald til markørposisjon" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "side vald frå markørposisjon" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "side vald frå markørposisjon" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "side vald frå markørposisjon" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "side vald frå markørposisjon" - -#: src/cthulhu/messages.py:2127 -#, fuzzy -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Du har allereie eit innstillingsvindauge for Cthulhu ope.\n" -"\n" -"Lukk dette før du opnar eit nytt." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "Inga filer funne." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Fremdriftsviser %d." - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "_Alle" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "Teiknsettingsnivå" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "Inga" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Søkjer." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Søk fullført." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Cthulhus brukarinnstillingar vart lasta på nytt." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr " Samanhengen er %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Vel ynskja stemme:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "ikke vald" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Opplesning slått av." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Opplesning slått på." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "raskere." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "saktere." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "høgare." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "lågare." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "raskere." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Rate:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Vo_lum:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Opplesning slått av." - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Opplesning slått av." - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Inga tenarar er tilgjengelege.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Inga stemmer er tilgjengelege.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Opplesning slått på." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "Opplesning vil ikkje verta brukt.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " prikk prikk prikk" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Innstillingar for Cthulhu" - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu styrer markøren." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Opplesning er utilgjengeleg." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Inga filer funne." - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "streng ikkje funne" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "streng ikkje funne" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Strukturelle navigasjonstastar er slått av." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Strukturelle navigasjonstastar er slått på." - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "Inga filer funne." - -#: src/cthulhu/messages.py:2380 -#, fuzzy, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Rad %d, kolonne %d" - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "%d tabell" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Uttal celle" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Snakk" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Ikkje-uniform" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Ikkje i ein tabell." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "Kolonneoverkskrift" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "kolonne %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Botnen på kolonnen." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Toppen på kolonnen." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "ikke vald" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "ikke vald" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "rad %d" - -#: src/cthulhu/messages.py:2462 -#, fuzzy, python-format -msgid "row %(index)d of %(total)d" -msgstr "rad %d av %d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Byrjalse av rad." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Slutten av rad." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "Flytter flat vising til enden av linja." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "ikkje vald" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "ikke vald" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "vald" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "ikke vald" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Innstillingar for Cthulhu for %s" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "mellomrom" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Går rundt til botnen." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Går rundt til toppen." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 oppføringar" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, fuzzy, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Cella går over %d rader" -msgstr[1] "Cella går over %d rader" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d kolonne" -msgstr[1] "%d kolonnar" - -#: src/cthulhu/messages.py:2593 -#, fuzzy, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Cella går over %d kolonnar" -msgstr[1] "Cella går over %d kolonnar" - -#: src/cthulhu/messages.py:2610 -#, fuzzy, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] " %d %s teikn" -msgstr[1] " %d %s teikn" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "dialog" -msgstr[1] "dialog" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fil funne" -msgstr[1] "%d filer funne" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d skjema" -msgstr[1] "%d skjema" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d overskrift" -msgstr[1] "%d overskrifter" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d oppføring" -msgstr[1] "%d oppføringar" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Inga landemerker funne." -msgstr[1] "Inga landemerker funne." - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d fil funne" -msgstr[1] "%d filer funne" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Det finst ikkje fleire blokksitater." -msgstr[1] "Det finst ikkje fleire blokksitater." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "forlater tabell." -msgstr[1] "forlater tabell." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Liste med %d oppføring" -msgstr[1] "Liste med %d oppføringar" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Liste med %d oppføring" -msgstr[1] "Liste med %d oppføringar" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "Tabell med %d rad" -msgstr[1] "Tabell med %d rader" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d kolonne" -msgstr[1] "%d kolonnar" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "Tabell med %d rad" -msgstr[1] "Tabell med %d rader" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d prosent." -msgstr[1] "%d prosent." - -#: src/cthulhu/messages.py:2764 -#, fuzzy, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d prosent av dokumentet er lest" -msgstr[1] "%d prosent av dokumentet er lest" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%s %s piksel" -msgstr[1] "%s %s pikslar" - -#: src/cthulhu/messages.py:2777 -#, fuzzy, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] " %d %s teikn" -msgstr[1] " %d %s teikn" - -#: src/cthulhu/messages.py:2784 -#, fuzzy, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%d av %d oppføring vald" -msgstr[1] "%d av %d oppføringar vald" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d mellomrom" -msgstr[1] "%d mellomrom" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulator" -msgstr[1] "%d tabulatorar" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabell" -msgstr[1] "%d tabellar" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabell med %d rader og %d kolonnar." -msgstr[1] "tabell med %d rader og %d kolonnar." - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabell med %d rader og %d kolonnar." -msgstr[1] "tabell med %d rader og %d kolonnar." - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "Tabell med %d rad" -msgstr[1] "Tabell med %d rader" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "sekund" -msgstr[1] "sekund" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d lenkja som ikkje er besøkt" -msgstr[1] "%d lenkjer som ikkje er besøkt" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d besøkt lenkje" -msgstr[1] "%d besøkte lenkjer" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "bryter" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVÅ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "trenivå %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TRENIVÅ %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "spørjeteikn" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "kombinasjonsboks" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html-innhald" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "kolon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "del" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "avsnitt" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "Uttale" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "arkfaneliste" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "sitatteikn" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "html-innhald" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "horisontal" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "vertikal linje" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "horisontal" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "vertikal linje" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "horisontal" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "vertikal linje" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Ikonpanel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "html-innhald" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Animasjon" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "html-innhald" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Animasjon" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "Søkjer." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d besøkt lenkje" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "snurreknapp" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "samanslått" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "utvida" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horisontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikal" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "merket av" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "ikkje merket av" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "på" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "av" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "delvis merket av" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "trykket" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ikkje trykket" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "ikkje vald" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "vald" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ikke vald" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "ikkje vald" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d besøkt lenkje" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d lenkja som ikkje er besøkt" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "grået ut" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "fleirval" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "ugyldig" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "ugyldig" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "ugyldig" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "Stavekontroll" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "ugyldig" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Finn" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "Cthulhu skjermlesar og -forstørrar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "Lukk" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "Finn" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Søk etter:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Søk etter:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Toppen av vindauget" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Toppen av vindauget" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Start frå:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Bryt" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Søk _bakover" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "Søk etter:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Treff på små/store bokstavar" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Treff berre på h_ele ord" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Alternativ for søk" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Forval" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Store bokstavar" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlenkja" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Program" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Vindauge" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Innstillingar for Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Bærbar" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "Tastaturutforming" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "Start frå:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Vis verktøytips" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "Snakk" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Braille-bindingar" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Program" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "Les opp _oppdateringar for fremdriftsviser" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "Strukturelle navigasjonstastar er slått på." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Generelt" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lum:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Tone_storleik" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Rate:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Person:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Opplesningssynthesi_zer:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Opplesnings_system:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "_Stemmeinnstillingar:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "_Stemmeinnstillingar:" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "_Stemmeinnstillingar:" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Slå på opplesning" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Ekstra informasjon" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "Detaljgrad" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Alle" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "Teiknsettingsnivå" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Tal tomme linjer" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Les opp tekst_indentering og tekstjustering" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -#, fuzzy -msgid "Speak tutorial messages" -msgstr "Les meldingar frå" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "Tal _cellekoordinater" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "Tal _cellekoordinater" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "Ikkje s_nakk" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Tale" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Slå på braille_støtte" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Forkortedde rollenamn" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Slå på _kant" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "Vis fleire alternativ" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "I_ngen" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "Indikator for utval" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "Hyperlenkja" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "Slå på _forstørring" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Slå på taste_ekko" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Slå på _navigasjonstastar" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "Slå på _modifiseringstastar" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Slå på _funksjonstastar" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "_Slå på opplesning" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Slå på _modifiseringstastar" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Slå på _funksjonstastar" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Slå på _aksjonstastar" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Slå på _navigasjonstastar" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Slå på _ordekko" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "Slå på _ordekko" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Tasteekko" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Cthulhu e_ndringstast(er):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Tastaturbindingar" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "Ordbok for uttale" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Ny oppføring" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Slett" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Uttale" - -#: src/cthulhu/cthulhu-setup.ui:3243 -#, fuzzy -msgid "_Speak all" -msgstr "Snakk" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Ikkje s_nakk" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Nullstill" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "Tekstattributter" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Flytt til _botn" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Flytt ein ne_d" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Flytt ein _opp" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Flytt til _toppen" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "" -"Juster valde\n" -"attributtar" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "Indikator for blindeskrift" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Tekstattributter" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "Assistent" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "Assistent" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "Skalerings_faktor:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "del" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "tabell" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -#, fuzzy -msgctxt "textattr" -msgid "foreground color" -msgstr "Kantfarge:" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -#, fuzzy -msgctxt "textattr" -msgid "invisible" -msgstr "utilgjengeleg" - -#: src/cthulhu/text_attribute_names.py:156 -#, fuzzy -msgctxt "textattr" -msgid "justification" -msgstr "del" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "venstre parantes" - -#: src/cthulhu/text_attribute_names.py:176 -#, fuzzy -msgctxt "textattr" -msgid "line height" -msgstr "Linje høgre" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "avsnitt" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -#, fuzzy -msgctxt "textattr" -msgid "pixels below lines" -msgstr "Tal tomme linjer" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "høgre parantes" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "kalh" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -#, fuzzy -msgctxt "textattr" -msgid "text rotation" -msgstr "N_overande stad" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "understrek" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "vertikal linje" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "Linje høgre" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -#, fuzzy -msgctxt "textattr" -msgid "writing mode" -msgstr "Går ut av læringsmodus." - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -#, fuzzy -msgctxt "textattr" -msgid "engrave" -msgstr "e gravis" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -#, fuzzy -msgctxt "textattr" -msgid "outline" -msgstr "understrek" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "understrek" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "lenkja" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -#, fuzzy -msgctxt "textattr" -msgid "double" -msgstr "(dobbeltklikk)" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "lågare." - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "Passord" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "fll" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "trtbl" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "venstre alt" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "høgre alt" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "cent" - -#: src/cthulhu/text_attribute_names.py:493 -#, fuzzy -msgctxt "textattr" -msgid "no justification" -msgstr "Les opp tekst_indentering og tekstjustering" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "fyll" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -#, fuzzy -msgctxt "textattr" -msgid "condensed" -msgstr "sekund" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "sekund" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "utvida" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "utvida" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "utvida" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "utvida" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "Forval" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "Tekst" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "Topptekst" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "ny linje" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -#, fuzzy -msgctxt "textattr" -msgid "super" -msgstr "Super" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "Stopp" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "tekst" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "_Botn:" - -#: src/cthulhu/text_attribute_names.py:662 -#, fuzzy -msgctxt "textattr" -msgid "text-bottom" -msgstr "Flytt til _botn" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -#, fuzzy -msgctxt "textattr" -msgid "lr" -msgstr "fll" - -#: src/cthulhu/text_attribute_names.py:726 -#, fuzzy -msgctxt "textattr" -msgid "rl" -msgstr "Ctrl" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "tab" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "Stavekontroll" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/oc.po b/po/oc.po deleted file mode 100644 index 1b76830..0000000 --- a/po/oc.po +++ /dev/null @@ -1,9312 +0,0 @@ -# Translation of oc.po to Occitan -# Occitan translation of cthulhu. -# Copyright (C) 2004-2007 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# Yannig Marchegay (Kokoyaya) , 2006-2008 -# Cédric Valmary (Tot en òc) , 2015. -# Cédric VALMARY , 2016. -# Cédric Valmary (totenoc.eu) , 2016. -msgid "" -msgstr "" -"Project-Id-Version: oc\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2021-05-11 20:57+0200\n" -"Last-Translator: Quentin PAGÈS\n" -"Language-Team: Tot en òc (totenoc.eu)\n" -"Language: oc\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 2.4.3\n" -"X-Launchpad-Export-Date: 2015-05-21 18:05+0000\n" -"X-Project-Style: gnome\n" - -msgid "Cthulhu Screen Reader" -msgstr "Lector d'ecran Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" -"lector d'ecran;oral;braille;votz;sintèsi vocala;sintesi vocala;lector " -"ecran;tts;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "flch" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "etiq" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "marc" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "selcol" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "tèstacol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icòn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "quadr" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "dess" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "selfi" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "empl" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "pol" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "panver" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "tèsta" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "quadrint" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etiq" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "pnljaces" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "ligam" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "elemlst" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "barmnu" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "elemmnu" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "pnlopt" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgn" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "lstong" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnuctxt" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "barprog" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "bot" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "botrad" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "elemrad" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "pnlrac" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "tèstalin" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "bardesf" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "pnldesf" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sccn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprdr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "liss" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "pnlpar" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "botregl" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "barestat" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "mnudet" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "botbsc" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "barespl" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "astúcia" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arbr" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tabarb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "desc" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "fen" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "fen" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "tèsta" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pè" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apl" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "baredc" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "compin" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Chèc gras 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Espanhòl gras 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francés canadian gras 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francés gras 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Lituanian gras 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Neerlandés gras 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvegian gras 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvegian gras 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvegian gras 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvegian gras 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polonés gras 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugués gras 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Suedés gras 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabi gras 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galés gras 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galés gras 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemand gras 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemand gras 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemand gras 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Anglés britanic gras 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Anglés britanic gras 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Anglés american gras 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Anglés american gras 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francés canadian gras 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francés gras 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grèc gras 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Indi gras 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Ordenador ongrés de 8 punts" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Ongrés gras 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Ongrés gras 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italian gras 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Neerlandés bèlga gras 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espaci" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "linha novèla" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "punt d'exclamacion" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "vergueta" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nombre" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "per cent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "e" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostròf" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "parentèsi dobrissenta" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "parentèsi tampanta" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "estèla" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "mai" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "virgula" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "jonhent" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punt" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra oblica" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dos punts" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punt virgula" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "inferior a" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "egal a" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "superior a" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "question" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "arròba" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "croquet dobrissent" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "barra oblica invèrsa" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "croquet tampant" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "circonflèxee" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "soslinhament" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grèu" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "acolada dobrissenta" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra verticala" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "acolada tampanta" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espaci insecable" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "punt d'exclamacion inversat" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cents" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "liura" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "signe monetari" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra verticala discontinua" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "seccion" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "trèma" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "ordinal femenin" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "vergueta francesa dobrissenta" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "negacion logica" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "jonhent condicional" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "marca depausada" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "grases" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "mai o mens" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "carrat" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "cub" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "accent agut" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "pè de mosca" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "punt median" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilha" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "exponent 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "vergueta francesa tampanta" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "un quart" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "una mitat" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tres quarts" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "punt d'interrogacion inversat" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a agut" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRÈU" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AGUT" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCONFLÈXE" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDA" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A TRÈMA" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A ENCERCLAT" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILHA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRÈU" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AGUT" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCONFLÈXE" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E TRÈMA" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRÈU" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AGUT" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCONFLÈXE" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I TRÈMA" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDA" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRÈU" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AGUT" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCONFLÈXE" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDA" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O TRÈMA" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "còps" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O RAIAT" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRÈU" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AGUT" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCONFLÈXE" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U TRÈMA" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AGUT" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "eszett" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grèu" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circonflèxe" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilda" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a trèma" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a encerclat" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilha" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grèu" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e agut" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circonflèxe" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e trèma" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i agut" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circonflèxe" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i trèma" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilda" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o agut" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circonflèxe" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilda" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o trèma" - -# obélus -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "devesit per" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o raiat" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u agut" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grèu" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circonflèxe" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u trèma" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y agut" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y trèma" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y TRÈMA" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "jonhent quadratenc" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "vergueta simpla dobrissenta" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "vergueta simpla tampanta" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "vergueta bassa simpla" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "vergueta dobla dobrissenta" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "vergueta dobla tampanta" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "vergueta bassa dobla" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "obèla" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "obèla dobla" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "piuse" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "piuse triangulara" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mila" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prime" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "prime doble" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "prima dobla" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "jonhent" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marca depausada" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "signe de verificacion" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "gròs signe de verificacion" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "piuse en forma de x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "exponent 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "exponent 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "exponent 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "exponent 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "exponent 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "exponent 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "exponent 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "mai en exponent" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "mens en exponent" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "egal en exponent" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "parentèsi esquèrra en exponent" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "parentèsi dreita en exponent" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "exponent n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "indici 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "indici 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "indici 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "indici 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "indici 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "indici 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "indici 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "indici 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "indici 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "indici 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "pus en indici" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "mens en indici" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "egal en indici" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "parentèsi esquèrra en indici" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "parentèsi dreita en indici" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "carrat negre" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "lausange negre" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "caractèr de remplaçament d'objècte" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Plaça lo puntador sus l'element actual." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Efectua un clic esquèrre sus l'element actual de la revision globala." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Efectua un clic dreit sus l'element actual de la revision globala." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Legís lo document en entièr." - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Legís la linha actuala de la revision globala." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Efectua l'operacion « ont soi » de basa." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Efectua l'operacion « ont soi » detalhada." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Legís la linha actuala de la revision globala." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Legir los detalhs del ligam." - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Legís la barra d'estat." - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Legís la barra de títol." - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Dobrís la fenèstra de recèrca." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Va a la lista seguenta." - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Recèrca l'ocurréncia venenta d'una cadena." - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Recèrca l'ocurréncia precedenta d'una cadena." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Activa e desactiva lo mòde de la revision globala." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Deplaça la revision globala a la posicion finala." - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Desplaça la revision globala a la posicion d'origina." - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Deplaça la revision globala a la posicion finala." - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Desplaça la revision globala al començament de la linha precedenta." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Legís la linha actuala de la revision globala." - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Letreja la linha actuala de la revision globala." - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Letreja foneticament la linha actuala de la revision globala." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Deplaça la revision globala al començament de la linha seguenta." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Deplaça la revision globala al precedent element o mot." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Legís l'element o lo mot actual de la revision globala." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Letreja l'element o lo mot actual de la revision globala." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Letreja foneticament l'element o lo mot actual de la revision globala." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Deplaça la revision globala a l'element o lo mot venent." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Deplaça la revision globala en dessús del mot actual." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Legís l'objècte actual de la revision globala." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Deplaça la revision globala en dejós del mot actual." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Deplaça la revision globala al caractèr precedent." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Legís lo caractèr actual de la revision globala." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Legís foneticament lo caractèr actual de la revision globala." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Legís la valor Unicode del caractèr actual de la revision globala." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Deplaça la revision globala al caractèr venent." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Deplaça la revision globala a la fin de la linha." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Desplaça la revision globala aval, a asquèrra." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Còpia lo contengut de l'examèn global cap al quichapapièrs." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Apond lo contengut de l'examèn global a la fin del quichapapièrs." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Deplaça la revision globala a la posicion finala." - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Determina se cal legir unicament la cellula actuala del tablèu o la linha " -"enlista." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Legís los atributs associats amb lo caractèr de tèxte actual." - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Desplaça l'afichatge braille cap a esquèrra." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Desplaça l'afichatge braille cap a dreita." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Tòrna a l'objècte que possedís lo focus del clavièr." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Activa o desactiva lo braille abreujat." - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Tracta una tòca de rotatge del cursor." - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marca lo començament d'una seleccion de tèxte." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marca la fin d'una seleccion de tèxte." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Activa lo mòde d'aprendissatge. Quichatz sus Escap per quitar lo mòde " -"d'aprendissatge." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Demesís lo ritme de lectura." - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Aumenta lo ritme de lectura." - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Demesís la nautor de la votz." - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Aumenta la nautor de la votz." - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Aumenta lo ritme de lectura." - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Demesís lo ritme de lectura." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Recèrca l'ocurréncia precedenta d'una cadena." - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Seleccionatz lo sintetizador vocal desirat." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Demesís lo ritme de lectura." - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Aumenta lo ritme de lectura." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Paramètres pel tipe de votz" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Activa o desactiva l'amortiment del son a la lectura." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Activa o desactiva lo nivèl de verbositat de la votz." - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Activa o desactiva lo mòde de lectura amb la mirga." - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Quita lo lector d'ecran" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Aficha la bóstia de dialòg de configuracion de las preferéncias." - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" -"Aficha la bóstia de dialòg de configuracion de las preferéncias de " -"l'aplicacion." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Activa o desactiva la lectura de l'indentacion e de la justificacion." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Modifica l'estil de lectura dels nombres." - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Activa lo nivèl de lectura de pontuacion seguent." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Activa lo nivèl de rapèl de las tòcas seguent." - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Activa lo perfil de paramètres seguent." - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Activa l'estil de lectura de las majusculas seguent." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Activa lo nivèl de rapèl de las tòcas seguent." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Aficha successivament los nivèls de desbugatge a l'execucion." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Plaçar un signet a l'endreit pnt soi actualament." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Va a l'emplaçament del signet precedent." - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Anar al favorit." - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Va a l'emplaçament del signet venent." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Apondre un favorit." - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Enregistrar los signets." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Activa o desactiva lo mòde de lectura amb la mirga." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Presenta l'ora actuala" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Presenta la data actuala" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Transmet la comanda seguenta a l'aplicacion actuala." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" -"Legís e aficha lo braille pel messatge precedent del salon de discussion." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Indica se cal anonciar que los contactes son a picar un messatge." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Indica se cal balhar los istorics de messatges per salon de discussion." - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Indica se cal far precedir los messatges pel nom del salon de discussion." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linha a esquèrra" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linha a dreita" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linha amont" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linha aval" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Immobilizar" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Amont a esquèrra" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Aval a esquèrra" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posicion del cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Sièis punts" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Rotatge del cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Començament talhar" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Talhar la linha" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Presenta lo darrièr messatge de notificacion." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Presenta la lista dels messatges de notificacion" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Presenta lo messatge de notificacion precedent." - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Presenta lo darrièr messatge de notificacion." - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Va al caractèr seguent" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Va al caractèr precedent." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Va al mot seguent." - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Va al mot precedent." - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Va a la linha seguenta." - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Va a la linha precedenta." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Va al començament del fichièr." - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Va a la fin del fichièr." - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Va al començament de la linha." - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Va a la fin de la linha." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Va a l'objècte seguent." - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Va a l'objècte precedent." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Provòca lo desenrotlament de la bóstia combinada actuala." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Bascula entre lo mòde de navigacion amb lo cursor natiu e lo del lector " -"d'ecran." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Avança lo paramètre de cortesiá de zòna dinamica." - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Definís lo nivèl de cortesiá de zòna dinamica per defaut a pas cap." - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Reveire los anoncis de las zònas dinamicas." - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Susvelha las zònas dinamicas." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" -"Desplaça lo focus dins o en defòra de l'objècte susvolat pel puntador de la " -"mirga." - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Definir la linha d'utilizar coma entèstas dinamicas de colomna." - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Escafa las entèstas dinamicas de colomna." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Definir la linha d'utilizar coma entèstas dinamicas de linha." - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Escafa las entèstas dinamicas de linha" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Presenta lo contengut de la linha de picada." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Activa o desactiva las tòcas de navigacion per estructura." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Va al blòt de citacion precedent." - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Va al blòt de citacion seguent." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Aficha la lista dels blòts de citacion." - -# -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Va al boton precedent." - -# -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Va al boton seguent." - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Aficha la lista dels botons." - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Va a la casa de marcar precedenta." - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Va a la casa de marcar seguenta." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Aficha la lista de las casas de marcar." - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Va a l'element clicable precedent." - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Va a l'element clicable seguent." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Aficha una lista dels elements clicables." - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Va a la bóstia combinada precedenta." - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Va a la bóstia combinada seguenta." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Va a la debuta del contenedor." - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Va a la fin de la linha." - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Aficha la lista de las bóstias combinadas." - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Va a la zòna de picada precedenta." - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Va a la zòna de picada seguenta." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Aficha la lista de las zònas de picada." - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Va al camp de formulari precedent." - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Va al camp de formulari seguent." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Aficha la lista dels camps de formulari." - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Va a l'entèsta precedenta." - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Va a l'entèsta seguenta." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Aficha la lista dels entèstas." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Va al títol precedent de nivèl %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Va al títol seguent de nivèl %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Aficha una lista dels entèstas de nivèl %d." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Va al tablèu precedent." - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Va al tablèu seguent." - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Aficha la lista dels tablèus." - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Va a l'imatge precedent." - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Va a l'imatge seguent." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Aficha una lista dels imatges." - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Va al punt de referéncia precedent." - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Va al punt de referéncia seguent." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Aficha una lista dels punts de referéncia." - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Tòrna a l'objècte important precedent." - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Tòrna a l'objècte important venent." - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Aficha la lista dels objèctes importants." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Tòrna al ligam precedent." - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Va al ligam seguent." - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Aficha la lista dels ligams." - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Va a la lista precedenta." - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Va a la lista seguenta." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Aficha la lista de las listas." - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Va a la lista d'elements precedenta." - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Va a la lista d'elements seguenta." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Aficha la lista dels elements de lista." - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Va a la zòna dinamica precedenta." - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Va a la zòna dinamica seguenta." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Va a la darrièra zòna dinamica qu'a efectuat un anonci." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Tòrna a l'objècte que possedís lo focus del clavièr." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Activa o desactiva las tòcas de navigacion per estructura." - -# -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Va al paragraf precedent." - -# -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Va al paragraf seguent" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Aficha la lista dels paragrafes." - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Va al boton ràdio precedent." - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Va al boton ràdio seguent." - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Aficha la lista dels botons ràdio." - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Va al separador precedent." - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Va al separador seguent." - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Va al tablèu precedent." - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Va al tablèu seguent." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Aficha la lista dels tablèus." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Se desplaça d'una cellula cap aval." - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Va a la primièra cellula d'un tablèu." - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Va a la darrièra cellula d'un tablèu." - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Se desplaça d'una cellula cap a esquèrra." - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Se desplaça d'una cellula cap a dreita." - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Se desplaça d'una cellula cap amont." - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Activa o desactiva lo mòde de lectura amb la mirga." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Bascula entre lo mòde navigacion e lo mòde focus." - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Activa lo mòde focus permanent." - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Activa lo mòde navigacion permanent." - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Va al ligam pas visitat seguent." - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Va al ligam pas visitat seguent." - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Aficha la lista dels ligams pas visitats." - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Va al ligam visitat seguent." - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Va al ligam visitat seguent." - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Aficha la lista dels ligams visitats." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "blau aliça" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "blanc antic" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "aiga-marina" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azur" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "burèl" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisca" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "negre" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "ametla mondada" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blau" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "blau violet" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "marron" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "blau capdet" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartrosa" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chocolat" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "coralh" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "blau viu" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "cremesin" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cian" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "blau escur" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "cian escur" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "jaune palha escur" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "gris escur" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verd escur" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "khaki escur" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta escur" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "verd oliva escur" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "irange escur" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "orquidèa escur" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "roge escur" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmon escur" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "verd ocean escur" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "blau lausa escur" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "gris lausa escur" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turquesa escur" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violet escur" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "ròse prigond" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "blau cèl prigond" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "gris rabatut" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "blau dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "roge tèule" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "blanc floral" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "verd bòsc" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fúchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gris gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "blanc espectral" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "daurat" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "jaune palha" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "gris" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verd" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "verd jaune" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "melat" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "ròse passion" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "roge indian" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indi" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "evòri" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "brun kaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "blau lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "blanc lavanda" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "verd prada" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "bège citron seda" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "blau clar" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "coralh clar" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "cian clar" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "jaune palha clar" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "gris clar" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "verd clar" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "ròse clar" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmon clar" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "verd ocean clar" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "blau cèl clar" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "gris lausa clar" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "blau acièr clar" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "jaune clar" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "verd citron" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "verd citron escur" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "teissut de lin" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "marron" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "aiga-marina mejan" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "blau mejan" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orquidèa mejan" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "porpre mejan" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "verd ocean mejan" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "blau lausa mejan" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "verd prima mejan" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turquesa mejan" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "roge violet" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "blau nuèit" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "blanc menta" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "ròse brumós" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mocassin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "blanc navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "bleu marina" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "Blanc dentèla" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "jaune oliva" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "verd oliva" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "irange" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "roge-irange" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orquidèa" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "jaune palha palle" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "verd palle" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turquesa palle" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "roge-violet palle" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "burèl papaia" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "burèl persèc" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "brun peró" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "ròse" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "pruna" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "blau posca" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "porpre" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "roge" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "brun rosat" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "blau rei" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "cuèr" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmon" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "brun sabla" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "verd ocean" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "cauquilhatge" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "tèrra de siena" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "gris argent" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "blau cèl" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "blau lausa" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "gris lausa" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "blanc nevós" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "verd prima" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "blau acièr" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "brun rós" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "sarcèla" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "cardon" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "roge tomata" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquesa" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "parma" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "blat" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "blanc" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "blanc fumada" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "jaune" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "jaune verd" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Activar" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Mòde focus automatic pendent la navigacion per estructura" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Mòde focus automatic pendent la navigacion amb lo cursor" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Mòde focus automatic pendent la navigacion amb lo cursor" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punt _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punt _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Pun_ts 7 e 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "A_nullar" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Sautar cap a" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_D'acòrdi" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Icòna" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Pas cap" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "verificar" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Indica se vòstres con_tactes pican un messatge" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Balhar los istorics de _messages per salon de discussion." - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Legir los messatges que provenon de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Totes los ca_nals" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Totes los canals quand una _fenèstra %s quina que siá es activa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Un canal unicament se sa _fenèstra es activa" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Legir lo nom del salon de discussion" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Activar lo mòde disposicion pel contengut" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "clic doble" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "clic triple" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizador per defaut" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Cadena actuala" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Cadena de remplaçament" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Activar lo _rapèl per caractèr" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Activar las tòcas _diacriticas de non espaçament" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Emplaçament a_ctual" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Longor minimala del tèxte correspondent :" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opcions de recèrca" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Legir _unicament las linhas cambiadas pendent la recèrca" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Legir los resultats pendent la _recèrca" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Comanda" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Acorchi" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Per defaut" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Mòde mesa en pagina." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "seccion" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Acorchis Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Enregistrar los signets." - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Ora e data" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Mòde d'examèn amb la mirga activat." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navigacion" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Mòde objècte." - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Pas ligada" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Desactivacion de la revision globala." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Activa o desactiva lo nivèl de verbositat de la votz." - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "contengut principal" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificat" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Burèu" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificacion" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Notificacion" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferéncias del lector d'ecran per %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marcar en braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Prononciat levat se" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Prononciar" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Enregistrar lo perfil coma « en conflicte »" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflicte de perfils d'utilizaires !" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Lo perfil %s existís ja.\n" -"Contunhar la mesa a jorn del perfil existent amb aquestas novèlas " -"modificacions ?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Cargar un perfil d'utilizaire" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Sètz a mand de modificar lo perfil actiu. S'avètz\n" -"simplament modificat d'unas preferéncias, seràn\n" -"perdudas al cargament del perfil.\n" -"\n" -"Cal cargar lo perfil ? Aquò anullarà las modificacions recentas ?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Enregistrar lo perfil jos" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nom del _perfil :" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Cargar un perfil d'utilizaire" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Totes" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicacion" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Fenèstra" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Pas cap" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Qualques" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "La màger par_t" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Linha" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Frasa" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Citacion" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Boton" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Legenda" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Casa de marcar" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Element clicable" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Quadre combinat" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descripcion" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Títol" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "intercala" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imatge" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Libellat" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Punt de referéncia" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivèl" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Ligam" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Element de lista" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objècte" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragraf" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Boton ràdio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Ròtle" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Element seleccionat" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Estat" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Tèxte" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valor" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blòts de citacion" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botons" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Casas de marcar" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Elements clicables" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Bóstias combinadas" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entradas" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Camps del formulari" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Entèstas" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "intercala" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imatges" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Entèstas de nivèl %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Punts de referéncia" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Objèctes importants" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Ligams" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listas" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Elements de lista" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragrafes" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Botons ràdio" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tablèus" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Ligams pas visitats" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Ligams visitats" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navigacion a travèrs la pagina" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Aviar automaticament la lectura d'una pagina tre qu'es _cargada pel primièr " -"còp" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Presenta lo resumit d'una pagina quand es cargada pel primièr còp" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Talhar la sintèsi vocala en _tròces entre las pausas" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "votz per defaut %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Per defaut" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Iperligam" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistèma" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Majuscula" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Correccion ortografica" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Letrejar l'_error" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Letrejar la _suggestion" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Presentar lo _contèxte d'error" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Legir las coordenadas de las cellulas del classador" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Anonciar las _entèstas de cellula" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigacion a travèrs los tablèus" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Ignorar las linhas _voidas" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Legir la _cellula" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Legir las coordenadas de las _cellulas" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Legir l'espan_dida de las cellulas que cavalcan mantuna linha/colomnas" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nom d'atribut" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Contrarotlar la navigacion amb lo cursor" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Activar la navigacion per estructura" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Cort" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Notificacion" -msgstr[1] "Notificacion" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Maj." - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Elev" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Contraròtle" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "maj esquèrra" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt esquèrra" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "contraròtle esquèrra" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "maj dreita" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt dreita" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "contraròtle dreita" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta esquèrra" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta dreita" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "varr. num." - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "varr. maj." - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "varr. maj." - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "arrèst desfil." - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "pagina prec." - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "pagina seg." - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab esquèrra" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "retorn arrièr" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "entrada" - -# en france le nom des deux touches est confondu (return = celle sous backspace, -# enter celle sur le pavé numérique). -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "entrada" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "naut" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "bas" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "esquèrra" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "dreita" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "tòca Super esquèrra" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "tòca Super dreita" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menú" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ajuda" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "cambiament de mòde" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escap" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "inser." - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "suprimir" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "origina" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "fin" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "començament" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "accent circonflèxee" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "cercle" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "raiat" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "mens" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insercion" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Verr. maj." - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "gras %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "italica %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s italica gras" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "escript %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "escript en gras %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s gotic" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s doble-trait" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s gotic gras" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s sans-serif" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s sans-serif gras" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s sans-serif italica" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s sans-serif italica gras" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s monospace" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s sens punt" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "sageta esquèrra" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "sageta naut" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "sageta dreita" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "sageta bas" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "sageta esquèrra dreita" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "sageta naut bas" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "sageta nòrd oèst" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "sageta nòrd èst" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "sageta sud èst" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "sageta amb talon cap a esquèrra" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "sageta amb talon cap amont" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "sageta amb talon cap a dreita" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "sageta amb talon cap aval" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "sageta dobla esquèrra" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "sageta dobla naut" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "sageta dobla dreita" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "sageta dobla bas" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "sageta dobla esquèrra dreita" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "sageta dobla naut bas" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "sageta dobla nòrd oèst" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "sageta dobla nòrd èst" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "sageta dobla sud èst" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "sageta dobla sud oèst" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "sageta cap a dreita" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "punta de sageta cap a dreita" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "mens" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "inferior a" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "superior a" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "accent circonflèxee" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "brèva" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punt" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dobla linha vertical" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "ellipsa orizontala" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "per totes" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "derivada parciala" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "existís" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "existís pas" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "void" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "increment" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "aparten a" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "aparten pas a" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "pichon aparten a" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "conten coma element" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "conten pas coma element" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "pichon conten coma element" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "çò que caliá desmotrar" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produit" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproduit" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "soma" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "mai o mens" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "punt mai" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "barra oblica de division" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "diferéncia d'ensembles" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operator asterisc" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operator redond" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operator piuse" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "raiç carrada" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "raiç cubica" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "raiç quatrena" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcional a" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinit" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "angle dreit" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "angle" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "angle mesurat" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "angle esferic" - -# obélus -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "devesís" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "es pas un devesidor de" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "parallèl a" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "pas parallèl a" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logica e" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logica o" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "interseccion" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "union" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integrala" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integrala dobla" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integrala tripla" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integrala de contorn" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integrala de surfàcia" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integrala de volum" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integrala dins lo sens orari" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integrala de contorn dins lo sens antiorari" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integrala de contorn dins lo sens orari" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "par consequéncia" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "perque" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "rapòrt" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporcion" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "punt mens" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "excès" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporcion geometrica" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "omotetic" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "tilda renversada" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "S colcat capvirat" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusoïd" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "produit corona" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "pas tilda" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "mens tilda" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asimptoticament egal a" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "pas asimptoticament egal a" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "gaireben egal a" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "aproximativament mas pas estrictament egal a" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ni aproximativement ni estrictament egal a" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "gaireben egal a" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "pas gaireben egal a" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "gaireben egal o egal a" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "tilda tripla" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "totes egals a" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "equivalent a" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometricament equivalent a" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "diferéncia entre" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "tanh cap al limit" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometricament egal a" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "aproximativament egal a o imatge de" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "imatge de o aproximativament egal a" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dos-punts egal" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "egal dos-punts" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "redond dins egal" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "egal amb redond en cap" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "correspond a" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estima" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "eqüiangular a" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "egal amb estela en cap" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "egal dèlta" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "egal per definicion a" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "mesurat per" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "egalitat en dobte" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "pas egal a" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identic a" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "pas identic a" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "estictament equivalent a" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "inferior o egal a" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "superior o egal a" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "mai pichon que per dessús egal a" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "mai grand que per dessús egal a" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "mai pichon mas pas egal a" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "mai grand mas pas egal a" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "fòrça mai pichon que" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "fòrça mai grand que" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "entre" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "pas equivalent a" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "pas mai pichon que" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "pas superior a" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ni inferior ni egal a" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ni superior ni egal a" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "ni inferior ni equivalent a" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "ni superior ni equivalent a" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "no inferior ni equivalent a" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ni superior ni equivalent a" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "inferior o superior a" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "superior o inferior a" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ni inferior ni superior a" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ni superior ni inferior a" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "precedís" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "seguís" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "precedís o es egal a" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "seguís o es egal a" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "precedís o es equivalent a" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "seguís o es equivalent a" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "precedís pas" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "seguís pas" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "sosensemble de" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "surensemble de" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "pas un sosensemble de" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "pas un surensemble de" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "sosensemble o egal a" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "surensemble o egal a" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ni un sosensemble ni egal a" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ni un surensemble ni egal a" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "sosensemble mas pas egal a" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "surensemble mas pas egal a" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "seleccion multipla" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiplicacion de multiensemble" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "union de multiensemble" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "imatge carrat de" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "original carrat de" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "imatge carrat o egal a" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "original carrat o egal a" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "interseccion carrada" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "union carrada" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "plus cerclat" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "mens cerclat" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "multiplicat per cerclat" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "barra oblica de division cerclada" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "operator punt cerclat" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operator redond cerclat" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operator asterisc cerclat" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "egal cerclat" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "jonhent cerclat" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus enquadrat" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "mens enquadrat" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "multiplicat par enquadrat" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operator punt enquadrat" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "cunh dreit" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "cunh esquèrra" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "cunh cap aval" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "cunh cap amont" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "assercion" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modeliza" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "verai" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "obliga" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "barra verticala tripla amb torniquet a dreita" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "barra verticala dobla amb torniquet a dreita double" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "pròva pas" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "pas verai" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "obliga pas" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "non-barra verticala dobla amb torniquet a dreita dobla" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "precedís jos relacion" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "seguís jos relacion" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "sosgrop normal de" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "conten coma sosgrop normal" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "sosgrop normal o egal a" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "conten coma sosgrop normal o egal a" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original de" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "imatge de" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multijeccion" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matritz ermiciana conjugada" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercala" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "o exclusiu" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "non e" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "non o" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "angle dreit amb arc" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triangle rectangle" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operator lausange" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operator punt" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operator estela" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "devesit multiplicat" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "nosèl parpalhòl" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "produit semidirècte a esquèrra de factor normal" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "produit semidirècte a dreita de factor normal" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "produit semidirècte a esquèrra" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "produit semidirècte a dreita" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "mens tilda capvirat" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "negacion logica" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "negacion logica" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "prime doble" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "prime doble" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "interseccion dobla" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "prima dobla" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "fcthulhu" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "egal e parallèl a" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "inferior o egal a" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "superior o egal a" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "considerablament mai pichon que" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "considerablament mai grand que" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "inferior o egal a" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "superior o egal a" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "egal o mai pichon que" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "egal o mai grand que" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "egal o precedís" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "egal o seguís" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "ni precedent ni egal a" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ni seguent ni egal a" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "superior o egal a" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "ni original carrat ni egal a" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "superior o egal a" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "original carrat o diferent de" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "inferior o egal a" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "superior o egal a" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "precedent mas pas equivalent a" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "seguent mas pas equivalent a" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "pas un sosgrop normal de" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "conten pas coma sosgrop normal" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "ni sosgrop normal ni egal a" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "ni egal ni contenent coma sosgrop normal" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "tres punts suspenduts" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "tres punts medians" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "tres punts diagonals cap al caire naut a dreita" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "tres punts diagonals cap al caire bas a dreita" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "aparten a amb long trait orizontal" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "aparten a amb barra verticala al cap del trait orizontal" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "pichon aparten a amb barra verticala al cap del trait orizontal" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "aparten a amb punt en cap" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "aparten a amb trait en cap" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "pichon aparten a amb trait en cap" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "aparten a amb trait soscrit" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "aparten a amb dos traits orizontals" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "conten amb long trait orizontal" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "conten amb barra verticala al cap del trait orizontal" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "pichon conten amb barra verticala al cap del trait orizontal" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "conten amb trait en cap" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "pichon conten amb trait en cap" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "aparten a un sac en notacion z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "parentèsi dobrissenta" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "parentèsi tampanta" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "alt esquèrra" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "alt dreita" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "acolada dobrissenta" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "acolada inferiora" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "vergueta francesa dobrissenta" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "vergueta francesa tampanta" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "punt median" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "union puntat" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "union amb mai" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "interseccion carrada" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "union carrada" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "carrat negre" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "carrat blanc" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "lausange negre" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "cercle blanc" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "cercle negre" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "pichon cercle blanc" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "carrat negre mejan" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s amb soslinhament" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s amb barra oblica" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s amb linha verticala" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplicacion" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "void" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "gras" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "signet localizat" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "favorits enregistrats" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "los signets pòdon pas èsser enregistrats" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Pas pus cap de punt de referéncia." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Pas pus cap de punt de referéncia." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Mòde de contornament activat." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Impossible d'obténer l'afichatge de la calculadoira" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "icòna" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Estil de lectura de las majusculas definit a icòna." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "pas cap" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Estil de lectura de las majusculas definit a pas cap." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "verificar" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Estil de lectura de las majusculas definit a anonci." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Gecko contraròtla lo cursor." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Gecko contraròtla lo cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cellula %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "seleccionat" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "pas seleccionat" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Empacha l'utilizacion de l'opcion" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Fòrça l'utilizacion de l'opcion" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCION" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Paramètres facultatius" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Usatge : " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Çò que seguís es invalid : " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Aficha las aplicacions aviadas conegudas" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Cargar lo perfil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Lo perfil pòt pas èsser cargat : %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Impossible d'aviar lo lector d'ecran perque se pòt pas connectar al burèu." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Impossible d'activar lo gestionari de paramètres. Sortida." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Una autra instància del lector d'ecran es ja aviada per aquesta session.\n" -"Aviatz « cthulhu --replace » per remplaçar aqueste processus per un novèl." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOM" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Utiliza un repertòri alternatiu per las preferéncias dels utilizaires" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DOS" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Aficha las aplicacions aviadas conegudas" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Remplaça una instància actualament aviada d'aqueste lector d'ecran" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Mostrar aqueste messatge d'ajuda e quitar" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Manda la sortida de desbugatge dins debug-AAAA-MM-JJ-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Manda la sortida de desbugatge dins lo fichièr indicat" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FICHIÈR" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Definís las preferéncias d'utilizaire (mòde tèxte)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Definís las preferéncias d'utilizaire (mòde tèxte)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Raportar las anomalias a https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Contengut apondut al quichapapièrs." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "accent agut" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Contengut apondut al quichapapièrs." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copiat" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Contengut apondut al quichapapièrs." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "mai rapid." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Anonciar pas quand los contactes pican un messatge." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "Anonciar quand los contactes pican un messatge." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Messatge del salon de discussion %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Novèl onglet de discussion %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Legir pas lo nom del salon de discussion." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "legir lo nom del salon de discussion." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Balhar pas los istorics de messatges per salon de discussion." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Balhar los istorics de messatges per salon de discussion." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "començament de fraccion" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "fin de fraccion" - -#: src/cthulhu/messages.py:452 -#, fuzzy -msgctxt "content" -msgid "insertion start" -msgstr "començament de fraccion" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "fin de fraccion" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "verd clar" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "Letrejar la _suggestion" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Fin del tablèu" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Pas dins un tablèu." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "pas seleccionat" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Lo boton per defaut es %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Lo boton per defaut es %s" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Lo boton per defaut es %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " indici %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " exponent %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Pas dins un tablèu." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "document entièr seleccionat" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "document entièr seleccionat" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "document seleccionat dempuèi la posicion del cursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "document deseleccionat dempuèi la posicion del cursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "document seleccionat fins a la posicion del cursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "document deseleccionat fins a la posicion del cursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Entèsta dinamica de colomna definida per la linha %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Entèsta dinamica de colomna escafada." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Entèsta dinamica de linha definida per la colomna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Entèsta dinamica de linha escafada." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "void" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f quilooctets" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megaoctets" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Cap de fichièr pas trobat." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Contengut apondut a la fin del quichapapièrs." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Contengut apondut al quichapapièrs." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Examèn global pas utilizat." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Activacion de la revision globala." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Desactivacion de la revision globala." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Deplaça la revision globala en dessús del mot actual." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "conten una formula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "Dobrís la fenèstra de recèrca." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "ligam d'imatge amb de zònas clicablas" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "La tòca picada es ja ligada a %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tòca capturada : %s. Quichatz sus Entrada per confirmar." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "La tòca novèla es : %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Acorchi suprimit. Quichatz sus Entrada per confirmar." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "L'acorchi es estat levat." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "picatz una tòca novèla" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tòca" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Rapèl de tòca definit per tòca." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Pas cap" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Rapèl de tòca definit a pas cap." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tòca e mot" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Rapèl de tòca definit a tòca e mot." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "frasa" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Rapèl de tòca definit per frasa." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "mot" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Rapèl de tòca definit per mot." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "mot e frasa" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Rapèl de tòca definit a mot e frasa." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Enrodat per : %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "un simbòl actuarial" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "una bóstia" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "cercle negre" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "un simbòl de division longa" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "un radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "una bóstia arredondida" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "orizontal" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "barra verticala" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "una barra diagonala cap aval" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "una barra diagonala cap amont" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "sageta dreita" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Contunhar dempuèi aval" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "una linha a esquèrra" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "una linha a dreita" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "una linha amont" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "un angle de fasa" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "un simbòl de factoriala aràbia" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "e" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "començament de fraccion" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "començament de fraccion sens barra" - -# SunGloss -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "devesit per" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "fin de fraccion" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "raiç carrada" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "raiç cubica" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "raiç de" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "començament de raiç" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "fin de raiç" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "indici 0" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "ordinal femenin" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "indici 0" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "ordinal femenin" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "ordinal femenin" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "ordinal femenin" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "fin de tablèu" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "fin de tablèu imbricat" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccessible" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Desactivada" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Lectura de l'indentacion e de la justificacion desactivada." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Activada" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Lectura de l'indentacion e de la justificacion activada." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Mòde d'aprendissatge. Quichatz sus Escap per quitar." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Mòde d'aprentissatge activat. Quichatz sus una tòca per entendre sa foncion. " -"Per afichar la documentacion del lector d'ecran, quichatz sus F1. Per " -"obténer la lista dels acorchis de clavièr per defaut del lector d'ecran, " -"quichatz sus F2. Per obténer la lista dels acorchis de clavièr del lector " -"d'ecran per l'aplicacion actuala, quichatz sus F3. Per quitar lo mòde " -"d'aprentissatge, quichatz sus Escap." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1249 -#, fuzzy -msgctxt "role" -msgid "leaving complementary content." -msgstr "contengut complementari" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "informacion" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "contengut principal" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Navigacion a travèrs la pagina" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Navigacion a travèrs los tablèus" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "Desactivacion de la revision globala." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "Letrejar la _suggestion" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "sortida del tablèu." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "linha seleccionada en dejós de la posicion del cursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "linha seleccionada en dejós de la posicion del cursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "linha deseleccionada en dejós de la posicion del cursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "linha deseleccionada en dessús de la posicion del cursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Fin del mòde d'aprendissatge." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" -"linha seleccionada del començament fins a la posicion precedenta del cursor" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "linha seleccionada de la posicion precedenta del cursor fins a la fin" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ligam" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "meteissa pagina" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "site identic" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "site diferent" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "ligam %(uri)s cap a %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s ligam" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "ligam %s visitat" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Utilizatz las sagetas naut e bas per percórrer la lista. Quichatz sus Escap " -"per quitar." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Totas las zònas dinamicas son definidas a « desactivat »" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "nivèls de cortesiá de las zònas dinamicas restablits" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nivèl de cortesiá %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "definicion de la zòna dinamica a « afirmatiu »" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "definicion de la zòna dinamica a « desactivat »" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "definicion de la zòna dinamica a « educat »" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "definicion de la zòna dinamica a « peremptòri »" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Susvelhança de las zònas dinamicas desactivada" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Susvelhança de las zònas dinamicas activada" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "cap de messatge dinamic pas enregistrat" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "La presa en carga de las zònas dinamicas es desactivada" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Introbable" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Impossible de trobar l'emplaçament actual." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "desactivat" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "activat" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "mal ortografiat" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Mot mal ortografiat : %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Lo contèxte es %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Mòde navigacion" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Mòde focus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Per activar lo mòde focus quichatz sus %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Lo mòde focus es permanent." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Lo mòde navigacion es permanent." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Mòde mesa en pagina." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Mòde objècte." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Pas pus cap d'objècte important." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "L'objècte generat pel susvòl del puntador es pas estat trobat." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Mòde d'examèn amb la mirga desactivat." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Mòde d'examèn amb la mirga activat." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Error : impossible de crear la lista dels objèctes." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d per cent." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Va al mot precedent." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nivèl d'imbricacion %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Un novèl objècte es estat apondut" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Cap d'aplicacion es pas activa." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Pas cap de focus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Cap d'aplicacion es pas activa." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Pas mai de blòt de citacion." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Pas mai de boton." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Pas pus cap de casa de marcar." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Pas pus cap d'objècte important." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Pas cap d'element mai de clicable." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Pas pus cap de bóstia combinada." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Pas pus cap de zòna de picada." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Pas pus cap de camp de formulari." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Pas pus cap d'entèsta." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Pas pus cap d'entèsta al nivèl %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Pas pus cap de tablèu." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Pas cap d'imatge mai." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Pas pus cap de punt de referéncia." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Pas mai cap de ligam." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Pas pus cap delista." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Pas pus cap d'element de lista." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Pas pus cap de zòna dinamica." - -# -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Pas mai de paragraf." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Pas pus cap de boton ràdio precedent." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Pas pus cap de separador." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Pas pus cap de tablèu." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Pas pus cap de ligam pas visitat." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Pas pus cap de ligam visitat." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Pas de tèxte seleccionat." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Pas mai cap de ligam." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificacion" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Bas" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Naut" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Pas cap de messatge de notificacion" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "chifras" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Legir los nombres coma de chifras." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "mots" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Legir las cadenas de cassa mesclada coma de _mots" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "desactivada" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "activada" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Cargament en cors. Pacientatz." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Cargament acabat." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Cargament de %s acabat." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "La pagina possedís %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "pagina seleccionada dempuèi la posicion del cursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "pagina seleccionada fins a la posicion del cursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "pagina deseleccionada dempuèi la posicion del cursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "pagina deseleccionada fins a la posicion del cursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "paragraf seleccionat cap aval dempuèi la posicion del cursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragraf seleccionat cap amont dempuèi la posicion del cursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "paragraf deseleccionat cap aval dempuèi la posicion del cursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragraf deseleccionat cap amont dempuèi la posicion del cursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Avètz ja dobèrt una bóstia de dialòg de las preferéncias d'Cthulhu.\n" -"Tampatz-la abans de ne dobrir una novèla." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapositiva %(position)d sus %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Perfil definit a %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Cap de perfil pas trobat." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra de progression %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Totes" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Nivèl de pontuacion definit a totes." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "La màger part" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Nivèl de pontuacion definit a la màger part." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Pas cap" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Nivèl de pontuacion definit a pas cap." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Qualques uns" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Nivèl de pontuacion definit a qualques uns." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Recèrca." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Recèrca acabada." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Paramètres del lector d'ecran recargats." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Lo tèxte seleccionat es : %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Linha suprimida." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Indicador de seleccion" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "pas seleccionat" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Sintèsi vocala desactivada." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Sintèsi vocala activada." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "mai rapid." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "mens rapid." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "mai naut." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "mens naut." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "mai fòrt." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "mai rapid." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "Taus" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Vo_lum :" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Cap de servidor pas disponible." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Pas cap de votz disponibla." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Sintèsi vocala activada." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "La sintèsi vocala serà pas utilizada." - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Nivèl de verbositat : concís" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Nivèl de verbositat : charraire" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " punt punt punt" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Mòde de contornament activat." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "La sintèsi vocala es pas disponibla." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Introbable" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "cadena pas trobada" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "cadena pas trobada" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Tòcas de navigacion per estructura desactivadas." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Tòcas de navigacion per estructura activadas." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Introbable" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Linha %(row)d, colomna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Fin del tablèu" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Legir la cellula" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Legir la linha" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Pas unifòrme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Pas dins un tablèu." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Colomnas reordenadas" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Linhas reordenadas" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "colomna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "colomna %(index)d sus %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Bas de la colomna." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Naut de la colomna." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "pas seleccionat" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "pas seleccionat" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "linha %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "linha %(index)d sus %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Començament de la linha." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Fin de linha." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Linha suprimida." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Darrièra linha suprimida." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Linha aponduda." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Linha aponduda a la fin del tablèu." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "Linha suprimida." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "pas seleccionat" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "seleccionat" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "pas seleccionat" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H oras, %M minutas e %S segondas" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H oras e %M minutas" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "anullar" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "restablir" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "blanc" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Contunhar dempuèi aval" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Contunhar dempuèi amont" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 element" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "La cellula s'espandís sus %d linha" -msgstr[1] "La cellula s'espandís sus %d linhas" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d colomna" -msgstr[1] " %d colomnas" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "La cellula s'espandís sus %d colomna" -msgstr[1] "La cellula s'espandís sus %d colomnas" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "Tròp long de %d caractèr" -msgstr[1] "Tròp long de %d caractèrs" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d bóstia de dialòg)" -msgstr[1] "(%d bóstias de dialòg)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d bóstia de dialòg sens focus" -msgstr[1] "%d bóstias de dialòg sens focus" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d octet" -msgstr[1] "%d octets" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fichièr trobat" -msgstr[1] "%d fichièrs trobats" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulari" -msgstr[1] "%d formularis" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d entèsta" -msgstr[1] "%d entèstas" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d element" -msgstr[1] "%d elements" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d punt de referéncia" -msgstr[1] "%d punts de referéncia" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d element trobat" -msgstr[1] "%d elements trobats" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Pas pus cap de blòt de citacion" -msgstr[1] "Pas pus cap de blòt de citacion" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Desactivacion de la revision globala." -msgstr[1] "Desactivacion de la revision globala." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista amb %d element" -msgstr[1] "Lista amb %d elements" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Lista amb %d element" -msgstr[1] "Lista amb %d elements" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Valor" -msgstr[1] "Valor" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tablèu matematic amb %d linha" -msgstr[1] "tablèu matematic amb %d linhas" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d colomna" -msgstr[1] "%d colomnas" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tablèu matematic imbricat amb %d linha" -msgstr[1] "tablèu matematic imbricat amb %d linhas" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d messatge.\n" -msgstr[1] "%d messatges.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d per cent." -msgstr[1] "%d per cent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d per cent del document legit" -msgstr[1] "%d per cent del document legit" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixèl" -msgstr[1] "%d pixèls" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s caractèr" -msgstr[1] "%(count)d %(repeatChar)s caractèrs" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d sus %(total)d element seleccionat" -msgstr[1] "%(index)d sus %(total)d elements seleccionats" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d acorchi per defaut del lector d'ecran de trobat." -msgstr[1] "%d acorchis per defaut del lector d'ecran de trobats." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d acorchi del lector d'ecran per %(application)s trobat." -msgstr[1] "%(count)d acorchis del lector d'ecran per %(application)s trobats." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espaci" -msgstr[1] "%d espacis" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d onglet" -msgstr[1] "%d onglets" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tablèu" -msgstr[1] "%d tablèus" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "Activar lo mòde disposicion pel contengut" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tablèu amb %d linha" -msgstr[1] "tablèu amb %d linhas" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tablèu amb %d linha" -msgstr[1] "tablèu amb %d linhas" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tablèu amb %d linha" -msgstr[1] "tablèu amb %d linhas" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d ligam pas visitat" -msgstr[1] "%d ligams pas visitats" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d ligam visitat" -msgstr[1] "%d ligams visitats" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "boton amb dos estats" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "sus %(index)d sus %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d sus %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVÈL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nivèl d'arborescéncia %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVÈL DE L'ARBORESCÉNCIA %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "suggestion" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "bóstia combinada modificabla" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "modificable" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "resumit" - -#: src/cthulhu/object_properties.py:155 -#, fuzzy -msgctxt "role" -msgid "acknowledgments" -msgstr "complement" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "mot" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "annèxe" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "entrada bibliografica" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografia" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "capítol" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "dos punts" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conclusion" - -# SunGloss -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "devesit per" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "crèdit" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "crèdits" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "direccion" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "nòta finala" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "nòtas finalas" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilòg" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "exemple" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "mot" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glossari" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "indentacion" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "interseccion" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "saut de pagina" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "pagina prec." - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "prefàcia" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prològue" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "vergueta" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "sostítol" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "Activar lo mòde disposicion pel contengut" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivèl %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "barra de desfilament orizontala" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "barra de desfilament verticala" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "cursor orizontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "cursor vertical" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "separador orizontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "separador vertical" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "cambiament de mòde" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Panèl d'icònas" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "bandièra" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "contengut complementari" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informacion" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "contengut principal" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigacion" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "region" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "recèrca" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "%d ligam visitat" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "Pas pus cap de boton" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "clicable" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "reduit" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "espandit" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "a una descripcion longa" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "orizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "marcada" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "pas marcada" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "activada" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "desactivada" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "parcialament marcada" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "quichada" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "pas quichada" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "pas seleccionat" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "seleccionat" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "pas seleccionat" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "pas seleccionat" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visitat" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "pas visitat" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "grisat" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "lectura sola" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "lectsola" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "requesit" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "seleccion multipla" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "entrada invalida" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "invalid" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "ortografia" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "ortografia" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "gramatica invalida" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatica" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Recercar" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Bóstia de dialòg de recèrca del lector d'ecran" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Tampar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Recercar" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Recercar :" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Recercar :" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Naut de la fenèstra" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Naut de la fenèstra" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Aviar dempuèi :" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Recèrca _circulara" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Recèrca en _arrièr" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Sens de la recèrca :" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Respectar la cassa" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Mots _entièrs solament" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opcions :" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Defaut" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Majusculas" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Iperligam" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistèma" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicacion" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Fenèstra" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Lector d'ecran Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Ajuda" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Aplicar" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "Ordenador _portable" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Agençament del clavièr" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Perfil actiu :" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Perfil a l'aviada :" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Carga" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Enregistrar _jos" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Suprimir" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Perfils" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Presentacion de las infobullas" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Legir l'objècte jos la mir_ga" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Mirga" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Forma_t de l'ora :" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Format d_e data :" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Ora e data" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Legir _tot" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Indicador Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frequéncia (seg) :" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplicacion" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Seguiment de las mesas a jorn per bi_p" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Barra de progression - frequéncia" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Activar lo _retorn e l'avança rapida en mòde legir tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Activar la navigacion per estructura" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Legir to_t per :" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Legir to_t per :" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "General" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lum :" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Nau_tor :" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "Taus" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persona :" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "lenga" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "S_intetizador vocal :" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Sistèma de _sintèsi vocala :" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipe de _votz :" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Estil de lectura de las majusculas definit a icòna." - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Paramètres pel tipe de votz" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Legir las cadenas de cassa mesclada coma de _mots" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Legir los _nombres coma de chifras" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Reglatges generals de la votz" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Votz" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Activar la sintèsi vocala" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Ver_bós" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Verbositat" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Totas" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Nivèl de pontuacion" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Legiscatz pas que lo tèxte afichat" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Legir las linhas voidas" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Legir l'_indentacion e la justificacion" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Legir l'a_corchi dels objèctes" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Legir la p_osicion filha" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Legir los messatges del tutorial" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Los messatges _sistèma son detalhats" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Legir las coordenadas de las _cellulas" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Mòde focus automatic pendent la navigacion amb lo cursor" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Activar la navigacion per estructura" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Activar la navigacion per estructura" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Legir las coordenadas de las _cellulas" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Mòde focus automatic pendent la navigacion amb lo cursor" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Descripcion" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Le_gir la linha completa dins los tabladors" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Legir la linha completa dins los tablèus de _documents" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Legir la lin_ha completa dins los tablèus d'interfàcia" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Contèxte parlat" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Parladís" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Activar la _presa en carga del braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Noms de ròtle _abreujats" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Desactivar lo simbòl _fin de linha" - -# manque contexte, peut ête en lien avec contracted Braille, d'où abréviation -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tablèu de contraccions :" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Activar lo braille abreujat" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Activar lo rapèl per _mot" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Paramètres d'afichatge" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Pas cap" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicador de seleccion" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicador d'iperligams" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Activar los _messatges flash" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Durada dels messatges (seg) :" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Los messatges son _persistents" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Los messatges son _detalhats" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Reglatges generals de la votz" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Activar lo _rapèl de las tòcas" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Activar las tòcas de _navigacion" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Activar las tòcas de _modificacion" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Activar las tòcas de _foncions" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "_Activar la sintèsi vocala" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Activar las tòcas de _modificacion" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Activar las tòcas de _foncions" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Activar las tòcas d'_accion" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Activar las tòcas de _navigacion" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Activar lo rapèl per _mot" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Activar lo rapèl per _frasa" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Rapèl de tòca" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Tòca(s) de _modificacion del lector d'ecran :" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Acorchis de clavièr" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Diccionari de Prononciacion" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Dintrada _novèla" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Suprimir" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Prononciacion" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Legir _tot" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Legir pas _res" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Reïnicializar" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributs del tèxte" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Desplaçar ava_l de tot" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Desplaçar cap a_val" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Desplaçar cap a_mont" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Desplaçar amon_t de tot" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Ajustar los atributs seleccionats" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicador Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributs de tèxte" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "bas" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "lenga" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Contengut apondut al quichapapièrs." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "color de rèireplan" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "nautor completa del rèireplan" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "rèireplan grisat" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direccion" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "modificable" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "familha" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "color de primièr plan" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "primièr plan grisat" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efèit de poliça" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indentacion" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "error" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisible" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justificacion" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "lenga" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "marge d'esquèrra" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "nautor de linha" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "Estil de paragraf" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixèls en dessús de las linhas" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixèls en dejós de las linhas" - -# selon la traduction de gtk+ (po-properties) : « Pixels à l'intérieur de la coupure » -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixèls entre las linhas d'un paragraf" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "marge de dreita" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "elevacion" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "escala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "talha" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "espandit" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "raiat" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decoracion del tèxte" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotacion del tèxte" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "ombra del tèxte" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "soslinhament" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "varianta" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "alinhament vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "grassa" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "mòde de cesura" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "mòde d'escritura" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "verai" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "fals" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "pas cap" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "emprenta" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "relèu" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "contorn" - -# SunGloss -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "linha en dessús" - -# SunGloss -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "linha a travèrs" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "cluquejant" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "negre" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "simple" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "doble" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "bas" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "caractèr" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "mot" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "mot puèi caractèr" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "evd" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "dve" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "esquèrra" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "dreita" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centre" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "sens justificacion" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "justificat" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "super condensat" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "fòrça condensat" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensat" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "mièg condensat" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "mièg espandit" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "espandit" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "fòrça espandit" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "super espandit" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "majusculas pichonas" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblic" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "italica" - -# -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Defaut" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Còs de tèxte" - -# -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Títol" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "sus la linha de basa" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "en indici" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "en exponent" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "amont" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "alinhat en naut" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "al mitan" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "aval" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "alinhat en bas" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "ereitat" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "ed-nb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "de-nb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "nb-de" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "nb-ed" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bn-de" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bn-ed" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "ed" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "de" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "nb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "continú" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "ortografia" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Quichatz sus espaci per cambiar d'estat." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Quichatz sus espaci per desvolopar, e utilizar naut e bas per seleccionar un " -"element." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Quichatz sus Alt+F6 per balhar lo focus a las fenèstras filhas." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Utilizatz las tòcas senhalizadas o picatz de letras per vos desplaçar d'un " -"element l'autre." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Per aténher los menús del sistèma, quichatz sus las tòcas Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Utilizatz las sagetas naut e bas per seleccionar un element." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Per reduire la branca, quichatz sus Maj e esquèrra." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Per desplegar la branca, quichatz sus Maj e dreita." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Quichar sus Entrada per activar." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Picatz de tèxte." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" -"Utilizatz las sagetas d'esquèrra e de dreita per afichar los autres onglets." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Per activar quichatz sus Espaci." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Utilizatz las sagetas naut e bas per causir una valor. O picatz la valor " -"numerica desirada." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Utilizatz las segetas per cambiar." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Per navigar, quichatz sus las sagetas esquèrra e dreita. Per vos desplaçar a " -"travèrs los elements, quichatz sus las sagetas naut o bas." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Per entrar dins lo sosmenú, quichatz sus la sageta dreita." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Per demesir quichatz sus la sageta esquèrra, per aumentar sus la sageta " -"dreita. Pel minimum quichatz sus Origina e pel maximum sus Fin." diff --git a/po/or.po b/po/or.po deleted file mode 100644 index 448e68a..0000000 --- a/po/or.po +++ /dev/null @@ -1,9814 +0,0 @@ -# translation of cthulhu.HEAD.or.po to Oriya -# This file is distributed under the same license as the PACKAGE package. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. -# -# Subhransu Behera , 2006. -# Subhransu Behera , 2006. -# Manoj Kumar Giri , 2009. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD.or\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2009-03-10 17:25+0530\n" -"Last-Translator: Manoj Kumar Giri \n" -"Language-Team: Oriya \n" -"Language: or\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n" -"\n" -"\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "ଓର୍କା ସ୍କ୍ରିନ ପାଠକ /ଛୋଟକୁ ବଡ ଦେଖଉଥିବା ଉପକରଣ " - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -#, fuzzy -msgid "alrt" -msgstr "ସତର୍କ" - -#: src/cthulhu/braille_rolenames.py:54 -#, fuzzy -msgid "anim" -msgstr "ଜୀବନାୟନ" - -#: src/cthulhu/braille_rolenames.py:57 -#, fuzzy -msgid "arw" -msgstr "ତୀର" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "ସିଏଏଲ" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "ସିଏନଭି" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "ସିପିଟିଏନ" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "ସିଏଚ୍ କେ" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -#, fuzzy -msgid "icn" -msgstr "ଚିତ୍ରସଙ୍କେତ" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "ଡାଏଲ" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "ଅଂକନ କର" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -#, fuzzy -msgctxt "shortbraille" -msgid "form" -msgstr "ଫର୍ମ" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -#, fuzzy -msgid "ifrm" -msgstr "ବନ୍ଧେଇ" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -#, fuzzy -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "ରେଡିଓ" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "ସ୍ପିନ" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "ଶବ୍ଦ" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tବାର" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -#, fuzzy -msgid "tre" -msgstr "ବୃକ୍ଷ" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "ପାରା" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "ସ୍ବୟଂଚାଳିତ" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "ଖାଲି ସ୍ଥାନ" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "ନୂଆରେଖା" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "ଟ୍ଯାବ" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "ଉଚ୍ଚ ସ୍ବରରେକୁହ" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "ଉଦ୍ଧୃତାଂଶ" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "ସଂଖ୍ଯା" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "ଡଲାର" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "ପ୍ରତିଶତ" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ଏବଂ" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "ବର୍ଣ୍ଣମାଳା ଚିହ୍ନ" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "ବାମପାରେନ" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "ଡାହାଣ ପାରେନ" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "ତାରାଚିହ୍ନ" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "ୟୋଗଚିହ୍ନ" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "କମା" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "ଡ୍ଯାସ" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "ବିନ୍ଦୁ" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "ସ୍ଲାଶ" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "ବିରାମ ଚିହ୍ନ" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "ଅର୍ଦ୍ଧବିରାମ ଚିହ୍ନ" - -#: src/cthulhu/chnames.py:126 -#, fuzzy -msgid "less" -msgstr "କ୍ଷୁଦ୍ରତର" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "ସମାନ ଚିହ୍ନ" - -#: src/cthulhu/chnames.py:134 -#, fuzzy -msgid "greater" -msgstr "ବ୍ରୁହତର" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "ପ୍ରଶ୍ନ" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "ଏଠାରେ" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "ବାମ ବନ୍ଧନୀ" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "ବେକସ୍ଲାଶ" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "ଡାହାଣ ବନ୍ଧନୀ" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "କ୍ଯାରେଟ" - -#: src/cthulhu/chnames.py:162 -#, fuzzy -msgid "underline" -msgstr "ଅବରେଖନ" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -#, fuzzy -msgid "grave" -msgstr "ସ୍ମାରକ ଚିହ୍ନ" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "ବାମ ବର୍ଗବନ୍ଧନୀ" - -#: src/cthulhu/chnames.py:174 -#, fuzzy -msgid "vertical bar" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "ଡାହାଣ ବର୍ଗବନ୍ଧନୀ" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "ଟିଲଡେ" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "ପଛକୁ (Backspace)" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -#, fuzzy -msgid "broken bar" -msgstr "ମେନୁ ପଟି" - -#: src/cthulhu/chnames.py:215 -#, fuzzy -msgid "section" -msgstr "ଅଂଶ" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -#, fuzzy -msgid "registered" -msgstr "କେନ୍ଦ୍ରୀଭୂତ" - -#: src/cthulhu/chnames.py:247 -#, fuzzy -msgid "macron" -msgstr "ଚିତ୍ରସଙ୍କେତ" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -#, fuzzy -msgid "mu" -msgstr "ମୁ" - -#: src/cthulhu/chnames.py:275 -#, fuzzy -msgid "paragraph marker" -msgstr "ଅନୁଚ୍ଛେଦ" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "ଡାଏଲ" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -#, fuzzy -msgid "times" -msgstr "ଚିତ୍ର" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -#, fuzzy -msgid "o stroke" -msgstr "ବର୍ଣ୍ଣମାଳା ଚିହ୍ନ" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -#, fuzzy -msgid "florin" -msgstr "ସଂଯୋଗ" - -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "ଡ୍ଯାସ" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -#, fuzzy -msgid "dagger" -msgstr "ପୃଷ୍ଠା" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -#, fuzzy -msgid "per mille" -msgstr "ବ୍ରେଲ" - -#: src/cthulhu/chnames.py:629 -#, fuzzy -msgid "prime" -msgstr "ବନ୍ଧେଇ" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -#, fuzzy -msgid "check mark" -msgstr "ତନଖି ବାକ୍ସ" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "ବାମପାରେନ" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "ଡାହାଣ ପାରେନ" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "ବାମପାରେନ" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "ଡାହାଣ ପାରେନ" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ସାମଗ୍ରୀରେ ବାମ କ୍ଲିକ କରେ ୤" - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "ଚଳିତ ସମତଳ ପୁନଃଦୃଶ୍ଯ ସାମଗ୍ରୀରେ ଡାହାଣ କ୍ଲିକ କରେ ୤" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "ସମଗ୍ର ଦଲିଲକୁ କହେ ୤" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ରେଖାକୁ କହେ" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ରେଖାକୁ କହେ" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "ଖାଲି ରେଖାଗୁଡିକୁ କହ" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "ସ୍ଥିତି ବାର" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "ଉପସ୍ଥାପନା ଉଇଜାର୍ଡ" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "ଓର୍କା ଖୋଜ ଡାଏଲଗକୁ ଖୋଲେ" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "ଗୋଟିଏ ସ୍ଟ୍ରିଙ୍ଗର ପରବର୍ତ୍ତୀ ଦୃଷ୍ଟାନ୍ତକୁ ଖୋଜେ ୤" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "ଗୋଟିଏ ସ୍ଟ୍ରିଙ୍ଗର ପୂର୍ବବର୍ତ୍ତୀ ଦୃଷ୍ଟାନ୍ତକୁ ଖୋଜେ ୤" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "ସମତଳ ପୁନରାଲୋଚନା ମୋଡକୁ ପ୍ରବେଶ ଏବଂ ପ୍ରସ୍ଥାନ କରେ ୤" - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "ଶେଷ ସ୍ଥାନକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "ହୋମ ସ୍ଥାନକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ" - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "ଶେଷ ସ୍ଥାନକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "ପୂର୍ବବର୍ତ୍ତୀ ରେଖାର ଆରମ୍ଭକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ରେଖାକୁ କହେ" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ରେଖାକୁ କହେ" - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ରେଖାକୁ କହେ" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "ପରବର୍ତ୍ତୀ ଧାଡିର ଆରମ୍ଭକୁ ସମତଳ ପୁନରାଲୋଚନା ଘୁଞ୍ଚାଏ" - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "ସମତଳ ପୁନରାଲୋଚନାକୁ ପୂର୍ବବର୍ତ୍ତୀ ଶବ୍ଦ କିମ୍ବା ସାମଗ୍ରୀକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ରେଖାକୁ କହେ" - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ରେଖାକୁ କହେ" - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ରେଖାକୁ କହେ" - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "ପରବର୍ତ୍ତୀ ସାମଗ୍ରୀ କିମ୍ବା ଶବ୍ଦକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "ଚଳିତ ଶବ୍ଦର ଉପର ଶବ୍ଦକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ବସ୍ତୁକୁ କହେ ୤" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "ଚଳିତ ଶବ୍ଦର ତଳ ଶବ୍ଦକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "ପୂର୍ବବର୍ତ୍ତୀ ଅକ୍ଷରକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ଅକ୍ଷରକୁ କହେ ୤" - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ଅକ୍ଷରକୁ କହେ ୤" - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "ଚଳିତ ସମତଳ ପୁନରାଲୋଚନା ଅକ୍ଷରକୁ କହେ ୤" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "ପରବର୍ତ୍ତୀ ଅକ୍ଷରକୁ ସମତଳ ପୁନରାଲୋଚନା ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "ଧାଡିର ଶେଷକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "ସମତଳ ପୁନରାଲୋଚନାକୁ ତଳର ବାମକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "ଶେଷ ସ୍ଥାନକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "କେବଳ ଚଳିତ ଟେବୁଲ କୋଷ କିମ୍ବା ସମଗ୍ର ଧାଡିକୁ ପଢାୟିବ କି ନାହିଁ ଟୋଗଲ କରେ ୤" - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "ଚଳିତ ଟେକ୍ସଟ ଅକ୍ଷର ସହିତ ସମ୍ମିଳିତ ଗୁଣଗୁଡିକୁ ପଢେ ୤" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "ପ୍ଯାନସ ଏବଂ ବ୍ରେଇଲ ପ୍ରଦର୍ଶନ ବାମକୁ କର" - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "ପ୍ଯାନସ ଏବଂ ବ୍ରେଇଲ ପ୍ରଦର୍ଶନ ଡାହାଣକୁ କର" - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "କିବୋର୍ଡ ଲକ୍ଷ୍ଯ ସହିତ ବସ୍ତୁକୁ ଫେରେ ୤" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "ପରବର୍ତ୍ତୀ ଧାଡିର ଆରମ୍ଭକୁ ସମତଳ ପୁନରାଲୋଚନା ଘୁଞ୍ଚାଏ" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "ଶିକ୍ଷା ମୋଡକୁ ପ୍ରବେଶ କରେ ୤ ଶିକ୍ଷା ମୋଡରୁ ପ୍ରସ୍ଥାନ କରିବା ପାଇଁ ଏସ୍କେପକୁ ଦବାଅ" - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "କଥା କହିବା ଦର ହ୍ରାସ କରେ ୤" - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "କଥାକହିବା ଦର ବୃଦ୍ଧିକରେ ୤" - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "କଥା କହିବା ସ୍ବରକୁ ହ୍ରାସ କରେ ୤" - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "କଥାକହିବା ସ୍ବରକୁ ବୃଦ୍ଧି କରେ ୤" - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "କଥାକହିବା ଦର ବୃଦ୍ଧିକରେ ୤" - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "କଥା କହିବା ଦର ହ୍ରାସ କରେ ୤" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "ଇଚ୍ଛିତ କଥା କହିବା ସରଭର ମନୋନୀତ କର" - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "ଇଚ୍ଛିତ କଥା କହିବା ସରଭର ମନୋନୀତ କର" - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "କଥା କହିବା ଦର ହ୍ରାସ କରେ ୤" - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "କଥାକହିବା ଦର ବୃଦ୍ଧିକରେ ୤" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "କଥା କହିବା ନୀରବ କରିବାକୁ ଟୋଗଲ କରେ ୤" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "ପସନ୍ଦଗୁଡିକ କନଫିଗରେସନ ଡାଏଲଗକୁ ପ୍ରଦର୍ଶନ କରେ ୤" - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "ପସନ୍ଦଗୁଡିକ କନଫିଗରେସନ ଡାଏଲଗକୁ ପ୍ରଦର୍ଶନ କରେ ୤" - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "_ଅନୁଚ୍ଛେଦକରଣ ଏବଂ ନ୍ଯାଯୋଚିତକରଣ କହ" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "କଥାକହିବା ସଂଶ୍ଳେଷଣ_କାରକ:" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "ଚାଲିବା ସମଯରେ ଡିବଗ୍ ସ୍ତରକୁ ଆବର୍ତ୍ତିତ କରେ ୤" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "ଗୋଟିଏ ପୂର୍ବବର୍ତ୍ତୀ ଚାଟ କକ୍ଷ ସଂଦେଶକୁ କୁହ ଏବଂ ବ୍ରେଇଲ କର ୤" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -" ଚାଟ କକ୍ଷର ସଂଦେଶଗୁଡିକୁ ଚାଟ କକ୍ଷର ନାମ ଦ୍ବାରା ଉପସର୍ଗୟୁକ୍ତ ଆମ୍ଭେ କରିବୁ କି ନାହିଁ ଟୋଗଲ କରେ ୤" - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -" ଚାଟ କକ୍ଷର ସଂଦେଶଗୁଡିକୁ ଚାଟ କକ୍ଷର ନାମ ଦ୍ବାରା ଉପସର୍ଗୟୁକ୍ତ ଆମ୍ଭେ କରିବୁ କି ନାହିଁ ଟୋଗଲ କରେ ୤" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "ରେଖା ବାମ" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "ରେଖା ଡାହାଣ" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "ରେଖା ଉପର" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "ରେଖା ତଳ" - -#: src/cthulhu/cmdnames.py:662 -#, fuzzy -msgid "Freeze" -msgstr "ଜମାଇ ଦିଅନ୍ତୁ" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "ଉପର ବାମପାଖ" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "ତଳ (_B):" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "ଦର୍ଶିକା ସ୍ଥିତି" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "ଦର୍ଶିକା ସ୍ଥିତି" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "ରେଖା" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "ପରବର୍ତ୍ତୀ ଅକ୍ଷରକୁ ସମତଳ ପୁନରାଲୋଚନା ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "ପୂର୍ବବର୍ତ୍ତୀ ଅକ୍ଷରକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "ପରବର୍ତ୍ତୀ ଧାଡିର ଆରମ୍ଭକୁ ସମତଳ ପୁନରାଲୋଚନା ଘୁଞ୍ଚାଏ" - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "ଧାଡିର ଶେଷକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "" -"ଗଣନା କୋଷଗୁଡିକୁ କହିବା ବେଳେ ଧାଡିକୁ ଗତିଶୀଳ ସ୍ତମ୍ଭ ଶୀର୍ଷଟୀକାଗୁଡିକ ପରି ଉପୟୋଗ କରିବା ପାଇଁ ସ୍ଥିର କର ୤" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "ଗତିଶୀଳ ସ୍ତମ୍ଭ ଶୀର୍ଷଟୀକା ପରିଷ୍କାର ହେଲା" - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"ଗଣନା କୋଷଗୁଡିକୁ କହିବା ବେଳେ ସ୍ତମ୍ଭକୁ ଗତିଶୀଳ ଧାଡି ଶୀର୍ଷଟୀକାଗୁଡିକ ପରି ଉପୟୋଗ କରିବା ପାଇଁ ସ୍ଥିର କର ୤" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "ଗତିଶୀଳ ଧାଡି ଶୀର୍ଷଟୀକା ପରିଷ୍କାର ହେଲା" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "ଇନପୁଟ ରେଖାର ବିଷଯଗୁଡିକୁ କହେ ୤" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "ଅଧିକ ବିକଳ୍ପ ପ୍ରଦର୍ଶନକର" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "ତନଖି ବାକ୍ସ" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "ତନଖି ବାକ୍ସ" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "ସମ୍ମିଳିତ ବାକ୍ସ" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "ସମ୍ମିଳିତ ବାକ୍ସ" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l ଧାରକ" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l ଧାରକ" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "ଆଉ ଅଧିକ ଶିରୋନାମ ନାହିଁ" - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "ଆଉ ଅଧିକ ଶିରୋନାମ ନାହିଁ" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "ଆଭ୍ଯନ୍ତରୀଣ ବନ୍ଧେଇ" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "ଆଭ୍ଯନ୍ତରୀଣ ବନ୍ଧେଇ" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "ରେଡିଓ ଚାବି" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "ଅଧିକ ବିକଳ୍ପ ପ୍ରଦର୍ଶନକର" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "ତାଲିକା ବସ୍ତୁ" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "ତାଲିକା ବସ୍ତୁ" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "ରେଡିଓ ଚାବି" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "କିବୋର୍ଡ ଲକ୍ଷ୍ଯ ସହିତ ବସ୍ତୁକୁ ଫେରେ ୤" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "କିବୋର୍ଡ ଲକ୍ଷ୍ଯ ସହିତ ବସ୍ତୁକୁ ଫେରେ ୤" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "ଅନୁଚ୍ଛେଦ" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "ଅନୁଚ୍ଛେଦ" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "ରେଡିଓ ଚାବି" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "ରେଡିଓ ଚାବି" - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "ରେଡିଓ ଚାବି" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "ରେଡିଓ ଚାବି" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "କୋଷକୁ ଘୁଞ୍ଚାଅ" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "କୋଷକୁ ଘୁଞ୍ଚାଅ" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "କୋଷକୁ ଘୁଞ୍ଚାଅ" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "ଟୋଗଲବଟନ" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "କି ପ୍ରତିଧ୍ବନି _ସକ୍ଷମ କର" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "କଳା" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "ଧୂସରହୋଇଥିବା" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "ସବୁଜ (_G):" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "ଡାହାଣ ବର୍ଗବନ୍ଧନୀ" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "ଡାହାଣ କଣ୍ଟ୍ରୋଲ" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "ଡାହାଣ ପାରେନ" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "ଡାହାଣ ବର୍ଗବନ୍ଧନୀ" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "ଡାହାଣ ପାରେନ" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "ଡାହାଣ ପାରେନ" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "ଡାହାଣ ଅଲ୍ଟ" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "ଡାହାଣ ପାରେନ" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "ନୂଆରେଖା" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "ପ୍ରତିଛବି" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "ଶେଷ" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "ଟ୍ଯାବ" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "ଧଳା ଅନ୍ତର" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "ଧଳା ଅନ୍ତର" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "ସମ୍ପୁର୍ଣ୍ଣ ପରଦା ପ୍ରଦର୍ଶନ" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "ଚିତ୍ର ସଙ୍କେତ" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "କିଛି ନୁହେଁ" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "ବନାନ ଯାଞ୍ଚ କରନ୍ତୁ" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "ଶବ୍ଦ ଦ୍ବାରା ପ୍ରତିଧ୍ବନି _ସକ୍ଷମ କର" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "କାର୍ୟ୍ଯ କିଗୁଡିକୁ _ସକ୍ଷମ କର" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "ଚ_ଳିତ ସ୍ଥାନ" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "କମା" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "କି ବନ୍ଧନଗୁଡିକ" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "ପୂର୍ବ ନିର୍ଦ୍ଧାରିତ" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "ଶିକ୍ଷା ମୋଡରୁ ପ୍ରସ୍ଥାନ କରୁଛି ୤" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "ଅଂଶ" - -#: src/cthulhu/guilabels.py:296 -#, fuzzy -msgid "Braille Bindings" -msgstr "ବ୍ରେଇଲ ବନ୍ଧନଗୁଡିକ" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "ପରିବର୍ତ୍ତିତ" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -#, fuzzy -msgid "_Desktop" -msgstr "_ ଡେସ୍କଟପ " - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "ଶୀର୍ଷକ" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "ଓର୍କା ପସନ୍ଦ" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "ଉଚ୍ଚାରଣ କରନ୍ତୁ" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "ସମସ୍ତ (_A)" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "ପ୍ରୟୋଗ" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "ଓ୍ବିଣ୍ଡୋ" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "କିଛି ନାହିଁ (_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "କେ_ତେକ" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "ଅ_ଧିକାଂଶ" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "ରେଖା" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -#, fuzzy -msgid "Sentence" -msgstr "କେନ୍ଦ୍ରୀଭୂତ" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "ଉଦ୍ଧୃତାଂଶ" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "ବଟନ" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "ଶିରୋନାମା" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "ଚେକ୍ ବକ୍ସ(ୟାଞ୍ଚ ବକ୍ସ)" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "ସମ୍ମିଳିତ ବାକ୍ସ" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "ଶୀର୍ଷକ" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "ଶୀର୍ଷକ" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "ଅନ୍ତବର୍ତ୍ତୀ ଫ୍ରେମ" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "ପ୍ରତିଛବି" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "ସୂଚକ" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "ଲିଙ୍କ" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "ତାଲିକା" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ତାଲିକା ସାମଗ୍ରୀ" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "ପରିଚ୍ଛେଦ" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "ରେଡିଓବଟନ" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "ଚୟିତ" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "ଅବସ୍ଥିତି" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "ପାଠ୍ଯ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "ଉଦ୍ଧୃତାଂଶ" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "ବଟନ" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "ଚେକ୍ ବକ୍ସ(ୟାଞ୍ଚ ବକ୍ସ)" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "ସମ୍ମିଳିତ ବାକ୍ସ" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "ଶୀର୍ଷକ" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "ଅନ୍ତବର୍ତ୍ତୀ ଫ୍ରେମ" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "ପ୍ରତିଛବି" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "ଲିଙ୍କ" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "ତାଲିକା" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ତାଲିକା ସାମଗ୍ରୀ" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "ପରିଚ୍ଛେଦ" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "ରେଡିଓବଟନ" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "ସାରଣୀ" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "ପୂର୍ବ ନିର୍ଦ୍ଧାରିତ" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "ସଂଯୋଗ" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "ପ୍ରତିଶତ" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "ଚଳିତ_କୋଷକୁ କଥାରେ କୁହ" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "ଗୁଣଧର୍ମ ନାମ" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "ଅ_ଳ୍ପ" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "ଅଲଟ_R" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "ବାମ କଣ୍ଟ୍ରୋଲ" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "ବାମ ସିଫ୍ଟ" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "ବାମ ଅଲ୍ଟ" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ବାମ କଣ୍ଟ୍ରୋଲ" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "ଡାହାଣ ସିଫ୍ଟ" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "ଡାହାଣ ଅଲ୍ଟ" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "ଡାହାଣ କଣ୍ଟ୍ରୋଲ" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ବାମ ମେଟା" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "ଡାହାଣ ମେଟା" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "ନମ ଲକ (Num Lk)" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "କ୍ଯାପ୍ସ ଲକ (Caps Lock)" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "କ୍ଯାପ୍ସ ଲକ (Caps Lock)" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "ସ୍କ୍ରୋଲ ଲକ" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "ଗୋଟିଏ ପ୍ରୁଷ୍ଠା ଉପରକୁ (Page Up)" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "ଗୋଟିଏ ପ୍ରୁଷ୍ଠା ତଳକୁ (Page Down)" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "ବାମ ଟାବ" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "ପଛକୁ (Backspace)" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "ପ୍ରବେଶ କରନ୍ତୁ" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "ଉପର" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "ତଳ" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "ବାମ" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "ଡାହାଣ" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "ମେନୁ" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ସାହାୟ୍ଯ" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "ବାହାରକୁ ବାହାରି ଯାଆନ୍ତୁ" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -#, fuzzy -msgid "insert" -msgstr "ତାଲିକା" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -#, fuzzy -msgid "delete" -msgstr "ବିଲୋପ କର" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "ମୂଳସ୍ଥାନ" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "ଶେଷ" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "ବର୍ଣ୍ଣମାଳା ଚିହ୍ନ" - -#: src/cthulhu/keynames.py:305 -#, fuzzy -msgid "minus" -msgstr "ବିଯୋଗ" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "ତାଲିକା" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "କ୍ଯାପସ୍ _ଲକ" - -#: src/cthulhu/keybindings.py:166 -#, fuzzy -msgid "Alt_R" -msgstr "ଅଲଟ_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "ମେଟା2" - -#: src/cthulhu/keybindings.py:183 -#, fuzzy -msgid "Alt_L" -msgstr "ଅଲ୍ଟ_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "ମୋଟା" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "ତେର୍ଛା" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "କାର୍ୟ୍ଯସ୍ଥାନ" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "ବାମପାରେନ" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "ତୀର" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "ଡାହାଣ ପାରେନ" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "ତୀର" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "ଡାହାଣ କଣ୍ଟ୍ରୋଲ" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "ବିଯୋଗ" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "କ୍ଷୁଦ୍ରତର" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "ବ୍ରୁହତର" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "ବିନ୍ଦୁ" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "ସ୍ବଂୟ ସମାପ୍ତି" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "ଖାଲି" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "ୟୋଗଚିହ୍ନ" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "ବିଯୋଗ" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "ବିଭାଜକ" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "ସମାନୁପାତିକ" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "ଡାହାଣ ଅଲ୍ଟ" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "ବହୁସ୍ତର ଝରକା" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "ବିଭାଜକ" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "ଡିରେକ୍ଟୋରି ଝରକା" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "ଆଭ୍ଯନ୍ତରୀଣ ବନ୍ଧେଇ" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "ସମାନୁପାତିକ" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "ବିଯୋଗ" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "ଟିଲଡେ" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "ଟିଲଡେ" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "ଟିଲଡେ" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "ସମାନ ଚିହ୍ନ" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "ସମାନ ଚିହ୍ନ" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "ସମାନ ଚିହ୍ନ" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "ସମାନ ନୁହେଁ" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "ବ୍ରୁହତର" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "ଦବାୟାଇ ନାହିଁ" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ଚୟିତ ହୋଇନାହିଁ" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "ଖାଲି ସ୍ଥାନ" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "ଚୟିତ ହୋଇନାହିଁ" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "ଚୟିତ ହୋଇନାହିଁ" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "ସମାନ ଚିହ୍ନ" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "ଡ୍ଯାସ" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "ଡାହାଣ ମେଟା" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "ବାମ ଟାବ" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "ତଳ" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "ଅଂଶ" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ଡାଏଲ" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "ଚିତ୍ର" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "ଆଭ୍ଯନ୍ତରୀଣ ବନ୍ଧେଇ" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "ସାଧାରଣ" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ଡାହାଣ ଅଲ୍ଟ" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "ଡାହାଣ ବର୍ଗବନ୍ଧନୀ" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "ବିଭାଜକ" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "ଡିରେକ୍ଟୋରି ଝରକା" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "ଠାରୁ କମ୍ କିମ୍ବା ସମାନ" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "ଠାରୁ ଅତ୍ଯଧିକ କିମ୍ବା ର ସମାନ" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ବାମପାରେନ" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "ଡାହାଣ ପାରେନ" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "ବାମ ଅଲ୍ଟ" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "ଡାହାଣ ଅଲ୍ଟ" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "ବାମ ବର୍ଗବନ୍ଧନୀ" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "ତଳ" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "ବାମ ବନ୍ଧନୀ" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "ଡାହାଣ ବନ୍ଧନୀ" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "ଧଳା ଅନ୍ତର" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "ଧଳା ଅନ୍ତର" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "ଧଳା ଅନ୍ତର" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "ଅବରେଖନ" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "ପ୍ରୟୋଗ" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "ଖାଲି" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "ମୋଟା" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "କୌଣସି ଫାଇଲ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "ସ୍ଟ୍ରିଙ୍ଗ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ଚିତ୍ରସଙ୍କେତ" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "କିଛି ନୁହେଁ" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "ବନାନ ଯାଞ୍ଚ କରନ୍ତୁ" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "ଚୟିତ" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "ଚୟିତ ହୋଇନାହିଁ" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "ଅମନୋନୀତହେଲା" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "ଏହି ସହାୟତା ସନ୍ଦେଶ ଦେଖାନ୍ତୁ" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "ଓର୍କା ପସନ୍ଦ" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr " https://groups.io/g/stormux. କୁ ବଗ୍ ଗୁଡିକ ସୂଚନା ଜଣାଅ" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "ଦ୍ରୁତତର" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "ଚାଟକକ୍ଷର ନାମ କହ ନାହିଁ ୤" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "ଚାଟ କକ୍ଷ ନାମ କୁହ ୤" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "ବିଲୋପ କର" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "ତାଲିକା" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "ପ୍ରଶ୍ନ" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "h t m l ଧାରକ" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "h t m l ଧାରକ" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "ଚୟିତ ହୋଇନାହିଁ" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "ସ୍ଟ୍ରିଙ୍ଗ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "ସମଗ୍ର ଦଲିଲ ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "ସମଗ୍ର ଦଲିଲ ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "କର୍ସର ସ୍ଥାନରୁ ଦଲିଲ ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "କର୍ସର ସ୍ଥାନକୁ ଦଲିଲ ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -#, fuzzy -msgid "Dynamic column header cleared." -msgstr "ଗତିଶୀଳ ସ୍ତମ୍ଭ ଶୀର୍ଷଟୀକା ପରିଷ୍କାର ହେଲା" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "ଗତିଶୀଳ ଧାଡି ଶୀର୍ଷଟୀକା ସ୍ତମ୍ଭ ନିମନ୍ତେ ସ୍ଥିର ହୋଇଛି%s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "ଗତିଶୀଳ ଧାଡି ଶୀର୍ଷଟୀକା ପରିଷ୍କାର ହେଲା" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ଖାଲି" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "କୌଣସି ଫାଇଲ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "ସମତଳ ପୁନରାଲୋଚନା ମୋଡକୁ ପ୍ରବେଶ ଏବଂ ପ୍ରସ୍ଥାନ କରେ ୤" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "ଚଳିତ ଶବ୍ଦର ଉପର ଶବ୍ଦକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "ସଂଳାପ" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "ପପ-ଅପ ତାଲିକା" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "କି ଧରାପଡିଲା : %s ୤ ସୁନିଶ୍ଚିତ କରିବା ପାଇଁ ଏଣ୍ଟର ଦବାଅ" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "ନୂଆ କି ହେଉଛି : %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "ନୂଆ କି ପ୍ରବିଷ୍ଟ କର" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "କିଛି ନୁହେଁ" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "କେନ୍ଦ୍ରୀଭୂତ" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "ଶବ୍ଦ" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "ଏବଂ" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "ମୂଳ ଝରକା" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "ମୂଳ ଝରକା" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "ମୂଳ ଝରକା" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "ଖାଲି ସ୍ଥାନ" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "ଅବରେଖନ" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "ସାରଣୀ" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "ଅପ୍ରବେଶୟୋଗ୍ଯ" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "ସାରଣୀ" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "_ଅନୁଚ୍ଛେଦକରଣ ଏବଂ ନ୍ଯାଯୋଚିତକରଣ କହ" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "ସାରଣୀ" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "_ଅନୁଚ୍ଛେଦକରଣ ଏବଂ ନ୍ଯାଯୋଚିତକରଣ କହ" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "ଶିକ୍ଷା ମୋଡ ୤ ପ୍ରସ୍ଥାନ କରିବା ପାଇଁ ଏସ୍କେପ କିକୁ ଦବାଅ ୤" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "ଜୀବନାୟନ" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "କର୍ସର ସ୍ଥାନରୁ ତଳକୁ ଧାଡି ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "କର୍ସର ସ୍ଥାନରୁ ଧାଡି ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "ଶିକ୍ଷା ମୋଡରୁ ପ୍ରସ୍ଥାନ କରୁଛି ୤" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ସଂଯୋଗ" - -#: src/cthulhu/messages.py:1518 -#, fuzzy -msgid "same page" -msgstr "ପୃଷ୍ଠା" - -#: src/cthulhu/messages.py:1522 -#, fuzzy -msgid "same site" -msgstr "ମେନୁ ବସ୍ତୁ" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, fuzzy, python-format -msgid "%s link" -msgstr "ସଂଯୋଗ" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "ସଂଯୋଗ" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "କୌଣସି ଫାଇଲ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "ଚ_ଳିତ ସ୍ଥାନ" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "ବନ୍ଦ" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "ଅନ" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "ଭୁଲ ବନାନ ଥିବା ଶବ୍ଦ:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "କଥା କହିବା ଅକ୍ଷମ ହେଲା" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "କଥା କହିବା ସକ୍ଷମ ହେଲା" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "ବାମପାରେନ" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "ପ୍ରୟୋଗ" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "କୌଣସି ଫୋକସ ନାହିଁ" - -#: src/cthulhu/messages.py:1867 -#, fuzzy -msgid "No application has focus." -msgstr "ପ୍ରୟୋଗ" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "ଅଦଳବଦଳ ଚାବି" - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "ତନଖି ବାକ୍ସ" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "ସମ୍ମିଳିତ ବାକ୍ସ" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "ଆଉ ଅଧିକ ଶିରୋନାମ ନାହିଁ" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "ଆଭ୍ଯନ୍ତରୀଣ ବନ୍ଧେଇ" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "ଆଉ ଅଧିକ ଶିରୋନାମ ନାହିଁ" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "ତାଲିକା ବସ୍ତୁ" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "ଅନୁଚ୍ଛେଦ" - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "ରେଡିଓ ଚାବି" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "ଅନୁଚ୍ଛେଦ" - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "ବୃକ୍ଷ ସାରଣୀ" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "ମନୋନୀତ ହୋଇନାହିଁ" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "ଶୀର୍ଷକ" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "ତଳ (_B):" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "ଉପର (_T):" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "ଶବ୍ଦ" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "ବନ୍ଦ" - -#: src/cthulhu/messages.py:2051 -#, fuzzy -msgid "on" -msgstr "ଅନ" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "କର୍ସର ସ୍ଥାନରୁ ପୃଷ୍ଠା ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "କର୍ସର ସ୍ଥାନକୁ ପୃଷ୍ଠା ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "କର୍ସର ସ୍ଥାନରୁ ପୃଷ୍ଠା ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "କର୍ସର ସ୍ଥାନରୁ ପୃଷ୍ଠା ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "କର୍ସର ସ୍ଥାନରୁ ପୃଷ୍ଠା ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "କର୍ସର ସ୍ଥାନରୁ ପୃଷ୍ଠା ମନୋନୀତ ହେଲା" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "କୌଣସି ଫାଇଲ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:2151 -#, fuzzy, python-format -msgid "Progress bar %d." -msgstr "ପ୍ରଗତି ସୂଚକ" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "ସମସ୍ତ (_A)" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr " ବିରାମଚିହ୍ନ ସ୍ତର" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "କିଛି ନୁହେଁ" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "ଖୋଜୁଛି" - -#: src/cthulhu/messages.py:2207 -#, fuzzy -msgid "Search complete." -msgstr "ତଦନ୍ତ ସଂପୂର୍ଣ୍ଣ ହୋଇଛି" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "ଓର୍କା ଉପୟୋଗ କର୍ତ୍ତା ସେଟିଙ୍ଗ ଗୁଡିକ ପୁନଃ ଲୋଡ ହେଲା" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "ଇଚ୍ଛିତ କଣ୍ଠସ୍ବର ମନୋନୀତ କର:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "ଅମନୋନୀତହେଲା" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "କଥା କହିବା ଅକ୍ଷମ ହେଲା" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "କଥା କହିବା ସକ୍ଷମ ହେଲା" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "ଦ୍ରୁତତର" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "ଅତି ଧୀର" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "ଉଚ୍ଚତର" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "ନିମ୍ନତର" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "ଦ୍ରୁତତର" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "ହାର (_R):" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "ଭଲ୍ଯୁ_ମ:" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "କୌଣସି ସରଭର ଉପଲବ୍ଧ ନାହିଁ ୤\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "କୌଣସି କଣ୍ଠସ୍ବର ଉପଲବ୍ଧ ନାହିଁ ୤ \n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "କଥା କହିବା ସକ୍ଷମ ହେଲା" - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "କଥା କହିବା ଉପୟୋଗ ହେବ ନାହିଁ ୤ \n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "ବିନ୍ଦୁ ବିନ୍ଦୁ ବିନ୍ଦୁ" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "ଓର୍କା ପସନ୍ଦ" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "କଥା କହିବା ଅନୁପଲବ୍ଧ ଅଛି ୤" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "କୌଣସି ଫାଇଲ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "ସ୍ଟ୍ରିଙ୍ଗ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "ସ୍ଟ୍ରିଙ୍ଗ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "କୌଣସି ଫାଇଲ ମିଳିଲା ନାହିଁ" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "ସାରଣୀ" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ସ୍ତମ୍ଭ ଶୀର୍ଷଟୀକା" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, fuzzy, python-format -msgid "column %d" -msgstr "ସ୍ତମ୍ଭ %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "ଅମନୋନୀତହେଲା" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "ଅମନୋନୀତହେଲା" - -#: src/cthulhu/messages.py:2458 -#, fuzzy, python-format -msgid "row %d" -msgstr "ଧାଡି %d" - -#: src/cthulhu/messages.py:2462 -#, fuzzy, python-format -msgid "row %(index)d of %(total)d" -msgstr "ଧାଡି %d ର %d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "ବିଲୋପ କର" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -#, fuzzy -msgid "Row inserted." -msgstr "ତାଲିକା" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "ଧାଡିର ଶେଷକୁ ସମତଳ ପୁନରାଲୋଚନାକୁ ଘୁଞ୍ଚାଏ ୤" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "ମନୋନୀତ ହୋଇନାହିଁ" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "ଅମନୋନୀତହେଲା" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "ଚୟିତ" - -#: src/cthulhu/messages.py:2521 -#, fuzzy -msgctxt "text" -msgid "unselected" -msgstr "ଅମନୋନୀତହେଲା" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "ଓର୍କା ପସନ୍ଦ" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "ଧଳା ଅନ୍ତର" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -#, fuzzy -msgid "0 items" -msgstr "୦ ସାମଗ୍ରୀ" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "ସ୍ତମ୍ଭ %d" -msgstr[1] "ସ୍ତମ୍ଭ %d" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "ସଂଳାପ" -msgstr[1] "ସଂଳାପ" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d ବାଇଟ" -msgstr[1] "%d ବାଇଟ" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ଫାଇଲ ମିଳିଲା" -msgstr[1] "%d ଫାଇଲ ମିଳିଲା" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d ବସ୍ତୁ" -msgstr[1] "%d ବସ୍ତୁ" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d ଫାଇଲ ମିଳିଲା" -msgstr[1] "%d ଫାଇଲ ମିଳିଲା" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "ଟେବୁଲ ଛାଡୁଛି" -msgstr[1] "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "ଟେବୁଲ ଛାଡୁଛି" -msgstr[1] "ଟେବୁଲ ଛାଡୁଛି" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "ତାଲିକା ବସ୍ତୁ" -msgstr[1] "ତାଲିକା ବସ୍ତୁ" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "ତାଲିକା ବସ୍ତୁ" -msgstr[1] "ତାଲିକା ବସ୍ତୁ" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "ଧାଡି %d ଏବଂ %d ସ୍ତମ୍ଭଗୁଡିକ ସହିତ ଟେବୁଲ ୤" -msgstr[1] "ଧାଡି %d ଏବଂ %d ସ୍ତମ୍ଭଗୁଡିକ ସହିତ ଟେବୁଲ ୤" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "ପିକ୍ସେଲ" -msgstr[1] "ପିକ୍ସେଲ" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "ଖାଲି ସ୍ଥାନ" -msgstr[1] "ଖାଲି ସ୍ଥାନ" - -#: src/cthulhu/messages.py:2813 -#, fuzzy, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "ଟ୍ଯାବ" -msgstr[1] "ଟ୍ଯାବ" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "ସାରଣୀ" -msgstr[1] "ସାରଣୀ" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "ଧାଡି %d ଏବଂ %d ସ୍ତମ୍ଭଗୁଡିକ ସହିତ ଟେବୁଲ ୤" -msgstr[1] "ଧାଡି %d ଏବଂ %d ସ୍ତମ୍ଭଗୁଡିକ ସହିତ ଟେବୁଲ ୤" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "ଧାଡି %d ଏବଂ %d ସ୍ତମ୍ଭଗୁଡିକ ସହିତ ଟେବୁଲ ୤" -msgstr[1] "ଧାଡି %d ଏବଂ %d ସ୍ତମ୍ଭଗୁଡିକ ସହିତ ଟେବୁଲ ୤" - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "ଧାଡି %d ଏବଂ %d ସ୍ତମ୍ଭଗୁଡିକ ସହିତ ଟେବୁଲ ୤" -msgstr[1] "ଧାଡି %d ଏବଂ %d ସ୍ତମ୍ଭଗୁଡିକ ସହିତ ଟେବୁଲ ୤" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "ସେକେଣ୍ଡ" -msgstr[1] "ସେକେଣ୍ଡ" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "ଅଦଳବଦଳ କରନ୍ତୁ" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ବୃକ୍ଷ ସ୍ତର %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "ପ୍ରଶ୍ନ" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "ସମ୍ମିଳିତ ବାକ୍ସ" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html ବିଷଯ" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "ଶବ୍ଦ" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "ବିରାମ ଚିହ୍ନ" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "ଡିରେକ୍ଟୋରି ଝରକା" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "ଅନୁଚ୍ଛେଦ" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "ଶବ୍ଦ" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "ଡିରେକ୍ଟୋରି ଝରକା" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "ଟାବ ତାଲିକା" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "ଉଦ୍ଧୃତାଂଶ" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "html ବିଷଯ" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "ଦୃଶ୍ଯବଦଳା ପଟି" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -#, fuzzy -msgid "Icon panel" -msgstr "ପସନ୍ଦ ଝରକା" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "html ବିଷଯ" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "ଜୀବନାୟନ" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "html ବିଷଯ" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "ଜୀବନାୟନ" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "ଖୋଜୁଛି" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "ସଂଯୋଗ" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "ଘୂର୍ଣନ ଚାବି" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "ନଷ୍ଟ ହୋଇଗଲା" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "ପ୍ରସାରିତ" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -#, fuzzy -msgid "vertical" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "ଯାଞ୍ଜ କରାଗଲା" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "ୟାଞ୍ଚ ହୋଇନାହିଁ" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "ଅନ" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "ବନ୍ଦ" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "ୟାଞ୍ଚ ହୋଇନାହିଁ" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "ଦବାଗଲା" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ଦବାୟାଇ ନାହିଁ" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "ମନୋନୀତ ହୋଇନାହିଁ" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "ଚୟିତ" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "ମନୋନୀତ ହୋଇନାହିଁ" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "ମନୋନୀତ ହୋଇନାହିଁ" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ଧୂସରହୋଇଥିବା" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "ଚୟିତ ହୋଇନାହିଁ" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "ଅବୈଧ" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "ଅବୈଧ" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "ବନାନ ଯାଞ୍ଚ କରନ୍ତୁ" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "ବନାନ ଯାଞ୍ଚ କରନ୍ତୁ" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "ଅବୈଧ" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -#, fuzzy -msgid "Find" -msgstr "ଖୋଜନ୍ତୁ" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "ଓରକା ସ୍କ୍ରିନ ପାଠକ ଏବଂ ଛୋଟକୁ ବଡକରି ଦେଖାଉଥିବା ୟନ୍ତ୍ର" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "ବନ୍ଦ କର" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "ଖୋଜନ୍ତୁ" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "ଏଥିପାଇଁ ସନ୍ଧାନ କରନ୍ତୁ (_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -#, fuzzy -msgid "Search for:" -msgstr "ପାଇଁ ଖୋଜ:" - -#: src/cthulhu/cthulhu-find.ui:166 -#, fuzzy -msgid "_Top of window" -msgstr "_ ଉଇଣ୍ଡୋର ଉପରେ" - -#: src/cthulhu/cthulhu-find.ui:175 -#, fuzzy -msgid "Top of window" -msgstr "ଉଇଣ୍ଡୋର ଉପରେ" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "ଠାରୁ ଆରମ୍ଭ କର:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "ଆର ଧାଡ଼ିକି ମୋଡ଼ନ୍ତୁ (_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "ପଛୁଆ ଖୋଜନ୍ତୁ (_b)" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "ଡିରେକ୍ଟୋରି ଝରକା" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "ଅକ୍ଷର ପ୍ରକାର ମିଳାନ୍ତୁ (_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "କେବଳ ସଂପୂର୍ଣ୍ଣ ଶବ୍ଦ ମିଳାନ୍ତୁ (_e)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "ବିକଳ୍ପପ୍ଯାନ" - -#: src/cthulhu/cthulhu-setup.ui:43 -#, fuzzy -msgid "Default" -msgstr "ପୂର୍ବ ନିର୍ଦ୍ଧାରିତ" - -#: src/cthulhu/cthulhu-setup.ui:46 -#, fuzzy -msgid "Uppercase" -msgstr "ପ୍ରତିଶତ" - -#: src/cthulhu/cthulhu-setup.ui:49 -#, fuzzy -msgid "Hyperlink" -msgstr "ସଂଯୋଗ" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "ପ୍ରୟୋଗ" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "ଓ୍ବିଣ୍ଡୋ" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "ଓର୍କା ପସନ୍ଦ" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_ଲାପଟପ" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "କିବୋର୍ଡ ବିରଚନାଗୁଡିକ" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "ଠାରୁ ଆରମ୍ଭ କର:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "ପ୍ରଗତି ସୂଚକ" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "ବ୍ରେଇଲ ବନ୍ଧନଗୁଡିକ" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "ପ୍ରୟୋଗ" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "ପ୍ରଗତି ସୂଚକ" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "ସାଧାରଣ" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "ଭଲ୍ଯୁ_ମ:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "ସ୍ବର ମାତ୍ରା (_t):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "ହାର (_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_ବ୍ଯକ୍ତି:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "କଥାକହିବା ସଂଶ୍ଳେଷଣ_କାରକ:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "କଥା କହିବା_ ପ୍ରଣାଳୀ:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "_କଣ୍ଠସ୍ବର ସେଟିଙ୍ଗଗୁଡିକ:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "_କଣ୍ଠସ୍ବର ସେଟିଙ୍ଗଗୁଡିକ:" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "_କଣ୍ଠସ୍ବର ସେଟିଙ୍ଗଗୁଡିକ:" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_କଥା କହିବା ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "ଆବଶ୍ଯକତାରୁ ଅଧିକ _କହିବା" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "ଆବଶ୍ଯକତାରୁ ଅଧିକ ଶବ୍ଦ ଉପୟୋଗ" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "ସମସ୍ତ (_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr " ବିରାମଚିହ୍ନ ସ୍ତର" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "ଖାଲି ରେଖାଗୁଡିକୁ କହ" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "_ଅନୁଚ୍ଛେଦକରଣ ଏବଂ ନ୍ଯାଯୋଚିତକରଣ କହ" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "ଖାଲି ରେଖାଗୁଡିକୁ କହ" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "ବକ୍ତବ୍ଯ" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "ବ୍ରେଇଲ ସମର୍ଥନ _ ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_ସଂକ୍ଷିପ୍ତ ହୋଇଥିବା ପାତ୍ର ନାମଗୁଡିକ" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "ଶବ୍ଦ ଦ୍ବାରା ପ୍ରତିଧ୍ବନି _ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "ଅଧିକ ବିକଳ୍ପ ପ୍ରଦର୍ଶନକର" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "କିଛି ନାହିଁ (_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "ମ୍ଯାଗନିଫାଯର _ ସକ୍ଷମ କର" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ବ୍ରେଲ" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "କି ପ୍ରତିଧ୍ବନି _ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "କାର୍ୟ୍ଯ କିଗୁଡିକୁ _ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "ପରିବର୍ତ୍ତକ କିଗୁଡିକୁ _ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "କାର୍ୟ୍ଯ କି ଗୁଡିକୁ _ ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "_କଥା କହିବା ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "ପରିବର୍ତ୍ତକ କିଗୁଡିକୁ _ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "କାର୍ୟ୍ଯ କି ଗୁଡିକୁ _ ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "କାର୍ୟ୍ଯ କିଗୁଡିକୁ _ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "ଶବ୍ଦ ଦ୍ବାରା ପ୍ରତିଧ୍ବନି _ସକ୍ଷମ କର" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "କି ପ୍ରତିଧ୍ବନି" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "ଓର୍କା _ପରିବର୍ତ୍ତକ କି(ଗୁଡିକ):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "କି ବନ୍ଧନଗୁଡିକ" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "ଜୀବନାୟନ" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -#, fuzzy -msgid "_Delete" -msgstr "ଅପସାରଣ କରନ୍ତୁ (_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -#, fuzzy -msgid "Pronunciation" -msgstr "ଜୀବନାୟନ" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_ପୁନଃସ୍ଥିରକର" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "ଟେକ୍ସଟ ଗୁଣଗୁଡିକ" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "ବ୍ରେଇଲ ବନ୍ଧନଗୁଡିକ" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "ଟେକ୍ସଟ ଗୁଣଗୁଡିକ" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "ସହକାରୀ" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "ନିମ୍ନ" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "ସହକାରୀ" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "ଶେଷ" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "ମାପିବା _କାରଣ:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "ଡିରେକ୍ଟୋରି ଝରକା" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "ସାରଣୀ" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "ଅନୁଚ୍ଛେଦ" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "କାଲେଣ୍ଡର" - -#: src/cthulhu/text_attribute_names.py:234 -#, fuzzy -msgctxt "textattr" -msgid "size" -msgstr "ଆକାର" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "ସ୍ଟ୍ରାଇକ ଥ୍ରୁ" - -#: src/cthulhu/text_attribute_names.py:258 -#, fuzzy -msgctxt "textattr" -msgid "style" -msgstr "ସାରଣୀ" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "ଅବରେଖନ" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "ଡାହାଣ (_R):" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -#, fuzzy -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -#, fuzzy -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -#, fuzzy -msgctxt "textattr" -msgid "none" -msgstr "କିଛି ନୁହେଁ" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "ଭୂଲମ୍ବ ରେଖା" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "ସଂଯୋଗ" - -#: src/cthulhu/text_attribute_names.py:407 -#, fuzzy -msgctxt "textattr" -msgid "black" -msgstr "କଳା" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "ନିମ୍ନ" - -#: src/cthulhu/text_attribute_names.py:435 -#, fuzzy -msgctxt "textattr" -msgid "char" -msgstr "ଶୀର୍ଷକ" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "ଶବ୍ଦ" - -#: src/cthulhu/text_attribute_names.py:452 -#, fuzzy -msgctxt "textattr" -msgid "word char" -msgstr "ଶୀର୍ଷକ" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "ବାମ" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "ଡାହାଣ" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "କେନ୍ଦ୍ରୀଭୂତ" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "ଭରଣ ବସ୍ତୁ" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -#, fuzzy -msgctxt "textattr" -msgid "extra condensed" -msgstr "ପ୍ରସାରିତ" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "ଅର୍ଦ୍ଧବିରାମ ଚିହ୍ନ" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "ସାଧାରଣ" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "ପ୍ରସାରିତ" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "ପ୍ରସାରିତ" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "ପ୍ରସାରିତ" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ପ୍ରସାରିତ" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "ଅସ୍ବଚ୍ଛ" - -#: src/cthulhu/text_attribute_names.py:584 -#, fuzzy -msgctxt "textattr" -msgid "italic" -msgstr "ତେର୍ଛା" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "ପୂର୍ବ ନିର୍ଦ୍ଧାରିତ" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "ଟେକ୍ସଟ ଭାଗ" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "ଶୀର୍ଷକ" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -#, fuzzy -msgctxt "textattr" -msgid "super" -msgstr "ଖାଲି ସ୍ଥାନ" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "ଉପର" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "ପାଠ୍ଯ" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "ତଳ" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -#, fuzzy -msgctxt "textattr" -msgid "lr-tb" -msgstr "ସତର୍କ" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -#, fuzzy -msgctxt "textattr" -msgid "tb-rl" -msgstr "ସାରଣୀ" - -#: src/cthulhu/text_attribute_names.py:698 -#, fuzzy -msgctxt "textattr" -msgid "tb-lr" -msgstr "ସାରଣୀ" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "ଟ୍ଯାବ" - -#: src/cthulhu/text_attribute_names.py:738 -#, fuzzy -msgctxt "textattr" -msgid "solid" -msgstr "ସର୍ପକ" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "ବନାନ ଯାଞ୍ଚ କରନ୍ତୁ" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/pa.po b/po/pa.po deleted file mode 100644 index fd219a5..0000000 --- a/po/pa.po +++ /dev/null @@ -1,9748 +0,0 @@ -# translation of cthulhu.HEAD.po to Punjabi -# This file is distributed under the same license as the PACKAGE package. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. -# -# Amanpreet Singh Alam , 2005. -# A S Alam , 2006. -# A S Alam , 2007. -# A S Alam , 2007, 2008, 2023. -# PrithiPal Dhaliwal , 2008. -# Amanpreet Singh Alam , 2009, 2011. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-24 19:34-0700\n" -"Last-Translator: A S Alam \n" -"Language-Team: Punjabi \n" -"Language: pa\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 23.04.3\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Poedit-Bookmarks: 589,-1,-1,-1,-1,-1,-1,-1,-1,-1\n" - -msgid "Cthulhu Screen Reader" -msgstr "ਓਰਕਾ ਸਕਰੀਨ ਰੀਡਰ" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "ਚੇਤਾਵਨੀ" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "ਕੈਲੰ" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "ਮਿਤੀ" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "ਫਰੇਮ" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "ਡਾਇਲ" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "ਡਿਪ" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "ਡਰਾਇੰਗ" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "ਵਲੋਂ" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "ਚਿੱਤਰ" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "ਸਿਆਹੀ" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "ਮੇਨੂ" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "ਰੇਡੀਓ" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "ਸੰਕੇਤ" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "ਪ੍ਹੈਰਾ" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "ਆਟੋ" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "ਚੈੱਕ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "ਸਪੇਨੀ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "ਕਨੇਡਾ ਫਰੈਂਚ ਗਰੇਡ ੨" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "ਫਰਾਂਸ ਫਰੈਂਚ ਗਰੇਡ ੨ " - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "ਲਿਬੀਆ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "ਨੀਂਦਰਲੈਂਡ ਡੱਚ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "ਨੋਰਵੇਜਿਨ ਗਰੇਡ 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "ਨੋਰਵੇਜਿਨ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "ਨੋਰਵੇਜਿਨ ਗਰੇਡ ੨" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "ਨੋਰਵੇਜਿਨ ਗਰੇਡ 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "ਪੋਲੈਂਡ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "ਪੁਰਤਗਾਲੀ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "ਸਵੀਡਨ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "ਅਰਬੀ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "ਵੇਲਿਸ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "ਵੇਲਿਸ ਗਰੇਡ ੨" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "ਜਰਮਨ ਗਰੇਡ 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "ਜਰਮਨ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "ਜਰਮਨ ਗਰੇਡ ੨" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "ਇੰਗਲੈਂਡ ਅੰਗਰੇਜੀ ਗਰੇਡ ੨" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "ਇੰਗਲੈਂਡ ਅੰਗਰੇਜੀ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "ਅਮਰੀਕਾ ਅੰਗਰੇਜੀ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "ਅਮਰੀਕਾ ਅੰਗਰੇਜੀ ਗਰੇਡ ੨" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "ਕਨੇਡਾ ਫਰੈਂਚ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "ਫਰਾਂਸ ਫਰੈਚ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "ਗਰੀਕ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "ਹਿੰਦੀ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "ਹੰਗਰੀਆਈ ਗਰੇਡ 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "ਹੰਗਰੀਆਈ ਗਰੇਡ 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "ਇਤਾਲਵੀ ਗਰੇਡ ੧" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "ਬੈਲਜੀਅਮ ਡੱਚ ਗਰੇਡ ੧" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "ਖਾਲੀ ਥਾਂ" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "ਨਵੀਂਸਤਰ" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "ਟੈਬ" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "ਹੈਰਾਨੀਵਾਚਕ" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "ਕਾਮੇ" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "ਨੰਬਰ" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "ਡਾਲਰ" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "ਫ਼ੀ-ਸਦੀ" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ਅਤੇ" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "ਅਪੋਸਟਰੋਫੇ" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "ਖੱਬੀ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "ਤਾਰਾ" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "ਜੋੜ" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "ਕਾਮਾ" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "ਡੈਸ਼" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "ਬਿੰਦੀ" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "ਸਲੇਸ਼" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "ਕੋਲਨ" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "ਅਰਧ-ਕੋਲਮ" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "ਘੱਟ" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "ਸਮਾਨ" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "ਵੱਧ" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "ਸਵਾਲੀਆ" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "ਐਟ" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "ਖੱਬੀ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "ਬੈਕ-ਸਲੇਸ਼" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "ਸੱਜੀ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "ਕੈਰਟ" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "ਹੇਠਾਂ ਸਤਰ" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "ਗਰੇਇਵ ਕੀਤਾ" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "ਖੱਬੀ ਛੋਟੀ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "ਵਰਟੀਕਲ ਬਾਰ" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "ਟੀਲਡ" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "ਕੋਈ ਬਰੇਕ ਸਪੇਸ ਨਹੀਂ" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "ਉੱਲਟ ਹੈਰਾਨੀਜਨਕ ਪੁੰਆਇੰਟ।" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "ਸੈਂਟ" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr " ਪਾਊਂਡ" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "ਕਰੰਸੀ ਸਾਈਨ" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "ਯੇਨ" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "ਟੁੱਟੀ ਪੱਟੀ" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "ਭਾਗ" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "ਡਿਗਰੀ" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "ਕਾਪੀਰਾਈਟ" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "ਘਾਤ" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "ਖੱਬੇ ਡਬਲ ਕੋਣੀ ਬਰੈਕਟ " - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "ਲਾਜੀਕਲ NOT" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr " ਸੌਫਟ ਹਾਈਫਨ" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "ਰਜਿਸਟਰਡ" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "ਮਾਈਕਰੋਨ" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "ਡਿਗਰੀ" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "ਜੋੜ ਜਾਂ ਘਟਾਓ" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "ਸੁਪਰਸਕਰਿਪਟ ੨" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "ਸੁਪਰਸਕਰਿਪਟ 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "ਏਕਿਊਟ" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "ਮੂ" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "ਪ੍ਹੈਰਾਗਰਾਫ ਮੇਕਰ" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "ਵਿਚਕਾਰ ਬਿਂਦੀ" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "ਸੈਡੀਲਾ" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "ਸੁਪਰਸਕਰਿਪਟ ੧" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ਆਰਡੀਨਲ" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "ਸੱਜੇ ਡਬਲ ਐਂਗਲ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "ਇੱਕ ਚੌਥਾਈ" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "ਅੱਧਾ" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "ਤਿੰਨ ਚੌਥਾਈ" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "ਉਲਟ ਸਵਾਲੀਆ ਚਿੰਨ" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "ਏਕਿਊਟ" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "ਏਗਰੇਵ" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "ਟਾਈਮ" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s ਸਾਰਪ" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "ਏਗਰੇਵ" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "ਸਰਕਮਪਲਿਕਸ" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "ਏਟੀਲਡ" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "ਏਮਲੌਟ" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "ਏਰਿੰਗ" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ਏ ਈ" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "ਸੈਡੀਲਾ" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "ਏਗਰੇਵ" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "ਏਕਿਊਟ" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "ਸਰਕਮਪਲਿਕਸ" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "ਏਮਲੌਟ" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "ਆਈ ਗਰੇਵ" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "ਏਕਿਊਟ" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "ਸਰਕਮਪਲਿਕਸ" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "ਅਮਲੌਟ" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "ਇਥ" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "ਇਨ ਟੀਲਡ" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "ਓ ਗਰੇਵ " - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "ਓ ਕਿਊਟ" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "ਸਰਕਮਪਲਿਕਸ" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "ਓ ਟੀਲਡ" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "ਓ ਅਮਲੌਟ" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "ਇਸ ਨਾਲ ਭਾਗ" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "ਓ ਸਟਰੋਕ" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "ਥੋਰਨ" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "ਏਕਿਊਟ" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "ਏਗਰੇਵ" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "ਸਰਕਮਫਲਿਕਸ" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "ਏ ਅਮਲੌਟ" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "ਵਾਈ ਏਕਿਊਟ" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "ਵਾਈ ਅਮਲੌਟ" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "ਫਲੋਰਿਨ" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "ਇਨ ਡੈਸ਼" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "ਖੱਬੇ ਸਿੰਗਲ ਕੋਟ" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "ਸੱਜੇ ਸਿੰਗਲ ਕੋਟ " - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "ਇੱਕਲਾ ਘੱਟ ਕੋਟ" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "ਖੱਬੇ ਡਬਲ ਕੋਟ" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "ਸੱਜੇ ਡਬਲ ਕੋਟ" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "ਡਬਲ ਘੱਟ ਕੋਟ" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "ਡੱਜਰ" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "ਡਬਲ ਡੱਜਰ" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "ਬੁੱਲਿਟ" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "ਤਿੰਨ-ਐਂਗਲ ਬੁਲਿੱਟ" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "ਪਰ ਮੀਲ" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "ਪਰਾਈਮ" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "ਦੂਹਰਾ ਪਰਾਈਮ" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "ਤੀਹਰਾ ਪਰਾਈਮ" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "ਹਾਏਫਨ ਬੁਲਿੱਟ" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "ਈਯੁਰੂ" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "ਟਰੇਡਮਾਰਕ" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "ਚੈੱਕ ਮਾਰਕ" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "ਹੈਵੀ ਚੈੱਕ ਮਾਰਕ" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "ਐਕਸ-ਸੇਪਡ ਬੁਲਿੱਟ" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "ਘਾਤ 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "ਘਾਤ 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "ਘਾਤ 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "ਘਾਤ 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "ਘਾਤ 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "ਘਾਤ 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "ਘਾਤ 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "ਘਾਤ ਜੋੜ" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "ਘਾਤ ਘਟਾਓ" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "ਘਾਤ ਬਰਾਬਰ" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "ਘਾਤ ਖੱਬੀ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "ਘਾਤ ਸੱਜੀ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "ਘਾਤ n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "ਪੈਰ ਵਿੱਚ 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "ਪੈਰ ਵਿੱਚ 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "ਪੈਰ ਵਿੱਚ 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "ਪੈਰ ਵਿੱਚ 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "ਪੈਰ ਵਿੱਚ 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "ਪੈਰ ਵਿੱਚ 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "ਪੈਰ ਵਿੱਚ 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "ਪੈਰ ਵਿੱਚ 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "ਪੈਰ ਵਿੱਚ 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "ਪੈਰ ਵਿੱਚ 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "ਪੈਰ ਵਿੱਚ ਜੋੜ" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "ਪੈਰ ਵਿੱਚ ਘਟਾਓ" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "ਪੈਰ ਵਿੱਚ ਬਰਾਬਰ" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "ਪੈਰ ਵਿੱਚ ਖੱਬੀ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "ਪੈਰ ਵਿੱਚ ਸੱਜੀ ਬਰੈਕਟ" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "ਕਾਲਾ ਵਰਗ" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "ਕਾਲਾ ਡਾਇਮੰਡ" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "ਆਬਜੈਕਟ ਤਬਦੀਲੀ ਅੱਖਰ" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "ਮੌਜੂਦਾ ਆਈਟਮ ਲਈ ਪੁਆਇੰਟਰ ਦਾ ਰੂਟ" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "ਮੌਜੂਦਾ ਸਮਤਲ ਝਲਕ ਆਈਟਮ ਉੱਤੇ ਖੱਬਾ ਕਲਿੱਕ ਕਰੋ" - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "ਮੌਜੂਦਾ ਸਮਤਲ ਝਲਕ ਇਕਾਈ ਉੱਤੇ ਸੱਜਾ ਕਲਿੱਕ ਕਰਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "ਪੂਰਾ ਡੌਕੂਮੈਂਟ ਬੋਲੋ" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "ਮੌਜੂਦਾ ਸਮਤਲ ਝਲਕ ਸਤਰ ਬੋਲਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "ਜਿੱਥੇ ਮੈਂ ਉਪਰੇਸਨ ਹੋਵਾਂ ਬੇਸਕ ਕਾਰਵਾਈ ਕਰਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "ਜਿੱਥੇ ਮੈਂ ਉਪਰੇਸਨ ਹੋਵਾਂ ਵੇਰਵਾ ਦਿਉ। " - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "ਮੌਜੂਦਾ ਚੋਣ ਨੂੰ ਬੋਲੋ" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "ਲਿੰਕ ਵੇਰਵੇ ਨੂੰ ਬੋਲੋ" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "ਮੂਲ ਬਟਨ ਪੇਸ਼ ਕਰੋ" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "ਹਾਲਤ ਪੱਟੀ ਪੇਸ਼ ਕਰੋ" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "ਟਾਈਟਲ ਪੱਟੀ ਪੇਸ਼ ਕਰੋ" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "ਖੋਜ ਡਾਈਲਾਗ ਖੋਲ੍ਹੋ" - -#: src/cthulhu/cmdnames.py:118 -#, fuzzy -msgid "Show actions list" -msgstr "ਅਗਲੀ ਲਿਸਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "ਇੱਕ ਸਤਰ ਦੇ ਅਗਲੇ ਭਾਗ ਲਈ ਖੋਜ ਕਰਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "ਇੱਕ ਸਤਰ ਦੇ ਪੁਰਾਣਾ ਮੌਕੇ ਲਈ ਖੋਜ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "ਸਮਤਲ ਝਲਕ ਢੰਗ ਵਿੱਚ ਦਾਖਲ ਕਰਦੀ ਅਤੇ ਬੰਦ ਕਰਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਅੰਤਮ ਥਾਂ ਉੱਤੇ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਘਰ ਥਾਂ ਉੱਤੇ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਅੰਤਮ ਥਾਂ ਉੱਤੇ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਪਿਛਲੀ ਸਤਰ ਦੇ ਸ਼ੁਰੂ ਵਿੱਚ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "ਮੌਜੂਦਾ ਸਮਤਲ ਝਲਕ ਸਤਰ ਬੋਲਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "ਮੌਜੂਦਾ ਫਲੈਟ ਰਵਿਊ ਲਾਈਨ ਸਪੈੱਲ ਦਿਉ।" - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "ਮੌਜੂਦਾ ਫਲੈਟ ਰਵਿਊ ਫਿਨੋਟੈਕਲੀ ਸਪੈੱਲ ਦਿਉ।" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਅਗਲੀ ਸਤਰ ਦੇ ਸ਼ੁਰੂ ਵਿੱਚ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਇਕਾਈ ਜਾਂ ਸ਼ਬਦ ਤੋਂ ਪਿੱਛੇ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "ਮੌਜੂਦਾ ਫਲੈਟ ਰਵਿਊ ਆਈਟਮ ਅਤੇ ਸਬਦ ਬੋਲਦਾ ਹੈ।" - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "ਮੌਜੂਦਾ ਫਲੈਟ ਰਵਿਊ ਆਈਟਮ ਅਤੇ ਸਬਦ ਸਪੈੱਲ ਹਨ।" - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "ਮੌਜੂਦਾ ਫਲੈਟ ਰਵਿਊ ਆਈਟਮ ਅਤੇ ਸਬਦ ਫਿਨੋਟੈਕਲੀ ਸਪੈੱਲ ਹਨ।" - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਇਕਾਈ ਜਾਂ ਸ਼ਬਦ ਤੋਂ ਅੱਗੇ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਮੌਜੂਦਾ ਸ਼ਬਦ ਦੇ ਉੱਪਰ ਸ਼ਬਦ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "ਮੌਜੂਦਾ ਸਮਤਲ ਝਲਕ ਇਕਾਈ ਬੋਲਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਮੌਜੂਦਾ ਸ਼ਬਦ ਦੇ ਹੇਠਾਂ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਮੌਜੂਦ ਅੱਖਰ ਦੇ ਪਿੱਛੇ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "ਮੌਜੂਦਾ ਸਮਤਲ ਝਲਕ ਅੱਖਰ ਬੋਲਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "ਮੌਜੂਦਾ ਫਲੈਟ ਰਵਿਊ ਅੱਖਰ ਫਿਨੋਟੈਕਲੀ ਬੋਲਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "ਮੌਜੂਦਾ ਆਮ ਰੀਵਿਊ ਅੱਖਰ ਲਈ ਯੂਨੀਕੋਡ ਮੁੱਲ ਬੋਲੋ।" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਅਗਲੇ ਅੱਖਰ ਲਈ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਸਤਰ ਦੇ ਅੰਤ 'ਚ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "ਸਮਤਲ ਝਲਕ ਤੋਂ ਹੇਠਾਂ ਖੱਬੇ ਲਈ ਭੇਜੋ।" - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "ਮੌਜੂਦਾ ਫਲੈਟ ਰਵਿਊ ਆਈਟਮ ਅਤੇ ਸਬਦ ਬੋਲਦਾ ਹੈ।" - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "ਮੌਜੂਦਾ ਫਲੈਟ ਰਵਿਊ ਆਈਟਮ ਅਤੇ ਸਬਦ ਬੋਲਦਾ ਹੈ।" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਅੰਤਮ ਥਾਂ ਉੱਤੇ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "ਤਬਦੀਲ ਕਰਦੀ ਹੈ ਕਿ ਕੀ ਸਿਰਫ਼ ਮੌਜੂਦਾ ਸਾਰਣੀ ਸੈੱਲ ਨੂੰ ਪੜ੍ਹਿਆ ਜਾਵੇ ਜਾਂ ਪੂਰੀ ਕਤਾਰ ਨੂੰ।" - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "ਮੌਜੂਦਾ ਪਾਠ ਅੱਖਰ ਨਾਲ ਸਬੰਧਤ ਗੁਣ ਪੜ੍ਹਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "ਬਰਾਇੱਲੇ ਝਲਕ ਨੂੰ ਖੱਬੇ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "ਬਰਾਇੱਲੇ ਝਲਕ ਨੂੰ ਸੱਜੇ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "ਕੀ-ਬੋਰਡ ਫੋਕਸ ਨਾਲ ਇਕਾਈ ਲਈ ਵਾਪਿਸ।" - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "ਕਨਟੈਕਟਡ ਬਰੇਇਲ ਯੋਗ(_E)" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "ਟੈਕਸਟ ਚੋਣ ਲਈ ਸ਼ੁਰੂ ਦਾ ਨਿਸ਼ਾਨ ਲਗਾਉ।" - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "ਟੈਕਸਟ ਚੋਣ ਦਾ ਅੰਤ ਨਿਸ਼ਾਨ ਲਗਾਉ।" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "ਸਿੱਖਣ ਢੰਗ ਵਿੱਚ ਦਾਖਲ ਹੋਏ। ਸਿੱਖਣ ਢੰਗ ਬੰਦ ਕਰਨ ਲਈ Escape ਦਬਾਓ।" - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "ਧੁਨੀ ਦਰ ਘਟਾਓ।" - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "ਧੁਨੀ ਦਰ ਵਧਾਓ।" - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "ਧੁਨੀ ਪਿੱਚ ਘਟਾਓ।" - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "ਧੁਨੀ ਪਿੱਚ ਵਧਾਓ।" - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "ਧੁਨੀ ਦਰ ਵਧਾਓ।" - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "ਧੁਨੀ ਦਰ ਘਟਾਓ।" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "ਇੱਕ ਸਤਰ ਦੇ ਪੁਰਾਣਾ ਮੌਕੇ ਲਈ ਖੋਜ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "ਅਗਲੀ ਵੱਡਦਰਸ਼ੀ ਸਥਿਤੀ ਲਈ ਜਾਰੀ ਰੱਖੋ।" - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "ਧੁਨੀ ਦਰ ਘਟਾਓ।" - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "ਧੁਨੀ ਦਰ ਵਧਾਓ।" - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "ਵਾਈਸ ਕਿਸਮ ਸੈਟਿੰਗਾਂ" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "ਧੁਨੀ ਦੀ ਚੁੱਪ ਨੂੰ ਬਦਲਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "ਮਾਊਸ ਰੀਵਿਊ ਮੋਡ ਬਦਲੋ।" - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "ਸਕਰੀਨ ਰੀਡਰ" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "ਪਸੰਦ ਸੰਰਚਨਾ ਵਾਰਤਾਲਾਪ ਵੇਖਾਉਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "ਐਪਲੀਕੇਸ਼ਨ ਕਾਰਜਗੁਜ਼ਾਰੀ ਸੰਰਚਨਾ ਡਾਈਲਾਗ ਵੇਖਾਉਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "ਬੋਲ ਦੂਰੀ ਅਤੇ ਇਕਸਾਰਤਾ(_i)" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "ਅਗਲੀ ਵੱਡਦਰਸ਼ੀ ਸਥਿਤੀ ਲਈ ਜਾਰੀ ਰੱਖੋ।" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "ਅਗਲੀ ਵੱਡਦਰਸ਼ੀ ਸਥਿਤੀ ਲਈ ਜਾਰੀ ਰੱਖੋ।" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "ਅਗਲੀ ਵੱਡਦਰਸ਼ੀ ਸਥਿਤੀ ਲਈ ਜਾਰੀ ਰੱਖੋ।" - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "ਅਗਲੀ ਵੱਡਦਰਸ਼ੀ ਸਥਿਤੀ ਲਈ ਜਾਰੀ ਰੱਖੋ।" - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "ਅਗਲੀ ਵੱਡਦਰਸ਼ੀ ਸਥਿਤੀ ਲਈ ਜਾਰੀ ਰੱਖੋ।" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "ਚੱਲਣ ਸਮੇਂ ਡੀਬੱਗ ਪੱਧਰ ਤਬਦੀਲ ਕਰਦਾ ਹੈ।" - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "ਬੁੱਕਮਾਰਕ ਜਿੱਥੇ ਮੈਂ ਮੌਜੂਦਾ ਸਥਿਤੀ ਅਨੁਸਾਰ ਹੋਵਾਂ।" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "ਪਿਛਲੀ ਬੁੱਕਮਾਰਕ ਦਿੱਖ ਤੇ ਜਾਉ।" - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "ਬੁੱਕਮਾਰਕ ਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "ਅਗਲੀ ਬੁੱਕਮਾਰਕ ਦਿੱਖ ਤੇ ਜਾਉ।" - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "ਬੁੱਕਮਾਰਕ ਜੋੜੋ।" - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "ਬੁੱਕਮਾਰਕ ਸੰਭਾਲੋ।" - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "ਮਾਊਸ ਰੀਵਿਊ ਮੋਡ ਬਦਲੋ।" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "ਅਗਲੀ ਕਮਾਂਡ ਮੌਜੂਦਾ ਐਪਲੀਕੇਸ਼ਨ ਲਈ ਭੇਜੋ।" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "ਇੱਕ ਪਿਛਲਾ ਗੱਲਬਾਤ ਰੂਮ ਸੁਨੇਹਾ ਬੋਲੋ ਅਤੇ ਬਰਾਇੱਲੀ" - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "ਜਦੋਂ ਸਾਡੇ ਦੋਸਤ ਲਿਖ ਰਹੇ ਹੋਣ ਤਾਂ ਕੀ ਅਸੀਂ ਦੱਸੀਏ ਨੂੰ ਬਦਲੋ" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "ਬਦਲੋ ਕਿ ਕੀ ਅਸੀਂ ਗੱਲਬਾਤ ਰੂਮ ਸੁਨੇਹਿਆਂ ਨੂੰ ਸੁਨੇਹਾ ਅਤੀਤ ਵਿੱਚ ਦੇਈਏ।" - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "ਬਦਲੋ ਕਿ ਕੀ ਗੱਲਬਾਤ ਰੂਮ ਸੁਨੇਹਿਆਂ ਅੱਗੇ ਗੱਲਬਾਤ ਰੂਮ ਦਾ ਜੋੜਿਆ ਜਾਵੇ।" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "ਲਾਇਨ ਖੱਬੇ" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "ਲਾਇਨ ਸੱਜੇ" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "ਲਾਇਨ ਹੇਠਾਂ" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "ਲਾਇਨ ਹੇਠਾਂ" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "ਸਥਿਰ" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "ਉੱਤੇ ਖੱਬਾ" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "ਹੇਠਾਂ ਅੱਧਾ" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "ਛੇ ਬਿੰਦੀਆਂ" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "ਕਰਸਰ ਰੂਟਿੰਗ" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "ਕੱਟ ਸ਼ੁਰੂ" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "ਕੱਟ ਲਾਈਨ" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "ਆਖਰੀ ਨੋਟੀਫਿਕੇਸ਼ਨ ਸੁਨੇਹਾ ਦਿਉ।" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "ਨੋਟੀਫਿਕੇਸ਼ਨ ਸੁਨੇਹਾ ਲਿਸਟ ਦਿਉ।" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "ਪਿਛਲਾ ਨੋਟੀਫਿਕੇਸ਼ਨ ਸੁਨੇਹਾ ਦਿਉ।" - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "ਆਖਰੀ ਨੋਟੀਫਿਕੇਸ਼ਨ ਸੁਨੇਹਾ ਦਿਉ।" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "ਅਗਲੇ ਅੱਖਰ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "ਪਿਛਲੇ ਅੱਖਰ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "ਅਗਲੇ ਸ਼ਬਦ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "ਪਿਛਲੇ ਸ਼ਬਦ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "ਅਗਲੀ ਲਾਈਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "ਪਿਛਲੀ ਲਾਈਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "ਫਾਇਲ ਦੇ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "ਫਾਇਲ ਦੇ ਤਲ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "ਲਾਈਨ ਦੇ ਸ਼ੁਰੂ ਵਿੱਚ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "ਲਾਈਨ ਦੇ ਅੰਤ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "ਅਗਲੇ ਆਬਜੈਕਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "ਪਿਛਲੇ ਆਬਜੈਕਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "ਮੌਜੂਦਾ ਕੰਬੋ ਬਾਕਸ ਨੂੰ ਫੈਲਾਉਣ ਦਾ ਕਾਰਨ ਹੈ।" - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "ਗੀਕੋ ਨੇਟਿਵ ਅਤੇ ਓਰਕਾ ਕਾਰਿਟ ਨੇਵੀਗੇਸ਼ਨ ਵਿੱਚ ਬਦਲੋ।" - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "ਮਾਹਰ ਲਾਈਵ ਖੇਤਰ ਸਭਿਅਕ ਸੈਟਿੰਗ ਹੈ।" - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "ਡਿਫਾਲਟ ਲਾਈਵ ਖੇਤਰ ਸਭਿਅਕ ਲੈਵਲ ਬੰਦ ਕਰੋ।" - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "ਲਾਈਵ ਖੇਤਰ ਐਲਾਨਾਂ ਦੀ ਜਾਂਚ ਕਰੋ।" - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "ਲਾਈਵ ਖੇਤਰ ਦੀ ਨਿਗਰਾਨੀ।" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "ਕੈਲਸ ਸੈੱਲ ਬੋਲਣ ਦੌਰਾਨ ਡਾਇਨਮਿਕ ਕਾਲਮ ਹੈਡਰ ਵਾਂਗ ਵਰਤਣ ਵਾਸਤੇ ਕਤਾਰ ਦਿਓ।" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "ਸਫ਼ਰੀ ਕਾਲਮ ਸਿਰਲੇਖ ਸਾਫ਼ ਕੀਤਾ।" - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "ਕੈਲਸ ਸੈੱਲ ਬੋਲਣ ਦੌਰਾਨ ਡਾਇਨਮਿਕ ਕਾਤਰ ਹੈਡਰ ਵਾਂਗ ਵਰਤਣ ਵਾਸਤੇ ਕਾਲਮ ਦਿਓ।" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "ਕਤਾਰ ਹੈੱਡਰ ਲਗਾਤਾਰ ਸਾਫ਼ ਕਰੋ" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "ਇਨਪੁੱਟ ਲਾਈਨ ਦੀ ਸਮੱਗਰੀ ਪੇਸ਼ ਕਰੋ।" - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "ਢਾਂਚਾ ਨੇਵੀਗੇਸ਼ਨ ਸਵਿੱਚਾਂ ਬਦਲੋ।" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "ਪਿਛਲੇ ਬਲਾਕ-ਕੋਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "ਅਗਲੇ ਬਲਾਕ-ਕੋਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "ਪਿਛਲੇ ਬਟਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "ਅਗਲੇ ਬਟਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "ਹੋਰ ਚੋਣਾਂ ਵੇਖਾਓ" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "ਪਿਛਲੇ ਚੋਣ-ਬਕਸੇ ਉੱਤੇ ਜਾਓ" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "ਅਗਲੇ ਚੋਣ ਬਾਕਸ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "ਪਿਛਲੇ ਟੇਬਲ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "ਅਗਲੇ ਟੇਬਲ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "ਪਿਛਲੇ ਕੰਬੋ ਬਾਕਸ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "ਅਗਲੇ ਕੰਬੋ ਬਾਕਸ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l container" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l container" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "ਪਿਛਲੀ ਐਂਟਰੀ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "ਪਿਛਲੀ ਐਂਟਰੀ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "ਪਿਛਲੇ ਫਾਰਮ ਖੇਤਰ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "ਅਗਲੇ ਫਾਰਮ ਖੇਤਰ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "ਪਿਛਲੇ ਹੈਡਿੰਗ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "ਅਗਲੇ ਹੈਡਿੰਗ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "ਲੈਵਲ %d ਦੇ ਪਿਛਲੇ ਹੈਡਿੰਗ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "ਲੈਵਲ %d ਦੇ ਪਿਛਲੇ ਹੈੱਡਿੰਗ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "ਲੈਵਲ %d ਉੱਤੇ ਕੋਈ ਹੋਰ ਹੈਡਿੰਗ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "ਪਿਛਲੇ ਟੇਬਲ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "ਅੰਦਰੂਨੀ ਫਰੇਮ" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "ਪਿਛਲੀ ਲਾਈਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "ਅਗਲੀ ਲਾਈਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "ਪਿਛਲੇ ਲੈਂਡਮਾਰਕ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "ਅਗਲੇ ਲੈਡਮਾਰਕ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "ਪਿਛਲੇ ਵੱਡੇ ਆਬਜੈਕਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "ਅੱਗੇ ਵੱਡੇ ਆਬਜੈਕਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "ਕੋਈ ਹੋਰ ਵੱਡਾ ਆਬਜੈਕਟ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "ਪਿਛਲੀ ਲਾਈਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "ਅਗਲੀ ਲਾਈਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "ਹੋਰ ਚੋਣਾਂ ਵੇਖਾਓ" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "ਪਿਛਲੀ ਲਿਸਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "ਅਗਲੀ ਲਿਸਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "ਪਿਛਲੀ ਲਿਸਟ ਆਈਟਮ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "ਅਗਲੀ ਲਿਸਟ ਆਈਟਮ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "ਪਿਛਲੇ ਲਾਈਨ ਖੇਤਰ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "ਅਗਲੇ ਲਾਈਵ ਖੇਤਰ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "ਲਾਈਵ ਖੇਤਰ ਐਲਾਨਾਂ ਦੀ ਜਾਂਚ ਕਰੋ।" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "ਫੋਕਸ ਹੋਈ ਆਈਟਮ ਬਾਰੇ ਅੰਸਟਰੇ ਲਈ ਡੀਬੱਗ ਜਾਣਕਾਰੀ ਛਾਪਦੀ ਹੈ।" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "ਕੀ-ਬੋਰਡ ਫੋਕਸ ਨਾਲ ਇਕਾਈ ਲਈ ਵਾਪਿਸ।" - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "ਢਾਂਚਾ ਨੇਵੀਗੇਸ਼ਨ ਸਵਿੱਚਾਂ ਬਦਲੋ।" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "ਪਿਛਲੇ ਪ੍ਹੈਰੇ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "ਅਗਲੇ ਪ੍ਹੈਰੇ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "ਪਿਛਲੇ ਰੇਡੀਓ ਬਟਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "ਅਗਲੇ ਰੇਡੀਓ ਬਟਨ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "ਕੋਈ ਹੋਰ ਰੇਡੀਓ ਬਟਨ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "ਪਿਛਲੇ ਅੱਖਰ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "ਅਗਲੇ ਅੱਖਰ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "ਪਿਛਲੇ ਟੇਬਲ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "ਅਗਲੇ ਟੇਬਲ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "ਇੱਕ ਸੈੱਲ ਹੇਠਾਂ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "ਇੱਕ ਟੇਬਲ ਦੇ ਪਹਿਲੇ ਸੈੱਲ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "ਇੱਕ ਟੇਬਲ ਦੇ ਆਖਰੀ ਸੈੱਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "ਇੱਕ ਸੈੱਲ ਖੱਬੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "ਇੱਕ ਸੈੱਲ ਸੱਜੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "ਇੱਕ ਸੈੱਲ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "ਮਾਊਸ ਰੀਵਿਊ ਮੋਡ ਬਦਲੋ।" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "ਸਵਿੱਚ ਗੂੰਜ ਯੋਗ(_k)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "ਪਿਛਲੀ ਅਣ-ਖੋਲ੍ਹੇ ਲਿੰਕ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "ਅਗਲੇ ਅਣ-ਖੋਲ੍ਹੇ ਲਿੰਕ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "ਕੋਈ ਹੋਰ ਨਾ-ਖੋਲ੍ਹਿਆ ਲਿੰਕ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "ਪਿਛਲੇ ਖੋਲ੍ਹੇ ਲਿੰਕ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "ਅਗਲੇ ਅਣ-ਖੋਲ੍ਹੇ ਲਿੰਕ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "ਕੋਈ ਹੋਰ ਖੋਲ੍ਹਿਆ ਲਿੰਕ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "ਸੰਤ੍ਰਿਪਤ ਨੀਲਾ" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "ਕਾਲਾ" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "ਕਾਲਾ ਡਾਇਮੰਡ" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "ਸੰਤ੍ਰਿਪਤ ਨੀਲਾ" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "ਸੰਤ੍ਰਿਪਤ ਨੀਲਾ" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "ਏਗਰੇਵ" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "ਸੰਤ੍ਰਿਪਤ ਹਰਾ" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "ਸੰਤ੍ਰਿਪਤ ਹਰਾ" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "ਸੰਤ੍ਰਿਪਤ ਲਾਲ" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "ਸੰਤ੍ਰਿਪਤ ਹਰਾ" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "ਸੰਤ੍ਰਿਪਤ ਨੀਲਾ" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "ਆਈ ਗਰੇਵ" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "ਅਸੰਤ੍ਰਿਪਤ ਹਰਾ" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "ਗਰੇ ਕੀਤਾ" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "ਡਿਗਰੀ" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "ਹਿੰਦੀ ਗਰੇਡ ੧" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "ਸੱਜਾ ਕੰਟਰੋਲ" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "ਸੱਜਾ ਆਲਟ" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "ਸੱਜਾ ਸੁਪਰ" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "ਸੱਜਾ ਤੀਰ" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "ਨਵੀਂਸਤਰ" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "ਚਿੱਤਰ" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "ਅਸੰਤ੍ਰਿਪਤ ਨੀਲਾ" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "ਸੰਤਰੀ" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "ਸੰਤ੍ਰਿਪਤ ਲਾਲ" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "ਸੰਤ੍ਰਿਪਤ ਹਰਾ" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "ਪੇਰੂ" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "ਗੁਲਾਬੀ" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "ਫਿੱਕਾ ਜਾਮਨੀ" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "end" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "ਸੰਤ੍ਰਿਪਤ ਨੀਲਾ" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s ਸਕਰੀਨ" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "ਸਿਲਵਰ" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "ਅਸਮਾਨੀ ਨੀਲਾ" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "ਅਸੰਤ੍ਰਿਪਤ ਨੀਲਾ" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "ਸਲੇਟੀ" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "ਬਰਫ਼" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "ਅਸੰਤ੍ਰਿਪਤ ਨੀਲਾ" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "ਟੈਬ" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "ਟਮਾਟਰ" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "ਜਾਮਨੀ" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "ਕਣਕ" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "ਖਾਲੀ ਥਾਂ" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "ਖਾਲੀ ਥਾਂ" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "ਪੀਲਾ" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "ਪੂਰੀ ਸਕਰੀਨ" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -#, fuzzy -msgid "Automatic focus mode during structural navigation" -msgstr "ਓਰਕਾ ਢਾਂਚਾ ਨੇਵੀਗੇਸ਼ਨ ਵਰਤੋਂ(_S)" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "ਡਾਟ_7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "ਡਾਟ_8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "ਡਾਟ 7 ਅਤ 8 (_d)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "ਰੱਦ ਕਰੋ(_C)" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "ਜਾਓ(_J)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "ਠੀਕ ਹੈ(_O)" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "ਆਈਕਾਨ" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "ਕੋਈ ਨਹੀਂ" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "ਸ਼ਬਦ-ਜੋੜ" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "ਜਦੋਂ ਦੋਸਤ ਲਿਖ ਰਹੇ ਹੋਣ ਤਾਂ ਸੂਚਨਾ ਦਿਓ(_b)" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "ਚੈਟ ਰੂਮ ਦਾ ਖਾਸ ਅਤੀਤ ਦਿਓ(_m)" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "ਸੁਨੇਹਾ ਇਸ ਤੋਂ ਬੋਲੋ" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "ਸਭ ਚੈਨਲ (_n)" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "ਸਭ ਚੈਨਲ, ਜਦੋਂ ਕੋਈ ਵੀ %s ਵਿੰਡੋ ਐਕਟਿਵ ਹੋਵੇ(_y)" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "ਇੱਕ ਚੈਨਲ ਤਾਂ ਹੀ ਜੇ ਇਸ ਦੀ ਵਿੰਡੋ ਐਕਟਿਵ ਹੈ(_w)" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "ਗੱਲਬਾਤ ਰੂਮ ਨਾਂ ਬੋਲੋ(_S)" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "ਡਬਲ ਕਲਿੱਕ" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "ਤੀਹਰੀ ਵਾਰ ਕਲਿੱਕ" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "ਡਿਫਾਲਟ ਸ਼ੰਸ਼ਲੇਸ਼ਕ" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "ਅਸਲ ਲਾਈਨ" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "ਬਦਲਵੀਂ ਲਾਈਨ" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "ਅੱਖਰ ਰਾਹੀਂ ਗੂੰਜ ਯੋਗ(_r)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "ਗ਼ੈਰ-ਫਾਸਲੇ ਵਾਲੀਆਂ ਡਾਇਆਕ੍ਰਿਟੀਕਲ ਸਵਿੱਚਾਂ ਚਾਲੂ(_d)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "ਮੌਜੂਦਾ ਟਿਕਾਣਾ(_u)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "ਰਲਦੇ ਅੱਖਰਾਂ ਦੀ ਘੱਟੋ-ਘੱਟ ਲੰਬਾਈ:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "ਖੋਜ ਚੋਣਾਂ" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "ਖੋਜ ਦੇ ਬਦਲੀਆਂ ਲਾਈਨਾਂ ਹੀ ਬੋਲੋ(_y)" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "ਖੋਜ ਦੇ ਦੌਰਾਨ ਨਤੀਜੇ ਬੋਲੋ(_f)" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "ਕਮਾਂਡ" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "ਸਵਿੱਚ ਬਾਈਡਿੰਗ" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "ਡਿਫਾਲਟ" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "ਸਿੱਖਣ ਢੰਗ" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "ਕਾਰਵਾਈਆਂ" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ਬਰਾਇੱਲੇ ਬਾਇਡਿੰਗ" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "ਬੁੱਕਮਾਰਕ" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "ਤਾਰੀਖ ਅਤੇ ਸਮਾਂ" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "ਟੇਬਲ ਨੇਵੀਗੇਸ਼ਨ" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "ਆਬਜੈਕਟ ਵੇਰਵੇ" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "ਅਨਬਾਊਂਡ" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "ਫਲੈਟ ਪੜਤਾਲ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ।" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "ਬੋਲ ਅਤੇ ਵੱਧ ਵੇਰਵੇ" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "ਸੋਧਿਆਂ" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "ਡੈਸਕਟਾਪ(_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "ਨੋਟੀਫਿਕੇਸ਼ਨ" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "ਕੁੱਲ ਲਏ" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "%s ਨੋਟੀਫਿਕੇਸ਼ਨ" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "ਓਰਕਾ ਪਸੰਦ" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "ਬਲੇਇਲ 'ਚ ਮਾਰਕ" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "ਪੇਸ਼ ਕਰੋ, ਜਦੋਂ ਤੱਕ ਕਿ" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "ਬੋਲੋ" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "ਪ੍ਰੋਫਾਇਲ ਨੂੰ ਛੋਟ ਵਜੋਂ ਸੰਭਾਲੋ" - -#: src/cthulhu/guilabels.py:429 -#, fuzzy -msgid "User Profile Conflict!" -msgstr "ਯੂਜ਼ਰ ਪ੍ਰੋਫਾਇਲ ਅਪਵਾਦ!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -#, fuzzy -msgid "Load user profile" -msgstr "ਯੂਜ਼ਰ ਪ੍ਰੋਫਾਇਲ ਲੋਡ ਕਰੋ" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "ਪ੍ਰੋਫਾਇਲ ਇੰਝ ਸੰਭਾਲੋ" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "ਪ੍ਰੋਫਾਇਲ ਨਾਂ(_P):" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "ਯੂਜ਼ਰ ਪ੍ਰੋਫਾਇਲ ਲੋਡ ਕਰੋ" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "ਸਭ" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "ਐਪਲੀਕੇਸ਼ਨ" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "ਵਿੰਡੋ" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "ਕੋਈ ਨਹੀਂ(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "ਕੁਝ(_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "ਅਕਸਰ(_o)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "ਲਾਈਨ" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "ਵਾਕ" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "ਕਾਮੇ" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "ਬਟਨ" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "ਸੁਰਖੀ" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "ਚੋਣਬਕਸਾ" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "ਕਲਿੱਕ ਕਰਨ ਯੋਗ" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "ਕੰਬੋ ਬਕਸਾ" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "ਘਾਤ n" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "ਹੈਡਿੰਗ" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "ਅੰਦਰੂਨੀ ਫਰੇਮ" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "ਚਿੱਤਰ" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "ਲੇਬਲ" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "ਟਰੇਡਮਾਰਕ" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "ਲੈਵਲ" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "ਲਿੰਕ" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "ਲਿਸਟ" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ਲਿਸਟ ਆਈਟਮ" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "ਆਬਜੈਕਟ" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "ਪ੍ਹੈਰਾ" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "ਰੇਡੀਓ ਬਟਨ" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "ਰੋਲ" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "ਚੁਣਿਆ" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "ਹਾਲਤ" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "ਟੈਕਸਟ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "ਮੁੱਲ" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "ਕੋਈ ਹੋਰ ਬੈਕ-ਕੋਟ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "ਬਟਨ" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "ਚੋਣਬਕਸਾ" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "ਕੰਬੋ ਬਕਸਾ" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "ਐਂਟਰੀਆਂ" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "ਹੈਡਿੰਗ" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "ਅੰਦਰੂਨੀ ਫਰੇਮ" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "ਚਿੱਤਰ" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "ਲੈਵਲ %d ਉੱਤੇ ਕੋਈ ਹੋਰ ਹੈਡਿੰਗ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "ਟਰੇਡਮਾਰਕ" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "ਕੋਈ ਹੋਰ ਵੱਡਾ ਆਬਜੈਕਟ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "ਲਿੰਕ" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "ਲਿਸਟ" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ਲਿਸਟ ਆਈਟਮ" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "ਪ੍ਹੈਰਾ" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "ਰੇਡੀਓ ਬਟਨ" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "ਟੇਬਲ" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d ਅਣ-ਖੋਲ੍ਹੇ ਲਿੰਕ" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d ਖੋਲ੍ਹੇ ਲਿੰਕ" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "ਪੇਜ਼ ਨੇਵੀਗੇਸ਼ਨ" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "ਜਦੋਂ ਪਹਿਲਾਂ ਲੋਡ ਹੋਵੇ ਤਾਂ ਪੇਜ਼ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ ਬੋਲਣਾ ਸ਼ੁਰੂ ਕਰੋ(_l)" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "ਜਦੋਂ ਪਹਿਲਾਂ ਲੋਡ ਹੋਵੇ ਤਾਂ ਪੇਜ਼ ਨੂੰ ਆਟੋਮੈਟਿਕ ਹੀ ਬੋਲਣਾ ਸ਼ੁਰੂ ਕਰੋ(_l)" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s ਡਿਫਾਲਟ ਆਵਾਜ਼" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "ਡਿਫਾਲਟ" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "ਹਾਇਪਰਲਿੰਕ" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "ਸਿਸਟਮ" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "ਵੱਡੇ ਅੱਖਰ" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "ਧੁਨੀ ਡਿਸਪੈਚਰ" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "ਸਪਰੈੱਡ ਸ਼ੀਟ ਸੈੱਲ ਕੋਆਰਡੀਨੇਟ ਬੋਲੋ" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "ਸੈੱਲ ਹੈੱਡਰ ਬੋਲੋ(_h)" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "ਟੇਬਲ ਨੇਵੀਗੇਸ਼ਨ" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "ਖਾਲੀ ਸੈੱਲ ਛੱਡੋ(_b)" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "ਸੈੱਲ ਬੋਲੋ(_c)" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "ਸੈੱਲ ਧੁਰੇ ਬੋਲੋ(_c)" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "ਮਲਟੀਪਲ ਸੈੱਲ ਸਪੈਨ ਬੋਲੋ(_m)" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "ਗੁਣ ਨਾਂ" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "ਓਰਕਾ ਕਰਿਏਟ ਨੇਵਗੀਸ਼ਨ ਵਰਤੋਂ(_O)" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "ਢਾਂਚਾ ਨੇਵੀਗੇਸ਼ਨ ਸਵਿੱਚਾਂ ਬਦਲੋ।" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "ਸੰਖੇਪ(_f)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "ਨੋਟੀਫਿਕੇਸ਼ਨ" -msgstr[1] "ਨੋਟੀਫਿਕੇਸ਼ਨ" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "ਸ਼ਿਫ਼ਟ" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "ਕੰਟਰੋਲ" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "ਖੱਬੀ ਸਿਫ਼ਟ" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "ਖੱਬਾ ਆਲਟ" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ਖੱਬਾ ਕੰਟਰੋਲ" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "ਸੱਜਾ ਸਿਫਟ" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "ਸੱਜਾ ਆਲਟ" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "ਸੱਜਾ ਕੰਟਰੋਲ" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ਖੱਬਾ ਮੀਟਾ" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "ਸੱਜਾ ਮੀਟਾ" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "ਨਮ ਲਾਕ" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "ਕੈਪਸ ਲਾਕ" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "ਕੈਪਸ ਲਾਕ" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "ਸਕਰੋਲ ਲਾਕ" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "ਸਫ਼ਾ ਉੱਤੇ" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "ਸਫ਼ਾ ਹੇਠਾਂ" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "ਖੱਬੀ ਟੈਬ" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "ਬੈਕਸਪੇਸ" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "ਵਾਪਸ" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "ਐਂਟਰ" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "ਉੱਤੇ" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "ਹੇਠਾਂ" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "ਖੱਬਾ" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "ਸੱਜਾ" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "ਖੱਬਾ ਸੁਪਰ" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "ਸੱਜਾ ਸੁਪਰ" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "ਮੇਨੂ" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ਮੱਦਦ" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "ਮਲਟੀ" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "ਮੋਡ ਬਦਲੋ" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "ਸ਼ੁਰੂ" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "ਸਰਕਮਫਲਿਕਸ" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ਰਿੰਗ" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "ਸਟਰੋਕ" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "ਘਟਾਓ" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "ਕੈਪਸ ਲਾਕ(_L)" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "ਸੁਪਰ" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "ਸ਼ਿਫ਼ਟ" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "ਗੂੜਾ" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "ਟੇਡੇ" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr " %s ਪੈਰ ਵਿੱਚ" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr " %s ਪੈਰ ਵਿੱਚ" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "ਵਰਕਸਪੇਸ " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s ਪਰਸੰਗ" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "ਖੱਬਾ ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "ਸੱਜਾ ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "ਸੱਜਾ ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "ਸੱਜਾ ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "ਸੱਜਾ ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "ਖੱਬਾ ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "ਖੱਬਾ ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "ਸੱਜਾ ਤੀਰ" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "ਖੱਬੇ ਡਬਲ ਕੋਟ" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "ਡਬਲ ਡੱਜਰ" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "ਸੱਜੇ ਡਬਲ ਕੋਟ" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "ਡਬਲ ਡੱਜਰ" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "ਸੱਜੇ ਡਬਲ ਕੋਟ" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "ਸੱਜਾ-ਪਾਸਾ ਦਰਸਾਉਂਦਾ" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "ਸੱਜਾ-ਪਾਸਾ ਤੀਰਮੁੱਢ" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "ਘਟਾਓ" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "ਘੱਟ" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "ਸਰਕਮਫਲਿਕਸ" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "ਬਿੰਦੀ" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "ਵਰਟੀਕਲ ਇਕਸਾਰ" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "ਹਰੀਜੱਟਲ" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "ਆਟੋ-ਪੂਰਨ" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "ਖਾਲੀ" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "ਚਾਲੂ ਹੈ" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "ਕਤਾਰ ਦੇ ਅੰਤ ਉੱਤੇ।" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "ਸਬ" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "ਜੋੜ ਜਾਂ ਘਟਾਓ" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "ਜੋੜ" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "ਘਟਾਓ" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "ਵੱਖਰੇਵਾਂ" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "ਘਣਮੂਲ" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "ਅਨੁਪਾਤੀ" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "ਬੇਅੰਤ" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "ਸੱਜਾ ਆਲਟ" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "ਇੱਕਲਾ" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "ਪਰਤੀਬਾਹੀ" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "ਵਰਟੀਕਲ ਇਕਸਾਰ" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "ਇਸ ਨਾਲ ਭਾਗ" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "ਵੱਖਰੇਵਾਂ" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "ਬਰਾਬਰ ਤੋਂ ਨਹੀ" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "ਲਾਜੀਕਲ NOT" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "ਲਾਜੀਕਲ NOT" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "ਦਿਸ਼ਾ" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "ਅੰਦਰੂਨੀ ਫਰੇਮ" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "ਡਬਲ ਪਰਾਈਮ" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "ਅਨੁਪਾਤੀ" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "ਘਟਾਓ" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "ਟੀਲਡ" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "ਇਨ ਟੀਲਡ" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "ਇਨ ਟੀਲਡ" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "ਲੱਗਭਗ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ਲੱਗਭਗ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "ਲੱਗਭਗ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "ਲੱਗਭਗ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ਲੱਗਭਗ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "ਲੱਗਭਗ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "ਤੀਹਰੀ ਵਾਰ ਕਲਿੱਕ" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "ਲੱਗਭਗ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "ਵੱਖਰੀ ਸਾਈਟ" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "ਬਰਾਬਰ ਤੋਂ ਨਹੀ" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "ਸਮਾਨ" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "ਸਮਾਨ" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ਬਰਾਬਰ ਤੋਂ ਨਹੀ" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ਬਰਾਬਰ ਤੋਂ ਨਹੀ" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "ਤਿੰਨ-ਐਂਗਲ ਬੁਲਿੱਟ" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "ਸਮਾਨ" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "ਬਰਾਬਰ ਤੋਂ ਨਹੀ" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "ਬਰਾਬਰ ਤੋਂ ਨਹੀ" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "ਵਰਟੀਕਲ" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "ਬਰਾਬਰ ਤੋਂ ਨਹੀ" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "ਬਰਾਬਰ ਤੋਂ ਨਹੀ" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "ਨਹੀਂ ਦਬਾਇਆ" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ਚੁਣਿਆ ਨਹੀਂ" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "ਪੈਰ ਵਿੱਚ 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "ਘਾਤ" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "ਬਹੁ-ਚੋਣ" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "ਇਕਸਾਰ" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "ਬਹੁ-ਚੋਣ" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "ਪੈਰ ਵਿੱਚ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "ਇਨ ਡੈਸ਼" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "ਪੈਰ ਵਿੱਚ ਜੋੜ" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "ਪੈਰ ਵਿੱਚ ਘਟਾਓ" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "ਸੱਜਾ ਮੀਟਾ" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "ਖੱਬੀ ਟੈਬ" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "ਹੇਠਾਂ" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "ਭਾਗ" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "ਸੱਚ" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "ਸੱਚ" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ਆਰਡੀਨਲ" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "ਚਿੱਤਰ" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "ਮਲਟੀ" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "ਅੰਦਰੂਨੀ ਫਰੇਮ" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "ਸਧਾਰਨ" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ਸੱਜੇ ਸਿੰਗਲ ਕੋਟ " - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "ਵੱਖਰੇਵਾਂ" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "ਲਾਜੀਕਲ NOT" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "ਲਾਜੀਕਲ NOT" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "ਡਬਲ ਪਰਾਈਮ" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "ਡਬਲ ਪਰਾਈਮ" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "ਦਿਸ਼ਾ" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "ਡਬਲ ਪਰਾਈਮ" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "ਘੱਟ ਜਾਂ ਬਰਾਬਰ" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "ਬਰਾਬਰ ਜਾਂ ਵੱਧ" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "ਵਰਟੀਕਲ ਇਕਸਾਰ" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ਖੱਬੀ ਬਰੈਕਟ" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "ਸੱਜੇ ਬਰੈਕਟ" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "ਖੱਬਾ ਆਲਟ" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "ਸੱਜਾ ਆਲਟ" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "ਖੱਬੀ ਛੋਟੀ ਬਰੈਕਟ" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "ਤਲ" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "ਖੱਬੇ ਡਬਲ ਕੋਣੀ ਬਰੈਕਟ " - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "ਸੱਜੇ ਡਬਲ ਐਂਗਲ ਬਰੈਕਟ" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "ਵਿਚਕਾਰ ਬਿਂਦੀ" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "ਕਾਲਾ ਵਰਗ" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "ਚਿੱਟਾ ਵਰਗ" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "ਕਾਲਾ ਡਾਇਮੰਡ" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "ਚਿੱਟਾ ਚੱਕਰ" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "ਕਾਲਾ ਚੱਕਰ" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "ਚਿੱਟਾ ਬੁਲਿੱਟ" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "ਕਾਲਾ ਵਰਗ" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "ਹੇਠਾਂ ਸਤਰ" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "ਵਰਟੀਕਲ ਇਕਸਾਰ" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "ਐਪਲੀਕੇਸ਼ਨ" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "ਖਾਲੀ" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "ਗੂੜਾ" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "ਬੁੱਕਮਾਰਕ ਦਾਖਲ ਹੈ" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "ਬੁੱਕਮਾਰਕ ਸੰਭਾਲੋ" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "ਬੁੱਕਮਾਰਕ ਸੰਭਾਲੇਆ ਨਹੀ ਜਾ ਸਕਿਆ।" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "ਕੋਈ ਲੈਂਡਮਾਰਕ ਨਹੀਂ ਲੱਭਿਆ" - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "ਕੋਈ ਲੈਂਡਮਾਰਕ ਨਹੀਂ ਲੱਭਿਆ" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "ਬਾਏਪਾਸ ਮੋਡ ਯੋਗ ਹੈ।" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "ਕੈਲਕੂਲੇਟਰ ਡਿਸਪਲੇਅ ਲੈਣ ਲਈ ਅਸਮਰੱਥ" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ਆਈਕਾਨ" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "ਕੋਈ ਨਹੀਂ" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "ਸ਼ਬਦ-ਜੋੜ" - -#: src/cthulhu/messages.py:157 -#, fuzzy -msgid "Capitalization style set to spell." -msgstr "ਸਭ ਲਈ ਵਿਰਾਮ ਚਿੰਨ੍ਹ ਲੈਵਲ ਸੈੱਟ ਕਰੋ।" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "ਗੀਕੋ ਕਰੀਟ ਕੰਟਰੋਲ ਕਰਦਾ ਹੈ।" - -#: src/cthulhu/messages.py:170 -#, fuzzy -msgid "Cthulhu is controlling the caret." -msgstr "ਗੀਕੋ ਕਰੀਟ ਕੰਟਰੋਲ ਕਰਦਾ ਹੈ।" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "ਸੈੱਲ %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "ਚੁਣਿਆ ਨਹੀਂ" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "ਨਾ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "ਚੋਣ ਦੀ ਵਰਤੋਂ ਰੋਕੋ" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "ਚੋਣ ਦੀ ਧੱਕੇ ਨਾਲ ਵਰਤੋਂ" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "ਚੋਣ" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -#, fuzzy -msgid "The following are not valid: " -msgstr "ਅੱਗੇ ਦਿੱਤੇ ਆਰਗੂਮੈਂਟ ਢੁੱਕਵੇਂ ਨਹੀਂ ਹਨ: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "ਜਾਣੇ ਚੱਲਦੇ ਐਪਲੀਕੇਸ਼ਨ ਪਰਿੰਟ ਕਰੋ" - -#: src/cthulhu/messages.py:237 -#, fuzzy -msgid "Load profile" -msgstr "ਯੂਜ਼ਰ ਪ੍ਰੋਫਾਇਲ ਲੋਡ ਕਰੋ" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "ਬੁੱਕਮਾਰਕ ਸੰਭਾਲੇਆ ਨਹੀ ਜਾ ਸਕਿਆ।" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "ਯੂਜ਼ਰ ਪਸੰਦ ਲਈ ਬਦਲਵੀਂ ਡਾਇਰੈਕਟਰੀ ਵਰਤੋਂ" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "ਜਾਣੇ ਚੱਲਦੇ ਐਪਲੀਕੇਸ਼ਨ ਪਰਿੰਟ ਕਰੋ" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "ਮੌਜੂਦਾ ਚੱਲ ਰਹੇ ਓਰਕਾ ਨੂੰ ਬਦਲੋ" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "ਇਹ ਮੱਦਦ ਵੇਖਾਉਦਾ ਹੈ" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "ਯੂਜ਼ਰ ਪਸੰਦ ਸੈੱਟਅੱਪ (ਪਾਠ ਵਰਜਨ)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "ਯੂਜ਼ਰ ਪਸੰਦ ਸੈੱਟਅੱਪ (ਪਾਠ ਵਰਜਨ)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "ਬੱਗ ਜਾਣਕਾਰੀ https://groups.io/g/stormux ਉੱਤੇ ਭੇਜੋ।" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "ਏਕਿਊਟ" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "ਤੇਜ਼।" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "ਜਦੋਂ ਤੁਹਾਡਾ ਦੋਸਤ ਲਿਖ ਰਿਹਾ ਹੋਵੇ ਤਾਂ ਸੂਚਨਾ ਨਾ ਦਿਓ।" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "ਜਦੋਂ ਤੁਹਾਡਾ ਦੋਸਤ ਲਿਖੇ ਤਾਂ ਸੂਚਨਾ ਦਿਓ।" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "ਗੱਲਬਾਤ ਰੂਮ %s ਤੋਂ ਸੁਨੇਹਾ" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "ਨਵੀਂ ਚੈੱਟ ਟੈਬ %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "ਗੱਲਬਾਤ ਰੂਮ ਨਾਂ ਨਾ ਬੋਲੋ" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "ਗੱਲਬਾਤ ਰੂਪ ਨਾਂ ਬੋਲੋ।" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "ਚੈੱਟ ਰੂਮ ਖਾਸ ਸੁਨੇਹਾ ਅਤੀਤ ਨਾ ਦਿਓ।" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "ਚੈੱਟ ਰੂਪ ਲਈ ਖਾਸ ਸੁਨੇਹਾ ਅਤੀਤ ਦਿਓ।" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "delete" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "insert" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "ਸਵਾਲੀਆ" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "ਟੇਬਲ ਦਾ ਅੰਤ" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "ਟੇਬਲ ਵਿੱਚ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "ਚੁਣਿਆ ਨਹੀਂ" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "%s ਡਿਫਾਲਟ ਬਟਨ ਹੈ" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "%s ਡਿਫਾਲਟ ਬਟਨ ਹੈ" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "%s ਡਿਫਾਲਟ ਬਟਨ ਹੈ" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " %s ਪੈਰ ਵਿੱਚ" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " ਘਾਤ %s" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "ਟੇਬਲ ਵਿੱਚ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "ਪੂਰਾ ਦਸਤਾਵੇਜ਼ ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "ਪੂਰਾ ਦਸਤਾਵੇਜ਼ ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਚੁਣਿਆ ਦਸਤਾਵੇਜ਼" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਅਣ-ਚੁਣਿਆ ਡੌਕੂਮੈਂਟ" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੱਕ ਚੁਣਿਆ ਦਸਤਾਵੇਜ਼" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੱਕ ਅਣ-ਚੁਣਿਆ ਡੌਕੂਮੈਂਟ" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "%d ਕਤਾਰ ਲਈ ਸਫ਼ਰੀ ਕਾਲਮ ਹੈੱਡਰ ਸੈੱਟ ਕਰੋ" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "ਸਫ਼ਰੀ ਕਾਲਮ ਹੈੱਡਰ ਸਾਫ਼ ਕੀਤਾ।" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "ਕਾਲਮ %s ਲਈ ਸਫ਼ਰੀ ਕਤਾਰ ਹੈੱਡਰ ਦਿਓ" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "ਸਫ਼ਰੀ ਕਤਾਰ ਹੈੱਡਰ ਸਾਫ਼ ਕਰੋ।" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ਖਾਲੀ" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f ਕਿਲੋਬਾਈਟ" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f ਮੇਗਾਬਾਈਟ" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "ਕੋਈ ਫਾਇਲ ਨਹੀਂ ਲੱਭੀ ਹੈ।" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "ਫਲੈਟ ਪੜਤਾਲ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ।" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "ਫਲੈਟ ਪੜਤਾਲ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ।" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "ਸਮਤਲ ਝਲਕ ਨੂੰ ਮੌਜੂਦਾ ਸ਼ਬਦ ਦੇ ਉੱਪਰ ਸ਼ਬਦ ਭੇਜਦੀ ਹੈ।" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "ਫਾਰਮੂਲਾ ਹੈ" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "ਡਾਈਲਾਗ" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "ਪੋਪਅੱਪ ਮੇਨੂ" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "ਚਿੱਤਰ ਨਕਸ਼ਾ ਲਿੰਕ" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "ਦਿੱਤੀ ਸਵਿੱਚ ਪਹਿਲਾਂ ਹੀ %s ਹੀ ਬਾਊਂਡ ਹੈ।" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "ਸਵਿੱਚ ਫੜੀ: %s। ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ enter ਦਬਾਓ।" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "ਨਵੀਂ ਸਵਿੱਚ: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "ਸਵਿੱਚ ਬਾਈਡਿੰਗ ਹਟਾਈ ਗਈ। ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ enter ਦਬਾਓ।" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "ਕੀਬਾਈਡਿੰਗ ਹਟਾਈ ਗਈ ਹੈ।" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "ਨਵੀਂ ਸਵਿੱਚ ਦਿਓ" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "ਸਵਿੱਚ" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "ਸ਼ਬਦ ਲਈ ਸੈੱਟ ਕੀਤੀ ਸਵਿੱਚ ਗੂੰਜ।" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "ਕੋਈ ਨਹੀਂ" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "ਸ਼ਬਦ ਲਈ ਸੈੱਟ ਕੀਤੀ ਸਵਿੱਚ ਗੂੰਜ।" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "ਸਵਿੱਚ ਅਤੇ ਸ਼ਬਦ" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "ਸ਼ਬਦ ਲਈ ਸੈੱਟ ਕੀਤੀ ਸਵਿੱਚ ਗੂੰਜ।" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "ਵਾਕ" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "ਵਾਕ ਲਈ ਸੈੱਟ ਕੀਤੀ ਸਵਿੱਚ ਗੂੰਜ।" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "ਸ਼ਬਦ" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "ਸ਼ਬਦ ਲਈ ਸੈੱਟ ਕੀਤੀ ਸਵਿੱਚ ਗੂੰਜ।" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "ਸ਼ਬਦ ਅਤੇ ਵਾਕ" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "ਵਾਕ ਲਈ ਸੈੱਟ ਕੀਤੀ ਸਵਿੱਚ ਗੂੰਜ।" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "ਬਾਕਸ" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "ਚੱਕਰ" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "ਹਰੀਜੱਟਲ" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "ਵਰਟੀਕਲ ਬਾਰ" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "ਸੱਜਾ ਤੀਰ" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "ਹੇਠਾਂ ਵੱਲ ਸਮੇਟਿਆ ਜਾ ਰਿਹਾ ਹੈ" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "ਲਾਈਨ ਉਚਾਈ" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "ਅਤੇ" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "ਉੱਤੇ" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "ਵਰਗਮੂਲ " - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "ਘਣਮੂਲ" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "ਰੂਟ ਬਾਹੀ" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "ਰੂਟ ਬਾਹੀ" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "ਰੂਟ ਬਾਹੀ" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "ਪੈਰ ਵਿੱਚ 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "ਘਾਤ" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "ਪੈਰ ਵਿੱਚ 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "ਘਾਤ" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "ਘਾਤ" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "ਘਾਤ" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "ਟੇਬਲ" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "ਲੜੀ ਟੇਬਲ" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "ਨਾ-ਪਹੁੰਚਯੋਗ" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "ਬੰਦ ਹੈ" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "ਚਾਲੂ ਹੈ" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "ਬੋਲ ਦੂਰੀ ਅਤੇ ਇਕਸਾਰਤਾ(_i)" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "ਸਿੱਖਣ ਢੰਗ ਹੈ। ਬਾਹਰ ਜਾਣ ਲਈ Escape ਦਬਾਓ।" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "ਸਜੀਵਤਾ" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "ਪੇਜ਼ ਨੇਵੀਗੇਸ਼ਨ" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "ਟੇਬਲ ਨੇਵੀਗੇਸ਼ਨ" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਸਤਰਾਂ ਚੁਣੀਆਂ ਸਤਰਾਂ" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਉੱਪਰ ਚੁਣੀਆਂ ਸਤਰਾਂ" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਲਈਨ ਅਣ-ਚੁਣੀ ਹੇਠਾਂ ਵੱਲ" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਉੱਪਰ ਅਣ-ਚੁਣੀ ਲਾਈਨ" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "ਸਿੱਖਣ ਢੰਗ ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਉੱਪਰ ਚੁਣੀਆਂ ਲਾਈਨਾਂ" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਸਤਰਾਂ ਚੁਣੀਆਂ ਲਾਈਨਾਂ" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ਸਬੰਧ" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ਉਹੀ ਪੇਜ਼" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ਉਹੀ ਸਾਈਟ" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "ਵੱਖਰੀ ਸਾਈਟ" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s %(file)s ਨਾਲ ਲਿੰਕ ਹੈ" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s ਲਿੰਕ" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "%s ਖੋਲ੍ਹੇ ਲਿੰਕ" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "ਸਭ ਲਾਈਵ ਖੇਤਰ ਬੰਦ (ਆਫ਼) ਸੈੱਟ ਕਰੋ" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "ਲਾਈਵ ਖੇਤਰ ਲਈ ਸੱਭਿਅਕ ਲੈਵਲ ਰੀ-ਸਟੋਰ ਕੀਤੇ ਗਏ" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "ਸੱਭਿਅਕ ਲੈਵਲ %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "ਲਾਈਵ ਖੇਤਰ ਨੂੰ ਨਿਸ਼ਚੇਆਤਮਕ ਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "ਲਾਈਵ ਖੇਤਰ ਨੂੰ ਬੰਦ ਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "ਲਾਈਵ ਖੇਤਰ ਨੂੰ ਪੋਲਾਇਟ ਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "ਲਾਈਵ ਖੇਤਰ ਨੂੰ ਉਜੱਡ ਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "ਲਾਈਵ ਖੇਤਰ ਨਿਗਰਾਨ ਬੰਦ ਹੈ" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "ਲਾਈਵ ਖੇਤਰ ਨਿਗਰਾਨ ਚਾਲੂ ਹੈ" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "ਕੋਈ ਲਾਈਵ ਸੁਨੇਹਾ ਨਹੀਂ ਸੰਭਾਲਿਆ ਗਿਆ" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "ਲਾਈਵ ਖੇਤਰ ਸਹਿਯੋਗ ਬੰਦ ਹੈ" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "ਨਹੀਂ ਲੱਭਿਆ" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "ਮੌਜੂਦਾ ਟਿਕਾਣਾ ਲੱਭਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ।" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "ਬੰਦ" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "ਚਾਲੂ" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "ਗਲਤ ਸ਼ਬਦ-ਜੋੜ" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "ਗਲਤ ਸ਼ਬਦ-ਜੋੜ: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "%s ਪਰਸੰਗ" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "ਅਗਲੇ ਆਬਜੈਕਟ ਉੱਤੇ ਜਾਓ।" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "ਮਾਊਸ ਉੱਤੇ ਆਬਜੈਕਟ ਨਹੀਂ ਲੱਭਿਆ।" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "ਮਾਊਂਸ ਸੁਧਾਰ ਆਯੋਗ ਕੀਤਾ।" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "ਮਾਊਂਸ ਸੁਧਾਰ ਯੋਗ ਕੀਤਾ।" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "ਫੀ-ਸਦੀ %d।" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "ਪਿਛੇ ਨਹੀਂ।" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "ਲੜੀ ਲੈਵਲ %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "ਨਵੀਂ ਆਈਟਮ ਜੋੜੀ ਗਈ" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "ਕਿਸੇ ਐਪਲੀਕੇਸਨ ਦਾ ਫੋਕਸ ਨਹੀਂ।" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "ਕੋਈ ਫੋਕਸ ਨਹੀਂ" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "ਕਿਸੇ ਐਪਲੀਕੇਸਨ ਦਾ ਫੋਕਸ ਨਹੀਂ।" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "ਕੋਈ ਹੋਰ ਬੈਕ-ਕੋਟ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "ਕੋਈ ਹੋਰ ਬਟਨ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "ਕੋਈ ਹੋਰ ਚੋਣ ਬਾਕਸ ਨਹੀਂ।" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "ਕੋਈ ਹੋਰ ਵੱਡਾ ਆਬਜੈਕਟ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "ਕੋਈ ਹੋਰ ਲਿੰਕ-ਯੋਗ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "ਕੋਈ ਹੋਰ ਕੰਬੋ ਬਾਕਸ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "ਕੋਈ ਹੋਰ ਐਂਟਰੀ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "ਕੋਈ ਹੋਰ ਫਾਰਮ ਖੇਤਰ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "ਕੋਈ ਹੋਰ ਹੈਡਿੰਗ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "ਲੈਵਲ %d ਉੱਤੇ ਕੋਈ ਹੋਰ ਹੈਡਿੰਗ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "ਅੰਦਰੂਨੀ ਫਰੇਮ" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "ਕੋਈ ਹੋਰ ਚਿੱਤਰ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "ਕੋਈ ਲੈਂਡਮਾਰਕ ਨਹੀਂ ਲੱਭਿਆ" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "ਕੋਈ ਹੋਰ ਲਿੰਕ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "ਕੋਈ ਹੋਰ ਲਿਸਟ ਨਹੀਂ।" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "ਕੋਈ ਹੋਰ ਲਿਸਟ ਆਈਟਮ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "ਕੋਈ ਹੋਰ ਲਾਈਵ ਖੇਤਰ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "ਕੋਈ ਹੋਰ ਪ੍ਹੈਰਾ ਨਹੀਂ।" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "ਕੋਈ ਹੋਰ ਰੇਡੀਓ ਬਟਨ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "ਕੋਈ ਹੋਰ ਵੱਖਰੇਵਾਂ ਨਹੀਂ।" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "ਕੋਈ ਹੋਰ ਟੇਬਲ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "ਕੋਈ ਹੋਰ ਨਾ-ਖੋਲ੍ਹਿਆ ਲਿੰਕ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "ਕੋਈ ਹੋਰ ਖੋਲ੍ਹਿਆ ਲਿੰਕ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "ਨਾ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "ਲਿੰਕ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "ਨੋਟੀਫਿਕੇਸ਼ਨ" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "ਤਲ" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "ਉੱਤੇ" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "ਕੋਈ ਨੋਟੀਫਿਕੇਸ਼ਨ ਸੁਨੇਹਾ ਨਹੀਂ" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "ਸ਼ਬਦ" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "ਮਲਟੀਕੇਸ ਸਤਰਾਂ ਸ਼ਬਦਾਂ ਵਾਂਗ ਬੋਲੋ(_d)" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "ਬੰਦ" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ਚਾਲੂ" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "ਲੋਡਿੰਗ ਜਾਰੀ। ਉਡੀਕੋ ਜੀ।" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "ਲੋਡਿੰਗ ਪੂਰੀ ਹੋਈ।" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s ਲੋਡਿੰਗ ਪੂਰੀ ਹੋਈ।" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਸਫ਼ਾ ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੱਕ ਸਫ਼ਾ ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਪੇਜ਼ ਅਣ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੱਕ ਪੇਜ਼ ਅਣ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਸਫ਼ਾ ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਸਫ਼ਾ ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਪੇਜ਼ ਅਣ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "ਕਰਸਰ ਸਥਿਤੀ ਤੋਂ ਪੇਜ਼ ਅਣ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"ਤੁਹਾਡੇ ਕੋਲ ਓਰਕਾ ਪਸੰਦ ਦਾ ਡਾਈਲਾਗ ਪਹਿਲਾਂ ਹੀ ਖੁੱਲ੍ਹਾ ਹੈ।\n" -"ਨਵਾਂ ਖੋਲ੍ਹਣ ਤੋਂ ਪਹਿਲਾਂ ਉਸ ਨੂੰ ਬੰਦ ਕਰੋ ਜੀ।" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "ਕੋਈ ਪਰੋਫਾਇਲ ਨਹੀਂ ਲੱਭਿਆ।" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "ਤਰੱਕੀ ਪੱਟੀ %d" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "ਸਭ" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "ਸਭ ਲਈ ਵਿਰਾਮ ਚਿੰਨ੍ਹ ਲੈਵਲ ਸੈੱਟ ਕਰੋ।" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "ਬਹੁਤੇ" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "ਕੋਈ ਨਹੀਂ" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "ਕੁਝ" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "ਕੁਝ ਲਈ ਵਿਰਾਮ ਚਿੰਨ੍ਹ ਲੈਵਲ ਸੈੱਟ ਕਰੋ।" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "ਖੋਜ ਜਾਰੀ ਹੈ।" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "ਖੋਜ ਮੁਕੰਮਲ ਹੋਈ।" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "ਸਕਰੀਨ ਰੀਡਰ ਸੈਟਿੰਗਾਂ ਨੂੰ ਮੁੜ-ਲੋਡ ਕੀਤਾ।" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "ਚੁਣੀ ਲਿਖਤ ਹੈ: %s" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "ਕਤਾਰ ਹਟਾਈ ਗਈ।" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "ਲੋੜੀਦੀ ਆਵਾਜ਼ ਚੁਣੋ:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "ਨਾ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "ਧੁਨੀ ਆਯੋਗ ਹੈ।" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "ਧੁਨੀ ਯੋਗ ਕੀਤੀ ਹੈ।" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "ਤੇਜ਼।" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "ਹੌਲੀ।" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "ਉੱਤਲਾ।" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "ਹੇਠਲਾਂ।" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "ਤੇਜ਼।" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "ਦਰ(_R):" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "ਵਾਲੀਅਮ(_l):" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "ਧੁਨੀ ਡਿਸਪੈਚਰ" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "ਧੁਨੀ ਡਿਸਪੈਚਰ" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "ਕੋਈ ਸਰਵਰ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ।\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "ਕੋਈ ਆਵਾਜ਼ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ।\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "ਧੁਨੀ ਯੋਗ ਕੀਤੀ ਹੈ।" - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "ਧੁਨੀ ਨਹੀਂ ਵਰਤੀ ਜਾਵੇਗੀ।\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " ਡਾਟ ਡਾਟ ਡਾਟ" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "ਓਰਕਾ ਪਸੰਦ" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "ਬਾਏਪਾਸ ਮੋਡ ਯੋਗ ਹੈ।" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "ਧੁਨੀ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "ਨਹੀਂ ਲੱਭਿਆ" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "ਹਾਲਤ ਪੱਟੀ ਨਹੀਂ ਲੱਭੀ" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "ਸਤਰ ਨਹੀਂ ਲੱਭੀ" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "ਢਾਂਚਾ ਨੇਵੀਗੇਸ਼ਨ ਸਵਿੱਚਾਂ ਬੰਦ ਹਨ।" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "ਢਾਂਚਾ ਨੇਵੀਗੇਸ਼ਨ ਸਵਿੱਚਾਂ ਚਾਲੂ ਹਨ।" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "ਨਹੀਂ ਲੱਭਿਆ" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "ਕਤਾਰ %(row)d, ਕਾਲਮ %(column)d।" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "ਟੇਬਲ ਦਾ ਅੰਤ" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "ਸੈੱਲ ਬੋਲੋ" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "ਕਤਾਰ ਬੋਲੋ" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "ਨਾ-ਇਕਸਾਰ" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "ਟੇਬਲ ਵਿੱਚ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ਕਾਲਮ ਸਿਰਲੇਖ" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "ਕਾਲਮ %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "%(total)d ਵਿੱਚ ਕਾਲਮ %(index)d " - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "ਕਾਲਮ ਦੇ ਥੱਲੇ।" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "ਕਾਲਮ ਦੇ ਉੱਤੇ।" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "ਨਾ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "ਨਾ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "ਕਤਾਰ %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "%(total)d ਵਿੱਚੋਂ %(index)d ਕਤਾਰ" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "ਕਤਾਰ ਦੇ ਸ਼ੁਰੂ ਵਿੱਚ।" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "ਕਤਾਰ ਦੇ ਅੰਤ ਉੱਤੇ।" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "ਕਤਾਰ ਹਟਾਈ ਗਈ।" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "ਆਖਰੀ ਕਤਾਰ ਹਟਾਈ ਗਈ ਹੈ।" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "ਕਤਾਰ ਜੋੜੀ ਗਈ।" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "ਕਤਾਰ ਨੂੰ ਟੇਬਲ ਦੇ ਅੰਤ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ ਹੈ।" - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "ਕਤਾਰ %s ਚੁਣੀਆਂ" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "ਨਾ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "ਨਾ-ਚੁਣਿਆ" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H ਘੰਟੇ, %M ਮਿੰਟ ਅਤੇ %S ਸਕਿੰਟ" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H ਘੰਟੇ ਅਤੇ %M ਮਿੰਟ" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "ਯੂਨੀਕੋਡ %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "ਵਾਪਿਸ" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "ਪਰਤਾਓ" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "ਓਰਕਾ ਪਸੰਦ" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "ਖਾਲੀ ਥਾਂ" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "ਹੇਠਾਂ ਵੱਲ ਸਮੇਟਿਆ ਜਾ ਰਿਹਾ ਹੈ" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "ਉੱਤੇ ਵੱਲ ਸਮੇਟਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "੦ ਆਈਟਮ" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "%d ਕਤਾਰ ਸੈੱਲ ਸਪੈਨ" -msgstr[1] "%d ਕਤਾਰ ਸੈੱਲ ਸਪੈਨ" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d ਕਾਲਮ" -msgstr[1] "%d ਕਾਲਮ" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "%d ਕਾਲਮ ਸੈੱਲ ਸਪੈਨ" -msgstr[1] "%d ਕਾਲਮ ਸੈੱਲ ਸਪੈਨ" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d ਅੱਖਰ ਬਹੁਤ ਲੰਮਾ ਹੈ" -msgstr[1] "%d ਅੱਖਰ ਬਹੁਤ ਲੰਮੇ ਹਨ" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d ਡਾਈਲਾਗ)" -msgstr[1] "(%d ਡਾਈਲਾਗ)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d ਅਣ-ਫੋਕਸ ਡਾਈਲਾਗ" -msgstr[1] "%d ਅਣ-ਫੋਕਸ ਡਾਈਲਾਗ" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d ਬਾਈਟ" -msgstr[1] "%d ਬਾਈਟ" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ਫਾਈਲ ਮਿਲੀ" -msgstr[1] "%d ਫਾਈਲਾਂ ਮਿਲੀਆਂ" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d ਫਾਰਮ" -msgstr[1] "%d ਫਾਰਮ" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d ਹੈੱਡਿੰਗ" -msgstr[1] "%d ਹੈੱਡਿੰਗ" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d ਆਈਟਮ" -msgstr[1] "%d ਆਈਟਮਾਂ" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d ਲੈਂਡਮਾਰਕ" -msgstr[1] "%d ਲੈਂਡਮਾਰਕ" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d ਆਈਟਮ ਮਿਲੀ" -msgstr[1] "%d ਆਈਟਮਾਂ ਮਿਲੀਆਂ" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "ਕੋਈ ਹੋਰ ਬੈਕ-ਕੋਟ ਨਹੀਂ ਹੈ।" -msgstr[1] "ਕੋਈ ਹੋਰ ਬੈਕ-ਕੋਟ ਨਹੀਂ ਹੈ।" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" -msgstr[1] "ਟੇਬਲ ਛੱਡਿਆ ਜਾ ਰਿਹਾ ਹੈ।" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d ਆਈਟਮ ਨਾਲ ਲਿਸਟ" -msgstr[1] "%d ਆਈਟਮਾਂ ਨਾਲ ਲਿਸਟ" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "%d ਆਈਟਮ ਨਾਲ ਲਿਸਟ" -msgstr[1] "%d ਆਈਟਮਾਂ ਨਾਲ ਲਿਸਟ" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d ਮੁੱਲ" -msgstr[1] "%d ਮੁੱਲ" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "ਟੇਬਲ ਵਿੱਚ %d ਕਤਾਰ" -msgstr[1] "ਟੇਬਲ ਵਿੱਚ %d ਕਤਾਰਾਂ" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d ਕਾਲਮ" -msgstr[1] "%d ਕਾਲਮ" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "ਟੇਬਲ ਵਿੱਚ %d ਕਤਾਰ" -msgstr[1] "ਟੇਬਲ ਵਿੱਚ %d ਕਤਾਰਾਂ" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d ਸੁਨੇਹਾ।\n" -msgstr[1] "%d ਸੁਨੇਹੇ।\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "ਫੀ-ਸਦੀ %d।" -msgstr[1] "ਫੀ-ਸਦੀ %d।" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d ਫੀਸਦੀ ਡੌਕੂਮੈਂਟ ਪੜ੍ਹਿਆ" -msgstr[1] "%d ਫੀਸਦੀ ਡੌਕੂਮੈਂਟ ਪੜ੍ਹਿਆ" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d ਪਿਕਸਲ" -msgstr[1] "%d ਪਿਕਸਲ" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "%(count)d %(repeatChar)s ਅੱਖਰ" - -#: src/cthulhu/messages.py:2784 -#, fuzzy, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%d %d ਵਿੱਚੋਂ ਆਈਟਮ ਚੁਣੀ" -msgstr[1] "%d %d ਵਿੱਚੋਂ ਆਈਟਮਾਂ ਚੁਣੀ" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, fuzzy, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%s ਵਿੱਚ ਕੋਈ ਓਰਕਾ ਸ਼ਾਰਟਕੱਟ ਨਹੀਂ ਲੱਭਿਆ।" -msgstr[1] "%s ਵਿੱਚ ਕੋਈ ਓਰਕਾ ਸ਼ਾਰਟਕੱਟ ਨਹੀਂ ਲੱਭਿਆ।" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d ਸਪੇਸ " -msgstr[1] "%d ਸਪੇਸ" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d ਟੈਬ" -msgstr[1] "%d ਟੈਬਾਂ" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d ਟੇਬਲ" -msgstr[1] "%d ਟੇਬਲ" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "ਟੇਬਲ ਵਿੱਚ %d ਕਤਾਰ" -msgstr[1] "ਟੇਬਲ ਵਿੱਚ %d ਕਤਾਰਾਂ" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%d ਕਤਾਰਾਂ ਅਤੇ %d ਕਾਲਮਾਂ ਨਾਲ ਟੇਬਲ ਹੈ।" -msgstr[1] "%d ਕਤਾਰਾਂ ਅਤੇ %d ਕਾਲਮਾਂ ਨਾਲ ਟੇਬਲ ਹੈ।" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "ਟੇਬਲ ਵਿੱਚ %d ਕਤਾਰ" -msgstr[1] "ਟੇਬਲ ਵਿੱਚ %d ਕਤਾਰਾਂ" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d ਸਕਿੰਟ ਪਹਿਲਾਂ" -msgstr[1] "%d ਸਕਿੰਟ ਪਹਿਲਾਂ" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d ਮਿੰਟ ਪਹਿਲਾਂ" -msgstr[1] "%d ਮਿੰਟ ਪਹਿਲਾਂ" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d ਘੰਟਾ ਪਹਿਲਾਂ" -msgstr[1] "%d ਘੰਟੇ ਪਹਿਲਾਂ" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d ਦਿਨ ਪਹਿਲਾਂ" -msgstr[1] "%d ਦਿਨ ਪਹਿਲਾਂ" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d ਅਣ-ਖੋਲ੍ਹੇ ਲਿੰਕ" -msgstr[1] "%d ਅਣ-ਖੋਲ੍ਹੇ ਲਿੰਕ" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d ਖੋਲ੍ਹੇ ਲਿੰਕ" -msgstr[1] "%d ਖੋਲ੍ਹੇ ਲਿੰਕ" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "ਬਦਲੋ" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(total)d ਵਿੱਚੋਂ %(index)d ਉੱਤੇ" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(total)d ਵਿੱਚੋਂ %(index)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "%d ਲੇਬਲ" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ਲੜੀ ਪੱਧਰ %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "%s ਲਈ ਵੇਰਵੇ" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "ਸਵਾਲੀਆ" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "ਕੰਬੋ ਬਕਸਾ" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html ਭਾਗ" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "ਫ਼ੀਡ" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "ਸ਼ਕਲ" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "ਸ਼ਬਦ ਬਾਅਦ" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "ਚੈਪਟਰ" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "ਕੋਲਨ" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "ਸਿੱਟਾ" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "ਕਵਰ" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "ਮਾਣ" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "ਮਾਣ" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "ਦਿਸ਼ਾ" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "ਪ੍ਹੈਰਾ" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "ਮਿਸਾਲ" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "ਅੱਗੇ" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "ਸ਼ਬਦਾਵਲੀ" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "ਇੰਡੈਕਸ" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "ਜਾਣ ਪਛਾਣ" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "ਸਫ਼ਾ ਸੂਚੀ" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "ਹਿੱਸਾ" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "ਮੁੱਖ-ਬੰਦ" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "ਕਾਮੇ" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "QNA" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "ਸਮੱਗਰੀ ਸਾਰਣੀ" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s ਲੈਵਲ %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "ਹਰੀਜੱਟਲ ਸਕਰੋਲ ਪੱਟੀ" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "ਵਰਟੀਕਲ ਸਕਰੋਲ ਪੱਟੀ" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "ਹਰੀਜੱਟਲ ਸਲਾਈਡਰ" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "ਵਰਟੀਕਲ ਸਲਾਈਡਰ" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "ਹਰੀਜੱਟਲ ਵੰਡਕਾਰ" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "ਵਰਟੀਕਲ ਵੰਡਕਾਰ" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "ਸਵਿੱਚ" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "ਆਈਕਾਨ ਪੈਨਲ" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "ਜ਼ਰੂਰੀ ਸਮੱਗਰੀ" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "ਜਾਣਕਾਰੀ" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "ਮੁੱਖ ਸਮੱਗਰੀ" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "ਨੇਵੀਗੇਸ਼ਨ" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "ਖੇਤਰ" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "ਖੋਜ" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "ਖੋਲ੍ਹੇ ਲਿੰਕ" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "ਮੇਨੂ ਬਟਨ" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "ਲੜੀਬੱਧ" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "ਕਲਿੱਕ ਕਰਨ ਯੋਗ" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "ਸਮੇਟਿਆ" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "ਫੈਲਾਇਆ" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "ਲੰਮਾ ਵੇਰਵਾ ਹੈ" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "ਹਰੀਜੱਟਲ" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "ਵਰਟੀਕਲ" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "ਸਹੀ ਕੀਤਾ" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "ਸਹੀ ਨਹੀਂ ਕੀਤਾ" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "ਚਾਲੂ" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "ਬੰਦ" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "ਅਧੂਰਾ ਚੈੱਕ ਕੀਤਾ" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "ਦਬਾਇਆ" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ਨਹੀਂ ਦੱਬੇ" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "ਨਾ ਚੁਣੇ" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "ਚੁਣਿਆ" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ਨਾ-ਚੁਣਿਆ" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "ਚੁਣਿਆ ਨਹੀਂ" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "ਖੋਲ੍ਹੇ" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "ਅਣ-ਖੋਲ੍ਹੇ" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ਗਰੇ ਕੀਤਾ" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "ਕੇਵਲ ਪੜ੍ਹਨ ਲਈ" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "ਰਲਵੇਂ" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "ਲੋੜੀਦਾ" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "ਬਹੁ-ਚੋਣ" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "ਗਲਤ ਐਂਟਰੀ" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "ਗਲਤ" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ਗਲਤ ਸ਼ਬਦ-ਜੋੜ" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ਸ਼ਬਦ-ਜੋੜ" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "ਗਲਤ ਵਿਆਕਰਨ" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "ਵਿਆਕਰਨ" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "ਖੋਜ" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "ਸਕਰੀਨ ਰੀਡਰ ਖੋਜ ਡਾਈਲਾਗ" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "ਬੰਦ ਕਰੋ(_C)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "ਲੱਭੋ(_F)" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "ਖੋਜ(_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "ਖੋਜ:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "ਝਰੋਖੇ ਦੇ ਉੱਤੇ(_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "ਝਰੋਖੇ ਦੇ ਉੱਤੇ" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "ਇਸ ਤੋਂ ਸ਼ੁਰੂ:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "ਪਾਸਿਓ ਸਮੇਟੋ(_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "ਪਿੱਛੇ ਖੋਜ(_b)" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "ਖੋਜ ਦਿਸ਼ਾ:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "ਅੱਖਰ ਆਕਾਰ ਮਿਲਾਓ(_ਨ)se" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "ਪੂਰੇ ਸ਼ਬਦ ਹੀ ਖੋਜੋ(_e)" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "ਚੋਣਾਂ:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "ਡਿਫਾਲਟ" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "ਵੱਡੇ ਅੱਖਰ" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "ਹਾਈਪਰਲਿੰਕ" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "ਸਿਸਟਮ" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "ਐਪਲੀਕੇਸ਼ਨ" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "ਵਿੰਡੋ" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "ਓਰਕਾ ਪਸੰਦ" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "ਮਦਦ(_H)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "ਲਾਗੂ ਕਰੋ(_A)" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "ਲੈਪਟਾਪ(_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "ਕੀ-ਬੋਰਡ ਲੇਆਉਟ" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "ਐਕਟਿਵ ਪ੍ਰੋਫਾਇਲ(_P):" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "ਸ਼ੁਰੂਆਤ ਪ੍ਰੋਫਾਇਲ:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "ਲੋਡ(_L)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "ਇੰਝ ਸੰਭਾਲੋ(_A)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "ਹਟਾਓ(_R)" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "ਪਰੋਫਾਈਲ" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "ਟੂਲ-ਟਿੱਪ ਦਿਓ(_P)" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "ਮਾਊਸ ਹੇਠਲੇ ਆਬਜੈਕਟ ਬੋਲੋ(_u)" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "ਮਾਊਸ" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "ਸਮਾਂ ਫਾਰਮੈਟ(_T):" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "ਮਿਤੀ ਫਾਰਮੈਟ(_e):" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "ਸਮਾਂ ਤੇ ਤਾਰੀਖ" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "ਬੋਲ ਅੱਪਡੇਟ(_S)" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "ਬਰਾਇੱਲੇ ਅੱਪਡੇਟ(_B)" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "ਫਰੀਕਿਊਂਸੀ (ਸਕਿੰਟ):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "ਲਾਗੂ ਕਰੋ:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "ਬੀਪ ਅੱਪਡੇਟ(_p)" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "ਤਰੱਕੀ ਪੱਟੀ ਅੱਪਡੇਟ" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "ਸਭ ਇਸ ਰਾਹੀਂ ਕਹੋ(_y):" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "ਸਭ ਬੋਲੋ" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "ਆਮ" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "ਵਾਲੀਅਮ(_l):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "ਪਿੱਚ(_t):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "ਦਰ(_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "ਵਿਅਕਤੀ(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "ਭਾਸ਼ਾ(_L):" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "ਸਪੀਚ ਸ਼ੰਸ਼ਲੇਸ਼ਕ(_z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "ਬੋਲਣ ਸਿਸਟਮ(_s):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "ਆਵਾਜ਼ ਕਿਸਮ(_V):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "ਵਾਈਸ ਕਿਸਮ ਸੈਟਿੰਗਾਂ" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "ਮਲਟੀਕੇਸ ਸਤਰਾਂ ਸ਼ਬਦਾਂ ਵਾਂਗ ਬੋਲੋ(_d)" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "ਗਲੋਬਲ ਵਾਇਸ ਸੈਟਿੰਗਾਂ" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "ਆਵਾਜ਼" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "ਬੋਲ ਯੋਗ(_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "ਜਾਣਕਾਰੀ(_b)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "ਵੱਧ ਜਾਣਕਾਰੀ" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "ਸਭ(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "ਵਿਰਾਮ ਚਿੰਨ੍ਹ ਪੱਧਰ" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "ਕੇਵਲ ਵਿਖਾਇਆ ਗਿਆ ਟੈਕਸਟ ਹੀ ਬੋਲੋ" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "ਖਾਲੀ ਲਾਇਨਾਂ ਬੋਲ੍ਹੋ" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "ਬੋਲ ਦੂਰੀ ਅਤੇ ਇਕਸਾਰਤਾ(_i)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "ਆਬਜੈਕਟ ਨੀਮੋਨਿਕਸ ਬੋਲੋ(_k)" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "ਟਟੋਰੀਅਲ ਸੁਨੇਹੇ ਬੋਲੋ" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "ਰੰਗ ਦੇ ਨਾਂ ਬੋਲੋ(_p)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "ਵਰਣਨ ਨੂੰ ਬੋਲੋ(_d)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "ਬੋਲਿਆ ਪ੍ਰਸੰਗ" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "ਬੋਲੀ" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "ਬਰਾਲੀ ਸਹਿਯੋਗ ਯੋਗ(_S)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "ਸੰਖੇਪ ਰੋਲ ਨਾਂ(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "ਲਾਈਨ ਅੰਤ ਨਿਸ਼ਾਨ ਆਯੋਗ(_e)" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "ਕਨਟਰਾਸ਼ਨ ਟੇਬਲ(_T):" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "ਕਨਟੈਕਟਡ ਬਰੇਇਲ ਯੋਗ(_E)" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "ਸ਼ਬਦ ਸਮੇਟਣਾ ਸਮਰੱਥ(_w)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "ਡਿਸਪਲੇਅ ਸੈਟਿੰਗਾਂ" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "ਕੋਈ ਨਹੀਂ(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "ਚੋਣਕਾਰ ਇੰਡੀਕੇਟਰ" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "ਹਾਇਰਪਲਿੰਕ ਇੰਡੀਕੇਟਰ" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "ਫ਼ਲੈਸ਼ ਸੁਨੇਹੇ ਸਮਰੱਥ(_m)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "ਫ਼ਲੈਸ਼ ਸੁਨੇਹਾ ਸੈਟਿੰਗਾਂ" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ਬਰਾਇੱਲੇ" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "ਸਵਿੱਚ ਗੂੰਜ ਯੋਗ(_k)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "ਅੱਖਰ ਸਵਿੱਚਾਂ ਯੋਗ(_a)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "ਮਾਡੀਫਾਇਰ ਸਵਿੱਚਾਂ ਯੋਗ(_m)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "ਫੰਕਸ਼ਨ ਸਵਿੱਚਾਂ ਯੋਗ(_f)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "ਸਪੇਸ ਸਮਰੱਥ(_s)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "ਮਾਡੀਫਾਇਰ ਸਵਿੱਚਾਂ ਯੋਗ(_m)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "ਫੰਕਸ਼ਨ ਸਵਿੱਚਾਂ ਯੋਗ(_f)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "ਕਾਰਵਾਈ ਕੁੰਜੀਆਂ ਯੋਗ(_t)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "ਨੇਵੀਗੇਸ਼ਨ ਸਵਿੱਚਾਂ ਯੋਗ(_n)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "ਸ਼ਬਦ ਰਾਹੀਂ ਗੂੰਜ ਯੋਗ(_w)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "ਸ਼ਬਦ ਰਾਹੀਂ ਗੂੰਜ ਯੋਗ(_s)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "ਗੂੰਜ" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "ਸਕਰੀਨ ਰੀਡਰ ਮੋਡੀਫਾਇਰ ਸਵਿੱਚਾਂ(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "ਸਵਿੱਚ ਬਾਈਡਿੰਗ" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "ਉਚਾਰਨ ਡਿਕਸ਼ਨਰੀ" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "ਨਵੀਂ ਐਂਟਰੀ(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "ਹਟਾਓ(_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "ਉਚਾਰਨ" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "ਸਭ ਬੋਲੋ(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "ਕੁਝ ਨਾ ਬੋਲੋ(_n)" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "ਰੀਸੈੱਟ(_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "ਲਿਖਤ ਗੁਣ" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "ਤਲ ਉੱਤੇ ਭੇਜੋ(_b)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "ਹੇਠਾਂ ਭੇਜੋ(_d)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "ਇੱਕ ਉੱਤੇ ਭੇਜੋ(_u)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "ਉੱਤੇ ਭੇਜੋ(_t)" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "ਚੁਣੇ ਗੁਣ ਅਡਜੱਸਟ ਕਰੋ" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "ਬਰੇਇਲ ਇੰਡੀਕੇਟਰ" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "ਟੈਕਸਟ ਗੁਣ" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "ਸਹਾਇਕ" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "ਘੱਟ" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "ਸਹਾਇਕ" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "ਭਾਸ਼ਾ(_L):" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "ਯੇਨ" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "ਸਕੇਲ ਫੈਕਟਰ(_f):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "ਬੈਕਗਰਾਊਂਡ ਰੰਗ" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "ਬੈਕਗਰਾਊਂਡ ਪੂਰੀ ਉਚਾਈ" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "ਬੈਕਗਰਾਊਂਡ ਸਟਿੱਪਲ" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "ਦਿਸ਼ਾ" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "ਸੋਧਯੋਗ" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "ਪਰਿਵਾਰ ਨਾਂ" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "ਫਾਰਗਰਾਊਂਡ ਰੰਗ" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "ਫਾਰਗਰਾਊਂਡ ਸਟਿੱਪਲ" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "ਫੋਂਟ ਪਰਭਾਵ" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "ਹਾਸ਼ੀਏ ਤੋਂ ਦੂਰ" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "ਗਲਤੀ" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "ਅਦਿੱਖ" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "ਇਕਸਾਰ" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "ਭਾਸ਼ਾ" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "ਖੱਬਾ ਹਾਸ਼ੀਆ" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "ਲਾਈਨ ਉਚਾਈ" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "ਪ੍ਹੈਰਾ ਸਟਾਈਲ" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "ਪਿਕਸਲ ਉੱਤੇ ਲਾਈਨਾਂ" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "ਪਿਕਸਲ ਹੇਠਾਂ ਲਾਈਨਾਂ" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "ਪਿਕਸਲਾਂ 'ਚ ਸਮੇਟੇ" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "ਸੱਜਾ ਹਾਸ਼ੀਆ" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "ਉਭਾਰੋ" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "ਸਕੇਲ" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "ਸਾਈਜ਼" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "ਖਿੱਚੋ" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "ਵਿੰਨੋ" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "ਸਾਈਟਲ" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "ਟੈਕਸਟ ਸਜਾਵਟ" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "ਟੈਕਸਟ ਘੁੰਮਾਓ" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "ਟੈਕਸਟ ਛਾਂ" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "ਹੇਠਾਂ ਲਾਈਨ" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "ਬਦਲ" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "ਵਰਟੀਕਲ ਇਕਸਾਰ" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "ਉਚਾਈ" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "ਸਮੇਟਣ ਮੋਡ" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "ਲਿਖਣ ਢੰਗ" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "ਸੱਚ" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "ਝੂਠ" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ਕੋਈ ਨਹੀਂ" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "ਅੰਗਰੇਵੀ" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "ਅੰਬੋਸ" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "ਆਉਟਲਾਈਨ" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "ਲਾਈਨ-ਉੱਤੇ" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "ਲਾਈਨ ਲਾਓ" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "ਖਾਲੀ" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "ਕਾਲਾ" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "ਇੱਕਲਾ" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "ਦੂਹਰਾ" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "ਘੱਟ" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "ਅੱਖਰ" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "ਸ਼ਬਦ" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "ਸ਼ਬਦ ਅੱਖਰ" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "ਖੱਬੇ" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "ਸੱਜੇ" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "ਕੇਂਦਰ" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "ਇਕਸਾਰ ਨਹੀਂ" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "ਭਰੋ" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ਅਲਟਰਾ ਠੰਡਾ" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "ਬਹੁਤ ਠੰਡਾ" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "ਠੰਡਾ" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "ਅਰਧ ਠੰਡਾ" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "ਸਧਾਰਨ" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "ਅਰਧ ਫੈਲਿਆ" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "ਫੈਲਾਇਆ" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "ਬਹੁਤ ਫੈਲਿਆ" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ਐਲਟਰਾ ਫੈਲਿਆ" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "ਛੋਟਾ ਕੈਪਸ" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "ਤਿਰਛੇ" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "ਟੇਡੇ" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "ਡਿਫਾਲਟ" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "ਟੈਕਸਟ ਬਾਡੀ" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "ਹੈਡਿੰਗ" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "ਬੇਸ-ਲਾਈਨ" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "ਸਬ" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "ਸੁਪਰ" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "ਉੱਤੇ" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "ਟੈਕਸਟ-ਉੱਤੇ" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "ਮੱਧ" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "ਤਲ" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "ਟੈਕਸਟ-ਤਲ" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "ਵਾਧਾ" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "ਗੂੜਾ" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "ਸ਼ਬਦ-ਜੋੜ" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "ਬਦਲਣ ਲਈ ਸਪੇਸ ਦੱਬੋ।" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "ਫੈਲਾਉਣ ਲਈ ਸਪੇਸ ਦੱਬੋ ਅਤੇ ਇੱਕ ਆਈਟਮ ਚੁਣਨ ਵਾਸਤੇ ਉੱਤੇ ਅਤੇ ਹੇਠਾਂ ਦੀ ਵਰਤੋਂ ਕਰੋ।" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "ਅਧੀਨ ਵਿੰਡੋ ਲਈ ਫੋਕਸ ਦੇਣ ਵਾਸਤੇ Alt+F6 ਦੱਬੋ।" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "ਆਈਟਮਾਂ ਨੂੰ ਹਿਲਾਉਣ ਵਾਸਤੇ, ਜਾਂ ਤਾਂ ਤੀਰ ਨਿਸ਼ਾਨ ਵਰਤੋਂ ਜਾਂ ਖੋਜ ਲਈ ਉੱਤੇ ਲਿਖੋ।" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "ਸਿਸਟਮ ਮੇਨੂ ਲੈਣ ਵਾਸਤੇ Alt+F1 ਸਵਿੱਚ ਦੱਬੋ।" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "ਇੱਕ ਆਈਟਮ ਚੁਣਨ ਵਾਸਤੇ ਉੱਤੇ ਅਤੇ ਹੇਠਾਂ ਵਰਤੋਂ।" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "ਸਮੇਟਣ ਵਾਸਤੇ ਸਿਫਟ ਪਲੱਸ ਖੱਬਾ ਦੱਬੋ।" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "ਫੈਲਾਉਣ ਵਾਸਤੇ ਸਿਫਟ ਪਲੱਸ ਸੱਜਾ ਦੱਬੋ।" - -#: src/cthulhu/tutorialgenerator.py:397 -#, fuzzy -msgid "To activate press return." -msgstr "ਸਰਗਰਮ ਕਰਨ ਵਾਸਤੇ ਸਪੇਸ ਦੱਬੋ।" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "ਟੈਕਸਟ 'ਚ ਲਿਖੋ।" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "ਹੋਰ ਟੈਬਾਂ ਵੇਖਣ ਵਾਸਤੇ ਖੱਬਾ ਅਤੇ ਸੱਜਾ ਵਰਤੋਂ।" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "ਸਰਗਰਮ ਕਰਨ ਵਾਸਤੇ ਸਪੇਸ ਦੱਬੋ।" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "ਚੁਣੇ ਮੁੱਲ ਲਈ ਉੱਤੇ ਜਾਂ ਹੇਠਾਂ ਤੀਰ ਵਰਤੋਂ ਜਾਂ ਲੋੜੀਦਾ ਗਿਣਤੀ ਨੰਬਰ ਲਿਖੋ।" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "ਬਦਲਣ ਵਾਸਤੇ ਤੀਰ ਸਵਿੱਚ ਵਰਤੋਂ।" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"ਏਧਰ-ਓਧਰ ਜਾਣ ਵਾਸਤੇ, ਖੱਬਾ ਜਾਂ ਸੱਜਾ ਤੀਰ ਦੱਬੋ। ਆਈਟਮਾਂ ਵਿੱਚ ਜਾਣ ਲਈ ਉੱਤੇ ਜਾਂ ਹੇਠਾਂ ਤੀਰ ਵਰਤੋਂ।" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "ਸਬ-ਮੇਨੂ ਵਿੱਚ ਜਾਣ ਵਾਸਤੇ, ਸੱਜਾ ਤੀਰ ਦੱਬੋ।" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"ਘਟਾਉਣ ਵਾਸਤੇ ਖੱਬਾ ਤੀਰ ਦੱਬੋ, ਵਧਾਉਣ ਵਾਸਤੇ ਸੱਜਾ ਤੀਰ ਦੱਬੋ। ਘੱਟੋ-ਘੱਟ ਕਰਨ ਵਾਸਤੇ ਘਰ (home) ਦੱਬੋ, " -"ਅਤੇ ਵੱਧੋ-ਵੱਧ ਲਈ ਐਂਡ (end) ਦੱਬੋ।" diff --git a/po/pl.po b/po/pl.po deleted file mode 100644 index 1344ea9..0000000 --- a/po/pl.po +++ /dev/null @@ -1,9306 +0,0 @@ -# Polish translation for cthulhu. -# Copyright © 2007-2023 the cthulhu authors. -# This file is distributed under the same license as the cthulhu package. -# Stanisław Małolepszy , 2007. -# Piotr Leszczyński , 2008-2009. -# Tomasz Dominikowski , 2009. -# Wadim Dziedzic , 2009. -# Piotr Drąg , 2010-2023. -# Paweł Żołnowski , 2014. -# Aviary.pl , 2007-2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-15 17:05+0200\n" -"Last-Translator: Piotr Drąg \n" -"Language-Team: Polish \n" -"Language: pl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " -"|| n%100>=20) ? 1 : 2);\n" - -msgid "Cthulhu Screen Reader" -msgstr "Czytnik ekranowy Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "czytnik;ekran;dostępność;mowa;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Czeskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Hiszpańskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanadyjskie francuskie 2. stopnia" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francuskie 2. stopnia" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Łotewskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Niderlandzkie holenderskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norweskie 0. stopnia" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norweskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norweskie 2. stopnia" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norweskie 3. stopnia" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugalskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Szwedzkie 1. stopnia" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Walijskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Walijskie 2. stopnia" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Niemieckie 0. stopnia" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Niemieckie 1. stopnia" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Niemieckie 2. stopnia" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Brytyjskie angielskie 2. stopnia" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Brytyjskie angielskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Amerykańskie angielskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Amerykańskie angielskie 2. stopnia" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadyjskie francuskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francuskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Greckie 1. stopnia" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi 1. stopnia" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Węgierski komputer 8-punktowy" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Węgierskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Węgierskie 2. stopnia" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Włoskie 1. stopnia" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgijskie holenderskie 1. stopnia" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "odstęp" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nowy wiersz" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulacja" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "wykrzyknik" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "cudzysłów" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "znak hash" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "i" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "lewy nawias" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "prawy nawias" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "gwiazdka" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "przecinek" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "myślnik" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "kropka" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "ukośnik" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dwukropek" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "średnik" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "znak mniejszości" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "znak równości" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "znak większości" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "znak zapytania" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "małpa" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "lewy nawias kwadratowy" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "ukośnik wsteczny" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "prawy nawias kwadratowy" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "daszek" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "podkreślenie" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "odwrotna kreska" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "lewy nawias klamrowy" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "pionowa kreska" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "prawy nawias klamrowy" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tylda" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "spacja niełamliwa" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "odwrócony wykrzyknik" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centy" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "funty" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "znak waluty" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "pionowa kreska przerywana" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "znak akapitu" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diereza" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "znak praw autorskich" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a w indeksie górnym" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "lewy podwójny cudzysłów ostrokątny" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "znak zaprzeczenia" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "łącznik opcjonalny" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "zastrzeżony znak towarowy" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "nadkreślenie" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "stopnie" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "znak plus-minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "dwa w indeksie górnym" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "trzy w indeksie górnym" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "kreska" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mi" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "znak akapitu" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "punkt środkowy" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "haczyk" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "jeden w indeksie górnym" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "liczebnik porządkowy" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "prawy podwójny cudzysłów ostrokątny" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "jedna czwarta" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "jedna druga" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "trzy czwarte" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "odwrócony znak zapytania" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a z kreską" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "WIELKIE A Z ODWROTNĄ KRESKĄ" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "WIELKIE A Z KRESKĄ" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "WIELKIE A Z DASZKIEM" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "WIELKIE A Z TYLDĄ" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "WIELKIE A Z UMLAUTEM" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "WIELKIE A Z KÓŁKIEM" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "WIELKA ŁACIŃSKA LIGATURA AE" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "WIELKIE C Z HACZYKIEM" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "WIELKIE E Z ODWROTNĄ KRESKĄ" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "WIELKIE E Z KRESKĄ" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "WIELKIE E Z DASZKIEM" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "WIELKIE E Z UMLAUTEM" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "WIELKIE I Z ODWROTNĄ KRESKĄ" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "WIELKIE I Z KRESKĄ" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "WIELKIE I Z DASZKIEM" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "WIELKIE I Z UMLAUTEM" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "WIELKI ZNAK ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "WIELKIE N Z TYLDĄ" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "WIELKIE O Z ODWROTNĄ KRESKĄ" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "WIELKIE O Z KRESKĄ" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "WIELKIE O Z DASZKIEM" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "WIELKIE O Z TYLDĄ" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "WIELKIE O Z UMLAUTEM" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "znak iloczynu" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "WIELKIE PRZEKREŚLONE O" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "WIELKIE U Z ODWROTNĄ KRESKĄ" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "WIELKIE U Z KRESKĄ" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "WIELKIE U Z DASZKIEM" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "WIELKIE U Z UMLAUTEM" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "WIELKIE Y Z KRESKĄ" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "WIELKI ZNAK THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "niemiecka ligatura es-zet" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a z odwrotną kreską" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a z daszkiem" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a z tyldą" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a z umlautem" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a z kółkiem" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "łacińska ligatura ae" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c z haczykiem" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e z odwrotną kreską" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e z kreską" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e z daszkiem" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e z umlautem" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i z odwrotną kreską" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i z kreską" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i z daszkiem" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i z umlautem" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "znak eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n z tyldą" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o z odwrotną kreską" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o z kreską" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o z daszkiem" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o z tyldą" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o z umlautem" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "znak ilorazu" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "przekreślone o" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "znak thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u z kreską" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u z odwrotną kreską" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u z daszkiem" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u z umlautem" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y z kreską" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y z umlautem" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "WIELKIE Y z UMLAUTEM" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "floren" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "półpauza" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "lewy cudzysłów pojedynczy" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "prawy cudzysłów pojedynczy" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "dolny apostrofowy cudzysłów pojedynczy" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "lewy cudzysłów podwójny" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "prawy cudzysłów podwójny" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dolny apostrofowy cudzysłów podwójny" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "krzyż" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "podwójny krzyż" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "znak wyliczenia" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "znak wyliczenia w formie trójkąta" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prim" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "bis" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "ter" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "znak wyliczenia w formie kreski" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "znak handlowy" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "znak wyboru" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "wytłuszczony znak wyboru" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "znak wyliczenia w formie iksa" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "0 w indeksie górnym" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "4 w indeksie górnym" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "5 w indeksie górnym" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "6 w indeksie górnym" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "7 w indeksie górnym" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "8 w indeksie górnym" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "9 w indeksie górnym" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "plus w indeksie górnym" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "minus w indeksie górnym" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "znak równości w indeksie górnym" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "lewy nawias w indeksie górnym" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "prawy nawias w indeksie górnym" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n w indeksie górnym" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "0 w indeksie dolnym" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "1 w indeksie dolnym" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "2 w indeksie dolnym" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "3 w indeksie dolnym" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "4 w indeksie dolnym" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "5 w indeksie dolnym" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "6 w indeksie dolnym" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "7 w indeksie dolnym" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "8 w indeksie dolnym" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "9 w indeksie dolnym" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "plus w indeksie dolnym" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "minus w indeksie dolnym" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "znak równości w indeksie dolnym" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "lewy nawias w indeksie dolnym" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "prawy nawias w indeksie dolnym" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "czarny kwadrat" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "czarny romb" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "znak zastąpienia obiektu" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Przenieś kursor do bieżącego elementu" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" -"Wykonaj kliknięcie lewym przyciskiem myszy na elemencie przeglądanym " -"w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" -"Wykonaj kliknięcie prawym przyciskiem myszy na elemencie przeglądanym " -"w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Odczytaj cały dokument" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Odczytaj całe okno w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Wskaż obecną pozycję" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Wskaż szczegółowo obecną pozycję" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Odczytaj obecne zaznaczenie" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Odczytaj informacje o odnośniku" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Przedstaw domyślny przycisk" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Przedstaw zawartość paska stanu" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Przedstaw zawartość paska tytułowego" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Otwórz okno wyszukiwania" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Pokaż listę działań" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Wyszukaj następne wystąpienie ciągu znaków" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Wyszukaj poprzednie wystąpienie ciągu znaków" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Przełącz tryb nawigacyjny" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" -"Przełącz ograniczenie przeglądu płaskiego do bieżącego obiektuPrzełącz " -"ograniczanie przeglądania w trybie nawigacyjnym do aktywnego obiektu" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Przenieś przeglądanie w trybie nawigacyjnym do pozycji początkowej" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Przenieś przeglądanie w trybie nawigacyjnym do pozycji końcowej" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Przenieś przeglądanie w trybie nawigacyjnym do poprzedniego wiersza" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Odczytaj wiersz przeglądany w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Literuj wiersz przeglądany w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Odczytaj fonetycznie wiersz przeglądany w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" -"Przenieś przeglądanie w trybie nawigacyjnym do początku następnego wiersza" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" -"Przenieś przeglądanie w trybie nawigacyjnym do poprzedniego elementu lub " -"słowa" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Odczytaj element lub słowo przeglądane w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Literuj element lub słowo przeglądane w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Odczytaj fonetycznie element lub słowo przeglądane w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" -"Przenieś przeglądanie w trybie nawigacyjnym do następnego elementu lub słowa" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" -"Przenieś przeglądanie w trybie nawigacyjnym do słowa znajdującego się nad " -"bieżącym słowem" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Odczytaj obiekt przeglądany w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" -"Przenieś przeglądanie w trybie nawigacyjnym do słowa znajdującego się pod " -"bieżącym słowem" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Przenieś przeglądanie w trybie nawigacyjnym do poprzedniego znaku" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Odczytaj znak przeglądany w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Odczytaj fonetycznie znak przeglądany w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Odczytaj wartość unikodu znaku przeglądanego w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Przenieś przeglądanie w trybie nawigacyjnym do następnego znaku" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Przenieś przeglądanie w trybie nawigacyjnym na koniec wiersza" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Przenieś przeglądanie w trybie nawigacyjnym w lewy dolny róg" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Skopiuj treść przeglądaną w trybie nawigacyjnym do schowka" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Dołącz treść przeglądaną w trybie nawigacyjnym do schowka" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Wyświetl treść przeglądaną w trybie nawigacyjnym" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Przełącz między czytaniem jedynie bieżącej komórki tabeli a czytaniem całego " -"wiersza" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Odczytaj atrybuty przypisane bieżącemu znakowi" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Przesuń znaki na monitorze brajlowskim w lewo" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Przesuń znaki na monitorze brajlowskim w prawo" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Wróć do obiektu" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Włącz lub wyłącz skróty brajlowskie" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Wykonaj polecenie klawisza pozycji kursora" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Oznacz początek zaznaczenia" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Oznacz koniec zaznaczenia" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Włącz tryb nauki. Aby go opuścić, należy wcisnąć klawisz Escape" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Zmniejsz prędkość mowy" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Zwiększ prędkość mowy" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Zmniejsz wysokość głosu" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Zwiększ wysokość głosu" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Zwiększ głośność mowy" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Zmniejsz głośność mowy" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Wybierz poprzednie ustawienie mowy" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Wybierz następne ustawienie mowy" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Zmniejsz bieżące ustawienie mowy" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Zwiększ bieżące ustawienie mowy" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Zapisz ustawienia mowy" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Przełącz wyciszanie mowy" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Przełącz poziom informacji mowy" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Przełącz tryb uśpienia" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Zakończ działanie czytnika ekranowego" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Wyświetl okno preferencji" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Wyświetl okno preferencji programu" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Przełącz odczytywanie wcięć i wyrównania tekstu" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Zmień styl odczytywania liczb" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Przejdź do następnego poziomu odczytywania interpunkcji" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Przejdź do następnego syntezatora mowy" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Przejdź do następnego profilu ustawień" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Przejdź do następnego stylu kapitalizacji" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Przejdź do następnego poziomu powtarzania klawiszy" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Przełącz poziom debugowania podczas uruchomienia" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Powiadom o bieżącej pozycji względem wybranej zakładki" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Przejdź do poprzedniego położenia zakładki" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Przejdź do zakładki" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Przejdź do następnego położenia zakładki" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Dodaj zakładkę" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Zapisz zakładki" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Przełącz tryb odczytywania kursorem myszy" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Przedstaw obecny czas" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Przedstaw obecną datę" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Przedstaw rozmiar i położenie aktywnego obiektu" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Przedstaw następne polecenie do aktywnego programu" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" -"Odczytaj i wyświetl na monitorze brajlowskim ostatniej wiadomości z pokoju " -"rozmów" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Przełącz informowanie o pisaniu wiadomości przez znajomych" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Przełącz dostęp do historii poszczególnych pokojów rozmów" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Przełącz poprzedzanie odczytywania wiadomości z pokojów rozmów odczytaniem " -"nazwy pokoju" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Wiersz w lewo" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Wiersz w prawo" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Wiersz wyżej" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Wiersz niżej" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Wstrzymaj" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Górny lewy róg" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Dolny lewy róg" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Pozycja kursora" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Sześć punktów" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Pozycja kursora" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Początek zaznaczenia" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Koniec zaznaczenia" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Przedstaw ostatni komunikat powiadamiania" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Prezentuje listę komunikatów powiadamiania" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Przedstaw poprzedni komunikat powiadamiania" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Przedstaw następny komunikat powiadamiania" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Przejdź do następnego znaku" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Przejdź do poprzedniego znaku" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Przejdź do następnego słowa" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Przejdź do poprzedniego słowa" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Przejdź do następnego wiersza" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Przejdź do poprzedniego wiersza" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Przejdź na początek pliku" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Przejdź na koniec pliku" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Przejdź na początek wiersza" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Przejdź na koniec wiersza" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Przejdź do następnego obiektu" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Przejdź do poprzedniego obiektu" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Spowoduj wyświetlenie elementów listy rozwijanej" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Przełącz pomiędzy natywną nawigacją a nawigacją czytnika ekranowego" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Podwyższ ustawienia grzeczności obszaru dynamicznego" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Ustaw domyślny poziom grzeczności na: wyłączony" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Przejrzyj informacje z obszaru dynamicznego" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitoruj obszary dynamiczne" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Przejdź do obiektu uaktywnianego po najechaniu myszą" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Ustaw wiersz, który będzie służyć za dynamiczne nagłówki kolumn" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Usuń dynamiczne nagłówki kolumn" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Ustaw kolumnę, która będzie służyć za dynamiczne nagłówki wierszy" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Usuń dynamiczne nagłówki wierszy" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Przedstaw zawartość wiersza wejściowego" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Przełącz obsługę strukturalnych klawiszy nawigacyjnych" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Przejdź do poprzedniego cytatu blokowego" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Przejdź do następnego cytatu blokowego" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Wyświetl listę cytatów blokowych" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Przejdź do poprzedniego przycisku" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Przejdź do następnego przycisku" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Wyświetl listę przycisków" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Przejdź do poprzedniego pola wyboru" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Przejdź do następnego pola wyboru" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Wyświetl listę pól wyboru" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Przejdź do poprzedniego klikalnego elementu" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Przejdź do następnego klikalnego elementu" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Wyświetl listę klikalnych elementów" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Przejdź do poprzedniej listy rozwijanej" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Przejdź do następnej listy rozwijanej" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Przejdź na początek kontenera" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Przejdź na koniec kontenera" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Wyświetl listę list rozwijanych" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Przejdź do poprzedniej pozycji" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Przejdź do następnej pozycji" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Wyświetl listę pozycji" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Przejdź do poprzedniego pola formularza" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Przejdź do następnego pola formularza" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Wyświetl listę pól formularza" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Przejdź do poprzedniego nagłówka" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Przejdź do następnego nagłówka" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Wyświetl listę nagłówków" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Przejdź do poprzedniego nagłówka o %d. poziomie" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Przejdź do następnego nagłówka o %d. poziomie" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Wyświetl listę nagłówków o %d. poziomie" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Przejdź do poprzedniej wewnętrznej ramki" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Przejdź do następnej wewnętrznej ramki" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Wyświetl listę wewnętrznych ramek" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Przejdź do poprzedniego obrazu" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Przejdź do następnego obrazu" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Wyświetl listę obrazów" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Przejdź do poprzednich współrzędnych" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Przejdź do następnych współrzędnych" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Wyświetl listę współrzędnych" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Przejdź do poprzedniego dużego obiektu" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Przejdź do następnego dużego obiektu" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Wyświetl listę dużych obiektów" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Przejdź do poprzedniego odnośnika" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Przejdź do następnego odnośnika" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Wyświetl listę odnośników" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Przejdź do poprzedniej listy" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Przejdź do następnej listy" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Wyświetl listę list" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Przejdź do poprzedniego elementu listy" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Przejdź do następnego elementu listy" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Wyświetl listę elementów listy" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Przejdź do poprzedniego obszaru dynamicznego" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Przejdź do następnego obszaru dynamicznego" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" -"Przejdź do ostatniego obszaru dynamicznego, z którego pochodzi ogłoszenie" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" -"Przejdź do elementu nadrzędnego obiektu za pomocą zaznaczania nawigacji." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" -"Przejdź do pierwszego elementu potomnego obiektu za pomocą zaznaczania " -"nawigacji." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" -"Przejdź do następnego elementu pokrewnego obiektu za pomocą zaznaczania " -"nawigacji." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" -"Przejdź do poprzedniego elementu pokrewnego obiektu za pomocą zaznaczania " -"nawigacji." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Kliknij obiekt za pomocą zaznaczania nawigacji." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Przełącz uproszczoną nawigację między obiektami." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Przejdź do poprzedniego akapitu" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Przejdź do następnego akapitu" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Wyświetl listę akapitów" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Przejdź do poprzedniego pola jednokrotnego wyboru" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Przejdź do następnego pola jednokrotnego wyboru" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Wyświetla listę pól jednokrotnego wyboru" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Przejdź do poprzedniego separatora" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Przejdź do następnego separatora" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Przejdź do poprzedniej tabeli" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Przejdź do następnej tabeli" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Wyświetl listę tabel" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Przejdź do komórki niżej" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Przejdź do pierwszej komórki w tabeli" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Przejdź do ostatniej komórki w tabeli" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Przejdź do komórki na lewo" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Przejdź do komórki na prawo" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Przejdź do komórki wyżej" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Przełącz tryb układu" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Przełącz między trybem przeglądania a trybem zaznaczania" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Włącz lepki tryb zaznaczania" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Włącz lepki tryb przeglądania" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Przejdź do poprzedniego nieodwiedzonego odnośnika" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Przejdź do następnego nieodwiedzonego odnośnika" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Wyświetl listę nieodwiedzonych odnośników" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Przejdź do poprzedniego odwiedzonego odnośnika" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Przejdź do następnego odwiedzonego odnośnika" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Wyświetl listę odwiedzonych odnośników" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "alice blue" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antique white" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akwamaryna" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "lazur" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beż" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "czarny" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "blanszowany migdał" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "niebieski" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "niebieskofioletowy" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "brązowy" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "cadet blue" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "czekoladowy" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koralowy" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "cornflower blue" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "cornsilk" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "karmazynowy" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cyjan" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "ciemnoniebieski" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "ciemny cyjan" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "ciemny goldenrod" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "ciemnoszary" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "ciemnozielony" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "ciemny khaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "ciemna magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "ciemny oliwkowozielony" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "ciemnopomarańczowy" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "ciemna orchidea" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "ciemnoczerwony" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "ciemny łososiowy" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "ciemny morskozielony" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "ciemny szaroniebieski" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "ciemny niebieskoszary" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "ciemny turkus" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "ciemnofioletowy" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "nasycony różowy" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "nasycony błękit" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "zgaszony szary" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodger blue" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "ceglany" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "floral white" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "leśny" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksja" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "ghost white" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "złoty" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "goldenrod" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "szary" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "zielony" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "zielonożółty" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "honeydew" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "rażący różowy" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indian red" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indygo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "kość słoniowa" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lawendowy" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "róż lawendowy" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "trawiasty" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "cytrynowy szyfon" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "jasnoniebieski" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "jasny koralowy" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "jasny cyjan" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "jasna żółć goldenrod" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "jasnoszary" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "jasnozielony" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "jasnoróżowy" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "jasny łososiowy" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "jasny morskozielony" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "jasny błękit" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "jasny niebieskoszary" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "jasny stalowoniebieski" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "jasnożółty" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limonkowy" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limonkowozielony" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "lniany" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "kasztanowy" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "średnia akwamaryna" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "średni niebieski" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "średnia orchidea" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "średni fioletowy" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "średni morskozielony" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "średni szaroniebieski" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "średni wiosennozielony" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "średni turkus" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "średni fioletowoczerwony" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "ciemnogranatowy" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "jasny miętowy" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "różany" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokasynowy" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajo white" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "granatowy" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "stara koronka" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliwkowy" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "oliwkowy roboczy" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "pomarańczowy" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "pomarańczowoczerwony" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchidea" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "blady goldenrod" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "bladozielony" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "blady turkus" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "blady fioletowoczerwony" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "ptyś brzoskwiniowy" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "różowy" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "śliwkowy" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "powder blue" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "fioletowy" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "czerwony" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "różany brąz" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "royal blue" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "saddle brown" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "łososiowy" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "piaskowy brąz" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "morskozielony" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "muszla" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sjena palona" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "srebrny" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "błękit" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "szaroniebieski" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "niebieskoszary" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "śnieg" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "wiosennozielony" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "stalowoniebieski" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "jasnobrązowy" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "morski" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "oset" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "pomidorowy" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turkus" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "fiołkowy" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "pszenica" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "biały" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "biały dym" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "żółty" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "żółtozielony" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktywuj" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatyczny tryb zaznaczania podczas nawigacji strukturalnej" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatyczny tryb zaznaczania podczas nawigacji karetką" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatyczny tryb zaznaczania podczas natywnej nawigacji" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punkt _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punkt _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Pun_kty 7 i 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Anuluj" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Przejdź do" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Dźwięk" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Nic" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Odczyt" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "_Informowanie o pisaniu wiadomości przez znajomych" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "_Dostęp do historii poszczególnych pokojów rozmów" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Odczytywanie wiadomości z" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Wszystkich ka_nałów" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Wszystkich kanałów, jeśli okno %s jest akt_ywne" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Kanału, którego okno jest akty_wne" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Odczytywanie nazwy pokoju rozmów" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Tryb układu dla treści" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "podwójne kliknięcie" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "potrójne kliknięcie" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Domyślny syntezator mowy" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Poszukiwany tekst" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Tekst wymawiany" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Echo _znaków" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Klawisze znaków _diakrytycznych" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Bieżą_ca pozycja" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimalna ilość zgodnych znaków:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opcje wyszukiwania" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Odcz_ytywanie tylko nowych wierszy w trakcie wyszukiwania" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "O_dczytywanie wyników wyszukiwania w trakcie trwania procesu" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Polecenie" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Przypisanie klawiszy" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Domyślne" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Tryb nauki" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Działania" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Przypisania monitora brajlowskiego" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Zakładki" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Data i czas" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Odczytywanie kursorem myszy" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Nawigacja między obiektami" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Informacje o obiekcie" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Nieprzypisane" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Przeglądanie w trybie nawigacyjnym" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Mowa i ilość informacji" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Treść przeglądana w trybie nawigacyjnym" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Zmodyfikowane" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Standardowy" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Powiadomienia" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Otrzymano" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Przedstawianie powiadomień" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferencje Cthulhu dla %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Podkreślenie na monitorze" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Aktywny poza" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Odczytywanie" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Zapisz profil jako konflikt" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Konflikt profili użytkownika" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profil %s już istnieje.\n" -"Kontynuować aktualizowanie istniejącego profilu za pomocą nowych zmian?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Wczytaj profil użytkownika" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Wprowadzone zostaną zmiany w aktywnym profilu. Jeśli\n" -"w tym samym czasie użytkownik wprowadził zmiany w\n" -"preferencjach, to zostaną one odrzucone podczas\n" -"wczytywania profilu.\n" -"\n" -"Kontynuować wczytywanie profilu, odrzucając poprzednie zmiany?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Zapisz profil jako" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Nazwa profilu:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Usuń profil użytkownika" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Usunięty zostanie profil %s. Wszystkie niezapisane ustawienia oraz " -"ustawienia zapisane w tym profilu zostaną utracone. Kontynuować usuwanie " -"tego profilu i wszystkich powiązanych ustawień?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Wszystkie" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Program" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Okno" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "Br_ak" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Niektór_e" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Wię_kszość" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Wierszu" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Zdaniu" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Cytat blokowy" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Przycisk" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Nagłówek" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Pole wyboru" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Element klikalny" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Lista rozwijana" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Opis" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Nagłówek" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Wewnętrzna ramka" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Obraz" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etykieta" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Współrzędna" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Poziom" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Odnośnik" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Element listy" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Obiekt" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Akapit" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Przycisk wyboru" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rola" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Zaznaczony element" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stan" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Tekst" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "Adres URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Wartość" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Cytaty blokowe" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Przyciski" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Pola wyboru" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Elementy klikalne" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Listy rozwijane" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Pozycje" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Pola formularza" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Nagłówki" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Wewnętrzne ramki" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Obrazy" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Nagłówki o %d. poziomie" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Współrzędne" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Duże obiekty" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Odnośniki" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listy" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Elementy listy" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Akapity" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Przyciski wyboru" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabele" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Nieodwiedzone odnośniki" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Odwiedzone odnośniki" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Nawigacja" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "_Automatyczne rozpoczynanie odczytywania strony po wczytaniu" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Odczytywanie podsumowania strony po wczytaniu" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Dzielenie odczytywanego tekstu na _segmenty pomiędzy pauzami" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Domyślny głos programu %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Domyślny" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Odnośnik" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Systemowy" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Wielkie litery" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Sprawdzanie pisowni" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Lit_erowanie błędu" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Literowanie p_odpowiedzi" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Prezentowanie _kontekstu błędu" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Odczytywanie współrzędnych komórki arkusza kalkulacyjnego" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Odczytywanie zaznaczonego zakresu arkusza kalkulacyjnego" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Informowanie o _komórce nagłówka" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Poruszanie się po tabelach" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Omijanie pustych komó_rek" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Odczytywanie _komórki" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Od_czytywanie współrzędnych komórki" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Odczytywanie ko_mórek połączonych" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nazwa atrybutu" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Kontrola nawigacji karetki" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Nawigacja _strukturalna" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Schemat dźwięków:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Schemat dźwięków" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "N_iska" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d powiadomienie" -msgstr[1] "%d powiadomienia" -msgstr[2] "%d powiadomień" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "lewy Shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "lewy Alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "lewy Control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "prawy Shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "prawy Alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "prawy Control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "lewy klawisz Meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "prawy klawisz Meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "Num Lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "Caps Lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "Caps Lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "Scroll Lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "Page Up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "Page Down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "lewy Tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "Backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "Return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "Enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "w górę" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "w dół" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "w lewo" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "w prawo" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "lewy klawisz Super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "prawy klawisz Super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "pomoc" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "przełącznik trybu" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "Escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "Insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "Delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "Home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "End" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "Begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "daszek" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "kółko" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "przekreślenie" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Prawy Alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Lewy Alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "pogrubione %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "pochylone %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "pogrubione, pochylone %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "pismo %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "pogrubione pismo %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktura %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "podwójnie przekreślone %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "pogrubiona fraktura %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s o zmiennej szerokości" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "pogrubione %s o zmiennej szerokości" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "pochylone %s o zmiennej szerokości" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "pogrubione, pochylone %s o zmiennej szerokości" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s o stałej szerokości" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "bezkropkowe %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "strzałka w lewo" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "strzałka w górę" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "strzałka w prawo" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "strzałka w dół" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "strzałka w lewo i w prawo" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "strzałka w górę i w dół" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "strzałka na północny zachód" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "strzałka na północny wschód" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "strzałka na południowy wschód" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "strzałka w lewo od kreski" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "strzałka w górę od kreski" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "strzałka w prawo od kreski" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "strzałka w dół od kreski" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "podwójna strzałka w lewo" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "podwójna strzałka w górę" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "podwójna strzałka w prawo" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "podwójna strzałka w dół" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "podwójna strzałka w lewo i w prawo" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "podwójna strzałka w górę i w dół" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "podwójna strzałka na północny zachód" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "podwójna strzałka na północny wschód" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "podwójna strzałka na południowy wschód" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "podwójna strzałka na południowy zachód" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "strzałka zwrócona w prawo" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "grot strzałki zwrócony w prawo" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "odjąć" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "mniejsze niż" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "większe niż" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "daszek" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "haczek" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "brewis" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "kropka" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "podwójna pionowa linia" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "poziomy wielokropek" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "dla każdego" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "różnica zbiorów" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "różniczka cząstkowa" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "istnieje" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "nie istnieje" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "zbiór pusty" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "laplasjan" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "jest elementem" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "nie jest elementem" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "jest małym elementem" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "zawiera w sobie element" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "nie zawiera w sobie elementu" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "zawiera w sobie mały element" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "koniec dowodu" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produkt" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koprodukt" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sumowanie" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus-plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus z kropką" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "przez" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "różnica zbioru" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "gwiazdka" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "pierścień" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "punkt" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "pierwiastek kwadratowy" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "pierwiastek sześcienny" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "pierwiastek czwartego stopnia" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "współmiernie do" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "nieskończoność" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "kąt prosty" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "kąt" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "kąt mierzony" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "kąt sferyczny" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "dzieli" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "nie dzieli" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "równoległe do" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "nierównoległe do" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "koniunkcja" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "alternatywa" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "część wspólna" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "suma zbiorów" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "całka" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "całka podwójna" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "całka potrójna" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "całka krzywoliniowa" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "całka powierzchniowa" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "całka objętościowa" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "całka zgodnie z ruchem wskazówek zegara" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "całka krzywoliniowa zgodnie z ruchem wskazówek zegara" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "całka krzywoliniowa przeciwnie do ruchu wskazówek zegara" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "zatem" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "ponieważ" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "stosunek" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporcja" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "minus z kropką" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "nadmiar" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporcja geometryczna" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "jednokładny" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tylda" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "odwrócona tylda" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "odwrócone leniwe S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "fala sinusoidalna" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "produkt wieńcowy" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "nie tylda" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "tylda z minusem" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptotycznie równa się" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "asymptotycznie nie równa się" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "w przybliżeniu równa się" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "w przybliżeniu, ale nie naprawdę równa się" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "w przybliżeniu ani naprawdę nie równa się" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "prawie równa się" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "prawie nie równa się" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "prawie równe lub równa się" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "potrójna tylda" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "wszystko równa się" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "odpowiada" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrycznie odpowiada" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "różnica między" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "zbliża się do limitu" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrycznie równa się" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "w przybliżeniu równa się lub obraz" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "obraz lub w przybliżeniu równa się" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dwukropek ze znakiem równości" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "znak równości z dwukropkiem" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "pierścień w znaku równości" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "pierścień nad znakiem równości" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "zgadza się" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "szacuje" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "równokątny" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "gwiazdka nad znakiem równości" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta nad znakiem równości" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "równa się według definicji" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "zmierzone przez" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "znak zapytania nad znakiem równości" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "nie równa się" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "tożsame z" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "nietożsame z" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "ściśle odpowiada" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "mniejsze lub równe" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "większe lub równe" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "mniejsze nad znakiem równości" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "większe nad znakiem równości" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "mniejsze lub nierówne" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "większe lub nierówne" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "dużo mniej niż" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "dużo więcej niż" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "między" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "nie odpowiada" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "nie mniejsze niż" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "nie większe niż" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "nie mniejsze ani równe" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "nie większe ani równe" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "mniejsze lub odpowiadające" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "większe lub odpowiadające" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "nie mniejsze ani odpowiadające" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "nie większe ani odpowiadające" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "mniejsze lub większe" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "większe lub mniejsze" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "nie mniejsze ani większe" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "nie większe ani mniejsze" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "poprzedza" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "następuje po" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "poprzedza lub równe" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "następuje po lub równe" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "poprzedza lub odpowiada" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "następuje po lub odpowiada" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "nie poprzedza" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "nie następuje po" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "podzbiór" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "nadzbiór" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "nie jest podzbiorem" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "nie jest nadzbiorem" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "podzbiór lub równe" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "nadzbiór lub równe" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "nie jest podzbiorem ani równe" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "nie jest nadzbiorem ani równe" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "podzbiór ze znakiem nierówności" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "nadzbiór ze znakiem nierówności" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "wielozbiór" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "mnożenie wielozbioru" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "suma mnogościowa wielozbioru" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "obraz kwadratowy" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "oryginał kwadratowy" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "obraz kwadratowy lub równa się" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "oryginał kwadratowy lub równa się" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "cap kwadratowy" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "cap kwadratowy" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "plus w okręgu" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "minus w okręgu" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "iloczyn w okręgu" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "dzieli w okręgu" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "kropka w okręgu" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "pierścień w okręgu" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "gwiazdka w okręgu" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "znak równości w okręgu" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "myślnik w okręgu" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus w kwadracie" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "minus w kwadracie" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "iloczyn w kwadracie" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "kropka w kwadracie" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "pinezka w prawo" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "pinezka w lewo" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "pinezka w dół" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "pinezka w górę" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "twierdzenie" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modeluje" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "prawda" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "oddziałuje" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "potrójna kreska pionowa z prawym kołowrotem" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "podwójna kreska pionowa z podwójnym prawym kołowrotem" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "nie dowodzi" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "nieprawda" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "nie oddziałuje" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "przekreślona podwójna kreska pionowa z podwójnym prawym kołowrotem" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "poprzedza w związku" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "następuje po w związku" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "podgrupa normalna" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "ideał" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "podgrupa normalna lub równa się" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "ideał lub równa się" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "oryginał" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "obraz" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "wielomapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "sprzężenie hermitowskie macierzy" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "interkalacja" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "alternatywa wykluczająca" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "dysjunkcja" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "binegacja" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "kąt prosty z łukiem" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "trójkąt prosty" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "diament" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "kropka" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "gwizdka" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "iloczyn dzielenia" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "muszka" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "lewy produkt półprosty normalnego czynnika" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "prawy produkt półprosty normalnego czynnika" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "lewy produkt półprosty" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "prawy produkt półprosty" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "odwrócona tylda znaku równości" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "kręta logiczna alternatywa" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "kręta logiczna koniunkcja" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "podwójny podzbiór" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "podwójny nadzbiór" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "podwójna część wspólna" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "podwójna suma zbiorów" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "widły" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "równe i równoległe do" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "mniejsze niż z kropką" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "większe niż z kropką" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "o wiele mniejsze niż" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "o wiele większe niż" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "mniejsze niż równe lub większe niż" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "większe niż równe lub mniejsze niż" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "równe lub mniejsze niż" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "równe lub większe niż" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "równe lub poprzedza" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "równe lub następuje po" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "nie poprzedza ani równe" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "nie następuje po ani równe" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "nie jest obrazem kwadratowym ani równe" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "nie jest oryginałem kwadratowym ani równe" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "obraz kwadratowy lub nierówne" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "oryginał kwadratowy lub nierówne" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "mniejsze niż, ale nieodpowiadające" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "większe niż, ale nieodpowiadające" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "poprzedza, ale nie odpowiada" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "następuje po, ale nie odpowiada" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "nie jest podgrupą normalną" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "nie jest ideałem" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "nie jest ideałem ani nie równa się" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "nie jest ideałem ani nie równa się" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "wielokropek pionowy" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "wielokropek poziomy na środku" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "wielokropek przekątny od górnego prawego rogu" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "wielokropek przekątny od dolnego prawego rogu" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "jest elementem z długim poziomym przekreśleniem" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "jest elementem z pionową kreską na końcu przekreślenia poziomego" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "jest małym elementem z pionową kreską na końcu przekreślenia poziomego" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "jest elementem z kropką nad znakiem" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "jest elementem z kreską nad znakiem" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "jest małym elementem z kreską nad znakiem" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "jest elementem z kreską pod znakiem" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "jest elementem z dwoma poziomymi przekreśleniami" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "zawiera w sobie element z długim poziomym przekreśleniem" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" -"zawiera w sobie element z pionową kreską na końcu długiego poziomego " -"przekreślenia" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"zawiera w sobie mały element z pionową kreską na końcu długiego poziomego " -"przekreślenia" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "zawiera w sobie element z kreską nad znakiem" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "zawiera w sobie mały element z kreską nad znakiem" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "członkostwo w worku notacji Z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "lewy sufit" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "prawy sufit" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "lewa podłoga" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "prawa podłoga" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "górny nawias klamrowy" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "dolny nawias klamrowy" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "lewy cudzysłów ostrokątny" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "prawy cudzysłów ostrokątny" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "kropka w okręgu" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "suma zbiorów z kropką" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "suma zbiorów z plusem" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "kwadratowa część wspólna" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "kwadratowa suma zbiorów" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "czarny kwadrat" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "biały kwadrat" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "czarny romb" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "białe kółko" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "czarne kółko" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "biały znak wyliczenia" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "mało-średni czarny kwadrat" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s z podkreśleniem" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s z ukośnikiem" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s z pionową linią" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "program" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "pusty" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "pogrubiony" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "zakładka wprowadzona" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "zakładki zapisane" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "nie można zapisać zakładek" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nie odnaleziono zakładek." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Nie odnaleziono zakładki." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Tryb ominięcia włączony." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Nie udało się uzyskać dostępu do ekranu kalkulatora" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Styl kapitalizacji jest ustawiony na ikonę." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "brak" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Styl kapitalizacji jest ustawiony na nie odczytywanie niczego." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "odczyt" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Styl kapitalizacji jest ustawiony na odczytywanie." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Program ma kontrolę nad karetką." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu kontroluje kursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Komórka %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "Zaznaczono %s" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "Zaznaczono od %s do %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "Odznaczono od %s do %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "Odznaczono %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Zabrania używania opcji" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Wymusza użycie opcji" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCJA" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Opcjonalne parametry" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Użycie: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Następujące parametry nie są prawidłowe: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Wyświetla nazwy wszystkich uruchomionych programów" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Wczytuje profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Nie można wczytać profilu: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Nie można uruchomić Cthulhu, ponieważ nie można połączyć się z pulpitem.Nie " -"można uruchomić czytnika ekranowego, ponieważ nie może się on połączyć " -"z pulpitem." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Nie można aktywować menedżera ustawień. Kończenie działania." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Inny proces czytnika ekranowego jest już uruchomiony w tej sesji.\n" -"Polecenie „cthulhu --replace” zastąpi ten proces nowym." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAZWA" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Korzysta z alternatywnego katalogu dla preferencji użytkownika" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "KATALOG" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Wersja tego programu" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Zastąp aktualnie uruchomioną instancję Cthulhu" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Wyświetla ten komunikat pomocy i kończy działanie" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Wysyła wyniki debugowania do pliku debug-RRRR-MM-DD-GG:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Wysyła wyniki debugowania do określonego pliku" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "PLIK" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Preferencje użytkownika (wersja tekstowa)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Preferencje użytkownika (wersja graficzna)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" -"Prosimy zgłaszać błędy na adres https://groups.io/g/stormux (w języku " -"angielskim)." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Wycięto zaznaczenie do schowka." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "wycięto" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Skopiowano zaznaczenie do schowka." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "skopiowano" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Wklejono treść ze schowka." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "wklejono" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Nie informuj o pisaniu wiadomości przez znajomych." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "informuj o pisaniu wiadomości przez znajomych." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Wiadomość z pokoju rozmów %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nowa karta rozmowy %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Nie wymawiaj nazwy pokoju rozmów." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "wymawiaj nazwę pokoju rozmów." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Nie pozwalaj na dostęp do historii pokoju rozmów." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Pozwalaj na dostęp do historii pokoju rozmów." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "początek usunięcia" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "koniec usunięcia" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "początek wstawienia" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "koniec wstawienia" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "początek wyróżnienia" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "koniec wyróżnienia" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "koniec podpowiedzi" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Koniec kontenera." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Brak obiektu w kontenerze." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "zaznaczono wszystkie elementy" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Domyślny przycisk to %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Domyślny przycisk to %s. Wyszarzony" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Nie odnaleziono domyślnego przycisku" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " %s w indeksie dolnym" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " %s w indeksie górnym" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Nie ma w oknie" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "zaznaczono cały dokument" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "odznaczono cały dokument" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "zaznaczono część dokumentu poniżej kursora" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "odznaczono część dokumentu poniżej kursora" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "zaznaczono część dokumentu powyżej kursora" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "odznaczono część dokumentu powyżej kursora" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynamiczny nagłówek kolumn ustawiony dla %d. wiersza" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynamiczny nagłówek kolumn usunięty." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynamiczny nagłówek wierszy ustalony dla kolumny %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynamiczny nagłówek wierszy usunięty." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "pusty" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobajtów" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabajtów" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Nie odnaleziono plików." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Dołączono treść do schowka." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Skopiowano treść do schowka." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Tryb nawigacyjny nie jest używany." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Wejście w tryb nawigacyjny." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Wyjście z trybu nawigacyjnego." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" -"Przeglądanie w trybie nawigacyjnym jest ograniczone do aktywnego obiektu" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Przeglądanie w trybie nawigacyjnym jest nieograniczone" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "ma formułę" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "otwiera okno" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "otwiera siatkę" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "otwiera pole listy" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "otwiera menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "otwiera drzewo" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "odnośnik mapy obrazu" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Wprowadzony klawisz jest już przypisany do %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" -"Przypisane klawisze: %s. Proszę nacisnąć klawisz Enter, aby zatwierdzić " -"zmianę." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Wprowadzony klawisz to: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" -"Przypisanie klawiszy usunięte. Proszę nacisnąć klawisz Enter, aby " -"zatwierdzić zmianę." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Przypisanie klawiszy zostało usunięte." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "proszę wprowadzić nowy klawisz" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "klawisz" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Powtarzanie jest ustawione na powtarzanie klawisza." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nic" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Powtarzanie jest ustawione na niepowtarzanie niczego." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "klawisz i słowo" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Powtarzanie jest ustawione na powtarzanie klawisza i słowa." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "zdanie" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Powtarzanie jest ustawione na powtarzanie zdania." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "słowo" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Powtarzanie jest ustawione na powtarzanie słowa." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "słowo i zdanie" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Powtarzanie jest ustawione na powtarzanie słowa i zdania." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Załączony w: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "symbol aktuarialny" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "pudełko" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "kółko" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "długi znak dzielenia" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "pierwiastek" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "okrągłe pudełko" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "poziome przekreślenie" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "pionowe przekreślenie" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "przekreślenie przekątne od dolnego rogu" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "przekreślenie przekątne od górnego rogu" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "strzałka na północny wschód" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "linia na końcu" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "linia po lewej" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "linia po prawej" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "linia na górze" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "kąt wskazowy" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "arabski symbol silni" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "i" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "początek ułamka" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "początek ułamka bez kreski ułamkowej" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "przez" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "koniec ułamka" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "pierwiastek kwadratowy z" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "pierwiastek sześcienny z" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "pierwiastek z" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "początek pierwiastka" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "koniec pierwiastka" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "indeks dolny" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "indeks górny" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "przed w indeksie dolnym" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "przed w indeksie górnym" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "pod podstawą" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "nad podstawą" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "koniec tabeli" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "koniec osadzonej tabeli" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "niedostępny" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Wyłączone" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Odczytywanie wcięć i wyrównania tekstu jest wyłączone." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Włączenie" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Odczytywanie wcięć i wyrównania tekstu jest włączone." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Tryb nauki. Wyjście: klawisz Escape." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Tryb nauki został włączony. Proszę nacisnąć klawisz, aby poznać jego " -"funkcję. Naciśnięcie klawisza F1 wyświetli dokumentację czytnika ekranowego. " -"Naciśnięcie klawisza F2 wyświetli domyślne skróty czytnika ekranowego. " -"Naciśnięcie klawisza F3 wyświetli skróty klawiszowe dla bieżącego programu. " -"Aby opuścić tryb nauki, należy nacisnąć klawisz Escape." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "wyjście z cytatu blokowego." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "wyjście z informacji." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "wyjście z kanału." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "wyjście z ilustracji." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "wyjście z formularza." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "wyjście z baneru." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "wyjście z treści uzupełniającej." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "wyjście z informacji." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "wyjście z głównej treści." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "wyjście z nawigacji." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "wyjście z regionu." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "wyjście z wyszukiwania." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "wyjście z listy." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "wyjście z panelu." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "wyjście z tabeli." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "wyjście z podpowiedzi." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "wyjście ze streszczenia." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "wyjście z podziękowań." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "wyjście z posłowia." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "wyjście z załącznika." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "wyjście z bibliografii." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "wyjście z rozdziału." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "wyjście z kolofonu." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "wyjście z zakończenia." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "wyjście z autora." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "wyjście z autorów." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "wyjście z dedykacji." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "wyjście z przypisów końcowych." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "wyjście z epigrafu." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "wyjście z epilogu." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "wyjście z erraty." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "wyjście z przykładu." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "wyjście ze wstępu." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "wyjście z glosariusza." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "wyjście z indeksu." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "wyjście z wprowadzenia." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "wyjście z listy stron." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "wyjście z części." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "wyjście z przedmowy." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "wyjście z prologu." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "wyjście z cytatu wrzuconego." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "wyjście z FAQ." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "wyjście z podpowiedzi." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "wyjście ze spisu treści." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "zaznaczono wiersz od pozycji kursora" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "zaznaczono wiersz do pozycji kursora" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "odznaczono wiersz od pozycji kursora" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "odznaczono wiersz do pozycji kursora" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Opuszczanie trybu nauki." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "zaznaczono wiersz do pozycji kursora" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "zaznaczono wiersz od pozycji kursora" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "odnośnik" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ta sama strona" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ta sama witryna" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "inna witryna" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "Odnośnik %(uri)s do %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "odnośnik %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "odwiedzony odnośnik %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Klawisze strzałek w górę i w dół: nawigacja na liście. Klawisz Escape: " -"wyjście." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Wszystkie obszary dynamiczne zostały wyłączone" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "poziomy grzeczności obszarów dynamicznych zostały przywrócone" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "poziom grzeczności %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "ustalenie grzeczności obszaru dynamicznego na poziomie: stanowczy" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "ustalenie grzeczności obszaru dynamicznego na poziomie: wyłączony" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "ustalenie grzeczności obszaru dynamicznego na poziomie: grzeczny" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "ustalenie grzeczności obszaru dynamicznego na poziomie: niegrzeczny" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Monitorowanie obszarów dynamicznych zostało wyłączone" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Monitorowanie obszarów dynamicznych zostało włączone" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nie zapisano żadnych wiadomości dynamicznych" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Obsługa obszarów dynamicznych została wyłączona" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nie odnaleziono" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Nie można odnaleźć bieżącej lokalizacji." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "wyłączony" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "włączony" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "błędnie napisane" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Błędnie napisane słowo: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Kontekst: %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Tryb przeglądania" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Tryb zaznaczania" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Naciśnięcie %s włącza tryb zaznaczania." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Tryb zaznaczania jest lepki." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Tryb przeglądania jest lepki." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Tryb układu." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Tryb obiektów." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Przeniesiono kursor obiektu." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Obiekt uaktywniany po najechaniu myszą nie został odnaleziony." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Wyłączono odczytywanie kursorem myszy." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Włączono odczytywanie kursorem myszy." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Błąd: nie można utworzyć listy obiektów." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Brak elementów potomnych." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Brak następnego elementu." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Brak elementu nadrzędnego." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Brak poprzedniego elementu." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Włączono uproszczoną nawigację." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Wyłączono uproszczoną nawigację." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "%d. poziom zagnieżdżenia" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Nowy element został dodany" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Nie odnaleziono działań na: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Brak zaznaczenia" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Żaden program nie jest zaznaczony." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Brak dalszych cytatów blokowych." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Brak dalszych przycisków." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Brak dalszych pól wyboru." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Brak dalszych dużych obiektów." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Brak dalszych elementów klikalnych." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Brak dalszych list rozwijanych." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Brak dalszych pozycji." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Brak dalszych pól formularza." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Brak dalszych nagłówków." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Brak dalszych nagłówków o %d. poziomie." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Brak dalszych wewnętrznych ramek." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Brak dalszych obrazów." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nie odnaleziono współrzędnych." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Brak dalszych odnośników." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Brak dalszych list." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Brak dalszych elementów listy." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Brak dalszych obszarów dynamicznych." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Brak dalszych akapitów." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Brak dalszych przycisków wyboru." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Brak dalszych separatorów." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Brak dalszych tabel." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Brak dalszych nieodwiedzonych odnośników." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Brak dalszych odwiedzonych odnośników." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Nie zaznaczono tekstu." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nie jest na odnośniku." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Powiadomienie" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Dół" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Góra" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Brak komunikatów powiadamiania" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "cyfry" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Odczytywanie liczb jako cyfry." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "słowa" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Odczytywanie liczb jako słowa." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "wyłączony" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "włączony" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Wczytywanie. Proszę czekać." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Ukończono wczytywanie." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Ukończono wczytywanie %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Elementy strony: %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "zaznaczono stronę od pozycji kursora" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "zaznaczono stroną do pozycji kursora" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "odznaczono stronę od pozycji kursora" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "odznaczono stronę do pozycji kursora" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "zaznaczono akapit od pozycji kursora" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "zaznaczono akapit od pozycji kursora" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "odznaczono akapit od pozycji kursora" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "odznaczono akapit od pozycji kursora" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Jedno okno konfiguracyjne programu Cthulhu zostało już otwarte.\n" -"Proszę zamknąć je przed otwarciem nowego." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "slajd %(position)d z %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil jest ustawiony na %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nie odnaleziono profilów." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Pasek postępu %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Wszystko" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Poziom interpunkcji jest ustawiony na odczytywanie wszystkiego." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Większość" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Poziom interpunkcji jest ustawiony na odczytywanie większości." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nic" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Poziom interpunkcji jest ustawiony na nie odczytywanie niczego." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Niektóre" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Poziom interpunkcji jest ustawiony na odczytywanie niektórych." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Wyszukiwanie." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Wyszukiwanie ukończone." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Ustawienia Cthulhu zostały ponownie wczytane." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Zaznaczony tekst: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Usunięto zaznaczenie." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Przywrócono zaznaczenie." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Odznaczono tekst." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Rozmiar: %d, %d. Położenie: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Szerokość: %d. Wysokość: %d. %d od lewej. %d od góry." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Mowa wyłączona." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Mowa włączona." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "szybciej." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "wolniej." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "wyżej." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "niżej." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "głośniej." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "ciszej." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Prędkość %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Wysokość tonu %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Głośność %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Moduł Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Głos Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Brak dostępnych modułów Speech-dispatcher" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Brak dostępnych głosów Speech-dispatcher" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Ustawienia mowy zapisane" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Nie można zapisać ustawień mowy" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Poziom informacji: mało" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Poziom informacji: dużo" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " wielokropek" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu wita." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu czai się pod falami." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Tryb uśpienia włączony dla %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Tryb uśpienia wyłączony dla %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Mowa jest niedostępna." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Nie odnaleziono" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Nie odnaleziono paska stanu" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "nie odnaleziono tekstu" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Strukturalne klawisze nawigacyjne zostały wyłączone." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Strukturalne klawisze nawigacyjne zostały włączone." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nie odnaleziono" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "%(row)d. wiersz, %(column)d. kolumna." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Koniec tabeli" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Odczytywanie komórki" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Odczytywanie wiersza" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Niestandardowa" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Brak obiektu w tabeli." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Zmieniono kolejność kolumn" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Zmieniono kolejność rzędów" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "%d. kolumna" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolumna %(index)d z %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Dół kolumny." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Góra kolumny." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Zaznaczono kolumnę %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Zaznaczono kolumny od %s do %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Odznaczono kolumny od %s do %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Odznaczono kolumnę %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "%d. wiersz" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "wiersz %(index)d z %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Początek rzędu." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Koniec rzędu." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Usunięto wiersz." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Usunięto ostatni wiersz." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Wstawiono wiersz." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Wstawiono wiersz na końcu tabeli." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Zaznaczono wiersz %s" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Zaznaczono wiersze od %s do %s" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Odznaczono wiersze od %s do %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Odznaczono wiersz %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "zaznaczono" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "odznaczono" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H godzin, %M minut i %S sekund" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H godzin i %M minut" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unikod %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "cofnij" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "ponów" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu wersja %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "białe znaki" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Przechodzenie do końca." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Przechodzenie do początku." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elementów" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Komórka obejmuje %d wiersz" -msgstr[1] "Komórka obejmuje %d wiersze" -msgstr[2] "Komórka obejmuje %d wierszy" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d kolumna" -msgstr[1] " %d kolumny" -msgstr[2] " %d kolumn" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Komórka obejmuje %d kolumnę" -msgstr[1] "Komórka obejmuje %d kolumny" -msgstr[2] "Komórka obejmuje %d kolumn" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "O %d znak za dużo" -msgstr[1] "O %d znaki za dużo" -msgstr[2] "O %d znaków za dużo" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d okno)" -msgstr[1] "(%d okna)" -msgstr[2] "(%d okien)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d niezaznaczone okno" -msgstr[1] "%d niezaznaczone okna" -msgstr[2] "%d niezaznaczonych okien" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bajt" -msgstr[1] "%d bajty" -msgstr[2] "%d bajtów" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Odnaleziono %d plik" -msgstr[1] "Odnaleziono %d pliki" -msgstr[2] "Odnaleziono %d plików" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formularz" -msgstr[1] "%d formularze" -msgstr[2] "%d formularzy" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d nagłówek" -msgstr[1] "%d nagłówki" -msgstr[2] "%d nagłówków" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d element" -msgstr[1] "%d elementy" -msgstr[2] "%d elementów" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d współrzędna" -msgstr[1] "%d współrzędne" -msgstr[2] "%d współrzędnych" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "Odnaleziono %d element" -msgstr[1] "Odnaleziono %d elementy" -msgstr[2] "Odnaleziono %d elementów" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Wyjście z %d cytatu blokowego." -msgstr[1] "Wyjście z %d cytatów blokowych." -msgstr[2] "Wyjście z %d cytatów blokowych." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Wyjście z %d listy." -msgstr[1] "Wyjście z %d list." -msgstr[2] "Wyjście z %d list." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Lista o nieznanej wielkości" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista z %d elementem" -msgstr[1] "Lista z %d elementami" -msgstr[2] "Lista z %d elementami" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Kanał o nieznanej wielkości" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Kanał z %d artykułem" -msgstr[1] "Kanał z %d artykułami" -msgstr[2] "Kanał z %d artykułami" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Lista definicji z %d terminem" -msgstr[1] "Lista definicji z %d terminami" -msgstr[2] "Lista definicji z %d terminami" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d wartość" -msgstr[1] "%d wartości" -msgstr[2] "%d wartości" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabela matematyczna z %d wierszem" -msgstr[1] "tabela matematyczna z %d wierszami" -msgstr[2] "tabela matematyczna z %d wierszami" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d kolumna" -msgstr[1] "%d kolumny" -msgstr[2] "%d kolumn" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "osadzona tabela z %d wierszem" -msgstr[1] "osadzona tabela z %d wierszami" -msgstr[2] "osadzona tabela z %d wierszami" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d komunikat.\n" -msgstr[1] "%d komunikaty.\n" -msgstr[2] "%d komunikatów.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d procent." -msgstr[1] "%d procenty." -msgstr[2] "%d procent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "Przeczytano %d procent treści dokumentu" -msgstr[1] "Przeczytano %d procenty treści dokumentu" -msgstr[2] "Przeczytano %d procent treści dokumentu" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d piksel" -msgstr[1] "%d piksele" -msgstr[2] "%d pikseli" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d znak %(repeatChar)s" -msgstr[1] "%(count)d znaki %(repeatChar)s" -msgstr[2] "%(count)d znaków %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "Wybrano %(index)d z %(total)d elementu" -msgstr[1] "Wybrano %(index)d z %(total)d elementów" -msgstr[2] "Wybrano %(index)d z %(total)d elementów" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Odnaleziono %d domyślny skrót czytnika ekranowego." -msgstr[1] "Odnaleziono %d domyślne skróty czytnika ekranowego." -msgstr[2] "Odnaleziono %d domyślnych skrótów czytnika ekranowego." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Odnaleziono %(count)d skrót czytnika ekranowego dla programu %(application)s." -msgstr[1] "" -"Odnaleziono %(count)d skróty czytnika ekranowego dla programu " -"%(application)s." -msgstr[2] "" -"Odnaleziono %(count)d skrótów czytnika ekranowego dla programu " -"%(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d odstęp" -msgstr[1] "%d odstępy" -msgstr[2] "%d odstępów" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulator" -msgstr[1] "%d tabulatory" -msgstr[2] "%d tabulatorów" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabela" -msgstr[1] "%d tabele" -msgstr[2] "%d tabel" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabela o nieznanej wielkości" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabela z %d kolumną i nieznaną liczbą wierszy" -msgstr[1] "tabela z %d kolumnami i nieznaną liczbą wierszy" -msgstr[2] "tabela z %d kolumnami i nieznaną liczbą wierszy" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabela z %d wierszem i nieznaną liczbą kolumn" -msgstr[1] "tabela z %d wierszami i nieznaną liczbą kolumn" -msgstr[2] "tabela z %d wierszami i nieznaną liczbą kolumn" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabela z %d wierszem" -msgstr[1] "tabela z %d wierszami" -msgstr[2] "tabela z %d wierszami" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d sekunda temu" -msgstr[1] "%d sekundy temu" -msgstr[2] "%d sekund temu" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minuta temu" -msgstr[1] "%d minuty temu" -msgstr[2] "%d minut temu" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d godzina temu" -msgstr[1] "%d godziny temu" -msgstr[2] "%d godzin temu" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d dzień temu" -msgstr[1] "%d dni temu" -msgstr[2] "%d dni temu" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d nieodwiedzony odnośnik" -msgstr[1] "%d nieodwiedzone odnośniki" -msgstr[2] "%d nieodwiedzonych odnośników" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d odwiedzony odnośnik" -msgstr[1] "%d odwiedzone odnośniki" -msgstr[2] "%d odwiedzonych odnośników" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "przełączenie" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "na %(index)d z %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d z %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "%(index)d. element" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "%d. POZIOM" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "%d. poziom drzewa" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "%d. POZIOM DRZEWA" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "informacje dla: %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "ma informacje w: %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "podpowiedź" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "edytowalna lista rozwijana" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "edytowalna treść" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "kanał" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "ilustracja" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "streszczenie" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "podziękowania" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "posłowie" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "załącznik" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "wpis bibliograficzny" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografia" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "rozdział" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "kolofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "zakończenie" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "okładka" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "autor" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "autorzy" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedykacja" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "przypis końcowy" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "przypisy końcowe" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "przykład" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "wstęp" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosariusz" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "indeks" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "wprowadzenie" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "koniec strony" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "lista stron" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "część" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "przedmowa" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "cytat wrzucony" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "FAQ" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "podtytuł" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "spis treści" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s %(level)d. poziomu" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "poziomy pasek przewijania" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "pionowy pasek przewijania" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "poziomy suwak" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "pionowy suwak" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "pozioma linia podziału" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "pionowa linia podziału" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "przełącznik" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Panel ikon" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "baner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "treść uzupełniająca" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informacja" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "główna treść" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "nawigacja" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "region" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "wyszukiwanie" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "odwiedzony odnośnik" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "przycisk menu" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "uporządkowane rosnąco" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "uporządkowane malejąco" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "uporządkowane" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "element klikalny" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "zwinięty" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "rozwinięty" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "ma długi opis" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "poziomy" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "pionowy" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "zaznaczony" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "niezaznaczony" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "włączony" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "wyłączony" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "częściowo zaznaczony" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "wciśnięty" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "niewciśnięty" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "niewybrane" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "wybrany" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "niewybrany" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "niewybrana" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "odwiedzony" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "nieodwiedzony" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "wyszarzony" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "odczyt" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "odcz" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "wymagane" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "wielokrotny wybór" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "błąd pola" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "błąd" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "błąd pisowni" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "pisownia" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "błąd gramatyczny" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatyka" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Znajdź" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Okno wyszukiwania czytnika ekranowego" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "Za_mknij" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Znajdź" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "Wy_szukiwanie:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Wyszukiwanie:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Góra _okna" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Góra okna" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Rozpocznij od:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Przechodzenie" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Szukaj _wstecz" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Kierunek wyszukiwania:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Rozróżnianie wielkości liter" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Dopasowani_e tylko całych słów" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opcje:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Domyślny" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Wielkie litery" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Odnośnik" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Systemowy" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Program" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Okno" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferencje Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "Pomo_c" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Zastosuj" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Układ klawiatury" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Aktywny profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profil początkowy:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Wczytaj" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Z_apisz jako" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Usuń" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profile" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Wyświetlanie podpowiedzi" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Odczytywa_nie obiektu pod kursorem myszy" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Mysz" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Format _czasu:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "_Format daty:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Czas i data" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Odczytywanie _aktualizacji" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Aktualizacje w _brajlu" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Częstotliwość (w sekundach):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Zastosowanie do:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Dźwięk aktualizacji" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Zmiany na pasku postępu" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "P_rzewijanie w odczytywaniu wszystkiego" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Nawigacja _strukturalna w odczytywaniu wszystkiego" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "_Odczytywanie wszystkiego po:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Informowanie o _cytatach blokowych w odczytywaniu wszystkiego" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Informowanie o _listach w odczytywaniu wszystkiego" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Informowanie o _tabelach w odczytywaniu wszystkiego" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "_Informowanie o panelach w odczytywaniu wszystkiego" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Informowanie o _formularzach w odczytywaniu wszystkiego" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Informowanie o _współrzędnych w odczytywaniu wszystkiego" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Odczytywanie wszystkiego" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Prezentacja elementu:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Ogólne" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Głoś_ność:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Wys_okość:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "Te_mpo:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "Oso_ba:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Język:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Syntezato_r mowy:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_System mowy:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Rodzaj głosu:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Styl _kapitalizacji:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Ustawienia rodzaju głosu" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Odczytywanie ciągów z kapitalikami jako _słowa" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Odczytywanie _liczb jako cyfry" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Ustawienia głosu globalnego" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Głos" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Mo_wa" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Pełna" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Szczegółowość" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "Wszys_tkie" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Interpunkcja" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Odczytywanie tylko wyświetlanego tekstu" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Odczytywanie pustych wierszy" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Odczytywanie w_cięć i wyrównania tekstu" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Odczytywanie _obiektu pod kursorem myszy" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Odczytywanie pozycji _potomnej" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Odczytywanie komunikatów samouczka" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Szczegółowe komunikaty systemowe" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Od_czytywanie kolorów jako nazwy" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Informowanie o _cytatach blokowych podczas nawigacji" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Informowanie o _listach podczas nawigacji" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Informowanie o _tabelach podczas nawigacji" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Odczytywanie wskaźnika _błędu pisowni" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "_Informowanie o panelach podczas nawigacji" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Informowanie o _współrzędnych podczas nawigacji" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Informowanie o _formularzach podczas nawigacji" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Odczytywanie _opisów" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Odczytywanie całych rzędów w _arkuszach kalkulacyjnych" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Odczytywanie całych rzędów w tablach _dokumentów" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Odczytywanie całych rzędów w tabelach _interfejsu użytkownika" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Kontekst mowy" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Mowa" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Ob_sługa alfabetu Braille’a" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Skrócone n_azwy funkcji" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Wyłączenie symboli końca wi_ersza" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tabela skrótów:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "S_króty brajlowskie" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Zawijanie _słów" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Ustawienia wyświetlania" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "Br_ak" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Wskaźnik zaznaczenia" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Wskaźnik odnośnika" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "_Błyskawiczne wiadomości" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Czas trwania (w sekundach):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "_Trwałe wiadomości" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "_Szczegółowe wiadomości" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Ustawienia wiadomości błyskawicznych" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Alfabet Braille’a" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Powtarzanie _klawiszy" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Klawisze _alfanumeryczne" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Klawisze n_umeryczne" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Klawisze _interpunkcji" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "_Spacja" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Klawisze _dodatkowe" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Klawisze _funkcyjne" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Klawisze ak_cyjne" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Klawisze _nawigacyjne" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Powtarzanie _słów" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Powtarzanie _zdań" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Powtarzanie" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Klawisze dodatkowe _czytnika ekranowego:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Przypisania klawiszy" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Słownik wymowy" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nowa pozycja" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Usuń" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Wymowa" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Odczytywanie wszy_stkiego" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Bez odczytywa_nia czegokolwiek" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "P_rzywróć domyślne" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atrybuty tekstowe" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Przenieś na ko_niec" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Przenieś w _dół" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Przenieś w gó_rę" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "_Przenieś na początek" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Zmień wybrany atrybut" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Wskaźnik brajlowski" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atrybuty tekstowe" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Włącz asystenta AI" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Dostawca:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokalny - Bezpłatny)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Plik klucza _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Ścieżka do pliku klucza API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Pobierz klucz API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Otwórz przeglądarkę, aby uzyskać klucz API Claude i zapisać automatycznie" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Wymagaj potwierdzenia przed działaniami AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Model Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nazwa modelu dla Ollama (np. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Punkt końcowy Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL punktu końcowego API Ollama (np. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Jakość zrzutu ekranu:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Niska" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Średnia" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Wysoka" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Asystent AI" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Kod _języka:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Współczynnik _skalowania:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Obraz w skali _szarości" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Odwróć obraz" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "O_braz czarno-biały" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Próg czerni/bieli:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analizuj kolory" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Kopiuj wyniki do _schowka" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alfa, b : brawo, c : czarli, d : delta, e : eko, f : fokstrot, g : golf, " -"h : hotel, i : india, j : dżuliet, k : kilo, l : lima, m : majk, n : " -"nowember, o : oskar, p : papa, q : kebek, r : romijo, s : siera, t : tango, " -"u : juniform, v : wiktor, w : łyski, x : eks-rej, y : janki, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "kolor tła" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "pełna wysokość tła" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "kropkowanie tła" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "kierunek" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "edytowalny" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nazwa rodziny" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "kolor pierwszego planu" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "kropkowanie pierwszego planu" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efekt czcionki" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "wcięcie" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "błąd" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "niewidoczny" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "wyrównanie" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "język" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "lewy margines" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "wysokość wiersza" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "styl akapitu" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pikseli ponad wierszami" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pikseli pod wierszem" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pikseli wewnątrz zawiniętego wiersza" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "prawy margines" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "podniesienie" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "skala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "rozmiar" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "rozciągnięcie" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "przekreślony" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "styl" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "dekoracja tekstu" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "obrót tekstu" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "cień tekstu" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "podkreślenie" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "wariant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "wyrównanie pionowe" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "grubość" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "tryb zawijania" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "tryb pisania" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "prawda" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "fałsz" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "brak" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "grawerowany" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "wytłaczany" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "kontur" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "podkreślenie górne" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "przekreślony" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "mruganie" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "czarny" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "pojedyncze" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "podwójne" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "niskie" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "znak" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "słowo" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "słowo lub znak" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ldp" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "pdl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "lewo" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "prawo" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "środek" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "bez justowania" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "wypełnienie" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra ścieśniony" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "ekstra ścieśniony" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "ścieśniony" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "na wpół ścieśniony" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normalny" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "na wpół rozciągnięty" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "rozciągnięty" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "ekstra rozciągnięty" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra rozciągnięty" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "małe litery" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblique" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "pochylony" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Domyślny" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Treść tekstu" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Nagłówek" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "linia bazowa" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "indeks dolny" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "indeks górny" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "góra" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "góra tekstu" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "środek" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "dół" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "dół tekstu" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "dziedziczenie" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "pełna" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "pisownia" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Przełączania dokonuje się za pomocą klawisza spacji." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Proszę wcisnąć klawisz spacji, aby rozwinąć menu i klawiszy strzałek w górę " -"lub w dół, aby wybrać element z menu." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Proszę wcisnąć klawisz Alt+F6, aby zaznaczyć okna potomne." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Aby przejść do elementów, należy skorzystać z klawiszy strzałek, albo " -"wprowadzić szukane wyrażenie." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Aby dostać się do menu systemowych, proszę nacisnąć klawisze Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Klawisze strzałek w górę i w dół służą do wyboru elementu." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Aby zwinąć, należy wcisnąć klawisz Shift i strzałki w lewo." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Aby rozwinąć, należy wcisnąć klawisz Shift i strzałki w prawo." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Aby uaktywnić, należy nacisnąć klawisz Return." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Proszę wprowadzić tekst." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Klawisze strzałek w lewo i w prawo służą do zmiany kart." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Aby uaktywnić, należy wcisnąć klawisz spacji." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Aby wybrać wartość, proszę skorzystać z klawiszy strzałek w górę i w dół. " -"Można także wprowadzić wartość liczbową." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Zmian dokonuje się klawiszami strzałek." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Aby przemieszczać się, proszę używać klawiszy strzałek w lewo lub prawo. " -"Elementy menu zmienia się za pomocą klawiszy strzałek w górę lub w dół." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" -"Aby wejść do menu podrzędnego, proszę wcisnąć klawisz strzałki w prawo." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Aby zmniejszyć, proszę wcisnąć klawisz strzałki w lewo, aby zwiększyć, " -"klawisz strzałki w prawo. Do zminimalizowania służy klawisz Home, a do " -"maksymalizowania klawisz End." diff --git a/po/pt.po b/po/pt.po deleted file mode 100644 index 27c23ad..0000000 --- a/po/pt.po +++ /dev/null @@ -1,9251 +0,0 @@ -# cthulhu's Portuguese translation. -# Copyright © 2004-2021 cthulhu -# This file is distributed under the same license as the cthulhu package. -# Rui Batista , 2009, 2010, 2011, 2012. -# Duarte Loreto , 2004, 2006, 2007, 2008, 2013, 2015. -# Bruno Ramalhete , 2015. -# Pedro Albuquerque , 2015. -# Sérgio Cardeira , 2016. -# Tiago Carrrondo , 2016. -# Tiago Santos , 2014 - 2016. -# Hugo Carvalho , 2020, 2021, 2022, 2023, 2024. -# -msgid "" -msgstr "" -"Project-Id-Version: 3.10\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2024-04-27 23:37+0100\n" -"Last-Translator: Hugo Carvalho \n" -"Language-Team: Português \n" -"Language: pt\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.4.2\n" -"X-Language: pt_PT\n" -"X-Source-Language: C\n" -"X-Project-Style: gnome\n" - -msgid "Cthulhu Screen Reader" -msgstr "Leitor de ecrã Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "leitor;ecrã;acessibilidade;voz;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "ale" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "seta" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "tela" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "leg" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "cs" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "selcor" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "cabcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cxsu" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "data" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ic" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "mol" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "marc" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dia" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "pandir" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "des" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fich" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "ench" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fon" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "transp" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "cabe" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "ima" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "moldi" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etiq" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "paincam" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "link" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lis" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "itlis" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "menu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "barmen" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "itmen" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "painop" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pag" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "listsep" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pai" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "sen" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mencon" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "bprog" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "bot" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "botexc" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "iexc" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "praiz" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "cli" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "barrol" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "prol" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sec" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "sep" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "bdes" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "pdiv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "bgir" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "best" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tab" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cel" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "imdes" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "con" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tex" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "balt" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "bferr" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "dica" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arv" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tarv" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "desc" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vis" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "jan" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "tit" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "rod" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apli" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "bed" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "cemb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Checo de Grau 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Espanhol de Grau 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francês do Canadá de Grau 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francês de França de Grau 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letão de Grau 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Neerlandês dos Países Baixos de Grau 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norueguês de Grau 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norueguês de Grau 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norueguês de Grau 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norueguês de Grau 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polaco de Grau 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Português de Grau 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Sueco de Grau 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Árabe de Grau 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galês de Grau 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galês de Grau 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemão de Grau 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemão de Grau 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemão de Grau 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Inglês do Reino Unido de Grau 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Inglês do Reino Unido de Grau 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Inglês dos E.U.A de Grau 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Inglês dos E.U.A de Grau 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francês do Canadá de Grau 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francês de França de Grau 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grego de Grau 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Indiano de Grau 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Húngaro ponto 8 informático" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Húngaro de Grau 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Húngaro de Grau 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiano de Grau 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Neerlandês Belga de Grau 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espaço" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "novalinha" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "exclamação" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "aspas" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "cardinal" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "cifrão" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percentagem" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "i comercial" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apóstrofo" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "parênteses esquerdo" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "parênteses direito" - -# ../lisp/menus.jl -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterísco" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "mais" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "vírgula" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "hífen" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "ponto" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dois pontos" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "ponto e vírgula" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "menor" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "igual" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "maior" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "interrogação" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "arroba" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "parênteses reto esquerdo" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "barra invertida" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "parênteses reto direito" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "circunflexo" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "sublinhado" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "chaveta esquerda" - -# -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra vertical" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "chaveta direita" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "til" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espaço sem quebra" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "ponto de exclamação invertido" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cêntimos" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "libra" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "sinal de moeda" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "iene" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra vertical quebrada" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "secção" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "diacrítico" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a elevado" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "menor duplo" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "negação lógica" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "hifen pequeno" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "marca registada" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "graus" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "mais ou menos" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "elevado a 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "elevado a 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "agudo" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "miu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "marca de parágrafo" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "ponto centrado" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilha" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "elevado a 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "o elevado" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "maior duplo" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "um quarto" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "um meio" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "três quartos" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "ponto de interrogação invertido" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a agudo" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AGUDO" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TIL" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A TREMA" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A ANEL" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILHA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AGUDO" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E TREMA" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AGUDO" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CINCUNFLEXO" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I TREMA" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TIL" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AGUDO" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TIL" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O TREMA" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "vezes" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O COM BARRA" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AGUDO" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U TREMA" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AGUDO" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "eszett" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circunflexo" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a til" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a trema" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a anel" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilha" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e agudo" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circunflexo" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e trema" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i agudo" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circunflexo" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i trema" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n til" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o agudo" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circunflexo" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o til" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o trema" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "dividido por" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o com traço" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u agudo" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circunflexo" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u trema" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y agudo" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y trema" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y TREMA" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "travessão grande" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "plica esquerda" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "plica direita" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "plica esquerda em baixo" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "aspas esquerdas" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "aspas direitas" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "aspas em baixo" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "punhal" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "punhal duplo" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "ponto de item redondo" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "ponto de item triangular" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "permilagem" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "plica" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "plica dupla" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "til triplo" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "ponto de item em hífen" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marca registada" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "sinal de visto" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "sinal de visto negrito" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "ponto de item em x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "elevado a 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "elevado a 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "elevado a 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "elevado a 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "elevado a 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "elevado a 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "elevado a 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "elevado mais" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "elevado menos" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "elevado igual" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "parênteses esquerdo elevado" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "parênteses direito elevado" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "elevado a n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "subscrito 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "subscrito 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "subscrito 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "subscrito 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "subscrito 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "subscrito 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "subscrito 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "subscrito 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "subscrito 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "subscrito 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "subscrito mais" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "subscrito menos" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "subscrito igual" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "subscrito parênteses esquerdo" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "subscrito parênteses direito" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "quadrado preto" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "losango preto" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "carácter de substituição" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Encaminha o ponteiro para o item atual" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Realiza um clique esquerdo no item atual da revisão plana" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Realiza um clique direito no item atual da revisão plana" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Lê todo o documento" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Lê toda a janela utilizando a revisão plana" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Realiza a operação básica \"Onde estou\"" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Realiza a operação detalhada \"Onde estou\"" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Lê a seleção atual" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Lê os detalhes da hiperligação" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Apresentar o botão predefinido" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Apresenta a barra de estado" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Apresenta a barra de título" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Abre a janela de «Localizar»" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Mostrar lista de ações" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Procura pela instância seguinte de uma expressão" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Procura pela instância anterior de uma expressão" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Entra e sai do modo de revisão plana" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Alterne a restrição da revisão plana ao objeto atual" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Move a revisão plana para a posição de início" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Move a revisão plana para a posição final" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Move a revisão plana para o início da linha anterior" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Lê a linha da revisão plana atual" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Soletra a linha de revisão plana atual" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Soletra foneticamente a linha de revisão plana atual" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Move a revisão plana para o início da linha seguinte" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Move a revisão plana para o item ou palavra anterior" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Lê a palavra ou item atualmente em revisão plana" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Soletra a palavra ou item atualmente em revisão plana" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Soletra foneticamente a palavra ou item atualmente em revisão plana" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Move a revisão plana para o item ou palavra seguinte" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Move a revisão plana para a palavra acima da palavra atual" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Lê o objeto da revisão plana atual" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Move a revisão plana para a palavra abaixo da palavra atual" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Move a revisão plana para o carácter anterior" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Lê o carácter atual na revisão plana" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Soletra foneticamente o carácter atual na revisão plana" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Lê o valor unicode do carácter atual em revisão plana" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Move a revisão plana para o carácter seguinte" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Move a revisão plana para o final da linha" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Move a revisão plana para o canto inferior esquerdo" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copia o conteúdo em revisão plana para a área de transferência" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Anexa o conteúdo em revisão plana à área de transferência" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Mostrar conteúdo de revisão plana" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Alterna entre ler apenas a célula atual na tabela ou toda a linha" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Lê os atributos associados ao carácter de texto atual" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Move a linha braille à esquerda" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Move a linha braille à direita" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Volta ao objeto com o foco de teclado" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Liga e desliga o braille contraído" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Processa uma tecla de encaminhamento do cursor" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marca o início de uma seleção de texto" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marca o fim de uma seleção de texto" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Entra em modo de aprendizagem. Prima \"Esc\" para sair do modo de " -"aprendizagem" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Reduz a velocidade da voz" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Aumenta a velocidade da voz" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Diminui o tom da voz" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Aumenta o tom da voz" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Aumenta o volume da voz" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Reduz o volume da voz" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Selecionar a definição de voz anterior" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Selecionar a definição de voz seguinte" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Diminuir a definição de voz atual" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Aumentar a definição de voz atual" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Guardar definições de voz" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Alterna o silenciar da voz" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Alterna a verbosidade da voz" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Alternar modo de suspensão" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Termina o leitor de ecrã" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Mostra a janela de configuração de preferências" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Mostra o diálogo de configuração de preferências da aplicação" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Alterna a leitura da indentação e justificação" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Altera o estilo do número dito" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Circula para a próxima leitura de nível de pontuação" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Alterna para sintetizador de voz seguinte" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Circula para o próximo perfil de definições" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Circula para o próximo estilo de maiúsculas" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Circula para o próximo nível de eco de tecla" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Circula o nível de depuração durante a execução" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Marcar onde me encontro em relação à posição atual" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Ir para a localização marcada anterior" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Ir para o marcador" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Ir para a próxima localização marcada" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Adicionar um marcador" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Gravar marcadores" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Alternar a revisão com o rato" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Apresenta a hora atual" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Apresenta a data atual" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Tamanho atual e localização do objeto atual" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Passa o comando seguinte para a aplicação atual" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Ler e mostrar em braille uma mensagem anterior na sala de diálogo" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Alternar se é ou não anunciado quando os contactos estão a digitar" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Alternar se nós fornecemos ou não histórias das mensagens específicas da " -"sala de conversação" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Alternar se nós prefixamos ou não as mensagens da sala de conversação com o " -"nome da sala de conversação" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linha à Esquerda" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linha à Direita" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linha Acima" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linha Abaixo" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Congelar" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Topo à Esquerda" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Fundo à Esquerda" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posição do Cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Seis Pontos" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Encaminhamento do Cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Início do Corte" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Cortar Linh" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Apresenta a última mensagem de notificação" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Apresenta a lista de mensagens de notificação" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Apresenta a mensagem de notificação anterior" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Apresenta mensagem de notificação seguinte" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Ir para o caráter seguinte" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Ir para o caráter anterior" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Ir para a palavra seguinte" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Ir para a palavra anterior" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Ir para a linha seguinte" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Ir para a linha anterior" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Ir para o topo do ficheiro" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Ir para o final do ficheiro" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Ir para o início da linha" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Ir para o fim da linha" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Ir para o objeto seguinte" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Ir para o objeto anterior" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Expande a caixa combinada atual" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Alterna entre os modos de navegação nativo e de cursor do leitor de ecrã" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Definição avançada de notificação de regiões interativas" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Desativa o filtro de notificação das regiões interativas" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Rever o anúncio da região interativa" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitorizar as regiões interativas" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Move o foco para dentro e para fora de onde o rato está a pairar" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Definir a linha a utilizar como cabeçalhos dinâmicos de coluna" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Limpa os cabeçalhos de colunas dinâmicas" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Definir a coluna a utilizar como cabeçalhos dinâmicos de linha" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Limpar os cabeçalhos de linhas dinâmicas" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Apresenta o conteúdo da linha de entrada" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Alterna as teclas de navegação estruturada" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Ir para a citação anterior" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Ir para a citação seguinte" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Mostra uma lista de citações" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Ir para o botão anterior" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Ir para o botão seguinte" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Mostra uma lista de botões" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Ir para a caixa de seleção anterior" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Ir para a caixa de seleção seguinte" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Mostra uma lista de caixas de seleção" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Ir para a tabela anterior" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Ir para a tabela seguinte" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Mostra uma lista de tabelas" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Ir para a caixa de seleção única anterior" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Ir para a caixa combinada seguinte" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Ir para o início do ''container''" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Ir para o fim do ''container''" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Mostra uma lista de caixas combinadas" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Ir para o campo anterior" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Ir para a entrada seguinte" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Exibir uma lista de entradas" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Ir para o campo anterior do formulário" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Ir para o campo seguinte do formulário" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Mostra uma lista de campos de formulário" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Ir para o título anterior" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Ir para o título seguinte" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Mostra uma lista de cabeçalhos" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Ir para o título anterior no nível %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Ir para o título seguinte no nível %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Mostra uma lista de títulos no nível %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Ir para o quadro interno anterior" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Ir para o quadro interno seguinte" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Mostra uma lista de quadros internos" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Ir para a imagem anterior" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Ir para a imagem seguinte" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Mostra uma lista de imagens" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Ir para o marcador de zona anterior" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Ir para o marcador de zona seguinte" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Mostra uma lista de marcadores" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Ir para o objeto grande anterior" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Ir para o objeto grande seguinte" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Mostra uma lista de objetos grandes" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Ir para a ligação anterior" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Ir para a ligação seguinte" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Mostra uma lista de ligações" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Ir para a lista anterior" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Ir para a lista seguinte" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Mostra uma lista de listas" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Ir para o item de lista anterior" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Ir para o item de lista seguinte" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Mostra uma lista de itens de lista" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Ir para a região interativa anterior" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Ir para a região interativa seguinte" - -# -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Ir para a última região interativa que fez um anúncio" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Ir para o parente do objeto com foco no navegador." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Ir para o primeiro parente do objeto com foco no navegador." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Ir para o próximo irmão do objeto com foco no navegador." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Ir para o irmão anterior do objeto com foco no navegador." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Clica no objeto com foco do navegador." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Alterna navegação simplificada de objetos." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Ir para o parágrafo anterior" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Ir para o parágrafo seguinte" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Mostra uma lista de parágrafos" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Ir para o botão rádio anterior" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Ir para o botão rádio seguinte" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Mostra uma lista de botões rádio" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Ir para o separador anterior" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Ir para o separador seguinte" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Ir para a tabela anterior" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Ir para a tabela seguinte" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Mostra uma lista de tabelas" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Ir uma célula para baixo" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Ir para a primeira célula numa tabela" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Ir para a última célula numa tabela" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Vai uma célula para a esquerda" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Vai uma célula para a direita" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Vai uma célula para cima" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Alternar a revisão com o rato" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Alterna entre modo de navegação e modo de foco" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Ativa modo de foco pegajoso" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Ativa modo de procura adesiva" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Ir para a ligação por visitar anterior" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Ir para a ligação por visitar seguinte" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Mostra uma lista de ligações por visitar" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Ir para a ligação visitada anterior" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Ir para a ligação visitada seguinte" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Mostra uma lista de ligações visitadas" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "azul alice" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "branco velho" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "azul marinho claro" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azure" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "bege" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "preto" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "bege claro" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "azul" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "azul violeta" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "castanho" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "madeira clara" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "azul cadete" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "verde chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chocolate" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "coral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "azul milho" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "branco sujo" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "vermelho escuro" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "ciano" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "azul escuro" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "ciano escuro" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "dourado escuro" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "cinzento escuro" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verde escuro" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "khadi escuro" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta escuro" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "verde azeitona escuro" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "laranja escuro" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "orquídea escuro" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "vermelho escuro" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmão escuro" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "verde mar escuro" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "azul dark slate" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "cinzento dark slate" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turquesa escuro" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violeta escuro" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "rosa profundo" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "azul celeste profundo" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "cinzento esbatido" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "azul dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "cor de tijolo" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "branco floral" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "verde floresta" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "rosa fúcsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "cinzento claro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "branco fantasma" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "dourado" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "dourado velho" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "cinzento" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verde" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "verde amarelado" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "cor de mel" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "rosa quente" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "vermelho índio" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "marfim" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "caqui" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavanda corada" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "relva" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "chiffon limão" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "azul claro" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "coral claro" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "ciano claro" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "amarelo dourado claro" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "chaveta cinzento claro" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "verde claro" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "rosa claro" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmão claro" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "verde mar claro" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "azul celeste claro" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "cinzento slate claro" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "azul aço claro" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "amarelo claro" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lima" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "verde lima" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linho" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "vermelho acastanhado" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "azul marinho médio" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "azul médio" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orquídea médio" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "púrpura médio" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "verde mar médio" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "azul slate médio" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "verde primavera médio" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turquesa médio" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "vermelho violeta médio" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "azul meia noite" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "hortelã" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rosa névoa" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mocassim" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "branco navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "marinha" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "branco renda" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliveira" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "oliveira escuro" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "laranja" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "vermelho alaranjado" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orquídea" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "dourado pálido" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "verde pálido" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turquesa pálido" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "vermelho violeta pálido" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaia" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "pêssego" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "ameixa" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "azul pólvora" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "púrpura" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "vermelho" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "castanho rosado" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "azul real" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "castanho sela" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmão" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "castanho areia" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "verde mar" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "concha marinha" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "castanho siena" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "prateado" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "azul celeste" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "azul slate" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "cinzento slate" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "neve" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "verde primavera" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "azul aço" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "bronzeado" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "azul petróleo" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "cinzento thistle" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomate" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquesa" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violeta" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "erva" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "branco" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "branco fumo" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "amarelo" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "amarelo esverdeado" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Ativar" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Modo de foco automático durante a navegação estruturada" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Modo de foco automático durante a navegação com cursor" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Modo de foco automático durante a navegação nativa" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Ponto _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Ponto _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Pontos 7 _e 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Cancelar" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Ir para" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Aceitar" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ícone" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Nenhum" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Soletrar" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Anunciar quando os seus _contactos estão a escrever" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Fornecer um histórico de _mensagens específico das salas de diálogo" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Ler mensagens de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Todos os ca_nais" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Todos os canais quando uma _qualquer janela de %s estiver ativa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Só um canal se a sua _janela estiver ativa" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Ler o nome da sala de diálogo" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Ativar modo de disposição para conteúdo" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "clique duplo" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "clique triplo" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizador predefinido" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Expressão atual" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Expressão de substituição" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Ativar o eco por ca_rácter" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Ativar as teclas _diacríticas que não representam espaços" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Localização at_ual" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Comprimento mínimo do texto encontrado:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opções de procura" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Ler só l_inhas alteradas durante a procura" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Ler os resultados durante a _procura" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Comando" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Associação de Teclas" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Predefinição" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Modo de aprendizagem" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Ações" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Atalhos Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Marcadores" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Data e Hora" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Revisão com o rato" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Navegação de objetos" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Detalhes do objeto" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Remover associação" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Revisão plana" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Voz e verbosidade" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Conteúdo da revisão plana" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificado" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "Computa_dor de secretária" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificações" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Recebido" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Apresentador de notificações" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferências do Cthulhu para %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marcar em braille" - -# 48x48/emblems/emblem-presentation.icon.in.h:1 -# 48x48/emblems/emblem-presentation.icon.in.h:1 -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Apresentar exceto se" - -# 48x48/emblems/emblem-special.icon.in.h:1 -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Ler" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Gravar perfil como conflito" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflito no perfil do utilizador!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"O perfil %s já existe.\n" -"Continuar a atualizar o perfil com estas novas mudanças?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Carregar perfil do utilizador" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Você está prestes a alterar o perfil ativo. Se tiver\n" -"feito alterações nas suas preferências, estas serão\n" -"descartadas quando o perfil for carregado.\n" -"\n" -"Continuar a carregar o perfil descartando as alterações anteriores?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Gravar perfil como" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nome do _perfil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Remover perfil do utilizador" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Está prestes a remover as %s do perfil. Todas as definições não guardadas e " -"definições guardadas neste perfil serão perdidas. Pretende continuar e " -"remover este perfil e todas as definições relacionadas?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Tudo" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicação" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Janela" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Nenhuma" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Alguns" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Maioria" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Linha" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Frase" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Citação" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Botão" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Legenda" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Caixa de verificação" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Clicável" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Caixa de combinação" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descrição" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Título" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Quadro interno" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imagem" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiqueta" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Marco" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Grau" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Ligação" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Item de lista" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objeto" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Parágrafo" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Botão rádio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Papel" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Item selecionado" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Estado" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Texto" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valor" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Citações" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botões" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Caixas de verificação" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Clicáveis" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Caixas de combinação" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entradas" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Campos de formulário" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Títulos" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Quadros internos" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imagens" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Títulos no nível %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Marcos" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Objetos grandes" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Ligações" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listas" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Itens de lista" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Parágrafos" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Botões rádio" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabelas" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Ligações por visitar" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Ligações visitadas" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navegação de página" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"_Iniciar automaticamente a leitura de uma página ao carregá-la pela primeira " -"vez" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"_Iniciar automaticamente a leitura de uma página ao carregá-la pela primeira " -"vez" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Partir o _discurso em pedaços entre pausas" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "voz predefinida do %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Predefinição" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiperligação" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Maiúsculas" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Despachante de voz" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Ortografia" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "_Erro ortográfico" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Sugestão ortográfica" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "_Contexto atual de erro" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Ler as coordenadas da célula da folha de cálculo" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Ler sempre o intervalo selecionado da folha de cálculo" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Ler o cabeçal_ho da célula" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navegação de Tabela" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Ignorar as células _vazias" - -# 48x48/emblems/emblem-special.icon.in.h:1 -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Ler a _célula" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Ler as coordenadas da _célula" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Ler grupos de _múltiplas células" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nome do Atributo" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Navegação por cursor de controlo" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Ativar a navegação e_struturada" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Tema de som:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Tema de som" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Breve" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d notificação" -msgstr[1] "%d notificações" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "shift esquerdo" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt esquerdo" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control esquerdo" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "shift direito" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt direito" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control direito" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta esquerdo" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta direito" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab esquerdo" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "recuo" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "enter" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "seta para cima" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "seta para baixo" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "seta para a esquerda" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "seta para a direita" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super esquerdo" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super direito" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gráficos" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ajuda" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "alternador de modo" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "esc" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "dilite" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "iniciar" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circunflexo" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "anel" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "barra" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "menos" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "negrito %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "itálico %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "negrito itálico %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "subscrito %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "negrito subscrito %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fratura %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "enfatizado %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "fratura %s negrito" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif negrito %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif itálico %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif bold negrito itálico %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "monoespaçada %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "sem pontos %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "seta esquerda" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "seta acima" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "seta direita" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "seta abaixo" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "seta direita e esquerda" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "seta acima e abaixo" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "seta noroeste" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "seta nordeste" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "seta sudoeste" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "seta esquerda de barra" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "seta acima de barra" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "seta direita de barra" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "seta abaixo de barra" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "seta esquerda dupla" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "seta dupla acima" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "seta direita dupla" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "seta dupla abaixo" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "aspas direitasseta direita e esquerda dupla" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "seta acima e abaixo dupla" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "seta noroeste dupla" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "seta nordeste dupla" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "seta sudeste dupla" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "seta sudoeste dupla" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "seta apontando à direita" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "cabeça de seta à direita" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "menor que" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "maior que" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circunflexo" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "ponto" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "linha vertical dupla" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "reticências horizontais" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "para tudo" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complemento" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "diferencial parcial" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "existe" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "não existe" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "conjunto vazio" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "incremento" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "pertence" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "não pertence" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "pertence pequeno" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "contém" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "não contém" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "contém pequeno" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "fim de prova" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produto" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproduto" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "soma" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "mais ou menos" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "mais grande" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "divisão" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "barra esquerda" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operador asterisco" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operador anel" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operador marca" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "raíz quadrada" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "raíz cúbica" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "raíz quarta" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcional a" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinito" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "ângulo reto" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "ângulo" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "ângulo medido" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "ângulo esférico" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "divide" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "não divide" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paralelo a" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "não paralelo a" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "e lógico" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "ou lógico" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersecção" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "união" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integral duplo" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integral triplo" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integral do contorno" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integral de superfície" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integral de volume" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral direito" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integral de contorno direito" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integral de contorno esquerdo" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "portanto" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "porque" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "rácio" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporção" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "ponto menos" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "excesso" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporção geométrica" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotética" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "til" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "til inverso" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "s deitado" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "onda seno" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "produto anel" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "não til" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "menos til" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "igual a" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "não igual a" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "aproximadamente igual a" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "aproximadamente mas não igual a" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "nem aproximadamente nem igual a" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "quase igual a" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "não quase igual a" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "quase igual ou igual a" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "til triplo" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "tudo igual a" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "equivalente a" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometricamente equivalente a" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "diferença entre" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "próximo do limite" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometricamente igual a" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "aproximadamente igual ou a imagem de" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "imagem de, ou aproximadamente igual a" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dois pontos igual" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "igual dois pontos" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "anel dentro de igual" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "anel sobre igual" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "corresponde a" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estima" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "ângulo sobre igual" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "estrela sobre igual" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta sobre igual" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "igual a por definição" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "m sobre igual" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "interrogação sobre igual" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "diferente de" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "idêntico a" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "não idêntico a" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "estritamente equivalente a" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "menor ou igual a" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "maior ou igual a" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "menor sobre igual" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "maior sobre igual" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "menor mas não igual a" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "maior mas não igual a" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "muito menor que" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "muito maior que" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "entre" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "não equivalente a" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "não menor que" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "não maior que" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "nem menor nem igual a" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "nem maior nem igual a" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "menor ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "maior ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "nem menor nem equivalente a" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "nem maior nem equivalente a" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "menor ou maior que" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "maior ou menor que" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "nem menor nem maior que" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "nem maior nem menor que" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "precede" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "sucede" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "precede ou igual a" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "sucede ou igual a" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "precede ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "sucede ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "não precede" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "não sucede" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subconjunto de" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superconjunto de" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "não subconjunto de" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "não superconjunto de" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subconjunto de ou igual a" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superconjunto de ou igual a" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "nem subconjunto de nem igual a" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "superconjunto de nem igual a" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subconjunto de com não igual a" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superconjunto de com não igual a" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiconjuntos" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiplicação de multiconjuntos" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "união de multiconjuntos" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "imagem quadrada de" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "quadrado original de" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "imagem quadrada de ou igual a" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "quadrado original de ou igual a" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "topo quadrado" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "taça quadrada" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "mais em círculo" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "menos em círculo" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "vezes em círculo" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "divisão em círculo" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "ponto em círculo" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "anel em círculo" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "asterisco em círculo" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "igual em círculo" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "traço em círculo" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "mais em quadrado" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "menos em quadrado" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "vezes em quadrado" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "ponto em quadrado" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "entroncamento direito" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "entroncamento esquerdo" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "entroncamento abaixo" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "entroncamento acima" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "asserção" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modelos" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "verdadeiro" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "força" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "barra vertical tripla com entroncamento direito" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "barra vertical dupla com entroncamento direito" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "não prova" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "não verdadeiro" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "não força" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "barra vertical tripla dupla entroncamento duplo direito negada" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "precede sob relação" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "sucede sob relação" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "subgrupo normal de" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "contém como subgrupo normal" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "subgrupo normal de ou igual a" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "contém subgrupo normal de ou igual a" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original de" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "imagem de" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matriz conjugada" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalar" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "ou exclusivo" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "não e" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "não ou" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ângulo direito com arco" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triângulo direito" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operador diamante" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operador ponto" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operador estrela" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "divisão vezes" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "laço borboleta" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "produto semidireto do fator normal esquerdo" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "produto semidireto do fator normal direito" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "produto semidireto esquerdo" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "produto semidireto direito" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "til inverso igual" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "ou lógico curvo" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "e lógico curvo" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "duplo subconjunto" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "duplo superconjunto" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "intersecção dupla" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "união dupla" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "forquilha" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "igual e paralelo a" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "menor que com ponto" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "maior que com ponto" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "muito muito menor que" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "muito muito maior que" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "menor que igual a ou maior que" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "maior que igual a ou menor que" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "igual a ou menor que" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "igual a ou maior que" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "igual a ou precede" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "igual a ou sucede" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "não precede ou igual" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "não sucede ou igual" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "imagem não quadrada de, ou igual a" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "não quadrado original de, ou igual a" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "imagem quadrada de, ou não igual a" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "quadrado original de, ou não igual a" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "menor que mas não equivalente a" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "maior que mas não equivalente a" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "precede mas não equivalente a" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "sucede mas não equivalente a" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "não subgrupo normal de" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "não contém como subgrupo normal" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "não subgrupo normal de ou igual a" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "não contém como subgrupo normal ou igual" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "reticências verticais" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "reticências horizontais centradas" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "reticências diagonais à direita para cima" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "reticências diagonais à direita para baixo" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "pertence com traço longo" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "pertence com barra vertical no fim do traço" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "pertence pequeno com barra vertical no fim do traço" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "pertence com ponto acima" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "pertence com barra acima" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "pertence pequeno com barra acima" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "pertence com barra abaixo" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "pertence com dois traços" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "contém com traço longo" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "contém com barra vertical no fim do traço" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "contém pequeno com barra vertical no fim do traço" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "pertence pequeno com barra vertical no fim do traço" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "pertence com barra acima" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "pertence em notação z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "topo de parênteses esquerdo" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "topo de parênteses direito" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "fundo de parênteses esquerdo" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "fundo de parênteses direito" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "chaveta superior" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "chaveta inferior" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "parênteses angular esquerdo" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "parênteses angular direito" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "círculo com ponto" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "união com ponto" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "união com mais" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "intersecção quadrada" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "união quadrada" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "quadrado preto" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "quadrado em branco" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "losango preto" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "círculo em branco" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "círculo preto" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "marca branca" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "quadrado preto médio pequeno" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s com sublinhado" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s com barra" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s com linha vertical" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplicação" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "em branco" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "negrito" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "entrou num marcador" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "marcadores gravados" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "impossível gravar os marcadores" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nenhum marcador encontrado." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Marcador não encontrado." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Modo bypass ativado." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Impossível aceder ao ecrã da calculadora" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ícone" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Estilo de maiúsculas definido como ícone." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "nenhum" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Estilo de maiúsculas definido como nenhum." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "soletrar" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Estilo de maiúsculas definido como soletrar." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "A aplicação está a controlar o cursor." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "O Cthulhu está a controlar o cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Célula %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s selecionada" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s por %s selecionadas" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s por %s não selecionadas" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s não selecionada" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Impedir a utilização da opção" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Forçar a utilização da opção" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPÇÃO" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Argumentos opcionais" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Utilização: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Os seguintes não são válidos: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Imprimir as aplicações conhecidas em execução" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Carregar perfil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "O perfil não pôde ser carregado: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Não é possível iniciar o Cthulhu porque não consegue ligar-se ao ambiente de " -"trabalho.Impossível iniciar o leitor de ecrã porque não se consegue ligar ao " -"Desktop." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Impossível ativar o gestor de definições. A terminar." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Já está em execução outro processo do leitor de ecrã para esta sessão.\n" -"Execute \"cthulhu --replace\" para substituir esse processo por um novo." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Utilizar uma pasta alternativa para as preferências do utilizador" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "PASTA" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versão desta aplicação" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Substituir uma instância do Cthulhu atualmente em execução" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Mostrar esta mensagem de ajuda e sair" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Enviar informação de depuração para debug-AAAA-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Enviar informação de depuração para o ficheiro especificado" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FICHEIRO" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Definir as preferências do utilizador (versão em texto)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Definir as preferências do utilizador (versão em GUI)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Reportar erros (em inglês) para https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Conteúdo cortado para a área de transferência." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "cortar" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Conteúdo copiado para a área de transferência." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copiado" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Conteúdo colado da área de transferência." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "colado" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Não anunciar quando os seus contactos estão a escrever." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anunciar quando os seus contactos estão a escrever." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Mensagem da sala de diálogo %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Novo separador de diálogo %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Não ler o nome da sala de diálogo." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "ler o nome da sala de conversação." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" -"Não fornecer um histórico de mensagens específico das salas de diálogo." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Fornecer um histórico de mensagens específico das salas de diálogo." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "início de eliminação" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "fim de eliminação" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "início de inserção" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "fim de inserção" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "início do destaque" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "fim do destaque" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "fim da sugestão" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Fim do ''container''." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Não está num ''container''." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "todos os itens selecionados" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "O botão predefinido é %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "O botão predefinido é %s. Acinzentado" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "O botão predefinido não encontrado" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subscrito %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " elevado %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Não está numa caixa de diálogo" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "todo o documento selecionado" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "todo o documento desselecionado" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "documento selecionado a partir da posição do cursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "documento não selecionado a partir da posição do cursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "documento selecionado até à posição do cursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "documento não selecionado até à posição do cursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Cabeçalho dinâmico de coluna definido para a linha %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Cabeçalho dinâmico de coluna limpo." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Cabeçalho dinâmico de linha definido para a coluna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Cabeçalho dinâmico de linha limpo." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "vazia" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Nenhum ficheiro encontrado." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Conteúdo anexado à área de transferência." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Conteúdo copiado para a área de transferência." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Não está em revisão plana." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "A entrar em revisão plana." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "A sair da revisão plana." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Revisão plana restrita ao objeto atual" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Revisão plana sem restrições" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "contém fórmula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "abre a janela" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "abre a grelha" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "abre a caixa da lista" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "abre o menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "abre a árvore" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "ligação de mapa de imagem" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "A tecla introduzida já está associada a %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tecla capturada: %s. Prima Enter para confirmar." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "A nova tecla é: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Atalho de teclado apagado. Prima Enter para confirmar." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "O atalho de teclado foi removido." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "digite uma nova tecla" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tecla" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Eco definido para tecla." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nenhum" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Eco definido para nenhum." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tecla e palavra" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Eco definido para tecla e palavra." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "frase" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Eco definido para frase." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "palavra" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Eco definido para palavra." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "palavra e frase" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Eco definido para palavra e frase." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Entre: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "um símbolo atuarial" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "uma caixa" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "um círculo" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "sinal de divisão longo" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "um radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "uma caixa arredondada" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "horizontal traço" - -# -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "uma barra vertical" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "barra diagonal longa" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "uma barra diagonal acima" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "seta noroeste" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "uma linha no fundo" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "uma linha à esquerda" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "uma linha à direita" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "uma linha no topo" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "ângulo fasorial" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "um síbolo fatorial árabe" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "i comercial" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "início da fração" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "fração sem barra, início" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "sobre" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "fim de fração" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "raíz quadrada de" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "raíz cúbica de" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "raiz de" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "início da raiz" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "fim da raiz" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subscrito" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "elevado" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pré-subscrito" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pré-elevado" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "escrito por baixo" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "escrito por cima" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "fim de tabela" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "fim de tabela aninhada" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inacessível" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Desativada" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Leitura de indentação e justificação desativada." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Ativada" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Leitura da indentação e justificação ativada." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Modo de aprendizagem. Prima \"Esc\" para sair." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"A iniciar o modo de aprendizagem. Pressione qualquer tecla para ouvir a sua " -"função. Para ver a documentação do leitor de ecrã pressione F1. Para obter " -"uma lista dos atalhos predefinidos do leitor de ecrã, pressione F2. Para " -"obter uma lista dos atalhos do leitor de ecrã para a aplicação atual, " -"pressione F3. Para terminar o modo de aprendizagem, pressione a tecla Esc." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "a abandonar citação." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "a abandonar detalhes." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "a abandonar fonte." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "a abandonar figura." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "a abandonar formulário." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "a sair da faixa." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "a abandonar conteúdo complementar." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "a abandonar informação." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "a abandonar conteúdo principal." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "a sair da navegação." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "a sair da região." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "a sair da procura." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "a sair da lista." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "a sair do painel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "a abandonar a tabela." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "a sair da dica de ferramentas." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "a sair de abstrato." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "a abandonar agradecimentos." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "a abandonar posfácio." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "a abandonar anexo." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "a abandonar bibliografia." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "a abandonar capítulo." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "a abandonar colofão." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "a abandonar conclusão." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "a abandonar crédito." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "a abandonar créditos." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "a sair de dedicação." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "a sair da tabela." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "a abandonar epígrafe." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "a abandonar epílogo." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "a abandonar errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "a abandonar exemplo." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "a abandonar introdução." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "a abandonar glossário." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "a abandonar índice." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "a sair da introdução." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "a abandonar lista de páginas." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "a abandonar peça." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "a abandonar prefácio." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "a abandonar prólogo." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "a abandonar frase-chave." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "a abandonar QNA." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "a abandonar sugestão." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "a abandonar tabela de conteúdos." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "linha selecionada abaixo da posição do cursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "linha selecionada acima da posição do cursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "linha não selecionada abaixo da posição do cursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "linha não selecionada acima da posição do cursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "A sair do modo de aprendizagem." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "linha selecionada desde o início até à posição anterior do cursor" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "linha selecionada até ao final a partir da posição anterior do cursor" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ligação" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "mesma página" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "mesmo site" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "site diferente" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "ligação %(uri)s para %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "ligação %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "hiperligação %s visitada" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Utilize as «Setas para Cima e para Baixo» para navegar na lista. Pressione " -"Esc para sair." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Todas as regiões interativas estão desligadas" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "nível de notificações das regiões interativas restaurado" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nível de notificações %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "a definir as regiões interativas para acertivo" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "a definir as regiões interativas para desligado" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "a definir as regiões interativas para educado" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "a definir as regiões interativas para rude" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "A monitorização de regiões interativas está desligada" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "A monitorização de regiões interativas está ligada" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nenhuma mensagem de região interativa gravada" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "O suporte para regiões interativas está desligado" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Não encontrada" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Impossível encontrar a localização atual." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "desligado" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "ligado" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "mal escrito" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Palavra incorreta: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Contexto é %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Modo de navegação" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Modo de foco" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Para ativar o modo de foco prima %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "O modo de foco é fixo." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "O modo de navegação é fixo." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Modo de disposição." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Modo de objeto." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Ponteiro movido para objeto." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Objeto de pairar com o rato não encontrado." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Revisão com o rato inativa." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Revisão com o rato ativa." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Erro: impossível criar lista de objetos." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Nenhum dependente." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Nenhum seguinte." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Nenhum acima." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Nenhum anterior." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Navegação simplificada ativada." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Navegação simplificada desativada." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Grau de aninhar %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Foi adicionado um novo item" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Nenhuma ação encontrada em: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Sem foco" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nenhuma aplicação tem foco." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Não existem mais citações." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Não existem mais botões." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Não existem mais caixas de verificação." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Não existem mais objetos grandes." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Não existem mais clicáveis." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Não existem mais caixas de combinação." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Não existem mais entradas." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Não existem mais campos de formulário." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Não existe mais nenhum título." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Não existem mais títulos de nível %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Não há mais quadros internos." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Não existem mais imagens." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nenhum marco encontrado." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Não existem mais ligações." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Não existem mais listas." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Não existe mais itens de lista." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Não existem mais regiões interativas." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Não existe mais nenhum parágrafo." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Não existe mais nenhum botão rádio." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Não existe mais nenhum separador." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Não existem mais tabelas." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Não existem mais ligações por visitar." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Não existem mais ligações visitadas." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Sem texto selecionado." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Não é ligação." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificação" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Fundo" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Topo" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Sem mensagem de notificação" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "dígitos" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Dizer números como dígitos." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "palavras" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Dizer números como palavras." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "desligado" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ligado" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "A carregar. Aguarde." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Carregamento terminado." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Terminou o carregamento de %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "A página tem %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "página selecionada a partir da posição do cursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "página selecionada até à posição do cursor" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "página não selecionada a partir da posição do cursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "página não selecionada até à posição do cursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "parágrafo selecionado abaixo da posição do cursor" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "prágrafo selecionado acima da posição do cursor" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "parágrafo não selecionado abaixo da posição do cursor" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "parágrafo não selecionado acima da posição do cursor" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Já possui uma instância do diálogo de preferências do Cthulhu aberta.\n" -"\n" -"Feche-a antes de abrir uma nova." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapositivo %(position)d de %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Perfil definido como %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nenhum perfil encontrado." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra de progresso %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Toda" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Grau de pontuação definido para toda." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Maioria" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Grau de pontuação definido para a maioria." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nenhuma" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Grau de pontuação definido para nenhuma." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Alguma" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Grau de pontuação definido para alguma." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "A procurar." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Procura terminada." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Definições do Cthulhu recarregadas." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "O texto selecionado é: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Seleção eliminada." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Seleção reposta." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Texto não selecionado." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Tamanho: %d, %d. Localização: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Largura: %d. Altura: %d. %d da esquerda. %d do topo." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Voz desativada." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Voz ativada." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "mais rápido." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "mais lento." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "mais alto." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "mais baixo." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "alto." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "baixo." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Velocidade %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Tom %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volume %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Módulo do Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Voz do Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nenhum módulo Speech-dispatcher disponível" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nenhuma voz Speech-dispatcher disponível" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Definições de voz guardadas" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Não foi possível guardar as definições de voz" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Grau de verbosidade: breve" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Grau de verbosidade: verboso" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " ponto ponto ponto" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "O Cthulhu dá-lhe as boas-vindas." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu espreita sob as ondas." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Modo de suspensão ativado para %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Modo de suspensão desativado para %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "A voz está indisponível." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Não encontrada" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Barra de estado não encontrada" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "expressão não encontrada" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Teclas de navegação estruturada desativadas." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Teclas de navegação estruturada ativadas." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Não encontrada" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Linha %(row)d, coluna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Fim da tabela" - -# 48x48/emblems/emblem-special.icon.in.h:1 -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Lê a célula" - -# 48x48/emblems/emblem-special.icon.in.h:1 -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Lê a linha" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Não uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Não se encontra numa tabela." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Colunas reordenadas" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Linhas reordenadas" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "coluna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "coluna %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Fundo da coluna." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Topo da coluna." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Coluna %s selecionada" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Colunas %s por %s selecionadas" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Colunas %s por %s não selecionadas" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Coluna %s desselecionada" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "linha %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "linha %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Início da linha." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Final da linha." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Linha apagada." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Última linha apagada." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Linha inserida." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Linha inserida no fim da tabela." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Linha %s selecionada" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Linhas %s por %s selecionadas" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Linhas %s por %s não selecionadas" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Linha %s desselecionada" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "selecionado" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "desselecionado" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H horas %M minutos e %S segundos" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H horas e %M minutos" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "anular" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "refazer" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versão %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "espaço em branco" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "A voltar para baixo." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "A voltar para cima." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 itens" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Célula estende-se por %d linha" -msgstr[1] "Célula estende-se por %d linhas" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d coluna" -msgstr[1] " %d colunas" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Célula estende-se por %d coluna" -msgstr[1] "Célula estende-se por %d colunas" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d carácter demasiado extenso" -msgstr[1] "%d caracteres demasiado extenso" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d diálogo)" -msgstr[1] "(%d diálogos)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d janela sem foco" -msgstr[1] "%d janelas sem foco" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ficheiro encontrado" -msgstr[1] "%d ficheiros encontrados" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulário" -msgstr[1] "%d formulários" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d título" -msgstr[1] "%d títulos" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d item" -msgstr[1] "%d itens" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d marco" -msgstr[1] "%d marcos" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d item encontrado" -msgstr[1] "%d itens encontrados" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "A abandonar %d citação." -msgstr[1] "A abandonar %d citações." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "A abandonar %d lista." -msgstr[1] "A abandonar %d listas." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Lista de tamanho desconhecido" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista com %d item" -msgstr[1] "Lista com %d itens" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Fonte de tamanho desconhecido" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Fonte com %d artigo" -msgstr[1] "Fonte com %d artigos" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Lista descritiva com %d termo" -msgstr[1] "Lista descritiva com %d termos" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d valor" -msgstr[1] "%d valores" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabela matemática com %d linha" -msgstr[1] "tabela matemática com %d linhas" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d coluna" -msgstr[1] "%d colunas" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tabela matemática aninhada com %d linha" -msgstr[1] "tabela matemática aninhada com %d linhas" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d mensagem.\n" -msgstr[1] "%d mensagens.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d por cento." -msgstr[1] "%d por cento." - -# python-format -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d por cento do documento lido" -msgstr[1] "%d por cento do documento lido" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixels" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d carácter %(repeatChar)s" -msgstr[1] "%(count)d caracteres %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d de %(total)d itens selecionado" -msgstr[1] "%(index)d de %(total)d itens selecionados" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d atalho predefinido do leitor de ecrã encontrado." -msgstr[1] "%d atalhos por omissão do leitor de ecrã encontrados." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"%(count)d atalho do leitor de ecrã encontrado para a aplicação " -"%(application)s." -msgstr[1] "" -"%(count)d atalhos do leitor de ecrã encontrados para a aplicação " -"%(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espaço" -msgstr[1] "%d espaços" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulação" -msgstr[1] "%d tabulações" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabela" -msgstr[1] "%d tabelas" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabela de tamanho desconhecido" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabela com %d coluna, contagem de linhas desconhecida" -msgstr[1] "tabela com %d colunas, contagem de linhas desconhecida" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabela com %d linha, contagem de colunas desconhecida" -msgstr[1] "tabela com %d linhas, contagem de colunas desconhecida" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabela com %d linha" -msgstr[1] "tabela com %d linhas" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d segundo atrás" -msgstr[1] "%d segundos atrás" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minuto atrás" -msgstr[1] "%d minutos atrás" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d hora atrás" -msgstr[1] "%d horas atrás" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d dia atrás" -msgstr[1] "%d dias atrás" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d ligação por visitar" -msgstr[1] "%d ligações por visitar" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d ligação visitada" -msgstr[1] "%d ligações visitadas" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "alternar" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "em %(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "item %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NÍVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nível de árvore %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NÍVEL DE ÁRVORE %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detalhes para %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "tem detalhes em %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "sugestão" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "caixa combinada editavel" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "conteúdo editável" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "fonte" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figura" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "abstrato" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "confirmações" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "depois da palavra" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "apêndice" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "entrada bibliográfica" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografia" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "capítulo" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "cólofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conslusão" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "capa" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "crédito" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "créditos" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedicação" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "nota final" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "notas finais" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epígrafe" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epílogo" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "exemplo" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "prefácio" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosário" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "índex" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introdução" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "quebra de página" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "lista da páginapage up" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "parte" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "preâmbulo" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prólogo" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "frase chave" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "QNA" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "legenda" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "tabela de conteúdos" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "t%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nível %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "barra de deslocamento horizontal" - -# -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "barra de deslocamento vertical" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "cursor horizontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "cursor vertical" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "divisor horizontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "divisor vertical" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "mudar" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Painel de ícones" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "faixa" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "conteúdo complementar" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informação" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "conteúdo principal" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navegação" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "região" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "procura" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "hiperligação visitada" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "botão do menu" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "ordenação ascendente" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "ordenação descendente" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "ordenado" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "clicável" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "ocultado" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "expandido" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "tem descrição longa" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "marcada" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "desmarcada" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "ligado" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "desligado" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "parcialmente marcada" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "clicado" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "não clicado" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "não selecionado" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "selecionado" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "não selecionado" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "não selecionada" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visitada" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "por visitar" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "escurecido" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "só de leitura" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "soleitura" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "requerido" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "seleção múltipla" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "entrada inválida" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "inválido" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "soletrar inválido" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "soletrar" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "gramática inválida" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramática" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Localizar" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Diálogo de procura do leitor de ecrã" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Fechar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Localizar" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Procurar por:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Procurar por:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Topo da janela" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Topo da janela" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Começar a partir de:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Dar a volta" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Procurar para _trás" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Direção de procura:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Comparar maiúsculas" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Comparar só _palavra completa" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opções:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Predefinição" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Maiúsculas" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiperligação" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicação" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Janela" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferências do Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "A_juda" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Aplicar" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "Computador _Portátil" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Tipo de teclado" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Perfil ativo:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Perfil inicial:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Carregar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Gravar _Como" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Remover" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Perfis" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Apresentar dicas" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Dizer o _objeto sob o rato" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Rato" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Formato de _hora:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formato d_e data:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Hora e data" - -# 48x48/emblems/emblem-special.icon.in.h:1 -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Dizer progresso" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Percentagem em Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frequência (segundos):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplica-se a:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Sons de progresso" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Atualizações da barra de progresso" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Ativar _recuo e avanço em dizer tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Ativar a navegação e_struturada em dizer tudo" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "_Dizer tudo por:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Anunciar citações em bloco em Dizer tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Anunciar li_stas em Dizer tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Anunciar _tabelas em Dizer tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Anunciar _painéis em Dizer tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Anunciar _formulários em Dizer tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Anunciar _pontos de referência em Dizer tudo" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Ler Tudo" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Apresentação de elemento:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Geral" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lume:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Frequência:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Velocidade:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Pessoa:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Idioma:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Sinteti_zador de voz:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Sistema de voz:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipo de _voz:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Estilo de maiúsculas:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Definições de tipo de voz" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Ler expressões com maiúsculas e minúsculas como pala_vras" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Ler os _números como dígitos" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Definições globais de voz" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Ativar a voz" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Ver_bosidade" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Verbosidade" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Todas" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Grau de pontuação" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Ler só o texto mostrado" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Ler linhas em branco" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Dizer a _indentação e alinhamento" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Dizer mnemónicas dos ob_jetos" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Dizer a p_osição do filho" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Ler as mensagens tutoriais" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Mensagens de _sistema detalhadas" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Dizer as _cores como nomes" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Anunciar citações de bloco durante a navegação" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Anunciar _listas durante a navegação" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Anunciar _tabelas durante a navegação" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Lê palavras indicadas como _mal escritas" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Anunciar _painéis durante a navegação" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Anunciar _pontos de referência durante a navegação" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Anunciar _formulários durante a navegação" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "_Descrição da voz" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Dizer linha completa em _folhas de cálculo" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Dizer linha completa em tabelas de _documento" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Dizer linha completa em tabelas _GUI" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Contexto falado" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Ativar _suporte Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Nomes de controlos _abreviados" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Desativar o símbolo de _fim de linha" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tabela de contrações:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Ativar abreviaturas Braille" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Ativar continuação da _palavra" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Definições de monitor" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Nenhuma" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicador de seleção" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicador de hiperligação" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Ativar _mensagens flash" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Duração (segs):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Mensagens são _persistentes" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Mensagens são _detalhadas" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Definições de mensagens flash" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Ativar eco de _teclas" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Ativar teclas _alfabéticas" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Ativar teclas N_uméricas" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Ativar teclas de _pontuação" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Ativar e_spaço" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Ativar teclas _modificadoras" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Ativar teclas de _função" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Ativar Teclas de ação" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Ativar teclas de _navegação" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Ativar eco por _palavra" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Ativar eco por _frase" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Eco" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Teclas _modificadoras do leitor de ecrã:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Atalhos de teclado" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Dicionário de pronunciação" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nova entrada" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Eliminar" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronunciação" - -# 48x48/emblems/emblem-special.icon.in.h:1 -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Ler tudo" - -# 48x48/emblems/emblem-special.icon.in.h:1 -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Não ler" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Repor" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributos do texto" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mover para o _fundo" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mover a_baixo um" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mover a_cima um" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mover para o _topo" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Ajustar o atributo selecionado" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicador Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributos do texto" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Ativar assistente de IA" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Fornecedor:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Local - Grátis)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Ficheiro de chave _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Caminho para o ficheiro de chave API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Obter chave API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Abrir navegador para obter a chave API Claude e guardar automaticamente" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Requer confirmação antes de ações de IA" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Modelo Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nome do modelo para Ollama (ex. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Ponto de acesso Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL do ponto de acesso API Ollama (ex. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Qualidade da captura de ecrã:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Baixo" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Médio" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Alto" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Assistente de IA" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Código de _idioma:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Fator de _escala:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Imagem em escala de _cinzentos" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Inverter imagem" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Imagem a _preto e branco" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Limiar preto/branco:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analisar cores" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Copiar resultados para a área de _transferência" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alfa, b : bravo, c : tchárli, d : delta, e : eco, f : focstrote, g : " -"golfe, h : hotel, i : índia, j : juliéte, k : quilo, l : lima, m : maique, " -"n : novêmber, o : óscar, p : papa, q : quebéque, r : rômiô, s : sierra, t : " -"tango, u : uniforme, v : victor, w : uisquy, x : écsrrei, y : ianqui, z : " -"zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "cor de fundo" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "altura total do fundo" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "fundo por pontos" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direção" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editável" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nome de família" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "cor do texto" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "cor do texto em pontos" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efeito de letra" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indentação" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "erro" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisível" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "alinhamento" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "idioma" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "margem esquerda" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "altura da linha" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "estilo de parágrafo" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixels sobre as linhas" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixels sob as linhas" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixels dentro de uma quebra de linha" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "margem direita" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "elevação" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "escala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "tamanho" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "condensação" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "rasurado" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estilo" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decoração do texto" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotação do texto" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "sombra do texto" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "sublinhado" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variante" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "alinhamento vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "espessura" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "modo de quebra" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "modo de escrita" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "verdadeiro" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falso" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "nenhum" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "embutido" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "relevo" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "destacado" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "linha acima" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "rasurado" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "piscar" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "preto" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "único" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "duplo" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "baixo" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "carácter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "palavra" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "carácter de palavra" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "epd" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "dpe" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "esquerda" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "direita" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centro" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "sem alinhamento" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "preencher" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensado" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensado" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensado" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensado" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi expandido" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expandido" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra expandido" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra expandido" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "maiúsculas pequenas" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblíquo" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "itálico" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Predefinição" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Corpo do texto" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Título" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "linha base" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "subscrito" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "sobrescrito" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "topo" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "topo do texto" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "meio" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "fundo" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "fundo do texto" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "herdar" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "epd-tf" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "dpe-tf" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tf-de" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tf-ed" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "ft-de" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "ft-ed" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "ed" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "de" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tf" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "sólido" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "soletrar" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Prima espaço para alternar." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Prima espaço para expandir, utilize acima e abaixo para selecionar um item." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Prima alt+f6 para dar o foco a janelas filhas." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Para mover para os itens, utilize as teclas de setas ou escreva o que " -"procura." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Para entrar nos menus de sistema prima Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Utilize acima e abaixo para selecionar um item." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Para recolher, prima Shift+Seta esquerda." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Para expandir, prima Shift+Seta direita." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Para ativar prima Enter." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Insira texto." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Utilize esquerda e direita para ver outros separadores." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Para ativar prima espaço." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Utilize as setas acima ou abaixo para selecionar o valor. Ou insira o valor " -"numérico desejado." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Utilize as teclas de setas para alterar." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Para navegar, prima as setas esquerda ou direita. Para mover ao longo dos " -"itens prima as setas acima ou abaixo." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Para entrar num submenu, prima a seta direita." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Para diminuir prima a seta esquerda, para aumentar prima a seta direita. " -"Para ir para o mínimo prima Home e para o máximo prima End." diff --git a/po/pt_BR.po b/po/pt_BR.po deleted file mode 100644 index 5f30adb..0000000 --- a/po/pt_BR.po +++ /dev/null @@ -1,9319 +0,0 @@ -# Brazilian Portuguese translation of Cthulhu. -# Copyright (C) 2022 the Cthulhu authors. -# This file is distributed under the same license as the cthulhu package. -# Raphael Higino , 2004-2005. -# Jonh Wendell , 2007. -# Fábio Nogueira , 2007. -# Michel Recondo , 2008. -# André Gondim 2009. -# Jonh Wendell , 2009. -# Marco de Freitas , 2009. -# Leonardo Ferreira Fontenelle , 2007-2009. -# Og Maciel , 2007, 2009. -# Djavan Fagundes , 2007, 2010. -# Felipe Vieira Borges , 2010 -# Hugo Vaz Sampaio , 2010. -# Rodrigo Padula de Oliveira , 2011. -# Antonio Fernandes C. Neto , 2011, 2012. -# José Vilmar Estácio de Souza , 2013. -# Júnior Pires , 2013. -# Raniere Gaia , 2015. -# Rafael Gazoni , 2016. -# Enrico Nicoletto , 2013-2016, 2018. -# Bruno Lopes da Silva , 2018. -# Henrique Machado Campos , 2020. -# Tiago Melo Casal , 2007-2021. -# Rafael Fontenelle , 2013-2021. -# Matheus Barbosa , 2022. -# Leônidas Araújo , 2022. -# Alex Jr , 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2024-03-08 08:48-0300\n" -"Last-Translator: Leônidas Araújo \n" -"Language-Team: Brazilian Portuguese \n" -"Language: pt_BR\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 3.3.1\n" -"X-Project-Style: gnome\n" -"X-DL-Team: pt_BR\n" -"X-DL-Module: cthulhu\n" -"X-DL-Branch: master\n" -"X-DL-Domain: po\n" -"X-DL-State: Translating\n" - -msgid "Cthulhu Screen Reader" -msgstr "Leitor de tela Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "leitor;tela;acessibilidade;voz;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "sta" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -# área de gráficos -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "ágrf" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "lgnd" - -# caixa de seleção | item de menu de seleção -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "slç" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "slcor" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "cbçcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cxc" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ícn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "qdr" - -# seletor -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "sltr" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "pndir" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "desenh" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "slarq" - -# preenchedor -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "prc" - -# fonte -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -# painel transparente -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "transpa" - -# título -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "ttl" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "qdri" - -# rótulo -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "rtl" - -# painel sobreposto -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "pnspost" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "itmlst" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "brmnu" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "itmmnu" - -# painel de opções -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "pnopç" - -# aba de página -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "apg" - -# lista de abas de página -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "lstabas" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pn" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "snh" - -# menu de contexto -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnuctx" - -# barra de progresso -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "brprg" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "bt" - -# botão de opção -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "btopç" - -# ítem de menu de opções -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "itmmnuopç" - -# painel raiz -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "pnrz" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "cbçln" - -# barra de rolagem -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "brrlg" - -# painel de rolagem -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "pnrlg" - -# seção -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sç" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprdr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "dslz" - -# painel ajustável -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "pnajus" - -# botão do seletor numérico -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "btslnum" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "brstt" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cél" - -# item de menu destacável -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "itmmnudstc" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -# botão de alternância -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "btaltr" - -# barra de ferramentas -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "brfer" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "dica" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "árv" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tblárv" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "dsc" - -# porta de visualização -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "prtvslz" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "jnl" - -# cabeçalho -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "cbç" - -# rodapé -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "rdp" - -# parágrafo -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "pará" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apl" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "bredt" - -# componente embutido -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Tcheco grau 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Espanhol grau 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Francês do Canadá grau 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francês da França grau 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letão grau 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holandês dos Países Baixos grau 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norueguês grau 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norueguês grau 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norueguês grau 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norueguês grau 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polonês grau 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Português grau 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Sueco grau 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Árabe grau 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galês grau 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galês grau 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Alemão grau 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Alemão grau 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Alemão grau 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Inglês do Reino Unido grau 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Inglês do Reino Unido grau 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Inglês dos Estados Unidos grau 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Inglês dos Estados Unidos grau 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Francês do Canadá grau 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francês da França grau 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grego grau 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi grau 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Húngaro informático de 8 pontos" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Húngaro grau 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Húngaro grau 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiano grau 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Holandês da Bélgica grau 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "espaço" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nova linha" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "exclamação" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "aspas" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "número" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "cifrão" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "porcento" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "e comercial" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apóstrofo" - -# abre parêntesis -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "abre parêntesis" - -# fecha parêntesis -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "fecha parêntesis" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterisco" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "mais" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "vírgula" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "hífen" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "ponto" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "barra" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dois pontos" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "ponto e vírgula" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "menor que" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "igual" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "maior que" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "interrogação" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "arroba" - -# abre colchete -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "abre colchete" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "barra invertida" - -# fecha colchete -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "fecha colchete" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "circunflexo" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "sublinha" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -# abre chave -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "abre chave" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "barra vertical" - -# fecha chave -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "fecha chave" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "til" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "espaço não separável" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "ponto de exclamação invertido" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centavos" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "libras" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "símbolo monetário" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "iene" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "barra vertical cortada" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "parágrafo" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "trema" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "ordinal feminino" - -# abre aspas angulares -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "abre aspas angulares" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "não lógico" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "hífen discricionário" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrado" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "mácron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "graus" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "mais ou menos" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "2 sobrescrito" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "3 sobrescrito" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "agudo" - -# micro -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "micro" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "marcador de parágrafo" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "ponto mediano" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilha" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 sobrescrito" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -# fecha aspas angulares -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "fecha aspas angulares" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "um quarto" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "um meio" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "três quartos" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "interrogação invertida" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a agudo" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AGUDO" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TIL" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A TREMA" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A CÍRCULO" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILHA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AGUDO" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E TREMA" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AGUDO" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I TREMA" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TIL" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AGUDO" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TIL" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O TREMA" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "vezes" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O CORTADO" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AGUDO" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUNFLEXO" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U TREMA" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AGUDO" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circunflexo" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a til" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a trema" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a círculo" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilha" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e agudo" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circunflexo" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e trema" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i agudo" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circunflexo" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i trema" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n til" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o agudo" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circunflexo" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o til" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o trema" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "dividido por" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o cortado" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u agudo" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circunflexo" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u trema" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y agudo" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y trema" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y TREMA" - -# encher -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florim" - -# traço -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "traço" - -# [apóstrofo de abertura] -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "apóstrofo esquerdo" - -# [verdadeiro apóstrofo] -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "apóstrofo direito" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "aspa baixa simples" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "abre aspas" - -# fecha aspas -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "fecha aspas" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "aspa baixa dupla" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "cruz" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "cruz dupla" - -# bolinha -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "bolinha" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "marcador triangular" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "por mil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "plica" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "plica dupla" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "plica tripla" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "marcador hífen" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marca comercial" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "marca de seleção" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "marca de seleção realçada" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "marcador x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "0 sobrescrito" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "4 sobrescrito" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "5 sobrescrito" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "6 sobrescrito" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "7 sobrescrito" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "8 sobrescrito" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "9 sobrescrito" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "mais sobrescrito" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "menor sobrescrito" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "igual sobrescrito" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "parêntese esquerdo sobrescrito" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "parêntese direito sobrescrito" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n sobrescrito" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "0 subscrito" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "1 subscrito" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "2 subscrito" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "3 subscrito" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "4 subscrito" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "5 subscrito" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "6 subscrito" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "7 subscrito" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "8 subscrito" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "9 subscrito" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "mais subscrito" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "menor subscrito" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "igual subscrito" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "parêntese esquerdo subscrito" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "parêntese direito subscrito" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "quadrado negro" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "losango negro" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "caractere de substituição de objeto" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Move o ponteiro para o item atual" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Clica com o botão esquerdo no item plano em revisão atual" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Clica com o botão direito no item plano em revisão atual" - -# "Fala" fica um pouco estranho aqui -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Lê o documento inteiro" - -# "Fala" fica um pouco estranho aqui -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Lê a tela inteira usando revisão plana" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Executa a operação básica de Onde Eu Estou" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Executa a operação detalhada de Onde Eu Estou" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Fala a seleção atual" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Fala os detalhes do link" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Apresentar o botão padrão" - -# "Fala" fica um pouco estranho aqui -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Apresenta a barra de estado" - -# "Fala" fica um pouco estranho aqui -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Apresenta a barra de título" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Abre o diálogo de Localizar" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Mostrar lista de ações" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Pesquisa pela próxima ocorrência de um trecho de texto" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Pesquisa pela ocorrência anterior de um trecho de texto" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Entra e sai do modo de revisão plana" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Alterne a restrição da revisão plana ao objeto atual" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Move a revisão plana para a posição inicial" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Move a revisão plana para a posição final" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Move a revisão plana para o início da linha anterior" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Fala a linha de revisão plana atual" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Soletra a linha de revisão plana atual" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Soletra foneticamente a linha de revisão plana atual" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Move a revisão plana para o início da próxima linha" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Move a revisão plana para o item ou palavra anterior" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Fala a palavra ou item atualmente em revisão plana" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Soletra a palavra ou item atualmente em revisão plana" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Soletra foneticamente a palavra ou item atualmente em revisão plana" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Move a revisão plana para o item ou palavra seguinte" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Move a revisão plana para a palavra acima da palavra atual" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Fala o objeto atualmente em revisão plana" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Move a revisão plana para a palavra abaixo da palavra atual" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Move a revisão plana para o caractere anterior" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Fala o caractere atual em revisão plana" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Fala foneticamente o caractere atual em revisão plana" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Fala o valor Unicode do caractere atual em revisão plana" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Move a revisão plana para o caractere seguinte" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Move a revisão plana para o final da linha" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Move a revisão plana para o canto inferior esquerdo" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copia o conteúdo sob revisão plana para a área de transferência" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Acrescenta o conteúdo sob revisão plana para a área de transferência" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Mostrar conteúdo de revisão plana" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Alterna entre ler apenas a célula atual da tabela ou toda a linha" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Lê os atributos associados ao caractere de texto atual" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Varre a linha braille para a esquerda" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Varre a linha braille para a direita" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Retorna ao objeto com foco do teclado" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Ativa ou desativa o Braille contraído" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Processa uma tecla de encaminhamento do cursor" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marca o início de uma seleção de texto" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marca o fim de uma seleção de texto" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Entra no modo de aprendizado. Pressione ESC para sair deste modo" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Diminui a velocidade da fala" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Aumenta a velocidade da fala" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Diminui a tonalidade da fala" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Aumenta a tonalidade da fala" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Aumenta o volume da fala" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Diminui o volume da fala" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Selecionar a configuração de voz anterior" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Selecionar a próxima configuração de voz" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Diminuir a configuração de voz atual" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Aumentar a configuração de voz atual" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Salvar configurações de voz" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Alterna o silenciamento da fala" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Alterna o nível de verbosidade da fala" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Alternar modo de suspensão" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Encerra o leitor de tela" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Exibe o diálogo de configuração de preferências" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Exibe o diálogo de configuração de preferências do aplicativo" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Alterna a fala entre recuo e justificação" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Altera o estilo de números falados" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Circula para o próximo nível de fala de pontuação" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Alterna para o próximo sintetizador de voz" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Circula para o próximo perfil de configurações" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Circula para o próximo estilo de letras maiúsculas" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Circula para o próximo nível de eco de tecla" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Circula entre os níveis de depuração durante a execução" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Marca onde eu estou em relação à posição atual" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Vai para o local do marcador anterior" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Vai para marcador" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Vai para o local do próximo marcador" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Adiciona marcador" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Salva marcadores" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Habilita ou desabilita o modo de revisão do mouse" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Fala a hora atual" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Fala a data atual" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Apresenta tamanho e local do objeto atual" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Passa o próximo comando para o aplicativo atual" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Lê e mostra no Braille uma mensagem anterior de sala de bate-papo" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" -"Alterna entre anunciarmos ou não quando nossos amigos estiverem digitando" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Alterna entre fornecer ou não históricos de mensagens específicas para cada " -"sala de bate-papo" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Alterna entre preceder ou não mensagens de sala de bate-papo com o nome da " -"sala" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linha à esquerda" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linha à direita" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linha acima" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linha abaixo" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Congelar" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Canto superior esquerdo" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Canto inferior esquerdo" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Posição do cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Seis pontos" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Encaminhamento do cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Inicio de corte" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Linha de corte" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Apresenta a última mensagem de notificação" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Apresenta lista de mensagens de notificação" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Apresenta a mensagem de notificação anterior" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Apresenta próxima mensagem de notificação" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Vai para o próximo caractere" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Vai para o caractere anterior" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Vai para a próxima palavra" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Vai para a palavra anterior" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Vai para a próxima linha" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Vai para a linha anterior" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Vai para o início do arquivo" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Vai para o fim do arquivo" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Vai para o começo da linha" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Vai para o fim da linha" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Vai para o próximo objeto" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Vai para o objeto anterior" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Faz a caixa de combinação atual ser expandida" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Alterna a navegação por cursor entre nativo e leitor de tela" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Avança a configuração de polidez da região dinâmica" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Configura o nível padrão de polidez da região dinâmica para desligado" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Revisa anúncio de região dinâmica" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitora regiões dinâmicas" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Move o foco para dentro e para fora da área sob o mouse" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Configura a linha a ser usada como cabeçalhos dinâmicos de coluna" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Limpa os cabeçalhos dinâmicos de coluna" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Configura a coluna a ser usada como cabeçalhos dinâmicos de linha" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Limpa os cabeçalhos dinâmicos de linha" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Apresenta o conteúdo da linha de entrada" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Habilita ou desabilita teclas de navegação estrutural" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Vai para a citação anterior" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Vai para a próxima citação" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Exibe uma lista de citações" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Vai para o botão anterior" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Vai para o próximo botão" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Exibe uma lista de botões" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Vai para a caixa de seleção anterior" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Vai para a próxima caixa de seleção" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Exibe uma lista de caixas de seleção" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Vai para o objeto clicável anterior" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Vai para o próximo objeto clicável" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Exibe uma lista de objetos clicáveis" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Vai para a caixa de combinação anterior" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Vai para a próxima caixa de combinação" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Vai para o início do contêiner" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Vai para o fim do contêiner" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Exibe uma lista de caixas de combinação" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Vai para a entrada anterior" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Vai para a próxima entrada" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Exibe uma lista de entradas" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Vai para o campo de formulário anterior" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Vai para o próximo campo de formulário" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Exibe uma lista de campos de formulário" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Vai para o título anterior" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Vai para o próximo título" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Exibe uma lista de títulos" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Vai para o título anterior no nível %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Vai para o próximo título no nível %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Exibe uma lista de títulos de nível %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Vai para o quadro interno anterior" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Vai para o próximo quadro interno" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Mostra uma lista de quadros internos" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Vai para a imagem anterior" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Vai para a próxima imagem" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Exibe uma lista de imagens" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Vai para o marco anterior" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Vai para o próximo marco" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Exibe uma lista de marcos" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Vai para o bloco anterior" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Vai para o próximo bloco" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Exibe uma lista de blocos" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Vai para o link anterior" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Vai para o próximo link" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Exibe uma lista de links" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Vai para a lista anterior" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Vai para a próxima lista" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Exibe uma lista de listas" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Vai para o item anterior da lista" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Vai para o próximo item da lista" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Exibe uma lista de itens de lista" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Vai para a região dinâmica anterior" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Vai para a próxima região dinâmica" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Vai para a última região que fez um anúncio" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Ir para o parente do objeto com foco no navegador." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Ir para o primeiro parente do objeto com foco no navegador." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Ir para o próximo irmão do objeto com foco no navegador." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Ir para o irmão anterior do objeto com foco no navegador." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Clica no objeto com foco do navegador." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Alterna navegação simplificada de objetos." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Vai para o parágrafo anterior" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Vai para o próximo parágrafo" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Exibe uma lista de parágrafos" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Vai para o botão de opção anterior" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Vai para o próximo botão de opção" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Exibe uma lista de botões de opção" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Vai para o separador anterior" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Vai para o próximo separador" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Vai para a tabela anterior" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Vai para próxima tabela" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Exibe uma lista de tabelas" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Vai para a célula de baixo" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Vai para a primeira célula em uma tabela" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Vai para a última célula em uma tabela" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Vai para a célula da esquerda" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Vai para a célula da direita" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Vai para a célula de cima" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Habilita ou desabilita o modo de leiaute" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Alterna entre o modo de navegação e o modo de foco" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Habilita o modo fixo de foco" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Habilita o modo fixo de navegação" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Vai para o link anterior não visitado" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Vai para o próximo link não visitado" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Exibe uma lista de links não visitados" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Vai para o link visitado anteriormente" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Vai para o próximo link visitado" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Exibe uma lista de links visitados" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "azul-bebê" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "branco antigo" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "água-marinha" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azul-celeste" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "bege" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "biscuit" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "preto" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "amêndoa" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "azul" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "violeta-azulado" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "marrom" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "madeira" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "azul-cadete" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "amarelo-esverdeado" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "chocolate" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "coral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "azul flor de milho" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "amarelo-seda" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "carmim" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "ciano" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "azul escuro" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "ciano escuro" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "amarelo-solidago-escuro" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "cinza escuro" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verde escuro" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "cáqui-escuro" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta escuro" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "verde-oliva-escuro" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "laranja escuro" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "orquídea-escuro" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "vermelho escuro" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "salmão escuro" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "verde-mar-escuro" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "azul-ardósia-escuro" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "cinza ardósia escuro" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turquesa-escuro" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violeta-escuro" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "rosa profundo" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "azul céu profundo" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "cinza fosco" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "azul furtivo" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "tijolo refratário" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "branco floral" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "verde floresta" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fúcsia" - -# O termo também é traduzido como cinza-médio em outros "projetos" --Enrico -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "cinza-prata" - -# Encontrei esta cor também traduzida como branco-mistério, mas ao pesquisar na internet, não me parece ser uma definição popular. --Enrico -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "branco fantasma" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "ouro" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "amarelo-solidago" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "cinza" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verde" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "verde-nilo" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "verde-melão" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "rosa forte" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "vermelho indiano" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "índigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "marfim" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "cáqui" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavanda avermelhada" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "verde-grama" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "verde-primitivo" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "azul claro" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "coral claro" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "ciano claro" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "amarelo-solidago-claro" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "cinza claro" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "verde claro" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "rosa claro" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "salmão claro" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "verde-mar-claro" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "azul céu claro" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "cinza ardósia claro" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "azul-aço-claro" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "amarelo claro" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lima" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "verde lima" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linho" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "bordô" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "água-marinha-médio" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "azul-médio" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orquídea-médio" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "púrpura-médio" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "verde-mar-médio" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "azul-ardósia-médio" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "verde primavera médio" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turquesa-médio" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "vermelho violeta médio" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "azul meia-noite" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "creme de menta" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rosa embaçado" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mocassim" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "branco navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "naval" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "renda antiga" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliva" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "oliva parda" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "laranja" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "jambo" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orquídea" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "amarelo-solidago-pálido" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "verde pálido" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turquesa-pálido" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "vermelho violeta pálido" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "mamão batido" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "pêssego" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "ameixa" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "azul pólvora" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "púrpura" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "vermelho" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "marrom rosado" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "azul real" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "marrom sela" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "salmão" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "marrom amarelado" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "verde-mar" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "concha" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "prata" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "azul céu" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "azul-ardósia" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "cinza ardósia" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "neve" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "verde primavera" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "azul-aço" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "castanho claro" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "verde-azulado" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "cardo" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomate" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turquesa" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violeta" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "trigo" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "branco" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "branco fumaça" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "amarelo" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "verde amarelado" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Ativar" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Modo de foco automático durante a navegação estrutural" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Modo de foco automático durante a navegação por cursor" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Modo de foco automático durante a navegação nativa" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Ponto _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Ponto _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Pontos 7 _e 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Cancelar" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Ir para" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ícone" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Nenhum" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Soletrar" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Anunciar quanto _amigos estiverem digitando" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" -"Fornecer _históricos de mensagens específicos para cada sala de bate-papo" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Falar mensagens de" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Todos os ca_nais" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Todos os canais quando _qualquer janela do %s estiver ativa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Um canal _somente se sua janela está ativa" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Falar o nome da sala de bate-papo" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Habilita o modo leiaute para conteúdo" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "clique duplo" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "clique triplo" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizador padrão" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Texto real" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Texto substitutivo" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Habilitar eco por _caractere" - -# Acredito que qualquer brasileiro vai entender "teclas mortas" melhor que -# "teclas diacríticas não espaçadoras"! -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Habilitar teclas _mortas" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Localização at_ual" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Comprimento mínimo do texto correspondente:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opções de pesquisa" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Falar _somente as linhas modificadas durante a busca" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Falar resultados enquanto _localiza" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Comando" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Atalho" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Padrão" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Modo aprendizado" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Ações" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Associações Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Marcadores" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Hora e data" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Revisão por mouse" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Navegação de objetos" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Detalhes do objeto" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Sem atalho" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Revisão plana" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Fala e verbosidade" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Conteúdo da revisão plana" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificado" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "Computa_dor de mesa" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Notificações" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Recebido" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Apresentador de notificação" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferências do Cthulhu para %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Marcar em Braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Exceto" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Fale" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Salvar perfil como conflito" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflito em perfil de usuário!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"O perfil %s já existe.\n" -"Continuar atualizando o perfil existente com estas novas alterações?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Carregar perfil de usuário" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Você está prestes a alterar o perfil atual. Se você\n" -"acabou de fazer alterações em suas preferências, elas serão\n" -"descartadas ao carregar o perfil.\n" -"\n" -"Continuar carregando perfil descartando alterações anteriores?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Salvar perfil como" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nome do _perfil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Remover perfil de usuário" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Você está prestes a remover o perfil %s. Todas as configurações e " -"configurações não salvas neste perfil serão perdidas. Deseja continuar e " -"remover este perfil e todas as configurações relacionadas?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Todas" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicativo" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Janela" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Nenhum" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Algu_m" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Mai_oria" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Linha" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Sentença" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Citação" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Botão" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Legenda" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Caixa de seleção" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Objeto clicável" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Caixa de combinação" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descrição" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Título" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Quadro interno" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imagem" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Rótulo" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Marco" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nível" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Link" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Item de lista" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objeto" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Parágrafo" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Botão de opção" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Regra" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Item selecionado" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Estado" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Texto" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valor" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Citações" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Botões" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Caixas de seleção" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Objetos clicáveis" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Caixas de combinação" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Entradas" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Campos do formulário" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Títulos" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Quadros internos" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imagens" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Títulos de nível %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Marcos" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Blocos" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Links" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listas" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Itens de Lista" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Parágrafos" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Botões de opção" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabelas" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Links não visitados" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Links visitados" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navegação da página" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Iniciar automaticamente a _ler a página quando ela for carregada pela " -"primeira vez" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"_Apresenta o resumo de uma página quando ela é carregada pela primeira vez" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "_Quebrar a fala em pedaços separados por pausas" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Voz padrão %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Padrão" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Link" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Maiúscula" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Verificação ortográfica" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Soletrar _erro" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Soletrar _sugestão" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Apresentar _contexto do erro" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Ler as coordenadas de célula da planilha" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Sempre ler o intervalo da planilha selecionada" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Anunciar _cabeçalho da célula" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navegação da tabela" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Pular _células em branco" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Ler _célula" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Ler as coordenadas da _célula" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Ler _número de células mescladas" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Nome do atributo" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Usar navegação por cursor" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Habilitar navegação _estrutural" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Tema de som:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Tema de som" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Cur_to" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d notificação" -msgstr[1] "%d notificações" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "shift da esquerda" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt da esquerda" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control da esquerda" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "shift da direita" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt da direita" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control da direita" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "tecla windows da esquerda" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "tecla windows da direita" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab da esquerda" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "enter" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "cima" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "baixo" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "esquerda" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "direita" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super esquerdo" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super direito" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ajuda" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "alterar modo" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "ESC" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circunflexo" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "círculo" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "cortado" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "menos" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_Direito" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_Esquerdo" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s negrito" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s itálico" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s negrito itálico" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s script" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s script negrito" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s gótico" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s com traço duplo" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s negrito gótico" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s sans-serif" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s sans-serif negrito" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s sans-serif itálico" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s sans-serif negrito itálico" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s monoespaçado" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s sem ponto" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "seta para esquerda" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "seta para cima" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "seta para direita" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "seta para baixo" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "seta para esquerda e direita" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "seta para cima e baixo" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "seta para noroeste" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "seta para nordeste" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "seta para sudeste" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "seta para esquerda da barra" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "seta para cima da barra" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "seta para direita da barra" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "seta para cima da barra" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "seta dupla para esquerda" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "seta dupla para cima" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "seta dupla para direita" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "seta dupla para baixo" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "seta dupla para esquerda e direita" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "seta dupla para cima e baixo" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "seta dupla para noroeste" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "seta dupla para nordeste" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "seta dupla para sudeste" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "seta dupla para sudoeste" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "seta apontando para direita" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "ponta de seta apontando para direita" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "menos" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "menor que" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "maior que" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circunflexo" - -# caron (ganchinho) -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "caron" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "ponto" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "linha vertical dupla" - -# reticências -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "reticências" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "para todo" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complemento" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "derivada parcial" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "existe" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "não existe" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "conjunto vazio" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "incremento" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "pertence" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "não pertence" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "não pertence pequeno" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "contém como um membro" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "não contém como um membro" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "contém como um membro pequeno" - -# "end of proof" está relacionado com o termo em latim QED (quod erat demonstrandum), com versão em português CQD (como se queria demonstrar) -- Rafael -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "fim de prova" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produto" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coproduto" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "soma" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "menos ou mais" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "ponto mais" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "barra de divisão" - -# Traduções literais "define" e "menos" não parecem fazer sentido nesta string -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "diferença de conjunto" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operador asterisco" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operador anel" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operador ponto grande" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "raiz quadrada" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "raiz cúbica" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "raiz quarta" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcional a" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinito" - -# ângulo reto -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "ângulo reto" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "ângulo" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "ângulo medido" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "ângulo esférico" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "divide" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "não divisível" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paralelo a" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "não paralelo a" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "e lógico" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "ou lógico" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "interseção" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "união" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integral dupla" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integral tripla" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integral de contorno" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integral de superfície" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integral de volume" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral horária" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integral de contorno horária" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integral de contorno anti-horária" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "portanto" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "porque" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "razão" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporção" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "ponto menos" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "excesso" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporção geométrica" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotético" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "til" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "til invertido" - -# operador que indica negação lógica -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "negação lógica" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "onda senoide" - -# produto coroa / produto orlado / produto anel / produto wreath -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "produto coroa" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "não til" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "menos til" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "assintomaticamente igual a" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "não assintomaticamente igual a" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "aproximadamente igual a" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "aproximadamente, mas não exatamente igual a" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "nem aproximadamente nem exatamente igual a" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "quase igual a" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "não quase igual a" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "quase igual ou igual a" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "til triplo" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "tudo igual a" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "equivalente a" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometricamente equivalente a" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "diferença entre" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "aproxima do limite" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometricamente igual a" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "aproximadamente igual a ou a imagem de" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "imagem de ou aproximadamente igual a" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dois pontos igual" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "igual dois pontos" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "anel em igual a" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "anel igual a" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "corresponde a" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estima" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "equiangular a" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "estrela igual" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta igual a" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "igual a por definição" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "medido por" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "interrogação igual a" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "diferente" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "idêntico a" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "não idêntico a" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "estritamente equivalente a" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "menor que ou igual a" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "maior que ou igual a" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "menor que sobre igual a" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "maior que sobre igual a" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "menor que mas não igual a" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "maior que, mas não igual a" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "muito menor que" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "muito maior que" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "entre" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "não equivalente a" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "não menor que" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "não maior que" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "nem menor que nem igual a" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "nem maior que nem igual a" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "menor que ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "maior que ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "nem menor que nem equivalente a" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "nem maior que nem equivalente a" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "menor que ou maior que" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "maior que ou menor que" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "nem menor que nem maior que" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "nem maior que nem menor que" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "precede" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "sucede" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "precede ou igual a" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "sucede ou igual a" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "precede ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "sucede ou equivalente a" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "não precede" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "não sucede" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "subconjunto de" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superconjunto de" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "não um subconjunto de" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "não um superconjunto de" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "subconjunto de ou igual a" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superconjunto de ou igual a" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "nem um subconjunto de nem igual a" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "nem um superconjunto de nem igual a" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "subconjunto de com não igual a" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superconjunto de com não igual a" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiconjunto" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiplicação multiconjunto" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "união multiconjunto" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "imagem quadrada de" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "quadrado original de" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "imagem quadrada de ou igual a" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "quadrado original de ou igual a" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "quadrado boca embaixo" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "quadrado boca em cima" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "mais circulado" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "menos circulado" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "vezes circulado" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "barra de divisão circulada" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "operador ponto circulado" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operador anel circulado" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operador asterisco circulado" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "igual circulado" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "hífen circulado" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "mais no quadrado" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "menos no quadrado" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "vezes no quadrado" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operador de ponto no quadrado" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "tacha direita" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "tacha esquerda" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "tacha baixo" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "tacha cima" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "asserção" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modelos" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "verdadeiro" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "força" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "tacha direita barra vertical tripla" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "tacha direita barra vertical dupla" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "não prova" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "não verdadeiro" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "não força" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "tacha direita dupla barra vertical dupla negada" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "precede sob relação" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "sucede sob relação" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normal subgrupo de" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "contém como normal subgrupo" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normal subgrupo de ou igual a" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "contém como normal subgrupo de ou igual a" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original de" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "imagem de" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matriz conjugada hermitiana" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalar" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "ou exclusivo" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "não e" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nem" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ângulo direito com arco" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triângulo direito" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operador diamante" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operador ponto" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operador estrela" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "sucessivas divisões" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "gravata de borboleta" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "produto semidireto fator normal esquerdo" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "produto semidireto fator normal direito" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "produto semidireto esquerdo" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "produto semidireto direito" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "igual til reverso" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "ou lógico ondulado" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "e lógico ondulado" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "subconjunto duplo" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "superconjunto duplo" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "interseção dupla" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "união dupla" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "tridente inverso" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "igual e paralelo a" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "menor que com ponto" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "maior que com ponto" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "muito menor que" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "muito maior que" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "menor do que igual a ou maior que" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "maior que igual a ou menor que" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "igual a ou menor que" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "igual a ou maior que" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "igual a ou precede" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "igual a ou sucede" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "não precede ou igual" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "não sucede ou igual" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "não imagem quadrada de ou igual a" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "não original quadrado de ou igual a" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "imagem quadrada de ou não igual a" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "original quadrado de ou não igual a" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "menor ou igual, mas não equivalente a" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "maior ou igual que, mas não equivalente a" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "precede, mas não equivalente a" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "sucede, mas não equivalente a" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "não normal subgrupo de" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "não contém como normal subgrupo" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "não normal subgrupo de ou igual a" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "não contém como normal subgrupo ou igual" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "elipse vertical" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "elipse horizontal a meia linha" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "elipse diagonal direita superior" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "elipse diagonal direita inferior" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "pertence com cortado horizontal longo" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "pertence com barra vertical ao final do cortado horizontal longo" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "pertence pequeno com barra vertical ao final do cortado horizontal" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "elemento de com ponto acima" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "pertence com barra em cima" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "pertence pequeno com barra em cima" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "pertence com barra em baixo" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "pertence com dois cortados horizontais" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "contém com cortado horizontal longo" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "contém com barra vertical ao fim do cortado horizontal" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "contém pequeno com barra vertical ao fim do cortado horizontal" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "contém com barra em cima" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "contém pequeno com barra em cima" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "notação z, membro de bolsa" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "teto esquerdo" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "teto direito" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "piso esquerdo" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "piso direito" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "chave para cima" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "chave para baixo" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "colchete angular esquerdo" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "colchete angular direito" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "ponto circulado" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "união com ponto" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "união com mais" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "interseção quadrada" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "união quadrada" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "quadrado negro" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "quadrado branco" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "losango negro" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "círculo branco" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "círculo negro" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bolinha branca" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "quadradinho médio negro" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s com sublinhado" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s com barra" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s com linha vertical" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplicativo" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "em branco" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "negrito" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "marcador salvo" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "marcadores salvos" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "não foi possível salvar os marcadores" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nenhum marcador localizado." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Marcador não localizado." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Modo de repasse habilitado." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Não foi possível obter a tela da calculadora" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ícone" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Estilo de letras maiúsculas definido para ícone." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "nenhum" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Estilo de letras maiúsculas definido para nenhum." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "soletrar" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Estilo de letras maiúsculas definido para soletrar." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "O aplicativo está controlando o cursor." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "O Cthulhu está controlando o cursor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Célula %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s selecionada" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s até %s selecionadas" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s até %s desmarcadas" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s desmarcada" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Evita o uso de opção" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Força o uso de opção" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPÇÃO" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Argumentos opcionais" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Uso: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Os seguintes itens não são válidos: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Exibe os aplicativos em execução conhecidos" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Carregar perfil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Não foi possível carregar o perfil: %s" - -# O termo correto seria "ambiente gráfico de área de trabalho", porém a fins de resumo, usa-se a foma abreviada: ambiente gráfico. -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Não é possível iniciar o Cthulhu porque não consegue conectar-se à área de " -"trabalho.Não foi possível iniciar o leitor de tela porque ele não pode " -"conectar-se ao ambiente gráfico." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Não foi possível ativar o gerenciador de configurações. Saindo." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Já existe outro processo de leitor de tela em execução para esta sessão.\n" -"Execute “cthulhu --replace” para substituir este processo por um novo." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NOME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Usa um diretório alternativo para as configurações do usuário" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versão deste aplicativo" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Substituir uma instância do Cthulhu atualmente em execução" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Mostra essa mensagem de ajuda e sai" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Envia informações de depuração para debug-AAAA-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Envia informações de depuração para o arquivo especificado" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ARQUIVO" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Configura as preferências do usuário (versão texto)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Configura as preferências do usuário (versão em interface gráfica)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Relate erros para https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Corta seleção para a área de transferência." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "recorte" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Seleção copiada para a área de transferência." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copiado" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Conteúdo colado da área de transferência." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "colado" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Não anunciar quando nossos amigos estão teclando." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anunciar quando nossos amigos estão teclando." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Mensagem da sala de bate-papo %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nova aba de bate-papo %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Não falar o nome da sala de bate-papo." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "falar o nome da sala de bate-papo." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" -"Não fornecer históricos de mensagens específicos para cada sala de bate-papo." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" -"Fornecer históricos de mensagens específicos para cada sala de bate-papo." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "começo da exclusão" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "fim da exclusão" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "começo da inserção" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "fim da inserção" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "começo do realce" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "fim do realce" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "fim da sugestão" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Fim do contêiner." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Não em um contêiner." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "todos itens selecionados" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Botão padrão é %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "O botão padrão é %s. cinzentado" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Botão padrão não encontrado" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " subscrito %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " sobrescrito %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Não está em uma caixa de diálogo" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "documento todo selecionado" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "documento inteiro desmarcado" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "documento selecionado a partir da posição do cursor" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "documento desmarcado a partir da posição do cursor" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "documento selecionado até a posição do cursor" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "documento desmarcado até a posição do cursor" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Cabeçalho de coluna dinâmica definido para linha %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Cabeçalho de coluna dinâmica limpo." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Cabeçalho de linha dinâmica definido pra coluna %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Cabeçalho de linha dinâmica limpo." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "vazio" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabytes" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Nenhum arquivo localizado." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Conteúdo acrescentado à área de transferência." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Conteúdo copiado para a área de transferência." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Não está usando revisão plana." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Entrando na revisão plana." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Deixando revisão plana." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Revisão plana restrita ao objeto atual" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Revisão plana irrestrita" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "tem fórmula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "abre diálogo" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "abre grade" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "abre caixa de listagem" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "abre menu" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "abre árvore" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "link de mapa de imagens" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "A tecla digitada já está associada a %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tecla capturada: %s. Pressione Enter para confirmar." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "A nova tecla é: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Atalho excluído. Pressione Enter para confirmar." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "O atalho foi removido." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "digite a nova tecla" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tecla" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Eco definido para tecla." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nenhum" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Eco definido para nenhum." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tecla e palavra" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Eco definido para tecla e palavra." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "sentença" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Eco definido para sentença." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "palavra" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Eco definido para palavra." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "palavra e sentença" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Eco definido para palavra e sentença." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Delimitado por: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "um símbolo atuarial" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "uma caixa" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "um círculo" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "uma divisão com barra comprida" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "um radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "uma caixa arredondada" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "um risco horizontal" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "um risco vertical" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "um risco na diagonal ímpar" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "um risco na diagonal par" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "uma seta para o nordeste" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "uma linha no chão" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "uma linha na esquerda" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "uma linha na direita" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "uma linha no topo" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "um ângulo" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "um símbolo fatorial arábico" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "e" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "começo da fração" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "começo de fração sem barra" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "sobre" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "fim da fração" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "raiz quadrada de" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "raiz cúbica de" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "raiz de" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "começo da raiz" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "fim da raiz" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "subscrito" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "sobrescrito" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pré subscrito" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pré-sobrescrito" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "índice inferior" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "índice superior" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "fim da tabela" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "fim de tabela aninhada" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inacessível" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Desabilitado" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Desabilitada fala de recuo e justificação." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Habilitado" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Habilitada fala de recuo e justificação." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Modo de aprendizado. Pressione ESC para sair." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Entrando no modo de aprendizado. Pressione qualquer tecla para ouvir sua " -"função. Para ver a documentação do leitor de tela, pressione F1. Para obter " -"uma lista de atalhos padrão do leitor de tela, pressione F2. Para obter uma " -"lista de atalhos do leitor de tela para o aplicativo atual, pressione F3. " -"Para sair do modo de aprendizado, pressione a tecla ESC." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "deixando a citação." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "deixando os detalhes." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "deixando o feed." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "deixando a figura." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "deixando o formulário." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "deixando a faixa de página." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "deixando o conteúdo complementar." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "deixando as informações." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "deixando o conteúdo principal." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "deixando a navegação." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "deixando a região." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "deixando a pesquisa." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "deixando a lista." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "deixando o painel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "deixando a tabela." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "deixando a dica." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "deixando o resumo." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "deixando os agradecimentos." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "deixando o posfácio." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "deixando o apêndice." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "deixando a bibliografia." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "deixando o capítulo." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "deixando o colofão." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "deixando a conclusão." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "deixando o crédito." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "deixando os créditos." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "deixando a dedicação." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "deixando as notas finais." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "deixando a epígrafe." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "deixando o epílogo." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "deixando a errata." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "deixando o exemplo." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "deixando o preâmbulo." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "deixando o glossário." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "deixando o índice." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "deixando a introdução." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "deixando a lista de páginas." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "deixando a parte." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "deixando o prefácio." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "deixando o prólogo." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "deixando a citação." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "deixando P&R." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "deixando as sugestões." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "deixando a tabela de conteúdo." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "linha selecionada a partir da posição do cursor" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "linha selecionada até a posição do cursor" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "linha desmarcada a partir da posição do cursor" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "linha desmarcada até a posição do cursor" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Saindo do modo de aprendizado." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "linha selecionada do começo até a posição anterior do cursor" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "linha selecionada até o fim a partir da posição anterior do cursor" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "link" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "mesma página" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "mesmo site" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "site diferente" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "link %(uri)s para %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "link %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "visitado link %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "Use as setas cima e baixo para navegar na lista. Tecle ESC para sair." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Todas as regiões dinâmicas configuradas como desligadas" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "níveis de polidez de regiões dinâmicas restaurados" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nível de polidez %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "configurando região dinâmica como agressiva" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "configurando região dinâmica como desligada" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "configurando região dinâmica como educada" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "configurando região dinâmica como grosseira" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Monitoração de região dinâmica desligada" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Monitoração de região dinâmica ligada" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nenhuma mensagem dinâmica salva" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Suporte a região dinâmica está desligado" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Não localizado" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Não foi possível encontrar a localização atual." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "desligado" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "ligado" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "erro de ortografia" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Palavra incorreta: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Contexto é %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Modo de navegação" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Modo de foco" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Para habilitar o modo de foco, pressione %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Modo pegajoso de foco." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Modo pegajoso de navegação." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Modo leiaute." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Modo objeto." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Ponteiro movido para objeto." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Objeto sob o mouse não localizado." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Revisão do mouse desabilitada." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Revisão do mouse habilitada." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Erro: Não foi possível criar a lista de objetos." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Não há filhos." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Não há próximo." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Nenhum pai." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Nenhum anterior." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Navegação simplificada ativada." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Navegação simplificada desativada." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nível de aninhamento %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Novo item adicionado" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Nenhuma ação encontrada em: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Sem foco" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nenhum aplicativo possui foco." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Não há mais citações." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Não há mais botões." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Não há mais caixas de seleção." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Não há mais blocos." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Não há mais objetos clicáveis." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Não há mais caixas de combinação." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Não há mais entradas." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Não há mais campos de formulário." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Não há mais títulos." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Não há mais títulos de nível %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Não há mais quadros internos." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Não há mais imagens." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nenhum marco localizado." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Não há mais links." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Não há mais listas." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Não há mais itens da lista." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Não há mais regiões dinâmicas." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Não há mais parágrafos." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Não há mais botões de opção." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Não há mais separadores." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Não há mais tabelas." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Não há mais links não visitados." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Não há mais links visitados." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Nenhum texto selecionado." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Não é um link." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificação" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Baixo" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Topo" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Sem mensagens de notificação" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "dígitos" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Falar os números como dígitos." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "palavras" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Lê números como palavras." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "desligada" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ligada" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Carregando. Por favor aguarde." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Carregamento concluído." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Carregamento de %s concluído." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Página tem %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "página selecionada a partir da posição do cursor" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "página selecionada até a posição do cursor" - -# Não existe "desselecionar". Aceito sugestões. -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "página desmarcada a partir da posição do cursor" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "página desmarcada até a posição do cursor" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "parágrafo selecionado do cursor para baixo" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "parágrafo selecionado do cursor para cima" - -# Não existe "desselecionar". Aceito sugestões. -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "parágrafo desmarcado do cursor para baixo" - -# Não existe "desselecionar". Aceito sugestões. -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "parágrafo desmarcado do cursor para cima" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Você já tem uma instância do diálogo de preferências do Cthulhu aberto.\n" -"Por favor feche-o antes de abrir um novo." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "slide %(position)d de %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Perfil definido para %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nenhum perfil localizado." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Barra de progresso %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Tudo" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Nível de pontuação definido para tudo." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Maioria" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Nível de pontuação definido para maioria." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nenhum" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Nível de pontuação definido para nenhum." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Algum" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Nível de pontuação definido para algum." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Pesquisando." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Pesquisa completa." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Configurações do Cthulhu recarregadas." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Texto selecionado é: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Seleção apagada." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Indicador restaurada." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Texto não selecionado." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Tamanho: %d, %d. Local: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Largura: %d. Altura: %d. %d da esquerda. %d do topo." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Fala desabilitada." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Fala habilitada." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "mais rápido." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "mais devagar." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "maior." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "menor." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "mais alto." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "mais baixo." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Velocidade %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Tom %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volume %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Módulo do Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Voz do Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nenhum módulo Speech-dispatcher disponível" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nenhuma voz Speech-dispatcher disponível" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Configurações de voz salvas" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Não foi possível salvar as configurações de voz" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Nível de verbosidade: breve" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Nível de verbosidade: verboso" - -# " ponto ponto ponto" [o espaço no início é necessário] -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " ponto ponto ponto" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "O Cthulhu dá as boas-vindas." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu espreita sob as ondas." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Modo de suspensão ativado para %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Modo de suspensão desativado para %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Fala indisponível." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Não localizado" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Barra de status não localizada" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "trecho não localizado" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Navegação estrutural por teclas desabilitada." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Navegação estrutural por teclas habilitada." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Não localizado" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Linha %(row)d, coluna %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Fim da tabela" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Falar célula" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Falar linha" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Não-uniforme" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Não em uma tabela." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Colunas reordenadas" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Linhas reordenadas" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "coluna %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "coluna %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Fundo da coluna." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Topo da coluna." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Coluna %s selecionada" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Colunas %s até %s selecionadas" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Colunas %s até %s desmarcadas" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Coluna %s desmarcada" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "linha %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "linha %(index)d de %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Início da linha." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Fim da linha." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Linha apagada." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Última linha apagada." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Linha inserida." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Linha inserida ao fim da tabela." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Linha %s selecionada" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Linhas %s até %s selecionadas" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Linhas %s até %s desmarcadas" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Linha %s desmarcada" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "selecionado" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "desmarcado" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H horas, %M minutos e %S segundos" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H horas e %M minutos" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "desfazer" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "refazer" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versão %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "espaço em branco" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Saltando para o fim." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Voltando ao início." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 itens" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Célula ocupa %d linha" -msgstr[1] "Célula ocupa %d linhas" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d coluna" -msgstr[1] " %d colunas" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Célula ocupa %d coluna" -msgstr[1] "Célula ocupa %d colunas" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d caractere muito longo" -msgstr[1] "%d caracteres muito longos" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d diálogo)" -msgstr[1] "(%d diálogos)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d diálogo sem foco" -msgstr[1] "%d diálogos sem foco" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d bytes" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d arquivo localizado" -msgstr[1] "%d arquivos localizados" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulário" -msgstr[1] "%d formulários" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d título" -msgstr[1] "%d títulos" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d item" -msgstr[1] "%d itens" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d marco" -msgstr[1] "%d marcos" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d item localizado" -msgstr[1] "%d itens localizados" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Deixando %d citação." -msgstr[1] "Deixando %d citações." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Deixando %d lista." -msgstr[1] "Deixando %d listas." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Lista de tamanho desconhecido" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista com %d item" -msgstr[1] "Lista com %d itens" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Feed de tamanho desconhecido" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Feed com %d artigo" -msgstr[1] "Feed com %d artigos" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Lista de descrição com %d termo" -msgstr[1] "Lista de descrição com %d termos" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d valor" -msgstr[1] "%d valores" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabela matemática com %d linha" -msgstr[1] "tabela matemática com %d linhas" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d coluna" -msgstr[1] "%d colunas" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tabela matemática aninhada com %d linha" -msgstr[1] "tabela matemática aninhada com %d linhas" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d mensagem.\n" -msgstr[1] "%d mensagens.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d porcento." -msgstr[1] "%d porcento." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d porcento do documento lido" -msgstr[1] "%d porcento do documento lido" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixels" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d caractere %(repeatChar)s" -msgstr[1] "%(count)d caracteres %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d de %(total)d item selecionado" -msgstr[1] "%(index)d de %(total)d itens selecionados" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d atalho padrão do leitor de tela localizado." -msgstr[1] "%d atalhos padrões do leitor de tela localizados." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d atalho do leitor de tela para %(application)s localizado." -msgstr[1] "" -"%(count)d atalhos do leitor de tela para %(application)s localizados." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d espaço" -msgstr[1] "%d espaços" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tab" -msgstr[1] "%d tabs" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabela" -msgstr[1] "%d tabelas" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabela de tamanho desconhecido" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabela com %d coluna; contagem de linhas desconhecida" -msgstr[1] "tabela com %d colunas; contagem de linhas desconhecida" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabela com %d linhas; contagem de colunas desconhecida" -msgstr[1] "tabela com %d linhas; contagem de colunas desconhecida" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabela com %d linha" -msgstr[1] "tabela com %d linhas" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d segundo atrás" -msgstr[1] "%d segundos atrás" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minuto atrás" -msgstr[1] "%d minutos atrás" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d hora atrás" -msgstr[1] "%d horas atrás" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d dia atrás" -msgstr[1] "%d dias atrás" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d link não visitado" -msgstr[1] "%d links não visitados" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d link visitado" -msgstr[1] "%d links visitados" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "alternar" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "em %(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d de %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "item %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NÍVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nível de árvore %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NÍVEL DE ÁRVORE %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detalhes para %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "possui detalhes em %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "sugestão" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "caixa de combinação editável" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "conteúdo editável" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "feed" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figura" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "resumo" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "agradecimentos" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "posfácio" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "apêndice" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "entrada bibliográfica" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografia" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "capítulo" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colofão" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "conclusão" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "capa" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "crédito" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "créditos" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedicação" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "nota final" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "notas finais" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epígrafe" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epílogo" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "errata" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "exemplo" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "preâmbulo" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glossário" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "índice" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introdução" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "quebra de página" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "lista de páginas" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "parte" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "prefácio" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prólogo" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "citação" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "P&R" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "subtítulo" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "tabela de conteúdo" - -# título -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "t%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nível %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "barra de rolagem horizontal" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "barra de rolagem vertical" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "deslizador horizontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "deslizador vertical" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "separador horizontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "separador vertical" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "alternador" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Painel de ícone" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "faixa de página" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "conteúdo complementar" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informações" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "conteúdo principal" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navegação" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "região" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "pesquisa" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "link visitado" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "botão de menu" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "ordenado ascendente" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "ordenado descendente" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "ordenado" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "clicável" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "recolhido" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "expandido" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "possui descrição comprida" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "selecionada" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "não selecionada" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "ligado" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "desligado" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "parcialmente selecionada" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "pressionado" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "não pressionado" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "não selecionado" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "selecionado" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "não selecionado" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "não selecionada" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "visitado" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "não visitado" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "acinzentado" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "apenas leitura" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "apleit" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "obrigatório" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "seleção múltipla" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "entrada inválida" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "inválido" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ortografia inválida" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ortografia" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "gramática inválida" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramática" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Localizar" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Diálogo localizar do leitor de tela" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Fechar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Localizar" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Pesquisar por:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Pesquisar por:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Topo da janela" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Topo da janela" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Iniciar de:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Voltar ao início" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Pesquisar para _trás" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Direção da pesquisa:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Diferenciar maiúsculas de minúsculas" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Coincidir apenas com palavra _completa" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opções:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Padrão" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Maiúsculo" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlink" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistema" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicativo" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Janela" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferências do Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Ajuda" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "A_plicar" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Notebook" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Disposição do teclado" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Ativar _perfil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Perfil de inicialização:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Carregar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Salvar _como" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Remover" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Perfis" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Apresentar dicas" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Falar objeto sob o _mouse" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Mouse" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Forma_to de hora:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formato de dat_a:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Hora e data" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Falar atualizaçõe_s" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Atualizações em _Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frequência (segs):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplicar em:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Atualizações em bi_pes" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Falar as atualizações da barra de progresso" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Habilitar _retrocesso e avanço rápido em ler tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Habilitar navegação _estrutural em Ler tudo" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Ler tudo p_or:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Anunciar c_itações no Ler tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Anunciar li_stas no Ler tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Anunciar _tabelas no Ler tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Anunciar _painéis no Ler tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Anunciar _formulários no Ler tudo" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Anunciar _marcos no Ler tudo" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Ler tudo" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Apresentação do elemento:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Geral" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lume:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Ton_alidade:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "V_elocidade:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Personagem:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Idioma:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Sinteti_zador de fala:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Sistema de fala:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipo de _voz:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Estilo de letras maiús_culas:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Configurações de tipo de voz" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Falar _palavras com maiúsculas misturadas como palavras separadas" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Falar _números como dígitos" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Configurações gerais de voz" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voz" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Habilitar fala" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Detal_hado" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Verbosidade" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Tudo" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Nível de pontuação" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Falar somente o texto exibido" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Falar linhas em branco" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Falar recuo e just_ificação" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Falar m_nemônicos do objeto" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Falar p_osição filha" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Falar mensagens tutorial" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Detalhar mensagens de _sistema" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Fa_lar cores como nomes" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Anunciar c_itações durante a navegação" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Anunciar _listas durante a navegação" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Anunciar _tabelas durante a navegação" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Falar indicador de palavra com _erro de ortografia" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Anunciar _painéis durante a navegação" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Anunciar _marcos durante a navegação" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Anunciar _formulários durante a navegação" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Falar _descrição" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Falar linhas completas em _planilhas" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Falar linhas completas em tabelas de _documento" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Falar linhas completas em tabelas da interface _gráfica" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Contexto falado" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Fala" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Habilitar o _suporte a Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Nomes _abreviados de funções" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Desabilitar símbolo de _fim de linha" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Tabela de _abreviatura:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Habilitar Braille _abreviado" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Habilitar quebra por _palavra" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Configurações de exibição" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Nenhum" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicador de seleção" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicador de link" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Habilitar mensagens _flash" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "D_uração (segundos):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Mensagens persis_tentes" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Mensagens _detalhadas" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Configurações de mensagem flash" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Habilitar eco de _tecla" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Habilitar teclas _alfabéticas" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Habilitar teclas n_uméricas" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Habilitar teclas de _pontuação" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Habilitar e_spaço" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Habilitar teclas _modificadoras" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Habilitar teclas de _função" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Habilitar teclas de açã_o" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Habilitar teclas de _navegação" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Habilitar eco por _palavra" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Habilitar eco por _sentença" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Eco" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Tecla(s) _modificadora(s) do leitor de tela:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Atalhos" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Dicionário de pronúncia" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nova entrada" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "E_xcluir" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronúncia" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Falar _tudo" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Falar _nada" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Restaurar" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributos do texto" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mover para o _fim" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mover para _baixo" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mover para _cima" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mover para o _início" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Ajustar atributo selecionado" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicador Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributos do texto" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Ativar assistente de IA" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Provedor:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Local - Grátis)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Arquivo de chave _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Caminho para o arquivo de chave API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Obter chave API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Abrir navegador para obter a chave API Claude e salvar automaticamente" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Requer confirmação antes de ações de IA" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Modelo Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Nome do modelo para Ollama (ex. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Endpoint Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL do endpoint da API Ollama (ex. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Qualidade da captura de tela:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Baixo" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Médio" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Alto" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Assistente de IA" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Código de _idioma:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Fator de _escala:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Imagem em escala de _cinza" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Inverter imagem" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Imagem em _preto e branco" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Limiar preto/branco:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analisar cores" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Copiar resultados para a área de _transferência" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alfa, b : bravo, c : carlos, d : delta, e : eco, f : foxtrot, g : golf, " -"h : hotel, i : índia, j : julieta, k : kilo, l : lima, m : mike, n : " -"novembro, o : oscar, p : papa, q : quebec, r : romeo, s : serra, t : tango, " -"u : uniforme, v : victor, w : whiskey, x : xray, y : yankee, z : zulú" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "cor do plano de fundo" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "altura total do plano de fundo" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "pontilhado do plano de fundo" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direção" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editável" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nome da família" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "cor do primeiro plano" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "pontilhado do primeiro plano" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efeito da fonte" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "recuo" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "engano" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invisível" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "alinhamento" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "idioma" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "margem esquerda" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "altura da linha" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "estilo do parágrafo" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixels sobre as linhas" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixels sob as linhas" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixels entre linhas do parágrafo" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "margem direita" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "elevação" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "escala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "tamanho" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "alongamento" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "tachado" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "estilo" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decoração do texto" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotação do texto" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "sombra do texto" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "sublinha" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variação" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "alinhamento vertical" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "peso" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "quebra de texto" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "modo de escrita" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "verdadeiro" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falso" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "nenhum" - -# Baixo relevo também é "para cima", ver wikipédia. -# Falta uma tradução para "engrave"... -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "entalhe" - -# Alto relevo não é exatamente o mesmo que "relevo para cima" -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "relevo" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "contorno" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "sobrelinha" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "tachado" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "piscante" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "negra" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "simples" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dupla" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "baixa" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "caractere" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "palavra" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "palavra caractere" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "e-d" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "d-e" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "esquerda" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "direita" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centro" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "sem justificação" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "justificado" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensado" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensado" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensado" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensado" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi expandido" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "expandido" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra expandido" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra expandido" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "versalete" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblíquo" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "itálico" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Padrão" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Corpo de texto" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Título" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "linha de base" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sob" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "sobre" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "topo" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "topo do texto" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "meio" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "baixo" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "fundo do texto" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "herdar" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "ed-cb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "de-cb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "cb-de" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "cb-ed" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bc-de" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bc-ed" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "ed" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "de" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "cb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "sólido" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "ortografia" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Pressione espaço para alternar." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Pressione espaço para expandir, e seta para cima ou para baixo para " -"selecionar um item." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Pressione Alt+F6 para dar foco às janelas filhas." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Para mover-se entre os itens, use as teclas de setas, ou a pesquisa-enquanto-" -"digita." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Para acessar o menu do sistema pressione as teclas Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Use cima e baixo para selecionar um item." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Para recolher, pressione shift mais esquerda." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Para expandir, pressione shift mais direita." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Para ativar, pressione Enter." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Digite texto." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Use esquerda e direita para ver outras abas." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Para ativar, pressione espaço." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Use a seta para cima ou para baixo para selecionar o valor. Ou digite o " -"valor numérico desejado." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Use as teclas de seta para alterar." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Para navegar, pressione seta para a esquerda ou para a direita. Para mover-" -"se entre itens, pressione seta para cima ou para baixo." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Para entrar em um submenu, pressione a seta para direita." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Para diminuir, pressione a seta para a esquerda; para aumentar, pressione a " -"seta para a direita. Para o valor mínimo pressione Home, e para o máximo, " -"pressione End." diff --git a/po/ro.po b/po/ro.po deleted file mode 100644 index 92a04cb..0000000 --- a/po/ro.po +++ /dev/null @@ -1,9283 +0,0 @@ -# Cthulhu Romanian translation -# This file is distributed under the same license as the cthulhu package. -# Lucian Adrian Grijincu , 2009, 2010, 2011, 2016. -# Morie Daniel Alexandru , 2010. -# Jobava , 2015, 2016. -# Daniel Șerbănescu , 2018. -msgid "" -msgstr "" -"Project-Id-Version: gnome-cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-08 17:22+0300\n" -"Last-Translator: Florentina Mușat \n" -"Language-Team: Gnome Romanian Translation Team \n" -"Language: ro\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " -"20)) ? 1 : 2);\n" -"X-Generator: Poedit 3.3.2\n" -"X-Project-Style: gnome\n" -"X-Poedit-SourceCharset: UTF-8\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cititorul de ecran Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "ecran;cititor;accesibilitate;vorbire;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "atnț" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "sgt" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "etc" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "csbif" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "selcul" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "antetcol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "lstsel" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "pct" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "psl" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "cdrn" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "pdos" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "desen" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "selfiș" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "umpl" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "selfnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "formular" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gea" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "antet" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "cdrint" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etch" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "panstr" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "leg" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "elemlist" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "brmnu" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "elemmnu" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "panopt" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "lsttab" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pan" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "prl" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "mnuctx" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "barprg" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "elemmnrd" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "panrăd" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "antrnd" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "bardrl" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "pandrl" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sect" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "gls" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "pandsprțit" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "btncntr" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "barstare" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "elemmndtsbl" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "btncmt" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "barunlt" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "pont" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "arb" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tblarb" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "nec" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vizor" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "frst" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "antt" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "subsl" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "apl" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "baredit" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "încrp" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Cehă gradul 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spaniolă gradul 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Franceză canadiană gradul 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Franceză gradul 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letonă gradul 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Olandeză gradul 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norvegiană gradul 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norvegiană gradul 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norvegiană gradul 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norvegiană gradul 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Poloneză gradul 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugheză gradul 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Suedeză gradul 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabă gradul 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galeză gradul 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galeză gradul 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Germană gradul 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Germană gradul 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Germană gradul 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Engleză britanică gradul 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Engleză britanică gradul 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Engleză americană gradul 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Engleză americană gradul 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Franceză canadiană gradul 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Franceză gradul 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Greacă gradul 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi gradul 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Calculator maghiar cu 8 puncte" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Maghiară gradul 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Maghiară gradul 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italiană gradul 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Flamandă grad 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "spațiu" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "linie nouă" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "semnul exclamării" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "ghilimele" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "diez" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "și" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "paranteză deschisă" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "paranteză închisă" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "asterisc" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "virgulă" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "cratimă" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punct" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "linie oblică" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "două puncte" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "punct și virgulă" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "mai mic" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "egal" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "mai mare" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "semnul întrebării" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "a rond" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "paranteză pătrată deschisă" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "linie oblică inversă" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "paranteză pătrată închisă" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "accent circumflex" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "liniuță de subliniere" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "accent grav" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "acoladă deschisă" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "bară verticală" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "acoladă închisă" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tildă" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "spațiu de unire" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "semnul exclamării inversat" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "liră" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "simbol monetar" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "bară verticală întreruptă" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "secțiune" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "umlaut" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "drepturi de autor" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a ca exponent" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "ghilimele franceze deschise" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "negațit logică" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "cratimă" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "marcă înregistrată" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "grade" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus sau minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "2 ca exponent" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "3 ca exponent" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "ascuțit" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "miu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "marcaj paragraf" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "punct mijlociu" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "sedilă" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "1 la exponent" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "ghilimele franceze închise" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "o pătrime" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "o jumătate" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "trei pătrimi" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "semnul întrebării inversat" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a ascuțit" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A cu accent grav" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ascuțit" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A circumflex" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A tilda" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A cu umlaut" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A cu cerculeț" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A lipit de E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C cu sedilă" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E grav" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ascuțit" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E circumflex" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E cu umlaut" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I grav" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ascuțit" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I circumflex" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I cu umlaut" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "Eth" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N tilda" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O grav" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ascuțit" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O circumflex" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O tilda" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O cu umlaut" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "înmulțire" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O barat" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U grav" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ascuțit" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U circumflex" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U umlaut" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ascuțit" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "Thorn" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s ascuțit" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grav" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilda" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a cu umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a cu cerculeț" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ligatura a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cu sedila" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grav" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e ascuțit" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e cu umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grav" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i ascuțit" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i cu umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilda" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grav" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o ascuțit" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilda" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o cu umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "împărțit la" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o barat" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u ascuțit" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grav" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u cu umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y ascuțit" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y cu umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y cu umlaut" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "f cu cârlig" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "linie de dialog" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "ghilimele simple deschise" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "ghilimele simple închise" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "ghilimele simple deschise" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "ghilimele duble deschise" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "ghilimele duble închise" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "ghilimele duble deschise" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "pumnal" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "pumnal dublu" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "bulină" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "bulină triunghiulară" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "la mie" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prim" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "secund" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "triplu prim" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "bulină cratimă" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "marcă comercială" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "simbol bifare" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "simbol bifare îngroșat" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "bulină sub formă de x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "0 ca exponent" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "4 ca exponent" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "5 ca exponent" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "6 ca exponent" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "7 ca exponent" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "8 ca exponent" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "9 ca exponent" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "plus ca exponent" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "minus ca exponent" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "egal ca exponent" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "paranteză deschisă ca exponent" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "paranteză închisă ca exponent" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "n ca exponent" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "0 ca indice" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "1 ca indice" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "2 ca indice" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "3 ca indice" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "4 ca indice" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "5 ca indice" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "6 ca indice" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "7 ca indice" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "8 ca indice" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "9 ca indice" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "plus ca indice" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "minus ca indice" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "egal ca indice" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "paranteză deschisă ca indice" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "paranteză închisă ca indice" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "pătrat negru" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "diamant negru" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "caracter de înlocuire obiect" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Conduce cursorul la elementul curent" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Execută clic stânga pe elementul curent în prezentarea plată" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Execută clic dreapta pe elementul curent în prezentarea plată" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Pronunță întreg documentul" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Pronunță fereastra curentă folosind prezentarea plată" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Execută operația de bază Unde sunt" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Execută operația detaliată Unde sunt" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Pronunță selecția curentă" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Pronunță detaliile legăturii" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Prezintă butonul implicit" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Prezintă bara de stare" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Prezintă bara de titlu" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Deschide dialogul de căutare" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Afișează lista de acțiuni" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Caută instanța următoare a unui șir" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Caută instanța anterioară a unui șir" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Intră și ieși din modul de recenzie plat" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Comută prezentarea plată restrictivă la obiectul curent" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Mută prezentarea plată la poziția „acasă”" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Mută prezentarea plată la poziția „sfârșit”" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Mută prezentarea plată la începutul liniei precedente" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Pronunță linia curentă din prezentarea plată" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Citește literă cu literă linia curentă din prezentarea plată" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Citește fonetic, literă cu literă, linia curentă din prezentarea plată" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Mută prezentarea plată la începutul liniei următoare" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Mută prezentarea plată la elementul sau cuvântul anterior" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Pronunță elementul sau cuvântul curent din prezentarea plată" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" -"Citește literă cu literă elementul sau cuvântul curent din prezentarea plată" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Citește fonetic literă cu literă elementul sau cuvântul curent din " -"prezentarea plată" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Mută prezentarea plată la elementul sau cuvântul următor" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Mută prezentarea plată la cuvântul de deasupra celui curent" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Pronunță obiectul curent din prezentarea plată" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Mută prezentarea plată la cuvântul de sub cel curent" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Mută prezentarea plată la caracterul anterior" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Pronunță caracterul curent din prezentarea plată" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Pronunță fonetic caracterul curent din prezentarea plată" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Pronunță valoarea Unicode a caracterului curent din prezentarea plată" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Mută prezentarea plată la următorul caracter" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Mută prezentarea plată la sfârșitul liniei" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Mută prezentarea plată la bază în stânga" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Copiază conținutul din prezentarea plată pe clipboard" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Adaugă conținutul din prezentarea plată la clipboard" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Arată conținutul prezentării plate" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Comută între citirea celulei curente a tabelului sau a întreg rândului" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Citește atributele asociate caracterului curent din text" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Mută afișajul Braille la stânga" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Mută afișajul Braille la dreapta" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Întoarce obiectul pe care este focalizată tastatura" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Activează sau dezactivează modul Braille contractat" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Procesează o tastă de rutare a cursorului" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Marchează începutul unei selecții de text" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Marchează sfârșitul unei selecții de text" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Intră în modul de învățare. Apăsați ESC pentru a ieși din modul de învățare" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Micșorează viteza vorbirii" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Mărește viteza vorbirii" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Micșorează înălțimea sunetelor" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Mărește înălțimea sunetelor" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Mărește volumul vorbirii" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Micșorează volumul vorbirii" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Selectează setarea anterioară de vorbire" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Selectează setarea următoare de vorbire" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Micșorează setarea curentă de vorbire" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Mărește setarea curentă de vorbire" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Salvează setările de vorbire" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Comută activarea citirii" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Comută nivelul de verbozitate al vorbirii" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Comută modul de somn" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Iese din cititorul de ecran" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Afișează fereastra de configurație a preferințelor" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Afișează fereastra de configurație a preferințelor aplicației" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Comută pronunțarea indentării și alinierii" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Schimbă stilul de pronunțare al numerelor" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Comută către următorul nivel de pronunțare a punctuației" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Ciclează la următorul sintetizator de vorbire" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Comută către următorul profil de configurări" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Comută stilul de literă mare sau mică" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Comută către următorul nivel de ecou al tastelor" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Ciclează nivelul de depanare în timpul execuției" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Pune un semn de carte unde sunt cu privire la poziția curentă" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Navighează la locația semnului de carte precedent" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Du-te la semnul de carte" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Navighează la locația următorului semn de carte" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Agaugă semn de carte" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Salvează semnele de carte" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Comută modul de revizuire a mausului" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Prezintă timpul curent" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Prezintă data curentă" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Prezintă dimensiunea și locația documentului curent" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Trimite comanda următoare către aplicația curentă" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" -"Pronunță și afișează în Braille un mesaj anterior dintr-o cameră de chat" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Comută dacă anunțăm sau nu când contactele tastează" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Comută emiterea mesajelor de istorie din camere de discuție" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Comută prefixarea mesajelor din camere de discuții cu numele camerei de " -"discuție" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linia spre stânga" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linia spre dreapta" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linia în sus" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linia în jos" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Înghețare" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Stânga sus" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Stânga jos" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Poziție cursor" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Șase puncte" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Rutare cursor" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Început tăiere" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Taie linie" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Prezintă ultimul mesaj de notificare" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Prezintă lista mesajelor de notificare" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Prezintă mesajul de notificare anterior" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Prezintă următorul mesaj de înștiințare" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Navighează la caracterul următor" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Navighează la caracterul anterior" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Navighează la cuvântul următor" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Navighează la cuvântul anterior" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Navighează la linia următoare" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Navighează la linia anterioară" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Navighează la începutul fișierului" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Navighează la sfârșitul fișierului" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Navighează la începutul liniei" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Navighează la sfârșitul liniei" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Navighează la obiectul următor" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Navighează la obiectul anterior" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Cauzează expandarea listei de selecție curente" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Comută între modul de navigare nativ și cu cursor din cititorul de ecran" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Avansează configurările de politețe ale regiunii dinamice" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" -"Stabilește nivelul implicit de politețe al regiunii dinamice ca dezactivat" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Revizualizează anunțurile regiunii dinamice" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Monitorizează regiunile dinamice" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Mută focalizarea în și în afara obiectului de sub maus" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Stabilește un rând ce va fi folosit drept antet dinamic de coloană" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Curăță antetul dinamic de coloană" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Stabilește coloana ce va fi folosită drept antet dinamic de rând" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Curăță antetul dinamic de rând" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Prezintă conținutul liniei de intrare" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Comută tastele de navigare structurală" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Navighează la blocul de citare anterior" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Navighează la blocul de citare următor" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Afișează o listă de citate bloc" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Navighează la butonul anterior" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Navighează la butonul următor" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Afișează o listă de butoane" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Navighează la căsuța de bifare anterioară" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Navighează la căsuța de bifare următoare" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Afișează o listă de căsuțe de bifat" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Navighează la elementul clicabil anterior" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Navighează la elementul clicabil următor" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Afișează o listă de elemente clicabile" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Navighează la lista de selecție anterioară" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Navighează la lista de selecție următoare" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Navighează la începutul containerului" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Navighează la sfârșitul containerului" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Afișează o listă de liste de selecție" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Navighează la înregistrarea anterioară" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Navighează la înregistrarea următoare" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Afișează o listă de înregistrări" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Navighează la intrarea de formular anterioară" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Navighează la intrarea de formular următoare" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Afișează o listă de câmpuri de formular" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Navighează la antetul anterior" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Navighează la antetul următor" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Afișează o listă de antete" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Navighează la antetul anterior de nivel %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Navighează la antetul următor de nivel %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Afișează o listă de antete la nivelul %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Navighează la cadrul intern anterior" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Navighează la cadrul intern următor" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Afișează o listă de cadre interne" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Navighează la imaginea anterioară" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Navighează la linia următoare" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Afișează o listă de imagini" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Navighează la semnul de carte anterior" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Navighează la semnul de carte următor" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Afișează o listă de semne de carte" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Navighează la obiectul mare anterior" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Navighează la obiectul mare următor" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Afișează o listă de obiecte mari" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Navighează la legătura anterioară" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Navighează la legătura următoare" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Afișează o listă de legături" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Navighează la lista anterioară" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Navighează la lista următoare" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Afișează o listă de liste" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Navighează la elementul de listă anterior" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Navighează la elementul de listă următor" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Afișează o listă de elemente de listă" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Navighează la regiunea dinamică anterioară" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Navighează la regiunea dinamică următoare" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Navighează la ultima regiune dinamică care a făcut un anunț" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Navighează la superiorul obiectului cu focalizare de navigator." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" -"Navighează la primul inferior al obiectului cu focalizare de navigator." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" -"Navighează la fratele următor al obiectului cu focalizare de navigator." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" -"Navighează la fratele anterior al obiectului cu focalizare de navigator." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Clic pe obiectul cu focalizarea de navigator." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Comută navigarea obiectului simplificată." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Navighează la paragraful anterior" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Navighează la paragraful următor" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Afișează o listă de paragrafe" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Navighează la butonul radio anterior" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Navighează la butonul radio următor" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Afișează o listă de butoane radio" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Navighează la separatorul anterior" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Navighează la separatorul următor" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Navighează la tabelul anterior" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Navighează la tabelul următor" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Afișează o listă de tabele" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Navighează cu o celulă în jos" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Navighează la prima celulă din tabel" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Navighează la ultima celulă din tabel" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Navighează cu o celulă în stânga" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Navighează cu o celulă în dreapta" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Navighează cu o celulă în sus" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Comută modul de prezentare" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Comută între modul navigare și modul focalizare" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Activează modul de focalizare lipicios" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Activează modul de navigare lipicios" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Navighează la legătura nevizitată anterioară" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Navighează la legătura nevizitată următoare" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Afișează o listă de legături nevizitate" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Navighează la legătura vizitată anterioară" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Navighează la legătura vizitată următoare" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Afișează o listă de legături vizitate" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "albastru alice" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "alb antic" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "acvamarin" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azuriu" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "bej" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "negru" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "migdale decojite" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "albastru" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "albastru violet" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "maro" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "burlywood" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "albastru cadet" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "ciocolatiu" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "coral" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "albastru floare de porumb" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "mătase de porumb" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "purpuriu" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "bleu" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "albastru închis" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "bleu deschis" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "goldenrod închis" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "gri închis" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "verde închis" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "khaki închis" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "magenta închis" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "verde măsliniu închis" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "portocaliu închis" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "orhidee închis" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "roșu închis" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "somon închis" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "verde marin închis" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "ardezie albastru închis" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "ardezie gri închis" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "turcoaz închis" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "violet închis" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "roz profund" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "albastru cer profund" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "gri ton închis" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "albastru dodger" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "foc cărămiziu" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "alb floral" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "verde pădure" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "alb fantomă" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "auriu" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "auriu de splinuță" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "gri" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "verde" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "verde galben" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "mană" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "roz aprins" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "roșu indian" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "fildeș" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "levănțică" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "levănțică palidă" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "verde gazon" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "lămâie palidă" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "albastru deschis" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "coral deschis" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "bleu deschis" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "galben goldenrod deschis" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "gri deschis" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "verde deschis" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "roz deschis" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "somon deschis" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "verde marin deschis" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "albastru cer deschis" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "gri ardezie deschis" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "albastru oțel deschis" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "galben deschis" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limetă" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limetă verde" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "pânză de in" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "maro" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "acvamarin mediu" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "albastru mediu" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orhidee mediu" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "purpuriu mediu" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "verdemarin mediu" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "albastru ardezie mediu" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "verde primăvăratic mediu" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "turcoaz mediu" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "roșu violet mediu" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "albastru miezul nopții" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "cremă de mentă" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "rouă de trandafir" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mocasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "alb navajo" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "marin" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "dantelă veche" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "măsliniu" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "măsliniu cafeniu" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "portocaliu" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "roșu portocaliu" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orhidee" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "goldenrod palid" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "verde palid" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "turcoaz palid" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "roșu violet palid" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya whip" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "peach puff" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "roz" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "prună" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "albastru pudră" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purpuriu" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "roșu" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "maro trandafiriu" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "albastru regal" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "maro șa" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "somon" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "maro nisip" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "verde marin" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "scoică marină" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "argintiu" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "albastru cer" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "albastru ardezie" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "gri ardezie" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "zăpadă" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "verde primăvăratic" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "albastru oțel" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "bronz" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "verde azur" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "scaiete" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomată" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turcoaz" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violet" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "grâu" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "alb" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "fum alb" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "galben" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "galben verde" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Activează" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Mod de focalizare automată în timpul navigării structurale" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Mod de focalizare automat în timpul navigării cu cursor" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Mod de focalizare automată în timpul navigării native" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punctul _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punctul _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Punctele 7 ș_i 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Anulează" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "Navighează _la" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Ok" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Iconiță" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Nimic" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Ortografie" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "_Anunță când contactele scriu" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Emite _mesaje de istorie a camerei de discuție" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Pronunță mesajele de la" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Toate ca_nalele" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Toate canalele când orice f_ereastră %s este activă" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Un canal doar dacă _fereastra sa este activă" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "Pronunță numele unei camere de di_scuție" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Activează modul de prezentare pentru conținut" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dublu clic" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "triplu clic" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Sintetizator implicit" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Șirul de înlocuit" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Șirul înlocuitor" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Activează re_darea pe litere" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Activează tastele _diacritice ce nu introduc spații" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Locația c_urentă" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Lungimea minimă a textului potrivit:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opțiuni de căutare" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Pronunță doar liniile modificare în timpul căută_rii" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Pronunță rezultatele în _timpul câutării" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Comandă" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Asocieri de taste" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Implicit" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Mod de învățare" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Acțiuni" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Asocierile Braille" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Marcaje" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Data și ora" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Revizuire maus" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Navigare obiect" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Detalii obiect" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Neasociate" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Prezentare plată" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Vorbire și detaliere" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Conținut prezentare plată" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Modificat" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "Calculator _de birou" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Înștiințări" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Primit" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Prezentator de înștiințare" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferințe Cthulhu pentru %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Evidențiază în Braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Prezintă mai puțin pentru valorile" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Pronunță" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Salvează profilul ca conflict" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Conflict de profil de utilizator!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profilul %s există deja.\n" -"Continuați actualizarea profilului existent cu aceste noi modificări?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Încarcă profilul utilizatorului" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Sunteți pe cale de a schimba profilul activ. Dacă ați\n" -"modificat preferințele, modificările vor fi pierdute\n" -"la încărcarea profilului.\n" -"\n" -"Continuați încărcarea profilului pierzând modificările?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Salvează profilul ca" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Nume _profil:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Elimină profilul utilizatorului" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Sunteți pe cale de a elimina profilul „%s”. Toate configurările nesalvate și " -"cele salvate în acest profil vor fi pierdute. Continuați să eliminați acest " -"profil și configurările lui?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Toate" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplicație" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Fereastră" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Niciunul" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "U_nele" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Maj_oritatea" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Linie" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Propoziție" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Citat" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Buton" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Etichetă" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Căsuță de bifat" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Clicabil" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Listă de selecție" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Descriere" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Antet" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Cadru intern" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Imagine" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etichetă" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Semn de carte" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivel" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Legătură" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Listă" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Element listă" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Obiect" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragraf" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Buton radio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rol" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Element selectat" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stare" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Valoare" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Citate bloc" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Butoane" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Căsuțe de bifare" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Clicabile" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Liste de selecție" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Elemente" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Câmpuri de formular" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Antete" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Cadre interne" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Imagini" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Antete la nivelul %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Semne de carte" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Obiecte mari" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Legături" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Elemente listă" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragrafe" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Butoane radio" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabele" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Legături nevizitate" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Legături vizitate" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navigare pagină" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Pronunță pagina automat _la prima încărcare" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Prezintă un sumar al paginii la prima încărcare" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Împarte vocea în b_ucăți între pauze" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "vocea implicită %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Implicită" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiperlegătură" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Majuscule" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Dispecer voce" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Verificare ortografică" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "_Eroare ortografică" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "_Sugestie ortografică" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "_Contextul prezent al erorii" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Pronunță coordonatele celulelor foii de calcul" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Pronunță întotdeauna intervalul selectat din foaia de calcul" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Anunță _antetul celulei" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigare tabel" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Omite celulele _goale" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Pronunță _celula" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Pronunță coordonatele _celulei" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Pronunță întinderile celulelor _multiple" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Numele atributului" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Controlează navigarea cu cursor" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Activează navigarea _structurală" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Tema sonoră:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Tema sonoră" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Pe scu_rt" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d înștiințare" -msgstr[1] "%d înștiințări" -msgstr[2] "%d de înștiințări" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "shift stânga" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt stânga" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "control stânga" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "shift dreapta" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt dreapta" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "control dreapta" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta stânga" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta dreapta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "pagină mai sus" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "pagină mai jos" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab stânga" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "sus" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "jos" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "stânga" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "dreapta" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super stânga" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super dreapta" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "meniu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt dreapta" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ajutor" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "schimbare mod" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "cerculeț" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "bară" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s aldin" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s cursiv" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s aldin cursiv" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s indice" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s indice aldin" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s fraktur" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s dublu tăiat" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s aldin fraktur" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s sans-serif" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s fără serife" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s fără serife cursiv" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s fără serife aldin cursiv" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s monospațiat" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s fără punct" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "săgeată stânga" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "săgeată sus" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "săgeată dreapta" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "săgeată jos" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "săgeată stânga-dreapta" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "săgeată sus-jos" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "săgeată nord-vest" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "săgeată nord-est" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "săgeată sud-est" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "săgeată la stânga cu bară" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "săgeată sus cu bară" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "săgeată dreapta cu bară" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "săgeată jos cu bară" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "săgeată stânga dublă" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "săgeată sus dublă" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "săgeată dreapta dublă" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "săgeată jos dublă" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "săgeată stânga-dreapta dublă" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "săgeată sus-jos dublă" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "săgeată nord-vest dublă" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "săgeată nord-est dublă" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "săgeată sud-est dublă" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "săgeată sud-est dublă" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "săgeată spre dreapta" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "vârf de săgeată spre dreapta" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "mai mic" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "mai mare" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "brevă" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punct" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "linie verticală dublă" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "trei puncte orizontale" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "pentru tot" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "complement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "diferențială parțială" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "există" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "nu există" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "mulțimea vidă" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "increment" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "aparține" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "nu aparține" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "aparține mic" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "conține ca membru" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "nu conține ca membru" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "conține ca membru mic" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "sfârșitul demonstrației" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produs" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "coprodus" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "sumă" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "plus sau minus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "punct plus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "împărțire" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "minus pentru mulțimi" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "separator" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operator inel" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operator glonț" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "radical" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "radical de ordin 3" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "radical de ordin 4" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporțional cu" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "infinit" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "unghi dreapta" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "unghi" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "unghi măsurat" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "unghi sferic" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "divide" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "nu divide" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paralel cu" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "neparalel cu" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "și logic" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "sau logic" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "intersecție" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "uniune" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integrală" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "integrală dublă" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "integrală triplă" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "integrală contur" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integrală de suprafață" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integrală volum" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integrală orar" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "integrală de contur orar" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "integrală de contur antiorar" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "rezultă" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "deoarece" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "raport" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporție]" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "punct minus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "xces" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "proporție geometrică" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetic" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tildă" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "tildă inversă" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "s leneș inversat" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusoidă" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "produs în coroană" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "tildă negată" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "aproximativ" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "egal asimptotic cu" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "nu este egal asimptotic cu" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "aproximativ egal cu" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "aproximativa dar nu exact egal cu" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "nici aproximativ nici egal cu" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "aproape egal cu" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "nu aproape egal cu" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "aproape egal sau egal cu" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "triplu tildă" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "toate egal cu" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "echivalent cu" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "echivalent gemoetric cu" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "diferența dintre" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "se apropie limitei" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometric egal cu" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "aproximativ egal cu sau imaginea lui" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "imaginea lui sau aproximativ egal cu" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "două puncte egal" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "egal două puncte" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "inel în egal cu" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "inel egal cu" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "corespunde cu" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estimează" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "echiangular la" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "egal cu steluță" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta egal cu" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "egal cu prin definiție" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "măsurat în" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "egal cu semnul întrebării" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "neegal cu" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identic cu" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "neidentic cu" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "echivalent strict cu" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "mai mic sau egal cu" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "mai mare sau egal cu" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "mai mic sau egal cu" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "mai mare sau egal cu" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "mai mic dar nu egal cu" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "mai mare dar nu egal cu" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "mult mai puțin decât" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "mult mai mult decât" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "între" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "neechivalent cu" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "nu mai puțin decât" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "nu mai mare decât" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "nici mai mic decât nici egal cu" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "nici mai mare decât nici egal cu" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "mai mic decât sau echivalent cu" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "mai mare decât sau echivalent cu" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "nici mai mic decât nici echivalent cu" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "nici mai mare decât nici echivalent cu" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "mai mic decât sau mai mare decât" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "mai mare decât sau mai mic decât" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "nici mai mic decât nici mai mare decât" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "nici mai mare decât nici mai mic decât" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "precedă" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "succedă" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "precedă sau egal cu" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "succedă sau egal cu" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "precedă sau echivalent cu" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "succedă sau echivalent cu" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "nu precedă" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "nu succedă" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "submulțime a lui" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "supramulțime a lui" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "nu este o submulțime a lui" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "nu este o supramulțime a lui" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "submulțime sau egal cu" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "supramulțime sau egal cu" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "nici submulțime a lui nici egal cu" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "nici supramulțime a lui nici egal cu" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "submulțime a lui fără egalitate cu" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "supramulțime a lui fără egalitate cu" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multimulțime" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multiplicarea multimulțimii" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "uniunea multimulțimii" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "imaginea pătrată a lui" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "pătratul original al lui" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "imaginea pătrată a lui sau egal cu" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "pătratul original al lui sau egal cu" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "pălărie pătrată" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "cană pătrată" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "plus în cerc" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "minus în cerc" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "înmulțit în cerc" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "divizat în cerc" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "operator punct în cerc" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operator inel în cerc" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operator asterisc în cerc" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "egal în cerc" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "cratimă în cerc" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus în pătrat" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "minus în pătrat" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "înmulțit în pătrat" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operator punct în pătrat" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "tack drept" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "tack stâng" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "tack în jos" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "tack in sus" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "asserție" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modelează" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "adevărat" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "forțează" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "bară verticală tripă și turnichet dreapta" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "bară verticală dublă și dublu turnichet dreapta" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "nu demonstrează" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "neadevărat" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "nu forțează" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "bară verticală dublă negată și dublu turnichet dreapta" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "precedă sub relație" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "succedă sub relație" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "subgrup normal al lui" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "conține ca subgrup normal" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "subgrup al lui sau egal cu" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "conține ca subgrup al lui sau egal cu" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original de la" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "imaginea lui" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multihartă" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "matrice hermițiană conjugată" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "intercalat" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "sau exclusiv" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "și negat" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "sau negat" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "unghi drept cu arc" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "triunghi drept" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operator diamant" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operator punct" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operatorul stea" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "împărțit înmulțit" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "papion" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "product semidirect normal la stânga" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "product semidirect normal la dreapta" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "produs semidirect la stânga" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "produs semidirect la dreapta" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "tilda egal invers" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "sau logic italic" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "și logic italic" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "submulțime dublă" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "supramulțime dublă" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "intersecție dublă" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "uniune dublă" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "furcă" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "egal și paralel cu" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "mai mic sau egal decât cu punct" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "mai mare sau egal decât cu punct" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "cu mult mai mic decât de" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "cu mult mai mare de" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "mai mic sau egal decât sau mai mare decât" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "mai mare decât sau mai mic decât" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "egal cu sau mai puțin decât" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "egal cu sau mai mare decât" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "egal cu sau procedă" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "egal cu sau succedă" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "nu procedă sau egal" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "nu succedă sau egal" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "nu este imaginea pătrată a lui sau egal cu" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "nu este pătrat original al sau egal cu" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "imaginea pătrată a lui sau neegal cu" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "pătrat original al sau nu este egal cu" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "mai mic dar neechivalent cu" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "mai mare dar neechivalent cu" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "procedă dar nu este echivalent cu" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "succedă dar nu este echivalent" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "nu este subgrup normal al" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "nu conține ca subgrup normal" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "nu este subgrup normal al sau egal cu" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "nu conține ca subgrup normal sau egal" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "trei puncte verticale" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "trei puncte orizontale centrale" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "trei puncte diagonală dreapta sus" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "trei puncte diagonală dreapta jos" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "element cu tăietură lungă orizontală" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "element cu bară verticală la capătul tăieturii orizontale" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "element mic cu bară verticală la capătul tăieturii orizontale" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "element cu punct deasupra" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "element cu bară deasupra" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "element mic cu bară deasupra" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "element cu bară dedesubt" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "element cu două tăieturi orizontale" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "conținut cu tăietură lungă orizontală" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "conținut cu bară verticală la capătul tăieturii orizontale" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "conținut mic cu bară verticală la capătul tăieturii orizontale" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "conținut cu bară deasupra" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "conținut mic cu bară deasupra" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "membrul grămezii în notația z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "plafon stânga" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "plafon dreapta" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "podea stânga" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "podea dreapta" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "acoladă sus" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "acoladă jos" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "paranteză unghiulară stânga" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "paranteză unghiulară dreapta" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "cerc cu punct" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "reuniune cu punct" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "reuniune cu plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "intersecție pătrată" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "reuniune pătrată" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "pătrat negru" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "pătrat alb" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "romb negru" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "cerc alb" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "cerc negru" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "bulină albă" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "pătrat negru mediu mic" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s subliniat" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s tăiat oblic" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s cu linie verticală" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "aplicație" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "linie goală" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "aldin" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "semnul de carte a fost introdus" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "semnele de carte au fost salvate" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "semnele de carte nu au putut fi salvate" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nu există marcajele." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Nu există marcajul." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Modul de ocolire este activat." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Nu se poate obține afișajul calculatorului" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "iconiță" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Stilul de majusculă stabilit la iconiță." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "niciunul" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Stilul de majusculă stabilit la nimic." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "ortografie" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Stilul de majusculă stabilit la ortografie." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Aplicația controlează cursorul." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu controlează cursorul." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Celula %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s selectată" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s până la %s selectate" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s până la %s deselectate" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s deselectată" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Împiedică utilizarea opțiunii" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Forțează utilizarea opțiunii" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPȚIUNE" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Argumente opționale" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Utilizare: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Următoarele nu sunt valide: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Afișează aplicațiile cunoscute care sunt în execuție" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Încarcă profilul" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profilul nu a putut fi încărcat: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Nu se poate porni Cthulhu deoarece nu se poate conecta la desktop.Nu se " -"poate porni cititorul de ecran deoarece nu se poate conecta la sistemul " -"grafic." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Nu se poate activa gestionarul de configurări. Se iese." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Un alt proces de cititor de ecran rulează deja pentru această sesiune\n" -"Rulați „cthulhu --replace” pentru a înlocui acel proces cu unul nou." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NUME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Folosește un alt dosar pentru preferințele utilizatorului" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Versiunea acestei aplicații" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Înlocuiește o instanță Cthulhu aflată în execuție" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Afișează acest mesaj de ajutor și iese" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Trimite ieșirea de depanare către debug-AAAA-LL-ZZ-OO:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Trimite ieșirea de depanare fișierului specificat" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FIȘIER" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Configurare preferințe utilizator (în mod text)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Configurare preferințe utilizator (mod grafic)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Raportați defectele la https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Taie selecția în clipboard." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "taie" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "S-a copiat selecția în clipboard." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "copiat" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Conținut lipit din clipboard." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "lipit" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Nu anunța când contactele tastează." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "anunță când contactele tastează." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Mesaj din camera de discuție %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Tab de discuție nou %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Nu pronunța numele camerei de discuție." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "pronunță numele camerei de discuție." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Nu emite _mesaje de istorie a camerelor de discuție." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Emite mesaje de istorie a camerelor de discuție." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "începutul ștergerii" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "sfârșitul ștergerii" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "începutul inserției" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "sfârșitul inserției" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "începutul evidențierii" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "sfârșitul evidențierii" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "sfârșitul sugestiei" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Sfârși de container." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Nu într-un container." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "toate elementele selectate" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Butonul implicit este %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Butonul implicit este %s. Este gri" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Nu s-a găsit butonul implicit" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " %s ca indice" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " %s ca exponent" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Nu într-un dialog" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "întreg documentul selectat" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "întregul document selectat" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "document selectat de la poziția curentă a cursorului" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "document deselectat de la poziția curentă a cursorului" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "document selectat până la poziția curentă a cursorului" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "document deselectat până la poziția curentă a cursorului" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Antetul dinamic de coloană este rândul %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Antetul dinamic de coloană a fost curățat." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Antetul dinamic de rând este coloana %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Antetul dinamic de rând a fost curățat." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "gol" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kiloocteți" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megaocteți" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Nici un fișier găsit." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Conținut atașat în clipboard." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Conținut copiat în clipboard." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Nu se utilizează prezentarea plată." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Se intră în prezentarea plată." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Se părăsește prezentarea plată." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Prezentarea plată restricționată la obiectul curent" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Prezentarea plată nerestricționată" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "are formula" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "deschide dialogul" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "deschide grila" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "deschide lista" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "deschide meniul" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "deschide arborele" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "legătură de pe o imagine-hartă" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Tasta introdusă este deja asociată pentru %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tastă capturată: %s. Pentru a confirma apăsați enter." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Noua tastă este: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Asocierea de taste a fost ștearsă. Pentru a confirma apăsați enter." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Asocierea de taste a fost eliminată." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "introduceți o nouă tastă" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tastă" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Echo stabilit la cheie." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nimic" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Echo stabilit la Nimic." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tastă și cuvânt" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Echo stabilit la cheie și cuvânt." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "propoziție" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Echo stabilit la propoziție." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "cuvânt" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Echo stabilit la cuvânt." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "cuvânt și propoziție" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Echo stabilit la cuvânt și propoziție." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Capsulat de: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "un simbol acturial" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "o cutie" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "un cerc" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "un semn lung de divizor" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "un radical" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "o cutie rotunjită" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "o tăiere orizontală" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "o tăiere verticală" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "o tăietură diagonală de sus în jos" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "o tăietură diagonală de jos în sus" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "o săgeată spre nord-vest" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "o linie la bază" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "o linie la stânga" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "o linie la dreapta" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "o linie deasupra" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "un unghi de fazor" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "un simbol factorial arab" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "și" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "început de fracție" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "început de fracție fără bară" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "deasupra" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "sfârșit de fracție" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "rădăcină pătrată din" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "rădăcină cubică din" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "pătratul lui" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "început pătrat" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "sfârșit pătrat" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "indice" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "exponent" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pre-indice" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pre-exponent" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "subindice" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "supraexponent" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "sfârșit tabel" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "sfârșitul tabelului encapsulat" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "inaccesibil" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Dezactivată" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Pronunțarea indentarii și alinierii este dezactivată." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Activată" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Pronunțarea indentării și alinierii este activată." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Modul de învățare. Apăsați escape pentru a ieși." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Se inițiază modul de învățare. Apăsați orice tastă pentru a auzi funcție " -"ei. Pentru a deschide documentația cititorului de ecran, apăsați F1. Pentru " -"a obține lista cu scurtăturile de tastatură implicite, apăsați F2. Pentru a " -"obține lista scurtăturilor cititorului de ecran pentru aplicația curentă, " -"apăsați F3. Pentru a ieși din modul de învățare, apăsați tasta Escape." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "se părăsește citatul." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "se părăsesc detaliile." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "se părăsește fluxul." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "se părăsește figura." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "se părăsește formularul." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "se părăsește bannerul." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "se părăsește conținutul complimentar." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "se părăsește informația." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "se părăsește conținutul principal." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "se părăsește navigația." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "se părăsește regiunea." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "se părăsește căutarea." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "se părăsește lista." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "se părăsește panoul." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "se părăsește tabelul." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "se părăsește indiciul." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "se părăsește abstractul." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "se părăsesc recunoștiințele." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "se părăsește cuvântul de concluzie." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "se părăsește apendicele." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "se părăsește bibliografia." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "se părăsește capitolul." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "se părăsește colofonul." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "se părăsește concluzia." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "se părăsește creditul." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "se părăsesc creditele." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "se părăsește dedicația." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "se părăsesc notele de final." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "se părăsește epigraful." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "se părăsește epilogul." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "se părăsește revizia." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "se părăsește exemplul." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "se părăsește cuvântul înainte." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "se părăsește glosarul." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "se părăsește indexul." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "se părăsește introducerea." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "se părăsește lista paginilor." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "se părăsește partea." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "se părăsește prefața." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "se părăsește prologul." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "se părăsește citatul." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "se părăsește QNA." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "se părăsește sugestia." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "se părăsește cuprinsul." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "linie selectată sub poziția curentă a cursorului" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "linie selectată deasupra poziției curentă a cursorului" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "linie deselectată sub poziția curentă a cursorului" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "linie deselectată deasupra poziției curentă a cursorului" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Se iese din modul de învățare." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "linie selectată de la început până la poziția anterioară a cursorului" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "linie selectată de la poziția anterioară a cursorului până la sfârșit" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "legătură" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "aceeași pagină" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "același site" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "site diferit" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s legătură la %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "legătura %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "legătură vizitată %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Folosiți Săgețile Sus și Jos pentru navigarea listei. Apăsați Escape pentru " -"a ieși." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Toate regiunile dinamice au fost configurate ca oprite" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "nivelul de politețe al regiunilor dinamice a fost restaurat" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nivelul de politețe %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "configurează regiunea dinamică ca impunătoare" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "configurează regiunea dinamică ca oprită" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "configurează regiunea dinamică ca politicoasă" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "configurează regiunea dinamică ca nepoliticoasă" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Suportul pentru monitorizarea regiunilor dinamice este dezactivat" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Suportul pentru regiuni dinamice este activat" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nici un mesaj din regiunea dinamică nu a fost salvat" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Suportul pentru regiuni dinamice este dezactivat" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nu a fost găsit" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Nu s-a putut găsi locația curentă." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "dezactivat" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "activat" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "ortografiat greșit" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Cuvânt ortografiat greșit: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Contextul este %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Mod navigare" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Modul focus" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Pentru a activa modul focus apăsați %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Modul focus este lipicios." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Modul navigare este lipicios." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Mod de prezentare." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Modul obiect." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Indicator mutat la obiect." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Obiectul de sub maus nu a fost găsit." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Revizuirea mausului dezactivată." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Revizuirea mausului activată." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Eroare: Nu s-a putut crea lista de obiecte." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Nu există inferiori." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Nu există următorul." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Nu există superior." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Nu există anteriorul." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Navigarea simplificată activată." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Navigarea simplificată dezactivată." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nivel de imbricare %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Noul element a fost adăugat" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Nu s-au găsit acțiuni pe: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Nimic nu este focalizat" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nici o aplicație nu este focalizată." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Nu mai sunt blocuri de citare." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Nu mai există butoane." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Nu mai există căsuțe de bifare." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Nu mai există obiecte mari." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Nu mai sunt elemente clicabile." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Nu mai există liste de selecție." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Nu mai există înregistrări." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Nu mai există intrări de formular." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Nu mai există antete." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Nu mai există antete de nivel %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Nu mai există cadre interne." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Nu mai sunt imagini." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nu mai există semne de carte." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Nu mai sunt legături." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Nu mai există liste." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Nu mai există elemente în listă." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Nu mai există regiuni dinamice." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Nu mai există paragrafe." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Nu mai există butoane radio." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Nu mai există separatori." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Nu mai există tabele." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Nu mai există legături nevizitate." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Nu mai există legături vizitate." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Niciun text selectat." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nu este o legătură." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Notificare" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Final" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Început" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Niciun mesaj de notificare" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "cifre" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Pronunță numerele ca cifre." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "cuvinte" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Pronunță numerele ca cuvinte." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "dezactivat" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "activat" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Pagina se încarcă. Așteptați." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Pagina s-a încărcat." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Pagina se încarcă %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Pagina are %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "pagină selectată de la poziția curentă a cursorului" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "pagină selectată până la poziția curentă a cursorului" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "pagină deselectată de la poziția curentă a cursorului" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "pagină deselectată până la poziția curentă a cursorului" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "paragraf selectat mai jos de la poziția cursorului" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "paragraf selectat mai sus de la poziția cursorului" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "paragraf deselectat mai jos de la poziția cursorului" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "paragraf deselectat mai sus de la poziția cursorului" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Există deja o instanță deschisă a ferestrei de configurare a preferințelor " -"Cthulhu.\n" -"\n" -"Închideți-o înainte de a deschide una nouă." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapozitivul %(position)d din %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profilul setat la %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Niciun profil găsit." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Bara de progres %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Toate" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Nivelul punctuației definit la toate." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Majoritatea" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Nivelul punctuației definit la majoritatea." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nimic" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Nivelul punctuației definit la nimic." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Unele" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Nivelul punctuației definit la unele." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Se caută." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Căutare completă." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Setările Cthulhu au fost reîncărcate." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Textul selectat este: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Selecție ștearsă." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Selecție restaurată." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Text neselectat." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Dimensiune %d, %d. Locație: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Lățime: %d. Înălțime: %d. %d de la stânga. %d de la dreapta." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Sinteza de voce este dezactivată." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Sinteza de voce este activată." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "mai rapid." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "mai lent." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "mai înalt." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "mai jos." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "mai tare." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "mai fin." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Rată %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Înălțime %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volum %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Modul Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Voce Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nu sunt disponibile module Speech-dispatcher" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nu sunt disponibile voci Speech-dispatcher" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Setările de vorbire au fost salvate" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Setările de vorbire nu au putut fi salvate" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Nivelul detalierii: sumar" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Nivelul detalierii: detaliat" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " puncte de suspensie" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu vă urează bun venit." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu pândește sub valuri." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Mod somn activat pentru %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Mod somn dezactivat pentru %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Sinteza de voce nu este disponibilă." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Negăsit" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Bara de stare nu a fost găsită" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "șirul nu a fost găsit" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Tastele de navigare structurală sunt dezactivate." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Tastele de navigare structurală sunt activate." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nu a fost găsit" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Rândul %(row)d, coloana %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Sfârși de tabel" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Pronunță celula" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Pronunță rândul" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Ne uniform" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Nu sunt într-un tabel." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Coloane reordonate" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Rânduri reordonate" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "coloana %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "coloana %(index)d din %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Sfârșit de coloană." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Început de coloană." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Coloana %s selectată" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Coloanele %s până la %s selectate" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Coloanele %s până la %s deselectate" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Coloana %s deselectată" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "rând %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "rândul %(index)d din %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Început de rând." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Sfărșit de rând." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Rândul a fost șters." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Ultimul rând a fost șters." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Rândul a fost inserat." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Rândul a fost inserat la sfârșitul tabelului." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Rândul %s selectat" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Rândurile %s până la %s selectate" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Rândurile %s până la %s deselectate" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Rândul %s deselectat" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "selectat" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "neselectată" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H ore, %M minute și %S secunde" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H ore și %M minute" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "anulează" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "refă" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu versiunea %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "spațiu gol" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Înfășurare în jos." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Înfășurare în sus." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 elemente" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Celula se întinde pe %d rând" -msgstr[1] "Celula se întinde pe %d rânduri" -msgstr[2] "Celula se întinde pe %d de rânduri" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d coloană" -msgstr[1] " %d coloane" -msgstr[2] " %d de coloane" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Celula se întinde pe %d coloană" -msgstr[1] "Celula se întinde pe %d coloane" -msgstr[2] "Celula se întinde pe %d de coloane" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d caracter prea lung" -msgstr[1] "%d caractere prea lung" -msgstr[2] "%d de caractere prea lung" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d fereastră de dialog)" -msgstr[1] "(%d ferestre de dialog)" -msgstr[2] "(%d de ferestre de dialog)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d fereastră nevocalizată" -msgstr[1] "%d ferestre nevocalizate" -msgstr[2] "%d de ferestre nevocalizate" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d octet" -msgstr[1] "%d octeți" -msgstr[2] "%d de octeți" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fișier găsit" -msgstr[1] "%d fișiere găsite" -msgstr[2] "%d de fișiere găsite" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formular" -msgstr[1] "%d formulare" -msgstr[2] "%d de formulare" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d antet" -msgstr[1] "%d antete" -msgstr[2] "%d de antete" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d element" -msgstr[1] "%d elemente" -msgstr[2] "%d de elemente" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d marcaj" -msgstr[1] "%d marcaje" -msgstr[2] "%d de marcaje" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d element găsit" -msgstr[1] "%d elemente găsite" -msgstr[2] "%d de elemente găsite" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Se părăsește %d citat." -msgstr[1] "Se părăsește %d citate." -msgstr[2] "Se părăsește %d de citate." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Se părăsește %d listă." -msgstr[1] "Se părăsește %d liste." -msgstr[2] "Se părăsește %d de liste." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Listă de dimensiune necunoscută" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Listă cu %d element" -msgstr[1] "Listă cu %d elemente" -msgstr[2] "Listă cu %d de elemente" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Flux de dimensiune necunoscută" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Flux cu %d articol" -msgstr[1] "Flux cu %d articole" -msgstr[2] "Flux cu %d de articole" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Listă de descriere cu %d termen" -msgstr[1] "Listă de descriere cu %d termeni" -msgstr[2] "Listă de descriere cu %d de termeni" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d valoare" -msgstr[1] "%d valori" -msgstr[2] "%d de valori" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "tabel matematic cu %d rând" -msgstr[1] "tabel matematic cu %d rânduri" -msgstr[2] "tabel matematic cu %d de rânduri" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d coloană" -msgstr[1] "%d coloane" -msgstr[2] "%d de coloane" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "tabel matematic encapsulat cu %d rând" -msgstr[1] "tabel matematic encapsulat cu %d rânduri" -msgstr[2] "tabel matematic encapsulat cu %d de rânduri" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d mesaj.\n" -msgstr[1] "%d mesaje.\n" -msgstr[2] "%d de mesaje.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d procent." -msgstr[1] "%d procente." -msgstr[2] "%d de procente." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d procent din document citit" -msgstr[1] "%d procente din document citite" -msgstr[2] "%d de procente din document citite" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixel" -msgstr[1] "%d pixeli" -msgstr[2] "%d de pixeli" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d caracter %(repeatChar)s" -msgstr[1] "%(count)d caractere %(repeatChar)s" -msgstr[2] "%(count)d de caractere %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d din %(total)d element selectat" -msgstr[1] "%(index)d din %(total)d elemente selectate" -msgstr[2] "%(index)d din %(total)d de elemente selectate" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -"%d scurtătură de tastatură implicită găsită pentru cititorul de ecran." -msgstr[1] "" -"%d scurtături de tastatură implicite găsite pentru cititorul de ecran." -msgstr[2] "" -"%d scurtături de tastatură implicite găsite pentru cititorul de ecran." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"%(count)d scurtătură de tastatură pentru cititorul de ecran găsită pentru " -"%(application)s." -msgstr[1] "" -"%(count)d scurtături de tastatură pentru cititorul de ecran găsite pentru " -"%(application)s." -msgstr[2] "" -"%(count)d de scurtături de tastatură pentru cititorul de ecran găsite pentru " -"%(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d spațiu" -msgstr[1] "%d spații" -msgstr[2] "%d de spații" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tab" -msgstr[1] "%d taburi" -msgstr[2] "%d de taburi" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabel" -msgstr[1] "%d tabele" -msgstr[2] "%d de tabele" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabel de dimensiune necunoscută" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabel cu %d coloană, număr de rânduri necunoscut" -msgstr[1] "tabel cu %d coloane, număr de rânduri necunoscut" -msgstr[2] "tabel cu %d de coloane, număr de rânduri necunoscut" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabel cu %d rând, număr de coloane necunoscut" -msgstr[1] "tabel cu %d rânduri, număr de coloane necunoscut" -msgstr[2] "tabel cu %d de rânduri, număr de coloane necunoscut" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabel cu %d rând" -msgstr[1] "tabel cu %d rânduri" -msgstr[2] "tabel cu %d de rânduri" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "acum %d secundă" -msgstr[1] "acum %d secunde" -msgstr[2] "acum %d de secunde" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "acum %d minut" -msgstr[1] "acum %d minute" -msgstr[2] "acum %d de minute" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "acum %d oră" -msgstr[1] "acum %d ore" -msgstr[2] "acum %d de ore" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "acum %d zi" -msgstr[1] "acum %d zile" -msgstr[2] "acum %d de zile" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d legătură nevizitată" -msgstr[1] "%d legături nevizitate" -msgstr[2] "%d de legături nevizitate" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d legătură vizitată" -msgstr[1] "%d legături vizitate" -msgstr[2] "%d de legături vizitate" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "comută" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "pe %(index)d din %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d din %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "elementul %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVELUL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nivelul în arbore %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVELUL %d ÎN ARBORE" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detalii pentru %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "are detalii în %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "sugestie" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "listă de selecție editabilă" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "conținut editabil" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "flux" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figură" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "abstract" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "recunoștiințe" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "cuvânt de concluzie" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "apendice" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "intrare de bibliografie" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografie" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "capitol" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "colofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "concluzie" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "copertă" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "credit" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "credite" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedicație" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "notă de final" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "note de final" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epliog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "rectificare" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "exemplu" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "cuvânt înainte" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "glosar" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "index" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introducere" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "întrerupere de pagină" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "lista cu pagini" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "parte" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "prefață" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "citat" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "QNA" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "subtitlu" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "cuprins" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivel %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "bară de derulare orizontală" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "bară de derulare verticală" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "comutator orizontal" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "comutator vertical" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "despărțitor orizontal" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "despărțitor vertical" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "comutator" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Panou iconiță" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "baner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "conținut complementar" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informație" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "conținut principal" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigație" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "regiune" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "căutare" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "legătură vizitată" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "buton de meniu" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "sortat crescător" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "sortat descrescător" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "sortat" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "clicabil" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "contractat" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "desfășurat" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "are descriere lungă" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "orizontal" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertical" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "bifată" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nebifată" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "activată" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "dezactivată" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "bifată parțial" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "apăsat" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "neapăsat" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "nu este selectat" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "selectat" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "neselectat" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "neselectat" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "vizitată" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "nevizitată" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "decolorat" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "protejat ca scriere" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "prtjtscr" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "necesar" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "selecție-multiplă" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "intrare nevalidă" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "nevalidă" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ortografie nevalidă" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "ortografie" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "gramatică nevalidă" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatică" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Caută" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Dialogul Caută al cititorului de ecran" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "În_chide" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Caută" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "Cau_tă după:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Caută după:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Începu_tul ferestrei" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Începutul ferestrei" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Începând de la:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Reia de la început" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Caută în sens _invers" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Direcția de căutare:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Majuscule semnificative" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Potrivir_e doar pentru cuvântul întreb" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opțiuni:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Implicit" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Majuscule" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiperlegătură" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplicație" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Fereastră" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Preferințe Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Ajutor" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Aplică" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Aranjament de tastatură" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Profiluri active:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profil de pornire:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "Î_ncarcă" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Salvează c_a" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Elimină" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiluri" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Prezintă indicii" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Pronunță obiectul de sub mau_s" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Maus" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Formatul _timpului:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formatul dat_ei:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Data și ora" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Pronunță actuali_zările" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Actualizări _Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frecvență (secunde):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Se aplică la:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Actualizări sono_re" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Actualizările barei de progres" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Activează de_rularea înainte sau înapoi în Spune tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Activează navigarea _structurală în Spune tot" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Pronunță tot d_upă:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Anunță _citate în Spune tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Anunță li_ste în Spune tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Anunță _tabele în spune tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Anunță _panouri în Spune tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Anunță _formulare în Spune tot" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Anunță _marcaje în Spune tot" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Spune tot" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Prezentarea elementului:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "General" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lum:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Înălț_ime:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Rată:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Persoană:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Limbă:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Sinteti_zatorul de voce:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Systemul de pronunție:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Tipul _vocii:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Stil de _capitalizare:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Configurări tip voce" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Pronunță șirurile cu ma_juscule în interior ca niște cuvinte separate" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Pronunță _numerele ca cifre" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Configurări voce globală" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Voce" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Activează sintetizarea vocală" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Detali_at" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Detaliere" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Toate" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Nivelul punctuației" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Pronunță doar textul afișat" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Pronunță liniile goale" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Pronunță _indentarea și alinierea" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "_Pronunță mnemonicele obiectului" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Pronunță p_oziția copilului" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Pronunță mesajele îndrumarului" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Mesajele de _sistem sunt detaliate" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Pronunță culorile ca nume" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Anunță _citatele în timpul navigării" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Anunță _listele în timpul navigării" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Anunță _tabelele în timpul navigării" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Pronunță indicatorul de greșeală _ortografică" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Anunță _panourile în timpul navigației" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Anunță _mesajele în timpul navigației" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Anunță formulare în timpul navigației" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Pronunță _descrierea" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Pronunță întregul _rând în foile de calcul" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Pronunță întregul rând în tabelele _documentelor" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Pronunță întregul rând în tabelele _GUI" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Context de vorbire" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Pronunție" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Activează _suportul Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Abreviază numele controalelor" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "D_ezactivează simbolul de sfârșit de linie" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Tabelul de prescurtări:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Activează Braille prescurtat" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Activează încadrarea cu_vintelor" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Configurări de afișare" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Niciunul" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indicator de selecție" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indicator de hiperlegătură" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Activează _mesajele fulger" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "D_urată (secunde):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Mesajele sunt _persistente" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Mesajele sunt _detaliate" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Configurări mesaje fulger" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Activează pronunțarea _tastelor" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Activează tastele _alfabetice" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Activează tastele n_umerice" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Activează tastele de _punctuație" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Activează _spațiul" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Activează tastele _modificator" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Activează tastele _funcționale" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Activează tastele de _acțiune" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Activează tastele de _navigare" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Activează re_darea pe cuvinte" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Activea_ză redarea pe propoziții" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Echo" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Cheia(le) _modificatoare ale cititorului de ecran:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Asocieri de taste" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Dicționar de pronunție" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Intrare nouă" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "Șter_ge" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Pronunțare" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Pronunță t_ot" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Nu pronunța _nimic" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Reset" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atribute text" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Mută la coa_dă" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Mută mai _jos" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Mută mai s_us" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Mu_tă în vârf" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Ajustează atributul selectat" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indicator Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atribute text" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Activează asistentul AI" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Furnizor:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Local - Gratuit)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Fișier cheie _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Calea către fișierul cheie API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Obține cheia API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Deschide browserul pentru a obține cheia API Claude și a o salva automat" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Necesită confirmare înainte de acțiunile AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Model Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Numele modelului pentru Ollama (de ex. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Endpoint Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL-ul endpoint-ului API Ollama (de ex. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Calitatea capturii de ecran:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Scăzut" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Mediu" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Înalt" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Asistent AI" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Cod _limbă:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Factor de _scalare:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Imagine în _tonuri de gri" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Inversează imaginea" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Imagine _alb-negru" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Prag alb/negru:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analizează culorile" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Copiază rezultatele în _clipboard" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : Ana, ă : ăsta, â : â din a, b : Barbu, c : Constantin, d : Dumitru, e : " -"Elena, f : Florea, g : Gheorghe, h : Haralambie, i : Ion, î : î din i, j : " -"Jean, k : Kilogram, l : Luca, m : Marin, n : Nicolae, o : Olga, p : Petre, " -"q : Quebec, r : Radu, s : Sandu, ș : șirag, t : Tudor, ț : țară, u : Udrea, " -"v : Vasile, w : Whiskey, x : Xenopol, y : I grec, z : Zamfir" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "culoare de fundal" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "fundal înălțime totală" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "pointilare fundal" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "direcție" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "editabil" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "nume familie" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "culoare prim plan" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "pointilare prim plan" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efect font" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indentare" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "greșeală" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "invizibil" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "aliniere" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "limbă" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "marginea stângă" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "înălțimea liniei" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "stilul paragrafului" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixeli deasupra liniei" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixeli sub linie" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixeli în încadrare" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "marginea dreaptă" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "ridicare" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "scală" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "dimensiune" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "întindere" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "tăiat" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "decorații text" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotație text" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "umbră text" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "subliniere" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variantă" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "aliniere verticală" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "greutate" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "mod înfășurare" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "mod scriere" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "adevărat" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "fals" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "niciunul" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "gravat" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "reliefat" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "schițat" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "liniuță deasupra" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "linie prin" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "clipire" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "negru" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "simplu" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dublu" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "mai jos" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "caracter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "cuvânt" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "caracter cuvânt" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "st-dr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "dr-st" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "stânga" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "dreapta" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centrat" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "nici o aliniere" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "umplere" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensat" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensat" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensat" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensat" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi expandat" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "extins" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra extins" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra extins" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "litere mici" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblic" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "cursiv" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Implicit" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Corp text" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Antet" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "linie de bază" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "sub" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "supra" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "vârf" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "text-vârf" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "mijloc" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "bază" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "text-bază" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "moștenit" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "sd-sj" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "ds-sj" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "sj-ds" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "sj-sd" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "js-ds" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "js-sd" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "sd" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "ds" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "sj" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "îngroșat" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "ortografie" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Apăsați spațiu pentru a comuta." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Apăsați spațiu pentru a desfășura, și sus și jos pentru a selecta un element " -"din meniu." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Apăsati alt+f pentru a focaliza ferestrele copil." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Pentru a sări la elemente, folosește sau tastele săgeți sau căutarea prin " -"tastarea prefixului." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Pentru a ajunge la meniurile de sistem apasă tastele alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Folosiți sus și jos pentru a selecta un element." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Pentru a plia, apăsați shift plus stânga." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Pentru a extinde, apăsați shift plus dreapta." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Pentru a activa apăsați enter." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Tastați un text." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Folosiți stânga și dreapta pentru a vedea alte taburi." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Pentru a activa apăsați spațiu." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Folosiți săgețile în sus sau în jos pentru a selecta valoarea sau scrieți " -"valoarea numerică dorită." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Folosiți săgețile pentru a modifica." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Pentru navigare apăsați săgeata stângă sau dreaptă. Pentru a muta prin " -"elemente apăsați săgețile sus sau jos." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Pentru a deschide submeniul, apăsați săgeata dreaptă." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Pentru micșorare apăsați săgeata stângă, pentru mărire apăsați săgeata " -"dreaptă.Pentru a ajunge la minimum apăsați tasata HOME, iar pentru maximum, " -"tasta END." diff --git a/po/ru.po b/po/ru.po deleted file mode 100644 index 23ef69d..0000000 --- a/po/ru.po +++ /dev/null @@ -1,9278 +0,0 @@ -# Translation of cthulhu to Russian -# -# Nickolay V. Shmyrev , 2006. -# Anatoly Kamynin , 2007. -# Yuri Kozlov , 2010. -# Yuri Myasoedov , 2012, 2013, 2014. -# Melman , 2021. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu trunk\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-12 17:47+0300\n" -"Last-Translator: Artur So \n" -"Language-Team: Russian \n" -"Language: ru\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Экранный диктор Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "экран;чтец;доступность;речь;брайль;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "вним" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "мульт" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "стрел" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "кал" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "вджрис" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "подп" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "отм" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "выбцв" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "загст" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "выпсп" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "дат" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "знч" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "обл" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "наб" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "длг" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "папк" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "гипертекст" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "рисов" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "файл" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "зпл" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "шрифт" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "форм" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "стекл" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "заг" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "изоб" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "внобл" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "метк" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "разоб" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "ссыл" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "спис" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "элспис" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "мен" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "панмен" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "элмен" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "парам" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "стр" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "спвкл" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "пан" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "пар" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "всплмен" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "индвып" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "кнп" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "кнопвыб" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "пунктвыб" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "главоб" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "згстр" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "прок" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "облпрок" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "глв" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "разд" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "плзнк" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "панразд" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "счетч" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "пансост" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "табл" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "ячей" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "элемотмен" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "терм" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "текст" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "перекл" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "панинст" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "подск" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "дер" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "дертаб" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "неизв" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "прсмтр" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "окн" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "загл" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "подп" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "абз" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "прил" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "авто" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "облпр" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "вст" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Чешский уровень 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Испанский уровень 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Канадский французский уровень 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Французский уровень 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Латышский уровень 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Голландский уровень 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Норвежский уровень 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Норвежский уровень 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Норвежский уровень 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Норвежский уровень 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Польский уровень 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Португальский уровень 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Шведский уровень 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Арабский уровень 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Валлийский уровень 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Валлийский уровень 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Немецкий уровень 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Немецкий уровень 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Немецкий уровень 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Британский английский уровень 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Британский английский уровень 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Английский уровень 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Английский уровень 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Канадский французский уровень 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Французский уровень 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Греческий уровень 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Хинди уровень 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Венгерский 8-ми точечный компьютер" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Венгерский уровень 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Венгерский уровень 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Итальянский уровень 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Бельгийский голландский уровень 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "пробел" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "новая строка" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "табуляция" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "восклицательный знак" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "кавычка" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "решётка" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "доллар" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "процент" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "амперсанд" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "апостроф" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "левая скобка" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "правая скобка" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "звезда" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "плюс" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "запятая" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "тире" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "точка" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "косая черта" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "двоеточие" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "точка с запятой" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "меньше" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "равно" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "больше" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "вопрос" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "собака" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "левая квадратная скобка" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "обратная косая черта" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "правая квадратная скобка" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "крышка" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "подчёркивание" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "обратное ударение" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "левая фигурная скобка" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "вертикальная линия" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "правая фигурная скобка" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "тильда" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "неразрывный пробел" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "перевёрнутый восклицательный знак" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "центы" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "фунты" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "знак валюты" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "йены" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "вертикальная линия с разрывом" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "глава" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "трема" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "авторское право" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "верхний индекс а" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "левая двойная угловая кавычка" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "логическое нет" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "тире" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "зарегистрированная марка" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "черта над" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "градусы" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "плюс-минус" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "верхний индекс два" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "верхний индекс три" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "ударение" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "мю" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "абзац" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "точка в центре" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "седиль" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "верхний индекс один" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "порядковое" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "правая двойная угловая кавычка" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "одна четвёртая" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "одна вторая" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "три четверти" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "перевёрнутый вопросительный знак" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "а с ударением" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "заглавное а с обратным ударением" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "заглавное а с ударением" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "заглавное а с крышкой" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "заглавное а с тильдой" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "заглавное а с умляутом" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "заглавное а с кружком" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "заглавное ае" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "заглавное ц с седилем" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "заглавное е с обратным ударением" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "заглавное е с ударением" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "заглавное е с крышкой" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "заглавное е с умляутом" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "заглавное и с обратным ударением" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "заглавное и с ударением" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "заглавное и с крышкой" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "заглавное и с умляутом" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "заглавное зе" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "заглавное эн с тильдой" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "заглавное о с обратным ударением" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "заглавное о с ударением" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "заглавное о с крышкой" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "заглавное о с тильдой" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "заглавное о с умляутом" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "умножить крест" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "заглавное о перечёркнутое" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "заглавное у с обратным ударением" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "заглавное у с ударением" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "заглавное у с крышкой" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "заглавное у с умляутом" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "заглавное игрек с ударением" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "заглавное торн" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "эс двойное" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "а с обратным ударением" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "а с крышкой" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "а с тильдой" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "а с умляутом" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "а с кружком" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ае" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "це с седилем" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "е с обратным ударением" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "е с ударением" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "е с крышкой" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "е с умляутом" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "и с обратным ударением" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "и с ударением" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "и с крышкой" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "и с умляутом" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "зе" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "эн с тильдой" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "о с обратным ударением" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "о с ударением" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "о с крышкой" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "о с тильдой" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "о с умляутом" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "разделить на" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "о перечёркнутое" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "торн" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "у с ударением" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "у с обратным ударением" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "у с крышкой" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "у с умляутом" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "игрек с ударением" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "игрек с умляутом" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "заглавное игрек с умляутом" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "флорин" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "среднее тире" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "левая одиночная кавычка" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "правая одиночная кавычка" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "одиночная нижняя кавычка" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "левая двойная кавычка" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "правая двойная кавычка" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "двойная нижняя кавычка" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "кинжал" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "двойной кинжал" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "жирная точка" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "треугольная точка" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "промилле" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "штрих" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "двойной штрих" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "тройной штрих" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "отметка-дефис" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "евро" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "торговая марка" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "галочка" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "жирная галочка" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "отметка в форме икс" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "верхний индекс 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "верхний индекс 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "верхний индекс 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "верхний индекс 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "верхний индекс 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "верхний индекс 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "верхний индекс 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "верхний индекс плюс" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "верхний индекс минус" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "верхний индекс равно" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "верхний индекс открывающая скобка" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "верхний индекс закрывающая скобка" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "верхний индекс n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "нижний индекс 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "нижний индекс 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "нижний индекс 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "нижний индекс 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "нижний индекс 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "нижний индекс 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "нижний индекс 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "нижний индекс 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "нижний индекс 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "нижний индекс 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "нижний индекс плюс" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "нижний индекс минус" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "нижний индекс равно" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "нижний индекс открывающая скобка" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "нижний индекс закрывающая скобка" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "квадрат" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "ромб" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "символ замещения объекта" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Переместить указатель на текущий элемент" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" -"Щёлкнуть левой кнопкой мыши по текущему элементу в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" -"Щёлкнуть правой кнопкой мыши по текущему элементу в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Прочитать весь документ" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Произнести всё окно в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Сообщить о текущем положении" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Сообщить о текущем положении подробно" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Произнести текущее выделение" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Произнести сведения о ссылке" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Представить кнопку по умолчанию" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Представить содержимое строки состояния" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Представить заголовок окна" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Открыть диалоговое окно поиска" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Показать список действий" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Найти следующее вхождение строки" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Найти предыдущее вхождение строки" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Войти или выйти из режима общего осмотра" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Переключить ограничительный общий осмотр на текущий объект" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Переместить общий осмотр в начало" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Переместить общий осмотр в конец" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Переместить общий осмотр к началу предыдущей строки" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Произнести текущую строку в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Произнести текущую строку по буквам в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Произнести фонетически текущую строку в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Переместить общий осмотр в начало следующей строки" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Переместить общий осмотр к предыдущему элементу или слову" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Произнести текущий элемент или слово в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Произнести по буквам текущий элемент или слово в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Произнести фонетически текущий элемент или слово в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Переместить общий осмотр к следующему элементу или слову" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Переместить общий осмотр к слову над текущим словом" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Произнести текущий объект в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Переместить общий осмотр к слову под текущим словом" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Переместить общий осмотр к предыдущему символу" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Произнести текущий символ в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Произнести фонетически текущий символ в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" -"Произнести значение символа в кодировке Unicode в режиме общего осмотра" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Переместить общий осмотр к следующему символу" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Переместить общий осмотр в конец строки" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Переместить общий осмотр в левый нижний угол" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Копировать содержимое общего осмотра в буфер обмена" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Добавить содержимое общего осмотра в буфер обмена" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Показать содержимое режима общего осмотра" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Произносить только текущую ячейку таблицы или всю строку" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Произносить атрибуты текущего символа" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Перемещаться по строке на дисплее брайля влево" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Перемещаться по строке на дисплее брайля вправо" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Вернуться к объекту с фокусом ввода" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Включить или отключить сокращенный шрифт брайля" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Работа с клавишей курсорного управления" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Отметить начало выделения текста" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Отметить конец выделения текста" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Войти в режим изучения клавиатуры. Нажмите escape для выхода из этого режима" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Уменьшить темп речи" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Увеличить темп речи" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Понизить тон речи" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Повысить тон речи" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Увеличить громкость речи" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Уменьшить громкость речи" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Выбрать предыдущую настройку речи" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Выбрать следующую настройку речи" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Уменьшить текущую настройку речи" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Увеличить текущую настройку речи" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Сохранить настройки речи" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Временно включить или отключить речь" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Переключить уровень информативности речи" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Переключить спящий режим" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Завершить работу экранного диктора" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Показать диалог настройки параметров" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Показать диалог настройки параметров приложения" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Переключить озвучивание отступов и выравниваний" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Изменить стиль произношения чисел" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Следующий уровень озвучивания пунктуации" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Следующий синтезатор речи" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Следующий профиль параметров" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Следующий стиль прописных букв" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Следующий уровень озвучивания клавиш" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Переключить уровень отладки во время работы приложения" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Произнести путь от закладки к текущему положению" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Перейти к предыдущей закладке" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Перейти к закладке" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Перейти к следующей закладке" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Добавить закладку" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Сохранить закладки" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Произносить ли элементы под указателем мыши" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Сообщить текущее время" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Сообщить текущую дату" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Текущий размер и расположение текущего объекта" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Передавать следующие команды непосредственно в приложение" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Произнести и отобразить в Брайле предыдущее сообщение беседы" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Уведомлять ли о том, что собеседник начал печатать" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Представлять ли историю сообщений беседы" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "Произносить ли название беседы перед новым сообщением беседы" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Строка влево" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Строка вправо" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Строка вверх" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Строка вниз" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Зафиксировать" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Верхний левый" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Нижний левый" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Позиция курсора" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Шесть точек" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Курсорное управление" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Начало вырезания" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Вырезать строку" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Сообщить последнее уведомление" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Сообщить список уведомлений" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Сообщить предыдущее уведомление" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Сообщить следующее уведомление" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Перейти к следующему символу" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Перейти к предыдущему символу" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Перейти к следующему слову" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Перейти к предыдущему слову" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Перейти к следующей строке" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Перейти к предыдущей строке" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Перейти к началу файла" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Перейти к концу файла" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Перейти к началу строки" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Перейти к концу строки" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Перейти к следующему объекту" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Перейти к предыдущему объекту" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Раскрыть текущее поле со списком" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Переключить навигацию экранного диктора между основной и курсорной" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Расширенные настройки работы с изменяющимися областями" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Отключить вежливое напоминание об изменяющихся областях" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Повторить предыдущие сообщения об изменяющихся областях" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Следить за изменяющимися областями" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Навести фокус и убрать его с элемента под мышью" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" -"Задать строку для использования в качестве динамических заголовков столбцов" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Очистить временные заголовки столбцов" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" -"Задать столбец для использования в качестве динамических заголовков строк" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Очистить временные заголовки строк" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Представить содержимое строки ввода" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Включить или выключить клавиши структурной навигации" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Перейти к предыдущему блоку цитирования" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Перейти к следующему блоку цитирования" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Показать список блоков цитирования" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Перейти к предыдущей кнопке" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Перейти к следующей кнопке" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Показать список кнопок" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Перейти к предыдущей кнопке-флажку" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Перейти к следующей кнопке-флажку" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Показать список кнопок-флажков" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Перейти к предыдущему объекту для нажатия" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Перейти к следующему объекту для нажатия" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Показать список объектов для нажатия" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Перейти к предыдущему полю со списком" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Перейти к следующему полю со списком" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Перейти к началу контейнера" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Перейти к концу контейнера" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Показать список полей со списками" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Перейти к предыдущему полю ввода" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Перейти к следующему полю ввода" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Показать список элементов" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Перейти к предыдущему полю формы" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Перейти к следующему полю формы" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Показать список полей формы" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Перейти к предыдущему заголовку" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Перейти к следующему заголовку" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Показать список заголовков" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Перейти к предыдущему заголовку уровня %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Перейти к следующему заголовку уровня %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Показать список заголовков уровня %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Перейти к предыдущей внутренней области" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Перейти к следующей внутренней области" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Показать список внутренних областей" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Перейти к предыдущему изображению" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Перейти к следующему изображению" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Показать список изображений" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Перейти к предыдущему ориентиру" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Перейти к следующему ориентиру" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Показать список ориентиров" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Перейти к предыдущему крупному объекту" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Перейти к следующему крупному объекту" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Показать список крупных объектов" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Переходит к предыдущей ссылке" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Переходит к следующей ссылке" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Показать список ссылок" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Перейти к предыдущему списку" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Перейти к следующему списку" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Показать список списков" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Перейти к предыдущему элементу списка" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Перейти к следующему элементу списка" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Показать список элементов списка" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Перейти к предыдущей изменяющейся области" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Перейти к следующей изменяющейся области" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Перейти к последней объявленной изменяющейся области" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Перейти к родительскому объекту с фокусом навигатора." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Перейти к первому дочернему объекту с фокусом навигатора." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Перейти к следующему родственному объекту с фокусом навигатора." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Перейти к предыдующему родственному объекту с фокусом навигатора." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Щелкните на объекте с фокусом навигатора." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Переключить упрощенную навигацию по объектам." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Перейти к предыдущему абзацу" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Перейти к следующему абзацу" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Показать список абзацев" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Перейти к предыдущему переключателю" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Перейти к следующему переключателю" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Показать список переключателей" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Перейти к предыдущему разделителю" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Перейти к следующему разделителю" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Перейти к предыдущей таблице" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Перейти к следующей таблице" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Показать список таблиц" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Перейти к ячейке снизу" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Перейти к первой ячейке в таблице" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Перейти к последней ячейке в таблице" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Перейти к ячейке слева" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Перейти к ячейке справа" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Перейти к ячейке сверху" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Переключить режим макета" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Переключить между режимом чтения и режимом фокуса" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Включить принудительный режим фокуса" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Включить принудительный режим чтения" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Перейти к предыдущей непосещённой ссылке" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Перейти к следующей непосещённой ссылке" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Показать список непосещённых ссылок" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Перейти к предыдущей посещённой ссылке" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Перейти к следующей посещённой ссылке" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Показать список посещённых ссылок" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "бледно-голубой" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "античный белый" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "аквамариновый" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "лазурный" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "бежевый" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "бисквитный" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "чёрный" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "бланшированный миндаль" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "синий" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "сине-фиолетовый" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "коричневый" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "желтовато-коричневый" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "серо-синий" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "салатовый" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "шоколадный" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "коралловый" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "васильковый" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "бледно-жёлтый" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "тёмно-красный" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "циан" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "тёмно-синий" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "тёмный циан" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "тёмно-золотой" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "тёмно-серый" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "тёмно-зелёный" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "тёмный хаки" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "тёмный маджента" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "тёмный оливково-зелёный" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "тёмно-оранжевый" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "тёмно-лиловый" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "тёмно-красный" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "тёмная лососина" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "тёмный зелёный морской" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "тёмно-аспидный синий" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "тёмный аспидно-серый" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "тёмно-бирюзовый" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "глубокий фиолетовый" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "глубокий розовый" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "глубокий небесно-голубой" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "тускло-серый" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "защитно-синий" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "кирпичный" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "цветочно-белый" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "лесная зелень" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "фуксия" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "светлый серо-фиолетовый" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "туманно-белый" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "золотой" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "золотисто-берёзовый" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "серый" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "зелёный" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "жёлто-зелёный" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "белая мускатная дыня" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "ярко-розовый" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "индийский красный" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "индиго" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "слоновая кость" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "хаки" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "лаванда" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "розово-лавандовый" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "зелёная лужайка" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "лимонно-кремовый" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "светло-синий" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "коралловый светлый" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "светлый циан" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "светло-жёлтый золотистый" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "светло-серый" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "салатовый" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "светло-розовый" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "светло-лососёвый" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "морской светло-зелёный" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "светлый небесно-голубой" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "светлый аспидно-серый" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "светло-синяя сталь" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "светло-жёлтый" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "лайм" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "зелёный лайм" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "льняной" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "маджента" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "коричнево-малиновый" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "умеренный аквамарин" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "умеренный синий" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "умеренный цвет орхидеи" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "умеренный фиолетовый" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "умеренный морской зелёный" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "умеренный аспидно-синий" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "умеренный весенне-зелёный" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "умеренный бирюзовый" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "фиолетово-красный" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "полуночно-синий" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "кремовый мятный" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "тускло-розовый" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "мокасин" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "белый навахо" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "тёмно-синий" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "старые кружева" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "оливковый" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "нежно-оливковый" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "оранжевый" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "оранжево-красный" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "орхидея" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "бледный золотисто-берёзовый" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "бледно-зелёный" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "бледно-бирюзовый" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "бледный фиолетово-красный" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "побег папайи" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "персиковый" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "перу" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "розовый" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "сливовый" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "пороховая синь" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "пурпурный" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "красный" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "розово-коричневый" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "ярко-синий" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "старая кожа" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "лососёвый" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "песочный" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "зелёный морской" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "морская пена" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "охра" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "серебряный" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "небесно-голубой" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "синевато-серый" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "аспидно-серый" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "снежный" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "весенне-зелёный" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "синяя сталь" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "рыжевато-коричневый" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "сине-зелёный" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "чертополох" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "томатный" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "бирюзовый" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "фиолетовый" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "пшеничный" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "белый" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "дымчатый белый" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "жёлтый" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "жёлто-зелёный" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Включить" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Автоматический режим фокуса, включаемый при структурной навигации" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Автоматический режим фокуса, включаемый при курсорной навигации" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Автоматический режим фокуса, включаемый при курсорной навигации" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Точка _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Точка _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Точки 7 _и 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Отмена" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Перейти к" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Значок" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Отключено" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Произносить" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Уведомлять, когда _собеседник печатает" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Представлять _историю сообщений для каждой беседы" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Произносить сообщения из" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Все кан_алы" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Все каналы, когда акт_ивно любое окно %s" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Канал, _окно которого выбрано" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "Произносить название бес_еды" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Включить режим макета для содержимого" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "двойной щелчок" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "тройной щелчок" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Синтезатор по умолчанию" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Строка" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Строка замены" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Включить озвучивание по сим_волам" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Включить озвучивание непробельных _диакритических клавиш" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Текущее положение" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Минимальная длина совпавшего текста:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Параметры поиска" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Во время поиска озвучивать изм_енение строки" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Произносить результаты во время п_оиска" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Команда" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Привязка клавиш" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "По умолчанию" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Режим изучения" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Действия" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Привязки Брайля" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Закладки" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Дата и время" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Озвучивание элементов под указателем мыши" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Навигация по объектам" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Сведения об объекте" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Не задано" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Режим общего осмотра" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Речь и многословие" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Содержимое режима общего осмотра" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Изменено" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "Н_астольный компьютер" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Уведомления" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Получено" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Презентер уведомлений" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Настройки Cthulhu для %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Отмечать в Брайле" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Произносить, если не" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Произнести" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Сохранить профиль как конфликтующий" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Конфликтующий профиль пользователя!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Профиль %s уже существует.\n" -"Продолжить обновление существующего профиля с новыми изменениями?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Загрузить профиль пользователя" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Вы собираетесь изменить текущий профиль. Если\n" -"вы просто изменили настройки, они будут сброшены\n" -"при загрузке профиля.\n" -"\n" -"Продолжить загрузку профиля, отменив предыдущие изменения?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Сохранить профиль как" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Название _профиля:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Удалить профиль пользователя" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Вы собираетесь удалить профиль %s. Все несохранённые настройки и настройки, " -"сохранённые в этом профиле, будут потеряны. Хотите продолжить и удалить этот " -"профиль и все связанные настройки?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Все" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Приложение" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Окно" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Нет" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Некоторые" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Большинство" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Строка" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Предложение" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Блок цитирования" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Кнопка" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Заголовок" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Кнопка-флажок" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Нажимаемый объект" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Поле со списком" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Описание" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Заголовок" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Внутренняя область" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Изображение" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Текстовая метка" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Ориентир" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Уровень" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Ссылка" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Список" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Элемент списка" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Объект" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Абзац" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Переключатель" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Роль" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Выбранный элемент" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Состояние" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Текст" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Значение" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Блоки цитирования" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Кнопки" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Кнопки-флажки" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Нажимаемые объекты" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Поля со списками" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Элементы" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Поля формы" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Заголовки" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Внутренние области" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Изображения" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Заголовки уровня %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Ориентиры" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Крупные объекты" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Ссылки" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Списки" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Элементы списка" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Абзацы" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Переключатели" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Таблицы" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Непосещённые ссылки" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Посещённые ссылки" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Перемещение по странице" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" -"Автоматически начинать чтение страницы, когда она загружена в _первый раз" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" -"Предоставлять _сводку сведений о странице, когда она загружена в первый раз" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Разделять речь на фра_зы между паузами" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "голос по умолчанию %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "По умолчанию" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Гиперссылка" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Системный" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Прописная" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Диспетчер речи" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Проверка правописания" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Произносить _ошибку по буквам" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Произносить _совет по буквам" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Предоставлять _контекст ошибки" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Произносить координаты ячеек электронной таблицы" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Всегда произносить выбранный диапазон ячеек электронной таблицы" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Произносить заголовок _ячейки" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Перемещение по таблицам" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Пропускать пу_стые строки" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Произнести _ячейку" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Произносить координаты ячеек" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Произносить размеры _больших ячеек" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Название атрибута" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Управление курсорной навигацией" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Включить _структурную навигацию" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Тема звуков:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Тема звуков" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Кратко" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d уведомление" -msgstr[1] "%d уведомления" -msgstr[2] "%d уведомлений" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Ctrl" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "левый shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "левый alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "левый control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "правый shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "правый alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "правый control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "левая meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "правая meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "левый tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "вверх" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "вниз" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "влево" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "вправо" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "левый super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "правый super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "меню" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "справка" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "мульти" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "переключатель режима" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "циркумфлекс" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "кружок" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "перечёркивание" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "минус" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Правый Alt" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Супер" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Мета 2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Левый Alt" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "%s в жирном начертании" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "%s в курсивном начертании" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "%s в жирном курсивном начертании" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s в рукописном начертании" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "%s в жирном рукописном начертании" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s во фрактурном начертании" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "%s в двойном начертании" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "%s в жирном фрактурном начертании" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s без засечек" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "%s в жирном начертании без засечек" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "%s в курсивном начертании без засечек" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "%s в жирном курсивном начертании без засечек" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s в моноширинном начертании" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s без точки" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "стрелка влево" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "стрелка вверх" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "стрелка вправо" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "стрелка вниз" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "стрелка влево-вправо" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "стрелка вверх-вниз" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "стрелка северо-запад" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "стрелка северо-восток" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "стрелка юго-восток" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "стрелка влево от линии" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "стрелка вверх от линии" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "стрелка вправо от линии" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "стрелка вниз от линии" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "двойная стрелка влево" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "двойная стрелка вверх" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "двойная стрелка вправо" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "двойная стрелка вниз" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "двойная стрелка влево-вправо" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "двойная стрелка вверх-вниз" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "двойная стрелка северо-запад" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "двойная стрелка северо-восток" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "двойная стрелка юго-восток" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "двойная стрелка юго-запад" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "стрелка-указатель вправо" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "наконечник стрелки вправо" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "минус" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "меньше чем" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "больше чем" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "циркумфлекс" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "гачек" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "бревис" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "точка" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "двойная вертикальная линия" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "горизонтальное многоточие" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "для всех" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "дополнение" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "частичный дифференциал" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "существует" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "не существует" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "пустое множество" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "инкремент" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "набла" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "элемент" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "не элемент" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "малый элемент" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "содержит как члена" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "не содержит как члена" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "малый содержит как члена" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "конец доказательства" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "произведение" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "копроизведение" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "суммирование" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "минус или плюс" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "плюс с точкой" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "косая черта деления" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "разность множеств" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "оператор звёздочка" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "оператор кружок" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "оператор жирная точка" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "квадратный корень" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "кубический корень" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "корень четвёртой степени" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "пропорционально" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "бесконечность" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "прямой угол" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "угол" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "измеренный угол" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "сферический угол" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "разделяет" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "не разделяет" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "параллельно" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "не параллельно" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "логическое и" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "логическое или" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "пересечение" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "объединение" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "интеграл" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "двойной интеграл" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "тройной интеграл" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "контурный интеграл" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "поверхностный интеграл" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "объёмный интеграл" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "интеграл с обходом по часовой стрелке" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "контурный интеграл с обходом по часовой стрелке" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "контурный интеграл с обходом против часовой стрелки" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "следовательно" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "поскольку" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "отношение" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "пропорция" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "точка минус" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "избыток" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "геометрическая пропорция" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "гомотетично" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "тильда" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "обратная тильда" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "перевёрнутая лежащая на боку S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "синусоидальная волна" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "сплетение" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "не тильда" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "минус тильда" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "асимптотически равно" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "не асимптотически равно" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "конгруэнтно равно" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "конгруэнтно, но не фактически равно" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ни конгруэнтно, ни фактически равно" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "почти равно" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "не почти равно" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "почти равно или равно" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "тройная тильда" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "все равны" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "эквивалентно" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "геометрически эквивалентно" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "разница между" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "приближается к пределу" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "геометрически равно" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "конгруэнтно равно или образ" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "образ или конгруэнтно равно" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "двоеточие равно" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "равно двоеточие" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "кружок в равно" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "кружок равно" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "соответствует" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "равняется" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "равноугольно" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "звезда равно" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "дельта равно" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "равно по определению" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "измерено по" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "может быть равно" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "не равно" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "идентично" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "не идентично" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "строго эквивалентно" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "меньше чем или равно" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "больше чем или равно" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "меньше чем над равно" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "больше чем над равно" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "меньше чем, но не равно" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "больше чем, но не равно" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "гораздо меньше чем" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "гораздо больше чем" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "между" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "не эквивалентно" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "не меньше чем" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "не больше чем" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ни меньше чем, ни равно" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ни больше чем, ни равно" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "меньше чем или эквивалентно" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "больше чем или эквивалентно" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ни меньше чем, ни эквивалентно" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ни больше чем, ни эквивалентно" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "меньше чем или больше чем" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "больше чем или меньше чем" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ни меньше чем, ни больше чем" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ни больше чем, ни меньше чем" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "предшествует" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "следует" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "предшествует или равно" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "следует или равно" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "предшествует или эквивалентно" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "следует или эквивалентно" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "не предшествует" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "не следует" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "подмножество" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "супермножество" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "не подмножество" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "не супермножество" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "подмножество или равно" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "супермножество или равно" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ни подмножество, ни равно" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ни супермножество, ни равно" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "подмножество с не равно" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "супермножество с не равно" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "мультимножество" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "умножение мультимножества" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "объединение мультимножества" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "квадратный образ" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "квадратный оригинал" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "квадратный образ или равно" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "квадратный оригинал или равно" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "квадратная крышка" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "квадратная чашка" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "плюс в круге" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "минус в круге" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "умножение в круге" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "косая черта деления в круге" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "оператор точка в круге" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "оператор кружок в круге" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "оператор звёздочка в круге" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "равно в круге" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "тире в круге" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "плюс в квадрате" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "минус в квадрате" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "умножение в квадрате" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "оператор точка в квадрате" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "кнопка вправо" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "кнопка влево" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "кнопка вниз" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "кнопка вверх" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "утверждение" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "моделирует" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "истина" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "принуждает" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "правая крестовина с тройной вертикальной чертой" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "двойная правая крестовина с двойной вертикальной чертой" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "не доказывает" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "не истина" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "не принуждает" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "отрицаемая двойная правая крестовина с двойной вертикальной чертой" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "предшествует в силу отношения" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "следует в силу отношения" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "нормальная подгруппа" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "содержит как нормальную подгруппу" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "нормальная подгруппа или равно" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "содержит как нормальную подгруппу или равно" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "оригинал" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "образ" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "мультикарта" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "эрмитово-сопряжённая матрица" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "интеркалировать" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "исключающее или" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "не и" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "также не" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "правый угол с дугой" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "правый треугольник" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "оператор ромб" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "оператор точка" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "оператор звезда" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "деление умножение" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "галстук-бабочка" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "полупрямое произведение с левым нормальным множителем" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "полупрямое произведение с правым нормальным множителем" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "левое полупрямое произведение" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "правое полупрямое произведение" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "обратная тильда равно" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "вьющееся логическое или" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "вьющееся логическое и" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "двойное подмножество" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "двойное супермножество" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "двойное пересечение" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "двойное объединение" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "вилы" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "равно и параллельно" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "меньше чем с точкой" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "больше чем с точкой" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "много меньше чем" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "много больше чем" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "меньше чем, равно или больше чем" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "больше чем, равно или меньше чем" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "равно или меньше чем" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "равно или больше чем" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "равно или предшествует" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "равно или следует" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "не предшествует или равно" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "не следует или равно" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "не квадратный образ или равно" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "не квадратный оригинал или равно" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "квадратный образ или не равно" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "квадратный оригинал или не равно" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "меньше чем, но не эквивалентно" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "больше чем, но не эквивалентно" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "предшествует, но не эквивалентно" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "следует, но не эквивалентно" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "не нормальная подгруппа" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "не содержит как нормальную подгруппу" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "не нормальная подгруппа или равно" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "не содержит как нормальную подгруппу или равно" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "вертикальное многоточие" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "горизонтальное многоточие на средней линии" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "диагональное многоточие вверх направо" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "диагональное многоточие вниз направо" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "элемент с длинным горизонтальным перечёркиванием" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "элемент с вертикальной чертой в конце горизонтального перечёркивания" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"малый элемент с вертикальной чертой в конце горизонтального перечёркивания" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "элемент с точкой сверху" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "элемент с чертой сверху" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "малый элемент с чертой сверху" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "элемент с чертой снизу" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "элемент с двумя горизонтальными перечёркиваниями" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "содержит с длинным горизонтальным перечёркиванием" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "содержит с вертикальной чертой в конце горизонтального перечёркивания" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"малый содержит с вертикальной чертой в конце горизонтального перечёркивания" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "содержит с чертой сверху" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "малый содержит с чертой сверху" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z-нотация членства в комплекте" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "предельный уровень слева" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "предельный уровень справа" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "минимальный уровень слева" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "минимальный уровень справа" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "фигурная скобка вверх" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "фигурная скобка вниз" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "левая угловая скобка" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "правая угловая скобка" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "точка в круге" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "объединение с точкой" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "объединение с плюсом" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "квадратное пересечение" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "квадратное объединение" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "квадрат" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "пустой квадрат" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "ромб" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "пустой круг" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "круг" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "пустая жирная точка" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "средний малый квадрат" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s с подчёркиванием" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s с косой чертой" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s с вертикальной линией" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "приложение" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "пустое" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "полужирный" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "закладка установлена" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "закладки сохранены" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "не удалось сохранить закладки" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Закладки не найдены." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Закладка не найдена." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Режим прямой передачи команд включён." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Не удалось найти дисплей калькулятора" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "сигнал" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Прописные буквы обозначаются сигналом." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "нет" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Стиль прописных букв не установлен." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "произносить" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Прописные буквы произносятся." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Приложение управляет курсором." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu управляет курсором." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Ячейка %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s выделена" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "Выделены ячейки с %s по %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "Снято выделение ячеек с %s по %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "Снято выделение ячейки %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Исключить использование параметра" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Принудительно использовать параметр" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "ПАРАМЕТР" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Необязательные аргументы" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Использование: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Следующее является неверным: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Вывести список известных запущенных приложений" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Загрузить профиль" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Не удалось загрузить профиль: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Не удаётся запустить Cthulhu, так как невозможно подключиться к рабочему " -"столу.Не удалось запустить экранный диктор, т. к. он не может подключиться к " -"рабочему столу." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Не удалось включить диспетчер параметров. Выход." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"В этом сеансе уже запущен процесс экранного диктора.\n" -"Выполните команду «cthulhu --replace», чтобы заменить существующий процесс." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "ИМЯ" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Использовать другой каталог с параметрами пользователя" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "КАТАЛОГ" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Версия этого приложения" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Заменить текущий экземпляр Cthulhu" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Показать это справочное сообщение и выйти" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Записывать отладочные данные в debug-ГГГГ-ММ-ДД-ЧЧ:ММ:СС.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Записывать отладочные данные в указанный файл" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ФАЙЛ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Задать параметры пользователя (текстовая версия)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Задать параметры пользователя (графическая версия)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Об ошибках сообщайте в список рассылки https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Выделенное вырезано в буфер обмена." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "вырезано" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Выделенное скопировано в буфер обмена." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "скопировано" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Содержимое вставлено из буфера обмена." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "вставлено" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Не уведомлять, когда собеседник печатает." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "уведомлять, когда собеседник печатает." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Сообщение из беседы %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Новая вкладка беседы %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Не произносить название беседы." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "произнести название беседы." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Не представлять историю сообщений для каждой беседы." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Представлять историю сообщений для каждой беседы." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "начало удаления" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "конец удаления" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "начало вставки" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "конец вставки" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "начало подсветки" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "конец подсветки" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "конец совета" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Конец контейнера." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Не в контейнере." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "выбраны все элементы" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Кнопка по умолчанию %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Кнопка по умолчанию %s. Неактивно" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Кнопка по умолчанию не найдена" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " нижний индекс %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " верхний индекс %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Не в диалоговом окне" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "выделен весь документ" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "снято выделение всего документа" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "выделено содержимое документа от позиции курсора" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "снято выделение документа от позиции курсора до конца" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "выделено содержимое документа до позиции курсора" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "снято выделение документа от начала до позиции курсора" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Установлен временный заголовок для строки %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Временный заголовок столбца очищен." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Установлен временный заголовок строки для %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Временный заголовок строки очищен." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "пустая строка" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f килобайт" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f мегабайт" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Файлы не найдены." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Добавляет содержимое в буфер обмена." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Копирует содержимое в буфер обмена." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Не использовать общий осмотр." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Войти в режим общего осмотра." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Выйти из режима общего осмотра." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Общий осмотр, ограниченный текущим объектом" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Общий осмотр неограничен" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "содержит формулу" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "открывает диалог" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "открывает интерактивную таблицу" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "открывает список" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "открывает меню" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "открывает дерево" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "ссылка в карте изображений" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Введённая клавиша уже используется для %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Нажата клавиша %s. Нажмите Enter для подтверждения." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Новая клавиша: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Привязка клавиши удалена. Нажмите Enter для подтверждения." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Привязка к клавише удалена." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "введите новую клавишу" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "по клавишам" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Включено озвучивание по клавишам." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Отключено" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Озвучивание клавиш выключено." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "по клавишам и словам" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Включено озвучивание по клавишам и словам." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "по предложениям" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Включено озвучивание по предложениям." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "по словам" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Включено озвучивание по словам." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "по словам и предложениям" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Включено озвучивание по словам и предложениям." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Заключено в: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "актуарный символ" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "скобки" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "круг" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "длинное деление" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "радикал" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "круглые скобки" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "горизонтальное перечёркивание" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "вертикальное перечёркивание" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "диагональное перечёркивание вниз" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "диагональное перечёркивание вверх" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "стрелка северо-восток" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "линия снизу" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "линия слева" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "линия справа" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "линия сверху" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "фазовый угол" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "арабский символ факториала" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "и" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "начало дроби" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "дробь без черты, начало" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "над" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "конец дроби" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "квадратный корень из" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "кубический корень из" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "корень из" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "начало корня" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "конец корня" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "нижний индекс" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "верхний индекс" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "преднижний индекс" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "преверхний индекс" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "подтекстовый" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "надтекстовый" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "конец таблицы" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "конец вложенной таблицы" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "недоступно" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Выключено" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Озвучивание отступов и выравниваний выключено." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Включено" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Озвучивание отступов и выравниваний включено." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Режим изучения. Нажмите escape для выхода." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Вход в режим изучения. Нажмите клавишу, чтобы прослушать её назначение. " -"Чтобы открыть документацию по экранному диктору, нажмите F1. Чтобы получить " -"список комбинаций клавиш, нажмите F2. Чтобы получить список комбинаций " -"клавиш текущего приложения, нажмите F3. Чтобы выйти из режима изучения, " -"нажмите клавишу escape." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "выход из блока цитирования." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "покидаем детали." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "выход из ленты." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "выход из рисунка." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "выход из формы." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "выход из баннера." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "выход из дополнительного содержимого." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "выход из сведений." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "выход из основного содержимого." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "выход из навигации." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "выход из области." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "выход из поиска." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "выход из списка." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "выход из панели." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "выход из таблицы." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "покидаем подсказку." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "выход из аннотации." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "выход из списка благодарностей." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "выход из послесловия." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "выход из приложения." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "выход из библиографии." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "выход из главы." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "выход из выходных данных." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "выход из заключения." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "выход из упоминания." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "выход из упоминаний." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "выход из посвящения." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "выход из концевых сносок." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "выход из эпиграфа." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "выход из эпилога." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "выход из списка опечаток." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "выход из примера." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "выход из предисловия." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "выход из глоссария." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "выход из указатель." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "выход из введения." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "выход из списка страниц." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "выход из части." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "выход из вступления." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "выход из пролога." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "выход из цитаты." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "выход из вопросов и ответов." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "выход из совета." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "выход из содержания." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "выделена строка вниз от позиции курсора" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "выделена строка вверх от позиции курсора" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "снято выделение строки вниз от позиции курсора" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "снято выделение строки вверх от позиции курсора" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Выход из режима изучения." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "выделена строка от начала до предыдущей позиции курсора" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "выделена строка от предыдущей позиции курсора до конца" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ссылка" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "эта же страница" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "этот же сайт" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "другой сайт" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s ссылается на %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "ссылка %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "посещённая ссылка %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Для перемещения по списку используйте клавиши со стрелками вверх и вниз. " -"Чтобы выйти, нажмите Escape." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Все изменяющиеся области выключены" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "уровни вежливого уведомления об изменяющихся областях восстановлены" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "уровень вежливого уведомления %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "установка напористого режима изменяющихся областей" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "выключение режима изменяющихся областей" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "установка вежливого режима изменяющихся областей" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "установка грубого режима изменяющихся областей" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Слежение за изменяющимися областями выключено" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Слежение за изменяющимися областями включено" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "нет сохранённых сообщений от изменяющихся областей" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Поддержка изменяющихся областей выключена" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Не найдено" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Не удалось определить текущее положение." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "отключено" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "включено" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "написано неправильно" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Слово с ошибкой: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "В контексте %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Режим чтения" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Режим фокуса" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Чтобы включить режим фокуса, нажмите %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Принудительный режим фокусировки." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Принудительный режим чтения." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Режим макета." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Режим объекта." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Указатель перемещен на объект." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Объект под мышью не найден." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Озвучивание элементов под указателем мыши выключено." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Озвучивание элементов под указателем мыши включено." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Ошибка: не удалось создать список объектов." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Нет дочернего." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Нет следующего." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Нет родительского." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Нет предыдущего." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Упрощенная навигация включена." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Упрощенная навигация выключена." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Уровень вложенности %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Добавлен новый элемент" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Не найдено действий для: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Нет фокуса" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Нет приложения с фокусом." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Больше нет блоков цитирования." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Больше нет кнопок." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Больше нет кнопок-флажков." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Больше нет крупных объектов." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Больше нет нажимаемых объектов." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Больше нет полей со списками." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Больше нет полей ввода." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Больше нет полей форм." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Больше нет заголовков." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Нет больше заголовков уровня %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Больше нет внутренних областей." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Больше нет изображений." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Больше нет ориентиров." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Больше нет ссылок." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Больше нет списков." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Больше нет элементов списка." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Больше нет изменяющихся областей." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Больше нет абзацев." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Больше нет переключателей." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Больше нет разделителей." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Больше нет таблиц." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Больше нет непосещённых ссылок." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Больше нет посещённых ссылок." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Текст не выбран." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Не на ссылке." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Уведомление" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Конец" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Начало" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Нет уведомлений" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "цифрами" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Произносить числа цифрами (прим.: 159 — один пять девять)" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "словами" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Произносить числа словами (прим.: 159 — сто пятьдесят девять)" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "отключено" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "включено" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Подождите, выполняется загрузка." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Загрузка завершена." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Завершение загрузки %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Страница имеет %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "выделена страница от позиции курсора" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "выделена страница до позиции курсора" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "снято выделение страницы от позиции курсора" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "снято выделение страницы до позиции курсора" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "выделен абзац ниже позиции курсора" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "выделен абзац выше позиции курсора" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "снято выделение с абзаца ниже позиции курсора" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "снято выделение с абзаца выше позиции курсора" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Диалог настроек Cthulhu уже открыт.\n" -"Закройте его перед открытием нового диалога." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "слайд %(position)d из %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Профиль установлен в %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Профили не найдены." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Индикатор выполнения %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Все" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Уровень пунктуации — все." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Большинство" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Уровень пунктуации — большинство." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Нет" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Уровень пунктуации — нет." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Некоторые" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Уровень пунктуации — некоторые." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Поиск." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Поиск завершён." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Настройки Cthulhu перезагружены." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Выбранный текст: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Выбранное удалено." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Выбранное восстановлено." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Текст не выделен." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Размер: %d, %d. Позиция: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Ширина: %d. Высота: %d. %d слева. %d справа." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Речь выключена." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Речь включена." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "быстрее." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "медленнее." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "выше." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "ниже." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "громче." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "тише." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Скорость %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Высота тона %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Громкость %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Модуль Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Голос Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Нет доступных модулей Speech-dispatcher" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Нет доступных голосов Speech-dispatcher" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Настройки речи сохранены" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Не удалось сохранить настройки речи" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Уровень информативности: кратко" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Уровень информативности: подробно" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " троеточие" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu приветствует вас." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Ктулху таится под волнами." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Режим сна включён для %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Спящий режим отключён для %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Речь недоступна." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Не найдено" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Строка статуса не найдена" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "строка не найдена" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Клавиши структурной навигации выключены." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Клавиши структурной навигации включены." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Не найдено" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Строка %(row)d, столбец %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Конец таблицы" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Произнести ячейку" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Произнести строку" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Не одинаковые" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Не в таблице." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Порядок столбцов изменён" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Порядок строк изменён" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "столбец %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "столбец %(index)d из %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Конец столбца." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Начало столбца." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Выделен столбец %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Выбраны столбцы с %s по %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Снято выделение столбцов с %s по %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Снято выделение столбца %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "строка %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "строка %(index)d из %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Начало строки." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Конец строки." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Строка удалена." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Последняя строка удалена." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Строка вставлена." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Строка вставлена в конец таблицы." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Выделена строка %s" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Выделены строки с %s по %s" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Снято выделение строк с %s по %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Снято выделение строки %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "выделен" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "не выделен" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H часов, %M минут и %S секунд" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H часов и %M минут" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Юникод %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "отмена" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "повтор" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu версия %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "пробел" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Продолжение с конца." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Продолжение с начала." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 элементов" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Ячейка занимает %d строку" -msgstr[1] "Ячейка занимает %d строки" -msgstr[2] "Ячейка занимает %d строк" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d столбец" -msgstr[1] " %d столбца" -msgstr[2] " %d столбцов" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Ячейка занимает %d столбец" -msgstr[1] "Ячейка занимает %d столбца" -msgstr[2] "Ячейка занимает %d столбцов" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d символ это слишком много" -msgstr[1] "%d символа это слишком много" -msgstr[2] "%d символов это слишком много" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d диалог)" -msgstr[1] "(%d диалога)" -msgstr[2] "(%d диалогов)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d неактивный диалог" -msgstr[1] "%d неактивных диалога" -msgstr[2] "%d неактивных диалогов" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d байт" -msgstr[1] "%d байта" -msgstr[2] "%d байт" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d файл найден" -msgstr[1] "%d файла найдено" -msgstr[2] "%d файлов найдено" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d форма" -msgstr[1] "%d формы" -msgstr[2] "%d форм" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d заголовок" -msgstr[1] "%d заголовка" -msgstr[2] "%d заголовков" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d элемент" -msgstr[1] "%d элемента" -msgstr[2] "%d элементов" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d ориентир" -msgstr[1] "%d ориентира" -msgstr[2] "%d ориентиров" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "Найден %d элемент" -msgstr[1] "Найдено %d элемента" -msgstr[2] "Найдено %d элементов" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Выход из %d блока цитирования." -msgstr[1] "Выход из %d блоков цитирования." -msgstr[2] "Выход из %d блоков цитирования." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Выход из %d списка." -msgstr[1] "Выход из %d списков." -msgstr[2] "Выход из %d списков." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Список неизвестного размера" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Список с %d элементом" -msgstr[1] "Список с %d элементами" -msgstr[2] "Список с %d элементами" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Лента неизвестного размера" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Лента с %d статьей" -msgstr[1] "Лента с %d статьями" -msgstr[2] "Лента с %d статьями" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Список описаний с %d элементом" -msgstr[1] "Список описаний с %d элементами" -msgstr[2] "Список описаний с %d элементами" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d значение" -msgstr[1] "%d значения" -msgstr[2] "%d значений" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "математическая таблица с %d строкой" -msgstr[1] "математическая таблица с %d строками" -msgstr[2] "математическая таблица с %d строками" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d столбец" -msgstr[1] "%d столбца" -msgstr[2] "%d столбцов" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "вложенная математическая таблица с %d строкой" -msgstr[1] "вложенная математическая таблица с %d строками" -msgstr[2] "вложенная математическая таблица с %d строками" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d сообщение.\n" -msgstr[1] "%d сообщения.\n" -msgstr[2] "%d сообщений.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d процент." -msgstr[1] "%d процента." -msgstr[2] "%d процентов." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "Прочитан %d процент документа" -msgstr[1] "Прочитано %d процента документа" -msgstr[2] "Прочитано %d процентов документа" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d пиксел" -msgstr[1] "%d пиксела" -msgstr[2] "%d пикселов" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d символ %(repeatChar)s" -msgstr[1] "%(count)d символа %(repeatChar)s" -msgstr[2] "%(count)d символов %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d из %(total)d элемента выделено" -msgstr[1] "%(index)d из %(total)d элементов выделено" -msgstr[2] "%(index)d из %(total)d элементов выделено" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Найдено %d клавиатурное сокращение по умолчанию." -msgstr[1] "Найдено %d клавиатурных сокращения по умолчанию." -msgstr[2] "Найдено %d клавиатурных сокращений по умолчанию." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Найдено %(count)d клавиатурное сокращение для приложения %(application)s." -msgstr[1] "" -"Найдено %(count)d клавиатурных сокращения для приложения %(application)s." -msgstr[2] "" -"Найдено %(count)d клавиатурных сокращений для приложения %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d пробел" -msgstr[1] "%d пробела" -msgstr[2] "%d пробелов" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d символ табуляции" -msgstr[1] "%d символа табуляции" -msgstr[2] "%d символов табуляции" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d таблица" -msgstr[1] "%d таблицы" -msgstr[2] "%d таблиц" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "таблица неизвестного размера" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "таблица с %d столбцом, количество строк неизвестно" -msgstr[1] "таблица с %d столбцами, количество строк неизвестно" -msgstr[2] "таблица с %d столбцами, количество строк неизвестно" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "таблица с %d строкой, количество столбцов неизвестно" -msgstr[1] "таблица с %d строками, количество столбцов неизвестно" -msgstr[2] "таблица с %d строками, количество столбцов неизвестно" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "таблица с %d строкой" -msgstr[1] "таблица с %d строками" -msgstr[2] "таблица с %d строками" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d секунду назад" -msgstr[1] "%d секунды назад" -msgstr[2] "%d секунд назад" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d минуту назад" -msgstr[1] "%d минуты назад" -msgstr[2] "%d минут назад" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d час назад" -msgstr[1] "%d часа назад" -msgstr[2] "%d часов назад" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d день назад" -msgstr[1] "%d дня назад" -msgstr[2] "%d дней назад" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d непосещённая ссылка" -msgstr[1] "%d непосещённых ссылки" -msgstr[2] "%d непосещённых ссылок" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d посещённая ссылка" -msgstr[1] "%d посещённых ссылки" -msgstr[2] "%d посещённых ссылок" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "переключить" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "на %(index)d в %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d в %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "элемент %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "УРОВЕНЬ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "уровень дерева %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "УРОВЕНЬ ДЕРЕВА %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "детали для %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "есть детали в %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "совет" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "редактируемое поле со списком" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "редактируемое содержимое" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "лента" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "рисунок" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "аннотация" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "список благодарностей" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "послесловие" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "приложение" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "библиографическая запись" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "библиография" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "глава" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "выходные данные" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "заключение" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "обложка" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "упоминание" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "упоминания" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "посвящение" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "концевая сноска" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "концевые сноски" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "эпиграф" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "эпилог" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "список опечаток" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "пример" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "предисловие" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "глоссарий" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "указатель" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "введение" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "разрыв страницы" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "список страниц" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "часть" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "вступление" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "пролог" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "цитата" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Вопросы и ответы" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "подзаголовок" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "содержание" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "заг%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s уровень %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "горизонтальная полоса прокрутки" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "вертикальная полоса прокрутки" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "горизонтальный ползунок" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "вертикальный ползунок" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "горизонтальный разделитель" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "вертикальный разделитель" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "переключатель" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Область значков" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "баннер" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "дополнительное содержимое" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "сведения" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "основное содержание" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "навигация" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "область" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "поиск" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "посещённая ссылка" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "кнопка меню" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "отсортировано по возрастанию" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "отсортировано по убыванию" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "отсортировано" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "можно нажать" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "свёрнуто" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "расширено" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "есть подробное описание" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "горизонтальная" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "вертикальная" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "отмечено" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "не отмечено" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "включено" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "отключено" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "частично отмечено" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "нажато" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "не нажато" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "не выбрано" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "выбрано" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "не выбрано" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "не выделено" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "посещённая" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "непосещённая" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "неактивно" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "только для чтения" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "только чтен" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "необходимо заполнить" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "множественное выделение" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "неверный ввод" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "неверный" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "неверное написание" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "правописание" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "неверная грамматика" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "грамматика" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Найти" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Диалоговое окно поиска" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Закрыть" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Найти" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "Ис_кать:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Искать:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Вершина окна" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Вершины окна" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Начать от:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Автоматически переходить к _началу" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Искать _назад" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Направление поиска:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Учитывать _регистр" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Искать только _полные слова" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Параметры:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "По умолчанию" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Прописная" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Гиперссылка" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Система" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Приложение" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Окно" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Настройки Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Справка" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Применить" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Ноутбук" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Раскладка клавиатуры" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Текущий профиль:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Начальный профиль:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Загрузить" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Сохранить _как" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Удалить" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Профили" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Представлять всплывающие подсказки" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Озвучивать объект под указателем _мыши" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Мышь" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Формат времени:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Формат _даты:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Время и дата" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Произносить _обновления" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Отображать обновления в Брайле" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Частота (сек):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Применяется к:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Нарастающие звуковые сигналы при обновлениях индикатора выполнения" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Обновления индикатора выполнения" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Включить _перемотку назад и вперёд в «Читать всё»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Включить _структурную навигацию в «Читать всё»" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Читать всё п_о:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Уведомлять о _блоках цитирования в «Читать всё»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Уведомлять о _списках в «Читать всё»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Уведомлять о _таблицах в «Читать всё»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Уведомлять о _панелях в «Читать всё»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Уведомлять о _формах в «Читать всё»" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Уведомлять об _ориентирах в «Читать всё»" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Читать всё" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Представление элемента:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Общие" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Г_ромкость:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Высота _тона:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Темп:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Голос:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Язык:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "_Синтезатор речи:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Система _поддержки речи:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Тип _голоса:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Стиль прописных букв:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Параметры типа голоса" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Произносить по сл_овам строки со смешанным регистром" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Произносить _числа цифрами" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Общие голосовые параметры" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Голос" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Включить речь" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Подробно" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Информативность" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Всё" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Пунктуация" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Произносить только показанный на экране текст" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Произносить пустые строки" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Сообщать отступы и _выравнивания" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Сооб_щать мнемоники объектов" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Сообщать дочернее поло_жение" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Произносить сообщения для обучения" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Подробные системные сообщения" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Произносить цвета как _названия" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Уведомлять о блоках _цитирования при навигации" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Уведомлять о _списках при навигации" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Уведомлять о _таблицах при навигации" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Произносить _указатель слов с ошибками" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Уведомлять о _панелях при навигации" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Уведомлять об _ориентирах при навигации" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Уведомлять о _формах при навигации" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Произносить _описание" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Произносить строку в _электронных таблицах полностью" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Произносить строку в таблицах _документов полностью" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Произносить строку в таблицах _графического интерфейса полностью" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Речевой контекст" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Речь" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Включить _поддержку Брайля" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Сокращённое _назначение" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Выключить символ _конца строки" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Таблица _сокращений:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Включить брайлевскую кратк_опись" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Включить _перенос по словам" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Параметры отображения" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Нет" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Индикатор выделения" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Индикатор гиперссылки" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Включить _быстрые сообщения" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Длительно_сть (в секундах):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Сообщения отображаются _до закрытия пользователем" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Подробные _сообщения" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Параметры быстрых сообщений" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Брайль" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Включить _озвучивание клавиш" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Включить озвучивание _буквенных клавиш" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Включить озвучивание _цифровых клавиш" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Включить озвучивание клавиш _пунктуации" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Включить о_звучивание пробелов" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Включить озвучивание клавиш-_модификаторов" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Включить озвучивание _функциональных клавиш" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Включить озвучивание клавиш _действий" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Включить озвучивание клавиш _навигации" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Включить озвучивание по _словам" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Включить озвучивание по п_редложениям" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Озвучивание" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Клавиши-_модификаторы:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Привязки клавиш" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Словарь произношений" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Н_овое поле" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Удалить" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Произношение" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Произносить _всё" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Не произносить" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Сбросить" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Атрибуты текста" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Переместить в к_онец" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Переместить ни_же" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Переместить выш_е" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Переместить в _начало" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Подправить выделенные атрибуты" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Индикатор Брайля" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Атрибуты текста" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Включить ИИ-помощника" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Поставщик:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Локальный - Бесплатно)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Файл ключа _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Путь к файлу ключа API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Получить ключ API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Открыть браузер для получения ключа API Claude и автоматического сохранения" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Требовать подтверждение перед действиями ИИ" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Модель Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Название модели для Ollama (напр. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Конечная точка Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL конечной точки API Ollama (напр. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Качество снимка экрана:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Низкое" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Среднее" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Высокое" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "ИИ-помощник" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Код _языка:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Масштаб_ный коэффициент:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Изображение в _оттенках серого" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Инвертировать изображение" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Чёрно-белое изображение" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Порог чёрного/белого:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Анализировать цвета" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Копировать результаты в _буфер обмена" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : альфа, b : браво, c : чарли, d : дельта, e : ехо, f : фокстрот, g : " -"гольф, h : хотель, i : индия, j : джульет, k : кило, l : лима, m : майк, n : " -"ноябрь, o : оскар, p : папа, q : квебек, r : ромео, s : сиерра, t : танго, " -"u : униформа, v : виктор, w : виски, x : икс, y : янки, z : зулу, а : анна, " -"б : борис, в : василий, г : галина, д : дмитрий, е : елена, ё : ёж, ж : жук, " -"з : зинаида, и : иван, й : иван краткий, к : константин, л : леонид, м : " -"мария, н : николай, о : ольга, п : павел, р : роман, с : сергей, т : тамара, " -"у : ульяна, ф : фёдор, х : харитон, ц : центр, ч : человек, ш : шура, щ : " -"щука, ъ : твёрдый знак, ы : еры, ь : мягкий знак, э : эхо, ю : юлия, я : яков" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "цвет фона" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "фон в высоту строки" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "рисунок фона" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "направление" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "редактируемый" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "семейство шрифтов" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "цвет символов" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "рисунок символов" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "стиль шрифта" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "отступ" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "ошибка" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "невидимый" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "выравнивание" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "язык" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "левая граница" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "высота строки" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "стиль параграфа" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "точек над строками" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "точек под строками" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "точек между перенесённым текстом" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "правая граница" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "подъём" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "масштаб" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "размер" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "сжатие" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "перечёркивание" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "начертание" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "оформление" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "вращение" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "тень" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "подчёркивание" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "вариант" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "вертикальное выравнивание" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "вес" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "режим переноса" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "направление" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "включено" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "выключено" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "отсутствует" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "впечатанный" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "выпуклый" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "очертания" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "надчёркнутый" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "зачёркнутый" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "мигающий" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "чёрный" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "одиночное" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "двойное" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "нижнее" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "по символу" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "по слову" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "по слову по символу" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "слева направо" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "справа налево" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "по левому краю" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "по правому краю" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "по центру" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "без выравнивания" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "по ширине" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "очень сильно сжатый" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "сильно сжатый" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "сжатый" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "немного сжатый" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "обычный" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "немного расширенный" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "расширенный" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "сильно расширенный" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "очень сильно расширенный" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "уменьшенные заглавные" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "скошенный" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "курсив" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "По умолчанию" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Текст" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Заголовок" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "по основанию" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "нижний индекс" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "верхний индекс" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "верх" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "верх текста" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "середина" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "низ" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "низ текста" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "по наследству" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "слева направо и сверху вниз" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "справа налево и сверху вниз" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "сверху вниз и справа налево" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "сверху вниз и слева направо" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "снизу вверх и справа налево" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "снизу вверх и слева направо" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "слева направо" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "справа налево" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "сверху вниз" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "сплошное" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "правописание" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Нажмите пробел для переключения." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Нажмите пробел для раскрытия списка, используйте клавиши со стрелками вверх " -"и вниз для выбора элемента." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Нажмите Alt и F6 для перехода в дочернее окно." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Для перемещения к элементу используйте клавиши со стрелками или поиск по " -"мере набора." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Для перехода в системное меню нажмите комбинацию Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Используйте клавиши со стрелками вверх и вниз для выбора элемента." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Чтобы свернуть, нажмите Shift + клавиша со стрелкой влево." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Чтобы раскрыть, нажмите Shift + клавиша со стрелкой вправо." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Для активации нажмите пробел." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Вводите текст." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" -"Используйте клавиши со стрелками влево и вправо для перехода на другие " -"вкладки." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Для активации нажмите пробел." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Используйте клавиши со стрелками вверх и вниз для выбора значения. Или " -"введите требуемое число." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Для изменения используйте клавиши со стрелками." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Для перемещения используйте клавиши со стрелками влево и вправо. Для выбора " -"элемента — клавиши со стрелками вверх и вниз." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Для перехода в подменю нажмите клавишу со стрелкой вправо." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Для уменьшения значения нажмите клавишу со стрелкой влево, для увеличения — " -"вправо. Для установки минимального значения нажмите Home, для максимального " -"— End." diff --git a/po/rw.po b/po/rw.po deleted file mode 100644 index eced17b..0000000 --- a/po/rw.po +++ /dev/null @@ -1,9995 +0,0 @@ -# translation of cthulhu to Kinyarwanda. -# Copyright (C) 2005 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# Steve Murphy , 2005 -# Steve performed initial rough translation from compendium built from translations provided by the following translators: -# Philibert Ndandali , 2005. -# Viateur MUGENZI , 2005. -# Noëlla Mupole , 2005. -# Carole Karema , 2005. -# JEAN BAPTISTE NGENDAHAYO , 2005. -# Augustin KIBERWA , 2005. -# Donatien NSENGIYUMVA , 2005.. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2005-03-31 20:55-0700\n" -"Last-Translator: Steve Murphy \n" -"Language-Team: Kinyarwanda \n" -"Language: rw\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -msgid "Cthulhu Screen Reader" -msgstr "" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -#, fuzzy -msgid "anim" -msgstr "Iyega" - -#: src/cthulhu/braille_rolenames.py:57 -#, fuzzy -msgid "arw" -msgstr "Akambi" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -#, fuzzy -msgid "clrchsr" -msgstr "Ibara" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -#, fuzzy -msgid "colhdr" -msgstr "Inkingi Umutwempangano" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -# starmath/source\smres.src:RID_TOOLBOXWINDOW.6.RID_DOTX.text -#: src/cthulhu/braille_rolenames.py:85 -#, fuzzy -msgid "dat" -msgstr "Akadomo" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -#, fuzzy -msgid "icn" -msgstr "Agashushondanga" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -#, fuzzy -msgid "frm" -msgstr "ikadiri" - -# basctl/source\basicide\basidesh.src:RID_STR_STDDIALOGNAME.text -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "Ikiganiro" - -# basctl/source\basicide\basidesh.src:RID_STR_STDDIALOGNAME.text -#: src/cthulhu/braille_rolenames.py:100 -#, fuzzy -msgid "dlg" -msgstr "Ikiganiro" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Common.xcs:....Image.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Enable.text -#: src/cthulhu/braille_rolenames.py:142 -#, fuzzy -msgid "img" -msgstr "Ishusho" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -#, fuzzy -msgid "lbl" -msgstr "Akarango" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -# offmgr/source\offapp\dialog\hyprlink.src:RID_SVXDLG_HYPERLINK.BTN_INSERT_BOOKMARK.text -#: src/cthulhu/braille_rolenames.py:154 -#, fuzzy -msgid "lnk" -msgstr "Ihuza" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFont.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCJK.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCTL.List.text -#: src/cthulhu/braille_rolenames.py:157 -#, fuzzy -msgid "lst" -msgstr "Urutonde" - -#: src/cthulhu/braille_rolenames.py:160 -#, fuzzy -msgid "lstitm" -msgstr "Ibigize by'ilisiti" - -# #-#-#-#-# sfx2.pot (PACKAGE VERSION) #-#-#-#-# -# sfx2/source\dialog\cfg.src:DLG_CONFIG.1.TP_CONFIG_MENU.text -# #-#-#-#-# sfx2.pot (PACKAGE VERSION) #-#-#-#-# -# sfx2/source\dialog\cfg.src:STR_MENU.text -#: src/cthulhu/braille_rolenames.py:163 -#, fuzzy -msgid "mnu" -msgstr "Ibikubiyemo" - -# LOCALIZATION NOTE END : DO not localize the entities above; test case -#: src/cthulhu/braille_rolenames.py:166 -#, fuzzy -msgid "mnubr" -msgstr "Umurongo w'ibikubiyemo" - -#: src/cthulhu/braille_rolenames.py:169 -#, fuzzy -msgid "mnuitm" -msgstr "Ibikubiyemo Ikintu" - -#: src/cthulhu/braille_rolenames.py:172 -#, fuzzy -msgid "optnpn" -msgstr "Ihitamo" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFont.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCJK.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCTL.List.text -#: src/cthulhu/braille_rolenames.py:178 -#, fuzzy -msgid "tblst" -msgstr "Urutonde" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -#, fuzzy -msgid "popmnu" -msgstr "Ibikubiyemo" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -#, fuzzy -msgid "rdmnuitm" -msgstr "Ibikubiyemo Ikintu" - -#: src/cthulhu/braille_rolenames.py:202 -#, fuzzy -msgid "rtpn" -msgstr "Imizi" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -#, fuzzy -msgid "rwhdr" -msgstr "Urubariro Umutwempangano" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Table.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Frame.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Graphic.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Calc.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Draw.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Chart.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Formula.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Impress.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.OLEMisc.Settings.Delimiter.text -#: src/cthulhu/braille_rolenames.py:217 -#, fuzzy -msgid "seprtr" -msgstr "Mutandukanya" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -#, fuzzy -msgid "spltpn" -msgstr "Gutandukanya" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....DataSettings.CharacterEmphasis.text -#: src/cthulhu/braille_rolenames.py:229 -#, fuzzy -msgid "statbr" -msgstr "star" - -#: src/cthulhu/braille_rolenames.py:232 -#, fuzzy -msgid "tbl" -msgstr "Imbonerahamwe" - -#: src/cthulhu/braille_rolenames.py:235 -#, fuzzy -msgid "cll" -msgstr "Akarango" - -#: src/cthulhu/braille_rolenames.py:244 -#, fuzzy -msgid "tomnuitm" -msgstr "Ibikubiyemo Ikintu" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -#, fuzzy -msgid "tglbtn" -msgstr "Mukomatanya Akabuto" - -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....DataSettings.CharacterEmphasis.text -#: src/cthulhu/braille_rolenames.py:256 -#, fuzzy -msgid "tbar" -msgstr "star" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -#, fuzzy -msgid "trtbl" -msgstr "imbonerahamwe#" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND1_AND.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND2_AND.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND3_AND.text -#: src/cthulhu/braille_rolenames.py:274 -#, fuzzy -msgid "wnd" -msgstr "na" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Table.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Frame.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Graphic.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Calc.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Draw.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Chart.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Formula.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Impress.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.OLEMisc.Settings.Delimiter.text -#: src/cthulhu/braille_rolenames.py:283 -#, fuzzy -msgid "para" -msgstr "Mutandukanya" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:292 -#, fuzzy -msgid "edtbr" -msgstr "Guhindura" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -#, fuzzy -msgid "space" -msgstr "Umwanya" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -#, fuzzy -msgid "tab" -msgstr "Imbonerahamwe" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "" - -#: src/cthulhu/chnames.py:62 -#, fuzzy -msgid "quote" -msgstr "Gushyiraho akugarizo" - -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS1.SC_OPCODE_SQRT.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS1.SC_OPCODE_SIN.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS1.SC_OPCODE_TAN.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS1.SC_OPCODE_SIN_HYP.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS1.SC_OPCODE_TAN_HYP.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS1.SC_OPCODE_TRUNC.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS1.SC_OPCODE_ROUND.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS1.SC_OPCODE_ROUND_UP.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS1.SC_OPCODE_ROUND_DOWN.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_PHI.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_NORM_INV.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_S_NORM_INV.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_LOG_INV.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_GAMMA_INV.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_BETA_DIST.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_BETA_INV.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_T_INV.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_F_INV.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_CHI_INV.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_CHAR.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_TEXT.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_FIXED.2.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_LEFT.4.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_RIGHT.4.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_MID.6.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_REPT.4.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\scfuncs.src:RID_SC_FUNCTION_DESCRIPTIONS2.SC_OPCODE_BASE.2.text -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "umubare" - -# sc/source\core\src\compiler.src:RID_SC_FUNCTION_NAMES.SC_OPCODE_CURRENCY.text -#: src/cthulhu/chnames.py:70 -#, fuzzy -msgid "dollar" -msgstr "IDOLARI" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "ku ijana" - -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND1_AND.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND2_AND.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND3_AND.text -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "na" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "" - -#: src/cthulhu/chnames.py:86 -#, fuzzy -msgid "left paren" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/chnames.py:90 -#, fuzzy -msgid "right paren" -msgstr "Agasodeko Iburyo" - -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....DataSettings.CharacterEmphasis.text -#: src/cthulhu/chnames.py:94 -#, fuzzy -msgid "star" -msgstr "star" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -#, fuzzy -msgid "plus" -msgstr "Guteranya" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_COMMA.text -#: src/cthulhu/chnames.py:102 -#, fuzzy -msgid "comma" -msgstr "Akitso" - -# officecfg/registry\schema\org\openoffice\Office\Common.xcs:....Font.UnderLine..5.text -#: src/cthulhu/chnames.py:106 -#, fuzzy -msgid "dash" -msgstr "AKANYEREZO" - -# starmath/source\smres.src:RID_TOOLBOXWINDOW.6.RID_DOTX.text -#: src/cthulhu/chnames.py:110 -#, fuzzy -msgid "dot" -msgstr "Akadomo" - -# officecfg/registry\schema\org\openoffice\Office\Common.xcs:....Font.Strikeout..5.text -#: src/cthulhu/chnames.py:114 -#, fuzzy -msgid "slash" -msgstr "AKARONGOKABERAMYE" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/chnames.py:118 -#, fuzzy -msgid "colon" -msgstr "Agashushondanga" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/chnames.py:122 -#, fuzzy -msgid "semicolon" -msgstr "Agashushondanga" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_LES.text -#: src/cthulhu/chnames.py:126 -#, fuzzy -msgid "less" -msgstr "Birutwa" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/chnames.py:134 -#, fuzzy -msgid "greater" -msgstr "Biruta" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "" - -# starmath/source\smres.src:RID_TOOLBOXWINDOW.6.RID_DOTX.text -#: src/cthulhu/chnames.py:142 -#, fuzzy -msgid "at" -msgstr "Akadomo" - -#: src/cthulhu/chnames.py:146 -#, fuzzy -msgid "left bracket" -msgstr "Agakubo Ibumoso" - -# officecfg/registry\schema\org\openoffice\Office\Common.xcs:....Font.Strikeout..5.text -#: src/cthulhu/chnames.py:150 -#, fuzzy -msgid "backslash" -msgstr "AKARONGOKABERAMYE" - -#: src/cthulhu/chnames.py:154 -#, fuzzy -msgid "right bracket" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/chnames.py:158 -#, fuzzy -msgid "caret" -msgstr "Ikimenyetso" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -#, fuzzy -msgid "left brace" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/chnames.py:174 -#, fuzzy -msgid "vertical bar" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/chnames.py:178 -#, fuzzy -msgid "right brace" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -#, fuzzy -msgid "tilde" -msgstr "Imbonerahamwe" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "Umwanya" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -#, fuzzy -msgid "cents" -msgstr "ku ijana" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -# LOCALIZATION NOTE END : DO not localize the entities above; test case -#: src/cthulhu/chnames.py:211 -#, fuzzy -msgid "broken bar" -msgstr "Umurongo w'ibikubiyemo" - -#: src/cthulhu/chnames.py:215 -#, fuzzy -msgid "section" -msgstr "Ibiro Agashushondanga" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -#, fuzzy -msgid "left double angle bracket" -msgstr "Agakubo Ibumoso" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -# #-#-#-#-# sfx2.pot (PACKAGE VERSION) #-#-#-#-# -# sfx2/source\dialog\cfg.src:DLG_CONFIG.1.TP_CONFIG_MENU.text -# #-#-#-#-# sfx2.pot (PACKAGE VERSION) #-#-#-#-# -# sfx2/source\dialog\cfg.src:STR_MENU.text -#: src/cthulhu/chnames.py:271 -#, fuzzy -msgid "mu" -msgstr "Ibikubiyemo" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "" - -#: src/cthulhu/chnames.py:295 -#, fuzzy -msgid "right double angle bracket" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -#, fuzzy -msgid "one half" -msgstr "Ikintu" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -# svx/source\stbctrls\stbctrls.src:RID_SVXSTR_SELMODE_ER.text -#: src/cthulhu/chnames.py:383 -#, fuzzy -msgid "ETH" -msgstr "EXT" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -#, fuzzy -msgid "a tilde" -msgstr "Imbonerahamwe" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -#, fuzzy -msgid "n tilde" -msgstr "Imbonerahamwe" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -#, fuzzy -msgid "o tilde" -msgstr "Imbonerahamwe" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -# officecfg/registry\schema\org\openoffice\Office\Common.xcs:....Font.UnderLine..5.text -#: src/cthulhu/chnames.py:579 -#, fuzzy -msgid "en dash" -msgstr "AKANYEREZO" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -#, fuzzy -msgid "right single quote" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -# setup2/source\ui\pages\pipath.src:RESID_PAGE_PAGEINSTPATH.STR_FREE.text -#: src/cthulhu/chnames.py:625 -#, fuzzy -msgid "per mille" -msgstr "Bihari" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -#, fuzzy -msgid "check mark" -msgstr "Kugenzura... Ikintu" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -# sfx2/source\dialog\cfg.src:TP_CONFIG_STATBAR.GRP_STATBAR.text -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "Akarongo k'imimerere" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "Umutwe" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Mburabuzi" - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Mburabuzi" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "imbonerahamwe# Inkingi Umutwempangano" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "Mukomatanya Akabuto" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "Mukomatanya Akabuto" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_CHECKBOX.text -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Akazu k'ihitamo" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_COMBOBOX.text -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Akazu k'ilisiti irambuka" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "By'imbere Ikadiri" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "By'imbere Ikadiri" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Ibigize by'ilisiti" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -# svx/source\form\fmexpl.src:RID_FMSHELL_CONVERSIONMENU.SID_FM_CONVERTTO_RADIOBUTTON.text -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Buto Radiyo" - -# svx/source\form\fmexpl.src:RID_FMSHELL_CONVERSIONMENU.SID_FM_CONVERTTO_RADIOBUTTON.text -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "Buto Radiyo" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Table.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Frame.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Graphic.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Calc.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Draw.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Chart.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Formula.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Impress.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.OLEMisc.Settings.Delimiter.text -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "Mutandukanya" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "imbonerahamwe#" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "imbonerahamwe#" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "Mukomatanya Akabuto" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "Biruta" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Common.xcs:....Image.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Enable.text -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Ishusho" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "Biruta" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "Imbonerahamwe" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "Umwanya" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "Umwanya" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Agashushondanga" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "Urufunguzo Y Cyangwa N" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_COMMA.text -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "Akitso" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "Iyega" - -# setup2/source\ui\pages\pipath.src:RESID_PAGE_PAGEINSTPATH.STR_FREE.text -#: src/cthulhu/guilabels.py:296 -#, fuzzy -msgid "Braille Bindings" -msgstr "Bihari" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -#, fuzzy -msgid "_Desktop" -msgstr "Ibiro Agashushondanga" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "Akarango" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "Iyega" - -# sc/source\ui\src\optdlg.src:RID_SCPAGE_CONTENT.GB_WINDOW.text -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "Idirishya" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Gushyiraho akugarizo" - -# svx/sdi\svxslots.src:SID_FM_PUSHBUTTON.text -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Kanda Buto" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "Iyega" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_CHECKBOX.text -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Akazu k'ihitamo" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_COMBOBOX.text -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Akazu k'ilisiti irambuka" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "Ibiro Agashushondanga" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Urubariro Umutwempangano" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "By'imbere Ikadiri" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Common.xcs:....Image.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Enable.text -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Ishusho" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Akarango" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFont.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCJK.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCTL.List.text -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "Urutonde" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "Ibigize by'ilisiti" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "" - -# svx/source\form\fmexpl.src:RID_FMSHELL_CONVERSIONMENU.SID_FM_CONVERTTO_RADIOBUTTON.text -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Buto Radiyo" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Gushyiraho akugarizo" - -# svx/sdi\svxslots.src:SID_FM_PUSHBUTTON.text -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Kanda Buto" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_CHECKBOX.text -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Akazu k'ihitamo" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_COMBOBOX.text -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Akazu k'ilisiti irambuka" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "By'imbere Ikadiri" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Common.xcs:....Image.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Enable.text -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Ishusho" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFont.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCJK.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCTL.List.text -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "Urutonde" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "Ibigize by'ilisiti" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "" - -# svx/source\form\fmexpl.src:RID_FMSHELL_CONVERSIONMENU.SID_FM_CONVERTTO_RADIOBUTTON.text -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Buto Radiyo" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Imbonerahamwe" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "" - -# offmgr/source\offapp\dialog\hyprlink.src:RID_SVXDLG_HYPERLINK.BTN_INSERT_BOOKMARK.text -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Ihuza" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "ku ijana" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Ikimenyetso" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..0.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..0.text -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "ibumoso" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..0.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..0.text -#: src/cthulhu/keynames.py:64 -#, fuzzy -msgid "left alt" -msgstr "ibumoso" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..0.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..0.text -#: src/cthulhu/keynames.py:68 -#, fuzzy -msgid "left control" -msgstr "ibumoso" - -#: src/cthulhu/keynames.py:72 -#, fuzzy -msgid "right shift" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/keynames.py:76 -#, fuzzy -msgid "right alt" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/keynames.py:80 -#, fuzzy -msgid "right control" -msgstr "Agakubo Iburyo" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..0.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..0.text -#: src/cthulhu/keynames.py:84 -#, fuzzy -msgid "left meta" -msgstr "ibumoso" - -#: src/cthulhu/keynames.py:88 -#, fuzzy -msgid "right meta" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -# sfx2/source\view\framedlg.src:TP_FRAMEPROPERTIES.GB_SCROLLING.text -#: src/cthulhu/keynames.py:105 -#, fuzzy -msgid "scroll lock" -msgstr "Agafashagenda" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -#, fuzzy -msgid "page up" -msgstr "Umwanya" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -#, fuzzy -msgid "page down" -msgstr "Umwanya" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..0.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..0.text -#: src/cthulhu/keynames.py:145 -#, fuzzy -msgid "left tab" -msgstr "ibumoso" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "Umwanya" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "Umwanya" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..0.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..0.text -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "ibumoso" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "Agasodeko Iburyo" - -# #-#-#-#-# sfx2.pot (PACKAGE VERSION) #-#-#-#-# -# sfx2/source\dialog\cfg.src:DLG_CONFIG.1.TP_CONFIG_MENU.text -# #-#-#-#-# sfx2.pot (PACKAGE VERSION) #-#-#-#-# -# sfx2/source\dialog\cfg.src:STR_MENU.text -#: src/cthulhu/keynames.py:205 -#, fuzzy -msgid "menu" -msgstr "Ibikubiyemo" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND1_AND.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND2_AND.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND3_AND.text -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "na" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Umwanya" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "Akambi" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "Akambi" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_LES.text -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "Birutwa" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "Biruta" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -# starmath/source\smres.src:RID_TOOLBOXWINDOW.6.RID_DOTX.text -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "Akadomo" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "Guteranya" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Table.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Frame.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Graphic.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Calc.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Draw.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Chart.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Formula.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Impress.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.OLEMisc.Settings.Delimiter.text -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "Mutandukanya" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "Ihitamo" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Table.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Frame.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Graphic.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Calc.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Draw.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Chart.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Formula.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Impress.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.OLEMisc.Settings.Delimiter.text -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Mutandukanya" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "Ibiro Agashushondanga" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "By'imbere Ikadiri" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "Ihitamo" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "Imbonerahamwe" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "Imbonerahamwe" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "Imbonerahamwe" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_LES.text -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "Birutwa" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "Biruta" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "Biruta" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_LES.text -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "Birutwa" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "Biruta" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_LES.text -#: src/cthulhu/mathsymbols.py:1707 -#, fuzzy -msgctxt "math symbol" -msgid "not less than" -msgstr "Birutwa" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "Biruta" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "Biruta" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "Biruta" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "Agakubo Iburyo" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..0.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..0.text -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "ibumoso" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Common.xcs:....Image.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Enable.text -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "Ishusho" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "By'imbere Ikadiri" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Table.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Frame.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Graphic.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Calc.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Draw.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Chart.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Formula.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Impress.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.OLEMisc.Settings.Delimiter.text -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "Mutandukanya" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_LES.text -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "Birutwa" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "Biruta" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_LES.text -#: src/cthulhu/mathsymbols.py:2025 -#, fuzzy -msgctxt "math symbol" -msgid "very much less than" -msgstr "Birutwa" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:2028 -#, fuzzy -msgctxt "math symbol" -msgid "very much greater than" -msgstr "Biruta" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_LES.text -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "Birutwa" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "Biruta" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "Agasodeko Iburyo" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..0.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..0.text -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "ibumoso" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "Agakubo Ibumoso" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "Umwanya" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "Umwanya" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "Umwanya" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "Iyega" - -#: src/cthulhu/messages.py:48 -#, fuzzy -msgid "blank" -msgstr "Inyuma" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "OYA" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "Agashushondanga" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "Ibiro Agashushondanga" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "h" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "h" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -#, fuzzy -msgid "entire document selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -#, fuzzy -msgid "Dynamic column header cleared." -msgstr "imbonerahamwe# Inkingi Umutwempangano" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -# basctl/source\basicide\basidesh.src:RID_STR_STDDIALOGNAME.text -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "Ikiganiro" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "Ibikubiyemo" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "Ijambobanga... Umwandiko" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "Ipaji Kuri Gusoma" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND1_AND.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND2_AND.text -# #-#-#-#-# sc.pot (PACKAGE VERSION) #-#-#-#-# -# sc/source\ui\src\condfrmt.src:RID_SCDLG_CONDFORMAT.FT_COND3_AND.text -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "na" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "Imizi" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "Imizi" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "Imizi" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -# sw/source\ui\shells\shells.src:STR_SWBG_TABLE_CELL.text -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "Akazu k'imbonerahamwe" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "imbonerahamwe#" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Imbonerahamwe" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Imbonerahamwe" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "Iyega" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "Urubuga Ipaji Byanze" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "Urubuga Ipaji Byanze" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -# offmgr/source\offapp\dialog\hyprlink.src:RID_SVXDLG_HYPERLINK.BTN_INSERT_BOOKMARK.text -#: src/cthulhu/messages.py:1514 -#, fuzzy -msgid "link" -msgstr "Ihuza" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/messages.py:1518 -#, fuzzy -msgid "same page" -msgstr "Umwanya" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -# offmgr/source\offapp\dialog\hyprlink.src:RID_SVXDLG_HYPERLINK.BTN_INSERT_BOOKMARK.text -#: src/cthulhu/messages.py:1534 -#, fuzzy, python-format -msgid "%s link" -msgstr "Ihuza" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "imbonerahamwe#" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "Agashushondanga" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "OYA" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "a Inyandiko" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "imbonerahamwe#" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -#, fuzzy -msgid "No application has focus." -msgstr "Iyega" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "Mukomatanya Akabuto" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_CHECKBOX.text -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "Akazu k'ihitamo" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_COMBOBOX.text -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "Akazu k'ilisiti irambuka" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "By'imbere Ikadiri" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "Ibigize by'ilisiti" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -# svx/source\form\fmexpl.src:RID_FMSHELL_CONVERSIONMENU.SID_FM_CONVERTTO_RADIOBUTTON.text -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "Buto Radiyo" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Table.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Frame.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.WriterObject.Graphic.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Calc.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Draw.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Chart.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Image.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Formula.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.Impress.Settings.Delimiter.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....Insert.Caption.OfficeObject.OLEMisc.Settings.Delimiter.text -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "Mutandukanya" - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "imbonerahamwe#" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "Iyega" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "Inyobora:" - -#: src/cthulhu/messages.py:2013 -#, fuzzy -msgid "No notification messages" -msgstr "Ubutumwa bugera ako kanya" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "Ijambobanga... Umwandiko" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/messages.py:2051 -#, fuzzy -msgid "on" -msgstr "Agashushondanga" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_PROGRESSBAR.text -#: src/cthulhu/messages.py:2151 -#, fuzzy, python-format -msgid "Progress bar %d." -msgstr "Umurongo w'aho bigeze" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "Akarango" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Ijwi" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -#, fuzzy -msgid "Speech enabled." -msgstr "OYA" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "OYA" - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "OYA" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -#, fuzzy -msgid " dot dot dot" -msgstr "Akadomo Akadomo Akadomo" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -# sfx2/source\dialog\cfg.src:TP_CONFIG_STATBAR.GRP_STATBAR.text -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "Akarongo k'imimerere" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -# sw/source\ui\shells\shells.src:STR_SWBG_TABLE_CELL.text -#: src/cthulhu/messages.py:2389 -#, fuzzy -msgid "Speak cell" -msgstr "Akazu k'imbonerahamwe" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "Inkingi Umutwempangano" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, fuzzy, python-format -msgid "column %d" -msgstr "Inkingi Umutwempangano" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:2458 -#, fuzzy, python-format -msgid "row %d" -msgstr "Urubariro Umutwempangano" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:2517 -#, fuzzy -msgctxt "text" -msgid "selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:2521 -#, fuzzy -msgctxt "text" -msgid "unselected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/messages.py:2556 -#, fuzzy -msgid "white space" -msgstr "Umwanya" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -#, fuzzy -msgid "0 items" -msgstr "Ibigize by'ilisiti" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -# basctl/source\basicide\basidesh.src:RID_STR_STDDIALOGNAME.text -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "Ikiganiro" -msgstr[1] "Ikiganiro" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "Ibigize by'ilisiti" -msgstr[1] "Ibigize by'ilisiti" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Ibigize by'ilisiti" -msgstr[1] "Ibigize by'ilisiti" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "ku ijana" -msgstr[1] "ku ijana" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "Guteranya" -msgstr[1] "Guteranya" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -# sc/source\ui\dbgui\asciiopt.src:RID_SCDLG_ASCII.CKB_SPACE.text -#: src/cthulhu/messages.py:2808 -#, fuzzy, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "Umwanya" -msgstr[1] "Umwanya" - -#: src/cthulhu/messages.py:2813 -#, fuzzy, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "Ikintu" -msgstr[1] "Ikintu" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "Imbonerahamwe" -msgstr[1] "Imbonerahamwe" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "imbonerahamwe# Urubariro Umutwempangano" -msgstr[1] "imbonerahamwe# Urubariro Umutwempangano" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "Mukomatanya Akabuto" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, fuzzy, python-format -msgid "tree level %d" -msgstr "imbonerahamwe#" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "Ibiro Agashushondanga" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_COMBOBOX.text -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "Akazu k'ilisiti irambuka" - -# sw/source\ui\shells\shells.src:STR_SWBG_TABLE_CELL.text -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "Akazu k'imbonerahamwe" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "Agashushondanga" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "Iyega" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -#, fuzzy -msgctxt "role" -msgid "page break" -msgstr "Ipaji Isunika" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "Ipaji Isunika Urutonde" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "Gushyiraho akugarizo" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -# sfx2/source\view\framedlg.src:TP_FRAMEPROPERTIES.GB_SCROLLING.text -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "Agafashagenda" - -# sfx2/source\view\framedlg.src:TP_FRAMEPROPERTIES.GB_SCROLLING.text -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "Agafashagenda" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -#, fuzzy -msgid "Icon panel" -msgstr "Ihitamo" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Iyega" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Iyega" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "Buto Nkaragwa" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -# 2175 -#: src/cthulhu/object_properties.py:507 -#, fuzzy -msgid "expanded" -msgstr "cya/ byagutse" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -#, fuzzy -msgid "vertical" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "Ivivuwe" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "OYA Ivivuwe" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "Agashushondanga" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/object_properties.py:549 -#, fuzzy -msgctxt "radiobutton" -msgid "selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/object_properties.py:552 -#, fuzzy -msgctxt "radiobutton" -msgid "not selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "OYA Ivivuwe" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -# sw/source\ui\ribbar\inputwin.src:MN_CALC_POPUP.MN_POP_OPS.MN_CALC_GRE.text -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -#, fuzzy -msgid "grayed" -msgstr "Biruta" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -#, fuzzy -msgid "multi-select" -msgstr "OYA Ivivuwe" - -# sc/source\ui\src\globstr.src:RID_GLOBSTR.STR_INVALID.text -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "Sibyo" - -# sc/source\ui\src\globstr.src:RID_GLOBSTR.STR_INVALID.text -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "Sibyo" - -# sc/source\ui\src\globstr.src:RID_GLOBSTR.STR_INVALID.text -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "Sibyo" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "Kugenzura... Ikintu" - -# sc/source\ui\src\globstr.src:RID_GLOBSTR.STR_INVALID.text -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "Sibyo" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -# sc/source\ui\src\optdlg.src:RID_SCPAGE_CONTENT.GB_WINDOW.text -#: src/cthulhu/cthulhu-find.ui:166 -#, fuzzy -msgid "_Top of window" -msgstr "Idirishya" - -# sc/source\ui\src\optdlg.src:RID_SCPAGE_CONTENT.GB_WINDOW.text -#: src/cthulhu/cthulhu-find.ui:175 -#, fuzzy -msgid "Top of window" -msgstr "Idirishya" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Ihitamo" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:46 -#, fuzzy -msgid "Uppercase" -msgstr "ku ijana" - -# offmgr/source\offapp\dialog\hyprlink.src:RID_SVXDLG_HYPERLINK.BTN_INSERT_BOOKMARK.text -#: src/cthulhu/cthulhu-setup.ui:49 -#, fuzzy -msgid "Hyperlink" -msgstr "Ihuza" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "" - -# sc/source\ui\src\optdlg.src:RID_SCPAGE_CONTENT.GB_WINDOW.text -#: src/cthulhu/cthulhu-setup.ui:83 -#, fuzzy -msgid "Window" -msgstr "Idirishya" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -# setup2/source\ui\pages\pipath.src:RESID_PAGE_PAGEINSTPATH.STR_FREE.text -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Bihari" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -# basctl/source\basicide\tbxctl.src:RID_TOOLBOX.SID_INSERT_PROGRESSBAR.text -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "Umurongo w'aho bigeze" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2187 -#, fuzzy -msgid "Enable Braille _support" -msgstr "Ijwi Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -# offmgr/source\offapp\dialog\hyprlink.src:RID_SVXDLG_HYPERLINK.BTN_INSERT_BOOKMARK.text -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "Ihuza" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -# setup2/source\ui\pages\pipath.src:RESID_PAGE_PAGEINSTPATH.STR_FREE.text -#: src/cthulhu/cthulhu-setup.ui:2766 -#, fuzzy -msgid "Braille" -msgstr "Bihari" - -#: src/cthulhu/cthulhu-setup.ui:2780 -#, fuzzy -msgid "Enable _key echo" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "Ijwi Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2864 -#, fuzzy -msgid "Enable _modifier keys" -msgstr "Ijwi Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2879 -#, fuzzy -msgid "Enable _function keys" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2894 -#, fuzzy -msgid "Enable ac_tion keys" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2909 -#, fuzzy -msgid "Enable _navigation keys" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2965 -#, fuzzy -msgid "Enable echo by _word" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "Urufunguzo Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Intego- nyuguti" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Ijwi Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3204 -#, fuzzy -msgid "Pronunciation" -msgstr "Iyega" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "Ijwi Y Cyangwa N" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "Akambi" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "bushyinguro" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "Imbonerahamwe" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "Agasodeko Ibumoso" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "Agasodeko Iburyo" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "Ikimenyetso" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "imbonerahamwe# Umurongo" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..2.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..2.text -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "iburyo" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "imbonerahamwe# Umurongo" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -# offmgr/source\offapp\dialog\hyprlink.src:RID_SVXDLG_HYPERLINK.BTN_INSERT_BOOKMARK.text -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "Ihuza" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -#, fuzzy -msgctxt "textattr" -msgid "low" -msgstr "Akambi" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "Ijambobanga... Umwandiko" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFont.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCJK.List.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Writer.xcs:....DefaultFontCTL.List.text -#: src/cthulhu/text_attribute_names.py:459 -#, fuzzy -msgctxt "textattr" -msgid "ltr" -msgstr "Urutonde" - -#: src/cthulhu/text_attribute_names.py:466 -#, fuzzy -msgctxt "textattr" -msgid "rtl" -msgstr "imbonerahamwe#" - -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\DataAccess.xcs:....Column.Align..0.text -# #-#-#-#-# officecfg.pot (PACKAGE VERSION) #-#-#-#-# -# officecfg/registry\schema\org\openoffice\Office\Math.xcs:....StandardFormat.HorizontalAlignment..0.text -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "ibumoso" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "Agakubo Iburyo" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "ku ijana" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "" - -# sfx2/source\toolbox\tbxopdlg.src:TP_CONFIG_OBJECTBAR.STR_SYMBOL.text -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "Agashushondanga" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -# 2175 -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "cya/ byagutse" - -# 2175 -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "cya/ byagutse" - -# 2175 -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "cya/ byagutse" - -# 2175 -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "cya/ byagutse" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "Urubariro Umutwempangano" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "Imbonerahamwe" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "Kugenzura... Ikintu" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/si.po b/po/si.po deleted file mode 100644 index 97ce1e3..0000000 --- a/po/si.po +++ /dev/null @@ -1,9326 +0,0 @@ -# translation of cthulhu.po to Sinhala -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# -# Danishka Navin , 2007. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2007-08-20 12:29+0530\n" -"Last-Translator: Danishka Navin \n" -"Language-Team: Sinhala \n" -"Language: si\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: KBabel 1.11.4\n" - -msgid "Cthulhu Screen Reader" -msgstr "" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "ඩයල් කරනු" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -#, fuzzy -msgctxt "shortbraille" -msgid "form" -msgstr "පෝරමය" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "ඉඟිය" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "ස්වයංක්‍රීය" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "පටිත්ත" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "ඇල ඉර" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "වම් වරහන" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "පසු ඇල ඉර" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "දකුණු වරහන" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "වම් සඟල වරහන" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "සිරස් තීරුව" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "විකල්ප ලකුණ" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "අංශය" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "කතු හිමිකම" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "ලුහු යා ඉර" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:291 -#, fuzzy -msgid "ordinal" -msgstr "අග්‍රය" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "කෙටි ඉර" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "† ලකුණ" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "බුලටය" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "ලකුණ" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "තත්ව තීරුව" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "පහළ (_B):" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "දර්ශකයේ පිහිටීම" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "දර්ශකයේ පිහිටීම" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "රේඛාව" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "විකල්ප බොත්තම" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "ටොගල බොත්තම" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "සලකුණු කොටුව" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "සංයුක්ත කොටුව" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "විකල්ප බොත්තම" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "විකල්ප බොත්තම" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "අඳුරු" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "පිළිඹිබු" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "අඳුරු" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "පටිත්ත" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "කිසිවක් නැත" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "ප්‍රකෘතිය" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "අංශය" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "වෙනස් කළ" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "යටි ලියමන" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "සියළු (_A)" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "යෙදුම" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "කවුළුව" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "කිසිවක් නැත (_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "රේඛාව" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "බොත්තම" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "යටි ලියමන" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "සලකුණු කොටුව" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "සංයුක්ත කොටුව" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "යටි ලියමන" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "ශීර්ෂකය" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "පිළිඹිබු" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "ලේබලය" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "පුරුක" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "ලැයිස්තුව" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ලැයිස්තුව" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "ඡේදය" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "විකල්ප බොත්තම" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "තත්වය" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "පෙළ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "බොත්තම" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "සලකුණු කොටුව" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "සංයුක්ත කොටුව" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "පිළිඹිබු" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "පුරුක" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "ලැයිස්තුව" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "ඡේදය" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "විකල්ප බොත්තම" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "වගුව" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "ප්‍රකෘතිය" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "පුරුක" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "පසු ඇල ඉර" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "කතු හිමිකම" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "වම් සඟල වරහන" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "මෙනුව" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -#, fuzzy -msgid "delete" -msgstr "මකන්න (_D)" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "කෙටි ඉර" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "වම් සඟල වරහන" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "ඊතලය" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "වෙනකරනය" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "අංශය" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "විකල්ප ලකුණ" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "විකල්ප ලකුණ" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "විකල්ප ලකුණ" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "කෙටි ඉර" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "දකුණු වරහන" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "වම් වරහන" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "අංශය" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "අනුරුව" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "සිරස් තීරුව" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "වම් සඟල වරහන" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "වම් සඟල වරහන" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "වම් සඟල වරහන" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "වම් සඟල වරහන" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "වම් වරහන" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "දකුණු වරහන" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "බුලටය" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "යෙදුම" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "නිරූපකය" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "අංශය" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "කිසිවක් නැත" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "රහස්පදය" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "සිරස් තීරුව" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "වගුව" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "වගුව" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "වගුව" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "සජීවනය" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "පුරුක" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "කිසිවක් නැත" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "" - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "ටොගල බොත්තම" - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "සලකුණු කොටුව" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "" - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "සංයුක්ත කොටුව" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "" - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "විකල්ප බොත්තම" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "යටි ලියමන" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "පහළ (_B):" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "ඉහළ (_T):" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "රහස්පදය" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "සියළු (_A)" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "කිසිවක් නැත" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "තත්ව තීරුව" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "" - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "පික්සල" -msgstr[1] "පික්සල" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "තත්පර" -msgstr[1] "තත්පර" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "ටොගල බොත්තම" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "අංශය" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "සංයුක්ත කොටුව" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "අංශය" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "ලැයිස්තුව" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "රෝල් තීරුව" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "සිරස් තීරුව" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "සිරස් තීරුව" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "සිරස් තීරුව" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "සජීවිකරණය" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "සජීවිකරණය" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "බොත්තම" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "සලකුණු කොටුව" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "කිසිවක් නැත" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "අඳුරු" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "අවලංගු" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "අවලංගු" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "අවලංගු" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "අක්‍ෂර වින්‍යාසය පරීක්‍ෂා කරන්න" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "අවලංගු" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "සොයන්න" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "වසන්න" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "සොයන්න" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "සඳහා සොයන්න (_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "වටා එතුම (_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "පසුපසට සොයන්න" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "සඳහා සොයන්න (_S):" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "යටි ලියමන" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "ප්‍රකෘතිය" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "යෙදුම" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "කවුළුව" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "යෙදුම" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "සාමාන්‍ය" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "සියළු (_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Speech" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "කිසිවක් නැත (_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "මකන්න (_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "ප්‍රකෘති තත්වයට සකසන්න (_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "අංශය" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "වගුව" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -#, fuzzy -msgctxt "textattr" -msgid "justification" -msgstr "අංශය" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "ඡේදය" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "දකුණු සඟළ වරහන" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "දිනදසුන" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "සිරස් තීරුව" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "දකුණ (_R):" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "පුරුක" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "රහස්පදය" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "කතු හිමිකම" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -#, fuzzy -msgctxt "textattr" -msgid "condensed" -msgstr "තත්පර" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "තත්පර" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "ප්‍රකෘතිය" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "පෙළ" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "ශීර්ෂකය" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "නවතන්න" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "පහළ (_B):" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -#, fuzzy -msgctxt "textattr" -msgid "rl" -msgstr "Ctrl" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "පටිත්ත" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "අක්‍ෂර වින්‍යාසය පරීක්‍ෂා කරන්න" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/sk.po b/po/sk.po deleted file mode 100644 index c4663a5..0000000 --- a/po/sk.po +++ /dev/null @@ -1,9479 +0,0 @@ -# Slovak translation for cthulhu. -# Copyright (C) 2013 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Peter Mráz , 2013. -# Peter Vágner , 2016, 2018. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2018-09-12 12:18+0200\n" -"Last-Translator: Peter Vágner \n" -"Language-Team: slovenčina <>\n" -"Language: sk\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n" -"X-Generator: Gtranslator 2.91.7\n" - -msgid "Cthulhu Screen Reader" -msgstr "Ukončí čítačku obrazovky" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#  PK: kde sa to zobrazi? lebo nazov jazyku je malym, viackrat -# PM: zobrazuje sa to pri výbere druhu braillovho písma asi to má byť malým zmenil som -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "čeština plnopis" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "španielčina plnopis" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "kanadská francúzština skratkopis" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "francúzština skratkopis" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "lotyština plnopis" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "holandčina plnopis" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "nórčina" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "nórčina plnopis" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "nórčina skratkopis" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "nórčina stupeň 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "poľština plnopis" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "portugalčina plnopis" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "švédčina plnopis" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "arabčina plnopis" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "waleština plnopis" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "waleština skratkopis" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "nemčina" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "nemčina plnopis" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "nemčina skratkopis" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "angličtina skratkopis" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "angličtina plnopis" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "americká angličtina plnopis" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "americká angličtina skratkopis" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "kanadská francúzština plnopis" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "francúzština plnopis" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "gréčtina plnopis" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "hindčina plnopis" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "maďarský počítačový 8 bodový brail" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "maďarčina plnopis" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "maďarčina plnopis" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "taliančina plnopis" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "belgická holandčina plnopis" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "medzera" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nový riadok" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulátor" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "výkričník" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "úvodzovky" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "krížik" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolár" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percento" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ampersand" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "zátvorka" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "zatvoriť" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "hviezda" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "čiarka" - -# PM:tento znak sa volá HYPHEN-MINUS -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "spojovník" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "bodka" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "lomka" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dvojbodka" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "bodkočiarka" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "menší" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "rovná sa" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "väčší" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "otáznik" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "zavináč" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "hranatá zátvorka" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "opačná lomka" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "hranatá zatvoriť" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "vokáň" - -# http://www.rozhlas.sk/radio-slovensko/slovencina-na-slovicko/Podciarkovnik-nie-podtrznik?l=2&i=2038&p=8 -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "podčiarkovník" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "prízvuk" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "zložená zátvorka" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "zvislá čiara" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "zložená zatvoriť" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "vlnovka" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "tvrdá medzera" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "obrátený výkričník" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "libra" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "mena" - -# je to hovorené myslím ze yen by to nezvládlo poveda správne -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "prerušená zvislá čiara" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "paragraf" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "prehláska" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "kopirajt" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "horný index a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "dvojitá lomená zátvorka" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logický zápor" - -# PM: zalomiteľný spojovník= rozdeľovník slov -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "rozdeľovník" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrované" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "pruh nad" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "stupňov" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus mínus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "horný index 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "horný index 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "dĺžeň" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mí" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "označenie odseku" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "bodka v prostriedku" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "sédij" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "horný index 1" - -# PM: je to príznak poradovej číslovky u nás používame bodku, ako to preložiť neviem -# MČ: navrhujem niečo ako: „vporadí“, „pozíciz v rade“, alebo niečo podobné, ale veľmi záleži na tom ako sa to naozaj číta. -# PV: Analogicky ku horný index A je toto podľa unicode tabuľky horný index O. Keďže sa toto inak u nás bežne nevyskytuje, navrhujem horný index O -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "horný index o" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "dvojitá lomená zatvoriť" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "štvrtina" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "polovica" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tri štvrtiny" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "obrátený otáznik" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "dlhé a" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A S PRÍZVUKOM" - -# PM: nie som si isté či to neprekladať ako veľké dlhé a ale v originále to tiež nie je tak -# MČ: záleží od toho ako to naozaj vysloví. -# PM: v programe je nastavenie či sa má čítať veľkosť písmen -# MČ: tak by som to ponechal tak. Nech si môže používateľ nastaviť ako to chce. -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "DLHÉ A" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A S VOKÁŇOM" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A S VLNOVKOU" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "PREHLASOVANÉ A" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A S KRÚŽKOM" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "OTVORENÉ E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C SO SÉDIJ" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E S PRÍZVUKOM" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "DLHÉ E" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E S VOKÁŇOM" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "PREHLASOVANÉ E" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I S PRÍZVUKOM" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "DLHÉ I" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I S VOKÁŇOM" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "PREHLASOVANÉ I" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ED" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N S VLNOVKOU" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O S PRÍZVUKOM" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "DLHÉ O" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "UO" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O S VLNOVKOU" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "PREHLASOVANÉ O" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "krát" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "PREŠKRTNUTÉ O" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U S PRÍZVUKOM" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "DLHÉ U" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U S VOKÁŇOM" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "PREHLASOVANÉ U" - -# MČ: Neviem ako to vysloví, ale bol by som za ypsilon, aby to bolo rozlíšiteľné -# PM: skúšal som to v Orce zrejme to záleží od lokalizácie syntetizátora. Číta mi to ypsilon v slovenčine a uaj v angličtine -# PV: overené, takto by som to ponechal, správne to pri editácii slovenského textu so slovenským hlasom eSpeak číta "dlhé ypsilon" -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "DLHÉ Y" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "SORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "ostré s" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a s prízvukom" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a s vokáňom" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a s vlnovkou" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "prehlasované a" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a s krúžkom" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "otvorené e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c so sédij" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e s prízvukom" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "dlhé e" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e s vokáňom" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "prehlasované e" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i s prízvukom" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "dlhé i" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i s vokáňom" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "prehlasované i" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "ed" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n s vlnovkou" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o s prízvukom" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "dlhé o" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "uo" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o s vlnovkou" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "prehlasované o" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "deleno" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "preškrtnuté o" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "sorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "dlhé u" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u s prízvukom" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u s vokáňom" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "prehlasované u" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "dlhé y" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "prehlasované y" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "PREHLASOVANÉ Y" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florén" - -# PM: Pomlčka je dash, hyphen je spojovník, soft hyphen je rozdelovník, en dash je klasická pomlčka (v dĺžke písmena n), em dash je dlhá pomlčka (v dĺžke písmena m) -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "pomlčka" - -# MČ: V slovenčine sa táto používa ako pravá, ak sa nemýlim. -# PM: rozhodol som sa zmeniť preklad lebo toto sa číta pri stlačení klávesu a pri zápíse nejakého iného ako slovenského textu by z toho nevidiaci mohli byť zmätený -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "horné jednoduché úvodzovky" - -# MČ: Táto sa v slovenčine nevyužíva, neviem ako by sa mala nazývať, aby sa neplietla -# MČ: nezvýraznil si, ako pri ostatných, že ide o jednoduchú úvodzovku. Tak si to chcel? -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "odsuvník" - -# MČ: Táto sa používa v slovenčine ako ľavá, otváracia. -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "dolné jednoduché úvodzovky" - -# MČ: V slovenčine sa táto používa ako pravá, zatváracia. -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "horné úvodzovky" - -# MČ: Táto sa v slovenčine nevyužíva, neviem ako by sa mala nazývať, aby sa neplietla -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "dvojitá horná opačná úvodzovka" - -# MČ: Táto sa používa v slovenčine ako ľavá, otváracia. -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dolné úvodzovky" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "kríž" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dvojkríž" - -# MČ: najčastejší znak na odrážky býva pomlčka. Nemalo by sa zvýrazniť, že ide o guličku? -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "odrážka" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trojuhoľníková odrážka" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promile" - -# PM: toto je čiarka ktorá sa používa napríklad na označenie napríklad derivácie -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "" - -# PM: toto je čiarka ktorá sa používa napríklad na označenie napríklad dvojitej derivácie -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "triple prime" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "odrážka v tvare pomlčky" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "ochranná známka" - -# DK: nebude vhodnejsie "zaškrtnutie" ? -# PM: ide o to ako sa má ten znak prečítať a myslím že fajka je lepšia -# MČ: pozor, ale tuším existuje aj znak „fajka“, navrhujem „znak zašktnutia“ -# PM: to že ide o znak je jasné lebo sa to vysloví pri stlačení klávesu -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "zaškrtnutie" - -# DK: detto -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "tučné zaškrtnutie" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "odrážka v tvare x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "horný index 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "horný index 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "horný index 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "horný index 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "horný index 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "horný index 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "horný index 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "horný index plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "horný index mínus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "horný index rovná sa" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "horný index zátvorka" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "horný index zátvorka zatvoriť" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "horný index n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "dolný index 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "dolný index 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "dolný index 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "dolný index 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "dolný index 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "dolný index 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "dolný index 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "dolný index 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "dolný index 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "dolný index 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "dolný index plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "dolný index mínus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "dolný index rovná sa" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "dolný index zátvorka" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "dolný index zátvorka zatvoriť" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "čierny štvorec" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "čierny diamant" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "znak zastupuje objekt" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Premiestni kurzor myši na aktuálnu položku." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" -"Vykoná klik ľavým tlačidlom myši na aktuálnej položke plošného prezerania." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" -"Vykoná klik pravým tlačidlom myši na aktuálnej položke plošného prezerania." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Prečíta celý dokument." - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Prečíta obsah celého okna pomocou plošného prezerania." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Oznámi informácie o aktuálnom prvku." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Oznámi podrobné informácie o aktuálnom prvku." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Oznámi aktuálny výber." - -# GtkCheckButton -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Prečíta podrobnosti o odkaze." - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Prejde na nasledujúce tlačidlo." - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Oznámi stavový riadok." - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Oznámi názov okna." - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Otvorí Dialóg vyhľadávanie čítačky obrazovky." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Vyhľadá nasledujúci výskyt textu." - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Vyhľadá predchádzajúci výskyt textu." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Zapína a vypína režim plošného prezerania." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Premiestni plošné prezeranie na koniec textu." - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Premiestni plošné prezeranie na začiatok textu." - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Premiestni plošné prezeranie na koniec textu." - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Premiestni plošné prezeranie na začiatok predchádzajúceho riadku." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Oznámi aktuálny riadok plošného prezerania." - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Vyhláskuje aktuálny riadok plošného prezerania." - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Foneticky vyhláskuje aktuálny riadok plošného prezerania." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Premiestni plošné prezeranie na začiatok nasledujúceho riadku." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Premiestni plošné prezeranie na predchádzajúcu položku alebo slovo." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Oznámi aktuálnu položku alebo slovo plošného prezerania." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Vyhláskuje aktuálnu položku alebo slovo plošného prezerania." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Foneticky vyhláskuje aktuálnu položku alebo slovo plošného prezerania." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Premiestni plošné prezeranie na nasledujúcu položku alebo slovo." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Premiestni plošné prezeranie na slovo zobrazené nad aktuálnym slovom." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Oznámi aktuálny objekt plošného prezerania." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Premiestni plošné prezeranie na slovo zobrazené pod aktuálnym slovom." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Premiestni plošné prezeranie na predchádzajúci znak." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Oznámi aktuálny znak plošného prezerania." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Foneticky vyhláskuje aktuálny znak plošného prezerania." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" -"Oznámi číselnú hodnotu aktuálneho znaku plošného prezerania v systéme " -"unicode." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Premiestni plošné prezeranie na nasledujúci znak." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Premiestni plošné prezeranie na koniec riadku." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Premiestni plošné prezeranie do ľavého dolného rohu." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Skopíruje obsah plošného prezerania do schránky." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Pripojí obsah plošného prezerania za obsah v schránke." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Premiestni plošné prezeranie na koniec textu." - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Prepína oznamovanie buniek alebo celých riadkov pri navigácii v tabuľkách." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Oznámi vlastnosti aktuálneho znaku v texte." - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Posunie brailovský riadok doľava." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Posunie brailovský riadok vpravo." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Vráti plošné prezeranie na objekt zameraný z klávesnice." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Zapína alebo vypína skratkopis brailového písma." - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Spracuje smerové tlačidlo." - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Označí začiatok výberu textu." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Označí koniec výberu textu." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Zapína režim učenia. Stlačením klávesu escape môžete režim učenia vypnúť." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Znižuje tempo reči." - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Zvyšuje tempo reči." - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Znižuje výšku reči." - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Zvyšuje výšku reči." - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Zosilňuje hlasitosť reči." - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Zoslabuje hlasitosť reči." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Vyhľadá predchádzajúci výskyt textu." - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Cyklicky prechádza na nasledujúci profil nastavení." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Oznámi aktuálny výber." - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Oznámi aktuálny výber." - -# GtkLabel -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Nastavenia typu hlasu" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Zapína alebo vypína umlčanie hlasového výstupu." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Prepína úroveň výrečnosti." - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Prepína režim prezerania myšou." - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Ukončí čítačku obrazovky" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Zobrazí konfiguračný dialóg Nastavenia čítačky obrazovky." - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" -"Zobrazí konfiguračný dialóg Nastavenia čítačky obrazovky pre aktívnu " -"aplikáciu." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Prepína oznamovanie odsadenia a zarovnania textu." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Prepína spôsob vyslovovania čísiel." - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "" -"Cyklicky prechádza na nasledujúce nastavenie úrovne čítania interpunkcie." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Cyklicky prechádza na nasledujúce nastavenie odozvy klávesnice." - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Cyklicky prechádza na nasledujúci profil nastavení." - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Cyklicky prechádza na nasledujúci spôsob oznamovania veľkých písmen." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Cyklicky prechádza na nasledujúce nastavenie odozvy klávesnice." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Prepína úroveň ladenia počas behu." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Oznámi informácie o umiestnení záložky vzhľadom na aktuálnu pozíciu." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Prejde na miesto predchádzajúcej záložky." - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Prejde na záložku." - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Prejde na miesto nasledujúcej záložky." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Pridá záložku." - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Uloží záložky." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Prepína režim prezerania myšou." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Oznámi aktuálny čas." - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Oznámi aktuálny dátum." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Prepustí nasledujúci príkaz práve aktívnej aplikácii." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Oznámi predchádzajúcu správu v diskusnej miestnosti." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Prepína, či sa má oznamovať, že vaši priatelia píšu." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Prepína, či sa má poskytnúť história správ jednotlivých diskusných " -"miestností." - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "Prepína, či sa pred správy má pripojiť názov diskusnej miestnosti." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Posunúť doľava" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Posunúť doprava" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Posunúť hore" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Posunúť dole" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Zmraziť" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Ľavý horný roh" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Ľavý dolný roh" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Pozícia kurzora" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Šesť bodov" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Smerovanie kurzora" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Začiatok výberu" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Koniec výberu" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Zopakuje posledné oznámenie z lišty správ." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Zobrazí zoznam oznámení z lišty správ." - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Oznámi predchádzajúce oznámenie z lišty správ." - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Zopakuje posledné oznámenie z lišty správ." - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Prejde na nasledujúci znak." - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Prejde na predchádzajúci znak." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Prejde na nasledujúce slovo." - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Prejde na predchádzajúce slovo." - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Prejde do nasledujúceho riadku." - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Prejde do predchádzajúceho riadku." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Prejde na začiatok súboru." - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Prejde na koniec súboru." - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Prejde na začiatok riadku." - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Prejde na koniec riadku." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Prejde na nasledujúci objekt." - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Prejde na predchádzajúci objekt." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Rozbalí aktuálne kombinované pole." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Prepína medzi natívnym režimom navigácie kurzora a navigáciou čítačky " -"obrazovky." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" -"Prepína na nasledujúcu úroveň oznamovania automaticky obnovovaného obsahu." - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Vypína predvolenú úroveň oznamovania automaticky obnovovaného obsahu." - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Zopakuje oznámenie automaticky obnovovaného obsahu." - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Sledovať automaticky obnovovaný obsah." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" -"Prejde do alebo z objektu vysunutého po prechode myšou nad iným objektom." - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Nastaví riadok ako dynamické hlavičky stĺpca tabuľky." - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Vymaže dynamicky priradené hlavičky stĺpca tabuľky." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Nastaví stĺpec ako dynamické hlavičky riadku tabuľky." - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Vymaže dynamicky priradené hlavičky riadku tabuľky" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Oznámi obsah vstupného poľa." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Zapína a vypína klávesy štrukturálnej navigácie." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Prejde na predchádzajúcu citáciu" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Prejde na nasledujúcu citáciu" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Zobrazí zoznam citácií" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Prejde na predchádzajúce tlačidlo." - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Prejde na nasledujúce tlačidlo." - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Zobrazí zoznam tlačidiel." - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Prejde na predchádzajúce zaškrtávacie pole." - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Prejde na nasledujúce zaškrtávacie pole." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Zobrazí zoznam zaškrtávacích polí." - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Prejde na predchádzajúci klikateľný objekt." - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Prejde na nasledujúci klikateľný objekt." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Zobrazí zoznam klikateľných objektov." - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Prejde na predchádzajúce kombinované pole." - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Prejde na nasledujúce kombinované pole." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Prejde na začiatok kontajneru." - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Prejde na koniec kontajneru." - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Zobrazí zoznam kombinovaných polí." - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Prejde na predchádzajúci textový vstup." - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Prejde na nasledujúci textový vstup." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Zobrazí zoznam textových vstupov." - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Prejde na predchádzajúci prvok formulára." - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Prejde na nasledujúci prvok formulára." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Zobrazí zoznam prvkov formulára." - -# PV: nasledujúce typy prvkov sú už prekladané ako záhlavie v moduloch at-spi alebo gail. V skutočnosti sa jedná o nadpisy na webovej stránke

až
. -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Prejde na predchádzajúci nadpis." - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Prejde na nasledujúci nadpis." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Zobrazí zoznam nadpisov." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Prejde na predchádzajúci nadpis úrovne %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Prejde na nasledujúci nadpis úrovne %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Zobrazí zoznam nadpisov úrovne %d." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Prejde do predchádzajúcej tabuľky." - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Prejde do nasledujúcej tabuľky." - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Zobrazí zoznam tabuliek." - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Prejde na predchádzajúci obrázok." - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Prejde na nasledujúci obrázok." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Zobrazí zoznam obrázkov." - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Prejde do predchádzajúcej oblasti stránky" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Prejde do nasledujúcej oblasti stránky." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Zobrazí zoznam oblastí stránky." - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Prejde na predchádzajúci veľký objekt." - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Prejde na nasledujúci veľký objekt." - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Zobrazí zoznam veľkých objektov." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Prejde na predchádzajúci odkaz." - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Prejde na nasledujúci odkaz." - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Zobrazí zoznam odkazov." - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Prejde do predchádzajúceho zoznamu." - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Prejde do nasledujúceho zoznamu." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Zobrazí zoznam zoznamov." - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Prejde na predchádzajúcu položku zoznamu." - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Prejde na nasledujúcu položku zoznamu." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Zobrazí zoznam položiek zoznamu." - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Prejde do predchádzajúcej oblasti s automaticky obnovovaným obsahom." - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Prejde do nasledujúcej oblasti s automaticky obnovovaným obsahom." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" -"Prejde do oblasti kde sa nachádza naposledy zmenený automaticky obnovovaný " -"obsah." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Vráti plošné prezeranie na objekt zameraný z klávesnice." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Prejsť na prvého potomka objektu so zameraním navigátora." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Prejsť na nasledujúceho súrodenca objektu so zameraním navigátora." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Prejsť na predchádzajúceho súrodenca objektu so zameraním navigátora." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Vráti plošné prezeranie na objekt zameraný z klávesnice." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Zapína a vypína klávesy štrukturálnej navigácie." - -# PV: Nie som si istý či odsek alebo odstavec. Libreoffice používa odsek, Firefox a Thunderbird odsek -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Prejde do predchádzajúceho odseku." - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Prejde do nasledujúceho odseku." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Zobrazí zoznam odsekov." - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Prejde na predchádzajúce rádiové tlačidlo." - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Prejde na nasledujúce rádiové tlačidlo." - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Zobrazí zoznam rádiových tlačidiel." - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Prejde na predchádzajúci oddeľovač." - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Prejde na nasledujúci oddeľovač." - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Prejde do predchádzajúcej tabuľky." - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Prejde do nasledujúcej tabuľky." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Zobrazí zoznam tabuliek." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Prejde o bunku nižšie." - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Prejde do prvej bunky v tabuľke." - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Prejde do poslednej bunky v tabuľke." - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Prejde o bunku vľavo." - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Prejde o bunku do prava." - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Prejde o bunku vyššie." - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Prepína režim prezerania myšou." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Prepína medzi režimom zameriavania a režimom prehliadania." - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Zapína vynútený režim zameriavania." - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Zapína vynútený režim prehliadania." - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Prejde na predchádzajúci nenavštívený odkaz." - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Prejde na ďalší nenavštívený odkaz." - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Zobrazí zoznam nenavštívených odkazov." - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Prejde na predchádzajúci navštívený odkaz." - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Prejde na ďalší navštívený odkaz." - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Zobrazí zoznam navštívených odkazov." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antická biela" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarínová" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azúrová" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "béžová" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "polievková" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "čierna" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "mandľová" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "modrá" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "modrofialová" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "hnedá" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "červenomodrá" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "likérová" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "čokoládová" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koralová" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "nevädzová modrá" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "kukuricová" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "karmínová" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "modrozelená" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "tmavomodrá" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "tmavomodrozelená" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "tmavý zlatobyľ" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "tmavosivá" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "tmavozelená" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "tmavá khaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "tmavorozalínová" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "tmavoolivovozelená" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "tmavooranžová" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "tmavoorchideová" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "tmavočervená" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "tmavolososová" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "tmavozelenomodrá" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "tmavobridlicová modrá" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "tmavobridlicová sivá" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "tmavotyrkisová" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "tmavofialová" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "studená ružová" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "studená blankytná" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "kalná sivá" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "tehlová" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "kvetinová biela" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "jedľovo zelená" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksiová" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "našedlá" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "priesvitná biela" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "zlatá" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "zlatobyľ" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "sivá" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "zelená" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "zelenožltá" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "medovinová" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "teplá ružová" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indiánska červená" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigová" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "slonovinová" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "khaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "levanduľová" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "vínovočervená" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "trávovo zelená" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "lemon šifón" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "svetlomodrá" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "svetlokoralová" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "svetlomodrozelená" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "svetlozlatistá žltá" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "svetlosivá" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "svetlozelená" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "svetloružová" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "svetlolososová" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "svetlozelenomodrá" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "svetloblankytná" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "svetlobridlicová sivá" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "svetlooceľová modrá" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "svetložltá" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limetková" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limetkovozelená" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "ľanová" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "rozalínová" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "gaštanovočervená" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "stredná akvamarínová" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "stredná modrá" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "stredná orchideová" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "stredná purpurová" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "stredná zelenomodrá" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "stredná bridlicová modrá" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "stredná jarná zelená" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "stredná tyrkisová" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "Stredná fialovočervená" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "polnočná modrá" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "mätová krémová" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "jemná ružová" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokasínová" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "Navažská biela" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "námornícka modrá" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "telová" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olivová" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "olivová fádna" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oranžová" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "oranžovočervená" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orchideová" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "bledý zlatobyľ" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "bledozelená" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "bledotyrkisová" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "bledofialovočervená" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "broskiňová" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peruánska" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "ružová" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "slivková" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "sivomodrá" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "purpurová" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "červená" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "ružovohnedá" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "kráľovská modrá" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "sedlová hnedá" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "lososová" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "piesková hnedá" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "zelenomodrá" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "lastúrová" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "hlinená" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "strieborná" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "blankytná" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "bridlicová modrá" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "bridlicová sivá" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "snehová" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "jarná zelená" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "oceľovo modrá" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "žltohnedá" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "tmavá modrozelená" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "bodliaková" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "paradajková" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "tyrkisová" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "fialová" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "pšeničná" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "biela" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "biely dym" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "žltá" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "žltozelená" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktivovať" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automaticky aktivovať režim zameriavania počas štrukturálnej navigácie" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automaticky aktivovať režim zameriavania počas navigácie kurzorom" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automaticky aktivovať režim zameriavania počas navigácie kurzorom" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Bod _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Bod _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Body 7 _a 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Zrušiť" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Prejsť na" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Nič" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "hláskovanie" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Oznamovať, keď _priatelia píšu" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Poskytnúť históriu _správ jednotlivých diskusných miestností" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Oznamovať správy" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "zo všetkých _kanálov" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "zo všetkých kanálov, ak je niektoré okno _aplikácie %s aktívne" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "iba z kanála, ktorého _okno je aktívne" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "Oznamovať _názov diskusnej miestnosti" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Povoliť rozloženie ako na obrazovke" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dvojkliknutie" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trojkliknutie" - -# MČ: Neviem, či píšem správne, ale ide o syntézu reči, tak by som skôr povedal „syntezátor“, ale možno sa mýlim. I keď podľa slovníka by mali byť tie pojmy zameniteľné, ale „syntetizáror“ je podľa mňa nástroj na hranie hudby. -# PM: syntetizátor je podľa mňa nástroj na syntézu niečoho -# http://sk.wikipedia.org/wiki/Syntetiz%C3%A1tor -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Predvolený syntetizátor" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Pôvodný reťazec" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Nahradzujúci reťazec" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Povoliť odozvu po _znakoch" - -# PM: videl som to viac-krát takto nazvané -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Povoliť mŕtve klávesy s _diakritikou" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Aktuálnej pozícii" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimálna dĺžka zhodujúca sa s textom:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Možnosti Hľadania" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Čítať len rozdielne riadk_y počas vyhľadávania" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Automaticky čítať výsledky počas vy_hľadávania" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "čiarka" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Klávesová skratka" - -# PK: ako je to mozne, ved to ukazuje len na jeden riadok v kode -# PM: je to dynamicky generovaný súbor podla súboru ui -# na viacerých miestach -# *https://bugzilla.gnome.org/show_bug.cgi?id=686690 -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Predvolené" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "režim zápisu" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "paragraf" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Brailové skratky" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Uloží záložky." - -# GtkLabel -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Čas a dátum" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Prezeranie myšou povolené." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navigácia" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Bez klávesovej skratky" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Odchod z režimu plošného prezerania" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "hlavný obsah" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Zmenené" - -# GtkRadioButton -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Stolný počítač" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Oznámenie" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Prijaté" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Oznámenie" - -# dialog title -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Nastavenia čítačky obrazovky pre %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "V brail. písme" - -# PM: nie som si istý dúfam že som dobre pochopil komentár autorov -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Neuvádzať ak" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Hovoriť" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Uložiť profil ako Konflikt" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Konflikt používateľských profilov!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profil s názvom %s už existuje.\n" -"Aktualizovať tento existujúci profil s novými nastaveniami?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Načítať používateľský profil" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Chystáte sa zmeniť aktívny profil. Ak Ste\n" -"práve urobili zmeny v konfigurácii, tieto zmeny\n" -"budú načítaním profilu stratené..\n" -"\n" -"Načítať profil a zahodiť predchádzajúce zmeny?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Uložiť profil ako" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Názov profilu:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Načítať používateľský profil" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Všetko" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplikáciu" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Okno" - -# MČ: Nepasuje mi to tam, skôr by som dal „Žiadna“, ale nie ssom si istý ako to potom zosúladiť s ďalšími troma reťazcami. -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Nič" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "N_iečo" - -# MČ: máš rovnaký akcelerátor aj na „_Všetko“ -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Väčšina" - -# Hovoriť všetko po: -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Riadkoch" - -# Hovoriť všetko po: -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Vetách" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Citácia" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Tlačidlo" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Titulok" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Zaškrtávacie pole" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "klikateľné" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kombinované pole" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Popis" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Nadpis" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "vložené medzi" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Obrázok" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Označenie" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Oblasť stránky" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Úroveň" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Odkaz" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Zoznam" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Položka zoznamu" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekt" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Odsek" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Rádiové tlačidlo" - -# PV: všetky v tejto skupine kontextu sú typy prvkov. Odborne sa hovorý o object roles and states typoch a stavoch objektov. -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Typ prvku" - -# PM: akebo vybraná - neviem čo bude lepšie -# PV: Vybraná s významom aktívna alebo má fokus, pretože preklad označená predpokladá akciu, ktorou používateľ položku označí -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Vybratá položka" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stav" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Hodnota" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Citácie" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Tlačidlá" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Zaškrtávacie polia" - -# GtkLabel -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Klikateľné objekty" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kombinované polia" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Textové vstupy" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Prvky formulára" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Nadpisy" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "vložené medzi" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Obrázky" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Nadpisy úrovne %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Oblasti stránky" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Veľké objekty" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Odkazy" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Zoznamy" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Položky zoznamu" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Odseky" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Rádiové tlačidlá" - -# GtkLabel -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabuľky" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Nenavštívené odkazy" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Navštívené odkazy" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Navigácia na stránke" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Automaticky spustiť p_lynulé čítanie po načítaní stránky" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Prečítať súhrn hneď po načítaní stránky" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Roz_deliť reč na časti podľa prestávok" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Predvolený hlas %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Predvolený" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hypertext" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Systém" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Veľké písmená" - -# PM: Zvolil som takýto názov -# PV: chápem, že teraz sa dávajú aplikáciám univerzálne názvy napr. videá, fotky, mapy... toto ale každý pozná ako speech-dispatcher nezávisle na to, v akom jazyku sa hovorí. -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Zvýraznenie preklepov" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Hláskovať _chyby" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Hláskovať _návrhy" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Oznamovať _kontext chýb" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Oznamovať súradnice bunky" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Vždy hovoriť rozsah výberu buniek v hárku" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Oznamovať _hlavičku bunky" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Navigácia v tabuľke" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Preskakovať _prázdne bunky" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Hovoriť _bunky" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Oznamovať _súradnice bunky" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Oznamovať rozloženie cez viaceré bunky" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Názov atribútu" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Riadiť navigáciu kurzora" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Povoliť štrukturálnu navigáciu" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Zvuková _téma:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Zvuková téma" - -# PK: rod? -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Stručná" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Oznámenie" -msgstr[1] "Oznámenie" -msgstr[2] "Oznámenie" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Šift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Kontrol" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "ľavý šift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "ľavý alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ľavý kontrol" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "pravý šift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "pravý alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "pravý kontrol" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ľavý meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "pravý meta" - -# MČ: nie som si istý, či by sa tieto klávesy nemali preložiť. I keď je pravda, že sa to takto bežne používa. -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "nam lok" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "kaps lok" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "kaps lok" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "skrol lok" - -# MČ: tu už by som sa jednoznačne prihováral za preklad. Napr. „stránku vyššie“, alebo niečo podobné -# PK: som za to aby sa to ponechalo, je to takto napisane na klavesnici aj -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "pejdž ap" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "pejdž daun" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "bekspejs" - -# PM: tuším to v naších končinách nerozlišujeme -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "enter" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "hore" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "dole" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "doľava" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "doprava" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "ľavý super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "pravý super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "ponuka" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "Pomocník" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "iskejp" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "dilít" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "houm" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "bigin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "vokáň" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "krúžok" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "preškrtnutie" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "mínus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "tučné %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "kurzíva %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "tučné aj kurzíva %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "index %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "tučné index %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktúra %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "dvojitý obris %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "tučné fraktúra %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "bezpätkové %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "tučné bezpätkové %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "kurzíva bezpätkové %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "tučné kurzíva bezpätkové %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "s pevnou šírkou %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "bez bodky %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "šípka doľava" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "šípka hore" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "šípka doprava" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "šípka dolu" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "šípka zľava doprava" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "šípka hore dolu" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "šípka doľava hore" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "šípka doprava hore" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "šípka doprava dolu" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "šípka doľava od zarážky" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "šípka hore od zarážky" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "šípka doprava od zarážky" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "šípka dolu od zarážky" - -# MČ: V slovenčine sa táto používa ako pravá, zatváracia. -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dvojitá šípka doľava" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dvojitá šípka hore" - -# MČ: Táto sa v slovenčine nevyužíva, neviem ako by sa mala nazývať, aby sa neplietla -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dvojitá šípka doprava" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dvojitá šípka dolu" - -# MČ: Táto sa v slovenčine nevyužíva, neviem ako by sa mala nazývať, aby sa neplietla -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dvojitá šípka zľava doprava" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dvojitá šípka hore dolu" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dvojitá šípka doľava hore" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dvojitá šípka doprava hore" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dvojitá šípka doprava dolu" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dvojitá šípka doľava dolu" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "šípka ukazujúca doprava" - -# PM: aby sa to nemýlilo s inými šípkami -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "hrot šípky ukazujúcej vpravo" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "mínus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "menší než" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "väčší než" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "striežka" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "háčik" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "guľatý háčik" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "bodka" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "rovnobežne s" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "tri bodky" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "pre všetky" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "doplnok" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "parciálna derivácia" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "existuje" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "neexistuje" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "prázdna množina" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "prírastok" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "je prvkom" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "nie je prvkom" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "malé je prvkom" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "obsahuje ako člen" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "neobsahuje ako člen" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "malé obsahuje ako člen" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "koniec dôkazu" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "súčin" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "vedľajší súčin" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "súčet" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "plus mínus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus s bodkou" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "deliaca lomka" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "množinové mínus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "operátor hviezdička" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operátor krúžok" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operátor bodka" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "druhá odmocnina" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "tretia odmocnina" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "štvrta odmocnina" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "úmerné" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "nekonečno" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "pravý uhol" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "uhol" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "meraný uhol" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sférický uhol" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "delí" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "nedelí" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "rovnobežka" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "nerovnobežka" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logické a" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logické alebo" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "prienik" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "zjednotenie" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integrál" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dvojitý integrál" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "trojitý integrál" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "krivkový integrál" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "plošný integrál" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "objemový integrál" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integrál v smere hodinových ručičiek" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "krivkový integrál v smere hodinových ručičiek" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "krivkový integrál v proti smere hodinových ručičiek" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "preto" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "pretože" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "pomer" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporcia" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "mínus s bodkou" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "prevyšuje" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrická proporcia" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "rovnoľahlý" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "úmerné" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "opačná vlnovka" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "obrátené lenivé S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sínusovka" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "nie je úmerné" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "mínus vlnovka" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptoticky sa rovná" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "asymptoticky sa nerovná" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "približne sa rovná" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "približne ale nie úplne sa rovná" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ani približne ani úplne sa rovná" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "takmer úplne sa rovná" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "takmer približne sa nerovná" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "približne alebo úplne sa rovná" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "trojitá vlnovka" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "všetko sa rovná" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometricky ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "rozdieľ oproti" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "približuje sa k limitu" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometricky sa rovná" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "približne sa rovná alebo je obrazom" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "je obrazom alebo sa približne rovná" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dvojbodka rovná sa" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "rovná sa dvojbodka" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "krúžok v rovná sa" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "rovná sa s krúžkom" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "zodpovedá" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "odhaduje sa" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "má zhodné uhly" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "rovná sa s hviezdičkou" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "rovná sa s deltou" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "podľa definície sa rovná" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "merané podľa" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "rovná sa s otáznikom" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "nerovná sa" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "je identický" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "nie je identický" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "presne ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "menší alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "väčší alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "skôr menší ako sa rovná" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "skôr väčší ako sa rovná" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "menší ale nerovná sa" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "väčší ale nerovná sa" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "ešte menší" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "ešte väčší" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "medzi" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "nie je ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "nie je menší než" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "nie je väčší než" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ani menší ani sa nerovná" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ani väčší ani sa nerovná" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "menší než alebo ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "väčší než alebo ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ani menší ani ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ani väčší ani ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "menší alebo väčší" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "väčší alebo menší" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ani menší ani väčší" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ani väčší ani menší" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "predchádzajúci" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "nasledujúci" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "predchádzajúci alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "nasledujúci alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "predchádzajúci alebo ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "nasledujúci alebo ekvivalentný" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "nie je predchádzajúci" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "nie je nasledujúci" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "je podmnožina" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "je nadmnožina" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "nie je podmnožina" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "nie je nadmnožina" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "podmnožina alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "nadmnožina alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ani podmnožina ani sa nerovná" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ani nadmnožina ani sa nerovná" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "podmnožina a nerovná sa" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "nadmnožina a nerovná sa" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multimnožina" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "násobenie multimnožín" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "zjednotenie multimnožín" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "je štvorcový obraz" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "je štvorcový originál" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "štvorcový obraz alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "štvorcový originál alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "štvorcová čiapočka" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "štvorcová šálka" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "logický súčet" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "mínus v krúžku" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "krát v krúžku" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "deliaca lomka v krúžku" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "operátor bodka v krúžku" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "operátor krúžok v krúžku" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "operátor hviezdička v krúžku" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "rovná sa v krúžku" - -# PM: Pomlčka je dash, hyphen je spojovník, soft hyphen je rozdelovník, en dash je klasická pomlčka (v dĺžke písmena n), em dash je dlhá pomlčka (v dĺžke písmena m) -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "spojovník v krúžku" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus vo štvorčeku" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "mínus vo štvorčeku" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "krát vo štvorčeku" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "operátor bodka vo štvorčeku" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "pripojené zprava" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "pripojené zľava" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "pripojené zdola" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "pripojené zhora" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "tvrdenie" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modely" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "pravda" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "vynucuje" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "trojitá zvislá čiara so vstupom vpravo" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dvojitá zvislá čiara s dvojitým vstupom vpravo" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "nedokazuje" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "nepravda" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "nevynucuje" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "negovaná dvojitá zvislá čiara s dvojitým vstupom vpravo" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "predchádzajúci vo vzťahu" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "nasledujúci vo vzťahu" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "je normálna podskupina" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "obsahuje ako normálnu podskupinu" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normálna podskupina alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "obsahuje ako normálnu podskupinu alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "je originál" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "je obraz" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimapa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitovská transpozícia matice" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "vložené medzi" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "exkluzívna disjunkcia" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "pravý uhol s oblúčikom" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "pravouhlý trojuholník" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "kosoštvorcový operátor" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operátor bodka" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operátor hviezdička" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "deleno krát" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "mašľa" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "ľavý normálny faktor polopriameho súčinu" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "pravý normálny faktor polopriameho súčinu" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "ľavý polopriamy súčin" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "pravý polopriamy súčin" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "obrátená vlnovka rovná sa" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "zložené logické alebo" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "zložené logické a" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dvojitá podmnožina" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dvojitá nadmnožina" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dvojitý prienik" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dvojité zjednotenie" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "vidly" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "rovná sa a rovnobežný" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "menší neš s bodkou" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "väčší než s bodkou" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "ešte oveľa menší" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "ešte oveľa väčší" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "menší alebo sa rovná alebo väčší" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "väčší alebo sa rovná alebo menší" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "rovná sa alebo menší" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "rovná sa alebo väčší" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "rovná sa alebo predchádzajúci" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "rovná sa alebo nasledujúci" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "nie je predchádzajúci alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "nie je nasledujúci alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "nie je štvorcový obraz alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "nie je štvorcový originál alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "štvorcový obraz alebo sa nerovná" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "štvorcový originál alebo sa nerovná" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "menší než ale neekvivalentný" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "väčší než ale neekvivalentný" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "predchádzajúci ale neekvivalentný" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "nasledujúci ale neekvivalentný" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "nie je normálna podskupina" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "neobsahuje ako normálnu podskupinu" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "nie je normálna podskupina alebo rovná sa" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "neobsahuje ako normálnu podskupinu alebo sa rovná" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "zvislá výpustka" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "vodorovná výpustka vstrede" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "uhlopriečna výpustka vpravo hore" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "uhlopriečna výpustka vpravo dole" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "je prvkom s dlhým vodorovným preškrtnutím" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "je prvkom so zvislov čiarov na konci vodorovného preškrtnutia" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "malé je prvkom so zvislov čiarov na konci vodorovného preškrtnutia" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "je prvkom s bodkou nad" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "je prvkom s čiarkou nad" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "je prvkom s čiarou nad" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "je prvkom s čiarou pod" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "je prvkom s dvojitým vodorovným preškrtnutím" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "obsahuje s dlhým vodorovným preškrtnutím" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "obsahuje so zvislou čiarov na konci vodorovného preškrtnutia" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "malé obsahuje so zvislou čiarov na konci vodorovného preškrtnutia" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "obsahuje s čiarou nad" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "malé obsahuje s čiarou nad" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ľavý strop" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "pravý strop" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "ľavé dno" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "pravé dno" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "horná zložená zátvorka" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "spodná zložená zátvorka" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "ľava lomená zátvorka" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "pravá lomená zátvorka" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "bodka v krúžku" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "zjednotenie s bodkou" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "zjednotenie so znamienkom plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "štvorcový prienik" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "štvorcové zjednotenie" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "čierny štvorec" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "biely štvorec" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "čierny diamant" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "biely kruh" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "čierny kruh" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "odrážka v tvare bielej bodky" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "čierny stredne veľký štvorec" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "podčiarknuté %s" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "preškrtnuté %s" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "zvisle preškrtnuté %s" - -# Restrict to -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "Aplikáciu" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "prázdny" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "tučné" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "záložka vložená" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "záložky uložené" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "záložky sa nepodarilo uložiť" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nenájdené žiadne oblasti stránky." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Nenájdené žiadne oblasti stránky." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Režim prepúšťania zapnutý" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Nie je možné získať obrazovku kalkulačky" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Spôsob oznamovania veľkých písmen: Ikona" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "Nič" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Spôsob oznamovania veľkých písmen: Nič" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "hláskovanie" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Spôsob oznamovania veľkých písmen: Hláskovanie" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Navigáciu kurzorom riadi aplikácia." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Navigáciu kurzorom riadi aplikácia." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "bunka %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s vybrané" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s do %s vybrané" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s do %s nevybrané" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s nevybrané" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Zabráni použitiu voľby" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Vynúti použitie voľby" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "VOĽBA" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Voliteľné argumenty" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Použitie: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Nasledujú chybne zadané: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "vypíše prístupné spustené aplikácie" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Načíta profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profil sa nepodarilo načítať: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Nie je možné spustiť čítačku obrazovky, pretože sa nepodarilo pripojiť k " -"pracovnej ploche." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Nie je možné aktivovať správcu nastavení. Koniec." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Pre toto sedenie je už spustený proces čítačky obrazovky.\n" -"Spustite „cthulhu --replace“ ak si tento proces želáte nahradiť." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NÁZOV" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Použije iný adresár pre používateľské nastavenia" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "ADRESÁR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "vypíše prístupné spustené aplikácie" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Nahradí už spustenú inštanciu čítačky obrazovky" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Zobrazí tento text pomocníka a skončí" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Odošle ladiace informácie do súboru debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Odošle výstup pre ladenie do zadaného súboru" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "SÚBOR" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Používateľské nastavenia (textová verzia)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Používateľské nastavenia (grafická verzia)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Chyby oznamujte na adresu https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Výber vystrihnutý do schránky." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "vystrihnuté" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Výber skopírovaný do schránky." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "Skopírované" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Prilepený obsah schránky." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "Prilepené" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Neoznamovať, keď priatelia píšu." - -# PK: preco nie malym? -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "Oznamovať, keď priatelia píšu." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Správa z diskusnej miestnosti %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nová diskusná záložka %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Nehovoriť názov diskusnej miestnosti." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "Hovoriť názov diskusnej miestnosti." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Neposkytovať históriu správ jednotlivých diskusných miestností." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Poskytovať históriu správ jednotlivých diskusných miestností." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "začiatok zlomku" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "koniec zlomku" - -#: src/cthulhu/messages.py:452 -#, fuzzy -msgctxt "content" -msgid "insertion start" -msgstr "začiatok zlomku" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "koniec zlomku" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "svetlozelená" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "Hláskovať _návrhy" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Koniec kontajneru" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "nie v kontajnery." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "Všetky položky vybraté" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Predvolené tlačidlo je %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Predvolené tlačidlo je %s" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Predvolené tlačidlo je %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " dolný index %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " horný index %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "nie v tabuľke." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "vybratý celý dokument" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "Nevybratý celý dokument" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokument vybratý od pozícii kurzora" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "výber dokumentu zrušený od pozícii kurzora" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokument vybratý po pozíciu kurzora" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "výber dokumentu zrušený po pozíciu kurzora" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "dynamicky nastavená hlavička stĺpca pre riadok %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "dynamicky nastavená hlavička stĺpca vymazaná" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "dynamicky nastavená hlavička riadku pre stĺpec %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "dynamicky nastavená hlavička riadku vymazaná" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "prázdne" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobajtov" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabajtov" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Neboli nájdené žiadne súbory." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Obsah plošného prezerania pripojený do schránky." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Obsah plošného prezerania skopírovaný do schránky." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Plošné prezeranie sa nepoužíva." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Vstup do režimu plošného prezerania" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Odchod z režimu plošného prezerania" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Premiestni plošné prezeranie na slovo zobrazené nad aktuálnym slovom." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Plochý prehľad neobmedzený" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "má vzorec" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "Otvorí Dialóg vyhľadávanie čítačky obrazovky." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "zoznam strán" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "odkaz obrázkovej mapy" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Zadaná skratka je už priradená %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Klávesová skratka zachytená: %s. Potvrďte stlačením klávesu Enter." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Nová klávesová skratka je: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Klávesová skratka odstránená. Potvrďte stlačením klávesu enter." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Klávesová skratka bola odstránená." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "Vložte klávesovú skratku" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "kláves" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Odozva klávesov: kláves" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Nič" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Odozva klávesov: Nič" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "kláves a slovo" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Odozva klávesov: kláves a slovo" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "veta" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Odozva klávesov: veta" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "slovo" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "odozva klávesov: slovo" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "slovo a veta" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "odozva klávesov: slovo a veta" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Uzatvorené: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "aktuariálskym symbolom" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "obdĺžnikom" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "kruhom" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "symbolom dlhého delenia" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "odmocninou" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "zaobleným obdĺžnikom" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "vodorovným preškrtnutím" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "zvislým preškrtnutím" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "uhlopriečnym preškrtnutím vpravo dole" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "uhlopriečnym preškrtnutím vpravo hore" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "šípkou doprava hore" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "čiarou na spodku" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "čiarou na ľavej strane" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "čiarou na pravej strane" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "čiarou na vrchu" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "fázorovým uhlom" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "arabským symbolom faktoriálu" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "a" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "začiatok zlomku" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "začiatok zlomku bez čiary" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "lomeno" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "koniec zlomku" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "druhá odmocnina z" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "tretia odmocnina z" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "mocnina z" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "začiatok mocniny" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "koniec mocniny" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "dolný index" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "horný index" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "s predchádzajúcim dolným indexom" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "s predchádzajúcim horným indexom" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "výraz s dolným indexom" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "výraz s horným indexom" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "koniec tabuľky" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "koniec vnorenej tabuľky" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "Neprístupné" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Vypnuté" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Oznamovanie odsadenia a zarovnania textu vypnuté" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Zapnuté" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Oznamovanie odsadenia a zarovnania textu zapnuté" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Režim učenia. Stlačte kláves escape na ukončenie" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Vstup do režimu učenia. Po stlačení ktoréhokoľvek klávesu bude oznámená " -"jeho funkcia. Pomocník čítačky obrazovky zobrazíte stlačením F1. Stlačením " -"klávesu F2 získate zoznam predvolených klávesových skratiek čítačky " -"obrazovky. Stlačením klávesu F3 získate zoznam klávesových skratiek čítačky " -"obrazovky platných pri používaní aktuálnej aplikácii. Režim učenia ukončíte " -"stlačením klávesu Escape." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "odchod z citácie." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "odchod z tabuľky." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "odchod zo zoznamu článkov" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "odchod zo znázornenia" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "odchod z formulára." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "odchod z baneru." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "odchod z doplnkového obsahu." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "Odchod z informácií" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "Odchod z hlavného obsahu." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "Odchod z navigácie." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "odchod z oblasti." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "odchod z vyhľadávánia." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "odchod zo zoznamu." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "odchod z panelu." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "odchod z tabuľky." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "odchod zo zoznamu." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "odchod z abstraktu." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "Odchod z poďakovania." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "odchod z dôvetku." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "odchod z dodatku." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "odchod z bibliografie." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "odchod z kapitoly." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "odchod z tiráže." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "odchod zo záveru." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "odchod zo zdroja." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "odchod zo zoznamu zdrojov." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "Odchod z venovania." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "odchod z koncových poznámok." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "odchod z epigrafu." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "odchod z epilógu." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "odchod z opravy chýb." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "odchod z príkladu." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "odchod z úvodného slova." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "odchod zo slovníčka pojmov." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "odchod z registra." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "Odchod z úvodu." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "odchod zo zoznamu strán." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "odchod z časti." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "odchod z predslovu." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "odchod z prológu." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "odchod z upútavky." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "odchod z otázok a odpovedí." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "odchod z oblasti." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "Odchod z obsahu." - -# PV: tieto správy sa pravdepodobne už nepoužívajú, preložil som podľa toho, ako sa v aplikáciách gedit a libre office writer správa ctrl+shift+down a ctrl+shift+up -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "Riadok vybratý od pozícii kurzora" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "Riadok vybratý po pozíciu kurzora" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "výber riadku zrušený od pozícii kurzora" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "výber riadku zrušený po pozíciu kurzora" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Odchod z režimu učenia" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "riadok vybratý po predchádzajúcu pozíciu kurzora" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "riadok vybratý od predchádzajúcej pozícii kurzora" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "odkaz" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "na tejto stránke" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "na tomto webe" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "na inej stránke" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s odkaz na %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s odkaz" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "navštívený odkaz %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Na pohyb v zozname použite klávesy šípka hore a šípka dolu. Skončíte " -"stlačením klávesu escape." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "oznamovanie automaticky obnovovaného obsahu vypnuté pre všetky oblasti" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" -"Nastavená predvolená úroveň oznamovania automaticky obnovovaného obsahu pre " -"všetky oblasti" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "úroveň oznamovania %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "Úroveň automaticky obnovovaného textu je asertívne" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "Úroveň automaticky obnovovaného textu je vypnuté" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "Úroveň automaticky obnovovaného textu je zdvorilé" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "Úroveň automaticky obnovovaného textu je drzé" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Sledovanie automaticky obnovovaného obsahu vypnuté" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Sledovanie automaticky obnovovaného obsahu zapnuté" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nie je uložené oznámenie automaticky obnovovaného obsahu" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "podpora automaticky obnovovaného obsahu je vypnutá" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "nenájdené" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "nie je možné určiť aktuálne umiestnenie" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "vypnutý" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "zapnutý" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "preklep" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Preklep v slove: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "v kontexte: %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "režim prehliadania" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Režim zameriavania" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Režim zameriavania zapnete stlačením %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Vynútený režim zameriavania." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Vynútený režim prehliadania." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Režim zameriavania" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objekt" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Prejde na nasledujúci objekt." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "objekt zobrazený po prechode myšou nenájdený" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Prezeranie myšou zakázané." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Prezeranie myšou povolené." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Chyba: nie je možné vytvoriť zoznam objektov." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Žiadni potomkovia." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d percent." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Prejde na predchádzajúce slovo." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "úroveň vnorenia %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Pridaná nová položka" - -# PK: dal by som neni zamerana -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Žiadna aplikácia nie je zameraná." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Bez zamerania" - -# PK: dal by som neni zamerana -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Žiadna aplikácia nie je zameraná." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Žiadne ďalšie citácie" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Žiadne ďalšie tlačidlá." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Žiadne ďalšie zaškrtávacie polia." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "žiadne ďalšie veľké objekty." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Žiadne ďalšie klikateľné objekty." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "žiadne ďalšie kombinované polia." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "žiadne ďalšie textové vstupy" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Žiadne ďalšie prvky formulára." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Žiadne ďalšie nadpisy." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Žiadne ďalšie nadpisy úrovne %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Žiadne ďalšie tabuľky." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Žiadne ďalšie obrázky." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nenájdené žiadne oblasti stránky." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Žiadne ďalšie odkazy." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Žiadne ďalšie zoznamy." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Žiadne ďalšie položky zoznamu." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "žiadne ďalšie oblasti s automaticky obnovovaným obsahom." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Žiadne ďalšie odseky." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "žiadne ďalšie rádiové tlačidlá." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Žiadne ďalšie oddeľovače." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Žiadne ďalšie tabuľky." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Žiadne ďalšie nenavštívené odkazy." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Žiadne ďalšie navštívené odkazy." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Žiadny vybratý text." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nie je zameraný odkaz." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Oznámenie" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Spodok" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Vrch" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Neboli nájdené správy oznámení" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "číslice" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "čítať každú číslicu zvlášť" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "slová" - -# GtkLabel -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Čítať čísla po slovách" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "vypnuté" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "zapnuté" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Prebieha načítavanie. Prosím čakajte." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Načítavanie ukončené." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Ukončené načítavanie %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Stránka má %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "Strana vybratá od pozícii kurzora" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "Strana vybratá po pozíciu kurzora" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "Výber strany zrušený od pozícii kurzora" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "Výber strany zrušený po pozíciu kurzora" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "Odsek vybratý od pozícii kurzora" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "Odsek vybratý po pozíciu kurzora" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "Výber odseku zrušený od pozícii kurzora" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "Výber odseku zrušený po pozíciu kurzora" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Už máte otvorené jedno dialógové okno s nastaveniami čítačky obrazovky. Pred " -"otvorením nového okna najskôr, prosím, toto okno zatvorte." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "snímok %(position)d z %(count)d" - -# GtkLabel -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil nastavený na %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Neboli nájdené žiadne profili." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Ukazovateľ priebehu %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Všetko" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Úroveň interpunkcie: Všetko" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Väčšina" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Ǔroveň interpunkcie: Väčšina" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Nič" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Ǔroveň interpunkcie: Nič" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Niečo" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Úroveň interpunkcie: Niečo" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Prebieha vyhľadávanie." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Vyhľadávanie dokončené." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Nastavenia čítačky obrazovky boli znovu načítané." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Vybratý text: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Výber vymazaný." - -# GtkLabel -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Výber obnovený." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "nevybrané" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Reč vypnutá." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Reč zapnutá." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "Rýchlejšie." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "Pomalšie." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "Vyššie." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "Nižšie." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "hlasnejšie." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "tihšie.." - -# nastavuje to rýchlosť hovorenia -# GtkLabel -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Tempo:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Výška %s" - -# GtkLabel -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "_Hlasitosť:" - -# PM: Zvolil som takýto názov -# PV: chápem, že teraz sa dávajú aplikáciám univerzálne názvy napr. videá, fotky, mapy... toto ale každý pozná ako speech-dispatcher nezávisle na to, v akom jazyku sa hovorí. -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech Dispatcher" - -# PM: Zvolil som takýto názov -# PV: chápem, že teraz sa dávajú aplikáciám univerzálne názvy napr. videá, fotky, mapy... toto ale každý pozná ako speech-dispatcher nezávisle na to, v akom jazyku sa hovorí. -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Hlasový výstup nie je k dispozícii" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Hlasový výstup nie je k dispozícii" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Reč zapnutá." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "záložky sa nepodarilo uložiť" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Úroveň výrečnosti: stručná" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Úroveň výrečnosti: podrobná" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " bodka bodka bodka" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu vás víta." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu číha pod vlnami." - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Režim prepúšťania zapnutý" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Režim spánku vypnutý pre %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Hlasový výstup nie je k dispozícii" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "nenájdené" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Text nenájdený" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "Text nenájdený" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "klávesy štrukturálnej navigácie vypnuté." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "klávesy štrukturálnej navigácie zapnuté." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "nenájdené" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Riadok %(row)d, Stĺpec %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Koniec tabuľky" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Oznamovať bunky" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Oznamovať riadky" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Neuniformná" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "nie v tabuľke." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Stĺpce preusporiadané" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "riadky preusporiadané" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "stĺpec %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "stĺpec %(index)d z %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "spodok stĺpca." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "vrch stĺpca." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Stĺpec %s vybratý" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Stĺpce %s do %s vybraté" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Stĺpce %s do %s nevybraté" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Stĺpec %s nevybratý" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "riadok %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "riadok %(index)d z %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Začiatok riadku." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Koniec riadku." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Riadok zmazaný." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Posledný riadok zmazaný." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Vložený riadok." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Vložený riadok na koniec tabuľky." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Riadok %s vybratý" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Riadky %s do %s vybraté" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Riadky %s do %s vybraté" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Riadok %s nevybratý" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "vybrané" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "nevybrané" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H hodín, %M minút a %S sekúnd." - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H hodín aa %M minút." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "späť" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "znovu" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "biele miesto" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "prechod cez spodok" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "prechod cez vrch" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 položiek" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Bunka zaberá %d riadkov" -msgstr[1] "Bunka zaberá %d riadok" -msgstr[2] "Bunka zaberá %d riadky" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d stĺpcov" -msgstr[1] "%d stĺpec" -msgstr[2] "%d stĺpce" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Bunka zaberá %d stĺpcov" -msgstr[1] "Bunka zaberá %d stĺpec" -msgstr[2] "Bunka zaberá %d stĺpce" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "dlhšie o %d znakov" -msgstr[1] "dlhšie o %d znak" -msgstr[2] "dlhšie o %d znaky" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialógových okien)" -msgstr[1] "(%d dialógové okno)" -msgstr[2] "(%d dialógové okná)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d nezameraných dialógových okien" -msgstr[1] "%d nezamerané dialógové okno" -msgstr[2] "%d nezamerané dialógové okná" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bajtov" -msgstr[1] "%d bajt" -msgstr[2] "%d bajty" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "nájdených %d súborov" -msgstr[1] "nájdený %d súbor" -msgstr[2] "nájdené %d súbory" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulárov" -msgstr[1] "%d formulár" -msgstr[2] "%d formuláre" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d nadpisov" -msgstr[1] "%d nadpis" -msgstr[2] "%d nadpisy" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d položiek" -msgstr[1] "%d položka" -msgstr[2] "%d položiek" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d oblastí stránky" -msgstr[1] "%d oblasť stránky" -msgstr[2] "%d oblasti stránky" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "nájdených %d položiek" -msgstr[1] "nájdená %d položka" -msgstr[2] "nájdené %d položky" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Odchod z %d citácií." -msgstr[1] "Odchod z %d citácie." -msgstr[2] "Odchod z %d citácií." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Odchod z %d zoznamov." -msgstr[1] "Odchod z %d zoznamu." -msgstr[2] "Odchod z %d zoznamov." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "zoznam má %d položiek" -msgstr[1] "zoznam má %d položku" -msgstr[2] "zoznam má %d položky" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "zoznam má %d položiek" -msgstr[1] "zoznam má %d položku" -msgstr[2] "zoznam má %d položky" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Hodnota" -msgstr[1] "Hodnota" -msgstr[2] "Hodnota" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "matematická tabuľka má %d riadkov" -msgstr[1] "matematická tabuľka má %d riadok" -msgstr[2] "matematická tabuľka má %d riadky" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d stĺpcov" -msgstr[1] "%d stĺpec" -msgstr[2] "%d stĺpce" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "vnorená matematická tabuľka má %d riadkov" -msgstr[1] "vnorená matematická tabuľka má %d riadok" -msgstr[2] "vnorená matematická tabuľka má %d riadky" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d správ\n" -msgstr[1] "%d správa\n" -msgstr[2] "%d správy\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d percent." -msgstr[1] "%d percento." -msgstr[2] "%d percentá." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "prečítaných %d percent dokumentu" -msgstr[1] "prečítané %d percento dokumentu" -msgstr[2] "prečítané %d percentá dokumentu" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d pixelov" -msgstr[1] "%d pixel" -msgstr[2] "%d pixely" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d znakov %(repeatChar)s" -msgstr[1] "%(count)d znak %(repeatChar)s" -msgstr[2] "%(count)d znaky %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "vybratých %(index)d z %(total)d položiek" -msgstr[1] "vybratá %(index)d z %(total)d položiek" -msgstr[2] "vybraté %(index)d z %(total)d položiek" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Nájdených %d skratiek čítačky obrazovky." -msgstr[1] "Nájdená %d skratka čítačky obrazovky." -msgstr[2] "Nájdené %d skratky čítačky obrazovky" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Nájdených %(count)d skratiek čítačky obrazovky pre %(application)s." -msgstr[1] "Nájdená %(count)d skratka čítačky obrazovky pre %(application)s." -msgstr[2] "Nájdené %(count)d skratky čítačky obrazovky pre %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d medzier" -msgstr[1] "%d medzera" -msgstr[2] "%d medzery" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d znakov tabulátor" -msgstr[1] "%d znak tabulátor" -msgstr[2] "%d znaky tabulátor" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabuliek" -msgstr[1] "%d tabuľka" -msgstr[2] "%d tabuľky" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "obsah" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabuľka má %d riadkov" -msgstr[1] "tabuľka má %d riadok" -msgstr[2] "tabuľka má %d riadky" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabuľka má %d riadkov" -msgstr[1] "tabuľka má %d riadok" -msgstr[2] "tabuľka má %d riadky" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabuľka má %d riadkov" -msgstr[1] "tabuľka má %d riadok" -msgstr[2] "tabuľka má %d riadky" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d nenavštívených odkazov" -msgstr[1] "%d nenavštívený odkaz" -msgstr[2] "%d nenavštívené odkazy" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d navštívených odkazov" -msgstr[1] "%d navštívený odkaz" -msgstr[2] "%d navštívené odkazy" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "Prepnutie" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(index)d z %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d z %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "ÚROVEŇ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "Úroveň stromu %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "ÚROVEŇ STROMU %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "otáznik" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "Upravovateľné kombinované pole" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "upravovateľný obsah" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "zoznam článkov" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "znázornenie" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "abstrakt" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "poďakovanie" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "dôvetok" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "dodatok" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "položka bibliografie" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografia" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "kapitola" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "tiráž" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "záver" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "obálka" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "zdroj" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "zdroje" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "venovanie" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "koncová poznámka" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "koncové poznámky" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilóg" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "oprava chýb" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "príklad" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "úvodné slovo" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "slovníček pojmov" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "register" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "úvod" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "zlom strany" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "zoznam strán" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "časť" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "predslov" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prológ" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "upútavka" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "otázky a odpovede" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "podnázov" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "obsah" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s úrovne %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "vodorovný posúvač" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "zvislý posúvač" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "vodorovný posuvník" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "zvislý posuvník" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "vodorovný rozdeľovač" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "zvislý rozdeľovač" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "Prepínač" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "panel s ikonami" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "baner" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "doplnkový obsah" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informácie" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "hlavný obsah" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigácia" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "oblasť" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "vyhľadávanie" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "navštívený odkaz" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "Tlačidlo s ponukou" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klikateľné" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "zatvorené" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "otvorené" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "obsahuje dlhý popis" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "vodorovný" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "zvislý" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "zaškrtnuté" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nezaškrtnuté" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "zapnutý" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "vypnutý" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "čiastočne zaškrtnuté" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "stlačené" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "nestlačené" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "nevybraté" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "vybraté" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "nevybraté" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "nevybratá" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "navštívený" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "nenavštívený" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "nedostupné" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "len na čítanie" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "požadované" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "viacnásobný výber" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "Neplatný vstup" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "neplatný" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "Neplatný pravopis" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "pravopis" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "Neplatná gramatika" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatika" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Nájsť" - -# generic name -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Dialóg hľadať Čítačky obrazovky" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Zavrieť" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Nájsť" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Hľadaný text:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Hľadaný text:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Vrchu okna" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Vrchu okna" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Začať od:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Pokračovať do_okola" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Hľadať _dozadu" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Smer hľadania" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Rozlišovať veľkosť písmen" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Porovnávať len celé slová" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Možnosti Hľadania" - -# PK: ako je to mozne, ved to ukazuje len na jeden riadok v kode -# PM: je to dynamicky generovaný súbor podla súboru ui -# na viacerých miestach -# *https://bugzilla.gnome.org/show_bug.cgi?id=686690 -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Predvolené" - -# PM: ide o nastavenie ovplyvňujúce spôsob čítania -# Voice type -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Veľké písmená" - -# MČ: nie som si istý, ale hypertext je text, ktorý obasuje odkazy. Hyperlink by mal byť ten odkaz. Či nie? (viakrat) -# PK: ako moze byt typ hlasu hypertext, co to znamena? -# PM: číta to osobitne hypertexové odkazy -# Voice type -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hypertextový odkaz" - -# Voice type -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Systém" - -# Restrict to -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Aplikáciu" - -# Restrict to -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Okno" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Nastavenia Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Pomocník" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "P_oužiť" - -# MČ: nebolo by vhodnejšie „prenosný počítač“? Keď je ten druhý „stolný počítač“? -# PM: u nás je zaužívané notebook -# GtkRadioButton -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "Note_book" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Rozloženie klávesnice" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Aktívny profil:" - -# PM: ide o profil, ktorý sa má načítať pri štarte -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profil načítaný po štarte:" - -# GtkButton -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Načítať" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Uložiť _ako" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profily" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Uvádzať _bublinové popisy" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Pomenovať objekt pod kurzorom _myši" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Myš" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Formát času:" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Formát _dátumu:" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Čas a dátum" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Hovoriť aktualizácie" - -# GtkLabel -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Zo_braziť aktualizácie v brailly" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -# GtkLabel -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frekvencia (sekundy):" - -# Restrict to -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Aplikáciu" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Pípať aktualizácie" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Aktualizácie indikátora priebehu" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Povoliť funkcie p_revinúť a rýchlo dopredu počas plynulého čítania" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Povoliť štrukturálnu navigáciu poča_s plynulého čítania" - -# GtkLabel -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "_Plynulé čítanie po:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Oznamovať bloky citácií počas plynulého čítania" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Oznamovať zoznamy poča_s plynulého čítania" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Oznamovať _tabuľky počas plynulého čítania" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Oznamovať _panely počas plynulého čítania" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Oznamovať _formuláre počas plynulého čítania" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Ozna_movať oblasti stránky počas plynulého čítania" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Plynulé čítanie" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Prezentácia prvku:" - -# tab label -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Všeobecné" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Hlasitosť:" - -# Nastavuje sa poloha hlasu -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Výška:" - -# nastavuje to rýchlosť hovorenia -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Tempo:" - -# PM: vyberá sa tu jazyk pre syntetizátor -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "O_soba:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "jazyk" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "S_yntetizátor reči:" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Systé_m reči:" - -# GtkLabel -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Typ hlasu:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Spôsob oznamovania _veľkých písmen" - -# GtkLabel -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Nastavenia typu hlasu" - -# GtkLabel -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Hovor_iť reťazce s rôznymi veľkosťami písmen ako slová" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Čítať _čísla po čísliciach" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Globálne nastavenia hlasu" - -# tab label -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Hlas" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Povoliť ro_zprávanie" - -# PM: výrečnosť -# GtkRadioButton -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Po_drobná" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Výrečnosť" - -# Punctuation Level -# GtkRadioButton -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Všetko" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Úroveň interpunkcie" - -# GtkCheckButton -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Hovoriť iba zobrazený text" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Hovoriť prázdne riadky" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Hovoriť od_sadenie a zarovnanie" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Hovoriť _mnemoniky objektov" - -# GtkCheckButton -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Hovoriť pozíciu podradeného prvku" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Hovoriť tútorské správy" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Systémové správy sú podrobné" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Čítať názvy _farieb" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Oznamovať bloky citácií počas navigácie" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Oznamovať zoznamy počas navigácie" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Oznamovať _tabuľky počas navigácie" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Oznamovať indikátor _preklepov" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Oznamovať _panely počas navigácie" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Ozna_movať oblasti stránky počas navigácie" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Oznamovať _formuláre počas navigácie" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Oznamovať _popis" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Čítať celý riadok pri navigácii v há_rkoch" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Čítať celý riadok pri navigácii v tabuľkách v _dokumente" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Čítať celý riadok pri navigácii v tabuľkách _grafického rozhrania" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Hovorený kontext" - -# PM: Na karte sa nastavuje čo všetko má cthulhu hovoriť -# tab label -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Rozprávanie" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Povoliť podporu _braillovho písma" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Skrátené názvy rolí" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Zakázať symbol _konca riadku" - -# GtkLabel -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Prekladová _tabuľka:" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Povoliť skratkopis v braillovom písme" - -# GtkCheckButton -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Povoliť delenie _slov" - -# Myslí sa displej pre braillove písmo -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Nastavenia displeja" - -# GtkRadioButton -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "Ž_iadny" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Indikátor výberu" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Indikátor hypertextového odkazu" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Povoliť _blikajúce správy" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Doba zobrazenia (sek):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "S_právy sú trvalé" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Správy sú _podrobné" - -# GtkLabel -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Nastavenia blikajúcich správ" - -# tab label -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braillovo písmo" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Povoliť odozvu _klávesov" - -# PM: myslia sa šípky a klávesy ako home, end, page up, page down -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Povoliť _abecedné znaky" - -# PM: myslia sa klávesy ako Shift Ctrl Alt -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Povoliť _číslice" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Povoliť inter_punkčné klávesy" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Povoliť _medzeru" - -# PM: myslia sa klávesy ako Shift Ctrl Alt -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Povoliť _modifikačné klávesy" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Povoliť _funkčné klávesy" - -# PM: myslia sa klávesy ako ESC Backspace -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Povoliť _akčné klávesy" - -# PM: myslia sa šípky a klávesy ako home, end, page up, page down -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Povoliť _navigačné klávesy" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Povoliť odozvu po _slovách" - -# GtkCheckButton -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Povoliť odozvu po _vetách" - -# PM: na karte sa nastavuje, či sa majú zopakovať stlačené klávesy -# MČ: Možno by som použil „Ozývanie kláves“. Echo je ozvena a kláves sa nezopakuje, ale vysloví, ktorý bol zatlačený. -# tab label -# PM: jeden z významov je aj zopakovať viď http://translate.google.sk/#en/sk/echo -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Odozva klávesov" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "_Modifikačný kláves(y) čítačky obrazovky:" - -# tab label -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Klávesové skratky" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Slovník výslovnosti" - -# GtkButton -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nový záznam" - -# GtkButton -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "O_dstrániť" - -# tab label -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Výslovnosť" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Hovoriť všetko" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Nehovoriť n_ič" - -# GtkButton -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "O_bnoviť pôvodné" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Textové atribúty" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Presunúť na_spodok" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Presunúť _nižšie" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Presunúť _vyššie" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Presunúť na_vrch" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Prispôsobiť vybrané atribúty" - -# GtkLabel -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Indikátor v braillovom písme" - -# tab label -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Textové atribúty" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Poskytovateľ:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokálny - Zadarmo)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Súbor API _kľúča:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Cesta k súboru kľúča API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Získať _Claude API kľúč" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Otvoriť prehliadač na získanie Claude API kľúča a automaticky uložiť" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Vyžadovať potvrdenie pred akciami AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _model:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Názov modelu pre Ollama (napr. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _koncový bod:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL koncového bodu Ollama API (napr. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Kvalita snímky obrazovky:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "nízko" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Stredná" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Vysoká" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "jazyk" - -# je to hovorené myslím ze yen by to nezvládlo poveda správne -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "jen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Sivý obrázok" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Invertovať obrázok" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Čiernobiely obrázok" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Prah čiernej/bielej:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analyzovať farby" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Obsah plošného prezerania skopírovaný do schránky." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : adam, b : božena, c : cyril, č : čadca, d : dávid, ď : ďumbier, e : " -"emil, f : františek, g : gustáv, h : helena, i : ivan, j : jozef, k : karol, " -"l : ladislav, ľ : ľubochňa, m : mária, n : norbert, ň : nitra, o : oto, p : " -"peter, q : quido, r : rudolf, ř : řehoř, s : svätopluk, š : šimon, t : " -"tomáš, ť : teplá, u : urban, v : václav, w : dvojitéVé, x : xaver, y : " -"ypsilon, z : zuzana, ž : žofia" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "farba pozadia" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "plná výška pozadia" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "vzorovanie pozadia" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "smer" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "upravovateľné" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "názov rodiny písma" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "farba popredia" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "vzorovanie popredia" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efekt písma" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "odsadenie" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "gramatická chyba" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "neviditeľný" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "zarovnanie" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "jazyk" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "ľavý okraj" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "výška riadku" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "štýl odseku" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "pixely nad riadkami" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "pixely pod riadkami" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "pixely v zalomení" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "pravý okraj" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "zdvih" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "zväčšenie" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "veľkosť" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "riadkovanie" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "preškrtnutie" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "štýl" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "dekorácia textu" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "rotácia textu" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "tieňovanie textu" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "podčiarknutie" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "zvislé zarovnanie" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "hrúbka" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "režim zalomenia" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "režim zápisu" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "áno" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "nie" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "žiadne" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "rytina" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "reliéf" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "obris" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "nadčiarknuté" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "preškrtnuté" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "blikajúce" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "čierne" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "jednoduché" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dvojité" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "nízko" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "znak" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "slovo" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "abecedný znak" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "z ľava do prava" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "z prava do ľava" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "vľavo" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "vpravo" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "na stred" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "nezarovnané" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "do bloku" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "veľmi zhustené" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "zhustenejšie" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "zhustené" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "čiastočne zhustené" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normálne" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "čiastočne roztiahnuté" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "roztiahnuté" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "roztiahnutejšie" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "veľmi roztiahnuté" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "kapitálky" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "skosené" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kurzíva" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "východzí" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "telo textu" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "nadpis" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "základná čiara" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "dolný index" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "horný index" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "hore" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "na vrch textu" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "na stred" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "dolu" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "na spodok textu" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "zdedené" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lp-hd" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "pl-hd" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "hd-pl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "hd-lp" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "dh-pl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "dh-lp" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lp" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "pl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "hd" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "neprerušované" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "kontrola pravopisu" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Prepnete stlačením medzerníka." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Otvoríte stlačením medzerníka a následne môžete vyberať hodnotu šípkami hore " -"a dolu." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Stlačením alt+F6 môžete prechádzať medzi podradenými oknami" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"na pohyb po položkách používajte kurzorové šípky alebo začnite vyhľadávať " -"postupným zapisovaním." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Do systémovej ponuky vstúpite stlačením alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Pomocou klávesov hore a dolu vyberte položku." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Zatvoríte stlačením shift+ľavá šípka." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Otvoríte stlačením shift+pravá šípka." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Stlačením klávesu enter aktivujete položku." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Zapíšte text." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Na zobrazenie ostatných kariet použite klávesy ľavá a pravá šípka." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Aktivujete stlačením medzerníka" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "Použite šípky hore a dolu na výber hodnoty alebo zapíšte číslo." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Zmenu vykonáte stlačením kurzorových klávesov" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Na navigáciu medzi ponukami používajte klávesy ľavá a pravá šípka. " -"Prechádzať po položkách môžete klávesmi šípka hore a šípka dolu." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Do podponuky vstúpite stlačením klávesu pravá šípka." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Na zníženie hodnoty stlačte kláves ľavá šípka, na zvýšenie hodnoty stlačte " -"kláves pravá šípka, pre nastavenie minimálnej hodnoty stlačte kláves home a " -"pre nastavenie maximálnej hodnoty stlačte kláves end." diff --git a/po/sl.po b/po/sl.po deleted file mode 100644 index 7b41aa2..0000000 --- a/po/sl.po +++ /dev/null @@ -1,9312 +0,0 @@ -# Slovenian translations for cthulhu. -# Copyright (C) 2005-2006 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# -# Matjaž Horvat , 2006. -# Matej Urbančič , 2007–2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-09-10 23:33+0200\n" -"Last-Translator: Matej Urbančič \n" -"Language-Team: Slovenian GNOME Translation Team \n" -"Language: sl_SI\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || " -"n%100==4 ? 3 : 0);\n" -"X-Poedit-SourceCharset: utf-8\n" -"X-Generator: Poedit 3.0.1\n" - -msgid "Cthulhu Screen Reader" -msgstr "Zaslonski bralnik Orka" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "govor;zaslonski bralnik;Braillova pisava;brajica;povečevalnik" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "opoz" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "puš" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kol" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "pan" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "nasl" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "pot" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "izbbrv" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "glvstl" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "sps" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ikona" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "okv" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "kliči" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "pog" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "pmap" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "ris" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "izdat" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "pis" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "obrazec" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "stk" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "naslov" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "slk" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "okv" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "ozn" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "panrvn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "povez" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "sez" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "prdsez" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mni" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnvrs" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "prdmen" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "izbpan" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "zavstran" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "sezzav" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "plt" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "ges" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "pjvmen" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "kaznap" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "gmb" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "radpred" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "korpan" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "glavrs" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "drs" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "drspan" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "oddelek" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "loč" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "drsgmb" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "ločpan" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "vrt" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "vrstan" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "celica" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "prodtmen" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "bes" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "prkgmb" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "orvrs" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "nam" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "drevo" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tabdrv" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "nez" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "opog" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "okn" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "glv" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "nog" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "ods" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "prog" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "samd" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "urvrs" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "vgr" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Češčina, 1. razred" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Španščina, 1. razred" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanadska francoščina, 2. razred" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francoska francoščina, 2. razred" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Latvijščina, 1. razred" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Nizozemščina, 1. razred" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norveščina, 0. razred" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norveščina, 1. razred" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norveščina, 2. razred" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norveščina, 3. razred" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Poljščina, 1. razred" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugalščina, 1. razred" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Švedščina, 1. razred" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabščina, 1. razred" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Valižanščina, 1. razred" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Valižanščina, 2. razred" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Nemščina, 0. razred" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Nemščina, 1. razred" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Nemščina, 2. razred" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Angleška angleščina, 2. razred" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Angleška angleščina, 1. razred" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Ameriška angleščina, 1. razred" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Ameriška angleščina, 2. razred" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadska francoščina, 1. razred" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francoska francoščina, 1. razred" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grščina, 1. razred" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindujščina, 1. razred" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Madžarščina, 8 pik, računalniški" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Madžarščina, 1. razred" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Madžarščina, 2. razred" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italijanščina, 1. razred" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgijska nizozemščina, 1. razred" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "presledek" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "nova vrstica" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabulator" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "klicaj" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "navedek" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "številčni znak" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "odstotek" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "in" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "opuščaj" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "levi oklepaj" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "desni oklepaj" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "zvezdica" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "vejica" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "pomišljaj" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "pika" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "desna poševnica" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dvopičje" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "podpičje" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "manjše kot" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "enačaj" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "večje" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "vprašaj" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "afna" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "levi oglati uklepaj" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "leva poševnica" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "desni oglati zaklepaj" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "strešica" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "podčrtaj" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "krativec" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "levi zaviti uklepaj" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "navpičnica" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "desni zaviti zaklepaj" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "presledek brez preloma" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "obrnjeni klicaj" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centov" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "funtov" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "znak valute" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jenov" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "presledna navpičnica" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "znak za člen" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "preglas" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "znak za avtorske pravice" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "nadpisani a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "levi francoski narekovaj" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logični ne" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "vezaj" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "znak za registrirano" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "makron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "stopinje" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus-minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "nadpisana številka 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "nadpisana številka 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "ostrivec" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "grška črka mi" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "znak za odstavek" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "sredinska pika" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "sedij" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "nadpisana številka 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "desni francoski narekovaj" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "četrtina" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "polovica" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tri četrtine" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "obrnjeni vprašaj" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "mala črka a z ostrivcem" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "velika črka A s krativcem" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "velika črka A z ostrivcem" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "velika črka A s cirkumfleksom" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "velika črka A s tildo" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "velika črka A s preglasom" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "velika črka A s krožcem zgoraj" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "ligatura velikih črk A in E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "Velika črka C s sedijem" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "velika črka E s krativcem" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "velika črka E z ostrivcem" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "velika črka E s cirkumfleksom" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "velika črka E s preglasom" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "velika črka I s krativcem" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "velika črka I z ostrivcem" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "velika črka I s cirkumfleksom" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "velika črka I s preglasom" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "velika črka ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "velika črka N s tildo" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "velika črka O s krativcem" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "velika črka O z ostrivcem" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "velika črka O s cirkumfleksom" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "velika črka O s tildo" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "velika črka O s preglasom" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "krat" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "prečrtana velika črka O" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "velika črka U s krativcem" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "velika črka U z ostrivcem" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "velika črka U s cirkumfleksom" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "velika črka U s preglasom" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "velika črka Y z ostrivcem" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "velika črka thorn" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "ostri s" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "mala črka a s krativcem" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "mala črka a s cirkumfleksom" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "mala črka a s tildo" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "mala črka a s preglasom" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "mala črka a s krožcem" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ligatura malih črk a in e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "mala črka c s sedijem" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "mala črka e s krativcem" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "mala črka e z ostrivcem" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "mala črka e s cirkumfleksom" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "mala črka e s preglasom" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "mala črka i s krativcem" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "mala črka i z ostrivcem" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "mala črka i s cirkumfleksom" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "mala črka i s preglasom" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "mala črka eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "mala črka n s tildo" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "mala črka o s krativcem" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "mala črka o z ostrivcem" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "mala črka o s cirkumfleksom" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "mala črka o s tildo" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "mala črka o s preglasom" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "deljeno z" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "mala prečrtana črka o" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "mala črka thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "mala črka u z ostrivcem" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "mala črka u s krativcem" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "mala črka u s cirkumfleksom" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "mala črka u s preglasom" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "mala črka y z ostrivcem" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "mala črka y s preglasom" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "velika črka Y s preglasom" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "pomišljaj" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "levi enojni narekovaj" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "desni enojni narekovaj" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "levi spodnji enojni narekovaj" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "levi dvojni narekovaj" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "desni dvojni narekovaj" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "levi spodnji dvojni narekovaj" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "konjugirano transponirana" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "obelisk" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "vrstična oznaka" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trikotna vrstična oznaka" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "znak za minuto, odvod" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "znak za sekundo, drugi odvod" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "znak za stotinko, trojni odvod" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "pomišljaj vrstična oznaka" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "evrov" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "zaščitni znak" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "kljukica" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "odebeljena kljukica" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "vrstična oznaka v obliki črke x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "nadpisana številka 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "nadpisana številka 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "nadpisana številka 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "nadpisana številka 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "nadpisana številka 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "nadpisana številka 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "nadpisana številka 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "nadpisani znak plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "nadpisani znak minus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "nadpisani enačaj" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "nadpisani uklepaj" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "nadpisani zaklepaj" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "nadpisana črka n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "podpisana številka 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "podpisana številka 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "podpisana številka 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "podpisana številka 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "podpisana številka 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "podpisana številka 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "podpisana številka 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "podpisana številka 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "podpisana številka 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "podpisana številka 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "podpisani znak plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "podpisani znak minus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "podpisani enačaj" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "podpisani uklepaj" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "podpisani zaklepaj" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "črni kvadrat" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "črni karo" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "znak vsebnik za zamenjavo predmeta" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Premakne kazalnik na trenutni predmet." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Izvedi levi klik na trenutnem predmetu v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Izvedi desni klik na trenutnem predmetu v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Preberi celoten dokument" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Izgovori celotno vsebino okna v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Izvedi enostavno opravilo Kje sem" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Izvedi podrobno opravilo Kje sem" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Izgovori trenuten izbor" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Izgovori podrobnosti povezave" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Predstavi privzeti gumb" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Predstavi vrstico stanja" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Predstavi naslovno vrstico" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Odpri pogovorno okno iskanja" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Pokaži meni dejanj" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Poišči naslednji zadetek niza" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Poišči predhodni zadetek niza" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Vstopi in izstopi iz načina vrstičnega pregleda" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Preklopi omejujoč vrstični pregled na trenutni predmet" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Premakni vrstični pregled na začetek" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Premakni vrstični pregled na konec" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Vrstični pregled premakni na začetek prejšnje vrstice" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Izgovori trenutno vrstico v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Črkuj trenutno vrstico v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Fonetično črkuj trenutno vrstico v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Premakni vrstični pregled na začetek naslednje vrstice" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Premakni vrstični pregled na predhodni predmet ali besedo" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Izgovori trenutni predmet ali besedo v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Črkuj trenutni predmet ali besedo v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Fonetično črkuj trenutni predmet ali besedo v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Premakni vrstični pregled do naslednjega predmeta ali besede" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Premakni vrstični pregled do besede nad trenutno besedo" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Izgovori trenutni predmet v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Premakni vrstični pregled do besede pod trenutno besedo" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Premakni vrstični pregled do predhodnega znaka" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Izgovori trenutni znak v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Fonetično izgovori trenutni znak v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Izgovori oznako unikod trenutnega znaka v vrstičnem pregledu" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Premakni vrstični pregled do naslednjega znaka" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Premakni vrstični pogled na konec vrstice" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Premakni vrstični pregled v spodnji levi kot" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Kopiraj vsebino v vrstičnem pregledu v odložišče" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Pripni vsebino v vrstičnem pregledu v odložišče" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Pokaži vsebino vrstičnega pregleda" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Preklopi med branjem trenutne celice ali celotne vrstice razpredelnice" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Preberi atribute, povezane s trenutnim besedilnim znakom" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Postavi Brajev zaslon levo" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Postavi Brajev zaslon desno" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Vrni se na predmet s tipkovnico" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Preklopi skrčeno obliko Brajeve pisave" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Obdelaj kazalne tipke" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Označi začetek izbora besedila" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Označi konec izbora besedila" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Vstopi v učni način. Za izhod pritisnite ubežno tipko ESC." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Zmanjšaj hitrost govora" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Povečaj hitrost govora" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Zmanjšaj višino govora" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Povečaj višino govora" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Povečaj glasnost govor" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Zmanjšaj glasnost govora" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Poišči predhodni zadetek niza" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Preklopi na naslednji odmev govora" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Zmanjšaj hitrost govora" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Povečaj hitrost govora" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Nastavitve vrste glasu" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Preklopi utišanje govora" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Preklopi raven podrobnosti govorne razlage" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Preklopi način razporeditve" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Končaj zaslonski bralnik" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Pokaži pogovorno okno možnosti" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Pokaži pogovorno okno možnosti programa" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Preklopi izgovarjanje zamikanja in poravnave" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Spremeni slog izgovorjave števil" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Poišči naslednjo raven izgovorjave ločil" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Preklopi na naslednji odmev govora" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Izberi naslednji profil nastavitev" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Krožno preklopi na naslednji slog velikih začetnic" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Preklopi med več ravnmi odmeva vnosa" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Zaokroži ravni razhroščevanja ob zagonu" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Ustvari zaznamek z upoštevanjem trenutnega mesta" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Skoči na predhodno mesto zaznamka" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Skoči na zaznamek" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Skoči na naslednje mesto zaznamka" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Dodaj zaznamek" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Shrani zaznamke" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Preklopi način preverjanja miške" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Predstavi trenutni čas" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Predstavi trenutni datum" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Pokaži velikost in mesto trenutnega predmeta" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Pošlje naslednji ukaz trenutno dejavnemu programu" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Izgovori in z brajico izpiši predhodno sporočilo iz klepetalnice" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Preklop med možnostjo oznanjanja pisanja sporočil" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Preklopi med podporo zgodovini določenih sporočil v klepetalnicah" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "Preklopi predpone sporočil pogovorov z imenom klepetalnice" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Premakni levo" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Premakni desno" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Premakni navzgor" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Premakni navzdol" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Zamrzni" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Zgoraj levo" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Spodaj levo" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Položaj kazalke" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Šest pik" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Kazalne tipke" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Začetek izbire kopiranja" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Konec izbire kopiranja" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Prikaži zadnje obvestilo" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Prikaži seznam obvestilnih sporočil" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Prikaži predhodnje obvestilo" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Prikaži naslednje obvestilo" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Skoči na naslednji znak" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Skoči na predhodni znak" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Skoči na naslednjo besed" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Skoči na predhodno besedo" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Skoči na naslednjo vrstico" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Skoči na predhodno vrstico" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Skoči na vrh datoteke" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Skoči na dno datoteke" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Skoči na začetek vrstice" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Skoči na konec vrstice" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Skoči na naslednji predmet" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Skoči na predhodni predmet" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Povzroči razširjanje pojavnega menija" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Preklopi med privzetim in tipkovnim krmarjenjem" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Napredna nastavitev prijaznosti samodejno posodobljenih predelov" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Nastavitev privzete prijaznosti posodobljenih predelov je izključeno" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Pregled objav samodejno posodobljenih predelov" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Nadzoruj samodejno posodobljenih predelov" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" -"Premakni dejanje na oziroma stran od trenutnega pojavnega predmeta miške" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Določi vrstice za dinamično glavo stolpca" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Počisti glave dejavnih stolpcev" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Določitev stolpca za dinamično glavo vrstice" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Počisti glave dejavnih vrstic" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Predstavi vsebino vnosne vrstice" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Preklopi tipke strukturnega krmarjenja" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Skoči na predhodni navedek" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Skoči na naslednji navedek" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Pokaži seznam navedkov" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Skoči na predhodni gumb" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Skoči na naslednji gumb" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Pokaži seznam gumbov" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Skoči na predhodno potrditveno polje" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Skoči na naslednje potrditveno polje" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Pokaži seznam potrditvenih polj" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Skoči na predhodni predmet, ki ga je mogoče klikniti" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Skoči na naslednji predmet, ki ga je mogoče klikniti" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Prikaži seznam predmetov, ki jih je mogoče klikniti" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Skoči na predhodni pojavni meni" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Skoči na naslednji pojavni meni" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Skoči na začetek predmeta" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Skoči na konec predmeta" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Pokaži seznam spustnih polj" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Skoči na predhodni vnos" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Skoči na naslednji vnos" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Pokaži seznam vnosov" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Skoči na predhodno polje obrazca" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Skoči na naslednje polje obrazca" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Pokaži seznam polj obrazca" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Skoči na predhodni naslov" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Skoči na naslednji naslov" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Pokaži seznam naslovov" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Skoči na predhodni naslov na %d. ravni" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Skoči na naslednji naslov na %d. ravni" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Pokaži seznam naslovov na %d. ravni" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Skoči na predhodni notranji okvir" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Skoči na naslednji notranji okvir" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Pokaže seznam notranjih okvirjev" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Skoči na predhodno sliko" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Skoči na naslednjo sliko" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Prikaži seznam slik" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Skoči na predhodno mestno oznako" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Skoči na naslednjo mestno oznako" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Pokaži seznam mestnih oznak" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Skoči na predhodni večji predmet" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Skoči na naslednji večji predmet" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Pokaži seznam velikih predmetov" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Skoči na predhodno povezavo" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Skoči na naslednjo povezavo" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Pokaži seznam povezav" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Skoči na predhodni seznam" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Skoči na naslednji seznam" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Pokaži seznam seznamov" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Skoči na predhodni predmet seznama" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Skoči na naslednji predmet seznama" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Pokaži seznam predmetov seznama" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Skoči na predhodni samodejno posodobljeni predel" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Skoči na naslednji samodejno posodobljeni predel" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Skoči na zadnje območje z objavo" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Skoči na nadrejeni predmet in ga postavi v žarišče." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Skoči na prvi podrejen predmet in ga postavi v žarišče." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Skoči na naslednji predmet in ga postavi v žarišče." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Skoči na predhodni predmet in ga postavi v žarišče." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Kliknii na predmet in ga postavi v žarišče." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Preklopi poenostavljeno krmarjenje predmeta" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Skoči na predhodni odstavek" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Skoči na naslednji odstavek" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Pokaže seznam odstavkov" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Skoči na predhodni radijski gumb" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Skoči na naslednji radijski gumb" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Pokaže seznam radijskih gumbov" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Skoči na predhodni ločilnik" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Skoči na naslednji ločilnik" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Skoči na predhodno razpredelnico" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Skoči na naslednjo razpredelnico" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Pokaže seznam razpredelnic" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Skoči eno celico navzdol" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Skoči na prvo celico v razpredelnici" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Skoči na zadnjo celico v razpredelnici" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Skoči eno celico levo" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Skoči eno celico desno" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Skoči eno celico navzgor" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Preklopi način razporeditve" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Preklopi med načinom iskanja in načinom žarišča" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Omogoči lepljiv način žarišča" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Omogoči lepljiv način brskanja" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Skoči na predhodno neobiskano povezavo" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Skoči na naslednjo neobiskano povezavo" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Pokaži seznam neobiskanih povezav" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Skoči na predhodno obiskano povezavo" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Skoči na naslednjo obiskano povezavo" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Pokaži seznam obiskanih povezav" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "bledomodra" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antično bela" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "morsko modra" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azurna" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "bež" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "kožno rjava" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "črna" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "marcipan" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "modra" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "modrovijolična" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "rjava" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "svetlo lesena" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadetsko modra" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "čokoladno rjava" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koralna" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "cikorija" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "sivo rumena" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "škrlatna" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "sinja" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "temno modra" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "temno sinja" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "temna zlata" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "temno siva" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "temno zelena" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "temna kaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "temna magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "temno olivno zelena" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "temno oranžna" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "škrlatna orhideja" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "temno rdeča" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "temno lososovo rdeča" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "temno morsko zelena" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "temno skrilasto modra" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "temno skrilasto siva" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "temna turkizna" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "temno vijolična" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "globoka rožnata" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "svetlo nebesno modra" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "Zamazano siva" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "FNebesno modra" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "opečnato rdeča" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "rožno bela" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "gozdnato zelena" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksija" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "belo siva" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "umazano bela" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "zlata" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "zlata palica" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "siva" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "zelena" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "rumeno zelena" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "mana" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "vroča rožnata" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "okra" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "slonokoščena" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "kaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "sivka" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "modrikasta sivka" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "travniško zelena" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "sladko limonska" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "svetlo modra" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "svetlo koralna" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "svetlo sinja" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "svetlo zlato rumena" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "svetlo siva" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "svetlo zelena" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "svetla rožnata" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "svetlo lososovo rdeča" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "svetlo morsko zelena" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "svetlo nebesno modra" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "bledo skrilasto siva" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "svetlo jekleno modra" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "svetlo rumena" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limeta" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limeta zeleno" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "lanena" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "kostanjeva" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "blaga morsko modra" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "blaga modra" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "blaga škrlatna orhideja" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "blaga škrlatna" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "blago morsko zelena" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "blaga skrilasto modra" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "blaga spomladansko zelena" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "blaga turkizna" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "blaga vijolično rdeča" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "črno modra" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "kremna mint" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "kožno rožnata" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokasinska oker" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajsko bela" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "mornarska" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "čipkasto bela" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "olivna" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "temno olivna" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "oranžna" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "rdeče-oranžna" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "škrlatna orhideja" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "bleda zlatorumena" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "bledo zelena" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "bleda turkizna" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "bledo vijolično rdeča" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaja" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "breskova" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "roza" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "slivova" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "sprano modra" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "škrlatna" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "rdeča" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rožnato rjava" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "kraljevsko modra" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "sedlasto rjava" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "lososovo rdeča" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "peščeno rjava" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "morsko zelena" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "školjčna" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "siena" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "srebrna" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "nebesno modra" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "skrilasto modra" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "skrilasto siva" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "snežena" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "spomladansko zelena" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "jekleno modra" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "zagorelo rjava" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "modrozelena" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "osatna" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "paradižnikova" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turkizna" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "vijolična" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "pšenična" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "bela" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "dimno bela" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "rumena" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "rumenozelena" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Omogoči" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Samodejni način žariščenja med strukturnim krmarjenjem" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Samodejni način žariščenja med krmarjenem s kazalko" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Samodejni način žariščenja med krmarjenjem s kazalko" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Pika _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Pika _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Piki 7 _in 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Prekliči" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Skoči na" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_V redu" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikona" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Brez" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Črkuj" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Oznani, kadar _prijatelji tipkajo sporočilo." - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Omogoči podporo zgodovini določenih _sporočil v klepetalnicah." - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Izgovori sporočila od" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Vse _kanali" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Vsi kanali kadar je dejavno _katerokoli %s okno programa" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Samo kanal katerega _okno je dejavno" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Izgovori ime klepetalnice." - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Omogoči način porazdelitve za vsebino" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dvojni klik" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trojni klik" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Privzeti sintetizator govora" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Dejanski niz" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Niz zamenjave" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Omogoči odmev _znakov" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Omogoči _razločevalne tipke" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Trenutno mesto" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Najmanjša dolžina skladnega besedila:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Možnosti iskanja" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Izgovori le _spremenjene vrstice med iskanjem" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Izgovori zadetke med _iskanjem" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Ukaz" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Tipkovna bližnjica" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Privzeto" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Učni način" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Dejanja" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Brajeve vezi" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Zaznamki" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Datum in čas" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Pregled miške" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Krmarjenje predmeta" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Podrobnosti predmeta" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "nedoločena tipkovna bližnjica" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Vrstični pregled" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Govor in podrobnosti razlage" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Vsebina vrstičnega pregleda" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Spremenjeno" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Namizje" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Obvestila" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Prejeto" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Prikazovanje obvestil" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Nastavitve Cthulhu za %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Označi v brajici" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Izgovori razen" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Izgovori" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Shrani profil kot spor" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Spor profila uporabnika" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profil %s že obstaja.\n" -"Ali naj se s temi spremembami posodobi obstoječi profil?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Naloži uporabniški profil" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Spremenjen bo dejavni profil. V kolikor ste\n" -"pravkar spremenili možnosti nastavitev, bodo\n" -"te izgubljene med nalaganjem profila.\n" -"\n" -"Ali naj se spremembe prezrejo in se naloži shranjeni profil?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Shrani profil kot" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Ime profila:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Odstrani uporabniški profil" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Profil %s bo s tem dejanjem odstranjen, prav tako bodo odstranjene " -"nastavitve profila. Ali želite nadaljevati in odstraniti profil in " -"nastavitve?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Vse" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Program" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Okno" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Brez" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Nekateri" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Večina" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "vrstici" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "stavku" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Navedek" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Gumb" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Naslov" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Potrditveno polje" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Klikljivo" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Spustno polje" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Opis" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Naslov" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Notranji okvir" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Slika" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Oznaka" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Mestna oznaka" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Raven" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Povezava" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Seznam" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Predmet seznama" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Predmet" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Odstavek" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radijski gumb" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Vloga" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Izbrani predmeti" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stanje" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Besedilo" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Vrednost" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Navedki" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Gumbi" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Potrditvena polja" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Razpredelnice" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Spustna polja" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Vnosi" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Polja obrazca" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Naslovi" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Notranji okvirji" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Slike" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Naslovi na %d ravni." - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Mestne oznake" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Veliki predmeti" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Povezave" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Seznami" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Predmeti seznama" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Odstavki" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radijski gumbi" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Razpredelnice" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Neobiskane povezave" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Obiskane povezave" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Krmarjenje po strani" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Samodejno začni z izgovarjanjem vsebine strani po _nalaganju" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Predstavi povzetek strani, ko je prvič naložena" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Razdeli govor na _zloge med premori" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s privzeti glas" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Privzeto" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiperpovezava" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Velike črke" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Sestavljalnik govora" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Preverjanje črkovanja" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Napaka v _črkovanju" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Predlog _črkovanja" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Predstavi _vsebino napake" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Izgovori koordinate celic razpredelnice" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Vedno izgovori obseg izbora v preglednici" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Oznani _glavo celice" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Krmarjenje po razpredelnici" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Preskoči _prazne celice" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Izgovori _celico" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Izgovori koordinate _celic" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Izgovori _širino več celic" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Ime atributa" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Nadzor nad krmarjenjem kazalke" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Omogoči _strukturno krmarjenje" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Zvočna tema:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Zvočna tema" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Kratko" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d obvestil" -msgstr[1] "%d obvestilo" -msgstr[2] "%d obvestili" -msgstr[3] "%d obvestila" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "dvigalka" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "izmenjalka" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "krmilka" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "leva dvigalka" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "leva izmenjalka" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "leva krmilka" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "desna dvigalka" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "desna izmenjalka" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "desna krmilka" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "levi meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "desni meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "zaklep številčnice" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "zaklep velikosti črk" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "zaklep dvigalke" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "zaklep drsnika" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "predhodna stran" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "naslednja stran" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "levi tabulator" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "vračalka" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "vnašalka" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "vnašalka" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "gor" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "dol" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "levo" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "desno" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "leva menijska tipka" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "desna menijska tipka" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "meni" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "pomoč" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "večnamenska tipka" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "preklopna tipka" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "ubežnica" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "vstavi" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "izbriši" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "začetek" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "konec" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "začetek" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "cirkumfleks" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "krožec" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "prečrtano" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Vstavi" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "desna izmenjalka" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "krepko %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "ležeče %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "krepko ležeče %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "skript %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "krepak skript %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "Gotski znak %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "dvojno prečrtano %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "Krepak gotski znak %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif krepko %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif ležeče %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif krepko ležeče %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "monospace %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s brez pike" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "puščica levo" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "puščica gor" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "puščica desno" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "puščica navzdol" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "puščica levo-desno" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "puščica gor-dol" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "puščica severozahod" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "puščica severovzhod" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "puščica jugovzhod" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "leva puščica s črto" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "puščica navzgor s črto" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "desna puščica s črto" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "puščica navzdol s črto" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dvojna puščica levo" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dvojna puščica gor" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dvojna puščica desno, ekvivalenca" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dvojna puščica dol" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dvojna puščica levo-desno, je ekvivalenten" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dvojna puščica gor-dol" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dvojna puščica severozahod" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dvojna puščica severovzhod" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dvojna puščica jugovzhod" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dvojna puščica jugozahod" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "desna puščica" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "desna glava puščice" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "manj kot" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "Večje kot" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "cirkumfleks" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "strešica" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "zaokrožena strešica" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "dot" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dvojna navpična črta" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "vodoravno tripičje" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "za vse" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "komplement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "delni diferencial" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "obstoja" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "ne obstaja" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "prazna množica" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "povečanje" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "je element iz" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "ni element iz" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "je mali element iz" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "vsebuje predmet" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "ne vsebuje predmeta" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "mali znak vsebuje predmet" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "konec dokaza" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produkt" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koprodukt" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "vsota" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus-plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus s piko zgoraj" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "deljenje" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "komplement" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "asterisk" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "operater krožec" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "operater vrstične oznake" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "kvadratni koren" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "tretji koren" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "četrti koren" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "je sorazmeren z" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "neskončno" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "pravi kot" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "kot" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "izmerjeni kot" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sferični kot" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "deli" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "ne deli" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "vzporedno z" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "ni vzporedno z" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logični in" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logični ali" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "presek" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unija" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dvojni integral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "trojni integral" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "krivuljni integral" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "površinski integral" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "prostorninski integral" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "integral, orientiran v smeri urinega kazalca" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "konturni integral, orientiran v smeri urinega kazalca" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "konturni integral, orientiran v nasprotni smeri urinega kazalca" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "logični znak torej" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "logični znak ker" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "razmerje" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "v razmerju" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "minus s piko zgoraj" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "presežek" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrično razmerje" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetija" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "obrnjena tilda" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "ležeči s" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusni val" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "venčni produkt" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "ni tilda" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minus-tilda" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "je asimptotično enako" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ni asimptotično enako" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "je skladen z" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "približno enak, vendar ne tudi enak z" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "niti približno enak niti enak z" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "približno enako" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ni približno enako" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "približno enako ali enako" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "trojna tilda" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "je skladen z" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekvivalentno" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrijsko ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "razlika med" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "se steka k limiti" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrično enako kot" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "približno enako kot ali slika " - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "slika ali približno enako kot" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dvopičje enačaj" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "enačaj dvopičje" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "krožec v enačaju" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "enako kot s krožcem" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "sovpada z" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "ocenjeno kot" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "enakokoten z" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "je enako z zvezdico" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta enako" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "enak kot po definiciji" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "izmerjeni kot" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "vprašljivo enak kot" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "ni enako" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "je identično enako" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "ni identično enako" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "strogo ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "less than or equal to" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "greater than or equal to" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "je manj ali je enako" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "je večje ali je enako" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "je manj, vendar ne enako" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "je več, vendar ne enako" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "much less than" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "much greater than" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "between" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "ni ekvivalentno" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "ni manjši kot" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "ni večji kot" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ni ne manjši ne enak kot" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ni ne večji ne enak kot" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "manjši kot ali ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "večji kot ali ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ni ne manjši ne ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ni ne večji ne ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "je manjši kot oziroma večji kot" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "je večji kot oziroma manjši kot" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ni ne manjši ne večji kot" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ni ne večji ne manjši kot" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "je predhodnik" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "je naslednik" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "je predhodnik ali je enako kot" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "je naslednik ali je enako kot" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "je predhodnik ali ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "je naslednik ali ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "ni predhodnik" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ni naslednik" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "je podmnožica" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "je nadmnožica" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "ni podmnožica" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "ni nadmnožica" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "je podmnožica ali je enaka množica" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "je nadmnožica ali enaka množica" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ni podmnožica niti ni enaka množica" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ni nadmnožica niti ni enaka množica" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "podmnožica, ki ni enaka kot" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "nadmnožica, ki ni enaka kot" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "množica" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "množenje množice" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "unija množice" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "Kvadrat slike" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadrat originala" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "kvadrat slike ali je enako kot" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "kvadrat originala ali je enako kot" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "kvadrat brez črte spodaj" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadrat brez črte zgoraj" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "plus v krogu, izključujoči logični ali" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "minus v krogu" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "tenzorski produkt" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "deljeno v krogu" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "točka v krogu" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "krožec v krogu" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "zvezdica v krogu" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "enačaj v krogu" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "pomišljaj v krogu" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plus v kvadratu" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "minus v kvadratu" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "krat v kvadratu" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "točka v kvadratu" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "levi element" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "desni element" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "zgornji element" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "je pravokoten na" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "napoved" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modeli" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "prav" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "vsili" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "trojna navpična črta in črta v desno" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dvojna navpična črta in enačaj v desno" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "ne potrjuje" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "ni prav" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "ne vsili" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "dvojna navpična črta in negiran enačaj v desno" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "je predhodnik pod pogojem" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "je naslednik pod pogojem" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "običajna podmnožica" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "znak vsebuje predmet kot običajno podskupino" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "običajna podmnožica ali enaka z" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "vsebuje kot običajna podmnožica ali enako kot" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "slika" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "črta s krožcem" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitska konjugirana matrika" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "interkalacija" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "xor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "logični ne-IN" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "logični ALI" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "kotnik z oznako kota" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "desni trikotnik" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "operator karo" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "operator sredinska pika" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "operator zvezdica" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "deljenje množenje" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "je naravna združitev za" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "je levi polneposredni produkt za" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "je desni polneposredni produkt za" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "levi polneposredni produkt" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "desni polneposredni produkt" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "obrnjena tilda je enako" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "zaviti logični ALI" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "zaviti logični IN" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dvojna podmnožica" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dvojna nadmnožica" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dvojni presek" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dvojna unija" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "vilice" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "enako in paralelno z" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "je manj kot s piko " - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "je več kot s piko " - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "je veliko manj kot" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "je veliko več kot" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "je manjše kot ali večje kot" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "je večje kot ali manjše kot" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "je enako ali manjše kot" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "je enako ali večje kot" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "je enako ali je predhodnik" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "je enako ali je naslednik" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "ni predhodnik ali enako kot" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ni naslednik ali enako kot" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "nekvadrirana slika ali enako kot" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "nekvadriran original ali enako kot" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "kvadrat slike ali enako kot" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "kvadrat originala ali ni enako kot" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "je manjše kot, vendar ni ekvivalentno z" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "je večje kot, vendar ni ekvivalentno z" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "je predhodnik, vendar ni ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "je naslednik, vendar ni ekvivalenten z" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "ni normalna podskupina" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "ne vsebuje kot običajna podmnožica" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "ni običajna podmnožica oziroma ni enako kot" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "ne vsebuje kot običajna podmnožica ali enako kot" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "navpično tripičje" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "sredinsko tripičje" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "desno navzgor diagonalno tripičje" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "desno navzdol diagonalno tripičje" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "je element z daljšo srednjo črto" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "vsebuje z navpično črto na srednji črti" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "mali vsebuje z navpično črto na srednji črti" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "je element s piko nad znakom" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "je element s črto zgoraj" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "je mali element s črto zgoraj" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "je element s črto spodaj" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "je element z dvema srednjima črtama" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "znak vsebuje predmet z daljšo srednjo črto" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "znak vsebuje predmet z navpično črto na srednji črti" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "mali znak vsebuje z navpično črto na srednji črti" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "znak vsebuje predmet s črto zgoraj" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "mali znak vsebuje s črto zgoraj" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "članstvo z" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "levi zgornji celi del" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "desni zgornji celi del" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "levi spodnji celi del" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "desni spodnji celi del" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "zaviti uklepaj zgoraj" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "zaviti uklepaj spodaj" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "levi kotni uklepaj" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "desni kotni zaklepaj" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "obkrožena točka" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "unija s piko" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "unija z znakom plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "kvadrat preseka" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "kvadrat unije" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "črni kvadrat" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "beli kvadrat" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "black diamond" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "white circle" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "black circle" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "white bullet" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "srednji črni kvadrat" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s podčrtano" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s s poševnico" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s z vodoravno črto" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "program" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "prazno" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "krepko" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "zaznamek vnesen" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "zaznamek shranjen" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "zaznamkov ni mogoče shraniti" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Ni najdenega nobenega zaznamka." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Ni najdenega nobenega zaznamka." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Omogočen način preusmeritve ukazov" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Ni mogoče prikazati okna računala" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikona" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" -"Slog velikih začetnic je nastavljen na predvajanje zvočne ikone pred veliko " -"začetnico." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "brez" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" -"Slog velikih začetnic je izklopljen, ob veliki začetnici program ne stori " -"ničesar." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "črkovanje" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" -"Slog velikih začetnic je nastavljen na izgovorjavo besed »velika začetnica« " -"pred veliko začetnico." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Program nadzira kazalko." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Gecko nadzira kazalnik." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Celica %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "Celica %s je izbrana" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "Celice med %s in %s so izbrane" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "Celice med %s in %s sedaj niso izbrane" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "Celica %s sedaj ni izbrana" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Prepreči uporabo možnosti" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Vsili uporabo možnosti" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "MOŽNOST" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Izbirni argumenti" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Uporaba: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Naslednji argumenti niso veljavni:" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Izpiši seznam znanih programov" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Naloži profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profila ni mogoče naložiti: %s." - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Zaslonskega bralnika ni mogoče začeti, ker ga ni mogoče povezati z namizjem." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Ni mogoče omogočiti upravljalnika nastavitev. Program bo končan." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Primerek zaslonskega bralnika je za to sejo že zagnan.\n" -"Z ukazom »cthulhu --replace« je mogoče zamenjati trenutno opravilo z novim." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "IME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Uporabi drugo mapo za nastavitve uporabnika" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "MAPA" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Različica programa" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Zamenjaj trenutno zagnani primerek zaslonskega bralnika" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Pokaži pomoč in končaj" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Pošlji izpis razhroščevanja datoteki debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Pošlji izpis razhroščevanja določeni datoteki." - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "DATOTEKA" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Nastavitve možnosti uporabnika (besedilna različica)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Nastavitve možnosti uporabnika (grafična različica)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Pošiljanje poročil o napakah na https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Izreži izbrano v odložišče." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "izreži" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Kopirana izbira v odložišče." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopirano" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Prilepljena vsebina iz odložišča." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "prilepljeno" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Ne oznani, kadar prijatelji tipkajo sporočilo." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "oznani, kadar prijatelji tipkajo sporočilo" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Sporočilo klepetalnice %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Nov zavihek klepeta %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Ne izgovori imena klepetalnice." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "izgovori ime klepetalnice." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Ne omogoči podpore zgodovini določenih sporočil v klepetalnicah." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Omogoči podporo zgodovini določenih sporočil v klepetalnicah." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "začetek brisanja" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "konec brisanja" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "začetek vstavljanja" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "konec vstavljanja" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "začetek poudarjanja" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "konec poudarjanja" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "konec predloga" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Konec predmeta." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Ni v predmetu." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "izbrani so vsi predmeti" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Privzeti gumb je %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Privzeti gumb je %s. Posiven" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Privzetega gumba ni mogoče najti" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " podpisano %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " nadpisano %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Ni v pogovornem oknu" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "izbran celoten dokument" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "izbor celotnega dokumenta je preklican" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokument izbran pod položajem kazalke" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "odstranjen izbor dokumenta pod položajem kazalke" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokument izbran na položaj kazalke" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "odstranjen izbor dokumenta na položaj kazalke" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dejavna glava stolpcev določena v vrstici %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Glava stolpca je počiščena." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dinamično določena glave vrstice za stolpec %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Počiščena je dinamična določitev glave vrstice" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "prazno" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobajtov" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabajtov" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Ni najdenih datotek." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Pripni vsebino v odložišče." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Vsebina je kopirana v odložišče." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Način vrstičnega pregleda ni v uporabi." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Omogočen je način vrstičnega pregleda." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Izstop iz načina vrstičnega pregleda." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Vrstični pregled je omejen na trenutni predmet" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Vrstični pregled brez omejitev" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "s formulo" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "odpre pogovorno okno" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "odpre razpredelnico" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "odpre seznam strani" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "odpre meni" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "odpre drevesno strukturo" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "povezava načrta slike" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Vnesena tipka je že določena za %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Zajeta tipka: %s. Za potrditev pritisnite tipko vnosa." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Nov ključ je: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Tipkovna bližnjica je izbrisana. Za potrditev pritisnite tipko enter." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Tipkovna bližnjica je odstranjena." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "vnos novega ključa" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "ključ" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Odmev vnosa določen na znak." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Brez" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Odmev vnosa ni določen." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "ključ in beseda" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Odmev vnosa določen na znak in besedo." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "stavek" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Odmev vnosa določen na stavek." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "beseda" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Odmev vnosa določen na besedo." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "beseda in stavek" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Odmev vnosa določen na besedo in stavek." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Zaprt z: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "akturialni simbol" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "škatla" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "krog" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "dolg delilni znak" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "zaklepaji" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "zaokrožena škatla" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "vodoravno prečrtano" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "navpično prečrtano" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "navzdol diagonalno prečrtano" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "navzgor diagonalno prečrtano" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "puščica severovzhod" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "črta na dnu" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "črta na levi" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "črta na desni" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "črta na vrhu" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "fazorski kot" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "arabski faktorski simbol" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "in" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "začetek ulomka" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "začetek ulomka brez črte" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "ulomljeno z" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "konec ulomka" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "kvadratni koren" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "tretji koren" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "koren" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "začetek korena" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "konec korena" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "podpisano" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "nadpisano" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pred-podpisano" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pred-nadpisano" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "podskript" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "nadskript" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "konec razpredelnice" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "konec gnezdene razpredelnice" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "nedostopno" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Onemogočeno" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Izgovarjanje zamikov in poravnav je onemogočeno." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Omogočeno" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Izgovarjanje zamikov in poravnav je omogočeno." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Učni način. Za izhod pritisnite tipko Esc." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Vstop v način učenja. Za poslušanje funkcije pritisnite poljubno tipko. Za " -"prikaz privzetih tipkovnih bližnjic pritisnite tipko F1. Za prikaz bližnjic " -"trenutno zagnanega programa pritisnite F2, za ogled dokumentacije " -"zaslonskega bralnika pritisnite F3. Za izhod iz načina učenja pritisnite " -"ubežno tipko (Esc)." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "konec navedka." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "konec podrobnosti." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "konec vira." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "konec sheme." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "konec obrazca." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "konec pasice." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "konec dodatne vsebine." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "konec podrobnosti." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "konec glavne vsebine." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "konec krmarjenja." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "konec območja." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "konec iskanja." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "konec seznama." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "konec polja." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "konec razpredelnice." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "konec orodnega namiga." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "konec povzetka." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "konec priznanja." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "konec razlage." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "konec dodatka." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "konec bibliografije." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "konec poglavja." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "konec kolofona." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "konec zaključka." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "konec zasluge." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "konec zaslug." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "konec posvetila." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "konec končnih opomb." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "konec epigrafa." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "konec epiloga." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "konec seznama tiskarskih napak." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "konec primera." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "konec predgovora." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "konec slovarja." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "konec pojmovnega kazala." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "konec uvoda." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "konec seznama strani." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "konec dela." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "konec predgovora." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "konec prologa." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "konec poudarjenega navedka." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "konec vprašanj in odgovorov." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "konec predloga." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "kazalo vsebine" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "vrstica izbrana pod položajem kazalke" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "vrstica izbrana nad položajem kazalke" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "odstranjen izbor vrstice pod položajem kazalke" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "odstranjen izbor vrstice nad položajem kazalke" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Izhod iz učnega načina." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "vrstica je izbrana od začetka do predhodne lege kazalke" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "vrstica je izbrana od prejšnje lege kazalke do konca vrstice" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "povezava" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ista spletna stran" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "isto spletišče" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "drugo spletišče" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s povezan z datoteko %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s povezava" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "obiskana povezava %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Uporaba puščic gor in dol za krmarjenje po seznamu. Za izhod pritisnite " -"tipko Esc." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Vsi samodejno posodobljeni predeli nastavljeni na nedejavno" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "Shranjena raven prijaznosti samodejno posodobljenih predelov" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "raven prijaznosti %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "nastavitev samodejno posodobljenih predelov na nedoločno" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "nastavitev samodejno posodobljenih predelov na nedejavno" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "nastavitev samodejno posodobljenih predelov na prijazno" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "nastavitev samodejno posodobljenih predelov na nesramno" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Nadzor samodejno posodobljenih predelov je izključen." - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Nadzor samodejno posodobljenih predelov je vključen." - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "Ni shranjenih samodejnih sporočil" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Podpora samodejno posodobljenim predelom" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Ni mogoče najti mesta" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Ni mogoče najti trenutnega mesta" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "onemogočeno" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "omogočeno" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "napačno črkovano" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Napačno črkovana beseda: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Vsebina je %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Načina brskanja" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Način žariščenja oken" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Za omogočanje načina žarišča pritisnite %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Lepljivi način žariščenja." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Lepljivi način brskanja" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Način razporeditve" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Predmetni način" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Kazalnik je premaknjen na predmet." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Pojavnega predmeta miške ni mogoče najti." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Govor je onemogočen." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Govor je omogočen." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Napaka: ni mogoče ustvariti seznama predmetov." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Ni podrejenih predmetov" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Ni naslednjega predmeta." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Ni nadrejenega predmeta" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Ni predhodnega predmeta" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Poenostavljeno krmarjenje predmeta je omogočeno." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Poenostavljeno krmarjenje predmeta je onemogočeno." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Raven gnezdenja %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Dodan je nov predmet" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Ni najdenih dejavnosti na: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Ni v žarišču" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Noben program nima oken v žarišču." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Ni več navedkov." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Ni več gumbov." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Ni več potrditvenih polj" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Ni več velikih predmetov." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Ni več predmetov, ki jih je mogoče klikniti." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Ni več pojavnih menijev." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Ni več vnosov." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Ni več polj v obrazcu." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Ni več naslovov." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Ni več naslovov na ravni %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Ni več notranjih okvirjev." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Ni drugih slik" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Ni najdenih mestnih oznak." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Ni več povezav." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Ni več seznamov" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Ni več predmetov seznama" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Ni več samodejno posodobljenih predelov" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Ni več odstavkov." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Ni več radijskih gumbov" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Ni več ločilnikov." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Ni več razpredelnic." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Ni več neobiskanih povezav" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Ni več obiskanih povezav." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Ni izbranega besedila" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Ni na povezavi." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Obvestilo" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Na dnu" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Na vrhu" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Ni obvestil" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "števke" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Izgovori števila kot števke" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "besede" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Izgovori števila kot besede" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "onemogočeno" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "omogočeno" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Nalaganje. Počakajte." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Končano nalaganje." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Končano nalaganje %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Stran vključuje %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "stran izbrana iz položaja kazalke" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "stran izbrana na položaj kazalke" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "odstranjen izbor strani iz položaja kazalke" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "odstranjen izbor strani na položaj kazalke" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "odstavek izbrana nižje od položaja kazalke" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "odstavek izbran višje od položaja kazalke" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "odstranjen izbor odstavka nižje od položaja kazalke" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "odstranjen izbor odstavka višje od položaja kazalke" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Okno nastavitev programa Orka je že odprto.\n" -"Zaprite prvo okno pred odpiranjem novega." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "diapozitiv %(position)d od %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Nastavljen je profil %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Ni najdenih profilov." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Vrstica napredka %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Vsa" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Izgovarjanje ločil je določeno na izgovorjavo vseh." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Večino" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Izgovarjanje ločil je določeno na izgovorjavo večine." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Brez" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Izgovarjanje ločil je onemogočeno." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Nekatera" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Izgovarjanje ločil je omejeno na izgovorjavo nekaterih." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Iskanje." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Iskanje je končano." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Nastavitve zaslonskega bralnika so ponovno naložene." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Izbrano besedilo je: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Izbira je izbrisana." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Izbira je obnovljena." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Neizbrano besedilo." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Velikost: %d, %d. Mesto: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Širina: %d. Višina: %d. %d z leve. %d od vrha." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Govor je onemogočen." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Govor je omogočen." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "hitreje." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "počasneje." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "višje." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "nižje." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "glasneje." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "tišje." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Hitrost %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Višina %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Glasnost %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Modul speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Glas speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Na voljo ni delujočega strežnika." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Na voljo ni nameščenih glasov." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Govor je omogočen." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Govor ne bo uporabljen." - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Raven podrobnosti: kratko" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Raven podrobnosti: podrobno" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " pika pika pika" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Orka različice %s." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu preži pod valovi." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Način spanja omogočen za %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Način spanja onemogočen za %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Govor ni na voljo." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Ni mogoče najti" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Vrstice stanja ni mogoče najti" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "niza ni mogoče najti" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Strukturne tipke krmarjenja so onemogočene." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Strukturne tipke krmarjenja so omogočene." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Predmeta ni mogoče najti" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Vrstica %(row)d, stolpec %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Konec razpredelnice" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Izgovori celico" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Izgovori vrstico" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Neenotna razpredelnica" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Ni v razpredelnici." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Stolpci so prerazporejeni" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Vrstice so prerazporejene" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "stolpec %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "stolpec %(index)d od %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Dno stolpca." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Vrh stolpca." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Stolpec %s je izbran" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Stolpci med %s in %s so izbrani" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Stolpci med %s in %s sedaj niso izbrani" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Stolpec %s sedaj ni izbran" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "vrstica %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "vrstica %(index)d od %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Začetek vrstice." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Konec vrstice." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Vrstica je izbrisana." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Zadnja vrstica je izbrisana." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Vrstica je vstavljena." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Vrstica je vstavljena na koncu razpredelnice." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Vrstica %s je izbrana" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Vrstice med %s in %s so izbrane" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Vrstice med %s in %s sedaj niso izbrane" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Vrstica %s sedaj ni izbrana" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "izbrano" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "neizbrano" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H ur, %M minut in %S sekund" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H ur in %M minut" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "razveljavi" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "ponovno uveljavi" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Orka različice %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "prazen prostor" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Prelom na dnu." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Prelom na vrhu." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 predmetov" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Celica je razširjena preko %d vrstic" -msgstr[1] "Celica je razširjena preko %d vrstice" -msgstr[2] "Celica je razširjena preko %d vrstic" -msgstr[3] "Celica je razširjena preko %d vrstic" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d stolpcev" -msgstr[1] "%d stolpec" -msgstr[2] "%d stolpca" -msgstr[3] "%d stolpci" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Celica je razširjena preko %d stolpcev" -msgstr[1] "Celica je razširjena preko %d stolpca" -msgstr[2] "Celica je razširjena preko %d stolpcev" -msgstr[3] "Celica je razširjena preko %d stolpcev" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d znakov predolgo" -msgstr[1] "%d znak predolgo" -msgstr[2] "%d znaka predolgo" -msgstr[3] "%d znaki predolgo" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d pogovornih oken)" -msgstr[1] "(%d pogovorno okno)" -msgstr[2] "(%d pogovorni okni)" -msgstr[3] "(%d pogovorna okna)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d pogovornih oken izven žarišča" -msgstr[1] "%d pogovorno okno izven žarišča" -msgstr[2] "%d pogovorni okni izven žarišča" -msgstr[3] "%d pogovorna okna izven žarišča" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bajtov" -msgstr[1] "%d bajt" -msgstr[2] "%d bajta" -msgstr[3] "%d bajti" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d najdenih datotek" -msgstr[1] "%d najdena datoteka" -msgstr[2] "%d najdeni datoteki" -msgstr[3] "%d najdene datoteke" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d obrazcev" -msgstr[1] "%d obrazec" -msgstr[2] "%d obrazca" -msgstr[3] "%d obrazci" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d naslovov" -msgstr[1] "%d naslov" -msgstr[2] "%d naslova" -msgstr[3] "%d naslovi" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d predmetov" -msgstr[1] "%d predmet" -msgstr[2] "%d predmeta" -msgstr[3] "%d predmeti" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d mestnih oznak" -msgstr[1] "%d mestna oznaka" -msgstr[2] "%d mestni oznaki" -msgstr[3] "%d mestne oznake" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d najdenih predmetov" -msgstr[1] "%d najden predmet" -msgstr[2] "%d najdena predmeta" -msgstr[3] "%d najdeni predmeti" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Konec %d navedkov." -msgstr[1] "Konec %d navedka." -msgstr[2] "Konec %d navedkov." -msgstr[3] "Konec %d navedkov." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Konec %d seznamov." -msgstr[1] "Konec %d seznama." -msgstr[2] "Konec %d seznamov." -msgstr[3] "Konec %d seznamov." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Seznam neznane velikosti" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Seznam s skupno %d predmeti" -msgstr[1] "Seznam s skupno %d predmetom" -msgstr[2] "Seznam s skupno %d predmetoma" -msgstr[3] "Seznam s skupno %d predmeti" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Vir neznane velikosti" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Vir s skupno %d prispevki" -msgstr[1] "Vir s skupno %d prispevkom" -msgstr[2] "Vir s skupno %d prispevkoma" -msgstr[3] "Vir s skupno %d prispevki" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Seznam opisov s skupno %d vnosi" -msgstr[1] "Seznam opisov s skupno %d vnosom" -msgstr[2] "Seznam opisov s skupno %d vnosoma" -msgstr[3] "Seznam opisov s skupno %d vnosi" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d vrednosti" -msgstr[1] "%d vrednost" -msgstr[2] "%d vrednosti" -msgstr[3] "%d vrednosti" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "matematična razpredelnica s %d vrsticami" -msgstr[1] "matematična razpredelnica z %d vrstico" -msgstr[2] "matematična razpredelnica z %d vrsticama" -msgstr[3] "matematična razpredelnica %d vrsticami" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d stolpcev" -msgstr[1] "%d stolpec" -msgstr[2] "%d stolpca" -msgstr[3] "%d stolpci" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "gnezdena matematična razpredelnica s %d vrsticami" -msgstr[1] "gnezdena matematična razpredelnica z %d vrstico" -msgstr[2] "gnezdena matematična razpredelnica z %d vrsticama" -msgstr[3] "gnezdena matematična razpredelnica z %d vrsticami" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d sporočil.\n" -msgstr[1] "%d sporočilo.\n" -msgstr[2] "%d sporočili.\n" -msgstr[3] "%d sporočila.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d odstotkov." -msgstr[1] "%d odstotek." -msgstr[2] "%d odstotka." -msgstr[3] "%d odstotki." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "Prebranih je %d odstotkov dokumenta" -msgstr[1] "Prebran je %d odstotek dokumenta" -msgstr[2] "Prebrana sta %d odstotkav dokumenta" -msgstr[3] "Prebrani so %d odstotki dokumenta" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d točk" -msgstr[1] "%d točka" -msgstr[2] "%d točki" -msgstr[3] "%d točke" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(repeatChar)s %(count)d ponovitev" -msgstr[1] "%(repeatChar)s %(count)d ponovitev" -msgstr[2] "%(repeatChar)s %(count)d ponovitvi" -msgstr[3] "%(repeatChar)s %(count)d ponovitve" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d od %(total)d izbranih predmetov" -msgstr[1] "%(index)d od %(total)d izbranega predmeta" -msgstr[2] "%(index)d od %(total)d izbranih predmetov" -msgstr[3] "%(index)d od %(total)d izbranih predmetov" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Najdenih je %d privzetih tipkovnih bližnjic zaslonskega bralnika." -msgstr[1] "Najdena je %d privzeta tipkovna bližnjica zaslonskega bralnika." -msgstr[2] "Najdeni sta %d privzeti tipkovni bližnjici zaslonskega bralnika." -msgstr[3] "Najdene so %d privzete tipkovne bližnjice zaslonskega bralnika." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Najdenih je %(count)d tipkovnih bližnjic zaslonskega bralnika za program " -"%(application)s." -msgstr[1] "" -"Najdena je %(count)d tipkovna bližnjica zaslonskega bralnika za program " -"%(application)s." -msgstr[2] "" -"Najdeni sta %(count)d tipkovni bližnjici zaslonskega bralnika za program " -"%(application)s." -msgstr[3] "" -"Najdene so %(count)d tipkovne bližnjice zaslonskega bralnika za program " -"%(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d presledkov" -msgstr[1] "%d presledek" -msgstr[2] "%d presledka" -msgstr[3] "%d presledki" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulatorjev" -msgstr[1] "%d tabulator" -msgstr[2] "%d tabulatorja" -msgstr[3] "%d tabulatorji" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d razpredelnic" -msgstr[1] "%d razpredelnica" -msgstr[2] "%d razpredelnici" -msgstr[3] "%d razpredelnice" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "kazalo neznane velikosti" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "razpredelnica s skupno %d stolpci, število vrstic ni znano" -msgstr[1] "razpredelnica s skupno %d stolpcem, število vrstic ni znano" -msgstr[2] "razpredelnica s skupno %d stolpcema, število vrstic ni znano" -msgstr[3] "razpredelnica s skupno %d stolpci, število vrstic ni znano" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "razpredelnica s skupno %d vrsticami, število stolpcev ni znano" -msgstr[1] "razpredelnica s skupno %d vrstico, število stolpcev ni znano" -msgstr[2] "razpredelnica s skupno %d vrsticama, število stolpcev ni znano" -msgstr[3] "razpredelnica s skupno %d vrsticami, število stolpcev ni znano" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "razpredelnica s skupno %d vrsticami" -msgstr[1] "razpredelnica s skupno %d vrstico" -msgstr[2] "razpredelnica s skupno %d vrsticama" -msgstr[3] "razpredelnica s skupno %d vrsticami" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "Pred %d sekundami" -msgstr[1] "Pred %d sekundo" -msgstr[2] "Pred %d sekundama" -msgstr[3] "Pred %d sekundami" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "Pred %d minutami" -msgstr[1] "Pred %d minuto" -msgstr[2] "Pred %d minutama" -msgstr[3] "Pred %d minutami" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "Pred %d urami" -msgstr[1] "Pred %d uro" -msgstr[2] "Pred %d urama" -msgstr[3] "Pred %d urami" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "Pred %d dnevi" -msgstr[1] "Pred %d dnevom" -msgstr[2] "Pred %d dnevoma" -msgstr[3] "Pred %d dnevi" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d neobiskanih povezav" -msgstr[1] "%d neobiskana povezava" -msgstr[2] "%d neobiskani povezavi" -msgstr[3] "%d neobiskane povezave" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d obiskanih povezav" -msgstr[1] "%d obiskana povezava" -msgstr[2] "%d obiskani povezavi" -msgstr[3] "%d obiskane povezave" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "preklopi" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "na %(index)d od %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d od %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "predmet %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "Raven %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "raven drevesa %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "Raven drevesa %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "podrobnosti za %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "vključuje podrobnosti za %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "predlog" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "uredljiv pojavni meni" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "uredljiva vsebina" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "vir" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "shema" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "povzetek" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "priznanje" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "razlaga" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "dodatek" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "bibliografski vnos" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografija" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "poglavje" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "kolofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "zaključek" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "naslovnica" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "zasluga" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "zasluge" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "posvetilo" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "končna opomba" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "končne opombe" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "seznam tiskarskih napak" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "primer" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "predgovor" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "slovar" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "pojmovno kazalo" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "uvod" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "prelom strani" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "seznam strani" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "del" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "predgovor" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "poudarjen navedek" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "Vprašanja in odgovori" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "podnapis" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "kazalo" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s raven %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "vodoravni drsnik" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "navpični drsnik" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "vodoravni drsnik" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "navpični drsnik" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "vodoravni razdelilnik" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "razdelilnik" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "preklopna tipka" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Pult ikon" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "pasica" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "dodatna vsebina" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "podrobnosti" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "glavna vsebina" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "krmarjenje" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "območje" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "iskanje" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "obiskana povezava" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "gumb menija" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "razvrščeno naraščajoče" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "razvrščeno padajoče" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "razvrščeno" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klikljivo" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "zloženo" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "razširjeno" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "ima dolg opis" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "vodoravno" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "navpično" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "označeno" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "ni označeno" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "omogočeno" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "onemogočeno" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "delno označeno" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "pritisnjeno" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ni pritisnjeno" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "ni izbrano" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "izbrano" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ni izbrano" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "ni izbrano" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "obiskano" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "neobiskano" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "sivo" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "le za branje" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "samo za branje" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "zahtevano" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "več izbir" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "neveljaven vnos" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "neveljavno" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "neveljavno črkovanje" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "črkovanje" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "neveljavna slovnica" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "slovnica" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Najdi" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Pogovorno okno zaslonskega bralnika" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Zapri" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Najdi" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Poišči:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Poišči:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Vrh okna" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Vrh okna" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Začni od:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Prelomi vrstice" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Poišči _nazaj" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Smer iskanja:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Upoštevaj velikost črk" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Poišči le _cele besede" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Možnosti:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Privzeto" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Velike črke" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiperpovezava" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Program" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Okno" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Nastavitve Orke" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "Pomo_č" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Uveljavi" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Prenosni računalnik" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Razpored tipkovnice" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Dejavni profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Začetni profil:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Naloži" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Shrani _kot" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Odstrani" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profili" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Uporabi namige" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Govorni predmet pod _miško" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Miška" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Oblika zapisa _časa:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Oblika zapisa _datuma:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Čas in datum" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Izgovori posodobitve" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Izgovori _Brajeve posodobitve" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frekvenca (sek):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Uveljavljen za:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Zapiskaj ob _posodobitvah" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Posodobitve kazalnik napredka" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Omogoči preskoke vsebine naprej in nazaj v načinu polne izgovorjave" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Omogoči _strukturno krmarjenje v načinu polne izgovorjave" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Izgovori _vse v:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Oznani _navedke v načinu polne izgovorjave" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Oznani _sezname v načinu polne izgovorjave" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Oznani _razpredelnice v načinu polne izgovorjave" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Oznani _polja v načinu polne izgovorjave" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Oznani _obrazce v načinu polne izgovorjave" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Oznani _mestne oznake v načinu polne izgovorjave" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Izgovori vse" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Predstavitev elementa:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Splošno" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "G_lasnost:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "_Višina:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "Hit_rost:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Oseba:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Jezik:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Sinte_za govora:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Govorni _sistem:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Vrsta _glasu:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Slog _velikih začetnic:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Nastavitve vrste glasu" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Izgovori nize z več besedami kot _besede" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Izgovori _števila kot števke" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Splošne nastavitve glasu" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Glas" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Omogoči govor" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Podrobno" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Razločnost" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Vse" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Raven ločil" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Izgovori le prikazano besedilo" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Izgovori prazne vrstice" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "_Izgovarjanje zamikov in poravnav" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Izgovori _mnemotehniko predmeta." - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Izgovori p_odrejeno lego" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Izgovori sporočila vodnika" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Sistemska sporočila so podrobna" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Izgovori _barve z imeni" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Oznani _navedke med krmarjenjem" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Oznani _sezname med krmarjenjem" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Oznani _razpredelnice med krmarjenjem" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "_Izgovori označeno napačno črkovano besede" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Oznani _polja v načinu polne izgovorjave" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Oznani _mestne oznake med krmarjenjem" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Oznani _obrazce med krmarjenjem" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Izgovori _opis" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Izgovori celotno vrstico v _preglednici" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Izgovori celotno vrstico v _razpredelnici dokumenta" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Izgovori celotno vrstico v _razpredelnicah vmesnika" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Vsebina izgovorjave" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Govor" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Omogoči podporo _brajici" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Okr_ajšana imena vlog" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Onemogoči simbol za _konec vrstice" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_Razpredelnica skrčenih zapisov" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Omogoči skrčeni zapis brajice" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Omogoči prelom _besed" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Nastavitve zaslona" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Brez" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Kazalnik izbire" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Kazalnik hiperpovezav" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Omogoči _hitra sporočila" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Trajanje (sekunde):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Sporočila so _ponavljanoča" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Sporočila so _podrobna" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Nastavitve hitrih sporočil" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Brajeva pisava" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Omogoči odmev t_ipk" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Omogoči tipke _črk" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Omogoči tipke _številk" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Omogoči tipke _ločil" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Omogoči _presledek" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Omogoči _spremenilne tipke" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Omogoči _funkcijske tipke" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Omogoči _tipke dejanj" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Omogoči _krmilne tipke" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Omogoči odmev _besed" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Omogoči odmev _stavkov" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Odmev" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Spremenilne tipke zaslonskega bralnika:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Tipkovne povezave" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Slovar izgovorjav" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Nov vnos" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Izbriši" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Izgovorjava" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Izgovori vse" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Ne izgovarjaj" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Ponastavi" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributi besedila" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Premakni na dn_o" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Premakni eno navz_dol" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Premakni eno navz_gor" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Premakni na vr_h" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Prilagodi izbrane atribute" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Brajev kazalnik" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributi besedila" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Omogoči AI pomočnika" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Ponudnik:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokalno - Brezplačno)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Datoteka API _ključa:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Pot do datoteke ključa API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Pridobi _Claude API ključ" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Odpri brskalnik za pridobitev Claude API ključa in samodejno shrani" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Zahtevaj potrditev pred dejanji AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _model:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Ime modela za Ollama (npr. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _končna točka:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL končne točke Ollama API (npr. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Kakovost posnetka zaslona:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "nizko" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Srednja" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Visoka" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI pomočnik" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Jezik:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "jenov" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Faktor povečave:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Sivinska slika" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Obrni sliko" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Črno-bela slika" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Prag črno/belo:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analiziraj barve" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Vsebina je kopirana v odložišče." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alfa, b : bravo, c : cesta, č : čas d : delta, e : eho, f : fokstrot, " -"g : golf, h : hotel, i : india, j : julija, k : kilo, l : lima, m : mati, " -"n : november, o : oslo, p : pero, q : quebec, r : romeo, s : sestra, š : " -"šivanka t : trava u : usta, v : viktor, w : whiskey, x : xray, y : yankee, " -"z : zulu ž : žival" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "barva ozadja" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "polna višina ozadja" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "točkanje ozadja" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "smer" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "uredljivo" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "družinsko ime" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "barva pisave" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "točkanje pisave" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "učinek pisave" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "zamik" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "napaka" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "nevidno" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "poravnava" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "jezik" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "levi rob" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "višina vrstice" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "slog odstavka" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "točke nad vrstico" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "točke pod vrstico" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "točke znotraj preloma" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "desni rob" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "dvigni" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "povečava" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "velikost" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "raztegnjeno" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "prečrtano" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "slog" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "oblikovanje besedila" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "vrtenje besedila" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "senčenje besedila" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "podčrtano" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "velikost pisave" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "navpična poravnava" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "teža" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "način preloma" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "način pisanja" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "prav" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "napak" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "brez" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "izrezljano" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "vbočeno" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "oris" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "nadčrtano" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "prečrtano" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "utripanje" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "črna" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "enojno" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dvojno" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "nizko" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "znak" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "beseda" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "znak besede" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "lzd" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "dzl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "levo" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "desno" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "sredinsko" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "brez poravnave" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "polnilo" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "najbolj skrčeno besedilo" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "bolj skrčeno besedilo" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "skrčeno besedilo" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "malo skrčeno besedilo" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "običajno besedilo" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "malo razširjeno besedilo" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "razširjeno besedilo" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "bolj razširjeno besedilo" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "najbolj razširjeno besedilo" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "mele velike črke" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "poševno" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "ležeče" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "privzeto" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Telo besedila" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Naslov" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "osnovnica besedila" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "podpisano" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "nadpisano" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "zgoraj" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "besedilo-zgoraj" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "na sredini" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "na dnu" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "besedilo-na-dnu" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "prevzemi" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "ld-zn" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "dl-zn" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "zn-dl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "zn-ld" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "sn-dl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "sn-ld" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "ld" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "dl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "zn" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "polno" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "črkovanje" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Za preklop pritisnite preslednico." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Za razširitev pritisnite preslednico, za izbor predmeta pa uporabite smerni " -"tipki gor in dol." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Za izbor podrejenega okna v žarišče uporabite sočasno tipki alt+F6." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Za premik na predmete, uporabite smerne tipke ali pa vpišite besedo v " -"iskalnik." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Za dostop do sistemskih menijev pritisnite tipki alt+F." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Uporabite tipki gor in dol za izbiro predmeta." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Za zložitev sočasno pritisnite shift in levo smerno tipko." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Za razširitev sočasno pritisnite shift in desno smerno tipko." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Za zagon je treba pritisniti vnašalko." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Vnosno polje besedila." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Uporabite tipki levo in desno za pregled ostalih zavihkov." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Za zagon pritisnite preslednico." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Za izbor vrednosti uporabite tipki gor in dol ali pa vtipkate želene " -"številčne vrednosti." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Za spreminjanje uporabite smerne tipke." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Za krmarjenje pritisnite levo ali desno smerno tipko, za prehod med predmeti " -"pa smerni tipki gor in dol." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Za vstop v podrejeni meni pritisnite desno smerno tipko." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Za zmanjšanje pritisnite levo puščico, za povečanje pa desno. Za najmanjšo " -"vrednost pritisnite tipko Začetek, za največjo pa tipko Konec." diff --git a/po/sq.po b/po/sq.po deleted file mode 100644 index e79ceea..0000000 --- a/po/sq.po +++ /dev/null @@ -1,10007 +0,0 @@ -# Përkthimi i cthulhu.HEAD në shqip. -# Copyright (C) 2007 Free Software Foundation, Inc. -# This file is distributed under the same license as the CTHULHU package. -# -# Laurent Dhima , 2007. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2007-09-14 12:21+0200\n" -"Last-Translator: Laurent Dhima \n" -"Language-Team: albanian \n" -"Language: sq\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#, fuzzy -msgid "Cthulhu Screen Reader" -msgstr "Ekrani Zmadhues (Lupë)" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -#, fuzzy -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:97 -#, fuzzy -msgctxt "shortbraille" -msgid "dial" -msgstr "telefonatë" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:124 -#, fuzzy -msgctxt "shortbraille" -msgid "form" -msgstr "formular" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:289 -#, fuzzy -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "hapësirë" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "rresht i ri" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "skedë" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "pikëçuditje" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "citim" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "numër" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "përqindje" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "dhe" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrofë" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "kllapë e majtë" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "kllapë e djathtë" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "yll" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "presje" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "vizë ndarëse" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "pikë" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "slash" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dy pika" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "pikëpresje" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "më e vogël" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "e barabartë" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "më e madhe" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "pikëpyetje" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "kllapë e drejtë e majtë" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "backslash" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "kllapë e drejtë e djathtë" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "caret" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "nënvijë" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "pikë theksuese" - -#: src/cthulhu/chnames.py:170 -#, fuzzy -msgid "left brace" -msgstr "majtas" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "shtyllë vertikale" - -#: src/cthulhu/chnames.py:178 -#, fuzzy -msgid "right brace" -msgstr "djathtas" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cents" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pounds" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "shtyllë e ndërprerë" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "seksion" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "kllapë e dyfishtë këndore e majtë" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logical not" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "regjistruar" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "gradë" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus ose minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superscript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superscript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -#, fuzzy -msgid "acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "shënues paragrafi" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "pikë e mesme" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superscript 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "kllapë e dyfishtë këndore e djathtë" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "një e katërta" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "një e dyta" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tre të katërtat" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "pikëçuditje e përmbysur" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "Ë" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "times" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a me theks" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "ç" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e me theks" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "ë" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i me theks" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o me theks" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "pjestuar me" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u me theks" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "thonjëzë e majtë teke" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "thonjëzë e djathtë teke" - -#: src/cthulhu/chnames.py:593 -#, fuzzy -msgid "single low quote" -msgstr "thonjëzë e majtë teke" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "thonjëzë e majtë dyshe" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "thonjëzë e djathtë dyshe" - -#: src/cthulhu/chnames.py:605 -#, fuzzy -msgid "double low quote" -msgstr "thonjëzë e majtë dyshe" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "dagger" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dopjo dagger" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prime" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "double prime" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "double prime" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "hyphen bullet" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "euro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "trademark" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "shenja zgjedhjes" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "shenjë e theksuar zgjedhje" - -#: src/cthulhu/chnames.py:668 -#, fuzzy -msgid "x-shaped bullet" -msgstr "x" - -#: src/cthulhu/chnames.py:672 -#, fuzzy -msgid "superscript 0" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:676 -#, fuzzy -msgid "superscript 4" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:680 -#, fuzzy -msgid "superscript 5" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:684 -#, fuzzy -msgid "superscript 6" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:688 -#, fuzzy -msgid "superscript 7" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:692 -#, fuzzy -msgid "superscript 8" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:696 -#, fuzzy -msgid "superscript 9" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:700 -#, fuzzy -msgid "superscript plus" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:704 -#, fuzzy -msgid "superscript minus" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:708 -#, fuzzy -msgid "superscript equals" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:720 -#, fuzzy -msgid "superscript n" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:724 -#, fuzzy -msgid "subscript 0" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:728 -#, fuzzy -msgid "subscript 1" -msgstr "superscript 1" - -#: src/cthulhu/chnames.py:732 -#, fuzzy -msgid "subscript 2" -msgstr "superscript 2" - -#: src/cthulhu/chnames.py:736 -#, fuzzy -msgid "subscript 3" -msgstr "superscript 3" - -#: src/cthulhu/chnames.py:740 -#, fuzzy -msgid "subscript 4" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:744 -#, fuzzy -msgid "subscript 5" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:748 -#, fuzzy -msgid "subscript 6" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:752 -#, fuzzy -msgid "subscript 7" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:756 -#, fuzzy -msgid "subscript 8" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:760 -#, fuzzy -msgid "subscript 9" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:764 -#, fuzzy -msgid "subscript plus" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:772 -#, fuzzy -msgid "subscript equals" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "kllapë e majtë" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "kllapë e djathtë" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "kuti e zezë" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "diamant i zi" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "majtas kliko në element." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "djathtas kliko në element." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Shqipto të gjithë dokumentin." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "Shqipto të gjithë dokumentin." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "Më thuaj ku jam." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "Më thuaj ku jam." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Flit" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "Flit në të bardhë rreshta" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "Prezantime" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Hap dritaren e dialogut Cthulhu për kërkime." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "Kërkon korresponduesin në vijim të një teksti." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "Kërkon korresponduesin paraardhës të një teksti." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "dhe modaliteti." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "fund." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "shtëpia." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "fund." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "nga." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "element." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "element." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "element." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "nga." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "element." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "element." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "element." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "element." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "element." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "element." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "element." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "element." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "element." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "element." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "element." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "element." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "element." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "fund nga." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "poshtë majtas." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "fund." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "me tekst." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "braille majtas." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "braille djathtas." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "me tastiera." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "nga." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Aktivon modalitetin e mësimit. Shtyp escape për të dalë nga ky modalitet." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "Ul shpejtësinë e shqiptimit." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "Rrit shpejtësinë e shqiptimit." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "shqiptimi." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "shqiptimi." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Rrit shpejtësinë e shqiptimit." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Ul shpejtësinë e shqiptimit." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Zgjidh shqiptimi." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Zgjidh shqiptimi." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "Ul shpejtësinë e shqiptimit." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "Rrit shpejtësinë e shqiptimit." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "nga shqiptimi." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "Shfaq dritaren e dialogut të konfigurimit të preferimeve." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "" -"Shfaq dritaren e dialogut të konfigurimit të preferimeve të aplikativit." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "Fl_it dhe" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "titull etiketa." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "Speech:" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "Libërshënues pd I me." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "Shko tek pozicioni paraardhës në libërshënues." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "Shko tek libërshënimi." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "Shko tek pozicioni në vazhdim në libërshënues." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "Shto libërshënues." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "Ruaj libërsh[nuesin." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "Flit dhe braille a mesazh." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Kavo me emri nga." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "Kavo me emri nga." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Linja majtas" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Linja djathtas" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Linja sipër" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Linja poshtë" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Sipër majtas" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "Poshtë djathtas" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Pozicioni i kursorit" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "Pozicioni i kursorit" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "Linja" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "formular." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "formular." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "nga." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "fund nga." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "e shtrirë." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "Ndryshues dhe." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "kreu." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "kreu." - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "nga." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "në." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "Jo." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Shfaq" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "titull." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "titull." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "formular." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "formular." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "m" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "m" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "formular." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "formular." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "titull." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "titull." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "titull etiketa." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "titull etiketa." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Jo etiketa." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "kornizë e brendshme" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "titull." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Jo." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Jo." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Jo." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Shfaq" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "listë element." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "listë element." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "listë element." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "listë element." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "me tastiera." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "me tastiera." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "titull." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "titull." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "titull." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "pulsant radio" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "listë." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "tabelë." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "poshtë." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "i pari në a tabelë." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "e fundit në a tabelë." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "majtas." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "djathtas." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "sipër." - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "A_ktivo" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "lidhje." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "lidhje." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "Jo." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "lidhje." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "lidhje." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "Jo." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "diamant i zi" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "a me theks" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i me theks" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "jeshile" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "gradë" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "djathtas" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "djathtas kontrolli" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "kllapë e djathtë" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "djathtas" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "kllapë e djathtë" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "kllapë e djathtë" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "djathtas alt" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "kllapë e djathtë" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "rresht i ri" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Figura" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "jeshile" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "gradë" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "skedë" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "hapësirë bosh" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "hapësirë bosh" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -#, fuzzy -msgid "Dot _7" -msgstr "Pikë _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -#, fuzzy -msgid "Dot _8" -msgstr "Pikë _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -#, fuzzy -msgid "Dots 7 an_d 8" -msgstr "Pika _dhe 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikona" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Asnjë" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -#, fuzzy -msgid "_Speak Chat Room name" -msgstr "Flit Dhoma emri" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -#, fuzzy -msgid "double click" -msgstr "double prime" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -#, fuzzy -msgid "Default Synthesizer" -msgstr "E prezgjedhur" - -#: src/cthulhu/guilabels.py:218 -#, fuzzy -msgid "Actual String" -msgstr "Stringë" - -#: src/cthulhu/guilabels.py:227 -#, fuzzy -msgid "Replacement String" -msgstr "Zëvendësim Stringë" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "Aktivo nga" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "Ak_tivo" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -#, fuzzy -msgid "C_urrent location" -msgstr "Akt_ual pozicioni" - -#: src/cthulhu/guilabels.py:249 -#, fuzzy -msgid "Minimum length of matched text:" -msgstr "nga tekst:" - -#: src/cthulhu/guilabels.py:253 -#, fuzzy -msgid "Find Options" -msgstr "Gjej Mundësitë" - -#: src/cthulhu/guilabels.py:259 -#, fuzzy -msgid "Onl_y speak changed lines during find" -msgstr "Vetëm rreshta gjej" - -#: src/cthulhu/guilabels.py:265 -#, fuzzy -msgid "Speak results during _find" -msgstr "_Flit gjej" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "presje" - -#: src/cthulhu/guilabels.py:275 -#, fuzzy -msgid "Key Binding" -msgstr "Kyçi" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "E prezgjedhur" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Dil nga modaliteti i mësimit." - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "seksion" - -#: src/cthulhu/guilabels.py:296 -#, fuzzy -msgid "Braille Bindings" -msgstr "Braille" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "Ruaj libërsh[nuesin." - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "Tabela Lundrimi" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -#, fuzzy -msgid "Unbound" -msgstr "pounds" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "Ndryshuar" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -#, fuzzy -msgid "_Desktop" -msgstr "_Desktop" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "titull" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Preferimet Cthulhu për %s" - -#: src/cthulhu/guilabels.py:396 -#, fuzzy -msgid "Mark in braille" -msgstr "në braille" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -#, fuzzy -msgid "Speak" -msgstr "Flit" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "Të gjith_a" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "Aplikativi" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "Dritarja" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "_Asnjë" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -#, fuzzy -msgid "So_me" -msgstr "Ndonjë" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -#, fuzzy -msgid "Line" -msgstr "Linja" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "citim" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Butoni" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "Kapitulli" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "kuti zgjedhjeje" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "kuti e kombinuar" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "titull" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Titulli" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "kornizë e brendshme" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Figura" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiketa" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "trademark" - -#: src/cthulhu/guilabels.py:611 -#, fuzzy -msgctxt "structural navigation" -msgid "Level" -msgstr "etiketa" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "Lidhje" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "element liste" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragrafi" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "pulsant radio" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "zgjedhur" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "Gjendja" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Teksti" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Jo." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Butoni" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "kuti zgjedhjeje" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "kuti e kombinuar" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "Titulli" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "kornizë e brendshme" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Figura" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Jo etiketa." - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "trademark" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Jo." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "Lidhje" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "element liste" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragrafi" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "pulsant radio" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabela" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "lidhje" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "lidhje" - -#: src/cthulhu/guilabels.py:801 -#, fuzzy -msgid "Page Navigation" -msgstr "Faqja Lundrimi" - -#: src/cthulhu/guilabels.py:807 -#, fuzzy -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "a faqe është i pari" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "a faqe është i pari" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, fuzzy, python-format -msgid "%s default voice" -msgstr "prezgjedhur" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "E prezgjedhur" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "lidhje" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "përqindje" - -#: src/cthulhu/guilabels.py:852 -#, fuzzy -msgid "Speech Dispatcher" -msgstr "Speech" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "Flit" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -#, fuzzy -msgid "Announce cell _header" -msgstr "kreu" - -#: src/cthulhu/guilabels.py:896 -#, fuzzy -msgid "Table Navigation" -msgstr "Tabela Lundrimi" - -#: src/cthulhu/guilabels.py:900 -#, fuzzy -msgid "Skip _blank cells" -msgstr "Kapërce në të _bardhë" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "Shqipto qelinë" - -#: src/cthulhu/guilabels.py:909 -#, fuzzy -msgid "Speak _cell coordinates" -msgstr "Flit" - -#: src/cthulhu/guilabels.py:914 -#, fuzzy -msgid "Speak _multiple cell spans" -msgstr "Flit shu_mëfish" - -#: src/cthulhu/guilabels.py:918 -#, fuzzy -msgid "Attribute Name" -msgstr "Pronësi Emri" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "Theksi Lundrimi" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "Lundrimi" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alert" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "majtas kontrolli" - -#: src/cthulhu/keynames.py:60 -#, fuzzy -msgid "left shift" -msgstr "majtas shift" - -#: src/cthulhu/keynames.py:64 -#, fuzzy -msgid "left alt" -msgstr "majtas alt" - -#: src/cthulhu/keynames.py:68 -#, fuzzy -msgid "left control" -msgstr "majtas kontrolli" - -#: src/cthulhu/keynames.py:72 -#, fuzzy -msgid "right shift" -msgstr "djathtas shift" - -#: src/cthulhu/keynames.py:76 -#, fuzzy -msgid "right alt" -msgstr "djathtas alt" - -#: src/cthulhu/keynames.py:80 -#, fuzzy -msgid "right control" -msgstr "djathtas kontrolli" - -#: src/cthulhu/keynames.py:84 -#, fuzzy -msgid "left meta" -msgstr "majtas" - -#: src/cthulhu/keynames.py:88 -#, fuzzy -msgid "right meta" -msgstr "djathtas" - -#: src/cthulhu/keynames.py:92 -#, fuzzy -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -#, fuzzy -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -#, fuzzy -msgid "page up" -msgstr "faqja shkon sipër" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -#, fuzzy -msgid "page down" -msgstr "faqja poshtë" - -#: src/cthulhu/keynames.py:145 -#, fuzzy -msgid "left tab" -msgstr "majtas tab" - -#: src/cthulhu/keynames.py:153 -#, fuzzy -msgid "backspace" -msgstr "hapësirë" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "" - -#: src/cthulhu/keynames.py:161 -#, fuzzy -msgid "enter" -msgstr "Në qendër" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -#, fuzzy -msgid "down" -msgstr "faqja poshtë" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -#, fuzzy -msgid "left" -msgstr "majtas alt" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -#, fuzzy -msgid "right" -msgstr "copyright" - -#: src/cthulhu/keynames.py:197 -#, fuzzy -msgid "left super" -msgstr "kllapë e majtë" - -#: src/cthulhu/keynames.py:201 -#, fuzzy -msgid "right super" -msgstr "kllapë e djathtë" - -#: src/cthulhu/keynames.py:205 -#, fuzzy -msgid "menu" -msgstr "menu" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -#, fuzzy -msgid "delete" -msgstr "_Elemino" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -#, fuzzy -msgid "end" -msgstr "dhe" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -#, fuzzy -msgid "circumflex" -msgstr "a circumflex" - -#: src/cthulhu/keynames.py:291 -#, fuzzy -msgid "ring" -msgstr "a ring" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "o stroke" - -#: src/cthulhu/keynames.py:305 -#, fuzzy -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "" - -#: src/cthulhu/keybindings.py:171 -#, fuzzy -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "" - -#: src/cthulhu/keybindings.py:188 -#, fuzzy -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -#, fuzzy -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "me të trasha" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "Konteksti është %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "kllapë e majtë" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "shigjetë" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "kllapë e djathtë" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "shigjetë" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "shigjeta-djathtas" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "thonjëzë e majtë dyshe" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dopjo dagger" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "thonjëzë e djathtë dyshe" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dopjo dagger" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "thonjëzë e djathtë dyshe" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "shigjeta-djathtas" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "kokë shigjete-djathtas" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "më e vogël" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "më e madhe" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "a circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "pikë" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horizontalisht" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "plotësim automatik" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "Mbarimi nga." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "plus ose minus" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "ndarës" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "rrënjë kubike" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "pafundësi" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "djathtas alt" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "panel me nivele" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "pjestuar me" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Ndarës" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "e ndryshme nga" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "seksion" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "kornizë e brendshme" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:1512 -#, fuzzy -msgctxt "math symbol" -msgid "triple integral" -msgstr "Rifresko:" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -#, fuzzy -msgctxt "math symbol" -msgid "surface integral" -msgstr "Rifresko:" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "a tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "afërsisht e barabartë" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "afërsisht e barabartë" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "afërsisht e barabartë" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "afërsisht e barabartë" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "afërsisht e barabartë" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "afërsisht e barabartë" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "a tilde" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "afërsisht e barabartë" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "e ndryshme nga" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "e barabartë" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "e barabartë" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "e ndryshme nga" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "e ndryshme nga" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "e barabartë" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "e ndryshme nga" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "e ndryshme nga" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "vertikalisht" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "e ndryshme nga" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "e ndryshme nga" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "më e madhe" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "jo i shtypur" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "zgjedhje e shumëfishtë" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "zgjedhje e shumëfishtë" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "e barabartë" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "en dash" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "plus ose minus" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "djathtas" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "majtas tab" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "seksion" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "jo i shtypur" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ordinal" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "figurë" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "kornizë e brendshme" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "thonjëzë e djathtë teke" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "djathtas" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "ndarës" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "më i vogël ose i barabartë" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "më i madh ose i barabartë" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertikalisht" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "kllapë e majtë" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "kllapë e djathtë" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "majtas alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "djathtas alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "majtas" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "majtas" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "kllapë e dyfishtë këndore e majtë" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "kllapë e dyfishtë këndore e djathtë" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "pikë e mesme" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "rrënjë katrore" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "kuti e zezë" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "kuti e bardhë" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "diamant i zi" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "rreth i bardhë" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "rreth i zi" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "e bardhë" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "kuti e zezë" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "nënvijë" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "aplikativ" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "rresht bosh" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "me të trasha" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -#, fuzzy -msgid "bookmarks could not be saved" -msgstr "nuk" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "Shko tek libërshënimi." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "teksti nuk u gjet" - -#: src/cthulhu/messages.py:93 -#, fuzzy -msgid "Bypass mode enabled." -msgstr "Speech." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ikonë" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "është." - -#: src/cthulhu/messages.py:170 -#, fuzzy -msgid "Cthulhu is controlling the caret." -msgstr "është." - -#: src/cthulhu/messages.py:173 -#, fuzzy, python-format -msgid "Cell %s" -msgstr "Qeli" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "zgjedhur" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "nga element zgjedhur" - -#: src/cthulhu/messages.py:193 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "nga element zgjedhur" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "i pa zgjedhur" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "nuk" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "a acute" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, fuzzy, python-format -msgid "Message from chat room %s" -msgstr "Mesazhi" - -#: src/cthulhu/messages.py:385 -#, fuzzy, python-format -msgid "New chat tab %s" -msgstr "E re tab" - -#: src/cthulhu/messages.py:394 -#, fuzzy -msgid "Do not speak chat room name." -msgstr "nuk emri." - -#: src/cthulhu/messages.py:403 -#, fuzzy -msgid "speak chat room name." -msgstr "emri." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "seksion" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "pikëpyetje" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "m" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "Not në a tabelë." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "nga element zgjedhur" - -#: src/cthulhu/messages.py:498 -#, fuzzy, python-format -msgid "Default button is %s" -msgstr "E prezgjedhur është" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "E prezgjedhur është" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "E prezgjedhur është" - -#: src/cthulhu/messages.py:518 -#, fuzzy, python-format -msgid " subscript %s" -msgstr "superscript a" - -#: src/cthulhu/messages.py:524 -#, fuzzy, python-format -msgid " superscript %s" -msgstr "superscript a" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "Not në a tabelë." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "zgjedhur i gjithë dokumenti" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "zgjedhur i gjithë dokumenti" - -#: src/cthulhu/messages.py:548 -#, fuzzy -msgid "document selected from cursor position" -msgstr "zgjedhur" - -#: src/cthulhu/messages.py:554 -#, fuzzy -msgid "document unselected from cursor position" -msgstr "zgjedhur" - -#: src/cthulhu/messages.py:560 -#, fuzzy -msgid "document selected to cursor position" -msgstr "zgjedhur" - -#: src/cthulhu/messages.py:566 -#, fuzzy -msgid "document unselected to cursor position" -msgstr "zgjedhur" - -#: src/cthulhu/messages.py:571 -#, fuzzy, python-format -msgid "Dynamic column header set for row %d" -msgstr "kreu për " - -#: src/cthulhu/messages.py:577 -#, fuzzy -msgid "Dynamic column header cleared." -msgstr "kreu." - -#: src/cthulhu/messages.py:583 -#, fuzzy, python-format -msgid "Dynamic row header set for column %s" -msgstr "kreu për" - -#: src/cthulhu/messages.py:589 -#, fuzzy -msgid "Dynamic row header cleared." -msgstr "kreu." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "" - -#: src/cthulhu/messages.py:596 -#, fuzzy, python-format -msgid "%.2f kilobytes" -msgstr "kilobytes" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "" - -#: src/cthulhu/messages.py:603 -#, fuzzy -msgid "No files found." -msgstr "Jo." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "dhe modaliteti." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "dritare dialogu" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "menu e shpalosëshme" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, fuzzy, python-format -msgid "The key entered is already bound to %s" -msgstr "është Asgjë." - -#: src/cthulhu/messages.py:701 -#, fuzzy, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Kyçi Shtypi shkruaj." - -#: src/cthulhu/messages.py:706 -#, fuzzy, python-format -msgid "The new key is: %s" -msgstr "i ri është" - -#: src/cthulhu/messages.py:711 -#, fuzzy -msgid "Key binding deleted. Press enter to confirm." -msgstr "Kyçi Shtypi shkruaj." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -#, fuzzy -msgid "enter new key" -msgstr "shkruaj i ri" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "Asnjë" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "Linja" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "Fjalëkalimi" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "rreth i zi" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "horizontalisht" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "shtyllë vertikale" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "poshtë." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "dhe" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "rrënjë katrore" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "rrënjë kubike" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "panel bazë" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "panel bazë" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "panel bazë" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "tabelë" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "tabelë e degëzuar" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Tabela" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "Fl_it dhe" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Tabela" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "Fl_it dhe" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Modaliteti mësues. Shtyp escape për të dalë." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "animacion" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Faqja Lundrimi" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1292 -#, fuzzy -msgid "leaving table." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Tabela Lundrimi" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "tabelë." - -#: src/cthulhu/messages.py:1471 -#, fuzzy -msgid "line selected down from cursor position" -msgstr "zgjedhur poshtë" - -#: src/cthulhu/messages.py:1477 -#, fuzzy -msgid "line selected up from cursor position" -msgstr "zgjedhur sipër" - -#: src/cthulhu/messages.py:1484 -#, fuzzy -msgid "line unselected down from cursor position" -msgstr "zgjedhur poshtë" - -#: src/cthulhu/messages.py:1491 -#, fuzzy -msgid "line unselected up from cursor position" -msgstr "zgjedhur sipër" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Duke dalë nga modaliteti mësim." - -#: src/cthulhu/messages.py:1505 -#, fuzzy -msgid "line selected from start to previous cursor position" -msgstr "zgjedhur sipër" - -#: src/cthulhu/messages.py:1511 -#, fuzzy -msgid "line selected to end from previous cursor position" -msgstr "zgjedhur poshtë" - -#: src/cthulhu/messages.py:1514 -#, fuzzy -msgid "link" -msgstr "lidhje" - -#: src/cthulhu/messages.py:1518 -#, fuzzy -msgid "same page" -msgstr "faqe" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "" - -#: src/cthulhu/messages.py:1531 -#, fuzzy, python-format -msgid "%(uri)s link to %(file)s" -msgstr "lidhje" - -#: src/cthulhu/messages.py:1534 -#, fuzzy, python-format -msgid "%s link" -msgstr "lidhje" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "lidhje" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, fuzzy, python-format -msgid "politeness level %s" -msgstr "niveli %d i degëzimit" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "Jo." - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "Akt_ual pozicioni" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "në" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "Fjala e gabuar:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Fjala e shqiptuar keq: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Konteksti është %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Jo." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Speech." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Speech." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d përqind." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "listë." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, fuzzy, python-format -msgid "Nesting level %d" -msgstr "etiketa" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Asnjë aplikativ ka fokus." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Asnjë fokusim" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Asnjë aplikativ ka fokus." - -#: src/cthulhu/messages.py:1872 -#, fuzzy -msgid "No more blockquotes." -msgstr "Jo." - -#: src/cthulhu/messages.py:1877 -#, fuzzy -msgid "No more buttons." -msgstr "Jo." - -#: src/cthulhu/messages.py:1882 -#, fuzzy -msgid "No more check boxes." -msgstr "Jo." - -#: src/cthulhu/messages.py:1888 -#, fuzzy -msgid "No more large objects." -msgstr "Jo." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Jo." - -#: src/cthulhu/messages.py:1898 -#, fuzzy -msgid "No more combo boxes." -msgstr "Jo." - -#: src/cthulhu/messages.py:1903 -#, fuzzy -msgid "No more entries." -msgstr "Jo." - -#: src/cthulhu/messages.py:1908 -#, fuzzy -msgid "No more form fields." -msgstr "Jo formular." - -#: src/cthulhu/messages.py:1913 -#, fuzzy -msgid "No more headings." -msgstr "Jo." - -#: src/cthulhu/messages.py:1919 -#, fuzzy, python-format -msgid "No more headings at level %d." -msgstr "Jo etiketa." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "kornizë e brendshme" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "Jo." - -#: src/cthulhu/messages.py:1935 -#, fuzzy -msgid "No landmark found." -msgstr "Jo." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "Jo." - -#: src/cthulhu/messages.py:1945 -#, fuzzy -msgid "No more lists." -msgstr "Jo." - -#: src/cthulhu/messages.py:1950 -#, fuzzy -msgid "No more list items." -msgstr "Jo listë elementët." - -#: src/cthulhu/messages.py:1957 -#, fuzzy -msgid "No more live regions." -msgstr "Jo listë elementët." - -#: src/cthulhu/messages.py:1962 -#, fuzzy -msgid "No more paragraphs." -msgstr "Jo." - -#: src/cthulhu/messages.py:1967 -#, fuzzy -msgid "No more radio buttons." -msgstr "Jo." - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "Jo." - -#: src/cthulhu/messages.py:1977 -#, fuzzy -msgid "No more tables." -msgstr "Jo." - -#: src/cthulhu/messages.py:1982 -#, fuzzy -msgid "No more unvisited links." -msgstr "Jo." - -#: src/cthulhu/messages.py:1987 -#, fuzzy -msgid "No more visited links." -msgstr "Jo." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "nuk zgjedhur" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "Not në a tabelë." - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "titull" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "_Poshtë:" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "_Sipër:" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "Fjalëkalimi" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "" - -#: src/cthulhu/messages.py:2051 -#, fuzzy -msgid "on" -msgstr "në" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "" - -#: src/cthulhu/messages.py:2059 -#, fuzzy -msgid "Finished loading." -msgstr "Përfundoi." - -#: src/cthulhu/messages.py:2064 -#, fuzzy, python-format -msgid "Finished loading %s." -msgstr "Përfundoi." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "zgjedhur në faqe nga pozicioni i kursorit" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "zgjedhur në faqe deri tek pozicioni i kursorit" - -#: src/cthulhu/messages.py:2089 -#, fuzzy -msgid "page unselected from cursor position" -msgstr "zgjedhur në faqe nga pozicioni i kursorit" - -#: src/cthulhu/messages.py:2095 -#, fuzzy -msgid "page unselected to cursor position" -msgstr "zgjedhur në faqe deri tek pozicioni i kursorit" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "zgjedhur në faqe nga pozicioni i kursorit" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "zgjedhur në faqe nga pozicioni i kursorit" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "zgjedhur në faqe nga pozicioni i kursorit" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "zgjedhur në faqe nga pozicioni i kursorit" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "Jo." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Shtylla e progresit të %d." - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "Të gjith_a" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "Asnjë" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -#, fuzzy -msgid "Searching." -msgstr "Duke kërkuar." - -#: src/cthulhu/messages.py:2207 -#, fuzzy -msgid "Search complete." -msgstr "Kërko." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "është." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "Konteksti është %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Zgjidh:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "i pa zgjedhur" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -#, fuzzy -msgid "Speech disabled." -msgstr "Speech." - -#: src/cthulhu/messages.py:2258 -#, fuzzy -msgid "Speech enabled." -msgstr "Speech." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Shpejtësia:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Vo_lumi:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Jo në dispozicion j" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Jo në dispozicion j" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Speech." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "Speech nuk j" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr "" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "Preferimet" - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "është." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -#, fuzzy -msgid "Speech is unavailable." -msgstr "Speech është jo në dispozicion." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Jo." - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "teksti nuk u gjet" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "teksti nuk u gjet" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -#, fuzzy -msgid "Structural navigation keys on." -msgstr "në." - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "Jo." - -#: src/cthulhu/messages.py:2380 -#, fuzzy, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Rresht." - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "tabelë" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Shqipto qelinë" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Shqipto rreshtin" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -#, fuzzy -msgid "Not in a table." -msgstr "Not në a tabelë." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "kreu i kollonës" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -#, fuzzy -msgid "Bottom of column." -msgstr "Poshtë nga." - -#: src/cthulhu/messages.py:2430 -#, fuzzy -msgid "Top of column." -msgstr "Sipër nga." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "i pa zgjedhur" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "i pa zgjedhur" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "" - -#: src/cthulhu/messages.py:2462 -#, fuzzy, python-format -msgid "row %(index)d of %(total)d" -msgstr "nga" - -#: src/cthulhu/messages.py:2467 -#, fuzzy -msgid "Beginning of row." -msgstr "nga." - -#: src/cthulhu/messages.py:2472 -#, fuzzy -msgid "End of row." -msgstr "Mbarimi nga." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "fund nga." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "nuk zgjedhur" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "i pa zgjedhur" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "i zgjedhur" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "i pa zgjedhur" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "Preferimet Cthulhu për %s" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "hapësirë bosh" - -#: src/cthulhu/messages.py:2562 -#, fuzzy -msgid "Wrapping to bottom." -msgstr "poshtë." - -#: src/cthulhu/messages.py:2568 -#, fuzzy -msgid "Wrapping to top." -msgstr "sipër." - -#: src/cthulhu/messages.py:2573 -#, fuzzy -msgid "0 items" -msgstr "elementët" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, fuzzy, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Qeli rreshta" -msgstr[1] "Qeli rreshta" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "Rresht." -msgstr[1] "Rresht." - -#: src/cthulhu/messages.py:2593 -#, fuzzy, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Qeli kollona" -msgstr[1] "Qeli kollona" - -#: src/cthulhu/messages.py:2610 -#, fuzzy, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d %s simbol" -msgstr[1] "%d %s simbole" - -#: src/cthulhu/messages.py:2618 -#, fuzzy, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "dritare dialogu" -msgstr[1] "dritare dialogu" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, fuzzy, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, fuzzy, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "U gjet %d file" -msgstr[1] "U gjet %d file" - -#: src/cthulhu/messages.py:2640 -#, fuzzy, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "formular" -msgstr[1] "formular" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d titull" -msgstr[1] "%d tituj" - -#: src/cthulhu/messages.py:2652 -#, fuzzy, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "element" -msgstr[1] "element" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "trademark" -msgstr[1] "trademark" - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "U gjet %d file" -msgstr[1] "U gjet %d file" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Jo." -msgstr[1] "Jo." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "tabelë." -msgstr[1] "tabelë." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, fuzzy, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista me element" -msgstr[1] "Lista me element" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Lista me element" -msgstr[1] "Lista me element" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "Tabela me" -msgstr[1] "Tabela me" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "Tabela me" -msgstr[1] "Tabela me" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d përqind." -msgstr[1] "%d përqind." - -#: src/cthulhu/messages.py:2764 -#, fuzzy, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "nga" -msgstr[1] "nga" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "pixels" -msgstr[1] "pixels" - -#: src/cthulhu/messages.py:2777 -#, fuzzy, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%d %s simbol" -msgstr[1] "%d %s simbole" - -#: src/cthulhu/messages.py:2784 -#, fuzzy, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "nga element zgjedhur" -msgstr[1] "nga element zgjedhur" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d hapësirë" -msgstr[1] "%d hapësira" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d skedë" -msgstr[1] "%d skeda" - -#: src/cthulhu/messages.py:2820 -#, fuzzy, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "tabelë" -msgstr[1] "tabelë" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabelë me rreshta dhe kollona." -msgstr[1] "tabelë me rreshta dhe kollona." - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabelë me rreshta dhe kollona." -msgstr[1] "tabelë me rreshta dhe kollona." - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "Tabela me" -msgstr[1] "Tabela me" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "sekonda" -msgstr[1] "sekonda" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, fuzzy, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "lidhje" -msgstr[1] "lidhje" - -#: src/cthulhu/messages.py:2892 -#, fuzzy, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "lidhje" -msgstr[1] "lidhje" - -#: src/cthulhu/object_properties.py:41 -#, fuzzy -msgid "toggle" -msgstr "pulsant shkëmbimi" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVELI %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "niveli %d i degëzimit" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVELI %d i PEMËS" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "pikëpyetje" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "kuti e kombinuar" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "dy pika" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "seksion" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "paragraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "Funksioni" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "tab listë" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "citim" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "horizontalisht" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "shtyllë vertikale" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "horizontalisht" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "shtyllë vertikale" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "horizontalisht" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "shtyllë vertikale" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -#, fuzzy -msgid "Icon panel" -msgstr "Ikona panel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Animacioni" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Animacioni" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "Duke kërkuar." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "lidhje" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "kontrollues zgjedhjës" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "e palosur" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "e shpalosur" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horizontalisht" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikalisht" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "zgjedhur" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "jo i zgjedhur" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "në" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "jo i zgjedhur" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "i shtypur" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "jo i shtypur" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "nuk zgjedhur" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "zgjedhur" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "jo i zgjedhur" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "nuk zgjedhur" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "lidhje" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "lidhje" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -#, fuzzy -msgid "grayed" -msgstr "jeshile" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "zgjedhje e shumëfishtë" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "I pavlefshëm" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "I pavlefshëm" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "I pavlefshëm" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "Kontrolli i drejtshkrimit" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "I pavlefshëm" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -#, fuzzy -msgid "Find" -msgstr "Gjej" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "Cthulhu, lexues dhe zmadhues ekrani" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "Mbyll" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "Gjej" - -#: src/cthulhu/cthulhu-find.ui:85 -#, fuzzy -msgid "_Search for:" -msgstr "Kërko për:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -#, fuzzy -msgid "Search for:" -msgstr "Kërko për:" - -#: src/cthulhu/cthulhu-find.ui:166 -#, fuzzy -msgid "_Top of window" -msgstr "Sipër nga dri_tare" - -#: src/cthulhu/cthulhu-find.ui:175 -#, fuzzy -msgid "Top of window" -msgstr "Sipër nga dritare" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -#, fuzzy -msgid "Start from:" -msgstr "Fillimi:" - -#: src/cthulhu/cthulhu-find.ui:226 -#, fuzzy -msgid "_Wrap around" -msgstr "_Rifillo nga fillimi" - -#: src/cthulhu/cthulhu-find.ui:242 -#, fuzzy -msgid "Search _backwards" -msgstr "Kërko m_brapsht" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "Kërko për:" - -#: src/cthulhu/cthulhu-find.ui:291 -#, fuzzy -msgid "_Match case" -msgstr "Respekto _Gërma të mëdha/vogla" - -#: src/cthulhu/cthulhu-find.ui:306 -#, fuzzy -msgid "Match _entire word only" -msgstr "V_etëm fjalën e plotë" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Gjej Mundësitë" - -#: src/cthulhu/cthulhu-setup.ui:43 -#, fuzzy -msgid "Default" -msgstr "E prezgjedhur" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -#, fuzzy -msgid "Application" -msgstr "Aplikativi" - -#: src/cthulhu/cthulhu-setup.ui:83 -#, fuzzy -msgid "Window" -msgstr "Dritarja" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "Preferimet" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -#, fuzzy -msgid "_Laptop" -msgstr "_Laptop" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr " Tastiera Planimetria" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "Fillimi:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "Flit gjithçka" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Aplikativi" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "Flit" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "në." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -#, fuzzy -msgid "Say All B_y:" -msgstr "Gjithçka:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "Gjithçka:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -#, fuzzy -msgid "General" -msgstr "Të përgjithshme" - -#: src/cthulhu/cthulhu-setup.ui:1188 -#, fuzzy -msgid "Vo_lume:" -msgstr "Vo_lumi:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -#, fuzzy -msgid "Pi_tch:" -msgstr "_Toni:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -#, fuzzy -msgid "_Rate:" -msgstr "_Shpejtësia:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1345 -#, fuzzy -msgid "Speech synthesi_zer:" -msgstr "Speech:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -#, fuzzy -msgid "Speech _system:" -msgstr "_Speech:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "Zë:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "Zë:" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -#, fuzzy -msgid "Speak multicase strings as wor_ds" -msgstr "_Flit gjej" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "Zë:" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -#, fuzzy -msgid "_Enable speech" -msgstr "Aktivo shqiptimi" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -#, fuzzy -msgid "Ver_bose" -msgstr "Ver_bose" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -#, fuzzy -msgid "_All" -msgstr "Të gjith_a" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -#, fuzzy -msgid "Speak blank lines" -msgstr "Flit në të bardhë rreshta" - -#: src/cthulhu/cthulhu-setup.ui:1835 -#, fuzzy -msgid "Speak _indentation and justification" -msgstr "Fl_it dhe" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -#, fuzzy -msgid "Speak tutorial messages" -msgstr "Flit shu_mëfish" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "Flit" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "Flit" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "Flit as_një" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -#, fuzzy -msgid "Speech" -msgstr "Speech" - -#: src/cthulhu/cthulhu-setup.ui:2187 -#, fuzzy -msgid "Enable Braille _support" -msgstr "Aktivo Braille" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Aktivo nga" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "Shfaq" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "_Asnjë" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr " Zgjedhja" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr " Zgjedhja" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "Aktivo z_madhuesi" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -#, fuzzy -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -#, fuzzy -msgid "Enable _key echo" -msgstr "A_ktivo" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Ak_tivo" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "Aktivo" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Aktivo" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "Aktivo shqiptimi" - -#: src/cthulhu/cthulhu-setup.ui:2864 -#, fuzzy -msgid "Enable _modifier keys" -msgstr "Aktivo" - -#: src/cthulhu/cthulhu-setup.ui:2879 -#, fuzzy -msgid "Enable _function keys" -msgstr "Aktivo" - -#: src/cthulhu/cthulhu-setup.ui:2894 -#, fuzzy -msgid "Enable ac_tion keys" -msgstr "Ak_tivo" - -#: src/cthulhu/cthulhu-setup.ui:2909 -#, fuzzy -msgid "Enable _navigation keys" -msgstr "Aktivo" - -#: src/cthulhu/cthulhu-setup.ui:2965 -#, fuzzy -msgid "Enable echo by _word" -msgstr "Aktivo nga" - -#: src/cthulhu/cthulhu-setup.ui:2980 -#, fuzzy -msgid "Enable echo by _sentence" -msgstr "Aktivo nga" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Kyçi" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Kyçi:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -#, fuzzy -msgid "Key Bindings" -msgstr "Kyçi" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr " Fjalori" - -#: src/cthulhu/cthulhu-setup.ui:3161 -#, fuzzy -msgid "_New entry" -msgstr "E re fushë shtimi" - -#: src/cthulhu/cthulhu-setup.ui:3176 -#, fuzzy -msgid "_Delete" -msgstr "_Elemino" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3243 -#, fuzzy -msgid "_Speak all" -msgstr "Flit gjithçka" - -#: src/cthulhu/cthulhu-setup.ui:3257 -#, fuzzy -msgid "Speak _none" -msgstr "Flit as_një" - -#: src/cthulhu/cthulhu-setup.ui:3271 -#, fuzzy -msgid "_Reset" -msgstr "_Nga fillimi" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "Teksti Veçoritë" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -#, fuzzy -msgid "Move to _bottom" -msgstr "Lëvize poshtë" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -#, fuzzy -msgid "Move _down one" -msgstr "Lëvize poshtë" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -#, fuzzy -msgid "Move _up one" -msgstr "Lëvize sipër" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -#, fuzzy -msgid "Move to _top" -msgstr "Lëvize sipër" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr " Përshtat zgjedhur" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr " Braille" - -#: src/cthulhu/cthulhu-setup.ui:3549 -#, fuzzy -msgid "Text Attributes" -msgstr "Teksti Veçoritë" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "Asistenti" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "Asistenti" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "yen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "Shkalla:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -#, fuzzy -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "a e m j x p" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -#, fuzzy -msgctxt "textattr" -msgid "direction" -msgstr "seksion" - -#: src/cthulhu/text_attribute_names.py:97 -#, fuzzy -msgctxt "textattr" -msgid "editable" -msgstr "tabelë" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:156 -#, fuzzy -msgctxt "textattr" -msgid "justification" -msgstr "seksion" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:169 -#, fuzzy -msgctxt "textattr" -msgid "left margin" -msgstr "kllapë e majtë" - -#: src/cthulhu/text_attribute_names.py:176 -#, fuzzy -msgctxt "textattr" -msgid "line height" -msgstr "Linja djathtas" - -#: src/cthulhu/text_attribute_names.py:186 -#, fuzzy -msgctxt "textattr" -msgid "paragraph style" -msgstr "paragraf" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -#, fuzzy -msgctxt "textattr" -msgid "pixels below lines" -msgstr "Flit në të bardhë rreshta" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -#, fuzzy -msgctxt "textattr" -msgid "right margin" -msgstr "kllapë e djathtë" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:228 -#, fuzzy -msgctxt "textattr" -msgid "scale" -msgstr "kalendar" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -#, fuzzy -msgctxt "textattr" -msgid "text rotation" -msgstr "Akt_ual pozicioni" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -#, fuzzy -msgctxt "textattr" -msgid "underline" -msgstr "nënvijë" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:302 -#, fuzzy -msgctxt "textattr" -msgid "vertical align" -msgstr "shtyllë vertikale" - -#: src/cthulhu/text_attribute_names.py:309 -#, fuzzy -msgctxt "textattr" -msgid "weight" -msgstr "Linja djathtas" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -#, fuzzy -msgctxt "textattr" -msgid "writing mode" -msgstr "Duke dalë nga modaliteti mësim." - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:365 -#, fuzzy -msgctxt "textattr" -msgid "engrave" -msgstr "e me theks" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -#, fuzzy -msgctxt "textattr" -msgid "outline" -msgstr "nënvijë" - -#: src/cthulhu/text_attribute_names.py:386 -#, fuzzy -msgctxt "textattr" -msgid "overline" -msgstr "nënvijë" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -#, fuzzy -msgctxt "textattr" -msgid "blink" -msgstr "lidhje" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:421 -#, fuzzy -msgctxt "textattr" -msgid "double" -msgstr "double prime" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:442 -#, fuzzy -msgctxt "textattr" -msgid "word" -msgstr "Fjalëkalimi" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:473 -#, fuzzy -msgctxt "textattr" -msgid "left" -msgstr "majtas alt" - -#: src/cthulhu/text_attribute_names.py:480 -#, fuzzy -msgctxt "textattr" -msgid "right" -msgstr "copyright" - -#: src/cthulhu/text_attribute_names.py:487 -#, fuzzy -msgctxt "textattr" -msgid "center" -msgstr "cents" - -#: src/cthulhu/text_attribute_names.py:493 -#, fuzzy -msgctxt "textattr" -msgid "no justification" -msgstr "Fl_it dhe" - -#: src/cthulhu/text_attribute_names.py:500 -#, fuzzy -msgctxt "textattr" -msgid "fill" -msgstr "mbushës" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:521 -#, fuzzy -msgctxt "textattr" -msgid "condensed" -msgstr "sekonda" - -#: src/cthulhu/text_attribute_names.py:528 -#, fuzzy -msgctxt "textattr" -msgid "semi condensed" -msgstr "sekonda" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:542 -#, fuzzy -msgctxt "textattr" -msgid "semi expanded" -msgstr "e shpalosur" - -#: src/cthulhu/text_attribute_names.py:549 -#, fuzzy -msgctxt "textattr" -msgid "expanded" -msgstr "e shpalosur" - -#: src/cthulhu/text_attribute_names.py:556 -#, fuzzy -msgctxt "textattr" -msgid "extra expanded" -msgstr "e shpalosur" - -#: src/cthulhu/text_attribute_names.py:563 -#, fuzzy -msgctxt "textattr" -msgid "ultra expanded" -msgstr "e shpalosur" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:591 -#, fuzzy -msgctxt "textattr" -msgid "Default" -msgstr "E prezgjedhur" - -#: src/cthulhu/text_attribute_names.py:598 -#, fuzzy -msgctxt "textattr" -msgid "Text body" -msgstr "Teksti" - -#: src/cthulhu/text_attribute_names.py:605 -#, fuzzy -msgctxt "textattr" -msgid "Heading" -msgstr "Titulli" - -#: src/cthulhu/text_attribute_names.py:613 -#, fuzzy -msgctxt "textattr" -msgid "baseline" -msgstr "rresht i ri" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:627 -#, fuzzy -msgctxt "textattr" -msgid "super" -msgstr "Super" - -#: src/cthulhu/text_attribute_names.py:634 -#, fuzzy -msgctxt "textattr" -msgid "top" -msgstr "Ndal" - -#: src/cthulhu/text_attribute_names.py:641 -#, fuzzy -msgctxt "textattr" -msgid "text-top" -msgstr "tekst" - -#: src/cthulhu/text_attribute_names.py:648 -#, fuzzy -msgctxt "textattr" -msgid "middle" -msgstr "pikë e mesme" - -#: src/cthulhu/text_attribute_names.py:655 -#, fuzzy -msgctxt "textattr" -msgid "bottom" -msgstr "_Poshtë:" - -#: src/cthulhu/text_attribute_names.py:662 -#, fuzzy -msgctxt "textattr" -msgid "text-bottom" -msgstr "Lëvize poshtë" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:726 -#, fuzzy -msgctxt "textattr" -msgid "rl" -msgstr "Ctrl" - -#: src/cthulhu/text_attribute_names.py:733 -#, fuzzy -msgctxt "textattr" -msgid "tb" -msgstr "skedë" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -#, fuzzy -msgctxt "textattr" -msgid "spelling" -msgstr "Kontrolli i drejtshkrimit" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" diff --git a/po/sr.po b/po/sr.po deleted file mode 100644 index 99a5f51..0000000 --- a/po/sr.po +++ /dev/null @@ -1,9312 +0,0 @@ -# Serbian translation of cthulhu -# Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2021. -# This file is distributed under the same license as the cthulhu package. -# Данило Шеган -# Мирослав Николић , 2012—2021. -# Марко М. Костић , 2020. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2022-08-09 10:28+0200\n" -"Last-Translator: Марко М. Костић \n" -"Language-Team: српски \n" -"Language: sr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " -"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Project-Style: gnome\n" -"X-Generator: Poedit 3.1.1\n" - -msgid "Cthulhu Screen Reader" -msgstr "Читач екрана Орка" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "читач екрана;говор;брајева азбука;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "упзр" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "аним" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "срл" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "кал" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "плт" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "нтпс" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "пзш" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "бирбје" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "зглкол" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "пзи" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "дат" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "икн" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "окв" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "пзв" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "прз" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "дип" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "хтмл" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "црт" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "бирдт" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "ппу" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "слб" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "форм" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "стп" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "зглв" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "слк" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "унок" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "нтп" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "нслгпвш" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "вза" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "спс" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "ствспс" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "изб" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "линизб" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "ствизб" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "повопц" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "стр" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "спсјз" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "пнл" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "лзк" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "искизб" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "лннап" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "дгм" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "радио" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "стврдизб" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "крнпв" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "зглрд" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "лнпм" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "пвпм" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "одељ" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "раздвјч" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "клизач" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "пврздв" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "вртт" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "линстњ" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "тбл" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "пољ" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "одствизб" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "терм" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "ткст" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "прбцвч" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "лнал" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "свт" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "стб" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "тблст" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "нпз" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "пглд" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "прз" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "згл" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "пдн" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "псус" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "прг" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "самд" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "лнурђ" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "угњ" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Чешки, 1. степен" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Шпански, 1. степен" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Канадски француски, 2. степен" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Француски француски, 2. степен" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Летонски, 1. степен" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Холандски, 1. степен" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Норвешки, 0. степен" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Норвешки, 1. степен" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Норвешки, 2. степен" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Норвешки, 3. степен" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Пољски, 1. степен" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Португалски, 1. степен" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Шведски, 1. степен" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Арапски, 1. степен" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Велшки, 1. степен" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Велшки, 2. степен" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Немачки, 0. степен" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Немачки, 1. степен" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Немачки, 2. степен" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Британски енглески, 2. степен" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Британски енглески, 1. степен" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Амерички енглески, 1. степен" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Амерички енглески, 2. степен" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Канадски француски, 1. степен" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Француски француски, 1. степен" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Грчки, 1. степен" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Индијски, 1. степен" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Мађарски рачунар са 8 тачкица" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Мађарски, 1. степен" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Мађарски, 2. степен" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Италијански, 1. степен" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Белгијски, 1. степен" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "размак" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "нови ред" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "таб" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "узвичник" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "наводник" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "број" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "долар" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "проценат" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "и" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "апостроф" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "лева мала заграда" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "десна мала заграда" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "звездица" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "плус" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "запета" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "црта" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "тачка" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "коса црта" - -# bug: colon? -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "две тачке" - -# bug: colon? -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "тачка-зарез" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "мање" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "једнако" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "веће" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "упитник" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "лудо а" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "лева угласта" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "контра коса црта" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "десна угласта" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "капица" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "подвлака" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "краткоузлазни" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "лева витичаста" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "усправна црта" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "десна витичаста" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "тилда" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "без размака" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "обрнути знак узвика" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "центи" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "фунте" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "знак валуте" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "јен" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "прекинута усправна црта" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "одељак" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "дијарезис" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "ауторска права" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "изложилац а" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "лева двострука оштра заграда" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "логично не" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "краткосилазни нагласак" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "заштитни знак" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "макрон" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "степени" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "плус-минус" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "изложилац 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "изложилац 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "дугоузлазно" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "ми" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "обележивач пасуса" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "средња тачка" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "седиља" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "изложилац 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "редни број" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "десна двострука оштра заграда" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "једна четвртина" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "половина" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "три четвртине" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "обрнути знак питања" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "мало дугоузлазно а" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "ВЕЛИКО КРАТКОУЗЛАЗНО А" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "ВЕЛИКО ДУГОУЗЛАЗНО А" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "ВЕЛИКО ДУГОСИЛАЗНО А" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "ВЕЛИКО А СА ТИЛДОМ" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "ВЕЛИКО А СА ДВЕ ТАЧКЕ" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "ВЕЛИКО А СА КРУЖИЋЕМ" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "ВЕЛИКО АЕ" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "ВЕЛИКО Ц СА СЕДИЉОМ" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "ВЕЛИКО КРАТКОУЗЛАЗНО Е" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "ВЕЛИКО ДУГОУЗЛАЗНО Е" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "ВЕЛИКО ДУГОСИЛАЗНО Е" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "ВЕЛИКО Е СА ДВЕ ТАЧКЕ" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "ВЕЛИКО КРАТКОУЗЛАЗНО И" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "ВЕЛИКО ДУГОУЗЛАЗНО И" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "ВЕЛИКО ДУГОСИЛАЗНО И" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "ВЕЛИКО И СА ДВЕ ТАЧКЕ" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ВЕЛИКО Ђ ЛАТИНИЦОМ" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "ВЕЛИКО Н СА ТИЛДОМ" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "ВЕЛИКО КРАТКОУЗЛАЗНО О" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "ВЕЛИКО ДУГОУЗЛАЗНО О" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "ВЕЛИКО ДУГОСИЛАЗНО О" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "ВЕЛИКО О СА ТИЛДОМ" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "ВЕЛИКО О СА ДВЕ ТАЧКЕ" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "пута" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "ПРЕЦРТАНО ВЕЛИКО О" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "ВЕЛИКО КРАТКОУЗЛАЗНО У" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "ВЕЛИКО ДУГОУЗЛАЗНО У" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "ВЕЛИКО ДУГОСИЛАЗНО У" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "ВЕЛИКО У СА ДВЕ ТАЧКЕ" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "ВЕЛИКО ДУГОУЗЛАЗНО ИПСИЛОН" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "ТОРН" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "немачко мало дупло с" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "мало краткоузлазно а" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "мало дугосилазно а" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "мало а са тилдом" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "мало а са две тачке" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "мало а са кружићем" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "мало ае" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "мало ц са седиљом" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "мало краткоузлазно е" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "мало дугоузлазно е" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "мало дугосилазно е" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "мало е са две тачке" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "мало краткоузлазно и" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "мало дугоузлазно и" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "мало дугосилазно и" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "мало и са две тачке" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "мало ђ латиницом" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "мало н са тилдом" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "мало краткоузлазно о" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "мало дугоузлазно о" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "мало дугосилазно о" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "мало о са тилдом" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "мало о са две тачке" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "подељено" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "мало прецртано о" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "мало торн" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "мало дугоузлазно у" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "мало краткоузлазно у" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "мало дугосилазно у" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "мало у са две тачке" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "мало дугоузлазно ипсилон" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "мало ипсилон са две тачке" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "ВЕЛИКО ИПСИЛОН СА ДВЕ ТАЧКЕ" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "мало флорин" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "средња црта" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "леви самостални наводник" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "десни самостални наводник" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "самостални доњи наводник" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "леви двоструки наводник" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "десни двоструки наводник" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "двоструки доњи наводник" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "дагер" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "дупли дагер" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "метак" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "троугаони метак" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "промил" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "примус" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "секундум" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "троструки" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "метак цртица" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "евро" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "заштитни знак" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "знак штиклирања" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "подебљани знак штиклирања" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "икс метак" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "изложилац 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "изложилац 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "изложилац 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "изложилац 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "изложилац 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "изложилац 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "изложилац 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "изложилац плус" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "изложилац минус" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "изложилац једнакости" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "изложилац леве заграде" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "изложилац десне заграде" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "изложилац ен" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "индекс 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "индекс 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "индекс 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "индекс 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "индекс 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "индекс 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "индекс 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "индекс 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "индекс 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "индекс 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "индекс плус" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "индекс минус" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "индекс једнакости" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "индекс леве заграде" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "индекс десне заграде" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "црни квадратић" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "црни ромб" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "заменско слово објекта" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Постави показивач на текућу ставку" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Обави леви клик на тренутну ставку равног прегледа" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Обави десни клик на тренутну ставку равног прегледа" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Изговори читав документ" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Изговори читав прозор користећи раван преглед" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Обавља основну где сам ја операција" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Обавља детаљну где сам ја операција" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Изговори текући одабир" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Изговори појединости везе" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Представи подразумевано дугме" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Изговори траку стања" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Изговори траку наслова" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Отвори прозорче за претрагу" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Иде на следећи списак" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Тражи следеће појављивање ниске" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Тражи претходно појављивање ниске" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Улази и излази из режима равног прегледа" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Премести раван преглед на крајњи положај" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Премести раван преглед на почетни положај" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Премести раван преглед на крајњи положај" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Премести раван преглед на почетак претходне линије" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Изговори текућу линију равног прегледа" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Сричи текућу линију равног прегледа" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Фонетски изговори текућу линију равног прегледа" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Премести раван преглед на почетак наредне линије" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Премешта раван преглед на претходну ставку или реч" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Изговара ставку или реч текућег равног прегледа" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Сриче ставку или реч текућег равног прегледа" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Фонетски изговара ставку или реч текућег равног прегледа" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Премешта раван преглед на следећу ставку или реч" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Премешта раван преглед на реч изнад тренутне речи" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Сриче текући објекат равног прегледа" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Премешта раван преглед на реч испод тренутне речи" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Премешта раван преглед на претходни знак" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Изговара текући знак равног прегледа" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Фонетски изговара текући знак равног прегледа" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Изговара уникодну вредност текућег знака равног прегледа" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Премешта раван преглед на следећи знак" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Премешта раван преглед на крај линије" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Премешта раван преглед на дно лево" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Умножава садржај под равним прегледом у оставу" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Прикачиње садржај под равним прегледом у оставу" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Премести раван преглед на крајњи положај" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Врши пребацивање у зависности од тога да ли треба да чита само текућу ћелију " -"табеле или цео ред" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Чита атрибуте повезане са тренутним знаком текста" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Проширује Брајев екран на лево" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Проширује Брајев екран на десно" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Враћа се на објекат са фокусом тастатуре" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Укључује и искључује скупљено Брајево писмо" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Обрађује тастер рутине курсора" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Означава почетак избора текста" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Означава крај избора текста" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Уноси режим учења. Притисните „Напусти“ да изађете из режима учења" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Смањује проток изговора" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Повећава проток изговора" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Смањује врхунац изговора" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Повећава врхунац изговора" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Повећава јачину тона изговора" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Смањује јачину тона изговора" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Тражи претходно појављивање ниске" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Одаберите жељени сервер говора." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Смањује проток изговора" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Повећава проток изговора" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Подешавања врсте гласа" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Укључује ућуткивања изговора" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Подешава ниво причљивости изговора" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Окида стање режима распоређивања" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Затвара читача екрана" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Приказује прозорче подешавања поставки" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Приказује прозорче подешавања поставки програма" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Укључује изговор увлачења и поравнања" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Мења стил изговореног броја" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Пребацује на следећи изговор нивоа интерпункције" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Пребацује на следећи ниво одјека тастера" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Пребацује на следећи профил подешавања" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Пребацује на следећи изглед великих слова" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Пребацује на следећи ниво одјека тастера" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Пребацује на ниво исправљања грешака за време покретања" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Обележава где сам поштујући текући положај" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Иде на претходно место обележивача" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Иде на обележивач" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Иде на следеће место обележивача" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Додаје обележивач" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Чува обележиваче" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Укључује режим прегледа мишем" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Представља текуће време" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Представља текући датум" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Представи величину и положај тренутног објекта" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Прослеђује следећу наредбу текућем програму" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Изговара Брајевим писмом претходну поруку причаонице" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" -"Врши пребацивање у зависности од тога да ли најављујемо када наши другари " -"пишу" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Врши пребацивање у зависности да ли смо обезбедили историјате посебне поруке " -"причаонице" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Врши пребацивање зависно од тога да ли смо за префикс поруке причаонице " -"поставили назив причаонице" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Поравнај лево" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Поравнај десно" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Поравнај горе" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Поравнај доле" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Замрзни" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Горе лево" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Доле лево" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Положај курсора" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Шест тачака" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Рутине курсора" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Почетак одсецања" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Ред одсецања" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Приказује последњу поруку обавештења" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Прикажи списак порука обавештења" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Приказује претходну поруку обавештења" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Приказује последњу поруку обавештења" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Иде на следећи знак" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Иде на претходни знак" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Иде на следећу реч" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Иде на претходну реч" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Иде на следећи ред" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Иде на претходни ред" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Иде на врх датотеке" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Иде на дно датотеке" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Иде на почетак реда" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Иде на крај реда" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Прелази на следећи објекат" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Прелази на претходни објекат" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Доводи до тога да текуће прозорче за избор бива раширено" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Пребацује кретање показивача између изворног и читачем екрана" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Напредујте у подешавањима љубазности живе области" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Подесите основни ниво љубазности живе области на искљулчено" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Преглед најаве живе области" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Надгледа живе области" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Приближава и удаљује први план са текућег положаја миша" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Поставите ред који ће бити коришћен као динамичко заглавље колоне" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Чисти динамичка заглавља колоне" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Поставите колону која ће бити коришћена као динамичко заглавље реда" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Чисти динамичка заглавља реда" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Представља садржај линије уноса" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Пребацује тастере структурне навигације" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Иде на претходни блок цитата" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Иде на следећи блок цитата" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Приказује списак блокова цитата" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Иде на претходно дугме" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Иде на следеће дугме" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Приказује списак дугмади" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Иде на претходно поље за потврду" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Иде на следеће поље за потврду" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Приказује списак поља за потврду" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Иде на претходни објекат на који се може кликнути" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Иде на следећи објекат на који се може клинути" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Приказује списак са објектима на које се може кликнути" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Иде на претходно прозорче за избор" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Иде на следеће прозорче за избор" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Иде на почетак контејнера" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Иде на крај контејнера" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Приказује списак прозорчића за избор" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Иде на претходни унос" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Иде на следећи унос" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Приказује списак уноса" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Иде на претходно поље формулара" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Иде на следеће поље формулара" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Приказује списак поља формулара" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Иде на претходно заглавље" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Иде на следеће заглавље" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Приказује списак заглавља" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Иде на претходно заглавље на нивоу %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Иде на следеће заглавље на нивоу %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Приказује списак заглавља на %d. нивоу" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Иде на претходну табелу" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Иде на следећу табелу" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Приказује списак табела" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Иде на претходну слику" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Иде на следећу сику" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Приказује списак слика" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Иде на претходни орјентир" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Иде на следећи орјентир" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Приказује списак орјентира" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Иде на претходни велики објекат" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Иде на следећи велики објекат" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Приказује списак великих објеката" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Иде на претходну везу" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Иде на следећу везу" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Приказује списак веза" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Иде на претходни списак" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Иде на следећи списак" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Приказује списак спискова" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Иде на претходну ставку списка" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Иде на следећу ставку списка" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Приказује списак ставки списка" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Иде на претходну живу област" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Иде на следећу живу област" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Иде на последњу живу област која објави саопштење" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Иди на родитељ објекта са фокусом навигатора." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Иди на прво дете објекта са фокусом навигатора." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Иди на следећег суседа објекта са фокусом навигатора." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Иди на претходног суседа објекта са фокусом навигатора." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Враћа се на објекат са фокусом тастатуре" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Пребацује тастере структурне навигације" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Иде на претходни пасус" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Иде на следећи пасус" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Приказује списак пасуса" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Иде на претходно радио дугме" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Иде на следеће радио дугме" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Приказује списак радио дугмади" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Иде на претходни раздвајач" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Иде на следећи раздвајач" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Иде на претходну табелу" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Иде на следећу табелу" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Приказује списак табела" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Иде доле једну ћелију" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Иде на прву ћелију у табели" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Иде на последњу ћелију у табели" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Иде лево једну ћелију" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Иде десно једну ћелију" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Иде горе једну ћелију" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Окида стање режима распоређивања" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Пребацује се између режима читања и фокусирања" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Укључује режим лепљивог фокуса" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Укључује режим лепљивог разгледања" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Иде на претходну непосећену везу" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Иде на следећу непосећену везу" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Приказује списак непосећених веза" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Иде на претходну посећену везу" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Иде на следећу посећену везу" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Приказује списак посећених веза" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "алис плава" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "античко беле" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "аквамарин" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "азурна" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "беж" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "чорбаста" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "црна" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "бланширано бадемаста" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "плава" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "плаво љубичаста" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "браон" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "светло смеђа" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "академска плава" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "шартреска" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "чоколадна" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "корална" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "различак плава" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "кукурузно свилена" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "тамно црвена" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "светло зелено плава" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "тамно плава" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "тамно зелено плава" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "златица тамно жута" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "тамно сива" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "тамно зелена" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "тамна жутомрка" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "тамна пурпурно црвена" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "тамна маслинасто зелена" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "тамна наранџаста" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "тамна орхидеја" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "тамно црвена" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "лосос тамна" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "тамна морско зелена" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "тамна шкриљкасто плава" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "тамна шкриљкасто сива" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "тамна тиркизна" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "тамно љубичаста" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "тамно розе" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "дубоко небески плава" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "мутно сива" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "врдламски плава" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "цигла" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "цветна бела" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "шумска зелена" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "фуксија" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "геинсборо" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "дух бела" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "златна" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "златичаста" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "сива" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "зелена" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "зелено жута" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "медљикаста" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "топла розе" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "индијска црвена" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "индиго" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "слоновача" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "жутомрка" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "лаванда" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "румена лаванда" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "травњак зелена" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "лимун шифонска" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "светло плава" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "светло корална" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "светла светло плава" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "светло златичасто зелена" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "светло сива" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "светло зелена" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "светло розе" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "светла лосос" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "светла морско зелена" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "светла небески плава" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "светло шкриљкасто сива" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "светло челично плава" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "светла жута" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "лимета" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "зелена лимете" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "боја платна" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "пурпурно црвена" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "бордо" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "средње аквамарин" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "средње плава" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "средње орхидеја" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "средње љубичасто" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "средње морско зелена" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "средње шкриљкасто пава" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "средње пролећно зелена" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "средње тиркизна" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "средње љубичасто зелена" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "поноћно плава" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "светло зелена кремаста" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "магловита розе" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "мокасина" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "навахо бела" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "морнарска" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "стара чипка" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "маслинаста" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "маслинасто жуђкасто смеђа" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "наранџаста" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "наранџасто црвена" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "орхидеја" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "бледо златичаста" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "бледо зелена" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "бледо тиркизна" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "бледо љубичасто црвена" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "папаја" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "лист брескве" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "перу" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "розе" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "шљива" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "прашкасто плава" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "љубичаста" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "црвена" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "ружичасто браонкаста" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "краљевско плава" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "браон коњског седла" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "лосос" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "пескивита браон" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "морска зелена" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "морска шкољка" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "сијена" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "сребрна" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "небеско плава" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "шкриљкасто плава" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "шкриљкасто сива" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "снежна" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "пролећно зелена" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "челично плава" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "жутомрка" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "гроготовац" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "чкаљ" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "парадајз" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "тиркизна" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "љубичаста" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "боја жита" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "бела" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "димно бела" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "жута" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "жуто зелена" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Активирај" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" -"Омогући аутоматски режим усредсређивања приликом кретања кроз структуру" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Аутоматски режим усредсређивања приликом кретања знака за уметање" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Аутоматски режим усредсређивања приликом изворног кретања" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Тачка _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Тачка _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Тачке 7 _и 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Откажи" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Иди на" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "У _реду" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Иконица" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Ништа" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Писање" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Најави када _другари почну да пишу" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Обезбеди историјате посебне _поруке причаонице" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Изговори поруке" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Са свих _канала" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Са свих канала када је _било који %s прозор активан" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Само са канала коме је _активан прозор" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Изговори назив причаонице" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Омогући режим простирања садржаја" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "двоструки клик" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "троструки клик" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Основни синтетизатор" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Стварна ниска" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Ниска замене" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Укључи одјек _знаком" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Укључи _диакритичке тастере без размака" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Трен_утно место" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Најмања дужина одговарајућег текста:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Опције претраге" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Изговарај _само измењене линије током претраге" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Изговарај резултате током _претраге" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Наредба" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Свезе тастера" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Основно" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Режим распоређивања." - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "одељак" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Пречице Брајевог писма" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Чува обележиваче" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Датум и време" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Преглед мишем је укључен." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "навигација" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Режим објеката." - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Неповезана" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Напуштам раван преглед." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Подешава ниво причљивости изговора" - -# bug: colon? -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "главни садржај" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Измењено" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Стони рачунар" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Обавештење" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Примљено" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Обавештење" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu подешавања за %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Означи на Брајевом писму" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Прикажи, изузев ако" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Изговори" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Сачувај профил као сукоб" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Сукоб корисничког профила!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Већ постоји профил „%s“.\n" -"Да наставим ажурирање постојећег профила са овим новим изменама?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Учитај кориснички профил" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Само што нисте изменили активни профил. Ако сте само\n" -"начинили измене у вашим поставкама, исте ће бити\n" -"одбачене приликом учитавања профила.\n" -"\n" -"Да наставим са учитавањем профила одбацујући претходне измене?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Сачувај профил као" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Назив _профила:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Уклони кориснички профил" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Уклонићете профил %s. Сва несачувана подешавања и сачувана подешавања унутар " -"овог профила ће бити изгубљена. Да ли желите да наставите са уклањањем овог " -"профила и свих сродних подешавања?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Све" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Програм" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Прозор" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Ништа" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "По_нешто" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "В_ећина" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Ред" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Реченица" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Блок цитата" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Дугме" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Наслов" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Поље за потврду" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Може се кликнути" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Прозорче за избор" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Опис" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Заглавље" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "уметање" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Слика" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Натпис" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Орјентир" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Ниво" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Веза" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Списак" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Ставка списка" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Објекат" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Пасус" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Радио дугме" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Улога" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Изабрана ставка" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Стање" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Текст" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "Путања" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Вредност" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Блокови цитата" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Дугмад" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Поља за потврду" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Објекти на које се може кликнути" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Прозорчићи за избор" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Уноси" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Поља формулара" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Заглавља" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "уметање" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Слике" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Заглавље на %d. нивоу" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Орјентири" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Велики објекти" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Везе" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Спискови" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Ставке списка" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Пасуси" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Радио дугмад" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Табеле" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Непосећене везе" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Посећене везе" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Кретање страницом" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Самостално почни да изговараш страницу када је први пут _учитана" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Представи сажетак странице када је први пут учитана" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Подели говор на г_рупе између пауза" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s основни глас" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Основно" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Хипервеза" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Систем" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Велика слова" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Диспечер говора" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Провера правописа" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Правописна гр_ешка" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Правописни _савет" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Прикажи _смисао грешке" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Изговарај координате ћелија таблице" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Увек изговарај изабрани опсег у таблици" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Најави _заглавље поља" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Кретање табелом" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Прескочи _празне ћелије" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Изговори _ћелију" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Изговарај координате _ћелија" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Изговори распон _вишеструке ћелије" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Назив особине" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Управља кретањем показивача" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Укључи _структурно кретање" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Звучна _тема:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Звучна тема" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Украт_ко" - -#: src/cthulhu/guilabels.py:953 -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Обавештење" -msgstr[1] "Обавештење" -msgstr[2] "Обавештење" -msgstr[3] "Обавештење" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Помак" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Алт" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Контрол" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "леви помак" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "леви алт" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "леви контрол" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "десни помак" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "десни алт" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "десни контрол" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "леви мета" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "десни мета" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "број закључан" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "закључавање слова" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "закључавање тастера шифт" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "закључавање померања" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "страница горе" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "страница доле" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "леви табулатор" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "брисање" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "унеси" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "унеси" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "горе" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "доле" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "лево" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "десно" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "леви супер" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "десни супер" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "избор" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Алт Гр" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "помоћ" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "више" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "пребацивач режима" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "напусти" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "уметни" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "обриши" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "почетна" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "крај" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "почетак" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "дугосилазно" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "прстен" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "црта за прецртавање" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "минус" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Уметни" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Закључавање_слова" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Алт_Д" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Супер" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Мета2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Алт_Л" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ктрл" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Помак" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "подебљано %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "искошено %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "подебљано искошено %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "скриптно %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "подебљано скриптно %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "фрактурно %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "двопотезно %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "подебљано фрактурно %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "безсерифно %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "безсерифно подебљано %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "безсерифно искошено %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "безсерифно подебљано искошено %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "једнопросторно %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s без тачке" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "стрелица на лево" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "стрелица на горе" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "стрелица на десно" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "стрелица на доле" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "стрелица лево-десно" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "стрелица горе-доле" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "стрелица северо-запад" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "стрелица северо-исток" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "стрелица југо-исток" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "стрелица на лево са цртицом" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "стрелица на горе са цртицом" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "стрелица на десно са цртицом" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "стрелица на доле са цртицом" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "двострука стрелица на лево" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "двострука стрелица на горе" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "двострука стрелица на десно" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "двострука стрелица на доле" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "двострука стрелица на лево и десно" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "двострука стрелица на доле и горе" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "двострука стрелица на северо-запад" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "двострука стрелица на северо-исток" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "двострука стрелица на југо-исток" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "двострука стрелица на југо-запад" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "десна указујућа стрелица" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "десни указујући врх стрелице" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "минус" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "мање" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "веће" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "дугосилазно" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "хачек" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "бревом" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "тачка" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "двострука усправна линија" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "три тачке" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "за свако" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "комплемент" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "парцијални диференцијал" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "постоји" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "не постоји" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "празан скуп" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "делта" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "набла" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "припада" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "не припада" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "мали елемент" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "садржи као члан" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "не садржи као члан" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "мало садржи као члан" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "крај доказа" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "производ" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "копроизвод" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "сума" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "плус-минус" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "плус са тачком" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "разломачка коса црта" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "минус скупа" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "звездица" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "кружић" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "метак" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "квадратни корен" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "трећи корен" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "четврти корен" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "пропорционално са" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "бесконачно" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "десни угао" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "угао" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "измерени угао" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "сферни угао" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "дели" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "не дели" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "паралелно са" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "није паралелно са" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "логичко и" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "логичко или" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "пресек" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "унија" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "интеграл" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "двоструки интеграл" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "троструки интеграл" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "гранични интеграл" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "интеграл површине" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "интеграл запремине" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "кружни интеграл на десно" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "гранични кружни интеграл на десно" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "гранични кружни интеграл на лево" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "због тога" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "зато што" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "однос" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "пропорција" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "минус са тачком" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "вишак" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "геометријска пропорција" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "хомотетик" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "тилда" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "обрнута тилда" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "обрнуто лењо с" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "синусни талас" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "уплетени производ" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "није тилда" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "минус тилда" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "асимптотски једнако" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "није асимптотски једнако" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "приближно једнако" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "приближно али заправо није једнако" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ни приближно ни заправо једнако" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "скоро једнако" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "није скоро једнако" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "скоро једнако или једнако" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "трострука тилда" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "потпуно једнако" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "еквивалент" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "геометријски еквивалент" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "разлика између" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "приближава се граници" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "геометријски једнако са" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "приближно једнако или слика" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "слика или приближно једнако" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "двотачка једнако" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "једнако двотачка" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "кружић у једнакости" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "кружић на једнакости" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "одговара" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "процењује се" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "угаоноједнако" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "једнако са звездицом" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "делта једнако" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "једнако са по дефиницији" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "измерено са" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "упитна једнакост" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "није једнако са" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "идентично са" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "није идентично са" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "изричити еквивалент" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "мање или једнако са" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "веће или једнако са" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "мање преко једнакости" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "веће преко једнакости" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "мање али није једнако са" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "веће али није једнако са" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "много мање од" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "много веће од" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "између" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "није еквивалент са" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "није мање од" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "није веће од" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ни мање од ни једнако са" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ни веће од ни једнако са" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "мање од или еквивалент са" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "веће од или еквивалент са" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ни мање од ни еквивалент са" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ни веће од ни еквивалент са" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "мање од или веће од" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "веће од или мање од" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ни мање од ни веће од" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ни веће од ни мање од" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "претходи" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "следи" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "претходи или једнако са" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "следи или једнако са" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "претходи или еквивалент са" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "следи или еквивалент са" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "не претходи" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "не следи" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "подскуп" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "суперскуп" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "није подскуп" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "није суперскуп" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "подскуп или једнако" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "суперскуп или једнако" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ни подскуп ни једнако" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ни суперскуп ни једнако" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "подскуп са неједнакошћу" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "суперскуп са неједнакошћу" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "мултискуп" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "множење мултискупа" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "унија мултискупа" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "квадратна слика" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "квадратни оригинал" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "квадратни преслик или једнако" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "квадратни оригинал или једнако" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "квадратни врх" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "квадратно дно" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "заокружени плус" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "заокружени минус" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "заокружено пута" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "заокружена коса црта дељења" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "заокружена тачка" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "заокружени кружић" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "заокружена звездица" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "заокружена једнакост" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "заокружена цртица" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "уквадраћени плус" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "уквадраћени минус" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "уквадраћено пута" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "уквадраћена тачка" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "десни ексерчић" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "леви ексерчић" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "ексерчић на доле" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "ексерчић на горе" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "утврђивање" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "модели" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "тачно" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "присиљава" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "повратни стил десне троструке усправне траке" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "повратни стил десне двоструке усправне траке" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "не доказује" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "није тачно" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "не присиљава" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "повратни стил негиране десне двоструке усправне траке" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "претходи под односом" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "следи под односом" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "нормална подгрупа" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "садржи нормалну подгрупу" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "нормална подгрупа или једнако" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "садржи нормалну подгрупу или једнако" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "оригинал" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "слика симбола" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "мултимап" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "ермитска конјугована матрица" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "уметање" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "иксор" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "нанд" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "нор" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "десни угао са луком" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "десни троугао" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "ромб" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "тачка" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "звездица" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "подељено пута" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "здруживање" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "леви нормални полудиректни производ чиниоца" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "десни нормални полудиректни производ чиниоца" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "леви полудиректни производ" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "десни полудиректни производ" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "обрнута тилда једнакости" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "увијено логичко или" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "увијено логичко и" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "двоструки подскуп" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "двоструки суперскуп" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "двоструки пресек" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "двострука унија" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "рачва" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "једнако и паралелно са" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "мање са тачком" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "веће са тачком" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "врло много мање од" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "врло много веће од" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "мање од једнако са или веће од" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "веће од једнако са или мање од" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "једнако са или мање од" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "једнако са или веће од" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "једнако са или претходи" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "једнако са или следи" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "не претходи или једнако" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "не следи или једнако" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "није квадратни преслик или једнако" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "није квадратни оригинал или једнако" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "квадратни преслик или није једнако" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "квадратни оригинал или није једнако" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "мање али није еквивалент" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "веће али није еквивалент" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "претходи али није еквивалент" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "следи али није еквивалент" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "није нормална подгрупа" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "не садржи нормалну подгрупу" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "није нормална подгрупа или једнако" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "не садржи нормалну подгрупу или једнако" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "усправна тротачка" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "водоравна тротачка по средини" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "дијагонална тротачка од доле на десно" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "дијагонална тротачка од горе на десно" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "елемент са дугим водоравним прецртом" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "елемент са ограниченим водоравним прецртом" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "мали елемент са ограниченим водоравним прецртом" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "елемент са тачком изнад" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "елемент са цртицом изнад" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "мали елемент са цртицом изнад" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "елемент са цртицом испод" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "елемент са два водоравна прецрта" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "садржи са дугим водоравним прецртом" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "садржи са ограниченим водоравним прецртом" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "мало садржи са ограниченим водоравним прецртом" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "садржи са цртицом изнад" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "мало садржи са цртицом изнад" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "члан зед обележавања" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "лево упољавање" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "десно упољавање" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "лево удољавање" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "десно удољавање" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "горња витичаста" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "доња витичаста" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "лева витичаста заграда" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "десна витичаста заграда" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "заокружена тачка" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "унија са тачком" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "унија са плусом" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "квадратни пресек" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "квадратна унија" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "црни квадратић" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "бели квадратић" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "црни ромб" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "бели кружић" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "црни кружић" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "бели метак" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "црни средње мали квадратић" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s са подвлаком" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s са косом цртом" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s са усправном линијом" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "програм" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "празно" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "подебљано" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "обележивач је унешен" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "обележивач је сачуван" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "обележивач не може бити сачуван" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Нисам пронашао орјентир." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Нисам пронашао орјентир." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Заобилази режим укљученог." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Не могу да добавим приказ калкулатора" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "иконица" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Изглед великих слова је постављен на иконицу." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ништа" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Изглед великих слова је постављен на ништа." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "писање" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Изглед великих слова је постављен на писање." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Програм контролише уметак." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Програм контролише уметак." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Ћелија %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s ћелија је изабрано" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "изабрано од ћелије %s до %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "избор ћелије %s до %s је поништен" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "поништен је избор %s ћелија" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Спречава коришћење опције" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Присиљава коришћење опције" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "ОПЦИЈА" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Необавезни аргументи" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Начин коришћења: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Следеће није исправно: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Штампа познате покренуте програме" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Учитава профил" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Профил не може бити учитан: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Не могу да покренем читача екрана зато што не може да се повеже са радном " -"површи." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Не могу да покренем управника подешавања. Излазим." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Већ је покренут један процес читача екрана за ову сесију.\n" -"Покрените наредбу „cthulhu --replace“ да замените тај процес новим." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "НАЗИВ" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Користи алтернативни директоријум за корисничке поставке" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "ДИР" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Издање овог програма" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Мења тренутно покренути примерак овог читача екрана" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Прикажи ову помоћну поруку и изађи" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Шаље излаз исправљања грешака у „debug-YYYY-MM-DD-HH:MM:SS.out“" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Шаље излаз исправљања грешака у одређену датотеку" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ДАТОТЕКА" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Подешава поставке корисника (текстуална верзија)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Подешава поставке корисника (издање графичког сучеља)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Пријавите грешке на „https://groups.io/g/stormux“." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Исеците избор у оставу." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "исеци" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Избор је умножен у оставу." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "умножен" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Садржај је убачен из оставе." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "убачен" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Неће најављивати када другари почну да пишу." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "најавиће када другари почну да пишу." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Порука из причаонице %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Нови језичак ћаскања %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Неће изговорити назив причаонице." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "изговориће назив причаонице." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Неће обезбедити историјате посебне поруке причаонице." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Обезбедиће историјате посебне поруке причаонице." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "почетак брисања" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "крај брисања" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "почетак уметања" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "крај уметања" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "покрећем означавање" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "крај истицања" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "крај савета" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Крај контејнера." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Није у контејнеру." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "све ставке су изабране" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Основно дугме је %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Подразумевано дугме је %s. Засивљено" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Основно дугме је %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " индекс %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " изложилац %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Није на табели." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "изабран је читав документ" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "поништен је избор целог документа" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "изабран је документ од положаја курсора" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "поништен је избор документа од положаја курсора" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "изабран је документ на положај курсора" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "поништен је избор документа на положај курсора" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Динамичко заглавље колоне подешено за ред %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Динамичко заглавље колоне је обрисано." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Динамичко заглавље реда подешено за колону %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Динамичко заглавље реда је обрисано." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "празно" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f килобајта" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f мегабајта" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Нисам пронашао ниједну датотеку." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Садржај је прикачен у оставу." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Садржај је умножен у оставу." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Не користим раван преглед." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Улазим у раван преглед." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Напуштам раван преглед." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Премешта раван преглед на реч изнад тренутне речи" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Равни преглед неограничен" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "садржи формулу" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "отвара дијалог" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "отвара мрежу" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "отвара списак" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "отвара мени" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "отвара стабло" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "веза мапиране слике" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Тастер који сте унели је већ повезан са „%s“" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Тастер је ухваћен: %s. Притисните „ентер“ да потврдите." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Нови тастер је: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Пречица тастатуре је обрисана. Притисните „ентер“ да потврдите." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Пречица тастатуре је уклоњена." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "унесите нови тастер" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "тастер" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Одјек је подешен на тастер." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ништа" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Одјек је подешен на ништа." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "тастер и реч" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Одјек је подешен на тастер и реч." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "реченица" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Одјек је подешен на реченицу." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "реч" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Одјек је подешен на реч." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "реч и реченица" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Одјек је подешен на реч и реченицу." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Затворено: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "актуарски симбол" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "поље" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "кружић" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "дуги знак дељења" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "радикал" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "заобљено поље" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "водоравни прецрт" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "усправни прецрт" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "доњи дијагонални прецрт" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "горњи дијагонални прецрт" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "стрелица северозапад" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "линија при дну" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "линија с лева" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "линија с десна" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "линија при врху" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "фазни угао" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "арапски симбол факторијела" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "и" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "почетак разломка" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "разломак без црте, почетак" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "над" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "крај разломка" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "квадратни корен" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "трећи корен" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "корен" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "почетак корена" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "крај корена" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "индекс" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "изложилац" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "пред-индекс" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "пред-изложилац" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "подизложилац" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "надизложилац" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "крај табеле" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "крај угнежђене табеле" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "недоступно" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Искључено" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Изговор увлачења и поравнања је искључен." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Укључено" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Изговор увлачења и поравнања је укључен." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Режим за учење. Притисните „Напусти“ да изађете." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Улазим у режим за учење. Притисните било који тастер да чујете његову " -"функцију. Да видите документацију читача екрана, притисните F1. Да добавите " -"списак подразумеваних пречица читача екрана, притисните F2. Да добавите " -"списак пречица читача екрана за тренутни програм, притисните F3. Да изађете " -"из режима за учење, притисните тастер „Esc“." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "напуштам блок цитата." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "напуштам појединости." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "напуштам довод." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "напуштам фигуру." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "напуштам формулар." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "напуштам врпцу." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "напуштам комплементарни садржај." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "напуштам информације." - -# bug: colon? -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "напуштам главни садржај." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "напуштам навигацију." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "напуштам област." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "напуштам претрагу." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "напуштам списак." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "напуштам панел." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "напуштам табелу." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "напуштам облачић." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "напуштам сажетак." - -# bug: colon? -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "напуштам захвалнице." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "напуштам поговор." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "напуштам додатак." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "напуштам библиографију." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "напуштам поглавље." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "напуштам знак штампара." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "напуштам закључак." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "напуштам заслугу." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "напуштам заслуге." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "напуштам посвету." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "напуштам белешке на крају." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "напуштам епиграф." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "напуштам епилог." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "напуштам штампарске грешке." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "напуштам пример." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "напуштам предговор." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "напуштам појмовник." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "напуштам индекс." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "напуштам увод." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "напуштам списак страница." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "напуштам део." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "напуштам увод." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "напуштам пролог." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "напуштам цитат." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "напуштам питања и одговоре." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "напуштам савет." - -# bug: colon? -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "напуштам табелу садржаја." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "изабрана је линија од положаја курсора на доле" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "изабрана је линија од положаја курсора на горе" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "поништен је избор линије од положаја курсора на доле" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "поништен је избор линије од положаја курсора на горе" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Напуштам режим учења." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "изабрана је линија на почетку претходног положаја курсора" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "изабрана је линија на крају претходног положаја курсора" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "веза" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "иста страница" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "исти сајт" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "други сајт" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s веза до %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s веза" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "посећена веза %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Користите стрелице на горе и на доле за кретање кроз списак. Притисните " -"„Изађи“ да изађете." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Све живе области су подешене на искључено" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "враћени су нивои љубазности живих области" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "ниво учтивости %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "подешавам живу област на самопоуздано" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "подешавам живу област на искључење" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "подешавам живу област на љубазно" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "подешавам живу област на непристојно" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Надгледање живих области је искључено" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Надгледање живих области је укључено" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "нема сачуваних стварних порука" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Подршка живе области је искључена" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Нисам пронашао" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Не могу да пронађем текуће место." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "искљ" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "укљ" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "погрешно написано" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Погрешно написана реч: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Садржај је %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Режим читања" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Режим усредсређивања" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "За укључивање режима усредсређивања, притисните %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Режим усредсређивања је сада лепљив." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Режим разгледања је лепљив." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Режим распоређивања." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Режим објеката." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Нема више великих објеката." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Миш изнад објекта није пронађен." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Преглед мишем је искључен." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Преглед мишем је укључен." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Грешка: Не могу да направим списак објеката." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Нема деце." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Нема следећег." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d проценат." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Иде на претходну реч" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Поједностављена навигација укључена." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Поједностављена навигација искључена." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Ниво угнежђивања %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Нова ставка је додата" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Нема радњи на: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Без фокуса" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Ниједан програм није у првом плану." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Нема више блокова цитата." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Нема више дугмади." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Нема више поља за потврду." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Нема више великих објеката." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Нема више објеката на које се може кликнути." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Нема више прозорчића за избор." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Нема више уноса." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Нема више поља формулара." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Нема више заглавља." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Нема више заглавља на нивоу %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Нема више табела." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Нема више слика." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Нисам пронашао орјентир." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Нема више веза." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Нема више спсискова." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Нема више ставки на списку." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Нема више живих области." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Нема више пасуса." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Нема више радио дугмади." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Нема више раздвајача." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Нема више табела." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Нема више непосећених веза." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Нема више посећених веза." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Нема изабраног текста." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Није на вези." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Обавештење" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Дно" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Врх" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Нема порука обавештења" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "цифре" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Изговара бројеве као цифре." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "речи" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Изговара бројеве као речи." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "искљ" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "укљ" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Учитавам. Сачекајте мало." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Учитавање је завршено." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Завршeно је учитавање %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Страница има %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "изабрана је страна од положаја курсора" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "изабрана је страна на положај курсора" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "поништен је избор стране од положаја курсора" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "поништен је избор стране на положај курсора" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "изабран је пасус испод положаја курсора" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "изабран је пасус изнад положаја курсора" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "поништен је избор пасуса испод положаја курсора" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "поништен је избор пасуса изнад положаја курсора" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Већ је отворен један примерак прозорчета поставки Орке.\n" -"Затворите га пре него што отворите нови." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "сличица %(position)d од %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Профил је постављен на „%s“." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Нисам пронашао профиле." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Линија напредовања %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Све" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Ниво интерпункције је подешен на све." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Већина" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Ниво интерпункције је подешен на већину." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ништа" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Ниво интерпункције је подешен на ништа." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Понешто" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Ниво интерпункције је подешен на понешто." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Претражујем." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Претрага је обављена." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Подешавања читача екрана су поново учитана." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Изабрани текст је: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Избор је обрисан." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Избор је враћен." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Поништен је избор текста." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Величина: %d, %d. Положај: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Ширина: %d. Висина: %d. %d са леве стране. %d са врха." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Говор је искључен." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Говор је укључен." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "брже." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "спорије." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "гласније." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "тише." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "гласније." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "спорије." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Брзина %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Висина %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Јачина звука %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Модул speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Глас speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Нема доступних сервера." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Нема доступних гласова." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Говор је укључен." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Говор се неће користити." - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Ниво причљивости: низак" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Ниво причљивости: висок" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " тачка тачка тачка" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu вас поздравља." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu вреба испод таласа." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Режим спавања укључен за %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Режим спавања искључен за %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Изговор није доступан." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Нисам пронашао" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Нисам нашао траку стања" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "ниска није пронађена" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Тастери структурног кретања су искључени." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Тастери структурног кретања су укључени." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Није пронађено" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Ред %(row)d, колона %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Крај табеле" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Изговори ћелију" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Изговори ред" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Нејединствена" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Није на табели." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Колоне су поново поређане" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Редови су поново поређани" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "колона %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "колона бр. %(index)d од %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Дно колоне." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Врх колоне." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Колона %s је изабрана" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Колоне %s до %s изабрано" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Поништен је избор колона %s до %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Поништен је избор колоне %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "ред %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "ред бр. %(index)d од %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Почетак реда." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Крај реда." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Ред је обрисан." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Последњи ред је обрисан." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Ред је убачен." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Ред је убачен на крај табеле." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Ред %s је изабран" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Редови %s до %s изабрани" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Поништен је избор редова %s до %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Поништен је избор реда %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "изабрано" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "поништен је избор" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H сати, %M минута и %S секунде" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H сати и %M минута" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Уникод %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "поништи" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "врати" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu верзија %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "размак" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Преламам на дно." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Преламам на врх." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 ставки" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Ћелија обухвата %d ред" -msgstr[1] "Ћелија обухвата %d реда" -msgstr[2] "Ћелија обухвата %d редова" -msgstr[3] "Ћелија обухвата %d ред" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d колона" -msgstr[1] " %d колоне" -msgstr[2] " %d колона" -msgstr[3] " %d колона" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Ћелија обухвата %d колону" -msgstr[1] "Ћелија обухвата %d колоне" -msgstr[2] "Ћелија обухвата %d колона" -msgstr[3] "Ћелија обухвата %d колону" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d знак је предуг" -msgstr[1] "%d знака су предуга" -msgstr[2] "%d знакова је предуго" -msgstr[3] "%d знак је предуг" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d прозорче)" -msgstr[1] "(%d прозорчета)" -msgstr[2] "(%d прозорчета)" -msgstr[3] "(%d прозорче)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d прозорче није у првом плану" -msgstr[1] "%d прозорчета нису у првом плану" -msgstr[2] "%d прозорчета није у првом плану" -msgstr[3] "%d прозорче није у првом плану" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d бајт" -msgstr[1] "%d бајта" -msgstr[2] "%d бајтова" -msgstr[3] "%d бајт" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Пронашао сам %d датотеку" -msgstr[1] "Пронашао сам %d датотеке" -msgstr[2] "Пронашао сам %d датотека" -msgstr[3] "Пронашао сам %d датотеку" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d формулар" -msgstr[1] "%d формулара" -msgstr[2] "%d формулара" -msgstr[3] "%d образац" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d заглавље" -msgstr[1] "%d заглавља" -msgstr[2] "%d заглавља" -msgstr[3] "%d заглавље" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d ставка" -msgstr[1] "%d ставке" -msgstr[2] "%d ставки" -msgstr[3] "%d ставка" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d орјентир" -msgstr[1] "%d орјентира" -msgstr[2] "%d орјентира" -msgstr[3] "%d орјентир" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "Пронашао сам %d ставку" -msgstr[1] "Пронашао сам %d ставке" -msgstr[2] "Пронашао сам %d ставки" -msgstr[3] "Пронашао сам %d ставку" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Напуштам %d блок цитата." -msgstr[1] "Напуштам %d блока цитата." -msgstr[2] "Напуштам %d блокова цитата." -msgstr[3] "Напуштам %d блок цитата." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Напуштам %d списак." -msgstr[1] "Напуштам %d списка." -msgstr[2] "Напуштам %d спискова." -msgstr[3] "Напуштам %d списак." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Списак непознате величине" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Списак са %d ставком" -msgstr[1] "Списак са %d ставке" -msgstr[2] "Списак са %d ставки" -msgstr[3] "Списак са %d ставком" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Довод непознате величине" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Довод са %d чланком" -msgstr[1] "Довод са %d чланка" -msgstr[2] "Довод са %d чланака" -msgstr[3] "Довод са %d чланком" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Опис са %d појмом" -msgstr[1] "Опис са %d појма" -msgstr[2] "Опис са %d појмова" -msgstr[3] "Опис са %d појмом" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d вредност" -msgstr[1] "%d вредности" -msgstr[2] "%d вредности" -msgstr[3] "%d вредност" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "математичка табела са %d пољем" -msgstr[1] "математичка табела са %d поља" -msgstr[2] "математичка табела са %d поља" -msgstr[3] "математичка табела са %d пољем" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d колона" -msgstr[1] "%d колоне" -msgstr[2] "%d колона" -msgstr[3] "%d колона" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "угнежђена математичка табела са %d редом" -msgstr[1] "угнежђена математичка табела са %d реда" -msgstr[2] "угнежђена математичка табела са %d реда" -msgstr[3] "угнежђена математичка табела са %d редом" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d порукa.\n" -msgstr[1] "%d поруке.\n" -msgstr[2] "%d порукa.\n" -msgstr[3] "%d порукa.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d проценат." -msgstr[1] "%d процента." -msgstr[2] "%d процената." -msgstr[3] "%d проценат." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d проценат документа је прочитан" -msgstr[1] "%d процента документа је прочитано" -msgstr[2] "%d процената документа је прочитано" -msgstr[3] "%d проценат документа је прочитан" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d пиксел" -msgstr[1] "%d пиксела" -msgstr[2] "%d пиксела" -msgstr[3] "%d пиксел" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d знак %(repeatChar)s" -msgstr[1] "%(count)d знака %(repeatChar)s" -msgstr[2] "%(count)d знакова %(repeatChar)s" -msgstr[3] "Један знак %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "Изабрана је %(index)d ставка од %(total)d" -msgstr[1] "Изабране су %(index)d ставке од %(total)d" -msgstr[2] "Изабрано је %(index)d ставки од %(total)d" -msgstr[3] "Изабрана је једна ставка од %(total)d" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Пронашао сам %d основну пречицу читача екрана." -msgstr[1] "Пронашао сам %d основне пречице читача екрана." -msgstr[2] "Пронашао сам %d основних пречица читача екрана." -msgstr[3] "Пронашао сам %d основну пречицу читача екрана." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Пронашао сам %(count)d пречицу читача екрана за %(application)s." -msgstr[1] "Пронашао сам %(count)d пречице читача екрана за %(application)s." -msgstr[2] "Пронашао сам %(count)d пречица читача екрана за %(application)s." -msgstr[3] "Пронашао сам једну пречицу читача екрана за %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d размак" -msgstr[1] "%d размака" -msgstr[2] "%d размака" -msgstr[3] "%d размак" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d табулатор" -msgstr[1] "%d табулатора" -msgstr[2] "%d табулатора" -msgstr[3] "%d табулатор" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d табела" -msgstr[1] "%d табеле" -msgstr[2] "%d табела" -msgstr[3] "%d табела" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "табела непознате величине" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "табела са %d колоном, непознати број редова" -msgstr[1] "табела са %d колоне, непознати број редова" -msgstr[2] "табела са %d колона, непознати број редова" -msgstr[3] "табела са %d колоном, непознати број редова" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "табела са %d редом, непознати број колона" -msgstr[1] "табела са %d реда, непознати број колона" -msgstr[2] "табела са %d редова, непознати број колона" -msgstr[3] "табела са %d редом, непознати број колона" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "табела има %d ред" -msgstr[1] "табела има %d реда" -msgstr[2] "табела има %d редова" -msgstr[3] "табела има %d ред" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "пре %d секунду" -msgstr[1] "пре %d секунди" -msgstr[2] "пре %d секунди" -msgstr[3] "пре %d секунду" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "пре %d минут" -msgstr[1] "пре %d минута" -msgstr[2] "пре %d минута" -msgstr[3] "пре %d минут" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "пре %d сат" -msgstr[1] "пре %d сати" -msgstr[2] "пре %d сати" -msgstr[3] "пре %d сат" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "пре %d дан" -msgstr[1] "пре %d дана" -msgstr[2] "пре %d дана" -msgstr[3] "пре %d дан" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d непосећена веза" -msgstr[1] "%d непосећене везе" -msgstr[2] "%d непосећених веза" -msgstr[3] "%d непосећена веза" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d посећена веза" -msgstr[1] "%d посећене везе" -msgstr[2] "%d посећених веза" -msgstr[3] "%d посећена веза" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "прекидач" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(index)d од %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d од %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "ставка %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "НИВО %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ниво стабла %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "НИВО СТАБЛА %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "појединости за %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "постоје појединости за %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "савет" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "изборно прозорче је за уређивање" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "измењив садржај" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "довод" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "фигура" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "сажетак" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "заслуге" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "поговор" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "додатак" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "библиографски унос" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "библиографија" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "поглавље" - -# bug: colon? -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "знак штампара" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "закључак" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "насловница" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "заслуга" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "заслуге" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "посвета" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "белешка на крају" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "белешке на крају" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "епиграф" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "епилог" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "штампарске грешке" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "пример" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "предговор" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "речник" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "индекс" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "увод" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "прелом странице" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "списак страница" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "део" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "увод" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "пролог" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "цитат" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "питања и одговори" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "поднаслов" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "табела садржаја" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "з%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s %(level)d. ниво" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "водоравна трака премицања" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "усправна трака премицања" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "водоравни клизач" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "усправни клизач" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "водоравни разделник" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "усправни разделник" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "пребацивач" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Панел иконица" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "врпца" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "комплементарни садржај" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "информације" - -# bug: colon? -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "главни садржај" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "навигација" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "област" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "претрага" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "посећена веза" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "дугме изборника" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "поређано узлазно" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "поређано низлазно" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "поређано" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "може се кликнути" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "скупљено" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "раширено" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "има опширан опис" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "водоравно" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "усправно" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "означено" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "није означено" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "укљ" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "искљ" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "делимично означено" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "притиснуто" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "није притиснуто" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "није изабрано" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "изабрано" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "није изабрано" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "није изабрана" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "посећена" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "непосећена" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "засенчено" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "само читање" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "самочтњ" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "обавезно" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "више-изборно" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "неисправан унос" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "неисправно" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "неисправно писање" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "правопис" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "неисправна граматика" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "граматика" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Пронађи" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Прозорче претраге за читач екрана" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Затвори" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Пронађи" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Потражи:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Потражи:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Врха прозора" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Врха прозора" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Почни са:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Преламај _около" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Тражи _уназад" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Смер претраживања:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Упореди величину слова" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Упореди само _целе речи" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Опције:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Основно" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Велика слова" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Хипервеза" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Систем" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Програм" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Прозор" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Читач екрана Орка" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "По_моћ" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Примени" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Преносни рачунар" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Распоред тастатуре" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Активни _профил:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Профил покретања:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Учитај" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Сачувај _као" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Уклони" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Профили" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Прикажи облачиће објашњења" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Изговори предмете под _мишем" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Миш" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Облик _времена:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Облик _датума:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Датум и време" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Изговори _ажурирања" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Брајева ажурирања" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Учестаност (сек):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Примени на:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Огласи ажурирања" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Освежавања линије напредовања" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Укључи _премотавање уназад и брзо унапред за изговор свега" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Укључи _структурно кретање у изговору свега" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Изговори све _према:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Најави _блокове цитата у изговору свега" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Најави _списак у изговору свега" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Најави _табеле у изговору свега" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Најави _панеле у изговору свега" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Најави _формуларе у изговору свега" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Најави _орјентире у изговору свега" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Изговори све" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Представљање елемента:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Опште" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Јачина _звука:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Највиша _тачка:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Проток:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Особа:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Језик:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Синтетизатор _говора:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Систем изговора:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Врсте _гласа:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Изглед великих слова:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Подешавања врсте гласа" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Изговори ниске са више слова као _речи" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Изговори _бројеве као цифре" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Општа подешавања гласа" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Говор" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Укључи _изговор" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Оп_ширно" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Опширност" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Све" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Ниво интерпункције" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Говори само приказан текст" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Изговори празне редове" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Изговори _увлачење и поравнање" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Изговори подсетник _објекта" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Изговори положај _детета" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Изговори поруке упутства" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Поруке _система су опширне" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Изговори _боје као називе" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Најави _блокове цитата приликом навигације" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Најави _спискове приликом навигације" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Најави _табеле приликом навигације" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Изговори указивач _лоше написане речи" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Најави _панеле приликом навигације" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Најави _орјентире приликом навигације" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Најави _формуларе приликом навигације" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Изговори _опис" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Изговори читав ред у табеларним прорачунима" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Изговори читав ред у табелама _документа" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Изговори читав ред у табелама _графичког сучеља" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Говорни контекст" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Говор" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Укључи Брајеву _подршку" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Скраћени називи улоге" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Искључи симбол _краја реда" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Табела _скраћивања:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Укључи скраћено Брајево писмо" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Омогући пре_ламање речи" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Подешавања екрана" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Ништа" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Указивач избора" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Указивач хипервезе" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Укључи _поруке бљеска" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Трајање (секунди):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Поруке су _трајне" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Поруке су _опширне" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Поставке бљескаве поруке" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Брајево писмо" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Укључи _одјек тастера" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Укључи тастере _слова" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Укључи тастере _бројева" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Укључи тастере _интерпункције" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Укључи _размак" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Укључи тастере _измењивача" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Укључи тастере _функције" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Укључи тастере _радње" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Укључи тастере _кретања" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Укључи одјек _речју" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Укључи одјек _реченицом" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Одјек" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Тастер(и) _измењивача читача екрана:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Свезе тастера" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Речник изговора" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Нови унос" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Обриши" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Изговор" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Изговори _све" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Не _изговарај ништа" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Поново постави" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Атрибути текста" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Премести на д_но" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Премести за један _доле" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Премести за један _горе" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Премести на в_рх" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Подесите изабрани атрибут" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Указивач Брајевог писма" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Атрибути текста" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Омогући AI помоћника" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Добављач:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Локални - Бесплатни)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Датотека API _кључа:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Путања до датотеке API кључа" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Преузми _Claude API кључ" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Отвори прегледач да преузмеш Claude API кључ и аутоматски сачувај" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Захтевај потврду пре AI радњи" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _модел:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Име модела за Ollama (нпр. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _крајња тачка:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL крајње тачке Ollama API (нпр. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Квалитет снимка екрана:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "доле" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Средње" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Високо" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI помоћник" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Језик:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "јен" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Фактор скалирања:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Слика у сивим тоновима" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Инвертуј слику" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Црно-бела слика" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Праг црно/бело:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Анализирај боје" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Садржај је умножен у оставу." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"а : авала, б : београд, в : ваљево, г : голија, д : дрина, ђ : ђаковица, е : " -"европа, ж : жабљак, з : земун, и : игало, ј : јадран, к : косово, л : " -"ловћен, љ : љубовија, м : морава, н : ниш, њ : његош, о : обилић, п : пирот, " -"р : рума, с : сава, т : тимок, ћ : ћуприја, у : ужице, ф : футог, х : херој, " -"ц : цетиње, ч : чачак, џ : џеп, ш : шабац" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "боја позадине" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "пуна висина позадине" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "истачкавање позадине" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "усмерење" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "измењив" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "назив фамилије" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "боја првог плана" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "истачкавање првог плана" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "ефекат фонта" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "увлачење" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "грешка" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "невидљив" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "поравнавање" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "језик" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "лева маргина" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "висина линије" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "стил пасуса" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "тачака изнад линија" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "тачака испод линија" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "тачака унутар прелома" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "десна маргина" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "издигнуће" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "размера" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "величина" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "развлачење" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "прецртано" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "стил" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "украс текста" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "усмерење текста" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "сенка текста" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "подвлака" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "варијанта" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "усправно поравнање" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "тежина" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "режим прелома" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "режим уписа" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "тачно" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "нетачно" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ништа" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "гравирано" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "испупчено" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "оквирно" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "надвучено" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "линија преко" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "трептав" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "црно" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "једноструко" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "двоструко" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "доле" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "знак" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "реч" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "знак речи" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "лнд" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "днл" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "лево" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "десно" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "на средину" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "без поравнања" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "попуњено" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "врло збијен" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "веома збијен" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "збијен" - -# bug: colon? -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "полу збијен" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "обично" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "полу раширен" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "раширен" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "веома раширен" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "врло раширен" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "мала слова" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "коса" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "искошена" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Основно" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Тело текста" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Заглавље" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "основни правац" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "под" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "над" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "врх" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "текст на врх" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "средина" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "дно" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "текст на дно" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "наслеђен" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "лд-тб" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "дл-тб" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "тб-дл" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "тб-лд" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "бт-дл" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "бт-лд" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "лд" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "дл" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "тб" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "пуна" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "правопис" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Притисните размак да измените." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Притисните размак да раширите, и користите горе и доле да изаберете ставку." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Притисните алт+ф6 да поставите проистекли прозор у први план." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Да прелазите на ставке, користите или тастере стрелица или куцајте претрагу." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Да стигнете до изборника система притисните тастер алт+ф1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Користите горе и доле да изаберете ставку." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Да скупите, притисните шифт плус лево." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Да раширите, притисните шифт плус десно." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Да активирате притисните унеси." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Упишите текст." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Користите лево и десно да видите друге језичке." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Да активирате притисните размак." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Користите стрелице на горе или на доле да изаберете вредност. Или укуцајте " -"жељену нумеричку вредност." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Користите тастере стрелица да промените." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Да се крећете, притисните леву или десну стрелицу. Да се крећете кроз ставке " -"притисните стрелице горе или доле." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Да унесете под изборник, притисните стрелицу десно." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Да смањите притисните стрелицу лево, да повећате притисните стрелицу десно. " -"Да поставите на најмање притисните почетак, а за највише притисните крај." diff --git a/po/sr@latin.po b/po/sr@latin.po deleted file mode 100644 index 9b66827..0000000 --- a/po/sr@latin.po +++ /dev/null @@ -1,9325 +0,0 @@ -# Serbian translation of cthulhu -# Courtesy of Prevod.org team (http://prevod.org/) -- 2003—2017. -# This file is distributed under the same license as the cthulhu package. -# Danilo Šegan -# Miroslav Nikolić , 2012—2017. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2018-02-16 09:37+0100\n" -"Last-Translator: Marko M. Kostić \n" -"Language-Team: srpski \n" -"Language: sr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " -"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Project-Style: gnome\n" -"X-Generator: Poedit 2.0.3\n" - -msgid "Cthulhu Screen Reader" -msgstr "Čitač ekrana Orka" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "čitač ekrana;govor;brajeva azbuka;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "upzr" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "srl" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "plt" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "ntps" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "pzš" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "birbje" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "zglkol" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "pzi" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ikn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "okv" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "pzv" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "prz" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "crt" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "birdt" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "ppu" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "slb" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "stp" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "zglv" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "slk" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "unok" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "ntp" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "nslgpvš" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "vza" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "sps" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "stvsps" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "izb" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "linizb" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "stvizb" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "povopc" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "str" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "spsjz" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "lzk" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "iskizb" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "lnnap" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "dgm" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "stvrdizb" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "krnpv" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "zglrd" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "lnpm" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "pvpm" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "odelj" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "razdvjč" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "klizač" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "pvrzdv" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "vrtt" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "linstnj" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "polj" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "odstvizb" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "tkst" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "prbcvč" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "lnal" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "svt" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "stb" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "npz" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "pgld" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "prz" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "zgl" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "pdn" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "psus" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "prg" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "samd" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "lnurđ" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "ugnj" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Češki, 1. stepen" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Španski, 1. stepen" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanadski francuski, 2. stepen" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Francuski francuski, 2. stepen" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letonski, 1. stepen" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holandski, 1. stepen" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norveški, 0. stepen" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norveški, 1. stepen" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norveški, 2. stepen" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norveški, 3. stepen" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Poljski, 1. stepen" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugalski, 1. stepen" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Švedski, 1. stepen" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arapski, 1. stepen" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Velški, 1. stepen" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Velški, 2. stepen" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Nemački, 0. stepen" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Nemački, 1. stepen" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Nemački, 2. stepen" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Britanski engleski, 2. stepen" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Britanski engleski, 1. stepen" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Američki engleski, 1. stepen" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Američki engleski, 2. stepen" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadski francuski, 1. stepen" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Francuski francuski, 1. stepen" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grčki, 1. stepen" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Indijski, 1. stepen" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Mađarski računar sa 8 tačkica" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Mađarski, 1. stepen" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Mađarski, 1. stepen" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italijanski, 1. stepen" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgijski, 1. stepen" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "razmak" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "novi red" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "uzvičnik" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "navodnik" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "broj" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procenat" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "i" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "leva mala zagrada" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "desna mala zagrada" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "zvezdica" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plus" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "zapeta" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "crta" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "tačka" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "kosa crta" - -# bug: colon? -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dve tačke" - -# bug: colon? -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "tačka-zarez" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "manje" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "jednako" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "veće" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "upitnik" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "ludo a" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "leva uglasta" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "kontra kosa crta" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "desna uglasta" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "kapica" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "podvlaka" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "kratkouzlazni" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "leva vitičasta" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "uspravna crta" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "desna vitičasta" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "bez razmaka" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "obrnuti znak uzvika" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "centi" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "funte" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "znak valute" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "jen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "prekinuta uspravna crta" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "odeljak" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "dijarezis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "autorska prava" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "izložilac a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "leva dvostruka oštra zagrada" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logično ne" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "kratkosilazni naglasak" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "zaštitni znak" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "makron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "stepeni" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus-minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "izložilac 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "izložilac 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "dugouzlazno" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mi" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "obeleživač pasusa" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "srednja tačka" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "sedilja" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "izložilac 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "redni broj" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "desna dvostruka oštra zagrada" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "jedna četvrtina" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "polovina" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "tri četvrtine" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "obrnuti znak pitanja" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "malo dugouzlazno a" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "VELIKO KRATKOUZLAZNO A" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "VELIKO DUGOUZLAZNO A" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "VELIKO DUGOSILAZNO A" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "VELIKO A SA TILDOM" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "VELIKO A SA DVE TAČKE" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "VELIKO A SA KRUŽIĆEM" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "VELIKO AE" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "VELIKO C SA SEDILJOM" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "VELIKO KRATKOUZLAZNO E" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "VELIKO DUGOUZLAZNO E" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "VELIKO DUGOSILAZNO E" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "VELIKO E SA DVE TAČKE" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "VELIKO KRATKOUZLAZNO I" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "VELIKO DUGOUZLAZNO I" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "VELIKO DUGOSILAZNO I" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "VELIKO I SA DVE TAČKE" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "VELIKO Đ LATINICOM" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "VELIKO N SA TILDOM" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "VELIKO KRATKOUZLAZNO O" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "VELIKO DUGOUZLAZNO O" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "VELIKO DUGOSILAZNO O" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "VELIKO O SA TILDOM" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "VELIKO O SA DVE TAČKE" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "puta" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "PRECRTANO VELIKO O" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "VELIKO KRATKOUZLAZNO U" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "VELIKO DUGOUZLAZNO U" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "VELIKO DUGOSILAZNO U" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "VELIKO U SA DVE TAČKE" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "VELIKO DUGOUZLAZNO IPSILON" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "TORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "nemačko malo duplo s" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "malo kratkouzlazno a" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "malo dugosilazno a" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "malo a sa tildom" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "malo a sa dve tačke" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "malo a sa kružićem" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "malo ae" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "malo c sa sediljom" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "malo kratkouzlazno e" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "malo dugouzlazno e" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "malo dugosilazno e" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "malo e sa dve tačke" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "malo kratkouzlazno i" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "malo dugouzlazno i" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "malo dugosilazno i" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "malo i sa dve tačke" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "malo đ latinicom" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "malo n sa tildom" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "malo kratkouzlazno o" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "malo dugouzlazno o" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "malo dugosilazno o" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "malo o sa tildom" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "malo o sa dve tačke" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "podeljeno" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "malo precrtano o" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "malo torn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "malo dugouzlazno u" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "malo kratkouzlazno u" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "malo dugosilazno u" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "malo u sa dve tačke" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "malo dugouzlazno ipsilon" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "malo ipsilon sa dve tačke" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "VELIKO IPSILON SA DVE TAČKE" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "malo florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "srednja crta" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "levi samostalni navodnik" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "desni samostalni navodnik" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "samostalni donji navodnik" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "levi dvostruki navodnik" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "desni dvostruki navodnik" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dvostruki donji navodnik" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "dager" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dupli dager" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "metak" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "trougaoni metak" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promil" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "primus" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "sekundum" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "trostruki" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "metak crtica" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "evro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "zaštitni znak" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "znak štikliranja" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "podebljani znak štikliranja" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "iks metak" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "izložilac 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "izložilac 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "izložilac 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "izložilac 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "izložilac 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "izložilac 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "izložilac 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "izložilac plus" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "izložilac minus" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "izložilac jednakosti" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "izložilac leve zagrade" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "izložilac desne zagrade" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "izložilac en" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "indeks 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "indeks 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "indeks 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "indeks 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "indeks 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "indeks 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "indeks 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "indeks 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "indeks 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "indeks 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "indeks plus" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "indeks minus" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "indeks jednakosti" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "indeks leve zagrade" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "indeks desne zagrade" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "crni kvadratić" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "crni romb" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "zamensko slovo objekta" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Postavi pokazivač na tekuću stavku." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Obavlja levi klik na trenutnu stavku ravnog pregleda." - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Obavlja desni klik na trenutnu stavku ravnog pregleda." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Izgovara čitav dokument." - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Izgovara čitav prozor koristeći ravan pregled." - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Obavlja osnovnu gde sam ja operacija." - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Obavlja detaljnu gde sam ja operacija." - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Izgovara tekuću liniju ravnog pregleda." - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Izgovara pojedinosti veze." - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Ide na sledeće dugme." - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Izgovara traku stanja." - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Izgovara liniju naslova." - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Otvara prozorče za pretragu." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Traži sledeće pojavljivanje niske." - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Traži prethodno pojavljivanje niske." - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Ulazi i izlazi iz režima ravnog pregleda." - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Premešta ravan pregled na krajnji položaj." - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Premešta ravan pregled na početni položaj." - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Premešta ravan pregled na krajnji položaj." - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Premešta ravan pregled na početak prethodne linije." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Izgovara tekuću liniju ravnog pregleda." - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Sriče tekuću liniju ravnog pregleda." - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Fonetski izgovara tekuću liniju ravnog pregleda." - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Premešta ravan pregled na početak naredne linije." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Premešta ravan pregled na prethodnu stavku ili reč." - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Izgovara stavku ili reč tekućeg ravnog pregleda." - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Sriče stavku ili reč tekućeg ravnog pregleda." - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Fonetski izgovara stavku ili reč tekućeg ravnog pregleda." - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Premešta ravan pregled na sledeću stavku ili reč." - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Premešta ravan pregled na reč iznad trenutne reči." - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Sriče tekući objekat ravnog pregleda." - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Premešta ravan pregled na reč ispod trenutne reči." - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Premešta ravan pregled na prethodni znak." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Izgovara tekući znak ravnog pregleda." - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Fonetski izgovara tekući znak ravnog pregleda." - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Izgovara unikodnu vrednost tekućeg znaka ravnog pregleda." - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Premešta ravan pregled na sledeći znak." - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Premešta ravan pregled na kraj linije." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Premešta ravan pregled na dno levo." - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Umnožava sadržaj pod ravnim pregledom u ostavu." - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Prikačinje sadržaj pod ravnim pregledom u ostavu." - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Premešta ravan pregled na krajnji položaj." - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Vrši prebacivanje u zavisnosti od toga da li treba da čita samo tekuću " -"ćeliju tabele ili ceo red." - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Čita atribute povezane sa trenutnim znakom teksta." - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Proširuje Brajev ekran na levo." - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Proširuje Brajev ekran na desno." - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Vraća se na objekat sa fokusom tastature." - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Uključuje i isključuje skupljeno Brajevo pismo." - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Obrađuje taster rutine kursora." - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Označava početak izbora teksta." - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Označava kraj izbora teksta." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Unosi režim učenja. Pritisnite „Napusti“ da izađete iz režima učenja." - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Smanjuje protok izgovora." - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Povećava protok izgovora." - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Smanjuje vrhunac izgovora." - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Povećava vrhunac izgovora." - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Povećava jačinu tona izgovora." - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Smanjuje jačinu tona izgovora." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Odaberite željeni server govora." - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Odaberite željeni server govora." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Smanjuje protok izgovora." - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Povećava protok izgovora." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Podešavanja vrste glasa" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Uključuje ućutkivanja izgovora." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Podešava nivo pričljivosti izgovora." - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Uključuje režim pregleda mišem." - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Zatvara čitača ekrana" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Prikazuje prozorče podešavanja postavki." - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Prikazuje prozorče podešavanja postavki programa." - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Uključuje izgovor uvlačenja i poravnanja." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Menja stil izgovorenog broja." - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Prebacuje na sledeći izgovor nivoa interpunkcije." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Prebacuje na sledeći nivo odjeka tastera." - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Prebacuje na sledeći profil podešavanja." - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Prebacuje na sledeći izgled velikih slova." - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Prebacuje na sledeći nivo odjeka tastera." - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Prebacuje na nivo ispravljanja grešaka za vreme pokretanja." - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Obeležava gde sam poštujući tekući položaj." - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Ide na prethodno mesto obeleživača." - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Ide na obeleživač." - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Ide na sledeće mesto obeleživača." - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Dodaje obeleživač." - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Sačuvajte obeleživače." - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Uključuje režim pregleda mišem." - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Predstavlja tekuće vreme." - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Predstavlja tekući datum." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Prosleđuje sledeću naredbu tekućem programu." - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Izgovara Brajevim pismom prethodnu poruku pričaonice." - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" -"Vrši prebacivanje u zavisnosti od toga da li najavljujemo kada naši drugari " -"pišu." - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Vrši prebacivanje u zavisnosti da li smo obezbedili istorijate posebne " -"poruke pričaonice." - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Vrši prebacivanje zavisno od toga da li smo za prefiks poruke pričaonice " -"postavili naziv pričaonice." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Poravnaj levo" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Poravnaj desno" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Poravnaj gore" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Poravnaj dole" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Zamrzni" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Gore levo" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Dole levo" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Položaj kursora" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Šest tačaka" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Rutine kursora" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Početak odsecanja" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Red odsecanja" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Prikazuje poslednju poruku obaveštenja." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Prikaži spisak poruka obaveštenja" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Prikazuje prethodnu poruku obaveštenja." - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Prikazuje poslednju poruku obaveštenja." - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Ide na sledeći znak." - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Ide na prethodni znak." - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Ide na sledeću reč." - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Ide na prethodnu reč." - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Ide na sledeću liniju." - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Ide na prethodnu liniju." - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Ide na vrh datoteke." - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Ide na dno datoteke." - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Ide na početak linije." - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Ide na kraj linije." - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Prelazi na sledeći objekat." - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Prelazi na prethodni objekat." - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Dovodi do toga da tekuće prozorče za izbor biva rašireno." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Prebacuje kretanje pokazivača između izvornog i čitačem ekrana." - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Napredujte u podešavanjima ljubaznosti žive oblasti." - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Podesite osnovni nivo ljubaznosti žive oblasti na iskljulčeno." - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Pregled najave žive oblasti." - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Nadgleda žive oblasti." - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Približava i udaljuje prvi plan sa tekućeg položaja miša." - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Postavite red koji će biti korišćen kao dinamičko zaglavlje kolone." - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Čisti dinamička zaglavlja kolone." - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Postavite kolonu koja će biti korišćena kao dinamičko zaglavlje reda." - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Čisti dinamička zaglavlja reda" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Predstavlja sadržaj linije unosa." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Prebacuje tastere strukturne navigacije." - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Ide na prethodni blok citata." - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Ide na sledeći blok citata." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Prikazuje spisak blokova citata." - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Ide na prethodno dugme." - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Ide na sledeće dugme." - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Prikazuje spisak dugmadi." - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Ide na prethodno polje za potvrdu." - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Ide na sledeće polje za potvrdu." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Prikazuje spisak polja za potvrdu." - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Ide na prethodni objekat na koji se može kliknuti." - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Ide na sledeći objekat na koji se može klinuti." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Prikazuje spisak sa objektima na koje se može kliknuti." - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Ide na prethodno prozorče za izbor." - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Ide na sledeće prozorče za izbor." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Ide na početak kontejnera." - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Ide na kraj kontejnera." - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Prikazuje spisak prozorčića za izbor." - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Ide na prethodni unos." - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Ide na sledeći unos." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Prikazuje spisak unosa." - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Ide na prethodno polje formulara." - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Ide na sledeće polje formulara." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Prikazuje spisak polja formulara." - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Ide na prethodno zaglavlje." - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Ide na sledeće zaglavlje." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Prikazuje spisak zaglavlja." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Ide na prethodno zaglavlje na nivou %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Ide na sledeće zaglavlje na nivou %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Prikazuje spisak zaglavlja na %d. nivou." - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Ide na prethodnu tabelu." - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Ide na sledeću tabelu." - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Prikazuje spisak tabela." - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Ide na prethodnu sliku." - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Ide na sledeću siku." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Prikazuje spisak slika." - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Ide na prethodni orjentir." - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Ide na sledeći orjentir." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Prikazuje spisak orjentira." - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Ide na prethodni veliki objekat." - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Ide na sledeći veliki objekat." - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Prikazuje spisak velikih objekata." - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Ide na prethodnu hiper-vezu." - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Ide na sledeću hiper-vezu." - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Prikazuje spisak veza." - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Ide na prethodni spisak." - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Ide na sledeći spisak." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Prikazuje spisak spiskova." - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Ide na prethodnu stavku spiska." - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Ide na sledeću stavku spiska." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Prikazuje spisak stavki spiska." - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Ide na prethodnu živu oblast." - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Ide na sledeću živu oblast." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Ide na poslednju živu oblast koja objavi saopštenje." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Vraća se na objekat sa fokusom tastature." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Vraća se na objekat sa fokusom tastature." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Prebacuje tastere strukturne navigacije." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Ide na prethodni pasus." - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Ide na sledeći pasus." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Prikazuje spisak pasusa." - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Ide na prethodno radio dugme." - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Ide na sledeće radio dugme." - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Prikazuje spisak radio dugmadi." - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Ide na prethodni razdvajač." - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Ide na sledeći razdvajač." - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Ide na prethodnu tabelu." - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Ide na sledeću tabelu." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Prikazuje spisak tabela." - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Ide dole jednu ćeliju." - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Ide na prvu ćeliju u tabeli." - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Ide na poslednju ćeliju u tabeli." - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Ide levo jednu ćeliju." - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Ide desno jednu ćeliju." - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Ide gore jednu ćeliju." - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Uključuje režim pregleda mišem." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Menja između režima čitanja i fokusiranja." - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Uključuje režim lepljivog fokusa." - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Uključuje režim lepljivog razgledanja." - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Ide na prethodnu neposećenu vezu." - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Ide na sledeću neposećenu vezu." - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Prikazuje spisak neposećenih veza." - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Ide na prethodnu posećenu vezu." - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Ide na sledeću posećenu vezu." - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Prikazuje spisak posećenih veza." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "alis plava" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antičko bele" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarin" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azurna" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "bež" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "čorbasta" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "crna" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "blanširano bademasta" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "plava" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "plavo ljubičasta" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "braon" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "svetlo smeđa" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "akademska plava" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "šartreska" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "čokoladna" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "koralna" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "različak plava" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "kukuruzno svilena" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "tamno crvena" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "svetlo zeleno plava" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "tamno plava" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "tamno zeleno plava" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "zlatica tamno žuta" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "tamno siva" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "tamno zelena" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "tamna žutomrka" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "tamna purpurno crvena" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "tamna maslinasto zelena" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "tamna narandžasta" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "tamna orhideja" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "tamno crvena" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "losos tamna" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "tamna morsko zelena" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "tamna škriljkasto plava" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "tamna škriljkasto siva" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "tamna tirkizna" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "tamno ljubičasta" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "tamno roze" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "duboko nebeski plava" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "mutno siva" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "vrdlamski plava" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "cigla" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "cvetna bela" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "šumska zelena" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuksija" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "geinsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "duh bela" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "zlatna" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "zlatičasta" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "siva" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "zelena" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "zeleno žuta" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "medljikasta" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "topla roze" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indijska crvena" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "slonovača" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "žutomrka" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanda" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "rumena lavanda" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "travnjak zelena" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "limun šifonska" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "svetlo plava" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "svetlo koralna" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "svetla svetlo plava" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "svetlo zlatičasto zelena" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "svetlo siva" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "svetlo zelena" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "svetlo roze" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "svetla losos" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "svetla morsko zelena" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "svetla nebeski plava" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "svetlo škriljkasto siva" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "svetlo čelično plava" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "svetla žuta" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limeta" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "zelena limete" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "boja platna" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "purpurno crvena" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "bordo" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "srednje akvamarin" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "srednje plava" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "srednje orhideja" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "srednje ljubičasto" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "srednje morsko zelena" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "srednje škriljkasto pava" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "srednje prolećno zelena" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "srednje tirkizna" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "srednje ljubičasto zelena" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "ponoćno plava" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "svetlo zelena kremasta" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "maglovita roze" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mokasina" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navaho bela" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "mornarska" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "stara čipka" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "maslinasta" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "maslinasto žuđkasto smeđa" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "narandžasta" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "narandžasto crvena" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orhideja" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "bledo zlatičasta" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "bledo zelena" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "bledo tirkizna" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "bledo ljubičasto crvena" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaja" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "list breskve" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "roze" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "šljiva" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "praškasto plava" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "ljubičasta" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "crvena" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "ružičasto braonkasta" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "kraljevsko plava" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "braon konjskog sedla" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "losos" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "peskivita braon" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "morska zelena" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "morska školjka" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sijena" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "srebrna" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "nebesko plava" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "škriljkasto plava" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "škriljkasto siva" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "snežna" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "prolećno zelena" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "čelično plava" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "žutomrka" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "grogotovac" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "čkalj" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "paradajz" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "tirkizna" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "ljubičasta" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "boja žita" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "bela" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "dimno bela" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "žuta" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "žuto zelena" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktiviraj" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" -"Omogući automatski režim usredsređivanja prilikom kretanja kroz strukturu" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatski režim usredsređivanja prilikom kretanja znaka za umetanje" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatski režim usredsređivanja prilikom kretanja znaka za umetanje" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Tačka _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Tačka _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Tačke 7 _i 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Otkaži" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Idi na" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "U _redu" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Ništa" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "pisanje" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Najavi kada _drugari počnu da pišu" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Obezbedi istorijate posebne _poruke pričaonice" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Izgovori poruke" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Sa svih _kanala" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Sa svih kanala kada je _bilo koji %s prozor aktivan" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Samo sa kanala kome je _aktivan prozor" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Izgovori naziv pričaonice" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Omogući režim prostiranja sadržaja" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dvostruki klik" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trostruki klik" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Osnovni sintetizator" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Stvarna niska" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Niska zamene" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Uključi odjek _znakom" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Uključi _diakritičke tastere bez razmaka" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Tren_utno mesto" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Najmanja dužina odgovarajućeg teksta:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Opcije pretrage" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Izgovaraj _samo izmenjene linije tokom pretrage" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Izgovaraj rezultate tokom _pretrage" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "zapeta" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Sveze tastera" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Osnovno" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "režim upisa" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "odeljak" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Prečice Brajevog pisma" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Sačuvajte obeleživače." - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Datum i vreme" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Pregled mišem je uključen." - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "navigacija" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Nepovezana" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Napuštam ravan pregled." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -# bug: colon? -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "glavni sadržaj" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Izmenjeno" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Stoni računar" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Obaveštenje" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Obaveštenje" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Postavke čitača ekrana za „%s“" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Označi na Brajevom pismu" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Prikaži, izuzev ako" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Izgovori" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Sačuvaj profil kao sukob" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Sukob korisničkog profila!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Već postoji profil „%s“.\n" -"Da nastavim ažuriranje postojećeg profila sa ovim novim izmenama?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Učitaj korisnički profil" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Samo što niste izmenili aktivni profil. Ako ste samo\n" -"načinili izmene u vašim postavkama, iste će biti\n" -"odbačene prilikom učitavanja profila.\n" -"\n" -"Da nastavim sa učitavanjem profila odbacujući prethodne izmene?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Sačuvaj profil kao" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Naziv _profila:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Učitaj korisnički profil" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Sve" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Program" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Prozor" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Ništa" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Po_nešto" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "V_ećina" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Red" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Rečenica" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Blok citata" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Dugme" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Naslov" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Polje za potvrdu" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Može se kliknuti" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Prozorče za izbor" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Opis" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Zaglavlje" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "umetanje" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Slika" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Natpis" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Orjentir" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivo" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Veza" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Spisak" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Stavka spiska" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekat" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Pasus" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radio dugme" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Uloga" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Izabrana stavka" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Stanje" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Tekst" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "Putanja" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Vrednost" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blokovi citata" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Dugmad" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Polja za potvrdu" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Objekti na koje se može kliknuti" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Prozorčići za izbor" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Unosi" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Polja formulara" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Zaglavlja" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "umetanje" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Slike" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Zaglavlje na %d. nivou" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Orjentiri" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Veliki objekti" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Veze" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Spiskovi" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Stavke spiska" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Pasusi" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radio dugmad" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabele" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Neposećene veze" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Posećene veze" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Kretanje stranicom" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Samostalno počni da izgovaraš stranicu kada je prvi put _učitana" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Predstavi sažetak stranice kada je prvi put učitana" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Podeli govor na g_rupe između pauza" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s osnovni glas" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Osnovno" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hiperveza" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Velika slova" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Dispečer govora" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Provera pravopisa" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Pravopisna gr_eška" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Pravopisni _savet" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Prikaži _smisao greške" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Izgovaraj koordinate ćelija tablice" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Najavi _zaglavlje polja" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Kretanje tabelom" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Preskoči _prazne ćelije" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Izgovori _ćeliju" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Izgovaraj koordinate _ćelija" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Izgovori raspon _višestruke ćelije" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Naziv osobine" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Upravlja kretanjem pokazivača" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Uključi _strukturno kretanje" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Ukrat_ko" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Obaveštenje" -msgstr[1] "Obaveštenje" -msgstr[2] "Obaveštenje" -msgstr[3] "Obaveštenje" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Pomak" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Kontrol" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "levi pomak" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "levi alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "levi kontrol" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "desni pomak" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "desni alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "desni kontrol" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "levi meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "desni meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "broj zaključan" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "zaključavanje slova" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "zaključavanje slova" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "zaključavanje pomeranja" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "stranica gore" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "stranica dole" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "levi tabulator" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "brisanje" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "unesi" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "unesi" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "gore" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "dole" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "levo" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "desno" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "levi super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "desni super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "izbor" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "pomoć" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "više" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "prebacivač režima" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "napusti" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "umetni" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "obriši" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "početna" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "kraj" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "početak" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "dugosilazno" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "prsten" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "crta za precrtavanje" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Umetni" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Zaključavanje_slova" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_D" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ktrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Pomak" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "podebljano %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "iskošeno %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "podebljano iskošeno %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "skriptno %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "podebljano skriptno %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "frakturno %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "dvopotezno %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "podebljano frakturno %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "bezserifno %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "bezserifno podebljano %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "bezserifno iskošeno %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "bezserifno podebljano iskošeno %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "jednoprostorno %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s bez tačke" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "strelica na levo" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "strelica na gore" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "strelica na desno" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "strelica na dole" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "strelica levo-desno" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "strelica gore-dole" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "strelica severo-zapad" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "strelica severo-istok" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "strelica jugo-istok" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "strelica na levo sa crticom" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "strelica na gore sa crticom" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "strelica na desno sa crticom" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "strelica na dole sa crticom" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dvostruka strelica na levo" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dvostruka strelica na gore" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dvostruka strelica na desno" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dvostruka strelica na dole" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dvostruka strelica na levo i desno" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dvostruka strelica na dole i gore" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dvostruka strelica na severo-zapad" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dvostruka strelica na severo-istok" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dvostruka strelica na jugo-istok" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dvostruka strelica na jugo-zapad" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "desna ukazujuća strelica" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "desni ukazujući vrh strelice" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "manje" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "veće" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "dugosilazno" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "haček" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "brevom" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "tačka" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dvostruka uspravna linija" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "tri tačke" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "za svako" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "komplement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "parcijalni diferencijal" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "postoji" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "ne postoji" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "prazan skup" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "delta" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "pripada" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "ne pripada" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "mali element" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "sadrži kao član" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "ne sadrži kao član" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "malo sadrži kao član" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "kraj dokaza" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "proizvod" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koproizvod" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "suma" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "plus-minus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "plus sa tačkom" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "razlomačka kosa crta" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "minus skupa" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "zvezdica" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "kružić" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "metak" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "kvadratni koren" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "treći koren" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "četvrti koren" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proporcionalno sa" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "beskonačno" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "desni ugao" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "ugao" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "izmereni ugao" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sferni ugao" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "deli" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "ne deli" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paralelno sa" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "nije paralelno sa" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logičko i" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logičko ili" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "presek" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "unija" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dvostruki integral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "trostruki integral" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "granični integral" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "integral površine" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "integral zapremine" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "kružni integral na desno" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "granični kružni integral na desno" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "granični kružni integral na levo" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "zbog toga" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "zato što" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "odnos" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proporcija" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "minus sa tačkom" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "višak" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrijska proporcija" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetik" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "obrnuta tilda" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "obrnuto lenjo s" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusni talas" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "upleteni proizvod" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "nije tilda" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minus tilda" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asimptotski jednako" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "nije asimptotski jednako" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "približno jednako" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "približno ali zapravo nije jednako" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ni približno ni zapravo jednako" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "skoro jednako" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "nije skoro jednako" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "skoro jednako ili jednako" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "trostruka tilda" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "potpuno jednako" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekvivalent" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrijski ekvivalent" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "razlika između" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "približava se granici" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrijski jednako sa" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "približno jednako ili slika" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "slika ili približno jednako" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "dvotačka jednako" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "jednako dvotačka" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "kružić u jednakosti" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "kružić na jednakosti" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "odgovara" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "procenjuje se" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "ugaonojednako" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "jednako sa zvezdicom" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta jednako" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "jednako sa po definiciji" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "izmereno sa" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "upitna jednakost" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "nije jednako sa" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identično sa" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "nije identično sa" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "izričiti ekvivalent" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "manje ili jednako sa" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "veće ili jednako sa" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "manje preko jednakosti" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "veće preko jednakosti" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "manje ali nije jednako sa" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "veće ali nije jednako sa" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "mnogo manje od" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "mnogo veće od" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "između" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "nije ekvivalent sa" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "nije manje od" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "nije veće od" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ni manje od ni jednako sa" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ni veće od ni jednako sa" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "manje od ili ekvivalent sa" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "veće od ili ekvivalent sa" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ni manje od ni ekvivalent sa" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ni veće od ni ekvivalent sa" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "manje od ili veće od" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "veće od ili manje od" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ni manje od ni veće od" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ni veće od ni manje od" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "prethodi" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "sledi" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "prethodi ili jednako sa" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "sledi ili jednako sa" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "prethodi ili ekvivalent sa" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "sledi ili ekvivalent sa" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "ne prethodi" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ne sledi" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "podskup" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "superskup" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "nije podskup" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "nije superskup" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "podskup ili jednako" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "superskup ili jednako" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ni podskup ni jednako" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ni superskup ni jednako" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "podskup sa nejednakošću" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "superskup sa nejednakošću" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multiskup" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "množenje multiskupa" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "unija multiskupa" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "kvadratna slika" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadratni original" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "kvadratni preslik ili jednako" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "kvadratni original ili jednako" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "kvadratni vrh" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadratno dno" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "zaokruženi plus" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "zaokruženi minus" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "zaokruženo puta" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "zaokružena kosa crta deljenja" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "zaokružena tačka" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "zaokruženi kružić" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "zaokružena zvezdica" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "zaokružena jednakost" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "zaokružena crtica" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "ukvadraćeni plus" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "ukvadraćeni minus" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "ukvadraćeno puta" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "ukvadraćena tačka" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "desni ekserčić" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "levi ekserčić" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "ekserčić na dole" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "ekserčić na gore" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "utvrđivanje" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modeli" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "tačno" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "prisiljava" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "povratni stil desne trostruke uspravne trake" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "povratni stil desne dvostruke uspravne trake" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "ne dokazuje" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "nije tačno" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "ne prisiljava" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "povratni stil negirane desne dvostruke uspravne trake" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "prethodi pod odnosom" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "sledi pod odnosom" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normalna podgrupa" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "sadrži normalnu podgrupu" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normalna podgrupa ili jednako" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "sadrži normalnu podgrupu ili jednako" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "slika simbola" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "multimap" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "ermitska konjugovana matrica" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "umetanje" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "iksor" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "nand" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "nor" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "desni ugao sa lukom" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "desni trougao" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "romb" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "tačka" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "zvezdica" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "podeljeno puta" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "združivanje" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "levi normalni poludirektni proizvod činioca" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "desni normalni poludirektni proizvod činioca" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "levi poludirektni proizvod" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "desni poludirektni proizvod" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "obrnuta tilda jednakosti" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "uvijeno logičko ili" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "uvijeno logičko i" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dvostruki podskup" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dvostruki superskup" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dvostruki presek" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dvostruka unija" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "račva" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "jednako i paralelno sa" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "manje sa tačkom" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "veće sa tačkom" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "vrlo mnogo manje od" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "vrlo mnogo veće od" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "manje od jednako sa ili veće od" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "veće od jednako sa ili manje od" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "jednako sa ili manje od" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "jednako sa ili veće od" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "jednako sa ili prethodi" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "jednako sa ili sledi" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "ne prethodi ili jednako" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ne sledi ili jednako" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "nije kvadratni preslik ili jednako" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "nije kvadratni original ili jednako" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "kvadratni preslik ili nije jednako" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "kvadratni original ili nije jednako" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "manje ali nije ekvivalent" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "veće ali nije ekvivalent" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "prethodi ali nije ekvivalent" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "sledi ali nije ekvivalent" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "nije normalna podgrupa" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "ne sadrži normalnu podgrupu" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "nije normalna podgrupa ili jednako" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "ne sadrži normalnu podgrupu ili jednako" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "uspravna trotačka" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "vodoravna trotačka po sredini" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "dijagonalna trotačka od dole na desno" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "dijagonalna trotačka od gore na desno" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "element sa dugim vodoravnim precrtom" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "element sa ograničenim vodoravnim precrtom" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "mali element sa ograničenim vodoravnim precrtom" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "element sa tačkom iznad" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "element sa crticom iznad" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "mali element sa crticom iznad" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "element sa crticom ispod" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "element sa dva vodoravna precrta" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "sadrži sa dugim vodoravnim precrtom" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "sadrži sa ograničenim vodoravnim precrtom" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "malo sadrži sa ograničenim vodoravnim precrtom" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "sadrži sa crticom iznad" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "malo sadrži sa crticom iznad" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "član zed obeležavanja" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "levo upoljavanje" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "desno upoljavanje" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "levo udoljavanje" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "desno udoljavanje" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "gornja vitičasta" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "donja vitičasta" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "leva vitičasta zagrada" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "desna vitičasta zagrada" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "zaokružena tačka" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "unija sa tačkom" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "unija sa plusom" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "kvadratni presek" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "kvadratna unija" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "crni kvadratić" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "beli kvadratić" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "crni romb" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "beli kružić" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "crni kružić" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "beli metak" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "crni srednje mali kvadratić" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s sa podvlakom" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s sa kosom crtom" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s sa uspravnom linijom" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "program" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "prazno" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "podebljano" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "obeleživač je unešen" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "obeleživač je sačuvan" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "obeleživač ne može biti sačuvan" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Nisam pronašao orjentir." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Nisam pronašao orjentir." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Zaobilazi režim uključenog." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Ne mogu da dobavim prikaz kalkulatora" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikonica" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Izgled velikih slova je postavljen na ikonicu." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ništa" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Izgled velikih slova je postavljen na ništa." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "pisanje" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Izgled velikih slova je postavljen na pisanje." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Program kontroliše umetak." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Program kontroliše umetak." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Ćelija %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "izabrano" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "poništen je izbor" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Sprečava korišćenje opcije" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Prisiljava korišćenje opcije" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPCIJA" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Neobavezni argumenti" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Način korišćenja: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Sledeće nije ispravno: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Štampa poznate pokrenute programe" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Učitava profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profil ne može biti učitan: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Ne mogu da pokrenem čitača ekrana zato što ne može da se poveže sa radnom " -"površi." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Ne mogu da pokrenem upravnika podešavanja. Izlazim." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Već je pokrenut jedan proces čitača ekrana za ovu sesiju.\n" -"Pokrenite naredbu „cthulhu --replace“ da zamenite taj proces novim." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAZIV" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Koristi alternativni direktorijum za korisničke postavke" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Štampa poznate pokrenute programe" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Menja trenutno pokrenuti primerak ovog čitača ekrana" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Prikaži ovu pomoćnu poruku i izađi" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Šalje izlaz ispravljanja grešaka u „debug-YYYY-MM-DD-HH:MM:SS.out“" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Šalje izlaz ispravljanja grešaka u određenu datoteku" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "DATOTEKA" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Podešava postavke korisnika (tekstualna verzija)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Podešava postavke korisnika (izdanje grafičkog sučelja)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Prijavite greške na „https://groups.io/g/stormux“." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Isecite izbor u ostavu." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "iseci" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Izbor je umnožen u ostavu." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "umnožen" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Sadržaj je ubačen iz ostave." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "ubačen" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Neće najavljivati kada drugari počnu da pišu." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "najaviće kada drugari počnu da pišu." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Poruka iz pričaonice %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Novi jezičak ćaskanja %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Neće izgovoriti naziv pričaonice." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "izgovoriće naziv pričaonice." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Neće obezbediti istorijate posebne poruke pričaonice." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Obezbediće istorijate posebne poruke pričaonice." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "početak razlomka" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "kraj razlomka" - -#: src/cthulhu/messages.py:452 -#, fuzzy -msgctxt "content" -msgid "insertion start" -msgstr "početak razlomka" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "kraj razlomka" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "svetlo zelena" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "Pravopisni _savet" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Kraj kontejnera." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Nije u kontejneru." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "nije izabrano" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Osnovno dugme je %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Osnovno dugme je %s" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Osnovno dugme je %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " indeks %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " izložilac %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Nije na tabeli." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "izabran je čitav dokument" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "izabran je čitav dokument" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "izabran je dokument od položaja kursora" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "poništen je izbor dokumenta od položaja kursora" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "izabran je dokument na položaj kursora" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "poništen je izbor dokumenta na položaj kursora" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dinamičko zaglavlje kolone podešeno za red %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dinamičko zaglavlje kolone je obrisano." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dinamičko zaglavlje reda podešeno za kolonu %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dinamičko zaglavlje reda je obrisano." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "prazno" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobajta" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabajta" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Nisam pronašao nijednu datoteku." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Sadržaj je prikačen u ostavu." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Sadržaj je umnožen u ostavu." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Ne koristim ravan pregled." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Ulazim u ravan pregled." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Napuštam ravan pregled." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Premešta ravan pregled na reč iznad trenutne reči." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "sadrži formulu" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "Otvara prozorče za pretragu." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "spisak stranica" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "veza mapirane slike" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Taster koji ste uneli je već povezan sa „%s“" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Taster je uhvaćen: %s. Pritisnite „enter“ da potvrdite." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Novi taster je: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Prečica tastature je obrisana. Pritisnite „enter“ da potvrdite." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Prečica tastature je uklonjena." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "unesite novi taster" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "taster" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Odjek tastera je podešen na taster." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ništa" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Odjek tastera je podešen na ništa." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "taster i reč" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Odjek tastera je podešen na taster i reč." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "rečenica" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Odjek tastera je podešen na rečenicu." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "reč" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Odjek tastera je podešen na reč." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "reč i rečenica" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Odjek tastera je podešen na reč i rečenicu." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Zatvoreno: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "aktuarski simbol" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "polje" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "kružić" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "dugi znak deljenja" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "radikal" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "zaobljeno polje" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "vodoravni precrt" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "uspravni precrt" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "donji dijagonalni precrt" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "gornji dijagonalni precrt" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "strelica severozapad" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "linija pri dnu" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "linija s leva" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "linija s desna" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "linija pri vrhu" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "fazni ugao" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "arapski simbol faktorijela" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "i" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "početak razlomka" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "razlomak bez crte, početak" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "nad" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "kraj razlomka" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "kvadratni koren" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "treći koren" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "koren" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "početak korena" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "kraj korena" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "indeks" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "izložilac" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "pred-indeks" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "pred-izložilac" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "podizložilac" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "nadizložilac" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "kraj tabele" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "kraj ugnežđene tabele" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "nedostupno" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Isključeno" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Izgovor uvlačenja i poravnanja je isključen." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Uključeno" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Izgovor uvlačenja i poravnanja je uključen." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Režim za učenje. Pritisnite „Napusti“ da izađete." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Ulazim u režim za učenje. Pritisnite bilo koji taster da čujete njegovu " -"funkciju. Da vidite dokumentaciju čitača ekrana, pritisnite F1. Da dobavite " -"spisak podrazumevanih prečica čitača ekrana, pritisnite F2. Da dobavite " -"spisak prečica čitača ekrana za trenutni program, pritisnite F3. Da izađete " -"iz režima za učenje, pritisnite taster „Esc“." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "napuštam blok citata." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "napuštam tabelu." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "napuštam dovod." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "napuštam figuru." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "napuštam formular." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "napuštam vrpcu." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "napuštam komplementarni sadržaj." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "napuštam informacije." - -# bug: colon? -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "napuštam glavni sadržaj." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "napuštam navigaciju." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "napuštam oblast." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "napuštam pretragu." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "napuštam spisak." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "napuštam panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "napuštam tabelu." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "napuštam spisak." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "napuštam sažetak." - -# bug: colon? -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "napuštam zahvalnice." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "napuštam pogovor." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "napuštam dodatak." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "napuštam bibliografiju." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "napuštam poglavlje." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "napuštam znak štampara." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "napuštam zaključak." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "napuštam zaslugu." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "napuštam zasluge." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "napuštam posvetu." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "napuštam beleške na kraju." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "napuštam epigraf." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "napuštam epilog." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "napuštam štamparske greške." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "napuštam primer." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "napuštam predgovor." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "napuštam pojmovnik." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "napuštam indeks." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "napuštam uvod." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "napuštam spisak stranica." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "napuštam deo." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "napuštam uvod." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "napuštam prolog." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "napuštam citat." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "napuštam pitanja i odgovore." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "napuštam oblast." - -# bug: colon? -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "napuštam tabelu sadržaja." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "izabrana je linija od položaja kursora na dole" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "izabrana je linija od položaja kursora na gore" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "poništen je izbor linije od položaja kursora na dole" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "poništen je izbor linije od položaja kursora na gore" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Napuštam režim učenja." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "izabrana je linija na početku prethodnog položaja kursora" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "izabrana je linija na kraju prethodnog položaja kursora" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "veza" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ista stranica" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "isti sajt" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "drugi sajt" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s veza do %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s veza" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "posećena veza %s" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Koristite strelice na gore i na dole za kretanje kroz spisak. Pritisnite " -"„Izađi“ da izađete." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Sve žive oblasti su podešene na isključeno" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "vraćeni su nivoi ljubaznosti živih oblasti" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "nivo učtivosti %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "podešavam živu oblast na samopouzdano" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "podešavam živu oblast na isključenje" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "podešavam živu oblast na ljubazno" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "podešavam živu oblast na nepristojno" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Nadgledanje živih oblasti je isključeno" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Nadgledanje živih oblasti je uključeno" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "nema sačuvanih stvarnih poruka" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Podrška žive oblasti je isključena" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Nisam pronašao" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Ne mogu da pronađem tekuće mesto." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "isklj" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "uklj" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "pogrešno napisano" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Pogrešno napisana reč: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Sadržaj je %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Režim čitanja" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Režim usredsređivanja" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Za uključivanje režima usredsređivanja, pritisnite %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Režim usredsređivanja je sada lepljiv." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Režim razgledanja je lepljiv." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Režim usredsređivanja" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objekat" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Prelazi na sledeći objekat." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Miš iznad objekta nije pronađen." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Pregled mišem je isključen." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Pregled mišem je uključen." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Greška: Ne mogu da napravim spisak objekata." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "%d procenat." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Ide na prethodnu reč." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nivo ugnežđivanja %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Nova stavka je dodata" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Nijedan program nije u prvom planu." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Bez fokusa" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Nijedan program nije u prvom planu." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Nema više blokova citata." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Nema više dugmadi." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Nema više polja za potvrdu." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Nema više velikih objekata." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Nema više objekata na koje se može kliknuti." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Nema više prozorčića za izbor." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Nema više unosa." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Nema više polja formulara." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Nema više zaglavlja." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Nema više zaglavlja na nivou %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Nema više tabela." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Nema više slika." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Nisam pronašao orjentir." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Nema više veza." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Nema više spsiskova." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Nema više stavki na spisku." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Nema više živih oblasti." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Nema više pasusa." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Nema više radio dugmadi." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Nema više razdvajača." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Nema više tabela." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Nema više neposećenih veza." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Nema više posećenih veza." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Nema izabranog teksta." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Nije na vezi." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Obaveštenje" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Dno" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Vrh" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Nema poruka obaveštenja" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "cifre" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Izgovara brojeve kao cifre." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "reči" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Izgovara brojeve kao reči." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "isklj" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "uklj" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Učitavam. Sačekajte malo." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Učitavanje je završeno." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Završeno je učitavanje %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Stranica ima %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "izabrana je strana od položaja kursora" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "izabrana je strana na položaj kursora" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "poništen je izbor strane od položaja kursora" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "poništen je izbor strane na položaj kursora" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "izabran je pasus ispod položaja kursora" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "izabran je pasus iznad položaja kursora" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "poništen je izbor pasusa ispod položaja kursora" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "poništen je izbor pasusa iznad položaja kursora" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Već je otvoren jedan primerak prozorčeta postavki Orke.\n" -"Zatvorite ga pre nego što otvorite novi." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "sličica %(position)d od %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil je postavljen na „%s“." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Nisam pronašao profile." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Linija napredovanja %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Sve" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Nivo interpunkcije je podešen na sve." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Većina" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Nivo interpunkcije je podešen na većinu." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ništa" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Nivo interpunkcije je podešen na ništa." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Ponešto" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Nivo interpunkcije je podešen na ponešto." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Pretražujem." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Pretraga je obavljena." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Podešavanja čitača ekrana su ponovo učitana." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Izabrani tekst je: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Izbor je obrisan." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Izbor je vraćen." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "poništen je izbor" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Govor je isključen." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Govor je uključen." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "brže." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "sporije." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "glasnije." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "tiše." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "glasnije." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "sporije." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Protok:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "Jačina _zvuka:" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Dispečer govora" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Dispečer govora" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Nema dostupnih servera." - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Nema dostupnih glasova." - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Govor je uključen." - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Govor se neće koristiti." - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Nivo pričljivosti: nizak" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Nivo pričljivosti: visok" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " tačka tačka tačka" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "Zaobilazi režim uključenog." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Izgovor nije dostupan." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Nisam pronašao" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "niska nije pronađena" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "niska nije pronađena" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Tasteri strukturnog kretanja su isključeni." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Tasteri strukturnog kretanja su uključeni." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Nije pronađeno" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Red %(row)d, kolona %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Kraj tabele" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Izgovori ćeliju" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Izgovori red" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Nejedinstvena" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Nije na tabeli." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Kolone su ponovo poređane" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Redovi su ponovo poređani" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "kolona %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolona br. %(index)d od %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Dno kolone." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Vrh kolone." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "poništen je izbor" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "poništen je izbor" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "red %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "red br. %(index)d od %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Početak reda." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Kraj reda." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Red je obrisan." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Poslednji red je obrisan." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Red je ubačen." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Red je ubačen na kraj tabele." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "Red je obrisan." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "poništen je izbor" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "izabrano" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "poništen je izbor" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%1 sati, %2 minuta i %3 sekunde." - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%d i %d." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unikod %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "poništi" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "vrati" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "razmak" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Prelamam na dno." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Prelamam na vrh." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 stavki" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Ćelija obuhvata %d red" -msgstr[1] "Ćelija obuhvata %d reda" -msgstr[2] "Ćelija obuhvata %d redova" -msgstr[3] "Ćelija obuhvata %d red" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d kolona" -msgstr[1] " %d kolone" -msgstr[2] " %d kolona" -msgstr[3] " %d kolona" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Ćelija obuhvata %d kolonu" -msgstr[1] "Ćelija obuhvata %d kolone" -msgstr[2] "Ćelija obuhvata %d kolona" -msgstr[3] "Ćelija obuhvata %d kolonu" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d znak je predug" -msgstr[1] "%d znaka su preduga" -msgstr[2] "%d znakova je predugo" -msgstr[3] "%d znak je predug" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d prozorče)" -msgstr[1] "(%d prozorčeta)" -msgstr[2] "(%d prozorčeta)" -msgstr[3] "(%d prozorče)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d prozorče nije u prvom planu" -msgstr[1] "%d prozorčeta nisu u prvom planu" -msgstr[2] "%d prozorčeta nije u prvom planu" -msgstr[3] "%d prozorče nije u prvom planu" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bajt" -msgstr[1] "%d bajta" -msgstr[2] "%d bajtova" -msgstr[3] "%d bajt" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Pronašao sam %d datoteku" -msgstr[1] "Pronašao sam %d datoteke" -msgstr[2] "Pronašao sam %d datoteka" -msgstr[3] "Pronašao sam %d datoteku" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formular" -msgstr[1] "%d formulara" -msgstr[2] "%d formulara" -msgstr[3] "%d obrazac" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d zaglavlje" -msgstr[1] "%d zaglavlja" -msgstr[2] "%d zaglavlja" -msgstr[3] "%d zaglavlje" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d stavka" -msgstr[1] "%d stavke" -msgstr[2] "%d stavki" -msgstr[3] "%d stavka" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d orjentir" -msgstr[1] "%d orjentira" -msgstr[2] "%d orjentira" -msgstr[3] "%d orjentir" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "Pronašao sam %d stavku" -msgstr[1] "Pronašao sam %d stavke" -msgstr[2] "Pronašao sam %d stavki" -msgstr[3] "Pronašao sam %d stavku" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Napuštam %d blok citata." -msgstr[1] "Napuštam %d bloka citata." -msgstr[2] "Napuštam %d blokova citata." -msgstr[3] "Napuštam %d blok citata." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Napuštam %d spisak." -msgstr[1] "Napuštam %d spiska." -msgstr[2] "Napuštam %d spiskova." -msgstr[3] "Napuštam %d spisak." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Spisak sa %d stavkom" -msgstr[1] "Spisak sa %d stavke" -msgstr[2] "Spisak sa %d stavki" -msgstr[3] "Spisak sa %d stavkom" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Spisak sa %d stavkom" -msgstr[1] "Spisak sa %d stavke" -msgstr[2] "Spisak sa %d stavki" -msgstr[3] "Spisak sa %d stavkom" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Vrednost" -msgstr[1] "Vrednost" -msgstr[2] "Vrednost" -msgstr[3] "Vrednost" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "matematička tabela sa %d poljem" -msgstr[1] "matematička tabela sa %d polja" -msgstr[2] "matematička tabela sa %d polja" -msgstr[3] "matematička tabela sa %d poljem" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d kolona" -msgstr[1] "%d kolone" -msgstr[2] "%d kolona" -msgstr[3] "%d kolona" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "ugnežđena matematička tabela sa %d redom" -msgstr[1] "ugnežđena matematička tabela sa %d reda" -msgstr[2] "ugnežđena matematička tabela sa %d reda" -msgstr[3] "ugnežđena matematička tabela sa %d redom" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d poruka.\n" -msgstr[1] "%d poruke.\n" -msgstr[2] "%d poruka.\n" -msgstr[3] "%d poruka.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d procenat." -msgstr[1] "%d procenta." -msgstr[2] "%d procenata." -msgstr[3] "%d procenat." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d procenat dokumenta je pročitan" -msgstr[1] "%d procenta dokumenta je pročitano" -msgstr[2] "%d procenata dokumenta je pročitano" -msgstr[3] "%d procenat dokumenta je pročitan" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d piksel" -msgstr[1] "%d piksela" -msgstr[2] "%d piksela" -msgstr[3] "%d piksel" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d znak %(repeatChar)s" -msgstr[1] "%(count)d znaka %(repeatChar)s" -msgstr[2] "%(count)d znakova %(repeatChar)s" -msgstr[3] "Jedan znak %(repeatChar)s" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "Izabrana je %(index)d stavka od %(total)d" -msgstr[1] "Izabrane su %(index)d stavke od %(total)d" -msgstr[2] "Izabrano je %(index)d stavki od %(total)d" -msgstr[3] "Izabrana je jedna stavka od %(total)d" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Pronašao sam %d osnovnu prečicu čitača ekrana." -msgstr[1] "Pronašao sam %d osnovne prečice čitača ekrana." -msgstr[2] "Pronašao sam %d osnovnih prečica čitača ekrana." -msgstr[3] "Pronašao sam %d osnovnu prečicu čitača ekrana." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Pronašao sam %(count)d prečicu čitača ekrana za %(application)s." -msgstr[1] "Pronašao sam %(count)d prečice čitača ekrana za %(application)s." -msgstr[2] "Pronašao sam %(count)d prečica čitača ekrana za %(application)s." -msgstr[3] "Pronašao sam jednu prečicu čitača ekrana za %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d razmak" -msgstr[1] "%d razmaka" -msgstr[2] "%d razmaka" -msgstr[3] "%d razmak" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tabulator" -msgstr[1] "%d tabulatora" -msgstr[2] "%d tabulatora" -msgstr[3] "%d tabulator" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabela" -msgstr[1] "%d tabele" -msgstr[2] "%d tabela" -msgstr[3] "%d tabela" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabela sadržaja" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabela ima %d red" -msgstr[1] "tabela ima %d reda" -msgstr[2] "tabela ima %d redova" -msgstr[3] "tabela ima %d red" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabela ima %d red" -msgstr[1] "tabela ima %d reda" -msgstr[2] "tabela ima %d redova" -msgstr[3] "tabela ima %d red" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabela ima %d red" -msgstr[1] "tabela ima %d reda" -msgstr[2] "tabela ima %d redova" -msgstr[3] "tabela ima %d red" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d neposećena veza" -msgstr[1] "%d neposećene veze" -msgstr[2] "%d neposećenih veza" -msgstr[3] "%d neposećena veza" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d posećena veza" -msgstr[1] "%d posećene veze" -msgstr[2] "%d posećenih veza" -msgstr[3] "%d posećena veza" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "prekidač" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(index)d od %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d od %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVO %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "nivo stabla %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "NIVO STABLA %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "upitnik" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "izborno prozorče je za uređivanje" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "izmenjiv sadržaj" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "dovod" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figura" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "sažetak" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "zasluge" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "pogovor" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "dodatak" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "bibliografski unos" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografija" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "poglavlje" - -# bug: colon? -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "znak štampara" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "zaključak" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "naslovnica" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "zasluga" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "zasluge" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "posveta" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "beleška na kraju" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "beleške na kraju" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "štamparske greške" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "primer" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "predgovor" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "rečnik" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "indeks" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "uvod" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "prelom stranice" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "spisak stranica" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "deo" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "uvod" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "citat" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "pitanja i odgovori" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "podnaslov" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "tabela sadržaja" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "z%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s %(level)d. nivo" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "vodoravna traka premicanja" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "uspravna traka premicanja" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "vodoravni klizač" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "uspravni klizač" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "vodoravni razdelnik" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "uspravni razdelnik" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "prebacivač" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Panel ikonica" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "vrpca" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "komplementarni sadržaj" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "informacije" - -# bug: colon? -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "glavni sadržaj" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigacija" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "oblast" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "pretraga" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "posećena veza" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "dugme izbornika" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "može se kliknuti" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "skupljeno" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "rašireno" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "ima opširan opis" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "vodoravno" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "uspravno" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "označeno" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "nije označeno" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "uklj" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "isklj" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "delimično označeno" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "pritisnuto" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "nije pritisnuto" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "nije izabrano" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "izabrano" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "nije izabrano" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "nije izabrana" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "posećena" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "neposećena" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "zasenčeno" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "samo čitanje" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "samočtnj" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "obavezno" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "više-izborno" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "neispravan unos" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "neispravno" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "neispravno pisanje" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "pravopis" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "neispravna gramatika" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "gramatika" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Pronađi" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Prozorče pretrage za čitač ekrana" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Zatvori" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Pronađi" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Potraži:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Potraži:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Vrha prozora" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Vrha prozora" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Počni sa:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "Prelamaj _okolo" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Traži _unazad" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Smer pretraživanja:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Uporedi veličinu slova" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Uporedi samo _cele reči" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Opcije pretrage" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Osnovno" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Velika slova" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiperveza" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Program" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Prozor" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Čitač ekrana Orka" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "Po_moć" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Primeni" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Prenosni računar" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Raspored tastature" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktivni _profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Profil pokretanja:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Učitaj" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Sačuvaj _kao" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profili" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Prikaži oblačiće objašnjenja" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Izgovori predmete pod _mišem" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Miš" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Oblik _vremena:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Oblik _datuma:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Datum i vreme" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Izgovori _ažuriranja" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Brajeva ažuriranja" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Učestanost (sek):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Program" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Oglasi ažuriranja" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Osvežavanja linije napredovanja" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Uključi _premotavanje unazad i brzo unapred za izgovor svega" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Uključi _strukturno kretanje u izgovoru svega" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Izgovori sve _prema:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Najavi _blokove citata u izgovoru svega" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Najavi _spisak u izgovoru svega" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Najavi _tabele u izgovoru svega" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Najavi _panele u izgovoru svega" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Najavi _formulare u izgovoru svega" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Najavi _orjentire u izgovoru svega" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Izgovori sve" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Opšte" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Jačina _zvuka:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Najviša _tačka:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Protok:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Osoba:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "jezik" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Sintetizator _govora:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_Sistem izgovora:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Vrste _glasa:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Izgled velikih slova:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Podešavanja vrste glasa" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Izgovori niske sa više slova kao _reči" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Izgovori _brojeve kao cifre" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Opšta podešavanja glasa" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Govor" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Uključi _izgovor" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Op_širno" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Opširnost" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Sve" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Nivo interpunkcije" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Govori samo prikazan tekst" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Izgovori prazne redove" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Izgovori _uvlačenje i poravnanje" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Izgovori podsetnik _objekta" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Izgovori položaj _deteta" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Izgovori poruke uputstva" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Poruke _sistema su opširne" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Izgovori _boje kao nazive" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Najavi _blokove citata prilikom navigacije" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Najavi _spiskove prilikom navigacije" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Najavi _tabele prilikom navigacije" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Izgovori ukazivač _loše napisane reči" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Najavi _panele prilikom navigacije" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Najavi _orjentire prilikom navigacije" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Najavi _formulare prilikom navigacije" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Izgovori _opis" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Izgovori čitav red u tabelarnim proračunima" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Izgovori čitav red u tabelama _dokumenta" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Izgovori čitav red u tabelama _grafičkog sučelja" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Govorni kontekst" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Govor" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Uključi Brajevu _podršku" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Skraćeni nazivi uloge" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Isključi simbol _kraja reda" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Tabela _skraćivanja:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Uključi skraćeno Brajevo pismo" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Omogući pre_lamanje reči" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Podešavanja ekrana" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Ništa" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Ukazivač izbora" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Ukazivač hiperveze" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Uključi _poruke bljeska" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Trajanje poruke (sek.):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Poruke su _trajne" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Poruke su _opširne" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Postavke bljeskave poruke" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Brajevo pismo" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Uključi _odjek tastera" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Uključi tastere _slova" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Uključi tastere _brojeva" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Uključi tastere _interpunkcije" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Uključi _razmak" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Uključi tastere _izmenjivača" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Uključi tastere _funkcije" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Uključi tastere _radnje" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Uključi tastere _kretanja" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Uključi odjek _rečju" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Uključi odjek _rečenicom" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Odjek tastera" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Taster(i) _izmenjivača čitača ekrana:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Sveze tastera" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Rečnik izgovora" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Novi unos" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Obriši" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Izgovor" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Izgovori _sve" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Ne _izgovaraj ništa" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Ponovo postavi" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Atributi teksta" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Premesti na d_no" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Premesti za jedan _dole" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Premesti za jedan _gore" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Premesti na v_rh" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Podesite izabrane atribute" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Ukazivač Brajevog pisma" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Atributi teksta" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "dole" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "jezik" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "jen" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Sadržaj je umnožen u ostavu." - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : avala, b : beograd, v : valjevo, g : golija, d : drina, đ : đakovica, " -"e : evropa, ž : žabljak, z : zemun, i : igalo, j : jadran, k : kosovo, l : " -"lovćen, lj : ljubovija, m : morava, n : niš, nj : njegoš, o : obilić, p : " -"pirot, r : ruma, s : sava, t : timok, ć : ćuprija, u : užice, f : futog, h : " -"heroj, c : cetinje, č : čačak, dž : džep, š : šabac" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "boja pozadine" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "puna visina pozadine" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "istačkavanje pozadine" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "usmerenje" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "izmenjiv" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "naziv familije" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "boja prvog plana" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "istačkavanje prvog plana" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "efekat fonta" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "uvlačenje" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "greška" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "nevidljiv" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "poravnavanje" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "jezik" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "leva margina" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "visina linije" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "stil pasusa" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "tačaka iznad linija" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "tačaka ispod linija" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "tačaka unutar preloma" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "desna margina" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "izdignuće" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "razmera" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "veličina" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "razvlačenje" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "precrtano" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "ukras teksta" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "usmerenje teksta" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "senka teksta" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "podvlaka" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "varijanta" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "uspravno poravnanje" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "težina" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "režim preloma" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "režim upisa" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "tačno" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "netačno" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ništa" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "gravirano" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "ispupčeno" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "okvirno" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "nadvučeno" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "linija preko" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "treptav" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "crno" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "jednostruko" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dvostruko" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "dole" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "znak" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "reč" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "znak reči" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "lnd" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "dnl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "levo" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "desno" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "na sredinu" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "bez poravnanja" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "popunjeno" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "vrlo zbijen" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "veoma zbijen" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "zbijen" - -# bug: colon? -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "polu zbijen" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "obično" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "polu raširen" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "raširen" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "veoma raširen" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "vrlo raširen" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "mala slova" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "kosa" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "iskošena" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Osnovno" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Telo teksta" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Zaglavlje" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "osnovni pravac" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "pod" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "nad" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "vrh" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "tekst na vrh" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "sredina" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "dno" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "tekst na dno" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "nasleđen" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "ld-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "dl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-dl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-ld" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-dl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-ld" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "ld" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "dl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "puna" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "pravopis" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Pritisnite razmak da izmenite." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Pritisnite razmak da raširite, i koristite gore i dole da izaberete stavku." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Pritisnite alt+f6 da postavite proistekli prozor u prvi plan." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Da prelazite na stavke, koristite ili tastere strelica ili kucajte pretragu." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Da stignete do izbornika sistema pritisnite taster alt+f1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Koristite gore i dole da izaberete stavku." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Da skupite, pritisnite šift plus levo." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Da raširite, pritisnite šift plus desno." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Da aktivirate pritisnite unesi." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Upišite tekst." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Koristite levo i desno da vidite druge jezičke." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Da aktivirate pritisnite razmak." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Koristite strelice na gore ili na dole da izaberete vrednost. Ili ukucajte " -"željenu numeričku vrednost." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Koristite tastere strelica da promenite." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Da se krećete, pritisnite levu ili desnu strelicu. Da se krećete kroz stavke " -"pritisnite strelice gore ili dole." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Da unesete pod izbornik, pritisnite strelicu desno." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Da smanjite pritisnite strelicu levo, da povećate pritisnite strelicu desno. " -"Da postavite na najmanje pritisnite početak, a za najviše pritisnite kraj." diff --git a/po/sv.po b/po/sv.po deleted file mode 100644 index e990d7b..0000000 --- a/po/sv.po +++ /dev/null @@ -1,9245 +0,0 @@ -# Swedish messages for cthulhu. -# Copyright © 2004-2023 Free Software Foundation, Inc. -# Christian Rose , 2004. -# Daniel Nylander , 2006, 2007, 2008, 2009, 2010, 2011, 2012. -# Anders Jonsson , 2015, 2016, 2017, 2018, 2019, 2020, 2022, 2023. -# Luna Jernberg , 2021, 2022. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-08 15:58+0200\n" -"Last-Translator: Anders Jonsson \n" -"Language-Team: Swedish \n" -"Language: sv\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu skärmläsare" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "skärm;läsare;tillgänglighet;tal;punktskrift;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrm" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "pil" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "kal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "ryta" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "rubk" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "kry" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "färgvä" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "kolhuv" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "kbr" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "ikn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "ram" - -# http://osdir.com/ml/cthulhu-list/2014-06/msg00017.html -# A dial is a circular value-setting widget. -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "nrskiv" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "kpa" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "rita" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "filväl" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "utf" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "typsn" - -# FIXME: Ren gissning -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "formulär" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "rubr" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "bld" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "irm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etik" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lagpan" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lispos" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mny" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "menrad" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "menpos" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "altpan" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "sdf" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "lös" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmny" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "frlind" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "kna" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "radmenpos" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpan" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rahuv" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "rulra" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "rulpan" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "avsn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "avgräns" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "skju" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "delapan" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "snur" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statra" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cell" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "mpatb" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "växkn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "verfä" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tips" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "trä" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "tret" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "okä" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "visom" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "fön" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "huv" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "sidf" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "styck" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "prg" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "redra" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "inbä" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Tjeckiska grad 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Spanska grad 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanadensisk franska grad 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Fransk franska grad 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Lettiska grad 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Holländsk nederländska grad 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norska grad 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norska grad 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norska grad 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norska grad 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Polska grad 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portugisiska grad 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Svenska grad 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arabiska grad 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Kymriska grad 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Kymriska grad 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Tyska grad 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Tyska grad 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Tyska grad 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Brittisk engelska grad 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Brittisk engelska grad 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Amerikansk engelska grad 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Amerikansk engelska grad 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanadensisk franska grad 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Fransk franska grad 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Grekiska grad 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hindi grad 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "8-punkts ungerska för dator" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Ungerska grad 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Ungerska grad 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Italienska grad 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belgisk nederländska grad 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "blanksteg" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "ny rad" - -# Uttalas vid tabbkomplettering -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tabb" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "utropstecken" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "citattecken" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nummer" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dollartecken" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "procenttecken" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "och-tecken" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrof" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "vänsterparentes" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "högerparentes" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "stjärna" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "plustecken" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "komma" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "streck" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "punkt" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "snedstreck" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "kolon" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "semikolon" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "mindre än" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "lika med" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "större än" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "frågetecken" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "snabel a" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "vänster hakparentes" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "omvänt snedstreck" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "höger hakparentes" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "utelämningstecken" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "understruken" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grav" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "vänster klammerparentes" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertikal linje" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "höger klammerparentes" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "icke-brytande blanksteg" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "uppochnedvänt utropstecken" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cent-tecken" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "pundtecken" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "valutasymbol" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen-tecken" - -# I brist på annat -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "brutet rör-tecken" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "avsnitt" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "dieresis" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "copyright" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "feminin-ordinal" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "vänsterställt dubbelt vinkelcitattecken" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logiskt inte" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "mjuk interpunkt" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registrerat varumärke" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "makron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "grader" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "plus eller minus" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "upphöjt till 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "upphöjt till 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "akut" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "my" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "paragraftecken" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "mittenpunkt" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilj" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "upphöjt till 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordningstecken" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "högerställt dubbelt vinkelcitattecken" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "en kvarts" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "en halv" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "trekvarts" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "uppochnedvänt frågetecken" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a akut" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAV" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AKUT" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRKUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "Ä" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "Å" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "AE-ligatur" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILJ" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAV" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AKUT" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRKUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E TREMA" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAV" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AKUT" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRKUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I TREMA" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "EDH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAV" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AKUT" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRKUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "Ö" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "gånger" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "GENOMSTRUKET O" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAV" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AKUT" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRKUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U TREMA" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AKUT" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "TÖRN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "dubbel-s" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grav" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a cirkumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "ä" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "å" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ae-ligatur" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilj" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grav" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e akut" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e cirkumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e dieresis" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grav" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i akut" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i cirkumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i trema" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "edh" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grav" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o akut" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o cirkumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "ö" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "delat med" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "genomstruket o" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "törn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u akut" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grav" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u cirkumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u trema" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y akut" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y trema" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y TREMA" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "tankstreck" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "vänsterställt enkelt citattecken" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "högerställt enkelt citattecken" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "enkelt lågt citattecken" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "vänsterställt dubbelt vinkelcitattecken" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "högerställt dubbelt vinkelcitattecken" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dubbelt lågt citattecken" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "kors" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "dubbelkors" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "listpunkt" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "triangulär listpunkt" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "promille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "primtecken" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "dubbelprimtecken" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "trippelprimtecken" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "interpunkt" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "eurotecken" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "varumärke" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "bock" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "tungt kryssmärke" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-formad interpunkt" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "upphöjd 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "upphöjd 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "upphöjd 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "upphöjd 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "upphöjd 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "upphöjd 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "upphöjd 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "upphöjt plustecken" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "upphöjt minustecken" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "upphöjt lika med-tecken" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "upphöjd vänsterparentes" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "upphöjd högerparentes" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "upphöjt n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "nedsänkt 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "nedsänkt 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "nedsänkt 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "nedsänkt 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "nedsänkt 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "nedsänkt 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "nedsänkt 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "nedsänkt 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "nedsänkt 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "nedsänkt 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "nedsänkt plustecken" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "nedsänkt minustecken" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "nedsänkt lika med-tecken" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "nedsänkt vänsterparentes" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "nedsänkt högerparentes" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "svart kvadrat" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "svart diamant" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "objektersättningstecken" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Vägled muspekaren till det aktuella objektet" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Genomför vänsterklick på aktuellt platt granskningsobjekt" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Genomför högerklick på aktuellt platt granskningsobjekt" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Läs upp hela dokument" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Läs upp hela fönstret med platt granskning" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Genomför den grundläggande Var är jag-åtgärden" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Genomför den detaljerade Var är jag-åtgärden" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Läs upp aktuell markering" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Läs upp länkdetaljer" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Presentera standardknappen" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Presentera statusraden" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Presentera namnlisten" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Öppna sökdialogrutan" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Visa åtgärdslista" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Sök efter nästa instans av en sträng" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Sök efter föregående instans av en sträng" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Gå in i och lämna platt granskningsläge" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Växla begränsning av platt granskning till aktuellt objekt" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Flytta platt granskning till hempositionen" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Flytta platt granskning till slutpositionen" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Flytta platt granskning till början av föregående rad" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Läs upp den aktuella platta granskningsraden" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Bokstavera den aktuella platta granskningsraden" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Bokstavera fonetiskt den aktuella platta granskningsraden" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Flytta platt granskning till början av nästa rad" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Flytta platt granskning till det föregående objektet eller ordet" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Läs upp det aktuella platta granskningsobjektet eller ordet" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Bokstavera det aktuella platta granskningsobjektet eller ordet" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Bokstavera fonetiskt det aktuella platta granskningsobjektet eller ordet" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Flytta platt granskning till nästa objekt eller ord" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Flytta platt granskning till ordet ovanför det aktuella ordet" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Läs upp det aktuella platta granskningsobjektet" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Flytta platt granskning till ordet nedanför det aktuella ordet" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Flytta platt granskning till föregående tecken" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Läs upp det aktuella platta granskningstecknet" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Uttala fonetiskt det aktuella platta granskningstecknet" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Läs upp Unicode-värdet för det aktuella platta granskningstecknet" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Flytta platt granskning till nästa tecken" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Flytta platt granskning till slutet på raden" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Flytta platt granskning till nedre vänsterkant" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Kopiera innehållet under platt granskning till urklipp" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Lägg till innehållet under platt granskning till urklipp" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Visa innehåll för platt granskning" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Växla huruvida bara den aktuella tabellcellen eller hela raden ska läsas upp" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Läs attributen associerade med det aktuella texttecknet" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Flytta punktskriftsskärmen åt vänster" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Flytta punktskriftsskärmen åt höger" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Återgå till objektet med tangentbordsfokus" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Aktivera eller inaktivera litterär punktskrift" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Behandla en markörriktningstangent" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Markera början av en textmarkering" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Markera slutet av en textmarkering" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Gå in i inlärningsläge. Tryck Escape för att lämna inlärningsläget" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Sänk uppläsningshastigheten" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Öka uppläsningshastigheten" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Sänk tonarten" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Höj tonarten" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Öka uppläsningsvolymen" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Minska uppläsningsvolymen" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Välj föregående talinställning" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Välj nästa talinställning" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Minska aktuell talinställning" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Öka aktuell talinställning" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Spara talinställningar" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Växla uppläsningen av eller på" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Växla informationsnivå för tal" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Växla viloläge" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Avsluta skärmläsaren" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Visa dialogrutan för inställningar" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Visa konfigurationsdialogen för programinställningar" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Växla uppläsning av textindentering och textjustering" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Ändra stil för upplästa nummer" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Växla till nästa nivå för uppläsning av skiljetecken" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Växla till nästa talsyntes" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Växla till nästa inställningsprofil" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Växla till nästa versaliseringsstil" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Växla till nästa nivå för tangenteko" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Växla felsökningsnivån vid körtid" - -# Relaterat till Where Am I-funktionen -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Bokmärkets Var är jag i förhållande till aktuell position" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Gå till föregående bokmärkesplats" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Gå till bokmärke" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Gå till nästa bokmärkesplats" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Lägg till bokmärke" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Spara bokmärken" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Växla musgranskningsläge" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Presentera aktuell tid" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Presentera aktuellt datum" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Presentera storlek och plats för aktuellt objekt" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Skicka vidare nästa kommando till det aktuella programmet" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Läs upp och skriv punktskrift för ett tidigare chattrumsmeddelande" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Växla huruvida vi annonserar när våra kompisar skriver något" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Växla huruvida vi tillhandahåller historik för chattrumsspecifika meddelanden" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Växla huruvida vi inleder chattrumsmeddelanden med namnet på chattrummet" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Rad vänster" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Rad höger" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Rad uppåt" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Rad nedåt" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Frys" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Övre vänster" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Nedre vänster" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Markörposition" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Sex punkter" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Markörriktning" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Början av markering" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Markera rad" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Presentera senaste aviseringsmeddelandet" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Presentera lista med aviseringsmeddelanden" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Presentera föregående aviseringsmeddelande" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Presentera nästa aviseringsmeddelande" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Gå till nästa tecken" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Gå till föregående tecken" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Gå till nästa ord" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Gå till föregående ord" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Gå till nästa rad" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Gå till föregående rad" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Gå till början av filen" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Gå till slutet av filen" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Gå till början av raden" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Gå till slutet av raden" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Gå till nästa objekt" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Gå till föregående objekt" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Gör att aktuell kombinationsruta expanderas" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Växla mellan programmets egna och skärmläsarens markörnavigering" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Öka snällhetsinställning för levande region" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Ställ in standardsnällhetsnivå för levande regioner till av" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Visa annonseringar om levande regioner igen" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Övervaka levande regioner" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Flytta fokus till och bort från objektet under muspekaren" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Ställ in raden att använda som dynamiska kolumnhuvuden" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Töm de dynamiska kolumnhuvudena" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Ställ in kolumnen att använda som dynamiska radhuvuden" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Töm de dynamiska radhuvudena" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Presentera innehållet på inmatningsraden" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Växla strukturella navigeringstangenter" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Gå till föregående blockcitat" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Gå till nästa blockcitat" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Visa en lista över blockcitat" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Gå till föregående knapp" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Gå till nästa knapp" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Visa en lista över knappar" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Gå till föregående kryssruta" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Gå till nästa kryssruta" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Visa en lista över kryssrutor" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Gå till föregående klickbara" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Gå till nästa klickbara" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Visa en lista över klickbara" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Gå till föregående kombinationsruta" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Gå till nästa kombinationsruta" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Gå till början av behållaren" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Gå till slutet av behållaren" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Visa en lista över kombinationsrutor" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Gå till föregående post" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Gå till nästa post" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Visa en lista över poster" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Gå till föregående formulärfält" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Gå till nästa formulärfält" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Visa en lista över formulärfält" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Gå till föregående rubrik" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Gå till nästa rubrik" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Visa en lista över rubriker" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Gå till föregående rubrik på nivå %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Gå till nästa rubrik på nivå %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Visa en lista över rubriker på nivå %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Gå till föregående intern ram" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Gå till nästa intern ram" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Visa en lista över interna ramar" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Gå till föregående bild" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Gå till nästa bild" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Visa en lista över bilder" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Gå till föregående landmärke" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Gå till nästa landmärke" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Visa en lista över landmärken" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Gå till föregående stora objekt" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Gå till nästa stora objekt" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Visa en lista över stora objekt" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Gå till föregående länk" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Gå till nästa länk" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Visa en lista över länkar" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Gå till föregående lista" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Gå till nästa lista" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Visa en lista över listor" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Gå till föregående listobjekt" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Gå till nästa listobjekt" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Visa en lista över listobjekt" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Gå till föregående levande region" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Gå till nästa levande region" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Gå till senaste levande region som gjorde en annonsering" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Gå till föräldern till objektet med navigeringsfokus." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Gå till det första barnet till objektet med navigeringsfokus." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Gå till nästa syskon till objektet med navigeringsfokus." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Gå till föregående syskon till objektet med navigeringsfokus." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Klicka på objektet med navigeringsfokus." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Växla förenklad objektnavigering." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Gå till föregående stycke" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Gå till nästa stycke" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Visa en lista över stycken" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Gå till föregående radioknapp" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Gå till nästa radioknapp" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Visa en lista över radioknappar" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Gå till föregående avgränsare" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Gå till nästa avgränsare" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Gå till föregående tabell" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Gå till nästa tabell" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Visa en lista över tabeller" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Gå en cell nedåt" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Gå till första cellen i en tabell" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Gå till sista cellen i en tabell" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Gå en cell åt vänster" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Gå en cell åt höger" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Gå en cell uppåt" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Växla layoutläge" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Växla mellan bläddringsläge och fokusläge" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Aktivera klistrigt fokusläge" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Aktivera klistrigt bläddringsläge" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Gå till föregående obesökta länk" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Gå till nästa obesökta länk" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Visa en lista över obesökta länkar" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Gå till föregående besökta länk" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Gå till nästa besökta länk" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Visa en lista över besökta länkar" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "aliceblå" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antikvit" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "akvamarin" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "azurblå" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "beige" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "bisque" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "svart" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "skållad mandel" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "blå" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "blåviolett" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "brun" - -# https://en.wikipedia.org/wiki/Burl -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "trävril" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "kadettblå" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "chartreuse" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "choklad" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "korall" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "kornblå" - -# Del av honblomman hos majs. -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "majssilke" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "karmosinröd" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "cyan" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "mörkblå" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "mörkcyan" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "mörk gullris" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "mörkgrå" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "mörkgrön" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "mörk kaki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "mörk magenta" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "mörk olivgrön" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "mörk orange" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "mörk orkidé" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "mörkröd" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "mörk laxrosa" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "mörk havsgrön" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "mörk skifferblå" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "mörk skiffergrå" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "mörk turkos" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "mörk violett" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "djuprosa" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "djup himmelsblå" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "dunkelgrå" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "dodgerblå" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "eldfast tegelsten" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "blomvit" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "skogsgrön" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuchsia" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "gainsboro" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "spökvit" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "guld" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "gullris" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "grå" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "grön" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "gröngul" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "honungsdagg" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "hett rosa" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "indiskt röd" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "elfenben" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "kaki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavendel" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavendelrodnad" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "gräsmattegrönt" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "citronchiffong" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "ljusblå" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "ljus korall" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "ljuscyan" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "ljust gullrisgul" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "ljusgrå" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "ljusgrön" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "ljusrosa" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "ljus laxrosa" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "ljus havsgrön" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "ljus himmelsblå" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "ljus skiffergrå" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "ljus stålblå" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "ljusgul" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "lime" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limegrön" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "linne" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "magenta" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "vinröd" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "mellanakvamarin" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "mellanblå" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "mellanorkidé" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "mellanlila" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "mellanhavsgrön" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "mellanskifferblå" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "mellanvårgrön" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "mellanturkos" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "mellanviolettröd" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "midnattsblå" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "mintgrädde" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "dimrosa" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "mockasin" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajovit" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "marinblå" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "gammal spets" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "oliv" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "ljus olivbrun" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "orange" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "orangeröd" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orkidé" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "blek gullris" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "blekgrön" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "blek turkos" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "blek violettröd" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papayavisp" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "persikopuff" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "rosa" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "plommon" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "pulverblå" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "lila" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "röd" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "rosenbrun" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "kungsblå" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "sadelbrun" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "laxrosa" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "sandbrun" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "havsgrön" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "snäckskal" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "sienna" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "silver" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "himmelsblå" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "skifferblå" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "skiffergrå" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "snö" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "vårgrön" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "stålblå" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "mellanbrun" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "teal" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "tistel" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "tomat" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turkos" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "violett" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "vete" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "vit" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "vit rök" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "gul" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "gulgrön" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktivera" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Automatiskt fokusläge under strukturell navigering" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Automatiskt fokusläge under markörnavigering" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Automatiskt fokusläge under programmets egen navigering" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Punkt _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Punkt _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Punkt 7 oc_h 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "A_vbryt" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Hoppa till" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Ikon" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Ingen" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Bokstavering" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Annonsera när dina _kompisar skriver något" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Tillhandahåll historik för chattrumsspecifika _meddelanden" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Läs upp meddelanden från" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Alla ka_naler" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Alla kanaler när nå_got %s-fönster är aktivt" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "En kanal endast om dess _fönster är aktivt" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Läs upp chattrummets namn" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Aktivera layoutläge för innehåll" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "dubbelklick" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "trippelklick" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Standardsyntes" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Faktisk sträng" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Ersättningssträng" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Aktivera eko efter te_cken" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Aktivera icke-_blankstegs diakritiska tangenter" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "A_ktuell position" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Minimal längd på matchande text:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Sökalternativ" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Läs _endast upp ändrade rader under sökning" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Läs upp resultat under _sökning" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Kommando" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Tangentbindning" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Standard" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Inlärningsläge" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Åtgärder" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Punktskriftsbindningar" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Bokmärken" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Datum och tid" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Musgranskning" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Objektnavigering" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Objektdetaljer" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Inte bunden" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Platt granskning" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Tal och informationsnivå" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Innehåll för platt granskning" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Ändrad" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Stationär dator" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Aviseringar" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Mottaget" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Aviseringspresentatör" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Cthulhu-inställningar för %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Markera i punktskrift" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Presentera såvida inte" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Läs upp" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Konflikt vid sparande av profil" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Konflikt i användarprofil!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Profilen %s finns redan.\n" -"Fortsätt med att uppdatera den befintliga profilen med dessa nya ändringar?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Läs in användarprofil" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Du är på väg att ändra den aktiva profilen. Om du\n" -"precis har gjort ändringar i dina inställningar så\n" -"kommer de att förkastas när profilen läses in.\n" -"\n" -"Fortsätt med att läsa in profilen och förkasta tidigare ändringar?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Spara profil som" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profilnamn:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Ta bort användarprofil" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Du håller på att ta bort profilen %s. Alla osparade inställningar och " -"inställningar som sparats i denna profil kommer att gå förlorade. Vill du " -"fortsätta med att ta bort denna profil och alla relaterade inställningar?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Alla" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Program" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Fönster" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Inget" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Vi_ssa" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Fl_esta" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Rad" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Mening" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Blockcitat" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Knapp" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Rubrik" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Kryssruta" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Klickbar" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Kombinationsruta" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Beskrivning" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Rubrik" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Intern ram" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Bild" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etikett" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Landmärke" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Nivå" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Länk" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Lista" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Listobjekt" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Objekt" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Stycke" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radioknapp" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Roll" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Markerat objekt" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Tillstånd" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Värde" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blockcitat" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Knappar" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Kryssrutor" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Klickbara" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Kombinationsrutor" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Poster" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Formulärfält" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Rubriker" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Interna ramar" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Bilder" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Rubriker på nivå %d" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Landmärken" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Stora objekt" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Länkar" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listor" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Listobjekt" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Stycken" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radioknappar" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tabeller" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Obesökta länkar" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Besökta länkar" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Sidnavigering" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Börja automatiskt läsa upp en sida när den först _läses in" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Presentera sammanfattning för en sida när den först läses in" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Dela upp tal i de_lar mellan pauser" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Standardröst för %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Standard" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Hyperlänk" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "System" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Versal" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Uppläsningsassistent" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Stavningskontroll" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Bokstavera f_el" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Bokstavera _förslag" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Presentera _sammanhang för fel" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Läs upp koordinater för kalkylbladscell" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Läs alltid upp markerat kalkylbladsintervall" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Meddela cell_huvud" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Tabellnavigering" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Hoppa över _tomma celler" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Läs upp _cell" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Läs upp _cellkoordinater" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Läs upp _flera cellspann" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Attributnamn" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Kontrollera markörnavigering" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Aktivera _strukturell navigering" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Ljud_tema:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Ljudtema" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Kor_t" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d avisering" -msgstr[1] "%d aviseringar" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Skift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "vänster skift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "vänster alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "vänster control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "höger skift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "höger alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "höger control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "vänster meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "höger meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "shift lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "vänster tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backsteg" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "upp" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "ned" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "vänster" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "höger" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "vänster super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "höger super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "meny" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "help" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "lägesväxling" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "cirkumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "genomstruket" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "minus" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Skift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "fet %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "kursiv %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "fet kursiv %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "%s i skrivstil" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "fet %s i skrivstil" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "%s i frakturstil" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "dubbelstreckad %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "fet %s i frakturstil" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "%s utan serifer" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "fet %s utan serifer" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "kursiv %s utan serifer" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "fet kursiv %s utan serifer" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "%s med fast breddsteg" - -# Bokstaven i eller j utan prick -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "%s utan prick" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "vänsterpil" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "uppåtpil" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "högerpil" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "nedåtpil" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "vänster-höger-pil" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "uppåt-nedåt-pil" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "nordvästpil" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "nordostpil" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "sydostpil" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "vänsterpil från streck" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "uppåtpil från streck" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "högerpil från streck" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "nedåtpil från streck" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dubbel vänsterpil" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "dubbel uppåtpil" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dubbel högerpil" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "dubbel nedåtpil" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dubbel vänster-höger-pil" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "dubbel uppåt-nedåt-pil" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "dubbel nordvästpil" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "dubbel nordostpil" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "dubbel sydostpil" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "dubbel sydvästpil" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "högerställd pil" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "högerriktat pilhuvud" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "minus" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "mindre än" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "större än" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "cirkumflex" - -# Hake eller háček på svenska. -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "hake" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "brevis" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "punkt" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "dubbel vertikal linje" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "horisontell ellips" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "för alla" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "komplement" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "partiell differential" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "det existerar" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "det existerar icke" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "tomma mängden" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "inkrement" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "element i" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "inte ett element i" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "litet element i-tecken" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "innehåller som en medlem" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "innehåller inte som en medlem" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "litet innehåller som en medlem-tecken" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "vilket skulle bevisas" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "produkt" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "koprodukt" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "summa" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "minus eller plus" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "punktplus" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "divisionssnedstreck" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "mängdminus" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "asteriskoperator" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "ringoperator" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "listpunktoperator" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "kvadratrot" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "tredjerot" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "fjärderot" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "proportionell mot" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "oändlighet" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "rät vinkel" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "vinkel" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "uppmätt vinkel" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "sfärisk vinkel" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "delar" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "delar inte" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "parallell med" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "inte parallell med" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "logiskt och" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "logiskt eller" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "snitt" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "union" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "dubbelintegral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "trippelintegral" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "konturintegral" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "ytintegral" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "volymintegral" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "medurs integral" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "medurs konturintegral" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "moturs konturintegral" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "alltså" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "därför att" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "förhållande" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proportion" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "punktminus" - -# Osäker -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "överflöd" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrisk proportion" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetisk" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "omvänt tilde" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "omvänt liggande S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinusvåg" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "kransprodukt" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "inte tilde" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "minustilde" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asymptotiskt lika med" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "inte asymptotiskt lika med" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "approximativt lika med" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "approximativt men inte faktiskt lika med" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "varken approximativt eller faktiskt lika med" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "nästan lika med" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "inte nästan lika med" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "nästan lika med eller lika med" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "trippeltilde" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "alla lika med" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometriskt ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "skillnad mellan" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "går mot gränsvärdet" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometriskt lika med" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "approximativt lika med eller bilden av" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "bild av eller approximativt lika med" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "kolon lika med" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "lika med kolon" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ring i lika med-tecken" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ring lika med" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "motsvarar" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "estimerar" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "likvinklig med" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "stjärna lika med" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "delta lika med" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "lika med per definition" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "uppmäts av" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "ifrågasatt lika med" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "inte lika med" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "identiskt med" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "inte identiskt med" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "strikt ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "mindre än eller lika med" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "större än eller lika med" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "mindre än ovanför lika med" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "större än ovanför lika med" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "mindre än men inte lika med" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "större än men inte lika med" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "mycket mindre än" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "mycket större än" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "mellan" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "inte ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "inte mindre än" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "inte större än" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "varken mindre än eller lika med" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "varken större än eller lika med" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "mindre än eller ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "större än eller ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "varken mindre än eller ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "varken större än eller ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "mindre än eller större än" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "större än eller mindre än" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "varken mindre än eller större än" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "varken större än eller mindre än" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "kommer före" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "kommer efter" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "kommer före eller är lika med" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "kommer efter eller är lika med" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "kommer före eller är ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "kommer efter eller är ekvivalent med" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "kommer inte före" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "kommer inte efter" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "delmängd av" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "omfattande mängd av" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "inte en delmängd av" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "inte omfattande mängd av" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "delmängd av eller lika med" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "omfattande mängd av eller lika med" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "varken en delmängd av eller lika med" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "varken omfattande mängd av eller lika med" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "delmängd av med inte lika med" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "omfattande mängd av med inte lika med" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "multimängd" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "multimängdsmultiplikation" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "multimängdsunion" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "kvadratisk bild av" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "kvadratiskt original av" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "kvadratisk bild av eller lika med" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "kvadratiskt original av eller lika med" - -# Alternativt namn SquareIntersection -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "kvadratiskt snitt" - -# Alternativt namn SquareUnion -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "kvadratisk union" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "inringat plustecken" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "inringat minustecken" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "inringat gångertecken" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "inringat divisionssnedstreck" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "inringad punktoperator" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "inringad ringoperator" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "inringad asteriskoperator" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "inringat lika med-tecken" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "inringat streck" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "plustecken i fyrkant" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "minustecken i fyrkant" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "gångertecken i fyrkant" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "punktoperator i fyrkant" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "häftstift åt höger" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "häftstift åt vänster" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "häftstift nedåt" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "häftstift uppåt" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "påstående" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modellerar" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "sant" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "tvingar" - -# Osäker -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "turnstile åt höger med tredubbelt vertikalt streck" - -# Osäker -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "dubbel turnstile åt höger med dubbelt vertikalt streck" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "bevisar inte" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "inte sant" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "tvingar inte" - -# Osäker -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "negerad dubbel turnstile åt höger med dubbelt vertikal streck" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "kommer före under relation" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "kommer efter under relation" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normal undergrupp av" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "innehåller som normal undergrupp" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normal undergrupp av eller lika med" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "innehåller som normal undergrupp av eller lika med" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "original av" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "bild av" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "flervärd avbildning" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermitesk konjugatmatris" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "interkalera" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "exklusivt eller" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "icke-och" - -# nor=Not or i logik -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "icke-eller" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "rät vinkel med båge" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "rätvinklig triangel" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "diamantoperator" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "punktoperator" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "stjärnoperator" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "delat med-tecken på gångertecken" - -# Används för Natural Join i SQL -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "bowtie" - -# Osäker -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "halvdirekt normalfaktorprodukt åt vänster" - -# Osäker -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "halvdirekt normalfaktorprodukt åt höger" - -# Osäker -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "halvdirekt produkt åt vänster" - -# Osäker -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "halvdirekt produkt åt höger" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "omvänt tilde lika med" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "krulligt logiskt eller" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "krulligt logiskt och" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "dubbel delmängd" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "dubbel omfattande mängd av" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "dubbelt snitt" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "dubbel union" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "högaffel" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "lika med och parallell med" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "mindre än med punkt" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "större än med punkt" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "väldigt mycket mindre än" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "väldigt mycket större än" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "mindre än lika med eller större än" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "större än lika med eller mindre än" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "lika med eller mindre än" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "lika med eller större än" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "lika med eller kommer före" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "lika med eller kommer efter" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "kommer varken före eller är lika med" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "kommer varken efter eller är lika med" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "varken kvadratisk bild av eller lika med" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "varken kvadratiskt original av eller lika med" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "kvadratisk bild av eller inte lika med" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "kvadratiskt original av eller inte lika med" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "mindre än men inte ekvivalent med" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "större än men inte ekvivalent med" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "kommer före men är inte ekvivalent med" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "kommer efter men är inte ekvivalent med" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "inte normal undergrupp av" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "innehåller inte som normal undergrupp" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "varken normal undergrupp av eller lika med" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "innehåller varken som normal undergrupp eller lika med" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "vertikal ellips" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "horisontell mittradsellips" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "diagonal uppåt-högerellips" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "diagonal nedåt-högerellips" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "element i-tecken med långt horisontellt streck" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "element i-tecken med vertikalt streck i slutet på horisontellt streck" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"litet element i-tecken med vertikalt streck i slutet på horisontellt streck" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "element i-tecken med punkt ovanpå" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "element i-tecken med streck över" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "litet element i-tecken med streck över" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "element i-tecken med streck under" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "element i-tecken med två horisontella streck" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "innehåller-tecken med långt horisontellt streck" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "innehåller-tecken med vertikalt streck i slutet på horisontellt streck" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"litet innehåller-tecken med vertikalt streck i slutet på horisontellt streck" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "innehåller-tecken med streck över" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "litet innehåller-tecken med streck över" - -# bag = multiset -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "medlemskap i multimängd enligt z-notation" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "vänstertak" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "högertak" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "vänstergolv" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "högergolv" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "takklammerparentes" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "golvklammerparentes" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "vänster vinkelparentes" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "höger vinkelparentes" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "inringad punkt" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "union med punkt" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "union med plus" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "kvadratiskt snitt" - -# Alternativt namn SquareUnion -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "kvadratisk union" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "svart kvadrat" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "vit kvadrat" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "svart diamant" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "vit cirkel" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "svart cirkel" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "vit punkt" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "svart medelstor kvadrat" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s med understreck" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s med snedstreck" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s med vertikal linje" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "program" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "blank" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "fet" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "bokmärke nåddes" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "bokmärken sparade" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "bokmärken kunde inte sparas" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Inga bokmärken hittades." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Bokmärket hittades inte." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Åsidosättningsläge aktiverat." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Kunde inte få tag på miniräknarens fönster" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "ikon" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Versaliseringsstil inställd till ikon." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ingen" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Versaliseringsstil inställd till ingen." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "bokstavering" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Versaliseringsstil inställd till bokstavering." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Programmet kontrollerar markören." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu styr markören." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Cell %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s markerad" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s till %s markerade" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s till %s avmarkerade" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s avmarkerad" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Förhindra användning av flagga" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Tvinga användning av flagga" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "FLAGGA" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Valfria argument" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Användning: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Följande är inte giltiga: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Skriv ut de kända körande programmen" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Läs in profil" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profil kunde inte läsas in: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Kan inte starta Cthulhu eftersom det inte kan ansluta till skrivbordet.Kan " -"inte starta skärmläsaren för att den inte kan ansluta till skrivbordet." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Kunde inte aktivera inställningshanteraren. Avslutar." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"En annan skärmläsarprocess kör redan för denna session.\n" -"Kör ”cthulhu --replace” för att ersätta den processen med en ny." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAMN" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Använd alternativ katalog för användarinställningar" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "KAT" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Version av detta program" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Ersätt en för närvarande körande instans av Cthulhu" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Visa detta hjälpmeddelande och avsluta" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Skicka felsökningsutskrift till debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Skicka felsökningsutskrift till angiven fil" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FIL" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Ställ in användarinställningar (textversion)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Ställ in användarinställningar (användargränssnittsversion)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" -"Rapportera fel till https://groups.io/g/stormux\n" -"Skicka synpunkter på översättningen till tp-sv@listor.tp-sv.se" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Klippte ut markering till urklipp." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "klippte ut" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Kopierade markering till urklipp." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopierade" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Klistrade in innehåll från urklipp." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "klistrade in" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Annonsera inte när dina kompisar skriver något." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "annonsera när dina kompisar skriver något." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Meddelande från chattrummet %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Ny chattflik %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Läs inte upp chattrummets namn." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "läs upp chattrummets namn." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Tillhandahåll inte historik för chattrumsspecifika meddelanden." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Tillhandahåll historik för chattrumsspecifika meddelanden." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "start på borttagning" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "slut på borttagning" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "start på infogning" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "slut på infogning" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "start på markering" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "slut på markering" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "slut på förslag" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Slut på behållare." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Inte i en behållare." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "alla objekt markerade" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Standardknapp är %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Standardknapp är %s. Inaktiverad" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Standardknapp ej hittad" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " nedsänkt %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " upphöjt %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Inte i en dialogruta" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "hela dokumentet markerat" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "hela dokumentet avmarkerat" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "dokument markerat från markörposition" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "dokument avmarkerat från markörposition" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "dokument markerat till markörposition" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "dokument avmarkerat till markörposition" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Dynamiskt kolumnhuvud inställt för rad %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dynamiskt kolumnhuvud tömdes." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Dynamiskt radhuvud inställt för kolumnen %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dynamiskt radhuvud tömdes." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "tom" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobyte" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabyte" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Inga filer hittades." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "La till innehåll till urklipp." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Kopierade innehåll till urklipp." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Använder inte platt granskningsläge." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Går in i platt granskningsläge." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Lämnar platt granskningsläge." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Platt granskning begränsad till aktuellt objekt" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Platt granskning obegränsad" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "har formeln" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "öppnar dialogruta" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "öppnar rutnät" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "öppnar listruta" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "öppnar meny" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "öppnar träd" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "länk i image map" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Angiven tangent är redan bunden till %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tangent fångad: %s. Tryck Enter för att bekräfta." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Den nya tangenten är: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Tangentbindning borttagen. Tryck Enter för att bekräfta." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Tangentbindningen har tagits bort." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "ange ny tangent" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tangent" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Eko inställt till tangent." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ingen" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Eko inställt till inget." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tangent och ord" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Eko inställt till tangent och ord." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "mening" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Eko inställt till mening." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "ord" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Eko inställt till ord." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "ord och mening" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Eko inställt till ord och mening." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Omgiven av: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "en matematisk symbol" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "en låda" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "en cirkel" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "ett långt divisionsstreck" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "en rot" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "en rundad låda" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "en horisontell överstrykning" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "en vertikal överstrykning" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "en diagonalt nedgående överstrykning" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "en diagonalt uppgående överstrykning" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "en nordostpil" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "en linje nedanför" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "en linje till vänster" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "en linje till höger" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "en linje ovanför" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "en fasvektorvinkel" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "en arabisk fakultetssymbol" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "och" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "start på bråk" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "start på bråk utan bråkstreck" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "över" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "slut på bråk" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "kvadratrot av" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "tredjerot av" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "rot av" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "start på rot" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "slut på rot" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "nedsänkt" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "upphöjt" - -# Beskriver nedsänkta tecken som är placerade innan huvudtecknet snarare än efter. -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "inledande nedsänkt" - -# Beskriver upphöjda tecken som är placerade innan huvudtecknet snarare än efter. -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "inledande upphöjt" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "underskrift" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "överskrift" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "slut på tabell" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "slut på nästlad tabell" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "otillgänglig" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Inaktiverad" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Uppläsning av textindentering och textjustering inaktiverad." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Aktiverad" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Uppläsning av textindentering och textjustering aktiverad." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Inlärningsläge. Tryck Escape för att lämna." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Går in i inlärningsläge. Tryck valfri tangent för att höra dess funktion. " -"Tryck F1 för att se skärmläsarens dokumentation. Tryck F2 för att få en " -"lista över skärmläsarens standardgenvägar. Tryck F3 för att få en lista över " -"skärmläsarens genvägar för det aktuella programmet. Tryck escape för att gå " -"ut ur inlärningsläget." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "lämnar blockcitat." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "lämnar detaljer." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "lämnar flöde." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "lämnar figur." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "lämnar formulär." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "lämnar banderoll." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "lämnar kompletterande innehåll." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "lämnar information." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "lämnar huvudinnehåll." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "lämnar navigering." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "lämnar region." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "lämnar sökning." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "lämnar lista." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "lämnar panel." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "lämnar tabell." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "lämnar inforuta." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "lämnar sammanfattning." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "lämnar tillkännagivanden." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "lämnar efterord." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "lämnar appendix." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "lämnar bibliografi." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "lämnar kapitel." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "lämnar kolofon." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "lämnar avslutning." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "lämnar erkännande." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "lämnar erkännanden." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "lämnar dedikation." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "lämnar slutnoter." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "lämnar epigraf." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "lämnar epilog." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "lämnar rättelser." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "lämnar exempel." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "lämnar förord." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "lämnar ordlista." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "lämnar index." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "lämnar introduktion." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "lämnar sidlista." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "lämnar del." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "lämnar inledning." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "lämnar prolog." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "lämnar utdragscitat." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "lämnar frågor och svar." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "lämnar förslag." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "lämnar innehållsförteckning." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "rad markerad ner från markörposition" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "rad markerad upp från markörposition" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "rad avmarkerad ner från markörposition" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "rad avmarkerad upp från markörposition" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Lämnar inlärningsläget." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "rad markerad från början till föregående markörposition" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "rad markerad till slutet från föregående markörposition" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "länk" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "samma sida" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "samma plats" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "annan plats" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s-länk till %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s-länk" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "besökt %s-länk" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Använd uppåt- och nedåtpil för att navigera i listan. Tryck Escape för att " -"avsluta." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Alla levande regioner inställda till av" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "snällhetsnivåer för levande regioner återställda" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "snällhetsnivå %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "ställer in levande region till påträngande" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "ställer in levande region till av" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "ställer in levande region till snäll" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "ställer in levande region till fräck" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Övervakning av levande regioner är av" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Övervakning av levande regioner är på" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "inget levande meddelande sparat" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Stöd för levande regioner är av" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Hittades inte" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Kunde inte hitta aktuell plats." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "av" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "på" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "felstavat" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Felstavat ord: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Sammanhanget är %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Bläddringsläge" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Fokusläge" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "För att aktivera fokusläge tryck %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Fokusläge är klistrigt." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Bläddringsläge är klistrigt." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Layoutläge." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Objektläge." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Pekare flyttad till objekt." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Hovringsobjekt hittades inte." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Musgranskning inaktiverad." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Musgranskning aktiverad." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Fel: Kunde inte skapa en lista över objekt." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Inga barn." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Ingen efterföljande." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Ingen förälder." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Ingen föregående." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Förenklad navigering aktiverad." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Förenklad navigering inaktiverad." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Nästlad nivå %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Ett nytt objekt har lagts till" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Inga åtgärder hittades på: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Ingen fokus" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Inget program har fokus." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Inga fler blockcitat." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Inga fler knappar." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Inga fler kryssrutor." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Inga fler stora objekt." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Inga fler klickbara." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Inga fler kombinationsrutor." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Inga fler poster." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Inga fler formulärfält." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Inga fler rubriker." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Inga fler rubriker på nivå %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Inga fler interna ramar." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Inga fler bilder." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Inget landmärke hittades." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Inga fler länkar." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Inga fler listor." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Inga fler listobjekt." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Inga fler levande regioner." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Inga fler stycken." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Inga fler radioknappar." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Inga fler avgränsare." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Inga fler tabeller." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Inga fler obesökta länkar." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Inga fler besökta länkar." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Ingen text markerad." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Inte på en länk." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Avisering" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Nedre" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Övre" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Inga aviseringsmeddelanden" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "siffror" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Läs upp nummer som siffror." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "ord" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Läs upp nummer som ord." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "av" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "på" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Läser in. Var god vänta." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Inläsning färdig." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Inläsning av %s färdig." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Sidan har %s." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "sida markerad från markörposition" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "sida markerad till markörposition" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "sida avmarkerad från markörposition" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "sida avmarkerad till markörposition" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "stycke markerat ned från markörposition" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "stycke markerat upp från markörposition" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "stycke avmarkerat ned från markörposition" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "stycke avmarkerat upp från markörposition" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Du har redan en instans av Cthulhus inställningsdialog öppen.\n" -"Stäng den innan du öppnar en ny." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "bild %(position)d av %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil inställd till %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Inga profiler hittades." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Förloppsindikator %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Alla" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Skiljeteckensnivå inställd till alla." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Flesta" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Skiljeteckensnivå inställd till flesta." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Inget" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Skiljeteckensnivå inställd till inget." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Vissa" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Skiljeteckensnivå inställd till vissa." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Söker." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Sökningen är färdig." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu-inställningar laddades om." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Markerad text är: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Markering togs bort." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Markering återställd." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Text avmarkerad." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Storlek: %d, %d. Plats: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Bredd: %d. Höjd: %d. %d från vänster. %d från toppen." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Uppläsning inte aktiverad." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Uppläsning aktiverad." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "snabbare." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "långsammare." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "högre." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "lägre." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "högre." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "tystare." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Hastighet %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Tonhöjd %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Volym %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher-modul %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher-röst %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Inga Speech-dispatcher-moduler tillgängliga" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Inga Speech-dispatcher-röster tillgängliga" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Talinställningar sparade" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Talinställningar kunde inte sparas" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Informationsnivå: kort" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Informationsnivå: informativ" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " punkt punkt punkt" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu välkomnar dig." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu lurar under vågorna." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Viloläge aktiverat för %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Viloläge inaktiverat för %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Uppläsning är inte tillgänglig." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Hittades inte" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Statusraden hittades inte" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "strängen hittades inte" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Strukturella navigeringstangenter av." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Strukturella navigeringstangenter på." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Hittades inte" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Rad %(row)d, kolumn %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Slut på tabell" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Läs upp cell" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Läs upp rad" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Icke likformig" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Inte i en tabell." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Kolumnordning ändrad" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Radordning ändrad" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "kolumn %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolumn %(index)d av %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Nederst i kolumnen." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Överst i kolumnen." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Kolumn %s markerad" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Kolumn %s till %s markerade" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Kolumn %s till %s avmarkerade" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Kolumn %s avmarkerad" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "rad %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "rad %(index)d av %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Början av raden." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Slutet på raden." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Rad togs bort." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Sista raden togs bort." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Rad infogades." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Rad infogad på slutet av tabellen." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Rad %s markerad" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Rad %s till %s markerade" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Rad %s till %s avmarkerade" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Rad %s avmarkerad" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "markerad" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "avmarkerad" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H timmar, %M minuter och %S sekunder" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H timmar och %M minuter" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "ångra" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "gör om" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu version %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "vitsteg" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Börjar om från botten." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Börjar om från toppen." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 objekt" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Cellen spänner över %d rad" -msgstr[1] "Cellen spänner över %d rader" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d kolumn" -msgstr[1] " %d kolumner" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Cellen spänner över %d kolumn" -msgstr[1] "Cellen spänner över %d kolumner" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d tecken för långt" -msgstr[1] "%d tecken för långt" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d dialog)" -msgstr[1] "(%d dialoger)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d ofokuserad dialog" -msgstr[1] "%d ofokuserade dialoger" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" -msgstr[1] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d fil hittades" -msgstr[1] "%d filer hittades" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d formulär" -msgstr[1] "%d formulär" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d rubrik" -msgstr[1] "%d rubriker" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d objekt" -msgstr[1] "%d objekt" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d landmärke" -msgstr[1] "%d landmärken" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d objekt hittades" -msgstr[1] "%d objekt hittades" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Lämnar %d blockcitat." -msgstr[1] "Lämnar %d blockcitat." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Lämnar %d lista." -msgstr[1] "Lämnar %d listor." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Lista med okänd storlek" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Lista med %d objekt" -msgstr[1] "Lista med %d objekt" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Flöde med okänd storlek" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Flöde med %d artikel" -msgstr[1] "Flöde med %d artiklar" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Beskrivningslista med %d term" -msgstr[1] "Beskrivningslista med %d termer" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d värde" -msgstr[1] "%d värden" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "matematisk tabell med %d rad" -msgstr[1] "matematisk tabell med %d rader" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d kolumn" -msgstr[1] "%d kolumner" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "nästlad matematisk tabell med %d rad" -msgstr[1] "nästlad matematisk tabell med %d rader" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d meddelande.\n" -msgstr[1] "%d meddelanden.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d procent." -msgstr[1] "%d procent." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d procent av dokumentet har lästs" -msgstr[1] "%d procent av dokumentet har lästs" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d bildpunkt" -msgstr[1] "%d bildpunkter" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s tecken" -msgstr[1] "%(count)d %(repeatChar)s tecken" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d av %(total)d objekt markerat" -msgstr[1] "%(index)d av %(total)d objekt markerade" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d standardgenväg för skärmläsare hittades." -msgstr[1] "%d standardgenvägar för skärmläsare hittades." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d skärmläsargenväg för %(application)s hittades." -msgstr[1] "%(count)d skärmläsargenvägar för %(application)s hittades." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d blanksteg" -msgstr[1] "%d blanksteg" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d flik" -msgstr[1] "%d flikar" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tabell" -msgstr[1] "%d tabeller" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "tabell med okänd storlek" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "tabell med %d kolumn, okänt antal rader" -msgstr[1] "tabell med %d kolumner, okänt antal rader" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "tabell med %d rad, okänt antal kolumner" -msgstr[1] "tabell med %d rader, okänt antal kolumner" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "tabell med %d rad" -msgstr[1] "tabell med %d rader" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d sekund sedan" -msgstr[1] "%d sekunder sedan" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d minut sedan" -msgstr[1] "%d minuter sedan" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d timme sedan" -msgstr[1] "%d timmar sedan" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d dag sedan" -msgstr[1] "%d dagar sedan" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d obesökt länk" -msgstr[1] "%d obesökta länkar" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d besökt länk" -msgstr[1] "%d besökta länkar" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "växla" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "på %(index)d av %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d av %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "objekt %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "NIVÅ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "trädnivå %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TRÄDNIVÅ %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "detaljer för %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "har detaljer i %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "förslag" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "redigerbar kombinationsruta" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "redigerbart innehåll" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "flöde" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "figur" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "sammanfattning" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "tillkännagivanden" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "efterord" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "appendix" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "bibliografipost" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "bibliografi" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "kapitel" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "kolofon" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "avslutning" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "omslag" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "erkännande" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "erkännanden" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "dedikation" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "slutnot" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "slutnoter" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "epigraf" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "epilog" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "rättelser" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "exempel" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "förord" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "ordlista" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "index" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "introduktion" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "sidbrytning" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "sidlista" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "del" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "inledning" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "prolog" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "utdragscitat" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "frågor och svar" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "undertitel" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "innehållsförteckning" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s nivå %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "horisontell rullningslist" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "vertikal rullningslist" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "horisontellt skjutreglage" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "vertikalt skjutreglage" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "horisontell avdelare" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "vertikal avdelare" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "brytare" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Ikonpanel" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "banderoll" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "kompletterande innehåll" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "information" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "huvudinnehåll" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "navigering" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "region" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "sökning" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "besökt länk" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "menyknapp" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "sorterad stigande" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "sorterad fallande" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "sorterad" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "klickbar" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "infälld" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "utfälld" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "har lång beskrivning" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "horisontell" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "vertikal" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "kryssad" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "inte kryssad" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "på" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "av" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "delvis kryssad" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "nedtryckt" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "inte nedtryckt" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "inte markerat" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "markerad" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "inte markerad" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "inte markerad" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "besökt" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "obesökt" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "gråad" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "skrivskyddad" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "skrskydd" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "nödvändig" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "flermarkering" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "ogiltig post" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "ogiltig" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "ogiltig stavning" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "stavning" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "ogiltig grammatik" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "grammatik" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Sök" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Sökdialog för Skärmläsare" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "S_täng" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Sök" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Sök efter:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Sök efter:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Ö_verkant av fönster" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Överkant av fönster" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Börja från:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Börja om" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Sök _baklänges" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Sökriktning:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Skiftlägeskänslig" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Matcha endast _hela ord" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Alternativ:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Standard" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Versaler" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hyperlänk" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "System" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Program" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Fönster" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu-inställningar" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Hjälp" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Verkställ" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Bärbar dator" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Tangentbordslayout" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Aktiv _profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Uppstartsprofil:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Läs in" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Spara s_om" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Ta bort" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiler" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Presentera inforutor" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Läs upp objekt under m_uspekare" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Mus" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Tidsformat:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Dat_umformat:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Tid och datum" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "_Läs upp uppdateringar" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Punktskriftsuppdateringar" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Frekvens (sekunder):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Gäller för:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Si_gnalera uppdateringar" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Uppdateringar i förloppsindikator" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Aktive_ra spolning bakåt och framåt i Läs upp allt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Aktivera _strukturell navigering i Läs upp allt" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Läs upp allt _efter:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Annonsera block_citat i Läs upp allt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Annonsera li_stor i Läs upp allt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Annonsera _tabeller i Läs upp allt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Annonsera _paneler i Läs upp allt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Annonsera _formulär i Läs upp allt" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Annonsera land_märken i Läs upp allt" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Läs upp allt" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Element_presentation:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Allmänt" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Vo_lym:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Tonar_t:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Hastighet:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Person:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "Sp_råk:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Talsynt_es:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Uppläsnings_system:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Röstt_yp:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "Versal_iseringsstil:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Inställningar för rösttyp" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Läs upp strängar med blandade skiftlägen som or_d" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Läs upp _nummer som siffror" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Allmänna röstinställningar" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Röst" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Aktiv_era uppläsning" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Informati_v" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Informationsnivå" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Alla" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Skiljeteckensnivå" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Läs endast upp visad text" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Läs upp blanka rader" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Läs upp text_indentering och textjustering" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Läs u_pp minnesobjekt" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Läs upp barnp_osition" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Läs upp handledningsmeddelanden" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Systemmeddelanden är detaljerade" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Läs u_pp färger som namn" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Annonsera block_citat under navigering" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Annonsera _listor under navigering" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Annonsera _tabeller under navigering" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Läs upp _indikator för felstavade ord" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Annonsera _paneler under navigering" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Annonsera land_märken under navigering" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Annonsera _formulär under navigering" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Läs upp _beskrivning" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Läs upp hel _rad i kalkylblad" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Läs upp hel rad i _dokumenttabeller" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Läs upp hel rad i _gränssnittstabeller" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Talsammanhang" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Uppläsning" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Aktivera punktskrifts_stöd" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Förkortade rollnamn" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Inaktivera _radslutssymbol" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Kontraktions_tabell:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "_Aktivera litterär punktskrift" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Aktivera radbrytning mellan _ord" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Visningsinställningar" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Ingen" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Markeringsindikator" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hyperlänksindikator" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Aktivera blixt_meddelanden" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "Län_gd (sek):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Meddelanden är _beständiga" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Meddelanden är _detaljerade" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Inställningar för blixtmeddelanden" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Punktskrift" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Aktivera tangent_eko" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Aktivera bokst_avstangenter" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Aktivera si_ffertangenter" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Aktivera s_kiljetecken" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Aktivera blank_steg" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Aktivera _modifierartangenter" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Aktivera _funktionstangenter" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Aktivera å_tgärdstangenter" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Aktivera _navigeringstangenter" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Aktivera eko efter _ord" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Aktivera eko efter _mening" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Eko" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "_Modifierartangent(er) för skärmläsare:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Tangentbindningar" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Uttalsordlista" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Ny post" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Ta bort" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Uttal" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Läs upp alla" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Läs inte upp _något" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Återställ" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Textattribut" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Flytta _nederst" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Flytta en _nedåt" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Flytta en _uppåt" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Flytta _överst" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Justera markerat attribut" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Punktskriftsindikator" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Textattribut" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Aktivera AI-assistent" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Leverantör:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Lokal - Gratis)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API-_nyckelfil:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Sökväg till API-nyckelfil" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Hämta _Claude API-nyckel" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Öppna webbläsaren för att hämta Claude API-nyckel och spara automatiskt" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Kräv bekräftelse före AI-åtgärder" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama-_modell:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Modellnamn för Ollama (t.ex. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama-_slutpunkt:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API-slutpunkt-URL (t.ex. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Skärmbilds_kvalitet:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Låg" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Medium" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Hög" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI-assistent" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Språkkod:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Skalningsfaktor:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Gråskalebild" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Invertera bild" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Svartvit bild" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Svart/vit-_tröskel:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Analysera färger" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Kopiera resultat till _urklipp" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : adam, b : bertil, c : cesar, d : david, e : erik, f : filip, g : gustav, " -"h : helge, i : ivar, j : johan, k : kalle, l : ludvig, m : martin, n : " -"niklas, o : olof, p : petter, q : quintus, r : rudolf, s : sigurd, t : tore, " -"u : urban, v : viktor, w : wilhelm, x : xerxes, y : yngve, z : zäta, å : " -"åke, ä : ärlig, ö : östen" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "bakgrundsfärg" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "full höjd för bakgrund" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "bakgrundsprick" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "riktning" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "redigerbar" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "familjenamn" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "förgrundsfärg" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "förgrundsprick" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "typsnittseffekt" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "indragning" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "misstag" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "osynlig" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "justering" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "språk" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "vänstermarginal" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "radhöjd" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "styckestil" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "bildpunkter ovan rader" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "bildpunkter under rader" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "bildpunkter inom radbrytning" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "högermarginal" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "förhöj" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "skala" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "storlek" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "sträck" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "genomstruken" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "stil" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "textdekoration" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "textrotering" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "textskugga" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "understruken" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "variant" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "vertikal justering" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "vikt" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "radbrytningsläge" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "skrivläge" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "sant" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "falskt" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ingen" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "gravera" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "ciselera" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "kontur" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "överstrykning" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "streck igenom" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "blink" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "svart" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "enkel" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "dubbel" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "låg" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "tecken" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "ord" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "ordtecken" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "vänster" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "höger" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "centrera" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "ingen justering" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "fyll" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ultra condensed" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "extra condensed" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "condensed" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "semi condensed" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "normal" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "semi expanded" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "utfälld" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "extra expanded" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ultra expanded" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "kapitäler" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "oblik" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "kursiv" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Standard" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Brödtext" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Rubrik" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "grundlinje" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "under" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "super" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "överst" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "överst" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "mitten" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "nederst" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "nederst" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "ärv" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "fast" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "stavning" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Tryck på blanksteg för att växla." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Tryck på blanksteg för att fälla ut och använd pil upp och ned för att välja " -"ett objekt." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Tryck på Alt+F6 för att ge fokus till barnfönster." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"För att förflytta till objekten, använd antingen piltangenterna eller skriv " -"in något för att söka." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Tryck på Alt+F1 för att komma till systemmenyerna." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Använd uppåt och nedåt för att välja ett objekt." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Tryck på Skift plus vänster för att fälla in." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Tryck på Skift plus höger för att fälla ut." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Tryck på retur för att aktivera." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Skriv in text." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Använd vänster och höger för att visa andra flikar." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Tryck på blanksteg för att aktivera." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Använd pil upp eller ned för att välja ett värde. Eller skriv in det önskade " -"numeriska värdet." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Använd piltangenterna för att ändra." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Tryck på vänster eller höger pil för att navigera. Tryck på pil upp eller " -"ned för att flytta dig genom objekten." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Tryck på högerpil för att gå in i en undermeny." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Tryck på vänsterpil för att minska, tryck på högerpil för att öka. Tryck på " -"Home för att gå till minimum och End för att gå till maximum." diff --git a/po/ta.po b/po/ta.po deleted file mode 100644 index 3670a43..0000000 --- a/po/ta.po +++ /dev/null @@ -1,9841 +0,0 @@ -# translation of cthulhu.HEAD.ta.po to Tamil -# translation of cthulhu.HEAD.ta.po to -# Copyright (C) 2001, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. -# -# Jayaradha N , 2004. -# Felix , 2006. -# drtvasudevan , 2006. -# Dr.T.Vasudevan , 2007, 2009, 2010, 2011, 2012, 2013. -# I. Felix , 2008, 2009. -# Dr,T,Vasudevan , 2010, 2011. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD.ta\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2013-03-22 14:57+0530\n" -"Last-Translator: Dr.T.Vasudevan \n" -"Language-Team: Tamil <>\n" -"Language: ta\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 1.5\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\\n\n" -"\n" - -msgid "Cthulhu Screen Reader" -msgstr "ஆர்கா திரை படிப்பி " - -#, fuzzy -msgid "screen;reader;accessibility;speech;braille;" -msgstr "திரைபடிப்பான்;பேசுதல்;ப்ரெய்ல்;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "எச்ரி" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "அசை" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "அம்பு" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "நாகாடி" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "காவா" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "தலை" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "தேபெ" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "நிறதேர்" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "நிரதலை" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "சேபெ" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "தேதி " - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "சின்" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "சட்ட" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "அழை" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "உரை" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "அடைப" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "ஹெச்டி" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "வரைபு" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "கோதே" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "நிர" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "எரு" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "படி" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "கண்டி" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "தலை" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "படம்" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "உள்ச" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "லேபி" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "அப" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "இணை" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "பட்" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "பட்உ" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "பட்டி" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "படிப" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "படிஉ" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "விருப" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "பக்" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "தத்ப" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "பல" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "கசொ" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "பாப்மெ" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "முன்ப" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "பொத்" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "தேபொத்" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "தேபஉ" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "ரூட்ப" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "நித" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "சுப" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "சுபே" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "தொகு" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "பிரி" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "நக" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "பலபி" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "சுழல்" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "நிப" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "அட்ட" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "அறை" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "நகூப" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "முனை" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "உரை" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "மாபொ" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "கப" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "ககு" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "கிளை" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "கிஅ" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "தெரியா" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "சாள" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "தல" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "அகு" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "பத்தி" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "பபா" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "தானி" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "திப" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "பொ" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "செக் க்ரேட் 1 " - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "ஸ்பானிஷ் க்ரேட் 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "கனடா பிரெஞ்சு க்ரேட் 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "ஃப்ரான்ஸ் பிரெஞ்சு க்ரேட் 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "இலட்வியன் க்ரேட் 1 " - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "நெதர்லாந்து டச்சு க்ரேட் 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "நார்வேஜியன் க்ரேட் 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "நார்வேஜியன் க்ரேட் 1 " - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr " நார்வேஜியன் க்ரேட் 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "நார்வேஜியன் க்ரேட் 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "போலிஷ் க்ரேட் 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "போர்த்துக்கீசிய க்ரேட் 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "சுவீடிஷ் க்ரேட் 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "அராபிக் க்ரேட் 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "வெல்ஷ் க்ரேட் 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "வெல்ஷ் க்ரேட் 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "ஜெர்மன் க்ரேட் 0 " - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "ஜெர்மன் க்ரேட் 1 " - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "ஜெர்மன் க்ரேட் 2 " - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "யூ.கே. ஆங்கிலம் க்ரேட் 2 " - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "யூ.கே ஆங்கிலம் 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "யூ.எஸ் ஆங்கிலம் 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "யூ.எஸ் ஆங்கிலம் 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "கனடா பிரெஞ்சு கிரேட் 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "ஃப்ரான்ஸ் பிரெஞ்சு கிரேட் 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "கிரீக் கிரேட் 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "ஹிந்தி கிரேட் 1 " - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "ஹங்கேரியன் 8 புள்ளி கணினி" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "ஹங்கேரியன் க்ரேட் 1 " - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "ஹங்கேரியன் க்ரேட் 1 " - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "இத்தாலியன் கிரேட் 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "பெல்ஜியம் டச்சு கிரேட் 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "இடைவெளி" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "புதிய வரி" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "கீற்று" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "வியப்பு" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "குறி" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "எண்" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "டாலர்" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "சதவீதம்" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "மற்றும்" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "தொகுநிலைக்குறி" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "இடது அடைப்பு" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "வலது அடைப்பு" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "நட்சத்திரம்" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "கூட்டல்" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "காற்புள்ளி" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "கோடு" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "புள்ளி" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "வகு" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "அரைப்புள்ளி" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "அரைப்புள்ளி" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "குறைவு" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "சமம்" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "அதிகம்" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "வினா" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "அட்" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "இடது சதுர அடைப்புக்குறி" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "பின்வெட்டு" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "வலது சதுர அடைப்புக்குறி" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "காரட்" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "அடிக்கோடு" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "க்ரேவ்" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "இடது முள் அடைப்புக்குறி" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "செங்குத்து கோல்" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "வலது முள் அடைப்புக்குறி" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "டில்டே" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "முறிப்பு இடைவெளி இல்லை" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "தலைகீழ் வியப்பு குறி" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "சென்ட்கள்" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "பவுண்டுகள்" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "பண குறி" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "யென்" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "உடைந்த கோல்" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "செக்ஷன்" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "டயரெஸிஸ்" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "காப்புரிமை" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "மேலெழுத்து எ" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "இடது இரட்டை அம்பு அடைப்புக்குறி" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "தருக்கரீதியாக இல்லை" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "மெது ஹைபன்" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "பதிவு செய்யப்பட்டது" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "மேக்ரான்" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "பாகைகள்" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "கூட்டல் அல்லது கழித்தல்" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "மேலெழுத்து 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "மேலெழுத்து 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "அக்யூட்" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "மு" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "பத்தி அடையாளம்" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "நடு புள்ளி" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "செடில்லா" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "மேலெழுத்து 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "அழை" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "வலது இரட்டை அம்பு அடைப்புக்குறி" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "கால் பாகம்" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "அரை பாகம்" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "முக்கால் பாகம்" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "தலைகீழ் கேள்விக்குறி" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a அக்யூட்" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "ஏ க்ரேவ்" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "ஏ அக்யூட்" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "ஏ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "ஏ டில்டே" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "ஏ உம்லௌட்" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "ஏ ரிங்" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "ஏ ஈ" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "சி செடில்லா" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "ஈ க்ரேவ்" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "ஈ அக்யூட்" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "ஈ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "ஈஉம்லௌட்" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "ஐ க்ரேவ்" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "ஐ அக்யூட்" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "ஐ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "ஐ உம்லௌட்" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ஈடிஹெச்" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "என் டில்டே" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "ஓ க்ரேவ்" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "ஓ அக்யூட்" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "ஓ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "ஓ டில்டே" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "ஓ உம்லௌட்" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "மடங்கு" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "ஓ ஸ்ட்ரோக்" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "யூ க்ரேவ்" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "யூ அக்யூட்" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "யூ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "யூ உம்லௌட்" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "ஒய் அக்யூட்" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "தார்ன்" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "எஸ் ஷார்ப்" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "எ க்ரேவ்" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "எ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "எ டில்டே" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "எ உம்லௌட்" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "எ வளையம்" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "எ இ" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "சி செடில்லா" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "இ க்ரேவ்" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "இ அக்யூட்" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "இ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "இ உம்லௌட்" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "ஐ க்ரேவ்" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "ஐ அக்யூட்" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "ஐ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "ஐ உம்லௌட்" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "இடிஹெச்(eth)" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "என் டில்டே" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "ஒ க்ரேவ் " - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "ஓ அக்யூட்" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "ஓ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "ஓ டில்டே" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "ஓ உம்லௌட்" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "வகுத்தல்" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "ஒ ஸ்ட்ரோக்" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "தார்ன்" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "யூ அக்யூட்" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "யு க்ரேவ்" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "யூ ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "யூ உம்லௌட்" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "ஒய் அக்யூட்" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "ஒய் உம்லௌட்" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "ஒய் உம்லௌட்" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "ஃப்லோரிங்" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "என் கோடு" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "இடது ஒற்றை மேற்கோள்" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "வலது ஒற்றை மேற்கோள்" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "single low quote" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "இடது இரட்டை மேற்கோள்" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "வலது இரட்டை மேற்கோள்" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "double low quote" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "கத்தி" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "இரட்டை கத்தி" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "புல்லட்" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "முக்கோண புல்லட்" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "ஆயிரத்தில்" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "முதன்மை" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "இரட்டை முதன்மை" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "இரட்டை முதன்மை" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "ஹைபன் புல்லட்" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "யூரோ" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "வர்த்தக சின்னம்" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "சரி குறி" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "தடிமனான சரி குறி" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "X வடிவ புல்லட்" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "மேலெழுத்து 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "மேலெழுத்து 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "மேலெழுத்து 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "மேலெழுத்து 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "மேலெழுத்து 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "மேலெழுத்து 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "மேலெழுத்து 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "மேலெழுத்து +" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "மேலெழுத்து -" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "மேலெழுத்து =" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "மேலெழுத்து [" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "மேலெழுத்து ]" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "மேலெழுத்து n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "கீழொட்டு 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "கீழொட்டு 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "கீழொட்டு 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "கீழொட்டு 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "கீழொட்டு 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "கீழொட்டு 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "கீழொட்டு 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "கீழொட்டு 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "கீழொட்டு 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "கீழொட்டு 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "கீழொட்டு +" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "கீழொட்டு -" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "கீழொட்டு =" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "கீழொட்டு இடது அடைப்பு" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "கீழொட்டு வலது அடைப்பு" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "கருப்பு சதுரம்" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "கருப்பு வைரம்" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "அடுத்த எழுத்துருவுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "நிலை காட்டியை நடப்பு உருப்படிக்கு திருப்புகிறது." - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "தற்போதைய தட்டை ஆய்வு உருப்படியின் மீது இடது சொடுக்கு செய்கிறது" - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "தற்போதைய தட்டை ஆய்வு உருப்படியின் மீது வலது சொடுக்கு செய்கிறது" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "முழு ஆவணத்திற்கும் பேசுகிறது." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "தட்டை ஆய்வு பாங்கை பயன்படுத்தவில்லை" - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "அடிப்படை எங்கு உள்ளேன் ஆய்வை செய்கிறது " - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "விரிவான எங்கு உள்ளேன் ஆய்வை செய்கிறது ." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "தற்போதைய தட்டை ஆய்வு வரியை பேசுகிறது" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "வெற்று வரிகளை பேசு" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "அடுத்த பொத்தானுக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "நிலைப்பட்டை ஐ பேசுகிறது." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "தலைப்பை பேசுகிறது" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "ஆர்கா தேடல் உரையாடலை துவக்குகிறது." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "அடுத்த சர நிகழ்வை தேடுகிறது." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "முந்தைய சர நிகழ்வை தேடுகிறது." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "தட்டை ஆய்வு பாங்கில் சென்று மீள்கிறது" - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "தட்டை ஆய்வை கடைசி இடத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "தட்டை ஆய்வை இல்ல இடத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "தட்டை ஆய்வை கடைசி இடத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "தட்டை ஆய்வை முந்தைய வரியின் ஆரம்பத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "தற்போதைய தட்டை ஆய்வு வரியை பேசுகிறது" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "உள்ளீடு வரியின் உள்ளடக்கங்களை பேசுகிறது." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "இப்போதைய தட்டை ஆய்வு வரியை எழுத்து கூட்டி சொல்லுகிறது." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "தட்டை ஆய்வை அடுத்த வரியின் ஆரம்ப இடத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "தட்டை ஆய்வை முந்தைய உருப்படி அல்லது சொல்லுக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "தற்போதைய தட்டை ஆய்வு பொருளை அல்லது சொல்லை பேசுகிறது." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "தற்போதைய தட்டை ஆய்வு பொருளை அல்லது சொல்லை எழுத்துக்கூட்டி சொல்கிறது." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "தற்போதைய தட்டை ஆய்வு பொருளை அல்லது சொல்லை ஒலி கூட்டி சொல்கிறது." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "தட்டை ஆய்வை அடுத்த உருப்படி அல்லது சொல்லுக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "தட்டை ஆய்வை தற்போதைய சொல்லுக்கு மேலுள்ள சொல்லுக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "தட்டை ஆய்வில் தற்போதைய பொருளை பேசுகிறது" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "தட்டை ஆய்வை தற்போதைய சொல்லுக்கு கீழுள்ள சொல்லுக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "தட்டை ஆய்வை முந்தைய எண்எழுத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "தட்டை ஆய்வில் தற்போதைய எண்ணெழுதுருவை பேசுகிறது" - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "நடப்பு தட்டையான மறுபார்வை எழுத்தை ஃபொனிடிக்காக பேசவும்." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "தட்டை ஆய்வில் தற்போதைய யூளனிக்கோட் மதிப்பை பேசுகிறது" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "தட்டை ஆய்வை அடுத்த எண்எழுத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "தட்டை ஆய்வை வரியின் கடைசிக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "தட்டை ஆய்வை இடது கீழ் பக்கம் நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "தற்போதைய தட்டை ஆய்வு பொருளை ஒட்டுப்பலகைக்கு பிரதி எடுக்கிறது" - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "தற்போதைய தட்டை ஆய்வு பொருளை ஒட்டுப்பலகைக்கு பின் சேர்கிறது" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "தட்டை ஆய்வை கடைசி இடத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "தற்போதைய அறையை படிப்பதா அல்லது முழு வரியை படிப்பதா என நிலை மாற்றுகிறது." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "தற்போதைய உரை எழுதுருவுடன் சம்பந்தப்பட்ட பண்புகளை படிக்கிறது." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "ப்ரெய்ல் காட்சியை இடது பக்கத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "ப்ரெய்ல் காட்சியை வலது பக்கத்துக்கு நகர்த்துகிறது." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "விசைப்பலகை குவிப்புடன் பொருளுக்கு திரும்புகிறது." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "சுருக்க ப்ரெய்லியை நிலை மாற்ற" - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "ஒரு நிலைக்காட்டி பொருத்தி விசையை செயலாக்குகிறது" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "உரை தேர்வின் ஆரம்பத்தை குறிக்கிறது." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "உரை தேர்வின் இறுதியை குறிக்கிறது." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"கற்கும் முறைக்கு நுழைகிறது. கற்கும் முறையிலிருந்து வெளியேற விடுபடு விசையை " -"அழுத்தவும்." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "குரல் விகிதத்தைக் குறைக்கிறது." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "குரல் விகிதத்தை அதிகரிக்கிறது." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "குரல் தொனியை குறைக்கிறது." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "குரல் தொனியை அதிகரிக்கிறது." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "குரல் விகிதத்தை அதிகரிக்கிறது." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "குரல் விகிதத்தைக் குறைக்கிறது." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "வேண்டிய குரல் சேவையகத்தை தேர்ந்தெடு." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "வேண்டிய குரல் சேவையகத்தை தேர்ந்தெடு." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "குரல் விகிதத்தைக் குறைக்கிறது." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "குரல் விகிதத்தை அதிகரிக்கிறது." - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "பேச்சு வகை அமைவுகள்" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "குரல் உருவாக்கத்தை நிலை மாற்றுகிறது." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "சொடுக்கி ஆய்வு முறைமையை நிலைமாற்றுகிறது" - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "ஆர்கா திரை படிப்பி " - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "முன்னுரிமை கட்டமைப்பு உரையாடலை காட்டுகிறது." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "நிரலின் முன்னுரிமை கட்டமைப்பு உரையாடலை காட்டுகிறது." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "உள்ளடக்கம் மற்றும் ஒழுங்கு இவற்றை சொல்லுவதை நிலை மாற்றுகிறது" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "நிறுத்தற்குறி நிலையின் அடுத்த மட்டத்துக்கு சுழற்றுகிறது." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "எதிரொலிப்பின் அடுத்த நிலைக்கு சுழற்றுகிறது." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "அடுத்த வரியுரு அமைப்புக்கு சுழற்றுகிறது." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "எழுத்து மேல்நிலை பாங்கின் அடுத்த மட்டத்துக்கு சுழலுகிறது." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "எதிரொலிப்பின் அடுத்த நிலைக்கு சுழற்றுகிறது." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "வழு நீக்கு மட்டத்தை இயங்கு நேரத்தில் சுழற்றுகிறது.." - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "இப்போதைய இடத்துடன் நான் எங்கே இருக்கிறேன் புத்தகக்குறி இடுக" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "முந்தைய புத்தகக்குறி இடத்துக்கு செல்க" - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "புத்தகக்குறிக்கு போகவும்" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "அடுத்த புத்தகக்குறி இடத்துக்கு செல்க" - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "புத்தகக்குறிக்கு சேர்க்கவும்." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "புத்தகக்குறிகளை சேமி" - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "சொடுக்கி ஆய்வு முறைமையை நிலைமாற்றுகிறது" - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "நடப்பு நேரம்." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "நடப்பு தேதி" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "இப்போதைய பயன்பாட்டுக்கு அடுத்த கட்டளையை இயக்குகிறது." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "ஒரு முந்தைய அரட்டை அறை செய்தியை பேசு, ப்ரெய்ல் முறையில் காட்டு" - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "நண்பர்கள் தட்டச்சும்போது நாம் வருகையை தெரிவிக்கலாமா என்பதை நிலைமாற்றுகிறது." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "அரட்டை அறை குறிப்பான வரலாற்றை தரலாமா என்பதை நிலைமாற்றுகிறது. " - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"அரட்டை அறை செய்திகளை அரட்டை அறை பெயரால் முன்னொட்டு அமைக்கலாமா என்பதை மாற்றுகிறது." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "இடது வரி" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "வலது வரி" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "மேல் வரி" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "கீழ் வரி" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Freeze" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "மேல் இடது" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "கீழ் இடது" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "நிலை காட்டி இடம்" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "ஆறு புள்ளிகள்" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "நிலை காட்டி பொருத்தி" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "நகலெடுப்பு துவக்கம்" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "வரியை நகலெடு" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "கடைசி அறிவிப்பு செய்தியை முன்வைக்கிறது." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "செய்திகள் பட்டியல் அறிவிப்பை முன்வை" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "முந்தைய அறிவிப்பு செய்தியை முன்வைக்கிறது." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "கடைசி அறிவிப்பு செய்தியை முன்வைக்கிறது." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "அடுத்த எழுத்துருவுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "முந்தைய எழுத்துருவுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "அடுத்த சொல்லுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "முந்தைய சொல்லுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "அடுத்த வரிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "முந்தைய வரிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "கோப்பின் தலைக்கு போகிறது." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "கோப்பின் அடிக்கு போகிறது" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "வரியின் ஆரம்பத்துக்கு போகிறது." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "உவரியின் இறுதிக்கு போகிறது." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "அடுத்த பொருளுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "முந்தைய பொருளுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "இப்போதைய கூட்டு பெட்டியை விரிக்கிறது" - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "இயல்பான கெக்கோ மற்றும் ஆர்கா காரட் உலாவல் நடுவே மாறுகிறது" - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "முன்கூட்டிய நிகழ்விட மரியாதை அமைப்பு." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "முன்னிருப்பு நிகழ்விட மரியாதை மட்டத்தை இல்லை என ஆக்கு." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "நிகழ்விட அறிக்கையை மீள்பார்வை செய்க." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "நிகழ்விடங்களை கண்காணி." - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "குவிப்பை நடப்பு சொடுக்கி இடத்திற்கு உள்ளும் வெளியேவும் நகர்த்துகிறது. " - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "இயங்கு நிலை பத்தி தலைப்புகளாக பயன்படுத்த வரியை அமைக்கவும்" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "இயங்கு பத்தி தலைப்புகளை நீக்குகிறது" - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "இயங்கு நிலை வரி தலைப்புகளாக பயன்படுத்த பத்தியை அமைக்கவும்" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "இயங்கு வரி தலைப்புகளை நீக்குகிறது" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "உள்ளீடு வரியின் உள்ளடக்கங்களை தருகிறது." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "அமைப்பு உலாவல் விசைகளை மாற்றுகிறது. " - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "முந்தைய பெரு மேற்கோளுக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "அடுத்த பெரு மேற்கோளுக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:852 -#, fuzzy -msgid "Display a list of blockquotes" -msgstr "பெரு மேற்கோள் பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "முந்தைய பொத்தானுக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "அடுத்த பொத்தானுக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "பொத்தான்கள் பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "முந்தைய தேர்வு பெட்டிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "அடுத்த தேர்வு பெட்டிக்கு செல்கிறது.." - -#: src/cthulhu/cmdnames.py:870 -#, fuzzy -msgid "Display a list of check boxes" -msgstr "தேர்வு பெட்டி பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "முந்தைய அட்டவணைக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "அடுத்த அட்டவணைக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "அட்டவணை பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "முந்தைய கூட்டுப்பெட்டிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "அடுத்த கூட்டுப்பெட்டிக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "ஹெச்டிஎம்எல் பெட்டி" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "ஹெச்டிஎம்எல் பெட்டி" - -#: src/cthulhu/cmdnames.py:901 -#, fuzzy -msgid "Display a list of combo boxes" -msgstr "கூட்டுப்பெட்டிகள் பட்டியலை காட்டுகிறது." - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "முந்தைய உள்ளீட்டுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "அடுத்த உள்ளீட்டுக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "உள்ளீட்டுகள் பட்டியலை காட்டுகிறது." - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "முந்தைய படிவ புலத்துக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "அடுத்த படிவ புலத்துக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:919 -#, fuzzy -msgid "Display a list of form fields" -msgstr "படிவ புலங்கள் பட்டியலை காட்டுகிறது." - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "முந்தைய தலைப்புக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "அடுத்த தலைப்புக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "தலைப்புகள் பட்டியலை காட்டுகிறது." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "மட்டம் %d இல் முந்தைய தலைப்புக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "மட்டம் %d இல் அடுத்த தலைப்புக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "அடுக்கு %d இல் தலைப்புகள் பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "முந்தைய அட்டவணைக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "உள்ளார்ந்த சட்டம்" - -#: src/cthulhu/cmdnames.py:949 -#, fuzzy -msgid "Display a list of internal frames" -msgstr "அட்டவணை பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "முந்தைய வரிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "அடுத்த வரிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "அட்டவணை பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "முந்தைய புத்தகக் குறிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "அடுத்த புத்தகக் குறிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "தொடுப்புகள் பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "முந்தைய பெரிய பொருளுக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "அடுத்த பெரிய பொருளுக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "பெரிய பொருட்களின் பட்டியலை காட்டுகிறது." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "முந்தைய வரிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "அடுத்த வரிக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "தொடுப்புகள் பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "முந்தைய பட்டியலுக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "அடுத்த பட்டியலுக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:1006 -#, fuzzy -msgid "Display a list of lists" -msgstr "பட்டியல் பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "முந்தைய பட்டியல் உருப்படிக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "அடுத்த பட்டியல் உருப்படிக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "உருப்படிகள் பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "முந்தைய நிகழ்விடத்துக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "அடுத்த நிகழ்விடத்துக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "கடைசியாக ஒரு அறிக்கை வெளியிட்ட நிகழ்விடத்துக்கு செல்க" - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "குவிப்பில் உள்ள பொருளின் மூதாதையரின் வழு நீக்கு தகவலை அச்சிடுகிறது." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "விசைப்பலகை குவிப்புடன் பொருளுக்கு திரும்புகிறது." - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "அமைப்பு உலாவல் விசைகளை மாற்றுகிறது. " - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "முந்தைய பத்திக்கு செல்கிறது. ." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "அடுத்த பத்திக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "பத்திகள் பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "முந்தைய ரேடியோ பொத்தானுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "அடுத்த ரேடியோ பொத்தானுக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "தேர்வு பொத்தான் பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "முந்தைய பிரிப்பானுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "அடுத்த பிரிப்பானுக்கு செல்கிறது." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "முந்தைய அட்டவணைக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "அடுத்த அட்டவணைக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "அட்டவணை பட்டியலை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "ஒரு அறை கீழ் பக்கம் செல்கிறது" - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "ஒரு அட்டவணையில் முதல் அறைக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "ஒரு அட்டவணையில் கடைசி அறைக்கு செல்கிறது" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "ஒரு அறை இடது பக்கம் செல்கிறது" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "ஒரு அறை வலது பக்கம் செல்கிறது" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "ஒரு அறை மேல் பக்கம் செல்கிறது" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "சொடுக்கி ஆய்வு முறைமையை நிலைமாற்றுகிறது" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "விசை எதிரொலிப்பை செயல்படுத்து (_k)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "முந்தைய முன்னம் பார்க்காத தொடுப்புக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "அடுத்த முன்னம் பார்க்காத தொடுப்புக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr " முன்னம் பார்க்காத தொடுப்புகளை காட்டுகிறது" - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "முந்தைய முன்னம் பார்த்த தொடுப்புக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "அடுத்த முன்னம் பார்த்த தொடுப்புக்கு செல்கிறது " - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "முன்னம் பார்த்த தொடுப்புகளை காட்டுகிறது" - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "நீல தெவிட்டம்" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "கருப்பு" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "கருப்பு வைரம்" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "நீல தெவிட்டம்" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "நீல தெவிட்டம்" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "எ க்ரேவ்" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "பச்சை தெவிட்டம்" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "பச்சை தெவிட்டம்" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "சிவப்பு தெவிட்டம்" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "பச்சை தெவிட்டம்" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "நீல தெவிட்டம்" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "ஐ க்ரேவ்" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "பச்சை தெவிட்ட குறைப்பு" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "சாம்பல் நிறமிடப்பட்டது" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "பாகைகள்" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "ஹிந்தி கிரேட் 1 " - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "வலது முள் அடைப்புக்குறி" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "வலது கன்ட்ரோல்" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "வலது அடைப்பு" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "வலது முள் அடைப்புக்குறி" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "வலது அடைப்பு" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "வலது அடைப்பு" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "வலது ஆல்ட்" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "வலது அடைப்பு" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "வலது சூப்பர்" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "வலது அம்புக்குறி" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "புதிய வரி" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "படம்" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "நீல தெவிட்ட குறைப்பு" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "சிவப்பு தெவிட்டம்" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "பச்சை தெவிட்டம்" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "கிளை" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "நீல தெவிட்டம்" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s திரை" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "நீல தெவிட்ட குறைப்பு" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "நீல தெவிட்ட குறைப்பு" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "பொத்" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "வெள்ளை இடைவெளி" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "வெள்ளை இடைவெளி" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "முழு திரை" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_A செயலாக்கு" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "புள்ளி _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "புள்ளி _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "புள்ளிகள் 7 _மற்றும் 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "சின்" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "ஒன்றுமில்லை" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "சொல்லு" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "(_b) நண்பர்கள் தட்டச்சும்போது என் வருகையை தெரிவி" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "(_m) அரட்டை அறை குறிப்பான வரலாற்றை தருக" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "இவரிடமிருந்து செய்தியை கூறுக" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "(_n) அனைத்து வாய்க்கால்களும்" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "(_y) எந்த %s சாளரம் திறந்து இருந்தாலும் அனைத்து ஓடைகளும் " - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "அதன் சாளரம் செயலில் இருந்தால் மட்டும் ஒரு வாய்க்கால்" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "(_S) அரட்டை அறை பெயரை கூறுக" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "இரட்டிப்பு சொடுக்கு" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "மூன்று சொடுக்கு" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "குரல் தொகுப்பி: " - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "உண்மைச்சரம்" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "மாற்ற சரம்" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "எழுத்துருவால் எதிரொலிப்பை செயல்படுத்து (_r)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "வெற்று இடமில்லா டயாக்ரிடிக் விசைகளை செயல்படுத்து (_d) " - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "(_u) தற்போதைய இடம்" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "ஒத்திசைந்த உரையில் குறைந்த பட்ச நீளம்" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "தேடல் தேர்வுகள்" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "(_y) தேடல் போது மாறிய வரிகளை மட்டும் கூறுக" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "(_f) தேடல் பதில் கிடைத்தபோது கூறுக" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "காற்புள்ளி" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "விசை பிணைப்பு" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "முன்னிருப்பு" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "எழுதும் முறைமை" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "செக்ஷன்" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ப்ரெய்லி எழுத்து முறை பிணைப்பு" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "புத்தகக்குறிகளை சேமி" - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "நேரம் மற்றும் தேதி" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "அட்டவணை உலாவல்" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "கட்டற்றது" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "தட்டை ஆய்வில் இருந்து வெளி செல்கிறது" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "மாற்றப்பட்டது" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_D பணிமேடை" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "அறிவிப்பு" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "அறிவிப்பு %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s க்கு ஆர்கா விருப்பங்கள்" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "ப்ரெயில் இல் குறிக்கவும்" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "உள்ளது, இல்லாவிடில்" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "பேசு" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "உருவரையை சங்கடம் என சேமி" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "பயனர் உருவரை முரண்பாடு!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"வரையுரு %s ஏற்கெனெவே உள்ளது.\n" -"இருக்கிற வரையுருவை புதிய மாற்றங்களுடன் மேம்படுத்தலாமா?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "பயனர் உருவரையை ஏற்று" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"நீங்கள் இப்போது செயலில் உள்ள வரையுருவை மாற்ற \n" -"உள்ளீர்கள். நீங்கள் இப்போதுதான் உங்கள் தேர்வுகளை \n" -"மாற்றி இருந்தால், அவை வரையுரு ஏற்றும்போது கைவிடப்படும்.\n" -"\n" -" முந்தைய மாற்றங்களை தள்ளி வரையுருவை ஏற்றலாமா?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "உருவரையை இப்படி சேமி" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_P உருவரை பெயர்:" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "பயனர் உருவரையை ஏற்று" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "அனைத்தும்" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "பயன்பாடு" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "சாளரம்" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "ஒன்றுமில்லை (_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "சில (_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "(_o) அனேகமாக அனைத்தும்" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "வரி" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "வாக்கியம்" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "பெரும்குறி" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "பொத்தான்" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "தலைப்பு" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "தேர்வுபெட்டி" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "சேர்க்கை பெட்டி" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "விவரணம்" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "தலைப்பு" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "உள்ளார்ந்த சட்டம்" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "படம்" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "விளக்கச்சீட்டு" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "வர்த்தக சின்னம்" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "மட்டம்" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "இணைப்பு" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "பட்டியல்" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "பட்டியல்உருப்படி" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "பொருள்" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "பத்தி" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "தேர்வுபொத்தான்" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "பங்கு" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "தேர்ந்தெடுக்கப்பட்ட உருப்படி" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "நிலை" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "உரை" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "யூஆர்ஐ" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "மதிப்பு" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "பெரு மேற்கோள்கள் " - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "பொத்தான்கள்" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "தேர்வுபெட்டிகள்" - -#: src/cthulhu/guilabels.py:706 -#, fuzzy -msgctxt "structural navigation" -msgid "Clickables" -msgstr "அட்டவணைகள்" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "சேர்க்கை பெட்டிகள்" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "உள்ளீடுகள்" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "படிவ புலங்கள் " - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr " தலைப்புகள்" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "உள்ளார்ந்த சட்டம்" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "படம்" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "அடுக்கு %d இல் தலைப்புகள் " - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "வர்த்தக சின்னம்" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "பெரிய பொருட்கள்" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "இணைப்புகள்" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "பட்டியல்கள்" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "பட்டியல்உருப்படிகள்" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "பத்திகள்" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "தேர்வுபொத்தான்கள்" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "அட்டவணைகள்" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr " முன்னம் பார்க்காத தொடுப்புகள்" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "முன்னம் பார்த்த தொடுப்புகள்" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "பக்கம் உலாவல்" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "(_l) முதன் முறை ஒரு பக்கம் ஏற்றப்பட்ட போது தானியங்கியாக பேச ஆரம்பி" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "(_l) முதன் முறை ஒரு பக்கம் ஏற்றப்பட்ட போது தானியங்கியாக பேச ஆரம்பி" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "பேச்சை இடைவெளிக்களுக்குளான தொகுதிகளாக பிரி" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s முன்னிருப்பு குரல் " - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "முன்னிருப்பு" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "மீஇணைப்பு" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "கணினி" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "மேல் நிலை எழுத்து" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "ஸ்பீச் டிஸ்பேச்சர்" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "ஸ்பெரட் ஷீட் அறை ஆயத்தொலவுகளை கூறுக" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "(_h) அறை தலைப்பை அறிவிக்க" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "அட்டவணை உலாவல்" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "(_b) வெற்று அறைகளை தவிர்க்கவும்" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "_c அறையை பேசு" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "(_c) அறையின் ஆயத்தொலைவுகளை கூறு" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "(_m) பல அறை வீச்சை கூறு" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "பண்புக்கூறு பெயர்" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "(_O) ஆர்கா காரட் உலாவலை பயன்படுத்து" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "அமைப்பு உலாவல் விசைகளை மாற்றுகிறது. " - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "சுருக்கம் (_f)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "அறிவிப்பு" -msgstr[1] "அறிவிப்பு" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "ஷிப்ட்" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "ஆல்ட் " - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "கன்ட்ரோல்" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "இடது ஷிப்ட்" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "இடது ஆல்ட்" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "இடது கன்ட்ரோல்" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "வலது ஷிப்ட்" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "வலது ஆல்ட்" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "வலது கன்ட்ரோல்" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "இடது மெடா" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "வலது ஆல்ட்" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "எண் பூட்டு " - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "தலைப்பெழுத்து பூட்டு" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "தலைப்பெழுத்து பூட்டு" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "சுருள் பட்டை" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "பக்கம்" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "பக்கம் கீழே" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "இடது டேப்" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "பின் செல்" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "அடுத்து" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "உள்ளிடு" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "மெலே" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "கீழே" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "இடது ஆல்ட்" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "வலது ஆல்ட்" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "இடது சூப்பர்" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "வலது சூப்பர்" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "பட்டியல்" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "உதவி" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "பல" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "முறைமை மாற்றி" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "விடுபடு" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "இடை செருகு" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "நீக்கு" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "இல்லம்" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "முடிவு" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "ஆரம்பம்" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "வளையம்" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "ஸ்ட்ரோக்" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "mnu" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "இடை செருகு" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "தலைப்பெழுத்து பூட்டு (_L)" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "வலது ஆல்ட் " - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "சூப்பர்" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "மெடா2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "இடது ஆல்ட் " - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "கன்ட்ரோல் " - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "ஷிப்ட்" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "தடிமனான" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "வலம் சாய்ந்த" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "கீழொட்டு %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "கீழொட்டு %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "பணி இடம்" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "சூழல் %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "இடது அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "வலது அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "வலது அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "வலது அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "வலது அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "இடது அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "இடது அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "வலது அம்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "இடது இரட்டை மேற்கோள்" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "இரட்டை கத்தி" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "வலது இரட்டை மேற்கோள்" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "இரட்டை கத்தி" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "வலது இரட்டை மேற்கோள்" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "வலது சுட்டும் அம்பு" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "வலது சுட்டும் அம்பு தலை" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "mnu" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "குறைவு" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "அதிகம்" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "ஸர்க்ளம்ப்லெக்ஸ்" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "புள்ளி" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "செங்குத்து ஒழுங்கீடு " - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "சரி விகிதம்" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "தானியங்கி நிறைவு" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "வெற்று" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "செயலாக்கப்பட்டது" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "வரியின் முடிவு." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "துணை" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "கூட்டல் அல்லது கழித்தல்" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "கூட்டல்" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "mnu" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "பிரிப்பி" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "வர்க மூலம்" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "க்யூப் ரூட்" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "வர்க மூலம்" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "சரி விகிதம்" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "எண்ணற்ற" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "வலது ஆல்ட்" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "தனி" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "அடுக்கிட்ட பலகம்" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "செங்குத்து ஒழுங்கீடு " - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "வகுத்தல்" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "பிரிப்பி" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "சமமல்ல" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "தருக்கரீதியாக இல்லை" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "தருக்கரீதியாக இல்லை" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "திசை" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "உள்ளார்ந்த சட்டம்" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "இரட்டை முதன்மை" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "சரி விகிதம்" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "mnu" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "டில்டே" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "என் டில்டே" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "என் டில்டே" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "ஏறக்குறைய சமம்" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ஏறக்குறைய சமம்" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "ஏறக்குறைய சமம்" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "ஏறக்குறைய சமம்" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ஏறக்குறைய சமம்" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "ஏறக்குறைய சமம்" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "மூன்று சொடுக்கு" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "ஏறக்குறைய சமம்" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "வேறு இடம்" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "சமமல்ல" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "சமம்" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "சமம்" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "சமமல்ல" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "சமமல்ல" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "முக்கோண புல்லட்" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "சமம்" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "சமமல்ல" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "சமமல்ல" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "முனையம்" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "சமமல்ல" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "சமமல்ல" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "அதிகம்" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "அழுத்தாதது" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr " தேர்ந்தெடுக்கப்படவில்லை" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "கீழொட்டு 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "மேலெழுத்து எ" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "பல் தேர்வு " - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "சீரமைப்பு" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "பல் தேர்வு " - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "வர்க மூலம்" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "வர்க மூலம்" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "வர்க மூலம்" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "வர்க மூலம்" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "கீழொட்டு =" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "என் கோடு" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "கீழொட்டு +" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "கீழொட்டு -" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "வர்க மூலம்" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "வர்க மூலம்" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "வலது ஆல்ட்" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "இடது டேப்" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "கீழே" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "செக்ஷன்" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "உண்மை" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "உண்மை" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "அழை" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "படம்" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "பல" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "உள்ளார்ந்த சட்டம்" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "இயல்பான" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "வலது ஒற்றை மேற்கோள்" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "வலது முள் அடைப்புக்குறி" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "பிரிப்பி" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "தருக்கரீதியாக இல்லை" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "தருக்கரீதியாக இல்லை" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "இரட்டை முதன்மை" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "இரட்டை முதன்மை" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "திசை" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "இரட்டை முதன்மை" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "குறைவு அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "அதிகமான அல்லது சமம்" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "செங்குத்து ஒழுங்கீடு " - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "இடது அடைப்பு" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "வலது அடைப்பு" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "இடது ஆல்ட்" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "வலது ஆல்ட்" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "இடது முள் அடைப்புக்குறி" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "கீழ்" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "இடது இரட்டை அம்பு அடைப்புக்குறி" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "வலது இரட்டை அம்பு அடைப்புக்குறி" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "நடு புள்ளி" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "தேடல் திசை:" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "வர்க மூலம்" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "கருப்பு சதுரம்" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "வெள்ளை சதுரம்" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "கருப்பு வைரம்" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "வெள்ளை வட்டம்" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "கருப்பு வட்டம்" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "வெள்ளை புல்லட்" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "கருப்பு சதுரம்" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "அடிக்கோடு" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "செங்குத்து ஒழுங்கீடு " - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "பயன்பாடு" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "வெற்று" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "தடிமனான" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "புத்தகக்குறி உள்ளிடப்பட்டது" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "புத்தகக்குறிகள் சேமிக்கப்பட்டன" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "புத்தகக்குறிகள் சேமிக்கப்பட முடியவில்லை" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "புத்தகக் குறி மேலும் இல்லை." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "புத்தகக் குறி மேலும் இல்லை." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "தவிர்ப்பு முறைமையை செயல்படுத்து." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "கணிப்பு பொறியை பெற முடியவில்லை" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "சின்னம்" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "எழுத்து மேல்நிலை பாங்கு சின்னத்துக்கு அமைக்கப்பட்டது" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "எதுவும் இல்லை" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "எழுத்து மேல்நிலை பாங்கு எதற்கும் அமைக்கப்படவில்லை" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "சொல்லு" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "எழுத்து மேல்நிலை பாங்கு சொல்வதற்கு அமைக்கப்பட்டது" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "கெக்கோ காரட் ஐ கட்டுப்படுத்துகிறது." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "ஆர்கா காரட் ஐ கட்டுப்படுத்துகிறது." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "அறை %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "தேர்ந்தெடுக்கப்பட்டது" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr " தேர்ந்தெடுக்கப்படவில்லை" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "தேர்வு நீக்கப்பட்டது" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "தேர்வை பயன்படுத்துவதை த்டை செய்க" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "தேர்வை கட்டாயப்படுத்து" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPTION" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "பின்வருவன செல்லுபடியாகாதன:" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "இயங்கும் தெரிந்த நிரல்களை அச்சிடுகிறது" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "உருவரையை ஏற்று" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "உருவரையை ஏற்ற முடியவில்லை:%s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "மேல்மேசைக்கு தொடர்பில்லாததால் ஆர்காவை துவக்க முடியாது" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -#, fuzzy -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"இந்த அமர்வுக்கு இன்னொரு ஆர்கா செயல் இய்ங்கிக்கொண்டு இருக்கிறது. \n" -"இதை நிறுத்தி புதியதை இயக்க \"cthulhu --replace\" ஐ இயக்கவும்." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "பயனர் முன்னுரிமை அமைப்புக்கு மாற்று அடைவை பயன்படுத்துக" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "இயங்கும் தெரிந்த நிரல்களை அச்சிடுகிறது" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "தற்போது இயங்கும் ஆர்காவை மாற்று" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "இந்த உதவி செய்தியை காட்டவும்" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "debug-YYYY-MM-DD-HH:MM:SS.out கோப்புக்கு வழு நீக்கு வெளியீட்டை அனுப்புக" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "குறிப்பிட்ட கோப்புக்கு வழு நீக்கு வெளியீட்டை அனுப்புக" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FILE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "பயனர் முன்னுரிமைகளை அமை (உரை பதிப்பு)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "பயனர் முன்னுரிமைகளை அமை (உரை பதிப்பு)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "பிழைகளை https://groups.io/g/stormuxல் அறிக்கையிடவும்." - -#: src/cthulhu/messages.py:325 -#, fuzzy -msgid "Cut selection to clipboard." -msgstr "உள்ளடக்கத்தை ஒட்டுப்பலகைக்கு பிரதி எடுத்த" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "அக்யூட்" - -#: src/cthulhu/messages.py:337 -#, fuzzy -msgid "Copied selection to clipboard." -msgstr "உள்ளடக்கத்தை ஒட்டுப்பலகைக்கு பிரதி எடுத்த" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -#, fuzzy -msgid "Pasted contents from clipboard." -msgstr "உள்ளடக்கத்தை ஒட்டுப்பலகைக்கு பிரதி எடுத்த" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "வேகமாக." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "நண்பர்கள் தட்டச்சும்போது தெரிவிக்காதே" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "நண்பர்கள் தட்டச்சும்போது தெரிவி" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "அரட்டை அறை %s இலிருந்து செய்தி" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "புதிய அரட்டை தத்தல் %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "அரட்டை அறை பெயரை பேசாதே" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "அரட்டை அறை பெயரை பேசு" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "அரட்டை அறை குறிப்பான வரலாற்றை தராதே." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "அரட்டை அறை குறிப்பான வரலாற்றை தருக" - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "தேர்வு சுட்டி" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "நீக்கு" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "இடை செருகு" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "வினா" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "அட்டவணை முடிந்தது" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "பட்டியலில் இல்லை." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr " தேர்ந்தெடுக்கப்படவில்லை" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "முன்னிருப்பு பொத்தான் %s " - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "முன்னிருப்பு பொத்தான் %s " - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "முன்னிருப்பு பொத்தான் %s " - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "கீழொட்டு %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "மேலெழுத்து %s" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "பட்டியலில் இல்லை." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "முழு ஆவணம் தேர்ந்தெடுக்கப்பட்டது" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "முழு ஆவணம் தேர்ந்தெடுக்கப்பட்டது" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து தேர்ந்தெடுக்கப்பட்ட ஆவணம்" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து தேர்வு நீக்கப்பட்ட ஆவணம்" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "நிலைகாட்டி இடத்திற்கு தேர்ந்தெடுக்கப்பட்ட ஆவணம்" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "நிலைகாட்டி இடத்திற்கு தேர்வு நீக்கப்பட்ட ஆவணம்" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "இயங்கு பத்தி %d க்கு வரி தலைப்பு அமை " - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "இயங்கு பத்தி தலைப்பு நிரல் நீக்கப்பட்டது" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "இயங்கு வரி தலைப்பு பத்தி %s க்கு அமைக்கப்பட்டது" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "இயங்கு வரி தலைப்பு சுத்தப்படுத்தப்பட்டது" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "வெற்று" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f கிலோபைட்டுகள்" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f மெகாபைட்டுகள்" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "கோப்புகள் ஏதும் பிடிக்கப் படவில்லை" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "உள்ளடக்கத்தை ஒட்டுப்பலகைக்கு பின் சேர்த்தது" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "உள்ளடக்கத்தை ஒட்டுப்பலகைக்கு பிரதி எடுத்த" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "தட்டை ஆய்வு பாங்கை பயன்படுத்தவில்லை" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "தட்டை ஆய்வு பாங்கில் செல்கிறது" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "தட்டை ஆய்வில் இருந்து வெளி செல்கிறது" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "தட்டை ஆய்வை தற்போதைய சொல்லுக்கு மேலுள்ள சொல்லுக்கு நகர்த்துகிறது." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "சூத்திரத்தை கொண்டுள்ளது" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "உரையாடல்" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "மேல்மீட்பு பட்டி" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "வரைபட பட இணைப்பு" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "உள்ளிட்ட விசை %s க்கு ஏற்கெனவே பிணைக்கப்பட்டது." - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "அமைத்த விசை: %s. உறுதி செய்ய உள்ளிடு விசையை அழுத்துக " - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "புதிய விசை: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "நிறுவல் முடிந்தது. எண்டர் விசையை அழுத்தி தொடரவும்" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "விசை பிணைப்பு நீக்கப்பட்டது" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "புதிய விசையை உள்ளிடு" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "விசை" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "விசை எதிரொலிப்பு விசை க்கு அமைக்கப்பட்டது." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "ஒன்றுமில்லை" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "விசை எதிரொலிப்பு ஏதுமில்லை க்கு அமைக்கப்பட்டது." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "விசை மற்றும் சொல்" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "விசை எதிரொலிப்பு விசை மற்றும் சொல் க்கு அமைக்கப்பட்டது." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "வாக்கியம்" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "விசை எதிரொலிப்பு வாக்கியத்துக்கு அமைக்கப்பட்டது." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "சொல்" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "விசை எதிரொலிப்பு சொல்லுக்கு அமைக்கப்பட்டது." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "சொல் மற்றும் வாக்கியம்" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "விசை எதிரொலிப்பு சொல் மற்றும் வாக்கியத்துக்கு அமைக்கப்பட்டது." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "கருப்பு வட்டம்" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "சரி விகிதம்" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "செங்குத்து கோல்" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "வலது அம்புக்குறி" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "கீழுக்கு மடிகிறது " - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "கோடு உயரம்" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "மற்றும்" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "மேல்வரி" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "வர்க மூலம்" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "க்யூப் ரூட்" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "மூல பலகம்" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "மூல பலகம்" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "மூல பலகம்" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "கீழொட்டு 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "மேலெழுத்து எ" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "கீழொட்டு 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "மேலெழுத்து எ" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "மேலெழுத்து எ" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "மேலெழுத்து எ" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "அட்டவணை" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "கிளை அட்டவணை" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "அணுக முடியவில்லை" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "செயல்நீக்கப்பட்டது" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "உள்ளடக்கம் மற்றும் ஒழுங்கு இவற்றை சொல்லுவதை செயல் நீக்குகிறது" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "செயலாக்கப்பட்டது" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "உள்ளடக்கம் மற்றும் ஒழுங்கு இவற்றை சொல்லுவதை செயலாக்குகிறது" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "கற்கும் முறை. வெளியேற விடுபடு விசையை அழுத்தவும்." - -#: src/cthulhu/messages.py:1201 -#, fuzzy -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"கற்கும் முறைக்கு நுழைகிறது. எந்த விசையின் பயன்பாட்டையும் அறிய அந்த விசையை அழுத்துக. " -"எல்லா ஓர்கா முன்னிருப்பு குறுக்கு விசைகளின் பட்டியலை பெற 1 ஐ அழுத்துக; நடப்பு நிரலின் " -"ஓர்கா குறுக்கு விசைகளின் பட்டியலை பெற 2 ஐ அழுத்துக. ஆவணங்களை காண எஃப் 1 ஐ அழுத்துக. " -"கற்கும் முறையிலிருந்து வெளியேற எஸ்கேப் விசையை அழுத்தவும்." - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "அசைவூட்டம்" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "பக்கம் உலாவல்" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "அட்டவணை உலாவல்" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "தட்டை ஆய்வில் இருந்து வெளி செல்கிறது" - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "அட்டவணையை விட்டு வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து கீழே தேர்ந்தெடுக்கப்பட்ட வரி" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து மேலே தேர்ந்தெடுக்கப்பட்ட வரி" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து கீழே தேர்வு நீக்கப்பட்ட வரி" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து மேலே தேர்வு நீக்கப்பட்ட வரி" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "கற்கும் முறையிலிருந்து வெளியேறுகிறது." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து மேலே தேர்ந்தெடுக்கப்பட்ட வரி" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து கீழே தேர்ந்தெடுக்கப்பட்ட வரி" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "இணைப்பு" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "அதே பக்கம்" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "அதே இடம்" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "வேறு இடம்" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s இணைப்பு %(file)s க்கு " - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s இணைப்பு" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d முன்னம் பார்த்த தொடுப்பு " - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"பட்டியலில் மேலே கீழே போக மேலே, கீழே அம்புக்குறிகளை பயன்படுத்துக. வெளியேற விடுபடு " -"விசையை அழுத்தவும்." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "நிகழ்விடங்கள் நீக்கியதாக அமை." - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "நிகழ்விட மரியாதை மட்டங்கள் மீட்டமைக்கப்பட்டன" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "மரியாதை மட்டம் %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "நிகழ்விடத்தை உறுதி என அமைக்க" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "நிகழ்விடம் செயல்நீக்கு" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "நிகழ்விடத்தை மரியாதை என அமைக்க " - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "நிகழ்விடத்தை மரியாதை கெட்ட என அமைக்க" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "நிகழ்விட கண்காணிப்பு விலக்கு" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "நிகழ்விட கண்காணிப்பு இயக்கு" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "நிகழ் செய்திகள் இல்லை" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "நிகழிடம் ஆதரவு நீக்குக" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "காணவில்லை" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "தற்போதைய இடத்தை கண்டுபிடிக்க முடியவில்லை" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "நிறுத்து" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "இயக்கு" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "தவறான எழுத்துக் கோவை உள்ள சொல்" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "பிழையாக எழுதிய சொல்: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "சூழல் %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -#, fuzzy -msgid "Focus mode" -msgstr "பட்டியல் சுருக்கு வழிகள் முறை" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -#, fuzzy -msgid "Layout mode." -msgstr "பட்டியல் சுருக்கு வழிகள் முறை" - -#: src/cthulhu/messages.py:1785 -#, fuzzy -msgid "Object mode." -msgstr "பொருள்" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "அடுத்த பொருளுக்கு செல்கிறது." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "சொடுக்கியால் உயிர்ப்புரும் உருப்படி காணப்படவில்லை" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "சொடுக்கி அதிகரிப்புகள் முடங்கின." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "சொடுக்கி அதிகரிப்புகள் செயலாயின." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "பிழை! பொருட்களின் பட்டியலை உருவாக்க முடியவில்லை." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d சதவீதம்" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "முந்தைய சொல்லுக்கு செல்கிறது." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "கிளை நிலை %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "புதிய உருப்படி சேர்க்கப்பட்டது." - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "எந்த பயன்பாடும் குவிப்பில் இல்லை" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "குவிப்பு இல்லை" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "எந்த பயன்பாடும் குவிப்பில் இல்லை" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "பெரு மேற்கோள் ஏதும் இனி இல்லை" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "பொத்தான் மேலுமில்லை" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "தேர்வு பெட்டி மேலும் இல்லை" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "பெரிய பொருட்கள் ஏதும் இனி இல்லை" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "மேலும் அட்டவணைகள் இல்லை" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "கூட்டுப்பெட்டி மேலும் இல்லை" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "உள்ளீடு மேலும் இல்லை." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "படிவ புலங்கள் ஏதும் இனி இல்லை" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "மேலும் தலைப்புகள் இல்லை" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "அடுக்கு %d இல் மேலும் தலைப்புகள் இல்லை" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "உள்ளார்ந்த சட்டம்" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "மேலும் அட்டவணைகள் இல்லை" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "புத்தகக் குறி மேலும் இல்லை." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "மேலும் தொடுப்புகள் இல்லை" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "மேலும் பட்டியல்கள் ஏதும் இனி இல்லை" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "பட்டியல் உருப்படி மேலும் இல்லை" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr " மேலும் நிகழ்விடம் இல்லை" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "பத்திகள் மேலும் இல்லை" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "தேர்வு பொத்தான் மேலும் இல்லை" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "பிரிப்பான்கள் மேலும் இல்லை" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "மேலும் அட்டவணைகள் இல்லை" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "மேலும் முன்னம் பார்க்காத தொடுப்புகள் ஏதும் இனி இல்லை" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "மேலும் முன்னம் பார்த்த தொடுப்புகள் ஏதும் இனி இல்லை" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "தேர்ந்தெடுக்கப்படவில்லை" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "மேலும் தொடுப்புகள் இல்லை" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "அறிவிப்பு" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "கீழ்" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "மேல்" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "அறிவிப்பு செய்திகள் ஏதும் இல்லை" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "சொல்" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "Speak multicase strings as wor_ds" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "இயக்கமில்லை" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "இயக்கத்தில்" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "ஏற்றுகிறது. தயைசெய்து காத்திருக்கவும்." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "ஏற்றல் முடிந்தது " - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s. ஐ ஏற்றல் முடிந்தது " - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து தேர்ந்தெடுக்கப்பட்ட பக்கம்" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "நிலைகாட்டி இடத்திற்கு தேர்ந்தெடுக்கப்பட்ட பக்கம்" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து தேர்வு நீக்கப்பட்ட பக்கம்" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "நிலைகாட்டி இடத்திற்கு தேர்வு நீக்கப்பட்ட பக்கம்" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து கீழே தேர்ந்தெடுக்கப்பட்ட பத்தி" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து மேலே தேர்ந்தெடுக்கப்பட்ட பத்தி" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து கீழே தேர்வு நீக்கப்பட்ட பத்தி" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "நிலைகாட்டி இடத்திலிருந்து மேலே தேர்வு நீக்கப்பட்ட பத்தி" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"நீங்கள் ஆர்கா தேர்வுகள் உரையாடல் ஒன்றை ஏற்கெனவே திறந்து உள்ளீர். \n" -" புதிய உரையாடலை துவக்கு முன் அதை மூடவும்.." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "காட்சிவில்லை %(position)d %(count)d இல்" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "வரியுரு %s க்கு அமைக்கப்பட்டது." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "வரியுருக்கள் ஏதும் காணப் படவில்லை" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "%d முன்னேற்ற பட்டை" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "அனைத்தும்" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "நிறுத்தற்குறி நிலை எல்லாவற்றுக்கும் என அமைக்கப்பட்டது" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "அனேகமாக அனைத்தும்" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "நிறுத்தற்குறி நிலை அனேகமாக அனைத்தும் என அமைக்கப்பட்டது" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "ஒன்றுமில்லை" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "நிறுத்தற்குறி நிலை ஏதுமில்லை என அமைக்கப்பட்டது" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "சில" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "நிறுத்தற்குறி நிலை சில என அமைக்கப்பட்டது" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "தேடுகிறது." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "தேடல் முடிந்தது" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "ஆர்கா பயனர் அமைவுகள் மீண்டும் ஏற்றப்பட்டது." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "தேர்ந்தெடுக்கப்பட்ட உருப்படி" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "வரி நீக்கப்பட்டது." - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "தேர்வு சுட்டி" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "தேர்வு நீக்கப்பட்டது" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "குரலை செயல்நீக்கு" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "குரலை செயல்படுத்து." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "வேகமாக." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "மெதுவாக." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "உயர்ந்த." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "குறைந்த." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "வேகமாக." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "விகிதம்: (_R)" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "ஒலி அளவு: (_l)" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "ஸ்பீச் டிஸ்பேச்சர்" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "ஸ்பீச் டிஸ்பேச்சர்" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "சேவையங்கள் எதுவும் இல்லை.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "குரல்கள் எதுவும் இல்லை.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "குரலை செயல்படுத்து." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "குரல் பயன்படுத்த மாட்டாது.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " புள்ளி புள்ளி புள்ளி" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr " ஆர்கா பதிப்பு %s" - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "ஆர்கா காரட் ஐ கட்டுப்படுத்துகிறது." - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "தவிர்ப்பு முறைமையை செயல்படுத்து." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "குரல் இருப்பில் இல்லை" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "காணவில்லை" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "சரம் காணவில்லை" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "சரம் காணவில்லை" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "அமைப்பு உலாவல் விசைகள் இயங்கவில்லை " - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "அமைப்பு உலாவல் விசைகள் இயங்குகிறன " - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "காணவில்லை" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "வரி %(row)d, பத்தி %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "அட்டவணை முடிந்தது" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "அறையை பேசு" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "வரியை பேசு" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "ஒழுங்கு இல்லாத ." - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "பட்டியலில் இல்லை." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "பத்திகள் மீட்டு அமைக்கப்பட்டன" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "வரிகள் மீட்டு அமைக்கப்பட்டன" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "பத்தி %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "பத்தி %(index)d, %(total)d இல்" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "பத்தியின் கீழ் பாகம்." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "பத்தியின் மேல் பாகம்." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "தேர்வு நீக்கப்பட்டது" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "தேர்வு நீக்கப்பட்டது" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "நிரை %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "வரி %(index)d, %(total)d இல்" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "வரியின் ஆரம்பம்." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "வரியின் முடிவு." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "வரி நீக்கப்பட்டது." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "கடைசி வரி நீக்கப்பட்டது." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "வரி செருகப்பட்டது." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "பட்டியலின் இறுதியில் வரி சொருகப்பட்டது." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "வரி நீக்கப்பட்டது." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "தேர்வு நீக்கப்பட்டது" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "தேர்ந்தெடுக்கப்பட்டது" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "தேர்வு நீக்கப்பட்டது" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H மணிகள் %M நிமிடங்கள் மற்றும் %S வினாடிகள். " - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H மணிகள் மற்றும் %M நிமிடங்கள்" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "யூனிகோட் %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr " ஆர்கா பதிப்பு %s" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "வெள்ளை இடைவெளி" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "கீழுக்கு மடிகிறது " - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "மேலுக்கு மடிகிறது " - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 உருப்படி" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "அறை வீச்சு %d வரி " -msgstr[1] "அறை வீச்சு %d வரிகள்" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d பத்தி " -msgstr[1] "%d பத்திகள் " - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "அறை வீச்சு %d பத்தி" -msgstr[1] "அறை வீச்சு %d பத்திகள்" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d எழுத்துரு மிக நீளமானது" -msgstr[1] "%d எழுத்துருக்கள் மிக நீளமானவை" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d உரையாடல்)" -msgstr[1] "(%d உரையாடல்கள்)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d குவிப்பில்லா உரையாடல்" -msgstr[1] "%d குவிப்பில்லா உரையாடல்கள்" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d பைட்" -msgstr[1] "%d பைட்கள்" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d கோப்பு கிடைத்துள்ளது" -msgstr[1] "%d கோப்புகள் கிடைத்துள்ளன" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d படிவம்" -msgstr[1] "%d படிவங்கள்" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d தலைப்பு " -msgstr[1] "%d தலைப்புகள்" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d உருப்படி" -msgstr[1] "%d உருப்படிகள்" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "புத்தகக் குறி மேலும் இல்லை." -msgstr[1] "புத்தகக் குறி மேலும் இல்லை." - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d உருப்படி கிடைத்துள்ளது" -msgstr[1] "%d உருப்படிகள் கிடைத்துள்ளன" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "பெரு மேற்கோள் ஏதும் இனி இல்லை" -msgstr[1] "பெரு மேற்கோள் ஏதும் இனி இல்லை" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "தட்டை ஆய்வில் இருந்து வெளி செல்கிறது" -msgstr[1] "தட்டை ஆய்வில் இருந்து வெளி செல்கிறது" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "உருப்படி %d உடன் பட்டியல்" -msgstr[1] "உருப்படிகள் %d உடன் பட்டியல்" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "உருப்படி %d உடன் பட்டியல்" -msgstr[1] "உருப்படிகள் %d உடன் பட்டியல்" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "மதிப்பு" -msgstr[1] "மதிப்பு" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "%d வரியுடன் அட்டவணை" -msgstr[1] "%d வரிகளுடன் அட்டவணை" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d பத்தி " -msgstr[1] "%d பத்தி " - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "%d வரியுடன் அட்டவணை" -msgstr[1] "%d வரிகளுடன் அட்டவணை" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d செய்தி.\n" -msgstr[1] "%d செய்திகள்.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d சதவீதம்" -msgstr[1] "%d சதவீதம்" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "ஆவணத்தில் %d சதவிகிதம் படிக்கப்பட்டது. " -msgstr[1] "ஆவணத்தில் %d சதவிகிதம் படிக்கப்பட்டது. " - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "பிக்ஸல்கள்" -msgstr[1] "பிக்ஸல்கள்" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s எழுத்துரு" -msgstr[1] "%(count)d %(repeatChar)s எழுத்துருக்கள்" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d, %(total)d இல் உருப்படி தேர்ந்தெடுக்கப்பட்டது" -msgstr[1] "%(index)d, %(total)d இல் உருப்படிகள் தேர்ந்தெடுக்கப்பட்டன" - -#: src/cthulhu/messages.py:2793 -#, fuzzy, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d ஆர்கா சுருக்கு வழி முன்னிருப்பாக காணப்பட்டது" -msgstr[1] "%d ஆர்கா சுருக்கு வழிகள் முன்னிருப்பாக காணப்பட்டது" - -#: src/cthulhu/messages.py:2801 -#, fuzzy, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d ஆர்கா சுருக்கு விசை %(application)s நிரல்களுக்கு காணப்பட்டது" -msgstr[1] "%(count)d ஆர்கா சுருக்கு விசைகள் %(application)s நிரல்களுக்கு காணப்பட்டது" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d இடைவெளி" -msgstr[1] "%d இடைவெளிகள்" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d கீற்று" -msgstr[1] "%d கீற்றுகள்" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d அட்டவணை" -msgstr[1] "%d அட்டவணைகள்" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "%d வரியுடன் அட்டவணை" -msgstr[1] "%d வரிகளுடன் அட்டவணை" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%(rows)d வரிகள் மற்றும் %(columns)d பத்திகளுடன் அட்டவணை" -msgstr[1] "%(rows)d வரிகள் மற்றும் %(columns)d பத்திகளுடன் அட்டவணை" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "%d வரியுடன் அட்டவணை" -msgstr[1] "%d வரிகளுடன் அட்டவணை" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "நொடிகள்" -msgstr[1] "நொடிகள்" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d முன்னம் பார்க்காத தொடுப்பு" -msgstr[1] "%d முன்னம் பார்க்காத தொடுப்புகள்" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d முன்னம் பார்த்த தொடுப்பு " -msgstr[1] "%d முன்னம் பார்த்த தொடுப்புகள்" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "மாற்றி" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "வரி %(index)d மீது %(total)d இல்" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "வரி %(index)d, மீது %(total)d இல்" - -#: src/cthulhu/object_properties.py:60 -#, fuzzy, python-format -msgid "item %(index)d" -msgstr "உருப்படி %(index)d மீது, %(total)d இல்" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "LEVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "கிளை நிலை %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "வினா" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "அடுத்த கூட்டுப்பெட்டிக்கு செல்கிறது" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "ஹெச்டிஎம்எல் உள்ளடக்கம்" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "சொல்" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "அரைப்புள்ளி" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "மேல்வரி" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "திசை" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "பத்தி" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "சொல்" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "தள்ளல்" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "திசை" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "தத்தல் பட்டியல்" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "குறி" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "ஹெச்டிஎம்எல் உள்ளடக்கம்" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s level %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "சரி விகிதம்" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "செங்குத்து கோல்" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "சரி விகிதம்" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "செங்குத்து ஒழுங்கீடு " - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "சரி விகிதம்" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "செங்குத்து ஒழுங்கீடு " - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "முறைமை மாற்றி" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "சின்ன பலகம்" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "ஹெச்டிஎம்எல் உள்ளடக்கம்" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "அசை" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "ஹெச்டிஎம்எல் உள்ளடக்கம்" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "அசை" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "தேடுகிறது." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d முன்னம் பார்த்த தொடுப்பு " - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "சுழல் பொத்தான்" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "குறுக்கப்பட்டது" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "விரிவாக்கப்பட்டது" - -#: src/cthulhu/object_properties.py:511 -#, fuzzy -msgid "has long description" -msgstr "விவரணம்" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "சரி விகிதம்" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "முனையம்" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "சோதிக்கப்பட்டது" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "சோதிக்காதது" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "இயக்கத்தில்" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "இயக்கமில்லை" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "முழுமையாக சோதிக்காதது" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "அழுத்தியது" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "அழுத்தாதது" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "தேர்ந்தெடுக்கப்படவில்லை" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "தேர்வுசெய்தது" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "தேர்ந்தெடுக்கப்படவில்லை" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "தேர்ந்தெடுக்கப்படவில்லை" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr " முன்னம் பார்த்தது" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr " முன்னம் பார்க்காதது" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "சாம்பல் நிறமிடப்பட்டது" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "படிக்க மட்டும் " - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "rdonly" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "அவசியம்" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "பல் தேர்வு " - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "செல்லுபடியாகாத" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "செல்லுபடியாகாத" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "spelling" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "spelling" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "செல்லுபடியாகாத" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "சாளரம்" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "ஆர்கா திரை படிப்பி மற்றும் பெரிதாக்கி" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "மூடு" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "சாளரம்" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "(_S) இதற்காக தேடுக:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "இதற்கு தேடுக:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "(_T) சாளரம்" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "சாளரத்தின் மேல் பாகம்" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "இங்கிருந்து ஆரம்பி:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "(_W)மடிந்து வருதல்" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "(_b) தேடல் பின்னே" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "தேடல் திசை:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "(_M) பொருத்த நிலை" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "(_e) உள்ளிடும் வார்தையை மட்டும் பொருத்து" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "தேடல் தேர்வுகள்" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "முன்னிருப்பு" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "மேல்நிலை எழுத்து" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "மீ இணைப்பு" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "கணினி" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "பயன்பாடு" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "சாளரம்" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "ஆர்கா விருப்பங்கள்" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "(_L) மடிக்கணினி" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "விசைப்பலகை இடஅமைவு" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_P செயலில் உள்ள உருவரை" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "உருவரை துவக்கு:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_L ஏற்று" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -#, fuzzy -msgid "Save _As" -msgstr "உருவரையை இப்படி சேமி" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "வரியுருக்கள்" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "(_P) தற்போதைய கருவிசுட்டிகள்" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "_u சொடுக்கி கீழ் உள்ள பொருளை கூறுக" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "சொடுக்கி" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_T நேர ஒழுங்கு:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "_e தேதி ஒழுங்கு" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "நேரம் மற்றும் தேதி" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "(_S) அனைத்தையும் பேசு" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "ப்ரெய்லி சுட்டிக்காட்டி" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "அதிர்வெண் (வினாடிகள்):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "பயன்பாடு" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "முன்னேற்ற பட்டை இற்றைப்படுத்தல்" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "அமைப்பு உலாவல் விசைகளை மாற்றுகிறது. " - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "(_y) அனைத்தையும் இதால் சொல்:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "(_y) அனைத்தையும் இதால் சொல்:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "பொது" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "ஒலி அளவு: (_l)" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "தொனி (_t):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "விகிதம்: (_R)" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "நபர்: (_P)" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "மொழி" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "குரல் தொகுப்பி: (_z)" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "குரல் அமைப்பு: (_s)" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "குரல் வகை: (_V)" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -#, fuzzy -msgid "_Capitalization style:" -msgstr "எழுத்து மேல்நிலை பாங்கு சின்னத்துக்கு அமைக்கப்பட்டது" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "பேச்சு வகை அமைவுகள்" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Speak multicase strings as wor_ds" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "உலகளாவிய பேச்சு அமைவுகள்" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "குரல்" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "குரலை செயல்படுத்து (_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "விரிவான விளக்கம்" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "விரிவான விளக்கம்" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "அனைத்தும் (_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "நிறுத்தற்குறி மட்டம்" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "காட்டப்பட்ட உரையை மட்டுமே பேசுக" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "வெற்று வரிகளை பேசு" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "உள்ளடக்கம் மற்றும் நிரப்பலை பேசு (_i)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Spea_k object mnemonics" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "_o சிசு இடத்தை சொல்" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "பயிற்சி செய்திகளை கூறுக " - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "(_c) அறையின் ஆயத்தொலைவுகளை கூறு" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "(_c) அறையின் ஆயத்தொலைவுகளை கூறு" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "விவரணம்" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "பேசிய சூழமைவு" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "குரல்" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "ப்ரெய்லி எழுத்து முறை துணையை செயல்படுத்து (_s)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "சுருக்கப்பட்ட பங்கு பெயர்கள் (_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "(_e) வரி இறுதி குறியை முடமாக்கு " - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "(_T) குறுக்குதல் அட்டவணை:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "(_E) சுருக்கிய ப்ரெய்லியை செயல்படுத்து" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "எல்லைக்கோடு செயல்படுத்து (_d)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "காட்சி அமைவுகள்" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "ஒன்றுமில்லை (_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "தேர்வு சுட்டி" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr " மீஇணைப்பு சுட்டி" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "அளவாக்கியை செயல்படுத்து (_m)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "உலகளாவிய பேச்சு அமைவுகள்" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ப்ரெய்லி எழுத்து முறை" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "விசை எதிரொலிப்பை செயல்படுத்து (_k)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "செயல்பாட்டு விசைகளை செயல்படுத்து (_n) " - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "மாற்றி விசைகளை செயல்படுத்து (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "செயல்பாட்டு விசைகளை செயல்படுத்து (_f) " - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "குரலை செயல்படுத்து (_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "மாற்றி விசைகளை செயல்படுத்து (_m)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "செயல்பாட்டு விசைகளை செயல்படுத்து (_f) " - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "செயல் விசைகளை செயல்படுத்து (_t)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "செயல்பாட்டு விசைகளை செயல்படுத்து (_n) " - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "சொல்லால் எதிரொலிப்பை செயல்படுத்து (_w)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "வாக்கியத்தால் எதிரொலிப்பை செயல்படுத்து (_s)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "விசை எதிரொலிப்பு" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "ஆர்கா திரை படிப்பி மற்றும் பெரிதாக்கி" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "விசை பிணைப்பு" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr " உச்சரிப்பு அகராதி" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "புதிய நுழைவு" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "(_D) நீக்கு" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "உச்சரிப்பு" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "(_S) அனைத்தையும் பேசு" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_n ஏதும் பேசாதே" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "(_R) மீட்டமை" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "உரை பண்புகள்" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "(_b) கீழ் செல்க" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "(_d) ஒரு முறை கீழ் செல்க" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "(_u) ஒரு முறை மேல் செல்க" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "(_t) மேல் செல்க" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "தேர்ந்தெடுத்த பண்புகளை சரிசெய்க" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "ப்ரெய்லி சுட்டிக்காட்டி" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "உரை பண்புகள்" - -#: src/cthulhu/cthulhu-setup.ui:3568 -#, fuzzy -msgid "Enable AI Assistant" -msgstr "உதவியாளர்" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "கீழ்" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -#, fuzzy -msgid "AI Assistant" -msgstr "உதவியாளர்" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "மொழி" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "யென்" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "அளவு காரணி: (_f)" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -#, fuzzy -msgid "Copy Results to _Clipboard" -msgstr "உள்ளடக்கத்தை ஒட்டுப்பலகைக்கு பிரதி எடுத்த" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "பின்னணி நிறம்" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "பின்னணி உயரம்" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "பின்னணி புள்ளிகள்" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "திசை" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "திருத்தவியலும்" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "குடும்ப பெயர்" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "முன்னணி நிறம்" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "முன்னணி புள்ளிகள்" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "எழுத்துரு தோற்றம்" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "தள்ளல்" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "பிழை" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "கண்ணுக்கு தெரியாத" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "சீரமைப்பு" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "மொழி" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "இடது எல்லை" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "கோடு உயரம்" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "பத்தி பாங்கு" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "வரிகள் மேல் படத் துணுக்குகள்" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "வரிகள் கீழ் படத் துணுக்குகள் " - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "மடிப்புக்கு உள் படத் துணுக்குகள்" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "வலது எல்லை" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "மேலெழும்புதல்" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "அளவு கோல்" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "அளவு" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "இழுவை" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "உரை அடித்தல்" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "பாங்கு" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "உரை அலங்காரம்" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "உரை திருப்பம்" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "உரை நிழலிடுகை" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "அடிக்கோடு" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "பேதம்" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "செங்குத்து ஒழுங்கீடு " - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "கனம்" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "மடிப்பு முறைமை" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "எழுதும் முறைமை" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "உண்மை" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "தவறு" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "எதுவும் இல்லை" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "செதுக்கு" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "பதி" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "உருவரை" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "மேல்வரி" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "கோடு" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "சிமிட்டல்" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "கருப்பு" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "தனி" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "இரட்டிப்பு" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "கீழ்" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "உரு" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "சொல்" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "சொல் உரு" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "இடவலம்" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "வலஇடம்" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "இடது" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "வலது" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "நடு" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "no justification" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "நிரப்பு" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ரத்தின சுருக்கம்" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "மேலும் சுருக்கிய" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "சுருக்கிய" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "பகுதி சுருக்கிய" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "இயல்பான" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "பகுதி விரிவாக்கப்பட்டது" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "விரிவாக்கப்பட்டது" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "மேலும் விரிவாக்கப்பட்டது" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "மிக்க விரிவாக்கப்பட்டது" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "சிறுதலை எழுத்து" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "இடம் சாய்ந்த" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "வலம் சாய்ந்த" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "முன்னிருப்பு" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "உரை பகுதி" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "தலைப்பு" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "அடி" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "துணை" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "சூப்பர்" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "மேல்" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "உரை- மேல்" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "மத்திய" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "கீழ்" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "உரை- கீழ்" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "பெற்ற" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "மேலிருந்துகீழ்-இடவலம் " - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "கீழிருந்துமேல்- வலஇடம்" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "கீழிருந்துமேல்-இடவலம்" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "இடவலம்" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "வலஇடம்" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "மேலிருந்துகீழ்" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "solid" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "spelling" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "மாற்ற இடைவெளி விசையை அழுத்து ." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "விரிவாக்க இடைவெளி விசையை அழுத்துக; மற்றும் மேலே கீழே விசைகளால் தேர்வு செய்க." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "துணை சாளரத்துக்கு போக ஆல்ட் + எஃப் 6 விசைகளை அழுத்தவும்." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "To move to items, use either the arrow keys or type ahead searching." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "To get to the system menus press the alt+f1 key." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "ஒரு உருப்படியை பயன்படுத்த மேலே கீழே விசைகளை அழுத்தவும்." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "அனைத்தையும் சுருக்க ஷிப்ட் மற்றும் இடது விசைகளை அழுத்தவும்." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "அனைத்தையும் விரிக்க ஷிப்ட் மற்றும் வலது விசைகளை அழுத்தவும்." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "செயல்படுத்த என்டர் விசையை அழுத்துக." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "வகை உள்ளே உரை." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "இடது மற்றும் வலது விசைகளை மற்ற கீற்றுகளை பார்க்க பயன்படுத்துக." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "செயல்படுத்த இடைவெளி விசையை அழுத்துக." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"மதிப்பை தேர்ந்தெடுக்க அம்பு குறி விசைகளை பயன்படுத்தவும். அல்லது தேவையான எண்ணை " -"உள்ளிடுக.." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "அம்புக்குறி விசைகளை மாற்றுவதற்கு வரை." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"நகர இடது அல்லது வலது அம்புக்குறி விசைகளை அழுத்துக. உருப்படிகளுள் நகர மேல் கீழ் " -"அல்லது விசைகளை பயன்படுத்தவும்." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "துணை பட்டியலுக்கு போக வலது அம்புக்குறி விசை அழுத்தவும்." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"குறைக்க இடது அம்புக்குறி, அதிகமாக்க வலது அம்புக்குறி. குறைந்த பட்சத்துக்கு இல்லம், " -"அதிக பட்சத்துக்கு முடிவு விசை." diff --git a/po/te.po b/po/te.po deleted file mode 100644 index f5f8b45..0000000 --- a/po/te.po +++ /dev/null @@ -1,9849 +0,0 @@ -# translation of cthulhu.HEAD.te.po to Telugu -# Telugu translation of cthulhu -# Copyright (C) 2012 Swecha Telugu translations team -# This file is distributed under the same license as the cthulhu package. -# -# Krishna Babu K , 2008, 2009, 2012. -# A Mohan Vamsee2011. -# Praveen Illa , 2012. -# Sasi bhushan Boddepalli , 2012 -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD.te\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2012-04-17 18:31+0530\n" -"Last-Translator: Sasi Bhushan Boddepalli \n" -"Language-Team: Telugu \n" -"Language: te\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n!=1);\n" -"X-Generator: KBabel 1.11.4\n" - -msgid "Cthulhu Screen Reader" -msgstr "ఓర్కా తెరచదువరి" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "సిజెక్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "స్పానిష్ గ్రేడు" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "కెనడా ఫ్రెంట్ గ్రేడు 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "ఫ్రాన్స్‍ ఫ్రెంచ్ గ్రేడు 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "లాట్విన్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "నెదర్లాండ్స్‍ డచ్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "నార్వేజియన్ గ్రేడు 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "నార్వేజియన్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "నార్వేజియన్ గ్రేడు 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "నార్వేజియన్ గ్రేడు 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "పాలిష్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "పోర్చుగీస్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "స్వీడిష్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "అరబిక్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "వెల్ష్‍ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "వెల్ష్‍ గ్రేడు 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "జెర్మన్ గ్రేడు 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "జెర్మన్ గ్రేడ్ 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "జెర్మన్ గ్రేడు 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "U.K. ఇంగ్లీష్ గ్రేడు 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "U.K. ఇంగ్లీష్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "U.S. ఇంగ్లీష్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "U.S. ఇంగ్లీష్ గ్రేడు 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "కెనడా ఫ్రెంచ్ గ్రేడ్ 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "ఫ్రాన్స్‍ ఫ్రెంచ్ గ్రేడ్ 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "గ్రీక్ గ్రేడ్ 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "హింది గ్రేడ్ 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -#, fuzzy -msgid "Hungarian Grade 1" -msgstr "లాట్విన్ గ్రేడు 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "జెర్మన్ గ్రేడు 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "ఇటాలియన్ గ్రేడ్ 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "బెల్జియమ్ డచ్ గ్రేడ్ 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "ఖాళి" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "కొత్తవరుస" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "టాబ్" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "ఎక్స్‍‌క్లైమ్" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "కోట్" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "సంఖ్య" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "డాలర్" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "శాతం" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "మరియు" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "అపాస్ట్రోఫీ" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "ఎడమ పారెన్" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "కుడి పారెన్" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "స్టార్" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "ప్లస్" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "కామా" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "డాష్" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "డాట్" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "స్లాష్" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "కోలన్" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "సెమీకోలన్" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "లెస్" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "ఈక్వల్స్‍" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "గ్రేటర్" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "క్వశ్చన్" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "ఎట్" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "ఎడమ బ్రాకెట్" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "బ్యాక్‌స్లాష్" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "కుడి బ్రాకెట్" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "కారెట్" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "క్రిందిగీత" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "గ్రేవ్" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "ఎడమ బ్రేస్" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "నిలువు బార్" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "కుడి బ్రేస్" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "టిల్డ్‍" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "ఎలాంటి అంతరాయము కల్పించు ఖాళి లేదు" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "విలోమ అశ్చర్యార్ధక బిందువు" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "సెంట్స్‍" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "పౌండ్స్‍" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "కరన్సీ సంజ్ఞ" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "యెన్" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "విరిగిన బార్" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "భాగము" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "డైరసిస్" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "కాపీరైట్" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "సూపర్‌స్క్రిప్టు a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "ఎడమ డబుల్ ఎంగిల్ బ్రాకెట్" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "లాజికల్ నాట్" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "సాఫ్టు హైఫన్" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "నమోదైన" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "మాక్రోన్" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "‍డిగ్రీలు" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "ప్లస్ లేదా మైనస్" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "సూపర్‌స్క్రిప్ట్‍ 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "సూపర్‌స్క్రిప్ట్‍ 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "ఎక్యూట్" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "పరిచ్ఛేదం గుర్తుంచునది" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "మద్య చుక్క" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "సెడిల్లా" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "సూపర్‌స్క్రిప్ట్‍ 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ఆర్డినల్" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "కుడి డబుల్ యాంగిల్ బ్రాకెట్" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "ఒకటిలో నాలుగవ" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "ఒకటిలో సగం" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "మూటిలో నాలుగవ" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "తిరగబడ్డ ప్రశ్నార్ధకం" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a ఎక్యూట్" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A గ్రేవ్" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ఎక్యూట్" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A సర్‌కమ్‌ఫ్లక్స్‍" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A టిల్డ్‍" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A రింగ్" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C సెడిల్లా" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E గ్రేవ్" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ఎక్యూట్" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E సర్‌కమ్‌ఫ్లెక్స్‍" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I గ్రేవ్" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ఎక్యూట్" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I సర్‌కమ్‌ఫ్లక్స్‍" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N టిల్డ్‍" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O గ్రేవ్" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ఎక్యూట్" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O సర్‌కమ్‌ఫ్లక్స్‍" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O టిల్డ్‍" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "సమయాలు" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O స్ట్రోక్" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U గ్రేవ్" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ఎక్యూట్" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U సర్‌కమ్‌ఫ్లెక్స్‍" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ఎక్యూట్" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "త్రోన్" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s షార్ప్‍" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a గ్రేవ్" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a సర్‌కమ్‌ఫ్లెక్స్‍" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a టిల్డ్‍" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a ఆమ్లోట్" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a రింగ్" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c సె‍డిల్లా" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e గ్రేవ్" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e ఎక్యూట్" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e సర్‌కమ్‌ఫ్లెక్స్‍" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i గ్రేవ్" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i ఎక్యూట్" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i సర్‌కమ్‌ఫ్లెక్స్‍" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n టిల్డ్‍" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o గ్రేవ్" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o ఎక్యూట్" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o సర్‌కమ్‌ఫ్లెక్స్‍" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o టిల్డ్‍" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "దీని ద్వారా విభజించబడింది" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o స్ట్రోక్" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "థ్రోన్" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u ఎక్యూట్" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u గ్రేవ్" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u సర్‌కమ్‌ఫ్లెక్స్‍" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y ఎక్యూట్" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y ఆమ్లౌట్" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "ఫ్లోరిన్" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en డాష్" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "ఎడమ సింగిల్ కోట్" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "కుడి సింగిల్ కోట్" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "సింగిల్ కోట్ తక్కువగా ఉన్నది" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "ఎడమ డబుల్ కోట్" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "కుడి డబుల్ కోట్" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "డబుల్ కోట్ తక్కువగా ఉన్నది" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "డాగ్గర్" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "డబుల్ డాగ్గర్" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "బుల్లెట్" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "త్రికోణ బుల్లెట్" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "ఒక్కో మైలుకి" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "ప్రధాన" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "ద్వంద ప్రధాన" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "ద్వంద ప్రధాన" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "హైఫన్ బుల్లెట్" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "యూరో" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "వ్యాపారగుర్తు" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "చెక్ మార్క్‍" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "భారీ చెక్ మార్క్‍" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x-రూపక బుల్లెట్" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "సూపర్‌స్క్రిప్టు 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "సూపర్‌స్క్రిప్టు 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "సూపర్‌స్క్రిప్టు 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "సూపర్‌స్క్రిప్టు 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "సూపర్‌స్క్రిప్టు 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "సూపర్‌స్క్రిప్టు 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "సూపర్‌స్క్రిప్టు 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "సూపర్‌స్క్రిప్టు ప్లస్" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "సూపర్‌స్క్రిప్టు మైనస్" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "సూపర్‌స్క్రిప్టునకు సరిసమానమైనది" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "సూపర్‌స్క్రిప్టు ఎడమ పారెన్" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "సూపర్‌స్క్రిప్టు కుడి పారెన్" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "సబ్‌స్క్రిప్టు n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "సబ్‌స్క్రిప్టు 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "సబ్‌స్క్రిప్టు 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "సబ్‌స్క్రిప్టు 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "సబ్‌స్క్రిప్టు 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "సబ్‌స్క్రిప్టు 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "సబ్‌స్క్రిప్టు 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "సబ్‌స్క్రిప్టు 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "సబ్‌స్క్రిప్టు 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "సబ్‌స్క్రిప్టు 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "సబ్‌స్క్రిప్టు 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "సబ్‌స్క్రిప్టు ప్లస్" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "సబ్‌స్క్రిప్టు మైనస్" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "సబ్‌స్క్రిప్టునకు సరిసమానమైనది " - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "సబ్‌స్క్రిప్టు ఎడమ పారెన్" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "సబ్‌స్క్రిప్టు కుడి పారెన్" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "నలుపు వర్గం" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "నలుపు వజ్రం" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "తరువాతి అక్షరంకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "సూచికను ప్రస్తుత అంశమునకు మార్గముచేస్తున్నది." - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "ప్రస్తుత సమతల పరిశోదిత అంశంపైన ఎడమ నొక్కను జరుపుము." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "ప్రస్తుత సమతల పరిశోదిత అంశంపైన కుడి నొక్కను జరుపుము." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "మొత్తం పత్రమును మాట్లాడుము." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ వరుసను మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "ప్రాధమిక నేను ఎక్కడ ఉన్నాను కార్యమును జరుపుము." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "విశదీకరణ నేను ఎక్కడ ఉన్నాను కార్యమును జరుపుము." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ వరుసను మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "ఖాళీ వరుసలను మాట్లాడుము" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "తరువాతి బటన్‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "స్థితి పట్టీని మాట్లాడుము." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "శీర్షిక పట్టీని మాట్లాడుము." - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "ఒర్కా యొక్క కనుగోను డైలాగ్‌ను తెరువుము." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "స్ట్రింగ్ యొక్క తరువాతి సంభావన కొరకు శోదిస్తుంది." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "స్ట్రింగ్ యొక్క మునుపటి సంభవం కొరకు అన్వేషిస్తోంది." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "సమతల పరిఅన్వేషణ రీతిని ప్రవేశిస్తుంది మరియు బయటకువస్తుంది." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "సమతల పరిశోదనను ముగింపు స్థానమునకు కదుల్చుతుంది." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "సమతల పరిశోదనను నివాస స్థానమునకు కదుపుతుంది." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "సమతల పరిశోదనను ముగింపు స్థానమునకు కదుల్చుతుంది." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "సమతల పరిఅన్వేషణను మునుపటి వరుస యొక్క మొదటికి కదుపుతుంది." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ వరుసను మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "ప్రస్తుత పరిఅన్వేషణ వరుసను ఉచ్చరిస్తుంది." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ వరుసను ఫోనెటికల్‌గా ఉచ్చరిస్తుంది." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "సమతల పరిఅన్వేషణను తరువాతి వరుస యొక్క మొదటికి కదుల్చుతుంది." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "సమతల పరిఅన్వేషణను మునుపటి అంశముకు లేదా పదముకు కదుల్చుతుంది." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ అంశము లేదా పదంను మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ అంశము లేదా పదంను ఉచ్చరిస్తుంది." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ అంశము లేదా పదంను ఫోనిటికల్‌గా ఉచ్చరిస్తుంది." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "సమతల పరిఅన్వేషణను తరువాతి అంశము లేదా పదముకు కదుపుతుంది." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "సమతల పరిఅన్వేషణను ప్రస్తుత పదంకు పైనఉన్న పదంకు కదుల్చుతుంది." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ ఆబ్జక్టు ను మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "ప్రస్తుత పదముకు క్రిందనఉన్న పదముకు సమతల పరిఅన్వేషణను కదుపుతుంది." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "మునుపటి అక్షరంకు సమతల పరిఅన్వేషణను కదుపుతుంది." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "ప్రస్తుత సమతల పరిశోదన అక్షరంను మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ అక్షరంను ఫోనిటికల్‌గా మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "ప్రస్తుత సమతల పరిశోదన అక్షరంయొక్క యూనికోడ్ గురించి మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "సమతల పరిఅన్వేషణను తరువాతి అక్షరంకు కదుల్చుతుంది." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "సమతల పరిఅన్వేషణను వరుస చిరవరకు కదుపుతుంది." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "సమతల పరిఅన్వేషణను క్రింది ఎడమకు కదుల్చుము." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ అంశము లేదా పదంను మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "ప్రస్తుత సమతల పరిఅన్వేషణ అంశము లేదా పదంను మాట్లాడుతుంది." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "సమతల పరిశోదనను ముగింపు స్థానమునకు కదుల్చుతుంది." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "పట్టిక ప్రస్తుత అరను చదవాలా లేదా మొత్త అడ్డువరసను చదవాలో మార్చుతుంది." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "ప్రస్తుత పాఠము అక్షరంతో కలిసిఉన్న యాట్రిబ్యూట్స్‍‌ను చదువుతుంది." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "బ్రెయిలీ ప్రదర్శనను ఎడమవైపుకు ఉంచుతుంది." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "బ్రెయిలీ ప్రదర్శనను కుడివైపుకు ఉంచుతుంది." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "కీబోర్డు దృష్టితో ఆబ్జక్ట్స్‍ కు తిప్పిపంపుము." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "సంగ్రహించిన బ్రైలీ ఆన్ మరియు ఆఫ్ నకు మార్చుము." - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "ఒక కర్సర్ రూటింగ్ కీని విశ్లేషిస్తుంది." - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "ఎంపిక చేయబడిన పాఠము మొదలు నుండి గుర్తుచేయబడినది." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "ఎంపిక చేయబడిన పాఠము చివర నుండి గుర్తుచేయబడినది." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "అభ్యసించు రీతిలో ప్రవేశించుము. అభ్యసించు రీతినుండి బటయటకు వచ్చుటకు ఎస్కేప్ వత్తుము." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "ఉపన్యాసం దరను తగ్గిస్తోంది." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "ఉపన్యాసం దరను పెంచుతుంది." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "ఉపన్యాసం స్థాయి తగ్గిస్తుంది." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "ఉపన్యాసం స్థాయి పెంచుతుంది." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "ఉపన్యాసం దరను పెంచుతుంది." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "ఉపన్యాసం దరను తగ్గిస్తోంది." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "కావలిసిన ఉపన్యాసం సేవికను ఎంపికచేసుకొనుము." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "కావలిసిన ఉపన్యాసం సేవికను ఎంపికచేసుకొనుము." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "ఉపన్యాసం దరను తగ్గిస్తోంది." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "ఉపన్యాసం దరను పెంచుతుంది." - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "ఉపన్యాసం మౌనంను మార్చుతుంది." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "మౌస్ సమీక్ష పరిశీలనను మార్చుతుంది." - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "ఓర్కా తెరచదువరి" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "అభీష్టాల ఆకృతీకరణ డైలాగ్‌ను ప్రదర్శిస్తుంది." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "అనువర్తనం అభీష్టాల ఆకృతీకరణ డైలాగ్‌ను ప్రదర్శిస్తుంది." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "వరుసక్రమంను మరియు సర్దబాటును మాట్లాడుటను మార్చును." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "తరువాత విరామ స్థాయిని మాట్లాడుటకు ఆవృతంలు." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "తరువాత కీ ప్రతిధ్వని స్థాయినకు ఆవృతంలు." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "తరువాత విరామ స్థాయిని మాట్లాడుటకు ఆవృతంలు." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "తరువాత విరామ స్థాయిని మాట్లాడుటకు ఆవృతంలు." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "తరువాత కీ ప్రతిధ్వని స్థాయినకు ఆవృతంలు." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "నడుస్తున్న సమయములో తనిఖీచేయు స్థాయిని వృత్తీకరించును." - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "ప్రస్తుత స్థానంను అనుసరించి నేను ఎక్కడ ఉన్నాను ను ఇష్టాంశము చేయుము." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "మునుపటి ఇష్టాంశము స్థానమునకు ‌వెళ్ళము." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "ఇష్టాంశము‌కు వెళ్ళుము." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "తరువాతి ఇష్టాంశము స్థానమునకు వెళ్ళుము." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "ఇష్టాంశము‌ జతచేయుము." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "ఇష్టాంశము‌లను దాయుము." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "మౌస్ సమీక్ష పరిశీలనను మార్చుతుంది." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "ప్రస్తుత సమయము." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "ప్రస్తుత తేది." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "ప్రస్తుత కార్యక్షేత్రమునకు తదుపరి ఆదేశమును పంపించుము." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "మునుపటి చాట్ రూమ్ సందేశాన్ని మాట్లాడుము మరియు బ్రెయిలిచేయుము." - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "మన బడ్డీలు టైప్ చేయునప్పుడు మనం ప్రకటించవలెనో లేదో మార్చుము." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "చాట్ రూమ్‌ని విశేషమైన సందేశ చరిత్రలతో మనము చాట్ రూమ్ సందేశాలతో తిరిగిసిద్దపరిస్తే మార్చుము." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "చాట్ రూమ్ పేరుతో మనము చాట్ రూమ్ సందేశాలతో తిరిగిసిద్దపరిస్తే మార్చుము." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "వరుస ఎడమ" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "వరుస కుడి" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "వరుస పైన" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "వరుస క్రింద" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Freeze" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "పైన ఎడమ" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "క్రింది అర్దభాగం" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "కర్సర్ స్థానము" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "ఆరు డాట్‌లు" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "కర్సర్ దారిచూపుట" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "తెంచుట మొదలయ్యను" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "విరిగిన వరుస" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "ప్రస్తుత ఆఖరి ప్ర్కటన సందేశం." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "ప్రస్తుత ప్రకటన సందేశముల జాబితా" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "ప్రస్తుతము మునుపు ప్రకటన సందేశము." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "ప్రస్తుత ఆఖరి ప్ర్కటన సందేశం." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "తరువాతి అక్షరంకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "మునుపటి అక్షరంకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "తరువాతి పదంకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "మునుపటి పదంకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "తరువాతి వరుసకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "మునుపటి వరుసకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "ఫైలు యొక్క పైకి వెళుతుంది." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "ఫైలు యొక్క క్రిందకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "వరుస మొదలకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "వరుస చివరకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "తరువాతి ఆబ్జక్ట్‍‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "మునుపటి ఆబ్జక్ట్‍‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "ప్రస్తుత కాంబో పెట్టె విస్తరించుటకు కారణమౌతుంది." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "Gecko స్వాబావిక మరియు ఓర్కా కారెట్ నావిగేషన్ మద్య మారుతుంది." - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "అధునాతన చేతన ప్రాతంము మర్యాద అమరికలు." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "అప్రమేయ చేతన ప్రాంతము మర్యాద స్థాయిని ఆఫ్‌కు అమర్చుము." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "చేతన ప్రాంతము ప్రకటనను పరిశోదించుము." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "మానిటర్ చేతన ప్రాంతములు." - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "ప్రస్తుత మోస్ మీదకు మరియు దూరముగా కేంద్రీకరించును." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "" -"calc అరలను మాట్లాడుతున్నప్పుడు అడ్డువరుసను యాంత్రిక నిలువువరుస యెగువ సూచీలలాగా ఉపయోగించునట్లు " -"అమర్చుము." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "యాంత్రిక నిలువువరుస యెగువ సూచీలను శుభ్రంచేయుము." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "" -"calc అరలను మాట్లాడుతున్నప్పుడు నిలువువరుసను యాంత్రిక అడ్డువరుస యెగువ సూచీలలాగా ఉపయోగించునట్లు " -"మార్చుము." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "యాంత్రిక అడ్డువరుస యెగువ సూచీలను శుభ్రంచేస్తుంది" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "ఇన్‌పుట్ ఫైలు యొక్క విషయములను సమర్పించును." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "నిర్మాణ నావిగెషన్ కీలను మార్చుతుంది." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "మునుపటి బ్లాక్‌కోట్‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "తరువాతి బ్లాక్‌కోట్‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "మునుపటి బటన్‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "తరువాతి బటన్‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "ఎక్కువ ఐచ్చికాలను ప్రదర్శించుము" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "మునుపటి తనిఖీ పేటికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "తరువాతి తనిఖీ పేటికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "మునుపటి పట్టికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "తరువాతి పట్టికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "మునుపటి కాంబో పేటికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "తరువాతి కాంబో పేటికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l కప్పిఉంచునది" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l కప్పిఉంచునది" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "మునుపటి ప్రవేశమునకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "తరువాతి ప్రవేశమునకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "మునుపటి రూపం క్షేత్రముకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "తరువాతి రూపం క్షేత్రముకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "మునుపటి హెడ్డింగ్‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "తరువాతి హెడ్డింగ్‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "స్థాయి %d వద్ద మునుపటి హెడ్డింగ్‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "స్థాయి %d వద్ద తరువాతి హెడ్డింగ్‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "స్థాయి %d నందు ఏ యెగువ సూచీలులేవు." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "మునుపటి పట్టికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "అంతర్గత చట్రము" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "మునుపటి వరుసకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "తరువాతి వరుసకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "మునుపటి లాండ్‌మార్క్‍‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "తరువాతి లాండ్‌మార్క్‍‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "మునుపటి పెద్ద ఆబ్జక్ట్‍‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "తరువాతి పెద్ద ఆబ్జక్ట్‍‌కు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "ఏ పెద్ద ఆబ్జక్టులు లేవు." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "మునుపటి వరుసకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "తరువాతి వరుసకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "ఎక్కువ ఐచ్చికాలను ప్రదర్శించుము" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "మునుపటి జాబితాకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "తరువాతి జాబితాకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "మునుపటి జాబితా అంశముకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "తరువాతి జాబితా అంశముకు వెళ్లుతుంది." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "మునుపటి చేతన ప్రాతంకు వెళ్లుతుంది." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "తరువాతి చేతన ప్రాతంకు వెళ్లుతుంది." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "ప్రకటన చేసినటువంటి మునుపటి చేతన ప్రాంతము వెళ్లుతుంది." - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "అంశము యొక్క పూర్వపు చరిత్రను కేంద్రీకరించి దిద్దిన సమాచారమును ముద్రించును." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "కీబోర్డు దృష్టితో ఆబ్జక్ట్స్‍ కు తిప్పిపంపుము." - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "నిర్మాణ నావిగెషన్ కీలను మార్చుతుంది." - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "మునుపటి పరిచ్ఛేదమునకు వెళ్లుతుంది." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "తరువాతి పరిచ్ఛేదమునకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "మునుపటి రేడియో బటన్‌కు వెళ్లుతుంది." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "తరువాతి రేడియో బటన్‌కు వెళ్లుతుంది." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "ఏరేడియో బటన్‌కు లేవు." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "మునుపటి విభజికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "తరువాతి విభజికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "మునుపటి పట్టికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "తరువాతి పట్టికకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "ఒక అర క్రిందకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "పట్టికలో మొదటి అరకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "పట్టికలో చివరి అక్షరంకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "ఒక అర ఎడమవైపుకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "ఒక అర కుడికి వేళుతుంది." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "ఒక అర పైకి వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "మౌస్ సమీక్ష పరిశీలనను మార్చుతుంది." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "కీ ఎకో చైతన్యం చేయుము(_k)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "మునుపటి దర్శించని లింకుకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "తరువాతి దర్శించని లింకుకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "ఏ దర్శించని లింకులు లేవు." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "మునుపటి దర్శించిన లింకుకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "తరువాతి దర్శించిన లింకుకు వెళుతుంది." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "ఏ దర్శించిన లింకులు లేవు." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "నలుపు" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "నలుపు వజ్రం" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "a గ్రేవ్" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i గ్రేవ్" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "గ్రేయ్డ్‍" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "‍డిగ్రీలు" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "హింది గ్రేడ్ 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "కుడి బ్రేస్" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "right control" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "కుడి పారెన్" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "కుడి బ్రేస్" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "కుడి పారెన్" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "కుడి పారెన్" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "right alt" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "కుడి పారెన్" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "కుడి సూపర్" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "కుడి ఆరో" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "కొత్తవరుస" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Image" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "tre" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s తెర" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "btn" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "శ్వేత ఖాళి" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "శ్వేత ఖాళి" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "పూర్తి తెర" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "చుక్క _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "చుక్క _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "చుక్కలు 7 మరియు 8(_d)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Icon" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "ఏదీకాదు" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "స్పెల్లింగ్" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "మన బడ్డీలు టైప్ చేయునప్పుడు మనం ప్రకటించుము(_b)" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "చాట్ రూమ్ విషేషమైన సందేశపు చరిత్రలను అందించుము(_m)" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "నుండి సందేశాలను మాట్లాడుము" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "అన్ని ప్రసారమార్గాలు(_n)" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "_y %s విండో క్రియాశీలంగా ఉంటేమాత్రమే అన్ని ప్రసారమార్గాలు" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "దాని విండో క్రియాశీలంగా ఉంటేమాత్రమే ప్రసారమార్గం(_w)" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "చాట్ రూమ్ పేరును మాట్లాడుము(_S)" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "రెండు నొక్కులు" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "మూడు నొక్కులు" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "అప్రమేయ సింథసైజర్" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "వాస్తవ స్ట్రింగ్" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "పునఃస్థాపన స్ట్రింగ్" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "ఎకోను అక్షరము ద్వారా చైతన్యంచేయుము(_r)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "ఖాళీలేని డైయాక్రిటికల్ కీలను చైతన్యంచేయుము(_n)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "ప్రస్తుత స్థానము(_u)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "సరిపోలిన పాఠముయొక్క కనిష్ఠ పొడవు:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "ఐచ్చికాలను కనుగొనుము" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "కనుగొనునప్పుడు మార్చిన వరుసలను మాత్రమే మాట్లాడుము(_y)" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "కనుగొనునప్పుడు ఫలితాలను మాట్లాడుము(_f)" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "కామా" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "కీ బంధనము" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "అప్రమేయం" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "వ్రాయు మోడ్" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "భాగము" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "బ్రైయిలీ బంధనములు" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "ఇష్టాంశములు దాయబడినవి" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "పట్టిక నావిగేషన్" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "బందనంకాని" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "సమతల పరిఅన్వేషణ రీతి నుండి బయటకువస్తున్నది." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "సవరించిన" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "డెస్కుటాప్(_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "ప్రకటన" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "ప్రకటన %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s కొరకు ఓర్కా అభీష్టాలు" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "బ్రైయిలీనందు గుర్తుంచుము" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "ప్రస్తుతం తప్ప" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "మాట్లాడు" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "వివరములను విరుద్దముగా భద్రపరుచుము" - -#: src/cthulhu/guilabels.py:429 -#, fuzzy -msgid "User Profile Conflict!" -msgstr "వాడుకరి వివరాల సంఘర్షణ!" - -#: src/cthulhu/guilabels.py:436 -#, fuzzy, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"%s అను వివరము ముందుగానే కలదు.\n" -"ఈ సరిక్రొత్త మార్పులతో ప్రస్తుత వివరములను అప్డేట్ చేయవలెనా?" - -#: src/cthulhu/guilabels.py:446 -#, fuzzy -msgid "Load user profile" -msgstr "వాడుకరి వివరములను బర్తీచేయుము" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"మీరు క్రియాశీలపరిచిన వివరములను మార్చుటకు సిద్ధముగా ఉన్నారు.\n" -"మీరు కేవలం మీ ప్రాధాన్యములలో మార్పులను చేసినచో,\n" -"అవి వివరముల భర్తీలో పడివేయును.\n" -"\n" -"వివరములలో పూర్వపు మార్పులను వ్వతిరేకించటమును కొనసాగించవలనా లేదా?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "వివరములను ఈ విధముగా బద్రపరుచుము" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "వివరముల పేరు:(_p)" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "వాడుకరి వివరములను బర్తీచేయుము" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "అన్ని" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "అనువర్తనము" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "విండో" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "ఏదీకాదు(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "కొన్ని(_m)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "ఎక్కువ(_o)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "వరుస" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "వాక్యము" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "కోట్" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Button" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "Caption" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "కాంబో బాక్స్‍" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "సబ్‌స్క్రిప్టు n" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Heading" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Image" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Label" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "వ్యాపారగుర్తు" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "Link" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "List" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "పరిచ్ఛేదము" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "ఎంపికకాబడినది" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "స్థితి" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Text" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "ఏ బ్లాక్‌కోట్స్‍ లేవు." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Button" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "CheckBox" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "కాంబో బాక్స్‍" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "Heading" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "InternalFrame" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Image" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "స్థాయి %d నందు ఏ యెగువ సూచీలులేవు." - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "వ్యాపారగుర్తు" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "ఏ పెద్ద ఆబ్జక్టులు లేవు." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "Link" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "List" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "ListItem" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "పరిచ్ఛేదము" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "RadioButton" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Table" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d దర్శించని లింకు" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d దర్శించిన లింకు" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "పుట నావిగేషన్" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "పుట మొదటిసారి నింపబడినప్పుడు స్వయంచాలకంగా మాట్లాడుట ప్రారంభించుము(_l)" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "పుట మొదటిసారి నింపబడినప్పుడు స్వయంచాలకంగా మాట్లాడుట ప్రారంభించుము(_l)" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "ఉపణ్యాశమును విరామము మథ్యలో ముక్కలుగా చేయుము(_u)" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s అప్రమేయ స్వరం" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "అప్రమేయం" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "హైపర్‌లింకు" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "వ్యవస్థ" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "అప్పర్‌కేస్" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "ఉపన్యాసం చేరవేయునది" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "స్ప్రెడ్ షీట్ అర అక్షములను మాట్లాడుతుంది" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "అర యెగువ సూచీను ప్రకటించుము(_h)" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "పట్టిక నావిగేషన్" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "బ్లాంక్ అరలను వదులుము(_b)" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "మాట్లాడు అర(_c)" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "అర అక్షములను మాట్లాడుము(_c)" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "బహుళ అర స్పానులను మాట్లాడుము(_m)" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "యాట్రిబ్యూట్‌ పేరు" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "ఓర్కా కారెట్ నావిగెషన్‌ను ఉపయోగించుము(_O)" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "నిర్మాణ నావిగెషన్ కీలను మార్చుతుంది." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "టూకీగా(_f)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "ప్రకటన" -msgstr[1] "ప్రకటన" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt_R" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Ctrl" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "left shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "left alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "left control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "right shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "right alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "right control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "left meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "right meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "left tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "వెనుకదిని ఖాళి చేయుము" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "వెనుదిరుగుము" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "ప్రవేశించుము" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "పైన" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "పైన" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "ఎడమ" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "కుడి" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "ఎడమ సూపర్" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "కుడి సూపర్" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "మెనూ" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "సహాయము" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "మల్టీ" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "మోడ్‌ని మార్చుము" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "తప్పించుకొను" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "చొప్పించు" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "తొలగించు" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "హోమ్" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "ముగింపు" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "మొదలుపెట్టు" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "సర్‌కమ్‌ఫ్లెక్స్‍" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "రింగ్" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "స్ట్రోక్" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "మైనస్" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "చొప్పించు" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "సూపర్" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "మెటా2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "మందమైన" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "italic" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "సూబ్‌స్క్రిప్టు %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "సూబ్‌స్క్రిప్టు %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "పనిస్థలం" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "సందర్భం %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "ఎడమ ఆరో" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "బాణం" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "కుడి ఆరో" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "బాణం" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "కుడి ఆరో" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "కుడి ఆరో" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "కుడి ఆరో" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "ఎడమ ఆరో" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "ఎడమ ఆరో" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "కుడి ఆరో" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "ఎడమ డబుల్ కోట్" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "డబుల్ డాగ్గర్" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "కుడి డబుల్ కోట్" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "డబుల్ డాగ్గర్" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "కుడి డబుల్ కోట్" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "కుడి-సూచిక బాణం" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "కుడి-సూచిక బాణపుతల" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "మైనస్" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "లెస్" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "గ్రేటర్" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "సర్‌కమ్‌ఫ్లెక్స్‍" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "డాట్" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "నిలువైన సమలేఖనం" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "అడ్డముగా" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "స్వయంచాలకముగింపు" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "ఖాళి" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "చైతన్యంచేయుము" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "అడ్డువరుస ముగింపు." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "సబ్" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "ప్లస్ లేదా మైనస్" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "ప్లస్" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "మైనస్" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "విభజని" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "క్యూబ్ రూట్" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "అనంతం" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "right alt" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "ఏకాకి" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "పోరరూపక ఫలకం" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "నిలువైన సమలేఖనం" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "దీని ద్వారా విభజించబడింది" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Separator" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "సమానం కాదు" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "లాజికల్ నాట్" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "లాజికల్ నాట్" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "నిర్దేశించు" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "అంతర్గత చట్రము" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "ద్వంద ప్రధాన" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "మైనస్" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "టిల్డ్‍" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n టిల్డ్‍" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n టిల్డ్‍" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "దాదాపు కు సమానం" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "దాదాపు కు సమానం" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "దాదాపు కు సమానం" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "దాదాపు కు సమానం" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "దాదాపు కు సమానం" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "దాదాపు కు సమానం" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "మూడు నొక్కులు" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "దాదాపు కు సమానం" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "భిన్నమైన సైటు" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "సమానం కాదు" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "ఈక్వల్స్‍" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "ఈక్వల్స్‍" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "సమానం కాదు" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "సమానం కాదు" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "త్రికోణ బుల్లెట్" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "ఈక్వల్స్‍" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "సమానం కాదు" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "సమానం కాదు" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "నిలువుగా" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "సమానం కాదు" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "సమానం కాదు" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "గ్రేటర్" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "వత్తబడలేదు" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ఎంపిక కాలేదు" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "సబ్‌స్క్రిప్టు 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "సూపర్‌స్క్రిప్టు a" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "బహుళ-ఎంపిక" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "న్యాయం చేయు" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "బహుళ-ఎంపిక" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "సబ్‌స్క్రిప్టునకు సరిసమానమైనది " - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "en డాష్" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "సబ్‌స్క్రిప్టు ప్లస్" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "సబ్‌స్క్రిప్టు మైనస్" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "right meta" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "left tab" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "పైన" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "భాగము" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "సత్యము" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "సత్యము" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ఆర్డినల్" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "చిత్రము" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "మల్టీ" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "అంతర్గత చట్రము" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "సాధారణ" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "కుడి సింగిల్ కోట్" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "కుడి బ్రేస్" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "విభజని" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "లాజికల్ నాట్" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "లాజికల్ నాట్" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "ద్వంద ప్రధాన" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "ద్వంద ప్రధాన" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "నిర్దేశించు" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "ద్వంద ప్రధాన" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "తక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "ఎక్కువ లేదా సమానం" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "నిలువైన సమలేఖనం" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ఎడమ పారెన్" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "కుడి పారెన్" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "left alt" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "right alt" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "ఎడమ బ్రేస్" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "క్రింద" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "ఎడమ డబుల్ ఎంగిల్ బ్రాకెట్" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "కుడి డబుల్ యాంగిల్ బ్రాకెట్" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "మద్య చుక్క" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "వర్గమూలం" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "నలుపు వర్గం" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "శ్వేత వర్గం" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "నలుపు వజ్రం" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "శ్వేత వృత్తం" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "నలుపు వృత్తం" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "శ్వేత బుల్లెట్" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "నలుపు వర్గం" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "క్రిందిగీత" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "నిలువైన సమలేఖనం" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "అనువర్తనం" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "బ్లాంక్" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "మందమైన" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "ఇష్టాంశము ప్రవేశపెట్టబడింది" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "ఇష్టాంశములు దాయబడినవి" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "ఇష్టాంశములు దాయబడలేవు" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "ఏ లాండ్‌మార్క్‍ కనబడలేదు." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "ఏ లాండ్‌మార్క్‍ కనబడలేదు." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "బైపాస్ మోడ్‌ని క్రియాశీలీకరించెను." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "గణితయంత్రము ప్రదర్శన నిర్వీర్యమైనది" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ప్రతిమ" - -#: src/cthulhu/messages.py:117 -#, fuzzy -msgid "Capitalization style set to icon." -msgstr "పంక్టువేషన్ స్థాయిని దేనికి అమర్చలేదు." - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "ఏదీకాదు" - -#: src/cthulhu/messages.py:137 -#, fuzzy -msgid "Capitalization style set to none." -msgstr "పంక్టువేషన్ స్థాయిని దేనికి అమర్చలేదు." - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "స్పెల్లింగ్" - -#: src/cthulhu/messages.py:157 -#, fuzzy -msgid "Capitalization style set to spell." -msgstr "పంక్చ్యయేషన్ స్థాయిని అన్నిటికీ అమర్చెను." - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "కారెట్‌ను Gecko నియంత్రిస్తోంది." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "కారెట్‌ను ఓర్కా నియంత్రిస్తోంది." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "అర %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "ఎంపిక కాలేదు" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "ఎంపికకాని" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "ఐచ్చికం యొక్క ఉపయోగంను నిరోధించుము" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "ఐచ్చికం యొక్క బలవంతపు ఉపయోగం" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -#, fuzzy -msgid "The following are not valid: " -msgstr "ఈ ముదలగు సమాచారాత్మక విలువలు చెల్లవు: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "తెలిసిన నడుస్తున్న కార్యక్షేత్రములను ముద్రించుము" - -#: src/cthulhu/messages.py:237 -#, fuzzy -msgid "Load profile" -msgstr "వాడుకరి వివరములను బర్తీచేయుము" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "ఇష్టాంశములు దాయబడలేవు" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "వాడుకరి అభీష్టముల కొరకు వైకల్పిక సంచయంను ఉపయోగించుము" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "తెలిసిన నడుస్తున్న కార్యక్షేత్రములను ముద్రించుము" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "ప్రస్తుతం నడుస్తున్న ఆర్కా పునఃస్థాపన చేయుము" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "ఈ సహయక సందేశంను చూపుము" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "debug-YYYY-MM-DD-HH:MM:SS.outనకు దిద్దుబాటు ఫలితాంశమును పంపించుము" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "నిర్దేశించబడిన ఫైలునకు దిద్దుబాటు ఫలితాంశమును పంపించుము" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "వాడుకరి అభిష్టాలను అమర్చుము (పాఠము వర్షన్)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "వాడుకరి అభిష్టాలను అమర్చుము (పాఠము వర్షన్)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "బగ్‌లను https://groups.io/g/stormux. కు నివేదించండి." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "ఎక్యూట్" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "వేగమైన." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "మన బడ్డీలు టైప్ చేయునప్పుడు మనం ప్రకటించవద్దు." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "మన బడ్డీలు టైప్ చేయునప్పుడు మనం ప్రకటించుము." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "చాట్ రూమ్ %s నుండి సందేశం" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "కొత్త చాట్ టాబ్ %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "చాట్ రూమ్ పేరును మాట్లాడవద్దు." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "చాట్ రూమ్ పేరును మాట్లాడుము." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "చాట్ రూమ్ విషేషమైన సందేశపు చరిత్రలను అందించవద్దు." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "చాట్ రూమ్ విషేషమైన సందేశపు చరిత్రలను అందించుము." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "తొలగించు" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "చొప్పించు" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "క్వశ్చన్" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "పట్టిక ముగియనున్నది" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "పట్టికలో లేదు." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "ఎంపిక కాలేదు" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "అప్రమేయ బటన్ %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "అప్రమేయ బటన్ %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "అప్రమేయ బటన్ %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "సూబ్‌స్క్రిప్టు %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "సూపర్‌స్క్రిప్టు %s" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "పట్టికలో లేదు." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "మొత్త పత్రము ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "మొత్త పత్రము ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "కర్సర్ స్థానమునుండి పత్రము ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "కర్సర్ స్థానమునుండి పత్రము ఎంపికకాబడలేదు" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "కర్సర్ స్థానముకు పత్రము ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "కర్సర్ స్థానముకు పత్రము ఎంపికకాబడలేదు" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "అడ్డువరుస %d కొరకు యాంత్రిక నిలువువరుస యెగువ సూచీ అమర్చబడింది" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "యాంత్రిక నిలువువరుస యెగువ సూచీ శుభ్రంచేయబడింది." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "యాంత్రిక అడ్డువరుస యెగువ సూచీ నిలువువరుస %s కొరకు అమర్చబడింది" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "యాంత్రిక అడ్డువరుస యెగువ సూచీ శుభ్రంచేయబడింది." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ఖాళి" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f కిలోబైట్స్‍" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f మెగాబైట్స్‍" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "ఏ ఫైలులు కనబడలేదు." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "సమతల పరిఅన్వేషణ రీతిని ప్రవేశిస్తుంది." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "సమతల పరిఅన్వేషణ రీతిని ప్రవేశిస్తుంది." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "సమతల పరిఅన్వేషణ రీతి నుండి బయటకువస్తున్నది." - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "సమతల పరిఅన్వేషణను ప్రస్తుత పదంకు పైనఉన్న పదంకు కదుల్చుతుంది." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "సూత్రమును కలిగిఉంది" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "డైలాగ్" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "పాప్అప్ మెనూ" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "ప్రతిమకు దారిచూపు లింకు" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "ప్రవేశపెట్టిన కీ ఇప్పటికే %s కు బంధనం అయిఉంది" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "కీ లోబరచబడింది: %s. నిర్ధారించుటకు ప్రవేశంను వత్తుము." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "కొత్త కీ: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "కీ బందనము తొలగించబడినది. నిర్ధారించుటకు ప్రవేశంను వత్తుము." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "కీబంధనం తీసివేయబడింది." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "కొత్త కీను ప్రవేశపెట్టుము" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "కీ " - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "కీ ఎకోని కీకు అమర్చెను." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "ఏదీకాదు" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "కీ ఎకోని దేనికి అమర్చలేదు." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "కీ మరియు పదము" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "కీ ఎకోని కీకు మరియు పదమునకు అమర్చెను ." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "వాక్యము" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "కీ ఎకోని వాఖ్యమునకు అమర్చుము." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "పదము" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "కీ ప్రతిధ్వనిని పదమునకు అమర్చుము." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "పదము మరియువాఖ్యము" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "కీ ఎకోని పదము మరియు వాఖ్యమునకు అమర్చెను." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "నలుపు వృత్తం" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "అడ్డముగా" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "నిలువు బార్" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "కుడి ఆరో" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "క్రిందకు మడుచుచున్నది." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "వరుస ఎత్తు" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "మరియు" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "ఓవర్‌లైన్" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "వర్గమూలం" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "క్యూబ్ రూట్" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "రూట్ ఫలకం" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "రూట్ ఫలకం" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "రూట్ ఫలకం" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "సబ్‌స్క్రిప్టు 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "సూపర్‌స్క్రిప్టు a" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "సబ్‌స్క్రిప్టు 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "సూపర్‌స్క్రిప్టు a" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "సూపర్‌స్క్రిప్టు a" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "సూపర్‌స్క్రిప్టు a" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "పట్టిక" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "వృక్షము పట్టిక" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "వాడుకొనలేని" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "నిస్సారమైనది" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "వరుసక్రమంను మరియు సర్దబాటును మాట్లాడుట సంభవించలేదు." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "చైతన్యంచేయుము" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "వరుసక్రమంను మరియు సర్దబాటును మాట్లాడుట సంభవించెను." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "అభ్యాసన రీతి. బయటకు వచ్చుటకు ఎస్కేప్ ను వత్తుము." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "యానిమేషన్" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "పుట నావిగేషన్" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "పట్టిక నావిగేషన్" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "సమతల పరిఅన్వేషణ రీతి నుండి బయటకువస్తున్నది." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "పట్టికను వదిలివేయుట." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "కర్సర్ స్థానమునుండి వరుసక్రిందకు ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "కర్సర్ స్థానమునుండి వరుసపైకి ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "కర్సర్ స్థానమునుండి వరుసక్రిందకు ఎంపికకాబడలేదు" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "కర్సర్ స్థానమునుండి వరుసపైకి ఎంపికకాబడలేదు" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "అభ్యాసన రీతినుండి బయటకువస్తోంది." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "వరుసమొదలు నుండి కర్సర్ స్థానముకి ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "కర్సర్ స్థానమునుండి వరుస చివరకు ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "లింకు" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "అదే పుట" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "అదే సైటు" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "భిన్నమైన సైటు" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)sలను %(file)sకు లింకుచేస్తుంది" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s లింకు" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d దర్శించిన లింకు" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "Up and Down Arrowలను జాబితాలో విహరించుటకు ఉపయోగించుము.బయటకు Escapeని నొక్కుము." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "అన్ని చేతన ప్రాతంలను ఆఫ్‌కు అమర్చుము" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "చేతన ప్రాతంల మర్యాద స్థాయిలను తిరిగిఉంచుము" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "మర్యాద స్థాయి %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "చేతన ప్రాతంను ఎస్సర్టివ్‌కు అమర్చుట" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "చేతన ప్రాతంను ఆఫ్‌కు అమర్చుట" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "చేతన ప్రాతంను మర్యాదకు అమర్చుట" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "చేతన ప్రాతంను రూడ్‌కు అమర్చుము" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "చేతన ప్రాంతాల మానిటరింగ్ ఆఫ్ చేయబడింది" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "చేతన ప్రాంతాల మానిటరింగ్ ఆన్ చేయబడింది" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "ఏ లైవ్ సందేశం దాయబడలేదు" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "చేతన ప్రాతం మద్దతు ఆఫ్ చేయబడింది" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "దృష్టీకరించలేదు" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "ప్రస్తుత స్థానము కనుగొనలేదు" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "ఆఫ్‌చేయి" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "ఆన్‌చేయి" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "తప్పుగా స్పెల్‌చేయబడినది" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "తప్పుగాఉచ్చరించిన పదం: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "సందర్భం %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -#, fuzzy -msgid "Focus mode" -msgstr "షార్ట్ కట్‌ల మోడ్ జాబితా." - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -#, fuzzy -msgid "Layout mode." -msgstr "షార్ట్ కట్‌ల మోడ్ జాబితా." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "తరువాతి ఆబ్జక్ట్‍‌కు వెళుతుంది." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "మోస్ చూపించే అంశము దొరకలేదు." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "మౌస్ విస్తరింపులు అచేతనంచేయబడినవి." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "మౌస్ విస్తరింపులు చైతన్యంచేయబడినవి." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d శాతం." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "మునుపటి పదంకు వెళుతుంది." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "తదుపరి స్థాయి %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "క్రొత్త అంశమును జతపరిచెను" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "ఏ అనువర్తనం దృష్టీకరించబడలేదు." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "దృష్టీకరించలేదు" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "ఏ అనువర్తనం దృష్టీకరించబడలేదు." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "ఏ బ్లాక్‌కోట్స్‍ లేవు." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "ఏ బటన్‌లు లేవు." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "ఏ తనిఖీ పేటికలులేవు." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "ఏ పెద్ద ఆబ్జక్టులు లేవు." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "ఏ పట్టికలు లేవు." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "ఏ కాంబో పేటికలులేవు." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "ఏ ప్రవేశములు లేవు." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "ఏ ఫారము క్షేత్రాలు లేవు." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "ఏ యెగువ సూచీలు లేవు." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "స్థాయి %d నందు ఏ యెగువ సూచీలులేవు." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "అంతర్గత చట్రము" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "ఏ పట్టికలు లేవు." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "ఏ లాండ్‌మార్క్‍ కనబడలేదు." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "ఏ జాబితాలు లేవు." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "ఏ జాబితాలు లేవు." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "ఏ జాబితా అంశములు లేవు." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "ఏ చేతన ప్రాంతములు లేవు." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "ఏ పరిచ్ఛేదములు లేవు." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "ఏరేడియో బటన్‌కు లేవు." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "ఏ విభజికలు లేవు." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "ఏ పట్టికలు లేవు." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "ఏ దర్శించని లింకులు లేవు." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "ఏ దర్శించిన లింకులు లేవు." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "ఎంపికకాబడలేదు" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "పట్టికలో లేదు." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "ప్రకటన" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "క్రింద" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "పైన" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "ఎలాంటి ప్రకటన సందేశములు లేవు" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "పదము" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "ఎన్నోరకములగల పదబంధములను పదములుగా మాట్లాడుము(_d)" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "ఆఫ్" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "ఆన్" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "నింపుతోంది. దయచేసి వేచిఉండండి." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "నింపుట పూర్తైంది." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s నింపుట పూర్తైంది." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "కర్సర్ స్థానమునుండి పుట ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "కర్సర్ స్థానమునుండి పుట ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "కర్సర్ స్థానమునుండి పుట ఎంపికకాబడలేదు" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "కర్సర్ స్థానమునుండి పుట ఎంపికకాబడలేదు" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "కర్సర్ స్థానమునుండి పరిచ్ఛేదమును ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "కర్సర్ స్థానమునుండి పరిచ్ఛేదమును ఎంపికకాబడినది" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "కర్సర్ స్థానమునుండి పరిచ్ఛేదమును ఎంపికకాబడలేదు" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "కర్సర్ స్థానమునుండి పరిచ్ఛేదమును ఎంపికకాబడలేదు" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"మీరు ఓర్కా అభీష్టాల డైలాగ్ యొక్క సంభవము ఇప్పటికే తెరిచిఉంది.\n" -"కొత్త దానిని తెరుచుటకు ముందు దానిని మూయుము." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "%(position)dఅను స్లైడ్ %(count)dనకు చెందినది" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "ఏ ఫైలులు కనబడలేదు." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "పురోగతి పట్టీ %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "అన్ని" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "పంక్చ్యయేషన్ స్థాయిని అన్నిటికీ అమర్చెను." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "ఎక్కువ" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "పంక్టువేషన్ స్థాయిని చాలావాటికి అమర్చెను." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "ఏదీకాదు" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "పంక్టువేషన్ స్థాయిని దేనికి అమర్చలేదు." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "కొన్ని" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "పంక్టువేషన్ స్థాయిని కొన్నిటికి అమర్చెను." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "అన్వేషించుచున్నది." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "అన్వేషణ పూర్తైంది." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "ఓర్కా అమరికలు తిరిగినింపబడినవి." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "సందర్భం %s" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "అడ్డ వరుసను తొలగించెను" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "కావలిసిన ద్వనిని ఎంపికచేయుము:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "ఎంపికకాని" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "ఉపన్యాసం అచేతనం చేయబడింది." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "ఉపన్యాసం చైతన్యం చేయబడింది." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "వేగమైన." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "నెమ్మదైన." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "ఎక్కువ." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "తక్కువ." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "వేగమైన." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "దర(_R):" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "వాల్యూమ్(_l):" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "ఉపన్యాసం చేరవేయునది" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "ఉపన్యాసం చేరవేయునది" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "ఏ సేవికలు అందుబాటులోలేవు.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "ఏ స్వరాలు అందుబాటులో లేదు.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "ఉపన్యాసం చైతన్యం చేయబడింది." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "ఉపన్యాసం ఉపయోగించబడబోదు.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " dot dot dot" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "ఓర్కా అభీష్టాలు" - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "కారెట్‌ను ఓర్కా నియంత్రిస్తోంది." - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "బైపాస్ మోడ్‌ని క్రియాశీలీకరించెను." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "ఉపన్యాసం అందుబాటులో లేదు." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "దృష్టీకరించలేదు" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "పాస్‌ఫ్రేజ్ కనబడలేదు" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "స్ట్రింగ్ కనబడలేదు" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "నిర్మాణ నావిగేషన్ కీ ఆఫ్అయిఉంది." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "నిర్మాణ నావిగేషన్ కీ ఆన్అయిఉంది." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "దృష్టీకరించలేదు" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "అడ్డువరుస %(row)d, నిలువువరుస %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "పట్టిక ముగియనున్నది" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "మాట్లాడు అర" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "మాట్లాడు అడ్డువరుస" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "సమానత-కాని" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "పట్టికలో లేదు." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "ColumnHeader" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "నిలువువరుస %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "నిలువువరుస %(index)d మొత్తం %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "నిలువవరుస యొక్క క్రిందన." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "నిలువువరుస యొక్క పైన." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "ఎంపికకాని" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "ఎంపికకాని" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "అడ్డువరుస %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "అడ్డవరుస %(index)d మొత్తం %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "అడ్డువరుస ప్రారంభము." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "అడ్డువరుస ముగింపు." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "అడ్డ వరుసను తొలగించెను" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "చివరి అడ్డ వరుసను తొలగించెను." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "అడ్డ వరుసను జతపరిచెను." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "పట్టిక చివరిలో అడ్డవరుసను అమర్చుము." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "అడ్డ వరుసను తొలగించెను" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "ఎంపికకాని" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "ఎంపికకాబడిన" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "ఎంపికకాని" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H గడియలు, %M నిముషములు మరియు %S సెకన్‌లు." - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H గడియలు మరియు %M నిముషములు." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "యూనికోడ్ %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, fuzzy, python-format -msgid "Cthulhu version %s." -msgstr "%s కొరకు ఓర్కా అభీష్టాలు" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "శ్వేత ఖాళి" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "క్రిందకు మడుచుచున్నది." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "పైకి మడుచుచున్నది." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 అంశములు" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "అర స్పాన్స్‍ %d అడ్డువరుస" -msgstr[1] "అర స్పాన్స్‍ %d అడ్డువరుసలు" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d నిలువువరుస" -msgstr[1] "%d నిలువువరుసలు" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "అర స్పాన్స్‍ %d నిలువువరుసలు" -msgstr[1] "అర స్పాన్స్‍ %d నిలువువరుసలు" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d అక్షరము చాలా పొడవైనది" -msgstr[1] "%d అక్షరములు చాలా పొడవైనవి" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d డైలాగు)" -msgstr[1] "(%d డైలాగులు)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d కేంద్రీకరించలేని డైలాగ్" -msgstr[1] "%d కేంద్రీకరించలేని డైలాగ్‌లు" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d బైటు" -msgstr[1] "%d బైట్స్‍" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ఫైలు కనబడినది" -msgstr[1] "%d ఫైలులు కనబడినవి" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d రూపం" -msgstr[1] "%d రూపాలు" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d హెడ్డింగ్" -msgstr[1] "%d హెడ్డింగ్స్‍" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d అంశము" -msgstr[1] "%d అంశములు" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "ఏ లాండ్‌మార్క్‍ కనబడలేదు." -msgstr[1] "ఏ లాండ్‌మార్క్‍ కనబడలేదు." - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d ఫైలు కనబడినది" -msgstr[1] "%d ఫైలులు కనబడినవి" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "ఏ బ్లాక్‌కోట్స్‍ లేవు." -msgstr[1] "ఏ బ్లాక్‌కోట్స్‍ లేవు." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "సమతల పరిఅన్వేషణ రీతి నుండి బయటకువస్తున్నది." -msgstr[1] "సమతల పరిఅన్వేషణ రీతి నుండి బయటకువస్తున్నది." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d అంశముతో జాబితాచేయుము" -msgstr[1] "%d అంశములతో జాబితాచేయుము" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "%d అంశముతో జాబితాచేయుము" -msgstr[1] "%d అంశములతో జాబితాచేయుము" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "పట్టిక వెడల్పు %d అడ్డువరుస" -msgstr[1] "పట్టిక వెడల్పు %d అడ్డువరుసలు" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d నిలువువరుస" -msgstr[1] "%d నిలువువరుసలు" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "పట్టిక వెడల్పు %d అడ్డువరుస" -msgstr[1] "పట్టిక వెడల్పు %d అడ్డువరుసలు" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d ఖాళి.\n" -msgstr[1] "%d ఖాళీలు.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d శాతం." -msgstr[1] "%d శాతం." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d శాతం పత్రము చదువబడినది" -msgstr[1] "%d శాతం పత్రము చదువబడినది" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s అక్షరం" -msgstr[1] "%(count)d %(repeatChar)s అక్షరాలు" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d అంశం ఎంపికచేయబడింది %(total)d" -msgstr[1] "%(index)d అంశాలు ఎంపికచేయబడినవి %(total)d లలో" - -#: src/cthulhu/messages.py:2793 -#, fuzzy, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d అను ఓర్కా అప్రమేయపు షార్ట్ కట్‌ని అన్వేషించెను." -msgstr[1] "%d అను ఓర్కా అప్రమేయపు షార్ట్ కట్‌లను అన్వేషించెను." - -#: src/cthulhu/messages.py:2801 -#, fuzzy, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)dఅను ఓర్కా షార్ట్ కట్‌ను %(application)sనకు అన్వేషించెను." -msgstr[1] "%(count)dఅను ఓర్కా షార్ట్ కట్‌లను %(application)sనకు అన్వేషించెను." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d ఖాళి" -msgstr[1] "%d ఖాళీలు" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d టాబ్" -msgstr[1] "%d టాబ్‌లు" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d పట్టిక" -msgstr[1] "%d పట్టికలు" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "పట్టిక వెడల్పు %d అడ్డువరుస" -msgstr[1] "పట్టిక వెడల్పు %d అడ్డువరుసలు" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "పట్టిక వెడల్పు %d అడ్డువరుస" -msgstr[1] "పట్టిక వెడల్పు %d అడ్డువరుసలు" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "పట్టిక వెడల్పు %d అడ్డువరుస" -msgstr[1] "పట్టిక వెడల్పు %d అడ్డువరుసలు" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d దర్శించని లింకు" -msgstr[1] "%d దర్శించని లింకులు" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d దర్శించిన లింకు" -msgstr[1] "%d దర్శించిన లింకులు" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "మార్పు" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(total)d యొక్క %(index)d పై ఉన్నది" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(total)d యొక్క %(index)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "స్థాయి %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "వృక్ష స్థాయి %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "వృక్ష స్థాయి%d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "క్వశ్చన్" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "కాంబో బాక్స్‍" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html విషయము" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "పదము" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "కోలన్" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "ఓవర్‌లైన్" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "నిర్దేశించు" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "పరిచ్ఛేదము" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "పదము" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "ధర్ఖాస్తు" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "నిర్దేశించు" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "టాబ్ జాబితా" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "కోట్" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "html విషయము" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s స్థాయి %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "అడ్డముగా" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "నిలువు బార్" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "అడ్డముగా" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "నిలువైన సమలేఖనం" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "అడ్డముగా" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "నిలువైన సమలేఖనం" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "మోడ్‌ని మార్చుము" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "ప్రతిమ ఫలకం" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "html విషయము" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Animation" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "html విషయము" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Animation" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "అన్వేషించుచున్నది." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d దర్శించిన లింకు" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "స్పిన్ బటన్" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "కూలిన" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "విస్తరించిన" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "అడ్డముగా" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "నిలువుగా" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "పరిశీలించబడింది" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "పరిశీలించబడలేదు" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "ఆన్" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "ఆఫ్" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "పాక్షికంగా పరిశీలించబడింది" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "వత్తబడింది" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "వత్తబడలేదు" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "ఎంపికకాబడలేదు" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "ఎంపికకాబడినది" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ఎంపికకాబడలేదు" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "ఎంపికచేయలేదు" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d దర్శించిన లింకు" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d దర్శించని లింకు" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "గ్రేయ్డ్‍" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "చదువుటకు మాత్రమే" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "rdonly" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "అవసరమైనది" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "బహుళ-ఎంపిక" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "చెల్లని" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "చెల్లని" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "స్పెల్లింగ్" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "స్పెల్లింగ్" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "చెల్లని" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "కనుగొను" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "తెర చదువరి" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "మూసివేయి" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "కనుగొను" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "కొరకు (_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "కొరకు అన్వేషించు:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "విండో కి పైన(_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "విండో కి పైన" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "నుండి ప్రారంభించుము:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "చట్టూ మలుచుము(_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "వెనుకకు అన్వేషించు(_b)" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "దారిని వెతుకుము:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "బడిని సరిచూడుము(_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "మొత్త పదమును మాత్రమే సరిపోల్చుము(_e)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "ఐచ్చికాలను కనుగొనుము" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "అప్రమేయం" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "అప్పర్‌కేస్" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "హైపర్‌లింకు" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "వ్యవస్థ" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "అనువర్తనము" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "విండో" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "ఓర్కా అభీష్టాలు" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "లాప్‌ట్యాప్ (_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "కీబోర్డు వాస్తు" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "క్రియాశీల వివరములు(_P):" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "వివరములను ప్రారంభించుము:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "భర్తీచేయుము(_L)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -#, fuzzy -msgid "Save _As" -msgstr "వివరములను ఈ విధముగా బద్రపరుచుము" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -#, fuzzy -msgid "Profiles" -msgstr "వివరములు" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "ప్రస్తుత చిట్కాలు(_P)" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "మౌస్ యొక్క అంశమును గూర్చి మాట్లాడుము(_u)" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "సమయం ఆకృతి:(_T)" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "తేది ఆకృతి:(_e)" - -#: src/cthulhu/cthulhu-setup.ui:625 -#, fuzzy -msgid "Time and Date" -msgstr "సమయము మరియు తేది" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "అన్నిటిని మాట్లాడుము(_S)" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "బ్రైయిలీ బంధనములు" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "పౌనఃపుణ్యం (సెకన్‌లు):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "అనువర్తనము" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "పురోగతి బార్ అప్‌డేట్‌లు" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "నిర్మాణ నావిగెషన్ కీలను మార్చుతుంది." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "ద్వారా చెప్పుము (_y):" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "ద్వారా చెప్పుము (_y):" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "సాధారణ" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "వాల్యూమ్(_l):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "స్థాయి(_t):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "దర(_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "వ్యక్తి(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "భాష" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "ఉపన్యాసం సిథసైజర్(_z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "ఉపన్యాసం వ్యవస్థ(_s):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "స్వరం రకం (_V):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "స్వరం రకము అమరికలు" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "ఎన్నోరకములగల పదబంధములను పదములుగా మాట్లాడుము(_d)" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "గ్లోబల్ వాయిస్ అమరికలు" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "స్వరం" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "ఉపన్యాసం చైతన్యంచేయుము(_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "వెర్బోస్(_b)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "వెర్బోసిటి" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "అన్ని(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "పంక్చ్యయేషన్ స్థాయి" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "ప్రదర్శించిన " - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "ఖాళీ వరుసలను మాట్లాడుము" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "వరుసక్రమంను మరియు సర్దబాటును మాట్లాడుము(_i)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "అంశము నెమోనిక్‌ల గురించి మాట్లాడుము(_k)" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "చేల్డ్ స్థాయి గురించి మాట్లాడుము(_o)" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "వెబ్ భోదిని సందేశాలను మాట్లాడుము" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "అర అక్షములను మాట్లాడుము(_c)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "అర అక్షములను మాట్లాడుము(_c)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "చేల్డ్ స్థాయి గురించి మాట్లాడుము(_o)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -#, fuzzy -msgid "Spoken Context" -msgstr "మాట్లాడిన అంశము" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "ఉపన్యాసం" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "బ్రెయిలీ మద్దతును చైతన్యంచేయుము(_s)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "సంక్షిప్తపరిచిన రోలా పేరులు(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "వరుస గుర్తు చివరిని నిరుపయోగపరిచెను(_e)" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "సంకుచితత్వ పట్టిక(_T):" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "సంకుచిత బ్రెయిలిని చైతన్యంచేయుము(_E)" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "ఎకోను పదము ద్వారా చైతన్యంచేయుము(_w)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "ప్రదర్శన అమరికలు" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "ఏదీకాదు(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "ఎంపిక సూచకి" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "హైపర్‌లింక్ సూచకి" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "బ్రెయిలి" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "కీ ఎకో చైతన్యం చేయుము(_k)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "నావిగేషన్ కీలను చైతన్యంచేయుము(_n)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "సవరణి కీలను చైతన్యంచేయుము(_m)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "కార్యక్రమము కీలను చైతన్యంచేయుము(_f)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "ఉపన్యాసం చైతన్యంచేయుము(_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "సవరణి కీలను చైతన్యంచేయుము(_m)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "కార్యక్రమము కీలను చైతన్యంచేయుము(_f)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "చర్యా కీలను చైతన్యంచేయుము(_t)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "నావిగేషన్ కీలను చైతన్యంచేయుము(_n)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "ఎకోను పదము ద్వారా చైతన్యంచేయుము(_w)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "ఎకోను వాఖ్యము ద్వారా చైతన్యంచేయుము(_s)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "కీ ఎకో" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "ఓర్కా నవరణి కీ(లు)(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "కీ బందనములు" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "ఉచ్ఛారణా పదకోశం" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "కొత్త ప్రవేశం (_N)" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "తొలగించు (_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "పంక్చ్యుయేషన్" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "అన్నిటిని మాట్లాడుము(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "ఏదీ మాట్లాడవద్దు(_n)" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "తిరిగిఉంచు(_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "పాఠము యాట్రిబ్యూట్స్‍" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "క్రిందకు కదుల్చుము(_b)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "ఒకటి క్రిందకు కదుల్చుము(_d)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "ఒకటి పైకి కదుల్చుము(_u)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "పైకి కదుల్చుము(_t)" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "" -"ఎంపికచేసిన యాట్రిబ్యూట్‌లను\n" -"సర్దండి" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "బ్రెయిలి సూచకి" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "పాఠము యాట్రిబ్యూట్స్‍" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "తక్కువ" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "భాష" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "యెన్" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "వెలుపలి రంగం వర్ణము " - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "వెలుపలి రంగం పూర్తి ఎత్తు" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "వెలుపలి రంగం బిందువుల గీత" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "నిర్దేశించు" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "సరిచేయుపట్టిక" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "కుటుంబ పేరు " - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "ముందు భాగము వర్ణము" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "ముందు భాగము బిందువుల గీత" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "అక్షరశైలి ప్రభావం" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "ధర్ఖాస్తు" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "తప్పిదం " - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "దర్శించలేని" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "న్యాయం చేయు" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "భాష" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "ఎడమ అంచు" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "వరుస ఎత్తు" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "పరిచ్ఛేదము శైలి" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "వరుసల పైనున్న పిక్సెల్‌లు" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "వరుసలు క్రిందవున్న పిక్సెల్‌లు" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "సర్దుబాటు చేయబడిన పిక్సెల్‌లు " - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "కుడి అంచు" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "ఉన్నతిచెందు" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "scale" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "పరిమాణం" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "సాగతీయు" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "దూసుకువెళ్ళుము" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "శైలి" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "పాఠమును అలంకరించుట" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "పాఠము భ్రమణము" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "పాఠము నీడ" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "క్రిందిగీత" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "చరరాశి" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "నిలువైన సమలేఖనం" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "బరువు" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "సర్దుబాటుచేయు మోడ్" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "వ్రాయు మోడ్" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "సత్యము" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "అసత్యము" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ఏదీకాదు" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "మలచు" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "ఉబ్బెత్తు" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "సారాంశ నివేదిక" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "ఓవర్‌లైన్" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "వరుస ద్వారా" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "చీకరించు" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "నలుపు" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "ఏకాకి" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "ద్వంద" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "తక్కువ" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "కార్" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "పదము" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "కార్ పదం" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "ఎడమ" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "కుడి" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "మథ్య" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "న్యాయము చేయలేదు" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "నింపునది" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "తీవ్రముగా సంగ్రహమైనది" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "ఎక్కువగా సంగ్రహమైనది" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "సంగ్రహమించినది" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "అర్ధముగా సంగ్రహించబడెను" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "సాధారణ" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "అర్ధముగా విస్తరించిన" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "విస్తరించిన" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "ఎక్కువగా విస్తరించిన" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "విస్తృతంగా విస్తరించిన" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "చిన్న టోపీలు" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "విపరీతమైన" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "italic" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "అప్రమేయం" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "పాఠ భాగం" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "శీర్షిక" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "మూల వరుస" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "సబ్" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "సూపర్" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "పైన" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "పాఠము పైన" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "మథ్య" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "క్రింద" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "పాఠము క్రింద" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "వంశపారంపర్యంగా పొందు" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "ధృడమైనది" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "స్పెల్లింగ్" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "మార్పునకు space నొక్కుము" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "విస్తరించుటకు spaceని నొక్కుము,అంశమును ఎన్నుకొనుటకు up మరియు down ఉపయోగించుము." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "చిన్న విండోలను కేంద్రీకరించుటకు alt+f6ని నొక్కుము" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "అంశములకు వెళ్ళవలిసినచో సూచిక కీలునుగాని శోధించేదానిలో టైప్ చేయుము." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "సిస్టమ్ జాబితాలలోకి పోవునచో alt+f1కీని నొక్కుము." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "ఒక అంశమును ఎంపికచేయవలనిచో up మరియు downని ఉపయోగించుము." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "నాశనము చేయుటకు shift plus left నొక్కుము." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "విస్తరించుటకు shift plus right నొక్కుము." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "ఉత్తేజపరుచుటకు return ని నొక్కుము." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "పాఠములో టైప్ చేయుము." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "ఇతర టాబ్‌లకు ఎడమ మరియు కుడిని ఉపయోగించుము." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "ఉత్తేజపరుచుటకు spaceని నొక్కుము." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"విలువను ఎంపిక చేయవలసినచో up లేక downని ఉపయోగించుము.లేక ఆశించిన సంఖ్యపు విలువలో టైప్ చేయుము." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "మార్పునకు సూచిక కీలను ఉపయోగించుము." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"విహరించుటకు left లేక right సూచికలను నొక్కుము.అంశములలో తిరుగుటకు up లేక down సూచికలను " -"ఎంపిక చేసుకొనుము." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "జాబితాలోపలికి పోవుటకు కుడి సూచికను నొక్కుము." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"తగ్గించుటకు ఎడమ సూచికను, పెంచుటకు కుడి సూచికను నొక్కుము.చిన్నది చేయుటకు home పెద్దది చేయుటకు " -"end నొక్కుము." diff --git a/po/tg.po b/po/tg.po deleted file mode 100644 index 63707f4..0000000 --- a/po/tg.po +++ /dev/null @@ -1,9591 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Victor Ibragimov , 2013. -# -msgid "" -msgstr "" -"Project-Id-Version: Tajik Gnome\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2014-01-15 13:35+0500\n" -"Last-Translator: Victor Ibragimov \n" -"Language-Team: \n" -"Language: tg\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 1.6.3\n" - -msgid "Cthulhu Screen Reader" -msgstr "Хонандаи экрани Cthulhu" - -#, fuzzy -msgid "screen;reader;accessibility;speech;braille;" -msgstr "хонандаи экран;нутқ;брайл;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "огоҳ" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "тасв" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "тир" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "тақ" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "тас" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "зерн" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "брч" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "интрг" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "шуморагирӣ" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "кашидан" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "шакл" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "парол" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "Радио" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "шарт" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "tip" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "барнома" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "худкор" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Навъи чехии 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Навъи испании 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Навъи фаронсавии Канада 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Навъи фаронсавии Фаронса 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Навъи латвиягии 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Навъи голландии Нидерландия 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Навъи норвегиягии 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Навъи норвегиягии 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Навъи норвегиягии 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Навъи норвегиягии 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Навъи полякии 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Навъи португалии 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Навъи шведии 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Навъи арабии 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Навъи уэлсии 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Навъи уэлсии 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Навъи олмонии 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Навъи олмонии 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Навъи олмонии 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Навъи англисии Британия 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Навъи англисии Британия 2" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Навъи англисии ИМА 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Навъи англисии ИМА 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Навъи фаронсавии Канада 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Навъи фаронсавии Фаронса 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Навъи юнонӣ 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Навъи ҳиндӣ 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Компютери маҷористонии 8 нуқтагӣ" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Навъи маҷористонии 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "Навъи маҷористонии 1" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Навъи италиягии 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Навъи голландии Белгия 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "фосила" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "хати нав" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "варақа" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "хитоб" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "иқтибос" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "рақам" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "доллар" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "фоиз" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ва" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "апостроф" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "қавси чап" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "қавси рост" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "ситорача" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "ҷамъ" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "вергул" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "рах" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "нуқта" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "буриш" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "аломати баён" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "нуқтавергул" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "хурдтар" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "баробар" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "зиёдтар" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "савол" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "дар" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "камонаки чап" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "аломати хати каҷи баръакс" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "камонаки рост" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "аломати ^" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "зерхаткашӣ" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "паст" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "банди чап" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "навори амудӣ" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "банди рост" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "тилда" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "бе фазои ҷудо" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "нуқтаи хитоби баръакс" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "сент" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "фунт" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "аломати асъор" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "йен" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "навори шикаста" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "қисмат" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "ҳуқуқи муаллиф" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "абарнигошт а" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "қавси дукунҷаи чап" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "не-и мантиқӣ" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "тиреи нозук" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "сабтшуда" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "зада" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "дараҷа" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "ҷамъ ё тарҳ" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "абарнигошт 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "абарнигошт 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "нишонагузори банд" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "нуқтаи миёна" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "думча" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "абарнигошт 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "тартибӣ" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "қавси дукунҷаи рост" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "чоряк" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "нисф" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "аз чор се ҳисса" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "аломати саволи баръакс" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "а-и зада" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "А-и паст" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "А-и зада" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "А-и дароз" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "А-и тилда" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "А-и умляут" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "ҲАЛҚА" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "Ч (C CEDILLA)" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "Е-и паст" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "Е-и зада" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "Е-и дароз" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "Е-и умляут" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "И-и паст" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "И-и зада" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "И-и дароз" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "И-и умляут" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "-УМ" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "Н-и тилда" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "О-и паст" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "О-и зада" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "О-и дароз" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "О-и тилда" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "О-и умляут" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "зарб" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "О-и шикаста" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "У-и паст" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "У-и зада" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "У-и дароз" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "У-и умляут" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Й-и зада" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "Торн" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "с-и тез" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "а-и паст" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "а-и дароз" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "а-и тилда" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "а-и умбляут" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "а-и ҳалқа" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "с-и седил" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "е-и паст" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "е-и зада" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "е-и дароз" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "е-и умляут" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "и-и паст" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "и-и зада" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "и-и дароз" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "и-и умляут" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "-ум" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "н-и тилда" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "о-и паст" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "о-и зада" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "о-и дароз" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "о-и тилда" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "о-и умляут" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "тақсимшуда бо" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "о-и бурида" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "торн" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "у-и зада" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "у-и паст" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "у-и дароз" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "у-и умляут" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "й-и зада" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "й-и умляут" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Й-и умляут" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "флорин" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "тиреи поён" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "нохунаки яктогии чап" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "нохунаки яктогии рост" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "нохунаки яктогии поён" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "нохунаки дутогии чап" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "нохунаки дутогии рост" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "нохунаки дутогии поён" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "салибча" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "салибчаи дугона" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "нишон" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "нишони секунҷа" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "промил" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "нохунаки асосӣ" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "нохунаки асосии дутогӣ" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "нохунаки асосии дутогӣ" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "нишонаи тире" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "евро" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "Тамғаи корхона" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "аломати тасдиқ" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "аломати тасдиқи пурранг" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "нишрна дар шакли x" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "абарнигошт 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "абарнигошт 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "абарнигошт 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "абарнигошт 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "абарнигошт 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "абарнигошт 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "абарнигошт 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "ҷамъи абарнигошт" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "тарҳи абарнигошт" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "баробари абарнигошт" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "қавси чапи абарнигошт" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "қавси рости абарнигошт" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "абарнигошт n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "зернигошт 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "зернигошт 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "зернигошт 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "зернигошт 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "зернигошт 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "зернигошт 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "зернигошт 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "зернигошт 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "зернигошт 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "зернигошт 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "ҷамъи зернигошт" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "тарҳи зернигошт" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "баробари зернигошт" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "қавси чапи зернигошт" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "қавси рости зернигошт" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "чоркунҷаи сиёҳ" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "алмоси сиёҳ" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "Ба аломати оянда мегузарад." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "Курсорро ба объекти ҷорӣ равона месозад." - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Талаффуз кардани тамоми ҳуҷҷат" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "Талаффуз кардани тамоми ҳуҷҷат" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Ҳуҷҷат пурра интихоб шуд" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "Ба тугмаи навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "Талаффуз кардани навори вазъият" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "Талаффуз кардани навори унвон" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Равзанаи ҷустуҷӯиро мекушояд." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "" - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "Ба аввали хат мегузарад." - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "Ба аввали хат мегузарад." - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "" - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "Ба аломати қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "Ба аломати оянда мегузарад." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "Ба охири хат мегузарад." - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "Ба аввали хат мегузарад." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "Ба охири хат мегузарад." - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "Интихоб кардани сервери талаффузи дилхоҳ." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "Интихоб кардани сервери талаффузи дилхоҳ." - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "Танзимоти намуди садо" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "Зомини ҳолати намоиши муш." - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Хонандаи экранро хомӯш мекунад" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "Ба сарварақи навбатӣ дар сатҳи %d мегузарад." - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "Гузаштан ба ҷойгиршавии хатчӯби қаблӣ." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "Гузаштан ба хатчӯб." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "Гузаштан ба ҷойгиршавии хатчӯби навбатӣ." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "Илова кардани хатбарак." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "Захираи хатчӯбҳо." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "Зомини ҳолати намоиши муш." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "Вақти ҷории ҳозира." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "Санаи ҷории ҳозира." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Сафкашии чап" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Сафкашии рост" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Хат ба боло" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Хат ба поён" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Боздоштани тасвир" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Болои чап" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Поён чап" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Вазъияти курсор" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Шаш нуқтагӣ" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Масиргузории курсор" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Буридани ибтидо" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Буридани хат" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "Паёми огоҳии охирини ҳозира." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Рӯйхати паёмҳои огоҳии ҳозира." - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "Паёми огоҳии қаблии ҳозира." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "Паёми огоҳии охирини ҳозира." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Ба аломати оянда мегузарад." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "Ба аломати қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "Ба калимаи оянда мегузарад." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "Ба калимаи қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "Ба хати оянда мегузарад." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "Ба хати қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "Ба болои файл мегузарад." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "Ба поёни файл мегузарад." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Ба аввали хат мегузарад." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "Ба охири хат мегузарад." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "Ба объекти навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "Ба объекти навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "Боиси васеъ шудани менюи кушодашаванда мешавад." - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "" - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "Ба минтақаи истиқоматии охирине мегузарад, ки огоҳӣ додааст." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "Назорати қисмҳои фаъол" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Ба охири хат мегузарад." - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "Ба нақли қавли қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "Ба нақли қавли навбатӣ мегазарад." - -#: src/cthulhu/cmdnames.py:852 -#, fuzzy -msgid "Display a list of blockquotes" -msgstr "Рӯйхати нақли қавлҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "Ба тугмаи қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "Ба тугмаи навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Рӯйхати тугмаҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Ба байрақчаи қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Ба байрақчаи навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:870 -#, fuzzy -msgid "Display a list of check boxes" -msgstr "Рӯйхати байрақчаҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "Ба ҷадвали қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "Ба ҷадвали набатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "Рӯйхати ҷадвалҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "Ба ҷаъбаи мураккаби қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Ба ҷаъбаи мураккаби навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "Ба охири хат мегузарад." - -#: src/cthulhu/cmdnames.py:901 -#, fuzzy -msgid "Display a list of combo boxes" -msgstr "Рӯйхати ҷаъбаҳои мураккабро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "Ба вурудии қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "Ба вурудии навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "Рӯйхати вурудиҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "Ба майдони шакли қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "Ба майдони шакли навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:919 -#, fuzzy -msgid "Display a list of form fields" -msgstr "Рӯйхати шакли майдонҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "Ба сарварақи қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "Ба сарварақи навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "Рӯйхати сарварақҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Ба сарварақи қаблӣ дар сатҳи %d мегузарад." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Ба сарварақи навбатӣ дар сатҳи %d мегузарад." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Рӯйхати сарварақҳоро дар сатҳи %d намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "Ба ҷадвали қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "Ба ҷадвали набатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:949 -#, fuzzy -msgid "Display a list of internal frames" -msgstr "Рӯйхати ҷадвалҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "Ба хати қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "Ба хати оянда мегузарад." - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "Рӯйхати ҷадвалҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "Ба аломати марзии қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "Ба аломати марзии навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "Рӯйхати рамзҳои марзаро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Ба объекти калони қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Ба объекти калони навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Рӯйхати объектҳои калонро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "Ба хати қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "Ба хати оянда мегузарад." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Рӯйхати пайвандҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "Ба рӯйхати қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "Ба рӯйхати навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1006 -#, fuzzy -msgid "Display a list of lists" -msgstr "Рӯйхати рӯйхатҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Ба объекти рӯйхати қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Ба объекти рӯйхати навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "Рӯйхати объектҳои рӯйхатро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "Ба минтақаи истиқоматии қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "Ба минтақаи истиқоматии навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "Ба минтақаи истиқоматии охирине мегузарад, ки огоҳӣ додааст." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "Ба банди қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "Ба банди навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "Рӯйхатҳои бандҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Ба тугмаи радиои қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "Ба тугмаи радиои навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "Рӯйхати тугмаҳои радиоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "Ба ҷудокунандаи қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "Ба ҷудокунандаи навбатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "Ба ҷадвали қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "Ба ҷадвали набатӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "Рӯйхати ҷадвалҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "Як катак поён меравад" - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "Ба катаки аввалин дар ҷадвал мегузарад." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "Ба катаки охирин дар ҷадвал мегузарад." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "Як катак чап мегузарад." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "Як катак рост мегузарад." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "Як катак боло мегузарад." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "Зомини ҳолати намоиши муш." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "Ягон пайванди кушоданашудаи дигар нест." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "Ягон пайванди кушоданашудаи дигар нест." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "Рӯйхати пайвандҳоро намоиш медиҳад." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "Ба объекти рӯйхати қаблӣ мегузарад." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "Ягон пайванди кушодашудаи дигар нест." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "Рӯйхати пайвандҳоро намоиш медиҳад." - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "сиёҳ" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "алмоси сиёҳ" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "а-и паст" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "и-и паст" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "дараҷа" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "Навъи ҳиндӣ 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "банди рост" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "банди рост" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "қавси рост" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "банди рост" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "қавси рост" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "қавси рост" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "қавси рост" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "қавси рост" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "тири рост" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "хати нав" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "tre" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "дараҷа" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "btn" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "чоркунҷаи сафед" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Фаъол кардан" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Бекор кардан" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Гузариш ба" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_OK" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Ҳеҷ" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "имло" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Талаффузи паём аз" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Ҳамаи ка_налҳо" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Ҳамаи каналҳо ҳангоми фаъол будани равзанаи an_y %s" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "зеркунии дубора" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Синтезатори пешфарз" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Ҷ_ойгиршавии ҷорӣ" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Ёфтани имконот" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "вергул" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Тугмабандӣ" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Пешфарз" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "қисмат" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "Захираи хатчӯбҳо." - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "Вақт ва сана" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "Паймоиши саҳифа" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Начаспида" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Тағйирёфта" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Мизи корӣ" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Огоҳӣ" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Огоҳии %s" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Бартариҳои хонандаи экран барои %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Талаффуз кардан" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Бор кардани профили корбар" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Захира кардани профил ҳамчун" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Номи профил:" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "Бор кардани профили корбар" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Ҳама" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Барнома" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Равзана" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Ҳеҷ" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Баъзе" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Қисми зиёд" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Сатр" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Ҷумла" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Нақли қавл" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Тугма" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Зернавис" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Байрақча" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Ҷаъбаи мураккаб" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Тавсиф" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Сарлавҳа" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Барчасп" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Рамзи марза" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Сатҳ" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Пайванд" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Рӯйхат" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Объекти рӯйхат" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Объект" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Банд" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Тугмаи радио" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Нақш" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Интихоби объект" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Вазъият" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Матн" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Қимат" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Нақли қавлҳо" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Тугмаҳо" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Байрақчаҳо" - -#: src/cthulhu/guilabels.py:706 -#, fuzzy -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Ҷадвалҳо" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Ҷаъбаҳои мураккаб" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Вурудиҳо" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Майдонҳои шакл" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Сарлавҳаҳо" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Рамзҳои марза" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Объектҳои калон" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Пайвандҳо" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Рӯйхатҳо" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Объектҳои рӯйхат" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Бандҳо" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Ҷадвалҳо" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Паймоиши саҳифа" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Пешфарз" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Гиперпайванд" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Система" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Ҳарфҳои калон" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "Талаффуз кардани координатҳои _катак" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Талаффуз кардани _катак" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Талаффуз кардани координатҳои _катак" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Номи сифат" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Идоракунии паймоиш бо тугмаҳо" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Огоҳӣ" -msgstr[1] "Огоҳӣ" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "бозгашт" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "up" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "down" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "left" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "right" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "меню" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "кӯмак" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "чандгона" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "аломати тарҳ" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Дарҷ кардан" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "пурранг" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "хам" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr " зернигошт %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr " зернигошт %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Фазои корӣ " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "Мӯҳтаво %s аст" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "тири чап" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "тири чап" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "тири рост" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "тири чап" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "тири рост" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "тири рост" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "тири рост" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "тири чап" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "тири чап" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "тири рост" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "нохунаки дутогии чап" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "салибчаи дугона" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "нохунаки дутогии рост" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "салибчаи дугона" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "нохунаки дутогии рост" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "тири ишоратии рост" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "нӯки тири нишонагузории рост" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "аломати тарҳ" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "хурдтар" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "зиёдтар" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "а-и дароз" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "нуқта" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "нохунаки асосии дутогӣ" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "уфуқӣ" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "холӣ" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "Фаъол" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "зер" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "ҷамъ ё тарҳ" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "ҷамъ" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "аломати тарҳ" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "решаи квадрат" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "решаи куб" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "решаи квадрат" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "беохир" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "қавси рост" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "ягона" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "тақсимшуда бо" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "нобаробар ба" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "не-и мантиқӣ" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "не-и мантиқӣ" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "самт" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "нохунаки асосии дутогӣ" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "аломати тарҳ" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "тилда" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "н-и тилда" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "н-и тилда" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "тақрибан баробар ба" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "тақрибан баробар ба" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "тақрибан баробар ба" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "тақрибан баробар ба" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "тақрибан баробар ба" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "тақрибан баробар ба" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "а-и тилда" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "тақрибан баробар ба" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "сайтҳои гуногун" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "нобаробар ба" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "баробар" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "баробар" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "нобаробар ба" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "нобаробар ба" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "нишони секунҷа" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "баробар" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "нобаробар ба" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "нобаробар ба" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "амудӣ" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "нобаробар ба" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "нобаробар ба" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "зиёдтар" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "пахшнашуда" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "зернигошт 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "абарнигошт а" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "чандгона" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "баробаркунӣ" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "решаи квадрат" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "решаи квадрат" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "решаи квадрат" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "решаи квадрат" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "баробари зернигошт" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "тиреи поён" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "ҷамъи зернигошт" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "тарҳи зернигошт" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "решаи квадрат" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "решаи квадрат" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "камонаки рост" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "камонаки чап" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "down" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "қисмат" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "тартибӣ" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "чандгона" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "муқаррарӣ" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "нохунаки яктогии рост" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "банди рост" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "не-и мантиқӣ" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "не-и мантиқӣ" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "нохунаки асосии дутогӣ" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "нохунаки асосии дутогӣ" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "самт" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "нохунаки асосии дутогӣ" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "хурдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "зиёдтар аз ё баробар ба" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "амудӣ" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "қавси чап" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "қавси рост" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "қавси чап" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "қавси рост" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "банди чап" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "поён" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "қавси дукунҷаи чап" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "қавси дукунҷаи рост" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "нуқтаи миёна" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "Самти ҷустуҷӯ:" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "решаи квадрат" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "чоркунҷаи сиёҳ" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "чоркунҷаи сафед" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "алмоси сиёҳ" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "доираи сафед" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "доираи сиёҳ" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "нишони сафед" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "чоркунҷаи сиёҳ" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "зерхаткашӣ" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "Барнома" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "холӣ" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "пурранг" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "Ягон рамзи марза ёфт нашуд." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "Ягон рамзи марза ёфт нашуд." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "нишона" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "ҳеҷ" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "имло" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Катаки %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "интихобшуда" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "интихобшуда" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "ИМКОН" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Бор кардани профил" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "НОМ" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ФАЙЛ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "а-и зада" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "зудтар." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Паём аз хонаи чати %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Варақаи нави чати %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Талаффуз накардани номи хонаи чат" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "Талаффуз кардани номи хонаи чат" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "delete" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "insert" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "савол" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "Охири ҷадвал" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "интихобнашуда" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Тугмаи пешфарз %s аст" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Тугмаи пешфарз %s аст" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "Тугмаи пешфарз %s аст" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " зернигошт %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " абарнигошт %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "Ҳуҷҷат пурра интихоб шуд" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "Ҳуҷҷат пурра интихоб шуд" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "холӣ" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f килобайт" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f мегабайт" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Ягон файл ёфт нашуд." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "формула дорад" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "Равзанаи ҷустуҷӯиро мекушояд." - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Калиди нав: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "калид" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Ҳеҷ" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "Ба калимаи оянда мегузарад." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "ҷумла" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "калима" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "Ба калимаи оянда мегузарад." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "доираи сиёҳ" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "уфуқӣ" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "навори амудӣ" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "тири рост" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "ва" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "решаи квадрат" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "решаи куб" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "зернигошт 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "абарнигошт а" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "зернигошт 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "абарнигошт а" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "абарнигошт а" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "абарнигошт а" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "Фаъол" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "дастнорас" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Ғайрифаъол" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Фаъол" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "Ягон нохунаки блоки дигар нест." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Паймоиши саҳифа" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "нохунаки яктогии чап" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "пайванд" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ҳамон саҳифа" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ҳамон сайт" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "сайтҳои гуногун" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "пайванди %s" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "Ягон пайванди кушодашудаи дигар нест." - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Вуҷуд надорад" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Ҷойгиршавии ҷорӣ ёфт нашуд." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "ғайрифаъол" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "фаъол" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "хатогӣ" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Калимаҳои хатогӣ: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Мӯҳтаво %s аст" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -#, fuzzy -msgid "Object mode." -msgstr "Объект" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Ба объекти навбатӣ мегузарад." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Зомини ҳолати намоиши муш." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Талаффуз фаъл аст." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d фоиз." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "Ба калимаи қаблӣ мегузарад." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Ягон объект илова нашудааст" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Ягон барнома нуқтаи миёна надорад." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Бе фокус" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Ягон барнома нуқтаи миёна надорад." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Ягон нохунаки блоки дигар нест." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Ягон тугмаи дигар нест." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Ягон байрақчаи дигар нест." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Ягон объекти калони дигар нест." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Ягон ҷадвали дигар нест." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Ягон ҷаъбаи мураккаби дигар нест." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Ягон вуруди дигар нест." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Ягон шакли майдони дигар нест." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Ягон сарлавҳаи дигар нест." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Ягон сарлавҳаи дигар дар сатҳи %d нест." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "Ягон ҷадвали дигар нест." - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "Ягон ҷадвали дигар нест." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Ягон рамзи марза ёфт нашуд." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Ягон пайванди дигар нест." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Ягон рӯйхати дигар нест." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Ягон объекти дигар дар рӯйхат нест." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Ягон минтақаи зиндаи дигар нест." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Ягон банди дигар нест." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Ягон аломати қайди дигар нест." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Ягон ҷудокунандаи дигар нест." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Ягон ҷадвали дигар нест." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Ягон пайванди кушоданашудаи дигар нест." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Ягон пайванди кушодашудаи дигар нест." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "интихобнашуда" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "Ягон пайванди дигар нест." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Огоҳӣ" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Поён" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Боло" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "калима" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "Талаффузи паём аз" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "ғайрифаъол" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "фаъол" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Бор шуда истодааст. Интизор шавед." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Боркунӣ ба анҷом расид." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Боркунии %s ба анҷом расид." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Профил ба %s таъин шудааст." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Ягон профил ёфт нашуд." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Навори ҳолати ичро %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Ҳама" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Ҳеҷ" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Ҷустуҷӯ рафта истодааст." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Ҷустуҷӯ ба анҷом расид." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Хонандаи экрани Cthulhu" - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "Интихоби объект" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Интихоб кардани садои дилхоҳ:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "интихобнашуда" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Талаффуз ғайрифаъл аст." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Талаффуз фаъл аст." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "зудтар." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "оҳистатар." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "баландтар." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "пасттар." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "зудтар." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "_Баҳо:" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "сутуни %d" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "Ягон хидмат дастрас нест.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "Ягон садо дастрас нест.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "Талаффуз фаъл аст." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "Талаффуз истифода намешавад.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " нуқта нуқта нуқта" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Талаффуз дастрас нест." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Вуҷуд надорад" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "сатр ёфт нашудааст" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "сатр ёфт нашудааст" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Вуҷуд надорад" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Охири ҷадвал" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "сутуни %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Болои сутун." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "интихобнашуда" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "интихобнашуда" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "сатри %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "интихобнашуда" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "интихобнашуда" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "интихобшуда" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H соат, %M дақиқа ва %S сония." - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H соат ва %M дақиқа." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Юникод %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 объект" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d сутун" -msgstr[1] " %d сутун" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d гуфтугӯ)" -msgstr[1] "(%d гуфтугӯ)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d байт" -msgstr[1] "%d байт" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d файл ёфт шудааст" -msgstr[1] "%d файл ёфт шудаанд" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d шакл" -msgstr[1] "%d шакл" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d сарварақ" -msgstr[1] "%d сарварақ" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d объект" -msgstr[1] "%d объект" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Рамзи марза" -msgstr[1] "Рамзи марза" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d объект ёфт шуд" -msgstr[1] "%d объект ёфт шуданд" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Ягон нохунаки блоки дигар нест." -msgstr[1] "Ягон нохунаки блоки дигар нест." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "Қимат" -msgstr[1] "Қимат" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d сутун" -msgstr[1] "%d сутун" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d паём.\n" -msgstr[1] "%d паём.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d фоиз." -msgstr[1] "%d фоиз." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d фазо" -msgstr[1] "%d фазо" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d варақа" -msgstr[1] "%d варақа" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d ҷадвал" -msgstr[1] "%d ҷадвал" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "" -msgstr[1] "" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "иваз кардан" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "САТҲИ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "савол" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "Ба ҷаъбаи мураккаби навбатӣ мегузарад." - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "таҳриршаванда" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "калима" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "аломати баён" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "самт" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "калима" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "фосила" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "самт" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "иқтибос" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "уфуқӣ" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "навори амудӣ" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "уфуқӣ" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "навори амудӣ" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "уфуқӣ" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "навори амудӣ" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Лавҳаи нишонаҳо" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Огоҳӣ" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "зичшудаи нисфӣ" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Паймоиши саҳифа" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "Ҷустуҷӯ рафта истодааст." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "боздидшуда" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "Ягон тугмаи дигар нест." - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "густаришёфта" - -#: src/cthulhu/object_properties.py:511 -#, fuzzy -msgid "has long description" -msgstr "Тавсиф" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "уфуқӣ" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "амудӣ" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "интихобнашуда" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "фаъол" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "ғайрифаъол" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "пахшнашуда" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "интихобнашуда" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "интихобшуда" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "интихобнашуда" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "интихобнашуда" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "боздидшуда" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "боздиднашуда" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "танҳо барои хондан" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "лозимӣ" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "санҷиши имло" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "санҷиши имло" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Ёфтан" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Равзанаи гуфтугӯи ҷустуҷӯ дар Хонандаи экран" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Пӯшидан" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Ёфтан" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Ҷустуҷӯи:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Ҷустуҷӯи:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Болои равзана" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Болои равзана" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Самти ҷустуҷӯ:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Ёфтани имконот" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Пешфарз" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Ҳарфҳои калон" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Гиперпайванд" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Система" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Барнома" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Равзана" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "Хонандаи экрани Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Кӯмак" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Татбиқ кардан" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Лэптоп" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Тарҳбандии клавиатура" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Профили _фаъол:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Профили оғози кор:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Бор кардан" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Захира кардан ҳам_чун" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Профилҳо" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Муш" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Формати вақт:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Формати _сана:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Вақт ва сана" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "_Ҳамаро талаффуз кардан" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Шрифти Брайл" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Барнома" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Умумӣ" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Баҳо:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Шахс:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "забон" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Намуди садо:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Танзимоти намуди садо" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Танзимоти умумии садо" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Садо" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Фаъол кардани талаффуз" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Ҳама" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "Талаффуз кардани координатҳои _катак" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "Талаффуз кардани координатҳои _катак" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "Тавсиф" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Талаффуз" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Танзимоти дисплей" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Ҳеҷ" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Индикатори гиперпайвандҳо" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "Танзимоти умумии садо" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Шрифти Брайл" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "_Фаъол кардани талаффуз" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Тугмабандӣ" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Луғати талаффуз" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Вуруди нав" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Нест кардан" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Талаффуз" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Ҳамаро талаффуз кардан" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Талаффуз накардан" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Танзими дубора" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Интиқол додан ба _поён" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Интиқол додан ба як сатҳи _поён" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Интиқол додан ба як сатҳи _боло" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Интиқол додан ба _боло" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "паст" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "забон" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "йен" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "ранги пасзамина" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "самт" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "таҳриршаванда" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "номи оила" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "таъсири шрифт" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "фосила" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "хато" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "ноаён" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "баробаркунӣ" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "забон" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "ҳошияи чап" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "ҳошияи рост" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "тулӯъ" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "миқёсбандӣ" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "андоза" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "кашдиҳӣ" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "сабк" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "зерхаткашӣ" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "вариант" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "ғавсӣ" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ҳеҷ" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "хулоса" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "сиёҳ" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "ягона" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "дугона" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "паст" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "аломат" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "калима" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "чап" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "рост" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "марказ" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "пуркунӣ" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ултразичшуда" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "зичшудаи изофӣ" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "зичшуда" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "зичшудаи нисфӣ" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "муқаррарӣ" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "густаришёфтаи нисфӣ" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "густаришёфта" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "густаришёфтаи изофӣ" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ултрагустаришёфта" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "каҷ" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "хам" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Пешфарз" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Сарлавҳа" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "зер" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "супер" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "боло" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "болои матн" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "миёна" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "поён" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "поёни матн" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "меросӣ" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "ТБ" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "яклухт" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "санҷиши имло" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Барои зомин шудан фосиларо зер кунед." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Барои густариш додан фосиларо зер кунед, ва барои интихоби ягон объект боло " -"ва поёнро истифода баред." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Барои ҷалби диққат ба равзанаҳои иловагӣ alt+f6-ро зер кунед." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Барои ҳаракат ба объектҳо, ё аз калидҳои тир истифода баред ё дар ҷустуҷӯи " -"пешомада чоп кунед." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Барои дастрасӣ ба менюҳои система тугмаи alt+f1-ро зер кунед." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Барои фаъол кардан \"Enter\"-ро пахш кунед." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Навъи матн." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Барои намоиши варақаҳои дигар чап ва ростро истифода баред." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Барои фаъол кардан фосиларо зер намоед." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Барои интихоби қимат тири боло ё поёнро истифода баред. Ё дар қимати рақамии " -"дилхоҳ чоп кунед." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Барои тағйир додан калидҳои тирро истифода баред." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Барои паймудан, тири чап ё ростро зер кунед. Барои ҳаракат аз байни объектҳо " -"тири боло ё поёнро зер кунед." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Барои ворид шудан ба зер меню, тири ростро зер намоед." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Барои кам кардан тугмаи чапро зер кунед, барои зиёд кардан тугмаи ростро зер " -"кунед. Барои ба ҳадди ақал рафтан хонаро зер кунед, ва барои ҳадди аксар " -"анҷомро зер кунед." diff --git a/po/th.po b/po/th.po deleted file mode 100644 index 5a4879f..0000000 --- a/po/th.po +++ /dev/null @@ -1,9836 +0,0 @@ -# translation of cthulhu.HEAD.po to Thai -# Thai translation of cthulhu -# Copyright (C) 2006-2009 Free Software Foundation, Inc. -# This file is distributed under the same license as the cthulhu package. -# -# Supranee Thirawatthanasuk , 2006, 2007. -# Theppitak Karoonboonyanan , 2008-2009. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu.HEAD\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2009-02-23 11:19+0700\n" -"Last-Translator: Theppitak Karoonboonyanan \n" -"Language-Team: Thai \n" -"Language: th\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -msgid "Cthulhu Screen Reader" -msgstr "โปรแกรมอ่านหน้าจอ Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "หน้าจอ;อ่าน;การเข้าถึง;เสียงพูด;อักษรเบรลล์;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "วาด" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "คำแนะนำ" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "ภาษาเช็ก ระดับ 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "ภาษาสเปน ระดับ 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "ภาษาฝรั่งเศสแคนาดา ระดับ 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "ภาษาฝรั่งเศสฝรั่งเศส ระดับ 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "ภาษาลัตเวีย ระดับ 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "ภาษาดัตช์เนเธอร์แลนด์ ระดับ 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "ภาษานอร์เวย์ ระดับ 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "ภาษานอร์เวย์ ระดับ 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "ภาษานอร์เวย์ ระดับ 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "ภาษานอร์เวย์ ระดับ 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "ภาษาโปแลนด์ ระดับ 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "ภาษาโปรตุเกส ระดับ 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "ภาษาสวีเดน ระดับ 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "ภาษาอารบิก ระดับ 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "ภาษาเวลส์ ระดับ 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "ภาษาเวลส์ ระดับ 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "ภาษาเยอรมัน ระดับ 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "ภาษาเยอรมัน ระดับ 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "ภาษาเยอรมัน ระดับ 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "ภาษาอังกฤษบริติช ระดับ 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "ภาษาอังกฤษบริติช ระดับ 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "ภาษาอังกฤษอเมริกัน ระดับ 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "ภาษาอังกฤษอเมริกัน ระดับ 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "ภาษาฝรั่งเศสแคนาดา ระดับ 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "ภาษาฝรั่งเศสฝรั่งเศส ระดับ 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "ภาษากรีก ระดับ 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "ภาษาฮินดี ระดับ 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -#, fuzzy -msgid "Hungarian Grade 1" -msgstr "ภาษาลัตเวีย ระดับ 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "ภาษาเยอรมัน ระดับ 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "ภาษาอิตาลี ระดับ 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "ภาษาดัตช์เบลเยียม ระดับ 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "เว้นวรรค" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "บรรทัดใหม่" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "แท็บ" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "อัศเจรีย์" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "อัญประกาศ" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "ชาร์ป" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "ดอลลาร์" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "เปอร์เซ็นต์" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "และ" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "apostrophe" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "วงเล็บเปิด" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "วงเล็บปิด" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "ดอกจัน" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "บวก" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "จุลภาค" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "ประ" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "จุด" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "ทับ" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "ทวิภาค" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "อัฒภาค" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "น้อยกว่า" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "เท่ากับ" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "มากกว่า" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "ปรัศนี" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "แอต" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "วงเล็บเหลี่ยมเปิด" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "แบ็กสแลช" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "วงเล็บเหลี่ยมปิด" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "หมวกคว่ำ" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "ขีดล่าง" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "วงเล็บปีกกาเปิด" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "ขีดตั้ง" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "วงเล็บปีกกาปิด" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/chnames.py:187 -#, fuzzy -msgid "no break space" -msgstr "backspace" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "อัศเจรีย์หัวกลับ" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "เซ็นต์" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "ปอนด์" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "หน่วยเงินตรา" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "เยน" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "ขีดตั้งขาดกลาง" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "หัวข้อ" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "ลิขสิทธิ์" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "วงเล็บแหลมคู่เปิด" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "นิเสธ" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "ยัติภังค์ซอฟต์แวร์" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "จดทะเบียน" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "องศา" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "บวกลบ" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "ยกกำลังสอง" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "ยกกำลังสาม" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -#, fuzzy -msgid "acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "มิว" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "กำกับย่อหน้า" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "จุดกลาง" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "ยกกำลังหนึ่ง" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ออร์ดินัล" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "วงเล็บแหลมคู่ปิด" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "หนึ่งในสี่" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "ครึ่งหนึ่ง" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "สามในสี่" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "ปรัศนีหัวกลับ" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "คูณ" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O ขีดทับ" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "หาร" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o ขีดทับ" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "อัญประกาศเดี่ยวเปิด" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "อัญประกาศเดี่ยวปิด" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "อัญประกาศเดี่ยวล่าง" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "อัญประกาศเปิด" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "อัญประกาศปิด" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "อัญประกาศล่าง" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "dagger" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "double dagger" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "bullet" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "bullet สามเหลี่ยม" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "เปอร์มิลล์" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "ไพรม์" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "ดับเบิลไพรม์" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "ดับเบิลไพรม์" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "bullet ยัติภังค์" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "ยูโร" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "เครื่องหมายการค้า" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "ถูก" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "ถูกหนา" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "bullet รูปกากบาท" - -#: src/cthulhu/chnames.py:672 -#, fuzzy -msgid "superscript 0" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:676 -#, fuzzy -msgid "superscript 4" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:680 -#, fuzzy -msgid "superscript 5" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:684 -#, fuzzy -msgid "superscript 6" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:688 -#, fuzzy -msgid "superscript 7" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:692 -#, fuzzy -msgid "superscript 8" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:696 -#, fuzzy -msgid "superscript 9" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:700 -#, fuzzy -msgid "superscript plus" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:704 -#, fuzzy -msgid "superscript minus" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:708 -#, fuzzy -msgid "superscript equals" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:712 -#, fuzzy -msgid "superscript left paren" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:716 -#, fuzzy -msgid "superscript right paren" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:720 -#, fuzzy -msgid "superscript n" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:724 -#, fuzzy -msgid "subscript 0" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:728 -#, fuzzy -msgid "subscript 1" -msgstr "ยกกำลังหนึ่ง" - -#: src/cthulhu/chnames.py:732 -#, fuzzy -msgid "subscript 2" -msgstr "ยกกำลังสอง" - -#: src/cthulhu/chnames.py:736 -#, fuzzy -msgid "subscript 3" -msgstr "ยกกำลังสาม" - -#: src/cthulhu/chnames.py:740 -#, fuzzy -msgid "subscript 4" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:744 -#, fuzzy -msgid "subscript 5" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:748 -#, fuzzy -msgid "subscript 6" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:752 -#, fuzzy -msgid "subscript 7" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:756 -#, fuzzy -msgid "subscript 8" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:760 -#, fuzzy -msgid "subscript 9" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:764 -#, fuzzy -msgid "subscript plus" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:768 -#, fuzzy -msgid "subscript minus" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:772 -#, fuzzy -msgid "subscript equals" -msgstr "a ยกขึ้น" - -#: src/cthulhu/chnames.py:776 -#, fuzzy -msgid "subscript left paren" -msgstr "วงเล็บเปิด" - -#: src/cthulhu/chnames.py:780 -#, fuzzy -msgid "subscript right paren" -msgstr "วงเล็บปิด" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "สี่เหลี่ยมทึบ" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "ข้าวหลามตัดทึบ" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "ไปยังอักขระถัดไป" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "คลิกเมาส์ซ้ายที่รายการการสำรวจหน้าจอแบบแบนตรงตำแหน่งปัจจุบัน" - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "คลิกเมาส์ขวาที่รายการการสำรวจหน้าจอแบบแบนตรงตำแหน่งปัจจุบัน" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "อ่านออกเสียงเอกสารทั้งหมด" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "อ่านออกเสียงตรงบรรทัดปัจจุบันของการสำรวจหน้าจอแบบแบน" - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "อ่านข้อมูลตำแหน่งปัจจุบันอย่างคร่าวๆ" - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "อ่านข้อมูลตำแหน่งปัจจุบันอย่างละเอียด" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "อ่านออกเสียงตรงบรรทัดปัจจุบันของการสำรวจหน้าจอแบบแบน" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "อ่านออกเสียงบรรทัดว่าง" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "แสดงปุ่มเริ่มต้น" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "อ่านออกเสียงแถบสถานะ" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "อ่านออกเสียงหัวหน้าต่าง" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "เปิดกล่องโต้ตอบการค้นหา Cthulhu" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "แสดงรายการการกระทำ" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "ค้นหากรณีถัดไปของสตริง" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "ค้นหากรณีก่อนหน้าของสตริง" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "เข้าและออกจากการสำรวจหน้าจอแบบแบน" - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังตำแหน่งท้ายสุด" - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังตำแหน่งบ้านของผู้ใช้" - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังตำแหน่งท้ายสุด" - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังจุดเริ่มต้นของบรรทัดก่อนหน้า" - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "อ่านออกเสียงตรงบรรทัดปัจจุบันของการสำรวจหน้าจอแบบแบน" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "สะกดบรรทัดปัจจุบันของการสำรวจหน้าจอแบบแบน" - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "สะกดบรรทัดปัจจุบันของการสำรวจหน้าจอแบบแบน โดยออกชื่อพยัญชนะ" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังจุดเริ่มต้นของบรรทัดถัดไป" - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังรายการหรือคำก่อนหน้า" - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "อ่านออกเสียงรายการหรือคำของการสำรวจหน้าจอแบบแบนตรงตำแหน่งปัจจุบัน" - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "สะกดรายการหรือคำของการสำรวจหน้าจอแบบแบนตรงตำแหน่งปัจจุบัน" - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "สะกดรายการหรือคำของการสำรวจหน้าจอแบบแบนตรงตำแหน่งปัจจุบัน โดยออกชื่อพยัญชนะ" - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังรายการหรือคำถัดไป" - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังคำที่อยู่เหนือคำปัจจุบัน" - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "อ่านออกเสียงวัตถุของการสำรวจหน้าจอแบบแบนตรงตำแหน่งปัจจุบัน" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังคำที่อยู่ใต้คำปัจจุบัน" - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังอักขระที่อยู่ก่อนหน้า" - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "อ่านออกเสียงอักขระที่ตำแหน่งปัจจุบันของการสำรวจหน้าจอแบบแบน" - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "อ่านออกเสียงอักขระที่ตำแหน่งปัจจุบันของการสำรวจหน้าจอแบบแบน โดยออกชื่อพยัญชนะ" - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "อ่านออกเสียงอักขระที่ตำแหน่งปัจจุบันของการสำรวจหน้าจอแบบแบน" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังอักขระถัดไป" - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังท้ายบรรทัด" - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังล่างซ้าย" - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "อ่านออกเสียงรายการหรือคำของการสำรวจหน้าจอแบบแบนตรงตำแหน่งปัจจุบัน" - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "อ่านออกเสียงรายการหรือคำของการสำรวจหน้าจอแบบแบนตรงตำแหน่งปัจจุบัน" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังตำแหน่งท้ายสุด" - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "สลับวิธีอ่าน ว่าจะอ่านเฉพาะช่องตารางปัจจุบัน หรืออ่านทั้งแถว" - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "อ่านคุณลักษณะที่สัมพันธ์กับอักขระข้อความปัจจุบัน" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "กวาดการแสดงอักษรเบรลล์ไปยังด้านซ้าย" - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "กวาดการแสดงอักษรเบรลล์ไปยังด้านขวา" - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "กลับไปที่วัตถุที่ได้โฟกัสแป้นพิมพ์อยู่" - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "เ_ปิดใช้อักษรเบรลล์แบบย่อ" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "ไปยังต้นบรรทัด" - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "ไปยังท้ายบรรทัด" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "เข้าโหมดเรียนรู้ กด escape เพื่อออกจากโหมดเรียนรู้" - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "ลดอัตราเร็วเสียงพูด" - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "เพิ่มอัตราเร็วเสียงพูด" - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "ลดระดับเสียงพูด" - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "เพิ่มระดับเสียงพูด" - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "เพิ่มอัตราเร็วเสียงพูด" - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "ลดอัตราเร็วเสียงพูด" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "เลือกการตั้งค่าเสียงพูดก่อนหน้า" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "เลือกการตั้งค่าเสียงพูดถัดไป" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "ลดการตั้งค่าเสียงพูดปัจจุบัน" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "เพิ่มการตั้งค่าเสียงพูดปัจจุบัน" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "บันทึกการตั้งค่าเสียงพูด" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "เปิด/ปิดเสียงพูด" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "สลับโหมดพักเครื่อง" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "แสดงกล่องโต้ตอบการกำหนดค่าปรับแต่ง" - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "แสดงกล่องโต้ตอบการกำหนดค่าปรับแต่งของโปรแกรมประยุกต์" - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "อ่านออกเสียงการร่น_ข้อความและการจัดชิดขอบ" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "วนไปยังตำแหน่งถัดไปของแว่นขยาย" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "วนไปยังตำแหน่งถัดไปของแว่นขยาย" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "วนไปยังตำแหน่งถัดไปของแว่นขยาย" - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "วนไปยังตำแหน่งถัดไปของแว่นขยาย" - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "วนไปยังตำแหน่งถัดไปของแว่นขยาย" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "วนค่าระดับการดีบั๊กขณะทำงาน" - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "อ่านข้อมูลของที่คั่นหน้าเทียบกับตำแหน่งปัจจุบัน" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "ไปยังตำแหน่งที่คั่นหน้าก่อนหน้า" - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "ไปยังตำแหน่งที่คั่นหน้า" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "ไปยังตำแหน่งที่คั่นหน้าถัดไป" - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "เพิ่มที่คั่นหน้า" - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "บันทึกที่คั่นหน้า" - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "เปิด/ปิดการสำรวจหน้าจอด้วยเมาส์" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "ส่งคำสั่งถัดไปต่อให้กับโปรแกรมปัจจุบัน" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "อ่านออกเสียงและแสดงอักษรเบรลล์ข้อความในห้องสนทนาข้อความก่อน" - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "สลับว่าจะประกาศเมื่อคู่สนทนากำลังพิมพ์หรือไม่" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "สลับว่าจะแสดงประวัติข้อความเฉพาะของห้องสนทนาหรือไม่" - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "สลับว่าจะแสดงชื่อห้องหน้าข้อความในห้องสนทนาหรือไม่" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "เลื่อนบรรทัดไปทางซ้าย" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "เลื่อนบรรทัดไปทางขวา" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "เลื่อนบรรทัดขึ้น" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "เลื่อนบรรทัดลง" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "ค้างไว้" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "ซ้ายบน" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "ครึ่งล่าง" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "ตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "" - -#: src/cthulhu/cmdnames.py:689 -#, fuzzy -msgid "Cursor Routing" -msgstr "ตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "" - -#: src/cthulhu/cmdnames.py:703 -#, fuzzy -msgid "Cut Line" -msgstr "บรรทัด" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "ไปยังอักขระถัดไป" - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "ไปยังอักขระก่อนหน้า" - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "ไปยังคำถัดไป" - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "ไปยังคำก่อนหน้า" - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "ไปยังบรรทัดถัดไป" - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "ไปยังบรรทัดก่อนหน้า" - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "ไปยังต้นแฟ้ม" - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "ไปยังท้ายแฟ้ม" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "ไปยังต้นบรรทัด" - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "ไปยังท้ายบรรทัด" - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "ไปยังวัตถุชิ้นถัดไป" - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "ไปยังวัตถุชิ้นก่อนหน้า" - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "ทำให้กล่องคอมโบปัจจุบันขยายออก" - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "สลับไปมาระหว่างการท่องดูด้วยเคอร์เซอร์ของ Gecko เองกับของ Cthulhu" - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "เลื่อนระดับความสุภาพของพื้นที่แสดงสด" - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "กำหนดระดับความสุภาพปริยายของพื้นที่แสดงสดเป็นค่าปิด" - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "ประกาศการสำรวจพื้นที่แสดงสด" - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "เฝ้าสังเกตพื้นที่แสดงสด" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "กำหนดแถวที่จะใช้เป็นหัวคอลัมน์ชนิดแปรเปลี่ยน สำหรับการอ่านออกเสียงช่องตาราง calc" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "ล้างหัวคอลัมน์ชนิดแปรเปลี่ยน" - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "กำหนดคอลัมน์ที่จะใช้เป็นหัวแถวชนิดแปรเปลี่ยน สำหรับการอ่านออกเสียงช่องตาราง calc" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "ล้างหัวแถวชนิดแปรเปลี่ยน" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "อ่านออกเสียงเนื้อหาของบรรทัดที่รับข้อความ" - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "เปิด/ปิดการใช้ปุ่มท่องดูตามโครงสร้าง" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "ไปยังบล็อคอ้างคำพูดก่อนหน้า" - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "ไปยังบล็อคอ้างคำพูดถัดไป" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "ไปยังปุ่มก่อนหน้า" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "ไปยังปุ่มถัดไป" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "แสดงตัวเลือกเพิ่มเติม" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "ไปยังกล่องกาก่อนหน้า" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "ไปยังกล่องกาถัดไป" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "ไปยังตารางก่อนหน้า" - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "ไปยังตารางถัดไป" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "ไปยังกล่องคอมโบก่อนหน้า" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "ไปยังกล่องคอมโบถัดไป" - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "เครื่องบรรจุ html" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "เครื่องบรรจุ html" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "ไปยังช่องป้อนข้อความก่อนหน้า" - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "ไปยังช่องป้อนข้อความถัดไป" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "ไปยังช่องข้อมูลแบบฟอร์มช่องก่อนหน้า" - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "ไปยังช่องข้อมูลแบบฟอร์มช่องถัดไป" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "ไปยังหัวข้อก่อนหน้า" - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "ไปยังหัวข้อถัดไป" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "ไปยังหัวข้อก่อนหน้าที่ระดับ %d" - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "ไปยังหัวข้อถัดไปที่ระดับ %d" - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "ไม่มีหัวข้ออีกในระดับ %d" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "ไปยังตารางก่อนหน้า" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "กรอบภายใน" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "ไปยังบรรทัดก่อนหน้า" - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "ไปยังบรรทัดถัดไป" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "ไปยังตำแหน่งสำคัญตำแหน่งก่อนหน้า" - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "ไปยังตำแหน่งสำคัญตำแหน่งถัดไป" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "ไปยังวัตถุใหญ่ชิ้นก่อนหน้า" - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "ไปยังวัตถุใหญ่ชิ้นถัดไป" - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "ไม่มีวัตถุใหญ่อีก" - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "ไปยังบรรทัดก่อนหน้า" - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "ไปยังบรรทัดถัดไป" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "แสดงตัวเลือกเพิ่มเติม" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "ไปยังรายชื่อก่อนหน้า" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "ไปยังรายชื่อถัดไป" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "ไปยังรายการก่อนหน้าในรายชื่อ" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "ไปยังรายการถัดไปในรายชื่อ" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "ไปยังพื้นที่แสดงสดก่อนหน้า" - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "ไปยังพื้นที่แสดงสดถัดไป" - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "ประกาศการสำรวจพื้นที่แสดงสด" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "ไปยังพาเรนต์ของวัตถุที่มีโฟกัสตัวนำทาง" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "ไปยังลูกตัวแรกของวัตถุที่มีโฟกัสตัวนำทาง" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "ไปยังพี่น้องถัดไปของวัตถุที่มีโฟกัสตัวนำทาง" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "ไปยังพี่น้องก่อนหน้าของวัตถุที่มีโฟกัสตัวนำทาง" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "กลับไปที่วัตถุที่ได้โฟกัสแป้นพิมพ์อยู่" - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "เปิด/ปิดการใช้ปุ่มท่องดูตามโครงสร้าง" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "ไปยังย่อหน้าก่อนหน้า" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "ไปยังย่อหน้าถัดไป" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "ไปยังปุ่มวิทยุก่อนหน้า" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "ไปยังปุ่มวิทยุถัดไป" - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "ไม่มีปุ่มวิทยุอีก" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "ไปยังย่อหน้าก่อนหน้า" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "ไปยังย่อหน้าถัดไป" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "ไปยังตารางก่อนหน้า" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "ไปยังตารางถัดไป" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "เลื่อนลงหนึ่งช่องตาราง" - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "ไปยังช่องแรกสุดของตาราง" - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "ไปยังช่องท้ายสุดของตาราง" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "เลื่อนไปทางซ้ายหนึ่งช่องตาราง" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "เลื่อนไปทางขวาหนึ่งช่องตาราง" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "เลื่อนขึ้นหนึ่งช่องตาราง" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "เปิด/ปิดการสำรวจหน้าจอด้วยเมาส์" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "เปิดใช้งานการออกเ_สียงแป้นพิมพ์" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "ไปยังลิงก์ก่อนหน้าที่ยังไม่ได้ดู" - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "ไปยังลิงก์ถัดไปที่ยังไม่ได้ดู" - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "ไม่มีลิงก์ที่ยังไม่ดูอีก" - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "ไปยังลิงก์ก่อนหน้าที่ดูแล้ว" - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "ไปยังลิงก์ถัดไปที่ดูแล้ว" - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "ไม่มีลิงก์ที่ดูแล้วอีก" - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "เพิ่มสีน้ำเงิน" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "ดำ" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "ข้าวหลามตัดทึบ" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "เพิ่มสีน้ำเงิน" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "เพิ่มสีน้ำเงิน" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "a grave" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "เพิ่มสีเขียว" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "เพิ่มสีเขียว" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "เพิ่มสีแดง" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "เพิ่มสีเขียว" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "เพิ่มสีน้ำเงิน" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i grave" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "ลดสีเขียว" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "ปิดใช้งาน" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "องศา" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "ภาษาฮินดี ระดับ 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "วงเล็บปีกกาปิด" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "ปุ่ม control ขวา" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "วงเล็บปิด" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "วงเล็บปีกกาปิด" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "วงเล็บปิด" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "วงเล็บปิด" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "ปุ่ม alt ขวา" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "วงเล็บปิด" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "super ขวา" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "บรรทัดใหม่" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "ภาพ" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "ลดสีน้ำเงิน" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "เพิ่มสีแดง" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "เพิ่มสีเขียว" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "end" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "เพิ่มสีน้ำเงิน" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "หน้าจอ %s" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "ลดสีน้ำเงิน" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "ลดสีน้ำเงิน" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "แท็บ" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "บรรทัดว่าง" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "บรรทัดว่าง" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "เต็มจอ" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "จุด _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "จุด _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "จุด 7 แ_ละ 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "ไอคอน" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "ไม่มี" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "สะกดคำ:" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "ประกาศเมื่อคู่_สนทนากำลังพิมพ์" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "แสดงประวัติ_ข้อความเฉพาะของห้องสนทนา" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "อ่านออกเสียงข้อความจาก" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "ทุก_ห้อง" - -#: src/cthulhu/guilabels.py:173 -#, fuzzy, python-format -msgid "All channels when an_y %s window is active" -msgstr "ทุกห้องเมื่อมีหน้าต่างของ Pidgin ได้โ_ฟกัส" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "เ_ฉพาะห้องที่หน้าต่างโฟกัสอยู่เท่านั้น" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_อ่านออกเสียงชื่อห้องสนทนา" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -#, fuzzy -msgid "double click" -msgstr "(คลิกซ้อนสองครั้ง)" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -#, fuzzy -msgid "triple click" -msgstr "(คลิกซ้อนสามครั้ง)" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "ตัวสังเคราะห์เสียงปริยาย" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "ข้อความจริง" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "ข้อความสำหรับอ่าน" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -#, fuzzy -msgid "Enable echo by cha_racter" -msgstr "เปิดใช้งานการออกเสียงทีละ_คำ" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -#, fuzzy -msgid "Enable non-spacing _diacritical keys" -msgstr "เปิดใช้งานปุ่มท่อ_งสำรวจ" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "ตำแหน่ง_ปัจจุบัน" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "ความยาวต่ำสุดของข้อความที่ตรง:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "ตัวเลือกการค้นหา" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "อ่านออกเสียงเฉพาะเมื่อเ_ปลี่ยนบรรทัดเท่านั้นขณะค้นหา" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "อ่านออกเสียงสิ่งที่พบขณะ_ค้นหา" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "จุลภาค" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "ปุ่มลัด" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "ค่าปริยาย" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "ออกจากโหมดเรียนรู้" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "การกระทำ" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ปุ่มลัดเบรลล์" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "ที่คั่นหน้า" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "การท่องดูตาราง" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "ไม่มีปุ่มเรียก" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "มีการแก้ไข" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "เ_ดสก์ท็อป" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "การแจ้งเหตุ %s" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "ได้รับแล้ว" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "การแจ้งเหตุ %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "ค่าปรับแต่ง Cthulhu สำหรับ %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "เน้นในอักษรเบรลล์" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "นำเสนอนอกจาก" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "อ่านออกเสียง" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -#, fuzzy -msgctxt "ProgressBar" -msgid "All" -msgstr "ทั้ง_หมด" - -#: src/cthulhu/guilabels.py:504 -#, fuzzy -msgctxt "ProgressBar" -msgid "Application" -msgstr "โปรแกรม" - -#: src/cthulhu/guilabels.py:509 -#, fuzzy -msgctxt "ProgressBar" -msgid "Window" -msgstr "หน้าต่าง" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -#, fuzzy -msgctxt "punctuation level" -msgid "_None" -msgstr "_ไม่" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "ออกเสียงบ้_าง" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "ออกเสียงเ_กือบทั้งหมด" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "บรรทัด" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "ประโยค" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "อัญประกาศ" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "ปุ่ม" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "ป้ายบรรยาย" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "กล่องกาเครื่องหมาย" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "กล่องคอมโบ" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "ป้ายบรรยาย" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "หัวข้อ" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "กรอบภายใน" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "ภาพ" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "ป้ายชื่อ" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "เครื่องหมายการค้า" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "ลิงก์" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "รายชื่อ" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "รายการในรายชื่อ" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "ย่อหน้า" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "ปุ่มวิทยุ" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "เลือกแล้ว" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "สถานะ" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "ข้อความ" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "ไม่มีบล็อคอ้างคำพูดอีก" - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "ปุ่ม" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "กล่องกาเครื่องหมาย" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "กล่องคอมโบ" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "หัวข้อ" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "กรอบภายใน" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "ภาพ" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "ไม่มีหัวข้ออีกในระดับ %d" - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "เครื่องหมายการค้า" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "ไม่มีวัตถุใหญ่อีก" - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "ลิงก์" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "รายชื่อ" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "รายการในรายชื่อ" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "ย่อหน้า" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "ปุ่มวิทยุ" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "ตาราง" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d ลิงก์ที่ยังไม่ดู" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d ลิงก์ที่ดูแล้ว" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "การท่องดูหน้าเว็บ" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "_อ่านออกเสียงหน้าเว็บทันทีที่เปิดครั้งแรก" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "_อ่านออกเสียงหน้าเว็บทันทีที่เปิดครั้งแรก" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "เสียงปริยายของ %s" - -#: src/cthulhu/guilabels.py:832 -#, fuzzy -msgctxt "VoiceType" -msgid "Default" -msgstr "ค่าปริยาย" - -#: src/cthulhu/guilabels.py:836 -#, fuzzy -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "ไฮเพอร์ลิงก์" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "" - -#: src/cthulhu/guilabels.py:848 -#, fuzzy -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "ตัวพิมพ์ใหญ่" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -#, fuzzy -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "สะกดคำ:" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "อ่านออกเสียงพิกัดช่องตารางของตารางคำนวณ" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "ประกาศ_หัวของช่องตาราง" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "การท่องดูตาราง" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "ข้ามช่องตารางเ_ปล่า" - -#: src/cthulhu/guilabels.py:905 -#, fuzzy -msgid "Speak _cell" -msgstr "อ่านออกเสียงช่องตาราง" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "อ่านออกเสียงพิกัด_ช่องตาราง" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "อ่านออกเสียงช่องตารางที่เกยห_ลายช่อง" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "ชื่อคุณลักษณะ" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "ใช้การ_ท่องดูด้วยเคอร์เซอร์ของ Cthulhu" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "เปิด/ปิดการใช้ปุ่มท่องดูตามโครงสร้าง" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "ธีม_เสียง:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "ธีมเสียง" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "โดยย่_อ" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "ไม่เรียงชิดขอบ" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt_R" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "ปุ่ม control ซ้าย" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "ปุ่ม shift ซ้าย" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "ปุ่ม alt ซ้าย" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ปุ่ม control ซ้าย" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "ปุ่ม shift ขวา" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "ปุ่ม alt ขวา" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "ปุ่ม control ขวา" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ปุ่ม meta ซ้าย" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "ปุ่ม meta ขวา" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "แท็บซ้าย" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "ขึ้น" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "ลง" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "ซ้าย" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "ขวา" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super ซ้าย" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super ขวา" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "เมนู" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "วิธีใช้" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "สลับโหมด" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "" - -#: src/cthulhu/keynames.py:276 -#, fuzzy -msgid "circumflex" -msgstr "a circumflex" - -#: src/cthulhu/keynames.py:291 -#, fuzzy -msgid "ring" -msgstr "a ring" - -#: src/cthulhu/keynames.py:301 -#, fuzzy -msgid "stroke" -msgstr "o ขีดทับ" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "ลบ" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "หนา" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "ตัวเอียง" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "a ยกขึ้น" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "พื้นที่ทำงาน " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "บริบทคือ %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "วงเล็บเปิด" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "ลูกศร" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "วงเล็บปิด" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "ลูกศร" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "ลูกศรชี้ขวา" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "อัญประกาศเปิด" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "double dagger" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "อัญประกาศปิด" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "double dagger" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "อัญประกาศปิด" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "ลูกศรชี้ขวา" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "หัวลูกศรชี้ขวา" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "ลบ" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "น้อยกว่า" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "มากกว่า" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "a circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "จุด" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "การเรียงชิดขอบแนวดิ่ง" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "แนวนอน" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "เติมเต็มคำอัตโนมัติ" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "ว่างเปล่า" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "ท้ายแถว" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "ตัวห้อย" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "บวกลบ" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "บวก" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "ลบ" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "ขีดคั่น" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "รากที่สาม" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "ตามสัดส่วนพิกัด" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "อนันต์" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "ปุ่ม alt ขวา" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "เส้นเดี่ยว" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "การเรียงชิดขอบแนวดิ่ง" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "หาร" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "ขีดคั่น" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "ไม่เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "นิเสธ" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "นิเสธ" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "ทิศทางการเขียน" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "กรอบภายใน" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "ดับเบิลไพรม์" - -#: src/cthulhu/mathsymbols.py:1512 -#, fuzzy -msgctxt "math symbol" -msgid "triple integral" -msgstr "ระยะเวลาการอ่าน:" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -#, fuzzy -msgctxt "math symbol" -msgid "surface integral" -msgstr "ระยะเวลาการอ่าน:" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "ตามสัดส่วนพิกัด" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "ลบ" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "tilde" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "ประมาณ" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "ประมาณ" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "ประมาณ" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "ประมาณ" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "ประมาณ" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "ประมาณ" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "a tilde" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "ประมาณ" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "คนละไซต์" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "ไม่เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "ไม่เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "ไม่เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "bullet สามเหลี่ยม" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "ไม่เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "ไม่เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "แนวตั้ง" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "ไม่เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "ไม่เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "มากกว่า" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "ไม่ได้กด" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "a ยกขึ้น" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "เลือกได้หลายข้อ" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "การเรียงชิดขอบ" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "เลือกได้หลายข้อ" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "เท่ากับ" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "en dash" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "บวกลบ" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "ปุ่ม meta ขวา" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "แท็บซ้าย" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "ลง" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "หัวข้อ" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "จริง" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "จริง" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ออร์ดินัล" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "ภาพ" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "กรอบภายใน" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "ปกติ" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "อัญประกาศเดี่ยวปิด" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "วงเล็บปีกกาปิด" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "ขีดคั่น" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "นิเสธ" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "นิเสธ" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "ดับเบิลไพรม์" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "ดับเบิลไพรม์" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "ทิศทางการเขียน" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "ดับเบิลไพรม์" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "น้อยกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "มากกว่าหรือเท่ากับ" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "การเรียงชิดขอบแนวดิ่ง" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "วงเล็บเปิด" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "วงเล็บปิด" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "ปุ่ม alt ซ้าย" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "ปุ่ม alt ขวา" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "วงเล็บปีกกาเปิด" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "ล่าง" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "วงเล็บแหลมคู่เปิด" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "วงเล็บแหลมคู่ปิด" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "จุดกลาง" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "รากที่สอง" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "สี่เหลี่ยมทึบ" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "สี่เหลี่ยมโปร่ง" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "ข้าวหลามตัดทึบ" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "วงกลมโปร่ง" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "วงกลมทึบ" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "bullet โปร่ง" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "สี่เหลี่ยมทึบ" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "ขีดล่าง" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "การเรียงชิดขอบแนวดิ่ง" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "โปรแกรม" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "ว่าง" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "หนา" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "เข้าสู่ที่คั่นหน้า" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "บันทึกที่คั่นหน้าแล้ว" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "ไม่สามารถบันทึกที่คั่นหน้า" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "ไม่พบตำแหน่งสำคัญ" - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "ไม่พบตำแหน่งสำคัญ" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "เปิดใช้โหมดส่งผ่าน" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "ไม่สามารถอ่านค่าดิสเพลย์ของเครื่องคิดเลข" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "ไอคอน" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "" - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "ไม่มี" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "" - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "สะกดผิด" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "Gecko กำลังควบคุมเคอร์เซอร์" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu กำลังควบคุมเคอร์เซอร์" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "เซลล์ %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "เลือกแล้ว" - -#: src/cthulhu/messages.py:186 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "เลือกรายการ %d ใน %d รายการ" - -#: src/cthulhu/messages.py:193 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "เลือกรายการ %d ใน %d รายการ" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "ป้องกันการใช้ตัวเลือก" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "บังคับใช้ตัวเลือก" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "พิมพ์โปรแกรมที่รู้จักที่ทำงานอยู่" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "ไม่สามารถบันทึกที่คั่นหน้า" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "ใช้ค่าปรับแต่งสำหรับผู้ใช้จากไดเรกทอรีที่กำหนด" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "พิมพ์โปรแกรมที่รู้จักที่ทำงานอยู่" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "แสดงข้อความวิธีใช้นี้" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "ตั้งค่าปรับแต่งสำหรับผู้ใช้ (ฉบับข้อความ)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "ตั้งค่าปรับแต่งสำหรับผู้ใช้ (ฉบับข้อความ)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "รายงานข้อผิดพลาดไปยัง https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "a acute" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "เร็วขึ้น" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "ไม่ต้องประกาศเมื่อคู่สนทนากำลังพิมพ์" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "ประกาศเมื่อคู่สนทนากำลังพิมพ์" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "ข้อความจากห้องสนทนา %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "แท็บห้องสนทนาใหม่ %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "ไม่ต้องอ่านชื่อห้องสนทนา" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "อ่านชื่อห้องสนทนา" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "ไม่ต้องแสดงประวัติข้อความเฉพาะของห้องสนทนา" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "แสดงประวัติข้อความเฉพาะของห้องสนทนา" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "delete" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "insert" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "ปรัศนี" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "เครื่องบรรจุ html" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "ไม่อยู่ในตาราง" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "เลือกอยู่" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "ปุ่มปริยายคือ %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "ปุ่มปริยายคือ %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "ปุ่มปริยายคือ %s" - -#: src/cthulhu/messages.py:518 -#, fuzzy, python-format -msgid " subscript %s" -msgstr "a ยกขึ้น" - -#: src/cthulhu/messages.py:524 -#, fuzzy, python-format -msgid " superscript %s" -msgstr "a ยกขึ้น" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "ไม่อยู่ในตาราง" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "เลือกทั้งเอกสารอยู่" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "เลือกทั้งเอกสารอยู่" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "เลือกลงมาจากตำแหน่งเคอร์เซอร์ถึงท้ายเอกสาร" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "เลิกเลือกลงมาจากตำแหน่งเคอร์เซอร์ถึงท้ายเอกสาร" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "เลือกขึ้นไปจากตำแหน่งเคอร์เซอร์ถึงต้นเอกสาร" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "เลิกเลือกขึ้นไปจากตำแหน่งเคอร์เซอร์ถึงต้นเอกสาร" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "หัวคอลัมน์ชนิดแปรเปลี่ยนสำหรับแถว %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "ล้างหัวคอลัมน์ชนิดแปรเปลี่ยนเรียบร้อยแล้ว" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "หัวแถวชนิดแปรเปลี่ยนสำหรับคอลัมน์ %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "ล้างหัวแถวชนิดแปรเปลี่ยนเรียบร้อยแล้ว" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "ว่างเปล่า" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f กิโลไบต์" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f เมกะไบต์" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "ไม่พบแฟ้ม" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "" - -#: src/cthulhu/messages.py:634 -#, fuzzy -msgid "Entering flat review." -msgstr "เข้าและออกจากการสำรวจหน้าจอแบบแบน" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "เลื่อนการสำรวจหน้าจอแบบแบนไปยังคำที่อยู่เหนือคำปัจจุบัน" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "ตรวจสอบแบบแบนไม่จำกัด" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "มีสูตร" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "กล่องโต้ตอบ" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "เมนูผุดขึ้น" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "ลิงก์ใน image map" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "ปุ่มลัดที่กดได้เชื่อมโยงกับ %s อยู่ก่อนแล้ว" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "ปุ่มที่จับได้: %s กรุณากด enter เพื่อยืนยัน" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "ปุ่มใหม่คือ: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "ปุ่มลัดถูกลบแล้ว กรุณากด enter เพื่อยืนยัน" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "ปุ่มลัดถูกลบแล้ว" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "กดเพื่อป้อนปุ่มใหม่" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "" - -#: src/cthulhu/messages.py:761 -#, fuzzy -msgctxt "key echo" -msgid "None" -msgstr "ไม่มี" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "ไปยังคำถัดไป" - -#: src/cthulhu/messages.py:813 -#, fuzzy -msgctxt "key echo" -msgid "sentence" -msgstr "ประโยค" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "เปิดใช้งานการออกเสียงทีละ_ประโยค" - -#: src/cthulhu/messages.py:839 -#, fuzzy -msgctxt "key echo" -msgid "word" -msgstr "คำ" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "ไปยังคำถัดไป" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "วงกลมทึบ" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "แนวนอน" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "ขีดตั้ง" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "กำลังเริ่มหาใหม่จากท้ายหน้า" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "ความสูงบรรทัด" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "และ" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "ขีดเส้นบน" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "รากที่สอง" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "รากที่สาม" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "ช่องหลัก" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "ช่องหลัก" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "ช่องหลัก" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "a ยกขึ้น" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "a ยกขึ้น" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "a ยกขึ้น" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "a ยกขึ้น" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "ขีดล่าง" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "a ยกขึ้น" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "ตาราง" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "ตารางแบบต้นไม้" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "ไม่มีสิ่งอำนวยความสะดวก" - -#: src/cthulhu/messages.py:1169 -#, fuzzy -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "แก้ไขได้" - -#: src/cthulhu/messages.py:1174 -#, fuzzy -msgid "Speaking of indentation and justification disabled." -msgstr "อ่านออกเสียงการร่น_ข้อความและการจัดชิดขอบ" - -#: src/cthulhu/messages.py:1179 -#, fuzzy -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "เปิดใช้เ_ส้นขอบ" - -#: src/cthulhu/messages.py:1184 -#, fuzzy -msgid "Speaking of indentation and justification enabled." -msgstr "อ่านออกเสียงการร่น_ข้อความและการจัดชิดขอบ" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "โหมดเรียนรู้ กด escape เพื่อออกจากโหมด" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "ภาพเคลื่อนไหว" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "การท่องดูหน้าเว็บ" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "การท่องดูตาราง" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "เลือกบรรทัดลงมาจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "เลือกบรรทัดขึ้นไปจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "เลิกเลือกบรรทัดลงมาจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "เลิกเลือกบรรทัดขึ้นไปจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "กำลังออกจากโหมดเรียนรู้" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "เลือกบรรทัดจากต้นบรรทัดถึงตำแหน่งเคอร์เซอร์ที่แล้ว" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "เลือกบรรทัดจากตำแหน่งเคอร์เซอร์ที่แล้วจนจบบรรทัด" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ลิงก์" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "หน้าเดียวกัน" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ไซต์เดียวกัน" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "คนละไซต์" - -#: src/cthulhu/messages.py:1531 -#, fuzzy, python-format -msgid "%(uri)s link to %(file)s" -msgstr "ลิงก์ %s ไปยัง %s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "ลิงก์ %s" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d ลิงก์ที่ดูแล้ว" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "ปิดพื้นที่แสดงสดทั้งหมดแล้ว" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "คืนค่าระดับความสุภาพของพื้นที่แสดงสดทั้งหมดแล้ว" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "ระดับความสุภาพ %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "กำหนดพื้นที่แสดงสดเป็นแบบจุกจิก" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "ปิดพื้นที่แสดงสด" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "กำหนดพื้นที่แสดงสดเป็นแบบสุภาพ" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "กำหนดพื้นที่แสดงสดเป็นแบบกระด้าง" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "ปิดการเฝ้าสังเกตพื้นที่แสดงสดแล้ว" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "เปิดการเฝ้าสังเกตพื้นที่แสดงสดแล้ว" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "ไม่มีข้อความสดบันทึกไว้" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "การรองรับพื้นที่แสดงสดถูกปิดอยู่" - -#: src/cthulhu/messages.py:1654 -#, fuzzy -msgctxt "location" -msgid "Not found" -msgstr "ไม่พบแฟ้ม" - -#: src/cthulhu/messages.py:1659 -#, fuzzy -msgid "Could not find current location." -msgstr "ตำแหน่ง_ปัจจุบัน" - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "ปิด" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "เปิด" - -#: src/cthulhu/messages.py:1677 -#, fuzzy -msgid "misspelled" -msgstr "คำสะกดผิด:" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "คำที่สะกดผิด: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "บริบทคือ %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "ไปยังวัตถุชิ้นถัดไป" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "ปิดการปรับเมาส์ช่วยการมองเห็นแล้ว" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "เปิดใช้การปรับเมาส์ช่วยการมองเห็นแล้ว" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "ไม่มีลูก" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d เปอร์เซ็นต์" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "ไปยังคำก่อนหน้า" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "ซ้อน %d ระดับ" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "ไม่มีโปรแกรมใดได้โฟกัสอยู่" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "ไม่มีโฟกัส" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "ไม่มีโปรแกรมใดได้โฟกัสอยู่" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "ไม่มีบล็อคอ้างคำพูดอีก" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "ไม่มีปุ่มอีก" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "ไม่มีกล่องกาอีก" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "ไม่มีวัตถุใหญ่อีก" - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "ไม่มีตารางอีก" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "ไม่มีกล่องคอมโบอีก" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "ไม่มีช่องป้อนข้อความอีก" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "ไม่มีช่องข้อมูลแบบฟอร์มอีก" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "ไม่มีหัวข้ออีก" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "ไม่มีหัวข้ออีกในระดับ %d" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "กรอบภายใน" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "ไม่มีตารางอีก" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "ไม่พบตำแหน่งสำคัญ" - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "ไม่มีรายชื่ออีก" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "ไม่มีรายชื่ออีก" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "ไม่มีรายการในรายชื่ออีก" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "ไม่มีพื้นที่แสดงสดอีก" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "ไม่มีย่อหน้าอีก" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "ไม่มีปุ่มวิทยุอีก" - -#: src/cthulhu/messages.py:1972 -#, fuzzy -msgid "No more separators." -msgstr "ไม่มีย่อหน้าอีก" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "ไม่มีตารางอีก" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "ไม่มีลิงก์ที่ยังไม่ดูอีก" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "ไม่มีลิงก์ที่ดูแล้วอีก" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "ไม่อยู่ในตาราง" - -#: src/cthulhu/messages.py:2001 -#, fuzzy -msgid "Notification" -msgstr "การแจ้งเหตุ %s" - -#: src/cthulhu/messages.py:2005 -#, fuzzy -msgctxt "notification" -msgid "Bottom" -msgstr "_ล่าง:" - -#: src/cthulhu/messages.py:2009 -#, fuzzy -msgctxt "notification" -msgid "Top" -msgstr "_บน:" - -#: src/cthulhu/messages.py:2013 -#, fuzzy -msgid "No notification messages" -msgstr "การแจ้งเหตุ %s" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "คำ" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "อ่านออกเสียงข้อความผสมตัวพิมพ์ใหญ่-เล็กแยกเป็น_คำ" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "ปิด" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "เปิด" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "กำลังเรียกอ่าน โปรดรอสักครู่" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "เรียกอ่านเสร็จแล้ว" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "เรียกอ่าน %s เสร็จแล้ว" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "เลือกหน้าลงมาจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "เลือกหน้าขึ้นไปจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "เลิกเลือกหน้าลงมาจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "เลิกเลือกหน้าขึ้นไปจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:2101 -#, fuzzy -msgid "paragraph selected down from cursor position" -msgstr "เลือกหน้าลงมาจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:2107 -#, fuzzy -msgid "paragraph selected up from cursor position" -msgstr "เลือกหน้าลงมาจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:2114 -#, fuzzy -msgid "paragraph unselected down from cursor position" -msgstr "เลิกเลือกหน้าลงมาจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:2121 -#, fuzzy -msgid "paragraph unselected up from cursor position" -msgstr "เลิกเลือกหน้าลงมาจากตำแหน่งเคอร์เซอร์" - -#: src/cthulhu/messages.py:2127 -#, fuzzy -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"คุณได้เปิดกล่องโต้ตอบปรับแต่ง Cthulhu ไว้แล้วกล่องหนึ่ง\n" -"\n" -"กรุณาปิดกล่องโต้ตอบนั้นก่อนที่จะเปิดกล่องใหม่" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "ไม่พบแฟ้ม" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "แถบบอกความก้าวหน้า %d" - -#: src/cthulhu/messages.py:2157 -#, fuzzy -msgctxt "spoken punctuation" -msgid "All" -msgstr "ทั้ง_หมด" - -#: src/cthulhu/messages.py:2163 -#, fuzzy -msgid "Punctuation level set to all." -msgstr "การออกเสียงเครื่องหมายวรรคตอน" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "" - -#: src/cthulhu/messages.py:2181 -#, fuzzy -msgctxt "spoken punctuation" -msgid "None" -msgstr "ไม่มี" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "กำลังค้นหา" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "การค้นหาเสร็จสบูรณ์" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "โหลดการตั้งค่า Cthulhu ใหม่แล้ว" - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "บริบทคือ %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "เลือกเสียงที่ต้องการ:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "ปิดใช้งานเสียงพูด" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "เปิดใช้งานเสียงพูด" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "เร็วขึ้น" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "ช้าลง" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "สูงขึ้น" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "ต่ำลง" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "เร็วขึ้น" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "ความเร็ว %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "ระดับเสียง %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "ระดับเสียง %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "โมดูล Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "เสียง Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "ไม่มีโมดูล Speech-dispatcher ที่พร้อมใช้งาน" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "ไม่มีเสียง Speech-dispatcher ที่พร้อมใช้งาน" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "บันทึกการตั้งค่าเสียงพูดแล้ว" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "ไม่สามารถบันทึกการตั้งค่าเสียงพูดได้" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " จุด จุด จุด" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu ยินดีต้อนรับ" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu แฝงตัวอยู่ใต้คลื่น" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "เปิดใช้งานโหมดพักเครื่องสำหรับ %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "โหมดพักเครื่องถูกปิดใช้งานสำหรับ %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "เสียงพูดไม่สามารถใช้งานได้" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "ไม่พบแฟ้ม" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "ไม่พบสตริง" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "ไม่พบสตริง" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "ปิดใช้ปุ่มท่องดูตามโครงสร้างแล้ว" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "เปิดใช้ปุ่มท่องดูตามโครงสร้างแล้ว" - -#: src/cthulhu/messages.py:2377 -#, fuzzy -msgctxt "structural navigation" -msgid "Not found" -msgstr "ไม่พบแฟ้ม" - -#: src/cthulhu/messages.py:2380 -#, fuzzy, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "แถว %d, คอลัมน์ %d" - -#: src/cthulhu/messages.py:2384 -#, fuzzy -msgid "End of table" -msgstr "%d ตาราง" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "อ่านออกเสียงช่องตาราง" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "อ่านออกเสียงทั้งแถว" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "ช่องตารางไม่ปกติ" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "ไม่อยู่ในตาราง" - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "หัวคอลัมน์" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "คอลัมน์ %d" - -#: src/cthulhu/messages.py:2420 -#, fuzzy, python-format -msgid "column %(index)d of %(total)d" -msgstr "คอลัมน์ %d จาก %d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "ท้ายคอลัมน์" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "ต้นคอลัมน์" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "แถว %d" - -#: src/cthulhu/messages.py:2462 -#, fuzzy, python-format -msgid "row %(index)d of %(total)d" -msgstr "แถว %d จาก %d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "ต้นแถว" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "ท้ายแถว" - -#: src/cthulhu/messages.py:2476 -#, fuzzy -msgid "Row deleted." -msgstr "delete" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "" - -#: src/cthulhu/messages.py:2484 -#, fuzzy -msgid "Row inserted." -msgstr "insert" - -#: src/cthulhu/messages.py:2489 -#, fuzzy -msgid "Row inserted at the end of the table." -msgstr "ไปยังท้ายบรรทัด" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "เลือกอยู่" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu เวอร์ชัน %s" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "บรรทัดว่าง" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "กำลังเริ่มหาใหม่จากท้ายหน้า" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "กำลังเริ่มหาใหม่จากต้นหน้า" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 รายการ" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, fuzzy, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "ช่องตารางเกยไป %d แถว" - -#: src/cthulhu/messages.py:2586 -#, fuzzy, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d คอลัมน์" - -#: src/cthulhu/messages.py:2593 -#, fuzzy, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "ช่องตารางเกยไป %d คอลัมน์" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d กล่องโต้ตอบ)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d กล่องโต้ตอบไม่มีโฟกัส" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d ไบต์" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "พบ %d แฟ้ม" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d ฟอร์ม" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d หัวข้อ" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d รายการ" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "ไม่พบตำแหน่งสำคัญ" - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "พบ %d แฟ้ม" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "ไม่มีบล็อคอ้างคำพูดอีก" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "กำลังออกจากตาราง" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "รายชื่อซึ่งมี %d รายการ" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "รายชื่อซึ่งมี %d รายการ" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "ตาราง %d แถว" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d คอลัมน์" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "ตาราง %d แถว" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "" - -#: src/cthulhu/messages.py:2758 -#, fuzzy, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d เปอร์เซ็นต์" - -#: src/cthulhu/messages.py:2764 -#, fuzzy, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "อ่านเอกสารแล้ว %d เปอร์เซ็นต์" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%s %s พิกเซล" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "อักขระ %(repeatChar)s %(count)d ตัว" - -#: src/cthulhu/messages.py:2784 -#, fuzzy, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "เลือกรายการ %d ใน %d รายการ" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "เว้น %d วรรค" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d แท็บ" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d ตาราง" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "ตาราง %d แถว %d คอลัมน์" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "ตาราง %d แถว %d คอลัมน์" - -#: src/cthulhu/messages.py:2847 -#, fuzzy, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "ตาราง %d แถว" - -#: src/cthulhu/messages.py:2861 -#, fuzzy, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "วินาที" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d ลิงก์ที่ยังไม่ดู" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d ลิงก์ที่ดูแล้ว" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "สลับค่า" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "ระดับที่ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ต้นไม้ระดับที่ %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "ต้นไม้ระดับที่ %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "ปรัศนี" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "กล่องคอมโบ" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "เนื้อหา html" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "คำ" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "ทวิภาค" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "ขีดเส้นบน" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "ทิศทางการเขียน" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "ย่อหน้า" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "คำ" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "การร่นย่อหน้า" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "ทิศทางการเขียน" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "รายการแท็บ" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "อัญประกาศ" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "เนื้อหา html" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s ระดับ %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "แนวนอน" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "ขีดตั้ง" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "แนวนอน" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "การเรียงชิดขอบแนวดิ่ง" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "แนวนอน" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "การเรียงชิดขอบแนวดิ่ง" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "สลับโหมด" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "พาเนลไอคอน" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "เนื้อหา html" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "ภาพเคลื่อนไหว" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "เนื้อหา html" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "ภาพเคลื่อนไหว" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "กำลังค้นหา" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d ลิงก์ที่ดูแล้ว" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "ปุ่มปรับเลข" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "หุบ" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "ขยาย" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "แนวนอน" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "แนวตั้ง" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "กาอยู่" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "ไม่ได้กา" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "เปิด" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "ปิด" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "กาบางส่วน" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "กดอยู่" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "ไม่ได้กด" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "เลือกอยู่" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/object_properties.py:555 -#, fuzzy -msgctxt "tablecell" -msgid "not selected" -msgstr "ไม่ได้เลือก" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d ลิงก์ที่ดูแล้ว" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d ลิงก์ที่ยังไม่ดู" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "ปิดใช้งาน" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "อ่านได้อย่างเดียว" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "อ่านเท่านั้น" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "จำเป็น" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "เลือกได้หลายข้อ" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "ใช้ไม่ได้" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "ใช้ไม่ได้" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "สะกดผิด" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "สะกดผิด" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "ใช้ไม่ได้" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "หา" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "โปรแกรมอ่านหน้าจอและแว่นขยายของ Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "ปิด" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "หา" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_ค้นหา:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "ค้นหา:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_บนสุดของหน้าต่าง" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "บนสุดของหน้าต่าง" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "เริ่มจาก:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "หมดแล้วเ_ริ่มใหม่" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "ค้นหา_ย้อนหลัง" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "ทิศทางการเขียน" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "ตัว_พิมพ์ใหญ่-เล็กตรงกัน" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "ค้นหาทั้งคำเ_ท่านั้น" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "ตัวเลือกการค้นหา" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "ค่าปริยาย" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "ตัวพิมพ์ใหญ่" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "ไฮเพอร์ลิงก์" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "โปรแกรม" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "หน้าต่าง" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "ค่าปรับแต่ง Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "แ_ล็ปท็อป" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "ผังแป้นพิมพ์" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:345 -#, fuzzy -msgid "Start-up Profile:" -msgstr "เริ่มจาก:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "นำเสนอคำแ_นะนำเครื่องมือ" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "อ่านออกเสียงวัตถุที่อยู่ใต้เ_มาส์" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "_อ่านออกเสียงทั้งหมด" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "ปุ่มลัดเบรลล์" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "โปรแกรม" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "อ่านออกเสียงการเปลี่ยนแปลง_ในแถบบอกความคืบหน้า" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "เปิด/ปิดการใช้ปุ่มท่องดูตามโครงสร้าง" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "ออกเสียงทั้งหมด_ทีละ:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "ออกเสียงทั้งหมด_ทีละ:" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_การนำเสนอองค์ประกอบ:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "ทั่วไป" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_ความดัง:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "ระดั_บเสียง:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "อัตราเร็_ว:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "เสียงผู้พู_ด:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "ภาษา" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "ตัว_สังเคราะห์เสียง:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "_ระบบเสียงพูด:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "การตั้งค่าเสีย_ง:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "การตั้งค่าเสีย_ง:" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "อ่านออกเสียงข้อความผสมตัวพิมพ์ใหญ่-เล็กแยกเป็น_คำ" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "การตั้งค่าเสีย_ง:" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "เ_ปิดใช้งานเสียงพูด" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_ละเอียด" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "ความละเอียดของถ้อยคำ" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "ทั้ง_หมด" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "การออกเสียงเครื่องหมายวรรคตอน" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "อ่านออกเสียงบรรทัดว่าง" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "อ่านออกเสียงการร่น_ข้อความและการจัดชิดขอบ" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "อ่านออกเสียง_รหัสย่อของวัตถุ" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "อ่านออกเสียงข้อความบทเรียน" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "อ่านออกเสียงพิกัด_ช่องตาราง" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "อ่านออกเสียงพิกัด_ช่องตาราง" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "ไ_ม่ต้องอ่านออกเสียง" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "เสียงพูด" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "เปิดใช้งานการ_รองรับอักษรเบรลล์" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_ชื่อวัตถุอย่างย่อ" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "ปิดการใช้สัญลักษณ์_จบบรรทัด" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "_ตารางการย่อ:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "เ_ปิดใช้อักษรเบรลล์แบบย่อ" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "เปิดใช้เ_ส้นขอบ" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "แสดงตัวเลือกเพิ่มเติม" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -#, fuzzy -msgctxt "braille dots" -msgid "_None" -msgstr "_ไม่" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "การบ่งชี้สิ่งที่เลือก" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "การบ่งชี้ไฮเพอร์ลิงก์" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "เปิดใช้งานแว่น_ขยาย" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "อักษรเบรลล์" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "เปิดใช้งานการออกเ_สียงแป้นพิมพ์" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "เปิดใช้งานปุ่มท่อ_งสำรวจ" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "เปิดใช้งานปุ่มยกแ_คร่" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "เปิดใช้งานปุ่ม_ฟังก์ชัน" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "เ_ปิดใช้งานเสียงพูด" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "เปิดใช้งานปุ่มยกแ_คร่" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "เปิดใช้งานปุ่ม_ฟังก์ชัน" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "เปิดใช้งานปุ่มปฏิ_บัติการ" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "เปิดใช้งานปุ่มท่อ_งสำรวจ" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "เปิดใช้งานการออกเสียงทีละ_คำ" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "เปิดใช้งานการออกเสียงทีละ_ประโยค" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "การออกเสียงแป้นพิมพ์" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "ปุ่ม_ประกอบของ Cthulhu:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "ปุ่มลัด" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "พจนานุกรมคำอ่าน" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "รายการให_ม่" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_ลบ" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "คำอ่าน" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_อ่านออกเสียงทั้งหมด" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "ไ_ม่ต้องอ่านออกเสียง" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_คืนค่าเดิม" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "คุณลักษณะข้อความ" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "เลื่อนไปล่า_งสุด" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "เลื่อน_ลงหนึ่งขั้น" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "เลื่อน_ขึ้นหนึ่งขั้น" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "เลื่อนไป_บนสุด" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "" -"ปรับคุณลักษณะ\n" -"ที่เลือก" - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "การบ่งชี้ด้วยอักษรเบรลล์" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "คุณลักษณะข้อความ" - -# for Thai. -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "เปิดใช้งานผู้ช่วย AI" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "ผู้_ให้บริการ:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (ในเครื่อง - ฟรี)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "ไฟล์_คีย์ API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "เส้นทางไปยังไฟล์คีย์ API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "รับคีย์ API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "เปิดเบราว์เซอร์เพื่อรับคีย์ API ของ Claude และบันทึกโดยอัตโนมัติ" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "ต้องยืนยันก่อนดำเนินการ AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_โมเดล Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "ชื่อโมเดลสำหรับ Ollama (เช่น llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Endpoint ของ Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL endpoint ของ Ollama API (เช่น http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_คุณภาพภาพหน้าจอ:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "ต่ำ" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "ปานกลาง" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "สูง" - -# for Thai. -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "ผู้ช่วย AI" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "รหัส_ภาษา:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_ตัวคูณมาตราส่วน:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "ภาพ_ระดับสีเทา" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_กลับสีภาพ" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "ภาพ_ขาวดำ" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_เกณฑ์ขาว/ดำ:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_วิเคราะห์สี" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "คัดลอกผลลัพธ์ไปยัง_คลิปบอร์ด" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "สีพื้นหลัง" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "ใช้ความสูงพื้นหลังสูงสุด" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "ใช้พื้นหลังแบบประจุด" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "ทิศทางการเขียน" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "แก้ไขได้" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "ชื่อตระกูลแบบอักษร" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "สีตัวอักษร" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "วาดอักษรแบบประจุด" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "ลูกเล่นแบบอักษร" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "การร่นย่อหน้า" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "ไม่แสดง" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "การเรียงชิดขอบ" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "ภาษา" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "ขอบซ้าย" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "ความสูงบรรทัด" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "สไตล์ของย่อหน้า" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "จำนวนจุดที่เว้นเหนือบรรทัด" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "จำนวนจุดที่เว้นใต้บรรทัด" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "จำนวนจุดที่เว้นระหว่างบรรทัดในย่อหน้า" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "ขอบขวา" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "ระยะยก" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "อัตราขยาย" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "ขนาด" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "การยืด" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "ขีดฆ่า" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "สไตล์" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "การประดับข้อความ" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "การหมุนข้อความ" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "เงาข้อความ" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "ขีดเส้นใต้" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "แบบย่อย" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "การเรียงชิดขอบแนวดิ่ง" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "ความหนา" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "โหมดการตัดบรรทัด" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "โหมดการเขียน" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "จริง" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "เท็จ" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "ไม่มี" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "สลัก" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "นูน" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "เส้นขอบ" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "ขีดเส้นบน" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "ขีดทับกลาง" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "กะพริบ" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "ดำ" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "เส้นเดี่ยว" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "เส้นคู่" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "ต่ำ" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "อักขระ" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "คำ" - -#: src/cthulhu/text_attribute_names.py:452 -#, fuzzy -msgctxt "textattr" -msgid "word char" -msgstr "อักขระ" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ซ้ายไปขวา" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "ขวามาซ้าย" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "ซ้าย" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "ขวา" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "ตรงกลาง" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "ไม่เรียงชิดขอบ" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "เต็ม" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "บีบที่สุด" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "บีบมาก" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "บีบ" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "กึ่งบีบ" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "ปกติ" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "กึ่งขยาย" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "ขยาย" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "ขยายมาก" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ขยายที่สุด" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "ตัวพิมพ์ใหญ่ตัวเล็ก" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "ตัวเอน" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "ตัวเอียง" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "ปริยาย" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "เนื้อความ" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "หัวข้อ" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "เส้นบรรทัด" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "ตัวห้อย" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "ตัวยก" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "บน" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "ขอบบนของข้อความ" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "กลาง" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "ล่าง" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "ขอบล่างของข้อความ" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "สืบทอด" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "ซ้ายไปขวา-บนลงล่าง" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "ขวามาซ้าย-บนลงล่าง" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "บนลงล่าง-ขวามาซ้าย" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "บนลงล่าง-ซ้ายไปขวา" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "ล่างขึ้นบน-ขวามาซ้าย" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "ล่างขึ้นบน-ซ้ายไปขวา" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "ซ้ายไปขวา" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "ขวามาซ้าย" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "บนลงล่าง" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "เส้นทึบ" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "สะกดผิด" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "กดแคร่เว้นวรรคเพื่อสลับค่า" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "กดแคร่เว้นวรรคเพื่อขยาย และใช้ปุ่มขึ้นและลงเลือกรายการ" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "กด alt+f6 เพื่อย้ายโฟกัสไปยังหน้าต่างลูก" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "เลื่อนไปยังรายการต่างๆ ด้วยปุ่มลูกศร หรือใช้วิธีค้นขณะป้อนก็ได้" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "หากต้องการเปิดเมนูระบบ กดปุ่ม alt+f1" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "กดปุ่มขึ้นและลงเพื่อเลือกรายการ" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "ยุบด้วยการกด shift และลูกศรซ้าย" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "ขยายด้วยการกด shift และลูกศรขวา" - -#: src/cthulhu/tutorialgenerator.py:397 -#, fuzzy -msgid "To activate press return." -msgstr "เรียกใช้ด้วยปุ่มแคร่เว้นวรรค" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "ป้อนข้อความ" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "กดปุ่มลูกศรซ้ายและขวาเพื่อดูแท็บอื่นๆ" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "เรียกใช้ด้วยปุ่มแคร่เว้นวรรค" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "ใช้ปุ่มลูกศรขึ้นหรือลงเพื่อเปลี่ยนค่า หรือพิมพ์ค่าตัวเลขที่ต้องการ" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "ใช้ปุ่มลูกศรเพื่อเปลี่ยนค่าที่เลือก" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "ท่องดูด้วยปุ่มลูกศรซ้ายหรือขวา เลื่อนไปยังรายการต่างๆ ด้วยปุ่มลูกศรขึ้นหรือลง" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "เลือกเมนูย่อยด้วยปุ่มลูกศรขวา" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"ลดค่าด้วยปุ่มลูกศรซ้าย เพิ่มค่าด้วยปุ่มลูกศรขวา ไปยังค่าต่ำสุดด้วยปุ่ม home ไปยังค่าสูงสุดด้วยปุ่ม end" diff --git a/po/tr.po b/po/tr.po deleted file mode 100644 index dfe63a5..0000000 --- a/po/tr.po +++ /dev/null @@ -1,9181 +0,0 @@ -# Turkish translation of Cthulhu. -# Copyright (C) 2008-2023 Cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the Cthulhu package. -# -# Baris Cicek , 2008, 2009. -# Gökhan Gurbetoğlu , 2015. -# Neriman Kara , 2016. -# Olcay Aşçı , 2017. -# Muhammet Kara , 2011, 2014, 2015, 2016, 2017. -# Hanifi Çakmak , 2018. -# Çağatay Yiğit Şahin , 2019. -# Emin Tufan Çetin , 2017-2023. -# Sabri Ünal , 2023. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-10-13 15:42+0300\n" -"Last-Translator: Sabri Ünal \n" -"Language-Team: Turkish \n" -"Language: tr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.4\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu Ekran Okuyucu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "ekran;okuyucu;erişilebilirlik;konuşma;braille;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "uyrı" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "ok" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "tak" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "tuvl" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "bşlk" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "ony" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "rnksçc" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "stnbşl" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "açl" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "tar" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "smg" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "çrçv" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "ara" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "çiz" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "dsysçc" - -# doldurucu -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "dld" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "yztp" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -# cam panel -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "cpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "bşlk" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "rsm" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "etkt" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "ktmnpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "bgl" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstöge" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnü" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnüçbğ" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnüöge" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "sçnkpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "syfs" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "syfst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "prl" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "açlmnü" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "ilçub" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "dğm" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radyo" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnüöge" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "kökpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "strbşl" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "kyçb" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "kypn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "bölm" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "ayraç" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "kydrc" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "blkpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "döndür" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "drmçbğ" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "hcr" - -# yırtılan menü ögesi -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "yrtmnüöge" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "uçbr" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "mtn" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "açkpdüğ" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "arçbğ" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "ipucu" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "ağç" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "ağtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "blnmyn" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "grşaln" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "pncr" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "bşlk" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "uyglm" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "oto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "dznçbğ" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "gml" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Çekçe Derece 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "İspanyolca Derece 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Kanada Fransızcası Derece 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Fransız Fransızcası Derece 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Letonca Derece 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Hollanda Felemenkçesi Derece 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Norveççe Derece 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Norveççe Derece 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Norveççe Derece 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Norveççe Derece 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Lehçe Derece 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Portekizce Derece 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "İsveççe Derece 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Arapça Derece 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Galce Derece 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Galce Derece 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Almanca Derece 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Almanca Derece 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Almanca Derece 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "B.K. İngilizcesi Derece 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "B.K. İngilizcesi Derece 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "A.B.D. İngilizcesi Derece 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "A.B.D. İngilizcesi Derece 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Kanada Fransızcası Derece 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Fransız Fransızcası Derece 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Yunanca Derece 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hintçe Derece 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Macarca 8 nokta bilgisayar" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Macarca Derece 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Macarca Derece 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "İtalyanca Derece 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Belçika Felemenkçesi Derece 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "boşluk" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "yeni satır" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "sekme" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "ünlem" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "alıntı" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "nümerik" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dolar" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "yüzde" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ve" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "kesme işareti" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "sol parantez" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "sağ parantez" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "yıldız" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "artı" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "virgül" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "çizgi" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "nokta" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "eğik çizgi" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "iki nokta üst üste" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "noktalı virgül" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "küçüktür" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "eşittir" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "büyüktür" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "soru işareti" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "sol köşeli parantez" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "ters eğik çizgi" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "sağ köşeli parantez" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "düzeltme imi" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "alt çizgi" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "sol parantez" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "dik çizgi" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "sağ parantez" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "tilda" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "bölünmeyen boşluk" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "ters ünlem" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "sent" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "ingiliz lirası" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "değer işareti" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "yen" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "dik çizgi" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "paragraf" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "ses değiştirme işareti" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "telif hakkı" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "üstsimge a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "sol tek alıntı" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "mantıksal değil işareti" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "koşullu kesme işareti" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "tescilli" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "uzatma işareti" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "derece" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "artı veya eksi" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "üstsimge 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "üstsimge 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "tiz" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "paragraf işaretçisi" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "orta nokta" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "çengel işareti" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "üstsimge 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "sırasal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "sağ tek alıntı" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "dörtte bir" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "yarım" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "dörtte üç" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "ters soru işareti" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a akut" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A AKUT" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "DÜZELTME İŞARETLİ A" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TİLDA" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A HALKA" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "Çengelli C" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E AKUT" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "DÜZELTME İŞARETLİ E" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I AKUT" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "DÜZELTME İŞARETLİ I" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TİLDA" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O AKUT" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "DÜZELTME İŞARETLİ O" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TİLDA" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "çarpı" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O YANÇİZGİ" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U AKUT" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "DÜZELTME İŞARETLİ U" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y AKUT" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "esszet" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "düzeltme işaretli a" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilda" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a halka" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "ç" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e akut" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "düzeltme işaretli e" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i akut" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "düzeltme işaretli i" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilda" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o akut" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "düzeltme işaretli o" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilda" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "bölme işareti" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o yançizgi" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u akut" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "düzeltme işaretli u" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y akut" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "çizgi" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "sol tek tırnak" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "sağ tek tırnak" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "tek alt tırnak" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "sol çift tırnak" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "sağ çift tırnak" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "çift alt tırnak" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "kama" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "çift kama" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "madde imi" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "üçgen madde imi" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "mil başına" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "asal" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "çift asal" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "üçlü asal" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "çizgi madde imi" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "avro" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "tescilli marka" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "onay imi" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "kalın onay imi" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x şeklinde madde imi" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "üstsimge 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "üstsimge 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "üstsimge 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "üstsimge 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "üstsimge 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "üstsimge 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "üstsimge 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "üstsimge artı" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "üstsimge eksi" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "üstsimge eşittir" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "üstsimge sol tek tırnak" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "üstsimge sağ tek tırnak" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "üstsimge n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "altsimge 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "altsimge 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "altsimge 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "altsimge 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "altsimge 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "altsimge 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "altsimge 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "altsimge 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "altsimge 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "altsimge 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "altsimge artı" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "altsimge eksi" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "altsimge eşittir" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "altsimge sol tek tırnak" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "altsimge sağ tek tırnak" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "içi dolu kare" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "siyah baklava dilimi" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "nesne değiştirme karakteri" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "İşaretçiyi geçerli ögeye yönelt" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Geçerli düz bakış ögesi üzerinde sol tıklama gerçekleştir" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Geçerli düz bakış ögesi üzerinde sağ tıklama gerçekleştir" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Tüm belgeyi seslendir" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Düz bakış ile tüm pencereyi seslendir" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Basit Neredeyim işlemini gerçekleştir" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Ayrıntılı Neredeyim işlemini gerçekleştir" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Geçerli seçimi seslendir" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Bağlantı ayrıntılarını seslendir" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Öntanımlı düğmeyi sun" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Durum çubuğunu sun" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Başlık çubuğunu sun" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Bul penceresini aç" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Eylem listesini göster" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Dizgenin sonraki görüldüğü yeri ara" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Dizgenin önceki görüldüğü yeri ara" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Düz bakış kipine gir ve çık" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Düz bakışı kısıtlamayı geçerli nesneye değiştir" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Düz bakışı başlangıç konumuna taşı" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Düz bakışı bitiş konumuna taşı" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Düz bakışı önceki satırın başına taşı" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Geçerli düz bakış satırını seslendir" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Geçerli düz bakış satırını hecele" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "Geçerli düz bakış satırını fonetik olarak hecele" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Düz bakışı sonraki satırın başına taşı" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Düz bakışı önceki öge ya da sözcüğe taşı" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Geçerli düz bakış nesne ya da sözcüğünü oku" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "Geçerli düz bakış nesne ya da sözcüğünü hecele" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "Geçerli düz bakış nesne ya da sözcüğünü fonetik olarak oku" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Düz bakışı sonraki öge ya da sözcüğe taşı" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Düz bakışı geçerli sözcüğün üstündeki sözcüğe taşı" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Geçerli düz bakış nesnesini seslendir" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Düz bakışı geçerli sözcüğün altındaki sözcüğe taşı" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Düz bakışı önceki karaktere taşı" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Geçerli düz bakış karakterini seslendir" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Geçerli düz bakış karakterini fonetik olarak seslendir" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Geçerli düz bakış karakterinin Unicode değerini seslendir" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Düz bakışı sonraki karaktere taşı" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Düz bakışı satırın sonuna taşı" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Düz bakışı sol alta taşı" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Düz bakış altındaki içeriği panoya kopyala" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Düz bakış altındaki içeriği panoya ekle" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Düz bakış içeriklerini göster" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"Yalnızca geçerli tablo hücresinin mi yoksa tüm satırın mı okunacağını " -"değiştir" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Geçerli metin karakteriyle ilişkilendirilmiş öznitelikleri oku" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Braille görüntüsünü sola doğru kaydır" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Braille görüntüsünü sağa doğru kaydır" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Klavye odaklı nesneye dön" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Kısaltmalı Braille’i aç ve kapat" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "İmleç yönlendirme tuşunu işle" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Metin seçiminin başını imle" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Metin seçiminin bitimini imle" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "" -"Öğrenme kipine gir. Öğrenme kipinden çıkmak için kaçış (esc) tuşuna bas" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Konuşma hızını düşür" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Konuşma hızını artır" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Konuşma perdesini düşür" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Konuşma perdesini yükselt" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Konuşma ses düzeyini artır" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Konuşma ses düzeyini azalt" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Önceki konuşma ayarını seç" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Sonraki konuşma ayarını seç" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Geçerli konuşma ayarını azalt" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Geçerli konuşma ayarını artır" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Konuşma ayarlarını kaydet" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Konuşmanın sessizliğini aç ya da kapat" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Konuşma ayrıntı düzeyini değiştir" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Uyku modunu değiştir" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Ekran okuyucudan çık" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Tercihler yapılandırma penceresini göster" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Uygulama tercihlerini yapılandırma penceresini göster" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Girintileme ve yaslamanın konuşulmasını aç ya da kapat" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Sayı seslendirme biçemini değiştir" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Sonraki noktalama konuşma düzeyine geç" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Sonraki konuşma sentezleyiciye geç" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Sonraki ayarlar profiline geç" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Sonraki büyük harf biçemine geç" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Sonraki tuş geri bildirim düzeyine geç" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Çalıştırma sırasında hata ayıklama düzeyine geç" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Geçerli konuma göre nerede olduğumu yer imi yap" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Önceki yer imi konumuna git" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Yer imine git" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Sonraki yer imi konumuna git" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Yer imi ekle" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Yer imlerini kaydet" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Fare bakış kipini değiştir" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Geçerli saati sun" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Geçerli tarihi sun" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Geçerli nesnenin şimdiki boyutu ve konumu" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Geçerli uygulamaya sonraki komutu geçir" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Önceki sohbet odası iletisini seslendir ve braille ile belirt" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Arkadaşlarınız yazarken bunun duyurulmasını aç ya da kapat" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "" -"Sohbet odasına yönelik iletilerin geçmişlerinin sağlanmasını aç ya da kapat" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Sohbet odası iletilerine sohbet odasının adının ön ek olarak eklenmesini aç " -"ya da kapat" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Sola Kaydır" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Sağa kaydır" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Yukarı Kaydır" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Aşağı Kaydır" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Dondur" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Sol Üst" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Sol Alt" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "İmleç Konumu" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Altı Nokta" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "İmleç Yönlendirme" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Kesme Başlangıcı" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Satır Kes" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "En son bildirim iletisini sun" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Bildirim iletileri listesini sun" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Önceki bildirim iletisini sun" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Sonraki bildirim iletisini sun" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Sonraki karaktere git" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Önceki karaktere git" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Sonraki sözcüğe git" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Önceki sözcüğe git" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Sonraki satıra git" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Önceki satıra git" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Dosyanın en üstüne git" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Dosyanın en altına git" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Satırın başına git" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Satırın sonuna git" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Sonraki nesneye git" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Önceki nesneye git" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Geçerli açılır kutunun genişlemesini sağlar" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "Yerli ve ekran okuyucu karet gezinimi arasında geçiş yap" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Canlı bölge yumuşaklığı ayarını değiştir" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Öntanımlı canlı bölge yumuşaklığını kapalı olarak ayarla" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Canlı bölge duyurusunu gözden geçir" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Canlı bölgeleri izle" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Odağı geçerli fare konumuna getir ya da çek" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Dinamik sütun başlığı olarak kullanılacak satırı ayarla" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Dinamik sütun başlıklarını temizle" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Dinamik satır başlığı olarak kullanılacak sütunu ayarla" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Dinamik satır başlıklarını temizle" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Girdi satırının içeriklerini sun" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Yapısal dolaşım tuşlarını aç ya da kapat" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Önceki blok alıntıya git" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Sonraki blok alıntıya git" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Blok alıntıların listesini göster" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Önceki düğmeye git" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Sonraki düğmeye git" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Düğmelerin listesini göster" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Önceki onay kutusuna git" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Sonraki onay kutusuna git" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Onay kutularının listesini göster" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Önceki tıklanabilire git" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Sonraki tıklanabilire git" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Tıklanabilirlerin listesini göster" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Önceki açılır kutuya git" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Sonraki açılır kutuya git" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Taşıyıcının başına git" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Taşıyıcının sonuna git" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Açılır kutuların listesini göster" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Önceki girdiye git" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Sonraki girdiye git" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Girdilerin listesini göster" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Önceki form alanına git" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Sonraki form alanına git" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Form alanlarının listesini göster" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Önceki başlığa git" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Sonraki başlığa git" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Başlıkların listesini göster" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "%d düzeyindeki önceki başlığa git" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "%d düzeyindeki sonraki başlığa git" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "%d düzeyindeki başlıkların listesini göster" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Önceki iç kareye git" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Sonraki iç kareye git" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "İç karelerin listesini göster" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Önceki resme git" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Sonraki resme git" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Resimlerin listesini göster" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Önceki sınır işaretine git" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Sonraki sınır işaretine git" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Sınır işaretlerinin listesini göster" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Sonraki büyük nesneye git" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Sonraki büyük nesneye git" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Büyük nesnelerin listesini göster" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Önceki bağlantıya git" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Sonraki bağlantıya git" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Bağlantıların listesini göster" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Önceki listeye git" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Sonraki listeye git" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Listelerin listesini göster" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Önceki liste ögesine git" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Sonraki liste ögesine git" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Liste ögelerinin listesini göster" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Önceki canlı bölgeye git" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Sonraki canlı bölgeye git" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Duyuru yapmış son canlı bölgeye git" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Gezgin odaklı nesnenin üst nesnesine git." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Gezgin odaklı nesnenin ilk alt ögesine git." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Gezgin odaklı nesnenin sonraki kardeşine git." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Gezgin odaklı nesnenin önceki kardeşine git." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Gezgin odaklı nesneye tıkla." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Basitleştirilmiş nesne gezintisini aç ya da kapat." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Önceki paragrafa git" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Sonraki paragrafa git" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Paragrafların listesini göster" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Önceki radyo düğmesine git" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Sonraki radyo düğmesine git" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Radyo düğmelerinin listesini göster" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Önceki ayraca git" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Sonraki ayraca git" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Önceki tabloya git" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Sonraki tabloya git" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Tabloların listesini göster" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Bir hücre aşağı git" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Tablodaki ilk hücreye git" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Tablodaki son hücreye git" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Bir hücre sola git" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Bir hücre sağa git" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Bir hücre yukarı git" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Düzen kipini değiştir" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Göz atma kipiyle odak kipi arasında geçiş yap" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Yapışkan odak kipini etkinleştir" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Yapışkan göz atma kipini etkinleştir" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Önceki ziyaret edilmemiş bağlantıya git" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Sonraki ziyaret edilmemiş bağlantıya git" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Ziyaret edilmemiş bağlantıların listesini göster" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Önceki ziyaret edilmiş bağlantıya git" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Sonraki ziyaret edilmiş bağlantıya git" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Ziyaret edilmiş bağlantıların listesini göster" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "alice mavisi" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "antik beyaz" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "deniz yeşili" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "gök mavisi" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "bej" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "mat porselen" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "siyah" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "beyazlatılmış badem" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "mavi" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "mavi mor" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "kahverengi" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "kumlu kahverengi" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "harbiye mavisi" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "uçuk yeşil" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "çikolata" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "mercan" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "peygamberçiçeği mavisi" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "mısır püskülü" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "koyu kırmızı" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "camgöbeği" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "koyu mavi" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "koyu camgöbeği" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "koyu altın başak" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "koyu gri" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "koyu yeşil" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "koyu haki" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "koyu eflatun" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "koyu zeytin yeşili" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "koyu turuncu" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "koyu orkide" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "koyu kırmızı" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "koyu somon" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "koyu deniz yeşili" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "koyu kurşun mavisi" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "koyu kurşun grisi" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "koyu turkuaz" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "koyu mor" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "derin pembe" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "derin gökyüzü mavisi" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "loş gri" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "parlak gök mavisi" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "ateş tuğlası" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "çiçek beyazı" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "orman yeşili" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "fuşya" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "açık gri" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "hayalet beyazı" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "altın" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "altın başak" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "gri" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "yeşil" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "yeşil sarı" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "balsıra" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "sıcak pembe" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "hint kırmızısı" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "indigo" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "fildişi" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "haki" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "lavanta" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "lavanta allık" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "çim yeşili" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "limoni şifon" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "açık mavi" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "açık mercan" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "açık camgöbeği" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "açık altın başak sarısı" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "açık gri" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "açık yeşil" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "açık pembe" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "açık somon" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "açık deniz yeşili" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "açık gökyüzü mavisi" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "açık kurşun grisi" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "açık çelik mavisi" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "açık sarı" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "limon rengi" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "limon yeşili" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "keten" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "eflatun" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "kestane rengi" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "orta deniz yeşili" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "orta mavi" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "orta orkide" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "orta mor" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "orta deniz yeşili" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "orta kurşun mavisi" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "orta bahar yeşili" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "orta turkuaz" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "orta mor kırmızı" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "gece mavisi" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "mint krem" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "puslu gül" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "sütbeyaz" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "navajo beyazı" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "donanma" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "eski dantel" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "zeytin" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "zeytin yeşili" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "turuncu" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "turuncu kırmızı" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "orkide" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "soluk altın başak" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "soluk yeşil" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "soluk turkuaz" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "soluk mor kırmızı" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "papaya" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "şeftali pufu" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "peru" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "pembe" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "erik" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "pudra mavisi" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "mor" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "kırmızı" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "pembe kahverengi" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "kraliyet mavisi" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "eyer kahverengisi" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "somon" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "kumlu kahverengi" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "deniz yeşili" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "deniz kabuğu" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "koyu kahverengi" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "gümüş" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "gök mavisi" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "kurşun mavisi" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "kurşun grisi" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "kar" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "bahar yeşili" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "çelik mavisi" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "taba rengi" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "deniz mavisi" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "devedikeni" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "domates" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "turkuaz" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "menekşe" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "buğday" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "beyaz" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "beyaz duman" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "sarı" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "sarı yeşil" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Aktifleştir" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Yapısal gezinme sırasında kendiliğinden odaklama kipi" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Klavyeyle gezinme sırasında kendiliğinden odaklama kipi" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Yerli gezinme sırasında kendiliğinden odaklama kipi" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Nokta _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Nokta _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Nokta 7 v_e 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "İ_ptal" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Atla" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Tamam" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Simge" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Hiçbiri" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Hece" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "_Arkadaşlarınız yazarken bunu duyur" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Sohbet odasına özel _ileti geçmişlerini sağla" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Gelen iletileri seslendir" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Tüm ka_nallar" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "_Bir %s penceresi etkin olduğunda tüm kanallar" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Yalnızca _penceresi etkinse bir kanal" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Sohbet Odasının adını seslendir" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "İçerik için düzen kipini etkinleştir" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "çift tıklama" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "üç tıklama" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Öntanımlı Sentezleyici" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Asıl Dizge" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Okunuş Dizgesi" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Ka_rakter geri bildirimini etkinleştir" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Boşluksuz _aksanlı tuşları etkinleştir" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Şimdiki kon_um" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Eşleşen metnin en az uzunluğu:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Bulma Seçenekleri" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Bul işlemi sırasında _yalnızca değişen satırları seslendir" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "_Bul işlemi sırasında sonuçları seslendir" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Komut" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Kısayol tuşu" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Öntanımlı" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Öğrenme kipi" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Eylemler" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Braille Bağları" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Yer imleri" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Tarih ve saat" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Fare bakışı" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Nesne gezintisi" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Nesne ayrıntıları" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Bağsız" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Düz bakış" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Konuşma ve ayrıntı düzeyi" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Düz bakış içerikleri" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Değiştirildi" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Masaüstü" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Bildirimler" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Alındı" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Bildirim sunucu" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s için Cthulhu Tercihleri" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Braille içinde işaretle" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Yalnızca Mevcut" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Seslendir" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Profili Farklı Kaydetme Çakışması" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Kullanıcı Profili Çakışması!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"%s profili zaten var.\n" -"Var olan profil üzerinde bu değişiklikleri yapmak ister misiniz?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Kullanıcı profilini yükle" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Aktif profili değiştirmek üzeresiniz. Eğer tercihlerinizde\n" -"yeni değişiklikler yaptıysanız, profil yüklenirken bunlar\n" -"kaybolacaktır.\n" -"\n" -"Önceki değişiklikleri atarak profili yüklemeye devam etmek ister misiniz?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Profili Farklı Kaydet" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Profil Adı:" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Kullanıcı profilini kaldır" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"%s profilini silmek üzeresiniz. Kaydedilmemiş tüm ayarlar ve bu profile " -"kaydedilen ayarlar kaybolacak. Bu profili ve tüm ilgili ayarları kaldırmak " -"konusunda emin misiniz?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Tümü" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Uygulama" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Pencere" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Hiçbiri" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Ba_zı" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "En ç_ok" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Satır" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Tümce" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Blok Alıntı" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Düğme" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Başlık" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Onay Kutusu" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Tıklanabilir" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Açılır Kutu" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Açıklama" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Başlık" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "İç Kare" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Resim" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Etiket" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Sınır İşareti" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Düzey" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Bağlantı" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Liste" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Liste Ögesi" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Nesne" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Paragraf" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Radyo Düğmesi" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Rol" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Seçili Öge" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Durum" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Metin" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Değer" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Blok Alıntılar" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Düğmeler" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Onay Kutuları" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Tıklanabilirler" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Açılır Kutular" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Girişler" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Form Alanları" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Başlıklar" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "İç Kareler" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Resimler" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "%d Düzeyindeki Başlıklar" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Sınır İşareti" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Büyük Nesneler" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Bağlantılar" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Listeler" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Liste Ögeleri" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Paragraflar" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Radyo Düğmeleri" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Tablolar" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Ziyaret Edilmemiş Bağlantılar" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Ziyaret Edilmiş Bağlantılar" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Sayfa Dolaşımı" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Bir sayfa i_lk kez yüklendiğinde otomatik olarak seslendirmeye başla" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "İlk kez yüklendiğinde sayfanın özetini _sun" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Duraklamalar arasında konuşmaları par_çalara ayır" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s öntanımlı ses" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Öntanımlı" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Bağlantı" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Büyük Harf" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Konuşma Sentezleyici" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Yazım Denetimi" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Yazım _hatası" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Yazım _önerisi" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Hatanın _içeriğini sun" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Hesap çizelgesi hücre koordinatlarını seslendir" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Seçilen hesap çizelgesi aralığını her zaman seslendir" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "_Hücre başlığını duyur" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Tablo Dolaşımı" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "_Boş hücreleri atla" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "H_ücreyi seslendir" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Hü_cre koordinatlarını seslendir" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "_Çoklu hücre aralığını seslendir" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Öznitelik Adı" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Düzeltme imi dolaşımını denetle" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "_Yapısal dolaşımı etkinleştir" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "Ses _teması:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Ses teması" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "Ö_zet" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d bildirim" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Kontrol" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "sola kaydır" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "sol alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "sol kontrol" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "sağa kaydır" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "sağ alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "sağ kontrol" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "sol meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "sağ meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "büyük harf kilidi" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "büyük harf kilidi" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "önceki sayfa" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "sonraki sayfa" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "sol tab" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "geri tuşu" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "enter" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "yukarı" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "aşağı" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "sol" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "sağ" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "sol süper" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "sağ süper" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "menü" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "yardım" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "çoklu" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "kip değiştir" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "esc" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "insert" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "delete" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "başlangıç" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "düzeltme işareti" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "halka" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "vuru" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "eksi" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Büyük _Harf Kilidi" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Süper" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "kalın %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "eğik %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "kalın eğik %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "el yazısı %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "kalın el yazısı %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "eski yazı %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "çift çizgili %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "kalın eski yazı %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "sans-serif %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "sans-serif kalın %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "sans-serif eğik %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "sans-serif kalın eğik %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "eş aralıklı %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "noktasız %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "sol ok" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "yukarı ok" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "sağ ok" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "aşağı ok" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "sol sağ ok" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "yukarı aşağı ok" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "kuzey batı oku" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "kuzey doğu oku" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "güney doğu oku" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "çubuktan sola ok" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "çubuktan yukarı ok" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "çubuktan sağa ok" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "çubuktan aşağı ok" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "sola çift ok" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "yukarı çift ok" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "sağa çift ok" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "aşağı çift ok" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "sola sağa çift ok" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "yukarı aşağı çift ok" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "kuzey batıya çift ok" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "kuzey doğuya çift ok" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "güney doğuya çift ok" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "güney batıya çift ok" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "sağ yönlü ok" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "sağ yönlü ok başı" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "eksi" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "küçüktür" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "büyüktür" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "düzeltme işareti" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "vurgu imi (hacek)" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "breve" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "nokta" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "çift dikey çizgi" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "yatay üç nokta" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "her" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "tümleyen" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "kısmi diferansiyel" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "vardır" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "yoktur" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "boş küme" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "arttır" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "nabla" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "elemanıdır" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "elemanı değildir" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "küçük elemanıdır" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "eleman olarak içerir" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "eleman olarak içermez" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "küçük eleman olarak içerir" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "kanıt sonu" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "çarpım" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "alt çarpım" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "toplam" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "artı eksi" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "artı nokta" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "bölüm" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "eksi ayarla" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "yıldız işlemi" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "halka işlemi" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "im işlemi" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "karekök" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "küpkök" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "dördüncü kök" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "orantılı" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "sonsuz" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "dik açı" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "açı" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "ölçülmüş açı" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "küresel açı" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "böler" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "bölmez" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "paraleldir" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "paralel değildir" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "mantıksal ve" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "mantıksal veya" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "kesişim" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "birleşim" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "çift integral" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "üçlü integral" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "kontür integrali" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "yüzey integrali" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "hacim integrali" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "saat yönünde integral" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "saat yönünde kontür integrali" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "saat yönünün tersinde kontür integrali" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "öyleyse" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "çünkü" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "oran" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "orantı" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "eksi nokta" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "fazla" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "geometrik orantı" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "homotetik" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "yaklaşıktır" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "ters yaklaşıktır" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "ters çevrilmiş tembel S" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "sinüs dalgası" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "burum çarpımı" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "yaklaşık değildir" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "eksi yaklaşıktır" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "asimptotik olarak eşittir" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "asimptotik olarak eşit değildir" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "yaklaşık olarak eşittir" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "tam olarak değil ama yaklaşık olarak eşittir" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ne yaklaşık olarak ne de tam olarak eşittir" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "neredeyse eşittir" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "neredeyse eşit değildir" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "neredeyse eşittir veya tam eşittir" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "üçlü yaklaşıktır" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "tümü eşittir" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "eşdeğerdir" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "geometrik olarak eşdeğerdir" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "aralarındaki fark" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "limite yaklaşırken" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "geometrik olarak eşittir" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "yaklaşık olarak eşittir ya da görüntüsüdür" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "görüntüsüdür ya da yaklaşık olarak eşittir" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "iki nokta eşittir" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "eşittir iki nokta" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "eşittir içinde halka" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "halkalı eşittir" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "karşılık gelir" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "tahminen" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "eşaçılıdır" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "yıldızlı eşittir" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "deltalı eşittir" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "tanım olarak eşittir" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "ile ölçülür" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "soru işaretli eşittir" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "eşit değildir" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "özdeştir" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "özdeş değildir" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "katı şekilde eşdeğerdir" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "küçük eşittir" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "büyük eşittir" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "eşittir üzeri küçüktür" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "eşittir üzeri büyüktür" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "küçüktür ama eşit değildir" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "büyüktür ama eşit değildir" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "çok daha küçüktür" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "çok daha büyüktür" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "arasındadır" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "eşdeğer değildir" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "küçük değildir" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "büyük değildir" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "küçük eşit değildir" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "büyük eşit değildir" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "küçüktür ya da eşdeğerdir" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "büyüktür ya da eşdeğerdir" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "küçük ya da eşdeğer değildir" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "büyük ya da eşdeğer değildir" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "küçüktür ya da büyüktür" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "büyüktür ya da küçüktür" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "küçük ya da büyük değildir" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "büyük ya da küçük değildir" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "öncülüdür" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "ardılıdır" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "öncülüdür ya da eşittir" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "ardılıdır ya da eşittir" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "öncülüdür ya da eşdeğeridir" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "ardılıdır ya da eşdeğeridir" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "öncülü değildir" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "ardılı değildir" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "alt kümesidir" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "üst kümesidir" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "alt kümesi değildir" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "üst kümesi değildir" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "alt kümesidir ya da eşittir" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "üst kümesidir ya da eşittir" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "alt kümesi ya da eşidi değildir" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "üst kümesi ya da eşidi değildir" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "eşit olmamakla beraber alt kümesidir" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "eşit olmamakla beraber üst kümesidir" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "çoklu küme" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "çoklu küme çarpımı" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "çoklu küme birleşimi" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "görüntü karesidir" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "görüntü aslıdır" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "görüntü karesidir ya da eşittir" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "görüntü aslıdır ya da eşittir" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "kare kep" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "kare kap" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "halkalı artı" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "halkalı eksi" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "halkalı çarpı" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "halkalı bölü" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "halkalı nokta işlemi" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "halkalı halka işlemi" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "halkalı yıldız işlemi" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "halkalı eşittir" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "halkalı çizgi" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "kareli artı" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "kareli eksi" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "kareli çarpı" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "kareli nokta işlemi" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "sağ çivi" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "sol çivi" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "aşağı çivi" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "yukarı çivi" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "iddia" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "modeller" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "doğru" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "zorlar" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "üçlü dikey çubuklu sağ turnike" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "çift dikey çubuklu çift sağ turnike" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "kanıtlamaz" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "doğru değil" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "zorlamaz" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "olumsuzlanmış çift dikey çubuklu çift sağ turnike" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "ilişki altında öncülüdür" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "ilişki altında ardılıdır" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "normal alt grubudur" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "normal alt grubu olarak içerir" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "normal alt grubudur ya da eşittir" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "normal alt grubu ya da eşidi olarak içerir" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "aslıdır" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "görüntüsüdür" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "çoklueşlem" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "hermit eşleniği matrisi" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "araya ekleme" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "dışlayıcı veya" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "ve değil" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "veya değil" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "yaylı dik açı" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "dik üçgen" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "karo işlemi" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "nokta işlemi" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "yıldız işlemi" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "bölüm çarpımı" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "papyon" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "sol normal etmen yarıyönlendirmeli çarpım" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "sağ normal etmen yarıyönlendirmeli çarpım" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "sol yarıyönlendirmeli çarpım" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "sağ yarıyönlendirmeli çarpım" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "ters yaklaşık eşittir" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "kıvrımlı mantıksal veya" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "kıvrımlı mantıksal ve" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "çift altküme" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "çift üstküme" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "çift kesişim" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "çift birleşim" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "dirgen" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "eşit ve paraleldir" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "noktalı küçüktür" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "noktalı büyüktür" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "çok fazla küçüktür" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "çok fazla büyüktür" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "küçük eşittir ya da büyüktür" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "büyük eşittir ya da küçüktür" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "eşittir ya da küçüktür" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "eşittir ya da büyüktür" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "eşittir ya da öncülüdür" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "eşittir ya da ardılıdır" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "öncülü ya da eşidi değildir" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "ardılı ya da eşidi değildir" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "kare görüntüsü ya da eşidi değildir" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "kare aslı ya da eşidi değildir" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "kare görüntüsüdür ya da eşit değildir" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "kare aslıdır ya da eşit değildir" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "küçüktür ama eşdeğeri değildir" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "büyüktür ama eşdeğeri değildir" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "öncülüdür ama eşdeğeri değildir" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "ardılıdır ama eşdeğeri değildir" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "normal altgrubu değildir" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "normal altgrup olarak içermez" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "normal altgrubu ya da eşidi değildir" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "normal altgrubu ya da eşidi olarak içermez" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "diket üç nokta" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "ortadan yatay üç nokta" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "yukarı sağ çapraz üç nokta" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "aşağı sağ çapraz üç nokta" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "uzun yatay üst çizgili elemanıdır" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "uzun yatay üst çizginin sonunda dikey çubuklu elemanıdır" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "küçük uzun yatay üst çizginin sonunda dikey çubuklu elemanıdır" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "üstten noktalı elemanıdır" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "üstten çubuklu elemanıdır" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "küçük üstten çubuklu elemanıdır" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "alttan çubuklu elemanıdır" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "çift yatak üst çizgili elemanıdır" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "uzun yatay üst çizgili içerir" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "uzun yatay üst çizginin sonunda dikey çubuklu içerir" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "küçük uzun yatay üst çizginin sonunda dikey çubuklu içerir" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "üstten çubuklu içerir" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "küçük üstten çubuklu içerir" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z gösterimli torba üyeliği" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "sol tavan" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "sağ tavan" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "sol taban" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "sağ taban" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "üst çengel" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "alt çengel" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "sol açılı parantez" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "ağ açılı parantez" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "halkalı nokta" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "noktalı birleşim" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "artılı birleşim" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "kare kesişim" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "kare birleşim" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "siyah kare" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "beyaz kare" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "siyah karo" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "beyaz daire" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "siyah daire" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "beyaz im" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "siyah orta küçük kare" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "altı çizgili %s" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "bölmeli %s" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "dikey çizgili %s" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "uygulama" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "boşluk" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "kalın" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "yer imi girildi" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "yer imleri kaydedildi" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "yer imleri kaydedilemedi" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Yer imi bulunamadı." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Yer imi bulunamadı." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Atlama kipi etkin." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Hesap makinesi ekranı alınamadı" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "simge" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Büyük harf ayarlama biçemi olarak simge ayarlandı." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "hiçbiri" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Büyük harf ayarlama biçemi olarak hiçbiri ayarlanmadı." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "hecele" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Büyük harf ayarlama biçemi olarak heceleme ayarlandı." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Düzenleme imini uygulama denetliyor." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu imleci kontrol ediyor." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "%s hücresi" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "%s seçildi" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "%s ile %s arası seçildi" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "%s ile %s arası seçim kaldırıldı" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "%s seçimi kaldırıldı" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Seçeneği kullanmayı önle" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Seçeneği kullanmaya zorla" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "SEÇENEK" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "İsteğe bağlı bağımsız değişkenler" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Kullanım: " - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Şunlar geçersiz: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Bilinen çalışan uygulamaları yazdırır" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Profil yükle" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profil yüklenemiyor: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "Cthulhu başlatılamıyor çünkü masaüstüne bağlanamıyor." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Ayarlar yöneticisi etkinleştirilemiyor. Çıkılıyor." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Bu oturum için hali hazırda başka bir ekran okuyucu işlemi çalışıyor.\n" -"Bu işlemi yeni bir işlemle değiştirmek için “cthulhu --replace” komutunu " -"çalıştırın." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "AD" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Kullanıcı tercihleri için alternatif dizini kullan" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "KLASÖR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Bu uygulamanın sürümü" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Şu anda çalışan bir Cthulhu örneğini değiştir" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Bu yardımı göster ve çık" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Hata ayıklama çıktısını debug-YYYY-AA-GG-SS:DD:SS.out dosyasına gönder" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Hata ayıklama çıktısını belirtilen dosyaya gönder" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "DOSYA" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Kullanıcı tercihlerini yapılandır (metin sürümü)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Kullanıcı tercihlerini ayarla (GUI sürümü)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Hataları https://groups.io/g/stormux adresine bildirin." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Seçim panoya kesildi." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "kesildi" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Seçim panoya kopyalandı." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "kopyalandı" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Pano içeriği yapıştırıldı." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "yapıştırıldı" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Arkadaşlarım yazarken bunu duyurma." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "arkadaşlarınız yazarken duyur." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "%s sohbet odasından ileti" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Yeni sohbet sekmesi %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Sohbet odasının adını seslendirme." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "sohbet odasının adını seslendir." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Sohbet odasına özel ileti geçmişlerini sağlama." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Sohbet odasına özel ileti geçmişlerini sağla." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "silme başlangıcı" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "silme sonu" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "ekleme başlangıcı" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "ekleme sonu" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "vurgulama başlangıcı" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "vurgulama sonu" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "öneri sonu" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Taşıyıcının sonu." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Bir taşıyıcıda değil." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "tüm ögeler seçildi" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Öntanımlı düğme %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Öntanımlı düğme %s. Soluk" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Öntanımlı düğme bulunamadı" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " altsimge %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " üstsimge %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "İletişim kutusunda değil" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "tüm belge seçildi" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "tüm belge seçimi kaldırıldı" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "belge imleç konumundan itibaren seçili" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "belge imleç konumundan itibaren seçimsiz" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "belge imleç konumuna kadar seçili" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "belge imleç konumuna kadar seçimsiz" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "%d satırı için dinamik sütun başlığı kümesi" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Dinamik sütun başlığı temizlendi." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "%s sütunu için dinamik satır başlığı kümesi" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Dinamik satır başlığı temizlendi." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "boş" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilobayt" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabayt" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Hiçbir dosya bulunamadı." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Panoya eklenmiş içerikler." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Panoya kopyalanmış içerikler." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Düz bakış kullanılamıyor." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Düz bakışa giriliyor." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Düz bakıştan çıkılıyor." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Düz bakış geçerli nesneye kısıtlandı" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Sınırsız düz bakış" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "formülü" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "ietişim penceresini açar" - -# Kılavuzu da açabilir. Lakin kullanım yerinden emin olamıyorum. -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "ızgarayı açar" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "liste kutusu açar" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "menüyü açar" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "ağacı açar" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "grafik haritası bağı" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Girilen tuş zaten %s ile bağlı" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Tuş alındı: %s. Onaylamak için giriş tuşuna basın." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Yeni tuş: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Kısayol tuşu silindi. Onaylamak için enter’e basın." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Kısayol kaydedildi." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "yeni kısayol tuşlarına basın" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "tuş" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Geri bildirim tuş olarak ayarlandı." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Hiçbiri" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Geri bildirim hiçbiri olarak ayarlandı." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "tuş ve sözcük" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Geri bildirim tuş ve sözcük olarak ayarlandı." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "tümce" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Geri bildirim tümce olarak ayarlandı." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "sözcük" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Geri bildirim sözcük olarak ayarlandı." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "sözcük ve tümce" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Geri bildirim sözcük ve tümce olarak ayarlandı." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Çevreleyen: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "aktüeryal bir sembol" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "bir kutu" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "bir daire" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "bir uzun bölme işareti" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "bir radikal" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "bir yuvarlak köşeli kutu" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "bir yatak çizgi" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "bir dikey çizgi" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "bir aşağı çapraz çizgi" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "bir yukarı çapraz çizgi" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "bir kuzeydoğu oku" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "altta bir çizgi" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "solda bir çizgi" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "sağda bir çizgi" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "üstte bir çizgi" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "bir fazör açısı" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "bir arapça faktöryel sembolü" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "ve" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "kesir başlangıcı" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "çubuksuz kesir, başlangıç" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "altı" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "kesir sonu" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "karekök" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "küpkök" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "kök" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "kök başlangıcı" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "kök bitişi" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "altsimge" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "üstsimge" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "ön-altsimge" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "ön-üstsimge" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "altından simge" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "üzerinden simge" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "tablo sonu" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "iç içe tablo sonu" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "erişilemez" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Devre dışı bırakıldı" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Girinti ve yaslamanın okunması devre dışı bırakıldı." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Etkinleştirildi" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Girinti ve yaslamanın okunması etkinleştirildi." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Öğrenme kipi. Çıkış için kaçış tuşuna basın." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Öğrenme kipine giriliyor. İşlevini öğrenmek için bir tuşa basın. Ekran " -"okuyucusunun belgelendirmesini görüntülemek için F1’e basın. Ekran " -"okuyucusunun öntanımlı kısayollarının bir listesini almak için F2’ye basın. " -"Ekran okuyucusunun geçerli uygulama için tanımlı kısayollarının bir " -"listesini almak için F3’e basın. Öğrenme kipinden çıkmak için Esc’ye basın." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "blok alıntıdan çıkılıyor." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "ayrıntılardan çıkılıyor." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "beslemeden çıkılıyor." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "figürden çıkılıyor." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "formdan çıkılıyor." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "afişten çıkılıyor." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "tamamlayıcı içerikten çıkılıyor." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "bilgiden çıkılıyor." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "ana içerikten çıkılıyor." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "gezintiden çıkılıyor." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "bölgeden çıkılıyor." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "aramadan çıkılıyor." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "listeden çıkılıyor." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "panelden çıkılıyor." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "tablodan çıkılıyor." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "ipucundan çıkılıyor." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "soyuttan çıkılıyor." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "teşekkürlerden çıkılıyor." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "son sözden çıkılıyor." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "eklentilerden çıkılıyor." - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "kaynakçadan çıkılıyor." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "bölümden çıkılıyor." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "baskı bilgisinden çıkılıyor." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "sonuçtan çıkılıyor." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "jenerikten çıkılıyor." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "jeneriklerden çıkılıyor." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "ithaftan çıkılıyor." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "son notlardan çıkılıyor." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "yazıttan çıkılıyor." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "son yazıdan çıkılıyor." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "düzeltmelerden çıkılıyor." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "örnekten çıkılıyor." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "ön sözden çıkılıyor." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "sözlükten çıkılıyor." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "indeksten çıkılıyor." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "girişten çıkılıyor." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "sayfa listesinden çıkılıyor." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "bölümden çıkılıyor." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "ön sözden çıkılıyor." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "girizgâhtan çıkılıyor." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "tanıtımdan çıkılıyor." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "QNA’dan çıkılıyor." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "öneriden çıkılıyor." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "içerikler tablosundan çıkılıyor." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "satır imleç konumundan aşağı doğru seçildi" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "satır imleç konumundan yukarı doğru seçildi" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "satır imleç konumundan aşağı doğru seçimsiz" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "satır imleç konumundan yukarı doğru seçimsiz" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Öğrenme kipinden çıkıyor." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "satır önceki imleç konumundan itibaren seçildi" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "önceki imleç konumundan satır sonuna kadar seçildi" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "bağlantı" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "aynı sayfa" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "aynı site" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "başka site" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s, %(file)s dosyasına bağlanır" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s bağlantısı" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "ziyaret edilmiş %s bağlantısı" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Listede gezinmek için Yukarı ve Aşağı Ok tuşlarını kullanın. Çıkmak için Esc " -"tuşuna basın." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Tüm canlı bölgeler kapatıldı" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "canlı bölgelerin yumuşaklık düzeyleri geri alındı" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "yumuşaklık düzeyi %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "canlı bölge iddialı olarak belirleniyor" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "canlı bölge kapalı belirleniyor" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "canlı bölge sert olarak belirleniyor" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "canlı bölge kaba olarak belirleniyor" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Canlı bölgeleri izleme kapalı" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Canlı bölgeleri izleme açık" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "kayıtlı canlı ileti yok" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Canlı bölge desteği kapalı" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Bulunamadı" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Geçerli konum bulunamadı." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "kapalı" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "açık" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "yazım hatalı" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Yanlış yazılmış sözcük: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "İçerik %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Göz atma kipi" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Odak kipi" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Odak kipini etkinleştirmek için %s tuşuna basın." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Odak kipi yapışkan." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Gözatma kipi yapışkan." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Düzen kipi." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Nesne kipi." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "İmleç nesneye taşındı." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Nesne üzerinde fare bulunamadı." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Fare bakışı devre dışı." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Fare bakışı etkin." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Hata: Nesnelerin listesi oluşturulamıyor." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Alt yok." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Metin yok." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Üst yok." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Önceki yok." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Basitleştirilmiş gezinti etkinleştirildi." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Basitleştirilmiş gezinti devre dışı bırakıldı." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Dallanma düzeyi %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Yeni öge eklendi" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "%s üstünde eylem bulunamadı" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Odak yok" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Herhangi bir uygulama odakta değil." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Başka blok alıntı yok." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Başka düğme yok." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Başka onay kutusu yok." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Başka büyük nesne yok." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Tıklanabilecek başka bir şey yok." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Başka açılır kutu yok." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Başka giriş yok." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Başka form alanı yok." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Başka başlık yok." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "%d düzeyinde başka başlık yok." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Başka iç kare yok." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Başka bir grafik yok." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Sınır işareti bulunamadı." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Başka bir bağlantı yok." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Başka liste yok." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Başka liste ögesi yok." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Başka canlı bölge yok." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Başka paragraf yok." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Başka radyo düğmesi yok." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Başka ayraç yok." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Başka tablo yok." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Başka ziyaret edilmemiş bağlantı yok." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Başka ziyaret edilmiş bağlantı yok." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Seçili metin yok." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Bir bağlantı üzerinde değilsiniz." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Bildirim" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Alt" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Üst" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Bildirim iletisi yok" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "rakamlar" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Sayıları rakam olarak seslendir." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "sözcükler" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Sayıları sözcük olarak seslendir." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "seçili değil" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "seçili" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Yükleniyor. Lütfen bekleyin." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Yükleme bitti." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s yüklemesi bitti." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Sayfada %s var." - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "sayfa imleç konumundan itibaren seçili" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "sayfa imleç konumuna kadar seçili" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "sayfa imleç konumundan itibaren seçimsiz" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "imleç konumuna kadar seçimsiz" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "imleç konumundan aşağıya doğru paragraf seçildi" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "imleç konumundan yukarıya doğru paragraf seçildi" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "imleç konumundan aşağıya doğru paragraf seçimi kaldırıldı" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "imleç konumundan yukarıya doğru paragraf seçimi kaldırıldı" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Şu an zaten Cthulhu tercihleri penceresi açık.\n" -"Yenisini açmadan önce lütfen bunu kapatın." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "slayt %(position)d / %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profil %s olarak ayarlandı." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Hiçbir profil bulunamadı." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "İlerleme çubuğu %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Tümü" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Noktalama düzeyi tümü olarak ayarlandı." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Çoğu" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Noktalama düzeyi çoğu olarak ayarlandı." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Hiçbiri" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Noktalama düzeyi hiç olarak ayarlandı." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Birazı" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Noktalama düzeyi birazı olarak ayarlandı." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Arıyor." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Arama tamamlandı." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu ayarları yeniden yüklendi." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Seçili metin şudur: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Seçim silindi." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Seçim geri yüklendi." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Metin seçimi kaldırıldı." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Boyut: %d, %d. Konum: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Genişlik: %d. Yükseklik: %d. %d soldan. %d üstten." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Konuşma kapatıldı." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Konuşma etkin." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "daha hızlı." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "daha yavaş." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "daha yüksek." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "daha düşük." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "daha sesli." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "daha yumuşak." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Hız %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Perde %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Ses düzeyi %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher modülü %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher sesi %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Kullanılabilir Speech-dispatcher modülü yok" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Kullanılabilir Speech-dispatcher sesi yok" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Konuşma ayarları kaydedildi" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Konuşma ayarları kaydedilemedi" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Ayrıntı düzeyi: kısa ve öz" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Ayrıntı düzeyi: ayrıntılı" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " nokta nokta nokta" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu sizi karşılıyor." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu dalgaların altında pusuya yatmış." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "%s için uyku modu etkinleştirildi" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "%s için uyku modu devre dışı bırakıldı" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Konuşma kullanılamaz." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Bulunamadı" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Durum çubuğu bulunamadı" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "dizge bulunamadı" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Yapısal dolaşım tuşları kapalı." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Yapısal dolaşım tuşları açık." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Bulunamadı" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Satır %(row)d, sütun %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Tablonun sonu" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Sütunu seslendir" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Satırı seslendir" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Düzensiz" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Bir tabloda değil." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Sütunlar yeniden sıralandı" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Satırlar yeniden sıralandı" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "sütun %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "kolon %(index)d / %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Sütun sonu." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Sütun başı." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Sütun %s seçildi" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "%s ile %s sütunları arası seçildi" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "%s ile %s sütunları arası seçimi kaldırıldı" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Sütun %s seçimi kaldırıldı" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "satır %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "satır %(index)d / %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Satır başlangıcı." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Satır sonu." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Satır silindi." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Son satır silindi." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Satır eklendi." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Tablonun sonuna satır eklendi." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Satır %s seçildi" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "%s ile %s satırları arası seçildi" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "%s ile %s satırları arası seçimi kaldırıldı" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Satır %s seçimi kaldırıldı" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "seçilmiş" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "seçilmemiş" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H saat, %M dakika ve %S saniye" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H saat ve %M dakika" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unikod %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "geri al" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "yinele" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu sürüm %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "beyaz boşluk" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "En alta kaydırılıyor." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "En üste kaydırılıyor." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 öge" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Hücre %d satırı kapsıyor" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d sütun" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Hücre %d sütunu kapsıyor" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d karakter çok uzun" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d pencere)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d odaksız pencere" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d bayt" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d dosya bulundu" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d form" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d başlık" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d öge" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d sınır işareti" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d öge bulundu" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "%d blok alıntıdan çıkılıyor." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "%d listeden çıkılıyor." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Bilinmeyen boyutlu liste" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d ögeli liste" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Bilinmeyen boyutlu besleme" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "%d maddeli besleme" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "%d terimli açıklama listesi" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d değer" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "%d satırlı matematik tablosu" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d sütun" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "%d satırlı iç içe matematik tablosu" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d ileti.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "yüzde %d." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "Belgenin yüzde %d kadarı okundu" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d piksel" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s karakter" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(total)d ögeden %(index)d tanesi seçildi" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d ekran okuyucusu öntanımlı kısayolu bulundu." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(application)s için %(count)d ekran okuyucusu kısayolu bulundu." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d boşluk" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d sekme karakteri" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d tablo" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "bilinmeyen boyutlu tablo" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "%d sütunlu tablo, satır sayısı bilinmiyor" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%d satırlı tablo, sütun sayısı bilinmiyor" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "%d satırlı tablo" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d saniye önce" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d dakika önce" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d saat önce" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d gün önce" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d ziyaret edilmemiş bağlantı" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d ziyaret edilmiş bağlantı" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "seçim düğmesi" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(index)d / %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d / %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "öge %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "DÜZEY %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "ağaç düzeyi %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "AĞAÇ DÜZEYİ %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "%s ayrıntıları" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "%s içinde ayrıntılar var" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "öneri" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "düzenlenebilir açılır kutu" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "düzenlenebilir içerik" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "besleme" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "şekil" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "soyut" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "teşekkürler" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "son söz" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "eklentiler" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "kaynakça girdisi" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "kaynakça" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "bölüm" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "baskı bilgisi" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "sonuç" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "kapak" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "jenerik" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "kredi" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "ithaf" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "son not" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "son notlar" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "yazıt" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "son söz" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "düzeltmeler" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "örnek" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "ön söz" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "sözlük" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "indeks" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "giriş" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "sayfa sonu" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "sayfa listesi" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "bölüm" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "ön söz" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "girizgâh" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "tanıtım" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "QNA" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "alt yazı" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "içerikler tablosu" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s düzey %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "yatay kaydırma çubuğu" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "dikey kaydırma çubuğu" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "yatay kaydırıcı" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "dikey kaydırıcı" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "yatay ayraç" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "dikey ayraç" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "değiştir" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Simge paneli" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "afiş" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "tamamlayıcı içerik" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "bilgi" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "ana içerik" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "gezinti" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "bölge" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "arama" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "ziyaret edilmiş bağlantı" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "menü düğmesi" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "artan sıralı" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "azalan sıralı" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "sıralı" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "tıklanabilir" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "daraltılmış" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "genişletilmiş" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "uzun açıklaması var" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "yatay" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "dikey" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "işaretli" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "işaretli değil" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "açık" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "kapalı" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "kısmen işaretli" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "basılı" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "basılı değil" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "seçilmedi" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "seçili" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "seçili değil" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "seçili değil" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "ziyaret edilmiş" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "ziyaret edilmemiş" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "soluk" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "salt okunur" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "saltokunur" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "gerekli" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "çoklu-seçim" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "geçersiz girdi" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "geçersiz" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "yazım hatası" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "yazım" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "geçersiz dil bilgisi" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "dil bilgisi" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Bul" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Ekran Okuyucusu Bul Penceresi" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Kapat" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Bul" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Aranacak:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Aranacak:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Pencerenin üs_tü" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Pencerenin üstü" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "İtibaren başla:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Sarmala" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "_Geriye doğru ara" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Arama yönü:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Eşleş_me durumu" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Yalnızca _tam sözcüğü eşleştir" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Seçenekler:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Öntanımlı" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Büyük harf" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Hiper Bağ" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Sistem" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Uygulama" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Pencere" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu Tercihleri" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Yardım" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Uygula" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Dizüstü" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Klavye Düzeni" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Etkin _Profil:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Ba_şlangıç Profili:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "Yük_le" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "_Farklı Kaydet" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "_Kaldır" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiller" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "İpuçlarını _sun" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "_Farenin altındaki nesneyi seslendir" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Fare" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "_Zaman biçimi:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Tarih bi_çimi:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Saat ve Tarih" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Güncellemeleri _seslendir" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "_Braille güncellemeleri" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Sıklık (saniye):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Şun(lar)a uygulanır:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "Değişiklikleri bi_p ile bildir" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "İlerleme Çubuğu Değişiklikleri" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Tümünü Seslendirmede _başa sarma ve ileri sarmayı etkinleştir" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Tümünü Seslendirmede _yapısal gezinmeyi etkinleştir" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "_Seslendirme Türü:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Tüm blok _alıntıları bildir" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Tüm li_steleri bildir" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Tüm _tabloları bildir" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Tüm _panelleri bildir" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Tüm _form alanlarını bildir" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Tüm sınır _işaretlerini bildir" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Tümünü Seslendir" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "Öğe _sunumu:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Genel" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Ses yüksek_liği:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "P_erde:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Hız:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Kişi:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Dil:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Konuşma s_entezleyici:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Konuşma _sistemi:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "_Ses türü:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Büyük harf ayarlama biçemi:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Ses Türü Ayarları" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Değişik büyüklükteki dizgeleri _sözcük olarak oku" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Sayıları _rakam olarak seslendir" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Genel Ses Ayarları" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Ses" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Konuşmayı _etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Detay" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Ayrıntı Düzeyi" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Tümü" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Noktalama Düzeyi" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Yalnızca görüntülenen metni seslendir" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Boş satırları seslendir" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "_Girintileri ve yaslamaları seslendir" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Nesne ipuçlarını seslendi_r" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Nesnenin sayısal k_onumunu bildir" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Yönlendirici iletileri seslendir" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "Ayrıntılı _sistem iletileri" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Renkleri ad olarak s_eslendir" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Gezinti sırasında blok _alıntıları bildir" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Gezinti sırasında _listeleri bildir" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Gezinti sırasında _tabloları bildir" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "_Hatalı yazılmış sözcük belirtecini bildir" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Gezinti sırasında _panelleri bildir" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Gezinti sırasında sınır _işaretlerini bildir" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Gezinti sırasında _formları bildir" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "_Açıklamayı seslendir" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Hesap tablola_rında satırın tamamını seslendir" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "_Belge tablolarında satırın tamamını seslendir" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "_Görsel Arayüz tablolarında satırın tamamını seslendir" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Konuşulan Bağlam" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Konuşma" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Braille de_steğini etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Kıs_altılmış rol adları" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "_Satır sonu sembolünü kapat" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Kısaltma _Tablosu:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Kısaltmalı Braille’i _Etkinleştir" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "_Sözcük kaydırmayı etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Görüntü Ayarları" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Hiçbiri" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Seçim Göstergesi" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Hiperbağ Göstergesi" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Flaş _iletileri etkinleştir" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "S_üre (saniye):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "_Kalıcı iletiler" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "_Ayrıtılı iletiler" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Flaş İleti Ayarları" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Braille" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "_Tuş geri bildirimini etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "_Alfabetik tuşları söyle" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "_Sayısal tuşları etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "_Noktalama tuşlarını etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Bo_şluk tuşunu etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "_Düzenleyici tuşları etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "_Fonksiyon tuşlarını etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Eylem _tuşlarını söyle" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Yö_n tuşlarını etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "_Sözcük geri bildirimini etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "_Tümce geri bildirimini etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Geri Bildirim" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "Ekran Okuyucu _Girişken Tuşu/Tuşları:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Kısayol Tuşları" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Telaffuz Sözlüğü" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Ye_ni girdi" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Sil" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Telaffuz" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Tümünü _seslendir" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Hiçbiri_ni seslendirme" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "Sıfı_rla" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Metin öznitelikleri" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "En a_lta taşı" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Bir _aşağı taşı" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Bir y_ukarı taşı" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "_Üste taşı" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Seçili niteliği ayarla" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Braille İmleci" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Metin Öznitelikleri" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Yapay zeka asistanını etkinleştir" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Sağlayıcı:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Yerel - Ücretsiz)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API _Anahtar Dosyası:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "API anahtar dosyasının yolu" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "_Claude API Anahtarı Al" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Claude API anahtarını almak ve otomatik kaydetmek için tarayıcıyı aç" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Yapay zeka eylemlerinden önce onay iste" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama _Modeli:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Ollama için model adı (örn. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama _Uç Noktası:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API uç nokta URL'si (örn. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "Ekran Görüntüsü _Kalitesi:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Düşük" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Orta" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Yüksek" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Yapay zeka asistanı" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "_Dil kodu:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "_Ölçekleme faktörü:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "_Gri tonlamalı görüntü" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "Görüntüyü _ters çevir" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Siyah beyaz görüntü" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "Siyah/Beyaz _Eşiği:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "Renkleri _analiz et" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Sonuçları _panoya kopyala" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "arka plan rengi" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "arka plan tam yüksekliği" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "arka plan çizgileri" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "yön" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "düzenlenebilir" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "aile adı" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "ön alan rengi" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "ön alan çizgileri" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "yazı tipi etkisi" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "girinti" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "hata" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "görünmez" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "hizalama" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "dil" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "sol kenar boşluğu" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "satır yüksekliği" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "paragraf biçemi" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "satırın üzerindeki pikseller" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "satırın altındaki pikseller" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "bölme içindeki pikseller" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "sağ kenar boşluğu" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "yükselim" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "ölçek" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "boyut" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "genişleme" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "üstü çizili" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "biçem" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "metin süslemesi" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "metin döndürülmesi" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "metin gölgeleme" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "alt çizgi" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "türev" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "dikey hizalama" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "ağırlık" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "bölme kipi" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "yazma kipi" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "doğru" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "yanlış" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "hiçbiri" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "gömük" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "kabarık" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "dış hatlar" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "üzeri çizgili" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "üstü çizili" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "yanıp sönen" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "siyah" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "tek" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "çift" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "düşük" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "karakter" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "sözcük" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "sözcük karakteri" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "sol" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "sağ" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "orta" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "hizalama yok" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "doldur" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "çok sıkı" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "aşırı sıkı" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "sıkı" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "yarı sıkı" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "olağan" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "yarı geniş" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "genişletilmiş" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "çok geniş" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "aşırı geniş" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "küçük harfler" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "kalın" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "eğik" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Öntanımlı" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Metin içeriği" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Başlık" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "taban çizgisi" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "alt" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "süper" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "üst" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "metin-üstü" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "orta" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "alt" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "metin-altı" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "kalıtsal" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "düz" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "heceleme" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Lütfen seçim için boşluğa basın." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Genişletmek için boşluk, ardından bir öge seçmek için yukarı ve aşağı " -"tuşlarını kullanın." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Odağı alt pencerelere vermek için alt+f6 tuşlarına bas." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Ögeleri taşımak için ok tuşlarını kullanın ya da arama için doğrudan yazın." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Sistem menüsünü almak için alt+f1 tuşlarına bakın." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Bir öge seçmek için yukarı ve aşağı kullanın." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Daraltmak için lütfen shift ile sola basın." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Genişletmek için lütfen shift ile sağa basın." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Etkinleştirmek için giriş tuşuna basın." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Metin içine yaz." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Sekmeler arasında geçiş için sol ve sağ ok tuşlarını kullanın." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Etkinleştirmek için boşluğa basın." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Değer seçmek için yukarı ya da aşağı okları kullanın. Ya da istenen rakamsal " -"değeri yazın." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Değiştirmek için ok tuşlarını kullanın." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Gezmek için, lütfen sol ya da sağ ok. Ögeler arasında geçmek için yukarı ya " -"da aşağı oka basın." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Açmak için sağ ok tuşunu kullanın." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Azaltmak için sol, artırmak için sağ ok tuşlarını kullanın. Değeri en az ve " -"en çok olarak ayarlamak için, home ve end tuşlarını kullanın." diff --git a/po/ug.po b/po/ug.po deleted file mode 100644 index a2f8505..0000000 --- a/po/ug.po +++ /dev/null @@ -1,9801 +0,0 @@ -# Uyghur translation for cthulhu. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# Gheyret Kenji,2010. -# Sahran , 2010. -# Zeper , 2010. -# Muhemmed Erdem , 2011 -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2013-03-07 20:34+0900\n" -"Last-Translator: Gheyret Kenji \n" -"Language-Team: Uyghur Computer Science Association \n" -"Language: ug\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu ئېكران ئوقۇغۇ" - -#, fuzzy -msgid "screen;reader;accessibility;speech;braille;" -msgstr "screen reader;speech;braille;ئېكران ئوقۇغۇچ;تاۋۇش;ئەمالار ئېلىپبەسى;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "؟؟؟" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "نومۇر بۇراش" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "سىز" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "كۆزنەك" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "رادىئو" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "ئاتالغۇ" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "كۆرسەتمە" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "ئاپتوماتىك" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "چېخچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "ئىسپانچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "كانادا فىرانسۇزچىنى 2-دەرىجە" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "فىرانسىيە فىرانسۇزچىنى 2-دەرىجە" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "لاتۋىيە تىلى 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "گوللاندىيە گېرمانچىسى 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "نورۋېگىيەچە 0-دەرىجە" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "نورۋېگىيەچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "نورۋېگىيەچە 2-دەرىجە" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "نورۋېگىيەچە 3-دەرىجە" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "پولشاچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "پورتۇگالچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "شىۋىتچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "ئەرەبچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "ۋېلشچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "ۋېلشچە 2-دەرىجە" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "گېرمانچە 0-دەرىجە" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "گېرمانچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "گېرمانچە 2-دەرىجە" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "ئەنگلىيە ئىنگلىزچىسى 2-دەرىجە" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "ئەنگلىيە ئىنگلىزچىسى 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "ئامېرىكا ئىنگلىزچىسى 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "ئامېرىكا ئىنگلىزچىسى 2-دەرىجە" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "كانادا فىرانسۇزچىنى 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "فىرانسىيە فىرانسۇزچىنى 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "گىرېكچە بىرىنچى دەرىجە" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "ھىندىچە بىرىنچى دەرىجە" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "ماجارچە 8 چېكىتلىك كومپيۇتېر" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "ماجارچە بىرىنچى دەرىجە" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "ماجارچە بىرىنچى دەرىجە" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "ئىتاليانچە 1-دەرىجە" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "بېلگىيە گېرمانچىسى 1-دەرىجە" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "بوشلۇق" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "يېڭى قۇر" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "بەتكۈچ" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "ئۈندەش" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "نەقىل" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "نومۇر" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "دوللار" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "پىرسەنت" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "ۋە" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "ئايرىش بەلگىسى" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "سول چوڭ تىرناق" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "ئوڭ چوڭ تىرناق" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "يۇلتۇز" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "پىلۇس" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "پەش" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "سىزىقچە" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "چېكىت" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "يانتۇ سىزىق" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "قوش چېكىت" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "چېكىتلىك پەش" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "كىچىك" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "تەڭلىك" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "چوڭ" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "سوئال" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "دا" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "سول تىرناق" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "تەتۈر يانتۇ سىزىق" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "ئوڭ تىرناق" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "نۇربەلگىسى" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "ئاستى سىزىق" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "تۆۋەن ئۇرغۇ بەلگىسى" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "ئوڭ قوش تىرناق" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "تىك بالداق" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "سول چوڭ تىرناق" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "سوزۇش بەلگىسى" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "ئۈزلۈكسىز بوشلۇق" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "تەتۈر ئۈندەش" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "سېنت" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "قاداق" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "پۇل بەلگىسى" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "يېن" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "تىك سىزىق" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "دائىرە" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "ئۈزۈك" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "نەشر ھوقۇقى" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "ئۈستىدىكى a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "سول قوش تىرناق" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "لوگىكىلىق ياق بەلگىسى" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "يۇمشاق سىزىقچە" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "خەتلىتىلدى" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "سوزۇق تاۋۇش بەلگىسى" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "گرادۇس" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "پىلۇس ۋە مىنۇس" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "يۇقىرىقى 6" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "يۇقىرىقى 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "ئۇرغۇلۇق" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "پاراگراف بەلگىسى" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "ئوتتۇرا نۇقتا" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "ئاۋاز ئۆزگەرتىش بەلگىسى" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "ئۈستۈنكى 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "تەرتىپ" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "ئوڭ قوش تىرناق" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "چارەك" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "يېرىم" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "ئۈچ چارەك" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "تەتۈر سوئال بەلگىسى" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "á" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "À" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "Á" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "Â" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "Ã" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "Ä" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "Å" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "Æ" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "È" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "É" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "Ê" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "Ë" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "Ì" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "Í" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "Î" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "Ï" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "Ñ" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "Ò" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "Ó" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "Ô" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "Õ" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "Ö" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "ۋاقىت" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "Ø" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "Ù" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "Ú" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "Û" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "Ü" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Ý" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "Þ" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "ß" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "à" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "â" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "ã" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "ä" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "å" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "æ" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "ç" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "è" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "é" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "ê" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "ë" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "ì" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "í" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "î" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "ï" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "ñ" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "ò" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "ó" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "ô" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "õ" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "ö" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "بۆلۈش بەلگىسى" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "ø'" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "þ" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "ú" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "ù" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "û" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "ü" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "ý" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "ÿ" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Ÿ" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "ƒ" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "سىزىقچە" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "سول تاق پەش" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "ئوڭ تاق پەش" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "تۆۋەنكى تاق پەش" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "سول قوش پەش" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "ئوڭ قوش پەش" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "تۆۋەنكى قوش پەش" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "ئىسترېلكا" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "قوش ئىسترېلكا" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "تۈر بەلگىسى" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "ئۈچبۇلۇڭ تۈر بەلگىسى" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "مىڭدىن بىر" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "تاق پەش" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "قوش پەش" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "قوش پەش" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "سىزىقچە تۈرى" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "ياۋرو" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "سودا ماركىسى" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "توغرا بەلگىسى" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "توم توغرا بەلگىسى" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x شەكىللىك تۈر بەلگىسى" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "يۇقىرىقى 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "يۇقىرىقى 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "يۇقىرىقى 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "يۇقىرىقى 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "يۇقىرىقى7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "يۇقىرىقى 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "يۇقىرىقى 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "يۇقىرىقى پىلۇس" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "يۇقىرىقى مىنۇس" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "يۇقىرىقى تەڭلىك" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "يۇقىرىقى سول تىرناق" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "يۇقىرىقى ئوڭ تىرناق" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "يۇقىرىقى n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "تۆۋەنكى 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "تۆۋەنكى 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "تۆۋەنكى 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "تۆۋەنكى 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "تۆۋەنكى 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "تۆۋەنكى 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "تۆۋەنكى 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "تۆۋەنكى 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "تۆۋەنكى 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "تۆۋەنكى 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "تۆۋەنكى پىلۇس" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "تۆۋەنكى مىنۇس" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "تۆۋەنكى تەڭلىك" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "تۆۋەنكى سول تىرناق" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "تۆۋەنكى ئوڭ تىرناق" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "ئىچى پۈتەي كۋادرات" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "ئىچى پۈتەي رومبا" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "كېيىنكى ھەرپكە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "ئىسترېلكىنى ھازىرقى تۈرگە يۆنەلدۈرىدۇ." - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "ھازىرقى تەكشى كۆرۈش تۈرىدە سول توپچىنى چېكىشنى ئورۇنلايدۇ." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "ھازىرقى تەكشى كۆرۈش تۈرىدە ئوڭ توپچىنى چېكىشنى ئورۇنلايدۇ." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "پۈتكۈل پۈتۈكنى ئوقۇت." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "تەكشى كۆرۈنۈشنى ئىشلەتمىگەن." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "نەدە مەشغۇلات قىلىشىمنى ئاددىي ئورۇندايدۇ." - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "نەدە مەشغۇلات قىلىشىمنى تەپسىلىي ئورۇندايدۇ." - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "ھازىرقى تەكشى كۆرۈش قۇرىنى سۆزلىتىدۇ." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "بوش قۇرلارنى سۆزلەت" - -#: src/cthulhu/cmdnames.py:101 -#, fuzzy -msgid "Present the default button" -msgstr "كېيىنكى توپچىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "ھالەت بالدىقىنى سۆزلىتىدۇ." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "ماۋزۇ بالدىقىنى سۆزلىتىدۇ." - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "«Cthulhu ئىزدەش كۆزنىكى» نى ئاچىدۇ." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "بىر تېكىستنىڭ كېيىنكى ئۈلگىسىنى ئىزدەيدۇ." - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "بىر تېكىستنىڭ ئالدىنقى ئۈلگىسىنى ئىزدەيدۇ." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "تەكشى كۆرۈش ھالىتىگە كىرىدۇ ۋە چېكىنىدۇ." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "تەكشى كۆرۈشنى ئاخىرقى ئورنىغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "تەكشى كۆرۈشنى دەسلەپكى ئورنىغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "تەكشى كۆرۈشنى ئاخىرقى ئورنىغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "تەكشى كۆرۈشنى ئالدىنقى قۇرنىڭ بېشىغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "ھازىرقى تەكشى كۆرۈش قۇرىنى سۆزلىتىدۇ." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "ھازىرقى تەكشى كۆرۈش قۇرىنى ھەجىلەيدۇ." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "ھازىرقى تەكشى كۆرۈش قۇرىنى فونېتىكىلىق تەلەپپۇز ئارقىلىق ھەجىلەيدۇ." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "تەكشى كۆرۈشنى كېيىنكى قۇرنىڭ بېشىغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "تەكشى كۆرۈشنى ئالدىنقى تۈر ياكى سۆزگە يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "ھازىرقى تەكشى كۆرىدىغان تۈر ياكى سۆزنى سۆزلىتىدۇ." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "ھازىرقى تەكشى كۆرىدىغان تۈر ياكى سۆزنى ھەجىلەيدۇ." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"ھازىرقى تەكشى كۆرىدىغان تۈر ياكى سۆزنى فونېتىكىلىق تەلەپپۇز ئارقىلىق " -"ھەجىلەيدۇ." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "تەكشى كۆرۈشنى كېيىنكى تۈر ياكى سۆزگە يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "تەكشى كۆرۈشنى ھازىرقى سۆزنىڭ ئۈستىدىكى سۆزگە يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "ھازىرقى تەكشى كۆرىدىغان ئوبيېكتنى سۆزلىتىدۇ." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "تەكشى كۆرۈشنى ھازىرقى سۆزنىڭ ئاستىدىكى سۆزگە يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "تەكشى كۆرۈشنى ئالدىنقى ھەرپكە يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "ھازىرقى تەكشى كۆرىدىغان ھەرپنى سۆزلىتىدۇ." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "" -"ھازىرقى تەكشى كۆرىدىغان ھەرپنى فونېتىكىلىق تەلەپپۇز ئارقىلىق سۆزلىتىدۇ." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "ھازىرقى تەكشى كۆرىدىغان ھەرپنىڭ يۇنىكود قىممىتىنى سۆزلىتىدۇ." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "تەكشى كۆرۈشنى كېيىنكى ھەرپكە يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "تەكشى كۆرۈشنى قۇرنىڭ ئاخىرىغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "تەكشى كۆرۈشنى ئاستى سولغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "تەكشى كۆرۈشتىكى مەزمۇنلارنى چاپلاش تاختىسىغا كۆچۈرىدۇ." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "" -"تەكشى كۆرۈشتىكى مەزمۇنلارنى چاپلاش تاختىسىدىكى مەزمۇنلارنىڭ ئارقىسىغا قوشىدۇ." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "تەكشى كۆرۈشنى ئاخىرقى ئورنىغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "" -"ھازىرقى جەدۋەل كاتەكچىسى ياكى پۈتۈن قۇرنى ئوقۇش-ئوقۇماسلىقنى ئالماشتۇرىدۇ." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "ھازىرقى تېكىستكە مۇناسىۋەتلىك ھەرپلەرنىڭ خاسلىقلىرىنى ئوقۇيدۇ." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "ئەمالار يېزىقى كۆرسىتىشىنى سولغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "ئەمالار يېزىقى كۆرسىتىشىنى ئوڭغا يۆتكەيدۇ." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "ھەرپتاختا فوكۇسىنىڭ نەڭىگە قايتىدۇ." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "قىسىلغان ئەمالار يېزىقىنى ئاچىدۇ ۋە ياپىدۇ." - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "نۇربەلگە يۆنەلدۈرۈش كۇنۇپكىسىنى بىرتەرەپ قىلىدۇ." - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "تېكىست تاللاشنىڭ بېشىغا بەلگە سالىدۇ." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "تېكىست تاللاشنىڭ ئاخىرىغا بەلگە سالىدۇ." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "ئۆگىنىش ھالىتىگە كىرىدۇ. «ESC» بېسىپ ئۆگىنىش ھالىتىدىن چېكىنىڭ." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "تاۋۇش تېزلىكىنى تۆۋەنلىتىدۇ." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "تاۋۇش تېزلىكىنى ئاشۇرىدۇ." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "تاۋۇش ئاھاڭىنى تۆۋەنلىتىدۇ." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "تاۋۇش ئاھاڭىنى يۇقىرىلىتىدۇ." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "تاۋۇش تېزلىكىنى ئاشۇرىدۇ." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "تاۋۇش تېزلىكىنى تۆۋەنلىتىدۇ." - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "ماس تاۋۇش مۇلازىمېتىرنى تاللاڭ." - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "ماس تاۋۇش مۇلازىمېتىرنى تاللاڭ." - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "تاۋۇش تېزلىكىنى تۆۋەنلىتىدۇ." - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "تاۋۇش تېزلىكىنى ئاشۇرىدۇ." - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "ئاۋاز تىپى تەڭشىكى" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "تاۋۇش بىرىكتۈرۈشنى ئالماشتۇرىدۇ." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "چاشقىنەك كۆرۈش ھالىتىگە ئالماشتۇر." - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "Cthulhu ئېكران ئوقۇغۇ" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "مايىللىقىنى سەپلەش سۆزلەشكۈسىنى كۆرسىتىدۇ" - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "پروگرامما مايىللىقىنى سەپلەش سۆزلەشكۈسىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "تارتىلىش ۋە رەتلەشنى سۆزلىتىشنى ئالماشتۇرىدۇ." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "كېيىنكى تىنىش بەلگىسىنى ئوقۇش دەرىجىسىگە ئايلىنىپ بارىدۇ." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "كېيىنكى كۇنۇپكا ئەكس سادا دەرىجىسىگە ئايلىنىپ بارىدۇ." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "كېيىنكى تەڭشەك profile غا ئايلىنىپ بارىدۇ." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "كېيىنكى چوڭ ھەرپكە ئايلاندۇرۇشقا ئايلىنىپ بارىدۇ." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "كېيىنكى كۇنۇپكا ئەكس سادا دەرىجىسىگە ئايلىنىپ بارىدۇ." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "ئىجرا ۋاقتىدا سازلاش دەرىجىسىگە ئايلىنىپ بارىدۇ." - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "مەن دىققەت قىلغان ھازىرقى ئورۇننى خەتكۈش قىلىپ ساقلايدۇ." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "ئالدىنقى خەتكۈش ئورنىغا يۆتكەل." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "خەتكۈچكە يۆتكەل." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "كېيىنكى خەتكۈش ئورنىغا يۆتكەل." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "خەتكۈش قوشىدۇ." - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "خەتكۈچلەرنى ساقلا." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "چاشقىنەك كۆرۈش ھالىتىگە ئالماشتۇر." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "ھازىرقى ۋاقىت." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "ھازىرقى چېسلا." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "ھازىرقى پروگراممىغا كېيىنكى بۇيرۇقنى ئۆتكۈزىدۇ." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "ئالدىنقى چايخانا ئۇچۇرىنى ئوقۇت ۋە ئەمالار يېزىقى ئارقىلىق ئىپادىلە." - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "دوستلىرىمىز كىرگۈزۈۋاتقاندا ئۇقتۇرۇش قىلامدۇق ياقمۇ." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "قوزغالغاندا ئەڭ ئاخىرقى ئەڭگىمەنى ئاچما" - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "چايخانا ئۇچۇرى بىلەن چايخانا ئاتىنى قوشامدۇ يوق." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "سولغا يۆتكە" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "ئوڭغا يۆتكە" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "يۇقىرىغا يۆتكە" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "ئاستىغا يۆتكە" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "توڭلات" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "سول ئۈستى" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "سول ئاستى" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "نۇربەلگە ئورنى" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "ئالتە نۇقتا" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "نۇربەلگە يېتەكلەش" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "كېسىشنى باشلا" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "قۇرنى كەس" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "ئاخىرقى ئۇقتۇرۇش ئۇچۇرى." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "ئۇقتۇرۇش ئۇچۇرلىرى تىزىمى" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "ئالدىنقى ئۇقتۇرۇش ئۇچۇرى." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "ئاخىرقى ئۇقتۇرۇش ئۇچۇرى." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "كېيىنكى ھەرپكە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "ئالدىنقى ھەرپكە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "كېيىنكى سۆزگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "ئالدىنقى سۆزگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "كېيىنكى قۇرغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "ئالدىنقى قۇرغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "ھۆججەت چوقىسىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "ھۆججەت ئاخىرىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "قۇر بېشىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "قۇر ئاخىرىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "كېيىنكى نەڭگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "ئالدىنقى نەڭ يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "ھازىرقى تاللاش-تىزىمى كېڭەيتىلىدۇ." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Gecko يەرلىك ۋە Cthulhu نۇر نۇقتىسى ئارىسىدىكى يول باشلاشنى ئالماشتۇرىدۇ." - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "تۇرىدىغان رايون ئەدەپلىك تەڭشىكىنى يۇقىرىلات." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "تۇرىدىغان رايون ئەدەپلىك دەرىجىسىنى تاقاققا تەڭشە." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "تۇرىدىغان رايون ئۇقتۇرۇش كۆرسەت" - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "تۇرىدىغان رايونلارنى كۆزەت" - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "فوكۇسنى ھازىرقى چاشقىنەكنىڭ ئاستىغا يۆتكەيدۇ ۋە قايتۇرىدۇ." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "قۇرنى ھەرىكەتچان ئىستون قېشى قىلىپ تەڭشەيدۇ." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "ھەرىكەتچان ئىستون قاشلىرىنى تازىلايدۇ." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "ئىستوننى ھەرىكەتچان قۇر قېشى قىلىپ تەڭشەيدۇ." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "ھەرىكەتچان قۇر قاشلىرىنى تازىلايدۇ" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "كىرگۈزۈش قۇرىنىڭ مەزمۇنلىرىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "قۇرۇلما يولباشچى كۇنۇپكىسىنى ئالماشتۇر." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "ئالدىنقى بۆلەك-نەقىلگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "كېيىنكى بۆلەك-نەقىلگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:852 -#, fuzzy -msgid "Display a list of blockquotes" -msgstr "بۆلەك-نەقىل تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "ئالدىنقى توپچىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "كېيىنكى توپچىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "توپچىلار تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "ئالدىنقى تاللاش رامكىسىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "كېيىنكى تاللاش رامكىسىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:870 -#, fuzzy -msgid "Display a list of check boxes" -msgstr "تاللاش رامكىسى تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "ئالدىنقى جەدۋەلگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "كېيىنكى جەدۋەلگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "جەدۋەللەرنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "ئالدىنقى تاللاش-تىزىمىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "كېيىنكى تاللاش-تىزىمىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "h t m l قاچىسى" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "h t m l قاچىسى" - -#: src/cthulhu/cmdnames.py:901 -#, fuzzy -msgid "Display a list of combo boxes" -msgstr "تاللاش-تىزىم رامكىسىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "ئالدىنقى كىرگۈگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "كېيىنكى كىرگۈگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "كىرگۈلەر تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "ئالدىنقى فورما دائىرىسىگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "كېيىنكى فورما دائىرىسىگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:919 -#, fuzzy -msgid "Display a list of form fields" -msgstr "فورما خەت بۆلەكلىرىنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "ئالدىنقى ماۋزۇغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "كېيىنكى ماۋزۇغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "ماۋزۇلارنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "%d دەرىجىدىكى ئالدىنقى ماۋزۇغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "%d دەرىجىدىكى كېيىنكى ماۋزۇغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "%d دەرىجىدىكى ماۋزۇلارنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "ئالدىنقى جەدۋەلگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "ئىچكى كۆزنەك" - -#: src/cthulhu/cmdnames.py:949 -#, fuzzy -msgid "Display a list of internal frames" -msgstr "جەدۋەللەرنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "ئالدىنقى قۇرغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "كېيىنكى قۇرغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "جەدۋەللەرنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "ئالدىنقى مۇساپە بەلگىسىگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "كېيىنكى مۇساپە بەلگىسىگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "ئۇلانمىلارنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "ئالدىنقى چوڭ نەڭگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "كېيىنكى چوڭ نەڭگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "چوڭ نەڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "ئالدىنقى قۇرغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "كېيىنكى قۇرغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "ئۇلانمىلارنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "ئالدىنقى تىزىمغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "كېيىنكى تىزىمغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1006 -#, fuzzy -msgid "Display a list of lists" -msgstr "تىزىملارنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "ئالدىنقى تىزىم تۈرىگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "كېيىنكى تىزىم تۈرىگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "تىزىمنىڭ ئەزالىرىنى(item) تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "ئالدىنقى تۇرىدىغان رايونغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "كېيىنكى تۇرىدىغان رايونغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "ئاخىرقى ئېلان قىلىنغان تۇرىدىغان رايونغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1034 -#, fuzzy -msgid "Go to the parent of the object with navigator focus." -msgstr "فوكۇسلۇق ئوبيېكتنىڭ ئەجدادى ھەققىدە سازلاش ئۇچۇرىنى بېسىپ چىقىرىدۇ." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "ھەرپتاختا فوكۇسىنىڭ نەڭىگە قايتىدۇ." - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "قۇرۇلما يولباشچى كۇنۇپكىسىنى ئالماشتۇر." - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "ئالدىنقى ئابزاس‏قا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "كېيىنكى ئابزاس‏قا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "ئابزاس‏لارنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "ئالدىنقى تاللاش توپچىسىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "كېيىنكى تاللاش توپچىسىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "تاللاش توپچىسىنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "ئالدىنقى ئايرىش بەلگىسىگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "كېيىنكى ئايرىش بەلگىسىگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "ئالدىنقى جەدۋەلگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "كېيىنكى جەدۋەلگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "جەدۋەللەرنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "بىر كاتەك ئاستىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "جەدۋەلدىكى دەسلەپكى كاتەككە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "جەدۋەلدىكى ئاخىرقى كاتەككە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "بىر كاتەك سولغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "بىر كاتەك ئوڭغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "بىر كاتەك ئۈستىگە يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "چاشقىنەك كۆرۈش ھالىتىگە ئالماشتۇر." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "كۇنۇپكا ئەكس سادانى قوزغات(_K)" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "زىيارەت قىلىنمىغان ئالدىنقى ئۇلانمىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "زىيارەت قىلىنمىغان كېيىنكى ئۇلانمىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "زىيارەت قىلىنمىغان ئۇلانمىلارنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "زىيارەت قىلىنغان ئالدىنقى ئۇلانمىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "زىيارەت قىلىنغان كېيىنكى ئۇلانمىغا يۆتكىلىدۇ." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "زىيارەت قىلىنغان ئۇلانمىلارنىڭ تىزىمىنى كۆرسىتىدۇ." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "توق كۆك" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "قارا" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "ئىچى پۈتەي رومبا" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "توق كۆك" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "توق كۆك" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "à" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "توق يېشىل" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "توق يېشىل" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "توق قىزىل" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "توق يېشىل" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "توق كۆك" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "ì" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "ئاچ يېشىل" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "كۈل رەڭ قىلىندى" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "گرادۇس" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "ھىندىچە بىرىنچى دەرىجە" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "سول چوڭ تىرناق" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "ئوڭ Control كۇنۇپكىسى" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "ئوڭ چوڭ تىرناق" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "سول چوڭ تىرناق" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "ئوڭ چوڭ تىرناق" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "ئوڭ چوڭ تىرناق" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "ئوڭ Alt كۇنۇپكىسى" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "ئوڭ چوڭ تىرناق" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "ئوڭ super" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "ئوڭ يا ئوق" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "يېڭى قۇر" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "سۈرەت" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "ئاچ كۆك" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "توق قىزىل" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "توق يېشىل" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "tre" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "توق كۆك" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "%s ئېكران" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "ئاچ كۆك" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "ئاچ كۆك" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "btn" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "ئاق بوشلۇق" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "ئاق بوشلۇق" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "پۈتۈن ئېكران" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "ئاكتىپلا(_A)" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "چېكىت_7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "چېكىت_8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "چېكىت 7 ۋە 8 (_D)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "سىنبەلگە" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "يوق" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "ئىملا" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "دوستلىرىڭىز كىرگۈزۈۋاتقاندا ئۇقتۇرسۇن(_B)" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "چايخانا ئالاھىدە ئۇچۇر خاتىرىلىرىنى تەمىنلە(_M)" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "كەلگەن ئۇچۇرلارنى ئوقۇت" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "بارلىق قاناللار(_N)" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "خالىغان بىر %s كۆزنەك ھەرىكەتچان بولسا بارلىق قانال(_Y)" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "كۆزنىكى ھەرىكەتچان بولسا بىرلا قانال(_W)" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "چايخانا ئاتىنى ئوقۇت(_S)" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "قوش چەك" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "ئۇچ چېكىش" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "كۆڭۈلدىكى بىرىكتۈرگۈچ" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "ھازىرقى تېكىست" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "ئالمىشىدىغان تېكىست" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "ئەكس سادانى ھەرپ-بەلگە قوزغاتسۇن(_R)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "بوشلۇقسىز پەرقلەندۈرۈش كۇنۇپكىلىرىنى قوزغات(_D)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "ھازىرقى ئورۇن(_U)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "ماس كەلگەن تېكىستنىڭ ئەڭ كىچىك ئۇزۇنلۇقى:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "ئىزدە تاللانمىلىرى" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "ئىزدەۋاتقاندا ئۆزگەرتكەن قۇرلارنىلا سۆزلەت(_Y)" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "ئىزدەۋاتقاندا نەتىجىلەرنى سۆزلەت" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "پەش" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "كۇنۇپكا باغى" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "كۆڭۈلدىكى" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "يېزىش ھالىتى" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "دائىرە" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "ئەمالار يېزىقى باغلىرى" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "خەتكۈچلەرنى ساقلا." - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "ۋاقىت ۋە چېسلا" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "جەدۋەل يولباشچىسى" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "باغسىزلا" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "تەكشى كۆرۈشتىن ئايرىلىۋاتىدۇ." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "ئۆزگەرتىلگەن ۋاقتى" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "ئۈستەلئۈستى(_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "ئۇقتۇرۇش" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "ئۇقتۇرۇش %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s ئۈچۈن Cthulhu مايىللىقى" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "braille ئىچىدە بەلگە قوي" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "يوشۇرۇن شەرت" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "سۆزلەش" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "سەپلىمە ھۆججەتنى توقۇنۇشقان بويىچە ساقلا" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "ئىشلەتكۈچى Profile دا توقۇنۇش يۈز بەردى" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"سەپلىمە ھۆججەت %s ئاللىبۇرۇن مەۋجۇت.\n" -"يېڭى ئۆزگەرتىلگەن سەپلىمە ھۆججەتنى يېڭىلاشنى داۋاملاشتۇرامسىز؟" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "ئىشلەتكۈچى سەپلىمە ھۆججىتىنى يۈكلە" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"سىز پائالىيەت سەپلىمە ھۆججىتىنى ئۆزگەرتمەكچى.\n" -"ئەگەر بايىلا مايىللىقىڭىزنى ئۆزگەرتكەن بولسىڭىز، سەپلىمە ھۆججەت يۈكلەنگەندە " -"تاشلىۋېتىدۇ.\n" -"\n" -"سەپلىمە ھۆججەتنى يۈكلەشنى داۋاملاشتۇرۇپ ئالدىنقى ئۆزگەرتىشلەرنى تاشلىۋېتەمدۇ؟" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "باشقا ئاتتا ساقلا" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "سەپلىمە ھۆججەت ئاتى(_P):" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "ئىشلەتكۈچى سەپلىمە ھۆججىتىنى يۈكلە" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "ھەممىسى" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "پروگرامما" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "كۆزنەك" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "يوق(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "بەزى(_M)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "كۆپىنچە(_O)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "قۇر" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "جۈملە" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "بۆلەك-نەقىل" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "توپچا" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "ماۋزۇ" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "تاللاش رامكىسى" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "بىرىكمە رامكا" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "چۈشەندۈرۈش" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "ماۋزۇ" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "ئىچكى كۆزنەك" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "سۈرەت" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "ئەن" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "سودا ماركىسى" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "دەرىجە" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "ئۇلانما" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "تىزىم" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "تىزىم ئەزايى" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "نەڭ" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "ئابزاس" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "تاق تاللاش كۇنۇپكىسى" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "رول" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "تاللانغان تۈر" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "ھالەت" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "تېكىست" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "قىممەت" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "بۆلەك-نەقىللەر" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "توپچىلار" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "تاللاش رامكىلىرى" - -#: src/cthulhu/guilabels.py:706 -#, fuzzy -msgctxt "structural navigation" -msgid "Clickables" -msgstr "جەدۋەللەر" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "تاللاش-تىزىم رامكىلىرى" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "تۈرلەر" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "فورما خەت بۆلەكلىرى" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "ماۋزۇلار" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "ئىچكى كۆزنەك" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "سۈرەت" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "%d دەرىجىدىكى ماۋزۇ" - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "سودا ماركىسى" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "چوڭ نەڭلەر" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "ئۇلانمىلار" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "تىزىملار" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "تىزىم ئەزالىرى" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "ئابزاس‏لار" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "تاللاش توپچىلىرى" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "جەدۋەللەر" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "زىيارەت قىلىنمىغان ئۇلانمىلار" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "زىيارەت قىلىنغان ئۇلانمىلار" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "بەت يولباشچىسى" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "بىر بەت دەسلەپ يۈكلەنگەندە ئاپتوماتىك سۆزلەشنى باشلا(_L)" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "بىر بەت دەسلەپ يۈكلەنگەندە ئاپتوماتىك سۆزلەشنى باشلا(_L)" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "تىنىۋېلىش ئارىلىقىدىكى تاۋۇشنى يېرىپ بۆلەككە بۆل(_U)" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s كۆڭۈلدىكى ئۈن" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "كۆڭۈلدىكى" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "ئۇلانما" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "سىستېما" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "چوڭ يېزىلىش" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "تاۋۇش پېرېداتچىك" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "ئېلېكترونلۇق جەدۋەل كاتەك كوئوردېناتلىرىنى سۆزلەت" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "كاتەك قېشىنى ئۇقتۇر" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "جەدۋەل يولباشچىسى" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "بوش كاتەكلەردىن ئاتلا(_B)" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "كاتەكنى سۆزلەت" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "كاتەك كوئوردېناتلىرىنى سۆزلەت(_C)" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "كۆپ كاتەكلەرنى سۆزلەت(_M)" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "خاسلىق ئاتى" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "Cthulhu نۇر نۇقتىسى يولباشچىسىنى قوللان(_O)" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "قۇرۇلما يولباشچى كۇنۇپكىسىنى ئالماشتۇر." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "قىسقا(_F)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "ئۇقتۇرۇش" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "تىزگىن" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "سول Shift كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "سول Alt كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ئوڭ Control كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "ئوڭ Shift كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "ئوڭ Alt كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "ئوڭ Control كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "سول meta كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "ئوڭ meta كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "سول tab كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter كۇنۇپكىسى" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "ئۈستىگە" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "ئاستى" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "سول" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "ئوڭ" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "سول super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "ئوڭ super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "تىزىملىك" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "ياردەم" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "كۆپ" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "شەكىل ئالماشتۇر" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "Esc" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "قىستۇر" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "ئۆچۈر" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "باش بەت" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "باشلا" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "سوزۇش بەلگىسى" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "قوڭغۇراق" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "سائەت ئاۋازى" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "مىنۇس" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "قىستۇر" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "توم" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "يانتۇ" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr " تۆۋەنكى %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr " تۆۋەنكى %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "خىزمەت بوشلۇقى " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "كونتېكىست %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "سول يا ئوق" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "يا ئوق" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "ئوڭ يا ئوق" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "يا ئوق" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "ئوڭ يا ئوق" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "ئوڭ يا ئوق" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "ئوڭ يا ئوق" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "سول يا ئوق" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "سول يا ئوق" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "ئوڭ يا ئوق" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "سول قوش پەش" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "قوش ئىسترېلكا" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "ئوڭ قوش پەش" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "قوش ئىسترېلكا" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "ئوڭ قوش پەش" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "ئوڭ يۆنىلىش ئىسترېلكىسى" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "ئوڭ يۆنىلىش ئىسترېلكىسى بېشى" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "مىنۇس" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "كىچىك" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "چوڭ" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "سوزۇش بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "چېكىت" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "تىك يۆنىلىشتە رەتلە" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "توغرىسىغا" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "ئۆزلۈكىدىن تاماملا" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "بوش" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "ئىناۋەتلىك قىلىنغان" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "قۇر ئاخىرى." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "تۆۋەن" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "پىلۇس ۋە مىنۇس" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "پىلۇس" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "مىنۇس" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "ئايرىغۇچ" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "كۇب يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "ئوڭ تاناسىپ" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "چەكسىز" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "ئوڭ Alt كۇنۇپكىسى" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "يەككە" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "قەۋەتلىك پەنجىرە" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "تىك يۆنىلىشتە رەتلە" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "بۆلۈش بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "ئايرىغۇچ" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "تەڭ ئەمەس" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "لوگىكىلىق ياق بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "لوگىكىلىق ياق بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "يۆنىلىش" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "ئىچكى كۆزنەك" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "قوش پەش" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "ئوڭ تاناسىپ" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "مىنۇس" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "سوزۇش بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "ñ" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "ñ" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "تەخمىنىي" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "تەخمىنىي" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "تەخمىنىي" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "تەخمىنىي" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "تەخمىنىي" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "تەخمىنىي" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "ئۇچ چېكىش" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "تەخمىنىي" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "باشقا جاي" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "تەڭ ئەمەس" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "تەڭلىك" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "تەڭلىك" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "تەڭ ئەمەس" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "تەڭ ئەمەس" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "ئۈچبۇلۇڭ تۈر بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "تەڭلىك" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "تەڭ ئەمەس" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "تەڭ ئەمەس" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "بويىغا" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "تەڭ ئەمەس" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "تەڭ ئەمەس" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "چوڭ" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "بېسىقسىز" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "تۆۋەنكى 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "ئۈستىدىكى a" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "كۆپ-تاللاش" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "تەڭشىمە" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "كۆپ-تاللاش" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "تۆۋەنكى تەڭلىك" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "سىزىقچە" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "تۆۋەنكى پىلۇس" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "تۆۋەنكى مىنۇس" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "ئوڭ meta كۇنۇپكىسى" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "سول tab كۇنۇپكىسى" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "ئاستى" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "دائىرە" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "راست" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "راست" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "تەرتىپ" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "سۈرەت" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "كۆپ" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "ئىچكى كۆزنەك" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "نورمال" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "ئوڭ تاق پەش" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "سول چوڭ تىرناق" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "ئايرىغۇچ" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "لوگىكىلىق ياق بەلگىسى" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "لوگىكىلىق ياق بەلگىسى" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "قوش پەش" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "قوش پەش" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "يۆنىلىش" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "قوش پەش" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "كىچىك ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "چوڭ ياكى تەڭ" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "تىك يۆنىلىشتە رەتلە" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "سول چوڭ تىرناق" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "ئوڭ چوڭ تىرناق" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "سول Alt كۇنۇپكىسى" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "ئوڭ Alt كۇنۇپكىسى" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "ئوڭ قوش تىرناق" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "ئاستى" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "سول قوش تىرناق" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "ئوڭ قوش تىرناق" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "ئوتتۇرا نۇقتا" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "ئىزدەش يۆنىلىشى:" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "ئىچى پۈتەي كۋادرات" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "ئىچى بوش كۋادرات" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "ئىچى پۈتەي رومبا" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "ئىچى بوش چەمبەر" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "ئىچى پۈتەي چەمبەر" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "ئىچى بوش تۈر بەلگىسى" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "ئىچى پۈتەي كۋادرات" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "ئاستى سىزىق" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "تىك يۆنىلىشتە رەتلە" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "پروگرامما" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "بوشلۇق" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "توم" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "خەتكۈش كىرگۈزۈلدى" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "خەتكۈچلەر ساقلاندى" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "خەتكۈچلەرنى ساقلىيالمىدى" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "مۇساپە بەلگىسى تېپىلمىدى." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "مۇساپە بەلگىسى تېپىلمىدى." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "ئايلىنىپ ئۆتۈش ھالىتى قوزغىتىلدى." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "ھېسابلىغۇچنى كۆرسىتىشكە ئېرىشەلمىدى" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "سىنبەلگە" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "چوڭ ھەرپكە ئايلاندۇرۇش ئۇسلۇبىنى «سىنبەلگە» گە تەڭشەيدۇ." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "يوق" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "چوڭ ھەرپكە ئايلاندۇرۇش ئۇسلۇبىنى «يوق» قا تەڭشەيدۇ." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "ئىملا" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "چوڭ ھەرپكە ئايلاندۇرۇش ئۇسلۇبىنى «ئىملا» غا تەڭشەيدۇ." - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "Gecko نۇر نۇقتىسىنى تىزگىنلەۋاتىدۇ." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu نۇربەلگىسىنى تىزگىنلەۋاتىدۇ." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "%s كاتەكچىسى" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "تاللانغان" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "تاللانمىغان" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "تاللانمىنى قوللىنىشنى چەكلە" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "تاللاشنى قوللىنىشنى زورلا" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPTION" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "تۆۋەندىكىلەر ئىناۋەتسىز: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "ئىجرا قىلىنىۋاتقان پروگراممىلارنى باس." - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "profile نى ئوقۇ" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Profile نى ئوقۇغىلى بولمىدى: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "ئۈستەلئۈستىگە باغلىنالمىغانلىقتىن Cthulhu نى قوزغاتقىلى بولمىدى." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -#, fuzzy -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"بۇ ئەڭگىمەدە باشقا بىر Cthulhu ئىجراسى بار.\n" -"كونىسىنى يېڭىسىغا ئالماشتۇرۇش ئۈچۈن «cthulhu --replace» بۇيرۇقىنى ئىجرا " -"قىلىڭ." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "ئىشلەتكۈچى مايىللىقى ئۈچۈن زاپاس مۇندەرىجىنى قوللان" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "ئىجرا قىلىنىۋاتقان پروگراممىلارنى باس." - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "ئىجرا قىلىنىۋاتقان Cthulhu نى ئالماشتۇر" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "بۇ ياردەم ئۇچۇرىنى كۆرسەت" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "سىناق چىقىرىشىنى debug-YYYY-MM-DD-HH:MM:SS.out گە يوللا" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "سىناق چىقىرىشىنى بەلگىلەنگەن ھۆججەتكە يوللا" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FILE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "ئىشلەتكۈچى مايىللىقلىرىنى(تېكىست نۇسخىسى) تەڭشە" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "ئىشلەتكۈچى مايىللىقلىرىنى(تېكىست نۇسخىسى) تەڭشە" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "كەمتۈكلەرنى https://groups.io/g/stormux غا مەلۇم قىلىڭ." - -#: src/cthulhu/messages.py:325 -#, fuzzy -msgid "Cut selection to clipboard." -msgstr "چاپلاش تاختىسىدىكى كۆچۈرۈلگەن مەزمۇنلار" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "ئۇرغۇلۇق" - -#: src/cthulhu/messages.py:337 -#, fuzzy -msgid "Copied selection to clipboard." -msgstr "چاپلاش تاختىسىدىكى كۆچۈرۈلگەن مەزمۇنلار" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -#, fuzzy -msgid "Pasted contents from clipboard." -msgstr "چاپلاش تاختىسىدىكى كۆچۈرۈلگەن مەزمۇنلار" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "تېزرەك." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "دوستلىرىڭىز كىرگۈزۈۋاتقاندا ئۇقتۇرمىسۇن." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "دوستلىرىڭىز كىرگۈزۈۋاتقاندا ئۇقتۇرسۇن." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "چايخانا %s دىن كەلگەن ئۇچۇر" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "يېڭى سۆھبەت بەتكۈچى %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "چايخانا ئاتىنى ئوقۇتما." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "چايخانا ئاتىنى ئوقۇت." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "قوزغالغاندا ئەڭ ئاخىرقى ئەڭگىمەنى ئاچما" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "چايخانا ئالاھىدە ئۇچۇر خاتىرىلىرىنى تەمىنلە." - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "تاللاش كۆرسەتكۈچى" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "ئۆچۈر" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "قىستۇر" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "سوئال" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "جەدۋەل ئاخىرى" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "جەدۋەلدە يوق" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "تاللانمىدى" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "كۆڭۈلدىكى توپا %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "كۆڭۈلدىكى توپا %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "كۆڭۈلدىكى توپا %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " تۆۋەنكى %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " يۇقىرىقى %s" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "جەدۋەلدە يوق" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "پۈتكۈل پۈتۈك تاللاندى" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "پۈتكۈل پۈتۈك تاللاندى" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "نۇربەلگىسى تۇرغان ئورۇندىن باشلاپ تاللانغان پۈتۈك" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "نۇربەلگىسى تۇرغان ئورۇندىن باشلاپ تاللانمىغان پۈتۈك" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "نۇربەلگە ئورنىغىچە تاللانغان پۈتۈك" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "نۇربەلگە ئورنىغىچە تاللانمىغان پۈتۈك" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "قۇر %d نىڭ دىنامىكىلىق ئىستون قېشى بەلگىلەندى" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "دىنامىكىلىق ئىستون قېشى تازىلاندى." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "ئىستون %s نىڭ دىنامىكىلىق قۇر قېشى بەلگىلەندى" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "دىنامىكىلىق قۇر قېشى تازىلاندى." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "بوش" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f كىلوبايت" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f مېگابايت" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "ھۆججەتلەر تېپىلمىدى." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "چاپلاش تاختىسىنىڭ ئارقىسىغا قوشۇلغان مەزمۇنلار." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "چاپلاش تاختىسىدىكى كۆچۈرۈلگەن مەزمۇنلار" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "تەكشى كۆرۈنۈشنى ئىشلەتمىگەن." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "تەكشى كۆرۈشكە كىرىۋاتىدۇ." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "تەكشى كۆرۈشتىن ئايرىلىۋاتىدۇ." - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "تەكشى كۆرۈشنى ھازىرقى سۆزنىڭ ئۈستىدىكى سۆزگە يۆتكەيدۇ." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "فورمۇلا" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "سۆزلەشكۈ" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "قاڭقىش تىزىملىكى" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "رەسىم خەرىتىسى ئۇلانمىسى" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "كىرگۈزگەن كۇنۇپكا ئاللىبۇرۇن %s گە باغلانغان" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "كۇنۇپكا تۇتۇلدى:%s. جەزملەش ئۈچۈن enter نى بېسىڭ." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "يېڭى كۇنۇپكا: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "ئاچقۇچ بېغى ئۆچۈرۈلدى. enter كۇنۇپكىسىنى بېسىپ جەزملەڭ." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "كۇنۇپكا بېغى چىقىرىۋېتىلدى." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "يېڭى ئاچقۇچ كىرگۈزۈڭ" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "ئاچقۇچ" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "كۇنۇپكا ئەكس سادانى كۇنۇپكىغا بەلگىلە." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "يوق" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "كۇنۇپكا ئەكس سادانى يوق قىلىپ بەلگىلە." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "كۇنۇپكا ۋە سۆز" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "كۇنۇپكا ئەكس سادانى كۇنۇپكا ۋە سۆزگە بەلگىلە." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "جۈملە" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "كۇنۇپكا ئەكس سادانى جۈملىگە بەلگىلە." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "سۆز" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "كۇنۇپكا ئەكس سادانى سۆزگە بەلگىلە." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "سوز ۋە جۈملە" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "كۇنۇپكا ئەكس سادانى سۆز ۋە جۈملىگە بەلگىلە." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "ئىچى پۈتەي چەمبەر" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "توغرىسىغا" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "تىك بالداق" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "ئوڭ يا ئوق" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "ئاستىغا سىيرىلىۋاتىدۇ." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "قۇر كەڭلىكى" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "ۋە" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "ئۈستى سىزىق" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "يىلتىز بەلگىسى" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "كۇب يىلتىز بەلگىسى" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "يىلتىز پەنجىرە" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "يىلتىز پەنجىرە" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "يىلتىز پەنجىرە" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "تۆۋەنكى 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "ئۈستىدىكى a" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "تۆۋەنكى 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "ئۈستىدىكى a" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "ئۈستىدىكى a" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "ئۈستىدىكى a" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "جەدۋەل" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "شاخسىمان جەدۋەل" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "زىيارەت قىلغىلى بولمىدى" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "ئىناۋەتسىز قىلىنغان" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "تارتىلىش ۋە رەتلەشنى سۆزلىتىش تاقالدى." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "ئىناۋەتلىك قىلىنغان" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "تارتىلىش ۋە رەتلەشنى سۆزلىتىش قوزغىتىلدى." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "ئۆگىنىش ھالىتى. «ESC» بېسىلسا ئاخىرلىشىدۇ." - -#: src/cthulhu/messages.py:1201 -#, fuzzy -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"ئۆگىنىش ھالىتىگە كىرىۋاتىدۇ. خالىغان كۇنۇپكىنى بېسىپ ئۇنىڭ ئىقتىدارىنى " -"ئاڭلاڭ. Cthulhu نىڭ كۆڭۈلدىكى تېزلەتمىلىرىگە ئېرىشىش ئۈچۈن 1 نى بېسىڭ. " -"نۆۋەتتىكى پروگراممىدىكى Cthulhu نىڭ تېزلەتمىلىرىگە ئېرىشىش ئۈچۈن 2 نى بېسىڭ. " -"Cthulhu نىڭ قوللانمىلىرىنى كۆرۈش ئۈچۈن F1 نى بېسىڭ. ئۆگىنىش ھالىتىنى " -"ئاخىرلاشتۇرۇش ئۈچۈن ESC نى بېسىڭ." - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "جانلاندۇرۇم" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "بەت يولباشچىسى" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "جەدۋەل يولباشچىسى" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "تەكشى كۆرۈشتىن ئايرىلىۋاتىدۇ." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "ئايرىلىش جەدۋىلى" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "نۇربەلگىسى ئورنىدىن ئاستىغا تاللانغان قۇر" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "نۇربەلگىسى ئورنىدىن يۇقىرىغا تاللانغان قۇر" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "نۇربەلگىسى ئورنىدىن ئاستىغا تاللانمىغان قۇر" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "نۇربەلگىسى ئورنىدىن يۇقىرىغا تاللانمىغان قۇر" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "ئۆگىنىش ھالىتىنى ئاخىرلاشتۇرۇۋاتىدۇ." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "بېشىدىن نۇربەلگىسى تۇرغان ئورۇنغىچە تاللانغان قۇر" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "نۇربەلگىسى تۇرغان ئورۇندىن ئاخىرىغىچە تاللانغان قۇر" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "ئۇلانما" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "ئوخشاش بەت" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "ئوخشاش تورتۇرا" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "باشقا جاي" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s دېگىنى %(file)s غا ئۇلانما قىلىنغان" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s ئۇلانما" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d زىيارەت قىلىنغان ئۇلانما" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"يۇقىرىغا ۋە تۆۋەنگە ئىسترېلكىسىنى ئىشلىتىپ تىزىشنى يېتەكلەڭ. Escape نى " -"بېسىپ چېكىنىڭ." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "بارلىق تۇرىدىغان رايونلارنى تاقاق قىلىپ تەڭشە" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "تۇرىدىغان رايون ئەدەپلىك دەرىجىلىرى ئەسلىگە قايتۇرۇلدى" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "ئەدەپلىك دەرىجىسى %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "تۇرىدىغان رايوننى ئىشەنچكە تەڭشەۋاتىدۇ" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "تۇرىدىغان رايوننى تاقاق قىلىپ تەڭشەۋاتىدۇ" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "تۇرىدىغان رايوننى ئەدەپلىككە تەڭشەۋاتىدۇ" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "تۇرىدىغان رايوننى قوپالغا تەڭشەۋاتىدۇ" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "تۇرىدىغان رايونلارنى كۆزىتىش يېپىق" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "تۇرىدىغان رايونلارنى كۆزىتىش ئوچۇق" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "تۇرىدىغان رايون ئۇچۇرى ساقلانمىدى" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "تۇرىدىغان رايون دەستىكى يېپىق" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "تېپىلمىدى" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "ھازىرقى ئورۇننى تاپالمىدى." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "چەكلە" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "قوزغات" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "ئىملاسى خاتا" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "ئىملاسى خاتا سوز: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "كونتېكىست %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -#, fuzzy -msgid "Focus mode" -msgstr "تېزلەتمە كۆرسىتىش ھالىتى." - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -#, fuzzy -msgid "Layout mode." -msgstr "تېزلەتمە كۆرسىتىش ھالىتى." - -#: src/cthulhu/messages.py:1785 -#, fuzzy -msgid "Object mode." -msgstr "نەڭ" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "كېيىنكى نەڭگە يۆتكىلىدۇ." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "چاشقىنەك ئاستىدىكى ئوبيېكت تېپىلمىدى." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "چاشقىنەك كۈچەيتمىلىرى تاقاق." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "چاشقىنەك كۈچەيتمىلىرى ئوچۇق." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "خاتالىق: نەڭلەر تىزىمىنى قۇرغىلى بولمىدى." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d پىرسەنت." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "ئالدىنقى سۆزگە يۆتكىلىدۇ." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "گىرەلەشمە دەرىجە %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "يېڭى تۈر قوشۇلدى" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "پروگرامما فوكۇسلانمىدى." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "فوكۇس يوق" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "پروگرامما فوكۇسلانمىدى." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "باشقا بۆلەك-نەقىل يوق." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "باشقا توپچا يوق." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "باشقا تاللاش رامكىسى يوق." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "باشقا چوڭ ئوبيېكت يوق." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "باشقا جەدۋەل يوق." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "باشقا تاللاش-تىزىمى يوق." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "باشقا كىرگۈ يوق." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "باشقا فورما دائىرىسى يوق." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "باشقا ماۋزۇ يوق." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "%d دەرىجىدىكى باشقا ماۋزۇ يوق." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "ئىچكى كۆزنەك" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "باشقا جەدۋەل يوق." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "مۇساپە بەلگىسى تېپىلمىدى." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "ئۇلانمىلار يوق." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "باشقا تىزىم يوق." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "باشقا تىزىم تۇرى يوق." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "باشقا تۇرىدىغان رايون يوق." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "باشقا ئابزاس‏ يوق." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "باشقا تاللاش توپچىسى يوق." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "باشقا ئايرىش بەلگىسى يوق." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "باشقا جەدۋەل يوق." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "باشقا زىيارەت قىلىنمىغان ئۇلانما يوق." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "باشقا زىيارەت قىلىنغان ئۇلانما يوق." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "تاللانمىدى" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "ئۇلانمىلار يوق." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "ئۇقتۇرۇش" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "ئاستى" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "ئۈستى" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "ئۇقتۇرۇش ئۇچۇرلىرى يوق" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "سۆز" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "يېزىلىشى ھەر خىل بولغان تېكىستنى بىر سۆز قىلىپ سۆزلەت(_D)" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "چەكلە" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "قوزغات" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "يۈكلەۋاتىدۇ. سەل ساقلاڭ." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "ئوقۇش تاماملاندى." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "%s نى ئوقۇش تاماملاندى." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "نۇربەلگىسى تۇرغان ئورۇندىن باشلاپ تاللانغان بەت" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "نۇربەلگىسى تۇرغان ئورۇنغىچە تاللانغان بەت" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "نۇربەلگىسى تۇرغان ئورۇندىن باشلاپ تاللانمىغان بەت" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "نۇربەلگىسى تۇرغان ئورۇنغىچە تاللانمىغان بەت" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "نۇربەلگىسى ئورنىدىن ئاستىغا تاللانغان پاراگراف" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "نۇربەلگىسى ئورنىدىن يۇقىرىغا تاللانغان پاراگراف" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "نۇربەلگىسى ئورنىدىن ئاستىغا تاللانمىغان پاراگراف" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "نۇربەلگىسى ئورنىدىن يۇقىرىغا تاللانمىغان پاراگراف" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"سىز ئاللىقاچان Cthulhu نىڭ مايىللىق سۆزلەشكۈسىنى ئېچىپ بولغان.\n" -"يېڭىنى ئېچىشتىن ئاۋۋال ئۇنى يېپىڭ." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "%(count)d دىكى %(position)d - تال" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Profile نى %s غا بەلگىلەيدۇ." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "profiles تېپىلمىدى." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "ئىلگىرىلەش بالدىقى %d" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "ھەممىسى" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "تىنىش بەلگىلىرى دەرىجىسىنى \"ھەممە\" گە تەڭشە." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "كۆپىنچە" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "تىنىش بەلگىلىرى دەرىجىسىنى \"كۆپىنچە\" گە تەڭشە." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "يوق" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "تىنىش بەلگىلىرى دەرىجىسىنى \"يوق\"قا تەڭشە." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "بەزى" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "تىنىش بەلگىلىرى دەرىجىسىنى \"بەزى\"گە تەڭشە." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "ئىزدەۋاتىدۇ." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "ئىزدەش تاماملاندى." - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "Cthulhu ئىشلەتكۈچى تەڭشەكلىرى قايتا ئوقۇلدى." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "تاللانغان تۈر" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "قۇر ئۆچۈرۈلدى." - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "تاللاش كۆرسەتكۈچى" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "تاللانمىغان" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "تاۋۇش ئىقتىدارى تاقاق." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "تاۋۇش ئىقتىدارى ئوچۇق." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "تېزرەك." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "ئاستىراق." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "يۇقىرىراق." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "تۆۋەنرەك." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "تېزرەك." - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "سۈرئەت(_R):" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "ئاۋاز چوڭلۇقى(_L)" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "تاۋۇش پېرېداتچىك" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "تاۋۇش پېرېداتچىك" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "مۇلازىمېتىر يوق.\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "ئۈن يوق.\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "تاۋۇش ئىقتىدارى ئوچۇق." - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "تاۋۇش ئىشلىتىلمەيدۇ.\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " چېكىت چېكىت چېكىت" - -#: src/cthulhu/messages.py:2326 -#, fuzzy -msgid "Cthulhu welcomes you." -msgstr "ئوركا(Cthulhu)نىڭ نەشرى %s." - -#: src/cthulhu/messages.py:2329 -#, fuzzy -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu نۇربەلگىسىنى تىزگىنلەۋاتىدۇ." - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "ئايلىنىپ ئۆتۈش ھالىتى قوزغىتىلدى." - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "تاۋۇشنى ئىشلەتكىلى بولمايدۇ." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "تېپىلمىدى" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "تېكىست تېپىلمىدى" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "تېكىست تېپىلمىدى" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "قۇرۇلما يولباشچى كۇنۇپكىسىنى ياپ." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "قۇرۇلما يولباشچى كۇنۇپكىسىنى ئاچ." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "تېپىلمىدى" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "قۇر %(row)d, ئىستون %(column)d" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "جەدۋەل ئاخىرى" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "كاتەكنى سۆزلەت" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "قۇرنى سۆزلەت" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "تەكشىسىز" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "جەدۋەلدە يوق" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "ئىستونلارنىڭ قايتا ئورۇنلاشتۇرۇلدى" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "قۇرلار قايتا ئورۇنلاشتۇرۇلدى" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "ئىستون %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "ئىستون %(index)d دىكى %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "ئىستون ئاخىرى." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "ئىستون چوقىسى." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "تاللانمىغان" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "تاللانمىغان" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "قۇر %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "قۇر %(index)d دىكى %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "قۇرنىڭ بەشى." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "قۇر ئاخىرى." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "قۇر ئۆچۈرۈلدى." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "ئاخىرقى قۇر ئۆچۈرۈلدى." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "قۇر قىستۇرۇلدى ." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "قۇر جەدۋەلنىڭ ئاخىرىغا قىستۇرۇلدى." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "قۇر ئۆچۈرۈلدى." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "تاللانمىغان" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "تاللانغان" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "تاللانمىغان" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H سائەت, %M مىنۇت ۋە %S سېكۇنت." - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H سائەت ۋە %M مىنۇت." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "يۇنىكود %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "ئوركا(Cthulhu)نىڭ نەشرى %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "ئاق بوشلۇق" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "ئاستىغا سىيرىلىۋاتىدۇ." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "چوققىغا سىيرىلىۋاتىدۇ." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 تۈر" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "كاتەك %d قۇرنى ئىگىلىدى" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d ئىستون" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "كاتەك %d ئىستوننى ئىگىلىدى" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d دانە ھەرپ بەك ئۇزۇن" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d سۆزلەشكۈ)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d دانە فوكۇسسىز سۆزلەشكۈ" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d بايت" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d ھۆججەت تېپىلدى" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d جەدۋەل" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d ماۋزۇ" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "‏‏%d تۈر" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "مۇساپە بەلگىسى تېپىلمىدى." - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d تۈر تېپىلدى" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "باشقا بۆلەك-نەقىل يوق." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "تەكشى كۆرۈشتىن ئايرىلىۋاتىدۇ." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d تۈر تىزىمى" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "%d تۈر تىزىمى" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "قىممەت" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "%d قۇرلۇق جەدۋەل" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d ئىستون" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "%d قۇرلۇق جەدۋەل" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d ئۇچۇر.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d پىرسەنت." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "پۈتۈكنىڭ %d پىرسەنتى ئوقۇلدى" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "چېكىت" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s ھەرپ" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d / %(total)d تۈر تاللاندى" - -#: src/cthulhu/messages.py:2793 -#, fuzzy, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d دانە Cthulhu كۆڭۈلدىكى تېزلەتمىسى تېپىلدى." - -#: src/cthulhu/messages.py:2801 -#, fuzzy, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "%(count)d Cthulhu تېزلەتمىسى (%(application)s نىڭ ) تېپىلدى." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d بوشلۇق" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tab بەلگىسى" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d جەدۋەل" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "%d قۇرلۇق جەدۋەل" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "%d قۇرلۇق جەدۋەل" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "%d قۇرلۇق جەدۋەل" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d زىيارەت قىلىنمىغان ئۇلانما" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d زىيارەت قىلىنغان ئۇلانما" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "ئالماشتۇر" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "%(index)d دىكى %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d / %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "LEVEL %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "شاخسىمان دەرىجە %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "شاخسىمان دەرىجە %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "سوئال" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "كېيىنكى تاللاش-تىزىمىغا يۆتكىلىدۇ." - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "html مەزمۇنى" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "سۆز" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "قوش چېكىت" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "ئۈستى سىزىق" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "يۆنىلىش" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "ئابزاس" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "سۆز" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "تارتىلىش" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "يۆنىلىش" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "بەتكۈچ تىزىمى" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "نەقىل" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "html مەزمۇنى" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s level %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "توغرىسىغا" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "تىك بالداق" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "توغرىسىغا" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "تىك يۆنىلىشتە رەتلە" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "توغرىسىغا" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "تىك يۆنىلىشتە رەتلە" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "شەكىل ئالماشتۇر" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "سىنبەلگە تاختىيى" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "html مەزمۇنى" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "جانلاندۇرۇم" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "html مەزمۇنى" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "جانلاندۇرۇم" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "ئىزدەۋاتىدۇ." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d زىيارەت قىلىنغان ئۇلانما" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "چىغ توپچا" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "قاتلانغان" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "يېيىلدى" - -#: src/cthulhu/object_properties.py:511 -#, fuzzy -msgid "has long description" -msgstr "چۈشەندۈرۈش" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "توغرىسىغا" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "بويىغا" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "تاللاقلىق" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "تاللاقسىز" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "قوزغات" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "چەكلە" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "قىسمەن تاللاقلىق" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "بېسىلغان" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "بېسىقسىز" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "تاللانمىدى" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "تاللانغان" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "تاللانمىدى" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "تاللانمىدى" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "كۆرۈلگەن" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "كۆرۈلمىگەن‏" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "كۈل رەڭ قىلىندى" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "ئوقۇشقىلا بولىدىغان" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "ئوقۇلىدىغانلا" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "تەلەپ" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "كۆپ-تاللاش" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "ئىناۋەتسىز" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "ئىناۋەتسىز" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "ھەجىلەش" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "ھەجىلەش" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "ئىناۋەتسىز" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "ئىزدە" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "ئېكران ئوقۇغۇچ" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "ياپ" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "ئىزدە" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "ئىزدە(_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "ئىزدە:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "كۆزنەك چوققىسى(_T):" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "كۆزنەك چوققىسى:" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "دىن باشلا:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "ئايلاندۇرۇپ قەۋەتلە(_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "ئارقىغا قاراپ ئىزدىسۇن(_B)" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "ئىزدەش يۆنىلىشى:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "چوڭ كىچىك ھەرپنى پەرقلەندۈر(_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "پۈتۈن سۆزگە ماسلاش(_E)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "ئىزدە تاللانمىلىرى" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "كۆڭۈلدىكى" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "چوڭ يېزىلىش" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "ئۇلانما" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "سىستېما" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "پروگرامما" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "كۆزنەك" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu مايىللىقى" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "يان كومپيۇتېر(_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "ھەرپتاختا ئورۇنلاشتۇرۇلۇشى" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "ئاكتىپ سەپلىمە ھۆججەت(_P):" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "سەپلىمە ھۆججەت قوزغالسۇن:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "يۈكلە(_L)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -#, fuzzy -msgid "Save _As" -msgstr "باشقا ئاتتا ساقلا" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Profiles" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "ھازىرقى كۆرسەتمىلەر(_P)" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "چاشقىنەك ئاستىدىكى ئوبيېكتنى سۆزلەت(_U)" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "چاشقىنەك" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "ۋاقىت فورماتى(_T):" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "چېسلا فورماتى(_E):" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "ۋاقىت ۋە چېسلا" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "ھەممىسىنى ئوقۇت(_S)" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Braille كۆرسەتكۈچى" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "چاستوتىسى (سېكۇنت):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "پروگرامما" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "سۈرئەت بالداقنى يېڭىلاش" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "قۇرۇلما يولباشچى كۇنۇپكىسىنى ئالماشتۇر." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "سۆزلەشتىن توختاش(_Y):" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "سۆزلەشتىن توختاش(_Y):" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "ئادەتتىكى" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "ئاۋاز چوڭلۇقى(_L)" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "ئاھاڭ(_T):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "سۈرئەت(_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "كىشى(_P)" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "تىل" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "تاۋۇش بىرىكتۈرگۈچ(_Z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "تاۋۇش سىستېمىسى(_S):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "ئاۋاز تىپى(_V):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -#, fuzzy -msgid "_Capitalization style:" -msgstr "چوڭ ھەرپكە ئايلاندۇرۇش ئۇسلۇبىنى «سىنبەلگە» گە تەڭشەيدۇ." - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "ئاۋاز تىپى تەڭشىكى" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "يېزىلىشى ھەر خىل بولغان تېكىستنى بىر سۆز قىلىپ سۆزلەت(_D)" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "ئومۇمىي دائىرىدىكى ئاۋاز تەڭشىكى" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "ئاۋاز" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "تاۋۇش قوزغات(_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "تەپسىلىي(_B)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "تەپسىلىيلىك" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "ھەممىسى(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "تىنىش دەرىجىسى" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "كۆرسىتىلگەن تېكىستنىلا سۆزلەت" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "بوش قۇرلارنى سۆزلەت" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "تارتىلىش ۋە رەتلەشنى سۆزلەت(_I):" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "ئوبيېكت خاتىرىلىگۈچلەرنى سۆزلەت(_K):" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "بالا ئورنىنى سۆزلەت(_O)" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "يېتەكچى ئۇچۇرلارنى سۆزلەت" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "كاتەك كوئوردېناتلىرىنى سۆزلەت(_C)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "كاتەك كوئوردېناتلىرىنى سۆزلەت(_C)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "چۈشەندۈرۈش" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "سۆزلەنگەن مەزمۇن" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "تاۋۇش" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "ئەمالار يېزىقى دەستىكىنى تاقا(_S)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "قىسقارتىلغان رول ئاتلىرى(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "سىزىق ئاخىرى سىمۋولىنى تاقا(_E):" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "قىسقارتىش جەدۋىلى(_T):" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "قىسىلغان ئەمالار يېزىقىنى قوزغات(_E)" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "گىرۋەكنى قوزغات(_D)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "كۆرۈنمە يۈز تەڭشىكى" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "يوق(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "تاللاش كۆرسەتكۈچى" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "ئۇلانما كۆرسەتكۈچى" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "چوڭايتىشنى قوزغات(_M)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "ئومۇمىي دائىرىدىكى ئاۋاز تەڭشىكى" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "ئەمالار يېزىقى" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "كۇنۇپكا ئەكس سادانى قوزغات(_K)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "يول باشلاش كۇنۇپكىلىرىنى قوزغات(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "ئېنىقلىغۇچى كۇنۇپكىلىرىنى قوزغات(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "ئىقتىدار كۇنۇپكىلىرىنى قوزغات(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "تاۋۇش قوزغات(_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "ئېنىقلىغۇچى كۇنۇپكىلىرىنى قوزغات(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "ئىقتىدار كۇنۇپكىلىرىنى قوزغات(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "مەشغۇلات كۇنۇپكىلىرىنى قوزغات(_T)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "يول باشلاش كۇنۇپكىلىرىنى قوزغات(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "ئەكس سادانى سۆز قوزغاتسۇن(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "ئەكس سادانى جۈملە قوزغاتسۇن(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "كۇنۇپكا ئەكس ساداسى" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Cthulhu ئېنىقلىغۇچى كۇنۇپكىسى(لىرى):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "كۇنۇپكا باغلىنىشى" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "تەلەپپۇز لۇغىتى" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "يېڭى كىرگۈ(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "ئۆچۈر(_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "تەلەپپۇز" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "ھەممىسىنى ئوقۇت(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "ھېچنەرسىنى سۆزلەتمە(_N):" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "ئەسلىگە قايتۇر(_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "تېكىست خاسلىقى" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "ئاستىغا يۆتكەل(_B)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "ئاستىغا بىر يۆتكەل" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "ئۈستىگە بىر يۆتكەل" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "ئۈستىگە يۆتكەل(_T)" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "تاللانغان خاسلىقلارنى تەڭشەش" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Braille كۆرسەتكۈچى" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "تېكىست خاسلىقلىرى" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "تۆۋەن" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "تىل" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "يېن" - -#: src/cthulhu/cthulhu-setup.ui:3831 -#, fuzzy -msgid "_Scale Factor:" -msgstr "چوڭايتىش نىسبىتى(_F):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3946 -#, fuzzy -msgid "Copy Results to _Clipboard" -msgstr "چاپلاش تاختىسىدىكى كۆچۈرۈلگەن مەزمۇنلار" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "تەگلىك رەڭگى" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "تەگلىك پۈتۈن ئېگىزلىكى" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "تەگلىك سىزمىلىرى" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "يۆنىلىش" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "تەھرىرچان" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "تەگات" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "ئالدى كۆرۈنۈش رەڭگى" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "ئالدى كۆرۈنۈش سىزمىلىرى" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "فونت ئۈنۈمى" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "تارتىلىش" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "خاتالىق" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "يوشۇرۇن" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "تەڭشىمە" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "تىل" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "سولدىكى بوشلۇق" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "قۇر كەڭلىكى" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "پاراگراف ئۇسلۇبى" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "قۇر ئۈستىدىكى پىكسېللار" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "قۇر ئاستىدىكى پىكسېللار" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "بۆلۈم ئىچىدىكى پىكسېللار" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "ئوڭ بوشلۇق" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "كۆتۈرۈلۈش" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "نىسبىتى" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "چوڭلۇقى" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "سوزۇلۇش" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "سىزىق سىز" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "ئۇسلۇب" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "تېكىست بېزىكى" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "تېكىست ئايلاندۇرۇش" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "تېكىست سايىسى" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "ئاستى سىزىق" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "ۋارىيانتى" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "تىك يۆنىلىشتە رەتلە" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "توملۇقى" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "قاتلاش ھالىتى" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "يېزىش ھالىتى" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "راست" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "يالغان" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "يوق" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "ئويما" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "قاپارتما" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "تېزىس" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "ئۈستى سىزىق" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "سىزىق سىز" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "چاقناش" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "قارا" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "يەككە" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "قوش" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "تۆۋەن" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "ھەرپ" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "سۆز" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "سۆز ھەرپ" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "سول" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "ئوڭ" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "ئوتتۇرا" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "توغرىلاش يوق" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "تولدۇر" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "ئۇلترا قىسىلغان" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "ئارتۇقچە قىسىلغان" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "قىسىلغان" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "يېرىم قىسىلغان" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "نورمال" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "يېرىم كېڭەيتىلگەن" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "يېيىلدى" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "ئارتۇقچە كېڭەيتىلگەن" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "ئۇلترا كېڭەيتىلگەن" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "كىچىك ھەرپلەر" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "قىيپاش" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "يانتۇ" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "كۆڭۈلدىكى" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "تېكىست گەۋدىسى" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "ماۋزۇ" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "ئاساسىي سىزىق" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "تۆۋەن" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "ئۆرلە" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "چوققا" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "تېكىست-چوققىسى" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "ئوتتۇرا" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "ئاستى" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "تېكىست-ئاخىرى" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "ۋارىسلىق قىل" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "پۈتەي" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "ھەجىلەش" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "بوشلۇقنى بېسىپ ئالماشتۇرۇڭ." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"كېڭەيتىش ئۈچۈن بوشلۇقنى بېسىڭ، ۋە بىر تۈر تاللاش ئۈچۈن يۇقىرىغا ۋە ئاستىغا " -"كۇنۇپكىسىنى قوللىنىڭ." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "فوكۇسنى بالا كۆزنەكلەرگە بەرمەك ئۈچۈن alt+f6 كۇنۇپكىلىرىنى بېسىڭ." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"تۈرلەرگە يۆتكەش ئۈچۈن، يۆنىلىش كۇنۇپكىلىرىنى قوللىنىڭ ياكى بولمىسا ئىزدەش " -"ئۈچۈن ھەرپ كىرگۈزۈڭ." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "سىستېما تىزىملىكلىرىگە ئېرىشىش ئۈچۈن alt+f1 كۇنۇپكىسىنى بېسىڭ." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "بىر تۈر تاللاش ئۈچۈن يۇقىرىغا ۋە ئاستىغا كۇنۇپكىسىنى قوللىنىڭ." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "تارايتىش ئۈچۈن shift بىلەن سولنى بېسىڭ." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "كېڭەيتىش ئۈچۈن shift بىلەن ئوڭنى بېسىڭ." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "ئاكتىپلاش ئۈچۈن قايتۇرۇش كۇنۇپكىسىنى بېسىڭ." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "تېكىست ئىچىگە يېزىڭ." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "باشقا بەتكۈچلەرنى كۆرۈش ئۈچۈن سول ۋە ئوڭ كۇنۇپكىسىنى قوللىنىڭ." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "ئاكتىپلاش ئۈچۈن بوشلۇق كۇنۇپكىسىنى بېسىڭ." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"يۇقىرىغا ۋە تۆۋەنگە ئىسترېلكىسىنى قوللىنىپ قىممەتنى تاللاڭ. ياكى ماس نومۇر " -"قىممىتىنى كىرگۈزۈڭ نى بېسىپ چېكىنىڭ." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "ئىسترېلكا كۇنۇپكىلىرىنى قوللىنىپ ئۆزگەرتىڭ." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"سول ياكى ئوڭ ئىسترېلكىنى بېسىپ يېتەكلەڭ. تۈرلەرگە يۆتكىلىش ئۈچۈن يۇقىرىغا " -"ياكى تۆۋەنگە ئىسترېلكىسىنى بېسىڭ." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "تارماق تىزىملىككە كىرىش ئۈچۈن ئوڭ ئىسترېلكىنى بېسىڭ." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"تارايتىش ئۈچۈن سول ئىسترېلكىنى بېسىڭ، كېڭەيتىش ئۈچۈن ئوڭ ئىسترېلكىنى بېسىڭ. " -"كىچىكلىتىش ئۈچۈن home كۇنۇپكىسىنى بېسىڭ، ۋە چوڭايتىش ئۈچۈن end كۇنۇپكىسىنى " -"بېسىڭ." diff --git a/po/uk.po b/po/uk.po deleted file mode 100644 index da33b95..0000000 --- a/po/uk.po +++ /dev/null @@ -1,9329 +0,0 @@ -# Ukrainian translation of cthulhu -# Copyright (C) 2005 Free Software Foundation, Inc. -# -# Maxim Dziumanenko , 2005-2009. -# wanderlust , 2009. -# Sergiy Gavrylov , 2010. -# int_ua , 2011. -# Korostil Daniel , 2011, 2012. -# Daniel Korostil , 2012. -# Mykola Tkach , 2013. -# Andriy Bandura , 2014, 2017. -# Yuri Chornoivan , 2020, 2021, 2022, 2023. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-08-11 21:31+0300\n" -"Last-Translator: Yuri Chornoivan \n" -"Language-Team: Ukrainian \n" -"Language: uk\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : " -"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Lokalize 20.12.0\n" - -msgid "Cthulhu Screen Reader" -msgstr "Інструмент читання з екрана «Cthulhu»" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "екран;читач;доступність;мовлення;брайль;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "увага" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "мульт" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "стріл" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "клндр" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "канв" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "зглвк" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "прап" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "колір" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "стовп" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "дат" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "пікт" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "наб" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "малювати" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "файлвиб" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "шрифт" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "форм" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "мал" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "внкдр" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "мітк" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "посил" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "спис" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "елспис" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "мен" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "елменю" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "парам" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "стор" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "вклад" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "панл" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "гасло" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "вигульк" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "поступ" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "кноп" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "радіо" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "елрадмн" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "прокрут" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "розд" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "рядст" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "табл" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "комрк" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "терм" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "текст" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "підказ" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "дер" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "дертабл" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "невід" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "вікн" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "абз" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "прог" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "авто" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "рдктр" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "вбуд" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Чеська, рівень 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Іспанська, рівень 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Канадська французька, рівень 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Французька, рівень 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Латвійська, рівень 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Голландська, рівень 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Норвезька, рівень 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Норвезька, рівень 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Норвезька, рівень 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Норвезька, рівень 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Польська, рівень 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Португальська, рівень 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Шведська, рівень 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "Арабська, рівень 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Валлійська, рівень 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Валлійська, рівень 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Німецька, рівень 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Німецька, рівень 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Німецька, рівень 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Британська англійська, рівень 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Британська англійська, рівень 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Англійська, рівень 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Англійська, рівень 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Канадська французька, рівень 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Французька, рівень 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Грецька, рівень 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Гінді, рівень 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "Угорська 8-ми точковий комп'ютер" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "Угорська, рівень 1" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "Угорська, рівень 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Італійська, рівень 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Бельгійська голландська, рівень 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "пробіл" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "новий рядок" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "табуляція" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "знак оклику" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "лапки" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "число" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "долар" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "процент" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "амперсанд" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "апостроф" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "ліва дужка" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "права дужка" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "зірочка" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "плюс" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "кома" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "дефіс" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "крапка" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "коса риска" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "двокрапка" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "крапка з комою" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "менше" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "дорівнює" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "більше" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "запитання" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "собака" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "ліва квадратна дужка" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "забій" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "права квадратна дужка" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "переведення каретки" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "підкреслення" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "зворотна дужка" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "ліва фігурна дужка" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "вертикальна лінія" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "права фігурна дужка" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "тильда" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "без розриву" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "перевернутий знак оклику" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "центи" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "фунти" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "знак валюти" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "єни" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "вертикальна лінія з розривом" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "розділ" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "умляут" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "авторське право" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "верхній індекс а" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "ліва подвійна дужка-ялинка" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "логічне ні" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "тире" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "зареєстрована марка" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "риска над" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "градуси" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "плюс-мінус" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "верхній індекс два" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "верхній індекс три" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "з наголосом" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "му" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "абзац" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "точка у центрі" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "седиль" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "верхній індекс один" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "градус" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "права подвійна дужка-ялинка" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "чверть" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "половина" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "три чверті" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "перевернутий знак оклику" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "а з наголосом" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "велика А зі зворотним наголосом" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "велика А з наголосом" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "велика А з дахом" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "велика А з тильдою" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "велика А з двокрапкою" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "велика А з колом" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "велика АЕ" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "велика С з седиллю" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "велика Е зі зворотним наголосом" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "велика Е з наголосом" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "велика Е з дахом" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "велика Е з двокрапкою" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "велика І зі зворотним наголосом" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "велика І з наголосом" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "велика І з дахом" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "велика І з двокрапкою" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "велика ЗЕ" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "велика N з тильдою" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "велика О зі зворотним наголосом" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "велика О з наголосом" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "велика О з дахом" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "велика О з тильдою" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "велика О з двокрапкою" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "множення хрест" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "велика О перекреслена" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "велика U зі зворотним наголосом" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "велика U з наголосом" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "велика U з дахом" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "велика U з двокрапкою" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "велика Y з наголосом" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "велика сокирка" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s з дієзом" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "а зі зворотним наголосом" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "а з наголосом" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "а з тильдою" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "а з двокрапкою" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "а з колом" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "ае" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c з седиллю" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e зі зворотним наголосом" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e з наголосом" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e з дахом" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "е з двокрапкою" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "і зі зворотним наголосом" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "і з наголосом" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "і з дахом" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "і з двокрапкою" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "зе" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n з тильдою" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "о зі зворотним наголосом" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "о з наголосом" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "о з дахом" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "о з тильдою" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "о з двокрапкою" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "розділити на" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "о перекреслене" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "сокирка" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u з наголосом" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u зі зворотним наголосом" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u з дахом" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u з двокрапкою" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y з наголосом" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y з двокрапкою" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "велика Y з двокрапкою" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "флорин" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "дефіс" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "ліва одинарна дужка" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "права одинарна дужка" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "одинарна нижня дужка" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "ліві подвійні лапки" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "праві подвійні лапки" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "подвійні нижні лапки" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "кинджал" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "подвійний кинджал" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "жирна точка" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "трикутна точка" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "на милю" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "просте" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "подвійне просте" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "потрійне просте" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "позначка-тире" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "євро" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "торгова марка" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "галочка" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "жирна галочка" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "позначка у формі ікс" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "верхній індекс 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "верхній індекс 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "верхній індекс 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "верхній індекс 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "верхній індекс 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "верхній індекс 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "верхній індекс 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "верхній індекс плюс" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "верхній індекс мінус" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "верхній індекс дорівнює" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "верхній індекс ліва дужка" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "верхній індекс права дужка" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "верхній індекс n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "нижній індекс 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "нижній індекс 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "нижній індекс 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "нижній індекс 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "нижній індекс 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "нижній індекс 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "нижній індекс 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "нижній індекс 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "нижній індекс 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "нижній індекс 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "нижній індекс плюс" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "нижній індекс мінус" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "нижній індекс дорівнює" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "нижній індекс ліва дужка" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "нижній індекс права дужка" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "заповнений квадрат" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "ромб" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "символ заміни об'єкта" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "Направляє вказівник до поточного елемента" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "Клацнути лівою кнопкою миші на поточному елементі у звичайному режимі" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "Клацнути правою кнопкою миші на поточному елементі у простому режимі." - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "Виголосити цілий документ" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "Виголосити ціле вікно при плоскому перегляді" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "Повідомити про поточне положення" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "Докладно оголосити поточне положення" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "Вимовити поточний позначений фрагмент тексту" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "Вимовити подробиці посилання" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Вимовити типову кнопку" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "Вимовити смужку стану" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "Вимовити заголовок вікна" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "Відкрити діалогове вікно пошуку" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Показати список дій" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "Шукати наступний екземпляр рядка" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "Шукати попередній екземпляр рядка" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "Вхід та вихід у режим плоского перегляду" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "Увімкнути або вимкнути обмеження плоского перегляду поточним об'єктом" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "Перемістити плоский перегляд на початок рядка" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "Перемістити плоский перегляд на кінець рядка" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "Перемістити плоский перегляд на початок попереднього рядка" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "Вимовити поточний рядок при плоскому перегляді" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "Вимовити поточний рядок по літерах у режимі загального огляду" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "" -"Фонетично вимовити поточний рядок по літерах у режимі загального огляду" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "Перемістити плоский перегляд на початок наступного рядка" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "Перемістити плоский перегляд на попередній пункт або слово" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "Вимовити поточний елемент або слово у режимі загального огляду" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "" -"Вимовити по літерах поточний елемент або слово у режимі загального огляду" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "" -"Вимовити за буквами поточний елемент або слово у режимі загального огляду" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "Перемістити плоский перегляд на наступний елемент чи слово" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "Перемістити плоский перегляд на слово, що вище від поточного слова" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "Вимовити поточний об'єкт при плоскому перегляді" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "Перемістити плоский перегляд на слово нижче поточного слова" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "Перемістити плоский перегляд на попередній символ" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "Вимовити поточний символ при плоскому перегляді" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "Вимовити поточний символ у режимі загального огляду" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "Вимовити значення Юнікоду теперішнього символу при плоскому перегляді" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "Перемістити плоский перегляд на початок на наступний символ" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "Перемістити плоский перегляд на кінець рядка" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "Перемістити плоский перегляд вниз ліворуч" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "Копіює вміст загального огляду в буфер обміну" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "Додає вміст загального огляду в буфер обміну" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "Показати вміст загального перегляду" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Увімкнути/вимкнути читання поточної комірки або всього рядка" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "Читає атрибути з поточного символу тексту" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "Пристосувати дисплей брайля ліворуч" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "Пристосувати дисплей Брайля справа" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "Повертає об'єкт, що має фокус клавіатури" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "Увімкнути або вимкнути обмеження Брайля" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "Обробити ключ руху курсора" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "Позначити початок вибраного тексту" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "Позначити кінець вибраного тексту" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Вхід у режим навчання. Для виходу з режиму навчання натисніть Esc" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "Зменшити швидкість вимови" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "Збільшити швидкість вимови" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "Зменшити висоту тону вимови" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "Збільшити висоту тону вимови" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "Збільшити гучність вимови" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "Зменшити гучність вимови" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Вибрати попереднє налаштування мовлення" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Вибрати наступне налаштування мовлення" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Зменшити поточне налаштування мовлення" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Збільшити поточне налаштування мовлення" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Зберегти налаштування мовлення" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "Увімкнути або вимкнути звук вимови" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "Перемкнути рівень подробиць у мовленні" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Перемкнути режим сну" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "Вийти з програми для читання з екрана" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "Показати вікно параметрів" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "Показати вікно параметрів програми" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "Перемкнути вимову відступів та вирівнювання" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "Змінити стиль вимови числа" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "Перемкнути на наступний рівень вимови пунктуації" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "Циклічний перехід до наступного синтезатора мови" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "Перемкнути на наступний профіль параметрів" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "Перемкнути на наступний стиль прописних літер" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "Перемкнути на наступний рівень озвучування клавіш" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "Перемикнутися між рівнями діагностики під час роботи програми" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "Шлях від закладки до поточного положення" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "Перейти до попередньої закладки" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "Перейти до закладки" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "Перейти до наступної закладки" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "Додати закладку" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "Зберегти закладки" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "Увімкнути або вимкнути режим вимови під вказівником миші" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "Показати поточний час" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "Показати поточну дату" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "Вивести дані щодо розміру і розташування поточного об'єкта" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "Передати наступну команду прямо до поточної програми" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "Вимовити кодом брайля попереднє повідомлення кімнати спілкування" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Озвучувати те, що співрозмовник почав друкувати" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Чи представляти історію повідомлень бесіди" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Увімкнути або вимкнути префікс з назвою кімнати розмов для повідомлень у " -"кімнаті спілкування." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Рядок ліворуч" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Рядок праворуч" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Лінія вгору" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Лінія вниз" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Зафіксувати" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Вгору ліворуч" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "Нижній лівий" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Позиція курсору" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Шість крапок" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Рух курсору" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Почати вирізання" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Вирізаний рядок" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "Показати останнє повідомлення сповіщення" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Показати список повідомлень сповіщення" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "Показати попереднє повідомлення сповіщення" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "Показати наступне повідомлення сповіщення" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "Перейти до наступного символу" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "Перейти до попереднього символу" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "Перейти до наступного слова" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "Перейти до попереднього слова" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "Перейти до наступного рядка" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "Перейти до попереднього рядка" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "Перейти до початку файла" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "Перейти до кінця файла" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "Перейти до початку рядка" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "Перейти до кінця рядка" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "Перейти до наступного об'єкта" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "Перейти до попереднього об'єкта" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "Розгорнути поточний розкривний список" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Перемкнути навігацію курсором між типовою програмою та програмою читання з " -"екрана" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "Розширені параметри роботи із змінюваними областями" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "Вимкнути ввічливе нагадування про змінювані області" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "Повторити попередні повідомлення про змінювані області" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "Слідкувати за змінюваними областями" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "Перемістити курсор у поточне розташування миші та з нього" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "Вказати рядок як динамічні заголовки стовпчиків" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "Очистити тимчасовий заголовок стовпчика" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "Вказати стовпчик як динамічні заголовки рядків" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "Очистити динамічні заголовки рядків" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "Показати вміст рядка введення" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "Увімкнути або вимкнути клавіші структурної навігації" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "Перейти до попереднього блоку" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "Перейти до наступного блоку" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "Показати список блоків цитування" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "Перейти до попередньої кнопки" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "Перейти до наступної кнопки" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "Показати список кнопок" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "Перейти до попередньої позначки" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "Перейти до наступної позначки" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "Показати список позначок" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "Перейти до попереднього об'єкта для клацання" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "Перейти до наступного об'єкта для клацання" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "Показати список об'єктів для клацання" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "Перейти до попереднього спадного списку" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "Перейти до наступного спадного списку" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "Перейти до початку контейнера" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "Перейти до кінця контейнера" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "Показати список спадних списків" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "Перейти до попереднього поля введення" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "Перейти до наступного поля введення" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "Показати список полів введення" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "Перейти до попереднього поля форми" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "Перейти до наступного поля форми" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "Показати список полів форми" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "Перейти до попереднього заголовка" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "Перейти до наступного заголовка" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "Показати список заголовків" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "Перейти до попереднього заголовка рівня %d" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "Перейти до наступного заголовка рівня %d" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "Показати список заголовків рівня %d" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "Перейти до попереднього вбудованого фрейма" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "Перейти до наступного вбудованого фрейма" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "Показати список вбудованих фреймів" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "Перейти до попереднього зображення" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "Перейти до наступного зображення" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "Показати список зображень" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "Перейти до попереднього орієнтира" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "Перейти до наступного орієнтира" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "Показати список орієнтирів" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "Перейти до попереднього великого об'єкта" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "Перейти до наступного великого об'єкта" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "Показати список великих об’єктів" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "Перейти до попереднього посилання" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "Перейти до наступного посилання" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "Показати список посилань" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "Перейти до наступного списку" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "Перейти до наступного списку" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "Показати список списків" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "Перейти до попереднього елемента списку" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "Перейти до наступного елемента списку" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "Показати список елементів списку" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "Перейти до попередньої інтерактивної області." - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "Перейти до попередньої інтерактивної області." - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "Перейти до останньої інтерактивної ділянки, яка зробила оголошення" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Перейти до батьківського об'єкта для фокусованого об'єкта навігатора." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "" -"Перейти до першого дочірнього об'єкта для фокусованого об'єкта навігатора." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "" -"Перейти до наступного однорівневого об'єкта для фокусованого об'єкта " -"навігатора." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "" -"Перейти до попереднього однорівневого об'єкта для фокусованого об'єкта " -"навігатора." - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "Клацнути на фокусованому об'єкті навігатора." - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "Увімкнути або вимкнути спрощену навігацію об'єктами." - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "Перейти до попереднього абзацу" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "Перейти до наступного абзацу" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "Показати список абзаців" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "Перейти до попередньої кнопки вибору" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "Перейти до наступної кнопки вибору" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "Показати список перемикачів" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "Перейти до попереднього розділювача" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "Перейти до наступного розділювача" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "Перейти до попередньої таблиці" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "Перейти до наступної таблиці" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "Показати список таблиць" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "Перейти до комірки нижче" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "Перейти до першої комірки таблиці" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "Перейти до останньої комірки таблиці" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "Перейти до комірки ліворуч" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "Перейти до комірки праворуч" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "Перейти до комірки вище" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "Увімкнути або вимкнути режим компонування" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "Перемкнути між режимом читання та фокусування" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "Увімкнути примусовий режим фокусування" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "Увімкнути примусовий режим огляду" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "Перейти до попереднього невідвіданого посилання" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "Перейти до наступного невідвіданого посилання" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "Показати список невідвіданих посилань" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "Перейти до попереднього відвіданого посилання" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "Перейти до наступного відвіданого посилання" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "Показати список відвіданих посилань" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "блакитний еліс" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "античний білий" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "аквамариновий" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "лазуровий" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "бежевий" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "суповий" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "чорний" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "мигдальний" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "синій" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "фіалковий" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "коричневий" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "жовтувато-коричневий" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "кадетський синій" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "зеленувато-жовтий" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "шоколадний" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "кораловий" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "волошковий" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "блідо-жовтий" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "кармазиновий" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "бірюзовий" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "темно-синій" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "темно-бірюзовий" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "темно-золотий" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "темно-сірий" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "темно-зелений" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "темний брунатно-зеленуватий" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "темно-бузковий" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "темно-зелено-оливковий" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "темно-жовтогарячий" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "темний синяво-рожевий" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "темно-червоний" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "темно-лососевий" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "темно-зелено-морський" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "темно-сизий" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "темний шиферно-сірий" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "темно-бірюзовий" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "темно-фіолетовий" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "глибокий рожевий" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "густий небесно-блакитний" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "тьмяно-сірий" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "захисний синій" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "цегляний" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "квітковий білий" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "лісно-зелений" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "ясно-бурячковий" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "світлий сіро-фіолетовий" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "примарно-білий" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "золотий" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "золотистий" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "сірий" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "зелений" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "зелено-жовтий" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "нектарний" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "яскраво-рожевий" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "індійський червоний" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "індиго" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "жовтуватий" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "брунатно-зеленуватий" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "блідо-ліловий" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "рум'яно-ліловий" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "зелено-батистовий" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "лимонно-кремовий" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "світло-синій" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "світло-кораловий" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "світло-бірюзовий" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "світло-жовтий золотистий" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "світло-сірий" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "салатовый" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "світло-рожевий" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "світло-лососевий" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "світло-зелено-морський" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "світлий небесно-блакитний" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "світлий шиферно-сірий" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "світло-сталевий синій" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "світло-жовтий" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "яскравий світло-зелений" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "світло-зелений" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "лляний" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "пурпуровий" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "каштановий" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "помірний аквамариновий" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "помірно-синій" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "помірний синяво-рожевий" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "помірно-пурпурний" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "помірний зелено-морський" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "помірно-сизий" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "помірний весняно-зелений" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "помірний бірюзовий" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "фіолетово-червоний" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "чорнувато-синій" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "кремовий м'ятний" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "тьмяно-рожевий" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "мокасиновий" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "білий навахо" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "темно-синій" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "старе мереживо" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "оливковий" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "ніжно-оливковий" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "помаранчевий" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "помаранчево-червоний" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "синяво-рожевий" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "блідо-золотистий" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "блідо-зелений" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "блідо-бірюзовий" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "блідий фіолетово-червоний" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "пагін папаї" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "персиковий пух" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "перу" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "рожевий" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "сливовий" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "порошково-синій" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "пурпуровий" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "червоний" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "рожево-коричневий" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "червоняво-синій" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "сідловий" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "лососевий" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "гірчичний" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "морський зелений" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "морська черепашка" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "вохряний" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "срібний" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "небесно-блакитний" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "сизий" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "шиферно-сірий" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "сніжний" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "весняно-зелений" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "синювато-сталевий" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "брунатний" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "зеленувато-голубий" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "будяковий" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "томатний" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "бірюзовий" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "фіолетовий" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "пшеничний" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "білий" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "димчасто-білий" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "жовтий" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "жовто-зелений" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "_Увімкнути" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "Автоматичний режим фокусування під час структурної навігації" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "Автоматичний режим фокусування під час курсорної навігації" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "Автоматичний режим фокусування під час природної навігації" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Точка _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Точка _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Точки 7 _та 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "_Скасувати" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "_Перейти до" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "_Гаразд" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "Піктограма" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "Немає" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "Вимова" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Говорити, коли _співрозмовник друкує" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Надавати _історію повідомлень для кожної бесіди" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Вимовляти повідомлення з" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Всі кан_али" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Всі канали, якщо вікно %s акт_ивне" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Канал, _вікно якого вибрано" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "Вимовити назву _бесіди" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "Увімкнути режим компонування для вмісту" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "подвійний клік" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "потрійний клік" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Типовий синтезатор" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Рядок" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Рядок заміни" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Увімкнути озвучення за _буквами" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Увімкнути несамостійні _діакритичні клавіші" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "_Поточне розташування" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Мінімальна довжина тексту, що відповідає:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Параметри пошуку" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Під час пошуку озвучувати _зміни рядка" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Вимовляти результати під час по_шуку" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "Команда" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Прив'язки клавіш" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "Типово" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "Режим навчання" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Дії" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Прив'язки системи Брайля" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Закладки" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "Дата і час" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "Перевірка мишки" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "Навігація об'єктами" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "Подробиці про об'єкт" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Не вказано" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "Загальний перегляд" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "Озвучення та докладність" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "Вміст загального перегляду" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "Змінено" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Настільна" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Сповіщення" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Отримано" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "Представлення сповіщень" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Параметри Cthulhu для %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Позначати у брайлі" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Лише якщо" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Вимовити" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Зберегти профіль як конфліктний" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "Конфлікт профілю користувача!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Профіль %s уже існує.\n" -"Продовжити оновлення наявного профілю з цими змінами?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "Завантажити профіль користувача" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Ви збираєтесь змінити активний профіль. Якщо ви\n" -"збираєтесь лише змінити дещо в налаштування, це\n" -"буде відкинуто при його завантажені.\n" -"\n" -"Продовжити завантаження профілю, відкинувши попередні зміни?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Зберегти профіль як" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "_Назва профілю" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "Вилучити профіль користувача" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"Ви наказали програмі вилучити профіль %s. Усі незбережені значення " -"параметрів і усі параметри, які було збережено у цьому профілі, буде " -"втрачено. Хочете продовжити виконання дії і вилучити цей профіль і усі " -"пов'язані із ним значення параметрів?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Усі" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Програма" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Вікно" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "_Жоден" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "_Деякі" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "_Найбільше" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Рядок" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Речення" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "Блок цитування" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "Кнопка" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "Заголовок" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Позначки" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "Об'єкт для клацання" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "Розкривний список" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "Опис" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "Заголовок" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Внутрішня рамка" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "Зображення" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "Мітка" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "Орієнтир" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "Рівень" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "Посилання" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "Список" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "Елемент списку" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "Об'єкт" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Абзац" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Перемикач" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "Роль" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "Вибраний елемент" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "Стан" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "Текст" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "Значення" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Блоки цитування" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Кнопки" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Позначки" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "Об'єкти для клацання" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "Розкривні списки" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "Елементи" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "Поля форми" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "Заголовки" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Внутрішні рамки" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "Зображення" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Заголовки рівня %d." - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "Орієнтири" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Великі об'єкти." - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "Посилання" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "Списки" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "Елементи списку" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Абзаци" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Перемикачі" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "Таблиці" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "Невідвідані посилання" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "Відвідані посилання" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Переміщення на сторінці" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Вимовляти початок сторінки, коли вона завантажена в_перше" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "_Подавати підсумок сторінки, коли вона завантажена вперше" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Розбивати промову на _фрагменти призупиняючи" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "типовий голос %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Типово" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Гіперпосилання" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Система" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Верхній регістр" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Диспетчер мови" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "Перевірка правопису" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "Вимовляти _помилку по буквах" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "Вимовляти _пропозицію по буквах" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "Надавати _контекст помилки" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "Вимовляти координати комірок таблиці" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "Завжди виголошувати позначений діапазон у електронній таблиці" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "Вимовляти заголовок _комірки" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Переміщення у таблицях" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Пропускати _порожні рядки" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "В_имовити комірку" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Вимовляти координати _комірок" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Вимовляти розміри _великих комірок" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Назва атрибуту" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "Керування курсорною навігацією" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "Увімкнути _структурну навігацію." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Тема звуків:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Тема звуків" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Стисло" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d сповіщення" -msgstr[1] "%d сповіщення" -msgstr[2] "%d сповіщень" -msgstr[3] "%d сповіщення" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "ліва Shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "ліва Alt" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ліва Control" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "права Shift" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "права Alt" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "права Control" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "ліва Meta" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "права Meta" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "NumLock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "Кепслок" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "Кепслок" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "ScrollLock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "PageUp" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "PageDown" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "ліва табуляція" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "ввід" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "вгору" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "вниз" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "ліворуч" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "праворуч" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "лівий super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "правий super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "меню" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "довідка" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "мульти" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "перемикач режиму" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "скасувати" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "вставити" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "вилучити" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "на початок" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "у кінець" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "початок" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "циркумфлекс" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "з кільцем" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "перекреслене" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "мінус" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "Insert" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "жирний %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "курсив %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "жирний курсив %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "індекс %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "жирний індекс %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "фрактура %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "контурний %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "жирна фрактура %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "без засічок %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "жирний без засічок %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "курсив без засічок %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "жирний курсив без засічок %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "пропорційний %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "без крапочки %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "ліва стрілка" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "верхня стрілка" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "права стрілка" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "нижня стрілка" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "стрілка вліво-вправо" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "стрілка вгору-вниз" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "стрілка північний захід" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "стрілка північний схід" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "стрілка південний схід" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "ліва стрілка від стійки" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "верхня стрілка від стійки" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "права стрілка від стійки" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "нижня стрілка від стійки" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "ліва подвійна стрілка" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "верхня подвійна стрілка" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "права подвійна стрілка" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "нижня подвійна стрілка" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "подвійна стрілка вліво-вправо" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "подвійна стрілка вгору-вниз" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "північно-західна подвійна стрілка" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "північно-східна подвійна стрілка" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "південно-східна подвійна стрілка" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "південно-східна подвійна стрілка" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "стрілка з правим вказівником" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "стрілка з вістрям та правим вказівником" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "мінус" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "менше" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "більше" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "циркумфлекс" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "гачек" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "бревіс" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "крапка" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "подвійна вертикальна риска" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "три крапки" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "для всіх" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "доповнення" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "частинний диференціал" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "існує" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "не існує" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "порожня множина" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "приріст" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "набла" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "належить" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "не належить" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "малий символ належить" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "містить" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "не містить" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "малий символ містить" - -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "кінець доведення" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "добуток" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "кодобуток" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "сума" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "мінус або плюс" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "плюс з крапкою" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "ділення як скісна риска" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "різниця множин" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "оператор зірочка" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "оператор композиції" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "оператор множення" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "квадратний корінь" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "кубічний корінь" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "корінь четвертого степеня" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "пропорційно" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "нескінченість" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "прямий кут" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "кут" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "виміряний кут" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "сферичний кут" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "ділиться" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "не ділиться" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "паралельне" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "не паралельне" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "логічне і" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "логічне або" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "перетин" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "об'єднання" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "інтеграл" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "подвійний інтеграл" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "потрійний інтеграл" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "криволінійний інтеграл" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "поверхневий інтеграл" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "об'ємний інтеграл" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "інтеграл за годинник. стрілкою" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "криволінійний інтеграл по замкненому контуру з додатною орієнтацією" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "криволінійний інтеграл по замкненому контуру з від'ємною орієнтацією" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "відповідно" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "тому що" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "відношення" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "пропорція" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "мінус з крапкою" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "надлишок" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "геометрична пропорція" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "гомотетія" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "тильда" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "зворотна тильда" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "обернута лінива латинська ес" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "синусоїда" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "вінковий добуток" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "не тильда" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "мінус з тильдою" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "асимптотично дорівнює" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "асимптотично не дорівнює" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "наближено дорівнює" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "наближено, але не точно, дорівнює" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "ні наближено, ні точно не дорівнює" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "майже дорівнює" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "майже не дорівнює" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "майже дорівнює або дорівнює" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "потрійна тильда" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "усе дорівнює" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "рівносильне" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "геометрично еквівалентне" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "різниця між" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "досягається границя" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "геометрично дорівнює" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "наближено дорівнює або є образом" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "є образом або наближено дорівнює" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "двокрапка дорівнює" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "дорівнює двокрапка" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "кільце у знаку рівності" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "кільце дорівнює" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "відповідає" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "оцінювання" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "рівнокутні з" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "зірочка дорівнює" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "дельта дорівнює" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "дорівнює за визначенням" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "виміряно" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "може дорівнювати" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "не дорівнює" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "тотожність" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "не тотожність" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "строго рівносильне" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "менше або дорівнює" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "більше або дорівнює" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "менше або рівне" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "більше або рівне" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "менше або не рівне" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "більше або не рівне" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "набагато менше" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "набагато більше" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "між" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "не рівносильне" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "не менше" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "не більше" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "не менше і не дорівнює" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "не більше і не дорівнює" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "менше або рівносильне" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "більше або рівносильне" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "не менше і не рівносильне" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "не більше і не рівносильне" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "менше або більше" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "більше або менше" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "не менше і не більше" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "не більше і не менше" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "передує" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "слідує" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "передує або дорівнює" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "слідує або дорівнює" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "передує або рівносильне" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "слідує або рівносильне" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "не передує" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "не слідує" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "підмножина" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "надмножина" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "не підмножина" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "не надмножина" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "підмножина або дорівнює" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "надмножина або дорівнює" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "не підмножина і не дорівнює" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "не надмножина і не дорівнює" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "підмножина, але не дорівнює" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "надмножина, але не дорівнює" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "мультимножина" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "множення мультимножин" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "об'єднання мультимножин" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "квадратний образ" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "квадратний оригінал" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "квадратний образ або дорівнює" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "квадратний оригінал або дорівнює" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "квадратний перетин" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "квадратне об'єднання" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "плюс в кружечку" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "мінус в кружечку" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "множення в кружечку" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "скісна риска в кружечку" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "крапка в кружечку" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "композиція в кружечку" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "зірка в кружечку" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "дорівнює в кружечку" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "дефіс в кружечку" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "плюс у квадраті" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "мінус у квадраті" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "множення у квадраті" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "крапка у квадраті" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "правий турнікет" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "лівий турнікет" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "тавтологія" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "суперечність" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "твердження" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "є моделлю" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "є істиною" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "змушує" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "потрійний вертикальний стрижень і правий турнікет" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "подвійний вертикальний стрижень і правий турнікет" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "не доводить" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "не є істиною" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "не змушує" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "заперечення подвійного вертикального стрижня і правого турнікету" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "відношення передує" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "відношення слідує" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "нормальна підгрупа" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "містить нормальну підгрупу " - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "нормальна підгрупа або дорівнює" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "містить як нормальну підгрупу або дорівнює" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "оригінал" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "зображення" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "мультивідображення" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "спряжена ермітова матриця" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "втулений" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "виключне або" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "штрих Шеффера" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "стрілка Пірса" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "прямий кут з дугою" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "прямий трикутник" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "оператор ромб" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "оператор крапка" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "оператор зірка" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "ділення і множення" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "петля" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "лівий напівпрямий добуток з нормальним множником" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "правий напівпрямий добуток з нормальним множником" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "лівий напівпрямий добуток" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "правий напівпрямий добуток" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "зворотна тильда дорівнює" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "закручене логічне або" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "закручене логічне і" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "подвійна підмножина" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "подвійна надмножина" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "подвійний перетин" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "подвійне об'єднання" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "вила" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "дорівнює і паралельне" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "менше з крапкою" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "більше з крапкою" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "дуже менше" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "дуже більше" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "менше-рівне або більше" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "більше-рівне або менше" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "рівне або менше" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "рівне або більше" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "рівне або передує" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "рівне або слідує" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "не передує і не рівне" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "не слідує і не рівне" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "не квадратний образ і не дорівнює" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "не квадратний оригінал і не дорівнює" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "квадратний образ або не дорівнює" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "квадратний оригінал і не дорівнює" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "менше, але не рівносильне" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "більше, але не рівносильне" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "передує, але не рівносильне" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "слідує, але не рівносильне" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "не нормальна підгрупа" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "не містить як нормальну підгрупу" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "не нормальна підгрупа і не дорівнює" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "не містить як нормальну підгрупу і не дорівнює" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "вертикальні трикрапки" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "середні горизонтальні трикрапки" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "діагональні трикрапки вправо вгору" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "діагональні трикрапки вправо вниз" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "символ „належить“ з довгою горизонтальною рискою" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" -"символ „належить“ з вертикальним стрижнем на кінці горизонтальної риски" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" -"малий символ „належить“ з вертикальним стрижнем на кінці горизонтальної риски" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "символ „належить“ з крапкою вгорі" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "символ „належить“ з рискою над ним" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "малий символ „належить“ з рискою над ним" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "символ „належить“ з рискою внизу" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "символ „належить“ з двома горизонтальними рисками" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "символ „містить“ з довгою горизонтальною рискою" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "символ „містить“ з вертикальним стрижнем на кінці горизонтальної риски" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" -"малий символ „містить“ з вертикальним стрижнем на кінці горизонтальної риски" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "символ „містить“ з рискою над ним" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "малий символ „містить“ з рискою вгорі" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "пакетна приналежність у z-нотації" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "ліва стеля" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "права стеля" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "ліва підлога" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "права підлога" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "верхня фігурна дужка" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "нижня фігурна дужка" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "ліва кутова дужка" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "права кутова дужка" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "крапка у кружечку" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "об'єднання з крапкою" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "об'єднання з плюсом" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "квадратний перетин" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "квадратне об'єднання" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "чорний квадрат" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "білий квадрат" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "чорний ромб" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "білий круг" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "чорний круг" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "білий кружечок" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "чорний малий квадрат по середині" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s з підкресленням" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s із скісною рискою" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s із вертикальною рискою" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "програма" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "порожній" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "жирний" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "закладка введена" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "закладки збережені" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "не вдається зберегти закладки" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "Закладок не знайдено." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "Закладку не знайдено." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Режим прямої передачі команд увімкнено." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Не вдається знайти дисплей калькулятора" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "сигнал" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "Прописні літери позначаються піктограмою." - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "немає" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "Стиль прописних літер не встановлено." - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "вимова" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "Прописні літери вимовляються." - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "Програма керує курсором." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu керує курсором." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Комірка %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "Позначено %s" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "Позначено комірки від %s до %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "Знято позначення з комірок від %s до %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "Знято позначення з %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Примусово вимкнути параметр" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Примусово увімкнути параметр" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "ПАРАМЕТР" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "Необов'язкові аргументи" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "Використання:" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "Недійсний:" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "Вивести відомі запущені програми" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "Завантажити профіль" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "Неможливо завантажити профіль: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" -"Неможливо запустити Cthulhu, оскільки неможливо підключитися до " -"стільниці.Неможливо запустити читач екрана, бо неможливо з'єднатись зі " -"стільницею." - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "Не вдалось увімкнути менеджер параметрів. Вихід." - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"Інший процес читання екрана вже запущено для цього сеансу.\n" -"Виконайте команду „cthulhu --replace“, щоб замінити цей процес новішим." - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "НАЗВА" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Використовувати інший каталог з параметрами користувача" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "КАТ" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "Версія цієї програми" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Замінити поточний екземпляр Cthulhu" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "Показати це повідомлення довідки та вийти" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Надіслати налагоджувальний вивід до debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Надіслати налагоджувальний вивід у вказаний файл" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "ФАЙЛ" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Вказати параметри користувача (текстова версія)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "Вказати параметри користувача (графічна версія)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Повідомити про помилку у список розсилки https://groups.io/g/stormux." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "Вирізує вміст у буфер обміну." - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "вирізати" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "Скопійовано вміст у буфер обміну." - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "скопійовано" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "Вставлено вміст із буфера обміну." - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "вставлено" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Не сповіщати, коли ваші друзі набирають." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "сповіщати, коли ваші друзі набирають." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Повідомлення з розмови %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Нова вкладка бесіди %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Не вимовляти назву кімнати розмов. " - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "назва кімнати розмови." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Не представляти історію повідомлень для кожної бесіди." - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Представляти історію повідомлень для кожної бесіди." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "початок вилучення" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "кінець вилучення" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "початок вставлення" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "кінець вставлення" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "початок підсвічування" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "кінець підсвічування" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "кінець пропозиції" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "Кінець контейнера." - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "Не у контейнері." - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "позначено усі пункти" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Типова кнопка %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "Типовою є кнопка %s. Неактивна" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "Типової кнопки не знайдено" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "нижній індекс %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " верхній індекс %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "Не є діалоговим вікном" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "виділено весь документ" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "знято позначення з усього документа" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "документ виділено від позиції курсора" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "знято виділення документа від позиції курсору до кінця" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "документ виділено до позиції курсора" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "знято виділення документа від початку до позиції курсору" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Встановлено тимчасовий заголовок для рядка %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Динамічний заголовок стовпчика очищено." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Динамічний заголовок рядка очищено для стовпчика %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Динамічний заголовок рядка очищено." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "порожній" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f кілобайт" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f мегабайт" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Файли не знайдені." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "Додає вміст у буфер обміну." - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "Копіює вміст у буфер обміну." - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "Не використовувати загальний огляд." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Увійти в режим загального перегляду." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Залишити режим загального перегляду." - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "Плоский перегляд обмежено поточним об'єктом" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Плоский перегляд не обмежено" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "містить формулу" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "відкриває діалогове вікно" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "відкриває таблицю" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "відкриває спадний список" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "відкриває меню" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "відкриває ієрархію" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "посилання у зображені" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Введена клавіша вже використовується для %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Клавішу захоплено: %s. Для підтвердження натисніть Enter" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Нова клавіша: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Визначено натискання клавіші. Натисніть „Enter“ для підтвердження." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Прив'язку до клавіш вилучено." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "введіть нову клавішу" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "клавіша" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "Встановлено озвучування для клавіш." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Немає" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "Озвучення немає." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "клавіша та слово" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "Встановлено озвучування для клавіш і слів." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "речення" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "Встановлено озвучування для речень." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "слово" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "Встановлено озвучування для слів." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "слово та речення" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "Встановлено озвучування для слів і речень." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "Закрито: %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "страховий символ" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "квадрат" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "коло" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "довгий знак ділення" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "радикал" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "квадрат із заокругленими кутами" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "горизонтальна риска" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "вертикальна риска" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "нижня діагональна риска" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "верхня діагональна риска" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "північно-східна стрілка" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "лінія вниз" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "лінія наліво" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "лінія направо" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "лінія догори" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "фазовий кут" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "арабський символ факторіала" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "та" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "початок дробу" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "дріб без риски, початок" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "риска дробу" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "кінець дробу" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "квадратний корінь" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "кубічний корінь" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "корінь" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "початок виразу під коренем" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "кінець виразу під коренем" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "нижній індекс" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "верхній індекс" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "перед нижнім індексом" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "перед верхнім індексом" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "підкреслення" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "надкреслення" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "кінець таблиці" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "кінець вкладеної таблиці" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "недоступно" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Вимкнено" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Вимкнено вимову відступів та вирівнювань." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Увімкнено" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Увімкнено вимову відступів та вирівнювань." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Режим навчання. Для виходу натисніть Esc." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"Вхід у режим вивчення клавіатури. Натисніть клавішу, щоб прослухати її " -"призначення. Щоб переглянути документацію екранного читача, натисніть F1. " -"Щоб отримати список типових комбінацій клавіш програми, натисніть F2. Щоб " -"отримати список скорочень для поточної програми, натисніть F3. Щоб вийти з " -"режиму вивчення, натисніть клавішу скасування." - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "кінець блоку цитування." - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "полишаємо подробиці." - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "кінець стрічки." - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "кінець рисунка." - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "кінець форми." - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "кінець банера." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "кінець додаткового матеріалу." - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "кінець інформації." - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "кінець основного матеріалу." - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "кінець навігації." - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "кінець області." - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "кінець пошуку." - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "кінець списку." - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "кінець панелі." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "кінець таблиці." - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "полишаємо підказку." - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "кінець анотації." - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "кінець визнань." - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "кінець післямови." - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "кінець додатка" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "кінець бібліографії." - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "кінець глави." - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "кінець вихідних даних." - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "кінець висновку." - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "кінець подяки." - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "кінець подяк." - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "кінець присвяти." - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "кінець кінцевих приміток." - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "кінець епіграфа." - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "кінець епілогу." - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "кінець списку друкарських помилок." - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "кінець прикладу." - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "кінець преамбули." - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "кінець словника." - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "кінець покажчика." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "кінець вступу." - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "кінець списку сторінок." - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "кінець частини." - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "кінець передмови." - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "кінець прологу." - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "кінець помітних цитат." - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "кінець ЧАП." - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "полишаємо пропозицію." - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "кінець змісту." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "рядок виділено вниз від позиції курсора" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "рядок виділено вгору від позиції курсора" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "знято виділення рядка від позиції курсору до кінця" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "знято виділення рядка від початку до позиції курсору" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Вихід з режиму навчання." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "виділений рядок від початку до попередньої позиції курсора" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "виділений рядок від попередньої позиції курсору до кінця" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "посилання" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "та ж сторінка" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "той же сайт" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "інший сайт" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s посилання на %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "посилання %s" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "%s відвідане посилання" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "" -"Використовуйте стрілки вгору і вниз, щоб пересуватись по списку. І натисніть " -"«Escape», щоб вийти." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Всі сповіщення про змінювані області вимкнено" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "Рівні ввічливого сповіщення про змінювані області відновлено" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "рівень ввічливого сповіщення %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "встановлення наполегливого режиму змінюваних областей" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "вимкнення змінюваних областей" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "встановлення ввічливого режиму змінюваних областей" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "встановлення грубого режиму змінюваних областей" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Стеження за змінюваними областями вимкнено" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Стеження за змінюваними областями увімкнено" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "не збережено повідомлення про зміни" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Підтримка змінюваних областей вимкнено" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Не знайдено" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Не вдається знайти поточне розташування." - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "вимкнено" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "увімкнено" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "слово з помилкою" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Слово з помилкою: %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "У контексті %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "Режим читання" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "Режим фокусування" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "Для увімкнення режиму фокусування натисніть %s." - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "Примусовий режим фокусування." - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "Режим огляду - примусовий." - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "Режим компонування." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "Режим об'єктів." - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "Вказівник пересунуто на об'єкт." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Не знайдено мишку над об'єктом." - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "Перевірка мишки вимкнена." - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "Перевірка мишки увімкнена." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "Помилка: не можливо створити список об'єктів." - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Немає дочірніх." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "Немає наступного." - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "Немає батьківського." - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "Немає попереднього." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "Увімкнено спрощену навігацію." - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "Вимкнено спрощену навігацію." - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Рівень вкладення %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Додано новий елемент" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "Не знайдено дій на таке: %s" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Немає фокусу" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Немає сфокусованої програми." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Більше немає блоків цитування." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Більше немає кнопок." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Більше немає відміток." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Більше немає великих об'єктів." - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "Більше немає об'єктів для клацання." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Більше немає розкривних списків." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Більше немає полів вводу." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Більше немає полів форм." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Більше немає заголовків." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Більше немає заголовків рівня %d." - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "Більше немає вбудованих фреймів." - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "Більше немає зображень." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Орієнтири не знайдені." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "Більше немає посилань." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Більше немає списків." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Більше немає елементів списку." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Більше немає змінюваних областей." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Більше немає тексту." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Більше немає кнопок вибору." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Більше немає розділювачів." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Більше немає таблиць." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Більше немає невідвіданих посилань." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Більше немає відвіданих посилань." - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "Немає виділеного тексту." - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "Не над посиланням." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Сповіщення" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Низ" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Верхівка" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Нема повідомлень сповіщення" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "цифри" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "Вимовляти числа як цифри." - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "слова" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "Вимовляти числа як слова." - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "вимкнено" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "увімкнено" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Завантаження, зачекайте." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Завантаження завершено." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Завершення завантаження %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "Сторінка має %s" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "сторінка виділена від позиції курсора" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "сторінка виділена до позиції курсора" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "знято виділення сторінки від позиції курсору" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "знято виділення сторінки до позиції курсору" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "абзац виділено вниз від позиції курсора" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "абзац виділено вгору від позиції курсора" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "знято виділення з абзацу вниз від позиції курсора" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "знято виділення з абзацу вгору від позиції курсора" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Вікно налаштування параметрів Cthulhu вже відкрито.\n" -"Закрийте його спочатку." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "слайд %(position)d of %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "Профіль встановлено у %s." - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "Профілі не знайдені." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Рядок поступу %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Усі" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Рівень пунктуації вказано для всіх." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Більшість" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Рівень пунктуації вказано для більшості." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Жоден" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Рівень пунктуації не вказано." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Деякі" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Для деяких вказано рівень пунктуації." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Пошук." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Пошук завершено." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Налаштування Cthulhu перезавантажено." - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "Позначений текст: %s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "Позначене вилучено." - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "Позначення відновлено." - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "Позначення тексту скасовано." - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "Розміри: %d на %d. Розташування: %d, %d." - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "Ширина: %d. Висота: %d. %d від лівого краю. %d від верхнього краю." - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Вимову вимкнено." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Вимову увімкнено." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "швидше." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "повільніше." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "вище." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "нижче." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "гучніше." - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "тихіше." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Швидкість %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Висота тону %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Гучність %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Модуль Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Голос Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Немає доступних модулів Speech-dispatcher" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Немає доступних голосів Speech-dispatcher" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Налаштування мовлення збережено" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Не вдалося зберегти налаштування мовлення" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "Рівень подробиць: короткий" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "Рівень подробиць: детальний" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " три крапки " - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu вітає вас." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Ктулху ховається під хвилями." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Режим сну увімкнено для %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Режим сну вимкнено для %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Вимова недоступна." - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "Не знайдено" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "Смужку стану не знайдено" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "рядок не знайдено" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Клавіші структурної навігації вимкнені." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Клавіші структурної навігації увімкнені." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Не знайдено" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Рядок %(row)d, стовпчик %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Кінець таблиці" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Вимовити комірку" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Вимовити рядок" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Не однакові" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Не у таблиці." - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "Порядок стовпчиків змінено" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "Порядок рядків змінено" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "стовпчик %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "стовпчик %(index)d з %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Кінець стовпчика." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Початок стовпчика." - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "Позначено стовпчик %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "Позначено стовпчики з %s до %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "Знято позначення зі стовпчиків з %s до %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "Знято позначення зі стовпчика %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "рядок %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "рядок %(index)d з %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Початок рядка" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Кінець рядка." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Рядок вилучено." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Останній рядок вилучено." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Рядок вставлено." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Рядок вставлено в кінець таблиці." - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "Позначено рядок %s" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "Позначено рядки з %s до %s" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "Знято позначення з рядків з %s до %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "Знято позначення з рядка %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "виділений" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "не виділений" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H годин, %M хвилин і %S секунд" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H годин і %M хвилин" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Юнікод %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "повернути" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "повторити" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu версія %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "Порожній рядок" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Продовження з кінця." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Продовження з початку." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 елементів" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Комірка займає %d рядок" -msgstr[1] "Комірка займає %d рядки" -msgstr[2] "Комірка займає %d рядків" -msgstr[3] "Комірка займає %d рядок" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d стовпчик" -msgstr[1] "%d стовпчики" -msgstr[2] "%d стовпчиків" -msgstr[3] "%d стовпчик" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Комірка займає %d стовпчик" -msgstr[1] "Комірка займає %d стовпчики" -msgstr[2] "Комірка займає %d стовпчиків" -msgstr[3] "Комірка займає %d стовпчик" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d символ надто довгий" -msgstr[1] "%d символи надто довгі" -msgstr[2] "%d символів надто довгі" -msgstr[3] "%d символ надто довгий" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d діалог)" -msgstr[1] "(%d діалоги)" -msgstr[2] "(%d діалогів)" -msgstr[3] "(%d діалог)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d неактивний діалог" -msgstr[1] "%d неактивні діалоги" -msgstr[2] "%d неактивних діалогів" -msgstr[3] "%d неактивний діалог" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d байт" -msgstr[1] "%d байти" -msgstr[2] "%d байтів" -msgstr[3] "%d байт" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "%d файл знайдено" -msgstr[1] "%d файли знайдено" -msgstr[2] "%d файлів знайдено" -msgstr[3] "%d файл знайдено" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d форма" -msgstr[1] "%d форми" -msgstr[2] "%d форм" -msgstr[3] "%d форма" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d заголовок" -msgstr[1] "%d заголовки" -msgstr[2] "%d заголовків" -msgstr[3] "%d заголовок" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d елемент" -msgstr[1] "%d елементи" -msgstr[2] "%d елементів" -msgstr[3] "%d елемент" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d орієнтир" -msgstr[1] "%d орієнтири" -msgstr[2] "%d орієнтирів" -msgstr[3] "%d орієнтир" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "%d елемент знайдено" -msgstr[1] "%d елементи знайдено" -msgstr[2] "%d елементів знайдено" -msgstr[3] "%d елемент знайдено" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Кінець %d блоку цитування." -msgstr[1] "Кінець %d блоків цитування." -msgstr[2] "Кінець %d блоків цитування." -msgstr[3] "Кінець %d блоку цитування." - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Залишаємо %d список." -msgstr[1] "Залишаємо %d списки." -msgstr[2] "Залишаємо %d списків." -msgstr[3] "Залишаємо %d список." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "Список невідомого розміру" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Список з %d елементом" -msgstr[1] "Список з %d елементами" -msgstr[2] "Список з %d елементами" -msgstr[3] "Список з %d елементом" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "Стрічка невідомого розміру" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "Стрічка з %d статтею" -msgstr[1] "Стрічка з %d статтями" -msgstr[2] "Стрічка з %d статтями" -msgstr[3] "Стрічка з %d статтею" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Список описів із %d терміном" -msgstr[1] "Список описів із %d термінами" -msgstr[2] "Список описів із %d термінами" -msgstr[3] "Список описів із %d терміном" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d значення" -msgstr[1] "%d значення" -msgstr[2] "%d значень" -msgstr[3] "%d значення" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "математична таблиця з %d рядком" -msgstr[1] "математична таблиця з %d рядками" -msgstr[2] "математична таблиця з %d рядками" -msgstr[3] "математична таблиця з %d рядком" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d стовпчик" -msgstr[1] "%d стовпчики" -msgstr[2] "%d стовпчиків" -msgstr[3] "%d стовпчик" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "вкладена математична таблиця з %d рядком" -msgstr[1] "вкладена математична таблиця з %d рядками" -msgstr[2] "вкладена математична таблиця з %d рядками" -msgstr[3] "вкладена математична таблиця з %d рядком" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d повідомлення.\n" -msgstr[1] "%d повідомлення.\n" -msgstr[2] "%d повідомлень.\n" -msgstr[3] "%d повідомлення.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d відсоток." -msgstr[1] "%d відсотка." -msgstr[2] "%d відсотків." -msgstr[3] "%d відсоток." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d відсоток документа прочитано" -msgstr[1] "%d відсотки документа прочитано" -msgstr[2] "%d відсотків документа прочитано" -msgstr[3] "%d відсоток документа прочитано" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d точка" -msgstr[1] "%d точки" -msgstr[2] "%d точок" -msgstr[3] "%d точка" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d символ %(repeatChar)s " -msgstr[1] "%(count)d символи %(repeatChar)s " -msgstr[2] "%(count)d символів %(repeatChar)s " -msgstr[3] "%(count)d символ %(repeatChar)s " - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d з %(total)d елемент виділено" -msgstr[1] "%(index)d з %(total)d елементи виділено" -msgstr[2] "%(index)d з %(total)d елементів виділено" -msgstr[3] "%(index)d з %(total)d елемент виділено" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "%d типове клавіатурне скорочення знайдено." -msgstr[1] "%d типових клавіатурних скорочень знайдено." -msgstr[2] "%d типових клавіатурних скорочень знайдено." -msgstr[3] "%d типове клавіатурне скорочення знайдено." - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "" -"Знайдено %(count)d клавіатурне скорочення для програми %(application)s." -msgstr[1] "" -"Знайдено %(count)d клавіатурних скорочень для програми %(application)s." -msgstr[2] "" -"Знайдено %(count)d клавіатурних скорочень для програми %(application)s." -msgstr[3] "" -"Знайдено %(count)d клавіатурне скорочення для програми %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d пробіл" -msgstr[1] "%d пробіли" -msgstr[2] "%d пробілів" -msgstr[3] "%d пробіл" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d табуляція" -msgstr[1] "%d табуляції" -msgstr[2] "%d табуляцій" -msgstr[3] "%d табуляція" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d таблиця" -msgstr[1] "%d таблиці" -msgstr[2] "%d таблиць" -msgstr[3] "%d таблиця" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "таблиця невідомого розміру" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "таблиця із %d стовпчиком, кількість рядків невідома" -msgstr[1] "таблиця із %d стовпчиками, кількість рядків невідома" -msgstr[2] "таблиця із %d стовпчиками, кількість рядків невідома" -msgstr[3] "таблиця із %d стовпчиком, кількість рядків невідома" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "таблиця із %d рядком, кількість стовпчиків невідома" -msgstr[1] "таблиця із %d рядками, кількість стовпчиків невідома" -msgstr[2] "таблиця із %d рядками, кількість стовпчиків невідома" -msgstr[3] "таблиця із %d рядком, кількість стовпчиків невідома" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "таблиця з %d рядком" -msgstr[1] "таблиця з %d рядками" -msgstr[2] "таблиця з %d рядками" -msgstr[3] "таблиця з %d рядком" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d секунду тому" -msgstr[1] "%d секунди тому" -msgstr[2] "%d секунд тому" -msgstr[3] "%d секунду тому" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d хвилину тому" -msgstr[1] "%d хвилини тому" -msgstr[2] "%d хвилин тому" -msgstr[3] "%d хвилину тому" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d годину тому" -msgstr[1] "%d години тому" -msgstr[2] "%d годин тому" -msgstr[3] "%d годину тому" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d день тому" -msgstr[1] "%d дні тому" -msgstr[2] "%d днів тому" -msgstr[3] "%d день тому" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d невідвідане посилання" -msgstr[1] "%d невідвіданих посилання" -msgstr[2] "%d невідвіданих посилання" -msgstr[3] "%d невідвідане посилання" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d відвідане посилання" -msgstr[1] "%d відвіданих посилання" -msgstr[2] "%d відвіданих посилання" -msgstr[3] "%d відвідане посилання" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "перемикнути" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "у %(index)d з %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d з %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "пункт %(index)d" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "РІВЕНЬ %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "рівень дерева %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "РІВЕНЬ ДЕРЕВА %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "подробиці щодо %s" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "містить подробиці щодо %s" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "пропозиція" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "редагований розкривний список" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "редаговані дані" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "стрічка" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "рисунок" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "анотація" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "визнання" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "післямова" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "додаток" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "елемент бібліографії" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "бібліографія" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "глава" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "вихідні дані" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "висновок" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "обкладинка" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "подяка" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "подяки" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "присвята" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "кінцева примітка" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "кінцеві примітки" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "епіграф" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "епілог" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "список друкарських помилок" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "приклад" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "преамбула" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "словник" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "покажчик" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "вступ" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "розрив сторінки" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "список сторінок" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "частина" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "передмова" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "пролог" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "помітні цитати" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "ЧАП" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "підзаголовок" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "зміст" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s рівень %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "горизонтальна смуга прокрутки" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "вертикальна смуга прокрутки" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "горизонтальний повзунок" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "вертикальний повзунок" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "горизонтальний розгалужувач" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "вертикальний розгалужувач" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "перемикач" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Панель піктограм" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "банер" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "додатковий матеріал" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "інформація" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "основний матеріал" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "навігація" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "область" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "пошук" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "відвідане посилання" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "кнопка меню" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "упорядковано за зростанням" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "упорядковано за спаданням" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "упорядковано" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "можна клацнути" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "згорнуто" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "розгорнуто" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "наявний довгий опис." - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "горизонтальна" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "вертикальна" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "позначено" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "не позначено" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "увімкнено" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "вимкнено" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "частково позначено" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "натиснуто" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "не натиснуто" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "не вибрано" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "виділена" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "не виділена" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "не вибрано" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "відвідано" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "невідвідано" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "неактивне" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "лише для читання" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "лише читання" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "треба заповнити" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "множинне виділення" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "неправильний запис" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "неправильний" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "неправильна орфографія" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "орфографія" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "неправильна граматика" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "граматика" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Знайти" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "Діалогове вікно пошуку екранного читача" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "_Закрити" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "_Знайти" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "Шука_ти:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Шукати:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "_Вгорі вікна" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Вгорі вікна" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Почати з:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Досягнувши кінця, починати спочатку" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "_Шукати назад" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "Напрямок пошуку:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "Збіг за _регістром" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Збіг за _цілими словами" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "Параметри:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Типово" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Верхній регістр" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Посилання" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Система" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Програма" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Вікно" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Параметри Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "_Довідка" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "_Застосувати" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "_Портативний" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "Розкладка клавіатури" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "Активний _профіль:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Профіль запуску:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Завантажити" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "Зберегти _як" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "Ви_лучити" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "Профілі" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "_Виводити контексті підказки" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Озвучувати об'єкт під вказівником _миші" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "Миша" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Формат _часу:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Формат _дати:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "Час і дата" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "Вимовляти _оновлення" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "Оновлення на _брайлі" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Частота (сек):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "Застосовується до:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "_Гудки оновлення" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "Оновлення смужки поступу" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "Увімкнути перемотування вперед та назад у Вимовляти все" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "Увімкнути _структурну навігацію у Вимовляти все" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Вимовляти все п_о:" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "Оголосити блоки _цитат у Вимовляти все" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "Оголосити _списки у Вимовляти все" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "Оголосити _таблиці у Вимовляти все" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "Оголосити _панелі у Вимовляти все" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "Оголосити _форми у Вимовляти все" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "Оголосити _орієнтири у Вимовляти все" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Вимовляти все" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Представлення елемента:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Загальне" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "_Гучність" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "Висота _тону:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Темп:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "_Особа:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "_Мова:" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Син_тезатор мови:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "С_истема озвучування мови:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "Тип _голосу:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "_Стиль великих літер:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "Параметри типу голосу" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Вимовляти рядки із _складених слів по складах" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "Вимовляти _числа як цифри" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "Загальні параметри голосу" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "Голос" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "_Увімкнути вимову" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "_Докладно" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "Докладність" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "_Усе" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "Рівень пунктуації" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Вимовляти лише показаний текст" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Вимовляти розриви рядків" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Вимовляти _відступи та вирівнювання" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Озвучувати _мнемоніку об'єктів" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Озвучувати дочірню _позицію" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Вимовляти повідомлення для навчання" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "_Системні повідомлення — докладні" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "Вимовляти _кольори як назви" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "Оголошувати блоки _цитат під час навігації" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "Оголошувати _списки під час навігації" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "Оголошувати _таблиці під час навігації" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "Вимовляти вказівник _неправильних слів" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "Оголошувати _панелі під час навігації" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "Оголошувати _орієнтири під час навігації" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "Оголошувати _форми під час навігації" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "Вимовляти _опис" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "Вимовляти увесь рядок у електронних _таблицях" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "Вимовляти увесь рядок у _таблицях документа" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "Вимовляти увесь рядок у _таблицях граф. інтерфейсу" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "Зміст мовлення" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Озвучення" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Увімкнути _підтримку Брайля" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "_Скорочені назви ролей" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Вимкнути символ _кінця рядка" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Таблиця _скорочень:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Ув_імкнути скорочення Брайля" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "Увімкнути п_еренесення слів" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "Параметри екрана" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "_Немає" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "Індикатор вибору" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "Індикатор гіперпосилання" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "Увімкнути вигулькні повідомлення" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "_Тривалість (у секундах):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "Повідомлення є _постійними" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "Повідомлення є _докладними" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "Параметри вигулькних повідомлень" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Брайль" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Увімкнути озвучення _клавіш" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "Увімкнути клавіші _алфавіту" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "Увімкнути _цифрові клавіші" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "Увімкнути _пунктуаційні клавіші" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "Увімкнути проб_іл" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Увімкнути клавіші-_модифікатори" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Увімкнути _функціональні клавіші" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Увімкнути клавіші _дій" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Увімкнути клавіші _переміщення" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Увімкнути озвучення с_ловами" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Увімкнути озвучення _реченнями" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "Озвучення" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "_Клавіші-модифікатори екранного читача:" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Прив'язки клавіш" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "Словник вимови" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "Н_ова стаття" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "В_илучити" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Вимова" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "Вимовити _все" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "_Не вимовляти" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "_Скинути" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "Атрибути тексту" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "В к_інець" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "На один _вниз" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "На один в_гору" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "На _початок" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "Коригувати вибраний атрибут" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "Індикатор Брайля" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Атрибути тексту" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Увімкнути помічника ШІ" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "_Постачальник:" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Локальний - Безкоштовно)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Файл ключа _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Шлях до файлу ключа API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Отримати ключ API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "" -"Відкрити браузер для отримання ключа API Claude та автоматичного збереження" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Вимагати підтвердження перед діями ШІ" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "_Модель Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Назва моделі для Ollama (напр. llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "_Кінцева точка Ollama:" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL кінцевої точки API Ollama (напр. http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Якість знімка екрана:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Низька" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Середня" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Висока" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Помічник ШІ" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Код _мови:" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Коефіцієнт _масштабування:" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Зображення у _відтінках сірого" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Інвертувати зображення" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "_Чорно-біле зображення" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Поріг чорного/білого:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Аналізувати кольори" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Копіювати результати до _буфера обміну" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : альфа, b : браво, c : чарлі, d : дельта, e : ехо, f : фокстрот, g : " -"гольф, h : хотель, i : індія, j : джульєт, k : кіло, l : ліма, m : майк, n : " -"листопад, o : оскар, p : папа, q : квебек, r : ромео, s : с'єрра, t : танго, " -"u : уніформа, v : віктор, w : віскі, x : ікс, y : янки, z : зулу, а : антін, " -"б : богдан, в : василь, г : галина, ґ : ґава, д : дмитро, е : едуард, є : " -"єва, ж : жук, з : зінаїда, и : ирід, і : іван, й : йот, к : констянтин, л : " -"левко, м : марічка, н : ніна, о : олена, п : павло, р : роман, с : сергій, " -"т : тарас, у : уляна, ф : федір, х : харитон, ц : центр, ч : чоловік, ш : " -"шура, щ : щука, ь : м'який знак, ю : юлія, я : яків" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "колір тла" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "тло у висоту рядка" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "рисунок на тлі" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "напрямок" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "редагований" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "родина шрифтів" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "колір символів" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "малюнок символів" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "стиль шрифту" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "відступ" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "помилка" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "невидимий" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "вирівнювання" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "мова" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "ліва межа" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "висота рядка" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "стиль параграфу" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "точок над рядками" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "точок під рядками" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "точок між переміщеним текстом" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "права межа" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "підйом" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "масштаб" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "розмір" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "стиснення" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "перекреслення" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "гарнітура" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "оформлення" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "обертання" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "тінь" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "підкреслення" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "варіант" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "вертикальне вирівнювання" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "вага" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "режим переносу" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "напрямок" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "увімкнено" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "вимкнено" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "відсутній" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "вдрукований" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "випуклий" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "контур" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "надкреслений" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "закреслений" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "блимальний" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "чорний" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "лінія" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "подвійна лінія" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "нижня" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "по символу" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "по слову" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "по символу слова" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "зліва направо" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "справа наліво" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "ліворуч" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "праворуч" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "у центрі" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "без вирівнювання" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "у ширину" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "дуже сильно стиснений" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "сильно стиснений" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "стиснений" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "трошки стиснений" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "звичайний" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "трохи розтиснений" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "розгорнуто" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "сильно розтиснений" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "дуже сильно розтиснений" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "малі прописні" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "скошений" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "курсив" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Типово" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Текст" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Заголовок" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "по основі" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "нижній індекс" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "верхній індекс" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "вгору" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "верх тексту" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "середина" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "низ" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "низ тексту" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "спадково" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "зліва направо та згори вниз" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "справа наліво та згори вниз" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "згори вниз та справа наліво" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "згори вниз та зліва направо" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "знизу вгору та справа наліво" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "знизу вгору та справа направо" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "зліва направо" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "справа наліво" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "згори донизу" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "суцільне" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "орфографія" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Натисніть пробіл для перемикання." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "" -"Натисніть пробіл для розкриття списку, використовуйте стрілки вгору та вниз " -"для вибору елемента." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Натисніть Alt та F6 для переходу у дочірнє вікно." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Для переміщення елементів використовуйте стрілки чи пошук під час вводу." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Для переходу у системне меню, натисніть клавіші Alt та F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Використовуйте стрілки вгору та вниз для вибору елемента." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Щоб згорнути піддерево, натисніть Shift та праворуч." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Для розкриття піддерева натисніть клавіші shift та вліво." - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "Натисніть return, щоб увімкнути." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Введіть текст." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "" -"Використовуйте клавіші ліворуч та праворуч для переходу на інші вкладки." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Для активації натисніть пробіл." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Використовуйте стрілки вгору та вниз для вибору значення. Або введіть " -"потрібне число." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Для переходу використовуйте стрілки." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Для переходу між меню використовуйте стрілки вліво та вправо. Для вибору - " -"стрілки вгору та вниз." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Для переходу у підменю, натисніть стрілку право." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Для зменшення значення натисніть стрілку ліворуч, для збільшення - праворуч. " -"Для встановлення мінімального значення натисніть Home, для максимального - " -"End." diff --git a/po/vi.po b/po/vi.po deleted file mode 100644 index 234453c..0000000 --- a/po/vi.po +++ /dev/null @@ -1,9805 +0,0 @@ -# Vietnamese translation for Cthulhu. -# Copyright © 2010 GNOME i18n Project for Vietnamese. -# Nguyễn Thái Ngọc Duy , 2007. -# Clytie Siddall , 2007-2010. -# Truong Anh Tuan , 2010. -msgid "" -msgstr "" -"Project-Id-Version: cthulhu TRUNK\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2011-04-14 18:47+0700\n" -"Last-Translator: Truong Anh Tuan \n" -"Language-Team: Vietnamese \n" -"Language: vi\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: LocFactoryEditor 1.8\n" - -msgid "Cthulhu Screen Reader" -msgstr "Trình đọc màn hình Cthulhu" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "màn hình;đọc;trợ năng;giọng nói;chữ nổi;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "báo" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "ảhoạt" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "mtên" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "lịch" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "vvẽ" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "đđề" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "kiểm" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "chmàu" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "đcột" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "thợp" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "ngày" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "hình" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "ô" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "quay" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "tho" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "ôtm" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "vẽ" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "chtập" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "điền" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "phg" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "mẫu" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "ôtỷ" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "tiđề" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "ảnh" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "kgnội" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "nhãn" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "ôtầng" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lkết" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "dsách" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "mụcds" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "tđơn" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "ttđơn" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mụctđ" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "ôtùy" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "trg" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "dstab" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "bảng" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "mậtk" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "tự_mở" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "tiếnh" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "nút" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "cmột" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "mụctdmột" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "gốc" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "đhàng" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "tcuộn" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "ôcuộn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "phần" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "tách" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "trượt" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "ôtách" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "xoay" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "tttr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "bảng" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "ô" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "rời" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "tbcuối" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "chữ" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "bật-tắt" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "ccụ" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "gợiý" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "cây" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "bcây" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "lạ" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "cxem" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "csổ" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "đầu" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "chân" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "đvăn" - -# Name: do not translate/ tên: đừng dịch -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "ứng" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "tđộng" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "chỉnh" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "nhúng" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "Séc lớp 1" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "Tây Ban Nha lớp 1" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "Pháp (Ca-na-đa) lớp 2" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "Pháp (Pháp) lớp 2" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "Lát-vi-a lớp 1" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "Hà Lan (Hà Lan) lớp 1" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "Na Uy lớp 0" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "Na Uy lớp 1" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "Na Uy lớp 2" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "Na Uy lớp 3" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "Ba Lan lớp 1" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "Bồ Đào Nha lớp 1" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "Thuỵ Điển lớp 1" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "A Rập lớp 1" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "Ouen-s lớp 1" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "Ouen-s lớp 2" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "Đức lớp 0" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "Đức lớp 1" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "Đức lớp 2" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "Anh (Quốc Anh) lớp 2" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "Anh (Quốc Anh) lớp 1" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "Anh (Mỹ) lớp 1" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "Anh (Mỹ) lớp 2" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "Pháp (Ca-na-đa) lớp 1" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "Pháp (Pháp) lớp 1" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "Hy Lạp lớp 1" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "Hin-đi lớp 1" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "" - -#: src/cthulhu/brltablenames.py:153 -#, fuzzy -msgid "Hungarian Grade 1" -msgstr "Lát-vi-a lớp 1" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "Đức lớp 2" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "Ý lớp 1" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "Hà Lan (Bỉ) lớp 1" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "dấu cách" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "dòng mới" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "dấu cảm" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "dấu trích dẫn" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "số" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "dấu đô la" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "dấu phần trăm" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "dấu và" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "dấu lược" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "dấu ngoặc đơn trái" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "dấu ngoặc đơn phải" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "dấu sao" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "dấu cộng" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "dấu phẩy" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "dấu gạch" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "dấu chấm" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "dấu xuyệc" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "dấu hai chấm" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "dấu chấm phẩy" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "ít hơn" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "dấu bằng" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "lớn hơn" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "dấu hỏi" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "dấu a còng" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "dấu ngoặc trái" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "dấu xuyệc ngược" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "dấu ngoặc phải" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "con nháy" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "gạch dưới" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "huyền" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "dấu ngoặc móc trái" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "thanh dọc" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "dấu ngoặc móc phải" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "dấu ngã" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "dấu cách không ngắt" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "dấu chấm than ngược" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "dấu đồng xu" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "dấu đồng Anh" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "dấu tiền tệ" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "dấu đồng Nhật" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "thanh bị ngắt" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "phần" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "dấu tách đôi" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "tác quyền" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "chữ a cao" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "dấu ngoặc nhọn đôi trái" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "phủ định" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "dấu nối mềm" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "dấu đăng ký" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "dấu nối ở trên" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "dấu độ" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "cộng hay trừ" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "số hai cao" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "số ba cao" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "dấu sắc" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "chữ Hy Lạp cổ « miu »" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "dấu đoạn văn" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "chấm giữa" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "dấu móc dưới" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "số 1 cao" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ký hiệu độ" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "dấu ngoặc nhọn đôi phải" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "một phần tư" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "một phần hai" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "ba phần tư" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "dấu chấm than đảo" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a sắc" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A HUYỀN" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A SẮC" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A MŨ" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A NGÃ" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A HAI CHẤM TRÊN" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A TRÒN TRÊN" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E một âm" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C MÓC DƯỚI" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E HUYỀN" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E SẮC" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E MŨ" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E HAI CHẤM TRÊN" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I HUYỀN" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I SẮC" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I MŨ" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I HAI CHẤM TRÊN" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "Ð" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N NGÃ" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O HUYỀN" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O SẮC" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O MŨ" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O NGÃ" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O HAI CHẤM TRÊN" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "nhân" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O THANH TRÊN" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U HUYỀN" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U SẮC" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U MŨ" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U HAI CHẤM TRÊN" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y SẮC" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "þ" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "dấu thăng" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a huyền" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a mũ" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a ngã" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a hai chấm trên" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a tròn trên" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e cùng chữ" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c móc dưới" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e huyền" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e sắc" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e mũ" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e hai chấm trên" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i huyền" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i sắc" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i mũ" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i hai chấm trên" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "ð" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n ngã" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o huyền" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o sắc" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o mũ" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o ngã" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o hai chấm trên" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "chia" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o thanh trên" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "Þ" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u sắc" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u huyền" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u mũ" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u hai chấm trên" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y sắc" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y hai chấm trên" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "U HAI CHẤM TRÊN" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "ƒ" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "dấu nối" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "dấu trích dẫn đơn trái" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "dấu trích dẫn đơn phải" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "dấu trích dẫn dưới đơn" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "dấu trích dẫn đôi trái" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "dấu trích dẫn đôi phải" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "dấu trích dẫn dưới đôi" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "†" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "‡" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "chấm đầu dòng" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "hình giác đầu dòng" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "trên nghìn ‰" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "′" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "″" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "″" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "dấu nối đầu dòng" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "đồng Âu €" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "nhãn hiệu" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "dấu kiểm" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "dấu kiểm đậm" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x đầu dòng" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "số 0 cao" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "số 4 cao" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "số 5 cao" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "số 6 cao" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "số 7 cao" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "số 8 cao" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "số 9 cao" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "dấu cộng cao" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "dấu trừ cao" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "dấu bằng cao" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "mở ngoặc đơn cao" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "đóng ngoặc đơn cao" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "chữ n cao" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "số 0 thấp" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "số 1 thấp" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "số 2 thấp" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "số 3 thấp" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "số 4 thấp" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "số 5 thấp" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "số 6 thấp" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "số 7 thấp" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "số 8 thấp" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "số 9 thấp" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "dấu cộng thấp" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "dấu trừ thấp" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "dấu bằng thấp" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "mở ngoặc đơn thấp" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "đóng ngoặc đơn thấp" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "vuông đen" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "thoi đen" - -#: src/cthulhu/chnames.py:806 -#, fuzzy -msgid "object replacement character" -msgstr "Đi tới ký tự kế tiếp." - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "Chuyển con trỏ sang mục hiện thời." - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "Thực hiện nhắp trái trên mục xem lại phẳng hiện có." - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "Thực hiện nhắp trái trên mục xem lại phẳng hiện có." - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "Nói toàn tài liệu." - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "Nói dòng xem lại phẳng hiện có." - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "Thực hiện thao tác cơ bản Tôi ở đâu?" - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "Thực hiện thao tác chi tiết Tôi ở đâu?" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "Nói dòng xem lại phẳng hiện có." - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "Đọc dòng trống" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "Trình bày nút mặc định" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "Nói nhãn của thanh trạng thái." - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "Nói nhãn của thanh tựa đề." - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "Mở hộp thoại Tìm." - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "Hiển thị danh sách hành động" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "Tìm chuỗi tương tự lần nữa" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "Tìm chuỗi cũ." - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "Vào và rời chế độ xem lại phẳng." - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "Chuyển điểm xem lại phẳng tới vị trí cuối." - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "Chuyển điểm xem lại phẳng về." - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "Chuyển điểm xem lại phẳng tới vị trí cuối." - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "Chuyển điểm xem lại phẳng về đầu dòng trước." - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "Nói dòng xem lại phẳng hiện có." - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "Nói theo chính tả dòng xem lại phẳng hiện tại." - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "Nói theo chính tả ngữ âm dòng xem lại phẳng hiện tại." - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "Chuyển điểm xem lại phẳng tới đầu dòng kế tiếp." - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "Chuyển điểm xem lại phẳng về mục hay từ trước đó." - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "Nói mục hay từ xem lại phẳng hiện thời." - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "Nói theo chính tả mục hay từ xem lại phẳng hiện thời." - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "Nói theo chính tả ngữ âm mục hay từ xem lại phẳng hiện thời." - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "Chuyển điểm xem lại phẳng tới mục hay từ kế tiếp." - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "Chuyển điểm xem lại phẳng lên từ trên từ hiện có." - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "Nói đối tượng xem lại phẳng hiện có." - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "Chuyển điểm xem lại phẳng xuống từ dưới từ hiện có." - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "Chuyển điểm xem lại phẳng về ký tự trước đó." - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "Nói ký tự xem lại phẳng hiện có." - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "Nói ngữ âm ký tự xem lại phẳng hiện có." - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "Nói giá trị Unicode của ký tự xem lại phẳng hiện có." - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "Chuyển điểm xem lại phẳng tới ký tự kế tiếp." - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "Chuyển điểm xem lại phẳng tới cuối dòng." - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "Chuyển điểm xem lại phẳng qua trái, góc dưới." - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "Nói mục hay từ xem lại phẳng hiện thời." - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "Nói mục hay từ xem lại phẳng hiện thời." - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "Chuyển điểm xem lại phẳng tới vị trí cuối." - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "Bật/tắt có nên đọc chỉ ô bảng hiện thời, hoặc toàn bộ hàng." - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "Đọc các thuộc tính liên quan đến ký tự chữ hiện có." - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "Kéo ngang vùng hiển thị nổi qua trái." - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "Kéo ngang vùng hiển thị nổi qua phải." - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "Trở về đối tượng có tiêu điểm bàn phím." - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "Bật/tắt chữ nổi súc tích." - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "Xử lý một phím định tuyến con trỏ." - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "Đánh dấu điểm bắt đầu lựa chọn đoạn văn." - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "Đánh dấu điểm kết thúc lựa chọn đoạn văn." - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "Vào chế độ học. Hãy bấm phím Escape để thoát khỏi chế độ học." - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "Giảm tốc độ nói tiếng." - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "Tăng tốc độ nói tiếng." - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "Giảm độ cao giọng nói." - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "Tăng độ cao giọng nói." - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "Tăng tốc độ nói tiếng." - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "Giảm tốc độ nói tiếng." - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "Chọn cài đặt giọng nói trước đó" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "Chọn cài đặt giọng nói tiếp theo" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "Giảm cài đặt giọng nói hiện tại" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "Tăng cài đặt giọng nói hiện tại" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "Lưu cài đặt giọng nói" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "Bật/tắt câm giọng nói." - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "Bật/tắt chế độ ngủ" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "Hiển thị hộp thoại cấu hình tùy thích." - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "Hiển thị hộp thoại cấu hình tùy thích của ứng dụng." - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "Đổi đọc thụt lề và canh đều." - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "Chuyển giữa các mức tần suất đọc dấu chấm." - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "Chuyển giữa các mức âm phím." - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "Chuyển giữa các mức tần suất đọc dấu chấm." - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "Chuyển giữa các mức tần suất đọc dấu chấm." - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "Chuyển giữa các mức âm phím." - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "Xoay vòng chế độ gỡ lỗi vào lúc chạy." - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "Lưu liên kết đến chỗ này tương ứng với vị trí hiện tại." - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "Về địa chỉ liên kết trước." - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "Theo liên kết lưu." - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "Đi tới địa chỉ liên kết kế tiếp." - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "Lưu liên kết" - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "Lưu các liên kết." - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "Bật/tắt chế độ xem lại con chuột." - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "Đọc giờ hiện tại." - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "Đọc ngày hiện tại." - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "Gửi lệnh kế tiếp cho ứng dụng hiện thời." - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "Nói và hiển thị bằng chữ nổi một tin nhắn phòng trò chuyện trước." - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "Bật/tắt chức năng thông báo khi bạn bè đang gõ." - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "Bật/tắt chức năng cung cấp lược sử cho mỗi phòng trò chuyện." - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "" -"Bật/tắt thêm tên của phòng trò chuyện trước tin nhắn trong phòng trò chuyện." - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "Dòng trái" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "Dòng phải" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "Dòng trên" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "Dòng dưới" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "Đông đặc" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "Trên trái" - -#: src/cthulhu/cmdnames.py:672 -#, fuzzy -msgid "Bottom Left" -msgstr "Nửa bên dưới" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "Vị trí con nháy" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "Sáu Chấm" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "Định tuyến con trỏ" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "Bắt đầu Chép" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "Kết thúc chép" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "Đọc thông báo cuối." - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "Đọc danh sách thông báo" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "Đọc thông báo trước." - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "Đọc thông báo cuối." - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "Đi tới ký tự kế tiếp." - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "Đi về ký tự trước đó." - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "Đi tới từ kế tiếp." - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "Đi về từ trước đó." - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "Đi tới dòng kế tiếp." - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "Đi về dòng trước đó." - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "Đi về đầu của tập tin." - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "Đi tới cuối của tập tin." - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "Đi về đầu của dòng." - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "Đi tới cuối của dòng." - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "Đi tới đối tượng kế tiếp." - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "Đi về đối tượng trước." - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "Gây ra hộp tổ hợp được giãn ra." - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "" -"Chuyển đổi giữa cách duyệt qua sở hữu của Gecko và kiểu dấu mũ của Oca." - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "Tăng giá trị tùy theo vùng động." - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "Tắt mức tùy theo vùng động." - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "Xem lại thông báo vùng động." - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "Theo dõi vùng động." - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "Chuyển tiêu điểm vào và ra vị trí con chuột hiện thời." - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "Đặt hàng cần dùng làm phần đầu cột động khi nói ô kiểu tính." - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "Xoá sạch các đầu cột động." - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "Đặt cột cần dùng làm phần đầu hàng động khi nói ô bảng tính." - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "Xoá sạch các đầu hàng động." - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "Đọc nội dung trên dòng nhập." - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "Bật/tắt các phím duyệt qua kiểu cấu trúc." - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "Đi về khối trích dẫn trước." - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "Đi tới khối trích dẫn kế tiếp." - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "Nhảy về nút trước." - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "Nhảy tới nút tiếp." - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "Hiển thị tùy chọn thêm" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "Nhảy về hộp chọn trước." - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "Nhảy tới hộp chọn tiếp." - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "Đi về bảng trước." - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "Đi tới bảng kế tiếp." - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "Nhảy về hộp tổ hợp trước." - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "Nhảy tới hộp tổ hợp tiếp." - -#: src/cthulhu/cmdnames.py:893 -#, fuzzy -msgid "Go to start of container" -msgstr "đồ chứa h t m l" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "đồ chứa h t m l" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "Nhảy về mục nhập trước." - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "Nhảy tới mục nhập tiếp." - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "Đi về trường mẫu trước." - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "Đi tới trường mẫu kế tiếp." - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "Đi về tiêu đề trước đó." - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "Đi tới tiêu đề kế tiếp." - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "Nhảy về tiêu đề trước ở cấp %d." - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "Nhảy tới tiêu đề tiếp ở cấp %d." - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "Không còn tiêu đầu nào nữa ở cấp %d." - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "Đi về bảng trước." - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "khung nội bộ" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "Đi về dòng trước đó." - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "Đi tới dòng kế tiếp." - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "Đi về mốc trước đó." - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "Đi tới mốc kế tiếp." - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "Đi về đối tượng lớn trước." - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "Đi tới đối tượng lớn kế tiếp." - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "Không còn đối tượng lớn nào nữa." - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "Đi về dòng trước đó." - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "Đi tới dòng kế tiếp." - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "Hiển thị tùy chọn thêm" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "Đi về danh sách trước." - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "Đi tới danh sách kế tiếp." - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "Đi về mục danh sách trước." - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "Đi tới mục danh sách kế tiếp." - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "Đi về vùng động trước đó." - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "Đi tới vùng động kế tiếp." - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "Tới vùng động cuối mà đã có thông báo." - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "Đi đến cha của đối tượng có tiêu điểm điều hướng." - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "Đi đến con đầu tiên của đối tượng có tiêu điểm điều hướng." - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "Đi đến anh chị em tiếp theo của đối tượng có tiêu điểm điều hướng." - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "Đi đến anh chị em trước đó của đối tượng có tiêu điểm điều hướng." - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "Trở về đối tượng có tiêu điểm bàn phím." - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "Bật/tắt các phím duyệt qua kiểu cấu trúc." - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "Nhảy về đoạn văn trước." - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "Nhảy tới đoạn văn tiếp." - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "Nhảy về nút chọn một trước." - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "Nhảy tới nút chọn một tiếp." - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "Không còn nút chọn một nào nữa." - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "Đi về dấu tách trước đó." - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "Đi tới dấu tách kế tiếp." - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "Đi về bảng trước." - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "Đi tới bảng kế tiếp." - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "Chuyển bên dưới theo một ô" - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "Đi về ô đầu của bảng." - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "Đi tới ô cuối của bảng." - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "Chuyển bên trái theo một ô" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "Chuyển bên phải theo một ô" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "Chuyển bên trên theo một ô" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "Bật/tắt chế độ xem lại con chuột." - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "Bật _phản hồi phím" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "Đi về liên kết chưa thăm trước." - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "Đi tới liên kết chưa thăm kế tiếp." - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "Không còn liên kết chưa thăm nào nữa." - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "Đi về liên kết đã thăm trước." - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "Đi tới liên kết đã tham kế tiếp." - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "Không còn liên kết đã thăm nào nữa." - -#: src/cthulhu/colornames.py:39 -#, fuzzy -msgctxt "color name" -msgid "alice blue" -msgstr "Màu xanh tối đa" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "" - -#: src/cthulhu/colornames.py:69 -#, fuzzy -msgctxt "color name" -msgid "black" -msgstr "đen" - -#: src/cthulhu/colornames.py:74 -#, fuzzy -msgctxt "color name" -msgid "blanched almond" -msgstr "thoi đen" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "" - -#: src/cthulhu/colornames.py:99 -#, fuzzy -msgctxt "color name" -msgid "cadet blue" -msgstr "Màu xanh tối đa" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "" - -#: src/cthulhu/colornames.py:139 -#, fuzzy -msgctxt "color name" -msgid "dark blue" -msgstr "Màu xanh tối đa" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:154 -#, fuzzy -msgctxt "color name" -msgid "dark gray" -msgstr "a huyền" - -#: src/cthulhu/colornames.py:159 -#, fuzzy -msgctxt "color name" -msgid "dark green" -msgstr "Màu lục tối đa" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "" - -#: src/cthulhu/colornames.py:174 -#, fuzzy -msgctxt "color name" -msgid "dark olive green" -msgstr "Màu lục tối đa" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "" - -#: src/cthulhu/colornames.py:189 -#, fuzzy -msgctxt "color name" -msgid "dark red" -msgstr "Màu đỏ tối đa" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "" - -#: src/cthulhu/colornames.py:199 -#, fuzzy -msgctxt "color name" -msgid "dark sea green" -msgstr "Màu lục tối đa" - -#: src/cthulhu/colornames.py:204 -#, fuzzy -msgctxt "color name" -msgid "dark slate blue" -msgstr "Màu xanh tối đa" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:234 -#, fuzzy -msgctxt "color name" -msgid "dim gray" -msgstr "i huyền" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "" - -#: src/cthulhu/colornames.py:254 -#, fuzzy -msgctxt "color name" -msgid "forest green" -msgstr "Màu lục tối thiểu" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:284 -#, fuzzy -msgctxt "color name" -msgid "gray" -msgstr "màu xám tắt" - -#: src/cthulhu/colornames.py:289 -#, fuzzy -msgctxt "color name" -msgid "green" -msgstr "dấu độ" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "" - -#: src/cthulhu/colornames.py:309 -#, fuzzy -msgctxt "color name" -msgid "indian red" -msgstr "Hin-đi lớp 1" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "" - -#: src/cthulhu/colornames.py:349 -#, fuzzy -msgctxt "color name" -msgid "light blue" -msgstr "dấu ngoặc móc phải" - -#: src/cthulhu/colornames.py:354 -#, fuzzy -msgctxt "color name" -msgid "light coral" -msgstr "ctrl phải" - -#: src/cthulhu/colornames.py:359 -#, fuzzy -msgctxt "color name" -msgid "light cyan" -msgstr "dấu ngoặc đơn phải" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "" - -#: src/cthulhu/colornames.py:369 -#, fuzzy -msgctxt "color name" -msgid "light gray" -msgstr "dấu ngoặc móc phải" - -#: src/cthulhu/colornames.py:374 -#, fuzzy -msgctxt "color name" -msgid "light green" -msgstr "dấu ngoặc đơn phải" - -#: src/cthulhu/colornames.py:379 -#, fuzzy -msgctxt "color name" -msgid "light pink" -msgstr "dấu ngoặc đơn phải" - -#: src/cthulhu/colornames.py:384 -#, fuzzy -msgctxt "color name" -msgid "light salmon" -msgstr "alt phải" - -#: src/cthulhu/colornames.py:389 -#, fuzzy -msgctxt "color name" -msgid "light sea green" -msgstr "dấu ngoặc đơn phải" - -#: src/cthulhu/colornames.py:394 -#, fuzzy -msgctxt "color name" -msgid "light sky blue" -msgstr "super phải" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "" - -#: src/cthulhu/colornames.py:409 -#, fuzzy -msgctxt "color name" -msgid "light yellow" -msgstr "mũi tên phải" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "" - -#: src/cthulhu/colornames.py:424 -#, fuzzy -msgctxt "color name" -msgid "linen" -msgstr "dòng mới" - -#: src/cthulhu/colornames.py:429 -#, fuzzy -msgctxt "color name" -msgid "magenta" -msgstr "Ảnh" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "" - -#: src/cthulhu/colornames.py:464 -#, fuzzy -msgctxt "color name" -msgid "medium slate blue" -msgstr "Màu xanh tối thiểu" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "" - -#: src/cthulhu/colornames.py:534 -#, fuzzy -msgctxt "color name" -msgid "orange red" -msgstr "Màu đỏ tối đa" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "" - -#: src/cthulhu/colornames.py:549 -#, fuzzy -msgctxt "color name" -msgid "pale green" -msgstr "Màu lục tối đa" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "" - -#: src/cthulhu/colornames.py:599 -#, fuzzy -msgctxt "color name" -msgid "red" -msgstr "end" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "" - -#: src/cthulhu/colornames.py:609 -#, fuzzy -msgctxt "color name" -msgid "royal blue" -msgstr "Màu xanh tối đa" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "" - -#: src/cthulhu/colornames.py:629 -#, fuzzy -msgctxt "color name" -msgid "sea green" -msgstr "màn hình %s" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "" - -#: src/cthulhu/colornames.py:654 -#, fuzzy -msgctxt "color name" -msgid "slate blue" -msgstr "Màu xanh tối thiểu" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "" - -#: src/cthulhu/colornames.py:674 -#, fuzzy -msgctxt "color name" -msgid "steel blue" -msgstr "Màu xanh tối thiểu" - -#: src/cthulhu/colornames.py:679 -#, fuzzy -msgctxt "color name" -msgid "tan" -msgstr "tab" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "" - -#: src/cthulhu/colornames.py:714 -#, fuzzy -msgctxt "color name" -msgid "white" -msgstr "khoảng trắng" - -#: src/cthulhu/colornames.py:719 -#, fuzzy -msgctxt "color name" -msgid "white smoke" -msgstr "khoảng trắng" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "" - -#: src/cthulhu/colornames.py:729 -#, fuzzy -msgctxt "color name" -msgid "yellow green" -msgstr "Toàn màn hình" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "Chấm _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "Chấm _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "Chấm 7 _và 8" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "" - -#: src/cthulhu/guilabels.py:131 -#, fuzzy -msgctxt "capitalization style" -msgid "Icon" -msgstr "Biểu tượng" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "Không có" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "chính tả" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "Thông báo khi _bạn bè đang gõ" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "Cung cấp lược sử _mỗi phòng chát" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "Nói mọi tin nhắn từ" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "Mọi kê_nh" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "Mọi kênh khi có một cửa sổ %s hoạt động" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "Chỉ kênh có cửa _sổ hoạt động" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "_Nói tên phòng trò chuyện" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "nhấn đúp" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "nhấn ba lần" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "Bộ tổng hợp mặc định" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "Chuỗi thật" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "Chuỗi thay thế" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "Bật phản hồi theo _ký tự" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "Bật phím chỉ thêm _dấu phụ" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "Vị trí _hiện tại" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "Độ dài văn bản khớp tối thiểu :" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "Tùy chọn tìm" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "Chỉ nói dòng nào tha_y đổi trong khi tìm" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "Nói _kết quả trong khi tìm" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "dấu phẩy" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "Tổ hợp phím" - -#: src/cthulhu/guilabels.py:280 -#, fuzzy -msgctxt "keybindings" -msgid "Default" -msgstr "Mặc định" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "chế độ viết" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "Hành động" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "Tổ hợp chữ nổi" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "Dấu trang" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "Duyệt Bảng" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "Chưa kết hợp" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "Đang rời chế độ xem lại phẳng." - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -#, fuzzy -msgctxt "keybindings" -msgid "Modified" -msgstr "Điều chỉnh" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "_Máy để bàn" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "Thông báo" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "Đã nhận" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "Thông báo %s" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "Tùy thích Cthulhu cho %s" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "Đánh dấu bằng chữ nổi" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "Đọc trừ khi" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "Nói" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "Lưu hồ sơ như một xung đột" - -#: src/cthulhu/guilabels.py:429 -#, fuzzy -msgid "User Profile Conflict!" -msgstr "Xung đột Hồ sơ Người dùng!" - -#: src/cthulhu/guilabels.py:436 -#, fuzzy, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"Hồ sơ %s đã tồn tại.\n" -"Tiếp tục cập nhật các thay đổi này và thoát khỏi hồ sơ?" - -#: src/cthulhu/guilabels.py:446 -#, fuzzy -msgid "Load user profile" -msgstr "Mở Hồ sơ Người dùng" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"Hồ sơ hiện hành như đã bị bạn thay đổi. Nếu bạn\n" -"chỉ thay đổi tùy chọn, nó sẽ bị hủy khi mở hồ sơ.\n" -"\n" -"Tiếp tục mở hồ sơ và bỏ qua các thay đổi trước đó?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "Lưu hồ sơ thành" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "Tên _hồ sơ:" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "Mở Hồ sơ Người dùng" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "Tất cả" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "Ứng dụng" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "Cửa sổ" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "Khô_ng có" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "Một _số" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "Phần _lớn" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "Dòng" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "Câu" - -#: src/cthulhu/guilabels.py:536 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "dấu trích dẫn" - -#: src/cthulhu/guilabels.py:542 -#, fuzzy -msgctxt "structural navigation" -msgid "Button" -msgstr "Nút" - -#: src/cthulhu/guilabels.py:548 -#, fuzzy -msgctxt "structural navigation" -msgid "Caption" -msgstr "Đầu đề" - -#: src/cthulhu/guilabels.py:554 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Box" -msgstr "Hộp kiểm tra" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "" - -#: src/cthulhu/guilabels.py:566 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "hộp tổ hợp" - -#: src/cthulhu/guilabels.py:572 -#, fuzzy -msgctxt "structural navigation" -msgid "Description" -msgstr "chữ n cao" - -#: src/cthulhu/guilabels.py:578 -#, fuzzy -msgctxt "structural navigation" -msgid "Heading" -msgstr "Tiêu đề" - -#: src/cthulhu/guilabels.py:584 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "Khung nội bộ" - -#: src/cthulhu/guilabels.py:590 -#, fuzzy -msgctxt "structural navigation" -msgid "Image" -msgstr "Ảnh" - -#: src/cthulhu/guilabels.py:596 -#, fuzzy -msgctxt "structural navigation" -msgid "Label" -msgstr "Nhãn" - -#: src/cthulhu/guilabels.py:604 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmark" -msgstr "nhãn hiệu" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "" - -#: src/cthulhu/guilabels.py:617 -#, fuzzy -msgctxt "structural navigation" -msgid "Link" -msgstr "Liên kết" - -#: src/cthulhu/guilabels.py:623 -#, fuzzy -msgctxt "structural navigation" -msgid "List" -msgstr "Danh sách" - -#: src/cthulhu/guilabels.py:629 -#, fuzzy -msgctxt "structural navigation" -msgid "List Item" -msgstr "Mục danh sách" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "" - -#: src/cthulhu/guilabels.py:641 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "Đoạn văn" - -#: src/cthulhu/guilabels.py:647 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "Nút chọn một" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "" - -#: src/cthulhu/guilabels.py:660 -#, fuzzy -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "được chọn" - -#: src/cthulhu/guilabels.py:667 -#, fuzzy -msgctxt "structural navigation" -msgid "State" -msgstr "Trạng thái" - -#: src/cthulhu/guilabels.py:673 -#, fuzzy -msgctxt "structural navigation" -msgid "Text" -msgstr "Văn bản" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "" - -#: src/cthulhu/guilabels.py:690 -#, fuzzy -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "Không còn khối trích dẫn nào nữa." - -#: src/cthulhu/guilabels.py:695 -#, fuzzy -msgctxt "structural navigation" -msgid "Buttons" -msgstr "Nút" - -#: src/cthulhu/guilabels.py:700 -#, fuzzy -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "Hộp kiểm tra" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "" - -#: src/cthulhu/guilabels.py:711 -#, fuzzy -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "hộp tổ hợp" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "" - -#: src/cthulhu/guilabels.py:726 -#, fuzzy -msgctxt "structural navigation" -msgid "Headings" -msgstr "Tiêu đề" - -#: src/cthulhu/guilabels.py:731 -#, fuzzy -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "Khung nội bộ" - -#: src/cthulhu/guilabels.py:736 -#, fuzzy -msgctxt "structural navigation" -msgid "Images" -msgstr "Ảnh" - -#: src/cthulhu/guilabels.py:742 -#, fuzzy, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "Không còn tiêu đầu nào nữa ở cấp %d." - -#: src/cthulhu/guilabels.py:749 -#, fuzzy -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "nhãn hiệu" - -#: src/cthulhu/guilabels.py:756 -#, fuzzy -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "Không còn đối tượng lớn nào nữa." - -#: src/cthulhu/guilabels.py:761 -#, fuzzy -msgctxt "structural navigation" -msgid "Links" -msgstr "Liên kết" - -#: src/cthulhu/guilabels.py:766 -#, fuzzy -msgctxt "structural navigation" -msgid "Lists" -msgstr "Danh sách" - -#: src/cthulhu/guilabels.py:771 -#, fuzzy -msgctxt "structural navigation" -msgid "List Items" -msgstr "Mục danh sách" - -#: src/cthulhu/guilabels.py:776 -#, fuzzy -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "Đoạn văn" - -#: src/cthulhu/guilabels.py:781 -#, fuzzy -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "Nút chọn một" - -#: src/cthulhu/guilabels.py:786 -#, fuzzy -msgctxt "structural navigation" -msgid "Tables" -msgstr "Bảng" - -#: src/cthulhu/guilabels.py:791 -#, fuzzy -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "%d liên kết chưa thăm" - -#: src/cthulhu/guilabels.py:796 -#, fuzzy -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "%d liên kết đã thăm" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "Duyệt Trang" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "Tự động _bắt đầu nói một trang mới nạp" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "Tự động _bắt đầu nói một trang mới nạp" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "Chia ra từng đ_oạn tiếng nói giữa hai lần tạm dừng" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "Giọng nói mặc định %s" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "Mặc định" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "Siêu liên kết" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "Hệ thống" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "Chữ hoa" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Bộ Phát Tiếng Nói" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "Nói toạ độ ô trong bảng tính" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "T_hông báo phần đầu ô" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "Duyệt Bảng" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "Bỏ qua ô _rỗng" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "Nó_i ô" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "Nói t_oạ độ ô" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "Nói ô th_eo nhiều hàng" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "Tên thuộc tính" - -#: src/cthulhu/guilabels.py:925 -#, fuzzy -msgid "Control caret navigation" -msgstr "Dùng khả năng duyệt qua dấu mũ _Cthulhu" - -#: src/cthulhu/guilabels.py:930 -#, fuzzy -msgid "Enable _structural navigation" -msgstr "Bật/tắt các phím duyệt qua kiểu cấu trúc." - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "_Chủ đề âm thanh:" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "Chủ đề âm thanh" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "_Ngắn" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "Thông báo" - -#: src/cthulhu/keynames.py:48 -#, fuzzy -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -#, fuzzy -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt phải" - -#: src/cthulhu/keynames.py:56 -#, fuzzy -msgctxt "keyboard" -msgid "Control" -msgstr "ctrl trái" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "Shift trái" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "alt trái" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "ctrl trái" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "shift phải" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "alt phải" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "ctrl phải" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "meta trái" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "meta phải" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "khoá chữ số" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "khoá chữ hoa" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "khoá chữ hoa" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "khoá cuộn" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "trang lên" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "trang xuống" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "Tab trái" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "xoá lùi" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "xuống dòng" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "lên" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "xuống" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "trái" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "phải" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "super trái" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "super phải" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "trình đơn" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "trợ giúp" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "đa" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "chuyển đổi chế độ" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "chèn" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "xoá" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "end" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "bắt đầu" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "dấu mũ" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "dấu vòng" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "gạch đè" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "trừ" - -#: src/cthulhu/keybindings.py:150 -#, fuzzy -msgid "Insert" -msgstr "chèn" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt phải" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt trái" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "đậm" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "nghiêng" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "chữ %s cao" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "chữ %s cao" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "Vùng làm việc " - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "Ngữ cảnh là %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "mũi tên trái" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "mũi tên" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "mũi tên phải" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "mũi tên" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "mũi tên phải" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "mũi tên phải" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "mũi tên phải" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "mũi tên trái" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "mũi tên trái" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "mũi tên phải" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "dấu trích dẫn đôi trái" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "‡" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "dấu trích dẫn đôi phải" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "‡" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "dấu trích dẫn đôi phải" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "mũi tên phải" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "đầu mũi tên phải" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "trừ" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "ít hơn" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "lớn hơn" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "dấu mũ" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "dấu chấm" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "canh lề thẳng đứng" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "nằm ngang" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "tự động điền nốt" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "rỗng" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "Bật" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "Cuối hàng." - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "dưới" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "cộng hay trừ" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "dấu cộng" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "trừ" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "bộ tách" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "căn bậc ba" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "Tỷ lệ" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "vô hạn" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "alt phải" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "đơn" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "ô sắp từng tầng" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "canh lề thẳng đứng" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "chia" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "Bộ tách" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "không bằng" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "phủ định" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "phủ định" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "hướng" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -#, fuzzy -msgctxt "math symbol" -msgid "integral" -msgstr "khung nội bộ" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "″" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -#, fuzzy -msgctxt "math symbol" -msgid "proportion" -msgstr "Tỷ lệ" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "trừ" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "dấu ngã" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n ngã" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n ngã" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "gần bằng" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "gần bằng" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "gần bằng" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "gần bằng" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "gần bằng" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "gần bằng" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "nhấn ba lần" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "gần bằng" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "trang chủ khác" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "không bằng" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "dấu bằng" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "dấu bằng" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "không bằng" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "không bằng" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "hình giác đầu dòng" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "dấu bằng" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "không bằng" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "không bằng" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "thẳng đứng" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "không bằng" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "không bằng" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "lớn hơn" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "chưa bấm" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "số 0 thấp" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "chữ a cao" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "đa chọn" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "sắp thẳng" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "đa chọn" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "dấu bằng thấp" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "dấu nối" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "dấu cộng thấp" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "dấu trừ thấp" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "meta phải" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "Tab trái" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "xuống" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "phần" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "đúng" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "đúng" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ký hiệu độ" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "ảnh" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "đa" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -#, fuzzy -msgctxt "math symbol" -msgid "intercalate" -msgstr "khung nội bộ" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "chuẩn" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "dấu trích dẫn đơn phải" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "dấu ngoặc móc phải" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "bộ tách" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "phủ định" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "phủ định" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "″" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "″" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "hướng" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "″" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "ít hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "lớn hơn hay bằng" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "canh lề thẳng đứng" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "dấu ngoặc đơn trái" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "dấu ngoặc đơn phải" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "alt trái" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "alt phải" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "dấu ngoặc móc trái" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "dưới" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "dấu ngoặc nhọn đôi trái" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "dấu ngoặc nhọn đôi phải" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "chấm giữa" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "căn bậc hai" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "vuông đen" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "vuông trắng" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "thoi đen" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "tròn trắng" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "tròn đen" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "chấm trắng đầu dòng" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "vuông đen" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "gạch dưới" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "canh lề thẳng đứng" - -#: src/cthulhu/messages.py:45 -#, fuzzy -msgctxt "generic name" -msgid "application" -msgstr "ứng dụng" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "trắng" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "đậm" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "liên kết đã lưu" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "liên kết đã lưu vào đĩa" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "không thể lưu liên kết" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "Không tìm thấy." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "Không tìm thấy." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "Chế độ đi vòng đã bật." - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "Không thể hiển thị bàn tính" - -#: src/cthulhu/messages.py:107 -#, fuzzy -msgctxt "capitalization style" -msgid "icon" -msgstr "biểu tượng" - -#: src/cthulhu/messages.py:117 -#, fuzzy -msgid "Capitalization style set to icon." -msgstr "Không đọc dấu chấm." - -#: src/cthulhu/messages.py:127 -#, fuzzy -msgctxt "capitalization style" -msgid "none" -msgstr "không có" - -#: src/cthulhu/messages.py:137 -#, fuzzy -msgid "Capitalization style set to none." -msgstr "Không đọc dấu chấm." - -#: src/cthulhu/messages.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "spell" -msgstr "chính tả" - -#: src/cthulhu/messages.py:157 -#, fuzzy -msgid "Capitalization style set to spell." -msgstr "Đọc tất cả dấu chấm." - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "Gecko đang điều khiển dấu mũ." - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu đang điều khiển dấu mũ." - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "Ô %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "được chọn" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "chưa chọn" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "Ngăn cản dùng tùy chọn" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "Ép buộc dùng tùy chọn" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -#, fuzzy -msgid "The following are not valid: " -msgstr "Các tham số sau không hợp lệ:" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "In những ứng dụng được biết là vẫn chạy" - -#: src/cthulhu/messages.py:237 -#, fuzzy -msgid "Load profile" -msgstr "Mở Hồ sơ Người dùng" - -#: src/cthulhu/messages.py:244 -#, fuzzy, python-format -msgid "Profile could not be loaded: %s" -msgstr "không thể lưu liên kết" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "Dùng thư mục xen kẽ cho tùy thích người dùng" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "In những ứng dụng được biết là vẫn chạy" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "Thay thế phiên bản Cthulhu hiện đang chạy" - -#: src/cthulhu/messages.py:286 -#, fuzzy -msgid "Show this help message and exit" -msgstr "Hiển thị trợ giúp này" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "Gửi kết xuất gỡ lỗi cho tập tin debug-NNĂM-TG-NG-GI:PH:GY.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "Gửi kết xuất gỡ lỗi cho tập tin đưa ra" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "Thiết lập tùy thích người dùng (kiểu văn bản)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "Thiết lập tùy thích người dùng (kiểu văn bản)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "Hãy thông báo lỗi nào cho ." - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "dấu sắc" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "nhanh hơn." - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "Không thông báo khi bạn bè đang gõ." - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "thông báo khi bạn bè đang gõ." - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "Tin nhắn từ phòng chát %s" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "Thẻ chát mới %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "Không nói tên của phòng chát." - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "nói tên của phòng chát." - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "Không cung cấp lược sử mỗi phòng chát" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "Cung cấp lược sử mỗi phòng chát." - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "xoá" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "chèn" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "dấu hỏi" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "Kết thúc bảng" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "Không phải trong bảng." - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "chưa chọn" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "Nút mặc định là %s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "Nút mặc định là %s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "Nút mặc định là %s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "chữ %s cao" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "chữ %s cao" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "Không phải trong bảng." - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "toàn bộ tài liệu đã chọn" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "toàn bộ tài liệu đã chọn" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "tài liệu được chọn từ vị trí con trỏ" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "tài liệu bị bỏ chọn từ vị trí con trỏ" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "tài liệu được chọn đến vị trí con trỏ" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "tài liệu bị bỏ chọn đến vị trí con trỏ" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "Phần đầu cột động đã đặt cho hàng %d" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "Phần đầu cột động bị xoá." - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "Phần đầu hàng động đã đặt cho cột %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "Phần đầu hàng động bị xoá." - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "rỗng" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f kilôbyte" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f megabyte" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "Không tìm ra." - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "" - -#: src/cthulhu/messages.py:627 -#, fuzzy -msgid "Not using flat review." -msgstr "Đang vào chế độ xem lại phẳng." - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "Đang vào chế độ xem lại phẳng." - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "Đang rời chế độ xem lại phẳng." - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "Chuyển điểm xem lại phẳng lên từ trên từ hiện có." - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "Xem phẳng không giới hạn" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "có công thức" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "hộp thoại" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -#, fuzzy -msgid "opens menu" -msgstr "trình đơn tự mở" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "liên kết sơ đồ ảnh" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "Bạn đã nhập một phím đã đóng kết với %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "Đã bắt phím: %s. Nhấn enter để xác nhận." - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "Phím mới là: %s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "Tổ hợp phím bị xoá. Nhấn phím Enter để xác nhận." - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "Tổ hợp phím đã bị xoá." - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "nhập phím mới" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "phím" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "Âm phím đặt thành phím." - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "Không có" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "Âm phím đặt thành rỗng." - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "phím và từ" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "Âm phím đặt thành phím và từ." - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "câu" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "Âm phím đặt thành câu." - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "từ" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "Âm phím đặt thành từ." - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "từ và câu" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "Âm phím đặt thành từ và câu." - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "tròn đen" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "nằm ngang" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "thanh dọc" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "mũi tên phải" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "Cuộn đến đáy." - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "bề cao dòng" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "dấu và" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "gạch trên" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "căn bậc hai" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "căn bậc ba" - -#: src/cthulhu/messages.py:1089 -#, fuzzy -msgid "root of" -msgstr "ô gốc" - -#: src/cthulhu/messages.py:1098 -#, fuzzy -msgid "root start" -msgstr "ô gốc" - -#: src/cthulhu/messages.py:1104 -#, fuzzy -msgid "root end" -msgstr "ô gốc" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "số 0 thấp" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "chữ a cao" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "số 0 thấp" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "chữ a cao" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "chữ a cao" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "chữ a cao" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "bảng" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "bảng cây" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "không tới được" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "Tắt" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "Tắt đọc thụt lề và canh đều." - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "Bật" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "Bật đọc thụt lề và canh đều." - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "Chế độ học. Hãy bấm phim Escape để thoát." - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "hoạt ảnh" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "Duyệt Trang" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "Duyệt Bảng" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "Đang rời chế độ xem lại phẳng." - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "rời bảng." - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "dòng được chọn bên dưới vị trí con trỏ" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "dòng được chọn bên trên vị trí con trỏ" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "dòng bị bỏ chọn bên dưới vị trí con trỏ" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "dòng bị bỏ chọn bên trên vị trí con trỏ" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "Đang thoát khỏi chế độ học." - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "dòng được chọn bên trái vị trí con trỏ" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "dòng được chọn bên phải vị trí con trỏ" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "liên kết" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "cùng trang" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "cùng trang chủ" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "trang chủ khác" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "liên kết %(uri)s đến tập tin %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "liên kết %s" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d liên kết đã thăm" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "Nhấn Lên và Xuống để chuyển trong danh sách. Nhấn Escape để thoát." - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "Mọi vùng động đã bị tắt" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "mọi vùng động có mức tùy theo gốc" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "mức tùy theo %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "đang đặt vùng động thành khẳng định" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "đang đặt vùng động thành bị tắt" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "đang đặt vùng động thành tùy theo" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "đang đặt vùng động thành không tùy theo" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "Theo dõi vùng động bị tắt" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "Theo dõi vùng động đã bật" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "không có thông điệp động được lưu" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "Hỗ trợ vùng động bị tắt" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "Không tìm thấy" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "Không tìm thấy vị trí hiện thời." - -#: src/cthulhu/messages.py:1666 -#, fuzzy -msgctxt "locking key state" -msgid "off" -msgstr "tắt" - -#: src/cthulhu/messages.py:1673 -#, fuzzy -msgctxt "locking key state" -msgid "on" -msgstr "bật" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "sai chính tả" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "Từ sai chính tả : %s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "Ngữ cảnh là %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "" - -#: src/cthulhu/messages.py:1717 -#, fuzzy -msgid "Focus mode" -msgstr "Chế độ danh sách phím tắt." - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "" - -#: src/cthulhu/messages.py:1771 -#, fuzzy -msgid "Layout mode." -msgstr "Chế độ danh sách phím tắt." - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "Đi tới đối tượng kế tiếp." - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "Không tìm thấy con chuột ở trên đối tượng." - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "Con chuột tăng cường bị tắt." - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "Con chuột tăng cường đã bật." - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "Không có con." - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "%d phần trăm." - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "Đi về từ trước đó." - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "Cấp lồng nhau %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "Mục mới đã được thêm vào" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "Không có ứng dụng có tiêu điểm." - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "Không có tiêu điểm" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "Không có ứng dụng có tiêu điểm." - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "Không còn khối trích dẫn nào nữa." - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "Không còn nút nào nữa." - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "Không còn hộp chọn nào nữa." - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "Không còn đối tượng lớn nào nữa." - -#: src/cthulhu/messages.py:1893 -#, fuzzy -msgid "No more clickables." -msgstr "Không còn bảng nào nữa." - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "Không còn hộp tổ hợp nào nữa." - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "Không còn mục nhập nào nữa." - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "Không còn trường mẫu nào nữa." - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "Không còn tiêu đề nào nữa." - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "Không còn tiêu đầu nào nữa ở cấp %d." - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "khung nội bộ" - -#: src/cthulhu/messages.py:1929 -#, fuzzy -msgid "No more images." -msgstr "Không còn bảng nào nữa." - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "Không tìm thấy." - -#: src/cthulhu/messages.py:1940 -#, fuzzy -msgid "No more links." -msgstr "Không còn danh sách nào nữa." - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "Không còn danh sách nào nữa." - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "Không còn mục danh sách nào nữa." - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "Không có vùng động nào nữa." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "Không còn đoạn văn nào nữa." - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "Không còn nút chọn một nào nữa." - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "Không còn dấu tách nào nữa." - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "Không còn bảng nào nữa." - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "Không còn liên kết chưa thăm nào nữa." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "Không còn liên kết đã thăm nào nữa." - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "chưa chọn" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "Không phải trong bảng." - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "Thông báo" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "Dưới:" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "Trên:" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "Không có thông báo" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "từ" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "Nói chuỗi đa từ th_eo từ" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "tắt" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "bật" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "Đang nạp. Vui lòng chờ." - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "Hoàn tất nạp." - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "Hoàn tất nạp %s." - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "trang được chọn từ vị trí con trỏ" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "trang được chọn đến vị trí con trỏ" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "trang bị bỏ chọn từ vị trí con trỏ" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "trang bị bỏ chọn đến vị trí con trỏ" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "đoạn văn được chọn bên dưới vị trí con trỏ" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "đoạn văn được chọn bên trên vị trí con trỏ" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "đoạn văn bị bỏ chọn bên dưới vị trí con trỏ" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "đoạn văn bị bỏ chọn bên trên vị trí con trỏ" - -#: src/cthulhu/messages.py:2127 -#, fuzzy -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"Bạn đã mở một hộp thoại tùy thích Cthulhu.\n" -"\n" -"Hãy đóng nó trước khi mở cái mới." - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "slide %(position)d trên %(count)d" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "" - -#: src/cthulhu/messages.py:2146 -#, fuzzy -msgid "No profiles found." -msgstr "Không tìm ra." - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "Thanh tiến hành %d." - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "Tất cả" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "Đọc tất cả dấu chấm." - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "Phần lớn" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "Đọc phần lớn dấu chấm." - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "Không có" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "Không đọc dấu chấm." - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "Một vài" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "Đọc một vài dấu chấm." - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "Đang tìm." - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "Tìm kiếm hoàn tất." - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "Đã tải lại cài đặt Cthulhu." - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "Ngữ cảnh là %s" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "Hàng đã xoá." - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "Chọn giọng nói đã muốn:" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "chưa chọn" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "Tiếng nói bị tắt." - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "Tiếng nói đã bật." - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "nhanh hơn." - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "chậm hơn." - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "cao hơn." - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "thấp hơn." - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "nhanh hơn." - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "Tốc độ %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "Cao độ %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "Âm lượng %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Mô-đun Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Giọng Speech-dispatcher %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "Không có mô-đun Speech-dispatcher nào khả dụng" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "Không có giọng Speech-dispatcher nào khả dụng" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "Đã lưu cài đặt giọng nói" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "Không thể lưu cài đặt giọng nói" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " chấm chấm chấm" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu chào mừng bạn." - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu rình rập dưới những con sóng." - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "Đã bật chế độ ngủ cho %s" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "Đã tắt chế độ ngủ cho %s" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "Tiếng nói không sẵn sàng." - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "Không tìm thấy" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "Không tìm thấy" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "không tìm thấy" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "Các phím duyệt qua kiểu cấu trúc bị tắt." - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "Các phím duyệt qua kiểu cấu trúc đã bật." - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "Không tìm thấy" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "Hàng %(row)d, cột %(column)d." - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "Kết thúc bảng" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "Nói ô" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "Nói hàng" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "Không đều" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "Không phải trong bảng." - -#: src/cthulhu/messages.py:2408 -#, fuzzy -msgid "Columns reordered" -msgstr "Đầu cột" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "cột %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "cột %(index)d của %(total)d" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "Cuối cột." - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "Đầu cột." - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "chưa chọn" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "chưa chọn" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "hàng %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "hàng %(index)d của %(total)d" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "Đầu hàng." - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "Cuối hàng." - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "Hàng đã xoá." - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "Dòng cuối đã bị xóa." - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "Hàng đã chèn." - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "Hàng đã chèn vào cuối bảng." - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "Hàng đã xoá." - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "chưa chọn" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "được chọn" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "chưa chọn" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H giờ, %M phút và %S giây." - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H giờ và %M phút." - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu phiên bản %s." - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "khoảng trắng" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "Cuộn đến đáy." - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "Cuộn đến đỉnh." - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 mục" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "Ô nối %d hàng" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d cột" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "Ô nối %d cột" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "quá dài theo %d ký tự" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d hộp thoại)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d hộp thoại không có tiêu điểm" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d byte" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "Tìm thấy %d tập tin" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d mẫu" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d phần đầu" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d mục" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "Không tìm thấy." - -#: src/cthulhu/messages.py:2667 -#, fuzzy, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "Tìm thấy %d tập tin" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "Không còn khối trích dẫn nào nữa." - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "Đang rời chế độ xem lại phẳng." - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "Danh sách có %d mục" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "Danh sách có %d mục" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "Bảng %d hàng" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d cột" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "Bảng %d hàng" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d thông báo.\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "%d phần trăm." - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "%d phần trăm tài liệu đã đọc" - -#: src/cthulhu/messages.py:2771 -#, fuzzy, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "điểm ảnh" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s ký tự" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(index)d của %(total)d mục được chọn" - -#: src/cthulhu/messages.py:2793 -#, fuzzy, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "Tìm thấy %d phím tắt Cthulhu ngầm định." - -#: src/cthulhu/messages.py:2801 -#, fuzzy, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "Tìm thấy %(count)d phím tắt Cthulhu cho %(application)s." - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d dấu cách" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d tab" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d bảng" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "Bảng %d hàng" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "Bảng %d hàng" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "Bảng %d hàng" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d liên kết chưa thăm" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d liên kết đã thăm" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "bật/tắt" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "trên %(index)d của %(total)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(index)d của %(total)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "CẤP %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "cấp cây %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "CẤP CÂY %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "dấu hỏi" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "hộp tổ hợp" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "nội dung HTML" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "từ" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "dấu hai chấm" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "gạch trên" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "hướng" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -#, fuzzy -msgctxt "role" -msgid "epigraph" -msgstr "đoạn văn" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "từ" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "thụt lề" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "hướng" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "danh sách tab" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "dấu trích dẫn" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "nội dung HTML" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s cấp %(level)d" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "nằm ngang" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "thanh dọc" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "nằm ngang" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "canh lề thẳng đứng" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "nằm ngang" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "canh lề thẳng đứng" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "chuyển đổi chế độ" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "Bảng biểu tượng" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -#, fuzzy -msgctxt "role" -msgid "complementary content" -msgstr "nội dung HTML" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "Hoạt ảnh" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "nội dung HTML" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "Hoạt ảnh" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "Đang tìm." - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d liên kết đã thăm" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "nút xoay" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "đã co lại" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "đã giãn ra" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "nằm ngang" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "thẳng đứng" - -#: src/cthulhu/object_properties.py:522 -#, fuzzy -msgctxt "checkbox" -msgid "checked" -msgstr "đã kiểm tra" - -#: src/cthulhu/object_properties.py:525 -#, fuzzy -msgctxt "checkbox" -msgid "not checked" -msgstr "chưa kiểm tra" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr "bật" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr "tắt" - -#: src/cthulhu/object_properties.py:536 -#, fuzzy -msgctxt "checkbox" -msgid "partially checked" -msgstr "chọn một phần" - -#: src/cthulhu/object_properties.py:539 -#, fuzzy -msgctxt "togglebutton" -msgid "pressed" -msgstr "đã bấm" - -#: src/cthulhu/object_properties.py:542 -#, fuzzy -msgctxt "togglebutton" -msgid "not pressed" -msgstr "chưa bấm" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "chưa chọn" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "được chọn" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "chưa chọn" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "chưa chọn" - -#: src/cthulhu/object_properties.py:558 -#, fuzzy -msgctxt "link state" -msgid "visited" -msgstr "%d liên kết đã thăm" - -#: src/cthulhu/object_properties.py:561 -#, fuzzy -msgctxt "link state" -msgid "unvisited" -msgstr "%d liên kết chưa thăm" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "màu xám tắt" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "chỉ đọc" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "chỉ_đọc" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "yêu cầu" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "đa chọn" - -#: src/cthulhu/object_properties.py:600 -#, fuzzy -msgctxt "error" -msgid "invalid entry" -msgstr "không hợp lệ" - -#: src/cthulhu/object_properties.py:607 -#, fuzzy -msgctxt "error" -msgid "invalid" -msgstr "không hợp lệ" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "chính tả" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "chính tả" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "không hợp lệ" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "Tìm" - -#: src/cthulhu/cthulhu-find.ui:13 -#, fuzzy -msgid "Screen Reader Find Dialog" -msgstr "Bộ đọc màn hình và kính lúp" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -#, fuzzy -msgid "_Close" -msgstr "Đóng" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -#, fuzzy -msgid "_Find" -msgstr "Tìm" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "_Tìm:" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "Tìm:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "Đỉ_nh cửa sổ" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "Đỉnh cửa sổ" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "Bắt đầu từ:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "_Cuộn lại" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "Tìm _ngược" - -#: src/cthulhu/cthulhu-find.ui:263 -#, fuzzy -msgid "Search direction:" -msgstr "hướng" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "_Phân biệt hoa/thường" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "Tìm _nguyên từ" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "Tùy chọn tìm" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "Mặc định" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "Chữ hoa" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "Siêu liên kết" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "Hệ thống" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "Ứng dụng" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "Cửa sổ" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Tùy thích Cthulhu" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "Máy _xách tay" - -#: src/cthulhu/cthulhu-setup.ui:294 -#, fuzzy -msgid "Keyboard Layout" -msgstr "Bố trí bàn phím" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "_Hồ sơ hiện hành:" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "Hồ sơ khởi nạp:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "_Nạp" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -#, fuzzy -msgid "Save _As" -msgstr "Lưu hồ sơ thành" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -#, fuzzy -msgid "Profiles" -msgstr "Hồ sơ" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "Đọc _gợi ý" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "Nói đối tượng nằm dưới ch_uột" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "Định dạng _Thời gian:" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "Định dạng _ngày tháng:" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "_Nói tất cả" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "Tổ hợp chữ nổi" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "Tần số (giây):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "Ứng dụng" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -#, fuzzy -msgid "Progress Bar Updates" -msgstr "Cập nhật thanh tiến hành" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "Bật/tắt các phím duyệt qua kiểu cấu trúc." - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "Nói tất cả th_eo :" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "Nói tất cả th_eo :" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "_Trình bày phần tử:" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "Chung" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "Âm _lượng:" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "C_ao:" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "_Tỷ lệ:" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "N_gười:" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "ngôn ngữ" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "Bộ tổng hợ_p tiếng nói:" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "Hệ thống tiếng _nói:" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -#, fuzzy -msgid "_Voice type:" -msgstr "Thiết lập giọng _nói:" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -#, fuzzy -msgid "Voice Type Settings" -msgstr "Thiết lập giọng _nói:" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "Nói chuỗi đa từ th_eo từ" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -#, fuzzy -msgid "Global Voice Settings" -msgstr "Thiết lập giọng _nói:" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "Bật _nói" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "Ch_i tiết" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -#, fuzzy -msgid "Verbosity" -msgstr "Độ chi tiết" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "Tất _cả" - -#: src/cthulhu/cthulhu-setup.ui:1758 -#, fuzzy -msgid "Punctuation Level" -msgstr "Tần suất đọc dấu chấm" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "Chỉ đọc văn bản đang xem" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "Đọc dòng trống" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "Cũng nó_i sự thụt lề và canh đều" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "Nói phím gọi nhớ _về đối tượng" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "Nói vị trí _phụ" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "Nói thông điệp trợ lý" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "Nói t_oạ độ ô" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "Nói t_oạ độ ô" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "Nói vị trí _phụ" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "Tiếng nói" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "Bật khả năng _hỗ trợ chữ nổi" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "Tên v_ai viết tắt" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "Tắt _ký hiệu kết thúc dòng" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "Bảng _từ rút gọn:" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "Bật chữ nổi _rút gọn" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "Bật _viền" - -#: src/cthulhu/cthulhu-setup.ui:2336 -#, fuzzy -msgid "Display Settings" -msgstr "Hiển thị tùy chọn thêm" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "Khô_ng có" - -#: src/cthulhu/cthulhu-setup.ui:2503 -#, fuzzy -msgid "Selection Indicator" -msgstr "Cái chỉ vùng chọn" - -#: src/cthulhu/cthulhu-setup.ui:2603 -#, fuzzy -msgid "Hyperlink Indicator" -msgstr "Cái chỉ siêu liên kết" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -#, fuzzy -msgid "Enable flash _messages" -msgstr "Bật _kính lúp" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "Chữ nổi" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "Bật _phản hồi phím" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "Bật phím du_yệt qua" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "Bật phí_m sửa đổi" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "Bật phím chức _năng" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "Bật _nói" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "Bật phí_m sửa đổi" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "Bật phím chức _năng" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "Bậ_t phím hành động" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "Bật phím du_yệt qua" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "Bật phản hồi th_eo từ" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "Bật phản hồi theo câ_u" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "Phản hồi phím" - -#: src/cthulhu/cthulhu-setup.ui:3026 -#, fuzzy -msgid "Screen Reader _Modifier Key(s):" -msgstr "Bộ đọc màn hình và kính lúp" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "Tổ hợp bàn phím" - -#: src/cthulhu/cthulhu-setup.ui:3143 -#, fuzzy -msgid "Pronunciation Dictionary" -msgstr "Từ điển Phát âm" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "_Mục mới" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "_Xoá" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "Phát âm" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "_Nói tất cả" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "Không _nói" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "Đặt _lại" - -#: src/cthulhu/cthulhu-setup.ui:3322 -#, fuzzy -msgid "Text attributes" -msgstr "Thuộc tính văn bản" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "Chuyển xuống _dưới" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "Chuyển _xuống một" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "Chuyển _lên một" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "Chuyển lên _trên" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "" -"Điều chỉnh các\n" -"thuộc tính đã chọn." - -#: src/cthulhu/cthulhu-setup.ui:3522 -#, fuzzy -msgid "Braille Indicator" -msgstr "Cái chỉ chữ nổi" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "Thuộc tính văn bản" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "Bật Trợ lý AI" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "Nhà cung cấp(_P):" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (Cục bộ - Miễn phí)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "Tập tin khóa _API:" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "Đường dẫn đến tập tin khóa API" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "Lấy Khóa API _Claude" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "Mở trình duyệt để lấy khóa API Claude và lưu tự động" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "Yêu cầu xác nhận trước các hành động AI" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Mô hình Ollama(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Tên mô hình cho Ollama (ví dụ: llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Điểm cuối Ollama(_E):" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "URL điểm cuối API Ollama (ví dụ: http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "_Chất lượng ảnh chụp màn hình:" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "Thấp" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "Trung bình" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "Cao" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "Trợ lý AI" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "Mã ngôn ngữ(_L):" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "Hệ số tỷ lệ(_S):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "Ảnh _Thang độ xám" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "_Đảo ngược ảnh" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "Ảnh _Đen trắng" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "_Ngưỡng Đen/Trắng:" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "_Phân tích màu sắc" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "Sao chép kết quả vào _bộ nhớ tạm" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "màu nền" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "bề cao đầy nền" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "chấm lên nền" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "hướng" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "sửa được" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "họ" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "màu cảnh gần" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "chấm lên cảnh gần" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "hiệu ứng phông chữ" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "thụt lề" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "lỗi" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "vô hình" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "sắp thẳng" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "ngôn ngữ" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "lề bên trái" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "bề cao dòng" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "kiểu dáng đoạn văn" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "điểm ảnh bên trên dòng" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "điểm ảnh dưới dòng" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "điểm ảnh bên trong dòng cuộn" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "lề bên phải" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "nâng" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "tỷ lệ" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "kích cỡ" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "giãn" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "gạch đè" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "kiểu dáng" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "trang trí chữ" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "xoay chữ" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "bóng chữ" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "gạch dưới" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "biến thể" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "canh lề thẳng đứng" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "độ đậm" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "chế độ cuộn" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "chế độ viết" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "đúng" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "sai" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "không có" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "khắc" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "chạm nổi" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "nét ngoài" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "gạch trên" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "gạch qua" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "nháy" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "đen" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "đơn" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "đôi" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "thấp" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "ký tự" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "từ" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "ngắt theo từ" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "ltr" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "rtl" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "trái" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "phải" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "giữa" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "không sắp thẳng" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "tô đầy" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "rất hẹp" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "rất hẹp" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "hẹp" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "bán hẹp" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "chuẩn" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "bán mở rộng" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "mở rộng" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "rất mở rộng" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "cực mở rộng" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "chữ hoa nhỏ" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "xiên" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "nghiêng" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "Mặc định" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "Thân văn bản" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "Tiêu đề" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "đường cơ bản" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "dưới" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "siêu" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "trên" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "trên văn bản" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "giữa" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "dưới" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "dưới văn bản" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "kế thừa" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "đặc" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "chính tả" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "Bấm phím dài để bật/tắt." - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "Bấm phím dài để mở rộng, bấm mũi tên trên và dưới để chọn mục." - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "Bấm tổ hợp phím Alt+F6 để đặt tiêu điểm trong cửa sổ con." - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "" -"Để chuyển sang mục, dùng hoặc phím mũi tên hoặc chức năng tìm kiếm theo " -"chuỗi gõ." - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "Để vào trình đơn hệ thống, bấm tổ hợp phím Alt+F1." - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "Dùng mũi tên trên và dưới để chọn mục." - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "Để co lại, bấm đồng thời phím dài và mũi tên bên trái." - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "Để mở rộng, bấm đồng thời phím dài và mũi tên bên phải." - -#: src/cthulhu/tutorialgenerator.py:397 -#, fuzzy -msgid "To activate press return." -msgstr "Để kích hoạt, bấm phím dài." - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "Gõ chuỗi." - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "Dùng phím mũi tên bên trên/phải để xem các thanh khác." - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "Để kích hoạt, bấm phím dài." - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "" -"Dùng phím mũi tên bên trên/dưới để chọn giá trị. Hoặc gõ giá trị thuộc số đã " -"muốn." - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "Dùng phím mũi tên để thay đổi." - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "" -"Để duyệt qua, bấm phím mũi tên bên trái/phải. Để chuyển qua các mục, bấm mũi " -"tên bên trên/dưới." - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "Để vào trình đơn con, bấm phím mũi tên bên phải." - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "" -"Để giảm, bấm phím mũi tên bên trái; để tăng, bấm phím mũi tên bên phải. Để " -"xuống tối thiểu, bấm phím Home, lên tối đa thì bấm phím End." diff --git a/po/zh_CN.po b/po/zh_CN.po deleted file mode 100644 index d5f8c8b..0000000 --- a/po/zh_CN.po +++ /dev/null @@ -1,9161 +0,0 @@ -# Simplified Chinese translation for cthulhu. -# Copyright (C) 2004-2019 cthulhu's COPYRIGHT HOLDER -# This file is distributed under the same license as the cthulhu package. -# Li Shaojie ,2004. -# QAed by Funda Wang , 2008. -# Ray Wang , 2008, 2010. -# vicwjb , 2010. -# Dean Lee , 2010. -# Wei Li , 2011. -# YunQiang Su , 2010, 2011, 2012. -# Boyuan Yang <073plan@gmail.com>, 2016. -# Mandy Wang , 2017. -# Mingcong Bai , 2017, 2018. -# Dingzhong Chen , 2019. -# lumingzh , 2022. -# -msgid "" -msgstr "" -"Project-Id-Version: cthulhu master\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2023-09-01 16:31+0800\n" -"Last-Translator: Eni \n" -"Language-Team: Chinese - China \n" -"Language: zh_CN\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.3.2\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu 屏幕阅读器" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "屏幕;阅读器;无障碍;语音;盲文;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -# 这一段是给盲文用的。汉语拼音的盲文方式参见 https://zh.wikipedia.org/wiki/%E7%9B%B2%E6%96%87#.E4.B8.AD.E5.9C.8B.E5.A4.A7.E9.99.B8,总之大概一个音节占两格,标上声调就是三个了。 -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "form" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "单选框" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "提示" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "自动" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "捷克语(一级)" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "西班牙语(一级)" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "加拿大法语(二级)" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "法国法语(二级)" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "拉脱维亚语(一级)" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "荷兰语(一级)" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "挪威语(零级)" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "挪威语(一级)" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "挪威语(二级)" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "挪威语(第三级)" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "波兰语(一级)" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "葡萄牙语(一级)" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "瑞典语(一级)" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "阿拉伯语(一级)" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "威尔士语(一级)" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "威尔士语(二级)" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "德语(零级)" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "德语(一级)" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "德语(二级)" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "英式英语(二级)" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "英式英语(一级)" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "美式英语(一级)" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "美式英语(二级)" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "加拿大法语(一级)" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "法国法语(一级)" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "希腊语(一级)" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "印地语(一级)" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "匈牙利 8 点计算机" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "匈牙利语(一级)" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "匈牙利语(二级)" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "意大利语(一级)" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "比利时荷兰语(一级)" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "空格" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "新行" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "制表符" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "感叹号" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "双引号" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "数字符号" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "美元符号" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "百分号" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "和" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "撇号" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "左圆括号" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "右圆括号" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "星号" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "加号" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "逗号" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "破折号" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "点" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "斜线" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "冒号" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "分号" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "小于号" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "等号" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "大于号" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "问号" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "左方括号" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "反斜线" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "右方括号" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "脱字符" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "下划线" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "抑音符" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "左花括号" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "竖线" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "右花括号" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "波浪号" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "不间断空格" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "倒感叹号" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "美分号" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "英镑号" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "货币符号" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "元" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "竖杠" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "章节号" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "间断" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "版权符号" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "上标 a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "左书名号" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "逻辑非符号" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "软连字符" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "注册商标符号" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "长音符号" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "度" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "正负" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "上标 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "上标 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "高音" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "µ" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "段落标记" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "点号" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "变音符号" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "上标 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "序数" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "右书名号" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "四分之一" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "二分之一" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "四分之三" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "倒问号" - -# 千万不要、不要、不要变成那样一个字母,否则鬼知道机器读出来什么鸟样…… -# 目前“A 促音”可能是有道理但是很奇怪的处理方式之一。考虑到用到这些字母的人大多知道 acute 是啥,咱还是别碰了吧。 -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "乘号" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "除号" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "半角破折号" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "左单引号" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "右单引号" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "单下引号" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "左双引号" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "右双引号" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "双下引号" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "剑号" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "双剑号" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "项目符号" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "三角项目符号" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "千分号" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "撇号" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "双撇号" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "三撇号" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "连字符" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "欧元号" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "商标符号" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "对号" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "粗体对号" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x 形符号" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "上标 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "上标 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "上标 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "上标 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "上标 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "上标 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "上标 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "上标加号" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "上标减号" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "上标等号" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "上标左圆括号" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "上标右圆括号" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "上标 n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "下标 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "下标 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "下标 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "下标 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "下标 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "下标 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "下标 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "下标 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "下标 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "下标 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "下标加号" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "下标减号" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "下标等号" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "下标左圆括号" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "下标右圆括号" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "实心方框" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "实心菱形" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "对象替换字符" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "移动指针到当前条目" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "在当前的平铺浏览项目中按下左键" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "在当前的平铺浏览项目中按下右键" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "朗读整个文档" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "在平铺浏览模式朗读整个窗口" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "执行基本的 我在哪 操作" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "执行详尽的 我在哪 操作" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "朗读当前选择" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "朗读链接细节" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "朗读默认按钮" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "朗读状态栏" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "朗读标题栏" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "打开查找对话框" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "显示动作列表" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "搜索下一个相同的字符串" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "搜索上一个相同的字符串" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "进入及离开平铺浏览模式" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "切换将平铺浏览限制到当前对象上" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "将平铺浏览移至家位置" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "将平铺浏览移至最尾位置" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "将平铺浏览移至上一行的行首" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "朗读当前的平铺浏览行" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "拼写出当前平铺浏览的行" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "按照发音拼写出当前平铺浏览的行" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "将平铺浏览移至下一行的行首" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "将平铺浏览移至上一个字符或字词" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "说出当前平铺浏览的项目或单词" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "拼写出当前平铺浏览的项目或单词" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "按照发音拼写出当前平铺浏览的项目或单词" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "将平铺浏览移至下一个项目或字词" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "将平铺浏览移至当前字词之上" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "朗读当前的平铺浏览对象" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "将平铺浏览移至当前字词之下" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "将平铺浏览移至上一个字符" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "朗读当前的平铺浏览字符" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "按照发音说写出当前平铺浏览的字母" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "朗读当前平铺浏览字符的 unicode 值" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "将平铺浏览移至下一个字符" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "将平铺浏览移至行尾" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "将平铺浏览移至左下" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "将平面浏览下的内容复制到剪贴板" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "将平面浏览下的内容添加到剪贴板" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "显示平铺浏览视图内容" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "切换应否阅读当前的表格或整行" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "阅读当前字符相关的属性" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "点字显示向左移" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "点字显示向右移" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "回到有键盘焦点的对象" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "打开和关闭布莱叶盲文" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "处理光标路径选择关键字" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "标记文本选择的开始" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "标记文本选择的结束" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "进入学习模式。按 Esc 键离开学习模式" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "减慢朗读速度" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "加快朗读速度" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "降低朗读音调" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "升高朗读音调" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "提高朗读音量" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "减低朗读音量" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "选择上一个语音设置" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "选择下一个语音设置" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "减小当前语音设置" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "增大当前语音设置" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "保存语音设置" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "切换合成语音开关" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "切换语音详细等级" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "切换睡眠模式" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "退出屏幕阅读器" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "显示首选项对话窗口" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "显示应用程序首选项配置对话框" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "是否在缩排及对齐时朗读" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "改变数字朗读方式" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "循环到下一个朗读标点符号级别的位置" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "循环到下一个朗读合成器级别" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "循环到下一个设置配置" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "循环到下一个大写字母朗读方式" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "循环到下一个按键朗读级别" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "在执行时循环调试级别" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "我关注的当前位置的书签" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "转到上一个书签位置" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "转到书签" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "转到下一个书签位置" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "添加书签" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "保存书签" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "切换鼠标查看模式" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "提供当前时间" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "提供当前日期" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "提供当前对象的大小和位置" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "传递下一个命令到当前应用程序" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "朗读及点出上一个聊天室的消息" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "当好友输入时,是否通知" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "切换是否提供特定聊天室的消息记录" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "切换是否将聊天室的名称加入聊天室的消息前" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "左移" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "右移" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "上移" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "下移" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "冻结" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "左上角" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "左下角" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "光标位置" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "六个点" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "光标导航" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "开始剪切" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "剪切行" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "显示最后一条通知信息" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "显示通知信息列表" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "显示前一条通知信息" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "显示下一条通知信息" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "移至下一个字符" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "移至前一个字符" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "移至下一个单字" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "移至上一个单字" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "移至下一行" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "移至上一行" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "移至文件的最上面" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "移至文件的最下面" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "转到行首" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "转到行尾" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "转到下一个对象" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "转到上一个对象" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "展开当前的下拉列表框" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "在原生导航和屏幕阅读器光标导航之间切换" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "高级活动区域更新水平设置" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "默认的活动区域更新水平设置为关闭" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "审阅活动区域声明" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "监视活动区域" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "将焦点移向和移出当前鼠标下的区域" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "将该行设定为动态列标题" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "清空动态列头" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "将该列设定为动态行标题" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "清空动态行头" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "显示输入行的内容" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "切换结构导航键" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "转到上一个块引用" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "转到下一个块引用" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "显示块引用列表" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "转到上一个按钮" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "转到下一个按钮" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "显示按钮列表" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "转到上一个复选框" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "转到下一个复选框" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "显示复选框列表" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "转到上一个可点击项" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "转到下一个可点击项" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "显示可点击项列表" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "转到上一个组合框" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "转到下一个复选框" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "移至容器开头" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "移至容器结尾" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "显示组合框列表" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "转到上一个条目" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "转到下一个条目" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "显示条目列表" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "转到上一个表单域" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "转到下一个表单域" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "显示表单域列表" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "移至前一个标题" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "移至下一个标题" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "显示标题列表" - -#: src/cthulhu/cmdnames.py:932 -#, python-format -msgid "Go to previous heading at level %d" -msgstr "转到上一个级别为 %d 的标题" - -#: src/cthulhu/cmdnames.py:936 -#, python-format -msgid "Go to next heading at level %d" -msgstr "转到下一个级别为 %d 的标题" - -#: src/cthulhu/cmdnames.py:940 -#, python-format -msgid "Display a list of headings at level %d" -msgstr "显示级别为 %d 的标题列表" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "转到上一个内联框架" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "转到下一个内联框架" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "显示内联框架列表" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "移至上一图像" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "移至下一图像" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "显示图像列表" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "转到上一个界标" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "转到下一个界标" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "显示界标列表" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "转到上一个大型对象" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "转到下一个大型对象" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "显示大型对象列表" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "移至上一链接" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "移至下一链接" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "显示链接列表" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "转到上一个列表" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "转到下一个列表" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "显示列表的列表" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "转到上一个列表条目" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "转到下一个列表条目" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "显示列表项列表" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "回到上一个活动区域" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "转到下一个活动区域" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "转到表中最后一个声明的活动区域" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "前往导航焦点对象的父元素。" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "前往导航焦点对象的第一个子元素。" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "前往导航焦点对象的下一个相邻元素。" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "前往导航焦点对象的上一个相邻元素。" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "点击导航焦点的对象。" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "切换简化对象导航。" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "转到上一个段落" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "转到下一个段落" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "显示段落列表" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "转到上一个单选按钮" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "转到下一个单选按钮" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "显示单选按钮列表" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "移至前一个分隔符" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "移至后一个分隔符" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "转到上一个表" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "转到下一个表" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "显示表格列表" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "下移一个单元格" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "转到表中的第一个单元格" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "转到表中的最后一个单元格" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "左移一个单元格" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "右移一个单元格" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "上移一个单元格" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "切换布局模式" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "切换浏览模式与焦点模式" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "启用黏性焦点模式" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "启用黏性浏览模式" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "移至前一个未浏览的链接" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "移至下一个未浏览的链接" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "显示尚未访问的链接列表" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "移至前一个浏览过的链接" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "移至下一个浏览过的链接" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "显示已访问过的链接列表" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "艾丽斯蓝色" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "古董白色" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "海蓝宝石色" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "蔚蓝色" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "米色" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "橘黄色" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "黑色" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "杏仁白色" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "蓝色" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "蓝紫色" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "棕色" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "原木色" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "灰蓝色" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "黄绿色" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "巧克力色" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "珊瑚色" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "矢菊花蓝色" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "玉米丝色" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "深红色的" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "蓝绿色的" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "深蓝色" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr "深蓝绿色" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "深金黄色" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "深灰色" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "深绿色" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "深卡其色" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "深品红色" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "深橄榄绿色" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "深橙色" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "深紫色" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "深红色" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "深鲑肉色" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "深海绿色" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "深石板蓝色" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "深石板灰色" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "深蓝绿色" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "深紫罗兰色" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "深粉色" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "深天蓝色" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "暗灰色" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "道奇蓝色" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "红砖色" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "花白色" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "森绿色" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "樱红色" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "亮灰色" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr "苍白色" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "金色" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "金黄色" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "灰色" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "绿色" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "绿黄色" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "蜜色" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "艳粉色" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "浅红色" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "靛蓝色" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "象牙色" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "卡其色" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "薰衣草紫色" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "薰衣草红色" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "草坪绿色" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "柠檬雪纺色" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "浅蓝色" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "浅珊瑚色" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "浅蓝绿色" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "浅金黄色" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "浅灰色" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "浅绿色" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "浅粉色" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "浅鲑肉色" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "浅海绿色" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "浅天蓝色" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "浅石板灰色" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "浅钢青色" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "浅黄色" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "绿黄色" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "绿黄色" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "亚麻色" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "品红色的" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "栗色" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "中海蓝宝石色" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "中蓝色" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "中紫色" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "中紫色" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "中海绿色" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "中石板蓝色" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "中嫩绿色" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "中绿色" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "中紫红色" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "暗蓝色" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "薄荷乳白色" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "粉玫瑰红色" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "鹿皮色" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "纳瓦白色" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "海军色" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "旧布黄色" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "橄榄绿色" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "草绿色" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "橙色" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "橙红色" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "淡紫色" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "苍金黄色" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "苍绿色" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "苍绿色" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "苍紫罗兰红色" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "番木色" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "粉桃红色" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "秘鲁色" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "粉色" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr "紫红色" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "浅灰蓝色" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "紫色" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "红色" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "蔷薇褐色" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "皇家蓝色" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "重褐色" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "鲑肉色" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "沙棕色" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "海绿色" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "海贝色" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr "赭色" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "银色" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "天蓝色" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "石板蓝色" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "石板灰色" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "雪白色" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "嫩绿色" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "钢青色" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "黄褐色" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "青绿色" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "蓟色" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "番茄色" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "蓝绿色" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "紫罗兰色" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "小麦色" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "白色" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "白雾色" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "黄色" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "黄绿色" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "激活(_A)" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "结构化导航时的自动焦点模式" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "使用光标浏览时自动焦点模式" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "使用原生浏览时自动焦点模式" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "点 _7" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "点 _8" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "点 7 和 8(_D)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "取消(_C)" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "跳到(_J)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "确定(_O)" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "图标" - -#: src/cthulhu/guilabels.py:139 -msgctxt "capitalization style" -msgid "None" -msgstr "无" - -#: src/cthulhu/guilabels.py:147 -msgctxt "capitalization style" -msgid "Spell" -msgstr "拼写" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "好友输入时通知(_B)" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "提供聊天室特定的消息历史(_M)" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "从以下位置朗读消息" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "所有频道(_N)" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "当任一 %s 窗口活动的时候打开所有频道(_Y)" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "当窗口是活动的时候只打开一个频道(_W)" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "朗读聊天室名(_S)" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "启用内容的布局模式" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "双击" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "三击" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "默认的合成器" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "实际字符串" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "替换字符串" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "启用字母朗读(_R)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "启用非空格辨别键(_D)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "当前位置(_U)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "匹配文本的最小长度:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "查找选项" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "查找时只朗读更改的行(_Y)" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "查找时读取结果(_F)" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "命令" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "按键绑定" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "默认" - -#: src/cthulhu/guilabels.py:285 -msgctxt "keybindings" -msgid "Learn mode" -msgstr "学习模式" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "动作" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "点字按键组合" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "书签" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "日期和时间" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "鼠标视图" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "对象导航" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "对象详情" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "未绑定" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "平铺视图" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "语音和详略" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "平铺视图内容" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "已修改" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "台式机(_D)" - -#: src/cthulhu/guilabels.py:369 -msgctxt "notification presenter" -msgid "Notifications" -msgstr "通知" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "已收到通知" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "通知控制" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s 的 Cthulhu 首选项" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "布莱叶盲文中的标记" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "隐藏条件" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "朗读" - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "仍然保存有冲突的配置" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "用户配置有冲突!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"配置 %s 已经存在。\n" -"继续使用新设置来更新现有的配置?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "加载用户配置" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"您正要修改活动的配置。\n" -"如果您刚刚修改了您的首选项,在配置文件加载时修改将被丢弃。\n" -"\n" -"继续加载配置并丢弃之前的更改?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "另存为" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "配置名称(_P):" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "移除用户配置" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" -"您即将删除配置 %s。所有未保存的设置以及在此配置中保存的设置都将丢失。您想要继" -"续移除此配置和所有相关的设置吗?" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "全部" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "应用程序" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "窗口" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "无(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "一些(_M)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "大多(_O)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "行" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "句子" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "块引用" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "按钮" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "标题" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "复选框" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "可点击对象" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "组合框" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "描述" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "标题" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "内联框架" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "图像" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "标签" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "界标" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "等级" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "链接" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "列表" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "列表项" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "对象" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "段落" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "单选按钮" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "角色" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "已选中条目" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "状态" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "文本" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "值" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "块引用" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "按钮" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "勾选框" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "多个可点击对象" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "组合框" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "条目" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "填表区" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "标题" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "内联框架" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "多个图像" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "级别为 %d 的标题" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "界标" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "大型对象" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "链接" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "列表" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "列表项" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "段落" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "单选按钮" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "表格" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "未访问的链接" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "访问过的链接" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "页面导航" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "在一个页面首次加载时自动开始朗读(_L)" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "在一个页面首次加载时朗读页面概要(_P)" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "把两个停顿之间的语音分隔成块(_U)" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s 默认语音" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "默认" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "超链接" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "系统" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "大写" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "拼写检查" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "拼写错误(_E)" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "拼写建议(_S)" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "显示错误上下文(_C)" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "朗读电子表格单元格坐标" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "总是朗读选中的电子表格范围" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "发表单元标题(_H)" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "表格导航" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "跳过空单元格(_B)" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "朗读单元格(_C)" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "朗读单元格坐标(_C)" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "朗读多重跨越单元(_M)" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "属性名称" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "控制光标导航" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "启用结构化导航(_S)" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "声音主题(_T):" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "声音主题" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "简短(_F)" - -#: src/cthulhu/guilabels.py:953 -#, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "%d 条通知" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "左 Shift" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "左 Alt 键" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "左 Control 键" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "右 Shift 键" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "右 Alt 键" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "右 Control 键" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "左 meta 键" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "右 meta 键" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "数字键盘锁定" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "大小写锁定" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "移位锁定" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "滚动锁定" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "上翻页键" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "下翻页键" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "左 Tab 键" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "退格键" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "返回键" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "回车键" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "上" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "下" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "左" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "右" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "左 super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "右 super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "菜单" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "帮助" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "多个" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "模式切换" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "Esc" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "插入" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "删除" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "Home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "End" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "Begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "音调符号" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "响铃" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "钟响" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "负" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "插入" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "粗体 %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "斜体 %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "粗斜体 %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "手写 %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "粗手写 %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "花体 %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "双线 %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "粗花体 %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "无衬线 %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "无衬线粗体 %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "无衬线斜体 %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "无衬线粗斜体 %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "等宽 %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "没有点的 %s" - -#: src/cthulhu/mathsymbols.py:1267 -msgctxt "math symbol" -msgid "left arrow" -msgstr "左箭头" - -#: src/cthulhu/mathsymbols.py:1270 -msgctxt "math symbol" -msgid "up arrow" -msgstr "上箭头" - -#: src/cthulhu/mathsymbols.py:1273 -msgctxt "math symbol" -msgid "right arrow" -msgstr "右箭头" - -#: src/cthulhu/mathsymbols.py:1276 -msgctxt "math symbol" -msgid "down arrow" -msgstr "下箭头" - -#: src/cthulhu/mathsymbols.py:1279 -msgctxt "math symbol" -msgid "left right arrow" -msgstr "左右箭头" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "上下箭头" - -#: src/cthulhu/mathsymbols.py:1285 -msgctxt "math symbol" -msgid "north west arrow" -msgstr "西北箭头" - -#: src/cthulhu/mathsymbols.py:1288 -msgctxt "math symbol" -msgid "north east arrow" -msgstr "东北箭头" - -#: src/cthulhu/mathsymbols.py:1291 -msgctxt "math symbol" -msgid "south east arrow" -msgstr "东南箭头" - -#: src/cthulhu/mathsymbols.py:1294 -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "自短线左箭头" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "自短线上箭头" - -#: src/cthulhu/mathsymbols.py:1300 -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "自短线右箭头" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "自短线下箭头" - -#: src/cthulhu/mathsymbols.py:1306 -msgctxt "math symbol" -msgid "left double arrow" -msgstr "左双箭头" - -#: src/cthulhu/mathsymbols.py:1309 -msgctxt "math symbol" -msgid "up double arrow" -msgstr "上双箭头" - -#: src/cthulhu/mathsymbols.py:1312 -msgctxt "math symbol" -msgid "right double arrow" -msgstr "右双箭头" - -#: src/cthulhu/mathsymbols.py:1315 -msgctxt "math symbol" -msgid "down double arrow" -msgstr "下双箭头" - -#: src/cthulhu/mathsymbols.py:1318 -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "左右双箭头" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "上下双箭头" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "西北双箭头" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "东北双箭头" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "东南双箭头" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "南西双箭头" - -#: src/cthulhu/mathsymbols.py:1336 -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "向右箭头" - -#: src/cthulhu/mathsymbols.py:1339 -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "向右箭头尖" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -msgctxt "math symbol" -msgid "minus" -msgstr "减号" - -#: src/cthulhu/mathsymbols.py:1347 -msgctxt "math symbol" -msgid "less than" -msgstr "小于号" - -#: src/cthulhu/mathsymbols.py:1351 -msgctxt "math symbol" -msgid "greater than" -msgstr "大于号" - -#: src/cthulhu/mathsymbols.py:1355 -msgctxt "math symbol" -msgid "circumflex" -msgstr "扬抑符" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "修改符" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "短空白符" - -#: src/cthulhu/mathsymbols.py:1367 -msgctxt "math symbol" -msgid "dot" -msgstr "点" - -#: src/cthulhu/mathsymbols.py:1371 -msgctxt "math symbol" -msgid "double vertical line" -msgstr "双竖线" - -#: src/cthulhu/mathsymbols.py:1374 -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "水平省略号" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "对于全部" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "补集" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "偏微分" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "存在" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "不存在" - -#: src/cthulhu/mathsymbols.py:1392 -msgctxt "math symbol" -msgid "empty set" -msgstr "空集" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "增量" - -#: src/cthulhu/mathsymbols.py:1398 -msgctxt "math symbol" -msgid "nabla" -msgstr "倒三角形" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "属于" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "不属于" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "小属于符号" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "作为成员包含" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "不作为成员包含" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "小作为成员包含符号" - -# Wheee! QED! -#: src/cthulhu/mathsymbols.py:1419 -msgctxt "math symbol" -msgid "end of proof" -msgstr "证毕" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "连乘积" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "余积" - -#: src/cthulhu/mathsymbols.py:1428 -msgctxt "math symbol" -msgid "sum" -msgstr "总和" - -#: src/cthulhu/mathsymbols.py:1434 -msgctxt "math symbol" -msgid "minus or plus" -msgstr "加减" - -#: src/cthulhu/mathsymbols.py:1437 -msgctxt "math symbol" -msgid "dot plus" -msgstr "点加号" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "除法斜线" - -#: src/cthulhu/mathsymbols.py:1443 -msgctxt "math symbol" -msgid "set minus" -msgstr "集合减" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "星号运算符" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "复合函数运算符" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "间隔号" - -#: src/cthulhu/mathsymbols.py:1455 -msgctxt "math symbol" -msgid "square root" -msgstr "平方根号" - -#: src/cthulhu/mathsymbols.py:1458 -msgctxt "math symbol" -msgid "cube root" -msgstr "立方根号" - -#: src/cthulhu/mathsymbols.py:1461 -msgctxt "math symbol" -msgid "fourth root" -msgstr "四次根号" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "成正比" - -#: src/cthulhu/mathsymbols.py:1467 -msgctxt "math symbol" -msgid "infinity" -msgstr "无穷" - -#: src/cthulhu/mathsymbols.py:1470 -msgctxt "math symbol" -msgid "right angle" -msgstr "直角" - -#: src/cthulhu/mathsymbols.py:1473 -msgctxt "math symbol" -msgid "angle" -msgstr "角" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "测量得角度" - -#: src/cthulhu/mathsymbols.py:1479 -msgctxt "math symbol" -msgid "spherical angle" -msgstr "球面角" - -#: src/cthulhu/mathsymbols.py:1482 -msgctxt "math symbol" -msgid "divides" -msgstr "整除" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "不整除" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "平行于" - -#: src/cthulhu/mathsymbols.py:1491 -msgctxt "math symbol" -msgid "not parallel to" -msgstr "不平行于" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -msgctxt "math symbol" -msgid "logical and" -msgstr "逻辑与" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -msgctxt "math symbol" -msgid "logical or" -msgstr "逻辑或" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -msgctxt "math symbol" -msgid "intersection" -msgstr "交" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "并集" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "积分" - -#: src/cthulhu/mathsymbols.py:1509 -msgctxt "math symbol" -msgid "double integral" -msgstr "二重积分" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "三重积分" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "围道积分" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "曲面积分" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "体积积分" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "顺时针积分" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "顺时针方向围线积分" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "逆时针方向围线积分" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "因此" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "因为" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "比" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "比例" - -#: src/cthulhu/mathsymbols.py:1545 -msgctxt "math symbol" -msgid "dot minus" -msgstr "点负号" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "超越符号" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "等比符号" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "同位符" - -#: src/cthulhu/mathsymbols.py:1557 -msgctxt "math symbol" -msgid "tilde" -msgstr "波浪号" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "反转波浪号" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "反向懒 S 符" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "正弦波" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "花边符号" - -#: src/cthulhu/mathsymbols.py:1572 -msgctxt "math symbol" -msgid "not tilde" -msgstr "非波浪线" - -#: src/cthulhu/mathsymbols.py:1575 -msgctxt "math symbol" -msgid "minus tilde" -msgstr "负波浪线" - -#: src/cthulhu/mathsymbols.py:1578 -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "渐近等于" - -#: src/cthulhu/mathsymbols.py:1581 -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "不渐近等于" - -#: src/cthulhu/mathsymbols.py:1584 -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "约等于" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "近似但实际上不等于" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "既不近似又不等于" - -#: src/cthulhu/mathsymbols.py:1593 -msgctxt "math symbol" -msgid "almost equal to" -msgstr "几乎等于" - -#: src/cthulhu/mathsymbols.py:1596 -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "不是几乎等于" - -#: src/cthulhu/mathsymbols.py:1599 -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "几乎等于或等于" - -#: src/cthulhu/mathsymbols.py:1602 -msgctxt "math symbol" -msgid "triple tilde" -msgstr "三层波浪线" - -#: src/cthulhu/mathsymbols.py:1605 -msgctxt "math symbol" -msgid "all equal to" -msgstr "完全等于" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "相当于" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "几何相当于" - -#: src/cthulhu/mathsymbols.py:1614 -msgctxt "math symbol" -msgid "difference between" -msgstr "不同之处" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "接近极限" - -#: src/cthulhu/mathsymbols.py:1620 -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "几何等于" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "约等于或象形符" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "象形或约等于" - -#: src/cthulhu/mathsymbols.py:1629 -msgctxt "math symbol" -msgid "colon equals" -msgstr "冒号等号" - -#: src/cthulhu/mathsymbols.py:1632 -msgctxt "math symbol" -msgid "equals colon" -msgstr "等号冒号" - -#: src/cthulhu/mathsymbols.py:1635 -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "内环等于" - -#: src/cthulhu/mathsymbols.py:1638 -msgctxt "math symbol" -msgid "ring equal to" -msgstr "环等于" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "对应于" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "估计" - -#: src/cthulhu/mathsymbols.py:1647 -msgctxt "math symbol" -msgid "equiangular to" -msgstr "等角于" - -#: src/cthulhu/mathsymbols.py:1650 -msgctxt "math symbol" -msgid "star equals" -msgstr "星等号" - -#: src/cthulhu/mathsymbols.py:1653 -msgctxt "math symbol" -msgid "delta equal to" -msgstr "三角等于" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "按定义等于" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "测量于" - -#: src/cthulhu/mathsymbols.py:1662 -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "问号等于" - -#: src/cthulhu/mathsymbols.py:1665 -msgctxt "math symbol" -msgid "not equal to" -msgstr "不等于" - -#: src/cthulhu/mathsymbols.py:1668 -msgctxt "math symbol" -msgid "identical to" -msgstr "恒等于" - -#: src/cthulhu/mathsymbols.py:1671 -msgctxt "math symbol" -msgid "not identical to" -msgstr "不恒等于" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "严格等于" - -#: src/cthulhu/mathsymbols.py:1677 -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "小于等于" - -#: src/cthulhu/mathsymbols.py:1680 -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "大于等于" - -#: src/cthulhu/mathsymbols.py:1683 -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "小于等于" - -#: src/cthulhu/mathsymbols.py:1686 -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "大于等于" - -#: src/cthulhu/mathsymbols.py:1689 -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "小于但不等于" - -#: src/cthulhu/mathsymbols.py:1692 -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "大于但不等于" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "远小于" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "远大于" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "在之间" - -#: src/cthulhu/mathsymbols.py:1704 -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "不等同" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "不小于" - -#: src/cthulhu/mathsymbols.py:1710 -msgctxt "math symbol" -msgid "not greater than" -msgstr "不大于" - -#: src/cthulhu/mathsymbols.py:1713 -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "不小于也不等于" - -#: src/cthulhu/mathsymbols.py:1716 -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "不大于也不等于" - -#: src/cthulhu/mathsymbols.py:1719 -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "小于或等同于" - -#: src/cthulhu/mathsymbols.py:1722 -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "大于或等同于" - -#: src/cthulhu/mathsymbols.py:1725 -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "不小于也不等同于" - -#: src/cthulhu/mathsymbols.py:1728 -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "不大于也不等同于" - -#: src/cthulhu/mathsymbols.py:1731 -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "小于或大于" - -#: src/cthulhu/mathsymbols.py:1734 -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "大于或小于" - -#: src/cthulhu/mathsymbols.py:1737 -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "不小于也不大于" - -#: src/cthulhu/mathsymbols.py:1740 -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "不大于也不小于" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "先于" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "后于" - -#: src/cthulhu/mathsymbols.py:1749 -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "先于或等于" - -#: src/cthulhu/mathsymbols.py:1752 -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "后于或等于" - -#: src/cthulhu/mathsymbols.py:1755 -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "先于或等同于" - -#: src/cthulhu/mathsymbols.py:1758 -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "后于或等同于" - -#: src/cthulhu/mathsymbols.py:1761 -msgctxt "math symbol" -msgid "does not precede" -msgstr "不先于" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "不后于" - -#: src/cthulhu/mathsymbols.py:1767 -msgctxt "math symbol" -msgid "subset of" -msgstr "包含于" - -#: src/cthulhu/mathsymbols.py:1770 -msgctxt "math symbol" -msgid "superset of" -msgstr "包含" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "不包含于" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "不包含" - -#: src/cthulhu/mathsymbols.py:1779 -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "包含于或等于" - -#: src/cthulhu/mathsymbols.py:1782 -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "包含或等于" - -#: src/cthulhu/mathsymbols.py:1785 -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "既不是子集也不等于" - -#: src/cthulhu/mathsymbols.py:1788 -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "既不是超集也不等于" - -#: src/cthulhu/mathsymbols.py:1791 -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "子集与不等于" - -#: src/cthulhu/mathsymbols.py:1794 -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "超集与不等于" - -#: src/cthulhu/mathsymbols.py:1797 -msgctxt "math symbol" -msgid "multiset" -msgstr "多集" - -#: src/cthulhu/mathsymbols.py:1800 -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "多集乘法" - -#: src/cthulhu/mathsymbols.py:1803 -msgctxt "math symbol" -msgid "multiset union" -msgstr "多集联合" - -#: src/cthulhu/mathsymbols.py:1806 -msgctxt "math symbol" -msgid "square image of" -msgstr "方形像" - -#: src/cthulhu/mathsymbols.py:1809 -msgctxt "math symbol" -msgid "square original of" -msgstr "方形原" - -#: src/cthulhu/mathsymbols.py:1812 -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "方形像或等于" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "平方或等于" - -#: src/cthulhu/mathsymbols.py:1818 -msgctxt "math symbol" -msgid "square cap" -msgstr "方形帽" - -#: src/cthulhu/mathsymbols.py:1821 -msgctxt "math symbol" -msgid "square cup" -msgstr "方形杯" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "带圈加号" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "带圈减号" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "带圈乘号" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "带圈除法斜线" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "圆圈点运算符" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "圆圈圆环运算符" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "带圆圈的星号运算符" - -#: src/cthulhu/mathsymbols.py:1845 -msgctxt "math symbol" -msgid "circled equals" -msgstr "圆圈等号" - -#: src/cthulhu/mathsymbols.py:1848 -msgctxt "math symbol" -msgid "circled dash" -msgstr "圆圈破折号" - -#: src/cthulhu/mathsymbols.py:1851 -msgctxt "math symbol" -msgid "squared plus" -msgstr "方框加号" - -#: src/cthulhu/mathsymbols.py:1854 -msgctxt "math symbol" -msgid "squared minus" -msgstr "方框减号" - -#: src/cthulhu/mathsymbols.py:1857 -msgctxt "math symbol" -msgid "squared times" -msgstr "方框叉号" - -#: src/cthulhu/mathsymbols.py:1860 -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "方框点号" - -#: src/cthulhu/mathsymbols.py:1863 -msgctxt "math symbol" -msgid "right tack" -msgstr "右钉符" - -#: src/cthulhu/mathsymbols.py:1866 -msgctxt "math symbol" -msgid "left tack" -msgstr "左钉符" - -#: src/cthulhu/mathsymbols.py:1869 -msgctxt "math symbol" -msgid "down tack" -msgstr "下钉符" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "上钉符" - -#: src/cthulhu/mathsymbols.py:1875 -msgctxt "math symbol" -msgid "assertion" -msgstr "断言" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "模" - -#: src/cthulhu/mathsymbols.py:1881 -msgctxt "math symbol" -msgid "true" -msgstr "真" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "强制" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "三竖条右转门" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "双竖条双右转门" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "并不能证明" - -#: src/cthulhu/mathsymbols.py:1896 -msgctxt "math symbol" -msgid "not true" -msgstr "假" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "不强制" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "非双竖条双右转门" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "先于下关系" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "后于下关系" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "为……的正规子群" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "包含为正规子群" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "正规子群或等于" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "属于正规子群或等于" - -#: src/cthulhu/mathsymbols.py:1923 -msgctxt "math symbol" -msgid "original of" -msgstr "原" - -#: src/cthulhu/mathsymbols.py:1926 -msgctxt "math symbol" -msgid "image of" -msgstr "像" - -#: src/cthulhu/mathsymbols.py:1929 -msgctxt "math symbol" -msgid "multimap" -msgstr "多重映射" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "厄密共轭矩阵" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "插入" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "异或" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "与非" - -#: src/cthulhu/mathsymbols.py:1944 -msgctxt "math symbol" -msgid "nor" -msgstr "或非" - -#: src/cthulhu/mathsymbols.py:1947 -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "带有弧的右角" - -#: src/cthulhu/mathsymbols.py:1950 -msgctxt "math symbol" -msgid "right triangle" -msgstr "右三角" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "菱形运算符" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "点运算符" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "星运算符" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "乘除号" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "蝴蝶结" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "左正规因子半直积" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "右正规因子半直积" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "左半直积" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "右半直积" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "横翻颚化符等号" - -#: src/cthulhu/mathsymbols.py:1995 -msgctxt "math symbol" -msgid "curly logical or" -msgstr "弯逻辑或" - -#: src/cthulhu/mathsymbols.py:1998 -msgctxt "math symbol" -msgid "curly logical and" -msgstr "弯逻辑与" - -#: src/cthulhu/mathsymbols.py:2001 -msgctxt "math symbol" -msgid "double subset" -msgstr "双子集" - -#: src/cthulhu/mathsymbols.py:2004 -msgctxt "math symbol" -msgid "double superset" -msgstr "双超集" - -#: src/cthulhu/mathsymbols.py:2007 -msgctxt "math symbol" -msgid "double intersection" -msgstr "双交会" - -#: src/cthulhu/mathsymbols.py:2010 -msgctxt "math symbol" -msgid "double union" -msgstr "双联合" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "草耙" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "等于和平行于" - -#: src/cthulhu/mathsymbols.py:2019 -msgctxt "math symbol" -msgid "less than with dot" -msgstr "有点的小于等于" - -#: src/cthulhu/mathsymbols.py:2022 -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "有点的大于等于" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "非常小于" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "非常大于" - -#: src/cthulhu/mathsymbols.py:2031 -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "小于等于或大于" - -#: src/cthulhu/mathsymbols.py:2034 -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "大于等于或小于" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "等于或小于" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "等于或大于" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "等于或先于" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "等于或后于" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "不先于或等于" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "不后于或等于" - -#: src/cthulhu/mathsymbols.py:2055 -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "不方形像或等于" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "不方形原或等于" - -#: src/cthulhu/mathsymbols.py:2061 -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "方形像或不等于" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "方形原或不等于" - -#: src/cthulhu/mathsymbols.py:2067 -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "小于而不等同于" - -#: src/cthulhu/mathsymbols.py:2070 -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "大于而不等同于" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "先于而不等同于" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "后于而不等同于" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "不是……的正常子群" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "不以子群包含" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "不是正常子群或等于" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "不以正常子群包含或等于" - -#: src/cthulhu/mathsymbols.py:2091 -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "垂直省略号" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "中置水平省略号" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "左下右上对角线省略号" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "左上右下对角线省略号" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "有长水平划的元素" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "在水平划末尾有竖条的元素" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "在水平划末尾有竖条的小型元素" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "上面带点的元素" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "有顶线的元素" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "有顶线的小型元素" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "有底线的元素" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "有两个水平划的元素" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "包含有长水平划" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "在水平划末尾包含有竖条" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "在水平划末尾小型包含有竖条" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "包含有顶线" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "小型包含有顶线" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "z 符号包成员" - -#: src/cthulhu/mathsymbols.py:2148 -msgctxt "math symbol" -msgid "left ceiling" -msgstr "左顶棚" - -#: src/cthulhu/mathsymbols.py:2151 -msgctxt "math symbol" -msgid "right ceiling" -msgstr "右顶棚" - -#: src/cthulhu/mathsymbols.py:2154 -msgctxt "math symbol" -msgid "left floor" -msgstr "左地板" - -#: src/cthulhu/mathsymbols.py:2157 -msgctxt "math symbol" -msgid "right floor" -msgstr "右地板" - -#: src/cthulhu/mathsymbols.py:2160 -msgctxt "math symbol" -msgid "top brace" -msgstr "上花括号" - -#: src/cthulhu/mathsymbols.py:2163 -msgctxt "math symbol" -msgid "bottom brace" -msgstr "下花括号" - -#: src/cthulhu/mathsymbols.py:2166 -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "数学左尖括号" - -#: src/cthulhu/mathsymbols.py:2169 -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "数学右尖括号" - -#: src/cthulhu/mathsymbols.py:2172 -msgctxt "math symbol" -msgid "circled dot" -msgstr "圆圈和点" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "带点的并运算符" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "带加号的并运算符" - -#: src/cthulhu/mathsymbols.py:2184 -msgctxt "math symbol" -msgid "square intersection" -msgstr "平方交运算符" - -#: src/cthulhu/mathsymbols.py:2186 -msgctxt "math symbol" -msgid "square union" -msgstr "平方并运算符" - -#: src/cthulhu/mathsymbols.py:2190 -msgctxt "math symbol" -msgid "black square" -msgstr "实心方框" - -#: src/cthulhu/mathsymbols.py:2194 -msgctxt "math symbol" -msgid "white square" -msgstr "空心方框" - -#: src/cthulhu/mathsymbols.py:2198 -msgctxt "math symbol" -msgid "black diamond" -msgstr "实心菱形" - -#: src/cthulhu/mathsymbols.py:2202 -msgctxt "math symbol" -msgid "white circle" -msgstr "空心圆形" - -#: src/cthulhu/mathsymbols.py:2206 -msgctxt "math symbol" -msgid "black circle" -msgstr "实心圆形" - -#: src/cthulhu/mathsymbols.py:2209 -msgctxt "math symbol" -msgid "white bullet" -msgstr "空心项目符号" - -#: src/cthulhu/mathsymbols.py:2213 -msgctxt "math symbol" -msgid "black medium small square" -msgstr "实心方框" - -#: src/cthulhu/mathsymbols.py:2219 -#, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "%s 带下划线" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "%s 带斜线" - -#: src/cthulhu/mathsymbols.py:2231 -#, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "%s 带竖线" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "应用程序" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "空" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "粗体" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "书签已输入" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "书签已保存" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "无法保存书签" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "没有找到书签。" - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "没有找到书签。" - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "已激活绕过模式。" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "无法获取计算器显示" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "图标" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "大写字母朗读方式设定为图标。" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "无" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "大写字母朗读方式设定为无。" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "拼写" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "大写字母朗读方式设定为拼读。" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "此应用程序正在控制插入符号。" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu 正在控制光标。" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "单元格 %s" - -#: src/cthulhu/messages.py:179 -#, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "已选中 %s" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "已选中 %s 到 %s" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "已取消选择 %s 到 %s" - -#: src/cthulhu/messages.py:199 -#, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "已取消选择 %s" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "阻止使用选项" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "强制使用选项" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "首选项" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "可选参数" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "用法:" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "以下参数无效: " - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "打印正在运行的应用程序" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "加载用户配置" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "无法加载配置文件: %s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "无法启动 Cthulhu,因为无法连接到桌面。" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "无法激活设置管理器。正在退出。" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"此会话已有一个屏幕阅读器进程正在运行。\n" -"运行“cthulhu --replace”命令以用新的取代已有进程。" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "名称" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "为用户首选项使用另外的目录" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "目录" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "此应用程序的版本" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "替换当前正在运行的 Cthulhu 实例" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "显示本帮助信息并退出" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "发送调试输出到 debug-YYYY-MM-DD-HH:MM:SS.out" - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "发送调试输出到指定的文件" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "文件" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "设定用户首选项(文字版本)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "设定用户首选项(图形版本)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "汇报错误至 https://groups.io/g/stormux。" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "选定的内容已剪切到剪贴板。" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "剪切" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "选定已复制到剪贴板。" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "已复制" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "已从剪贴板粘贴内容。" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "已粘贴" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "好友输入时不通知。" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "好友输入时通知。" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "来自聊天室 %s 的消息" - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "新聊天标签 %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "不要朗读聊天室名称。" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "朗读聊天室名称。" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "不要提供聊天室特定的消息历史。" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "提供聊天室特定的消息历史。" - -#: src/cthulhu/messages.py:442 -msgctxt "content" -msgid "deletion start" -msgstr "删除开始" - -#: src/cthulhu/messages.py:447 -msgctxt "content" -msgid "deletion end" -msgstr "删除结束" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "插入开始" - -#: src/cthulhu/messages.py:457 -msgctxt "content" -msgid "insertion end" -msgstr "插入结束" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "高亮开始" - -#: src/cthulhu/messages.py:467 -msgctxt "content" -msgid "highlight end" -msgstr "高亮结束" - -#: src/cthulhu/messages.py:474 -msgctxt "content" -msgid "suggestion end" -msgstr "建议结束" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "容器尾部。" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "不在容器内。" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "已选中所有项目" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "默认按钮为 %s" - -#: src/cthulhu/messages.py:506 -#, python-format -msgid "Default button is %s. Grayed" -msgstr "默认按钮为 %s。未选中" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "未找到默认按钮" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr " 上标 %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr " 上标 %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "不在对话框中" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "已选中整个文件" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "已取消选中整个文件" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "由光标位置开始选中文件" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "由光标位置开始取消选中文档" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "选中文档至光标位置" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "取消选中文档至光标位置" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "动态的设置 %d 行个标题列" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "已清除动态栏标头。" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "动态列标头设定给栏 %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "动态行头已清除。" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "空" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f KB" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f MB" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "未找到任何文件。" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "将内容附加到剪贴板。" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "将内容复制到剪贴板。" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "未使用平面浏览。" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "进入平铺浏览模式。" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "离开平铺浏览。" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "平铺浏览已限制到当前对象上" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "平铺浏览限制解除" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "有公式" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "打开对话框" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "打开网格" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "打开列表框" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "打开菜单" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "打开树" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "图像地图链接" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "输入的键已经绑定到了 %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "按键抓取:%s。按回车键确认。" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "新的按键是:%s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "检测到了按键组合。按回车键确认。" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "键绑定已被移除。" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "输入新的按键" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "字母" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "按键朗读设置为字母。" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "无" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "按键朗读设置为无。" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "字母和单词" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "按键朗读设置为字母和单词。" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "句子" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "按键朗读设置为句子。" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "单词" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "按键朗读设置为单词。" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "单词和句子" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "按键朗读设置为单词和句子。" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "外部符号:%s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "精算符号" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "方括号" - -#: src/cthulhu/messages.py:913 -msgctxt "math enclosure" -msgid "a circle" -msgstr "圆括号" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "长除号" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "星号" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "圆中括号" - -#: src/cthulhu/messages.py:945 -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "水平线" - -#: src/cthulhu/messages.py:953 -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "竖线" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "向下对角线" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "向上对角线" - -#: src/cthulhu/messages.py:977 -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "右上箭头" - -#: src/cthulhu/messages.py:985 -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "底部线" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "左侧线" - -#: src/cthulhu/messages.py:1001 -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "右侧线" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "顶部线" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "相量角度" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "阿拉伯阶乘符号" - -#: src/cthulhu/messages.py:1039 -msgctxt "math enclosure" -msgid "and" -msgstr "和" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "分数开始" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "没有分数线的分数,开始" - -#: src/cthulhu/messages.py:1060 -msgctxt "math fraction" -msgid "over" -msgstr "结束" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "分数结束" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "平方根号" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "三次根号" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "根是" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "开根号开始" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "开根号结束" - -#: src/cthulhu/messages.py:1111 -msgctxt "math script generic" -msgid "subscript" -msgstr "下标" - -#: src/cthulhu/messages.py:1118 -msgctxt "math script generic" -msgid "superscript" -msgstr "上标" - -#: src/cthulhu/messages.py:1125 -msgctxt "math script" -msgid "pre-subscript" -msgstr "前下标" - -#: src/cthulhu/messages.py:1132 -msgctxt "math script" -msgid "pre-superscript" -msgstr "前上标" - -#: src/cthulhu/messages.py:1141 -msgctxt "math script generic" -msgid "underscript" -msgstr "中下标" - -#: src/cthulhu/messages.py:1150 -msgctxt "math script generic" -msgid "overscript" -msgstr "中上标" - -#: src/cthulhu/messages.py:1154 -msgctxt "math table" -msgid "table end" -msgstr "表结束" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "嵌套表结束" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "不能存取" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "已禁用" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "朗读缩排及对齐已禁用。" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "已启用" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "朗读缩排及对齐已启用。" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "学习模式。按 Esc 键离开。" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"正在进入学习模式。按任意健倾听它的功能。要查看屏幕阅读器文档,请按 F1。要获取" -"屏幕阅读器默认快捷键,请按 F2。要获得当前应用程序的屏幕阅读器快捷键,请按 " -"F3。要退出学习模式,请按 ESC 键。" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "正在离开引用段。" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "正在离开详细信息。" - -#: src/cthulhu/messages.py:1227 -msgctxt "role" -msgid "leaving feed." -msgstr "正在离开源。" - -#: src/cthulhu/messages.py:1233 -msgctxt "role" -msgid "leaving figure." -msgstr "正在离开图表。" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "正在离开表单。" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "正在离开横幅。" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "正在离开互补内容。" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "正在离开信息框。" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "正在离开主内容。" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "正在离开导航。" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "正在离开区域。" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "正在离开搜索框。" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "正在离开列表。" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "正在离开面板。" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "正在离开表格。" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "正在离开提示信息。" - -#: src/cthulhu/messages.py:1302 -msgctxt "role" -msgid "leaving abstract." -msgstr "正在离开概览。" - -#: src/cthulhu/messages.py:1308 -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "正在离开鸣谢。" - -#: src/cthulhu/messages.py:1314 -msgctxt "role" -msgid "leaving afterword." -msgstr "正在离开后记。" - -#: src/cthulhu/messages.py:1320 -msgctxt "role" -msgid "leaving appendix." -msgstr "正在离开附录。" - -#: src/cthulhu/messages.py:1326 -msgctxt "role" -msgid "leaving bibliography." -msgstr "正在离开参考书目。" - -#: src/cthulhu/messages.py:1332 -msgctxt "role" -msgid "leaving chapter." -msgstr "正在离开章节。" - -#: src/cthulhu/messages.py:1338 -msgctxt "role" -msgid "leaving colophon." -msgstr "正在离开版权页。" - -#: src/cthulhu/messages.py:1344 -msgctxt "role" -msgid "leaving conclusion." -msgstr "正在离开结论。" - -#: src/cthulhu/messages.py:1350 -msgctxt "role" -msgid "leaving credit." -msgstr "正在离开贡献者名单。" - -#: src/cthulhu/messages.py:1356 -msgctxt "role" -msgid "leaving credits." -msgstr "正在离开贡献者名单。" - -#: src/cthulhu/messages.py:1362 -msgctxt "role" -msgid "leaving dedication." -msgstr "正在离开献词。" - -#: src/cthulhu/messages.py:1368 -msgctxt "role" -msgid "leaving endnotes." -msgstr "正在离开尾注。" - -#: src/cthulhu/messages.py:1374 -msgctxt "role" -msgid "leaving epigraph." -msgstr "正在离开题词。" - -#: src/cthulhu/messages.py:1380 -msgctxt "role" -msgid "leaving epilogue." -msgstr "正在离开结语。" - -#: src/cthulhu/messages.py:1386 -msgctxt "role" -msgid "leaving errata." -msgstr "正在离开勘误表。" - -#: src/cthulhu/messages.py:1392 -msgctxt "role" -msgid "leaving example." -msgstr "正在离开示例。" - -#: src/cthulhu/messages.py:1398 -msgctxt "role" -msgid "leaving foreword." -msgstr "正在离开前言。" - -#: src/cthulhu/messages.py:1404 -msgctxt "role" -msgid "leaving glossary." -msgstr "正在离开词汇表。" - -#: src/cthulhu/messages.py:1410 -msgctxt "role" -msgid "leaving index." -msgstr "正在离开索引。" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "正在离开引言。" - -#: src/cthulhu/messages.py:1422 -msgctxt "role" -msgid "leaving page list." -msgstr "正在离开页面列表。" - -#: src/cthulhu/messages.py:1428 -msgctxt "role" -msgid "leaving part." -msgstr "正在离开段。" - -#: src/cthulhu/messages.py:1434 -msgctxt "role" -msgid "leaving preface." -msgstr "正在离开序言。" - -#: src/cthulhu/messages.py:1440 -msgctxt "role" -msgid "leaving prologue." -msgstr "正在离开序章。" - -#: src/cthulhu/messages.py:1446 -msgctxt "role" -msgid "leaving pullquote." -msgstr "正在离开引用段。" - -#: src/cthulhu/messages.py:1452 -msgctxt "role" -msgid "leaving QNA." -msgstr "正在离开问答。" - -#: src/cthulhu/messages.py:1459 -msgctxt "role" -msgid "leaving suggestion." -msgstr "正在离开建议。" - -#: src/cthulhu/messages.py:1465 -msgctxt "role" -msgid "leaving table of contents." -msgstr "正在离开目录。" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "由光标位置开始向下选中行" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "由光标位置开始向上选中行" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "由光标位置开始向下取消选中行" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "由光标位置开始向上取消选中行" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "离开学习模式。" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "从行首选择到当前光标" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "从当前光标开始选择到行尾" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "链接" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "同一个页面" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "同一个地址" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "不同地址" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s 链接到 %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s 链接" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "已访问 %s 链接" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "用上下箭头去操纵列表。按 Esc 键退出。" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "所有活动区域更新水平设置为关闭" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "活动区域更新水平被恢复" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "活动水平 %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "活动区域设置为自信“assertive”" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "活动区域设置为关闭“off”" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "活动区域设置为礼貌“polite”" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "活动区域设置为粗鲁“rude”" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "活动区域监视已关闭" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "正在监视活动区域" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "未保存活动信息" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "活动区域支持关闭" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "未找到" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "未找到当前位置。" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "关" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "开" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "拼写错误" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "拼写错误的单词:%s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "上下文是 %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "浏览模式" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "焦点模式" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "要启用焦点模式请按 %s。" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "焦点模式为黏性模式。" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "浏览模式为黏性模式。" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "布局模式。" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "对象模式。" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "指针已移动到对象上。" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "鼠标指针下未找到对象。" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "已禁用鼠标查看模式。" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "已启用鼠标查看。" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "错误:无法创建对象列表。" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "没有子元素。" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "没有下一项。" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "没有父元素。" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "没有上一项。" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "简化导航已启用。" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "简化导航已禁用。" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "嵌套等级 %d" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "新条目已添加" - -#: src/cthulhu/messages.py:1859 -#, python-format -msgid "No actions found on: %s" -msgstr "在 %s 上没有发现可执行动作" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "没有焦点" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "未聚焦到程序。" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "没有更多块引用了。" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "没有更多按钮了。" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "没有更多复选框了。" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "没有更多大型对象了。" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "没有更多的可点击对象了。" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "没有更多复选框。" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "没有更多条目了。" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "没有更多表单域了。" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "没有其他标题。" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "没有更多级别为 %d 的标题。" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "没有更多的内联框架了。" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "没有更多的图像了。" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "没有找到更多的界标了。" - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "没有更多链接了。" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "没有更多列表了。" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "没有更多列表条目了。" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "没有更多的活动区域。" - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "没有更多段落了。" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "没有更多单选按钮了。" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "没有更多分隔符了。" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "没有更多的表了。" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "没有更多未访问的链接了。" - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "没有更多已访问的链接了。" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "未选中。" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "没有在链接上。" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "通知" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "底部" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "顶部" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "无通知消息" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "数码" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "将数字以数码形式朗读。" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "单词" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "把数字当做单词朗读(_D)" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr "关闭" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr "打开" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "正在载入,请稍候。" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "载入完成。" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "载入 %s 完成。" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "有 %s 页。" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "从光标标位置开始选中页" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "选中页至光标位置" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "从光标位置开始取消选择页" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "取消选中页到光标位置" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "由光标位置向下选中的段落" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "由光标位置向上选中的段落" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "由光标位置向下取消选中的段落" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "由光标位置向上取消选中的段落" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"您已经打开了一个 Cthulhu 首选项对话框实例。\n" -"打开一个新的此对话框前,请关闭它。" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "%(count)d 中的第 %(position)d 张" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "用户配置设定为 %s。" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "未找到配置文件。" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "进度条 %d。" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "全部" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "标点符号级别设为“全部”。" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "大多" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "标点符号级别设置为“大多”。" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "无" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "标点符号级别设置为无。" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "一些" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "标点符号级别设置为“一些”。" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "搜索中。" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "搜索完成。" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "已重新加载 Cthulhu 设置。" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "已选中的文字是:%s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "选定已删除。" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "选定已恢复。" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "文本已取消选中。" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "大小:%d,%d。位置:%d,%d。" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "宽度:%d。高度:%d。左起 %d。上起 %d。" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "已停用朗读功能。" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "已启用朗读功能。" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "加快语速。" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "减慢语速。" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "提高音调。" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "降低音调。" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "声音大一点。" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "更柔和。" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "语速 %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "音调 %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "音量 %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher 模块 %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher 语音 %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "没有可用的 Speech-dispatcher 模块" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "没有可用的 Speech-dispatcher 语音" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "语音设置已保存" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "无法保存语音设置" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "详细等级:简短" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "详细等级:详细" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " 点点点" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu 欢迎您。" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "克苏鲁潜伏在波涛之下。" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "已为 %s 启用睡眠模式" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "已为 %s 禁用睡眠模式" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "语音功能不存在。" - -#: src/cthulhu/messages.py:2342 -msgctxt "status bar" -msgid "Not found" -msgstr "未找到" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "未找到状态栏" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "未找到字符串" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "结构导航键关闭。" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "结构导航键打开。" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "未找到" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "行 %(row)d,列 %(column)d。" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "表尾" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "朗读单元格" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "朗读整行" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "不均匀的" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "不在表中。" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "列已重新排列" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "行已重新排列" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "列 %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "%(total)d 列中的第 %(index)d 列" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "列尾。" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "列头。" - -#: src/cthulhu/messages.py:2435 -#, python-format -msgid "Column %s selected" -msgstr "已选中列 %s" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "已选中列 %s 到 %s" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "已取消选中列 %s 到 %s" - -#: src/cthulhu/messages.py:2454 -#, python-format -msgid "Column %s unselected" -msgstr "已取消选中列 %s" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "行 %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "%(total)d 行中的第 %(index)d 行" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "行首。" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "行尾。" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "行已删除。" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "最后一行已删除。" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "行已插入。" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "行已插入到表末。" - -#: src/cthulhu/messages.py:2494 -#, python-format -msgid "Row %s selected" -msgstr "已选中行 %s" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "已选中行 %s 到 %s" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "已取消选中行 %s 到 %s" - -#: src/cthulhu/messages.py:2513 -#, python-format -msgid "Row %s unselected" -msgstr "已取消选中行 %s" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "已选中" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "未选中" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H 小时,%M 分钟零 %S 秒" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H 小时零 %M 分钟" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "Unicode %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "撤销" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "重做" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu 版本 %s。" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "空白空间" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "滚动到底部。" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "滚动到顶部。" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 个项目" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "单元格占了 %d 行" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] " %d 列" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "单元格占了 %d 列" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d 个字符过长" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d 个对话框)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d 个未获得焦点的对话框" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d 字节" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "找到了 %d 个文件" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d 个表单" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d 个标题" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d 个条目" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d 个界标" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "找到了 %d 个条目" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "正在离开 %d 个引用段。" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "正在离开 %d 个列表。" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "未知大小的列表" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "%d 个项目的列表" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "未知大小的订阅" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "有 %d 篇文章的订阅" - -#: src/cthulhu/messages.py:2710 -#, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "有 %d 个项目的描述列表" - -#: src/cthulhu/messages.py:2718 -#, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "%d 个数值" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "有 %d 行的数学表格" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d 列" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "有 %d 行的嵌套数学表格" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d 条消息。\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "百分之 %d。" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "文档的百分之 %d 已读" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d 个像素" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d %(repeatChar)s 字母" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "选中了 %(total)d 条目中的 %(index)d 个" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "已找到 %d 个屏幕阅读器默认快捷键。" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "已找到 %(count)d 个 %(application)s 的屏幕阅读器快捷键。" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d 个空格" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d 个跳格" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d 个表格" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "未知大小的表格" - -#: src/cthulhu/messages.py:2834 -#, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "有 %d 列的表格,行数未知" - -#: src/cthulhu/messages.py:2842 -#, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "有 %d 行的表格,列数未知" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "有 %d 行的表格" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "%d 秒前" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "%d 分钟前" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "%d 小时前" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "%d 天前" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d 个未访问的连接" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d 个已经访问的连接" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "切换" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "在 %(total)d 的 %(index)d 上" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(total)d 的 %(index)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "第 %(index)d 个项目" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "等级 %d" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "树型等级 %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "树型等级 %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "%s 的详细信息" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "在 %s 中有详细信息" - -#: src/cthulhu/object_properties.py:116 -msgctxt "role" -msgid "suggestion" -msgstr "建议" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "可编辑的组合框" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "可编辑的内容" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "源" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "图表" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "概览" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "鸣谢" - -#: src/cthulhu/object_properties.py:161 -msgctxt "role" -msgid "afterword" -msgstr "后记" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "附录" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "参考项" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "参考书目" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "章节" - -#: src/cthulhu/object_properties.py:191 -msgctxt "role" -msgid "colophon" -msgstr "版权页" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "结论" - -#: src/cthulhu/object_properties.py:203 -msgctxt "role" -msgid "cover" -msgstr "封面" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "贡献者名单" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "贡献者名单" - -#: src/cthulhu/object_properties.py:221 -msgctxt "role" -msgid "dedication" -msgstr "献词" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "尾注" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "尾注" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "题词" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "结语" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "勘误表" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "示例" - -#: src/cthulhu/object_properties.py:263 -msgctxt "role" -msgid "foreword" -msgstr "前言" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "词汇表" - -#: src/cthulhu/object_properties.py:275 -msgctxt "role" -msgid "index" -msgstr "索引" - -#: src/cthulhu/object_properties.py:281 -msgctxt "role" -msgid "introduction" -msgstr "引言" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "分页符" - -#: src/cthulhu/object_properties.py:293 -msgctxt "role" -msgid "page list" -msgstr "页面列表" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "段" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "序言" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "序章" - -#: src/cthulhu/object_properties.py:317 -msgctxt "role" -msgid "pullquote" -msgstr "引用段" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "问答" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "副标题" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "目录" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s 水平 %(level)d" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "水平滚动条" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "竖直滚动条" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "水平滑块" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "竖直滑块" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "水平分割线" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "竖直分割线" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "切换角色" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "图标面板" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "条幅" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "互补内容" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "信息框" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "主内容" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "页面导航" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "区域" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "搜索" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "已经访问的连接" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "菜单按钮" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "已升序排序" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "已降序排序" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "已排序" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "可点击对象" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "已收起" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "已展开" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "有长描述" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "水平" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "竖直" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "已勾选" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "未勾选" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "打开" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "关闭" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "已部分勾选" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "已按下" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "未按下" - -#: src/cthulhu/object_properties.py:546 -msgctxt "listitem" -msgid "not selected" -msgstr "未选中" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "已选中" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "未选中" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "未选中" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "已访问过" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "未访问" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "变灰" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "只读" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "不可编辑" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "必需" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "多选" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "无效条目" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "无效" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "无效拼写" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "拼写" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "无效语法" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "语法" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "查找" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "屏幕阅读器查找对话框" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "关闭(_C)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "查找(_F)" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "搜索(_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "搜索:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "最上层窗口(_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "最上层窗口" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "开始自:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "环绕(_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "反向搜索(_B)" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "搜索方向:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "区分大小写(_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "匹配整个单词(_E)" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "选项:" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "默认" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "大写" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "超链接" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "系统" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "应用程序" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "窗口" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu 首选项" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "帮助(_H)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "应用(_A)" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "笔记本(_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "键盘布局" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "活动配置(_P):" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "启动配置:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "加载(_L)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "另存为(_A)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "移除(_R)" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "用户配置" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "当前工具栏提示(_P)" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "朗读鼠标下的对象(_U)" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "鼠标" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "时间格式(_T):" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "日期格式(_E):" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "日期和时间" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "朗读更新(_S)" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "盲文更新(_B)" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "频率(秒):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "适用于:" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "蜂鸣更新(_P)" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "进度条更新" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "在说出全部时启用从头开始和快进(_R)" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "在说出全部时启用结构化导航(_S)" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "朗读全部使用(_Y):" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "在朗读全部时朗读引用段" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "在朗读全部时朗读列表" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "在朗读全部时朗读表格" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "在朗读全部时朗读面板" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "在朗读全部时朗读表单" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "在朗读全部时朗读 landmark 元素" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "朗读全部" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "元素显示方式(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "常规" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "音量(_L):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "音调(_T):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "速度(_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "朗读者(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "语言(_L):" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "朗读合成器(_Z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "朗读系统(_S):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "语音类型(_V):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "大写字母类型(_C):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "语音类型设置" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "把多组字符串当做单词朗读(_D)" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "将数字以数码形式朗读(_N)" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "全局语音设置" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "语音" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "启用朗读(_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "详细(_B)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "详细程度" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "全部(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "标点符号级" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "仅朗读显示的文本" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "朗读空白的行" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "朗读缩排及对齐(_I)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "朗读对象助记符(_K)" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "朗读子项位置(_O)" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "朗读指导信息" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "详细显示系统信息(_S)" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "将颜色以名字形式朗读(_P)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "浏览时朗读引用段(_Q)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "浏览时朗读列表(_L)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "浏览时朗读表格(_T)" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "朗读错误拼写单词指示(_M)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "浏览时朗读面板(_P)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "浏览时朗读 landmark 元素" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "浏览时朗读表单(_F)" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "朗读描述(_D)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "朗读工作表里的整列(_R)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "朗读文档表格里的整列(_D)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "朗读图形界面表格里的整列(_G)" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "朗读上下文" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "朗读" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "启用点字支持(_S)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "缩写任务名称(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "禁用行尾符(_E)" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "收缩表(_T):" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "启用缩短的布莱叶盲文(_E)" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "启用自动换行(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "显示设置" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "无(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "选择指示器" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "超链接指示器" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "启用消息闪烁(_M)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "时长(秒)(_U):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "保持的消息(_P)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "消息的细节(_D)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "消息闪烁设置" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "盲文" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "启用按键朗读(_K)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "启用字母键(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "启用数字键(_U)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "启用标点键(_P)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "启用空格(_S)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "启用修饰键(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "启用功能键(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "启用动作键(_T)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "启用方向键(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "启用单词朗读(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "由语句启用 echo(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "按键朗读" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "屏幕阅读器修饰键(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "键绑定" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "发音词典" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "新项目(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "删除(_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "读音" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "全部朗读(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "什么都不读(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "复位(_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "文本属性" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "移动到底部(_B)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "下移一个(_D)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "上移一个(_U)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "移动到顶部(_T)" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "调整选中的属性" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "布莱叶盲文指示器" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "文本属性" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "启用 AI 助手" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "提供者(_P):" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (命令行)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (命令行)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (谷歌)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (本地 - 免费)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API 密钥文件(_K):" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "API 密钥文件路径" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "获取 _Claude API 密钥" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "打开浏览器获取 Claude API 密钥并自动保存" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "在执行 AI 操作前需要确认" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama 模型(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Ollama 模型名称(例如 llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama 端点(_E):" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API 端点 URL(例如 http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "截图质量(_Q):" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "低" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "中等" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "高" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI 助手" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "语言代码(_L):" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "缩放系数(_S):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "灰度图像(_G)" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "反转图像(_I)" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "黑白图像(_B)" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "黑白阈值(_T):" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "分析颜色(_A)" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "将结果复制到剪贴板(_C)" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "背景颜色" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "全高度背景" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "背景点画" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "方向" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "可编辑" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "族名称" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "前景色" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "前景点画" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "字体效果" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "缩进" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "错误" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "不可见" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "调整" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "语言" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "左边距" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "行高" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "段落风格" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "行之上的像素" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "行之下的像素" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "卷起内部元素" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "右边距" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "升起" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "缩放" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "大小" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "拉伸" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "贯穿" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "风格" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "文本修饰" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "文字旋转" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "文本阴影" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "下划线" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "变形" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "垂直对齐" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "粗细" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "换行模式" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "写作模式" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "真" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "假" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "无" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "阴文" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "阳文" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "大纲" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "上划线" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "贯穿线" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "闪烁" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "黑" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "单" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "双" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "低" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "字符" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "单词" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "单词字符" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "左至右" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "右至左" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "左" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "右" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "居中" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "无调整" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "填充" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "过度收缩" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "超出收缩" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "收缩" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "半收缩" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "普通" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "半展开" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "已展开" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "超出展开" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "过度展开" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "小型大写" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "倾斜" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "斜体" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "默认" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "文本正文" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "标题" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "基线" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "下降" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "升高" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "上" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "文本头" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "中间" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "底部" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "文本尾" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "继承" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "实心的" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "拼写" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "按空格来切换。" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "按空格键展开,并使用上下键选择项目。" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "按 alt+f6 将焦点给与子窗口。" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "要移动到条目。可以使用方向键或开始字符搜索。" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "要访问系统菜单,请按下 alt+f1 键。" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "使用上下键选择条目。" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "要收起,按下 shift 加 左 键。" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "要展开,按下 shift 加 右 键。" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "按回车键激活。" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "键入文本。" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "使用左向键或右向键查看其它标签。" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "按空格键激活。" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "使用上下箭头选择值。或者输入期望的数字值。" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "使用箭头更改。" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "要导航,按左键头或右箭头。要在条目间移动,按上下键。" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "要进入子菜单,按右箭头。" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "要减少按左箭头,要增加按右箭头。要转到最小按 home,最大按 end。" diff --git a/po/zh_HK.po b/po/zh_HK.po deleted file mode 100644 index cf0b80d..0000000 --- a/po/zh_HK.po +++ /dev/null @@ -1,9695 +0,0 @@ -# Chinese (Hong Kong) translation of Cthulhu. -# Copyright (C) 2006-07 Free Software Foundation, Inc. -# Woodman Tuen , 2006-07. -# Hialan Liu , 2008. -# Chao-Hsiung Liao , 2009, 2010. -# Wei-Lun Chao , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: Cthulhu 3.3.5pre\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2014-08-19 20:28+0800\n" -"Last-Translator: Chao-Hsiung Liao \n" -"Language-Team: Chinese (Hong Kong) \n" -"Language: zh_HK\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 1.6.5\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu 螢幕閱讀器" - -#, fuzzy -msgid "screen;reader;accessibility;speech;braille;" -msgstr "screen reader;speech;braille;螢幕閱讀器;語音;點字;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "表單" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "提示" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "捷克語(第一級)" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "西班牙文(第一級)" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "加拿大法語(第二級)" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "法國法語 (第二級)" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "拉脫維亞文(第一級)" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "荷蘭文(第一級)" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "挪威文(第零級)" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "挪威文(第一級)" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "挪威文(第二級)" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "挪威文(第三級)" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "波蘭文(第一級)" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "葡萄牙文(第一級)" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "瑞典文(第一級)" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "阿拉伯文(第一級)" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "威爾斯語(第一級)" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "威爾斯語(第二級)" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "德文(第零級)" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "德文(第一級)" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "德文(第二級)" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "英式英文(第二級)" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "英式英文(第一級)" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "美式英文(第一級)" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "美式英文(第二級)" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "加拿大法語(第一級)" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "法國法語(第一級)" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "希臘文(第一級)" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "北印度文(第一級)" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "匈牙利 8 點電腦" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "匈牙利語(第一級)" - -#: src/cthulhu/brltablenames.py:157 -#, fuzzy -msgid "Hungarian Grade 2" -msgstr "匈牙利語(第一級)" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "意大利文(第一級)" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "比利時荷蘭文(第一級)" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "空白" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "換列" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "感歎號" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "引號" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "井字號" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "圓" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "and" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "撇號" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "左小括弧" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "右小括弧" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "星號" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "加號" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "逗號" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "破折號" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "點" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "斜線" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "冒號" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "分號" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "小於" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "等於" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "大於" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "問號" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "左中括號" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "倒斜線" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "右中括號" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "caret" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "底線" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "左大括號" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertical bar" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "右大括號" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "波紋號" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "沒有斷開的空白" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "inverted exclamation point" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cents" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "鎊" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "currency sign" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "日元" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "broken bar" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "章節" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "分音符" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "版權" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "left double angle bracket" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logical not" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "soft hyphen" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registered" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "度" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "加減" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superscript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superscript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acute" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "段落標記" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "middle dot" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superscript 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "right double angle bracket" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "one fourth" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "one half" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "three fourths" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "倒問號" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "乘" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "除以" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "左單引號" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "右單引號" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "下單引號" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "左雙引號" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "右雙引號" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "下雙引號" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "dagger" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "double dagger" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "項目符號" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "三角項目符號" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prime" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "double prime" - -#: src/cthulhu/chnames.py:637 -#, fuzzy -msgid "triple prime" -msgstr "double prime" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "hyphen bullet" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "歐元" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "註冊商標" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "check mark" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "heavy check mark" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x型項目符號" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "上標 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "上標 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "上標 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "上標 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "上標 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "上標 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "上標 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "上標加號" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "上標減號" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "上標等號" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "上標左括號" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "上標右括號" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "上標 n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "下標 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "下標 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "下標 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "下標 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "下標 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "下標 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "下標 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "下標 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "下標 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "下標 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "下標加號" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "下標減號" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "下標等號" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "下標左括號" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "下標右括號" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "實心方框" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "實心菱形" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "物件置換字符" - -#: src/cthulhu/cmdnames.py:42 -#, fuzzy -msgid "Route the pointer to the current item" -msgstr "將指標轉向目前的項目。" - -#: src/cthulhu/cmdnames.py:50 -#, fuzzy -msgid "Perform left click on current flat review item" -msgstr "在目前的 flat review 項目中按下左鍵" - -#: src/cthulhu/cmdnames.py:58 -#, fuzzy -msgid "Perform right click on current flat review item" -msgstr "在目前的 flat review 項目中按下右鍵" - -#: src/cthulhu/cmdnames.py:64 -#, fuzzy -msgid "Speak entire document" -msgstr "讀出整個文件。" - -#: src/cthulhu/cmdnames.py:72 -#, fuzzy -msgid "Speak entire window using flat review" -msgstr "未使用 flat review。" - -#: src/cthulhu/cmdnames.py:78 -#, fuzzy -msgid "Perform the basic Where Am I operation" -msgstr "進行基本的「我在哪裏」操作。" - -#: src/cthulhu/cmdnames.py:84 -#, fuzzy -msgid "Perform the detailed Where Am I operation" -msgstr "進行詳細的「我在哪裏」操作。" - -#: src/cthulhu/cmdnames.py:91 -#, fuzzy -msgid "Speak the current selection" -msgstr "讀出目前的 flat review 列。" - -#: src/cthulhu/cmdnames.py:95 -#, fuzzy -msgid "Speak link details" -msgstr "讀出空白的列" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "呈現預設按鈕" - -#: src/cthulhu/cmdnames.py:105 -#, fuzzy -msgid "Present the status bar" -msgstr "讀出狀態列。" - -#: src/cthulhu/cmdnames.py:109 -#, fuzzy -msgid "Present the title bar" -msgstr "讀出標題列。" - -#: src/cthulhu/cmdnames.py:114 -#, fuzzy -msgid "Open the Find dialog" -msgstr "開啟「尋找」對話盒。" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "" - -#: src/cthulhu/cmdnames.py:124 -#, fuzzy -msgid "Search for the next instance of a string" -msgstr "搜尋下一個相同的字串。" - -#: src/cthulhu/cmdnames.py:130 -#, fuzzy -msgid "Search for the previous instance of a string" -msgstr "搜尋上一個相同的字串。" - -#: src/cthulhu/cmdnames.py:137 -#, fuzzy -msgid "Enter and exit flat review mode" -msgstr "進入及離開 flat review 模式。" - -#: src/cthulhu/cmdnames.py:145 -#, fuzzy -msgid "Toggle restricting flat review to the current object" -msgstr "將 flat review 移至最尾位置。" - -#: src/cthulhu/cmdnames.py:153 -#, fuzzy -msgid "Move flat review to the home position" -msgstr "將 flat review 移至家位置。" - -#: src/cthulhu/cmdnames.py:161 -#, fuzzy -msgid "Move flat review to the end position" -msgstr "將 flat review 移至最尾位置。" - -#: src/cthulhu/cmdnames.py:169 -#, fuzzy -msgid "Move flat review to the beginning of the previous line" -msgstr "將 flat review 移至上一列的列首。" - -#: src/cthulhu/cmdnames.py:176 -#, fuzzy -msgid "Speak the current flat review line" -msgstr "讀出目前的 flat review 列。" - -#: src/cthulhu/cmdnames.py:185 -#, fuzzy -msgid "Spell the current flat review line" -msgstr "拼出目前的 flat review 列。" - -#: src/cthulhu/cmdnames.py:195 -#, fuzzy -msgid "Phonetically spell the current flat review line" -msgstr "拼出目前的 flat review 文字列。" - -#: src/cthulhu/cmdnames.py:202 -#, fuzzy -msgid "Move flat review to the beginning of the next line" -msgstr "將 flat review 移至下一列的列首。" - -#: src/cthulhu/cmdnames.py:211 -#, fuzzy -msgid "Move flat review to the previous item or word" -msgstr "將 flat review 移至上一個字符或字詞。" - -#: src/cthulhu/cmdnames.py:219 -#, fuzzy -msgid "Speak the current flat review item or word" -msgstr "讀出目前的 flat review 項目或字詞。" - -#: src/cthulhu/cmdnames.py:228 -#, fuzzy -msgid "Spell the current flat review item or word" -msgstr "拼出目前的 flat review 項目或字詞。" - -#: src/cthulhu/cmdnames.py:239 -#, fuzzy -msgid "Phonetically spell the current flat review item or word" -msgstr "拼出目前的 flat review 項目或字詞。" - -#: src/cthulhu/cmdnames.py:248 -#, fuzzy -msgid "Move flat review to the next item or word" -msgstr "將 flat review 移至下一個項目或字詞。" - -#: src/cthulhu/cmdnames.py:257 -#, fuzzy -msgid "Move flat review to the word above the current word" -msgstr "將 flat review 移至目前字詞之上。" - -#: src/cthulhu/cmdnames.py:267 -#, fuzzy -msgid "Speak the current flat review object" -msgstr "讀出目前的 flat review 物件。" - -#: src/cthulhu/cmdnames.py:276 -#, fuzzy -msgid "Move flat review to the word below the current word" -msgstr "將 flat review 移至目前字詞之下。" - -#: src/cthulhu/cmdnames.py:285 -#, fuzzy -msgid "Move flat review to the previous character" -msgstr "將 flat review 移至上一個字符。" - -#: src/cthulhu/cmdnames.py:293 -#, fuzzy -msgid "Speak the current flat review character" -msgstr "讀出目前的 flat review 字符。" - -#: src/cthulhu/cmdnames.py:303 -#, fuzzy -msgid "Phonetically speak the current flat review character" -msgstr "讀出目前的 flat review 字符。" - -#: src/cthulhu/cmdnames.py:313 -#, fuzzy -msgid "Speak unicode value of the current flat review character" -msgstr "讀出目前的 flat review 字符的 unicode 數值。" - -#: src/cthulhu/cmdnames.py:322 -#, fuzzy -msgid "Move flat review to the next character" -msgstr "將 flat review 移至下一個字符。" - -#: src/cthulhu/cmdnames.py:330 -#, fuzzy -msgid "Move flat review to the end of the line" -msgstr "將 flat review 移至行尾。" - -#: src/cthulhu/cmdnames.py:338 -#, fuzzy -msgid "Move flat review to the bottom left" -msgstr "將 flat review 移至左下。" - -#: src/cthulhu/cmdnames.py:347 -#, fuzzy -msgid "Copy the contents under flat review to the clipboard" -msgstr "將目前的 flat review 內容複製到剪貼簿。" - -#: src/cthulhu/cmdnames.py:357 -#, fuzzy -msgid "Append the contents under flat review to the clipboard" -msgstr "將目前的 flat review 內容添加到剪貼簿。" - -#: src/cthulhu/cmdnames.py:368 -#, fuzzy -msgid "Show flat review contents" -msgstr "將 flat review 移至最尾位置。" - -#: src/cthulhu/cmdnames.py:374 -#, fuzzy -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "切換應否閱讀目前的表格或整列。" - -#: src/cthulhu/cmdnames.py:379 -#, fuzzy -msgid "Read the attributes associated with the current text character" -msgstr "閱讀目前字符相關的屬性。" - -#: src/cthulhu/cmdnames.py:386 -#, fuzzy -msgid "Pan the braille display to the left" -msgstr "點字顯示向左移。" - -#: src/cthulhu/cmdnames.py:393 -#, fuzzy -msgid "Pan the braille display to the right" -msgstr "點字顯示向右移。" - -#: src/cthulhu/cmdnames.py:403 -#, fuzzy -msgid "Return to object with keyboard focus" -msgstr "回到有鍵盤焦點的物件" - -#: src/cthulhu/cmdnames.py:409 -#, fuzzy -msgid "Turn contracted braille on and off" -msgstr "開啟和關閉縮短式點字。" - -#: src/cthulhu/cmdnames.py:414 -#, fuzzy -msgid "Process a cursor routing key" -msgstr "處理游標轉向鍵。" - -#: src/cthulhu/cmdnames.py:417 -#, fuzzy -msgid "Mark the beginning of a text selection" -msgstr "標記文字選擇區域的開頭。" - -#: src/cthulhu/cmdnames.py:420 -#, fuzzy -msgid "Mark the end of a text selection" -msgstr "標記文字選擇區域的結尾。" - -#: src/cthulhu/cmdnames.py:427 -#, fuzzy -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "進入學習模式。 按離開鍵離開學習模式。" - -#: src/cthulhu/cmdnames.py:431 -#, fuzzy -msgid "Decrease the speech rate" -msgstr "減慢朗讀速度。" - -#: src/cthulhu/cmdnames.py:435 -#, fuzzy -msgid "Increase the speech rate" -msgstr "加快朗讀速度。" - -#: src/cthulhu/cmdnames.py:439 -#, fuzzy -msgid "Decrease the speech pitch" -msgstr "減低朗讀音調。" - -#: src/cthulhu/cmdnames.py:443 -#, fuzzy -msgid "Increase the speech pitch" -msgstr "加高朗讀音調。" - -#: src/cthulhu/cmdnames.py:447 -#, fuzzy -msgid "Increase the speech volume" -msgstr "加快朗讀速度。" - -#: src/cthulhu/cmdnames.py:451 -#, fuzzy -msgid "Decrease the speech volume" -msgstr "減慢朗讀速度。" - -#: src/cthulhu/cmdnames.py:454 -#, fuzzy -msgid "Select the previous speech setting" -msgstr "選擇偏好的語音伺服器。" - -#: src/cthulhu/cmdnames.py:457 -#, fuzzy -msgid "Select the next speech setting" -msgstr "選擇偏好的語音伺服器。" - -#: src/cthulhu/cmdnames.py:460 -#, fuzzy -msgid "Decrease the current speech setting" -msgstr "減慢朗讀速度。" - -#: src/cthulhu/cmdnames.py:463 -#, fuzzy -msgid "Increase the current speech setting" -msgstr "加快朗讀速度。" - -#: src/cthulhu/cmdnames.py:466 -#, fuzzy -msgid "Save speech settings" -msgstr "語音類型設定值" - -#: src/cthulhu/cmdnames.py:470 -#, fuzzy -msgid "Toggle the silencing of speech" -msgstr "切換為靜音。" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "" - -#: src/cthulhu/cmdnames.py:479 -#, fuzzy -msgid "Toggle sleep mode" -msgstr "切換滑鼠預覽模式。" - -#: src/cthulhu/cmdnames.py:483 -#, fuzzy -msgid "Quit the screen reader" -msgstr "結束螢幕閱讀器" - -#: src/cthulhu/cmdnames.py:487 -#, fuzzy -msgid "Display the preferences configuration dialog" -msgstr "顯示偏好設定對話視窗。" - -#: src/cthulhu/cmdnames.py:492 -#, fuzzy -msgid "Display the application preferences configuration dialog" -msgstr "顯示偏好設定對話盒。" - -#: src/cthulhu/cmdnames.py:497 -#, fuzzy -msgid "Toggle the speaking of indentation and justification" -msgstr "切換是否讀出縮排及對齊。" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "" - -#: src/cthulhu/cmdnames.py:507 -#, fuzzy -msgid "Cycle to the next speaking of punctuation level" -msgstr "循環至下一個標音符號等級。" - -#: src/cthulhu/cmdnames.py:512 -#, fuzzy -msgid "Cycle to the next speech synthesizer" -msgstr "循環至下一個按鍵回響等級。" - -#: src/cthulhu/cmdnames.py:520 -#, fuzzy -msgid "Cycle to the next settings profile" -msgstr "循環至下一個設定組合。" - -#: src/cthulhu/cmdnames.py:529 -#, fuzzy -msgid "Cycle to the next capitalization style" -msgstr "循環至下一個大寫樣式。" - -#: src/cthulhu/cmdnames.py:541 -#, fuzzy -msgid "Cycle to the next key echo level" -msgstr "循環至下一個按鍵回響等級。" - -#: src/cthulhu/cmdnames.py:546 -#, fuzzy -msgid "Cycle the debug level at run time" -msgstr "在執行時圈出偵錯級別。" - -#: src/cthulhu/cmdnames.py:553 -#, fuzzy -msgid "Bookmark where am I with respect to current position" -msgstr "指出我目前位置到書籤的相對關係" - -#: src/cthulhu/cmdnames.py:559 -#, fuzzy -msgid "Go to previous bookmark location" -msgstr "移至上一個書籤位置。" - -#: src/cthulhu/cmdnames.py:564 -#, fuzzy -msgid "Go to bookmark" -msgstr "移至書籤。" - -#: src/cthulhu/cmdnames.py:570 -#, fuzzy -msgid "Go to next bookmark location" -msgstr "移至下一個書籤位置。" - -#: src/cthulhu/cmdnames.py:574 -#, fuzzy -msgid "Add bookmark" -msgstr "加入書籤。" - -#: src/cthulhu/cmdnames.py:578 -#, fuzzy -msgid "Save bookmarks" -msgstr "儲存書籤。" - -#: src/cthulhu/cmdnames.py:582 -#, fuzzy -msgid "Toggle mouse review mode" -msgstr "切換滑鼠預覽模式。" - -#: src/cthulhu/cmdnames.py:586 -#, fuzzy -msgid "Present current time" -msgstr "表示目前的時刻。" - -#: src/cthulhu/cmdnames.py:590 -#, fuzzy -msgid "Present current date" -msgstr "表示目前的日期。" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -#, fuzzy -msgid "Pass the next command on to the current application" -msgstr "傳送「下一步」指令給目前的應用程式" - -#: src/cthulhu/cmdnames.py:607 -#, fuzzy -msgid "Speak and braille a previous chat room message" -msgstr "讀出及點出上一個聊天室的訊息。" - -#: src/cthulhu/cmdnames.py:615 -#, fuzzy -msgid "Toggle whether we announce when our buddies are typing" -msgstr "切換當我們的朋友在輸入時是否告知我們。" - -#: src/cthulhu/cmdnames.py:625 -#, fuzzy -msgid "Toggle whether we provide chat room specific message histories" -msgstr "切換是否提供指定聊天室的的訊息歷史紀錄。" - -#: src/cthulhu/cmdnames.py:636 -#, fuzzy -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "切換是否將聊天室的名稱加入聊天室的訊息前。" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "向左一列" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "向右一列" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "向上一列" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "向下一列" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "固定" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "左上" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "左下" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "游標位置" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "六點" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "游標轉向" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "剪下開頭" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "剪下行" - -#: src/cthulhu/cmdnames.py:707 -#, fuzzy -msgid "Present last notification message" -msgstr "顯示上次的通知訊息。" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "顯示通知訊息清單" - -#: src/cthulhu/cmdnames.py:715 -#, fuzzy -msgid "Present previous notification message" -msgstr "顯示前一個通知訊息。" - -#: src/cthulhu/cmdnames.py:719 -#, fuzzy -msgid "Present next notification message" -msgstr "顯示上次的通知訊息。" - -#: src/cthulhu/cmdnames.py:722 -#, fuzzy -msgid "Go to next character" -msgstr "移至下一個字符。" - -#: src/cthulhu/cmdnames.py:725 -#, fuzzy -msgid "Go to previous character" -msgstr "移至前一個字符。" - -#: src/cthulhu/cmdnames.py:728 -#, fuzzy -msgid "Go to next word" -msgstr "移至下一個單字。" - -#: src/cthulhu/cmdnames.py:731 -#, fuzzy -msgid "Go to previous word" -msgstr "移至下一個單字。" - -#: src/cthulhu/cmdnames.py:734 -#, fuzzy -msgid "Go to next line" -msgstr "移至下一列。" - -#: src/cthulhu/cmdnames.py:737 -#, fuzzy -msgid "Go to previous line" -msgstr "移至上一列。" - -#: src/cthulhu/cmdnames.py:740 -#, fuzzy -msgid "Go to the top of the file" -msgstr "移至檔案的最上面。" - -#: src/cthulhu/cmdnames.py:743 -#, fuzzy -msgid "Go to the bottom of the file" -msgstr "移至檔案的最下面。" - -#: src/cthulhu/cmdnames.py:746 -#, fuzzy -msgid "Go to the beginning of the line" -msgstr "移至行首。" - -#: src/cthulhu/cmdnames.py:749 -#, fuzzy -msgid "Go to the end of the line" -msgstr "移至行尾。" - -#: src/cthulhu/cmdnames.py:752 -#, fuzzy -msgid "Go to the next object" -msgstr "移至下一個物件。" - -#: src/cthulhu/cmdnames.py:755 -#, fuzzy -msgid "Go to the previous object" -msgstr "移至上一個物件。" - -#: src/cthulhu/cmdnames.py:760 -#, fuzzy -msgid "Cause the current combo box to be expanded" -msgstr "使目前的組合方塊展開。" - -#: src/cthulhu/cmdnames.py:767 -#, fuzzy -msgid "Switch between native and screen-reader caret navigation" -msgstr "在原生瀏覽與鍵盤瀏覽方式間切換。" - -#: src/cthulhu/cmdnames.py:776 -#, fuzzy -msgid "Advance live region politeness setting" -msgstr "進階即時播報區禮貌程度設定值。" - -#: src/cthulhu/cmdnames.py:786 -#, fuzzy -msgid "Set default live region politeness level to off" -msgstr "設定預設的即時播報區禮貌程度為關閉。" - -#: src/cthulhu/cmdnames.py:792 -#, fuzzy -msgid "Review live region announcement" -msgstr "檢閱即時播報區公告。" - -#: src/cthulhu/cmdnames.py:803 -#, fuzzy -msgid "Monitor live regions" -msgstr "監控即時播報區。" - -#: src/cthulhu/cmdnames.py:810 -#, fuzzy -msgid "Move focus into and away from the current mouse over" -msgstr "將焦點移入或移出目前滑鼠停駐的位置。" - -#: src/cthulhu/cmdnames.py:815 -#, fuzzy -msgid "Set the row to use as dynamic column headers" -msgstr "將列設定為使用動態欄標頭。" - -#: src/cthulhu/cmdnames.py:821 -#, fuzzy -msgid "Clear the dynamic column headers" -msgstr "清除動態欄標頭。" - -#: src/cthulhu/cmdnames.py:826 -#, fuzzy -msgid "Set the column to use as dynamic row headers" -msgstr "將欄設定為使用動態列標頭。" - -#: src/cthulhu/cmdnames.py:832 -#, fuzzy -msgid "Clear the dynamic row headers" -msgstr "清除動態式列標題" - -#: src/cthulhu/cmdnames.py:836 -#, fuzzy -msgid "Present the contents of the input line" -msgstr "表示輸入行的內容。" - -#: src/cthulhu/cmdnames.py:843 -#, fuzzy -msgid "Toggle structural navigation keys" -msgstr "切換結構導覽鍵。" - -#: src/cthulhu/cmdnames.py:846 -#, fuzzy -msgid "Go to previous blockquote" -msgstr "移至前一個區塊括弧。" - -#: src/cthulhu/cmdnames.py:849 -#, fuzzy -msgid "Go to next blockquote" -msgstr "移至下一個區塊括弧。" - -#: src/cthulhu/cmdnames.py:852 -#, fuzzy -msgid "Display a list of blockquotes" -msgstr "顯示區塊括弧清單。" - -#: src/cthulhu/cmdnames.py:855 -#, fuzzy -msgid "Go to previous button" -msgstr "移至前一個按鈕。" - -#: src/cthulhu/cmdnames.py:858 -#, fuzzy -msgid "Go to next button" -msgstr "移至下一個按鈕。" - -#: src/cthulhu/cmdnames.py:861 -#, fuzzy -msgid "Display a list of buttons" -msgstr "顯示按鈕清單。" - -#: src/cthulhu/cmdnames.py:864 -#, fuzzy -msgid "Go to previous check box" -msgstr "移至前一個核取方塊。" - -#: src/cthulhu/cmdnames.py:867 -#, fuzzy -msgid "Go to next check box" -msgstr "移至下一個核取方塊。" - -#: src/cthulhu/cmdnames.py:870 -#, fuzzy -msgid "Display a list of check boxes" -msgstr "顯示核取方塊清單。" - -#: src/cthulhu/cmdnames.py:874 -#, fuzzy -msgid "Go to previous clickable" -msgstr "移至前一個可按下項目。" - -#: src/cthulhu/cmdnames.py:878 -#, fuzzy -msgid "Go to next clickable" -msgstr "移至下一個可按下項目。" - -#: src/cthulhu/cmdnames.py:882 -#, fuzzy -msgid "Display a list of clickables" -msgstr "顯示可按下項目清單。" - -#: src/cthulhu/cmdnames.py:885 -#, fuzzy -msgid "Go to previous combo box" -msgstr "移至前一個組合方塊。" - -#: src/cthulhu/cmdnames.py:888 -#, fuzzy -msgid "Go to next combo box" -msgstr "移至下一個組合方塊。" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "" - -#: src/cthulhu/cmdnames.py:898 -#, fuzzy -msgid "Go to end of container" -msgstr "移至行尾。" - -#: src/cthulhu/cmdnames.py:901 -#, fuzzy -msgid "Display a list of combo boxes" -msgstr "顯示組合方塊清單。" - -#: src/cthulhu/cmdnames.py:904 -#, fuzzy -msgid "Go to previous entry" -msgstr "移至前一個項目。" - -#: src/cthulhu/cmdnames.py:907 -#, fuzzy -msgid "Go to next entry" -msgstr "移至下一個項目。" - -#: src/cthulhu/cmdnames.py:910 -#, fuzzy -msgid "Display a list of entries" -msgstr "顯示項目清單。" - -#: src/cthulhu/cmdnames.py:913 -#, fuzzy -msgid "Go to previous form field" -msgstr "移至前一個表單欄位。" - -#: src/cthulhu/cmdnames.py:916 -#, fuzzy -msgid "Go to next form field" -msgstr "移至下一個表單欄位。" - -#: src/cthulhu/cmdnames.py:919 -#, fuzzy -msgid "Display a list of form fields" -msgstr "顯示表單欄位清單。" - -#: src/cthulhu/cmdnames.py:922 -#, fuzzy -msgid "Go to previous heading" -msgstr "移至前一個標題。" - -#: src/cthulhu/cmdnames.py:925 -#, fuzzy -msgid "Go to next heading" -msgstr "移至下一個標題。" - -#: src/cthulhu/cmdnames.py:928 -#, fuzzy -msgid "Display a list of headings" -msgstr "顯示標題清單。" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "移至前一個第 %d 級標題。" - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "移至下一個第 %d 級標題。" - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "顯示第 %d 級標題清單。" - -#: src/cthulhu/cmdnames.py:943 -#, fuzzy -msgid "Go to previous internal frame" -msgstr "移至前一個工作表。" - -#: src/cthulhu/cmdnames.py:946 -#, fuzzy -msgid "Go to next internal frame" -msgstr "移至下一個工作表。" - -#: src/cthulhu/cmdnames.py:949 -#, fuzzy -msgid "Display a list of internal frames" -msgstr "顯示表格清單。" - -#: src/cthulhu/cmdnames.py:952 -#, fuzzy -msgid "Go to previous image" -msgstr "移至前一個影像。" - -#: src/cthulhu/cmdnames.py:955 -#, fuzzy -msgid "Go to next image" -msgstr "移至下一個影像。" - -#: src/cthulhu/cmdnames.py:958 -#, fuzzy -msgid "Display a list of images" -msgstr "顯示影像清單。" - -#: src/cthulhu/cmdnames.py:963 -#, fuzzy -msgid "Go to previous landmark" -msgstr "移至前一個地標。" - -#: src/cthulhu/cmdnames.py:968 -#, fuzzy -msgid "Go to next landmark" -msgstr "移至下一個地標。" - -#: src/cthulhu/cmdnames.py:973 -#, fuzzy -msgid "Display a list of landmarks" -msgstr "顯示地標清單。" - -#: src/cthulhu/cmdnames.py:978 -#, fuzzy -msgid "Go to previous large object" -msgstr "移至前一個大型物件。" - -#: src/cthulhu/cmdnames.py:983 -#, fuzzy -msgid "Go to next large object" -msgstr "移至下一個大型物件。" - -#: src/cthulhu/cmdnames.py:988 -#, fuzzy -msgid "Display a list of large objects" -msgstr "顯示大型物件清單。" - -#: src/cthulhu/cmdnames.py:991 -#, fuzzy -msgid "Go to previous link" -msgstr "移至前一個連結。" - -#: src/cthulhu/cmdnames.py:994 -#, fuzzy -msgid "Go to next link" -msgstr "移至下一個連結。" - -#: src/cthulhu/cmdnames.py:997 -#, fuzzy -msgid "Display a list of links" -msgstr "顯示連結清單。" - -#: src/cthulhu/cmdnames.py:1000 -#, fuzzy -msgid "Go to previous list" -msgstr "移至前一個清單。" - -#: src/cthulhu/cmdnames.py:1003 -#, fuzzy -msgid "Go to next list" -msgstr "移至下一個清單。" - -#: src/cthulhu/cmdnames.py:1006 -#, fuzzy -msgid "Display a list of lists" -msgstr "顯示清單的列表。" - -#: src/cthulhu/cmdnames.py:1009 -#, fuzzy -msgid "Go to previous list item" -msgstr "移至前一個清單項目。" - -#: src/cthulhu/cmdnames.py:1012 -#, fuzzy -msgid "Go to next list item" -msgstr "移至下一個清單項目。" - -#: src/cthulhu/cmdnames.py:1015 -#, fuzzy -msgid "Display a list of list items" -msgstr "顯示清單項目清單。" - -#: src/cthulhu/cmdnames.py:1020 -#, fuzzy -msgid "Go to previous live region" -msgstr "移至前一個即時播報區。" - -#: src/cthulhu/cmdnames.py:1025 -#, fuzzy -msgid "Go to next live region" -msgstr "移至下一個即時播報區。" - -#: src/cthulhu/cmdnames.py:1030 -#, fuzzy -msgid "Go to the last live region which made an announcement" -msgstr "發布公告時移至即時播報區。" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "前往導航器焦點物件的父物件。" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "前往導航器焦點物件的第一個子物件。" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "前往導航器焦點物件的下一個同層物件。" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "前往導航器焦點物件的上一個同層物件。" - -#: src/cthulhu/cmdnames.py:1050 -#, fuzzy -msgid "Click on the object with navigator focus." -msgstr "回到有鍵盤焦點的物件" - -#: src/cthulhu/cmdnames.py:1055 -#, fuzzy -msgid "Toggle simplified object navigation." -msgstr "切換結構導覽鍵。" - -#: src/cthulhu/cmdnames.py:1058 -#, fuzzy -msgid "Go to previous paragraph" -msgstr "移至前一段。" - -#: src/cthulhu/cmdnames.py:1061 -#, fuzzy -msgid "Go to next paragraph" -msgstr "移至下一段。" - -#: src/cthulhu/cmdnames.py:1064 -#, fuzzy -msgid "Display a list of paragraphs" -msgstr "顯示段落清單。" - -#: src/cthulhu/cmdnames.py:1067 -#, fuzzy -msgid "Go to previous radio button" -msgstr "移至前一個單選按鈕。" - -#: src/cthulhu/cmdnames.py:1070 -#, fuzzy -msgid "Go to next radio button" -msgstr "移至下一個單選按鈕。" - -#: src/cthulhu/cmdnames.py:1073 -#, fuzzy -msgid "Display a list of radio buttons" -msgstr "顯示單選按鈕清單。" - -#: src/cthulhu/cmdnames.py:1077 -#, fuzzy -msgid "Go to previous separator" -msgstr "移至前一個分隔符。" - -#: src/cthulhu/cmdnames.py:1081 -#, fuzzy -msgid "Go to next separator" -msgstr "移至下一個分隔符。" - -#: src/cthulhu/cmdnames.py:1084 -#, fuzzy -msgid "Go to previous table" -msgstr "移至前一個工作表。" - -#: src/cthulhu/cmdnames.py:1087 -#, fuzzy -msgid "Go to next table" -msgstr "移至下一個工作表。" - -#: src/cthulhu/cmdnames.py:1090 -#, fuzzy -msgid "Display a list of tables" -msgstr "顯示表格清單。" - -#: src/cthulhu/cmdnames.py:1093 -#, fuzzy -msgid "Go down one cell" -msgstr "移至下面一個儲存格。" - -#: src/cthulhu/cmdnames.py:1096 -#, fuzzy -msgid "Go to the first cell in a table" -msgstr "移至表格中的第一個儲存格。" - -#: src/cthulhu/cmdnames.py:1099 -#, fuzzy -msgid "Go to the last cell in a table" -msgstr "移至表格中的最後一個儲存格。" - -#: src/cthulhu/cmdnames.py:1102 -#, fuzzy -msgid "Go left one cell" -msgstr "移至左邊一個儲存格。" - -#: src/cthulhu/cmdnames.py:1105 -#, fuzzy -msgid "Go right one cell" -msgstr "移至右邊一個儲存格。" - -#: src/cthulhu/cmdnames.py:1108 -#, fuzzy -msgid "Go up one cell" -msgstr "移至上面一個儲存格。" - -#: src/cthulhu/cmdnames.py:1121 -#, fuzzy -msgid "Toggle layout mode" -msgstr "切換滑鼠預覽模式。" - -#: src/cthulhu/cmdnames.py:1137 -#, fuzzy -msgid "Switch between browse mode and focus mode" -msgstr "切換瀏覽模式與焦點模式。" - -#: src/cthulhu/cmdnames.py:1148 -#, fuzzy -msgid "Enable sticky focus mode" -msgstr "啟用黏性焦點模式。" - -#: src/cthulhu/cmdnames.py:1159 -#, fuzzy -msgid "Enable sticky browse mode" -msgstr "啟用黏性焦點模式。" - -#: src/cthulhu/cmdnames.py:1162 -#, fuzzy -msgid "Go to previous unvisited link" -msgstr "移至前一個未瀏覽的連結。" - -#: src/cthulhu/cmdnames.py:1165 -#, fuzzy -msgid "Go to next unvisited link" -msgstr "移至下一個未瀏覽連結。" - -#: src/cthulhu/cmdnames.py:1168 -#, fuzzy -msgid "Display a list of unvisited links" -msgstr "顯示未瀏覽連結清單。" - -#: src/cthulhu/cmdnames.py:1171 -#, fuzzy -msgid "Go to previous visited link" -msgstr "移至前一個瀏覽過的連結。" - -#: src/cthulhu/cmdnames.py:1174 -#, fuzzy -msgid "Go to next visited link" -msgstr "移至下一個瀏覽過的連結。" - -#: src/cthulhu/cmdnames.py:1177 -#, fuzzy -msgid "Display a list of visited links" -msgstr "顯示已瀏覽連結清單。" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "愛麗絲藍" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "古董白" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "碧寶石碧綠" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "蔚藍色" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "米黃色" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "陶坯黃" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "黑色" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "杏仁白" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "藍色" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "藍紫色" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "棕色" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "硬木色" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "軍服藍" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "查特酒綠" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "巧克力色" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "珊瑚色" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "矢車菊藍" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "玉米絲色" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "緋紅" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "青色" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "暗藍" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr " \t暗青" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "暗金菊色" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "暗灰色" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "暗綠" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "暗卡其色" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "暗洋紅" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "暗橄欖綠" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "暗橙" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "暗蘭紫" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "暗紅" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "暗鮭紅" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "暗海綠" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "暗岩藍" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "暗岩灰" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "暗綠松石色" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "暗紫" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "深粉紅" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "深天藍" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "暗淡灰色" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "道奇藍" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "耐火磚紅" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "花卉白" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "森林綠" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "品紅色" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "庚斯博羅灰" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr " \t幽靈白" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "金色" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "金菊色" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "灰色" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "綠色" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "綠黃" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "蜜瓜綠" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "暖粉紅" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "印度紅" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "靛色" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "象牙色" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "卡其色" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "薰衣草紫" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "薰衣草紫紅" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "草坪綠" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "檸檬綢色" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "亮藍" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "亮珊瑚色" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "亮青" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "亮金菊黃" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "亮灰色" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "亮綠" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "亮粉紅" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "亮鮭紅" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "亮海綠" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "亮天藍" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "亮岩灰" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "亮鋼藍" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "亮黃" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "鮮綠色" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "檸檬綠" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "亞麻色" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "洋紅" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "栗色" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "中碧藍色" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "中藍" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "中蘭紫" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "中紫紅" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "中海綠" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "中岩藍" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "中春綠色" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "中綠松石色" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "中青紫紅" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "午夜藍" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "薄荷奶油色" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "霧玫瑰色" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "鹿皮鞋色" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "那瓦霍白" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "海軍藍" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "舊蕾絲色" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "橄欖色" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "橄欖軍服綠" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "橙色" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "橙紅" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "蘭花紫" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "灰金菊色" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "灰綠" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "灰綠松石色" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "灰紫紅" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "蕃木瓜色" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "粉撲桃色" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "秘魯色" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "粉紅" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr " \t洋李色" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "嬰兒粉藍" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "紫色" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "紅色" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "玫瑰褐" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "品藍" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "鞍褐" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "鮭紅" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "沙棕色" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "暗海綠" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "海貝殼" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr " \t黃土赭色" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "銀色" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "天藍" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "岩藍" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "岩灰" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "雪白色" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "春綠" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "鋼青色" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "日曬色" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "水鴨色" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "薊色" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "番茄紅" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "綠寶石" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "礦紫" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "小麥色" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "白色" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "白煙色" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "黃色" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "黃綠" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "使用(_A)" - -#: src/cthulhu/guilabels.py:63 -#, fuzzy -msgid "Automatic focus mode during structural navigation" -msgstr "啟用結構式瀏覽(_S)" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "_7 點" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "_8 點" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "7 和 8 點(_D)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "取消(_C)" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "跳至(_J)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "確定(_O)" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "沒有" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "讀出" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "當你的朋友在輸入時告知(_B)" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "提供指定聊天室的訊息歷史紀錄(_M)" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "讀出訊息於" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "所有頻道(_N)" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "當任何 %s 視窗在使用中的所有頻道(_Y)" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "只有使用中視窗的頻道(_W)" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "讀出聊天室名稱(_S)" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "連按兩下" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "三擊" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "預設語音合成器" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "實際字串" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "置換字串" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "啟用字詞回響(_R)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "啟用非空白區別設定鍵(_D)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "目前位置(_U)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "比對文字的最小長度:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "「尋找」選項" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "尋找時只讀出有改變的列(_Y)" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "尋找時讀出結果(_F)" - -#: src/cthulhu/guilabels.py:270 -#, fuzzy -msgid "Command" -msgstr "逗號" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "按鍵組合" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "預設" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "書寫模式" - -#: src/cthulhu/guilabels.py:290 -#, fuzzy -msgid "Actions" -msgstr "章節" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "點字按鍵組合" - -#: src/cthulhu/guilabels.py:300 -#, fuzzy -msgid "Bookmarks" -msgstr "儲存書籤。" - -#: src/cthulhu/guilabels.py:304 -#, fuzzy -msgid "Date and time" -msgstr "時刻和日期" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "" - -#: src/cthulhu/guilabels.py:314 -#, fuzzy -msgid "Object navigation" -msgstr "表格導覽" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "未繫結" - -#: src/cthulhu/guilabels.py:334 -#, fuzzy -msgid "Flat review" -msgstr "離開 flat review。" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "已修改" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "桌面(_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "通知" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "已收到" - -#: src/cthulhu/guilabels.py:381 -#, fuzzy -msgid "Notification presenter" -msgstr "通知" - -#: src/cthulhu/guilabels.py:389 -#, fuzzy, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s 的螢幕閱讀器偏好設定" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "以點字標示" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "顯示於" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "讀出 " - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "將設定組合儲存為衝突" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "使用者設定組合有衝突!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"設定組合 %s 已經存在。\n" -"是否繼續以這些新的更改來更新現有的設定組合?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "載入使用者設定組合" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"你即將改變使用中的設定組合。如果你\n" -"剛剛在偏好設定中做了更改,這個更改會\n" -"在載入設定組合時被丟棄。\n" -"\n" -"是否繼續載入設定組合並放棄前面的更改?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "另存設定組合為" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "設定組合名稱(_P):" - -#: src/cthulhu/guilabels.py:482 -#, fuzzy -msgid "Remove user profile" -msgstr "載入使用者設定組合" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "全部" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "應用程式" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "視窗" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "沒有(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "一些(_M)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "大部份(_O)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "行" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "句子" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "區塊括弧" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "按鈕" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "標題" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "核取方塊" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "可按下" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "組合方塊" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "描述" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "標題" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "影像" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "標籤" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "地標" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "等級" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "連結" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "清單" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "清單項目" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "物件" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "段落" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "單選按鈕" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "角色" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "已選取的項目" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "狀態" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "文字" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "數值" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "區塊括弧" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "按鈕" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "核取方塊" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "可按下" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "組合方塊" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "項目" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "表單欄位" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "標題" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "影像" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "第 %d 級標題" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "地標" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "大型物件" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "連結" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "清單" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "清單項目" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "段落" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "單選按鈕" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "表格" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "未瀏覽連結的色彩" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "已瀏覽連結" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "面頁導覽" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "當第一次載入一個頁面時自動開始讀出內容(_L)" - -#: src/cthulhu/guilabels.py:812 -#, fuzzy -msgid "_Present summary of a page when it is first loaded" -msgstr "當第一次載入一個頁面時自動開始讀出內容(_L)" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "將語音根據停頓的地方隔開(_U)" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s 預設語音" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "預設值" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "超連結" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "系統" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "大寫字母" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "拼字檢查" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "拼字錯誤(_E)" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "拼字建議(_S)" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "呈現前後文錯誤(_C)" - -#: src/cthulhu/guilabels.py:879 -#, fuzzy -msgid "Speak spreadsheet cell coordinates" -msgstr "讀出工作表的儲存格坐標" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "讀出儲存格標題(_H)" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "表格導覽" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "略過空白儲存格(_B)" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "讀出儲存格(_C)" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "讀出儲存格坐標(_C)" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "讀出合併多個的儲存格(_M)" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "屬性名稱" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "控制鍵盤瀏覽" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "啟用結構式瀏覽(_S)" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "音效主題(_T):" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "音效主題" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "簡短(_F)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "通知" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "左 shift 鍵" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "左 alt 鍵" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "左 control 鍵" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "右 shift 鍵" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "右 alt 鍵" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "右 control 鍵" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "左 left 鍵" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "右 right 鍵" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -#, fuzzy -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "左 tab 鍵" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "上" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "下" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "左" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "右" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "left super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "right super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "選單" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "說明" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "mode switch" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "插入" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "刪除" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "結束" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "stroke" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "減號" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "插入" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "粗體" - -#: src/cthulhu/mathsymbols.py:1144 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "斜體" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1164 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "下標 %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "下標 %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1254 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "工作區" - -#: src/cthulhu/mathsymbols.py:1264 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "內文是 %s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "左箭頭" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "左箭頭" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "右箭頭" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "左箭頭" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "右箭頭" - -#: src/cthulhu/mathsymbols.py:1282 -msgctxt "math symbol" -msgid "up down arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "右箭頭" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "右箭頭" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "左箭頭" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "左箭頭" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "右箭頭" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "左雙引號" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "double dagger" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "右雙引號" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "double dagger" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "右雙引號" - -#: src/cthulhu/mathsymbols.py:1321 -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "右箭頭" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "right-pointing arrowhead" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "減號" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "小於" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "大於" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "點" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "垂直對齊" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "水平" - -#: src/cthulhu/mathsymbols.py:1377 -msgctxt "math symbol" -msgid "for all" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1380 -msgctxt "math symbol" -msgid "complement" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1383 -msgctxt "math symbol" -msgid "partial differential" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1386 -msgctxt "math symbol" -msgid "there exists" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1389 -msgctxt "math symbol" -msgid "there does not exist" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "空白" - -#: src/cthulhu/mathsymbols.py:1395 -msgctxt "math symbol" -msgid "increment" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "已啟用" - -#: src/cthulhu/mathsymbols.py:1401 -msgctxt "math symbol" -msgid "element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1404 -msgctxt "math symbol" -msgid "not an element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1407 -msgctxt "math symbol" -msgid "small element of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1410 -msgctxt "math symbol" -msgid "contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1413 -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1416 -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "列的結尾。" - -#: src/cthulhu/mathsymbols.py:1422 -msgctxt "math symbol" -msgid "product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1425 -msgctxt "math symbol" -msgid "coproduct" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "下標" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "加減" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "加號" - -#: src/cthulhu/mathsymbols.py:1440 -msgctxt "math symbol" -msgid "division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "減號" - -#: src/cthulhu/mathsymbols.py:1446 -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1449 -msgctxt "math symbol" -msgid "ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1452 -msgctxt "math symbol" -msgid "bullet operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "開根號" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "開三方" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "開根號" - -#: src/cthulhu/mathsymbols.py:1464 -msgctxt "math symbol" -msgid "proportional to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "無限大" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "右 alt 鍵" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "單線" - -#: src/cthulhu/mathsymbols.py:1476 -msgctxt "math symbol" -msgid "measured angle" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "垂直對齊" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "除以" - -#: src/cthulhu/mathsymbols.py:1485 -msgctxt "math symbol" -msgid "does not divide" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1488 -msgctxt "math symbol" -msgid "parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "文字走向" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -msgctxt "math symbol" -msgid "union" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:1512 -msgctxt "math symbol" -msgid "triple integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1518 -msgctxt "math symbol" -msgid "surface integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1521 -msgctxt "math symbol" -msgid "volume integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1524 -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1527 -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1533 -msgctxt "math symbol" -msgid "therefore" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1536 -msgctxt "math symbol" -msgid "because" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1539 -msgctxt "math symbol" -msgid "ratio" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "減號" - -#: src/cthulhu/mathsymbols.py:1548 -msgctxt "math symbol" -msgid "excess" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1551 -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "波紋號" - -#: src/cthulhu/mathsymbols.py:1560 -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1563 -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1566 -msgctxt "math symbol" -msgid "sine wave" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1569 -msgctxt "math symbol" -msgid "wreath product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "n tilde" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "幾乎等於" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "幾乎等於" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "幾乎等於" - -#: src/cthulhu/mathsymbols.py:1587 -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "幾乎等於" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "幾乎等於" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "幾乎等於" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "三擊" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "幾乎等於" - -#: src/cthulhu/mathsymbols.py:1608 -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "不同網站" - -#: src/cthulhu/mathsymbols.py:1617 -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1623 -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1626 -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "等於" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "等於" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1641 -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "三角項目符號" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "等於" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1656 -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1659 -msgctxt "math symbol" -msgid "measured by" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "垂直的" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1695 -msgctxt "math symbol" -msgid "much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1698 -msgctxt "math symbol" -msgid "much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1701 -msgctxt "math symbol" -msgid "between" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1707 -msgctxt "math symbol" -msgid "not less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "大於" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -msgctxt "math symbol" -msgid "succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "未按下" - -#: src/cthulhu/mathsymbols.py:1764 -msgctxt "math symbol" -msgid "does not succeed" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "下標 0" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1773 -msgctxt "math symbol" -msgid "not a subset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "多重選取" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "對齊" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "多重選取" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "開根號" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "開根號" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1815 -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "開根號" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "開根號" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -msgctxt "math symbol" -msgid "circled plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1827 -msgctxt "math symbol" -msgid "circled minus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -msgctxt "math symbol" -msgid "circled times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1833 -msgctxt "math symbol" -msgid "circled division slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1836 -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1839 -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1842 -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "下標等號" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "en dash" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "下標加號" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "下標減號" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "開根號" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "開根號" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "右 right 鍵" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "左 tab 鍵" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "下" - -#: src/cthulhu/mathsymbols.py:1872 -msgctxt "math symbol" -msgid "up tack" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "章節" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1884 -msgctxt "math symbol" -msgid "forces" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -msgctxt "math symbol" -msgid "does not prove" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "true" - -#: src/cthulhu/mathsymbols.py:1899 -msgctxt "math symbol" -msgid "does not force" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1908 -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1911 -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1914 -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1917 -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "ordinal" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "影像" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "multi" - -#: src/cthulhu/mathsymbols.py:1932 -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -msgctxt "math symbol" -msgid "xor" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1941 -msgctxt "math symbol" -msgid "nand" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "一般" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "右單引號" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "右大括號" - -#: src/cthulhu/mathsymbols.py:1965 -msgctxt "math symbol" -msgid "diamond operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1968 -msgctxt "math symbol" -msgid "dot operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1971 -msgctxt "math symbol" -msgid "star operator" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1974 -msgctxt "math symbol" -msgid "division times" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1989 -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1992 -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "文字走向" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "double prime" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:2025 -msgctxt "math symbol" -msgid "very much less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2028 -msgctxt "math symbol" -msgid "very much greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:2037 -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2040 -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2043 -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2046 -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2049 -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2052 -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:2058 -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:2064 -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2082 -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2085 -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "垂直對齊" - -#: src/cthulhu/mathsymbols.py:2094 -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2117 -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2120 -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2123 -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2126 -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2142 -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "左小括弧" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "右小括弧" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "左 alt 鍵" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "右 alt 鍵" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "左大括號" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "底部" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "left double angle bracket" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "right double angle bracket" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "middle dot" - -#: src/cthulhu/mathsymbols.py:2180 -msgctxt "math symbol" -msgid "union with dot" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2182 -msgctxt "math symbol" -msgid "union with plus" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "搜尋方向:" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "開根號" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "實心方框" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "空心方框" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "實心菱形" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "空心圓" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "實心圓形" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "空心項目符號" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "實心方框" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "底線" - -#: src/cthulhu/mathsymbols.py:2225 -#, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "垂直對齊" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "應用程式" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "空白" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "粗體" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "輸入的書籤" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "書籤已儲存" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "書籤無法被儲存" - -#: src/cthulhu/messages.py:79 -#, fuzzy -msgid "No bookmarks found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:87 -#, fuzzy -msgid "Bookmark not found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "已啟用略過功能。" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "無法取得計數機的顯示" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "圖示" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "將大寫樣式設為圖示。" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "沒有" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "將大寫樣式設為設為沒有。" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "讀出" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "將大寫樣式設為讀出。" - -#: src/cthulhu/messages.py:164 -#, fuzzy -msgid "The application is controlling the caret." -msgstr "Gecko 正在控制鍵盤瀏覽。" - -#: src/cthulhu/messages.py:170 -#, fuzzy -msgid "Cthulhu is controlling the caret." -msgstr "Gecko 正在控制鍵盤瀏覽。" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "儲存格 %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "已選取" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "避免使用的選項" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "強制使用的選項" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPTION" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "下列項目是無效的:" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "顯示已知執行的應用程式" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "載入設定組合" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "無法載入設定組合:%s" - -#: src/cthulhu/messages.py:249 -#, fuzzy -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "不能啟動螢幕閱讀器,因為它不能連接到桌面。" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "無法使用設定值管理程式。正在結束。" - -#: src/cthulhu/messages.py:259 -#, fuzzy -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"另一個螢幕閱讀器程序已經在這個作業階段中執行。\n" -"執行「cthulhu --replace」以新的程序取代該程序。" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "其它使用者偏好設定的資料夾名稱" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -#, fuzzy -msgid "Version of this application" -msgstr "顯示已知執行的應用程式" - -#: src/cthulhu/messages.py:282 -#, fuzzy -msgid "Replace a currently running instance of Cthulhu" -msgstr "替換目前執行的螢幕閱讀器實體" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "將除錯資訊輸出為 debug-YYYY-MM-DD-HH:MM:SS.out " - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "將除錯輸出資料傳送至指定的檔案" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FILE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "設定使用者偏好設定(文字版本)" - -#: src/cthulhu/messages.py:313 -#, fuzzy -msgid "Set up user preferences (GUI version)" -msgstr "設定使用者偏好設定(文字版本)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "匯報錯誤至 https://groups.io/g/stormux" - -#: src/cthulhu/messages.py:325 -#, fuzzy -msgid "Cut selection to clipboard." -msgstr "複製內容到剪貼薄。" - -#: src/cthulhu/messages.py:333 -#, fuzzy -msgctxt "clipboard" -msgid "cut" -msgstr "acute" - -#: src/cthulhu/messages.py:337 -#, fuzzy -msgid "Copied selection to clipboard." -msgstr "複製內容到剪貼薄。" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "" - -#: src/cthulhu/messages.py:349 -#, fuzzy -msgid "Pasted contents from clipboard." -msgstr "複製內容到剪貼薄。" - -#: src/cthulhu/messages.py:357 -#, fuzzy -msgctxt "clipboard" -msgid "pasted" -msgstr "較快。" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "當你的朋友在輸入時不要告知。" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "當你的朋友在輸入時告知。" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "來自聊天室 %s 的訊息 " - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "新聊天分頁 %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "不要讀出聊天室名稱。" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "讀出聊天室名稱。" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "不要提供指定聊天室的訊息歷史紀錄。" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "提供指定聊天室的訊息歷史紀錄。" - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "選擇區域指示器" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "刪除" - -#: src/cthulhu/messages.py:452 -msgctxt "content" -msgid "insertion start" -msgstr "" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "插入" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "亮綠" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "拼字建議(_S)" - -#: src/cthulhu/messages.py:483 -#, fuzzy -msgid "End of container." -msgstr "表格的結尾" - -#: src/cthulhu/messages.py:489 -#, fuzzy -msgid "Not in a container." -msgstr "不在表格中。" - -#: src/cthulhu/messages.py:493 -#, fuzzy -msgid "all items selected" -msgstr "沒有選取" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "預設按鈕為%s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "預設按鈕為%s" - -#: src/cthulhu/messages.py:512 -#, fuzzy -msgid "Default button not found" -msgstr "預設按鈕為%s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "下標 %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "上標 %s" - -#: src/cthulhu/messages.py:529 -#, fuzzy -msgid "Not in a dialog" -msgstr "不在表格中。" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "已選取整個文件" - -#: src/cthulhu/messages.py:542 -#, fuzzy -msgid "entire document unselected" -msgstr "已選取整個文件" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "從游標位置開始選取文件" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "從游標位置開始取消選取文件" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "選取至游標位置的文件" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "取消選取至游標位置的文件" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "動態欄標頭設定給第 %d 列" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "已清除動態欄標頭。" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "動態列標頭設定給欄 %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "已清除動態列標頭。" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "空白" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f KB" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f MB" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "找不到任何檔案。" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "附加內容到剪貼薄。" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "複製內容到剪貼薄。" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "未使用 flat review。" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "進入 flat review。" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "離開 flat review。" - -#: src/cthulhu/messages.py:649 -#, fuzzy -msgid "Flat review restricted to the current object" -msgstr "將 flat review 移至目前字詞之上。" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "平面檢視無限制" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "有公式" - -#: src/cthulhu/messages.py:665 -#, fuzzy -msgid "opens dialog" -msgstr "開啟「尋找」對話盒。" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "影像地圖連結" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "輸入的按鍵已繫結於 %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "按鍵擷取:%s。按 enter 確認。" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "新的按鍵是:%s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "按鍵組合已刪除。按 enter 確認。" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "該按鍵組合已經被移除。" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "輸入新的按鍵" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "按鍵" - -#: src/cthulhu/messages.py:747 -#, fuzzy -msgid "Echo set to key." -msgstr "按鍵回響設定為按鍵。" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "沒有" - -#: src/cthulhu/messages.py:773 -#, fuzzy -msgid "Echo set to None." -msgstr "按鍵回響設定為沒有。" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "按鍵和字詞" - -#: src/cthulhu/messages.py:799 -#, fuzzy -msgid "Echo set to key and word." -msgstr "按鍵回響設定為按鍵和字詞。" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "段落" - -#: src/cthulhu/messages.py:825 -#, fuzzy -msgid "Echo set to sentence." -msgstr "按鍵回響設定為段落。" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "字詞" - -#: src/cthulhu/messages.py:851 -#, fuzzy -msgid "Echo set to word." -msgstr "按鍵回響設定為字詞。" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "字詞和段落" - -#: src/cthulhu/messages.py:877 -#, fuzzy -msgid "Echo set to word and sentence." -msgstr "按鍵回響設定為字詞和段落。" - -#: src/cthulhu/messages.py:889 -#, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "" - -#: src/cthulhu/messages.py:905 -msgctxt "math enclosure" -msgid "a box" -msgstr "" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "實心圓形" - -#: src/cthulhu/messages.py:921 -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "水平" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "vertical bar" - -#: src/cthulhu/messages.py:961 -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:969 -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "右箭頭" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "跳至底部。" - -#: src/cthulhu/messages.py:993 -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "行高" - -#: src/cthulhu/messages.py:1009 -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "" - -#: src/cthulhu/messages.py:1017 -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "" - -#: src/cthulhu/messages.py:1026 -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "and" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "加頂線" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "" - -#: src/cthulhu/messages.py:1073 -#, fuzzy -msgid "square root of" -msgstr "開根號" - -#: src/cthulhu/messages.py:1081 -#, fuzzy -msgid "cube root of" -msgstr "開三方" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "下標 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "下標 0" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "已啟用" - -#: src/cthulhu/messages.py:1159 -msgctxt "math table" -msgid "nested table end" -msgstr "" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "不能存取" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "已停用" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "已停用讀出縮排及對齊。" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "已啟用" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "已啟用讀出縮排及對齊。" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "學習模式。 按離開鍵離開。" - -#: src/cthulhu/messages.py:1201 -#, fuzzy -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"進入學習模式。按任何鍵來聽它的功能。要檢視螢幕閱讀器的文件,請按 F1。要取得螢" -"幕閱讀器的預設捷徑鍵清單,請按 F2。要取得螢幕閱讀器對目前應用程式提供的捷徑鍵" -"清單,請按 F3。要離開學習模式,請按 escape 鍵。" - -#: src/cthulhu/messages.py:1210 -#, fuzzy -msgid "leaving blockquote." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1221 -#, fuzzy -msgid "leaving details." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1237 -#, fuzzy -msgid "leaving form." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1243 -#, fuzzy -msgctxt "role" -msgid "leaving banner." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "" - -#: src/cthulhu/messages.py:1255 -#, fuzzy -msgctxt "role" -msgid "leaving information." -msgstr "表格導覽" - -#: src/cthulhu/messages.py:1261 -#, fuzzy -msgctxt "role" -msgid "leaving main content." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1267 -#, fuzzy -msgctxt "role" -msgid "leaving navigation." -msgstr "面頁導覽" - -#: src/cthulhu/messages.py:1273 -#, fuzzy -msgctxt "role" -msgid "leaving region." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1279 -#, fuzzy -msgctxt "role" -msgid "leaving search." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1283 -#, fuzzy -msgid "leaving list." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1288 -#, fuzzy -msgid "leaving panel." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1296 -#, fuzzy -msgid "leaving tooltip." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "表格導覽" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "離開 flat review。" - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1416 -msgctxt "role" -msgid "leaving introduction." -msgstr "" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "拼字建議(_S)" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "從游標位置開始向下選取行" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "從游標位置開始向上選取行" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "從游標位置開始向下取消選取行" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "從游標位置開始向上取消選取行" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "離開學習模式。" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "從開始到前一個游標位置選取行" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "從前一個游標位置選取行至結尾" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "連結" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "相同頁面" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "相同網站" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "不同網站" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s 連結到 %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s 連結" - -#: src/cthulhu/messages.py:1538 -#, fuzzy, python-format -msgid "visited %s link" -msgstr "%d 個瀏覽過的連結" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "使用上、下方向鍵來瀏覽清單。按 Escape 結束。" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "將所有的即時播報區設為關閉" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "即時播報區禮貌程度已還原" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "禮貌程度 %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "將即時播報區設為堅決" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "將即時播報區設為關閉" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "將即時播報區設為禮貌" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "將即時播報區設為粗魯" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "即時播報區監控關閉" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "即時播報區監控開啟" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "沒有儲存即時訊息" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "即時播報區支援已關閉" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "找不到" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "找不到目前的位置。" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "關" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "開" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "拼錯" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "拼錯字詞:%s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "內文是 %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "瀏覽模式" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "焦點模式" - -#: src/cthulhu/messages.py:1736 -#, fuzzy, python-format -msgid "To enable focus mode press %s." -msgstr "啟用黏性焦點模式。" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "焦點模式為黏性模式。" - -#: src/cthulhu/messages.py:1758 -#, fuzzy -msgid "Browse mode is sticky." -msgstr "焦點模式為黏性模式。" - -#: src/cthulhu/messages.py:1771 -#, fuzzy -msgid "Layout mode." -msgstr "焦點模式" - -#: src/cthulhu/messages.py:1785 -#, fuzzy -msgid "Object mode." -msgstr "物件" - -#: src/cthulhu/messages.py:1789 -#, fuzzy -msgid "Pointer moved to object." -msgstr "移至下一個物件。" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "找不到滑鼠停駐物件。" - -#: src/cthulhu/messages.py:1800 -#, fuzzy -msgid "Mouse review disabled." -msgstr "切換滑鼠預覽模式。" - -#: src/cthulhu/messages.py:1805 -#, fuzzy -msgid "Mouse review enabled." -msgstr "已啟用朗讀功能。" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "錯誤:無法建立物件清單。" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "沒有子項目。" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -#, fuzzy -msgid "No parent." -msgstr "百分之%d。" - -#: src/cthulhu/messages.py:1832 -#, fuzzy -msgid "No previous." -msgstr "移至下一個單字。" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "巢狀清單第 %d 層" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "已加入新的項目" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "沒有應用程式取得焦點。" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "沒有焦點" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "沒有應用程式取得焦點。" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "沒有其他區塊括弧。" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "沒有其他按鈕。" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "沒有其他核取方塊。" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "沒有其他大型物件。" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "沒有更多可按下項目。" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "沒有其他組合方塊。" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "沒有其他項目。" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "沒有其他表單欄位。" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "沒有其他標題。" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "沒有其他第 %d 級標題。" - -#: src/cthulhu/messages.py:1924 -#, fuzzy -msgid "No more internal frames." -msgstr "沒有其他的表格。" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "沒有更多影像。" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "沒有其他連結。" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "沒有其他清單。" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "沒有其他清單項目。" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "No more live regions." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "沒有其他段落。" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "沒有其他單選按鈕。" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "沒有其他分隔符。" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "沒有其他的表格。" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "No more unvisited links." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "沒有其他參訪過的連結。" - -#: src/cthulhu/messages.py:1992 -#, fuzzy -msgid "No selected text." -msgstr "沒有選取" - -#: src/cthulhu/messages.py:1997 -#, fuzzy -msgid "Not on a link." -msgstr "沒有其他連結。" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "通知" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "底部" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "頂端" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "沒有通知訊息" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "" - -#: src/cthulhu/messages.py:2034 -#, fuzzy -msgctxt "number style" -msgid "words" -msgstr "字詞" - -#: src/cthulhu/messages.py:2041 -#, fuzzy -msgid "Speak numbers as words." -msgstr "將混合大小寫的字串讀為一個字(_D)" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr " 關" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr " 開" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "載入中,請稍候。" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "載入完成。" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "載入 %s 完成。" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "從游標位置開始選取頁" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "選取至游標位置的頁" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "從游標位置取消選取頁" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "取消選取頁至游標位置" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "從游標位置開始向下選取段落" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "從游標位置開始向上選取段落" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "從游標位置開始向下取消選取段落" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "從游標位置開始向上取消選取段落" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"你已經有一個開啟的 Cthulhu 偏好設定對話盒實體。\n" -"\n" -"請在開啟新的之前先關閉它。" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "投影片全部%(count)d張的第%(position)d張" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "設定組合設定為 %s。" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "找不到設定組合。" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "進度列%d。" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "全部" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "將標音符號等級為全部。" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "最多" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "標音符號等級設為最多。" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "沒有" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "標音符號等級設為沒有。" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "一些" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "標音符號等級設為一些。" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "搜尋中。" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "搜尋完成。" - -#: src/cthulhu/messages.py:2211 -#, fuzzy -msgid "Cthulhu settings reloaded." -msgstr "已重新載入螢幕閱讀器設定值。" - -#: src/cthulhu/messages.py:2216 -#, fuzzy, python-format -msgid "Selected text is: %s" -msgstr "已選取的項目" - -#: src/cthulhu/messages.py:2223 -#, fuzzy -msgid "Selection deleted." -msgstr "已刪除列。" - -#: src/cthulhu/messages.py:2233 -#, fuzzy -msgid "Selection restored." -msgstr "選擇區域指示器" - -#: src/cthulhu/messages.py:2238 -#, fuzzy -msgid "Text unselected." -msgstr "取消選取" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "已停用朗讀功能。" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "已啟用朗讀功能。" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "較快。" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "較慢。" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "較高。" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "較低。" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -#, fuzzy -msgid "softer." -msgstr "較快。" - -#: src/cthulhu/messages.py:2279 -#, fuzzy, python-format -msgid "Rate %d" -msgstr "速度(_R):" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "音調 %s" - -#: src/cthulhu/messages.py:2285 -#, fuzzy, python-format -msgid "Volume %s" -msgstr "音量(_L):" - -#: src/cthulhu/messages.py:2288 -#, fuzzy, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2291 -#, fuzzy, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech Dispatcher" - -#: src/cthulhu/messages.py:2294 -#, fuzzy -msgid "No speech-dispatcher modules available" -msgstr "沒有伺服器存在。\n" - -#: src/cthulhu/messages.py:2297 -#, fuzzy -msgid "No speech-dispatcher voices available" -msgstr "沒有聲音存在。\n" - -#: src/cthulhu/messages.py:2300 -#, fuzzy -msgid "Speech settings saved" -msgstr "已啟用朗讀功能。" - -#: src/cthulhu/messages.py:2303 -#, fuzzy -msgid "Speech settings could not be saved" -msgstr "不會使用語音功能。\n" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " 點點點" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu 歡迎您。" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "Cthulhu 潛伏在波濤之下。" - -#: src/cthulhu/messages.py:2333 -#, fuzzy, python-format -msgid "Sleep mode enabled for %s" -msgstr "已啟用略過功能。" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "已為 %s 停用睡眠模式" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "語音功能不存在。" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "找不到" - -#: src/cthulhu/messages.py:2347 -#, fuzzy -msgid "Status bar not found" -msgstr "找不到字串" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "找不到字串" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "結構導覽鍵關閉。" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "結構導覽鍵開啟。" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "找不到" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "列 %(row)d,欄 %(column)d。" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "表格的結尾" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "讀出儲存格" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "讀出整列" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "非制式" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "不在表格中。" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "重新排序的欄" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "重新排序的列" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "欄 %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "全部 %(total)d 欄的第 %(index)d 欄" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "欄的底部。" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "欄的頂端。" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "列 %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "全部 %(total)d 列的第 %(index)d 列" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "列的開頭。" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "列的結尾。" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "已刪除列。" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "已刪除最後一列。" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "已插入列。" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "已在表格結尾插入列。" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "已刪除列。" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "已選取" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:2532 -#, fuzzy -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H小時,%M分%S秒。" - -#: src/cthulhu/messages.py:2537 -#, fuzzy -msgid "%H hours and %M minutes" -msgstr "%H小時%M分。" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "萬國碼 %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "空白空間" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "跳至底部。" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "回到開始。" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 個項目" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "儲存格合併 %d 列" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d 欄" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "儲存格合併 %d 欄" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d 個字符太長" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d 個對話盒)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d 個未取得焦點的對話盒" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d 位元組" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "找到 %d 個檔案" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d 個表單" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d 個標題" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d 個項目" - -#: src/cthulhu/messages.py:2661 -#, fuzzy, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "地標" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "找到 %d 個項目" - -#: src/cthulhu/messages.py:2673 -#, fuzzy, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "沒有其他區塊括弧。" - -#: src/cthulhu/messages.py:2678 -#, fuzzy, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "離開 flat review。" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "有 %d 個項目的清單" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "有 %d 個項目的清單" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "數值" - -#: src/cthulhu/messages.py:2723 -#, fuzzy, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "有 %d 列的表格" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d 欄" - -#: src/cthulhu/messages.py:2738 -#, fuzzy, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "有 %d 列的表格" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d 個訊息。\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "百分之%d。" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "已讀取文件的百分之 %d" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d 個 %(repeatChar)s 字符" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(total)d 個項目中選取的 %(index)d 個項目" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "找到 %d 個螢幕閱讀器預設捷徑鍵。" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "找到 %(count)d 個螢幕閱讀器 %(application)s 捷徑鍵。" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d 個空格" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d 個 tab" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d 個表格" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "有 %d 列的表格" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "有 %d 列的表格" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "有 %d 列的表格" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d 個未瀏覽的連結" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d 個瀏覽過的連結" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "切換" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "於 %(total)d 中的 %(index)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(total)d 中的 %(index)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "第 %d 層" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "tree level %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "問號" - -#: src/cthulhu/object_properties.py:123 -#, fuzzy -msgid "editable combo box" -msgstr "移至下一個組合方塊。" - -#: src/cthulhu/object_properties.py:129 -#, fuzzy -msgid "editable content" -msgstr "是否可編輯" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -msgctxt "role" -msgid "acknowledgments" -msgstr "" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "字詞" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "冒號" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "加頂線" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "文字走向" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "字詞" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "縮排" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "文字走向" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "page up" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "引號" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -msgctxt "role" -msgid "table of contents" -msgstr "" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s 第 %(level)d 級" - -#: src/cthulhu/object_properties.py:356 -#, fuzzy -msgid "horizontal scroll bar" -msgstr "水平" - -#: src/cthulhu/object_properties.py:363 -#, fuzzy -msgid "vertical scroll bar" -msgstr "vertical bar" - -#: src/cthulhu/object_properties.py:372 -#, fuzzy -msgid "horizontal slider" -msgstr "水平" - -#: src/cthulhu/object_properties.py:381 -#, fuzzy -msgid "vertical slider" -msgstr "垂直對齊" - -#: src/cthulhu/object_properties.py:393 -#, fuzzy -msgid "horizontal splitter" -msgstr "水平" - -#: src/cthulhu/object_properties.py:405 -#, fuzzy -msgid "vertical splitter" -msgstr "垂直對齊" - -#: src/cthulhu/object_properties.py:411 -#, fuzzy -msgctxt "role" -msgid "switch" -msgstr "mode switch" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "圖示面板" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "" - -#: src/cthulhu/object_properties.py:438 -#, fuzzy -msgctxt "role" -msgid "information" -msgstr "通知" - -#: src/cthulhu/object_properties.py:444 -#, fuzzy -msgctxt "role" -msgid "main content" -msgstr "有點窄" - -#: src/cthulhu/object_properties.py:451 -#, fuzzy -msgctxt "role" -msgid "navigation" -msgstr "面頁導覽" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "" - -#: src/cthulhu/object_properties.py:467 -#, fuzzy -msgctxt "role" -msgid "search" -msgstr "搜尋中。" - -#: src/cthulhu/object_properties.py:474 -#, fuzzy -msgid "visited link" -msgstr "%d 個瀏覽過的連結" - -#: src/cthulhu/object_properties.py:480 -#, fuzzy -msgid "menu button" -msgstr "沒有其他按鈕。" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "可按下" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "已收起" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "已展開" - -#: src/cthulhu/object_properties.py:511 -#, fuzzy -msgid "has long description" -msgstr "描述" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "水平" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "垂直的" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "已點選" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "未點選" - -#: src/cthulhu/object_properties.py:529 -#, fuzzy -msgctxt "switch" -msgid "on" -msgstr " 開" - -#: src/cthulhu/object_properties.py:533 -#, fuzzy -msgctxt "switch" -msgid "off" -msgstr " 關" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "部份選取" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "已按下" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "未按下" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "沒有選取" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "已選取" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "沒有選取" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "沒有選取" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "已瀏覽" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "未瀏覽" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "grayed" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "唯讀" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "唯讀" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "必要的" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "多重選取" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "" - -#: src/cthulhu/object_properties.py:612 -#, fuzzy -msgctxt "error" -msgid "invalid spelling" -msgstr "拼字" - -#: src/cthulhu/object_properties.py:618 -#, fuzzy -msgctxt "error" -msgid "spelling" -msgstr "拼字" - -#: src/cthulhu/object_properties.py:623 -msgctxt "error" -msgid "invalid grammar" -msgstr "" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "尋找" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "螢幕閱讀器尋找對話盒" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "關閉(_C)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "尋找(_F)" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "搜尋字串(_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "搜尋:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "最上層視窗(_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "最上層視窗" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "開始自:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "回到檔案開始部份再搜尋(_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "向上搜尋(_B)" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "搜尋方向:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "符合大小寫(_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "只符合整個字詞(_E)" - -#: src/cthulhu/cthulhu-find.ui:327 -#, fuzzy -msgid "Options:" -msgstr "「尋找」選項" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "預設" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "大寫字母" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "超連結" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "系統" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "應用程式" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "視窗" - -#: src/cthulhu/cthulhu-setup.ui:141 -#, fuzzy -msgid "Cthulhu Preferences" -msgstr "Cthulhu 螢幕閱讀器" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "求助(_H)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "套用(_A)" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "筆記本電腦(_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "鍵盤配置" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "使用中設定組合(_P):" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "啟動時設定組合:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "載入(_L)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "另存新檔(_A)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "設定組合" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "顯示工具提示(_P)" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "唸出滑鼠下方的物件(_U)" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "滑鼠" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "時刻格式(_T):" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "日期格式(_E):" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "時刻和日期" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -#, fuzzy -msgid "_Speak updates" -msgstr "全部讀出(_S)" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -#, fuzzy -msgid "_Braille updates" -msgstr "點字指示器" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "頻率 (秒):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -#, fuzzy -msgid "Applies to:" -msgstr "應用程式" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "進度列更新" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -#, fuzzy -msgid "Enable _structural navigation in Say All" -msgstr "啟用結構式瀏覽(_S)" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "閱讀停頓於(_Y):" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1008 -#, fuzzy -msgid "Say All" -msgstr "閱讀停頓於(_Y):" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "元素呈現(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "一般" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "音量(_L):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "音調(_T):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "速度(_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "朗讀者(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -#, fuzzy -msgid "_Language:" -msgstr "語言" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "朗讀合成器(_Z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "朗讀系統(_S):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "聲音類型(_T):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -#, fuzzy -msgid "_Capitalization style:" -msgstr "將大寫樣式設為圖示。" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "語音類型設定值" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "將混合大小寫的字串讀為一個字(_D)" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "全域語音設定值" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "聲音" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "啟用朗讀(_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "詳細(_B)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "詳細模式" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "全部(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "標點層級" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "只讀出顯示的文字" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "讀出空白的列" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "讀出縮排及對齊(_I)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "讀出物件助記符(_K)" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "讀出子項位置(_O)" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "讀出教學訊息" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -#, fuzzy -msgid "S_peak colors as names" -msgstr "讀出儲存格坐標(_C)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -#, fuzzy -msgid "Announce _lists during navigation" -msgstr "啟用結構式瀏覽(_S)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -#, fuzzy -msgid "Announce _tables during navigation" -msgstr "啟用結構式瀏覽(_S)" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -#, fuzzy -msgid "Speak _misspelled-word indicator" -msgstr "讀出儲存格坐標(_C)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -#, fuzzy -msgid "Speak _description" -msgstr "描述" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "讀出的內容" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "朗讀" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "啟用點字支援(_S)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "縮寫任務名稱(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "停用行尾符號(_E)" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "縮短表(_T):" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "啟用縮短式點字(_E)" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -#, fuzzy -msgid "Enable _word wrap" -msgstr "啟用字詞回響(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "顯示設定值" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "沒有(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "選擇區域指示器" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "超連結指示器" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -#, fuzzy -msgid "Flash Message Settings" -msgstr "全域語音設定值" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "點字" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "啟用按鍵回響(_K)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -#, fuzzy -msgid "Enable _alphabetic keys" -msgstr "啟用導覽鍵(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2819 -#, fuzzy -msgid "Enable n_umeric keys" -msgstr "啟用修改鍵(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2834 -#, fuzzy -msgid "Enable _punctuation keys" -msgstr "啟用功能鍵(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2849 -#, fuzzy -msgid "Enable _space" -msgstr "啟用朗讀(_E)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "啟用修改鍵(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "啟用功能鍵(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "啟用動作鍵(_T)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "啟用導覽鍵(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "啟用字詞回響(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "啟用句子回響(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -#, fuzzy -msgid "Echo" -msgstr "按鍵回響" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "螢幕閱讀器修改鍵(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "按鍵組合" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "發音字典" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "新項目(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "刪除(_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "發音" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "全部讀出(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "讀出「沒有」(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "重設(_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "文字屬性" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "移至底部(_B)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "下移一列(_D)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "上移一列(_U)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "移至頂端(_T)" - -#: src/cthulhu/cthulhu-setup.ui:3422 -#, fuzzy -msgid "Adjust selected attribute" -msgstr "調整選取的屬性" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "點字指示器" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "文字屬性" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "提供者(_P):" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (CLI)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (本機 - 免費)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API 金鑰檔案(_K):" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "API 金鑰檔案路徑" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "取得 _Claude API 金鑰" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "開啟瀏覽器取得 Claude API 金鑰並自動儲存" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "在 AI 操作前要求確認" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama 模型(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Ollama 的模型名稱 (例如 llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama 端點(_E):" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API 端點 URL (例如 http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "螢幕截圖品質(_Q):" - -#: src/cthulhu/cthulhu-setup.ui:3763 -#, fuzzy -msgid "Low" -msgstr "低" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "中等" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "高" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3805 -#, fuzzy -msgid "_Language Code:" -msgstr "語言" - -#: src/cthulhu/cthulhu-setup.ui:3818 -#, fuzzy -msgid "eng" -msgstr "日元" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "灰階圖像(_G)" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "反轉圖像(_I)" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "黑白圖像(_B)" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "黑白閾值(_T):" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "分析顏色(_A)" - -#: src/cthulhu/cthulhu-setup.ui:3946 -#, fuzzy -msgid "Copy Results to _Clipboard" -msgstr "複製內容到剪貼薄。" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "背景顏色" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "背景完整高度" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "背景點狀遮罩" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "文字走向" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "是否可編輯" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "字型族系名稱" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "前景顏色" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "前景點狀遮罩" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "字型效果" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "縮排" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "失誤" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "隱形" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "對齊" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "語言" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "左邊界" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "行高" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "段落樣式" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "列頂端空間" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "列底部空間" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "換列時加上的像素" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "右邊界" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "抬升" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "縮放" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "大小" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "延伸" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "刪除線" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "樣式" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "文字裝飾" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "文字旋轉" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "文字陰影" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "底線" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "大小寫" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "垂直對齊" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "字重" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "換列模式" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "書寫模式" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "none" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "牢記" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "浮雕" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "輪廓" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "加頂線" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "刪除線" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "閃爍" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "黑色" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "單線" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "雙線" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "低" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "字符" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "文字" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "字符" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "左至右" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "右至左" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "靠左" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "靠右" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "置中" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "不使用對齊" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "左右對齊" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "極窄" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "很窄" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "窄" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "有點窄" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "一般" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "有點寛" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "寛" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "很寛" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "極寛" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "小寫" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "傾斜" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "斜體" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "預設值" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "內文" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "標題" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "基線" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "下標" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "上標" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "頂端" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "文字頂端" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "中間" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "底部" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "文字底部" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "繼承" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "固定" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "拼字" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "按下空白鍵切換。" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "使用空白鍵展開,並使用上或下方向鍵來選擇項目。" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "按下 alt+f6 將焦點集中至子視窗。" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "要移至某項目,可使用方向鍵或輸入搜尋。" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "要使用系統選單,請按 alt+f1 鍵。" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "使用上或下方向鍵來選擇項目。" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "要摺疊,按下 shift 加上左方向鍵。" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "要展開,按下 shift 加上右方向鍵。" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "要使用請按 enter。" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "輸入文字。" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "使用左和右方向鍵來檢視其他分頁。" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "要使用請按空白鍵。" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "使用上或下方向鍵來選擇數值。或直接輸入想要的數字值。" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "使用方向鍵來更改。" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "要導覽請按左或右方向鍵。要移動至項目請按上或下方向鍵。" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "要進入子選單,請按右方向鍵。" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "要減少按左方向鍵,增加按右方向鍵。要少按 home 按鍵,多按 end 按鍵。" diff --git a/po/zh_TW.po b/po/zh_TW.po deleted file mode 100644 index 562a535..0000000 --- a/po/zh_TW.po +++ /dev/null @@ -1,9526 +0,0 @@ -# Chinese (Taiwan) translation of Cthulhu. -# Copyright (C) 2006-07 Free Software Foundation, Inc. -# Woodman Tuen , 2006-07. -# Hialan Liu , 2008. -# Chao-Hsiung Liao , 2009, 2010. -# Wei-Lun Chao , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: Cthulhu 3.3.5pre\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-02 10:46-0500\n" -"PO-Revision-Date: 2017-02-22 16:18+0800\n" -"Last-Translator: Chao-Hsiung Liao \n" -"Language-Team: Traditional Chinese\n" -"Language: zh_TW\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 1.8.12\n" - -msgid "Cthulhu Screen Reader" -msgstr "Cthulhu 螢幕閱讀器" - -msgid "screen;reader;accessibility;speech;braille;" -msgstr "螢幕;閱讀器;無障礙;語音;點字;" - -#: src/cthulhu/braille_rolenames.py:44 -msgid "???" -msgstr "???" - -#: src/cthulhu/braille_rolenames.py:51 -msgid "alrt" -msgstr "alrt" - -#: src/cthulhu/braille_rolenames.py:54 -msgid "anim" -msgstr "anim" - -#: src/cthulhu/braille_rolenames.py:57 -msgid "arw" -msgstr "arw" - -#: src/cthulhu/braille_rolenames.py:60 -msgid "cal" -msgstr "cal" - -#: src/cthulhu/braille_rolenames.py:63 -msgid "cnv" -msgstr "cnv" - -#: src/cthulhu/braille_rolenames.py:67 -msgid "cptn" -msgstr "cptn" - -#: src/cthulhu/braille_rolenames.py:70 src/cthulhu/braille_rolenames.py:73 -msgid "chk" -msgstr "chk" - -#: src/cthulhu/braille_rolenames.py:76 -msgid "clrchsr" -msgstr "clrchsr" - -#: src/cthulhu/braille_rolenames.py:79 src/cthulhu/braille_rolenames.py:238 -msgid "colhdr" -msgstr "colhdr" - -#: src/cthulhu/braille_rolenames.py:82 -msgid "cbo" -msgstr "cbo" - -#: src/cthulhu/braille_rolenames.py:85 -msgid "dat" -msgstr "dat" - -#: src/cthulhu/braille_rolenames.py:88 src/cthulhu/braille_rolenames.py:139 -msgid "icn" -msgstr "icn" - -#: src/cthulhu/braille_rolenames.py:91 src/cthulhu/braille_rolenames.py:127 -msgid "frm" -msgstr "frm" - -#: src/cthulhu/braille_rolenames.py:97 -msgctxt "shortbraille" -msgid "dial" -msgstr "dial" - -#: src/cthulhu/braille_rolenames.py:100 -msgid "dlg" -msgstr "dlg" - -#: src/cthulhu/braille_rolenames.py:103 -msgid "dip" -msgstr "dip" - -#: src/cthulhu/braille_rolenames.py:106 src/cthulhu/braille_rolenames.py:136 -msgid "html" -msgstr "html" - -#: src/cthulhu/braille_rolenames.py:109 -msgid "draw" -msgstr "draw" - -#: src/cthulhu/braille_rolenames.py:112 -msgid "fchsr" -msgstr "fchsr" - -#: src/cthulhu/braille_rolenames.py:115 -msgid "flr" -msgstr "flr" - -#: src/cthulhu/braille_rolenames.py:118 -msgid "fnt" -msgstr "fnt" - -#: src/cthulhu/braille_rolenames.py:124 -msgctxt "shortbraille" -msgid "form" -msgstr "表單" - -#: src/cthulhu/braille_rolenames.py:130 -msgid "gpn" -msgstr "gpn" - -#: src/cthulhu/braille_rolenames.py:133 -msgid "hdng" -msgstr "hdng" - -#: src/cthulhu/braille_rolenames.py:142 -msgid "img" -msgstr "img" - -#: src/cthulhu/braille_rolenames.py:145 -msgid "ifrm" -msgstr "ifrm" - -#: src/cthulhu/braille_rolenames.py:148 -msgid "lbl" -msgstr "lbl" - -#: src/cthulhu/braille_rolenames.py:151 -msgid "lyrdpn" -msgstr "lyrdpn" - -#: src/cthulhu/braille_rolenames.py:154 -msgid "lnk" -msgstr "lnk" - -#: src/cthulhu/braille_rolenames.py:157 -msgid "lst" -msgstr "lst" - -#: src/cthulhu/braille_rolenames.py:160 -msgid "lstitm" -msgstr "lstitm" - -#: src/cthulhu/braille_rolenames.py:163 -msgid "mnu" -msgstr "mnu" - -#: src/cthulhu/braille_rolenames.py:166 -msgid "mnubr" -msgstr "mnubr" - -#: src/cthulhu/braille_rolenames.py:169 -msgid "mnuitm" -msgstr "mnuitm" - -#: src/cthulhu/braille_rolenames.py:172 -msgid "optnpn" -msgstr "optnpn" - -#: src/cthulhu/braille_rolenames.py:175 -msgid "pgt" -msgstr "pgt" - -#: src/cthulhu/braille_rolenames.py:178 -msgid "tblst" -msgstr "tblst" - -#: src/cthulhu/braille_rolenames.py:181 -msgid "pnl" -msgstr "pnl" - -#: src/cthulhu/braille_rolenames.py:184 -msgid "pwd" -msgstr "pwd" - -#: src/cthulhu/braille_rolenames.py:187 -msgid "popmnu" -msgstr "popmnu" - -#: src/cthulhu/braille_rolenames.py:190 -msgid "pgbar" -msgstr "pgbar" - -#: src/cthulhu/braille_rolenames.py:193 -msgid "btn" -msgstr "btn" - -#: src/cthulhu/braille_rolenames.py:196 -msgid "radio" -msgstr "radio" - -#: src/cthulhu/braille_rolenames.py:199 -msgid "rdmnuitm" -msgstr "rdmnuitm" - -#: src/cthulhu/braille_rolenames.py:202 -msgid "rtpn" -msgstr "rtpn" - -#: src/cthulhu/braille_rolenames.py:205 src/cthulhu/braille_rolenames.py:241 -msgid "rwhdr" -msgstr "rwhdr" - -#: src/cthulhu/braille_rolenames.py:208 -msgid "scbr" -msgstr "scbr" - -#: src/cthulhu/braille_rolenames.py:211 -msgid "scpn" -msgstr "scpn" - -#: src/cthulhu/braille_rolenames.py:214 -msgid "sctn" -msgstr "sctn" - -#: src/cthulhu/braille_rolenames.py:217 -msgid "seprtr" -msgstr "seprtr" - -#: src/cthulhu/braille_rolenames.py:220 -msgid "sldr" -msgstr "sldr" - -#: src/cthulhu/braille_rolenames.py:223 -msgid "spltpn" -msgstr "spltpn" - -#: src/cthulhu/braille_rolenames.py:226 -msgid "spin" -msgstr "spin" - -#: src/cthulhu/braille_rolenames.py:229 -msgid "statbr" -msgstr "statbr" - -#: src/cthulhu/braille_rolenames.py:232 -msgid "tbl" -msgstr "tbl" - -#: src/cthulhu/braille_rolenames.py:235 -msgid "cll" -msgstr "cll" - -#: src/cthulhu/braille_rolenames.py:244 -msgid "tomnuitm" -msgstr "tomnuitm" - -#: src/cthulhu/braille_rolenames.py:247 -msgid "term" -msgstr "term" - -#: src/cthulhu/braille_rolenames.py:250 -msgid "txt" -msgstr "txt" - -#: src/cthulhu/braille_rolenames.py:253 -msgid "tglbtn" -msgstr "tglbtn" - -#: src/cthulhu/braille_rolenames.py:256 -msgid "tbar" -msgstr "tbar" - -#: src/cthulhu/braille_rolenames.py:259 -msgid "tip" -msgstr "提示" - -#: src/cthulhu/braille_rolenames.py:262 -msgid "tre" -msgstr "tre" - -#: src/cthulhu/braille_rolenames.py:265 -msgid "trtbl" -msgstr "trtbl" - -#: src/cthulhu/braille_rolenames.py:268 -msgid "unk" -msgstr "unk" - -#: src/cthulhu/braille_rolenames.py:271 -msgid "vwprt" -msgstr "vwprt" - -#: src/cthulhu/braille_rolenames.py:274 -msgid "wnd" -msgstr "wnd" - -#: src/cthulhu/braille_rolenames.py:277 -msgid "hdr" -msgstr "hdr" - -#: src/cthulhu/braille_rolenames.py:280 -msgid "ftr" -msgstr "ftr" - -#: src/cthulhu/braille_rolenames.py:283 -msgid "para" -msgstr "para" - -#: src/cthulhu/braille_rolenames.py:286 -msgid "app" -msgstr "app" - -#: src/cthulhu/braille_rolenames.py:289 -msgid "auto" -msgstr "auto" - -#: src/cthulhu/braille_rolenames.py:292 -msgid "edtbr" -msgstr "edtbr" - -#: src/cthulhu/braille_rolenames.py:295 -msgid "emb" -msgstr "emb" - -#: src/cthulhu/brltablenames.py:41 -msgid "Czech Grade 1" -msgstr "捷克語(第一級)" - -#: src/cthulhu/brltablenames.py:45 -msgid "Spanish Grade 1" -msgstr "西班牙文(第一級)" - -#: src/cthulhu/brltablenames.py:49 -msgid "Canada French Grade 2" -msgstr "加拿大法語(第二級)" - -#: src/cthulhu/brltablenames.py:53 -msgid "France French Grade 2" -msgstr "法國法語 (第二級)" - -#: src/cthulhu/brltablenames.py:57 -msgid "Latvian Grade 1" -msgstr "拉脫維亞文(第一級)" - -#: src/cthulhu/brltablenames.py:61 -msgid "Netherlands Dutch Grade 1" -msgstr "荷蘭文(第一級)" - -#: src/cthulhu/brltablenames.py:65 -msgid "Norwegian Grade 0" -msgstr "挪威文(第零級)" - -#: src/cthulhu/brltablenames.py:69 -msgid "Norwegian Grade 1" -msgstr "挪威文(第一級)" - -#: src/cthulhu/brltablenames.py:73 -msgid "Norwegian Grade 2" -msgstr "挪威文(第二級)" - -#: src/cthulhu/brltablenames.py:77 -msgid "Norwegian Grade 3" -msgstr "挪威文(第三級)" - -#: src/cthulhu/brltablenames.py:81 -msgid "Polish Grade 1" -msgstr "波蘭文(第一級)" - -#: src/cthulhu/brltablenames.py:85 -msgid "Portuguese Grade 1" -msgstr "葡萄牙文(第一級)" - -#: src/cthulhu/brltablenames.py:89 -msgid "Swedish Grade 1" -msgstr "瑞典文(第一級)" - -#: src/cthulhu/brltablenames.py:93 -msgid "Arabic Grade 1" -msgstr "阿拉伯文(第一級)" - -#: src/cthulhu/brltablenames.py:97 -msgid "Welsh Grade 1" -msgstr "威爾斯語(第一級)" - -#: src/cthulhu/brltablenames.py:101 -msgid "Welsh Grade 2" -msgstr "威爾斯語(第二級)" - -#: src/cthulhu/brltablenames.py:105 -msgid "German Grade 0" -msgstr "德文(第零級)" - -#: src/cthulhu/brltablenames.py:109 -msgid "German Grade 1" -msgstr "德文(第一級)" - -#: src/cthulhu/brltablenames.py:113 -msgid "German Grade 2" -msgstr "德文(第二級)" - -#: src/cthulhu/brltablenames.py:117 -msgid "U.K. English Grade 2" -msgstr "英式英文(第二級)" - -#: src/cthulhu/brltablenames.py:121 -msgid "U.K. English Grade 1" -msgstr "英式英文(第一級)" - -#: src/cthulhu/brltablenames.py:125 -msgid "U.S. English Grade 1" -msgstr "美式英文(第一級)" - -#: src/cthulhu/brltablenames.py:129 -msgid "U.S. English Grade 2" -msgstr "美式英文(第二級)" - -#: src/cthulhu/brltablenames.py:133 -msgid "Canada French Grade 1" -msgstr "加拿大法語(第一級)" - -#: src/cthulhu/brltablenames.py:137 -msgid "France French Grade 1" -msgstr "法國法語(第一級)" - -#: src/cthulhu/brltablenames.py:141 -msgid "Greek Grade 1" -msgstr "希臘文(第一級)" - -#: src/cthulhu/brltablenames.py:145 -msgid "Hindi Grade 1" -msgstr "北印度文(第一級)" - -#: src/cthulhu/brltablenames.py:149 -msgid "Hungarian 8 dot computer" -msgstr "匈牙利 8 點電腦" - -#: src/cthulhu/brltablenames.py:153 -msgid "Hungarian Grade 1" -msgstr "匈牙利語(第一級)" - -#: src/cthulhu/brltablenames.py:157 -msgid "Hungarian Grade 2" -msgstr "匈牙利語(第一級)" - -#: src/cthulhu/brltablenames.py:161 -msgid "Italian Grade 1" -msgstr "義大利文(第一級)" - -#: src/cthulhu/brltablenames.py:165 -msgid "Belgium Dutch Grade 1" -msgstr "比利時荷蘭文(第一級)" - -#: src/cthulhu/chnames.py:46 src/cthulhu/keynames.py:149 -msgid "space" -msgstr "空白" - -#: src/cthulhu/chnames.py:50 -msgid "newline" -msgstr "換列" - -#: src/cthulhu/chnames.py:54 src/cthulhu/keynames.py:141 -msgid "tab" -msgstr "tab" - -#: src/cthulhu/chnames.py:58 -msgid "exclaim" -msgstr "感歎號" - -#: src/cthulhu/chnames.py:62 -msgid "quote" -msgstr "引號" - -#: src/cthulhu/chnames.py:66 -msgid "number" -msgstr "井字號" - -#: src/cthulhu/chnames.py:70 -msgid "dollar" -msgstr "圓" - -#: src/cthulhu/chnames.py:74 -msgid "percent" -msgstr "percent" - -#: src/cthulhu/chnames.py:78 -msgid "and" -msgstr "and" - -#: src/cthulhu/chnames.py:82 -msgid "apostrophe" -msgstr "撇號" - -#: src/cthulhu/chnames.py:86 -msgid "left paren" -msgstr "左小括弧" - -#: src/cthulhu/chnames.py:90 -msgid "right paren" -msgstr "右小括弧" - -#: src/cthulhu/chnames.py:94 -msgid "star" -msgstr "星號" - -#: src/cthulhu/chnames.py:98 src/cthulhu/keynames.py:309 -msgid "plus" -msgstr "加號" - -#: src/cthulhu/chnames.py:102 -msgid "comma" -msgstr "逗號" - -#: src/cthulhu/chnames.py:106 -msgid "dash" -msgstr "破折號" - -#: src/cthulhu/chnames.py:110 -msgid "dot" -msgstr "點" - -#: src/cthulhu/chnames.py:114 -msgid "slash" -msgstr "斜線" - -#: src/cthulhu/chnames.py:118 -msgid "colon" -msgstr "冒號" - -#: src/cthulhu/chnames.py:122 -msgid "semicolon" -msgstr "分號" - -#: src/cthulhu/chnames.py:126 -msgid "less" -msgstr "小於" - -#: src/cthulhu/chnames.py:130 -msgid "equals" -msgstr "等於" - -#: src/cthulhu/chnames.py:134 -msgid "greater" -msgstr "大於" - -#: src/cthulhu/chnames.py:138 -msgid "question" -msgstr "問號" - -#: src/cthulhu/chnames.py:142 -msgid "at" -msgstr "at" - -#: src/cthulhu/chnames.py:146 -msgid "left bracket" -msgstr "左中括號" - -#: src/cthulhu/chnames.py:150 -msgid "backslash" -msgstr "倒斜線" - -#: src/cthulhu/chnames.py:154 -msgid "right bracket" -msgstr "右中括號" - -#: src/cthulhu/chnames.py:158 -msgid "caret" -msgstr "caret" - -#: src/cthulhu/chnames.py:162 -msgid "underline" -msgstr "底線" - -#: src/cthulhu/chnames.py:166 src/cthulhu/keynames.py:266 -msgid "grave" -msgstr "grave" - -#: src/cthulhu/chnames.py:170 -msgid "left brace" -msgstr "左大括號" - -#: src/cthulhu/chnames.py:174 -msgid "vertical bar" -msgstr "vertical bar" - -#: src/cthulhu/chnames.py:178 -msgid "right brace" -msgstr "右大括號" - -#: src/cthulhu/chnames.py:182 src/cthulhu/keynames.py:281 -msgid "tilde" -msgstr "波紋號" - -#: src/cthulhu/chnames.py:187 -msgid "no break space" -msgstr "沒有斷開的空白" - -#: src/cthulhu/chnames.py:191 -msgid "inverted exclamation point" -msgstr "inverted exclamation point" - -#: src/cthulhu/chnames.py:195 -msgid "cents" -msgstr "cents" - -#: src/cthulhu/chnames.py:199 -msgid "pounds" -msgstr "鎊" - -#: src/cthulhu/chnames.py:203 -msgid "currency sign" -msgstr "currency sign" - -#: src/cthulhu/chnames.py:207 -msgid "yen" -msgstr "日元" - -#: src/cthulhu/chnames.py:211 -msgid "broken bar" -msgstr "broken bar" - -#: src/cthulhu/chnames.py:215 -msgid "section" -msgstr "章節" - -#: src/cthulhu/chnames.py:219 src/cthulhu/keynames.py:286 -msgid "diaeresis" -msgstr "分音符" - -#: src/cthulhu/chnames.py:223 -msgid "copyright" -msgstr "版權" - -#: src/cthulhu/chnames.py:227 -msgid "superscript a" -msgstr "superscript a" - -#: src/cthulhu/chnames.py:231 -msgid "left double angle bracket" -msgstr "left double angle bracket" - -#: src/cthulhu/chnames.py:235 -msgid "logical not" -msgstr "logical not" - -#: src/cthulhu/chnames.py:239 -msgid "soft hyphen" -msgstr "soft hyphen" - -#: src/cthulhu/chnames.py:243 -msgid "registered" -msgstr "registered" - -#: src/cthulhu/chnames.py:247 -msgid "macron" -msgstr "macron" - -#: src/cthulhu/chnames.py:251 -msgid "degrees" -msgstr "度" - -#: src/cthulhu/chnames.py:255 -msgid "plus or minus" -msgstr "加減" - -#: src/cthulhu/chnames.py:259 -msgid "superscript 2" -msgstr "superscript 2" - -#: src/cthulhu/chnames.py:263 -msgid "superscript 3" -msgstr "superscript 3" - -#: src/cthulhu/chnames.py:267 src/cthulhu/keynames.py:271 -msgid "acute" -msgstr "acute" - -#: src/cthulhu/chnames.py:271 -msgid "mu" -msgstr "mu" - -#: src/cthulhu/chnames.py:275 -msgid "paragraph marker" -msgstr "段落標記" - -#: src/cthulhu/chnames.py:279 -msgid "middle dot" -msgstr "middle dot" - -#: src/cthulhu/chnames.py:283 src/cthulhu/keynames.py:296 -msgid "cedilla" -msgstr "cedilla" - -#: src/cthulhu/chnames.py:287 -msgid "superscript 1" -msgstr "superscript 1" - -#: src/cthulhu/chnames.py:291 -msgid "ordinal" -msgstr "ordinal" - -#: src/cthulhu/chnames.py:295 -msgid "right double angle bracket" -msgstr "right double angle bracket" - -#: src/cthulhu/chnames.py:299 -msgid "one fourth" -msgstr "one fourth" - -#: src/cthulhu/chnames.py:303 -msgid "one half" -msgstr "one half" - -#: src/cthulhu/chnames.py:307 -msgid "three fourths" -msgstr "three fourths" - -#: src/cthulhu/chnames.py:311 -msgid "inverted question mark" -msgstr "倒問號" - -#: src/cthulhu/chnames.py:315 -msgid "a acute" -msgstr "a acute" - -#: src/cthulhu/chnames.py:319 -msgid "A GRAVE" -msgstr "A GRAVE" - -#: src/cthulhu/chnames.py:323 -msgid "A ACUTE" -msgstr "A ACUTE" - -#: src/cthulhu/chnames.py:327 -msgid "A CIRCUMFLEX" -msgstr "A CIRCUMFLEX" - -#: src/cthulhu/chnames.py:331 -msgid "A TILDE" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:335 -msgid "A UMLAUT" -msgstr "A UMLAUT" - -#: src/cthulhu/chnames.py:339 -msgid "A RING" -msgstr "A RING" - -#: src/cthulhu/chnames.py:343 -msgid "A E" -msgstr "A E" - -#: src/cthulhu/chnames.py:347 -msgid "C CEDILLA" -msgstr "C CEDILLA" - -#: src/cthulhu/chnames.py:351 -msgid "E GRAVE" -msgstr "E GRAVE" - -#: src/cthulhu/chnames.py:355 -msgid "E ACUTE" -msgstr "E ACUTE" - -#: src/cthulhu/chnames.py:359 -msgid "E CIRCUMFLEX" -msgstr "E CIRCUMFLEX" - -#: src/cthulhu/chnames.py:363 -msgid "E UMLAUT" -msgstr "E UMLAUT" - -#: src/cthulhu/chnames.py:367 -msgid "I GRAVE" -msgstr "I GRAVE" - -#: src/cthulhu/chnames.py:371 -msgid "I ACUTE" -msgstr "I ACUTE" - -#: src/cthulhu/chnames.py:375 -msgid "I CIRCUMFLEX" -msgstr "I CIRCUMFLEX" - -#: src/cthulhu/chnames.py:379 -msgid "I UMLAUT" -msgstr "I UMLAUT" - -#: src/cthulhu/chnames.py:383 -msgid "ETH" -msgstr "ETH" - -#: src/cthulhu/chnames.py:387 -msgid "N TILDE" -msgstr "N TILDE" - -#: src/cthulhu/chnames.py:391 -msgid "O GRAVE" -msgstr "O GRAVE" - -#: src/cthulhu/chnames.py:395 -msgid "O ACUTE" -msgstr "O ACUTE" - -#: src/cthulhu/chnames.py:399 -msgid "O CIRCUMFLEX" -msgstr "O CIRCUMFLEX" - -#: src/cthulhu/chnames.py:403 -msgid "O TILDE" -msgstr "O TILDE" - -#: src/cthulhu/chnames.py:407 -msgid "O UMLAUT" -msgstr "O UMLAUT" - -#: src/cthulhu/chnames.py:411 -msgid "times" -msgstr "乘" - -#: src/cthulhu/chnames.py:415 -msgid "O STROKE" -msgstr "O STROKE" - -#: src/cthulhu/chnames.py:419 -msgid "U GRAVE" -msgstr "U GRAVE" - -#: src/cthulhu/chnames.py:423 -msgid "U ACUTE" -msgstr "U ACUTE" - -#: src/cthulhu/chnames.py:427 -msgid "U CIRCUMFLEX" -msgstr "U CIRCUMFLEX" - -#: src/cthulhu/chnames.py:431 -msgid "U UMLAUT" -msgstr "U UMLAUT" - -#: src/cthulhu/chnames.py:435 -msgid "Y ACUTE" -msgstr "Y ACUTE" - -#: src/cthulhu/chnames.py:439 -msgid "THORN" -msgstr "THORN" - -#: src/cthulhu/chnames.py:443 -msgid "s sharp" -msgstr "s sharp" - -#: src/cthulhu/chnames.py:447 -msgid "a grave" -msgstr "a grave" - -#: src/cthulhu/chnames.py:451 -msgid "a circumflex" -msgstr "a circumflex" - -#: src/cthulhu/chnames.py:455 -msgid "a tilde" -msgstr "a tilde" - -#: src/cthulhu/chnames.py:459 -msgid "a umlaut" -msgstr "a umlaut" - -#: src/cthulhu/chnames.py:463 -msgid "a ring" -msgstr "a ring" - -#: src/cthulhu/chnames.py:467 -msgid "a e" -msgstr "a e" - -#: src/cthulhu/chnames.py:471 -msgid "c cedilla" -msgstr "c cedilla" - -#: src/cthulhu/chnames.py:475 -msgid "e grave" -msgstr "e grave" - -#: src/cthulhu/chnames.py:479 -msgid "e acute" -msgstr "e acute" - -#: src/cthulhu/chnames.py:483 -msgid "e circumflex" -msgstr "e circumflex" - -#: src/cthulhu/chnames.py:487 -msgid "e umlaut" -msgstr "e umlaut" - -#: src/cthulhu/chnames.py:491 -msgid "i grave" -msgstr "i grave" - -#: src/cthulhu/chnames.py:495 -msgid "i acute" -msgstr "i acute" - -#: src/cthulhu/chnames.py:499 -msgid "i circumflex" -msgstr "i circumflex" - -#: src/cthulhu/chnames.py:503 -msgid "i umlaut" -msgstr "i umlaut" - -#: src/cthulhu/chnames.py:507 -msgid "eth" -msgstr "eth" - -#: src/cthulhu/chnames.py:511 -msgid "n tilde" -msgstr "n tilde" - -#: src/cthulhu/chnames.py:515 -msgid "o grave" -msgstr "o grave" - -#: src/cthulhu/chnames.py:519 -msgid "o acute" -msgstr "o acute" - -#: src/cthulhu/chnames.py:523 -msgid "o circumflex" -msgstr "o circumflex" - -#: src/cthulhu/chnames.py:527 -msgid "o tilde" -msgstr "o tilde" - -#: src/cthulhu/chnames.py:531 -msgid "o umlaut" -msgstr "o umlaut" - -#: src/cthulhu/chnames.py:535 -msgid "divided by" -msgstr "除以" - -#: src/cthulhu/chnames.py:539 -msgid "o stroke" -msgstr "o stroke" - -#: src/cthulhu/chnames.py:543 -msgid "thorn" -msgstr "thorn" - -#: src/cthulhu/chnames.py:547 -msgid "u acute" -msgstr "u acute" - -#: src/cthulhu/chnames.py:551 -msgid "u grave" -msgstr "u grave" - -#: src/cthulhu/chnames.py:555 -msgid "u circumflex" -msgstr "u circumflex" - -#: src/cthulhu/chnames.py:559 -msgid "u umlaut" -msgstr "u umlaut" - -#: src/cthulhu/chnames.py:563 -msgid "y acute" -msgstr "y acute" - -#: src/cthulhu/chnames.py:567 -msgid "y umlaut" -msgstr "y umlaut" - -#: src/cthulhu/chnames.py:571 -msgid "Y UMLAUT" -msgstr "Y UMLAUT" - -#: src/cthulhu/chnames.py:575 -msgid "florin" -msgstr "florin" - -#: src/cthulhu/chnames.py:579 -msgid "en dash" -msgstr "en dash" - -#: src/cthulhu/chnames.py:584 -msgid "left single quote" -msgstr "左單引號" - -#: src/cthulhu/chnames.py:589 -msgid "right single quote" -msgstr "右單引號" - -#: src/cthulhu/chnames.py:593 -msgid "single low quote" -msgstr "下單引號" - -#: src/cthulhu/chnames.py:597 -msgid "left double quote" -msgstr "左雙引號" - -#: src/cthulhu/chnames.py:601 -msgid "right double quote" -msgstr "右雙引號" - -#: src/cthulhu/chnames.py:605 -msgid "double low quote" -msgstr "下雙引號" - -#: src/cthulhu/chnames.py:609 -msgid "dagger" -msgstr "dagger" - -#: src/cthulhu/chnames.py:613 -msgid "double dagger" -msgstr "double dagger" - -#: src/cthulhu/chnames.py:617 -msgid "bullet" -msgstr "項目符號" - -#: src/cthulhu/chnames.py:621 -msgid "triangular bullet" -msgstr "三角項目符號" - -#: src/cthulhu/chnames.py:625 -msgid "per mille" -msgstr "per mille" - -#: src/cthulhu/chnames.py:629 -msgid "prime" -msgstr "prime" - -#: src/cthulhu/chnames.py:633 -msgid "double prime" -msgstr "double prime" - -#: src/cthulhu/chnames.py:637 -msgid "triple prime" -msgstr "A TILDE" - -#: src/cthulhu/chnames.py:641 -msgid "hyphen bullet" -msgstr "hyphen bullet" - -#: src/cthulhu/chnames.py:645 -msgid "euro" -msgstr "歐元" - -#: src/cthulhu/chnames.py:649 -msgid "trademark" -msgstr "註冊商標" - -#: src/cthulhu/chnames.py:654 -msgid "check mark" -msgstr "check mark" - -#: src/cthulhu/chnames.py:659 -msgid "heavy check mark" -msgstr "heavy check mark" - -#: src/cthulhu/chnames.py:668 -msgid "x-shaped bullet" -msgstr "x型項目符號" - -#: src/cthulhu/chnames.py:672 -msgid "superscript 0" -msgstr "上標 0" - -#: src/cthulhu/chnames.py:676 -msgid "superscript 4" -msgstr "上標 4" - -#: src/cthulhu/chnames.py:680 -msgid "superscript 5" -msgstr "上標 5" - -#: src/cthulhu/chnames.py:684 -msgid "superscript 6" -msgstr "上標 6" - -#: src/cthulhu/chnames.py:688 -msgid "superscript 7" -msgstr "上標 7" - -#: src/cthulhu/chnames.py:692 -msgid "superscript 8" -msgstr "上標 8" - -#: src/cthulhu/chnames.py:696 -msgid "superscript 9" -msgstr "上標 9" - -#: src/cthulhu/chnames.py:700 -msgid "superscript plus" -msgstr "上標加號" - -#: src/cthulhu/chnames.py:704 -msgid "superscript minus" -msgstr "上標減號" - -#: src/cthulhu/chnames.py:708 -msgid "superscript equals" -msgstr "上標等號" - -#: src/cthulhu/chnames.py:712 -msgid "superscript left paren" -msgstr "上標左括號" - -#: src/cthulhu/chnames.py:716 -msgid "superscript right paren" -msgstr "上標右括號" - -#: src/cthulhu/chnames.py:720 -msgid "superscript n" -msgstr "上標 n" - -#: src/cthulhu/chnames.py:724 -msgid "subscript 0" -msgstr "下標 0" - -#: src/cthulhu/chnames.py:728 -msgid "subscript 1" -msgstr "下標 1" - -#: src/cthulhu/chnames.py:732 -msgid "subscript 2" -msgstr "下標 2" - -#: src/cthulhu/chnames.py:736 -msgid "subscript 3" -msgstr "下標 3" - -#: src/cthulhu/chnames.py:740 -msgid "subscript 4" -msgstr "下標 4" - -#: src/cthulhu/chnames.py:744 -msgid "subscript 5" -msgstr "下標 5" - -#: src/cthulhu/chnames.py:748 -msgid "subscript 6" -msgstr "下標 6" - -#: src/cthulhu/chnames.py:752 -msgid "subscript 7" -msgstr "下標 7" - -#: src/cthulhu/chnames.py:756 -msgid "subscript 8" -msgstr "下標 8" - -#: src/cthulhu/chnames.py:760 -msgid "subscript 9" -msgstr "下標 9" - -#: src/cthulhu/chnames.py:764 -msgid "subscript plus" -msgstr "下標加號" - -#: src/cthulhu/chnames.py:768 -msgid "subscript minus" -msgstr "下標減號" - -#: src/cthulhu/chnames.py:772 -msgid "subscript equals" -msgstr "下標等號" - -#: src/cthulhu/chnames.py:776 -msgid "subscript left paren" -msgstr "下標左括號" - -#: src/cthulhu/chnames.py:780 -msgid "subscript right paren" -msgstr "下標右括號" - -#: src/cthulhu/chnames.py:786 -msgid "black square" -msgstr "實心方框" - -#: src/cthulhu/chnames.py:792 -msgid "black diamond" -msgstr "實心菱形" - -#: src/cthulhu/chnames.py:806 -msgid "object replacement character" -msgstr "物件置換字元" - -#: src/cthulhu/cmdnames.py:42 -msgid "Route the pointer to the current item" -msgstr "將指標轉向目前的項目。" - -#: src/cthulhu/cmdnames.py:50 -msgid "Perform left click on current flat review item" -msgstr "在目前的 flat review 項目中按下左鍵" - -#: src/cthulhu/cmdnames.py:58 -msgid "Perform right click on current flat review item" -msgstr "在目前的 flat review 項目中按下右鍵" - -#: src/cthulhu/cmdnames.py:64 -msgid "Speak entire document" -msgstr "讀出整個文件。" - -#: src/cthulhu/cmdnames.py:72 -msgid "Speak entire window using flat review" -msgstr "使用 flat review 讀出整個視窗。" - -#: src/cthulhu/cmdnames.py:78 -msgid "Perform the basic Where Am I operation" -msgstr "進行基本的「我在哪裡」操作。" - -#: src/cthulhu/cmdnames.py:84 -msgid "Perform the detailed Where Am I operation" -msgstr "進行詳細的「我在哪裡」操作。" - -#: src/cthulhu/cmdnames.py:91 -msgid "Speak the current selection" -msgstr "讀出目前的 flat review 列。" - -#: src/cthulhu/cmdnames.py:95 -msgid "Speak link details" -msgstr "讀出連結的詳細資料。" - -#: src/cthulhu/cmdnames.py:101 -msgid "Present the default button" -msgstr "呈現預設按鈕" - -#: src/cthulhu/cmdnames.py:105 -msgid "Present the status bar" -msgstr "朗讀狀態列" - -#: src/cthulhu/cmdnames.py:109 -msgid "Present the title bar" -msgstr "朗讀標題列" - -#: src/cthulhu/cmdnames.py:114 -msgid "Open the Find dialog" -msgstr "開啟「尋找」對話盒。" - -#: src/cthulhu/cmdnames.py:118 -msgid "Show actions list" -msgstr "顯示動作清單" - -#: src/cthulhu/cmdnames.py:124 -msgid "Search for the next instance of a string" -msgstr "搜尋下一個相同的字串。" - -#: src/cthulhu/cmdnames.py:130 -msgid "Search for the previous instance of a string" -msgstr "搜尋上一個相同的字串。" - -#: src/cthulhu/cmdnames.py:137 -msgid "Enter and exit flat review mode" -msgstr "進入及離開 flat review 模式。" - -#: src/cthulhu/cmdnames.py:145 -msgid "Toggle restricting flat review to the current object" -msgstr "切換將平面檢視限制為目前物件" - -#: src/cthulhu/cmdnames.py:153 -msgid "Move flat review to the home position" -msgstr "將 flat review 移至家位置。" - -#: src/cthulhu/cmdnames.py:161 -msgid "Move flat review to the end position" -msgstr "將 flat review 移至最尾位置。" - -#: src/cthulhu/cmdnames.py:169 -msgid "Move flat review to the beginning of the previous line" -msgstr "將 flat review 移至上一列的列首。" - -#: src/cthulhu/cmdnames.py:176 -msgid "Speak the current flat review line" -msgstr "讀出目前的 flat review 列。" - -#: src/cthulhu/cmdnames.py:185 -msgid "Spell the current flat review line" -msgstr "拼出目前的 flat review 列。" - -#: src/cthulhu/cmdnames.py:195 -msgid "Phonetically spell the current flat review line" -msgstr "拼出目前的 flat review 文字列。" - -#: src/cthulhu/cmdnames.py:202 -msgid "Move flat review to the beginning of the next line" -msgstr "將 flat review 移至下一列的列首。" - -#: src/cthulhu/cmdnames.py:211 -msgid "Move flat review to the previous item or word" -msgstr "將 flat review 移至上一個字元或字詞。" - -#: src/cthulhu/cmdnames.py:219 -msgid "Speak the current flat review item or word" -msgstr "讀出目前的 flat review 項目或字詞。" - -#: src/cthulhu/cmdnames.py:228 -msgid "Spell the current flat review item or word" -msgstr "拼出目前的 flat review 項目或字詞。" - -#: src/cthulhu/cmdnames.py:239 -msgid "Phonetically spell the current flat review item or word" -msgstr "拼出目前的 flat review 項目或字詞。" - -#: src/cthulhu/cmdnames.py:248 -msgid "Move flat review to the next item or word" -msgstr "將 flat review 移至下一個項目或字詞。" - -#: src/cthulhu/cmdnames.py:257 -msgid "Move flat review to the word above the current word" -msgstr "將 flat review 移至目前字詞之上。" - -#: src/cthulhu/cmdnames.py:267 -msgid "Speak the current flat review object" -msgstr "讀出目前的 flat review 物件。" - -#: src/cthulhu/cmdnames.py:276 -msgid "Move flat review to the word below the current word" -msgstr "將 flat review 移至目前字詞之下。" - -#: src/cthulhu/cmdnames.py:285 -msgid "Move flat review to the previous character" -msgstr "將 flat review 移至上一個字元。" - -#: src/cthulhu/cmdnames.py:293 -msgid "Speak the current flat review character" -msgstr "讀出目前的 flat review 字元。" - -#: src/cthulhu/cmdnames.py:303 -msgid "Phonetically speak the current flat review character" -msgstr "讀出目前的 flat review 字元。" - -#: src/cthulhu/cmdnames.py:313 -msgid "Speak unicode value of the current flat review character" -msgstr "讀出目前的 flat review 字元的 unicode 數值。" - -#: src/cthulhu/cmdnames.py:322 -msgid "Move flat review to the next character" -msgstr "將 flat review 移至下一個字元。" - -#: src/cthulhu/cmdnames.py:330 -msgid "Move flat review to the end of the line" -msgstr "將 flat review 移至行尾。" - -#: src/cthulhu/cmdnames.py:338 -msgid "Move flat review to the bottom left" -msgstr "將 flat review 移至左下。" - -#: src/cthulhu/cmdnames.py:347 -msgid "Copy the contents under flat review to the clipboard" -msgstr "將目前的 flat review 內容複製到剪貼簿。" - -#: src/cthulhu/cmdnames.py:357 -msgid "Append the contents under flat review to the clipboard" -msgstr "將目前的 flat review 內容添加到剪貼簿。" - -#: src/cthulhu/cmdnames.py:368 -msgid "Show flat review contents" -msgstr "顯示平面檢視內容" - -#: src/cthulhu/cmdnames.py:374 -msgid "Toggle whether to read just the current table cell or the whole row" -msgstr "切換應否閱讀目前的表格或整列。" - -#: src/cthulhu/cmdnames.py:379 -msgid "Read the attributes associated with the current text character" -msgstr "閱讀目前字元相關的屬性。" - -#: src/cthulhu/cmdnames.py:386 -msgid "Pan the braille display to the left" -msgstr "點字顯示向左移。" - -#: src/cthulhu/cmdnames.py:393 -msgid "Pan the braille display to the right" -msgstr "點字顯示向右移。" - -#: src/cthulhu/cmdnames.py:403 -msgid "Return to object with keyboard focus" -msgstr "回到有鍵盤焦點的物件" - -#: src/cthulhu/cmdnames.py:409 -msgid "Turn contracted braille on and off" -msgstr "開啟和關閉縮短式點字。" - -#: src/cthulhu/cmdnames.py:414 -msgid "Process a cursor routing key" -msgstr "處理游標轉向鍵。" - -#: src/cthulhu/cmdnames.py:417 -msgid "Mark the beginning of a text selection" -msgstr "標記文字選擇區域的開頭。" - -#: src/cthulhu/cmdnames.py:420 -msgid "Mark the end of a text selection" -msgstr "標記文字選擇區域的結尾。" - -#: src/cthulhu/cmdnames.py:427 -msgid "Enter learn mode. Press escape to exit learn mode" -msgstr "進入學習模式。 按離開鍵離開學習模式。" - -#: src/cthulhu/cmdnames.py:431 -msgid "Decrease the speech rate" -msgstr "減慢朗讀速度。" - -#: src/cthulhu/cmdnames.py:435 -msgid "Increase the speech rate" -msgstr "加快朗讀速度。" - -#: src/cthulhu/cmdnames.py:439 -msgid "Decrease the speech pitch" -msgstr "減低朗讀音調。" - -#: src/cthulhu/cmdnames.py:443 -msgid "Increase the speech pitch" -msgstr "加高朗讀音調。" - -#: src/cthulhu/cmdnames.py:447 -msgid "Increase the speech volume" -msgstr "增加語音音量。" - -#: src/cthulhu/cmdnames.py:451 -msgid "Decrease the speech volume" -msgstr "減少語音音量。" - -#: src/cthulhu/cmdnames.py:454 -msgid "Select the previous speech setting" -msgstr "選擇上一個語音設定" - -#: src/cthulhu/cmdnames.py:457 -msgid "Select the next speech setting" -msgstr "選擇下一個語音設定" - -#: src/cthulhu/cmdnames.py:460 -msgid "Decrease the current speech setting" -msgstr "減小目前語音設定" - -#: src/cthulhu/cmdnames.py:463 -msgid "Increase the current speech setting" -msgstr "增大目前語音設定" - -#: src/cthulhu/cmdnames.py:466 -msgid "Save speech settings" -msgstr "儲存語音設定" - -#: src/cthulhu/cmdnames.py:470 -msgid "Toggle the silencing of speech" -msgstr "切換為靜音。" - -#: src/cthulhu/cmdnames.py:476 -msgid "Toggle speech verbosity level" -msgstr "切換語音詳細等級。" - -#: src/cthulhu/cmdnames.py:479 -msgid "Toggle sleep mode" -msgstr "切換睡眠模式" - -#: src/cthulhu/cmdnames.py:483 -msgid "Quit the screen reader" -msgstr "結束螢幕閱讀器" - -#: src/cthulhu/cmdnames.py:487 -msgid "Display the preferences configuration dialog" -msgstr "顯示偏好設定對話視窗。" - -#: src/cthulhu/cmdnames.py:492 -msgid "Display the application preferences configuration dialog" -msgstr "顯示偏好設定對話盒。" - -#: src/cthulhu/cmdnames.py:497 -msgid "Toggle the speaking of indentation and justification" -msgstr "切換是否讀出縮排及對齊。" - -#: src/cthulhu/cmdnames.py:503 -msgid "Change spoken number style" -msgstr "改變數字報讀的風格。" - -#: src/cthulhu/cmdnames.py:507 -msgid "Cycle to the next speaking of punctuation level" -msgstr "循環至下一個標音符號等級。" - -#: src/cthulhu/cmdnames.py:512 -msgid "Cycle to the next speech synthesizer" -msgstr "切換到下一個語音合成器" - -#: src/cthulhu/cmdnames.py:520 -msgid "Cycle to the next settings profile" -msgstr "循環至下一個設定檔。" - -#: src/cthulhu/cmdnames.py:529 -msgid "Cycle to the next capitalization style" -msgstr "循環至下一個大寫樣式。" - -#: src/cthulhu/cmdnames.py:541 -msgid "Cycle to the next key echo level" -msgstr "循環至下一個按鍵回響等級。" - -#: src/cthulhu/cmdnames.py:546 -msgid "Cycle the debug level at run time" -msgstr "在執行時圈出偵錯級別。" - -#: src/cthulhu/cmdnames.py:553 -msgid "Bookmark where am I with respect to current position" -msgstr "指出我目前位置到書籤的相對關係" - -#: src/cthulhu/cmdnames.py:559 -msgid "Go to previous bookmark location" -msgstr "移至上一個書籤位置。" - -#: src/cthulhu/cmdnames.py:564 -msgid "Go to bookmark" -msgstr "移至書籤。" - -#: src/cthulhu/cmdnames.py:570 -msgid "Go to next bookmark location" -msgstr "移至下一個書籤位置。" - -#: src/cthulhu/cmdnames.py:574 -msgid "Add bookmark" -msgstr "加入書籤。" - -#: src/cthulhu/cmdnames.py:578 -msgid "Save bookmarks" -msgstr "儲存書籤。" - -#: src/cthulhu/cmdnames.py:582 -msgid "Toggle mouse review mode" -msgstr "切換滑鼠預覽模式。" - -#: src/cthulhu/cmdnames.py:586 -msgid "Present current time" -msgstr "表示目前的時刻。" - -#: src/cthulhu/cmdnames.py:590 -msgid "Present current date" -msgstr "表示目前的日期。" - -#: src/cthulhu/cmdnames.py:595 -msgid "Present size and location of current object" -msgstr "" - -#: src/cthulhu/cmdnames.py:602 -msgid "Pass the next command on to the current application" -msgstr "傳送「下一步」指令給目前的應用程式" - -#: src/cthulhu/cmdnames.py:607 -msgid "Speak and braille a previous chat room message" -msgstr "讀出及點出上一個聊天室的訊息。" - -#: src/cthulhu/cmdnames.py:615 -msgid "Toggle whether we announce when our buddies are typing" -msgstr "切換當我們的朋友在輸入時是否告知我們。" - -#: src/cthulhu/cmdnames.py:625 -msgid "Toggle whether we provide chat room specific message histories" -msgstr "切換是否提供指定聊天室的的訊息歷史紀錄。" - -#: src/cthulhu/cmdnames.py:636 -msgid "" -"Toggle whether we prefix chat room messages with the name of the chat room" -msgstr "切換是否將聊天室的名稱加入聊天室的訊息前。" - -#: src/cthulhu/cmdnames.py:642 -msgid "Line Left" -msgstr "向左一列" - -#: src/cthulhu/cmdnames.py:647 -msgid "Line Right" -msgstr "向右一列" - -#: src/cthulhu/cmdnames.py:652 -msgid "Line Up" -msgstr "向上一列" - -#: src/cthulhu/cmdnames.py:657 -msgid "Line Down" -msgstr "向下一列" - -#: src/cthulhu/cmdnames.py:662 -msgid "Freeze" -msgstr "固定" - -#: src/cthulhu/cmdnames.py:667 -msgid "Top Left" -msgstr "左上" - -#: src/cthulhu/cmdnames.py:672 -msgid "Bottom Left" -msgstr "左下" - -#: src/cthulhu/cmdnames.py:677 -msgid "Cursor Position" -msgstr "游標位置" - -#: src/cthulhu/cmdnames.py:682 -msgid "Six Dots" -msgstr "六點" - -#: src/cthulhu/cmdnames.py:689 -msgid "Cursor Routing" -msgstr "游標轉向" - -#: src/cthulhu/cmdnames.py:696 -msgid "Cut Begin" -msgstr "剪下開頭" - -#: src/cthulhu/cmdnames.py:703 -msgid "Cut Line" -msgstr "剪下行" - -#: src/cthulhu/cmdnames.py:707 -msgid "Present last notification message" -msgstr "顯示上次的通知訊息。" - -#: src/cthulhu/cmdnames.py:711 -msgid "Present notification messages list" -msgstr "顯示通知訊息清單" - -#: src/cthulhu/cmdnames.py:715 -msgid "Present previous notification message" -msgstr "顯示前一個通知訊息。" - -#: src/cthulhu/cmdnames.py:719 -msgid "Present next notification message" -msgstr "朗讀下一則通知訊息" - -#: src/cthulhu/cmdnames.py:722 -msgid "Go to next character" -msgstr "移至下一個字元。" - -#: src/cthulhu/cmdnames.py:725 -msgid "Go to previous character" -msgstr "移至前一個字元。" - -#: src/cthulhu/cmdnames.py:728 -msgid "Go to next word" -msgstr "移至下一個單字。" - -#: src/cthulhu/cmdnames.py:731 -msgid "Go to previous word" -msgstr "移至下一個單字。" - -#: src/cthulhu/cmdnames.py:734 -msgid "Go to next line" -msgstr "移至下一列。" - -#: src/cthulhu/cmdnames.py:737 -msgid "Go to previous line" -msgstr "移至上一列。" - -#: src/cthulhu/cmdnames.py:740 -msgid "Go to the top of the file" -msgstr "移至檔案的最上面。" - -#: src/cthulhu/cmdnames.py:743 -msgid "Go to the bottom of the file" -msgstr "移至檔案的最下面。" - -#: src/cthulhu/cmdnames.py:746 -msgid "Go to the beginning of the line" -msgstr "移至行首。" - -#: src/cthulhu/cmdnames.py:749 -msgid "Go to the end of the line" -msgstr "移至行尾。" - -#: src/cthulhu/cmdnames.py:752 -msgid "Go to the next object" -msgstr "移至下一個物件。" - -#: src/cthulhu/cmdnames.py:755 -msgid "Go to the previous object" -msgstr "移至上一個物件。" - -#: src/cthulhu/cmdnames.py:760 -msgid "Cause the current combo box to be expanded" -msgstr "使目前的組合方塊展開。" - -#: src/cthulhu/cmdnames.py:767 -msgid "Switch between native and screen-reader caret navigation" -msgstr "在原生瀏覽與鍵盤瀏覽方式間切換。" - -#: src/cthulhu/cmdnames.py:776 -msgid "Advance live region politeness setting" -msgstr "進階即時播報區禮貌程度設定值。" - -#: src/cthulhu/cmdnames.py:786 -msgid "Set default live region politeness level to off" -msgstr "設定預設的即時播報區禮貌程度為關閉。" - -#: src/cthulhu/cmdnames.py:792 -msgid "Review live region announcement" -msgstr "檢閱即時播報區公告。" - -#: src/cthulhu/cmdnames.py:803 -msgid "Monitor live regions" -msgstr "監控即時播報區。" - -#: src/cthulhu/cmdnames.py:810 -msgid "Move focus into and away from the current mouse over" -msgstr "將焦點移入或移出目前滑鼠停駐的位置。" - -#: src/cthulhu/cmdnames.py:815 -msgid "Set the row to use as dynamic column headers" -msgstr "將列設定為使用動態欄標頭。" - -#: src/cthulhu/cmdnames.py:821 -msgid "Clear the dynamic column headers" -msgstr "清除動態欄標頭。" - -#: src/cthulhu/cmdnames.py:826 -msgid "Set the column to use as dynamic row headers" -msgstr "將欄設定為使用動態列標頭。" - -#: src/cthulhu/cmdnames.py:832 -msgid "Clear the dynamic row headers" -msgstr "清除動態式列標題" - -#: src/cthulhu/cmdnames.py:836 -msgid "Present the contents of the input line" -msgstr "表示輸入行的內容。" - -#: src/cthulhu/cmdnames.py:843 -msgid "Toggle structural navigation keys" -msgstr "切換結構導覽鍵。" - -#: src/cthulhu/cmdnames.py:846 -msgid "Go to previous blockquote" -msgstr "移至前一個區塊括弧。" - -#: src/cthulhu/cmdnames.py:849 -msgid "Go to next blockquote" -msgstr "移至下一個區塊括弧。" - -#: src/cthulhu/cmdnames.py:852 -msgid "Display a list of blockquotes" -msgstr "顯示區塊括弧清單。" - -#: src/cthulhu/cmdnames.py:855 -msgid "Go to previous button" -msgstr "前往上一個按鈕" - -#: src/cthulhu/cmdnames.py:858 -msgid "Go to next button" -msgstr "前往下一個按鈕" - -#: src/cthulhu/cmdnames.py:861 -msgid "Display a list of buttons" -msgstr "顯示按鈕清單。" - -#: src/cthulhu/cmdnames.py:864 -msgid "Go to previous check box" -msgstr "移至前一個勾選盒。" - -#: src/cthulhu/cmdnames.py:867 -msgid "Go to next check box" -msgstr "移至下一個勾選盒。" - -#: src/cthulhu/cmdnames.py:870 -msgid "Display a list of check boxes" -msgstr "顯示勾選盒清單。" - -#: src/cthulhu/cmdnames.py:874 -msgid "Go to previous clickable" -msgstr "移至前一個可按下項目。" - -#: src/cthulhu/cmdnames.py:878 -msgid "Go to next clickable" -msgstr "移至下一個可按下項目。" - -#: src/cthulhu/cmdnames.py:882 -msgid "Display a list of clickables" -msgstr "顯示可按下項目清單。" - -#: src/cthulhu/cmdnames.py:885 -msgid "Go to previous combo box" -msgstr "移至前一個組合方塊。" - -#: src/cthulhu/cmdnames.py:888 -msgid "Go to next combo box" -msgstr "移至下一個組合方塊。" - -#: src/cthulhu/cmdnames.py:893 -msgid "Go to start of container" -msgstr "移至容器的開頭。" - -#: src/cthulhu/cmdnames.py:898 -msgid "Go to end of container" -msgstr "移至容器的結尾。" - -#: src/cthulhu/cmdnames.py:901 -msgid "Display a list of combo boxes" -msgstr "顯示組合方塊清單。" - -#: src/cthulhu/cmdnames.py:904 -msgid "Go to previous entry" -msgstr "移至前一個項目。" - -#: src/cthulhu/cmdnames.py:907 -msgid "Go to next entry" -msgstr "移至下一個項目。" - -#: src/cthulhu/cmdnames.py:910 -msgid "Display a list of entries" -msgstr "顯示項目清單。" - -#: src/cthulhu/cmdnames.py:913 -msgid "Go to previous form field" -msgstr "前往上一個表單欄位" - -#: src/cthulhu/cmdnames.py:916 -msgid "Go to next form field" -msgstr "前往下一個表單欄位" - -#: src/cthulhu/cmdnames.py:919 -msgid "Display a list of form fields" -msgstr "顯示表單欄位清單。" - -#: src/cthulhu/cmdnames.py:922 -msgid "Go to previous heading" -msgstr "前往上一個標題" - -#: src/cthulhu/cmdnames.py:925 -msgid "Go to next heading" -msgstr "前往下一個標題" - -#: src/cthulhu/cmdnames.py:928 -msgid "Display a list of headings" -msgstr "顯示標題清單。" - -#: src/cthulhu/cmdnames.py:932 -#, fuzzy, python-format -msgid "Go to previous heading at level %d" -msgstr "移至前一個第 %d 級標題。" - -#: src/cthulhu/cmdnames.py:936 -#, fuzzy, python-format -msgid "Go to next heading at level %d" -msgstr "移至下一個第 %d 級標題。" - -#: src/cthulhu/cmdnames.py:940 -#, fuzzy, python-format -msgid "Display a list of headings at level %d" -msgstr "顯示第 %d 級標題清單。" - -#: src/cthulhu/cmdnames.py:943 -msgid "Go to previous internal frame" -msgstr "前往上一個內部框架" - -#: src/cthulhu/cmdnames.py:946 -msgid "Go to next internal frame" -msgstr "前往下一個內部框架" - -#: src/cthulhu/cmdnames.py:949 -msgid "Display a list of internal frames" -msgstr "顯示內部框架清單" - -#: src/cthulhu/cmdnames.py:952 -msgid "Go to previous image" -msgstr "移至前一個影像。" - -#: src/cthulhu/cmdnames.py:955 -msgid "Go to next image" -msgstr "移至下一個影像。" - -#: src/cthulhu/cmdnames.py:958 -msgid "Display a list of images" -msgstr "顯示影像清單。" - -#: src/cthulhu/cmdnames.py:963 -msgid "Go to previous landmark" -msgstr "移至前一個地標。" - -#: src/cthulhu/cmdnames.py:968 -msgid "Go to next landmark" -msgstr "移至下一個地標。" - -#: src/cthulhu/cmdnames.py:973 -msgid "Display a list of landmarks" -msgstr "顯示地標清單。" - -#: src/cthulhu/cmdnames.py:978 -msgid "Go to previous large object" -msgstr "移至前一個大型物件。" - -#: src/cthulhu/cmdnames.py:983 -msgid "Go to next large object" -msgstr "移至下一個大型物件。" - -#: src/cthulhu/cmdnames.py:988 -msgid "Display a list of large objects" -msgstr "顯示大型物件清單。" - -#: src/cthulhu/cmdnames.py:991 -msgid "Go to previous link" -msgstr "前往上一個連結" - -#: src/cthulhu/cmdnames.py:994 -msgid "Go to next link" -msgstr "前往下一個連結" - -#: src/cthulhu/cmdnames.py:997 -msgid "Display a list of links" -msgstr "顯示連結清單。" - -#: src/cthulhu/cmdnames.py:1000 -msgid "Go to previous list" -msgstr "移至前一個清單。" - -#: src/cthulhu/cmdnames.py:1003 -msgid "Go to next list" -msgstr "移至下一個清單。" - -#: src/cthulhu/cmdnames.py:1006 -msgid "Display a list of lists" -msgstr "顯示清單的列表。" - -#: src/cthulhu/cmdnames.py:1009 -msgid "Go to previous list item" -msgstr "移至前一個清單項目。" - -#: src/cthulhu/cmdnames.py:1012 -msgid "Go to next list item" -msgstr "移至下一個清單項目。" - -#: src/cthulhu/cmdnames.py:1015 -msgid "Display a list of list items" -msgstr "顯示清單項目清單。" - -#: src/cthulhu/cmdnames.py:1020 -msgid "Go to previous live region" -msgstr "移至前一個即時播報區。" - -#: src/cthulhu/cmdnames.py:1025 -msgid "Go to next live region" -msgstr "移至下一個即時播報區。" - -#: src/cthulhu/cmdnames.py:1030 -msgid "Go to the last live region which made an announcement" -msgstr "發布公告時移至即時播報區。" - -#: src/cthulhu/cmdnames.py:1034 -msgid "Go to the parent of the object with navigator focus." -msgstr "前往導覽器焦點物件的父物件。" - -#: src/cthulhu/cmdnames.py:1038 -msgid "Go to the first child of the object with navigator focus." -msgstr "前往導覽器焦點物件的第一個子物件。" - -#: src/cthulhu/cmdnames.py:1042 -msgid "Go to the next sibling of the object with navigator focus." -msgstr "前往導覽器焦點物件的下一個同層物件。" - -#: src/cthulhu/cmdnames.py:1046 -msgid "Go to the previous sibling of the object with navigator focus." -msgstr "前往導覽器焦點物件的上一個同層物件。" - -#: src/cthulhu/cmdnames.py:1050 -msgid "Click on the object with navigator focus." -msgstr "點擊具有導覽焦點的物件。" - -#: src/cthulhu/cmdnames.py:1055 -msgid "Toggle simplified object navigation." -msgstr "切換簡化物件導覽。" - -#: src/cthulhu/cmdnames.py:1058 -msgid "Go to previous paragraph" -msgstr "移至前一段。" - -#: src/cthulhu/cmdnames.py:1061 -msgid "Go to next paragraph" -msgstr "移至下一段。" - -#: src/cthulhu/cmdnames.py:1064 -msgid "Display a list of paragraphs" -msgstr "顯示段落清單。" - -#: src/cthulhu/cmdnames.py:1067 -msgid "Go to previous radio button" -msgstr "移至前一個單選按鈕。" - -#: src/cthulhu/cmdnames.py:1070 -msgid "Go to next radio button" -msgstr "移至下一個單選按鈕。" - -#: src/cthulhu/cmdnames.py:1073 -msgid "Display a list of radio buttons" -msgstr "顯示單選按鈕清單。" - -#: src/cthulhu/cmdnames.py:1077 -msgid "Go to previous separator" -msgstr "移至前一個分隔符。" - -#: src/cthulhu/cmdnames.py:1081 -msgid "Go to next separator" -msgstr "移至下一個分隔符。" - -#: src/cthulhu/cmdnames.py:1084 -msgid "Go to previous table" -msgstr "移至前一個工作表。" - -#: src/cthulhu/cmdnames.py:1087 -msgid "Go to next table" -msgstr "移至下一個工作表。" - -#: src/cthulhu/cmdnames.py:1090 -msgid "Display a list of tables" -msgstr "顯示表格清單。" - -#: src/cthulhu/cmdnames.py:1093 -msgid "Go down one cell" -msgstr "移至下面一個儲存格。" - -#: src/cthulhu/cmdnames.py:1096 -msgid "Go to the first cell in a table" -msgstr "移至表格中的第一個儲存格。" - -#: src/cthulhu/cmdnames.py:1099 -msgid "Go to the last cell in a table" -msgstr "移至表格中的最後一個儲存格。" - -#: src/cthulhu/cmdnames.py:1102 -msgid "Go left one cell" -msgstr "移至左邊一個儲存格。" - -#: src/cthulhu/cmdnames.py:1105 -msgid "Go right one cell" -msgstr "移至右邊一個儲存格。" - -#: src/cthulhu/cmdnames.py:1108 -msgid "Go up one cell" -msgstr "移至上面一個儲存格。" - -#: src/cthulhu/cmdnames.py:1121 -msgid "Toggle layout mode" -msgstr "切換滑鼠預覽模式。" - -#: src/cthulhu/cmdnames.py:1137 -msgid "Switch between browse mode and focus mode" -msgstr "切換瀏覽模式與焦點模式。" - -#: src/cthulhu/cmdnames.py:1148 -msgid "Enable sticky focus mode" -msgstr "啟用黏性焦點模式。" - -#: src/cthulhu/cmdnames.py:1159 -msgid "Enable sticky browse mode" -msgstr "啟用黏性瀏覽模式。" - -#: src/cthulhu/cmdnames.py:1162 -msgid "Go to previous unvisited link" -msgstr "移至前一個未瀏覽的連結。" - -#: src/cthulhu/cmdnames.py:1165 -msgid "Go to next unvisited link" -msgstr "移至下一個未瀏覽連結。" - -#: src/cthulhu/cmdnames.py:1168 -msgid "Display a list of unvisited links" -msgstr "顯示未瀏覽連結清單。" - -#: src/cthulhu/cmdnames.py:1171 -msgid "Go to previous visited link" -msgstr "移至前一個瀏覽過的連結。" - -#: src/cthulhu/cmdnames.py:1174 -msgid "Go to next visited link" -msgstr "移至下一個瀏覽過的連結。" - -#: src/cthulhu/cmdnames.py:1177 -msgid "Display a list of visited links" -msgstr "顯示已瀏覽連結清單。" - -#: src/cthulhu/colornames.py:39 -msgctxt "color name" -msgid "alice blue" -msgstr "愛麗絲藍" - -#: src/cthulhu/colornames.py:44 -msgctxt "color name" -msgid "antique white" -msgstr "古董白" - -#: src/cthulhu/colornames.py:49 -msgctxt "color name" -msgid "aquamarine" -msgstr "碧寶石碧綠" - -#: src/cthulhu/colornames.py:54 -msgctxt "color name" -msgid "azure" -msgstr "蔚藍色" - -#: src/cthulhu/colornames.py:59 -msgctxt "color name" -msgid "beige" -msgstr "米黃色" - -#: src/cthulhu/colornames.py:64 -msgctxt "color name" -msgid "bisque" -msgstr "陶坯黃" - -#: src/cthulhu/colornames.py:69 -msgctxt "color name" -msgid "black" -msgstr "黑色" - -#: src/cthulhu/colornames.py:74 -msgctxt "color name" -msgid "blanched almond" -msgstr "杏仁白" - -#: src/cthulhu/colornames.py:79 -msgctxt "color name" -msgid "blue" -msgstr "藍色" - -#: src/cthulhu/colornames.py:84 -msgctxt "color name" -msgid "blue violet" -msgstr "藍紫色" - -#: src/cthulhu/colornames.py:89 -msgctxt "color name" -msgid "brown" -msgstr "棕色" - -#: src/cthulhu/colornames.py:94 -msgctxt "color name" -msgid "burlywood" -msgstr "硬木色" - -#: src/cthulhu/colornames.py:99 -msgctxt "color name" -msgid "cadet blue" -msgstr "軍服藍" - -#: src/cthulhu/colornames.py:104 -msgctxt "color name" -msgid "chartreuse" -msgstr "查特酒綠" - -#: src/cthulhu/colornames.py:109 -msgctxt "color name" -msgid "chocolate" -msgstr "巧克力色" - -#: src/cthulhu/colornames.py:114 -msgctxt "color name" -msgid "coral" -msgstr "珊瑚色" - -#: src/cthulhu/colornames.py:119 -msgctxt "color name" -msgid "cornflower blue" -msgstr "矢車菊藍" - -#: src/cthulhu/colornames.py:124 -msgctxt "color name" -msgid "cornsilk" -msgstr "玉米絲色" - -#: src/cthulhu/colornames.py:129 -msgctxt "color name" -msgid "crimson" -msgstr "緋紅" - -#: src/cthulhu/colornames.py:134 -msgctxt "color name" -msgid "cyan" -msgstr "青色" - -#: src/cthulhu/colornames.py:139 -msgctxt "color name" -msgid "dark blue" -msgstr "暗藍" - -#: src/cthulhu/colornames.py:144 -msgctxt "color name" -msgid "dark cyan" -msgstr " \t暗青" - -#: src/cthulhu/colornames.py:149 -msgctxt "color name" -msgid "dark goldenrod" -msgstr "暗金菊色" - -#: src/cthulhu/colornames.py:154 -msgctxt "color name" -msgid "dark gray" -msgstr "暗灰色" - -#: src/cthulhu/colornames.py:159 -msgctxt "color name" -msgid "dark green" -msgstr "暗綠" - -#: src/cthulhu/colornames.py:164 -msgctxt "color name" -msgid "dark khaki" -msgstr "暗卡其色" - -#: src/cthulhu/colornames.py:169 -msgctxt "color name" -msgid "dark magenta" -msgstr "暗洋紅" - -#: src/cthulhu/colornames.py:174 -msgctxt "color name" -msgid "dark olive green" -msgstr "暗橄欖綠" - -#: src/cthulhu/colornames.py:179 -msgctxt "color name" -msgid "dark orange" -msgstr "暗橙" - -#: src/cthulhu/colornames.py:184 -msgctxt "color name" -msgid "dark orchid" -msgstr "暗蘭紫" - -#: src/cthulhu/colornames.py:189 -msgctxt "color name" -msgid "dark red" -msgstr "暗紅" - -#: src/cthulhu/colornames.py:194 -msgctxt "color name" -msgid "dark salmon" -msgstr "暗鮭紅" - -#: src/cthulhu/colornames.py:199 -msgctxt "color name" -msgid "dark sea green" -msgstr "暗海綠" - -#: src/cthulhu/colornames.py:204 -msgctxt "color name" -msgid "dark slate blue" -msgstr "暗岩藍" - -#: src/cthulhu/colornames.py:209 -msgctxt "color name" -msgid "dark slate gray" -msgstr "暗岩灰" - -#: src/cthulhu/colornames.py:214 -msgctxt "color name" -msgid "dark turquoise" -msgstr "暗綠松石色" - -#: src/cthulhu/colornames.py:219 -msgctxt "color name" -msgid "dark violet" -msgstr "暗紫" - -#: src/cthulhu/colornames.py:224 -msgctxt "color name" -msgid "deep pink" -msgstr "深粉紅" - -#: src/cthulhu/colornames.py:229 -msgctxt "color name" -msgid "deep sky blue" -msgstr "深天藍" - -#: src/cthulhu/colornames.py:234 -msgctxt "color name" -msgid "dim gray" -msgstr "暗淡灰色" - -#: src/cthulhu/colornames.py:239 -msgctxt "color name" -msgid "dodger blue" -msgstr "道奇藍" - -#: src/cthulhu/colornames.py:244 -msgctxt "color name" -msgid "fire brick" -msgstr "耐火磚紅" - -#: src/cthulhu/colornames.py:249 -msgctxt "color name" -msgid "floral white" -msgstr "花卉白" - -#: src/cthulhu/colornames.py:254 -msgctxt "color name" -msgid "forest green" -msgstr "森林綠" - -#: src/cthulhu/colornames.py:259 -msgctxt "color name" -msgid "fuchsia" -msgstr "品紅色" - -#: src/cthulhu/colornames.py:264 -msgctxt "color name" -msgid "gainsboro" -msgstr "庚斯博羅灰" - -#: src/cthulhu/colornames.py:269 -msgctxt "color name" -msgid "ghost white" -msgstr " \t幽靈白" - -#: src/cthulhu/colornames.py:274 -msgctxt "color name" -msgid "gold" -msgstr "金色" - -#: src/cthulhu/colornames.py:279 -msgctxt "color name" -msgid "goldenrod" -msgstr "金菊色" - -#: src/cthulhu/colornames.py:284 -msgctxt "color name" -msgid "gray" -msgstr "灰色" - -#: src/cthulhu/colornames.py:289 -msgctxt "color name" -msgid "green" -msgstr "綠色" - -#: src/cthulhu/colornames.py:294 -msgctxt "color name" -msgid "green yellow" -msgstr "綠黃" - -#: src/cthulhu/colornames.py:299 -msgctxt "color name" -msgid "honeydew" -msgstr "蜜瓜綠" - -#: src/cthulhu/colornames.py:304 -msgctxt "color name" -msgid "hot pink" -msgstr "暖粉紅" - -#: src/cthulhu/colornames.py:309 -msgctxt "color name" -msgid "indian red" -msgstr "印度紅" - -#: src/cthulhu/colornames.py:314 -msgctxt "color name" -msgid "indigo" -msgstr "靛色" - -#: src/cthulhu/colornames.py:319 -msgctxt "color name" -msgid "ivory" -msgstr "象牙色" - -#: src/cthulhu/colornames.py:324 -msgctxt "color name" -msgid "khaki" -msgstr "卡其色" - -#: src/cthulhu/colornames.py:329 -msgctxt "color name" -msgid "lavender" -msgstr "薰衣草紫" - -#: src/cthulhu/colornames.py:334 -msgctxt "color name" -msgid "lavender blush" -msgstr "薰衣草紫紅" - -#: src/cthulhu/colornames.py:339 -msgctxt "color name" -msgid "lawn green" -msgstr "草坪綠" - -#: src/cthulhu/colornames.py:344 -msgctxt "color name" -msgid "lemon chiffon" -msgstr "檸檬綢色" - -#: src/cthulhu/colornames.py:349 -msgctxt "color name" -msgid "light blue" -msgstr "亮藍" - -#: src/cthulhu/colornames.py:354 -msgctxt "color name" -msgid "light coral" -msgstr "亮珊瑚色" - -#: src/cthulhu/colornames.py:359 -msgctxt "color name" -msgid "light cyan" -msgstr "亮青" - -#: src/cthulhu/colornames.py:364 -msgctxt "color name" -msgid "light goldenrod yellow" -msgstr "亮金菊黃" - -#: src/cthulhu/colornames.py:369 -msgctxt "color name" -msgid "light gray" -msgstr "亮灰色" - -#: src/cthulhu/colornames.py:374 -msgctxt "color name" -msgid "light green" -msgstr "亮綠" - -#: src/cthulhu/colornames.py:379 -msgctxt "color name" -msgid "light pink" -msgstr "亮粉紅" - -#: src/cthulhu/colornames.py:384 -msgctxt "color name" -msgid "light salmon" -msgstr "亮鮭紅" - -#: src/cthulhu/colornames.py:389 -msgctxt "color name" -msgid "light sea green" -msgstr "亮海綠" - -#: src/cthulhu/colornames.py:394 -msgctxt "color name" -msgid "light sky blue" -msgstr "亮天藍" - -#: src/cthulhu/colornames.py:399 -msgctxt "color name" -msgid "light slate gray" -msgstr "亮岩灰" - -#: src/cthulhu/colornames.py:404 -msgctxt "color name" -msgid "light steel blue" -msgstr "亮鋼藍" - -#: src/cthulhu/colornames.py:409 -msgctxt "color name" -msgid "light yellow" -msgstr "亮黃" - -#: src/cthulhu/colornames.py:414 -msgctxt "color name" -msgid "lime" -msgstr "鮮綠色" - -#: src/cthulhu/colornames.py:419 -msgctxt "color name" -msgid "lime green" -msgstr "檸檬綠" - -#: src/cthulhu/colornames.py:424 -msgctxt "color name" -msgid "linen" -msgstr "亞麻色" - -#: src/cthulhu/colornames.py:429 -msgctxt "color name" -msgid "magenta" -msgstr "洋紅" - -#: src/cthulhu/colornames.py:434 -msgctxt "color name" -msgid "maroon" -msgstr "栗色" - -#: src/cthulhu/colornames.py:439 -msgctxt "color name" -msgid "medium aquamarine" -msgstr "中碧藍色" - -#: src/cthulhu/colornames.py:444 -msgctxt "color name" -msgid "medium blue" -msgstr "中藍" - -#: src/cthulhu/colornames.py:449 -msgctxt "color name" -msgid "medium orchid" -msgstr "中蘭紫" - -#: src/cthulhu/colornames.py:454 -msgctxt "color name" -msgid "medium purple" -msgstr "中紫紅" - -#: src/cthulhu/colornames.py:459 -msgctxt "color name" -msgid "medium sea green" -msgstr "中海綠" - -#: src/cthulhu/colornames.py:464 -msgctxt "color name" -msgid "medium slate blue" -msgstr "中岩藍" - -#: src/cthulhu/colornames.py:469 -msgctxt "color name" -msgid "medium spring green" -msgstr "中春綠色" - -#: src/cthulhu/colornames.py:474 -msgctxt "color name" -msgid "medium turquoise" -msgstr "中綠松石色" - -#: src/cthulhu/colornames.py:479 -msgctxt "color name" -msgid "medium violet red" -msgstr "中青紫紅" - -#: src/cthulhu/colornames.py:484 -msgctxt "color name" -msgid "midnight blue" -msgstr "午夜藍" - -#: src/cthulhu/colornames.py:489 -msgctxt "color name" -msgid "mint cream" -msgstr "薄荷奶油色" - -#: src/cthulhu/colornames.py:494 -msgctxt "color name" -msgid "misty rose" -msgstr "霧玫瑰色" - -#: src/cthulhu/colornames.py:499 -msgctxt "color name" -msgid "moccasin" -msgstr "鹿皮鞋色" - -#: src/cthulhu/colornames.py:504 -msgctxt "color name" -msgid "navajo white" -msgstr "那瓦霍白" - -#: src/cthulhu/colornames.py:509 -msgctxt "color name" -msgid "navy" -msgstr "海軍藍" - -#: src/cthulhu/colornames.py:514 -msgctxt "color name" -msgid "old lace" -msgstr "舊蕾絲色" - -#: src/cthulhu/colornames.py:519 -msgctxt "color name" -msgid "olive" -msgstr "橄欖色" - -#: src/cthulhu/colornames.py:524 -msgctxt "color name" -msgid "olive drab" -msgstr "橄欖軍服綠" - -#: src/cthulhu/colornames.py:529 -msgctxt "color name" -msgid "orange" -msgstr "橙色" - -#: src/cthulhu/colornames.py:534 -msgctxt "color name" -msgid "orange red" -msgstr "橙紅" - -#: src/cthulhu/colornames.py:539 -msgctxt "color name" -msgid "orchid" -msgstr "蘭花紫" - -#: src/cthulhu/colornames.py:544 -msgctxt "color name" -msgid "pale goldenrod" -msgstr "灰金菊色" - -#: src/cthulhu/colornames.py:549 -msgctxt "color name" -msgid "pale green" -msgstr "灰綠" - -#: src/cthulhu/colornames.py:554 -msgctxt "color name" -msgid "pale turquoise" -msgstr "灰綠松石色" - -#: src/cthulhu/colornames.py:559 -msgctxt "color name" -msgid "pale violet red" -msgstr "灰紫紅" - -#: src/cthulhu/colornames.py:564 -msgctxt "color name" -msgid "papaya whip" -msgstr "蕃木瓜色" - -#: src/cthulhu/colornames.py:569 -msgctxt "color name" -msgid "peach puff" -msgstr "粉撲桃色" - -#: src/cthulhu/colornames.py:574 -msgctxt "color name" -msgid "peru" -msgstr "秘魯色" - -#: src/cthulhu/colornames.py:579 -msgctxt "color name" -msgid "pink" -msgstr "粉紅" - -#: src/cthulhu/colornames.py:584 -msgctxt "color name" -msgid "plum" -msgstr " \t洋李色" - -#: src/cthulhu/colornames.py:589 -msgctxt "color name" -msgid "powder blue" -msgstr "嬰兒粉藍" - -#: src/cthulhu/colornames.py:594 -msgctxt "color name" -msgid "purple" -msgstr "紫色" - -#: src/cthulhu/colornames.py:599 -msgctxt "color name" -msgid "red" -msgstr "紅色" - -#: src/cthulhu/colornames.py:604 -msgctxt "color name" -msgid "rosy brown" -msgstr "玫瑰褐" - -#: src/cthulhu/colornames.py:609 -msgctxt "color name" -msgid "royal blue" -msgstr "品藍" - -#: src/cthulhu/colornames.py:614 -msgctxt "color name" -msgid "saddle brown" -msgstr "鞍褐" - -#: src/cthulhu/colornames.py:619 -msgctxt "color name" -msgid "salmon" -msgstr "鮭紅" - -#: src/cthulhu/colornames.py:624 -msgctxt "color name" -msgid "sandy brown" -msgstr "沙棕色" - -#: src/cthulhu/colornames.py:629 -msgctxt "color name" -msgid "sea green" -msgstr "暗海綠" - -#: src/cthulhu/colornames.py:634 -msgctxt "color name" -msgid "seashell" -msgstr "海貝殼" - -#: src/cthulhu/colornames.py:639 -msgctxt "color name" -msgid "sienna" -msgstr " \t黃土赭色" - -#: src/cthulhu/colornames.py:644 -msgctxt "color name" -msgid "silver" -msgstr "銀色" - -#: src/cthulhu/colornames.py:649 -msgctxt "color name" -msgid "sky blue" -msgstr "天藍" - -#: src/cthulhu/colornames.py:654 -msgctxt "color name" -msgid "slate blue" -msgstr "岩藍" - -#: src/cthulhu/colornames.py:659 -msgctxt "color name" -msgid "slate gray" -msgstr "岩灰" - -#: src/cthulhu/colornames.py:664 -msgctxt "color name" -msgid "snow" -msgstr "雪白色" - -#: src/cthulhu/colornames.py:669 -msgctxt "color name" -msgid "spring green" -msgstr "春綠" - -#: src/cthulhu/colornames.py:674 -msgctxt "color name" -msgid "steel blue" -msgstr "鋼青色" - -#: src/cthulhu/colornames.py:679 -msgctxt "color name" -msgid "tan" -msgstr "日曬色" - -#: src/cthulhu/colornames.py:684 -msgctxt "color name" -msgid "teal" -msgstr "水鴨色" - -#: src/cthulhu/colornames.py:689 -msgctxt "color name" -msgid "thistle" -msgstr "薊色" - -#: src/cthulhu/colornames.py:694 -msgctxt "color name" -msgid "tomato" -msgstr "番茄紅" - -#: src/cthulhu/colornames.py:699 -msgctxt "color name" -msgid "turquoise" -msgstr "綠寶石" - -#: src/cthulhu/colornames.py:704 -msgctxt "color name" -msgid "violet" -msgstr "礦紫" - -#: src/cthulhu/colornames.py:709 -msgctxt "color name" -msgid "wheat" -msgstr "小麥色" - -#: src/cthulhu/colornames.py:714 -msgctxt "color name" -msgid "white" -msgstr "白色" - -#: src/cthulhu/colornames.py:719 -msgctxt "color name" -msgid "white smoke" -msgstr "白煙色" - -#: src/cthulhu/colornames.py:724 -msgctxt "color name" -msgid "yellow" -msgstr "黃色" - -#: src/cthulhu/colornames.py:729 -msgctxt "color name" -msgid "yellow green" -msgstr "黃綠" - -#: src/cthulhu/guilabels.py:45 -msgid "_Activate" -msgstr "使用(_A)" - -#: src/cthulhu/guilabels.py:63 -msgid "Automatic focus mode during structural navigation" -msgstr "結構式瀏覽時自動焦點模式" - -#: src/cthulhu/guilabels.py:81 -msgid "Automatic focus mode during caret navigation" -msgstr "使用鍵盤瀏覽時自動焦點模式" - -#: src/cthulhu/guilabels.py:96 -msgid "Automatic focus mode during native navigation" -msgstr "使用鍵盤瀏覽時自動焦點模式" - -#: src/cthulhu/guilabels.py:102 src/cthulhu/cthulhu-setup.ui:2449 -#: src/cthulhu/cthulhu-setup.ui:2549 src/cthulhu/cthulhu-setup.ui:3468 -msgid "Dot _7" -msgstr "_7 點" - -#: src/cthulhu/guilabels.py:108 src/cthulhu/cthulhu-setup.ui:2465 -#: src/cthulhu/cthulhu-setup.ui:2565 src/cthulhu/cthulhu-setup.ui:3484 -msgid "Dot _8" -msgstr "_8 點" - -#: src/cthulhu/guilabels.py:114 src/cthulhu/cthulhu-setup.ui:2481 -#: src/cthulhu/cthulhu-setup.ui:2581 src/cthulhu/cthulhu-setup.ui:3500 -msgid "Dots 7 an_d 8" -msgstr "7 和 8 點(_D)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:117 src/cthulhu/cthulhu-setup.ui:190 -msgid "_Cancel" -msgstr "取消(_C)" - -#: src/cthulhu/guilabels.py:120 -msgid "_Jump to" -msgstr "跳至(_J)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/guilabels.py:123 src/cthulhu/cthulhu-setup.ui:206 -msgid "_OK" -msgstr "確定(_O)" - -#: src/cthulhu/guilabels.py:131 -msgctxt "capitalization style" -msgid "Icon" -msgstr "" - -#: src/cthulhu/guilabels.py:139 -#, fuzzy -msgctxt "capitalization style" -msgid "None" -msgstr "沒有" - -#: src/cthulhu/guilabels.py:147 -#, fuzzy -msgctxt "capitalization style" -msgid "Spell" -msgstr "讀出" - -#: src/cthulhu/guilabels.py:151 -msgid "Announce when your _buddies are typing" -msgstr "當您的朋友在輸入時告知(_B)" - -#: src/cthulhu/guilabels.py:156 -msgid "Provide chat room specific _message histories" -msgstr "提供指定聊天室的訊息歷史紀錄(_M)" - -#: src/cthulhu/guilabels.py:163 -msgid "Speak messages from" -msgstr "讀出訊息於" - -#: src/cthulhu/guilabels.py:168 -msgid "All cha_nnels" -msgstr "所有頻道(_N)" - -#: src/cthulhu/guilabels.py:173 -#, python-format -msgid "All channels when an_y %s window is active" -msgstr "當任何 %s 視窗在使用中的所有頻道(_Y)" - -#: src/cthulhu/guilabels.py:178 -msgid "A channel only if its _window is active" -msgstr "只有使用中視窗的頻道(_W)" - -#: src/cthulhu/guilabels.py:182 -msgid "_Speak Chat Room name" -msgstr "讀出聊天室名稱(_S)" - -#: src/cthulhu/guilabels.py:194 -msgid "Enable layout mode for content" -msgstr "啟用內容的配置模式" - -#: src/cthulhu/guilabels.py:199 src/cthulhu/keybindings.py:205 -msgid "double click" -msgstr "雙擊" - -#: src/cthulhu/guilabels.py:204 src/cthulhu/keybindings.py:211 -msgid "triple click" -msgstr "三擊" - -#: src/cthulhu/guilabels.py:210 -msgid "Default Synthesizer" -msgstr "預設語音合成器" - -#: src/cthulhu/guilabels.py:218 -msgid "Actual String" -msgstr "實際字串" - -#: src/cthulhu/guilabels.py:227 -msgid "Replacement String" -msgstr "置換字串" - -#. Translators: When this option is enabled, inserted text of length 1 is spoken. -#: src/cthulhu/guilabels.py:233 src/cthulhu/cthulhu-setup.ui:2950 -msgid "Enable echo by cha_racter" -msgstr "啟用字詞回響(_R)" - -#. Translators: When this option is enabled, dead keys will be announced when pressed. -#: src/cthulhu/guilabels.py:238 src/cthulhu/cthulhu-setup.ui:2924 -msgid "Enable non-spacing _diacritical keys" -msgstr "啟用非空白區別設定鍵(_D)" - -#: src/cthulhu/guilabels.py:244 src/cthulhu/cthulhu-find.ui:150 -msgid "C_urrent location" -msgstr "目前位置(_U)" - -#: src/cthulhu/guilabels.py:249 -msgid "Minimum length of matched text:" -msgstr "比對文字的最小長度:" - -#: src/cthulhu/guilabels.py:253 -msgid "Find Options" -msgstr "「尋找」選項" - -#: src/cthulhu/guilabels.py:259 -msgid "Onl_y speak changed lines during find" -msgstr "尋找時只讀出有改變的列(_Y)" - -#: src/cthulhu/guilabels.py:265 -msgid "Speak results during _find" -msgstr "尋找時讀出結果(_F)" - -#: src/cthulhu/guilabels.py:270 -msgid "Command" -msgstr "逗號" - -#: src/cthulhu/guilabels.py:275 -msgid "Key Binding" -msgstr "按鍵組合" - -#: src/cthulhu/guilabels.py:280 -msgctxt "keybindings" -msgid "Default" -msgstr "預設" - -#: src/cthulhu/guilabels.py:285 -#, fuzzy -msgctxt "keybindings" -msgid "Learn mode" -msgstr "書寫模式" - -#: src/cthulhu/guilabels.py:290 -msgid "Actions" -msgstr "動作" - -#: src/cthulhu/guilabels.py:296 -msgid "Braille Bindings" -msgstr "點字按鍵組合" - -#: src/cthulhu/guilabels.py:300 -msgid "Bookmarks" -msgstr "書籤" - -#: src/cthulhu/guilabels.py:304 -msgid "Date and time" -msgstr "時刻和日期" - -#: src/cthulhu/guilabels.py:310 -msgid "Mouse review" -msgstr "滑鼠複誦已啟用。" - -#: src/cthulhu/guilabels.py:314 -msgid "Object navigation" -msgstr "導覽" - -#: src/cthulhu/guilabels.py:321 -msgid "Object details" -msgstr "" - -#: src/cthulhu/guilabels.py:325 -msgid "Unbound" -msgstr "未繫結" - -#: src/cthulhu/guilabels.py:334 -msgid "Flat review" -msgstr "離開 flat review。" - -#: src/cthulhu/guilabels.py:341 -msgid "Speech and verbosity" -msgstr "" - -#: src/cthulhu/guilabels.py:352 -msgid "Flat review contents" -msgstr "主要内容" - -#: src/cthulhu/guilabels.py:358 -msgctxt "keybindings" -msgid "Modified" -msgstr "已修改" - -#: src/cthulhu/guilabels.py:361 src/cthulhu/cthulhu-setup.ui:256 -msgid "_Desktop" -msgstr "桌面(_D)" - -#: src/cthulhu/guilabels.py:369 -#, fuzzy -msgctxt "notification presenter" -msgid "Notifications" -msgstr "通知" - -#: src/cthulhu/guilabels.py:377 -msgctxt "notification presenter" -msgid "Received" -msgstr "已收到" - -#: src/cthulhu/guilabels.py:381 -msgid "Notification presenter" -msgstr "通知" - -#: src/cthulhu/guilabels.py:389 -#, python-format -msgid "Cthulhu Preferences for %s" -msgstr "%s 的 Cthulhu 偏好設定" - -#: src/cthulhu/guilabels.py:396 -msgid "Mark in braille" -msgstr "以點字標示" - -#: src/cthulhu/guilabels.py:408 -msgid "Present Unless" -msgstr "顯示於" - -#: src/cthulhu/guilabels.py:415 -msgid "Speak" -msgstr "讀出 " - -#: src/cthulhu/guilabels.py:422 -msgid "Save Profile As Conflict" -msgstr "將設定檔儲存為衝突" - -#: src/cthulhu/guilabels.py:429 -msgid "User Profile Conflict!" -msgstr "使用者設定檔有衝突!" - -#: src/cthulhu/guilabels.py:436 -#, python-format -msgid "" -"Profile %s already exists.\n" -"Continue updating the existing profile with these new changes?" -msgstr "" -"設定檔 %s 已經存在。\n" -"是否繼續以這些新的變更來更新現有的設定檔?" - -#: src/cthulhu/guilabels.py:446 -msgid "Load user profile" -msgstr "載入使用者設定檔" - -#: src/cthulhu/guilabels.py:455 -msgid "" -"You are about to change the active profile. If you\n" -"have just made changes in your preferences, they will\n" -"be dropped at profile load.\n" -"\n" -"Continue loading profile discarding previous changes?" -msgstr "" -"您即將改變使用中的設定檔。如果您\n" -"剛剛在偏好設定中做了變更,這個變更會\n" -"在載入設定檔時被丟棄。\n" -"\n" -"是否繼續載入設定檔並放棄前面的變更?" - -#: src/cthulhu/guilabels.py:466 -msgid "Save Profile As" -msgstr "另存設定檔為" - -#: src/cthulhu/guilabels.py:474 -msgid "_Profile Name:" -msgstr "設定檔名稱(_P):" - -#: src/cthulhu/guilabels.py:482 -msgid "Remove user profile" -msgstr "載入使用者設定檔" - -#: src/cthulhu/guilabels.py:490 -#, python-format -msgid "" -"You are about to remove profile %s. All unsaved settings and settings saved " -"in this profile will be lost. Do you want to continue and remove this " -"profile and all related settings?" -msgstr "" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. Choosing All means that Cthulhu will present progress bar updates regardless of what application and window they happen to be in. -#: src/cthulhu/guilabels.py:498 src/cthulhu/cthulhu-setup.ui:77 -msgctxt "ProgressBar" -msgid "All" -msgstr "全部" - -#: src/cthulhu/guilabels.py:504 -msgctxt "ProgressBar" -msgid "Application" -msgstr "應用程式" - -#: src/cthulhu/guilabels.py:509 -msgctxt "ProgressBar" -msgid "Window" -msgstr "視窗" - -#. Translators: this refers to how much punctuation will be spoken by Cthulhu when presenting text on the screen. -#: src/cthulhu/guilabels.py:513 src/cthulhu/cthulhu-setup.ui:1688 -msgctxt "punctuation level" -msgid "_None" -msgstr "沒有(_N)" - -#: src/cthulhu/guilabels.py:518 src/cthulhu/cthulhu-setup.ui:1704 -msgid "So_me" -msgstr "一些(_M)" - -#: src/cthulhu/guilabels.py:522 src/cthulhu/cthulhu-setup.ui:1720 -msgid "M_ost" -msgstr "大部份(_O)" - -#: src/cthulhu/guilabels.py:526 src/cthulhu/cthulhu-setup.ui:63 -msgid "Line" -msgstr "行" - -#: src/cthulhu/guilabels.py:530 src/cthulhu/cthulhu-setup.ui:66 -msgid "Sentence" -msgstr "句子" - -#: src/cthulhu/guilabels.py:536 -msgctxt "structural navigation" -msgid "Blockquote" -msgstr "區塊括弧" - -#: src/cthulhu/guilabels.py:542 -msgctxt "structural navigation" -msgid "Button" -msgstr "按鈕" - -#: src/cthulhu/guilabels.py:548 -msgctxt "structural navigation" -msgid "Caption" -msgstr "標題" - -#: src/cthulhu/guilabels.py:554 -msgctxt "structural navigation" -msgid "Check Box" -msgstr "勾選盒" - -#: src/cthulhu/guilabels.py:560 -msgctxt "structural navigation" -msgid "Clickable" -msgstr "可按下" - -#: src/cthulhu/guilabels.py:566 -msgctxt "structural navigation" -msgid "Combo Box" -msgstr "組合方塊" - -#: src/cthulhu/guilabels.py:572 -msgctxt "structural navigation" -msgid "Description" -msgstr "描述" - -#: src/cthulhu/guilabels.py:578 -msgctxt "structural navigation" -msgid "Heading" -msgstr "標題" - -#: src/cthulhu/guilabels.py:584 -msgctxt "structural navigation" -msgid "Internal Frame" -msgstr "" - -#: src/cthulhu/guilabels.py:590 -msgctxt "structural navigation" -msgid "Image" -msgstr "影像" - -#: src/cthulhu/guilabels.py:596 -msgctxt "structural navigation" -msgid "Label" -msgstr "標籤" - -#: src/cthulhu/guilabels.py:604 -msgctxt "structural navigation" -msgid "Landmark" -msgstr "地標" - -#: src/cthulhu/guilabels.py:611 -msgctxt "structural navigation" -msgid "Level" -msgstr "等級" - -#: src/cthulhu/guilabels.py:617 -msgctxt "structural navigation" -msgid "Link" -msgstr "連結" - -#: src/cthulhu/guilabels.py:623 -msgctxt "structural navigation" -msgid "List" -msgstr "清單" - -#: src/cthulhu/guilabels.py:629 -msgctxt "structural navigation" -msgid "List Item" -msgstr "清單項目" - -#: src/cthulhu/guilabels.py:635 -msgctxt "structural navigation" -msgid "Object" -msgstr "物件" - -#: src/cthulhu/guilabels.py:641 -msgctxt "structural navigation" -msgid "Paragraph" -msgstr "段落" - -#: src/cthulhu/guilabels.py:647 -msgctxt "structural navigation" -msgid "Radio Button" -msgstr "單選按鈕" - -#: src/cthulhu/guilabels.py:654 -msgctxt "structural navigation" -msgid "Role" -msgstr "角色" - -#: src/cthulhu/guilabels.py:660 -msgctxt "structural navigation" -msgid "Selected Item" -msgstr "已選取的項目" - -#: src/cthulhu/guilabels.py:667 -msgctxt "structural navigation" -msgid "State" -msgstr "狀態" - -#: src/cthulhu/guilabels.py:673 -msgctxt "structural navigation" -msgid "Text" -msgstr "文字" - -#: src/cthulhu/guilabels.py:679 -msgctxt "structural navigation" -msgid "URI" -msgstr "URI" - -#: src/cthulhu/guilabels.py:685 -msgctxt "structural navigation" -msgid "Value" -msgstr "數值" - -#: src/cthulhu/guilabels.py:690 -msgctxt "structural navigation" -msgid "Blockquotes" -msgstr "區塊括弧" - -#: src/cthulhu/guilabels.py:695 -msgctxt "structural navigation" -msgid "Buttons" -msgstr "按鈕" - -#: src/cthulhu/guilabels.py:700 -msgctxt "structural navigation" -msgid "Check Boxes" -msgstr "勾選盒" - -#: src/cthulhu/guilabels.py:706 -msgctxt "structural navigation" -msgid "Clickables" -msgstr "可按下" - -#: src/cthulhu/guilabels.py:711 -msgctxt "structural navigation" -msgid "Combo Boxes" -msgstr "組合方塊" - -#: src/cthulhu/guilabels.py:716 -msgctxt "structural navigation" -msgid "Entries" -msgstr "項目" - -#: src/cthulhu/guilabels.py:721 -msgctxt "structural navigation" -msgid "Form Fields" -msgstr "表單欄位" - -#: src/cthulhu/guilabels.py:726 -msgctxt "structural navigation" -msgid "Headings" -msgstr "標題" - -#: src/cthulhu/guilabels.py:731 -msgctxt "structural navigation" -msgid "Internal Frames" -msgstr "" - -#: src/cthulhu/guilabels.py:736 -msgctxt "structural navigation" -msgid "Images" -msgstr "影像" - -#: src/cthulhu/guilabels.py:742 -#, python-format -msgctxt "structural navigation" -msgid "Headings at Level %d" -msgstr "第 %d 級標題" - -#: src/cthulhu/guilabels.py:749 -msgctxt "structural navigation" -msgid "Landmarks" -msgstr "地標" - -#: src/cthulhu/guilabels.py:756 -msgctxt "structural navigation" -msgid "Large Objects" -msgstr "大型物件" - -#: src/cthulhu/guilabels.py:761 -msgctxt "structural navigation" -msgid "Links" -msgstr "連結" - -#: src/cthulhu/guilabels.py:766 -msgctxt "structural navigation" -msgid "Lists" -msgstr "清單" - -#: src/cthulhu/guilabels.py:771 -msgctxt "structural navigation" -msgid "List Items" -msgstr "清單項目" - -#: src/cthulhu/guilabels.py:776 -msgctxt "structural navigation" -msgid "Paragraphs" -msgstr "段落" - -#: src/cthulhu/guilabels.py:781 -msgctxt "structural navigation" -msgid "Radio Buttons" -msgstr "單選按鈕" - -#: src/cthulhu/guilabels.py:786 -msgctxt "structural navigation" -msgid "Tables" -msgstr "表格" - -#: src/cthulhu/guilabels.py:791 -msgctxt "structural navigation" -msgid "Unvisited Links" -msgstr "未瀏覽連結的色彩" - -#: src/cthulhu/guilabels.py:796 -msgctxt "structural navigation" -msgid "Visited Links" -msgstr "已瀏覽連結" - -#: src/cthulhu/guilabels.py:801 -msgid "Page Navigation" -msgstr "面頁導覽" - -#: src/cthulhu/guilabels.py:807 -msgid "Automatically start speaking a page when it is first _loaded" -msgstr "當第一次載入一個頁面時自動開始讀出內容(_L)" - -#: src/cthulhu/guilabels.py:812 -msgid "_Present summary of a page when it is first loaded" -msgstr "當第一次載入時呈現頁面的摘要(_P)" - -#. Translators: different speech systems and speech engines work differently when it comes to handling pauses (e.g., sentence boundaries). This property allows the user to specify whether speech should be sent to the speech synthesis system immediately when a pause directive is encountered or if it should be queued up and sent to the speech synthesis system once the entire set of utterances has been calculated. -#: src/cthulhu/guilabels.py:820 src/cthulhu/cthulhu-setup.ui:1483 -msgid "Break speech into ch_unks between pauses" -msgstr "將語音依停頓的地方隔開(_U)" - -#: src/cthulhu/guilabels.py:828 -#, python-format -msgid "%s default voice" -msgstr "%s 預設語音" - -#: src/cthulhu/guilabels.py:832 -msgctxt "VoiceType" -msgid "Default" -msgstr "預設值" - -#: src/cthulhu/guilabels.py:836 -msgctxt "VoiceType" -msgid "Hyperlink" -msgstr "超連結" - -#: src/cthulhu/guilabels.py:844 -msgctxt "VoiceType" -msgid "System" -msgstr "系統" - -#: src/cthulhu/guilabels.py:848 -msgctxt "VoiceType" -msgid "Uppercase" -msgstr "大寫字母" - -#: src/cthulhu/guilabels.py:852 -msgid "Speech Dispatcher" -msgstr "Speech Dispatcher" - -#: src/cthulhu/guilabels.py:856 -msgctxt "OptionGroup" -msgid "Spell Check" -msgstr "拼字檢查" - -#: src/cthulhu/guilabels.py:862 -msgid "Spell _error" -msgstr "拼字錯誤(_E)" - -#: src/cthulhu/guilabels.py:869 -msgid "Spell _suggestion" -msgstr "拼字建議(_S)" - -#: src/cthulhu/guilabels.py:874 -msgid "Present _context of error" -msgstr "呈現前後文錯誤(_C)" - -#: src/cthulhu/guilabels.py:879 -msgid "Speak spreadsheet cell coordinates" -msgstr "讀出工作表的儲存格坐標" - -#: src/cthulhu/guilabels.py:888 -msgid "Always speak selected spreadsheet range" -msgstr "" - -#: src/cthulhu/guilabels.py:892 -msgid "Announce cell _header" -msgstr "讀出儲存格標題(_H)" - -#: src/cthulhu/guilabels.py:896 -msgid "Table Navigation" -msgstr "表格導覽" - -#: src/cthulhu/guilabels.py:900 -msgid "Skip _blank cells" -msgstr "略過空白儲存格(_B)" - -#: src/cthulhu/guilabels.py:905 -msgid "Speak _cell" -msgstr "讀出儲存格(_C)" - -#: src/cthulhu/guilabels.py:909 -msgid "Speak _cell coordinates" -msgstr "讀出儲存格坐標(_C)" - -#: src/cthulhu/guilabels.py:914 -msgid "Speak _multiple cell spans" -msgstr "讀出合併多個的儲存格(_M)" - -#: src/cthulhu/guilabels.py:918 -msgid "Attribute Name" -msgstr "屬性名稱" - -#: src/cthulhu/guilabels.py:925 -msgid "Control caret navigation" -msgstr "控制鍵盤瀏覽" - -#: src/cthulhu/guilabels.py:930 -msgid "Enable _structural navigation" -msgstr "啟用結構式瀏覽(_S)" - -#. Translators: This is the label for a combo box where users can select a sound theme. -#: src/cthulhu/guilabels.py:935 src/cthulhu/cthulhu-setup.ui:1048 -msgid "Sound _theme:" -msgstr "音效主題(_T):" - -#. Translators: This is the title of a section in the preferences dialog containing sound theme options. -#: src/cthulhu/guilabels.py:939 src/cthulhu/cthulhu-setup.ui:1136 -msgid "Sound Theme" -msgstr "音效主題" - -#: src/cthulhu/guilabels.py:943 src/cthulhu/cthulhu-setup.ui:1621 -#: src/cthulhu/cthulhu-setup.ui:2365 -msgid "Brie_f" -msgstr "簡短(_F)" - -#: src/cthulhu/guilabels.py:953 -#, fuzzy, python-format -msgid "%d notification" -msgid_plural "%d notifications" -msgstr[0] "通知" - -#: src/cthulhu/keynames.py:48 -msgctxt "keyboard" -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/keynames.py:52 -msgctxt "keyboard" -msgid "Alt" -msgstr "Alt" - -#: src/cthulhu/keynames.py:56 -msgctxt "keyboard" -msgid "Control" -msgstr "Control" - -#: src/cthulhu/keynames.py:60 -msgid "left shift" -msgstr "左 shift 鍵" - -#: src/cthulhu/keynames.py:64 -msgid "left alt" -msgstr "左 alt 鍵" - -#: src/cthulhu/keynames.py:68 -msgid "left control" -msgstr "左 control 鍵" - -#: src/cthulhu/keynames.py:72 -msgid "right shift" -msgstr "右 shift 鍵" - -#: src/cthulhu/keynames.py:76 -msgid "right alt" -msgstr "右 alt 鍵" - -#: src/cthulhu/keynames.py:80 -msgid "right control" -msgstr "右 control 鍵" - -#: src/cthulhu/keynames.py:84 -msgid "left meta" -msgstr "左 left 鍵" - -#: src/cthulhu/keynames.py:88 -msgid "right meta" -msgstr "右 right 鍵" - -#: src/cthulhu/keynames.py:92 -msgid "num lock" -msgstr "num lock" - -#: src/cthulhu/keynames.py:96 -msgid "caps lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:101 -msgid "shift lock" -msgstr "caps lock" - -#: src/cthulhu/keynames.py:105 -msgid "scroll lock" -msgstr "scroll lock" - -#: src/cthulhu/keynames.py:109 src/cthulhu/keynames.py:113 -#: src/cthulhu/keynames.py:117 src/cthulhu/keynames.py:121 -msgid "page up" -msgstr "page up" - -#: src/cthulhu/keynames.py:125 src/cthulhu/keynames.py:129 -#: src/cthulhu/keynames.py:133 src/cthulhu/keynames.py:137 -msgid "page down" -msgstr "page down" - -#: src/cthulhu/keynames.py:145 -msgid "left tab" -msgstr "左 tab 鍵" - -#: src/cthulhu/keynames.py:153 -msgid "backspace" -msgstr "backspace" - -#: src/cthulhu/keynames.py:157 -msgid "return" -msgstr "return" - -#: src/cthulhu/keynames.py:161 -msgid "enter" -msgstr "enter" - -#: src/cthulhu/keynames.py:165 src/cthulhu/keynames.py:169 -msgid "up" -msgstr "上" - -#: src/cthulhu/keynames.py:173 src/cthulhu/keynames.py:177 -msgid "down" -msgstr "下" - -#: src/cthulhu/keynames.py:181 src/cthulhu/keynames.py:185 -msgid "left" -msgstr "左" - -#: src/cthulhu/keynames.py:189 src/cthulhu/keynames.py:193 -msgid "right" -msgstr "右" - -#: src/cthulhu/keynames.py:197 -msgid "left super" -msgstr "left super" - -#: src/cthulhu/keynames.py:201 -msgid "right super" -msgstr "right super" - -#: src/cthulhu/keynames.py:205 -msgid "menu" -msgstr "選單" - -#: src/cthulhu/keynames.py:209 -msgid "Alt Gr" -msgstr "Alt Gr" - -#: src/cthulhu/keynames.py:213 -msgid "help" -msgstr "說明" - -#: src/cthulhu/keynames.py:217 -msgid "multi" -msgstr "multi" - -#: src/cthulhu/keynames.py:221 -msgid "mode switch" -msgstr "mode switch" - -#: src/cthulhu/keynames.py:225 -msgid "escape" -msgstr "escape" - -#: src/cthulhu/keynames.py:229 src/cthulhu/keynames.py:233 -msgid "insert" -msgstr "插入" - -#: src/cthulhu/keynames.py:237 src/cthulhu/keynames.py:241 -msgid "delete" -msgstr "刪除" - -#: src/cthulhu/keynames.py:245 src/cthulhu/keynames.py:249 -msgid "home" -msgstr "home" - -#: src/cthulhu/keynames.py:253 src/cthulhu/keynames.py:257 -msgid "end" -msgstr "結束" - -#: src/cthulhu/keynames.py:261 -msgid "begin" -msgstr "begin" - -#: src/cthulhu/keynames.py:276 -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/keynames.py:291 -msgid "ring" -msgstr "ring" - -#: src/cthulhu/keynames.py:301 -msgid "stroke" -msgstr "stroke" - -#: src/cthulhu/keynames.py:305 -msgid "minus" -msgstr "減號" - -#: src/cthulhu/keybindings.py:150 -msgid "Insert" -msgstr "插入" - -#: src/cthulhu/keybindings.py:154 src/cthulhu/keybindings.py:159 -msgid "Caps_Lock" -msgstr "Caps_Lock" - -#: src/cthulhu/keybindings.py:166 -msgid "Alt_R" -msgstr "Alt_R" - -#: src/cthulhu/keybindings.py:171 -msgid "Super" -msgstr "Super" - -#: src/cthulhu/keybindings.py:176 -msgid "Meta2" -msgstr "Meta2" - -#: src/cthulhu/keybindings.py:183 -msgid "Alt_L" -msgstr "Alt_L" - -#: src/cthulhu/keybindings.py:188 -msgid "Ctrl" -msgstr "Ctrl" - -#: src/cthulhu/keybindings.py:193 -msgid "Shift" -msgstr "Shift" - -#: src/cthulhu/mathsymbols.py:1134 -#, python-format -msgctxt "math symbol" -msgid "bold %s" -msgstr "粗體 %s" - -#: src/cthulhu/mathsymbols.py:1144 -#, python-format -msgctxt "math symbol" -msgid "italic %s" -msgstr "斜體 %s" - -#: src/cthulhu/mathsymbols.py:1154 -#, python-format -msgctxt "math symbol" -msgid "bold italic %s" -msgstr "粗斜體 %s" - -#: src/cthulhu/mathsymbols.py:1164 -#, python-format -msgctxt "math symbol" -msgid "script %s" -msgstr "手寫體 %s" - -#: src/cthulhu/mathsymbols.py:1174 -#, python-format -msgctxt "math symbol" -msgid "bold script %s" -msgstr "粗手寫體 %s" - -#: src/cthulhu/mathsymbols.py:1184 -#, python-format -msgctxt "math symbol" -msgid "fraktur %s" -msgstr "fraktur %s" - -#: src/cthulhu/mathsymbols.py:1194 -#, python-format -msgctxt "math symbol" -msgid "double-struck %s" -msgstr "雙重字體 %s" - -#: src/cthulhu/mathsymbols.py:1204 -#, python-format -msgctxt "math symbol" -msgid "bold fraktur %s" -msgstr "粗體 fraktur %s" - -#: src/cthulhu/mathsymbols.py:1214 -#, python-format -msgctxt "math symbol" -msgid "sans-serif %s" -msgstr "無襯線 %s" - -#: src/cthulhu/mathsymbols.py:1224 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold %s" -msgstr "無襯線粗體 %s" - -#: src/cthulhu/mathsymbols.py:1234 -#, python-format -msgctxt "math symbol" -msgid "sans-serif italic %s" -msgstr "無襯線斜體 %s" - -#: src/cthulhu/mathsymbols.py:1244 -#, python-format -msgctxt "math symbol" -msgid "sans-serif bold italic %s" -msgstr "無襯線粗斜體 %s" - -#: src/cthulhu/mathsymbols.py:1254 -#, python-format -msgctxt "math symbol" -msgid "monospace %s" -msgstr "等寬 %s" - -#: src/cthulhu/mathsymbols.py:1264 -#, python-format -msgctxt "math symbol" -msgid "dotless %s" -msgstr "無點%s" - -#: src/cthulhu/mathsymbols.py:1267 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow" -msgstr "顯示箭頭" - -#: src/cthulhu/mathsymbols.py:1270 -#, fuzzy -msgctxt "math symbol" -msgid "up arrow" -msgstr "Up" - -#: src/cthulhu/mathsymbols.py:1273 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow" -msgstr "顯示箭頭" - -#: src/cthulhu/mathsymbols.py:1276 -#, fuzzy -msgctxt "math symbol" -msgid "down arrow" -msgstr "顯示箭頭" - -#: src/cthulhu/mathsymbols.py:1279 -#, fuzzy -msgctxt "math symbol" -msgid "left right arrow" -msgstr "左至右" - -#: src/cthulhu/mathsymbols.py:1282 -#, fuzzy -msgctxt "math symbol" -msgid "up down arrow" -msgstr "提高或降低音量" - -#: src/cthulhu/mathsymbols.py:1285 -#, fuzzy -msgctxt "math symbol" -msgid "north west arrow" -msgstr "北" - -#: src/cthulhu/mathsymbols.py:1288 -#, fuzzy -msgctxt "math symbol" -msgid "north east arrow" -msgstr "北" - -#: src/cthulhu/mathsymbols.py:1291 -#, fuzzy -msgctxt "math symbol" -msgid "south east arrow" -msgstr "南" - -#: src/cthulhu/mathsymbols.py:1294 -#, fuzzy -msgctxt "math symbol" -msgid "left arrow from bar" -msgstr "左箭頭" - -#: src/cthulhu/mathsymbols.py:1297 -msgctxt "math symbol" -msgid "up arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1300 -#, fuzzy -msgctxt "math symbol" -msgid "right arrow from bar" -msgstr "右擊標題列代表的動作" - -#: src/cthulhu/mathsymbols.py:1303 -msgctxt "math symbol" -msgid "down arrow from bar" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1306 -#, fuzzy -msgctxt "math symbol" -msgid "left double arrow" -msgstr "雙精度" - -#: src/cthulhu/mathsymbols.py:1309 -#, fuzzy -msgctxt "math symbol" -msgid "up double arrow" -msgstr "在要查詢的字詞上按兩下滑鼠鍵" - -#: src/cthulhu/mathsymbols.py:1312 -#, fuzzy -msgctxt "math symbol" -msgid "right double arrow" -msgstr "雙精度" - -#: src/cthulhu/mathsymbols.py:1315 -#, fuzzy -msgctxt "math symbol" -msgid "down double arrow" -msgstr "Down" - -#: src/cthulhu/mathsymbols.py:1318 -#, fuzzy -msgctxt "math symbol" -msgid "left right double arrow" -msgstr "左至右" - -#: src/cthulhu/mathsymbols.py:1321 -#, fuzzy -msgctxt "math symbol" -msgid "up down double arrow" -msgstr "提高或降低音量" - -#: src/cthulhu/mathsymbols.py:1324 -msgctxt "math symbol" -msgid "north west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1327 -msgctxt "math symbol" -msgid "north east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1330 -msgctxt "math symbol" -msgid "south east double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1333 -msgctxt "math symbol" -msgid "south west double arrow" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1336 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrow" -msgstr "指向" - -#: src/cthulhu/mathsymbols.py:1339 -#, fuzzy -msgctxt "math symbol" -msgid "right-pointing arrowhead" -msgstr "指向" - -#: src/cthulhu/mathsymbols.py:1343 src/cthulhu/mathsymbols.py:1431 -#, fuzzy -msgctxt "math symbol" -msgid "minus" -msgstr "減號" - -#: src/cthulhu/mathsymbols.py:1347 -#, fuzzy -msgctxt "math symbol" -msgid "less than" -msgstr "" -"表示對紅色元件預設亮度的改變。0 表示不改變,小於 0 的數值表示減少,大於 0 的" -"數值表示增加。" - -#: src/cthulhu/mathsymbols.py:1351 -#, fuzzy -msgctxt "math symbol" -msgid "greater than" -msgstr "允許初始時縮放比例大於 100%" - -#: src/cthulhu/mathsymbols.py:1355 -#, fuzzy -msgctxt "math symbol" -msgid "circumflex" -msgstr "circumflex" - -#: src/cthulhu/mathsymbols.py:1359 -msgctxt "math symbol" -msgid "háček" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1363 -msgctxt "math symbol" -msgid "breve" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1367 -#, fuzzy -msgctxt "math symbol" -msgid "dot" -msgstr "點" - -#: src/cthulhu/mathsymbols.py:1371 -#, fuzzy -msgctxt "math symbol" -msgid "double vertical line" -msgstr "雙精度" - -#: src/cthulhu/mathsymbols.py:1374 -#, fuzzy -msgctxt "math symbol" -msgid "horizontal ellipsis" -msgstr "水平" - -#: src/cthulhu/mathsymbols.py:1377 -#, fuzzy -msgctxt "math symbol" -msgid "for all" -msgstr "全部" - -#: src/cthulhu/mathsymbols.py:1380 -#, fuzzy -msgctxt "math symbol" -msgid "complement" -msgstr "1 的補數" - -#: src/cthulhu/mathsymbols.py:1383 -#, fuzzy -msgctxt "math symbol" -msgid "partial differential" -msgstr "在字元未完整之前,輸入管道已經結束" - -#: src/cthulhu/mathsymbols.py:1386 -#, fuzzy -msgctxt "math symbol" -msgid "there exists" -msgstr "檔案已存在" - -#: src/cthulhu/mathsymbols.py:1389 -#, fuzzy -msgctxt "math symbol" -msgid "there does not exist" -msgstr "行事曆不存在" - -#: src/cthulhu/mathsymbols.py:1392 -#, fuzzy -msgctxt "math symbol" -msgid "empty set" -msgstr "沒電" - -#: src/cthulhu/mathsymbols.py:1395 -#, fuzzy -msgctxt "math symbol" -msgid "increment" -msgstr "逐步增加" - -#: src/cthulhu/mathsymbols.py:1398 -#, fuzzy -msgctxt "math symbol" -msgid "nabla" -msgstr "已啟用" - -#: src/cthulhu/mathsymbols.py:1401 -#, fuzzy -msgctxt "math symbol" -msgid "element of" -msgstr "元素 <%s> 不允許在頂端層級" - -#: src/cthulhu/mathsymbols.py:1404 -#, fuzzy -msgctxt "math symbol" -msgid "not an element of" -msgstr "元素 <%s> 不允許在頂端層級" - -#: src/cthulhu/mathsymbols.py:1407 -#, fuzzy -msgctxt "math symbol" -msgid "small element of" -msgstr "您的帳號" - -#: src/cthulhu/mathsymbols.py:1410 -#, fuzzy -msgctxt "math symbol" -msgid "contains as a member" -msgstr "主機名稱「%s」含有「[」但沒有「]」" - -#: src/cthulhu/mathsymbols.py:1413 -#, fuzzy -msgctxt "math symbol" -msgid "does not contain as a member" -msgstr "不包含" - -#: src/cthulhu/mathsymbols.py:1416 -#, fuzzy -msgctxt "math symbol" -msgid "small contains as a member" -msgstr "您的帳號" - -#: src/cthulhu/mathsymbols.py:1419 -#, fuzzy -msgctxt "math symbol" -msgid "end of proof" -msgstr "結束(_E)" - -#: src/cthulhu/mathsymbols.py:1422 -#, fuzzy -msgctxt "math symbol" -msgid "product" -msgstr "產品 ID" - -#: src/cthulhu/mathsymbols.py:1425 -#, fuzzy -msgctxt "math symbol" -msgid "coproduct" -msgstr "N/A" - -#: src/cthulhu/mathsymbols.py:1428 -#, fuzzy -msgctxt "math symbol" -msgid "sum" -msgstr "下標" - -#: src/cthulhu/mathsymbols.py:1434 -#, fuzzy -msgctxt "math symbol" -msgid "minus or plus" -msgstr "美制 Letter Plus" - -#: src/cthulhu/mathsymbols.py:1437 -#, fuzzy -msgctxt "math symbol" -msgid "dot plus" -msgstr "b-plus" - -#: src/cthulhu/mathsymbols.py:1440 -#, fuzzy -msgctxt "math symbol" -msgid "division slash" -msgstr "路徑不能以斜線 (/) 結尾" - -#: src/cthulhu/mathsymbols.py:1443 -#, fuzzy -msgctxt "math symbol" -msgid "set minus" -msgstr "設定" - -#: src/cthulhu/mathsymbols.py:1446 -#, fuzzy -msgctxt "math symbol" -msgid "asterisk operator" -msgstr "運算符號" - -#: src/cthulhu/mathsymbols.py:1449 -#, fuzzy -msgctxt "math symbol" -msgid "ring operator" -msgstr "左手無名指" - -#: src/cthulhu/mathsymbols.py:1452 -#, fuzzy -msgctxt "math symbol" -msgid "bullet operator" -msgstr "運算符號" - -#: src/cthulhu/mathsymbols.py:1455 -#, fuzzy -msgctxt "math symbol" -msgid "square root" -msgstr "根檔案系統" - -#: src/cthulhu/mathsymbols.py:1458 -#, fuzzy -msgctxt "math symbol" -msgid "cube root" -msgstr "檔案系統根" - -#: src/cthulhu/mathsymbols.py:1461 -#, fuzzy -msgctxt "math symbol" -msgid "fourth root" -msgstr "根檔案系統" - -#: src/cthulhu/mathsymbols.py:1464 -#, fuzzy -msgctxt "math symbol" -msgid "proportional to" -msgstr "" -"決定鍵盤瀏覽在放大檢視中的位置。數值有:\n" -"\n" -"• none:不追蹤鍵盤瀏覽\n" -"\n" -"• centered:鍵盤瀏覽顯示在放大區域的中央 (也表示了系統鍵盤瀏覽下的點) 而放大" -"的內容會隨著系統鍵盤瀏覽移動而捲動\n" -"\n" -"• proportional:放大的鍵盤瀏覽在縮放區域中正如同系統鍵盤瀏覽在畫面中的對應位" -"置\n" -"\n" -"• push:當放大的鍵盤瀏覽接觸到縮放區域的邊緣時,內容就會隨著捲動到檢視中" - -#: src/cthulhu/mathsymbols.py:1467 -#, fuzzy -msgctxt "math symbol" -msgid "infinity" -msgstr "無限大" - -#: src/cthulhu/mathsymbols.py:1470 -#, fuzzy -msgctxt "math symbol" -msgid "right angle" -msgstr "角" - -#: src/cthulhu/mathsymbols.py:1473 -#, fuzzy -msgctxt "math symbol" -msgid "angle" -msgstr "角" - -#: src/cthulhu/mathsymbols.py:1476 -#, fuzzy -msgctxt "math symbol" -msgid "measured angle" -msgstr "角" - -#: src/cthulhu/mathsymbols.py:1479 -#, fuzzy -msgctxt "math symbol" -msgid "spherical angle" -msgstr "角" - -#: src/cthulhu/mathsymbols.py:1482 -#, fuzzy -msgctxt "math symbol" -msgid "divides" -msgstr "" -"計算一期間內資產的直線折舊。直線折舊法在資產可用年限內將折舊花費平均分攤。可" -"用年限指資產折舊的期數,典型狀況下為年。" - -#: src/cthulhu/mathsymbols.py:1485 -#, fuzzy -msgctxt "math symbol" -msgid "does not divide" -msgstr "除號 [/]" - -#: src/cthulhu/mathsymbols.py:1488 -#, fuzzy -msgctxt "math symbol" -msgid "parallel to" -msgstr "串列埠" - -#: src/cthulhu/mathsymbols.py:1491 -#, fuzzy -msgctxt "math symbol" -msgid "not parallel to" -msgstr "串列埠" - -#: src/cthulhu/mathsymbols.py:1494 src/cthulhu/mathsymbols.py:1953 -#, fuzzy -msgctxt "math symbol" -msgid "logical and" -msgstr "當選擇排序時這個欄位用來排序的邏輯排序欄位 ID" - -#: src/cthulhu/mathsymbols.py:1497 src/cthulhu/mathsymbols.py:1956 -#, fuzzy -msgctxt "math symbol" -msgid "logical or" -msgstr "當選擇排序時這個欄位用來排序的邏輯排序欄位 ID" - -#: src/cthulhu/mathsymbols.py:1500 src/cthulhu/mathsymbols.py:1959 -#, fuzzy -msgctxt "math symbol" -msgid "intersection" -msgstr "文字走向" - -#: src/cthulhu/mathsymbols.py:1503 src/cthulhu/mathsymbols.py:1962 -#, fuzzy -msgctxt "math symbol" -msgid "union" -msgstr "Union Square" - -#: src/cthulhu/mathsymbols.py:1506 -msgctxt "math symbol" -msgid "integral" -msgstr "integral" - -#: src/cthulhu/mathsymbols.py:1509 -#, fuzzy -msgctxt "math symbol" -msgid "double integral" -msgstr "雙精度" - -#: src/cthulhu/mathsymbols.py:1512 -#, fuzzy -msgctxt "math symbol" -msgid "triple integral" -msgstr "Triple Peaks" - -#: src/cthulhu/mathsymbols.py:1515 -msgctxt "math symbol" -msgid "contour integral" -msgstr "contour integral" - -#: src/cthulhu/mathsymbols.py:1518 -#, fuzzy -msgctxt "math symbol" -msgid "surface integral" -msgstr "表面" - -#: src/cthulhu/mathsymbols.py:1521 -#, fuzzy -msgctxt "math symbol" -msgid "volume integral" -msgstr "音量" - -#: src/cthulhu/mathsymbols.py:1524 -#, fuzzy -msgctxt "math symbol" -msgid "clockwise integral" -msgstr "順時針方向旋轉(_R)" - -#: src/cthulhu/mathsymbols.py:1527 -#, fuzzy -msgctxt "math symbol" -msgid "clockwise contour integral" -msgstr "順時針旋轉 90°" - -#: src/cthulhu/mathsymbols.py:1530 -msgctxt "math symbol" -msgid "anticlockwise contour integral" -msgstr "anticlockwise contour integral" - -#: src/cthulhu/mathsymbols.py:1533 -#, fuzzy -msgctxt "math symbol" -msgid "therefore" -msgstr "這個檔案是影片檔,因此只有音訊的部分可以寫入碟片。" - -#: src/cthulhu/mathsymbols.py:1536 -#, fuzzy -msgctxt "math symbol" -msgid "because" -msgstr "由於沒有網路存取,某些服務已停用。" - -#: src/cthulhu/mathsymbols.py:1539 -#, fuzzy -msgctxt "math symbol" -msgid "ratio" -msgstr "比率" - -#: src/cthulhu/mathsymbols.py:1542 -msgctxt "math symbol" -msgid "proportion" -msgstr "proportion" - -#: src/cthulhu/mathsymbols.py:1545 -#, fuzzy -msgctxt "math symbol" -msgid "dot minus" -msgstr "點" - -#: src/cthulhu/mathsymbols.py:1548 -#, fuzzy -msgctxt "math symbol" -msgid "excess" -msgstr "" -"定義指派給工作區的名稱。如果列表比目前的工作區數量多,超過的名稱會被忽略。如" -"果列表太短,或是包含空白名稱,缺少的數值會以預設值取代 (\"工作區 N\")。" - -#: src/cthulhu/mathsymbols.py:1551 -#, fuzzy -msgctxt "math symbol" -msgid "geometric proportion" -msgstr "幾何形狀" - -#: src/cthulhu/mathsymbols.py:1554 -msgctxt "math symbol" -msgid "homothetic" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1557 -#, fuzzy -msgctxt "math symbol" -msgid "tilde" -msgstr "波紋號" - -#: src/cthulhu/mathsymbols.py:1560 -#, fuzzy -msgctxt "math symbol" -msgid "reversed tilde" -msgstr "A TILDE" - -#: src/cthulhu/mathsymbols.py:1563 -#, fuzzy -msgctxt "math symbol" -msgid "inverted lazy S" -msgstr "反轉的" - -#: src/cthulhu/mathsymbols.py:1566 -#, fuzzy -msgctxt "math symbol" -msgid "sine wave" -msgstr "正弦" - -#: src/cthulhu/mathsymbols.py:1569 -#, fuzzy -msgctxt "math symbol" -msgid "wreath product" -msgstr "產品 ID" - -#: src/cthulhu/mathsymbols.py:1572 -#, fuzzy -msgctxt "math symbol" -msgid "not tilde" -msgstr "A TILDE" - -#: src/cthulhu/mathsymbols.py:1575 -#, fuzzy -msgctxt "math symbol" -msgid "minus tilde" -msgstr "波紋號" - -#: src/cthulhu/mathsymbols.py:1578 -#, fuzzy -msgctxt "math symbol" -msgid "asymptotically equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1581 -#, fuzzy -msgctxt "math symbol" -msgid "not asymptotically equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1584 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1587 -#, fuzzy -msgctxt "math symbol" -msgid "approximately but not actually equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1590 -msgctxt "math symbol" -msgid "neither approximately nor actually equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1593 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal to" -msgstr "廢墨收集器將滿" - -#: src/cthulhu/mathsymbols.py:1596 -#, fuzzy -msgctxt "math symbol" -msgid "not almost equal to" -msgstr "廢墨收集器將滿" - -#: src/cthulhu/mathsymbols.py:1599 -#, fuzzy -msgctxt "math symbol" -msgid "almost equal or equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1602 -#, fuzzy -msgctxt "math symbol" -msgid "triple tilde" -msgstr "A TILDE" - -#: src/cthulhu/mathsymbols.py:1605 -#, fuzzy -msgctxt "math symbol" -msgid "all equal to" -msgstr "全部" - -#: src/cthulhu/mathsymbols.py:1608 -#, fuzzy -msgctxt "math symbol" -msgid "equivalent to" -msgstr "" -"用來顯示天氣壓力的單位 (例如風速)。有效的數值為「kpa」(kilopascal)、「hpa」" -"(百帕)、「mb」(毫巴,數學上相檔於 1 百帕,但顯示方式不同)、「mm-hg」(毫米-汞" -"柱)、「inch-hg」(英吋-汞柱)和「atm」(氣壓)。" - -#: src/cthulhu/mathsymbols.py:1611 -msgctxt "math symbol" -msgid "geometrically equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1614 -#, fuzzy -msgctxt "math symbol" -msgid "difference between" -msgstr "兩張影像之間的時間(_T):" - -#: src/cthulhu/mathsymbols.py:1617 -#, fuzzy -msgctxt "math symbol" -msgid "approaches the limit" -msgstr "限制" - -#: src/cthulhu/mathsymbols.py:1620 -#, fuzzy -msgctxt "math symbol" -msgid "geometrically equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1623 -#, fuzzy -msgctxt "math symbol" -msgid "approximately equal to or the image of" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1626 -#, fuzzy -msgctxt "math symbol" -msgid "image of or approximately equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1629 -#, fuzzy -msgctxt "math symbol" -msgid "colon equals" -msgstr "冒號" - -#: src/cthulhu/mathsymbols.py:1632 -#, fuzzy -msgctxt "math symbol" -msgid "equals colon" -msgstr "冒號" - -#: src/cthulhu/mathsymbols.py:1635 -#, fuzzy -msgctxt "math symbol" -msgid "ring in equal to" -msgstr "左手無名指" - -#: src/cthulhu/mathsymbols.py:1638 -#, fuzzy -msgctxt "math symbol" -msgid "ring equal to" -msgstr "左手無名指" - -#: src/cthulhu/mathsymbols.py:1641 -#, fuzzy -msgctxt "math symbol" -msgid "corresponds to" -msgstr "" -"注意: 程序是否優先執行可由它的 nice 值得出。較低的 nice 值" -"表示較優先執行。" - -#: src/cthulhu/mathsymbols.py:1644 -msgctxt "math symbol" -msgid "estimates" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1647 -#, fuzzy -msgctxt "math symbol" -msgid "equiangular to" -msgstr "三角項目符號" - -#: src/cthulhu/mathsymbols.py:1650 -#, fuzzy -msgctxt "math symbol" -msgid "star equals" -msgstr "等於" - -#: src/cthulhu/mathsymbols.py:1653 -#, fuzzy -msgctxt "math symbol" -msgid "delta equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1656 -#, fuzzy -msgctxt "math symbol" -msgid "equal to by definition" -msgstr "上一個字詞解釋(_P)" - -#: src/cthulhu/mathsymbols.py:1659 -#, fuzzy -msgctxt "math symbol" -msgid "measured by" -msgstr "在上下文中能被測量的距離單位" - -#: src/cthulhu/mathsymbols.py:1662 -#, fuzzy -msgctxt "math symbol" -msgid "questioned equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1665 -#, fuzzy -msgctxt "math symbol" -msgid "not equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1668 -#, fuzzy -msgctxt "math symbol" -msgid "identical to" -msgstr "垂直的" - -#: src/cthulhu/mathsymbols.py:1671 -#, fuzzy -msgctxt "math symbol" -msgid "not identical to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1674 -msgctxt "math symbol" -msgid "strictly equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1677 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1680 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equal to" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:1683 -#, fuzzy -msgctxt "math symbol" -msgid "less than over equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1686 -#, fuzzy -msgctxt "math symbol" -msgid "greater than over equal to" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:1689 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1692 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equal to" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:1695 -#, fuzzy -msgctxt "math symbol" -msgid "much less than" -msgstr "小於" - -#: src/cthulhu/mathsymbols.py:1698 -#, fuzzy -msgctxt "math symbol" -msgid "much greater than" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:1701 -#, fuzzy -msgctxt "math symbol" -msgid "between" -msgstr "資源圖表每次更新的時間,以毫秒表示" - -#: src/cthulhu/mathsymbols.py:1704 -#, fuzzy -msgctxt "math symbol" -msgid "not equivalent to" -msgstr "" -"用來顯示天氣壓力的單位 (例如風速)。有效的數值為「kpa」(kilopascal)、「hpa」" -"(百帕)、「mb」(毫巴,數學上相檔於 1 百帕,但顯示方式不同)、「mm-hg」(毫米-汞" -"柱)、「inch-hg」(英吋-汞柱)和「atm」(氣壓)。" - -#: src/cthulhu/mathsymbols.py:1707 -#, fuzzy -msgctxt "math symbol" -msgid "not less than" -msgstr "" -"表示對紅色元件預設亮度的改變。0 表示不改變,小於 0 的數值表示減少,大於 0 的" -"數值表示增加。" - -#: src/cthulhu/mathsymbols.py:1710 -#, fuzzy -msgctxt "math symbol" -msgid "not greater than" -msgstr "允許初始時縮放比例大於 100%" - -#: src/cthulhu/mathsymbols.py:1713 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equal to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1716 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1719 -#, fuzzy -msgctxt "math symbol" -msgid "less than or equivalent to" -msgstr "傳回小於" - -#: src/cthulhu/mathsymbols.py:1722 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or equivalent to" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:1725 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor equivalent to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1728 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor equivalent to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1731 -#, fuzzy -msgctxt "math symbol" -msgid "less than or greater than" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:1734 -#, fuzzy -msgctxt "math symbol" -msgid "greater than or less than" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:1737 -#, fuzzy -msgctxt "math symbol" -msgid "neither less than nor greater than" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1740 -#, fuzzy -msgctxt "math symbol" -msgid "neither greater than nor less than" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1743 -msgctxt "math symbol" -msgid "precedes" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1746 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds" -msgstr "" -"當連至可使用 IPv6 的網路時,若 IPv4 配置失敗,不過 IPv6 配置卻成功的話,請允" -"許連線完成。" - -#: src/cthulhu/mathsymbols.py:1749 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1752 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1755 -#, fuzzy -msgctxt "math symbol" -msgid "precedes or equivalent to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1758 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds or equivalent to" -msgstr "小於等於" - -#: src/cthulhu/mathsymbols.py:1761 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede" -msgstr "不接受工作" - -#: src/cthulhu/mathsymbols.py:1764 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed" -msgstr "不接受工作" - -#: src/cthulhu/mathsymbols.py:1767 -#, fuzzy -msgctxt "math symbol" -msgid "subset of" -msgstr "嵌入字體" - -#: src/cthulhu/mathsymbols.py:1770 -#, fuzzy -msgctxt "math symbol" -msgid "superset of" -msgstr "superscript a" - -#: src/cthulhu/mathsymbols.py:1773 -#, fuzzy -msgctxt "math symbol" -msgid "not a subset of" -msgstr "嵌入字體" - -#: src/cthulhu/mathsymbols.py:1776 -msgctxt "math symbol" -msgid "not a superset of" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1779 -#, fuzzy -msgctxt "math symbol" -msgid "subset of or equal to" -msgstr "嵌入字體" - -#: src/cthulhu/mathsymbols.py:1782 -#, fuzzy -msgctxt "math symbol" -msgid "superset of or equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1785 -#, fuzzy -msgctxt "math symbol" -msgid "neither a subset of nor equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1788 -#, fuzzy -msgctxt "math symbol" -msgid "neither a superset of nor equal to" -msgstr "大於等於" - -#: src/cthulhu/mathsymbols.py:1791 -#, fuzzy -msgctxt "math symbol" -msgid "subset of with not equal to" -msgstr "嵌入字體" - -#: src/cthulhu/mathsymbols.py:1794 -#, fuzzy -msgctxt "math symbol" -msgid "superset of with not equal to" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:1797 -#, fuzzy -msgctxt "math symbol" -msgid "multiset" -msgstr "多重選取" - -#: src/cthulhu/mathsymbols.py:1800 -#, fuzzy -msgctxt "math symbol" -msgid "multiset multiplication" -msgstr "對齊" - -#: src/cthulhu/mathsymbols.py:1803 -#, fuzzy -msgctxt "math symbol" -msgid "multiset union" -msgstr "Union Square" - -#: src/cthulhu/mathsymbols.py:1806 -#, fuzzy -msgctxt "math symbol" -msgid "square image of" -msgstr "影像" - -#: src/cthulhu/mathsymbols.py:1809 -#, fuzzy -msgctxt "math symbol" -msgid "square original of" -msgstr "原始影像" - -#: src/cthulhu/mathsymbols.py:1812 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1815 -#, fuzzy -msgctxt "math symbol" -msgid "square original of or equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1818 -#, fuzzy -msgctxt "math symbol" -msgid "square cap" -msgstr "卡普夏" - -#: src/cthulhu/mathsymbols.py:1821 -#, fuzzy -msgctxt "math symbol" -msgid "square cup" -msgstr "正方形" - -#: src/cthulhu/mathsymbols.py:1824 src/cthulhu/mathsymbols.py:2175 -#, fuzzy -msgctxt "math symbol" -msgid "circled plus" -msgstr "美制 Letter Plus" - -#: src/cthulhu/mathsymbols.py:1827 -#, fuzzy -msgctxt "math symbol" -msgid "circled minus" -msgstr "減號" - -#: src/cthulhu/mathsymbols.py:1830 src/cthulhu/mathsymbols.py:2178 -#, fuzzy -msgctxt "math symbol" -msgid "circled times" -msgstr "時刻" - -#: src/cthulhu/mathsymbols.py:1833 -#, fuzzy -msgctxt "math symbol" -msgid "circled division slash" -msgstr "路徑不能以斜線 (/) 結尾" - -#: src/cthulhu/mathsymbols.py:1836 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot operator" -msgstr "運算符號" - -#: src/cthulhu/mathsymbols.py:1839 -#, fuzzy -msgctxt "math symbol" -msgid "circled ring operator" -msgstr "左手無名指" - -#: src/cthulhu/mathsymbols.py:1842 -#, fuzzy -msgctxt "math symbol" -msgid "circled asterisk operator" -msgstr "運算符號" - -#: src/cthulhu/mathsymbols.py:1845 -#, fuzzy -msgctxt "math symbol" -msgid "circled equals" -msgstr "等於" - -#: src/cthulhu/mathsymbols.py:1848 -#, fuzzy -msgctxt "math symbol" -msgid "circled dash" -msgstr "破折號" - -#: src/cthulhu/mathsymbols.py:1851 -#, fuzzy -msgctxt "math symbol" -msgid "squared plus" -msgstr "美制 Letter Plus" - -#: src/cthulhu/mathsymbols.py:1854 -#, fuzzy -msgctxt "math symbol" -msgid "squared minus" -msgstr "減號" - -#: src/cthulhu/mathsymbols.py:1857 -#, fuzzy -msgctxt "math symbol" -msgid "squared times" -msgstr "時刻" - -#: src/cthulhu/mathsymbols.py:1860 -#, fuzzy -msgctxt "math symbol" -msgid "squared dot operator" -msgstr "運算符號" - -#: src/cthulhu/mathsymbols.py:1863 -#, fuzzy -msgctxt "math symbol" -msgid "right tack" -msgstr "右(_R):" - -#: src/cthulhu/mathsymbols.py:1866 -#, fuzzy -msgctxt "math symbol" -msgid "left tack" -msgstr "左(_L):" - -#: src/cthulhu/mathsymbols.py:1869 -#, fuzzy -msgctxt "math symbol" -msgid "down tack" -msgstr "向下(_D)" - -#: src/cthulhu/mathsymbols.py:1872 -#, fuzzy -msgctxt "math symbol" -msgid "up tack" -msgstr "向上(_U)" - -#: src/cthulhu/mathsymbols.py:1875 -#, fuzzy -msgctxt "math symbol" -msgid "assertion" -msgstr "(?( 後應該有判斷提示(assertion)" - -#: src/cthulhu/mathsymbols.py:1878 -msgctxt "math symbol" -msgid "models" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1881 -#, fuzzy -msgctxt "math symbol" -msgid "true" -msgstr "真 (true)" - -#: src/cthulhu/mathsymbols.py:1884 -#, fuzzy -msgctxt "math symbol" -msgid "forces" -msgstr "" -"檢查檔案系統與資料庫是否同步的間隔天數。0 表示任何時刻都進行索引,-1 表示只在" -"未成功關機時進行,而 -2 則會完全停用它。" - -#: src/cthulhu/mathsymbols.py:1887 -msgctxt "math symbol" -msgid "triple vertical bar right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1890 -msgctxt "math symbol" -msgid "double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1893 -#, fuzzy -msgctxt "math symbol" -msgid "does not prove" -msgstr "不接受工作" - -#: src/cthulhu/mathsymbols.py:1896 -#, fuzzy -msgctxt "math symbol" -msgid "not true" -msgstr "真 (True)" - -#: src/cthulhu/mathsymbols.py:1899 -#, fuzzy -msgctxt "math symbol" -msgid "does not force" -msgstr "蒲福氏風級 %.1f" - -#: src/cthulhu/mathsymbols.py:1902 -msgctxt "math symbol" -msgid "negated double vertical bar double right turnstile" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1905 -#, fuzzy -msgctxt "math symbol" -msgid "precedes under relation" -msgstr "歸檔為" - -#: src/cthulhu/mathsymbols.py:1908 -#, fuzzy -msgctxt "math symbol" -msgid "succeeds under relation" -msgstr "歸檔為" - -#: src/cthulhu/mathsymbols.py:1911 -#, fuzzy -msgctxt "math symbol" -msgid "normal subgroup of" -msgstr "一般" - -#: src/cthulhu/mathsymbols.py:1914 -#, fuzzy -msgctxt "math symbol" -msgid "contains as normal subgroup" -msgstr "一般" - -#: src/cthulhu/mathsymbols.py:1917 -#, fuzzy -msgctxt "math symbol" -msgid "normal subgroup of or equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:1920 -msgctxt "math symbol" -msgid "contains as normal subgroup of or equal to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1923 -#, fuzzy -msgctxt "math symbol" -msgid "original of" -msgstr "%f: 原始檔案名稱" - -#: src/cthulhu/mathsymbols.py:1926 -#, fuzzy -msgctxt "math symbol" -msgid "image of" -msgstr "影像" - -#: src/cthulhu/mathsymbols.py:1929 -#, fuzzy -msgctxt "math symbol" -msgid "multimap" -msgstr "multi" - -#: src/cthulhu/mathsymbols.py:1932 -#, fuzzy -msgctxt "math symbol" -msgid "hermitian conjugate matrix" -msgstr "轉換矩陣" - -#: src/cthulhu/mathsymbols.py:1935 -msgctxt "math symbol" -msgid "intercalate" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1938 -#, fuzzy -msgctxt "math symbol" -msgid "xor" -msgstr "XOR" - -#: src/cthulhu/mathsymbols.py:1941 -#, fuzzy -msgctxt "math symbol" -msgid "nand" -msgstr "" -"將資源規格編譯進資源檔。\n" -"資源規格檔案的延伸檔名必須為 .gresource.xml,\n" -"而資源檔案的延伸檔名叫做 .gresource。" - -#: src/cthulhu/mathsymbols.py:1944 -#, fuzzy -msgctxt "math symbol" -msgid "nor" -msgstr "<%s> 元素缺少了「name」或「id」元素" - -#: src/cthulhu/mathsymbols.py:1947 -#, fuzzy -msgctxt "math symbol" -msgid "right angle with arc" -msgstr "角" - -#: src/cthulhu/mathsymbols.py:1950 -#, fuzzy -msgctxt "math symbol" -msgid "right triangle" -msgstr "右(_R):" - -#: src/cthulhu/mathsymbols.py:1965 -#, fuzzy -msgctxt "math symbol" -msgid "diamond operator" -msgstr "Diamond Mine" - -#: src/cthulhu/mathsymbols.py:1968 -#, fuzzy -msgctxt "math symbol" -msgid "dot operator" -msgstr "運算符號" - -#: src/cthulhu/mathsymbols.py:1971 -#, fuzzy -msgctxt "math symbol" -msgid "star operator" -msgstr "運算符號" - -#: src/cthulhu/mathsymbols.py:1974 -#, fuzzy -msgctxt "math symbol" -msgid "division times" -msgstr "時刻" - -#: src/cthulhu/mathsymbols.py:1977 -msgctxt "math symbol" -msgid "bowtie" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1980 -msgctxt "math symbol" -msgid "left normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1983 -msgctxt "math symbol" -msgid "right normal factor semidirect product" -msgstr "" - -#: src/cthulhu/mathsymbols.py:1986 -#, fuzzy -msgctxt "math symbol" -msgid "left semidirect product" -msgstr "產品 ID" - -#: src/cthulhu/mathsymbols.py:1989 -#, fuzzy -msgctxt "math symbol" -msgid "right semidirect product" -msgstr "產品 ID" - -#: src/cthulhu/mathsymbols.py:1992 -#, fuzzy -msgctxt "math symbol" -msgid "reversed tilde equals" -msgstr "等於" - -#: src/cthulhu/mathsymbols.py:1995 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical or" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:1998 -#, fuzzy -msgctxt "math symbol" -msgid "curly logical and" -msgstr "logical not" - -#: src/cthulhu/mathsymbols.py:2001 -#, fuzzy -msgctxt "math symbol" -msgid "double subset" -msgstr "嵌入字體" - -#: src/cthulhu/mathsymbols.py:2004 -#, fuzzy -msgctxt "math symbol" -msgid "double superset" -msgstr "雙精度" - -#: src/cthulhu/mathsymbols.py:2007 -#, fuzzy -msgctxt "math symbol" -msgid "double intersection" -msgstr "雙精度" - -#: src/cthulhu/mathsymbols.py:2010 -#, fuzzy -msgctxt "math symbol" -msgid "double union" -msgstr "雙精度" - -#: src/cthulhu/mathsymbols.py:2013 -msgctxt "math symbol" -msgid "pitchfork" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2016 -#, fuzzy -msgctxt "math symbol" -msgid "equal and parallel to" -msgstr "串列埠" - -#: src/cthulhu/mathsymbols.py:2019 -#, fuzzy -msgctxt "math symbol" -msgid "less than with dot" -msgstr "傳回小於" - -#: src/cthulhu/mathsymbols.py:2022 -#, fuzzy -msgctxt "math symbol" -msgid "greater than with dot" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:2025 -#, fuzzy -msgctxt "math symbol" -msgid "very much less than" -msgstr "傳回小於" - -#: src/cthulhu/mathsymbols.py:2028 -#, fuzzy -msgctxt "math symbol" -msgid "very much greater than" -msgstr "允許初始時縮放比例大於 100%" - -#: src/cthulhu/mathsymbols.py:2031 -#, fuzzy -msgctxt "math symbol" -msgid "less than equal to or greater than" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:2034 -#, fuzzy -msgctxt "math symbol" -msgid "greater than equal to or less than" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:2037 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or less than" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:2040 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or greater than" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:2043 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or precedes" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:2046 -#, fuzzy -msgctxt "math symbol" -msgid "equal to or succeeds" -msgstr "不等於" - -#: src/cthulhu/mathsymbols.py:2049 -#, fuzzy -msgctxt "math symbol" -msgid "does not precede or equal" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:2052 -#, fuzzy -msgctxt "math symbol" -msgid "does not succeed or equal" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:2055 -#, fuzzy -msgctxt "math symbol" -msgid "not square image of or equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:2058 -#, fuzzy -msgctxt "math symbol" -msgid "not square original of or equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:2061 -#, fuzzy -msgctxt "math symbol" -msgid "square image of or not equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:2064 -#, fuzzy -msgctxt "math symbol" -msgid "square original of or not equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:2067 -#, fuzzy -msgctxt "math symbol" -msgid "less than but not equivalent to" -msgstr "傳回小於" - -#: src/cthulhu/mathsymbols.py:2070 -#, fuzzy -msgctxt "math symbol" -msgid "greater than but not equivalent to" -msgstr "8 進位值大於 \\377" - -#: src/cthulhu/mathsymbols.py:2073 -msgctxt "math symbol" -msgid "precedes but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2076 -msgctxt "math symbol" -msgid "succeeds but not equivalent to" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2079 -#, fuzzy -msgctxt "math symbol" -msgid "not normal subgroup of" -msgstr "一般" - -#: src/cthulhu/mathsymbols.py:2082 -#, fuzzy -msgctxt "math symbol" -msgid "does not contain as normal subgroup" -msgstr "裝置 %s 中不包含音樂檔案" - -#: src/cthulhu/mathsymbols.py:2085 -#, fuzzy -msgctxt "math symbol" -msgid "not normal subgroup of or equal to" -msgstr "最少有兩個檔案的名稱相同。" - -#: src/cthulhu/mathsymbols.py:2088 -msgctxt "math symbol" -msgid "does not contain as normal subgroup or equal" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2091 -#, fuzzy -msgctxt "math symbol" -msgid "vertical ellipsis" -msgstr "垂直" - -#: src/cthulhu/mathsymbols.py:2094 -#, fuzzy -msgctxt "math symbol" -msgid "midline horizontal ellipsis" -msgstr "水平" - -#: src/cthulhu/mathsymbols.py:2097 -msgctxt "math symbol" -msgid "up right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2100 -msgctxt "math symbol" -msgid "down right diagonal ellipsis" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2103 -msgctxt "math symbol" -msgid "element of with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2107 -msgctxt "math symbol" -msgid "element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2111 -msgctxt "math symbol" -msgid "small element of with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2114 -#, fuzzy -msgctxt "math symbol" -msgid "element of with dot above" -msgstr "段落頂端空間" - -#: src/cthulhu/mathsymbols.py:2117 -#, fuzzy -msgctxt "math symbol" -msgid "element of with overbar" -msgstr "元素 <%s> 不允許在頂端層級" - -#: src/cthulhu/mathsymbols.py:2120 -#, fuzzy -msgctxt "math symbol" -msgid "small element of with overbar" -msgstr "您的帳號" - -#: src/cthulhu/mathsymbols.py:2123 -#, fuzzy -msgctxt "math symbol" -msgid "element of with underbar" -msgstr "元素 <%s> 不允許在頂端層級" - -#: src/cthulhu/mathsymbols.py:2126 -#, fuzzy -msgctxt "math symbol" -msgid "element of with two horizontal strokes" -msgstr "兩個子元件之間的水平間距" - -#: src/cthulhu/mathsymbols.py:2129 -msgctxt "math symbol" -msgid "contains with long horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2132 -msgctxt "math symbol" -msgid "contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2136 -msgctxt "math symbol" -msgid "small contains with vertical bar at end of horizontal stroke" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2139 -#, fuzzy -msgctxt "math symbol" -msgid "contains with overbar" -msgstr "此文件不包含任何頁面" - -#: src/cthulhu/mathsymbols.py:2142 -#, fuzzy -msgctxt "math symbol" -msgid "small contains with overbar" -msgstr "您的帳號" - -#: src/cthulhu/mathsymbols.py:2145 -msgctxt "math symbol" -msgid "z notation bag membership" -msgstr "" - -#: src/cthulhu/mathsymbols.py:2148 -#, fuzzy -msgctxt "math symbol" -msgid "left ceiling" -msgstr "左(_L):" - -#: src/cthulhu/mathsymbols.py:2151 -#, fuzzy -msgctxt "math symbol" -msgid "right ceiling" -msgstr "右(_R):" - -#: src/cthulhu/mathsymbols.py:2154 -#, fuzzy -msgctxt "math symbol" -msgid "left floor" -msgstr "左(_L):" - -#: src/cthulhu/mathsymbols.py:2157 -#, fuzzy -msgctxt "math symbol" -msgid "right floor" -msgstr "右(_R):" - -#: src/cthulhu/mathsymbols.py:2160 -#, fuzzy -msgctxt "math symbol" -msgid "top brace" -msgstr "上(_T):" - -#: src/cthulhu/mathsymbols.py:2163 -#, fuzzy -msgctxt "math symbol" -msgid "bottom brace" -msgstr "下(_B):" - -#: src/cthulhu/mathsymbols.py:2166 -#, fuzzy -msgctxt "math symbol" -msgid "left angle bracket" -msgstr "角" - -#: src/cthulhu/mathsymbols.py:2169 -#, fuzzy -msgctxt "math symbol" -msgid "right angle bracket" -msgstr "角" - -#: src/cthulhu/mathsymbols.py:2172 -#, fuzzy -msgctxt "math symbol" -msgid "circled dot" -msgstr "破折號" - -#: src/cthulhu/mathsymbols.py:2180 -#, fuzzy -msgctxt "math symbol" -msgid "union with dot" -msgstr "傳回小於" - -#: src/cthulhu/mathsymbols.py:2182 -#, fuzzy -msgctxt "math symbol" -msgid "union with plus" -msgstr "美制 Letter Plus" - -#: src/cthulhu/mathsymbols.py:2184 -#, fuzzy -msgctxt "math symbol" -msgid "square intersection" -msgstr "永不(_E)" - -#: src/cthulhu/mathsymbols.py:2186 -#, fuzzy -msgctxt "math symbol" -msgid "square union" -msgstr "正方形" - -#: src/cthulhu/mathsymbols.py:2190 -#, fuzzy -msgctxt "math symbol" -msgid "black square" -msgstr "黑色" - -#: src/cthulhu/mathsymbols.py:2194 -#, fuzzy -msgctxt "math symbol" -msgid "white square" -msgstr "白色" - -#: src/cthulhu/mathsymbols.py:2198 -#, fuzzy -msgctxt "math symbol" -msgid "black diamond" -msgstr "黑色" - -#: src/cthulhu/mathsymbols.py:2202 -#, fuzzy -msgctxt "math symbol" -msgid "white circle" -msgstr "圓形" - -#: src/cthulhu/mathsymbols.py:2206 -#, fuzzy -msgctxt "math symbol" -msgid "black circle" -msgstr "圓形" - -#: src/cthulhu/mathsymbols.py:2209 -#, fuzzy -msgctxt "math symbol" -msgid "white bullet" -msgstr "白色" - -#: src/cthulhu/mathsymbols.py:2213 -#, fuzzy -msgctxt "math symbol" -msgid "black medium small square" -msgstr "實心方框" - -#: src/cthulhu/mathsymbols.py:2219 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with underline" -msgstr "底線(_U)" - -#: src/cthulhu/mathsymbols.py:2225 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with slash" -msgstr "路徑不能以斜線 (/) 結尾" - -#: src/cthulhu/mathsymbols.py:2231 -#, fuzzy, python-format -msgctxt "math symbol" -msgid "%s with vertical line" -msgstr "第 %d 列發生錯誤:%s" - -#: src/cthulhu/messages.py:45 -msgctxt "generic name" -msgid "application" -msgstr "應用程式" - -#: src/cthulhu/messages.py:48 -msgid "blank" -msgstr "空白" - -#: src/cthulhu/messages.py:51 -msgid "bold" -msgstr "粗體" - -#: src/cthulhu/messages.py:58 -msgid "bookmark entered" -msgstr "輸入的書籤" - -#: src/cthulhu/messages.py:65 -msgid "bookmarks saved" -msgstr "書籤已儲存" - -#: src/cthulhu/messages.py:72 -msgid "bookmarks could not be saved" -msgstr "書籤無法被儲存" - -#: src/cthulhu/messages.py:79 -msgid "No bookmarks found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:87 -msgid "Bookmark not found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:93 -msgid "Bypass mode enabled." -msgstr "已啟用略過功能。" - -#: src/cthulhu/messages.py:97 -msgid "Unable to get calculator display" -msgstr "無法取得計算機的顯示" - -#: src/cthulhu/messages.py:107 -msgctxt "capitalization style" -msgid "icon" -msgstr "圖示" - -#: src/cthulhu/messages.py:117 -msgid "Capitalization style set to icon." -msgstr "將大寫樣式設為圖示。" - -#: src/cthulhu/messages.py:127 -msgctxt "capitalization style" -msgid "none" -msgstr "沒有" - -#: src/cthulhu/messages.py:137 -msgid "Capitalization style set to none." -msgstr "將大寫樣式設為設為沒有。" - -#: src/cthulhu/messages.py:147 -msgctxt "capitalization style" -msgid "spell" -msgstr "讀出" - -#: src/cthulhu/messages.py:157 -msgid "Capitalization style set to spell." -msgstr "將大寫樣式設為讀出。" - -#: src/cthulhu/messages.py:164 -msgid "The application is controlling the caret." -msgstr "這個應用程式控制了導覽。" - -#: src/cthulhu/messages.py:170 -msgid "Cthulhu is controlling the caret." -msgstr "Cthulhu 正在控制游標。" - -#: src/cthulhu/messages.py:173 -#, python-format -msgid "Cell %s" -msgstr "儲存格 %s" - -#: src/cthulhu/messages.py:179 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s selected" -msgstr "已選取" - -#: src/cthulhu/messages.py:186 -#, python-format -msgctxt "cell" -msgid "%s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:193 -#, python-format -msgctxt "cell" -msgid "%s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:199 -#, fuzzy, python-format -msgctxt "cell" -msgid "%s unselected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:203 -msgid "Prevent use of option" -msgstr "避免使用的選項" - -#: src/cthulhu/messages.py:207 -msgid "Force use of option" -msgstr "強制使用的選項" - -#: src/cthulhu/messages.py:211 -msgid "OPTION" -msgstr "OPTION" - -#: src/cthulhu/messages.py:216 -msgid "Optional arguments" -msgstr "選擇性的引數" - -#: src/cthulhu/messages.py:220 -msgid "Usage: " -msgstr "用法:" - -#: src/cthulhu/messages.py:225 -msgid "The following are not valid: " -msgstr "下列項目是無效的:" - -#: src/cthulhu/messages.py:230 -msgid "Print the known running applications" -msgstr "顯示已知執行的應用程式" - -#: src/cthulhu/messages.py:237 -msgid "Load profile" -msgstr "載入設定檔" - -#: src/cthulhu/messages.py:244 -#, python-format -msgid "Profile could not be loaded: %s" -msgstr "無法載入設定檔:%s" - -#: src/cthulhu/messages.py:249 -msgid "Cannot start Cthulhu because it cannot connect to the Desktop." -msgstr "無法啟動 Cthulhu,因為無法連線到桌面。" - -#: src/cthulhu/messages.py:254 -msgid "Could not activate the settings manager. Exiting." -msgstr "無法使用設定值管理員。正在結束。" - -#: src/cthulhu/messages.py:259 -msgid "" -"Another Cthulhu process is already running for this session.\n" -"Run “cthulhu --replace” to replace that process with a new one." -msgstr "" -"另一個螢幕閱讀器程序已經在這個工作階段中執行。\n" -"執行「cthulhu --replace」以新的程序取代該程序。" - -#: src/cthulhu/messages.py:265 -msgid "NAME" -msgstr "NAME" - -#: src/cthulhu/messages.py:270 -msgid "Use alternate directory for user preferences" -msgstr "其它使用者偏好設定的資料夾名稱" - -#: src/cthulhu/messages.py:274 -msgid "DIR" -msgstr "DIR" - -#: src/cthulhu/messages.py:278 -msgid "Version of this application" -msgstr "顯示已知執行的應用程式" - -#: src/cthulhu/messages.py:282 -msgid "Replace a currently running instance of Cthulhu" -msgstr "取代目前正在執行的 Cthulhu 執行個體" - -#: src/cthulhu/messages.py:286 -msgid "Show this help message and exit" -msgstr "顯示這個求助訊息並離開" - -#: src/cthulhu/messages.py:294 -msgid "Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out" -msgstr "將除錯資訊輸出為 debug-YYYY-MM-DD-HH:MM:SS.out " - -#: src/cthulhu/messages.py:299 -msgid "Send debug output to the specified file" -msgstr "將除錯輸出資料傳送至指定的檔案" - -#: src/cthulhu/messages.py:303 -msgid "FILE" -msgstr "FILE" - -#: src/cthulhu/messages.py:309 -msgid "Set up user preferences (text version)" -msgstr "設定使用者偏好設定(文字版本)" - -#: src/cthulhu/messages.py:313 -msgid "Set up user preferences (GUI version)" -msgstr "設定使用者偏好設定(GUI 版本)" - -#: src/cthulhu/messages.py:317 -msgid "Report bugs to https://groups.io/g/stormux." -msgstr "匯報錯誤至 https://groups.io/g/stormux" - -#: src/cthulhu/messages.py:325 -msgid "Cut selection to clipboard." -msgstr "將選擇區域剪下貼到剪貼簿。" - -#: src/cthulhu/messages.py:333 -msgctxt "clipboard" -msgid "cut" -msgstr "剪下" - -#: src/cthulhu/messages.py:337 -msgid "Copied selection to clipboard." -msgstr "已複製選擇區域。到剪貼薄" - -#: src/cthulhu/messages.py:341 -msgctxt "clipboard" -msgid "copied" -msgstr "已複製" - -#: src/cthulhu/messages.py:349 -msgid "Pasted contents from clipboard." -msgstr "從剪貼薄貼上內容。" - -#: src/cthulhu/messages.py:357 -msgctxt "clipboard" -msgid "pasted" -msgstr "已貼上" - -#: src/cthulhu/messages.py:364 -msgid "Do not announce when your buddies are typing." -msgstr "當您的朋友在輸入時不要告知。" - -#: src/cthulhu/messages.py:371 -msgid "announce when your buddies are typing." -msgstr "當您的朋友在輸入時告知。" - -#: src/cthulhu/messages.py:379 -#, python-format -msgid "Message from chat room %s" -msgstr "來自聊天室 %s 的訊息 " - -#: src/cthulhu/messages.py:385 -#, python-format -msgid "New chat tab %s" -msgstr "新聊天分頁 %s" - -#: src/cthulhu/messages.py:394 -msgid "Do not speak chat room name." -msgstr "不要讀出聊天室名稱。" - -#: src/cthulhu/messages.py:403 -msgid "speak chat room name." -msgstr "讀出聊天室名稱。" - -#: src/cthulhu/messages.py:412 -msgid "Do not provide chat room specific message histories." -msgstr "不要提供指定聊天室的訊息歷史紀錄。" - -#: src/cthulhu/messages.py:420 -msgid "Provide chat room specific message histories." -msgstr "提供指定聊天室的訊息歷史紀錄。" - -#: src/cthulhu/messages.py:442 -#, fuzzy -msgctxt "content" -msgid "deletion start" -msgstr "分數開頭" - -#: src/cthulhu/messages.py:447 -#, fuzzy -msgctxt "content" -msgid "deletion end" -msgstr "分數結尾" - -#: src/cthulhu/messages.py:452 -#, fuzzy -msgctxt "content" -msgid "insertion start" -msgstr "分數開頭" - -#: src/cthulhu/messages.py:457 -#, fuzzy -msgctxt "content" -msgid "insertion end" -msgstr "分數結尾" - -#: src/cthulhu/messages.py:462 -msgctxt "content" -msgid "highlight start" -msgstr "" - -#: src/cthulhu/messages.py:467 -#, fuzzy -msgctxt "content" -msgid "highlight end" -msgstr "亮綠" - -#: src/cthulhu/messages.py:474 -#, fuzzy -msgctxt "content" -msgid "suggestion end" -msgstr "拼字建議(_S)" - -#: src/cthulhu/messages.py:483 -msgid "End of container." -msgstr "容器的結尾。" - -#: src/cthulhu/messages.py:489 -msgid "Not in a container." -msgstr "不在容器中。" - -#: src/cthulhu/messages.py:493 -msgid "all items selected" -msgstr "沒有選取" - -#: src/cthulhu/messages.py:498 -#, python-format -msgid "Default button is %s" -msgstr "預設按鈕為%s" - -#: src/cthulhu/messages.py:506 -#, fuzzy, python-format -msgid "Default button is %s. Grayed" -msgstr "預設按鈕為%s" - -#: src/cthulhu/messages.py:512 -msgid "Default button not found" -msgstr "預設按鈕為%s" - -#: src/cthulhu/messages.py:518 -#, python-format -msgid " subscript %s" -msgstr "下標 %s" - -#: src/cthulhu/messages.py:524 -#, python-format -msgid " superscript %s" -msgstr "上標 %s" - -#: src/cthulhu/messages.py:529 -msgid "Not in a dialog" -msgstr "不在表格中。" - -#: src/cthulhu/messages.py:535 -msgid "entire document selected" -msgstr "已選取整個文件" - -#: src/cthulhu/messages.py:542 -msgid "entire document unselected" -msgstr "已選取整個文件" - -#: src/cthulhu/messages.py:548 -msgid "document selected from cursor position" -msgstr "從游標位置開始選取文件" - -#: src/cthulhu/messages.py:554 -msgid "document unselected from cursor position" -msgstr "從游標位置開始取消選取文件" - -#: src/cthulhu/messages.py:560 -msgid "document selected to cursor position" -msgstr "選取至游標位置的文件" - -#: src/cthulhu/messages.py:566 -msgid "document unselected to cursor position" -msgstr "取消選取至游標位置的文件" - -#: src/cthulhu/messages.py:571 -#, python-format -msgid "Dynamic column header set for row %d" -msgstr "動態欄標頭設定給第 %d 列" - -#: src/cthulhu/messages.py:577 -msgid "Dynamic column header cleared." -msgstr "已清除動態欄標頭。" - -#: src/cthulhu/messages.py:583 -#, python-format -msgid "Dynamic row header set for column %s" -msgstr "動態列標頭設定給欄 %s" - -#: src/cthulhu/messages.py:589 -msgid "Dynamic row header cleared." -msgstr "已清除動態列標頭。" - -#: src/cthulhu/messages.py:593 -msgid "empty" -msgstr "空白" - -#: src/cthulhu/messages.py:596 -#, python-format -msgid "%.2f kilobytes" -msgstr "%.2f KB" - -#: src/cthulhu/messages.py:599 -#, python-format -msgid "%.2f megabytes" -msgstr "%.2f MB" - -#: src/cthulhu/messages.py:603 -msgid "No files found." -msgstr "找不到任何檔案。" - -#: src/cthulhu/messages.py:611 -msgid "Appended contents to clipboard." -msgstr "附加內容到剪貼薄。" - -#: src/cthulhu/messages.py:619 -msgid "Copied contents to clipboard." -msgstr "複製內容到剪貼薄。" - -#: src/cthulhu/messages.py:627 -msgid "Not using flat review." -msgstr "未使用 flat review。" - -#: src/cthulhu/messages.py:634 -msgid "Entering flat review." -msgstr "進入 flat review。" - -#: src/cthulhu/messages.py:641 -msgid "Leaving flat review." -msgstr "離開 flat review。" - -#: src/cthulhu/messages.py:649 -msgid "Flat review restricted to the current object" -msgstr "將 flat review 移至目前字詞之上。" - -#: src/cthulhu/messages.py:657 -msgid "Flat review unrestricted" -msgstr "平面檢視無限制" - -#: src/cthulhu/messages.py:661 -msgid "has formula" -msgstr "有公式" - -#: src/cthulhu/messages.py:665 -msgid "opens dialog" -msgstr "開啟「尋找」對話盒。" - -#: src/cthulhu/messages.py:669 -msgid "opens grid" -msgstr "" - -#: src/cthulhu/messages.py:673 -msgid "opens listbox" -msgstr "" - -#: src/cthulhu/messages.py:677 -msgid "opens menu" -msgstr "" - -#: src/cthulhu/messages.py:683 -msgid "opens tree" -msgstr "" - -#: src/cthulhu/messages.py:690 -msgid "image map link" -msgstr "影像地圖連結" - -#: src/cthulhu/messages.py:696 -#, python-format -msgid "The key entered is already bound to %s" -msgstr "輸入的按鍵已繫結於 %s" - -#: src/cthulhu/messages.py:701 -#, python-format -msgid "Key captured: %s. Press enter to confirm." -msgstr "按鍵擷取:%s。按 enter 確認。" - -#: src/cthulhu/messages.py:706 -#, python-format -msgid "The new key is: %s" -msgstr "新的按鍵是:%s" - -#: src/cthulhu/messages.py:711 -msgid "Key binding deleted. Press enter to confirm." -msgstr "按鍵組合已刪除。按 enter 確認。" - -#: src/cthulhu/messages.py:716 -msgid "The keybinding has been removed." -msgstr "該按鍵組合已經被移除。" - -#: src/cthulhu/messages.py:721 -msgid "enter new key" -msgstr "輸入新的按鍵" - -#: src/cthulhu/messages.py:735 -msgctxt "key echo" -msgid "key" -msgstr "按鍵" - -#: src/cthulhu/messages.py:747 -msgid "Echo set to key." -msgstr "按鍵回響設定為按鍵。" - -#: src/cthulhu/messages.py:761 -msgctxt "key echo" -msgid "None" -msgstr "沒有" - -#: src/cthulhu/messages.py:773 -msgid "Echo set to None." -msgstr "按鍵回響設定為沒有。" - -#: src/cthulhu/messages.py:787 -msgctxt "key echo" -msgid "key and word" -msgstr "按鍵和字詞" - -#: src/cthulhu/messages.py:799 -msgid "Echo set to key and word." -msgstr "按鍵回響設定為按鍵和字詞。" - -#: src/cthulhu/messages.py:813 -msgctxt "key echo" -msgid "sentence" -msgstr "段落" - -#: src/cthulhu/messages.py:825 -msgid "Echo set to sentence." -msgstr "按鍵回響設定為段落。" - -#: src/cthulhu/messages.py:839 -msgctxt "key echo" -msgid "word" -msgstr "字詞" - -#: src/cthulhu/messages.py:851 -msgid "Echo set to word." -msgstr "按鍵回響設定為字詞。" - -#: src/cthulhu/messages.py:865 -msgctxt "key echo" -msgid "word and sentence" -msgstr "字詞和段落" - -#: src/cthulhu/messages.py:877 -msgid "Echo set to word and sentence." -msgstr "按鍵回響設定為字詞和段落。" - -#: src/cthulhu/messages.py:889 -#, fuzzy, python-format -msgctxt "math enclosure" -msgid "Enclosed by: %s" -msgstr "%s – %s" - -#: src/cthulhu/messages.py:897 -msgctxt "math enclosure" -msgid "an actuarial symbol" -msgstr "精算的符號" - -#: src/cthulhu/messages.py:905 -#, fuzzy -msgctxt "math enclosure" -msgid "a box" -msgstr "組合方塊是否有項目" - -#: src/cthulhu/messages.py:913 -#, fuzzy -msgctxt "math enclosure" -msgid "a circle" -msgstr "圓形" - -#: src/cthulhu/messages.py:921 -#, fuzzy -msgctxt "math enclosure" -msgid "a long division sign" -msgstr "長" - -#: src/cthulhu/messages.py:929 -msgctxt "math enclosure" -msgid "a radical" -msgstr "" - -#: src/cthulhu/messages.py:937 -#, fuzzy -msgctxt "math enclosure" -msgid "a rounded box" -msgstr "該組合方塊的模型" - -#: src/cthulhu/messages.py:945 -#, fuzzy -msgctxt "math enclosure" -msgid "a horizontal strike" -msgstr "水平" - -#: src/cthulhu/messages.py:953 -#, fuzzy -msgctxt "math enclosure" -msgid "a vertical strike" -msgstr "垂直" - -#: src/cthulhu/messages.py:961 -#, fuzzy -msgctxt "math enclosure" -msgid "a down diagonal strike" -msgstr "Down" - -#: src/cthulhu/messages.py:969 -#, fuzzy -msgctxt "math enclosure" -msgid "an up diagonal strike" -msgstr "是否在文字中央加上刪除線" - -#: src/cthulhu/messages.py:977 -#, fuzzy -msgctxt "math enclosure" -msgid "a northeast arrow" -msgstr "東北" - -#: src/cthulhu/messages.py:985 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the bottom" -msgstr "下(_B):" - -#: src/cthulhu/messages.py:993 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the left" -msgstr "命令列" - -#: src/cthulhu/messages.py:1001 -#, fuzzy -msgctxt "math enclosure" -msgid "a line on the right" -msgstr "命令列" - -#: src/cthulhu/messages.py:1009 -#, fuzzy -msgctxt "math enclosure" -msgid "a line at the top" -msgstr "命令列" - -#: src/cthulhu/messages.py:1017 -#, fuzzy -msgctxt "math enclosure" -msgid "a phasor angle" -msgstr "角" - -#: src/cthulhu/messages.py:1026 -#, fuzzy -msgctxt "math enclosure" -msgid "an arabic factorial symbol" -msgstr "阿拉伯文" - -#: src/cthulhu/messages.py:1039 -#, fuzzy -msgctxt "math enclosure" -msgid "and" -msgstr "and" - -#: src/cthulhu/messages.py:1044 -msgid "fraction start" -msgstr "分數開頭" - -#: src/cthulhu/messages.py:1055 -msgid "fraction without bar, start" -msgstr "" - -#: src/cthulhu/messages.py:1060 -#, fuzzy -msgctxt "math fraction" -msgid "over" -msgstr "是否偏好圖示優於文字" - -#: src/cthulhu/messages.py:1065 -msgid "fraction end" -msgstr "分數結尾" - -#: src/cthulhu/messages.py:1073 -msgid "square root of" -msgstr "平方根" - -#: src/cthulhu/messages.py:1081 -msgid "cube root of" -msgstr "立方根" - -#: src/cthulhu/messages.py:1089 -msgid "root of" -msgstr "根" - -#: src/cthulhu/messages.py:1098 -msgid "root start" -msgstr "根開頭" - -#: src/cthulhu/messages.py:1104 -msgid "root end" -msgstr "根結尾" - -#: src/cthulhu/messages.py:1111 -#, fuzzy -msgctxt "math script generic" -msgid "subscript" -msgstr "下標 0" - -#: src/cthulhu/messages.py:1118 -#, fuzzy -msgctxt "math script generic" -msgid "superscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1125 -#, fuzzy -msgctxt "math script" -msgid "pre-subscript" -msgstr "簡報(_S)" - -#: src/cthulhu/messages.py:1132 -#, fuzzy -msgctxt "math script" -msgid "pre-superscript" -msgstr "無前置過濾器" - -#: src/cthulhu/messages.py:1141 -#, fuzzy -msgctxt "math script generic" -msgid "underscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1150 -#, fuzzy -msgctxt "math script generic" -msgid "overscript" -msgstr "superscript a" - -#: src/cthulhu/messages.py:1154 -#, fuzzy -msgctxt "math table" -msgid "table end" -msgstr "標記表格" - -#: src/cthulhu/messages.py:1159 -#, fuzzy -msgctxt "math table" -msgid "nested table end" -msgstr "End" - -#: src/cthulhu/messages.py:1164 -msgid "inaccessible" -msgstr "不能存取" - -#: src/cthulhu/messages.py:1169 -msgctxt "indentation and justification" -msgid "Disabled" -msgstr "已停用" - -#: src/cthulhu/messages.py:1174 -msgid "Speaking of indentation and justification disabled." -msgstr "已停用讀出縮排及對齊。" - -#: src/cthulhu/messages.py:1179 -msgctxt "indentation and justification" -msgid "Enabled" -msgstr "已啟用" - -#: src/cthulhu/messages.py:1184 -msgid "Speaking of indentation and justification enabled." -msgstr "已啟用讀出縮排及對齊。" - -#: src/cthulhu/messages.py:1192 -msgid "Learn mode. Press escape to exit." -msgstr "學習模式。 按離開鍵離開。" - -#: src/cthulhu/messages.py:1201 -msgid "" -"Entering learn mode. Press any key to hear its function. To view Cthulhu’s " -"documentation, press F1. To get a list of Cthulhu’s default shortcuts, press " -"F2. To get a list of Cthulhu’s shortcuts for the current application, press " -"F3. To exit learn mode, press the escape key." -msgstr "" -"進入學習模式。按任何鍵來聽它的功能。要檢視螢幕閱讀器的文件,請按 F1。要取得螢" -"幕閱讀器的預設捷徑鍵清單,請按 F2。要取得螢幕閱讀器對目前應用程式提供的捷徑鍵" -"清單,請按 F3。要離開學習模式,請按 escape 鍵。" - -#: src/cthulhu/messages.py:1210 -msgid "leaving blockquote." -msgstr "離開區塊引號。" - -#: src/cthulhu/messages.py:1221 -msgid "leaving details." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1227 -#, fuzzy -msgctxt "role" -msgid "leaving feed." -msgstr "離開表單。" - -#: src/cthulhu/messages.py:1233 -#, fuzzy -msgctxt "role" -msgid "leaving figure." -msgstr "離開表單。" - -#: src/cthulhu/messages.py:1237 -msgid "leaving form." -msgstr "離開表單。" - -#: src/cthulhu/messages.py:1243 -msgctxt "role" -msgid "leaving banner." -msgstr "離開橫幅。" - -#: src/cthulhu/messages.py:1249 -msgctxt "role" -msgid "leaving complementary content." -msgstr "離開互補內容。" - -#: src/cthulhu/messages.py:1255 -msgctxt "role" -msgid "leaving information." -msgstr "離開資訊。" - -#: src/cthulhu/messages.py:1261 -msgctxt "role" -msgid "leaving main content." -msgstr "離開主要內容。" - -#: src/cthulhu/messages.py:1267 -msgctxt "role" -msgid "leaving navigation." -msgstr "離開導覽。" - -#: src/cthulhu/messages.py:1273 -msgctxt "role" -msgid "leaving region." -msgstr "離開區域。" - -#: src/cthulhu/messages.py:1279 -msgctxt "role" -msgid "leaving search." -msgstr "離開搜尋。" - -#: src/cthulhu/messages.py:1283 -msgid "leaving list." -msgstr "離開列表。" - -#: src/cthulhu/messages.py:1288 -msgid "leaving panel." -msgstr "離開面板。" - -#: src/cthulhu/messages.py:1292 -msgid "leaving table." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1296 -msgid "leaving tooltip." -msgstr "離開列表。" - -#: src/cthulhu/messages.py:1302 -#, fuzzy -msgctxt "role" -msgid "leaving abstract." -msgstr "離開搜尋。" - -#: src/cthulhu/messages.py:1308 -#, fuzzy -msgctxt "role" -msgid "leaving acknowledgments." -msgstr "離開主要內容。" - -#: src/cthulhu/messages.py:1314 -#, fuzzy -msgctxt "role" -msgid "leaving afterword." -msgstr "離開表單。" - -#: src/cthulhu/messages.py:1320 -#, fuzzy -msgctxt "role" -msgid "leaving appendix." -msgstr "離開面板。" - -#: src/cthulhu/messages.py:1326 -#, fuzzy -msgctxt "role" -msgid "leaving bibliography." -msgstr "離開表單。" - -#: src/cthulhu/messages.py:1332 -#, fuzzy -msgctxt "role" -msgid "leaving chapter." -msgstr "離開橫幅。" - -#: src/cthulhu/messages.py:1338 -#, fuzzy -msgctxt "role" -msgid "leaving colophon." -msgstr "離開面板。" - -#: src/cthulhu/messages.py:1344 -#, fuzzy -msgctxt "role" -msgid "leaving conclusion." -msgstr "離開區域。" - -#: src/cthulhu/messages.py:1350 -#, fuzzy -msgctxt "role" -msgid "leaving credit." -msgstr "離開區域。" - -#: src/cthulhu/messages.py:1356 -#, fuzzy -msgctxt "role" -msgid "leaving credits." -msgstr "離開區域。" - -#: src/cthulhu/messages.py:1362 -#, fuzzy -msgctxt "role" -msgid "leaving dedication." -msgstr "離開導覽。" - -#: src/cthulhu/messages.py:1368 -#, fuzzy -msgctxt "role" -msgid "leaving endnotes." -msgstr "離開橫幅。" - -#: src/cthulhu/messages.py:1374 -#, fuzzy -msgctxt "role" -msgid "leaving epigraph." -msgstr "離開搜尋。" - -#: src/cthulhu/messages.py:1380 -#, fuzzy -msgctxt "role" -msgid "leaving epilogue." -msgstr "離開區域。" - -#: src/cthulhu/messages.py:1386 -#, fuzzy -msgctxt "role" -msgid "leaving errata." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1392 -#, fuzzy -msgctxt "role" -msgid "leaving example." -msgstr "離開工作表。" - -#: src/cthulhu/messages.py:1398 -#, fuzzy -msgctxt "role" -msgid "leaving foreword." -msgstr "離開表單。" - -#: src/cthulhu/messages.py:1404 -#, fuzzy -msgctxt "role" -msgid "leaving glossary." -msgstr "離開搜尋。" - -#: src/cthulhu/messages.py:1410 -#, fuzzy -msgctxt "role" -msgid "leaving index." -msgstr "離開面板。" - -#: src/cthulhu/messages.py:1416 -#, fuzzy -msgctxt "role" -msgid "leaving introduction." -msgstr "離開資訊。" - -#: src/cthulhu/messages.py:1422 -#, fuzzy -msgctxt "role" -msgid "leaving page list." -msgstr "離開列表。" - -#: src/cthulhu/messages.py:1428 -#, fuzzy -msgctxt "role" -msgid "leaving part." -msgstr "離開面板。" - -#: src/cthulhu/messages.py:1434 -#, fuzzy -msgctxt "role" -msgid "leaving preface." -msgstr "離開面板。" - -#: src/cthulhu/messages.py:1440 -#, fuzzy -msgctxt "role" -msgid "leaving prologue." -msgstr "離開區塊引號。" - -#: src/cthulhu/messages.py:1446 -#, fuzzy -msgctxt "role" -msgid "leaving pullquote." -msgstr "離開區塊引號。" - -#: src/cthulhu/messages.py:1452 -#, fuzzy -msgctxt "role" -msgid "leaving QNA." -msgstr "離開表單。" - -#: src/cthulhu/messages.py:1459 -#, fuzzy -msgctxt "role" -msgid "leaving suggestion." -msgstr "離開區域。" - -#: src/cthulhu/messages.py:1465 -#, fuzzy -msgctxt "role" -msgid "leaving table of contents." -msgstr "離開主要內容。" - -#: src/cthulhu/messages.py:1471 -msgid "line selected down from cursor position" -msgstr "從游標位置開始向下選取行" - -#: src/cthulhu/messages.py:1477 -msgid "line selected up from cursor position" -msgstr "從游標位置開始向上選取行" - -#: src/cthulhu/messages.py:1484 -msgid "line unselected down from cursor position" -msgstr "從游標位置開始向下取消選取行" - -#: src/cthulhu/messages.py:1491 -msgid "line unselected up from cursor position" -msgstr "從游標位置開始向上取消選取行" - -#: src/cthulhu/messages.py:1499 -msgid "Exiting learn mode." -msgstr "離開學習模式。" - -#: src/cthulhu/messages.py:1505 -msgid "line selected from start to previous cursor position" -msgstr "從開始到前一個游標位置選取行" - -#: src/cthulhu/messages.py:1511 -msgid "line selected to end from previous cursor position" -msgstr "從前一個游標位置選取行至結尾" - -#: src/cthulhu/messages.py:1514 -msgid "link" -msgstr "連結" - -#: src/cthulhu/messages.py:1518 -msgid "same page" -msgstr "相同頁面" - -#: src/cthulhu/messages.py:1522 -msgid "same site" -msgstr "相同網站" - -#: src/cthulhu/messages.py:1526 -msgid "different site" -msgstr "不同網站" - -#: src/cthulhu/messages.py:1531 -#, python-format -msgid "%(uri)s link to %(file)s" -msgstr "%(uri)s 連結到 %(file)s" - -#: src/cthulhu/messages.py:1534 -#, python-format -msgid "%s link" -msgstr "%s 連結" - -#: src/cthulhu/messages.py:1538 -#, python-format -msgid "visited %s link" -msgstr "已瀏覽 %s 連結" - -#: src/cthulhu/messages.py:1544 -msgid "Use Up and Down Arrow to navigate the list. Press Escape to exit." -msgstr "使用上、下方向鍵來瀏覽清單。按 Escape 結束。" - -#: src/cthulhu/messages.py:1554 -msgid "All live regions set to off" -msgstr "將所有的即時播報區設為關閉" - -#: src/cthulhu/messages.py:1564 -msgid "live regions politeness levels restored" -msgstr "即時播報區禮貌程度已還原" - -#: src/cthulhu/messages.py:1573 -#, python-format -msgid "politeness level %s" -msgstr "禮貌程度 %s" - -#: src/cthulhu/messages.py:1583 -msgid "setting live region to assertive" -msgstr "將即時播報區設為堅決" - -#: src/cthulhu/messages.py:1593 -msgid "setting live region to off" -msgstr "將即時播報區設為關閉" - -#: src/cthulhu/messages.py:1603 -msgid "setting live region to polite" -msgstr "將即時播報區設為禮貌" - -#: src/cthulhu/messages.py:1613 -msgid "setting live region to rude" -msgstr "將即時播報區設為粗魯" - -#: src/cthulhu/messages.py:1624 -msgid "Live regions monitoring off" -msgstr "即時播報區監控關閉" - -#: src/cthulhu/messages.py:1635 -msgid "Live regions monitoring on" -msgstr "即時播報區監控開啟" - -#: src/cthulhu/messages.py:1642 -msgid "no live message saved" -msgstr "沒有儲存即時訊息" - -#: src/cthulhu/messages.py:1649 -msgid "Live region support is off" -msgstr "即時播報區支援已關閉" - -#: src/cthulhu/messages.py:1654 -msgctxt "location" -msgid "Not found" -msgstr "找不到" - -#: src/cthulhu/messages.py:1659 -msgid "Could not find current location." -msgstr "找不到目前的位置。" - -#: src/cthulhu/messages.py:1666 -msgctxt "locking key state" -msgid "off" -msgstr "關" - -#: src/cthulhu/messages.py:1673 -msgctxt "locking key state" -msgid "on" -msgstr "開" - -#: src/cthulhu/messages.py:1677 -msgid "misspelled" -msgstr "拼錯" - -#: src/cthulhu/messages.py:1682 -#, python-format -msgid "Misspelled word: %s" -msgstr "拼錯字詞:%s" - -#: src/cthulhu/messages.py:1687 -#, python-format -msgid "Context is %s" -msgstr "內文是 %s" - -#: src/cthulhu/messages.py:1702 -msgid "Browse mode" -msgstr "瀏覽模式" - -#: src/cthulhu/messages.py:1717 -msgid "Focus mode" -msgstr "焦點模式" - -#: src/cthulhu/messages.py:1736 -#, python-format -msgid "To enable focus mode press %s." -msgstr "要啟用焦點模式請按%s。" - -#: src/cthulhu/messages.py:1747 -msgid "Focus mode is sticky." -msgstr "焦點模式為黏性模式。" - -#: src/cthulhu/messages.py:1758 -msgid "Browse mode is sticky." -msgstr "瀏覽模式為粘性模式。" - -#: src/cthulhu/messages.py:1771 -msgid "Layout mode." -msgstr "焦點模式" - -#: src/cthulhu/messages.py:1785 -msgid "Object mode." -msgstr "物件" - -#: src/cthulhu/messages.py:1789 -msgid "Pointer moved to object." -msgstr "移至下一個物件。" - -#: src/cthulhu/messages.py:1795 -msgid "Mouse over object not found." -msgstr "找不到滑鼠停駐物件。" - -#: src/cthulhu/messages.py:1800 -msgid "Mouse review disabled." -msgstr "滑鼠複誦已停用。" - -#: src/cthulhu/messages.py:1805 -msgid "Mouse review enabled." -msgstr "滑鼠複誦已啟用。" - -#: src/cthulhu/messages.py:1812 -msgid "Error: Could not create list of objects." -msgstr "錯誤:無法建立物件清單。" - -#: src/cthulhu/messages.py:1817 -msgid "No children." -msgstr "沒有子項目。" - -#: src/cthulhu/messages.py:1822 -msgid "No next." -msgstr "" - -#: src/cthulhu/messages.py:1827 -msgid "No parent." -msgstr "百分之%d。" - -#: src/cthulhu/messages.py:1832 -msgid "No previous." -msgstr "移至下一個單字。" - -#: src/cthulhu/messages.py:1837 -msgid "Simplified navigation enabled." -msgstr "" - -#: src/cthulhu/messages.py:1842 -msgid "Simplified navigation disabled." -msgstr "" - -#: src/cthulhu/messages.py:1847 src/cthulhu/object_properties.py:65 -#, python-format -msgid "Nesting level %d" -msgstr "巢狀清單第 %d 層" - -#: src/cthulhu/messages.py:1852 -msgid "New item has been added" -msgstr "已加入新的項目" - -#: src/cthulhu/messages.py:1859 -#, fuzzy, python-format -msgid "No actions found on: %s" -msgstr "沒有應用程式取得焦點。" - -#: src/cthulhu/messages.py:1863 -msgid "No focus" -msgstr "沒有焦點" - -#: src/cthulhu/messages.py:1867 -msgid "No application has focus." -msgstr "沒有應用程式取得焦點。" - -#: src/cthulhu/messages.py:1872 -msgid "No more blockquotes." -msgstr "沒有其他區塊括弧。" - -#: src/cthulhu/messages.py:1877 -msgid "No more buttons." -msgstr "沒有其他按鈕。" - -#: src/cthulhu/messages.py:1882 -msgid "No more check boxes." -msgstr "沒有其他勾選盒。" - -#: src/cthulhu/messages.py:1888 -msgid "No more large objects." -msgstr "沒有其他大型物件。" - -#: src/cthulhu/messages.py:1893 -msgid "No more clickables." -msgstr "沒有更多可按下項目。" - -#: src/cthulhu/messages.py:1898 -msgid "No more combo boxes." -msgstr "沒有其他組合方塊。" - -#: src/cthulhu/messages.py:1903 -msgid "No more entries." -msgstr "沒有其他項目。" - -#: src/cthulhu/messages.py:1908 -msgid "No more form fields." -msgstr "沒有其他表單欄位。" - -#: src/cthulhu/messages.py:1913 -msgid "No more headings." -msgstr "沒有其他標題。" - -#: src/cthulhu/messages.py:1919 -#, python-format -msgid "No more headings at level %d." -msgstr "沒有其他第 %d 級標題。" - -#: src/cthulhu/messages.py:1924 -msgid "No more internal frames." -msgstr "沒有其他的表格。" - -#: src/cthulhu/messages.py:1929 -msgid "No more images." -msgstr "沒有更多影像。" - -#: src/cthulhu/messages.py:1935 -msgid "No landmark found." -msgstr "No landmark found." - -#: src/cthulhu/messages.py:1940 -msgid "No more links." -msgstr "沒有其他連結。" - -#: src/cthulhu/messages.py:1945 -msgid "No more lists." -msgstr "沒有其他清單。" - -#: src/cthulhu/messages.py:1950 -msgid "No more list items." -msgstr "沒有其他清單項目。" - -#: src/cthulhu/messages.py:1957 -msgid "No more live regions." -msgstr "No more live regions." - -#: src/cthulhu/messages.py:1962 -msgid "No more paragraphs." -msgstr "沒有其他段落。" - -#: src/cthulhu/messages.py:1967 -msgid "No more radio buttons." -msgstr "沒有其他單選按鈕。" - -#: src/cthulhu/messages.py:1972 -msgid "No more separators." -msgstr "沒有其他分隔符。" - -#: src/cthulhu/messages.py:1977 -msgid "No more tables." -msgstr "沒有其他的表格。" - -#: src/cthulhu/messages.py:1982 -msgid "No more unvisited links." -msgstr "No more unvisited links." - -#: src/cthulhu/messages.py:1987 -msgid "No more visited links." -msgstr "沒有其他參訪過的連結。" - -#: src/cthulhu/messages.py:1992 -msgid "No selected text." -msgstr "沒有選取的文字。" - -#: src/cthulhu/messages.py:1997 -msgid "Not on a link." -msgstr "不是在連結上。" - -#: src/cthulhu/messages.py:2001 -msgid "Notification" -msgstr "通知" - -#: src/cthulhu/messages.py:2005 -msgctxt "notification" -msgid "Bottom" -msgstr "底部" - -#: src/cthulhu/messages.py:2009 -msgctxt "notification" -msgid "Top" -msgstr "頂端" - -#: src/cthulhu/messages.py:2013 -msgid "No notification messages" -msgstr "沒有通知訊息" - -#: src/cthulhu/messages.py:2020 -msgctxt "number style" -msgid "digits" -msgstr "數字寫做" - -#: src/cthulhu/messages.py:2027 -msgid "Speak numbers as digits." -msgstr "將數字讀為阿拉伯數字。" - -#: src/cthulhu/messages.py:2034 -msgctxt "number style" -msgid "words" -msgstr "數字讀做" - -#: src/cthulhu/messages.py:2041 -msgid "Speak numbers as words." -msgstr "將數字讀出來。" - -#: src/cthulhu/messages.py:2046 -msgid "off" -msgstr " 關" - -#: src/cthulhu/messages.py:2051 -msgid "on" -msgstr " 開" - -#: src/cthulhu/messages.py:2055 -msgid "Loading. Please wait." -msgstr "載入中,請稍候。" - -#: src/cthulhu/messages.py:2059 -msgid "Finished loading." -msgstr "載入完成。" - -#: src/cthulhu/messages.py:2064 -#, python-format -msgid "Finished loading %s." -msgstr "載入 %s 完成。" - -#: src/cthulhu/messages.py:2071 -#, python-format -msgid "Page has %s." -msgstr "頁面具有 %s。" - -#: src/cthulhu/messages.py:2077 -msgid "page selected from cursor position" -msgstr "從游標位置開始選取頁" - -#: src/cthulhu/messages.py:2083 -msgid "page selected to cursor position" -msgstr "選取至游標位置的頁" - -#: src/cthulhu/messages.py:2089 -msgid "page unselected from cursor position" -msgstr "從游標位置取消選取頁" - -#: src/cthulhu/messages.py:2095 -msgid "page unselected to cursor position" -msgstr "取消選取頁至游標位置" - -#: src/cthulhu/messages.py:2101 -msgid "paragraph selected down from cursor position" -msgstr "從游標位置開始向下選取段落" - -#: src/cthulhu/messages.py:2107 -msgid "paragraph selected up from cursor position" -msgstr "從游標位置開始向上選取段落" - -#: src/cthulhu/messages.py:2114 -msgid "paragraph unselected down from cursor position" -msgstr "從游標位置開始向下取消選取段落" - -#: src/cthulhu/messages.py:2121 -msgid "paragraph unselected up from cursor position" -msgstr "從游標位置開始向上取消選取段落" - -#: src/cthulhu/messages.py:2127 -msgid "" -"You already have an instance of an Cthulhu preferences dialog open.\n" -"Please close it before opening a new one." -msgstr "" -"您已經有一個開啟的 Cthulhu 偏好設定對話盒實體。\n" -"\n" -"請在開啟新的之前先關閉它。" - -#: src/cthulhu/messages.py:2132 -#, python-format -msgid "slide %(position)d of %(count)d" -msgstr "投影片全部%(count)d張的第%(position)d張" - -#: src/cthulhu/messages.py:2139 -#, python-format -msgid "Profile set to %s." -msgstr "設定檔設定為 %s。" - -#: src/cthulhu/messages.py:2146 -msgid "No profiles found." -msgstr "找不到設定檔。" - -#: src/cthulhu/messages.py:2151 -#, python-format -msgid "Progress bar %d." -msgstr "進度列%d。" - -#: src/cthulhu/messages.py:2157 -msgctxt "spoken punctuation" -msgid "All" -msgstr "全部" - -#: src/cthulhu/messages.py:2163 -msgid "Punctuation level set to all." -msgstr "將標音符號等級為全部。" - -#: src/cthulhu/messages.py:2169 -msgctxt "spoken punctuation" -msgid "Most" -msgstr "最多" - -#: src/cthulhu/messages.py:2175 -msgid "Punctuation level set to most." -msgstr "標音符號等級設為最多。" - -#: src/cthulhu/messages.py:2181 -msgctxt "spoken punctuation" -msgid "None" -msgstr "沒有" - -#: src/cthulhu/messages.py:2187 -msgid "Punctuation level set to none." -msgstr "標音符號等級設為沒有。" - -#: src/cthulhu/messages.py:2193 -msgctxt "spoken punctuation" -msgid "Some" -msgstr "一些" - -#: src/cthulhu/messages.py:2199 -msgid "Punctuation level set to some." -msgstr "標音符號等級設為一些。" - -#: src/cthulhu/messages.py:2203 -msgid "Searching." -msgstr "搜尋中。" - -#: src/cthulhu/messages.py:2207 -msgid "Search complete." -msgstr "搜尋完成。" - -#: src/cthulhu/messages.py:2211 -msgid "Cthulhu settings reloaded." -msgstr "已重新載入 Cthulhu 設定。" - -#: src/cthulhu/messages.py:2216 -#, python-format -msgid "Selected text is: %s" -msgstr "選取的文字為:%s" - -#: src/cthulhu/messages.py:2223 -msgid "Selection deleted." -msgstr "選擇區域已刪除。" - -#: src/cthulhu/messages.py:2233 -msgid "Selection restored." -msgstr "選擇區域已還原。" - -#: src/cthulhu/messages.py:2238 -msgid "Text unselected." -msgstr "取消選取" - -#: src/cthulhu/messages.py:2244 -#, python-format -msgid "Size: %d, %d. Location: %d, %d." -msgstr "" - -#: src/cthulhu/messages.py:2250 -#, python-format -msgid "Width: %d. Height: %d. %d from left. %d from top." -msgstr "" - -#: src/cthulhu/messages.py:2254 -msgid "Speech disabled." -msgstr "已停用朗讀功能。" - -#: src/cthulhu/messages.py:2258 -msgid "Speech enabled." -msgstr "已啟用朗讀功能。" - -#: src/cthulhu/messages.py:2261 -msgid "faster." -msgstr "較快。" - -#: src/cthulhu/messages.py:2264 -msgid "slower." -msgstr "較慢。" - -#: src/cthulhu/messages.py:2267 -msgid "higher." -msgstr "較高。" - -#: src/cthulhu/messages.py:2270 -msgid "lower." -msgstr "較低。" - -#: src/cthulhu/messages.py:2273 -msgid "louder." -msgstr "" - -#: src/cthulhu/messages.py:2276 -msgid "softer." -msgstr "較柔和。" - -#: src/cthulhu/messages.py:2279 -#, python-format -msgid "Rate %d" -msgstr "語速 %d" - -#: src/cthulhu/messages.py:2282 -#, python-format -msgid "Pitch %s" -msgstr "音調 %s" - -#: src/cthulhu/messages.py:2285 -#, python-format -msgid "Volume %s" -msgstr "音量 %s" - -#: src/cthulhu/messages.py:2288 -#, python-format -msgid "Speech-dispatcher module %s" -msgstr "Speech-dispatcher 模組 %s" - -#: src/cthulhu/messages.py:2291 -#, python-format -msgid "Speech-dispatcher voice %s" -msgstr "Speech-dispatcher 語音 %s" - -#: src/cthulhu/messages.py:2294 -msgid "No speech-dispatcher modules available" -msgstr "沒有可用的 Speech-dispatcher 模組" - -#: src/cthulhu/messages.py:2297 -msgid "No speech-dispatcher voices available" -msgstr "沒有可用的 Speech-dispatcher 語音" - -#: src/cthulhu/messages.py:2300 -msgid "Speech settings saved" -msgstr "語音設定已儲存" - -#: src/cthulhu/messages.py:2303 -msgid "Speech settings could not be saved" -msgstr "無法儲存語音設定" - -#: src/cthulhu/messages.py:2310 -msgctxt "Speech" -msgid "Verbosity level: brief" -msgstr "詳細等級:簡短" - -#: src/cthulhu/messages.py:2317 -msgctxt "Speech" -msgid "Verbosity level: verbose" -msgstr "詳細等級:詳細" - -#: src/cthulhu/messages.py:2323 -msgid " dot dot dot" -msgstr " 點點點" - -#: src/cthulhu/messages.py:2326 -msgid "Cthulhu welcomes you." -msgstr "Cthulhu 歡迎您。" - -#: src/cthulhu/messages.py:2329 -msgid "Cthulhu lurks beneath the waves." -msgstr "克蘇魯潛伏在波濤之下。" - -#: src/cthulhu/messages.py:2333 -#, python-format -msgid "Sleep mode enabled for %s" -msgstr "已為 %s 啟用睡眠模式" - -#: src/cthulhu/messages.py:2334 -#, python-format -msgid "Sleep mode disabled for %s" -msgstr "已為 %s 停用睡眠模式" - -#: src/cthulhu/messages.py:2337 -msgid "Speech is unavailable." -msgstr "語音功能不存在。" - -#: src/cthulhu/messages.py:2342 -#, fuzzy -msgctxt "status bar" -msgid "Not found" -msgstr "找不到" - -#: src/cthulhu/messages.py:2347 -msgid "Status bar not found" -msgstr "找不到字串" - -#: src/cthulhu/messages.py:2353 -msgid "string not found" -msgstr "找不到字串" - -#: src/cthulhu/messages.py:2361 -msgid "Structural navigation keys off." -msgstr "結構導覽鍵關閉。" - -#: src/cthulhu/messages.py:2369 -msgid "Structural navigation keys on." -msgstr "結構導覽鍵開啟。" - -#: src/cthulhu/messages.py:2377 -msgctxt "structural navigation" -msgid "Not found" -msgstr "找不到" - -#: src/cthulhu/messages.py:2380 -#, python-format -msgid "Row %(row)d, column %(column)d." -msgstr "列 %(row)d,欄 %(column)d。" - -#: src/cthulhu/messages.py:2384 -msgid "End of table" -msgstr "表格的結尾" - -#: src/cthulhu/messages.py:2389 -msgid "Speak cell" -msgstr "讀出儲存格" - -#: src/cthulhu/messages.py:2394 -msgid "Speak row" -msgstr "讀出整列" - -#: src/cthulhu/messages.py:2399 -msgid "Non-uniform" -msgstr "非制式" - -#: src/cthulhu/messages.py:2404 -msgid "Not in a table." -msgstr "不在表格中。" - -#: src/cthulhu/messages.py:2408 -msgid "Columns reordered" -msgstr "重新排序的欄" - -#: src/cthulhu/messages.py:2412 -msgid "Rows reordered" -msgstr "重新排序的列" - -#: src/cthulhu/messages.py:2416 -#, python-format -msgid "column %d" -msgstr "欄 %d" - -#: src/cthulhu/messages.py:2420 -#, python-format -msgid "column %(index)d of %(total)d" -msgstr "全部 %(total)d 欄的第 %(index)d 欄" - -#: src/cthulhu/messages.py:2425 -msgid "Bottom of column." -msgstr "欄的底部。" - -#: src/cthulhu/messages.py:2430 -msgid "Top of column." -msgstr "欄的頂端。" - -#: src/cthulhu/messages.py:2435 -#, fuzzy, python-format -msgid "Column %s selected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:2442 -#, python-format -msgid "Columns %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2449 -#, python-format -msgid "Columns %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2454 -#, fuzzy, python-format -msgid "Column %s unselected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:2458 -#, python-format -msgid "row %d" -msgstr "列 %d" - -#: src/cthulhu/messages.py:2462 -#, python-format -msgid "row %(index)d of %(total)d" -msgstr "全部 %(total)d 列的第 %(index)d 列" - -#: src/cthulhu/messages.py:2467 -msgid "Beginning of row." -msgstr "列的開頭。" - -#: src/cthulhu/messages.py:2472 -msgid "End of row." -msgstr "列的結尾。" - -#: src/cthulhu/messages.py:2476 -msgid "Row deleted." -msgstr "已刪除列。" - -#: src/cthulhu/messages.py:2480 -msgid "Last row deleted." -msgstr "已刪除最後一列。" - -#: src/cthulhu/messages.py:2484 -msgid "Row inserted." -msgstr "已插入列。" - -#: src/cthulhu/messages.py:2489 -msgid "Row inserted at the end of the table." -msgstr "已在表格結尾插入列。" - -#: src/cthulhu/messages.py:2494 -#, fuzzy, python-format -msgid "Row %s selected" -msgstr "已刪除列。" - -#: src/cthulhu/messages.py:2501 -#, python-format -msgid "Rows %s through %s selected" -msgstr "" - -#: src/cthulhu/messages.py:2508 -#, python-format -msgid "Rows %s through %s unselected" -msgstr "" - -#: src/cthulhu/messages.py:2513 -#, fuzzy, python-format -msgid "Row %s unselected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:2517 -msgctxt "text" -msgid "selected" -msgstr "已選取" - -#: src/cthulhu/messages.py:2521 -msgctxt "text" -msgid "unselected" -msgstr "取消選取" - -#: src/cthulhu/messages.py:2532 -msgid "%H hours, %M minutes and %S seconds" -msgstr "%H小時,%M分%S秒。" - -#: src/cthulhu/messages.py:2537 -msgid "%H hours and %M minutes" -msgstr "%H小時%M分。" - -#: src/cthulhu/messages.py:2541 -#, python-format -msgid "Unicode %s" -msgstr "萬國碼 %s" - -#: src/cthulhu/messages.py:2545 -msgctxt "command" -msgid "undo" -msgstr "復原" - -#: src/cthulhu/messages.py:2549 -msgctxt "command" -msgid "redo" -msgstr "取消復原" - -#: src/cthulhu/messages.py:2552 -#, python-format -msgid "Cthulhu version %s." -msgstr "Cthulhu 版本 %s。" - -#: src/cthulhu/messages.py:2556 -msgid "white space" -msgstr "空白空間" - -#: src/cthulhu/messages.py:2562 -msgid "Wrapping to bottom." -msgstr "跳至底部。" - -#: src/cthulhu/messages.py:2568 -msgid "Wrapping to top." -msgstr "回到開始。" - -#: src/cthulhu/messages.py:2573 -msgid "0 items" -msgstr "0 個項目" - -#: src/cthulhu/messages.py:2581 src/cthulhu/messages.py:2600 -#, python-format -msgid "Cell spans %d row" -msgid_plural "Cell spans %d rows" -msgstr[0] "儲存格合併 %d 列" - -#: src/cthulhu/messages.py:2586 -#, python-format -msgid " %d column" -msgid_plural " %d columns" -msgstr[0] "%d 欄" - -#: src/cthulhu/messages.py:2593 -#, python-format -msgid "Cell spans %d column" -msgid_plural "Cell spans %d columns" -msgstr[0] "儲存格合併 %d 欄" - -#: src/cthulhu/messages.py:2610 -#, python-format -msgid "%d character too long" -msgid_plural "%d characters too long" -msgstr[0] "%d 個字元太長" - -#: src/cthulhu/messages.py:2618 -#, python-format -msgid "(%d dialog)" -msgid_plural "(%d dialogs)" -msgstr[0] "(%d 個對話盒)" - -#: src/cthulhu/messages.py:2624 -#, python-format -msgid "%d unfocused dialog" -msgid_plural "%d unfocused dialogs" -msgstr[0] "%d 個未取得焦點的對話盒" - -#: src/cthulhu/messages.py:2628 -#, python-format -msgid "%d byte" -msgid_plural "%d bytes" -msgstr[0] "%d 位元組" - -#: src/cthulhu/messages.py:2633 -#, python-format -msgid "%d file found" -msgid_plural "%d files found" -msgstr[0] "找到 %d 個檔案" - -#: src/cthulhu/messages.py:2640 -#, python-format -msgid "%d form" -msgid_plural "%d forms" -msgstr[0] "%d 個表單" - -#: src/cthulhu/messages.py:2647 -#, python-format -msgid "%d heading" -msgid_plural "%d headings" -msgstr[0] "%d 個標題" - -#: src/cthulhu/messages.py:2652 -#, python-format -msgid "%d item" -msgid_plural "%d items" -msgstr[0] "%d 個項目" - -#: src/cthulhu/messages.py:2661 -#, python-format -msgid "%d landmark" -msgid_plural "%d landmarks" -msgstr[0] "%d 地標" - -#: src/cthulhu/messages.py:2667 -#, python-format -msgid "%d item found" -msgid_plural "%d items found" -msgstr[0] "找到 %d 個項目" - -#: src/cthulhu/messages.py:2673 -#, python-format -msgid "Leaving %d blockquote." -msgid_plural "Leaving %d blockquotes." -msgstr[0] "離開 %d 個區塊括弧。" - -#: src/cthulhu/messages.py:2678 -#, python-format -msgid "Leaving %d list." -msgid_plural "Leaving %d lists." -msgstr[0] "離開 %d 個列表。" - -#: src/cthulhu/messages.py:2688 -msgid "List of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2691 -#, python-format -msgid "List with %d item" -msgid_plural "List with %d items" -msgstr[0] "有 %d 個項目的清單" - -#: src/cthulhu/messages.py:2700 -msgid "Feed of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2704 -#, python-format -msgid "Feed with %d article" -msgid_plural "Feed with %d articles" -msgstr[0] "" - -#: src/cthulhu/messages.py:2710 -#, fuzzy, python-format -msgid "Description list with %d term" -msgid_plural "Description list with %d terms" -msgstr[0] "有 %d 個項目的清單" - -#: src/cthulhu/messages.py:2718 -#, fuzzy, python-format -msgid "%d value" -msgid_plural "%d values" -msgstr[0] "數值" - -#: src/cthulhu/messages.py:2723 -#, python-format -msgid "math table with %d row" -msgid_plural "math table with %d rows" -msgstr[0] "有 %d 列的數學表格" - -#: src/cthulhu/messages.py:2728 src/cthulhu/messages.py:2744 -#: src/cthulhu/messages.py:2852 -#, python-format -msgid "%d column" -msgid_plural "%d columns" -msgstr[0] "%d 欄" - -#: src/cthulhu/messages.py:2738 -#, python-format -msgid "nested math table with %d row" -msgid_plural "nested math table with %d rows" -msgstr[0] "有 %d 列的巢狀數學表格" - -#: src/cthulhu/messages.py:2753 -#, python-format -msgid "%d message.\n" -msgid_plural "%d messages.\n" -msgstr[0] "%d 個訊息。\n" - -#: src/cthulhu/messages.py:2758 -#, python-format -msgid "%d percent." -msgid_plural "%d percent." -msgstr[0] "百分之%d。" - -#: src/cthulhu/messages.py:2764 -#, python-format -msgid "%d percent of document read" -msgid_plural "%d percent of document read" -msgstr[0] "已讀取文件的百分之 %d" - -#: src/cthulhu/messages.py:2771 -#, python-format -msgid "%d pixel" -msgid_plural "%d pixels" -msgstr[0] "%d 像素" - -#: src/cthulhu/messages.py:2777 -#, python-format -msgid "%(count)d %(repeatChar)s character" -msgid_plural "%(count)d %(repeatChar)s characters" -msgstr[0] "%(count)d 個 %(repeatChar)s 字元" - -#: src/cthulhu/messages.py:2784 -#, python-format -msgid "%(index)d of %(total)d item selected" -msgid_plural "%(index)d of %(total)d items selected" -msgstr[0] "%(total)d 個項目中選取的 %(index)d 個項目" - -#: src/cthulhu/messages.py:2793 -#, python-format -msgid "%d Screen reader default shortcut found." -msgid_plural "%d Screen reader default shortcuts found." -msgstr[0] "找到 %d 個螢幕閱讀器預設捷徑鍵。" - -#: src/cthulhu/messages.py:2801 -#, python-format -msgid "%(count)d Screen reader shortcut for %(application)s found." -msgid_plural "%(count)d Screen reader shortcuts for %(application)s found." -msgstr[0] "找到 %(count)d 個螢幕閱讀器 %(application)s 捷徑鍵。" - -#: src/cthulhu/messages.py:2808 -#, python-format -msgid "%d space" -msgid_plural "%d spaces" -msgstr[0] "%d 個空格" - -#: src/cthulhu/messages.py:2813 -#, python-format -msgid "%d tab" -msgid_plural "%d tabs" -msgstr[0] "%d 個 tab" - -#: src/cthulhu/messages.py:2820 -#, python-format -msgid "%d table" -msgid_plural "%d tables" -msgstr[0] "%d 個表格" - -#: src/cthulhu/messages.py:2829 -msgid "table of unknown size" -msgstr "" - -#: src/cthulhu/messages.py:2834 -#, fuzzy, python-format -msgid "table with %d column, row count unknown" -msgid_plural "table with %d columns, row count unknown" -msgstr[0] "有 %d 列的表格" - -#: src/cthulhu/messages.py:2842 -#, fuzzy, python-format -msgid "table with %d row, column count unknown" -msgid_plural "table with %d rows, column count unknown" -msgstr[0] "有 %d 列的表格" - -#: src/cthulhu/messages.py:2847 -#, python-format -msgid "table with %d row" -msgid_plural "table with %d rows" -msgstr[0] "有 %d 列的表格" - -#: src/cthulhu/messages.py:2861 -#, python-format -msgid "%d second ago" -msgid_plural "%d seconds ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2866 -#, python-format -msgid "%d minute ago" -msgid_plural "%d minutes ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2871 -#, python-format -msgid "%d hour ago" -msgid_plural "%d hours ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2876 -#, python-format -msgid "%d day ago" -msgid_plural "%d days ago" -msgstr[0] "" - -#: src/cthulhu/messages.py:2884 -#, python-format -msgid "%d unvisited link" -msgid_plural "%d unvisited links" -msgstr[0] "%d 個未瀏覽的連結" - -#: src/cthulhu/messages.py:2892 -#, python-format -msgid "%d visited link" -msgid_plural "%d visited links" -msgstr[0] "%d 個瀏覽過的連結" - -#: src/cthulhu/object_properties.py:41 -msgid "toggle" -msgstr "切換" - -#: src/cthulhu/object_properties.py:46 -#, python-format -msgid "on %(index)d of %(total)d" -msgstr "於 %(total)d 中的 %(index)d" - -#: src/cthulhu/object_properties.py:51 -#, python-format -msgid "%(index)d of %(total)d" -msgstr "%(total)d 中的 %(index)d" - -#: src/cthulhu/object_properties.py:60 -#, python-format -msgid "item %(index)d" -msgstr "" - -#: src/cthulhu/object_properties.py:72 -#, python-format -msgid "LEVEL %d" -msgstr "第 %d 層" - -#: src/cthulhu/object_properties.py:76 -#, python-format -msgid "tree level %d" -msgstr "tree level %d" - -#: src/cthulhu/object_properties.py:80 -#, python-format -msgid "TREE LEVEL %d" -msgstr "TREE LEVEL %d" - -#: src/cthulhu/object_properties.py:94 -#, python-format -msgid "details for %s" -msgstr "" - -#: src/cthulhu/object_properties.py:109 -#, python-format -msgid "has details in %s" -msgstr "" - -#: src/cthulhu/object_properties.py:116 -#, fuzzy -msgctxt "role" -msgid "suggestion" -msgstr "問號" - -#: src/cthulhu/object_properties.py:123 -msgid "editable combo box" -msgstr "可編輯組合方塊" - -#: src/cthulhu/object_properties.py:129 -msgid "editable content" -msgstr "是否可編輯" - -#: src/cthulhu/object_properties.py:136 -msgctxt "role" -msgid "feed" -msgstr "" - -#: src/cthulhu/object_properties.py:143 -msgctxt "role" -msgid "figure" -msgstr "" - -#: src/cthulhu/object_properties.py:149 -msgctxt "role" -msgid "abstract" -msgstr "" - -#: src/cthulhu/object_properties.py:155 -#, fuzzy -msgctxt "role" -msgid "acknowledgments" -msgstr "1 的補數" - -#: src/cthulhu/object_properties.py:161 -#, fuzzy -msgctxt "role" -msgid "afterword" -msgstr "字詞" - -#: src/cthulhu/object_properties.py:167 -msgctxt "role" -msgid "appendix" -msgstr "" - -#: src/cthulhu/object_properties.py:173 -msgctxt "role" -msgid "bibliography entry" -msgstr "" - -#: src/cthulhu/object_properties.py:179 -msgctxt "role" -msgid "bibliography" -msgstr "" - -#: src/cthulhu/object_properties.py:185 -msgctxt "role" -msgid "chapter" -msgstr "" - -#: src/cthulhu/object_properties.py:191 -#, fuzzy -msgctxt "role" -msgid "colophon" -msgstr "冒號" - -#: src/cthulhu/object_properties.py:197 -msgctxt "role" -msgid "conclusion" -msgstr "" - -#: src/cthulhu/object_properties.py:203 -#, fuzzy -msgctxt "role" -msgid "cover" -msgstr "是否偏好圖示優於文字" - -#: src/cthulhu/object_properties.py:209 -msgctxt "role" -msgid "credit" -msgstr "" - -#: src/cthulhu/object_properties.py:215 -msgctxt "role" -msgid "credits" -msgstr "" - -#: src/cthulhu/object_properties.py:221 -#, fuzzy -msgctxt "role" -msgid "dedication" -msgstr "文字走向" - -#: src/cthulhu/object_properties.py:227 -msgctxt "role" -msgid "endnote" -msgstr "" - -#: src/cthulhu/object_properties.py:233 -msgctxt "role" -msgid "endnotes" -msgstr "" - -#: src/cthulhu/object_properties.py:239 -msgctxt "role" -msgid "epigraph" -msgstr "" - -#: src/cthulhu/object_properties.py:245 -msgctxt "role" -msgid "epilogue" -msgstr "" - -#: src/cthulhu/object_properties.py:251 -msgctxt "role" -msgid "errata" -msgstr "" - -#: src/cthulhu/object_properties.py:257 -msgctxt "role" -msgid "example" -msgstr "" - -#: src/cthulhu/object_properties.py:263 -#, fuzzy -msgctxt "role" -msgid "foreword" -msgstr "字詞" - -#: src/cthulhu/object_properties.py:269 -msgctxt "role" -msgid "glossary" -msgstr "" - -#: src/cthulhu/object_properties.py:275 -#, fuzzy -msgctxt "role" -msgid "index" -msgstr "縮排" - -#: src/cthulhu/object_properties.py:281 -#, fuzzy -msgctxt "role" -msgid "introduction" -msgstr "文字走向" - -#: src/cthulhu/object_properties.py:287 -msgctxt "role" -msgid "page break" -msgstr "" - -#: src/cthulhu/object_properties.py:293 -#, fuzzy -msgctxt "role" -msgid "page list" -msgstr "離開列表。" - -#: src/cthulhu/object_properties.py:299 -msgctxt "role" -msgid "part" -msgstr "" - -#: src/cthulhu/object_properties.py:305 -msgctxt "role" -msgid "preface" -msgstr "" - -#: src/cthulhu/object_properties.py:311 -msgctxt "role" -msgid "prologue" -msgstr "" - -#: src/cthulhu/object_properties.py:317 -#, fuzzy -msgctxt "role" -msgid "pullquote" -msgstr "引號" - -#: src/cthulhu/object_properties.py:326 -msgctxt "role" -msgid "QNA" -msgstr "" - -#: src/cthulhu/object_properties.py:332 -msgctxt "role" -msgid "subtitle" -msgstr "" - -#: src/cthulhu/object_properties.py:338 -#, fuzzy -msgctxt "role" -msgid "table of contents" -msgstr "啟用內容的配置模式" - -#: src/cthulhu/object_properties.py:344 -#, python-format -msgid "h%d" -msgstr "h%d" - -#: src/cthulhu/object_properties.py:349 -#, python-format -msgid "%(role)s level %(level)d" -msgstr "%(role)s 第 %(level)d 級" - -#: src/cthulhu/object_properties.py:356 -msgid "horizontal scroll bar" -msgstr "水平捲軸" - -#: src/cthulhu/object_properties.py:363 -msgid "vertical scroll bar" -msgstr "垂直捲軸" - -#: src/cthulhu/object_properties.py:372 -msgid "horizontal slider" -msgstr "水平滑動鈕" - -#: src/cthulhu/object_properties.py:381 -msgid "vertical slider" -msgstr "垂直滑動鈕" - -#: src/cthulhu/object_properties.py:393 -msgid "horizontal splitter" -msgstr "水平分隔" - -#: src/cthulhu/object_properties.py:405 -msgid "vertical splitter" -msgstr "垂直分隔" - -#: src/cthulhu/object_properties.py:411 -msgctxt "role" -msgid "switch" -msgstr "切換" - -#: src/cthulhu/object_properties.py:415 -msgid "Icon panel" -msgstr "圖示面板" - -#: src/cthulhu/object_properties.py:422 -msgctxt "role" -msgid "banner" -msgstr "橫幅" - -#: src/cthulhu/object_properties.py:430 -msgctxt "role" -msgid "complementary content" -msgstr "互補內容" - -#: src/cthulhu/object_properties.py:438 -msgctxt "role" -msgid "information" -msgstr "資訊" - -#: src/cthulhu/object_properties.py:444 -msgctxt "role" -msgid "main content" -msgstr "主要内容" - -#: src/cthulhu/object_properties.py:451 -msgctxt "role" -msgid "navigation" -msgstr "導覽" - -#: src/cthulhu/object_properties.py:460 -msgctxt "role" -msgid "region" -msgstr "區域" - -#: src/cthulhu/object_properties.py:467 -msgctxt "role" -msgid "search" -msgstr "搜尋" - -#: src/cthulhu/object_properties.py:474 -msgid "visited link" -msgstr "已瀏覽連結" - -#: src/cthulhu/object_properties.py:480 -msgid "menu button" -msgstr "選單按鈕" - -#: src/cthulhu/object_properties.py:484 -msgid "sorted ascending" -msgstr "" - -#: src/cthulhu/object_properties.py:488 -msgid "sorted descending" -msgstr "" - -#: src/cthulhu/object_properties.py:493 -msgid "sorted" -msgstr "" - -#: src/cthulhu/object_properties.py:497 -msgid "clickable" -msgstr "可按下" - -#: src/cthulhu/object_properties.py:502 -msgid "collapsed" -msgstr "已收起" - -#: src/cthulhu/object_properties.py:507 -msgid "expanded" -msgstr "已展開" - -#: src/cthulhu/object_properties.py:511 -msgid "has long description" -msgstr "具有長式描述" - -#: src/cthulhu/object_properties.py:515 -msgid "horizontal" -msgstr "水平" - -#: src/cthulhu/object_properties.py:519 -msgid "vertical" -msgstr "垂直的" - -#: src/cthulhu/object_properties.py:522 -msgctxt "checkbox" -msgid "checked" -msgstr "已點選" - -#: src/cthulhu/object_properties.py:525 -msgctxt "checkbox" -msgid "not checked" -msgstr "未點選" - -#: src/cthulhu/object_properties.py:529 -msgctxt "switch" -msgid "on" -msgstr "開" - -#: src/cthulhu/object_properties.py:533 -msgctxt "switch" -msgid "off" -msgstr "關" - -#: src/cthulhu/object_properties.py:536 -msgctxt "checkbox" -msgid "partially checked" -msgstr "部份選取" - -#: src/cthulhu/object_properties.py:539 -msgctxt "togglebutton" -msgid "pressed" -msgstr "已按下" - -#: src/cthulhu/object_properties.py:542 -msgctxt "togglebutton" -msgid "not pressed" -msgstr "未按下" - -#: src/cthulhu/object_properties.py:546 -#, fuzzy -msgctxt "listitem" -msgid "not selected" -msgstr "沒有選取" - -#: src/cthulhu/object_properties.py:549 -msgctxt "radiobutton" -msgid "selected" -msgstr "已選取" - -#: src/cthulhu/object_properties.py:552 -msgctxt "radiobutton" -msgid "not selected" -msgstr "沒有選取" - -#: src/cthulhu/object_properties.py:555 -msgctxt "tablecell" -msgid "not selected" -msgstr "沒有選取" - -#: src/cthulhu/object_properties.py:558 -msgctxt "link state" -msgid "visited" -msgstr "已瀏覽" - -#: src/cthulhu/object_properties.py:561 -msgctxt "link state" -msgid "unvisited" -msgstr "未瀏覽" - -#: src/cthulhu/object_properties.py:565 src/cthulhu/object_properties.py:569 -msgid "grayed" -msgstr "grayed" - -#: src/cthulhu/object_properties.py:576 -msgctxt "text" -msgid "read only" -msgstr "唯讀" - -#: src/cthulhu/object_properties.py:583 -msgctxt "text" -msgid "rdonly" -msgstr "唯讀" - -#: src/cthulhu/object_properties.py:587 src/cthulhu/object_properties.py:591 -msgid "required" -msgstr "必要的" - -#: src/cthulhu/object_properties.py:595 -msgid "multi-select" -msgstr "多重選取" - -#: src/cthulhu/object_properties.py:600 -msgctxt "error" -msgid "invalid entry" -msgstr "無效的項目" - -#: src/cthulhu/object_properties.py:607 -msgctxt "error" -msgid "invalid" -msgstr "無效" - -#: src/cthulhu/object_properties.py:612 -msgctxt "error" -msgid "invalid spelling" -msgstr "不正確的拼字" - -#: src/cthulhu/object_properties.py:618 -msgctxt "error" -msgid "spelling" -msgstr "拼字" - -#: src/cthulhu/object_properties.py:623 -#, fuzzy -msgctxt "error" -msgid "invalid grammar" -msgstr "無效" - -#: src/cthulhu/object_properties.py:629 -msgctxt "error" -msgid "grammar" -msgstr "" - -#: src/cthulhu/cthulhu-find.ui:7 -msgid "Find" -msgstr "尋找" - -#: src/cthulhu/cthulhu-find.ui:13 -msgid "Screen Reader Find Dialog" -msgstr "螢幕閱讀器尋找對話盒" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:29 -msgid "_Close" -msgstr "關閉(_C)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-find.ui:45 -msgid "_Find" -msgstr "尋找(_F)" - -#: src/cthulhu/cthulhu-find.ui:85 -msgid "_Search for:" -msgstr "搜尋字串(_S):" - -#: src/cthulhu/cthulhu-find.ui:92 src/cthulhu/cthulhu-find.ui:110 -msgid "Search for:" -msgstr "搜尋:" - -#: src/cthulhu/cthulhu-find.ui:166 -msgid "_Top of window" -msgstr "最上層視窗(_T)" - -#: src/cthulhu/cthulhu-find.ui:175 -msgid "Top of window" -msgstr "最上層視窗" - -#: src/cthulhu/cthulhu-find.ui:193 src/cthulhu/cthulhu-find.ui:196 -msgid "Start from:" -msgstr "開始自:" - -#: src/cthulhu/cthulhu-find.ui:226 -msgid "_Wrap around" -msgstr "回到檔案開始部份再搜尋(_W)" - -#: src/cthulhu/cthulhu-find.ui:242 -msgid "Search _backwards" -msgstr "向上搜尋(_B)" - -#: src/cthulhu/cthulhu-find.ui:263 -msgid "Search direction:" -msgstr "搜尋方向:" - -#: src/cthulhu/cthulhu-find.ui:291 -msgid "_Match case" -msgstr "符合大小寫(_M)" - -#: src/cthulhu/cthulhu-find.ui:306 -msgid "Match _entire word only" -msgstr "只符合整個字詞(_E)" - -#: src/cthulhu/cthulhu-find.ui:327 -msgid "Options:" -msgstr "「尋找」選項" - -#: src/cthulhu/cthulhu-setup.ui:43 -msgid "Default" -msgstr "預設" - -#: src/cthulhu/cthulhu-setup.ui:46 -msgid "Uppercase" -msgstr "大寫字母" - -#: src/cthulhu/cthulhu-setup.ui:49 -msgid "Hyperlink" -msgstr "超連結" - -#: src/cthulhu/cthulhu-setup.ui:52 -msgid "System" -msgstr "系統" - -#: src/cthulhu/cthulhu-setup.ui:80 -msgid "Application" -msgstr "應用程式" - -#: src/cthulhu/cthulhu-setup.ui:83 -msgid "Window" -msgstr "視窗" - -#: src/cthulhu/cthulhu-setup.ui:141 -msgid "Cthulhu Preferences" -msgstr "Cthulhu 偏好設定" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:158 -msgid "_Help" -msgstr "求助(_H)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:174 -msgid "_Apply" -msgstr "套用(_A)" - -#: src/cthulhu/cthulhu-setup.ui:272 -msgid "_Laptop" -msgstr "筆記本電腦(_L)" - -#: src/cthulhu/cthulhu-setup.ui:294 -msgid "Keyboard Layout" -msgstr "鍵盤配置" - -#: src/cthulhu/cthulhu-setup.ui:328 -msgid "Active _Profile:" -msgstr "使用中設定檔(_P):" - -#: src/cthulhu/cthulhu-setup.ui:345 -msgid "Start-up Profile:" -msgstr "啟動時設定檔:" - -#. This button will load the selected settings profile in the application. -#: src/cthulhu/cthulhu-setup.ui:393 -msgid "_Load" -msgstr "載入(_L)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:407 -msgid "Save _As" -msgstr "另存新檔(_A)" - -#. Translators: This is the label for a button in a dialog. -#: src/cthulhu/cthulhu-setup.ui:421 -msgid "_Remove" -msgstr "" - -#: src/cthulhu/cthulhu-setup.ui:450 -msgid "Profiles" -msgstr "設定檔" - -#: src/cthulhu/cthulhu-setup.ui:479 -msgid "_Present tooltips" -msgstr "顯示工具提示(_P)" - -#: src/cthulhu/cthulhu-setup.ui:495 -msgid "Speak object under mo_use" -msgstr "唸出滑鼠下方的物件(_U)" - -#: src/cthulhu/cthulhu-setup.ui:518 -msgid "Mouse" -msgstr "滑鼠" - -#: src/cthulhu/cthulhu-setup.ui:552 -msgid "_Time format:" -msgstr "時刻格式(_T):" - -#: src/cthulhu/cthulhu-setup.ui:569 -msgid "Dat_e format:" -msgstr "日期格式(_E):" - -#: src/cthulhu/cthulhu-setup.ui:625 -msgid "Time and Date" -msgstr "時刻和日期" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically speak the current percentage. -#: src/cthulhu/cthulhu-setup.ui:654 -msgid "_Speak updates" -msgstr "讀出更新(_S)" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically display the current percentage in braille. -#: src/cthulhu/cthulhu-setup.ui:673 -msgid "_Braille updates" -msgstr "點字更新(_B)" - -#: src/cthulhu/cthulhu-setup.ui:698 -msgid "10" -msgstr "10" - -#. Translators: Here this is a label for a spin button through which a user can customize the frequency in seconds an announcement should be made regarding the current value of a progress bar. -#: src/cthulhu/cthulhu-setup.ui:714 -msgctxt "ProgressBar" -msgid "Frequency (secs):" -msgstr "頻率 (秒):" - -#. Translators: Cthulhu has a setting which determines which progress bar updates should be announced. The options are all progress bars, only progress bars in the active application, or only progress bars in the current window. -#: src/cthulhu/cthulhu-setup.ui:728 -msgid "Applies to:" -msgstr "應用程式" - -#. Translators: This is an option in the Preferences dialog box related to the presentation of progress bar updates. If this checkbox is checked, Cthulhu will periodically emit beeps which increase in pitch as the value of the progress bar increases. -#: src/cthulhu/cthulhu-setup.ui:764 -msgid "Bee_p updates" -msgstr "嗶聲更新(_P)" - -#. Translators: This is a label in the Preferences dialog box. It applies to several options related to which progress bars Cthulhu should speak and how often Cthulhu should speak them. -#: src/cthulhu/cthulhu-setup.ui:789 -msgid "Progress Bar Updates" -msgstr "進度列更新" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if rewind and fast forward is enabled, Up Arrow and Down Arrow can be used within Say All to quickly move within the document to re-hear something which was just read or skip past something of no interest. -#: src/cthulhu/cthulhu-setup.ui:819 -msgid "Enable _rewind and fast forward in Say All" -msgstr "啟用 Say All 功能中的倒轉與快轉(_R)" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Normally, pressing any key will interrupt Say All presentation. However, if structural navigation is enabled for Say All, users can use commands such as H/Shift+H to jump to the next/previous heading, P/Shift+P to jump to the next/previous paragraph, T/Shift+T to jump to the next/previous table, and so on. Thus this setting is like fast forward and rewind, but with semantic awareness for web documents and similar content. -#: src/cthulhu/cthulhu-setup.ui:835 -msgid "Enable _structural navigation in Say All" -msgstr "在 Say All 啟用結構式瀏覽(_S)" - -#. Translators: Say all by refers to the way that Cthulhu will say (speak) an amount of text -- in particular, where Cthulhu where insert pauses. There are currently two choices (supplied by a combo box to the right of this label): say all by sentence and say all by line. If Cthulhu were speaking a work of fiction, it would probably be best to do say all by sentence so it sounds more natural. If Cthulhu were speaking something like a page of computer commands, doing a say all by line would work better. -#: src/cthulhu/cthulhu-setup.ui:861 -msgid "Say All B_y:" -msgstr "閱讀停頓於(_Y):" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered before speaking the text. At the end of the text, Cthulhu will announce that the blockquote is being exited. -#: src/cthulhu/cthulhu-setup.ui:900 -msgid "Announce block_quotes in Say All" -msgstr "在 Say All 中讀出區塊引號(_Q)" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered before speaking the content of that list. At the end of the list content, Cthulhu will announce that the list is being exited. -#: src/cthulhu/cthulhu-setup.ui:917 -msgid "Announce li_sts in Say All" -msgstr "在 Say All 中讀出列表(_S)" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered before speaking the content of that table. At the end of the table content, Cthulhu will announce that the table is being exited. -#: src/cthulhu/cthulhu-setup.ui:934 -msgid "Announce _tables in Say All" -msgstr "在 Say All 中讀出表格(_T)" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a panel has been entered before speaking the new location. At the end of the panel contents, Cthulhu will announce that the panel is being exited. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:951 -msgid "Announce _panels in Say All" -msgstr "在 Say All 中讀出面板(_P)" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce that a form has been entered before speaking the contents of that form. At the end of the form, Cthulhu will announce that the form is being exited. -#: src/cthulhu/cthulhu-setup.ui:968 -msgid "Announce _forms in Say All" -msgstr "在 Say All 中讀出表單(_F)" - -#. Translators: Cthulhu has a Say All feature which speaks the entire document. Some users want to hear additional information about what is being spoken. If this checkbox is checked, Cthulhu will announce when an ARIA landmark has been entered or exited. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:985 -msgid "Announce land_marks in Say All" -msgstr "在 Say All 中讀出地標(_M)" - -#: src/cthulhu/cthulhu-setup.ui:1008 -msgid "Say All" -msgstr "Say All" - -#. Translators: This is the label for a combo box where users can choose how Cthulhu presents element roles when a role sound is available. -#: src/cthulhu/cthulhu-setup.ui:1093 -msgid "Element _presentation:" -msgstr "元素呈現方式(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1154 -msgid "General" -msgstr "一般" - -#: src/cthulhu/cthulhu-setup.ui:1188 -msgid "Vo_lume:" -msgstr "音量(_L):" - -#: src/cthulhu/cthulhu-setup.ui:1236 -msgid "Pi_tch:" -msgstr "音調(_T):" - -#: src/cthulhu/cthulhu-setup.ui:1267 -msgid "_Rate:" -msgstr "速度(_R):" - -#: src/cthulhu/cthulhu-setup.ui:1293 -msgid "_Person:" -msgstr "朗讀者(_P):" - -#: src/cthulhu/cthulhu-setup.ui:1319 -msgid "_Language:" -msgstr "語言" - -#: src/cthulhu/cthulhu-setup.ui:1345 -msgid "Speech synthesi_zer:" -msgstr "朗讀合成器(_Z):" - -#: src/cthulhu/cthulhu-setup.ui:1371 -msgid "Speech _system:" -msgstr "朗讀系統(_S):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the combo box in which the user selects a voice type to configure. -#: src/cthulhu/cthulhu-setup.ui:1404 -msgid "_Voice type:" -msgstr "聲音類型(_T):" - -#. Translators: Cthulhu uses Speech Dispatcher to present content to users via text-to-speech. Speech Dispatcher has a feature to control how capital letters are presented: Do nothing at all; say the word 'capital' prior to presenting a capital letter (which Speech Dispatcher refers to as 'spell'), or play a tone (which Speech Dispatcher refers to as a sound 'icon'). Cthulhu refers to these things as 'capitalization style'. This string is the text of the label through which users can choose which of style they would prefer. -#: src/cthulhu/cthulhu-setup.ui:1418 -msgid "_Capitalization style:" -msgstr "大小寫樣式(_C):" - -#. Translators: Having multiple voice types in Cthulhu makes it possible for the user to more quickly identify properties of text non-visually, such as the fact that text is written in capital letters or is a link; or that text is actually visible on the screen as opposed to an Cthulhu-specific message. The available voice types in Cthulhu include: default, uppercase, hyperlink, and system -- each of which can be configured by the user to sound the way he/she finds most helpful. This string is displayed in the label for the group of all of the controls associated with configuring a particular voice type. -#: src/cthulhu/cthulhu-setup.ui:1454 -msgid "Voice Type Settings" -msgstr "語音類型設定值" - -#. Translators: multicase strings are StringsWithWordsMashedTogetherLikeThis. -#: src/cthulhu/cthulhu-setup.ui:1499 -msgid "Speak multicase strings as wor_ds" -msgstr "將混合大小寫的字串讀為一個字(_D)" - -#. Translators: If this setting is enabled, 123 will be spoken as the individual digits 1 2 3; otherwise, it will be sent to the synthesizer and (likely) spoken as one hundred and twenty three. -#: src/cthulhu/cthulhu-setup.ui:1515 -msgid "Speak _numbers as digits" -msgstr "將數字讀為阿拉伯數字(_N)" - -#: src/cthulhu/cthulhu-setup.ui:1540 -msgid "Global Voice Settings" -msgstr "全域語音設定值" - -#: src/cthulhu/cthulhu-setup.ui:1561 -msgid "Voice" -msgstr "聲音" - -#: src/cthulhu/cthulhu-setup.ui:1577 -msgid "_Enable speech" -msgstr "啟用朗讀(_E)" - -#: src/cthulhu/cthulhu-setup.ui:1637 src/cthulhu/cthulhu-setup.ui:2381 -msgid "Ver_bose" -msgstr "詳細(_B)" - -#: src/cthulhu/cthulhu-setup.ui:1659 src/cthulhu/cthulhu-setup.ui:2403 -msgid "Verbosity" -msgstr "詳細模式" - -#: src/cthulhu/cthulhu-setup.ui:1736 -msgid "_All" -msgstr "全部(_A)" - -#: src/cthulhu/cthulhu-setup.ui:1758 -msgid "Punctuation Level" -msgstr "標點層級" - -#. Translators: If this setting is enabled, Cthulhu will only speak text which is actually displayed on the screen. It will NOT speak things like the role of an item (e.g. checkbox) or its state (e.g. not checked) or say misspelled to indicate the presence of red squiggly spelling error lines -- things which Cthulhu normally speaks. This setting is primarily intended for low vision users and sighted users with a learning disability. -#: src/cthulhu/cthulhu-setup.ui:1799 -msgid "Only speak displayed text" -msgstr "只讀出顯示的文字" - -#: src/cthulhu/cthulhu-setup.ui:1819 -msgid "Speak blank lines" -msgstr "讀出空白的列" - -#: src/cthulhu/cthulhu-setup.ui:1835 -msgid "Speak _indentation and justification" -msgstr "讀出縮排及對齊(_I)" - -#: src/cthulhu/cthulhu-setup.ui:1850 -msgid "Spea_k object mnemonics" -msgstr "讀出物件助記符(_K)" - -#. Translators: This checkbox toggles whether or not Cthulhu says the child position (e.g., item 6 of 7). -#: src/cthulhu/cthulhu-setup.ui:1866 -msgid "Speak child p_osition" -msgstr "讀出子項位置(_O)" - -#: src/cthulhu/cthulhu-setup.ui:1882 -msgid "Speak tutorial messages" -msgstr "讀出教學訊息" - -#. Translators: Cthulhu has system messages which are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via speech, such as confirming the toggling of an Cthulhu setting via command. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer that brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:1898 -msgid "_System messages are detailed" -msgstr "讀出系統訊息詳細資料(_S)" - -#. Translators: Cthulhu has a command to present font and formatting information, including foreground and background color. The setting associated with this checkbox determines how Cthulhu will speak colors: As rgb values or as names (e.g. light blue). -#: src/cthulhu/cthulhu-setup.ui:1915 -msgid "S_peak colors as names" -msgstr "讀出顏色名稱(_P)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a blockquote has been entered as the user arrows into it and before speaking the text. Upon navigating out of the blockquote, Cthulhu will announce that the blockquote has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1932 -msgid "Announce block_quotes during navigation" -msgstr "在導覽過程中讀出區塊引號(_Q)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a list with x items has been entered as the user arrows into it and before speaking the list content. Upon navigating out of the list, Cthulhu will announce that the list has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1949 -msgid "Announce _lists during navigation" -msgstr "在導覽過程中讀出列表(_L)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a table with x rows and y columns has been entered as the user arrows into it and before speaking the table content. Upon navigating out of the table, Cthulhu will announce that the table has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:1966 -msgid "Announce _tables during navigation" -msgstr "在導覽過程中讀出表格(_T)" - -#. Translators: The misspelled-word indicator is the red squiggly line that appears underneath misspelled words in editable text fields. If this setting is enabled, when a user first moves into a word with this indicator, or types a misspelled word causing this indicator to appear, Cthulhu will announce that the word is misspelled. -#: src/cthulhu/cthulhu-setup.ui:1983 -msgid "Speak _misspelled-word indicator" -msgstr "讀出拼錯字詞指示(_M)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a panel has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the panel, Cthulhu will announce that the panel has been exited prior to speaking the new location. A panel is a generic container of objects, such as a group of related form fields. -#: src/cthulhu/cthulhu-setup.ui:2000 -msgid "Announce _panels during navigation" -msgstr "在導覽過程中讀出面板(_P)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce the ARIA landmark that has been entered as the user arrows into it and before speaking the text. Upon navigating out of the landmark, Cthulhu will announce that the landmark has been exited prior to speaking the new location. ARIA landmarks are the W3C defined HTML tag attribute 'role' used to identify important part of webpage like banners, main context, search, etc. -#: src/cthulhu/cthulhu-setup.ui:2017 -msgid "Announce land_marks during navigation" -msgstr "在導覽過程中讀出地標(_M)" - -#. Translators: Cthulhu can optionally speak additional details as the user navigates (e.g. via the arrow keys) within document content. If this checkbox is checked, Cthulhu will announce that a form has been entered as the user arrows into it and before speaking the new location. Upon navigating out of the form, Cthulhu will announce that the form has been exited prior to speaking the new location. -#: src/cthulhu/cthulhu-setup.ui:2034 -msgid "Announce _forms during navigation" -msgstr "在導覽過程中讀出表單(_F)" - -#. Translators: If this checkbox is checked, Cthulhu will speak the accessible description of an object. Whereas the accessible name of an object tends to be short and typically corresponds to what is displayed on screen, the contents of the accessible description tend to be longer, e.g. matching the text of the tooltip, and are sometimes redundant to the accessible name. Therefore, we allow the user to opt out of this additional information. -#: src/cthulhu/cthulhu-setup.ui:2051 -msgid "Speak _description" -msgstr "讀出描述(_D)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a spreadsheet. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2074 -msgid "Speak full row in sp_readsheets" -msgstr "在試算表中讀出完整的列(_R)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a document table. In this context, document tables include tables such as those found in Writer documents as well as HTML table elements, but exclude spreadsheet tables such as found in Calc. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2091 -msgid "Speak full row in _document tables" -msgstr "在文件中讀出完整的列(_D)" - -#. Translators: This checkbox is associated with the setting that determines what happens if a user presses Up or Down arrow to move row by row in a GUI table, such as a GtkTreeView. Document tables, such as those found in Writer and web content, and spreadsheet tables such as those found in Calc are not considered GUI tables. If this setting is enabled, Cthulhu will speak the entire row; if it is disabled, Cthulhu will only speak the cell with focus. -#: src/cthulhu/cthulhu-setup.ui:2108 -msgid "Speak full row in _GUI tables" -msgstr "在 _GUI 表格中讀出完整的列" - -#: src/cthulhu/cthulhu-setup.ui:2131 -msgid "Spoken Context" -msgstr "讀出的內容" - -#: src/cthulhu/cthulhu-setup.ui:2167 -msgid "Speech" -msgstr "朗讀" - -#: src/cthulhu/cthulhu-setup.ui:2187 -msgid "Enable Braille _support" -msgstr "啟用點字支援(_S)" - -#: src/cthulhu/cthulhu-setup.ui:2230 -msgid "_Abbreviated role names" -msgstr "縮寫任務名稱(_A)" - -#: src/cthulhu/cthulhu-setup.ui:2245 -msgid "Disable _end of line symbol" -msgstr "停用行尾符號(_E)" - -#. Translators: This string is associated with a combo box which allows the user to select the set of symbols to be used when Cthulhu presents print strings on a refreshable braille display. Braille symbols vary from language to language due in part to what print letters exist for that language. The other reason braille symbols vary is due to which braille contractions get used. Contractions are shorter forms of commonly-used letter combinations and words. For instance in English there is a single braille symbol for ing (dots 3-4-6), and the letter e (dots 1-5) all by itself represents the word every. The list of rules which dictate what contractions should be used and whether or not they can be used in a particular context are stored in tables provided by liblouis. -#: src/cthulhu/cthulhu-setup.ui:2269 -msgid "Contraction _Table:" -msgstr "縮短表(_T):" - -#: src/cthulhu/cthulhu-setup.ui:2300 -msgid "_Enable Contracted Braille" -msgstr "啟用縮短式點字(_E)" - -#. Translators: If this option is enabled, Cthulhu will adjust the text shown on the braille display so that only full words are shown. If it is not enabled, Cthulhu uses all of the cells on the display, but some words might not be fully shown requiring the user to scroll to see the remainder. -#: src/cthulhu/cthulhu-setup.ui:2315 -msgid "Enable _word wrap" -msgstr "啟用字詞回響(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2336 -msgid "Display Settings" -msgstr "顯示設定值" - -#. Translators: This option refers to the dot or dots in braille which will be used to underline certain characters. -#: src/cthulhu/cthulhu-setup.ui:2433 src/cthulhu/cthulhu-setup.ui:2533 -#: src/cthulhu/cthulhu-setup.ui:3452 -msgctxt "braille dots" -msgid "_None" -msgstr "沒有(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2503 -msgid "Selection Indicator" -msgstr "選擇區域指示器" - -#: src/cthulhu/cthulhu-setup.ui:2603 -msgid "Hyperlink Indicator" -msgstr "超連結指示器" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements in that they are temporarily shown on the refreshable braille display. Upon removal of the message, the original contents of the braille display are restored. This checkbox allows the user to toggle this feature. -#: src/cthulhu/cthulhu-setup.ui:2632 -msgid "Enable flash _messages" -msgstr "啟用閃動訊息(_M)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. This label is for the spin button through which a user can customize how long (in seconds) these temporary messages should be displayed. -#: src/cthulhu/cthulhu-setup.ui:2655 -msgid "D_uration (secs):" -msgstr "訊息持續時間[秒](_G):" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. Some users, however, would prefer to have the message remain displayed until they explicitly dismiss it. This can be accomplished by making flash messages persistent by checking this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2689 -msgid "Messages are _persistent" -msgstr "訊息為持續顯示(_P)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. In instances where the message to be displayed is long/detailed, Cthulhu provides a brief alternative. Users who prefer the brief alternative can uncheck this checkbox. -#: src/cthulhu/cthulhu-setup.ui:2706 -msgid "Messages are _detailed" -msgstr "訊息為詳細資料(_D)" - -#. Translators: Braille flash messages are similar in nature to notifications or announcements. They are most commonly used for Cthulhu to communicate Cthulhu-specific information to the user via braille, such as confirming the toggling of an Cthulhu setting via command. The reason they are called flash messages by screen readers is that they are shown on the refreshable braille display for only a brief time, after which the original contents of the display are restored. -#: src/cthulhu/cthulhu-setup.ui:2729 -msgid "Flash Message Settings" -msgstr "閃動訊息設定值" - -#: src/cthulhu/cthulhu-setup.ui:2766 -msgid "Braille" -msgstr "點字" - -#: src/cthulhu/cthulhu-setup.ui:2780 -msgid "Enable _key echo" -msgstr "啟用按鍵回響(_K)" - -#: src/cthulhu/cthulhu-setup.ui:2804 -msgid "Enable _alphabetic keys" -msgstr "啟用「彈跳鍵」" - -#: src/cthulhu/cthulhu-setup.ui:2819 -msgid "Enable n_umeric keys" -msgstr "啟用「彈跳鍵」" - -#: src/cthulhu/cthulhu-setup.ui:2834 -msgid "Enable _punctuation keys" -msgstr "啟用「彈跳鍵」" - -#: src/cthulhu/cthulhu-setup.ui:2849 -msgid "Enable _space" -msgstr "啟用空白(_S)" - -#: src/cthulhu/cthulhu-setup.ui:2864 -msgid "Enable _modifier keys" -msgstr "啟用修改鍵(_M)" - -#: src/cthulhu/cthulhu-setup.ui:2879 -msgid "Enable _function keys" -msgstr "啟用功能鍵(_F)" - -#: src/cthulhu/cthulhu-setup.ui:2894 -msgid "Enable ac_tion keys" -msgstr "啟用動作鍵(_T)" - -#: src/cthulhu/cthulhu-setup.ui:2909 -msgid "Enable _navigation keys" -msgstr "啟用導覽鍵(_N)" - -#: src/cthulhu/cthulhu-setup.ui:2965 -msgid "Enable echo by _word" -msgstr "啟用字詞回響(_W)" - -#: src/cthulhu/cthulhu-setup.ui:2980 -msgid "Enable echo by _sentence" -msgstr "啟用句子回響(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3002 -msgid "Echo" -msgstr "按鍵回響" - -#: src/cthulhu/cthulhu-setup.ui:3026 -msgid "Screen Reader _Modifier Key(s):" -msgstr "螢幕閱讀器修改鍵(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3094 -msgid "Key Bindings" -msgstr "按鍵組合" - -#: src/cthulhu/cthulhu-setup.ui:3143 -msgid "Pronunciation Dictionary" -msgstr "發音字典" - -#: src/cthulhu/cthulhu-setup.ui:3161 -msgid "_New entry" -msgstr "新項目(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3176 -msgid "_Delete" -msgstr "刪除(_D)" - -#: src/cthulhu/cthulhu-setup.ui:3204 -msgid "Pronunciation" -msgstr "發音" - -#: src/cthulhu/cthulhu-setup.ui:3243 -msgid "_Speak all" -msgstr "全部讀出(_S)" - -#: src/cthulhu/cthulhu-setup.ui:3257 -msgid "Speak _none" -msgstr "讀出「沒有」(_N)" - -#: src/cthulhu/cthulhu-setup.ui:3271 -msgid "_Reset" -msgstr "重設(_R)" - -#: src/cthulhu/cthulhu-setup.ui:3322 -msgid "Text attributes" -msgstr "文字屬性" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _bottom button, move that attribute to the bottom of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3356 -msgid "Move to _bottom" -msgstr "移至底部(_B)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _down one button, move that attribute down one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3371 -msgid "Move _down one" -msgstr "下移一列(_D)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move _up one button, move that attribute up one line in the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3386 -msgid "Move _up one" -msgstr "上移一列(_U)" - -#. Translators: This label is on a button on the Text Attributes pane of the Cthulhu Preferences dialog. On that pane there is a long list of possible text attributes. The user can select one and then, by using the Move to _top button, move that attribute to the top of the list. The ordering in the list is important as Cthulhu will speak the selected text attributes in the given order. -#: src/cthulhu/cthulhu-setup.ui:3401 -msgid "Move to _top" -msgstr "移至頂端(_T)" - -#: src/cthulhu/cthulhu-setup.ui:3422 -msgid "Adjust selected attribute" -msgstr "調整選取的屬性" - -#: src/cthulhu/cthulhu-setup.ui:3522 -msgid "Braille Indicator" -msgstr "點字指示器" - -#: src/cthulhu/cthulhu-setup.ui:3549 -msgid "Text Attributes" -msgstr "文字屬性" - -#: src/cthulhu/cthulhu-setup.ui:3568 -msgid "Enable AI Assistant" -msgstr "啟用 AI 助理" - -#: src/cthulhu/cthulhu-setup.ui:3587 -msgid "_Provider:" -msgstr "提供者(_P):" - -#: src/cthulhu/cthulhu-setup.ui:3602 -msgid "Claude Code (CLI)" -msgstr "Claude Code (命令列)" - -#: src/cthulhu/cthulhu-setup.ui:3603 -msgid "Codex (CLI)" -msgstr "Codex (命令列)" - -#: src/cthulhu/cthulhu-setup.ui:3604 -msgid "Gemini (Google)" -msgstr "Gemini (Google)" - -#: src/cthulhu/cthulhu-setup.ui:3605 -msgid "Ollama (Local - Free)" -msgstr "Ollama (本機 - 免費)" - -#: src/cthulhu/cthulhu-setup.ui:3619 -msgid "API _Key File:" -msgstr "API 金鑰檔案(_K):" - -#: src/cthulhu/cthulhu-setup.ui:3638 -msgid "Path to API key file" -msgstr "API 金鑰檔案路徑" - -#: src/cthulhu/cthulhu-setup.ui:3649 -msgid "Get _Claude API Key" -msgstr "取得 _Claude API 金鑰" - -#: src/cthulhu/cthulhu-setup.ui:3654 -msgid "Open browser to get Claude API key and save automatically" -msgstr "開啟瀏覽器以取得 Claude API 金鑰並自動儲存" - -#: src/cthulhu/cthulhu-setup.ui:3671 -msgid "Require confirmation before AI actions" -msgstr "在執行 AI 動作前需要確認" - -#: src/cthulhu/cthulhu-setup.ui:3691 -msgid "Ollama _Model:" -msgstr "Ollama 模型(_M):" - -#: src/cthulhu/cthulhu-setup.ui:3706 -msgid "Model name for Ollama (e.g., llama3.2-vision)" -msgstr "Ollama 模型名稱(例如 llama3.2-vision)" - -#: src/cthulhu/cthulhu-setup.ui:3719 -msgid "Ollama _Endpoint:" -msgstr "Ollama 端點(_E):" - -#: src/cthulhu/cthulhu-setup.ui:3734 -msgid "Ollama API endpoint URL (e.g., http://192.168.1.100:11434)" -msgstr "Ollama API 端點 URL(例如 http://192.168.1.100:11434)" - -#: src/cthulhu/cthulhu-setup.ui:3747 -msgid "Screenshot _Quality:" -msgstr "螢幕截圖品質(_Q):" - -#: src/cthulhu/cthulhu-setup.ui:3763 -msgid "Low" -msgstr "低" - -#: src/cthulhu/cthulhu-setup.ui:3764 -msgid "Medium" -msgstr "中等" - -#: src/cthulhu/cthulhu-setup.ui:3765 -msgid "High" -msgstr "高" - -#: src/cthulhu/cthulhu-setup.ui:3783 -msgid "AI Assistant" -msgstr "AI 助理" - -#: src/cthulhu/cthulhu-setup.ui:3805 -msgid "_Language Code:" -msgstr "語言代碼(_L):" - -#: src/cthulhu/cthulhu-setup.ui:3818 -msgid "eng" -msgstr "eng" - -#: src/cthulhu/cthulhu-setup.ui:3831 -msgid "_Scale Factor:" -msgstr "縮放係數(_S):" - -#: src/cthulhu/cthulhu-setup.ui:3855 -msgid "_Grayscale Image" -msgstr "灰階影像(_G)" - -#: src/cthulhu/cthulhu-setup.ui:3871 -msgid "_Invert Image" -msgstr "反轉影像(_I)" - -#: src/cthulhu/cthulhu-setup.ui:3887 -msgid "_Black and White Image" -msgstr "黑白影像(_B)" - -#: src/cthulhu/cthulhu-setup.ui:3906 -msgid "Black/White _Threshold:" -msgstr "黑白閾值(_T):" - -#: src/cthulhu/cthulhu-setup.ui:3930 -msgid "_Analyze Colors" -msgstr "分析顏色(_A)" - -#: src/cthulhu/cthulhu-setup.ui:3946 -msgid "Copy Results to _Clipboard" -msgstr "將結果複製到剪貼簿(_C)" - -#: src/cthulhu/cthulhu-setup.ui:3969 -msgid "OCR" -msgstr "OCR" - -#: src/cthulhu/phonnames.py:59 -msgid "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" -msgstr "" -"a : alpha, b : bravo, c : charlie, d : delta, e : echo, f : foxtrot, g : " -"golf, h : hotel, i : india, j : juliet, k : kilo, l : lima, m : mike, n : " -"november, o : oscar, p : papa, q : quebec, r : romeo, s : sierra, t : tango, " -"u : uniform, v : victor, w : whiskey, x : xray, y : yankee, z : zulu" - -#: src/cthulhu/text_attribute_names.py:67 -msgctxt "textattr" -msgid "background color" -msgstr "背景顏色" - -#: src/cthulhu/text_attribute_names.py:76 -msgctxt "textattr" -msgid "background full height" -msgstr "背景完整高度" - -#: src/cthulhu/text_attribute_names.py:83 -msgctxt "textattr" -msgid "background stipple" -msgstr "背景點狀遮罩" - -#: src/cthulhu/text_attribute_names.py:90 -msgctxt "textattr" -msgid "direction" -msgstr "文字走向" - -#: src/cthulhu/text_attribute_names.py:97 -msgctxt "textattr" -msgid "editable" -msgstr "是否可編輯" - -#: src/cthulhu/text_attribute_names.py:103 -msgctxt "textattr" -msgid "family name" -msgstr "字型族系名稱" - -#: src/cthulhu/text_attribute_names.py:110 -msgctxt "textattr" -msgid "foreground color" -msgstr "前景顏色" - -#: src/cthulhu/text_attribute_names.py:117 -msgctxt "textattr" -msgid "foreground stipple" -msgstr "前景點狀遮罩" - -#: src/cthulhu/text_attribute_names.py:125 -msgctxt "textattr" -msgid "font effect" -msgstr "字型效果" - -#: src/cthulhu/text_attribute_names.py:132 -msgctxt "textattr" -msgid "indent" -msgstr "縮排" - -#: src/cthulhu/text_attribute_names.py:138 -msgctxt "textattr" -msgid "mistake" -msgstr "失誤" - -#: src/cthulhu/text_attribute_names.py:149 -msgctxt "textattr" -msgid "invisible" -msgstr "隱形" - -#: src/cthulhu/text_attribute_names.py:156 -msgctxt "textattr" -msgid "justification" -msgstr "對齊" - -#: src/cthulhu/text_attribute_names.py:163 -msgctxt "textattr" -msgid "language" -msgstr "語言" - -#: src/cthulhu/text_attribute_names.py:169 -msgctxt "textattr" -msgid "left margin" -msgstr "左邊界" - -#: src/cthulhu/text_attribute_names.py:176 -msgctxt "textattr" -msgid "line height" -msgstr "行高" - -#: src/cthulhu/text_attribute_names.py:186 -msgctxt "textattr" -msgid "paragraph style" -msgstr "段落樣式" - -#: src/cthulhu/text_attribute_names.py:193 -msgctxt "textattr" -msgid "pixels above lines" -msgstr "列頂端空間" - -#: src/cthulhu/text_attribute_names.py:200 -msgctxt "textattr" -msgid "pixels below lines" -msgstr "列底部空間" - -#: src/cthulhu/text_attribute_names.py:208 -msgctxt "textattr" -msgid "pixels inside wrap" -msgstr "換列時加上的像素" - -#: src/cthulhu/text_attribute_names.py:214 -msgctxt "textattr" -msgid "right margin" -msgstr "右邊界" - -#: src/cthulhu/text_attribute_names.py:221 -msgctxt "textattr" -msgid "rise" -msgstr "抬升" - -#: src/cthulhu/text_attribute_names.py:228 -msgctxt "textattr" -msgid "scale" -msgstr "縮放" - -#: src/cthulhu/text_attribute_names.py:234 -msgctxt "textattr" -msgid "size" -msgstr "大小" - -#: src/cthulhu/text_attribute_names.py:243 -msgctxt "textattr" -msgid "stretch" -msgstr "延伸" - -#: src/cthulhu/text_attribute_names.py:251 -msgctxt "textattr" -msgid "strike through" -msgstr "刪除線" - -#: src/cthulhu/text_attribute_names.py:258 -msgctxt "textattr" -msgid "style" -msgstr "樣式" - -#: src/cthulhu/text_attribute_names.py:265 -msgctxt "textattr" -msgid "text decoration" -msgstr "文字裝飾" - -#: src/cthulhu/text_attribute_names.py:274 -msgctxt "textattr" -msgid "text rotation" -msgstr "文字旋轉" - -#: src/cthulhu/text_attribute_names.py:281 -msgctxt "textattr" -msgid "text shadow" -msgstr "文字陰影" - -#: src/cthulhu/text_attribute_names.py:288 -msgctxt "textattr" -msgid "underline" -msgstr "底線" - -#: src/cthulhu/text_attribute_names.py:295 -msgctxt "textattr" -msgid "variant" -msgstr "大小寫" - -#: src/cthulhu/text_attribute_names.py:302 -msgctxt "textattr" -msgid "vertical align" -msgstr "垂直對齊" - -#: src/cthulhu/text_attribute_names.py:309 -msgctxt "textattr" -msgid "weight" -msgstr "字重" - -#: src/cthulhu/text_attribute_names.py:316 -msgctxt "textattr" -msgid "wrap mode" -msgstr "換列模式" - -#: src/cthulhu/text_attribute_names.py:325 -msgctxt "textattr" -msgid "writing mode" -msgstr "書寫模式" - -#: src/cthulhu/text_attribute_names.py:341 -msgctxt "textattr" -msgid "true" -msgstr "true" - -#: src/cthulhu/text_attribute_names.py:349 -msgctxt "textattr" -msgid "false" -msgstr "false" - -#: src/cthulhu/text_attribute_names.py:358 -msgctxt "textattr" -msgid "none" -msgstr "none" - -#: src/cthulhu/text_attribute_names.py:365 -msgctxt "textattr" -msgid "engrave" -msgstr "牢記" - -#: src/cthulhu/text_attribute_names.py:372 -msgctxt "textattr" -msgid "emboss" -msgstr "浮雕" - -#: src/cthulhu/text_attribute_names.py:379 -msgctxt "textattr" -msgid "outline" -msgstr "輪廓" - -#: src/cthulhu/text_attribute_names.py:386 -msgctxt "textattr" -msgid "overline" -msgstr "加頂線" - -#: src/cthulhu/text_attribute_names.py:393 -msgctxt "textattr" -msgid "line through" -msgstr "刪除線" - -#: src/cthulhu/text_attribute_names.py:400 -msgctxt "textattr" -msgid "blink" -msgstr "閃爍" - -#: src/cthulhu/text_attribute_names.py:407 -msgctxt "textattr" -msgid "black" -msgstr "黑色" - -#: src/cthulhu/text_attribute_names.py:414 -msgctxt "textattr" -msgid "single" -msgstr "單線" - -#: src/cthulhu/text_attribute_names.py:421 -msgctxt "textattr" -msgid "double" -msgstr "雙線" - -#: src/cthulhu/text_attribute_names.py:428 -msgctxt "textattr" -msgid "low" -msgstr "低" - -#: src/cthulhu/text_attribute_names.py:435 -msgctxt "textattr" -msgid "char" -msgstr "字元" - -#: src/cthulhu/text_attribute_names.py:442 -msgctxt "textattr" -msgid "word" -msgstr "文字" - -#: src/cthulhu/text_attribute_names.py:452 -msgctxt "textattr" -msgid "word char" -msgstr "字元" - -#: src/cthulhu/text_attribute_names.py:459 -msgctxt "textattr" -msgid "ltr" -msgstr "左至右" - -#: src/cthulhu/text_attribute_names.py:466 -msgctxt "textattr" -msgid "rtl" -msgstr "右至左" - -#: src/cthulhu/text_attribute_names.py:473 -msgctxt "textattr" -msgid "left" -msgstr "靠左" - -#: src/cthulhu/text_attribute_names.py:480 -msgctxt "textattr" -msgid "right" -msgstr "靠右" - -#: src/cthulhu/text_attribute_names.py:487 -msgctxt "textattr" -msgid "center" -msgstr "置中" - -#: src/cthulhu/text_attribute_names.py:493 -msgctxt "textattr" -msgid "no justification" -msgstr "不使用對齊" - -#: src/cthulhu/text_attribute_names.py:500 -msgctxt "textattr" -msgid "fill" -msgstr "左右對齊" - -#: src/cthulhu/text_attribute_names.py:507 -msgctxt "textattr" -msgid "ultra condensed" -msgstr "極窄" - -#: src/cthulhu/text_attribute_names.py:514 -msgctxt "textattr" -msgid "extra condensed" -msgstr "很窄" - -#: src/cthulhu/text_attribute_names.py:521 -msgctxt "textattr" -msgid "condensed" -msgstr "窄" - -#: src/cthulhu/text_attribute_names.py:528 -msgctxt "textattr" -msgid "semi condensed" -msgstr "有點窄" - -#: src/cthulhu/text_attribute_names.py:535 -msgctxt "textattr" -msgid "normal" -msgstr "一般" - -#: src/cthulhu/text_attribute_names.py:542 -msgctxt "textattr" -msgid "semi expanded" -msgstr "有點寛" - -#: src/cthulhu/text_attribute_names.py:549 -msgctxt "textattr" -msgid "expanded" -msgstr "寛" - -#: src/cthulhu/text_attribute_names.py:556 -msgctxt "textattr" -msgid "extra expanded" -msgstr "很寛" - -#: src/cthulhu/text_attribute_names.py:563 -msgctxt "textattr" -msgid "ultra expanded" -msgstr "極寛" - -#: src/cthulhu/text_attribute_names.py:570 -msgctxt "textattr" -msgid "small caps" -msgstr "小寫" - -#: src/cthulhu/text_attribute_names.py:577 -msgctxt "textattr" -msgid "oblique" -msgstr "傾斜" - -#: src/cthulhu/text_attribute_names.py:584 -msgctxt "textattr" -msgid "italic" -msgstr "斜體" - -#: src/cthulhu/text_attribute_names.py:591 -msgctxt "textattr" -msgid "Default" -msgstr "預設值" - -#: src/cthulhu/text_attribute_names.py:598 -msgctxt "textattr" -msgid "Text body" -msgstr "內文" - -#: src/cthulhu/text_attribute_names.py:605 -msgctxt "textattr" -msgid "Heading" -msgstr "標題" - -#: src/cthulhu/text_attribute_names.py:613 -msgctxt "textattr" -msgid "baseline" -msgstr "基線" - -#: src/cthulhu/text_attribute_names.py:620 -msgctxt "textattr" -msgid "sub" -msgstr "下標" - -#: src/cthulhu/text_attribute_names.py:627 -msgctxt "textattr" -msgid "super" -msgstr "上標" - -#: src/cthulhu/text_attribute_names.py:634 -msgctxt "textattr" -msgid "top" -msgstr "頂端" - -#: src/cthulhu/text_attribute_names.py:641 -msgctxt "textattr" -msgid "text-top" -msgstr "文字頂端" - -#: src/cthulhu/text_attribute_names.py:648 -msgctxt "textattr" -msgid "middle" -msgstr "中間" - -#: src/cthulhu/text_attribute_names.py:655 -msgctxt "textattr" -msgid "bottom" -msgstr "底部" - -#: src/cthulhu/text_attribute_names.py:662 -msgctxt "textattr" -msgid "text-bottom" -msgstr "文字底部" - -#: src/cthulhu/text_attribute_names.py:670 -msgctxt "textattr" -msgid "inherit" -msgstr "繼承" - -#: src/cthulhu/text_attribute_names.py:677 -msgctxt "textattr" -msgid "lr-tb" -msgstr "lr-tb" - -#: src/cthulhu/text_attribute_names.py:684 -msgctxt "textattr" -msgid "rl-tb" -msgstr "rl-tb" - -#: src/cthulhu/text_attribute_names.py:691 -msgctxt "textattr" -msgid "tb-rl" -msgstr "tb-rl" - -#: src/cthulhu/text_attribute_names.py:698 -msgctxt "textattr" -msgid "tb-lr" -msgstr "tb-lr" - -#: src/cthulhu/text_attribute_names.py:705 -msgctxt "textattr" -msgid "bt-rl" -msgstr "bt-rl" - -#: src/cthulhu/text_attribute_names.py:712 -msgctxt "textattr" -msgid "bt-lr" -msgstr "bt-lr" - -#: src/cthulhu/text_attribute_names.py:719 -msgctxt "textattr" -msgid "lr" -msgstr "lr" - -#: src/cthulhu/text_attribute_names.py:726 -msgctxt "textattr" -msgid "rl" -msgstr "rl" - -#: src/cthulhu/text_attribute_names.py:733 -msgctxt "textattr" -msgid "tb" -msgstr "tb" - -#: src/cthulhu/text_attribute_names.py:738 -msgctxt "textattr" -msgid "solid" -msgstr "固定" - -#: src/cthulhu/text_attribute_names.py:745 -#: src/cthulhu/text_attribute_names.py:750 -msgctxt "textattr" -msgid "spelling" -msgstr "拼字" - -#: src/cthulhu/tutorialgenerator.py:173 -msgid "Press space to toggle." -msgstr "按下空白鍵切換。" - -#: src/cthulhu/tutorialgenerator.py:200 -msgid "Press space to expand, and use up and down to select an item." -msgstr "使用空白鍵展開,並使用上或下方向鍵來選擇項目。" - -#: src/cthulhu/tutorialgenerator.py:228 -msgid "Press alt+f6 to give focus to child windows." -msgstr "按下 alt+f6 將焦點集中至子視窗。" - -#: src/cthulhu/tutorialgenerator.py:290 -msgid "To move to items, use either the arrow keys or type ahead searching." -msgstr "要移至某項目,可使用方向鍵或輸入搜尋。" - -#: src/cthulhu/tutorialgenerator.py:296 -msgid "To get to the system menus press the alt+f1 key." -msgstr "要使用系統選單,請按 alt+f1 鍵。" - -#: src/cthulhu/tutorialgenerator.py:330 -msgid "Use up and down to select an item." -msgstr "使用上或下方向鍵來選擇項目。" - -#: src/cthulhu/tutorialgenerator.py:360 src/cthulhu/tutorialgenerator.py:539 -msgid "To collapse, press shift plus left." -msgstr "要摺疊,按下 shift 加上左方向鍵。" - -#: src/cthulhu/tutorialgenerator.py:366 src/cthulhu/tutorialgenerator.py:545 -msgid "To expand, press shift plus right." -msgstr "要展開,按下 shift 加上右方向鍵。" - -#: src/cthulhu/tutorialgenerator.py:397 -msgid "To activate press return." -msgstr "要使用請按 enter。" - -#: src/cthulhu/tutorialgenerator.py:427 -msgid "Type in text." -msgstr "輸入文字。" - -#: src/cthulhu/tutorialgenerator.py:455 -msgid "Use left and right to view other tabs." -msgstr "使用左和右方向鍵來檢視其他分頁。" - -#: src/cthulhu/tutorialgenerator.py:480 -msgid "To activate press space." -msgstr "要使用請按空白鍵。" - -#: src/cthulhu/tutorialgenerator.py:508 -msgid "" -"Use up or down arrow to select value. Or type in the desired numerical value." -msgstr "使用上或下方向鍵來選擇數值。或直接輸入想要的數字值。" - -#: src/cthulhu/tutorialgenerator.py:648 -msgid "Use arrow keys to change." -msgstr "使用方向鍵來變更。" - -#: src/cthulhu/tutorialgenerator.py:673 -msgid "" -"To navigate, press left or right arrow. To move through items press up or " -"down arrow." -msgstr "要導覽請按左或右方向鍵。要移動至項目請按上或下方向鍵。" - -#: src/cthulhu/tutorialgenerator.py:678 -msgid "To enter sub menu, press right arrow." -msgstr "要進入子選單,請按右方向鍵。" - -#: src/cthulhu/tutorialgenerator.py:713 -msgid "" -"To decrease press left arrow, to increase press right arrow. To go to " -"minimum press home, and for maximum press end." -msgstr "要減少按左方向鍵,增加按右方向鍵。要少按 home 按鍵,多按 end 按鍵。" diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 2e31090..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,35 +0,0 @@ -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[project] -name = "cthulhu" -dynamic = ["version"] -description = "Fork of the Orca screen reader" -readme = "README.md" -requires-python = ">=3.9" -license = { text = "LGPL-2.1-or-later" } -dependencies = [ - "pygobject>=3.18", - "pluggy", - "tomlkit", - "brlapi; extra == 'braille'", - "python-speechd; extra == 'speech'", - "piper-tts; extra == 'piper'", - "louis; extra == 'braille'" -] - -[project.optional-dependencies] -wayland = [ - "pywayland" -] - -[project.scripts] -cthulhu = "cthulhu.cthulhu:main" - -[tool.hatch.version] -path = "src/cthulhu/__init__.py" - -[tool.hatch.build.targets.wheel] -packages = ["src/cthulhu"] -include = ["src/cthulhu/*.ui"] diff --git a/scripts/build-wine-access.sh b/scripts/build-wine-access.sh deleted file mode 100644 index e591439..0000000 --- a/scripts/build-wine-access.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -sourceDir=$1 -buildDir=$2 -launcherOutput=$3 -binaryOutput=$4 - -cmake \ - -S "$sourceDir" \ - -B "$buildDir" \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_TOOLCHAIN_FILE="$sourceDir/winelib-toolchain.cmake" -cmake --build "$buildDir" --parallel -cmake -E copy "$buildDir/cthulhu-wine-access.exe" "$launcherOutput" -cmake -E copy "$buildDir/cthulhu-wine-access.exe.so" "$binaryOutput" diff --git a/sdk/go/tentacle/tentacle.go b/sdk/go/tentacle/tentacle.go new file mode 100644 index 0000000..6c1c3d9 --- /dev/null +++ b/sdk/go/tentacle/tentacle.go @@ -0,0 +1,277 @@ +// Copyright (c) 2026 Storm Dragon +// SPDX-License-Identifier: GPL-3.0-or-later + +// Package tentacle implements the experimental command, presentation and interaction SDK. +// It has no reader, input, or output backend dependencies. +package tentacle + +import ( + "bufio" + "context" + "encoding/json" + "errors" + "git.stormux.org/storm/cthulhu/internal/config" + "io" + "strconv" + "sync" + + "git.stormux.org/storm/cthulhu/internal/interaction" + "git.stormux.org/storm/cthulhu/internal/tentaclewire" +) + +type Binding struct { + Layout string `json:"layout"` + Scope string `json:"scope"` + Key string `json:"key"` +} + +// Presentation returns independent plain-text speech and braille messages. +// Declare Command.Presentation and obtain the local host grant before using it. +// Uninterruptible protects accepted speech through ordinary input/focus changes; +// session revocation and core lifecycle/output policy still take precedence. +type Extensions = tentaclewire.Extensions +type PreferencePage = tentaclewire.PreferencePage +type QuickSetting = tentaclewire.QuickSetting +type ReaderRequest = tentaclewire.ReaderRequest +type ReaderState = tentaclewire.ReaderState +type ExtensionEvent = tentaclewire.ExtensionEvent +type SpeechConfiguration = tentaclewire.SpeechConfiguration +type Voice = config.Voice +type VoiceFamily = config.VoiceFamily + +type Presentation = tentaclewire.Presentation + +// Interaction requires the explicit interaction grant as well as presentation. +type Interaction = tentaclewire.Interaction +type Submission = tentaclewire.Submission +type Item = tentaclewire.Item +type Form = interaction.Form +type Element = interaction.Element +type ListItem = interaction.Item +type Value = interaction.Value + +const ( + List = interaction.List + Entry = interaction.Entry + CheckBox = interaction.CheckBox + Button = interaction.Button +) + +// Handlers may run concurrently. Cancellation applies to the entire session; +// check ctx before side effects. Returning an error produces a generic RPC error, +// never the error text (which may contain private data). +type Handler func(ctx context.Context, arguments json.RawMessage) (any, error) + +type Command struct { + ID string `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + Bindings []Binding `json:"bindings,omitempty"` + Presentation bool `json:"presentation,omitempty"` + Interaction bool `json:"interaction,omitempty"` + // Settings exposes this interactive command through global Preferences. + // Register at most one; its handler opens a form without requiring arguments. + Reader bool `json:"reader,omitempty"` + Settings bool `json:"settings,omitempty"` + Handle Handler `json:"-"` +} + +var ErrProtocol = tentaclewire.ErrProtocol + +type request struct { + JSONRPC string `json:"jsonrpc"` + ID string `json:"id,omitempty"` + Method string `json:"method"` + Params json.RawMessage `json:"params"` +} + +// Serve owns the streams and closes them on return. Use stdin/stdout in a +// dedicated child process and exit when Serve returns. Shutdown/EOF cancels all +// handlers and waits for them; the host kills a child that ignores cancellation. +// Never print to stdout. Command declarations must remain unchanged during Serve. +func Serve(input io.ReadCloser, output io.WriteCloser, commands []Command) error { + return serve(input, output, commands, nil) +} + +// ServeWithExtensions declares session-owned preferences pages and quick settings. +func ServeWithExtensions(input io.ReadCloser, output io.WriteCloser, commands []Command, extensions Extensions) error { + if err := tentaclewire.ValidateExtensions(extensions); err != nil { + return err + } + return serve(input, output, commands, &extensions) +} + +func serve(input io.ReadCloser, output io.WriteCloser, commands []Command, extensions *Extensions) error { + ctx, cancel := context.WithCancel(context.Background()) + var workers sync.WaitGroup + var writeMutex sync.Mutex + defer func() { cancel(); input.Close(); output.Close(); workers.Wait() }() + handlers := make(map[string]Handler) + readerCommands := make(map[string]bool) + if len(commands) == 0 || len(commands) > 32 { + return ErrProtocol + } + settings := false + for _, command := range commands { + if command.Reader && !command.Interaction || command.Settings && (!command.Interaction || !command.Presentation || settings) || command.ID == "" || command.Handle == nil || handlers[command.ID] != nil { + return ErrProtocol + } + settings = settings || command.Settings + handlers[command.ID] = command.Handle + readerCommands[command.ID] = command.Reader + } + writeReply := func(id string, value any, failed bool, release func()) error { + reply := map[string]any{"jsonrpc": "2.0", "id": id, "result": value} + if failed { + delete(reply, "result") + reply["error"] = map[string]any{"code": -32603, "message": "Command failed"} + } + frame, err := json.Marshal(reply) + if err != nil || len(frame) > tentaclewire.MaxFrameBytes || tentaclewire.ValidateJSON(frame) != nil { + frame, _ = json.Marshal(map[string]any{"jsonrpc": "2.0", "id": id, + "error": map[string]any{"code": -32603, "message": "Invalid or oversized result"}}) + } + writeMutex.Lock() + defer writeMutex.Unlock() + // A completed reply may reach the host before Write returns. Release + // its handler slot first, with at most one additional serialized writer. + if release != nil { + release() + } + if ctx.Err() != nil { + return ctx.Err() + } + _, err = output.Write(append(frame, '\n')) + return err + } + reader := bufio.NewReader(input) + var sequence uint64 + session := "" + active := false + slots := make(chan struct{}, 8) + for { + frame, err := tentaclewire.ReadFrame(reader) + if errors.Is(err, io.EOF) { + return nil + } + if err != nil { + return err + } + var message request + if tentaclewire.DecodeStrict(frame, &message) != nil || message.JSONRPC != "2.0" { + return ErrProtocol + } + var fields map[string]json.RawMessage + _ = json.Unmarshal(frame, &fields) + for key := range fields { + if key != "jsonrpc" && key != "id" && key != "method" && key != "params" { + return ErrProtocol + } + } + if _, present := fields["id"]; present && message.ID == "" { + return ErrProtocol + } + if message.ID != "" { + number, err := strconv.ParseUint(message.ID, 10, 64) + if err != nil || number <= sequence || strconv.FormatUint(number, 10) != message.ID { + return ErrProtocol + } + sequence = number + } + switch message.Method { + case "initialize": + var params struct { + Protocol struct { + Major *int `json:"major"` + Minor *int `json:"minor"` + } `json:"protocol"` + Session string `json:"session"` + APIs []string `json:"apis"` + Capabilities []string `json:"capabilities"` + } + if session != "" || message.ID == "" || tentaclewire.DecodeStrict(message.Params, ¶ms) != nil || + params.Protocol.Major == nil || params.Protocol.Minor == nil || *params.Protocol.Major != 1 || *params.Protocol.Minor != 0 || params.Session == "" || len(params.Session) > 128 || + !tentaclewire.ValidAPIs(params.APIs, params.Capabilities) { + return ErrProtocol + } + for _, command := range commands { + if command.Presentation && len(params.APIs) < 2 || command.Interaction && (!command.Presentation || len(params.APIs) < 3) || command.Reader && len(params.APIs) != 4 { + return ErrProtocol + } + } + if extensions != nil && len(params.APIs) != 4 { + return ErrProtocol + } + session = params.Session + registration := map[string]any{"protocol": params.Protocol, "session": session, "commands": commands} + if extensions != nil { + registration["extensions"] = extensions + } + if err := writeReply(message.ID, registration, false, nil); err != nil { + return err + } + case "initialized": + var params struct { + Session string `json:"session"` + } + if session == "" || active || message.ID != "" || tentaclewire.DecodeStrict(message.Params, ¶ms) != nil || params.Session != session { + return ErrProtocol + } + active = true + case "command.invoke": + var params struct { + Command string `json:"command"` + Arguments json.RawMessage `json:"arguments"` + } + if !active || message.ID == "" || tentaclewire.DecodeStrict(message.Params, ¶ms) != nil || len(params.Arguments) == 0 || len(params.Arguments) > command_argument_limit(readerCommands[params.Command]) || handlers[params.Command] == nil { + return ErrProtocol + } + select { + case slots <- struct{}{}: + default: + return tentaclewire.ErrLimit + } + workers.Add(1) + go func(id string, handler Handler, arguments json.RawMessage) { + defer workers.Done() + released := false + release := func() { + if !released { + <-slots + released = true + } + } + defer release() + value, err := call_handler(ctx, handler, arguments) + if writeReply(id, value, err != nil, release) != nil { + cancel() + input.Close() + } + }(message.ID, handlers[params.Command], params.Arguments) + case "shutdown": + if message.ID != "" || (len(message.Params) != 0 && string(message.Params) != "null") { + return ErrProtocol + } + return nil + default: + return ErrProtocol + } + } +} + +func call_handler(ctx context.Context, handler Handler, arguments json.RawMessage) (value any, err error) { + defer func() { + if recover() != nil { + value = nil + err = errors.New("command panicked") + } + }() + return handler(ctx, arguments) +} + +func command_argument_limit(reader bool) int { + if reader { + return 48 * 1024 + } + return 16 * 1024 +} diff --git a/sdk/python/cthulhu_tentacle/__init__.py b/sdk/python/cthulhu_tentacle/__init__.py new file mode 100644 index 0000000..e5f29e9 --- /dev/null +++ b/sdk/python/cthulhu_tentacle/__init__.py @@ -0,0 +1,234 @@ +# Copyright (c) 2026 Storm Dragon +# SPDX-License-Identifier: GPL-3.0-or-later +"""Experimental command/presentation SDK. stdout is reserved for the protocol.""" + +import json +import sys +import threading +from dataclasses import dataclass, field + +MAX_FRAME = 64 * 1024 + + +class ProtocolError(Exception): + pass + + +@dataclass +class Command: + id: str + title: str + description: str + handle: object + bindings: list = field(default_factory=list) + presentation: bool = False + interaction: bool = False + settings: bool = False + reader: bool = False + + def declaration(self): + declaration = {"id": self.id, "title": self.title, "description": self.description, + "bindings": self.bindings} + if self.presentation: + declaration["presentation"] = True + for name in ("interaction", "settings", "reader"): + if getattr(self, name): + declaration[name] = True + return declaration + + +def present(speech="", braille="", uninterruptible=False): + """Return independent text messages from a presentation-enabled command.""" + if type(uninterruptible) is not bool or (uninterruptible and not speech): + raise ValueError("Uninterruptible output requires speech and a boolean option") + result = {key: text for key, text in (("speech", speech), ("braille", braille)) if text} + if uninterruptible: + result["uninterruptible"] = True + return result + + +def _object(pairs): + result = {} + for key, value in pairs: + if key in result: + raise ProtocolError("Duplicate key") + result[key] = value + return result + + +def _depth(value, depth=0): + if depth > 32: + raise ProtocolError("JSON nesting limit") + if isinstance(value, (dict, list)): + for child in value.values() if isinstance(value, dict) else value: + _depth(child, depth + 1) + + +def _constant(value): + raise ProtocolError("Invalid JSON number") + + +def _encode(value): + _depth(value) + return json.dumps(value, ensure_ascii=False, allow_nan=False, + separators=(",", ":")).encode("utf-8") + + +def _fields(value, required, optional=()): + if (not isinstance(value, dict) or not set(required) <= value.keys() + or value.keys() - set(required) - set(optional)): + raise ProtocolError("Invalid fields") + + +def serve(commands, inputStream=None, outputStream=None, extensions=None): + """Run in a dedicated child, then exit. Handlers receive (cancelled, arguments). + + cancelled is a threading.Event shared by the session. Up to eight handlers + run concurrently. Shutdown/EOF sets it and joins handlers; the host terminates + children that ignore cancellation. Exceptions become generic RPC errors. + Streams are binary, owned by this call, and closed on return. + """ + inputStream = inputStream if inputStream is not None else sys.stdin.buffer + outputStream = outputStream if outputStream is not None else sys.stdout.buffer + cancelled = threading.Event() + writeLock = threading.Lock() + workers = [] + slots = threading.BoundedSemaphore(8) + + def write_reply(requestId, value=None, failed=False, release=None): + reply = {"jsonrpc": "2.0", "id": requestId} + if failed: + reply["error"] = {"code": -32603, "message": "Command failed"} + else: + reply["result"] = value + try: + frame = _encode(reply) + if len(frame) > MAX_FRAME: + raise ValueError() + except (ValueError, TypeError, UnicodeError, RecursionError, ProtocolError): + frame = _encode({"jsonrpc": "2.0", "id": requestId, "error": { + "code": -32603, "message": "Invalid or oversized result"}}) + with writeLock: + # Bound eight handlers/waiting replies plus one serialized writer. + if release is not None: + release() + if not cancelled.is_set(): + outputStream.write(frame + b"\n") + outputStream.flush() + + def invoke(requestId, handler, arguments): + released = False + + def release_slot(): + nonlocal released + if not released: + slots.release() + released = True + + try: + value = handler(cancelled, arguments) + except BaseException: + value, failed = None, True + else: + failed = False + try: + write_reply(requestId, value, failed, release_slot) + except (OSError, ValueError): + cancelled.set() + finally: + release_slot() + + try: + commands = list(commands) + handlers = {command.id: command.handle for command in commands} + if (not 1 <= len(commands) <= 32 or len(handlers) != len(commands) + or any(not key or not callable(value) for key, value in handlers.items())): + raise ProtocolError("Invalid commands") + if (sum(command.settings for command in commands) > 1 + or any(command.interaction and not command.presentation + or command.settings and not command.interaction + or command.reader and not command.interaction for command in commands)): + raise ProtocolError("Invalid command capabilities") + session, active, sequence = None, False, 0 + while not cancelled.is_set(): + frame = inputStream.readline(MAX_FRAME + 2) + if not frame: + return + if not frame.endswith(b"\n") or len(frame) > MAX_FRAME + 1: + raise ProtocolError("Invalid frame size or termination") + try: + message = json.loads(frame.decode("utf-8"), object_pairs_hook=_object, + parse_constant=_constant) + _depth(message) + except (ValueError, UnicodeError, RecursionError) as error: + raise ProtocolError("Invalid JSON") from error + _fields(message, ("jsonrpc", "method"), ("id", "params")) + if message["jsonrpc"] != "2.0": + raise ProtocolError("Invalid JSON-RPC version") + requestId = message.get("id", "") + if requestId: + if (not isinstance(requestId, str) or not requestId.isascii() + or not requestId.isdecimal() or len(requestId) > 20 + or not sequence < int(requestId) < 2**64 + or str(int(requestId)) != requestId): + raise ProtocolError("Invalid request sequence") + sequence = int(requestId) + elif "id" in message: + raise ProtocolError("Invalid request ID") + method, params = message["method"], message.get("params") + if method == "initialize": + _fields(params, ("protocol", "session", "apis", "capabilities")) + version = params["protocol"] + if (session is not None or not requestId or version != {"major": 1, "minor": 0} + or any(type(value) is not int for value in version.values()) + or not isinstance(params["session"], str) or not params["session"] + or len(params["session"].encode("utf-8")) > 128 + or params["apis"] not in (["commands"], ["commands", "presentation"], + ["commands", "presentation", "interaction"], + ["commands", "presentation", "interaction", "reader-settings"]) + or params["capabilities"] != params["apis"] + or (any(command.presentation for command in commands) + and len(params["apis"]) < 2) + or (any(command.interaction for command in commands) and len(params["apis"]) < 3) + or ((extensions is not None or any(command.reader for command in commands)) + and len(params["apis"]) != 4)): + raise ProtocolError("Invalid initialization") + session = params["session"] + registration = {"protocol": version, "session": session, + "commands": [command.declaration() for command in commands]} + if extensions is not None: + registration["extensions"] = extensions + write_reply(requestId, registration) + elif method == "initialized": + _fields(params, ("session",)) + if session is None or active or requestId or params["session"] != session: + raise ProtocolError("Invalid activation") + active = True + elif method == "command.invoke": + _fields(params, ("command", "arguments")) + if (not active or not requestId or not isinstance(params["command"], str) + or params["command"] not in handlers + or len(_encode(params["arguments"])) > (48 if next( + command.reader for command in commands if command.id == params["command"]) else 16) * 1024): + raise ProtocolError("Invalid invocation") + workers = [worker for worker in workers if worker.is_alive()] + if not slots.acquire(blocking=False): + raise ProtocolError("Command limit") + worker = threading.Thread(target=invoke, args=(requestId, + handlers[params["command"]], params["arguments"])) + workers.append(worker) + worker.start() + elif method == "shutdown": + if requestId or params is not None: + raise ProtocolError("Invalid shutdown") + return + else: + raise ProtocolError("Unknown method") + finally: + cancelled.set() + # Join before closing buffered stdout: a blocked writer must remain + # subject to the host deadline rather than race a Python buffer close. + for worker in workers: + worker.join() + inputStream.close() + outputStream.close() diff --git a/set-version.sh b/set-version.sh deleted file mode 100755 index 9df26a2..0000000 --- a/set-version.sh +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -scriptDir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -dateInput="${1:-}" -branchInput="${2:-}" - -if [[ -z "$dateInput" ]]; then - dateInput="$(date +%Y.%m.%d)" -fi - -if [[ ! "$dateInput" =~ ^([0-9]{4}\.[0-9]{2}\.[0-9]{2})(-([A-Za-z0-9._-]+))?$ ]]; then - echo "Usage: $(basename "$0") [YYYY.MM.DD[-branch]] [branch]" >&2 - echo "Error: version must match YYYY.MM.DD or YYYY.MM.DD-branch" >&2 - exit 1 -fi - -datePart="${BASH_REMATCH[1]}" -suffixPart="${BASH_REMATCH[3]}" - -if [[ -n "$suffixPart" && -n "$branchInput" ]]; then - echo "Warning: branch argument ignored because suffix was provided in version." >&2 - branchInput="" -fi - -if [[ -z "$suffixPart" ]]; then - if [[ -z "$branchInput" ]]; then - branchInput="$(git -C "$scriptDir" branch --show-current 2>/dev/null || true)" - fi - - if [[ "$branchInput" == "HEAD" ]]; then - branchInput="" - fi - - if [[ -n "$branchInput" ]]; then - branchName="$(printf '%s' "$branchInput" | sed 's/[^A-Za-z0-9._-]/-/g')" - branchName="${branchName#-}" - branchName="${branchName%-}" - suffixPart="$branchName" - fi -fi - -pythonVersion="$datePart" -fullVersion="$datePart" -if [[ -n "$suffixPart" ]]; then - fullVersion="${fullVersion}-${suffixPart}" -fi - -if [[ ! "$fullVersion" =~ ^[0-9]{4}\.[0-9]{2}\.[0-9]{2}(-[A-Za-z0-9._-]+)?$ ]]; then - echo "Error: generated version '${fullVersion}' is invalid" >&2 - exit 1 -fi - -codeNameValue="" -if [[ -n "$suffixPart" ]]; then - codeNameValue="$suffixPart" -fi - -cthulhuVersionFile="${scriptDir}/src/cthulhu/cthulhuVersion.py" -mesonFile="${scriptDir}/meson.build" -pkgbuildFile="${scriptDir}/distro-packages/Arch-Linux/cthulhu/PKGBUILD" -winePkgbuildFile="${scriptDir}/distro-packages/Arch-Linux/cthulhu-wine-access/PKGBUILD" -slackwareBuildFile="${scriptDir}/distro-packages/Slackware/cthulhu.SlackBuild" -slintBuildFile="${scriptDir}/distro-packages/Slint/cthulhu.SlackBuild" -slintInfoFile="${scriptDir}/distro-packages/Slint/cthulhu-info" - -for path in "$cthulhuVersionFile" "$mesonFile" "$pkgbuildFile" "$winePkgbuildFile" "$slackwareBuildFile" "$slintBuildFile" "$slintInfoFile"; do - if [[ ! -f "$path" ]]; then - echo "Error: Missing file: $path" >&2 - exit 1 - fi -done - -sed -i "s/^version = \".*\"/version = \"${pythonVersion}\"/" "$cthulhuVersionFile" -sed -i "s/^codeName = \".*\"/codeName = \"${codeNameValue}\"/" "$cthulhuVersionFile" -sed -i "s/^ version: '.*',/ version: '${fullVersion}',/" "$mesonFile" -sed -i "s/^pkgver=.*/pkgver=${pythonVersion}/" "$pkgbuildFile" -sed -i "s/^pkgrel=.*/pkgrel=1/" "$pkgbuildFile" -sed -i "s/^pkgver=.*/pkgver=${pythonVersion}/" "$winePkgbuildFile" -sed -i "s/^pkgrel=.*/pkgrel=1/" "$winePkgbuildFile" -sed -i "s/^VERSION=\${VERSION:-.*}/VERSION=\${VERSION:-${pythonVersion}}/" "$slackwareBuildFile" -sed -i "s/^VERSION=\${VERSION:-.*}/VERSION=\${VERSION:-${pythonVersion}}/" "$slintBuildFile" -sed -i "s/^VERSION=\".*\"/VERSION=\"${pythonVersion}\"/" "$slintInfoFile" - -if ! rg -q "^version = \"${pythonVersion}\"" "$cthulhuVersionFile"; then - echo "Error: Failed to update ${cthulhuVersionFile}" >&2 - exit 1 -fi -if ! rg -q "^codeName = \"${codeNameValue}\"" "$cthulhuVersionFile"; then - echo "Error: Failed to update codeName in ${cthulhuVersionFile}" >&2 - exit 1 -fi -if ! rg -q "^ version: '${fullVersion}'," "$mesonFile"; then - echo "Error: Failed to update ${mesonFile}" >&2 - exit 1 -fi -if ! rg -q "^pkgver=${pythonVersion}$" "$pkgbuildFile"; then - echo "Error: Failed to update ${pkgbuildFile}" >&2 - exit 1 -fi -if ! rg -q "^pkgrel=1$" "$pkgbuildFile"; then - echo "Error: Failed to reset pkgrel in ${pkgbuildFile}" >&2 - exit 1 -fi -if ! rg -q "^pkgver=${pythonVersion}$" "$winePkgbuildFile"; then - echo "Error: Failed to update ${winePkgbuildFile}" >&2 - exit 1 -fi -if ! rg -q "^pkgrel=1$" "$winePkgbuildFile"; then - echo "Error: Failed to reset pkgrel in ${winePkgbuildFile}" >&2 - exit 1 -fi -if ! rg -q "^VERSION=\\\$\\{VERSION:-${pythonVersion}\\}$" "$slackwareBuildFile"; then - echo "Error: Failed to update ${slackwareBuildFile}" >&2 - exit 1 -fi -if ! rg -q "^VERSION=\\\$\\{VERSION:-${pythonVersion}\\}$" "$slintBuildFile"; then - echo "Error: Failed to update ${slintBuildFile}" >&2 - exit 1 -fi -if ! rg -q "^VERSION=\"${pythonVersion}\"$" "$slintInfoFile"; then - echo "Error: Failed to update ${slintInfoFile}" >&2 - exit 1 -fi - -echo "Updated version to ${fullVersion} in:" \ - "${cthulhuVersionFile}" \ - "${mesonFile}" \ - "${pkgbuildFile}" \ - "${winePkgbuildFile}" \ - "${slackwareBuildFile}" \ - "${slintBuildFile}" \ - "${slintInfoFile}" diff --git a/sounds/meson.build b/sounds/meson.build deleted file mode 100644 index 4681e33..0000000 --- a/sounds/meson.build +++ /dev/null @@ -1,28 +0,0 @@ -# Install sound theme files -# Themes are installed to: {datadir}/cthulhu/sounds/{theme_name}/ - -# Use explicit install_data for better compatibility across Meson versions -default_theme_sounds = files( - 'default/browse_mode.wav', - 'default/button.wav', - 'default/checkbox_checked.wav', - 'default/checkbox_mixed.wav', - 'default/checkbox_unchecked.wav', - 'default/combobox.wav', - 'default/focus_mode.wav', - 'default/link.wav', - 'default/link_visited.wav', - 'default/radiobutton_checked.wav', - 'default/radiobutton_unchecked.wav', - 'default/start.wav', - 'default/stop.wav', - 'default/switch_off.wav', - 'default/switch_on.wav', - 'default/togglebutton_checked.wav', - 'default/togglebutton_unchecked.wav', -) - -install_data( - default_theme_sounds, - install_dir: get_option('datadir') / 'cthulhu' / 'sounds' / 'default' -) diff --git a/src/cthulhu.py b/src/cthulhu.py deleted file mode 100644 index 9560f83..0000000 --- a/src/cthulhu.py +++ /dev/null @@ -1,422 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import argparse -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -import os -import shutil -import signal -import subprocess -import sys -import time - -def setup_paths(): - """Configure paths for both installed and source directory execution.""" - currentDir = os.path.dirname(os.path.abspath(__file__)) - - # Check if running from source - if os.path.exists(os.path.join(currentDir, 'plugins')): - # Running from source directory - sys.path.insert(0, os.path.dirname(currentDir)) - pythondir = currentDir - datadir = currentDir - else: - # Running installed - determine if local or system based on actual path - if currentDir.startswith(os.path.expanduser('~/.local')): - # Local installation (~/.local/bin/cthulhu) - prefix = os.path.expanduser('~/.local') - elif currentDir.startswith('/usr/local'): - # /usr/local installation - prefix = '/usr/local' - else: - # System installation (/usr/bin/cthulhu) - prefix = '/usr' - - # Try to find Python modules in multiple possible locations - python_version = f'python{sys.version_info.major}.{sys.version_info.minor}' - possible_pythondirs = [ - os.path.join(prefix, 'lib', python_version, 'site-packages'), - os.path.join('/usr', 'lib', python_version, 'site-packages'), # System fallback - os.path.join('/usr/local', 'lib', python_version, 'site-packages') # /usr/local fallback - ] - - # Use the first directory that contains the cthulhu module - pythondir = None - for candidate_dir in possible_pythondirs: - if os.path.exists(os.path.join(candidate_dir, 'cthulhu', '__init__.py')): - pythondir = candidate_dir - break - - if pythondir is None: - # Fallback to prefix-relative path if module not found - pythondir = os.path.join(prefix, 'lib', python_version, 'site-packages') - - datadir = os.path.join(prefix, 'share', 'cthulhu') - - sys.path.insert(1, pythondir) - - # Set environment variables for resource paths - if 'CTHULHU_DATA_DIR' not in os.environ: - os.environ['CTHULHU_DATA_DIR'] = datadir - -# Set up paths before importing Cthulhu modules -setup_paths() - -from cthulhu import debug -from cthulhu import messages -from cthulhu import settings -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu.cthulhu_platform import version, revision - -class ListApps(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - desktop = AXUtilities.get_desktop() - for app in AXObject.iter_children(desktop): - pid = AXObject.get_process_id(app) - try: - name = Atspi.Accessible.get_name(app) or "(none)" - except Exception: - name = "[DEAD]" - - try: - cmdline = subprocess.getoutput('cat /proc/%s/cmdline' % pid) - except Exception: - cmdline = '(exception encountered)' - else: - cmdline = cmdline.replace('\x00', ' ') - - print(time.strftime('%H:%M:%S', time.localtime()), - ' pid: %5s %-25s %s' % (pid, name, cmdline)) - - parser.exit() - -class PrintVersion(argparse.Action): - """Action to print the version of Cthulhu.""" - - def __call__(self, parser, namespace, values, option_string=None): - msg = version - if revision: - msg += f" (rev {revision})" - - atspi_version = Atspi.get_version() - msg += f", AT-SPI2 version: {atspi_version[0]}.{atspi_version[1]}.{atspi_version[2]}" - - session_type = os.environ.get("XDG_SESSION_TYPE") or "" - session_desktop = os.environ.get("XDG_SESSION_DESKTOP") or "" - session = f"{session_type} {session_desktop}".strip() - if session: - msg += f", Session: {session}" - - print(msg) - parser.exit() - -class Settings(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - settingsDict = getattr(namespace, 'settings', {}) - invalid = getattr(namespace, 'invalid', []) - for value in values.split(','): - item = str.title(value).replace('-', '') - try: - test = 'enable%s' % item - eval('settings.%s' % test) - except AttributeError: - try: - test = 'show%s' % item - eval('settings.%s' % test) - except AttributeError: - invalid.append(value) - continue - settingsDict[test] = self.const - setattr(namespace, 'settings', settingsDict) - setattr(namespace, 'invalid', invalid) - -class HelpFormatter(argparse.HelpFormatter): - def __init__(self, prog, indent_increment=2, max_help_position=32, - width=None): - - super().__init__(prog, indent_increment, max_help_position, width) - - def add_usage(self, usage, actions, groups, prefix=None): - super().add_usage(usage, actions, groups, messages.CLI_USAGE) - -class Parser(argparse.ArgumentParser): - def __init__(self, *args, **kwargs): - super(Parser, self).__init__( - epilog=messages.CLI_EPILOG, formatter_class=HelpFormatter, add_help=False) - self.add_argument( - "-h", "--help", action="help", help=messages.CLI_HELP) - self.add_argument( - "-v", "--version", action=PrintVersion, nargs=0, help=messages.CLI_VERSION) - self.add_argument( - "-r", "--replace", action="store_true", help=messages.CLI_REPLACE) - self.add_argument( - "-s", "--setup", action="store_true", help=messages.CLI_GUI_SETUP) - self.add_argument( - "-l", "--list-apps", action=ListApps, nargs=0, - help=messages.CLI_LIST_APPS) - self.add_argument( - "-e", "--enable", action=Settings, const=True, - help=messages.CLI_ENABLE_OPTION, metavar=messages.CLI_OPTION) - self.add_argument( - "-d", "--disable", action=Settings, const=False, - help=messages.CLI_DISABLE_OPTION, metavar=messages.CLI_OPTION) - self.add_argument( - "-p", "--profile", action="store", - help=messages.CLI_LOAD_PROFILE, metavar=messages.CLI_PROFILE_NAME) - self.add_argument( - "-u", "--user-prefs", action="store", - help=messages.CLI_LOAD_PREFS, metavar=messages.CLI_PREFS_DIR) - self.add_argument( - "--debug-file", action="store", - help=messages.CLI_DEBUG_FILE, metavar=messages.CLI_DEBUG_FILE_NAME) - self.add_argument( - "--debug", action="store_true", help=messages.CLI_ENABLE_DEBUG) - self.add_argument( - "--debug-startup", action="store_true", help=messages.CLI_ENABLE_STARTUP_DEBUG) - - self._optionals.title = messages.CLI_OPTIONAL_ARGUMENTS - - def parse_known_args(self, *args, **kwargs): - opts, invalid = super(Parser, self).parse_known_args(*args, **kwargs) - try: - invalid.extend(opts.invalid) - except Exception: - pass - if invalid: - print((messages.CLI_INVALID_OPTIONS + " ".join(invalid))) - - if opts.debug_file: - opts.debug = True - elif opts.debug: - opts.debug_file = time.strftime('debug-%Y-%m-%d-%H:%M:%S.out') - - return opts, invalid - -def setProcessName(name): - """Attempts to set the process name to the specified name.""" - - sys.argv[0] = name - - try: - from setproctitle import setproctitle - except ImportError: - pass - else: - setproctitle(name) - return True - - try: - from ctypes import cdll, byref, create_string_buffer - libc = cdll.LoadLibrary('libc.so.6') - stringBuffer = create_string_buffer(len(name) + 1) - stringBuffer.value = bytes(name, 'UTF-8') - libc.prctl(15, byref(stringBuffer), 0, 0, 0) - return True - except Exception: - pass - - return False - -def inGraphicalDesktop(): - """Returns True if we are in a graphical desktop.""" - - # TODO - JD: Make this desktop environment agnostic - try: - import gi - gi.require_version("Gdk", "3.0") - from gi.repository import Gdk - display = Gdk.Display.get_default() - except Exception: - return False - - return display is not None - -def getSessionType(): - sessionType = (os.environ.get("XDG_SESSION_TYPE") or "").strip().lower() - if sessionType: - return sessionType - if os.environ.get("WAYLAND_DISPLAY"): - return "wayland" - if os.environ.get("DISPLAY"): - return "x11" - return "unknown" - -def getXServerVendor(): - display = os.environ.get("DISPLAY") - if not display: - return None - - xdpyinfoPath = shutil.which("xdpyinfo") - if not xdpyinfoPath: - return None - - try: - result = subprocess.run( - [xdpyinfoPath, "-display", display], - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - timeout=1, - ) - except Exception: - return None - - for line in result.stdout.splitlines(): - if "vendor string:" in line: - return line.split("vendor string:", 1)[1].strip() - return None - -def otherCthulhus(): - """Returns the pid of any other instances of Cthulhu owned by this user.""" - - openFile = subprocess.Popen('pgrep -u %s -x cthulhu' % os.getuid(), - shell=True, - stdout=subprocess.PIPE).stdout - pids = openFile.read() - openFile.close() - cthulhus = [int(p) for p in pids.split()] - - pid = os.getpid() - return [p for p in cthulhus if p != pid] - -def cleanup(sigval): - """Tries to clean up any other running Cthulhu instances owned by this user.""" - - cthulhusToKill = otherCthulhus() - debug.printMessage(debug.LEVEL_INFO, "INFO: Cleaning up these PIDs: %s" % cthulhusToKill) - - def onTimeout(signum, frame): - cthulhusToKill = otherCthulhus() - debug.printMessage(debug.LEVEL_INFO, "INFO: Timeout cleaning up: %s" % cthulhusToKill) - for pid in cthulhusToKill: - os.kill(pid, signal.SIGKILL) - - for pid in cthulhusToKill: - os.kill(pid, sigval) - signal.signal(signal.SIGALRM, onTimeout) - signal.alarm(2) - while otherCthulhus(): - time.sleep(0.5) - -def main(): - debug.reset_startup_timing() - - setProcessName('cthulhu') - - parser = Parser() - args, invalid = parser.parse_known_args() - - if args.debug: - debug.debugLevel = debug.LEVEL_ALL - debug.eventDebugLevel = debug.LEVEL_OFF - debug.debugFile = open(args.debug_file, 'w') - - debug.set_startup_timing_enabled(args.debug or args.debug_startup) - debug.print_startup_timing("launcher main start") - - if args.replace: - with debug.startup_timing("replace cleanup"): - cleanup(signal.SIGKILL) - - settingsDict = getattr(args, 'settings', {}) - - with debug.startup_timing("graphical desktop check"): - graphicalDesktop = inGraphicalDesktop() - if not graphicalDesktop: - print(messages.CLI_NO_DESKTOP_ERROR) - return 1 - - with debug.startup_timing("session check"): - sessionType = getSessionType() - xServerVendor = None - if sessionType == "x11": - xServerVendor = getXServerVendor() - sessionDetails = [] - xdgSessionType = os.environ.get("XDG_SESSION_TYPE") - if xdgSessionType: - sessionDetails.append(f"XDG_SESSION_TYPE={xdgSessionType}") - if sessionType == "wayland": - waylandDisplay = os.environ.get("WAYLAND_DISPLAY") - if waylandDisplay: - sessionDetails.append(f"WAYLAND_DISPLAY={waylandDisplay}") - elif sessionType == "x11": - display = os.environ.get("DISPLAY") - if display: - sessionDetails.append(f"DISPLAY={display}") - if xServerVendor: - sessionDetails.append(f"X server vendor={xServerVendor}") - - if sessionDetails: - msg = f"INFO: Session: {sessionType} ({', '.join(sessionDetails)})" - else: - msg = f"INFO: Session: {sessionType}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - debug.printMessage(debug.LEVEL_INFO, "INFO: Preparing to launch.", True) - - debug.print_startup_timing("cthulhu import start") - from cthulhu import cthulhu - debug.print_startup_timing("cthulhu import complete") - manager = cthulhu.cthulhuApp.settingsManager - - if not manager: - print(messages.CLI_SETTINGS_MANAGER_ERROR) - return 1 - - debug.printMessage(debug.LEVEL_INFO, "INFO: About to activate settings manager.", True) - with debug.startup_timing("settings manager launcher activation"): - manager.activate(args.user_prefs, settingsDict) - sys.path.insert(0, manager.getPrefsDir()) - - if args.profile: - with debug.startup_timing("profile selection"): - try: - manager.setProfile(args.profile) - except Exception: - print(messages.CLI_LOAD_PROFILE_ERROR % args.profile) - manager.setProfile() - - if args.setup: - with debug.startup_timing("setup cleanup"): - cleanup(signal.SIGKILL) - with debug.startup_timing("preferences GUI startup"): - cthulhu.showPreferencesGUI() - - with debug.startup_timing("other instance check"): - otherInstances = otherCthulhus() - if otherInstances: - print(messages.CLI_OTHER_CTHULHUS_ERROR) - return 1 - - debug.printMessage(debug.LEVEL_INFO, "INFO: About to launch Cthulhu.", True) - debug.print_startup_timing("cthulhu main handoff") - return cthulhu.main() - -if __name__ == "__main__": - sys.exit(main()) diff --git a/src/cthulhu/.gitignore b/src/cthulhu/.gitignore deleted file mode 100644 index 4475fcd..0000000 --- a/src/cthulhu/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -Makefile -Makefile.in -cthulhu -cthulhu-setup -cthulhu_bin.py -cthulhu_i18n.py -cthulhu_platform.py -*.pyc -*~ diff --git a/src/cthulhu/__init__.py b/src/cthulhu/__init__.py deleted file mode 100644 index d893644..0000000 --- a/src/cthulhu/__init__.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Cthulhu Screen Reader""" - -__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc." -__license__ = "LGPL" diff --git a/src/cthulhu/acss.py b/src/cthulhu/acss.py deleted file mode 100644 index f70ec16..0000000 --- a/src/cthulhu/acss.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""ACSS --- Aural CSS. - -Class ACSS defines a simple wrapper for holding ACSS voice -definitions. Speech engines implement the code for converting -ACSS definitions into engine-specific markup codes. - -""" - -__id__ = "$Id$" -__author__ = "T. V. Raman" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Google Inc." -__license__ = "LGPL" - -class ACSS(dict): - - """Holds ACSS representation of a voice.""" - - FAMILY = 'family' - RATE = 'rate' - GAIN = 'gain' - AVERAGE_PITCH = 'average-pitch' - PITCH_RANGE = 'pitch-range' - STRESS = 'stress' - RICHNESS = 'richness' - PUNCTUATIONS = 'punctuations' - - # A value of None means use the engine's default value. - # - settings = { - FAMILY : None, - RATE : 50, - GAIN : 10, - AVERAGE_PITCH : 5, - PITCH_RANGE : 5, - STRESS : 5, - RICHNESS : 5, - PUNCTUATIONS : 'all' - } - - def __init__(self, props=None): - """Create and initialize ACSS structure.""" - dict.__init__(self) - props = props or {} - if props: - for k in props: - if k == 'established' or k in ACSS.settings: - # Do a 'deep copy' of the family. Otherwise, - # the new ACSS shares the actual data with the - # props passed in. This can cause unexpected - # side effects. - # - if k == ACSS.FAMILY: - self[k] = {} - for j in props[k].keys(): - self[k][j] = props[k][j] - else: - self[k] = props[k] - else: - self['established'] = False - - def __eq__(self, other): - if not isinstance(other, ACSS): - return False - compareKeys = ( - ACSS.FAMILY, - ACSS.RATE, - ACSS.AVERAGE_PITCH, - ACSS.GAIN, - ACSS.PITCH_RANGE, - ACSS.STRESS, - ACSS.RICHNESS, - ACSS.PUNCTUATIONS, - ) - for key in compareKeys: - if self.get(key) != other.get(key): - return False - return True - - def __setitem__ (self, key, value): - """Update name when we change values.""" - dict.__setitem__(self, key, value) - - def __delitem__(self, key): - """Update name if we delete a key.""" - dict.__delitem__(self, key) - - def name(self): - _name = 'acss-' - names = list(self.keys()) - if names: - names.sort() - for k in names: - _name += f"{k}-{self[k]}:" - _name = _name[:-1] - return _name - - def getLocale(self): - family = self.get(ACSS.FAMILY, {}) - return family.get('locale') - - def getDialect(self): - family = self.get(ACSS.FAMILY, {}) - return family.get('dialect') - - def update(self, newDict): - family = newDict.get(ACSS.FAMILY) - if isinstance(family, dict) and family.get('name') is None: - newDict.pop(ACSS.FAMILY) - - return super().update(newDict) diff --git a/src/cthulhu/action_presenter.py b/src/cthulhu/action_presenter.py deleted file mode 100644 index 092e385..0000000 --- a/src/cthulhu/action_presenter.py +++ /dev/null @@ -1,384 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Module for performing accessible actions via a list""" - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -import time -from typing import TYPE_CHECKING, Union - -import gi - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") -from gi.repository import Gdk, GLib, Gtk - -from . import cmdnames -from . import dbus_service -from . import debug -from . import focus_manager -from . import guilabels -from . import input_event -from . import keybindings -from . import messages -from . import cthulhu_state -from . import script_manager -from .ax_object import AXObject -from .ax_utilities import AXUtilities - -if TYPE_CHECKING: - from . import script - - -class ActionList(Gtk.Window): - """Window containing a list of accessible actions.""" - - def __init__(self, presenter: ActionPresenter): - super().__init__(window_position=Gtk.WindowPosition.MOUSE, transient_for=None) - self._presenter = presenter - self._setup_gui() - - def _setup_gui(self) -> None: - """Sets up the GUI for the actions list.""" - - self.set_title(guilabels.KB_GROUP_ACTIONS) - self.set_decorated(False) - - self._listbox = Gtk.ListBox() - self._listbox.set_selection_mode(Gtk.SelectionMode.SINGLE) - self._listbox.connect("row-activated", self._on_row_activated) - self._listbox.set_margin_top(5) - self._listbox.set_margin_bottom(5) - self.add(self._listbox) - - self.connect("key-press-event", self._on_key_press) - self.connect("destroy", self._on_destroy) - - def _on_key_press(self, widget, event) -> bool: - """Handles key press events.""" - - if event.keyval == Gdk.KEY_Escape: - self.destroy() - return True - return False - - def _on_row_activated(self, listbox, row) -> None: - """Handles row activation (Enter or double-click).""" - - action_name = getattr(row, "_action_name", None) - if action_name: - self._presenter._perform_action(action_name) - - def _on_destroy(self, widget) -> None: - """Handles window destruction.""" - - GLib.idle_add(self._presenter._clear_gui_and_restore_focus) - - def populate_actions(self, actions: Union[dict[str, str], list[str]]) -> None: - """Populates the list with accessible actions.""" - - if isinstance(actions, dict): - items = list(actions.items()) - else: - items = [(action, action) for action in actions] - - # Clear existing items - for child in self._listbox.get_children(): - self._listbox.remove(child) - - # Add actions to list - for action_name, label_text in items: - row = Gtk.ListBoxRow() - label = Gtk.Label(label=label_text, xalign=0) - label.set_margin_start(10) - label.set_margin_end(10) - row.add(label) - setattr(row, "_action_name", action_name) - self._listbox.add(row) - - # Select first item - if actions: - first_row = self._listbox.get_row_at_index(0) - if first_row: - self._listbox.select_row(first_row) - first_row.grab_focus() - - def show_gui(self) -> None: - """Shows the window.""" - - self.show_all() - self.present_with_time(time.time()) - self._listbox.grab_focus() - - -class ActionPresenter: - """Provides a list for performing accessible actions on an object.""" - - def __init__(self): - self._handlers = None - self._bindings = None - self._gui = None - self._obj = None - self._window = None - - # Initialize handlers - self._handlers = self.get_handlers(True) - # _bindings will be initialized lazily in get_bindings() - - msg = "ACTION PRESENTER: Registering D-Bus commands." - debug.printMessage(debug.LEVEL_INFO, msg, True) - controller = dbus_service.get_remote_controller() - controller.register_decorated_module("ActionPresenter", self) - - def get_handlers(self, refresh: bool = False) -> dict: - """Returns a dictionary of input event handlers.""" - - if self._handlers is None or refresh: - msg = "ACTION PRESENTER: Getting input event handlers." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._setup_handlers() - - return self._handlers - - def get_bindings(self, refresh: bool = False, is_desktop: bool = True) -> keybindings.KeyBindings: - """Returns keybindings for this presenter.""" - - if self._bindings is None or refresh: - msg = "ACTION PRESENTER: Getting key bindings." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._setup_bindings() - - return self._bindings - - def _setup_handlers(self) -> None: - """Sets up input event handlers for this presenter.""" - - msg = "ACTION PRESENTER: Setting up handlers." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self._handlers = {} - - self._handlers["show_actions_list"] = \ - input_event.InputEventHandler( - self.show_actions_list, - cmdnames.SHOW_ACTIONS_LIST) - - msg = "ACTION PRESENTER: Handlers set up." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _setup_bindings(self) -> None: - """Sets up key bindings for this presenter.""" - - msg = "ACTION PRESENTER: Setting up bindings." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self._bindings = keybindings.KeyBindings() - self._bindings.add(keybindings.KeyBinding( - "a", - keybindings.defaultModifierMask, - keybindings.CTHULHU_SHIFT_MODIFIER_MASK, - self._handlers["show_actions_list"])) - - msg = "ACTION PRESENTER: Bindings set up." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _restore_focus(self) -> None: - """Restores focus to the object associated with the actions list.""" - - tokens = ["ACTION PRESENTER: Restoring focus to", self._obj, "in", self._window] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - reason = "Action Presenter list is being destroyed" - app = AXObject.get_application(self._obj) - script = script_manager.get_manager().get_script(app, self._obj) - script_manager.get_manager().set_active_script(script, reason) - - manager = focus_manager.get_manager() - manager.clear_state(reason) - manager.set_active_window(self._window) - manager.set_locus_of_focus(None, self._obj) - - def _present_message(self, script, full_message, brief_message=None, notify_user=True) -> None: - """Presents a message using the provided script or the active script.""" - - if not notify_user: - return - - if script is not None: - script.presentMessage(full_message, brief_message) - return - - active_script = cthulhu_state.activeScript - if active_script is not None: - active_script.presentMessage(full_message, brief_message) - return - - msg = "ACTION PRESENTER: Unable to present message (no script)." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _clear_gui_and_restore_focus(self) -> None: - """Clears the GUI reference and then restores focus.""" - - self._gui = None - GLib.timeout_add(150, self._maybe_restore_focus) - - def _maybe_restore_focus(self) -> bool: - """Restores focus unless it already moved to another object in the target app.""" - - if not AXObject.is_valid(self._obj): - return False - - manager = focus_manager.get_manager() - current_focus = manager.get_locus_of_focus() - if current_focus and AXObject.is_valid(current_focus): - target_app = AXObject.get_application(self._obj) - focus_app = AXObject.get_application(current_focus) - if target_app and focus_app == target_app and current_focus != self._obj: - tokens = ["ACTION PRESENTER: Skipping focus restore; focus now on", current_focus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - self._restore_focus() - return False - - def _perform_action(self, action: str) -> None: - """Attempts to perform the named action.""" - - if self._gui is None: - msg = "ACTION PRESENTER: _perform_action called when self._gui is None." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - self._gui.hide() - result = AXObject.do_named_action(self._obj, action) - tokens = ["ACTION PRESENTER: Performing", action, "on", self._obj, "succeeded:", result] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # Use idle_add for asynchronous destruction to allow action to complete - GLib.idle_add(self._gui.destroy) - - def present_with_time(self, obj, start_time: float, script=None, notify_user=True) -> bool: - """Presents accessible actions for the given object with timing.""" - - try: - debug.printMessage(debug.LEVEL_INFO, f"ACTION PRESENTER: present_with_time called with obj: {obj}", True) - - if self._gui is not None: - msg = "ACTION PRESENTER: GUI already exists." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if obj is None: - msg = "ACTION PRESENTER: No object found, presenting LOCATION_NOT_FOUND" - debug.printMessage(debug.LEVEL_INFO, msg, True) - full_message = messages.LOCATION_NOT_FOUND_FULL - brief_message = messages.LOCATION_NOT_FOUND_BRIEF - self._present_message(script, full_message, brief_message, notify_user) - return True - - debug.printMessage(debug.LEVEL_INFO, f"ACTION PRESENTER: Getting actions for object: {obj}", True) - actions = {} - for i in range(AXObject.get_n_actions(obj)): - name = AXObject.get_action_name(obj, i) - if not name: - continue - localized_name = AXObject.get_action_localized_name(obj, i) - description = AXObject.get_action_description(obj, i) - actions[name] = localized_name or description or name - - debug.printMessage(debug.LEVEL_INFO, f"ACTION PRESENTER: Found {len(actions)} actions: {actions}", True) - - if not actions: - msg = "ACTION PRESENTER: No actions found, presenting NO_ACTIONS_FOUND_ON" - debug.printMessage(debug.LEVEL_INFO, msg, True) - name = AXObject.get_name(obj) or AXUtilities.get_localized_role_name(obj) - full_message = messages.NO_ACTIONS_FOUND_ON % name - self._present_message(script, full_message, notify_user=notify_user) - return True - - debug.printMessage(debug.LEVEL_INFO, "ACTION PRESENTER: Creating GUI", True) - self._obj = obj - self._window = focus_manager.get_manager().get_active_window() - - self._gui = ActionList(self) - self._gui.populate_actions(actions) - self._gui.show_gui() - - debug.printMessage(debug.LEVEL_INFO, "ACTION PRESENTER: GUI created successfully", True) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"ACTION PRESENTER: ERROR in present_with_time: {e}", True) - import traceback - debug.printMessage(debug.LEVEL_INFO, f"ACTION PRESENTER: Traceback: {traceback.format_exc()}", True) - return False - - @dbus_service.command - def show_actions_list( - self, - script: script.Script = None, - input_event: input_event.InputEvent = None, - notify_user: bool = True - ) -> bool: - """Shows the accessible actions list.""" - - try: - msg = f"ACTION PRESENTER: show_actions_list called! input_event: {input_event}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - start_time = time.time() - - obj = None - if input_event is not None: - obj = input_event.get_object() - debug.printMessage(debug.LEVEL_INFO, f"ACTION PRESENTER: Object from input_event: {obj}", True) - - if obj is None: - manager = focus_manager.get_manager() - _mode, obj = manager.get_active_mode_and_object_of_interest() - if obj is None: - obj = manager.get_locus_of_focus() - - result = self.present_with_time(obj, start_time, script, notify_user) - debug.printMessage(debug.LEVEL_INFO, f"ACTION PRESENTER: show_actions_list returning: {result}", True) - return result - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"ACTION PRESENTER: ERROR in show_actions_list: {e}", True) - import traceback - debug.printMessage(debug.LEVEL_INFO, f"ACTION PRESENTER: Traceback: {traceback.format_exc()}", True) - return False - - -_presenter = ActionPresenter() - -def getPresenter() -> ActionPresenter: - """Returns the Action Presenter singleton.""" - return _presenter diff --git a/src/cthulhu/ax_collection.py b/src/cthulhu/ax_collection.py deleted file mode 100644 index f2957b1..0000000 --- a/src/cthulhu/ax_collection.py +++ /dev/null @@ -1,167 +0,0 @@ -# Utilities for obtaining objects via the collection interface. -# -# Copyright 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-positional-arguments - -"""Utilities for obtaining objects via the collection interface.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -from typing import Optional -import time - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from .ax_object import AXObject - - -class AXCollection: - """Utilities for obtaining objects via the collection interface.""" - - # Too many arguments and too many local variables. - # This function wraps Atspi.MatchRule.new which has all the arguments. - # pylint: disable=R0913,R0914 - @staticmethod - def create_match_rule( - states: Optional[list[str]] = None, - state_match_type: Atspi.CollectionMatchType = Atspi.CollectionMatchType.ALL, - attributes: Optional[list[str]] = None, - attribute_match_type: Atspi.CollectionMatchType = Atspi.CollectionMatchType.ALL, - roles: Optional[list[str]] = None, - role_match_type: Atspi.CollectionMatchType = Atspi.CollectionMatchType.ALL, - interfaces: Optional[list[str]] = None, - interface_match_type: Atspi.CollectionMatchType = Atspi.CollectionMatchType.ALL, - invert: bool = False) -> Optional[Atspi.MatchRule]: - """Creates a match rule based on the supplied criteria.""" - - if states is None: - states = [] - if attributes is None: - attributes = [] - if roles is None: - roles = [] - if interfaces is None: - interfaces = [] - - state_set = Atspi.StateSet() - if states: - for state in states: - state_set.add(state) - - attributes_dict: dict[str, str] = {} - if attributes: - for attr in attributes: - key, value = attr.split(":", 1) - value = value.replace(":", r"\:") - if key in attributes_dict: - attributes_dict[key] = attributes_dict[key] + ":" + value - else: - attributes_dict[key] = value - - try: - rule = Atspi.MatchRule.new(state_set, - state_match_type, - attributes_dict, - attribute_match_type, - roles, - role_match_type, - interfaces, - interface_match_type, - invert) - except GLib.GError as error: - tokens = ["AXCollection: Exception in create_match_rule:", error] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - return rule - # pylint: enable=R0913,R0914 - - @staticmethod - def get_all_matches( - obj: Atspi.Accessible, - rule: Atspi.MatchRule, - order: Atspi.CollectionSortOrder = Atspi.CollectionSortOrder.CANONICAL - ) -> list[Atspi.Accessible]: - """Returns a list of objects matching the specified rule.""" - - if not AXObject.supports_collection(obj): - tokens = ["AXCollection:", obj, "does not implement this interface."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - if rule is None: - return [] - - start = time.time() - try: - # 0 means no limit on the number of results - # The final argument, traverse, is not supported but is expected. - matches = Atspi.Collection.get_matches(obj, rule, order, 0, True) - except GLib.GError as error: - tokens = ["AXCollection: Exception in get_all_matches:", error] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - msg = f"AXCollection: {len(matches)} match(es) found in {time.time() - start:.4f}s" - debug.print_message(debug.LEVEL_INFO, msg, True) - return matches - - @staticmethod - def get_first_match( - obj: Atspi.Accessible, - rule: Atspi.MatchRule, - order: Atspi.CollectionSortOrder = Atspi.CollectionSortOrder.CANONICAL - ) -> Optional[Atspi.Accessible]: - """Returns the first object matching the specified rule.""" - - if not AXObject.supports_collection(obj): - tokens = ["AXCollection:", obj, "does not implement this interface."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - if rule is None: - return None - - start = time.time() - try: - # 1 means limit the number of results to 1 - # The final argument, traverse, is not supported but is expected. - matches = Atspi.Collection.get_matches(obj, rule, order, 1, True) - except GLib.GError as error: - tokens = ["AXCollection: Exception in get_first_match:", error] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - match = None - if matches: - match = matches[0] - - tokens = ["AXCollection: found", match, f"in {time.time() - start:.4f}s"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return match diff --git a/src/cthulhu/ax_component.py b/src/cthulhu/ax_component.py deleted file mode 100644 index 17bdea6..0000000 --- a/src/cthulhu/ax_component.py +++ /dev/null @@ -1,416 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2024 Igalia, S.L. -# Copyright 2024 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position - -"""Utilities for obtaining position-related information about accessible objects.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Igalia, S.L." \ - "Copyright (c) 2024 GNOME Foundation Inc." -__license__ = "LGPL" - -from typing import Optional -import functools - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from .ax_object import AXObject -from .ax_utilities_role import AXUtilitiesRole - - -class AXComponent: - """Utilities for obtaining position-related information about accessible objects.""" - - @staticmethod - def get_center_point(obj: Atspi.Accessible) -> tuple[float, float]: - """Returns the center point of obj with respect to its window.""" - - rect = AXComponent.get_rect(obj) - return rect.x + rect.width / 2, rect.y + rect.height / 2 - - @staticmethod - def get_position(obj: Atspi.Accessible) -> tuple[int, int]: - """Returns the x, y position tuple of obj with respect to its window.""" - - if not AXObject.supports_component(obj): - return -1, -1 - - try: - point = Atspi.Component.get_position(obj, Atspi.CoordType.WINDOW) - except GLib.GError as error: - msg = f"AXComponent: Exception in get_position: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1, -1 - - if point is None: - tokens = ["AXComponent: get_position failed for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return -1, -1 - - return point.x, point.y - - @staticmethod - def get_rect(obj: Atspi.Accessible) -> Atspi.Rect: - """Returns the Atspi rect of obj with respect to its window.""" - - if not AXObject.supports_component(obj): - return Atspi.Rect() - - try: - rect = Atspi.Component.get_extents(obj, Atspi.CoordType.WINDOW) - except GLib.GError as error: - msg = f"AXComponent: Exception in get_rect: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return Atspi.Rect() - - return rect - - @staticmethod - def get_rect_intersection(rect1: Atspi.Rect, rect2: Atspi.Rect) -> Atspi.Rect: - """Returns a rect representing the intersection of rect1 and rect2.""" - - result = Atspi.Rect() - - dest_x = max(rect1.x, rect2.x) - dest_y = max(rect1.y, rect2.y) - dest_x2 = min(rect1.x + rect1.width, rect2.x + rect2.width) - dest_y2 = min(rect1.y + rect1.height, rect2.y + rect2.height) - - if dest_x2 >= dest_x and dest_y2 >= dest_y: - result.x = dest_x - result.y = dest_y - result.width = dest_x2 - dest_x - result.height = dest_y2 - dest_y - - tokens = ["AXComponent: The intersection of", rect1, "and", rect2, "is:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_size(obj: Atspi.Accessible) -> tuple[int, int]: - """Returns the width, height tuple of obj with respect to its window.""" - - if not AXObject.supports_component(obj): - return -1, -1 - - try: - point = Atspi.Component.get_size(obj, Atspi.CoordType.WINDOW) - except GLib.GError as error: - msg = f"AXComponent: Exception in get_position: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1, -1 - - if point is None: - tokens = ["AXComponent: get_size failed for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return -1, -1 - - # An Atspi.Point object stores width in x and height in y. - return point.x, point.y - - @staticmethod - def has_no_size(obj: Atspi.Accessible) -> bool: - """Returns True if obj has a width and height of 0.""" - - rect = AXComponent.get_rect(obj) - return not(rect.width or rect.height) - - @staticmethod - def has_no_size_or_invalid_rect(obj: Atspi.Accessible, clear_cache: bool = True) -> bool: - """Returns True if the rect associated with obj is sizeless or invalid.""" - - rect = AXComponent.get_rect(obj) - if not (rect.width or rect.height): - return True - - if rect.x == rect.y == rect.width == rect.height == -1: - return True - - if (rect.width < -1 or rect.height < -1): - tokens = ["WARNING: ", obj, "has a broken rect:", rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if clear_cache: - AXObject.clear_cache(obj) - rect = AXComponent.get_rect(obj) - if (rect.width < -1 or rect.height < -1): - msg = "AXComponent: Clearing cache did not fix the rect" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - return False - - @staticmethod - def is_empty_rect(rect: Atspi.Rect) -> bool: - """Returns True if rect's x, y, width, and height are all 0.""" - - return rect.x == 0 and rect.y == 0 and rect.width == 0 and rect.height == 0 - - @staticmethod - def is_same_rect(rect1: Atspi.Rect, rect2: Atspi.Rect) -> bool: - """Returns True if rect1 and rect2 represent the same bounding box.""" - - return rect1.x == rect2.x \ - and rect1.y == rect2.y \ - and rect1.width == rect2.width \ - and rect1.height == rect2.height - - @staticmethod - def object_contains_point(obj: Atspi.Accessible, x: int, y: int) -> bool: - """Returns True if obj's rect contains the specified point.""" - - if not AXObject.supports_component(obj): - return False - - if AXObject.is_bogus(obj): - return False - - try: - result = Atspi.Component.contains(obj, x, y, Atspi.CoordType.WINDOW) - except GLib.GError as error: - msg = f"AXComponent: Exception in object_contains_point: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - tokens = ["AXComponent: ", obj, f"contains point {x}, {y}: {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def object_intersects_rect(obj: Atspi.Accessible, rect: Atspi.Rect) -> bool: - """Returns True if the Atspi.Rect associated with obj intersects rect.""" - - intersection = AXComponent.get_rect_intersection(AXComponent.get_rect(obj), rect) - return not AXComponent.is_empty_rect(intersection) - - @staticmethod - def object_is_off_screen(obj: Atspi.Accessible) -> bool: - """Returns True if the rect associated with obj is off-screen""" - - rect = AXComponent.get_rect(obj) - if abs(rect.x) > 10000 or abs(rect.y) > 10000: - tokens = ["AXComponent: Treating", obj, "as offscreen due to position"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - if rect.width == 0 or rect.height == 0: - if not AXObject.get_child_count(obj): - tokens = ["AXComponent: Treating", obj, "as offscreen due to size and no children"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - if AXUtilitiesRole.is_menu(obj): - tokens = ["AXComponent: Treating", obj, "as offscreen due to size and role"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - tokens = ["AXComponent: Treating sizeless", obj, "as onscreen"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - result = rect.x + rect.width < 0 and rect.y + rect.height < 0 - tokens = ["AXComponent:", obj, f"is off-screen: {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def objects_have_same_rect(obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> bool: - """Returns True if obj1 and obj2 have the same rect.""" - - return AXComponent.is_same_rect(AXComponent.get_rect(obj1),AXComponent.get_rect(obj2)) - - @staticmethod - def objects_overlap(obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> bool: - """Returns True if the rects associated with obj1 and obj2 overlap.""" - - intersection = AXComponent.get_rect_intersection( - AXComponent.get_rect(obj1), AXComponent.get_rect(obj2)) - return not AXComponent.is_empty_rect(intersection) - - @staticmethod - def on_same_line(obj1: Atspi.Accessible, obj2: Atspi.Accessible, delta: int = 0) -> bool: - """Returns True if obj1 and obj2 are on the same line.""" - - rect1 = AXComponent.get_rect(obj1) - rect2 = AXComponent.get_rect(obj2) - y1_center = rect1.y + rect1.height / 2 - y2_center = rect2.y + rect2.height / 2 - - # If the center points differ by more than delta, they are not on the same line. - if abs(y1_center - y2_center) > delta: - return False - - # If there's a significant difference in height, they are not on the same line. - min_height = min(rect1.height, rect2.height) - max_height = max(rect1.height, rect2.height) - if min_height > 0 and max_height / min_height > 2.0: - return False - - return True - - @staticmethod - def _object_bounds_includes_children(obj: Atspi.Accessible) -> bool: - """Returns True if obj's rect is expected to include the rects of its children.""" - - if AXUtilitiesRole.is_menu(obj) or AXUtilitiesRole.is_page_tab(obj): - return False - - rect = AXComponent.get_rect(obj) - return rect.width > 0 and rect.height > 0 - - @staticmethod - def _find_descendant_at_point( - obj: Atspi.Accessible, x: int, y: int - ) -> Optional[Atspi.Accessible]: - """Checks each child to see if it has a descendant at the specified point.""" - - for child in AXObject.iter_children(obj): - if AXComponent._object_bounds_includes_children(child): - continue - for descendant in AXObject.iter_children(child): - if AXComponent.object_contains_point(descendant, x, y): - return descendant - return None - - @staticmethod - def _get_object_at_point(obj: Atspi.Accessible, x: int, y: int) -> Optional[Atspi.Accessible]: - """Returns the child (or descendant?) of obj at the specified point.""" - - if not AXObject.supports_component(obj): - return None - - try: - result = Atspi.Component.get_accessible_at_point(obj, x, y, Atspi.CoordType.WINDOW) - except GLib.GError as error: - msg = f"AXComponent: Exception in get_child_at_point: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - - tokens = ["AXComponent: Child of", obj, f"at {x}, {y} is", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def _get_descendant_at_point( - obj: Atspi.Accessible, x: int, y: int - ) -> Optional[Atspi.Accessible]: - """Returns the deepest descendant of obj at the specified point.""" - - child = AXComponent._get_object_at_point(obj, x, y) - if child is None and AXComponent.object_contains_point(obj, x, y): - descendant = AXComponent._find_descendant_at_point(obj, x, y) - if descendant is None: - return obj - child = descendant - - if child == obj or not AXObject.get_child_count(child): - return child - - result = AXComponent._get_descendant_at_point(child, x, y) - if result and not AXObject.is_dead(result): - return result - return child - - @staticmethod - def get_descendant_at_point( - obj: Atspi.Accessible, x: int, y: int - ) -> Optional[Atspi.Accessible]: - """Returns the deepest descendant of obj at the specified point.""" - - result = AXComponent._get_descendant_at_point(obj, x, y) - tokens = ["AXComponent: Descendant of", obj, f"at {x}, {y} is", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def scroll_object_to_point(obj: Atspi.Accessible, x: int, y: int) -> bool: - """Attempts to scroll obj to the specified point.""" - - if not AXObject.supports_component(obj): - return False - - try: - result = Atspi.Component.scroll_to_point(obj, Atspi.CoordType.WINDOW, x, y) - except GLib.GError as error: - msg = f"AXComponent: Exception in scroll_object_to_point: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - tokens = ["AXComponent: Scrolled", obj, f"to {x}, {y}:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def scroll_object_to_location(obj: Atspi.Accessible, location: Atspi.ScrollType) -> bool: - """Attempts to scroll obj to the specified Atspi.ScrollType location.""" - - if not AXObject.supports_component(obj): - return False - - try: - result = Atspi.Component.scroll_to(obj, location) - except GLib.GError as error: - msg = f"AXComponent: Exception in scroll_object_to_location: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - tokens = ["AXComponent: Scrolled", obj, "to", location, f": {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def sort_objects_by_size(objects: list[Atspi.Accessible]) -> list[Atspi.Accessible]: - """Returns objects sorted from smallest to largest.""" - - def _size_comparison(obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> int: - rect1 = AXComponent.get_rect(obj1) - rect2 = AXComponent.get_rect(obj2) - return (rect1.width * rect1.height) - (rect2.width * rect2.height) - - return sorted(objects, key=functools.cmp_to_key(_size_comparison)) - - @staticmethod - def sort_objects_by_position(objects: list[Atspi.Accessible]) -> list[Atspi.Accessible]: - """Returns objects sorted from top-left to bottom-right.""" - - def _spatial_comparison(obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> int: - rect1 = AXComponent.get_rect(obj1) - rect2 = AXComponent.get_rect(obj2) - rv = rect1.y - rect2.y or rect1.x - rect2.x - - # If the objects claim to have the same coordinates and the same parent, - # we probably have bogus coordinates from the implementation. - if not rv and AXObject.get_parent(obj1) == AXObject.get_parent(obj2): - rv = AXObject.get_index_in_parent(obj1) - AXObject.get_index_in_parent(obj2) - - rv = max(rv, -1) - rv = min(rv, 1) - return rv - - return sorted(objects, key=functools.cmp_to_key(_spatial_comparison)) diff --git a/src/cthulhu/ax_document.py b/src/cthulhu/ax_document.py deleted file mode 100644 index f261c18..0000000 --- a/src/cthulhu/ax_document.py +++ /dev/null @@ -1,280 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2024 Igalia, S.L. -# Copyright 2024 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position - -"""Utilities for obtaining document-related information about accessible objects.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Igalia, S.L." \ - "Copyright (c) 2024 GNOME Foundation Inc." -__license__ = "LGPL" - -import threading -import time -import urllib.parse - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from . import messages -from .ax_collection import AXCollection -from .ax_object import AXObject -from .ax_table import AXTable -from .ax_utilities_role import AXUtilitiesRole -from .ax_utilities_state import AXUtilitiesState - -class AXDocument: - """Utilities for obtaining document-related information about accessible objects.""" - - LAST_KNOWN_PAGE: dict[int, int] = {} - _lock = threading.Lock() - - @staticmethod - def _clear_stored_data() -> None: - """Clears any data we have cached for objects""" - - while True: - time.sleep(60) - msg = "AXDocument: Clearing local cache." - debug.print_message(debug.LEVEL_INFO, msg, True) - AXDocument.LAST_KNOWN_PAGE.clear() - - @staticmethod - def start_cache_clearing_thread() -> None: - """Starts thread to periodically clear cached details.""" - - thread = threading.Thread(target=AXDocument._clear_stored_data) - thread.daemon = True - thread.start() - - @staticmethod - def did_page_change(document: Atspi.Accessible) -> bool: - """Returns True if the current page changed.""" - - if not AXObject.supports_document(document): - return False - - old_page = AXDocument.LAST_KNOWN_PAGE.get(hash(document)) - result = old_page != AXDocument._get_current_page(document) - if result: - tokens = ["AXDocument: Previous page of", document, f"was {old_page}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return result - - @staticmethod - def _get_current_page(document: Atspi.Accessible) -> int: - """Returns the current page of document.""" - - if not AXObject.supports_document(document): - return 0 - - try: - page = Atspi.Document.get_current_page_number(document) - except GLib.GError as error: - msg = f"AXDocument: Exception in _get_current_page: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0 - - tokens = ["AXDocument: Current page of", document, f"is {page}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return page - - @staticmethod - def get_current_page(document: Atspi.Accessible) -> int: - """Returns the current page of document.""" - - if not AXObject.supports_document(document): - return 0 - - page = AXDocument._get_current_page(document) - AXDocument.LAST_KNOWN_PAGE[hash(document)] = page - return page - - @staticmethod - def get_page_count(document: Atspi.Accessible) -> int: - """Returns the page count of document.""" - - if not AXObject.supports_document(document): - return 0 - - try: - count = Atspi.Document.get_page_count(document) - except GLib.GError as error: - msg = f"AXDocument: Exception in get_page_count: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0 - - tokens = ["AXDocument: Page count of", document, f"is {count}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return count - - @staticmethod - def get_locale(document: Atspi.Accessible) -> str: - """Returns the locale of document.""" - - if not AXObject.supports_document(document): - return "" - - try: - result = Atspi.Document.get_locale(document) - except GLib.GError as error: - msg = f"AXDocument: Exception in get_locale: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "" - - if result is None: - tokens = ["AXDocument: get_locale failed for", document] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return "" - - tokens = ["AXDocument: Locale of", document, f"is '{result}'"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def _get_attributes_dict(document: Atspi.Accessible) -> dict[str, str]: - """Returns a dict with the document-attributes of document.""" - - if not AXObject.supports_document(document): - return {} - - try: - result = Atspi.Document.get_document_attributes(document) - except GLib.GError as error: - msg = f"AXDocument: Exception in _get_attributes_dict: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return {} - - tokens = ["AXDocument: Attributes of", document, "are:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result or {} - - @staticmethod - def get_uri(document: Atspi.Accessible) -> str: - """Returns the uri of document.""" - - if not AXObject.supports_document(document): - return "" - - attributes = AXDocument._get_attributes_dict(document) - return attributes.get("DocURL", attributes.get("URI", "")) - - @staticmethod - def get_mime_type(document: Atspi.Accessible) -> str: - """Returns the uri of document.""" - - if not AXObject.supports_document(document): - return "" - - attributes = AXDocument._get_attributes_dict(document) - return attributes.get("MimeType", "") - - @staticmethod - def is_plain_text(document: Atspi.Accessible) -> bool: - """Returns True if document is a plain-text document.""" - - return AXDocument.get_mime_type(document) == "text/plain" - - @staticmethod - def is_pdf(document: Atspi.Accessible) -> bool: - """Returns True if document is a PDF document.""" - - mime_type = AXDocument.get_mime_type(document) - if mime_type == "application/pdf": - return True - if mime_type == "text/html": - return AXDocument.get_uri(document).endswith(".pdf") - return False - - @staticmethod - def get_document_uri_fragment(document: Atspi.Accessible) -> str: - """Returns the fragment portion of document's uri.""" - - result = urllib.parse.urlparse(AXDocument.get_uri(document)) - return result.fragment - - @staticmethod - def _get_object_counts(document: Atspi.Accessible) -> dict[str, int]: - """Returns a dictionary of object counts used in a document summary.""" - - result = {"forms": 0, - "landmarks": 0, - "headings": 0, - "tables": 0, - "unvisited_links": 0, - "visited_links": 0} - - roles = [Atspi.Role.HEADING, - Atspi.Role.LINK, - Atspi.Role.TABLE, - Atspi.Role.FORM, - Atspi.Role.LANDMARK] - - rule = AXCollection.create_match_rule( - roles=roles, role_match_type=Atspi.CollectionMatchType.ANY) - matches = AXCollection.get_all_matches(document, rule) - - for obj in matches: - if AXUtilitiesRole.is_heading(obj): - result["headings"] += 1 - elif AXUtilitiesRole.is_form(obj): - result["forms"] += 1 - elif AXUtilitiesRole.is_table(obj) and not AXTable.is_layout_table(obj): - result["tables"] += 1 - elif AXUtilitiesRole.is_link(obj): - if AXUtilitiesState.is_visited(obj): - result["visited_links"] += 1 - else: - result["unvisited_links"] += 1 - elif AXUtilitiesRole.is_landmark(obj): - result["landmarks"] += 1 - - return result - - @staticmethod - def get_document_summary(document: Atspi.Accessible, only_if_found: bool = True) -> str: - """Returns a string summarizing the document's structure and objects of interest.""" - - result = [] - counts = AXDocument._get_object_counts(document) - result.append(messages.landmark_count(counts.get("landmarks", 0), only_if_found)) - result.append(messages.heading_count(counts.get("headings", 0), only_if_found)) - result.append(messages.form_count(counts.get("forms", 0), only_if_found)) - result.append(messages.table_count(counts.get("tables", 0), only_if_found)) - result.append(messages.visited_link_count(counts.get("visited_links", 0), only_if_found)) - result.append(messages.unvisited_link_count( - counts.get("unvisited_links", 0), only_if_found)) - result = list(filter(lambda x: x, result)) - if not result: - return "" - - return messages.PAGE_SUMMARY_PREFIX % ", ".join(result) diff --git a/src/cthulhu/ax_document_selection.py b/src/cthulhu/ax_document_selection.py deleted file mode 100644 index 975d696..0000000 --- a/src/cthulhu/ax_document_selection.py +++ /dev/null @@ -1,571 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Helpers for document-wide AT-SPI text selections.""" - -from __future__ import annotations - -import functools -from dataclasses import dataclass, field -from typing import Any, Optional, TYPE_CHECKING - -import gi - -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from .ax_object import AXObject -from .ax_text import AXText - -if TYPE_CHECKING: - from .script_utilities import Utilities - - -@dataclass -class AXSelectionRange: - start_object: Atspi.Accessible - start_offset: int - end_object: Atspi.Accessible - end_offset: int - start_is_active: bool = False - - def anchor_endpoint(self) -> tuple[Any, int]: - if self.start_is_active: - return self.end_object, self.end_offset - return self.start_object, self.start_offset - - def focus_endpoint(self) -> tuple[Any, int]: - if self.start_is_active: - return self.start_object, self.start_offset - return self.end_object, self.end_offset - - def active_endpoint(self) -> tuple[Any, int]: - if self.start_is_active: - return self.start_object, self.start_offset - return self.end_object, self.end_offset - - -@dataclass -class AXSelectionSnapshot: - document: Optional[Atspi.Accessible] - source_object: Optional[Atspi.Accessible] - ranges: list[AXSelectionRange] = field(default_factory=list) - anchor_focus_pairs: list[tuple[Any, int, Any, int]] = field(default_factory=list) - entire_document_selected: bool = False - is_authoritative: bool = False - - -@dataclass -class AXProjectedSelection: - obj: Optional[Atspi.Accessible] - local_ranges: list[tuple[int, int]] = field(default_factory=list) - text: str = "" - start_offset: int = 0 - end_offset: int = 0 - - -class AXDocumentSelection: - """Normalizes and applies document-wide text selections.""" - - def __init__(self, utilities: "Utilities") -> None: - self._utilities = utilities - - def empty_snapshot( - self, - source_object: Optional[Atspi.Accessible] = None, - document: Optional[Atspi.Accessible] = None, - ) -> AXSelectionSnapshot: - return AXSelectionSnapshot(document=document, source_object=source_object) - - def get_cached_snapshot(self, obj: Optional[Atspi.Accessible]) -> AXSelectionSnapshot: - document = self._utilities.getDocumentForObject(obj) - state = self._utilities._script.pointOfReference.get("selectionState", {}) - snapshot = state.get("snapshot") - if snapshot is None: - return self.empty_snapshot(obj, document) - if state.get("document") != document: - return self.empty_snapshot(obj, document) - return snapshot - - def refresh_snapshot(self, obj: Optional[Atspi.Accessible]) -> AXSelectionSnapshot: - document = self._utilities.getDocumentForObject(obj) - snapshot = self._fetch_snapshot(document, obj) - state = self._utilities._script.pointOfReference.get("selectionState", {}) - if state.get("document") != document: - state = {} - state["document"] = document - state["snapshot"] = snapshot - state.setdefault("textSelections", {}) - self._utilities._script.pointOfReference["selectionState"] = state - if snapshot.is_authoritative: - self._utilities._script.pointOfReference["entireDocumentSelected"] = snapshot.entire_document_selected - return snapshot - - def get_selected_objects(self, snapshot: AXSelectionSnapshot) -> list[Atspi.Accessible]: - seen = set() - objects = [] - for selectionRange in snapshot.ranges: - for obj in self._objects_for_range(selectionRange): - if hash(obj) in seen: - continue - seen.add(hash(obj)) - objects.append(obj) - return objects - - def get_projected_selection( - self, - obj: Optional[Atspi.Accessible], - snapshot: Optional[AXSelectionSnapshot] = None, - ) -> AXProjectedSelection: - if not obj: - return AXProjectedSelection(obj) - - snapshot = snapshot or self.get_cached_snapshot(obj) - if not snapshot.is_authoritative: - return AXProjectedSelection(obj) - - localRanges = [] - for selectionRange in snapshot.ranges: - localRanges.extend(self._project_range_onto_object(selectionRange, obj)) - localRanges = self._merge_ranges(localRanges) - - fragments = [] - for startOffset, endOffset in localRanges: - text = self._utilities.expandEOCs(obj, startOffset, endOffset) - if text: - fragments.append(text) - - if localRanges: - startOffset = localRanges[0][0] - endOffset = localRanges[-1][1] - else: - startOffset = endOffset = 0 - - return AXProjectedSelection( - obj=obj, - local_ranges=localRanges, - text=" ".join(fragments), - start_offset=startOffset, - end_offset=endOffset, - ) - - def get_all_selected_text( - self, - obj: Optional[Atspi.Accessible], - snapshot: Optional[AXSelectionSnapshot] = None, - ) -> tuple[str, int, int]: - if not obj: - return "", 0, 0 - - snapshot = snapshot or self.get_cached_snapshot(obj) - projected = self.get_projected_selection(obj, snapshot) - if not snapshot.is_authoritative or not snapshot.ranges: - return projected.text, projected.start_offset, projected.end_offset - - fragments = [] - for selectionRange in snapshot.ranges: - text = self._range_text(selectionRange) - if text: - fragments.append(text) - - return " ".join(fragments), projected.start_offset, projected.end_offset - - def clear_selection(self, obj: Optional[Atspi.Accessible]) -> bool: - if not obj: - return False - - snapshot = self.refresh_snapshot(obj) - if not snapshot.is_authoritative: - return False - - projected = self.get_projected_selection(obj, snapshot) - if not projected.local_ranges and not snapshot.entire_document_selected: - return False - - return self._set_document_ranges(snapshot.document, []) - - def adjust_selection(self, obj: Optional[Atspi.Accessible], offset: int) -> bool: - if not obj: - return False - - snapshot = self.refresh_snapshot(obj) - if not snapshot.is_authoritative: - return False - - ranges = list(snapshot.ranges) - anchorOffset = AXText.get_caret_offset(obj) - rangeIndex = self._resolve_primary_range_index(ranges, obj, anchorOffset) - if rangeIndex is None: - rangeIndex = len(ranges) - ranges.append( - AXSelectionRange( - start_object=obj, - start_offset=anchorOffset, - end_object=obj, - end_offset=anchorOffset, - start_is_active=False, - ) - ) - - selectionRange = ranges[rangeIndex] - anchorObject, anchorOffset = selectionRange.anchor_endpoint() - updatedRange = self._build_range(anchorObject, anchorOffset, obj, offset) - if updatedRange is None: - return False - - ranges[rangeIndex] = updatedRange - return self._set_document_ranges(snapshot.document, ranges) - - def _fetch_snapshot( - self, - document: Optional[Atspi.Accessible], - source_object: Optional[Atspi.Accessible], - ) -> AXSelectionSnapshot: - if not document: - return self.empty_snapshot(source_object, document) - - try: - rawSelections = Atspi.Document.get_text_selections(document) - except (AttributeError, GLib.GError, TypeError) as error: - msg = f"AXDocumentSelection: Exception in get_text_selections: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return self.empty_snapshot(source_object, document) - - ranges = [] - for rawSelection in rawSelections or []: - selectionRange = self._normalize_range(document, rawSelection) - if selectionRange is None: - return self.empty_snapshot(source_object, document) - ranges.append(selectionRange) - - ranges.sort(key=functools.cmp_to_key(self._compare_ranges)) - return AXSelectionSnapshot( - document=document, - source_object=source_object, - ranges=ranges, - anchor_focus_pairs=[ - ( - selectionRange.anchor_endpoint()[0], - selectionRange.anchor_endpoint()[1], - selectionRange.focus_endpoint()[0], - selectionRange.focus_endpoint()[1], - ) - for selectionRange in ranges - ], - entire_document_selected=self._is_entire_document_selected(ranges), - is_authoritative=bool(ranges), - ) - - def _normalize_range( - self, - document: Atspi.Accessible, - rawSelection: Any, - ) -> Optional[AXSelectionRange]: - startObject = getattr(rawSelection, "start_object", None) - endObject = getattr(rawSelection, "end_object", None) - startOffset = getattr(rawSelection, "start_offset", 0) - endOffset = getattr(rawSelection, "end_offset", 0) - startIsActive = bool(getattr(rawSelection, "start_is_active", False)) - - if not startObject or not endObject: - return None - if not AXObject.supports_text(startObject) or not AXObject.supports_text(endObject): - return None - if self._utilities.getDocumentForObject(startObject) != document: - return None - if self._utilities.getDocumentForObject(endObject) != document: - return None - - comparison = self._compare_positions(startObject, startOffset, endObject, endOffset) - if comparison is None: - return None - if comparison > 0: - startObject, endObject = endObject, startObject - startOffset, endOffset = endOffset, startOffset - startIsActive = not startIsActive - - if startObject == endObject and startOffset > endOffset: - startOffset, endOffset = endOffset, startOffset - startIsActive = not startIsActive - - if startObject == endObject and startOffset == endOffset: - return None - - return AXSelectionRange( - start_object=startObject, - start_offset=startOffset, - end_object=endObject, - end_offset=endOffset, - start_is_active=startIsActive, - ) - - def _is_entire_document_selected(self, ranges: list[AXSelectionRange]) -> bool: - if len(ranges) != 1: - return False - - selectionRange = ranges[0] - if selectionRange.start_offset != 0: - return False - if selectionRange.end_offset != AXText.get_character_count(selectionRange.end_object): - return False - - if self._find_previous_text_object(selectionRange.start_object) is not None: - return False - if self._find_next_text_object(selectionRange.end_object) is not None: - return False - - return True - - def _find_previous_text_object(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - current = obj - while current: - current = self._utilities.findPreviousObject(current) - if current is None: - return None - text = self._utilities.queryNonEmptyText(current) - if text: - return text - return None - - def _find_next_text_object(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - current = obj - while current: - current = self._utilities.findNextObject(current) - if current is None: - return None - text = self._utilities.queryNonEmptyText(current) - if text: - return text - return None - - def _compare_ranges(self, range1: AXSelectionRange, range2: AXSelectionRange) -> int: - comparison = self._compare_positions( - range1.start_object, - range1.start_offset, - range2.start_object, - range2.start_offset, - ) - if comparison is None: - return 0 - return comparison - - def _compare_positions( - self, - obj1: Atspi.Accessible, - offset1: int, - obj2: Atspi.Accessible, - offset2: int, - ) -> Optional[int]: - if obj1 == obj2: - if offset1 < offset2: - return -1 - if offset1 > offset2: - return 1 - return 0 - - seen = {hash(obj1)} - current = obj1 - while current: - current = self._utilities.findNextObject(current) - if current is None: - break - if hash(current) in seen: - break - if current == obj2: - return -1 - seen.add(hash(current)) - - seen = {hash(obj2)} - current = obj2 - while current: - current = self._utilities.findNextObject(current) - if current is None: - break - if hash(current) in seen: - break - if current == obj1: - return 1 - seen.add(hash(current)) - - return None - - def _objects_for_range(self, selectionRange: AXSelectionRange) -> list[Atspi.Accessible]: - objects = [selectionRange.start_object] - if selectionRange.start_object == selectionRange.end_object: - return objects - - seen = {hash(selectionRange.start_object)} - current = selectionRange.start_object - while current and current != selectionRange.end_object: - current = self._utilities.findNextObject(current) - if current is None or hash(current) in seen: - return [] - seen.add(hash(current)) - if self._utilities.queryNonEmptyText(current): - objects.append(current) - - if not objects or objects[-1] != selectionRange.end_object: - return [] - - return objects - - def _project_range_onto_object( - self, - selectionRange: AXSelectionRange, - obj: Atspi.Accessible, - ) -> list[tuple[int, int]]: - rangeObjects = self._objects_for_range(selectionRange) - if obj not in rangeObjects: - return [] - - if selectionRange.start_object == selectionRange.end_object == obj: - startOffset = min(selectionRange.start_offset, selectionRange.end_offset) - endOffset = max(selectionRange.start_offset, selectionRange.end_offset) - if startOffset < endOffset: - return [(startOffset, endOffset)] - return [] - - if obj == selectionRange.start_object: - startOffset = selectionRange.start_offset - endOffset = AXText.get_character_count(obj) - return [(startOffset, endOffset)] if startOffset < endOffset else [] - - if obj == selectionRange.end_object: - startOffset = 0 - endOffset = selectionRange.end_offset - return [(startOffset, endOffset)] if startOffset < endOffset else [] - - endOffset = AXText.get_character_count(obj) - return [(0, endOffset)] if endOffset else [] - - @staticmethod - def _merge_ranges(ranges: list[tuple[int, int]]) -> list[tuple[int, int]]: - if not ranges: - return [] - - merged = [] - for startOffset, endOffset in sorted(ranges): - if not merged or startOffset > merged[-1][1]: - merged.append((startOffset, endOffset)) - continue - merged[-1] = (merged[-1][0], max(merged[-1][1], endOffset)) - - return merged - - def _range_text(self, selectionRange: AXSelectionRange) -> str: - fragments = [] - for obj in self._objects_for_range(selectionRange): - if obj == selectionRange.start_object == selectionRange.end_object: - startOffset = selectionRange.start_offset - endOffset = selectionRange.end_offset - elif obj == selectionRange.start_object: - startOffset = selectionRange.start_offset - endOffset = AXText.get_character_count(obj) - elif obj == selectionRange.end_object: - startOffset = 0 - endOffset = selectionRange.end_offset - else: - startOffset = 0 - endOffset = AXText.get_character_count(obj) - - if startOffset >= endOffset: - continue - - text = self._utilities.expandEOCs(obj, startOffset, endOffset) - if text: - fragments.append(text) - - return " ".join(fragments) - - def _resolve_primary_range_index( - self, - ranges: list[AXSelectionRange], - obj: Atspi.Accessible, - caretOffset: int, - ) -> Optional[int]: - containing = [] - projected = [] - active = [] - for index, selectionRange in enumerate(ranges): - localRanges = self._project_range_onto_object(selectionRange, obj) - if localRanges: - projected.append(index) - for startOffset, endOffset in localRanges: - if startOffset <= caretOffset <= endOffset: - containing.append(index) - break - if selectionRange.active_endpoint()[0] == obj: - active.append(index) - - if len(containing) == 1: - return containing[0] - if len(projected) == 1: - return projected[0] - if len(active) == 1: - return active[0] - return None - - def _build_range( - self, - anchorObject: Atspi.Accessible, - anchorOffset: int, - focusObject: Atspi.Accessible, - focusOffset: int, - ) -> Optional[AXSelectionRange]: - comparison = self._compare_positions(anchorObject, anchorOffset, focusObject, focusOffset) - if comparison is None: - return None - if comparison <= 0: - return AXSelectionRange( - start_object=anchorObject, - start_offset=anchorOffset, - end_object=focusObject, - end_offset=focusOffset, - start_is_active=False, - ) - - return AXSelectionRange( - start_object=focusObject, - start_offset=focusOffset, - end_object=anchorObject, - end_offset=anchorOffset, - start_is_active=True, - ) - - def _set_document_ranges( - self, - document: Optional[Atspi.Accessible], - ranges: list[AXSelectionRange], - ) -> bool: - if not document: - return False - - selections = [] - for selectionRange in ranges: - selection = Atspi.TextSelection() - selection.start_object = selectionRange.start_object - selection.start_offset = selectionRange.start_offset - selection.end_object = selectionRange.end_object - selection.end_offset = selectionRange.end_offset - selection.start_is_active = selectionRange.start_is_active - selections.append(selection) - - try: - result = Atspi.Document.set_text_selections(document, selections) - except (AttributeError, GLib.GError, TypeError) as error: - msg = f"AXDocumentSelection: Exception in set_text_selections: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - return bool(result) diff --git a/src/cthulhu/ax_event_synthesizer.py b/src/cthulhu/ax_event_synthesizer.py deleted file mode 100644 index bc77c1b..0000000 --- a/src/cthulhu/ax_event_synthesizer.py +++ /dev/null @@ -1,362 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2005-2008 Sun Microsystems Inc. -# Copyright 2018-2023 Igalia, S.L. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-public-methods - -"""Provides support for synthesizing accessible input events.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2018-2023 Igalia, S.L." -__license__ = "LGPL" - -from typing import Optional -import gi -gi.require_version("Atspi", "2.0") -gi.require_version("Gtk", "3.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from .ax_component import AXComponent -from .ax_object import AXObject -from .ax_text import AXText -from .ax_utilities_debugging import AXUtilitiesDebugging -from .ax_utilities_role import AXUtilitiesRole - -class AXEventSynthesizer: - """Provides support for synthesizing accessible input events.""" - - @staticmethod - def _highest_ancestor(obj: Atspi.Accessible) -> bool: - """Returns True if the parent of obj is the application or None.""" - - parent = AXObject.get_parent(obj) - return parent is None or AXUtilitiesRole.is_application(parent) - - @staticmethod - def _is_scrolled_off_screen( - obj: Atspi.Accessible, - offset: Optional[int] = None, - ancestor: Optional[Atspi.Accessible] = None - ) -> bool: - """Returns true if obj, or the caret offset therein, is scrolled off-screen.""" - - tokens = ["AXEventSynthesizer: Checking if", obj, "is scrolled offscreen"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - rect = AXComponent.get_rect(obj) - ancestor = ancestor or AXObject.find_ancestor(obj, AXEventSynthesizer._highest_ancestor) - if ancestor is None: - tokens = ["AXEventSynthesizer: Could not get ancestor of", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - ancestor_rect = AXComponent.get_rect(ancestor) - intersection = AXComponent.get_rect_intersection(ancestor_rect, rect) - if AXComponent.is_empty_rect(intersection): - tokens = ["AXEventSynthesizer:", obj, "is outside of", ancestor, ancestor_rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - if offset is None: - tokens = ["AXEventSynthesizer:", obj, "is not scrolled offscreen"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - extents = AXText.get_character_rect(obj, offset) - if AXComponent.is_empty_rect(extents): - tokens = ["AXEventSynthesizer: Could not get character rect of", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - intersection = AXComponent.get_rect_intersection(extents, rect) - if AXComponent.is_empty_rect(intersection): - tokens = ["AXEventSynthesizer:", obj, "'s caret", extents, "not in obj", rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - @staticmethod - def _generate_mouse_event( - obj: Atspi.Accessible, relative_x: int, relative_y: int, event: str - ) -> bool: - tokens = ["AXEventSynthesizer: Attempting to generate mouse event on", obj, - f"at relative coordinates {relative_x},{relative_y}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - try: - device = Atspi.Device.new() - Atspi.Device.generate_mouse_event(device, obj, relative_x, relative_y, event) - except GLib.GError as error: - message = f"AXEventSynthesizer: Exception in _generate_mouse_event_new: {error}" - debug.print_message(debug.LEVEL_INFO, message, True) - return False - return True - - @staticmethod - def _mouse_event_on_character(obj: Atspi.Accessible, offset: Optional[int], event: str) -> bool: - """Performs the specified mouse event on the current character in obj.""" - - if offset is None: - offset = max(AXText.get_caret_offset(obj), 0) - - if AXEventSynthesizer._is_scrolled_off_screen(obj, offset): - AXEventSynthesizer.scroll_into_view(obj, offset) - if AXEventSynthesizer._is_scrolled_off_screen(obj, offset): - tokens = ["AXEventSynthesizer:", obj, "is still offscreen. Setting caret."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXText.set_caret_offset(obj, offset) - - extents = AXText.get_character_rect(obj, offset) - if AXComponent.is_empty_rect(extents): - return False - - rect = AXComponent.get_rect(obj) - intersection = AXComponent.get_rect_intersection(extents, rect) - if AXComponent.is_empty_rect(intersection): - tokens = ["AXEventSynthesizer:", obj, "'s caret", extents, "not in obj", rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - relative_x = (extents.x - rect.x) + extents.width / 2 - relative_y = (extents.y - rect.y) + extents.height / 2 - return AXEventSynthesizer._generate_mouse_event(obj, relative_x, relative_y, event) - - @staticmethod - def _mouse_event_on_object(obj: Atspi.Accessible, event: str) -> bool: - """Performs the specified mouse event on obj.""" - - if AXEventSynthesizer._is_scrolled_off_screen(obj): - AXEventSynthesizer.scroll_into_view(obj) - if AXEventSynthesizer._is_scrolled_off_screen(obj): - tokens = ["AXEventSynthesizer:", obj, "is still offscreen. Grabbing focus."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXObject.grab_focus(obj) - - rect = AXComponent.get_rect(obj) - relative_x = rect.width / 2 - relative_y = rect.height / 2 - return AXEventSynthesizer._generate_mouse_event(obj, relative_x, relative_y, event) - - @staticmethod - def route_to_character(obj: Atspi.Accessible, offset: Optional[int] = None) -> bool: - """Routes the pointer to the current character in obj.""" - - tokens = [f"AXEventSynthesizer: Attempting to route to offset {offset} in", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return AXEventSynthesizer._mouse_event_on_character(obj, offset, "abs") - - @staticmethod - def route_to_object(obj: Atspi.Accessible) -> bool: - """Moves the mouse pointer to the center of obj.""" - - tokens = ["AXEventSynthesizer: Attempting to route to", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return AXEventSynthesizer._mouse_event_on_object(obj, "abs") - - @staticmethod - def click_character( - obj: Atspi.Accessible, offset: Optional[int] = None, button: int = 1 - ) -> bool: - """Single click on the current character in obj using the specified button.""" - - tokens = [f"AXEventSynthesizer: Attempting to click at offset {offset} in", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return AXEventSynthesizer._mouse_event_on_character(obj, offset, f"b{button}c") - - @staticmethod - def click_object(obj: Atspi.Accessible, button: int = 1) -> bool: - """Single click on obj using the specified button.""" - - return AXEventSynthesizer._mouse_event_on_object(obj, f"b{button}c") - - @staticmethod - def _scroll_to_location( - obj: Atspi.Accessible, location: Atspi.ScrollType, - start_offset: Optional[int] = None, end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll to the specified location.""" - - before = AXComponent.get_position(obj) - AXText.scroll_substring_to_location(obj, location, start_offset, end_offset) - AXObject.clear_cache(obj, False, "To obtain updated location after scroll.") - after = AXComponent.get_position(obj) - tokens = ["AXEventSynthesizer: Text scroll, before:", before, "after:", after] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if before != after: - return - - AXComponent.scroll_object_to_location(obj, location) - AXObject.clear_cache(obj, False, "To obtain updated location after scroll.") - after = AXComponent.get_position(obj) - tokens = ["AXEventSynthesizer: Object scroll, before:", before, "after:", after] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - @staticmethod - def _scroll_to_point( - obj: Atspi.Accessible, x_coord: int, y_coord: int, - start_offset: Optional[int] = None, end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll obj to the specified point.""" - - before = AXComponent.get_position(obj) - AXText.scroll_substring_to_point(obj, x_coord, y_coord, start_offset, end_offset) - AXObject.clear_cache(obj, False, "To obtain updated location after scroll.") - after = AXComponent.get_position(obj) - tokens = ["AXEventSynthesizer: Text scroll, before:", before, "after:", after] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if before != after: - return - - AXComponent.scroll_object_to_point(obj, x_coord, y_coord) - AXObject.clear_cache(obj, False, "To obtain updated location after scroll.") - after = AXComponent.get_position(obj) - tokens = ["AXEventSynthesizer: Object scroll, before:", before, "after:", after] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - @staticmethod - def scroll_into_view( - obj: Atspi.Accessible, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll obj into view.""" - - AXEventSynthesizer._scroll_to_location( - obj, Atspi.ScrollType.ANYWHERE, start_offset, end_offset) - - @staticmethod - def scroll_to_center( - obj: Atspi.Accessible, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll obj to the center of its window.""" - - ancestor = AXObject.find_ancestor(obj, AXEventSynthesizer._highest_ancestor) - if ancestor is None: - tokens = ["AXEventSynthesizer: Could not get ancestor of", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return - - ancestor_rect = AXComponent.get_rect(ancestor) - x_coord = ancestor_rect.x + ancestor_rect.width / 2 - y_coord = ancestor_rect.y + ancestor_rect.height / 2 - AXEventSynthesizer._scroll_to_point(obj, x_coord, y_coord, start_offset, end_offset) - - @staticmethod - def scroll_to_top_edge( - obj: Atspi.Accessible, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll obj to the top edge.""" - - AXEventSynthesizer._scroll_to_location( - obj, Atspi.ScrollType.TOP_EDGE, start_offset, end_offset) - - @staticmethod - def scroll_to_top_left( - obj: Atspi.Accessible, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll obj to the top left.""" - - AXEventSynthesizer._scroll_to_location( - obj, Atspi.ScrollType.TOP_LEFT, start_offset, end_offset) - - @staticmethod - def scroll_to_left_edge( - obj: Atspi.Accessible, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll obj to the left edge.""" - - AXEventSynthesizer._scroll_to_location( - obj, Atspi.ScrollType.LEFT_EDGE, start_offset, end_offset) - - @staticmethod - def scroll_to_bottom_edge( - obj: Atspi.Accessible, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll obj to the bottom edge.""" - - AXEventSynthesizer._scroll_to_location( - obj, Atspi.ScrollType.BOTTOM_EDGE, start_offset, end_offset) - - @staticmethod - def scroll_to_bottom_right( - obj: Atspi.Accessible, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll obj to the bottom right.""" - - AXEventSynthesizer._scroll_to_location( - obj, Atspi.ScrollType.BOTTOM_RIGHT, start_offset, end_offset) - - @staticmethod - def scroll_to_right_edge( - obj: Atspi.Accessible, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> None: - """Attempts to scroll obj to the right edge.""" - - AXEventSynthesizer._scroll_to_location( - obj, Atspi.ScrollType.RIGHT_EDGE, start_offset, end_offset) - - @staticmethod - def try_all_clickable_actions(obj: Atspi.Accessible) -> bool: - """Attempts to perform a click-like action if one is available.""" - - actions = ["click", "press", "jump", "open", "activate"] - for action in actions: - if AXObject.do_named_action(obj, action): - tokens = ["AXEventSynthesizer: '", action, "' on", obj, "performed successfully"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - if debug.LEVEL_INFO < debug.debugLevel: - return False - - tokens = ["AXEventSynthesizer: Actions on", obj, ":", - AXUtilitiesDebugging.actions_as_string(obj)] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - -_synthesizer = AXEventSynthesizer() -def get_synthesizer() -> AXEventSynthesizer: - """Returns the Event Synthesizer.""" - - return _synthesizer diff --git a/src/cthulhu/ax_hypertext.py b/src/cthulhu/ax_hypertext.py deleted file mode 100644 index f2e741b..0000000 --- a/src/cthulhu/ax_hypertext.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2024 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position - -"""Utilities for obtaining information about accessible hypertext and hyperlinks.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Igalia, S.L." -__license__ = "LGPL" - -from typing import Optional -import os -import re -from urllib.parse import urlparse - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from .ax_object import AXObject - -class AXHypertext: - """Utilities for obtaining information about accessible hypertext and hyperlinks.""" - - @staticmethod - def _get_link_count(obj: Atspi.Accessible) -> int: - """Returns the number of hyperlinks in obj.""" - - if not AXObject.supports_hypertext(obj): - return 0 - - try: - count = Atspi.Hypertext.get_n_links(obj) - except GLib.GError as error: - msg = f"AXHypertext: Exception in _get_link_count: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0 - - tokens = ["AXHypertext:", obj, f"reports {count} hyperlinks"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return count - - @staticmethod - def _get_link_at_index(obj: Atspi.Accessible, index: int) -> Optional[Atspi.Hyperlink]: - """Returns the hyperlink object at the specified index.""" - - if not AXObject.supports_hypertext(obj): - return None - - try: - link = Atspi.Hypertext.get_link(obj, index) - except GLib.GError as error: - msg = f"AXHypertext: Exception in _get_link_at_index: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - - return link - - @staticmethod - def get_all_links_in_range( - obj: Atspi.Accessible, start_offset: int, end_offset: int - ) -> list[Atspi.Hyperlink]: - """Returns all the hyperlinks in obj who started within the specified range.""" - - links = [] - for i in range(AXHypertext._get_link_count(obj)): - link = AXHypertext._get_link_at_index(obj, i) - if start_offset <= AXHypertext.get_link_start_offset(link) < end_offset \ - or start_offset < AXHypertext.get_link_end_offset(link) <= end_offset: - links.append(link) - - tokens = [f"AXHypertext: {len(links)} hyperlinks found in", obj, - f"between start: {start_offset} and end: {end_offset}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return links - - @staticmethod - def get_all_links(obj: Atspi.Accessible) -> list[Atspi.Hyperlink]: - """Returns a list of all the hyperlinks in obj.""" - - links = [] - for i in range(AXHypertext._get_link_count(obj)): - link = AXHypertext._get_link_at_index(obj, i) - if link is not None: - links.append(link) - - tokens = [f"AXHypertext: {len(links)} hyperlinks found in", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return links - - @staticmethod - def get_link_uri(obj: Atspi.Accessible, index: int = 0) -> str: - """Returns the URI associated with obj at the specified index.""" - - try: - link = Atspi.Accessible.get_hyperlink(obj) - uri = Atspi.Hyperlink.get_uri(link, index) - except GLib.GError as error: - msg = f"AXHypertext: Exception in get_link_uri: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "" - - tokens = ["AXHypertext: URI of", obj, f"at index {index} is {uri}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return uri - - @staticmethod - def get_link_start_offset(obj: Atspi.Accessible) -> int: - """Returns the start offset of obj in the associated text.""" - - if isinstance(obj, Atspi.Hyperlink): - link = obj - obj = Atspi.Hyperlink.get_object(link, 0) - else: - link = Atspi.Accessible.get_hyperlink(obj) - - if link is None: - tokens = ["AXHypertext: Couldn't get hyperlink for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return -1 - - try: - offset = Atspi.Hyperlink.get_start_index(link) - except GLib.GError as error: - msg = f"AXHypertext: Exception in get_link_start_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1 - - tokens = ["AXHypertext: Start offset of", obj, f"is {offset}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return offset - - @staticmethod - def get_link_end_offset(obj: Atspi.Accessible) -> int: - """Returns the end offset of obj in the associated text.""" - - if isinstance(obj, Atspi.Hyperlink): - link = obj - obj = Atspi.Hyperlink.get_object(link, 0) - else: - link = Atspi.Accessible.get_hyperlink(obj) - - if link is None: - tokens = ["AXHypertext: Couldn't get hyperlink for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return -1 - - try: - offset = Atspi.Hyperlink.get_end_index(link) - except GLib.GError as error: - msg = f"AXHypertext: Exception in get_link_end_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1 - - tokens = ["AXHypertext: End offset of", obj, f"is {offset}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return offset - - @staticmethod - def get_link_basename( - obj: Atspi.Accessible, index: int = 0, remove_extension: bool = False - ) -> str: - """Strip directory and suffix off of the URL associated with obj.""" - - uri = AXHypertext.get_link_uri(obj, index) - if not uri: - return "" - - parsed_uri = urlparse(uri) - basename = os.path.basename(parsed_uri.path) - if remove_extension: - basename = os.path.splitext(basename)[0] - basename = re.sub(r"[-_]", " ", basename) - - tokens = ["AXHypertext: Basename for link", obj, f"is '{basename}'"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return basename - - @staticmethod - def find_child_at_offset(obj: Atspi.Accessible, offset: int) -> Optional[Atspi.Accessible]: - """Returns the child at offset, correcting for broken hypertext offset mappings.""" - - if child := AXHypertext.get_child_at_offset(obj, offset): - offset_in_parent = AXHypertext.get_character_offset_in_parent(child) - if offset_in_parent == offset: - return child - - tokens = [ - f"AXHypertext: Child at offset {offset} in", - obj, - "is", - child, - f"but reports offset {offset_in_parent}", - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if child_before := AXHypertext.get_child_at_offset(obj, offset - 1): - offset_in_parent = AXHypertext.get_character_offset_in_parent(child_before) - if offset_in_parent == offset: - tokens = [f"AXHypertext: Corrected child at offset {offset} in", obj, "is", - child_before, f"at offset {offset - 1}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return child_before - - if child_after := AXHypertext.get_child_at_offset(obj, offset + 1): - offset_in_parent = AXHypertext.get_character_offset_in_parent(child_after) - if offset_in_parent == offset: - tokens = [f"AXHypertext: Corrected child at offset {offset} in", obj, "is", - child_after, f"at offset {offset + 1}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return child_after - - for i in range(AXHypertext._get_link_count(obj)): - link = AXHypertext._get_link_at_index(obj, i) - if link is None or AXHypertext.get_link_start_offset(link) != offset: - continue - - try: - child = Atspi.Hyperlink.get_object(link, 0) - except GLib.GError as error: - msg = f"AXHypertext: Exception in find_child_at_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - continue - - if child is None: - continue - - tokens = [ - f"AXHypertext: Child at offset {offset} in", - obj, - "found via link enumeration:", - child, - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return child - - return None - - @staticmethod - def get_child_at_offset(obj: Atspi.Accessible, offset: int) -> Optional[Atspi.Accessible]: - """Returns the embedded-object child of obj at the specified offset.""" - - if not AXObject.supports_hypertext(obj): - return None - - try: - index = Atspi.Hypertext.get_link_index(obj, offset) - except GLib.GError as error: - msg = f"AXHypertext: Exception in get_child_at_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - - if index < 0: - return None - - link = AXHypertext._get_link_at_index(obj, index) - if link is None: - return None - - try: - child = Atspi.Hyperlink.get_object(link, 0) - except GLib.GError as error: - msg = f"AXHypertext: Exception in get_child_at_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - - tokens = [f"AXHypertext: Child at offset {offset} in", obj, "is", child] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return child - - @staticmethod - def get_character_offset_in_parent(obj: Atspi.Accessible) -> int: - """Returns the offset of the embedded-object obj in the text of its parent.""" - - if not AXObject.supports_text(AXObject.get_parent(obj)): - return -1 - - return AXHypertext.get_link_start_offset(obj) diff --git a/src/cthulhu/ax_object.py b/src/cthulhu/ax_object.py deleted file mode 100644 index 3614941..0000000 --- a/src/cthulhu/ax_object.py +++ /dev/null @@ -1,1581 +0,0 @@ -# Utilities for obtaining information about accessible objects. -# -# Copyright 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-lines -# pylint: disable=too-many-return-statements -# pylint: disable=too-many-public-methods - -"""Utilities for obtaining information about accessible objects.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -import re -import threading -import time -from typing import Callable, Generator, Optional - -import gi -gi.require_version("Atspi", "2.0") -gi.require_version("Gtk", "3.0") -from gi.repository import Atspi -from gi.repository import GLib -from gi.repository import Gtk - -from . import debug -from . import keynames - - -class AXObject: - """Utilities for obtaining information about accessible objects.""" - - KNOWN_DEAD: dict[int, bool] = {} - OBJECT_ATTRIBUTES: dict[int, dict[str, str]] = {} - REAL_APP_FOR_MUTTER_FRAME: dict[int, Atspi.Accessible] = {} - REAL_FRAME_FOR_MUTTER_FRAME: dict[int, Atspi.Accessible] = {} - - _lock = threading.Lock() - - @staticmethod - def _clear_stored_data() -> None: - """Clears any data we have cached for objects""" - - while True: - time.sleep(60) - AXObject._clear_all_dictionaries() - - @staticmethod - def _clear_all_dictionaries(reason: str = "") -> None: - msg = "AXObject: Clearing local cache." - if reason: - msg += f" Reason: {reason}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - with AXObject._lock: - AXObject.KNOWN_DEAD.clear() - AXObject.OBJECT_ATTRIBUTES.clear() - - @staticmethod - def clear_cache_now(reason: str = "") -> None: - """Clears all cached information immediately.""" - - AXObject._clear_all_dictionaries(reason) - - @staticmethod - def start_cache_clearing_thread() -> None: - """Starts thread to periodically clear cached details.""" - - thread = threading.Thread(target=AXObject._clear_stored_data) - thread.daemon = True - thread.start() - - @staticmethod - def get_toolkit_name(obj: Atspi.Accessible) -> str: - """Returns the toolkit name of obj as a lowercase string""" - - try: - app = Atspi.Accessible.get_application(obj) - name = Atspi.Accessible.get_toolkit_name(app) or "" - except GLib.GError as error: - tokens = ["AXObject: Exception calling _get_toolkit_name_on", app, f": {error}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return "" - - return name.lower() - - @staticmethod - def get_application(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the accessible application associated with obj.""" - - if obj is None: - return None - - try: - app = Atspi.Accessible.get_application(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_application: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - return app - - @staticmethod - def is_bogus(obj: Atspi.Accessible) -> bool: - """Hack to ignore certain objects. All entries must have a bug.""" - - # TODO - JD: Periodically check for fixes and remove hacks which are no - # longer needed. - - # https://bugzilla.mozilla.org/show_bug.cgi?id=1879750 - if AXObject.get_role(obj) == Atspi.Role.SECTION \ - and AXObject.get_role(AXObject.get_parent(obj)) == Atspi.Role.FRAME \ - and AXObject.get_toolkit_name(obj) == "gecko": - tokens = ["AXObject:", obj, "is bogus. See mozilla bug 1879750."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True, True) - return True - - return False - - @staticmethod - def has_broken_ancestry(obj: Atspi.Accessible) -> bool: - """Returns True if obj's ancestry is broken.""" - - if obj is None: - return False - - # https://bugreports.qt.io/browse/QTBUG-130116 - toolkit_name = AXObject.get_toolkit_name(obj) - if not toolkit_name.startswith("qt"): - return False - - if not AXObject._can_reach_application(obj): - tokens = ["AXObject:", obj, "has broken ancestry. See qt bug 130116."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - @staticmethod - def _can_reach_application(obj: Atspi.Accessible) -> bool: - """Returns True if obj's ancestry reaches the application.""" - - reached_app = False - parent = AXObject.get_parent(obj) - while parent and not reached_app: - reached_app = AXObject.get_role(parent) == Atspi.Role.APPLICATION - parent = AXObject.get_parent(parent) - - return reached_app - - @staticmethod - def has_broken_popup_ancestry(obj: Atspi.Accessible) -> bool: - """Returns True if obj is a popup item whose ancestry is broken.""" - - if obj is None or AXObject.is_dead(obj): - return False - - # Chromium Omnibox popups can lose their path back to the frame after - # the popup is closed and reopened. - if not AXObject.get_toolkit_name(obj).startswith("chromium"): - return False - - if AXObject.get_role(obj) != Atspi.Role.LIST_ITEM: - return False - - if not AXObject._can_reach_application(obj): - tokens = ["AXObject:", obj, "has broken popup ancestry."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - @staticmethod - def is_valid(obj: Atspi.Accessible) -> bool: - """Returns False if we know for certain this object is invalid""" - - return not (obj is None or AXObject.object_is_known_dead(obj)) - - @staticmethod - def object_is_known_dead(obj: Atspi.Accessible) -> bool: - """Returns True if we know for certain this object no longer exists""" - - return bool(obj and AXObject.KNOWN_DEAD.get(hash(obj))) is True - - @staticmethod - def _set_known_dead_status(obj: Atspi.Accessible, is_dead: bool) -> None: - """Updates the known-dead status of obj""" - - if obj is None: - return - - current_status = AXObject.KNOWN_DEAD.get(hash(obj)) - if current_status == is_dead: - return - - AXObject.KNOWN_DEAD[hash(obj)] = is_dead - if is_dead: - msg = "AXObject: Adding to known dead objects" - debug.print_message(debug.LEVEL_INFO, msg, True, True) - return - - if current_status: - tokens = ["AXObject: Removing", obj, "from known-dead objects"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - @staticmethod - def handle_error(obj: Atspi.Accessible, error: Exception, msg: str) -> None: - """Parses the exception and potentially updates our status for obj""" - - error_string = str(error) - if re.search(r"accessible/\d+ does not exist", error_string): - msg = msg.replace(error_string, "object no longer exists") - debug.print_message(debug.LEVEL_INFO, msg, True) - elif re.search(r"The application no longer exists", error_string): - msg = msg.replace(error_string, "app no longer exists") - debug.print_message(debug.LEVEL_INFO, msg, True) - else: - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - if AXObject.KNOWN_DEAD.get(hash(obj)) is False: - AXObject._set_known_dead_status(obj, True) - - @staticmethod - def supports_action(obj: Atspi.Accessible) -> bool: - """Returns True if the action interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_action_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_action_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def _has_document_spreadsheet(obj: Atspi.Accessible) -> bool: - # To avoid circular import. pylint: disable=import-outside-toplevel - from .ax_collection import AXCollection - rule = AXCollection.create_match_rule(roles=[Atspi.Role.DOCUMENT_SPREADSHEET]) - if rule is None: - return False - - frame = AXObject.find_ancestor_inclusive( - obj, lambda x: AXObject.get_role(x) == Atspi.Role.FRAME) - if frame is None: - return False - return bool(Atspi.Collection.get_matches( - frame, rule, Atspi.CollectionSortOrder.CANONICAL, 1, True)) - - @staticmethod - def supports_collection(obj: Atspi.Accessible) -> bool: - """Returns True if the collection interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - app = Atspi.Accessible.get_application(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in supports_collection: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - try: - iface = Atspi.Accessible.get_collection_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_collection_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - app_name = AXObject.get_name(app) - if app_name != "soffice": - return iface is not None - - if AXObject.find_ancestor_inclusive( - obj, lambda x: AXObject.get_role(x) == Atspi.Role.DOCUMENT_TEXT): - return True - - if AXObject._has_document_spreadsheet(obj): - msg = "AXObject: Treating soffice as not supporting collection due to spreadsheet." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - return True - - @staticmethod - def supports_component(obj: Atspi.Accessible) -> bool: - """Returns True if the component interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_component_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_component_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - - @staticmethod - def supports_document(obj: Atspi.Accessible) -> bool: - """Returns True if the document interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_document_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_document_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def find_real_app_and_window_for(obj: Atspi.Accessible, app: Optional[Atspi.Accessible] = None): - """Work around for window events coming from mutter-x11-frames.""" - - if app is None: - try: - app = Atspi.Accessible.get_application(obj) - except Exception as error: - msg = f"AXObject: Exception getting application of {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return None, None - - if AXObject.get_name(app) != "mutter-x11-frames": - return app, obj - - real_app = AXObject.REAL_APP_FOR_MUTTER_FRAME.get(hash(obj)) - real_frame = AXObject.REAL_FRAME_FOR_MUTTER_FRAME.get(hash(obj)) - if real_app is not None and real_frame is not None: - return real_app, real_frame - - tokens = ["AXObject:", app, "is not valid app for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - try: - desktop = Atspi.get_desktop(0) - except Exception as error: - tokens = ["AXObject: Exception getting desktop from Atspi:", error] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None, None - - name = AXObject.get_name(obj) - real_app = None - real_frame = None - for desktop_app in AXObject.iter_children(desktop): - if AXObject.get_name(desktop_app) == "mutter-x11-frames": - continue - for frame in AXObject.iter_children(desktop_app): - if name == AXObject.get_name(frame): - real_app = desktop_app - real_frame = frame - - tokens = ["AXObject:", real_app, "is real app for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if real_frame != obj: - msg = "AXObject: Updated frame to frame from real app" - debug.print_message(debug.LEVEL_INFO, msg, True) - - AXObject.REAL_APP_FOR_MUTTER_FRAME[hash(obj)] = real_app - AXObject.REAL_FRAME_FOR_MUTTER_FRAME[hash(obj)] = real_frame - return real_app, real_frame - - @staticmethod - def supports_editable_text(obj: Atspi.Accessible) -> bool: - """Returns True if the editable-text interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_editable_text_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_editable_text_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def supports_hyperlink(obj: Atspi.Accessible) -> bool: - """Returns True if the hyperlink interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_hyperlink(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_hyperlink on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def supports_hypertext(obj: Atspi.Accessible) -> bool: - """Returns True if the hypertext interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_hypertext_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_hypertext_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def supports_image(obj: Atspi.Accessible) -> bool: - """Returns True if the image interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_image_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_image_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def supports_selection(obj: Atspi.Accessible) -> bool: - """Returns True if the selection interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_selection_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_selection_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def supports_table(obj: Atspi.Accessible) -> bool: - """Returns True if the table interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_table_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_table_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def supports_table_cell(obj: Atspi.Accessible) -> bool: - """Returns True if the table cell interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_table_cell(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_table_cell on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def supports_text(obj: Atspi.Accessible) -> bool: - """Returns True if the text interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_text_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_text_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - return iface is not None - - @staticmethod - def supports_value(obj: Atspi.Accessible) -> bool: - """Returns True if the value interface is supported on obj""" - - if not AXObject.is_valid(obj): - return False - - try: - iface = Atspi.Accessible.get_value_iface(obj) - except GLib.GError as error: - msg = f"AXObject: Exception calling get_value_iface on {obj}: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return iface is not None - - @staticmethod - def get_path(obj: Atspi.Accessible) -> list[int]: - """Returns the path from application to obj as list of child indices""" - - if not AXObject.is_valid(obj): - return [] - - path = [] - acc = obj - while acc: - try: - path.append(Atspi.Accessible.get_index_in_parent(acc)) - except GLib.GError as error: - msg = f"AXObject: Exception getting index in parent for {acc}: {error}" - AXObject.handle_error(acc, error, msg) - return [] - acc = AXObject.get_parent_checked(acc) - - path.reverse() - return path - - @staticmethod - def get_index_in_parent(obj: Atspi.Accessible) -> int: - """Returns the child index of obj within its parent""" - - if not AXObject.is_valid(obj): - return -1 - - try: - index = Atspi.Accessible.get_index_in_parent(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_index_in_parent: {error}" - AXObject.handle_error(obj, error, msg) - return -1 - - return index - - @staticmethod - def get_parent(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the accessible parent of obj. See also get_parent_checked.""" - - if not AXObject.is_valid(obj): - return None - - try: - parent = Atspi.Accessible.get_parent(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_parent: {error}" - AXObject.handle_error(obj, error, msg) - return None - - if parent == obj: - tokens = ["AXObject:", obj, "claims to be its own parent"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - if parent is None \ - and AXObject.get_role(obj) not in [Atspi.Role.INVALID, Atspi.Role.DESKTOP_FRAME]: - tokens = ["AXObject:", obj, "claims to have no parent"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return parent - - @staticmethod - def get_parent_checked(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the parent of obj, doing checks for tree validity""" - - if not AXObject.is_valid(obj): - return None - - role = AXObject.get_role(obj) - if role in [Atspi.Role.INVALID, Atspi.Role.APPLICATION]: - return None - - parent = AXObject.get_parent(obj) - if parent is None: - return None - - if debug.LEVEL_INFO < debug.debugLevel: - return parent - - if AXObject.is_dead(obj): - return parent - - index = AXObject.get_index_in_parent(obj) - n_children = AXObject.get_child_count(parent) - if index < 0 or index >= n_children: - tokens = ["AXObject:", obj, "has index", index, - "; parent", parent, "has", n_children, "children"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return parent - - # This performs our check and includes any errors. We don't need the return value here. - AXObject.get_active_descendant_checked(parent, obj) - return parent - - @staticmethod - def _get_ancestors(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of the ancestors of obj, starting with its parent.""" - - ancestors = [] - parent = AXObject.get_parent_checked(obj) - while parent: - ancestors.append(parent) - parent = AXObject.get_parent_checked(parent) - ancestors.reverse() - return ancestors - - @staticmethod - def get_common_ancestor( - obj1: Atspi.Accessible, - obj2: Atspi.Accessible - ) -> Optional[Atspi.Accessible]: - """Returns the common ancestor of obj1 and obj2.""" - - tokens = ["AXObject: Looking for common ancestor of", obj1, "and", obj2] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if not (obj1 and obj2): - return None - - if obj1 == obj2: - return obj1 - - obj1_ancestors = AXObject._get_ancestors(obj1) + [obj1] - obj2_ancestors = AXObject._get_ancestors(obj2) + [obj2] - result = None - for a1, a2 in zip(obj1_ancestors, obj2_ancestors): - if a1 == a2: - result = a1 - else: - break - - tokens = ["AXObject: Common ancestor of", obj1, "and", obj2, "is", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def find_ancestor_inclusive( - obj: Atspi.Accessible, - pred: Callable[[Atspi.Accessible], bool] - ) -> Optional[Atspi.Accessible]: - """Returns obj, or the ancestor of obj, for which the function pred is true""" - - if pred(obj): - return obj - - return AXObject.find_ancestor(obj, pred) - - @staticmethod - def find_ancestor( - obj: Atspi.Accessible, - pred: Callable[[Atspi.Accessible], bool] - ) -> Optional[Atspi.Accessible]: - """Returns the ancestor of obj if the function pred is true""" - - if not AXObject.is_valid(obj): - return None - - # Keep track of objects we've encountered in order to handle broken trees. - objects = [obj] - parent = AXObject.get_parent_checked(obj) - while parent: - if parent in objects: - tokens = ["AXObject: Circular tree suspected in find_ancestor. ", - parent, "already in: ", objects] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - if pred(parent): - return parent - - objects.append(parent) - parent = AXObject.get_parent_checked(parent) - - return None - - @staticmethod - def is_ancestor( - obj: Atspi.Accessible, - ancestor: Atspi.Accessible, - inclusive: bool = False - ) -> bool: - """Returns true if ancestor is an ancestor of obj or, if inclusive, obj is ancestor.""" - - if not AXObject.is_valid(obj): - return False - - if not AXObject.is_valid(ancestor): - return False - - if obj == ancestor and inclusive: - return True - - return AXObject.find_ancestor(obj, lambda x: x == ancestor) is not None - - @staticmethod - def get_child(obj: Atspi.Accessible, index: int) -> Optional[Atspi.Accessible]: - """Returns the nth child of obj. See also get_child_checked.""" - - if not AXObject.is_valid(obj): - return None - - n_children = AXObject.get_child_count(obj) - if n_children <= 0: - return None - - if index == -1: - index = n_children - 1 - - if not 0 <= index < n_children: - return None - - try: - child = Atspi.Accessible.get_child_at_index(obj, index) - except GLib.GError as error: - msg = f"AXObject: Exception in get_child: {error}" - AXObject.handle_error(obj, error, msg) - return None - - if child == obj: - tokens = ["AXObject:", obj, "claims to be its own child"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - return child - - @staticmethod - def get_child_checked( - obj: Atspi.Accessible, index: int - ) -> Optional[Atspi.Accessible]: - """Returns the nth child of obj, doing checks for tree validity""" - - if not AXObject.is_valid(obj): - return None - - child = AXObject.get_child(obj, index) - if debug.LEVEL_INFO < debug.debugLevel: - return child - - parent = AXObject.get_parent(child) - if obj != parent: - tokens = ["AXObject:", obj, "claims", child, "as child; child's parent is", parent] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return child - - @staticmethod - def get_active_descendant_checked( - container: Atspi.Accessible, - reported_child: Atspi.Accessible - ) -> Optional[Atspi.Accessible]: - """Checks the reported active descendant and return the real/valid one.""" - - if not AXObject.has_state(container, Atspi.StateType.MANAGES_DESCENDANTS): - return reported_child - - index = AXObject.get_index_in_parent(reported_child) - try: - real_child = Atspi.Accessible.get_child_at_index(container, index) - except GLib.GError as error: - msg = f"AXObject: Exception in get_active_descendant_checked: {error}" - AXObject.handle_error(container, error, msg) - return reported_child - - if real_child != reported_child: - tokens = [ - "AXObject: ", container, f"'s child at {index} is ", real_child, - "; not reported child", reported_child - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return real_child - - @staticmethod - def _find_descendant( - obj: Atspi.Accessible, - pred: Callable[[Atspi.Accessible], bool] - ) -> Optional[Atspi.Accessible]: - """Returns the descendant of obj if the function pred is true""" - - if not AXObject.is_valid(obj): - return None - - for i in range(AXObject.get_child_count(obj)): - child = AXObject.get_child_checked(obj, i) - if child is None: - continue - if pred(child): - return child - child = AXObject._find_descendant(child, pred) - if child: - return child - - return None - - @staticmethod - def find_descendant( - obj: Atspi.Accessible, - pred: Callable[[Atspi.Accessible], bool] - ) -> Optional[Atspi.Accessible]: - """Returns the descendant of obj if the function pred is true""" - - start = time.time() - result = AXObject._find_descendant(obj, pred) - tokens = ["AXObject: find_descendant: found", result, f"in {time.time() - start:.4f}s"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def find_deepest_descendant(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the deepest descendant of obj""" - - if not AXObject.is_valid(obj): - return None - - last_child = AXObject.get_child(obj, AXObject.get_child_count(obj) - 1) - if last_child is None: - return obj - - return AXObject.find_deepest_descendant(last_child) - - @staticmethod - def _find_all_descendants( - obj: Atspi.Accessible, - include_if: Optional[Callable[[Atspi.Accessible], bool]], - exclude_if: Optional[Callable[[Atspi.Accessible], bool]], - matches: list[Atspi.Accessible] - ) -> None: - """Returns all descendants which match the specified inclusion and exclusion""" - - if not AXObject.is_valid(obj): - return - - child_count = AXObject.get_child_count(obj) - for i in range(child_count): - child = AXObject.get_child(obj, i) - if exclude_if and exclude_if(child): - continue - if include_if and include_if(child): - matches.append(child) - AXObject._find_all_descendants(child, include_if, exclude_if, matches) - - @staticmethod - def find_all_descendants( - root: Atspi.Accessible, - include_if: Optional[Callable[[Atspi.Accessible], bool]] = None, - exclude_if: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants which match the specified inclusion and exclusion""" - - start = time.time() - matches: list[Atspi.Accessible] = [] - AXObject._find_all_descendants(root, include_if, exclude_if, matches) - msg = ( - f"AXObject: find_all_descendants: {len(matches)} " - f"matches found in {time.time() - start:.4f}s" - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - return matches - - @staticmethod - def get_role(obj: Atspi.Accessible) -> Atspi.Role: - """Returns the accessible role of obj""" - - if not AXObject.is_valid(obj): - return Atspi.Role.INVALID - - try: - role = Atspi.Accessible.get_role(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_role: {error}" - AXObject.handle_error(obj, error, msg) - return Atspi.Role.INVALID - - AXObject._set_known_dead_status(obj, False) - return role - - @staticmethod - def get_role_name(obj: Atspi.Accessible, localized: bool = False) -> str: - """Returns the accessible role name of obj""" - - if not AXObject.is_valid(obj): - return "" - - try: - if not localized: - role_name = Atspi.Accessible.get_role_name(obj) - else: - role_name = Atspi.Accessible.get_localized_role_name(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_role_name: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - return role_name - - @staticmethod - def get_role_description(obj: Atspi.Accessible, is_braille: bool = False) -> str: - """Returns the accessible role description of obj""" - - if not AXObject.is_valid(obj): - return "" - - attrs = AXObject.get_attributes_dict(obj) - rv = attrs.get("roledescription", "") - if is_braille: - rv = attrs.get("brailleroledescription", rv) - return rv - - @staticmethod - def get_accessible_id(obj: Atspi.Accessible) -> str: - """Returns the accessible id of obj""" - - if not AXObject.is_valid(obj): - return "" - - try: - result = Atspi.Accessible.get_accessible_id(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_accessible_id: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - AXObject._set_known_dead_status(obj, False) - return result - - @staticmethod - def get_name(obj: Atspi.Accessible) -> str: - """Returns the accessible name of obj""" - - if not AXObject.is_valid(obj): - return "" - - try: - name = Atspi.Accessible.get_name(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_name: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - AXObject._set_known_dead_status(obj, False) - return name - - @staticmethod - def has_same_non_empty_name(obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> bool: - """Returns true if obj1 and obj2 share the same non-empty name""" - - name1 = AXObject.get_name(obj1) - if not name1: - return False - - return name1 == AXObject.get_name(obj2) - - @staticmethod - def get_description(obj: Atspi.Accessible) -> str: - """Returns the accessible description of obj""" - - if not AXObject.is_valid(obj): - return "" - - try: - description = Atspi.Accessible.get_description(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_description: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - return description - - @staticmethod - def get_image_description(obj: Atspi.Accessible) -> str: - """Returns the accessible image description of obj""" - - if not AXObject.supports_image(obj): - return "" - - try: - description = Atspi.Image.get_image_description(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_image_description: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - return description - - @staticmethod - def get_image_size(obj: Atspi.Accessible) -> tuple[int, int]: - """Returns a (width, height) tuple of the image in obj""" - - if not AXObject.supports_image(obj): - return 0, 0 - - try: - result = Atspi.Image.get_image_size(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_image_size: {error}" - AXObject.handle_error(obj, error, msg) - return 0, 0 - - # The return value is an AtspiPoint, hence x and y. - return result.x, result.y - - @staticmethod - def get_help_text(obj: Atspi.Accessible) -> str: - """Returns the accessible help text of obj""" - - if not AXObject.is_valid(obj): - return "" - - try: - # Added in Atspi 2.52. - text = Atspi.Accessible.get_help_text(obj) or "" - except GLib.GError: - # This is for prototyping in the meantime. - text = AXObject.get_attribute(obj, "helptext") or "" - - return text - - @staticmethod - def get_child_count(obj: Atspi.Accessible) -> int: - """Returns the child count of obj""" - - if not AXObject.is_valid(obj): - return 0 - - try: - count = Atspi.Accessible.get_child_count(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_child_count: {error}" - AXObject.handle_error(obj, error, msg) - return 0 - - return count - - @staticmethod - def iter_children( - obj: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> Generator[Atspi.Accessible, None, None]: - """Generator to iterate through obj's children. If the function pred is - specified, children for which pred is False will be skipped.""" - - if not AXObject.is_valid(obj): - return - - child_count = AXObject.get_child_count(obj) - if child_count > 500: - tokens = ["AXObject:", obj, "has more than 500 children"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True, True) - - for index in range(child_count): - child = AXObject.get_child(obj, index) - if child is None and not AXObject.is_valid(obj): - tokens = ["AXObject:", obj, "is no longer valid"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return - - if child is not None and (pred is None or pred(child)): - yield child - - @staticmethod - def get_previous_sibling(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the previous sibling of obj, based on child indices""" - - if not AXObject.is_valid(obj): - return None - - parent = AXObject.get_parent(obj) - if parent is None: - return None - - index = AXObject.get_index_in_parent(obj) - if index <= 0: - return None - - sibling = AXObject.get_child(parent, index - 1) - if sibling == obj: - tokens = ["AXObject:", obj, "claims to be its own sibling"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - return sibling - - @staticmethod - def get_next_sibling(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the next sibling of obj, based on child indices""" - - if not AXObject.is_valid(obj): - return None - - parent = AXObject.get_parent(obj) - if parent is None: - return None - - index = AXObject.get_index_in_parent(obj) - if index < 0: - return None - - sibling = AXObject.get_child(parent, index + 1) - if sibling == obj: - tokens = ["AXObject:", obj, "claims to be its own sibling"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - return sibling - - @staticmethod - def get_locale(obj: Atspi.Accessible) -> str: - """Returns the locale of obj""" - - if not AXObject.is_valid(obj): - return "" - - try: - locale = Atspi.Accessible.get_object_locale(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_locale: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - return locale or "" - - @staticmethod - def get_state_set(obj: Atspi.Accessible) -> Atspi.StateSet: - """Returns the state set associated with obj""" - - if not AXObject.is_valid(obj): - return Atspi.StateSet() - - try: - state_set = Atspi.Accessible.get_state_set(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_state_set: {error}" - AXObject.handle_error(obj, error, msg) - return Atspi.StateSet() - - if state_set is None: - tokens = ["AXObject: get_state_set failed for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return Atspi.StateSet() - - AXObject._set_known_dead_status(obj, False) - return state_set - - @staticmethod - def has_state(obj: Atspi.Accessible, state: Atspi.StateType) -> bool: - """Returns true if obj has the specified state""" - - if not AXObject.is_valid(obj): - return False - - return AXObject.get_state_set(obj).contains(state) - - @staticmethod - def clear_cache( - obj: Atspi.Accessible, - recursive: bool = False, - reason: str = "" - ) -> None: - """Clears the Atspi cached information associated with obj""" - - if obj is None: - return - - tokens = ["AXObject: Clearing AT-SPI cache on", obj, f"Recursive: {recursive}."] - if reason: - tokens.append(f" Reason: {reason}") - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if not recursive: - try: - Atspi.Accessible.clear_cache_single(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in clear_cache_single: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - try: - Atspi.Accessible.clear_cache(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in clear_cache: {error}" - AXObject.handle_error(obj, error, msg) - - @staticmethod - def get_process_id(obj: Atspi.Accessible) -> int: - """Returns the process id associated with obj""" - - if not AXObject.is_valid(obj): - return -1 - - try: - pid = Atspi.Accessible.get_process_id(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_process_id: {error}" - AXObject.handle_error(obj, error, msg) - return -1 - - return pid - - @staticmethod - def is_dead(obj: Atspi.Accessible) -> bool: - """Returns true of obj exists but is believed to be dead.""" - - if obj is None: - return False - - if not AXObject.is_valid(obj): - return True - - try: - # We use the Atspi function rather than the AXObject function because the - # latter intentionally handles exceptions. - Atspi.Accessible.get_name(obj) - except GLib.GError as error: - msg = f"AXObject: Accessible is dead: {error}" - AXObject.handle_error(obj, error, msg) - return True - - AXObject._set_known_dead_status(obj, False) - return False - - @staticmethod - def get_attributes_dict( - obj: Atspi.Accessible, - use_cache: bool = True - ) -> dict[str, str]: - """Returns the object attributes of obj as a dictionary.""" - - if not AXObject.is_valid(obj): - return {} - - if use_cache: - attributes = AXObject.OBJECT_ATTRIBUTES.get(hash(obj)) - if attributes: - return attributes - - try: - attributes = Atspi.Accessible.get_attributes(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_attributes_dict: {error}" - AXObject.handle_error(obj, error, msg) - return {} - - if attributes is None: - return {} - - AXObject.OBJECT_ATTRIBUTES[hash(obj)] = attributes - return attributes - - @staticmethod - def get_attribute( - obj: Atspi.Accessible, - attribute_name: str, - use_cache: bool = True - ) -> str: - """Returns the value of the specified attribute as a string.""" - - if not AXObject.is_valid(obj): - return "" - - attributes = AXObject.get_attributes_dict(obj, use_cache) - return attributes.get(attribute_name, "") - - @staticmethod - def get_n_actions(obj: Atspi.Accessible) -> int: - """Returns the number of actions supported on obj.""" - - if not AXObject.supports_action(obj): - return 0 - - try: - count = Atspi.Action.get_n_actions(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in get_n_actions: {error}" - AXObject.handle_error(obj, error, msg) - return 0 - - return count - - @staticmethod - def _normalize_action_name(action_name: str) -> str: - """Adjusts the name to account for differences in implementations.""" - - if not action_name: - return "" - - name = re.sub(r'(?<=[a-z])([A-Z])', r'-\1', action_name).lower() - name = re.sub('[!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~]', '-', name) - return name - - @staticmethod - def get_action_name(obj: Atspi.Accessible, i: int) -> str: - """Returns the name of obj's action at index i.""" - - if not 0 <= i < AXObject.get_n_actions(obj): - return "" - - try: - name = Atspi.Action.get_action_name(obj, i) - except GLib.GError as error: - msg = f"AXObject: Exception in get_action_name: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - return AXObject._normalize_action_name(name) - - @staticmethod - def get_action_names(obj: Atspi.Accessible) -> list[str]: - """Returns the list of actions supported on obj.""" - - results = [] - for i in range(AXObject.get_n_actions(obj)): - name = AXObject.get_action_name(obj, i) - if name: - results.append(name) - return results - - @staticmethod - def get_action_description(obj: Atspi.Accessible, i: int) -> str: - """Returns the description of obj's action at index i.""" - - if not 0 <= i < AXObject.get_n_actions(obj): - return "" - - try: - description = Atspi.Action.get_action_description(obj, i) - except GLib.GError as error: - msg = f"AXObject: Exception in get_action_description: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - return description - - @staticmethod - def get_action_localized_name(obj: Atspi.Accessible, i: int) -> str: - """Returns the localized name of obj's action at index i.""" - - if not 0 <= i < AXObject.get_n_actions(obj): - return "" - - try: - name = Atspi.Action.get_localized_name(obj, i) - except GLib.GError as error: - msg = f"AXObject: Exception in get_action_localized_name: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - return name - - @staticmethod - def get_action_key_binding(obj: Atspi.Accessible, i: int) -> str: - """Returns the key binding string of obj's action at index i.""" - - if not 0 <= i < AXObject.get_n_actions(obj): - return "" - - try: - keybinding = Atspi.Action.get_key_binding(obj, i) - except GLib.GError as error: - msg = f"AXObject: Exception in get_action_key_binding: {error}" - AXObject.handle_error(obj, error, msg) - return "" - - # GTK4 does this. - if keybinding == "": - return "" - return keybinding - - @staticmethod - def _get_label_for_key_sequence(sequence: str) -> str: - """Returns the human consumable label for the key sequence.""" - - if not sequence: - return "" - - # We get all sorts of variations in the keybinding string. Try to normalize it. - if len(sequence) > 1 and not sequence.startswith("<") and "," not in sequence: - tokens = sequence.split("+") - sequence = "".join(f"<{part}>" for part in tokens[:-1]) + tokens[-1] - - # We use Gtk for conversion to handle things like . - try: - key, mods = Gtk.accelerator_parse(sequence) - result = Gtk.accelerator_get_label(key, mods) - except GLib.GError as error: - msg = f"AXObject: Exception in _get_label_for_key_sequence: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - sequence = sequence.replace("<", "").replace(">", " ").strip() - else: - if result and not result.endswith("+"): - sequence = result - - return keynames.localize_key_sequence(sequence) - - @staticmethod - def get_accelerator(obj: Atspi.Accessible) -> str: - """Returns the accelerator/shortcut associated with obj.""" - - attrs = AXObject.get_attributes_dict(obj) - # The ARIA spec suggests a given shortcut's components should be separated by a "+". - # Multiple shortcuts are apparently allowed and separated by a space. - shortcuts = attrs.get("keyshortcuts", "").split(" ") - if shortcuts and shortcuts[0]: - result = " ".join(map(AXObject._get_label_for_key_sequence, shortcuts)).strip() - # Accelerators are typically modified and thus more than one character. - if len(result) > 1: - return result - - index = AXObject._find_first_action_with_keybinding(obj) - if index == -1: - return "" - - # This should be a string separated by semicolons and in the form: - # ;; (optional) - # In practice we get all sorts of variations. - - # If there's a third item, it's probably the accelerator. - strings = AXObject.get_action_key_binding(obj, index).split(";") - if len(strings) == 3: - return AXObject._get_label_for_key_sequence(strings[2]) - - # If the last thing has Ctrl in it, it's probably the accelerator. - result = AXObject._get_label_for_key_sequence(strings[-1]) - if "Ctrl" in result: - return result - - return "" - - @staticmethod - def get_mnemonic(obj: Atspi.Accessible) -> str: - """Returns the mnemonic associated with obj.""" - - attrs = AXObject.get_attributes_dict(obj) - # The ARIA spec suggests a given shortcut's components should be separated by a "+". - # Multiple shortcuts are apparently allowed and separated by a space. - shortcuts = attrs.get("keyshortcuts", "").split(" ") - if shortcuts and shortcuts[0]: - result = " ".join(map(AXObject._get_label_for_key_sequence, shortcuts)).strip() - # If it's not a single letter it's probably not the mnemonic. - if len(result) == 1: - return result - - index = AXObject._find_first_action_with_keybinding(obj) - if index == -1: - return "" - - # This should be a string separated by semicolons and in the form: - # ;; (optional) - # In practice we get all sorts of variations. - - strings = AXObject.get_action_key_binding(obj, index).split(";") - result = AXObject._get_label_for_key_sequence(strings[0]) - # If Ctrl is in the result, it's probably the accelerator rather than the mnemonic. - if "Ctrl" in result or "Control" in result: - return "" - - # Don't treat space as a mnemonic. - if result.lower() in [" ", "space", ""]: - return "" - - return result - - @staticmethod - def _find_first_action_with_keybinding(obj: Atspi.Accessible) -> int: - """Returns the index of the first action with a keybinding on obj.""" - - for i in range(AXObject.get_n_actions(obj)): - if AXObject.get_action_key_binding(obj, i): - return i - return -1 - - @staticmethod - def has_action(obj: Atspi.Accessible, action_name: str) -> bool: - """Returns true if the named action is supported on obj.""" - - return AXObject.get_action_index(obj, action_name) >= 0 - - @staticmethod - def get_action_index(obj: Atspi.Accessible, action_name: str) -> int: - """Returns the index of the named action or -1 if unsupported.""" - - action_name = AXObject._normalize_action_name(action_name) - for i in range(AXObject.get_n_actions(obj)): - if action_name == AXObject.get_action_name(obj, i): - return i - - return -1 - - @staticmethod - def do_action(obj: Atspi.Accessible, i: int) -> bool: - """Invokes obj's action at index i. The return value, if true, may be - meaningless because most implementors return true without knowing if - the action was successfully performed.""" - - if not 0 <= i < AXObject.get_n_actions(obj): - return False - - try: - result = Atspi.Action.do_action(obj, i) - except GLib.GError as error: - msg = f"AXObject: Exception in do_action: {error}" - AXObject.handle_error(obj, error, msg) - return False - - return result - - @staticmethod - def do_named_action(obj: Atspi.Accessible, action_name: str) -> bool: - """Invokes the named action on obj. The return value, if true, may be - meaningless because most implementors return true without knowing if - the action was successfully performed.""" - - index = AXObject.get_action_index(obj, action_name) - if index == -1: - tokens = ["INFO:", action_name, "not an available action for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - return AXObject.do_action(obj, index) - - @staticmethod - def grab_focus(obj: Atspi.Accessible) -> bool: - """Attempts to grab focus on obj. Returns true if successful.""" - - if not AXObject.supports_component(obj): - return False - - try: - result = Atspi.Component.grab_focus(obj) - except GLib.GError as error: - msg = f"AXObject: Exception in grab_focus: {error}" - AXObject.handle_error(obj, error, msg) - return False - - if debug.LEVEL_INFO < debug.debugLevel: - return result - - if result and not AXObject.has_state(obj, Atspi.StateType.FOCUSED): - tokens = ["AXObject:", obj, "lacks focused state after focus grab"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return result - -AXObject.start_cache_clearing_thread() diff --git a/src/cthulhu/ax_selection.py b/src/cthulhu/ax_selection.py deleted file mode 100644 index ffbd47e..0000000 --- a/src/cthulhu/ax_selection.py +++ /dev/null @@ -1,128 +0,0 @@ -# Utilities for obtaining information about containers supporting selection -# -# Copyright 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=wrong-import-position - -"""Utilities for obtaining information about containers supporting selection.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -from typing import Optional -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from .ax_object import AXObject -from .ax_utilities_role import AXUtilitiesRole - - -class AXSelection: - """Utilities for obtaining information about containers supporting selection.""" - - @staticmethod - def get_selected_child_count(obj: Atspi.Accessible) -> int: - """Returns the selected child count of obj""" - - if not AXObject.supports_selection(obj): - return 0 - - try: - count = Atspi.Selection.get_n_selected_children(obj) - except GLib.GError as error: - tokens = ["AXSelection: Exception in get_selected_child_count:", error] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return 0 - - tokens = ["AXSelection:", obj, "reports", count, "selected children"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return count - - @staticmethod - def get_selected_child(obj: Atspi.Accessible, index: int) -> Optional[Atspi.Accessible]: - """Returns the nth selected child of obj.""" - - n_children = AXSelection.get_selected_child_count(obj) - if n_children <= 0: - return None - - if index == -1: - index = n_children - 1 - - if not 0 <= index < n_children: - return None - - try: - child = Atspi.Selection.get_selected_child(obj, index) - except GLib.GError as error: - tokens = ["AXSelection: Exception in get_selected_child:", error] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - if child == obj: - tokens = ["AXSelection:", obj, "claims to be its own selected child"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - tokens = ["AXSelection:", child, "is selected child #", index, "of", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return child - - @staticmethod - def get_selected_children(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of all the selected children of obj.""" - - if obj is None: - return [] - - count = AXSelection.get_selected_child_count(obj) - if not count and AXUtilitiesRole.is_combo_box(obj): - container = AXObject.find_descendant( - obj, lambda x: AXUtilitiesRole.is_menu(x) or AXUtilitiesRole.is_list_box(x)) - return AXSelection.get_selected_children(container) - - children = set() - for i in range(count): - try: - child = Atspi.Selection.get_selected_child(obj, i) - except GLib.GError as error: - tokens = ["AXSelection: Exception in get_selected_children:", error] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - if child is not None: - children.add(child) - - if obj in children: - tokens = ["AXSelection:", obj, "claims to be its own selected child"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - children.remove(obj) - - result = list(children) - if len(result) != count: - tokens = ["AXSelection: Selected child count of", obj, f"is {count}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return result diff --git a/src/cthulhu/ax_table.py b/src/cthulhu/ax_table.py deleted file mode 100644 index 97d2975..0000000 --- a/src/cthulhu/ax_table.py +++ /dev/null @@ -1,1373 +0,0 @@ -# Utilities for obtaining information about accessible tables. -# -# Copyright 2023 Igalia, S.L. -# Copyright 2023 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-lines -# pylint: disable=too-many-public-methods -# pylint: disable=too-many-return-statements - -"""Utilities for obtaining information about accessible tables.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." \ - "Copyright (c) 2023 GNOME Foundation Inc." -__license__ = "LGPL" - -import threading -import time -from typing import Generator, Optional - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from . import messages -from . import object_properties -from .ax_object import AXObject -from .ax_component import AXComponent -from .ax_utilities_role import AXUtilitiesRole -from .ax_utilities_state import AXUtilitiesState - - -class AXTable: - """Utilities for obtaining information about accessible tables.""" - - # Things we cache. - CAPTIONS: dict[int, Atspi.Accessible] = {} - PHYSICAL_COORDINATES_FROM_CELL: dict[int, tuple[int, int]] = {} - PHYSICAL_COORDINATES_FROM_TABLE: dict[int, tuple[int, int]] = {} - PHYSICAL_SPANS_FROM_CELL: dict[int, tuple[int, int]] = {} - PHYSICAL_SPANS_FROM_TABLE: dict[int, tuple[int, int]] = {} - PHYSICAL_COLUMN_COUNT: dict[int, int] = {} - PHYSICAL_ROW_COUNT: dict[int, int] = {} - PRESENTABLE_COORDINATES: dict[int, tuple[Optional[str], Optional[str]]] = {} - PRESENTABLE_COORDINATES_LABELS: dict[int, str] = {} - PRESENTABLE_SPANS: dict[int, tuple[Optional[str], Optional[str]]] = {} - PRESENTABLE_COLUMN_COUNT: dict[int, Optional[int]] = {} - PRESENTABLE_ROW_COUNT: dict[int, Optional[int]] = {} - COLUMN_HEADERS_FOR_CELL: dict[int, list[Atspi.Accessible]] = {} - ROW_HEADERS_FOR_CELL: dict[int, list[Atspi.Accessible]] = {} - - # Things which have to be explicitly cleared. - DYNAMIC_COLUMN_HEADERS_ROW: dict[int, int] = {} - DYNAMIC_ROW_HEADERS_COLUMN: dict[int, int] = {} - - _lock = threading.Lock() - - @staticmethod - def start_cache_clearing_thread() -> None: - """Starts thread to periodically clear cached details.""" - - thread = threading.Thread(target=AXTable._clear_stored_data) - thread.daemon = True - thread.start() - - @staticmethod - def _clear_stored_data() -> None: - """Clears any data we have cached for objects""" - - while True: - time.sleep(60) - AXTable._clear_all_dictionaries() - - @staticmethod - def _clear_all_dictionaries(reason: str = "") -> None: - msg = "AXTable: Clearing cache." - if reason: - msg += f" Reason: {reason}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - with AXTable._lock: - AXTable.CAPTIONS.clear() - AXTable.PHYSICAL_COORDINATES_FROM_CELL.clear() - AXTable.PHYSICAL_COORDINATES_FROM_TABLE.clear() - AXTable.PHYSICAL_SPANS_FROM_CELL.clear() - AXTable.PHYSICAL_SPANS_FROM_TABLE.clear() - AXTable.PHYSICAL_COLUMN_COUNT.clear() - AXTable.PHYSICAL_ROW_COUNT.clear() - AXTable.PRESENTABLE_COORDINATES.clear() - AXTable.PRESENTABLE_COORDINATES_LABELS.clear() - AXTable.PRESENTABLE_COLUMN_COUNT.clear() - AXTable.PRESENTABLE_ROW_COUNT.clear() - AXTable.COLUMN_HEADERS_FOR_CELL.clear() - AXTable.ROW_HEADERS_FOR_CELL.clear() - - @staticmethod - def clear_cache_now(reason: str = "") -> None: - """Clears all cached information immediately.""" - - AXTable._clear_all_dictionaries(reason) - - @staticmethod - def get_caption(table: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the accessible object containing the caption of table.""" - - if not AXObject.supports_table(table): - return None - - if hash(table) in AXTable.CAPTIONS: - return AXTable.CAPTIONS.get(hash(table)) - - try: - caption = Atspi.Table.get_caption(table) - except GLib.GError as error: - msg = f"AXTable: Exception in get_caption: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - - tokens = ["AXTable: Caption for", table, "is", caption] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.CAPTIONS[hash(table)] = caption - return caption - - @staticmethod - def get_column_count(table: Atspi.Accessible, prefer_attribute: bool = True) -> int: - """Returns the column count of table.""" - - if not AXObject.supports_table(table): - return -1 - - if prefer_attribute: - count = AXTable._get_column_count_from_attribute(table) - if count is not None: - return count - - count = AXTable.PHYSICAL_COLUMN_COUNT.get(hash(table)) - if count is not None: - return count - - try: - count = Atspi.Table.get_n_columns(table) - except GLib.GError as error: - msg = f"AXTable: Exception in get_column_count: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1 - - tokens = ["AXTable: Column count for", table, "is", count] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PHYSICAL_COLUMN_COUNT[hash(table)] = count - return count - - @staticmethod - def _get_column_count_from_attribute(table: Atspi.Accessible) -> Optional[int]: - """Returns the value of the 'colcount' object attribute or None if not found.""" - - if hash(table) in AXTable.PRESENTABLE_COLUMN_COUNT: - return AXTable.PRESENTABLE_COLUMN_COUNT.get(hash(table)) - - attrs = AXObject.get_attributes_dict(table) - attr = attrs.get("colcount") - count = None - if attr is not None: - count = int(attr) - - tokens = ["AXTable: Column count attribute for", table, "is", count] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PRESENTABLE_COLUMN_COUNT[hash(table)] = count - return count - - @staticmethod - def get_row_count(table: Atspi.Accessible, prefer_attribute: bool = True) -> int: - """Returns the row count of table.""" - - if not AXObject.supports_table(table): - return -1 - - if prefer_attribute: - count = AXTable._get_row_count_from_attribute(table) - if count is not None: - return count - - count = AXTable.PHYSICAL_ROW_COUNT.get(hash(table)) - if count is not None: - return count - - try: - count = Atspi.Table.get_n_rows(table) - except GLib.GError as error: - msg = f"AXTable: Exception in get_row_count: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1 - - tokens = ["AXTable: Row count for", table, "is", count] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PHYSICAL_ROW_COUNT[hash(table)] = count - return count - - @staticmethod - def _get_row_count_from_attribute(table: Atspi.Accessible) -> Optional[int]: - """Returns the value of the 'rowcount' object attribute or None if not found.""" - - if hash(table) in AXTable.PRESENTABLE_ROW_COUNT: - return AXTable.PRESENTABLE_ROW_COUNT.get(hash(table)) - - attrs = AXObject.get_attributes_dict(table) - attr = attrs.get("rowcount") - count = None - if attr is not None: - count = int(attr) - - tokens = ["AXTable: Row count attribute for", table, "is", count] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PRESENTABLE_ROW_COUNT[hash(table)] = count - return count - - @staticmethod - def is_non_uniform_table( - table: Atspi.Accessible, max_rows: int = 25, max_cols: int = 25 - ) -> bool: - """Returns True if table has at least one cell with a span > 1.""" - - for row in range(min(max_rows, AXTable.get_row_count(table, False))): - for col in range(min(max_cols, AXTable.get_column_count(table, False))): - try: - if Atspi.Table.get_row_extent_at(table, row, col) > 1: - return True - if Atspi.Table.get_column_extent_at(table, row, col) > 1: - return True - except GLib.GError as error: - msg = f"AXTable: Exception in is_non_uniform_table: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - return False - - @staticmethod - def get_selected_column_count(table: Atspi.Accessible) -> int: - """Returns the number of selected columns in table.""" - - if not AXObject.supports_table(table): - return 0 - - try: - count = Atspi.Table.get_n_selected_columns(table) - except GLib.GError as error: - msg = f"AXTable: Exception in get_selected_column_count {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0 - - tokens = ["AXTable: Selected column count for", table, "is", count] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return count - - @staticmethod - def get_selected_columns(table: Atspi.Accessible) -> list[int]: - """Returns a list of column indices for the selected columns in table.""" - - if not AXObject.supports_table(table): - return [] - - try: - columns = Atspi.Table.get_selected_columns(table) - except GLib.GError as error: - msg = f"AXTable: Exception in get_selected_columns: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return [] - - tokens = ["AXTable: Selected columns for", table, "are", columns] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return columns - - @staticmethod - def get_selected_row_count(table: Atspi.Accessible) -> int: - """Returns the number of selected rows in table.""" - - if not AXObject.supports_table(table): - return 0 - - try: - count = Atspi.Table.get_n_selected_rows(table) - except GLib.GError as error: - msg = f"AXTable: Exception in get_selected_row_count {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0 - - tokens = ["AXTable: Selected row count for", table, "is", count] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return count - - @staticmethod - def get_selected_rows(table: Atspi.Accessible) -> list[int]: - """Returns a list of row indices for the selected rows in table.""" - - if not AXObject.supports_table(table): - return [] - - try: - rows = Atspi.Table.get_selected_rows(table) - except GLib.GError as error: - msg = f"AXTable: Exception in get_selected_rows: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return [] - - tokens = ["AXTable: Selected rows for", table, "are", rows] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return rows - - @staticmethod - def all_cells_are_selected(table: Atspi.Accessible) -> bool: - """Returns True if all cells in table are selected.""" - - if not AXObject.supports_table(table): - return False - - rows = AXTable.get_row_count(table, prefer_attribute=False) - if rows <= 0: - return False - - if AXTable.get_selected_row_count(table) == rows: - return True - - cols = AXTable.get_column_count(table, prefer_attribute=False) - return AXTable.get_selected_column_count(table) == cols - - @staticmethod - def get_cell_at(table: Atspi.Accessible, row: int, column: int) -> Optional[Atspi.Accessible]: - """Returns the cell at the 0-indexed row and column.""" - - if not AXObject.supports_table(table): - return None - - try: - cell = Atspi.Table.get_accessible_at(table, row, column) - except GLib.GError as error: - tokens = [f"AXTable: Exception getting cell at row: {row} col: {column} in", table, - ":", error] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - tokens = [f"AXTable: Cell at row: {row} col: {column} in", table, "is", cell] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return cell - - @staticmethod - def _get_cell_index(cell: Atspi.Accessible) -> int: - """Returns the index of cell to be used with the table interface.""" - - index = AXObject.get_attribute(cell, "table-cell-index") - if index is not None and index != "": - return int(index) - - # We might have nested cells. So far this has only been seen in Gtk, - # where the parent of a table cell is also a table cell. We need the - # index of the parent for use with the table interface. - parent = AXObject.get_parent(cell) - if AXObject.get_role(parent) == Atspi.Role.TABLE_CELL: - cell = parent - - return AXObject.get_index_in_parent(cell) - - @staticmethod - def get_cell_spans(cell: Atspi.Accessible, prefer_attribute: bool = True) -> tuple[int, int]: - """Returns the row and column spans.""" - - if not AXUtilitiesRole.is_table_cell_or_header(cell): - return -1, -1 - - if AXObject.supports_table_cell(cell): - row_span, col_span = AXTable._get_cell_spans_from_table_cell(cell) - else: - row_span, col_span = AXTable._get_cell_spans_from_table(cell) - - if not prefer_attribute: - return row_span, col_span - - rowspan_attr, colspan_attr = AXTable._get_cell_spans_from_attribute(cell) - if rowspan_attr is not None: - row_span = int(rowspan_attr) - if colspan_attr is not None: - col_span = int(colspan_attr) - - return row_span, col_span - - @staticmethod - def _get_cell_spans_from_attribute( - cell: Atspi.Accessible - ) -> tuple[Optional[str], Optional[str]]: - """Returns the row and column spans exposed via object attribute, or None, None.""" - - if hash(cell) in AXTable.PRESENTABLE_SPANS: - return AXTable.PRESENTABLE_SPANS.get(hash(cell), (None, None)) - - attrs = AXObject.get_attributes_dict(cell) - row_span = attrs.get("rowspan", None) - col_span = attrs.get("colspan", None) - - tokens = ["AXTable: Row and col span attributes for", cell, ":", row_span, ",", col_span] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PRESENTABLE_SPANS[hash(cell)] = row_span, col_span - return row_span, col_span - - @staticmethod - def _get_cell_spans_from_table(cell: Atspi.Accessible) -> tuple[int, int]: - """Returns the row and column spans of cell via the table interface.""" - - if hash(cell) in AXTable.PHYSICAL_SPANS_FROM_TABLE: - return AXTable.PHYSICAL_SPANS_FROM_TABLE.get(hash(cell), (-1, -1)) - - index = AXTable._get_cell_index(cell) - if index < 0: - return -1, -1 - - table = AXTable.get_table(cell) - if table is None: - return -1, -1 - - if not AXObject.supports_table(table): - return -1, -1 - - # Cells in a tree are expected to not span multiple rows or columns. - # Also this: https://bugreports.qt.io/browse/QTBUG-119167 - if AXUtilitiesRole.is_tree(table): - return 1, 1 - - try: - result = Atspi.Table.get_row_column_extents_at_index(table, index) - except GLib.GError as error: - msg = f"AXTable: Exception in _get_cell_spans_from_table: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1, -1 - - if result is None: - tokens = ["AXTable: get_row_column_extents_at_index failed for", cell, - f"at index {index} in", table] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return -1, -1 - - if not result[0]: - return -1, -1 - - row_span = result.row_extents - row_count = AXTable.get_row_count(table, False) - if row_span > row_count: - tokens = ["AXTable: Table iface row span for", cell, - f"{row_span} is greater than row count: {row_count}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - row_span = 1 - - col_span = result.col_extents - col_count = AXTable.get_column_count(table, False) - if col_span > col_count: - tokens = ["AXTable: Table iface col span for", cell, - f"{col_span} is greater than col count: {col_count}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - col_span = 1 - - tokens = ["AXTable: Table iface spans for", cell, - f"are rowspan: {row_span}, colspan: {col_span}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PHYSICAL_SPANS_FROM_TABLE[hash(cell)] = row_span, col_span - return row_span, col_span - - @staticmethod - def _get_cell_spans_from_table_cell(cell: Atspi.Accessible) -> tuple[int, int]: - """Returns the row and column spans of cell via the table cell interface.""" - - if hash(cell) in AXTable.PHYSICAL_SPANS_FROM_CELL: - return AXTable.PHYSICAL_SPANS_FROM_CELL.get(hash(cell), (-1, -1)) - - if not AXObject.supports_table_cell(cell): - return -1, -1 - - try: - # TODO - JD: We get the spans individually due to - # https://bugzilla.mozilla.org/show_bug.cgi?id=1862437 - row_span = Atspi.TableCell.get_row_span(cell) - col_span = Atspi.TableCell.get_column_span(cell) - except GLib.GError as error: - msg = f"AXTable: Exception in _get_cell_spans_from_table_cell: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1, -1 - - tokens = ["AXTable: TableCell iface spans for", cell, - f"are rowspan: {row_span}, colspan: {col_span}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PHYSICAL_SPANS_FROM_CELL[hash(cell)] = row_span, col_span - return row_span, col_span - - @staticmethod - def _get_column_headers_from_table( - table: Atspi.Accessible, column: int - ) -> list[Atspi.Accessible]: - """Returns the column headers of the indexed column via the table interface.""" - - if not AXObject.supports_table(table): - return [] - - if column < 0: - return [] - - try: - header = Atspi.Table.get_column_header(table, column) - except GLib.GError as error: - msg = f"AXTable: Exception in _get_column_headers_from_table: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return [] - - tokens = [f"AXTable: Table iface header for column {column} of", table, "is", header] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if header is not None: - return [header] - - return [] - - @staticmethod - def _get_column_headers_from_table_cell(cell: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns the column headers for cell via the table cell interface.""" - - if not AXObject.supports_table_cell(cell): - return [] - - try: - headers = Atspi.TableCell.get_column_header_cells(cell) - except GLib.GError as error: - msg = f"AXTable: Exception in _get_column_headers_from_table_cell: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return [] - - if headers is None: - tokens = ["AXTable: get_column_header_cells failed for", cell] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - tokens = ["AXTable: TableCell iface column headers for cell are:", headers] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return headers - - @staticmethod - def _get_row_headers_from_table(table: Atspi.Accessible, row: int) -> list[Atspi.Accessible]: - """Returns the row headers of the indexed row via the table interface.""" - - if not AXObject.supports_table(table): - return [] - - if row < 0: - return [] - - try: - header = Atspi.Table.get_row_header(table, row) - except GLib.GError as error: - msg = f"AXTable: Exception in _get_row_headers_from_table: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return [] - - tokens = [f"AXTable: Table iface header for row {row} of", table, "is", header] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if header is not None: - return [header] - - return [] - - @staticmethod - def _get_row_headers_from_table_cell(cell: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns the row headers for cell via the table cell interface.""" - - if not AXObject.supports_table_cell(cell): - return [] - - try: - headers = Atspi.TableCell.get_row_header_cells(cell) - except GLib.GError as error: - msg = f"AXTable: Exception in _get_row_headers_from_table_cell: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return [] - - if headers is None: - tokens = ["AXTable: get_row_header_cells failed for", cell] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - tokens = ["AXTable: TableCell iface row headers for cell are:", headers] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return headers - - @staticmethod - def get_new_row_headers( - cell: Atspi.Accessible, - old_cell: Optional[Atspi.Accessible] - ) -> list[Atspi.Accessible]: - """Returns row headers of cell that are not also headers of old_cell. """ - - if old_cell and not AXUtilitiesRole.is_table_cell_or_header(old_cell): - old_cell = AXObject.find_ancestor(old_cell, AXUtilitiesRole.is_table_cell_or_header) - - headers = AXTable.get_row_headers(cell) - if old_cell is None: - return headers - - old_headers = AXTable.get_row_headers(old_cell) - return list(set(headers).difference(set(old_headers))) - - @staticmethod - def get_new_column_headers( - cell: Atspi.Accessible, - old_cell: Optional[Atspi.Accessible] - ) -> list[Atspi.Accessible]: - """Returns column headers of cell that are not also headers of old_cell. """ - - if old_cell and not AXUtilitiesRole.is_table_cell_or_header(old_cell): - old_cell = AXObject.find_ancestor(old_cell, AXUtilitiesRole.is_table_cell_or_header) - - headers = AXTable.get_column_headers(cell) - if old_cell is None: - return headers - - old_headers = AXTable.get_column_headers(old_cell) - return list(set(headers).difference(set(old_headers))) - - @staticmethod - def get_row_headers(cell: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns the row headers for cell, doing extra work to ensure we have them all.""" - - if not AXUtilitiesRole.is_table_cell(cell): - return [] - - dynamic_header = AXTable.get_dynamic_row_header(cell) - if dynamic_header is not None: - return [dynamic_header] - - # Firefox has the following implementation: - # 1. Only gives us the innermost/closest header for a cell - # 2. Supports returning the header of a header - # Chromium has the following implementation: - # 1. Gives us all the headers for a cell - # 2. Does NOT support returning the header of a header - # The Firefox implementation means we can get all the headers with some work. - # The Chromium implementation means less work, but makes it hard to present - # the changed outer header when navigating among nested row/column headers. - # TODO - JD: Figure out what the rest do, and then try to get the implementations - # aligned. - - result = AXTable.ROW_HEADERS_FOR_CELL.get(hash(cell)) - if result is not None: - return result - - result = AXTable._get_row_headers(cell) - # There either are no headers, or we got all of them. - if len(result) != 1: - AXTable.ROW_HEADERS_FOR_CELL[hash(cell)] = result - return result - - others = AXTable._get_row_headers(result[0]) - while len(others) == 1 and others[0] not in result: - result.insert(0, others[0]) - others = AXTable._get_row_headers(result[0]) - - AXTable.ROW_HEADERS_FOR_CELL[hash(cell)] = result - return result - - @staticmethod - def _get_row_headers(cell: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns the row headers for cell.""" - - if AXObject.supports_table_cell(cell): - return AXTable._get_row_headers_from_table_cell(cell) - - row, column = AXTable._get_cell_coordinates_from_table(cell) - if row < 0 or column < 0: - return [] - - table = AXTable.get_table(cell) - if table is None: - return [] - - headers = [] - rowspan = AXTable._get_cell_spans_from_table(cell)[0] - for index in range(row, row + rowspan): - headers.extend(AXTable._get_row_headers_from_table(table, index)) - - return headers - - @staticmethod - def has_row_headers(table: Atspi.Accessible, stop_after: int = 10) -> bool: - """Returns True if table has any headers for rows 0-stop_after.""" - - if not AXObject.supports_table(table): - return False - - stop_after = min(stop_after + 1, AXTable.get_row_count(table)) - for i in range(stop_after): - if AXTable._get_row_headers_from_table(table, i): - return True - - return False - - @staticmethod - def get_column_headers(cell: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns the column headers for cell, doing extra work to ensure we have them all.""" - - if not AXUtilitiesRole.is_table_cell(cell): - return [] - - dynamic_header = AXTable.get_dynamic_column_header(cell) - if dynamic_header is not None: - return [dynamic_header] - - # Firefox has the following implementation: - # 1. Only gives us the innermost/closest header for a cell - # 2. Supports returning the header of a header - # Chromium has the following implementation: - # 1. Gives us all the headers for a cell - # 2. Does NOT support returning the header of a header - # The Firefox implementation means we can get all the headers with some work. - # The Chromium implementation means less work, but makes it hard to present - # the changed outer header when navigating among nested row/column headers. - # TODO - JD: Figure out what the rest do, and then try to get the implementations - # aligned. - - result = AXTable.COLUMN_HEADERS_FOR_CELL.get(hash(cell)) - if result is not None: - return result - - result = AXTable._get_column_headers(cell) - # There either are no headers, or we got all of them. - if len(result) != 1: - AXTable.COLUMN_HEADERS_FOR_CELL[hash(cell)] = result - return result - - others = AXTable._get_column_headers(result[0]) - while len(others) == 1 and others[0] not in result: - result.insert(0, others[0]) - others = AXTable._get_column_headers(result[0]) - - AXTable.COLUMN_HEADERS_FOR_CELL[hash(cell)] = result - return result - - @staticmethod - def _get_column_headers(cell: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns the column headers for cell.""" - - if AXObject.supports_table_cell(cell): - return AXTable._get_column_headers_from_table_cell(cell) - - row, column = AXTable._get_cell_coordinates_from_table(cell) - if row < 0 or column < 0: - return [] - - table = AXTable.get_table(cell) - if table is None: - return [] - - headers = [] - colspan = AXTable._get_cell_spans_from_table(cell)[1] - for index in range(column, column + colspan): - headers.extend(AXTable._get_column_headers_from_table(table, index)) - - return headers - - @staticmethod - def has_column_headers(table: Atspi.Accessible, stop_after: int = 10) -> bool: - """Returns True if table has any headers for columns 0-stop_after.""" - - if not AXObject.supports_table(table): - return False - - stop_after = min(stop_after + 1, AXTable.get_column_count(table)) - for i in range(stop_after): - if AXTable._get_column_headers_from_table(table, i): - return True - - return False - - @staticmethod - def get_cell_coordinates( - cell: Atspi.Accessible, - prefer_attribute: bool = True, - find_cell: bool = False - ) -> tuple[int, int]: - """Returns the 0-based row and column indices.""" - - if not AXUtilitiesRole.is_table_cell_or_header(cell) and find_cell: - cell = AXObject.find_ancestor(cell, AXUtilitiesRole.is_table_cell_or_header) - - if not AXUtilitiesRole.is_table_cell_or_header(cell): - return -1, -1 - - if AXObject.supports_table_cell(cell): - row, col = AXTable._get_cell_coordinates_from_table_cell(cell) - else: - row, col = AXTable._get_cell_coordinates_from_table(cell) - - if not prefer_attribute: - return row, col - - row_index, col_index = AXTable._get_cell_coordinates_from_attribute(cell) - if row_index is not None: - row = int(row_index) - 1 - if col_index is not None: - col = int(col_index) - 1 - - return row, col - - @staticmethod - def _get_cell_coordinates_from_table(cell: Atspi.Accessible) -> tuple[int, int]: - """Returns the row and column indices of cell via the table interface.""" - - if hash(cell) in AXTable.PHYSICAL_COORDINATES_FROM_TABLE: - return AXTable.PHYSICAL_COORDINATES_FROM_TABLE.get(hash(cell), (-1, -1)) - - index = AXTable._get_cell_index(cell) - if index < 0: - return -1, -1 - - table = AXTable.get_table(cell) - if table is None: - tokens = ["AXTable: Couldn't find table-implementing ancestor for", cell] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return -1, -1 - - try: - row = Atspi.Table.get_row_at_index(table, index) - column = Atspi.Table.get_column_at_index(table, index) - except GLib.GError as error: - msg = f"AXTable: Exception in _get_cell_coordinates_from_table: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1, -1 - - tokens = ["AXTable: Table iface coords for", cell, f"are row: {row}, col: {column}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PHYSICAL_COORDINATES_FROM_TABLE[hash(cell)] = row, column - return row, column - - @staticmethod - def _get_cell_coordinates_from_table_cell(cell: Atspi.Accessible) -> tuple[int, int]: - """Returns the row and column indices of cell via the table cell interface.""" - - if hash(cell) in AXTable.PHYSICAL_COORDINATES_FROM_CELL: - return AXTable.PHYSICAL_COORDINATES_FROM_CELL.get(hash(cell), (-1, -1)) - - if not AXObject.supports_table_cell(cell): - return -1, -1 - - try: - success, row, column = Atspi.TableCell.get_position(cell) - except GLib.GError as error: - msg = f"AXTable: Exception in _get_cell_coordinates_from_table_cell: {error}" - - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1, -1 - - if not success: - return -1, -1 - - tokens = ["AXTable: TableCell iface coords for", cell, f"are row: {row}, col: {column}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PHYSICAL_COORDINATES_FROM_CELL[hash(cell)] = row, column - return row, column - - @staticmethod - def _get_cell_coordinates_from_attribute( - cell: Atspi.Accessible - ) -> tuple[Optional[str], Optional[str]]: - """Returns the 1-based indices for cell exposed via object attribute, or None, None.""" - - if cell is None: - return None, None - - if hash(cell) in AXTable.PRESENTABLE_COORDINATES: - return AXTable.PRESENTABLE_COORDINATES.get(hash(cell), (None, None)) - - attrs = AXObject.get_attributes_dict(cell) - row_index = attrs.get("rowindex") - col_index = attrs.get("colindex") - - tokens = ["AXTable: Row and col index attributes for", cell, ":", row_index, ",", col_index] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PRESENTABLE_COORDINATES[hash(cell)] = row_index, col_index - if row_index is not None and col_index is not None: - return row_index, col_index - - row = AXObject.find_ancestor(cell, AXUtilitiesRole.is_table_row) - if row is None: - return row_index, col_index - - attrs = AXObject.get_attributes_dict(row) - row_index = attrs.get("rowindex", row_index) - col_index = attrs.get("colindex", col_index) - - tokens = ["AXTable: Updated attributes based on", row, ":", row_index, col_index] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PRESENTABLE_COORDINATES[hash(cell)] = row_index, col_index - return row_index, col_index - - @staticmethod - def get_presentable_sort_order_from_header( - obj: Atspi.Accessible, - include_name: bool = False - ) -> str: - """Returns the end-user-consumable row/column sort order from its header.""" - - if not AXUtilitiesRole.is_table_header(obj): - return "" - - sort_order = AXObject.get_attribute(obj, "sort", False) - if not sort_order or sort_order == "none": - return "" - - if sort_order == "ascending": - result = object_properties.SORT_ORDER_ASCENDING - elif sort_order == "descending": - result = object_properties.SORT_ORDER_DESCENDING - else: - result = object_properties.SORT_ORDER_OTHER - - if include_name: - name = AXObject.get_name(obj) - if name: - result = f"{name}. {result}" - - return result - - @staticmethod - def get_table(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns obj if it is a table, otherwise returns the ancestor table of obj.""" - - if obj is None: - return None - - if AXObject.supports_table_cell(obj): - try: - table = Atspi.TableCell.get_table(obj) - except GLib.GError as error: - msg = f"AXTable: Exception in get_table: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - else: - if AXObject.supports_table(table): - return table - - def is_table(x): - if AXUtilitiesRole.is_table(x) \ - or AXUtilitiesRole.is_tree_table(x) or AXUtilitiesRole.is_tree(x): - return AXObject.supports_table(x) - return False - - if is_table(obj): - return obj - - return AXObject.find_ancestor(obj, is_table) - - @staticmethod - def get_table_description_for_presentation(table: Atspi.Accessible) -> str: - """Returns an end-user-consumable string which describes the table.""" - - if not AXObject.supports_table(table): - return "" - - result = messages.table_size(AXTable.get_row_count(table), AXTable.get_column_count(table)) - if AXTable.is_non_uniform_table(table): - result = f"{messages.TABLE_NON_UNIFORM} {result}" - return result - - @staticmethod - def get_first_cell(table: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the first cell in table.""" - - row, col = 0, 0 - return AXTable.get_cell_at(table, row, col) - - @staticmethod - def get_last_cell(table: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the last cell in table.""" - - row, col = AXTable.get_row_count(table) - 1, AXTable.get_column_count(table) - 1 - return AXTable.get_cell_at(table, row, col) - - @staticmethod - def get_cell_above(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the cell above cell in table.""" - - row, col = AXTable.get_cell_coordinates(cell, prefer_attribute=False) - row -= 1 - return AXTable.get_cell_at(AXTable.get_table(cell), row, col) - - @staticmethod - def get_cell_below(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the cell below cell in table.""" - - row, col = AXTable.get_cell_coordinates(cell, prefer_attribute=False) - row += AXTable.get_cell_spans(cell, prefer_attribute=False)[0] - return AXTable.get_cell_at(AXTable.get_table(cell), row, col) - - @staticmethod - def get_cell_on_left(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the cell to the left.""" - - row, col = AXTable.get_cell_coordinates(cell, prefer_attribute=False) - col -= 1 - return AXTable.get_cell_at(AXTable.get_table(cell), row, col) - - @staticmethod - def get_cell_on_right(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the cell to the right.""" - - row, col = AXTable.get_cell_coordinates(cell, prefer_attribute=False) - col += AXTable.get_cell_spans(cell, prefer_attribute=False)[1] - return AXTable.get_cell_at(AXTable.get_table(cell), row, col) - - @staticmethod - def get_start_of_row(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the cell at the start of cell's row.""" - - row = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[0] - return AXTable.get_cell_at(AXTable.get_table(cell), row, 0) - - @staticmethod - def get_end_of_row(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the cell at the end of cell's row.""" - - row = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[0] - table = AXTable.get_table(cell) - col = AXTable.get_column_count(table) - 1 - return AXTable.get_cell_at(AXTable.get_table(cell), row, col) - - @staticmethod - def get_top_of_column(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the cell at the top of cell's column.""" - - col = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[1] - return AXTable.get_cell_at(AXTable.get_table(cell), 0, col) - - @staticmethod - def get_bottom_of_column(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the cell at the bottom of cell's column.""" - - col = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[1] - table = AXTable.get_table(cell) - row = AXTable.get_row_count(table) - 1 - return AXTable.get_cell_at(AXTable.get_table(cell), row, col) - - @staticmethod - def get_cell_formula(cell: Atspi.Accessible) -> Optional[str]: - """Returns the formula associated with this cell.""" - - attrs = AXObject.get_attributes_dict(cell, use_cache=False) - return attrs.get("formula", attrs.get("Formula")) - - @staticmethod - def is_first_cell(cell: Atspi.Accessible) -> bool: - """Returns True if this is the first cell in its table.""" - - row, col = AXTable.get_cell_coordinates(cell, prefer_attribute=False) - return row == 0 and col == 0 - - @staticmethod - def is_last_cell(cell: Atspi.Accessible) -> bool: - """Returns True if this is the last cell in its table.""" - - row, col = AXTable.get_cell_coordinates(cell, prefer_attribute=False) - if row < 0 or col < 0: - return False - - table = AXTable.get_table(cell) - if table is None: - return False - - return row + 1 == AXTable.get_row_count(table, prefer_attribute=False) \ - and col + 1 == AXTable.get_column_count(table, prefer_attribute=False) - - @staticmethod - def is_start_of_row(cell: Atspi.Accessible) -> bool: - """Returns True if this is the first cell in its row.""" - - col = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[1] - return col == 0 - - @staticmethod - def is_end_of_row(cell: Atspi.Accessible) -> bool: - """Returns True if this is the last cell in its row.""" - - col = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[1] - if col < 0: - return False - - table = AXTable.get_table(cell) - if table is None: - return False - - return col + 1 == AXTable.get_column_count(table, prefer_attribute=False) - - @staticmethod - def is_top_of_column(cell: Atspi.Accessible) -> bool: - """Returns True if this is the first cell in its column.""" - - row = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[0] - return row == 0 - - @staticmethod - def is_bottom_of_column(cell: Atspi.Accessible) -> bool: - """Returns True if this is the last cell in its column.""" - - row = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[0] - if row < 0: - return False - - table = AXTable.get_table(cell) - if table is None: - return False - - return row + 1 == AXTable.get_row_count(table, prefer_attribute=False) - - @staticmethod - def is_layout_table(table: Atspi.Accessible) -> bool: - """Returns True if this table should be treated as layout only.""" - - result, reason = False, "Not enough information" - attrs = AXObject.get_attributes_dict(table) - if AXUtilitiesRole.is_table(table): - if attrs.get("layout-guess") == "true": - result, reason = True, "The layout-guess attribute is true." - elif not AXObject.supports_table(table): - result, reason = True, "Doesn't support table interface." - elif attrs.get("xml-roles") == "table" or attrs.get("tag") == "table": - result, reason = False, "Is a web table without layout-guess set to true." - elif AXTable.has_column_headers(table) or AXTable.has_row_headers(table): - result, reason = False, "Has headers" - elif AXObject.get_name(table) or AXObject.get_description(table): - result, reason = False, "Has name or description" - elif AXTable.get_caption(table): - result, reason = False, "Has caption" - - tokens = ["AXTable:", table, f"is layout only: {result} ({reason})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_label_for_cell_coordinates(cell: Atspi.Accessible) -> str: - """Returns the text that should be used instead of the numeric indices.""" - - if hash(cell) in AXTable.PRESENTABLE_COORDINATES_LABELS: - return AXTable.PRESENTABLE_COORDINATES_LABELS.get(hash(cell), "") - - attrs = AXObject.get_attributes_dict(cell) - result = "" - - # The attribute officially has the word "index" in it for clarity. - # TODO - JD: Google Sheets needs to start using the correct attribute name. - col_label = attrs.get("colindextext", attrs.get("coltext")) - row_label = attrs.get("rowindextext", attrs.get("rowtext")) - if col_label is not None and row_label is not None: - result = f"{col_label}{row_label}" - - tokens = ["AXTable: Coordinates label for", cell, f": {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PRESENTABLE_COORDINATES_LABELS[hash(cell)] = result - if result: - return result - - row = AXObject.find_ancestor(cell, AXUtilitiesRole.is_table_row) - if row is None: - return result - - attrs = AXObject.get_attributes_dict(row) - col_label = attrs.get("colindextext", attrs.get("coltext", col_label)) - row_label = attrs.get("rowindextext", attrs.get("rowtext", row_label)) - if col_label is not None and row_label is not None: - result = f"{col_label}{row_label}" - - tokens = ["AXTable: Updated coordinates label based on", row, f": {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - AXTable.PRESENTABLE_COORDINATES_LABELS[hash(cell)] = result - return result - - @staticmethod - def get_dynamic_row_header(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the user-set row header for cell.""" - - table = AXTable.get_table(cell) - headers_column = AXTable.DYNAMIC_ROW_HEADERS_COLUMN.get(hash(table)) - if headers_column is None: - return None - - cell_row, cell_column = AXTable.get_cell_coordinates(cell) - if cell_column == headers_column: - return None - - return AXTable.get_cell_at(table, cell_row, headers_column) - - @staticmethod - def get_dynamic_column_header(cell: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the user-set column header for cell.""" - - table = AXTable.get_table(cell) - headers_row = AXTable.DYNAMIC_COLUMN_HEADERS_ROW.get(hash(table)) - if headers_row is None: - return None - - cell_row, cell_column = AXTable.get_cell_coordinates(cell) - if cell_row == headers_row: - return None - - return AXTable.get_cell_at(table, headers_row, cell_column) - - @staticmethod - def set_dynamic_row_headers_column(table: Atspi.Accessible, column: int) -> None: - """Sets the dynamic row headers column of table to column.""" - - AXTable.DYNAMIC_ROW_HEADERS_COLUMN[hash(table)] = column - - @staticmethod - def set_dynamic_column_headers_row(table: Atspi.Accessible, row: int) -> None: - """Sets the dynamic column headers row of table to row.""" - - AXTable.DYNAMIC_COLUMN_HEADERS_ROW[hash(table)] = row - - @staticmethod - def clear_dynamic_row_headers_column(table: Atspi.Accessible) -> None: - """Clears the dynamic row headers column of table.""" - - if hash(table) not in AXTable.DYNAMIC_ROW_HEADERS_COLUMN: - return - - AXTable.DYNAMIC_ROW_HEADERS_COLUMN.pop(hash(table)) - - @staticmethod - def clear_dynamic_column_headers_row(table: Atspi.Accessible) -> None: - """Clears the dynamic column headers row of table.""" - - if hash(table) not in AXTable.DYNAMIC_COLUMN_HEADERS_ROW: - return - - AXTable.DYNAMIC_COLUMN_HEADERS_ROW.pop(hash(table)) - - @staticmethod - def _get_visible_cell_range(table: Atspi.Accessible) -> tuple[tuple[int, int], tuple[int, int]]: - """Returns the (row, col) of the first and last visible cells in table.""" - - if not AXObject.supports_table(table): - return (-1, -1), (-1, -1) - - rect = AXComponent.get_rect(table) - tokens = ["AXTable: Rect for", table, "is", rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - first_cell = AXComponent.get_descendant_at_point(table, rect.x + 1, rect.y + 1) - tokens = ["AXTable: First visible cell for", table, "is", first_cell] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - start = AXTable.get_cell_coordinates(first_cell, prefer_attribute=False) - tokens = ["AXTable: First visible cell is at row", start[0], "column", start[1]] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - last_cell = AXComponent.get_descendant_at_point( - table, rect.x + rect.width - 1, rect.y + rect.height - 1) - tokens = ["AXTable: Last visible cell for", table, "is", last_cell] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - end = AXTable.get_cell_coordinates(last_cell, prefer_attribute=False) - tokens = ["AXTable: Last visible cell is at row", end[0], "column", end[1]] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if end == (-1, -1): - last_cell = AXTable.get_last_cell(table) - tokens = ["AXTable: Adjusted lasat visible cell for", table, "is", last_cell] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - end = AXTable.get_cell_coordinates(last_cell, prefer_attribute=False) - tokens = ["AXTable: Adjusted last cell is at row", end[0], "column", end[1]] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if AXUtilitiesRole.is_table_cell(last_cell) \ - and not AXUtilitiesRole.is_table_cell_or_header(first_cell): - candidate = AXTable.get_cell_above(last_cell) - while candidate and AXComponent.object_intersects_rect(candidate, rect): - first_cell = candidate - candidate = AXTable.get_cell_above(first_cell) - - candidate = AXTable.get_cell_on_left(first_cell) - while candidate and AXComponent.object_intersects_rect(candidate, rect): - first_cell = candidate - candidate = AXTable.get_cell_on_left(first_cell) - - tokens = ["AXTable: Adjusted first visible cell for", table, "is", first_cell] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - start = AXTable.get_cell_coordinates(first_cell, prefer_attribute=False) - tokens = ["AXTable: Adjusted first cell is at row", start[0], "column", start[1]] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return start, end - - @staticmethod - def iter_visible_cells(table: Atspi.Accessible) -> Generator[Atspi.Accessible, None, None]: - """Yields the visible cells in table.""" - - start, end = AXTable._get_visible_cell_range(table) - if start[0] < 0 or start[1] < 0 or end[0] < 0 or end[1] < 0: - return - - for row in range(start[0], end[0] + 1): - for col in range(start[1], end[1] + 1): - cell = AXTable.get_cell_at(table, row, col) - if cell is None: - continue - for child in AXObject.iter_children(cell, AXUtilitiesRole.is_table_cell): - if AXObject.get_name(child): - cell = child - break - yield cell - - @staticmethod - def get_showing_cells_in_same_row( - cell: Atspi.Accessible, - clip_to_window: bool = False - ) -> list[Atspi.Accessible]: - """Returns a list of all the cells in the same row as obj that are showing.""" - - row = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[0] - if row == -1: - return [] - - table = AXTable.get_table(cell) - start_index, end_index = 0, AXTable.get_column_count(table, False) - if clip_to_window: - rect = AXComponent.get_rect(table) - if (cell := AXComponent.get_descendant_at_point(table, rect.x + 1, rect.y)): - start_index = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[1] - if (cell := AXComponent.get_descendant_at_point( - table, rect.x + rect.width - 1, rect.y)): - end_index = AXTable.get_cell_coordinates(cell, prefer_attribute=False)[1] + 1 - - if start_index == end_index: - return [] - - cells = [] - for i in range(start_index, end_index): - cell = AXTable.get_cell_at(table, row, i) - if AXUtilitiesState.is_showing(cell): - cells.append(cell) - - if not cells: - tokens = ["AXTable: No visible cells found in row with", cell] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - tokens = ["AXTable: First visible cell in row with", cell, "is", cells[0]] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - tokens = ["AXTable: Last visible cell in row with", cell, "is", cells[-1]] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return cells - - -AXTable.start_cache_clearing_thread() diff --git a/src/cthulhu/ax_text.py b/src/cthulhu/ax_text.py deleted file mode 100644 index 11f429c..0000000 --- a/src/cthulhu/ax_text.py +++ /dev/null @@ -1,1611 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2024 Igalia, S.L. -# Copyright 2024 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-locals -# pylint: disable=too-many-public-methods -# pylint: disable=too-many-branches -# pylint: disable=too-many-lines - -"""Utilities for obtaining information about accessible text.""" - -# This has to be the first non-docstring line in the module to make linters happy. -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Igalia, S.L." \ - "Copyright (c) 2024 GNOME Foundation Inc." -__license__ = "LGPL" - -import enum -import locale -import re -from typing import Generator, Optional - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import colornames -from . import debug -from . import messages -from . import text_attribute_names -from .ax_object import AXObject -from .ax_utilities_role import AXUtilitiesRole -from .ax_utilities_state import AXUtilitiesState - -class AXTextAttribute(enum.Enum): - """Enum representing an accessible text attribute.""" - - # Note: Anything added here should also have an entry in text_attribute_names.py. - # The tuple is (non-localized name, enable by default). - BG_COLOR = ("bg-color", True) - BG_FULL_HEIGHT = ("bg-full-height", False) - BG_STIPPLE = ("bg-stipple", False) - DIRECTION = ("direction", False) - EDITABLE = ("editable", False) - FAMILY_NAME = ("family-name", True) - FG_COLOR = ("fg-color", True) - FG_STIPPLE = ("fg-stipple", False) - FONT_EFFECT = ("font-effect", True) - INDENT = ("indent", True) - INVALID = ("invalid", True) - INVISIBLE = ("invisible", False) - JUSTIFICATION = ("justification", True) - LANGUAGE = ("language", False) - LEFT_MARGIN = ("left-margin", False) - LINE_HEIGHT = ("line-height", False) - MARK = ("mark", True) - PARAGRAPH_STYLE = ("paragraph-style", True) - PIXELS_ABOVE_LINES = ("pixels-above-lines", False) - PIXELS_BELOW_LINES = ("pixels-below-lines", False) - PIXELS_INSIDE_WRAP = ("pixels-inside-wrap", False) - RIGHT_MARGIN = ("right-margin", False) - RISE = ("rise", False) - SCALE = ("scale", False) - SIZE = ("size", True) - STRETCH = ("stretch", False) - STRIKETHROUGH = ("strikethrough", True) - STYLE = ("style", True) - TEXT_DECORATION = ("text-decoration", True) - TEXT_POSITION = ("text-position", False) - TEXT_ROTATION = ("text-rotation", True) - TEXT_SHADOW = ("text-shadow", False) - UNDERLINE = ("underline", True) - VARIANT = ("variant", False) - VERTICAL_ALIGN = ("vertical-align", False) - WEIGHT = ("weight", True) - WRAP_MODE = ("wrap-mode", False) - WRITING_MODE = ("writing-mode", False) - - @classmethod - def from_string(cls, string: str) -> Optional['AXTextAttribute']: - """Returns the AXTextAttribute for the specified string.""" - - for attribute in cls: - if attribute.get_attribute_name() == string: - return attribute - - return None - - @classmethod - def from_localized_string(cls, string: str) -> Optional['AXTextAttribute']: - """Returns the AXTextAttribute for the specified localized string.""" - - for attribute in cls: - if attribute.get_localized_name() == string: - return attribute - - return None - - def get_attribute_name(self) -> str: - """Returns the non-localized name of the attribute.""" - - return self.value[0] - - def get_localized_name(self) -> str: - """Returns the localized name of the attribute.""" - - name = self.value[0] - return text_attribute_names.attribute_names.get(name, name) - - def get_localized_value(self, value) -> str: - """Returns the localized value of the attribute.""" - - if value is None: - return "" - - if value.endswith("px"): - value = value.split("px")[0] - if locale.localeconv()["decimal_point"] in value: - return messages.pixel_count(float(value)) - return messages.pixel_count(int(value)) - - if self in [AXTextAttribute.BG_COLOR, AXTextAttribute.FG_COLOR]: - return colornames.get_presentable_color_name(value) - - # TODO - JD: Is this still needed? - value = value.replace("-moz", "") - - # TODO - JD: Are these still needed? - if self == AXTextAttribute.JUSTIFICATION: - value = value.replace("justify", "fill") - elif self == AXTextAttribute.FAMILY_NAME: - value = value.split(",")[0].strip().strip('"') - - return text_attribute_names.attribute_values.get(value, value) - - def should_present_by_default(self) -> bool: - """Returns True if the attribute should be presented by default.""" - - return self.value[1] - - def value_is_default(self, value) -> bool: - """Returns True if value should be treated as the default value for this attribute.""" - - null_values = ["0", "0mm", "0px", "none", "false", "normal", "", None] - if value in null_values: - return True - - if self == AXTextAttribute.SCALE: - return float(value) == 1.0 - if self == AXTextAttribute.TEXT_POSITION: - return value == "baseline" - if self == AXTextAttribute.WEIGHT: - return value == "400" - if self == AXTextAttribute.LANGUAGE: - loc = locale.getlocale()[0] or "" - return value == loc[:2] - - return False - -class AXText: - """Utilities for obtaining information about accessible text.""" - - CACHED_TEXT_SELECTION: dict[int, tuple[str, int, int]] = {} - - @staticmethod - def get_character_at_offset( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the (character, start, end) for the current or specified offset.""" - - length = AXText.get_character_count(obj) - if not length: - return "", 0, 0 - - if offset is None: - offset = AXText.get_caret_offset(obj) - - if not 0 <= offset <= length: - msg = f"WARNING: Offset {offset} is not valid. No character can be provided." - debug.print_message(debug.LEVEL_INFO, msg, True) - return "", 0, 0 - - try: - result = Atspi.Text.get_string_at_offset(obj, offset, Atspi.TextGranularity.CHAR) - except GLib.GError as error: - msg = f"AXText: Exception in get_character_at_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "", 0, 0 - - if result is None: - tokens = ["AXText: get_string_at_offset (char) failed for", obj, f"at {offset}."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return "", 0, 0 - - debug_string = result.content.replace("\n", "\\n") - tokens = [f"AXText: Character at offset {offset} in", obj, - f"'{debug_string}' ({result.start_offset}-{result.end_offset})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result.content, result.start_offset, result.end_offset - - @staticmethod - def get_character_at_point(obj: Atspi.Accessible, x: int, y: int) -> tuple[str, int, int]: - """Returns the (character, start, end) at the specified point.""" - - offset = AXText.get_offset_at_point(obj, x, y) - if not 0 <= offset < AXText.get_character_count(obj): - return "", 0, 0 - - return AXText.get_character_at_offset(obj, offset) - - @staticmethod - def get_next_character( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the next (character, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_character, start, end = AXText.get_character_at_offset(obj, offset) - if not current_character: - return "", 0, 0 - - length = AXText.get_character_count(obj) - next_offset = max(end, offset + 1) - - while next_offset < length: - next_character, next_start, next_end = AXText.get_character_at_offset(obj, next_offset) - if (next_character, next_start, next_end) != (current_character, start, end): - return next_character, next_start, next_end - next_offset += 1 - - return "", 0, 0 - - @staticmethod - def get_previous_character( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the previous (character, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_character, start, end = AXText.get_character_at_offset(obj, offset) - if not current_character: - return "", 0, 0 - - if start <= 0: - return "", 0, 0 - - prev_offset = start - 1 - - while prev_offset >= 0: - prev_character, prev_start, prev_end = AXText.get_character_at_offset(obj, prev_offset) - if (prev_character, prev_start, prev_end) != (current_character, start, end): - return prev_character, prev_start, prev_end - prev_offset -= 1 - - return "", 0, 0 - - @staticmethod - def iter_character( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> Generator[tuple[str, int, int], None, None]: - """Generator to iterate by character in obj starting with the character at offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - last_result = None - length = AXText.get_character_count(obj) - while offset < length: - character, start, end = AXText.get_character_at_offset(obj, offset) - if last_result is None and not character: - return - if character and (character, start, end) != last_result: - yield character, start, end - offset = max(end, offset + 1) - last_result = character, start, end - - @staticmethod - def get_word_at_offset( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the (word, start, end) for the current or specified offset.""" - - length = AXText.get_character_count(obj) - if not length: - return "", 0, 0 - - if offset is None: - offset = AXText.get_caret_offset(obj) - - offset = min(max(0, offset), length - 1) - try: - result = Atspi.Text.get_string_at_offset(obj, offset, Atspi.TextGranularity.WORD) - except GLib.GError as error: - msg = f"AXText: Exception in get_word_at_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "", 0, 0 - - if result is None: - tokens = ["AXText: get_string_at_offset (word) failed for", obj, f"at {offset}."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return "", 0, 0 - - tokens = [f"AXText: Word at offset {offset} in", obj, - f"'{result.content}' ({result.start_offset}-{result.end_offset})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result.content, result.start_offset, result.end_offset - - @staticmethod - def get_word_at_point(obj: Atspi.Accessible, x: int, y: int) -> tuple[str, int, int]: - """Returns the (word, start, end) at the specified point.""" - - offset = AXText.get_offset_at_point(obj, x, y) - if not 0 <= offset < AXText.get_character_count(obj): - return "", 0, 0 - - return AXText.get_word_at_offset(obj, offset) - - @staticmethod - def get_next_word( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the next (word, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_word, start, end = AXText.get_word_at_offset(obj, offset) - if not current_word: - return "", 0, 0 - - length = AXText.get_character_count(obj) - next_offset = max(end, offset + 1) - - while next_offset < length: - next_word, next_start, next_end = AXText.get_word_at_offset(obj, next_offset) - if (next_word, next_start, next_end) != (current_word, start, end): - return next_word, next_start, next_end - next_offset += 1 - - return "", 0, 0 - - @staticmethod - def get_previous_word( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the previous (word, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_word, start, end = AXText.get_word_at_offset(obj, offset) - if not current_word: - return "", 0, 0 - - if start <= 0: - return "", 0, 0 - - prev_offset = start - 1 - - while prev_offset >= 0: - prev_word, prev_start, prev_end = AXText.get_word_at_offset(obj, prev_offset) - if (prev_word, prev_start, prev_end) != (current_word, start, end): - return prev_word, prev_start, prev_end - prev_offset -= 1 - - return "", 0, 0 - - @staticmethod - def iter_word( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> Generator[tuple[str, int, int], None, None]: - """Generator to iterate by word in obj starting with the word at offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - last_result = None - length = AXText.get_character_count(obj) - while offset < length: - word, start, end = AXText.get_word_at_offset(obj, offset) - if last_result is None and not word: - return - if word and (word, start, end) != last_result: - yield word, start, end - offset = max(end, offset + 1) - last_result = word, start, end - - @staticmethod - def get_line_at_offset( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the (line, start, end) for the current or specified offset.""" - - length = AXText.get_character_count(obj) - if not length: - return "", 0, 0 - - if offset is None: - offset = AXText.get_caret_offset(obj) - - # Don't adjust the length in multiline text because we want to say "blank" at the end. - # This may or may not be sufficient. GTK3 seems to give us the correct, empty line. But - # (at least) Chromium does not. See comment below. - if not AXUtilitiesState.is_multi_line(obj) \ - and not AXUtilitiesRole.is_paragraph(obj) and not AXUtilitiesRole.is_section(obj): - offset = min(max(0, offset), length - 1) - else: - offset = max(0, offset) - - try: - result = Atspi.Text.get_string_at_offset(obj, offset, Atspi.TextGranularity.LINE) - except GLib.GError as error: - msg = f"AXText: Exception in get_line_at_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "", 0, 0 - - if result is None: - tokens = ["AXText: get_string_at_offset (line) failed for", obj, f"at {offset}."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return "", 0, 0 - - # Try again, e.g. Chromium returns "", -1, -1. - if result.start_offset == result.end_offset == -1 and offset == length: - offset -= 1 - result = Atspi.Text.get_string_at_offset(obj, offset, Atspi.TextGranularity.LINE) - - debug_string = result.content.replace("\n", "\\n") - tokens = [f"AXText: Line at offset {offset} in", obj, - f"'{debug_string}' ({result.start_offset}-{result.end_offset})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if 0 <= offset < result.start_offset: - offset -= 1 - msg = f"ERROR: Start offset is greater than offset. Trying with offset {offset}" - debug.print_message(debug.LEVEL_INFO, msg, True) - result = Atspi.Text.get_string_at_offset(obj, offset, Atspi.TextGranularity.LINE) - - debug_string = result.content.replace("\n", "\\n") - tokens = [f"AXText: Line at offset {offset} in", obj, - f"'{debug_string}' ({result.start_offset}-{result.end_offset})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return result.content, result.start_offset, result.end_offset - - @staticmethod - def get_line_at_point(obj: Atspi.Accessible, x: int, y: int) -> tuple[str, int, int]: - """Returns the (line, start, end) at the specified point.""" - - offset = AXText.get_offset_at_point(obj, x, y) - if not 0 <= offset < AXText.get_character_count(obj): - return "", 0, 0 - - return AXText.get_line_at_offset(obj, offset) - - @staticmethod - def get_next_line( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the next (line, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_line, start, end = AXText.get_line_at_offset(obj, offset) - if not current_line: - return "", 0, 0 - - length = AXText.get_character_count(obj) - next_offset = max(end, offset + 1) - - while next_offset < length: - next_line, next_start, next_end = AXText.get_line_at_offset(obj, next_offset) - if (next_line, next_start, next_end) != (current_line, start, end): - return next_line, next_start, next_end - next_offset += 1 - - return "", 0, 0 - - @staticmethod - def get_previous_line( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the previous (line, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_line, start, end = AXText.get_line_at_offset(obj, offset) - if not current_line and offset == AXText.get_character_count(obj): - current_line, start, end = AXText.get_line_at_offset(obj, offset - 1) - if current_line.endswith("\n"): - start = offset - 1 - - if not current_line or start <= 0: - return "", 0, 0 - - prev_offset = start - 1 - - while prev_offset >= 0: - prev_line, prev_start, prev_end = AXText.get_line_at_offset(obj, prev_offset) - if (prev_line, prev_start, prev_end) != (current_line, start, end): - return prev_line, prev_start, prev_end - prev_offset -= 1 - - return "", 0, 0 - - @staticmethod - def iter_line( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> Generator[tuple[str, int, int], None, None]: - """Generator to iterate by line in obj starting with the line at offset.""" - - line, start, end = AXText.get_line_at_offset(obj, offset) - if not line: - return - - # If the caller provides an offset positioned at the end boundary of the - # current line (e.g. start iteration from the previous line's end), some - # implementations of Atspi return the same line again for that offset. - # To avoid yielding duplicates (e.g. in get_visible_lines()), only yield - # the current line when the offset points inside it; otherwise start with - # the next distinct line. - if offset is None or offset < end: - yield line, start, end - current_start = start - - while True: - next_line, next_start, next_end = AXText.get_next_line(obj, current_start) - if not next_line or next_start <= current_start: - break - yield next_line, next_start, next_end - current_start = next_start - - @staticmethod - def _find_sentence_boundaries(text: str) -> list[int]: - """Returns the offsets in text that should be treated as sentence beginnings.""" - - if not text: - return [] - - boundaries = [0] - pattern = r"[.!?]+(?=\s|\ufffc|$)" - for match in re.finditer(pattern, text): - end_pos = match.end() - # Skip whitespace to find start of next sentence. Do not skip embedded object - # characters since they represent child objects that must be traversed. - while end_pos < len(text) and text[end_pos].isspace(): - end_pos += 1 - # Only add boundary if we haven't reached the end and it's not a duplicate. - if end_pos < len(text) and end_pos not in boundaries: - boundaries.append(end_pos) - - if boundaries[-1] != len(text): - boundaries.append(len(text)) - - return boundaries - - @staticmethod - def has_sentence_ending(text: str) -> bool: - """Check if text contains a sentence ending.""" - - return bool(text and re.search(r"\S[.!?]+(\s|\ufffc|$)", text)) - - @staticmethod - def _get_sentence_at_offset_fallback( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Fallback sentence detection for broken implementations.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - text = AXText.get_all_text(obj) - if not text or offset < 0 or offset >= len(text): - return "", 0, 0 - - fallback_text, fallback_start, fallback_end = text, 0, len(text) - boundaries = AXText._find_sentence_boundaries(text) - for i in range(len(boundaries) - 1): - start, end = boundaries[i], boundaries[i + 1] - if start <= offset < end: - fallback_text, fallback_start, fallback_end = text[start:end], start, end - break - - tokens = ["AXText: Fallback sentence in", obj, - f" at offset {offset}: '{fallback_text}' ({fallback_start}-{fallback_end})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return fallback_text, fallback_start, fallback_end - - @staticmethod - def get_sentence_at_offset( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the (sentence, start, end) for the current or specified offset.""" - - length = AXText.get_character_count(obj) - if not length: - return "", 0, 0 - - if offset is None: - offset = AXText.get_caret_offset(obj) - - offset = min(max(0, offset), length - 1) - try: - result = Atspi.Text.get_string_at_offset(obj, offset, Atspi.TextGranularity.SENTENCE) - except GLib.GError as error: - msg = f"AXText: Exception in get_sentence_at_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return AXText._get_sentence_at_offset_fallback(obj, offset) - - if result is None: - tokens = ["AXText: get_string_at_offset (sentence) failed for", obj, f"at {offset}."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return "", 0, 0 - - if result.start_offset == result.end_offset == -1 or not result.content: - return AXText._get_sentence_at_offset_fallback(obj, offset) - - if (result.start_offset == result.end_offset and - result.start_offset in [0, -1] and not result.content): - return AXText._get_sentence_at_offset_fallback(obj, offset) - - tokens = [f"AXText: Sentence at offset {offset} in", obj, - f"'{result.content}' ({result.start_offset}-{result.end_offset})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result.content, result.start_offset, result.end_offset - - @staticmethod - def get_sentence_at_point(obj: Atspi.Accessible, x: int, y: int) -> tuple[str, int, int]: - """Returns the (sentence, start, end) at the specified point.""" - - offset = AXText.get_offset_at_point(obj, x, y) - if not 0 <= offset < AXText.get_character_count(obj): - return "", 0, 0 - - return AXText.get_sentence_at_offset(obj, offset) - - @staticmethod - def get_next_sentence( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the next (sentence, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_sentence, start, end = AXText.get_sentence_at_offset(obj, offset) - if not current_sentence: - return "", 0, 0 - - length = AXText.get_character_count(obj) - next_offset = max(end, offset + 1) - - while next_offset < length: - next_sentence, next_start, next_end = AXText.get_sentence_at_offset(obj, next_offset) - if (next_sentence, next_start, next_end) != (current_sentence, start, end): - return next_sentence, next_start, next_end - next_offset += 1 - - return "", 0, 0 - - @staticmethod - def get_previous_sentence( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the previous (sentence, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_sentence, start, end = AXText.get_sentence_at_offset(obj, offset) - if not current_sentence: - return "", 0, 0 - - if start <= 0: - return "", 0, 0 - - prev_offset = start - 1 - - while prev_offset >= 0: - prev_sentence, prev_start, prev_end = AXText.get_sentence_at_offset(obj, prev_offset) - if (prev_sentence, prev_start, prev_end) != (current_sentence, start, end): - return prev_sentence, prev_start, prev_end - prev_offset -= 1 - - return "", 0, 0 - - @staticmethod - def iter_sentence( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> Generator[tuple[str, int, int], None, None]: - """Generator to iterate by sentence in obj starting with the sentence at offset.""" - - sentence, start, end = AXText.get_sentence_at_offset(obj, offset) - if not sentence: - return - - # Avoid yielding a duplicate when the starting offset is exactly at the - # end boundary of the current sentence. Some implementations can return - # the same (sentence, start, end) again for that offset. - if offset is None or offset < end: - yield sentence, start, end - current_start = start - - while True: - next_sentence, next_start, next_end = AXText.get_next_sentence(obj, current_start) - if not next_sentence or next_start <= current_start: - break - yield next_sentence, next_start, next_end - current_start = next_start - - @staticmethod - def get_paragraph_at_offset( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the (paragraph, start, end) for the current or specified offset.""" - - length = AXText.get_character_count(obj) - if not length: - return "", 0, 0 - - if offset is None: - offset = AXText.get_caret_offset(obj) - - offset = min(max(0, offset), length - 1) - try: - result = Atspi.Text.get_string_at_offset(obj, offset, Atspi.TextGranularity.PARAGRAPH) - except GLib.GError as error: - msg = f"AXText: Exception in get_paragraph_at_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "", 0, 0 - - if result is None: - tokens = ["AXText: get_string_at_offset (paragraph) failed for", obj, f"at {offset}."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return "", 0, 0 - - tokens = [f"AXText: Paragraph at offset {offset} in", obj, - f"'{result.content}' ({result.start_offset}-{result.end_offset})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result.content, result.start_offset, result.end_offset - - @staticmethod - def get_paragraph_at_point(obj: Atspi.Accessible, x: int, y: int) -> tuple[str, int, int]: - """Returns the (paragraph, start, end) at the specified point.""" - - offset = AXText.get_offset_at_point(obj, x, y) - if not 0 <= offset < AXText.get_character_count(obj): - return "", 0, 0 - - return AXText.get_paragraph_at_offset(obj, offset) - - @staticmethod - def get_next_paragraph( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the next (paragraph, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_paragraph, start, end = AXText.get_paragraph_at_offset(obj, offset) - if not current_paragraph: - return "", 0, 0 - - length = AXText.get_character_count(obj) - next_offset = max(end, offset + 1) - - while next_offset < length: - next_paragraph, next_start, next_end = AXText.get_paragraph_at_offset(obj, next_offset) - if (next_paragraph, next_start, next_end) != (current_paragraph, start, end): - return next_paragraph, next_start, next_end - next_offset += 1 - - return "", 0, 0 - - @staticmethod - def get_previous_paragraph( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[str, int, int]: - """Returns the previous (paragraph, start, end) for the current or specified offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - current_paragraph, start, end = AXText.get_paragraph_at_offset(obj, offset) - if not current_paragraph: - return "", 0, 0 - - if start <= 0: - return "", 0, 0 - - prev_offset = start - 1 - - while prev_offset >= 0: - prev_paragraph, prev_start, prev_end = AXText.get_paragraph_at_offset(obj, prev_offset) - if (prev_paragraph, prev_start, prev_end) != (current_paragraph, start, end): - return prev_paragraph, prev_start, prev_end - prev_offset -= 1 - - return "", 0, 0 - - @staticmethod - def iter_paragraph( - obj: Atspi.Accessible, offset: Optional[int] = None - ) -> Generator[tuple[str, int, int], None, None]: - """Generator to iterate by paragraph in obj starting with the paragraph at offset.""" - - if offset is None: - offset = AXText.get_caret_offset(obj) - - last_result = None - length = AXText.get_character_count(obj) - while offset < length: - paragraph, start, end = AXText.get_paragraph_at_offset(obj, offset) - if last_result is None and not paragraph: - return - if paragraph and (paragraph, start, end) != last_result: - yield paragraph, start, end - offset = max(end, offset + 1) - last_result = paragraph, start, end - - @staticmethod - def supports_paragraph_iteration(obj: Atspi.Accessible) -> bool: - """Returns True if paragraph iteration is supported on obj.""" - - if not AXObject.supports_text(obj): - return False - - string, start, end = AXText.get_paragraph_at_offset(obj, 0) - result = string and 0 <= start < end - tokens = ["AXText: Paragraph iteration supported on", obj, f": {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return bool(result) - - @staticmethod - def get_character_count(obj: Atspi.Accessible) -> int: - """Returns the character count of obj.""" - - if not AXObject.supports_text(obj): - return 0 - - try: - count = Atspi.Text.get_character_count(obj) - except GLib.GError as error: - msg = f"AXText: Exception in get_character_count: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0 - - tokens = ["AXText:", obj, f"reports {count} characters."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return count - - @staticmethod - def get_caret_offset(obj: Atspi.Accessible) -> int: - """Returns the caret offset of obj.""" - - if not AXObject.supports_text(obj): - return -1 - - try: - offset = Atspi.Text.get_caret_offset(obj) - except GLib.GError as error: - msg = f"AXText: Exception in get_caret_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1 - - tokens = ["AXText:", obj, f"reports caret offset of {offset}."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return offset - - @staticmethod - def set_caret_offset(obj: Atspi.Accessible, offset: int) -> bool: - """Returns False if we definitely failed to set the offset. True cannot be trusted.""" - - if not AXObject.supports_text(obj): - return False - - try: - result = Atspi.Text.set_caret_offset(obj, offset) - except GLib.GError as error: - msg = f"AXText: Exception in set_caret_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - tokens = [f"AXText: Reported result of setting offset to {offset} in", obj, f": {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def set_caret_offset_to_start(obj: Atspi.Accessible) -> bool: - """Returns False if we definitely failed to set the offset. True cannot be trusted.""" - - return AXText.set_caret_offset(obj, 0) - - @staticmethod - def set_caret_offset_to_end(obj: Atspi.Accessible) -> bool: - """Returns False if we definitely failed to set the offset. True cannot be trusted.""" - - return AXText.set_caret_offset(obj, AXText.get_character_count(obj)) - - @staticmethod - def get_substring(obj: Atspi.Accessible, start_offset: int, end_offset: int) -> str: - """Returns the text of obj within the specified offsets.""" - - if not AXObject.supports_text(obj): - return "" - - if end_offset == -1: - end_offset = AXText.get_character_count(obj) - - try: - result = Atspi.Text.get_text(obj, start_offset, end_offset) - except GLib.GError as error: - msg = f"AXText: Exception in get_substring: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "" - - debug_string = result.replace("\n", "\\n") - tokens = ["AXText: Text of", obj, f"({start_offset}-{end_offset}): '{debug_string}'"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_all_text(obj: Atspi.Accessible) -> str: - """Returns the text content of obj.""" - - length = AXText.get_character_count(obj) - if not length: - return "" - - try: - result = Atspi.Text.get_text(obj, 0, length) - except GLib.GError as error: - msg = f"AXText: Exception in get_all_text: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "" - - words = result.split() - if len(words) > 20: - debug_string = f"{' '.join(words[:5])} ... {' '.join(words[-5:])}" - else: - debug_string = result - - debug_string = debug_string.replace("\n", "\\n") - tokens = ["AXText: Text of", obj, f"'{debug_string}'"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def _get_n_selections(obj: Atspi.Accessible) -> int: - """Returns the number of reported selected substrings in obj.""" - - if not AXObject.supports_text(obj): - return 0 - - try: - result = Atspi.Text.get_n_selections(obj) - except GLib.GError as error: - msg = f"AXText: Exception in _get_n_selections: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0 - - tokens = ["AXText:", obj, f"reports {result} selection(s)."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def _remove_selection(obj: Atspi.Accessible, selection_number: int) -> None: - """Attempts to remove the specified selection.""" - - if not AXObject.supports_text(obj): - return - - try: - Atspi.Text.remove_selection(obj, selection_number) - except GLib.GError as error: - msg = f"AXText: Exception in _remove_selection: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - @staticmethod - def has_selected_text(obj: Atspi.Accessible) -> bool: - """Returns True if obj has selected text.""" - - return bool(AXText.get_selected_ranges(obj)) - - @staticmethod - def is_all_text_selected(obj: Atspi.Accessible) -> bool: - """Returns True of all the text in obj is selected.""" - - length = AXText.get_character_count(obj) - if not length: - return False - - ranges = AXText.get_selected_ranges(obj) - if not ranges: - return False - - return ranges[0][0] == 0 and ranges[-1][1] == length - - @staticmethod - def clear_all_selected_text(obj: Atspi.Accessible) -> None: - """Attempts to clear the selected text.""" - - for i in range(AXText._get_n_selections(obj)): - AXText._remove_selection(obj, i) - - @staticmethod - def get_selection_start_offset(obj: Atspi.Accessible) -> int: - """Returns the leftmost offset of the selected text.""" - - ranges = AXText.get_selected_ranges(obj) - if ranges: - return ranges[0][0] - - return -1 - - @staticmethod - def get_selection_end_offset(obj: Atspi.Accessible) -> int: - """Returns the rightmost offset of the selected text.""" - - ranges = AXText.get_selected_ranges(obj) - if ranges: - return ranges[-1][1] - - return -1 - - @staticmethod - def get_selected_ranges(obj: Atspi.Accessible) -> list[tuple[int, int]]: - """Returns a list of (start_offset, end_offset) tuples reflecting the selected text.""" - - count = AXText._get_n_selections(obj) - if not count: - return [] - - selections = [] - for i in range(count): - try: - result = Atspi.Text.get_selection(obj, i) - except GLib.GError as error: - msg = f"AXText: Exception in get_selected_ranges: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - break - if 0 <= result.start_offset < result.end_offset: - selections.append((result.start_offset, result.end_offset)) - - tokens = ["AXText:", obj, f"reports selected ranges: {selections}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return selections - - @staticmethod - def get_cached_selected_text(obj: Atspi.Accessible) -> tuple[str, int, int]: - """Returns the last known selected string, start, and end for obj.""" - - string, start, end = AXText.CACHED_TEXT_SELECTION.get(hash(obj), ("", 0, 0)) - debug_string = string.replace("\n", "\\n") - tokens = ["AXText: Cached selection for", obj, f"is '{debug_string}' ({start}, {end})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return string, start, end - - @staticmethod - def update_cached_selected_text(obj: Atspi.Accessible) -> None: - """Updates the last known selected string, start, and end for obj.""" - - AXText.CACHED_TEXT_SELECTION[hash(obj)] = AXText.get_selected_text(obj) - - @staticmethod - def get_selected_text(obj: Atspi.Accessible) -> tuple[str, int, int]: - """Returns the selected string, start, and end for obj.""" - - selections = AXText.get_selected_ranges(obj) - if not selections: - return "", 0, 0 - - strings = [] - start_offset = -1 - end_offset = -1 - for selection in sorted(set(selections)): - strings.append(AXText.get_substring(obj, *selection)) - end_offset = selection[1] - if start_offset == -1: - start_offset = selection[0] - - text = " ".join(strings) - words = text.split() - if len(words) > 20: - debug_string = f"{' '.join(words[:5])} ... {' '.join(words[-5:])}" - else: - debug_string = text - - tokens = ["AXText: Selected text of", obj, - f"'{debug_string}' ({start_offset}-{end_offset})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return text, start_offset, end_offset - - @staticmethod - def _add_new_selection(obj: Atspi.Accessible, start_offset: int, end_offset: int) -> bool: - """Creates a new selection for the specified range in obj.""" - - if not AXObject.supports_text(obj): - return False - - try: - result = Atspi.Text.add_selection(obj, start_offset, end_offset) - except GLib.GError as error: - msg = f"AXText: Exception in _add_selection: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - return result - - @staticmethod - def _update_existing_selection( - obj: Atspi.Accessible, - start_offset: int, - end_offset: int, - selection_number: int = 0 - ) -> bool: - """Modifies specified selection in obj to the specified range.""" - - if not AXObject.supports_text(obj): - return False - - try: - result = Atspi.Text.set_selection(obj, selection_number, start_offset, end_offset) - except GLib.GError as error: - msg = f"AXText: Exception in set_selected_text: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - return result - - @staticmethod - def set_selected_text(obj: Atspi.Accessible, start_offset: int, end_offset: int) -> bool: - """Returns False if we definitely failed to set the selection. True cannot be trusted.""" - - # TODO - JD: For now we always assume and operate on the first selection. - # This preserves the original functionality prior to the refactor. But whether - # that functionality is what it should be needs investigation. - if AXText._get_n_selections(obj) > 0: - result = AXText._update_existing_selection(obj, start_offset, end_offset) - else: - result = AXText._add_new_selection(obj, start_offset, end_offset) - - if result and debug.LEVEL_INFO >= debug.debugLevel: - substring = AXText.get_substring(obj, start_offset, end_offset) - selection = AXText.get_selected_text(obj)[0] - if substring != selection: - msg = "AXText: Substring and selected text do not match." - debug.print_message(debug.LEVEL_INFO, msg, True) - - return result - - # TODO - JD: This should be converted to return AXTextAttribute values. - @staticmethod - def get_text_attributes_at_offset( - obj: Atspi.Accessible, - offset: Optional[int] = None - ) -> tuple[dict[str, str], int, int]: - """Returns a (dict, start, end) tuple for attributes at offset in obj.""" - - if not AXObject.supports_text(obj): - return {}, 0, 0 - - if offset is None: - offset = AXText.get_caret_offset(obj) - - try: - result = Atspi.Text.get_attribute_run(obj, offset, include_defaults=True) - except GLib.GError as error: - msg = f"AXText: Exception in get_text_attributes_at_offset: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return {}, 0, AXText.get_character_count(obj) - - if result is None: - tokens = ["AXText: get_attribute_run failed for", obj, f"at offset {offset}."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return {}, 0, AXText.get_character_count(obj) - - tokens = ["AXText: Attributes for", obj, f"at offset {offset} : {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - # Adjust for web browsers that report indentation and justification at object attributes - # rather than text attributes. - obj_attributes = AXObject.get_attributes_dict(obj, False) - if not result[0].get("justification"): - alternative = obj_attributes.get("text-align") - if alternative: - result[0]["justification"] = alternative - if not result[0].get("indent"): - alternative = obj_attributes.get("text-indent") - if alternative: - result[0]["indent"] = alternative - - return result[0] or {}, result[1] or 0, result[2] or AXText.get_character_count(obj) - - @staticmethod - def get_all_text_attributes( - obj: Atspi.Accessible, - start_offset: int = 0, - end_offset: int = -1 - ) -> list[tuple[int, int, dict[str, str]]]: - """Returns a list of (start, end, attrs dict) tuples for obj.""" - - if not AXObject.supports_text(obj): - return [] - - if end_offset == -1: - end_offset = AXText.get_character_count(obj) - - tokens = ["AXText: Getting attributes for", obj, f"chars: {start_offset}-{end_offset}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - rv = [] - offset = start_offset - while offset < end_offset: - attrs, start, end = AXText.get_text_attributes_at_offset(obj, offset) - if start <= end: - rv.append((max(start, offset), end, attrs)) - else: - # TODO - JD: We're sometimes seeing this from WebKit, e.g. in Evo gitlab messages. - msg = f"AXText: Start offset {start} > end offset {end}" - debug.print_message(debug.LEVEL_INFO, msg, True) - offset = max(end, offset + 1) - - msg = f"AXText: {len(rv)} attribute ranges found." - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - @staticmethod - def get_all_supported_text_attributes() -> list[AXTextAttribute]: - """Returns a set of all supported text attribute names.""" - - return list(AXTextAttribute) - - @staticmethod - def get_offset_at_point(obj: Atspi.Accessible, x: int, y: int) -> int: - """Returns the character offset in obj at the specified point.""" - - if not AXObject.supports_text(obj): - return -1 - - try: - offset = Atspi.Text.get_offset_at_point(obj, x, y, Atspi.CoordType.WINDOW) - except GLib.GError as error: - msg = f"AXText: Exception in get_offset_at_point: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1 - - tokens = ["AXText: Offset in", obj, f"at {x}, {y} is {offset}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return offset - - @staticmethod - def get_character_rect(obj: Atspi.Accessible, offset: Optional[int] = None) -> Atspi.Rect: - """Returns the Atspi rect of the character at the specified offset in obj.""" - - if not AXObject.supports_text(obj): - return Atspi.Rect() - - if offset is None: - offset = AXText.get_caret_offset(obj) - - try: - rect = Atspi.Text.get_character_extents(obj, offset, Atspi.CoordType.WINDOW) - except GLib.GError as error: - msg = f"AXText: Exception in get_character_rect: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return Atspi.Rect() - - tokens = [f"AXText: Offset {offset} in", obj, "has rect", rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return rect - - @staticmethod - def get_range_rect(obj: Atspi.Accessible, start: int, end: int) -> Atspi.Rect: - """Returns the Atspi rect of the string at the specified range in obj.""" - - if not AXObject.supports_text(obj): - return Atspi.Rect() - - if end <= 0: - end = AXText.get_character_count(obj) - - try: - rect = Atspi.Text.get_range_extents(obj, start, end, Atspi.CoordType.WINDOW) - except GLib.GError as error: - msg = f"AXText: Exception in get_range_rect: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return Atspi.Rect() - - tokens = [f"AXText: Range {start}-{end} in", obj, "has rect", rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return rect - - @staticmethod - def _rect_is_fully_contained_in(rect1: Atspi.Rect, rect2: Atspi.Rect) -> bool: - """Returns true if rect1 is fully contained in rect2""" - - return rect2.x <= rect1.x and rect2.y <= rect1.y \ - and rect2.x + rect2.width >= rect1.x + rect1.width \ - and rect2.y + rect2.height >= rect1.y + rect1.height - - @staticmethod - def _line_comparison(line_rect: Atspi.Rect, clip_rect: Atspi.Rect) -> int: - """Returns -1 (line above), 1 (line below), or 0 (line inside) clip_rect.""" - - # https://gitlab.gnome.org/GNOME/gtk/-/issues/6419 - clip_rect.y = max(0, clip_rect.y) - - if line_rect.y + line_rect.height / 2 < clip_rect.y: - return -1 - - if line_rect.y + line_rect.height / 2 > clip_rect.y + clip_rect.height: - return 1 - - return 0 - - @staticmethod - def get_visible_lines( - obj: Atspi.Accessible, - clip_rect: Atspi.Rect - ) -> list[tuple[str, int, int]]: - """Returns a list of (string, start, end) for lines of obj inside clip_rect.""" - - tokens = ["AXText: Getting visible lines for", obj, "inside", clip_rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - line, start, end = AXText.find_first_visible_line(obj, clip_rect) - debug_string = line.replace("\n", "\\n") - tokens = ["AXText: First visible line in", obj, f"is: '{debug_string}' ({start}-{end})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - result = [(line, start, end)] - offset = end - for line, start, end in AXText.iter_line(obj, offset): - line_rect = AXText.get_range_rect(obj, start, end) - if AXText._line_comparison(line_rect, clip_rect) > 0: - break - result.append((line, start, end)) - - line, start, end = result[-1] - debug_string = line.replace("\n", "\\n") - tokens = ["AXText: Last visible line in", obj, f"is: '{debug_string}' ({start}-{end})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def find_first_visible_line( - obj: Atspi.Accessible, - clip_rect: Atspi.Rect - ) -> tuple[str, int, int]: - """Returns the first (string, start, end) visible line of obj inside clip_rect.""" - - result = "", 0, 0 - length = AXText.get_character_count(obj) - low, high = 0, length - while low < high: - mid = (low + high) // 2 - line, start, end = AXText.get_line_at_offset(obj, mid) - if start == 0: - return line, start, end - - if start < 0: - tokens = ["AXText: Treating invalid offset as above", clip_rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - low = mid + 1 - continue - - result = line, start, end - previous_line, previous_start, previous_end = AXText.get_line_at_offset(obj, start - 1) - if previous_start <= 0 and previous_end <= 0: - return result - - text_rect = AXText.get_range_rect(obj, start, end) - if AXText._line_comparison(text_rect, clip_rect) < 0: - low = mid + 1 - continue - - if AXText._line_comparison(text_rect, clip_rect) > 0: - high = mid - continue - - previous_rect = AXText.get_range_rect(obj, previous_start, previous_end) - if AXText._line_comparison(previous_rect, clip_rect) != 0: - return result - - result = previous_line, previous_start, previous_end - high = mid - - return result - - @staticmethod - def find_last_visible_line( - obj: Atspi.Accessible, - clip_rect: Atspi.Rect - ) -> tuple[str, int, int]: - """Returns the last (string, start, end) visible line of obj inside clip_rect.""" - - result = "", 0, 0 - length = AXText.get_character_count(obj) - low, high = 0, length - while low < high: - mid = (low + high) // 2 - line, start, end = AXText.get_line_at_offset(obj, mid) - if end >= length: - return line, start, end - - if end <= 0: - tokens = ["AXText: Treating invalid offset as below", clip_rect] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - high = mid - continue - - result = line, start, end - next_line, next_start, next_end = AXText.get_line_at_offset(obj, end) - if next_start <= 0 and next_end <= 0: - return result - - text_rect = AXText.get_range_rect(obj, start, end) - if AXText._line_comparison(text_rect, clip_rect) < 0: - low = mid + 1 - continue - - if AXText._line_comparison(text_rect, clip_rect) > 0: - high = mid - continue - - next_rect = AXText.get_range_rect(obj, next_start, next_end) - if AXText._line_comparison(next_rect, clip_rect) != 0: - return result - - result = next_line, next_start, next_end - low = mid + 1 - - return result - - @staticmethod - def string_has_spelling_error(obj: Atspi.Accessible, offset: Optional[int] = None) -> bool: - """Returns True if the text attributes indicate a spelling error.""" - - attributes = AXText.get_text_attributes_at_offset(obj, offset)[0] - if attributes.get("invalid") == "spelling": - return True - if attributes.get("invalid") == "grammar": - return False - if attributes.get("text-spelling") == "misspelled": - return True - if attributes.get("underline") in ["error", "spelling"]: - return True - return False - - @staticmethod - def string_has_grammar_error(obj: Atspi.Accessible, offset: Optional[int] = None) -> bool: - """Returns True if the text attributes indicate a grammar error.""" - - attributes = AXText.get_text_attributes_at_offset(obj, offset)[0] - if attributes.get("invalid") == "grammar": - return True - if attributes.get("underline") == "grammar": - return True - return False - - @staticmethod - def is_eoc(character: str) -> bool: - """Returns True if character is an embedded object character (\ufffc).""" - - return character == "\ufffc" - - @staticmethod - def character_at_offset_is_eoc(obj: Atspi.Accessible, offset: int) -> bool: - """Returns True if character in obj is an embedded object character (\ufffc).""" - - character, _start, _end = AXText.get_character_at_offset(obj, offset) - return AXText.is_eoc(character) - - @staticmethod - def is_whitespace_or_empty(obj: Atspi.Accessible) -> bool: - """Returns True if obj lacks text, or contains only whitespace.""" - - if not AXObject.supports_text(obj): - return True - - return not AXText.get_all_text(obj).strip() - - @staticmethod - def has_presentable_text(obj: Atspi.Accessible) -> bool: - """Returns True if obj has presentable text.""" - - if not AXObject.supports_text(obj): - return False - - text = AXText.get_all_text(obj).strip() - if not text: - return AXUtilitiesRole.is_paragraph(obj) - - return bool(re.search(r"\w+", text)) - - @staticmethod - def scroll_substring_to_point( - obj: Atspi.Accessible, - x: int, - y: int, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> bool: - """Attempts to scroll obj to the specified point.""" - - length = AXText.get_character_count(obj) - if not length: - return False - - if start_offset is None: - start_offset = 0 - if end_offset is None: - end_offset = length - 1 - - try: - result = Atspi.Text.scroll_substring_to_point( - obj, start_offset, end_offset, Atspi.CoordType.WINDOW, x, y) - except GLib.GError as error: - msg = f"AXText: Exception in scroll_substring_to_point: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - tokens = ["AXText: Scrolled", obj, f"substring ({start_offset}-{end_offset}) to", - f"{x}, {y}: {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def scroll_substring_to_location( - obj: Atspi.Accessible, - location: Atspi.ScrollType, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None - ) -> bool: - """Attempts to scroll the substring to the specified Atspi.ScrollType location.""" - - length = AXText.get_character_count(obj) - if not length: - return False - - if start_offset is None: - start_offset = 0 - if end_offset is None: - end_offset = length - 1 - - try: - result = Atspi.Text.scroll_substring_to(obj, start_offset, end_offset, location) - except GLib.GError as error: - msg = f"AXText: Exception in scroll_substring_to_location: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - tokens = ["AXText: Scrolled", obj, f"substring ({start_offset}-{end_offset}) to", - location, f": {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result diff --git a/src/cthulhu/ax_utilities.py b/src/cthulhu/ax_utilities.py deleted file mode 100644 index 77498e4..0000000 --- a/src/cthulhu/ax_utilities.py +++ /dev/null @@ -1,999 +0,0 @@ -# Utilities for performing tasks related to accessibility inspection. -# -# Copyright 2023-2025 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=too-many-branches -# pylint: disable=too-many-public-methods -# pylint: disable=too-many-return-statements -# pylint: disable=too-many-statements -# pylint: disable=wrong-import-position - -"""Utilities for performing tasks related to accessibility inspection.""" - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023-2025 Igalia, S.L." -__license__ = "LGPL" - -from typing import Optional -import functools -import inspect -import queue -import threading -import time - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import debug -from .ax_component import AXComponent -from .ax_object import AXObject -from .ax_selection import AXSelection -from .ax_table import AXTable -from .ax_text import AXText -from .ax_utilities_application import AXUtilitiesApplication -from .ax_utilities_collection import AXUtilitiesCollection -from .ax_utilities_event import AXUtilitiesEvent -from .ax_utilities_relation import AXUtilitiesRelation -from .ax_utilities_role import AXUtilitiesRole -from .ax_utilities_state import AXUtilitiesState - - -class AXUtilities: - """Utilities for performing tasks related to accessibility inspection.""" - - COMPARE_COLLECTION_PERFORMANCE = False - - # Things we cache. - SET_MEMBERS: dict[int, list[Atspi.Accessible]] = {} - IS_LAYOUT_ONLY: dict[int, tuple[bool, str]] = {} - - _lock = threading.Lock() - - @staticmethod - def start_cache_clearing_thread() -> None: - """Starts thread to periodically clear cached details.""" - - thread = threading.Thread(target=AXUtilities._clear_stored_data) - thread.daemon = True - thread.start() - - @staticmethod - def _clear_stored_data() -> None: - """Clears any data we have cached for objects""" - - while True: - time.sleep(60) - AXUtilities._clear_all_dictionaries() - - @staticmethod - def _clear_all_dictionaries(reason: str = "") -> None: - msg = "AXUtilities: Clearing cache." - if reason: - msg += f" Reason: {reason}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - with AXUtilities._lock: - AXUtilities.SET_MEMBERS.clear() - AXUtilities.IS_LAYOUT_ONLY.clear() - - @staticmethod - def clear_all_cache_now(obj: Optional[Atspi.Accessible] = None, reason: str = "") -> None: - """Clears all cached information immediately.""" - - AXUtilities._clear_all_dictionaries(reason) - AXObject.clear_cache_now(reason) - AXUtilitiesRelation.clear_cache_now(reason) - AXUtilitiesEvent.clear_cache_now(reason) - if AXUtilitiesRole.is_table_related(obj): - AXTable.clear_cache_now(reason) - - @staticmethod - def can_be_active_window(window: Atspi.Accessible, clear_cache: bool = True) -> bool: - """Returns True if window can be the active window based on its state.""" - - if window is None: - return False - - if clear_cache: - AXObject.clear_cache(window, False, "Checking if window can be the active window") - app = AXUtilitiesApplication.get_application(window) - tokens = ["AXUtilities:", window, "from", app] - - if not AXUtilitiesState.is_active(window): - tokens.append("lacks active state") - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if not AXUtilitiesState.is_showing(window): - tokens.append("lacks showing state") - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if not AXUtilitiesState.is_visible(window): - tokens.append("lacks visible state") - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if AXUtilitiesState.is_iconified(window): - tokens.append("is iconified") - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if AXObject.get_name(app) == "mutter-x11-frames": - tokens.append("is from app that cannot have the real active window") - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if app and not AXUtilitiesApplication.is_application_in_desktop(app): - tokens.append("is from app unknown to AT-SPI2") - # Firefox alerts and dialogs suffer from this bug too, but if we ignore these windows - # we'll fail to fully present things like the file chooser dialog and the replace-file - # alert. https://bugzilla.mozilla.org/show_bug.cgi?id=1882794 - if not AXUtilitiesRole.is_dialog_or_alert(window): - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens.append("can be active window") - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - @staticmethod - def find_active_window() -> Optional[Atspi.Accessible]: - """Tries to locate the active window; may or may not succeed.""" - - candidates = [] - apps = AXUtilitiesApplication.get_all_applications(must_have_window=True) - for app in apps: - candidates.extend(list(AXObject.iter_children(app, AXUtilities.can_be_active_window))) - - if not candidates: - tokens = ["AXUtilities: Unable to find active window from", apps] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - if len(candidates) == 1: - tokens = ["AXUtilities: Active window is", candidates[0]] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return candidates[0] - - tokens = ["AXUtilities: These windows all claim to be active:", candidates] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - focused_candidates = [] - for frame in candidates: - if AXUtilitiesState.is_focused(frame): - focused_candidates.append(frame) - continue - focused = AXUtilities.get_focused_object(frame) - if focused is not None: - focused_candidates.append(frame) - - if len(focused_candidates) == 1: - tokens = ["AXUtilities: Active window has focus:", focused_candidates[0]] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return focused_candidates[0] - - if not focused_candidates and len(candidates) > 1: - tokens = ["AXUtilities: No focused active window found"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - guess = focused_candidates[0] if focused_candidates else candidates[0] - tokens = ["AXUtilities: Returning", guess, "as active window"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return guess - - @staticmethod - def is_unfocused_alert_or_dialog(obj: Atspi.Accessible) -> bool: - """Returns True if obj is an unfocused alert or dialog with presentable items.""" - - if not AXUtilitiesRole.is_dialog_or_alert(obj): - return False - if not AXObject.get_child_count(obj): - return False - if not AXUtilitiesState.is_showing(obj): - return False - return not AXUtilities.can_be_active_window(obj) - - @staticmethod - def get_unfocused_alerts_and_dialogs(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of all the unfocused alerts and dialogs in the app and window of obj.""" - - app = AXUtilitiesApplication.get_application(obj) - result = list(AXObject.iter_children(app, AXUtilities.is_unfocused_alert_or_dialog)) - - frame = AXObject.find_ancestor( - obj, lambda x: AXUtilitiesRole.is_application(AXObject.get_parent(x))) - result.extend(list(AXObject.iter_children(frame, AXUtilities.is_unfocused_alert_or_dialog))) - - tokens = ["AXUtilities: Unfocused alerts and dialogs for", obj, ":", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_all_widgets( - obj: Atspi.Accessible, - must_be_showing_and_visible: bool = True, - exclude_push_button: bool = False - ) -> list[Atspi.Accessible]: - """Returns all the descendants of obj with a widget role""" - - roles = AXUtilitiesRole.get_widget_roles() - if exclude_push_button and Atspi.Role.BUTTON in roles: - roles.remove(Atspi.Role.BUTTON) - - result = None - if AXObject.supports_collection(obj): - if not must_be_showing_and_visible: - result = AXUtilitiesCollection.find_all_with_role(obj, roles) - else: - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE] - result = AXUtilitiesCollection.find_all_with_role_and_all_states( - obj, roles, states) - - if not AXUtilities.COMPARE_COLLECTION_PERFORMANCE: - return result - - def is_match(acc): - if AXObject.get_role(acc) not in roles: - return False - if must_be_showing_and_visible: - return AXUtilitiesState.is_showing(acc) and AXUtilitiesState.is_visible(acc) - return True - - return AXObject.find_all_descendants(obj, is_match) - - @staticmethod - def get_default_button(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the default button descendant of obj""" - - result = None - if AXObject.supports_collection(obj): - result = AXUtilitiesCollection.find_default_button(obj) - if not AXUtilities.COMPARE_COLLECTION_PERFORMANCE: - return result - - return AXObject.find_descendant(obj, AXUtilitiesRole.is_default_button) - - @staticmethod - def get_focused_object(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the focused descendant of obj""" - - result = None - if AXObject.supports_collection(obj): - result = AXUtilitiesCollection.find_focused_object(obj) - if not AXUtilities.COMPARE_COLLECTION_PERFORMANCE: - return result - - return AXObject.find_descendant(obj, AXUtilitiesState.is_focused) - - @staticmethod - def get_info_bar(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the info bar descendant of obj""" - - result = None - if AXObject.supports_collection(obj): - result = AXUtilitiesCollection.find_info_bar(obj) - if not AXUtilities.COMPARE_COLLECTION_PERFORMANCE: - return result - - return AXObject.find_descendant(obj, AXUtilitiesRole.is_info_bar) - - @staticmethod - def get_status_bar(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the status bar descendant of obj""" - - result = None - if AXObject.supports_collection(obj): - result = AXUtilitiesCollection.find_status_bar(obj) - if not AXUtilities.COMPARE_COLLECTION_PERFORMANCE: - return result - - return AXObject.find_descendant(obj, AXUtilitiesRole.is_status_bar) - - @staticmethod - def _is_layout_only(obj: Atspi.Accessible) -> tuple[bool, str]: - """Returns True and a string reason if obj is believed to serve only for layout.""" - - reason = "" - role = AXObject.get_role(obj) - if role in AXUtilitiesRole.get_layout_only_roles(): - return True, "has layout-only role" - - if AXUtilitiesRole.is_layered_pane(obj, role): - result = AXObject.find_ancestor(obj, AXUtilitiesRole.is_desktop_frame) is not None - if result: - reason = "is inside desktop frame" - return result, reason - - if AXUtilitiesRole.is_menu(obj, role) or AXUtilitiesRole.is_list(obj, role): - result = AXObject.find_ancestor(obj, AXUtilitiesRole.is_combo_box) is not None - if result: - reason = "is inside combo box" - return result, reason - - if AXUtilitiesRole.is_group(obj, role): - result = not AXUtilities.has_explicit_name(obj) - if result: - reason = "lacks explicit name" - return result, reason - - if AXUtilitiesRole.is_panel(obj, role) or AXUtilitiesRole.is_grouping(obj, role): - name = AXObject.get_name(obj) - description = AXObject.get_description(obj) - labelled_by = AXUtilitiesRelation.get_is_labelled_by(obj) - described_by = AXUtilitiesRelation.get_is_described_by(obj) - if not (name or description or labelled_by or described_by): - return True, "lacks name, description, and relations" - if name == AXObject.get_name(AXUtilitiesApplication.get_application(obj)): - return True, "has same name as app" - if AXObject.get_child_count(obj) == 1: - child = AXObject.get_child(obj, 0) - if name == AXObject.get_name(child): - return True, "has same name as its only child" - if not AXUtilitiesRole.is_label(child) and child in labelled_by: - return True, "is labelled by non-label only child" - set_roles = AXUtilitiesRole.get_set_container_roles() - ancestor = AXObject.find_ancestor(obj, lambda x: AXObject.get_role(x) in set_roles) - if ancestor and AXObject.get_name(ancestor) == name: - return True, "is in set container with same name" - return False, reason - - if AXUtilitiesRole.is_section(obj, role) or AXUtilitiesRole.is_document(obj, role): - if AXUtilitiesState.is_focusable(obj): - return False, "is focusable" - if AXObject.has_action(obj, "click"): - return False, "has click action" - return True, "is not interactive" - - if AXUtilitiesRole.is_tool_bar(obj): - result = AXUtilitiesRole.is_page_tab_list(AXObject.get_child(obj, 0)) - if result: - reason = "is parent of page tab list" - return result, reason - - if AXUtilitiesRole.is_table(obj, role): - result = AXTable.is_layout_table(obj) - if result: - reason = "is layout table" - return result, reason - - if AXUtilitiesRole.is_table_row(obj): - if AXUtilitiesState.is_focusable(obj): - return False, "is focusable" - if AXUtilitiesState.is_selectable(obj): - return False, "is selectable" - if AXUtilitiesState.is_expandable(obj): - return False, "is expandable" - if AXUtilities.has_explicit_name(obj): - return False, "has explicit name" - return True, "is not focusable, selectable, or expandable and lacks explicit name" - - if AXUtilitiesRole.is_table_cell(obj, role): - if AXUtilitiesRole.is_table_cell(AXObject.get_child(obj, 0)): - return True, "child of this cell is table cell" - table = AXTable.get_table(obj) - if AXUtilitiesRole.is_table(table): - result = AXTable.is_layout_table(table) - if result: - reason = "is in layout table" - return result, reason - - return False, reason - - @staticmethod - def is_layout_only(obj: Atspi.Accessible) -> bool: - """Returns True if obj is believed to serve only for layout.""" - - if hash(obj) in AXUtilities.IS_LAYOUT_ONLY: - result, reason = AXUtilities.IS_LAYOUT_ONLY.get(hash(obj), (False, "")) - else: - result, reason = AXUtilities._is_layout_only(obj) - AXUtilities.IS_LAYOUT_ONLY[hash(obj)] = result, reason - - if reason: - tokens = ["AXUtilities:", obj, f"believed to be layout only: {result}, {reason}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return result - - @staticmethod - def is_message_dialog(obj: Atspi.Accessible) -> bool: - """Returns True if obj is a dialog that should be treated as a message dialog""" - - if not AXUtilitiesRole.is_dialog_or_alert(obj): - return False - - if not AXObject.supports_collection(obj): - widgets = AXUtilities.get_all_widgets(obj, exclude_push_button=True) - return not widgets - - if AXUtilitiesCollection.has_scroll_pane(obj): - tokens = ["AXUtilities:", obj, "is not a message dialog: has scroll pane"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if AXUtilitiesCollection.has_split_pane(obj): - tokens = ["AXUtilities:", obj, "is not a message dialog: has split pane"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if AXUtilitiesCollection.has_tree_or_tree_table(obj): - tokens = ["AXUtilities:", obj, "is not a message dialog: has tree or tree table"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if AXUtilitiesCollection.has_combo_box_or_list_box(obj): - tokens = ["AXUtilities:", obj, "is not a message dialog: has combo box or list box"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if AXUtilitiesCollection.has_editable_object(obj): - tokens = ["AXUtilities:", obj, "is not a message dialog: has editable object"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["AXUtilities:", obj, "is believed to be a message dialog"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - @staticmethod - def is_redundant_object(obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> bool: - """Returns True if obj2 is redundant to obj1.""" - - if obj1 == obj2: - return False - - if AXObject.get_name(obj1) != AXObject.get_name(obj2) \ - or AXObject.get_role(obj1) != AXObject.get_role(obj2): - return False - - tokens = ["AXUtilities:", obj2, "is redundant to", obj1] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - @staticmethod - def _sort_by_child_index(object_list: list[Atspi.Accessible]) -> list[Atspi.Accessible]: - """Returns the list of objects sorted according to child index.""" - - def cmp(x, y): - return AXObject.get_index_in_parent(x) - AXObject.get_index_in_parent(y) - - if not object_list or len(object_list) == 1: - return object_list - - result = sorted(object_list, key=functools.cmp_to_key(cmp)) - - first, second = result[0:2] - if AXUtilitiesRole.is_radio_button(first) and AXObject.get_toolkit_name(first) == "gtk": - # Gtk radio buttons are often in reverse order, except for when they're not. - # See https://gitlab.gnome.org/GNOME/gtk/-/issues/7839. - sorted_first, _sorted_second = AXComponent.sort_objects_by_position([first, second]) - if sorted_first != first: - result.reverse() - - if object_list != result: - tokens = ["AXUtilities: Original list", object_list] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - tokens = ["AXUtilities: Sorted list", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return result - - @staticmethod - def _get_set_members( - obj: Atspi.Accessible, container: Atspi.Accessible - ) -> list[Atspi.Accessible]: - """Returns the members of the container of obj""" - - if container is None: - tokens = ["AXUtilities: Members of", obj, "not obtainable: container is None"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - result = AXUtilitiesRelation.get_is_member_of(obj) - if result: - tokens = ["AXUtilities: Members of", obj, "in", container, "via member-of", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return AXUtilities._sort_by_child_index(result) - - result = AXUtilitiesRelation.get_is_node_parent_of(obj) - if result: - tokens = ["AXUtilities: Members of", obj, "in", container, "via node-parent-of", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return AXUtilities._sort_by_child_index(result) - - if AXUtilitiesRole.is_description_value(obj): - previous_sibling = AXObject.get_previous_sibling(obj) - while previous_sibling and AXUtilitiesRole.is_description_value(previous_sibling): - result.append(previous_sibling) - previous_sibling = AXObject.get_previous_sibling(previous_sibling) - result.append(obj) - next_sibling = AXObject.get_next_sibling(obj) - while next_sibling and AXUtilitiesRole.is_description_value(next_sibling): - result.append(next_sibling) - next_sibling = AXObject.get_next_sibling(next_sibling) - tokens = ["AXUtilities: Members of", obj, "in", container, "based on siblings", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - if AXUtilitiesRole.is_menu_related(obj): - result = list(AXObject.iter_children(container, AXUtilitiesRole.is_menu_related)) - tokens = ["AXUtilities: Members of", obj, "in", container, "based on menu role", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - role = AXObject.get_role(obj) - result = list(AXObject.iter_children(container, lambda x: AXObject.get_role(x) == role)) - tokens = ["AXUtilities: Members of", obj, "in", container, "based on role", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_set_members(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns the members of the container of obj.""" - - result: list[Atspi.Accessible] = [] - container = AXObject.get_parent_checked(obj) - if hash(container) in AXUtilities.SET_MEMBERS: - result = AXUtilities.SET_MEMBERS.get(hash(container), []) - - if obj not in result: - if result: - tokens = ["AXUtilities:", obj, "not in cached members of", container, ":", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - result = AXUtilities._get_set_members(obj, container) - AXUtilities.SET_MEMBERS[hash(container)] = result - - # In a collapsed combobox, one can arrow to change the selection without showing the items. - must_be_showing = not AXObject.find_ancestor(obj, AXUtilitiesRole.is_combo_box) - if not must_be_showing: - return result - - filtered = list(filter(AXUtilitiesState.is_showing, result)) - if result != filtered: - tokens = ["AXUtilities: Filtered non-showing:", set(result).difference(set(filtered))] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return filtered - - @staticmethod - def get_set_size(obj: Atspi.Accessible) -> int: - """Returns the total number of objects in this container.""" - - result = AXObject.get_attribute(obj, "setsize", False) - if isinstance(result, str) and result.isnumeric(): - return int(result) - - if AXUtilitiesRole.is_table_row(obj): - return AXTable.get_row_count(AXTable.get_table(obj)) - - if AXUtilitiesRole.is_table_cell_or_header(obj) \ - and not AXUtilitiesRole.is_table_row(AXObject.get_parent(obj)): - return AXTable.get_row_count(AXTable.get_table(obj)) - - if AXUtilitiesRole.is_combo_box(obj): - selected_children = AXSelection.get_selected_children(obj) - if not selected_children: - return -1 - if len(selected_children) == 1: - obj = selected_children[0] - - if AXUtilitiesRole.is_list(obj) or AXUtilitiesRole.is_list_box(obj): - obj = AXObject.find_descendant(obj, AXUtilitiesRole.is_list_item) - - child_count = AXObject.get_child_count(AXObject.get_parent(obj)) - if child_count > 500: - return child_count - - members = AXUtilities.get_set_members(obj) - return len(members) - - @staticmethod - def get_set_size_is_unknown(obj: Atspi.Accessible) -> bool: - """Returns True if the total number of objects in this container is unknown.""" - - if AXUtilitiesState.is_indeterminate(obj): - return True - - attrs = AXObject.get_attributes_dict(obj, False) - if attrs.get("setsize") == "-1": - return True - - if AXUtilitiesRole.is_table(obj): - return attrs.get("rowcount") == "-1" or attrs.get("colcount") == "-1" - - return False - - @staticmethod - def get_position_in_set(obj: Atspi.Accessible) -> int: - """Returns the position of obj with respect to the number of items in its container.""" - - result = AXObject.get_attribute(obj, "posinset", False) - if isinstance(result, str) and result.isnumeric(): - # ARIA posinset is 1-based. - return int(result) - 1 - - if AXUtilitiesRole.is_table_row(obj): - result = AXObject.get_attribute(obj, "rowindex", False) - if isinstance(result, str) and result.isnumeric(): - # ARIA posinset is 1-based. - return int(result) - 1 - - if AXObject.get_child_count(obj): - cell = AXObject.find_descendant(obj, AXUtilitiesRole.is_table_cell_or_header) - result = AXObject.get_attribute(cell, "rowindex", False) - - if isinstance(result, str) and result.isnumeric(): - # ARIA posinset is 1-based. - return int(result) - 1 - - if AXUtilitiesRole.is_table_cell_or_header(obj) \ - and not AXUtilitiesRole.is_table_row(AXObject.get_parent(obj)): - return AXTable.get_cell_coordinates(obj)[0] - - if AXUtilitiesRole.is_combo_box(obj): - selected_children = AXSelection.get_selected_children(obj) - if not selected_children: - return -1 - if len(selected_children) == 1: - obj = selected_children[0] - - child_count = AXObject.get_child_count(AXObject.get_parent(obj)) - if child_count > 500: - return AXObject.get_index_in_parent(obj) - - members = AXUtilities.get_set_members(obj) - if obj not in members: - return -1 - - return members.index(obj) - - @staticmethod - def has_explicit_name(obj: Atspi.Accessible) -> bool: - """Returns True if obj has an author/app-provided name as opposed to a calculated name.""" - - return AXObject.get_attribute(obj, "explicit-name") == "true" - - @staticmethod - def has_visible_caption(obj: Atspi.Accessible) -> bool: - """Returns True if obj has a visible caption.""" - - if not (AXUtilitiesRole.is_figure(obj) or AXObject.supports_table(obj)): - return False - - labels = AXUtilitiesRelation.get_is_labelled_by(obj) - for label in labels: - if AXUtilitiesRole.is_caption(label) \ - and AXUtilitiesState.is_showing(label) and AXUtilitiesState.is_visible(label): - return True - - return False - - @staticmethod - def get_displayed_label(obj: Atspi.Accessible) -> str: - """Returns the displayed label of obj.""" - - labels = AXUtilitiesRelation.get_is_labelled_by(obj) - strings = [AXObject.get_name(label) or AXText.get_all_text(label) for label in labels] - result = " ".join(strings) - return result - - @staticmethod - def get_displayed_description(obj: Atspi.Accessible) -> str: - """Returns the displayed description of obj.""" - - descriptions = AXUtilitiesRelation.get_is_described_by(obj) - strings = [AXObject.get_name(desc) or AXText.get_all_text(desc) for desc in descriptions] - result = " ".join(strings) - return result - - @staticmethod - def get_heading_level(obj: Atspi.Accessible) -> int: - """Returns the heading level of obj.""" - - if not AXUtilitiesRole.is_heading(obj): - return 0 - - use_cache = not AXUtilitiesState.is_editable(obj) - attrs = AXObject.get_attributes_dict(obj, use_cache) - - try: - value = int(attrs.get("level", "0")) - except ValueError: - tokens = ["AXUtilities: Exception getting value for", obj, "(", attrs, ")"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return 0 - - return value - - @staticmethod - def get_nesting_level(obj: Atspi.Accessible) -> int: - """Returns the nesting level of obj.""" - - def pred(x: Atspi.Accessible) -> bool: - if AXUtilitiesRole.is_list_item(obj): - return AXUtilitiesRole.is_list(AXObject.get_parent(x)) - return AXUtilitiesRole.have_same_role(obj, x) - - ancestors = [] - ancestor = AXObject.find_ancestor(obj, pred) - while ancestor: - ancestors.append(ancestor) - ancestor = AXObject.find_ancestor(ancestor, pred) - - return len(ancestors) - - @staticmethod - def get_next_object(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the next object (depth first, unless there's a flows-to relation)""" - - if not AXObject.is_valid(obj): - return None - - targets = AXUtilitiesRelation.get_flows_to(obj) - for target in targets: - if not AXObject.is_dead(target): - return target - - index = AXObject.get_index_in_parent(obj) + 1 - parent = AXObject.get_parent(obj) - while parent and not 0 < index < AXObject.get_child_count(parent): - obj = parent - index = AXObject.get_index_in_parent(obj) + 1 - parent = AXObject.get_parent(obj) - - if parent is None: - return None - - next_object = AXObject.get_child(parent, index) - if next_object == obj: - tokens = ["AXUtilities:", obj, "claims to be its own next object"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - return next_object - - @staticmethod - def get_previous_object(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the previous object (depth first, unless there's a flows-from relation)""" - - if not AXObject.is_valid(obj): - return None - - targets = AXUtilitiesRelation.get_flows_from(obj) - for target in targets: - if not AXObject.is_dead(target): - return target - - index = AXObject.get_index_in_parent(obj) - 1 - parent = AXObject.get_parent(obj) - while parent and not 0 <= index < AXObject.get_child_count(parent) - 1: - obj = parent - index = AXObject.get_index_in_parent(obj) - 1 - parent = AXObject.get_parent(obj) - - if parent is None: - return None - - previous_object = AXObject.get_child(parent, index) - if previous_object == obj: - tokens = ["AXUtilities:", obj, "claims to be its own previous object"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - return previous_object - - @staticmethod - def is_on_screen( - obj: Atspi.Accessible, - bounding_box: Optional[Atspi.Rect] = None, - clear_cache: bool = True - ) -> bool: - """Returns true if obj should be treated as being on screen.""" - - if clear_cache: - AXObject.clear_cache(obj, False, "Updating to check if object is on screen.") - - tokens = ["AXUtilities: Checking if", obj, "is showing and visible...."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if not (AXUtilitiesState.is_showing(obj) and AXUtilitiesState.is_visible(obj)): - tokens = ["AXUtilities:", obj, "is not showing and visible. Treating as off screen."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["AXUtilities:", obj, "is showing and visible. Checking hidden..."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if AXUtilitiesState.is_hidden(obj): - tokens = ["AXUtilities:", obj, "is reports being hidden. Treating as off screen."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["AXUtilities:", obj, "is not hidden. Checking size and rect..."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if AXComponent.has_no_size_or_invalid_rect(obj, clear_cache=clear_cache): - tokens = ["AXUtilities: Rect of", obj, "is unhelpful. Treating as on screen."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - tokens = ["AXUtilities:", obj, "has size and a valid rect. Checking if off screen..."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if AXComponent.object_is_off_screen(obj): - tokens = ["AXUtilities:", obj, "is believed to be off screen."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["AXUtilities:", obj, "is not off screen. Checking", - bounding_box, "intersection..."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if bounding_box is not None and not AXComponent.object_intersects_rect(obj, bounding_box): - tokens = ["AXUtilities", obj, "not in", bounding_box, ". Treating as off screen."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["AXUtilities:", obj, "is believed to be on screen."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - @staticmethod - def treat_as_leaf_node(obj: Atspi.Accessible) -> bool: - """Returns True if obj should be treated as a leaf node.""" - - if AXUtilitiesRole.children_are_presentational(obj): - # In GTK, the contents of the page tab descends from the page tab. - if AXUtilitiesRole.is_page_tab(obj): - return False - return True - - role = AXObject.get_role(obj) - if AXUtilitiesRole.is_combo_box(obj, role): - return not AXUtilitiesState.is_expanded(obj) - - if AXUtilitiesRole.is_menu(obj, role) and not AXUtilitiesRole.has_role_from_aria(obj): - return not AXUtilitiesState.is_expanded(obj) - - if AXObject.get_name(obj): - return AXUtilitiesRole.is_link(obj, role) or AXUtilitiesRole.is_label(obj, role) - - return False - - @staticmethod - def _get_on_screen_objects( - root: Atspi.Accessible, - cancellation_event: threading.Event, - bounding_box: Optional[Atspi.Rect] = None - ) -> list: - - tokens = ["AXUtilities: Getting on-screen objects in", root, f"({hex(id(root))})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - if cancellation_event.is_set(): - msg = "AXUtilities: Cancellation event set. Stopping search." - debug.print_message(debug.LEVEL_INFO, msg, True) - return [] - - if not AXUtilities.is_on_screen(root, bounding_box): - return [] - - if AXUtilities.treat_as_leaf_node(root): - return [root] - - if AXObject.supports_table(root) and AXObject.supports_selection(root): - return list(AXTable.iter_visible_cells(root)) - - objects = [] - root_name = AXObject.get_name(root) - if root_name or AXObject.get_description(root) or AXText.has_presentable_text(root): - objects.append(root) - - if bounding_box is None: - bounding_box = AXComponent.get_rect(root) - - for i, child in enumerate(AXObject.iter_children(root)): - tokens = [f"AXUtilities: Child {i} is", child, f"({hex(id(child))})"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if cancellation_event.is_set(): - msg = "AXUtilities: Cancellation event set. Stopping search." - debug.print_message(debug.LEVEL_INFO, msg, True) - break - - children = AXUtilities._get_on_screen_objects(child, cancellation_event, bounding_box) - objects.extend(children) - if root_name and children and root in objects and root_name == AXObject.get_name(child): - objects.remove(root) - - if objects: - return objects - - if AXUtilitiesState.is_focusable(root) or AXObject.has_action(root, "click"): - return [root] - - return [] - - @staticmethod - def get_on_screen_objects( - root: Atspi.Accessible, - bounding_box: Optional[Atspi.Rect] = None, - timeout: float = 5.0 - ) -> list: - """Returns a list of onscreen objects in the given root.""" - - result_queue: queue.Queue[list] = queue.Queue() - cancellation_event = threading.Event() - - def _worker(): - result = AXUtilities._get_on_screen_objects(root, cancellation_event, bounding_box) - if not cancellation_event.is_set(): - result_queue.put(result) - - worker_thread = threading.Thread(target=_worker) - worker_thread.start() - - try: - result = result_queue.get(timeout=timeout) - except queue.Empty: - tokens = ["AXUtilities: get_on_screen_objects timed out.", root] - debug.print_tokens(debug.LEVEL_WARNING, tokens, True) - cancellation_event.set() - result = [] - - msg = "AXUtilities: Checking AT-SPI responsiveness...." - debug.print_message(debug.LEVEL_INFO, msg, True) - desktop = AXUtilitiesApplication.get_desktop() - tokens = ["AXUtilities: Desktop is", desktop] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - worker_thread.join() - tokens = [f"AXUtilities: {len(result)} onscreen objects found in", root] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - -# Dynamically expose helper methods for compatibility with older callers. -# Keep side effects explicit in the underlying helpers (e.g., clear_cache flags). -for method_name, method in inspect.getmembers(AXUtilitiesApplication, predicate=inspect.isfunction): - setattr(AXUtilities, method_name, method) - -for method_name, method in inspect.getmembers(AXUtilitiesEvent, predicate=inspect.isfunction): - setattr(AXUtilities, method_name, method) - -for method_name, method in inspect.getmembers(AXUtilitiesRelation, predicate=inspect.isfunction): - setattr(AXUtilities, method_name, method) - -for method_name, method in inspect.getmembers(AXUtilitiesRole, predicate=inspect.isfunction): - setattr(AXUtilities, method_name, method) - -for method_name, method in inspect.getmembers(AXUtilitiesState, predicate=inspect.isfunction): - setattr(AXUtilities, method_name, method) - -for method_name, method in inspect.getmembers(AXUtilitiesCollection, predicate=inspect.isfunction): - if method_name.startswith("find"): - setattr(AXUtilities, method_name, method) - -AXUtilities.start_cache_clearing_thread() diff --git a/src/cthulhu/ax_utilities.pyi b/src/cthulhu/ax_utilities.pyi deleted file mode 100644 index 1a871da..0000000 --- a/src/cthulhu/ax_utilities.pyi +++ /dev/null @@ -1,1288 +0,0 @@ -# Stub file that should contain all public methods of AXUtilities -# -# Copyright 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -""" -Stub file that contains all public methods of AXUtilities, including -those which are added dynamically at runtime. This is needed for type -checkers, linters, and IDEs. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -class AXUtilities: - - # From ax_utilities.py - @staticmethod - def get_desktop(): ... - - @staticmethod - def get_all_applications(must_have_window=False): ... - - @staticmethod - def is_application_in_desktop(app): ... - - @staticmethod - def get_application_with_pid(pid): ... - - @staticmethod - def get_all_static_text_leaf_nodes(obj): ... - - @staticmethod - def get_all_widgets(obj, must_be_showing_and_visible=True): ... - - @staticmethod - def get_default_button(obj): ... - - @staticmethod - def get_focused_object(obj): ... - - @staticmethod - def get_status_bar(obj): ... - - # From ax_utilities_role.py - @staticmethod - def get_dialog_roles(include_alert_as_dialog=True): ... - - @staticmethod - def get_document_roles(): ... - - @staticmethod - def get_form_field_roles(): ... - - @staticmethod - def get_menu_item_roles(): ... - - @staticmethod - def get_menu_related_roles(): ... - - @staticmethod - def get_roles_to_exclude_from_clickables_list(): ... - - @staticmethod - def get_set_container_roles(): ... - - @staticmethod - def get_table_cell_roles(include_headers=True): ... - - @staticmethod - def get_table_header_roles(): ... - - @staticmethod - def get_table_related_roles(include_caption=False): ... - - @staticmethod - def get_tree_related_roles(): ... - - @staticmethod - def get_widget_roles(): ... - - @staticmethod - def have_same_role(obj1, obj2): ... - - @staticmethod - def is_accelerator_label(obj, role=None): ... - - @staticmethod - def is_alert(obj, role=None): ... - - @staticmethod - def is_animation(obj, role=None): ... - - @staticmethod - def is_application(obj, role=None): ... - - @staticmethod - def is_arrow(obj, role=None): ... - - @staticmethod - def is_article(obj, role=None): ... - - @staticmethod - def is_audio(obj, role=None): ... - - @staticmethod - def is_autocomplete(obj, role=None): ... - - @staticmethod - def is_block_quote(obj, role=None): ... - - @staticmethod - def is_button(obj, role=None): ... - - @staticmethod - def is_calendar(obj, role=None): ... - - @staticmethod - def is_canvas(obj, role=None): ... - - @staticmethod - def is_caption(obj, role=None): ... - - @staticmethod - def is_chart(obj, role=None): ... - - @staticmethod - def is_check_box(obj, role=None): ... - - @staticmethod - def is_check_menu_item(obj, role=None): ... - - @staticmethod - def is_color_chooser(obj, role=None): ... - - @staticmethod - def is_column_header(obj, role=None): ... - - @staticmethod - def is_combo_box(obj, role=None): ... - - @staticmethod - def is_comment(obj, role=None): ... - - @staticmethod - def is_content_deletion(obj, role=None): ... - - @staticmethod - def is_content_insertion(obj, role=None): ... - - @staticmethod - def is_default_button(obj, role=None): ... - - @staticmethod - def is_date_editor(obj, role=None): ... - - @staticmethod - def is_definition(obj, role=None): ... - - @staticmethod - def is_description_list(obj, role=None): ... - - @staticmethod - def is_description_term(obj, role=None): ... - - @staticmethod - def is_description_value(obj, role=None): ... - - @staticmethod - def is_desktop_frame(obj, role=None): ... - - @staticmethod - def is_desktop_icon(obj, role=None): ... - - @staticmethod - def is_dial(obj, role=None): ... - - @staticmethod - def is_dialog(obj, role=None): ... - - @staticmethod - def is_dialog_or_alert(obj, role=None): ... - - @staticmethod - def is_directory_pane(obj, role=None): ... - - @staticmethod - def is_document(obj, role=None): ... - - @staticmethod - def is_document_email(obj, role=None): ... - - @staticmethod - def is_document_frame(obj, role=None): ... - - @staticmethod - def is_document_presentation(obj, role=None): ... - - @staticmethod - def is_document_spreadsheet(obj, role=None): ... - - @staticmethod - def is_document_text(obj, role=None): ... - - @staticmethod - def is_document_web(obj, role=None): ... - - @staticmethod - def is_drawing_area(obj, role=None): ... - - @staticmethod - def is_editbar(obj, role=None): ... - - @staticmethod - def is_embedded(obj, role=None): ... - - @staticmethod - def is_entry(obj, role=None): ... - - @staticmethod - def is_extended(obj, role=None): ... - - @staticmethod - def is_file_chooser(obj, role=None): ... - - @staticmethod - def is_filler(obj, role=None): ... - - @staticmethod - def is_focus_traversable(obj, role=None): ... - - @staticmethod - def is_font_chooser(obj, role=None): ... - - @staticmethod - def is_footer(obj, role=None): ... - - @staticmethod - def is_footnote(obj, role=None): ... - - @staticmethod - def is_form(obj, role=None): ... - - @staticmethod - def is_frame(obj, role=None): ... - - @staticmethod - def is_glass_pane(obj, role=None): ... - - @staticmethod - def is_grouping(obj, role=None): ... - - @staticmethod - def is_header(obj, role=None): ... - - @staticmethod - def is_heading(obj, role=None): ... - - @staticmethod - def is_html_container(obj, role=None): ... - - @staticmethod - def is_horizontal_scrollbar(obj, role=None): ... - - @staticmethod - def is_horizontal_separator(obj, role=None): ... - - @staticmethod - def is_horizontal_slider(obj, role=None): ... - - @staticmethod - def is_icon(obj, role=None): ... - - @staticmethod - def is_icon_or_canvas(obj, role=None): ... - - @staticmethod - def is_image(obj, role=None): ... - - @staticmethod - def is_image_or_canvas(obj, role=None): ... - - @staticmethod - def is_image_map(obj, role=None): ... - - @staticmethod - def is_info_bar(obj, role=None): ... - - @staticmethod - def is_input_method_window(obj, role=None): ... - - @staticmethod - def is_internal_frame(obj, role=None): ... - - @staticmethod - def is_invalid_role(obj, role=None): ... - - @staticmethod - def is_label(obj, role=None): ... - - @staticmethod - def is_label_or_caption(obj, role=None): ... - - @staticmethod - def is_landmark(obj, role=None): ... - - @staticmethod - def is_layered_pane(obj, role=None): ... - - @staticmethod - def is_level_bar(obj, role=None): ... - - @staticmethod - def is_link(obj, role=None): ... - - @staticmethod - def is_list(obj, role=None): ... - - @staticmethod - def is_list_box(obj, role=None): ... - - @staticmethod - def is_list_item(obj, role=None): ... - - @staticmethod - def is_log(obj, role=None): ... - - @staticmethod - def is_mark(obj, role=None): ... - - @staticmethod - def is_marquee(obj, role=None): ... - - @staticmethod - def is_math(obj, role=None): ... - - @staticmethod - def is_math_fraction(obj, role=None): ... - - @staticmethod - def is_math_root(obj, role=None): ... - - @staticmethod - def is_menu(obj, role=None): ... - - @staticmethod - def is_menu_bar(obj, role=None): ... - - @staticmethod - def is_menu_item(obj, role=None): ... - - @staticmethod - def is_menu_item_of_any_kind(obj, role=None): ... - - @staticmethod - def is_menu_related(obj, role=None): ... - - @staticmethod - def is_modal_dialog(obj, role=None): ... - - @staticmethod - def is_multi_line_entry(obj, role=None): ... - - @staticmethod - def is_notification(obj, role=None): ... - - @staticmethod - def is_option_pane(obj, role=None): ... - - @staticmethod - def is_page(obj, role=None): ... - - @staticmethod - def is_page_tab(obj, role=None): ... - - @staticmethod - def is_page_tab_list(obj, role=None): ... - - @staticmethod - def is_page_tab_list_related(obj, role=None): ... - - @staticmethod - def is_panel(obj, role=None): ... - - @staticmethod - def is_paragraph(obj, role=None): ... - - @staticmethod - def is_password_text(obj, role=None): ... - - @staticmethod - def is_popup_menu(obj, role=None): ... - - @staticmethod - def is_progress_bar(obj, role=None): ... - - @staticmethod - def is_push_button(obj, role=None): ... - - @staticmethod - def is_push_button_menu(obj, role=None): ... - - @staticmethod - def is_radio_button(obj, role=None): ... - - @staticmethod - def is_radio_menu_item(obj, role=None): ... - - @staticmethod - def is_rating(obj, role=None): ... - - @staticmethod - def is_redundant_object(obj, role=None): ... - - @staticmethod - def is_root_pane(obj, role=None): ... - - @staticmethod - def is_row_header(obj, role=None): ... - - @staticmethod - def is_ruler(obj, role=None): ... - - @staticmethod - def is_scroll_bar(obj, role=None): ... - - @staticmethod - def is_scroll_pane(obj, role=None): ... - - @staticmethod - def is_section(obj, role=None): ... - - @staticmethod - def is_separator(obj, role=None): ... - - @staticmethod - def is_single_line_entry(obj, role=None): ... - - @staticmethod - def is_slider(obj, role=None): ... - - @staticmethod - def is_spin_button(obj, role=None): ... - - @staticmethod - def is_split_pane(obj, role=None): ... - - @staticmethod - def is_static(obj, role=None): ... - - @staticmethod - def is_status_bar(obj, role=None): ... - - @staticmethod - def is_subscript(obj, role=None): ... - - @staticmethod - def is_subscript_or_superscript(obj, role=None): ... - - @staticmethod - def is_suggestion(obj, role=None): ... - - @staticmethod - def is_superscript(obj, role=None): ... - - @staticmethod - def is_table(obj, role=None): ... - - @staticmethod - def is_table_cell(obj, role=None): ... - - @staticmethod - def is_table_cell_or_header(obj, role=None): ... - - @staticmethod - def is_table_column_header(obj, role=None): ... - - @staticmethod - def is_table_header(obj, role=None): ... - - @staticmethod - def is_table_related(obj, role=None, include_caption=False): ... - - @staticmethod - def is_table_row(obj, role=None): ... - - @staticmethod - def is_table_row_header(obj, role=None): ... - - @staticmethod - def is_tearoff_menu_item(obj, role=None): ... - - @staticmethod - def is_terminal(obj, role=None): ... - - @staticmethod - def is_text(obj, role=None): ... - - @staticmethod - def is_text_input(obj, role=None): ... - - @staticmethod - def is_timer(obj, role=None): ... - - @staticmethod - def is_title_bar(obj, role=None): ... - - @staticmethod - def is_toggle_button(obj, role=None): ... - - @staticmethod - def is_tool_bar(obj, role=None): ... - - @staticmethod - def is_tool_tip(obj, role=None): ... - - @staticmethod - def is_tree(obj, role=None): ... - - @staticmethod - def is_tree_or_tree_table(obj, role=None): ... - - @staticmethod - def is_tree_related(obj, role=None): ... - - @staticmethod - def is_tree_item(obj, role=None): ... - - @staticmethod - def is_tree_table(obj, role=None): ... - - @staticmethod - def is_unknown(obj, role=None): ... - - @staticmethod - def is_unknown_or_redundant(obj, role=None): ... - - @staticmethod - def is_vertical_scrollbar(obj, role=None): ... - - @staticmethod - def is_vertical_separator(obj, role=None): ... - - @staticmethod - def is_vertical_slider(obj, role=None): ... - - @staticmethod - def is_video(obj, role=None): ... - - @staticmethod - def is_viewport(obj, role=None): ... - - @staticmethod - def is_window(obj, role=None): ... - - # From ax_utilities_state.py - @staticmethod - def has_no_state(obj): ... - - @staticmethod - def has_popup(obj): ... - - @staticmethod - def has_tooltip(obj): ... - - @staticmethod - def is_active(obj): ... - - @staticmethod - def is_animated(obj): ... - - @staticmethod - def is_armed(obj): ... - - @staticmethod - def is_busy(obj): ... - - @staticmethod - def is_checkable(obj): ... - - @staticmethod - def is_checked(obj): ... - - @staticmethod - def is_collapsed(obj): ... - - @staticmethod - def is_default(obj): ... - - @staticmethod - def is_defunct(obj): ... - - @staticmethod - def is_editable(obj): ... - - @staticmethod - def is_enabled(obj): ... - - @staticmethod - def is_expandable(obj): ... - - @staticmethod - def is_expanded(obj): ... - - @staticmethod - def is_focusable(obj): ... - - @staticmethod - def is_focused(obj): ... - - @staticmethod - def is_horizontal(obj): ... - - @staticmethod - def is_iconified(obj): ... - - @staticmethod - def is_indeterminate(obj): ... - - @staticmethod - def is_invalid_state(obj): ... - - @staticmethod - def is_invalid_entry(obj): ... - - @staticmethod - def is_modal(obj): ... - - @staticmethod - def is_multi_line(obj): ... - - @staticmethod - def is_multiselectable(obj): ... - - @staticmethod - def is_opaque(obj): ... - - @staticmethod - def is_pressed(obj): ... - - @staticmethod - def is_read_only(obj): ... - - @staticmethod - def is_required(obj): ... - - @staticmethod - def is_resizable(obj): ... - - @staticmethod - def is_selectable(obj): ... - - @staticmethod - def is_selectable_text(obj): ... - - @staticmethod - def is_selected(obj): ... - - @staticmethod - def is_sensitive(obj): ... - - @staticmethod - def is_showing(obj): ... - - @staticmethod - def is_single_line(obj): ... - - @staticmethod - def is_stale(obj): ... - - @staticmethod - def is_transient(obj): ... - - @staticmethod - def is_truncated(obj): ... - - @staticmethod - def is_vertical(obj): ... - - @staticmethod - def is_visible(obj): ... - - @staticmethod - def is_visited(obj): ... - - @staticmethod - def manages_descendants(obj): ... - - @staticmethod - def supports_autocompletion(obj): ... - - # From ax_utilities_collection.py - @staticmethod - def find_all_with_interfaces(root, interface_list, pred=None): ... - - @staticmethod - def find_all_with_role(root, roles_list, pred=None): ... - - @staticmethod - def find_all_without_roles(root, role_list, pred=None): ... - - @staticmethod - def find_all_with_role_and_all_states(root, role_list, state_list, pred=None): ... - - @staticmethod - def find_all_with_role_and_any_state(root, role_list, state_list, pred=None): ... - - @staticmethod - def find_all_with_role_without_states(root, role_list, state_list, pred=None): ... - - @staticmethod - def find_all_with_states(root, state_list, pred=None): ... - - @staticmethod - def find_all_with_any_state(root, state_list, pred=None): ... - - @staticmethod - def find_all_without_states(root, state_list, pred=None): ... - - @staticmethod - def find_all_accelerator_labels(root, pred=None): ... - - @staticmethod - def find_all_alerts(root, pred=None): ... - - @staticmethod - def find_all_animations(root, pred=None): ... - - @staticmethod - def find_all_arrows(root, pred=None): ... - - @staticmethod - def find_all_articles(root, pred=None): ... - - @staticmethod - def find_all_audios(root, pred=None): ... - - @staticmethod - def find_all_autocompletes(root, pred=None): ... - - @staticmethod - def find_all_block_quotes(root, pred=None): ... - - @staticmethod - def find_all_buttons(root, pred=None): ... - - @staticmethod - def find_all_calendars(root, pred=None): ... - - @staticmethod - def find_all_canvases(root, pred=None): ... - - @staticmethod - def find_all_captions(root, pred=None): ... - - @staticmethod - def find_all_charts(root, pred=None): ... - - @staticmethod - def find_all_check_boxes(root, pred=None): ... - - @staticmethod - def find_all_check_menu_items(root, pred=None): ... - - @staticmethod - def find_all_clickables(root, pred=None): ... - - @staticmethod - def find_all_color_choosers(root, pred=None): ... - - @staticmethod - def find_all_column_headers(root, pred=None): ... - - @staticmethod - def find_all_combo_boxes(root, pred=None): ... - - @staticmethod - def find_all_comments(root, pred=None): ... - - @staticmethod - def find_all_content_deletions(root, pred=None): ... - - @staticmethod - def find_all_content_insertions(root, pred=None): ... - - @staticmethod - def find_all_date_editors(root, pred=None): ... - - @staticmethod - def find_all_definitions(root, pred=None): ... - - @staticmethod - def find_all_description_lists(root, pred=None): ... - - @staticmethod - def find_all_description_terms(root, pred=None): ... - - @staticmethod - def find_all_description_values(root, pred=None): ... - - @staticmethod - def find_all_desktop_frames(root, pred=None): ... - - @staticmethod - def find_all_desktop_icons(root, pred=None): ... - - @staticmethod - def find_all_dials(root, pred=None): ... - - @staticmethod - def find_all_dialogs(root, pred=None): ... - - @staticmethod - def find_all_dialogs_and_alerts(root, pred=None): ... - - @staticmethod - def find_all_directory_panes(root, pred=None): ... - - @staticmethod - def find_all_documents(root, pred=None): ... - - @staticmethod - def find_all_document_emails(root, pred=None): ... - - @staticmethod - def find_all_document_frames(root, pred=None): ... - - @staticmethod - def find_all_document_presentations(root, pred=None): ... - - @staticmethod - def find_all_document_spreadsheets(root, pred=None): ... - - @staticmethod - def find_all_document_texts(root, pred=None): ... - - @staticmethod - def find_all_document_webs(root, pred=None): ... - - @staticmethod - def find_all_drawing_areas(root, pred=None): ... - - @staticmethod - def find_all_editable_objects(root, pred=None): ... - - @staticmethod - def find_all_editbars(root, pred=None): ... - - @staticmethod - def find_all_embeddeds(root, pred=None): ... - - @staticmethod - def find_all_entries(root, pred=None): ... - - @staticmethod - def find_all_extendeds(root, pred=None): ... - - @staticmethod - def find_all_file_choosers(root, pred=None): ... - - @staticmethod - def find_all_fillers(root, pred=None): ... - - @staticmethod - def find_all_focus_traversables(root, pred=None): ... - - @staticmethod - def find_all_focusable_objects(root, pred=None): ... - - @staticmethod - def find_all_focusable_objects_with_click_ancestor(root, pred=None): ... - - @staticmethod - def find_all_focused_objects(root, pred=None): ... - - @staticmethod - def find_all_font_choosers(root, pred=None): ... - - @staticmethod - def find_all_footers(root, pred=None): ... - - @staticmethod - def find_all_footnotes(root, pred=None): ... - - @staticmethod - def find_all_forms(root, pred=None): ... - - @staticmethod - def find_all_form_fields(root, must_be_focusable=True, pred=None): ... - - @staticmethod - def find_all_frames(root, pred=None): ... - - @staticmethod - def find_all_glass_panes(root, pred=None): ... - - @staticmethod - def find_all_grids(root, pred=None): ... - - @staticmethod - def find_all_grid_cells(root, pred=None): ... - - @staticmethod - def find_all_groupings(root, pred=None): ... - - @staticmethod - def find_all_headers(root, pred=None): ... - - @staticmethod - def find_all_headings(root, pred=None): ... - - @staticmethod - def find_all_headings_at_level(root, level, pred=None): ... - - @staticmethod - def find_all_html_containers(root, pred=None): ... - - @staticmethod - def find_all_horizontal_scrollbars(root, pred=None): ... - - @staticmethod - def find_all_horizontal_separators(root, pred=None): ... - - @staticmethod - def find_all_horizontal_sliders(root, pred=None): ... - - @staticmethod - def find_all_icons(root, pred=None): ... - - @staticmethod - def find_all_icons_and_canvases(root, pred=None): ... - - @staticmethod - def find_all_images(root, pred=None): ... - - @staticmethod - def find_all_images_and_canvases(root, pred=None): ... - - @staticmethod - def find_all_images_and_image_maps(root, pred=None): ... - - @staticmethod - def find_all_image_maps(root, pred=None): ... - - @staticmethod - def find_all_info_bars(root, pred=None): ... - - @staticmethod - def find_all_input_method_windows(root, pred=None): ... - - @staticmethod - def find_all_internal_frames(root, pred=None): ... - - @staticmethod - def find_all_labels(root, pred=None): ... - - @staticmethod - def find_all_labels_and_captions(root, pred=None): ... - - @staticmethod - def find_all_landmarks(root, pred=None): ... - - @staticmethod - def find_all_layered_panes(root, pred=None): ... - - @staticmethod - def find_all_level_bars(root, pred=None): ... - - @staticmethod - def find_all_links(root, must_be_focusable=True, pred=None): ... - - @staticmethod - def find_all_lists(root, pred=None): ... - - @staticmethod - def find_all_list_boxes(root, pred=None): ... - - @staticmethod - def find_all_list_items(root, pred=None): ... - - @staticmethod - def find_all_live_regions(root, pred=None): ... - - @staticmethod - def find_all_logs(root, pred=None): ... - - @staticmethod - def find_all_marks(root, pred=None): ... - - @staticmethod - def find_all_marquees(root, pred=None): ... - - @staticmethod - def find_all_maths(root, pred=None): ... - - @staticmethod - def find_all_math_fractions(root, pred=None): ... - - @staticmethod - def find_all_math_roots(root, pred=None): ... - - @staticmethod - def find_all_menus(root, pred=None): ... - - @staticmethod - def find_all_menu_bars(root, pred=None): ... - - @staticmethod - def find_all_menu_items(root, pred=None): ... - - @staticmethod - def find_all_menu_items_of_any_kind(root, pred=None): ... - - @staticmethod - def find_all_menu_related_objects(root, pred=None): ... - - @staticmethod - def find_all_modal_dialogs(root, pred=None): ... - - @staticmethod - def find_all_multi_line_entries(root, pred=None): ... - - @staticmethod - def find_all_notifications(root, pred=None): ... - - @staticmethod - def find_all_option_panes(root, pred=None): ... - - @staticmethod - def find_all_pages(root, pred=None): ... - - @staticmethod - def find_all_page_tabs(root, pred=None): ... - - @staticmethod - def find_all_page_tab_lists(root, pred=None): ... - - @staticmethod - def find_all_page_tab_list_related_objects(root, pred=None): ... - - @staticmethod - def find_all_panels(root, pred=None): ... - - @staticmethod - def find_all_paragraphs(root, treat_headings_as_paragraphs=False, pred=None): ... - - @staticmethod - def find_all_password_texts(root, pred=None): ... - - @staticmethod - def find_all_popup_menus(root, pred=None): ... - - @staticmethod - def find_all_progress_bars(root, pred=None): ... - - @staticmethod - def find_all_push_buttons(root, pred=None): ... - - @staticmethod - def find_all_push_button_menus(root, pred=None): ... - - @staticmethod - def find_all_radio_buttons(root, pred=None): ... - - @staticmethod - def find_all_radio_menu_items(root, pred=None): ... - - @staticmethod - def find_all_ratings(root, pred=None): ... - - @staticmethod - def find_all_root_panes(root, pred=None): ... - - @staticmethod - def find_all_row_headers(root, pred=None): ... - - @staticmethod - def find_all_rulers(root, pred=None): ... - - @staticmethod - def find_all_scroll_bars(root, pred=None): ... - - @staticmethod - def find_all_scroll_panes(root, pred=None): ... - - @staticmethod - def find_all_sections(root, pred=None): ... - - @staticmethod - def find_all_selectable_objects(root, pred=None): ... - - @staticmethod - def find_all_selected_objects(root, pred=None): ... - - @staticmethod - def find_all_separators(root, pred=None): ... - - @staticmethod - def find_all_set_containers(root, pred=None): ... - - @staticmethod - def find_all_showing_objects(root, pred=None): ... - - @staticmethod - def find_all_showing_and_visible_objects(root, pred=None): ... - - @staticmethod - def find_all_showing_or_visible_objects(root, pred=None): ... - - @staticmethod - def find_all_single_line_entries(root, pred=None): ... - - @staticmethod - def find_all_sliders(root, pred=None): ... - - @staticmethod - def find_all_spin_buttons(root, pred=None): ... - - @staticmethod - def find_all_split_panes(root, pred=None): ... - - @staticmethod - def find_all_statics(root, pred=None): ... - - @staticmethod - def find_all_status_bars(root, pred=None): ... - - @staticmethod - def find_all_subscripts(root, pred=None): ... - - @staticmethod - def find_all_subscripts_and_superscripts(root, pred=None): ... - - @staticmethod - def find_all_suggestions(root, pred=None): ... - - @staticmethod - def find_all_superscripts(root, pred=None): ... - - @staticmethod - def find_all_supports_action(root, pred=None): ... - - @staticmethod - def find_all_supports_document(root, pred=None): ... - - @staticmethod - def find_all_supports_editable_text(root, pred=None): ... - - @staticmethod - def find_all_supports_hypertext(root, pred=None): ... - - @staticmethod - def find_all_supports_hyperlink(root, pred=None): ... - - @staticmethod - def find_all_supports_selection(root, pred=None): ... - - @staticmethod - def find_all_supports_table(root, pred=None): ... - - @staticmethod - def find_all_supports_table_cell(root, pred=None): ... - - @staticmethod - def find_all_supports_text(root, pred=None): ... - - @staticmethod - def find_all_supports_value(root, pred=None): ... - - @staticmethod - def find_all_tables(root, pred=None): ... - - @staticmethod - def find_all_table_cells(root, pred=None): ... - - @staticmethod - def find_all_table_cells_and_headers(root, pred=None): ... - - @staticmethod - def find_all_table_column_headers(root, pred=None): ... - - @staticmethod - def find_all_table_headers(root, pred=None): ... - - @staticmethod - def find_all_table_related_objects(root, pred=None, include_caption=False): ... - - @staticmethod - def find_all_table_rows(root, pred=None): ... - - @staticmethod - def find_all_table_row_headers(root, pred=None): ... - - @staticmethod - def find_all_tearoff_menu_items(root, pred=None): ... - - @staticmethod - def find_all_terminals(root, pred=None): ... - - @staticmethod - def find_all_texts(root, pred=None): ... - - @staticmethod - def find_all_text_inputs(root, pred=None): ... - - @staticmethod - def find_all_timers(root, pred=None): ... - - @staticmethod - def find_all_title_bars(root, pred=None): ... - - @staticmethod - def find_all_toggle_buttons(root, pred=None): ... - - @staticmethod - def find_all_tool_bars(root, pred=None): ... - - @staticmethod - def find_all_tool_tips(root, pred=None): ... - - @staticmethod - def find_all_trees(root, pred=None): ... - - @staticmethod - def find_all_trees_and_tree_tables(root, pred=None): ... - - @staticmethod - def find_all_tree_related_objects(root, pred=None): ... - - @staticmethod - def find_all_tree_items(root, pred=None): ... - - @staticmethod - def find_all_tree_tables(root, pred=None): ... - - @staticmethod - def find_all_unrelated_labels(root, must_be_showing=True, pred=None): ... - - @staticmethod - def find_all_unvisited_links(root, must_be_focusable=True, pred=None): ... - - @staticmethod - def find_all_vertical_scrollbars(root, pred=None): ... - - @staticmethod - def find_all_vertical_separators(root, pred=None): ... - - @staticmethod - def find_all_vertical_sliders(root, pred=None): ... - - @staticmethod - def find_all_videos(root, pred=None): ... - - @staticmethod - def find_all_viewports(root, pred=None): ... - - @staticmethod - def find_all_visible_objects(root, pred=None): ... - - @staticmethod - def find_all_visited_links(root, must_be_focusable=True, pred=None): ... - - @staticmethod - def find_default_button(root): ... - - @staticmethod - def find_focused_object(root): ... - - @staticmethod - def find_status_bar(root): ... diff --git a/src/cthulhu/ax_utilities_application.py b/src/cthulhu/ax_utilities_application.py deleted file mode 100644 index df82c48..0000000 --- a/src/cthulhu/ax_utilities_application.py +++ /dev/null @@ -1,209 +0,0 @@ -# Utilities for obtaining information about accessible applications. -# -# Copyright 2023-2024 Igalia, S.L. -# Copyright 2024 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=wrong-import-position - -"""Utilities for obtaining information about accessible applications.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023-2024 Igalia, S.L." \ - "Copyright (c) 2024 GNOME Foundation Inc." -__license__ = "LGPL" - -from typing import Optional -import subprocess - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from .ax_object import AXObject - -class AXUtilitiesApplication: - """Utilities for obtaining information about accessible applications.""" - - @staticmethod - def application_as_string(obj: Atspi.Accessible) -> str: - """Returns the application details of obj as a string.""" - - app = AXUtilitiesApplication.get_application(obj) - if app is None: - return "" - - string = ( - f"{AXObject.get_name(app)} " - f"({AXUtilitiesApplication.get_application_toolkit_name(obj)} " - f"{AXUtilitiesApplication.get_application_toolkit_version(obj)})" - ) - return string - - @staticmethod - def get_all_applications( - must_have_window: bool = False, - exclude_unresponsive: bool = False, - is_debug: bool = False - ) -> list[Atspi.Accessible]: - """Returns a list of running applications known to Atspi.""" - - desktop = AXUtilitiesApplication.get_desktop() - if desktop is None: - return [] - - def pred(obj: Atspi.Accessible) -> bool: - if exclude_unresponsive and AXUtilitiesApplication.is_application_unresponsive(obj): - return False - if AXObject.get_name(obj) == "mutter-x11-frames": - return is_debug - if must_have_window: - return AXObject.get_child_count(obj) > 0 - return True - - return list(AXObject.iter_children(desktop, pred)) - - @staticmethod - def get_application(obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the accessible application associated with obj""" - - if obj is None: - return None - - try: - app = Atspi.Accessible.get_application(obj) - except GLib.GError as error: - msg = f"AXUtilitiesApplication: Exception in get_application: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - return app - - @staticmethod - def get_application_toolkit_name(obj: Atspi.Accessible) -> str: - """Returns the toolkit name reported for obj's application.""" - - app = AXUtilitiesApplication.get_application(obj) - if app is None: - return "" - - try: - name = Atspi.Accessible.get_toolkit_name(app) - except GLib.GError as error: - msg = f"AXUtilitiesApplication: Exception in get_application_toolkit_name: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "" - - return name - - @staticmethod - def get_application_toolkit_version(obj: Atspi.Accessible) -> str: - """Returns the toolkit version reported for obj's application.""" - - app = AXUtilitiesApplication.get_application(obj) - if app is None: - return "" - - try: - version = Atspi.Accessible.get_toolkit_version(app) - except GLib.GError as error: - msg = f"AXUtilitiesApplication: Exception in get_application_toolkit_version: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return "" - - return version - - @staticmethod - def get_application_with_pid(pid: int) -> Optional[Atspi.Accessible]: - """Returns the accessible application with the specified pid""" - - applications = AXUtilitiesApplication.get_all_applications() - for child in applications: - if AXUtilitiesApplication.get_process_id(child) == pid: - return child - - tokens = ["WARNING: app with pid", pid, "is not in the accessible desktop"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - @staticmethod - def get_desktop() -> Optional[Atspi.Accessible]: - """Returns the accessible desktop""" - - try: - desktop = Atspi.get_desktop(0) - except GLib.GError as error: - tokens = ["ERROR: Exception getting desktop from Atspi:", error] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - return desktop - - @staticmethod - def get_process_id(obj: Atspi.Accessible) -> int: - """Returns the process id associated with obj""" - - try: - pid = Atspi.Accessible.get_process_id(obj) - except GLib.GError as error: - msg = f"AXUtilitiesApplication: Exception in get_process_id: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1 - - return pid - - @staticmethod - def is_application_in_desktop(app: Atspi.Accessible) -> bool: - """Returns true if app is known to Atspi""" - - applications = AXUtilitiesApplication.get_all_applications() - for child in applications: - if child == app: - return True - - tokens = ["WARNING:", app, "is not in the accessible desktop"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - @staticmethod - def is_application_unresponsive(app: Atspi.Accessible) -> bool: - """Returns true if app's process is known to be unresponsive.""" - - pid = AXUtilitiesApplication.get_process_id(app) - try: - state = subprocess.getoutput(f"cat /proc/{pid}/status | grep State") - state = state.split()[1] - except (GLib.GError, IndexError) as error: - tokens = [f"AXUtilitiesApplication: Exception checking state of pid {pid}: {error}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return False - - if state == "Z": - tokens = [f"AXUtilitiesApplication: pid {pid} is zombie process"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - if state == "T": - tokens = [f"AXUtilitiesApplication: pid {pid} is suspended/stopped process"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - return False diff --git a/src/cthulhu/ax_utilities_collection.py b/src/cthulhu/ax_utilities_collection.py deleted file mode 100644 index 98f4dda..0000000 --- a/src/cthulhu/ax_utilities_collection.py +++ /dev/null @@ -1,2462 +0,0 @@ -# Utilities for finding all objects that meet a certain criteria. -# -# Copyright 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-public-methods -# pylint: disable=too-many-lines - -"""Utilities for finding all objects that meet a certain criteria.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -import inspect -import time -from typing import Callable, Optional - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import debug -from .ax_collection import AXCollection -from .ax_object import AXObject -from .ax_utilities_debugging import AXUtilitiesDebugging -from .ax_utilities_relation import AXUtilitiesRelation -from .ax_utilities_role import AXUtilitiesRole -from .ax_utilities_state import AXUtilitiesState - - -class AXUtilitiesCollection: - """Utilities for finding all objects that meet a certain criteria.""" - - @staticmethod - def _apply_predicate( - matches: list[Atspi.Accessible], - pred: Callable[[Atspi.Accessible], bool] - ) -> list[Atspi.Accessible]: - if not matches: - return [] - - start = time.time() - tokens = ["AXUtilitiesCollection: Applying predicate ", pred] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - matches = list(filter(pred, matches)) - msg = f"AXUtilitiesCollection: {len(matches)} matches found in {time.time() - start:.4f}s" - debug.print_message(debug.LEVEL_INFO, msg, True) - return matches - - @staticmethod - def _find_all_with_states( - root: Atspi.Accessible, - state_list: list[Atspi.StateType], - state_match_type: Atspi.CollectionMatchType, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - if not (root and state_list): - return [] - - state_list = list(state_list) - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, state_match_type, "of:", state_list] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - rule = AXCollection.create_match_rule(states=state_list, state_match_type=state_match_type) - matches = AXCollection.get_all_matches(root, rule) - if pred is not None: - matches = AXUtilitiesCollection._apply_predicate(matches, pred) - - return matches - - @staticmethod - def _find_all_with_role( - root: Atspi.Accessible, - role_list: list[Atspi.Role], - role_match_type: Atspi.CollectionMatchType, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - if not (root and role_list): - return [] - - role_list = list(role_list) - if AXUtilitiesCollection._should_avoid_collection_for_roles(root, role_list): - return AXUtilitiesCollection._find_all_with_role_fallback( - root, role_list, role_match_type, pred) - - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, role_match_type, "of:", role_list] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - rule = AXCollection.create_match_rule(roles=role_list, role_match_type=role_match_type) - matches = AXCollection.get_all_matches(root, rule) - if pred is not None: - matches = AXUtilitiesCollection._apply_predicate(matches, pred) - - return matches - - @staticmethod - def _find_all_with_role_fallback( - root: Atspi.Accessible, - role_list: list[Atspi.Role], - role_match_type: Atspi.CollectionMatchType, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - def matchesLandmarkRole(acc, role): - if role == Atspi.Role.LANDMARK: - return True - if AXUtilitiesRole.is_landmark_banner(acc): - return True - if AXUtilitiesRole.is_landmark_complementary(acc): - return True - if AXUtilitiesRole.is_landmark_contentinfo(acc): - return True - if AXUtilitiesRole.is_landmark_form(acc): - return True - if AXUtilitiesRole.is_landmark_main(acc): - return True - if AXUtilitiesRole.is_landmark_navigation(acc): - return True - if AXUtilitiesRole.is_landmark_region(acc): - return True - if AXUtilitiesRole.is_landmark_search(acc): - return True - return AXUtilitiesRole.is_dpub(acc) - - def role_matches(acc): - role = AXObject.get_role(acc) - matched = role in role_list - if not matched and Atspi.Role.LANDMARK in role_list: - matched = matchesLandmarkRole(acc, role) - if role_match_type == Atspi.CollectionMatchType.NONE: - matched = not matched - if not matched: - return False - if pred is None: - return True - return pred(acc) - - return AXObject.find_all_descendants(root, role_matches) - - @staticmethod - def _should_avoid_collection_for_roles( - root: Atspi.Accessible, - role_list: list[Atspi.Role] - ) -> bool: - if Atspi.Role.LANDMARK not in role_list: - return False - - toolkit_name = AXObject.get_toolkit_name(root) - if toolkit_name in {"chromium", "chrome"}: - msg = ( - "AXUtilitiesCollection: Avoiding collection interface for landmarks " - f"in Chromium-family app (toolkit={toolkit_name})." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - app = AXObject.get_application(root) - raw_name = AXObject.get_name(app) or "" - app_name = raw_name.lower() - chromium_apps = { - "brave", - "chrome", - "chromium", - "edge", - "opera", - "vivaldi", - } - if not any(name in app_name for name in chromium_apps): - return False - - msg = ( - "AXUtilitiesCollection: Avoiding collection interface for landmarks " - f"in Chromium-family app ({raw_name or 'unknown app'})." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def find_all_with_interfaces( - root: Atspi.Accessible, - interface_list: list[str], - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which implement all the specified interfaces""" - - if not (root and interface_list): - return [] - - interface_list = list(interface_list) - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, "all of:", interface_list] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - rule = AXCollection.create_match_rule(interfaces=interface_list) - matches = AXCollection.get_all_matches(root, rule) - if pred is not None: - matches = AXUtilitiesCollection._apply_predicate(matches, pred) - - return matches - - @staticmethod - def find_all_with_role( - root: Atspi.Accessible, - role_list: list[Atspi.Role], - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with any of the specified roles""" - - return AXUtilitiesCollection._find_all_with_role( - root, role_list, Atspi.CollectionMatchType.ANY, pred) - - @staticmethod - def find_all_without_roles( - root: Atspi.Accessible, - role_list: list[Atspi.Role], - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which have none of the specified roles""" - - return AXUtilitiesCollection._find_all_with_role( - root, role_list, Atspi.CollectionMatchType.NONE, pred) - - @staticmethod - def find_all_with_role_and_all_states( - root: Atspi.Accessible, - role_list: list[Atspi.Role], - state_list: list[Atspi.StateType], - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with any of the roles, and all the states""" - - if not (root and role_list and state_list): - return [] - - role_list = list(role_list) - state_list = list(state_list) - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, "Roles:", role_list, "States:", state_list] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - rule = AXCollection.create_match_rule( - roles=role_list, role_match_type=Atspi.CollectionMatchType.ANY, - states=state_list, state_match_type=Atspi.CollectionMatchType.ALL) - matches = AXCollection.get_all_matches(root, rule) - if pred is not None: - matches = AXUtilitiesCollection._apply_predicate(matches, pred) - - return matches - - @staticmethod - def find_all_with_role_and_any_state( - root: Atspi.Accessible, - role_list: list[Atspi.Role], - state_list: list[Atspi.StateType], - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with any of the roles, and any of the states""" - - if not (root and role_list and state_list): - return [] - - role_list = list(role_list) - state_list = list(state_list) - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, "Roles:", role_list, "States:", state_list] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - rule = AXCollection.create_match_rule( - roles=role_list, role_match_type=Atspi.CollectionMatchType.ANY, - states=state_list, state_match_type=Atspi.CollectionMatchType.ANY) - matches = AXCollection.get_all_matches(root, rule) - if pred is not None: - matches = AXUtilitiesCollection._apply_predicate(matches, pred) - - return matches - - @staticmethod - def find_all_with_role_without_states( - root: Atspi.Accessible, - role_list: list[Atspi.Role], - state_list: list[Atspi.StateType], - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with any of the roles, and none of the states""" - - if not (root and role_list and state_list): - return [] - - role_list = list(role_list) - state_list = list(state_list) - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, "Roles:", role_list, "States:", state_list] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - rule = AXCollection.create_match_rule( - roles=role_list, role_match_type=Atspi.CollectionMatchType.ANY, - states=state_list, state_match_type=Atspi.CollectionMatchType.NONE) - matches = AXCollection.get_all_matches(root, rule) - if pred is not None: - matches = AXUtilitiesCollection._apply_predicate(matches, pred) - - return matches - - @staticmethod - def find_all_with_states( - root: Atspi.Accessible, - state_list: list[Atspi.StateType], - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which have all of the specified states""" - - return AXUtilitiesCollection._find_all_with_states( - root, state_list, Atspi.CollectionMatchType.ALL, pred) - - @staticmethod - def find_all_with_any_state( - root: Atspi.Accessible, - state_list: list[Atspi.StateType], - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which have any of the specified states""" - - return AXUtilitiesCollection._find_all_with_states( - root, state_list, Atspi.CollectionMatchType.ANY, pred) - - @staticmethod - def find_all_without_states( - root: Atspi.Accessible, - state_list: list[Atspi.StateType], - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which have none of the specified states""" - - return AXUtilitiesCollection._find_all_with_states( - root, state_list, Atspi.CollectionMatchType.NONE, pred) - - @staticmethod - def find_all_accelerator_labels( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the accelerator label role""" - - roles = [Atspi.Role.ACCELERATOR_LABEL] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_alerts( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the alert role""" - - roles = [Atspi.Role.ALERT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_animations( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the animation role""" - - roles = [Atspi.Role.ANIMATION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_arrows( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the arrow role""" - - roles = [Atspi.Role.ARROW] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_articles( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the article role""" - - roles = [Atspi.Role.ARTICLE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_audios( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the audio role""" - - roles = [Atspi.Role.AUDIO] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_autocompletes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the autocomplete role""" - - roles = [Atspi.Role.AUTOCOMPLETE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_block_quotes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the block quote role""" - - roles = [Atspi.Role.BLOCK_QUOTE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_buttons( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the push- or toggle-button role""" - - roles = [Atspi.Role.BUTTON, Atspi.Role.TOGGLE_BUTTON] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_calendars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the calendar role""" - - roles = [Atspi.Role.CALENDAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_canvases( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the canvas role""" - - roles = [Atspi.Role.CANVAS] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_captions( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the caption role""" - - roles = [Atspi.Role.CAPTION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_charts( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the chart role""" - - roles = [Atspi.Role.CHART] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_check_boxes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the checkbox role""" - - roles = [Atspi.Role.CHECK_BOX] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_check_menu_items( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the check menuitem role""" - - roles = [Atspi.Role.CHECK_MENU_ITEM] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_clickables( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all non-focusable descendants of root which support the click action""" - - if root is None: - return [] - - interfaces = ["Action"] - states = [Atspi.StateType.FOCUSABLE] - state_match_type = Atspi.CollectionMatchType.NONE - roles = AXUtilitiesRole.get_roles_to_exclude_from_clickables_list() - roles_match_type = Atspi.CollectionMatchType.NONE - attributes = ["xml-roles:gridcell"] - attribute_match_type = Atspi.CollectionMatchType.NONE - - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, roles_match_type, "of:", roles, ". pred:", pred] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - def is_match(obj): - result = AXObject.has_action(obj, "click") - tokens = ["AXUtilitiesCollection:", obj, AXUtilitiesDebugging.actions_as_string(obj), - "has click Action:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if not result: - return False - return pred is None or pred(obj) - - rule = AXCollection.create_match_rule( - interfaces=interfaces, - attributes=attributes, - attribute_match_type=attribute_match_type, - roles=roles, - role_match_type=roles_match_type, - states=states, - state_match_type=state_match_type) - matches = AXCollection.get_all_matches(root, rule) - matches = AXUtilitiesCollection._apply_predicate(matches, is_match) - return matches - - @staticmethod - def find_all_color_choosers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the color_chooser role""" - - roles = [Atspi.Role.COLOR_CHOOSER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_column_headers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the column header role""" - - roles = [Atspi.Role.COLUMN_HEADER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_combo_boxes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the combobox role""" - - roles = [Atspi.Role.COMBO_BOX] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_comments( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the comment role""" - - roles = [Atspi.Role.COMMENT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_content_deletions( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the content deletion role""" - - roles = [Atspi.Role.CONTENT_DELETION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_content_insertions( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the content insertion role""" - - roles = [Atspi.Role.CONTENT_INSERTION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_date_editors( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the date editor role""" - - roles = [Atspi.Role.DATE_EDITOR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_definitions( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the definition role""" - - roles = [Atspi.Role.DEFINITION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_description_lists( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the description list role""" - - roles = [Atspi.Role.DESCRIPTION_LIST] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_description_terms( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the description term role""" - - roles = [Atspi.Role.DESCRIPTION_TERM] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_description_values( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the description value role""" - - roles = [Atspi.Role.DESCRIPTION_VALUE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_desktop_frames( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the desktop frame role""" - - roles = [Atspi.Role.DESKTOP_FRAME] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_desktop_icons( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the desktop icon role""" - - roles = [Atspi.Role.DESKTOP_ICON] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_dials( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the dial role""" - - roles = [Atspi.Role.DIAL] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_dialogs( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the dialog role""" - - roles = [Atspi.Role.DIALOG] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_dialogs_and_alerts( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that has any dialog or alert role""" - - roles = AXUtilitiesRole.get_dialog_roles(True) - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_directory_panes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the directory pane role""" - - roles = [Atspi.Role.DIRECTORY_PANE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_documents( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that has any document-related role""" - - roles = AXUtilitiesRole.get_document_roles() - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_document_emails( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the document email role""" - - roles = [Atspi.Role.DOCUMENT_EMAIL] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_document_frames( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the document frame role""" - - roles = [Atspi.Role.DOCUMENT_FRAME] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_document_presentations( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the document presentation role""" - - roles = [Atspi.Role.DOCUMENT_PRESENTATION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_document_spreadsheets( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the document spreadsheet role""" - - roles = [Atspi.Role.DOCUMENT_SPREADSHEET] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_document_texts( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the document text role""" - - roles = [Atspi.Role.DOCUMENT_TEXT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_document_webs( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the document web role""" - - roles = [Atspi.Role.DOCUMENT_WEB] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_drawing_areas( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the drawing area role""" - - roles = [Atspi.Role.DRAWING_AREA] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_editable_objects( - root: Atspi.Accessible, - must_be_focusable: bool = True, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which are editable""" - - states = [Atspi.StateType.EDITABLE] - if must_be_focusable: - states.append(Atspi.StateType.FOCUSABLE) - return AXUtilitiesCollection.find_all_with_states(root, states, pred) - - @staticmethod - def find_all_editbars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the editbar role""" - - roles = [Atspi.Role.EDITBAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_embeddeds( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the embedded role""" - - roles = [Atspi.Role.EMBEDDED] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_entries( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the entry role""" - - roles = [Atspi.Role.ENTRY] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_extendeds( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the extended role""" - - roles = [Atspi.Role.EXTENDED] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_file_choosers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the file chooser role""" - - roles = [Atspi.Role.FILE_CHOOSER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_fillers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the filler role""" - - roles = [Atspi.Role.FILLER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_focusable_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which are focusable""" - - states = [Atspi.StateType.FOCUSABLE] - return AXUtilitiesCollection.find_all_with_states(root, states, pred) - - @staticmethod - def find_all_focusable_objects_with_click_ancestor( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all focusable descendants of root which support the click-ancestor action""" - - if root is None: - return [] - - interfaces = ["Action"] - states = [Atspi.StateType.FOCUSABLE] - state_match_type = Atspi.CollectionMatchType.ANY - roles = AXUtilitiesRole.get_roles_to_exclude_from_clickables_list() - roles_match_type = Atspi.CollectionMatchType.NONE - - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, roles_match_type, "of:", roles, ". pred:", pred] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - def is_match(obj): - result = AXObject.has_action(obj, "click-ancestor") - tokens = ["AXUtilitiesCollection:", obj, AXUtilitiesDebugging.actions_as_string(obj), - "has click-ancestor Action:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if not result: - return False - return pred is None or pred(obj) - - rule = AXCollection.create_match_rule( - interfaces=interfaces, - roles=roles, - role_match_type=roles_match_type, - states=states, - state_match_type=state_match_type) - matches = AXCollection.get_all_matches(root, rule) - matches = AXUtilitiesCollection._apply_predicate(matches, is_match) - return matches - - @staticmethod - def find_all_focused_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which are focused""" - - states = [Atspi.StateType.FOCUSED] - return AXUtilitiesCollection.find_all_with_states(root, states, pred) - - @staticmethod - def find_all_focus_traversables( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the focus traversable role""" - - roles = [Atspi.Role.FOCUS_TRAVERSABLE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_font_choosers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the font chooser role""" - - roles = [Atspi.Role.FONT_CHOOSER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_footers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the footer role""" - - roles = [Atspi.Role.FOOTER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_footnotes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the footnote role""" - - roles = [Atspi.Role.FOOTNOTE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_forms( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the form role""" - - roles = [Atspi.Role.FORM] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_form_fields( - root: Atspi.Accessible, - must_be_focusable: bool = True, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with a form-field-related role""" - - roles = AXUtilitiesRole.get_form_field_roles() - if not must_be_focusable: - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - states = [Atspi.StateType.FOCUSABLE] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_frames( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the frame role""" - - roles = [Atspi.Role.FRAME] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_glass_panes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the glass pane role""" - - roles = [Atspi.Role.GLASS_PANE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_grids( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that are grids""" - - if root is None: - return [] - - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, "pred:", pred] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - roles = [Atspi.Role.TABLE] - attributes = ["xml-roles:grid"] - rule = AXCollection.create_match_rule(roles=roles, attributes=attributes) - grids = AXCollection.get_all_matches(root, rule) - if pred is not None: - AXUtilitiesCollection._apply_predicate(grids, pred) - - return grids - - @staticmethod - def find_all_grid_cells( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that are grid cells""" - - if root is None: - return [] - - grids = AXUtilitiesCollection.find_all_grids(root, pred) - if not grids: - return [] - - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, "pred:", pred] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - cells = [] - for grid in grids: - cells.extend(AXUtilitiesCollection.find_all_table_cells(grid)) - - if pred is not None: - AXUtilitiesCollection._apply_predicate(cells, pred) - - return cells - - @staticmethod - def find_all_groupings( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the grouping role""" - - roles = [Atspi.Role.GROUPING] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_headers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the header role""" - - roles = [Atspi.Role.HEADER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_headings( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the heading role""" - - roles = [Atspi.Role.HEADING] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_headings_at_level( - root: Atspi.Accessible, - level: int, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the heading role""" - - if root is None: - return [] - - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, "Level:", level, "pred:", pred] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - roles = [Atspi.Role.HEADING] - attributes = [f"level:{level}"] - rule = AXCollection.create_match_rule(roles=roles, attributes=attributes) - matches = AXCollection.get_all_matches(root, rule) - if pred is not None: - matches = AXUtilitiesCollection._apply_predicate(matches, pred) - return matches - - @staticmethod - def find_all_html_containers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the html container role""" - - roles = [Atspi.Role.HTML_CONTAINER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_horizontal_scrollbars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that is a horizontal scrollbar""" - - roles = [Atspi.Role.SCROLL_BAR] - states = [Atspi.StateType.HORIZONTAL] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_horizontal_separators( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that is a horizontal separator""" - - roles = [Atspi.Role.SEPARATOR] - states = [Atspi.StateType.HORIZONTAL] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_horizontal_sliders( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that is a horizontal slider""" - - roles = [Atspi.Role.SLIDER] - states = [Atspi.StateType.HORIZONTAL] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_icons( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the icon role""" - - roles = [Atspi.Role.ICON] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_icons_and_canvases( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the icon or canvas role""" - - roles = [Atspi.Role.ICON, Atspi.Role.CANVAS] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_images( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the image role""" - - roles = [Atspi.Role.IMAGE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_images_and_canvases( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the image or canvas role""" - - roles = [Atspi.Role.IMAGE, Atspi.Role.CANVAS] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_images_and_image_maps( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the image or image map role""" - - roles = [Atspi.Role.IMAGE, Atspi.Role.IMAGE_MAP] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_image_maps( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the image map role""" - - roles = [Atspi.Role.IMAGE_MAP] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_info_bars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the info bar role""" - - roles = [Atspi.Role.INFO_BAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_input_method_windows( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the input method window role""" - - roles = [Atspi.Role.INPUT_METHOD_WINDOW] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_internal_frames( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the internal frame role""" - - roles = [Atspi.Role.INTERNAL_FRAME] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_labels( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the label role""" - - roles = [Atspi.Role.LABEL] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_labels_and_captions( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the label or caption role""" - - roles = [Atspi.Role.LABEL, Atspi.Role.CAPTION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_landmarks( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the landmark role""" - - roles = [Atspi.Role.LANDMARK] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_large_containers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that we consider a large container""" - - roles = AXUtilitiesRole.get_large_container_roles() - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_layered_panes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the layered pane role""" - - roles = [Atspi.Role.LAYERED_PANE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_level_bars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the level bar role""" - - roles = [Atspi.Role.LEVEL_BAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_links( - root: Atspi.Accessible, - must_be_focusable: bool = True, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the link role""" - - roles = [Atspi.Role.LINK] - if not must_be_focusable: - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - states = [Atspi.StateType.FOCUSABLE] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_live_regions( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that are live regions""" - - if root is None: - return [] - - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), - "Root:", root, "pred:", pred] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - attributes = [] - levels = ["off", "polite", "assertive"] - for level in levels: - attributes.append('container-live:' + level) - - rule = AXCollection.create_match_rule(attributes=attributes, - attribute_match_type=Atspi.CollectionMatchType.ANY) - matches = AXCollection.get_all_matches(root, rule) - if pred is not None: - matches = AXUtilitiesCollection._apply_predicate(matches, pred) - - return matches - - @staticmethod - def find_all_lists( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None, - include_description_lists: bool = False, - include_tab_lists: bool = False - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the list role""" - - roles = [Atspi.Role.LIST] - if include_description_lists: - roles.append(Atspi.Role.DESCRIPTION_LIST) - if include_tab_lists: - roles.append(Atspi.Role.PAGE_TAB_LIST) - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_list_boxes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the list box role""" - - roles = [Atspi.Role.LIST_BOX] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_list_items( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None, - include_description_terms: bool = False, - include_tabs: bool = False - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the list item role""" - - roles = [Atspi.Role.LIST_ITEM] - if include_description_terms: - roles.append(Atspi.Role.DESCRIPTION_TERM) - if include_tabs: - roles.append(Atspi.Role.PAGE_TAB) - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_logs( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the log role""" - - roles = [Atspi.Role.LOG] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_marks( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the mark role""" - - roles = [Atspi.Role.MARK] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_marquees( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the marquee role""" - - roles = [Atspi.Role.MARQUEE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_maths( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the math role""" - - roles = [Atspi.Role.MATH] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_math_fractions( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the math fraction role""" - - roles = [Atspi.Role.MATH_FRACTION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_math_roots( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the math root role""" - - roles = [Atspi.Role.MATH_ROOT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_menus( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the menu role""" - - roles = [Atspi.Role.MENU] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_menu_bars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the menubar role""" - - roles = [Atspi.Role.MENU_BAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_menu_items( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the menu item role""" - - roles = [Atspi.Role.MENU_ITEM] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_menu_items_of_any_kind( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that has any menu item role""" - - roles = AXUtilitiesRole.get_menu_item_roles() - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_menu_related_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that has any menu-related role""" - - roles = AXUtilitiesRole.get_menu_related_roles() - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_modal_dialogs( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the alert or dialog role and modal state""" - - roles = AXUtilitiesRole.get_dialog_roles(True) - states = [Atspi.StateType.MODAL] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_multi_line_entries( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the entry role and multiline state""" - - roles = [Atspi.Role.ENTRY] - states = [Atspi.StateType.MULTI_LINE] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_notifications( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the notification role""" - - roles = [Atspi.Role.NOTIFICATION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_option_panes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the option pane role""" - - roles = [Atspi.Role.OPTION_PANE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_pages( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the page role""" - - roles = [Atspi.Role.PAGE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_page_tabs( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the page tab role""" - - roles = [Atspi.Role.PAGE_TAB] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_page_tab_lists( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the page tab list role""" - - roles = [Atspi.Role.PAGE_TAB_LIST] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_page_tab_list_related_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the page tab or page tab list role""" - - roles = [Atspi.Role.PAGE_TAB_LIST, Atspi.Role.PAGE_TAB] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_panels( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the panel role""" - - roles = [Atspi.Role.PANEL] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_paragraphs( - root: Atspi.Accessible, - treat_headings_as_paragraphs: bool = False, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the paragraph role""" - - roles = [Atspi.Role.PARAGRAPH] - if treat_headings_as_paragraphs: - roles.append(Atspi.Role.HEADING) - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_password_texts( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the password text role""" - - roles = [Atspi.Role.PASSWORD_TEXT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_popup_menus( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the popup menu role""" - - roles = [Atspi.Role.POPUP_MENU] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_progress_bars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the progress bar role""" - - roles = [Atspi.Role.PROGRESS_BAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_push_buttons( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the push button role""" - - roles = [Atspi.Role.BUTTON] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_push_button_menus( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the push button menu role""" - - roles = [Atspi.Role.PUSH_BUTTON_MENU] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_radio_buttons( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the radio button role""" - - roles = [Atspi.Role.RADIO_BUTTON] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_radio_menu_items( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the radio menu item role""" - - roles = [Atspi.Role.RADIO_MENU_ITEM] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_ratings( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the rating role""" - - roles = [Atspi.Role.RATING] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_root_panes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the root pane role""" - - roles = [Atspi.Role.ROOT_PANE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_row_headers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the row header role""" - - roles = [Atspi.Role.ROW_HEADER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_rulers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the ruler role""" - - roles = [Atspi.Role.RULER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_scroll_bars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the scrollbar role""" - - roles = [Atspi.Role.SCROLL_BAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_scroll_panes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the scroll pane role""" - - roles = [Atspi.Role.SCROLL_PANE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_sections( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the section role""" - - roles = [Atspi.Role.SECTION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_selectable_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which are selectable""" - - states = [Atspi.StateType.SELECTABLE] - return AXUtilitiesCollection.find_all_with_states(root, states, pred) - - @staticmethod - def find_all_selected_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which are selected""" - - states = [Atspi.StateType.SELECTED] - return AXUtilitiesCollection.find_all_with_states(root, states, pred) - - @staticmethod - def find_all_separators( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the separator role""" - - roles = [Atspi.Role.SEPARATOR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_set_containers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with a set container role""" - - roles = AXUtilitiesRole.get_set_container_roles() - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_showing_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which are showing""" - - states = [Atspi.StateType.SHOWING] - return AXUtilitiesCollection.find_all_with_states(root, states, pred) - - @staticmethod - def find_all_showing_and_visible_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which are showing and visible""" - - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE] - return AXUtilitiesCollection.find_all_with_states(root, states, pred) - - @staticmethod - def find_all_showing_or_visible_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which are showing or visible""" - - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE] - return AXUtilitiesCollection.find_all_with_any_state(root, states, pred) - - @staticmethod - def find_all_single_line_entries( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the entry role and multiline state""" - - roles = [Atspi.Role.ENTRY] - states = [Atspi.StateType.SINGLE_LINE] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_sliders( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the slider role""" - - roles = [Atspi.Role.SLIDER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_spin_buttons( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the spin button role""" - - roles = [Atspi.Role.SPIN_BUTTON] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_split_panes( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the split pane role""" - - roles = [Atspi.Role.SPLIT_PANE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_statics( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the static role""" - - roles = [Atspi.Role.STATIC] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_status_bars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the statusbar role""" - - roles = [Atspi.Role.STATUS_BAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_subscripts( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the subscript role""" - - roles = [Atspi.Role.SUBSCRIPT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_subscripts_and_superscripts( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the subscript or superscript role""" - - roles = [Atspi.Role.SUBSCRIPT, Atspi.Role.SUPERSCRIPT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_suggestions( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the suggestion role""" - - roles = [Atspi.Role.SUGGESTION] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_superscripts( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the superscript role""" - - roles = [Atspi.Role.SUPERSCRIPT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_supports_action( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the action interface""" - - interfaces = ["Action"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_supports_document( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the document interface""" - - interfaces = ["Document"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_supports_editable_text( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the editable text interface""" - - interfaces = ["EditableText"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_supports_hypertext( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the hypertext interface""" - - interfaces = ["Hypertext"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_supports_hyperlink( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the hyperlink interface""" - - interfaces = ["Hyperlink"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_supports_selection( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the selection interface""" - - interfaces = ["Selection"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_supports_table( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the table interface""" - - interfaces = ["Table"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_supports_table_cell( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the table cell interface""" - - interfaces = ["TableCell"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_supports_text( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the text interface""" - - interfaces = ["Text"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_supports_value( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which support the value interface""" - - interfaces = ["Value"] - return AXUtilitiesCollection.find_all_with_interfaces(root, interfaces, pred) - - @staticmethod - def find_all_tables( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the table role""" - - if root is None: - return [] - - tokens = ["AXUtilitiesCollection:", inspect.currentframe(), "Root:", root, "pred:", pred] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - roles = [Atspi.Role.TABLE] - attributes = ["layout-guess:true"] - attribute_match_type = Atspi.CollectionMatchType.NONE - rule = AXCollection.create_match_rule( - roles=roles, - attributes=attributes, - attribute_match_type=attribute_match_type) - - tables = AXCollection.get_all_matches(root, rule) - if pred is not None: - AXUtilitiesCollection._apply_predicate(tables, pred) - - return tables - - @staticmethod - def find_all_table_cells( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the table cell role""" - - roles = [Atspi.Role.TABLE_CELL] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_table_cells_and_headers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the table cell or a header-related role""" - - roles = AXUtilitiesRole.get_table_cell_roles() - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_table_column_headers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the table column header role""" - - roles = [Atspi.Role.TABLE_COLUMN_HEADER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_table_headers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that has a table header related role""" - - roles = AXUtilitiesRole.get_table_header_roles() - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_table_related_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None, - include_caption: bool = False - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that has a table related role""" - - roles = AXUtilitiesRole.get_table_related_roles(include_caption) - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_table_rows( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the table row role""" - - roles = [Atspi.Role.TABLE_ROW] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_table_row_headers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the table row header role""" - - roles = [Atspi.Role.TABLE_ROW_HEADER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_tearoff_menu_items( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the tearoff menu item role""" - - roles = [Atspi.Role.TEAROFF_MENU_ITEM] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_terminals( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the terminal role""" - - roles = [Atspi.Role.TERMINAL] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_texts( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the text role""" - - roles = [Atspi.Role.TEXT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_text_inputs( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that has any role associated with textual input""" - - roles = [Atspi.Role.ENTRY, Atspi.Role.PASSWORD_TEXT, Atspi.Role.SPIN_BUTTON] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_timers( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the timer role""" - - roles = [Atspi.Role.TIMER] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_title_bars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the titlebar role""" - - roles = [Atspi.Role.TITLE_BAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_toggle_buttons( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the toggle button role""" - - roles = [Atspi.Role.TOGGLE_BUTTON] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_tool_bars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the toolbar role""" - - roles = [Atspi.Role.TOOL_BAR] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_tool_tips( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the tooltip role""" - - roles = [Atspi.Role.TOOL_TIP] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_trees( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the tree role""" - - roles = [Atspi.Role.TREE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_trees_and_tree_tables( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the tree or tree table role""" - - roles = [Atspi.Role.TREE, Atspi.Role.TREE_TABLE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_tree_related_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that has a tree related role""" - - roles = AXUtilitiesRole.get_tree_related_roles() - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_tree_items( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the tree item role""" - - roles = [Atspi.Role.TREE_ITEM] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_tree_tables( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the tree table role""" - - roles = [Atspi.Role.TREE_TABLE] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_unrelated_labels( - root: Atspi.Accessible, - must_be_showing: bool = True, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all the descendants of root that have a label role, but no relations""" - - def _pred(obj): - if not AXUtilitiesRelation.object_is_unrelated(obj): - return False - if pred is not None: - return pred(obj) - return True - - roles = [Atspi.Role.LABEL, Atspi.Role.STATIC] - if not must_be_showing: - matches = AXUtilitiesCollection.find_all_with_role(root, roles, _pred) - else: - states = [Atspi.StateType.SHOWING] - matches = AXUtilitiesCollection.find_all_with_role_and_all_states( - root, roles, states, _pred) - - return matches - - @staticmethod - def find_all_unvisited_links( - root: Atspi.Accessible, - must_be_focusable: bool = True, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the link role and without the visited state""" - - roles = [Atspi.Role.LINK] - states = [Atspi.StateType.VISITED] - result = AXUtilitiesCollection.find_all_with_role_without_states(root, roles, states, pred) - if must_be_focusable: - result = list(filter(AXUtilitiesState.is_focusable, result)) - return result - - @staticmethod - def find_all_vertical_scrollbars( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that is a vertical scrollbar""" - - roles = [Atspi.Role.SCROLL_BAR] - states = [Atspi.StateType.VERTICAL] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_vertical_separators( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that is a vertical separator""" - - roles = [Atspi.Role.SEPARATOR] - states = [Atspi.StateType.VERTICAL] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_vertical_sliders( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root that is a vertical slider""" - - roles = [Atspi.Role.SLIDER] - states = [Atspi.StateType.VERTICAL] - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_all_visible_objects( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root which are visible""" - - states = [Atspi.StateType.VISIBLE] - return AXUtilitiesCollection.find_all_with_states(root, states, pred) - - @staticmethod - def find_all_videos( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the video role""" - - roles = [Atspi.Role.VIDEO] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_viewports( - root: Atspi.Accessible, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the viewport role""" - - roles = [Atspi.Role.VIEWPORT] - return AXUtilitiesCollection.find_all_with_role(root, roles, pred) - - @staticmethod - def find_all_visited_links( - root: Atspi.Accessible, - must_be_focusable: bool = True, - pred: Optional[Callable[[Atspi.Accessible], bool]] = None - ) -> list[Atspi.Accessible]: - """Returns all descendants of root with the link role and focused and visited states""" - - roles = [Atspi.Role.LINK] - states = [Atspi.StateType.VISITED] - if must_be_focusable: - states.append(Atspi.StateType.FOCUSABLE) - return AXUtilitiesCollection.find_all_with_role_and_all_states(root, roles, states, pred) - - @staticmethod - def find_default_button(root: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the default button inside root""" - - roles = [Atspi.Role.BUTTON] - states = [Atspi.StateType.IS_DEFAULT] - rule = AXCollection.create_match_rule(roles=roles, states=states) - return AXCollection.get_first_match(root, rule) - - @staticmethod - def find_focused_object(root: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the focused object inside root""" - - states = [Atspi.StateType.FOCUSED] - rule = AXCollection.create_match_rule(states=states) - return AXCollection.get_first_match(root, rule) - - @staticmethod - def find_info_bar(root: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the info bar inside root""" - - roles = [Atspi.Role.INFO_BAR] - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE] - rule = AXCollection.create_match_rule(roles=roles, states=states) - return AXCollection.get_first_match(root, rule) - - @staticmethod - def find_status_bar(root: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Returns the status bar inside root""" - - roles = [Atspi.Role.STATUS_BAR] - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE] - rule = AXCollection.create_match_rule(roles=roles, states=states) - return AXCollection.get_first_match(root, rule) - - @staticmethod - def has_combo_box_or_list_box(root: Atspi.Accessible) -> bool: - """Returns True if there's a showing, visible combobox or listbox inside root""" - - roles = [Atspi.Role.COMBO_BOX, Atspi.Role.LIST_BOX] - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE] - rule = AXCollection.create_match_rule(roles=roles, - role_match_type=Atspi.CollectionMatchType.ANY, - states=states) - return bool(AXCollection.get_first_match(root, rule)) - - @staticmethod - def has_editable_object(root: Atspi.Accessible) -> bool: - """Returns True if there's a showing, visible, editable object inside root""" - - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE, Atspi.StateType.EDITABLE] - rule = AXCollection.create_match_rule(states=states) - return bool(AXCollection.get_first_match(root, rule)) - - @staticmethod - def has_scroll_pane(root: Atspi.Accessible) -> bool: - """Returns True if there's a showing, visible scroll pane inside root""" - - roles = [Atspi.Role.SCROLL_PANE] - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE] - rule = AXCollection.create_match_rule(roles=roles, - role_match_type=Atspi.CollectionMatchType.ANY, - states=states) - return bool(AXCollection.get_first_match(root, rule)) - - @staticmethod - def has_split_pane(root: Atspi.Accessible) -> bool: - """Returns True if there's a showing, visible split pane inside root""" - - roles = [Atspi.Role.SPLIT_PANE] - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE] - rule = AXCollection.create_match_rule(roles=roles, states=states) - return bool(AXCollection.get_first_match(root, rule)) - - @staticmethod - def has_tree_or_tree_table(root: Atspi.Accessible) -> bool: - """Returns True if there's a showing, visible tree or tree table inside root""" - - roles = [Atspi.Role.TREE, Atspi.Role.TREE_TABLE] - states = [Atspi.StateType.SHOWING, Atspi.StateType.VISIBLE] - rule = AXCollection.create_match_rule(roles=roles, - role_match_type=Atspi.CollectionMatchType.ANY, - states=states) - return bool(AXCollection.get_first_match(root, rule)) diff --git a/src/cthulhu/ax_utilities_debugging.py b/src/cthulhu/ax_utilities_debugging.py deleted file mode 100644 index 3bb1dde..0000000 --- a/src/cthulhu/ax_utilities_debugging.py +++ /dev/null @@ -1,285 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2024 Igalia, S.L. -# Copyright 2024 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-branches -# pylint: disable=too-many-public-methods -# pylint: disable=too-many-return-statements - -"""Utilities for obtaining accessibility information for debugging.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Igalia, S.L." \ - "Copyright (c) 2024 GNOME Foundation Inc." -__license__ = "LGPL" - -import inspect -import pprint -import types -from typing import Any - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from .ax_object import AXObject -from .ax_utilities_application import AXUtilitiesApplication -from .ax_utilities_relation import AXUtilitiesRelation - - -class AXUtilitiesDebugging: - """Utilities for obtaining accessibility information for debugging.""" - - @staticmethod - def _format_string(string: str = "") -> str: - if not string: - return "" - - string = string.replace("\n", "\\n").replace("\ufffc", "[OBJ]") - if len(string) < 100: - return string - - words = string.split() - string = f"{' '.join(words[:5])} ... {' '.join(words[-5:])} ({len(string)} chars.)" - return string - - @staticmethod - def as_string(obj: Any) -> str: - """Turns obj into a human-consumable string.""" - - if isinstance(obj, Atspi.Accessible): - result = AXObject.get_role_name(obj) - name = AXObject.get_name(obj) - if name: - result += f": '{AXUtilitiesDebugging._format_string(name)}'" - if not result: - result = "DEAD" - - return f"[{result} ({hex(id(obj))})] " - - if isinstance(obj, Atspi.Event): - any_data = AXUtilitiesDebugging._format_string( - AXUtilitiesDebugging.as_string(obj.any_data)) - return ( - f"{obj.type} for {AXUtilitiesDebugging.as_string(obj.source)} in " - f"{AXUtilitiesApplication.application_as_string(obj.source)} " - f"({obj.detail1}, {obj.detail2}, {any_data})" - ) - - if isinstance(obj, (Atspi.Role, Atspi.StateType, Atspi.CollectionMatchType, - Atspi.TextGranularity, Atspi.ScrollType)): - return obj.value_nick - - if isinstance(obj, Atspi.Rect): - return f"(x:{obj.x}, y:{obj.y}, width:{obj.width}, height:{obj.height})" - - if isinstance(obj, (list, set)): - return f"[{', '.join(map(AXUtilitiesDebugging.as_string, obj))}]" - - if isinstance(obj, dict): - stringified = {key: AXUtilitiesDebugging.as_string(value) for key, value in obj.items()} - formatter = pprint.PrettyPrinter(width=150) - return f"{formatter.pformat(stringified)}" - - if isinstance(obj, types.FunctionType): - if hasattr(obj, "__self__"): - return f"{obj.__module__}.{obj.__self__.__class__.__name__}.{obj.__name__}" - return f"{obj.__module__}.{obj.__name__}" - - if isinstance(obj, types.MethodType): - if hasattr(obj, "__self__"): - return f"{obj.__self__.__class__.__name__}.{obj.__name__}" - return f"{obj.__name__}" - - if isinstance(obj, types.FrameType): - module_name = inspect.getmodulename(obj.f_code.co_filename) - return f"{module_name}.{obj.f_code.co_name}" - - if isinstance(obj, inspect.FrameInfo): - module_name = inspect.getmodulename(obj.filename) or "" - return f"{module_name}.{obj.function}:{obj.lineno}" - - return str(obj) - - @staticmethod - def actions_as_string(obj: Atspi.Accessible) -> str: - """Returns information about the actions as a string.""" - - results = [] - for i in range(AXObject.get_n_actions(obj)): - result = AXObject.get_action_name(obj, i) - keybinding = AXObject.get_action_key_binding(obj, i) - if keybinding: - result += f" ({keybinding})" - results.append(result) - - return "; ".join(results) - - @staticmethod - def attributes_as_string(obj: Atspi.Accessible) -> str: - """Returns the object attributes of obj as a string.""" - - def as_string(attribute): - return f"{attribute[0]}:{attribute[1]}" - - return ", ".join(map(as_string, AXObject.get_attributes_dict(obj).items())) - - @staticmethod - def interfaces_as_string(obj: Atspi.Accessible) -> str: - """Returns the supported interfaces of obj as a string.""" - - if not AXObject.is_valid(obj): - return "" - - iface_checks = [ - (AXObject.supports_action, "Action"), - (AXObject.supports_collection, "Collection"), - (AXObject.supports_component, "Component"), - (AXObject.supports_document, "Document"), - (AXObject.supports_editable_text, "EditableText"), - (AXObject.supports_hyperlink, "Hyperlink"), - (AXObject.supports_hypertext, "Hypertext"), - (AXObject.supports_image, "Image"), - (AXObject.supports_selection, "Selection"), - (AXObject.supports_table, "Table"), - (AXObject.supports_table_cell, "TableCell"), - (AXObject.supports_text, "Text"), - (AXObject.supports_value, "Value"), - ] - - ifaces = [iface for check, iface in iface_checks if check(obj)] - return ", ".join(ifaces) - - @staticmethod - def relations_as_string(obj: Atspi.Accessible) -> str: - """Returns the relations associated with obj as a string.""" - - if not AXObject.is_valid(obj): - return "" - - def as_string(relations): - return relations.value_name[15:].replace("_", "-").lower() - - def obj_as_string(acc): - result = AXObject.get_role_name(acc) - name = AXObject.get_name(acc) - if name: - result += f": '{name}'" - if not result: - result = "DEAD" - return f"[{result}]" - - results = [] - for rel in AXUtilitiesRelation.get_relations(obj): - type_string = as_string(rel.get_relation_type()) - targets = AXUtilitiesRelation.get_relation_targets_for_debugging( - obj, rel.get_relation_type()) - target_string = ",".join(map(obj_as_string, targets)) - results.append(f"{type_string}: {target_string}") - - return "; ".join(results) - - @staticmethod - def state_set_as_string(obj: Atspi.Accessible) -> str: - """Returns the state set associated with obj as a string.""" - - if not AXObject.is_valid(obj): - return "" - - def as_string(state): - return state.value_name[12:].replace("_", "-").lower() - - return ", ".join(map(as_string, AXObject.get_state_set(obj).get_states())) - - @staticmethod - def text_for_debugging(obj: Atspi.Accessible) -> str: - """Returns the text content of obj for debugging.""" - - if not AXObject.supports_text(obj): - return "" - - try: - result = Atspi.Text.get_text(obj, 0, Atspi.Text.get_character_count(obj)) - except GLib.GError: - return "" - - return AXUtilitiesDebugging._format_string(result) - - @staticmethod - def object_details_as_string( - obj: Atspi.Accessible, - indent: str = "", - include_app: bool = True - ) -> str: - """Returns a string, suitable for printing, that describes details about obj.""" - - if not isinstance(obj, Atspi.Accessible): - return "" - - if AXObject.is_dead(obj): - return "(exception fetching data)" - - if include_app: - string = f"{indent}app='{AXUtilitiesApplication.application_as_string(obj)}' " - else: - string = indent - - name = AXUtilitiesDebugging._format_string(AXObject.get_name(obj)) - desc = AXUtilitiesDebugging._format_string(AXObject.get_description(obj)) - help_text = AXUtilitiesDebugging._format_string(AXObject.get_help_text(obj)) - obj_locale = AXObject.get_locale(obj) - ax_id = AXObject.get_accessible_id(obj) - string += ( - f"name='{name}' role='{AXObject.get_role_name(obj)}'" - f" axid='{ax_id}' id={hex(id(obj))}\n" - f"{indent}description='{desc}'\n" - f"{indent}help='{help_text}'\n" - f"{indent}locale='{obj_locale}'\n" - f"{indent}states='{AXUtilitiesDebugging.state_set_as_string(obj)}'\n" - f"{indent}relations='{AXUtilitiesDebugging.relations_as_string(obj)}'\n" - f"{indent}actions='{AXUtilitiesDebugging.actions_as_string(obj)}'\n" - f"{indent}interfaces='{AXUtilitiesDebugging.interfaces_as_string(obj)}'\n" - f"{indent}attributes='{AXUtilitiesDebugging.attributes_as_string(obj)}'\n" - f"{indent}text='{AXUtilitiesDebugging.text_for_debugging(obj)}'\n" - f"{indent}path={AXObject.get_path(obj)}" - ) - return string - - @staticmethod - def object_event_details_as_string(event: Atspi.Event, indent: str = "") -> str: - """Returns a string, suitable for printing, with details about event.""" - - if event.type.startswith("mouse:"): - return "" - - source = AXUtilitiesDebugging.object_details_as_string(event.source, indent, True) - any_data = AXUtilitiesDebugging.object_details_as_string(event.any_data, indent, False) - string = f"EVENT SOURCE:\n{source}\n" - if any_data: - string += f"\nEVENT ANY DATA:\n{any_data}\n" - return string diff --git a/src/cthulhu/ax_utilities_event.py b/src/cthulhu/ax_utilities_event.py deleted file mode 100644 index 035aaa1..0000000 --- a/src/cthulhu/ax_utilities_event.py +++ /dev/null @@ -1,838 +0,0 @@ -# Utilities for obtaining event-related information. -# -# Copyright 2024 Igalia, S.L. -# Copyright 2024 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-return-statements -# pylint: disable=too-many-branches -# pylint: disable=too-many-statements - -"""Utilities for obtaining event-related information.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Igalia, S.L." \ - "Copyright (c) 2024 GNOME Foundation Inc." -__license__ = "LGPL" - -import enum -import threading -import time - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import debug -from . import focus_manager - -from .ax_object import AXObject -from .ax_text import AXText -from .ax_utilities_role import AXUtilitiesRole -from .ax_utilities_state import AXUtilitiesState - -class TextEventReason(enum.Enum): - """Enum representing the reason for an object:text- event.""" - - UNKNOWN = enum.auto() - AUTO_DELETION = enum.auto() - AUTO_INSERTION_PRESENTABLE = enum.auto() - AUTO_INSERTION_UNPRESENTABLE = enum.auto() - BACKSPACE = enum.auto() - CHILDREN_CHANGE = enum.auto() - CUT = enum.auto() - DELETE = enum.auto() - FOCUS_CHANGE = enum.auto() - LIVE_REGION_UPDATE = enum.auto() - MOUSE_MIDDLE_BUTTON = enum.auto() - MOUSE_PRIMARY_BUTTON = enum.auto() - NAVIGATION_BY_CHARACTER = enum.auto() - NAVIGATION_BY_LINE = enum.auto() - NAVIGATION_BY_PARAGRAPH = enum.auto() - NAVIGATION_BY_PAGE = enum.auto() - NAVIGATION_BY_WORD = enum.auto() - NAVIGATION_TO_FILE_BOUNDARY = enum.auto() - NAVIGATION_TO_LINE_BOUNDARY = enum.auto() - PAGE_SWITCH = enum.auto() - PASTE = enum.auto() - REDO = enum.auto() - SAY_ALL = enum.auto() - SEARCH_PRESENTABLE = enum.auto() - SEARCH_UNPRESENTABLE = enum.auto() - SELECT_ALL = enum.auto() - SELECTED_TEXT_DELETION = enum.auto() - SELECTED_TEXT_INSERTION = enum.auto() - SELECTED_TEXT_RESTORATION = enum.auto() - SELECTION_BY_CHARACTER = enum.auto() - SELECTION_BY_LINE = enum.auto() - SELECTION_BY_PARAGRAPH = enum.auto() - SELECTION_BY_PAGE = enum.auto() - SELECTION_BY_WORD = enum.auto() - SELECTION_TO_FILE_BOUNDARY = enum.auto() - SELECTION_TO_LINE_BOUNDARY = enum.auto() - SPIN_BUTTON_VALUE_CHANGE = enum.auto() - TYPING = enum.auto() - TYPING_ECHOABLE = enum.auto() - UI_UPDATE = enum.auto() - UNDO = enum.auto() - UNSPECIFIED_COMMAND = enum.auto() - UNSPECIFIED_NAVIGATION = enum.auto() - UNSPECIFIED_SELECTION = enum.auto() - - -class AXUtilitiesEvent: - """Utilities for obtaining event-related information.""" - - LAST_KNOWN_DESCRIPTION: dict[int, str] = {} - LAST_KNOWN_NAME: dict[int, str] = {} - - LAST_KNOWN_CHECKED: dict[int, bool] = {} - LAST_KNOWN_EXPANDED: dict[int, bool] = {} - LAST_KNOWN_INDETERMINATE: dict[int, bool] = {} - LAST_KNOWN_INVALID_ENTRY: dict[int, bool] = {} - LAST_KNOWN_PRESSED: dict[int, bool] = {} - LAST_KNOWN_SELECTED: dict[int, bool] = {} - - IGNORE_NAME_CHANGES_FOR: list[int] = [] - - TEXT_EVENT_REASON: dict[Atspi.Event, TextEventReason] = {} - - _lock = threading.Lock() - - @staticmethod - def _clear_stored_data() -> None: - """Clears any data we have cached for objects""" - - while True: - time.sleep(60) - AXUtilitiesEvent._clear_all_dictionaries() - - @staticmethod - def _clear_all_dictionaries(reason: str = "") -> None: - msg = "AXUtilitiesEvent: Clearing local cache." - if reason: - msg += f" Reason: {reason}" - debug.print_message(debug.LEVEL_INFO, msg, True) - AXUtilitiesEvent.LAST_KNOWN_DESCRIPTION.clear() - AXUtilitiesEvent.LAST_KNOWN_NAME.clear() - AXUtilitiesEvent.LAST_KNOWN_CHECKED.clear() - AXUtilitiesEvent.LAST_KNOWN_EXPANDED.clear() - AXUtilitiesEvent.LAST_KNOWN_INDETERMINATE.clear() - AXUtilitiesEvent.LAST_KNOWN_INVALID_ENTRY.clear() - AXUtilitiesEvent.LAST_KNOWN_PRESSED.clear() - AXUtilitiesEvent.LAST_KNOWN_SELECTED.clear() - AXUtilitiesEvent.TEXT_EVENT_REASON.clear() - AXUtilitiesEvent.IGNORE_NAME_CHANGES_FOR.clear() - - @staticmethod - def clear_cache_now(reason: str = "") -> None: - """Clears all cached information immediately.""" - - AXUtilitiesEvent._clear_all_dictionaries(reason) - - @staticmethod - def save_object_info_for_events(obj: Atspi.Accessible) -> None: - """Saves properties, states, etc. of obj for later use in event processing.""" - - if obj is None: - return - - AXUtilitiesEvent.LAST_KNOWN_DESCRIPTION[hash(obj)] = AXObject.get_description(obj) - AXUtilitiesEvent.LAST_KNOWN_NAME[hash(obj)] = AXObject.get_name(obj) - AXUtilitiesEvent.LAST_KNOWN_CHECKED[hash(obj)] = AXUtilitiesState.is_checked(obj) - AXUtilitiesEvent.LAST_KNOWN_EXPANDED[hash(obj)] = AXUtilitiesState.is_expanded(obj) - AXUtilitiesEvent.LAST_KNOWN_INDETERMINATE[hash(obj)] = \ - AXUtilitiesState.is_indeterminate(obj) - AXUtilitiesEvent.LAST_KNOWN_PRESSED[hash(obj)] = AXUtilitiesState.is_pressed(obj) - AXUtilitiesEvent.LAST_KNOWN_SELECTED[hash(obj)] = AXUtilitiesState.is_selected(obj) - - window = focus_manager.get_manager().get_active_window() - AXUtilitiesEvent.LAST_KNOWN_NAME[hash(window)] = AXObject.get_name(window) - AXUtilitiesEvent.LAST_KNOWN_DESCRIPTION[hash(window)] = AXObject.get_description(window) - - @staticmethod - def start_cache_clearing_thread() -> None: - """Starts thread to periodically clear cached details.""" - - thread = threading.Thread(target=AXUtilitiesEvent._clear_stored_data) - thread.daemon = True - thread.start() - - @staticmethod - def get_text_event_reason(event: Atspi.Event) -> TextEventReason: - """Returns the TextEventReason for the given event.""" - - reason = AXUtilitiesEvent.TEXT_EVENT_REASON.get(event) - if reason is not None: - tokens = ["AXUtilitiesEvent: Cached reason for", event, f": {reason}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return reason - - reason = TextEventReason.UNKNOWN - if event.type.startswith("object:text-changed:insert"): - reason = AXUtilitiesEvent._get_text_insertion_event_reason(event) - elif event.type.startswith("object:text-caret-moved"): - reason = AXUtilitiesEvent._get_caret_moved_event_reason(event) - elif event.type.startswith("object:text-changed:delete"): - reason = AXUtilitiesEvent._get_text_deletion_event_reason(event) - elif event.type.startswith("object:text-selection-changed"): - reason = AXUtilitiesEvent._get_text_selection_changed_event_reason(event) - else: - raise ValueError(f"Unexpected event type: {event.type}") - - AXUtilitiesEvent.TEXT_EVENT_REASON[event] = reason - tokens = ["AXUtilitiesEvent: Reason for", event, f": {reason}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return reason - - @staticmethod - def _get_caret_moved_event_reason(event: Atspi.Event) -> TextEventReason: - """Returns the TextEventReason for the given event.""" - - from . import input_event_manager # pylint: disable=import-outside-toplevel - mgr = input_event_manager.get_manager() - - reason = TextEventReason.UNKNOWN - obj = event.source - mode, focus = focus_manager.get_manager().get_active_mode_and_object_of_interest() - if mode == focus_manager.SAY_ALL: - reason = TextEventReason.SAY_ALL - elif focus != obj and AXUtilitiesRole.is_text_input_search(focus): - if mgr.last_event_was_backspace() or mgr.last_event_was_delete(): - reason = TextEventReason.SEARCH_UNPRESENTABLE - else: - reason = TextEventReason.SEARCH_PRESENTABLE - elif mgr.last_event_was_caret_selection(): - if mgr.last_event_was_line_navigation(): - reason = TextEventReason.SELECTION_BY_LINE - elif mgr.last_event_was_word_navigation(): - reason = TextEventReason.SELECTION_BY_WORD - elif mgr.last_event_was_character_navigation(): - reason = TextEventReason.SELECTION_BY_CHARACTER - elif mgr.last_event_was_page_navigation(): - reason = TextEventReason.SELECTION_BY_PAGE - elif mgr.last_event_was_line_boundary_navigation(): - reason = TextEventReason.SELECTION_TO_LINE_BOUNDARY - elif mgr.last_event_was_file_boundary_navigation(): - reason = TextEventReason.SELECTION_TO_FILE_BOUNDARY - else: - reason = TextEventReason.UNSPECIFIED_SELECTION - elif mgr.last_event_was_caret_navigation(): - if mgr.last_event_was_line_navigation(): - reason = TextEventReason.NAVIGATION_BY_LINE - elif mgr.last_event_was_word_navigation(): - reason = TextEventReason.NAVIGATION_BY_WORD - elif mgr.last_event_was_character_navigation(): - reason = TextEventReason.NAVIGATION_BY_CHARACTER - elif mgr.last_event_was_page_navigation(): - reason = TextEventReason.NAVIGATION_BY_PAGE - elif mgr.last_event_was_line_boundary_navigation(): - reason = TextEventReason.NAVIGATION_TO_LINE_BOUNDARY - elif mgr.last_event_was_file_boundary_navigation(): - reason = TextEventReason.NAVIGATION_TO_FILE_BOUNDARY - else: - reason = TextEventReason.UNSPECIFIED_NAVIGATION - elif mgr.last_event_was_select_all(): - reason = TextEventReason.SELECT_ALL - elif mgr.last_event_was_primary_click_or_release(): - reason = TextEventReason.MOUSE_PRIMARY_BUTTON - elif mgr.last_event_was_tab_navigation(): - reason = TextEventReason.FOCUS_CHANGE - elif AXUtilitiesState.is_editable(obj) or AXUtilitiesRole.is_terminal(obj): - if mgr.last_event_was_backspace(): - reason = TextEventReason.BACKSPACE - elif mgr.last_event_was_delete(): - reason = TextEventReason.DELETE - elif mgr.last_event_was_cut(): - reason = TextEventReason.CUT - elif mgr.last_event_was_paste(): - reason = TextEventReason.PASTE - elif mgr.last_event_was_undo(): - reason = TextEventReason.UNDO - elif mgr.last_event_was_redo(): - reason = TextEventReason.REDO - elif mgr.last_event_was_page_switch(): - reason = TextEventReason.PAGE_SWITCH - elif mgr.last_event_was_command(): - reason = TextEventReason.UNSPECIFIED_COMMAND - elif mgr.last_event_was_printable_key(): - reason = TextEventReason.TYPING - elif AXObject.find_ancestor(obj, AXUtilitiesRole.children_are_presentational): - reason = TextEventReason.UI_UPDATE - return reason - - @staticmethod - def _get_text_deletion_event_reason(event: Atspi.Event) -> TextEventReason: - """Returns the TextEventReason for the given event.""" - - from . import input_event_manager # pylint: disable=import-outside-toplevel - mgr = input_event_manager.get_manager() - - reason = TextEventReason.UNKNOWN - obj = event.source - if AXObject.get_role(obj) in AXUtilitiesRole.get_text_ui_roles(): - reason = TextEventReason.UI_UPDATE - elif AXUtilitiesRole.is_live_region(obj): - reason = TextEventReason.LIVE_REGION_UPDATE - elif mgr.last_event_was_page_switch(): - reason = TextEventReason.PAGE_SWITCH - elif AXUtilitiesState.is_editable(obj) or AXUtilitiesRole.is_terminal(obj): - if mgr.last_event_was_backspace(): - reason = TextEventReason.BACKSPACE - elif mgr.last_event_was_delete(): - reason = TextEventReason.DELETE - elif mgr.last_event_was_cut(): - reason = TextEventReason.CUT - elif mgr.last_event_was_paste(): - reason = TextEventReason.PASTE - elif mgr.last_event_was_undo(): - reason = TextEventReason.UNDO - elif mgr.last_event_was_redo(): - reason = TextEventReason.REDO - elif mgr.last_event_was_command(): - reason = TextEventReason.UNSPECIFIED_COMMAND - elif mgr.last_event_was_printable_key(): - reason = TextEventReason.TYPING - elif mgr.last_event_was_up_or_down() or mgr.last_event_was_page_up_or_page_down(): - if AXUtilitiesRole.is_spin_button(obj) \ - or AXObject.find_ancestor(obj, AXUtilitiesRole.is_spin_button): - reason = TextEventReason.SPIN_BUTTON_VALUE_CHANGE - else: - reason = TextEventReason.AUTO_DELETION - if reason == TextEventReason.UNKNOWN: - selected_text, _start, _end = AXText.get_cached_selected_text(obj) - if selected_text and event.any_data.strip() == selected_text.strip(): - reason = TextEventReason.SELECTED_TEXT_DELETION - elif mgr.last_event_was_command(): - reason = TextEventReason.UNSPECIFIED_COMMAND - elif "\ufffc" in event.any_data and not event.any_data.replace("\ufffc", ""): - reason = TextEventReason.CHILDREN_CHANGE - return reason - - @staticmethod - def _get_text_insertion_event_reason(event: Atspi.Event) -> TextEventReason: - """Returns the TextEventReason for the given event.""" - - from . import input_event_manager # pylint: disable=import-outside-toplevel - mgr = input_event_manager.get_manager() - - reason = TextEventReason.UNKNOWN - obj = event.source - if AXObject.get_role(obj) in AXUtilitiesRole.get_text_ui_roles(): - reason = TextEventReason.UI_UPDATE - elif AXUtilitiesRole.is_live_region(obj): - reason = TextEventReason.LIVE_REGION_UPDATE - elif mgr.last_event_was_page_switch(): - reason = TextEventReason.PAGE_SWITCH - elif AXUtilitiesState.is_editable(obj) \ - or AXUtilitiesRole.is_terminal(obj): - selected_text, _start, _end = AXText.get_selected_text(obj) - if selected_text and event.any_data == selected_text: - reason = TextEventReason.SELECTED_TEXT_INSERTION - if mgr.last_event_was_backspace(): - reason = TextEventReason.BACKSPACE - elif mgr.last_event_was_delete(): - reason = TextEventReason.DELETE - elif mgr.last_event_was_cut(): - reason = TextEventReason.CUT - elif mgr.last_event_was_paste(): - reason = TextEventReason.PASTE - elif mgr.last_event_was_undo(): - if reason == TextEventReason.SELECTED_TEXT_INSERTION: - reason = TextEventReason.SELECTED_TEXT_RESTORATION - else: - reason = TextEventReason.UNDO - elif mgr.last_event_was_redo(): - if reason == TextEventReason.SELECTED_TEXT_INSERTION: - reason = TextEventReason.SELECTED_TEXT_RESTORATION - else: - reason = TextEventReason.REDO - elif mgr.last_event_was_command(): - reason = TextEventReason.UNSPECIFIED_COMMAND - elif mgr.last_event_was_space() and not AXUtilitiesRole.is_password_text(obj): - # Gecko inserts a newline at the offset past the space in contenteditables. - if event.any_data == "\n": - reason = TextEventReason.AUTO_INSERTION_UNPRESENTABLE - else: - reason = TextEventReason.TYPING - elif mgr.last_event_was_tab() or mgr.last_event_was_return(): - if not event.any_data.strip(): - reason = TextEventReason.TYPING - elif mgr.last_event_was_printable_key() or mgr.last_event_was_space(): - if reason == TextEventReason.SELECTED_TEXT_INSERTION: - reason = TextEventReason.AUTO_INSERTION_PRESENTABLE - else: - reason = TextEventReason.TYPING - from . import typing_echo_presenter # pylint: disable=import-outside-toplevel - presenter = typing_echo_presenter.get_presenter() - if AXUtilitiesRole.is_password_text(obj): - echo = presenter.get_key_echo_enabled() - else: - echo = presenter.get_character_echo_enabled() - if echo: - reason = TextEventReason.TYPING_ECHOABLE - elif mgr.last_event_was_middle_click() or mgr.last_event_was_middle_release(): - reason = TextEventReason.MOUSE_MIDDLE_BUTTON - elif mgr.last_event_was_up_or_down() or mgr.last_event_was_page_up_or_page_down(): - if AXUtilitiesRole.is_spin_button(obj) \ - or AXObject.find_ancestor(obj, AXUtilitiesRole.is_spin_button): - reason = TextEventReason.SPIN_BUTTON_VALUE_CHANGE - else: - reason = TextEventReason.AUTO_INSERTION_PRESENTABLE - if reason == TextEventReason.UNKNOWN: - if len(event.any_data) == 1: - pass - elif mgr.last_event_was_tab() and event.any_data != "\t": - reason = TextEventReason.AUTO_INSERTION_PRESENTABLE - elif mgr.last_event_was_return() and event.any_data != "\n": - if AXUtilitiesState.is_single_line(event.source): - # Example: The browser's address bar in response to return on a link. - reason = TextEventReason.AUTO_INSERTION_UNPRESENTABLE - else: - reason = TextEventReason.AUTO_INSERTION_PRESENTABLE - elif mgr.last_event_was_command(): - reason = TextEventReason.UNSPECIFIED_COMMAND - elif "\ufffc" in event.any_data and not event.any_data.replace("\ufffc", ""): - reason = TextEventReason.CHILDREN_CHANGE - - return reason - - @staticmethod - def _get_text_selection_changed_event_reason(event: Atspi.Event) -> TextEventReason: - """Returns the TextEventReason for the given event.""" - - from . import input_event_manager # pylint: disable=import-outside-toplevel - mgr = input_event_manager.get_manager() - - reason = TextEventReason.UNKNOWN - obj = event.source - focus = focus_manager.get_manager().get_locus_of_focus() - if focus != obj and AXUtilitiesRole.is_text_input_search(focus): - if mgr.last_event_was_backspace() or mgr.last_event_was_delete(): - reason = TextEventReason.SEARCH_UNPRESENTABLE - else: - reason = TextEventReason.SEARCH_PRESENTABLE - elif mgr.last_event_was_caret_selection(): - if mgr.last_event_was_line_navigation(): - reason = TextEventReason.SELECTION_BY_LINE - elif mgr.last_event_was_word_navigation(): - reason = TextEventReason.SELECTION_BY_WORD - elif mgr.last_event_was_character_navigation(): - reason = TextEventReason.SELECTION_BY_CHARACTER - elif mgr.last_event_was_page_navigation(): - reason = TextEventReason.SELECTION_BY_PAGE - elif mgr.last_event_was_line_boundary_navigation(): - reason = TextEventReason.SELECTION_TO_LINE_BOUNDARY - elif mgr.last_event_was_file_boundary_navigation(): - reason = TextEventReason.SELECTION_TO_FILE_BOUNDARY - else: - reason = TextEventReason.UNSPECIFIED_SELECTION - elif mgr.last_event_was_caret_navigation(): - if mgr.last_event_was_line_navigation(): - reason = TextEventReason.NAVIGATION_BY_LINE - elif mgr.last_event_was_word_navigation(): - reason = TextEventReason.NAVIGATION_BY_WORD - elif mgr.last_event_was_character_navigation(): - reason = TextEventReason.NAVIGATION_BY_CHARACTER - elif mgr.last_event_was_page_navigation(): - reason = TextEventReason.NAVIGATION_BY_PAGE - elif mgr.last_event_was_line_boundary_navigation(): - reason = TextEventReason.NAVIGATION_TO_LINE_BOUNDARY - elif mgr.last_event_was_file_boundary_navigation(): - reason = TextEventReason.NAVIGATION_TO_FILE_BOUNDARY - else: - reason = TextEventReason.UNSPECIFIED_NAVIGATION - elif mgr.last_event_was_select_all(): - reason = TextEventReason.SELECT_ALL - elif mgr.last_event_was_primary_click_or_release(): - reason = TextEventReason.MOUSE_PRIMARY_BUTTON - elif AXUtilitiesState.is_editable(obj) or AXUtilitiesRole.is_terminal(obj): - if mgr.last_event_was_backspace(): - reason = TextEventReason.BACKSPACE - elif mgr.last_event_was_delete(): - reason = TextEventReason.DELETE - elif mgr.last_event_was_cut(): - reason = TextEventReason.CUT - elif mgr.last_event_was_paste(): - reason = TextEventReason.PASTE - elif mgr.last_event_was_undo(): - reason = TextEventReason.UNDO - elif mgr.last_event_was_redo(): - reason = TextEventReason.REDO - elif mgr.last_event_was_page_switch(): - reason = TextEventReason.PAGE_SWITCH - elif mgr.last_event_was_command(): - reason = TextEventReason.UNSPECIFIED_COMMAND - elif mgr.last_event_was_printable_key(): - reason = TextEventReason.TYPING - elif mgr.last_event_was_up_or_down() or mgr.last_event_was_page_up_or_page_down(): - if AXUtilitiesRole.is_spin_button(obj) \ - or AXObject.find_ancestor(obj, AXUtilitiesRole.is_spin_button): - reason = TextEventReason.SPIN_BUTTON_VALUE_CHANGE - return reason - - @staticmethod - def is_presentable_active_descendant_change(event: Atspi.Event) -> bool: - """Returns True if this event should be presented as an active-descendant change.""" - - if not event.any_data: - msg = "AXUtilitiesEvent: No any_data." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - if not (AXUtilitiesState.is_focused(event.source) \ - or AXUtilitiesState.is_focused(event.any_data)): - msg = "AXUtilitiesEvent: Neither source nor child have focused state." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - focus = focus_manager.get_manager().get_locus_of_focus() - if AXUtilitiesRole.is_table_cell(focus): - table = AXObject.find_ancestor(focus, AXUtilitiesRole.is_tree_or_tree_table) - if table is not None and table != event.source: - msg = "AXUtilitiesEvent: Event is from a different tree or tree table." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def is_presentable_checked_change(event: Atspi.Event) -> bool: - """Returns True if this event should be presented as a checked-state change.""" - - old_state = AXUtilitiesEvent.LAST_KNOWN_CHECKED.get(hash(event.source)) - new_state = AXUtilitiesState.is_checked(event.source) - if old_state == new_state: - msg = "AXUtilitiesEvent: The new state matches the old state." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - AXUtilitiesEvent.LAST_KNOWN_CHECKED[hash(event.source)] = new_state - focus = focus_manager.get_manager().get_locus_of_focus() - if event.source != focus: - if not AXObject.is_ancestor(event.source, focus): - msg = "AXUtilitiesEvent: The source is not the locus of focus or its descendant." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - if not (AXUtilitiesRole.is_list_item(focus) or AXUtilitiesRole.is_tree_item(focus)): - msg = "AXUtilitiesEvent: The source descends from non-interactive-item focus." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - from . import input_event_manager # pylint: disable=import-outside-toplevel - mgr = input_event_manager.get_manager() - - # Radio buttons normally change their state when you arrow to them, so we handle the - # announcement of their state changes in the focus handling code. - if AXUtilitiesRole.is_radio_button(event.source) and not mgr.last_event_was_space(): - msg = "AXUtilitiesEvent: Only presentable for this role if toggled by user." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def is_presentable_description_change(event: Atspi.Event) -> bool: - """Returns True if this event should be presented as a description change.""" - - if not isinstance(event.any_data, str): - msg = "AXUtilitiesEvent: The any_data is not a string." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - old_description = AXUtilitiesEvent.LAST_KNOWN_DESCRIPTION.get(hash(event.source)) - new_description = event.any_data - if old_description == new_description: - msg = "AXUtilitiesEvent: The new description matches the old description." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - AXUtilitiesEvent.LAST_KNOWN_DESCRIPTION[hash(event.source)] = new_description - if not new_description: - msg = "AXUtilitiesEvent: The description is empty." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - if not AXUtilitiesState.is_showing(event.source): - msg = "AXUtilitiesEvent: The event source is not showing." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - focus = focus_manager.get_manager().get_locus_of_focus() - if event.source != focus and not AXObject.is_ancestor(focus, event.source): - msg = "AXUtilitiesEvent: The event is not from the locus of focus or ancestor." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def is_presentable_expanded_change(event: Atspi.Event) -> bool: - """Returns True if this event should be presented as an expanded-state change.""" - - old_state = AXUtilitiesEvent.LAST_KNOWN_EXPANDED.get(hash(event.source)) - new_state = AXUtilitiesState.is_expanded(event.source) - if old_state == new_state: - msg = "AXUtilitiesEvent: The new state matches the old state." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - AXUtilitiesEvent.LAST_KNOWN_EXPANDED[hash(event.source)] = new_state - focus = focus_manager.get_manager().get_locus_of_focus() - if event.source == focus: - msg = "AXUtilitiesEvent: Event is presentable, from the locus of focus." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - if not event.detail1 and not AXObject.is_ancestor(focus, event.source): - msg = "AXUtilitiesEvent: Event is not from the locus of focus or ancestor." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - if AXUtilitiesRole.is_table_row(event.source) or AXUtilitiesRole.is_list_box(event.source): - msg = "AXUtilitiesEvent: Event is presentable based on role." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - if AXUtilitiesRole.is_combo_box(event.source) or AXUtilitiesRole.is_button(event.source): - if not AXUtilitiesState.is_focused(event.source): - msg = "AXUtilitiesEvent: Only presentable for this role if focused." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def is_presentable_indeterminate_change(event: Atspi.Event) -> bool: - """Returns True if this event should be presented as an indeterminate-state change.""" - - old_state = AXUtilitiesEvent.LAST_KNOWN_INDETERMINATE.get(hash(event.source)) - new_state = AXUtilitiesState.is_indeterminate(event.source) - if old_state == new_state: - msg = "AXUtilitiesEvent: The new state matches the old state." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - AXUtilitiesEvent.LAST_KNOWN_INDETERMINATE[hash(event.source)] = new_state - - # If this state is cleared, the new state will become checked or unchecked - # and we should get object:state-changed:checked events for those cases. - if not new_state: - msg = "AXUtilitiesEvent: The new state should be presented as a checked-change." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - if event.source != focus_manager.get_manager().get_locus_of_focus(): - msg = "AXUtilitiesEvent: The event is not from the locus of focus." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def is_presentable_invalid_entry_change(event: Atspi.Event) -> bool: - """Returns True if this event should be presented as an invalid-entry-state change.""" - - old_state = AXUtilitiesEvent.LAST_KNOWN_INVALID_ENTRY.get(hash(event.source)) - new_state = AXUtilitiesState.is_invalid_entry(event.source) - if old_state == new_state: - msg = "AXUtilitiesEvent: The new state matches the old state." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - AXUtilitiesEvent.LAST_KNOWN_INVALID_ENTRY[hash(event.source)] = new_state - if event.source != focus_manager.get_manager().get_locus_of_focus(): - msg = "AXUtilitiesEvent: The event is not from the locus of focus." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def is_presentable_name_change(event: Atspi.Event) -> bool: - """Returns True if this event should be presented as a name change.""" - - if hash(event.source) in AXUtilitiesEvent.IGNORE_NAME_CHANGES_FOR: - msg = "AXUtilitiesEvent: Ignoring name change for this source." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - if not isinstance(event.any_data, str): - msg = "AXUtilitiesEvent: The any_data is not a string." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - old_name = AXUtilitiesEvent.LAST_KNOWN_NAME.get(hash(event.source)) - new_name = event.any_data - if old_name == new_name: - msg = "AXUtilitiesEvent: The new name matches the old name." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - AXUtilitiesEvent.LAST_KNOWN_NAME[hash(event.source)] = new_name - if not new_name: - msg = "AXUtilitiesEvent: The name is empty." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - if not AXUtilitiesState.is_showing(event.source): - msg = "AXUtilitiesEvent: The event source is not showing." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - if AXUtilitiesRole.is_frame(event.source): - if event.source != focus_manager.get_manager().get_active_window(): - msg = "AXUtilitiesEvent: Event is for frame other than the active window." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - # Example: Typing the subject in an email client causing the window name to change. - focus = focus_manager.get_manager().get_locus_of_focus() - if AXUtilitiesState.is_editable(focus) and AXText.get_character_count(focus) \ - and AXText.get_all_text(focus) in event.any_data: - msg = "AXUtilitiesEvent: Event is redundant notification for the locus of focus." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - if event.source != focus_manager.get_manager().get_locus_of_focus(): - msg = "AXUtilitiesEvent: The event is not from the locus of focus." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - if AXUtilitiesRole.is_list_item(event.source): - # Inspired by Firefox's downloads list in which the list item's name changes to show - # download progress. It's super chatty and stomps on the progress bar announcements. - if AXObject.find_descendant(event.source, AXUtilitiesRole.is_progress_bar): - msg = "AXUtilitiesEvent: The list item contains a progress bar." - debug.print_message(debug.LEVEL_INFO, msg, True) - AXUtilitiesEvent.IGNORE_NAME_CHANGES_FOR.append(hash(event.source)) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def is_presentable_pressed_change(event: Atspi.Event) -> bool: - """Returns True if this event should be presented as a pressed-state change.""" - - old_state = AXUtilitiesEvent.LAST_KNOWN_PRESSED.get(hash(event.source)) - new_state = AXUtilitiesState.is_pressed(event.source) - if old_state == new_state: - msg = "AXUtilitiesEvent: The new state matches the old state." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - AXUtilitiesEvent.LAST_KNOWN_PRESSED[hash(event.source)] = new_state - if event.source != focus_manager.get_manager().get_locus_of_focus(): - msg = "AXUtilitiesEvent: The event is not from the locus of focus." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def is_presentable_selected_change(event: Atspi.Event) -> bool: - """Returns True if this event should be presented as a selected-state change.""" - - old_state = AXUtilitiesEvent.LAST_KNOWN_SELECTED.get(hash(event.source)) - new_state = AXUtilitiesState.is_selected(event.source) - if old_state == new_state: - msg = "AXUtilitiesEvent: The new state matches the old state." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - AXUtilitiesEvent.LAST_KNOWN_SELECTED[hash(event.source)] = new_state - if event.source != focus_manager.get_manager().get_locus_of_focus(): - msg = "AXUtilitiesEvent: The event is not from the locus of focus." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def _is_presentable_text_event(event: Atspi.Event) -> bool: - """Returns True if this text event should be presented.""" - - if not (AXUtilitiesState.is_editable(event.source) or \ - AXUtilitiesRole.is_terminal(event.source)): - msg = "AXUtilitiesEvent: The source is neither editable nor a terminal." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - focus = focus_manager.get_manager().get_locus_of_focus() - if focus != event.source and not AXUtilitiesState.is_focused(event.source): - msg = "AXUtilitiesEvent: The source is neither focused, nor the locus of focus" - debug.print_message(debug.LEVEL_INFO, msg, True) - - # This can happen in web content where the focus is a contenteditable element and a - # new child element is created for new or changed text. - if AXObject.is_ancestor(event.source, focus): - msg = "AXUtilitiesEvent: The locus of focus is an ancestor of the source." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - return False - - msg = "AXUtilitiesEvent: Event is presentable." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - @staticmethod - def is_presentable_text_attributes_change(event: Atspi.Event) -> bool: - """Returns True if this text-attributes-change event should be presented.""" - - return AXUtilitiesEvent._is_presentable_text_event(event) - - @staticmethod - def is_presentable_text_deletion(event: Atspi.Event) -> bool: - """Returns True if this text-deletion event should be presented.""" - - return AXUtilitiesEvent._is_presentable_text_event(event) - - @staticmethod - def is_presentable_text_insertion(event: Atspi.Event) -> bool: - """Returns True if this text-insertion event should be presented.""" - - return AXUtilitiesEvent._is_presentable_text_event(event) - - -AXUtilitiesEvent.start_cache_clearing_thread() diff --git a/src/cthulhu/ax_utilities_relation.py b/src/cthulhu/ax_utilities_relation.py deleted file mode 100644 index c9cfee4..0000000 --- a/src/cthulhu/ax_utilities_relation.py +++ /dev/null @@ -1,389 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2024 Igalia, S.L. -# Copyright 2024 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-public-methods - -"""Utilities for obtaining relation-related information.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Igalia, S.L." \ - "Copyright (c) 2024 GNOME Foundation Inc." -__license__ = "LGPL" - -from typing import Optional -import threading -import time - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from .ax_object import AXObject - - -class AXUtilitiesRelation: - """Utilities for obtaining relation-related information.""" - - RELATIONS: dict[int, list[Atspi.Relation]] = {} - TARGETS: dict[int, dict[Atspi.RelationType, list[Atspi.Accessible]]] = {} - - _lock = threading.Lock() - - @staticmethod - def _clear_stored_data() -> None: - """Clears any data we have cached for objects""" - - while True: - time.sleep(60) - AXUtilitiesRelation._clear_all_dictionaries() - - @staticmethod - def _clear_all_dictionaries(reason: str = "") -> None: - msg = "AXUtilitiesRelation: Clearing local cache." - if reason: - msg += f" Reason: {reason}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - with AXUtilitiesRelation._lock: - AXUtilitiesRelation.RELATIONS.clear() - AXUtilitiesRelation.TARGETS.clear() - - @staticmethod - def clear_cache_now(reason: str = "") -> None: - """Clears all cached information immediately.""" - - AXUtilitiesRelation._clear_all_dictionaries(reason) - - @staticmethod - def start_cache_clearing_thread() -> None: - """Starts thread to periodically clear cached details.""" - - thread = threading.Thread(target=AXUtilitiesRelation._clear_stored_data) - thread.daemon = True - thread.start() - - @staticmethod - def get_relations(obj: Atspi.Accessible) -> list[Atspi.Relation]: - """Returns the list of Atspi.Relation objects associated with obj""" - - if not AXObject.is_valid(obj): - return [] - - relations = AXUtilitiesRelation.RELATIONS.get(hash(obj)) - if relations is not None: - return relations - - try: - relations = Atspi.Accessible.get_relation_set(obj) - except GLib.GError as error: - msg = f"AXUtilitiesRelation: Exception in get_relations: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return [] - - if relations is None: - tokens = ["AXUtilitiesRelation: get_relation_set failed for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - AXUtilitiesRelation.RELATIONS[hash(obj)] = relations - return relations - - @staticmethod - def _get_relation( - obj: Atspi.Accessible, - relation_type: Atspi.RelationType - ) -> Optional[Atspi.Relation]: - """Returns the specified Atspi.Relation for obj""" - - for relation in AXUtilitiesRelation.get_relations(obj): - if relation and relation.get_relation_type() == relation_type: - return relation - - return None - - - @staticmethod - def get_relation_targets_for_debugging( - obj: Atspi.Accessible, relation_type: Atspi.RelationType - ) -> list[Atspi.Accessible]: - """Returns the list of targets with the specified relation type to obj.""" - - return AXUtilitiesRelation._get_relation_targets(obj, relation_type) - - @staticmethod - def _get_relation_targets( - obj: Atspi.Accessible, - relation_type: Atspi.RelationType - ) -> list[Atspi.Accessible]: - """Returns the list of targets with the specified relation type to obj.""" - - cached_targets = AXUtilitiesRelation.TARGETS.get(hash(obj), {}) - cached_relation = cached_targets.get(relation_type) - if isinstance(cached_relation, list): - return cached_relation - - relation = AXUtilitiesRelation._get_relation(obj, relation_type) - if relation is None: - cached_targets[relation_type] = [] - AXUtilitiesRelation.TARGETS[hash(obj)] = cached_targets - return [] - - targets = set() - for i in range(relation.get_n_targets()): - if target := relation.get_target(i): - targets.add(target) - - # We want to avoid self-referential relationships. - type_includes_object = [Atspi.RelationType.MEMBER_OF] - if relation_type not in type_includes_object and obj in targets: - tokens = ["AXUtilitiesRelation: ", obj, "is in its own", relation_type, "target list"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - targets.remove(obj) - - result = list(targets) - cached_targets[relation_type] = result - AXUtilitiesRelation.TARGETS[hash(obj)] = cached_targets - return result - - @staticmethod - def get_is_controlled_by(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is controlled by.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.CONTROLLED_BY) - tokens = ["AXUtilitiesRelation:", obj, "is controlled by:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_controller_for(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is the controller for.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.CONTROLLER_FOR) - tokens = ["AXUtilitiesRelation:", obj, "is controller for:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_described_by(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is described by.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.DESCRIBED_BY) - tokens = ["AXUtilitiesRelation:", obj, "is described by:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_description_for(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is the description for.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.DESCRIPTION_FOR) - tokens = ["AXUtilitiesRelation:", obj, "is description for:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_details(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that contain details for obj.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.DETAILS) - tokens = ["AXUtilitiesRelation:", obj, "has details in:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_details_for(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj contains details for.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.DETAILS_FOR) - tokens = ["AXUtilitiesRelation:", obj, "contains details for:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_embedded_by(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is embedded by.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.EMBEDDED_BY) - tokens = ["AXUtilitiesRelation:", obj, "is embedded by:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_embeds(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj embeds.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.EMBEDS) - tokens = ["AXUtilitiesRelation:", obj, "embeds:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_error_for(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj contains an error message for.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.ERROR_FOR) - tokens = ["AXUtilitiesRelation:", obj, "is error for:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_error_message(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that contain an error message for obj.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.ERROR_MESSAGE) - tokens = ["AXUtilitiesRelation:", obj, "has error messages in:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_flows_from(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj flows from.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.FLOWS_FROM) - tokens = ["AXUtilitiesRelation:", obj, "flows from:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_flows_to(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj flows to.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.FLOWS_TO) - tokens = ["AXUtilitiesRelation:", obj, "flows to:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_label_for(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is the label for.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.LABEL_FOR) - tokens = ["AXUtilitiesRelation:", obj, "is label for:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_labelled_by( - obj: Atspi.Accessible, - exclude_ancestors: bool = True - ) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is labelled by.""" - - def is_not_ancestor(acc): - return not AXObject.is_ancestor(obj, acc) - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.LABELLED_BY) - if exclude_ancestors: - result = list(filter(is_not_ancestor, result)) - - tokens = ["AXUtilitiesRelation:", obj, "is labelled by:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_member_of(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is a member of.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.MEMBER_OF) - tokens = ["AXUtilitiesRelation:", obj, "is member of:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_node_child_of(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is the node child of.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.NODE_CHILD_OF) - tokens = ["AXUtilitiesRelation:", obj, "is node child of:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_node_parent_of(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is the node parent of.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.NODE_PARENT_OF) - tokens = ["AXUtilitiesRelation:", obj, "is node parent of:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_parent_window_of(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is a parent window of.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.PARENT_WINDOW_OF) - tokens = ["AXUtilitiesRelation:", obj, "is parent window of:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_popup_for(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is the popup for.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.POPUP_FOR) - tokens = ["AXUtilitiesRelation:", obj, "is popup for:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_subwindow_of(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is a subwindow of.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.SUBWINDOW_OF) - tokens = ["AXUtilitiesRelation:", obj, "is subwindow of:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_is_tooltip_for(obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Returns a list of accessible objects that obj is the tooltip for.""" - - result = AXUtilitiesRelation._get_relation_targets(obj, Atspi.RelationType.TOOLTIP_FOR) - tokens = ["AXUtilitiesRelation:", obj, "is tooltip for:", result] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def object_is_controlled_by(obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> bool: - """Returns True if obj1 is controlled by obj2.""" - - targets = AXUtilitiesRelation._get_relation_targets(obj1, Atspi.RelationType.CONTROLLED_BY) - result = obj2 in targets - tokens = ["AXUtilitiesRelation:", obj1, "is controlled by", obj2, f": {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def object_is_unrelated(obj: Atspi.Accessible) -> bool: - """Returns True if obj does not have any relations.""" - - return not AXUtilitiesRelation.get_relations(obj) - -AXUtilitiesRelation.start_cache_clearing_thread() diff --git a/src/cthulhu/ax_utilities_role.py b/src/cthulhu/ax_utilities_role.py deleted file mode 100644 index 7428867..0000000 --- a/src/cthulhu/ax_utilities_role.py +++ /dev/null @@ -1,2533 +0,0 @@ -# Utilities for obtaining role-related information. -# -# Copyright 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-public-methods -# pylint: disable=too-many-lines -# pylint: disable=too-many-branches -# pylint: disable=too-many-return-statements -# pylint: disable=too-many-statements - -"""Utilities for obtaining role-related information.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -from typing import Optional -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import debug -from . import object_properties -from . import role_keys -from .ax_object import AXObject -from .ax_utilities_state import AXUtilitiesState - -class AXUtilitiesRole: - """Utilities for obtaining role-related information.""" - - @staticmethod - def _get_display_style(obj: Atspi.Accessible) -> str: - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("display", "") - - @staticmethod - def _get_tag(obj: Atspi.Accessible) -> Optional[str]: - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("tag") - - @staticmethod - def _get_xml_roles(obj: Atspi.Accessible) -> list[str]: - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("xml-roles", "").split() - - @staticmethod - def children_are_presentational( - obj: Atspi.Accessible, - role: Optional[Atspi.Role] = None - ) -> bool: - """Returns True if the descendants of obj should be ignored. See ARIA spec.""" - - # Note: We are deliberately leaving out listbox options because they can be complex, - # both in ARIA and in GTK. - - roles = [ - Atspi.Role.BUTTON, - Atspi.Role.CHECK_BOX, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.IMAGE, - Atspi.Role.LEVEL_BAR, - Atspi.Role.PAGE_TAB, - Atspi.Role.PROGRESS_BAR, - Atspi.Role.RADIO_BUTTON, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.SCROLL_BAR, - Atspi.Role.SEPARATOR, - Atspi.Role.SLIDER, - Atspi.Role.SWITCH, - Atspi.Role.TOGGLE_BUTTON, - ] - - if role is None: - role = AXObject.get_role(obj) - - if role in roles: - tokens = ["AXUtilitiesRole:", obj, "has presentational children."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - @staticmethod - def get_dialog_roles(include_alert_as_dialog: bool = True) -> list[Atspi.Role]: - """Returns the list of roles we consider documents""" - - roles = [Atspi.Role.COLOR_CHOOSER, - Atspi.Role.DIALOG, - Atspi.Role.FILE_CHOOSER] - if include_alert_as_dialog: - roles.append(Atspi.Role.ALERT) - return roles - - @staticmethod - def get_document_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider documents""" - - roles = [Atspi.Role.DOCUMENT_EMAIL, - Atspi.Role.DOCUMENT_FRAME, - Atspi.Role.DOCUMENT_PRESENTATION, - Atspi.Role.DOCUMENT_SPREADSHEET, - Atspi.Role.DOCUMENT_TEXT, - Atspi.Role.DOCUMENT_WEB] - return roles - - @staticmethod - def get_form_field_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider form fields""" - - roles = [Atspi.Role.BUTTON, - Atspi.Role.CHECK_BOX, - Atspi.Role.RADIO_BUTTON, - Atspi.Role.COMBO_BOX, - Atspi.Role.DOCUMENT_FRAME, # rich text editing pred recommended - Atspi.Role.TEXT, # predicate recommended to check it is editable - Atspi.Role.LIST_BOX, - Atspi.Role.ENTRY, - Atspi.Role.PASSWORD_TEXT, - Atspi.Role.SPIN_BUTTON, - Atspi.Role.TOGGLE_BUTTON] - return roles - - @staticmethod - def get_large_container_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider a large container.""" - - # Note: We are deliberately leaving out sections because those are often DIVs - # which are generic and often not large. The primary consumer of this function - # is structural navigation which uses it for the jump-to-edge functionality. - roles = [Atspi.Role.ARTICLE, - Atspi.Role.BLOCK_QUOTE, - Atspi.Role.DESCRIPTION_LIST, - Atspi.Role.FORM, - Atspi.Role.FOOTER, - Atspi.Role.GROUPING, - Atspi.Role.HEADER, - Atspi.Role.HTML_CONTAINER, - Atspi.Role.LANDMARK, - Atspi.Role.LOG, - Atspi.Role.LIST, - Atspi.Role.MARQUEE, - Atspi.Role.PANEL, - Atspi.Role.TABLE, - Atspi.Role.TREE, - Atspi.Role.TREE_TABLE] - - return roles - - @staticmethod - def get_layout_only_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider are for layout only""" - - roles = [Atspi.Role.AUTOCOMPLETE, - Atspi.Role.FILLER, - Atspi.Role.REDUNDANT_OBJECT, - Atspi.Role.UNKNOWN, - Atspi.Role.SCROLL_PANE, - Atspi.Role.TEAROFF_MENU_ITEM] - return roles - - @staticmethod - def get_menu_item_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider menu items""" - - roles = [Atspi.Role.MENU_ITEM, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.TEAROFF_MENU_ITEM] - return roles - - @staticmethod - def get_menu_related_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider menu related""" - - roles = [Atspi.Role.MENU, - Atspi.Role.MENU_BAR, - Atspi.Role.POPUP_MENU, - Atspi.Role.MENU_ITEM, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.TEAROFF_MENU_ITEM] - return roles - - @staticmethod - def get_roles_to_exclude_from_clickables_list() -> list[Atspi.Role]: - """Returns the list of roles we want to exclude from the list of clickables""" - - roles = [Atspi.Role.COMBO_BOX, - Atspi.Role.ENTRY, - Atspi.Role.LIST_BOX, - Atspi.Role.MENU, - Atspi.Role.MENU_ITEM, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.PAGE_TAB, - Atspi.Role.PAGE_TAB_LIST, - Atspi.Role.PASSWORD_TEXT, - Atspi.Role.PROGRESS_BAR, - Atspi.Role.SLIDER, - Atspi.Role.SPIN_BUTTON, - Atspi.Role.TOOL_BAR, - Atspi.Role.TREE_ITEM, - Atspi.Role.TREE_TABLE, - Atspi.Role.TREE] - return roles - - @staticmethod - def get_set_container_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider a set container""" - - roles = [Atspi.Role.LIST, - Atspi.Role.MENU, - Atspi.Role.PAGE_TAB_LIST, - Atspi.Role.TABLE, - Atspi.Role.TREE, - Atspi.Role.TREE_TABLE] - return roles - - @staticmethod - def get_table_cell_roles(include_headers: bool = True) -> list[Atspi.Role]: - """Returns the list of roles we consider table cells""" - - roles = [Atspi.Role.TABLE_CELL] - if include_headers: - roles.extend([Atspi.Role.TABLE_COLUMN_HEADER, - Atspi.Role.TABLE_ROW_HEADER, - Atspi.Role.COLUMN_HEADER, - Atspi.Role.ROW_HEADER]) - return roles - - @staticmethod - def get_table_header_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider table headers""" - - roles = [Atspi.Role.TABLE_COLUMN_HEADER, - Atspi.Role.TABLE_ROW_HEADER, - Atspi.Role.COLUMN_HEADER, - Atspi.Role.ROW_HEADER] - return roles - - @staticmethod - def get_table_related_roles(include_caption: bool = False) -> list[Atspi.Role]: - """Returns the list of roles we consider table related""" - - roles = [Atspi.Role.TABLE, - Atspi.Role.TABLE_CELL, - Atspi.Role.TABLE_COLUMN_HEADER, - Atspi.Role.TABLE_ROW_HEADER, - Atspi.Role.COLUMN_HEADER, - Atspi.Role.ROW_HEADER] - if include_caption: - roles.append(Atspi.Role.CAPTION) - return roles - - @staticmethod - def get_text_ui_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider UI that displays static text""" - - roles = [Atspi.Role.INFO_BAR, - Atspi.Role.LABEL, - Atspi.Role.PAGE_TAB, - Atspi.Role.STATUS_BAR] - return roles - - @staticmethod - def get_tree_related_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider tree related""" - - roles = [Atspi.Role.TREE, - Atspi.Role.TREE_ITEM, - Atspi.Role.TREE_TABLE] - return roles - - @staticmethod - def get_widget_roles() -> list[Atspi.Role]: - """Returns the list of roles we consider widgets""" - - roles = [Atspi.Role.BUTTON, - Atspi.Role.CHECK_BOX, - Atspi.Role.COMBO_BOX, - Atspi.Role.ENTRY, - Atspi.Role.LIST_BOX, - Atspi.Role.PASSWORD_TEXT, - Atspi.Role.RADIO_BUTTON, - Atspi.Role.SLIDER, - Atspi.Role.SPIN_BUTTON, - Atspi.Role.SWITCH, - Atspi.Role.TEXT, # predicate recommended to check it is editable - Atspi.Role.TOGGLE_BUTTON] - return roles - - @staticmethod - def get_localized_role_name(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> str: - """Returns a string representing the localized role name of obj.""" - - if role is None: - role = AXObject.get_role(obj) - - if AXObject.supports_value(obj): - if AXUtilitiesRole.is_horizontal_slider(obj, role): - return object_properties.ROLE_SLIDER_HORIZONTAL - if AXUtilitiesRole.is_vertical_slider(obj, role): - return object_properties.ROLE_SLIDER_VERTICAL - if AXUtilitiesRole.is_horizontal_scrollbar(obj, role): - return object_properties.ROLE_SCROLL_BAR_HORIZONTAL - if AXUtilitiesRole.is_vertical_scrollbar(obj, role): - return object_properties.ROLE_SCROLL_BAR_VERTICAL - if AXUtilitiesRole.is_horizontal_separator(obj, role): - return object_properties.ROLE_SPLITTER_HORIZONTAL - if AXUtilitiesRole.is_vertical_separator(obj, role): - return object_properties.ROLE_SPLITTER_VERTICAL - if AXUtilitiesRole.is_split_pane(obj, role): - # The splitter has the opposite orientation of the split pane. - if AXObject.has_state(obj, Atspi.StateType.HORIZONTAL): - return object_properties.ROLE_SPLITTER_VERTICAL - if AXObject.has_state(obj, Atspi.StateType.VERTICAL): - return object_properties.ROLE_SPLITTER_HORIZONTAL - - if AXUtilitiesRole.is_suggestion(obj, role): - return object_properties.ROLE_CONTENT_SUGGESTION - - if AXUtilitiesRole.is_feed(obj, role): - return object_properties.ROLE_FEED - - if AXUtilitiesRole.is_figure(obj, role): - return object_properties.ROLE_FIGURE - - if AXUtilitiesRole.is_switch(obj, role): - return object_properties.ROLE_SWITCH - - if AXUtilitiesRole.is_dpub(obj): - if AXUtilitiesRole.is_landmark(obj, role): - if AXUtilitiesRole.is_dpub_acknowledgments(obj, role): - return object_properties.ROLE_ACKNOWLEDGMENTS - if AXUtilitiesRole.is_dpub_afterword(obj, role): - return object_properties.ROLE_AFTERWORD - if AXUtilitiesRole.is_dpub_appendix(obj, role): - return object_properties.ROLE_APPENDIX - if AXUtilitiesRole.is_dpub_bibliography(obj, role): - return object_properties.ROLE_BIBLIOGRAPHY - if AXUtilitiesRole.is_dpub_chapter(obj, role): - return object_properties.ROLE_CHAPTER - if AXUtilitiesRole.is_dpub_conclusion(obj, role): - return object_properties.ROLE_CONCLUSION - if AXUtilitiesRole.is_dpub_credits(obj, role): - return object_properties.ROLE_CREDITS - if AXUtilitiesRole.is_dpub_endnotes(obj, role): - return object_properties.ROLE_ENDNOTES - if AXUtilitiesRole.is_dpub_epilogue(obj, role): - return object_properties.ROLE_EPILOGUE - if AXUtilitiesRole.is_dpub_errata(obj, role): - return object_properties.ROLE_ERRATA - if AXUtilitiesRole.is_dpub_foreword(obj, role): - return object_properties.ROLE_FOREWORD - if AXUtilitiesRole.is_dpub_glossary(obj, role): - return object_properties.ROLE_GLOSSARY - if AXUtilitiesRole.is_dpub_index(obj, role): - return object_properties.ROLE_INDEX - if AXUtilitiesRole.is_dpub_introduction(obj, role): - return object_properties.ROLE_INTRODUCTION - if AXUtilitiesRole.is_dpub_pagelist(obj, role): - return object_properties.ROLE_PAGELIST - if AXUtilitiesRole.is_dpub_part(obj, role): - return object_properties.ROLE_PART - if AXUtilitiesRole.is_dpub_preface(obj, role): - return object_properties.ROLE_PREFACE - if AXUtilitiesRole.is_dpub_prologue(obj, role): - return object_properties.ROLE_PROLOGUE - if AXUtilitiesRole.is_dpub_toc(obj, role): - return object_properties.ROLE_TOC - elif role == role_keys.ROLE_DPUB_SECTION: - if AXUtilitiesRole.is_dpub_abstract(obj, role): - return object_properties.ROLE_ABSTRACT - if AXUtilitiesRole.is_dpub_colophon(obj, role): - return object_properties.ROLE_COLOPHON - if AXUtilitiesRole.is_dpub_credit(obj, role): - return object_properties.ROLE_CREDIT - if AXUtilitiesRole.is_dpub_dedication(obj, role): - return object_properties.ROLE_DEDICATION - if AXUtilitiesRole.is_dpub_epigraph(obj, role): - return object_properties.ROLE_EPIGRAPH - if AXUtilitiesRole.is_dpub_example(obj, role): - return object_properties.ROLE_EXAMPLE - if AXUtilitiesRole.is_dpub_pullquote(obj, role): - return object_properties.ROLE_PULLQUOTE - if AXUtilitiesRole.is_dpub_qna(obj, role): - return object_properties.ROLE_QNA - elif AXUtilitiesRole.is_list_item(obj, role): - if AXUtilitiesRole.is_dpub_biblioref(obj, role): - return object_properties.ROLE_BIBLIOENTRY - if AXUtilitiesRole.is_dpub_endnote(obj, role): - return object_properties.ROLE_ENDNOTE - else: - if AXUtilitiesRole.is_dpub_cover(obj, role): - return object_properties.ROLE_COVER - if AXUtilitiesRole.is_dpub_pagebreak(obj, role): - return object_properties.ROLE_PAGEBREAK - if AXUtilitiesRole.is_dpub_subtitle(obj, role): - return object_properties.ROLE_SUBTITLE - - if AXUtilitiesRole.is_landmark(obj, role): - if AXUtilitiesRole.is_landmark_without_type(obj, role): - return "" - if AXUtilitiesRole.is_landmark_banner(obj, role): - return object_properties.ROLE_LANDMARK_BANNER - if AXUtilitiesRole.is_landmark_complementary(obj, role): - return object_properties.ROLE_LANDMARK_COMPLEMENTARY - if AXUtilitiesRole.is_landmark_contentinfo(obj, role): - return object_properties.ROLE_LANDMARK_CONTENTINFO - if AXUtilitiesRole.is_landmark_main(obj, role): - return object_properties.ROLE_LANDMARK_MAIN - if AXUtilitiesRole.is_landmark_navigation(obj, role): - return object_properties.ROLE_LANDMARK_NAVIGATION - if AXUtilitiesRole.is_landmark_region(obj, role): - return object_properties.ROLE_LANDMARK_REGION - if AXUtilitiesRole.is_landmark_search(obj, role): - return object_properties.ROLE_LANDMARK_SEARCH - if AXUtilitiesRole.is_landmark_form(obj, role): - role = Atspi.Role.FORM - elif AXUtilitiesRole.is_comment(obj, role): - role = Atspi.Role.COMMENT - - if not isinstance(role, Atspi.Role): - return AXObject.get_role_name(obj, True) - - return Atspi.role_get_localized_name(role) - - @staticmethod - def has_role_from_aria(obj: Atspi.Accessible) -> bool: - """Returns True if obj's role comes from ARIA""" - - return bool(AXUtilitiesRole._get_xml_roles(obj)) - - @staticmethod - def have_same_role(obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> bool: - """Returns True if obj1 and obj2 have the same role""" - - return AXObject.get_role(obj1) == AXObject.get_role(obj2) - - @staticmethod - def is_accelerator_label(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the accelerator label role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.ACCELERATOR_LABEL - - @staticmethod - def is_alert(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the alert (a type of dialog) role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.ALERT - - @staticmethod - def is_aria_alert(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is an ARIA alert (should have notification role)""" - - if "alert" not in AXUtilitiesRole._get_xml_roles(obj): - return False - - if role is None: - role = AXObject.get_role(obj) - - if role != Atspi.Role.NOTIFICATION: - tokens = ["AXUtilitiesRole: Unexpected role for ARIA alert", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return True - - @staticmethod - def is_animation(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the animation role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.ANIMATION - - @staticmethod - def is_application(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the application role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.APPLICATION - - @staticmethod - def is_arrow(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the arrow role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.ARROW - - @staticmethod - def is_article(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the article role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.ARTICLE - - @staticmethod - def is_audio(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the audio role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.AUDIO - - @staticmethod - def is_autocomplete(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the autocomplete role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.AUTOCOMPLETE - - @staticmethod - def is_block_quote(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the block quote role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.BLOCK_QUOTE or AXUtilitiesRole._get_tag(obj) == "blockquote" - - @staticmethod - def is_button(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the push- or toggle-button role""" - - if role is None: - role = AXObject.get_role(obj) - return role in [Atspi.Role.BUTTON, Atspi.Role.TOGGLE_BUTTON] - - @staticmethod - def is_button_with_popup(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the push- or toggle-button role and a popup""" - - if not AXUtilitiesRole.is_button(obj, role): - return False - return AXUtilitiesState.has_popup(obj) - - @staticmethod - def is_calendar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the calendar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.CALENDAR - - @staticmethod - def is_canvas(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the canvas role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.CANVAS - - @staticmethod - def is_caption(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the caption role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.CAPTION - - @staticmethod - def is_chart(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the chart role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.CHART - - @staticmethod - def is_check_box(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the checkbox role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.CHECK_BOX - - @staticmethod - def is_check_menu_item(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the check menuitem role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.CHECK_MENU_ITEM - - @staticmethod - def is_code(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the code or code-like role""" - - return "code" in AXUtilitiesRole._get_xml_roles(obj) \ - or AXUtilitiesRole._get_tag(obj) in ["code", "pre"] - - @staticmethod - def is_color_chooser(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the color_chooser role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.COLOR_CHOOSER - - @staticmethod - def is_column_header(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the column header role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.COLUMN_HEADER - - @staticmethod - def is_combo_box(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the combobox role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.COMBO_BOX - - @staticmethod - def is_comment(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the comment role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.COMMENT or "comment" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_content_deletion(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the content deletion role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.CONTENT_DELETION \ - or "deletion" in AXUtilitiesRole._get_xml_roles(obj) \ - or "del" == AXUtilitiesRole._get_tag(obj) - - @staticmethod - def is_content_insertion(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the content insertion role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.CONTENT_INSERTION \ - or "insertion" in AXUtilitiesRole._get_xml_roles(obj) \ - or "ins" == AXUtilitiesRole._get_tag(obj) - - @staticmethod - def is_date_editor(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the date editor role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DATE_EDITOR - - @staticmethod - def is_default_button(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the push button role the is-default state""" - - return AXUtilitiesRole.is_push_button(obj, role) \ - and AXObject.has_state(obj, Atspi.StateType.IS_DEFAULT) - - @staticmethod - def is_definition(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the definition role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DEFINITION - - @staticmethod - def is_description_list(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the description list role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DESCRIPTION_LIST \ - or "dl" == AXUtilitiesRole._get_tag(obj) - - @staticmethod - def is_description_term(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the description term role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DESCRIPTION_TERM \ - or "dt" == AXUtilitiesRole._get_tag(obj) - - @staticmethod - def is_description_value(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the description value role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DESCRIPTION_VALUE \ - or "dd" == AXUtilitiesRole._get_tag(obj) - - @staticmethod - def is_desktop_frame(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the desktop frame role""" - - if role is None: - role = AXObject.get_role(obj) - if role == Atspi.Role.DESKTOP_FRAME: - return True - if role == Atspi.Role.FRAME: - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("is-desktop") == "true" - return False - - @staticmethod - def is_desktop_icon(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the desktop icon role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DESKTOP_ICON - - @staticmethod - def is_dial(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the dial role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DIAL - - @staticmethod - def is_dialog(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the dialog role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DIALOG - - @staticmethod - def is_dialog_or_alert(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has any dialog or alert role""" - - roles = AXUtilitiesRole.get_dialog_roles(True) - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_dialog_or_window(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has any dialog or window-related role""" - - roles = AXUtilitiesRole.get_dialog_roles(False) - roles.extend((Atspi.Role.FRAME, Atspi.Role.WINDOW)) - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_directory_pane(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the directory pane role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DIRECTORY_PANE - - @staticmethod - def is_docked_frame(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the frame role and is docked.""" - - if not AXUtilitiesRole.is_frame(obj, role): - return False - - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("window-type") == "dock" - - @staticmethod - def is_document(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has any document-related role""" - - roles = AXUtilitiesRole.get_document_roles() - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_document_email(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the document email role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DOCUMENT_EMAIL - - @staticmethod - def is_document_frame(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the document frame role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DOCUMENT_FRAME - - @staticmethod - def is_document_presentation(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the document presentation role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DOCUMENT_PRESENTATION - - @staticmethod - def is_document_spreadsheet(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the document spreadsheet role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DOCUMENT_SPREADSHEET - - @staticmethod - def is_document_text(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the document text role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DOCUMENT_TEXT - - @staticmethod - def is_document_web(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the document web role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DOCUMENT_WEB - - @staticmethod - def is_dpub(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has a DPub role.""" - - roles = AXUtilitiesRole._get_xml_roles(obj) - rv = bool(list(filter(lambda x: x.startswith("doc-"), roles))) - return rv - - @staticmethod - def is_dpub_abstract(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub abstract role.""" - - return "doc-abstract" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_acknowledgments(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub acknowledgments role.""" - - return "doc-acknowledgments" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_afterword(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub afterword role.""" - - return "doc-afterword" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_appendix(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub appendix role.""" - - return "doc-appendix" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_backlink(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub backlink role.""" - - return "doc-backlink" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_biblioref(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub biblioref role.""" - - return "doc-biblioref" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_bibliography(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub bibliography role.""" - - return "doc-bibliography" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_chapter(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub chapter role.""" - - return "doc-chapter" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_colophon(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub colophon role.""" - - return "doc-colophon" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_conclusion(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub conclusion role.""" - - return "doc-conclusion" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_cover(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub cover role.""" - - return "doc-cover" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_credit(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub credit role.""" - - return "doc-credit" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_credits(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub credits role.""" - - return "doc-credits" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_dedication(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub dedication role.""" - - return "doc-dedication" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_endnote(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub endnote role.""" - - return "doc-endnote" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_endnotes(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub endnotes role.""" - - return "doc-endnotes" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_epigraph(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub epigraph role.""" - - return "doc-epigraph" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_epilogue(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub epilogue role.""" - - return "doc-epilogue" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_errata(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub errata role.""" - - return "doc-errata" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_example(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub example role.""" - - return "doc-example" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_footnote(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub footnote role.""" - - return "doc-footnote" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_foreword(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub foreword role.""" - - return "doc-foreword" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_glossary(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub glossary role.""" - - return "doc-glossary" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_glossref(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub glossref role.""" - - return "doc-glossref" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_index(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub index role.""" - - return "doc-index" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_introduction(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub introduction role.""" - - return "doc-introduction" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_noteref(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub noteref role.""" - - return "doc-noteref" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_pagelist(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub pagelist role.""" - - return "doc-pagelist" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_pagebreak(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub pagebreak role.""" - - return "doc-pagebreak" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_part(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub part role.""" - - return "doc-part" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_preface(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub preface role.""" - - return "doc-preface" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_prologue(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub prologue role.""" - - return "doc-prologue" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_pullquote(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub pullquote role.""" - - return "doc-pullquote" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_qna(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub qna role.""" - - return "doc-qna" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_subtitle(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub subtitle role.""" - - return "doc-subtitle" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_dpub_toc(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the DPub toc role.""" - - return "doc-toc" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_drawing_area(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the drawing area role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.DRAWING_AREA - - @staticmethod - def is_editable_combo_box(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is an editable combobox""" - - if role is None: - role = AXObject.get_role(obj) - if role != Atspi.Role.COMBO_BOX: - return False - if AXUtilitiesState.is_editable(obj): - return True - return bool(AXObject.find_descendant(obj, AXUtilitiesRole.is_text_input)) - - @staticmethod - def is_editbar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the editbar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.EDITBAR - - @staticmethod - def is_embedded(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the embedded role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.EMBEDDED - - @staticmethod - def is_entry(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the entry role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.ENTRY - - @staticmethod - def is_extended(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the extended role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.EXTENDED - - @staticmethod - def is_feed(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the feed role""" - - return "feed" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_feed_article(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the article role and descends from a feed.""" - - if not AXUtilitiesRole.is_article(obj, role): - return False - - return AXObject.find_ancestor(obj, AXUtilitiesRole.is_feed) is not None - - @staticmethod - def is_figure(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the figure role or tag.""" - - return "figure" in AXUtilitiesRole._get_xml_roles(obj) \ - or AXUtilitiesRole._get_tag(obj) == "figure" - - @staticmethod - def is_file_chooser(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the file chooser role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.FILE_CHOOSER - - @staticmethod - def is_filler(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the filler role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.FILLER - - @staticmethod - def is_focus_traversable(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the focus traversable role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.FOCUS_TRAVERSABLE - - @staticmethod - def is_font_chooser(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the font chooser role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.FONT_CHOOSER - - @staticmethod - def is_footer(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the footer role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.FOOTER - - @staticmethod - def is_footnote(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the footnote role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.FOOTNOTE - - @staticmethod - def is_form(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the form role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.FORM - - @staticmethod - def is_frame(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the frame role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.FRAME - - @staticmethod - def is_glass_pane(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the glass pane role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.GLASS_PANE - - @staticmethod - def is_gui_list(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the list role but contains UI rather than static text.""" - - if not AXUtilitiesRole.is_list(obj, role): - return False - - return AXObject.get_toolkit_name(obj) == "gtk" - - @staticmethod - def is_grid(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the grid role.""" - - if not AXUtilitiesRole.is_table(obj, role): - return False - - return "grid" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_grid_cell(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the gridcell role or the cell role and is in a grid.""" - - if not AXUtilitiesRole.is_table_cell(obj, role): - return False - - roles = AXUtilitiesRole._get_xml_roles(obj) - if "gridcell" in roles: - return True - if "cell" in roles: - return AXObject.find_ancestor(obj, AXUtilitiesRole.is_grid) is not None - return False - - @staticmethod - def is_group(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is an ARIA group.""" - - return "group" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_grouping(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the grouping role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.GROUPING - - @staticmethod - def is_header(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the header role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.HEADER - - @staticmethod - def is_heading(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the heading role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.HEADING - - @staticmethod - def is_html_container(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the html container role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.HTML_CONTAINER - - @staticmethod - def is_horizontal_scrollbar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a horizontal scrollbar""" - - return AXUtilitiesRole.is_scroll_bar(obj, role) \ - and AXObject.has_state(obj, Atspi.StateType.HORIZONTAL) - - @staticmethod - def is_horizontal_separator(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a horizontal separator""" - - return AXUtilitiesRole.is_separator(obj, role) \ - and AXObject.has_state(obj, Atspi.StateType.HORIZONTAL) - - @staticmethod - def is_horizontal_slider(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a horizontal slider""" - - return AXUtilitiesRole.is_slider(obj, role) \ - and AXObject.has_state(obj, Atspi.StateType.HORIZONTAL) - - @staticmethod - def is_icon(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the icon role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.ICON - - @staticmethod - def is_icon_or_canvas(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the icon or canvas role""" - - if role is None: - role = AXObject.get_role(obj) - return role in [Atspi.Role.ICON, Atspi.Role.CANVAS] - - @staticmethod - def is_image(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the image role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.IMAGE - - @staticmethod - def is_image_or_canvas(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the image or canvas role""" - - if role is None: - role = AXObject.get_role(obj) - return role in [Atspi.Role.IMAGE, Atspi.Role.CANVAS] - - @staticmethod - def is_image_map(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the image map role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.IMAGE_MAP - - @staticmethod - def is_info_bar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the info bar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.INFO_BAR - - @staticmethod - def is_inline_internal_frame(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the internal frame role and is inline.""" - - if not AXUtilitiesRole.is_internal_frame(obj, role): - return False - - return "inline" in AXUtilitiesRole._get_display_style(obj) - - @staticmethod - def is_inline_list_item(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the list item role and is inline.""" - - if not AXUtilitiesRole.is_list_item(obj, role): - return False - - return "inline" in AXUtilitiesRole._get_display_style(obj) - - @staticmethod - def is_inline_suggestion(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the suggestion role and is inline.""" - - if not AXUtilitiesRole.is_suggestion(obj, role): - return False - - return "inline" in AXUtilitiesRole._get_display_style(obj) - - @staticmethod - def is_input_method_window(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the input method window role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.INPUT_METHOD_WINDOW - - @staticmethod - def is_internal_frame(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the internal frame role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.INTERNAL_FRAME or AXUtilitiesRole._get_tag(obj) == "iframe" - - @staticmethod - def is_invalid_role(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the invalid role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.INVALID - - @staticmethod - def is_label(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the label role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.LABEL - - @staticmethod - def is_label_or_caption(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the label or caption role""" - - if role is None: - role = AXObject.get_role(obj) - return role in [Atspi.Role.LABEL, Atspi.Role.CAPTION] - - @staticmethod - def is_landmark(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the landmark role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.LANDMARK - - @staticmethod - def is_landmark_banner(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the banner landmark role""" - - return "banner" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_landmark_complementary( - obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None - ) -> bool: - """Returns True if obj has the complementary landmark role""" - - return "complementary" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_landmark_contentinfo(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the contentinfo landmark role""" - - return "contentinfo" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_landmark_form(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the form landmark role""" - - return "form" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_landmark_main(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the main landmark role""" - - return "main" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_landmark_navigation(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the navigation landmark role""" - - return "navigation" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_landmark_region(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the region landmark role""" - - return "region" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_landmark_search(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the search landmark role""" - - return "search" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_landmark_without_type(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the landmark role but no type""" - - if not AXUtilitiesRole.is_landmark(obj, role): - return False - - roles = AXUtilitiesRole._get_xml_roles(obj) - return not roles - - @staticmethod - def is_large_container(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has a large container role""" - - if role is None: - role = AXObject.get_role(obj) - - return role in AXUtilitiesRole.get_large_container_roles() - - @staticmethod - def is_layered_pane(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the layered pane role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.LAYERED_PANE - - @staticmethod - def is_level_bar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the level bar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.LEVEL_BAR - - @staticmethod - def is_link(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the link role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.LINK - - @staticmethod - def is_list(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the list role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.LIST - - @staticmethod - def is_list_box(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the list box role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.LIST_BOX - - @staticmethod - def is_list_box_item(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is an item in a list box""" - - if not AXUtilitiesRole.is_list_item(obj, role): - return False - return AXObject.find_ancestor(obj, AXUtilitiesRole.is_list_box) is not None - - @staticmethod - def is_list_item(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the list item role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.LIST_ITEM - - @staticmethod - def is_log(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the log role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.LOG - - @staticmethod - def is_live_region(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a live region.""" - - attrs = AXObject.get_attributes_dict(obj) - return "container-live" in attrs and attrs.get("container-live") in ["polite", "assertive"] - - @staticmethod - def is_mark(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the mark role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.MARK \ - or "mark" in AXUtilitiesRole._get_xml_roles(obj) \ - or "mark" == AXUtilitiesRole._get_tag(obj) - - @staticmethod - def is_marquee(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the marquee role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.MARQUEE - - @staticmethod - def is_math(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the math role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.MATH - - @staticmethod - def is_math_enclose(obj: Atspi.Accessible) -> bool: - """Returns True if obj has the math enclose role/tag""" - - return AXUtilitiesRole._get_tag(obj) == "menclose" - - @staticmethod - def is_math_fenced(obj: Atspi.Accessible) -> bool: - """Returns True if obj has the math fenced role/tag""" - - return AXUtilitiesRole._get_tag(obj) == "mfenced" - - @staticmethod - def is_math_fraction(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the math fraction role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.MATH_FRACTION - - @staticmethod - def is_math_fraction_without_bar( - obj: Atspi.Accessible, role: Optional[Atspi.Role] = None - ) -> bool: - """Returns True if obj has the math fraction role and lacks the fraction bar""" - - if not AXUtilitiesRole.is_math_fraction(obj, role): - return False - - line_thickness = AXObject.get_attribute(obj, "linethickness") - if not line_thickness: - return False - - for char in line_thickness: - if char.isnumeric() and char != "0": - return False - - return True - - @staticmethod - def is_math_layout_only(obj: Atspi.Accessible) -> bool: - """Returns True if obj has a layout-only math role""" - - return AXUtilitiesRole._get_tag(obj) \ - in ["mrow", "mstyle", "merror", "mpadded", "none", "semantics"] - - @staticmethod - def is_math_multi_script(obj: Atspi.Accessible) -> bool: - """Returns True if obj has the math multi-scripts role/tag""" - - return AXUtilitiesRole._get_tag(obj) == "mmultiscripts" - - @staticmethod - def is_math_related(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has a math-related role""" - - if role is None: - role = AXObject.get_role(obj) - if role in [Atspi.Role.MATH, Atspi.Role.MATH_FRACTION, Atspi.Role.MATH_ROOT]: - return True - return AXUtilitiesRole._get_tag(obj) in ["math", - "maction", - "maligngroup", - "malignmark", - "menclose", - "merror", - "mfenced", - "mfrac", - "mglyph", - "mi", - "mlabeledtr", - "mlongdiv", - "mmultiscripts", - "mn", - "mo", - "mover", - "mpadded", - "mphantom", - "mprescripts", - "mroot", - "mrow", - "ms", - "mscarries", - "mscarry", - "msgroup", - "msline", - "mspace", - "msqrt", - "msrow", - "mstack", - "mstyle", - "msub", - "msup", - "msubsup", - "mtable", - "mtd", - "mtext", - "mtr", - "munder", - "munderover"] - - @staticmethod - def is_math_root(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the math root role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.MATH_ROOT - - @staticmethod - def is_math_square_root(obj: Atspi.Accessible) -> bool: - """Returns True if obj has the math root role/tag""" - - return AXUtilitiesRole._get_tag(obj) == "msqrt" - - @staticmethod - def is_math_sub_or_super_script(obj: Atspi.Accessible) -> bool: - """Returns True if obj has the math subscript or superscript role/tag""" - - return AXUtilitiesRole._get_tag(obj) in ["msub", "msup", "msubsup"] - - @staticmethod - def is_math_table(obj: Atspi.Accessible) -> bool: - """Returns True if obj has the math table role/tag""" - - return AXUtilitiesRole._get_tag(obj) == "mtable" - - @staticmethod - def is_math_table_row(obj: Atspi.Accessible) -> bool: - """Returns True if obj has the math table row role/tag""" - - return AXUtilitiesRole._get_tag(obj) in ["mtr", "mlabeledtr"] - - @staticmethod - def is_math_token(obj: Atspi.Accessible) -> bool: - """Returns True if obj has a math token role/tag""" - - return AXUtilitiesRole._get_tag(obj) in ["mi", "mn", "mo", "mtext", "ms", "mspace"] - - @staticmethod - def is_math_under_or_over_script(obj: Atspi.Accessible) -> bool: - """Returns True if obj has the math under-script or over-script role/tag""" - - return AXUtilitiesRole._get_tag(obj) in ["mover", "munder", "munderover"] - - @staticmethod - def is_menu(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the menu role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.MENU - - @staticmethod - def is_menu_bar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the menubar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.MENU_BAR - - @staticmethod - def is_menu_item(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the menu item role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.MENU_ITEM - - @staticmethod - def is_menu_item_of_any_kind(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has any menu item role""" - - roles = AXUtilitiesRole.get_menu_item_roles() - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_menu_related(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has any menu-related role""" - - roles = AXUtilitiesRole.get_menu_related_roles() - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_modal_dialog(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the alert or dialog role and modal state""" - - return AXUtilitiesRole.is_dialog_or_alert(obj, role) \ - and AXObject.has_state(obj, Atspi.StateType.MODAL) - - @staticmethod - def is_multi_line_entry(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the entry role and multiline state""" - - return AXUtilitiesRole.is_entry(obj, role) \ - and AXObject.has_state(obj, Atspi.StateType.MULTI_LINE) - - @staticmethod - def is_notification(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the notification role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.NOTIFICATION - - @staticmethod - def is_option_pane(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the option pane role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.OPTION_PANE - - @staticmethod - def is_page(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the page role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.PAGE - - @staticmethod - def is_page_tab(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the page tab role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.PAGE_TAB - - @staticmethod - def is_page_tab_list(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the page tab list role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.PAGE_TAB_LIST - - @staticmethod - def is_page_tab_list_related(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the page tab or page tab list role""" - - roles = [Atspi.Role.PAGE_TAB_LIST, Atspi.Role.PAGE_TAB] - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_panel(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the panel role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.PANEL - - @staticmethod - def is_paragraph(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the paragraph role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.PARAGRAPH - - @staticmethod - def is_password_text(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the password text role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.PASSWORD_TEXT - - @staticmethod - def is_popup_menu(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the popup menu role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.POPUP_MENU - - @staticmethod - def is_progress_bar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the progress bar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.PROGRESS_BAR - - @staticmethod - def is_push_button(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the push button role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.BUTTON - - @staticmethod - def is_push_button_menu(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the push button menu role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.PUSH_BUTTON_MENU - - @staticmethod - def is_radio_button(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the radio button role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.RADIO_BUTTON - - @staticmethod - def is_radio_menu_item(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the radio menu item role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.RADIO_MENU_ITEM - - @staticmethod - def is_rating(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the rating role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.RATING - - @staticmethod - def is_redundant_object_role(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the redundant object role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.REDUNDANT_OBJECT - - @staticmethod - def is_root_pane(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the root pane role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.ROOT_PANE - - @staticmethod - def is_row_header(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the row header role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.ROW_HEADER - - @staticmethod - def is_ruler(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the ruler role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.RULER - - @staticmethod - def is_scroll_bar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the scrollbar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SCROLL_BAR - - @staticmethod - def is_scroll_pane(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the scroll pane role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SCROLL_PANE - - @staticmethod - def is_section(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the section role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SECTION - - @staticmethod - def is_separator(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the separator role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SEPARATOR - - @staticmethod - def is_single_line_autocomplete_entry( - obj: Atspi.Accessible, role: Optional[Atspi.Role] = None - ) -> bool: - """Returns True if obj has the entry role and single-line state""" - - if not AXUtilitiesRole.is_single_line_entry(obj, role): - return False - - return AXUtilitiesState.supports_autocompletion(obj) - - @staticmethod - def is_single_line_entry(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the entry role and the single-line state""" - - if not AXUtilitiesState.is_single_line(obj): - return False - if AXUtilitiesRole.is_entry(obj, role): - return True - if AXUtilitiesRole.is_text(obj, role): - return AXUtilitiesState.is_editable(obj) - return False - - @staticmethod - def is_slider(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the slider role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SLIDER - - @staticmethod - def is_spin_button(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the spin button role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SPIN_BUTTON - - @staticmethod - def is_split_pane(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the split pane role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SPLIT_PANE - - @staticmethod - def is_static(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the static role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.STATIC - - @staticmethod - def is_status_bar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the statusbar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.STATUS_BAR - - @staticmethod - def is_subscript(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the subscript role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SUBSCRIPT - - @staticmethod - def is_subscript_or_superscript( - obj: Atspi.Accessible, role: Optional[Atspi.Role] = None - ) -> bool: - """Returns True if obj has the subscript or superscript role""" - - if role is None: - role = AXObject.get_role(obj) - return role in [Atspi.Role.SUBSCRIPT, Atspi.Role.SUPERSCRIPT] - - @staticmethod - def is_subscript_or_superscript_text( - obj: Atspi.Accessible, role: Optional[Atspi.Role] = None - ) -> bool: - """Returns True if obj has the subscript or superscript role and is not math-related""" - - if AXUtilitiesRole.is_math_related(obj, role): - return False - return AXUtilitiesRole.is_subscript_or_superscript(obj, role) - - @staticmethod - def is_suggestion(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the suggestion role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SUGGESTION \ - or "suggestion" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_superscript(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the superscript role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.SUPERSCRIPT - - @staticmethod - def is_svg(obj: Atspi.Accessible) -> bool: - """Returns True if obj is an svg.""" - - return AXUtilitiesRole._get_tag(obj) == "svg" - - @staticmethod - def is_switch(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the switch role.""" - - if role is None: - role = AXObject.get_role(obj) - - if role == Atspi.Role.SWITCH: - return True - - return "switch" in AXUtilitiesRole._get_xml_roles(obj) - - @staticmethod - def is_table(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the table role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TABLE - - @staticmethod - def is_table_cell(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the table cell role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TABLE_CELL - - @staticmethod - def is_table_cell_or_header(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the table cell or a header-related role""" - - roles = AXUtilitiesRole.get_table_cell_roles() - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_table_column_header(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the table column header role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TABLE_COLUMN_HEADER - - @staticmethod - def is_table_header(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has a table header related role""" - - roles = AXUtilitiesRole.get_table_header_roles() - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_table_related( - obj: Atspi.Accessible, - role: Optional[Atspi.Role] = None, - include_caption: bool = False - ) -> bool: - """Returns True if obj has a table-related role""" - - roles = AXUtilitiesRole.get_table_related_roles(include_caption) - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_table_row(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the table row role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TABLE_ROW - - @staticmethod - def is_table_row_header(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the table row header role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TABLE_ROW_HEADER - - @staticmethod - def is_tearoff_menu_item(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the tearoff menu item role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TEAROFF_MENU_ITEM - - @staticmethod - def is_terminal(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the terminal role""" - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TERMINAL - - @staticmethod - def is_text(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the text role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TEXT - - @staticmethod - def is_text_input(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has any role associated with textual input""" - - roles = [Atspi.Role.ENTRY, Atspi.Role.PASSWORD_TEXT, Atspi.Role.SPIN_BUTTON] - if role is None: - role = AXObject.get_role(obj) - if role in roles: - return True - if role == Atspi.Role.TEXT: - return AXUtilitiesState.is_editable(obj) and AXUtilitiesState.is_single_line(obj) - if AXUtilitiesRole.is_editable_combo_box(obj): - return True - return False - - @staticmethod - def is_text_input_date(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a date text input""" - - if not AXUtilitiesRole.is_text_input(obj, role): - return False - - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("text-input-type") == "date" - - @staticmethod - def is_text_input_email(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is an email text input""" - - if not AXUtilitiesRole.is_text_input(obj, role): - return False - - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("text-input-type") == "email" - - @staticmethod - def is_text_input_number(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a numeric text input""" - - if not AXUtilitiesRole.is_text_input(obj, role): - return False - - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("text-input-type") == "number" - - @staticmethod - def is_text_input_search(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a telephone text input""" - - if not AXUtilitiesRole.is_text_input(obj, role): - return False - - attrs = AXObject.get_attributes_dict(obj) - if attrs.get("text-input-type") == "search": - return True - if "searchbox" in AXUtilitiesRole._get_xml_roles(obj): - return True - - ax_id = AXObject.get_accessible_id(obj) or "" - if ax_id: - return "search" in ax_id.lower() or "find" in ax_id.lower() - - child = AXObject.get_child(obj, 0) - if AXUtilitiesRole.is_icon(child) or AXUtilitiesRole.is_image(child): - child_id = AXObject.get_accessible_id(child) or "" - if "search" in child_id.lower() or "find" in child_id.lower(): - return True - # Some toolkits don't localize the symbolic icon names, so it's worth a try. - child_name = AXObject.get_name(child).lower() - return "search" in child_name or "find" in child_name - - return False - - @staticmethod - def is_text_input_telephone(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a telephone text input""" - - if not AXUtilitiesRole.is_text_input(obj, role): - return False - - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("text-input-type") == "telephone" - - @staticmethod - def is_text_input_time(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a time text input""" - - if not AXUtilitiesRole.is_text_input(obj, role): - return False - - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("text-input-type") == "time" - - @staticmethod - def is_text_input_url(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a url text input""" - - if not AXUtilitiesRole.is_text_input(obj, role): - return False - - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("text-input-type") == "url" - - @staticmethod - def is_text_input_week(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a week text input""" - - if not AXUtilitiesRole.is_text_input(obj, role): - return False - - attrs = AXObject.get_attributes_dict(obj) - return attrs.get("text-input-type") == "week" - - @staticmethod - def is_time(obj: Atspi.Accessible, _role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the time role""" - - return "time" in AXUtilitiesRole._get_xml_roles(obj) \ - or "time" == AXUtilitiesRole._get_tag(obj) - - @staticmethod - def is_timer(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the timer role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TIMER - - @staticmethod - def is_title_bar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the titlebar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TITLE_BAR - - @staticmethod - def is_toggle_button(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the toggle button role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TOGGLE_BUTTON - - @staticmethod - def is_tool_bar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the toolbar role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TOOL_BAR - - @staticmethod - def is_tool_tip(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the tooltip role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TOOL_TIP - - @staticmethod - def is_tree(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the tree role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TREE - - @staticmethod - def is_tree_or_tree_table(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the tree or tree table role""" - - if role is None: - role = AXObject.get_role(obj) - return role in [Atspi.Role.TREE, Atspi.Role.TREE_TABLE] - - @staticmethod - def is_tree_related(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has a tree-related role""" - - roles = [Atspi.Role.TREE, - Atspi.Role.TREE_ITEM, - Atspi.Role.TREE_TABLE] - if role is None: - role = AXObject.get_role(obj) - return role in roles - - @staticmethod - def is_tree_item(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the tree item role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TREE_ITEM - - @staticmethod - def is_tree_table(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the tree table role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.TREE_TABLE - - @staticmethod - def is_unknown(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the unknown role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.UNKNOWN - - @staticmethod - def is_unknown_or_redundant(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the unknown or redundant object role""" - - if role is None: - role = AXObject.get_role(obj) - return role in [Atspi.Role.UNKNOWN, Atspi.Role.REDUNDANT_OBJECT] - - @staticmethod - def is_vertical_scrollbar(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a vertical scrollbar""" - - return AXUtilitiesRole.is_scroll_bar(obj, role) \ - and AXObject.has_state(obj, Atspi.StateType.VERTICAL) - - @staticmethod - def is_vertical_separator(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a vertical separator""" - - return AXUtilitiesRole.is_separator(obj, role) \ - and AXObject.has_state(obj, Atspi.StateType.VERTICAL) - - @staticmethod - def is_vertical_slider(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj is a vertical slider""" - - return AXUtilitiesRole.is_slider(obj, role) \ - and AXObject.has_state(obj, Atspi.StateType.VERTICAL) - - @staticmethod - def is_video(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the video role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.VIDEO - - @staticmethod - def is_viewport(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the viewport role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.VIEWPORT - - @staticmethod - def is_web_element(obj: Atspi.Accessible, exclude_pseudo_elements: bool = True) -> bool: - """Returns True if obj is a web element""" - - tag = AXUtilitiesRole._get_tag(obj) - if not tag: - return False - if not exclude_pseudo_elements: - return True - exclude = ["::before", "::after", "::marker"] - return tag not in exclude - - @staticmethod - def is_web_element_custom(obj: Atspi.Accessible) -> bool: - """Returns True if obj is a custom web element""" - - tag = AXUtilitiesRole._get_tag(obj) - return tag is not None and "-" in tag - - @staticmethod - def is_widget(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has a widget role""" - - if role is None: - role = AXObject.get_role(obj) - return role in AXUtilitiesRole.get_widget_roles() - - @staticmethod - def is_widget_controlled_by_line_navigation( - obj: Atspi.Accessible, role: Optional[Atspi.Role] = None - ) -> bool: - """Returns True if obj is a widget controlled by line navigation""" - - if role is None: - role = AXObject.get_role(obj) - - roles = [Atspi.Role.COMBO_BOX, - Atspi.Role.LIST_BOX, - Atspi.Role.MENU, - Atspi.Role.SPIN_BUTTON, - Atspi.Role.TREE, - Atspi.Role.TREE_TABLE] - if role in roles: - return True - - if AXUtilitiesState.is_editable(obj) or AXUtilitiesState.is_selectable(obj): - return AXObject.find_ancestor(obj, lambda x: AXObject.get_role(x) in roles) is not None - - if not AXUtilitiesState.is_vertical(obj): - return False - - return role in [Atspi.Role.SCROLL_BAR, - Atspi.Role.SEPARATOR, - Atspi.Role.SLIDER, - Atspi.Role.SPLIT_PANE] - - @staticmethod - def is_window(obj: Atspi.Accessible, role: Optional[Atspi.Role] = None) -> bool: - """Returns True if obj has the window role""" - - if role is None: - role = AXObject.get_role(obj) - return role == Atspi.Role.WINDOW diff --git a/src/cthulhu/ax_utilities_state.py b/src/cthulhu/ax_utilities_state.py deleted file mode 100644 index b146261..0000000 --- a/src/cthulhu/ax_utilities_state.py +++ /dev/null @@ -1,392 +0,0 @@ -# Utilities for obtaining state-related information. -# -# Copyright 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-public-methods -# pylint: disable=too-many-return-statements - -"""Utilities for obtaining state-related information.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import debug -from . import messages -from .ax_object import AXObject - - -class AXUtilitiesState: - """Utilities for obtaining state-related information.""" - - @staticmethod - def get_current_item_status_string(obj: Atspi.Accessible) -> str: - """Returns the current item status string of obj.""" - - if not AXUtilitiesState.is_active(obj): - return "" - - result = AXObject.get_attribute(obj, "current") - if not result: - return "" - if result == "date": - return messages.CURRENT_DATE - if result == "time": - return messages.CURRENT_TIME - if result == "location": - return messages.CURRENT_LOCATION - if result == "page": - return messages.CURRENT_PAGE - if result == "step": - return messages.CURRENT_STEP - return messages.CURRENT_ITEM - - @staticmethod - def has_no_state(obj: Atspi.Accessible) -> bool: - """Returns true if obj has an empty state set""" - - return AXObject.get_state_set(obj).is_empty() - - @staticmethod - def has_popup(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the has-popup state""" - - return AXObject.has_state(obj, Atspi.StateType.HAS_POPUP) - - @staticmethod - def has_tooltip(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the has-tooltip state""" - - return AXObject.has_state(obj, Atspi.StateType.HAS_TOOLTIP) - - @staticmethod - def is_active(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the active state""" - - return AXObject.has_state(obj, Atspi.StateType.ACTIVE) - - @staticmethod - def is_animated(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the animated state""" - - return AXObject.has_state(obj, Atspi.StateType.ANIMATED) - - @staticmethod - def is_armed(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the armed state""" - - return AXObject.has_state(obj, Atspi.StateType.ARMED) - - @staticmethod - def is_busy(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the busy state""" - - return AXObject.has_state(obj, Atspi.StateType.BUSY) - - @staticmethod - def is_checkable(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the checkable state""" - - if AXObject.has_state(obj, Atspi.StateType.CHECKABLE): - return True - - if AXObject.has_state(obj, Atspi.StateType.CHECKED): - tokens = ["AXUtilitiesState:", obj, "is checked but lacks state checkable"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - @staticmethod - def is_checked(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the checked state""" - - if not AXObject.has_state(obj, Atspi.StateType.CHECKED): - return False - - if not AXObject.has_state(obj, Atspi.StateType.CHECKABLE): - tokens = ["AXUtilitiesState:", obj, "is checked but lacks state checkable"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return True - - @staticmethod - def is_collapsed(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the collapsed state""" - - return AXObject.has_state(obj, Atspi.StateType.COLLAPSED) - - @staticmethod - def is_default(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the is-default state""" - - return AXObject.has_state(obj, Atspi.StateType.IS_DEFAULT) - - @staticmethod - def is_defunct(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the defunct state""" - - return AXObject.has_state(obj, Atspi.StateType.DEFUNCT) - - @staticmethod - def is_editable(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the editable state""" - - return AXObject.has_state(obj, Atspi.StateType.EDITABLE) - - @staticmethod - def is_enabled(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the enabled state""" - - return AXObject.has_state(obj, Atspi.StateType.ENABLED) - - @staticmethod - def is_expandable(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the expandable state""" - - if AXObject.has_state(obj, Atspi.StateType.EXPANDABLE): - return True - - if AXObject.has_state(obj, Atspi.StateType.EXPANDED): - tokens = ["AXUtilitiesState:", obj, "is expanded but lacks state expandable"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - @staticmethod - def is_expanded(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the expanded state""" - - if not AXObject.has_state(obj, Atspi.StateType.EXPANDED): - return False - - if not AXObject.has_state(obj, Atspi.StateType.EXPANDABLE): - tokens = ["AXUtilitiesState:", obj, "is expanded but lacks state expandable"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return True - - @staticmethod - def is_focusable(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the focusable state""" - - if AXObject.has_state(obj, Atspi.StateType.FOCUSABLE): - return True - - if AXObject.has_state(obj, Atspi.StateType.FOCUSED): - tokens = ["AXUtilitiesState:", obj, "is focused but lacks state focusable"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - @staticmethod - def is_focused(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the focused state""" - - if not AXObject.has_state(obj, Atspi.StateType.FOCUSED): - return False - - if not AXObject.has_state(obj, Atspi.StateType.FOCUSABLE): - tokens = ["AXUtilitiesState:", obj, "is focused but lacks state focusable"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return True - - @staticmethod - def is_hidden(obj: Atspi.Accessible) -> bool: - """Returns true if obj reports being hidden""" - - return AXObject.get_attribute(obj, "hidden", False) == "true" - - @staticmethod - def is_horizontal(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the horizontal state""" - - return AXObject.has_state(obj, Atspi.StateType.HORIZONTAL) - - @staticmethod - def is_iconified(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the iconified state""" - - return AXObject.has_state(obj, Atspi.StateType.ICONIFIED) - - @staticmethod - def is_indeterminate(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the indeterminate state""" - - return AXObject.has_state(obj, Atspi.StateType.INDETERMINATE) - - @staticmethod - def is_invalid_state(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the invalid_state state""" - - return AXObject.has_state(obj, Atspi.StateType.INVALID) - - @staticmethod - def is_invalid_entry(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the invalid_entry state""" - - return AXObject.has_state(obj, Atspi.StateType.INVALID_ENTRY) - - @staticmethod - def is_modal(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the modal state""" - - return AXObject.has_state(obj, Atspi.StateType.MODAL) - - @staticmethod - def is_multi_line(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the multi_line state""" - - return AXObject.has_state(obj, Atspi.StateType.MULTI_LINE) - - @staticmethod - def is_multiselectable(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the multiselectable state""" - - return AXObject.has_state(obj, Atspi.StateType.MULTISELECTABLE) - - @staticmethod - def is_opaque(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the opaque state""" - - return AXObject.has_state(obj, Atspi.StateType.OPAQUE) - - @staticmethod - def is_pressed(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the pressed state""" - - return AXObject.has_state(obj, Atspi.StateType.PRESSED) - - @staticmethod - def is_read_only(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the read-only state""" - - if AXObject.has_state(obj, Atspi.StateType.READ_ONLY): - return True - if AXUtilitiesState.is_editable(obj): - return False - - # We cannot count on GTK to set the read-only state on text objects. - return AXObject.get_role(obj) == Atspi.Role.TEXT - - @staticmethod - def is_required(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the required state""" - - return AXObject.has_state(obj, Atspi.StateType.REQUIRED) - - @staticmethod - def is_resizable(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the resizable state""" - - return AXObject.has_state(obj, Atspi.StateType.RESIZABLE) - - @staticmethod - def is_selectable(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the selectable state""" - - return AXObject.has_state(obj, Atspi.StateType.SELECTABLE) - - @staticmethod - def is_selectable_text(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the selectable-text state""" - - return AXObject.has_state(obj, Atspi.StateType.SELECTABLE_TEXT) - - @staticmethod - def is_selected(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the selected state""" - - return AXObject.has_state(obj, Atspi.StateType.SELECTED) - - @staticmethod - def is_sensitive(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the sensitive state""" - - return AXObject.has_state(obj, Atspi.StateType.SENSITIVE) - - @staticmethod - def is_showing(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the showing state""" - - return AXObject.has_state(obj, Atspi.StateType.SHOWING) - - @staticmethod - def is_single_line(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the single-line state""" - - return AXObject.has_state(obj, Atspi.StateType.SINGLE_LINE) - - @staticmethod - def is_stale(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the stale state""" - - return AXObject.has_state(obj, Atspi.StateType.STALE) - - @staticmethod - def is_transient(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the transient state""" - - return AXObject.has_state(obj, Atspi.StateType.TRANSIENT) - - @staticmethod - def is_truncated(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the truncated state""" - - return AXObject.has_state(obj, Atspi.StateType.TRUNCATED) - - @staticmethod - def is_vertical(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the vertical state""" - - return AXObject.has_state(obj, Atspi.StateType.VERTICAL) - - @staticmethod - def is_visible(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the visible state""" - - return AXObject.has_state(obj, Atspi.StateType.VISIBLE) - - @staticmethod - def is_visited(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the visited state""" - - return AXObject.has_state(obj, Atspi.StateType.VISITED) - - @staticmethod - def manages_descendants(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the manages-descendants state""" - - return AXObject.has_state(obj, Atspi.StateType.MANAGES_DESCENDANTS) - - @staticmethod - def supports_autocompletion(obj: Atspi.Accessible) -> bool: - """Returns true if obj has the supports-autocompletion state""" - - return AXObject.has_state(obj, Atspi.StateType.SUPPORTS_AUTOCOMPLETION) diff --git a/src/cthulhu/ax_value.py b/src/cthulhu/ax_value.py deleted file mode 100644 index 0308f73..0000000 --- a/src/cthulhu/ax_value.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2024 Igalia, S.L. -# Copyright 2024 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position - -"""Utilities for obtaining value-related information about accessible objects.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Igalia, S.L." \ - "Copyright (c) 2024 GNOME Foundation Inc." -__license__ = "LGPL" - -from typing import Optional -import threading -import time - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from .ax_object import AXObject -from .ax_utilities import AXUtilities - -class AXValue: - """Utilities for obtaining value-related information about accessible objects.""" - - LAST_KNOWN_VALUE: dict[int, float] = {} - _lock = threading.Lock() - - @staticmethod - def _clear_stored_data() -> None: - """Clears any data we have cached for objects""" - - while True: - time.sleep(60) - msg = "AXValue: Clearing local cache." - debug.print_message(debug.LEVEL_INFO, msg, True) - AXValue.LAST_KNOWN_VALUE.clear() - - @staticmethod - def start_cache_clearing_thread() -> None: - """Starts thread to periodically clear cached details.""" - - thread = threading.Thread(target=AXValue._clear_stored_data) - thread.daemon = True - thread.start() - - @staticmethod - def did_value_change(obj: Atspi.Accessible) -> bool: - """Returns True if the current value changed.""" - - if not AXObject.supports_value(obj): - return False - - old_value = AXValue.LAST_KNOWN_VALUE.get(hash(obj)) - result = old_value != AXValue._get_current_value(obj) - if result: - tokens = ["AXValue: Previous value of", obj, f"was {old_value}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return result - - @staticmethod - def _get_current_value(obj: Atspi.Accessible) -> float: - """Returns the current value of obj.""" - - if not AXObject.supports_value(obj): - return 0.0 - - try: - value = Atspi.Value.get_current_value(obj) - except GLib.GError as error: - msg = f"AXValue: Exception in _get_current_value: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0.0 - - tokens = ["AXValue: Current value of", obj, f"is {value}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return value - - @staticmethod - def get_current_value(obj: Atspi.Accessible) -> float: - """Returns the current value of obj.""" - - if not AXObject.supports_value(obj): - return 0.0 - - value = AXValue._get_current_value(obj) - AXValue.LAST_KNOWN_VALUE[hash(obj)] = value - return value - - @staticmethod - def get_current_value_text(obj: Atspi.Accessible) -> str: - """Returns the app-provided text-alternative for the current value of obj.""" - - text = AXObject.get_attribute(obj, "valuetext", False) or "" - if text: - tokens = ["AXValue: valuetext attribute for", obj, f"is '{text}'"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return text - - if not AXObject.supports_value(obj): - return "" - - try: - value = Atspi.Value.get_text(obj) - except GLib.GError as error: - msg = f"AXValue: Exception in get_current_value_text: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - value = "" - - tokens = ["AXValue: Value text of", obj, f"is '{value}'"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if value: - return value - - current = AXValue.get_current_value(obj) - if abs(current) < 1 and current != 0: - str_current = str(current) - decimal_places = len(str_current.split('.')[1]) - else: - decimal_places = 0 - - return f"{current:.{decimal_places}f}" - - @staticmethod - def get_value_as_percent(obj: Atspi.Accessible) -> Optional[int]: - """Returns the current value as a percent, or None if that is not applicable.""" - - if not AXObject.supports_value(obj): - return None - - value = AXValue.get_current_value(obj) - if AXUtilities.is_indeterminate(obj) and value <= 0: - tokens = ["AXValue:", obj, "has state indeterminate"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - minimum = AXValue.get_minimum_value(obj) - maximum = AXValue.get_maximum_value(obj) - if minimum == maximum: - return None - - result = int((value / (maximum - minimum)) * 100) - tokens = ["AXValue: Current value of", obj, f"as percent is is {result}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return result - - @staticmethod - def get_minimum_value(obj: Atspi.Accessible) -> float: - """Returns the minimum value of obj.""" - - if not AXObject.supports_value(obj): - return 0.0 - - try: - value = Atspi.Value.get_minimum_value(obj) - except GLib.GError as error: - msg = f"AXValue: Exception in get_minimum_value: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0.0 - - tokens = ["AXValue: Minimum value of", obj, f"is {value}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return value - - @staticmethod - def get_maximum_value(obj: Atspi.Accessible) -> float: - """Returns the maximum value of obj.""" - - if not AXObject.supports_value(obj): - return 0.0 - - try: - value = Atspi.Value.get_maximum_value(obj) - except GLib.GError as error: - msg = f"AXValue: Exception in get_maximum_value: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0.0 - - tokens = ["AXValue: Maximum value of", obj, f"is {value}"] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return value - -AXValue.start_cache_clearing_thread() diff --git a/src/cthulhu/backends/__init__.py b/src/cthulhu/backends/__init__.py deleted file mode 100644 index 301e5ea..0000000 --- a/src/cthulhu/backends/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - diff --git a/src/cthulhu/backends/meson.build b/src/cthulhu/backends/meson.build deleted file mode 100644 index f8a2b53..0000000 --- a/src/cthulhu/backends/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -backends_python_sources = files([ - '__init__.py', - 'toml_backend.py', -]) - -python3.install_sources( - backends_python_sources, - subdir: 'cthulhu/backends' -) diff --git a/src/cthulhu/backends/toml_backend.py b/src/cthulhu/backends/toml_backend.py deleted file mode 100644 index bdf3425..0000000 --- a/src/cthulhu/backends/toml_backend.py +++ /dev/null @@ -1,474 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""TOML backend for Cthulhu settings""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010-2011 Consorcio Fernando de los Rios." -__license__ = "LGPL" - -import os - -from tomlkit import parse, dumps, document - -from cthulhu import settings, acss - -class Backend: - - def __init__(self, prefsDir): - """ Initialize the TOML Backend. - """ - self.general = {} - self.pronunciations = {} - self.keybindings = {} - self.profiles = {} - self.settingsFile = os.path.join(prefsDir, "user-settings.toml") - self.appPrefsDir = os.path.join(prefsDir, "app-settings") - - self._defaultProfiles = {'default': { 'profile': settings.profile, - 'pronunciations': {}, - 'keybindings': {} - } - } - - def _stripNone(self, value): - if isinstance(value, dict): - cleaned = {} - for key, item in value.items(): - if item is None: - continue - cleanedItem = self._stripNone(item) - if cleanedItem is None: - continue - cleaned[key] = cleanedItem - return cleaned - if isinstance(value, list): - cleanedList = [] - for item in value: - if item is None: - continue - cleanedList.append(self._stripNone(item)) - return cleanedList - return value - - def _readDocument(self, fileName): - if os.path.exists(fileName): - with open(fileName, 'r', encoding='utf-8') as settingsFile: - return parse(settingsFile.read()) - return document() - - def _writeDocument(self, fileName, prefsDoc): - with open(fileName, 'w', encoding='utf-8') as settingsFile: - settingsFile.write(dumps(prefsDoc)) - - def _updateTable(self, targetTable, newValues, preserveMissingKeys=None): - if not isinstance(newValues, dict): - return - - preserveMissingKeys = set(preserveMissingKeys or []) - - for key in list(targetTable.keys()): - if key not in newValues: - if key in preserveMissingKeys: - continue - del targetTable[key] - continue - newValue = newValues[key] - existingValue = targetTable.get(key) - if isinstance(newValue, dict) and isinstance(existingValue, dict): - self._updateTable(existingValue, newValue) - continue - if existingValue != newValue: - targetTable[key] = newValue - - for key, newValue in newValues.items(): - if key not in targetTable: - targetTable[key] = newValue - - def _legacyProfileValue(self, profileTable, sectionName, legacyKey): - section = profileTable.get(sectionName) - if not isinstance(section, dict): - return None - return section.get(legacyKey) - - def _normalizeLegacyValue(self, currentKey, legacyValue): - if currentKey == 'keyboardLayout' and isinstance(legacyValue, str): - layout = legacyValue.strip().lower() - if layout == 'desktop': - return settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP - if layout == 'laptop': - return settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP - return legacyValue - - def _normalizeLegacyProfile(self, profileName, profileTable): - if not isinstance(profileTable, dict): - return profileTable - - profileSettings = {} - legacySections = { - 'metadata', - 'plugins', - 'ai-assistant', - 'ocr', - } - - for key, value in profileTable.items(): - if key in legacySections: - continue - if key == 'keybindings': - if isinstance(value, dict): - keybindings = dict(value) - keybindings.pop('keyboard-layout', None) - keybindings.pop('desktop-modifier-keys', None) - keybindings.pop('laptop-modifier-keys', None) - if keybindings: - profileSettings[key] = keybindings - continue - profileSettings[key] = value - - displayName = self._legacyProfileValue(profileTable, 'metadata', 'display-name') - internalName = self._legacyProfileValue(profileTable, 'metadata', 'internal-name') - if 'profile' not in profileSettings and (displayName or internalName): - profileSettings['profile'] = [ - displayName or str(profileName).title(), - internalName or profileName, - ] - - legacyKeyMap = { - ('keybindings', 'keyboard-layout'): 'keyboardLayout', - ('keybindings', 'desktop-modifier-keys'): 'cthulhuModifierKeys', - ('keybindings', 'laptop-modifier-keys'): 'cthulhuModifierKeys', - ('plugins', 'active-plugins'): 'activePlugins', - ('plugins', 'plugin-sources'): 'pluginSources', - ('ai-assistant', 'enabled'): 'aiAssistantEnabled', - ('ai-assistant', 'provider'): 'aiProvider', - ('ai-assistant', 'api-key-file'): 'aiApiKeyFile', - ('ai-assistant', 'ollama-model'): 'aiOllamaModel', - ('ai-assistant', 'ollama-endpoint'): 'aiOllamaEndpoint', - ('ai-assistant', 'confirmation-required'): 'aiConfirmationRequired', - ('ai-assistant', 'action-timeout'): 'aiActionTimeout', - ('ai-assistant', 'screenshot-quality'): 'aiScreenshotQuality', - ('ai-assistant', 'max-context-length'): 'aiMaxContextLength', - ('ocr', 'language-code'): 'ocrLanguageCode', - ('ocr', 'scale-factor'): 'ocrScaleFactor', - ('ocr', 'grayscale-image'): 'ocrGrayscaleImg', - ('ocr', 'invert-image'): 'ocrInvertImg', - ('ocr', 'black-white-image'): 'ocrBlackWhiteImg', - ('ocr', 'black-white-threshold'): 'ocrBlackWhiteImgValue', - ('ocr', 'color-calculation'): 'ocrColorCalculation', - ('ocr', 'color-calculation-max'): 'ocrColorCalculationMax', - ('ocr', 'copy-to-clipboard'): 'ocrCopyToClipboard', - } - - for (sectionName, legacyKey), currentKey in legacyKeyMap.items(): - if currentKey in profileSettings: - continue - legacyValue = self._legacyProfileValue(profileTable, sectionName, legacyKey) - if legacyValue is not None: - profileSettings[currentKey] = self._normalizeLegacyValue(currentKey, legacyValue) - - return profileSettings - - def _normalizeProfiles(self, profiles): - if not isinstance(profiles, dict): - return {} - return { - profileName: self._normalizeLegacyProfile(profileName, profileTable) - for profileName, profileTable in profiles.items() - } - - def _normalizeProfilesDocument(self, prefsDoc): - profiles = prefsDoc.get('profiles') - if not isinstance(profiles, dict): - return - - for profileName in list(profiles.keys()): - profileTable = profiles[profileName] - normalizedProfile = self._normalizeLegacyProfile(profileName, profileTable) - profiles[profileName] = self._stripNone(normalizedProfile) - - if 'format-version' in prefsDoc: - del prefsDoc['format-version'] - - def saveDefaultSettings(self, general, pronunciations, keybindings): - """ Save default settings for all the properties from - cthulhu.settings. """ - prefs = {'general': self._stripNone(general), - 'profiles': self._stripNone(self._defaultProfiles), - 'pronunciations': self._stripNone(pronunciations), - 'keybindings': self._stripNone(keybindings)} - - self.general = general - self.profiles = self._defaultProfiles - self.pronunciations = pronunciations - self.keybindings = keybindings - - prefsDoc = document() - prefsDoc['general'] = prefs['general'] - prefsDoc['profiles'] = prefs['profiles'] - prefsDoc['pronunciations'] = prefs['pronunciations'] - prefsDoc['keybindings'] = prefs['keybindings'] - - self._writeDocument(self.settingsFile, prefsDoc) - - def getAppSettings(self, appName): - fileName = os.path.join(self.appPrefsDir, f"{appName}.toml") - return self._readDocument(fileName) - - def saveAppSettings(self, appName, profile, general, pronunciations, keybindings): - prefsDoc = self.getAppSettings(appName) - profiles = prefsDoc.get('profiles') - if profiles is None or not isinstance(profiles, dict): - prefsDoc['profiles'] = {} - profiles = prefsDoc['profiles'] - - profileTable = profiles.get(profile) - if profileTable is None or not isinstance(profileTable, dict): - profiles[profile] = {} - profileTable = profiles[profile] - - self._updateTable(profileTable, { - 'general': self._stripNone(general), - 'pronunciations': self._stripNone(pronunciations), - 'keybindings': self._stripNone(keybindings), - }) - - fileName = os.path.join(self.appPrefsDir, f"{appName}.toml") - self._writeDocument(fileName, prefsDoc) - - def saveProfileSettings(self, profile, general, - pronunciations, keybindings): - """ Save minimal subset defined in the profile against current - defaults. """ - if profile is None: - profile = 'default' - - general['pronunciations'] = pronunciations - general['keybindings'] = keybindings - general = self._stripNone(general) - - prefsDoc = self._readDocument(self.settingsFile) - self._normalizeProfilesDocument(prefsDoc) - profiles = prefsDoc.get('profiles') - if profiles is None or not isinstance(profiles, dict): - prefsDoc['profiles'] = {} - profiles = prefsDoc['profiles'] - - profileTable = profiles.get(profile) - if profileTable is None or not isinstance(profileTable, dict): - profiles[profile] = {} - profileTable = profiles[profile] - - # Keep plugin persistence keys when callers provide partial updates. - self._updateTable( - profileTable, - general, - preserveMissingKeys={"activePlugins", "pluginSources"}, - ) - self._writeDocument(self.settingsFile, prefsDoc) - - def _getSettings(self): - """ Load from config file all settings """ - prefsDoc = self._readDocument(self.settingsFile) - try: - self.general = dict(prefsDoc.get('general', {})) - self.pronunciations = dict(prefsDoc.get('pronunciations', {})) - self.keybindings = dict(prefsDoc.get('keybindings', {})) - self.profiles = self._normalizeProfiles(dict(prefsDoc.get('profiles', {}))) - except Exception: - return - - def _migrateSettings(self, settingsDict): - """Migrate old setting names to new ones.""" - migrationKey = 'wineAccessibilityPluginMigrated' - activePlugins = settingsDict.get('activePlugins') - if isinstance(activePlugins, list) and migrationKey not in settingsDict: - if 'WineAccessibility' not in activePlugins: - activePlugins.append('WineAccessibility') - settingsDict[migrationKey] = True - - # Migration: enableSpeechIndentation -> enableIndentation - if 'enableSpeechIndentation' in settingsDict and 'enableIndentation' not in settingsDict: - settingsDict['enableIndentation'] = settingsDict['enableSpeechIndentation'] - - # Remove obsolete indentation settings that are now hardcoded - obsoleteKeys = [ - 'enableSpeechIndentation', - 'indentationChangeMode', - 'speakIndentationOnlyIfChanged', - 'indentationSpeechStyle', - 'indentationAudioUnit', - 'indentationSpacesPerLevel', - 'indentationTabWidth', - 'indentationAudioBaseFrequency', - 'indentationAudioStepFrequency', - 'indentationAudioMaxFrequency', - 'indentationAudioDuration', - 'indentationAudioVolume', - ] - for key in obsoleteKeys: - settingsDict.pop(key, None) - - return settingsDict - - def _hasLikelyCustomEchoVoice(self, echoVoice, defaultVoice): - """Return True when echoVoice appears intentionally customized.""" - - if not echoVoice: - return False - - echoEstablished = bool(echoVoice.get('established', False)) - if not defaultVoice: - return echoEstablished or bool(echoVoice.get(acss.ACSS.FAMILY)) - - for key in [acss.ACSS.RATE, acss.ACSS.AVERAGE_PITCH, acss.ACSS.GAIN, acss.ACSS.FAMILY]: - echoValue = echoVoice.get(key) - defaultValue = defaultVoice.get(key) - if echoValue is not None and echoValue != defaultValue: - return True - - return echoEstablished and bool(echoVoice.get(acss.ACSS.FAMILY)) - - def getGeneral(self, profile=None): - """ Get general settings from default settings and - override with profile values. """ - self._getSettings() - generalSettings = self.general.copy() - generalSettings = self._migrateSettings(generalSettings) - # Plugin state is profile-scoped; ignore legacy/global values. - generalSettings.pop('activePlugins', None) - generalSettings.pop('pluginSources', None) - defaultProfile = generalSettings.get('startingProfile', - ['Default', 'default']) - if profile is None: - profile = defaultProfile[1] - profileSettings = self.profiles[profile].copy() - profileSettings = self._migrateSettings(profileSettings) - for key, value in profileSettings.items(): - if key == 'voices': - for voiceType, voiceDef in value.items(): - value[voiceType] = acss.ACSS(voiceDef) - if key == 'echoVoice' and isinstance(value, dict): - value = acss.ACSS(value) - if key not in ['startingProfile', 'activeProfile']: - generalSettings[key] = value - - # Backward compatibility: recover custom echo behavior when legacy - # profiles have echoVoice but are missing custom-echo toggle keys. - if 'useCustomEchoVoice' not in profileSettings: - voices = generalSettings.get('voices') or {} - defaultVoice = voices.get(settings.DEFAULT_VOICE) - echoVoice = generalSettings.get('echoVoice') - if self._hasLikelyCustomEchoVoice(echoVoice, defaultVoice): - generalSettings['useCustomEchoVoice'] = True - if 'useCustomEchoForKey' not in profileSettings: - generalSettings['useCustomEchoForKey'] = True - if 'useCustomEchoForCharacter' not in profileSettings: - generalSettings['useCustomEchoForCharacter'] = True - - try: - generalSettings['activeProfile'] = profileSettings['profile'] - except KeyError: - generalSettings['activeProfile'] = defaultProfile - return generalSettings - - def getPronunciations(self, profile='default'): - """ Get pronunciation settings from default settings and - override with profile values. """ - self._getSettings() - pronunciations = self.pronunciations.copy() - profileSettings = self.profiles[profile].copy() - if 'pronunciations' in profileSettings: - pronunciations = profileSettings['pronunciations'] - return pronunciations - - def getKeybindings(self, profile='default'): - """ Get keybindings settings from default settings and - override with profile values. """ - self._getSettings() - keybindings = self.keybindings.copy() - profileSettings = self.profiles[profile].copy() - if 'keybindings' in profileSettings: - keybindings = profileSettings['keybindings'] - return keybindings - - def isFirstStart(self): - """ Check if we're in first start. """ - - return not os.path.exists(self.settingsFile) - - def _setProfileKey(self, key, value): - self.general[key] = value - - prefsDoc = self._readDocument(self.settingsFile) - general = prefsDoc.get('general') - if general is None or not isinstance(general, dict): - prefsDoc['general'] = {} - general = prefsDoc['general'] - - if value is None: - if key in general: - del general[key] - else: - general[key] = value - self._writeDocument(self.settingsFile, prefsDoc) - - def setFirstStart(self, value=False): - """Set firstStart. This user-configurable setting is primarily - intended to serve as an indication as to whether or not initial - configuration is needed.""" - self.general['firstStart'] = value - self._setProfileKey('firstStart', value) - - def availableProfiles(self): - """ List available profiles. """ - self._getSettings() - profiles = [] - - for profileName in self.profiles.keys(): - profileDict = self.profiles[profileName].copy() - profiles.append(profileDict.get('profile')) - - return profiles - - def removeProfile(self, profile): - """Remove an existing profile""" - def removeProfileFrom(dict): - del dict[profile] - # if we removed the last profile, restore the default ones - if len(dict) == 0: - for profileName in self._defaultProfiles: - dict[profileName] = self._defaultProfiles[profileName].copy() - - if profile in self.profiles: - removeProfileFrom(self.profiles) - - prefsDoc = self._readDocument(self.settingsFile) - profiles = prefsDoc.get('profiles') - if isinstance(profiles, dict) and profile in profiles: - removeProfileFrom(profiles) - self._writeDocument(self.settingsFile, prefsDoc) diff --git a/src/cthulhu/bookmarks.py b/src/cthulhu/bookmarks.py deleted file mode 100644 index 6d474f6..0000000 --- a/src/cthulhu/bookmarks.py +++ /dev/null @@ -1,330 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides the default implementation for bookmarks in Cthulhu.""" - -import pickle -import os -import urllib.parse - -from . import cthulhu # Need access to cthulhuApp - -from . import cmdnames -from . import keybindings -from . import input_event -from . import messages -from . import settings_manager -from .ax_object import AXObject - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -class Bookmarks: - """Represents a default bookmark handler.""" - def __init__(self, script): - self._script = script - self._bookmarks = {} - self._saveObservers = [] - self._loadObservers = [] - self._loadBookmarks() - self._currentbookmarkindex = None - self._handlers = self._setup_handlers() - self._bindings = self._setup_bindings() - - def get_bindings(self): - """Returns the bookmark keybindings.""" - - return self._bindings - - def get_handlers(self): - """Returns the bookmark handlers.""" - - return self._handlers - - def _setup_handlers(self): - """Sets up and returns the bookmark input event handlers.""" - - handlers = {} - - handlers["goToPrevBookmark"] = \ - input_event.InputEventHandler( - self.goToPrevBookmark, - cmdnames.BOOKMARK_GO_TO_PREVIOUS) - - handlers["goToNextBookmark"] = \ - input_event.InputEventHandler( - self.goToNextBookmark, - cmdnames.BOOKMARK_GO_TO_NEXT) - - handlers["goToBookmark"] = \ - input_event.InputEventHandler( - self.goToBookmark, - cmdnames.BOOKMARK_GO_TO) - - handlers["addBookmark"] = \ - input_event.InputEventHandler( - self.addBookmark, - cmdnames.BOOKMARK_ADD) - - handlers["saveBookmarks"] = \ - input_event.InputEventHandler( - self.saveBookmarks, - cmdnames.BOOKMARK_SAVE) - - return handlers - - def _setup_bindings(self): - """Sets up and returns the date-and-time-presenter key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "b", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("goToNextBookmark"))) - - bindings.add( - keybindings.KeyBinding( - "b", - keybindings.defaultModifierMask, - keybindings.CTHULHU_SHIFT_MODIFIER_MASK, - self._handlers.get("goToPrevBookmark"))) - - bindings.add( - keybindings.KeyBinding( - "b", - keybindings.defaultModifierMask, - keybindings.CTHULHU_ALT_MODIFIER_MASK, - self._handlers.get("saveBookmarks"))) - - for i in range(6): - bindings.add( - keybindings.KeyBinding( - str(i + 1), - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("goToBookmark"))) - - bindings.add( - keybindings.KeyBinding( - str(i + 1), - keybindings.defaultModifierMask, - keybindings.CTHULHU_ALT_MODIFIER_MASK, - self._handlers.get("addBookmark"))) - - return bindings - - def addSaveObserver(self, observer): - self._saveObservers.append(observer) - - def addLoadObserver(self, observer): - self._loadObservers.append(observer) - - def goToBookmark(self, script, inputEvent, index=None): - """ Go to the bookmark indexed by inputEvent.hw_code """ - # establish the _bookmarks index - index = index or inputEvent.hw_code - - try: - context = self._script.getFlatReviewContext() - context_info = self._bookmarks[index] - context.setCurrent(context_info['line'], context_info['zone'], \ - context_info['word'], context_info['char']) - self._bookmarks[index] = context_info - except KeyError: - self._script.presentMessage(messages.BOOKMARK_NOT_FOUND) - return - - self._script.flatReviewPresenter.present_item(script, inputEvent) - - # update the currentbookmark - self._currentbookmarkindex = index - - def addBookmark(self, script, inputEvent): - """ Add an in-page accessible object bookmark for this key. """ - context = self._script.getFlatReviewContext() - self._bookmarks[inputEvent.hw_code] = self._contextToBookmark(context) - self._script.presentMessage(messages.BOOKMARK_ENTERED) - - def saveBookmarks(self, script, inputEvent): - """ Save the bookmarks for this script. """ - try: - self.saveBookmarksToDisk(self._bookmarks) - self._script.presentMessage(messages.BOOKMARKS_SAVED) - except IOError: - self._script.presentMessage(messages.BOOKMARKS_SAVED_FAILURE) - - # Notify the observers - for o in self._saveObservers: - o() - - def goToNextBookmark(self, script, inputEvent): - """ Go to the next bookmark location. If no bookmark has yet to be - selected, the first bookmark will be used. """ - - # get the hardware keys that have registered bookmarks - hwkeys = sorted(self._bookmarks.keys()) - - # no bookmarks have been entered - if len(hwkeys) == 0: - self._script.presentMessage(messages.BOOKMARKS_NOT_FOUND) - return - # only 1 bookmark or we are just starting out - elif len(hwkeys) == 1 or self._currentbookmarkindex is None: - self.goToBookmark(None, index=hwkeys[0]) - return - - # find current bookmark hw_code in our sorted list. - # Go to next one if possible - try: - index = hwkeys.index(self._currentbookmarkindex) - self.goToBookmark(None, index=hwkeys[index+1]) - except (ValueError, KeyError, IndexError): - self.goToBookmark(None, index=hwkeys[0]) - - def goToPrevBookmark(self, script, inputEvent): - # get the hardware keys that have registered bookmarks - hwkeys = sorted(self._bookmarks.keys()) - - # no bookmarks have been entered - if len(hwkeys) == 0: - self._script.presentMessage(messages.BOOKMARKS_NOT_FOUND) - return - # only 1 bookmark or we are just starting out - elif len(hwkeys) == 1 or self._currentbookmarkindex is None: - self.goToBookmark(None, index=hwkeys[0]) - return - - # find current bookmark hw_code in our sorted list. - # Go to previous one if possible - try: - index = hwkeys.index(self._currentbookmarkindex) - self.goToBookmark(None, index=hwkeys[index-1]) - except (ValueError, KeyError, IndexError): - self.goToBookmark(None, index=hwkeys[0]) - - def _loadBookmarks(self): - """ Load this scripts saved bookmarks.""" - self._bookmarks = self.readBookmarksFromDisk() or {} - - # notify the observers - for o in self._loadObservers: - o() - - def readBookmarksFromDisk(self, filename=None): - """ Read saved bookmarks from disk. Currently an unpickled object - that represents a bookmark """ - filename = filename or self._script.name.split(' ')[0] - cthulhuDir = cthulhu.cthulhuApp.settingsManager.getPrefsDir() - if not cthulhuDir: - return - - cthulhuBookmarksDir = os.path.join(cthulhuDir, "bookmarks") - try: - inputFile = open( os.path.join( cthulhuBookmarksDir, \ - f'{filename}.pkl'), "r") - bookmarks = pickle.load(inputFile.buffer) - inputFile.close() - return bookmarks - except (IOError, EOFError, OSError): - return None - - def saveBookmarksToDisk(self, bookmarksObj, filename=None): - """ Write bookmarks to disk. bookmarksObj must be a pickleable - object. """ - filename = filename or self._script.name.split(' ')[0] - cthulhuDir = cthulhu.cthulhuApp.settingsManager.getPrefsDir() - cthulhuBookmarksDir = os.path.join(cthulhuDir, "bookmarks") - # create directory if it does not exist. correct place?? - try: - os.stat(cthulhuBookmarksDir) - except OSError: - os.mkdir(cthulhuBookmarksDir) - output = open( os.path.join( cthulhuBookmarksDir, \ - f'{filename}.pkl'), "w", os.O_CREAT) - pickle.dump(bookmarksObj, output.buffer) - output.close() - - def _contextToBookmark(self, context): - """Converts a flat_review.Context object into a bookmark.""" - context_info = {} - context_info['zone'] = context.zoneIndex - context_info['char'] = context.charIndex - context_info['word'] = context.wordIndex - context_info['line'] = context.lineIndex - return context_info - - def _bookmarkToContext(self, bookmark): - """Converts a bookmark into a flat_review.Context object.""" - context = self._script.getFlatReviewContext() - context.setCurrent(bookmark['line'], bookmark['zone'], \ - bookmark['word'], bookmark['char']) - return context - - def getURIKey(self): - """Returns the URI key for a given page as a URI stripped of - parameters?query#fragment as seen in urlparse.""" - uri = self._script.utilities.documentFrameURI() - if uri: - parsed_uri = urllib.parse.urlparse(uri) - return ''.join(parsed_uri[0:3]) - else: - return None - - def pathToObj(self, path): - """Return the object with the given path (relative to the - document frame). """ - returnobj = self._script.utilities.documentFrame() - for childnumber in path: - returnobj = AXObject.get_child(returnobj, childnumber) - if not returnobj: - break - - return returnobj - - def _objToPath(self, start_obj=None): - """Given an object, return it's path from the root accessible. If obj - is not provided, the current caret context is used. """ - if not start_obj: - [start_obj, characterOffset] = self._script.utilities.getCaretContext() - - if not start_obj: - return [] - - if self._script.utilities.isDocument(start_obj): - return [] - - path = [] - path.append(AXObject.get_index_in_parent(start_obj)) - p = AXObject.get_parent(start_obj) - while p: - if self._script.utilities.isDocument(p): - path.reverse() - return path - path.append(AXObject.get_index_in_parent(p)) - p = AXObject.get_parent(p) - - return [] diff --git a/src/cthulhu/braille.py b/src/cthulhu/braille.py deleted file mode 100644 index 71f1b4c..0000000 --- a/src/cthulhu/braille.py +++ /dev/null @@ -1,2112 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""A very experimental approach to the refreshable Braille display. This -module treats each line of the display as a sequential set of regions, where -each region can potentially backed by an Accessible object. Depending upon -the Accessible object, the cursor routing keys can be used to perform -operations on the Accessible object, such as invoking default actions or -moving the text caret. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import locale -import signal -import os -import re - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import brltablenames -from . import cmdnames -from . import debug -from . import logger -from . import cthulhu_state -from . import settings -from . import settings_manager - -from .ax_event_synthesizer import AXEventSynthesizer -from .ax_object import AXObject -from .ax_hypertext import AXHypertext -from .cthulhu_platform import tablesdir - -# Lazy initialization to avoid circular imports -_logger = None -log = None -_monitor = None -_settingsManager = None - -def _ensureLogger(): - """Ensure logger is initialized.""" - global _logger, log - if _logger is None: - from . import cthulhu - _logger = cthulhu.cthulhuApp.logger - log = _logger.newLog("braille") - -def _ensureSettingsManager(): - """Ensure settings manager is initialized.""" - global _settingsManager - if _settingsManager is None: - from . import cthulhu - _settingsManager = cthulhu.cthulhuApp.settingsManager - -try: - msg = "BRAILLE: About to import brlapi." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - import brlapi - _brlAPI = None - _brlAPIAvailable = True - _brlAPIRunning = False - _brlAPISourceId = 0 -except Exception: - msg = "BRAILLE: Could not import brlapi." - debug.printMessage(debug.LEVEL_WARNING, msg, True) - _brlAPIAvailable = False - _brlAPIRunning = False -else: - tokens = ["BRAILLE: brlapi imported", brlapi] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - -BRLAPI_PRIORITY_IDLE = 0 -BRLAPI_PRIORITY_DEFAULT = 50 -BRLAPI_PRIORITY_HIGH = 70 -brlapi_priority = BRLAPI_PRIORITY_DEFAULT - -try: - msg = "BRAILLE: About to import louis." - debug.printMessage(debug.LEVEL_INFO, msg, True) - import louis -except Exception: - msg = "BRAILLE: Could not import liblouis" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - louis = None -else: - tokens = ["BRAILLE: liblouis imported", louis] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - tokens = ["BRAILLE: tables location:", tablesdir] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # TODO: Can we get the tablesdir info at runtime? - if not tablesdir: - msg = "BRAILLE: Disabling liblouis due to unknown table location." \ - "This usually means cthulhu was built before liblouis was installed." - debug.printMessage(debug.LEVEL_INFO, msg, True) - louis = None - -try: - from . import brlmon -except Exception: - settings.enableBrailleMonitor = False - - -# brlapi keys which are not allowed to interrupt speech: -# -dontInteruptSpeechKeys = [] -if _brlAPIAvailable: - dontInteruptSpeechKeys = [ \ - brlapi.KEY_CMD_HWINLT, brlapi.KEY_CMD_HWINRT, \ - brlapi.KEY_CMD_FWINLT, brlapi.KEY_CMD_FWINRT, \ - brlapi.KEY_CMD_FWINLTSKIP, brlapi.KEY_CMD_FWINRTSKIP, \ - brlapi.KEY_CMD_LNUP, brlapi.KEY_CMD_LNDN] - -# Common names for most used BrlTTY commands, to be shown in the GUI: -# ATM, the ones used in default.py are: -# -command_name = {} - -if _brlAPIAvailable: - command_name[brlapi.KEY_CMD_HWINLT] = cmdnames.BRAILLE_LINE_LEFT - command_name[brlapi.KEY_CMD_FWINLT] = cmdnames.BRAILLE_LINE_LEFT - command_name[brlapi.KEY_CMD_FWINLTSKIP] = cmdnames.BRAILLE_LINE_LEFT - command_name[brlapi.KEY_CMD_HWINRT] = cmdnames.BRAILLE_LINE_RIGHT - command_name[brlapi.KEY_CMD_FWINRT] = cmdnames.BRAILLE_LINE_RIGHT - command_name[brlapi.KEY_CMD_FWINRTSKIP] = cmdnames.BRAILLE_LINE_RIGHT - command_name[brlapi.KEY_CMD_LNUP] = cmdnames.BRAILLE_LINE_UP - command_name[brlapi.KEY_CMD_LNDN] = cmdnames.BRAILLE_LINE_DOWN - command_name[brlapi.KEY_CMD_FREEZE] = cmdnames.BRAILLE_FREEZE - command_name[brlapi.KEY_CMD_TOP_LEFT] = cmdnames.BRAILLE_TOP_LEFT - command_name[brlapi.KEY_CMD_BOT_LEFT] = cmdnames.BRAILLE_BOTTOM_LEFT - command_name[brlapi.KEY_CMD_HOME] = cmdnames.BRAILLE_HOME - command_name[brlapi.KEY_CMD_SIXDOTS] = cmdnames.BRAILLE_SIX_DOTS - command_name[brlapi.KEY_CMD_ROUTE] = cmdnames.BRAILLE_ROUTE_CURSOR - command_name[brlapi.KEY_CMD_CUTBEGIN] = cmdnames.BRAILLE_CUT_BEGIN - command_name[brlapi.KEY_CMD_CUTLINE] = cmdnames.BRAILLE_CUT_LINE - -# The size of the physical display (width, height). The coordinate system of -# the display is set such that the upper left is (0,0), x values increase from -# left to right, and y values increase from top to bottom. -# -# For the purposes of testing w/o a braille display, we'll set the display -# size to width=32 and height=1. -# -# [[[TODO: WDW - Only a height of 1 is support at this time.]]] -# -DEFAULT_DISPLAY_SIZE = 32 -_displaySize = [DEFAULT_DISPLAY_SIZE, 1] - -# The list of lines on the display. This represents the entire amount of data -# to be drawn on the display. It will be clipped by the viewport if too large. -# -_lines = [] - -# The region with focus. This will be displayed at the home position. -# -_regionWithFocus = None - -# The last text information painted. This has the following fields: -# -# lastTextObj = the last accessible -# lastCaretOffset = the last caret offset of the last text displayed -# lastLineOffset = the last line offset of the last text displayed -# lastCursorCell = the last cell on the braille display for the caret -# -_lastTextInfo = (None, 0, 0, 0) - -# The viewport is a rectangular region of size _displaySize whose upper left -# corner is defined by the point (x, line number). As such, the viewport is -# identified solely by its upper left point. -# -viewport = [0, 0] - -# The callback to call on a BrlTTY input event. This is passed to -# the init method. -# -_callback = None - -# If True, the given portion of the currently displayed line is showing -# on the display. -# -endIsShowing = False -beginningIsShowing = False - -# 1-based offset saying which braille cell has the cursor. A value -# of 0 means no cell has the cursor. -# -cursorCell = 0 - -# The event source of a timeout used for flashing a message. -# -_flashEventSourceId = 0 - -# Line information saved prior to flashing any messages -# -_saved = None - -# Set to True when we lower our output priority -# -idle = False - -# Translators: These are the braille translation table names for different -# languages. You could read about braille tables at: -# http://en.wikipedia.org/wiki/Braille -# -TABLE_NAMES = {"Cz-Cz-g1": brltablenames.CZ_CZ_G1, - "Es-Es-g1": brltablenames.ES_ES_G1, - "Fr-Ca-g2": brltablenames.FR_CA_G2, - "Fr-Fr-g2": brltablenames.FR_FR_G2, - "Lv-Lv-g1": brltablenames.LV_LV_G1, - "Nl-Nl-g1": brltablenames.NL_NL_G1, - "No-No-g0": brltablenames.NO_NO_G0, - "No-No-g1": brltablenames.NO_NO_G1, - "No-No-g2": brltablenames.NO_NO_G2, - "No-No-g3": brltablenames.NO_NO_G3, - "Pl-Pl-g1": brltablenames.PL_PL_G1, - "Pt-Pt-g1": brltablenames.PT_PT_G1, - "Se-Se-g1": brltablenames.SE_SE_G1, - "ar-ar-g1": brltablenames.AR_AR_G1, - "cy-cy-g1": brltablenames.CY_CY_G1, - "cy-cy-g2": brltablenames.CY_CY_G2, - "de-de-g0": brltablenames.DE_DE_G0, - "de-de-g1": brltablenames.DE_DE_G1, - "de-de-g2": brltablenames.DE_DE_G2, - "en-GB-g2": brltablenames.EN_GB_G2, - "en-gb-g1": brltablenames.EN_GB_G1, - "en-us-g1": brltablenames.EN_US_G1, - "en-us-g2": brltablenames.EN_US_G2, - "fr-ca-g1": brltablenames.FR_CA_G1, - "fr-fr-g1": brltablenames.FR_FR_G1, - "gr-gr-g1": brltablenames.GR_GR_G1, - "hi-in-g1": brltablenames.HI_IN_G1, - "hu-hu-comp8": brltablenames.HU_HU_8DOT, - "hu-hu-g1": brltablenames.HU_HU_G1, - "hu-hu-g2": brltablenames.HU_HU_G2, - "it-it-g1": brltablenames.IT_IT_G1, - "nl-be-g1": brltablenames.NL_BE_G1} - -def listTables(): - tables = {} - try: - for fname in os.listdir(tablesdir): - if fname[-4:] in (".utb", ".ctb"): - alias = fname[:-4] - tables[TABLE_NAMES.get(alias, alias)] = \ - os.path.join(tablesdir, fname) - except OSError: - pass - - return tables - -def getDefaultTable(): - userLocale = locale.getlocale(locale.LC_MESSAGES)[0] - tokens = ["BRAILLE: User locale is", userLocale] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if userLocale in (None, "C"): - userLocale = locale.getdefaultlocale()[0] - tokens = ["BRAILLE: Default locale is", userLocale] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if userLocale in (None, "C"): - msg = "BRAILLE: Locale cannot be determined. Falling back on 'en-us'" - debug.printMessage(debug.LEVEL_INFO, msg, True) - language = "en-us" - else: - language = "-".join(userLocale.split("_")).lower() - - try: - tables = [x for x in os.listdir(tablesdir) if x[-4:] in (".utb", ".ctb")] - except OSError: - tokens = ["BRAILLE: Exception calling os.listdir for", tablesdir] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return "" - - # Some of the tables are probably not a good choice for default table.... - exclude = ["interline", "mathtext"] - - # Some of the tables might be a better default than others. For instance, someone who - # can read grade 2 braille presumably can read grade 1; the reverse is not necessarily - # true. Literary braille might be easier for some users to read than computer braille. - # We can adjust this based on user feedback, but in general the goal is a sane default - # for the largest group of users; not the perfect default for all users. - prefer = ["g1", "g2", "comp6", "comp8"] - - def isCandidate(t): - return t.startswith(language) and not any(e in t for e in exclude) - - tables = list(filter(isCandidate, tables)) - tokens = ["BRAILLE:", len(tables), "candidate tables for locale found:", ', '.join(tables)] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not tables: - return "" - - for p in prefer: - for table in tables: - if p in table: - return os.path.join(tablesdir, table) - - # If we couldn't find a preferred match, just go with the first match for the locale. - return os.path.join(tablesdir, tables[0]) - -if louis: - _defaultContractionTable = getDefaultTable() - tokens = ["BRAILLE: Default contraction table is:", _defaultContractionTable] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - -def _printBrailleEvent(level, command): - """Prints out a Braille event. The given level may be overridden - if the eventDebugLevel (see debug.setEventDebugLevel) is greater in - debug.py. - - Arguments: - - command: the BrlAPI command for the key that was pressed. - """ - - debug.printInputEvent( - level, - f"BRAILLE EVENT: {repr(command)}") - -class Region: - """A Braille region to be displayed on the display. The width of - each region is determined by its string. - """ - - def __init__(self, string, cursorOffset=0, expandOnCursor=False): - """Creates a new Region containing the given string. - - Arguments: - - string: the string to be displayed - - cursorOffset: a 0-based index saying where to draw the cursor - for this Region if it gets focus. - """ - - if not string: - string = "" - - # If louis is None, then we don't go into contracted mode. - self.contracted = settings.enableContractedBraille and louis is not None - - self.expandOnCursor = expandOnCursor - - # The uncontracted string for the line. - # - self.rawLine = string.strip("\n") - - if self.contracted: - self.contractionTable = settings.brailleContractionTable or _defaultContractionTable - if string.strip(): - tokens = ["BRAILLE: Contracting '", string, "' with table", self.contractionTable] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self.string, self.inPos, self.outPos, self.cursorOffset = \ - self.contractLine(self.rawLine, - cursorOffset, expandOnCursor) - else: - if string.strip(): - if not settings.enableContractedBraille: - msg = ( - f"BRAILLE: Not contracting '{string}' " - f"because contracted braille is not enabled." - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - msg = ( - f"BRAILLE: Not contracting '{string}' " - f"due to problem with liblouis." - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.string = self.rawLine - self.cursorOffset = cursorOffset - - def __str__(self): - return "Region: '%s', %d" % (self.string, self.cursorOffset) - - def processRoutingKey(self, offset): - """Processes a cursor routing key press on this Component. The offset - is 0-based, where 0 represents the leftmost character of string - associated with this region. Note that the zeroeth character may have - been scrolled off the display.""" - pass - - def getAttributeMask(self, getLinkMask=True): - """Creates a string which can be used as the attrOr field of brltty's - write structure for the purpose of indicating text attributes, links, - and selection. - - Arguments: - - getLinkMask: Whether or not we should take the time to get - the attributeMask for links. Reasons we might not want to - include knowing that we will fail and/or it taking an - unreasonable amount of time (AKA Gecko). - """ - - # Create an empty mask. - # - return '\x00' * len(self.string) - - def repositionCursor(self): - """Reposition the cursor offset for contracted mode. - """ - if self.contracted: - self.string, self.inPos, self.outPos, self.cursorOffset = \ - self.contractLine(self.rawLine, - self.cursorOffset, - self.expandOnCursor) - - def contractLine(self, line, cursorOffset=0, expandOnCursor=False): - """Contract the given line. Returns the contracted line, and the - cursor position in the contracted line. - - Arguments: - - line: Line to contract. - - cursorOffset: Offset of cursor,defaults to 0. - - expandOnCursor: Expand word under cursor, False by default. - """ - - try: - cursorOnSpace = line[cursorOffset] == ' ' - except IndexError: - cursorOnSpace = False - - if not expandOnCursor or cursorOnSpace: - mode = 0 - else: - mode = louis.compbrlAtCursor - - contracted, inPos, outPos, cursorPos = \ - louis.translate([self.contractionTable], - line, - cursorPos=cursorOffset, - mode=mode) - - # Make sure the cursor is at a realistic spot. - # Note that if cursorOffset is beyond the end of the buffer, - # a spurious value is returned by liblouis in cursorPos. - # - if cursorOffset >= len(line): - cursorPos = len(contracted) - else: - cursorPos = min(cursorPos, len(contracted)) - - return contracted, inPos, outPos, cursorPos - - def displayToBufferOffset(self, display_offset): - try: - offset = self.inPos[display_offset] - except IndexError: - # Off the chart, we just place the cursor at the end of the line. - offset = len(self.rawLine) - except AttributeError: - # Not in contracted mode. - offset = display_offset - - return offset - - def setContractedBraille(self, contracted): - if contracted: - self.contractionTable = settings.brailleContractionTable or _defaultContractionTable - self.contractRegion() - else: - self.expandRegion() - - def contractRegion(self): - if self.contracted: - return - self.string, self.inPos, self.outPos, self.cursorOffset = \ - self.contractLine(self.rawLine, - self.cursorOffset, - self.expandOnCursor) - self.contracted = True - - def expandRegion(self): - if not self.contracted: - return - self.string = self.rawLine - try: - self.cursorOffset = self.inPos[self.cursorOffset] - except IndexError: - self.cursorOffset = len(self.string) - self.contracted = False - -class Component(Region): - """A subclass of Region backed by an accessible. This Region will react - to any cursor routing key events and perform the default action on the - accessible, if a default action exists. - """ - - def __init__(self, accessible, string, cursorOffset=0, - indicator='', expandOnCursor=False): - """Creates a new Component. - - Arguments: - - accessible: the accessible - - string: the string to use to represent the component - - cursorOffset: a 0-based index saying where to draw the cursor - for this Region if it gets focus. - """ - - Region.__init__(self, string, cursorOffset, expandOnCursor) - if indicator: - if self.string: - self.string = indicator + ' ' + self.string - else: - self.string = indicator - - self.accessible = accessible - - def __str__(self): - return "Component: '%s', %d" % (self.string, self.cursorOffset) - - def getCaretOffset(self, offset): - """Returns the caret position of the given offset if the object - has text with a caret. Otherwise, returns -1. - - Arguments: - - offset: 0-based offset of the cell on the physical display - """ - return -1 - - def processRoutingKey(self, offset): - """Processes a cursor routing key press on this Component. The offset - is 0-based, where 0 represents the leftmost character of string - associated with this region. Note that the zeroeth character may have - been scrolled off the display.""" - - if cthulhu_state.activeScript and cthulhu_state.activeScript.utilities.\ - grabFocusBeforeRouting(self.accessible): - if AXObject.supports_component(self.accessible): - try: - Atspi.Component.grab_focus(self.accessible) - except Exception: - pass - - if AXObject.do_action(self.accessible, 0): - return - - # Do a mouse button 1 click if we have to. For example, page tabs - # don't have any actions but we want to be able to select them with - # the cursor routing key. - try: - result = AXEventSynthesizer.click_object(self.accessible, 1) - except Exception as error: - tokens = ["ERROR: Could not process routing key:", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - if not result: - msg = "INFO: Processing routing key failed" - debug.printMessage(debug.LEVEL_INFO, msg, True) - -class Link(Component): - """A subclass of Component backed by an accessible. This Region will be - marked as a link by dots 7 or 8, depending on the user's preferences. - """ - - def __init__(self, accessible, string, cursorOffset=0): - """Initialize a Link region. similar to Component, but here we always - have the region expand on cursor.""" - Component.__init__(self, accessible, string, cursorOffset, '', True) - - def __str__(self): - return "Link: '%s', %d" % (self.string, self.cursorOffset) - - def getAttributeMask(self, getLinkMask=True): - """Creates a string which can be used as the attrOr field of brltty's - write structure for the purpose of indicating text attributes and - selection. - Arguments: - - - getLinkMask: Whether or not we should take the time to get - the attributeMask for links. Reasons we might not want to - include knowing that we will fail and/or it taking an - unreasonable amount of time (AKA Gecko). - """ - - # Create an link indicator mask. - # - return chr(settings.brailleLinkIndicator) * len(self.string) - -class Text(Region): - """A subclass of Region backed by a Text object. This Region will - react to any cursor routing key events by positioning the caret in - the associated text object. The line displayed will be the - contents of the text object preceded by an optional label. - [[[TODO: WDW - need to add in text selection capabilities. Logged - as bugzilla bug 319754.]]]""" - - def __init__(self, accessible, label="", eol="", - startOffset=None, endOffset=None): - """Creates a new Text region. - - Arguments: - - accessible: the accessible that implements AccessibleText - - label: an optional label to display - """ - - self.accessible = accessible - if cthulhu_state.activeScript and self.accessible: - [string, self.caretOffset, self.lineOffset] = \ - cthulhu_state.activeScript.getTextLineAtCaret( - self.accessible, startOffset=startOffset, endOffset=endOffset) - else: - string = "" - self.caretOffset = 0 - self.lineOffset = 0 - - try: - endOffset = endOffset - self.lineOffset - except TypeError: - endOffset = len(string) - - try: - self.startOffset = startOffset - self.lineOffset - except TypeError: - self.startOffset = 0 - - string = string[self.startOffset:endOffset] - - self.caretOffset -= self.startOffset - - cursorOffset = min(self.caretOffset - self.lineOffset, len(string)) - - self._maxCaretOffset = self.lineOffset + len(string) - - self.eol = eol - - if label: - self.label = label + ' ' - else: - self.label = '' - - string = self.label + string - - cursorOffset += len(self.label) - - Region.__init__(self, string, cursorOffset, True) - - if not self.contracted and not settings.disableBrailleEOL: - self.string += self.eol - elif settings.disableBrailleEOL: - # Ensure there is a place to click on at the end of a line - # so the user can route the caret to the end of the line. - # - self.string += ' ' - - def __str__(self): - return "Text: '%s', %d" % (self.string, self.cursorOffset) - - def repositionCursor(self): - """Attempts to reposition the cursor in response to a new - caret position. If it is possible (i.e., the caret is on - the same line as it was), reposition the cursor and return - True. Otherwise, return False. - """ - - if not _regionWithFocus: - return False - - [string, caretOffset, lineOffset] = \ - cthulhu_state.activeScript.getTextLineAtCaret(self.accessible) - - cursorOffset = min(caretOffset - lineOffset, len(string)) - - if lineOffset != self.lineOffset: - return False - - self.caretOffset = caretOffset - self.lineOffset = lineOffset - - cursorOffset += len(self.label) - - if self.contracted: - self.string, self.inPos, self.outPos, cursorOffset = \ - self.contractLine(self.rawLine, cursorOffset, True) - - self.cursorOffset = cursorOffset - - return True - - def getCaretOffset(self, offset): - """Returns the caret position of the given offset if the object - has text with a caret. Otherwise, returns -1. - - Arguments: - - offset: 0-based offset of the cell on the physical display - """ - offset = self.displayToBufferOffset(offset) - - if offset < 0: - return -1 - - return min(self.lineOffset + offset, self._maxCaretOffset) - - def processRoutingKey(self, offset): - """Processes a cursor routing key press on this Component. The offset - is 0-based, where 0 represents the leftmost character of text - associated with this region. Note that the zeroeth character may have - been scrolled off the display. - """ - - caretOffset = self.getCaretOffset(offset) - - if caretOffset < 0: - return - - cthulhu_state.activeScript.utilities.setCaretOffset( - self.accessible, caretOffset) - - def getAttributeMask(self, getLinkMask=True): - """Creates a string which can be used as the attrOr field of brltty's - write structure for the purpose of indicating text attributes, links, - and selection. - - Arguments: - - getLinkMask: Whether or not we should take the time to get - the attributeMask for links. Reasons we might not want to - include knowing that we will fail and/or it taking an - unreasonable amount of time (AKA Gecko). - """ - - if not AXObject.supports_text(self.accessible): - return '' - - # Start with an empty mask. - # - stringLength = len(self.rawLine) - len(self.label) - lineEndOffset = self.lineOffset + stringLength - regionMask = [settings.BRAILLE_UNDERLINE_NONE]*stringLength - - attrIndicator = settings.textAttributesBrailleIndicator - selIndicator = settings.brailleSelectorIndicator - linkIndicator = settings.brailleLinkIndicator - script = cthulhu_state.activeScript - if script is None: - msg = "BRAILLE: Cannot get attribute mask without active script." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return "" - - if getLinkMask and linkIndicator != settings.BRAILLE_UNDERLINE_NONE: - if AXObject.supports_hypertext(self.accessible): - for link in AXHypertext.get_all_links(self.accessible): - start = AXHypertext.get_link_start_offset(link) - end = AXHypertext.get_link_end_offset(link) - if start < 0 or end < 0: - continue - if self.lineOffset <= start: - for i in range(start, end): - try: - regionMask[i] |= linkIndicator - except Exception: - pass - - if attrIndicator: - keys, enabledAttributes = script.utilities.stringToKeysAndDict( - settings.enabledBrailledTextAttributes) - - offset = self.lineOffset - while offset < lineEndOffset: - attributes, startOffset, endOffset = \ - script.utilities.textAttributes(self.accessible, - offset, True) - if endOffset <= offset: - break - mask = settings.BRAILLE_UNDERLINE_NONE - offset = endOffset - for attrib in attributes: - if enabledAttributes.get(attrib, '') != '': - if enabledAttributes[attrib] != attributes[attrib]: - mask = attrIndicator - break - if mask != settings.BRAILLE_UNDERLINE_NONE: - maskStart = max(startOffset - self.lineOffset, 0) - maskEnd = min(endOffset - self.lineOffset, stringLength) - for i in range(maskStart, maskEnd): - regionMask[i] |= attrIndicator - - if selIndicator: - selections = script.utilities.allTextSelections(self.accessible) - for startOffset, endOffset in selections: - maskStart = max(startOffset - self.lineOffset, 0) - maskEnd = min(endOffset - self.lineOffset, stringLength) - for i in range(maskStart, maskEnd): - regionMask[i] |= selIndicator - - if self.contracted: - contractedMask = [0] * len(self.rawLine) - outPos = self.outPos[len(self.label):] - if self.label: - # Transform the offsets. - outPos = \ - [offset - len(self.label) - 1 for offset in outPos] - for i, m in enumerate(regionMask): - try: - contractedMask[outPos[i]] |= m - except IndexError: - continue - regionMask = contractedMask[:len(self.string)] - - # Add empty mask characters for the EOL character as well as for - # any label that might be present. - # - regionMask += [0]*len(self.eol) - - if self.label: - regionMask = [0]*len(self.label) + regionMask - - return ''.join(map(chr, regionMask)) - - def contractLine(self, line, cursorOffset=0, expandOnCursor=True): - contracted, inPos, outPos, cursorPos = Region.contractLine( - self, line, cursorOffset, expandOnCursor) - - return contracted + self.eol, inPos, outPos, cursorPos - - def displayToBufferOffset(self, display_offset): - offset = Region.displayToBufferOffset(self, display_offset) - offset += self.startOffset - offset -= len(self.label) - return offset - - def setContractedBraille(self, contracted): - Region.setContractedBraille(self, contracted) - if not contracted: - self.string += self.eol - -class ReviewComponent(Component): - """A subclass of Component that is to be used for flat review mode.""" - - def __init__(self, accessible, string, cursorOffset, zone): - """Creates a new Component. - - Arguments: - - accessible: the accessible - - string: the string to use to represent the component - - cursorOffset: a 0-based index saying where to draw the cursor - for this Region if it gets focus. - - zone: the flat review Zone associated with this component - """ - Component.__init__(self, accessible, string, - cursorOffset, expandOnCursor=True) - self.zone = zone - - def __str__(self): - return "ReviewComponent: %s, %d" % (self.zone, self.cursorOffset) - -class ReviewText(Region): - """A subclass of Region backed by a Text object. This Region will - does not react to the caret changes, but will react if one updates - the cursorPosition. This class is meant to be used by flat review - mode to show the current character position. - """ - - def __init__(self, accessible, string, lineOffset, zone): - """Creates a new Text region. - - Arguments: - - accessible: the accessible that implements AccessibleText - - string: the string to use to represent the component - - lineOffset: the character offset into where the text line starts - - zone: the flat review Zone associated with this component - """ - Region.__init__(self, string, expandOnCursor=True) - self.accessible = accessible - self.lineOffset = lineOffset - self.zone = zone - - def __str__(self): - return "ReviewText: %s, %d" % (self.zone, self.cursorOffset) - - def getCaretOffset(self, offset): - """Returns the caret position of the given offset if the object - has text with a caret. Otherwise, returns -1. - - Arguments: - - offset: 0-based offset of the cell on the physical display - """ - offset = self.displayToBufferOffset(offset) - - if offset < 0: - return -1 - - return self.lineOffset + offset - - def processRoutingKey(self, offset): - """Processes a cursor routing key press on this Component. The offset - is 0-based, where 0 represents the leftmost character of text - associated with this region. Note that the zeroeth character may have - been scrolled off the display.""" - - caretOffset = self.getCaretOffset(offset) - cthulhu_state.activeScript.utilities.setCaretOffset( - self.accessible, caretOffset) - -class Line: - """A horizontal line on the display. Each Line is composed of a sequential - set of Regions. - """ - - def __init__(self, region=None): - self.regions = [] - self.string = "" - if region: - self.addRegion(region) - - def addRegion(self, region): - self.regions.append(region) - - def addRegions(self, regions): - self.regions.extend(regions) - - def getLineInfo(self, getLinkMask=True): - """Computes the complete string for this line as well as a - 0-based index where the focused region starts on this line. - If the region with focus is not on this line, then the index - will be -1. - - Arguments: - - getLinkMask: Whether or not we should take the time to get - the attributeMask for links. Reasons we might not want to - include knowing that we will fail and/or it taking an - unreasonable amount of time (AKA Gecko). - - Returns [string, offsetIndex, attributeMask, ranges] - """ - - string = "" - focusOffset = -1 - attributeMask = "" - ranges = [] - for region in self.regions: - if region == _regionWithFocus: - focusOffset = len(string) - if region.string: - string += region.string - mask = region.getAttributeMask(getLinkMask) - attributeMask += mask - - words = [word.span() for word in re.finditer(r"(^\s+|\S+\s*)", string)] - span = [] - for start, end in words: - if span and end - span[0] > _displaySize[0]: - ranges.append(span) - span = [] - if not span: - # Subdivide long words that exceed the display width. - wordLength = end - start - if wordLength > _displaySize[0]: - displayWidths = wordLength // _displaySize[0] - if displayWidths: - for i in range(displayWidths): - ranges.append([start + i * _displaySize[0], - start + (i+1) * _displaySize[0]]) - if wordLength % _displaySize[0]: - span = [start + displayWidths * _displaySize[0], end] - else: - continue - else: - span = [start, end] - else: - span[1] = end - if end == focusOffset: - ranges.append(span) - span = [] - else: - if span: - ranges.append(span) - - return [string, focusOffset, attributeMask, ranges] - - def getRegionAtOffset(self, offset): - """Finds the Region at the given 0-based offset in this line. - - Returns the [region, offsetinregion] where the region is - the region at the given offset, and offsetinregion is the - 0-based offset from the beginning of the region, representing - where in the region the given offset is.""" - - # Translate the cursor offset for this line into a cursor offset - # for a region, and then pass the event off to the region for - # handling. - # - foundRegion = None - string = "" - pos = 0 - for region in self.regions: - foundRegion = region - string = string + region.string - if len(string) > offset: - break - else: - pos = len(string) - - if offset >= len(string): - return [None, -1] - else: - return [foundRegion, offset - pos] - - def processRoutingKey(self, offset): - """Processes a cursor routing key press on this Component. The offset - is 0-based, where 0 represents the leftmost character of string - associated with this line. Note that the zeroeth character may have - been scrolled off the display.""" - - [region, regionOffset] = self.getRegionAtOffset(offset) - if region: - region.processRoutingKey(regionOffset) - - def setContractedBraille(self, contracted): - for region in self.regions: - region.setContractedBraille(contracted) - -def getRegionAtCell(cell): - """Given a 1-based cell offset, return the braille region - associated with that cell in the form of [region, offsetinregion] - where 'region' is the region associated with the cell and - 'offsetinregion' is the 0-based offset of where the cell is - in the region, where 0 represents the beginning of the region. - """ - - if len(_lines) > 0: - offset = (cell - 1) + viewport[0] - lineNum = viewport[1] - return _lines[lineNum].getRegionAtOffset(offset) - else: - return [None, -1] - -def getCaretContext(event): - """Gets the accesible and caret offset associated with the given - event. The event should have a BrlAPI event that contains an - argument value that corresponds to a cell on the display. - - Arguments: - - event: an instance of input_event.BrailleEvent. event.event is - the dictionary form of the expanded BrlAPI event. - """ - - offset = event.event["argument"] - [region, regionOffset] = getRegionAtCell(offset + 1) - if region and (isinstance(region, Text) or isinstance(region, ReviewText)): - accessible = region.accessible - caretOffset = region.getCaretOffset(regionOffset) - else: - accessible = None - caretOffset = -1 - - return [accessible, caretOffset] - -def clear(): - """Clears the logical structure, but keeps the Braille display as is - (until a refresh operation). - """ - - global _lines - global _regionWithFocus - global viewport - - _lines = [] - _regionWithFocus = None - viewport = [0, 0] - -def setLines(lines): - global _lines - _lines = lines - -def addLine(line): - """Adds a line to the logical display for painting. The line is added to - the end of the current list of known lines. It is necessary for the - viewport to be over the lines and for refresh to be called for the new - line to be painted. - - Arguments: - - line: an instance of Line to add. - """ - - _lines.append(line) - line._index = len(_lines) - -def getShowingLine(): - """Returns the Line that is currently being painted on the display. - """ - if len(_lines) > 0: - return _lines[viewport[1]] - else: - return Line() - -def setFocus(region, panToFocus=True, getLinkMask=True): - """Specififes the region with focus. This region will be positioned - at the home position if panToFocus is True. - - Arguments: - - region: the given region, which much be in a line that has been - added to the logical display - - panToFocus: whether or not to position the region at the home - position - - getLinkMask: Whether or not we should take the time to get the - attributeMask for links. Reasons we might not want to include - knowing that we will fail and/or it taking an unreasonable - amount of time (AKA Gecko). - """ - - global _regionWithFocus - - _regionWithFocus = region - - if not panToFocus or (not _regionWithFocus): - return - - # Adjust the viewport according to the new region with focus. - # The goal is to have the first cell of the region be in the - # home position, but we will give priority to make sure the - # cursor for the region is on the display. For example, when - # faced with a long text area, we'll show the position with - # the caret vs. showing the beginning of the region. - - lineNum = 0 - done = False - for line in _lines: - for reg in line.regions: - if reg == _regionWithFocus: - viewport[1] = lineNum - done = True - break - if done: - break - else: - lineNum += 1 - - line = _lines[viewport[1]] - [string, offset, attributeMask, ranges] = line.getLineInfo(getLinkMask) - - # If the cursor is too far right, we scroll the viewport - # so the cursor will be on the last cell of the display. - # - if _regionWithFocus.cursorOffset >= _displaySize[0]: - offset += _regionWithFocus.cursorOffset - _displaySize[0] + 1 - - viewport[0] = max(0, offset) - -def _idleBraille(): - """Try to hand off control to other screen readers without completely - shutting down the BrlAPI connection""" - - global idle - - if not idle: - try: - msg = "BRAILLE: Attempting to idle braille." - debug.printMessage(debug.LEVEL_INFO, msg, True) - _brlAPI.setParameter(brlapi.PARAM_CLIENT_PRIORITY, 0, False, BRLAPI_PRIORITY_IDLE) - idle = True - except Exception: - msg = "BRAILLE: Idling braille failled. This requires BrlAPI >= 0.8." - debug.printMessage(debug.LEVEL_INFO, msg, True) - pass - else: - msg = "BRAILLE: Idling braille succeeded." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - return idle - -def _clearBraille(): - """Clear Braille output, hand off control to other screen readers, without - completely shutting down the BrlAPI connection""" - - if not _brlAPIRunning: - # We do want to try to clear the output we left on the device - init(_callback) - - if _brlAPIRunning: - try: - _brlAPI.writeText("", 0) - _idleBraille() - except Exception: - msg = "BRAILLE: BrlTTY seems to have disappeared." - debug.printMessage(debug.LEVEL_WARNING, msg, True) - shutdown() - -def _enableBraille(): - """Re-enable Braille output after making it idle or clearing it""" - global idle - - tokens = ["BRAILLE: Enabling braille. BrlAPI running:", _brlAPIRunning] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not _brlAPIRunning: - msg = "BRAILLE: Need to initialize first." - debug.printMessage(debug.LEVEL_INFO, msg, True) - init(_callback) - - if _brlAPIRunning: - if idle: - msg = "BRAILLE: Is running, but idling." - debug.printMessage(debug.LEVEL_INFO, msg, True) - try: - # Restore default priority - msg = "BRAILLE: Attempting to de-idle braille." - debug.printMessage(debug.LEVEL_INFO, msg, True) - _brlAPI.setParameter(brlapi.PARAM_CLIENT_PRIORITY, 0, False, BRLAPI_PRIORITY_DEFAULT) - idle = False - except Exception: - msg = "BRAILLE: could not restore priority" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - else: - msg = "BRAILLE: De-idle succeeded." - debug.printMessage(debug.LEVEL_INFO, msg, True) - -def disableBraille(): - """Hand off control to other screen readers, shutting down the BrlAPI - connection if needed""" - - _ensureSettingsManager() - - global idle - - tokens = ["BRAILLE: Disabling braille. BrlAPI running:", _brlAPIRunning] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if _brlAPIRunning and not idle: - msg = "BRAILLE: BrlApi running and not idle." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - _ensureSettingsManager() - if not _idleBraille() and not _settingsManager.getSetting('enableBraille'): - # BrlAPI before 0.8 and we really want to shut down - msg = "BRAILLE: could not go idle, completely shut down" - debug.printMessage(debug.LEVEL_INFO, msg, True) - shutdown() - -def checkBrailleSetting(): - """Disable Braille if it got disabled in the preferences""" - - _ensureSettingsManager() - - msg = "BRAILLE: Checking braille setting." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if not _settingsManager.getSetting('enableBraille'): - disableBraille() - -def refresh(panToCursor=True, targetCursorCell=0, getLinkMask=True, stopFlash=True): - """Repaints the Braille on the physical display. This clips the entire - logical structure by the viewport and also sets the cursor to the - appropriate location. [[[TODO: WDW - I'm not sure how BrlTTY handles - drawing to displays with more than one line, so I'm only going to handle - drawing one line right now.]]] - - Arguments: - - panToCursor: if True, will adjust the viewport so the cursor is showing. - - targetCursorCell: Only effective if panToCursor is True. - 0 means automatically place the cursor somewhere on the display so - as to minimize movement but show as much of the line as possible. - A positive value is a 1-based target cell from the left side of - the display and a negative value is a 1-based target cell from the - right side of the display. - - getLinkMask: Whether or not we should take the time to get the - attributeMask for links. Reasons we might not want to include - knowing that we will fail and/or it taking an unreasonable - amount of time (AKA Gecko). - - stopFlash: if True, kill any flashed message that may be showing. - """ - - # TODO - JD: Split this work out into smaller methods. - - _ensureLogger() - _ensureSettingsManager() - - global endIsShowing - global beginningIsShowing - global cursorCell - global _monitor - global _lastTextInfo - - msg = f"BRAILLE: Refresh. Pan: {panToCursor} target: {targetCursorCell}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if stopFlash: - killFlash(restoreSaved=False) - - # TODO - JD: This should be taken care of in cthulhu.py. - _ensureSettingsManager() - if not _settingsManager.getSetting('enableBraille') \ - and not _settingsManager.getSetting('enableBrailleMonitor'): - if _brlAPIRunning: - msg = "BRAILLE: FIXME - Braille disabled, but not properly shut down." - debug.printMessage(debug.LEVEL_INFO, msg, True) - shutdown() - _lastTextInfo = (None, 0, 0, 0) - return - - if len(_lines) == 0: - _clearBraille() - _lastTextInfo = (None, 0, 0, 0) - return - - lastTextObj, lastCaretOffset, lastLineOffset, lastCursorCell = _lastTextInfo - tokens = ["BRAILLE: Last text object:", lastTextObj, - f"(Caret: {lastCaretOffset}, Line: {lastLineOffset}, Cell: {lastCursorCell})"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if _regionWithFocus and isinstance(_regionWithFocus, Text): - currentTextObj = _regionWithFocus.accessible - currentCaretOffset = _regionWithFocus.caretOffset - currentLineOffset = _regionWithFocus.lineOffset - else: - currentTextObj = None - currentCaretOffset = 0 - currentLineOffset = 0 - - onSameLine = currentTextObj and currentTextObj == lastTextObj \ - and currentLineOffset == lastLineOffset - - tokens = ["BRAILLE: Current text object:", currentTextObj, - f"(Caret: {currentCaretOffset}, Line: {currentLineOffset}). On same line:", - bool(onSameLine)] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if targetCursorCell < 0: - targetCursorCell = _displaySize[0] + targetCursorCell + 1 - msg = f"BRAILLE: Adjusted targetCursorCell to: {targetCursorCell}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - # If there is no target cursor cell and panning to cursor was - # requested, then try to set one. We - # currently only do this for text objects, and we do so by looking - # at the last position of the caret offset and cursor cell. The - # primary goal here is to keep the cursor movement on the display - # somewhat predictable. - - if panToCursor and targetCursorCell == 0 and onSameLine: - if lastCursorCell == 0: - msg = "BRAILLE: Not adjusting targetCursorCell. User panned caret out of view." - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif lastCaretOffset == currentCaretOffset: - targetCursorCell = lastCursorCell - msg = "BRAILLE: Setting targetCursorCell to previous value. Caret hasn't moved." - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif lastCaretOffset < currentCaretOffset: - newLocation = lastCursorCell + (currentCaretOffset - lastCaretOffset) - if newLocation <= _displaySize[0]: - msg = f"BRAILLE: Setting targetCursorCell based on offset: {newLocation}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - targetCursorCell = newLocation - else: - msg = "BRAILLE: Setting targetCursorCell to end of display." - debug.printMessage(debug.LEVEL_INFO, msg, True) - targetCursorCell = _displaySize[0] - elif lastCaretOffset > currentCaretOffset: - newLocation = lastCursorCell - (lastCaretOffset - currentCaretOffset) - if newLocation >= 1: - msg = f"BRAILLE: Setting targetCursorCell based on offset: {newLocation}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - targetCursorCell = newLocation - else: - msg = "BRAILLE: Setting targetCursorCell to start of display." - debug.printMessage(debug.LEVEL_INFO, msg, True) - targetCursorCell = 1 - - # Now, we figure out the 0-based offset for where the cursor actually is in the string. - - line = _lines[viewport[1]] - [string, focusOffset, attributeMask, ranges] = line.getLineInfo(getLinkMask) - msg = f"BRAILLE: Line {viewport[1]}: '{string}' focusOffset: {focusOffset} {ranges}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - cursorOffset = -1 - if focusOffset >= 0: - cursorOffset = focusOffset + _regionWithFocus.cursorOffset - msg = f"BRAILLE: Cursor offset in line string is: {cursorOffset}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - # Now, if desired, we'll automatically pan the viewport to show - # the cursor. If there's no targetCursorCell, then we favor the - # left of the display if we need to pan left, or we favor the - # right of the display if we need to pan right. - # - if panToCursor and (cursorOffset >= 0): - if len(string) <= _displaySize[0] and cursorOffset < _displaySize[0]: - msg = f"BRAILLE: Not adjusting offset {viewport[0]}. Cursor offset fits on display." - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif targetCursorCell: - viewport[0] = max(0, cursorOffset - targetCursorCell + 1) - msg = f"BRAILLE: Adjusting offset to {viewport[0]} based on targetCursorCell." - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif cursorOffset < viewport[0]: - viewport[0] = max(0, cursorOffset) - msg = f"BRAILLE: Adjusting offset to {viewport[0]} (cursor on left)" - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif cursorOffset >= (viewport[0] + _displaySize[0]): - viewport[0] = max(0, cursorOffset - _displaySize[0] + 1) - msg = f"BRAILLE: Adjusting offset to {viewport[0]} (cursor beyond display end)" - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - rangeForOffset = _getRangeForOffset(cursorOffset) - viewport[0] = max(0, rangeForOffset[0]) - msg = f"BRAILLE: Adjusting offset to {viewport[0]} (unhandled condition)" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if cursorOffset >= (viewport[0] + _displaySize[0]): - viewport[0] = max(0, cursorOffset - _displaySize[0] + 1) - msg = f"BRAILLE: Readjusting offset to {viewport[0]} (cursor beyond display end)" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - startPos, endPos = _adjustForWordWrap(targetCursorCell) - viewport[0] = startPos - - # Now normalize the cursor position to BrlTTY, which uses 1 as - # the first cursor position as opposed to 0. - # - cursorCell = cursorOffset - startPos - if (cursorCell < 0) or (cursorCell >= _displaySize[0]): - cursorCell = 0 - else: - cursorCell += 1 # Normalize to 1-based offset - - logLine = f"BRAILLE LINE: '{string}'" - debug.printMessage(debug.LEVEL_INFO, logLine, True) - log.info(logLine) - - logLine = f" VISIBLE: '{string[startPos:endPos]}', cursor={cursorCell}" - debug.printMessage(debug.LEVEL_INFO, logLine, True) - log.info(logLine) - - substring = string[startPos:endPos] - if attributeMask: - submask = attributeMask[startPos:endPos] - else: - submask = "" - - submask += '\x00' * (len(substring) - len(submask)) - - _ensureSettingsManager() - if _settingsManager.getSetting('enableBraille'): - _enableBraille() - - if _settingsManager.getSetting('enableBraille') and _brlAPIRunning: - writeStruct = brlapi.WriteStruct() - writeStruct.regionBegin = 1 - writeStruct.regionSize = len(substring) - while writeStruct.regionSize < _displaySize[0]: - substring += " " - if attributeMask: - submask += '\x00' - writeStruct.regionSize += 1 - writeStruct.text = substring - writeStruct.cursor = cursorCell - - # [[[WDW - if you want to muck around with the dots on the - # display to do things such as add underlines, you can use - # the attrOr field of the write structure to do so. The - # attrOr field is a string whose length must be the same - # length as the display and whose dots will end up showing - # up on the display. Each character represents a bitfield - # where each bit corresponds to a dot (i.e., bit 0 = dot 1, - # bit 1 = dot 2, and so on). Here's an example that underlines - # all the text.]]] - # - #myUnderline = "" - #for i in range(0, _displaySize[0]): - # myUnderline += '\xc0' - #writeStruct.attrOr = myUnderline - - if attributeMask: - writeStruct.attrOr = submask - - try: - _brlAPI.write(writeStruct) - except Exception: - msg = "BRAILLE: BrlTTY seems to have disappeared." - debug.printMessage(debug.LEVEL_WARNING, msg, True) - shutdown() - - if settings.enableBrailleMonitor: - if not _monitor: - try: - _monitor = brlmon.BrlMon(_displaySize[0]) - _monitor.show_all() - except Exception: - debug.printMessage(debug.LEVEL_WARNING, "brlmon failed") - _monitor = None - if attributeMask: - subMask = attributeMask[startPos:endPos] - else: - subMask = None - if _monitor: - _monitor.writeText(cursorCell, substring, subMask) - elif _monitor: - _monitor.destroy() - _monitor = None - - beginningIsShowing = startPos == 0 - endIsShowing = endPos >= len(string) - - # Remember the text information we were presenting (if any) - # - if _regionWithFocus and isinstance(_regionWithFocus, Text): - _lastTextInfo = (_regionWithFocus.accessible, - _regionWithFocus.caretOffset, - _regionWithFocus.lineOffset, - cursorCell) - else: - _lastTextInfo = (None, 0, 0, 0) - -def _flashCallback(): - global _lines - global _regionWithFocus - global viewport - global _flashEventSourceId - - if _flashEventSourceId: - (_lines, _regionWithFocus, viewport, flashTime) = _saved - refresh(panToCursor=False, stopFlash=False) - _flashEventSourceId = 0 - - return False - -def killFlash(restoreSaved=True): - global _flashEventSourceId - global _lines - global _regionWithFocus - global viewport - if _flashEventSourceId: - if _flashEventSourceId > 0: - GLib.source_remove(_flashEventSourceId) - if restoreSaved: - (_lines, _regionWithFocus, viewport, flashTime) = _saved - refresh(panToCursor=False, stopFlash=False) - _flashEventSourceId = 0 - -def resetFlashTimer(): - global _flashEventSourceId - if _flashEventSourceId > 0: - GLib.source_remove(_flashEventSourceId) - flashTime = _saved[3] - _flashEventSourceId = GLib.timeout_add(flashTime, _flashCallback) - -def _initFlash(flashTime): - """Sets up the state needed to flash a message or clears any existing - flash if nothing is to be flashed. - - Arguments: - - flashTime: if non-0, the number of milliseconds to display the - regions before reverting back to what was there before. - A 0 means to not do any flashing. A negative number - means display the message until some other message - comes along or the user presses a cursor routing key. - """ - - global _saved - global _flashEventSourceId - - if _flashEventSourceId: - if _flashEventSourceId > 0: - GLib.source_remove(_flashEventSourceId) - _flashEventSourceId = 0 - else: - _saved = (_lines, _regionWithFocus, viewport, flashTime) - - if flashTime > 0: - _flashEventSourceId = GLib.timeout_add(flashTime, _flashCallback) - elif flashTime < 0: - _flashEventSourceId = -666 - -def displayRegions(regionInfo, flashTime=0): - """Displays a list of regions on a single line, setting focus to the - specified region. The regionInfo parameter is something that is - typically returned by a call to braille_generator.generateBraille. - - Arguments: - - regionInfo: a list where the first element is a list of regions - to display and the second element is the region - with focus (must be in the list from element 0) - - flashTime: if non-0, the number of milliseconds to display the - regions before reverting back to what was there before. - A 0 means to not do any flashing. A negative number - means display the message until some other message - comes along or the user presses a cursor routing key. - """ - - # Block braille for applications in sleep mode - from . import cthulhu_state - from . import sleep_mode_manager - if cthulhu_state.activeScript and hasattr(cthulhu_state.activeScript, 'app'): - sleepModeManager = sleep_mode_manager.getManager() - if sleepModeManager.isActiveForApp(cthulhu_state.activeScript.app): - from . import debug - debug.printMessage(debug.LEVEL_INFO, "BRAILLE: Blocked by sleep mode", True) - return - - _initFlash(flashTime) - regions = regionInfo[0] - focusedRegion = regionInfo[1] - - clear() - line = Line() - for item in regions: - line.addRegion(item) - addLine(line) - setFocus(focusedRegion) - refresh(stopFlash=False) - -def displayMessage(message, cursor=-1, flashTime=0): - """Displays a single line, setting the cursor to the given position, - ensuring that the cursor is in view. - - Arguments: - - message: the string to display - - cursor: the 0-based cursor position, where -1 (default) means no cursor - - flashTime: if non-0, the number of milliseconds to display the - regions before reverting back to what was there before. - A 0 means to not do any flashing. A negative number - means display the message until some other message - comes along or the user presses a cursor routing key. - """ - - # Block braille for applications in sleep mode - from . import cthulhu_state - from . import sleep_mode_manager - if cthulhu_state.activeScript and hasattr(cthulhu_state.activeScript, 'app'): - sleepModeManager = sleep_mode_manager.getManager() - if sleepModeManager.isActiveForApp(cthulhu_state.activeScript.app): - from . import debug - debug.printMessage(debug.LEVEL_INFO, f"BRAILLE: Blocked by sleep mode: '{message}'", True) - return - - _initFlash(flashTime) - clear() - region = Region(message, cursor) - addLine(Line(region)) - setFocus(region) - refresh(True, stopFlash=False) - -def displayKeyEvent(event): - """Displays a KeyboardEvent. Typically reserved for locking keys like - Caps Lock and Num Lock.""" - - lockingStateString = event.getLockingStateString() - if lockingStateString: - keyname = event.getKeyName() - msg = f"{keyname} {lockingStateString}" - displayMessage(msg, flashTime=settings.brailleFlashTime) - -def _adjustForWordWrap(targetCursorCell): - startPos = viewport[0] - endPos = startPos + _displaySize[0] - msg = f"BRAILLE: Current range: ({startPos}, {endPos}). Target cell: {targetCursorCell}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if not _lines or not settings.enableBrailleWordWrap: - return startPos, endPos - - line = _lines[viewport[1]] - lineString, focusOffset, attributeMask, ranges = line.getLineInfo() - ranges = list(filter(lambda x: x[0] <= startPos + targetCursorCell < x[1], ranges)) - if ranges: - msg = f"BRAILLE: Adjusted range: ({ranges[0][0]}, {ranges[-1][1]})" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if ranges[-1][1] - ranges[0][0] > _displaySize[0]: - msg = "BRAILLE: Not adjusting range which is greater than display size" - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - startPos, endPos = ranges[0][0], ranges[-1][1] - - return startPos, endPos - -def _getRangeForOffset(offset): - string, focusOffset, attributeMask, ranges = _lines[viewport[1]].getLineInfo() - for r in ranges: - if r[0] <= offset < r[1]: - return r - for r in ranges: - if offset == r[1]: - return r - - return [0, 0] - -def panLeft(panAmount=0): - """Pans the display to the left, limiting the pan to the beginning - of the line being displayed. - - Arguments: - - panAmount: the amount to pan. A value of 0 means the entire - width of the physical display. - - Returns True if a pan actually happened. - """ - - oldX = viewport[0] - if panAmount == 0: - oldStart, oldEnd = _getRangeForOffset(oldX) - newStart, newEnd = _getRangeForOffset(oldStart - _displaySize[0]) - panAmount = max(0, min(oldStart - newStart, _displaySize[0])) - - viewport[0] = max(0, viewport[0] - panAmount) - msg = f"BRAILLE: Panning left. Amount: {panAmount} (from {oldX} to {viewport[0]})" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return oldX != viewport[0] - -def panRight(panAmount=0): - """Pans the display to the right, limiting the pan to the length - of the line being displayed. - - Arguments: - - panAmount: the amount to pan. A value of 0 means the entire - width of the physical display. - - Returns True if a pan actually happened. - """ - - oldX = viewport[0] - if panAmount == 0: - oldStart, oldEnd = _getRangeForOffset(oldX) - newStart, newEnd = _getRangeForOffset(oldEnd) - panAmount = max(0, min(newStart - oldStart, _displaySize[0])) - - if len(_lines) > 0: - lineNum = viewport[1] - newX = viewport[0] + panAmount - string, focusOffset, attributeMask, ranges = _lines[lineNum].getLineInfo() - if newX < len(string): - viewport[0] = newX - - msg = f"BRAILLE: Panning right. Amount: {panAmount} (from {oldX} to {viewport[0]})" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return oldX != viewport[0] - -def panToOffset(offset): - """Automatically pan left or right to make sure the current offset is - showing.""" - - msg = f"BRAILLE: Panning to offset {offset}. Current offset: {viewport[0]}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - while offset < viewport[0]: - if not panLeft(): - break - - while offset >= (viewport[0] + _displaySize[0]): - if not panRight(): - break - -def returnToRegionWithFocus(inputEvent=None): - """Pans the display so the region with focus is displayed. - - Arguments: - - inputEvent: the InputEvent instance that caused this to be called. - - Returns True to mean the command should be consumed. - """ - - setFocus(_regionWithFocus) - refresh(True) - - return True - -def setContractedBraille(event): - """Turns contracted braille on or off based upon the event. - - Arguments: - - event: an instance of input_event.BrailleEvent. event.event is - the dictionary form of the expanded BrlAPI event. - """ - - settings.enableContractedBraille = \ - (event.event["flags"] & brlapi.KEY_FLG_TOGGLE_ON) != 0 - for line in _lines: - line.setContractedBraille(settings.enableContractedBraille) - refresh() - -def processRoutingKey(event): - """Processes a cursor routing key event. - - Arguments: - - event: an instance of input_event.BrailleEvent. event.event is - the dictionary form of the expanded BrlAPI event. - """ - - # If a message is being flashed, we'll use a routing key to dismiss it. - # - if _flashEventSourceId: - killFlash() - return - - cell = event.event["argument"] - - if len(_lines) > 0: - cursor = cell + viewport[0] - lineNum = viewport[1] - _lines[lineNum].processRoutingKey(cursor) - - return True - -def _processBrailleEvent(event): - """Handles BrlTTY command events. This passes commands on to Cthulhu for - processing. - - Arguments: - - event: the BrlAPI input event (expanded) - """ - - _printBrailleEvent(debug.LEVEL_FINE, event) - - consumed = False - - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.signal(signal.SIGALRM, settings.timeoutCallback) - signal.alarm(settings.timeoutTime) - - if _callback: - try: - # Like key event handlers, a return value of True means - # the command was consumed. - # - consumed = _callback(event) - except Exception: - debug.printMessage(debug.LEVEL_WARNING, "Issue processing event:") - debug.printException(debug.LEVEL_WARNING) - consumed = False - - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.alarm(0) - - return consumed - -def _brlAPIKeyReader(source, condition): - """Method to read a key from the BrlAPI bindings. This is a - gobject IO watch handler. - """ - try: - key = _brlAPI.readKey(False) - except Exception: - debug.printMessage(debug.LEVEL_WARNING, "BrlTTY seems to have disappeared:") - debug.printException(debug.LEVEL_WARNING) - shutdown() - return - if key: - _processBrailleEvent(_brlAPI.expandKeyCode(key)) - return _brlAPIRunning - -def setupKeyRanges(keys): - """Hacky method to tell BrlTTY what to send and not send us via - the readKey method. This only works with BrlTTY v3.8 and better. - - Arguments: - -keys: a list of BrlAPI commands. - """ - - msg = "BRAILLE: Setting up key ranges." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if not _brlAPIRunning: - init(_callback) - - if not _brlAPIRunning: - msg = "BRAILLE: Not setting up key ranges: BrlAPI not running." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - msg = "BRAILLE: Ignoring all key ranges." - debug.printMessage(debug.LEVEL_INFO, msg, True) - _brlAPI.ignoreKeys(brlapi.rangeType_all, [0]) - - keySet = [brlapi.KEY_TYPE_CMD | brlapi.KEY_CMD_ROUTE] - - msg = "BRAILLE: Enabling commands:" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - for key in keys: - keySet.append(brlapi.KEY_TYPE_CMD | key) - - msg = "BRAILLE: Sending keys to BrlAPI." - debug.printMessage(debug.LEVEL_INFO, msg, True) - _brlAPI.acceptKeys(brlapi.rangeType_command, keySet) - - msg = "BRAILLE: Key ranges set up." - debug.printMessage(debug.LEVEL_INFO, msg, True) - -def setBrlapiPriority(level=BRLAPI_PRIORITY_DEFAULT): - """Set BRLAPI priority. - - Arguments: - - level: the priority level to apply. - """ - - global idle, brlapi_priority - - if not _brlAPIAvailable or not _brlAPIRunning or not settings.enableBraille: - return - - if idle: - msg = "BRAILLE: Braille is idle, don't change BRLAPI priority." - debug.printMessage(debug.LEVEL_INFO, msg, True) - brlapi_priority = level - return - - try: - tokens = ["BRAILLE: Setting priority to:", level] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - _brlAPI.setParameter(brlapi.PARAM_CLIENT_PRIORITY, 0, False, level) - except Exception as error: - msg = f"BRAILLE: Cannot set priority: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - else: - msg = "BRAILLE: Priority set." - debug.printMessage(debug.LEVEL_INFO, msg, True) - brlapi_priority = level - -def init(callback=None): - """Initializes the braille module, connecting to the BrlTTY driver. - - Arguments: - - callback: the method to call with a BrlTTY input event. - Returns False if BrlTTY cannot be accessed or braille has - not been enabled. - """ - - if not settings.enableBraille: - return False - - global _brlAPI - global _brlAPIRunning - global _brlAPISourceId - global _displaySize - global _callback - global _monitor - - tokens = ["BRAILLE: Initializing. Callback:", callback] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if _brlAPIRunning: - msg = "BRAILLE: BrlAPI is already running." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - _callback = callback - - tokens = ["BRAILLE: WINDOWPATH=", os.environ.get('WINDOWPATH')] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - tokens = ["BRAILLE: XDG_VTNR=", os.environ.get('XDG_VTNR')] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - try: - msg = "BRAILLE: Attempting connection with BrlAPI." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - _brlAPI = brlapi.Connection() - tokens = ["BRAILLE: Connection established with BrlAPI:", _brlAPI] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - msg = "BRAILLE: Attempting to enter TTY mode." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - _brlAPI.enterTtyModeWithPath() - msg = "BRAILLE: TTY mode entered." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - _brlAPIRunning = True - - (x, y) = _brlAPI.displaySize - msg = f"BRAILLE: Display size: ({x},{y})" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if x == 0: - msg = "BRAILLE: Error - 0 cells suggests display is not yet plugged in." - debug.printMessage(debug.LEVEL_WARNING, msg, True) - raise Exception - - _brlAPISourceId = GLib.io_add_watch(_brlAPI.fileDescriptor, - GLib.PRIORITY_DEFAULT, - GLib.IO_IN, - _brlAPIKeyReader) - - except NameError: - msg = "BRAILLE: Initialization failed: BrlApi is not defined." - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - except Exception: - msg = "BRAILLE: Initialization failed." - debug.printMessage(debug.LEVEL_WARNING, msg, True) - debug.printException(debug.LEVEL_WARNING) - - _brlAPIRunning = False - - if not _brlAPI: - return False - - try: - msg = "BRAILLE: Attempting to leave TTY mode." - debug.printMessage(debug.LEVEL_INFO, msg, True) - _brlAPI.leaveTtyMode() - msg = "BRAILLE: TTY mode exited." - debug.printMessage(debug.LEVEL_INFO, msg, True) - except Exception: - msg = "BRAILLE: Exception leaving TTY mode." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - try: - msg = "BRAILLE: Attempting to close connection." - debug.printMessage(debug.LEVEL_INFO, msg, True) - _brlAPI.closeConnection() - msg = "BRAILLE: Connection closed." - debug.printMessage(debug.LEVEL_INFO, msg, True) - except Exception: - msg = "BRAILLE: Exception closing connection." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - _brlAPI = None - return False - - _displaySize = [x, 1] - - # The monitor will be created in refresh if needed. - if _monitor: - _monitor.destroy() - _monitor = None - - clear() - refresh(True) - - msg = "BRAILLE: Initialized" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - -def shutdown(): - """Shuts down the braille module. Returns True if the shutdown procedure - was run. - """ - - msg = "BRAILLE: Attempting braille shutdown." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - global _brlAPI - global _brlAPIRunning - global _brlAPISourceId - global _monitor - global _displaySize - - if _brlAPIRunning: - _brlAPIRunning = False - - msg = "BRAILLE: Removing BrlAPI Source ID." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - GLib.source_remove(_brlAPISourceId) - _brlAPISourceId = 0 - - try: - msg = "BRAILLE: Attempting to leave TTY mode." - debug.printMessage(debug.LEVEL_INFO, msg, True) - _brlAPI.leaveTtyMode() - except Exception: - msg = "BRAILLE: Exception leaving TTY mode." - debug.printMessage(debug.LEVEL_WARNING, msg, True) - else: - msg = "BRAILLE: Leaving TTY mode succeeded." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - try: - msg = "BRAILLE: Attempting to close connection." - debug.printMessage(debug.LEVEL_INFO, msg, True) - _brlAPI.closeConnection() - except Exception: - msg = "BRAILLE: Exception closing connection." - debug.printMessage(debug.LEVEL_WARNING, msg, True) - else: - msg = "BRAILLE: Closing connection succeeded." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - _brlAPI = None - - if _monitor: - _monitor.destroy() - _monitor = None - _displaySize = [DEFAULT_DISPLAY_SIZE, 1] - else: - msg = "BRAILLE: Braille was not running." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - msg = "BRAILLE: Braille shutdown complete." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True diff --git a/src/cthulhu/braille_generator.py b/src/cthulhu/braille_generator.py deleted file mode 100644 index 43d3151..0000000 --- a/src/cthulhu/braille_generator.py +++ /dev/null @@ -1,531 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Utilities for obtaining braille presentations for objects.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import braille -from . import cthulhu # Need access to cthulhuApp -from . import debug -from . import generator -from . import messages -from . import object_properties -from . import role_keys -from . import cthulhu_state -from . import settings -from . import settings_manager -from .ax_object import AXObject -from .ax_text import AXText -from .ax_utilities import AXUtilities -from .ax_utilities_relation import AXUtilitiesRelation -from .braille_rolenames import shortRoleNames - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -class Space: - """A dummy class to indicate we want to insert a space into an - utterance, but only if there is text prior to the space.""" - def __init__(self, delimiter=" "): - self.delimiter = delimiter - -SPACE = [Space()] - -class BrailleGenerator(generator.Generator): - """Takes accessible objects and produces a list of braille Regions - for those objects. See the generateBraille method, which is the - primary entry point. Subclasses can feel free to override/extend - the brailleGenerators instance field as they see fit.""" - - SKIP_CONTEXT_ROLES = (Atspi.Role.MENU, - Atspi.Role.MENU_BAR, - Atspi.Role.PAGE_TAB_LIST, - Atspi.Role.REDUNDANT_OBJECT, - Atspi.Role.UNKNOWN, - Atspi.Role.COMBO_BOX) - - def __init__(self, script): - generator.Generator.__init__(self, script, "braille") - - def _addGlobals(self, globalsDict): - """Other things to make available from the formatting string. - """ - generator.Generator._addGlobals(self, globalsDict) - globalsDict['space'] = self.space - globalsDict['Component'] = braille.Component - globalsDict['Region'] = braille.Region - globalsDict['Text'] = braille.Text - globalsDict['Link'] = braille.Link - globalsDict['asString'] = self.asString - - def _isCandidateFocusedRegion(self, obj, region): - if not isinstance(region, (braille.Component, braille.Text)): - return False - - if not AXUtilities.have_same_role(obj, region.accessible): - return False - - return AXObject.get_name(obj) == AXObject.get_name(region.accessible) - - def generateBraille(self, obj, **args): - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - debug.printMessage(debug.LEVEL_INFO, "BRAILLE GENERATOR: generation disabled", True) - return [[], None] - - if obj == cthulhu_state.locusOfFocus \ - and not args.get('formatType', None): - args['formatType'] = 'focused' - result = self.generate(obj, **args) - - # We guess at the focused region. It's going to be a - # Component or Text region whose accessible is the same - # as the object we're generating braille for. There is - # a small hack-like thing here where we include knowledge - # that we represent the text area of editable comboboxes - # instead of the combobox itself. We also do the same - # for table cells because they sometimes have children - # that we present. - # - try: - focusedRegion = result[0] - except Exception: - focusedRegion = None - - for region in result: - if isinstance(region, (braille.Component, braille.Text)) \ - and self._script.utilities.isSameObject(region.accessible, obj, True): - focusedRegion = region - break - elif isinstance(region, braille.Text) \ - and AXUtilities.is_combo_box(obj) \ - and AXObject.get_parent(region.accessible) == obj: - focusedRegion = region - break - elif isinstance(region, braille.Component) \ - and AXUtilities.is_table_cell(obj) \ - and AXObject.get_parent(region.accessible) == obj: - focusedRegion = region - break - else: - - def pred(x): - return self._isCandidateFocusedRegion(obj, x) - - candidates = list(filter(pred, result)) - tokens = ["BRAILLE GENERATOR: Could not determine focused region for", - obj, "Candidates:", candidates] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if len(candidates) == 1: - focusedRegion = candidates[0] - - return [result, focusedRegion] - - ##################################################################### - # # - # Name, role, and label information # - # # - ##################################################################### - - def _generateRoleName(self, obj, **args): - """Returns the role name for the object in an array of strings, with - the exception that the Atspi.Role.UNKNOWN role will yield an - empty array. Note that a 'role' attribute in args will - override the accessible role of the obj. - """ - - if args.get('isProgressBarUpdate') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('brailleProgressBarUpdates'): - return [] - - result = [] - role = args.get('role', AXObject.get_role(obj)) - verbosityLevel = cthulhu.cthulhuApp.settingsManager.getSetting('brailleVerbosityLevel') - - doNotPresent = [Atspi.Role.UNKNOWN, - Atspi.Role.REDUNDANT_OBJECT, - Atspi.Role.FILLER, - Atspi.Role.EXTENDED, - Atspi.Role.LINK] - - # egg-list-box-style containers can expose selected panels as list items. - if AXUtilities.is_list_box(AXObject.get_parent(obj)): - doNotPresent.append(AXObject.get_role(obj)) - - if verbosityLevel == settings.VERBOSITY_LEVEL_BRIEF: - doNotPresent.extend([Atspi.Role.ICON, Atspi.Role.CANVAS]) - - if role == Atspi.Role.HEADING: - level = self._script.utilities.headingLevel(obj) - result.append(object_properties.ROLE_HEADING_LEVEL_BRAILLE % level) - - elif verbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE \ - and not args.get('readingRow', False) and role not in doNotPresent: - result.append(self.getLocalizedRoleName(obj, **args)) - return result - - def getLocalizedRoleName(self, obj, **args): - """Returns the localized name of the given Accessible object; the name - is suitable to be brailled. - - Arguments: - - obj: an Accessible object - """ - - if cthulhu.cthulhuApp.settingsManager.getSetting('brailleRolenameStyle') \ - == settings.BRAILLE_ROLENAME_STYLE_SHORT: - role = args.get('role', AXObject.get_role(obj)) - rv = shortRoleNames.get(role) - if rv: - return rv - - return super().getLocalizedRoleName(obj, **args) - - def _generateUnrelatedLabels(self, obj, **args): - result = [] - labels = self._script.utilities.unrelatedLabels(obj) - for label in labels: - name = self._generateName(label, **args) - result.extend(name) - - return result - - ##################################################################### - # # - # Keyboard shortcut information # - # # - ##################################################################### - - def _generateAccelerator(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the accelerator for the object, - or an empty array if no accelerator can be found. - """ - - verbosityLevel = cthulhu.cthulhuApp.settingsManager.getSetting('brailleVerbosityLevel') - if verbosityLevel == settings.VERBOSITY_LEVEL_BRIEF: - return [] - - result = [] - [mnemonic, shortcut, accelerator] = \ - self._script.utilities.mnemonicShortcutAccelerator(obj) - if accelerator: - result.append("(" + accelerator + ")") - return result - - ##################################################################### - # # - # Hierarchy and related dialog information # - # # - ##################################################################### - - def _generateAlertAndDialogCount(self, obj, **args): - """Returns an array of strings that says how many alerts and dialogs - are associated with the application for this object. [[[WDW - - I wonder if this string should be moved to settings.py.]]] - """ - result = [] - try: - alertAndDialogCount = \ - self._script.utilities.unfocusedAlertAndDialogCount(obj) - except Exception: - alertAndDialogCount = 0 - if alertAndDialogCount > 0: - result.append(messages.dialogCountBraille(alertAndDialogCount)) - - return result - - def _generateAncestors(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the text of the ancestors for - the object. This is typically used to present the context for - an object (e.g., the names of the window, the panels, etc., - that the object is contained in). If the 'priorObj' attribute - of the args dictionary is set, only the differences in - ancestry between the 'priorObj' and the current obj will be - computed. The 'priorObj' is typically set by Cthulhu to be the - previous object with focus. - """ - result = [] - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleContext'): - return result - args['includeContext'] = False - - # Radio button group names are treated separately from the - # ancestors. However, they can appear in the ancestry as a - # labeled panel. So, we need to exclude the first one of - # these things we come across. See also the - # generator.py:_generateRadioButtonGroup method that is - # used to find the radio button group name. - # - role = args.get('role', AXObject.get_role(obj)) - excludeRadioButtonGroup = role == Atspi.Role.RADIO_BUTTON - - parent = AXObject.get_parent_checked(obj) - if parent and (AXObject.get_role(parent) in self.SKIP_CONTEXT_ROLES): - parent = AXObject.get_parent_checked(parent) - while parent: - parentResult = [] - # [[[TODO: WDW - we might want to include more things here - # besides just those things that have labels. For example, - # page tab lists might be a nice thing to include. Logged - # as bugzilla bug 319751.]]] - # - role = AXObject.get_role(parent) - if role != Atspi.Role.FILLER \ - and role != Atspi.Role.INVALID \ - and role != Atspi.Role.SECTION \ - and role != Atspi.Role.SPLIT_PANE \ - and role != Atspi.Role.DESKTOP_FRAME \ - and not self._script.utilities.isLayoutOnly(parent): - args['role'] = role - parentResult = self.generate(parent, **args) - # [[[TODO: HACK - we've discovered oddness in hierarchies - # such as the gedit Edit->Preferences dialog. In this - # dialog, we have labeled groupings of objects. The - # grouping is done via a FILLER with two children - one - # child is the overall label, and the other is the - # container for the grouped objects. When we detect this, - # we add the label to the overall context.]]] - # - if role in [Atspi.Role.FILLER, Atspi.Role.PANEL]: - label = self._script.utilities.displayedLabel(parent) - if label and len(label) and not label.isspace(): - if not excludeRadioButtonGroup: - args['role'] = AXObject.get_role(parent) - parentResult = self.generate(parent, **args) - else: - excludeRadioButtonGroup = False - if result and parentResult: - result.append(braille.Region(" ")) - result.extend(parentResult) - if role == Atspi.Role.EMBEDDED: - break - - parent = AXObject.get_parent_checked(parent) - result.reverse() - return result - - def _generateFocusedItem(self, obj, **args): - result = [] - role = args.get('role', AXObject.get_role(obj)) - if role not in [Atspi.Role.LIST, Atspi.Role.LIST_BOX]: - return result - - if AXObject.supports_selection(obj): - items = self._script.utilities.selectedChildren(obj) - else: - items = [AXUtilities.get_focused_object(obj)] - if not (items and items[0]): - return result - - for item in map(self._generateName, items): - result.extend(item) - - return result - - def _generateTermValueCount(self, obj, **args): - count = self._script.utilities.getValueCountForTerm(obj) - if count < 0: - return [] - - return [f"({messages.valueCountForTerm(count)})"] - - def _generateStatusBar(self, obj, **args): - if not AXUtilities.is_status_bar(obj): - return [] - - items = self._script.utilities.statusBarItems(obj) - if not items or items == [obj]: - return [] - - result = [] - for child in items: - childResult = self.generate(child, includeContext=False) - if childResult: - result.extend(childResult) - result.append(braille.Region(" ")) - - return result - - def _generateListBoxItemWidgets(self, obj, **args): - if not AXUtilities.is_list_box(AXObject.get_parent(obj)): - return [] - - result = [] - for widget in AXUtilities.get_all_widgets(obj): - result.extend(self.generate(widget, includeContext=False)) - result.append(braille.Region(" ")) - return result - - def _generateProgressBarIndex(self, obj, **args): - if not args.get('isProgressBarUpdate') \ - or not self._shouldPresentProgressBarUpdate(obj, **args): - return [] - - acc, updateTime, updateValue = self._getMostRecentProgressBarUpdate() - if acc != obj: - number, count = self.getProgressBarNumberAndCount(obj) - return [f'{number}'] - - return [] - - def _generateProgressBarValue(self, obj, **args): - if args.get('isProgressBarUpdate') \ - and not self._shouldPresentProgressBarUpdate(obj, **args): - return [] - - result = self._generatePercentage(obj, **args) - if obj == cthulhu_state.locusOfFocus and not result: - return [''] - - return result - - def _generatePercentage(self, obj, **args): - percent = self._script.utilities.getValueAsPercent(obj) - if percent is not None: - return [f'{percent}%'] - - return [] - - def _getProgressBarUpdateInterval(self): - interval = cthulhu.cthulhuApp.settingsManager.getSetting('progressBarBrailleInterval') - if interval is None: - return super()._getProgressBarUpdateInterval() - - return int(interval) - - def _shouldPresentProgressBarUpdate(self, obj, **args): - if not cthulhu.cthulhuApp.settingsManager.getSetting('brailleProgressBarUpdates'): - return False - - return super()._shouldPresentProgressBarUpdate(obj, **args) - - ##################################################################### - # # - # Unfortunate hacks. # - # # - ##################################################################### - - def _generateAsPageTabOrScrollPane(self, obj, **args): - """If this scroll pane is labelled by a page tab, then return the page - tab information for the braille context instead. Thunderbird - folder properties is such a case. See bug #507922 for more - details. - """ - result = [] - labels = self._script.utilities.labelsForObject(obj) - for label in labels: - result.extend(self.generate(label, **args)) - break - - if not result: - # NOTE: there is no REAL_ROLE_SCROLL_PANE in formatting.py - # because currently fallback to the default formatting. - # We will provide the support for someone to override this, - # however, so we use REAL_ROLE_SCROLL_PANE here. - # - oldRole = self._overrideRole(role_keys.REAL_ROLE_SCROLL_PANE, args) - result.extend(self.generate(obj, **args)) - self._restoreRole(oldRole, args) - return result - - def _generateIncludeContext(self, obj, **args): - """Returns True or False to indicate whether context should be - included or not. - """ - - if args.get('isProgressBarUpdate'): - return False - - # For multiline text areas, we only show the context if we - # are on the very first line. Otherwise, we show only the - # line. - # - include = cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleContext') - if not include: - return include - if AXObject.supports_text(obj) \ - and (self._script.utilities.isTextArea(obj) or AXUtilities.is_label(obj)): - caretOffset = AXText.get_caret_offset(obj) - lineString, startOffset, endOffset = AXText.get_line_at_offset(obj, caretOffset) - - include = startOffset == 0 - if include: - flowsFrom = AXUtilitiesRelation.get_flows_from(obj) - if flowsFrom: - include = not self._script.utilities.isTextArea(flowsFrom[0]) - return include - - ##################################################################### - # # - # Other things for spacing # - # # - ##################################################################### - - def _generateEol(self, obj, **args): - result = [] - if not cthulhu.cthulhuApp.settingsManager.getSetting('disableBrailleEOL'): - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'eol' - result.append(self._script.formatting.getString(**args)) - return result - - def space(self, delimiter=" "): - if delimiter == " ": - return SPACE - else: - return [Space(delimiter)] - - def asString(self, content, delimiter=" "): - combined = "" - prior = None - if isinstance(content, str): - combined = content - elif content and isinstance(content, list): - # Strip off leading and trailing spaces. - # - while content and isinstance(content[0], Space): - content = content[1:] - while content and isinstance(content[-1], Space): - content = content[0:-1] - for element in content: - if isinstance(element, Space) and prior: - combined += element.delimiter - prior = None - else: - prior = self.asString(element) - combined = self._script.utilities.appendString( - combined, prior, delimiter) - return combined diff --git a/src/cthulhu/braille_rolenames.py b/src/cthulhu/braille_rolenames.py deleted file mode 100644 index e0b5865..0000000 --- a/src/cthulhu/braille_rolenames.py +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Dictionary of abbreviated rolenames for use with braille.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2012 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from .cthulhu_i18n import _ -from .cthulhu_i18n import C_ - -shortRoleNames = { - # Translators: short braille for the rolename of an invalid GUI object. - # We strive to keep it under three characters to preserve real estate. - Atspi.Role.INVALID: _("???"), - - # Translators: short braille for the rolename of an alert dialog. - # NOTE for all the short braille words: they we strive to keep them - # around three characters to preserve real estate on the braille - # display. The letters are chosen to make them unique across all - # other rolenames, and they typically act like an abbreviation. - Atspi.Role.ALERT: _("alrt"), - - # Translators: short braille for the rolename of an animation widget. - Atspi.Role.ANIMATION: _("anim"), - - # Translators: short braille for the rolename of an arrow widget. - Atspi.Role.ARROW: _("arw"), - - # Translators: short braille for the rolename of a calendar widget. - Atspi.Role.CALENDAR: _("cal"), - - # Translators: short braille for the rolename of a canvas widget. - Atspi.Role.CANVAS: _("cnv"), - - # Translators: short braille for the rolename of a caption (e.g., - # table caption). - Atspi.Role.CAPTION: _("cptn"), - - # Translators: short braille for the rolename of a checkbox. - Atspi.Role.CHECK_BOX: _("chk"), - - # Translators: short braille for the rolename of a check menu item. - Atspi.Role.CHECK_MENU_ITEM: _("chk"), - - # Translators: short braille for the rolename of a color chooser. - Atspi.Role.COLOR_CHOOSER: _("clrchsr"), - - # Translators: short braille for the rolename of a column header. - Atspi.Role.COLUMN_HEADER: _("colhdr"), - - # Translators: short braille for the rolename of a combo box. - Atspi.Role.COMBO_BOX: _("cbo"), - - # Translators: short braille for the rolename of a date editor. - Atspi.Role.DATE_EDITOR: _("dat"), - - # Translators: short braille for the rolename of a desktop icon. - Atspi.Role.DESKTOP_ICON: _("icn"), - - # Translators: short braille for the rolename of a desktop frame. - Atspi.Role.DESKTOP_FRAME: _("frm"), - - # Translators: short braille for the rolename of a dial. - # You should attempt to treat it as an abbreviation of - # the translated word for "dial". It is OK to use an - # unabbreviated word as long as it is relatively short. - Atspi.Role.DIAL: C_("shortbraille", "dial"), - - # Translators: short braille for the rolename of a dialog. - Atspi.Role.DIALOG: _("dlg"), - - # Translators: short braille for the rolename of a directory pane. - Atspi.Role.DIRECTORY_PANE: _("dip"), - - # Translators: short braille for the rolename of an HTML document frame. - Atspi.Role.DOCUMENT_FRAME: _("html"), - - # Translators: short braille for the rolename of a drawing area. - Atspi.Role.DRAWING_AREA: _("draw"), - - # Translators: short braille for the rolename of a file chooser. - Atspi.Role.FILE_CHOOSER: _("fchsr"), - - # Translators: short braille for the rolename of a filler. - Atspi.Role.FILLER: _("flr"), - - # Translators: short braille for the rolename of a font chooser. - Atspi.Role.FONT_CHOOSER: _("fnt"), - - # Translators: short braille for the rolename of a form. - # You should attempt to treat it as an abbreviation of - # the translated word for "form". It is OK to use an - # unabbreviated word as long as it is relatively short. - Atspi.Role.FORM: C_("shortbraille", "form"), - - # Translators: short braille for the rolename of a frame. - Atspi.Role.FRAME: _("frm"), - - # Translators: short braille for the rolename of a glass pane. - Atspi.Role.GLASS_PANE: _("gpn"), - - # Translators: short braille for the rolename of a heading. - Atspi.Role.HEADING: _("hdng"), - - # Translators: short braille for the rolename of an html container. - Atspi.Role.HTML_CONTAINER: _("html"), - - # Translators: short braille for the rolename of a icon. - Atspi.Role.ICON: _("icn"), - - # Translators: short braille for the rolename of a image. - Atspi.Role.IMAGE: _("img"), - - # Translators: short braille for the rolename of an internal frame. - Atspi.Role.INTERNAL_FRAME: _("ifrm"), - - # Translators: short braille for the rolename of a label. - Atspi.Role.LABEL: _("lbl"), - - # Translators: short braille for the rolename of a layered pane. - Atspi.Role.LAYERED_PANE: _("lyrdpn"), - - # Translators: short braille for the rolename of a link. - Atspi.Role.LINK: _("lnk"), - - # Translators: short braille for the rolename of a list. - Atspi.Role.LIST: _("lst"), - - # Translators: short braille for the rolename of a list item. - Atspi.Role.LIST_ITEM: _("lstitm"), - - # Translators: short braille for the rolename of a menu. - Atspi.Role.MENU: _("mnu"), - - # Translators: short braille for the rolename of a menu bar. - Atspi.Role.MENU_BAR: _("mnubr"), - - # Translators: short braille for the rolename of a menu item. - Atspi.Role.MENU_ITEM: _("mnuitm"), - - # Translators: short braille for the rolename of an option pane. - Atspi.Role.OPTION_PANE: _("optnpn"), - - # Translators: short braille for the rolename of a page tab. - Atspi.Role.PAGE_TAB: _("pgt"), - - # Translators: short braille for the rolename of a page tab list. - Atspi.Role.PAGE_TAB_LIST: _("tblst"), - - # Translators: short braille for the rolename of a panel. - Atspi.Role.PANEL: _("pnl"), - - # Translators: short braille for the rolename of a password field. - Atspi.Role.PASSWORD_TEXT: _("pwd"), - - # Translators: short braille for the rolename of a popup menu. - Atspi.Role.POPUP_MENU: _("popmnu"), - - # Translators: short braille for the rolename of a progress bar. - Atspi.Role.PROGRESS_BAR: _("pgbar"), - - # Translators: short braille for the rolename of a push button. - Atspi.Role.PUSH_BUTTON: _("btn"), - - # Translators: short braille for the rolename of a radio button. - Atspi.Role.RADIO_BUTTON: _("radio"), - - # Translators: short braille for the rolename of a radio menu item. - Atspi.Role.RADIO_MENU_ITEM: _("rdmnuitm"), - - # Translators: short braille for the rolename of a root pane. - Atspi.Role.ROOT_PANE: _("rtpn"), - - # Translators: short braille for the rolename of a row header. - Atspi.Role.ROW_HEADER: _("rwhdr"), - - # Translators: short braille for the rolename of a scroll bar. - Atspi.Role.SCROLL_BAR: _("scbr"), - - # Translators: short braille for the rolename of a scroll pane. - Atspi.Role.SCROLL_PANE: _("scpn"), - - # Translators: short braille for the rolename of a section (e.g., in html). - Atspi.Role.SECTION: _("sctn"), - - # Translators: short braille for the rolename of a separator. - Atspi.Role.SEPARATOR: _("seprtr"), - - # Translators: short braille for the rolename of a slider. - Atspi.Role.SLIDER: _("sldr"), - - # Translators: short braille for the rolename of a split pane. - Atspi.Role.SPLIT_PANE: _("spltpn"), - - # Translators: short braille for the rolename of a spin button. - Atspi.Role.SPIN_BUTTON: _("spin"), - - # Translators: short braille for the rolename of a statusbar. - Atspi.Role.STATUS_BAR: _("statbr"), - - # Translators: short braille for the rolename of a table. - Atspi.Role.TABLE: _("tbl"), - - # Translators: short braille for the rolename of a table cell. - Atspi.Role.TABLE_CELL: _("cll"), - - # Translators: short braille for the rolename of a table column header. - Atspi.Role.TABLE_COLUMN_HEADER: _("colhdr"), - - # Translators: short braille for the rolename of a table row header. - Atspi.Role.TABLE_ROW_HEADER: _("rwhdr"), - - # Translators: short braille for the rolename of a tear off menu item. - Atspi.Role.TEAROFF_MENU_ITEM: _("tomnuitm"), - - # Translators: short braille for the rolename of a terminal. - Atspi.Role.TERMINAL: _("term"), - - # Translators: short braille for the rolename of a text entry field. - Atspi.Role.TEXT: _("txt"), - - # Translators: short braille for the rolename of a toggle button. - Atspi.Role.TOGGLE_BUTTON: _("tglbtn"), - - # Translators: short braille for the rolename of a toolbar. - Atspi.Role.TOOL_BAR: _("tbar"), - - # Translators: short braille for the rolename of a tooltip. - Atspi.Role.TOOL_TIP: _("tip"), - - # Translators: short braille for the rolename of a tree. - Atspi.Role.TREE: _("tre"), - - # Translators: short braille for the rolename of a tree table. - Atspi.Role.TREE_TABLE: _("trtbl"), - - # Translators: short braille for when the rolename of an object is unknown. - Atspi.Role.UNKNOWN: _("unk"), - - # Translators: short braille for the rolename of a viewport. - Atspi.Role.VIEWPORT: _("vwprt"), - - # Translators: short braille for the rolename of a window. - Atspi.Role.WINDOW: _("wnd"), - - # Translators: short braille for the rolename of a header. - Atspi.Role.HEADER: _("hdr"), - - # Translators: short braille for the rolename of a footer. - Atspi.Role.FOOTER: _("ftr"), - - # Translators: short braille for the rolename of a paragraph. - Atspi.Role.PARAGRAPH: _("para"), - - # Translators: short braille for the rolename of a application. - Atspi.Role.APPLICATION: _("app"), - - # Translators: short braille for the rolename of a autocomplete. - Atspi.Role.AUTOCOMPLETE: _("auto"), - - # Translators: short braille for the rolename of an editbar. - Atspi.Role.EDITBAR: _("edtbr"), - - # Translators: short braille for the rolename of an embedded component. - Atspi.Role.EMBEDDED: _("emb") -} diff --git a/src/cthulhu/brlmon.py b/src/cthulhu/brlmon.py deleted file mode 100644 index f1efbb0..0000000 --- a/src/cthulhu/brlmon.py +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides a graphical braille display, mainly for development tasks.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2011 The Cthulhu Team." -__license__ = "LGPL" - -import brlapi -from gi.repository import Gtk - -from . import cthulhu_state -from .input_event import BrailleEvent - -# Attribute/Selection mask strings: -# -DOT_7 = '\x40' # 01000000 -DOT_8 = '\x80' # 10000000 -DOTS_78 = '\xc0' # 11000000 - -class BrlDot(Gtk.Alignment): - """A single braille dot.""" - - MARKUP_NORMAL = '%s' - SYMBOL_LOWERED = '\u25CB' # '○' - SYMBOL_RAISED = '\u25CF' # '●' - - def __init__(self, dotNumber, isRaised=False): - """Create a new BrlDot. - - Arguments: - - dotNumber: an integer reflecting the location of the dot within - an 8-dot braille cell, using traditional braille dot values. - """ - - super().__init__() - if dotNumber in [1, 2, 3, 7]: - self.set(1.0, 0.5, 0.0, 0.0) - self.set_padding(3, 0, 0, 3) - else: - self.set(0.0, 0.5, 0.0, 0.0) - self.set_padding(3, 0, 3, 0) - - self.label = Gtk.Label() - self.add(self.label) - if isRaised: - self.raiseDot() - else: - self.lowerDot() - - def raiseDot(self): - self.set(0.5, 0.5, 0, 0) - self.label.set_markup(self.MARKUP_NORMAL % self.SYMBOL_RAISED) - - def lowerDot(self): - self.set(0.5, 0.5, 0, 0) - self.label.set_markup(self.MARKUP_NORMAL % self.SYMBOL_LOWERED) - -class BrlCell(Gtk.Button): - """A single graphical braille cell with cursor routing capability.""" - - MARKUP_NORMAL = '%s' - MARKUP_CURSOR_CELL = '%s' - - def __init__(self, position): - """Create a new BrlCell. - - Arguments: - - position: The location of the cell with respect to the monitor. - """ - - Gtk.Button.__init__(self) - self.set_size_request(30, 45) - self._position = position - self._displayedChar = Gtk.Label() - self._dot7 = BrlDot(7) - self._dot8 = BrlDot(8) - - grid = Gtk.Grid() - grid.attach(self._displayedChar, 0, 0, 2, 3) - grid.attach(self._dot7, 0, 3, 1, 1) - grid.attach(self._dot8, 1, 3, 1, 1) - self.add(grid) - - self.connect("clicked", self._onCellClicked) - - def _onCellClicked(self, widget): - """Callback for the 'clicked' signal on the push button. Synthesizes - a fake brlapi command to route the cursor to the current cell, similar - to what occurs when a user presses the cursor routing key on his/her - hardware braille display.""" - - if not cthulhu_state.activeScript: - return - - fakeKeyPress = {} - fakeKeyPress['command'] = brlapi.KEY_CMD_ROUTE - fakeKeyPress['argument'] = self._position - event = BrailleEvent(fakeKeyPress) - cthulhu_state.activeScript.processRoutingKey(event) - - def clear(self): - """Clears the braille cell.""" - - self._displayedChar.set_markup("") - self._dot7.lowerDot() - self._dot8.lowerDot() - - def display(self, char, mask=None, isCursorCell=False): - """Displays the specified character in the cell. - - Arguments: - - char: The character to display in the cell. - - isCursorCell: If True, the cursor/caret is at this cell and this - should be indicated visually. - """ - - if char == '&': - char = '&' - elif char == '<': - char = '<' - elif char == '\t': - char = '$t' - - markup = self.MARKUP_NORMAL - if isCursorCell: - markup = markup % self.MARKUP_CURSOR_CELL - self._displayedChar.set_markup(markup % char) - - if mask in [DOT_7, DOTS_78]: - self._dot7.raiseDot() - if mask in [DOT_8, DOTS_78]: - self._dot8.raiseDot() - -class BrlMon(Gtk.Window): - """Displays a GUI braille monitor that mirrors what would be displayed - by Cthulhu on a connected, configured, and enabled braille display. Cursor - routing functionality is emulated by each cell being a push button. - Panning and other functionality found on hardware braille displays will - be added.""" - - def __init__(self, numCells=32): - """Create a new BrlMon. - - Arguments: - - numCells: how many braille cells to make - """ - - super().__init__() - self.set_title("Braille Monitor") - - grid = Gtk.Grid() - self.add(grid) - - self.cells = [] - for i in range(numCells): - cell = BrlCell(i) - grid.attach(cell, i, 0, 1, 1) - self.cells.append(cell) - - self.set_resizable(False) - self.set_property("accept-focus", False) - self.set_skip_taskbar_hint(True) - self.set_skip_pager_hint(True) - - def clear(self): - """Clears the braille monitor display.""" - - for cell in self.cells: - cell.clear() - - def writeText(self, cursorCell, string, mask=None): - """Display the given text and highlight the given - cursor cell. A cursorCell of 0 means no cell has - the cursor. - - Arguments: - - cursorCell: 1-based index of cell with cursor - - string: len must be <= num cells. - """ - - self.clear() - length = min(len(string), len(self.cells)) - for i in range(length): - isCursorCell = i == cursorCell - 1 - try: - cellMask = mask[i] - except (IndexError, TypeError): - cellMask = None - self.cells[i].display(string[i], cellMask, isCursorCell) diff --git a/src/cthulhu/brltablenames.py b/src/cthulhu/brltablenames.py deleted file mode 100644 index 65119c6..0000000 --- a/src/cthulhu/brltablenames.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Braille translation table names. These have been put in their own module -so that we can present them in the correct language when users change the -synthesizer language on the fly without having to reload a bunch of modules.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2013 The Cthulhu Team" -__license__ = "LGPL" - -from .cthulhu_i18n import _ - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -CZ_CZ_G1 = _("Czech Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -ES_ES_G1 = _("Spanish Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -FR_CA_G2 = _("Canada French Grade 2") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -FR_FR_G2 = _("France French Grade 2") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -LV_LV_G1 = _("Latvian Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -NL_NL_G1 = _("Netherlands Dutch Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -NO_NO_G0 = _("Norwegian Grade 0") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -NO_NO_G1 = _("Norwegian Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -NO_NO_G2 = _("Norwegian Grade 2") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -NO_NO_G3 = _("Norwegian Grade 3") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -PL_PL_G1 = _("Polish Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -PT_PT_G1 = _("Portuguese Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -SE_SE_G1 = _("Swedish Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -AR_AR_G1 = _("Arabic Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -CY_CY_G1 = _("Welsh Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -CY_CY_G2 = _("Welsh Grade 2") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -DE_DE_G0 = _("German Grade 0") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -DE_DE_G1 = _("German Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -DE_DE_G2 = _("German Grade 2") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -EN_GB_G2 = _("U.K. English Grade 2") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -EN_GB_G1 = _("U.K. English Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -EN_US_G1 = _("U.S. English Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -EN_US_G2 = _("U.S. English Grade 2") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -FR_CA_G1 = _("Canada French Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -FR_FR_G1 = _("France French Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -GR_GR_G1 = _("Greek Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -HI_IN_G1 = _("Hindi Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -HU_HU_8DOT = _("Hungarian 8 dot computer") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -HU_HU_G1 = _("Hungarian Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -HU_HU_G2 = _("Hungarian Grade 2") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -IT_IT_G1 = _("Italian Grade 1") - -# Translators: This is the name of a braille translation table. To learn more -# about braille translation tables, see http://en.wikipedia.org/wiki/Braille. -NL_BE_G1 = _("Belgium Dutch Grade 1") diff --git a/src/cthulhu/caret_navigation.py b/src/cthulhu/caret_navigation.py deleted file mode 100644 index e84533a..0000000 --- a/src/cthulhu/caret_navigation.py +++ /dev/null @@ -1,463 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides an Cthulhu-controlled caret for text content.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013-2015 Igalia, S.L." -__license__ = "LGPL" - -from . import cmdnames -from . import debug -from . import input_event -from . import keybindings -from . import messages -from . import settings_manager -from .ax_text import AXText - - -class CaretNavigation: - """Implements the caret navigation support available to scripts.""" - - def __init__(self, script): - if not (script and script.app): - msg = "CARET NAVIGATION: Caret navigation requires a script and app." - debug.printMessage(debug.LEVEL_INFO, msg) - - self._script = script - self._handlers = self._setup_handlers() - self._bindings = self._setup_bindings() - - def handles_navigation(self, handler): - """Returns True if handler is a navigation command.""" - - if handler not in self._handlers.values(): - return False - - if handler.function == self._toggle_enabled: - return False - - return True - - def get_bindings(self): - """Returns the caret-navigation keybindings.""" - - return self._bindings - - def get_handlers(self): - """Returns the caret-navigation handlers.""" - - return self._handlers - - def _setup_handlers(self): - """Sets up and returns the caret-navigation input event handlers.""" - - handlers = {} - - if not (self._script and self._script.app): - return handlers - - handlers["toggle_enabled"] = \ - input_event.InputEventHandler( - self._toggle_enabled, - cmdnames.CARET_NAVIGATION_TOGGLE) - - handlers["next_character"] = \ - input_event.InputEventHandler( - self._next_character, - cmdnames.CARET_NAVIGATION_NEXT_CHAR) - - handlers["previous_character"] = \ - input_event.InputEventHandler( - self._previous_character, - cmdnames.CARET_NAVIGATION_PREV_CHAR) - - handlers["next_word"] = \ - input_event.InputEventHandler( - self._next_word, - cmdnames.CARET_NAVIGATION_NEXT_WORD) - - handlers["previous_word"] = \ - input_event.InputEventHandler( - self._previous_word, - cmdnames.CARET_NAVIGATION_PREV_WORD) - - handlers["next_line"] = \ - input_event.InputEventHandler( - self._next_line, - cmdnames.CARET_NAVIGATION_NEXT_LINE) - - handlers["previous_line"] = \ - input_event.InputEventHandler( - self._previous_line, - cmdnames.CARET_NAVIGATION_PREV_LINE) - - handlers["start_of_file"] = \ - input_event.InputEventHandler( - self._start_of_file, - cmdnames.CARET_NAVIGATION_FILE_START) - - handlers["end_of_file"] = \ - input_event.InputEventHandler( - self._end_of_file, - cmdnames.CARET_NAVIGATION_FILE_END) - - handlers["start_of_line"] = \ - input_event.InputEventHandler( - self._start_of_line, - cmdnames.CARET_NAVIGATION_LINE_START) - - handlers["end_of_line"] = \ - input_event.InputEventHandler( - self._end_of_line, - cmdnames.CARET_NAVIGATION_LINE_END) - - return handlers - - def _setup_bindings(self): - """Sets up and returns the caret-navigation key bindings.""" - - bindings = keybindings.KeyBindings() - - if not (self._script and self._script.app): - return bindings - - bindings.add( - keybindings.KeyBinding( - "F12", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("toggle_enabled"))) - - bindings.add( - keybindings.KeyBinding( - "Right", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("next_character"))) - - bindings.add( - keybindings.KeyBinding( - "Left", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("previous_character"))) - - bindings.add( - keybindings.KeyBinding( - "Right", - keybindings.defaultModifierMask, - keybindings.CTRL_MODIFIER_MASK, - self._handlers.get("next_word"))) - - bindings.add( - keybindings.KeyBinding( - "Left", - keybindings.defaultModifierMask, - keybindings.CTRL_MODIFIER_MASK, - self._handlers.get("previous_word"))) - - bindings.add( - keybindings.KeyBinding( - "Down", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("next_line"))) - - bindings.add( - keybindings.KeyBinding( - "Up", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("previous_line"))) - - bindings.add( - keybindings.KeyBinding( - "End", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("end_of_line"))) - - bindings.add( - keybindings.KeyBinding( - "Home", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("start_of_line"))) - - bindings.add( - keybindings.KeyBinding( - "End", - keybindings.defaultModifierMask, - keybindings.CTRL_MODIFIER_MASK, - self._handlers.get("end_of_file"))) - - bindings.add( - keybindings.KeyBinding( - "Home", - keybindings.defaultModifierMask, - keybindings.CTRL_MODIFIER_MASK, - self._handlers.get("start_of_file"))) - - return bindings - - @staticmethod - def _toggle_enabled(script, event): - """Toggles caret navigation.""" - - if not event: - return False - - _settings_manager = settings_manager.getManager() - enabled = not _settings_manager.getSetting('caretNavigationEnabled') - if enabled: - string = messages.CARET_CONTROL_CTHULHU - else: - string = messages.CARET_CONTROL_APP - - script.presentMessage(string) - _settings_manager.setSetting('caretNavigationEnabled', enabled) - return True - - @staticmethod - def _next_character(script, event): - """Moves to the next character.""" - - if not event: - return False - - obj, offset = script.utilities.nextContext() - if not obj: - return False - - script.utilities.setCaretPosition(obj, offset) - script.updateBraille(obj) - script.sayCharacter(obj) - return True - - @staticmethod - def _previous_character(script, event): - """Moves to the previous character.""" - - if not event: - return False - - obj, offset = script.utilities.previousContext() - if not obj: - return False - - script.utilities.setCaretPosition(obj, offset) - script.updateBraille(obj) - script.sayCharacter(obj) - return True - - @staticmethod - def _next_word(script, event): - """Moves to the next word.""" - - if not event: - return False - - obj, offset = script.utilities.nextContext(skipSpace=True) - contents = script.utilities.getWordContentsAtOffset(obj, offset) - if not contents: - return False - - obj, end, string = contents[-1][0], contents[-1][2], contents[-1][3] - if string and string[-1].isspace(): - end -= 1 - - script.utilities.setCaretPosition(obj, end) - script.updateBraille(obj) - script.sayWord(obj) - return True - - @staticmethod - def _previous_word(script, event): - """Moves to the previous word.""" - - if not event: - return False - - obj, offset = script.utilities.previousContext(skipSpace=True) - contents = script.utilities.getWordContentsAtOffset(obj, offset) - if not contents: - return False - - obj, start = contents[0][0], contents[0][1] - script.utilities.setCaretPosition(obj, start) - script.updateBraille(obj) - script.sayWord(obj) - return True - - @staticmethod - def _next_line(script, event): - """Moves to the next line.""" - - if not event: - return False - - if script.inSayAll(): - _settings_manager = settings_manager.getManager() - if _settings_manager.getSetting('rewindAndFastForwardInSayAll'): - msg = "CARET NAVIGATION: inSayAll and rewindAndFastforwardInSayAll is enabled" - debug.printMessage(debug.LEVEL_INFO, msg) - return True - - obj, offset = script.utilities.getCaretContext() - line = script.utilities.getLineContentsAtOffset(obj, offset) - if not (line and line[0]): - return False - - contents = script.utilities.getNextLineContents() - if not contents: - return False - - obj, start = contents[0][0], contents[0][1] - script.utilities.setCaretPosition(obj, start) - script.speakContents(contents, priorObj=line[-1][0]) - script.displayContents(contents) - return True - - @staticmethod - def _previous_line(script, event): - """Moves to the previous line.""" - - if not event: - return False - - if script.inSayAll(): - _settings_manager = settings_manager.getManager() - if _settings_manager.getSetting('rewindAndFastForwardInSayAll'): - msg = "CARET NAVIGATION: inSayAll and rewindAndFastforwardInSayAll is enabled" - debug.printMessage(debug.LEVEL_INFO, msg) - return True - - - contents = script.utilities.getPreviousLineContents() - if not contents: - return False - - obj, start = contents[0][0], contents[0][1] - script.utilities.setCaretPosition(obj, start) - script.speakContents(contents) - script.displayContents(contents) - return True - - @staticmethod - def _start_of_line(script, event): - """Moves to the start of the line.""" - - if not event: - return False - - obj, offset = script.utilities.getCaretContext() - line = script.utilities.getLineContentsAtOffset(obj, offset) - if not (line and line[0]): - return False - - obj, start = line[0][0], line[0][1] - script.utilities.setCaretPosition(obj, start) - script.sayCharacter(obj) - script.displayContents(line) - return True - - @staticmethod - def _end_of_line(script, event): - """Moves to the end of the line.""" - - if not event: - return False - - obj, offset = script.utilities.getCaretContext() - line = script.utilities.getLineContentsAtOffset(obj, offset) - if not (line and line[0]): - return False - - obj, end, string = line[-1][0], line[-1][2], line[-1][3] - if string.strip() and string[-1].isspace(): - end -= 1 - - script.utilities.setCaretPosition(obj, end) - script.sayCharacter(obj) - script.displayContents(line) - return True - - @staticmethod - def _start_of_file(script, event): - """Moves to the start of the file.""" - - if not event: - return False - - document = script.utilities.documentFrame() - obj, offset = script.utilities.findFirstCaretContext(document, 0) - contents = script.utilities.getLineContentsAtOffset(obj, offset) - if not contents: - return False - - obj, offset = contents[0][0], contents[0][1] - script.utilities.setCaretPosition(obj, offset) - script.speakContents(contents) - script.displayContents(contents) - return True - - @staticmethod - def _end_of_file(script, event): - """Moves to the end of the file.""" - - if not event: - return False - - document = script.utilities.documentFrame() - tokens = ["CARET NAVIGATION: Go to end of", document] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - obj = script.utilities.getLastObjectInDocument(document) - tokens = ["CARET NAVIGATION: Last object in", document, "is", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - offset = 0 - text = script.utilities.queryNonEmptyText(obj) - if text: - offset = AXText.get_character_count(obj) - 1 - - while obj: - lastobj, lastoffset = script.utilities.nextContext(obj, offset) - if not lastobj: - break - obj, offset = lastobj, lastoffset - - contents = script.utilities.getLineContentsAtOffset(obj, offset) - if not contents: - return False - - obj, offset = contents[-1][0], contents[-1][2] - script.utilities.setCaretPosition(obj, offset) - script.speakContents(contents) - script.displayContents(contents) - return True diff --git a/src/cthulhu/chat.py b/src/cthulhu/chat.py deleted file mode 100644 index cc587f8..0000000 --- a/src/cthulhu/chat.py +++ /dev/null @@ -1,970 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Implements generic chat support.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010-2011 The Cthulhu Team" -__license__ = "LGPL" - -from . import cthulhu # Need access to cthulhuApp -from . import cmdnames -from . import debug -from . import guilabels -from . import input_event -from . import keybindings -from . import messages -from . import cthulhu_state -from . import settings -from . import settings_manager -from .ax_object import AXObject -from .ax_utilities import AXUtilities - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -############################################################################# -# # -# Ring List. A fixed size circular list by Flavio Catalani # -# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/435902 # -# # -# Included here to keep track of conversation histories. # -# # -############################################################################# - -class RingList: - def __init__(self, length): - self.__data__ = [] - self.__full__ = 0 - self.__max__ = length - self.__cur__ = 0 - - def append(self, x): - if self.__full__ == 1: - for i in range (0, self.__cur__ - 1): - self.__data__[i] = self.__data__[i + 1] - self.__data__[self.__cur__ - 1] = x - else: - self.__data__.append(x) - self.__cur__ += 1 - if self.__cur__ == self.__max__: - self.__full__ = 1 - - def get(self): - return self.__data__ - - def remove(self): - if (self.__cur__ > 0): - del self.__data__[self.__cur__ - 1] - self.__cur__ -= 1 - - def size(self): - return self.__cur__ - - def maxsize(self): - return self.__max__ - - def __str__(self): - return ''.join(self.__data__) - -############################################################################# -# # -# Conversation # -# # -############################################################################# - -class Conversation: - - # The number of messages to keep in the history - # - MESSAGE_LIST_LENGTH = 9 - - def __init__(self, name, accHistory, inputArea=None): - - """Creates a new instance of the Conversation class. - - Arguments: - - name: the chatroom/conversation name - - accHistory: the accessible which holds the conversation history - - inputArea: the editable text object for this conversation. - """ - - self.name = name - self.accHistory = accHistory - self.inputArea = inputArea - - # A cyclic list to hold the chat room history for this conversation - # - self._messageHistory = RingList(Conversation.MESSAGE_LIST_LENGTH) - - # Initially populate the cyclic lists with empty strings. - # - i = 0 - while i < self._messageHistory.maxsize(): - self.addMessage("") - i += 1 - - # Keep track of the last typing status because some platforms (e.g. - # MSN) seem to issue the status constantly and even though it has - # not changed. - # - self._typingStatus = "" - - def addMessage(self, message): - """Adds the current message to the message history. - - Arguments: - - message: A string containing the message to add - """ - - self._messageHistory.append(message) - - def getNthMessage(self, messageNumber): - """Returns the specified message from the message history. - - Arguments: - - messageNumber: the index of the message to get. - """ - - messages = self._messageHistory.get() - - return messages[messageNumber] - - def getTypingStatus(self): - """Returns the typing status of the buddy in this conversation.""" - - return self._typingStatus - - def setTypingStatus(self, status): - """Sets the typing status of the buddy in this conversation. - - Arguments: - - status: a string describing the current status. - """ - - self._typingStatus = status - -############################################################################# -# # -# ConversationList # -# # -############################################################################# - -class ConversationList: - - def __init__(self, messageListLength): - - """Creates a new instance of the ConversationList class. - - Arguments: - - messageListLength: the size of the message history to keep. - """ - - self.conversations = [] - - # A cyclic list to hold the most recent (messageListLength) previous - # messages for all conversations in the ConversationList. - # - self._messageHistory = RingList(messageListLength) - - # A corresponding cyclic list to hold the name of the conversation - # associated with each message in the messageHistory. - # - self._roomHistory = RingList(messageListLength) - - # Initially populate the cyclic lists with empty strings. - # - i = 0 - while i < self._messageHistory.maxsize(): - self.addMessage("", None) - i += 1 - - def addMessage(self, message, conversation): - """Adds the current message to the message history. - - Arguments: - - message: A string containing the message to add - - conversation: The instance of the Conversation class with which - the message is associated - """ - - if not conversation: - name = "" - else: - if not self.hasConversation(conversation): - self.addConversation(conversation) - name = conversation.name - - self._messageHistory.append(message) - self._roomHistory.append(name) - - def getNthMessageAndName(self, messageNumber): - """Returns a list containing the specified message from the message - history and the name of the chatroom/conversation associated with - that message. - - Arguments: - - messageNumber: the index of the message to get. - """ - - messages = self._messageHistory.get() - rooms = self._roomHistory.get() - - return messages[messageNumber], rooms[messageNumber] - - def hasConversation(self, conversation): - """Returns True if we know about this conversation. - - Arguments: - - conversation: the conversation of interest - """ - - return conversation in self.conversations - - def getNConversations(self): - """Returns the number of conversations we currently know about.""" - - return len(self.conversations) - - def addConversation(self, conversation): - """Adds conversation to the list of conversations. - - Arguments: - - conversation: the conversation to add - """ - - self.conversations.append(conversation) - - def removeConversation(self, conversation): - """Removes conversation from the list of conversations. - - Arguments: - - conversation: the conversation to remove - - Returns True if conversation was successfully removed. - """ - - # TODO - JD: In the Pidgin script, I do not believe we handle the - # case where a conversation window is closed. I *think* it remains - # in the overall chat history. What do we want to do in that case? - # I would assume that we'd want to remove it.... So here's a method - # to do so. Nothing in the Chat class uses it yet. - # - try: - self.conversations.remove(conversation) - except Exception: - return False - else: - return True - -############################################################################# -# # -# Chat # -# # -############################################################################# - -class Chat: - """This class implements the chat functionality which is available to - scripts. - """ - - def __init__(self, script, buddyListAncestries): - """Creates an instance of the Chat class. - - Arguments: - - script: the script with which this instance is associated. - - buddyListAncestries: a list of lists of roles beginning - with the object serving as the actual buddy list (e.g. - ROLE_TREE_TABLE) and ending with the top level object (e.g. - ROLE_FRAME). - """ - - self._script = script - self._buddyListAncestries = buddyListAncestries - - # Keybindings to provide conversation message history. The message - # review order will be based on the index within the list. Thus F1 - # is associated with the most recent message, F2 the message before - # that, and so on. A script could override this. Setting messageKeys - # to ["a", "b", "c" ... ] will cause "a" to be associated with the - # most recent message, "b" to be associated with the message before - # that, etc. Scripts can also override the messageKeyModifier. - # - self.messageKeys = \ - ["F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"] - self.messageKeyModifier = keybindings.CTHULHU_MODIFIER_MASK - self.messageCopyKeyModifier = keybindings.CTHULHU_SHIFT_MODIFIER_MASK - self.inputEventHandlers = {} - self.setupInputEventHandlers() - self.keyBindings = self.getKeyBindings() - - # The length of the message history will be based on how many keys - # are bound to the task of providing it. - # - self.messageListLength = len(self.messageKeys) - self._conversationList = ConversationList(self.messageListLength) - - self.focusedChannelRadioButton = None - self.allChannelsRadioButton = None - self.allMessagesRadioButton = None - self.buddyTypingCheckButton = None - self.chatRoomHistoriesCheckButton = None - self.speakNameCheckButton = None - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for chat functions which - will be used by the script associated with this chat instance.""" - - self.inputEventHandlers["togglePrefixHandler"] = \ - input_event.InputEventHandler( - self.togglePrefix, - cmdnames.CHAT_TOGGLE_ROOM_NAME_PREFIX) - - self.inputEventHandlers["toggleBuddyTypingHandler"] = \ - input_event.InputEventHandler( - self.toggleBuddyTyping, - cmdnames.CHAT_TOGGLE_BUDDY_TYPING) - - self.inputEventHandlers["toggleMessageHistoriesHandler"] = \ - input_event.InputEventHandler( - self.toggleMessageHistories, - cmdnames.CHAT_TOGGLE_MESSAGE_HISTORIES) - - self.inputEventHandlers["reviewMessage"] = \ - input_event.InputEventHandler( - self.readPreviousMessage, - cmdnames.CHAT_PREVIOUS_MESSAGE) - - self.inputEventHandlers["copyMessage"] = \ - input_event.InputEventHandler( - self.copyPreviousMessage, - cmdnames.CHAT_COPY_PREVIOUS_MESSAGE) - - return - - def getKeyBindings(self): - """Defines the chat-related key bindings which will be used by - the script associated with this chat instance. - - Returns: an instance of keybindings.KeyBindings. - """ - - keyBindings = keybindings.KeyBindings() - - keyBindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self.inputEventHandlers["togglePrefixHandler"])) - - keyBindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self.inputEventHandlers["toggleBuddyTypingHandler"])) - - keyBindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self.inputEventHandlers["toggleMessageHistoriesHandler"])) - - for messageKey in self.messageKeys: - keyBindings.add( - keybindings.KeyBinding( - messageKey, - keybindings.defaultModifierMask, - self.messageKeyModifier, - self.inputEventHandlers["reviewMessage"])) - - for messageKey in self.messageKeys: - keyBindings.add( - keybindings.KeyBinding( - messageKey, - keybindings.defaultModifierMask, - self.messageCopyKeyModifier, - self.inputEventHandlers["copyMessage"])) - - return keyBindings - - def getAppPreferencesGUI(self): - """Return a GtkGrid containing the application unique configuration - GUI items for the current application. """ - - from gi.repository import Gtk - - grid = Gtk.Grid() - grid.set_border_width(12) - - label = guilabels.CHAT_SPEAK_ROOM_NAME - value = cthulhu.cthulhuApp.settingsManager.getSetting('chatSpeakRoomName') - self.speakNameCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self.speakNameCheckButton.set_active(value) - grid.attach(self.speakNameCheckButton, 0, 0, 1, 1) - - label = guilabels.CHAT_ANNOUNCE_BUDDY_TYPING - value = cthulhu.cthulhuApp.settingsManager.getSetting('chatAnnounceBuddyTyping') - self.buddyTypingCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self.buddyTypingCheckButton.set_active(value) - grid.attach(self.buddyTypingCheckButton, 0, 1, 1, 1) - - label = guilabels.CHAT_SEPARATE_MESSAGE_HISTORIES - value = cthulhu.cthulhuApp.settingsManager.getSetting('chatRoomHistories') - self.chatRoomHistoriesCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self.chatRoomHistoriesCheckButton.set_active(value) - grid.attach(self.chatRoomHistoriesCheckButton, 0, 2, 1, 1) - - messagesFrame = Gtk.Frame() - grid.attach(messagesFrame, 0, 3, 1, 1) - label = Gtk.Label(f"{guilabels.CHAT_SPEAK_MESSAGES_FROM}") - label.set_use_markup(True) - messagesFrame.set_label_widget(label) - - messagesAlignment = Gtk.Alignment.new(0.5, 0.5, 1, 1) - messagesAlignment.set_padding(0, 0, 12, 0) - messagesFrame.add(messagesAlignment) - messagesGrid = Gtk.Grid() - messagesAlignment.add(messagesGrid) - - value = cthulhu.cthulhuApp.settingsManager.getSetting('chatMessageVerbosity') - - label = guilabels.CHAT_SPEAK_MESSAGES_ALL - rb1 = Gtk.RadioButton.new_with_mnemonic(None, label) - rb1.set_active(value == settings.CHAT_SPEAK_ALL) - self.allMessagesRadioButton = rb1 - messagesGrid.attach(self.allMessagesRadioButton, 0, 0, 1, 1) - - label = guilabels.CHAT_SPEAK_MESSAGES_ACTIVE - rb2 = Gtk.RadioButton.new_with_mnemonic(None, label) - rb2.join_group(rb1) - rb2.set_active(value == settings.CHAT_SPEAK_FOCUSED_CHANNEL) - self.focusedChannelRadioButton = rb2 - messagesGrid.attach(self.focusedChannelRadioButton, 0, 1, 1, 1) - - label = guilabels.CHAT_SPEAK_MESSAGES_ALL_IF_FOCUSED % \ - AXObject.get_name(self._script.app) - rb3 = Gtk.RadioButton.new_with_mnemonic(None, label) - rb3.join_group(rb1) - rb3.set_active(value == settings.CHAT_SPEAK_ALL_IF_FOCUSED) - self.allChannelsRadioButton = rb3 - messagesGrid.attach(self.allChannelsRadioButton, 0, 2, 1, 1) - - grid.show_all() - - return grid - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - if self.allChannelsRadioButton.get_active(): - verbosity = settings.CHAT_SPEAK_ALL_IF_FOCUSED - elif self.focusedChannelRadioButton.get_active(): - verbosity = settings.CHAT_SPEAK_FOCUSED_CHANNEL - else: - verbosity = settings.CHAT_SPEAK_ALL - - return { - 'chatMessageVerbosity': verbosity, - 'chatSpeakRoomName': self.speakNameCheckButton.get_active(), - 'chatAnnounceBuddyTyping': self.buddyTypingCheckButton.get_active(), - 'chatRoomHistories': self.chatRoomHistoriesCheckButton.get_active(), - } - - ######################################################################## - # # - # InputEvent handlers and supporting utilities # - # # - ######################################################################## - - def togglePrefix(self, script, inputEvent): - """ Toggle whether we prefix chat room messages with the name of - the chat room. - - Arguments: - - script: the script associated with this event - - inputEvent: if not None, the input event that caused this action. - """ - - line = messages.CHAT_ROOM_NAME_PREFIX_ON - speakRoomName = cthulhu.cthulhuApp.settingsManager.getSetting('chatSpeakRoomName') - cthulhu.cthulhuApp.settingsManager.setSetting('chatSpeakRoomName', not speakRoomName) - if speakRoomName: - line = messages.CHAT_ROOM_NAME_PREFIX_OFF - self._script.presentMessage(line) - - return True - - def toggleBuddyTyping(self, script, inputEvent): - """ Toggle whether we announce when our buddies are typing a message. - - Arguments: - - script: the script associated with this event - - inputEvent: if not None, the input event that caused this action. - """ - - line = messages.CHAT_BUDDY_TYPING_ON - announceTyping = cthulhu.cthulhuApp.settingsManager.getSetting('chatAnnounceBuddyTyping') - cthulhu.cthulhuApp.settingsManager.setSetting( - 'chatAnnounceBuddyTyping', not announceTyping) - if announceTyping: - line = messages.CHAT_BUDDY_TYPING_OFF - self._script.presentMessage(line) - - return True - - def toggleMessageHistories(self, script, inputEvent): - """ Toggle whether we provide chat room specific message histories. - - Arguments: - - script: the script associated with this event - - inputEvent: if not None, the input event that caused this action. - """ - - line = messages.CHAT_SEPARATE_HISTORIES_ON - roomHistories = cthulhu.cthulhuApp.settingsManager.getSetting('chatRoomHistories') - cthulhu.cthulhuApp.settingsManager.setSetting('chatRoomHistories', not roomHistories) - if roomHistories: - line = messages.CHAT_SEPARATE_HISTORIES_OFF - self._script.presentMessage(line) - - return True - - def readPreviousMessage(self, script, inputEvent=None, index=0): - """ Speak/braille a previous chat room message. - - Arguments: - - script: the script associated with this event - - inputEvent: if not None, the input event that caused this action. - - index: The index of the message to read -- by default, the most - recent message. If we get an inputEvent, however, the value of - index is ignored and the index of the event_string with respect - to self.messageKeys is used instead. - """ - - try: - index = self.messageKeys.index(inputEvent.event_string) - except Exception: - pass - - message, chatRoomName = self._get_message_for_index(index) - if message and chatRoomName: - self.utterMessage(chatRoomName, message, True) - - def copyPreviousMessage(self, script, inputEvent=None, index=0): - """Copy a previous chat room message to the clipboard.""" - - try: - index = self.messageKeys.index(inputEvent.event_string) - except Exception: - pass - - message, chatRoomName = self._get_message_for_index(index) - if not message: - return - - self._script.utilities.setClipboardText(message) - line = f"Copied {message} to clipboard." - self._script.presentMessage(line) - - def _get_message_for_index(self, index): - messageNumber = self.messageListLength - (index + 1) - message, chatRoomName = None, None - - if cthulhu.cthulhuApp.settingsManager.getSetting('chatRoomHistories'): - conversation = self.getConversation(cthulhu_state.locusOfFocus) - if conversation: - message = conversation.getNthMessage(messageNumber) - chatRoomName = conversation.name - else: - message, chatRoomName = \ - self._conversationList.getNthMessageAndName(messageNumber) - - return message, chatRoomName - - def utterMessage(self, chatRoomName, message, focused=True): - """ Speak/braille a chat room message. - - Arguments: - - chatRoomName: name of the chat room this message came from - - message: the chat room message - - focused: whether or not the current chatroom has focus. Defaults - to True so that we can use this method to present chat history - as well as incoming messages. - """ - - # Only speak/braille the new message if it matches how the user - # wants chat messages spoken. - # - verbosity = cthulhu.cthulhuApp.settingsManager.getAppSetting(self._script.app, 'chatMessageVerbosity') - if cthulhu_state.activeScript.name != self._script.name \ - and verbosity == settings.CHAT_SPEAK_ALL_IF_FOCUSED: - return - elif not focused and verbosity == settings.CHAT_SPEAK_FOCUSED_CHANNEL: - return - - text = "" - if chatRoomName and \ - cthulhu.cthulhuApp.settingsManager.getAppSetting(self._script.app, 'chatSpeakRoomName'): - text = messages.CHAT_MESSAGE_FROM_ROOM % chatRoomName - - if not settings.presentChatRoomLast: - text = self._script.utilities.appendString(text, message) - else: - text = self._script.utilities.appendString(message, text) - - if len(text.strip()): - voice = self._script.speechGenerator.voice(string=text) - self._script.speakMessage(text, voice=voice) - self._script.displayBrailleMessage(text) - - def getMessageFromEvent(self, event): - """Get the actual displayed message. This will almost always be the - unaltered any_data from an event of type object:text-changed:insert. - - Arguments: - - event: the Event from which to take the text. - - Returns the string which should be presented as the newly-inserted - text. (Things like chatroom name prefacing get handled elsewhere.) - """ - - return event.any_data - - def presentInsertedText(self, event): - """Gives the Chat class an opportunity to present the text from the - text inserted Event. - - Arguments: - - event: the text inserted Event - - Returns True if we handled this event here; otherwise False, which - tells the associated script that is not a chat event that requires - custom handling. - """ - - if not event \ - or not event.type.startswith("object:text-changed:insert") \ - or not event.any_data: - return False - - if self.isGenericTextObject(event.source): - # The script should handle non-chat specific text areas (e.g., - # adding a new account). - # - return False - - elif self.isInBuddyList(event.source): - # These are status changes. What the Pidgin script currently - # does for these is ignore them. It might be nice to add - # some options to allow the user to customize what status - # changes are presented. But for now, we'll ignore them - # across the board. - # - return True - - elif self.isTypingStatusChangedEvent(event): - self.presentTypingStatusChange(event, event.any_data) - return True - - elif self.isChatRoomMsg(event.source): - # We always automatically go back to focus tracking mode when - # someone sends us a message. - # - if self._script.flatReviewPresenter.is_active(): - self._script.flatReviewPresenter.quit() - - if self.isNewConversation(event.source): - name = self.getChatRoomName(event.source) - conversation = Conversation(name, event.source) - else: - conversation = self.getConversation(event.source) - name = conversation.name - message = self.getMessageFromEvent(event).strip("\n") - if message: - self.addMessageToHistory(message, conversation) - - # The user may or may not want us to present this message. Also, - # don't speak the name if it's the focused chat. - # - focused = self.isFocusedChat(event.source) - if focused: - name = "" - if message: - self.utterMessage(name, message, focused) - return True - - elif self.isAutoCompletedTextEvent(event): - text = event.any_data - voice = self._script.speechGenerator.voice(string=text) - self._script.speakMessage(text, voice=voice) - return True - - return False - - def presentTypingStatusChange(self, event, status): - """Presents a change in typing status for the current conversation - if the status has indeed changed and if the user wants to hear it. - - Arguments: - - event: the accessible Event - - status: a string containing the status change - - Returns True if we spoke the change; False otherwise - """ - - if cthulhu.cthulhuApp.settingsManager.getSetting('chatAnnounceBuddyTyping'): - conversation = self.getConversation(event.source) - if conversation and (status != conversation.getTypingStatus()): - voice = self._script.speechGenerator.voice(string=status) - self._script.speakMessage(status, voice=voice) - conversation.setTypingStatus(status) - return True - - return False - - def addMessageToHistory(self, message, conversation): - """Adds message to both the individual conversation's history - as well as to the complete history stored in our conversation - list. - - Arguments: - - message: a string containing the message to be added - - conversation: the instance of the Conversation class to which - this message belongs - """ - - conversation.addMessage(message) - self._conversationList.addMessage(message, conversation) - - ######################################################################## - # # - # Convenience methods for identifying, locating different accessibles # - # # - ######################################################################## - - def isGenericTextObject(self, obj): - """Returns True if the given accessible seems to be something - unrelated to the custom handling we're attempting to do here. - - Arguments: - - obj: the accessible object to examine. - """ - - return AXUtilities.is_editable(obj) and AXUtilities.is_single_line(obj) - - def isBuddyList(self, obj): - """Returns True if obj is the list of buddies in the buddy list - window. Note that this method relies upon a hierarchical check, - using a list of hierarchies provided by the script. Scripts - which have more reliable means of identifying the buddy list - can override this method. - - Arguments: - - obj: the accessible being examined - """ - - if obj is None: - return False - - for roleList in self._buddyListAncestries: - if self._script.utilities.hasMatchingHierarchy(obj, roleList): - return True - - return False - - def isInBuddyList(self, obj, includeList=True): - """Returns True if obj is, or is inside of, the buddy list. - - Arguments: - - obj: the accessible being examined - - includeList: whether or not the list itself should be - considered "in" the buddy list. - """ - - if includeList and self.isBuddyList(obj): - return True - - for roleList in self._buddyListAncestries: - role = roleList[0] - candidate = AXObject.find_ancestor(obj, lambda x: AXObject.get_role(x) == role) - if self.isBuddyList(candidate): - return True - - return False - - def isNewConversation(self, obj): - """Returns True if the given accessible is the chat history - associated with a new conversation. - - Arguments: - - obj: the accessible object to examine. - """ - - conversation = self.getConversation(obj) - return not self._conversationList.hasConversation(conversation) - - def getConversation(self, obj): - """Attempts to locate the conversation associated with obj. - - Arguments: - - obj: the accessible of interest - - Returns the conversation if found; None otherwise - """ - - if not obj: - return None - - name = "" - # TODO - JD: If we have multiple chats going on and those - # chats have the same name, and we're in the input area, - # this approach will fail. What I should probably do instead - # is, upon creation of a new conversation, figure out where - # the input area is and save it. For now, I just want to get - # things working. And people should not be in multiple chat - # rooms with identical names anyway. :-) - # - if (AXUtilities.is_text(obj) or AXUtilities.is_entry(obj)) \ - and AXUtilities.is_editable(obj): - name = self.getChatRoomName(obj) - - for conversation in self._conversationList.conversations: - if name: - if name == conversation.name: - return conversation - # Doing an equality check seems to be preferable here to - # utilities.isSameObject as a result of false positives. - # - elif obj == conversation.accHistory: - return conversation - - return None - - def isChatRoomMsg(self, obj): - """Returns True if the given accessible is the text object for - associated with a chat room conversation. - - Arguments: - - obj: the accessible object to examine. - """ - - if AXUtilities.is_text(obj) and AXUtilities.is_scroll_pane(AXObject.get_parent(obj)): - return not AXUtilities.is_editable(obj) and AXUtilities.is_multi_line(obj) - return False - - def isFocusedChat(self, obj): - """Returns True if we plan to treat this chat as focused for - the purpose of deciding whether or not a message should be - presented to the user. - - Arguments: - - obj: the accessible object to examine. - """ - - if AXUtilities.is_showing(obj): - active = self._script.utilities.topLevelObjectIsActiveAndCurrent(obj) - tokens = ["INFO:", obj, "'s window is focused chat:", active] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return active - - tokens = ["INFO:", obj, "is not focused chat (not showing)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - def getChatRoomName(self, obj): - """Attempts to find the name of the current chat room. - - Arguments: - - obj: The accessible of interest - - Returns a string containing what we think is the chat room name. - """ - - # Most of the time, it seems that the name can be found in the - # page tab which is the ancestor of the chat history. Failing - # that, we'll look at the frame name. Failing that, scripts - # should override this method. :-) - # - def pred(x): - return AXUtilities.is_page_tab(x) or AXUtilities.is_frame(x) - - ancestor = AXObject.find_ancestor(obj, pred) - name = "" - try: - text = self._script.utilities.displayedText(ancestor) - if text.lower().strip() != self._script.name.lower().strip(): - name = text - except Exception: - pass - - # Some applications don't trash their page tab list when there is - # only one active chat, but instead they remove the text or hide - # the item. Therefore, we'll give it one more shot. - # - if not name: - ancestor = AXObject.find_ancestor(obj, AXUtilities.is_frame) - try: - text = self._script.utilities.displayedText(ancestor) - if text.lower().strip() != self._script.name.lower().strip(): - name = text - except Exception: - pass - - return name - - def isAutoCompletedTextEvent(self, event): - """Returns True if event is associated with text being autocompleted. - - Arguments: - - event: the accessible event being examined - """ - - if not AXUtilities.is_text(event.source): - return False - - lastKey, mods = self._script.utilities.lastKeyAndModifiers() - if lastKey == "Tab" and event.any_data and event.any_data != "\t": - return True - - return False - - def isTypingStatusChangedEvent(self, event): - """Returns True if event is associated with a change in typing status. - - Arguments: - - event: the accessible event being examined - """ - - # TODO - JD: I still need to figure this one out. Pidgin seems to - # no longer be presenting this change in the conversation history - # as it was doing before. And I'm not yet sure what other apps do. - # In the meantime, scripts can override this. - # - return False diff --git a/src/cthulhu/chnames.py b/src/cthulhu/chnames.py deleted file mode 100644 index c191340..0000000 --- a/src/cthulhu/chnames.py +++ /dev/null @@ -1,822 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides getCharacterName that maps punctuation marks and other -individual characters into localized words.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -from . import mathsymbols -from . import cthulhu_state -from .cthulhu_i18n import _ - -# chnames is a dictionary where the keys represent a unicode character -# and the values represent the common term used for the character. -# -chnames = {} - -# Translators: this is the spoken word for the space character -# -chnames[" "] = _("space") - -# Translators: this is the spoken word for the newline character -# -chnames["\n"] = _("newline") - -# Translators: this is the spoken word for the tab character -# -chnames["\t"] = _("tab") - -# Translators: this is the spoken word for the character '!' (U+0021) -# -chnames["!"] = _("exclaim") - -# Translators: this is the spoken word for the character '"' (U+0022) -# -chnames["\""] = _("quote") - -# Translators: this is the spoken word for the character '#' (U+0023) -# -chnames["#"] = _("number") - -# Translators: this is the spoken word for the character '$' (U+0024) -# -chnames["$"] = _("dollar") - -# Translators: this is the spoken word for the character '%' (U+0025) -# -chnames["%"] = _("percent") - -# Translators: this is the spoken word for the character '&' (U+0026) -# -chnames["&"] = _("and") - -# Translators: this is the spoken word for the character ''' (U+0027) -# -chnames["'"] = _("apostrophe") - -# Translators: this is the spoken word for the character '(' (U+0028) -# -chnames["("] = _("left paren") - -# Translators: this is the spoken word for the character ')' (U+0029) -# -chnames[")"] = _("right paren") - -# Translators: this is the spoken word for the character '*' (U+002a) -# -chnames["*"] = _("star") - -# Translators: this is the spoken word for the character '+' (U+002b) -# -chnames["+"] = _("plus") - -# Translators: this is the spoken word for the character ',' (U+002c) -# -chnames[","] = _("comma") - -# Translators: this is the spoken word for the character '-' (U+002d) -# -chnames["-"] = _("dash") - -# Translators: this is the spoken word for the character '.' (U+002e) -# -chnames["."] = _("dot") - -# Translators: this is the spoken word for the character '/' (U+002f) -# -chnames["/"] = _("slash") - -# Translators: this is the spoken word for the character ':' (U+003a) -# -chnames[":"] = _("colon") - -# Translators: this is the spoken word for the character ';' (U+003b) -# -chnames[";"] = _("semicolon") - -# Translators: this is the spoken word for the character '< ' (U+003c) -# -chnames["<"] = _("less") - -# Translators: this is the spoken word for the character '=' (U+003d) -# -chnames["="] = _("equals") - -# Translators: this is the spoken word for the character '> ' (U+003e) -# -chnames[">"] = _("greater") - -# Translators: this is the spoken word for the character '?' (U+003f) -# -chnames["?"] = _("question") - -# Translators: this is the spoken word for the character '@' (U+0040) -# -chnames["@"] = _("at") - -# Translators: this is the spoken word for the character '[' (U+005b) -# -chnames["["] = _("left bracket") - -# Translators: this is the spoken word for the character '\' (U+005c) -# -chnames["\\"] = _("backslash") - -# Translators: this is the spoken word for the character ']' (U+005d) -# -chnames["]"] = _("right bracket") - -# Translators: this is the spoken word for the character '^' (U+005e) -# -chnames["^"] = _("caret") - -# Translators: this is the spoken word for the character '_' (U+005f) -# -chnames["_"] = _("underline") - -# Translators: this is the spoken word for the character '`' (U+0060) -# -chnames["`"] = _("grave") - -# Translators: this is the spoken word for the character '{' (U+007b) -# -chnames["{"] = _("left brace") - -# Translators: this is the spoken word for the character '|' (U+007c) -# -chnames["|"] = _("vertical bar") - -# Translators: this is the spoken word for the character '}' (U+007d) -# -chnames["}"] = _("right brace") - -# Translators: this is the spoken word for the character '~' (U+007e) -# -chnames["~"] = _("tilde") - -# Translators: this is the spoken character for the no break space -# character (e.g., " " in HTML -- U+00a0) -# -chnames['\u00a0'] = _("no break space") - -# Translators: this is the spoken word for the character '¡' (U+00a1) -# -chnames['\u00a1'] = _("inverted exclamation point") - -# Translators: this is the spoken word for the character '¢' (U+00a2) -# -chnames['\u00a2'] = _("cents") - -# Translators: this is the spoken word for the character '£' (U+00a3) -# -chnames['\u00a3'] = _("pounds") - -# Translators: this is the spoken word for the character '¤' (U+00a4) -# -chnames['\u00a4'] = _("currency sign") - -# Translators: this is the spoken word for the character '¥' (U+00a5) -# -chnames['\u00a5'] = _("yen") - -# Translators: this is the spoken word for the character '¦' (U+00a6) -# -chnames['\u00a6'] = _("broken bar") - -# Translators: this is the spoken word for the character '§' (U+00a7) -# -chnames['\u00a7'] = _("section") - -# Translators: this is the spoken word for the character '¨' (U+00a8) -# -chnames['\u00a8'] = _("diaeresis") - -# Translators: this is the spoken word for the character '©' (U+00a9) -# -chnames['\u00a9'] = _("copyright") - -# Translators: this is the spoken word for the character 'ª' (U+00aa) -# -chnames['\u00aa'] = _("superscript a") - -# Translators: this is the spoken word for the character '«' (U+00ab) -# -chnames['\u00ab'] = _("left double angle bracket") - -# Translators: this is the spoken word for the character '¬' (U+00ac) -# -chnames['\u00ac'] = _("logical not") - -# Translators: this is the spoken word for the character '­' (U+00ad) -# -chnames['\u00ad'] = _("soft hyphen") - -# Translators: this is the spoken word for the character '®' (U+00ae) -# -chnames['\u00ae'] = _("registered") - -# Translators: this is the spoken word for the character '¯' (U+00af) -# -chnames['\u00af'] = _("macron") - -# Translators: this is the spoken word for the character '°' (U+00b0) -# -chnames['\u00b0'] = _("degrees") - -# Translators: this is the spoken word for the character '±' (U+00b1) -# -chnames['\u00b1'] = _("plus or minus") - -# Translators: this is the spoken word for the character '²' (U+00b2) -# -chnames['\u00b2'] = _("superscript 2") - -# Translators: this is the spoken word for the character '³' (U+00b3) -# -chnames['\u00b3'] = _("superscript 3") - -# Translators: this is the spoken word for the character '´' (U+00b4) -# -chnames['\u00b4'] = _("acute") - -# Translators: this is the spoken word for the character 'µ' (U+00b5) -# -chnames['\u00b5'] = _("mu") - -# Translators: this is the spoken word for the character '¶' (U+00b6) -# -chnames['\u00b6'] = _("paragraph marker") - -# Translators: this is the spoken word for the character '·' (U+00b7) -# -chnames['\u00b7'] = _("middle dot") - -# Translators: this is the spoken word for the character '¸' (U+00b8) -# -chnames['\u00b8'] = _("cedilla") - -# Translators: this is the spoken word for the character '¹' (U+00b9) -# -chnames['\u00b9'] = _("superscript 1") - -# Translators: this is the spoken word for the character 'º' (U+00ba) -# -chnames['\u00ba'] = _("ordinal") - -# Translators: this is the spoken word for the character '»' (U+00bb) -# -chnames['\u00bb'] = _("right double angle bracket") - -# Translators: this is the spoken word for the character '¼' (U+00bc) -# -chnames['\u00bc'] = _("one fourth") - -# Translators: this is the spoken word for the character '½' (U+00bd) -# -chnames['\u00bd'] = _("one half") - -# Translators: this is the spoken word for the character '¾' (U+00be) -# -chnames['\u00be'] = _("three fourths") - -# Translators: this is the spoken word for the character '¿' (U+00bf) -# -chnames['\u00bf'] = _("inverted question mark") - -# Translators: this is the spoken word for the character 'á' (U+00e1) -# -chnames['\u00e1'] = _("a acute") - -# Translators: this is the spoken word for the character 'À' (U+00c0) -# -chnames['\u00c0'] = _("A GRAVE") - -# Translators: this is the spoken word for the character 'Á' (U+00c1) -# -chnames['\u00c1'] = _("A ACUTE") - -# Translators: this is the spoken word for the character 'Â' (U+00c2) -# -chnames['\u00c2'] = _("A CIRCUMFLEX") - -# Translators: this is the spoken word for the character 'Ã' (U+00c3) -# -chnames['\u00c3'] = _("A TILDE") - -# Translators: this is the spoken word for the character 'Ä' (U+00c4) -# -chnames['\u00c4'] = _("A UMLAUT") - -# Translators: this is the spoken word for the character 'Å' (U+00c5) -# -chnames['\u00c5'] = _("A RING") - -# Translators: this is the spoken word for the character 'Æ' (U+00c6) -# -chnames['\u00c6'] = _("A E") - -# Translators: this is the spoken word for the character 'Ç' (U+00c7) -# -chnames['\u00c7'] = _("C CEDILLA") - -# Translators: this is the spoken word for the character 'È' (U+00c8) -# -chnames['\u00c8'] = _("E GRAVE") - -# Translators: this is the spoken word for the character 'É' (U+00c9) -# -chnames['\u00c9'] = _("E ACUTE") - -# Translators: this is the spoken word for the character 'Ê' (U+00ca) -# -chnames['\u00ca'] = _("E CIRCUMFLEX") - -# Translators: this is the spoken word for the character 'Ë' (U+00cb) -# -chnames['\u00cb'] = _("E UMLAUT") - -# Translators: this is the spoken word for the character 'Ì' (U+00cc) -# -chnames['\u00cc'] = _("I GRAVE") - -# Translators: this is the spoken word for the character 'Í' (U+00cd) -# -chnames['\u00cd'] = _("I ACUTE") - -# Translators: this is the spoken word for the character 'Î' (U+00ce) -# -chnames['\u00ce'] = _("I CIRCUMFLEX") - -# Translators: this is the spoken word for the character 'Ï' (U+00cf) -# -chnames['\u00cf'] = _("I UMLAUT") - -# Translators: this is the spoken word for the character 'Ð' (U+00d0) -# -chnames['\u00d0'] = _("ETH") - -# Translators: this is the spoken word for the character 'Ñ' (U+00d1) -# -chnames['\u00d1'] = _("N TILDE") - -# Translators: this is the spoken word for the character 'Ò' (U+00d2) -# -chnames['\u00d2'] = _("O GRAVE") - -# Translators: this is the spoken word for the character 'Ó' (U+00d3) -# -chnames['\u00d3'] = _("O ACUTE") - -# Translators: this is the spoken word for the character 'Ô' (U+00d4) -# -chnames['\u00d4'] = _("O CIRCUMFLEX") - -# Translators: this is the spoken word for the character 'Õ' (U+00d5) -# -chnames['\u00d5'] = _("O TILDE") - -# Translators: this is the spoken word for the character 'Ö' (U+00d6) -# -chnames['\u00d6'] = _("O UMLAUT") - -# Translators: this is the spoken word for the character '×' (U+00d7) -# -chnames['\u00d7'] = _("times") - -# Translators: this is the spoken word for the character 'Ø' (U+00d8) -# -chnames['\u00d8'] = _("O STROKE") - -# Translators: this is the spoken word for the character 'Ù' (U+00d9) -# -chnames['\u00d9'] = _("U GRAVE") - -# Translators: this is the spoken word for the character 'Ú' (U+00da) -# -chnames['\u00da'] = _("U ACUTE") - -# Translators: this is the spoken word for the character 'Û' (U+00db) -# -chnames['\u00db'] = _("U CIRCUMFLEX") - -# Translators: this is the spoken word for the character 'Ü' (U+00dc) -# -chnames['\u00dc'] = _("U UMLAUT") - -# Translators: this is the spoken word for the character 'Ý' (U+00dd) -# -chnames['\u00dd'] = _("Y ACUTE") - -# Translators: this is the spoken word for the character 'Þ' (U+00de) -# -chnames['\u00de'] = _("THORN") - -# Translators: this is the spoken word for the character 'ß' (U+00df) -# -chnames['\u00df'] = _("s sharp") - -# Translators: this is the spoken word for the character 'à' (U+00e0) -# -chnames['\u00e0'] = _("a grave") - -# Translators: this is the spoken word for the character 'â' (U+00e2) -# -chnames['\u00e2'] = _("a circumflex") - -# Translators: this is the spoken word for the character 'ã' (U+00e3) -# -chnames['\u00e3'] = _("a tilde") - -# Translators: this is the spoken word for the character 'ä' (U+00e4) -# -chnames['\u00e4'] = _("a umlaut") - -# Translators: this is the spoken word for the character 'å' (U+00e5) -# -chnames['\u00e5'] = _("a ring") - -# Translators: this is the spoken word for the character 'æ' (U+00e6) -# -chnames['\u00e6'] = _("a e") - -# Translators: this is the spoken word for the character 'ç' (U+00e7) -# -chnames['\u00e7'] = _("c cedilla") - -# Translators: this is the spoken word for the character 'è' (U+00e8) -# -chnames['\u00e8'] = _("e grave") - -# Translators: this is the spoken word for the character 'é' (U+00e9) -# -chnames['\u00e9'] = _("e acute") - -# Translators: this is the spoken word for the character 'ê' (U+00ea) -# -chnames['\u00ea'] = _("e circumflex") - -# Translators: this is the spoken word for the character 'ë' (U+00eb) -# -chnames['\u00eb'] = _("e umlaut") - -# Translators: this is the spoken word for the character 'ì' (U+00ec) -# -chnames['\u00ec'] = _("i grave") - -# Translators: this is the spoken word for the character 'í' (U+00ed) -# -chnames['\u00ed'] = _("i acute") - -# Translators: this is the spoken word for the character 'î' (U+00ee) -# -chnames['\u00ee'] = _("i circumflex") - -# Translators: this is the spoken word for the character 'ï' (U+00ef) -# -chnames['\u00ef'] = _("i umlaut") - -# Translators: this is the spoken word for the character 'ð' (U+00f0) -# -chnames['\u00f0'] = _("eth") - -# Translators: this is the spoken word for the character 'ñ' (U+00f1) -# -chnames['\u00f1'] = _("n tilde") - -# Translators: this is the spoken word for the character 'ò' (U+00f2) -# -chnames['\u00f2'] = _("o grave") - -# Translators: this is the spoken word for the character 'ó' (U+00f3) -# -chnames['\u00f3'] = _("o acute") - -# Translators: this is the spoken word for the character 'ô' (U+00f4) -# -chnames['\u00f4'] = _("o circumflex") - -# Translators: this is the spoken word for the character 'õ' (U+00f5) -# -chnames['\u00f5'] = _("o tilde") - -# Translators: this is the spoken word for the character 'ö' (U+00f6) -# -chnames['\u00f6'] = _("o umlaut") - -# Translators: this is the spoken word for the character '÷' (U+00f7) -# -chnames['\u00f7'] = _("divided by") - -# Translators: this is the spoken word for the character 'ø' (U+00f8) -# -chnames['\u00f8'] = _("o stroke") - -# Translators: this is the spoken word for the character 'þ' (U+00fe) -# -chnames['\u00fe'] = _("thorn") - -# Translators: this is the spoken word for the character 'ú' (U+00fa) -# -chnames['\u00fa'] = _("u acute") - -# Translators: this is the spoken word for the character 'ù' (U+00f9) -# -chnames['\u00f9'] = _("u grave") - -# Translators: this is the spoken word for the character 'û' (U+00fb) -# -chnames['\u00fb'] = _("u circumflex") - -# Translators: this is the spoken word for the character 'ü' (U+00fc) -# -chnames['\u00fc'] = _("u umlaut") - -# Translators: this is the spoken word for the character 'ý' (U+00fd) -# -chnames['\u00fd'] = _("y acute") - -# Translators: this is the spoken word for the character 'ÿ' (U+00ff) -# -chnames['\u00ff'] = _("y umlaut") - -# Translators: this is the spoken word for the character 'Ÿ' (U+0178) -# -chnames['\u0178'] = _("Y UMLAUT") - -# Translators: this is the spoken word for the character 'ƒ' (U+0192) -# -chnames['\u0192'] = _("florin") - -# Translators: this is the spoken word for the character '–' (U+2013) -# -chnames['\u2013'] = _("en dash") - -# Translators: this is the spoken word for the left single quote: ‘ -# (U+2018) -# -chnames['\u2018'] = _("left single quote") - -# Translators: this is the spoken word for the right single quote: ’ -# (U+2019) -# -chnames['\u2019'] = _("right single quote") - -# Translators: this is the spoken word for the character '‚' (U+201a) -# -chnames['\u201a'] = _("single low quote") - -# Translators: this is the spoken word for the character '“' (U+201c) -# -chnames['\u201c'] = _("left double quote") - -# Translators: this is the spoken word for the character '”' (U+201d) -# -chnames['\u201d'] = _("right double quote") - -# Translators: this is the spoken word for the character '„' (U+201e) -# -chnames['\u201e'] = _("double low quote") - -# Translators: this is the spoken word for the character '†' (U+2020) -# -chnames['\u2020'] = _("dagger") - -# Translators: this is the spoken word for the character '‡' (U+2021) -# -chnames['\u2021'] = _("double dagger") - -# Translators: this is the spoken word for the character '•' (U+2022) -# -chnames['\u2022'] = _("bullet") - -# Translators: this is the spoken word for the character '‣' (U+2023) -# -chnames['\u2023'] = _("triangular bullet") - -# Translators: this is the spoken word for the character '‰' (U+2030) -# -chnames['\u2030'] = _("per mille") - -# Translators: this is the spoken word for the character '′' (U+2032) -# -chnames['\u2032'] = _("prime") - -# Translators: this is the spoken word for the character '″' (U+2033) -# -chnames['\u2033'] = _("double prime") - -# Translators: this is the spoken word for the character '‴' (U+2034) -# -chnames['\u2034'] = _("triple prime") - -# Translators: this is the spoken word for the character '⁃' (U+2043) -# -chnames['\u2043'] = _("hyphen bullet") - -# Translators: this is the spoken word for the character '€' (U+20ac) -# -chnames['\u20ac'] = _("euro") - -# Translators: this is the spoken word for the character '™' (U+2122) -# -chnames['\u2122'] = _("trademark") - -# Translators: this is the spoken word for the character '✓' (U+2713) -# It can be used as a bullet in a list. -# -chnames['\u2713'] = _("check mark") - -# Translators: this is the spoken word for the character '✔' (U+2714) -# It can be used as a bullet in a list. -# -chnames['\u2714'] = _("heavy check mark") - -# Translators: this is the spoken word for the character 'x' (U+2717) -# This symbol is included here because it can be used as a bullet in -# an OOo list. The goal is to inform the user of the appearance of -# the bullet, while making it clear that it is a bullet and not simply -# the typed letter 'x'. "Ballot x" might confuse the user. Hence the -# use of "x-shaped bullet". -# -chnames['\u2717'] = _("x-shaped bullet") - -# Translators: this is the spoken word for the character '⁰' (U+2070) -# -chnames['\u2070'] = _("superscript 0") - -# Translators: this is the spoken word for the character '⁴' (U+2074) -# -chnames['\u2074'] = _("superscript 4") - -# Translators: this is the spoken word for the character '⁵' (U+2075) -# -chnames['\u2075'] = _("superscript 5") - -# Translators: this is the spoken word for the character '⁶' (U+2076) -# -chnames['\u2076'] = _("superscript 6") - -# Translators: this is the spoken word for the character '⁷' (U+2077) -# -chnames['\u2077'] = _("superscript 7") - -# Translators: this is the spoken word for the character '⁸' (U+2078) -# -chnames['\u2078'] = _("superscript 8") - -# Translators: this is the spoken word for the character '⁹' (U+2079) -# -chnames['\u2079'] = _("superscript 9") - -# Translators: this is the spoken word for the character '⁺' (U+207a) -# -chnames['\u207a'] = _("superscript plus") - -# Translators: this is the spoken word for the character '⁻' (U+207b) -# -chnames['\u207b'] = _("superscript minus") - -# Translators: this is the spoken word for the character '⁼' (U+207c) -# -chnames['\u207c'] = _("superscript equals") - -# Translators: this is the spoken word for the character '⁽' (U+207d) -# -chnames['\u207d'] = _("superscript left paren") - -# Translators: this is the spoken word for the character '⁾' (U+207e) -# -chnames['\u207e'] = _("superscript right paren") - -# Translators: this is the spoken word for the character 'ⁿ' (U+207f) -# -chnames['\u207f'] = _("superscript n") - -# Translators: this is the spoken word for the character '₀' (U+2080) -# -chnames['\u2080'] = _("subscript 0") - -# Translators: this is the spoken word for the character '₁' (U+2081) -# -chnames['\u2081'] = _("subscript 1") - -# Translators: this is the spoken word for the character '₂' (U+2082) -# -chnames['\u2082'] = _("subscript 2") - -# Translators: this is the spoken word for the character '₃' (U+2083) -# -chnames['\u2083'] = _("subscript 3") - -# Translators: this is the spoken word for the character '₄' (U+2084) -# -chnames['\u2084'] = _("subscript 4") - -# Translators: this is the spoken word for the character '₅' (U+2085) -# -chnames['\u2085'] = _("subscript 5") - -# Translators: this is the spoken word for the character '₆' (U+2086) -# -chnames['\u2086'] = _("subscript 6") - -# Translators: this is the spoken word for the character '₇' (U+2087) -# -chnames['\u2087'] = _("subscript 7") - -# Translators: this is the spoken word for the character '₈' (U+2088) -# -chnames['\u2088'] = _("subscript 8") - -# Translators: this is the spoken word for the character '₉' (U+2089) -# -chnames['\u2089'] = _("subscript 9") - -# Translators: this is the spoken word for the character '₊' (U+208a) -# -chnames['\u208a'] = _("subscript plus") - -# Translators: this is the spoken word for the character '₋' (U+208b) -# -chnames['\u208b'] = _("subscript minus") - -# Translators: this is the spoken word for the character '₌' (U+208c) -# -chnames['\u208c'] = _("subscript equals") - -# Translators: this is the spoken word for the character '₍' (U+208d) -# -chnames['\u208d'] = _("subscript left paren") - -# Translators: this is the spoken word for the character '₎' (U+208e) -# -chnames['\u208e'] = _("subscript right paren") - -# Translators: StarOffice/OOo includes private-use unicode character U+E00A -# as a bullet which looks like the black square: ■ (U+25A0). Therefore, -# please use the same translation for this character. -# -chnames['\ue00a'] = _("black square") - -# Translators: StarOffice/OOo includes private-use unicode character U+E00C -# as a bullet which looks like the black diamond: ◆ (U+25C6). Therefore, -# please use the same translation for this character. -# -chnames['\ue00c'] = _("black diamond") - -# Translators: This refers to U+FFFC, the "object replacement character." -# This character appears in the accessible text of documents and serves as -# indication of the presence of an object within the text (e.g. an image -# or form field inside a paragraph). In an application which has full -# accessibility support for embedded objects, Cthulhu should present the object -# and NOT speak this character. However, for applications where this support -# is missing, the user can arrow to this character and Cthulhu should not be -# silent. This string is what Cthulhu will speak to the user should this occur. -# More information about this character can be found at: -# * http://www.fileformat.info/info/unicode/char/fffc/index.htm -# * http://en.wikipedia.org/wiki/Specials_(Unicode_block) -# -chnames['\ufffc'] = _("object replacement character") - -def getCharacterName(character, preferMath=False): - """Given a character, return its name as people might refer to it - in ordinary conversation. - - Arguments: - - character: the character to get the name for - - Returns a string representing the name for the character - """ - - if not preferMath and cthulhu_state.activeScript: - preferMath = cthulhu_state.activeScript.utilities.isInMath() - if not preferMath: - return character - return mathsymbols.getCharacterName(character) or character diff --git a/src/cthulhu/cmdnames.py b/src/cthulhu/cmdnames.py deleted file mode 100644 index 7b3ab06..0000000 --- a/src/cthulhu/cmdnames.py +++ /dev/null @@ -1,1182 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Command names which Cthulhu presents in speech and/or braille. These -have been put in their own module so that we can present them in -the correct language when users change the synthesizer language -on the fly without having to reload a bunch of modules.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2013 The Cthulhu Team" -__license__ = "LGPL" - -from .cthulhu_i18n import _ - -# Translators: this command will move the mouse pointer to the current item -# without clicking on it. -ROUTE_POINTER_TO_ITEM = _("Route the pointer to the current item") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Left click means to generate a left mouse button click on the current item. -LEFT_CLICK_REVIEW_ITEM = _("Perform left click on current flat review item") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Right click means to generate a right mouse button click on the current item. -RIGHT_CLICK_REVIEW_ITEM = _("Perform right click on current flat review item") - -# Translators: the Cthulhu "SayAll" command allows the user to press a key and have -# the entire document in a window be automatically spoken to the user. If the -# user presses any key during a SayAll operation, the speech will be interrupted -# and the cursor will be positioned at the point where the speech was interrupted. -SAY_ALL = _("Speak entire document") - -# Translators: the 'flat review' feature of Cthulhu allows the user to explore the -# text in a window in a 2D fashion. That is, Cthulhu treats all the text from all -# objects in a window (e.g., buttons, labels, etc.) as a sequence of words in a -# sequence of lines. The flat review feature allows the user to explore this text -# by the {previous,next} {line,word,character}. This string is the name of a command -# which causes Cthulhu to speak the entire contents of the window using flat review. -SAY_ALL_FLAT_REVIEW = _("Speak entire window using flat review") - -# Translators: the "Where Am I" feature of Cthulhu allows a user to press a key and -# then have information about their current context spoken and brailled to them. -# For example, the information may include the name of the current pushbutton -# with focus as well as its mnemonic. -WHERE_AM_I_BASIC = _("Perform the basic Where Am I operation") - -# Translators: the "Where Am I" feature of Cthulhu allows a user to press a key and -# then have information about their current context spoken and brailled to them. -# For example, the information may include the name of the current pushbutton -# with focus as well as its mnemonic. -WHERE_AM_I_DETAILED = _("Perform the detailed Where Am I operation") - -# Translators: This is the description of a dedicated command to speak the -# current selection / highlighted object(s). For instance, in a text object, -# "selection" refers to the selected/highlighted text. In a spreadsheet, it -# refers to the selected/highlighted cells. In an file manager, it refers to -# the selected/highlighted icons. Etc. -WHERE_AM_I_SELECTION = _("Speak the current selection") - -# Translators: This is the description of a dedicated command to speak details -# about a link, such as the uri and type of link. -WHERE_AM_I_LINK = _("Speak link details") - -# Translators: This command will cause the dialog's default button name to be -# spoken and displayed in braille. The "default" button in a dialog box is the -# button that gets activated when Enter is pressed anywhere within that dialog -# box. -PRESENT_DEFAULT_BUTTON = _("Present the default button") - -# Translators: This command will cause the window's status bar contents to be -# spoken and displayed in braille. -PRESENT_STATUS_BAR = _("Present the status bar") - -# Translators: This command will cause the window's title to be spoken and -# displayed in braille. -PRESENT_TITLE = _("Present the title bar") - -# Translators: the Cthulhu "Find" dialog allows a user to search for text in a -# window and then move focus to that text. For example, they may want to find -# the "OK" button. -SHOW_FIND_GUI = _("Open the Find dialog") - -# Translators: Cthulhu has a command which presents a menu with accessible actions -# that can be performed on the current object. This is the name of that command. -SHOW_ACTIONS_LIST = _("Show actions list") - -# Translators: the Cthulhu "Find" dialog allows a user to search for text in a -# window and then move focus to that text. For example, they may want to find -# the "OK" button. This string is used for finding the next occurrence of a -# string. -FIND_NEXT = _("Search for the next instance of a string") - -# Translators: the Cthulhu "Find" dialog allows a user to search for text in a -# window and then move focus to that text. For example, they may want to find -# the "OK" button. This string is used for finding the previous occurrence of a -# string. -FIND_PREVIOUS = _("Search for the previous instance of a string") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -TOGGLE_FLAT_REVIEW = _("Enter and exit flat review mode") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This switch allows the user to restrict the flat review function to a specific object. -TOGGLE_RESTRICT_FLAT_REVIEW = _("Toggle restricting flat review to the current object") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# The home position is the beginning of the content in the window. -REVIEW_HOME = _("Move flat review to the home position") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# The home position is the last bit of information in the window. -REVIEW_END = _("Move flat review to the end position") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -REVIEW_PREVIOUS_LINE = \ - _("Move flat review to the beginning of the previous line") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -REVIEW_CURRENT_LINE = _("Speak the current flat review line") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This particular command will cause Cthulhu to spell the current line character -# by character. -REVIEW_SPELL_CURRENT_LINE = _("Spell the current flat review line") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This particular command will cause Cthulhu to spell the current line character -# by character phonetically, saying "Alpha" for "a", "Bravo" for "b" and so on. -REVIEW_PHONETIC_CURRENT_LINE = \ - _("Phonetically spell the current flat review line") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -REVIEW_NEXT_LINE = _("Move flat review to the beginning of the next line") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Previous will go backwards in the window until you reach the top (i.e., it -# will wrap across lines if necessary). -REVIEW_PREVIOUS_ITEM = _("Move flat review to the previous item or word") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This command will speak the current word or item. -REVIEW_CURRENT_ITEM = _("Speak the current flat review item or word") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This particular command will cause Cthulhu to spell the current word or item -# character by character. -REVIEW_SPELL_CURRENT_ITEM = _("Spell the current flat review item or word") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This particular command will cause Cthulhu to spell the current word or item -# character by character phonetically, saying "Alpha" for "a", "Bravo" for "b" -# and so on. -REVIEW_PHONETIC_CURRENT_ITEM = \ - _("Phonetically spell the current flat review item or word") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Next will go forwards in the window until you reach the end (i.e., it -# will wrap across lines if necessary). -REVIEW_NEXT_ITEM = _("Move flat review to the next item or word") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Above in this case means geographically above, as if you drew a vertical -# line upward on the screen. -REVIEW_ABOVE = _("Move flat review to the word above the current word") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# With respect to this command, the flat review object is typically something -# like a pushbutton, a label, or some other GUI widget. The 'speaks' means it -# will speak the text associated with the object. -REVIEW_CURRENT_ACCESSIBLE = _("Speak the current flat review object") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Below in this case means geographically below, as if you drew a vertical -# line downward on the screen. -REVIEW_BELOW = _("Move flat review to the word below the current word") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Previous will go backwards in the window until you reach the top (i.e., it -# will wrap across lines if necessary). -REVIEW_PREVIOUS_CHARACTER = _("Move flat review to the previous character") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This command will speak the current character -REVIEW_CURRENT_CHARACTER = _("Speak the current flat review character") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This particular command will cause Cthulhu to present the character phonetically, -# saying "Alpha" for "a", "Bravo" for "b" and so on. -REVIEW_SPELL_CURRENT_CHARACTER = \ - _("Phonetically speak the current flat review character") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This particular command will cause Cthulhu to present the character's unicode -# value. -REVIEW_UNICODE_CURRENT_CHARACTER = \ - _("Speak unicode value of the current flat review character") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Previous will go forwards in the window until you reach the end (i.e., it -# will wrap across lines if necessary). -REVIEW_NEXT_CHARACTER = _("Move flat review to the next character") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This command will move to and present the end of the line. -REVIEW_END_OF_LINE = _("Move flat review to the end of the line") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# The bottom left is the bottom left of the window currently being reviewed. -REVIEW_BOTTOM_LEFT = _("Move flat review to the bottom left") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This command lets the user copy the contents currently being reviewed to the -# clipboard. -FLAT_REVIEW_COPY = _("Copy the contents under flat review to the clipboard") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# This command lets the user append the contents currently being reviewed to -# the existing contents of the clipboard. -FLAT_REVIEW_APPEND = \ - _("Append the contents under flat review to the clipboard") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Normally the contents are navigated without leaving the application being -# reviewed. There is a command which will place the entire contents of the -# flat review representation into a text view to make it easy to review -# and copy the text. This string describes that command. -FLAT_REVIEW_SHOW_CONTENTS = _("Show flat review contents") - -# Translators: when users are navigating a table, they sometimes want the -# entire row of a table read; other times they just want the current cell -# to be presented to them. -TOGGLE_TABLE_CELL_READ_MODE = \ - _("Toggle whether to read just the current table cell or the whole row") - -# Translators: the attributes being presented are the text attributes, such as -# bold, italic, font name, font size, etc. -READ_CHAR_ATTRIBUTES = \ - _("Read the attributes associated with the current text character") - -# Translators: a refreshable braille display is an external hardware device that -# presents braille characters to the user. There are a limited number of cells -# on the display (typically 40 cells). Cthulhu provides the feature to build up a -# longer logical line and allow the user to press buttons on the braille display -# so they can pan left and right over this line. -PAN_BRAILLE_LEFT = _("Pan the braille display to the left") - -# Translators: a refreshable braille display is an external hardware device that -# presents braille characters to the user. There are a limited number of cells -# on the display (typically 40 cells). Cthulhu provides the feature to build up a -# longer logical line and allow the user to press buttons on the braille display -# so they can pan left and right over this line. -PAN_BRAILLE_RIGHT = _("Pan the braille display to the right") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Flat review is modal, and the user can be exploring the window without -# changing which object in the window which has focus. The feature used here -# will return the flat review to the object with focus. -GO_BRAILLE_HOME = _("Return to object with keyboard focus") - -# Translators: braille can be displayed in many ways. Contracted braille -# provides a more efficient means to represent text, especially long -# documents. The feature used here is an option to toggle between contracted -# and uncontracted. -SET_CONTRACTED_BRAILLE = _("Turn contracted braille on and off") - -# Translators: hardware braille displays often have buttons near each braille -# cell. These are called cursor routing keys and are a way for a user to tell -# the machine they are interested in a particular character on the display. -PROCESS_ROUTING_KEY = _("Process a cursor routing key") - -# Translators: this is used to indicate the start point of a text selection. -PROCESS_BRAILLE_CUT_BEGIN = _("Mark the beginning of a text selection") - -# Translators: this is used to indicate the end point of a text selection. -PROCESS_BRAILLE_CUT_LINE = _("Mark the end of a text selection") - -# Translators: Cthulhu has a "Learn Mode" that will allow the user to type any key -# on the keyboard and hear what the effects of that key would be. The effects -# might be what Cthulhu would do if it had a handler for the particular key -# combination, or they might just be to echo the name of the key if Cthulhu doesn't -# have a handler. -ENTER_LEARN_MODE = _("Enter learn mode. Press escape to exit learn mode") - -# Translators: the speech rate is how fast the speech synthesis engine will -# generate speech. -DECREASE_SPEECH_RATE = _("Decrease the speech rate") - -# Translators: the speech rate is how fast the speech synthesis engine will -# generate speech. -INCREASE_SPEECH_RATE = _("Increase the speech rate") - -# Translators: the speech pitch is how high or low in pitch/frequency the -# speech synthesis engine will generate speech. -DECREASE_SPEECH_PITCH = _("Decrease the speech pitch") - -# Translators: the speech pitch is how high or low in pitch/frequency the -# speech synthesis engine will generate speech. -INCREASE_SPEECH_PITCH = _("Increase the speech pitch") - -# Translators: the speech volume is how high or low in gain/volume the -# speech synthesis engine will generate speech. -INCREASE_SPEECH_VOLUME = _("Increase the speech volume") - -# Translators: the speech volume is how high or low in gain/volume the -# speech synthesis engine will generate speech. -DECREASE_SPEECH_VOLUME = _("Decrease the speech volume") - -# Translators: This string describes the command to select the previous speech setting. -SPEECH_SETTING_PREVIOUS = _("Select the previous speech setting") - -# Translators: This string describes the command to select the next speech setting. -SPEECH_SETTING_NEXT = _("Select the next speech setting") - -# Translators: This string describes the command to decrease the current speech setting. -SPEECH_SETTING_DECREASE = _("Decrease the current speech setting") - -# Translators: This string describes the command to increase the current speech setting. -SPEECH_SETTING_INCREASE = _("Increase the current speech setting") - -# Translators: This string describes the command to save speech settings. -SPEECH_SETTINGS_SAVE = _("Save speech settings") - -# Translators: Cthulhu allows the user to turn speech synthesis on or off. -# We call it 'silencing'. -TOGGLE_SPEECH = _("Toggle the silencing of speech") - -# Translators: Cthulhu's verbosity levels control how much (or how little) -# Cthulhu will speak when presenting objects as the user navigates within -# applications and reads content. The levels can be toggled via command. -# This string describes that command. -TOGGLE_SPEECH_VERBOSITY = _("Toggle speech verbosity level") - -# Translators: this string is associated with the keyboard shortcut to toggle sleepmode -TOGGLE_SLEEP_MODE = _("Toggle sleep mode") - -# Translators: this string is associated with the keyboard shortcut to quit -# Cthulhu. -QUIT_CTHULHU = _("Quit the screen reader") - -# Translators: the preferences configuration dialog is the dialog that allows -# users to set their preferences for Cthulhu. -SHOW_PREFERENCES_GUI = _("Display the preferences configuration dialog") - -# Translators: the preferences configuration dialog is the dialog that allows -# users to set their preferences for a specific application within Cthulhu. -SHOW_APP_PREFERENCES_GUI = \ - _("Display the application preferences configuration dialog") - -# Translators: Cthulhu allows the user to enable/disable speaking of indentation -# and justification. -TOGGLE_SPOKEN_INDENTATION_AND_JUSTIFICATION = \ - _("Toggle the speaking of indentation and justification") - -# Translators: Cthulhu has a setting through which users can control how a number is -# spoken. The options are digits ("1 2 3") and words ("one hundred and twenty -# three"). This string to be translated refers to an Cthulhu command for quickly -# toggling between the two options. -CHANGE_NUMBER_STYLE = _("Change spoken number style") - -# Translators: Cthulhu allows users to cycle through punctuation levels. None, -# some, most, or all, punctuation will be spoken. -CYCLE_PUNCTUATION_LEVEL = _("Cycle to the next speaking of punctuation level") - -# Translators: Cthulhu allows users to cycle through the speech synthesizers -# available on their system, such as espeak, voxin, mbrola, etc. This string -# is the description of the command. -CYCLE_SYNTHESIZER = _("Cycle to the next speech synthesizer") - -# Translators: Cthulhu has a feature whereby users can set up different "profiles," -# which are collection of settings which apply to a given task, such as a -# "Spanish" profile which would use Spanish text-to-speech and Spanish braille -# and selected when reading Spanish content. This string to be translated refers -# to an Cthulhu command which makes it possible for users to quickly cycle amongst -# their saved profiles without having to get into a GUI. -CYCLE_SETTINGS_PROFILE = _("Cycle to the next settings profile") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via text- -# to-speech. Speech Dispatcher has a feature to control how capital letters are -# presented: Do nothing at all, say the word 'capital' prior to presenting a -# capital letter, or play a tone which Speech Dispatcher refers to as a sound -# 'icon'. This string to be translated refers to an Cthulhu command which makes it -# possible for users to quickly cycle amongst these alternatives without having -# to get into a GUI. -CYCLE_CAPITALIZATION_STYLE = _("Cycle to the next capitalization style") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; "world" spoken when -# the period is pressed. -# - sentence echo: "Hello world" spoken when the period is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo. The following string refers to a command that allows the user to quickly -# choose which type of echo is being used. -CYCLE_KEY_ECHO = _("Cycle to the next key echo level") - -# Translators: this is a debug message that Cthulhu users will not normally see. It -# describes a debug routine that allows the user to adjust the level of debug -# information that Cthulhu generates at run time. -CYCLE_DEBUG_LEVEL = _("Cycle the debug level at run time") - -# Translators: this command announces information regarding the relationship of -# the given bookmark to the current position. Note that in this context, the -# "bookmark" is storing the location of an accessible object, typically on a web -# page. -BOOKMARK_CURRENT_WHERE_AM_I = \ - _("Bookmark where am I with respect to current position") - -# Translators: this event handler cycles through the registered bookmarks and -# takes the user to the previous bookmark location. Note that in this context, -# the "bookmark" is storing the location of an accessible object, typically on -# a web page. -BOOKMARK_GO_TO_PREVIOUS = _("Go to previous bookmark location") - -# Translators: this command moves the user to the location stored at the bookmark. -# Note that in this context, the "bookmark" is storing the location of an -# accessible object, typically on a web page. -BOOKMARK_GO_TO = _("Go to bookmark") - -# Translators: this event handler cycles through the registered bookmarks and -# takes the user to the next bookmark location. Note that in this context, the -# "bookmark" is storing the location of an accessible object, typically on a web -# page. -BOOKMARK_GO_TO_NEXT = _("Go to next bookmark location") - -# Translators: this event handler binds an in-page accessible object location to -# the given input key command. -BOOKMARK_ADD = _("Add bookmark") - -# Translators: this event handler saves all bookmarks for the current application -# to disk. -BOOKMARK_SAVE = _("Save bookmarks") - -# Translators: Cthulhu allows the item under the pointer to be spoken. This toggles -# the feature without the need to get into a GUI. -MOUSE_REVIEW_TOGGLE = _("Toggle mouse review mode") - -# Translators: Cthulhu has a command to present the current time in speech and in -# braille. -PRESENT_CURRENT_TIME = _("Present current time") - -# Translators: Cthulhu has a command to present the current date in speech and in -# braille. -PRESENT_CURRENT_DATE = _("Present current date") - -# Translators: Cthulhu has a command to present the pixel size and location of -# the current object. This string is how this command is described in the list -# of keyboard shortcuts. -PRESENT_SIZE_AND_POSITION = _("Present size and location of current object") - -# Translators: Cthulhu normally intercepts all keyboard commands and only passes -# them along to the current application when they are not Cthulhu commands. This -# command causes the next command issued to be passed along to the current -# application, bypassing Cthulhu's interception of it. -BYPASS_NEXT_COMMAND = \ - _("Pass the next command on to the current application") - -# Translators: Cthulhu has a command to review previous chat room messages in -# speech and braille. This string to be translated is associated with the -# keyboard commands used to review those previous messages. -CHAT_PREVIOUS_MESSAGE = _("Speak and braille a previous chat room message") - -# Translators: Cthulhu has a command to copy a previous chat room message to -# the clipboard. This string is associated with the keyboard commands used to -# copy those messages. -CHAT_COPY_PREVIOUS_MESSAGE = _("Copy a previous chat room message to clipboard") - -# Translators: In chat applications, it is often possible to see that a "buddy" -# is typing currently (e.g. via a keyboard icon or status text). Some users like -# to have this typing status announced by Cthulhu; others find that announcement -# unpleasant. Therefore, it is a setting in Cthulhu. This string to be translated -# is associated with the command to toggle typing status presentation on or off. -CHAT_TOGGLE_BUDDY_TYPING = \ - _("Toggle whether we announce when our buddies are typing") - -# Translators: Cthulhu has a command to review previous chat room messages in -# speech and braille. Some users prefer to have this message history combined -# (e.g. the last ten messages which came in, no matter what room they came -# from). Other users prefer to have specific room history (e.g. the last ten -# messages from #a11y). Therefore, this is a setting in Cthulhu. This string to be -# translated is associated with the command to toggle specific room history on -# or off. -CHAT_TOGGLE_MESSAGE_HISTORIES = \ - _("Toggle whether we provide chat room specific message " \ - "histories") - -# Translators: In chat applications, Cthulhu automatically presents incoming -# messages in speech and braille. If a user is in multiple conversations or -# channels at the same time, it can be confusing to know what room or channel -# a given message came from just from hearing/reading it. For this reason, Cthulhu -# has an option to present the name of the room first ("#a11y hello!" -# instead of " hello!"). This string to be translated is associated with -# the command to toggle room name presentation on or off. -CHAT_TOGGLE_ROOM_NAME_PREFIX = \ - _("Toggle whether we prefix chat room messages with " \ - "the name of the chat room") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). When pressing the -# button, the display scrolls to the left. -BRAILLE_LINE_LEFT = _("Line Left") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). When pressing the -# button, the display scrolls to the right. -BRAILLE_LINE_RIGHT = _("Line Right") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). When pressing the -# button, the display scrolls up. -BRAILLE_LINE_UP = _("Line Up") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). When pressing the -# button, the display scrolls down. -BRAILLE_LINE_DOWN = _("Line Down") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). When pressing the -# button, it instructs the braille display to freeze. -BRAILLE_FREEZE = _("Freeze") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). When pressing the -# button, the display scrolls to the top left of the window. -BRAILLE_TOP_LEFT = _("Top Left") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). When pressing the -# button, the display scrolls to the bottom left of the window. -BRAILLE_BOTTOM_LEFT = _("Bottom Left") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). When pressing the -# button, the display scrolls to position containing the cursor. -BRAILLE_HOME = _("Cursor Position") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). When pressing the -# button, the display toggles between six-dot braille and eight-dot braille. -BRAILLE_SIX_DOTS = _("Six Dots") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). This command -# represents a whole set of buttons known as cursor routing keys and are a way -# for a user to move the application's caret to the position indicated on the -# display. -BRAILLE_ROUTE_CURSOR = _("Cursor Routing") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). This command -# represents the start of a selection operation. It is called "Cut Begin" to map -# to what BrlTTY users are used to: in character cell mode operation on virtual -# consoles, the act of copying text is erroneously called a "cut" operation. -BRAILLE_CUT_BEGIN = _("Cut Begin") - -# Translators: this is a command for a button on a refreshable braille display -# (an external hardware device used by people who are blind). This command -# represents marking the endpoint of a selection. It is called "Cut Line" to map -# to what BrlTTY users are used to: in character cell mode operation on virtual -# consoles, the act of copying text is erroneously called a "cut" operation. -BRAILLE_CUT_LINE = _("Cut Line") - -# Translators: this is a command which causes Cthulhu to present the last received -# notification message. -NOTIFICATION_MESSAGES_LAST = _("Present last notification message") - -# Translators: this is a command which causes Cthulhu to present a list of all the -# notification messages received. -NOTIFICATION_MESSAGES_LIST = _("Present notification messages list") - -# Translators: this is a command which causes Cthulhu to present the previous -# notification message. -NOTIFICATION_MESSAGES_PREVIOUS = _("Present previous notification message") - -# Translators: this is a command which causes Cthulhu to present the next -# notification message. -NOTIFICATION_MESSAGES_NEXT = _("Present next notification message") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_NEXT_CHAR = _("Go to next character") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_PREV_CHAR = _("Go to previous character") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_NEXT_WORD = _("Go to next word") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_PREV_WORD = _("Go to previous word") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_NEXT_LINE = _("Go to next line") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_PREV_LINE = _("Go to previous line") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_FILE_START = _("Go to the top of the file") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_FILE_END = _("Go to the bottom of the file") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_LINE_START = _("Go to the beginning of the line") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_LINE_END = _("Go to the end of the line") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_NEXT_OBJECT = _("Go to the next object") - -# Translators: this is a command related to navigating within a document. -CARET_NAVIGATION_PREV_OBJECT = _("Go to the previous object") - -# Translators: this is for causing a collapsed combo box which was reached -# by Cthulhu's caret navigation to be expanded. -CARET_NAVIGATION_EXPAND_COMBO_BOX = \ - _("Cause the current combo box to be expanded") - -# Translators: Gecko native caret navigation is where Firefox (or Thunderbird) -# itself controls how the arrow keys move the caret around HTML content. It's -# often broken, so Cthulhu needs to provide its own support. As such, Cthulhu offers -# the user the ability to toggle which application is controlling the caret. -CARET_NAVIGATION_TOGGLE = \ - _("Switch between native and screen-reader caret navigation") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# The "politeness" level is an indication of when the user wishes to be notified -# about a change to live region content. Examples include: never ("off"), when -# idle ("polite"), and when there is a change ("assertive"). Cthulhu has several -# features to facilitate accessing live regions. This string refers to a command -# to cycle through the different "politeness" levels. -LIVE_REGIONS_ADVANCE_POLITENESS = _("Advance live region politeness setting") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# The "politeness" level is an indication of when the user wishes to be notified -# about a change to live region content. Examples include: never ("off"), when -# idle ("polite"), and when there is a change ("assertive"). Cthulhu has several -# features to facilitate accessing live regions. This string refers to a command -# to turn off live regions by default. -LIVE_REGIONS_SET_POLITENESS_OFF = \ - _("Set default live region politeness level to off") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# This string refers to a command for reviewing up to nine stored previous live -# messages. -LIVE_REGIONS_REVIEW = _("Review live region announcement") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# This string refers to an Cthulhu command which allows the user to toggle whether -# or not Cthulhu pays attention to changes in live regions. Note that turning off -# monitoring of live events is NOT the same as turning the politeness level -# to "off". The user can opt to have no notifications presented (politeness -# level of "off") and still manually review recent updates to live regions via -# Cthulhu commands for doing so -- as long as the monitoring of live regions is -# enabled. -LIVE_REGIONS_MONITOR = _("Monitor live regions") - -# Translators: hovering the mouse over certain objects on a web page causes a -# new object to appear such as a pop-up menu. This command will move the user -# to the object which just appeared as a result of the user hovering the mouse. -# If the user is already in the mouse over object, this command will hide the -# mouse over and return the user to the object he/she was in. -MOUSE_OVER_MOVE = _("Move focus into and away from the current mouse over") - -# Translators: Cthulhu allows you to dynamically define which row of a spreadsheet -# or table should be treated as containing column headers. This string refers to -# the command to set the row. -DYNAMIC_COLUMN_HEADER_SET = _("Set the row to use as dynamic column headers") - -# Translators: Cthulhu allows you to dynamically define which row of a spreadsheet -# or table should be treated as containing column headers. This string refers to -# the command to unset the row so it is no longer treated as if it contained -# column headers. -DYNAMIC_COLUMN_HEADER_CLEAR = _("Clear the dynamic column headers") - -# Translators: Cthulhu allows you to dynamically define which column of a -# spreadsheet or table should be treated as containing row headers. This -# string refers to the command to set the column. -DYNAMIC_ROW_HEADER_SET = _("Set the column to use as dynamic row headers") - -# Translators: Cthulhu allows you to dynamically define which column of a -# spreadsheet or table should be treated as containing column headers. This -# string refers to the command to unset the column so it is no longer treated -# as if it contained row headers. -DYNAMIC_ROW_HEADER_CLEAR = _("Clear the dynamic row headers") - -# Translators: This string refers to an Cthulhu command. The "input line" refers -# to the place where one enters formulas for a spreadsheet. -PRESENT_INPUT_LINE = _("Present the contents of the input line") - -# Translators: the structural navigation keys are designed to move the caret -# around the document content by object type. Thus H moves you to the next -# heading, Shift H to the previous heading, T to the next table, and so on. -# This feature needs to be toggle-able so that it does not interfere with normal -# writing functions. -STRUCTURAL_NAVIGATION_TOGGLE = _("Toggle structural navigation keys") - -# Translators: this is for navigating among blockquotes in a document. -BLOCKQUOTE_PREV = _("Go to previous blockquote") - -# Translators: this is for navigating among blockquotes in a document. -BLOCKQUOTE_NEXT = _("Go to next blockquote") - -# Translators: this is for navigating among blockquotes in a document. -BLOCKQUOTE_LIST = _("Display a list of blockquotes") - -# Translators: this is for navigating among buttons in a document. -BUTTON_PREV = _("Go to previous button") - -# Translators: this is for navigating among buttons in a document. -BUTTON_NEXT = _("Go to next button") - -# Translators: this is for navigating among buttons in a document. -BUTTON_LIST = _("Display a list of buttons") - -# Translators: this is for navigating among check boxes in a document. -CHECK_BOX_PREV = _("Go to previous check box") - -# Translators: this is for navigating among check boxes in a document. -CHECK_BOX_NEXT = _("Go to next check box") - -# Translators: this is for navigating among check boxes in a document. -CHECK_BOX_LIST = _("Display a list of check boxes") - -# Translators: this is for navigating among clickable objects in a document. -# A "clickable" is a web element with an "onClick" handler. -CLICKABLE_PREV = _("Go to previous clickable") - -# Translators: this is for navigating among clickable objects in a document. -# A "clickable" is a web element with an "onClick" handler. -CLICKABLE_NEXT = _("Go to next clickable") - -# Translators: this is for navigating among clickable objects in a document. -# A "clickable" is a web element with an "onClick" handler. -CLICKABLE_LIST = _("Display a list of clickables") - -# Translators: this is for navigating among combo boxes in a document. -COMBO_BOX_PREV = _("Go to previous combo box") - -# Translators: this is for navigating among combo boxes in a document. -COMBO_BOX_NEXT = _("Go to next combo box") - -# Translators: This string describes a document navigation command which moves -# to the start of the current container. Examples of containers include tables, -# lists, and blockquotes. -CONTAINER_START = _("Go to start of container") - -# Translators: This string describes a document navigation command which moves -# to the end of the current container. Examples of containers include tables, -# lists, and blockquotes. -CONTAINER_END = _("Go to end of container") - -# Translators: this is for navigating among combo boxes in a document. -COMBO_BOX_LIST = _("Display a list of combo boxes") - -# Translators: this is for navigating among entries in a document. -ENTRY_PREV = _("Go to previous entry") - -# Translators: this is for navigating among entries in a document. -ENTRY_NEXT = _("Go to next entry") - -# Translators: this is for navigating among entries in a document. -ENTRY_LIST = _("Display a list of entries") - -# Translators: this is for navigating among form fields in a document. -FORM_FIELD_PREV = _("Go to previous form field") - -# Translators: this is for navigating among form fields in a document. -FORM_FIELD_NEXT = _("Go to next form field") - -# Translators: this is for navigating among form fields in a document. -FORM_FIELD_LIST = _("Display a list of form fields") - -# Translators: this is for navigating among headings (e.g.

) in a document. -HEADING_PREV = _("Go to previous heading") - -# Translators: this is for navigating among headings (e.g.

) in a document. -HEADING_NEXT = _("Go to next heading") - -# Translators: this is for navigating among headings (e.g.

) in a document. -HEADING_LIST = _("Display a list of headings") - -# Translators: this is for navigating among headings (e.g.

) in a document. -#

is a heading at level 1,

is a heading at level 2, etc. -HEADING_AT_LEVEL_PREV = _("Go to previous heading at level %d") - -# Translators: this is for navigating among headings (e.g.

) in a document. -#

is a heading at level 1,

is a heading at level 2, etc. -HEADING_AT_LEVEL_NEXT = _("Go to next heading at level %d") - -# Translators: this is for navigating among headings (e.g.

) in a document. -#

is a heading at level 1,

is a heading at level 2, etc. -HEADING_AT_LEVEL_LIST = _("Display a list of headings at level %d") - -# Translators: this is for navigating among iframes in a document. -IFRAME_PREV = _("Go to previous internal frame") - -# Translators: this is for navigating among iframes in a document. -IFRAME_NEXT = _("Go to next internal frame") - -# Translators: this is for navigating among images in a document. -IFRAME_LIST = _("Display a list of internal frames") - -# Translators: this is for navigating among images in a document. -IMAGE_PREV = _("Go to previous image") - -# Translators: this is for navigating among images in a document. -IMAGE_NEXT = _("Go to next image") - -# Translators: this is for navigating among images in a document. -IMAGE_LIST = _("Display a list of images") - -# Translators: this is for navigating among ARIA landmarks in a document. ARIA -# role landmarks are the W3C defined HTML tag attribute 'role' used to identify -# important part of webpage like banners, main context, search etc. -LANDMARK_PREV = _("Go to previous landmark") - -# Translators: this is for navigating among ARIA landmarks in a document. ARIA -# role landmarks are the W3C defined HTML tag attribute 'role' used to identify -# important part of webpage like banners, main context, search etc. -LANDMARK_NEXT = _("Go to next landmark") - -# Translators: this is for navigating among ARIA landmarks in a document. ARIA -# role landmarks are the W3C defined HTML tag attribute 'role' used to identify -# important part of webpage like banners, main context, search etc. -LANDMARK_LIST = _("Display a list of landmarks") - -# Translators: this is for navigating among large objects in a document. -# A 'large object' is a logical chunk of text, such as a paragraph, a list, -# a table, etc. -LARGE_OBJECT_PREV = _("Go to previous large object") - -# Translators: this is for navigating among large objects in a document. -# A 'large object' is a logical chunk of text, such as a paragraph, a list, -# a table, etc. -LARGE_OBJECT_NEXT = _("Go to next large object") - -# Translators: this is for navigating among large objects in a document. -# A 'large object' is a logical chunk of text, such as a paragraph, a list, -# a table, etc. -LARGE_OBJECT_LIST = _("Display a list of large objects") - -# Translators: this is for navigating among links in a document. -LINK_PREV = _("Go to previous link") - -# Translators: this is for navigating among links in a document. -LINK_NEXT = _("Go to next link") - -# Translators: this is for navigating among links in a document. -LINK_LIST = _("Display a list of links") - -# Translators: this is for navigating among lists in a document. -LIST_PREV = _("Go to previous list") - -# Translators: this is for navigating among lists in a document. -LIST_NEXT = _("Go to next list") - -# Translators: this is for navigating among lists in a document. -LIST_LIST = _("Display a list of lists") - -# Translators: this is for navigating among list items in a document. -LIST_ITEM_PREV = _("Go to previous list item") - -# Translators: this is for navigating among list items in a document. -LIST_ITEM_NEXT = _("Go to next list item") - -# Translators: this is for navigating among list items in a document. -LIST_ITEM_LIST = _("Display a list of list items") - -# Translators: this is for navigating among live regions in a document. A live -# region is an area of a web page that is periodically updated, e.g. a stock -# ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -LIVE_REGION_PREV = _("Go to previous live region") - -# Translators: this is for navigating among live regions in a document. A live -# region is an area of a web page that is periodically updated, e.g. a stock -# ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -LIVE_REGION_NEXT = _("Go to next live region") - -# Translators: this is for navigating among live regions in a document. A live -# region is an area of a web page that is periodically updated, e.g. a stock -# ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -LIVE_REGION_LAST = _("Go to the last live region which made an announcement") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. -NAVIGATOR_UP = _("Go to the parent of the object with navigator focus.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. -NAVIGATOR_DOWN = _("Go to the first child of the object with navigator focus.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. -NAVIGATOR_NEXT = _("Go to the next sibling of the object with navigator focus.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. -NAVIGATOR_PREVIOUS = _("Go to the previous sibling of the object with navigator focus.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. Users are also able to synthesize a click on the objects. -NAVIGATOR_PERFORM_ACTION = _("Click on the object with navigator focus.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. This hierarchy can be simplified, and the simplification can be -# toggled on and off. -NAVIGATOR_TOGGLE_SIMPLIFIED = _("Toggle simplified object navigation.") - -# Translators: this is for navigating among paragraphs in a document. -PARAGRAPH_PREV = _("Go to previous paragraph") - -# Translators: this is for navigating among paragraphs in a document. -PARAGRAPH_NEXT = _("Go to next paragraph") - -# Translators: this is for navigating among paragraphs in a document. -PARAGRAPH_LIST = _("Display a list of paragraphs") - -# Translators: this is for navigating among radio buttons in a document. -RADIO_BUTTON_PREV = _("Go to previous radio button") - -# Translators: this is for navigating among radio buttons in a document. -RADIO_BUTTON_NEXT = _("Go to next radio button") - -# Translators: this is for navigating among radio buttons in a document. -RADIO_BUTTON_LIST = _("Display a list of radio buttons") - -# Translators: this is for navigating among separators (e.g.
) in a -# document. -SEPARATOR_PREV = _("Go to previous separator") - -# Translators: this is for navigating among separators (e.g.
) in a -# document. -SEPARATOR_NEXT = _("Go to next separator") - -# Translators: this is for navigating among tables in a document. -TABLE_PREV = _("Go to previous table") - -# Translators: this is for navigating among tables in a document. -TABLE_NEXT = _("Go to next table") - -# Translators: this is for navigating among tables in a document. -TABLE_LIST = _("Display a list of tables") - -# Translators: this is for navigating among table cells in a document. -TABLE_CELL_DOWN = _("Go down one cell") - -# Translators: this is for navigating among table cells in a document. -TABLE_CELL_FIRST = _("Go to the first cell in a table") - -# Translators: this is for navigating among table cells in a document. -TABLE_CELL_LAST = _("Go to the last cell in a table") - -# Translators: this is for navigating among table cells in a document. -TABLE_CELL_LEFT = _("Go left one cell") - -# Translators: this is for navigating among table cells in a document. -TABLE_CELL_RIGHT = _("Go right one cell") - -# Translators: this is for navigating among table cells in a document. -TABLE_CELL_UP = _("Go up one cell") - -# Translators: When presenting the content of a line on a web page, Cthulhu by -# default presents the full line, including any links or form fields on that -# line, in order to reflect the on-screen layout as seen by sighted users. -# Not all users like this presentation, however, and prefer to have objects -# treated as if they were on individual lines, such as is done by Windows -# screen readers, so that unrelated objects (e.g. links in a navbar) are not -# all jumbled together. As a result, this is now configurable. If layout mode -# is enabled, Cthulhu will present the full line as it appears on the screen; if -# it is disabled, Cthulhu will treat each object as if it were on a separate line, -# both for presentation and navigation. This string is associated with the Cthulhu -# command to manually toggle layout mode on/off. -TOGGLE_LAYOUT_MODE = _("Toggle layout mode") - -# Translators: Cthulhu has a number of commands that override the default -# behavior within an application. For instance, on a web page, "h" moves -# you to the next heading. What should happen when you press an "h" in -# an entry on a web page depends: If you want to resume reading content, -# "h" should move to the next heading; if you want to enter text, "h" -# should not move you to the next heading. Similarly, if you are -# at the bottom of an entry and press Down arrow, should you leave the -# entry? Again, it depends on if you want to resume reading content or -# if you are editing the text in the entry. Because Cthulhu doesn't know -# what you want to do, it has two modes: In browse mode, Cthulhu treats -# key presses as commands to read the content; in focus mode, Cthulhu treats -# key presses as something that should be handled by the focused widget. -# This string is associated with the Cthulhu command to manually switch -# between these two modes. -TOGGLE_PRESENTATION_MODE = _("Switch between browse mode and focus mode") - -# Translators: (Please see the previous, detailed translator notes about -# Focus mode and Browse mode.) In order to minimize the amount of work Cthulhu -# users need to do to switch between focus mode and browse mode, Cthulhu attempts -# to automatically switch to the mode which is appropriate to the current -# web element. Sometimes, however, this automatic mode switching is not what -# the user wants. A good example being web apps which have their own keyboard -# navigation and use interaction model. As a result, Cthulhu has a command which -# enables setting a "sticky" focus mode which disables all automatic toggling. -# This string is associated with the Cthulhu command to enable sticky focus mode. -SET_FOCUS_MODE_STICKY = _("Enable sticky focus mode") - -# Translators: (Please see the previous, detailed translator notes about -# Focus mode and Browse mode.) In order to minimize the amount of work Cthulhu -# users need to do to switch between focus mode and browse mode, Cthulhu attempts -# to automatically switch to the mode which is appropriate to the current -# web element. Sometimes, however, this automatic mode switching is not what -# the user wants. A good example being web apps which have their own keyboard -# navigation and use interaction model. As a result, Cthulhu has a command which -# enables setting a "sticky" browse mode which disables all automatic toggling. -# This string is associated with the Cthulhu command to enable sticky browse mode. -SET_BROWSE_MODE_STICKY = _("Enable sticky browse mode") - -# Translators: this is for navigating among unvisited links in a document. -UNVISITED_LINK_PREV = _("Go to previous unvisited link") - -# Translators: this is for navigating among unvisited links in a document. -UNVISITED_LINK_NEXT = _("Go to next unvisited link") - -# Translators: this is for navigating among unvisited links in a document. -UNVISITED_LINK_LIST = _("Display a list of unvisited links") - -# Translators: this is for navigating among visited links in a document. -VISITED_LINK_PREV = _("Go to previous visited link") - -# Translators: this is for navigating among visited links in a document. -VISITED_LINK_NEXT = _("Go to next visited link") - -# Translators: this is for navigating among visited links in a document. -VISITED_LINK_LIST = _("Display a list of visited links") diff --git a/src/cthulhu/colornames.py b/src/cthulhu/colornames.py deleted file mode 100644 index 3a33267..0000000 --- a/src/cthulhu/colornames.py +++ /dev/null @@ -1,758 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Igalia, S.L." -__license__ = "LGPL" - -from .cthulhu_i18n import C_ - -cssNames = {} - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f0f8ff"] = C_("color name", "alice blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#faebd7"] = C_("color name", "antique white") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#7fffd4"] = C_("color name", "aquamarine") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f0ffff"] = C_("color name", "azure") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f5f5dc"] = C_("color name", "beige") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffe4c4"] = C_("color name", "bisque") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#000000"] = C_("color name", "black") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffebcd"] = C_("color name", "blanched almond") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#0000ff"] = C_("color name", "blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#8a2be2"] = C_("color name", "blue violet") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#a52a2a"] = C_("color name", "brown") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#deb887"] = C_("color name", "burlywood") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#5f9ea0"] = C_("color name", "cadet blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#7fff00"] = C_("color name", "chartreuse") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#d2691e"] = C_("color name", "chocolate") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ff7f50"] = C_("color name", "coral") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#6495ed"] = C_("color name", "cornflower blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fff8dc"] = C_("color name", "cornsilk") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#dc143c"] = C_("color name", "crimson") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#00ffff"] = C_("color name", "cyan") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#00008b"] = C_("color name", "dark blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#008b8b"] = C_("color name", "dark cyan") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#b8860b"] = C_("color name", "dark goldenrod") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#a9a9a9"] = C_("color name", "dark gray") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#006400"] = C_("color name", "dark green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#bdb76b"] = C_("color name", "dark khaki") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#8b008b"] = C_("color name", "dark magenta") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#556b2f"] = C_("color name", "dark olive green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ff8c00"] = C_("color name", "dark orange") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#9932cc"] = C_("color name", "dark orchid") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#8b0000"] = C_("color name", "dark red") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#e9967a"] = C_("color name", "dark salmon") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#8fbc8f"] = C_("color name", "dark sea green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#483d8b"] = C_("color name", "dark slate blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#2f4f4f"] = C_("color name", "dark slate gray") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#00ced1"] = C_("color name", "dark turquoise") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#9400d3"] = C_("color name", "dark violet") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ff1493"] = C_("color name", "deep pink") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#00bfff"] = C_("color name", "deep sky blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#696969"] = C_("color name", "dim gray") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#1e90ff"] = C_("color name", "dodger blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#b22222"] = C_("color name", "fire brick") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fffaf0"] = C_("color name", "floral white") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#228b22"] = C_("color name", "forest green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ff00ff"] = C_("color name", "fuchsia") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#dcdcdc"] = C_("color name", "gainsboro") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#HTML_color_names. -cssNames["#f8f8ff"] = C_("color name", "ghost white") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffd700"] = C_("color name", "gold") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#daa520"] = C_("color name", "goldenrod") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#808080"] = C_("color name", "gray") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#008000"] = C_("color name", "green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#adff2f"] = C_("color name", "green yellow") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f0fff0"] = C_("color name", "honeydew") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ff69b4"] = C_("color name", "hot pink") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#cd5c5c"] = C_("color name", "indian red") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#4b0082"] = C_("color name", "indigo") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fffff0"] = C_("color name", "ivory") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f0e68c"] = C_("color name", "khaki") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#e6e6fa"] = C_("color name", "lavender") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fff0f5"] = C_("color name", "lavender blush") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#7cfc00"] = C_("color name", "lawn green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fffacd"] = C_("color name", "lemon chiffon") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#add8e6"] = C_("color name", "light blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f08080"] = C_("color name", "light coral") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#e0ffff"] = C_("color name", "light cyan") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fafad2"] = C_("color name", "light goldenrod yellow") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#d3d3d3"] = C_("color name", "light gray") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#90ee90"] = C_("color name", "light green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffb6c1"] = C_("color name", "light pink") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffa07a"] = C_("color name", "light salmon") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#20b2aa"] = C_("color name", "light sea green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#87cefa"] = C_("color name", "light sky blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#778899"] = C_("color name", "light slate gray") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#b0c4de"] = C_("color name", "light steel blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffffe0"] = C_("color name", "light yellow") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#00ff00"] = C_("color name", "lime") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#32cd32"] = C_("color name", "lime green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#faf0e6"] = C_("color name", "linen") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ff00ff"] = C_("color name", "magenta") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#800000"] = C_("color name", "maroon") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#66cdaa"] = C_("color name", "medium aquamarine") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#0000cd"] = C_("color name", "medium blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ba55d3"] = C_("color name", "medium orchid") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#9370d8"] = C_("color name", "medium purple") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#3cb371"] = C_("color name", "medium sea green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#7b68ee"] = C_("color name", "medium slate blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#00fa9a"] = C_("color name", "medium spring green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#48d1cc"] = C_("color name", "medium turquoise") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#c71585"] = C_("color name", "medium violet red") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#191970"] = C_("color name", "midnight blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f5fffa"] = C_("color name", "mint cream") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffe4e1"] = C_("color name", "misty rose") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffe4b5"] = C_("color name", "moccasin") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffdead"] = C_("color name", "navajo white") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#000080"] = C_("color name", "navy") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fdf5e6"] = C_("color name", "old lace") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#808000"] = C_("color name", "olive") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#6b8e23"] = C_("color name", "olive drab") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffa500"] = C_("color name", "orange") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ff4500"] = C_("color name", "orange red") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#da70d6"] = C_("color name", "orchid") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#eee8aa"] = C_("color name", "pale goldenrod") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#98fb98"] = C_("color name", "pale green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#afeeee"] = C_("color name", "pale turquoise") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#d87093"] = C_("color name", "pale violet red") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffefd5"] = C_("color name", "papaya whip") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffdab9"] = C_("color name", "peach puff") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#cd853f"] = C_("color name", "peru") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffc0cb"] = C_("color name", "pink") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#dda0dd"] = C_("color name", "plum") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#b0e0e6"] = C_("color name", "powder blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#800080"] = C_("color name", "purple") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ff0000"] = C_("color name", "red") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#bc8f8f"] = C_("color name", "rosy brown") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#4169e1"] = C_("color name", "royal blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#8b4513"] = C_("color name", "saddle brown") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fa8072"] = C_("color name", "salmon") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f4a460"] = C_("color name", "sandy brown") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#2e8b57"] = C_("color name", "sea green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fff5ee"] = C_("color name", "seashell") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#a0522d"] = C_("color name", "sienna") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#c0c0c0"] = C_("color name", "silver") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#87ceeb"] = C_("color name", "sky blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#6a5acd"] = C_("color name", "slate blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#708090"] = C_("color name", "slate gray") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#fffafa"] = C_("color name", "snow") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#00ff7f"] = C_("color name", "spring green") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#4682b4"] = C_("color name", "steel blue") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#d2b48c"] = C_("color name", "tan") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#008080"] = C_("color name", "teal") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#d8bfd8"] = C_("color name", "thistle") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ff6347"] = C_("color name", "tomato") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#40e0d0"] = C_("color name", "turquoise") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ee82ee"] = C_("color name", "violet") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f5deb3"] = C_("color name", "wheat") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffffff"] = C_("color name", "white") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#f5f5f5"] = C_("color name", "white smoke") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#ffff00"] = C_("color name", "yellow") - -# Translators: This refers to a CSS color name. The name, hex value, and color -# can be found at http://www.w3schools.com/cssref/css_colornames.asp and at -# http://en.wikipedia.org/wiki/Web_colors#X11_color_names. -cssNames["#9acd32"] = C_("color name", "yellow green") - -def rgbToName(red, green, blue): - """Returns the localized name for the RGB value.""" - - hexString = f'#{red:02x}{green:02x}{blue:02x}' - cssName = cssNames.get(hexString) - if cssName: - return cssName - - # Find the closest match. - colors = {} - for key, value in cssNames.items(): - r, g, b = [int(s, 16) for s in (key[1:3], key[3:5], key[5:7])] - rd = abs(r - red) ** 2 - gd = abs(g - green) ** 2 - bd = abs(b - blue) ** 2 - colors[(rd + gd + bd)] = key - - # Hold black and white to higher standards than the other close colors. - d1 = min(colors.keys()) - match = colors.pop(d1) - if match not in ["#000000", "#ffffff"]: - return cssNames.get(match) - - d2 = min(colors.keys()) - if d2 - d1 < d1: - match = colors.pop(d2) - - return cssNames.get(match) diff --git a/src/cthulhu/common_keyboardmap.py b/src/cthulhu/common_keyboardmap.py deleted file mode 100644 index cf79ba5..0000000 --- a/src/cthulhu/common_keyboardmap.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -""" A list of common keybindings and unbound keys - pulled out from default.py: getKeyBindings() - with the goal of being more readable and less monolithic. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010-2011 The Cthulhu Team" -__license__ = "LGPL" - -from . import keybindings - -# Storing values -defaultModifierMask = keybindings.defaultModifierMask -CTHULHU_MODIFIER_MASK = keybindings.CTHULHU_MODIFIER_MASK -NO_MODIFIER_MASK = keybindings.NO_MODIFIER_MASK -CTHULHU_SHIFT_MODIFIER_MASK = keybindings.CTHULHU_SHIFT_MODIFIER_MASK -CTHULHU_CTRL_MODIFIER_MASK = keybindings.CTHULHU_CTRL_MODIFIER_MASK -CTHULHU_ALT_MODIFIER_MASK = keybindings.CTHULHU_ALT_MODIFIER_MASK -CTHULHU_CTRL_ALT_MODIFIER_MASK = keybindings.CTHULHU_CTRL_ALT_MODIFIER_MASK -SHIFT_MODIFIER_MASK = keybindings.SHIFT_MODIFIER_MASK -SHIFT_ALT_MODIFIER_MASK = keybindings.SHIFT_ALT_MODIFIER_MASK - -keymap = ( - - ("space", defaultModifierMask, CTHULHU_MODIFIER_MASK, - "preferencesSettingsHandler"), - - ("space", defaultModifierMask, CTHULHU_CTRL_MODIFIER_MASK, - "appPreferencesSettingsHandler"), - - ("BackSpace", defaultModifierMask, CTHULHU_MODIFIER_MASK, - "bypassNextCommandHandler"), - - ("q", defaultModifierMask, CTHULHU_CTRL_MODIFIER_MASK | SHIFT_MODIFIER_MASK, - "toggleSleepModeHandler"), - - ("q", defaultModifierMask, CTHULHU_MODIFIER_MASK, - "shutdownHandler"), - - - ##################################################################### - # # - # Unbound handlers # - # # - ##################################################################### - - ("", defaultModifierMask, NO_MODIFIER_MASK, - "cycleSettingsProfileHandler"), - - ("", defaultModifierMask, NO_MODIFIER_MASK, - "cycleDebugLevelHandler"), - - ("", defaultModifierMask, NO_MODIFIER_MASK, - "panBrailleLeftHandler"), - - ("", defaultModifierMask, NO_MODIFIER_MASK, - "panBrailleRightHandler"), -) diff --git a/src/cthulhu/compositor_state_adapter.py b/src/cthulhu/compositor_state_adapter.py deleted file mode 100644 index 6a4ecc1..0000000 --- a/src/cthulhu/compositor_state_adapter.py +++ /dev/null @@ -1,304 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Adapter that normalizes compositor and AT-SPI desktop context signals.""" - -from __future__ import annotations - -from dataclasses import replace -from collections.abc import Callable, Iterable -from typing import Any, Optional - -from . import cthulhu_state -from .ax_object import AXObject -from .compositor_state_types import ( - CompositorStateEvent, - DesktopContextSnapshot, - DESKTOP_TRANSITION_FINISHED, - DESKTOP_TRANSITION_STARTED, - DESKTOP_FOCUS_CONTEXT_CHANGED, - FLUSH_STALE_ATSPI_EVENTS, - PAUSE_ATSPI_CHURN, - PRIORITIZE_FOCUS, - RESUME_ATSPI_CHURN, - WORKSPACE_STATE_CHANGED, -) -from .compositor_state_i3 import I3WorkspaceBackend -from .compositor_state_wayland import NullWorkspaceBackend, WaylandSharedProtocolsBackend -from .wnck_support import get_session_type - - -class CompositorStateAdapter: - """Normalizes compositor state and desktop-focus context changes.""" - - def __init__( - self, - workspace_backends: Optional[Iterable[Any]] = None, - ) -> None: - if workspace_backends is None: - workspace_backends = [ - I3WorkspaceBackend(), - WaylandSharedProtocolsBackend(), - NullWorkspaceBackend(), - ] - self._workspaceBackends = list(workspace_backends) - self._workspaceBackend: Optional[Any] = None - self._listeners: list[Callable[[CompositorStateEvent], None]] = [] - self._snapshot = DesktopContextSnapshot(session_type=self.get_session_type()) - - def add_listener(self, listener: Callable[[CompositorStateEvent], None]) -> None: - if listener not in self._listeners: - self._listeners.append(listener) - - def remove_listener(self, listener: Callable[[CompositorStateEvent], None]) -> None: - if listener in self._listeners: - self._listeners.remove(listener) - - def get_snapshot(self) -> DesktopContextSnapshot: - return self._snapshot - - def refresh_workspace_context(self, reason: str) -> DesktopContextSnapshot: - """Refreshes and returns the selected backend's current workspace context.""" - - backend = self._workspaceBackend - refreshContext = getattr(backend, "refresh_context", None) - if callable(refreshContext): - refreshContext(reason) - return self._snapshot - - def get_session_type(self) -> str: - return get_session_type() - - def activate(self) -> None: - self._deactivate_current_backend() - for backend in self._workspaceBackends: - if not self._backend_is_available(backend): - continue - self._workspaceBackend = backend - self._snapshot = DesktopContextSnapshot( - session_type=self.get_session_type(), - backend_name=self._backend_name(), - ) - self._backend_activate(backend) - break - - if self._workspaceBackend is None: - self._snapshot = DesktopContextSnapshot(session_type=self.get_session_type()) - self.sync_accessible_context("activate") - - def deactivate(self) -> None: - self._deactivate_current_backend() - self._snapshot = DesktopContextSnapshot(session_type=self.get_session_type()) - cthulhu_state.compositorSnapshot = None - cthulhu_state.pauseAtspiChurn = False - cthulhu_state.prioritizedDesktopContextToken = None - - def sync_accessible_context(self, reason: str) -> DesktopContextSnapshot: - active_window = cthulhu_state.activeWindow - locus_of_focus = cthulhu_state.locusOfFocus - - active_window_snapshot = self._build_object_snapshot(active_window) - locus_of_focus_snapshot = self._build_object_snapshot(locus_of_focus) - workspaceSnapshot = self._snapshot - snapshot = DesktopContextSnapshot( - session_type=self.get_session_type(), - backend_name=self._backend_name(), - active_workspace_ids=workspaceSnapshot.active_workspace_ids, - workspace_transition_pending=workspaceSnapshot.workspace_transition_pending, - active_window_token=active_window_snapshot["token"], - locus_of_focus_token=locus_of_focus_snapshot["token"], - active_window_pid=active_window_snapshot["pid"], - locus_of_focus_pid=locus_of_focus_snapshot["pid"], - active_window_name=active_window_snapshot["name"], - locus_of_focus_name=locus_of_focus_snapshot["name"], - focused_window_id=workspaceSnapshot.focused_window_id, - focused_window_title=workspaceSnapshot.focused_window_title, - focused_workspace_empty=workspaceSnapshot.focused_workspace_empty, - ) - - previous_token = self._snapshot.active_window_token - self._snapshot = snapshot - cthulhu_state.compositorSnapshot = snapshot - - if snapshot.active_window_token != previous_token: - cthulhu_state.prioritizedDesktopContextToken = snapshot.active_window_token or None - self._emit( - DESKTOP_FOCUS_CONTEXT_CHANGED, - reason, - snapshot, - ) - self._emit( - PRIORITIZE_FOCUS, - reason, - snapshot, - ) - - return snapshot - - def _build_object_snapshot(self, obj: Any) -> dict[str, Any]: - if obj is None: - return {"token": "", "pid": -1, "name": ""} - - pid = AXObject.get_process_id(obj) - name = (AXObject.get_name(obj) or "").strip() - if not name: - name = AXObject.get_role_name(obj) or AXObject.get_accessible_id(obj) or "unknown" - - token = "" - if pid >= 0 or name: - token = f"{max(pid, 0)}:{name}" - - return {"token": token, "pid": pid, "name": name} - - def _handle_workspace_signal( - self, - signal_name: str, - workspace_ids: Optional[Iterable[str]] = None, - reason: str = "", - payload: Optional[dict[str, Any]] = None, - ) -> None: - if workspace_ids is not None: - payload = payload or {} - focusedWorkspaceEmpty = payload.get( - "focused_workspace_empty", - self._snapshot.focused_workspace_empty, - ) - clearAccessibleContext = focusedWorkspaceEmpty is True - snapshot = replace( - self._snapshot, - active_workspace_ids=frozenset(str(workspaceId) for workspaceId in workspace_ids if workspaceId), - workspace_transition_pending=signal_name == DESKTOP_TRANSITION_STARTED, - active_window_token="" if clearAccessibleContext else self._snapshot.active_window_token, - locus_of_focus_token="" if clearAccessibleContext else self._snapshot.locus_of_focus_token, - active_window_pid=-1 if clearAccessibleContext else self._snapshot.active_window_pid, - locus_of_focus_pid=-1 if clearAccessibleContext else self._snapshot.locus_of_focus_pid, - active_window_name="" if clearAccessibleContext else self._snapshot.active_window_name, - locus_of_focus_name="" if clearAccessibleContext else self._snapshot.locus_of_focus_name, - focused_window_id=payload.get( - "focused_window_id", - self._snapshot.focused_window_id, - ), - focused_window_title=payload.get( - "focused_window_title", - self._snapshot.focused_window_title, - ), - focused_workspace_empty=focusedWorkspaceEmpty, - ) - self._snapshot = snapshot - cthulhu_state.compositorSnapshot = snapshot - - if signal_name == DESKTOP_TRANSITION_STARTED: - cthulhu_state.pauseAtspiChurn = True - self._emit(signal_name, reason, snapshot, payload) - self._emit(PAUSE_ATSPI_CHURN, reason, snapshot, payload) - return - - if signal_name == DESKTOP_TRANSITION_FINISHED: - cthulhu_state.pauseAtspiChurn = False - self._emit(signal_name, reason, snapshot, payload) - self._emit(RESUME_ATSPI_CHURN, reason, snapshot, payload) - self._emit(FLUSH_STALE_ATSPI_EVENTS, reason, snapshot, payload) - return - - if signal_name == PAUSE_ATSPI_CHURN: - cthulhu_state.pauseAtspiChurn = True - elif signal_name == RESUME_ATSPI_CHURN: - cthulhu_state.pauseAtspiChurn = False - - self._emit(signal_name, reason, snapshot, payload) - return - - normalized = (signal_name or "").strip().lower() - if not normalized: - return - - if "transition" not in normalized and "workspace" not in normalized: - return - - if any(marker in normalized for marker in ("start", "begin", "enter", "prepare", "opening")): - self._handle_workspace_signal( - DESKTOP_TRANSITION_STARTED, - self._snapshot.active_workspace_ids, - signal_name, - ) - return - - if any(marker in normalized for marker in ("end", "complete", "finished", "finish", "leave", "exit", "stop", "done")): - self._handle_workspace_signal( - DESKTOP_TRANSITION_FINISHED, - self._snapshot.active_workspace_ids, - signal_name, - ) - return - - if "flush" in normalized or "stale" in normalized: - self._emit(FLUSH_STALE_ATSPI_EVENTS, signal_name, self._snapshot) - return - - if "workspace" in normalized: - self._handle_workspace_signal( - WORKSPACE_STATE_CHANGED, - self._snapshot.active_workspace_ids, - signal_name, - ) - - def _emit( - self, - event_type: str, - reason: str, - snapshot: Optional[DesktopContextSnapshot], - payload: Optional[dict[str, Any]] = None, - ) -> None: - event = CompositorStateEvent(event_type, reason=reason, snapshot=snapshot, payload=payload or {}) - for listener in list(self._listeners): - listener(event) - - def _backend_is_available(self, backend: Any) -> bool: - if hasattr(backend, "is_available"): - try: - return bool(backend.is_available(self.get_session_type())) - except TypeError: - return bool(backend.is_available()) - if hasattr(backend, "available"): - return bool(backend.available) - return True - - def _backend_activate(self, backend: Any) -> None: - if hasattr(backend, "activate"): - try: - backend.activate(self._handle_workspace_signal) - except TypeError: - try: - backend.activate(self) - except TypeError: - backend.activate() - - def _backend_deactivate(self, backend: Any) -> None: - if hasattr(backend, "deactivate"): - try: - backend.deactivate(self) - except TypeError: - backend.deactivate() - - def _deactivate_current_backend(self) -> None: - if self._workspaceBackend is None: - return - - self._backend_deactivate(self._workspaceBackend) - self._workspaceBackend = None - - def _backend_name(self) -> str: - if self._workspaceBackend is None: - return "" - - name = getattr(self._workspaceBackend, "name", "") - if name: - return str(name) - - return self._workspaceBackend.__class__.__name__ diff --git a/src/cthulhu/compositor_state_i3.py b/src/cthulhu/compositor_state_i3.py deleted file mode 100644 index ad13091..0000000 --- a/src/cthulhu/compositor_state_i3.py +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Optional i3 IPC backend for authoritative X11 workspace and focus state.""" - -from __future__ import annotations - -import importlib -import threading -from collections.abc import Mapping -from typing import Any, Optional - -from gi.repository import GLib - -from . import debug -from .compositor_state_types import ( - DESKTOP_TRANSITION_FINISHED, - DESKTOP_TRANSITION_STARTED, - WORKSPACE_STATE_CHANGED, -) -from .wnck_support import get_session_type - - -class I3WorkspaceBackend: - """Tracks the focused i3 workspace and its real foreground X11 window.""" - - name = "i3-ipc" - - def __init__(self, *, i3ipc_module: Any = None) -> None: - self._i3ipc = i3ipc_module - self._connection: Any = None - self._emitSignal: Any = None - self._eventThread: Optional[threading.Thread] = None - self._active = False - self._lastContext: Optional[tuple[Any, ...]] = None - - def is_available(self, session_type: str | None = None) -> bool: - effectiveSessionType = (session_type or get_session_type()).strip().lower() - if effectiveSessionType != "x11": - return False - - if self._i3ipc is None: - try: - self._i3ipc = importlib.import_module("i3ipc") - except ImportError: - return False - - return self._ensure_connection() - - def activate(self, emit_signal: Any = None) -> None: - self.deactivate() - self._emitSignal = emit_signal - if emit_signal is None or not self.is_available(): - return - - self._active = True - self._subscribe() - self._refresh_context("activate", transition=False) - self._eventThread = threading.Thread( - target=self._run_event_loop, - name="cthulhu-i3-ipc", - daemon=True, - ) - self._eventThread.start() - - def deactivate(self, emit_signal: Any = None) -> None: - self._active = False - connection = self._connection - if connection is not None: - quitLoop = getattr(connection, "main_quit", None) - if callable(quitLoop): - try: - quitLoop() - except Exception: - pass - - commandSocket = getattr(connection, "_cmd_socket", None) - if commandSocket is not None: - try: - commandSocket.close() - except Exception: - pass - - self._connection = None - self._eventThread = None - self._emitSignal = None - self._lastContext = None - - def refresh_context(self, reason: str) -> None: - """Refreshes the cached i3 focus context without emitting a transition.""" - - self._refresh_context(reason, transition=False) - - def _ensure_connection(self) -> bool: - if self._connection is not None: - return True - if self._i3ipc is None: - return False - - connectionClass = getattr(self._i3ipc, "Connection", None) - if not callable(connectionClass): - return False - - try: - try: - self._connection = connectionClass(auto_reconnect=True) - except TypeError: - self._connection = connectionClass() - self._connection.get_workspaces() - except Exception as error: - self._connection = None - msg = f"COMPOSITOR STATE: i3 IPC unavailable: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - return True - - def _subscribe(self) -> None: - if self._connection is None or self._i3ipc is None: - return - - onEvent = getattr(self._connection, "on", None) - eventType = getattr(self._i3ipc, "Event", None) - if not callable(onEvent) or eventType is None: - return - - onEvent(eventType.WORKSPACE, self._handle_ipc_event) - onEvent(eventType.WINDOW, self._handle_ipc_event) - - def _run_event_loop(self) -> None: - connection = self._connection - runLoop = getattr(connection, "main", None) - if not callable(runLoop): - return - - try: - runLoop() - except Exception as error: - if self._active: - msg = f"COMPOSITOR STATE: i3 IPC event loop stopped: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - - def _handle_ipc_event(self, _connection: Any, event: Any) -> None: - if not self._active: - return - - change = str(getattr(event, "change", "") or "changed") - GLib.idle_add(self._refresh_context, f"i3-{change}", True) - - def _query_context(self) -> tuple[set[str], dict[str, Any]]: - if self._connection is None: - raise RuntimeError("i3 IPC is not connected") - - workspaceReplies = self._connection.get_workspaces() - focusedReply = next( - (workspace for workspace in workspaceReplies if bool(getattr(workspace, "focused", False))), - None, - ) - if focusedReply is None: - raise RuntimeError("i3 did not report a focused workspace") - - workspaceName = str(getattr(focusedReply, "name", "") or "").strip() - if not workspaceName: - raise RuntimeError("i3 focused workspace has no name") - - tree = self._connection.get_tree() - focusedWorkspace = next( - ( - workspace - for workspace in tree.workspaces() - if str(getattr(workspace, "name", "") or "") == workspaceName - ), - None, - ) - if focusedWorkspace is None: - raise RuntimeError(f"i3 tree is missing focused workspace {workspaceName}") - - windowNodes = [ - node - for node in focusedWorkspace - if self._positive_window_id(getattr(node, "window", None)) is not None - ] - focusedNode = tree.find_focused() - focusedWindowId: Optional[int] = None - focusedWindowTitle = "" - if focusedNode is not None and focusedNode.workspace() is focusedWorkspace: - focusedWindowId = self._positive_window_id(getattr(focusedNode, "window", None)) - if focusedWindowId is not None: - focusedWindowTitle = str( - getattr(focusedNode, "window_title", None) - or getattr(focusedNode, "name", None) - or "" - ).strip() - - payload = { - "focused_window_id": focusedWindowId, - "focused_window_title": focusedWindowTitle, - "focused_workspace_empty": not windowNodes, - } - return {workspaceName}, payload - - @staticmethod - def _positive_window_id(value: Any) -> Optional[int]: - try: - windowId = int(value) - except (TypeError, ValueError): - return None - return windowId if windowId > 0 else None - - def _refresh_context(self, reason: str, transition: bool = True) -> bool: - if not self._active: - return False - - try: - workspaceIds, payload = self._query_context() - except Exception as error: - msg = f"COMPOSITOR STATE: Could not query i3 context: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - unknownPayload = { - "focused_window_id": None, - "focused_window_title": "", - "focused_workspace_empty": None, - } - self._lastContext = None - self._emit_signal( - WORKSPACE_STATE_CHANGED, - set(), - f"{reason}: i3-context-unknown", - unknownPayload, - ) - return False - - context = ( - frozenset(workspaceIds), - payload["focused_window_id"], - payload["focused_window_title"], - payload["focused_workspace_empty"], - ) - if context == self._lastContext: - return False - self._lastContext = context - - if transition: - self._emit_signal(DESKTOP_TRANSITION_STARTED, workspaceIds, reason, payload) - self._emit_signal(WORKSPACE_STATE_CHANGED, workspaceIds, reason, payload) - if transition: - self._emit_signal(DESKTOP_TRANSITION_FINISHED, workspaceIds, reason, payload) - return False - - def _emit_signal( - self, - signalType: str, - workspaceIds: set[str], - reason: str, - payload: Mapping[str, Any], - ) -> None: - if callable(self._emitSignal): - self._emitSignal(signalType, workspaceIds, reason, dict(payload)) diff --git a/src/cthulhu/compositor_state_types.py b/src/cthulhu/compositor_state_types.py deleted file mode 100644 index 5880b6d..0000000 --- a/src/cthulhu/compositor_state_types.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Normalized compositor-state event vocabulary and snapshots.""" - -from __future__ import annotations - -from dataclasses import dataclass, field -from typing import Any, Mapping, Optional - -DESKTOP_FOCUS_CONTEXT_CHANGED = "DESKTOP_FOCUS_CONTEXT_CHANGED" -PRIORITIZE_FOCUS = "PRIORITIZE_FOCUS" -WORKSPACE_STATE_CHANGED = "WORKSPACE_STATE_CHANGED" -DESKTOP_TRANSITION_STARTED = "DESKTOP_TRANSITION_STARTED" -DESKTOP_TRANSITION_FINISHED = "DESKTOP_TRANSITION_FINISHED" -PAUSE_ATSPI_CHURN = "PAUSE_ATSPI_CHURN" -RESUME_ATSPI_CHURN = "RESUME_ATSPI_CHURN" -FLUSH_STALE_ATSPI_EVENTS = "FLUSH_STALE_ATSPI_EVENTS" - - -@dataclass(frozen=True, slots=True) -class DesktopContextSnapshot: - """Immutable snapshot of the desktop context tracked by the adapter.""" - - session_type: str - backend_name: str = "" - active_workspace_ids: frozenset[str] = field(default_factory=frozenset) - workspace_transition_pending: bool = False - active_window_token: str = "" - locus_of_focus_token: str = "" - active_window_pid: int = -1 - locus_of_focus_pid: int = -1 - active_window_name: str = "" - locus_of_focus_name: str = "" - focused_window_id: Optional[int] = None - focused_window_title: str = "" - focused_workspace_empty: Optional[bool] = None - - -@dataclass(frozen=True, slots=True) -class CompositorStateEvent: - """Normalized event emitted by the compositor state adapter.""" - - type: str - reason: str = "" - snapshot: Optional[DesktopContextSnapshot] = None - payload: Mapping[str, Any] = field(default_factory=dict) diff --git a/src/cthulhu/compositor_state_wayland.py b/src/cthulhu/compositor_state_wayland.py deleted file mode 100644 index ba6f22a..0000000 --- a/src/cthulhu/compositor_state_wayland.py +++ /dev/null @@ -1,365 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Wayland workspace backends for normalized compositor state tracking.""" - -from __future__ import annotations - -import os -from collections.abc import Mapping, Sequence -from typing import Any - -from gi.repository import GLib - -from . import debug -from .compositor_state_types import ( - DESKTOP_TRANSITION_FINISHED, - DESKTOP_TRANSITION_STARTED, - WORKSPACE_STATE_CHANGED, -) -from .wayland_protocols import ext_workspace_v1 -from .wnck_support import get_session_type - - -class NullWorkspaceBackend: - """No-op backend used when no real workspace backend is available.""" - - name = "null" - - def __init__(self) -> None: - self._emitSignal = None - - def is_available(self, session_type: str | None = None) -> bool: - return True - - def activate(self, emit_signal: Any = None) -> None: - self._emitSignal = emit_signal - - def deactivate(self, emit_signal: Any = None) -> None: - self._emitSignal = None - - -class WaylandSharedProtocolsBackend: - """Runtime-optional backend for the ext-workspace shared Wayland protocol.""" - - name = "wayland-shared-protocols" - - def __init__( - self, - *, - environment: Mapping[str, str] | None = None, - protocols: Any = None, - ) -> None: - self._environment = environment if environment is not None else os.environ - self._protocols = protocols or ext_workspace_v1 - self._emitSignal = None - self._display = None - self._registry = None - self._workspaceManager = None - self._workspaceStates: dict[Any, dict[str, Any]] = {} - self._batchDirty = False - self._transitionPending = False - self._dispatchSourceId = 0 - - def is_available(self, session_type: str | None = None) -> bool: - effectiveSessionType = (session_type or get_session_type()).strip().lower() - return ( - effectiveSessionType == "wayland" - and bool((self._environment.get("WAYLAND_DISPLAY") or "").strip()) - and bool(self._protocols.has_runtime_support()) - ) - - def activate(self, emit_signal: Any = None) -> None: - self.deactivate() - self._emitSignal = emit_signal - - if emit_signal is None or not self.is_available(): - return - - displayClass = self._protocols.get_display_class() - if displayClass is None: - return - - try: - self._display = displayClass() - connect = getattr(self._display, "connect", None) - if callable(connect): - connect() - get_registry = getattr(self._display, "get_registry", None) - if not callable(get_registry): - raise RuntimeError("Wayland display missing registry access") - self._registry = get_registry() - self._bind_listener(self._registry, "global", self._handle_registry_global) - self._bind_listener(self._registry, "global_remove", self._handle_registry_global_remove) - self._roundtrip() - self._install_dispatch_watch() - except Exception as error: - msg = f"COMPOSITOR STATE: Wayland backend activation failed: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - self.deactivate() - - def deactivate(self, emit_signal: Any = None) -> None: - self._workspaceStates = {} - self._batchDirty = False - self._transitionPending = False - self._remove_dispatch_watch() - self._safe_close_proxy(self._workspaceManager) - self._safe_close_proxy(self._registry) - self._workspaceManager = None - self._registry = None - - if self._display is not None: - disconnect = getattr(self._display, "disconnect", None) - if callable(disconnect): - try: - disconnect() - except Exception: - pass - self._display = None - self._emitSignal = None - - def _bind_listener(self, target: Any, event_name: str, callback: Any) -> bool: - dispatcher = getattr(target, "dispatcher", None) - if dispatcher is not None: - try: - dispatcher[event_name] = callback - return True - except Exception: - pass - - add_listener = getattr(target, "add_listener", None) - if callable(add_listener): - try: - add_listener(**{event_name: callback}) - return True - except TypeError: - try: - add_listener(event_name, callback) - return True - except TypeError: - pass - - attributeName = f"on_{event_name}" - if hasattr(target, attributeName): - setattr(target, attributeName, callback) - return True - - return False - - def _roundtrip(self) -> None: - if self._display is None: - return - - for methodName in ("roundtrip", "dispatch", "dispatch_pending"): - method = getattr(self._display, methodName, None) - if callable(method): - method() - break - - def _install_dispatch_watch(self) -> None: - if self._display is None or self._dispatchSourceId: - return - - getFd = getattr(self._display, "get_fd", None) - if not callable(getFd): - return - - try: - displayFd = int(getFd()) - except Exception: - return - - if displayFd < 0: - return - - self._dispatchSourceId = GLib.io_add_watch( - displayFd, - GLib.PRIORITY_DEFAULT, - GLib.IO_IN | GLib.IO_ERR | GLib.IO_HUP, - self._dispatch_display_events, - ) - - def _remove_dispatch_watch(self) -> None: - if not self._dispatchSourceId: - return - - try: - GLib.source_remove(self._dispatchSourceId) - except Exception: - pass - - self._dispatchSourceId = 0 - - def _dispatch_display_events(self, _fd: int, condition: Any) -> bool: - if condition & (GLib.IO_ERR | GLib.IO_HUP): - self.deactivate() - return False - - dispatch = getattr(self._display, "dispatch", None) - if not callable(dispatch): - self.deactivate() - return False - - try: - while True: - dispatched = dispatch(block=False) - if not dispatched: - break - except TypeError: - try: - dispatch() - except Exception: - self.deactivate() - return False - except Exception: - self.deactivate() - return False - - return True - - def _safe_close_proxy(self, proxy: Any) -> None: - if proxy is None: - return - - for methodName in ("destroy", "release"): - method = getattr(proxy, methodName, None) - if callable(method): - try: - method() - except Exception: - pass - return - - def _handle_registry_global(self, *args: Any) -> None: - if self._workspaceManager is not None: - return - - globalName, interfaceName, interfaceVersion = self._parse_registry_global_args(args) - if interfaceName != self._protocols.INTERFACE_NAME: - return - - registry = self._registry - if registry is None: - return - - bindVersion = min(interfaceVersion, self._protocols.INTERFACE_VERSION) - try: - self._workspaceManager = self._protocols.bind_workspace_manager( - registry, - globalName, - bindVersion, - ) - except Exception: - self._workspaceManager = None - - if self._workspaceManager is None: - return - - self._bind_listener(self._workspaceManager, "workspace", self._handle_workspace_manager_workspace) - self._bind_listener(self._workspaceManager, "done", self._handle_workspace_manager_done) - self._bind_listener(self._workspaceManager, "finished", self._handle_workspace_manager_finished) - - def _handle_registry_global_remove(self, *args: Any) -> None: - return - - def _handle_workspace_manager_workspace(self, *args: Any) -> None: - workspaceHandle = args[-1] if args else None - if workspaceHandle is None or workspaceHandle in self._workspaceStates: - return - - self._workspaceStates[workspaceHandle] = {"active": False} - self._bind_listener(workspaceHandle, "id", self._handle_workspace_id) - self._bind_listener(workspaceHandle, "state", self._handle_workspace_state) - self._bind_listener(workspaceHandle, "removed", self._handle_workspace_removed) - - def _handle_workspace_id(self, workspaceHandle: Any, workspaceId: str, *_args: Any) -> None: - workspaceState = self._workspaceStates.setdefault(workspaceHandle, {"active": False}) - workspaceState["workspace_id"] = (workspaceId or "").strip() - self._batchDirty = True - - def _handle_workspace_state(self, workspaceHandle: Any, stateValue: Any, value: Any = None, *_args: Any) -> None: - workspaceState = self._workspaceStates.setdefault(workspaceHandle, {"active": False}) - workspaceState["active"] = self._workspace_is_active(stateValue, value) - self._batchDirty = True - self._emit_transition_started("workspace-state-update") - - def _handle_workspace_removed(self, workspaceHandle: Any, *_args: Any) -> None: - self._workspaceStates.pop(workspaceHandle, None) - self._batchDirty = True - self._emit_transition_started("workspace-removed") - - def _handle_workspace_manager_done(self, *_args: Any) -> None: - if not self._batchDirty: - return - - activeWorkspaceIds = self._active_workspace_ids() - self._emit_signal(WORKSPACE_STATE_CHANGED, activeWorkspaceIds, "workspace-batch-done") - self._emit_signal(DESKTOP_TRANSITION_FINISHED, activeWorkspaceIds, "workspace-batch-done") - self._batchDirty = False - self._transitionPending = False - - def _handle_workspace_manager_finished(self, *_args: Any) -> None: - self._workspaceManager = None - - def _workspace_is_active(self, stateValue: Any, value: Any = None) -> bool: - if isinstance(stateValue, str): - return stateValue.strip().lower() == "active" and bool(value) - - if isinstance(stateValue, Mapping): - return bool(stateValue.get("active")) - - if isinstance(stateValue, Sequence) and not isinstance(stateValue, (str, bytes, bytearray)): - return self._protocols.ACTIVE_STATE_VALUE in stateValue - - return bool(stateValue) - - def _active_workspace_ids(self) -> set[str]: - workspaceIds = set() - for workspaceHandle, workspaceState in self._workspaceStates.items(): - if not workspaceState.get("active"): - continue - workspaceId = (workspaceState.get("workspace_id") or "").strip() - if not workspaceId: - workspaceId = self._workspace_id(workspaceHandle) - workspaceIds.add(workspaceId) - return workspaceIds - - def _workspace_id(self, workspaceHandle: Any) -> str: - return f"workspace:{id(workspaceHandle)}" - - def _emit_transition_started(self, reason: str) -> None: - if self._transitionPending: - return - self._transitionPending = True - self._emit_signal(DESKTOP_TRANSITION_STARTED, self._active_workspace_ids(), reason) - - def _emit_signal(self, signalType: str, workspaceIds: set[str], reason: str) -> None: - if callable(self._emitSignal): - self._emitSignal(signalType, workspaceIds, reason) - return - - def _parse_registry_global_args(self, args: Sequence[Any]) -> tuple[int, str, int]: - if len(args) >= 4: - _, globalName, interfaceName, interfaceVersion = args[-4:] - elif len(args) >= 3: - globalName, interfaceName, interfaceVersion = args[-3:] - else: - return (-1, "", 0) - - try: - parsedName = int(globalName) - except (TypeError, ValueError): - parsedName = -1 - - try: - parsedVersion = int(interfaceVersion) - except (TypeError, ValueError): - parsedVersion = self._protocols.INTERFACE_VERSION - - return parsedName, str(interfaceName or ""), parsedVersion diff --git a/src/cthulhu/cthulhu-find.ui b/src/cthulhu/cthulhu-find.ui deleted file mode 100644 index b24158d..0000000 --- a/src/cthulhu/cthulhu-find.ui +++ /dev/null @@ -1,359 +0,0 @@ - - - - - False - 12 - Find - False - True - dialog - - - Screen Reader Find Dialog - - - - - - True - False - vertical - - - True - False - end - - - _Close - True - True - True - False - True - - - - False - True - 0 - - - - - _Find - True - False - True - True - True - False - True - - - - False - True - 1 - - - - - False - True - end - 0 - - - - - True - False - 20 - 20 - - - True - False - 5 - - - True - False - 0 - _Search for: - True - True - searchForEntry - 12 - - - Search for: - - - - - 0 - 0 - - - - - True - True - True - ● - True - - - Search for: - - - - - - 1 - 0 - 2 - - - - - 0 - 0 - - - - - True - False - end - 20 - 20 - - - True - False - 0 - none - - - True - False - - - True - False - - - C_urrent location - True - True - False - True - True - True - - - - 0 - 0 - - - - - _Top of window - True - True - False - True - True - currentLocationRadioButton - - - Top of window - - - - - - 0 - 1 - - - - - - - - - True - False - Start from: - - - Start from: - - - - - - - - - - 0 - 0 - - - - - True - False - 0 - none - - - True - False - - - True - False - - - _Wrap around - True - True - False - True - True - True - - - - 0 - 1 - - - - - Search _backwards - True - True - False - True - True - - - - 0 - 0 - - - - - - - - - True - False - Search direction: - - - - - - - - 1 - 0 - - - - - True - False - 0 - none - - - True - False - - - True - False - - - _Match case - True - True - False - True - True - - - - 0 - 0 - - - - - Match _entire word only - True - True - False - True - True - - - - 0 - 1 - - - - - - - - - True - False - Options: - - - - - - - - 2 - 0 - - - - - 0 - 1 - - - - - True - True - 1 - - - - - - closeButton - findButton - - - diff --git a/src/cthulhu/cthulhu-setup.ui b/src/cthulhu/cthulhu-setup.ui deleted file mode 100644 index bfc0a40..0000000 --- a/src/cthulhu/cthulhu-setup.ui +++ /dev/null @@ -1,4747 +0,0 @@ - - - - - 9999 - 10 - 1 - 10 - - - 1 - 10 - 3 - 1 - 1 - - - 0 - 255 - 200 - 10 - 50 - - - - - - - - - - - - - - - - - - - - - Default - - - Uppercase - - - Hyperlink - - - System - - - - - - - - - - - Line - - - Sentence - - - - - - - - - - - All - - - Application - - - Window - - - - - - - - - - - Insert, KP_Insert - - - KP_Insert - - - Insert - - - Caps_Lock, Shift_Lock - - - - - - - - - - - - - 10 - 5 - 0.10000000149 - 1 - - - 9999 - 10 - 1 - 10 - - - 9999 - 0 - 1 - 10 - - - 100 - 50 - 1 - 10 - - - 10 - 10 - 0.10000000149 - 1 - - - 1 - 0.5 - 0.05000000075 - 0.10000000149 - - - 10 - 5 - 0.10000000149 - 1 - - - 100 - 50 - 1 - 10 - - - 10 - 10 - 0.10000000149 - 1 - - - False - Cthulhu Preferences - normal - - - - - True - False - vertical - 3 - - - True - False - end - - - _Help - True - True - True - False - True - - - - False - False - 0 - - - - - _Apply - True - True - True - False - True - - - - False - False - 1 - - - - - _Cancel - True - True - True - False - True - - - - False - False - 2 - - - - - _OK - True - True - True - False - True - - - - False - False - 3 - - - - - False - True - end - 0 - - - - - True - True - - - True - False - 12 - 10 - 10 - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - _Desktop - True - True - False - True - True - True - - - - 0 - 0 - - - - - _Laptop - True - True - False - True - True - generalDesktopButton - - - - 0 - 1 - - - - - - - - - True - False - Keyboard Layout - - - - - - - - 0 - 0 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - True - - - 150 - True - False - 0 - Active _Profile: - True - availableProfilesComboBox1 - - - - - - 0 - 0 - - - - - True - False - 0 - Start-up Profile: - availableProfilesComboBox2 - - - - - - 0 - 1 - - - - - 200 - True - False - model9 - - - - 0 - - - - - 1 - 0 - - - - - True - False - model9 - - - - 0 - - - - - 1 - 1 - - - - - _Load - True - True - True - True - - - - 2 - 0 - - - - - Save _As - True - True - True - True - - - - 3 - 0 - - - - - _Remove - True - True - True - True - - - - 4 - 0 - - - - - - - - - - - - - - - - - - True - False - Profiles - - - - - - - - 0 - 3 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - _Present tooltips - True - True - False - True - 0 - True - - - - 0 - 0 - - - - - Speak object under mo_use - True - True - False - True - 0 - True - True - - - - 0 - 1 - - - - - - - - - True - False - Mouse - - - - - - - - 0 - 1 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - True - - - 150 - True - False - 0 - _Time format: - True - timeFormatCombo - - - - - - 0 - 0 - - - - - True - False - 0 - Dat_e format: - True - dateFormatCombo - - - - - - 0 - 1 - - - - - True - False - liststore1 - - - - - 0 - - - - - 1 - 0 - - - - - True - False - liststore2 - - - - - 0 - - - - - 1 - 1 - - - - - - - - - True - False - Time and Date - - - - - - - - 0 - 2 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - _Speak updates - True - True - False - start - True - True - 0 - True - True - - - - 0 - 0 - - - - - _Braille updates - True - True - False - True - True - True - - - - 0 - 1 - - - - - True - False - 10 - 20 - - - True - True - ● - 10 - progressBarUpdateIntervalAdjustment - 1 - True - 10 - - - - 1 - 0 - - - - - True - False - Frequency (secs): - True - progressBarUpdateIntervalSpinButton - 0 - - - 0 - 0 - - - - - True - False - Applies to: - True - progressBarVerbosity - 0 - - - 0 - 1 - - - - - True - False - model7 - - - - - 0 - - - - - 1 - 1 - - - - - 0 - 3 - - - - - - - - - True - False - Progress Bar Updates - - - - - - - - 1 - 0 - 2 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - Enable _rewind and fast forward in Say All - True - True - False - True - 0 - True - - - - 0 - 0 - - - - - Enable _structural navigation in Say All - True - True - False - True - 0 - True - True - - - - 0 - 1 - - - - - True - False - 20 - 20 - - - -` - True - False - Say All B_y: - True - sayAllStyle - 0 - - - - - - 0 - 0 - - - - - True - False - model2 - - - - - 0 - - - - - 1 - 0 - - - - - 0 - 8 - - - - - Announce block_quotes in Say All - True - True - False - True - 0 - True - True - - - - 0 - 2 - - - - - Announce li_sts in Say All - True - True - False - True - 0 - True - True - - - - 0 - 5 - - - - - Announce _tables in Say All - True - True - False - True - 0 - True - True - - - - 0 - 7 - - - - - Announce _panels in Say All - True - True - False - True - 0 - True - True - - - - 0 - 6 - - - - - Announce _forms in Say All - True - True - False - True - 0 - True - True - - - - 0 - 3 - - - - - Announce land_marks in Say All - True - True - False - True - 0 - True - True - - - - 0 - 4 - - - - - - - - - True - False - Say All - - - - - - - - 1 - 2 - 2 - - - - - 0 - - - - - True - False - General - - - 0 - False - - - - - True - False - 12 - 10 - 10 - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 10 - 20 - - - Enable _sounds - True - True - False - True - 0 - True - True - - - - 0 - 0 - 2 - - - - - True - False - 0 - Sound _volume: - True - soundVolumeScale - - - - - - 0 - 1 - - - - - True - True - soundVolumeAdjustment - 2 - 2 - right - - - - 1 - 1 - - - - - True - False - 12 - - - True - False - 0 - Audio _backend: - True - soundSinkCombo - - - - - - False - True - 0 - - - - - True - False - - - - - - - False - True - 1 - - - - - 0 - 2 - 2 - - - - - - - - - True - False - Output - - - - - - - - 0 - 0 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 10 - 20 - - - True - False - 12 - - - True - False - 0 - Sound _theme: - True - soundThemeCombo - - - - - - False - True - 0 - - - - - True - False - - - - - - - False - True - 1 - - - - - 0 - 0 - 2 - - - - - True - False - 12 - - - True - False - 0 - Element _presentation: - True - roleSoundPresentationCombo - - - - - - False - True - 0 - - - - - True - False - - - - - - - False - True - 1 - - - - - 0 - 1 - 2 - - - - - Play sound for _role - True - True - False - True - 0 - True - - - - 0 - 2 - 2 - - - - - Play sound for _state - True - True - False - True - 0 - True - - - - 0 - 3 - 2 - - - - - Play sound for p_osition in set - True - True - False - True - 0 - True - - - - 0 - 4 - 2 - - - - - Play sound for _value - True - True - False - True - 0 - True - - - - 0 - 5 - 2 - - - - - Use stereo _position for object sounds - True - True - False - True - 0 - True - - - - 0 - 6 - 2 - - - - - - - - - True - False - Presentation - - - - - - - - 1 - 0 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 10 - 20 - - - Bee_p progress bar updates - True - True - False - True - 0 - True - True - - - - 0 - 0 - 2 - - - - - True - False - 0 - Beep _frequency (secs): - True - progressBarBeepIntervalSpinButton - - - - - - 0 - 1 - - - - - True - True - 0 - progressBarBeepIntervalAdjustment - 1 - True - 0 - - - - 1 - 1 - - - - - - - - - True - False - Alerts - - - - - - - - 0 - 1 - 2 - - - - - 1 - - - - - True - False - Sounds - - - 1 - False - - - - - True - False - 12 - 10 - 40 - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 12 - - - True - False - 1 - Vo_lume: - True - right - volumeScale - - - - - - 0 - 8 - - - - - True - True - volumeAdjustment - 1 - right - - - - - 1 - 8 - - - - - True - True - pitchAdjustment - 1 - right - - - - - 1 - 7 - - - - - True - False - 1 - Pi_tch: - True - right - pitchScale - - - 0 - 7 - - - - - True - True - rateAdjustment - 0 - 0 - right - - - - - 1 - 6 - - - - - True - False - 1 - _Rate: - True - right - rateScale - - - 0 - 6 - - - - - True - False - - - - 1 - 4 - - - - - True - False - 1 - _Person: - True - right - speechFamilies - - - 0 - 4 - - - - - True - False - - - - 1 - 3 - - - - - True - False - 1 - _Language: - True - right - speechLanguages - - - 0 - 3 - - - - - True - False - - - - 1 - 2 - - - - - True - False - 1 - Speech synthesi_zer: - True - right - speechServers - - - 0 - 2 - - - - - True - False - - - - 1 - 1 - - - - - True - False - 1 - Speech _system: - True - right - speechSystems - - - 0 - 1 - - - - - True - False - model1 - - - - - 0 - - - - - 1 - 0 - - - - - True - False - 1 - _Voice type: - True - right - voiceTypesCombo - - - 0 - 0 - - - - - True - False - _Capitalization style: - True - right - capitalizationStyle - 1 - - - 0 - 5 - - - - - True - False - - - - - 0 - - - - - 1 - 5 - - - - - False - False - 1 - Serial _device: - True - right - hardwareDeviceCombo - - - - - - 0 - 9 - - - - - False - False - - - - 1 - 9 - - - - - - - - - True - False - Voice Type Settings - - - - - - - - 0 - 0 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - Break speech into ch_unks between pauses - True - True - False - True - True - True - - - - 0 - 0 - - - - - Speak multicase strings as wor_ds - True - True - False - True - True - True - - - - 0 - 1 - - - - - Speak _numbers as digits - True - True - False - True - True - True - - - - 0 - 2 - - - - - - - - - - - - True - False - Global Voice Settings - - - - - - - - 1 - 0 - - - - - 2 - - - - - True - False - Voice - - - 2 - False - - - - - True - False - 12 - 10 - 10 - - - _Enable speech - True - True - False - True - True - True - - - - 0 - 0 - - - - - True - False - vertical - 50 - 20 - - - True - False - 20 - 20 - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - Brie_f - True - True - False - True - True - True - - - - 0 - 0 - - - - - Ver_bose - True - True - False - True - True - speechBriefButton - - - - 0 - 1 - - - - - - - - - True - False - Verbosity - - - - - - - - 0 - 0 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - _None - True - True - False - True - True - True - - - - 0 - 0 - - - - - So_me - True - True - False - True - True - noneButton - - - - 0 - 1 - - - - - M_ost - True - True - False - True - True - noneButton - - - - 0 - 2 - - - - - _All - True - True - False - True - True - noneButton - - - - 0 - 3 - - - - - - - - - True - False - Punctuation Level - - - - - - - - 0 - 1 - - - - - 0 - 0 - - - - - True - False - 20 - 10 - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - Only speak displayed text - True - True - False - True - True - True - - - - 0 - 0 - - - - - True - False - - - Speak blank lines - True - True - False - True - True - True - - - - 0 - 0 - - - - - Spea_k object mnemonics - True - True - False - True - True - True - - - - 0 - 3 - - - - - Speak child p_osition - True - True - False - True - True - True - - - - 0 - 4 - - - - - Speak tutorial messages - True - True - False - True - True - True - - - - 0 - 5 - - - - - _System messages are detailed - True - True - False - True - 0 - True - True - - - - 0 - 7 - - - - - S_peak colors as names - True - True - False - True - 0 - True - True - - - - 0 - 8 - - - - - Announce block_quotes during navigation - True - True - False - True - 0 - True - True - - - - 0 - 9 - - - - - Announce _lists during navigation - True - True - False - True - 0 - True - True - - - - 0 - 12 - - - - - Announce _tables during navigation - True - True - False - True - 0 - True - True - - - - 0 - 14 - - - - - Speak _misspelled-word indicator - True - True - False - True - 0 - True - True - - - - 0 - 2 - - - - - Announce _panels during navigation - True - True - False - True - 0 - True - True - - - - 0 - 13 - - - - - Announce land_marks during navigation - True - True - False - True - 0 - True - True - - - - 0 - 11 - - - - - Announce _forms during navigation - True - True - False - True - 0 - True - True - - - - 0 - 10 - - - - - Speak _description - True - True - False - True - 0 - True - True - - - - 0 - 6 - - - - - 0 - 1 - - - - - Speak full row in sp_readsheets - True - True - False - True - 0 - True - True - - - - 0 - 4 - - - - - Speak full row in _document tables - True - True - False - True - 0 - True - True - - - - 0 - 3 - - - - - Speak full row in _GUI tables - True - True - False - True - 0 - True - True - - - - 0 - 2 - - - - - - - - - True - False - Spoken Context - - - - - - - - 0 - 0 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 6 - - - Report indentation chan_ges - True - True - False - True - True - - - - 0 - 0 - - - - - True - False - 4 - 24 - - - _Speech - True - True - False - True - True - - - - 0 - 0 - - - - - _Beeps - True - True - False - True - True - indentationSpeechButton - - - - 0 - 1 - - - - - Speech _and beeps - True - True - False - True - True - indentationSpeechButton - - - - 0 - 2 - - - - - 0 - 1 - - - - - - - - - True - False - Indentation - - - - - - - - 0 - 1 - - - - - 1 - 0 - - - - - 0 - 1 - - - - - 3 - - - - - True - False - Speech - - - 3 - False - - - - - True - False - 12 - 10 - 10 - - - True - False - - - Enable Braille _support - True - True - False - True - True - True - - - - 0 - 0 - - - - - 0 - 0 - - - - - True - False - 10 - 10 - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - _Abbreviated role names - True - True - False - True - True - - - - 0 - 1 - - - - - Disable _end of line symbol - True - True - False - True - True - - - - 0 - 0 - - - - - True - False - 20 - 20 - - - True - False - 0.40999999642372131 - Contraction _Table: - True - contractionTableCombo - - - - - - 0 - 0 - - - - - True - False - - - - 1 - 0 - - - - - 0 - 4 - - - - - _Enable Contracted Braille - True - True - False - True - True - - - - 0 - 3 - - - - - Enable _word wrap - True - True - False - True - True - - - - 0 - 2 - - - - - - - - - True - False - Display Settings - - - - - - - - 0 - 0 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - Brie_f - True - True - False - True - True - True - - - - 0 - 0 - - - - - Ver_bose - True - True - False - True - True - brailleBriefButton - - - - 0 - 1 - - - - - - - - - True - False - Verbosity - - - - - - - - 0 - 1 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 20 - - - _None - True - True - False - True - True - True - - - - 0 - 0 - - - - - Dot _7 - True - True - False - True - True - brailleSelectionNoneButton - - - - 0 - 1 - - - - - Dot _8 - True - True - False - True - True - brailleSelectionNoneButton - - - - 1 - 0 - - - - - Dots 7 an_d 8 - True - True - False - True - True - brailleSelectionNoneButton - - - - 1 - 1 - - - - - - - - - True - False - Selection Indicator - - - - - - - - 0 - 2 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 20 - - - _None - True - True - False - True - True - True - - - - 0 - 0 - - - - - Dot _7 - True - True - False - True - True - brailleLinkNoneButton - - - - 0 - 1 - - - - - Dot _8 - True - True - False - True - True - brailleLinkNoneButton - - - - 1 - 0 - - - - - Dots 7 an_d 8 - True - True - False - True - True - brailleLinkNoneButton - - - - 1 - 1 - - - - - - - - - True - False - Hyperlink Indicator - - - - - - - - 0 - 3 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - - - Enable flash _messages - True - True - False - True - 0 - True - True - - - - 0 - 0 - - - - - True - False - - - True - False - D_uration (secs): - True - brailleFlashTimeSpinButton - 0 - - - 0 - 0 - - - - - True - True - ● - brailleFlashTimeAdjustment - 1 - True - 5 - - - - 1 - 0 - - - - - 0 - 3 - - - - - Messages are _persistent - True - True - False - True - 0 - True - True - - - - 0 - 2 - - - - - Messages are _detailed - True - True - False - True - 0 - True - True - - - - 0 - 1 - - - - - - - - - True - False - Flash Message Settings - end - - - - - - - - 1 - 0 - - - - - - - - - - - - - - 0 - 1 - - - - - 4 - - - - - True - False - Braille - - - 4 - False - - - - - True - False - 12 - - - Enable _key echo - True - True - False - True - True - - - - 0 - 0 - - - - - True - False - 25 - - - True - False - - - Enable _alphabetic keys - True - True - False - True - True - - - - 0 - 0 - - - - - Enable n_umeric keys - True - True - False - True - True - - - - 0 - 1 - - - - - Enable _punctuation keys - True - True - False - True - True - - - - 0 - 2 - - - - - Enable _space - True - True - False - True - True - - - - 0 - 3 - - - - - Enable _modifier keys - True - True - False - True - True - - - - 0 - 4 - - - - - Enable _function keys - True - True - False - True - True - - - - 0 - 5 - - - - - Enable ac_tion keys - True - True - False - True - True - - - - 0 - 6 - - - - - Enable _navigation keys - True - True - False - True - True - - - - 0 - 7 - - - - - Enable non-spacing _diacritical keys - True - True - False - True - True - - - - 0 - 8 - - - - - - - - - - 0 - 1 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 10 - 8 - - - Use c_ustom echo voice settings - True - True - False - True - True - - - - 0 - 0 - 2 - - - - - Use custom _speech-dispatcher module for echo - True - True - False - True - True - - - - 0 - 1 - 2 - - - - - True - False - 1 - Echo _module: - True - echoSpeechServers - - - - - - 0 - 2 - - - - - True - False - - - - - - - 1 - 2 - - - - - True - False - 1 - Echo _voice: - True - echoSpeechFamilies - - - - - - 0 - 3 - - - - - True - False - - - - - - - 1 - 3 - - - - - True - False - 1 - Echo ra_te: - True - echoRateScale - - - - - - 0 - 4 - - - - - True - True - echoRateAdjustment - 0 - 0 - right - - - - 1 - 4 - - - - - True - False - 1 - Echo pi_tch: - True - echoPitchScale - - - - - - 0 - 5 - - - - - True - True - echoPitchAdjustment - 1 - right - - - - 1 - 5 - - - - - True - False - 1 - Echo vo_lume: - True - echoVolumeScale - - - - - - 0 - 6 - - - - - True - True - echoVolumeAdjustment - 1 - right - - - - 1 - 6 - - - - - Use custom voice for _key echo - True - True - False - True - True - - - - 0 - 7 - 2 - - - - - Use custom voice for _character echo - True - True - False - True - True - - - - 0 - 8 - 2 - - - - - Use custom voice for _word echo - True - True - False - True - True - - - - 0 - 9 - 2 - - - - - Use custom voice for _sentence echo - True - True - False - True - True - - - - 0 - 10 - 2 - - - - - - - - - True - False - Echo Voice - - - - - - - - 0 - 2 - - - - - Enable echo by cha_racter - True - True - False - True - True - - - - 0 - 3 - - - - - Enable echo by _word - True - True - False - True - True - - - - 0 - 4 - - - - - Enable echo by _sentence - True - True - False - True - True - - - - 0 - 5 - - - - - 5 - - - - - True - False - Echo - - - 5 - False - - - - - True - False - 12 - 10 - 10 - - - True - False - 10 - 10 - - - True - False - Screen Reader _Modifier Key(s): - True - cthulhuModifierComboBox - - - - - - 0 - 0 - - - - - True - False - model8 - - - - - 0 - - - - - 1 - 0 - - - - - 0 - 0 - - - - - True - True - True - True - in - - - True - True - True - - - - - - - - 0 - 1 - - - - - 6 - - - - - True - False - Key Bindings - - - 6 - False - - - - - True - False - - - True - False - True - True - 5 - 0 - none - - - True - False - 12 - - - True - True - 5 - in - - - True - True - True - - - - - - - - - - - - True - False - Pronunciation Dictionary - - - - - - - - 0 - 0 - - - - - True - False - - - _New entry - True - True - True - 5 - True - - - - 0 - 0 - - - - - _Delete - True - True - True - 5 - True - - - - 1 - 0 - - - - - 0 - 1 - - - - - 7 - - - - - True - False - Pronunciation - - - 7 - False - - - - - True - False - True - True - - - True - False - True - True - 5 - 0 - none - - - True - False - 12 - - - True - False - True - True - - - True - False - - - _Speak all - True - True - 5 - True - - - - 0 - 0 - - - - - Speak _none - True - True - 5 - True - - - - 1 - 0 - - - - - _Reset - True - True - True - 5 - True - - - - 2 - 0 - - - - - 0 - 1 - - - - - True - True - True - True - 5 - in - - - True - True - True - - - - - - - - 0 - 0 - - - - - - - - - True - False - Text attributes - - - - - - - - 0 - 0 - - - - - True - False - - - True - False - 5 - 0 - none - - - True - False - 12 - - - True - False - - - Move to _bottom - True - True - True - 5 - True - - - - 0 - 3 - - - - - Move _down one - True - True - True - 5 - True - - - - 0 - 2 - - - - - Move _up one - True - True - True - 5 - True - - - - 0 - 1 - - - - - Move to _top - True - True - True - 5 - True - - - - 0 - 0 - - - - - - - - - True - False - Adjust selected attribute - - - - - - - - 0 - 0 - - - - - True - False - 5 - 0 - none - - - True - False - 12 - - - True - False - - - _None - True - True - False - True - True - True - - - - 0 - 0 - - - - - Dot _7 - True - True - False - True - True - textBrailleNoneButton - - - - 0 - 1 - - - - - Dot _8 - True - True - False - True - True - textBrailleNoneButton - - - - 0 - 2 - - - - - Dots 7 an_d 8 - True - True - False - True - True - textBrailleNoneButton - - - - 0 - 3 - - - - - - - - - True - False - Braille Indicator - - - - - - - - 0 - 1 - - - - - 1 - 0 - - - - - 8 - - - - - True - False - Text Attributes - - - 8 - False - - - - - True - False - 12 - 12 - 12 - 12 - 6 - 12 - - - Enable AI Assistant - True - True - False - True - True - - - - 0 - 0 - 2 - - - - - True - False - start - _Provider: - True - aiProviderCombo - - - 0 - 1 - - - - - True - False - True - - Claude Code (CLI) - Codex (CLI) - Gemini (Google) - Ollama (Local - Free) - - - - - 1 - 1 - - - - - True - False - start - API _Key File: - True - aiApiKeyEntry - - - 0 - 2 - - - - - True - False - 6 - - - True - True - True - Path to API key file - - - - True - True - 0 - - - - - Get _Claude API Key - True - True - True - True - Open browser to get Claude API key and save automatically - - - - False - False - 1 - - - - - 1 - 2 - - - - - Require confirmation before AI actions - True - True - False - True - True - True - - - - 0 - 3 - 2 - - - - - True - False - start - Ollama _Model: - True - aiOllamaModelEntry - - - 0 - 4 - - - - - True - True - True - llama3.2-vision - Model name for Ollama (e.g., llama3.2-vision) - - - - 1 - 4 - - - - - True - False - start - Ollama _Endpoint: - True - aiOllamaEndpointEntry - - - 0 - 5 - - - - - True - True - True - http://localhost:11434 - Ollama API endpoint URL (e.g., http://192.168.1.100:11434) - - - - 1 - 5 - - - - - True - False - start - Screenshot _Quality: - True - aiScreenshotQualityCombo - - - 0 - 6 - - - - - True - False - True - 1 - - Low - Medium - High - - - - - 1 - 6 - - - - - 9 - - - - - True - False - AI Assistant - - - 9 - False - - - - - True - False - 12 - 12 - 12 - 12 - 6 - 12 - - - True - False - start - _Language Code: - True - ocrLanguageEntry - - - 0 - 0 - - - - - True - True - eng - - - - 1 - 0 - - - - - True - False - start - _Scale Factor: - True - ocrScaleSpinButton - - - 0 - 1 - - - - - True - True - ocrScaleAdjustment - 3 - - - - 1 - 1 - - - - - _Grayscale Image - True - True - False - True - True - - - - 0 - 2 - 2 - - - - - _Invert Image - True - True - False - True - True - - - - 0 - 3 - 2 - - - - - _Black and White Image - True - True - False - True - True - - - - 0 - 4 - 2 - - - - - True - False - start - Black/White _Threshold: - True - ocrBlackWhiteValueSpinButton - - - 0 - 5 - - - - - True - True - ocrBlackWhiteValueAdjustment - 200 - - - - 1 - 5 - - - - - _Analyze Colors - True - True - False - True - True - - - - 0 - 6 - 2 - - - - - Copy Results to _Clipboard - True - True - False - True - True - - - - 0 - 7 - 2 - - - - - 10 - - - - - True - False - OCR - - - 10 - False - - - - - True - True - 3 - 1 - - - - - - helpButton - applyButton - cancelButton - okButton - - - diff --git a/src/cthulhu/cthulhu.py b/src/cthulhu/cthulhu.py deleted file mode 100644 index ec7d8e8..0000000 --- a/src/cthulhu/cthulhu.py +++ /dev/null @@ -1,1138 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""The main module for the Cthulhu screen reader.""" - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2011 The Cthulhu Team" \ - "Copyright (c) 2012 Igalia, S.L." -__license__ = "LGPL" - -import faulthandler -from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union - -from . import dbus_service - -if TYPE_CHECKING: - from types import FrameType - from gi.repository import Gtk - - from .settings_manager import SettingsManager - from .script_manager import ScriptManager - from .plugin_system_manager import PluginSystemManager - from .input_event import InputEvent - from .input_event_manager import InputEventManager - from .event_manager import EventManager - from .compositor_state_adapter import CompositorStateAdapter - from .signal_manager import SignalManager - from .dynamic_api_manager import DynamicApiManager - from .speech import Speech - from .braille import Braille - from .script import Script - -class APIHelper: - """Helper class for plugin API interactions, including keybindings.""" - - def __init__(self, app: Cthulhu) -> None: - """Initialize the APIHelper. - - Arguments: - - app: the Cthulhu application - """ - self.app: Cthulhu = app - self._gestureBindings: Dict[Optional[str], List[Any]] = {} - - def registerGestureByString( - self, - function: Callable[..., Any], - name: str, - gestureString: str, - inputEventType: str = 'default', - normalizer: str = 'cthulhu', - learnModeEnabled: bool = True, - contextName: Optional[str] = None, - globalBinding: bool = False - ) -> Optional[Any]: - """Register a gesture by string.""" - import logging - logger = logging.getLogger(__name__) - - logger.info(f"=== APIHelper.registerGestureByString called ===") - logger.info(f"gestureString: {gestureString}") - logger.info(f"name: {name}") - logger.info(f"contextName: {contextName}") - - if not gestureString.startswith("kb:"): - logger.warning(f"Gesture string doesn't start with 'kb:': {gestureString}") - return None - - # Extract the key portion from the gesture string - key = gestureString.split(":", 1)[1] - logger.info(f"Extracted key: {key}") - - # Handle Cthulhu modifier specially - if "cthulhu+" in key.lower(): - from . import keybindings - key_parts = key.lower().split("+") - logger.info(f"Key parts: {key_parts}") - - # Start with the base Cthulhu modifier - modifiers = keybindings.CTHULHU_MODIFIER_MASK - - # Extract the final key (without modifiers) - final_key = key_parts[-1] - logger.info(f"Final key: {final_key}") - - # Check for additional modifiers and combine them properly - if "control" in key_parts and "shift" in key_parts: - # Combine Cthulhu + Control + Shift modifiers - modifiers = (keybindings.CTHULHU_MODIFIER_MASK | - keybindings.CTRL_MODIFIER_MASK | - keybindings.SHIFT_MODIFIER_MASK) - logger.info(f"Using CTHULHU+CTRL+SHIFT combined mask: {modifiers}") - elif "control" in key_parts: - # Use the pre-defined Cthulhu+Control mask - modifiers = keybindings.CTHULHU_CTRL_MODIFIER_MASK - logger.info(f"Using CTHULHU_CTRL_MODIFIER_MASK: {modifiers}") - elif "shift" in key_parts: - # Use the pre-defined combined mask rather than trying to OR them - modifiers = keybindings.CTHULHU_SHIFT_MODIFIER_MASK - logger.info(f"Using CTHULHU_SHIFT_MODIFIER_MASK: {modifiers}") - else: - logger.info(f"Using CTHULHU_MODIFIER_MASK: {modifiers}") - - # Create a keybinding handler - class GestureHandler: - def __init__(self, function: Callable[..., Any], description: str, learnModeEnabled: bool = True) -> None: - self.function: Callable[..., Any] = function - self.description: str = description - self.learnModeEnabled: bool = learnModeEnabled - - def __call__(self, script: Any, inputEvent: Any) -> bool: - try: - logger.info(f"=== Plugin keybinding handler called! ===") - return function(script, inputEvent) - except Exception as e: - import logging - logging.getLogger(__name__).error(f"Error in keybinding handler: {e}") - return True - - handler = GestureHandler(function, name, learnModeEnabled) - logger.info(f"Created handler: {handler}") - - # Create the binding object regardless of whether there's an active script - # This allows plugins to define bindings that will work when a script becomes active - from . import cthulhu_state - from . import keybindings - binding = keybindings.KeyBinding( - final_key, - keybindings.defaultModifierMask, - modifiers, - handler) - - logger.info(f"Created binding: keysym={binding.keysymstring}, modifiers={binding.modifiers}, mask={binding.modifier_mask}") - - # Store binding for later reference - if contextName not in self._gestureBindings: - self._gestureBindings[contextName] = [] - self._gestureBindings[contextName].append(binding) - logger.info(f"Stored binding in context '{contextName}'") - - plugin_manager = None - if contextName and self.app: - try: - plugin_manager = self.app.getPluginSystemManager() - except Exception: - plugin_manager = None - if plugin_manager: - plugin_manager.add_keybinding(contextName, binding, global_binding=globalBinding) - - if contextName and self.app and plugin_manager: - if not globalBinding and cthulhu_state.activeScript: - plugin_manager.activate_keybindings_for_plugin(contextName) - elif not globalBinding: - debug.printMessage(debug.LEVEL_INFO, "No active script available - binding stored for later registration", True) - else: - if cthulhu_state.activeScript and not globalBinding: - logger.info(f"Adding binding to active script: {cthulhu_state.activeScript}") - bindings = cthulhu_state.activeScript.getKeyBindings() - bindings.add(binding) - - # Register key grab at the system level - grab_ids = addKeyGrab(binding) - logger.info(f"Key grab IDs: {grab_ids}") - - # For later removal - if grab_ids: - binding._grab_ids = grab_ids - else: - debug.printMessage(debug.LEVEL_INFO, "No active script available - binding stored for later registration", True) - - debug.printMessage(debug.LEVEL_INFO, f"Created binding: {binding.keysymstring} with modifiers {binding.modifiers}", True) - logger.info("=== APIHelper.registerGestureByString completed ===") - return binding - else: - logger.warning(f"Key doesn't contain 'cthulhu+': {key}") - - return None - - def unregisterShortcut(self, binding: Any, contextName: Optional[str] = None) -> None: - """Unregister a previously registered shortcut. - - Arguments: - - binding: the binding to unregister - - contextName: the context for this gesture - """ - removed_via_plugin_manager: bool = False - if contextName and self.app: - try: - plugin_manager = self.app.getPluginSystemManager() - except Exception: - plugin_manager = None - if plugin_manager: - plugin_manager.remove_keybinding(contextName, binding) - removed_via_plugin_manager = True - if not removed_via_plugin_manager: - # Remove from script's keybindings - from . import cthulhu_state - if cthulhu_state.activeScript: - bindings = cthulhu_state.activeScript.getKeyBindings() - bindings.remove(binding) - - # Remove key grab at system level - if hasattr(binding, '_grab_ids'): - for grab_id in binding._grab_ids: - self.app.removeKeyGrab(grab_id) - - # Remove from tracking - if contextName in self._gestureBindings: - if binding in self._gestureBindings[contextName]: - self._gestureBindings[contextName].remove(binding) - - -import gi -import importlib -import os -import signal -import sys - -gi.require_version("Atspi", "2.0") -gi.require_version("Gdk", "3.0") -from gi.repository import Atspi -from gi.repository import Gdk -from gi.repository import GObject - -from . import braille -from . import debug -from . import event_manager -from . import compositor_state_adapter -from . import keybindings -from . import learn_mode_presenter -from . import logger -from . import mako_notification_monitor -from . import screen_lock_monitor -from . import messages -from . import notification_presenter -from . import focus_manager -from . import cthulhu_modifier_manager -from . import cthulhu_state -from . import cthulhu_platform -from . import script_manager -from . import settings -from . import settings_manager -from . import speech -from . import sound -from . import sound_theme_manager -from . import mouse_review -from .ax_object import AXObject -from .ax_utilities import AXUtilities -# Lazy import to avoid circular dependency -# from .input_event import BrailleEvent -from . import cmdnames -from . import plugin_system_manager # This will now be your pluggy-based implementation -from . import guilabels -from . import acss -from . import text_attribute_names -from . import speechserver -from . import input_event -from . import input_event_manager -from . import pronunciation_dict -from . import cthulhu_gtkbuilder -from . import signal_manager -from . import dynamic_api_manager -from . import translation_manager -from . import resource_manager - - -# Old global variables removed - now using cthulhuApp.* instead - -EXIT_CODE_HANG: int = 50 - -# The user-settings module (see loadUserSettings). -# -_userSettings: Optional[Any] = None - -######################################################################## -# # -# METHODS TO HANDLE APPLICATION LIST AND FOCUSED OBJECTS # -# # -######################################################################## - -CARET_TRACKING: str = "caret-tracking" -FOCUS_TRACKING: str = "focus-tracking" -FLAT_REVIEW: str = "flat-review" -MOUSE_REVIEW: str = "mouse-review" -OBJECT_NAVIGATOR: str = "object-navigator" -SAY_ALL: str = "say-all" - -def getActiveModeAndObjectOfInterest() -> tuple[str, Any]: - return focus_manager.get_manager().get_active_mode_and_object_of_interest() - -def emitRegionChanged(obj: Any, startOffset: Optional[int] = None, endOffset: Optional[int] = None, mode: Optional[str] = None) -> None: - """Notifies interested clients that the current region of interest has changed.""" - focus_manager.get_manager().emit_region_changed(obj, startOffset, endOffset, mode) - -def setActiveWindow(frame: Any, app: Optional[Any] = None, alsoSetLocusOfFocus: bool = False, notifyScript: bool = False) -> None: - real_app: Optional[Any] = app - real_frame: Any = frame - if frame is not None and hasattr(AXObject, "find_real_app_and_window_for"): - real_app, real_frame = AXObject.find_real_app_and_window_for(frame, app) - focus_manager.get_manager().set_active_window( - real_frame, real_app, set_window_as_focus=alsoSetLocusOfFocus, notify_script=notifyScript) - -def setLocusOfFocus(event: Optional[Any], obj: Any, notifyScript: bool = True, force: bool = False) -> None: - """Sets the locus of focus (i.e., the object with visual focus) and - notifies the script of the change should the script wish to present - the change to the user. - - Arguments: - - event: if not None, the Event that caused this to happen - - obj: the Accessible with the new locus of focus. - - notifyScript: if True, propagate this event - - force: if True, don't worry if this is the same object as the - current locusOfFocus - """ - - focus_manager.get_manager().set_locus_of_focus( - event, obj, notify_script=notifyScript, force=force) - -######################################################################## -# # -# METHODS FOR PRE-PROCESSING AND MASSAGING BRAILLE EVENTS. # -# # -######################################################################## - -def _processBrailleEvent(event: Any) -> bool: - """Called whenever a key is pressed on the Braille display. - - Arguments: - - command: the BrlAPI event for the key that was pressed. - - Returns True if the event was consumed; otherwise False - """ - - consumed: bool = False - - # Braille key presses always interrupt speech. - # - # Lazy import to avoid circular dependency - from .input_event import BrailleEvent - event = BrailleEvent(event) - if event.event['command'] not in braille.dontInteruptSpeechKeys: - speech.stop() - cthulhu_state.lastInputEvent = event - - try: - consumed = cthulhuApp.eventManager.processBrailleEvent(event) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - # TODO - JD: Is this still possible? - if not consumed and learn_mode_presenter.getPresenter().is_active(): - consumed = True - - return consumed - -######################################################################## -# # -# METHODS FOR HANDLING INITIALIZATION, SHUTDOWN, AND USE. # -# # -######################################################################## - -def deviceChangeHandler(deviceManager: Any, device: Any) -> None: - """New keyboards being plugged in stomp on our changes to the keymappings, - so we have to re-apply""" - source = device.get_source() - if source == Gdk.InputSource.KEYBOARD: - msg: str = "CTHULHU: Keyboard change detected, re-creating the xmodmap" - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu_modifier_manager.getManager().refreshCthulhuModifiers("Keyboard change detected.") - -def loadUserSettings(script: Optional[Any] = None, inputEvent: Optional[Any] = None, skipReloadMessage: bool = False) -> bool: - """Loads (and reloads) the user settings module, reinitializing - things such as speech if necessary. - - Returns True to indicate the input event has been consumed. - """ - - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Loading User Settings', True) - debug.print_startup_timing("load user settings start") - - global _userSettings - - # Shutdown the output drivers and give them a chance to die. - - with debug.startup_timing("output driver shutdown"): - player = sound.getPlayer() - player.shutdown() - speech.shutdown() - braille.shutdown() - - with debug.startup_timing("script manager deactivate for settings load"): - cthulhuApp.scriptManager.deactivate() - cthulhuApp.getSignalManager().emitSignal('load-setting-begin') - - reloaded: bool = False - with debug.startup_timing("settings profile load"): - if _userSettings: - _profile = cthulhuApp.settingsManager.getSetting('activeProfile')[1] - try: - _userSettings = cthulhuApp.settingsManager.getGeneralSettings(_profile) - cthulhuApp.settingsManager.setProfile(_profile) - reloaded = True - except ImportError: - debug.printException(debug.LEVEL_INFO) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - else: - _profile = cthulhuApp.settingsManager.profile - try: - _userSettings = cthulhuApp.settingsManager.getGeneralSettings(_profile) - except ImportError: - debug.printException(debug.LEVEL_INFO) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - if not script: - script = cthulhuApp.scriptManager.get_default_script() - - with debug.startup_timing("app settings load"): - cthulhuApp.settingsManager.loadAppSettings(script) - - if cthulhuApp.settingsManager.getSetting('enableSpeech'): - msg = 'CTHULHU: About to enable speech' - debug.printMessage(debug.LEVEL_INFO, msg, True) - with debug.startup_timing("speech initialization"): - try: - speech.init() - if reloaded and not skipReloadMessage: - script.speakMessage(messages.SETTINGS_RELOADED) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - else: - msg = 'CTHULHU: Speech is not enabled in settings' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if cthulhuApp.settingsManager.getSetting('enableBraille'): - msg = 'CTHULHU: About to enable braille' - debug.printMessage(debug.LEVEL_INFO, msg, True) - with debug.startup_timing("braille initialization"): - try: - braille.init(_processBrailleEvent) - except Exception: - debug.printException(debug.LEVEL_WARNING) - msg = 'CTHULHU: Could not initialize connection to braille.' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - else: - msg = 'CTHULHU: Braille is not enabled in settings' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - - with debug.startup_timing("mouse review update"): - if cthulhuApp.settingsManager.getSetting('enableMouseReview'): - mouse_review.getReviewer().activate() - else: - mouse_review.getReviewer().deactivate() - - if cthulhuApp.settingsManager.getSetting('enableSound'): - with debug.startup_timing("sound initialization"): - player.init() - - with debug.startup_timing("cthulhu modifier refresh"): - cthulhu_modifier_manager.getManager().refreshCthulhuModifiers("Loading user settings.") - - # Activate core systems FIRST before loading plugins - with debug.startup_timing("core manager activation"): - cthulhuApp.compositorStateAdapter.activate() - cthulhuApp.scriptManager.activate() - cthulhuApp.eventManager.activate() - - cthulhuApp.getSignalManager().emitSignal('load-setting-begin') - - # NOW load plugins after script system is ready - activePluginsSetting = cthulhuApp.settingsManager.getSetting('activePlugins') or [] - debug.printMessage( - debug.LEVEL_INFO, - f"CTHULHU: Active plugins defaults: {settings.activePlugins}", - True, - ) - debug.printMessage( - debug.LEVEL_INFO, - f"CTHULHU: Active plugins from settings manager: {activePluginsSetting}", - True, - ) - activePlugins = list(activePluginsSetting) - debug.printMessage(debug.LEVEL_INFO, f'CTHULHU: Loading active plugins: {activePlugins}', True) - with debug.startup_timing("active plugin load"): - cthulhuApp.getPluginSystemManager().setActivePlugins(activePlugins) - - # Refresh keybindings to include plugin bindings (after script manager is active) - with debug.startup_timing("plugin keybinding refresh"): - cthulhuApp.getPluginSystemManager().refresh_active_script_keybindings() - - cthulhuApp.getSignalManager().emitSignal('load-setting-completed') - - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: User Settings Loaded', True) - debug.print_startup_timing("load user settings complete") - - return True - -def _showPreferencesUI(script: Any, prefs: dict[str, Any]) -> None: - if cthulhu_state.cthulhuOS: - cthulhu_state.cthulhuOS.showGUI() - return - - try: - module = importlib.import_module('.cthulhu_gui_prefs', 'cthulhu') - except Exception: - debug.printException(debug.LEVEL_SEVERE) - return - - uiFile: str = os.path.join(cthulhu_platform.datadir, - cthulhu_platform.package, - "ui", - "cthulhu-setup.ui") - - cthulhu_state.cthulhuOS = module.CthulhuSetupGUI(uiFile, "cthulhuSetupWindow", prefs) - cthulhu_state.cthulhuOS.init(script) - cthulhu_state.cthulhuOS.showGUI() - -def showAppPreferencesGUI(script: Optional[Any] = None, inputEvent: Optional[Any] = None) -> bool: - """Displays the user interface to configure the settings for a - specific applications within Cthulhu and set up those app-specific - user preferences using a GUI. - - Returns True to indicate the input event has been consumed. - """ - - prefs: dict[str, Any] = {} - for key in settings.userCustomizableSettings: - prefs[key] = cthulhuApp.settingsManager.getSetting(key) - - script = script or cthulhu_state.activeScript - _showPreferencesUI(script, prefs) - - return True - -def showPreferencesGUI(script: Optional[Any] = None, inputEvent: Optional[Any] = None) -> bool: - """Displays the user interface to configure Cthulhu and set up - user preferences using a GUI. - - Returns True to indicate the input event has been consumed. - """ - - prefs: dict[str, Any] = cthulhuApp.settingsManager.getGeneralSettings(cthulhuApp.settingsManager.profile) - script = cthulhuApp.scriptManager.get_default_script() - _showPreferencesUI(script, prefs) - - return True - -def addKeyGrab(binding: Any) -> list[int]: - """ Add a key grab for the given key binding.""" - - manager = input_event_manager.get_manager() - return manager.add_grabs_for_keybinding(binding) - -def removeKeyGrab(id: int) -> None: - """ Remove the key grab for the given key binding.""" - - manager = input_event_manager.get_manager() - manager.remove_grab_by_id(id) - -def mapModifier(keycode: int) -> int: - manager = input_event_manager.get_manager() - return manager.map_keycode_to_modifier(keycode) - -def quitCthulhu(script: Optional[Any] = None, inputEvent: Optional[Any] = None) -> bool: - """Quit Cthulhu. Check if the user wants to confirm this action. - If so, show the confirmation GUI otherwise just shutdown. - - Returns True to indicate the input event has been consumed. - """ - - shutdown() - - return True - -def showFindGUI(script: Optional[Any] = None, inputEvent: Optional[Any] = None) -> None: - """Displays the user interface to perform an Cthulhu Find. - - Returns True to indicate the input event has been consumed. - """ - - try: - module = importlib.import_module('.cthulhu_gui_find', 'cthulhu') - module.showFindUI() - except Exception: - debug.printException(debug.LEVEL_SEVERE) - -# If True, this module has been initialized. -# -_initialized: bool = False - -def init() -> bool: - """Initialize the cthulhu module, which initializes the speech and braille - modules. Also builds up the application list, registers for AT-SPI events, - and creates scripts for all known applications. - - Returns True if the initialization procedure has run, or False if this - module has already been initialized. - """ - - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Initializing', True) - debug.print_startup_timing("cthulhu init start") - - global _initialized - - if _initialized and cthulhuApp.settingsManager.isScreenReaderServiceEnabled(): - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Already initialized', True) - return False - - # Do not hang on initialization if we can help it. - # - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.signal(signal.SIGALRM, settings.timeoutCallback) - signal.alarm(settings.timeoutTime) - - # Activate settings manager before loading user settings - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Activating settings manager', True) - with debug.startup_timing("settings manager init activation"): - cthulhuApp.settingsManager.activate() - - with debug.startup_timing("load user settings"): - loadUserSettings() - - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.alarm(0) - - _initialized = True - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Initialized', True) - debug.print_startup_timing("cthulhu init complete") - - return True - -def _start_dbus_service() -> bool: - """Starts the D-Bus remote controller service in an idle callback.""" - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Starting D-Bus remote controller', True) - try: - # Start the D-Bus service - dbus_service.get_remote_controller().start() - - # Register speech and verbosity manager - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Registering SpeechManager D-Bus module', True) - from . import speech_and_verbosity_manager - speech_manager = speech_and_verbosity_manager.getManager() - dbus_service.get_remote_controller().register_decorated_module("SpeechManager", speech_manager) - - # Register typing echo presenter - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Registering TypingEchoManager D-Bus module', True) - from . import typing_echo_presenter - typing_echo_manager = typing_echo_presenter.getManager() - dbus_service.get_remote_controller().register_decorated_module("TypingEchoManager", typing_echo_manager) - - # Register plugin system manager - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Registering PluginSystemManager D-Bus module', True) - plugin_manager = cthulhuApp.getPluginSystemManager() - dbus_service.get_remote_controller().register_decorated_module("PluginSystemManager", plugin_manager) - - except Exception as e: - msg: str = f"CTHULHU: Failed to start D-Bus service: {e}" - debug.printMessage(debug.LEVEL_SEVERE, msg, True) - return False # Remove the idle callback - -def start() -> None: - """Starts Cthulhu.""" - - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Starting', True) - debug.print_startup_timing("cthulhu start begin") - - if not _initialized: - init() - - # Do not hang on startup if we can help it. - # - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.signal(signal.SIGALRM, settings.timeoutCallback) - signal.alarm(settings.timeoutTime) - - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.alarm(0) - - # Event handlers for input devices being plugged in/unplugged. - # Used to re-create the Xmodmap when a new keyboard is plugged in. - # Necessary, because plugging in a new keyboard resets the Xmodmap - # and stomps our changes - with debug.startup_timing("input device monitor setup"): - display = Gdk.Display.get_default() - devmanager = display.get_device_manager() - devmanager.connect("device-added", deviceChangeHandler) - devmanager.connect("device-removed", deviceChangeHandler) - - with debug.startup_timing("desktop startup notification"): - Gdk.notify_startup_complete() - msg = 'CTHULHU: Startup complete notification made' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Starting Atspi main event loop', True) - - # Start D-Bus remote controller service after ATSPI is ready - with debug.startup_timing("startup idle services"): - cthulhuApp.getMakoNotificationMonitor().start() - cthulhuApp.getScreenLockMonitor().start() - GObject.idle_add(_start_dbus_service) - - debug.print_startup_timing("AT-SPI main loop start") - Atspi.event_main() - -def die(exitCode: int = 1) -> None: - pid: int = os.getpid() - if exitCode == EXIT_CODE_HANG: - # Someting is hung and we wish to abort. - os.kill(pid, signal.SIGKILL) - return - - shutdown() - sys.exit(exitCode) - if exitCode > 1: - os.kill(pid, signal.SIGTERM) - -def timeout(signum: Optional[int] = None, frame: Optional[FrameType] = None) -> None: - msg: str = 'TIMEOUT: something has hung. Aborting.' - debug.printMessage(debug.LEVEL_SEVERE, msg, True) - debug.printStack(debug.LEVEL_SEVERE) - debug.examineProcesses(force=True) - die(EXIT_CODE_HANG) - -def shutdown(script: Optional[Any] = None, inputEvent: Optional[Any] = None) -> bool: - """Exits Cthulhu. Unregisters any event listeners and cleans up. - - Returns True if the shutdown procedure ran or False if this module - was never initialized. - """ - - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Shutting down', True) - - # Shutdown D-Bus remote controller service early - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Shutting down D-Bus remote controller', True) - dbus_service.get_remote_controller().shutdown() - - global _initialized - - if not _initialized: - return False - - # Try to say goodbye, but be defensive if something has hung. - # - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.signal(signal.SIGALRM, settings.timeoutCallback) - signal.alarm(settings.timeoutTime) - - if cthulhu_state.activeScript is not None: - cthulhu_state.activeScript.presentationInterrupt() - - cthulhuApp.getSignalManager().emitSignal('stop-application-completed') - sound_theme_manager.getManager().playStopSound(wait=True, timeoutSeconds=1) - cthulhuApp.getPluginSystemManager().unloadAllPlugins(ForceAllPlugins=True) - cthulhuApp.getScreenLockMonitor().stop() - cthulhuApp.getMakoNotificationMonitor().stop() - - # Deactivate the event manager first so that it clears its queue and will not - # accept new events. Then let the script manager unregister script event listeners. - cthulhuApp.compositorStateAdapter.deactivate() - cthulhuApp.eventManager.deactivate() - cthulhuApp.scriptManager.deactivate() - - # Shutdown all the other support. - # - if settings.enableSpeech: - speech.shutdown() - if settings.enableBraille: - braille.shutdown() - if settings.enableSound: - player = sound.getPlayer() - player.shutdown() - - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.alarm(0) - - _initialized = False - cthulhu_modifier_manager.getManager().unsetCthulhuModifiers("Shutting down.") - - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Quitting Atspi main event loop', True) - Atspi.event_quit() - debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Shutdown complete', True) - - return True - -exitCount: int = 0 - -def shutdownOnSignal(signum: int, frame: Optional[FrameType]) -> None: - global exitCount - - signalString: str = f'({signal.strsignal(signum)})' - msg: str = f"CTHULHU: Shutting down and exiting due to signal={signum} {signalString}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - # Well...we'll try to exit nicely, but if we keep getting called, - # something bad is happening, so just quit. - # - if exitCount: - die(signum) - else: - exitCount += 1 - - # Try to do a graceful shutdown if we can. - # - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.signal(signal.SIGALRM, settings.timeoutCallback) - signal.alarm(settings.timeoutTime) - - try: - if _initialized: - shutdown() - else: - # We always want to try to shutdown speech since the - # speech servers are very persistent about living. - # - speech.shutdown() - shutdown() - cleanExit: bool = True - except Exception: - cleanExit = False - - if settings.timeoutCallback and (settings.timeoutTime > 0): - signal.alarm(0) - - if not cleanExit: - die(EXIT_CODE_HANG) - -def crashOnSignal(signum: int, frame: Optional[FrameType]) -> None: - signalString: str = f'({signal.strsignal(signum)})' - msg: str = f"CTHULHU: Shutting down and exiting due to signal={signum} {signalString}" - debug.printMessage(debug.LEVEL_SEVERE, msg, True) - debug.printStack(debug.LEVEL_SEVERE) - cthulhu_modifier_manager.getManager().unsetCthulhuModifiers("Crashed") - sys.exit(1) - -def main() -> int: - """The main entry point for Cthulhu. The exit codes for Cthulhu will - loosely be based on signals, where the exit code will be the - signal used to terminate Cthulhu (if a signal was used). Otherwise, - an exit code of 0 means normal completion and an exit code of 50 - means Cthulhu exited because of a hang.""" - - msg: str = f"CTHULHU: Launching version {cthulhu_platform.version}" - if cthulhu_platform.revision: - msg += f" (rev {cthulhu_platform.revision})" - - sessionType: str = os.environ.get('XDG_SESSION_TYPE') or "" - sessionDesktop: str = os.environ.get('XDG_SESSION_DESKTOP') or "" - session: str = "%s %s".strip() % (sessionType, sessionDesktop) - if session: - msg += f" session: {session}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - debug.print_startup_timing("cthulhu main start") - - with debug.startup_timing("faulthandler setup"): - if debug.debugFile and os.path.exists(debug.debugFile.name): - faulthandler.enable(file=debug.debugFile, all_threads=True) - else: - faulthandler.enable(all_threads=False) - - # Method to call when we think something might be hung. - # - settings.timeoutCallback = timeout - - # Various signal handlers we want to listen for. - # - with debug.startup_timing("signal handler setup"): - signal.signal(signal.SIGHUP, shutdownOnSignal) - signal.signal(signal.SIGINT, shutdownOnSignal) - signal.signal(signal.SIGTERM, shutdownOnSignal) - signal.signal(signal.SIGQUIT, shutdownOnSignal) - signal.signal(signal.SIGSEGV, crashOnSignal) - - debug.printMessage(debug.LEVEL_INFO, "CTHULHU: Enabling accessibility (if needed).", True) - with debug.startup_timing("accessibility enable check"): - if not cthulhuApp.settingsManager.isAccessibilityEnabled(): - cthulhuApp.settingsManager.setAccessibility(True) - - debug.printMessage(debug.LEVEL_INFO, "CTHULHU: Initializing.", True) - with debug.startup_timing("cthulhu init"): - init() - debug.printMessage(debug.LEVEL_INFO, "CTHULHU: Initialized.", True) - - script = cthulhu_state.activeScript - with debug.startup_timing("startup sound"): - sound_theme_manager.getManager().playStartSound(wait=False) - soundFailureReason = sound.getSoundSystemFailureReason() - if soundFailureReason: - debug.printMessage( - debug.LEVEL_INFO, - f"CTHULHU: Startup sound failed. Continuing without sound. Reason: {soundFailureReason}", - True - ) - with debug.startup_timing("startup focus recovery"): - cthulhuApp.getSignalManager().emitSignal('start-application-completed') - if script: - window = script.utilities.activeWindow() - - if window and not cthulhu_state.locusOfFocus: - app = AXObject.get_application(window) - setActiveWindow(window, app, alsoSetLocusOfFocus=True, notifyScript=True) - - # setActiveWindow does some corrective work needed thanks to - # mutter-x11-frames. So retrieve the window just in case. - window = cthulhu_state.activeWindow - cthulhuApp.scriptManager.activate_script_for_context(app, window, "startup: launch") - - focusedObject = AXUtilities.get_focused_object(window) - tokens = ["CTHULHU: Focused object is:", focusedObject] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if focusedObject: - setLocusOfFocus(None, focusedObject) - cthulhuApp.scriptManager.activate_script_for_context( - AXObject.get_application(focusedObject), focusedObject, "startup: focused-object") - - try: - msg = "CTHULHU: Starting ATSPI registry." - debug.printMessage(debug.LEVEL_INFO, msg, True) - debug.print_startup_timing("AT-SPI registry start") - start() # waits until we stop the registry - except Exception: - msg = "CTHULHU: Exception starting ATSPI registry." - debug.printMessage(debug.LEVEL_SEVERE, msg, True) - die(EXIT_CODE_HANG) - return 0 - -class Cthulhu(GObject.Object): - # basic signals - __gsignals__: Dict[str, Tuple[Any, ...]] = { - "start-application-completed": (GObject.SignalFlags.RUN_LAST, None, ()), - "stop-application-completed": (GObject.SignalFlags.RUN_LAST, None, ()), - "load-setting-begin": (GObject.SignalFlags.RUN_LAST, None, ()), - "load-setting-completed": (GObject.SignalFlags.RUN_LAST, None, ()), - "setup-inputeventhandlers-completed": (GObject.SignalFlags.RUN_LAST, None, ()), # compat signal for register input event handlers - "request-cthulhu-preferences": (GObject.SignalFlags.RUN_LAST, None, ()), - "request-application-preferences": (GObject.SignalFlags.RUN_LAST, None, ()), - "active-script-changed": (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_PYOBJECT,)), # New signal to indicate active script change - } - def __init__(self) -> None: - debug.print_startup_timing("cthulhuApp construction start") - GObject.Object.__init__(self) - # add members - with debug.startup_timing("resource manager construction"): - self.resourceManager: resource_manager.ResourceManager = resource_manager.ResourceManager(self) - with debug.startup_timing("settings manager construction"): - self.settingsManager: SettingsManager = settings_manager.SettingsManager(self) - with debug.startup_timing("event manager construction"): - self.eventManager: EventManager = event_manager.EventManager(self) - with debug.startup_timing("compositor adapter construction"): - self.compositorStateAdapter: CompositorStateAdapter = \ - compositor_state_adapter.CompositorStateAdapter() - self.eventManager.set_compositor_state_adapter(self.compositorStateAdapter) - with debug.startup_timing("script manager construction"): - self.scriptManager: ScriptManager = script_manager.ScriptManager(self) - script_manager._manager = self.scriptManager - with debug.startup_timing("logger construction"): - self.logger: logger.Logger = logger.Logger() - with debug.startup_timing("signal manager construction"): - self.signalManager: SignalManager = signal_manager.SignalManager(self) - with debug.startup_timing("dynamic API manager construction"): - self.dynamicApiManager: DynamicApiManager = dynamic_api_manager.DynamicApiManager(self) - with debug.startup_timing("translation manager construction"): - self.translationManager: TranslationManager = translation_manager.TranslationManager(self) - self.debugManager: Any = debug - with debug.startup_timing("API helper construction"): - self.APIHelper: APIHelper = APIHelper(self) - with debug.startup_timing("notification monitor construction"): - self.makoNotificationMonitor: mako_notification_monitor.MakoNotificationMonitor = \ - mako_notification_monitor.MakoNotificationMonitor(self) - with debug.startup_timing("screen lock monitor construction"): - self.screenLockMonitor: screen_lock_monitor.ScreenLockMonitor = \ - screen_lock_monitor.ScreenLockMonitor(self) - with debug.startup_timing("compat API registration"): - self.createCompatAPI() - with debug.startup_timing("plugin manager construction"): - self.pluginSystemManager: PluginSystemManager = plugin_system_manager.PluginSystemManager(self) - # Scan for available plugins at startup - with debug.startup_timing("plugin scan"): - self.pluginSystemManager.rescanPlugins() - debug.print_startup_timing("cthulhuApp construction complete") - - def getAPIHelper(self) -> APIHelper: - return self.APIHelper - - def getPluginSystemManager(self) -> PluginSystemManager: - return self.pluginSystemManager - - def getMakoNotificationMonitor(self) -> mako_notification_monitor.MakoNotificationMonitor: - return self.makoNotificationMonitor - - def getScreenLockMonitor(self) -> screen_lock_monitor.ScreenLockMonitor: - return self.screenLockMonitor - - def getDynamicApiManager(self) -> DynamicApiManager: - return self.dynamicApiManager - - def getSignalManager(self) -> SignalManager: - return self.signalManager - - def getEventManager(self) -> EventManager: - return self.eventManager - - def getCompositorStateAdapter(self) -> CompositorStateAdapter: - return self.compositorStateAdapter - - def getSettingsManager(self) -> SettingsManager: - return self.settingsManager - - def getScriptManager(self) -> ScriptManager: - return self.scriptManager - - def get_scriptManager(self) -> ScriptManager: - return self.scriptManager - - def getDebugManager(self) -> Any: - return self.debugManager - - def getTranslationManager(self) -> TranslationManager: - return self.translationManager - - def getResourceManager(self) -> resource_manager.ResourceManager: - return self.resourceManager - - def getLogger(self) -> logger.Logger: # New getter for the logger - return self.logger - - def get_debug_snapshot(self) -> Dict[str, Dict[str, object]]: - """Returns read-only runtime counters useful for diagnostics.""" - - speechServer = speech.getSpeechServer() - snapshot: Dict[str, Dict[str, object]] = { - "cthulhu_state": { - "active_window_present": cthulhu_state.activeWindow is not None, - "locus_of_focus_present": cthulhu_state.locusOfFocus is not None, - "active_script_present": cthulhu_state.activeScript is not None, - "pending_self_hosted_focus_present": cthulhu_state.pendingSelfHostedFocus is not None, - "device_present": cthulhu_state.device is not None, - "pause_atspi_churn": cthulhu_state.pauseAtspiChurn, - "prioritized_desktop_context_token_present": - cthulhu_state.prioritizedDesktopContextToken is not None, - }, - "speech": { - "speech_server_present": speechServer is not None, - "speech_server": speechServer.__class__.__name__ if speechServer else "", - }, - "sound": sound.get_debug_snapshot(), - "event_manager": self.eventManager.get_debug_snapshot(), - "script_manager": self.scriptManager.get_debug_snapshot(), - "input_event_manager": input_event_manager.get_manager().get_debug_snapshot(), - "plugin_system_manager": self.pluginSystemManager.get_debug_snapshot(), - } - return snapshot - - def addKeyGrab(self, binding: Any) -> List[int]: - return addKeyGrab(binding) - - def removeKeyGrab(self, grab_id: int) -> None: - return removeKeyGrab(grab_id) - - def run(self, cacheValues: bool = True) -> int: - return main() - - def stop(self) -> None: - pass - - def createCompatAPI(self) -> None: - # for now add compatibility layer using Dynamic API - # should be removed step by step - # use clean objects, getters and setters instead - - self.getDynamicApiManager().registerAPI('Logger', self.logger) # Use instance - self.getDynamicApiManager().registerAPI('SettingsManager', self.settingsManager) # Use instance - self.getDynamicApiManager().registerAPI('ScriptManager', self.scriptManager) # Use instance - self.getDynamicApiManager().registerAPI('EventManager', self.eventManager) # Use instance - self.getDynamicApiManager().registerAPI('Speech', speech) - self.getDynamicApiManager().registerAPI('Sound', sound) - self.getDynamicApiManager().registerAPI('Braille', braille) - self.getDynamicApiManager().registerAPI('Debug', debug) - self.getDynamicApiManager().registerAPI('Messages', messages) - self.getDynamicApiManager().registerAPI('Cmdnames', cmdnames) - self.getDynamicApiManager().registerAPI('NotificationPresenter', notification_presenter) - self.getDynamicApiManager().registerAPI('MakoNotificationMonitor', self.makoNotificationMonitor) - self.getDynamicApiManager().registerAPI('ScreenLockMonitor', self.screenLockMonitor) - self.getDynamicApiManager().registerAPI('CthulhuState', cthulhu_state) - self.getDynamicApiManager().registerAPI('CthulhuPlatform', cthulhu_platform) - self.getDynamicApiManager().registerAPI('Settings', settings) - self.getDynamicApiManager().registerAPI('Keybindings', keybindings) - self.getDynamicApiManager().registerAPI('GuiLabels', guilabels) - self.getDynamicApiManager().registerAPI('Acss', acss) - self.getDynamicApiManager().registerAPI('TextAttributeNames', text_attribute_names) - self.getDynamicApiManager().registerAPI('PronunciationDict', pronunciation_dict) - self.getDynamicApiManager().registerAPI('InputEvent', input_event) - self.getDynamicApiManager().registerAPI('SpeechServer', speechserver) - self.getDynamicApiManager().registerAPI('CthulhuGtkbuilder', cthulhu_gtkbuilder) - self.getDynamicApiManager().registerAPI('AXObject', AXObject) - self.getDynamicApiManager().registerAPI('AXUtilities', AXUtilities) - self.getDynamicApiManager().registerAPI('LearnModePresenter', learn_mode_presenter) - # cthulhu lets say, special compat handling.... - self.getDynamicApiManager().registerAPI('EmitRegionChanged', emitRegionChanged) - self.getDynamicApiManager().registerAPI('LoadUserSettings', loadUserSettings) - self.getDynamicApiManager().registerAPI('APIHelper', self.APIHelper) - -cthulhuApp: Cthulhu = Cthulhu() - -def getManager() -> Cthulhu: - return cthulhuApp - -if __name__ == "__main__": - GObject.threads_init() - sys.exit(cthulhuApp.run()) diff --git a/src/cthulhu/cthulhuVersion.py b/src/cthulhu/cthulhuVersion.py deleted file mode 100644 index ce4f73e..0000000 --- a/src/cthulhu/cthulhuVersion.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -version = "2026.09.09" -codeName = "" diff --git a/src/cthulhu/cthulhu_bin.py.in b/src/cthulhu/cthulhu_bin.py.in deleted file mode 100644 index 4ece8da..0000000 --- a/src/cthulhu/cthulhu_bin.py.in +++ /dev/null @@ -1,380 +0,0 @@ -#!@PYTHON@ -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import argparse -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -import os -import shutil -import signal -import subprocess -import sys -import time - -sys.prefix = '@prefix@' -pythondir = '@pythondir@' -pythondir = pythondir.replace('${PYTHON_PREFIX}', '@PYTHON_PREFIX@') -pythondir = pythondir.replace('${prefix}', '@prefix@') -sys.path.insert(1, pythondir) - -# Do not import Cthulhu here. It is imported in main(). The reason why is that -# start-up failures due to imports in cthulhu.py are not getting output, making -# them challenging to debug when they cannot be reproduced locally. - -from cthulhu import debug -from cthulhu import messages -from cthulhu import settings -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu.cthulhu_platform import version, revision - -class ListApps(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - desktop = AXUtilities.get_desktop() - for app in AXObject.iter_children(desktop): - pid = AXObject.get_process_id(app) - try: - name = Atspi.Accessible.get_name(app) or "(none)" - except Exception: - name = "[DEAD]" - - try: - cmdline = subprocess.getoutput('cat /proc/%s/cmdline' % pid) - except Exception: - cmdline = '(exception encountered)' - else: - cmdline = cmdline.replace('\x00', ' ') - - print(time.strftime('%H:%M:%S', time.localtime()), - ' pid: %5s %-25s %s' % (pid, name, cmdline)) - - parser.exit() - -class PrintVersion(argparse.Action): - """Action to print the version of Cthulhu.""" - - def __call__(self, parser, namespace, values, option_string=None): - msg = version - if revision: - msg += f" (rev {revision})" - - atspi_version = Atspi.get_version() - msg += f", AT-SPI2 version: {atspi_version[0]}.{atspi_version[1]}.{atspi_version[2]}" - - session_type = os.environ.get("XDG_SESSION_TYPE") or "" - session_desktop = os.environ.get("XDG_SESSION_DESKTOP") or "" - session = f"{session_type} {session_desktop}".strip() - if session: - msg += f", Session: {session}" - - print(msg) - parser.exit() - -class Settings(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - settingsDict = getattr(namespace, 'settings', {}) - invalid = getattr(namespace, 'invalid', []) - for value in values.split(','): - item = str.title(value).replace('-', '') - try: - test = 'enable%s' % item - eval('settings.%s' % test) - except AttributeError: - try: - test = 'show%s' % item - eval('settings.%s' % test) - except AttributeError: - invalid.append(value) - continue - settingsDict[test] = self.const - setattr(namespace, 'settings', settingsDict) - setattr(namespace, 'invalid', invalid) - -class HelpFormatter(argparse.HelpFormatter): - def __init__(self, prog, indent_increment=2, max_help_position=32, - width=None): - - super().__init__(prog, indent_increment, max_help_position, width) - - def add_usage(self, usage, actions, groups, prefix=None): - super().add_usage(usage, actions, groups, messages.CLI_USAGE) - -class Parser(argparse.ArgumentParser): - def __init__(self, *args, **kwargs): - super(Parser, self).__init__( - epilog=messages.CLI_EPILOG, formatter_class=HelpFormatter, add_help=False) - self.add_argument( - "-h", "--help", action="help", help=messages.CLI_HELP) - self.add_argument( - "-v", "--version", action=PrintVersion, nargs=0, help=messages.CLI_VERSION) - self.add_argument( - "-r", "--replace", action="store_true", help=messages.CLI_REPLACE) - self.add_argument( - "-s", "--setup", action="store_true", help=messages.CLI_GUI_SETUP) - self.add_argument( - "-l", "--list-apps", action=ListApps, nargs=0, - help=messages.CLI_LIST_APPS) - self.add_argument( - "-e", "--enable", action=Settings, const=True, - help=messages.CLI_ENABLE_OPTION, metavar=messages.CLI_OPTION) - self.add_argument( - "-d", "--disable", action=Settings, const=False, - help=messages.CLI_DISABLE_OPTION, metavar=messages.CLI_OPTION) - self.add_argument( - "-p", "--profile", action="store", - help=messages.CLI_LOAD_PROFILE, metavar=messages.CLI_PROFILE_NAME) - self.add_argument( - "-u", "--user-prefs", action="store", - help=messages.CLI_LOAD_PREFS, metavar=messages.CLI_PREFS_DIR) - self.add_argument( - "--debug-file", action="store", - help=messages.CLI_DEBUG_FILE, metavar=messages.CLI_DEBUG_FILE_NAME) - self.add_argument( - "--debug", action="store_true", help=messages.CLI_ENABLE_DEBUG) - self.add_argument( - "--debug-startup", action="store_true", help=messages.CLI_ENABLE_STARTUP_DEBUG) - - self._optionals.title = messages.CLI_OPTIONAL_ARGUMENTS - - def parse_known_args(self, *args, **kwargs): - opts, invalid = super(Parser, self).parse_known_args(*args, **kwargs) - try: - invalid.extend(opts.invalid) - except Exception: - pass - if invalid: - print((messages.CLI_INVALID_OPTIONS + " ".join(invalid))) - - if opts.debug_file: - opts.debug = True - elif opts.debug: - opts.debug_file = time.strftime('debug-%Y-%m-%d-%H:%M:%S.out') - - return opts, invalid - -def setProcessName(name): - """Attempts to set the process name to the specified name.""" - - sys.argv[0] = name - - try: - from setproctitle import setproctitle - except ImportError: - pass - else: - setproctitle(name) - return True - - try: - from ctypes import cdll, byref, create_string_buffer - libc = cdll.LoadLibrary('libc.so.6') - stringBuffer = create_string_buffer(len(name) + 1) - stringBuffer.value = bytes(name, 'UTF-8') - libc.prctl(15, byref(stringBuffer), 0, 0, 0) - return True - except Exception: - pass - - return False - -def inGraphicalDesktop(): - """Returns True if we are in a graphical desktop.""" - - # TODO - JD: Make this desktop environment agnostic - try: - import gi - gi.require_version("Gdk", "3.0") - from gi.repository import Gdk - display = Gdk.Display.get_default() - except Exception: - return False - - return display is not None - -def getSessionType(): - sessionType = (os.environ.get("XDG_SESSION_TYPE") or "").strip().lower() - if sessionType: - return sessionType - if os.environ.get("WAYLAND_DISPLAY"): - return "wayland" - if os.environ.get("DISPLAY"): - return "x11" - return "unknown" - -def getXServerVendor(): - display = os.environ.get("DISPLAY") - if not display: - return None - - xdpyinfoPath = shutil.which("xdpyinfo") - if not xdpyinfoPath: - return None - - try: - result = subprocess.run( - [xdpyinfoPath, "-display", display], - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - timeout=1, - ) - except Exception: - return None - - for line in result.stdout.splitlines(): - if "vendor string:" in line: - return line.split("vendor string:", 1)[1].strip() - return None - -def otherCthulhus(): - """Returns the pid of any other instances of Cthulhu owned by this user.""" - - openFile = subprocess.Popen('pgrep -u %s -x cthulhu' % os.getuid(), - shell=True, - stdout=subprocess.PIPE).stdout - pids = openFile.read() - openFile.close() - cthulhus = [int(p) for p in pids.split()] - - pid = os.getpid() - return [p for p in cthulhus if p != pid] - -def cleanup(sigval): - """Tries to clean up any other running Cthulhu instances owned by this user.""" - - cthulhusToKill = otherCthulhus() - debug.printMessage(debug.LEVEL_INFO, "INFO: Cleaning up these PIDs: %s" % cthulhusToKill) - - def onTimeout(signum, frame): - cthulhusToKill = otherCthulhus() - debug.printMessage(debug.LEVEL_INFO, "INFO: Timeout cleaning up: %s" % cthulhusToKill) - for pid in cthulhusToKill: - os.kill(pid, signal.SIGKILL) - - for pid in cthulhusToKill: - os.kill(pid, sigval) - signal.signal(signal.SIGALRM, onTimeout) - signal.alarm(2) - while otherCthulhus(): - time.sleep(0.5) - -def main(): - debug.reset_startup_timing() - - setProcessName('cthulhu') - - parser = Parser() - args, invalid = parser.parse_known_args() - - if args.debug: - debug.debugLevel = debug.LEVEL_ALL - debug.eventDebugLevel = debug.LEVEL_OFF - debug.debugFile = open(args.debug_file, 'w') - - debug.set_startup_timing_enabled(args.debug or args.debug_startup) - debug.print_startup_timing("launcher main start") - - if args.replace: - with debug.startup_timing("replace cleanup"): - cleanup(signal.SIGKILL) - - settingsDict = getattr(args, 'settings', {}) - - with debug.startup_timing("graphical desktop check"): - graphicalDesktop = inGraphicalDesktop() - if not graphicalDesktop: - print(messages.CLI_NO_DESKTOP_ERROR) - return 1 - - with debug.startup_timing("session check"): - sessionType = getSessionType() - xServerVendor = None - if sessionType == "x11": - xServerVendor = getXServerVendor() - sessionDetails = [] - xdgSessionType = os.environ.get("XDG_SESSION_TYPE") - if xdgSessionType: - sessionDetails.append(f"XDG_SESSION_TYPE={xdgSessionType}") - if sessionType == "wayland": - waylandDisplay = os.environ.get("WAYLAND_DISPLAY") - if waylandDisplay: - sessionDetails.append(f"WAYLAND_DISPLAY={waylandDisplay}") - elif sessionType == "x11": - display = os.environ.get("DISPLAY") - if display: - sessionDetails.append(f"DISPLAY={display}") - if xServerVendor: - sessionDetails.append(f"X server vendor={xServerVendor}") - - if sessionDetails: - msg = f"INFO: Session: {sessionType} ({', '.join(sessionDetails)})" - else: - msg = f"INFO: Session: {sessionType}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - debug.printMessage(debug.LEVEL_INFO, "INFO: Preparing to launch.", True) - - debug.print_startup_timing("cthulhu import start") - from cthulhu import cthulhu - debug.print_startup_timing("cthulhu import complete") - manager = cthulhu.cthulhuApp.settingsManager - - if not manager: - print(messages.CLI_SETTINGS_MANAGER_ERROR) - return 1 - - debug.printMessage(debug.LEVEL_INFO, "INFO: About to activate settings manager.", True) - with debug.startup_timing("settings manager launcher activation"): - manager.activate(args.user_prefs, settingsDict) - sys.path.insert(0, manager.getPrefsDir()) - - if args.profile: - with debug.startup_timing("profile selection"): - try: - manager.setProfile(args.profile) - except Exception: - print(messages.CLI_LOAD_PROFILE_ERROR % args.profile) - manager.setProfile() - - if args.setup: - with debug.startup_timing("setup cleanup"): - cleanup(signal.SIGKILL) - with debug.startup_timing("preferences GUI startup"): - cthulhu.showPreferencesGUI() - - with debug.startup_timing("other instance check"): - otherInstances = otherCthulhus() - if otherInstances: - print(messages.CLI_OTHER_CTHULHUS_ERROR) - return 1 - - debug.printMessage(debug.LEVEL_INFO, "INFO: About to launch Cthulhu.", True) - debug.print_startup_timing("cthulhu main handoff") - return cthulhu.main() - -if __name__ == "__main__": - sys.exit(main()) diff --git a/src/cthulhu/cthulhu_gtkbuilder.py b/src/cthulhu/cthulhu_gtkbuilder.py deleted file mode 100644 index 747bd11..0000000 --- a/src/cthulhu/cthulhu_gtkbuilder.py +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Displays a GUI for the user to quit Cthulhu.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import gettext -import importlib.resources as resources -import os -from gi.repository import Gtk - -from .cthulhu_i18n import _ - -class GtkBuilderWrapper: - """ - Superclass for GtkBuilder based applications. Just derive from this - and your subclass should create methods whose names correspond to - the signal handlers defined in the GtkBuilder file. Any other attributes - in your class will be safely ignored. - - This class will give you the ability to do: - subclass_instance.GtkWindow.method(...) - subclass_instance.widget_name... - """ - - def __init__(self, fileName, windowName): - # Load GtkBuilder file. - self.builder = Gtk.Builder() - self.builder.set_translation_domain(gettext.textdomain()) - self._add_builder_from_file(fileName) - self.gtkWindow = self.builder.get_object(windowName) - - # Force the localization of widgets to work around a GtkBuilder - # bug. See bgo bug 589362. - # - for obj in self.builder.get_objects(): - self.localize_widget(obj) - - # Set default application icon. - self.set_cthulhu_icon() - - instance_attributes = {} - for attribute in dir(self.__class__): - instance_attributes[attribute] = getattr(self, attribute) - self.builder.connect_signals(instance_attributes) - - def _add_builder_from_file(self, fileName): - if os.path.exists(fileName): - self.builder.add_from_file(fileName) - return - - resourceName = os.path.basename(fileName) - try: - uiPath = resources.files(__package__).joinpath(resourceName) - except Exception: - uiPath = None - - if uiPath and uiPath.is_file(): - with resources.as_file(uiPath) as resolvedPath: - self.builder.add_from_file(str(resolvedPath)) - return - - self.builder.add_from_file(fileName) - - def set_cthulhu_icon(self): - """Get the icon in all sizes from the current theme and set them as - default for all application windows. - """ - - icon_theme = Gtk.IconTheme.get_default() - try: - icon16 = icon_theme.load_icon("cthulhu", 16, 0) - icon22 = icon_theme.load_icon("cthulhu", 22, 0) - icon24 = icon_theme.load_icon("cthulhu", 24, 0) - icon32 = icon_theme.load_icon("cthulhu", 32, 0) - icon48 = icon_theme.load_icon("cthulhu", 48, 0) - except Exception: - return - else: - Gtk.Window.set_default_icon_list((icon16, - icon22, - icon24, - icon32, - icon48)) - - def get_widget(self, attribute): - """Return the requested widget. This routine has been introduced - (and calls to it made by the Cthulhu GtkBuilder sub-classes), to prevent - "No class attribute" pychecker errors caused when using __getattr__. - - Arguments: - - attribute: name of the widget to return. - """ - - widget = self.builder.get_object(attribute) - if widget is None: - raise AttributeError("Widget [" + attribute + "] not found") - - return widget - - def __getattr__(self, attribute): # Called when no attribute in __dict__ - widget = self.builder.get_object(attribute) - if widget is None: - raise AttributeError("Widget [" + attribute + "] not found") - self.__dict__[attribute] = widget # Add reference to cache. - - return widget - - def localize_widget(self, obj): - """Force the localization of the label/title of GtkBuilder objects - - Arguments: - - obj: the GtkBuilder object whose label or title should be localized - """ - - # TODO - JD: This is a workaround for a GtkBuilder bug which prevents - # the strings displayed by widgets from being translated. See bgo bug - # 589362. - # - try: - useMarkup = obj.get_use_markup() - useUnderline = obj.get_use_underline() - except Exception: - useMarkup = False - useUnderline = False - - if isinstance(obj, Gtk.Frame): - # For some reason, if we localize the frame, which has a label - # but does not (itself) support use_markup, we get unmarked - # labels which are not bold but which do have . If we - # skip the frames, the labels get processed as expected. And - # there was much rejoicing. Yea. - # - return - - try: - title = obj.get_title() - if title and len(title): - obj.set_title(_(title)) - except Exception: - try: - text = obj.get_label() - except Exception: - return False - - if text and len(text): - if useMarkup: - obj.set_markup(_(text)) - else: - obj.set_label(_(text)) - - if useUnderline: - obj.set_use_underline(True) - - return True diff --git a/src/cthulhu/cthulhu_gui_find.py b/src/cthulhu/cthulhu_gui_find.py deleted file mode 100644 index af99110..0000000 --- a/src/cthulhu/cthulhu_gui_find.py +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Displays a GUI for the Cthulhu Find window""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import os -import sys -import gi -gi.require_version("Gtk", "3.0") -from gi.repository import Gtk -import locale - -from . import find -from . import guilabels -from . import cthulhu_gtkbuilder -from . import cthulhu_state -from . import cthulhu_platform - -OS = None - -class CthulhuFindGUI(cthulhu_gtkbuilder.GtkBuilderWrapper): - - def __init__(self, fileName, windowName): - """Initialize the Cthulhu configuration GUI. - - Arguments: - - fileName: name of the GtkBuilder file. - - windowName: name of the component to get from the GtkBuilder file. - """ - - cthulhu_gtkbuilder.GtkBuilderWrapper.__init__(self, fileName, windowName) - self.activeScript = None - self.caseSensitive = None - self.matchEntireWord = None - self.searchBackwards = None - self.searchString = None - self.startAtTop = None - self.windowWrap = None - - def init(self): - # Initialize the dialog box controls. - self.searchString = "" - self.searchBackwards = False - self.caseSensitive = False - self.matchEntireWord = False - self.windowWrap = True - self.startAtTop = False - - self.activeScript = cthulhu_state.activeScript - - def showGUI(self): - """Show the Cthulhu Find dialog. This assumes that the GUI has - already been created. - """ - - findDialog = self.get_widget("findDialog") - ts = cthulhu_state.lastInputEvent.timestamp - if ts == 0: - ts = Gtk.get_current_event_time() - findDialog.present_with_time(ts) - - # Populate the dialog box from the previous searchQuery, should - # one exist. Note: This is necessary because we are destroying - # the dialog (rather than merely hiding it) before performing the - # search. - - try: - searchForEntry = self.get_widget("searchForEntry") - searchForEntry.set_text(cthulhu_state.searchQuery.searchString) - searchForEntry.select_region(0, len(searchForEntry.get_text())) - if cthulhu_state.searchQuery.startAtTop: - self.get_widget("topRadioButton").set_active(True) - self.get_widget("matchCaseCheckbox").set_active(\ - cthulhu_state.searchQuery.caseSensitive) - self.get_widget("matchEntireWordCheckbox").set_active(\ - cthulhu_state.searchQuery.matchEntireWord) - self.get_widget("wrapAroundCheckbox").set_active(\ - cthulhu_state.searchQuery.windowWrap) - self.get_widget("searchBackwardsCheckbox").set_active(\ - cthulhu_state.searchQuery.searchBackwards) - except Exception: - pass - - def searchForEntryChanged(self, widget): - """Signal handler for the "changed" signal for the - searchForEntry GtkEntry widget. The user has changed - the string to be searched for. - - Arguments: - - widget: the component that generated the signal. - """ - - self.searchString = widget.get_text() - findButton = self.get_widget("findButton") - if len(self.searchString) > 0: - findButton.set_sensitive(True) - else: - findButton.set_sensitive(False) - - def startingPointChanged(self, widget): - """Signal handler for the "toggled" signal for the - currentLocationRadioButton or topRadioButton GtkRadioButton - widgets. The user has toggled the starting point for the search. - - Arguments: - - widget: the component that generated the signal. - """ - - if widget.get_active(): - if widget.get_label() == guilabels.FIND_START_AT_CURRENT_LOCATION: - self.startAtTop = False - else: - self.startAtTop = True - - def matchCaseChecked(self, widget): - """Signal handler for the "toggled" signal for the - matchCaseCheckbox GtkCheckButton widget. The user has - [un]checked the "Match Case" checkbox. - - Arguments: - - widget: the component that generated the signal. - """ - - self.caseSensitive = widget.get_active() - - def matchEntireWordChecked(self, widget): - """Signal handler for the "toggled" signal for the - matchEntireWordCheckbox GtkCheckButton widget. - The user has [un]checked the "Match entire word" - checkbox. - - Arguments: - - widget: the component that generated the signal. - """ - - self.matchEntireWord = widget.get_active() - - def searchBackwardsChecked(self, widget): - """Signal handler for the "toggled" signal for the - searchBackwardsCheckbox GtkCheckButton widget. - The user has [un]checked the "Search backwards" - checkbox. - - Arguments: - - widget: the component that generated the signal. - """ - - self.searchBackwards = widget.get_active() - - def wrapAroundChecked(self, widget): - """Signal handler for the "toggled" signal for the - wrapAroundCheckbox GtkCheckButton widget. The user has - [un]checked the "Wrap around" checkbox. - - Arguments: - - widget: the component that generated the signal. - """ - - self.windowWrap = widget.get_active() - - def closeButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the cancelButton - GtkButton widget. The user has clicked the Cancel button. - Hide the dialog. - - Arguments: - - widget: the component that generated the signal. - """ - - self.get_widget("findDialog").hide() - - def findButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the findButton - GtkButton widget. The user has clicked the Find button. - Call the method to begin the search. - - Arguments: - - widget: the component that generated the signal. - """ - - cthulhu_state.searchQuery = find.SearchQuery() - cthulhu_state.searchQuery.searchString = self.searchString - cthulhu_state.searchQuery.searchBackwards = self.searchBackwards - cthulhu_state.searchQuery.caseSensitive = self.caseSensitive - cthulhu_state.searchQuery.matchEntireWord = self.matchEntireWord - cthulhu_state.searchQuery.startAtTop = self.startAtTop - cthulhu_state.searchQuery.windowWrap = self.windowWrap - - self.activeScript.findCommandRun = True - - # Merely hiding the dialog causes the find to take place before - # the original window has fully regained focus. - self.get_widget("findDialog").destroy() - - - def findDialogDestroyed(self, widget): - """Signal handler for the "destroyed" signal for the findDialog - GtkWindow widget. Reset OS to None. - - Arguments: - - widget: the component that generated the signal. - """ - - global OS - - OS = None - -def showFindUI(): - global OS - - if not OS: - uiFile = os.path.join(cthulhu_platform.datadir, - cthulhu_platform.package, - "ui", - "cthulhu-find.ui") - OS = CthulhuFindGUI(uiFile, "findDialog") - OS.init() - - OS.showGUI() - -def main(): - locale.setlocale(locale.LC_ALL, '') - - showFindUI() - - Gtk.main() - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/cthulhu/cthulhu_gui_navlist.py b/src/cthulhu/cthulhu_gui_navlist.py deleted file mode 100644 index ac82fff..0000000 --- a/src/cthulhu/cthulhu_gui_navlist.py +++ /dev/null @@ -1,196 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Displays a GUI for Cthulhu navigation list dialogs""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2012 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") -from gi.repository import GObject, Gdk, Gtk - -from . import debug -from . import guilabels -from . import cthulhu_state -from .ax_event_synthesizer import AXEventSynthesizer -from .ax_object import AXObject - -class CthulhuNavListGUI: - - def __init__(self, title, columnHeaders, rows, selectedRow): - self._tree = None - self._activateButton = None - self._jumpToButton = None - self._gui = self._createNavListDialog(columnHeaders, rows, selectedRow) - self._gui.set_title(title) - self._gui.set_modal(True) - self._gui.set_keep_above(True) - self._gui.set_focus_on_map(True) - self._gui.set_accept_focus(True) - self._script = cthulhu_state.activeScript - self._document = None - - def _createNavListDialog(self, columnHeaders, rows, selectedRow): - dialog = Gtk.Dialog() - dialog.set_default_size(500, 400) - - grid = Gtk.Grid() - contentArea = dialog.get_content_area() - contentArea.add(grid) - - scrolledWindow = Gtk.ScrolledWindow() - grid.add(scrolledWindow) - - self._tree = Gtk.TreeView() - self._tree.set_hexpand(True) - self._tree.set_vexpand(True) - scrolledWindow.add(self._tree) - - cols = [GObject.TYPE_OBJECT, GObject.TYPE_INT] - cols.extend(len(columnHeaders) * [GObject.TYPE_STRING]) - model = Gtk.ListStore(*cols) - - cell = Gtk.CellRendererText() - column = Gtk.TreeViewColumn("Accessible", cell, text=0) - column.set_visible(False) - self._tree.append_column(column) - - cell = Gtk.CellRendererText() - column = Gtk.TreeViewColumn("offset", cell, text=1) - column.set_visible(False) - self._tree.append_column(column) - - for i, header in enumerate(columnHeaders): - cell = Gtk.CellRendererText() - column = Gtk.TreeViewColumn(header, cell, text=i+2) - column.set_sort_column_id(i+2) - self._tree.append_column(column) - - for row in rows: - rowIter = model.append(None) - for i, cell in enumerate(row): - model.set_value(rowIter, i, cell) - - self._tree.set_model(model) - selection = self._tree.get_selection() - selection.select_path(selectedRow) - - btn = dialog.add_button(guilabels.BTN_CANCEL, Gtk.ResponseType.CANCEL) - btn.connect('clicked', self._onCancelClicked) - - self._jumpToButton = dialog.add_button(guilabels.BTN_JUMP_TO, Gtk.ResponseType.APPLY) - self._jumpToButton.connect('clicked', self._onJumpToClicked) - - self._activateButton = dialog.add_button( - guilabels.ACTIVATE, Gtk.ResponseType.OK) - self._activateButton.connect('clicked', self._onActivateClicked) - self._activateButton.grab_default() - - self._tree.connect('key-release-event', self._onKeyRelease) - self._tree.connect('cursor-changed', self._onCursorChanged) - self._tree.set_search_column(2) - - return dialog - - def showGUI(self): - self._document = self._script.utilities.documentFrame() - x, y, width, height = self._script.utilities.getBoundingBox(self._document) - if (width and height): - self._gui.move(x + 100, y + 100) - - self._gui.show_all() - ts = cthulhu_state.lastInputEvent.timestamp - if ts == 0: - ts = Gtk.get_current_event_time() - self._gui.present_with_time(ts) - - def _onCursorChanged(self, widget): - obj, offset = self._getSelectedAccessibleAndOffset() - n_actions = AXObject.get_n_actions(obj) - self._activateButton.set_sensitive(n_actions > 0) - if n_actions > 0: - self._activateButton.grab_default() - else: - self._jumpToButton.grab_default() - - def _onKeyRelease(self, widget, event): - keycode = event.hardware_keycode - keymap = Gdk.Keymap.get_default() - entries_for_keycode = keymap.get_entries_for_keycode(keycode) - entries = entries_for_keycode[-1] - eventString = Gdk.keyval_name(entries[0]) - if eventString == 'Return': - self._gui.activate_default() - - def _onCancelClicked(self, widget): - self._gui.destroy() - - def _onJumpToClicked(self, widget): - obj, offset = self._getSelectedAccessibleAndOffset() - self._gui.destroy() - self._script.utilities.setCaretPosition(obj, offset, self._document) - - def _onActivateClicked(self, widget): - obj, offset = self._getSelectedAccessibleAndOffset() - self._gui.destroy() - if not obj: - return - - self._script.utilities.setCaretPosition(obj, offset) - if not AXEventSynthesizer.try_all_clickable_actions(obj): - tokens = ["INFO: Attempting a synthesized click on", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - AXEventSynthesizer.click_object(obj) - - def _getSelectedAccessibleAndOffset(self): - if not self._tree: - msg = "ERROR: Could not get navlist tree" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return None, -1 - - selection = self._tree.get_selection() - if not selection: - msg = "ERROR: Could not get selection for navlist tree" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return None, -1 - - model, paths = selection.get_selected_rows() - if not paths: - msg = "ERROR: Could not get paths for navlist tree" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return None, -1 - - obj = model.get_value(model.get_iter(paths[0]), 0) - offset = model.get_value(model.get_iter(paths[0]), 1) - return obj, max(0, offset) - -def showUI(title='', columnHeaders=[], rows=[()], selectedRow=0): - gui = CthulhuNavListGUI(title, columnHeaders, rows, selectedRow) - gui.showGUI() diff --git a/src/cthulhu/cthulhu_gui_prefs.py b/src/cthulhu/cthulhu_gui_prefs.py deleted file mode 100644 index 9667f7f..0000000 --- a/src/cthulhu/cthulhu_gui_prefs.py +++ /dev/null @@ -1,5416 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Displays a GUI for the user to set Cthulhu preferences.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") -from gi.repository import Atspi - -import os -import json -import subprocess -import sys -import threading -from gi.repository import Gdk -from gi.repository import GLib -from gi.repository import Gtk -from gi.repository import GObject -from gi.repository import Pango -import time - -from . import acss -from . import debug -from . import event_manager -from . import guilabels -from . import messages -from . import cthulhu -from . import cthulhu_gtkbuilder -from . import cthulhu_gui_profile -from . import cthulhu_state -from . import settings -from . import settings_manager -from . import sound_sink -from . import input_event -from . import input_event_manager -from . import keybindings -from . import pronunciation_dict -from . import braille -from . import speech -from . import speechserver -from . import text_attribute_names -from . import sound_theme_manager -from . import script_manager -from .ax_object import AXObject -from .ax_utilities import AXUtilities - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -try: - import louis -except ImportError: - louis = None -from .cthulhu_platform import tablesdir -if louis and not tablesdir: - louis = None - -(HANDLER, DESCRIP, MOD_MASK1, MOD_USED1, KEY1, CLICK_COUNT1, OLDTEXT1, \ - TEXT1, MODIF, EDITABLE) = list(range(10)) - -(NAME, IS_SPOKEN, IS_BRAILLED, VALUE) = list(range(4)) - -(ACTUAL, REPLACEMENT) = list(range(2)) - -# Must match the order of voice types in the GtkBuilder file. -# -(DEFAULT, UPPERCASE, HYPERLINK, SYSTEM) = list(range(4)) - -# Must match the order that the timeFormatCombo is populated. -# -(TIME_FORMAT_LOCALE, TIME_FORMAT_12_HM, TIME_FORMAT_12_HMS, TIME_FORMAT_24_HMS, - TIME_FORMAT_24_HMS_WITH_WORDS, TIME_FORMAT_24_HM, - TIME_FORMAT_24_HM_WITH_WORDS) = list(range(7)) - -# Must match the order that the dateFormatCombo is populated. -# -(DATE_FORMAT_LOCALE, DATE_FORMAT_NUMBERS_DM, DATE_FORMAT_NUMBERS_MD, - DATE_FORMAT_NUMBERS_DMY, DATE_FORMAT_NUMBERS_MDY, DATE_FORMAT_NUMBERS_YMD, - DATE_FORMAT_FULL_DM, DATE_FORMAT_FULL_MD, DATE_FORMAT_FULL_DMY, - DATE_FORMAT_FULL_MDY, DATE_FORMAT_FULL_YMD, DATE_FORMAT_ABBREVIATED_DM, - DATE_FORMAT_ABBREVIATED_MD, DATE_FORMAT_ABBREVIATED_DMY, - DATE_FORMAT_ABBREVIATED_MDY, DATE_FORMAT_ABBREVIATED_YMD) = list(range(16)) - -class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper): - def __init__(self, fileName, windowName, prefsDict): - """Initialize the Cthulhu configuration GUI. - - Arguments: - - fileName: name of the GtkBuilder file. - - windowName: name of the component to get from the GtkBuilder file. - - prefsDict: dictionary of preferences to use during initialization - """ - - cthulhu_gtkbuilder.GtkBuilderWrapper.__init__(self, fileName, windowName) - self.prefsDict = prefsDict - - self._defaultProfile = ['Default', 'default'] - self.bbindings = None - self.cellRendererText = None - self.defaultVoice = None - self.disableKeyGrabPref = None - self.getTextAttributesView = None - self.hyperlinkVoice = None - self.initializingSpeech = None - self.kbindings = None - self.keyBindingsModel = None - self.keyBindView = None - self.newBinding = None - self.pendingKeyBindings = None - self.planeCellRendererText = None - self.pronunciationModel = None - self.pronunciationView = None - self._plugin_combo = None - self._plugin_model = None - self._plugin_entries = {} - self._plugin_enabled_button = None - self._plugin_disabled_button = None - self._plugin_description_view = None - self._updating_plugin_controls = False - self._available_plugins = set() - self._plugin_canonical_map = {} - self._plugin_group_map = {} - self._plugin_tabs = {} - self._plugin_tabs_cached = False - self._dynamic_plugin_tabs = {} - self.screenHeight = None - self.screenWidth = None - self.speechFamiliesChoice = None - self.speechFamiliesChoices = None - self.speechFamiliesModel = None - self.hardwareDeviceChoice = None - self.hardwareDeviceChoices = None - self.hardwareDeviceModel = None - self.speechLanguagesChoice = None - self.speechLanguagesChoices = None - self.speechLanguagesModel = None - self.speechFamilies = [] - self.speechServersChoice = None - self.speechServersChoices = None - self.speechServersModel = None - self.speechSystemsChoice = None - self.speechSystemsChoices = None - self.speechSystemsModel = None - self.echoVoice = None - self.echoSpeechFamiliesChoice = None - self.echoSpeechFamiliesChoices = None - self.echoSpeechFamiliesModel = None - self.echoSpeechServersChoice = None - self.echoSpeechServersChoices = None - self.echoSpeechServersModel = None - self.initializingEchoSpeech = False - self._echoVoiceFetchToken = 0 - self._updatingEchoSpeechFamilies = False - self.systemVoice = None - self.uppercaseVoice = None - self.window = None - self.workingFactories = None - self.savedGain = None - self.savedPitch = None - self.savedRate = None - self.soundThemeCombo = None - self.soundSinkCombo = None - self.roleSoundPresentationCombo = None - self.soundVolumeScale = None - self.progressBarBeepIntervalSpinButton = None - self._isInitialSetup = False - self._updatingSpeechFamilies = False - self.selectedFamilyChoices = {} - self.selectedLanguageChoices = {} - self.profilesCombo = None - self.profilesComboModel = None - self.startingProfileCombo = None - self._initialFocusSyncAttempts = 0 - self._capturedKey = [] - self.script = None - - def init(self, script): - """Initialize the Cthulhu configuration GUI. Read the users current - set of preferences and set the GUI state to match. Setup speech - support and populate the combo box lists on the Speech Tab pane - accordingly. - """ - - self.script = script - - # Restore the default rate/pitch/gain, - # in case the user played with the sliders. - # - try: - voices = cthulhu.cthulhuApp.settingsManager.getSetting('voices') - defaultVoice = voices[settings.DEFAULT_VOICE] - except KeyError: - defaultVoice = {} - try: - self.savedGain = defaultVoice[acss.ACSS.GAIN] - except KeyError: - self.savedGain = 10.0 - try: - self.savedPitch = defaultVoice[acss.ACSS.AVERAGE_PITCH] - except KeyError: - self.savedPitch = 5.0 - try: - self.savedRate = defaultVoice[acss.ACSS.RATE] - except KeyError: - self.savedRate = 50.0 - - # ***** Key Bindings treeview initialization ***** - - self.keyBindView = self.get_widget("keyBindingsTreeview") - - if self.keyBindView.get_columns(): - for column in self.keyBindView.get_columns(): - self.keyBindView.remove_column(column) - - self.keyBindingsModel = Gtk.TreeStore( - GObject.TYPE_STRING, # Handler name - GObject.TYPE_STRING, # Human Readable Description - GObject.TYPE_STRING, # Modifier mask 1 - GObject.TYPE_STRING, # Used Modifiers 1 - GObject.TYPE_STRING, # Modifier key name 1 - GObject.TYPE_STRING, # Click count 1 - GObject.TYPE_STRING, # Original Text of the Key Binding Shown 1 - GObject.TYPE_STRING, # Text of the Key Binding Shown 1 - GObject.TYPE_BOOLEAN, # Key Modified by User - GObject.TYPE_BOOLEAN) # Row with fields editable or not - - self.planeCellRendererText = Gtk.CellRendererText() - - self.cellRendererText = Gtk.CellRendererText() - self.cellRendererText.set_property("ellipsize", Pango.EllipsizeMode.END) - - # HANDLER - invisble column - # - column = Gtk.TreeViewColumn("Handler", - self.planeCellRendererText, - text=HANDLER) - column.set_resizable(True) - column.set_visible(False) - column.set_sort_column_id(HANDLER) - self.keyBindView.append_column(column) - - # DESCRIP - # - column = Gtk.TreeViewColumn(guilabels.KB_HEADER_FUNCTION, - self.cellRendererText, - text=DESCRIP) - column.set_resizable(True) - column.set_min_width(380) - column.set_sort_column_id(DESCRIP) - self.keyBindView.append_column(column) - - # MOD_MASK1 - invisble column - # - column = Gtk.TreeViewColumn("Mod.Mask 1", - self.planeCellRendererText, - text=MOD_MASK1) - column.set_visible(False) - column.set_resizable(True) - column.set_sort_column_id(MOD_MASK1) - self.keyBindView.append_column(column) - - # MOD_USED1 - invisble column - # - column = Gtk.TreeViewColumn("Use Mod.1", - self.planeCellRendererText, - text=MOD_USED1) - column.set_visible(False) - column.set_resizable(True) - column.set_sort_column_id(MOD_USED1) - self.keyBindView.append_column(column) - - # KEY1 - invisble column - # - column = Gtk.TreeViewColumn("Key1", - self.planeCellRendererText, - text=KEY1) - column.set_resizable(True) - column.set_visible(False) - column.set_sort_column_id(KEY1) - self.keyBindView.append_column(column) - - # CLICK_COUNT1 - invisble column - # - column = Gtk.TreeViewColumn("ClickCount1", - self.planeCellRendererText, - text=CLICK_COUNT1) - column.set_resizable(True) - column.set_visible(False) - column.set_sort_column_id(CLICK_COUNT1) - self.keyBindView.append_column(column) - - # OLDTEXT1 - invisble column which will store a copy of the - # original keybinding in TEXT1 prior to the Apply or OK - # buttons being pressed. This will prevent automatic - # resorting each time a cell is edited. - # - column = Gtk.TreeViewColumn("OldText1", - self.planeCellRendererText, - text=OLDTEXT1) - column.set_resizable(True) - column.set_visible(False) - column.set_sort_column_id(OLDTEXT1) - self.keyBindView.append_column(column) - - # TEXT1 - # - rendererText = Gtk.CellRendererText() - rendererText.connect("editing-started", - self.editingKey, - self.keyBindingsModel) - rendererText.connect("editing-canceled", - self.editingCanceledKey) - rendererText.connect('edited', - self.editedKey, - self.keyBindingsModel, - MOD_MASK1, MOD_USED1, KEY1, CLICK_COUNT1, TEXT1) - - column = Gtk.TreeViewColumn(guilabels.KB_HEADER_KEY_BINDING, - rendererText, - text=TEXT1, - editable=EDITABLE) - - column.set_resizable(True) - column.set_sort_column_id(OLDTEXT1) - self.keyBindView.append_column(column) - - # MODIF - # - rendererToggle = Gtk.CellRendererToggle() - rendererToggle.connect('toggled', - self.keyModifiedToggle, - self.keyBindingsModel, - MODIF) - column = Gtk.TreeViewColumn(guilabels.KB_MODIFIED, - rendererToggle, - active=MODIF, - activatable=EDITABLE) - #column.set_visible(False) - column.set_resizable(True) - column.set_sort_column_id(MODIF) - self.keyBindView.append_column(column) - - # EDITABLE - invisble column - # - rendererToggle = Gtk.CellRendererToggle() - rendererToggle.set_property('activatable', False) - column = Gtk.TreeViewColumn("Modified", - rendererToggle, - active=EDITABLE) - column.set_visible(False) - column.set_resizable(True) - column.set_sort_column_id(EDITABLE) - self.keyBindView.append_column(column) - - # Populates the treeview with all the keybindings: - # - self._populateKeyBindings() - - self.window = self.get_widget("cthulhuSetupWindow") - - self._setKeyEchoItems() - - self.speechSystemsModel = \ - self._initComboBox(self.get_widget("speechSystems")) - self.speechServersModel = \ - self._initComboBox(self.get_widget("speechServers")) - self.speechLanguagesModel = \ - self._initComboBox(self.get_widget("speechLanguages")) - self.speechFamiliesModel = \ - self._initComboBox(self.get_widget("speechFamilies")) - try: - self.hardwareDeviceModel = \ - self._initComboBox(self.get_widget("hardwareDeviceCombo")) - except AttributeError: - self.hardwareDeviceModel = None - self.echoSpeechServersModel = \ - self._initComboBox(self.get_widget("echoSpeechServers")) - self.echoSpeechFamiliesModel = \ - self._initComboBox(self.get_widget("echoSpeechFamilies")) - self._initSpeechState() - self._initEchoSpeechState() - - # TODO - JD: Will this ever be the case?? - self._isInitialSetup = \ - not os.path.exists(cthulhu.cthulhuApp.settingsManager.getPrefsDir()) - - try: - self._initPluginsPage() - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"PREFERENCES DIALOG: Plugin page init failed: {e}", True) - - appPage = self.script.getAppPreferencesGUI() - if appPage: - label = Gtk.Label(label=AXObject.get_name(self.script.app)) - self.get_widget("notebook").append_page(appPage, label) - - self._cache_plugin_tabs() - self._update_plugin_tabs() - self._refresh_dynamic_plugin_tabs() - self._initGUIState() - self._initSoundThemeState() - - def _initPluginsPage(self) -> None: - pluginsPage = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) - pluginsPage.set_border_width(12) - - infoLabel = Gtk.Label(label="Select a plugin, then choose whether it is enabled or disabled.") - infoLabel.set_line_wrap(True) - infoLabel.set_halign(Gtk.Align.START) - pluginsPage.pack_start(infoLabel, False, False, 0) - - pluginGrid = Gtk.Grid(row_spacing=10, column_spacing=10) - pluginLabel = Gtk.Label(label="_Plugin:") - pluginLabel.set_use_underline(True) - pluginLabel.set_halign(Gtk.Align.START) - self._plugin_model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) - self._plugin_combo = Gtk.ComboBox.new_with_model(self._plugin_model) - text_renderer = Gtk.CellRendererText() - self._plugin_combo.pack_start(text_renderer, True) - self._plugin_combo.add_attribute(text_renderer, "text", 0) - self._plugin_combo.set_hexpand(True) - self._plugin_combo.connect("changed", self._on_plugin_selection_changed) - pluginLabel.set_mnemonic_widget(self._plugin_combo) - pluginGrid.attach(pluginLabel, 0, 0, 1, 1) - pluginGrid.attach(self._plugin_combo, 1, 0, 1, 1) - pluginsPage.pack_start(pluginGrid, False, False, 0) - - stateFrame = Gtk.Frame(label="State") - stateFrame.set_shadow_type(Gtk.ShadowType.NONE) - stateBox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12) - stateBox.set_border_width(6) - self._plugin_enabled_button = Gtk.RadioButton.new_with_mnemonic(None, "_Enabled") - self._plugin_disabled_button = Gtk.RadioButton.new_with_mnemonic_from_widget( - self._plugin_enabled_button, - "_Disabled", - ) - self._plugin_enabled_button.connect("toggled", self._on_plugin_enabled_toggled) - self._plugin_disabled_button.connect("toggled", self._on_plugin_disabled_toggled) - stateBox.pack_start(self._plugin_enabled_button, False, False, 0) - stateBox.pack_start(self._plugin_disabled_button, False, False, 0) - stateFrame.add(stateBox) - pluginsPage.pack_start(stateFrame, False, False, 0) - - descriptionLabel = Gtk.Label(label="_Description:") - descriptionLabel.set_use_underline(True) - descriptionLabel.set_halign(Gtk.Align.START) - pluginsPage.pack_start(descriptionLabel, False, False, 0) - - descriptionScrolled = Gtk.ScrolledWindow() - descriptionScrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - descriptionScrolled.set_size_request(-1, 180) - self._plugin_description_view = Gtk.TextView() - self._plugin_description_view.set_editable(False) - self._plugin_description_view.set_cursor_visible(True) - self._plugin_description_view.set_accepts_tab(False) - self._plugin_description_view.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) - self._plugin_description_view.get_accessible().set_name("Plugin description") - descriptionLabel.set_mnemonic_widget(self._plugin_description_view) - descriptionScrolled.add(self._plugin_description_view) - pluginsPage.pack_start(descriptionScrolled, True, True, 0) - - notebook = self.get_widget("notebook") - notebook.append_page(pluginsPage, Gtk.Label(label="Plugins")) - - self._populate_plugin_list() - pluginsPage.show_all() - - def _populate_plugin_list(self) -> None: - if not self._plugin_combo: - return - - try: - selected_plugin = self._get_selected_plugin_name() - selected_index = 0 - self._plugin_model.clear() - self._plugin_entries = {} - self._available_plugins = set() - self._plugin_canonical_map = {} - self._plugin_group_map = {} - - manager = cthulhu.cthulhuApp.getPluginSystemManager() - if manager: - try: - manager.rescanPlugins() - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"PREFERENCES DIALOG: Plugin rescan failed: {e}", True) - manager = None - - active_plugins = list(self.prefsDict.get("activePlugins", settings.activePlugins) or []) - active_plugins_lower = {name.lower() for name in active_plugins} - - plugin_infos = manager.plugins if manager else [] - self._available_plugins = {info.get_module_name() for info in plugin_infos} - canonical_counts = {} - canonical_builtins = {} - for info in plugin_infos: - canonical = info.get_canonical_name() - canonical_counts[canonical] = canonical_counts.get(canonical, 0) + 1 - if info.builtin: - canonical_builtins[canonical] = True - - for plugin_info in sorted(plugin_infos, key=lambda item: (item.get_name() or item.get_module_name()).lower()): - plugin_name = plugin_info.get_module_name() - canonical_name = plugin_info.get_canonical_name() - if plugin_info.hidden: - continue - - self._plugin_canonical_map[plugin_name] = canonical_name - - is_active = ( - plugin_name in active_plugins - or plugin_name.lower() in active_plugins_lower - or (plugin_info.preferred_alias and (canonical_name in active_plugins or canonical_name.lower() in active_plugins_lower)) - or plugin_info.builtin - ) - - can_toggle = True - if canonical_builtins.get(canonical_name) and not plugin_info.builtin: - is_active = False - can_toggle = False - - if plugin_info.builtin: - can_toggle = False - - display_name = plugin_info.get_name() or plugin_name - description = plugin_info.get_description() - version = plugin_info.get_version() - if version: - description = f"{description}\n\nVersion: {version}" if description else f"Version: {version}" - if canonical_counts.get(canonical_name, 0) > 1: - source_label = plugin_info.get_source_label() - display_name += f" ({source_label})" - if canonical_builtins.get(canonical_name) and not plugin_info.builtin: - description += "\n\nThis copy cannot be enabled because a built-in plugin uses the same name." - if plugin_info.builtin: - description += "\n\nThis built-in plugin is always enabled." - - if plugin_name == selected_plugin: - selected_index = len(self._plugin_model) - self._plugin_model.append([display_name, plugin_name]) - self._plugin_entries[plugin_name] = { - "active": is_active, - "can_toggle": can_toggle, - "description": description, - } - self._plugin_group_map.setdefault(canonical_name, []).append(plugin_name) - - if len(self._plugin_model): - self._plugin_combo.set_active(selected_index) - else: - self._update_selected_plugin_controls() - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"PREFERENCES DIALOG: Plugin list build failed: {e}", True) - - def _get_selected_plugin_name(self) -> str | None: - if not self._plugin_combo: - return None - tree_iter = self._plugin_combo.get_active_iter() - if tree_iter is None: - return None - return self._plugin_model.get_value(tree_iter, 1) - - def _on_plugin_selection_changed(self, widget: Gtk.ComboBox) -> None: - self._update_selected_plugin_controls() - - def _update_selected_plugin_controls(self) -> None: - plugin_name = self._get_selected_plugin_name() - plugin_entry = self._plugin_entries.get(plugin_name, {}) - is_active = bool(plugin_entry.get("active", False)) - can_toggle = bool(plugin_entry.get("can_toggle", False)) - - self._updating_plugin_controls = True - try: - self._plugin_enabled_button.set_active(is_active) - self._plugin_disabled_button.set_active(not is_active) - self._plugin_enabled_button.set_sensitive(can_toggle) - self._plugin_disabled_button.set_sensitive(can_toggle) - description = str(plugin_entry.get("description", "")) - self._plugin_description_view.get_buffer().set_text(description) - self._plugin_description_view.get_buffer().place_cursor( - self._plugin_description_view.get_buffer().get_start_iter() - ) - finally: - self._updating_plugin_controls = False - - def _on_plugin_enabled_toggled(self, widget: Gtk.RadioButton) -> None: - if widget.get_active() and not self._updating_plugin_controls: - self._set_plugin_active(self._get_selected_plugin_name(), True) - - def _on_plugin_disabled_toggled(self, widget: Gtk.RadioButton) -> None: - if widget.get_active() and not self._updating_plugin_controls: - self._set_plugin_active(self._get_selected_plugin_name(), False) - - def _set_plugin_active(self, plugin_name: str | None, is_active: bool) -> None: - plugin_entry = self._plugin_entries.get(plugin_name) - if not plugin_entry or not plugin_entry.get("can_toggle", False): - self._update_selected_plugin_controls() - return - - if is_active: - canonical_name = self._plugin_canonical_map.get(plugin_name) - for other_name in self._plugin_group_map.get(canonical_name, []): - if other_name != plugin_name: - self._plugin_entries[other_name]["active"] = False - - plugin_entry["active"] = is_active - self._update_selected_plugin_controls() - self._update_plugin_tabs() - - def _get_active_plugins_from_ui(self) -> list[str]: - existing_plugins = list(self.prefsDict.get("activePlugins", settings.activePlugins) or []) - preserved_plugins = [ - name for name in existing_plugins - if name not in self._plugin_entries and name in self._available_plugins - ] - selected_plugins = [] - for canonical_name, plugin_names in self._plugin_group_map.items(): - active_in_group = [ - name for name in plugin_names - if self._plugin_entries.get(name, {}).get("active", False) - ] - if active_in_group: - selected_plugins.append(active_in_group[-1]) - return preserved_plugins + selected_plugins - - def _apply_plugin_changes(self) -> None: - active_plugins = self._get_active_plugins_from_ui() - self.prefsDict["activePlugins"] = active_plugins - self._populate_plugin_list() - self._update_plugin_tabs(active_plugins) - - def _get_active_plugin_infos(self): - manager = cthulhu.cthulhuApp.getPluginSystemManager() - if not manager: - return [] - return [info for info in manager.plugins if info.loaded and info.instance] - - def _get_plugin_preferences_page(self, plugin_info): - plugin_instance = plugin_info.instance - if not plugin_instance: - return None - - if hasattr(plugin_instance, "getPreferencesGUI"): - page = plugin_instance.getPreferencesGUI() - elif hasattr(plugin_instance, "get_preferences_gui"): - page = plugin_instance.get_preferences_gui() - else: - return None - - if not page: - return None - - label = plugin_info.get_name() or plugin_info.get_module_name() - if isinstance(page, (list, tuple)) and len(page) == 2: - page, label = page - - if isinstance(label, str): - label_widget = Gtk.Label(label=label) - else: - label_widget = label - - return page, label_widget - - def _refresh_dynamic_plugin_tabs(self): - notebook = self.get_widget("notebook") - if not notebook: - return - - for tab in list(self._dynamic_plugin_tabs.values()): - page = tab.get("page") - if page: - page_num = notebook.page_num(page) - if page_num != -1: - notebook.remove_page(page_num) - - self._dynamic_plugin_tabs = {} - - plugin_infos = self._get_active_plugin_infos() - for plugin_info in sorted(plugin_infos, key=lambda item: (item.get_name() or item.get_module_name()).lower()): - result = self._get_plugin_preferences_page(plugin_info) - if not result: - continue - - page, label = result - if not page or not label: - continue - - notebook.append_page(page, label) - page.show_all() - label.show() - self._dynamic_plugin_tabs[plugin_info.get_module_name()] = { - "page": page, - "label": label, - } - - for plugin_name in self._dynamic_plugin_tabs: - tab = self._plugin_tabs.get(plugin_name) - if not tab: - continue - page = tab.get("page") - if not page: - continue - page_num = notebook.page_num(page) - if page_num != -1: - notebook.remove_page(page_num) - - def _cache_plugin_tabs(self): - if self._plugin_tabs_cached: - return - - notebook = self.get_widget("notebook") - if not notebook: - return - - tab_specs = [ - ("AIAssistant", "aiPage", "aiTabLabel"), - ("OCR", "ocrGrid", "ocrTabLabel"), - ] - - for plugin_name, page_id, label_id in tab_specs: - page = self.get_widget(page_id) - label = self.get_widget(label_id) - if not page or not label: - continue - position = notebook.page_num(page) - self._plugin_tabs[plugin_name] = { - "page": page, - "label": label, - "position": position, - } - - self._plugin_tabs_cached = True - - def _get_active_plugins_for_tabs(self): - if self._plugin_entries: - return self._get_active_plugins_from_ui() - return list(self.prefsDict.get("activePlugins", settings.activePlugins) or []) - - @staticmethod - def _plugin_active(active_plugins, names): - active_lower = {name.lower() for name in active_plugins} - return any(name.lower() in active_lower for name in names) - - def _update_plugin_tabs(self, active_plugins=None): - if not self._plugin_tabs: - return - - notebook = self.get_widget("notebook") - if not notebook: - return - - if active_plugins is None: - active_plugins = self._get_active_plugins_for_tabs() - - for plugin_name, tab in self._plugin_tabs.items(): - if plugin_name in self._dynamic_plugin_tabs: - continue - page = tab["page"] - label = tab["label"] - position = tab["position"] - page_num = notebook.page_num(page) - is_active = self._plugin_active(active_plugins, [plugin_name]) - - if is_active and page_num == -1: - insert_pos = min(max(position, 0), notebook.get_n_pages()) - notebook.insert_page(page, label, insert_pos) - page.show_all() - label.show() - elif not is_active and page_num != -1: - notebook.remove_page(page_num) - - def _getACSSForVoiceType(self, voiceType): - """Return the ACSS value for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - Returns the voice dictionary for the given voice type. - """ - - if voiceType == DEFAULT: - voiceACSS = self.defaultVoice - elif voiceType == UPPERCASE: - voiceACSS = self.uppercaseVoice - elif voiceType == HYPERLINK: - voiceACSS = self.hyperlinkVoice - elif voiceType == SYSTEM: - voiceACSS = self.systemVoice - else: - voiceACSS = self.defaultVoice - - return voiceACSS - - def writeUserPreferences(self): - """Write out the user's generic Cthulhu preferences. - """ - pronunciationDict = self.getModelDict(self.pronunciationModel) - keyBindingsDict = self.getKeyBindingsModelDict(self.keyBindingsModel) - self.prefsDict.update(self.script.getPreferencesFromGUI()) - self.prefsDict.update(self._get_plugin_preferences_from_gui()) - cthulhu.cthulhuApp.settingsManager.saveSettings(self.script, - self.prefsDict, - pronunciationDict, - keyBindingsDict) - - def _get_plugin_preferences_from_gui(self): - preferences = {} - for plugin_info in self._get_active_plugin_infos(): - plugin_instance = plugin_info.instance - if not plugin_instance: - continue - - if hasattr(plugin_instance, "getPreferencesFromGUI"): - plugin_prefs = plugin_instance.getPreferencesFromGUI() - elif hasattr(plugin_instance, "get_preferences_from_gui"): - plugin_prefs = plugin_instance.get_preferences_from_gui() - else: - continue - - if isinstance(plugin_prefs, dict): - preferences.update(plugin_prefs) - - return preferences - - def _getKeyValueForVoiceType(self, voiceType, key, useDefault=True): - """Look for the value of the given key in the voice dictionary - for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - key: the key to look for in the voice dictionary. - - useDefault: if True, and the key isn't found for the given voice - type, the look for it in the default voice dictionary - as well. - - Returns the value of the given key, or None if it's not set. - """ - - if voiceType == DEFAULT: - voice = self.defaultVoice - elif voiceType == UPPERCASE: - voice = self.uppercaseVoice - if key not in voice: - if not useDefault: - return None - voice = self.defaultVoice - elif voiceType == HYPERLINK: - voice = self.hyperlinkVoice - if key not in voice: - if not useDefault: - return None - voice = self.defaultVoice - elif voiceType == SYSTEM: - voice = self.systemVoice - if key not in voice: - if not useDefault: - return None - voice = self.defaultVoice - else: - voice = self.defaultVoice - - if key in voice: - return voice[key] - else: - return None - - def _getFamilyNameForVoiceType(self, voiceType): - """Gets the name of the voice family for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - Returns the name of the voice family for the given voice type, - or None if not set. - """ - - familyName = None - family = self._getKeyValueForVoiceType(voiceType, acss.ACSS.FAMILY) - - if family and speechserver.VoiceFamily.NAME in family: - familyName = family[speechserver.VoiceFamily.NAME] - - return familyName - - def _setFamilyNameForVoiceType(self, voiceType, name, language, dialect, variant): - """Sets the name of the voice family for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - name: the name of the voice family to set. - - language: the locale of the voice family to set. - - dialect: the dialect of the voice family to set. - """ - - family = self._getKeyValueForVoiceType(voiceType, - acss.ACSS.FAMILY, - False) - - voiceACSS = self._getACSSForVoiceType(voiceType) - if family: - family[speechserver.VoiceFamily.NAME] = name - family[speechserver.VoiceFamily.LANG] = language - family[speechserver.VoiceFamily.DIALECT] = dialect - family[speechserver.VoiceFamily.VARIANT] = variant - else: - voiceACSS[acss.ACSS.FAMILY] = {} - voiceACSS[acss.ACSS.FAMILY][speechserver.VoiceFamily.NAME] = name - voiceACSS[acss.ACSS.FAMILY][speechserver.VoiceFamily.LANG] = language - voiceACSS[acss.ACSS.FAMILY][speechserver.VoiceFamily.DIALECT] = dialect - voiceACSS[acss.ACSS.FAMILY][speechserver.VoiceFamily.VARIANT] = variant - voiceACSS['established'] = True - - #settings.voices[voiceType] = voiceACSS - - def _getRateForVoiceType(self, voiceType): - """Gets the speaking rate value for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - Returns the rate value for the given voice type, or None if - not set. - """ - - return self._getKeyValueForVoiceType(voiceType, acss.ACSS.RATE) - - def _setRateForVoiceType(self, voiceType, value): - """Sets the speaking rate value for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - value: the rate value to set. - """ - - voiceACSS = self._getACSSForVoiceType(voiceType) - voiceACSS[acss.ACSS.RATE] = value - voiceACSS['established'] = True - #settings.voices[voiceType] = voiceACSS - - def _getPitchForVoiceType(self, voiceType): - """Gets the pitch value for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - Returns the pitch value for the given voice type, or None if - not set. - """ - - return self._getKeyValueForVoiceType(voiceType, - acss.ACSS.AVERAGE_PITCH) - - def _setPitchForVoiceType(self, voiceType, value): - """Sets the pitch value for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - value: the pitch value to set. - """ - - voiceACSS = self._getACSSForVoiceType(voiceType) - voiceACSS[acss.ACSS.AVERAGE_PITCH] = value - voiceACSS['established'] = True - #settings.voices[voiceType] = voiceACSS - - def _getVolumeForVoiceType(self, voiceType): - """Gets the volume (gain) value for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - Returns the volume (gain) value for the given voice type, or - None if not set. - """ - - return self._getKeyValueForVoiceType(voiceType, acss.ACSS.GAIN) - - def _setVolumeForVoiceType(self, voiceType, value): - """Sets the volume (gain) value for the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - - value: the volume (gain) value to set. - """ - - voiceACSS = self._getACSSForVoiceType(voiceType) - voiceACSS[acss.ACSS.GAIN] = value - voiceACSS['established'] = True - #settings.voices[voiceType] = voiceACSS - - def _setVoiceSettingsForVoiceType(self, voiceType): - """Sets the family, rate, pitch and volume GUI components based - on the given voice type. - - Arguments: - - voiceType: one of DEFAULT, UPPERCASE, HYPERLINK, SYSTEM - """ - - familyName = self._getFamilyNameForVoiceType(voiceType) - self._setSpeechFamiliesChoice(familyName) - - rate = self._getRateForVoiceType(voiceType) - if rate is not None: - self.get_widget("rateScale").set_value(rate) - else: - self.get_widget("rateScale").set_value(50.0) - - pitch = self._getPitchForVoiceType(voiceType) - if pitch is not None: - self.get_widget("pitchScale").set_value(pitch) - else: - self.get_widget("pitchScale").set_value(5.0) - - volume = self._getVolumeForVoiceType(voiceType) - if volume is not None: - self.get_widget("volumeScale").set_value(volume) - else: - self.get_widget("volumeScale").set_value(10.0) - - def _setSpeechFamiliesChoice(self, familyName): - """Sets the active item in the families ("Person:") combo box - to the given family name. - - Arguments: - - familyName: the family name to use to set the active combo box item. - """ - - if len(self.speechFamilies) == 0: - return - - languageSet = False - familySet = False - for family in self.speechFamilies: - name = family[speechserver.VoiceFamily.NAME] - if name == familyName: - lang = family[speechserver.VoiceFamily.LANG] - dialect = family[speechserver.VoiceFamily.DIALECT] - - if dialect: - language = lang + '-' + dialect - else: - language = lang - - i = 0 - for languageChoice in self.speechLanguagesChoices: - if languageChoice == language: - self.get_widget("speechLanguages").set_active(i) - self.speechLanguagesChoice = self.speechLanguagesChoices[i] - languageSet = True - - self._setupFamilies() - - i = 0 - for familyChoice in self.speechFamiliesChoices: - name = familyChoice[speechserver.VoiceFamily.NAME] - if name == familyName: - self._setSpeechFamiliesActive(i) - self.speechFamiliesChoice = self.speechFamiliesChoices[i] - familySet = True - break - i += 1 - - break - - i += 1 - - break - - if not languageSet: - tokens = ["PREFERENCES DIALOG: Could not find speech language match for", familyName] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.get_widget("speechLanguages").set_active(0) - self.speechLanguagesChoice = self.speechLanguagesChoices[0] - - if languageSet: - self.selectedLanguageChoices[self.speechServersChoice] = i - - if not familySet: - tokens = ["PREFERENCES DIALOG: Could not find speech family match for", familyName] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._setSpeechFamiliesActive(0) - self.speechFamiliesChoice = self.speechFamiliesChoices[0] - - if familySet: - self.selectedFamilyChoices[self.speechServersChoice, - self.speechLanguagesChoice] = i - - def _setSpeechFamiliesActive(self, index): - """Sets speechFamilies active index while suppressing preview chatter.""" - - self._updatingSpeechFamilies = True - try: - self.get_widget("speechFamilies").set_active(index) - finally: - self._updatingSpeechFamilies = False - - def _setupFamilies(self): - """Gets the list of voice variants for the current speech server and - current language. - If there are variants, get the information associated with - each voice variant and add an entry for it to the variants - GtkComboBox list. - """ - - combobox = self.get_widget("speechFamilies") - combobox.set_model(None) - self.speechFamiliesModel.clear() - - currentLanguage = self.speechLanguagesChoice - - i = 0 - self.speechFamiliesChoices = [] - for family in self.speechFamilies: - lang = family[speechserver.VoiceFamily.LANG] - dialect = family[speechserver.VoiceFamily.DIALECT] - - if dialect: - language = lang + '-' + dialect - else: - language = lang - - if language != currentLanguage: - continue - - name = family[speechserver.VoiceFamily.NAME] - self.speechFamiliesChoices.append(family) - self.speechFamiliesModel.append((i, name)) - i += 1 - - combobox.set_model(self.speechFamiliesModel) - if i == 0: - tokens = ["No speech family was available for", str(currentLanguage), "."] - debug.printTokens(debug.LEVEL_SEVERE, tokens, True) - debug.printStack(debug.LEVEL_FINEST) - self.speechFamiliesChoice = None - return - - # If user manually selected a family for the current speech server - # this choice it's restored. In other case the first family - # (usually the default one) is selected - # - selectedIndex = 0 - if (self.speechServersChoice, self.speechLanguagesChoice) \ - in self.selectedFamilyChoices: - selectedIndex = self.selectedFamilyChoices[self.speechServersChoice, - self.speechLanguagesChoice] - - self._setSpeechFamiliesActive(selectedIndex) - - def _setSpeechLanguagesChoice(self, languageName): - """Sets the active item in the languages ("Language:") combo box - to the given language name. - - Arguments: - - languageName: the language name to use to set the active combo box item. - """ - - if len(self.speechLanguagesChoices) == 0: - return - - valueSet = False - i = 0 - for language in self.speechLanguagesChoices: - if language == languageName: - self.get_widget("speechLanguages").set_active(i) - self.speechLanguagesChoice = self.speechLanguagesChoices[i] - valueSet = True - break - i += 1 - - if not valueSet: - tokens = ["PREFERENCES DIALOG: Could not find speech language match for", languageName] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.get_widget("speechLanguages").set_active(0) - self.speechLanguagesChoice = self.speechLanguagesChoices[0] - - if valueSet: - self.selectedLanguageChoices[self.speechServersChoice] = i - - self._setupFamilies() - - def _setupVoices(self): - """Gets the list of voices for the current speech server. - If there are families, get the information associated with - each voice family and add an entry for it to the families - GtkComboBox list. - """ - - combobox = self.get_widget("speechLanguages") - combobox.set_model(None) - self.speechLanguagesModel.clear() - self.speechFamilies = self.speechServersChoice.getVoiceFamilies() - self.speechLanguagesChoices = [] - - if len(self.speechFamilies) == 0: - debug.printMessage(debug.LEVEL_SEVERE, "No speech voice was available.") - debug.printStack(debug.LEVEL_FINEST) - self.speechLanguagesChoice = None - return - - done = {} - i = 0 - for family in self.speechFamilies: - lang = family[speechserver.VoiceFamily.LANG] - dialect = family[speechserver.VoiceFamily.DIALECT] - if (lang,dialect) in done: - continue - done[lang,dialect] = True - - if dialect: - language = lang + '-' + dialect - else: - language = lang - - # TODO: get translated language name from CLDR or such - msg = language - if msg == "": - # Unsupported locale - msg = "default language" - - self.speechLanguagesChoices.append(language) - self.speechLanguagesModel.append((i, msg)) - i += 1 - - # If user manually selected a language for the current speech server - # this choice it's restored. In other case the first language - # (usually the default one) is selected - # - selectedIndex = 0 - if self.speechServersChoice in self.selectedLanguageChoices: - selectedIndex = self.selectedLanguageChoices[self.speechServersChoice] - - combobox.set_model(self.speechLanguagesModel) - - self.get_widget("speechLanguages").set_active(selectedIndex) - if self.initializingSpeech: - self.speechLanguagesChoice = self.speechLanguagesChoices[selectedIndex] - - self._setupFamilies() - - # The family name will be selected as part of selecting the - # voice type. Whenever the families change, we'll reset the - # voice type selection to the first one ("Default"). - # - comboBox = self.get_widget("voiceTypesCombo") - types = [guilabels.SPEECH_VOICE_TYPE_DEFAULT, - guilabels.SPEECH_VOICE_TYPE_UPPERCASE, - guilabels.SPEECH_VOICE_TYPE_HYPERLINK, - guilabels.SPEECH_VOICE_TYPE_SYSTEM] - self.populateComboBox(comboBox, types) - comboBox.set_active(DEFAULT) - voiceType = comboBox.get_active() - self._setVoiceSettingsForVoiceType(voiceType) - - def _setSpeechServersChoice(self, serverInfo): - """Sets the active item in the speech servers combo box to the - given server. - - Arguments: - - serversChoices: the list of available speech servers. - - serverInfo: the speech server to use to set the active combo - box item. - """ - - if len(self.speechServersChoices) == 0: - return - - # We'll fallback to whatever we happen to be using in the event - # that this preference has never been set. - # - if not serverInfo: - serverInfo = speech.getInfo() - if serverInfo and len(serverInfo) >= 2 and serverInfo[1] == 'default': - defaultFamily = None - voices = self.prefsDict.get("voices", {}) - defaultVoice = voices.get(settings.DEFAULT_VOICE) if voices else None - if defaultVoice: - defaultFamily = acss.ACSS(defaultVoice).get(acss.ACSS.FAMILY) - - resolved = self._resolveSpeechDispatcherServerForFamily(defaultFamily) - if resolved is not None: - serverInfo = resolved.getInfo() - - valueSet = False - i = 0 - for server in self.speechServersChoices: - if serverInfo == server.getInfo(): - self.get_widget("speechServers").set_active(i) - self.speechServersChoice = server - valueSet = True - break - i += 1 - - if not valueSet: - tokens = ["PREFERENCES DIALOG: Could not find speech server match for", serverInfo] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.get_widget("speechServers").set_active(0) - self.speechServersChoice = self.speechServersChoices[0] - - self._setupVoices() - - def _setupSpeechServers(self): - """Gets the list of speech servers for the current speech factory. - If there are servers, get the information associated with each - speech server and add an entry for it to the speechServers - GtkComboBox list. Set the current choice to be the first item. - """ - - combobox = self.get_widget("speechServers") - combobox.set_model(None) - self.speechServersModel.clear() - self.speechServersChoices = \ - self.speechSystemsChoice.SpeechServer.getSpeechServers() - if len(self.speechServersChoices) == 0: - debug.printMessage(debug.LEVEL_SEVERE, "Speech not available.") - debug.printStack(debug.LEVEL_FINEST) - self.speechServersChoice = None - self.speechLanguagesChoices = [] - self.speechLanguagesChoice = None - self.speechFamiliesChoices = [] - self.speechFamiliesChoice = None - combobox.set_model(self.speechServersModel) - return - - i = 0 - for server in self.speechServersChoices: - name = server.getInfo()[0] - self.speechServersModel.append((i, name)) - i += 1 - - combobox.set_model(self.speechServersModel) - self._setSpeechServersChoice(self.prefsDict["speechServerInfo"]) - - def _setSpeechSystemsChoice(self, systemName): - """Set the active item in the speech systems combo box to the - given system name. - - Arguments: - - factoryChoices: the list of available speech factories (systems). - - systemName: the speech system name to use to set the active combo - box item. - """ - - systemName = systemName.strip("'") - - if len(self.speechSystemsChoices) == 0: - self.speechSystemsChoice = None - return - - valueSet = False - i = 0 - for speechSystem in self.speechSystemsChoices: - name = speechSystem.__name__ - if name.endswith(systemName): - self.get_widget("speechSystems").set_active(i) - self.speechSystemsChoice = self.speechSystemsChoices[i] - valueSet = True - break - i += 1 - - if not valueSet: - tokens = ["PREFERENCES DIALOG: Could not find speech system match for", systemName] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.get_widget("speechSystems").set_active(0) - self.speechSystemsChoice = self.speechSystemsChoices[0] - - self._setupSpeechServers() - - def _setupSpeechSystems(self, factories): - """Sets up the speech systems combo box and sets the selection - to the preferred speech system. - - Arguments: - -factories: the list of known speech factories (working or not) - """ - - combobox = self.get_widget("speechSystems") - combobox.set_model(None) - self.speechSystemsModel.clear() - self.workingFactories = [] - for factory in factories: - try: - servers = factory.SpeechServer.getSpeechServers() - if len(servers): - self.workingFactories.append(factory) - except Exception: - debug.printException(debug.LEVEL_FINEST) - - self.speechSystemsChoices = [] - if len(self.workingFactories) == 0: - debug.printMessage(debug.LEVEL_SEVERE, "Speech not available.") - debug.printStack(debug.LEVEL_FINEST) - self.speechSystemsChoice = None - self.speechServersChoices = [] - self.speechServersChoice = None - self.speechLanguagesChoices = [] - self.speechLanguagesChoice = None - self.speechFamiliesChoices = [] - self.speechFamiliesChoice = None - combobox.set_model(self.speechSystemsModel) - return - - i = 0 - for workingFactory in self.workingFactories: - self.speechSystemsChoices.append(workingFactory) - name = workingFactory.SpeechServer.getFactoryName() - self.speechSystemsModel.append((i, name)) - i += 1 - - combobox.set_model(self.speechSystemsModel) - if self.prefsDict["speechServerFactory"]: - self._setSpeechSystemsChoice(self.prefsDict["speechServerFactory"]) - else: - self.speechSystemsChoice = None - - def _initSpeechState(self): - """Initialize the various speech components. - """ - - voices = self.prefsDict["voices"] - self.defaultVoice = acss.ACSS(voices.get(settings.DEFAULT_VOICE)) - self.uppercaseVoice = acss.ACSS(voices.get(settings.UPPERCASE_VOICE)) - self.hyperlinkVoice = acss.ACSS(voices.get(settings.HYPERLINK_VOICE)) - self.systemVoice = acss.ACSS(voices.get(settings.SYSTEM_VOICE)) - - # Just a note on general naming pattern: - # - # * = The name of the combobox - # *Model = the name of the comobox model - # *Choices = the Cthulhu/speech python objects - # *Choice = a value from *Choices - # - # Where * = speechSystems, speechServers, speechLanguages, speechFamilies - # - factories = cthulhu.cthulhuApp.settingsManager.getSpeechServerFactories() - if len(factories) == 0 or not self.prefsDict.get('enableSpeech', True): - self.workingFactories = [] - self.speechSystemsChoice = None - self.speechServersChoices = [] - self.speechServersChoice = None - self.speechLanguagesChoices = [] - self.speechLanguagesChoice = None - self.speechFamiliesChoices = [] - self.speechFamiliesChoice = None - return - - try: - speech.init() - except Exception: - self.workingFactories = [] - self.speechSystemsChoice = None - self.speechServersChoices = [] - self.speechServersChoice = None - self.speechLanguagesChoices = [] - self.speechLanguagesChoice = None - self.speechFamiliesChoices = [] - self.speechFamiliesChoice = None - return - - # This cascades into systems->servers->voice_type->families... - # - self.initializingSpeech = True - self._setupSpeechSystems(factories) - self._setupHardwareDevice() - self._updateHardwareDeviceVisibility() - self.initializingSpeech = False - - def _getSpeechDispatcherFactory(self): - """Returns the Speech Dispatcher factory if available.""" - - factories = cthulhu.cthulhuApp.settingsManager.getSpeechServerFactories() - for factory in factories: - try: - if factory.SpeechServer.getFactoryName() == guilabels.SPEECH_DISPATCHER: - return factory - except Exception: - debug.printException(debug.LEVEL_FINEST) - - return None - - def _setEchoVoiceFamily(self, family): - """Sets echo voice family from the selected server family object.""" - - if not family: - return - - name = family.get(speechserver.VoiceFamily.NAME) - language = family.get(speechserver.VoiceFamily.LANG) - dialect = family.get(speechserver.VoiceFamily.DIALECT) - variant = family.get(speechserver.VoiceFamily.VARIANT) - self.echoVoice[acss.ACSS.FAMILY] = { - speechserver.VoiceFamily.NAME: name, - speechserver.VoiceFamily.LANG: language, - speechserver.VoiceFamily.DIALECT: dialect, - speechserver.VoiceFamily.VARIANT: variant, - } - self.echoVoice['established'] = True - - def _resolveSpeechDispatcherServerForFamily(self, family): - """Returns a concrete Speech Dispatcher server matching the voice family.""" - - if not family or not self.speechServersChoices: - return None - - name = family.get(speechserver.VoiceFamily.NAME) - language = family.get(speechserver.VoiceFamily.LANG) - dialect = family.get(speechserver.VoiceFamily.DIALECT) - variant = family.get(speechserver.VoiceFamily.VARIANT) - if not name: - return None - - for server in self.speechServersChoices: - info = server.getInfo() - if not info or len(info) < 2 or info[1] == 'default': - continue - - try: - families = server.getVoiceFamilies() - except Exception: - debug.printException(debug.LEVEL_FINEST) - continue - - for candidate in families: - if candidate.get(speechserver.VoiceFamily.NAME) != name: - continue - if candidate.get(speechserver.VoiceFamily.LANG) != language: - continue - if candidate.get(speechserver.VoiceFamily.DIALECT) != dialect: - continue - if candidate.get(speechserver.VoiceFamily.VARIANT) != variant: - continue - - tokens = [ - "PREFERENCES DIALOG: Resolved voice family", - name, - "to speech server", - info, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return server - - tokens = [ - "PREFERENCES DIALOG: Could not resolve speech server for family", - family, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - def _getSpeechServerChoiceForSave(self): - """Returns the server choice that should be persisted for speech settings.""" - - server = self.speechServersChoice - if not server or self.speechSystemsChoice != self._getSpeechDispatcherFactory(): - return server - - info = server.getInfo() - if not info or len(info) < 2 or info[1] != 'default': - return server - - defaultFamily = None - if self.defaultVoice is not None: - defaultFamily = self.defaultVoice.get(acss.ACSS.FAMILY) - - resolved = self._resolveSpeechDispatcherServerForFamily(defaultFamily) - return resolved or server - - def _getEchoSpeechServerFamilyForSave(self): - """Returns the most specific echo family to use for server resolution.""" - - family = None - if self.echoVoice is not None: - family = self.echoVoice.get(acss.ACSS.FAMILY) - - if family: - return family - - if self.defaultVoice is not None: - return self.defaultVoice.get(acss.ACSS.FAMILY) - - return None - - def _getEchoSpeechServerChoiceForSave(self): - """Returns the echo speech server choice that should be persisted.""" - - server = self.echoSpeechServersChoice - if server is None: - return None - - info = server.getInfo() - if not info or len(info) < 2 or info[1] != 'default': - return server - - family = self._getEchoSpeechServerFamilyForSave() - resolved = self._resolveSpeechDispatcherServerForFamily(family) - if resolved is not None: - return resolved - - speechServer = self._getSpeechServerChoiceForSave() - if speechServer is not None: - speechInfo = speechServer.getInfo() - if speechInfo and len(speechInfo) >= 2 and speechInfo[1] != 'default': - tokens = [ - "PREFERENCES DIALOG: Falling back to main speech server for echo", - speechInfo, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return speechServer - - return server - - def _populateEchoSpeechFamilies(self, families): - """Populate the echo family combobox from the provided families list.""" - - combobox = self.get_widget("echoSpeechFamilies") - combobox.set_model(None) - self.echoSpeechFamiliesModel.clear() - self.echoSpeechFamiliesChoices = list(families or []) - self.echoSpeechFamiliesChoice = None - - selectedIndex = 0 - selectedMatchFound = False - selectedFamily = self.echoVoice.get(acss.ACSS.FAMILY) - selectedName = selectedLanguage = selectedDialect = selectedVariant = None - if selectedFamily: - selectedName = selectedFamily.get(speechserver.VoiceFamily.NAME) - selectedLanguage = selectedFamily.get(speechserver.VoiceFamily.LANG) - selectedDialect = selectedFamily.get(speechserver.VoiceFamily.DIALECT) - selectedVariant = selectedFamily.get(speechserver.VoiceFamily.VARIANT) - - for i, family in enumerate(self.echoSpeechFamiliesChoices): - name = family.get(speechserver.VoiceFamily.NAME) or "" - language = family.get(speechserver.VoiceFamily.LANG) or "" - dialect = family.get(speechserver.VoiceFamily.DIALECT) or "" - variant = family.get(speechserver.VoiceFamily.VARIANT) - display = name - locale = language - if dialect: - locale = f"{language}-{dialect}" if language else dialect - if locale: - display = f"{name} ({locale})" - self.echoSpeechFamiliesModel.append((i, display)) - if selectedName == name and selectedLanguage == language \ - and selectedDialect == dialect and selectedVariant == variant: - selectedIndex = i - selectedMatchFound = True - - combobox.set_model(self.echoSpeechFamiliesModel) - if self.echoSpeechFamiliesChoices: - self._updatingEchoSpeechFamilies = True - try: - combobox.set_active(selectedIndex) - finally: - self._updatingEchoSpeechFamilies = False - self.echoSpeechFamiliesChoice = self.echoSpeechFamiliesChoices[selectedIndex] - - def _fetchEchoSpeechFamiliesWorker(self, serverInfo, requestToken): - """Fetch module-specific voices in a subprocess and apply asynchronously.""" - - queryScript = """ -import json -import sys -from cthulhu import speechdispatcherfactory -from cthulhu import speechserver - -serverInfo = json.loads(sys.argv[1]) -if isinstance(serverInfo, list): - serverInfo = tuple(serverInfo) - -server = speechdispatcherfactory.SpeechServer.getSpeechServer(serverInfo) -families = server.getVoiceFamilies() if server else [] - -result = [] -for family in families: - result.append({ - "name": family.get(speechserver.VoiceFamily.NAME), - "lang": family.get(speechserver.VoiceFamily.LANG), - "dialect": family.get(speechserver.VoiceFamily.DIALECT), - "variant": family.get(speechserver.VoiceFamily.VARIANT), - }) - -print(json.dumps(result)) -""" - - familyDefs = None - try: - completed = subprocess.run( - [sys.executable, "-c", queryScript, json.dumps(serverInfo)], - capture_output=True, - text=True, - timeout=4.0, - check=False, - ) - if completed.returncode == 0 and completed.stdout.strip(): - familyDefs = json.loads(completed.stdout.strip()) - else: - tokens = [ - "PREFERENCES DIALOG: Echo voice fetch failed for", - serverInfo, - "rc=", - completed.returncode, - ] - debug.printTokens(debug.LEVEL_WARNING, tokens, True) - except subprocess.TimeoutExpired: - tokens = ["PREFERENCES DIALOG: Echo voice fetch timed out for", serverInfo] - debug.printTokens(debug.LEVEL_WARNING, tokens, True) - except Exception: - debug.printException(debug.LEVEL_WARNING) - - GLib.idle_add(self._applyFetchedEchoSpeechFamilies, requestToken, familyDefs) - - def _applyFetchedEchoSpeechFamilies(self, requestToken, familyDefs): - """Apply fetched echo families if this is still the active request.""" - - if requestToken != self._echoVoiceFetchToken: - return False - - if not isinstance(familyDefs, list): - return False - - families = [] - for familyDef in familyDefs: - if not isinstance(familyDef, dict): - continue - families.append( - speechserver.VoiceFamily({ - speechserver.VoiceFamily.NAME: familyDef.get("name"), - speechserver.VoiceFamily.LANG: familyDef.get("lang"), - speechserver.VoiceFamily.DIALECT: familyDef.get("dialect"), - speechserver.VoiceFamily.VARIANT: familyDef.get("variant"), - }) - ) - - if not families: - return False - - self._populateEchoSpeechFamilies(families) - return False - - def _setupEchoSpeechFamilies(self): - """Populate echo voice family list for the current echo server.""" - self._echoVoiceFetchToken += 1 - requestToken = self._echoVoiceFetchToken - useCustomModule = self.get_widget("useCustomEchoSpeechServerCheckButton").get_active() - fallbackFamilies = list(self.speechFamiliesChoices or []) - self._populateEchoSpeechFamilies(fallbackFamilies) - - if useCustomModule and self.echoSpeechServersChoice: - serverInfo = self.echoSpeechServersChoice.getInfo() - thread = threading.Thread( - target=self._fetchEchoSpeechFamiliesWorker, - args=(serverInfo, requestToken), - daemon=True, - ) - thread.start() - - def _setEchoSpeechServersChoice(self, serverInfo): - """Set the active echo module based on stored server info.""" - - if not self.echoSpeechServersChoices: - self.echoSpeechServersChoice = None - self._setupEchoSpeechFamilies() - return - - if serverInfo and len(serverInfo) >= 2 and serverInfo[1] == 'default': - family = self._getEchoSpeechServerFamilyForSave() - resolved = self._resolveSpeechDispatcherServerForFamily(family) - if resolved is None: - speechServer = self._getSpeechServerChoiceForSave() - if speechServer is not None: - speechInfo = speechServer.getInfo() - if speechInfo and len(speechInfo) >= 2 and speechInfo[1] != 'default': - resolved = speechServer - tokens = [ - "PREFERENCES DIALOG: Reusing main speech server for echo", - speechInfo, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if resolved is not None: - serverInfo = resolved.getInfo() - - valueSet = False - for i, server in enumerate(self.echoSpeechServersChoices): - info = server.getInfo() - if serverInfo and info == serverInfo: - self.get_widget("echoSpeechServers").set_active(i) - self.echoSpeechServersChoice = server - valueSet = True - break - - if not valueSet: - self.get_widget("echoSpeechServers").set_active(0) - self.echoSpeechServersChoice = self.echoSpeechServersChoices[0] - - self._setupEchoSpeechFamilies() - - def _setupEchoSpeechServers(self): - """Populate available speech-dispatcher modules for echo.""" - - combobox = self.get_widget("echoSpeechServers") - combobox.set_model(None) - self.echoSpeechServersModel.clear() - self.echoSpeechServersChoices = [] - self.echoSpeechServersChoice = None - - if not self.prefsDict.get('enableSpeech', True): - combobox.set_model(self.echoSpeechServersModel) - self._setupEchoSpeechFamilies() - return - - factory = self._getSpeechDispatcherFactory() - if factory is None: - combobox.set_model(self.echoSpeechServersModel) - self._setupEchoSpeechFamilies() - return - - try: - self.echoSpeechServersChoices = factory.SpeechServer.getSpeechServers() - except Exception: - debug.printException(debug.LEVEL_WARNING) - self.echoSpeechServersChoices = [] - - for i, server in enumerate(self.echoSpeechServersChoices): - name = server.getInfo()[0] - self.echoSpeechServersModel.append((i, name)) - - combobox.set_model(self.echoSpeechServersModel) - self._setEchoSpeechServersChoice(self.prefsDict.get("echoSpeechServerInfo")) - - def _initEchoSpeechState(self): - """Initialize echo voice controls and choices.""" - - self.echoVoice = acss.ACSS( - self.prefsDict.get("echoVoice", settings.echoVoice) or {}) - - baseVoice = self.defaultVoice or acss.ACSS( - self.prefsDict.get("voices", {}).get(settings.DEFAULT_VOICE, {})) - - rate = self.echoVoice.get(acss.ACSS.RATE, baseVoice.get(acss.ACSS.RATE, 50.0)) - pitch = self.echoVoice.get(acss.ACSS.AVERAGE_PITCH, baseVoice.get(acss.ACSS.AVERAGE_PITCH, 5.0)) - volume = self.echoVoice.get(acss.ACSS.GAIN, baseVoice.get(acss.ACSS.GAIN, 10.0)) - - self.get_widget("echoRateScale").set_value(rate) - self.get_widget("echoPitchScale").set_value(pitch) - self.get_widget("echoVolumeScale").set_value(volume) - - self.initializingEchoSpeech = True - self._setupEchoSpeechServers() - self.initializingEchoSpeech = False - - self._setEchoVoiceItems() - - def _setSpokenTextAttributes(self, view, setAttributes, - state, moveToTop=False): - """Given a set of spoken text attributes, update the model used by the - text attribute tree view. - - Arguments: - - view: the text attribute tree view. - - setAttributes: the list of spoken text attributes to update. - - state: the state (True or False) that they all should be set to. - - moveToTop: if True, move these attributes to the top of the list. - """ - - model = view.get_model() - view.set_model(None) - - [attrList, attrDict] = \ - self.script.utilities.stringToKeysAndDict(setAttributes) - [allAttrList, allAttrDict] = self.script.utilities.stringToKeysAndDict( - cthulhu.cthulhuApp.settingsManager.getSetting('allTextAttributes')) - - for i in range(0, len(attrList)): - for path in range(0, len(allAttrList)): - localizedKey = text_attribute_names.getTextAttributeName( - attrList[i], self.script) - localizedValue = text_attribute_names.getTextAttributeName( - attrDict[attrList[i]], self.script) - if localizedKey == model[path][NAME]: - thisIter = model.get_iter(path) - model.set_value(thisIter, NAME, localizedKey) - model.set_value(thisIter, IS_SPOKEN, state) - model.set_value(thisIter, VALUE, localizedValue) - if moveToTop: - thisIter = model.get_iter(path) - otherIter = model.get_iter(i) - model.move_before(thisIter, otherIter) - break - - view.set_model(model) - - def _setBrailledTextAttributes(self, view, setAttributes, state): - """Given a set of brailled text attributes, update the model used - by the text attribute tree view. - - Arguments: - - view: the text attribute tree view. - - setAttributes: the list of brailled text attributes to update. - - state: the state (True or False) that they all should be set to. - """ - - model = view.get_model() - view.set_model(None) - - [attrList, attrDict] = \ - self.script.utilities.stringToKeysAndDict(setAttributes) - [allAttrList, allAttrDict] = self.script.utilities.stringToKeysAndDict( - cthulhu.cthulhuApp.settingsManager.getSetting('allTextAttributes')) - - for i in range(0, len(attrList)): - for path in range(0, len(allAttrList)): - localizedKey = text_attribute_names.getTextAttributeName( - attrList[i], self.script) - if localizedKey == model[path][NAME]: - thisIter = model.get_iter(path) - model.set_value(thisIter, IS_BRAILLED, state) - break - - view.set_model(model) - - def _getAppNameForAttribute(self, attributeName): - """Converts the given Atk attribute name into the application's - equivalent. This is necessary because an application or toolkit - (e.g. Gecko) might invent entirely new names for the same text - attributes. - - Arguments: - - attribName: The name of the text attribute - - Returns the application's equivalent name if found or attribName - otherwise. - """ - - return self.script.utilities.getAppNameForAttribute(attributeName) - - def _updateTextDictEntry(self): - """The user has updated the text attribute list in some way. Update - the "enabledSpokenTextAttributes" and "enabledBrailledTextAttributes" - preference strings to reflect the current state of the corresponding - text attribute lists. - """ - - model = self.getTextAttributesView.get_model() - spokenAttrStr = "" - brailledAttrStr = "" - noRows = model.iter_n_children(None) - for path in range(0, noRows): - localizedKey = model[path][NAME] - key = text_attribute_names.getTextAttributeKey(localizedKey) - - # Convert the normalized, Atk attribute name back into what - # the app/toolkit uses. - # - key = self._getAppNameForAttribute(key) - - localizedValue = model[path][VALUE] - value = text_attribute_names.getTextAttributeKey(localizedValue) - - if model[path][IS_SPOKEN]: - spokenAttrStr += key + ":" + value + "; " - if model[path][IS_BRAILLED]: - brailledAttrStr += key + ":" + value + "; " - - self.prefsDict["enabledSpokenTextAttributes"] = spokenAttrStr - self.prefsDict["enabledBrailledTextAttributes"] = brailledAttrStr - - def contractedBrailleToggled(self, checkbox): - grid = self.get_widget('contractionTableGrid') - grid.set_sensitive(checkbox.get_active()) - self.prefsDict["enableContractedBraille"] = checkbox.get_active() - - def contractionTableComboChanged(self, combobox): - model = combobox.get_model() - myIter = combobox.get_active_iter() - self.prefsDict["brailleContractionTable"] = model[myIter][1] - - def flashPersistenceToggled(self, checkbox): - grid = self.get_widget('flashMessageDurationGrid') - grid.set_sensitive(not checkbox.get_active()) - self.prefsDict["flashIsPersistent"] = checkbox.get_active() - - def textAttributeSpokenToggled(self, cell, path, model): - """The user has toggled the state of one of the text attribute - checkboxes to be spoken. Update our model to reflect this, then - update the "enabledSpokenTextAttributes" preference string. - - Arguments: - - cell: the cell that changed. - - path: the path of that cell. - - model: the model that the cell is part of. - """ - - thisIter = model.get_iter(path) - model.set(thisIter, IS_SPOKEN, not model[path][IS_SPOKEN]) - self._updateTextDictEntry() - - def textAttributeBrailledToggled(self, cell, path, model): - """The user has toggled the state of one of the text attribute - checkboxes to be brailled. Update our model to reflect this, - then update the "enabledBrailledTextAttributes" preference string. - - Arguments: - - cell: the cell that changed. - - path: the path of that cell. - - model: the model that the cell is part of. - """ - - thisIter = model.get_iter(path) - model.set(thisIter, IS_BRAILLED, not model[path][IS_BRAILLED]) - self._updateTextDictEntry() - - def textAttrValueEdited(self, cell, path, new_text, model): - """The user has edited the value of one of the text attributes. - Update our model to reflect this, then update the - "enabledSpokenTextAttributes" and "enabledBrailledTextAttributes" - preference strings. - - Arguments: - - cell: the cell that changed. - - path: the path of that cell. - - new_text: the new text attribute value string. - - model: the model that the cell is part of. - """ - - thisIter = model.get_iter(path) - model.set(thisIter, VALUE, new_text) - self._updateTextDictEntry() - - def textAttrCursorChanged(self, widget): - """Set the search column in the text attribute tree view - depending upon which column the user currently has the cursor in. - """ - - [path, focusColumn] = self.getTextAttributesView.get_cursor() - if focusColumn: - noColumns = len(self.getTextAttributesView.get_columns()) - for i in range(0, noColumns): - col = self.getTextAttributesView.get_column(i) - if focusColumn == col: - self.getTextAttributesView.set_search_column(i) - break - - def _createTextAttributesTreeView(self): - """Create the text attributes tree view. The view is the - textAttributesTreeView GtkTreeView widget. The view will consist - of a list containing three columns: - IS_SPOKEN - a checkbox whose state indicates whether this text - attribute will be spoken or not. - NAME - the text attribute name. - VALUE - if set, (and this attributes is enabled for speaking), - then this attribute will be spoken unless it equals - this value. - """ - - self.getTextAttributesView = self.get_widget("textAttributesTreeView") - - if self.getTextAttributesView.get_columns(): - for column in self.getTextAttributesView.get_columns(): - self.getTextAttributesView.remove_column(column) - - model = Gtk.ListStore(GObject.TYPE_STRING, - GObject.TYPE_BOOLEAN, - GObject.TYPE_BOOLEAN, - GObject.TYPE_STRING) - - # Initially setup the list store model based on the values of all - # the known text attributes. - # - [allAttrList, allAttrDict] = self.script.utilities.stringToKeysAndDict( - cthulhu.cthulhuApp.settingsManager.getSetting('allTextAttributes')) - for i in range(0, len(allAttrList)): - thisIter = model.append() - localizedKey = text_attribute_names.getTextAttributeName( - allAttrList[i], self.script) - localizedValue = text_attribute_names.getTextAttributeName( - allAttrDict[allAttrList[i]], self.script) - model.set_value(thisIter, NAME, localizedKey) - model.set_value(thisIter, IS_SPOKEN, False) - model.set_value(thisIter, IS_BRAILLED, False) - model.set_value(thisIter, VALUE, localizedValue) - - self.getTextAttributesView.set_model(model) - - # Attribute Name column (NAME). - column = Gtk.TreeViewColumn(guilabels.TEXT_ATTRIBUTE_NAME) - column.set_min_width(250) - column.set_resizable(True) - renderer = Gtk.CellRendererText() - column.pack_end(renderer, True) - column.add_attribute(renderer, 'text', NAME) - self.getTextAttributesView.insert_column(column, 0) - - # Attribute Speak column (IS_SPOKEN). - speakAttrColumnLabel = guilabels.PRESENTATION_SPEAK - column = Gtk.TreeViewColumn(speakAttrColumnLabel) - renderer = Gtk.CellRendererToggle() - column.pack_start(renderer, False) - column.add_attribute(renderer, 'active', IS_SPOKEN) - renderer.connect("toggled", - self.textAttributeSpokenToggled, - model) - self.getTextAttributesView.insert_column(column, 1) - column.clicked() - - # Attribute Mark in Braille column (IS_BRAILLED). - markAttrColumnLabel = guilabels.PRESENTATION_MARK_IN_BRAILLE - column = Gtk.TreeViewColumn(markAttrColumnLabel) - renderer = Gtk.CellRendererToggle() - column.pack_start(renderer, False) - column.add_attribute(renderer, 'active', IS_BRAILLED) - renderer.connect("toggled", - self.textAttributeBrailledToggled, - model) - self.getTextAttributesView.insert_column(column, 2) - column.clicked() - - # Attribute Value column (VALUE) - column = Gtk.TreeViewColumn(guilabels.PRESENTATION_PRESENT_UNLESS) - renderer = Gtk.CellRendererText() - renderer.set_property('editable', True) - column.pack_end(renderer, True) - column.add_attribute(renderer, 'text', VALUE) - renderer.connect("edited", self.textAttrValueEdited, model) - - self.getTextAttributesView.insert_column(column, 4) - - # Check all the enabled (spoken) text attributes. - # - self._setSpokenTextAttributes( - self.getTextAttributesView, - cthulhu.cthulhuApp.settingsManager.getSetting('enabledSpokenTextAttributes'), - True, True) - - # Check all the enabled (brailled) text attributes. - # - self._setBrailledTextAttributes( - self.getTextAttributesView, - cthulhu.cthulhuApp.settingsManager.getSetting('enabledBrailledTextAttributes'), - True) - - # Connect a handler for when the user changes columns within the - # view, so that we can adjust the search column for item lookups. - # - self.getTextAttributesView.connect("cursor_changed", - self.textAttrCursorChanged) - - def pronActualValueEdited(self, cell, path, new_text, model): - """The user has edited the value of one of the actual strings in - the pronunciation dictionary. Update our model to reflect this. - - Arguments: - - cell: the cell that changed. - - path: the path of that cell. - - new_text: the new pronunciation dictionary actual string. - - model: the model that the cell is part of. - """ - - thisIter = model.get_iter(path) - model.set(thisIter, ACTUAL, new_text) - - def pronReplacementValueEdited(self, cell, path, new_text, model): - """The user has edited the value of one of the replacement strings - in the pronunciation dictionary. Update our model to reflect this. - - Arguments: - - cell: the cell that changed. - - path: the path of that cell. - - new_text: the new pronunciation dictionary replacement string. - - model: the model that the cell is part of. - """ - - thisIter = model.get_iter(path) - model.set(thisIter, REPLACEMENT, new_text) - - def pronunciationFocusChange(self, widget, event, isFocused): - """Callback for the pronunciation tree's focus-{in,out}-event signal.""" - - cthulhu.cthulhuApp.settingsManager.setSetting('usePronunciationDictionary', not isFocused) - - def pronunciationCursorChanged(self, widget): - """Set the search column in the pronunciation dictionary tree view - depending upon which column the user currently has the cursor in. - """ - - [path, focusColumn] = self.pronunciationView.get_cursor() - if focusColumn: - noColumns = len(self.pronunciationView.get_columns()) - for i in range(0, noColumns): - col = self.pronunciationView.get_column(i) - if focusColumn == col: - self.pronunciationView.set_search_column(i) - break - - def _createPronunciationTreeView(self): - """Create the pronunciation dictionary tree view. The view is the - pronunciationTreeView GtkTreeView widget. The view will consist - of a list containing two columns: - ACTUAL - the actual text string (word). - REPLACEMENT - the string that is used to pronounce that word. - """ - - self.pronunciationView = self.get_widget("pronunciationTreeView") - - if self.pronunciationView.get_columns(): - for column in self.pronunciationView.get_columns(): - self.pronunciationView.remove_column(column) - - model = Gtk.ListStore(GObject.TYPE_STRING, - GObject.TYPE_STRING) - - # Initially setup the list store model based on the values of all - # existing entries in the pronunciation dictionary -- unless it's - # the default script. - # - if not self.script.app: - _profile = self.prefsDict.get('activeProfile')[1] - pronDict = cthulhu.cthulhuApp.settingsManager.getPronunciations(_profile) - else: - pronDict = pronunciation_dict.pronunciation_dict - for pronKey in sorted(pronDict.keys()): - thisIter = model.append() - try: - actual, replacement = pronDict[pronKey] - except Exception: - # Try to do something sensible for the previous format of - # pronunciation dictionary entries. See bug #464754 for - # more details. - # - actual = pronKey - replacement = pronDict[pronKey] - model.set(thisIter, - ACTUAL, actual, - REPLACEMENT, replacement) - - self.pronunciationView.set_model(model) - - # Pronunciation Dictionary actual string (word) column (ACTUAL). - column = Gtk.TreeViewColumn(guilabels.DICTIONARY_ACTUAL_STRING) - column.set_min_width(250) - column.set_resizable(True) - renderer = Gtk.CellRendererText() - renderer.set_property('editable', True) - column.pack_end(renderer, True) - column.add_attribute(renderer, 'text', ACTUAL) - renderer.connect("edited", self.pronActualValueEdited, model) - self.pronunciationView.insert_column(column, 0) - - # Pronunciation Dictionary replacement string column (REPLACEMENT) - column = Gtk.TreeViewColumn(guilabels.DICTIONARY_REPLACEMENT_STRING) - renderer = Gtk.CellRendererText() - renderer.set_property('editable', True) - column.pack_end(renderer, True) - column.add_attribute(renderer, 'text', REPLACEMENT) - renderer.connect("edited", self.pronReplacementValueEdited, model) - self.pronunciationView.insert_column(column, 1) - - self.pronunciationModel = model - - # Connect a handler for when the user changes columns within the - # view, so that we can adjust the search column for item lookups. - # - self.pronunciationView.connect("cursor_changed", - self.pronunciationCursorChanged) - - self.pronunciationView.connect( - "focus_in_event", self.pronunciationFocusChange, True) - self.pronunciationView.connect( - "focus_out_event", self.pronunciationFocusChange, False) - - def _initGUIState(self): - """Adjust the settings of the various components on the - configuration GUI depending upon the users preferences. - """ - - prefs = self.prefsDict - - # Speech pane. - # - enable = prefs["enableSpeech"] - self.get_widget("speechSupportCheckButton").set_active(enable) - self.get_widget("speechOptionsGrid").set_sensitive(enable) - - enable = prefs["onlySpeakDisplayedText"] - self.get_widget("onlySpeakDisplayedTextCheckButton").set_active(enable) - self.get_widget("contextOptionsGrid").set_sensitive(not enable) - - if prefs["verbalizePunctuationStyle"] == \ - settings.PUNCTUATION_STYLE_NONE: - self.get_widget("noneButton").set_active(True) - elif prefs["verbalizePunctuationStyle"] == \ - settings.PUNCTUATION_STYLE_SOME: - self.get_widget("someButton").set_active(True) - elif prefs["verbalizePunctuationStyle"] == \ - settings.PUNCTUATION_STYLE_MOST: - self.get_widget("mostButton").set_active(True) - else: - self.get_widget("allButton").set_active(True) - - if prefs["speechVerbosityLevel"] == settings.VERBOSITY_LEVEL_BRIEF: - self.get_widget("speechBriefButton").set_active(True) - else: - self.get_widget("speechVerboseButton").set_active(True) - - self.get_widget("onlySpeakDisplayedTextCheckButton").set_active( - prefs["onlySpeakDisplayedText"]) - - - self.get_widget("speakBlankLinesCheckButton").set_active(\ - prefs["speakBlankLines"]) - self.get_widget("speakMultiCaseStringsAsWordsCheckButton").set_active(\ - prefs["speakMultiCaseStringsAsWords"]) - self.get_widget("speakNumbersAsDigitsCheckButton").set_active( - prefs.get("speakNumbersAsDigits", settings.speakNumbersAsDigits)) - self.get_widget("enableTutorialMessagesCheckButton").set_active(\ - prefs["enableTutorialMessages"]) - self.get_widget("enablePauseBreaksCheckButton").set_active(\ - prefs["enablePauseBreaks"]) - self.get_widget("enablePositionSpeakingCheckButton").set_active(\ - prefs["enablePositionSpeaking"]) - self.get_widget("enableMnemonicSpeakingCheckButton").set_active(\ - prefs["enableMnemonicSpeaking"]) - self.get_widget("speakMisspelledIndicatorCheckButton").set_active( - prefs.get("speakMisspelledIndicator", settings.speakMisspelledIndicator)) - self.get_widget("speakDescriptionCheckButton").set_active( - prefs.get("speakDescription", settings.speakDescription)) - self.get_widget("speakContextBlockquoteCheckButton").set_active( - prefs.get("speakContextBlockquote", settings.speakContextList)) - self.get_widget("speakContextLandmarkCheckButton").set_active( - prefs.get("speakContextLandmark", settings.speakContextLandmark)) - self.get_widget("speakContextNonLandmarkFormCheckButton").set_active( - prefs.get("speakContextNonLandmarkForm", settings.speakContextNonLandmarkForm)) - self.get_widget("speakContextListCheckButton").set_active( - prefs.get("speakContextList", settings.speakContextList)) - self.get_widget("speakContextPanelCheckButton").set_active( - prefs.get("speakContextPanel", settings.speakContextPanel)) - self.get_widget("speakContextTableCheckButton").set_active( - prefs.get("speakContextTable", settings.speakContextTable)) - - enable = prefs.get("messagesAreDetailed", settings.messagesAreDetailed) - self.get_widget("messagesAreDetailedCheckButton").set_active(enable) - - enable = prefs.get("useColorNames", settings.useColorNames) - self.get_widget("useColorNamesCheckButton").set_active(enable) - - enable = prefs.get("readFullRowInGUITable", settings.readFullRowInGUITable) - self.get_widget("readFullRowInGUITableCheckButton").set_active(enable) - - enable = prefs.get("readFullRowInDocumentTable", settings.readFullRowInDocumentTable) - self.get_widget("readFullRowInDocumentTableCheckButton").set_active(enable) - - enable = prefs.get("readFullRowInSpreadSheet", settings.readFullRowInSpreadSheet) - self.get_widget("readFullRowInSpreadSheetCheckButton").set_active(enable) - - style = prefs.get("capitalizationStyle", settings.capitalizationStyle) - combobox = self.get_widget("capitalizationStyle") - options = [guilabels.CAPITALIZATION_STYLE_NONE, - guilabels.CAPITALIZATION_STYLE_ICON, - guilabels.CAPITALIZATION_STYLE_SPELL] - self.populateComboBox(combobox, options) - if style == settings.CAPITALIZATION_STYLE_ICON: - value = guilabels.CAPITALIZATION_STYLE_ICON - elif style == settings.CAPITALIZATION_STYLE_SPELL: - value = guilabels.CAPITALIZATION_STYLE_SPELL - else: - value = guilabels.CAPITALIZATION_STYLE_NONE - combobox.set_active(options.index(value)) - - combobox2 = self.get_widget("dateFormatCombo") - sdtime = time.strftime - ltime = time.localtime - self.populateComboBox(combobox2, - [sdtime(messages.DATE_FORMAT_LOCALE, ltime()), - sdtime(messages.DATE_FORMAT_NUMBERS_DM, ltime()), - sdtime(messages.DATE_FORMAT_NUMBERS_MD, ltime()), - sdtime(messages.DATE_FORMAT_NUMBERS_DMY, ltime()), - sdtime(messages.DATE_FORMAT_NUMBERS_MDY, ltime()), - sdtime(messages.DATE_FORMAT_NUMBERS_YMD, ltime()), - sdtime(messages.DATE_FORMAT_FULL_DM, ltime()), - sdtime(messages.DATE_FORMAT_FULL_MD, ltime()), - sdtime(messages.DATE_FORMAT_FULL_DMY, ltime()), - sdtime(messages.DATE_FORMAT_FULL_MDY, ltime()), - sdtime(messages.DATE_FORMAT_FULL_YMD, ltime()), - sdtime(messages.DATE_FORMAT_ABBREVIATED_DM, ltime()), - sdtime(messages.DATE_FORMAT_ABBREVIATED_MD, ltime()), - sdtime(messages.DATE_FORMAT_ABBREVIATED_DMY, ltime()), - sdtime(messages.DATE_FORMAT_ABBREVIATED_MDY, ltime()), - sdtime(messages.DATE_FORMAT_ABBREVIATED_YMD, ltime()) - ]) - - indexdate = DATE_FORMAT_LOCALE - dateFormat = self.prefsDict["presentDateFormat"] - if dateFormat == messages.DATE_FORMAT_LOCALE: - indexdate = DATE_FORMAT_LOCALE - elif dateFormat == messages.DATE_FORMAT_NUMBERS_DM: - indexdate = DATE_FORMAT_NUMBERS_DM - elif dateFormat == messages.DATE_FORMAT_NUMBERS_MD: - indexdate = DATE_FORMAT_NUMBERS_MD - elif dateFormat == messages.DATE_FORMAT_NUMBERS_DMY: - indexdate = DATE_FORMAT_NUMBERS_DMY - elif dateFormat == messages.DATE_FORMAT_NUMBERS_MDY: - indexdate = DATE_FORMAT_NUMBERS_MDY - elif dateFormat == messages.DATE_FORMAT_NUMBERS_YMD: - indexdate = DATE_FORMAT_NUMBERS_YMD - elif dateFormat == messages.DATE_FORMAT_FULL_DM: - indexdate = DATE_FORMAT_FULL_DM - elif dateFormat == messages.DATE_FORMAT_FULL_MD: - indexdate = DATE_FORMAT_FULL_MD - elif dateFormat == messages.DATE_FORMAT_FULL_DMY: - indexdate = DATE_FORMAT_FULL_DMY - elif dateFormat == messages.DATE_FORMAT_FULL_MDY: - indexdate = DATE_FORMAT_FULL_MDY - elif dateFormat == messages.DATE_FORMAT_FULL_YMD: - indexdate = DATE_FORMAT_FULL_YMD - elif dateFormat == messages.DATE_FORMAT_ABBREVIATED_DM: - indexdate = DATE_FORMAT_ABBREVIATED_DM - elif dateFormat == messages.DATE_FORMAT_ABBREVIATED_MD: - indexdate = DATE_FORMAT_ABBREVIATED_MD - elif dateFormat == messages.DATE_FORMAT_ABBREVIATED_DMY: - indexdate = DATE_FORMAT_ABBREVIATED_DMY - elif dateFormat == messages.DATE_FORMAT_ABBREVIATED_MDY: - indexdate = DATE_FORMAT_ABBREVIATED_MDY - elif dateFormat == messages.DATE_FORMAT_ABBREVIATED_YMD: - indexdate = DATE_FORMAT_ABBREVIATED_YMD - combobox2.set_active (indexdate) - - combobox3 = self.get_widget("timeFormatCombo") - self.populateComboBox(combobox3, - [sdtime(messages.TIME_FORMAT_LOCALE, ltime()), - sdtime(messages.TIME_FORMAT_12_HM, ltime()), - sdtime(messages.TIME_FORMAT_12_HMS, ltime()), - sdtime(messages.TIME_FORMAT_24_HMS, ltime()), - sdtime(messages.TIME_FORMAT_24_HMS_WITH_WORDS, ltime()), - sdtime(messages.TIME_FORMAT_24_HM, ltime()), - sdtime(messages.TIME_FORMAT_24_HM_WITH_WORDS, ltime())]) - indextime = TIME_FORMAT_LOCALE - timeFormat = self.prefsDict["presentTimeFormat"] - if timeFormat == messages.TIME_FORMAT_LOCALE: - indextime = TIME_FORMAT_LOCALE - elif timeFormat == messages.TIME_FORMAT_12_HM: - indextime = TIME_FORMAT_12_HM - elif timeFormat == messages.TIME_FORMAT_12_HMS: - indextime = TIME_FORMAT_12_HMS - elif timeFormat == messages.TIME_FORMAT_24_HMS: - indextime = TIME_FORMAT_24_HMS - elif timeFormat == messages.TIME_FORMAT_24_HMS_WITH_WORDS: - indextime = TIME_FORMAT_24_HMS_WITH_WORDS - elif timeFormat == messages.TIME_FORMAT_24_HM: - indextime = TIME_FORMAT_24_HM - elif timeFormat == messages.TIME_FORMAT_24_HM_WITH_WORDS: - indextime = TIME_FORMAT_24_HM_WITH_WORDS - combobox3.set_active (indextime) - - self.get_widget("speakProgressBarUpdatesCheckButton").set_active( - prefs.get("speakProgressBarUpdates", settings.speakProgressBarUpdates)) - self.get_widget("brailleProgressBarUpdatesCheckButton").set_active( - prefs.get("brailleProgressBarUpdates", settings.brailleProgressBarUpdates)) - self.get_widget("beepProgressBarUpdatesCheckButton").set_active( - prefs.get("beepProgressBarUpdates", settings.beepProgressBarUpdates)) - - interval = prefs["progressBarUpdateInterval"] - self.get_widget("progressBarUpdateIntervalSpinButton").set_value(interval) - - comboBox = self.get_widget("progressBarVerbosity") - levels = [guilabels.PROGRESS_BAR_ALL, - guilabels.PROGRESS_BAR_APPLICATION, - guilabels.PROGRESS_BAR_WINDOW] - self.populateComboBox(comboBox, levels) - comboBox.set_active(prefs["progressBarVerbosity"]) - - enable = prefs["enableMouseReview"] - self.get_widget("enableMouseReviewCheckButton").set_active(enable) - - # Braille pane. - # - self.get_widget("enableBrailleCheckButton").set_active( \ - prefs["enableBraille"]) - state = prefs["brailleRolenameStyle"] == \ - settings.BRAILLE_ROLENAME_STYLE_SHORT - self.get_widget("abbrevRolenames").set_active(state) - - self.get_widget("disableBrailleEOLCheckButton").set_active( - prefs["disableBrailleEOL"]) - - if louis is None: - self.get_widget( \ - "contractedBrailleCheckButton").set_sensitive(False) - else: - self.get_widget("contractedBrailleCheckButton").set_active( \ - prefs["enableContractedBraille"]) - # Set up contraction table combo box and set it to the - # currently used one. - # - tablesCombo = self.get_widget("contractionTableCombo") - tableDict = braille.listTables() - selectedTableIter = None - selectedTable = prefs["brailleContractionTable"] or \ - braille.getDefaultTable() - if tableDict: - tablesModel = Gtk.ListStore(str, str) - names = sorted(tableDict.keys()) - for name in names: - fname = tableDict[name] - it = tablesModel.append([name, fname]) - if os.path.join(braille.tablesdir, fname) == \ - selectedTable: - selectedTableIter = it - cell = self.planeCellRendererText - tablesCombo.clear() - tablesCombo.pack_start(cell, True) - tablesCombo.add_attribute(cell, 'text', 0) - tablesCombo.set_model(tablesModel) - if selectedTableIter: - tablesCombo.set_active_iter(selectedTableIter) - else: - tablesCombo.set_active(0) - else: - tablesCombo.set_sensitive(False) - if prefs["brailleVerbosityLevel"] == settings.VERBOSITY_LEVEL_BRIEF: - self.get_widget("brailleBriefButton").set_active(True) - else: - self.get_widget("brailleVerboseButton").set_active(True) - - self.get_widget("enableBrailleWordWrapCheckButton").set_active( - prefs.get("enableBrailleWordWrap", settings.enableBrailleWordWrap)) - - selectionIndicator = prefs["brailleSelectorIndicator"] - if selectionIndicator == settings.BRAILLE_UNDERLINE_7: - self.get_widget("brailleSelection7Button").set_active(True) - elif selectionIndicator == settings.BRAILLE_UNDERLINE_8: - self.get_widget("brailleSelection8Button").set_active(True) - elif selectionIndicator == settings.BRAILLE_UNDERLINE_BOTH: - self.get_widget("brailleSelectionBothButton").set_active(True) - else: - self.get_widget("brailleSelectionNoneButton").set_active(True) - - linkIndicator = prefs["brailleLinkIndicator"] - if linkIndicator == settings.BRAILLE_UNDERLINE_7: - self.get_widget("brailleLink7Button").set_active(True) - elif linkIndicator == settings.BRAILLE_UNDERLINE_8: - self.get_widget("brailleLink8Button").set_active(True) - elif linkIndicator == settings.BRAILLE_UNDERLINE_BOTH: - self.get_widget("brailleLinkBothButton").set_active(True) - else: - self.get_widget("brailleLinkNoneButton").set_active(True) - - enable = prefs.get("enableFlashMessages", settings.enableFlashMessages) - self.get_widget("enableFlashMessagesCheckButton").set_active(enable) - - enable = prefs.get("flashIsPersistent", settings.flashIsPersistent) - self.get_widget("flashIsPersistentCheckButton").set_active(enable) - - enable = prefs.get("flashIsDetailed", settings.flashIsDetailed) - self.get_widget("flashIsDetailedCheckButton").set_active(enable) - - duration = prefs["brailleFlashTime"] - self.get_widget("brailleFlashTimeSpinButton").set_value(duration / 1000) - - # Key Echo pane. - # - self.get_widget("keyEchoCheckButton").set_active( \ - prefs["enableKeyEcho"]) - self.get_widget("enableAlphabeticKeysCheckButton").set_active( - prefs.get("enableAlphabeticKeys", settings.enableAlphabeticKeys)) - self.get_widget("enableNumericKeysCheckButton").set_active( - prefs.get("enableNumericKeys", settings.enableNumericKeys)) - self.get_widget("enablePunctuationKeysCheckButton").set_active( - prefs.get("enablePunctuationKeys", settings.enablePunctuationKeys)) - self.get_widget("enableSpaceCheckButton").set_active( - prefs.get("enableSpace", settings.enableSpace)) - self.get_widget("enableModifierKeysCheckButton").set_active( \ - prefs["enableModifierKeys"]) - self.get_widget("enableFunctionKeysCheckButton").set_active( \ - prefs["enableFunctionKeys"]) - self.get_widget("enableActionKeysCheckButton").set_active( \ - prefs["enableActionKeys"]) - self.get_widget("enableNavigationKeysCheckButton").set_active( \ - prefs["enableNavigationKeys"]) - self.get_widget("enableDiacriticalKeysCheckButton").set_active( \ - prefs["enableDiacriticalKeys"]) - self.get_widget("enableEchoByCharacterCheckButton").set_active( \ - prefs["enableEchoByCharacter"]) - self.get_widget("enableEchoByWordCheckButton").set_active( \ - prefs["enableEchoByWord"]) - self.get_widget("enableEchoBySentenceCheckButton").set_active( \ - prefs["enableEchoBySentence"]) - self.get_widget("useCustomEchoVoiceCheckButton").set_active( - prefs.get("useCustomEchoVoice", settings.useCustomEchoVoice)) - self.get_widget("useCustomEchoSpeechServerCheckButton").set_active( - prefs.get("useCustomEchoSpeechServer", settings.useCustomEchoSpeechServer)) - self.get_widget("useCustomEchoForKeyCheckButton").set_active( - prefs.get("useCustomEchoForKey", settings.useCustomEchoForKey)) - self.get_widget("useCustomEchoForCharacterCheckButton").set_active( - prefs.get("useCustomEchoForCharacter", settings.useCustomEchoForCharacter)) - self.get_widget("useCustomEchoForWordCheckButton").set_active( - prefs.get("useCustomEchoForWord", settings.useCustomEchoForWord)) - self.get_widget("useCustomEchoForSentenceCheckButton").set_active( - prefs.get("useCustomEchoForSentence", settings.useCustomEchoForSentence)) - self._setEchoVoiceItems() - - # Text attributes pane. - # - self._createTextAttributesTreeView() - - brailleIndicator = prefs["textAttributesBrailleIndicator"] - if brailleIndicator == settings.BRAILLE_UNDERLINE_7: - self.get_widget("textBraille7Button").set_active(True) - elif brailleIndicator == settings.BRAILLE_UNDERLINE_8: - self.get_widget("textBraille8Button").set_active(True) - elif brailleIndicator == settings.BRAILLE_UNDERLINE_BOTH: - self.get_widget("textBrailleBothButton").set_active(True) - else: - self.get_widget("textBrailleNoneButton").set_active(True) - - # Pronunciation dictionary pane. - # - self._createPronunciationTreeView() - - # General pane. - # - self.get_widget("presentToolTipsCheckButton").set_active( - prefs["presentToolTips"]) - - if prefs["keyboardLayout"] == settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP: - self.get_widget("generalDesktopButton").set_active(True) - else: - self.get_widget("generalLaptopButton").set_active(True) - - combobox = self.get_widget("sayAllStyle") - self.populateComboBox(combobox, [guilabels.SAY_ALL_STYLE_LINE, - guilabels.SAY_ALL_STYLE_SENTENCE]) - combobox.set_active(prefs["sayAllStyle"]) - self.get_widget("rewindAndFastForwardInSayAllCheckButton").set_active( - prefs.get("rewindAndFastForwardInSayAll", settings.rewindAndFastForwardInSayAll)) - self.get_widget("structNavInSayAllCheckButton").set_active( - prefs.get("structNavInSayAll", settings.structNavInSayAll)) - self.get_widget("sayAllContextBlockquoteCheckButton").set_active( - prefs.get("sayAllContextBlockquote", settings.sayAllContextBlockquote)) - self.get_widget("sayAllContextLandmarkCheckButton").set_active( - prefs.get("sayAllContextLandmark", settings.sayAllContextLandmark)) - self.get_widget("sayAllContextNonLandmarkFormCheckButton").set_active( - prefs.get("sayAllContextNonLandmarkForm", settings.sayAllContextNonLandmarkForm)) - self.get_widget("sayAllContextListCheckButton").set_active( - prefs.get("sayAllContextList", settings.sayAllContextList)) - self.get_widget("sayAllContextPanelCheckButton").set_active( - prefs.get("sayAllContextPanel", settings.sayAllContextPanel)) - self.get_widget("sayAllContextTableCheckButton").set_active( - prefs.get("sayAllContextTable", settings.sayAllContextTable)) - - # Cthulhu User Profiles - # - self.profilesCombo = self.get_widget('availableProfilesComboBox1') - self.startingProfileCombo = self.get_widget('availableProfilesComboBox2') - self.profilesComboModel = self.get_widget('model9') - self.__initProfileCombo() - if self.script.app: - self.get_widget('profilesFrame').set_sensitive(False) - - active_plugins = self._get_active_plugins_for_tabs() - self._update_plugin_tabs(active_plugins) - - # AI Assistant settings - # - if self._plugin_active(active_plugins, ["AIAssistant"]): - self._initAIState() - - # Indentation settings - # - self._initIndentationState() - - # OCR Plugin settings - # - if self._plugin_active(active_plugins, ["OCR"]): - self._initOCRState() - - def __initProfileCombo(self): - """Adding available profiles and setting active as the active one""" - - availableProfiles = self.__getAvailableProfiles() - self.profilesComboModel.clear() - - if not len(availableProfiles): - self.profilesComboModel.append(self._defaultProfile) - else: - for profile in availableProfiles: - self.profilesComboModel.append(profile) - - activeProfile = self.prefsDict.get('activeProfile') or self._defaultProfile - startingProfile = self.prefsDict.get('startingProfile') or self._defaultProfile - - activeProfileIter = self.getComboBoxIndex(self.profilesCombo, - activeProfile[0]) - startingProfileIter = self.getComboBoxIndex(self.startingProfileCombo, - startingProfile[0]) - self.profilesCombo.set_active(activeProfileIter) - self.startingProfileCombo.set_active(startingProfileIter) - - def __getAvailableProfiles(self): - """Get available user profiles.""" - return cthulhu.cthulhuApp.settingsManager.availableProfiles() - - def _initAIState(self): - """Initialize AI Assistant tab widgets with current settings.""" - prefs = self.prefsDict - - # Store widget references - self.enableAICheckButton = self.get_widget("enableAICheckButton") - self.aiProviderCombo = self.get_widget("aiProviderCombo") - self.aiApiKeyEntry = self.get_widget("aiApiKeyEntry") - self.aiOllamaModelEntry = self.get_widget("aiOllamaModelEntry") - self.aiOllamaEndpointEntry = self.get_widget("aiOllamaEndpointEntry") - self.aiConfirmationCheckButton = self.get_widget("aiConfirmationCheckButton") - self.aiScreenshotQualityCombo = self.get_widget("aiScreenshotQualityCombo") - - # Set enable AI checkbox - enabled = prefs.get("aiAssistantEnabled", settings.aiAssistantEnabled) - self.enableAICheckButton.set_active(enabled) - - # Set provider combo - provider = prefs.get("aiProvider", settings.aiProvider) - providerIndex = 0 # Default to Claude Code - if provider == settings.AI_PROVIDER_CODEX: - providerIndex = 1 - elif provider == settings.AI_PROVIDER_GEMINI: - providerIndex = 2 - elif provider == settings.AI_PROVIDER_OLLAMA: - providerIndex = 3 - self.aiProviderCombo.set_active(providerIndex) - - # Set API key file - apiKeyFile = prefs.get("aiApiKeyFile", settings.aiApiKeyFile) - self.aiApiKeyEntry.set_text(apiKeyFile) - - # Set Ollama model - ollamaModel = prefs.get("aiOllamaModel", settings.aiOllamaModel) - self.aiOllamaModelEntry.set_text(ollamaModel) - - # Set Ollama endpoint - ollamaEndpoint = prefs.get("aiOllamaEndpoint", settings.aiOllamaEndpoint) - self.aiOllamaEndpointEntry.set_text(ollamaEndpoint) - - # Set confirmation checkbox - confirmationRequired = prefs.get("aiConfirmationRequired", settings.aiConfirmationRequired) - self.aiConfirmationCheckButton.set_active(confirmationRequired) - - # Set screenshot quality combo - quality = prefs.get("aiScreenshotQuality", settings.aiScreenshotQuality) - qualityIndex = 1 # Default to medium - if quality == settings.AI_SCREENSHOT_QUALITY_LOW: - qualityIndex = 0 - elif quality == settings.AI_SCREENSHOT_QUALITY_HIGH: - qualityIndex = 2 - self.aiScreenshotQualityCombo.set_active(qualityIndex) - - # Enable/disable controls based on AI enabled state - self._updateAIControlsState(enabled) - - def _updateAIControlsState(self, enabled): - """Refresh AI controls while keeping configuration fields editable.""" - _ = enabled # kept for signal/call compatibility - # Keep settings editable even when AI assistant is disabled so users - # can configure providers/keys before enabling it. - self.aiProviderCombo.set_sensitive(True) - self.aiConfirmationCheckButton.set_sensitive(True) - self.aiScreenshotQualityCombo.set_sensitive(True) - try: - self.get_widget("aiGetClaudeKeyButton").set_sensitive(True) - except: - pass # Button might not exist in older UI files - - current_provider = self.prefsDict.get("aiProvider", settings.aiProvider) - self._updateProviderControls(current_provider) - - def _initIndentationState(self): - """Initialize Indentation widgets with current settings.""" - prefs = self.prefsDict - - self.enableIndentationCheckButton = self.get_widget("enableIndentationCheckButton") - self.indentationSpeechButton = self.get_widget("indentationSpeechButton") - self.indentationBeepsButton = self.get_widget("indentationBeepsButton") - self.indentationSpeechAndBeepsButton = self.get_widget("indentationSpeechAndBeepsButton") - self.indentationModeGrid = self.get_widget("indentationModeGrid") - - enabled = prefs.get("enableIndentation", settings.enableIndentation) - self.enableIndentationCheckButton.set_active(enabled) - - mode = prefs.get("indentationPresentationMode", settings.indentationPresentationMode) - if mode == settings.INDENTATION_PRESENTATION_BEEPS: - self.indentationBeepsButton.set_active(True) - elif mode == settings.INDENTATION_PRESENTATION_SPEECH_AND_BEEPS: - self.indentationSpeechAndBeepsButton.set_active(True) - else: - self.indentationSpeechButton.set_active(True) - - self._updateIndentationControlsState(enabled) - - def _updateIndentationControlsState(self, enabled): - """Enable or disable indentation mode controls based on checkbox state.""" - self.indentationModeGrid.set_sensitive(enabled) - - def _updateProviderControls(self, provider): - """Update visibility/sensitivity of provider-specific controls.""" - # API key controls (only needed for Gemini - not for Claude Code or Ollama) - api_key_needed = provider in [settings.AI_PROVIDER_GEMINI] - self.aiApiKeyEntry.set_sensitive(api_key_needed) - - # Get Claude API Key button (only for Claude Code) - try: - claude_button = self.get_widget("aiGetClaudeKeyButton") - claude_button.set_visible(provider == settings.AI_PROVIDER_CLAUDE_CODE) - except: - pass # Button might not exist - - # Ollama model and endpoint entries (only for Ollama) - ollama_enabled = provider == settings.AI_PROVIDER_OLLAMA - self.aiOllamaModelEntry.set_sensitive(ollama_enabled) - self.aiOllamaEndpointEntry.set_sensitive(ollama_enabled) - - # Update labels based on provider - if provider == settings.AI_PROVIDER_CLAUDE_CODE: - self.aiApiKeyEntry.set_placeholder_text("No API key needed - uses Claude Code CLI") - elif provider == settings.AI_PROVIDER_CODEX: - self.aiApiKeyEntry.set_placeholder_text("No API key needed - uses Codex CLI") - elif provider == settings.AI_PROVIDER_OLLAMA: - self.aiApiKeyEntry.set_placeholder_text("No API key needed - uses local Ollama") - else: - self.aiApiKeyEntry.set_placeholder_text("Path to API key file") - - def _initOCRState(self): - """Initialize OCR Plugin tab widgets with current settings.""" - prefs = self.prefsDict - - # Store widget references - self.ocrLanguageEntry = self.get_widget("ocrLanguageEntry") - self.ocrScaleSpinButton = self.get_widget("ocrScaleSpinButton") - self.ocrGrayscaleCheckButton = self.get_widget("ocrGrayscaleCheckButton") - self.ocrInvertCheckButton = self.get_widget("ocrInvertCheckButton") - self.ocrBlackWhiteCheckButton = self.get_widget("ocrBlackWhiteCheckButton") - self.ocrBlackWhiteValueSpinButton = self.get_widget("ocrBlackWhiteValueSpinButton") - self.ocrColorCalculationCheckButton = self.get_widget("ocrColorCalculationCheckButton") - self.ocrCopyToClipboardCheckButton = self.get_widget("ocrCopyToClipboardCheckButton") - - # Set language code - languageCode = prefs.get("ocrLanguageCode", settings.ocrLanguageCode) - self.ocrLanguageEntry.set_text(languageCode) - - # Set scale factor - scaleFactor = prefs.get("ocrScaleFactor", settings.ocrScaleFactor) - self.ocrScaleSpinButton.set_value(scaleFactor) - - # Set checkboxes - grayscale = prefs.get("ocrGrayscaleImg", settings.ocrGrayscaleImg) - self.ocrGrayscaleCheckButton.set_active(grayscale) - - invert = prefs.get("ocrInvertImg", settings.ocrInvertImg) - self.ocrInvertCheckButton.set_active(invert) - - blackWhite = prefs.get("ocrBlackWhiteImg", settings.ocrBlackWhiteImg) - self.ocrBlackWhiteCheckButton.set_active(blackWhite) - - blackWhiteValue = prefs.get("ocrBlackWhiteImgValue", settings.ocrBlackWhiteImgValue) - self.ocrBlackWhiteValueSpinButton.set_value(blackWhiteValue) - - colorCalculation = prefs.get("ocrColorCalculation", settings.ocrColorCalculation) - self.ocrColorCalculationCheckButton.set_active(colorCalculation) - - copyToClipboard = prefs.get("ocrCopyToClipboard", settings.ocrCopyToClipboard) - self.ocrCopyToClipboardCheckButton.set_active(copyToClipboard) - - def _initSoundThemeState(self): - """Initialize sound widgets with current settings.""" - prefs = self.prefsDict - - # Get widget references - self.soundSinkCombo = self.get_widget("soundSinkCombo") - self.soundThemeCombo = self.get_widget("soundThemeCombo") - self.roleSoundPresentationCombo = self.get_widget("roleSoundPresentationCombo") - self.soundVolumeScale = self.get_widget("soundVolumeScale") - self.progressBarBeepIntervalSpinButton = self.get_widget("progressBarBeepIntervalSpinButton") - self.soundSinkCombo.set_can_focus(False) - self.soundThemeCombo.set_can_focus(False) - self.roleSoundPresentationCombo.set_can_focus(False) - self.get_widget("enableSoundCheckButton").set_active( - prefs.get("enableSound", settings.enableSound) - ) - self.soundVolumeScale.set_value( - float(prefs.get("soundVolume", settings.soundVolume)) - ) - self.get_widget("playSoundForRoleCheckButton").set_active( - prefs.get("playSoundForRole", settings.playSoundForRole) - ) - self.get_widget("playSoundForStateCheckButton").set_active( - prefs.get("playSoundForState", settings.playSoundForState) - ) - self.get_widget("playSoundForPositionInSetCheckButton").set_active( - prefs.get("playSoundForPositionInSet", settings.playSoundForPositionInSet) - ) - self.get_widget("playSoundForValueCheckButton").set_active( - prefs.get("playSoundForValue", settings.playSoundForValue) - ) - self.get_widget("spatializeObjectSoundsCheckButton").set_active( - prefs.get("spatializeObjectSounds", settings.spatializeObjectSounds) - ) - self.get_widget("beepProgressBarUpdatesCheckButton").set_active( - prefs.get("beepProgressBarUpdates", settings.beepProgressBarUpdates) - ) - self.progressBarBeepIntervalSpinButton.set_value( - int(prefs.get("progressBarBeepInterval", settings.progressBarBeepInterval)) - ) - - self._soundSinkChoices = [ - (settings.SOUND_SINK_AUTO, guilabels.SOUND_BACKEND_AUTO), - (settings.SOUND_SINK_PIPEWIRE, guilabels.SOUND_BACKEND_PIPEWIRE), - (settings.SOUND_SINK_PULSE, guilabels.SOUND_BACKEND_PULSE), - (settings.SOUND_SINK_ALSA, guilabels.SOUND_BACKEND_ALSA), - ] - self.soundSinkCombo.remove_all() - for _, label in self._soundSinkChoices: - self.soundSinkCombo.append_text(label) - runtimeSoundSink = cthulhu.cthulhuApp.settingsManager.getSetting("soundSink") - currentSink = sound_sink.normalize_sound_sink_choice( - prefs.get("soundSink", runtimeSoundSink if runtimeSoundSink is not None else settings.soundSink) - ) - sinkIndex = 0 - for index, (value, _) in enumerate(self._soundSinkChoices): - if value == currentSink: - sinkIndex = index - break - self.soundSinkCombo.set_active(sinkIndex) - - # Populate sound theme combo box - themeManager = sound_theme_manager.getManager() - availableThemes = themeManager.getAvailableThemes() - - # Clear and populate combo - add "None" as first option - self.soundThemeCombo.remove_all() - self.soundThemeCombo.append_text(sound_theme_manager.THEME_NONE) - for theme in availableThemes: - self.soundThemeCombo.append_text(theme) - - # Build the full list for index lookup - allThemes = [sound_theme_manager.THEME_NONE] + availableThemes - - # Set active theme - currentTheme = prefs.get("soundTheme", settings.soundTheme) - if currentTheme in allThemes: - self.soundThemeCombo.set_active(allThemes.index(currentTheme)) - elif len(allThemes) > 1: - # Default to first actual theme (skip "none") - self.soundThemeCombo.set_active(1) - else: - self.soundThemeCombo.set_active(0) - - self._roleSoundPresentationChoices = [ - (settings.ROLE_SOUND_PRESENTATION_SOUND_AND_SPEECH, "Sound and speech"), - (settings.ROLE_SOUND_PRESENTATION_SPEECH_ONLY, "Speech only"), - (settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY, "Sound only"), - ] - self.roleSoundPresentationCombo.remove_all() - for _, label in self._roleSoundPresentationChoices: - self.roleSoundPresentationCombo.append_text(label) - currentPresentation = prefs.get( - "roleSoundPresentation", - settings.roleSoundPresentation - ) - presentationIndex = 0 - for index, (value, _) in enumerate(self._roleSoundPresentationChoices): - if value == currentPresentation: - presentationIndex = index - break - self.roleSoundPresentationCombo.set_active(presentationIndex) - - def soundThemeComboChanged(self, widget): - """Signal handler for the sound theme combo box.""" - activeText = widget.get_active_text() - if activeText: - self.prefsDict["soundTheme"] = activeText - - def soundSinkComboChanged(self, widget): - """Signal handler for the sound backend combo box.""" - activeIndex = widget.get_active() - if activeIndex < 0: - return - value = self._soundSinkChoices[activeIndex][0] - self.prefsDict["soundSink"] = value - - def roleSoundPresentationComboChanged(self, widget): - """Signal handler for the role sound presentation combo box.""" - activeIndex = widget.get_active() - if activeIndex < 0: - return - value = self._roleSoundPresentationChoices[activeIndex][0] - self.prefsDict["roleSoundPresentation"] = value - - def soundVolumeValueChanged(self, widget): - """Signal handler for the sound volume scale.""" - self.prefsDict["soundVolume"] = widget.get_value() - - def progressBarBeepIntervalValueChanged(self, widget): - """Signal handler for the progress bar beep interval spin button.""" - self.prefsDict["progressBarBeepInterval"] = widget.get_value_as_int() - - - def _updateCthulhuModifier(self): - combobox = self.get_widget("cthulhuModifierComboBox") - keystring = ", ".join(self.prefsDict["cthulhuModifierKeys"]) - combobox.set_active(self.getComboBoxIndex(combobox, keystring)) - - def populateComboBox(self, combobox, items): - """Populates the combobox with the items provided. - - Arguments: - - combobox: the GtkComboBox to populate - - items: the list of strings with which to populate it - """ - - model = Gtk.ListStore(str) - for item in items: - model.append([item]) - combobox.set_model(model) - - def getComboBoxIndex(self, combobox, searchStr, col=0): - """ For each of the entries in the given combo box, look for searchStr. - Return the index of the entry if searchStr is found. - - Arguments: - - combobox: the GtkComboBox to search. - - searchStr: the string to search for. - - Returns the index of the first entry in combobox with searchStr, or - 0 if not found. - """ - - model = combobox.get_model() - myiter = model.get_iter_first() - for i in range(0, len(model)): - name = model.get_value(myiter, col) - if name == searchStr: - return i - myiter = model.iter_next(myiter) - - return 0 - - def getComboBoxList(self, combobox): - """Get the list of values from the active combox - """ - active = combobox.get_active() - model = combobox.get_model() - activeIter = model.get_iter(active) - activeLabel = model.get_value(activeIter, 0) - activeName = model.get_value(activeIter, 1) - return [activeLabel, activeName] - - def getKeyBindingsModelDict(self, model, modifiedOnly=True): - modelDict = {} - node = model.get_iter_first() - while node: - child = model.iter_children(node) - while child: - key, modified = model.get(child, HANDLER, MODIF) - if modified or not modifiedOnly: - value = [] - value.append(list(model.get( - child, KEY1, MOD_MASK1, MOD_USED1, CLICK_COUNT1))) - modelDict[key] = value - child = model.iter_next(child) - node = model.iter_next(node) - - return modelDict - - def getModelDict(self, model): - """Get the list of values from a list[str,str] model - """ - pronunciation_dict.pronunciation_dict = {} - currentIter = model.get_iter_first() - while currentIter is not None: - key, value = model.get(currentIter, ACTUAL, REPLACEMENT) - if key and value: - pronunciation_dict.setPronunciation(key, value) - currentIter = model.iter_next(currentIter) - modelDict = pronunciation_dict.pronunciation_dict - return modelDict - - def showGUI(self): - """Show the Cthulhu configuration GUI window. This assumes that - the GUI has already been created. - """ - - cthulhuSetupWindow = self.get_widget("cthulhuSetupWindow") - - accelGroup = Gtk.AccelGroup() - cthulhuSetupWindow.add_accel_group(accelGroup) - helpButton = self.get_widget("helpButton") - (keyVal, modifierMask) = Gtk.accelerator_parse("F1") - helpButton.add_accelerator("clicked", - accelGroup, - keyVal, - modifierMask, - 0) - - try: - ts = cthulhu_state.lastInputEvent.timestamp - # Ensure timestamp fits in 32-bit range for GTK - if ts > 4294967295: # 2^32 - 1 - ts = ts % 4294967296 # Wrap to 32-bit range - except Exception: - ts = 0 - if ts == 0: - ts = Gtk.get_current_event_time() - cthulhuSetupWindow.present_with_time(int(ts)) - - # We always want to re-order the text attributes page so that enabled - # items are consistently at the top. - # - self._setSpokenTextAttributes( - self.getTextAttributesView, - cthulhu.cthulhuApp.settingsManager.getSetting('enabledSpokenTextAttributes'), - True, True) - - if self.script.app: - title = guilabels.PREFERENCES_APPLICATION_TITLE % AXObject.get_name(self.script.app) - cthulhuSetupWindow.set_title(title) - - cthulhuSetupWindow.show() - self._initialFocusSyncAttempts = 0 - GLib.idle_add(self._set_initial_window_state) - GLib.idle_add(self._set_initial_gtk_focus) - GLib.timeout_add(50, self._set_initial_window_state) - - def _set_initial_gtk_focus(self): - """Give GTK focus to a real preferences control as soon as the dialog appears.""" - - candidateIds = [ - "generalDesktopButton", - "generalLaptopButton", - "availableProfilesComboBox1", - "speechSupportCheckButton", - "notebook", - ] - cthulhuSetupWindow = self.get_widget("cthulhuSetupWindow") - for widgetId in candidateIds: - widget = self.get_widget(widgetId) - if not widget.get_visible() or not widget.get_sensitive(): - continue - if not widget.get_can_focus(): - continue - - debug.printMessage( - debug.LEVEL_INFO, - f"PREFERENCES DIALOG: Setting initial GTK focus to {widgetId}", - True, - ) - cthulhuSetupWindow.set_focus(widget) - widget.grab_focus() - return False - - debug.printMessage( - debug.LEVEL_INFO, - "PREFERENCES DIALOG: No focusable initial GTK widget found", - True, - ) - return False - - def _set_initial_window_state(self): - """Sync Cthulhu's active window to preferences without forcing dialog focus.""" - - self._initialFocusSyncAttempts += 1 - activeWindow = AXUtilities.find_active_window() - if activeWindow is None: - return self._initialFocusSyncAttempts < 5 - - app = AXObject.get_application(activeWindow) - appName = (AXObject.get_name(app) or "").lower() - if appName != "cthulhu": - return self._initialFocusSyncAttempts < 5 - - debug.printTokens( - debug.LEVEL_INFO, - ["PREFERENCES DIALOG: Syncing active window to", activeWindow], - True, - ) - cthulhu.setActiveWindow(activeWindow, notifyScript=False) - - tokens = ["PREFERENCES DIALOG: Synced initial window state to", activeWindow] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - def _initComboBox(self, combobox): - """Initialize the given combo box to take a list of int/str pairs. - - Arguments: - - combobox: the GtkComboBox to initialize. - """ - - cell = Gtk.CellRendererText() - combobox.pack_start(cell, True) - # We only want to display one column; not two. - # - try: - columnToDisplay = combobox.get_cells()[0] - combobox.add_attribute(columnToDisplay, 'text', 1) - except Exception: - combobox.add_attribute(cell, 'text', 1) - model = Gtk.ListStore(int, str) - combobox.set_model(model) - - # Force the display comboboxes to be left aligned. - # - if isinstance(combobox, Gtk.ComboBoxText): - size = combobox.size_request() - cell.set_fixed_size(size[0] - 29, -1) - - return model - - def _setKeyEchoItems(self): - """[In]sensitize the checkboxes for the various types of key echo, - depending upon whether the value of the key echo check button is set. - """ - - enable = self.get_widget("keyEchoCheckButton").get_active() - self.get_widget("enableAlphabeticKeysCheckButton").set_sensitive(enable) - self.get_widget("enableNumericKeysCheckButton").set_sensitive(enable) - self.get_widget("enablePunctuationKeysCheckButton").set_sensitive(enable) - self.get_widget("enableSpaceCheckButton").set_sensitive(enable) - self.get_widget("enableModifierKeysCheckButton").set_sensitive(enable) - self.get_widget("enableFunctionKeysCheckButton").set_sensitive(enable) - self.get_widget("enableActionKeysCheckButton").set_sensitive(enable) - self.get_widget("enableNavigationKeysCheckButton").set_sensitive(enable) - self.get_widget("enableDiacriticalKeysCheckButton").set_sensitive( \ - enable) - self._setEchoVoiceItems() - - def _setEchoVoiceItems(self): - """[In]sensitize echo voice controls based on current state.""" - - useCustomVoice = self.get_widget("useCustomEchoVoiceCheckButton").get_active() - useCustomModule = self.get_widget("useCustomEchoSpeechServerCheckButton").get_active() - keyEchoEnabled = self.get_widget("keyEchoCheckButton").get_active() - charEchoEnabled = self.get_widget("enableEchoByCharacterCheckButton").get_active() - wordEchoEnabled = self.get_widget("enableEchoByWordCheckButton").get_active() - sentenceEchoEnabled = self.get_widget("enableEchoBySentenceCheckButton").get_active() - speechEnabled = self.get_widget("speechSupportCheckButton").get_active() - - speechSystemIsDispatcher = False - if self.speechSystemsChoice: - try: - speechSystemIsDispatcher = \ - self.speechSystemsChoice.SpeechServer.getFactoryName() == guilabels.SPEECH_DISPATCHER - except Exception: - speechSystemIsDispatcher = False - - voiceControlsEnabled = useCustomVoice and speechEnabled - moduleOverrideAvailable = voiceControlsEnabled and speechSystemIsDispatcher - moduleControlsEnabled = moduleOverrideAvailable and useCustomModule - - self.get_widget("useCustomEchoSpeechServerCheckButton").set_sensitive(moduleOverrideAvailable) - self.get_widget("echoSpeechServers").set_sensitive(moduleControlsEnabled) - self.get_widget("echoSpeechFamilies").set_sensitive(voiceControlsEnabled) - - self.get_widget("echoRateScale").set_sensitive(useCustomVoice) - self.get_widget("echoPitchScale").set_sensitive(useCustomVoice) - self.get_widget("echoVolumeScale").set_sensitive(useCustomVoice) - - self.get_widget("useCustomEchoForKeyCheckButton").set_sensitive(useCustomVoice and keyEchoEnabled) - self.get_widget("useCustomEchoForCharacterCheckButton").set_sensitive( - useCustomVoice and charEchoEnabled) - self.get_widget("useCustomEchoForWordCheckButton").set_sensitive(useCustomVoice and wordEchoEnabled) - self.get_widget("useCustomEchoForSentenceCheckButton").set_sensitive( - useCustomVoice and sentenceEchoEnabled) - - def _presentMessage(self, text, interrupt=False, voice=None): - """If the text field is not None, presents the given text, optionally - interrupting anything currently being spoken. - - Arguments: - - text: the text to present - - interrupt: if True, interrupt any speech currently being spoken - - voice: the voice to use; if None, use the default system voice - """ - - self.script.speakMessage(text, voice=voice, interrupt=interrupt) - try: - self.script.displayBrailleMessage(text, flashTime=-1) - except Exception: - pass - - def _previewVoiceSelection(self, voiceType, name): - """Present a short preview in the currently selected voice.""" - - if not name: - return - - voice = self._getACSSForVoiceType(voiceType) - if not voice: - return - - previewVoice = acss.ACSS(voice) - if self.speechSystemsChoice \ - and self.speechSystemsChoice.SpeechServer.getFactoryName() == guilabels.SPEECH_DISPATCHER: - previewMessage = messages.SPEECH_VOICE_VALUE % name - else: - previewMessage = messages.SPEECH_VOICE_VALUE_GENERIC % name - - # Speak through the currently-selected preferences speech server so - # preview uses the chosen module/voice, not the globally-active one. - server = self.speechServersChoice - if server and hasattr(server, "speak"): - try: - server.speak(previewMessage, previewVoice, interrupt=True) - return - except Exception: - debug.printException(debug.LEVEL_WARNING) - - self._presentMessage(previewMessage, interrupt=True, voice=previewVoice) - - def _createNode(self, appName): - """Create a new root node in the TreeStore model with the name of the - application. - - Arguments: - - appName: the name of the TreeStore Node (the same of the application) - """ - - model = self.keyBindingsModel - - myiter = model.append(None) - model.set_value(myiter, DESCRIP, appName) - model.set_value(myiter, MODIF, False) - - return myiter - - def _getIterOf(self, appName): - """Returns the Gtk.TreeIter of the TreeStore model - that matches the application name passed as argument - - Arguments: - - appName: a string with the name of the application of the node wanted - it's the same that the field DESCRIP of the model treeStore - """ - - model = self.keyBindingsModel - - for row in model: - if ((model.iter_depth(row.iter) == 0) \ - and (row[DESCRIP] == appName)): - return row.iter - - return None - - def _clickCountToString(self, clickCount): - """Given a numeric clickCount, returns a string for inclusion - in the list of keybindings. - - Argument: - - clickCount: the number of clicks associated with the keybinding. - """ - - clickCountString = "" - if clickCount == 2: - clickCountString = f" ({guilabels.CLICK_COUNT_DOUBLE})" - elif clickCount == 3: - clickCountString = f" ({guilabels.CLICK_COUNT_TRIPLE})" - - return clickCountString - - def _insertRow(self, handl, kb, parent=None, modif=False): - """Appends a new row with the new keybinding data to the treeview - - Arguments: - - handl: the name of the handler associated to the keyBinding - - kb: the new keybinding. - - parent: the parent node of the treeview, where to append the kb - - modif: whether to check the modified field or not. - - Returns a Gtk.TreeIter pointing at the new row. - """ - - model = self.keyBindingsModel - - if parent is None: - parent = self._getIterOf(guilabels.KB_GROUP_DEFAULT) - - if parent is not None: - myiter = model.append(parent) - if not kb.keysymstring: - text = None - else: - clickCount = self._clickCountToString(kb.click_count) - keysymstring = kb.keysymstring - text = keybindings.getModifierNames(kb.modifiers) \ - + keysymstring \ - + clickCount - - model.set_value(myiter, HANDLER, handl) - model.set_value(myiter, DESCRIP, kb.handler.description) - model.set_value(myiter, MOD_MASK1, str(kb.modifier_mask)) - model.set_value(myiter, MOD_USED1, str(kb.modifiers)) - model.set_value(myiter, KEY1, kb.keysymstring) - model.set_value(myiter, CLICK_COUNT1, str(kb.click_count)) - if text is not None: - model.set_value(myiter, OLDTEXT1, text) - model.set_value(myiter, TEXT1, text) - model.set_value(myiter, MODIF, modif) - model.set_value(myiter, EDITABLE, True) - - return myiter - else: - return None - - def _insertRowBraille(self, handl, com, inputEvHand, - parent=None, modif=False): - """Appends a new row with the new braille binding data to the treeview - - Arguments: - - handl: the name of the handler associated to the brailleBinding - - com: the BrlTTY command - - inputEvHand: the inputEventHandler with the new brailleBinding - - parent: the parent node of the treeview, where to append the kb - - modif: whether to check the modified field or not. - - Returns a Gtk.TreeIter pointing at the new row. - """ - - model = self.keyBindingsModel - - if parent is None: - parent = self._getIterOf(guilabels.KB_GROUP_BRAILLE) - - if parent is not None: - myiter = model.append(parent) - model.set_value(myiter, HANDLER, handl) - model.set_value(myiter, DESCRIP, inputEvHand.description) - model.set_value(myiter, KEY1, str(com)) - model.set_value(myiter, TEXT1, braille.command_name[com]) - model.set_value(myiter, MODIF, modif) - model.set_value(myiter, EDITABLE, False) - return myiter - else: - return None - - def _markModified(self): - """ Mark as modified the user custom key bindings: - """ - - try: - self.script.setupInputEventHandlers() - keyBinds = keybindings.KeyBindings() - keyBinds = cthulhu.cthulhuApp.settingsManager.overrideKeyBindings(self.script, keyBinds) - keyBind = keybindings.KeyBinding(None, None, None, None) - treeModel = self.keyBindingsModel - - myiter = treeModel.get_iter_first() - while myiter is not None: - iterChild = treeModel.iter_children(myiter) - while iterChild is not None: - descrip = treeModel.get_value(iterChild, DESCRIP) - keyBind.handler = \ - input_event.InputEventHandler(None, descrip) - if keyBinds.hasKeyBinding(keyBind, - typeOfSearch="description"): - treeModel.set_value(iterChild, MODIF, True) - iterChild = treeModel.iter_next(iterChild) - myiter = treeModel.iter_next(myiter) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - def _populateKeyBindings(self, clearModel=True): - """Fills the TreeView with the list of Cthulhu keybindings - - Arguments: - - clearModel: if True, initially clear out the key bindings model. - """ - - self.keyBindView.set_model(None) - self.keyBindView.set_headers_visible(False) - self.keyBindView.hide() - if clearModel: - self.keyBindingsModel.clear() - self.kbindings = None - - appName = AXObject.get_name(self.script.app) - iterApp = self._createNode(appName) - iterCthulhu = self._createNode(guilabels.KB_GROUP_DEFAULT) - iterUnbound = self._createNode(guilabels.KB_GROUP_UNBOUND) - iterNotificationPresenter = self._createNode(guilabels.KB_GROUP_NOTIFICATIONS) - iterFlatReviewPresenter = self._createNode(guilabels.KB_GROUP_FLAT_REVIEW) - iterSpeechAndVerbosity = self._createNode(guilabels.KB_GROUP_SPEECH_VERBOSITY) - iterDateAndTime = self._createNode(guilabels.KB_GROUP_DATE_AND_TIME) - iterBookmarks = self._createNode(guilabels.KB_GROUP_BOOKMARKS) - iterObjectNav = self._createNode(guilabels.KB_GROUP_OBJECT_NAVIGATION) - iterWhereAmIPresenter = self._createNode(guilabels.KB_GROUP_WHERE_AM_I) - iterLearnMode = self._createNode(guilabels.KB_GROUP_LEARN_MODE) - iterMouseReviewer = self._createNode(guilabels.KB_GROUP_MOUSE_REVIEW) - iterActionPresenter = self._createNode(guilabels.KB_GROUP_ACTIONS) - - if not self.kbindings: - self.kbindings = keybindings.KeyBindings() - self.script.setupInputEventHandlers() - allKeyBindings = self.script.getKeyBindings() - defKeyBindings = self.script.getDefaultKeyBindings() - npKeyBindings = self.script.getNotificationPresenter().get_bindings() - svKeyBindings = self.script.getSpeechAndVerbosityManager().get_bindings() - dtKeyBindings = self.script.getDateAndTimePresenter().get_bindings() - bmKeyBindings = self.script.getBookmarks().get_bindings() - onKeyBindings = self.script.get_objectNavigator().get_bindings() - lmKeyBindings = self.script.getLearnModePresenter().get_bindings() - mrKeyBindings = self.script.getMouseReviewer().get_bindings() - acKeyBindings = self.script.getActionPresenter().get_bindings() - - layout = cthulhu.cthulhuApp.settingsManager.getSetting('keyboardLayout') - isDesktop = layout == settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP - frKeyBindings = self.script.getFlatReviewPresenter().get_bindings(isDesktop) - waiKeyBindings = self.script.getWhereAmIPresenter().get_bindings(isDesktop) - - for kb in allKeyBindings.keyBindings: - if not self.kbindings.hasKeyBinding(kb, "strict"): - handl = self.script.getInputEventHandlerKey(kb.handler) - if npKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterNotificationPresenter) - elif onKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterObjectNav) - elif frKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterFlatReviewPresenter) - elif waiKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterWhereAmIPresenter) - elif svKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterSpeechAndVerbosity) - elif dtKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterDateAndTime) - elif bmKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterBookmarks) - elif lmKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterLearnMode) - elif acKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterActionPresenter) - elif mrKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterMouseReviewer) - elif not defKeyBindings.hasKeyBinding(kb, "description"): - self._insertRow(handl, kb, iterApp) - elif kb.keysymstring: - self._insertRow(handl, kb, iterCthulhu) - else: - self._insertRow(handl, kb, iterUnbound) - self.kbindings.add(kb) - - if not self.keyBindingsModel.iter_has_child(iterApp): - self.keyBindingsModel.remove(iterApp) - - if not self.keyBindingsModel.iter_has_child(iterUnbound): - self.keyBindingsModel.remove(iterUnbound) - - self._updateCthulhuModifier() - self._markModified() - iterBB = self._createNode(guilabels.KB_GROUP_BRAILLE) - self.bbindings = self.script.getBrailleBindings() - for com, inputEvHand in self.bbindings.items(): - handl = self.script.getInputEventHandlerKey(inputEvHand) - self._insertRowBraille(handl, com, inputEvHand, iterBB) - - self.keyBindView.set_model(self.keyBindingsModel) - self.keyBindView.set_headers_visible(True) - self.keyBindingsModel.set_sort_column_id(OLDTEXT1, Gtk.SortType.ASCENDING) - self.keyBindView.show() - - # Keep track of new/unbound keybindings that have yet to be applied. - # - self.pendingKeyBindings = {} - - def _cleanupSpeechServers(self): - """Remove unwanted factories and drivers for the current active - factory, when the user dismisses the Cthulhu Preferences dialog.""" - - for workingFactory in self.workingFactories: - if not (workingFactory == self.speechSystemsChoice): - workingFactory.SpeechServer.shutdownActiveServers() - else: - servers = workingFactory.SpeechServer.getSpeechServers() - for server in servers: - if not (server == self.speechServersChoice): - server.shutdown() - - def speechSupportChecked(self, widget): - """Signal handler for the "toggled" signal for the - speechSupportCheckButton GtkCheckButton widget. The user has - [un]checked the 'Enable Speech' checkbox. Set the 'enableSpeech' - preference to the new value. Set the rest of the speech pane items - [in]sensensitive depending upon whether this checkbox is checked. - - Arguments: - - widget: the component that generated the signal. - """ - - enable = widget.get_active() - self.prefsDict["enableSpeech"] = enable - self.get_widget("speechOptionsGrid").set_sensitive(enable) - self._setupEchoSpeechServers() - self._setEchoVoiceItems() - - def onlySpeakDisplayedTextToggled(self, widget): - """Signal handler for the "toggled" signal for the GtkCheckButton - onlySpeakDisplayedText. In addition to updating the preferences, - set the sensitivity of the contextOptionsGrid. - - Arguments: - - widget: the component that generated the signal. - """ - - enable = widget.get_active() - self.prefsDict["onlySpeakDisplayedText"] = enable - self.get_widget("contextOptionsGrid").set_sensitive(not enable) - - - def _scanSerialDevices(self): - """Scan for available serial devices and return a list of paths.""" - import glob - devices = [] - patterns = [ - "/dev/ttyUSB*", - "/dev/ttyACM*", - "/dev/ttyS*", - "/dev/ttyAMA*", - "/dev/rfcomm*", - "/dev/serial/by-id/*", - ] - for pattern in patterns: - devices.extend(glob.glob(pattern)) - devices = sorted(set(devices)) - return devices - - def _setupHardwareDevice(self): - """Sets up the hardware device combo box with available serial ports. - - Populates the combo with scanned serial devices and restores the - previously saved selection if still available. - """ - if self.hardwareDeviceModel is None: - return - combobox = self.get_widget("hardwareDeviceCombo") - combobox.set_model(None) - self.hardwareDeviceModel.clear() - self.hardwareDeviceChoices = [] - - devices = self._scanSerialDevices() - saved_device = self.prefsDict.get("hardwareSpeechDevice", - settings.hardwareSpeechDevice) - - # Always include a "(none)" option so the user can clear the device - self.hardwareDeviceChoices.append("") - self.hardwareDeviceModel.append((0, "(none)")) - i = 1 - for device in devices: - self.hardwareDeviceChoices.append(device) - self.hardwareDeviceModel.append((i, device)) - i += 1 - - # If the saved device is not in the scanned list but is non-empty, - # append it so the user still sees their configured device. - if saved_device and saved_device not in devices: - self.hardwareDeviceChoices.append(saved_device) - self.hardwareDeviceModel.append((i, saved_device)) - i += 1 - - combobox.set_model(self.hardwareDeviceModel) - self._setHardwareDeviceChoice(saved_device) - - @staticmethod - def _isHardwareSpeechFactory(factory): - moduleName = getattr(factory, "__name__", "") - return moduleName.split(".")[-1] == "hardwarefactory" - - def _setHardwareDeviceChoice(self, device_name): - """Set the active item in the hardware device combo box. - - Arguments: - - device_name: the device path to select. - """ - if not self.hardwareDeviceChoices: - self.hardwareDeviceChoice = None - return - - for i, choice in enumerate(self.hardwareDeviceChoices): - if choice == device_name: - self.get_widget("hardwareDeviceCombo").set_active(i) - self.hardwareDeviceChoice = choice - return - - self.get_widget("hardwareDeviceCombo").set_active(0) - self.hardwareDeviceChoice = self.hardwareDeviceChoices[0] - - def _updateHardwareDeviceVisibility(self): - """Show or hide the hardware device combo based on speech system. - - The hardware device selector is only visible when the hardware - speech synthesizer factory is active. - """ - if self.hardwareDeviceModel is None: - return - is_hardware = False - if self.speechSystemsChoice: - try: - is_hardware = self._isHardwareSpeechFactory(self.speechSystemsChoice) - except Exception: - pass - - self.get_widget("hardwareDeviceLabel").set_visible(is_hardware) - self.get_widget("hardwareDeviceCombo").set_visible(is_hardware) - - def hardwareDeviceChanged(self, widget): - """Signal handler for the hardware device combo box changed signal. - - Arguments: - - widget: the component that generated the signal. - """ - if self.initializingSpeech: - return - - selected_index = widget.get_active() - if selected_index >= 0 and selected_index < len(self.hardwareDeviceChoices): - self.hardwareDeviceChoice = self.hardwareDeviceChoices[selected_index] - else: - self.hardwareDeviceChoice = None - - # Update runtime settings so the factory sees the new device - if self.hardwareDeviceChoice is not None: - settings.hardwareSpeechDevice = self.hardwareDeviceChoice - - def speechSystemsChanged(self, widget): - """Signal handler for the "changed" signal for the speechSystems - GtkComboBox widget. The user has selected a different speech - system. Clear the existing list of speech servers, and setup - a new list of speech servers based on the new choice. Setup a - new list of voices for the first speech server in the list. - - Arguments: - - widget: the component that generated the signal. - """ - - if self.initializingSpeech: - return - - selectedIndex = widget.get_active() - self.speechSystemsChoice = self.speechSystemsChoices[selectedIndex] - self._setupSpeechServers() - self._setupEchoSpeechServers() - self._setEchoVoiceItems() - self._updateHardwareDeviceVisibility() - - def speechServersChanged(self, widget): - """Signal handler for the "changed" signal for the speechServers - GtkComboBox widget. The user has selected a different speech - server. Clear the existing list of voices, and setup a new - list of voices based on the new choice. - - Arguments: - - widget: the component that generated the signal. - """ - - if self.initializingSpeech: - return - - selectedIndex = widget.get_active() - self.speechServersChoice = self.speechServersChoices[selectedIndex] - - # Whenever the speech servers change, we need to make sure we - # clear whatever family was in use by the current voice types. - # Otherwise, we can end up with family names from one server - # bleeding over (e.g., "Paul" from Fonix ends up getting in - # the "Default" voice type after we switch to eSpeak). - # - try: - del self.defaultVoice[acss.ACSS.FAMILY] - del self.uppercaseVoice[acss.ACSS.FAMILY] - del self.hyperlinkVoice[acss.ACSS.FAMILY] - del self.systemVoice[acss.ACSS.FAMILY] - except Exception: - pass - - self._setupVoices() - self._setEchoVoiceItems() - - def speechLanguagesChanged(self, widget): - """Signal handler for the "value_changed" signal for the languages - GtkComboBox widget. The user has selected a different voice - language. Save the new voice language name based on the new choice. - - Arguments: - - widget: the component that generated the signal. - """ - - if self.initializingSpeech: - return - - selectedIndex = widget.get_active() - try: - self.speechLanguagesChoice = self.speechLanguagesChoices[selectedIndex] - if (self.speechServersChoice, self.speechLanguagesChoice) in \ - self.selectedFamilyChoices: - i = self.selectedFamilyChoices[self.speechServersChoice, \ - self.speechLanguagesChoice] - family = self.speechFamiliesChoices[i] - name = family[speechserver.VoiceFamily.NAME] - language = family[speechserver.VoiceFamily.LANG] - dialect = family[speechserver.VoiceFamily.DIALECT] - variant = family[speechserver.VoiceFamily.VARIANT] - voiceType = self.get_widget("voiceTypesCombo").get_active() - self._setFamilyNameForVoiceType(voiceType, name, language, dialect, variant) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - # Remember the last family manually selected by the user for the - # current speech server. - # - if not selectedIndex == -1: - self.selectedLanguageChoices[self.speechServersChoice] = selectedIndex - - self._setupFamilies() - - def speechFamiliesChanged(self, widget): - """Signal handler for the "value_changed" signal for the families - GtkComboBox widget. The user has selected a different voice - family. Save the new voice family name based on the new choice. - - Arguments: - - widget: the component that generated the signal. - """ - - if self.initializingSpeech: - return - - selectedIndex = widget.get_active() - try: - family = self.speechFamiliesChoices[selectedIndex] - name = family[speechserver.VoiceFamily.NAME] - language = family[speechserver.VoiceFamily.LANG] - dialect = family[speechserver.VoiceFamily.DIALECT] - variant = family[speechserver.VoiceFamily.VARIANT] - voiceType = self.get_widget("voiceTypesCombo").get_active() - self._setFamilyNameForVoiceType(voiceType, name, language, dialect, variant) - if not self._updatingSpeechFamilies: - self._previewVoiceSelection(voiceType, name) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - # Remember the last family manually selected by the user for the - # current speech server. - # - if not selectedIndex == -1: - self.selectedFamilyChoices[self.speechServersChoice, \ - self.speechLanguagesChoice] = selectedIndex - - def voiceTypesChanged(self, widget): - """Signal handler for the "changed" signal for the voiceTypes - GtkComboBox widget. The user has selected a different voice - type. Setup the new family, rate, pitch and volume component - values based on the new choice. - - Arguments: - - widget: the component that generated the signal. - """ - - if self.initializingSpeech: - return - - voiceType = widget.get_active() - self._setVoiceSettingsForVoiceType(voiceType) - - def rateValueChanged(self, widget): - """Signal handler for the "value_changed" signal for the rateScale - GtkScale widget. The user has changed the current rate value. - Save the new rate value based on the currently selected voice - type. - - Arguments: - - widget: the component that generated the signal. - """ - - rate = widget.get_value() - voiceType = self.get_widget("voiceTypesCombo").get_active() - self._setRateForVoiceType(voiceType, rate) - voices = cthulhu.cthulhuApp.settingsManager.getSetting('voices') - voices.get(settings.DEFAULT_VOICE, {})[acss.ACSS.RATE] = rate - cthulhu.cthulhuApp.settingsManager.setSetting('voices', voices) - - def pitchValueChanged(self, widget): - """Signal handler for the "value_changed" signal for the pitchScale - GtkScale widget. The user has changed the current pitch value. - Save the new pitch value based on the currently selected voice - type. - - Arguments: - - widget: the component that generated the signal. - """ - - pitch = widget.get_value() - voiceType = self.get_widget("voiceTypesCombo").get_active() - self._setPitchForVoiceType(voiceType, pitch) - voices = cthulhu.cthulhuApp.settingsManager.getSetting('voices') - voices.get(settings.DEFAULT_VOICE, {})[acss.ACSS.AVERAGE_PITCH] = pitch - cthulhu.cthulhuApp.settingsManager.setSetting('voices', voices) - - def volumeValueChanged(self, widget): - """Signal handler for the "value_changed" signal for the voiceScale - GtkScale widget. The user has changed the current volume value. - Save the new volume value based on the currently selected voice - type. - - Arguments: - - widget: the component that generated the signal. - """ - - volume = widget.get_value() - voiceType = self.get_widget("voiceTypesCombo").get_active() - self._setVolumeForVoiceType(voiceType, volume) - voices = cthulhu.cthulhuApp.settingsManager.getSetting('voices') - voices.get(settings.DEFAULT_VOICE, {})[acss.ACSS.GAIN] = volume - cthulhu.cthulhuApp.settingsManager.setSetting('voices', voices) - - def useCustomEchoVoiceToggled(self, widget): - """Signal handler for enabling/disabling custom echo voice settings.""" - - self.prefsDict["useCustomEchoVoice"] = widget.get_active() - self._setEchoVoiceItems() - self._setupEchoSpeechFamilies() - - def useCustomEchoSpeechServerToggled(self, widget): - """Signal handler for enabling/disabling custom echo module override.""" - - self.prefsDict["useCustomEchoSpeechServer"] = widget.get_active() - self._setEchoVoiceItems() - self._setupEchoSpeechFamilies() - - def echoSpeechServersChanged(self, widget): - """Signal handler for selecting the echo speech-dispatcher module.""" - - if self.initializingEchoSpeech: - return - - selectedIndex = widget.get_active() - if selectedIndex < 0: - self.echoSpeechServersChoice = None - self.prefsDict["echoSpeechServerInfo"] = None - self._setupEchoSpeechFamilies() - return - - self.echoSpeechServersChoice = self.echoSpeechServersChoices[selectedIndex] - self.prefsDict["echoSpeechServerInfo"] = self.echoSpeechServersChoice.getInfo() - self._setupEchoSpeechFamilies() - - def echoSpeechFamiliesChanged(self, widget): - """Signal handler for selecting the echo voice family.""" - - if self.initializingEchoSpeech or self._updatingEchoSpeechFamilies: - return - - selectedIndex = widget.get_active() - if selectedIndex < 0: - self.echoSpeechFamiliesChoice = None - return - - self.echoSpeechFamiliesChoice = self.echoSpeechFamiliesChoices[selectedIndex] - self._setEchoVoiceFamily(self.echoSpeechFamiliesChoice) - - def echoRateValueChanged(self, widget): - """Signal handler for changing custom echo rate.""" - - if self.echoVoice is None: - self.echoVoice = acss.ACSS({}) - self.echoVoice[acss.ACSS.RATE] = widget.get_value() - self.echoVoice['established'] = True - - def echoPitchValueChanged(self, widget): - """Signal handler for changing custom echo pitch.""" - - if self.echoVoice is None: - self.echoVoice = acss.ACSS({}) - self.echoVoice[acss.ACSS.AVERAGE_PITCH] = widget.get_value() - self.echoVoice['established'] = True - - def echoVolumeValueChanged(self, widget): - """Signal handler for changing custom echo volume.""" - - if self.echoVoice is None: - self.echoVoice = acss.ACSS({}) - self.echoVoice[acss.ACSS.GAIN] = widget.get_value() - self.echoVoice['established'] = True - - def checkButtonToggled(self, widget): - """Signal handler for "toggled" signal for basic GtkCheckButton - widgets. The user has altered the state of the checkbox. - Set the preference to the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - # To use this default handler please make sure: - # The name of the setting that will be changed is: settingName - # The id of the widget in the ui should be: settingNameCheckButton - # - settingName = Gtk.Buildable.get_name(widget) - # strip "CheckButton" from the end. - settingName = settingName[:-11] - self.prefsDict[settingName] = widget.get_active() - if settingName in [ - "enableEchoByCharacter", - "enableEchoByWord", - "enableEchoBySentence", - "useCustomEchoForKey", - "useCustomEchoForCharacter", - "useCustomEchoForWord", - "useCustomEchoForSentence"]: - self._setEchoVoiceItems() - - def keyEchoChecked(self, widget): - """Signal handler for the "toggled" signal for the - keyEchoCheckbutton GtkCheckButton widget. The user has - [un]checked the 'Enable Key Echo' checkbox. Set the - 'enableKeyEcho' preference to the new value. [In]sensitize - the checkboxes for the various types of key echo, depending - upon whether this value is checked or unchecked. - - Arguments: - - widget: the component that generated the signal. - """ - - self.prefsDict["enableKeyEcho"] = widget.get_active() - self._setKeyEchoItems() - - def brailleSelectionChanged(self, widget): - """Signal handler for the "toggled" signal for the - brailleSelectionNoneButton, brailleSelection7Button, - brailleSelection8Button or brailleSelectionBothButton - GtkRadioButton widgets. The user has toggled the braille - selection indicator value. If this signal was generated - as the result of a radio button getting selected (as - opposed to a radio button losing the selection), set the - 'brailleSelectorIndicator' preference to the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - if widget.get_active(): - if widget.get_label() == guilabels.BRAILLE_DOT_7: - self.prefsDict["brailleSelectorIndicator"] = \ - settings.BRAILLE_UNDERLINE_7 - elif widget.get_label() == guilabels.BRAILLE_DOT_8: - self.prefsDict["brailleSelectorIndicator"] = \ - settings.BRAILLE_UNDERLINE_8 - elif widget.get_label() == guilabels.BRAILLE_DOT_7_8: - self.prefsDict["brailleSelectorIndicator"] = \ - settings.BRAILLE_UNDERLINE_BOTH - else: - self.prefsDict["brailleSelectorIndicator"] = \ - settings.BRAILLE_UNDERLINE_NONE - - def brailleLinkChanged(self, widget): - """Signal handler for the "toggled" signal for the - brailleLinkNoneButton, brailleLink7Button, - brailleLink8Button or brailleLinkBothButton - GtkRadioButton widgets. The user has toggled the braille - link indicator value. If this signal was generated - as the result of a radio button getting selected (as - opposed to a radio button losing the selection), set the - 'brailleLinkIndicator' preference to the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - if widget.get_active(): - if widget.get_label() == guilabels.BRAILLE_DOT_7: - self.prefsDict["brailleLinkIndicator"] = \ - settings.BRAILLE_UNDERLINE_7 - elif widget.get_label() == guilabels.BRAILLE_DOT_8: - self.prefsDict["brailleLinkIndicator"] = \ - settings.BRAILLE_UNDERLINE_8 - elif widget.get_label() == guilabels.BRAILLE_DOT_7_8: - self.prefsDict["brailleLinkIndicator"] = \ - settings.BRAILLE_UNDERLINE_BOTH - else: - self.prefsDict["brailleLinkIndicator"] = \ - settings.BRAILLE_UNDERLINE_NONE - - def brailleIndicatorChanged(self, widget): - """Signal handler for the "toggled" signal for the - textBrailleNoneButton, textBraille7Button, textBraille8Button - or textBrailleBothButton GtkRadioButton widgets. The user has - toggled the text attributes braille indicator value. If this signal - was generated as the result of a radio button getting selected - (as opposed to a radio button losing the selection), set the - 'textAttributesBrailleIndicator' preference to the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - if widget.get_active(): - if widget.get_label() == guilabels.BRAILLE_DOT_7: - self.prefsDict["textAttributesBrailleIndicator"] = \ - settings.BRAILLE_UNDERLINE_7 - elif widget.get_label() == guilabels.BRAILLE_DOT_8: - self.prefsDict["textAttributesBrailleIndicator"] = \ - settings.BRAILLE_UNDERLINE_8 - elif widget.get_label() == guilabels.BRAILLE_DOT_7_8: - self.prefsDict["textAttributesBrailleIndicator"] = \ - settings.BRAILLE_UNDERLINE_BOTH - else: - self.prefsDict["textAttributesBrailleIndicator"] = \ - settings.BRAILLE_UNDERLINE_NONE - - def punctuationLevelChanged(self, widget): - """Signal handler for the "toggled" signal for the noneButton, - someButton or allButton GtkRadioButton widgets. The user has - toggled the speech punctuation level value. If this signal - was generated as the result of a radio button getting selected - (as opposed to a radio button losing the selection), set the - 'verbalizePunctuationStyle' preference to the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - if widget.get_active(): - if widget.get_label() == guilabels.PUNCTUATION_STYLE_NONE: - self.prefsDict["verbalizePunctuationStyle"] = \ - settings.PUNCTUATION_STYLE_NONE - elif widget.get_label() == guilabels.PUNCTUATION_STYLE_SOME: - self.prefsDict["verbalizePunctuationStyle"] = \ - settings.PUNCTUATION_STYLE_SOME - elif widget.get_label() == guilabels.PUNCTUATION_STYLE_MOST: - self.prefsDict["verbalizePunctuationStyle"] = \ - settings.PUNCTUATION_STYLE_MOST - else: - self.prefsDict["verbalizePunctuationStyle"] = \ - settings.PUNCTUATION_STYLE_ALL - - def cthulhuModifierChanged(self, widget): - """Signal handler for the changed signal for the cthulhuModifierComboBox - Set the 'cthulhuModifierKeys' preference to the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - model = widget.get_model() - myIter = widget.get_active_iter() - cthulhuModifier = model[myIter][0] - self.prefsDict["cthulhuModifierKeys"] = cthulhuModifier.split(', ') - - def progressBarVerbosityChanged(self, widget): - """Signal handler for the changed signal for the progressBarVerbosity - GtkComboBox widget. Set the 'progressBarVerbosity' preference to - the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - model = widget.get_model() - myIter = widget.get_active_iter() - progressBarVerbosity = model[myIter][0] - if progressBarVerbosity == guilabels.PROGRESS_BAR_ALL: - self.prefsDict["progressBarVerbosity"] = \ - settings.PROGRESS_BAR_ALL - elif progressBarVerbosity == guilabels.PROGRESS_BAR_WINDOW: - self.prefsDict["progressBarVerbosity"] = \ - settings.PROGRESS_BAR_WINDOW - else: - self.prefsDict["progressBarVerbosity"] = \ - settings.PROGRESS_BAR_APPLICATION - - def capitalizationStyleChanged(self, widget): - model = widget.get_model() - myIter = widget.get_active_iter() - capitalizationStyle = model[myIter][0] - if capitalizationStyle == guilabels.CAPITALIZATION_STYLE_ICON: - self.prefsDict["capitalizationStyle"] = settings.CAPITALIZATION_STYLE_ICON - elif capitalizationStyle == guilabels.CAPITALIZATION_STYLE_SPELL: - self.prefsDict["capitalizationStyle"] = settings.CAPITALIZATION_STYLE_SPELL - else: - self.prefsDict["capitalizationStyle"] = settings.CAPITALIZATION_STYLE_NONE - self.script.speechAndVerbosityManager.update_capitalization_style() - - def sayAllStyleChanged(self, widget): - """Signal handler for the "changed" signal for the sayAllStyle - GtkComboBox widget. Set the 'sayAllStyle' preference to the - new value. - - Arguments: - - widget: the component that generated the signal. - """ - - model = widget.get_model() - myIter = widget.get_active_iter() - sayAllStyle = model[myIter][0] - if sayAllStyle == guilabels.SAY_ALL_STYLE_LINE: - self.prefsDict["sayAllStyle"] = settings.SAYALL_STYLE_LINE - elif sayAllStyle == guilabels.SAY_ALL_STYLE_SENTENCE: - self.prefsDict["sayAllStyle"] = settings.SAYALL_STYLE_SENTENCE - - def dateFormatChanged(self, widget): - """Signal handler for the "changed" signal for the dateFormat - GtkComboBox widget. Set the 'dateFormat' preference to the - new value. - - Arguments: - - widget: the component that generated the signal. - """ - - dateFormatCombo = widget.get_active() - if dateFormatCombo == DATE_FORMAT_LOCALE: - newFormat = messages.DATE_FORMAT_LOCALE - elif dateFormatCombo == DATE_FORMAT_NUMBERS_DM: - newFormat = messages.DATE_FORMAT_NUMBERS_DM - elif dateFormatCombo == DATE_FORMAT_NUMBERS_MD: - newFormat = messages.DATE_FORMAT_NUMBERS_MD - elif dateFormatCombo == DATE_FORMAT_NUMBERS_DMY: - newFormat = messages.DATE_FORMAT_NUMBERS_DMY - elif dateFormatCombo == DATE_FORMAT_NUMBERS_MDY: - newFormat = messages.DATE_FORMAT_NUMBERS_MDY - elif dateFormatCombo == DATE_FORMAT_NUMBERS_YMD: - newFormat = messages.DATE_FORMAT_NUMBERS_YMD - elif dateFormatCombo == DATE_FORMAT_FULL_DM: - newFormat = messages.DATE_FORMAT_FULL_DM - elif dateFormatCombo == DATE_FORMAT_FULL_MD: - newFormat = messages.DATE_FORMAT_FULL_MD - elif dateFormatCombo == DATE_FORMAT_FULL_DMY: - newFormat = messages.DATE_FORMAT_FULL_DMY - elif dateFormatCombo == DATE_FORMAT_FULL_MDY: - newFormat = messages.DATE_FORMAT_FULL_MDY - elif dateFormatCombo == DATE_FORMAT_FULL_YMD: - newFormat = messages.DATE_FORMAT_FULL_YMD - elif dateFormatCombo == DATE_FORMAT_ABBREVIATED_DM: - newFormat = messages.DATE_FORMAT_ABBREVIATED_DM - elif dateFormatCombo == DATE_FORMAT_ABBREVIATED_MD: - newFormat = messages.DATE_FORMAT_ABBREVIATED_MD - elif dateFormatCombo == DATE_FORMAT_ABBREVIATED_DMY: - newFormat = messages.DATE_FORMAT_ABBREVIATED_DMY - elif dateFormatCombo == DATE_FORMAT_ABBREVIATED_MDY: - newFormat = messages.DATE_FORMAT_ABBREVIATED_MDY - elif dateFormatCombo == DATE_FORMAT_ABBREVIATED_YMD: - newFormat = messages.DATE_FORMAT_ABBREVIATED_YMD - self.prefsDict["presentDateFormat"] = newFormat - - def timeFormatChanged(self, widget): - """Signal handler for the "changed" signal for the timeFormat - GtkComboBox widget. Set the 'timeFormat' preference to the - new value. - - Arguments: - - widget: the component that generated the signal. - """ - - timeFormatCombo = widget.get_active() - if timeFormatCombo == TIME_FORMAT_LOCALE: - newFormat = messages.TIME_FORMAT_LOCALE - elif timeFormatCombo == TIME_FORMAT_12_HM: - newFormat = messages.TIME_FORMAT_12_HM - elif timeFormatCombo == TIME_FORMAT_12_HMS: - newFormat = messages.TIME_FORMAT_12_HMS - elif timeFormatCombo == TIME_FORMAT_24_HMS: - newFormat = messages.TIME_FORMAT_24_HMS - elif timeFormatCombo == TIME_FORMAT_24_HMS_WITH_WORDS: - newFormat = messages.TIME_FORMAT_24_HMS_WITH_WORDS - elif timeFormatCombo == TIME_FORMAT_24_HM: - newFormat = messages.TIME_FORMAT_24_HM - elif timeFormatCombo == TIME_FORMAT_24_HM_WITH_WORDS: - newFormat = messages.TIME_FORMAT_24_HM_WITH_WORDS - self.prefsDict["presentTimeFormat"] = newFormat - - def speechVerbosityChanged(self, widget): - """Signal handler for the "toggled" signal for the speechBriefButton, - or speechVerboseButton GtkRadioButton widgets. The user has - toggled the speech verbosity level value. If this signal was - generated as the result of a radio button getting selected - (as opposed to a radio button losing the selection), set the - 'speechVerbosityLevel' preference to the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - if widget.get_active(): - if widget.get_label() == guilabels.VERBOSITY_LEVEL_BRIEF: - self.prefsDict["speechVerbosityLevel"] = \ - settings.VERBOSITY_LEVEL_BRIEF - else: - self.prefsDict["speechVerbosityLevel"] = \ - settings.VERBOSITY_LEVEL_VERBOSE - - def progressBarUpdateIntervalValueChanged(self, widget): - """Signal handler for the "value_changed" signal for the - progressBarUpdateIntervalSpinButton GtkSpinButton widget. - - Arguments: - - widget: the component that generated the signal. - """ - - self.prefsDict["progressBarUpdateInterval"] = widget.get_value_as_int() - - def brailleFlashTimeValueChanged(self, widget): - self.prefsDict["brailleFlashTime"] = widget.get_value_as_int() * 1000 - - def abbrevRolenamesChecked(self, widget): - """Signal handler for the "toggled" signal for the abbrevRolenames - GtkCheckButton widget. The user has [un]checked the 'Abbreviated - Rolenames' checkbox. Set the 'brailleRolenameStyle' preference - to the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - if widget.get_active(): - self.prefsDict["brailleRolenameStyle"] = \ - settings.BRAILLE_ROLENAME_STYLE_SHORT - else: - self.prefsDict["brailleRolenameStyle"] = \ - settings.BRAILLE_ROLENAME_STYLE_LONG - - def brailleVerbosityChanged(self, widget): - """Signal handler for the "toggled" signal for the brailleBriefButton, - or brailleVerboseButton GtkRadioButton widgets. The user has - toggled the braille verbosity level value. If this signal was - generated as the result of a radio button getting selected - (as opposed to a radio button losing the selection), set the - 'brailleVerbosityLevel' preference to the new value. - - Arguments: - - widget: the component that generated the signal. - """ - - if widget.get_active(): - if widget.get_label() == guilabels.VERBOSITY_LEVEL_BRIEF: - self.prefsDict["brailleVerbosityLevel"] = \ - settings.VERBOSITY_LEVEL_BRIEF - else: - self.prefsDict["brailleVerbosityLevel"] = \ - settings.VERBOSITY_LEVEL_VERBOSE - - def keyModifiedToggle(self, cell, path, model, col): - """When the user changes a checkbox field (boolean field)""" - - model[path][col] = not model[path][col] - return - - def editingKey(self, cell, editable, path, treeModel): - """Starts user input of a Key for a selected key binding""" - - self._presentMessage(messages.KB_ENTER_NEW_KEY) - cthulhu_state.capturingKeys = True - try: - script_manager.get_manager().get_active_script().removeKeyGrabs() - except Exception: - pass - try: - input_event_manager.get_manager().unmap_all_modifiers() - except Exception: - pass - self._unmapCthulhuModifiersForCapture() - editable.connect('key-press-event', self.kbKeyPressed) - return - - def _unmapCthulhuModifiersForCapture(self): - """Unmap Cthulhu modifier keys so they can be captured as bindings.""" - device = cthulhu_state.device - if device is None: - return - - for modifierKey in settings.cthulhuModifierKeys: - keycode = keybindings.getKeycode(modifierKey) - if keycode == 0 and modifierKey == "Shift_Lock": - keycode = keybindings.getKeycode("Caps_Lock") - if keycode: - try: - device.unmap_modifier(keycode) - except Exception: - pass - - def editingCanceledKey(self, editable): - """Stops user input of a Key for a selected key binding""" - - cthulhu_state.capturingKeys = False - self._capturedKey = [] - try: - script_manager.get_manager().get_active_script().refreshKeyGrabs() - except Exception: - pass - return - - def _processKeyCaptured(self, keyPressedEvent): - """Called when a new key event arrives and we are capturing keys. - (used for key bindings redefinition) - """ - - # We want the keyname rather than the printable character. - # If it's not on the keypad, get the name of the unshifted - # character. (i.e. "1" instead of "!") - # - keycode = keyPressedEvent.hardware_keycode - keymap = Gdk.Keymap.get_default() - entries_for_keycode = keymap.get_entries_for_keycode(keycode) - entries = entries_for_keycode[-1] - eventString = Gdk.keyval_name(entries[0]) - eventState = keyPressedEvent.state - eventKeyvalName = Gdk.keyval_name(keyPressedEvent.keyval) - - cthulhuMods = settings.cthulhuModifierKeys - if eventKeyvalName in cthulhuMods: - eventString = eventKeyvalName - self._capturedKey = ['', keybindings.CTHULHU_MODIFIER_MASK, 0] - return False - if eventKeyvalName == "KP_0" \ - and "KP_Insert" in cthulhuMods \ - and eventState & Gdk.ModifierType.SHIFT_MASK: - eventString = "KP_Insert" - self._capturedKey = ['', keybindings.CTHULHU_MODIFIER_MASK, 0] - return False - - modifierKeys = ['Alt_L', 'Alt_R', 'Control_L', 'Control_R', - 'Shift_L', 'Shift_R', 'Meta_L', 'Meta_R', - 'Num_Lock', 'Caps_Lock', 'Shift_Lock'] - if eventString in modifierKeys: - return False - - eventState = eventState & Gtk.accelerator_get_default_mod_mask() - if not self._capturedKey \ - or eventString in ['Return', 'Escape']: - self._capturedKey = [eventString, eventState, 1] - return True - - string, modifiers, clickCount = self._capturedKey - isCthulhuModifier = modifiers & keybindings.CTHULHU_MODIFIER_MASK - if isCthulhuModifier: - eventState |= keybindings.CTHULHU_MODIFIER_MASK - self._capturedKey = [eventString, eventState, clickCount + 1] - - return True - - def kbKeyPressed(self, editable, event): - """Special handler for the key_pressed events when editing the - keybindings. This lets us control what gets inserted into the - entry. - """ - - keyProcessed = self._processKeyCaptured(event) - if not keyProcessed: - return True - - if not self._capturedKey: - return False - - keyName, modifiers, clickCount = self._capturedKey - if not keyName or keyName in ["Return", "Escape"]: - return False - - isCthulhuModifier = modifiers & keybindings.CTHULHU_MODIFIER_MASK - if keyName in ["Delete", "BackSpace"] and not isCthulhuModifier: - editable.set_text("") - self._presentMessage(messages.KB_DELETED) - self._capturedKey = [] - self.newBinding = None - return True - - self.newBinding = keybindings.KeyBinding(keyName, - keybindings.defaultModifierMask, - modifiers, - None, - clickCount) - modifierNames = keybindings.getModifierNames(modifiers) - clickCountString = self._clickCountToString(clickCount) - newString = modifierNames + keyName + clickCountString - description = self.pendingKeyBindings.get(newString) - - if description is None: - - def match(x): - return x.keysymstring == keyName and x.modifiers == modifiers \ - and x.click_count == clickCount and x.handler - - matches = list(filter(match, self.kbindings.keyBindings)) - if matches: - description = matches[0].handler.description - - if description: - msg = messages.KB_ALREADY_BOUND % description - delay = int(1000 * settings.doubleClickTimeout) - GLib.timeout_add(delay, self._presentMessage, msg) - else: - msg = messages.KB_CAPTURED % newString - editable.set_text(newString) - self._presentMessage(msg) - - return True - - def editedKey(self, cell, path, new_text, treeModel, - modMask, modUsed, key, click_count, text): - """The user changed the key for a Keybinding: update the model of - the treeview. - """ - - cthulhu_state.capturingKeys = False - self._capturedKey = [] - try: - script_manager.get_manager().get_active_script().refreshKeyGrabs() - except Exception: - pass - myiter = treeModel.get_iter_from_string(path) - try: - originalBinding = treeModel.get_value(myiter, text) - except Exception: - originalBinding = '' - modified = (originalBinding != new_text) - - try: - string = self.newBinding.keysymstring - mods = self.newBinding.modifiers - clickCount = self.newBinding.click_count - except Exception: - string = '' - mods = 0 - clickCount = 1 - - mods = mods & Gdk.ModifierType.MODIFIER_MASK - if mods & (1 << Atspi.ModifierType.SHIFTLOCK) \ - and mods & keybindings.CTHULHU_MODIFIER_MASK: - mods ^= (1 << Atspi.ModifierType.SHIFTLOCK) - - treeModel.set(myiter, - modMask, str(keybindings.defaultModifierMask), - modUsed, str(int(mods)), - key, string, - text, new_text, - click_count, str(clickCount), - MODIF, modified) - speech.stop() - if new_text: - message = messages.KB_CAPTURED_CONFIRMATION % new_text - description = treeModel.get_value(myiter, DESCRIP) - self.pendingKeyBindings[new_text] = description - else: - message = messages.KB_DELETED_CONFIRMATION - - if modified: - self._presentMessage(message) - self.pendingKeyBindings[originalBinding] = "" - - return - - def presentToolTipsChecked(self, widget): - """Signal handler for the "toggled" signal for the - presentToolTipsCheckButton GtkCheckButton widget. - The user has [un]checked the 'Present ToolTips' - checkbox. Set the 'presentToolTips' - preference to the new value if the user can present tooltips. - - Arguments: - - widget: the component that generated the signal. - """ - - self.prefsDict["presentToolTips"] = widget.get_active() - - def keyboardLayoutChanged(self, widget): - """Signal handler for the "toggled" signal for the generalDesktopButton, - or generalLaptopButton GtkRadioButton widgets. The user has - toggled the keyboard layout value. If this signal was - generated as the result of a radio button getting selected - (as opposed to a radio button losing the selection), set the - 'keyboardLayout' preference to the new value. Also set the - matching list of Cthulhu modifier keys - - Arguments: - - widget: the component that generated the signal. - """ - - if widget.get_active(): - if widget.get_label() == guilabels.KEYBOARD_LAYOUT_DESKTOP: - self.prefsDict["keyboardLayout"] = \ - settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP - self.prefsDict["cthulhuModifierKeys"] = \ - settings.DESKTOP_MODIFIER_KEYS - else: - self.prefsDict["keyboardLayout"] = \ - settings.GENERAL_KEYBOARD_LAYOUT_LAPTOP - self.prefsDict["cthulhuModifierKeys"] = \ - settings.LAPTOP_MODIFIER_KEYS - - def pronunciationAddButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the - pronunciationAddButton GtkButton widget. The user has clicked - the Add button on the Pronunciation pane. A new row will be - added to the end of the pronunciation dictionary list. Both the - actual and replacement strings will initially be set to an empty - string. Focus will be moved to that row. - - Arguments: - - widget: the component that generated the signal. - """ - - model = self.pronunciationView.get_model() - thisIter = model.append() - model.set(thisIter, ACTUAL, "", REPLACEMENT, "") - path = model.get_path(thisIter) - col = self.pronunciationView.get_column(0) - self.pronunciationView.grab_focus() - self.pronunciationView.set_cursor(path, col, True) - - def pronunciationDeleteButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the - pronunciationDeleteButton GtkButton widget. The user has clicked - the Delete button on the Pronunciation pane. The row in the - pronunciation dictionary list with focus will be deleted. - - Arguments: - - widget: the component that generated the signal. - """ - - model, oldIter = self.pronunciationView.get_selection().get_selected() - model.remove(oldIter) - - def textSelectAllButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the - textSelectAllButton GtkButton widget. The user has clicked - the Speak all button. Check all the text attributes and - then update the "enabledSpokenTextAttributes" and - "enabledBrailledTextAttributes" preference strings. - - Arguments: - - widget: the component that generated the signal. - """ - - attributes = cthulhu.cthulhuApp.settingsManager.getSetting('allTextAttributes') - self._setSpokenTextAttributes( - self.getTextAttributesView, attributes, True) - self._setBrailledTextAttributes( - self.getTextAttributesView, attributes, True) - self._updateTextDictEntry() - - def textUnselectAllButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the - textUnselectAllButton GtkButton widget. The user has clicked - the Speak none button. Uncheck all the text attributes and - then update the "enabledSpokenTextAttributes" and - "enabledBrailledTextAttributes" preference strings. - - Arguments: - - widget: the component that generated the signal. - """ - - attributes = cthulhu.cthulhuApp.settingsManager.getSetting('allTextAttributes') - self._setSpokenTextAttributes( - self.getTextAttributesView, attributes, False) - self._setBrailledTextAttributes( - self.getTextAttributesView, attributes, False) - self._updateTextDictEntry() - - def textResetButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the - textResetButton GtkButton widget. The user has clicked - the Reset button. Reset all the text attributes to their - initial state and then update the "enabledSpokenTextAttributes" - and "enabledBrailledTextAttributes" preference strings. - - Arguments: - - widget: the component that generated the signal. - """ - - attributes = cthulhu.cthulhuApp.settingsManager.getSetting('allTextAttributes') - self._setSpokenTextAttributes( - self.getTextAttributesView, attributes, False) - self._setBrailledTextAttributes( - self.getTextAttributesView, attributes, False) - - attributes = cthulhu.cthulhuApp.settingsManager.getSetting('enabledSpokenTextAttributes') - self._setSpokenTextAttributes( - self.getTextAttributesView, attributes, True) - - attributes = \ - cthulhu.cthulhuApp.settingsManager.getSetting('enabledBrailledTextAttributes') - self._setBrailledTextAttributes( - self.getTextAttributesView, attributes, True) - - self._updateTextDictEntry() - - def textMoveToTopButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the - textMoveToTopButton GtkButton widget. The user has clicked - the Move to top button. Move the selected rows in the text - attribute view to the very top of the list and then update - the "enabledSpokenTextAttributes" and "enabledBrailledTextAttributes" - preference strings. - - Arguments: - - widget: the component that generated the signal. - """ - - textSelection = self.getTextAttributesView.get_selection() - [model, paths] = textSelection.get_selected_rows() - for path in paths: - thisIter = model.get_iter(path) - model.move_after(thisIter, None) - self._updateTextDictEntry() - - def textMoveUpOneButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the - textMoveUpOneButton GtkButton widget. The user has clicked - the Move up one button. Move the selected rows in the text - attribute view up one row in the list and then update the - "enabledSpokenTextAttributes" and "enabledBrailledTextAttributes" - preference strings. - - Arguments: - - widget: the component that generated the signal. - """ - - textSelection = self.getTextAttributesView.get_selection() - [model, paths] = textSelection.get_selected_rows() - for path in paths: - thisIter = model.get_iter(path) - indices = path.get_indices() - if indices[0]: - otherIter = model.iter_nth_child(None, indices[0]-1) - model.swap(thisIter, otherIter) - self._updateTextDictEntry() - - def textMoveDownOneButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the - textMoveDownOneButton GtkButton widget. The user has clicked - the Move down one button. Move the selected rows in the text - attribute view down one row in the list and then update the - "enabledSpokenTextAttributes" and "enabledBrailledTextAttributes" - preference strings. - - Arguments: - - widget: the component that generated the signal. - """ - - textSelection = self.getTextAttributesView.get_selection() - [model, paths] = textSelection.get_selected_rows() - noRows = model.iter_n_children(None) - for path in paths: - thisIter = model.get_iter(path) - indices = path.get_indices() - if indices[0] < noRows-1: - otherIter = model.iter_next(thisIter) - model.swap(thisIter, otherIter) - self._updateTextDictEntry() - - def textMoveToBottomButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the - textMoveToBottomButton GtkButton widget. The user has clicked - the Move to bottom button. Move the selected rows in the text - attribute view to the bottom of the list and then update the - "enabledSpokenTextAttributes" and "enabledBrailledTextAttributes" - preference strings. - - Arguments: - - widget: the component that generated the signal. - """ - - textSelection = self.getTextAttributesView.get_selection() - [model, paths] = textSelection.get_selected_rows() - for path in paths: - thisIter = model.get_iter(path) - model.move_before(thisIter, None) - self._updateTextDictEntry() - - def helpButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the helpButton - GtkButton widget. The user has clicked the Help button. - - Arguments: - - widget: the component that generated the signal. - """ - - self.script.learnModePresenter.show_help(page="preferences") - - def restoreSettings(self): - """Restore the settings we saved away when opening the preferences - dialog.""" - # Restore the default rate/pitch/gain, - # in case the user played with the sliders. - # - voices = cthulhu.cthulhuApp.settingsManager.getSetting('voices') - defaultVoice = voices.get(settings.DEFAULT_VOICE) - if defaultVoice is not None: - defaultVoice[acss.ACSS.GAIN] = self.savedGain - defaultVoice[acss.ACSS.AVERAGE_PITCH] = self.savedPitch - defaultVoice[acss.ACSS.RATE] = self.savedRate - - def saveBasicSettings(self): - if not self._isInitialSetup: - self.restoreSettings() - - if self.soundSinkCombo is not None: - activeIndex = self.soundSinkCombo.get_active() - if activeIndex >= 0: - self.prefsDict["soundSink"] = self._soundSinkChoices[activeIndex][0] - - enable = self.get_widget("speechSupportCheckButton").get_active() - self.prefsDict["enableSpeech"] = enable - - if self.speechSystemsChoice: - self.prefsDict["speechServerFactory"] = \ - self.speechSystemsChoice.__name__ - - # Save hardware speech device setting when hardware factory is active - if self.speechSystemsChoice and \ - self._isHardwareSpeechFactory(self.speechSystemsChoice): - if self.hardwareDeviceChoice is not None: - self.prefsDict["hardwareSpeechDevice"] = self.hardwareDeviceChoice - else: - self.prefsDict["hardwareSpeechDevice"] = "" - else: - self.prefsDict["hardwareSpeechDevice"] = settings.hardwareSpeechDevice - - speechServerChoice = self._getSpeechServerChoiceForSave() - if speechServerChoice: - self.prefsDict["speechServerInfo"] = \ - speechServerChoice.getInfo() - else: - activeSpeechInfo = speech.getInfo() - if activeSpeechInfo: - self.prefsDict["speechServerInfo"] = activeSpeechInfo - - runtimeSpeechServerInfo = cthulhu.cthulhuApp.settingsManager.getSetting( - "speechServerInfo" - ) - if runtimeSpeechServerInfo and not self.prefsDict.get("speechServerInfo"): - self.prefsDict["speechServerInfo"] = runtimeSpeechServerInfo - - existingSpeechServerInfo = self.prefsDict.get("speechServerInfo") - if existingSpeechServerInfo: - self.prefsDict["speechServerInfo"] = existingSpeechServerInfo - - if self.defaultVoice is not None: - self.prefsDict["voices"] = { - settings.DEFAULT_VOICE: acss.ACSS(self.defaultVoice), - settings.UPPERCASE_VOICE: acss.ACSS(self.uppercaseVoice), - settings.HYPERLINK_VOICE: acss.ACSS(self.hyperlinkVoice), - settings.SYSTEM_VOICE: acss.ACSS(self.systemVoice), - } - - self.prefsDict["useCustomEchoVoice"] = \ - self.get_widget("useCustomEchoVoiceCheckButton").get_active() - self.prefsDict["useCustomEchoSpeechServer"] = \ - self.get_widget("useCustomEchoSpeechServerCheckButton").get_active() - self.prefsDict["useCustomEchoForKey"] = \ - self.get_widget("useCustomEchoForKeyCheckButton").get_active() - self.prefsDict["useCustomEchoForCharacter"] = \ - self.get_widget("useCustomEchoForCharacterCheckButton").get_active() - self.prefsDict["useCustomEchoForWord"] = \ - self.get_widget("useCustomEchoForWordCheckButton").get_active() - self.prefsDict["useCustomEchoForSentence"] = \ - self.get_widget("useCustomEchoForSentenceCheckButton").get_active() - - if self.echoVoice is None: - self.echoVoice = acss.ACSS({}) - - # Persist slider values directly so saving does not depend on - # value-changed signal timing. - self.echoVoice[acss.ACSS.RATE] = self.get_widget("echoRateScale").get_value() - self.echoVoice[acss.ACSS.AVERAGE_PITCH] = self.get_widget("echoPitchScale").get_value() - self.echoVoice[acss.ACSS.GAIN] = self.get_widget("echoVolumeScale").get_value() - self.echoVoice['established'] = True - self.prefsDict["echoVoice"] = acss.ACSS(self.echoVoice) - - echoSpeechServerChoice = self._getEchoSpeechServerChoiceForSave() - if echoSpeechServerChoice: - self.prefsDict["echoSpeechServerInfo"] = echoSpeechServerChoice.getInfo() - else: - self.prefsDict["echoSpeechServerInfo"] = None - - def applyButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the applyButton - GtkButton widget. The user has clicked the Apply button. - Write out the users preferences. Shut down any active speech servers - that were started. Reload the users preferences to get the new - speech, braille and key echo value to take effect. Do not dismiss - the configuration window. - - Arguments: - - widget: the component that generated the signal. - """ - - msg = "PREFERENCES DIALOG: Apply button clicked" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - self.saveBasicSettings() - activeProfile = self.getComboBoxList(self.profilesCombo) - startingProfile = self.getComboBoxList(self.startingProfileCombo) - - self.prefsDict['profile'] = activeProfile - self.prefsDict['activeProfile'] = activeProfile - self.prefsDict['startingProfile'] = startingProfile - cthulhu.cthulhuApp.settingsManager.setStartingProfile(startingProfile) - - self._apply_plugin_changes() - self.writeUserPreferences() - cthulhu.loadUserSettings(self.script) - self._initSoundThemeState() - self._refresh_dynamic_plugin_tabs() - braille.checkBrailleSetting() - self._initSpeechState() - self._initEchoSpeechState() - self._populateKeyBindings() - self.__initProfileCombo() - - msg = "PREFERENCES DIALOG: Handling Apply button click complete" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - def cancelButtonClicked(self, widget): - """Signal handler for the "clicked" signal for the cancelButton - GtkButton widget. The user has clicked the Cancel button. - Don't write out the preferences. Destroy the configuration window. - - Arguments: - - widget: the component that generated the signal. - """ - - msg = "PREFERENCES DIALOG: Cancel button clicked" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - self.windowClosed(widget) - self.get_widget("cthulhuSetupWindow").destroy() - - msg = "PREFERENCES DIALOG: Handling Cancel button click complete" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - def okButtonClicked(self, widget=None): - """Signal handler for the "clicked" signal for the okButton - GtkButton widget. The user has clicked the OK button. - Write out the users preferences. Shut down any active speech servers - that were started. Reload the users preferences to get the new - speech, braille and key echo value to take effect. Hide the - configuration window. - - Arguments: - - widget: the component that generated the signal. - """ - - msg = "PREFERENCES DIALOG: OK button clicked" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - self.applyButtonClicked(widget) - self._cleanupSpeechServers() - self.get_widget("cthulhuSetupWindow").destroy() - - msg = "PREFERENCES DIALOG: Handling OK button click complete" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - def windowClosed(self, widget): - """Signal handler for the "closed" signal for the cthulhuSetupWindow - GtkWindow widget. This is effectively the same as pressing the - cancel button, except the window is destroyed for us. - - Arguments: - - widget: the component that generated the signal. - """ - - msg = "PREFERENCES DIALOG: Window is being closed" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - self.suspendEvents() - - factory = cthulhu.cthulhuApp.settingsManager.getSetting('speechServerFactory') - if factory: - self._setSpeechSystemsChoice(factory) - - server = cthulhu.cthulhuApp.settingsManager.getSetting('speechServerInfo') - if server: - self._setSpeechServersChoice(server) - - self._cleanupSpeechServers() - self.restoreSettings() - - GObject.timeout_add(1000, self.resumeEvents) - - msg = "PREFERENCES DIALOG: Window closure complete" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - def windowDestroyed(self, widget): - """Signal handler for the "destroyed" signal for the cthulhuSetupWindow - GtkWindow widget. Reset cthulhu_state.cthulhuOS to None, so that the - GUI can be rebuilt from the GtkBuilder file the next time the user - wants to display the configuration GUI. - - Arguments: - - widget: the component that generated the signal. - """ - - msg = "PREFERENCES DIALOG: Window is being destroyed" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - self.keyBindView.set_model(None) - self.getTextAttributesView.set_model(None) - self.pronunciationView.set_model(None) - self.keyBindView.set_headers_visible(False) - self.getTextAttributesView.set_headers_visible(False) - self.pronunciationView.set_headers_visible(False) - self.keyBindView.hide() - self.getTextAttributesView.hide() - self.pronunciationView.hide() - cthulhu_state.cthulhuOS = None - - msg = "PREFERENCES DIALOG: Window destruction complete" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - def resumeEvents(self): - msg = "PREFERENCES DIALOG: Re-registering floody events." - debug.printMessage(debug.LEVEL_ALL, msg, True) - - manager = event_manager.getManager() - manager.registerListener("object:state-changed:showing") - manager.registerListener("object:children-changed:remove") - manager.registerListener("object:selection-changed") - manager.registerListener("object:property-change:accessible-name") - - def suspendEvents(self): - msg = "PREFERENCES DIALOG: Deregistering floody events." - debug.printMessage(debug.LEVEL_ALL, msg, True) - - manager = event_manager.getManager() - manager.deregisterListener("object:state-changed:showing") - manager.deregisterListener("object:children-changed:remove") - manager.deregisterListener("object:selection-changed") - manager.deregisterListener("object:property-change:accessible-name") - - def showProfileGUI(self, widget): - """Show profile Dialog to add a new one""" - - cthulhu_gui_profile.showProfileUI(self) - - def saveProfile(self, profileToSaveLabel): - """Creates a new profile based on the name profileToSaveLabel and - updates the Preferences dialog combo boxes accordingly.""" - - if not profileToSaveLabel: - return - profileToSave = profileToSaveLabel.replace(' ', '_').lower() - profile = [profileToSaveLabel, profileToSave] - - def saveActiveProfile(newProfile = True): - if newProfile: - activeProfileIter = self.profilesComboModel.append(profile) - self.profilesCombo.set_active_iter(activeProfileIter) - - self.prefsDict['profile'] = profile - self.prefsDict['activeProfile'] = profile - self.saveBasicSettings() - self.writeUserPreferences() - - availableProfiles = [p[1] for p in self.__getAvailableProfiles()] - if isinstance(profileToSave, str) \ - and profileToSave != '' \ - and profileToSave not in availableProfiles \ - and profileToSave != self._defaultProfile[1]: - saveActiveProfile() - else: - if profileToSave is not None: - message = guilabels.PROFILE_CONFLICT_MESSAGE % \ - f"{GLib.markup_escape_text(profileToSaveLabel)}" - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL, - type=Gtk.MessageType.INFO, - buttons=Gtk.ButtonsType.YES_NO) - dialog.set_markup(f"{guilabels.PROFILE_CONFLICT_LABEL}") - dialog.format_secondary_markup(message) - dialog.set_title(guilabels.PROFILE_CONFLICT_TITLE) - response = dialog.run() - if response == Gtk.ResponseType.YES: - dialog.destroy() - saveActiveProfile(False) - else: - dialog.destroy() - - - def removeProfileButtonClicked(self, widget): - """Remove profile button clicked handler - - If we removed the last profile, a default one will automatically get - added back by the settings manager. - """ - - oldProfile = self.getComboBoxList(self.profilesCombo) - - message = guilabels.PROFILE_REMOVE_MESSAGE % \ - f"{GLib.markup_escape_text(oldProfile[0])}" - dialog = Gtk.MessageDialog(self.window, Gtk.DialogFlags.MODAL, - type=Gtk.MessageType.INFO, - buttons=Gtk.ButtonsType.YES_NO) - dialog.set_markup(f"{guilabels.PROFILE_REMOVE_LABEL}") - dialog.format_secondary_markup(message) - if dialog.run() == Gtk.ResponseType.YES: - # If we remove the currently used starting profile, fallback on - # the first listed profile, or the default one if there's - # nothing better - newStartingProfile = self.prefsDict.get('startingProfile') - if not newStartingProfile or newStartingProfile == oldProfile: - newStartingProfile = self._defaultProfile - for row in self.profilesComboModel: - rowProfile = row[:] - if rowProfile != oldProfile: - newStartingProfile = rowProfile - break - # Update the current profile to the active profile unless we're - # removing that one, in which case we use the new starting - # profile - newProfile = self.prefsDict.get('activeProfile') - if not newProfile or newProfile == oldProfile: - newProfile = newStartingProfile - - cthulhu.cthulhuApp.settingsManager.removeProfile(oldProfile[1]) - self.loadProfile(newProfile) - - # Make sure nothing is referencing the removed profile anymore - startingProfile = self.prefsDict.get('startingProfile') - if not startingProfile or startingProfile == oldProfile: - self.prefsDict['startingProfile'] = newStartingProfile - cthulhu.cthulhuApp.settingsManager.setStartingProfile(newStartingProfile) - self.writeUserPreferences() - - dialog.destroy() - - def loadProfileButtonClicked(self, widget): - """Load profile button clicked handler""" - - if self._isInitialSetup: - return - - dialog = Gtk.MessageDialog(None, - Gtk.DialogFlags.MODAL, - type=Gtk.MessageType.INFO, - buttons=Gtk.ButtonsType.YES_NO) - - dialog.set_markup(f"{guilabels.PROFILE_LOAD_LABEL}") - dialog.format_secondary_markup(guilabels.PROFILE_LOAD_MESSAGE) - response = dialog.run() - if response == Gtk.ResponseType.YES: - dialog.destroy() - self.loadSelectedProfile() - else: - dialog.destroy() - - def loadSelectedProfile(self): - """Load selected profile""" - - activeProfile = self.getComboBoxList(self.profilesCombo) - self.loadProfile(activeProfile) - - def loadProfile(self, profile): - """Load profile""" - - self.saveBasicSettings() - - self.prefsDict['activeProfile'] = profile - cthulhu.cthulhuApp.settingsManager.setProfile(profile[1]) - self.prefsDict = cthulhu.cthulhuApp.settingsManager.getGeneralSettings(profile[1]) - - cthulhu.loadUserSettings(skipReloadMessage=True) - - self._initGUIState() - self._initSoundThemeState() - - braille.checkBrailleSetting() - - self._initSpeechState() - self._initEchoSpeechState() - - self._populateKeyBindings() - - self.__initProfileCombo() - - # Indentation signal handlers - - def enableIndentationToggled(self, widget): - """Enable indentation checkbox toggled handler.""" - enabled = widget.get_active() - self.prefsDict["enableIndentation"] = enabled - self._updateIndentationControlsState(enabled) - - def indentationModeToggled(self, widget): - """Indentation mode radio toggled handler.""" - if not widget.get_active(): - return - - mapping = { - "indentationSpeechButton": settings.INDENTATION_PRESENTATION_SPEECH, - "indentationBeepsButton": settings.INDENTATION_PRESENTATION_BEEPS, - "indentationSpeechAndBeepsButton": settings.INDENTATION_PRESENTATION_SPEECH_AND_BEEPS, - } - widgetName = Gtk.Buildable.get_name(widget) - mode = mapping.get(widgetName) - if mode is not None: - self.prefsDict["indentationPresentationMode"] = mode - - # AI Assistant signal handlers - - def enableAIToggled(self, widget): - """Enable AI Assistant checkbox toggled handler""" - enabled = widget.get_active() - self.prefsDict["aiAssistantEnabled"] = enabled - self._updateAIControlsState(enabled) - - def aiProviderChanged(self, widget): - """AI Provider combo box changed handler""" - providers = [ - settings.AI_PROVIDER_CLAUDE_CODE, - settings.AI_PROVIDER_CODEX, - settings.AI_PROVIDER_GEMINI, - settings.AI_PROVIDER_OLLAMA - ] - activeIndex = widget.get_active() - if 0 <= activeIndex < len(providers): - provider = providers[activeIndex] - self.prefsDict["aiProvider"] = provider - self._updateProviderControls(provider) - - def aiApiKeyChanged(self, widget): - """AI API key file entry changed handler""" - self.prefsDict["aiApiKeyFile"] = widget.get_text() - - def aiOllamaModelChanged(self, widget): - """AI Ollama model entry changed handler""" - self.prefsDict["aiOllamaModel"] = widget.get_text() - - def aiOllamaEndpointChanged(self, widget): - """AI Ollama endpoint entry changed handler""" - self.prefsDict["aiOllamaEndpoint"] = widget.get_text() - - def aiGetClaudeKeyClicked(self, widget): - """Get Claude API Key button clicked handler""" - import subprocess - import os - - try: - # Open browser to Claude API key page - subprocess.run(["xdg-open", "https://console.anthropic.com/"], check=True) - - # Show dialog with instructions - dialog = Gtk.MessageDialog( - parent=self, - flags=Gtk.DialogFlags.MODAL, - type=Gtk.MessageType.INFO, - buttons=Gtk.ButtonsType.OK, - message_format="Claude API Key Setup" - ) - dialog.format_secondary_text( - "Browser opened to get your Claude API key.\n\n" - "💡 TIP: Claude offers $5 free credit, then ~$20/month for Pro.\n" - "Ollama is also available as a free alternative.\n\n" - "Steps:\n" - "1. Sign up or log in to your Anthropic account\n" - "2. Go to 'API Keys' in Account Settings\n" - "3. Click 'Create Key' and copy the API key\n" - "4. Click OK below when you have your key ready\n" - "5. Paste the API key when prompted" - ) - dialog.run() - dialog.destroy() - - # Show API key input dialog - key_dialog = Gtk.MessageDialog( - parent=self, - flags=Gtk.DialogFlags.MODAL, - type=Gtk.MessageType.QUESTION, - buttons=Gtk.ButtonsType.OK_CANCEL, - message_format="Enter Claude API Key" - ) - key_dialog.format_secondary_text("Paste your Claude API key (starts with 'sk-ant-'):") - - # Add text entry to dialog - entry = Gtk.Entry() - entry.set_placeholder_text("sk-ant-your-api-key-here...") - entry.set_visibility(False) # Hide key for security - entry.set_width_chars(50) - key_dialog.get_content_area().pack_start(entry, False, False, 0) - entry.show() - - response = key_dialog.run() - api_key = entry.get_text().strip() - key_dialog.destroy() - - if response == Gtk.ResponseType.OK and api_key: - # Save API key to file - config_dir = os.path.expanduser("~/.local/share/cthulhu") - os.makedirs(config_dir, exist_ok=True) - api_key_file = os.path.join(config_dir, "claude-api-key") - - with open(api_key_file, 'w') as f: - f.write(api_key) - os.chmod(api_key_file, 0o600) # Secure file permissions - - # Update GUI - self.get_widget("aiApiKeyEntry").set_text(api_key_file) - self.prefsDict["aiApiKeyFile"] = api_key_file - - # Success message - success_dialog = Gtk.MessageDialog( - parent=self, - flags=Gtk.DialogFlags.MODAL, - type=Gtk.MessageType.INFO, - buttons=Gtk.ButtonsType.OK, - message_format="API Key Saved Successfully" - ) - success_dialog.format_secondary_text(f"Claude API key saved to:\n{api_key_file}") - success_dialog.run() - success_dialog.destroy() - - except Exception as e: - # Error dialog - error_dialog = Gtk.MessageDialog( - parent=self, - flags=Gtk.DialogFlags.MODAL, - type=Gtk.MessageType.ERROR, - buttons=Gtk.ButtonsType.OK, - message_format="Error Setting Up API Key" - ) - error_dialog.format_secondary_text(f"Failed to open browser or save API key:\n{str(e)}") - error_dialog.run() - error_dialog.destroy() - - def aiApiKeyBrowseClicked(self, widget): - """AI API key browse button clicked handler""" - dialog = Gtk.FileChooserDialog( - title="Select API Key File", - parent=self, - action=Gtk.FileChooserAction.OPEN - ) - dialog.add_buttons( - Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, - Gtk.STOCK_OPEN, Gtk.ResponseType.OK - ) - - response = dialog.run() - if response == Gtk.ResponseType.OK: - filename = dialog.get_filename() - self.aiApiKeyEntry.set_text(filename) - self.prefsDict["aiApiKeyFile"] = filename - - dialog.destroy() - - def aiConfirmationToggled(self, widget): - """AI confirmation required checkbox toggled handler""" - self.prefsDict["aiConfirmationRequired"] = widget.get_active() - - def aiScreenshotQualityChanged(self, widget): - """AI screenshot quality combo box changed handler""" - qualities = [settings.AI_SCREENSHOT_QUALITY_LOW, - settings.AI_SCREENSHOT_QUALITY_MEDIUM, - settings.AI_SCREENSHOT_QUALITY_HIGH] - activeIndex = widget.get_active() - if 0 <= activeIndex < len(qualities): - self.prefsDict["aiScreenshotQuality"] = qualities[activeIndex] - - # OCR Plugin Settings Handlers - def ocrLanguageChanged(self, widget): - """OCR language code entry changed handler""" - self.prefsDict["ocrLanguageCode"] = widget.get_text() - - def ocrScaleChanged(self, widget): - """OCR scale factor spin button changed handler""" - self.prefsDict["ocrScaleFactor"] = int(widget.get_value()) - - def ocrGrayscaleToggled(self, widget): - """OCR grayscale image checkbox toggled handler""" - self.prefsDict["ocrGrayscaleImg"] = widget.get_active() - - def ocrInvertToggled(self, widget): - """OCR invert image checkbox toggled handler""" - self.prefsDict["ocrInvertImg"] = widget.get_active() - - def ocrBlackWhiteToggled(self, widget): - """OCR black and white image checkbox toggled handler""" - self.prefsDict["ocrBlackWhiteImg"] = widget.get_active() - - def ocrBlackWhiteValueChanged(self, widget): - """OCR black/white threshold spin button changed handler""" - self.prefsDict["ocrBlackWhiteImgValue"] = int(widget.get_value()) - - def ocrColorCalculationToggled(self, widget): - """OCR color calculation checkbox toggled handler""" - self.prefsDict["ocrColorCalculation"] = widget.get_active() - - def ocrCopyToClipboardToggled(self, widget): - """OCR copy to clipboard checkbox toggled handler""" - self.prefsDict["ocrCopyToClipboard"] = widget.get_active() - diff --git a/src/cthulhu/cthulhu_gui_profile.py b/src/cthulhu/cthulhu_gui_profile.py deleted file mode 100644 index b0edb9c..0000000 --- a/src/cthulhu/cthulhu_gui_profile.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Displays the Save Profile As dialog.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Consorcio Fernando de los Rios." -__license__ = "LGPL" - -import locale -import sys -import gi -gi.require_version("Gtk", "3.0") -from gi.repository import Gtk - -from . import guilabels -from . import cthulhu_state - -OS = None -newProfile = None - -class CthulhuProfileGUI(Gtk.Dialog): - - def __init__(self): - """Initialize the Cthulhu profile configuration GUI.""" - - Gtk.Dialog.__init__(self) - self.set_title(guilabels.PROFILE_SAVE_AS_TITLE) - self.set_has_resize_grip(False) - - self.add_button('gtk-cancel', Gtk.ResponseType.CANCEL) - self.add_button('gtk-save', Gtk.ResponseType.ACCEPT) - - grid = Gtk.Grid() - grid.set_property('margin', 12) - grid.set_row_spacing(10) - grid.set_column_spacing(10) - - # Right now the content area is a GtkBox. We'll need to update - # this once GtkBox is fully deprecated. - contentArea = self.get_content_area() - contentArea.pack_start(grid, True, True, 0) - - self.profileEntry = Gtk.Entry() - self.profileEntry.set_property('hexpand', True) - self.profileEntry.set_activates_default(True) - grid.attach(self.profileEntry, 1, 0, 1, 1) - - label = Gtk.Label(guilabels.PROFILE_NAME_LABEL) - label.set_use_underline(True) - label.set_mnemonic_widget(self.profileEntry) - grid.attach(label, 0, 0, 1, 1) - - defaultButton = self.get_widget_for_response(Gtk.ResponseType.ACCEPT) - defaultButton.set_property('can-default', True) - defaultButton.set_property('has-default', True) - - self.connect('response', self.onResponse) - self.connect('destroy', self.onDestroy) - - self.searchString = None - self.profileString = None - self.prefsDialog = None - - def init(self): - self.profileString = '' - - def showGUI(self, prefsDialog): - """Show the Save Profile As dialog.""" - - self.show_all() - self.prefsDialog = prefsDialog - self.profileEntry.set_text(self.profileString) - - ts = cthulhu_state.lastInputEvent.timestamp - if ts == 0: - ts = Gtk.get_current_event_time() - self.present_with_time(ts) - - def onResponse(self, widget, response): - """Signal handler for the responses emitted by the dialog.""" - - if response in [Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT]: - self.hide() - return - - if response == Gtk.ResponseType.ACCEPT: - global newProfile - - newProfile = self.profileEntry.get_text() - if newProfile: - self.destroy() - if self.prefsDialog: - self.prefsDialog.saveProfile(newProfile) - - def onDestroy(self, widget): - """Signal handler for the 'destroy' signal of the dialog.""" - - global OS - - OS = None - -def showProfileUI(prefsDialog=None): - global OS - global newProfile - - newProfile = None - - if not OS: - OS = CthulhuProfileGUI() - OS.init() - - OS.showGUI(prefsDialog) - -def main(): - locale.setlocale(locale.LC_ALL, '') - - showProfileUI() - - Gtk.main() - sys.exit(0) - -if __name__ == "__main__": - main() diff --git a/src/cthulhu/cthulhu_i18n.py.in b/src/cthulhu/cthulhu_i18n.py.in deleted file mode 100644 index d15999d..0000000 --- a/src/cthulhu/cthulhu_i18n.py.in +++ /dev/null @@ -1,91 +0,0 @@ -# Cthulhu -# -# Copyright 2004-2008 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -"""Provides i18n support for cthulhu using the gettext module. Tells -gettext where to find localized strings and creates an alias, _, that -maps to the gettext.gettext function. This function will accept a -string and return a localized string for that string. -""" - -import gettext -import importlib -import os -import sys - -# Alias gettext.gettext to _ and gettext.ngettext to ngettext -# -_ = gettext.gettext -ngettext = gettext.ngettext -cgettext = gettext.gettext - -# Tell gettext where to find localized strings. -# -localedir = "@localedir@".replace('${prefix}', '@prefix@') -gettext.bindtextdomain ("@GETTEXT_PACKAGE@", localedir) -gettext.textdomain("cthulhu") - -######################################################################## -# # -# Utility methods to facilitate easier translation # -# # -######################################################################## - -def C_(ctx, s): - """Provide qualified translatable strings via context.""" - translated = cgettext('%s\x04%s' % (ctx, s)) - if '\x04' in translated: - # no translation found, return input string - return s - return translated - -def setModuleLocale(moduleName, newLocale=None): - global _, ngettext, cgettext - - try: - translation = gettext.translation('cthulhu', localedir, languages=[newLocale]) - _ = translation.gettext - ngettext = translation.ngettext - cgettext = translation.gettext - except: - _ = gettext.gettext - ngettext = gettext.ngettext - cgettext = gettext.gettext - module = sys.modules.get(moduleName) - if module: - importlib.reload(module) - -def setLocaleForMessages(newLocale=None): - modules = ['cthulhu.tutorialgenerator', 'cthulhu.messages'] - for module in modules: - setModuleLocale(module, newLocale) - -def setLocaleForNames(newLocale=None): - modules = ['cthulhu.chnames', 'cthulhu.keynames', 'cthulhu.phonnames', - 'cthulhu.text_attribute_names', 'cthulhu.object_properties', - 'cthulhu.cmdnames', 'cthulhu.keybindings', 'cthulhu.colornames', - 'cthulhu.mathsymbols'] - for module in modules: - setModuleLocale(module, newLocale) - -def setLocaleForGUI(newLocale=None): - modules = ['cthulhu.cthulhu_gtkbuilder', - 'cthulhu.guilabels', - 'cthulhu.brltablenames'] - for module in modules: - setModuleLocale(module, newLocale) diff --git a/src/cthulhu/cthulhu_modifier_manager.py b/src/cthulhu/cthulhu_modifier_manager.py deleted file mode 100644 index 86ea50f..0000000 --- a/src/cthulhu/cthulhu_modifier_manager.py +++ /dev/null @@ -1,229 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# Copyright (c) 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Manages the Cthulhu modifier key(s).""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2026 Stormux" -__license__ = "LGPL" - -import os -import re -import subprocess - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -import cthulhu.debug as debug -import cthulhu.settings as settings - -class CthulhuModifierManager: - """Manages the Cthulhu modifier.""" - - def __init__(self): - self._originalXmodmap = b"" - self._capsLockCleared = False - - def refreshCthulhuModifiers(self, reason=""): - """Refreshes the Cthulhu modifier keys.""" - - msg = "CTHULHU MODIFIER MANAGER: Refreshing Cthulhu modifiers" - if reason: - msg += f": {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - display = os.environ.get("DISPLAY") - if not display: - msg = "CTHULHU MODIFIER MANAGER: DISPLAY not set, skipping xkbcomp operations" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - self.unsetCthulhuModifiers(reason) - with subprocess.Popen(["xkbcomp", display, "-"], - stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) as process: - self._originalXmodmap, _ = process.communicate() - self._createCthulhuXmodmap() - - def unsetCthulhuModifiers(self, reason=""): - """Turns the Cthulhu modifiers back into their original purpose.""" - - msg = "CTHULHU MODIFIER MANAGER: Attempting to restore original xmodmap" - if reason: - msg += f": {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if not self._originalXmodmap: - msg = "CTHULHU MODIFIER MANAGER: No stored xmodmap found" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - display = os.environ.get("DISPLAY") - if not display: - msg = "CTHULHU MODIFIER MANAGER: DISPLAY not set, skipping xmodmap restoration" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - self._capsLockCleared = False - with subprocess.Popen(["xkbcomp", "-w0", "-", display], - stdin=subprocess.PIPE, stdout=None, stderr=None) as process: - process.communicate(self._originalXmodmap) - - msg = "CTHULHU MODIFIER MANAGER: Original xmodmap restored" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _createCthulhuXmodmap(self): - """Makes a Cthulhu-specific Xmodmap so that the modifier works.""" - - msg = "CTHULHU MODIFIER MANAGER: Creating Cthulhu xmodmap" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if "Caps_Lock" in settings.cthulhuModifierKeys \ - or "Shift_Lock" in settings.cthulhuModifierKeys: - self.setCapsLockAsCthulhuModifier(True) - self._capsLockCleared = True - elif self._capsLockCleared: - self.setCapsLockAsCthulhuModifier(False) - self._capsLockCleared = False - - def setCapsLockAsCthulhuModifier(self, enable): - """Enable or disable use of the caps lock key as a Cthulhu modifier key.""" - - msg = "CTHULHU MODIFIER MANAGER: Setting caps lock as the Cthulhu modifier" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - display = os.environ.get("DISPLAY") - if not display: - msg = "CTHULHU MODIFIER MANAGER: DISPLAY not set, cannot modify caps lock" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if not self._originalXmodmap: - msg = "CTHULHU MODIFIER MANAGER: No xmodmap available, cannot modify caps lock" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - interpretCapsLineProg = re.compile( - r'^\s*interpret\s+Caps[_+]Lock[_+]AnyOfOrNone\s*\(all\)\s*{\s*$', re.I) - normalCapsLineProg = re.compile( - r'^\s*action\s*=\s*LockMods\s*\(\s*modifiers\s*=\s*Lock\s*\)\s*;\s*$', re.I) - interpretShiftLineProg = re.compile( - r'^\s*interpret\s+Shift[_+]Lock[_+]AnyOf\s*\(\s*Shift\s*\+\s*Lock\s*\)\s*{\s*$', re.I) - normalShiftLineProg = re.compile( - r'^\s*action\s*=\s*LockMods\s*\(\s*modifiers\s*=\s*Shift\s*\)\s*;\s*$', re.I) - disabledModLineProg = re.compile( - r'^\s*action\s*=\s*NoAction\s*\(\s*\)\s*;\s*$', re.I) - normalCapsLine = ' action= LockMods(modifiers=Lock);' - normalShiftLine = ' action= LockMods(modifiers=Shift);' - disabledModLine = ' action= NoAction();' - lines = self._originalXmodmap.decode('UTF-8').split('\n') - foundCapsInterpretSection = False - foundShiftInterpretSection = False - modified = False - for i, line in enumerate(lines): - if not foundCapsInterpretSection and not foundShiftInterpretSection: - if interpretCapsLineProg.match(line): - foundCapsInterpretSection = True - elif interpretShiftLineProg.match(line): - foundShiftInterpretSection = True - elif foundCapsInterpretSection: - if enable: - if normalCapsLineProg.match(line): - lines[i] = disabledModLine - modified = True - else: - if disabledModLineProg.match(line): - lines[i] = normalCapsLine - modified = True - if line.find('}'): - foundCapsInterpretSection = False - elif foundShiftInterpretSection: - if enable: - if normalShiftLineProg.match(line): - lines[i] = disabledModLine - modified = True - else: - if disabledModLineProg.match(line): - lines[i] = normalShiftLine - modified = True - if line.find('}'): - foundShiftInterpretSection = False - if modified: - msg = "CTHULHU MODIFIER MANAGER: Updating xmodmap" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - with subprocess.Popen(["xkbcomp", "-w0", "-", display], - stdin=subprocess.PIPE, stdout=None, stderr=None) as process: - process.communicate(bytes('\n'.join(lines), 'UTF-8')) - else: - msg = "CTHULHU MODIFIER MANAGER: Not updating xmodmap" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def toggleModifier(self, keyboardEvent): - """Toggles the modifier to enable double-clicking causing normal behavior.""" - - if keyboardEvent.keyval_name in ["Caps_Lock", "Shift_Lock"]: - self._toggleModifierLock(keyboardEvent) - return - - def _toggleModifierLock(self, keyboardEvent): - """Toggles the lock for a modifier to enable double-clicking causing normal behavior.""" - - if not keyboardEvent.is_pressed_key(): - return - - def toggle(modifiers, modifier): - if modifiers & modifier: - lock = Atspi.KeySynthType.UNLOCKMODIFIERS - msg = "CTHULHU MODIFIER MANAGER: Unlocking CapsLock" - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - lock = Atspi.KeySynthType.LOCKMODIFIERS - msg = "CTHULHU MODIFIER MANAGER: Locking CapsLock" - debug.printMessage(debug.LEVEL_INFO, msg, True) - Atspi.generate_keyboard_event(modifier, "", lock) - - if keyboardEvent.keyval_name == "Caps_Lock": - modifier = 1 << Atspi.ModifierType.SHIFTLOCK - elif keyboardEvent.keyval_name == "Shift_Lock": - modifier = 1 << Atspi.ModifierType.SHIFT - else: - return - - msg = "CTHULHU MODIFIER MANAGER: Scheduling lock change" - debug.printMessage(debug.LEVEL_INFO, msg, True) - GLib.timeout_add(1, toggle, keyboardEvent.modifiers, modifier) - -_manager = None -def getManager(): - """Returns the Cthulhu Modifier Manager""" - - global _manager - if _manager is None: - _manager = CthulhuModifierManager() - return _manager - diff --git a/src/cthulhu/cthulhu_platform.py.in b/src/cthulhu/cthulhu_platform.py.in deleted file mode 100644 index 38dee96..0000000 --- a/src/cthulhu/cthulhu_platform.py.in +++ /dev/null @@ -1,54 +0,0 @@ -# Cthulhu -# -# Copyright 2006-2008 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -from cthulhu import cthulhuVersion - -"""Holds platform-specific settings. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -# $CTHULHU_VERSION -# -versionSuffix = f"-{cthulhuVersion.codeName}" if cthulhuVersion.codeName else "" -version = f"Cthulhu screen reader version {cthulhuVersion.version}{versionSuffix}" - -# The revision if built from git; otherwise an empty string -# -revision = "@REVISION@" - -# "--prefix" parameter used when configuring the build. -# -prefix = "@prefix@" - -# The package name (should be "cthulhu"). -# -package = "@PACKAGE@" - -# The location of the data directory (usually "share"). -# -datadir = "@datadir@".replace('${prefix}', '@prefix@') - -# The directory where we could find liblouis translation tables. -# -tablesdir = "@LOUIS_TABLE_DIR@" diff --git a/src/cthulhu/cthulhu_state.py b/src/cthulhu/cthulhu_state.py deleted file mode 100644 index de5ed82..0000000 --- a/src/cthulhu/cthulhu_state.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Holds state that is shared among many modules. -""" - -from typing import Optional, Any - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010 Joanmarie Diggs, Mesar Hameed." -__license__ = "LGPL" - -# NOTE: resist the temptation to do any imports here. They can -# easily cause circular imports. -# -# We use forward references in type hints to avoid importing: -# - Atspi.Accessible for focus and window -# - Script for activeScript -# - InputEvent for lastInputEvent - -# The Accessible that has visual focus. -# -locusOfFocus: Optional[Any] = None # Actually: Optional[Atspi.Accessible] - -# A pending focused object from a Cthulhu-owned window that should be used -# for keyboard-event context until the queued focus event is processed. -# -pendingSelfHostedFocus: Optional[Any] = None # Actually: Optional[Atspi.Accessible] - -# The currently active window. -# -activeWindow: Optional[Any] = None # Actually: Optional[Atspi.Accessible] - -# The latest compositor snapshot. -# -compositorSnapshot: Optional[Any] = None - -# Whether AT-SPI churn should be paused for compositor transitions. -# -pauseAtspiChurn: bool = False - -# Whether a trusted screen locker has requested secure-input isolation. -# -screenLockActive: bool = False - -# The desktop-context token that should be prioritized next. -# -prioritizedDesktopContextToken: Optional[str] = None - -# The currently active script. -# -activeScript: Optional[Any] = None # Actually: Optional[Script] - -# The currently active mode (focus, say all, flat review, etc.) and obj -activeMode: Optional[str] = None -objOfInterest: Optional[Any] = None # Actually: Optional[Atspi.Accessible] - -# Used to capture keys to redefine key bindings by the user. -# -capturingKeys: bool = False - -# The last non-modifier key event received. -# -lastNonModifierKeyEvent: Optional[Any] = None # Actually: Optional[KeyboardEvent] - -# The InputEvent instance representing the last input event. This is -# set each time a mouse, keyboard or braille event is received. -# -lastInputEvent: Optional[Any] = None # Actually: Optional[InputEvent] - -# Used to determine if the user wishes Cthulhu to pass the next command -# along to the current application rather than consuming it. -# -bypassNextCommand: bool = False - -# The last searchQuery -# -searchQuery: Optional[str] = None - -# Handle to the Cthulhu Preferences Glade GUI object. -# -cthulhuOS: Optional[Any] = None # Actually: Optional[CthulhuSetupGUI] - -# Set to True if the last key opened the preferences dialog -# -openingDialog: bool = False - -# The AT-SPI device (needed for key grabs). Will be set to None if AT-SPI -# is too old to support the new device API. -# -device: Optional[Any] = None # Actually: Optional[Atspi.Device] diff --git a/src/cthulhu/date_and_time_presenter.py b/src/cthulhu/date_and_time_presenter.py deleted file mode 100644 index 8371f1d..0000000 --- a/src/cthulhu/date_and_time_presenter.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Module for date and time presentation""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2016-2023 Igalia, S.L." -__license__ = "LGPL" - -import time -from typing import Optional, Dict, Callable, Any - -from . import cthulhu # Need access to cthulhuApp -from . import cmdnames -from . import input_event -from . import keybindings -from . import settings_manager - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -class DateAndTimePresenter: - """Provides commands to present the date and time.""" - - def __init__(self) -> None: - self._handlers: Dict[str, input_event.InputEventHandler] = self._setup_handlers() - self._bindings: keybindings.KeyBindings = self._setup_bindings() - - def get_bindings(self) -> keybindings.KeyBindings: - """Returns the date-and-time-presenter keybindings.""" - - return self._bindings - - def get_handlers(self) -> Dict[str, input_event.InputEventHandler]: - """Returns the date-and-time-presenter handlers.""" - - return self._handlers - - def _setup_handlers(self) -> Dict[str, input_event.InputEventHandler]: - """Sets up and returns the date-and-time-presenter input event handlers.""" - - handlers = {} - - handlers["presentTimeHandler"] = \ - input_event.InputEventHandler( - self.present_time, - cmdnames.PRESENT_CURRENT_TIME) - - handlers["presentDateHandler"] = \ - input_event.InputEventHandler( - self.present_date, - cmdnames.PRESENT_CURRENT_DATE) - - return handlers - - def _setup_bindings(self) -> keybindings.KeyBindings: - """Sets up and returns the date-and-time-presenter key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "t", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("presentTimeHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "t", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("presentDateHandler"), - 2)) - - return bindings - - def present_time(self, script: Any, event: Optional[Any] = None) -> bool: - """Presents the current time.""" - - format = cthulhu.cthulhuApp.settingsManager.getSetting('presentTimeFormat') - script.presentMessage(time.strftime(format, time.localtime())) - return True - - def present_date(self, script: Any, event: Optional[Any] = None) -> bool: - """Presents the current date.""" - - format = cthulhu.cthulhuApp.settingsManager.getSetting('presentDateFormat') - script.presentMessage(time.strftime(format, time.localtime())) - return True - - -_presenter: Optional[DateAndTimePresenter] = None - -def getPresenter() -> DateAndTimePresenter: - global _presenter - if _presenter is None: - _presenter = DateAndTimePresenter() - return _presenter diff --git a/src/cthulhu/dbus_service.py b/src/cthulhu/dbus_service.py deleted file mode 100644 index de1c908..0000000 --- a/src/cthulhu/dbus_service.py +++ /dev/null @@ -1,1173 +0,0 @@ -# Cthulhu -# -# Copyright 2025 Valve Corporation -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -"""Provides a D-Bus interface for remotely controlling Cthulhu.""" - -import ast -import contextlib -import enum -import inspect -import os -import time -import types -import typing -import xml.etree.ElementTree as ET -from collections.abc import Callable -from typing import Optional - -from gi.repository import GLib - -try: - from dasbus.connection import SessionMessageBus - from dasbus.error import DBusError - from dasbus.server.interface import dbus_interface - from dasbus.server.publishable import Publishable - from dasbus.typing import UInt32 as UInt32 # noqa: PLC0414 (re-export) - _dasbus_available = True -except ImportError: - SessionMessageBus = None - DBusError = Exception - Publishable = object - UInt32 = int - _dasbus_available = False - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import ( # pylint: disable=no-name-in-module - cthulhu_state, - debug, - script_manager, - cthulhu_platform, -) - - -if not _dasbus_available: - def dbus_interface(_interface_name): - """Returns a no-op interface decorator when dasbus is unavailable.""" - - def _decorator(cls): - cls.__dbus_xml__ = "" - return cls - - return _decorator - - -def _get_input_event(): - from . import input_event # pylint: disable=import-outside-toplevel - - return input_event - - -def _get_input_event_manager(): - from . import input_event_manager # pylint: disable=import-outside-toplevel - - return input_event_manager - - -def command(func): - """Decorator to mark a method as a D-Bus command using its docstring. - - Usage: - @command - def toggle_speech(self, script=None, event=None): - '''Toggles speech on and off.''' - # method implementation - """ - description = func.__doc__ or f"D-Bus command: {func.__name__}" - func.dbus_command_description = description - return func - - -def parameterized_command(func): - """Decorator to mark a method as a D-Bus parameterized command using its docstring. - - Usage: - @parameterized_command - def get_voices_for_language( - self, - language, - variant='', - script=None, - event=None, - notify_user=False - ): - '''Returns a list of available voices for the specified language.''' - # method implementation - """ - description = func.__doc__ or f"D-Bus parameterized command: {func.__name__}" - func.dbus_parameterized_command_description = description - return func - - -def getter(func): - """Decorator to mark a method as a D-Bus getter using its docstring. - - Usage: - @getter - def get_rate(self): - '''Returns the current speech rate.''' - # method implementation - """ - description = func.__doc__ or f"D-Bus getter: {func.__name__}" - func.dbus_getter_description = description - return func - - -def setter(func): - """Decorator to mark a method as a D-Bus setter using its docstring. - - Usage: - @setter - def set_rate(self, value): - '''Sets the current speech rate.''' - # method implementation - """ - description = func.__doc__ or f"D-Bus setter: {func.__name__}" - func.dbus_setter_description = description - return func - - -def _filter_kwargs_for_callable(method: Callable, kwargs: dict[str, object]) -> dict[str, object]: - """Filters kwargs down to what the callable accepts.""" - - try: - sig = inspect.signature(method) - except (TypeError, ValueError): - return kwargs - - for param in sig.parameters.values(): - if param.kind == inspect.Parameter.VAR_KEYWORD: - return kwargs - - allowed = set(sig.parameters.keys()) - allowed.discard("self") - return {key: value for key, value in kwargs.items() if key in allowed} - - -class _Kind(enum.Enum): - """Decorated-method kinds detected during module registration.""" - - COMMAND = enum.auto() - PARAMETERIZED = enum.auto() - GETTER = enum.auto() - SETTER = enum.auto() - - -class _ModuleRegistration: # pylint: disable=too-many-instance-attributes - """Tracks a module's decorated methods and its published D-Bus interface.""" - - def __init__(self, module_name: str) -> None: - self._module_name: str = module_name - self._commands: dict[str, Callable] = {} - self._parameterized_commands: dict[str, Callable] = {} - self._getters: dict[str, Callable] = {} - self._setters: dict[str, Callable] = {} - self._descriptions: dict[str, str] = {} - self._dbus_object: Optional[object] = None - self._object_path: str = "" - - def get_module_name(self) -> str: - """Returns the module name.""" - - return self._module_name - - def get_commands(self) -> dict[str, Callable]: - """Returns the simple (non-parameterized) commands.""" - - return self._commands - - def get_parameterized_commands(self) -> dict[str, Callable]: - """Returns the parameterized commands.""" - - return self._parameterized_commands - - def get_getters(self) -> dict[str, Callable]: - """Returns the property getters.""" - - return self._getters - - def get_setters(self) -> dict[str, Callable]: - """Returns the property setters.""" - - return self._setters - - def get_descriptions(self) -> dict[str, str]: - """Returns the description for each exposed CamelCase member name.""" - - return self._descriptions - - def get_object_path(self) -> str: - """Returns the D-Bus object path under which the module is published.""" - - return self._object_path - - def set_object_path(self, path: str) -> None: - """Stores the D-Bus object path under which the module was published.""" - - self._object_path = path - - def get_dbus_object(self) -> Optional[object]: - """Returns the published D-Bus interface instance, or None if not published.""" - - return self._dbus_object - - def set_dbus_object(self, obj: object) -> None: - """Stores the published D-Bus interface instance.""" - - self._dbus_object = obj - - def is_empty(self) -> bool: - """Returns True if the registration has no decorated members.""" - - return not ( - self._commands or self._parameterized_commands or self._getters or self._setters - ) - - def total_member_count(self) -> int: - """Returns the total number of exposed members (commands + properties).""" - - return ( - len(self._commands) - + len(self._parameterized_commands) - + len(self._getters) - + len(self._setters) - ) - - def find_command(self, command_name: str) -> Optional[Callable]: - """Returns the original command method for the given CamelCase name, or None.""" - - return self._commands.get(command_name) or self._parameterized_commands.get(command_name) - - def find_getter(self, property_name: str) -> Optional[Callable]: - """Returns the original getter for the given CamelCase property name, or None.""" - - return self._getters.get(property_name) - - def find_setter(self, property_name: str) -> Optional[Callable]: - """Returns the original setter for the given CamelCase property name, or None.""" - - return self._setters.get(property_name) - - def add_decorated_member( - self, kind: _Kind, attr_name: str, method: Callable, description: str - ) -> None: - """Records a decorated method under its DBus member name.""" - - dbus_name = self._dbus_name_for(attr_name, kind) - if kind is _Kind.COMMAND: - self._commands[dbus_name] = method - self._descriptions[dbus_name] = description - elif kind is _Kind.PARAMETERIZED: - self._parameterized_commands[dbus_name] = method - self._descriptions[dbus_name] = description - elif kind is _Kind.GETTER: - self._getters[dbus_name] = method - if dbus_name not in self._descriptions: - self._descriptions[dbus_name] = description - elif kind is _Kind.SETTER: - self._setters[dbus_name] = method - self._descriptions[dbus_name] = description - - @staticmethod - def _dbus_name_for(attr_name: str, kind: _Kind) -> str: - """Returns the CamelCase D-Bus name for a Python attribute name and decorator kind.""" - - if kind in (_Kind.GETTER, _Kind.SETTER) and attr_name.startswith(("get_", "set_")): - attr_name = attr_name[4:] - return "".join(word.capitalize() for word in attr_name.split("_")) - - @classmethod - def from_module_instance( - cls, module_name: str, module_instance: object - ) -> "_ModuleRegistration": - """Walks module_instance and groups its decorated members by kind.""" - - registration = cls(module_name) - for attr_name in dir(module_instance): - method = getattr(module_instance, attr_name, None) - if not callable(method): - continue - kind, description = cls._classify_method(method) - if kind is None: - continue - registration.add_decorated_member(kind, attr_name, method, description) - return registration - - @staticmethod - def _classify_method(method: Callable) -> tuple[Optional[_Kind], str]: - """Returns (kind, description) for a decorated method, or (None, '') if undecorated.""" - - description = getattr(method, "dbus_command_description", None) - if description is not None: - return _Kind.COMMAND, description - - description = getattr(method, "dbus_parameterized_command_description", None) - if description is not None: - return _Kind.PARAMETERIZED, description - - description = getattr(method, "dbus_getter_description", None) - if description is not None: - return _Kind.GETTER, description - - description = getattr(method, "dbus_setter_description", None) - if description is not None: - return _Kind.SETTER, description - - return None, "" - - -class _InterfaceBuilder: - """Builds an introspectable D-Bus interface class from a _ModuleRegistration.""" - - _RESERVED_PARAMS = frozenset({"self", "script", "event", "notify_user"}) - _BUILTIN_TYPES: typing.ClassVar[dict[str, object]] = { - "bool": bool, - "int": int, - "UInt32": UInt32, - "float": float, - "str": str, - "list": list, - "tuple": tuple, - "dict": dict, - "None": type(None), - } - - @classmethod - def build(cls, registration: _ModuleRegistration) -> type: - """Dynamically constructs a D-Bus interface class for the registered module.""" - - def for_publication(self): - """Returns the D-Bus interface XML for publication.""" - - return self.__dbus_xml__ # pylint: disable=no-member - - namespace: dict[str, object] = {"for_publication": for_publication} - for cname, method in registration.get_commands().items(): - namespace[cname] = cls._make_command_method(method) - for cname, method in registration.get_parameterized_commands().items(): - namespace[cname] = cls._make_parameterized_command_method(method) - getters = registration.get_getters() - setters = registration.get_setters() - for cname in set(getters) | set(setters): - namespace[cname] = cls._make_property(getters.get(cname), setters.get(cname)) - - module_name = registration.get_module_name() - new_cls = type(f"{module_name}DBusInterface", (Publishable,), namespace) - interface_name = f"org.stormux.Cthulhu1.{module_name}" - new_cls = dbus_interface(interface_name)(new_cls) - new_cls.__dbus_xml__ = cls._inject_docstrings( - new_cls.__dbus_xml__, registration.get_descriptions() - ) - return new_cls - - @staticmethod - def _inject_docstrings(xml_text: str, descriptions: dict[str, str]) -> str: - """Adds org.gtk.GDBus.DocString annotations to methods and properties in the XML.""" - - if not descriptions: - return xml_text - # XML is generated in-process by dasbus, not untrusted input. - root = ET.fromstring(xml_text) # noqa: S314 - for iface in root.findall("interface"): - for element in list(iface.findall("method")) + list(iface.findall("property")): - name = element.get("name") - description = descriptions.get(name) if name else None - if not description: - continue - annotation = ET.Element( - "annotation", - {"name": "org.gtk.GDBus.DocString", "value": description}, - ) - element.insert(0, annotation) - return ET.tostring(root, encoding="unicode") - - @staticmethod - def _strip_optional(annotation): - """Returns the non-None branch of Optional[T] / T | None, else the annotation unchanged.""" - - origin = typing.get_origin(annotation) - union_type = getattr(types, "UnionType", None) - union_origins = (typing.Union,) if union_type is None else (typing.Union, union_type) - if origin in union_origins: - non_none = tuple(arg for arg in typing.get_args(annotation) if arg is not type(None)) - if len(non_none) == 1: - return non_none[0] - return annotation - - @classmethod - def _resolve_annotation(cls, annotation): - """Resolves annotation to a real type, or returns the original string.""" - - # Resolve each annotation independently. typing.get_type_hints is all-or-nothing: - # a single TYPE_CHECKING-only name on a sibling parameter (e.g. `script: default.Script`) - # makes it raise NameError and lose every annotation in the function. Walking the AST - # per-annotation lets resolvable names, such as `language: str`, survive. - if not isinstance(annotation, str): - return annotation - try: - tree = ast.parse(annotation, mode="eval") - except SyntaxError: - return annotation - try: - return cls._type_from_node(tree.body) - except (KeyError, AttributeError, TypeError): - return annotation - - @classmethod - def _type_from_node(cls, node: ast.AST): - """Reconstructs a type from an AST node using a fixed builtin whitelist.""" - - if isinstance(node, ast.Name): - return cls._BUILTIN_TYPES[node.id] - if isinstance(node, ast.Constant): - if node.value is None: - return type(None) - raise KeyError(node.value) - if isinstance(node, ast.Subscript): - base = cls._type_from_node(node.value) - slice_node = node.slice - if isinstance(slice_node, ast.Tuple): - args = tuple(cls._type_from_node(elt) for elt in slice_node.elts) - return base[args] - return base[cls._type_from_node(slice_node)] - if isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr): - return typing.Union[cls._type_from_node(node.left), cls._type_from_node(node.right)] - raise KeyError(ast.dump(node)) - - @classmethod - def _resolved_signature(cls, method: Callable) -> inspect.Signature: - """Returns method's signature with string annotations resolved per-parameter.""" - - sig = inspect.signature(method) - new_params = [ - param.replace(annotation=cls._resolve_annotation(param.annotation)) - for param in sig.parameters.values() - ] - return sig.replace( - parameters=new_params, - return_annotation=cls._resolve_annotation(sig.return_annotation), - ) - - @classmethod - def _make_command_method(cls, method: Callable) -> Callable: - """Builds a D-Bus method (notify_user) -> bool wrapping an @command method.""" - - return_annotation = cls._resolved_signature(method).return_annotation - coerce_to_bool = return_annotation in (inspect.Signature.empty, type(None), bool) - if coerce_to_bool: - return_annotation = bool - - def Method(_self, notify_user: bool = True) -> bool: # pylint: disable=invalid-name - # Local imports break a circular import: dbus_service is imported by speech_manager, - # and script_manager (transitively) imports speech_manager. - event = _get_input_event().RemoteControllerEvent() - manager = script_manager.get_manager() - script = manager.get_active_script() or manager.get_default_script() - kwargs = {"script": script, "event": event, "notify_user": notify_user} - result = method(**_filter_kwargs_for_callable(method, kwargs)) - _get_input_event_manager().get_manager().process_remote_controller_event(event) - if coerce_to_bool: - return bool(result) - return result - - Method.__signature__ = inspect.Signature( # type: ignore[attr-defined] - [ - inspect.Parameter("self", inspect.Parameter.POSITIONAL_OR_KEYWORD), - inspect.Parameter( - "notify_user", - inspect.Parameter.POSITIONAL_OR_KEYWORD, - default=True, - annotation=bool, - ), - ], - return_annotation=return_annotation, - ) - Method.__annotations__ = {"notify_user": bool, "return": return_annotation} - return Method - - @classmethod - def _make_parameterized_command_method(cls, method: Callable) -> Callable: - """Builds a D-Bus method mirroring a @parameterized_command's user-facing signature.""" - - original_sig = cls._resolved_signature(method) - user_params = [ - (name, param) - for name, param in original_sig.parameters.items() - if name not in cls._RESERVED_PARAMS - ] - - new_params = [inspect.Parameter("self", inspect.Parameter.POSITIONAL_OR_KEYWORD)] - annotations: dict[str, object] = {} - for name, param in user_params: - annotation = cls._strip_optional(param.annotation) - if annotation is inspect.Signature.empty: - annotation = cls._type_for_default(param.default) - new_params.append( - inspect.Parameter( - name, - inspect.Parameter.POSITIONAL_OR_KEYWORD, - default=param.default, - annotation=annotation, - ) - ) - annotations[name] = annotation - - new_params.append( - inspect.Parameter( - "notify_user", - inspect.Parameter.POSITIONAL_OR_KEYWORD, - default=True, - annotation=bool, - ) - ) - annotations["notify_user"] = bool - - return_annotation = original_sig.return_annotation - if return_annotation is inspect.Signature.empty: - return_annotation = bool - annotations["return"] = return_annotation - - new_sig = inspect.Signature(new_params, return_annotation=return_annotation) - - def Method(_self, *args, **kwargs): # pylint: disable=invalid-name - bound = new_sig.bind(_self, *args, **kwargs) - bound.apply_defaults() - bound.arguments.pop("self", None) - notify_user = bound.arguments.pop("notify_user") - - event = _get_input_event().RemoteControllerEvent() - manager = script_manager.get_manager() - script = manager.get_active_script() or manager.get_default_script() - kwargs = {"script": script, "event": event, "notify_user": notify_user} - kwargs.update(bound.arguments) - result = method(**_filter_kwargs_for_callable(method, kwargs)) - _get_input_event_manager().get_manager().process_remote_controller_event(event) - return result - - Method.__signature__ = new_sig # type: ignore[attr-defined] - Method.__annotations__ = annotations - return Method - - @staticmethod - def _type_for_default(default: object) -> object: - """Returns a DBus-compatible type hint for an unannotated parameter.""" - - if default is inspect.Signature.empty: - return str - if isinstance(default, bool): - return bool - if isinstance(default, int): - return int - if isinstance(default, float): - return float - if isinstance(default, str): - return str - return str - - @classmethod - def _make_property( - cls, get_method: Optional[Callable], set_method: Optional[Callable] - ) -> property: - """Builds a D-Bus property from a getter and/or setter pair.""" - - read = cls._make_property_getter(get_method) if get_method is not None else None - write = cls._make_property_setter(set_method) if set_method is not None else None - return property(read, write) - - @classmethod - def _make_property_getter(cls, get_method: Callable) -> Callable: - """Builds the read accessor for a D-Bus property, wrapping the original @getter method.""" - - return_annotation = cls._resolved_signature(get_method).return_annotation - if return_annotation is inspect.Signature.empty: - return_annotation = bool - - def read(_self, _original=get_method): - return _original() - - read.__signature__ = inspect.Signature( # type: ignore[attr-defined] - [inspect.Parameter("self", inspect.Parameter.POSITIONAL_OR_KEYWORD)], - return_annotation=return_annotation, - ) - read.__annotations__ = {"return": return_annotation} - return read - - @classmethod - def _make_property_setter(cls, set_method: Callable) -> Callable: - """Builds the write accessor for a D-Bus property, wrapping the original @setter method.""" - - set_sig = cls._resolved_signature(set_method) - value_param = next(param for name, param in set_sig.parameters.items() if name != "self") - value_type = cls._strip_optional(value_param.annotation) - if value_type is inspect.Signature.empty: - value_type = bool - - def write(_self, value, _original=set_method): - _original(value) - - write.__signature__ = inspect.Signature( # type: ignore[attr-defined] - [ - inspect.Parameter("self", inspect.Parameter.POSITIONAL_OR_KEYWORD), - inspect.Parameter( - "value", - inspect.Parameter.POSITIONAL_OR_KEYWORD, - annotation=value_type, - ), - ] - ) - write.__annotations__ = {"value": value_type} - return write - - -@dbus_interface("org.stormux.Cthulhu1.Service") -class CthulhuDBusServiceInterface(Publishable): - """Internal D-Bus service object that handles D-Bus specifics.""" - - _WINE_FOCUS_DEBOUNCE_MS = 50 - - def for_publication(self): - """Returns the D-Bus interface XML for publication.""" - - return self.__dbus_xml__ # pylint: disable=no-member - - def ShowPreferences(self) -> bool: # pylint: disable=invalid-name - """Shows Cthulhu's preferences GUI.""" - - msg = "DBUS SERVICE: ShowPreferences called." - debug.print_message(debug.LEVEL_INFO, msg, True) - - manager = script_manager.get_manager() - script = manager.get_active_script() or manager.get_default_script() - if script is None: - msg = "DBUS SERVICE: No script available" - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - - script.showPreferencesGUI() - return True - - def PresentMessage(self, message: str) -> bool: # pylint: disable=invalid-name - """Presents message to the user.""" - - msg = f"DBUS SERVICE: PresentMessage called with: '{message}'" - debug.print_message(debug.LEVEL_INFO, msg, True) - - manager = script_manager.get_manager() - script = cthulhu_state.activeScript or manager.get_default_script() - if script is None: - msg = "DBUS SERVICE: No script available" - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - - script.presentMessage(message) - return True - - def SpeakText(self, text: str, interrupt: bool) -> bool: # pylint: disable=invalid-name - """Speaks plain text without also presenting it in braille.""" - - if not text: - return False - - from . import speech # pylint: disable=import-outside-toplevel - - speech.speak(text, interrupt=interrupt) - return True - - def BrailleMessage(self, text: str) -> bool: # pylint: disable=invalid-name - """Displays a message on the active braille display.""" - - if not text: - return False - - from . import braille # pylint: disable=import-outside-toplevel - - braille.displayMessage(text, flashTime=-1) - return True - - def CancelSpeech(self) -> bool: # pylint: disable=invalid-name - """Stops current speech and sound output.""" - - from . import speech # pylint: disable=import-outside-toplevel - - speech.stop() - return True - - def SpeakSsml(self, requestId: str, ssml: str) -> int: # pylint: disable=invalid-name - """Rejects SSML when its timing and mark semantics cannot be preserved.""" - - del requestId - try: - root = ET.fromstring(ssml) - except ET.ParseError: - debug.print_message(debug.LEVEL_WARNING, "DBUS SERVICE: Invalid SSML rejected", True) - return 87 # ERROR_INVALID_PARAMETER - - if root.tag.rsplit("}", 1)[-1].lower() != "speak": - debug.print_message(debug.LEVEL_WARNING, "DBUS SERVICE: Non-speak SSML rejected", True) - return 87 - - debug.print_message( - debug.LEVEL_INFO, - "DBUS SERVICE: SSML rejected because mark and completion semantics are unavailable", - True, - ) - return 50 # ERROR_NOT_SUPPORTED - - def PresentAccessibleEvent( # pylint: disable=invalid-name,too-many-arguments - self, - sourceId: str, - eventType: str, - name: str, - role: str, - value: str, - states: str, - description: str, - position: int, - count: int, - windowTitle: str, - ) -> bool: - """Presents a normalized accessibility event received from Wine.""" - - del states - eventType = eventType.casefold() - debug.print_message( - debug.LEVEL_INFO, - ( - "WINE ACCESS EVENT: " - f"type={eventType} source={sourceId} name={name!r} " - f"role={role!r} value={value!r} window={windowTitle!r}" - ), - True, - ) - if eventType == "focus": - self._wineAccessibleFocusSource = sourceId - else: - if eventType not in {"value", "selection"}: - return False - focusedSource = getattr(self, "_wineAccessibleFocusSource", None) - focusedWindow = getattr(self, "_wineAccessibleWindowTitle", None) - pendingFocus = getattr(self, "_wineAccessiblePendingFocus", None) - if focusedWindow is None and pendingFocus is not None: - focusedWindow = pendingFocus[2] - if sourceId != focusedSource: - if eventType != "selection": - return False - if not windowTitle or windowTitle != focusedWindow: - return False - - if role.casefold() == "client": - role = "" - parts = [part for part in (name, role, value, description) if part] - if position > 0 and count > 0: - parts.append(f"{position} of {count}") - if not parts and not (eventType == "focus" and windowTitle): - return False - - message = ", ".join(parts) - now = time.monotonic() - signature = (sourceId, message or windowTitle) - lastSignature = getattr(self, "_wineAccessibleLastSignature", None) - lastTime = getattr(self, "_wineAccessibleLastTime", 0.0) - if signature == lastSignature and now - lastTime < 0.1: - if eventType == "focus": - self._wineAccessiblePendingFocus = None - return False - - if eventType == "focus": - self._wineAccessiblePendingFocus = (signature, parts, windowTitle) - if not getattr(self, "_wineAccessibleFocusTimeoutId", 0): - self._wineAccessibleFocusTimeoutId = GLib.timeout_add( - self._WINE_FOCUS_DEBOUNCE_MS, - self._present_pending_accessible_focus, - ) - return True - - pending = getattr(self, "_wineAccessiblePendingFocus", None) - if pending is not None and ( - pending[0][0] == sourceId or (windowTitle and pending[2] == windowTitle) - ): - self._wineAccessiblePendingFocus = (signature, parts, pending[2]) - return True - - self._wineAccessibleLastSignature = signature - self._wineAccessibleLastTime = now - return self.PresentMessage(message) - - def _present_pending_accessible_focus(self) -> bool: - """Presents the final focus event after Wine's transient focus burst.""" - - pending = getattr(self, "_wineAccessiblePendingFocus", None) - self._wineAccessiblePendingFocus = None - self._wineAccessibleFocusTimeoutId = 0 - if pending is None: - return False - - signature, parts, windowTitle = pending - self._wineAccessibleLastSignature = signature - self._wineAccessibleLastTime = time.monotonic() - parts = list(parts) - if windowTitle: - previousTitle = getattr(self, "_wineAccessibleWindowTitle", None) - self._wineAccessibleWindowTitle = windowTitle - if windowTitle != previousTitle and windowTitle not in parts: - parts.append(windowTitle) - if parts: - self.PresentMessage(", ".join(parts)) - return False - - def GetVersion(self) -> str: # pylint: disable=invalid-name - """Returns Cthulhu's version and revision if available.""" - - result = cthulhu_platform.version - if cthulhu_platform.revision: - result += f" (rev {cthulhu_platform.revision})" - - atspi_version = Atspi.get_version() - result += f", AT-SPI2 version: {atspi_version[0]}.{atspi_version[1]}.{atspi_version[2]}" - - session_type = os.environ.get("XDG_SESSION_TYPE") or "" - session_desktop = os.environ.get("XDG_SESSION_DESKTOP") or "" - session = f"{session_type} {session_desktop}".strip() - if session: - result += f", Session: {session}" - - msg = f"DBUS SERVICE: GetVersion called, returning: {result}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return result - - def GetRuntimeStateSnapshot(self) -> str: # pylint: disable=invalid-name - """Returns read-only runtime state counters for diagnostics.""" - - msg = "DBUS SERVICE: GetRuntimeStateSnapshot called." - debug.print_message(debug.LEVEL_INFO, msg, True) - - from . import cthulhu # pylint: disable=import-outside-toplevel - - snapshot = cthulhu.cthulhuApp.get_debug_snapshot() - return debug.format_runtime_state_snapshot(snapshot) - - def Quit(self) -> bool: # pylint: disable=invalid-name - """Quits Cthulhu.""" - - msg = "DBUS SERVICE: Quit called." - debug.print_message(debug.LEVEL_INFO, msg, True) - - from . import cthulhu # pylint: disable=import-outside-toplevel - - # cthulhu.shutdown() shuts down the dbus service, so send the response immediately and then - # do the actual shutdown after a brief delay. - def _delayed_shutdown(): - cthulhu.shutdown() - return False - - GLib.timeout_add(100, _delayed_shutdown) - return True - - -class CthulhuRemoteController: - """Manages Cthulhu's D-Bus service for remote control.""" - - SERVICE_NAME = "org.stormux.Cthulhu1.Service" - OBJECT_PATH = "/org/stormux/Cthulhu1/Service" - - def __init__(self) -> None: - self._dbus_service_interface: Optional[CthulhuDBusServiceInterface] = None - self._is_running: bool = False - self._bus: Optional[SessionMessageBus] = None - self._registered: dict[str, _ModuleRegistration] = {} - self._pending_registrations: dict[str, object] = {} - - def start(self) -> bool: - """Starts the D-Bus service.""" - - if not _dasbus_available: - msg = "REMOTE CONTROLLER: dasbus library not available, D-Bus service disabled." - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - - if self._is_running: - msg = "REMOTE CONTROLLER: Start called but service is already running." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - msg = "REMOTE CONTROLLER: Attempting to start D-Bus service." - debug.print_message(debug.LEVEL_INFO, msg, True) - - try: - self._bus = SessionMessageBus() - msg = ( - f"REMOTE CONTROLLER: SessionMessageBus acquired: " - f"{self._bus.connection.get_unique_name()}" - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - except DBusError as e: - self._bus = None - msg = f"REMOTE CONTROLLER: Failed to acquire D-Bus session bus: {e}" - debug.print_message(debug.LEVEL_SEVERE, msg, True) - return False - - self._dbus_service_interface = CthulhuDBusServiceInterface() - try: - self._bus.publish_object(self.OBJECT_PATH, self._dbus_service_interface) - self._bus.register_service(self.SERVICE_NAME) - except DBusError as e: - msg = f"REMOTE CONTROLLER: Failed to publish service or request name: {e}" - debug.print_message(debug.LEVEL_SEVERE, msg, True) - if self._dbus_service_interface and self._bus: - with contextlib.suppress(DBusError): - self._bus.unpublish_object(self.OBJECT_PATH) - self._dbus_service_interface = None - self._bus = None - return False - - self._is_running = True - msg = ( - f"REMOTE CONTROLLER: Service started name={self.SERVICE_NAME} path={self.OBJECT_PATH}." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - self._process_pending_registrations() - self._print_registration_summary() - return True - - def shutdown(self) -> None: - """Shuts down the D-Bus service.""" - - if not self._is_running: - msg = "REMOTE CONTROLLER: Shutdown called but service is not running." - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - msg = "REMOTE CONTROLLER: Attempting to shut down D-Bus service." - debug.print_message(debug.LEVEL_INFO, msg, True) - - for module_name in list(self._registered): - self._unpublish_module(module_name) - - if self._dbus_service_interface is not None and self._bus is not None: - with contextlib.suppress(DBusError): - self._bus.unpublish_object(self.OBJECT_PATH) - self._dbus_service_interface = None - - if self._bus is not None: - with contextlib.suppress(DBusError): - self._bus.unregister_service(self.SERVICE_NAME) - self._bus.disconnect() - self._bus = None - - self._is_running = False - msg = "REMOTE CONTROLLER: D-Bus service shut down." - debug.print_message(debug.LEVEL_INFO, msg, True) - self._pending_registrations.clear() - - def register_decorated_module(self, module_name: str, module_instance: object) -> None: - """Registers a module's decorated D-Bus methods, getters, and setters.""" - - if not self._is_running or self._bus is None: - msg = f"REMOTE CONTROLLER: Service not ready; queuing registration for {module_name}." - debug.print_message(debug.LEVEL_INFO, msg, True) - self._pending_registrations[module_name] = module_instance - return - self._publish_module(module_name, module_instance) - - def deregister_module_commands(self, module_name: str) -> bool: - """Deregisters a previously-registered module.""" - - if module_name in self._pending_registrations: - del self._pending_registrations[module_name] - msg = f"REMOTE CONTROLLER: Removed pending registration for {module_name}." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - if module_name not in self._registered: - msg = f"REMOTE CONTROLLER: Module '{module_name}' is not registered." - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - - return self._unpublish_module(module_name) - - def present_message_internal(self, message: str) -> bool: - """Presents a message via speech and/or braille without a D-Bus round-trip.""" - - if self._dbus_service_interface is None: - msg = "REMOTE CONTROLLER: Cannot present message; service not started." - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - - return self._dbus_service_interface.PresentMessage(message) - - def execute_command_internal( - self, - module_name: str, - command_name: str, - notify_user: bool = True, - ) -> bool: - """Executes a module command without a D-Bus round-trip.""" - - registration = self._registered.get(module_name) - if registration is None: - msg = f"REMOTE CONTROLLER: Module '{module_name}' not found." - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - - method = registration.find_command(command_name) - if method is None: - msg = f"REMOTE CONTROLLER: Unknown command '{command_name}' in '{module_name}'." - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - - event = _get_input_event().RemoteControllerEvent() - manager = script_manager.get_manager() - script = manager.get_active_script() or manager.get_default_script() - kwargs = {"script": script, "event": event, "notify_user": notify_user} - result = method(**_filter_kwargs_for_callable(method, kwargs)) - _get_input_event_manager().get_manager().process_remote_controller_event(event) - return bool(result) - - def get_value_internal(self, module_name: str, property_name: str) -> object: - """Gets a runtime value from a module without a D-Bus round-trip.""" - - registration = self._registered.get(module_name) - if registration is None: - msg = f"REMOTE CONTROLLER: Module '{module_name}' not found." - debug.print_message(debug.LEVEL_WARNING, msg, True) - return None - - method = registration.find_getter(property_name) - if method is None: - msg = f"REMOTE CONTROLLER: Unknown getter '{property_name}' in '{module_name}'." - debug.print_message(debug.LEVEL_WARNING, msg, True) - return None - - return method() - - def set_value_internal(self, module_name: str, property_name: str, value: object) -> bool: - """Sets a runtime value on a module without a D-Bus round-trip.""" - - registration = self._registered.get(module_name) - if registration is None: - msg = f"REMOTE CONTROLLER: Module '{module_name}' not found." - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - - method = registration.find_setter(property_name) - if method is None: - msg = f"REMOTE CONTROLLER: Unknown setter '{property_name}' in '{module_name}'." - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - - result = method(value) - if result is None: - return True - return bool(result) - - def _publish_module(self, module_name: str, module_instance: object) -> None: - """Builds the per-module D-Bus interface and publishes it on the bus.""" - - if self._bus is None: - return - - if module_name in self._registered: - msg = f"REMOTE CONTROLLER: Module {module_name} already registered. Replacing." - debug.print_message(debug.LEVEL_INFO, msg, True) - self._unpublish_module(module_name) - - registration = _ModuleRegistration.from_module_instance(module_name, module_instance) - if registration.is_empty(): - return - - try: - interface_class = _InterfaceBuilder.build(registration) - # for_publication is supplied to the namespace, so the class isn't actually - # abstract; pylint can't statically infer that. - dbus_object = interface_class() # pylint: disable=abstract-class-instantiated - object_path = f"{self.OBJECT_PATH}/{module_name}" - self._bus.publish_object(object_path, dbus_object) - except DBusError as e: - msg = f"REMOTE CONTROLLER: Failed to publish module {module_name}: {e}" - debug.print_message(debug.LEVEL_SEVERE, msg, True) - return - - registration.set_dbus_object(dbus_object) - registration.set_object_path(object_path) - self._registered[module_name] = registration - - msg = ( - f"REMOTE CONTROLLER: Registered {registration.total_member_count()} member(s) " - f"for {module_name} at {object_path}." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - - def _unpublish_module(self, module_name: str) -> bool: - """Removes a module's D-Bus interface from the bus.""" - - registration = self._registered.get(module_name) - if registration is None or self._bus is None: - return False - try: - self._bus.unpublish_object(registration.get_object_path()) - except DBusError as e: - msg = f"REMOTE CONTROLLER: Error unpublishing {module_name}: {e}" - debug.print_message(debug.LEVEL_WARNING, msg, True) - return False - del self._registered[module_name] - msg = f"REMOTE CONTROLLER: Unpublished {module_name}." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - def _process_pending_registrations(self) -> None: - """Publishes any modules that registered before the service was ready.""" - - if not self._pending_registrations: - return - msg = ( - f"REMOTE CONTROLLER: Processing {len(self._pending_registrations)} pending " - f"module registrations." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - for module_name, module_instance in list(self._pending_registrations.items()): - self._publish_module(module_name, module_instance) - self._pending_registrations.clear() - - def _print_registration_summary(self) -> None: - """Logs a summary of the registered modules and their member counts.""" - - modules = len(self._registered) - commands = sum( - len(reg.get_commands()) + len(reg.get_parameterized_commands()) - for reg in self._registered.values() - ) - getters = sum(len(reg.get_getters()) for reg in self._registered.values()) - setters = sum(len(reg.get_setters()) for reg in self._registered.values()) - msg = ( - f"REMOTE CONTROLLER: Registration summary: {modules} modules, " - f"{commands} commands, {getters} getters, {setters} setters." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - - -_remote_controller: CthulhuRemoteController = CthulhuRemoteController() - - -def get_remote_controller() -> CthulhuRemoteController: - """Returns the CthulhuRemoteController singleton.""" - - return _remote_controller diff --git a/src/cthulhu/debug-2025-06-25-23:07:09.out b/src/cthulhu/debug-2025-06-25-23:07:09.out deleted file mode 100644 index 89af5e3..0000000 --- a/src/cthulhu/debug-2025-06-25-23:07:09.out +++ /dev/null @@ -1,1736 +0,0 @@ -INFO: Preparing to launch. - 23:07:09.925003 -SCRIPT MANAGER: Initializing - 23:07:09.935501 -SCRIPT MANAGER: Initialized - 23:07:09.935528 -SETTINGS MANAGER: Initializing - 23:07:09.944951 -SETTINGS MANAGER: Initialized - 23:07:09.946518 -BRAILLE: About to import brlapi. - 23:07:09.962514 -BRAILLE: brlapi imported - 23:07:09.965243 -BRAILLE: About to import louis. - 23:07:09.965256 -BRAILLE: liblouis imported - 23:07:09.967086 -BRAILLE: tables location: /usr/share/liblouis/tables - 23:07:09.967108 -BRAILLE: User locale is en_US - 23:07:09.981985 -BRAILLE: 5 candidate tables for locale found: en-us-comp8-ext.utb, en-us-comp6.ctb, en-us-g1.ctb, en-us-comp8.ctb, en-us-g2.ctb - 23:07:09.982267 -BRAILLE: Default contraction table is: /usr/share/liblouis/tables/en-us-g1.ctb - 23:07:09.982284 -EVENT MANAGER: Initializing - 23:07:09.989103 -EVENT MANAGER: Async Mode is True - 23:07:09.989114 -Event manager initialized - 23:07:09.989407 -INFO: About to activate settings manager. - 23:07:10.053130 -SETTINGS MANAGER: Activating - 23:07:10.053151 -SETTINGS MANAGER: Attempt to load cthulhu-customizations from /home/storm/.local/share/cthulhu/cthulhu-customizations.py succeeded. - 23:07:10.061833 -SETTINGS MANAGER: Activated - 23:07:10.062048 -SETTINGS MANAGER: Current profile is None - 23:07:10.062066 -SETTINGS MANAGER: Current profile is now default - 23:07:10.062078 -SETTINGS MANAGER: Setting profile to: default - 23:07:10.062086 -SETTINGS MANAGER: Loading settings for default profile - 23:07:10.062102 -SETTINGS MANAGER: Settings for default profile loaded - 23:07:10.062321 -SETTINGS MANAGER: Merging settings. - 23:07:10.062329 -SETTINGS MANAGER: Settings merged. - 23:07:10.062339 -SETTINGS MANAGER: Setting runtime settings. - 23:07:10.062343 -SETTINGS MANAGER: Runtime settings set. - 23:07:10.062360 -INFO: About to launch Cthulhu. - 23:07:10.081208 -CTHULHU: Launching version Cthulhu screen reader version 2025.06.05-plugins (rev 408fb85) session: tty - 23:07:10.081252 -CTHULHU: Enabling accessibility (if needed). - 23:07:10.081342 -SETTINGS MANAGER: Checking if accessibility is enabled. - 23:07:10.081353 -SETTINGS MANAGER: Accessibility enabled: True - 23:07:10.082305 -CTHULHU: Initializing. - 23:07:10.082317 -CTHULHU: Initializing - 23:07:10.082323 -CTHULHU: Activating settings manager - 23:07:10.082341 -SETTINGS MANAGER: Activating - 23:07:10.082347 -SETTINGS MANAGER: Activated - 23:07:10.082588 -SETTINGS MANAGER: Current profile is default - 23:07:10.082617 -SETTINGS MANAGER: Setting profile to: default - 23:07:10.082630 -SETTINGS MANAGER: Loading settings for default profile - 23:07:10.082655 -SETTINGS MANAGER: Settings for default profile loaded - 23:07:10.082917 -SETTINGS MANAGER: Merging settings. - 23:07:10.082926 -SETTINGS MANAGER: Settings merged. - 23:07:10.082939 -SETTINGS MANAGER: Setting runtime settings. - 23:07:10.082944 -SETTINGS MANAGER: Runtime settings set. - 23:07:10.082966 -CTHULHU: Loading User Settings - 23:07:10.082971 -SPEECH: Shutting down - 23:07:10.083053 -BRAILLE: Attempting braille shutdown. - 23:07:10.083061 -BRAILLE: Braille was not running. - 23:07:10.083065 -SCRIPT MANAGER: Deactivating - 23:07:10.083071 -SCRIPT MANAGER: Deactivated - 23:07:10.083078 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.102397 -DEFAULT: Getting braille bindings. - 23:07:10.102979 -DEFAULT: Finished getting braille bindings. - 23:07:10.103003 -SCRIPT: default (module=cthulhu.scripts.default) initialized - 23:07:10.108625 -CTHULHU: About to enable speech - 23:07:10.108641 -SPEECH: Initializing - 23:07:10.108647 -SPEECH: Using speech server factory: cthulhu.speechdispatcherfactory - 23:07:10.733654 -SPEECH: Initialized - 23:07:10.733677 -CTHULHU: Braille is not enabled in settings - 23:07:10.733686 -Created binding: w with modifiers 256 - 23:07:10.740743 -Created binding: y with modifiers 256 - 23:07:10.741053 -Created binding: c with modifiers 257 - 23:07:10.741719 -Created binding: v with modifiers 257 - 23:07:10.742202 -Created binding: c with modifiers 257 - 23:07:10.742337 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.742411 -Created binding: v with modifiers 257 - 23:07:10.742848 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.742920 -Created binding: c with modifiers 257 - 23:07:10.743048 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.743111 -SCRIPT MANAGER: Activating - 23:07:10.743191 -EVENT MANAGER: Registering listeners for: default (module=cthulhu.scripts.default) - 23:07:10.743232 -EVENT MANAGER: registering listener for: focus: - 23:07:10.743239 -EVENT MANAGER: registering listener for: document:reload - 23:07:10.743733 -EVENT MANAGER: registering listener for: document:load-complete - 23:07:10.743908 -EVENT MANAGER: registering listener for: document:load-stopped - 23:07:10.744064 -EVENT MANAGER: registering listener for: mouse:button - 23:07:10.744258 -EVENT MANAGER: registering listener for: object:announcement - 23:07:10.744439 -EVENT MANAGER: registering listener for: object:property-change:accessible-name - 23:07:10.744600 -EVENT MANAGER: registering listener for: object:property-change:accessible-description - 23:07:10.744794 -EVENT MANAGER: registering listener for: object:text-caret-moved - 23:07:10.745071 -EVENT MANAGER: registering listener for: object:text-changed:delete - 23:07:10.745359 -EVENT MANAGER: registering listener for: object:text-changed:insert - 23:07:10.745634 -EVENT MANAGER: registering listener for: object:active-descendant-changed - 23:07:10.745892 -EVENT MANAGER: registering listener for: object:children-changed:add - 23:07:10.746090 -EVENT MANAGER: registering listener for: object:children-changed:remove - 23:07:10.746350 -EVENT MANAGER: registering listener for: object:state-changed:active - 23:07:10.746575 -EVENT MANAGER: registering listener for: object:state-changed:busy - 23:07:10.746787 -EVENT MANAGER: registering listener for: object:state-changed:focused - 23:07:10.746964 -EVENT MANAGER: registering listener for: object:state-changed:showing - 23:07:10.747140 -EVENT MANAGER: registering listener for: object:state-changed:checked - 23:07:10.747329 -EVENT MANAGER: registering listener for: object:state-changed:pressed - 23:07:10.747504 -EVENT MANAGER: registering listener for: object:state-changed:indeterminate - 23:07:10.747683 -EVENT MANAGER: registering listener for: object:state-changed:expanded - 23:07:10.747862 -EVENT MANAGER: registering listener for: object:state-changed:selected - 23:07:10.748040 -EVENT MANAGER: registering listener for: object:state-changed:sensitive - 23:07:10.748225 -EVENT MANAGER: registering listener for: object:text-attributes-changed - 23:07:10.748401 -EVENT MANAGER: registering listener for: object:text-selection-changed - 23:07:10.748548 -EVENT MANAGER: registering listener for: object:selection-changed - 23:07:10.748696 -EVENT MANAGER: registering listener for: object:property-change:accessible-value - 23:07:10.748847 -EVENT MANAGER: registering listener for: object:value-changed - 23:07:10.749028 -EVENT MANAGER: registering listener for: object:column-reordered - 23:07:10.749181 -EVENT MANAGER: registering listener for: object:row-reordered - 23:07:10.749335 -EVENT MANAGER: registering listener for: window:activate - 23:07:10.749483 -EVENT MANAGER: registering listener for: window:deactivate - 23:07:10.749632 -EVENT MANAGER: registering listener for: window:create - 23:07:10.749780 -EVENT MANAGER: registering listener for: window:destroy - 23:07:10.749925 -DEFAULT: Activating script for None - 23:07:10.750445 -BRAILLE: Checking braille setting. - 23:07:10.750460 -BRAILLE: Disabling braille. BrlAPI running: False - 23:07:10.750475 -BRAILLE: Setting up key ranges. - 23:07:10.750481 -BRAILLE: Not setting up key ranges: BrlAPI not running. - 23:07:10.750486 -SPEECH: Checking speech setting. - 23:07:10.750490 -SPEECH: Initializing - 23:07:10.750495 -SPEECH: Already initialized - 23:07:10.750498 -EVENT MANAGER: Registering keystroke listener function: > - 23:07:10.750649 -DEFAULT: Script for None activated - 23:07:10.757055 -SCRIPT MANAGER: Setting active script to default (module=cthulhu.scripts.default) reason: activate - 23:07:10.757129 -SCRIPT MANAGER: Activated - 23:07:10.757140 -EVENT MANAGER: Activating - 23:07:10.757147 -EVENT MANAGER: Activated - 23:07:10.757152 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.757285 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.757993 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.758154 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.758352 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.758784 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.758899 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.759017 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.759399 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.759935 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.760072 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.760207 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.760511 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.760620 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.760735 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.760935 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.761257 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.761333 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.761421 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.761657 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.761753 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.761813 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.761942 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.762264 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.762340 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.762428 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.762669 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.762723 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.762781 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.762938 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.763363 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.763444 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.763538 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.763793 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.763849 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.763908 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.764039 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.764362 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.764499 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.764643 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.764901 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.764959 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.765020 -CTHULHU: User Settings Loaded - 23:07:10.765135 -CTHULHU: Initialized - 23:07:10.765164 -CTHULHU: Initialized. - 23:07:10.765169 -SPEECH: Speak 'Cthulhu welcomes you.' acss: {'established': False} - 23:07:10.765204 -SPEECH OUTPUT: 'Cthulhu welcomes you.' {'established': False, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:10.765236 -SPEECH DISPATCHER: Speaking ' Cthulhu welcomes you. ' as string - 23:07:10.765254 -SPEECH DISPATCHER: Speaking 'Cthulhu welcomes you.' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:10.765714 -SCRIPT UTILITIES: Looking at [frame: 'storm@fenrir:~/git/fenrir/src'] from [application: 'lxterminal'] lxterminal - 23:07:10.774828 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] can be active window - 23:07:10.775202 -SCRIPT UTILITIES: Looking at [frame: 'storm@fenrir:~'] from [application: 'lxterminal'] lxterminal - 23:07:10.777840 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~'] lacks state active - 23:07:10.778077 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~'] is not active and showing, or is iconified - 23:07:10.778237 -SCRIPT UTILITIES: Looking at [frame: 'storm@fenrir:~'] from [application: 'lxterminal'] lxterminal - 23:07:10.780570 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~'] lacks state active - 23:07:10.780789 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~'] is not active and showing, or is iconified - 23:07:10.780935 -SCRIPT UTILITIES: Active window is [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:10.781083 -CTHULHU: Request to set active window to [frame: 'storm@fenrir:~/git/fenrir/src'] in [application: 'lxterminal'] - 23:07:10.781695 -CTHULHU: Active script is: default (module=cthulhu.scripts.default) - 23:07:10.781795 -CTHULHU: Changing locusOfFocus from None to [frame: 'storm@fenrir:~/git/fenrir/src']. Notify: True - 23:07:10.782309 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object for: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:10.782783 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object: True - 23:07:10.782912 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object for: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:10.783308 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object: True - 23:07:10.783437 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object for: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:10.783927 -BRAILLE: update disabled - 23:07:10.783939 -SPEECH GENERATOR: Starting unfocused generation for [frame: 'storm@fenrir:~/git/fenrir/src'] (using role: frame) - 23:07:10.784191 - GENERATION TIME: 0.0006 ----> oldAncestors=[] - GENERATION TIME: 0.0003 ----> newAncestors=[] -SPEECH GENERATOR: default voice requested with language='None', dialect='' - 23:07:10.785619 - GENERATION TIME: 0.0005 ----> labelOrName=[storm@fenrir:~/git/fenrir/src] -SPEECH GENERATOR: system voice requested with language='None', dialect='' - 23:07:10.788266 - GENERATION TIME: 0.0026 ----> roleName=[frame] -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object for: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:10.789710 - GENERATION TIME: 0.0017 ----> unfocusedDialogCount=[] - GENERATION TIME: 0.0003 ----> availability=[] - GENERATION TIME: 0.0007 ----> newNodeLevel=[] - GENERATION TIME: 0.0003 ----> unselectedCell=[] - GENERATION TIME: 0.0002 ----> clickable=[] - GENERATION TIME: 0.0002 ----> pause=[PAUSE] - GENERATION TIME: 0.0002 ----> hasLongDesc=[] - GENERATION TIME: 0.0002 ----> hasDetails=[] - GENERATION TIME: 0.0002 ----> detailsFor=[] - GENERATION TIME: 0.0003 ----> tutorial=[] - GENERATION TIME: 0.0004 ----> description=[] - GENERATION TIME: 0.0002 ----> hasPopup=[] - COMPLETION TIME: 0.0093 - SPEECH GENERATOR: Results: - 'storm@fenrir:~/git/fenrir/src' - '{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}' - 'frame' - '{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}' - 'PAUSE' - 'PAUSE' -SCRIPT UTILITIES: Not interrupting for locusOfFocus change: event is None - 23:07:10.793329 -SPEECH: Last spoke 0.0281 seconds ago - 23:07:10.793342 -SPEECH: Speak [storm@fenrir:~/git/fenrir/src, {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}, frame, {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}, PAUSE, PAUSE], acss: None - 23:07:10.793378 -SPEECH OUTPUT: 'storm@fenrir:~/git/fenrir/src frame.' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:10.793412 -SPEECH DISPATCHER: Speaking ' storm@fenrir:~/git/fenrir/src frame. ' as string - 23:07:10.793428 -SPEECH DISPATCHER: Speaking 'storm@fenrir:~/git/fenrir/src frame.' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:10.793662 -CTHULHU: Switching active mode from None to focus-tracking - 23:07:10.793871 -CTHULHU: Region of interest: [frame: 'storm@fenrir:~/git/fenrir/src'] ( 0) 0 - 23:07:10.794099 -CTHULHU: Switching object of interest from None to [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:10.794331 -SCRIPT MANAGER: Mapped [application: 'lxterminal'] to lxterminal - 23:07:10.795658 -SCRIPT MANAGER: Found cthulhu.scripts.toolkits.gtk - 23:07:10.796845 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.797146 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.797511 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.797602 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.797708 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.797949 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.798007 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.798066 -DEFAULT: Getting braille bindings. - 23:07:10.798188 -DEFAULT: Finished getting braille bindings. - 23:07:10.798211 -SCRIPT: lxterminal (module=cthulhu.scripts.toolkits.gtk.script) initialized - 23:07:10.803811 -SCRIPT MANAGER: Mapped [application: 'lxterminal'] to lxterminal - 23:07:10.804048 -SCRIPT MANAGER: Found cthulhu.scripts.toolkits.gtk - 23:07:10.804504 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.804781 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.805267 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.805364 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.805473 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.805765 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.805829 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.805896 -DEFAULT: Getting braille bindings. - 23:07:10.806020 -DEFAULT: Finished getting braille bindings. - 23:07:10.806029 -SCRIPT: lxterminal (module=cthulhu.scripts.toolkits.gtk.script) initialized - 23:07:10.810925 -DEFAULT: removing key grabs - 23:07:10.810957 -DEFAULT: Activating script for [application: 'lxterminal'] - 23:07:10.811055 -SETTINGS MANAGER: Loading settings for None profile - 23:07:10.811253 -SETTINGS MANAGER: Settings for default profile loaded - 23:07:10.811495 -SETTINGS MANAGER: Merging settings. - 23:07:10.811503 -SETTINGS MANAGER: Settings merged. - 23:07:10.811514 -SETTINGS MANAGER: Setting runtime settings. - 23:07:10.811518 -SETTINGS MANAGER: Runtime settings set. - 23:07:10.811544 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.811582 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.811875 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.811954 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.812043 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.812319 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.812392 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.812450 -BRAILLE: Checking braille setting. - 23:07:10.812633 -BRAILLE: Disabling braille. BrlAPI running: False - 23:07:10.812648 -BRAILLE: Setting up key ranges. - 23:07:10.812653 -BRAILLE: Not setting up key ranges: BrlAPI not running. - 23:07:10.812657 -SPEECH: Checking speech setting. - 23:07:10.812661 -SPEECH: Initializing - 23:07:10.812665 -SPEECH: Already initialized - 23:07:10.812667 -DEFAULT: Script for [application: 'lxterminal'] activated - 23:07:10.812922 -SCRIPT MANAGER: Setting active script to lxterminal (module=cthulhu.scripts.toolkits.gtk.script) reason: Launching. - 23:07:10.812963 -AXCollection: found [terminal | Terminal] in 0.0002s - 23:07:10.813769 -CTHULHU: Focused object is: [terminal: 'Terminal'] - 23:07:10.813867 -CTHULHU: Active script is: lxterminal (module=cthulhu.scripts.toolkits.gtk.script) - 23:07:10.813962 -CTHULHU: Changing locusOfFocus from [frame: 'storm@fenrir:~/git/fenrir/src'] to [terminal: 'Terminal']. Notify: True - 23:07:10.814230 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object for: [terminal: 'Terminal'] - 23:07:10.815283 -SCRIPT UTILITIES: [terminal: 'Terminal'] is top-level object: False - 23:07:10.815375 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object for: [terminal: 'Terminal'] - 23:07:10.816197 -SCRIPT UTILITIES: [terminal: 'Terminal'] is top-level object: False - 23:07:10.816291 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object for: [terminal: 'Terminal'] - 23:07:10.816869 -BRAILLE: update disabled - 23:07:10.816881 -SPEECH GENERATOR: Starting unfocused generation for [terminal: 'Terminal'] (using role: terminal) - 23:07:10.817059 - GENERATION TIME: 0.0007 ----> oldAncestors=[] -SCRIPT UTILITIES: Looking for common ancestor of [frame: 'storm@fenrir:~/git/fenrir/src'] and [terminal: 'Terminal'] - 23:07:10.818333 -SCRIPT UTILITIES: Common ancestor of [frame: 'storm@fenrir:~/git/fenrir/src'] and [terminal: 'Terminal'] is [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:10.819074 -DEFAULT: Not in SayAll - 23:07:10.819092 -SCRIPT UTILITIES: [filler] is deemed to be layout only - 23:07:10.819488 -SCRIPT UTILITIES: [page tab] is deemed to be layout only - 23:07:10.820064 -SCRIPT UTILITIES: [page tab list] is deemed to be layout only - 23:07:10.820621 -SCRIPT UTILITIES: [filler] is deemed to be layout only - 23:07:10.820948 - GENERATION TIME: 0.0034 ----> newAncestors=[] -SPEECH GENERATOR: default voice requested with language='None', dialect='' - 23:07:10.822888 - GENERATION TIME: 0.0017 ----> textContent=[[storm@fenrir src] $ sudo ./fenrir\n] - GENERATION TIME: 0.0008 ----> newNodeLevel=[] - GENERATION TIME: 0.0002 ----> unselectedCell=[] - GENERATION TIME: 0.0002 ----> clickable=[] - GENERATION TIME: 0.0002 ----> pause=[PAUSE] - GENERATION TIME: 0.0002 ----> hasLongDesc=[] - GENERATION TIME: 0.0002 ----> hasDetails=[] - GENERATION TIME: 0.0002 ----> detailsFor=[] - GENERATION TIME: 0.0002 ----> tutorial=[] -SCRIPT UTILITIES: Similarity between 'Terminal', 'storm@fenrir:~/git/fenrir/src': 0.27 (threshold: 0.5) - 23:07:10.825302 -SPEECH GENERATOR: system voice requested with language='None', dialect='' - 23:07:10.825322 - GENERATION TIME: 0.0005 ----> description=[storm@fenrir:~/git/fenrir/src] - GENERATION TIME: 0.0002 ----> hasPopup=[] - COMPLETION TIME: 0.0086 - SPEECH GENERATOR: Results: - '[storm@fenrir src] $ sudo ./fenrir -' - '{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}' - 'PAUSE' - 'storm@fenrir:~/git/fenrir/src' - '{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}' - 'PAUSE' -SCRIPT UTILITIES: Not interrupting for locusOfFocus change: event is None - 23:07:10.825572 -SPEECH: Last spoke 0.0322 seconds ago - 23:07:10.825584 -SPEECH: Speak [[storm@fenrir src] $ sudo./fenrir - , {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}, PAUSE, storm@fenrir:~/git/fenrir/src, {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}, PAUSE], acss: None - 23:07:10.825621 -SPEECH OUTPUT: '[storm@fenrir src] $ sudo ./fenrir - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:10.825648 -SPEECH DISPATCHER: Speaking ' [storm@fenrir src] $ sudo./fenrir - ' as string - 23:07:10.825683 -SPEECH DISPATCHER: Speaking '[storm@fenrir src] $ sudo ./fenrir - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:10.825937 -SPEECH: New voice {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}} != active voice {'established': False} - 23:07:10.826191 -SPEECH OUTPUT: 'storm@fenrir:~/git/fenrir/src.' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:10.826213 -SPEECH DISPATCHER: Speaking ' storm@fenrir:~/git/fenrir/src. ' as string - 23:07:10.826227 -SPEECH DISPATCHER: Speaking 'storm@fenrir:~/git/fenrir/src.' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:10.826441 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:10.826712 -CTHULHU: Switching object of interest from [frame: 'storm@fenrir:~/git/fenrir/src'] to [terminal: 'Terminal'] - 23:07:10.826878 -SCRIPT UTILITIES: New selection for [terminal: 'Terminal'] is '' (0, 0) - 23:07:10.827334 -SCRIPT MANAGER: Found cthulhu.scripts.terminal - 23:07:10.828736 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.828941 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.829257 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.829349 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.829446 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.829689 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.829745 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.829803 -DEFAULT: Getting braille bindings. - 23:07:10.829901 -DEFAULT: Finished getting braille bindings. - 23:07:10.829910 -SCRIPT: lxterminal (module=cthulhu.scripts.terminal.script) initialized - 23:07:10.835082 -DEFAULT: removing key grabs - 23:07:10.835217 -DEFAULT: Activating script for [application: 'lxterminal'] - 23:07:10.835327 -SETTINGS MANAGER: Loading settings for None profile - 23:07:10.835511 -SETTINGS MANAGER: Settings for default profile loaded - 23:07:10.835725 -SETTINGS MANAGER: Merging settings. - 23:07:10.835734 -SETTINGS MANAGER: Settings merged. - 23:07:10.835743 -SETTINGS MANAGER: Setting runtime settings. - 23:07:10.835747 -SETTINGS MANAGER: Runtime settings set. - 23:07:10.835766 -KEYBINDINGS: Could not find 257 handler for keybinding. - 23:07:10.835798 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.836117 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.836209 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.836311 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.836568 -KEYBINDINGS: 'Insert+Shift+c' (clipboard) already in keybindings - 23:07:10.836625 -KEYBINDINGS: 'Insert+Shift+v' (Cthulhu screen reader version 2025.06.05-plugins) already in keybindings - 23:07:10.836682 -BRAILLE: Checking braille setting. - 23:07:10.836877 -BRAILLE: Disabling braille. BrlAPI running: False - 23:07:10.836892 -BRAILLE: Setting up key ranges. - 23:07:10.836896 -BRAILLE: Not setting up key ranges: BrlAPI not running. - 23:07:10.836900 -SPEECH: Checking speech setting. - 23:07:10.836903 -SPEECH: Initializing - 23:07:10.836907 -SPEECH: Already initialized - 23:07:10.836909 -DEFAULT: Script for [application: 'lxterminal'] activated - 23:07:10.837131 -SCRIPT MANAGER: Setting active script to lxterminal (module=cthulhu.scripts.terminal.script) reason: Found focused object. - 23:07:10.837159 -CTHULHU: Starting ATSPI registry. - 23:07:10.837165 -CTHULHU: Starting - 23:07:10.837170 -CTHULHU: Startup complete notification made - 23:07:10.837379 -CTHULHU: Starting Atspi main event loop - 23:07:10.837387 -CTHULHU: Starting D-Bus remote controller - 23:07:10.837546 -CTHULHU: Failed to start D-Bus service: module 'cthulhu.debug' has no attribute 'print_message' - 23:07:10.837566 - -EVENT MANAGER: object:children-changed:add from None - 23:07:10.837717 -EVENT MANAGER: Ignoring because event is not from active app - 23:07:10.837741 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.668020 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.668161 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.668308 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.668649 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.668731 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.668868 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.668934 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.669065 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.669129 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.669277 -CTHULHU: Keyboard change detected, re-creating the xmodmap - 23:07:14.669339 - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203088982 - time=1750907234.948488 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:14.948618 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:14.948709 -LOCATION: [terminal: 'Terminal'] - 23:07:14.948791 -CONSUME: True Script indication - 23:07:14.948808 -DEFAULT: Interrupting presentation - 23:07:14.948816 -TOTAL PROCESSING TIME: 0.0005 - 23:07:14.948979 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -INFO: Handler is Move flat review to the beginning of the next line - 23:07:14.950040 -FLAT REVIEW PRESENTER: Creating new context. Restrict: False - 23:07:14.950051 -CTHULHU: Active mode: focus-tracking Object of interest: [terminal: 'Terminal'] - 23:07:14.950144 -SCRIPT UTILITIES: [frame: 'storm@fenrir:~/git/fenrir/src'] is top-level object for: [terminal: 'Terminal'] - 23:07:14.950654 -SCRIPT UTILITIES: [terminal: 'Terminal'] is in frame [frame: 'storm@fenrir:~/git/fenrir/src'] and dialog None - 23:07:14.951161 -FLAT REVIEW: Frame: [frame: 'storm@fenrir:~/git/fenrir/src'] Dialog: None. Top level: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:14.951306 -SCRIPT UTILITIES: Extents for [frame: 'storm@fenrir:~/git/fenrir/src'] are: [0, 50, 1920, 1030] - 23:07:14.952311 -SCRIPT UTILITIES: Extents for [filler] are: [2, 50, 1916, 1028] - 23:07:14.953031 -SCRIPT UTILITIES: Extents for [menu bar] are: [2, 50, 1916, 27] - 23:07:14.953708 -AXSelection: [menu bar] reports 0 selected children - 23:07:14.954098 -SCRIPT UTILITIES: Selected children not retrieved via selection interface. - 23:07:14.954111 -SCRIPT UTILITIES: Extents for [menu: 'File'] are: [2, 50, 42, 27] - 23:07:14.954611 -AXSelection: [menu bar] reports 0 selected children - 23:07:14.955082 -SCRIPT UTILITIES: Selected children not retrieved via selection interface. - 23:07:14.955095 -SCRIPT UTILITIES: Extents for [menu: 'Edit'] are: [44, 50, 43, 27] - 23:07:14.955454 -AXSelection: [menu bar] reports 0 selected children - 23:07:14.955895 -SCRIPT UTILITIES: Selected children not retrieved via selection interface. - 23:07:14.955908 -SCRIPT UTILITIES: Extents for [menu: 'Tabs'] are: [87, 50, 49, 27] - 23:07:14.956201 -AXSelection: [menu bar] reports 0 selected children - 23:07:14.956651 -SCRIPT UTILITIES: Selected children not retrieved via selection interface. - 23:07:14.956663 -SCRIPT UTILITIES: Extents for [menu: 'Help'] are: [136, 50, 49, 27] - 23:07:14.956905 -AXSelection: [menu bar] reports 0 selected children - 23:07:14.957347 -SCRIPT UTILITIES: Selected children not retrieved via selection interface. - 23:07:14.957359 -SCRIPT UTILITIES: Extents for [page tab list] are: [2, 78, 1916, 1000] - 23:07:14.957647 -SCRIPT UTILITIES: Extents for [page tab] are: [-1, -1, -1, -1] - 23:07:14.958334 -SCRIPT UTILITIES: Extents for [filler] are: [2, 78, 1916, 1000] - 23:07:14.958905 -SCRIPT UTILITIES: Extents for [terminal: 'Terminal'] are: [2, 78, 1902, 1000] - 23:07:14.959382 -SCRIPT UTILITIES: Extents for [scroll bar] are: [1904, 78, 14, 1000] - 23:07:14.960147 -FLAT REVIEW: 6 on-screen objects found for [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:14.960594 -SPEECH GENERATOR: default voice requested with language='None', dialect='' - 23:07:14.960797 -SPEECH GENERATOR: default voice requested with language='None', dialect='' - 23:07:14.961322 -SPEECH GENERATOR: default voice requested with language='None', dialect='' - 23:07:14.961813 -SPEECH GENERATOR: default voice requested with language='None', dialect='' - 23:07:14.962309 -FLAT REVIEW: Getting lines for [terminal | Terminal] offsets 0-3324 - 23:07:14.965142 -FLAT REVIEW: 58 lines found for [terminal: 'Terminal'] - 23:07:14.972553 -FLAT REVIEW: 63 zones found for [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:15.046845 -FLAT REVIEW: Zones clustered into 60 lines - 23:07:15.047697 -FLAT REVIEW: Searching for word at offset 3310 - 23:07:15.047841 -FLAT REVIEW: Checking WORD: '[storm@fenrir ' (3289-3303) [terminal | Terminal] - 23:07:15.049022 -FLAT REVIEW: Checking WORD: 'src] ' (3303-3308) [terminal | Terminal] - 23:07:15.049115 -FLAT REVIEW: Checking WORD: '$ ' (3308-3310) [terminal | Terminal] - 23:07:15.049204 -FLAT REVIEW: Checking WORD: 'sudo ' (3310-3315) [terminal | Terminal] - 23:07:15.049285 -FLAT REVIEW: On line 59, zone 0 word 3, char 0 - 23:07:15.049299 -CTHULHU: Switching active mode from focus-tracking to flat-review - 23:07:15.049357 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:15.049440 -TOTAL PROCESSING TIME: 0.0994 - 23:07:15.049486 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203089191 - time=1750907235.156218 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:15.156315 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:15.156404 -LOCATION: [terminal: 'Terminal'] - 23:07:15.156484 -CONSUME: True Is release for last non-modifier keyevent - 23:07:15.156506 -TOTAL PROCESSING TIME: 0.0003 - 23:07:15.156528 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203089356 - time=1750907235.321236 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:15.321345 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:15.321439 -LOCATION: [terminal: 'Terminal'] - 23:07:15.321514 -CONSUME: True Script indication - 23:07:15.321530 -DEFAULT: Interrupting presentation - 23:07:15.321539 -TOTAL PROCESSING TIME: 0.0004 - 23:07:15.321673 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:15.322738 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:15.322750 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:15.322841 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:15.322858 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:15.322935 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:15.324742 -SPEECH: Last spoke 4.4993 seconds ago - 23:07:15.324872 -SPEECH: Speak '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:15.324884 -SPEECH OUTPUT: '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:15.324909 -SPEECH DISPATCHER: Speaking ' [storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' as string - 23:07:15.324926 -SPEECH DISPATCHER: Speaking '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:15.325248 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:15.325591 -BRAILLE: update review disabled - 23:07:15.325628 -TOTAL PROCESSING TIME: 0.0029 - 23:07:15.325643 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203089506 - time=1750907235.471477 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:15.471598 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:15.471701 -LOCATION: [terminal: 'Terminal'] - 23:07:15.471787 -CONSUME: True Is release for last non-modifier keyevent - 23:07:15.471809 -TOTAL PROCESSING TIME: 0.0003 - 23:07:15.471831 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203089814 - time=1750907235.779310 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:15.779416 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:15.779501 -LOCATION: [terminal: 'Terminal'] - 23:07:15.779574 -CONSUME: True Script indication - 23:07:15.779590 -DEFAULT: Interrupting presentation - 23:07:15.779599 -TOTAL PROCESSING TIME: 0.0004 - 23:07:15.779719 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:15.780797 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:15.780810 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:15.780916 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:15.780936 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:15.781015 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:15.781355 -SPEECH: Last spoke 0.4565 seconds ago - 23:07:15.781398 -SPEECH: Speak '137 - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:15.781409 -SPEECH OUTPUT: '137 - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:15.781433 -SPEECH DISPATCHER: Speaking ' 137 - ' as string - 23:07:15.781449 -SPEECH DISPATCHER: Speaking '137 - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:15.781650 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:15.781883 -BRAILLE: update review disabled - 23:07:15.781920 -TOTAL PROCESSING TIME: 0.0011 - 23:07:15.781930 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203089956 - time=1750907235.921121 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:15.921238 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:15.921331 -LOCATION: [terminal: 'Terminal'] - 23:07:15.921414 -CONSUME: True Is release for last non-modifier keyevent - 23:07:15.921434 -TOTAL PROCESSING TIME: 0.0003 - 23:07:15.921453 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203090144 - time=1750907236.109303 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:16.109416 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:16.109511 -LOCATION: [terminal: 'Terminal'] - 23:07:16.109592 -CONSUME: True Script indication - 23:07:16.109611 -DEFAULT: Interrupting presentation - 23:07:16.109620 -TOTAL PROCESSING TIME: 0.0004 - 23:07:16.109728 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -INFO: Handler is Move flat review to the beginning of the next line - 23:07:16.110806 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:16.110820 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:16.110918 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:16.110937 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:16.111015 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:16.112826 -SPEECH: Last spoke 0.3315 seconds ago - 23:07:16.112947 -SPEECH: Speak '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:16.112958 -SPEECH OUTPUT: '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:16.112980 -SPEECH DISPATCHER: Speaking ' [storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' as string - 23:07:16.112998 -SPEECH DISPATCHER: Speaking '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:16.113267 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:16.113586 -BRAILLE: update review disabled - 23:07:16.113620 -TOTAL PROCESSING TIME: 0.0028 - 23:07:16.113630 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203090331 - time=1750907236.296409 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:16.296527 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:16.296627 -LOCATION: [terminal: 'Terminal'] - 23:07:16.296712 -CONSUME: True Is release for last non-modifier keyevent - 23:07:16.296734 -TOTAL PROCESSING TIME: 0.0003 - 23:07:16.296752 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203090391 - time=1750907236.356025 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:16.356124 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:16.356229 -LOCATION: [terminal: 'Terminal'] - 23:07:16.356316 -CONSUME: True Script indication - 23:07:16.356335 -DEFAULT: Interrupting presentation - 23:07:16.356344 -TOTAL PROCESSING TIME: 0.0004 - 23:07:16.356463 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -INFO: Handler is Move flat review to the beginning of the next line - 23:07:16.357525 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:16.357534 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:16.357619 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:16.357634 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:16.357709 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:16.358801 -SPEECH: Last spoke 0.2459 seconds ago - 23:07:16.358877 -SPEECH: Speak '[storm@fenrir src] $ sudo ./fenrir - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:16.358889 -SPEECH OUTPUT: '[storm@fenrir src] $ sudo ./fenrir - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:16.358911 -SPEECH DISPATCHER: Speaking ' [storm@fenrir src] $ sudo./fenrir - ' as string - 23:07:16.358927 -SPEECH DISPATCHER: Speaking '[storm@fenrir src] $ sudo ./fenrir - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:16.359148 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:16.359453 -BRAILLE: update review disabled - 23:07:16.359515 -TOTAL PROCESSING TIME: 0.0020 - 23:07:16.359526 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203090526 - time=1750907236.491058 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:16.491167 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:16.491273 -LOCATION: [terminal: 'Terminal'] - 23:07:16.491360 -CONSUME: True Is release for last non-modifier keyevent - 23:07:16.491381 -TOTAL PROCESSING TIME: 0.0003 - 23:07:16.491400 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203090601 - time=1750907236.566086 - keyType=unknown - clickCount=3 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:16.566210 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:16.566327 -LOCATION: [terminal: 'Terminal'] - 23:07:16.566405 -CONSUME: True Script indication - 23:07:16.566422 -DEFAULT: Interrupting presentation - 23:07:16.566434 -TOTAL PROCESSING TIME: 0.0004 - 23:07:16.566533 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -INFO: Handler is Move flat review to the beginning of the next line - 23:07:16.567598 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:16.567610 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:16.567726 -TOTAL PROCESSING TIME: 0.0001 - 23:07:16.567739 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203090721 - time=1750907236.686099 - keyType=unknown - clickCount=3 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:16.686199 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:16.686279 -LOCATION: [terminal: 'Terminal'] - 23:07:16.686363 -CONSUME: True Is release for last non-modifier keyevent - 23:07:16.686387 -TOTAL PROCESSING TIME: 0.0003 - 23:07:16.686404 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203090811 - time=1750907236.776032 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:16.776164 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:16.776308 -LOCATION: [terminal: 'Terminal'] - 23:07:16.776391 -CONSUME: True Script indication - 23:07:16.776407 -DEFAULT: Interrupting presentation - 23:07:16.776421 -TOTAL PROCESSING TIME: 0.0005 - 23:07:16.776507 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -INFO: Handler is Move flat review to the beginning of the next line - 23:07:16.777569 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:16.777578 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:16.777692 -TOTAL PROCESSING TIME: 0.0001 - 23:07:16.777704 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203090939 - time=1750907236.903973 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:16.904099 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:16.904248 -LOCATION: [terminal: 'Terminal'] - 23:07:16.904332 -CONSUME: True Is release for last non-modifier keyevent - 23:07:16.904349 -TOTAL PROCESSING TIME: 0.0004 - 23:07:16.904363 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203092026 - time=1750907237.991251 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:17.991356 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:17.991443 -LOCATION: [terminal: 'Terminal'] - 23:07:17.991519 -CONSUME: True Script indication - 23:07:17.991536 -DEFAULT: Interrupting presentation - 23:07:17.991544 -TOTAL PROCESSING TIME: 0.0004 - 23:07:17.991652 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:17.992715 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:17.992725 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:17.992855 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:17.992867 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:17.992953 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:17.994744 -SPEECH: Last spoke 1.6360 seconds ago - 23:07:17.994872 -SPEECH: Speak '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:17.994884 -SPEECH OUTPUT: '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:17.994909 -SPEECH DISPATCHER: Speaking ' [storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' as string - 23:07:17.994928 -SPEECH DISPATCHER: Speaking '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:17.995152 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:17.995466 -BRAILLE: update review disabled - 23:07:17.995503 -TOTAL PROCESSING TIME: 0.0028 - 23:07:17.995517 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203092187 - time=1750907238.152456 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:18.152637 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:18.152772 -LOCATION: [terminal: 'Terminal'] - 23:07:18.152893 -CONSUME: True Is release for last non-modifier keyevent - 23:07:18.152914 -TOTAL PROCESSING TIME: 0.0004 - 23:07:18.152940 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203092566 - time=1750907238.531246 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:18.531371 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:18.531490 -LOCATION: [terminal: 'Terminal'] - 23:07:18.531597 -CONSUME: True Script indication - 23:07:18.531613 -DEFAULT: Interrupting presentation - 23:07:18.531627 -TOTAL PROCESSING TIME: 0.0005 - 23:07:18.531782 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:18.532850 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:18.532861 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:18.532971 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:18.532985 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:18.533084 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:18.533439 -SPEECH: Last spoke 0.5386 seconds ago - 23:07:18.533481 -SPEECH: Speak '137 - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:18.533492 -SPEECH OUTPUT: '137 - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:18.533516 -SPEECH DISPATCHER: Speaking ' 137 - ' as string - 23:07:18.533532 -SPEECH DISPATCHER: Speaking '137 - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:18.533747 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:18.533996 -BRAILLE: update review disabled - 23:07:18.534032 -TOTAL PROCESSING TIME: 0.0012 - 23:07:18.534040 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203092686 - time=1750907238.651057 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:18.651161 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:18.651267 -LOCATION: [terminal: 'Terminal'] - 23:07:18.651360 -CONSUME: True Is release for last non-modifier keyevent - 23:07:18.651379 -TOTAL PROCESSING TIME: 0.0003 - 23:07:18.651394 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203092851 - time=1750907238.816279 - keyType=unknown - clickCount=3 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:18.816402 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:18.816497 -LOCATION: [terminal: 'Terminal'] - 23:07:18.816579 -CONSUME: True Script indication - 23:07:18.816597 -DEFAULT: Interrupting presentation - 23:07:18.816606 -TOTAL PROCESSING TIME: 0.0004 - 23:07:18.816723 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:18.817786 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:18.817796 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:18.817883 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:18.817894 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:18.817968 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:18.818313 -SPEECH: Last spoke 0.2849 seconds ago - 23:07:18.818353 -SPEECH: Speak 'Killed - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:18.818364 -SPEECH OUTPUT: 'Killed - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:18.818386 -SPEECH DISPATCHER: Speaking ' Killed - ' as string - 23:07:18.818402 -SPEECH DISPATCHER: Speaking 'Killed - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:18.818603 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:18.818826 -BRAILLE: update review disabled - 23:07:18.818859 -TOTAL PROCESSING TIME: 0.0011 - 23:07:18.818868 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203092994 - time=1750907238.959129 - keyType=unknown - clickCount=3 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:18.959266 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:18.959390 -LOCATION: [terminal: 'Terminal'] - 23:07:18.959505 -CONSUME: True Is release for last non-modifier keyevent - 23:07:18.959523 -TOTAL PROCESSING TIME: 0.0004 - 23:07:18.959546 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203093294 - time=1750907239.259315 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:19.259434 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:19.259532 -LOCATION: [terminal: 'Terminal'] - 23:07:19.259616 -CONSUME: True Script indication - 23:07:19.259635 -DEFAULT: Interrupting presentation - 23:07:19.259645 -TOTAL PROCESSING TIME: 0.0004 - 23:07:19.259762 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:19.260822 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:19.260831 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:19.260916 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:19.260928 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:19.261055 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:19.262803 -SPEECH: Last spoke 0.4446 seconds ago - 23:07:19.262917 -SPEECH: Speak 'CTHULHU: Exception starting ATSPI registry. - 14:18:04.616885 - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:19.262929 -SPEECH OUTPUT: 'CTHULHU: Exception starting ATSPI registry. - 14:18:04.616885 - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:19.262953 -SPEECH DISPATCHER: Speaking ' CTHULHU: Exception starting ATSPI registry. - 14:18:04.616885 - ' as string - 23:07:19.262971 -SPEECH DISPATCHER: Speaking 'CTHULHU: Exception starting ATSPI registry. - 14:18:04.616885 - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:19.263212 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:19.263546 -BRAILLE: update review disabled - 23:07:19.263585 -TOTAL PROCESSING TIME: 0.0028 - 23:07:19.263596 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203093436 - time=1750907239.401346 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:19.401476 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:19.401575 -LOCATION: [terminal: 'Terminal'] - 23:07:19.401659 -CONSUME: True Is release for last non-modifier keyevent - 23:07:19.401681 -TOTAL PROCESSING TIME: 0.0003 - 23:07:19.401701 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203094756 - time=1750907240.721348 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:20.721470 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:20.721557 -LOCATION: [terminal: 'Terminal'] - 23:07:20.721628 -CONSUME: True Script indication - 23:07:20.721644 -DEFAULT: Interrupting presentation - 23:07:20.721653 -TOTAL PROCESSING TIME: 0.0004 - 23:07:20.721757 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:20.722821 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:20.722831 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:20.722934 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:20.722948 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:20.723038 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:20.724585 -SPEECH: Last spoke 1.4618 seconds ago - 23:07:20.724688 -SPEECH: Speak 'after Emit Signal: setup-inputeventhandlers-completed - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:20.724700 -SPEECH OUTPUT: 'after Emit Signal: setup-inputeventhandlers-completed - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:20.724723 -SPEECH DISPATCHER: Speaking ' after Emit Signal: setup-inputeventhandlers-completed - ' as string - 23:07:20.724740 -SPEECH DISPATCHER: Speaking 'after Emit Signal: setup-inputeventhandlers-completed - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:20.724958 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:20.725231 -BRAILLE: update review disabled - 23:07:20.725266 -TOTAL PROCESSING TIME: 0.0025 - 23:07:20.725274 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203094906 - time=1750907240.871286 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:20.871386 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:20.871472 -LOCATION: [terminal: 'Terminal'] - 23:07:20.871545 -CONSUME: True Is release for last non-modifier keyevent - 23:07:20.871562 -TOTAL PROCESSING TIME: 0.0003 - 23:07:20.871580 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203094981 - time=1750907240.946104 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:20.946216 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:20.946304 -LOCATION: [terminal: 'Terminal'] - 23:07:20.946383 -CONSUME: True Script indication - 23:07:20.946398 -DEFAULT: Interrupting presentation - 23:07:20.946406 -TOTAL PROCESSING TIME: 0.0004 - 23:07:20.946507 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:20.947570 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:20.947578 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:20.947668 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:20.947680 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:20.947760 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:20.949155 -SPEECH: Last spoke 0.2246 seconds ago - 23:07:20.949267 -SPEECH: Speak 'after Emit Signal: setup-inputeventhandlers-completed - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:20.949279 -SPEECH OUTPUT: 'after Emit Signal: setup-inputeventhandlers-completed - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:20.949303 -SPEECH DISPATCHER: Speaking ' after Emit Signal: setup-inputeventhandlers-completed - ' as string - 23:07:20.949320 -SPEECH DISPATCHER: Speaking 'after Emit Signal: setup-inputeventhandlers-completed - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:20.949543 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:20.949863 -BRAILLE: update review disabled - 23:07:20.949897 -TOTAL PROCESSING TIME: 0.0023 - 23:07:20.949906 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203095116 - time=1750907241.081033 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:21.081137 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:21.081223 -LOCATION: [terminal: 'Terminal'] - 23:07:21.081295 -CONSUME: True Is release for last non-modifier keyevent - 23:07:21.081312 -TOTAL PROCESSING TIME: 0.0003 - 23:07:21.081327 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203095251 - time=1750907241.216080 - keyType=unknown - clickCount=3 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:21.216197 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:21.216296 -LOCATION: [terminal: 'Terminal'] - 23:07:21.216385 -CONSUME: True Script indication - 23:07:21.216405 -DEFAULT: Interrupting presentation - 23:07:21.216415 -TOTAL PROCESSING TIME: 0.0004 - 23:07:21.216515 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:21.217575 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:21.217584 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:21.217672 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:21.217684 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:21.217759 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:21.219130 -SPEECH: Last spoke 0.2700 seconds ago - 23:07:21.219237 -SPEECH: Speak 'after Emit Signal: setup-inputeventhandlers-completed - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:21.219249 -SPEECH OUTPUT: 'after Emit Signal: setup-inputeventhandlers-completed - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:21.219271 -SPEECH DISPATCHER: Speaking ' after Emit Signal: setup-inputeventhandlers-completed - ' as string - 23:07:21.219288 -SPEECH DISPATCHER: Speaking 'after Emit Signal: setup-inputeventhandlers-completed - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:21.219518 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:21.219798 -BRAILLE: update review disabled - 23:07:21.219833 -TOTAL PROCESSING TIME: 0.0023 - 23:07:21.219842 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203095431 - time=1750907241.396096 - keyType=unknown - clickCount=3 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:21.396200 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:21.396289 -LOCATION: [terminal: 'Terminal'] - 23:07:21.396367 -CONSUME: True Is release for last non-modifier keyevent - 23:07:21.396384 -TOTAL PROCESSING TIME: 0.0003 - 23:07:21.396398 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203095544 - time=1750907241.509004 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:21.509097 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:21.509196 -LOCATION: [terminal: 'Terminal'] - 23:07:21.509294 -CONSUME: True Script indication - 23:07:21.509312 -DEFAULT: Interrupting presentation - 23:07:21.509320 -TOTAL PROCESSING TIME: 0.0004 - 23:07:21.509416 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:21.510479 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:21.510488 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:21.510580 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:21.510591 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:21.510667 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:21.511816 -SPEECH: Last spoke 0.2927 seconds ago - 23:07:21.511910 -SPEECH: Speak 'after Emit Signal: start-application-completed - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:21.511921 -SPEECH OUTPUT: 'after Emit Signal: start-application-completed - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:21.511943 -SPEECH DISPATCHER: Speaking ' after Emit Signal: start-application-completed - ' as string - 23:07:21.511961 -SPEECH DISPATCHER: Speaking 'after Emit Signal: start-application-completed - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:21.512184 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:21.512447 -BRAILLE: update review disabled - 23:07:21.512480 -TOTAL PROCESSING TIME: 0.0020 - 23:07:21.512489 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203095701 - time=1750907241.666088 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:21.666218 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:21.666321 -LOCATION: [terminal: 'Terminal'] - 23:07:21.666399 -CONSUME: True Is release for last non-modifier keyevent - 23:07:21.666416 -TOTAL PROCESSING TIME: 0.0003 - 23:07:21.666431 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203095814 - time=1750907241.778988 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:21.779109 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:21.779198 -LOCATION: [terminal: 'Terminal'] - 23:07:21.779275 -CONSUME: True Script indication - 23:07:21.779292 -DEFAULT: Interrupting presentation - 23:07:21.779300 -TOTAL PROCESSING TIME: 0.0004 - 23:07:21.779391 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:21.780453 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:21.780462 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:21.780547 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:21.780559 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:21.780634 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:21.781896 -SPEECH: Last spoke 0.2701 seconds ago - 23:07:21.781982 -SPEECH: Speak 'after Emit Signal: load-setting-completed - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:21.781994 -SPEECH OUTPUT: 'after Emit Signal: load-setting-completed - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:21.782017 -SPEECH DISPATCHER: Speaking ' after Emit Signal: load-setting-completed - ' as string - 23:07:21.782035 -SPEECH DISPATCHER: Speaking 'after Emit Signal: load-setting-completed - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:21.782250 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:21.782518 -BRAILLE: update review disabled - 23:07:21.782558 -TOTAL PROCESSING TIME: 0.0021 - 23:07:21.782567 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203095964 - time=1750907241.929214 - keyType=unknown - clickCount=2 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:21.929318 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:21.929404 -LOCATION: [terminal: 'Terminal'] - 23:07:21.929477 -CONSUME: True Is release for last non-modifier keyevent - 23:07:21.929495 -TOTAL PROCESSING TIME: 0.0003 - 23:07:21.929513 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65438 - hw_code=90 - modifiers=256 - event_string=(KP_Insert) - keyval_name=(KP_Insert) - timestamp=203096421 - time=1750907242.386252 - keyType=modifier - clickCount=0 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Insert' (90) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:22.386364 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:22.386459 -LOCATION: [terminal: 'Terminal'] - 23:07:22.386541 -CONSUME: True Cthulhu modifier - 23:07:22.386561 -DEFAULT: Interrupting presentation - 23:07:22.386571 -TOTAL PROCESSING TIME: 0.0004 - 23:07:22.386667 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Insert' (90) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65434 - hw_code=81 - modifiers=256 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203096579 - time=1750907242.544087 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:22.544201 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:22.544294 -LOCATION: [terminal: 'Terminal'] - 23:07:22.544376 -CONSUME: True Script indication - 23:07:22.544394 -DEFAULT: Interrupting presentation - 23:07:22.544402 -TOTAL PROCESSING TIME: 0.0004 - 23:07:22.544483 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -INFO: Handler is Move flat review to the end position - 23:07:22.545546 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:22.545557 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:22.545645 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:22.552719 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:22.552805 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:22.553850 -SPEECH: Last spoke 0.7720 seconds ago - 23:07:22.553963 -SPEECH: Speak '[storm@fenrir src] $ sudo ./fenrir - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:22.553979 -SPEECH OUTPUT: '[storm@fenrir src] $ sudo ./fenrir - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:22.554006 -SPEECH DISPATCHER: Speaking ' [storm@fenrir src] $ sudo./fenrir - ' as string - 23:07:22.554027 -SPEECH DISPATCHER: Speaking '[storm@fenrir src] $ sudo ./fenrir - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:22.554265 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:22.554552 -BRAILLE: update review disabled - 23:07:22.554592 -TOTAL PROCESSING TIME: 0.0091 - 23:07:22.554604 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65438 - hw_code=90 - modifiers=0 - event_string=(KP_Insert) - keyval_name=(KP_Insert) - timestamp=203096721 - time=1750907242.686244 - keyType=modifier - clickCount=0 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Insert' (90) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:22.686360 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:22.686457 -LOCATION: [terminal: 'Terminal'] - 23:07:22.686540 -CONSUME: True Cthulhu modifier - 23:07:22.686560 -TOTAL PROCESSING TIME: 0.0003 - 23:07:22.686579 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Insert' (90) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203096729 - time=1750907242.693783 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:22.693878 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:22.693962 -LOCATION: [terminal: 'Terminal'] - 23:07:22.694040 -CONSUME: True Script indication - 23:07:22.694059 -TOTAL PROCESSING TIME: 0.0003 - 23:07:22.694074 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203096931 - time=1750907242.896194 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:22.896294 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:22.896376 -LOCATION: [terminal: 'Terminal'] - 23:07:22.896446 -CONSUME: True Script indication - 23:07:22.896463 -DEFAULT: Interrupting presentation - 23:07:22.896470 -TOTAL PROCESSING TIME: 0.0004 - 23:07:22.896580 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) vvvvv -INFO: Handler is Move flat review to the beginning of the previous line - 23:07:22.897642 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:22.897651 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:22.897737 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:22.897749 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:22.897823 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:22.899665 -SPEECH: Last spoke 0.3458 seconds ago - 23:07:22.899787 -SPEECH: Speak '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:22.899799 -SPEECH OUTPUT: '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:22.899822 -SPEECH DISPATCHER: Speaking ' [storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' as string - 23:07:22.899840 -SPEECH DISPATCHER: Speaking '[storm@fenrir src] $ sudo rm /tmp/fenrir_860417_2025-06-25_14-47-36.log - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:22.900065 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:22.900367 -BRAILLE: update review disabled - 23:07:22.900400 -TOTAL PROCESSING TIME: 0.0028 - 23:07:22.900409 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Home' (79) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65429 - hw_code=79 - modifiers=0 - event_string=(KP_Home) - keyval_name=(KP_Home) - timestamp=203097066 - time=1750907243.031547 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:23.031668 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:23.031766 -LOCATION: [terminal: 'Terminal'] - 23:07:23.031874 -CONSUME: True Is release for last non-modifier keyevent - 23:07:23.031905 -TOTAL PROCESSING TIME: 0.0004 - 23:07:23.031929 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Home' (79) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203097389 - time=1750907243.354225 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:23.354347 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:23.354447 -LOCATION: [terminal: 'Terminal'] - 23:07:23.354532 -CONSUME: True Script indication - 23:07:23.354553 -DEFAULT: Interrupting presentation - 23:07:23.354563 -TOTAL PROCESSING TIME: 0.0004 - 23:07:23.354683 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -vvvvv CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) vvvvv -INFO: Handler is Move flat review to the beginning of the next line - 23:07:23.355768 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:23.355784 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:23.355903 -FLAT REVIEW PRESENTER: Using existing context. Restrict: False - 23:07:23.355920 -CTHULHU: Active mode: flat-review Object of interest: [terminal: 'Terminal'] - 23:07:23.356020 -SPEECH GENERATOR: None voice requested with language='None', dialect='' - 23:07:23.357185 -SPEECH: Last spoke 0.4575 seconds ago - 23:07:23.357269 -SPEECH: Speak '[storm@fenrir src] $ sudo ./fenrir - ' acss: [{'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'lang': 'en', 'dialect': '', 'variant': 'none'}}] - 23:07:23.357280 -SPEECH OUTPUT: '[storm@fenrir src] $ sudo ./fenrir - ' {'established': True, 'rate': 85.0, 'average-pitch': 4.5, 'gain': 5.0, 'family': {'name': 'Lyubov', 'gender': None, 'lang': 'en', 'dialect': '', 'variant': 'none'}} - 23:07:23.357302 -SPEECH DISPATCHER: Speaking ' [storm@fenrir src] $ sudo./fenrir - ' as string - 23:07:23.357319 -SPEECH DISPATCHER: Speaking '[storm@fenrir src] $ sudo ./fenrir - ' - CTHULHU rate 85.0, pitch 4.5, volume 5.0, language en, punctuation: MOST - SD rate 72, pitch 0, volume 40, language en - 23:07:23.357521 -CTHULHU: Region of interest: [terminal: 'Terminal'] ( 0) 0 - 23:07:23.357782 -BRAILLE: update review disabled - 23:07:23.357816 -TOTAL PROCESSING TIME: 0.0021 - 23:07:23.357826 -^^^^^ CONSUME ATSPI_KEY_PRESSED_EVENT: 'KP_Page_Up' (81) ^^^^^ - -KEYBOARD_EVENT: type=ATSPI_KEY_RELEASED_EVENT - id=65434 - hw_code=81 - modifiers=0 - event_string=(KP_Page_Up) - keyval_name=(KP_Page_Up) - timestamp=203097539 - time=1750907243.504161 - keyType=unknown - clickCount=1 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:23.504273 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:23.504356 -LOCATION: [terminal: 'Terminal'] - 23:07:23.504429 -CONSUME: True Is release for last non-modifier keyevent - 23:07:23.504446 -TOTAL PROCESSING TIME: 0.0003 - 23:07:23.504463 -^^^^^ PROCESS ATSPI_KEY_RELEASED_EVENT: 'KP_Page_Up' (81) ^^^^^ - - -KEYBOARD_EVENT: type=ATSPI_KEY_PRESSED_EVENT - id=65438 - hw_code=90 - modifiers=256 - event_string=(KP_Insert) - keyval_name=(KP_Insert) - timestamp=203098821 - time=1750907244.786484 - keyType=modifier - clickCount=0 - shouldEcho=False - - -vvvvv PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Insert' (90) vvvvv -HOST_APP: [application: 'lxterminal'] - 23:07:24.786601 -WINDOW: [frame: 'storm@fenrir:~/git/fenrir/src'] - 23:07:24.786698 -LOCATION: [terminal: 'Terminal'] - 23:07:24.786771 -CONSUME: True Cthulhu modifier - 23:07:24.786788 -DEFAULT: Interrupting presentation - 23:07:24.786796 -TOTAL PROCESSING TIME: 0.0004 - 23:07:24.786891 -^^^^^ PROCESS ATSPI_KEY_PRESSED_EVENT: 'KP_Insert' (90) ^^^^^ - -CTHULHU: Shutting down and exiting due to signal=15 (Terminated) - 23:07:24.890901 -CTHULHU: Shutting down - 23:07:24.890939 -CTHULHU: Shutting down D-Bus remote controller - 23:07:24.890946 \ No newline at end of file diff --git a/src/cthulhu/debug.py b/src/cthulhu/debug.py deleted file mode 100644 index 7c689df..0000000 --- a/src/cthulhu/debug.py +++ /dev/null @@ -1,701 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides debug utilities for Cthulhu. Debugging is managed by a debug -level, which is held in the debugLevel field. All other methods take -a debug level, which is compared to the current debug level to -determine if the content should be output.""" - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -import inspect -from contextlib import contextmanager -import traceback -import os -import re -import subprocess -import sys -import time -import types -from typing import Any, Generator, Mapping, Optional, TextIO, Pattern, TYPE_CHECKING -from datetime import datetime - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -if TYPE_CHECKING: - from .ax_object import AXObject as AXObjectType - -AXObject: Optional[type[AXObjectType]] = None - -def _get_ax_object() -> type[AXObjectType]: - global AXObject - if AXObject is None: - from .ax_object import AXObject as ax_object - AXObject = ax_object - return AXObject - -# Used to turn off all debugging. -# -LEVEL_OFF = 10000 - -# Used to describe events of considerable importance and which will prevent -# normal program execution. -# -LEVEL_SEVERE = 1000 - -# Used to describe events of interest to end users or system managers or which -# indicate potential problems, but which Cthulhu can deal with without crashing. -# -LEVEL_WARNING = 900 - -# Used to indicate reasonably significant messages that make sense to end users -# and system managers. -# -# For the purposes of Cthulhu, LEVEL_INFO means display the text being sent to -# speech and braille. -# -LEVEL_INFO = 800 - -# Used to indicate static configuration information to assist in debugging -# problems that may be associated with a particular configuration. -# -# For the purposes of Cthulhu, LEVEL_CONFIGURATION means display the various -# aspects of whether a particular feature (e.g., speech, braille, etc.) -# is enabled or not as well as details about that feature. -# -LEVEL_CONFIGURATION = 700 - -# Used for lowest volume of detailed tracing information. -# -# For the purposes of Cthulhu, this is braille and keyboard input, script -# activation and deletion, locus of focus changes, and visual changes -# to the locus of focus. -# -LEVEL_FINE = 600 - -# Used for medium volume of detailed tracing information. -# -# For the purposes of Cthulhu, this is for debugging speech and braille -# generators and tracking the synthesis of device events. -# -LEVEL_FINER = 500 - -# Used for maximum volume of detailed tracing information. -# -# For the purposes of Cthulhu, this is for tracking all AT-SPI object -# events. NOTE that one can up the debug level of AT-SPI object -# events by setting the eventDebugLevel. In addition, one can filter -# events by setting eventDebugFilter to a regular expression that -# matches event type names. -# -LEVEL_FINEST = 400 - -# Used for all detailed tracing information, even finer than LEVEL_FINEST -# -LEVEL_ALL = 0 - -debugLevel: int = LEVEL_SEVERE - -# The debug file. If this is not set, then all debug output is done -# via stdout. If this is set, then all debug output is sent to the -# file. This can be useful for debugging because one can pass in a -# non-buffered file to better track down hangs. -# -debugFile: Optional[TextIO] = None - -# The debug filter should be either None (which means to match all -# events) or a compiled regular expression from the 're' module (see -# http://www.amk.ca/python/howto/regex/). The regular expression will -# be used as a matching function - if the event type creates a match -# in the regular expression, then it will be considered for output. A -# typical call to this method might look like: -# -# debug.eventDebugFilter = rc.compile('focus:|window:activate') -# -eventDebugLevel: int = LEVEL_FINEST -eventDebugFilter: Optional[Pattern[str]] = None - -# If True, we output debug information for the event queue. We -# use this in addition to log level to prevent debug logic from -# bogging down event handling. -# -debugEventQueue: bool = False - -# Startup timing is intentionally separate from normal event tracing. When -# explicitly enabled, it can print concise phase timings without turning on the -# full debug stream. -startupTimingEnabled: bool = False -_startupTimingStartTime: Optional[float] = None -_startupTimingLastTime: Optional[float] = None - -# What module(s) should be traced if traceit is being used. By default -# we'll just attend to ourself. (And by default, we will not enable -# traceit.) Note that enabling this functionality will drag your system -# to a complete and utter halt and should only be used in extreme -# desperation by developers who are attempting to reproduce a very -# specific, immediate issue. Trust me. :-) Disabling braille monitor in -# this case is also strongly advised. -# -TRACE_MODULES: list[str] = ['cthulhu'] - -# Specific modules to ignore with traceit. -# -TRACE_IGNORE_MODULES: list[str] = ['traceback', 'linecache', 'locale', 'gettext', - 'logging', 'UserDict', 'encodings', 'posixpath', - 'genericpath', 're'] - -# Specific apps to trace with traceit. -# -TRACE_APPS: list[str] = [] - -# What AT-SPI event(s) should be traced if traceit is being used. By -# default, we'll trace everything. Examples of what you might wish to -# do to narrow things down include: -# -# TRACE_EVENTS = ['object:state-changed', 'focus:'] -# (for any and all object:state-changed events plus focus: events) -# TRACE_EVENTS = ['object:state-changed:selected'] -# (if you know the exact event type of interest) -# -TRACE_EVENTS: list[str] = [] - -# What role(s) should be traced if traceit is being used. By -# default, we'll trace everything. An example of what you might wish -# to do to narrow things down, if you know buttons trigger the problem: -# -# TRACE_ROLES = [Atspi.Role.PUSH_BUTTON, Atspi.Role.TOGGLE_BUTTON] -# -TRACE_ROLES: list[Atspi.Role] = [] - -# Whether or not traceit should only trace the work being done when -# processing an actual event. This is when most bad things happen. -# So we'll default to True. -# -TRACE_ONLY_PROCESSING_EVENTS: bool = True - -objEvent: Optional[Atspi.Event] = None - -def printException(level: int) -> None: - """Prints out information regarding the current exception. - - Arguments: - - level: the accepted debug level - """ - - if level >= debugLevel: - println(level) - traceback.print_exc(100, debugFile) - println(level) - -def printStack(level: int) -> None: - """Prints out the current stack. - - Arguments: - - level: the accepted debug level - """ - - if level >= debugLevel: - println(level) - traceback.print_stack(None, 100, debugFile) - println(level) - -def _asString(obj: Any) -> str: - AXObject = _get_ax_object() - if isinstance(obj, Atspi.Accessible): - result = AXObject.get_role_name(obj) - name = AXObject.get_name(obj) - if name: - result += f": '{name}'" - if not result: - result = "DEAD" - - return f"[{result}]" - - if isinstance(obj, Atspi.Event): - return ( - f"{obj.type} for {_asString(obj.source)} in " - f"{_asString(AXObject.get_application(obj.source))} " - f"({obj.detail1}, {obj.detail2}, {_asString(obj.any_data)})" - ) - - if isinstance(obj, (Atspi.Role, Atspi.StateType, Atspi.CollectionMatchType)): - return obj.value_nick - - if isinstance(obj, list): - return f"[{', '.join(map(_asString, obj))}]" - - if isinstance(obj, types.FunctionType): - if hasattr(obj, "__self__"): - return f"{obj.__module__}.{obj.__self__.__class__.__name__}.{obj.__name__}" - return f"{obj.__module__}.{obj.__name__}" - - if isinstance(obj, types.FrameType): - module_name = inspect.getmodulename(obj.f_code.co_filename) - return f"{module_name}.{obj.f_code.co_name}" - - if isinstance(obj, inspect.FrameInfo): - module_name = inspect.getmodulename(obj.filename) - return f"{module_name}.{obj.function}" - - return str(obj) - -def _format_tokens(tokens: list[Any]) -> str: - text = " ".join(map(_asString, tokens)) - text = re.sub(r"[ \u00A0]+", " ", text) - text = re.sub(r" (?=[,.:)])(?![\n])", "", text) - return text - -def format_log_message(prefix: str, message: str, reason: Optional[str] = None) -> str: - text = f"{prefix}: {message}" - if reason: - text = f"{text} (reason={reason})" - return text - -def print_log(level: int, prefix: str, message: str, reason: Optional[str] = None, - timestamp: bool = False, stack: bool = False) -> None: - text = format_log_message(prefix, message, reason) - printMessage(level, text, timestamp, stack) - -def print_log_tokens(level: int, prefix: str, tokens: list[Any], reason: Optional[str] = None, - timestamp: bool = False, stack: bool = False) -> None: - text = format_log_message(prefix, _format_tokens(tokens), reason) - printMessage(level, text, timestamp, stack) - -def format_runtime_state_snapshot(snapshot: Mapping[str, Any]) -> str: - """Formats read-only runtime state counters for debug capture.""" - - lines = ["CTHULHU RUNTIME STATE SNAPSHOT"] - for section, values in snapshot.items(): - lines.append(f"[{section}]") - if not isinstance(values, Mapping): - lines.append(f"value: {values}") - continue - for key in sorted(values): - lines.append(f"{key}: {values[key]}") - - return "\n".join(lines) - -def reset_startup_timing() -> None: - """Reset the startup timing baseline.""" - - global _startupTimingStartTime - global _startupTimingLastTime - - now = time.monotonic() - _startupTimingStartTime = now - _startupTimingLastTime = now - -def set_startup_timing_enabled(enabled: bool = True) -> None: - """Enable or disable concise startup phase timing output.""" - - global startupTimingEnabled - - startupTimingEnabled = enabled - if enabled and _startupTimingStartTime is None: - reset_startup_timing() - -def is_startup_timing_enabled() -> bool: - """Returns True when startup timing output should be emitted.""" - - return startupTimingEnabled or debugLevel <= LEVEL_INFO - -def _startup_timing_level() -> int: - if debugLevel <= LEVEL_INFO: - return LEVEL_INFO - return LEVEL_SEVERE - -def print_startup_timing(phase: str) -> None: - """Print elapsed startup timing for a named phase.""" - - global _startupTimingStartTime - global _startupTimingLastTime - - if not is_startup_timing_enabled(): - return - - now = time.monotonic() - if _startupTimingStartTime is None or _startupTimingLastTime is None: - _startupTimingStartTime = now - _startupTimingLastTime = now - - delta = now - _startupTimingLastTime - total = now - _startupTimingStartTime - _startupTimingLastTime = now - - text = f"STARTUP TIMING: {phase}: +{delta:.3f}s, total {total:.3f}s" - printMessage(_startup_timing_level(), text, True) - -@contextmanager -def startup_timing(phase: str) -> Generator[None, None, None]: - """Context manager for timing a startup phase.""" - - if not is_startup_timing_enabled(): - yield - return - - print_startup_timing(f"{phase} start") - try: - yield - finally: - print_startup_timing(f"{phase} end") - -def printTokens(level: int, tokens: list[Any], timestamp: bool = False, stack: bool = False) -> None: - if level < debugLevel: - return - - println(level, _format_tokens(tokens), timestamp, stack) - -def print_tokens(level: int, tokens: list[Any], timestamp: bool = False, stack: bool = False) -> None: - return printTokens(level, tokens, timestamp, stack) - -def printMessage(level: int, text: str, timestamp: bool = False, stack: bool = False) -> None: - if level < debugLevel: - return - - println(level, text, timestamp, stack) - -def print_message(level: int, text: str, timestamp: bool = False, stack: bool = False) -> None: - return printMessage(level, text, timestamp, stack) - -def _stackAsString(max_frames: int = 4) -> str: - callers = [] - current_module = inspect.getmodule(inspect.currentframe()) - stack = inspect.stack() - for i in range(1, len(stack)): - frame = stack[i] - module = inspect.getmodule(frame[0]) - if module == current_module: - continue - if frame.function == 'main': - continue - if module is None or module.__name__ is None: - continue - callers.append(frame) - if len(callers) >= max_frames: - break - - callers.reverse() - return " > ".join(map(_asString, callers)) - -def println(level: int, text: str = "", timestamp: bool = False, stack: bool = False) -> None: - """Prints the text to stderr unless debug is enabled. - - If debug is enabled the text will be redirected to the - file debugFile. - - Arguments: - - level: the accepted debug level - - text: the text to print (default is a blank line) - """ - - if level >= debugLevel: - text = text.replace("\ufffc", "[OBJ]") - if timestamp: - text = text.replace("\n", f"\n{' ' * 18}") - text = f"{text} - {datetime.now().strftime('%H:%M:%S.%f')}" - if stack: - text += f" {_stackAsString()}" - - if debugFile: - try: - debugFile.writelines([text, "\n"]) - debugFile.flush() - except TypeError: - text = "TypeError when trying to write text" - debugFile.writelines([text, "\n"]) - debugFile.flush() - except Exception: - text = "Exception when trying to write text" - debugFile.writelines([text, "\n"]) - debugFile.flush() - else: - try: - sys.stderr.writelines([text, "\n"]) - sys.stderr.flush() - except TypeError: - text = "TypeError when trying to write text" - sys.stderr.writelines([text, "\n"]) - sys.stderr.flush() - except Exception: - text = "Exception when trying to write text" - sys.stderr.writelines([text, "\n"]) - sys.stderr.flush() - -def printResult(level: int, result: Any = None) -> None: - """Prints the return result, along with information about the - method, arguments, and any errors encountered.""" - - if level < debugLevel: - return - - stack = inspect.stack() - current, prev = stack[1], stack[2] - frame = current[0] - - # To better print arguments which are accessible objects - args = inspect.getargvalues(frame) - for key, value in list(args.locals.items()): - args.locals[key] = str(value) - fArgs = str.replace(inspect.formatargvalues(*args), "'", "") - - callString = 'CALL: %s.%s (line %s) -> %s.%s%s' % ( - inspect.getmodulename(prev[1]), prev[3], prev[2], - inspect.getmodulename(current[1]), current[3], fArgs) - string = f'{callString}\nRESULT: {result}' - println(level, f'{string}') - -def printObjectEvent(level: int, event: Atspi.Event, sourceInfo: Optional[str] = None, - timestamp: bool = False) -> None: - """Prints out an Python Event object. The given level may be - overridden if the eventDebugLevel is greater. Furthermore, only - events with event types matching the eventDebugFilter regular - expression will be printed. - - Arguments: - - level: the accepted debug level - - event: the Python Event to print - - sourceInfo: additional string to print out - """ - - if eventDebugFilter and not eventDebugFilter.match(event.type): - return - - level = max(level, eventDebugLevel) - - anydata = event.any_data - if isinstance(anydata, str) and len(anydata) > 100: - anydata = f"{anydata[0:100]} (...)" - - text = "OBJECT EVENT: %s (%d, %d, %s)" \ - % (event.type, event.detail1, event.detail2, anydata) - println(level, text, timestamp) - - if sourceInfo: - println(level, f"{' ' * 18}{sourceInfo}", timestamp) - -def printInputEvent(level: int, string: str, timestamp: bool = False) -> None: - """Prints out an input event. The given level may be overridden - if the eventDebugLevel (see setEventDebugLevel) is greater. - - Arguments: - - level: the accepted debug level - - string: the string representing the input event - """ - - println(max(level, eventDebugLevel), string, timestamp) - -def printDetails(level: int, indent: str, accessible: Atspi.Accessible, - includeApp: bool = True, timestamp: bool = False) -> None: - """Lists the details of the given accessible with the given - indentation. - - Arguments: - - level: the accepted debug level - - indent: a string containing spaces for indentation - - accessible: the accessible whose details are to be listed - - includeApp: if True, include information about the app - """ - - if level >= debugLevel and accessible: - println(level, - getAccessibleDetails(level, accessible, indent, includeApp), - timestamp) - -def getAccessibleDetails(level: int, acc: Atspi.Accessible, indent: str = "", - includeApp: bool = True) -> str: - """Returns a string, suitable for printing, that describes the - given accessible. - - Arguments: - - indent: A string to prefix the output with - - includeApp: If True, include information about the app - for this accessible. - """ - - if level < debugLevel: - return "" - - from .ax_utilities_debugging import AXUtilitiesDebugging - return AXUtilitiesDebugging.object_details_as_string(acc, indent, includeApp) - -# The following code originated from the following URL: -# -# http://www.dalkescientific.com/writings/diary/archive/ \ -# 2005/04/20/tracing_python_code.html -# -import linecache - -def _getFileAndModule(frame: types.FrameType) -> tuple[Optional[str], Optional[str]]: - filename, module = None, None - try: - filename = frame.f_globals["__file__"] - module = frame.f_globals["__name__"] - except Exception: - pass - else: - if (filename.endswith(".pyc") or filename.endswith(".pyo")): - filename = filename[:-1] - - return filename, module - -def _shouldTraceIt() -> bool: - AXObject = _get_ax_object() - if not objEvent: - return not TRACE_ONLY_PROCESSING_EVENTS - - eventSource = objEvent.source - if TRACE_APPS: - app = AXObject.get_application(eventSource) - if AXObject.get_name(app) not in TRACE_APPS: - return False - - if TRACE_ROLES and AXObject.get_role(eventSource) not in TRACE_ROLES: - return False - - if TRACE_EVENTS and \ - not [x for x in map(objEvent.type.startswith, TRACE_EVENTS) if x]: - return False - - return True - -def traceit(frame: types.FrameType, event: str, arg: Any) -> Optional[object]: - """Line tracing utility to output all lines as they are executed by - the interpreter. This is to be used by sys.settrace and is for - debugging purposes. - - Arguments: - - frame: is the current stack frame - - event: 'call', 'line', 'return', 'exception', 'c_call', 'c_return', - or 'c_exception' - - arg: depends on the event type (see docs for sys.settrace) - """ - - if not _shouldTraceIt(): - return None - - filename, module = _getFileAndModule(frame) - if not (filename and module): - return traceit - if module in TRACE_IGNORE_MODULES: - return traceit - if TRACE_MODULES and module.split('.')[0] not in TRACE_MODULES: - return traceit - if event not in ['call', 'line', 'return']: - return traceit - - lineno = frame.f_lineno - line = linecache.getline(filename, lineno).rstrip() - output = f'TRACE {module}:{lineno}: {line}' - - if event == 'call': - argvals = inspect.getargvalues(frame) - keys = [x for x in argvals[0] if x != 'self'] - try: - values = list(map(argvals[3].get, keys)) - except TypeError: - if len(keys) == 1 and isinstance(keys[0], list): - values = list(map(argvals[3].get, keys[0])) - else: - return traceit - for i, key in enumerate(keys): - output += f'\n ARG {key}={values[i]}' - - lineElements = line.strip().split() - if lineElements and lineElements[0] == 'return': - if event == 'line': - return traceit - output = f'{output} (rv: {arg})' - - println(LEVEL_ALL, output) - - return traceit - -def getOpenFDCount(pid: int) -> int: - procs = subprocess.check_output([ 'lsof', '-w', '-Ff', '-p', str(pid)]) - procs = procs.decode('UTF-8').split('\n') - files = list(filter(lambda s: s and s[0] == 'f' and s[1:].isdigit(), procs)) - - return len(files) - -def getCmdline(pid: int) -> str: - try: - openFile = os.popen(f'cat /proc/{pid}/cmdline') - cmdline = openFile.read() - openFile.close() - except Exception: - cmdline = '(Could not obtain cmdline)' - cmdline = cmdline.replace('\x00', ' ') - - return cmdline - -def pidOf(procName: str) -> list[int]: - openFile = subprocess.Popen(f'pgrep {procName}', - shell=True, - stdout=subprocess.PIPE).stdout - pids = openFile.read() - openFile.close() - return [int(p) for p in pids.split()] - -def examineProcesses(force: bool = False) -> None: - AXObject = _get_ax_object() - from .ax_utilities import AXUtilities - if force: - level = LEVEL_OFF - else: - level = LEVEL_ALL - - desktop = AXUtilities.get_desktop() - println(level, 'INFO: Desktop has %i apps:' % AXObject.get_child_count(desktop), True) - for i, app in enumerate(AXObject.iter_children(desktop)): - pid = AXObject.get_process_id(app) - cmd = getCmdline(pid) - fds = getOpenFDCount(pid) - name = AXObject.get_name(app) - if name == '': - name = 'WARNING: Possible hang or dead app' - println(level, '%3i. %s (pid: %s) %s file descriptors: %i' \ - % (i+1, name, pid, cmd, fds), True) - - # Other 'suspect' processes which might not show up as accessible apps. - otherApps = ['apport'] - for app in otherApps: - pids = pidOf(app) - if not pids: - println(level, f'INFO: no pid for {app}', True) - continue - - for pid in pids: - cmd = getCmdline(pid) - fds = getOpenFDCount(pid) - println(level, 'INFO: %s (pid: %s) %s file descriptors: %i' \ - % (app, pid, cmd, fds), True) diff --git a/src/cthulhu/desktop_keyboardmap.py b/src/cthulhu/desktop_keyboardmap.py deleted file mode 100644 index 1ce694c..0000000 --- a/src/cthulhu/desktop_keyboardmap.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -""" A list of common keybindings and unbound keys - pulled out from default.py: __getDesktopBindings() - with the goal of being more readable and less monolithic. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs, Mesar Hameed." -__license__ = "LGPL" - -from . import keybindings - -# Storing values -defaultModifierMask = keybindings.defaultModifierMask -CTHULHU_MODIFIER_MASK = keybindings.CTHULHU_MODIFIER_MASK -NO_MODIFIER_MASK = keybindings.NO_MODIFIER_MASK -CTHULHU_SHIFT_MODIFIER_MASK = keybindings.CTHULHU_SHIFT_MODIFIER_MASK - -keymap = ( - - ("KP_Divide", defaultModifierMask, CTHULHU_MODIFIER_MASK, - "routePointerToItemHandler"), - - # We want the user to be able to combine modifiers with the - # mouse click (e.g. to Shift+Click and select), therefore we - # do not "care" about the modifiers -- unless it's the Cthulhu - # modifier. - # - ("KP_Divide", CTHULHU_MODIFIER_MASK, NO_MODIFIER_MASK, - "leftClickReviewItemHandler"), - - ("KP_Multiply", CTHULHU_MODIFIER_MASK, NO_MODIFIER_MASK, - "rightClickReviewItemHandler"), - - ("KP_Add", defaultModifierMask, NO_MODIFIER_MASK, - "sayAllHandler", 1), - - ("KP_Delete", defaultModifierMask, NO_MODIFIER_MASK, - "findHandler"), - - ("KP_Delete", defaultModifierMask, CTHULHU_MODIFIER_MASK, - "findNextHandler"), - - ("KP_Delete", defaultModifierMask, CTHULHU_SHIFT_MODIFIER_MASK, - "findPreviousHandler"), -) \ No newline at end of file diff --git a/src/cthulhu/dynamic_api_manager.py b/src/cthulhu/dynamic_api_manager.py deleted file mode 100644 index e9a7bb3..0000000 --- a/src/cthulhu/dynamic_api_manager.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import gi -from gi.repository import GObject - -from cthulhu import resource_manager - -class DynamicApiManager(): - def __init__(self, app): - self.app = app - self.resourceManager = self.app.getResourceManager() - self.api = {'Cthulhu': self.app} - def registerAPI(self, key, value, application = '', contextName = None, overwrite = False): - if not overwrite: - try: - d = self.api[application][key] - return - except KeyError: - pass - # add profile - try: - d = self.api[application] - except KeyError: - self.api[application]= {} - # add dynamic API - self.api[application][key] = value - resourceContext = self.resourceManager.getResourceContext(contextName) - if resourceContext: - resourceEntry = resource_manager.ResourceEntry('api', key, value, value, key) - resourceContext.addAPI(application, key, resourceEntry) - - def unregisterAPI(self, key, application = '', contextName = None): - ok = False - try: - del self.api[application][key] - ok = True - except: - print('API Key: "{}/{}" not found,'.format(application, key)) - resourceContext = self.resourceManager.getResourceContext(contextName) - if resourceContext: - resourceContext.removeAPI(application, key) - return ok - def getAPI(self, key, application = '', fallback = True): - # get dynamic API - api = None - - try: - api = self.api[application][key] - return api - except: - if not fallback: - print('API Key: "{}/{}" not found,'.format(application, key)) - return None - - # we already tried this - if application == '': - return api - - try: - api = self.api[application][''] - except: - print('API Key: "{}/{}" not found,'.format(application, key)) - - return api diff --git a/src/cthulhu/event_manager.py b/src/cthulhu/event_manager.py deleted file mode 100644 index a67506a..0000000 --- a/src/cthulhu/event_manager.py +++ /dev/null @@ -1,1994 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2011. Cthulhu Team." -__license__ = "LGPL" - -import gi -gi.require_version('Atspi', '2.0') -from gi.repository import Atspi -from gi.repository import GLib -import queue -import threading -import time -from typing import TYPE_CHECKING, Optional, Dict, List, Tuple, Any, Union - -from . import cthulhu -from . import braille -from . import debug -from . import focus_manager -from . import input_event -from . import input_event_manager -from . import cthulhu_state -from . import script_manager -from . import settings -from .ax_object import AXObject -from .ax_utilities import AXUtilities -from .compositor_state_types import ( - CompositorStateEvent, - DESKTOP_FOCUS_CONTEXT_CHANGED, - DESKTOP_TRANSITION_FINISHED, - DESKTOP_TRANSITION_STARTED, - FLUSH_STALE_ATSPI_EVENTS, - PAUSE_ATSPI_CHURN, - PRIORITIZE_FOCUS, - RESUME_ATSPI_CHURN, - WORKSPACE_STATE_CHANGED, -) - -if TYPE_CHECKING: - from .cthulhu import Cthulhu - from .script import Script - from .input_event_manager import InputEventManager - -class EventManager: - - EMBEDDED_OBJECT_CHARACTER: str = '\ufffc' - RELEVANCE_KEEP: str = "keep" - RELEVANCE_COLLAPSE: str = "collapse" - RELEVANCE_DROP: str = "drop" - - def __init__(self, app: Cthulhu, asyncMode: bool = True) -> None: - debug.printMessage(debug.LEVEL_INFO, 'EVENT MANAGER: Initializing', True) - debug.printMessage(debug.LEVEL_INFO, f'EVENT MANAGER: Async Mode is {asyncMode}', True) - self.app: Cthulhu = app - self._asyncMode: bool = asyncMode - self._scriptListenerCounts: Dict[str, int] = {} - self._active: bool = False - self._enqueueCount: int = 0 - self._dequeueCount: int = 0 - self._cmdlineCache: Dict[int, str] = {} - self._eventQueue: queue.Queue[Any] = queue.Queue(0) - self._prioritizedEvent: Optional[Atspi.Event] = None - self._gidleId: int = 0 - self._prioritizedIdleId: int = 0 - self._gidleLock: threading.Lock = threading.Lock() - self._gilSleepTime: float = 0.00001 - self._synchronousToolkits: List[str] = ['VCL'] - self._eventsSuspended: bool = False - self._listener: Atspi.EventListener = Atspi.EventListener.new(self._enqueue) - - # Note: These must match what the scripts registered for, otherwise - # Atspi might segfault. - # - # Events we don't want to suspend include: - # object:text-changed:insert - marco - # object:property-change:accessible-name - gnome-shell issue #6925 - self._suspendableEvents: List[str] = ['object:children-changed:add', - 'object:children-changed:remove', - 'object:state-changed:sensitive', - 'object:state-changed:showing', - 'object:text-changed:delete'] - self._eventsTriggeringSuspension: List[Atspi.Event] = [] - self._ignoredEvents: List[str] = ['object:bounds-changed', - 'object:state-changed:defunct', - 'object:property-change:accessible-parent'] - self._parentsOfDefunctDescendants: List[Atspi.Accessible] = [] - self._compositorStateAdapter: Optional[Any] = None - self._churnSuppressed: bool = cthulhu_state.pauseAtspiChurn - self._prioritizedContextToken: Optional[str] = cthulhu_state.prioritizedDesktopContextToken - self._desktopContextConfirmedEmpty: bool = False - self._flushingStaleAtspiEvents: bool = False - self._relevanceBurstWindow: float = 0.15 - self._relevanceBurstHistory: Dict[Tuple[str, str, str], float] = {} - - cthulhu_state.device = None - self._keyHandlingActive: bool = False - self._inputEventManager: Optional[InputEventManager] = None - - debug.printMessage(debug.LEVEL_INFO, 'Event manager initialized', True) - - def activate(self) -> None: - """Called when this event manager is activated.""" - - debug.printMessage(debug.LEVEL_INFO, 'EVENT MANAGER: Activating', True) - self._activateKeyHandling() - self._active = True - GLib.idle_add(self._sync_focus_on_startup) - debug.printMessage(debug.LEVEL_INFO, 'EVENT MANAGER: Activated', True) - - def _sync_focus_on_startup(self) -> bool: - """Initialize active window and focus when startup missed focus events.""" - - if cthulhu_state.screenLockActive: - return False - - focus = cthulhu_state.locusOfFocus - if focus and not AXObject.is_dead(focus): - return False - - window = cthulhu_state.activeWindow - if not AXUtilities.can_be_active_window(window, clear_cache=True): - window = AXUtilities.find_active_window() - if window is not None: - tokens = ["EVENT MANAGER: Setting initial active window to", window] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setActiveWindow(window, alsoSetLocusOfFocus=True, notifyScript=False) - - if window is None: - return False - - focused = AXUtilities.get_focused_object(window) - if focused is not None and focused != cthulhu_state.locusOfFocus: - cthulhu.setLocusOfFocus(None, focused, notifyScript=True, force=True) - elif cthulhu_state.locusOfFocus is None: - cthulhu.setLocusOfFocus(None, window, notifyScript=True, force=True) - - if getattr(self, "_compositorStateAdapter", None) is not None: - self._compositorStateAdapter.sync_accessible_context("event-manager-startup") - - return False - - def _activateKeyHandling(self) -> None: - """Activates keyboard handling using InputEventManager with Atspi.Device.""" - - if self._keyHandlingActive: - return - - debug.printMessage(debug.LEVEL_INFO, 'EVENT MANAGER: Activating keyboard handling', True) - self._inputEventManager = input_event_manager.get_manager() - self._inputEventManager.set_compositor_state_adapter(self._compositorStateAdapter) - self._inputEventManager.start_key_watcher() - cthulhu_state.device = self._inputEventManager._device - self._keyHandlingActive = True - debug.printMessage(debug.LEVEL_INFO, 'EVENT MANAGER: Keyboard handling activated', True) - - def _deactivateKeyHandling(self) -> None: - """Deactivates keyboard handling.""" - - if not self._keyHandlingActive: - return - - debug.printMessage(debug.LEVEL_INFO, 'EVENT MANAGER: Deactivating keyboard handling', True) - if self._inputEventManager: - self._inputEventManager.stop_key_watcher() - cthulhu_state.device = None - self._keyHandlingActive = False - debug.printMessage(debug.LEVEL_INFO, 'EVENT MANAGER: Keyboard handling deactivated', True) - - def deactivate(self) -> None: - """Called when this event manager is deactivated.""" - - debug.printMessage(debug.LEVEL_INFO, 'EVENT MANAGER: Deactivating', True) - self._active = False - self._eventQueue = queue.Queue(0) - self._scriptListenerCounts = {} - self._deactivateKeyHandling() - debug.printMessage(debug.LEVEL_INFO, 'EVENT MANAGER: Deactivated', True) - - def get_debug_snapshot(self) -> Dict[str, object]: - """Returns read-only counters useful for long-uptime diagnostics.""" - - return { - "active": self._active, - "async_mode": self._asyncMode, - "event_queue_size": self._eventQueue.qsize(), - "prioritized_event_present": self._prioritizedEvent is not None, - "idle_source_id": self._gidleId, - "prioritized_idle_source_id": self._prioritizedIdleId, - "events_suspended": self._eventsSuspended, - "suspendable_event_types": len(self._suspendableEvents), - "events_triggering_suspension": len(self._eventsTriggeringSuspension), - "ignored_event_types": len(self._ignoredEvents), - "script_listener_types": len(self._scriptListenerCounts), - "parents_of_defunct_descendants": len(self._parentsOfDefunctDescendants), - "cmdline_cache_size": len(self._cmdlineCache), - "relevance_burst_history_size": len(self._relevanceBurstHistory), - "churn_suppressed": self._churnSuppressed, - "prioritized_context_token_present": self._prioritizedContextToken is not None, - "key_handling_active": self._keyHandlingActive, - "input_event_manager_present": self._inputEventManager is not None, - "screen_lock_active": cthulhu_state.screenLockActive, - } - - def set_screen_lock_active(self, active: bool, schedule_focus_resync: bool = True) -> None: - """Isolates screen-reader state while I38Lock owns secure input.""" - - if cthulhu_state.screenLockActive == active: - return - - cthulhu_state.screenLockActive = active - reason = ( - "I38Lock secure screen lock active" - if active - else "I38Lock secure screen lock released" - ) - input_event_manager.get_manager().set_secure_input_active(active, reason) - self._discard_queued_events_for_screen_lock() - - active_script = self.app.scriptManager.get_active_script() - if active and active_script is not None: - active_script.presentationInterrupt() - if active: - braille.clear() - - self.app.scriptManager.set_active_script(None, reason) - manager = focus_manager.get_manager() - if manager is not None: - manager.clear_state(reason) - cthulhu_state.pendingSelfHostedFocus = None - - if not active and schedule_focus_resync: - GLib.idle_add(self._sync_focus_on_startup) - - def _discard_queued_events_for_screen_lock(self) -> None: - """Drops queued accessibility events at both lock-state boundaries.""" - - self._gidleLock.acquire() - try: - self._eventQueue = queue.Queue(0) - self._prioritizedEvent = None - finally: - self._gidleLock.release() - - def set_compositor_state_adapter(self, adapter: Any) -> None: - """Stores the compositor state adapter used for startup wiring.""" - - if self._compositorStateAdapter is adapter: - return - - if self._compositorStateAdapter is not None and hasattr(self._compositorStateAdapter, "remove_listener"): - self._compositorStateAdapter.remove_listener(self._handle_compositor_signal) - - self._compositorStateAdapter = adapter - if self._inputEventManager is not None: - self._inputEventManager.set_compositor_state_adapter(adapter) - if adapter is not None and hasattr(adapter, "add_listener"): - adapter.add_listener(self._handle_compositor_signal) - - def _handle_compositor_signal(self, signal: CompositorStateEvent) -> None: - """Updates churn suppression state from compositor normalization signals.""" - - snapshot = signal.snapshot - signalType = signal.type - contextToken = getattr(signal, "context_token", None) - if contextToken is None and signal.payload: - contextToken = signal.payload.get("context_token") - if contextToken is None and snapshot is not None: - contextToken = snapshot.active_window_token or snapshot.locus_of_focus_token or None - if snapshot is not None: - snapshotToken = snapshot.active_window_token or snapshot.locus_of_focus_token or "" - if not contextToken: - contextToken = snapshotToken or None - - if signalType in (WORKSPACE_STATE_CHANGED, DESKTOP_TRANSITION_FINISHED): - self._update_i3_workspace_context(snapshot) - - if signalType in (DESKTOP_FOCUS_CONTEXT_CHANGED, PRIORITIZE_FOCUS): - self._prioritizedContextToken = contextToken - cthulhu_state.prioritizedDesktopContextToken = contextToken - return - - if signalType in (PAUSE_ATSPI_CHURN, DESKTOP_TRANSITION_STARTED): - self._churnSuppressed = True - cthulhu_state.pauseAtspiChurn = True - if contextToken: - self._prioritizedContextToken = contextToken - cthulhu_state.prioritizedDesktopContextToken = contextToken - return - - if signalType in (RESUME_ATSPI_CHURN, DESKTOP_TRANSITION_FINISHED): - self._churnSuppressed = False - cthulhu_state.pauseAtspiChurn = False - if contextToken: - self._prioritizedContextToken = contextToken - cthulhu_state.prioritizedDesktopContextToken = contextToken - if signalType == DESKTOP_TRANSITION_FINISHED: - self._flush_stale_atspi_events() - return - - if signalType == FLUSH_STALE_ATSPI_EVENTS: - self._flush_stale_atspi_events() - - def _update_i3_workspace_context(self, snapshot: Any) -> None: - """Clears stale accessible state when i3 confirms a blank workspace.""" - - if snapshot is None or snapshot.backend_name != "i3-ipc": - return - - workspaceEmpty = snapshot.focused_workspace_empty - if workspaceEmpty is None: - return - - if not workspaceEmpty: - if self._desktopContextConfirmedEmpty: - self._desktopContextConfirmedEmpty = False - GLib.idle_add(self._sync_focus_on_startup) - return - - if self._desktopContextConfirmedEmpty: - return - - self._desktopContextConfirmedEmpty = True - activeScript = self.app.scriptManager.get_active_script() - if activeScript is not None: - activeScript.presentationInterrupt() - - manager = focus_manager.get_manager() - if manager is not None: - manager.clear_state("confirmed empty i3 workspace") - cthulhu_state.pendingSelfHostedFocus = None - self._prioritizedContextToken = None - cthulhu_state.prioritizedDesktopContextToken = None - - defaultScript = self.app.scriptManager.get_default_script() - self.app.scriptManager.set_active_script( - defaultScript, - "focus: confirmed-empty-i3-workspace", - ) - - def ignoreEventTypes(self, eventTypeList: List[str]) -> None: - for eventType in eventTypeList: - if eventType not in self._ignoredEvents: - self._ignoredEvents.append(eventType) - - def unignoreEventTypes(self, eventTypeList: List[str]) -> None: - for eventType in eventTypeList: - if eventType in self._ignoredEvents: - self._ignoredEvents.remove(eventType) - - def _isDuplicateEvent(self, event: Atspi.Event) -> bool: - """Returns True if this event is already in the event queue.""" - - if self._inFlood() and self._prioritizeDuringFlood(event): - return False - - def isSame(x: Any) -> bool: - return x.type == event.type \ - and x.source == event.source \ - and x.detail1 == event.detail1 \ - and x.detail2 == event.detail2 \ - and x.any_data == event.any_data - - for e in self._eventQueue.queue: - if isSame(e): - return True - - return False - - def _getAppCmdline(self, app: Atspi.Accessible) -> str: - pid = AXObject.get_process_id(app) - if pid == -1: - return "" - - cmdline = self._cmdlineCache.get(pid) - if cmdline is None: - cmdline = debug.getCmdline(pid) - self._cmdlineCache[pid] = cmdline - return cmdline - - def _isSteamApp(self, app: Atspi.Accessible) -> bool: - name = AXObject.get_name(app) - if not name: - nameLower = "" - else: - nameLower = name.lower() - - if "steamwebhelper" in nameLower or nameLower in ("steam", "steam web helper"): - return True - - cmdline = self._getAppCmdline(app) - return "steamwebhelper" in cmdline - - def _isSteamNotificationEvent(self, event: Atspi.Event) -> bool: - return self._isLiveOrNotificationEvent(event) - - def _isSteamOverlayNavigationEvent(self, event: Atspi.Event, app: Atspi.Accessible) -> bool: - if not self._isSteamApp(app): - return False - - if not event.type.startswith(( - "object:property-change:accessible-name", - "object:active-descendant-changed", - )): - return False - - if not self._activeX11WindowIsSteamSelectionContext(): - return False - - return self._eventHasSteamQuickAccessContext(event) - - def _eventHasSteamQuickAccessContext(self, event: Atspi.Event) -> bool: - for obj in (event.source, getattr(event, "any_data", None)): - if obj is None or isinstance(obj, (str, bytes, int, float, bool)): - continue - try: - if self._hasSteamQuickAccessMarker(obj): - return True - except Exception: - continue - - return False - - @staticmethod - def _hasSteamQuickAccessMarker(obj: Any) -> bool: - def hasMarker(candidate: Any) -> bool: - if candidate is None: - return False - - name = AXObject.get_name(candidate) or "" - if name.startswith("QuickAccess_uid"): - return True - - accessibleId = AXObject.get_attribute(candidate, "id") or "" - if accessibleId.startswith("quickaccess_"): - return True - - className = AXObject.get_attribute(candidate, "class") or "" - return "quickaccess" in className.casefold() - - return AXObject.find_ancestor_inclusive(obj, hasMarker) is not None - - def _activeX11WindowIsSteamSelectionContext(self) -> bool: - window = input_event_manager.get_manager()._get_active_x11_window() - return self._x11WindowHasSteamGameClass(window) or self._x11WindowIsSteamBigPicture(window) - - @classmethod - def _x11WindowHasSteamGameClass(cls, window: Any) -> bool: - if window is None: - return False - - identifiers = [ - cls._safeSteamWindowCall(window, "get_class_group_name"), - cls._safeSteamWindowCall(window, "get_class_instance_name"), - ] - classGroup = cls._safeSteamWindowCall(window, "get_class_group") - if classGroup is not None: - identifiers.extend([ - cls._safeSteamWindowCall(classGroup, "get_name"), - cls._safeSteamWindowCall(classGroup, "get_res_class"), - ]) - - return any(cls._isSteamGameWindowIdentifier(identifier) for identifier in identifiers) - - @classmethod - def _x11WindowIsSteamBigPicture(cls, window: Any) -> bool: - if window is None: - return False - - name = cls._safeSteamWindowCall(window, "get_name") - if not isinstance(name, str) or name.strip() != "Steam Big Picture Mode": - return False - - identifiers = [ - cls._safeSteamWindowCall(window, "get_class_group_name"), - cls._safeSteamWindowCall(window, "get_class_instance_name"), - ] - classGroup = cls._safeSteamWindowCall(window, "get_class_group") - if classGroup is not None: - identifiers.extend([ - cls._safeSteamWindowCall(classGroup, "get_name"), - cls._safeSteamWindowCall(classGroup, "get_res_class"), - ]) - - normalized = { - identifier.strip().casefold() - for identifier in identifiers - if isinstance(identifier, str) - } - return bool(normalized.intersection({"steam", "steamwebhelper"})) - - @staticmethod - def _safeSteamWindowCall(window: Any, attrName: str): - attr = getattr(window, attrName, None) - if not callable(attr): - return None - - try: - return attr() - except Exception: - return None - - @staticmethod - def _isSteamGameWindowIdentifier(identifier: Any) -> bool: - if not isinstance(identifier, str): - return False - return identifier.strip().casefold().startswith("steam_app_") - - def _isLiveOrNotificationObject(self, obj: Any) -> bool: - if obj is None or isinstance(obj, (str, bytes, int, float, bool)): - return False - - try: - if AXUtilities.is_notification(obj) or AXUtilities.is_alert(obj): - return True - except Exception: - pass - - try: - liveAttr = AXObject.get_attribute(obj, 'live') - containerLive = AXObject.get_attribute(obj, 'container-live') - except Exception: - return isinstance(obj, Atspi.Accessible) - - if liveAttr in ('assertive', 'polite') or containerLive in ('assertive', 'polite'): - return True - - return False - - def _isLiveOrNotificationEvent(self, event: Atspi.Event) -> bool: - for obj in (event.any_data, event.source): - if self._isLiveOrNotificationObject(obj): - return True - - return False - - def _isPhaseOneWebRole(self, role: Atspi.Role) -> bool: - return role in ( - Atspi.Role.LINK, - Atspi.Role.PUSH_BUTTON, - Atspi.Role.CHECK_BOX, - Atspi.Role.RADIO_BUTTON, - Atspi.Role.LIST_ITEM, - Atspi.Role.LIST, - Atspi.Role.SECTION, - ) - - def _eventTouchesCurrentFocusContext(self, event: Atspi.Event) -> bool: - locusOfFocus = cthulhu_state.locusOfFocus - if locusOfFocus is None: - return False - - if event.source in (locusOfFocus, getattr(event, "any_data", None)): - return True - - focused = getattr(cthulhu_state, "pendingSelfHostedFocus", None) - if focused is not None and event.source in (focused, getattr(event, "any_data", None)): - return True - - return False - - def _shouldPreserveForRelevanceGate(self, event: Atspi.Event) -> bool: - if event.type.startswith("window"): - return True - - if event.type.startswith("mouse:button"): - return True - - if event.type.startswith("object:state-changed:focused") and event.detail1: - return True - - if self._eventTouchesCurrentFocusContext(event): - return True - - return self._isLiveOrNotificationEvent(event) - - def _eventRoleForRelevance(self, event: Atspi.Event) -> Optional[Atspi.Role]: - try: - return AXObject.get_role(event.source) - except Exception: - return None - - def _appNameForRelevance(self, app: Atspi.Accessible) -> str: - try: - appName = AXObject.get_name(app) - except Exception: - return "" - - return (appName or "").strip().lower() - - def _relevanceEventGroup(self, event: Atspi.Event, role: Atspi.Role) -> Optional[str]: - if event.type.startswith("object:children-changed:") and self._isPhaseOneWebRole(role): - return "children-changed" - - if event.type.startswith("object:property-change:accessible-name") and self._isPhaseOneWebRole(role): - return "accessible-name" - - return None - - def _classifyRelevance(self, event: Atspi.Event, app: Atspi.Accessible) -> str: - if self._shouldPreserveForRelevanceGate(event): - return self.RELEVANCE_KEEP - - if event.type.startswith("object:state-changed:focused"): - if event.detail1 or cthulhu_state.locusOfFocus is None: - return self.RELEVANCE_KEEP - if self._eventTouchesCurrentFocusContext(event): - return self.RELEVANCE_KEEP - return self.RELEVANCE_DROP - - role = self._eventRoleForRelevance(event) - eventGroup = self._relevanceEventGroup(event, role) - if eventGroup is None: - return self.RELEVANCE_KEEP - - if event.type.startswith("object:property-change:accessible-name") \ - and self._isPhaseOneWebRole(role): - try: - focused = AXUtilities.is_focused(event.source) - except Exception: - focused = False - if not focused: - return self.RELEVANCE_DROP - - if self._isBurstRelevanceEvent(event, app, eventGroup): - return self.RELEVANCE_COLLAPSE - - return self.RELEVANCE_KEEP - - def _isBurstRelevanceEvent( - self, - event: Atspi.Event, - app: Atspi.Accessible, - eventGroup: Optional[str] = None, - ) -> bool: - if self._shouldPreserveForRelevanceGate(event): - return False - - if eventGroup is None: - role = self._eventRoleForRelevance(event) - eventGroup = self._relevanceEventGroup(event, role) - - if eventGroup is None: - return False - - appName = self._appNameForRelevance(app) or "unknown-app" - try: - contextKey = self._context_token_for_event(event) - except Exception: - contextKey = None - contextKey = contextKey or f"source:{id(event.source)}" - burstKey = (appName, eventGroup, contextKey) - now = time.monotonic() - lastSeen = self._relevanceBurstHistory.get(burstKey) - self._relevanceBurstHistory[burstKey] = now - return lastSeen is not None and (now - lastSeen) < self._relevanceBurstWindow - - def _isSteamBurstChurnEvent(self, event: Atspi.Event, app: Atspi.Accessible) -> bool: - if not self._isSteamApp(app) or self._isLiveOrNotificationEvent(event): - return False - - if event.type.startswith("object:state-changed:focused"): - return not event.detail1 - - if event.type.startswith("object:children-changed:"): - return self._isBurstRelevanceEvent(event, app, "children-changed") - - return False - - def _ignore(self, event: Atspi.Event) -> bool: - """Returns True if this event should be ignored.""" - - if cthulhu_state.screenLockActive: - debug.print_log( - debug.LEVEL_INFO, - "EVENT MANAGER", - "Ignoring - secure screen lock is active", - "screen-lock-active", - True, - ) - return True - - app = AXObject.get_application(event.source) - debug.printMessage(debug.LEVEL_INFO, '') - tokens = ["EVENT MANAGER:", event.type, "from", app] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - def _log_ignore(reason: str, message: str) -> None: - debug.print_log(debug.LEVEL_INFO, "EVENT MANAGER", - f"Ignoring - {message}", reason, True) - - def _log_allow(reason: str, message: str) -> None: - debug.print_log(debug.LEVEL_INFO, "EVENT MANAGER", - f"Not ignoring - {message}", reason, True) - - def _ignore_with_reason(reason: str, message: str) -> bool: - _log_ignore(reason, message) - return True - - def _allow_with_reason(reason: str, message: str) -> bool: - _log_allow(reason, message) - return False - - if self._eventsSuspended: - tokens = ["EVENT MANAGER: Suspended events:", ', '.join(self._suspendableEvents)] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not self._active: - return _ignore_with_reason("inactive", "event manager is not active") - - if list(filter(event.type.startswith, self._ignoredEvents)): - return _ignore_with_reason("type-ignored", "event type is ignored") - - if AXObject.get_name(app) == 'gnome-shell': - if event.type.startswith('object:children-changed:remove'): - return _ignore_with_reason("gnome-shell", "children-changed:remove") - - if event.type.startswith('window'): - return _allow_with_reason("window-event", "event type is never ignored") - - if event.type.startswith('mouse:button'): - return _allow_with_reason("mouse-event", "event type is never ignored") - - if self._is_obsolete_by_context(event): - return _ignore_with_reason("compositor-stale-context", "event is from a stale compositor context") - - if self._churnSuppressed and not self._should_preserve_during_suppression(event): - return _ignore_with_reason("compositor-churn-paused", "event is suppressed during compositor churn") - - if self._isDuplicateEvent(event): - return _ignore_with_reason("duplicate", "duplicate event") - - if self._isSelfHostedFocusClearedEvent(event): - return _ignore_with_reason("self-hosted-focus-cleared", "self-hosted focused=false event") - - if self._isRedundantSelfHostedPropertyEvent(event): - return _ignore_with_reason("self-hosted-redundant-property", "self-hosted redundant property event") - - # Thunderbird spams us with these when a message list thread is expanded or collapsed. - if event.type.endswith('system') \ - and AXObject.get_name(app).lower().startswith('thunderbird'): - if AXUtilities.is_table_related(event.source) \ - or AXUtilities.is_tree_related(event.source) \ - or AXUtilities.is_section(event.source): - return _ignore_with_reason("thunderbird-system", "system event based on role") - - if self._inDeluge() and self._ignoreDuringDeluge(event): - return _ignore_with_reason("deluge", "event type during deluge") - - isSteamOverlayNavigationEvent = self._isSteamOverlayNavigationEvent(event, app) - script = cthulhu_state.activeScript - if event.type.startswith('object:children-changed') \ - or event.type.startswith('object:state-changed:sensitive'): - if not script: - if isSteamOverlayNavigationEvent: - _log_allow("steam-overlay-navigation", "no active script") - else: - return _ignore_with_reason("no-active-script", "no active script") - elif script.app != app: - # Allow Steam notifications from inactive apps. - if self._isSteamApp(app) and self._isSteamNotificationEvent(event): - _log_allow("steam-notification", "inactive app notification") - elif isSteamOverlayNavigationEvent: - _log_allow("steam-overlay-navigation", "inactive app overlay navigation") - else: - return _ignore_with_reason("inactive-app", "event not from active app") - - if isSteamOverlayNavigationEvent: - return _allow_with_reason("steam-overlay-navigation", "Steam overlay navigation event") - - relevance = self._classifyRelevance(event, app) - if relevance == self.RELEVANCE_DROP: - return _ignore_with_reason("event-relevance-drop", "event is background churn") - if relevance == self.RELEVANCE_COLLAPSE: - return _ignore_with_reason("event-relevance-collapse", "event was collapsed by relevance gate") - - if self._isSteamBurstChurnEvent(event, app): - return _ignore_with_reason("steam-burst-churn", "event is low-value Steam churn") - - if event.type.startswith('object:text-changed') \ - and self.EMBEDDED_OBJECT_CHARACTER in event.any_data \ - and not event.any_data.replace(self.EMBEDDED_OBJECT_CHARACTER, ""): - # We should also get children-changed events telling us the same thing. - # Getting a bunch of both can result in a flood that grinds us to a halt. - return _ignore_with_reason("embedded-only", "changed text only embedded objects") - - # TODO - JD: For now we won't ask for the name. Simply asking for the name should - # not break anything, and should be a reliable way to quickly identify defunct - # objects. But apparently the mere act of asking for the name causes Cthulhu to stop - # presenting Eclipse (and possibly other) applications. This might be an AT-SPI2 - # issue, but until we know for certain.... - #name = Atspi.Accessible.get_name(event.source) - - if AXUtilities.has_no_state(event.source): - return _ignore_with_reason("empty-state", "empty state set") - - if AXUtilities.is_defunct(event.source): - return _ignore_with_reason("defunct-source", "defunct source") - - role = AXObject.get_role(event.source) - if event.type.startswith('object:property-change:accessible-name'): - if role in [Atspi.Role.CANVAS, - Atspi.Role.ICON, - Atspi.Role.LIST_ITEM, # Web app spam - Atspi.Role.LIST, # Web app spam - Atspi.Role.PANEL, # TeamTalk5 spam - Atspi.Role.SECTION, # Web app spam - Atspi.Role.TABLE_ROW, # Thunderbird spam - Atspi.Role.TABLE_CELL, # Thunderbird spam - Atspi.Role.TREE_ITEM, # Thunderbird spam - Atspi.Role.IMAGE, # Thunderbird spam - Atspi.Role.MENU, - Atspi.Role.MENU_ITEM]: - return _ignore_with_reason("name-change-role", "role filtered") - # TeamTalk5 is notoriously spammy here, and name change events on widgets are - # typically only presented if they are focused. - if not AXUtilities.is_focused(event.source) \ - and role in [Atspi.Role.PUSH_BUTTON, - Atspi.Role.CHECK_BOX, - Atspi.Role.RADIO_BUTTON]: - return _ignore_with_reason("name-change-unfocused", "role and state") - elif event.type.startswith('object:property-change:accessible-value'): - if role == Atspi.Role.SPLIT_PANE and not AXUtilities.is_focused(event.source): - return _ignore_with_reason("value-change-unfocused", "role and state") - elif event.type.startswith('object:text-changed:insert') and event.detail2 > 1000 \ - and role in [Atspi.Role.TEXT, Atspi.Role.STATIC]: - return _ignore_with_reason("text-insert-large", "inserted text > 1000 chars") - elif event.type.startswith('object:state-changed:sensitive'): - if role in [Atspi.Role.MENU_ITEM, - Atspi.Role.MENU, - Atspi.Role.FILLER, - Atspi.Role.PANEL, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.RADIO_MENU_ITEM]: - return _ignore_with_reason("sensitive-role", "role filtered") - elif event.type.startswith('object:state-changed:selected'): - if not event.detail1 and role in [Atspi.Role.PUSH_BUTTON]: - return _ignore_with_reason("selected-button-false", "role and detail1") - elif event.type.startswith('object:state-changed:showing'): - if role not in [Atspi.Role.ALERT, - Atspi.Role.ANIMATION, - Atspi.Role.INFO_BAR, - Atspi.Role.MENU, - Atspi.Role.NOTIFICATION, - Atspi.Role.DIALOG, - Atspi.Role.STATUS_BAR, - Atspi.Role.TOOL_TIP]: - return _ignore_with_reason("showing-role", "role filtered") - - elif event.type.startswith('object:text-caret-moved'): - if role in [Atspi.Role.LABEL] and not AXUtilities.is_focused(event.source): - return _ignore_with_reason("caret-unfocused-label", "role and state") - - elif event.type.startswith('object:selection-changed'): - if event.source in self._parentsOfDefunctDescendants: - return _ignore_with_reason("defunct-descendant-parent", "parent of defunct descendants") - - if AXObject.is_dead(event.source): - return _ignore_with_reason("dead-source", "dead source") - - if event.type.startswith('object:children-changed') \ - or event.type.startswith('object:active-descendant-changed'): - if role in [Atspi.Role.MENU, - Atspi.Role.LAYERED_PANE, - Atspi.Role.MENU_ITEM]: - return _ignore_with_reason("children-role", "role filtered") - if event.any_data is None: - return _ignore_with_reason("missing-any-data", "no event.any_data") - if event.type.endswith('remove'): - if event.any_data == cthulhu_state.locusOfFocus: - msg = 'EVENT MANAGER: Locus of focus is being destroyed' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if AXObject.is_dead(cthulhu_state.locusOfFocus): - msg = 'EVENT MANAGER: Locus of focus is dead.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - tokens = ["EVENT MANAGER: Locus of focus:", cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - elif event.any_data == cthulhu_state.locusOfFocus: - msg = 'EVENT MANAGER: Locus of focus is being added.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - elif event.any_data == cthulhu_state.pendingSelfHostedFocus: - msg = 'EVENT MANAGER: Pending self-hosted focus is being added.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - elif self._eventsSuspended: - if event.type.endswith('add') and not self._eventTypeIsSuspended(event.type): - # Cthulhu is known to miss text insertion in Gtk3 when text insertions - # are suspended. So while we do need to suspend some of the resulting - # events, we also need to make sure the text insertion isn't suspended. - if AXUtilities.is_text(event.any_data): - return _ignore_with_reason("suspended-text", "child text is not suspended") - elif not self._eventTypeIsSuspended(event.type): - return _ignore_with_reason("suspended-event-type", "event type is not suspended") - - return False - - def _addToQueue(self, event: Any, asyncMode: bool) -> bool: - debugging = debug.debugEventQueue - if debugging: - debug.printMessage(debug.LEVEL_ALL, " acquiring lock...") - - with self._gidleLock: - effectiveAsyncMode = asyncMode or self._flushingStaleAtspiEvents - if debugging: - debug.printMessage(debug.LEVEL_ALL, " ...acquired") - debug.printMessage(debug.LEVEL_ALL, " calling queue.put...") - debug.printMessage(debug.LEVEL_ALL, " (full=%s)" \ - % self._eventQueue.full()) - - self._eventQueue.put(event) - if debugging: - debug.printMessage(debug.LEVEL_ALL, " ...put complete") - - if effectiveAsyncMode and not self._gidleId: - if self._gilSleepTime: - time.sleep(self._gilSleepTime) - self._gidleId = GLib.idle_add(self._dequeue) - - if debug.debugEventQueue: - debug.printMessage(debug.LEVEL_ALL, " releasing lock...") - debug.printMessage(debug.LEVEL_ALL, " ...released") - return effectiveAsyncMode - - def _queuePrintln(self, e: Any, isEnqueue: bool = True, isPrune: Optional[bool] = None) -> None: - """Convenience method to output queue-related debugging info.""" - - if debug.LEVEL_INFO < debug.debugLevel: - return - - tokens = [] - if isinstance(e, input_event.KeyboardEvent): - tokens.extend([e.event_string, e.hw_code]) - elif isinstance(e, input_event.BrailleEvent): - tokens.append(e.event) - elif not debug.eventDebugFilter or debug.eventDebugFilter.match(e.type): - tokens.append(e) - else: - return - - if isPrune: - tokens[0:0] = ["EVENT MANAGER: Pruning"] - elif isPrune is not None: - tokens[0:0] = ["EVENT MANAGER: Not pruning"] - elif isEnqueue: - tokens[0:0] = ["EVENT MANAGER: Queueing"] - else: - tokens[0:0] = ["EVENT MANAGER: Dequeued"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - def _suspendEvents(self, triggeringEvent: Atspi.Event) -> None: - self._eventsTriggeringSuspension.append(triggeringEvent) - - if self._eventsSuspended: - msg = "EVENT MANAGER: Events already suspended." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - msg = "EVENT MANAGER: Suspending events." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - for event in self._suspendableEvents: - self.deregisterListener(event) - - self._eventsSuspended = True - - def _unsuspendEvents(self, triggeringEvent: Atspi.Event, force: bool = False) -> None: - if triggeringEvent in self._eventsTriggeringSuspension: - self._eventsTriggeringSuspension.remove(triggeringEvent) - - if not self._eventsSuspended: - msg = "EVENT MANAGER: Events already unsuspended." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self._eventsTriggeringSuspension and not force: - msg = "EVENT MANAGER: Events are suspended for another event." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - msg = "EVENT MANAGER: Unsuspending events." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - for event in self._suspendableEvents: - self.registerListener(event) - - self._eventsSuspended = False - - def _shouldSuspendEventsFor(self, event: Atspi.Event) -> bool: - if AXUtilities.is_frame(event.source) \ - or (AXUtilities.is_window(event.source) \ - and AXUtilities.get_application_toolkit_name(event.source) == "clutter"): - if event.type.startswith("window"): - msg = "EVENT MANAGER: Should suspend events for window event." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - if event.type.endswith("active"): - msg = "EVENT MANAGER: Should suspend events for active event on window." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - if AXUtilities.is_document(event.source): - if event.type.endswith("busy") and event.detail1: - msg = "EVENT MANAGER: Should suspend events for busy:true event on document." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def _shouldUnsuspendEventsFor(self, event: Atspi.Event) -> bool: - if event.type.startswith("object:state-changed:focused") and event.detail1: - msg = "EVENT MANAGER: Should unsuspend events for newly-focused object." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if AXUtilities.is_document(event.source): - if event.type.endswith("busy") and not event.detail1: - msg = "EVENT MANAGER: Should unsuspend events for busy:false event on document." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - if event.type.startswith("document:load-complete"): - msg = "EVENT MANAGER: Should unsuspend events for load-complete event on document." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def _didSuspendEventsFor(self, event: Atspi.Event) -> bool: - return event in self._eventsTriggeringSuspension - - def _enqueue(self, e: Atspi.Event) -> None: - """Handles the enqueueing of all events destined for scripts. - - Arguments: - - e: an at-spi event. - """ - - if cthulhu_state.screenLockActive: - msg = "EVENT MANAGER: Dropping event during secure screen lock." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if debug.debugEventQueue: - if self._enqueueCount: - msg = f"EVENT MANAGER: _enqueue entered before exiting (count={self._enqueueCount})" - debug.printMessage(debug.LEVEL_ALL, msg, True) - self._enqueueCount += 1 - - inputEvents = (input_event.KeyboardEvent, input_event.BrailleEvent) - isObjectEvent = not isinstance(e, inputEvents) - - try: - ignore = isObjectEvent and self._ignore(e) - except Exception as error: - tokens = ["EVENT MANAGER: Exception evaluating event:", e, ":", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - ignore = True - if ignore: - if debug.debugEventQueue: - self._enqueueCount -= 1 - return - - if isObjectEvent and self._prioritizeSelfHostedFocusedEvent(e): - if debug.debugEventQueue: - self._enqueueCount -= 1 - return - - self._queuePrintln(e) - - if self._inFlood() and self._prioritizeDuringFlood(e): - msg = 'EVENT MANAGER: Pruning event queue due to flood.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._pruneEventsDuringFlood() - - if isObjectEvent and self._shouldSuspendEventsFor(e): - self._suspendEvents(e) - - asyncMode = self._asyncMode - if isObjectEvent: - if isinstance(e, input_event.MouseButtonEvent): - asyncMode = True - elif AXUtilities.get_application_toolkit_name(e.source) in self._synchronousToolkits: - asyncMode = False - elif e.type.startswith("object:children-changed"): - asyncMode = AXUtilities.is_table(e.source) - elif AXUtilities.is_notification(e.source): - # To decrease the likelihood that the popup will be destroyed before we - # have its contents. - asyncMode = False - script = cthulhu.cthulhuApp.scriptManager.get_script(AXObject.get_application(e.source), e.source) - script.eventCache[e.type] = (e, time.time()) - - asyncMode = self._addToQueue(e, asyncMode) - if not asyncMode: - self._dequeue() - - if debug.debugEventQueue: - self._enqueueCount -= 1 - - def _isSelfHostedFocusedEvent(self, event: Atspi.Event) -> bool: - """Returns True if the event is a newly-focused event from Cthulhu.""" - - if not event.type.startswith("object:state-changed:focused") or not event.detail1: - return False - - app = AXObject.get_application(event.source) - appName = (AXObject.get_name(app) or "").lower() - return appName == "cthulhu" - - def _isSelfHostedFocusClearedEvent(self, event: Atspi.Event) -> bool: - """Returns True if the event is a focus-lost event from Cthulhu.""" - - if not event.type.startswith("object:state-changed:focused") or event.detail1: - return False - - app = AXObject.get_application(event.source) - appName = (AXObject.get_name(app) or "").lower() - return appName == "cthulhu" - - def _isRedundantSelfHostedPropertyEvent(self, event: Atspi.Event) -> bool: - """Returns True if the event is redundant prefs startup noise from Cthulhu.""" - - app = AXObject.get_application(event.source) - appName = (AXObject.get_name(app) or "").lower() - if appName != "cthulhu": - return False - - if event.type.startswith("object:property-change:accessible-name"): - return AXUtilities.is_combo_box(event.source) or AXUtilities.is_table_cell(event.source) - - if event.type.startswith("object:property-change:accessible-value"): - return AXObject.get_role(event.source) == Atspi.Role.SLIDER \ - and event.source != cthulhu_state.locusOfFocus - - return False - - def _prioritizeSelfHostedFocusedEvent(self, event: Atspi.Event) -> bool: - """Schedules the latest focused-child event from Cthulhu ahead of the normal queue.""" - - if not self._isSelfHostedFocusedEvent(event): - return False - - tokens = ["EVENT MANAGER: Prioritizing self-hosted focused event for", event.source] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - script = self._get_scriptForEvent(event) - if script is not None: - script.eventCache[event.type] = (event, time.time()) - - self._gidleLock.acquire() - try: - replaced = self._prioritizedEvent is not None - self._prioritizedEvent = event - cthulhu_state.pendingSelfHostedFocus = event.source - if not self._prioritizedIdleId: - self._prioritizedIdleId = GLib.idle_add( - self._dequeuePrioritizedEvent, - priority=GLib.PRIORITY_HIGH_IDLE, - ) - finally: - self._gidleLock.release() - - msg = f"EVENT MANAGER: Prioritized self-hosted focused event. Replaced pending event: {replaced}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - return True - def _isNoFocus(self) -> bool: - if cthulhu_state.locusOfFocus or cthulhu_state.activeWindow or cthulhu_state.activeScript: - return False - - msg = 'EVENT MANAGER: No focus' - debug.printMessage(debug.LEVEL_SEVERE, msg, True) - return True - - def _onNoFocus(self) -> bool: - if cthulhu_state.screenLockActive: - return False - - if not self._isNoFocus(): - return False - - defaultScript = cthulhu.cthulhuApp.scriptManager.get_default_script() - cthulhu.cthulhuApp.scriptManager.set_active_script(defaultScript, 'focus: none') - defaultScript.idleMessage() - return False - - def _dequeuePrioritizedEvent(self) -> bool: - """Handles prioritized focused events from Cthulhu-owned windows.""" - - self._gidleLock.acquire() - try: - event = self._prioritizedEvent - self._prioritizedEvent = None - self._prioritizedIdleId = 0 - if event is not None and cthulhu_state.pendingSelfHostedFocus == event.source: - cthulhu_state.pendingSelfHostedFocus = None - finally: - self._gidleLock.release() - - if event is None: - return False - - tokens = ["EVENT MANAGER: Dequeued prioritized event", event] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - debugging = not debug.eventDebugFilter or debug.eventDebugFilter.match(event.type) - if debugging: - startTime = time.time() - msg = ( - f"\nvvvvv PROCESS OBJECT EVENT {event.type} " - f"(prioritized) vvvvv" - ) - debug.printMessage(debug.eventDebugLevel, msg, False) - - try: - self._processObjectEvent(event) - if self._didSuspendEventsFor(event): - self._unsuspendEvents(event) - elif self._eventsSuspended and self._shouldUnsuspendEventsFor(event): - self._unsuspendEvents(event, force=True) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - if debugging: - msg = ( - f"TOTAL PROCESSING TIME: {time.time() - startTime:.4f}" - f"\n^^^^^ PROCESS OBJECT EVENT {event.type} ^^^^^\n" - ) - debug.printMessage(debug.eventDebugLevel, msg, False) - - self._gidleLock.acquire() - try: - hasMore = self._prioritizedEvent is not None - if not hasMore and self._eventQueue.qsize() and not self._gidleId: - self._gidleId = GLib.idle_add(self._dequeue) - finally: - self._gidleLock.release() - - return hasMore - - def _dequeue(self) -> bool: - """Handles all events destined for scripts. Called by the GTK - idle thread.""" - - rerun = True - - if debug.debugEventQueue: - msg = f"EVENT MANAGER: Dequeue {self._dequeueCount}" - debug.printMessage(debug.LEVEL_ALL, msg, True) - self._dequeueCount += 1 - - try: - fromPriority = False - self._gidleLock.acquire() - try: - event = self._eventQueue.get_nowait() - finally: - self._gidleLock.release() - - self._queuePrintln(event, isEnqueue=False) - inputEvents = (input_event.KeyboardEvent, input_event.BrailleEvent) - if isinstance(event, inputEvents): - self._processInputEvent(event) - else: - debug.objEvent = event - debugging = not debug.eventDebugFilter \ - or debug.eventDebugFilter.match(event.type) - if debugging: - startTime = time.time() - msg = ( - f"\nvvvvv PROCESS OBJECT EVENT {event.type} " - f"(queue size: {self._eventQueue.qsize()}) vvvvv" - ) - debug.printMessage(debug.eventDebugLevel, msg, False) - self._processObjectEvent(event) - if self._didSuspendEventsFor(event): - self._unsuspendEvents(event) - elif self._eventsSuspended and self._shouldUnsuspendEventsFor(event): - self._unsuspendEvents(event, force=True) - - if debugging: - msg = ( - f"TOTAL PROCESSING TIME: {time.time() - startTime:.4f}" - f"\n^^^^^ PROCESS OBJECT EVENT {event.type} ^^^^^\n" - ) - debug.printMessage(debug.eventDebugLevel, msg, False) - - debug.objEvent = None - - self._gidleLock.acquire() - if self._eventQueue.empty(): - GLib.timeout_add(2500, self._onNoFocus) - self._gidleId = 0 - rerun = False # destroy and don't call again - self._gidleLock.release() - except queue.Empty: - msg = 'EVENT MANAGER: Attempted dequeue, but the event queue is empty' - debug.printMessage(debug.LEVEL_SEVERE, msg, True) - self._gidleId = 0 - rerun = False # destroy and don't call again - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - if debug.debugEventQueue: - self._dequeueCount -= 1 - msg = f"EVENT MANAGER: Leaving _dequeue. Count: {self._dequeueCount}" - debug.printMessage(debug.LEVEL_ALL, msg, True) - - return rerun - - def registerListener(self, eventType: str) -> None: - """Tells this module to listen for the given event type. - - Arguments: - - eventType: the event type. - """ - - msg = f'EVENT MANAGER: registering listener for: {eventType}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if eventType in self._scriptListenerCounts: - self._scriptListenerCounts[eventType] += 1 - else: - self._listener.register(eventType) - self._scriptListenerCounts[eventType] = 1 - - def deregisterListener(self, eventType: str) -> None: - """Tells this module to stop listening for the given event type. - - Arguments: - - eventType: the event type. - """ - - msg = f'EVENT MANAGER: deregistering listener for: {eventType}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if eventType not in self._scriptListenerCounts: - return - - self._scriptListenerCounts[eventType] -= 1 - if self._scriptListenerCounts[eventType] == 0: - self._listener.deregister(eventType) - del self._scriptListenerCounts[eventType] - - def registerScriptListeners(self, script: Script) -> None: - """Tells the event manager to start listening for all the event types - of interest to the script. - - Arguments: - - script: the script. - """ - - tokens = ["EVENT MANAGER: Registering listeners for:", script] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - for eventType in script.listeners.keys(): - self.registerListener(eventType) - - def deregisterScriptListeners(self, script: Script) -> None: - """Tells the event manager to stop listening for all the event types - of interest to the script. - - Arguments: - - script: the script. - """ - - tokens = ["EVENT MANAGER: De-registering listeners for:", script] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - for eventType in script.listeners.keys(): - self.deregisterListener(eventType) - - def _processInputEvent(self, event: Any) -> None: - """Processes the given input event based on the keybinding from the - currently-active script. - - Arguments: - - event: an instance of BrailleEvent or a KeyboardEvent - """ - - if cthulhu_state.screenLockActive or not cthulhu_state.activeScript: - return - - if not isinstance(event, input_event.BrailleEvent): - return - - data = f"'{repr(event.event)}'" - eType = str(event.type).upper() - startTime = time.time() - - msg = f"\nvvvvv PROCESS {eType} {data} vvvvv" - debug.printMessage(debug.eventDebugLevel, msg, False) - - try: - cthulhu_state.activeScript.processBrailleEvent(event) - except Exception as error: - tokens = ["EVENT MANAGER: Exception processing event:", error] - debug.printTokens(debug.LEVEL_WARNING, tokens, True) - - msg = ( - f"TOTAL PROCESSING TIME: {time.time() - startTime:.4f}" - f"^^^^^ PROCESS {eType} {data} ^^^^^\n" - ) - debug.printMessage(debug.eventDebugLevel, msg, False) - - @staticmethod - def _get_scriptForEvent(event: Any) -> Optional[Script]: - """Returns the script associated with event.""" - - if event.type.startswith("mouse:"): - return cthulhu.cthulhuApp.scriptManager.get_script_for_mouse_button_event(event) - - script = None - app = AXObject.get_application(event.source) - if AXUtilities.is_defunct(app): - tokens = ["EVENT MANAGER:", app, "is defunct. Cannot get script for event."] - debug.printTokens(debug.LEVEL_WARNING, tokens, True) - return None - - skipCheck = { - "object:children-changed", - "object:column-reordered", - "object:row-reordered", - "object:property-change", - "object:selection-changed", - "object:state-changed:checked", - "object:state-changed:expanded", - "object:state-changed:indeterminate", - "object:state-changed:pressed", - "object:state-changed:selected", - "object:state-changed:sensitive", - "object:state-changed:showing", - "object:text-changed", - } - - check = not any(event.type.startswith(x) for x in skipCheck) - tokens = ["EVENT MANAGER: Getting script for", app, "check:", check] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - script = cthulhu.cthulhuApp.scriptManager.get_script(app, event.source, sanity_check=check) - tokens = ["EVENT MANAGER: Script is ", script] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return script - - def _isActivatableEvent(self, event: Atspi.Event, script: Optional[Script] = None) -> Tuple[bool, str]: - """Determines if the event is one which should cause us to - change which script is currently active. - - Returns a (boolean, string) tuple indicating whether or not - this is an activatable event, and our reason (for the purpose - of debugging). - """ - - if not event.source: - return False, "event.source? What event.source??" - - if not script: - script = self._get_scriptForEvent(event) - if not script: - return False, "There is no script for this event." - - prioritizedContextToken = self._prioritizedContextToken or cthulhu_state.prioritizedDesktopContextToken - if self._churnSuppressed and prioritizedContextToken: - eventToken = self._context_token_for_event(event) - if eventToken not in (None, prioritizedContextToken): - return False, "Event context does not match compositor-prioritized context." - - if script == cthulhu_state.activeScript: - return False, "The script for this event is already active." - - if not script.isActivatableEvent(event): - return False, "The script says not to activate for this event." - - if cthulhu_state.activeScript is None: - active_window = cthulhu_state.activeWindow - if AXUtilities.is_focused(event.source): - return True, "No active script and event source is focused." - if active_window and AXObject.is_ancestor(event.source, active_window, inclusive=True): - return True, "No active script and event is in active window." - if AXUtilities.is_frame(event.source) or AXUtilities.is_window(event.source): - return True, "No active script and event source is window/frame." - - if script.forceScriptActivation(event): - return True, "The script insists it should be activated for this event." - - eType = event.type - - if eType.startswith('window:activate'): - windowActivation = True - else: - windowActivation = eType.startswith('object:state-changed:active') \ - and event.detail1 and AXUtilities.is_frame(event.source) - - if windowActivation: - if event.source != cthulhu_state.activeWindow: - return True, "Window activation" - else: - return False, "Window activation for already-active window" - - if eType.startswith('focus') \ - or (eType.startswith('object:state-changed:focused') - and event.detail1): - return True, "Event source claimed focus." - - if eType.startswith('object:state-changed:selected') and event.detail1 \ - and AXUtilities.is_menu(event.source) and AXUtilities.is_focusable(event.source): - return True, "Selection change in focused menu" - - # This condition appears with gnome-screensaver-dialog. - # See bug 530368. - if eType.startswith('object:state-changed:showing') \ - and AXUtilities.is_panel(event.source) and AXUtilities.is_modal(event.source): - return True, "Modal panel is showing." - - return False, "No reason found to activate a different script." - - def _eventSourceIsDead(self, event: Atspi.Event) -> bool: - if AXObject.is_dead(event.source): - tokens = ["EVENT MANAGER: source of", event.type, "is dead"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - def _ignoreDuringDeluge(self, event: Atspi.Event) -> bool: - """Returns true if this event should be ignored during a deluge.""" - - if self._eventSourceIsDead(event): - return True - - ignore = ["object:text-changed:delete", - "object:text-changed:insert", - "object:text-changed:delete:system", - "object:text-changed:insert:system", - "object:text-attributes-changed", - "object:text-caret-moved", - "object:children-changed:add", - "object:children-changed:add:system", - "object:children-changed:remove", - "object:children-changed:remove:system", - "object:property-change:accessible-name", - "object:property-change:accessible-description", - "object:selection-changed", - "object:state-changed:showing", - "object:state-changed:sensitive"] - - if event.type not in ignore: - return False - - return event.source != cthulhu_state.locusOfFocus - - def _inDeluge(self) -> bool: - size = self._eventQueue.qsize() - if size > 100: - msg = f"EVENT MANAGER: DELUGE! Queue size is {size}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def _processDuringFlood(self, event: Atspi.Event) -> bool: - """Returns true if this event should be processed during a flood.""" - - if self._eventSourceIsDead(event): - return False - - ignore = ["object:text-changed:delete", - "object:text-changed:insert", - "object:text-changed:delete:system", - "object:text-changed:insert:system", - "object:text-attributes-changed", - "object:text-caret-moved", - "object:children-changed:add", - "object:children-changed:add:system", - "object:children-changed:remove", - "object:children-changed:remove:system", - "object:property-change:accessible-name", - "object:property-change:accessible-description", - "object:selection-changed", - "object:state-changed:showing", - "object:state-changed:sensitive"] - - if event.type not in ignore: - return True - - return event.source == cthulhu_state.locusOfFocus - - def _prioritizeDuringFlood(self, event: Atspi.Event) -> bool: - """Returns true if this event should be prioritized during a flood.""" - - if event.type.startswith("object:state-changed:focused"): - return event.detail1 - - if event.type.startswith("object:state-changed:selected"): - return event.detail1 - - if event.type.startswith("object:text-selection-changed"): - return True - - if event.type.startswith("window:activate"): - return True - - if event.type.startswith("window:deactivate"): - return True - - if event.type.startswith("object:state-changed:active"): - return AXUtilities.is_frame(event.source) or AXUtilities.is_window(event.source) - - if event.type.startswith("document:load-complete"): - return True - - if event.type.startswith("object:state-changed:busy"): - return True - - return False - - def _pruneEventsDuringFlood(self) -> None: - """Gets rid of events we don't care about during a flood.""" - - oldSize = self._eventQueue.qsize() - - newQueue: queue.Queue[Any] = queue.Queue(0) - while not self._eventQueue.empty(): - try: - event = self._eventQueue.get() - except Exception: - continue - - if self._processDuringFlood(event): - newQueue.put(event) - self._queuePrintln(event, isPrune=False) - self._eventQueue.task_done() - - self._eventQueue = newQueue - newSize = self._eventQueue.qsize() - - msg = f"EVENT MANAGER: {oldSize - newSize} events pruned. New size: {newSize}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _context_token_for_accessible(self, accessible: Any) -> Optional[str]: - if accessible is None: - return None - - application = AXObject.get_application(accessible) - if application is None: - return None - - pid = AXObject.get_process_id(application) - name = (AXObject.get_name(accessible) or "").strip() - if not name: - name = AXObject.get_role_name(accessible) or AXObject.get_accessible_id(accessible) or "unknown" - if pid < 0 and not name: - return None - - return f"{max(pid, 0)}:{name}" - - def _context_token_for_event(self, event: Any) -> Optional[str]: - return self._context_token_for_accessible(getattr(event, "source", None)) - - def _event_is_from_stale_context(self, event: Any) -> bool: - prioritizedContextToken = self._prioritizedContextToken or cthulhu_state.prioritizedDesktopContextToken - if not prioritizedContextToken: - return False - - if getattr(event, "type", "").startswith("window:"): - return False - - eventToken = self._context_token_for_event(event) - if eventToken is None: - return False - - return eventToken != prioritizedContextToken - - def _is_obsolete_by_context(self, event: Any) -> bool: - if not (self._churnSuppressed or cthulhu_state.pauseAtspiChurn): - return False - - return self._event_is_from_stale_context(event) - - def _should_preserve_during_suppression(self, event: Any) -> bool: - eventType = getattr(event, "type", "") - if eventType.startswith("window:"): - return True - - if eventType.startswith("object:state-changed:focused") and getattr(event, "detail1", 0): - return True - - if eventType.startswith("object:state-changed:active"): - return AXUtilities.is_frame(event.source) or AXUtilities.is_window(event.source) - - if eventType.startswith("object:text-selection-changed"): - return True - - if eventType.startswith("object:selection-changed"): - return self._context_token_for_event(event) == (self._prioritizedContextToken or cthulhu_state.prioritizedDesktopContextToken) - - return False - - def _flush_stale_atspi_events(self) -> None: - """Drops queued events that no longer match the compositor context.""" - - with self._gidleLock: - self._flushingStaleAtspiEvents = True - originalQueue = self._eventQueue - self._eventQueue = queue.Queue(0) - - retainedEvents: list[Any] = [] - try: - while not originalQueue.empty(): - try: - event = originalQueue.get_nowait() - except queue.Empty: - break - - # Accessible property calls can dispatch nested AT-SPI events. - # Keep them outside _gidleLock so a nested enqueue cannot deadlock. - try: - isStale = self._event_is_from_stale_context(event) - shouldPreserve = ( - isStale - and self._should_preserve_during_suppression(event) - ) - except Exception: - retainedEvents.append(event) - raise - - if isStale and not shouldPreserve: - continue - - retainedEvents.append(event) - finally: - while not originalQueue.empty(): - try: - retainedEvents.append(originalQueue.get_nowait()) - except queue.Empty: - break - - with self._gidleLock: - eventsQueuedDuringFlush = self._eventQueue - mergedQueue: queue.Queue[Any] = queue.Queue(0) - for event in retainedEvents: - mergedQueue.put(event) - - while not eventsQueuedDuringFlush.empty(): - try: - mergedQueue.put(eventsQueuedDuringFlush.get_nowait()) - except queue.Empty: - break - - self._eventQueue = mergedQueue - self._flushingStaleAtspiEvents = False - if self._asyncMode and not self._eventQueue.empty() and not self._gidleId: - self._gidleId = GLib.idle_add(self._dequeue) - - def _inFlood(self) -> bool: - size = self._eventQueue.qsize() - if size > 50: - msg = f"EVENT MANAGER: FLOOD? Queue size is {size}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def _event_refreshes_xterm_handoff(self, event: Atspi.Event) -> bool: - """Returns True when an event can represent a real foreground transition.""" - - if event.type.startswith("window:activate"): - return True - - if event.type.startswith("object:state-changed:focused"): - return bool(event.detail1) - - if event.type.startswith("object:state-changed:active") and event.detail1: - return AXUtilities.is_frame(event.source) or AXUtilities.is_window(event.source) - - return False - - def _is_notification_event_during_xterm_handoff(self, event: Atspi.Event) -> bool: - """Returns True when an event should bypass XTerm handoff suppression.""" - - for obj in (event.source, event.any_data): - if obj is None or isinstance(obj, (str, bytes, int, float, bool)): - continue - try: - if AXUtilities.is_notification(obj) or AXUtilities.is_alert(obj): - return True - except Exception: - pass - - notificationEventTypes = ( - "window:create", - "object:property-change:accessible-name", - "object:property-change:accessible-value", - ) - if not event.type.startswith(notificationEventTypes): - return False - - app = AXObject.get_application(event.source) - appName = (AXObject.get_name(app) or "").casefold() - return appName in ( - "notification-daemon", - "notify-osd", - "xfce4-notifyd", - "mate-notification-daemon", - ) - - def _processObjectEvent(self, event: Atspi.Event) -> None: - """Handles all object events destined for scripts. - - Arguments: - - e: an at-spi event. - """ - - if cthulhu_state.screenLockActive: - return - - debug.printObjectEvent(debug.LEVEL_INFO, event, timestamp=True) - eType = event.type - - if self._desktopContextConfirmedEmpty \ - and not self._is_notification_event_during_xterm_handoff(event): - msg = "EVENT MANAGER: Ignoring AT-SPI event on confirmed empty i3 workspace." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - refreshXtermHandoff = self._event_refreshes_xterm_handoff(event) - isNotification = self._is_notification_event_during_xterm_handoff(event) - suppressForXterm = not isNotification and self._inputEventManager is not None and ( - self._inputEventManager.should_suppress_atspi_events_for_xterm( - refresh=refreshXtermHandoff, - ) - ) - if suppressForXterm: - msg = ( - "EVENT MANAGER: Ignoring AT-SPI event while XTerm owns the " - "foreground handoff." - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if eType.startswith("object:children-changed:remove") \ - and event.source == AXUtilities.get_desktop(): - cthulhu.cthulhuApp.scriptManager.reclaim_scripts() - return - - if eType.startswith("window:") and not eType.endswith("create"): - cthulhu.cthulhuApp.scriptManager.reclaim_scripts() - elif eType.startswith("object:state-changed:active") \ - and AXUtilities.is_frame(event.source): - cthulhu.cthulhuApp.scriptManager.reclaim_scripts() - - if AXObject.is_dead(event.source) or AXUtilities.is_defunct(event.source): - tokens = ["EVENT MANAGER: Ignoring defunct object:", event.source] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if eType.startswith("window:deactivate") or eType.startswith("window:destroy") \ - and cthulhu_state.activeWindow == event.source: - msg = 'EVENT MANAGER: Clearing active window, script, and locus of focus' - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu_state.locusOfFocus = None - cthulhu_state.activeWindow = None - cthulhu.cthulhuApp.scriptManager.set_active_script(None, "focus: active-window-dead") - return - - if AXUtilities.is_iconified(event.source): - tokens = ["EVENT MANAGER: Ignoring iconified object:", event.source] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - if self._inFlood(): - if not self._processDuringFlood(event): - msg = 'EVENT MANAGER: Not processing this event due to flood.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - if self._prioritizeDuringFlood(event): - msg = 'EVENT MANAGER: Pruning event queue due to flood.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._pruneEventsDuringFlood() - - if eType.startswith('object:selection-changed') \ - and event.source in self._parentsOfDefunctDescendants: - msg = 'EVENT MANAGER: Ignoring event from parent of defunct descendants' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if not debug.eventDebugFilter or debug.eventDebugFilter.match(eType) \ - and not eType.startswith("mouse:"): - indent = " " * 32 - debug.printDetails(debug.LEVEL_INFO, indent, event.source) - if isinstance(event.any_data, Atspi.Accessible): - debug.printMessage(debug.LEVEL_INFO, f"{indent}ANY DATA:") - debug.printDetails(debug.LEVEL_INFO, indent, event.any_data, includeApp=False) - - script = self._get_scriptForEvent(event) - if not script: - msg = "ERROR: Could not get script for event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - setNewActiveScript, reason = self._isActivatableEvent(event, script) - debug.print_log(debug.LEVEL_INFO, "EVENT MANAGER", - f"Change active script: {setNewActiveScript}", reason, True) - - if setNewActiveScript: - try: - cthulhu.cthulhuApp.scriptManager.set_active_script(script, reason) - except Exception as error: - tokens = ["EVENT MANAGER: Exception setting active script for", - event.source, ":", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - try: - script.processObjectEvent(event) - except Exception as error: - msg = f"EVENT MANAGER: Exception processing {event.type}: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - debug.printException(debug.LEVEL_INFO) - else: - if self._compositorStateAdapter is not None: - if eType.startswith("window:activate") or ( - eType.startswith("object:state-changed:focused") and event.detail1 - ): - self._compositorStateAdapter.sync_accessible_context(event.type) - - tokens = ["EVENT MANAGER: locusOfFocus:", cthulhu_state.locusOfFocus, - "activeScript:", cthulhu_state.activeScript] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if debug.LEVEL_INFO >= debug.debugLevel and cthulhu_state.activeScript: - attributes = cthulhu_state.activeScript.getTransferableAttributes() - for key, value in attributes.items(): - msg = f"EVENT MANAGER: {key}: {value}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def processBrailleEvent(self, brailleEvent: input_event.BrailleEvent) -> bool: - """Called whenever a cursor key is pressed on the Braille display. - - Arguments: - - brailleEvent: an instance of input_event.BrailleEvent - - Returns True if the command was consumed; otherwise False - """ - - if cthulhu_state.activeScript \ - and cthulhu_state.activeScript.consumesBrailleEvent(brailleEvent): - self._enqueue(brailleEvent) - return True - else: - return False - -_manager: Optional[EventManager] = None - -def getManager() -> Optional[EventManager]: - global _manager - if _manager is None: - try: - if cthulhu.cthulhuApp: - _manager = cthulhu.cthulhuApp.eventManager - except AttributeError: - pass - return _manager diff --git a/src/cthulhu/find.py b/src/cthulhu/find.py deleted file mode 100644 index 7ad7e09..0000000 --- a/src/cthulhu/find.py +++ /dev/null @@ -1,267 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides support for a flat review find.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2006-2008 Sun Microsystems Inc." \ - "Copyright (c) 2022 Igalia, S.L." -__license__ = "LGPL" - - -import copy -import re - -from . import debug -from . import messages -from . import cthulhu_state - -from .flat_review import Context - - -class _SearchQueryMatch: - """Represents a SearchQuery match.""" - - def __init__(self, context, pattern): - self._line = context.lineIndex - self._zone = context.zoneIndex - self._word = context.wordIndex - self._char = context.charIndex - self._pattern = pattern - self._lineString = context.getCurrent(Context.LINE)[0] - - def __str__(self): - return "SEARCH QUERY MATCH: '%s' (line %i, zone %i, word %i, char %i) for '%s'" % \ - (self._lineString, self._line, self._zone, self._word, self._char, self._pattern) - - def __eq__(self, other): - if not other: - return False - - return self._lineString == other._lineString and \ - self._line == other._line and \ - self._zone == other._zone and \ - self._word == other._word and \ - self._char == other._char - -class SearchQuery: - """Represents a search that the user wants to perform.""" - - def __init__(self): - """Creates a new SearchQuery. A searchQuery has the following - properties: - - searchString - the string to find - searchBackwards - if true, search upward for matches - caseSensitive - if true, case counts - matchEntireWord - if true, only match on the entire string - startAtTop - if true, begin the search from the top of - the window, rather than at the current - location - windowWrap - if true, when the top/bottom edge of the - window is reached wrap to the bottom/top - and continue searching - """ - - self.searchString = "" - self.searchBackwards = False - self.caseSensitive = False - self.matchEntireWord = False - self.windowWrap = False - self.startAtTop = False - self.debugLevel = debug.LEVEL_INFO - self._contextLocation = [0, 0, 0, 0] - self._match = None - self._wrapped = False - - def __str__(self): - string = f"FIND QUERY: '{self.searchString}'." - options = [] - if self.searchBackwards: - options.append("search backwards") - if self.caseSensitive: - options.append("case sensitive") - if self.matchEntireWord: - options.append("match entire word") - if self.windowWrap: - options.append("wrap") - if self.startAtTop: - options.append("start at top") - if options: - string += f" Options: {', '.join(options)}" - if self._match: - string += f" Last match: {self._match}" - return string - - def previousMatch(self): - if not cthulhu_state.searchQuery: - return None - return cthulhu_state.searchQuery._match - - def _saveContextLocation(self, context): - self._contextLocation = [context.lineIndex, - context.zoneIndex, - context.wordIndex, - context.charIndex] - - def _restoreContextLocation(self, context): - context.setCurrent(*self._contextLocation) - self._contextLocation = [0, 0, 0, 0] - - def _currentContextMatches(self, context, pattern, contextType): - if contextType == Context.LINE: - typeString = "LINE" - elif contextType == Context.ZONE: - typeString = "ZONE" - elif contextType == Context.WORD: - typeString = "WORD" - else: - return False - - string = context.getCurrent(contextType)[0] - match = re.search(pattern, string) - msg = "FIND: %s='%s'. Match: %s" % (typeString, string.replace("\n", "\\n"), match) - debug.println(self.debugLevel, msg, True) - return bool(match) - - def _move(self, context, contextType): - if contextType == Context.WORD: - if self.searchBackwards: - return context.goPrevious(Context.WORD, Context.WRAP_LINE) - return context.goNext(Context.WORD, Context.WRAP_LINE) - - if contextType == Context.ZONE: - if self.searchBackwards: - moved = context.goPrevious(Context.ZONE, Context.WRAP_LINE) - context.goEnd(Context.ZONE) - return moved - return context.goNext(Context.ZONE, Context.WRAP_LINE) - - if contextType == Context.LINE: - if self.searchBackwards: - moved = context.goPrevious(Context.LINE, Context.WRAP_LINE) - context.goEnd(Context.LINE) - else: - moved = context.goNext(Context.LINE, Context.WRAP_LINE) - if moved: - return True - if not self.windowWrap or self._wrapped: - return False - self._wrapped = True - if self.searchBackwards: - cthulhu_state.activeScript.presentMessage(messages.WRAPPING_TO_BOTTOM) - moved = context.goPrevious(Context.LINE, Context.WRAP_ALL) - else: - cthulhu_state.activeScript.presentMessage(messages.WRAPPING_TO_TOP) - moved = context.goNext(Context.LINE, Context.WRAP_ALL) - return moved - - return False - - def _findMatchIn(self, context, pattern, contextType): - found = self._currentContextMatches(context, pattern, contextType) - while not found: - if not self._move(context, contextType): - break - found = self._currentContextMatches(context, pattern, contextType) - - return found - - def _findMatch(self, context, pattern): - if not self._findMatchIn(context, pattern, Context.LINE): - return False - - if not self._findMatchIn(context, pattern, Context.ZONE): - return False - - if not self._findMatchIn(context, pattern, Context.WORD): - return False - - if not self.previousMatch(): - return True - - candidateMatch = _SearchQueryMatch(context, pattern) - if candidateMatch != self.previousMatch(): - return True - - if self._move(context, Context.WORD) \ - and self._findMatchIn(context, pattern, Context.WORD): - return True - - if self._move(context, Context.ZONE) \ - and self._findMatchIn(context, pattern, Context.ZONE): - return True - - if self._move(context, Context.LINE): - return self._findMatch(context, pattern) - - return False - - def findQuery(self, context): - """Performs a search on the string specified in searchQuery. - - Arguments: - - context: The context from active script - - Returns: - - The context of the match, if found - """ - - debug.println(self.debugLevel, str(self), True) - flags = re.U - if not self.caseSensitive: - flags = flags | re.IGNORECASE - if self.matchEntireWord: - regexp = "\\b" + self.searchString + "\\b" - else: - regexp = self.searchString - pattern = re.compile(regexp, flags) - - self._saveContextLocation(context) - if self.startAtTop: - context.goBegin(Context.WINDOW) - - location = None - if self._findMatch(context, pattern): - self._saveContextLocation(context) - self._match = _SearchQueryMatch(context, pattern) - self._wrapped = False - location = copy.copy(context) - else: - self._restoreContextLocation(context) - cthulhu_state.searchQuery = copy.copy(self) - return location - -def getLastQuery(): - """Grabs the last search query performed from cthulhu_state. - - Returns: - - A copy of the last search query, if it exists - """ - - lastQuery = copy.copy(cthulhu_state.searchQuery) - return lastQuery diff --git a/src/cthulhu/flat_review.py b/src/cthulhu/flat_review.py deleted file mode 100644 index 5a5735d..0000000 --- a/src/cthulhu/flat_review.py +++ /dev/null @@ -1,1483 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides the default implementation for flat review for Cthulhu.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2016 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -import re - -from . import braille -from . import debug -from . import cthulhu -from . import cthulhu_state -from . import settings -from .ax_event_synthesizer import AXEventSynthesizer -from .ax_component import AXComponent -from .ax_object import AXObject -from .ax_text import AXText -from .ax_utilities import AXUtilities - -EMBEDDED_OBJECT_CHARACTER = '\ufffc' - -class Char: - """A character's worth of presentable information.""" - - def __init__(self, word, index, startOffset, string, x, y, width, height): - """Creates a new char. - - Arguments: - - word: the Word instance this belongs to - - startOffset: the start offset with respect to the accessible - - string: the actual char - - x, y, width, height: the extents of this Char on the screen - """ - - self.word = word - self.index = index - self.startOffset = startOffset - self.endOffset = startOffset + 1 - self.string = string - self.x = x - self.y = y - self.width = width - self.height = height - - -class Word: - """A single chunk (word or object) of presentable information.""" - - def __init__(self, zone, index, startOffset, string, x, y, width, height): - """Creates a new Word. - - Arguments: - - zone: the Zone instance this belongs to - - index: the index of this Word in the Zone - - startOffset: the start offset with respect to the accessible - - string: the actual string - - x, y, width, height: the extents of this Word on the screen - """ - - self.zone = zone - self.index = index - self.startOffset = startOffset - self.string = string - self.length = len(string) - self.endOffset = self.startOffset + len(string) - self.x = x - self.y = y - self.width = width - self.height = height - self.chars = [] - - def __str__(self): - return "WORD: '%s' (%i-%i) %s" % \ - (self.string.replace("\n", "\\n"), - self.startOffset, - self.endOffset, - self.zone.accessible) - - def __getattribute__(self, attr): - if attr != "chars": - return super().__getattribute__(attr) - - chars = [] - for i, char in enumerate(self.string): - start = i + self.startOffset - extents = self._getCharExtents(start) - chars.append(Char(self, i, start, char, *extents)) - - return chars - - def _getCharExtents(self, start): - # NOTE: We intentionally avoid faking character extents to improve reviewability. - extents = self.x, self.y, self.width, self.height - - if AXObject.supports_text(self.zone.accessible): - try: - rect = Atspi.Text.get_range_extents( - self.zone.accessible, start, start + 1, Atspi.CoordType.SCREEN) - extents = rect.x, rect.y, rect.width, rect.height - except Exception as error: - tokens = ["FLAT REVIEW: Exception in getRangeExtents:", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return extents - - def getRelativeOffset(self, offset): - """Returns the char offset with respect to this word or -1.""" - - if self.startOffset <= offset < self.startOffset + len(self.string): - return offset - self.startOffset - - return -1 - - -class Zone: - """Represents text that is a portion of a single horizontal line.""" - - WORDS_RE = re.compile(r"(\S+\s*)", re.UNICODE) - TEXT_ROLES = ( - Atspi.Role.LABEL, - Atspi.Role.MENU, - Atspi.Role.MENU_ITEM, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.PAGE_TAB, - Atspi.Role.PUSH_BUTTON, - Atspi.Role.TABLE_CELL, - ) - - def __init__(self, accessible, string, x, y, width, height, role=None): - """Creates a new Zone. - - Arguments: - - accessible: the Accessible associated with this Zone - - string: the string being displayed for this Zone - - extents: x, y, width, height in screen coordinates - - role: Role to override accessible's role. - """ - - self.accessible = accessible - self.startOffset = 0 - self._string = string - self.length = len(string) - self.x = x - self.y = y - self.width = width - self.height = height - self.role = role or AXObject.get_role(accessible) - self._words = [] - - def __str__(self): - return "ZONE: '%s' %s" % (self._string.replace("\n", "\\n"), self.accessible) - - def __getattribute__(self, attr): - """To ensure we update the content.""" - - if attr not in ["words", "string"]: - return super().__getattribute__(attr) - - if attr == "string": - return self._string - - if not self._shouldFakeText(): - return self._words - - extents = self._getFakeTextExtents() - words = [] - for i, word in enumerate(re.finditer(self.WORDS_RE, self._string)): - words.append(Word(self, i, word.start(), word.group(), *extents)) - - self._words = words - return words - - def _shouldFakeText(self): - """Returns True if we should try to fake the text interface""" - - if self.role in self.TEXT_ROLES: - return True - - return False - - def _getFakeTextExtents(self): - # NOTE: We intentionally avoid faking word extents to improve reviewability. - return self.x, self.y, self.width, self.height - - def _extentsAreOnSameLine(self, zone, pixelDelta=5): - """Returns True if this Zone is physically on the same line as zone.""" - - if self.width == 0 and self.height == 0: - return zone.y <= self.y <= zone.y + zone.height - - if zone.width == 0 and self.height == 0: - return self.y <= zone.y <= self.y + self.height - - highestBottom = min(self.y + self.height, zone.y + zone.height) - lowestTop = max(self.y, zone.y) - if lowestTop >= highestBottom: - return False - - middle = self.y + self.height / 2 - zoneMiddle = zone.y + zone.height / 2 - if abs(middle - zoneMiddle) > pixelDelta: - return False - - return True - - def onSameLine(self, zone): - """Returns True if we treat this Zone and zone as being on one line.""" - - if Atspi.Role.SCROLL_BAR in [self.role, zone.role]: - return self.accessible == zone.accessible - - thisParent = AXObject.get_parent(self.accessible) - thisParentRole = AXObject.get_role(thisParent) - zoneParent = AXObject.get_parent(zone.accessible) - zoneParentRole = AXObject.get_role(zoneParent) - if Atspi.Role.MENU_BAR in [thisParentRole, zoneParentRole]: - return thisParent == zoneParent - - return self._extentsAreOnSameLine(zone) - - def getWordAtOffset(self, charOffset): - msg = f"FLAT REVIEW: Searching for word at offset {charOffset}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - for word in self.words: - tokens = ["FLAT REVIEW: Checking", word] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - offset = word.getRelativeOffset(charOffset) - if offset >= 0: - return word, offset - - if self.length == charOffset and self.words: - lastWord = self.words[-1] - return lastWord, lastWord.length - - return None, -1 - - def hasCaret(self): - """Returns True if this Zone contains the caret.""" - - return False - - def wordWithCaret(self): - """Returns the Word and relative offset with the caret.""" - - return None, -1 - -class TextZone(Zone): - """A Zone whose purpose is to display text of an object.""" - - def __init__(self, accessible, startOffset, string, x, y, width, height, role=None): - super().__init__(accessible, string, x, y, width, height, role) - - self.startOffset = startOffset - self.endOffset = self.startOffset + len(string) - self._itext = None - - def __getattribute__(self, attr): - """To ensure we update the content.""" - - if attr not in ["words", "string"]: - return super().__getattribute__(attr) - - string = AXText.get_substring(self.accessible, self.startOffset, self.endOffset) - words = [] - for i, word in enumerate(re.finditer(self.WORDS_RE, string)): - start, end = (pos + self.startOffset for pos in word.span()) - try: - rect = Atspi.Text.get_range_extents(self.accessible, start, end, Atspi.CoordType.SCREEN) - extents = rect.x, rect.y, rect.width, rect.height - except Exception: - extents = (self.x, self.y, self.width, self.height) - words.append(Word(self, i, start, word.group(), *extents)) - - self._string = string - self._words = words - return super().__getattribute__(attr) - - def hasCaret(self): - """Returns True if this Zone contains the caret.""" - - offset = AXText.get_caret_offset(self.accessible) - if self.startOffset <= offset < self.endOffset: - return True - - return self.endOffset == AXText.get_character_count(self.accessible) - - def wordWithCaret(self): - """Returns the Word and relative offset with the caret.""" - - if not self.hasCaret(): - return None, -1 - - return self.getWordAtOffset(AXText.get_caret_offset(self.accessible)) - - -class StateZone(Zone): - """A Zone whose purpose is to display the state of an object.""" - - def __init__(self, accessible, x, y, width, height, role=None): - super().__init__(accessible, "", x, y, width, height, role) - - def __getattribute__(self, attr): - """To ensure we update the state.""" - - if attr not in ["string", "brailleString"]: - return super().__getattribute__(attr) - - if attr == "string": - generator = cthulhu_state.activeScript.speechGenerator - else: - generator = cthulhu_state.activeScript.brailleGenerator - - return self._getStateString(generator) - - def _getStateString(self, generator): - result = generator.getStateIndicator(self.accessible, role=self.role) - if result: - return result[0] - - return "" - - -class ValueZone(Zone): - """A Zone whose purpose is to display the value of an object.""" - - def __init__(self, accessible, x, y, width, height, role=None): - super().__init__(accessible, "", x, y, width, height, role) - - def __getattribute__(self, attr): - """To ensure we update the value.""" - - if attr not in ["string", "brailleString"]: - return super().__getattribute__(attr) - - if attr == "string": - generator = cthulhu_state.activeScript.speechGenerator - else: - generator = cthulhu_state.activeScript.brailleGenerator - - return self._getValueString(generator) - - def _getValueString(self, generator): - # NOTE: This assembly is a stopgap until generators handle it directly. - rolename = generator.getLocalizedRoleName(self.accessible) - value = generator.getValue(self.accessible) - if rolename and value: - return f"{rolename} {value[0]}" - - return "" - - -class Line: - """A Line is a single line across a window and is composed of Zones.""" - - TEXT_BRAILLE_ROLES = ( - Atspi.Role.TEXT, - Atspi.Role.PASSWORD_TEXT, - Atspi.Role.TERMINAL, - ) - TEXT_BRAILLE_FALLBACK_ROLES = ( - Atspi.Role.PARAGRAPH, - Atspi.Role.HEADING, - Atspi.Role.LINK, - ) - - def __init__(self, - index, - zones): - """Creates a new Line, which is a horizontal region of text. - - Arguments: - - index: the index of this Line in the window - - zones: the Zones that make up this line - """ - self.index = index - self.zones = zones - self.brailleRegions = None - - def __getattribute__(self, attr): - if attr == "string": - return " ".join([zone.string for zone in self.zones]) - - if attr == "x": - return min(zone.x for zone in self.zones) - - if attr == "y": - return min(zone.y for zone in self.zones) - - if attr == "width": - return sum(zone.width for zone in self.zones) - - if attr == "height": - return max(zone.height for zone in self.zones) - - return super().__getattribute__(attr) - - def getBrailleRegions(self): - # [[[WDW - We'll always compute the braille regions. This - # allows us to handle StateZone and ValueZone zones whose - # states might be changing on us.]]] - # - if True or not self.brailleRegions: - self.brailleRegions = [] - brailleOffset = 0 - for zone in self.zones: - region = self._createBrailleRegion(zone) - if len(self.brailleRegions): - pad = braille.Region(" ") - pad.brailleOffset = brailleOffset - self.brailleRegions.append(pad) - brailleOffset += 1 - - zone.brailleRegion = region - region.brailleOffset = brailleOffset - self.brailleRegions.append(region) - - regionString = region.string - brailleOffset += len(regionString) - - if not settings.disableBrailleEOL: - if len(self.brailleRegions): - pad = braille.Region(" ") - pad.brailleOffset = brailleOffset - self.brailleRegions.append(pad) - brailleOffset += 1 - eol = braille.Region("$l") - eol.brailleOffset = brailleOffset - self.brailleRegions.append(eol) - - return self.brailleRegions - - def _createBrailleRegion(self, zone): - if self._shouldUseTextBrailleRegion(zone): - return braille.ReviewText(zone.accessible, - zone.string, - zone.startOffset, - zone) - - try: - brailleString = zone.brailleString - except Exception: - brailleString = zone.string - - return braille.ReviewComponent(zone.accessible, - brailleString, - 0, # cursor offset - zone) - - def _shouldUseTextBrailleRegion(self, zone): - # The 'isinstance(zone, TextZone)' test is a sanity check - # to handle problems with Java text. See Bug 435553. - if not isinstance(zone, TextZone): - return False - - role = AXObject.get_role(zone.accessible) - if role in self.TEXT_BRAILLE_ROLES: - return True - - # NOTE: Fallback roles kept for legacy cursor key routing support. - return role in self.TEXT_BRAILLE_FALLBACK_ROLES - -class Context: - """Contains the flat review regions for the current top-level object.""" - - ZONE = 0 - CHAR = 1 - WORD = 2 - LINE = 3 # includes all zones on same line - WINDOW = 4 - - WRAP_NONE = 0 - WRAP_LINE = 1 << 0 - WRAP_TOP_BOTTOM = 1 << 1 - WRAP_ALL = (WRAP_LINE | WRAP_TOP_BOTTOM) - - CONTAINER_ROLES = (Atspi.Role.MENU,) - VALUE_ZONE_ROLES = (Atspi.Role.SCROLL_BAR, Atspi.Role.SLIDER, Atspi.Role.PROGRESS_BAR) - REDUNDANT_NAME_ROLES = (Atspi.Role.TABLE_ROW,) - USELESS_NAME_ROLES = (Atspi.Role.TABLE_CELL, Atspi.Role.LABEL) - STATE_ZONE_ROLES = ( - Atspi.Role.CHECK_BOX, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.RADIO_BUTTON, - Atspi.Role.RADIO_MENU_ITEM, - ) - - def __init__(self, script, root=None): - """Create a new Context for script.""" - - self.script = script - self.zones = [] - self.lines = [] - self.lineIndex = 0 - self.zoneIndex = 0 - self.wordIndex = 0 - self.charIndex = 0 - self.targetCharInfo = None - self.focusZone = None - self.container = None - self.focusObj = cthulhu.getActiveModeAndObjectOfInterest()[1] or cthulhu_state.locusOfFocus - self.topLevel = None - self.bounds = Atspi.Rect() - - frame, dialog = script.utilities.frameAndDialog(self.focusObj) - if root is not None: - self.topLevel = root - tokens = ["FLAT REVIEW: Restricting flat review to", root] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - self.topLevel = dialog or frame - tokens = ["FLAT REVIEW: Frame:", frame, "Dialog:", dialog, ". Top level:", self.topLevel] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - try: - self.bounds = AXComponent.get_rect(self.topLevel) - except Exception: - tokens = ["ERROR: Exception getting extents of", self.topLevel] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - def isContainer(x): - return AXObject.get_role(x) in self.CONTAINER_ROLES - - container = AXObject.find_ancestor(self.focusObj, isContainer) - if not container and isContainer(self.focusObj): - container = self.focusObj - - self.container = container or self.topLevel - - self.zones, self.focusZone = self.getShowingZones(self.container) - self.lines = self.clusterZonesByLine(self.zones) - if not (self.lines and self.focusZone): - return - - for i, line in enumerate(self.lines): - if self.focusZone in line.zones: - self.lineIndex = i - self.zoneIndex = line.zones.index(self.focusZone) - word, offset = self.focusZone.wordWithCaret() - if word: - self.wordIndex = word.index - self.charIndex = offset - break - - msg = ( - f"FLAT REVIEW: On line {self.lineIndex}, zone {self.zoneIndex} " - f"word {self.wordIndex}, char {self.charIndex}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def splitTextIntoZones(self, accessible, string, startOffset, cliprect): - """Traverses the string, splitting it up into separate zones if the - string contains the EMBEDDED_OBJECT_CHARACTER, which is used by apps - such as Firefox to handle containment of things such as links in - paragraphs. - - Arguments: - - accessible: the accessible - - string: a substring from the accessible's text specialization - - startOffset: the starting character offset of the string - - cliprect: the extents that the Zones must fit inside. - - Returns a list of Zones for the visible text. - """ - - cliprect = self._ensureRect(cliprect) - zones = [] - substrings = [(*m.span(), m.group(0)) for m in EMBEDDED_OBJECT_RE.finditer(string)] - substrings = [(start + startOffset, end + startOffset, text) - for (start, end, text) in substrings] - for (start, end, substring) in substrings: - try: - rect = Atspi.Text.get_range_extents(accessible, start, end, Atspi.CoordType.SCREEN) - extents = rect.x, rect.y, rect.width, rect.height - except Exception: - extents = (0, 0, 0, 0) - if self.script.utilities.containsRegion(extents, cliprect): - clipping = self.script.utilities.intersection(extents, cliprect) - zones.append(TextZone(accessible, start, substring, *clipping)) - - return zones - - def getZonesFromText(self, accessible, cliprect): - """Gets a list of Zones from an object that implements the - AccessibleText specialization. - - Arguments: - - accessible: the accessible - - cliprect: the extents that the Zones must fit inside. - - Returns a list of Zones. - """ - - cliprect = self._ensureRect(cliprect) - if not self.script.utilities.hasPresentableText(accessible): - return [] - - zones = self._getSingleLineEditableZones(accessible) - if zones: - return zones - - upperMax = lowerMax = AXText.get_character_count(accessible) - upperMid = lowerMid = int(upperMax / 2) - upperMin = lowerMin = 0 - oldMid = 0 - - # performing binary search to locate first line inside clipped area - while oldMid != upperMid: - oldMid = upperMid - rect = Atspi.Text.get_range_extents(accessible, upperMid, upperMid + 1, - Atspi.CoordType.SCREEN) - x, y, width, height = rect.x, rect.y, rect.width, rect.height - if y > cliprect.y: - upperMax = upperMid - else: - upperMin = upperMid - upperMid = int((upperMax - upperMin) / 2) + upperMin - - # performing binary search to locate last line inside clipped area - oldMid = 0 - limit = cliprect.y+cliprect.height - while oldMid != lowerMid: - oldMid = lowerMid - rect = Atspi.Text.get_range_extents(accessible, lowerMid, lowerMid + 1, - Atspi.CoordType.SCREEN) - x, y, width, height = rect.x, rect.y, rect.width, rect.height - if y > limit: - lowerMax = lowerMid - else: - lowerMin = lowerMid - lowerMid = int((lowerMax - lowerMin) / 2) + lowerMin - - msg = "FLAT REVIEW: Getting lines for %s offsets %i-%i" % (accessible, upperMin, lowerMax) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - lines = self.script.utilities.getLinesForRange(accessible, upperMin, lowerMax) - tokens = ["FLAT REVIEW:", len(lines), "lines found for", accessible] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - for string, startOffset, endOffset in lines: - zones.extend(self.splitTextIntoZones(accessible, string, startOffset, cliprect)) - - return zones - - def _getSingleLineEditableZones(self, accessible): - # NOTE: Temporary workaround while text handling is refined. - if not (AXObject.supports_editable_text(accessible) - and AXUtilities.is_single_line(accessible)): - return [] - - rect = AXComponent.get_rect(accessible) - return [TextZone(accessible, 0, AXText.get_substring(accessible, 0, -1), - rect.x, rect.y, rect.width, rect.height)] - - def _insertStateZone(self, zones, accessible, extents): - """If the accessible presents non-textual state, such as a - checkbox or radio button, insert a StateZone representing - that state.""" - - # NOTE: Heuristic state-zone placement until handled by scripts. - - extents = self._ensureRect(extents) - indicatorExtents = [extents.x, extents.y, 1, extents.height] - role = AXObject.get_role(accessible) - if role == Atspi.Role.TOGGLE_BUTTON: - zone = StateZone(accessible, *indicatorExtents, role=role) - if zone: - zones.insert(0, zone) - return - - if role == Atspi.Role.TABLE_CELL \ - and self.script.utilities.hasMeaningfulToggleAction(accessible): - role = Atspi.Role.CHECK_BOX - - if role not in self.STATE_ZONE_ROLES: - return - - zone = None - stateOnLeft = True - - if len(zones) == 1 and isinstance(zones[0], TextZone): - textZone = zones[0] - textToLeftEdge = textZone.x - extents.x - textToRightEdge = (extents.x + extents.width) - (textZone.x + textZone.width) - stateOnLeft = textToLeftEdge > 20 - if stateOnLeft: - indicatorExtents[2] = textToLeftEdge - else: - indicatorExtents[0] = textZone.x + textZone.width - indicatorExtents[2] = textToRightEdge - - zone = StateZone(accessible, *indicatorExtents, role=role) - if zone: - if stateOnLeft: - zones.insert(0, zone) - else: - zones.append(zone) - - def getZonesFromAccessible(self, accessible, cliprect): - """Returns a list of Zones for the given accessible.""" - - cliprect = self._ensureRect(cliprect) - try: - if AXObject.supports_component(accessible): - rect = Atspi.Component.get_extents(accessible, Atspi.CoordType.SCREEN) - extents = rect.x, rect.y, rect.width, rect.height - else: - return [] - except Exception: - return [] - - try: - role = AXObject.get_role(accessible) - except Exception: - return [] - - zones = self.getZonesFromText(accessible, cliprect) - if not zones and role in self.VALUE_ZONE_ROLES: - zones.append(ValueZone(accessible, *extents)) - elif not zones: - string = "" - if role not in self.REDUNDANT_NAME_ROLES: - string = self.script.speechGenerator.getName(accessible, inFlatReview=True) - - if not string and role not in self.USELESS_NAME_ROLES: - string = self.script.speechGenerator.getRoleName(accessible) - if string: - zones.append(Zone(accessible, string, *extents)) - - self._insertStateZone(zones, accessible, extents) - - return zones - - def _isOrIsIn(self, child, parent): - if not (child and parent): - return False - - if child == parent: - return True - - return AXObject.find_ancestor(child, lambda x: x == parent) - - @staticmethod - def _ensureRect(rect): - if rect is None: - return Atspi.Rect() - if hasattr(rect, "x") and hasattr(rect, "y") \ - and hasattr(rect, "width") and hasattr(rect, "height"): - return rect - - try: - x, y, width, height = rect - except Exception: - return Atspi.Rect() - - newRect = Atspi.Rect() - newRect.x = x - newRect.y = y - newRect.width = width - newRect.height = height - return newRect - def setCurrentToZoneWithObject(self, obj): - """Attempts to set the current zone to obj, if obj is in the current context.""" - - tokens = ["FLAT REVIEW: Current", self.getCurrentAccessible(), - f"line: {self.lineIndex}, zone: {self.zoneIndex},", - f"word: {self.wordIndex}, char: {self.charIndex})"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - zone = self._findZoneWithObject(obj) - tokens = ["FLAT REVIEW: Zone with", obj, "is", zone] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if zone is None: - return False - - for i, line in enumerate(self.lines): - if zone in line.zones: - self.lineIndex = i - self.zoneIndex = line.zones.index(zone) - word, offset = zone.wordWithCaret() - if word: - self.wordIndex = word.index - self.charIndex = offset - msg = "FLAT REVIEW: Updated current zone." - debug.printMessage(debug.LEVEL_INFO, msg, True) - break - else: - msg = "FLAT REVIEW: Failed to update current zone." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - tokens = ["FLAT REVIEW: Updated", self.getCurrentAccessible(), - f"line: {self.lineIndex}, zone: {self.zoneIndex},", - f"word: {self.wordIndex}, char: {self.charIndex})"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - def _findZoneWithObject(self, obj): - """Returns the existing zone which contains obj.""" - - if obj is None: - return None - - for zone in self.zones: - if zone.accessible == obj: - return zone - - # Some items get pruned from the flat review tree. For instance, a - # tree item which has a descendant section whose text is the displayed - # text of the tree item, that section will be in the flat review tree - # but the ancestor item might not. - if AXObject.is_ancestor(zone.accessible, obj): - tokens = ["FLAT REVIEW:", zone.accessible, "is ancestor of zone accessible", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return zone - - return None - - def getShowingZones(self, root, boundingbox=None): - """Returns an unsorted list of all the zones under root and the focusZone.""" - - if boundingbox is None: - boundingbox = self.bounds - boundingbox = self._ensureRect(boundingbox) - - objs = self.script.utilities.getOnScreenObjects(root, boundingbox) - tokens = ["FLAT REVIEW:", len(objs), "on-screen objects found for", root] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - allZones, focusZone = [], None - for o in objs: - zones = self.getZonesFromAccessible(o, boundingbox) - if not zones: - descendant = self.script.utilities.realActiveDescendant(o) - if descendant: - zones = self.getZonesFromAccessible(descendant, boundingbox) - - if not zones: - continue - - allZones.extend(zones) - if not focusZone and zones and self.focusObj and self._isOrIsIn(o, self.focusObj): - zones = list(filter(lambda z: z.hasCaret(), zones)) or zones - focusZone = zones[0] - - tokens = ["FLAT REVIEW:", len(allZones), "zones found for", root] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return allZones, focusZone - - def clusterZonesByLine(self, zones): - """Returns a sorted list of Line clusters containing sorted Zones.""" - - if not zones: - return [] - - lineClusters = [] - sortedZones = sorted(zones, key=lambda z: z.y) - newCluster = [sortedZones.pop(0)] - for zone in sortedZones: - if zone.onSameLine(newCluster[-1]): - newCluster.append(zone) - else: - lineClusters.append(sorted(newCluster, key=lambda z: z.x)) - newCluster = [zone] - - if newCluster: - lineClusters.append(sorted(newCluster, key=lambda z: z.x)) - - lines = [] - for lineIndex, lineCluster in enumerate(lineClusters): - lines.append(Line(lineIndex, lineCluster)) - for zoneIndex, zone in enumerate(lineCluster): - zone.line = lines[lineIndex] - zone.index = zoneIndex - - tokens = ["FLAT REVIEW: Zones clustered into", len(lines), "lines"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return lines - - def getCurrent(self, flatReviewType=ZONE): - """Returns the current string, offset, and extent information.""" - - # NOTE: Legacy name; prefer getCurrentItem() for clarity. - - zone = self._getCurrentZone() - if not zone: - return None, -1, -1, -1, -1 - - current = zone - if flatReviewType == Context.LINE: - current = zone.line - elif flatReviewType != Context.ZONE and zone.words: - current = zone.words[self.wordIndex] - if flatReviewType == Context.CHAR and current.chars: - try: - current = current.chars[self.charIndex] - except Exception: - return None, -1, -1, -1, -1 - - return current.string, current.x, current.y, current.width, current.height - - def getCurrentItem(self, flatReviewType=ZONE): - return self.getCurrent(flatReviewType) - - def setCurrent(self, lineIndex, zoneIndex, wordIndex, charIndex): - """Sets the current character of interest. - - Arguments: - - lineIndex: index into lines - - zoneIndex: index into lines[lineIndex].zones - - wordIndex: index into lines[lineIndex].zones[zoneIndex].words - - charIndex: index lines[lineIndex].zones[zoneIndex].words[wordIndex].chars - """ - - self.lineIndex = lineIndex - self.zoneIndex = zoneIndex - self.wordIndex = wordIndex - self.charIndex = charIndex - self.targetCharInfo = self.getCurrent(Context.CHAR) - - def _getClickPoint(self): - string, x, y, width, height = self.getCurrent(Context.CHAR) - if (x < 0 and y < 0) or (width <= 0 and height <=0): - return -1, -1 - - # Click left of center to position the caret there. - x = int(max(x, x + (width / 2) - 1)) - y = int(y + height / 2) - - return x, y - - def routeToCurrent(self): - """Routes the mouse pointer to the current accessible.""" - - x, y = self._getClickPoint() - if x < 0 or y < 0: - return False - - return AXEventSynthesizer.route_to_point(x, y) - - def clickCurrent(self, button=1): - """Performs a mouse click on the current accessible.""" - - x, y = self._getClickPoint() - if x >= 0 and y >= 0 and AXEventSynthesizer.click_point(x, y, button): - return True - - if AXEventSynthesizer.click_object(self.getCurrentAccessible(), button): - return True - - return False - - def _getCurrentZone(self): - if not (self.lines and 0 <= self.lineIndex < len(self.lines)): - return None - - line = self.lines[self.lineIndex] - if not (line and 0 <= self.zoneIndex < len(line.zones)): - return None - - return line.zones[self.zoneIndex] - - def getCurrentAccessible(self): - """Returns the current accessible.""" - - zone = self._getCurrentZone() - if not zone: - return None - - return zone.accessible - - def getCurrentBrailleRegions(self): - """Gets the braille for the entire current line. - - Returns [regions, regionWithFocus] - """ - - if (not self.lines) \ - or (not self.lines[self.lineIndex].zones): - return [None, None] - - regionWithFocus = None - line = self.lines[self.lineIndex] - regions = line.getBrailleRegions() - - # Now find the current region and the current character offset - # into that region. - # - for zone in line.zones: - if zone.index == self.zoneIndex: - regionWithFocus = zone.brailleRegion - regionWithFocus.cursorOffset = 0 - if zone.words: - regionWithFocus.cursorOffset += zone.words[0].startOffset - zone.startOffset - for wordIndex in range(0, self.wordIndex): - regionWithFocus.cursorOffset += \ - len(zone.words[wordIndex].string) - regionWithFocus.cursorOffset += self.charIndex - regionWithFocus.repositionCursor() - break - - return [regions, regionWithFocus] - - def goBegin(self, flatReviewType=WINDOW): - """Moves this context's locus of interest to the first char - of the first relevant zone. - - Arguments: - - flatReviewType: one of ZONE, LINE or WINDOW - - Returns True if the locus of interest actually changed. - """ - - if (flatReviewType == Context.LINE) or (flatReviewType == Context.ZONE): - lineIndex = self.lineIndex - elif flatReviewType == Context.WINDOW: - lineIndex = 0 - else: - raise Exception("Invalid type: %d" % flatReviewType) - - if flatReviewType == Context.ZONE: - zoneIndex = self.zoneIndex - else: - zoneIndex = 0 - - wordIndex = 0 - charIndex = 0 - - moved = (self.lineIndex != lineIndex) \ - or (self.zoneIndex != zoneIndex) \ - or (self.wordIndex != wordIndex) \ - or (self.charIndex != charIndex) \ - - if moved: - self.lineIndex = lineIndex - self.zoneIndex = zoneIndex - self.wordIndex = wordIndex - self.charIndex = charIndex - self.targetCharInfo = self.getCurrent(Context.CHAR) - - return moved - - def goEnd(self, flatReviewType=WINDOW): - """Moves this context's locus of interest to the last char - of the last relevant zone. - - Arguments: - - flatReviewType: one of ZONE, LINE, or WINDOW - - Returns True if the locus of interest actually changed. - """ - - if (flatReviewType == Context.LINE) or (flatReviewType == Context.ZONE): - lineIndex = self.lineIndex - elif flatReviewType == Context.WINDOW: - lineIndex = len(self.lines) - 1 - else: - raise Exception("Invalid type: %d" % flatReviewType) - - if flatReviewType == Context.ZONE: - zoneIndex = self.zoneIndex - else: - zoneIndex = len(self.lines[lineIndex].zones) - 1 - - zone = self.lines[lineIndex].zones[zoneIndex] - if zone.words: - wordIndex = len(zone.words) - 1 - chars = zone.words[wordIndex].chars - if chars: - charIndex = len(chars) - 1 - else: - charIndex = 0 - else: - wordIndex = 0 - charIndex = 0 - - moved = (self.lineIndex != lineIndex) \ - or (self.zoneIndex != zoneIndex) \ - or (self.wordIndex != wordIndex) \ - or (self.charIndex != charIndex) \ - - if moved: - self.lineIndex = lineIndex - self.zoneIndex = zoneIndex - self.wordIndex = wordIndex - self.charIndex = charIndex - self.targetCharInfo = self.getCurrent(Context.CHAR) - - return moved - - def goPrevious(self, flatReviewType=ZONE, - wrap=WRAP_ALL, omitWhitespace=True): - """Moves this context's locus of interest to the first char - of the previous type. - - Arguments: - - flatReviewType: one of ZONE, CHAR, WORD, LINE - - wrap: if True, will cross boundaries, including top and - bottom; if False, will stop on boundaries. - - Returns True if the locus of interest actually changed. - """ - - if not self.lines: - debug.printMessage(debug.LEVEL_INFO, 'goPrevious(): no lines in context') - return False - - moved = False - - if flatReviewType == Context.ZONE: - if self.zoneIndex > 0: - self.zoneIndex -= 1 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - elif wrap & Context.WRAP_LINE: - if self.lineIndex > 0: - self.lineIndex -= 1 - self.zoneIndex = len(self.lines[self.lineIndex].zones) - 1 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - elif wrap & Context.WRAP_TOP_BOTTOM: - self.lineIndex = len(self.lines) - 1 - self.zoneIndex = len(self.lines[self.lineIndex].zones) - 1 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - elif flatReviewType == Context.CHAR: - if self.charIndex > 0: - self.charIndex -= 1 - moved = True - else: - moved = self.goPrevious(Context.WORD, wrap, False) - if moved: - zone = self.lines[self.lineIndex].zones[self.zoneIndex] - if zone.words: - chars = zone.words[self.wordIndex].chars - if chars: - self.charIndex = len(chars) - 1 - elif flatReviewType == Context.WORD: - zone = self.lines[self.lineIndex].zones[self.zoneIndex] - accessible = zone.accessible - lineIndex = self.lineIndex - zoneIndex = self.zoneIndex - wordIndex = self.wordIndex - charIndex = self.charIndex - - if self.wordIndex > 0: - self.wordIndex -= 1 - self.charIndex = 0 - moved = True - else: - moved = self.goPrevious(Context.ZONE, wrap) - if moved: - zone = self.lines[self.lineIndex].zones[self.zoneIndex] - if zone.words: - self.wordIndex = len(zone.words) - 1 - - # If we landed on a whitespace word or something with no words, - # we might need to move some more. - # - zone = self.lines[self.lineIndex].zones[self.zoneIndex] - if omitWhitespace \ - and moved \ - and ((len(zone.string) == 0) \ - or (len(zone.words) \ - and zone.words[self.wordIndex].string.isspace())): - - hasMoreText = False - if self.lineIndex > 0 and isinstance(zone, TextZone): - prevZone = self.lines[self.lineIndex - 1].zones[-1] - if prevZone.accessible == zone.accessible: - hasMoreText = True - - # If we're on whitespace in the same zone, then let's - # try to move on. If not, we've definitely moved - # across accessibles. If that's the case, let's try - # to find the first 'real' word in the accessible. - # If we cannot, then we're just stuck on an accessible - # with no words and we should do our best to announce - # this to the user (e.g., "whitespace" or "blank"). - # - if zone.accessible == accessible or hasMoreText: - moved = self.goPrevious(Context.WORD, wrap) - else: - wordIndex = self.wordIndex - 1 - while wordIndex >= 0: - if (not zone.words[wordIndex].string) \ - or not len(zone.words[wordIndex].string) \ - or zone.words[wordIndex].string.isspace(): - wordIndex -= 1 - else: - break - if wordIndex >= 0: - self.wordIndex = wordIndex - - if not moved: - self.lineIndex = lineIndex - self.zoneIndex = zoneIndex - self.wordIndex = wordIndex - self.charIndex = charIndex - - elif flatReviewType == Context.LINE: - if wrap & Context.WRAP_LINE: - if self.lineIndex > 0: - self.lineIndex -= 1 - self.zoneIndex = 0 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - elif (wrap & Context.WRAP_TOP_BOTTOM) \ - and (len(self.lines) != 1): - self.lineIndex = len(self.lines) - 1 - self.zoneIndex = 0 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - else: - raise Exception("Invalid type: %d" % flatReviewType) - - if moved and (flatReviewType != Context.LINE): - self.targetCharInfo = self.getCurrent(Context.CHAR) - - return moved - - def goNext(self, flatReviewType=ZONE, wrap=WRAP_ALL, omitWhitespace=True): - """Moves this context's locus of interest to first char of - the next type. - - Arguments: - - flatReviewType: one of ZONE, CHAR, WORD, LINE - - wrap: if True, will cross boundaries, including top and - bottom; if False, will stop on boundaries. - """ - - if not self.lines: - debug.printMessage(debug.LEVEL_INFO, 'goNext(): no lines in context') - return False - - moved = False - - if flatReviewType == Context.ZONE: - if self.zoneIndex < (len(self.lines[self.lineIndex].zones) - 1): - self.zoneIndex += 1 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - elif wrap & Context.WRAP_LINE: - if self.lineIndex < (len(self.lines) - 1): - self.lineIndex += 1 - self.zoneIndex = 0 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - braille.clear() - elif wrap & Context.WRAP_TOP_BOTTOM: - self.lineIndex = 0 - self.zoneIndex = 0 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - braille.clear() - elif flatReviewType == Context.CHAR: - zone = self.lines[self.lineIndex].zones[self.zoneIndex] - if zone.words: - chars = zone.words[self.wordIndex].chars - if chars: - if self.charIndex < (len(chars) - 1): - self.charIndex += 1 - moved = True - else: - moved = self.goNext(Context.WORD, wrap, False) - else: - moved = self.goNext(Context.WORD, wrap) - else: - moved = self.goNext(Context.ZONE, wrap) - elif flatReviewType == Context.WORD: - zone = self.lines[self.lineIndex].zones[self.zoneIndex] - accessible = zone.accessible - lineIndex = self.lineIndex - zoneIndex = self.zoneIndex - wordIndex = self.wordIndex - charIndex = self.charIndex - - if zone.words: - if self.wordIndex < (len(zone.words) - 1): - self.wordIndex += 1 - self.charIndex = 0 - moved = True - else: - moved = self.goNext(Context.ZONE, wrap) - else: - moved = self.goNext(Context.ZONE, wrap) - - # If we landed on a whitespace word or something with no words, - # we might need to move some more. - # - zone = self.lines[self.lineIndex].zones[self.zoneIndex] - if omitWhitespace \ - and moved \ - and ((len(zone.string) == 0) \ - or (len(zone.words) \ - and zone.words[self.wordIndex].string.isspace())): - - # If we're on whitespace in the same zone, then let's - # try to move on. If not, we've definitely moved - # across accessibles. If that's the case, let's try - # to find the first 'real' word in the accessible. - # If we cannot, then we're just stuck on an accessible - # with no words and we should do our best to announce - # this to the user (e.g., "whitespace" or "blank"). - # - if zone.accessible == accessible: - moved = self.goNext(Context.WORD, wrap) - else: - wordIndex = self.wordIndex + 1 - while wordIndex < len(zone.words): - if (not zone.words[wordIndex].string) \ - or not len(zone.words[wordIndex].string) \ - or zone.words[wordIndex].string.isspace(): - wordIndex += 1 - else: - break - if wordIndex < len(zone.words): - self.wordIndex = wordIndex - - if not moved: - self.lineIndex = lineIndex - self.zoneIndex = zoneIndex - self.wordIndex = wordIndex - self.charIndex = charIndex - - elif flatReviewType == Context.LINE: - if wrap & Context.WRAP_LINE: - if self.lineIndex < (len(self.lines) - 1): - self.lineIndex += 1 - self.zoneIndex = 0 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - elif (wrap & Context.WRAP_TOP_BOTTOM) \ - and (self.lineIndex != 0): - self.lineIndex = 0 - self.zoneIndex = 0 - self.wordIndex = 0 - self.charIndex = 0 - moved = True - else: - raise Exception("Invalid type: %d" % flatReviewType) - - if moved and (flatReviewType != Context.LINE): - self.targetCharInfo = self.getCurrent(Context.CHAR) - - return moved - - def goAbove(self, flatReviewType=LINE, wrap=WRAP_ALL): - """Moves this context's locus of interest to first char - of the type that's closest to and above the current locus of - interest. - - Arguments: - - flatReviewType: LINE - - wrap: if True, will cross top/bottom boundaries; if False, will - stop on top/bottom boundaries. - - Returns: [string, startOffset, endOffset, x, y, width, height] - """ - - moved = False - if flatReviewType == Context.CHAR: - # We want to shoot for the closest character, which we've - # saved away as self.targetCharInfo, which is the list - # [string, x, y, width, height]. - # - if not self.targetCharInfo: - self.targetCharInfo = self.getCurrent(Context.CHAR) - target = self.targetCharInfo - - [string, x, y, width, height] = target - middleTargetX = x + (width / 2) - - moved = self.goPrevious(Context.LINE, wrap) - if moved: - while True: - [string, bx, by, bwidth, bheight] = \ - self.getCurrent(Context.CHAR) - if (bx + width) >= middleTargetX: - break - elif not self.goNext(Context.CHAR, Context.WRAP_NONE): - break - - # Moving around might have reset the current targetCharInfo, - # so we reset it to our saved value. - # - self.targetCharInfo = target - elif flatReviewType == Context.LINE: - return self.goPrevious(flatReviewType, wrap) - else: - raise Exception("Invalid type: %d" % flatReviewType) - - return moved - - def goBelow(self, flatReviewType=LINE, wrap=WRAP_ALL): - """Moves this context's locus of interest to the first - char of the type that's closest to and below the current - locus of interest. - - Arguments: - - flatReviewType: one of WORD, LINE - - wrap: if True, will cross top/bottom boundaries; if False, will - stop on top/bottom boundaries. - - Returns: [string, startOffset, endOffset, x, y, width, height] - """ - - moved = False - if flatReviewType == Context.CHAR: - # We want to shoot for the closest character, which we've - # saved away as self.targetCharInfo, which is the list - # [string, x, y, width, height]. - # - if not self.targetCharInfo: - self.targetCharInfo = self.getCurrent(Context.CHAR) - target = self.targetCharInfo - - [string, x, y, width, height] = target - middleTargetX = x + (width / 2) - - moved = self.goNext(Context.LINE, wrap) - if moved: - while True: - [string, bx, by, bwidth, bheight] = \ - self.getCurrent(Context.CHAR) - if (bx + width) >= middleTargetX: - break - elif not self.goNext(Context.CHAR, Context.WRAP_NONE): - break - - # Moving around might have reset the current targetCharInfo, - # so we reset it to our saved value. - # - self.targetCharInfo = target - elif flatReviewType == Context.LINE: - moved = self.goNext(flatReviewType, wrap) - else: - raise Exception("Invalid type: %d" % flatReviewType) - - return moved -EMBEDDED_OBJECT_RE = re.compile(r"[^\ufffc]+") diff --git a/src/cthulhu/flat_review_presenter.py b/src/cthulhu/flat_review_presenter.py deleted file mode 100644 index bb0cc51..0000000 --- a/src/cthulhu/flat_review_presenter.py +++ /dev/null @@ -1,1194 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Module for flat-review commands""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2016-2023 Igalia, S.L." -__license__ = "LGPL" - -import gi -from typing import Optional, Dict, Callable, Any - -gi.require_version("Gtk", "3.0") -from gi.repository import Gtk - -from . import braille -from . import cmdnames -from . import debug -from . import flat_review -from . import guilabels -from . import input_event -from . import keybindings -from . import messages -from . import cthulhu -from . import cthulhu_state -from . import settings_manager -from . import settings - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -class FlatReviewPresenter: - """Provides access to on-screen objects via flat-review.""" - - def __init__(self) -> None: - self._context: Optional[flat_review.Context] = None - self._current_contents: str = "" - self._restrict: bool = cthulhu.cthulhuApp.settingsManager.getSetting("flatReviewIsRestricted") - self._handlers: Dict[str, Callable] = self._setup_handlers() - self._desktop_bindings: keybindings.KeyBindings = self._setup_desktop_bindings() - self._laptop_bindings: keybindings.KeyBindings = self._setup_laptop_bindings() - self._gui: Optional[Any] = None # Optional[Gtk.Window] - - def is_active(self) -> bool: - """Returns True if the flat review presenter is active.""" - - return self._context is not None - - def get_or_create_context(self, script: Optional[Any] = None) -> Optional[flat_review.Context]: - """Returns the flat review context, creating one if necessary.""" - - # TODO - JD: Scripts should not be able to interact with the - # context directly. get_or_create_context is public temporarily - # to prevent breakage. - - if not self._context: - msg = f"FLAT REVIEW PRESENTER: Creating new context. Restrict: {self._restrict}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if self._restrict: - mode, obj = cthulhu.getActiveModeAndObjectOfInterest() - self._context = flat_review.Context(script, root=obj) - else: - self._context = flat_review.Context(script) - - cthulhu.emitRegionChanged(self._context.getCurrentAccessible(), mode=cthulhu.FLAT_REVIEW) - if script is not None: - script.justEnteredFlatReviewMode = True - script.targetCursorCell = script.getBrailleCursorCell() - return self._context - - msg = f"FLAT REVIEW PRESENTER: Using existing context. Restrict: {self._restrict}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - # If we are in unrestricted mode, update the context as below. - # If the context already exists, but the active mode is not flat review, update - # the flat review location to that of the object of interest -- if the object of - # interest is in the flat review context (which means it's on screen). In some - # cases the object of interest will not be in the flat review context because it - # is represented by descendant text objects. setCurrentToZoneWithObject checks - # for this condition and if it can find a zone whose ancestor is the object of - # interest, it will set the current zone to the descendant, causing Cthulhu to - # present the text at the location of the object of interest. - mode, obj = cthulhu.getActiveModeAndObjectOfInterest() - obj = obj or cthulhu_state.locusOfFocus - if mode != cthulhu.FLAT_REVIEW and obj != self._context.getCurrentAccessible() \ - and not self._restrict: - tokens = ["FLAT REVIEW PRESENTER: Attempting to update location from", - self._context.getCurrentAccessible(), "to", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._context.setCurrentToZoneWithObject(obj) - - # If we are restricting, and the current mode is not flat review, calculate a new context - if self._restrict and mode != cthulhu.FLAT_REVIEW: - msg = "FLAT REVIEW PRESENTER: Creating new restricted context." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._context = flat_review.Context(script, obj) - - return self._context - - def get_bindings(self, is_desktop): - """Returns the flat-review-presenter keybindings.""" - - if is_desktop: - return self._desktop_bindings - return self._laptop_bindings - - def get_braille_bindings(self): - """Returns the flat-review-presenter braille bindings.""" - - bindings = {} - try: - bindings[braille.brlapi.KEY_CMD_LNUP] = \ - self._handlers.get("reviewAboveHandler") - bindings[braille.brlapi.KEY_CMD_LNDN] = \ - self._handlers.get("reviewBelowHandler") - bindings[braille.brlapi.KEY_CMD_FREEZE] = \ - self._handlers.get("toggleFlatReviewModeHandler") - bindings[braille.brlapi.KEY_CMD_TOP_LEFT] = \ - self._handlers.get("reviewHomeHandler") - bindings[braille.brlapi.KEY_CMD_BOT_LEFT] = \ - self._handlers.get("reviewBottomLeftHandler") - except Exception as error: - tokens = ["FLAT REVIEW PRESENTER: Exception getting braille bindings:", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return {} - return bindings - - def get_handlers(self): - """Returns the flat-review-presenter handlers.""" - - return self._handlers - - def _setup_handlers(self): - """Sets up and returns the flat-review-presenter input event handlers.""" - - handlers = {} - - handlers["toggleFlatReviewModeHandler"] = \ - input_event.InputEventHandler( - self.toggle_flat_review_mode, - cmdnames.TOGGLE_FLAT_REVIEW) - - handlers["reviewHomeHandler"] = \ - input_event.InputEventHandler( - self.go_home, - cmdnames.REVIEW_HOME) - - handlers["reviewEndHandler"] = \ - input_event.InputEventHandler( - self.go_end, - cmdnames.REVIEW_END) - - handlers["reviewBottomLeftHandler"] = \ - input_event.InputEventHandler( - self.go_bottom_left, - cmdnames.REVIEW_BOTTOM_LEFT) - - handlers["reviewPreviousLineHandler"] = \ - input_event.InputEventHandler( - self.go_previous_line, - cmdnames.REVIEW_PREVIOUS_LINE) - - handlers["reviewCurrentLineHandler"] = \ - input_event.InputEventHandler( - self.present_line, - cmdnames.REVIEW_CURRENT_LINE) - - handlers["reviewNextLineHandler"] = \ - input_event.InputEventHandler( - self.go_next_line, - cmdnames.REVIEW_NEXT_LINE) - - handlers["reviewSpellCurrentLineHandler"] = \ - input_event.InputEventHandler( - self.spell_line, - cmdnames.REVIEW_SPELL_CURRENT_LINE) - - handlers["reviewPhoneticCurrentLineHandler"] = \ - input_event.InputEventHandler( - self.phonetic_line, - cmdnames.REVIEW_PHONETIC_CURRENT_LINE) - - handlers["reviewEndOfLineHandler"] = \ - input_event.InputEventHandler( - self.go_end_of_line, - cmdnames.REVIEW_END_OF_LINE) - - handlers["reviewPreviousItemHandler"] = \ - input_event.InputEventHandler( - self.go_previous_item, - cmdnames.REVIEW_PREVIOUS_ITEM) - - handlers["reviewCurrentItemHandler"] = \ - input_event.InputEventHandler( - self.present_item, - cmdnames.REVIEW_CURRENT_ITEM) - - handlers["reviewNextItemHandler"] = \ - input_event.InputEventHandler( - self.go_next_item, - cmdnames.REVIEW_NEXT_ITEM) - - handlers["reviewSpellCurrentItemHandler"] = \ - input_event.InputEventHandler( - self.spell_item, - cmdnames.REVIEW_SPELL_CURRENT_ITEM) - - handlers["reviewPhoneticCurrentItemHandler"] = \ - input_event.InputEventHandler( - self.phonetic_item, - cmdnames.REVIEW_PHONETIC_CURRENT_ITEM) - - handlers["reviewPreviousCharacterHandler"] = \ - input_event.InputEventHandler( - self.go_previous_character, - cmdnames.REVIEW_PREVIOUS_CHARACTER) - - handlers["reviewCurrentCharacterHandler"] = \ - input_event.InputEventHandler( - self.present_character, - cmdnames.REVIEW_CURRENT_CHARACTER) - - handlers["reviewSpellCurrentCharacterHandler"] = \ - input_event.InputEventHandler( - self.spell_character, - cmdnames.REVIEW_SPELL_CURRENT_CHARACTER) - - handlers["reviewUnicodeCurrentCharacterHandler"] = \ - input_event.InputEventHandler( - self.unicode_current_character, - cmdnames.REVIEW_UNICODE_CURRENT_CHARACTER) - - handlers["reviewNextCharacterHandler"] = \ - input_event.InputEventHandler( - self.go_next_character, - cmdnames.REVIEW_NEXT_CHARACTER) - - handlers["reviewCurrentAccessibleHandler"] = \ - input_event.InputEventHandler( - self.present_object, - cmdnames.REVIEW_CURRENT_ACCESSIBLE) - - handlers["reviewAboveHandler"] = \ - input_event.InputEventHandler( - self.go_above, - cmdnames.REVIEW_ABOVE) - - handlers["reviewBelowHandler"] = \ - input_event.InputEventHandler( - self.go_below, - cmdnames.REVIEW_BELOW) - - handlers["showContentsHandler"] = \ - input_event.InputEventHandler( - self.show_contents, - cmdnames.FLAT_REVIEW_SHOW_CONTENTS) - - handlers["flatReviewCopyHandler"] = \ - input_event.InputEventHandler( - self.copy_to_clipboard, - cmdnames.FLAT_REVIEW_COPY) - - handlers["flatReviewAppendHandler"] = \ - input_event.InputEventHandler( - self.append_to_clipboard, - cmdnames.FLAT_REVIEW_APPEND) - - handlers["flatReviewSayAllHandler"] = \ - input_event.InputEventHandler( - self.say_all, - cmdnames.SAY_ALL_FLAT_REVIEW) - - handlers["flatReviewToggleRestrictHandler"] = \ - input_event.InputEventHandler( - self.toggle_restrict, - cmdnames.TOGGLE_RESTRICT_FLAT_REVIEW) - - return handlers - - def _setup_desktop_bindings(self): - """Sets up and returns the flat-review-presenter desktop key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "KP_Subtract", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("toggleFlatReviewModeHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Add", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("flatReviewSayAllHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "KP_Home", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewHomeHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Home", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewPreviousLineHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Up", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewCurrentLineHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "KP_Up", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewSpellCurrentLineHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "KP_Up", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewPhoneticCurrentLineHandler"), - 3)) - - bindings.add( - keybindings.KeyBinding( - "KP_Page_Up", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewNextLineHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Page_Up", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewEndHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Left", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewPreviousItemHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Left", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewAboveHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Begin", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewCurrentItemHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "KP_Begin", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewSpellCurrentItemHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "KP_Begin", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewPhoneticCurrentItemHandler"), - 3)) - - bindings.add( - keybindings.KeyBinding( - "KP_Begin", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewCurrentAccessibleHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Right", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewNextItemHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Right", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewBelowHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_End", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewPreviousCharacterHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_End", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewEndOfLineHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Down", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewCurrentCharacterHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "KP_Down", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewSpellCurrentCharacterHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "KP_Down", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewUnicodeCurrentCharacterHandler"), - 3)) - - bindings.add( - keybindings.KeyBinding( - "KP_Page_Down", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("reviewNextCharacterHandler"))) - - bindings.add( - keybindings.KeyBinding( - "f", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK | keybindings.SHIFT_MODIFIER_MASK, - self._handlers.get("showContentsHandler"))) - - bindings.add( - keybindings.KeyBinding( - "c", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("flatReviewCopyHandler"))) - - bindings.add( - keybindings.KeyBinding( - "c", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK | keybindings.SHIFT_MODIFIER_MASK, - self._handlers.get("flatReviewAppendHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("flatReviewToggleRestrictHandler"))) - - return bindings - - def _setup_laptop_bindings(self): - """Sets up and returns the flat-review-presenter laptop key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "p", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("toggleFlatReviewModeHandler"))) - - bindings.add( - keybindings.KeyBinding( - "semicolon", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("flatReviewSayAllHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "u", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewPreviousLineHandler"))) - - bindings.add( - keybindings.KeyBinding( - "u", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("reviewHomeHandler"))) - - bindings.add( - keybindings.KeyBinding( - "i", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewCurrentLineHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "i", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewSpellCurrentLineHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "i", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewPhoneticCurrentLineHandler"), - 3)) - - bindings.add( - keybindings.KeyBinding( - "o", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewNextLineHandler"))) - - bindings.add( - keybindings.KeyBinding( - "o", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("reviewEndHandler"))) - - bindings.add( - keybindings.KeyBinding( - "j", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewPreviousItemHandler"))) - - bindings.add( - keybindings.KeyBinding( - "j", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("reviewAboveHandler"))) - - bindings.add( - keybindings.KeyBinding( - "k", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewCurrentItemHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "k", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewSpellCurrentItemHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "k", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewPhoneticCurrentItemHandler"), - 3)) - - bindings.add( - keybindings.KeyBinding( - "k", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("reviewCurrentAccessibleHandler"))) - - bindings.add( - keybindings.KeyBinding( - "l", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewNextItemHandler"))) - - bindings.add( - keybindings.KeyBinding( - "l", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("reviewBelowHandler"))) - - bindings.add( - keybindings.KeyBinding( - "m", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewPreviousCharacterHandler"))) - - bindings.add( - keybindings.KeyBinding( - "m", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("reviewEndOfLineHandler"))) - - bindings.add( - keybindings.KeyBinding( - "comma", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewCurrentCharacterHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "comma", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewSpellCurrentCharacterHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "comma", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewUnicodeCurrentCharacterHandler"), - 3)) - - bindings.add( - keybindings.KeyBinding( - "period", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("reviewNextCharacterHandler"))) - - bindings.add( - keybindings.KeyBinding( - "f", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK | keybindings.SHIFT_MODIFIER_MASK, - self._handlers.get("showContentsHandler"))) - - bindings.add( - keybindings.KeyBinding( - "c", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("flatReviewCopyHandler"))) - - bindings.add( - keybindings.KeyBinding( - "c", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK | keybindings.SHIFT_MODIFIER_MASK, - self._handlers.get("flatReviewAppendHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("flatReviewToggleRestrictHandler"))) - - return bindings - - def start(self, script=None, event=None): - """Starts flat review.""" - - if self._context: - msg = "FLAT REVIEW PRESENTER: Already in flat review" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - msg = "FLAT REVIEW PRESENTER: Starting flat review" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if script is None: - script = cthulhu_state.activeScript - - self.get_or_create_context(script) - if event is None: - return - - if cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') != settings.VERBOSITY_LEVEL_BRIEF: - script.presentMessage(messages.FLAT_REVIEW_START) - self._item_presentation(script, event, script.targetCursorCell) - - def quit(self, script=None, event=None): - """Quits flat review.""" - - if self._context is None: - msg = "FLAT REVIEW PRESENTER: Not in flat review" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - msg = "FLAT REVIEW PRESENTER: Quitting flat review" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self._context = None - cthulhu.emitRegionChanged(cthulhu_state.locusOfFocus, mode=cthulhu.FOCUS_TRACKING) - - if event is None or script is None: - return - - if cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') != settings.VERBOSITY_LEVEL_BRIEF: - script.presentMessage(messages.FLAT_REVIEW_STOP) - script.updateBraille(cthulhu_state.locusOfFocus) - - def toggle_flat_review_mode(self, script, event=None): - """Toggles between flat review mode and focus tracking mode.""" - - if self.is_active(): - self.quit(script, event) - return True - - self.start(script, event) - return True - - def go_home(self, script, event=None): - """Moves to the top left of the current window.""" - - self._context = self.get_or_create_context(script) - self._context.goBegin(flat_review.Context.WINDOW) - self.present_line(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def go_end(self, script, event=None): - """Moves to the bottom right of the current window.""" - - self._context = self.get_or_create_context(script) - self._context.goEnd(flat_review.Context.WINDOW) - self.present_line(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def go_bottom_left(self, script, event=None): - """Moves to the bottom left of the current window.""" - - self._context = self.get_or_create_context(script) - self._context.goEnd(flat_review.Context.WINDOW) - self._context.goBegin(flat_review.Context.LINE) - self.present_line(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def go_previous_line(self, script, event=None): - """Moves to the previous line.""" - - self._context = self.get_or_create_context(script) - if self._context.goPrevious(flat_review.Context.LINE, flat_review.Context.WRAP_LINE): - self.present_line(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def present_line(self, script, event=None): - """Presents the current line.""" - - self._line_presentation(script, event, 1) - return True - - def go_next_line(self, script, event=None): - """Moves to the next line.""" - - self._context = self.get_or_create_context(script) - if self._context.goNext(flat_review.Context.LINE, flat_review.Context.WRAP_LINE): - self.present_line(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def spell_line(self, script, event=None): - """Presents the current line letter by letter.""" - - self._line_presentation(script, event, 2) - return True - - def phonetic_line(self, script, event=None): - """Presents the current line letter by letter phonetically.""" - - self._line_presentation(script, event, 3) - return True - - def go_start_of_line(self, script, event=None): - """Moves to the beginning of the current line.""" - - self._context = self.get_or_create_context(script) - self._context.goEnd(flat_review.Context.LINE) - self.present_character(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def go_end_of_line(self, script, event=None): - """Moves to the end of the line.""" - - self._context = self.get_or_create_context(script) - self._context.goEnd(flat_review.Context.LINE) - self.present_character(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def go_previous_item(self, script, event=None): - """Moves to the previous item or word.""" - - self._context = self.get_or_create_context(script) - if self._context.goPrevious(flat_review.Context.WORD, flat_review.Context.WRAP_LINE): - self.present_item(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def present_item(self, script, event=None, target_cursor_cell=0): - """Presents the current item/word.""" - - self._item_presentation(script, event, target_cursor_cell, 1) - return True - - def go_next_item(self, script, event=None): - """Moves to the next item or word.""" - - self._context = self.get_or_create_context(script) - if self._context.goNext(flat_review.Context.WORD, flat_review.Context.WRAP_LINE): - self.present_item(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - - return True - - def spell_item(self, script, event=None): - """Presents the current item/word letter by letter.""" - - self._item_presentation(script, event, script.targetCursorCell, 2) - return True - - def phonetic_item(self, script, event=None): - """Presents the current word letter by letter phonetically.""" - - self._item_presentation(script, event, script.targetCursorCell, 3) - return True - - def go_previous_character(self, script, event=None): - """Moves to the previous character.""" - - self._context = self.get_or_create_context(script) - if self._context.goPrevious(flat_review.Context.CHAR, flat_review.Context.WRAP_LINE): - self.present_character(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def present_character(self, script, event=None): - """Presents the current character.""" - - self._character_presentation(script, event, 1) - return True - - def go_next_character(self, script, event=None): - """Moves to the next character.""" - - self._context = self.get_or_create_context(script) - if self._context.goNext(flat_review.Context.CHAR, flat_review.Context.WRAP_LINE): - self.present_character(script, event) - script.targetCursorCell = script.getBrailleCursorCell() - return True - - def spell_character(self, script, event=None): - """Presents the current character phonetically.""" - - self._character_presentation(script, event, 2) - return True - - def unicode_current_character(self, script, event=None): - """Presents the current character's unicode value.""" - - self._character_presentation(script, event, 3) - return True - - def go_above(self, script, event=None): - """Moves to the character above.""" - - self._context = self.get_or_create_context(script) - if self._context.goAbove(flat_review.Context.CHAR, flat_review.Context.WRAP_LINE): - self.present_item(script, event, script.targetCursorCell) - return True - - def go_below(self, script, event=None): - """Moves to the character below.""" - - self._context = self.get_or_create_context(script) - if self._context.goBelow(flat_review.Context.CHAR, flat_review.Context.WRAP_LINE): - self.present_item(script, event, script.targetCursorCell) - return True - - def get_current_object(self, script, event=None): - """Returns the current accessible object.""" - - self._context = self.get_or_create_context(script) - return self._context.getCurrentAccessible() - - def present_object(self, script, event=None): - """Presents the current accessible object.""" - - self._context = self.get_or_create_context(script) - if not isinstance(event, input_event.BrailleEvent): - script.presentObject(self._context.getCurrentAccessible(), speechonly=True) - - cthulhu.emitRegionChanged(self._context.getCurrentAccessible(), mode=cthulhu.FLAT_REVIEW) - return True - - def left_click_on_object(self, script, event=None): - """Attempts to synthesize a left click on the current accessible.""" - - self._context = self.get_or_create_context(script) - return self._context.clickCurrent(1) - - def right_click_on_object(self, script, event=None): - """Attempts to synthesize a left click on the current accessible.""" - - self._context = self.get_or_create_context(script) - return self._context.clickCurrent(3) - - def route_pointer_to_object(self, script, event=None): - """Routes the mouse pointer to the current accessible.""" - - self._context = self.get_or_create_context(script) - return self._context.routeToCurrent() - - def get_braille_regions(self, script, event=None): - """Returns the braille regions and region with focus being reviewed.""" - - self._context = self.get_or_create_context(script) - regions, focused_region = self._context.getCurrentBrailleRegions() - return [regions, focused_region] - - def _get_all_lines(self, script, event=None): - """Returns a list of textual lines representing the contents.""" - - lines = [] - self._context = self.get_or_create_context(script) - self._context.goBegin(flat_review.Context.WINDOW) - string = self._context.getCurrent(flat_review.Context.LINE)[0] - while string is not None: - lines.append(string.rstrip("\n")) - if not self._context.goNext(flat_review.Context.LINE, flat_review.Context.WRAP_LINE): - break - string = self._context.getCurrent(flat_review.Context.LINE)[0] - return lines - - def say_all(self, script, event=None): - """Speaks the contents of the entire window.""" - - for string in self._get_all_lines(script, event): - if not string.isspace(): - script.speakMessage(string, script.speechGenerator.voice(string=string)) - - return True - - def show_contents(self, script, event=None): - """Displays the entire flat review contents in a text view.""" - - msg = "FLAT REVIEW PRESENTER: Showing contents." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - text = "\n".join(self._get_all_lines(script, event)) - title = guilabels.FLAT_REVIEW_CONTENTS - self._gui = FlatReviewContextGUI(script, title, text) - self._gui.show_gui() - return True - - def copy_to_clipboard(self, script, event=None): - """Copies the string just presented to the clipboard.""" - - if not self.is_active(): - script.presentMessage(messages.FLAT_REVIEW_NOT_IN) - return True - - script.utilities.setClipboardText(self._current_contents.rstrip("\n")) - script.presentMessage(messages.FLAT_REVIEW_COPIED) - return True - - def append_to_clipboard(self, script, event=None): - """Appends the string just presented to the clipboard.""" - - if not self.is_active(): - script.presentMessage(messages.FLAT_REVIEW_NOT_IN) - return True - - script.utilities.appendTextToClipboard(self._current_contents.rstrip("\n")) - script.presentMessage(messages.FLAT_REVIEW_APPENDED) - return True - - def toggle_restrict(self, script, event=None): - """ Toggles the restricting of flat review to the current object. """ - - self._restrict = not self._restrict - cthulhu.cthulhuApp.settingsManager.setSetting("flatReviewIsRestricted", self._restrict) - - if self._restrict: - script.presentMessage(messages.FLAT_REVIEW_RESTRICTED) - else: - script.presentMessage(messages.FLAT_REVIEW_UNRESTRICTED) - if self.is_active(): - # Reset the context - self._context = None - self.start() - - return True - - def _line_presentation(self, script, event, speech_type=1): - """Presents the current line.""" - - self._context = self.get_or_create_context(script) - line_string = self._context.getCurrent(flat_review.Context.LINE)[0] or "" - voice = script.speechGenerator.voice(string=line_string) - - if not isinstance(event, input_event.BrailleEvent): - if not line_string or line_string == "\n": - script.speakMessage(messages.BLANK) - elif line_string.isspace(): - script.speakMessage(messages.WHITE_SPACE) - elif line_string.isupper() and (speech_type < 2 or speech_type > 3): - script.speakMessage(line_string, voice) - elif speech_type == 2: - script.spellCurrentItem(line_string) - elif speech_type == 3: - script.phoneticSpellCurrentItem(line_string) - else: - line_string = script.utilities.adjustForRepeats(line_string) - script.speakMessage(line_string, voice) - - cthulhu.emitRegionChanged(self._context.getCurrentAccessible(), mode=cthulhu.FLAT_REVIEW) - script.updateBrailleReview() - self._current_contents = line_string - return True - - def _item_presentation(self, script, event, target_cursor_cell=0, speech_type=1): - """Presents the current item/word.""" - - self._context = self.get_or_create_context(script) - word_string = self._context.getCurrent(flat_review.Context.WORD)[0] or "" - voice = script.speechGenerator.voice(string=word_string) - if not isinstance(event, input_event.BrailleEvent): - if not word_string or word_string == "\n": - script.speakMessage(messages.BLANK) - else: - line_string = self._context.getCurrent(flat_review.Context.LINE)[0] or "" - if line_string == "\n": - script.speakMessage(messages.BLANK) - elif word_string.isspace(): - script.speakMessage(messages.WHITE_SPACE) - elif word_string.isupper() and speech_type == 1: - script.speakMessage(word_string, voice) - elif speech_type == 2: - script.spellCurrentItem(word_string) - elif speech_type == 3: - script.phoneticSpellCurrentItem(word_string) - elif speech_type == 1: - word_string = script.utilities.adjustForRepeats(word_string) - script.speakMessage(word_string, voice) - - cthulhu.emitRegionChanged(self._context.getCurrentAccessible(), mode=cthulhu.FLAT_REVIEW) - script.updateBrailleReview(target_cursor_cell) - self._current_contents = word_string - return True - - def _character_presentation(self, script, event, speech_type=1): - """Presents the current character.""" - - self._context = self.get_or_create_context(script) - char_string = self._context.getCurrent(flat_review.Context.CHAR)[0] or "" - if not isinstance(event, input_event.BrailleEvent): - if not char_string: - script.speakMessage(messages.BLANK) - else: - line_string = self._context.getCurrent(flat_review.Context.LINE)[0] or "" - if line_string == "\n" and speech_type != 3: - script.speakMessage(messages.BLANK) - elif speech_type == 3: - script.speakUnicodeCharacter(char_string) - elif speech_type == 2: - script.phoneticSpellCurrentItem(char_string) - else: - script.speakCharacter(char_string) - - cthulhu.emitRegionChanged(self._context.getCurrentAccessible(), mode=cthulhu.FLAT_REVIEW) - script.updateBrailleReview() - self._current_contents = char_string - return True - -class FlatReviewContextGUI: - """Presents the entire flat review context in a text view""" - - def __init__(self, script, title, text): - self._script = script - self._gui = self._create_dialog(title, text) - - def _create_dialog(self, title, text): - """Creates the dialog.""" - - dialog = Gtk.Dialog(title, - None, - Gtk.DialogFlags.MODAL, - (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)) - dialog.set_default_size(800, 600) - - scrolled_window = Gtk.ScrolledWindow() - scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - - textbuffer = Gtk.TextBuffer() - textbuffer.set_text(text) - textbuffer.place_cursor(textbuffer.get_start_iter()) - textview = Gtk.TextView(buffer=textbuffer) - textview.set_wrap_mode(Gtk.WrapMode.WORD) - - scrolled_window.add(textview) - scrolled_window.set_hexpand(True) - scrolled_window.set_vexpand(True) - - dialog.get_content_area().pack_start(scrolled_window, True, True, 0) - dialog.connect("response", self.on_response) - - return dialog - - def on_response(self, dialog, response): - """Handler for the 'response' signal of the dialog.""" - - if response == Gtk.ResponseType.CLOSE: - self._gui.destroy() - - def show_gui(self): - """Shows the dialog.""" - - self._gui.show_all() - time_stamp = cthulhu_state.lastInputEvent.timestamp - if time_stamp == 0: - time_stamp = Gtk.get_current_event_time() - self._gui.present_with_time(time_stamp) - - -_presenter = None -def getPresenter(): - """Returns the Flat Review Presenter""" - - global _presenter - if _presenter is None: - _presenter = FlatReviewPresenter() - return _presenter diff --git a/src/cthulhu/focus_manager.py b/src/cthulhu/focus_manager.py deleted file mode 100644 index 8391150..0000000 --- a/src/cthulhu/focus_manager.py +++ /dev/null @@ -1,489 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2005-2008 Sun Microsystems Inc. -# Copyright 2016-2023 Igalia, S.L. -# -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-instance-attributes -# pylint: disable=too-many-public-methods - -"""Module to manage the focused object, window, etc.""" - -# This has to be the first non-docstring line in the module to make linters happy. -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2016-2023 Igalia, S.L." -__license__ = "LGPL" - -from typing import TYPE_CHECKING, Optional, Tuple, Any - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import braille -from . import cthulhu_state -from . import dbus_service -from . import debug -from . import script_manager -from .ax_object import AXObject -from .ax_table import AXTable -from .ax_text import AXText - -if TYPE_CHECKING: - from .cthulhu import Cthulhu - from .input_event import InputEvent - from .scripts import default - -def _get_ax_utilities() -> Any: - # Avoid circular import with ax_utilities -> ax_utilities_event -> focus_manager. - from .ax_utilities import AXUtilities - return AXUtilities - -def _log(message: str, reason: Optional[str] = None, timestamp: bool = True, stack: bool = False) -> None: - debug.print_log(debug.LEVEL_INFO, "FOCUS MANAGER", message, reason, timestamp, stack) - -def _log_tokens(tokens: list, reason: Optional[str] = None, timestamp: bool = True, stack: bool = False) -> None: - debug.print_log_tokens(debug.LEVEL_INFO, "FOCUS MANAGER", tokens, reason, timestamp, stack) - -CARET_TRACKING = "caret-tracking" -FOCUS_TRACKING = "focus-tracking" -FLAT_REVIEW = "flat-review" -MOUSE_REVIEW = "mouse-review" -OBJECT_NAVIGATOR = "object-navigator" -SAY_ALL = "say-all" - - -class FocusManager: - """Manages the focused object, window, etc.""" - - def __init__(self, app: Cthulhu) -> None: - self.app: Cthulhu = app # Store app instance - self._window: Optional[Atspi.Accessible] = cthulhu_state.activeWindow - self._focus: Optional[Atspi.Accessible] = cthulhu_state.locusOfFocus - self._object_of_interest: Optional[Atspi.Accessible] = cthulhu_state.objOfInterest - self._active_mode: Optional[str] = cthulhu_state.activeMode - self._last_cell_coordinates: Tuple[int, int] = (-1, -1) - self._last_cursor_position: Tuple[Optional[Atspi.Accessible], int] = (None, -1) - self._penultimate_cursor_position: Tuple[Optional[Atspi.Accessible], int] = (None, -1) - - _log("Registering D-Bus commands.") - controller = dbus_service.get_remote_controller() - controller.register_decorated_module("FocusManager", self) - - def clear_state(self, reason: str = "") -> None: - """Clears everything we're tracking.""" - - _log("Clearing all state", reason) - self._focus = None - self._window = None - self._object_of_interest = None - self._active_mode = None - cthulhu_state.locusOfFocus = None - cthulhu_state.activeWindow = None - cthulhu_state.objOfInterest = None - cthulhu_state.activeMode = None - - def find_focused_object(self) -> Optional[Atspi.Accessible]: - """Returns the focused object in the active window.""" - - result = _get_ax_utilities().get_focused_object(self._window) - _log_tokens(["Focused object in", self._window, "is", result]) - return result - - def active_window_is_cthulhu(self) -> bool: - """Returns True if the active window belongs to Cthulhu itself.""" - - app = AXObject.get_application(self._window) - appName = (AXObject.get_name(app) or "").lower() - return appName == "cthulhu" - - def focus_and_window_are_unknown(self) -> bool: - """Returns True if we have no knowledge about what is focused.""" - - result = self._focus is None and self._window is None - if result: - _log("Focus and window are unknown") - - return result - - def focus_is_dead(self) -> bool: - """Returns True if the locus of focus is dead.""" - - if not AXObject.is_dead(self._focus): - return False - - _log("Focus is dead", "dead-focus") - return True - - def focus_is_active_window(self) -> bool: - """Returns True if the locus of focus is the active window.""" - - if self._focus is None: - return False - - return self._focus == self._window - - def focus_is_in_active_window(self) -> bool: - """Returns True if the locus of focus is inside the current window.""" - - return self._focus is not None and AXObject.is_ancestor(self._focus, self._window) - - def emit_region_changed( - self, obj: Atspi.Accessible, - start_offset: Optional[int] = None, - end_offset: Optional[int] = None, - mode: Optional[str] = None - ) -> None: - """Notifies interested clients that the current region of interest has changed.""" - - if start_offset is None: - start_offset = 0 - if end_offset is None: - end_offset = start_offset - if mode is None: - mode = FOCUS_TRACKING - - if obj is not None: - obj.emit("mode-changed::" + mode, 1, "") - - if mode != self._active_mode: - _log_tokens(["Switching mode from", self._active_mode, "to", mode]) - self._active_mode = mode - cthulhu_state.activeMode = mode - if mode == FLAT_REVIEW: - braille.setBrlapiPriority(braille.BRLAPI_PRIORITY_HIGH) - else: - braille.setBrlapiPriority() - - _log_tokens(["Region of interest:", obj, f"({start_offset}, {end_offset})"]) - if obj is not None: - obj.emit("region-changed", start_offset, end_offset) - - if obj != self._object_of_interest: - _log_tokens(["Switching object of interest from", self._object_of_interest, "to", obj]) - self._object_of_interest = obj - cthulhu_state.objOfInterest = obj - - def in_say_all(self) -> bool: - """Returns True if we are in say-all mode.""" - - return self._active_mode == SAY_ALL - - def get_active_mode_and_object_of_interest( - self - ) -> Tuple[Optional[str], Optional[Atspi.Accessible]]: - """Returns the current mode and associated object of interest""" - - _log_tokens(["Active mode:", self._active_mode, "Object of interest:", self._object_of_interest]) - return self._active_mode, self._object_of_interest - - def get_penultimate_cursor_position(self) -> Tuple[Optional[Atspi.Accessible], int]: - """Returns the penultimate cursor position as a tuple of (object, offset).""" - - obj, offset = self._penultimate_cursor_position - _log_tokens(["Penultimate cursor position:", obj, offset]) - return obj, offset - - def get_last_cursor_position(self) -> Tuple[Optional[Atspi.Accessible], int]: - """Returns the last cursor position as a tuple of (object, offset).""" - - obj, offset = self._last_cursor_position - _log_tokens(["Last cursor position:", obj, offset]) - return obj, offset - - def set_last_cursor_position(self, obj: Optional[Atspi.Accessible], offset: int) -> None: - """Sets the last cursor position as a tuple of (object, offset).""" - - _log_tokens(["Setting last cursor position to", obj, offset]) - self._penultimate_cursor_position = self._last_cursor_position - self._last_cursor_position = obj, offset - - def get_last_cell_coordinates(self) -> Tuple[int, int]: - """Returns the last known cell coordinates as a tuple of (row, column).""" - - row, column = self._last_cell_coordinates - _log(f"Last known cell coordinates: row={row}, column={column}") - return row, column - - def set_last_cell_coordinates(self, row: int, column: int) -> None: - """Sets the last known cell coordinates as a tuple of (row, column).""" - - _log(f"Setting last cell coordinates to row={row}, column={column}") - self._last_cell_coordinates = row, column - - def get_locus_of_focus(self) -> Optional[Atspi.Accessible]: - """Returns the current locus of focus (i.e. the object with visual focus).""" - - _log_tokens(["Locus of focus is", self._focus]) - return self._focus - - def set_locus_of_focus( - self, - event: Optional[Atspi.Event], - obj: Optional[Atspi.Accessible], - notify_script: bool = True, - force: bool = False - ) -> None: - """Sets the locus of focus (i.e., the object with visual focus).""" - - _log_tokens(["Request to set locus of focus to", obj], stack=True) - - # We clear the cache on the locus of focus because too many apps and toolkits fail - # to emit the correct accessibility events. We do so recursively on table cells - # to handle bugs like https://gitlab.gnome.org/GNOME/nautilus/-/issues/3253. - recursive = _get_ax_utilities().is_table_cell(obj) - AXObject.clear_cache(obj, recursive, "Setting locus of focus.") - if not force and obj == self._focus: - _log("Setting locus of focus to existing locus of focus", "no-change") - return - - # We save the current row and column of a newly focused or selected table cell so that on - # subsequent cell focus/selection we only present the changed location. - row, column = AXTable.get_cell_coordinates(obj, find_cell=True) - self.set_last_cell_coordinates(row, column) - - # We save the offset for text objects because some apps and toolkits emit caret-moved events - # immediately after a text object gains focus, even though the caret has not actually moved. - # TODO - JD: We should consider making this part of `save_object_info_for_events()` for the - # motivation described above. However, we need to audit callers that set/get the position - # before doing so. - self.set_last_cursor_position(obj, AXText.get_caret_offset(obj)) - AXText.update_cached_selected_text(obj) - - # We save additional information about the object for events that were received at the same - # time as the prioritized focus-change event so we don't double-present aspects about obj. - _get_ax_utilities().save_object_info_for_events(obj) - - # TODO - JD: Consider always updating the active script here. - script = self.app.scriptManager.get_active_script() - if event and (script and not script.app): - app = _get_ax_utilities().get_application(event.source) - script = self.app.scriptManager.get_script(app, event.source) - self.app.scriptManager.activate_script_for_context(app, event.source, "focus: locus-of-focus") - - old_focus = self._focus - if AXObject.is_dead(old_focus): - old_focus = None - - if obj is None: - _log("New locus of focus is null (being cleared)", "clearing") - self._focus = None - cthulhu_state.locusOfFocus = None - return - - if AXObject.is_dead(obj): - _log_tokens(["New locus of focus", obj, "is dead. Not updating."], "dead") - return - - if script is not None: - if not AXObject.is_valid(obj): - _log_tokens(["New locus of focus", obj, "is invalid. Not updating."], "invalid") - return - - _log_tokens(["Changing locus of focus from", old_focus, "to", obj, ". Notify:", notify_script]) - self._focus = obj - cthulhu_state.locusOfFocus = obj - - if not notify_script: - return - - if script is None: - _log("Cannot notify active script because there isn't one", "no-active-script") - return - - self.emit_region_changed(obj, mode=FOCUS_TRACKING) - script.locus_of_focus_changed(event, old_focus, self._focus) - - def active_window_is_active(self) -> bool: - """Returns True if the window we think is currently active is actually active.""" - - AXObject.clear_cache(self._window, False, "Ensuring the active window is really active.") - is_active = _get_ax_utilities().is_active(self._window) - _log_tokens([self._window, "is active:", is_active]) - return is_active - - def get_active_window(self) -> Optional[Atspi.Accessible]: - """Returns the currently-active window (i.e. without searching or verifying).""" - - _log_tokens(["Active window is", self._window], stack=True) - return self._window - - def set_active_window( - self, - frame: Optional[Atspi.Accessible], - app: Optional[Atspi.Accessible] = None, - set_window_as_focus: bool = False, - notify_script: bool = False - ) -> None: - """Sets the active window.""" - - tokens = ["Request to set active window to", frame] - if app is not None: - tokens.extend(["in", app]) - _log_tokens(tokens) - - if frame is None and AXObject.has_broken_popup_ancestry(self._focus): - _log_tokens( - ["Not clearing active window; focus", self._focus, "is in popup with broken ancestry"], - "broken-popup-ancestry", - ) - return - - if frame == self._window: - _log("Setting active window to existing active window", "no-change") - elif frame is None: - self._window = None - cthulhu_state.activeWindow = None - else: - self._window = frame - cthulhu_state.activeWindow = frame - - contextObject = self._focus - if set_window_as_focus: - self.set_locus_of_focus(None, self._window, notify_script) - elif not (self.focus_is_active_window() or self.focus_is_in_active_window()): - _log_tokens(["Focus", self._focus, "is not in", self._window], stack=True) - - if self.active_window_is_cthulhu(): - _log_tokens( - ["Skipping focused-object lookup and script activation for self-hosted window", self._window], - "self-window", - ) - return - else: - focusedObject = self.find_focused_object() - if focusedObject is not None and focusedObject != self._window: - _log_tokens(["Using focused object", focusedObject, "from active window", self._window]) - self.set_locus_of_focus(None, focusedObject, notify_script=True) - contextObject = focusedObject - elif self._focus is None: - _log_tokens(["No previous focus. Falling back to active window", self._window]) - self.set_locus_of_focus(None, self._window, notify_script=True) - contextObject = self._window - # Don't update the focus to the active window if we can't get to the active window - # from the focused object. https://bugreports.qt.io/browse/QTBUG-130116 - elif not AXObject.has_broken_ancestry(self._focus): - self.set_locus_of_focus(None, self._window, notify_script=True) - contextObject = self._window - - if contextObject is None: - contextObject = self._window - - app = _get_ax_utilities().get_application(contextObject) - self.app.scriptManager.activate_script_for_context(app, contextObject, "focus: active-window") - - @dbus_service.command - def toggle_presentation_mode( - self, - script: default.Script, - event: Optional[InputEvent] = None, - notify_user: bool = True - ) -> bool: - """Switches between browse mode and focus mode (web content only).""" - - return script.toggle_presentation_mode(event, document=None, notify_user=notify_user) - - @dbus_service.command - def toggle_layout_mode( - self, - script: default.Script, - event: Optional[InputEvent] = None, - notify_user: bool = True - ) -> bool: - """Switches between object mode and layout mode for line presentation (web content only).""" - - return script.toggle_layout_mode(event, notify_user=notify_user) - - @dbus_service.command - def enable_sticky_browse_mode( - self, - script: default.Script, - event: Optional[InputEvent] = None, - notify_user: bool = True - ) -> bool: - """Enables sticky browse mode (web content only).""" - - return script.enable_sticky_browse_mode(event, force_message=notify_user) - - @dbus_service.command - def enable_sticky_focus_mode( - self, - script: default.Script, - event: Optional[InputEvent] = None, - notify_user: bool = True - ) -> bool: - """Enables sticky focus mode (web content only).""" - - return script.enable_sticky_focus_mode(event, force_message=notify_user) - - @dbus_service.getter - def get_in_layout_mode(self) -> bool: - """Returns True if layout mode (as opposed to object mode) is active (web content only).""" - - if script := self.app.scriptManager.get_active_script(): - return script.in_layout_mode() - return False - - @dbus_service.getter - def get_in_focus_mode(self) -> bool: - """Returns True if focus mode is active (web content only).""" - - if script := self.app.scriptManager.get_active_script(): - return script.in_focus_mode() - return False - - @dbus_service.getter - def get_focus_mode_is_sticky(self) -> bool: - """Returns True if focus mode is active and 'sticky' (web content only).""" - - if script := self.app.scriptManager.get_active_script(): - return script.focus_mode_is_sticky() - return False - - @dbus_service.getter - def get_browse_mode_is_sticky(self) -> bool: - """Returns True if browse mode is active and 'sticky' (web content only).""" - - if script := self.app.scriptManager.get_active_script(): - return script.browse_mode_is_sticky() - return False - -_manager: Optional[FocusManager] = None -def get_manager() -> Optional[FocusManager]: - """Returns the Focus Manager""" - - global _manager - if _manager is None: - try: - from . import cthulhu - if cthulhu.cthulhuApp: - _manager = FocusManager(cthulhu.cthulhuApp) - except (ImportError, AttributeError): - pass - return _manager diff --git a/src/cthulhu/formatting.py b/src/cthulhu/formatting.py deleted file mode 100644 index 6c253a6..0000000 --- a/src/cthulhu/formatting.py +++ /dev/null @@ -1,1120 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Manages the formatting settings for Cthulhu.""" - -__id__ = "$Id:$" -__version__ = "$Revision:$" -__date__ = "$Date:$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -# If we were to adhere to the line-length requirements of 100 characters, -# this file would be even more cumbersome to look at than it already is. -# We shall respect the line-length requirements for all files that are not -# formatting.py. -# ruff: noqa: E501 - -import copy - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import object_properties -from . import role_keys - -TUTORIAL = '(tutorial and (pause + tutorial) or [])' -MNEMONIC = '(mnemonic and (pause + mnemonic + lineBreak) or [])' - -BRAILLE_TEXT = '[Text(obj, asString(labelOrName or placeholderText), asString(eol), startOffset, endOffset)]\ - + (invalid and [Region(" " + asString(invalid))])\ - + (required and [Region(" " + asString(required))])\ - + (readOnly and [Region(" " + asString(readOnly))])' - -formatting = { - - #################################################################### - # # - # Strings Cthulhu includes on its own (versus getting them from the # - # application. # - # # - #################################################################### - - 'strings' : { - 'speech': { - 'invalid': object_properties.INVALID_INDICATORS_SPEECH, - 'required': object_properties.STATE_REQUIRED_SPEECH, - 'readonly': object_properties.STATE_READ_ONLY_SPEECH, - 'insensitive': object_properties.STATE_INSENSITIVE_SPEECH, - 'checkbox': object_properties.CHECK_BOX_INDICATORS_SPEECH, - 'radiobutton': object_properties.RADIO_BUTTON_INDICATORS_SPEECH, - 'switch': object_properties.SWITCH_INDICATORS_SPEECH, - 'togglebutton': object_properties.TOGGLE_BUTTON_INDICATORS_SPEECH, - 'expansion': object_properties.EXPANSION_INDICATORS_SPEECH, - 'nodelevel': object_properties.NODE_LEVEL_SPEECH, - 'nestinglevel': object_properties.NESTING_LEVEL_SPEECH, - 'multiselect': object_properties.STATE_MULTISELECT_SPEECH, - 'iconindex': object_properties.ICON_INDEX_SPEECH, - 'groupindex': object_properties.GROUP_INDEX_SPEECH, - 'groupindextotalunknown':object_properties.GROUP_INDEX_TOTAL_UNKNOWN_SPEECH, - 'clickable': object_properties.STATE_CLICKABLE, - 'haslongdesc': object_properties.STATE_HAS_LONGDESC, - 'hasdetails': object_properties.RELATION_HAS_DETAILS, - 'detailsfor': object_properties.RELATION_DETAILS_FOR - }, - 'braille': { - 'eol': object_properties.EOL_INDICATOR_BRAILLE, - 'required': object_properties.STATE_REQUIRED_BRAILLE, - 'readonly': object_properties.STATE_READ_ONLY_BRAILLE, - 'insensitive': object_properties.STATE_INSENSITIVE_BRAILLE, - 'invalid': object_properties.INVALID_INDICATORS_BRAILLE, - 'checkbox': object_properties.CHECK_BOX_INDICATORS_BRAILLE, - 'radiobutton': object_properties.RADIO_BUTTON_INDICATORS_BRAILLE, - 'switch': object_properties.SWITCH_INDICATORS_BRAILLE, - 'togglebutton': object_properties.TOGGLE_BUTTON_INDICATORS_BRAILLE, - 'expansion': object_properties.EXPANSION_INDICATORS_BRAILLE, - 'nodelevel': object_properties.NODE_LEVEL_BRAILLE, - 'nestinglevel': object_properties.NESTING_LEVEL_BRAILLE, - }, - 'sound': { - 'invalid': object_properties.INVALID_INDICATORS_SOUND, - 'required': object_properties.STATE_REQUIRED_SOUND, - 'readonly': object_properties.STATE_READ_ONLY_SOUND, - 'insensitive': object_properties.STATE_INSENSITIVE_SOUND, - 'checkbox': object_properties.CHECK_BOX_INDICATORS_SOUND, - 'radiobutton': object_properties.RADIO_BUTTON_INDICATORS_SOUND, - 'switch': object_properties.SWITCH_INDICATORS_SOUND, - 'togglebutton': object_properties.TOGGLE_BUTTON_INDICATORS_SOUND, - 'expansion': object_properties.EXPANSION_INDICATORS_SOUND, - 'multiselect': object_properties.STATE_MULTISELECT_SOUND, - 'clickable': object_properties.STATE_CLICKABLE_SOUND, - 'haslongdesc': object_properties.STATE_HAS_LONGDESC_SOUND, - 'visited': object_properties.STATE_VISITED_SOUND, - }, - }, - - #################################################################### - # # - # Formatting for speech. # - # # - #################################################################### - - 'speech': { - 'prefix': { - 'ancestor': '[]', - 'focused': 'detailsFor', - 'unfocused': 'oldAncestors + newAncestors', - 'basicWhereAmI': 'toolbar', - 'detailedWhereAmI' : '[]' - }, - 'suffix': { - 'ancestor': '[]', - 'focused': '[]', - 'unfocused': 'newNodeLevel + unselectedCell + clickable + pause + hasLongDesc + hasDetails + detailsFor +' + TUTORIAL + ' + description + pause + hasPopup', - 'basicWhereAmI': TUTORIAL + ' + clickable + hasLongDesc + description + pause + hasPopup + pause + detailsFor + pause + allDetails', - 'detailedWhereAmI': TUTORIAL + ' + clickable + hasLongDesc + description + pause + hasPopup + detailsFor + pause + allDetails' - }, - 'default': { - 'ancestor': '[]', - 'focused': '[]', - 'unfocused': 'labelOrName + roleName + availability + ' + MNEMONIC + ' + accelerator + childWidget', - 'basicWhereAmI': 'labelOrName + roleName', - 'detailedWhereAmI' : 'pageSummary' - }, - Atspi.Role.ALERT: { - 'unfocused': 'roleName + labelOrName + pause + alertText' - }, - Atspi.Role.ANIMATION: { - 'unfocused': 'labelAndName' - }, - Atspi.Role.ARTICLE: { - 'focused': 'labelOrName + roleName', - 'unfocused': 'labelOrName + roleName + pause + currentLineText + allTextSelection', - }, - role_keys.ROLE_ARTICLE_IN_FEED: { - 'unfocused': '(labelOrName or currentLineText or roleName) + pause + positionInList', - }, - Atspi.Role.BLOCK_QUOTE: { - 'focused' : 'leaving or (roleName + pause + nestingLevel)', - 'unfocused': 'roleName + pause + nestingLevel + pause + displayedText', - }, - Atspi.Role.CANVAS: { - 'focused': 'labelAndName + (imageDescription or roleName) + pause + positionInList', - 'unfocused': 'labelAndName + (imageDescription or roleName) + pause + positionInList', - 'basicWhereAmI': 'parentRoleName + pause + labelAndName + pause + selectedItemCount + pause', - 'detailedWhereAmI': 'parentRoleName + pause + labelAndName + pause + selectedItemCount + pause + selectedItems + pause' - }, - Atspi.Role.CAPTION: { - 'unfocused': '((substring and currentLineText) or labelAndName) + roleName' - }, - Atspi.Role.CHECK_BOX: { - 'focused': 'checkedState', - 'unfocused': 'labelOrName + readOnly + roleName + checkedState + required + pause + invalid + availability + ' + MNEMONIC + ' + accelerator', - 'basicWhereAmI': 'namedContainingPanel + labelOrName + readOnly + roleName + checkedState + ' + MNEMONIC + ' + accelerator + required + pause + invalid' - }, - Atspi.Role.CHECK_MENU_ITEM: { - 'focused': 'checkedState', - 'unfocused': 'labelOrName + roleName + checkedState + required + availability + ' + MNEMONIC + ' + accelerator + pause + positionInList', - 'basicWhereAmI': 'ancestors + pause + labelOrName + roleName + checkedState + pause + accelerator + pause + positionInList + ' + MNEMONIC - }, - Atspi.Role.COLOR_CHOOSER: { - 'focused': 'value', - 'unfocused': 'label + roleName + value + required + availability + ' + MNEMONIC, - 'basicWhereAmI': 'label + roleName + value + percentage + ' + MNEMONIC + ' + accelerator + required' - }, - Atspi.Role.COLUMN_HEADER: { - 'focused': 'labelAndName + roleName + pause + sortOrder + pause + newRow + pause + newColumn', - 'unfocused': '((substring and currentLineText) or labelAndName) + roleName + pause + sortOrder + pause + newRow + pause + newColumn' - }, - Atspi.Role.COMBO_BOX: { - 'focused': 'labelOrName + roleName + expandableState', - 'unfocused': 'labelOrName + roleName + pause + value + pause + positionInList + ' + MNEMONIC + ' + accelerator', - }, - Atspi.Role.COMMENT: { - 'focused': 'labelOrName + roleName', - 'unfocused': 'labelOrName + roleName + pause + currentLineText + allTextSelection', - }, - # TODO - JD: When we bump dependencies to 2.34, remove this fake role and use the real one. - role_keys.ROLE_CONTENT_DELETION: { - 'focused': 'leaving or deletionStart', - 'unfocused': 'deletionStart + pause + displayedText + pause + deletionEnd', - }, - role_keys.ROLE_CONTENT_ERROR: { - 'unfocused': 'displayedText + pause + invalid', - }, - # TODO - JD: When we bump dependencies to 2.34, remove this fake role and use the real one. - role_keys.ROLE_CONTENT_INSERTION: { - 'focused': 'leaving or insertionStart', - 'unfocused': 'insertionStart + pause + displayedText + pause + insertionEnd', - }, - # TODO - JD: When we bump dependencies to 2.36, remove this fake role and use the real one. - role_keys.ROLE_CONTENT_MARK: { - 'focused': 'leaving or markStart', - 'unfocused': 'markStart + pause + displayedText + pause + markEnd', - }, - # TODO - JD: When we bump dependencies to 2.36, remove this fake role and use the real one. - role_keys.ROLE_CONTENT_SUGGESTION: { - 'focused': 'leaving or roleName', - }, - Atspi.Role.DESCRIPTION_LIST: { - 'focused' : 'leaving or (labelOrName + pause + (numberOfChildren or roleName) + pause + nestingLevel)', - 'unfocused': 'labelOrName + pause + focusedItem + pause + multiselectableState + (numberOfChildren or roleName) + pause' - }, - Atspi.Role.DESCRIPTION_TERM: { - 'unfocused': '(labelOrName or (displayedText + allTextSelection)) + roleName + pause + termValueCount + pause + positionInList', - }, - Atspi.Role.DESCRIPTION_VALUE: { - 'unfocused': '(labelOrName or (displayedText + allTextSelection)) + roleName + pause + positionInList', - }, - Atspi.Role.DIAL: { - 'focused': 'value', - 'unfocused': 'labelOrName + roleName + value + required + availability + ' + MNEMONIC, - 'basicWhereAmI': 'labelOrName + roleName + value + percentage + ' + MNEMONIC + ' + accelerator + required' - }, - Atspi.Role.DIALOG: { - 'focused': 'labelOrName + roleName + (unrelatedLabelsOrDescription)', - 'unfocused': '(expandedEOCs or (labelOrName + roleName + (unrelatedLabelsOrDescription)))' - }, - Atspi.Role.DOCUMENT_FRAME: { - 'unfocused': 'labelOrName + readOnly + textRole + currentLineText + anyTextSelection + ' + MNEMONIC, - 'basicWhereAmI': 'labelOrName + readOnly + textRole + textContent + anyTextSelection + ' + MNEMONIC, - 'detailedWhereAmI': 'labelOrName + readOnly + textRole + textContentWithAttributes + anyTextSelection + ' + MNEMONIC - }, - Atspi.Role.DOCUMENT_WEB: { - 'unfocused': 'labelOrName + readOnly + textRole + currentLineText + anyTextSelection + ' + MNEMONIC, - 'basicWhereAmI': 'labelOrName + readOnly + textRole + textContent + anyTextSelection + ' + MNEMONIC, - 'detailedWhereAmI': 'labelorName + readOnly + textRole + textContentWithAttributes + anyTextSelection + ' + MNEMONIC - }, - role_keys.ROLE_DPUB_LANDMARK: { - 'focused': 'leaving or labelOrName', - 'unfocused': 'labelOrName + currentLineText + allTextSelection' - }, - role_keys.ROLE_DPUB_SECTION: { - 'focused': 'leaving or (labelOrName + roleName)', - 'unfocused': 'labelOrName + currentLineText + allTextSelection' - }, - Atspi.Role.EMBEDDED: { - 'focused': 'labelOrName + roleName + availability', - 'unfocused': '(expandedEOCs or (labelOrName + unrelatedLabels)) + roleName + availability' - }, - Atspi.Role.ENTRY: { - 'focused': 'labelOrName + readOnly + textRole + (currentLineText or placeholderText) + allTextSelection', - 'unfocused': 'labelOrName + readOnly + textRole + (currentLineText or placeholderText) + allTextSelection + required + pause + invalid + ' + MNEMONIC, - 'basicWhereAmI': 'labelOrName + readOnly + textRole + (textContent or placeholderText) + anyTextSelection + required + pause + invalid + ' + MNEMONIC, - 'detailedWhereAmI': 'labelOrName + readOnly + textRole + (textContentWithAttributes or placeholderText) + anyTextSelection + required + pause + invalid + ' + MNEMONIC, - }, - role_keys.ROLE_FEED: { - 'focused': 'leaving or (labelOrName + pause + (numberOfChildren or roleName))', - 'unfocused': 'labelOrName + pause + (numberOfChildren or roleName)', - }, - Atspi.Role.FOOTNOTE: { - 'unfocused': 'labelOrName + roleName + pause + currentLineText + allTextSelection', - }, - Atspi.Role.FOOTER: { - 'unfocused': '(displayedText or name) + roleName', - }, - Atspi.Role.FORM: { - 'focused': 'leaving or (labelAndName + roleName)', - 'unfocused': '((substring and currentLineText) or labelAndName) + roleName' - }, - Atspi.Role.FRAME: { - 'focused': 'labelOrName', - 'unfocused': 'labelOrName + roleName + unfocusedDialogCount + availability' - }, - Atspi.Role.HEADER: { - 'unfocused': '(displayedText or name) + roleName', - }, - Atspi.Role.HEADING: { - 'focused': 'displayedText + roleName + expandableState', - 'unfocused': 'displayedText + roleName + expandableState', - 'basicWhereAmI': 'label + readOnly + textRole + pause + textContent + anyTextSelection + ' + MNEMONIC, - 'detailedWhereAmI': 'label + readOnly + textRole + pause + textContentWithAttributes + anyTextSelection + ' + MNEMONIC - }, - Atspi.Role.ICON: { - 'focused': 'labelAndName + (imageDescription or roleName) + pause + positionInList', - 'unfocused': 'labelAndName + (imageDescription or roleName) + pause + positionInList', - 'basicWhereAmI': 'parentRoleName + pause + labelAndName + pause + selectedItemCount + pause', - 'detailedWhereAmI': 'parentRoleName + pause + labelAndName + pause + selectedItemCount + pause + selectedItems + pause' - }, - Atspi.Role.IMAGE: { - 'unfocused': 'labelAndName + roleName' - }, - Atspi.Role.INFO_BAR: { - 'unfocused': 'labelAndName + unrelatedLabels' - }, - Atspi.Role.INTERNAL_FRAME: { - 'unfocused': 'labelAndName + roleName' - }, - Atspi.Role.LABEL: { - 'unfocused': 'label + ((displayedText + allTextSelection) or name) + roleName', - }, - Atspi.Role.LANDMARK: { - 'focused': 'leaving or (roleName + labelAndName)', - 'unfocused': 'roleName + (labelAndName or (substring and currentLineText)) + pause + unrelatedLabels' - }, - Atspi.Role.LAYERED_PANE: { - 'focused': '(labelAndName or roleName) + availability + noShowingChildren', - 'unfocused': '(labelAndName or roleName) + availability + noShowingChildren', - 'basicWhereAmI': '(labelAndName or roleName) + pause + selectedItemCount + pause', - 'detailedWhereAmI': '(labelAndName or roleName) + pause + roleName + pause + selectedItemCount + pause + selectedItems + pause' - }, - Atspi.Role.LINK: { - 'unfocused': '(name or displayedText) + roleName + pause + expandableState + availability + ' + MNEMONIC, - 'basicWhereAmI': 'linkInfo + pause + siteDescription + pause + fileSize + pause + ' + MNEMONIC - }, - Atspi.Role.LIST: { - 'focused' : 'leaving or (labelOrName + pause + (numberOfChildren or roleName) + pause + nestingLevel)', - 'unfocused': 'labelOrName + pause + focusedItem + pause + multiselectableState + (numberOfChildren or roleName) + pause' - }, - Atspi.Role.LIST_BOX: { - 'focused': 'labelOrName + multiselectableState + (numberOfChildren or roleName)', - 'unfocused': 'labelOrName + pause + focusedItem + pause + multiselectableState + (numberOfChildren or roleName) + pause' - }, - Atspi.Role.LIST_ITEM: { - 'focused': 'checkedStateIfCheckable + pause + expandableState', - 'unfocused': '(labelOrName or (displayedText + allTextSelection)) + checkedStateIfCheckable + pause + unselectedStateIfSelectable + pause + expandableState + pause + positionInList + pause + listBoxItemWidgets', - 'basicWhereAmI': 'label + roleName + pause + (name or displayedText) + checkedStateIfCheckable + pause + unselectedStateIfSelectable + pause + positionInList + pause + expandableState + (nodeLevel or nestingLevel) + pause' - }, - Atspi.Role.MATH: { - 'unfocused': 'math', - }, - # TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one. - role_keys.ROLE_MATH_ENCLOSED: { - 'unfocused': 'enclosedBase + enclosedEnclosures', - }, - # TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one. - role_keys.ROLE_MATH_FENCED: { - 'unfocused': 'fencedStart + pause + fencedContents + pause + fencedEnd', - }, - Atspi.Role.MATH_FRACTION: { - 'unfocused': 'fractionStart + pause + fractionNumerator + fractionLine + fractionDenominator + pause + fractionEnd + pause', - }, - Atspi.Role.MATH_ROOT: { - 'unfocused': 'rootStart + rootBase + pause + rootEnd + pause', - }, - # TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one. - role_keys.ROLE_MATH_MULTISCRIPT: { - 'unfocused': 'scriptBase + pause + scriptPrescripts + pause + scriptPostscripts + pause', - }, - # TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one. - role_keys.ROLE_MATH_SCRIPT_SUBSUPER: { - 'unfocused': 'scriptBase + pause + scriptSubscript + pause + scriptSuperscript + pause', - }, - # TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one. - role_keys.ROLE_MATH_SCRIPT_UNDEROVER: { - 'unfocused': 'scriptBase + pause + scriptUnderscript + pause + scriptOverscript + pause', - }, - # TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one. - role_keys.ROLE_MATH_TABLE: { - 'unfocused': 'mathTableStart + pause + mathTableRows + pause + mathTableEnd + pause', - }, - # TODO - JD: When we bump dependencies to TBD, remove this fake role and use the real one. - role_keys.ROLE_MATH_TABLE_ROW: { - 'unfocused': 'mathRow', - }, - Atspi.Role.MENU: { - 'focused': 'labelOrName + roleName', - 'unfocused': 'labelOrName + roleName + availability + ' + MNEMONIC + ' + accelerator + pause + positionInList', - 'basicWhereAmI': '(ancestors or parentRoleName) + pause + labelOrName + roleName + pause + positionInList + ' + MNEMONIC - }, - Atspi.Role.MENU_ITEM: { - 'focused': 'expandableState', - 'unfocused': 'labelOrName + checkedStateIfCheckable + expandableState + availability + ' + MNEMONIC + ' + accelerator + pause + positionInList', - 'basicWhereAmI': 'ancestors + pause + labelOrName + checkedStateIfCheckable + pause + accelerator + pause + positionInList + ' + MNEMONIC - }, - Atspi.Role.NOTIFICATION: { - 'unfocused': 'roleName + labelOrName + pause + (expandedEOCs or unrelatedLabelsOrDescription)' - }, - Atspi.Role.PAGE: { - 'focused': 'label + readOnly + currentLineText + anyTextSelection', - 'unfocused': 'label + readOnly + currentLineText + anyTextSelection + ' + MNEMONIC, - 'basicWhereAmI': 'label + readOnly + textRole + textContent + anyTextSelection + ' + MNEMONIC, - 'detailedWhereAmI': 'label + readOnly + textRole + textContentWithAttributes + anyTextSelection + ' + MNEMONIC - }, - Atspi.Role.PAGE_TAB: { - 'focused': 'labelOrName + roleName + availability + pause + positionInList + ' + MNEMONIC + ' + accelerator', - 'unfocused': 'labelOrName + roleName + availability + pause + positionInList + ' + MNEMONIC + ' + accelerator', - 'basicWhereAmI': 'parentRoleName + pause + labelOrName + roleName + availability + pause + positionInList + ' + MNEMONIC + ' + accelerator' - }, - Atspi.Role.PANEL: { - 'focused': 'leaving or (labelAndName + roleName + availability + pause + unrelatedLabels)', - 'unfocused': '((substring and currentLineText) or labelAndName) + roleName + availability + pause + unrelatedLabels' - }, - Atspi.Role.PARAGRAPH: { - 'focused': 'labelOrName + readOnly + textRole + textIndentation + currentLineText + allTextSelection', - 'unfocused': 'labelOrName + readOnly + textRole + textIndentation + currentLineText + allTextSelection + ' + MNEMONIC, - 'basicWhereAmI': 'label + readOnly + textRole + textContent + anyTextSelection + ' + MNEMONIC, - 'detailedWhereAmI': 'label + readOnly + textRole + textContentWithAttributes + anyTextSelection + ' + MNEMONIC - }, - Atspi.Role.PASSWORD_TEXT: { - 'focused': 'labelOrName + readOnly + textRole + currentLineText + allTextSelection', - 'unfocused': 'labelOrName + readOnly + textRole + currentLineText + allTextSelection + ' + MNEMONIC, - 'basicWhereAmI': 'label + readOnly + textRole + textContent + anyTextSelection + ' + MNEMONIC, - 'detailedWhereAmI': 'label + readOnly + textRole + textContentWithAttributes + anyTextSelection + ' + MNEMONIC - }, - Atspi.Role.PROGRESS_BAR: { - 'focused': 'progressBarIndex + (progressBarValue or roleName)', - 'unfocused': 'progressBarIndex + labelAndName + (progressBarValue or roleName)' - }, - Atspi.Role.PUSH_BUTTON: { - 'focused': 'expandableState', - 'unfocused': 'labelAndName + expandableState + roleName + availability + ' + MNEMONIC + ' + accelerator', - 'basicWhereAmI': 'labelAndName + expandableState + roleName + ' + MNEMONIC + ' + accelerator' - }, - Atspi.Role.RADIO_BUTTON: { - 'focused': 'radioState', - 'unfocused': 'newRadioButtonGroup + pause + (name or label) + pause + radioState + roleName + availability + lineBreak + ' + MNEMONIC + ' + accelerator + pause + positionInList + pause', - 'basicWhereAmI': 'radioButtonGroup + pause + (name or label) + roleName + pause + radioState + pause + positionInGroup + ' + MNEMONIC + ' + accelerator' - }, - Atspi.Role.RADIO_MENU_ITEM: { - # OpenOffice check menu items currently have a role of "menu item" - # rather then "check menu item", so we need to test if one of the - # states is CHECKED. If it is, then add that in to the list of - # speech utterances. Note that we can't tell if this is a "check - # menu item" that is currently unchecked and speak that state. - # See Cthulhu bug #433398 for more details. - # - 'focused': 'labelOrName + radioState + roleName + availability + positionInList', - 'unfocused': 'labelOrName + radioState + roleName + availability + ' + MNEMONIC + ' + accelerator + positionInList', - 'basicWhereAmI': 'ancestors + labelOrName + roleName + radioState + accelerator + positionInList + ' + MNEMONIC - }, - role_keys.ROLE_REGION: { - 'focused': 'leaving or (roleName + labelOrName)', - 'unfocused': 'labelOrName + roleName + currentLineText + allTextSelection' - }, - Atspi.Role.ROW_HEADER: { - 'focused': 'labelAndName + roleName + pause + sortOrder + pause + newRow + pause + newColumn', - 'unfocused': '((substring and currentLineText) or labelAndName) + roleName + pause + sortOrder + pause + newRow + pause + newColumn' - }, - Atspi.Role.SCROLL_BAR: { - 'focused': 'value', - 'unfocused': 'labelOrName + roleName + value + required + availability + ' + MNEMONIC, - 'basicWhereAmI': 'labelOrName + roleName + value + percentage + ' + MNEMONIC + ' + accelerator + required' - }, - Atspi.Role.SCROLL_PANE: { - 'unfocused': '(currentLineText + allTextSelection) or (labelOrName + roleName)', - }, - Atspi.Role.SECTION: { - 'focused': '(labelOrName or (currentLineText + allTextSelection)) + roleName', - 'unfocused': '(labelOrName or (currentLineText + allTextSelection)) + roleName + ' + MNEMONIC, - }, - Atspi.Role.SLIDER: { - 'focused': 'value', - 'unfocused': 'labelOrName + roleName + value + required + pause + invalid + availability + ' + MNEMONIC, - 'basicWhereAmI': 'labelOrName + roleName + value + percentage + ' + MNEMONIC + ' + accelerator + required + pause + invalid' - }, - Atspi.Role.SPIN_BUTTON: { - 'focused': '(displayedText or value)', - 'unfocused': 'labelAndName + (displayedText or value) + roleName + required + pause + invalid + availability + ' + MNEMONIC, - 'basicWhereAmI': 'label + roleName + name + (displayedText or value) + ' + MNEMONIC + ' + accelerator + required + pause + invalid' - }, - Atspi.Role.SEPARATOR: { - 'focused': 'roleName + availability', - 'unfocused': 'roleName + availability + (labelOrName or displayedText or value) + ' + MNEMONIC, - }, - Atspi.Role.SPLIT_PANE: { - 'focused': 'value', - 'unfocused': 'labelAndName + roleName + value + availability + ' + MNEMONIC, - 'basicWhereAmI' : 'labelAndName + roleName + value' - }, - Atspi.Role.STATIC: { - 'unfocused': '(displayedText or name) + roleName', - }, - Atspi.Role.STATUS_BAR: { - 'focused': 'labelAndName + roleName', - 'unfocused': 'labelAndName + roleName + pause + statusBar', - }, - Atspi.Role.SUBSCRIPT: { - 'unfocused': 'roleName + currentLineText + allTextSelection', - }, - Atspi.Role.SUPERSCRIPT: { - 'unfocused': 'roleName + currentLineText + allTextSelection', - }, - role_keys.ROLE_SWITCH: { - 'focused': 'switchState', - 'unfocused': 'labelOrName + roleName + switchState + availability + ' + MNEMONIC + ' + accelerator', - 'basicWhereAmI': 'labelOrName + roleName + switchState' - }, - Atspi.Role.TABLE: { - 'focused': 'leaving or (labelAndName + pause + table)', - 'unfocused': 'labelAndName + pause + table', - 'basicWhereAmI': 'labelAndName + pause + table' - }, - Atspi.Role.TABLE_CELL: { - 'ancestor': 'newRowHeader + newColumnHeader + pause + newRow + pause + newColumn', - 'focused': '((tableCell2ChildLabel + tableCell2ChildToggle) or cellCheckedState) + pause + (expandableState and (expandableState + pause + numberOfChildren + pause))', - 'unfocused': 'tableCellRow + pause', - 'basicWhereAmI': 'parentRoleName + pause + columnHeader + pause + rowHeader + pause + roleName + pause + cellCheckedState + pause + (realActiveDescendantDisplayedText or imageDescription + image) + pause + columnAndRow + pause + expandableState + pause + nodeLevel + pause', - 'detailedWhereAmI': 'parentRoleName + pause + columnHeader + pause + rowHeader + pause + roleName + pause + cellCheckedState + pause + (realActiveDescendantDisplayedText or imageDescription + image) + pause + columnAndRow + pause + tableCellRow + pause + expandableState + pause + nodeLevel + pause', - }, - role_keys.REAL_ROLE_TABLE_CELL: { - # the real cell information - # note that Atspi.Role.TABLE_CELL is used to work out if we need to - # read a whole row. It calls REAL_ROLE_TABLE_CELL internally. - # maybe it can be done in a cleaner way? - # - 'focused': '(tableCell2ChildLabel + tableCell2ChildToggle)\ - or (cellCheckedState + (expandableState and (expandableState + numberOfChildren)))', - 'unfocused': '(tableCell2ChildLabel + tableCell2ChildToggle)\ - or (newRowHeader + (newColumnHeader or columnHeaderIfToggleAndNoText) \ - + cellCheckedState\ - + (realActiveDescendantDisplayedText or imageDescription + image)\ - + (expandableState and (expandableState + numberOfChildren))\ - + required + pause + invalid)' - }, - Atspi.Role.TABLE_ROW: { - 'focused': 'expandableState', - 'unfocused': '(labelOrName or displayedText) + pause + expandableState + pause + positionInList', - 'basicWhereAmI': '(labelOrName or displayedText) + roleName + pause + positionInList + pause + expandableState + (nodeLevel or nestingLevel)' - }, - Atspi.Role.TEAROFF_MENU_ITEM: { - 'focused': '[]', - 'unfocused': 'labelOrName + roleName + availability ' - }, - Atspi.Role.TERMINAL: { - 'focused': 'textContent', - 'unfocused': 'textContent', - 'basicWhereAmI': 'label + readOnly + pause + textRole + pause + textContent + anyTextSelection + ' + MNEMONIC, - 'detailedWhereAmI': 'label + readOnly + pause + textRole + pause + textContentWithAttributes + anyTextSelection + ' + MNEMONIC - }, - Atspi.Role.TEXT: { - 'focused': 'labelOrName + readOnly + textRole + pause + textIndentation + (currentLineText or placeholderText) + allTextSelection', - 'unfocused': 'labelOrName + readOnly + textRole + pause + textIndentation + (currentLineText or placeholderText) + allTextSelection + ' + MNEMONIC, - 'basicWhereAmI': 'labelOrName + readOnly + textRole + pause + (textContent or placeholderText) + anyTextSelection + pause + ' + MNEMONIC, - 'detailedWhereAmI': 'labelOrName + readOnly + textRole + pause + (textContentWithAttributes or placeholderText) + anyTextSelection + pause + ' + MNEMONIC - }, - Atspi.Role.TOGGLE_BUTTON: { - 'focused': 'expandableState or toggleState', - 'unfocused': 'labelOrName + roleName + (expandableState or toggleState) + availability + ' + MNEMONIC + ' + accelerator', - 'basicWhereAmI': 'labelOrName + roleName + (expandableState or toggleState)' - }, - Atspi.Role.TOOL_BAR: { - 'focused': 'labelAndName + roleName', - 'unfocused': 'labelAndName + roleName', - }, - Atspi.Role.TOOL_TIP: { - 'focused': 'leaving or roleName', - 'unfocused': 'roleName + labelAndName', - 'basicWhereAmI': 'roleName + labelAndName' - }, - Atspi.Role.TREE: { - 'focused': 'labelAndName + roleName', - 'unfocused': 'labelAndName + roleName', - }, - Atspi.Role.TREE_ITEM: { - 'focused': 'expandableState', - 'unfocused': '(labelOrName or displayedText) + pause + expandableState + pause + positionInList', - 'basicWhereAmI': '(labelOrName or displayedText) + roleName + pause + positionInList + pause + expandableState + (nodeLevel or nestingLevel)' - }, - }, - - #################################################################### - # # - # Formatting for braille. # - # # - #################################################################### - - 'braille': { - 'prefix': { -# 'focused': 'ancestors\ -# + (rowHeader and [Region(" " + asString(rowHeader))])\ -# + (columnHeader and [Region(" " + asString(columnHeader))])\ -# + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\ -# + [Region(" ")]', -# 'unfocused': 'ancestors\ -# + (rowHeader and [Region(" " + asString(rowHeader))])\ -# + (columnHeader and [Region(" " + asString(columnHeader))])\ -# + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\ -# + [Region(" ")]', - 'focused': '(includeContext\ - and (ancestors\ - + (rowHeader and [Region(" " + asString(rowHeader))])\ - + (columnHeader and [Region(" " + asString(columnHeader))])\ - + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\ - + [Region(" ")])\ - or [])', - 'unfocused': '(includeContext\ - and (ancestors\ - + (rowHeader and [Region(" " + asString(rowHeader))])\ - + (columnHeader and [Region(" " + asString(columnHeader))])\ - + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\ - + [Region(" ")])\ - or [])', - }, - 'suffix': { - 'focused': '(nodeLevel and [Region(" " + asString(nodeLevel))])', - 'unfocused': '(nodeLevel and [Region(" " + asString(nodeLevel))])', - }, - 'default': { - 'focused': '[Component(obj,\ - asString(label + displayedText + value + roleName + required + invalid))]', - 'unfocused': '[Component(obj,\ - asString(label + displayedText + value + roleName + required + invalid))]', - }, - Atspi.Role.ALERT: { - 'unfocused': '((substring and ' + BRAILLE_TEXT + ')\ - or ([Component(obj, asString(labelAndName + roleName))]))' - }, - Atspi.Role.ANIMATION: { - 'unfocused': '[Component(obj,\ - asString(label + displayedText + roleName + (description and space(": ") + description)))]', - }, - Atspi.Role.APPLICATION: { - 'focused': '[Component(obj, asString(name + roleName))]', - 'unfocused': '[Component(obj, asString(name + roleName))]', - }, - Atspi.Role.ARTICLE: { - 'unfocused': '((substring and ' + BRAILLE_TEXT + ')\ - or ([Component(obj, asString(labelAndName + roleName))]\ - + (childWidget and ([Region(" ")] + childWidget))))' - }, - role_keys.ROLE_ARTICLE_IN_FEED: { - 'unfocused': '((substring and ' + BRAILLE_TEXT + ')\ - or ([Component(obj, asString(labelOrName + roleName))]))' - }, - #Atspi.Role.ARROW: 'default' - Atspi.Role.BLOCK_QUOTE: { - 'unfocused': BRAILLE_TEXT + ' + (roleName and [Region(" " + asString(roleName + nestingLevel))])', - }, - Atspi.Role.CANVAS: { - 'unfocused': '[Component(obj,\ - asString(((label + displayedText + imageDescription) or name) + roleName))]' - }, - Atspi.Role.CHECK_BOX: { - 'unfocused': '[Component(obj,\ - asString(labelOrName + roleName),\ - indicator=asString(checkedState))]' - }, - Atspi.Role.CHECK_MENU_ITEM: { - 'unfocused': '[Component(obj,\ - asString(label + displayedText + roleName + availability) + asString(accelerator),\ - indicator=asString(checkedState))]' - }, - Atspi.Role.COLUMN_HEADER: { - 'unfocused': '[Component(obj,\ - asString(((substring and currentLineText) or labelAndName) + roleName + sortOrder))]', - }, - Atspi.Role.COMBO_BOX: { - 'unfocused': '[Component(obj, asString(labelOrName + value + roleName), \ - labelOrName and (len(asString(labelOrName)) + 1) or 0)]' - }, - Atspi.Role.DESCRIPTION_TERM: { - 'unfocused': BRAILLE_TEXT + ' + ([Region(" " + asString(termValueCount))])', - }, - #Atspi.Role.DESKTOP_ICON: 'default' - Atspi.Role.DIAL: { - 'unfocused': '[Component(obj,\ - asString(labelOrName + value + roleName + required))]' - }, - Atspi.Role.DIALOG: { - 'unfocused': '[Component(obj, asString(labelOrName + roleName + (unrelatedLabelsOrDescription)))]' - }, - #Atspi.Role.DIRECTORY_PANE: 'default' - Atspi.Role.DOCUMENT_FRAME: { - 'focused': '[Text(obj, asString(placeholderText), asString(eol), startOffset, endOffset)]\ - + (required and [Region(" " + asString(required))])\ - + (readOnly and [Region(" " + asString(readOnly))])', - 'unfocused': BRAILLE_TEXT - }, - Atspi.Role.DOCUMENT_WEB: { - 'focused': '[Text(obj, asString(placeholderText), asString(eol), startOffset, endOffset)]\ - + (required and [Region(" " + asString(required))])\ - + (readOnly and [Region(" " + asString(readOnly))])', - 'unfocused': BRAILLE_TEXT - }, - Atspi.Role.ENTRY: { - 'unfocused': BRAILLE_TEXT - }, - Atspi.Role.FORM: { - 'unfocused': '((substring and ' + BRAILLE_TEXT + ')\ - or ([Component(obj, asString(labelAndName + roleName))]))' - }, - Atspi.Role.FRAME: { - 'focused': '[Component(obj,\ - asString(labelOrName + roleName + alertAndDialogCount))]', - 'unfocused': '[Component(obj,\ - asString(labelOrName + roleName + alertAndDialogCount))]', - }, - Atspi.Role.HEADING: { - 'unfocused': '[Text(obj, asString(placeholderText), "", startOffset, endOffset)]\ - + [Region(" " + asString(roleName))]' - }, - #Atspi.Role.HTML_CONTAINER: 'default' - Atspi.Role.ICON: { - 'unfocused': '[Component(obj,\ - asString(((label + displayedText + imageDescription) or name) + roleName))]' - }, - Atspi.Role.IMAGE: { - 'focused': '[Component(obj,\ - asString(labelAndName + value + roleName + required))]', - 'unfocused': '[Component(obj,\ - asString(labelAndName + value + roleName + required))]', - }, - Atspi.Role.LABEL: { - 'unfocused': BRAILLE_TEXT - }, - Atspi.Role.LINK: { - 'unfocused': '[Link(obj, asString(name or displayedText))] \ - + (roleName and [Region(" " + asString(roleName))])', - }, - Atspi.Role.LIST: { - 'unfocused': '[Component(obj,\ - asString(label + focusedItem + roleName),\ - asString(label) and (len(asString(label)) + 1) or 0)]' - }, - Atspi.Role.LIST_BOX: { - 'unfocused': '[Component(obj,\ - asString(label + focusedItem + roleName),\ - asString(label) and (len(asString(label)) + 1) or 0)]' - }, - Atspi.Role.LIST_ITEM: { - 'focused': '((substring and ' + BRAILLE_TEXT + ')\ - or ([Component(obj,\ - asString(label + displayedText + expandableState + roleName + availability) + asString(accelerator), indicator=asString(checkedStateIfCheckable))] \ - + (nestingLevel and [Region(" " + asString(nestingLevel))])\ - + (listBoxItemWidgets and ([Region(" ")] + listBoxItemWidgets))))', - 'unfocused': '((substring and ' + BRAILLE_TEXT + ')\ - or ([Component(obj, asString(labelOrName + expandableState))]\ - + (nestingLevel and [Region(" " + asString(nestingLevel))])\ - + (listBoxItemWidgets and ([Region(" ")] + listBoxItemWidgets))))', - }, - Atspi.Role.MENU: { - 'focused': '[Component(obj,\ - asString(labelOrName + roleName + availability) + asString(accelerator))]', - 'unfocused': '[Component(obj,\ - asString(labelOrName + roleName))]', - }, - #Atspi.Role.MENU_BAR: 'default' - Atspi.Role.MENU_ITEM: { - 'unfocused': '[Component(obj,\ - asString(labelOrName + expandableState + availability) + asString(accelerator),\ - indicator=asString(checkedStateIfCheckable))]' - }, - Atspi.Role.NOTIFICATION: { - 'unfocused': '((substring and ' + BRAILLE_TEXT + ')\ - or ([Component(obj, asString(labelAndName + roleName))]))' - }, - Atspi.Role.PAGE: { - 'unfocused': BRAILLE_TEXT - }, - #Atspi.Role.OPTION_PANE: 'default' - Atspi.Role.PAGE_TAB: { - 'focused': '[Component(obj,\ - asString(labelOrName + roleName + availability) + asString(accelerator))]', - 'unfocused': '[Component(obj,\ - asString(labelOrName + roleName))]' - }, - #Atspi.Role.PAGE_TAB_LIST: 'default' - Atspi.Role.PANEL: { - 'unfocused': '((substring and ' + BRAILLE_TEXT + ')\ - or ([Component(obj, asString(labelAndName + roleName))]\ - + (childWidget and ([Region(" ")] + childWidget))))' - }, - Atspi.Role.PARAGRAPH: { - 'unfocused': BRAILLE_TEXT - }, - Atspi.Role.PASSWORD_TEXT: { - 'unfocused': BRAILLE_TEXT - }, - Atspi.Role.PROGRESS_BAR: { - 'unfocused': '(progressBarValue and \ - [Component(obj, asString(labelAndName + progressBarValue + roleName + progressBarIndex))]) \ - or []' - }, - Atspi.Role.PUSH_BUTTON: { - 'unfocused': '[Component(obj,\ - asString((labelAndName or description) + expandableState + roleName))]' - }, - Atspi.Role.RADIO_BUTTON: { - 'unfocused': '[Component(obj,\ - asString((labelOrName or description) + roleName),\ - indicator=asString(radioState))]' - }, - Atspi.Role.RADIO_MENU_ITEM: { - 'focused': '[Component(obj,\ - asString((labelOrName or description) + roleName + availability)\ - + asString(accelerator),\ - indicator=asString(radioState))]', - 'unfocused': '[Component(obj,\ - asString(labelOrName or description)\ - + asString(accelerator),\ - indicator=asString(radioState))]' - }, - Atspi.Role.ROW_HEADER: { - 'unfocused': '[Component(obj,\ - asString(((substring and currentLineText) or labelAndName) + roleName + sortOrder))]', - }, - Atspi.Role.SCROLL_BAR: { - 'unfocused': '[Component(obj,\ - asString(labelOrName + value + roleName + required))]' - }, - Atspi.Role.SCROLL_PANE: { - 'unfocused': 'asPageTabOrScrollPane' - }, - Atspi.Role.SECTION: { - 'unfocused': BRAILLE_TEXT - }, - #'REAL_ROLE_SCROLL_PANE': 'default' - Atspi.Role.SLIDER: { - 'unfocused': '[Component(obj,\ - asString(labelOrName + value + roleName + required + invalid))]' - }, - Atspi.Role.SPIN_BUTTON: { - 'unfocused': '[Text(obj, asString(label), asString(eol))]\ - + (required and [Region(" " + asString(required))] or [])\ - + (readOnly and [Region(" " + asString(readOnly))] or [])' - }, - Atspi.Role.STATUS_BAR: { - 'unfocused': '[Component(obj, asString(labelOrName + roleName))]\ - + [Region(" ")] + statusBar', - }, - role_keys.ROLE_SWITCH: { - 'unfocused': '[Component(obj,\ - asString((labelOrName or description) + roleName),\ - indicator=asString(switchState))]' - }, - #Atspi.Role.SPLIT_PANE: 'default' - #Atspi.Role.TABLE: 'default' - Atspi.Role.TABLE_CELL: { - 'unfocused': '((substring and ' + BRAILLE_TEXT + ') or tableCellRow)', - }, - role_keys.REAL_ROLE_TABLE_CELL: { - 'unfocused': '((tableCell2ChildToggle + tableCell2ChildLabel)\ - or (substring and ' + BRAILLE_TEXT + ') \ - or (cellCheckedState\ - + (columnHeaderIfToggleAndNoText and [Region(" "), Component(obj, asString(columnHeaderIfToggleAndNoText))])\ - + ((realActiveDescendantDisplayedText and [Component(obj, asString(realActiveDescendantDisplayedText))])\ - or (imageDescription and [Region(" "), Component(obj, asString(imageDescription))]))\ - + (realActiveDescendantRoleName and [Component(obj, (realActiveDescendantDisplayedText and " " or "") + asString(realActiveDescendantRoleName))])\ - + (expandableState and [Region(" " + asString(expandableState))])\ - + (required and [Region(" " + asString(required))]))\ - or ([Component(obj,"")]))' - }, - #Atspi.Role.TABLE_COLUMN_HEADER: 'default' - #Atspi.Role.TABLE_ROW_HEADER: 'default' - Atspi.Role.TEAROFF_MENU_ITEM: { - 'unfocused': '[Component(obj,\ - asString(roleName))]' - }, - Atspi.Role.TERMINAL: { - 'unfocused': '[Text(obj)]' - }, - Atspi.Role.TEXT: { - 'unfocused': BRAILLE_TEXT - }, - Atspi.Role.TOGGLE_BUTTON: { - 'unfocused': '[Component(obj,\ - asString((labelOrName or description) + expandableState + roleName),\ - indicator=asString(toggleState))]' - }, - Atspi.Role.TOOL_BAR: { - 'unfocused': '[Component(obj, asString(labelOrName + roleName))]', - }, - Atspi.Role.TREE: { - 'unfocused': '[Component(obj, asString(labelOrName + roleName))]', - }, - Atspi.Role.TREE_ITEM: { - 'unfocused': '((substring and ' + BRAILLE_TEXT + ')\ - or ([Component(obj, asString(labelOrName + expandableState))]\ - + (nodeLevel and [Region(" " + asString(nodeLevel))])))', - }, - #Atspi.Role.TREE: 'default' - #Atspi.Role.TREE_TABLE: 'default' - #Atspi.Role.WINDOW: 'default' - }, - - #################################################################### - # # - # Formatting for sound. # - # # - #################################################################### - - 'sound': { - 'prefix': { - 'focused': '[]', - 'unfocused': '[]', - 'basicWhereAmI': '[]', - 'detailedWhereAmI': '[]' - }, - 'suffix': { - 'focused': '[]', - 'unfocused': 'clickable + hasLongDesc', - 'basicWhereAmI': '[]', - 'detailedWhereAmI': '[]' - }, - 'default': { - 'focused': '[]', - 'unfocused': 'roleName', - 'basicWhereAmI': '[]', - 'detailedWhereAmI': '[]' - }, - Atspi.Role.CANVAS: { - 'unfocused': 'roleName + positionInSet', - }, - Atspi.Role.CHECK_BOX: { - 'focused': 'checkedState', - 'unfocused': 'checkedState + required + invalid + availability', - }, - Atspi.Role.CHECK_MENU_ITEM: { - 'focused': 'checkedState', - 'unfocused': 'checkedState + availability + positionInSet', - }, - Atspi.Role.COMBO_BOX: { - 'focused': 'expandableState', - 'unfocused': 'roleName + positionInSet', - }, - Atspi.Role.DIAL: { - 'focused': 'percentage', - 'unfocused': 'roleName + percentage + required + invalid + availability', - }, - Atspi.Role.ENTRY: { - 'unfocused': 'roleName + readOnly + required + invalid + availability', - }, - Atspi.Role.HEADING: { - 'focused': 'expandableState', - 'unfocused': 'roleName + expandableState', - }, - Atspi.Role.ICON: { - 'unfocused': 'roleName + positionInSet', - }, - Atspi.Role.LINK: { - 'focused': 'expandableState', - 'unfocused': 'roleName + visitedState + expandableState', - }, - Atspi.Role.LIST: { - 'unfocused': 'roleName + multiselectableState', - }, - Atspi.Role.LIST_BOX: { - 'unfocused': 'roleName + multiselectableState', - }, - Atspi.Role.LIST_ITEM: { - 'focused': 'expandableState', - 'unfocused': 'roleName + expandableState + positionInSet', - }, - Atspi.Role.MENU_ITEM: { - 'focused': 'expandableState', - 'unfocused': 'roleName + expandableState + availability + positionInSet', - }, - Atspi.Role.PAGE_TAB: { - 'unfocused': 'roleName + positionInSet', - }, - Atspi.Role.PROGRESS_BAR: { - 'focused': 'progressBarValue', - 'unfocused': 'roleName + progressBarValue' - }, - Atspi.Role.PUSH_BUTTON: { - 'focused': 'expandableState', - 'unfocused': 'roleName + expandableState + availability', - }, - Atspi.Role.RADIO_BUTTON: { - 'focused': 'radioState', - 'unfocused': 'radioState + availability + positionInSet', - }, - Atspi.Role.RADIO_MENU_ITEM: { - 'focused': 'radioState', - 'unfocused': 'checkedState + availability + positionInSet', - }, - Atspi.Role.SCROLL_BAR: { - 'focused': 'percentage', - 'unfocused': 'roleName + percentage', - }, - Atspi.Role.SLIDER: { - 'focused': 'percentage', - 'unfocused': 'roleName + percentage + required + invalid + availability', - }, - Atspi.Role.SPIN_BUTTON: { - 'focused': 'percentage', - 'unfocused': 'roleName + availability + percentage + required + invalid', - }, - Atspi.Role.SPLIT_PANE: { - 'focused': 'percentage', - 'unfocused': 'roleName + percentage + availability', - }, - role_keys.ROLE_SWITCH: { - 'focused': 'switchState', - 'unfocused': 'switchState + availability', - }, - Atspi.Role.TABLE_CELL: { - 'focused': 'expandableState', - 'unfocused': 'roleName + expandableState', - }, - Atspi.Role.TABLE_ROW: { - 'focused': 'expandableState', - }, - Atspi.Role.TEXT: { - 'unfocused': 'roleName + readOnly + required + invalid + availability', - }, - Atspi.Role.TOGGLE_BUTTON: { - 'focused': 'expandableState or toggleState', - 'unfocused': '(expandableState or toggleState) + availability', - }, - Atspi.Role.TREE_ITEM: { - 'focused': 'expandableState', - 'unfocused': 'roleName + expandableState + positionInSet', - }, - }, -} - -class Formatting(dict): - - def __init__(self, script): - dict.__init__(self) - self._script = script - self.update(copy.deepcopy(formatting)) - - def update(self, newDict): - for key, val in newDict.items(): - if key in self: - if isinstance(self[key], dict) and isinstance(val, dict): - self[key].update(val) - elif isinstance(self[key], str) \ - and isinstance(val, str): - self[key] = val - else: - # exception or such like, we are trying to merge - # incompatible trees. - # throw an exception? - print("an error has occurred, cant merge dicts.") - else: - self[key] = val - - def getPrefix(self, **args): - """Get a formatting string to add on to the end of - formatting strings obtained by getFormat. - - Arguments expected in args: - - mode: output mode, such as 'speech', 'braille'. - - formatType: the type of formatting, such as - 'focused', 'basicWhereAmI', etc. - """ - prefix = self[args['mode']]['prefix'][args['formatType']] - return prefix - - def getSuffix(self, **args): - """Get a formatting string to add on to the end of - formatting strings obtained by getFormat. - - Arguments expected in args: - - mode: output mode, such as 'speech', 'braille'. - - role: the role, such as Atspi.Role.TEXT - - formatType: the type of formatting, such as - 'focused', 'basicWhereAmI', etc. - """ - suffix = self[args['mode']]['suffix'][args['formatType']] - return suffix - - def getString(self, **args): - """Gets a human consumable string for a specific value - (e.g., an indicator for a checkbox state). - - Arguments expected in args: - - mode: output mode, such as 'speech', 'braille'. - - stringType: the type of the string to get (see the dictionary above). - """ - return self['strings'][args['mode']][args['stringType']] - - def getFormat(self, **args): - """Get a formatting string for the given mode and formatType for a - role (e.g., a where am I string for a text object). - - Arguments expected in args: - - mode: output mode, such as 'speech', 'braille'. - - role: the role, such as Atspi.Role.TEXT - - formatType: the type of formatting, such as - 'focused', 'basicWhereAmI', etc. - """ - try: - return self[args['mode']][args['role']][args['formatType']] - except Exception: - pass - - if args.get('formatType') == 'ancestor': - try: - return self[args['mode']][args['role']]['focused'] - except Exception: - pass - - if args.get('formatType') == 'detailedWhereAmI': - try: - return self[args['mode']][args['role']]['basicWhereAmI'] - except Exception: - pass - - try: - return self[args['mode']][args['role']]['unfocused'] - except Exception: - pass - - - try: - return self[args['mode']]['default'][args['formatType']] - except Exception: - pass - - try: - return self[args['mode']]['default']['unfocused'] - except Exception: - return [] diff --git a/src/cthulhu/generator.py b/src/cthulhu/generator.py deleted file mode 100644 index 26756f7..0000000 --- a/src/cthulhu/generator.py +++ /dev/null @@ -1,1587 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Superclass of classes used to generate presentations for objects.""" - -__id__ = "$Id:$" -__version__ = "$Revision:$" -__date__ = "$Date:$" -__copyright__ = "Copyright (c) 2009 Sun Microsystems Inc." \ - "Copyright (c) 2015-2016 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -gi.require_version('Atk', '1.0') -from gi.repository import Atk - -import re -import sys -import time -import traceback - -from . import braille -from . import debug -from . import messages -from . import object_properties -from . import role_keys -from . import settings -from . import settings_manager -from .ax_object import AXObject -from .ax_text import AXText -from .ax_utilities import AXUtilities -from .ax_utilities_relation import AXUtilitiesRelation - -# Python 3.10 compatibility: -try: - import collections.abc as collections_abc -except ImportError: - import collections as collections_abc - -def _formatExceptionInfo(maxTBlevel=5): - cla, exc, trbk = sys.exc_info() - excName = cla.__name__ - try: - excArgs = exc.args - except KeyError: - excArgs = "" - excTb = traceback.format_tb(trbk, maxTBlevel) - return (excName, excArgs, excTb) - -# [[[WDW - general note -- for all the _generate* methods, it would be great if -# we could return an empty array if we can determine the method does not -# apply to the object. This would allow us to reduce the number of strings -# needed in formatting.py.]]] - -# The prefix to use for the individual generator methods -# -METHOD_PREFIX = "_generate" - -# Lazy initialization to avoid circular imports -_settingsManager = None - -def _ensureSettingsManager(): - """Ensure settings manager is initialized.""" - global _settingsManager - if _settingsManager is None: - from . import cthulhu - _settingsManager = cthulhu.cthulhu.cthulhuApp.settingsManager - -class Generator: - """Takes accessible objects and generates a presentation for those - objects. See the generate method, which is the primary entry - point.""" - - def __init__(self, script, mode): - self._mode = mode - self._script = script - self._activeProgressBars = {} - self._methodsDict = {} - for method in \ - [z for z in [getattr(self, y).__get__(self, self.__class__) \ - for y in [x for x in dir(self) if x.startswith(METHOD_PREFIX)]] \ - if isinstance(z, collections_abc.Callable)]: - name = method.__name__[len(METHOD_PREFIX):] - name = name[0].lower() + name[1:] - self._methodsDict[name] = method - self._verifyFormatting() - - def _addGlobals(self, globalsDict): - """Other things to make available from the formatting string. - """ - globalsDict['obj'] = None - globalsDict['role'] = None - - def _verifyFormatting(self): - - # Verify the formatting strings are OK. This is only - # for verification and does not effect the function of - # Cthulhu at all. - - # Populate the entire globals with empty arrays - # for the results of all the legal method names. - # - globalsDict = {} - for key in self._methodsDict.keys(): - globalsDict[key] = [] - self._addGlobals(globalsDict) - - for roleKey in self._script.formatting[self._mode]: - for key in ["focused", "unfocused"]: - try: - evalString = \ - self._script.formatting[self._mode][roleKey][key] - except Exception: - continue - else: - if not evalString: - # It's legal to have an empty string. - # - continue - while True: - try: - eval(evalString, globalsDict) - break - except NameError: - info = _formatExceptionInfo() - arg = info[1][0] - arg = arg.replace("name '", "") - arg = arg.replace("' is not defined", "") - if arg not in self._methodsDict: - debug.printException(debug.LEVEL_SEVERE) - globalsDict[arg] = [] - except Exception: - debug.printException(debug.LEVEL_SEVERE) - break - - def _overrideRole(self, newRole, args): - """Convenience method to allow you to temporarily override the role in - the args dictionary. This changes the role in args ags - returns the old role so you can pass it back to _restoreRole. - """ - oldRole = args.get('role', None) - args['role'] = newRole - return oldRole - - def _restoreRole(self, oldRole, args): - """Convenience method to restore the old role back in the args - dictionary. The oldRole should have been obtained from - _overrideRole. If oldRole is None, then the 'role' key/value - pair will be deleted from args. - """ - if oldRole: - args['role'] = oldRole - else: - del args['role'] - - def generateContents(self, contents, **args): - return [] - - def generateContext(self, obj, **args): - return [] - - def generate(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the complete presentation for the - object. The presentation to be generated depends highly upon the - formatting strings in formatting.py. - - args is a dictionary that may contain any of the following: - - alreadyFocused: if True, we're getting an object - that previously had focus - - priorObj: if set, represents the object that had focus before - this object - - includeContext: boolean (default=True) which says whether - the context for an object should be included as a prefix - and suffix - - role: a role to override the object's role - - formatType: the type of formatting, such as - 'focused', 'basicWhereAmI', etc. - - forceMnemonic: boolean (default=False) which says if we - should ignore the settings.enableMnemonicSpeaking setting - - forceTutorial: boolean (default=False) which says if we - should force a tutorial to be spoken or not - """ - - if AXObject.is_dead(obj): - msg = "GENERATOR: Cannot generate presentation for dead obj" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return [] - - startTime = time.time() - result = [] - globalsDict = {} - self._addGlobals(globalsDict) - globalsDict['obj'] = obj - try: - globalsDict['role'] = args.get('role', AXObject.get_role(obj)) - except Exception as error: - tokens = ["GENERATOR: Cannot generate presentation for", obj, ":", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return result - try: - # We sometimes want to override the role. We'll keep the - # role in the args dictionary as a means to let us do so. - # - args['role'] = globalsDict['role'] - - # We loop through the format string, catching each error - # as we go. Each error should always be a NameError, - # where the name is the name of one of our generator - # functions. When we encounter this, we call the function - # and get its results, placing them in the globals for the - # the call to eval. - # - args['mode'] = self._mode - if not args.get('formatType', None): - if args.get('alreadyFocused', False): - args['formatType'] = 'focused' - else: - args['formatType'] = 'unfocused' - - formatting = self._script.formatting.getFormat(**args) - - # Add in the context if this is the first time - # we've been called. - # - if not args.get('recursing', False): - if args.get('includeContext', True): - prefix = self._script.formatting.getPrefix(**args) - suffix = self._script.formatting.getSuffix(**args) - formatting = f'{prefix} + {formatting} + {suffix}' - args['recursing'] = True - - tokens = [self._mode.upper(), "GENERATOR: Starting", args.get('formatType'), - "generation for", obj, "(using role:", args.get('role'), ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # Reset 'usedDescriptionFor*' if a previous generator used it. - self._script.pointOfReference['usedDescriptionForName'] = False - self._script.pointOfReference['usedDescriptionForUnrelatedLabels'] = False - self._script.pointOfReference['usedDescriptionForAlert'] = False - - def debuginfo(x): - return self._resultElementToString(x, False) - - assert(formatting) - while True: - currentTime = time.time() - try: - result = eval(formatting, globalsDict) - break - except NameError: - result = [] - info = _formatExceptionInfo() - arg = info[1][0] - arg = arg.replace("name '", "") - arg = arg.replace("' is not defined", "") - if arg not in self._methodsDict: - debug.printException(debug.LEVEL_SEVERE) - break - globalsDict[arg] = self._methodsDict[arg](obj, **args) - duration = f"{time.time() - currentTime:.4f}" - if isinstance(globalsDict[arg], list): - stringResult = " ".join(filter(lambda x: x, - map(debuginfo, globalsDict[arg]))) - debug.printMessage(debug.LEVEL_ALL, - "%sGENERATION TIME: %s ----> %s=[%s]" \ - % (" " * 18, duration, arg, stringResult)) - - except Exception: - debug.printException(debug.LEVEL_SEVERE) - result = [] - - duration = f"{time.time() - startTime:.4f}" - debug.printMessage(debug.LEVEL_ALL, f"{' ' * 18}COMPLETION TIME: {duration}") - self._debugResultInfo(result) - if args.get('isProgressBarUpdate') and result and result[0]: - self.setProgressBarUpdateTimeAndValue(obj) - - return result - - def _resultElementToString(self, element, includeAll=True): - if not includeAll: - return str(element).replace("\n", "\\n") - - return f"\n{' ' * 18}'{element}'" - - def _debugResultInfo(self, result): - if debug.LEVEL_ALL < debug.debugLevel: - return - - info = f"{' ' * 18}{self._mode.upper()} GENERATOR: Results: " - info += f"{' '.join(map(self._resultElementToString, result))}" - debug.printMessage(debug.LEVEL_ALL, info) - - ##################################################################### - # # - # Name, role, and label information # - # # - ##################################################################### - - def _generateRoleName(self, obj, **args): - """Returns the role name for the object in an array of strings, with - the exception that the Atspi.Role.UNKNOWN role will yield an - empty array. Note that a 'role' attribute in args will - override the accessible role of the obj. - """ - # Subclasses must override this. - return [] - - def _fallBackOnDescriptionForName(self, obj, **args): - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.LABEL: - return False - - return True - - def _generateName(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the name of the object. If the object is directly - displaying any text, that text will be treated as the name. - Otherwise, the accessible name of the object will be used. If - there is no accessible name, then the description of the - object will be used. This method will return an empty array - if nothing can be found. [[[WDW - I wonder if we should just - have _generateName, _generateDescription, - _generateDisplayedText, etc., that don't do any fallback. - Then, we can allow the formatting to do the fallback (e.g., - 'displayedText or name or description'). [[[JD to WDW - I - needed a _generateDescription for whereAmI. :-) See below. - """ - result = [] - self._script.pointOfReference['usedDescriptionForName'] = False - name = AXObject.get_name(obj) - role = args.get('role', AXObject.get_role(obj)) - parent = AXObject.get_parent(obj) - if name: - result.append(name) - elif self._fallBackOnDescriptionForName(obj, **args): - description = AXObject.get_description(obj) - if description: - result.append(description) - self._script.pointOfReference['usedDescriptionForName'] = True - else: - link = None - if role == Atspi.Role.LINK: - link = obj - elif AXUtilities.is_link(parent): - link = parent - if link: - basename = self._script.utilities.linkBasenameToName(link) - if basename: - result.append(basename) - # To make the unlabeled icons in gnome-panel more accessible. - if not result and role == Atspi.Role.ICON and AXUtilities.is_panel(parent): - return self._generateName(parent) - - return result - - def _generatePlaceholderText(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the 'placeholder' text. This is typically text that - serves as a functional label and is found in a text widget until - that widget is given focus at which point the text is removed, - the assumption being that the user was able to see the text prior - to giving the widget focus. - """ - attrs = self._script.utilities.objectAttributes(obj) - placeholder = attrs.get('placeholder-text') - if placeholder and placeholder != AXObject.get_name(obj): - return [placeholder] - - placeholder = attrs.get('placeholder') - if placeholder and placeholder != AXObject.get_name(obj): - return [placeholder] - - return [] - - def _generateLabelAndName(self, obj, **args): - """Returns the label and the name as an array of strings for speech - and braille. The name will only be present if the name is - different from the label. - """ - result = [] - label = self._generateLabel(obj, **args) - name = self._generateName(obj, **args) - role = args.get('role', AXObject.get_role(obj)) - if not (label or name) and role == Atspi.Role.TABLE_CELL: - descendant = self._script.utilities.realActiveDescendant(obj) - name = self._generateName(descendant) - - # If we don't have a label, always use the name. - if not label: - return name - - result.extend(label) - if not name: - return result - - # Try to eliminate names which are redundant to the label. - # Convert all non-alphanumeric characters to space and get the words. - nameWords = re.sub(r"[\W_]", " ", name[0]).split() - labelWords = re.sub(r"[\W_]", " ", label[0]).split() - - # If all of the words in the name are in the label, the name is redundant. - if set(nameWords).issubset(set(labelWords)): - tokens = ["GENERATOR: name '", name[0], "' is redundant to label '", label[0], "'"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return result - - result.extend(name) - return result - - def _generateLabelOrName(self, obj, **args): - """Returns the label as an array of strings for speech and braille. - If the label cannot be found, the name will be used instead. - If the name cannot be found, an empty array will be returned. - """ - result = self._generateLabel(obj, **args) - if not result: - result = self._generateName(obj, **args) - - return result - - def _generateUnrelatedLabelsOrDescription(self, obj, **args): - result = self._generateUnrelatedLabels(obj, **args) - if result: - self._script.pointOfReference['usedDescriptionForUnrelatedLabels'] = False - return result - - result = self._generateDescription(obj, **args) - if result: - self._script.pointOfReference['usedDescriptionForUnrelatedLabels'] = True - - return result - - def _generateDescription(self, obj, **args): - """Returns an array of strings fo use by speech and braille that - represent the description of the object, if that description - is different from that of the name and label. - """ - - if self._script.pointOfReference.get('usedDescriptionForName'): - return [] - - if self._script.pointOfReference.get('usedDescriptionForAlert'): - return [] - - if self._script.pointOfReference.get('usedDescriptionForUnrelatedLabels'): - return [] - - description = AXObject.get_description(obj) \ - or self._script.utilities.displayedDescription(obj) or "" - if not description: - return [] - - name = AXObject.get_name(obj) - role = args.get('role', AXObject.get_role(obj)) - - try: - tokens = self._script.formatting[self._mode][role][args.get('formatType')].split() - isLabelAndName = 'labelAndName' in tokens - isLabelOrName = 'labelOrName' in tokens - except Exception: - isLabelAndName = False - isLabelOrName = False - - canUse = True - label = self._script.utilities.displayedLabel(obj) or "" - if isLabelAndName: - canUse = not self._script.utilities.stringsAreRedundant(name, description) \ - and not self._script.utilities.stringsAreRedundant(label, description) - elif isLabelOrName and label: - canUse = not self._script.utilities.stringsAreRedundant(label, description) - else: - canUse = not self._script.utilities.stringsAreRedundant(name, description) - - if not canUse: - return [] - - return [description] - - def _generateLabel(self, obj, **args): - """Returns the label for an object as an array of strings for use by - speech and braille. The label is determined by the displayedLabel - method of the script utility, and an empty array will be returned if - no label can be found. - """ - result = [] - label = self._script.utilities.displayedLabel(obj) - if label: - result.append(label) - return result - - def _generateStatusBar(self, obj, **args): - """Returns an array of strings that represent a status bar.""" - - return [] - - def _generateTermValueCount(self, obj, **args): - return [] - - ##################################################################### - # # - # Image information # - # # - ##################################################################### - - def _generateImageDescription(self, obj, **args ): - """Returns an array of strings for use by speech and braille that - represent the description of the image on the object, if it - exists. Otherwise, an empty array is returned. - """ - result = [] - description = AXObject.get_image_description(obj) - if description and len(description): - result.append(description) - return result - - ##################################################################### - # # - # State information # - # # - ##################################################################### - - def _generateClickable(self, obj, **args): - return [] - - def _generateHasLongDesc(self, obj, **args): - return [] - - def _generateHasDetails(self, obj, **args): - return [] - - def _generateDetailsFor(self, obj, **args): - return [] - - def _generateAllDetails(self, obj, **args): - return [] - - def _generateHasPopup(self, obj, **args): - return [] - - def _generateAvailability(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the grayed/sensitivity/availability state of the - object, but only if it is insensitive (i.e., grayed out and - inactive). Otherwise, and empty array will be returned. - """ - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'insensitive' - if not AXUtilities.is_sensitive(obj): - result.append(self._script.formatting.getString(**args)) - return result - - def _generateInvalid(self, obj, **args): - error = self._script.utilities.getError(obj) - if not error: - return [] - - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'invalid' - indicators = self._script.formatting.getString(**args) - - if error == 'spelling': - indicator = indicators[1] - elif error == 'grammar': - indicator = indicators[2] - else: - indicator = indicators[0] - - errorMessage = self._script.utilities.getErrorMessage(obj) - if errorMessage: - result.append(f"{indicator}: {errorMessage}") - else: - result.append(indicator) - - return result - - def _generateRequired(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the required state of the object, but only if it is - required (i.e., it is in a dialog requesting input and the - user must give it a value). Otherwise, and empty array will - be returned. - """ - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'required' - isRequired = AXUtilities.is_required(obj) - if not isRequired and AXUtilities.is_radio_button(obj): - parent = AXObject.get_parent(obj) - isRequired = AXUtilities.is_required(parent) - if isRequired: - result.append(self._script.formatting.getString(**args)) - return result - - def _generateReadOnly(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the read only state of this object, but only if it - is read only (i.e., it is a text area that cannot be edited). - """ - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'readonly' - if AXUtilities.is_read_only(obj) \ - or self._script.utilities.isReadOnlyTextArea(obj): - result.append(self._script.formatting.getString(**args)) - return result - - def _generateCellCheckedState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the checked state of the object. This is typically - for check boxes that are in a table. An empty array will be - returned if this is not a checkable cell. - """ - result = [] - if self._script.utilities.hasMeaningfulToggleAction(obj): - oldRole = self._overrideRole(Atspi.Role.CHECK_BOX, args) - result.extend(self.generate(obj, **args)) - self._restoreRole(oldRole, args) - - return result - - def _generateCheckedState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the checked state of the object. This is typically - for check boxes. [[[WDW - should we return an empty array if - we can guarantee we know this thing is not checkable?]]] - """ - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'checkbox' - indicators = self._script.formatting.getString(**args) - if AXUtilities.is_checked(obj): - result.append(indicators[1]) - elif AXUtilities.is_indeterminate(obj): - result.append(indicators[2]) - else: - result.append(indicators[0]) - return result - - def _generateRadioState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the checked state of the object. This is typically - for check boxes. [[[WDW - should we return an empty array if - we can guarantee we know this thing is not checkable?]]] - """ - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'radiobutton' - indicators = self._script.formatting.getString(**args) - if AXUtilities.is_checked(obj): - result.append(indicators[1]) - else: - result.append(indicators[0]) - return result - - def _generateChildWidget(self, obj, **args): - widgetRoles = [Atspi.Role.CHECK_BOX, - Atspi.Role.COMBO_BOX, - Atspi.Role.PUSH_BUTTON, - Atspi.Role.RADIO_BUTTON, - Atspi.Role.SLIDER, - Atspi.Role.TOGGLE_BUTTON] - - def isWidget(x): - return AXObject.get_role(x) in widgetRoles - - # For GtkListBox, such as those found in the control center - if AXUtilities.is_list_box(AXObject.get_parent(obj)): - widget = AXObject.find_descendant(obj, isWidget) - if widget: - return self.generate(widget, includeContext=False) - - return [] - - def _generateSwitchState(self, obj, **args): - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'switch' - indicators = self._script.formatting.getString(**args) - if AXUtilities.is_checked(obj) or AXUtilities.is_pressed(obj): - result.append(indicators[1]) - else: - result.append(indicators[0]) - return result - - def _generateToggleState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the checked state of the object. This is typically - for check boxes. [[[WDW - should we return an empty array if - we can guarantee we know this thing is not checkable?]]] - """ - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'togglebutton' - indicators = self._script.formatting.getString(**args) - if AXUtilities.is_checked(obj) or AXUtilities.is_pressed(obj): - result.append(indicators[1]) - else: - result.append(indicators[0]) - return result - - def _generateCheckedStateIfCheckable(self, obj, **args): - if AXUtilities.is_checkable(obj) or AXUtilities.is_check_menu_item(obj): - return self._generateCheckedState(obj, **args) - - if AXUtilities.is_checked(obj): - return self._generateCheckedState(obj, **args) - - return [] - - def _generateMenuItemCheckedState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the checked state of the menu item, only if it is - checked. Otherwise, and empty array will be returned. - """ - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'checkbox' - indicators = self._script.formatting.getString(**args) - if AXUtilities.is_checked(obj): - result.append(indicators[1]) - return result - - def _generateExpandableState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the expanded/collapsed state of an object, such as a - tree node. If the object is not expandable, an empty array - will be returned. - """ - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'expansion' - indicators = self._script.formatting.getString(**args) - if AXUtilities.is_collapsed(obj): - result.append(indicators[0]) - elif AXUtilities.is_expanded(obj): - result.append(indicators[1]) - elif AXUtilities.is_expandable(obj): - result.append(indicators[0]) - - return result - - def _generateMultiselectableState(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the multiselectable state of - the object. This is typically for list boxes. If the object - is not multiselectable, an empty array will be returned. - """ - - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'multiselect' - if AXUtilities.is_multiselectable(obj) and AXObject.get_child_count(obj): - result.append(self._script.formatting.getString(**args)) - return result - - ##################################################################### - # # - # Table interface information # - # # - ##################################################################### - - def _generateRowHeader(self, obj, **args): - """Returns an array of strings to be used in speech and braille that - represent the row header for an object that is in a table, if - it exists. Otherwise, an empty array is returned. - """ - - if args.get('readingRow'): - return [] - - result = [] - header = self._script.utilities.rowHeaderForCell(obj) - if not header: - return result - - text = self._script.utilities.displayedText(header) - if not text: - return result - - roleString = self.getLocalizedRoleName(obj, role=Atspi.Role.ROW_HEADER) - if args.get('mode') == 'speech': - if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE \ - and args.get('formatType') not in ['basicWhereAmI', 'detailedWhereAmI']: - text = f"{text} {roleString}" - elif args.get('mode') == 'braille': - text = f"{text} {roleString}" - - result.append(text) - return result - - def _generateColumnHeader(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the column header for an object - that is in a table, if it exists. Otherwise, an empty array - is returned. - """ - result = [] - header = self._script.utilities.columnHeaderForCell(obj) - if not header: - return result - - text = self._script.utilities.displayedText(header) - if not text: - return result - - roleString = self.getLocalizedRoleName(obj, role=Atspi.Role.COLUMN_HEADER) - if args.get('mode') == 'speech': - if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE \ - and args.get('formatType') not in ['basicWhereAmI', 'detailedWhereAmI']: - text = f"{text} {roleString}" - elif args.get('mode') == 'braille': - text = f"{text} {roleString}" - - result.append(text) - return result - - def _generateSortOrder(self, obj, **args): - description = self._script.utilities.getSortOrderDescription(obj) - if not description: - return [] - - return [description] - - def _generateTableCell2ChildLabel(self, obj, **args): - """Returns an array of strings for use by speech and braille for the - label of a toggle in a table cell that has a special 2 child - pattern that we run into. Otherwise, an empty array is - returned. - """ - result = [] - - # If this table cell has 2 children and one of them has a - # 'toggle' action and the other does not, then present this - # as a checkbox where: - # 1) we get the checked state from the cell with the 'toggle' action - # 2) we get the label from the other cell. - # See Cthulhu bug #376015 for more details. - # - if AXObject.get_child_count(obj) == 2: - cellOrder = [] - hasToggle = [False, False] - for i, child in enumerate(obj): - if self._script.utilities.hasMeaningfulToggleAction(child): - hasToggle[i] = True - break - if hasToggle[0] and not hasToggle[1]: - cellOrder = [ 1, 0 ] - elif not hasToggle[0] and hasToggle[1]: - cellOrder = [ 0, 1 ] - if cellOrder: - for i in cellOrder: - if not hasToggle[i]: - result.extend(self.generate(AXObject.get_child(obj, i), **args)) - return result - - def _generateTableCell2ChildToggle(self, obj, **args): - """Returns an array of strings for use by speech and braille for the - toggle value of a toggle in a table cell that has a special 2 - child pattern that we run into. Otherwise, an empty array is - returned. - """ - result = [] - - # If this table cell has 2 children and one of them has a - # 'toggle' action and the other does not, then present this - # as a checkbox where: - # 1) we get the checked state from the cell with the 'toggle' action - # 2) we get the label from the other cell. - # See Cthulhu bug #376015 for more details. - # - if AXObject.get_child_count(obj) == 2: - cellOrder = [] - hasToggle = [False, False] - for i, child in enumerate(obj): - if self._script.utilities.hasMeaningfulToggleAction(child): - hasToggle[i] = True - break - if hasToggle[0] and not hasToggle[1]: - cellOrder = [ 1, 0 ] - elif not hasToggle[0] and hasToggle[1]: - cellOrder = [ 0, 1 ] - if cellOrder: - for i in cellOrder: - if hasToggle[i]: - result.extend(self.generate(AXObject.get_child(obj, i), **args)) - return result - - def _generateColumnHeaderIfToggleAndNoText(self, obj, **args): - """If this table cell has a "toggle" action, and doesn't have any - label associated with it then also speak the table column - header. See Cthulhu bug #455230 for more details. - """ - # If we're reading just a single cell in speech, the new - # header portion is going to give us this information. - # - if args['mode'] == 'speech' and not args.get('readingRow', False): - return [] - - result = [] - descendant = self._script.utilities.realActiveDescendant(obj) - label = self._script.utilities.displayedText(descendant) - if not label and self._script.utilities.hasMeaningfulToggleAction(obj): - accHeader = self._script.utilities.columnHeaderForCell(obj) - if (accHeader): - result.append(AXObject.get_name(accHeader)) - return result - - def _generateRealTableCell(self, obj, **args): - """Cthulhu has a feature to automatically read an entire row of a table - as the user arrows up/down the roles. This leads to - complexity in the code. This method is used to return an - array of strings for use by speech and braille for a single - table cell itself. The string, 'blank', is added for empty - cells. - """ - result = [] - oldRole = self._overrideRole(role_keys.REAL_ROLE_TABLE_CELL, args) - result.extend(self.generate(obj, **args)) - self._restoreRole(oldRole, args) - return result - - def _generateTable(self, obj, **args): - """Returns an array of strings for use by speech and braille to present - the size of a table.""" - - if self._script.utilities.isLayoutOnly(obj): - return [] - - if self._script.utilities.isSpreadSheetTable(obj): - return [] - - rows, cols = self._script.utilities.rowAndColumnCount(obj) - - # This suggests broken or missing table interface. - if (rows < 0 or cols < 0) \ - and not self._script.utilities.rowOrColumnCountUnknown(obj): - return [] - - # This can happen if an author uses ARIA incorrectly, e.g. a grid whose - # immediate child is a gridcell rather than a row. In that case, just - # announce the role name. - if rows == 0 and cols == 0: - return self._generateRoleName(obj, **args) - - return [messages.tableSize(rows, cols)] - - def _generateTableCellRow(self, obj, **args): - """Cthulhu has a feature to automatically read an entire row of a table - as the user arrows up/down the roles. This leads to complexity in - the code. This method is used to return an array of strings - (and possibly voice and audio specifications) for an entire row - in a table if that's what the user has requested and if the row - has changed. Otherwise, it will return an array for just the - current cell. - """ - - presentAll = args.get('readingRow') is True \ - or args.get('formatType') == 'detailedWhereAmI' \ - or self._mode == 'braille' \ - or self._script.utilities.shouldReadFullRow(obj) - - if not presentAll: - return self._generateRealTableCell(obj, **args) - - args['readingRow'] = True - result = [] - cells = self._script.utilities.getShowingCellsInSameRow(obj, forceFullRow=True) - - # Remove any pre-calcuated values which only apply to obj and not row cells. - doNotInclude = ['startOffset', 'endOffset', 'string'] - otherCellArgs = args.copy() - for arg in doNotInclude: - otherCellArgs.pop(arg, None) - - for cell in cells: - if cell == obj: - cellResult = self._generateRealTableCell(cell, **args) - else: - cellResult = self._generateRealTableCell(cell, **otherCellArgs) - if cellResult and result and self._mode == 'braille': - result.append(braille.Region(object_properties.TABLE_CELL_DELIMITER_BRAILLE)) - result.extend(cellResult) - - result.extend(self._generatePositionInList(obj, **args)) - return result - - ##################################################################### - # # - # Text interface information # - # # - ##################################################################### - - def _generateExpandedEOCs(self, obj, **args): - """Returns the expanded embedded object characters for an object.""" - return [] - - def _generateSubstring(self, obj, **args): - start = args.get('startOffset') - end = args.get('endOffset') - if start is None or end is None: - return [] - - substring = args.get('string', self._script.utilities.substring(obj, start, end)) - if substring and self._script.EMBEDDED_OBJECT_CHARACTER not in substring: - return [substring] - - return [] - - def _generateStartOffset(self, obj, **args): - return args.get('startOffset') - - def _generateEndOffset(self, obj, **args): - return args.get('endOffset') - - def _generateCurrentLineText(self, obj, **args ): - """Returns an array of strings for use by speech and braille - that represents the current line of text, if - this is a text object. [[[WDW - consider returning an empty - array if this is not a text object.]]] - """ - result = self._generateSubstring(obj, **args) - if result: - return result - - [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj) - if text and self._script.EMBEDDED_OBJECT_CHARACTER not in text: - return [text] - - return [] - - def _generateDisplayedText(self, obj, **args ): - """Returns an array of strings for use by speech and braille that - represents all the text being displayed by the object. - """ - result = self._generateSubstring(obj, **args) - if result: - return result - - displayedText = self._script.utilities.displayedText(obj) - if not displayedText: - return [] - - return [displayedText] - - ##################################################################### - # # - # Tree interface information # - # # - ##################################################################### - - def _generateNodeLevel(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represents the tree node level of the object, or an empty - array if the object is not a tree node. - """ - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'nodelevel' - level = self._script.utilities.nodeLevel(obj) - if level >= 0: - result.append(self._script.formatting.getString(**args)\ - % (level + 1)) - return result - - ##################################################################### - # # - # Value interface information # - # # - ##################################################################### - - def _generateValue(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represents the value of the object. This is typically the - numerical value, but may also be the text of the 'value' - attribute if it exists on the object. [[[WDW - we should - consider returning an empty array if there is no value. - """ - - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.COMBO_BOX: - value = self._script.utilities.getComboBoxValue(obj) - return [value] - - if role == Atspi.Role.SEPARATOR and not AXUtilities.is_focused(obj): - return [] - - return [self._script.utilities.textForValue(obj)] - - ##################################################################### - # # - # Hierarchy and related dialog information # - # # - ##################################################################### - - def _generateApplicationName(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represents the name of the application for the object. - """ - result = [] - name = AXObject.get_name(AXObject.get_application(obj)) - if name: - result.append(name) - return result - - def _generateNestingLevel(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the nesting level of an object in a list. - """ - start = args.get('startOffset') - end = args.get('endOffset') - if start is not None and end is not None: - return [] - - result = [] - if not args.get('mode', None): - args['mode'] = self._mode - args['stringType'] = 'nestinglevel' - nestingLevel = self._script.utilities.nestingLevel(obj) - if nestingLevel: - result.append(self._script.formatting.getString(**args)\ - % nestingLevel) - return result - - def _generateRadioButtonGroup(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represents the radio button group label for the object, or an - empty array if the object has no such label. - """ - if not AXUtilities.is_radio_button(obj): - return [] - - radioGroupLabel = None - labelledBy = AXUtilitiesRelation.get_is_labelled_by(obj) - if labelledBy: - radioGroupLabel = labelledBy[0] - if radioGroupLabel: - return [self._script.utilities.displayedText(radioGroupLabel)] - - parent = AXObject.get_parent_checked(obj) - while parent: - if AXUtilities.is_panel(parent) or AXUtilities.is_filler(parent): - label = self._generateLabelAndName(parent) - if label: - return label - parent = AXObject.get_parent_checked(parent) - return [] - - def _generateRealActiveDescendantDisplayedText(self, obj, **args ): - """Objects, such as tables and trees, can represent individual cells - via a complicated nested hierarchy. This method returns an - array of strings for use by speech and braille that represents - the text actually being painted in the cell, if it can be - found. Otherwise, an empty array is returned. - """ - rad = self._script.utilities.realActiveDescendant(obj) - - if not (AXUtilities.is_table_cell(rad) and AXObject.get_child_count(rad)): - return self._generateDisplayedText(rad, **args) - - content = { - (AXObject.get_name(x) or AXText.get_all_text(x)).strip() - for x in AXObject.iter_children(rad) - } - rv = " ".join(filter(lambda x: x, content)) - if not rv: - return self._generateDisplayedText(rad, **args) - return [rv] - - def _generateRealActiveDescendantRoleName(self, obj, **args ): - """Objects, such as tables and trees, can represent individual cells - via a complicated nested hierarchy. This method returns an - array of strings for use by speech and braille that represents - the role of the object actually being painted in the cell. - """ - rad = self._script.utilities.realActiveDescendant(obj) - args['role'] = AXObject.get_role(rad) - return self._generateRoleName(rad, **args) - - def _generateNamedContainingPanel(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represents the nearest ancestor of an object which is a named panel. - """ - result = [] - parent = AXObject.get_parent_checked(obj) - while parent: - if AXUtilities.is_panel(parent): - label = self._generateLabelAndName(parent) - if label: - result.extend(label) - break - parent = AXObject.get_parent_checked(parent) - return result - - def _generatePageSummary(self, obj, **args): - return [] - - def _generatePositionInList(self, obj, **args): - return [] - - def _generateProgressBarIndex(self, obj, **args): - return [] - - def _generateProgressBarValue(self, obj, **args): - return [] - - def _getProgressBarUpdateInterval(self): - _ensureSettingsManager() - return int(cthulhu.cthulhuApp.settingsManager.getSetting('progressBarUpdateInterval')) - - def _shouldPresentProgressBarUpdate(self, obj, **args): - percent = self._script.utilities.getValueAsPercent(obj) - lastTime, lastValue = self.getProgressBarUpdateTimeAndValue(obj, type=self) - if percent == lastValue: - tokens = ["GENERATOR: Not presenting update for", obj, ". Value still", percent] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if percent == 100: - return True - - interval = int(time.time() - lastTime) - return interval >= self._getProgressBarUpdateInterval() - - def _cleanUpCachedProgressBars(self): - def isValid(x): - return not (self._script.utilities.isZombie(x) or AXObject.is_dead(x)) - - bars = list(filter(isValid, self._activeProgressBars)) - self._activeProgressBars = {x:self._activeProgressBars.get(x) for x in bars} - - def _getMostRecentProgressBarUpdate(self): - self._cleanUpCachedProgressBars() - if not self._activeProgressBars.values(): - return None, 0.0, None - - sortedValues = sorted(self._activeProgressBars.values(), key=lambda x: x[0]) - prevTime, prevValue = sortedValues[-1] - return list(self._activeProgressBars.keys())[-1], prevTime, prevValue - - def getProgressBarNumberAndCount(self, obj): - self._cleanUpCachedProgressBars() - if obj not in self._activeProgressBars: - self._activeProgressBars[obj] = 0.0, None - - thisValue = self.getProgressBarUpdateTimeAndValue(obj) - index = list(self._activeProgressBars.values()).index(thisValue) - return index + 1, len(self._activeProgressBars) - - def getProgressBarUpdateTimeAndValue(self, obj, **args): - if obj not in self._activeProgressBars: - self._activeProgressBars[obj] = 0.0, None - - return self._activeProgressBars.get(obj) - - def setProgressBarUpdateTimeAndValue(self, obj, lastTime=None, lastValue=None): - lastTime = lastTime or time.time() - lastValue = lastValue or self._script.utilities.getValueAsPercent(obj) - self._activeProgressBars[obj] = lastTime, lastValue - - def _getAlternativeRole(self, obj, **args): - role = self._getMathAlternativeRole(obj) - if role: - return role - - role = self._getDPubAlternativeRole(obj) - if role: - return role - - role = self._getSwitchOrSpecialRole(obj) - if role: - return role - - role = self._getContentAlternativeRole(obj) - if role: - return role - - role = self._getDescriptionListRole(obj) - if role: - return role - - role = self._getFeedAlternativeRole(obj) - if role: - return role - - role = self._getLandmarkAlternativeRole(obj) - if role: - return role - - if self._script.utilities.isDocument(obj) and AXObject.supports_image(obj): - return Atspi.Role.IMAGE - - return args.get('role', AXObject.get_role(obj)) - - def _getMathAlternativeRole(self, obj): - if not self._script.utilities.isMath(obj): - return None - if self._script.utilities.isMathSubOrSuperScript(obj): - return role_keys.ROLE_MATH_SCRIPT_SUBSUPER - if self._script.utilities.isMathUnderOrOverScript(obj): - return role_keys.ROLE_MATH_SCRIPT_UNDEROVER - if self._script.utilities.isMathMultiScript(obj): - return role_keys.ROLE_MATH_MULTISCRIPT - if self._script.utilities.isMathEnclose(obj): - return role_keys.ROLE_MATH_ENCLOSED - if self._script.utilities.isMathFenced(obj): - return role_keys.ROLE_MATH_FENCED - if self._script.utilities.isMathTable(obj): - return role_keys.ROLE_MATH_TABLE - if self._script.utilities.isMathTableRow(obj): - return role_keys.ROLE_MATH_TABLE_ROW - return None - - def _getDPubAlternativeRole(self, obj): - if not self._script.utilities.isDPub(obj): - return None - if self._script.utilities.isLandmark(obj): - return role_keys.ROLE_DPUB_LANDMARK - if AXUtilities.is_section(obj): - return role_keys.ROLE_DPUB_SECTION - return None - - def _getSwitchOrSpecialRole(self, obj): - if self._script.utilities.isSwitch(obj): - return role_keys.ROLE_SWITCH - if self._script.utilities.isAnchor(obj): - return Atspi.Role.STATIC - if self._script.utilities.isBlockquote(obj): - return Atspi.Role.BLOCK_QUOTE - if self._script.utilities.isComment(obj): - return Atspi.Role.COMMENT - return None - - def _getContentAlternativeRole(self, obj): - if self._script.utilities.isContentDeletion(obj): - return role_keys.ROLE_CONTENT_DELETION - if self._script.utilities.isContentError(obj): - return role_keys.ROLE_CONTENT_ERROR - if self._script.utilities.isContentInsertion(obj): - return role_keys.ROLE_CONTENT_INSERTION - if self._script.utilities.isContentMarked(obj): - return role_keys.ROLE_CONTENT_MARK - if self._script.utilities.isContentSuggestion(obj): - return role_keys.ROLE_CONTENT_SUGGESTION - return None - - def _getDescriptionListRole(self, obj): - if self._script.utilities.isDescriptionList(obj): - return Atspi.Role.DESCRIPTION_LIST - if self._script.utilities.isDescriptionListTerm(obj): - return Atspi.Role.DESCRIPTION_TERM - if self._script.utilities.isDescriptionListDescription(obj): - return Atspi.Role.DESCRIPTION_VALUE - return None - - def _getFeedAlternativeRole(self, obj): - if self._script.utilities.isFeedArticle(obj): - return role_keys.ROLE_ARTICLE_IN_FEED - if self._script.utilities.isFeed(obj): - return role_keys.ROLE_FEED - return None - - def _getLandmarkAlternativeRole(self, obj): - if not self._script.utilities.isLandmark(obj): - return None - if self._script.utilities.isLandmarkRegion(obj): - return role_keys.ROLE_REGION - return Atspi.Role.LANDMARK - - def getLocalizedRoleName(self, obj, **args): - role = args.get('role', AXObject.get_role(obj)) - - if AXObject.supports_value(obj): - if AXUtilities.is_horizontal_slider(obj): - return object_properties.ROLE_SLIDER_HORIZONTAL - if AXUtilities.is_vertical_slider(obj): - return object_properties.ROLE_SLIDER_VERTICAL - if AXUtilities.is_horizontal_scrollbar(obj): - return object_properties.ROLE_SCROLL_BAR_HORIZONTAL - if AXUtilities.is_vertical_scrollbar(obj): - return object_properties.ROLE_SCROLL_BAR_VERTICAL - if AXUtilities.is_horizontal_separator(obj): - return object_properties.ROLE_SPLITTER_HORIZONTAL - if AXUtilities.is_vertical_separator(obj): - return object_properties.ROLE_SPLITTER_VERTICAL - if AXUtilities.is_split_pane(obj) \ - and (AXUtilities.is_focused(obj) or args.get('alreadyFocused', False)): - # The splitter has the opposite orientation of the split pane. - if AXUtilities.is_horizontal(obj): - return object_properties.ROLE_SPLITTER_VERTICAL - if AXUtilities.is_vertical(obj): - return object_properties.ROLE_SPLITTER_HORIZONTAL - - if self._script.utilities.isContentSuggestion(obj): - return object_properties.ROLE_CONTENT_SUGGESTION - - if self._script.utilities.isFeed(obj): - return object_properties.ROLE_FEED - - if self._script.utilities.isFigure(obj): - return object_properties.ROLE_FIGURE - - if self._script.utilities.isMenuButton(obj): - return object_properties.ROLE_MENU_BUTTON - - if self._script.utilities.isSwitch(obj): - return object_properties.ROLE_SWITCH - - if self._script.utilities.isDPub(obj): - if self._script.utilities.isLandmark(obj): - if self._script.utilities.isDPubAcknowledgments(obj): - return object_properties.ROLE_ACKNOWLEDGMENTS - if self._script.utilities.isDPubAfterword(obj): - return object_properties.ROLE_AFTERWORD - if self._script.utilities.isDPubAppendix(obj): - return object_properties.ROLE_APPENDIX - if self._script.utilities.isDPubBibliography(obj): - return object_properties.ROLE_BIBLIOGRAPHY - if self._script.utilities.isDPubChapter(obj): - return object_properties.ROLE_CHAPTER - if self._script.utilities.isDPubConclusion(obj): - return object_properties.ROLE_CONCLUSION - if self._script.utilities.isDPubCredits(obj): - return object_properties.ROLE_CREDITS - if self._script.utilities.isDPubEndnotes(obj): - return object_properties.ROLE_ENDNOTES - if self._script.utilities.isDPubEpilogue(obj): - return object_properties.ROLE_EPILOGUE - if self._script.utilities.isDPubErrata(obj): - return object_properties.ROLE_ERRATA - if self._script.utilities.isDPubForeword(obj): - return object_properties.ROLE_FOREWORD - if self._script.utilities.isDPubGlossary(obj): - return object_properties.ROLE_GLOSSARY - if self._script.utilities.isDPubIndex(obj): - return object_properties.ROLE_INDEX - if self._script.utilities.isDPubIntroduction(obj): - return object_properties.ROLE_INTRODUCTION - if self._script.utilities.isDPubPagelist(obj): - return object_properties.ROLE_PAGELIST - if self._script.utilities.isDPubPart(obj): - return object_properties.ROLE_PART - if self._script.utilities.isDPubPreface(obj): - return object_properties.ROLE_PREFACE - if self._script.utilities.isDPubPrologue(obj): - return object_properties.ROLE_PROLOGUE - if self._script.utilities.isDPubToc(obj): - return object_properties.ROLE_TOC - elif role == role_keys.ROLE_DPUB_SECTION: - if self._script.utilities.isDPubAbstract(obj): - return object_properties.ROLE_ABSTRACT - if self._script.utilities.isDPubColophon(obj): - return object_properties.ROLE_COLOPHON - if self._script.utilities.isDPubCredit(obj): - return object_properties.ROLE_CREDIT - if self._script.utilities.isDPubDedication(obj): - return object_properties.ROLE_DEDICATION - if self._script.utilities.isDPubEpigraph(obj): - return object_properties.ROLE_EPIGRAPH - if self._script.utilities.isDPubExample(obj): - return object_properties.ROLE_EXAMPLE - if self._script.utilities.isDPubPullquote(obj): - return object_properties.ROLE_PULLQUOTE - if self._script.utilities.isDPubQna(obj): - return object_properties.ROLE_QNA - elif role == Atspi.Role.LIST_ITEM: - if self._script.utilities.isDPubBiblioentry(obj): - return object_properties.ROLE_BIBLIOENTRY - if self._script.utilities.isDPubEndnote(obj): - return object_properties.ROLE_ENDNOTE - else: - if self._script.utilities.isDPubCover(obj): - return object_properties.ROLE_COVER - if self._script.utilities.isDPubPagebreak(obj): - return object_properties.ROLE_PAGEBREAK - if self._script.utilities.isDPubSubtitle(obj): - return object_properties.ROLE_SUBTITLE - - if self._script.utilities.isLandmark(obj): - if self._script.utilities.isLandmarkWithoutType(obj): - return '' - if self._script.utilities.isLandmarkBanner(obj): - return object_properties.ROLE_LANDMARK_BANNER - if self._script.utilities.isLandmarkComplementary(obj): - return object_properties.ROLE_LANDMARK_COMPLEMENTARY - if self._script.utilities.isLandmarkContentInfo(obj): - return object_properties.ROLE_LANDMARK_CONTENTINFO - if self._script.utilities.isLandmarkMain(obj): - return object_properties.ROLE_LANDMARK_MAIN - if self._script.utilities.isLandmarkNavigation(obj): - return object_properties.ROLE_LANDMARK_NAVIGATION - if self._script.utilities.isLandmarkRegion(obj): - return object_properties.ROLE_LANDMARK_REGION - if self._script.utilities.isLandmarkSearch(obj): - return object_properties.ROLE_LANDMARK_SEARCH - if self._script.utilities.isLandmarkForm(obj): - role = Atspi.Role.FORM - elif self._script.utilities.isComment(obj): - role = Atspi.Role.COMMENT - - if not isinstance(role, Atspi.Role): - try: - return obj.getLocalizedRoleName() - except Exception: - return '' - - nonlocalized = Atspi.role_get_name(role) - atkRole = Atk.role_for_name(nonlocalized) - if atkRole == Atk.Role.INVALID and role == Atspi.Role.STATUS_BAR: - atkRole = Atk.role_for_name("statusbar") - - return Atk.role_get_localized_name(atkRole) - - def getStateIndicator(self, obj, **args): - if self._script.utilities.isSwitch(obj): - return self._generateSwitchState(obj, **args) - - role = args.get('role', AXObject.get_role(obj)) - - if role == Atspi.Role.MENU_ITEM: - return self._generateMenuItemCheckedState(obj, **args) - - if role in [Atspi.Role.RADIO_BUTTON, Atspi.Role.RADIO_MENU_ITEM]: - return self._generateRadioState(obj, **args) - - if role in [Atspi.Role.CHECK_BOX, Atspi.Role.CHECK_MENU_ITEM]: - return self._generateCheckedState(obj, **args) - - if role == Atspi.Role.TOGGLE_BUTTON: - return self._generateToggleState(obj, **args) - - if role == Atspi.Role.TABLE_CELL: - return self._generateCellCheckedState(obj, **args) - - return [] - - def getValue(self, obj, **args): - role = args.get('role', AXObject.get_role(obj)) - - if role == Atspi.Role.PROGRESS_BAR: - return self._generateProgressBarValue(obj, **args) - - if role in [Atspi.Role.SCROLL_BAR, Atspi.Role.SLIDER]: - return self._generatePercentage(obj, **args) - - return [] diff --git a/src/cthulhu/gstreamer_support.py b/src/cthulhu/gstreamer_support.py deleted file mode 100644 index 48b1745..0000000 --- a/src/cthulhu/gstreamer_support.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -"""Compatibility helpers for GStreamer GI bindings.""" - -from __future__ import annotations - -from typing import Any - - -def gst_init_check_available(gst: Any) -> bool: - """Return Gst.init_check(None) availability across GI variants.""" - - initCheckResult = gst.init_check(None) - if isinstance(initCheckResult, tuple): - return bool(initCheckResult[0]) - - return bool(initCheckResult) diff --git a/src/cthulhu/guilabels.py b/src/cthulhu/guilabels.py deleted file mode 100644 index d7c0dfd..0000000 --- a/src/cthulhu/guilabels.py +++ /dev/null @@ -1,1003 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Labels for Cthulhu's GUIs. These have been put in their own module so that we -can present them in the correct language when users change the language on the -fly without having to reload a bunch of modules.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2013 The Cthulhu Team" -__license__ = "LGPL" - -from .cthulhu_i18n import _, C_, ngettext - -# Translators: This string appears on a button in a dialog. "Activating" the -# selected item will perform the action that one would expect to occur if the -# object were clicked on with the mouse. If the object is a link, activating -# it will bring you to a new page. If the object is a button, activating it -# will press the button. If the object is a combobox, activating it will expand -# it to show all of its contents. And so on. -ACTIVATE = _("_Activate") - -# Translators: Cthulhu has a number of commands that override the default behavior -# within an application. For instance, on a web page Cthulhu's Structural Navigation -# command "h" moves you to the next heading. What should happen when you press -# "h" in an entry on a web page depends: If you want to resume reading content, -# "h" should move to the next heading; if you want to enter text, "h" should not -# move you to the next heading. Because Cthulhu doesn't know what you want to do, -# it has two modes: In browse mode, Cthulhu treats key presses as commands to read -# the content; in focus mode, Cthulhu treats key presses as something that should be -# handled by the focused widget. Cthulhu optionally can attempt to detect which mode -# is appropriate for the current situation and switch automatically. This string -# is a label for a GUI option to enable such automatic switching when structural -# navigation commands are used. As an example, if this setting were enabled, -# pressing "e" to move to the next entry would move focus there and also turn -# focus mode on so that the next press of "e" would type an "e" into the entry. -# If this setting is not enabled, the second press of "e" would continue to be -# a navigation command to move amongst entries. -AUTO_FOCUS_MODE_STRUCT_NAV = _("Automatic focus mode during structural navigation") - -# Translators: Cthulhu has a number of commands that override the default behavior -# within an application. For instance, if you are at the bottom of an entry and -# press Down arrow, should you leave the entry? It depends on if you want to -# resume reading content or if you are editing the text in the entry. Because -# Cthulhu doesn't know what you want to do, it has two modes: In browse mode, Cthulhu -# treats key presses as commands to read the content; in focus mode, Cthulhu treats -# key presses as something that should be handled by the focused widget. Cthulhu -# optionally can attempt to detect which mode is appropriate for the current -# situation and switch automatically. This string is a label for a GUI option to -# enable such automatic switching when caret navigation commands are used. As an -# example, if this setting were enabled, pressing Down Arrow would allow you to -# move into an entry but once you had done so, Cthulhu would switch to Focus mode -# and subsequent presses of Down Arrow would be controlled by the web browser -# and not by Cthulhu. If this setting is not enabled, Cthulhu would continue to control -# what happens when you press an arrow key, thus making it possible to arrow out -# of the entry. -AUTO_FOCUS_MODE_CARET_NAV = _("Automatic focus mode during caret navigation") - -# Translators: Cthulhu has a number of commands that override the default behavior -# within an application. For instance, if you are at the bottom of an entry and -# press Down arrow, should you leave the entry? It depends on if you want to -# resume reading content or if you are editing the text in the entry. Because -# Cthulhu doesn't know what you want to do, it has two modes: In browse mode, Cthulhu -# treats key presses as commands to read the content; in focus mode, Cthulhu treats -# key presses as something that should be handled by the focused widget. Cthulhu -# optionally can attempt to detect which mode is appropriate for the current -# situation and switch automatically. This string is a label for a GUI option to -# enable such automatic switching when native navigation commands are used. -# Here "native" means "not Cthulhu"; it could be a browser navigation command such -# as the Tab key, or it might be a web page behavior, such as the search field -# automatically gaining focus when the page loads. -AUTO_FOCUS_MODE_NATIVE_NAV = _("Automatic focus mode during native navigation") - -# Translators: A single braille cell on a refreshable braille display consists -# of 8 dots. Dot 7 is the dot in the bottom left corner. If the user selects -# this option, Dot 7 will be used to 'underline' text of interest, e.g. when -# "marking"/indicating that a given word is bold. -BRAILLE_DOT_7 = _("Dot _7") - -# Translators: A single braille cell on a refreshable braille display consists -# of 8 dots. Dot 8 is the dot in the bottom right corner. If the user selects -# this option, Dot 8 will be used to 'underline' text of interest, e.g. when -# "marking"/indicating that a given word is bold. -BRAILLE_DOT_8 = _("Dot _8") - -# Translators: A single braille cell on a refreshable braille display consists -# of 8 dots. Dots 7-8 are the dots at the bottom. If the user selects this -# option, Dots 7-8 will be used to 'underline' text of interest, e.g. when -# "marking"/indicating that a given word is bold. -BRAILLE_DOT_7_8 = _("Dots 7 an_d 8") - -# Translators: This is the label for a button in a dialog. -BTN_CANCEL = _("_Cancel") - -# Translators: This is the label for a button in a dialog. -BTN_JUMP_TO = _("_Jump to") - -# Translators: This is the label for a button in a dialog. -BTN_OK = _("_OK") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via -# text-to-speech. Speech Dispatcher has a feature to control how capital -# letters are presented: Do nothing at all, say the word 'capital' prior to -# presenting a capital letter (which Speech Dispatcher refers to as 'spell'), -# or play a tone (which Speech Dispatcher refers to as a sound 'icon'.) This -# string to be translated appears as a combo box item in Cthulhu's Preferences. -CAPITALIZATION_STYLE_ICON = C_("capitalization style", "Icon") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via -# text-to-speech. Speech Dispatcher has a feature to control how capital -# letters are presented: Do nothing at all, say the word 'capital' prior to -# presenting a capital letter (which Speech Dispatcher refers to as 'spell'), -# or play a tone (which Speech Dispatcher refers to as a sound 'icon'.) This -# string to be translated appears as a combo box item in Cthulhu's Preferences. -CAPITALIZATION_STYLE_NONE = C_("capitalization style", "None") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via -# text-to-speech. Speech Dispatcher has a feature to control how capital -# letters are presented: Do nothing at all, say the word 'capital' prior to -# presenting a capital letter (which Speech Dispatcher refers to as 'spell'), -# or play a tone (which Speech Dispatcher refers to as a sound 'icon'.) This -# string to be translated appears as a combo box item in Cthulhu's Preferences. -CAPITALIZATION_STYLE_SPELL = C_("capitalization style", "Spell") - -# Translators: If this checkbox is checked, then Cthulhu will tell you when one of -# your buddies is typing a message. -CHAT_ANNOUNCE_BUDDY_TYPING = _("Announce when your _buddies are typing") - -# Translators: If this checkbox is checked, then Cthulhu will provide the user with -# chat room specific message histories rather than just a single history which -# contains the latest messages from all the chat rooms that they are in. -CHAT_SEPARATE_MESSAGE_HISTORIES = _("Provide chat room specific _message histories") - -# Translators: This is the label of a panel holding options for how messages in -# this application's chat rooms should be spoken. The options are: Speak messages -# from all channels (i.e. even if the chat application doesn't have focus); speak -# messages from a channel only if it is the active channel; speak messages from -# any channel, but only if the chat application has focus. -CHAT_SPEAK_MESSAGES_FROM = _("Speak messages from") - -# Translators: This is the label of a radio button. If it is selected, Cthulhu will -# speak all new chat messages as they appear irrespective of whether or not the -# chat application currently has focus. This is the default behaviour. -CHAT_SPEAK_MESSAGES_ALL = _("All cha_nnels") - -# Translators: This is the label of a radio button. If it is selected, Cthulhu will -# speak all new chat messages as they appear if and only if the chat application -# has focus. The string substitution is for the application name (e.g Pidgin). -CHAT_SPEAK_MESSAGES_ALL_IF_FOCUSED = _("All channels when an_y %s window is active") - -# Translators: This is the label of a radio button. If it is selected, Cthulhu will -# only speak new chat messages for the currently active channel, irrespective of -# whether the chat application has focus. -CHAT_SPEAK_MESSAGES_ACTIVE = _("A channel only if its _window is active") - -# Translators: If this checkbox is checked, then Cthulhu will speak the name of the -# chat room prior to presenting an incoming message. -CHAT_SPEAK_ROOM_NAME = _("_Speak Chat Room name") - -# Translators: When presenting the content of a line on a web page, Cthulhu by -# default presents the full line, including any links or form fields on that -# line, in order to reflect the on-screen layout as seen by sighted users. -# Not all users like this presentation, however, and prefer to have objects -# treated as if they were on individual lines, such as is done by Windows -# screen readers, so that unrelated objects (e.g. links in a navbar) are not -# all jumbled together. As a result, this is now configurable. If layout mode -# is enabled, Cthulhu will present the full line as it appears on the screen; if -# it is disabled, Cthulhu will treat each object as if it were on a separate line, -# both for presentation and navigation. -CONTENT_LAYOUT_MODE = _("Enable layout mode for content") - -# Translators: Cthulhu's keybindings support double and triple "clicks" or key -# presses, similar to using a mouse. This string appears in Cthulhu's preferences -# dialog after a keybinding which requires a double click. -CLICK_COUNT_DOUBLE = _("double click") - -# Translators: Cthulhu's keybindings support double and triple "clicks" or key -# presses, similar to using a mouse. This string appears in Cthulhu's preferences -# dialog after a keybinding which requires a triple click. -CLICK_COUNT_TRIPLE = _("triple click") - -# Translators: This is a label which will appear in the list of available speech -# engines as a special item. It refers to the default engine configured within -# the speech subsystem. Apart from this item, the user will have a chance to -# select a particular speech engine by its real name (Festival, IBMTTS, etc.) -DEFAULT_SYNTHESIZER = _("Default Synthesizer") - -# Translators: This is a label for a column header in Cthulhu's pronunciation -# dictionary. The pronunciation dictionary allows the user to correct words -# which the speech synthesizer mispronounces (e.g. a person's name, a technical -# word) or doesn't pronounce as the user desires (e.g. an acronym) by providing -# an alternative string. The "Actual String" here refers to the word to be -# corrected as it would actually appear in text being read. Example: "LOL". -DICTIONARY_ACTUAL_STRING = _("Actual String") - -# Translators: This is a label for a column header in Cthulhu's pronunciation -# dictionary. The pronunciation dictionary allows the user to correct words -# which the speech synthesizer mispronounces (e.g. a person's name, a technical -# word) or doesn't pronounce as the user desires (e.g. an acronym) by providing -# an alternative string. The "Replacement String" here refers to how the user -# would like the "Actual String" to be pronounced by the speech synthesizer. -# Example: "L O L" or "Laughing Out Loud" (for Actual String "LOL"). -DICTIONARY_REPLACEMENT_STRING = _("Replacement String") - -# Translators: Cthulhu has an "echo" feature to present text as it is being written -# by the user. While Cthulhu's "key echo" options present the actual keyboard keys -# being pressed, "character echo" presents the character/string of length 1 that -# is inserted as a result of the keypress. -ECHO_CHARACTER = _("Enable echo by cha_racter") - -# Translators: Cthulhu has an "echo" feature to present text as it is being written -# by the user. This string refers to a "key echo" option. When this option is -# enabled, dead keys will be announced when pressed. -ECHO_DIACRITICAL = _("Enable non-spacing _diacritical keys") - -# Translators: Cthulhu has a "find" feature which allows the user to search the -# active application for on screen text and widgets. This label is associated -# with the setting to begin the search from the current location rather than -# from the top of the screen. -FIND_START_AT_CURRENT_LOCATION = _("C_urrent location") - -# Translators: This is the label for a spinbutton. This option allows the user -# to specify the number of matched characters that must be present before Cthulhu -# speaks the line that contains the results from an application's Find toolbar. -FIND_MINIMUM_MATCH_LENGTH = _("Minimum length of matched text:") - -# Translators: This is the label of a panel containing options for what Cthulhu -# presents when the user is in the Find toolbar of an application, e.g. Firefox. -FIND_OPTIONS = _("Find Options") - -# Translators: This is the label for a checkbox. This option controls whether -# the line that contains the match from an application's Find toolbar should -# always be spoken, or only spoken if it is a different line than the line -# which contained the last match. -FIND_ONLY_SPEAK_CHANGED_LINES = _("Onl_y speak changed lines during find") - -# Translators: This is the label for a checkbox. This option controls whether or -# not Cthulhu will automatically speak the line that contains the match while the -# user is performing a search from the Find toolbar of an application, e.g. -# Firefox. -FIND_SPEAK_RESULTS = _("Speak results during _find") - -# Translators: Command is a table column header where the cells in the column -# are a sentence that briefly describes what action Cthulhu will take if and when -# the user invokes that keyboard command. -KB_HEADER_FUNCTION = _("Command") - -# Translators: Key Binding is a table column header where the cells in the -# column represent keyboard combinations the user can press to invoke Cthulhu -# commands. -KB_HEADER_KEY_BINDING = _("Key Binding") - -# Translators: This string is a label for the group of Cthulhu commands which -# can be used in any setting, task, or application. They are not specific -# to, for instance, web browsing. -KB_GROUP_DEFAULT = C_("keybindings", "Default") - -# Translators: This string is a label for the group of Cthulhu commands which -# are related to its "learn mode". Please use the same translation as done -# in cmdnames.py -KB_GROUP_LEARN_MODE = C_("keybindings", "Learn mode") - -# Translators: This string is a label for the group of Cthulhu commands which -# are related to presenting and performing the accessible actions associated -# with the current object. -KB_GROUP_ACTIONS = _("Actions") - -# Translators: An external braille device has buttons on it that permit the -# user to create input gestures from the braille device. The braille bindings -# are what determine the actions Cthulhu will take when the user presses these -# buttons. -KB_GROUP_BRAILLE = _("Braille Bindings") - -# Translators: This string is a label for the group of Cthulhu commands which -# are related to saving and jumping among objects via "bookmarks". -KB_GROUP_BOOKMARKS = _("Bookmarks") - -# Translators: This string is a label for the group of Cthulhu commands which -# are related to presenting the date and time. -KB_GROUP_DATE_AND_TIME = _("Date and time") - -# Translators: This string is a label for the group of Cthulhu commands which -# are related to presenting the object under the mouse pointer in speech -# and/or braille. The translation should be consistent with the string -# used in cmdnames.py. -KB_GROUP_MOUSE_REVIEW = _("Mouse review") - -# Translators: This string is a label for the group of Cthulhu commands which -# are related to object navigation. -KB_GROUP_OBJECT_NAVIGATION = _("Object navigation") - -# Translators: This string is a label for the group of Cthulhu commands which -# are related to presenting information about the current location, such as -# the title, status bar, and default button of the current window; the -# name, role, and location of the currently-focused object; the selected -# text in the currently-focused object; etc. -KB_GROUP_WHERE_AM_I = _("Object details") - -# Translators: This string is a label for the group of Cthulhu commands which -# do not currently have an associated key binding. -KB_GROUP_UNBOUND = _("Unbound") - -# Translators: This string is a label for the group of Cthulhu commands which -# are related to Cthulhu's "flat review" feature. This feature allows the blind -# user to explore the text in a window in a 2D fashion. That is, Cthulhu treats -# all the text from all objects in a window (e.g., buttons, labels, etc.) as -# a sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Those commands are all listed under this group label. -KB_GROUP_FLAT_REVIEW = _("Flat review") - -# Translators: This string is a label for the group of Cthulhu commands which -# are related to Cthulhu's speech and verbosity settings. This group of commands -# allows on-the-fly configuration of how much (or little) Cthulhu says about a -# particular object, as well certain aspects of the voice with which things -# are spoken. -KB_GROUP_SPEECH_VERBOSITY = _("Speech and verbosity") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. The flat review feature allows -# the user to explore this text by the {previous,next} {line,word,character}. -# Normally the contents are navigated without leaving the application being -# reviewed. There is a command which will place the entire contents of the -# flat review representation into a text view to make it easy to review -# and copy the text. This string is the title of the window with the text view. -FLAT_REVIEW_CONTENTS = _("Flat review contents") - -# Translators: Modified is a table column header in Cthulhu's preferences dialog. -# This column contains a checkbox which indicates whether a key binding -# for an Cthulhu command has been changed by the user to something other than its -# default value. -KB_MODIFIED = C_("keybindings", "Modified") - -# Translators: This label refers to the keyboard layout (desktop or laptop). -KEYBOARD_LAYOUT_DESKTOP = _("_Desktop") - -# Translators: Cthulhu has a feature to list all of the notification messages -# received, similar to the functionality gnome-shell provides when you press -# Super+M, but it works in all desktop environments. Cthulhu's list is a table -# with two columns, one column for the text of the notification and one -# column for the time of the notification. This string is a column header -# for the text of the notifications. -NOTIFICATIONS_COLUMN_HEADER = C_("notification presenter", "Notifications") - -# Translators: Cthulhu has a feature to list all of the notification messages -# received, similar to the functionality gnome-shell provides when you press -# Super+M, but it works in all desktop environments. Cthulhu's list is a table -# with two columns, one column for the text of the notification and one -# column for the time of the notification. This string is a column header -# for the time, which will be relative (e.g. "10 minutes ago") or absolute. -NOTIFICATIONS_RECEIVED_TIME = C_("notification presenter", "Received") - -# Translators: This is the label for a button which dismisses the selected live -# notification from mako's queue. -NOTIFICATIONS_DISMISS_BUTTON = C_("notification presenter", "Dismiss Notification") - -# Translators: This is the label for a button which opens the list of actions -# for the selected live notification. -NOTIFICATIONS_ACTIONS_BUTTON = C_("notification presenter", "Notification Actions") - -# Translators: This is the title for the dialog listing the actions associated -# with the selected live notification. -NOTIFICATIONS_ACTIONS_TITLE = C_("notification presenter", "Notification Actions") - -# Translators: This is the label for a button which invokes the selected action -# from the notification actions dialog. -NOTIFICATIONS_INVOKE_ACTION_BUTTON = C_("notification presenter", "Invoke Action") - -# Translators: This string is a label for the group of Cthulhu commands which -# are associated with presenting notifications. -KB_GROUP_NOTIFICATIONS = _("Notification presenter") - -# Translators: Cthulhu's preferences can be configured on a per-application basis, -# allowing users to customize Cthulhu's behavior, keybindings, etc. to work one -# way in LibreOffice and another way in a chat application. This string is the -# title of Cthulhu's application-specific preferences dialog for an application. -# The string substituted in is the accessible name of the application (e.g. -# "Gedit", "Firefox", etc. -PREFERENCES_APPLICATION_TITLE = _("Cthulhu Preferences for %s") - -# Translators: This is a table column header. This column consists of a single -# checkbox. If the checkbox is checked, Cthulhu will indicate the associated item -# or attribute by "marking" it in braille. "Marking" is not the same as writing -# out the word; instead marking refers to adding some other indicator, e.g. -# "underlining" with braille dots 7-8 a word that is bold. -PRESENTATION_MARK_IN_BRAILLE = _("Mark in braille") - -# Translators: "Present Unless" is a column header of the text attributes panel -# of the Cthulhu preferences dialog. On this panel, the user can select a set of -# text attributes that they would like spoken and/or indicated in braille. -# Because the list of attributes could get quite lengthy, we provide the option -# to always speak/braille a text attribute *unless* its value is equal to the -# value given by the user in this column of the list. For example, given the -# text attribute "underline" and a present unless value of "none", the user is -# stating that he/she would like to have underlined text announced for all cases -# (single, double, low, etc.) except when the value of underline is none (i.e. -# when it's not underlined). "Present" here is being used as a verb. -PRESENTATION_PRESENT_UNLESS = _("Present Unless") - -# Translators: This is a table column header. The "Speak" column consists of a -# single checkbox. If the checkbox is checked, Cthulhu will speak the associated -# item or attribute (e.g. saying "Bold" as part of the information presented -# when the user gives the Cthulhu command to obtain the format and font details of -# the current text). -PRESENTATION_SPEAK = _("Speak") - -# Translators: This is the title of a message dialog informing the user that -# he/she attempted to save a new user profile under a name which already exists. -# A "user profile" is a collection of settings which apply to a given task, such -# as a "Spanish" profile which would use Spanish text-to-speech and Spanish -# braille and selected when reading Spanish content. -PROFILE_CONFLICT_TITLE = _("Save Profile As Conflict") - -# Translators: This is the label of a message dialog informing the user that -# he/she attempted to save a new user profile under a name which already exists. -# A "user profile" is a collection of settings which apply to a given task, such -# as a "Spanish" profile which would use Spanish text-to-speech and Spanish -# braille and selected when reading Spanish content. -PROFILE_CONFLICT_LABEL = _("User Profile Conflict!") - -# Translators: This is the message in a dialog informing the user that he/she -# attempted to save a new user profile under a name which already exists. -# A "user profile" is a collection of settings which apply to a given task, such -# as a "Spanish" profile which would use Spanish text-to-speech and Spanish -# braille and selected when reading Spanish content. -PROFILE_CONFLICT_MESSAGE = _("Profile %s already exists.\n" \ - "Continue updating the existing profile with " \ - "these new changes?") - -# Translators: This text is displayed in a message dialog when a user indicates -# he/she wants to switch to a new user profile which will cause him/her to lose -# settings which have been altered but not yet saved. A "user profile" is a -# collection of settings which apply to a given task such as a "Spanish" profile -# which would use Spanish text-to-speech and Spanish braille and selected when -# reading Spanish content. -PROFILE_LOAD_LABEL = _("Load user profile") - -# Translators: This text is displayed in a message dialog when a user indicates -# he/she wants to switch to a new user profile which will cause him/her to lose -# settings which have been altered but not yet saved. A "user profile" is a -# collection of settings which apply to a given task such as a "Spanish" profile -# which would use Spanish text-to-speech and Spanish braille and selected when -# reading Spanish content. -PROFILE_LOAD_MESSAGE = \ - _("You are about to change the active profile. If you\n" \ - "have just made changes in your preferences, they will\n" \ - "be dropped at profile load.\n\n" \ - "Continue loading profile discarding previous changes?") - -# Translators: Profiles in Cthulhu make it possible for users to quickly switch -# amongst a group of pre-defined settings (e.g. an 'English' profile for reading -# text written in English using an English-language speech synthesizer and -# braille rules, and a similar 'Spanish' profile for reading Spanish text. The -# following string is the title of a dialog in which users can save a newly- -# defined profile. -PROFILE_SAVE_AS_TITLE = _("Save Profile As") - -# Translators: Profiles in Cthulhu make it possible for users to quickly switch -# amongst a group of pre-defined settings (e.g. an 'English' profile for reading -# text written in English using an English-language speech synthesizer and -# braille rules, and a similar 'Spanish' profile for reading Spanish text. The -# following string is the label for a text entry in which the user enters the -# name of a new settings profile being saved via the 'Save Profile As' dialog. -PROFILE_NAME_LABEL = _("_Profile Name:") - -# Translators: Profiles in Cthulhu make it possible for users to quickly switch -# amongst a group of pre-defined settings (e.g. an 'English' profile for reading -# text written in English using an English-language speech synthesizer and -# braille rules, and a similar 'Spanish' profile for reading Spanish text. -# The following is a label in a dialog informing the user that he/she -# is about to remove a user profile, and action that cannot be undone. -PROFILE_REMOVE_LABEL = _("Remove user profile") - -# Translators: Profiles in Cthulhu make it possible for users to quickly switch -# amongst a group of pre-defined settings (e.g. an 'English' profile for reading -# text written in English using an English-language speech synthesizer and -# braille rules, and a similar 'Spanish' profile for reading Spanish text. -# The following is a message in a dialog informing the user that he/she -# is about to remove a user profile, an action that cannot be undone. -PROFILE_REMOVE_MESSAGE = _("You are about to remove profile %s. " \ - "All unsaved settings and settings saved in this " \ - "profile will be lost. Do you want to continue " \ - "and remove this profile and all related settings?") - -# Translators: Cthulhu has a setting which determines which progress bar updates -# should be announced. Choosing "All" means that Cthulhu will present progress bar -# updates regardless of what application and window they happen to be in. -PROGRESS_BAR_ALL = C_("ProgressBar", "All") - -# Translators: Cthulhu has a setting which determines which progress bar updates -# should be announced. Choosing "Application" means that Cthulhu will present -# progress bar updates as long as the progress bar is in the active application -# (but not necessarily in the current window). -PROGRESS_BAR_APPLICATION = C_("ProgressBar", "Application") - -# Translators: Cthulhu has a setting which determines which progress bar updates -# should be announced. Choosing "Window" means that Cthulhu will present progress -# bar updates as long as the progress bar is in the active window. -PROGRESS_BAR_WINDOW = C_("ProgressBar", "Window") - -# Translators: If this setting is chosen, no punctuation symbols will be spoken -# as a user reads a document. -PUNCTUATION_STYLE_NONE = C_("punctuation level", "_None") - -# Translators: If this setting is chosen, common punctuation symbols (like -# comma, period, question mark) will not be spoken as a user reads a document, -# but less common symbols (such as #, @, $) will. -PUNCTUATION_STYLE_SOME = _("So_me") - -# Translators: If this setting is chosen, the majority of punctuation symbols -# will be spoken as a user reads a document. -PUNCTUATION_STYLE_MOST = _("M_ost") - -# Translators: If this setting is chosen and the user is reading over an entire -# document, Cthulhu will pause at the end of each line. -SAY_ALL_STYLE_LINE = _("Line") - -# Translators: If this setting is chosen and the user is reading over an entire -# document, Cthulhu will pause at the end of each sentence. -SAY_ALL_STYLE_SENTENCE = _("Sentence") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of a blockquote. -SN_HEADER_BLOCKQUOTE = C_("structural navigation", "Blockquote") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of a button. -SN_HEADER_BUTTON = C_("structural navigation", "Button") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the caption of a table. -SN_HEADER_CAPTION = C_("structural navigation", "Caption") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the label of a check box. -SN_HEADER_CHECK_BOX = C_("structural navigation", "Check Box") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text displayed for a web element with an "onClick" handler. -SN_HEADER_CLICKABLE = C_("structural navigation", "Clickable") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the selected item in a combo box. -SN_HEADER_COMBO_BOX = C_("structural navigation", "Combo Box") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the description of an element. -SN_HEADER_DESCRIPTION = C_("structural navigation", "Description") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of a heading. -SN_HEADER_HEADING = C_("structural navigation", "Heading") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the title associated with an iframe. -SN_HEADER_IFRAME = C_("structural navigation", "Internal Frame") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text (alt text, title, etc.) associated with an image. -SN_HEADER_IMAGE = C_("structural navigation", "Image") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the label of a form field. -SN_HEADER_LABEL = C_("structural navigation", "Label") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of a landmark. ARIA role landmarks are the W3C defined HTML -# tag attribute 'role' used to identify important part of webpage like banners, -# main context, search etc. -SN_HEADER_LANDMARK = C_("structural navigation", "Landmark") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of a column which -# contains the level of a heading. Level will be a "1" for

, a "2" for

, -# and so on. -SN_HEADER_LEVEL = C_("structural navigation", "Level") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of a link. -SN_HEADER_LINK = C_("structural navigation", "Link") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of a list. -SN_HEADER_LIST = C_("structural navigation", "List") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of a list item. -SN_HEADER_LIST_ITEM = C_("structural navigation", "List Item") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of an object. -SN_HEADER_OBJECT = C_("structural navigation", "Object") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of a paragraph. -SN_HEADER_PARAGRAPH = C_("structural navigation", "Paragraph") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the label of a radio button. -SN_HEADER_RADIO_BUTTON = C_("structural navigation", "Radio Button") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the role of a widget. Examples include "heading", "paragraph", -# "table", "combo box", etc. -SN_HEADER_ROLE = C_("structural navigation", "Role") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the selected item of a form field. -SN_HEADER_SELECTED_ITEM = C_("structural navigation", "Selected Item") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the state of a widget. Examples include "checked"/"not checked", -# "selected"/"not selected", "visited/not visited", etc. -SN_HEADER_STATE = C_("structural navigation", "State") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the text of an entry. -SN_HEADER_TEXT = C_("structural navigation", "Text") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the URI of a link. -SN_HEADER_URI = C_("structural navigation", "URI") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title for a column which -# contains the value of a form field. -SN_HEADER_VALUE = C_("structural navigation", "Value") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_BLOCKQUOTE = C_("structural navigation", "Blockquotes") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_BUTTON = C_("structural navigation", "Buttons") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_CHECK_BOX = C_("structural navigation", "Check Boxes") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -# "Clickables" are web elements which have an "onClick" handler. -SN_TITLE_CLICKABLE = C_("structural navigation", "Clickables") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_COMBO_BOX = C_("structural navigation", "Combo Boxes") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_ENTRY = C_("structural navigation", "Entries") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_FORM_FIELD = C_("structural navigation", "Form Fields") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_HEADING = C_("structural navigation", "Headings") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_IFRAME = C_("structural navigation", "Internal Frames") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_IMAGE = C_("structural navigation", "Images") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -# Level will be a "1" for

, a "2" for

, and so on. -SN_TITLE_HEADING_AT_LEVEL = C_("structural navigation", "Headings at Level %d") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -# ARIA role landmarks are the W3C defined HTML tag attribute 'role' used to -# identify important part of webpage like banners, main context, search etc. -SN_TITLE_LANDMARK = C_("structural navigation", "Landmarks") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -# A 'large object' is a logical chunk of text, such as a paragraph, a list, -# a table, etc. -SN_TITLE_LARGE_OBJECT = C_("structural navigation", "Large Objects") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_LINK = C_("structural navigation", "Links") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_LIST = C_("structural navigation", "Lists") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_LIST_ITEM = C_("structural navigation", "List Items") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_PARAGRAPH = C_("structural navigation", "Paragraphs") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_RADIO_BUTTON = C_("structural navigation", "Radio Buttons") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_TABLE = C_("structural navigation", "Tables") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_UNVISITED_LINK = C_("structural navigation", "Unvisited Links") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is the title of such a dialog box. -SN_TITLE_VISITED_LINK = C_("structural navigation", "Visited Links") - -# Translators: This is the title of a panel holding options for how to navigate -# HTML content (e.g., Cthulhu caret navigation, positioning of caret, structural -# navigation, etc.). -PAGE_NAVIGATION = _("Page Navigation") - -# Translators: When the user loads a new web page, they can optionally have Cthulhu -# automatically start reading the page from beginning to end. This is the label -# of a checkbox in which users can indicate their preference. -READ_PAGE_UPON_LOAD = \ - _("Automatically start speaking a page when it is first _loaded") - -# Translators: When the user loads a new web page, they can optionally have Cthulhu -# automatically summarize details about the page, such as the number of elements -# (landmarks, forms, links, tables, etc.). -PAGE_SUMMARY_UPON_LOAD = _("_Present summary of a page when it is first loaded") - -# Translators: Different speech systems and speech engines work differently when -# it comes to handling pauses (e.g. sentence boundaries). This property allows -# the user to specify whether speech should be sent to the speech synthesis -# system immediately when a pause directive is encountered or if it should be -# queued up and sent to the speech synthesis system once the entire set of -# utterances has been calculated. -SPEECH_BREAK_INTO_CHUNKS = _("Break speech into ch_unks between pauses") - -# Translators: This string will appear in the list of available voices for the -# current speech engine. "%s" will be replaced by the name of the current speech -# engine, such as "Festival default voice" or "IBMTTS default voice". It refers -# to the default voice configured for given speech engine within the speech -# subsystem. Apart from this item, the list will contain the names of all -# available "real" voices provided by the speech engine. -SPEECH_DEFAULT_VOICE = _("%s default voice") - -# Translators: This refers to the voice used by Cthulhu when presenting the content -# of the screen and other messages. -SPEECH_VOICE_TYPE_DEFAULT = C_("VoiceType", "Default") - -# Translators: This refers to the voice used by Cthulhu when presenting one or more -# characters which is part of a hyperlink. -SPEECH_VOICE_TYPE_HYPERLINK = C_("VoiceType", "Hyperlink") - -# Translators: This refers to the voice used by Cthulhu when presenting information -# which is not displayed on the screen as text, but is still being communicated -# by the system in some visual fashion. For instance, Cthulhu says "misspelled" to -# indicate the presence of the red squiggly line found under a spelling error; -# Cthulhu might say "3 of 6" when a user Tabs into a list of six items and the -# third item is selected. And so on. -SPEECH_VOICE_TYPE_SYSTEM = C_("VoiceType", "System") - -# Translators: This refers to the voice used by Cthulhu when presenting one or more -# characters which is written in uppercase. -SPEECH_VOICE_TYPE_UPPERCASE = C_("VoiceType", "Uppercase") - -# Translators this label refers to the name of particular speech synthesis -# system. (http://devel.freebsoft.org/speechd) -SPEECH_DISPATCHER = _("Speech Dispatcher") - -# Translators: This label refers to the Piper neural text-to-speech system. -# (https://github.com/rhasspy/piper) -PIPER_TTS = _("Piper Neural TTS") -# Translators: This label refers to external hardware serial speech synthesizers. -HARDWARE_SPEECH = _("Hardware Speech Synthesizer") -# Translators: This label refers to the LiteTalk hardware speech synthesizer. -HARDWARE_LITETALK = _("LiteTalk") -# Translators: This label refers to the DoubleTalk LT hardware speech synthesizer. -HARDWARE_DOUBLETALK = _("DoubleTalk LT") -# Translators: This label refers to the TripleTalk hardware speech synthesizer. -HARDWARE_TRIPLETALK = _("TripleTalk") -# Translators: This label refers to the Dectalk hardware synthesizer. -HARDWARE_DECTALK = _("Dectalk") -# Translators: This is the label for the combo box that lets the user choose -# the serial device used by a hardware speech synthesizer. -HARDWARE_SERIAL_DEVICE = _("Serial _device:") - -# Translators: This is a label for a group of options related to Cthulhu's behavior -# when presenting an application's spell check dialog. -SPELL_CHECK = C_("OptionGroup", "Spell Check") - -# Translators: This is a label for a checkbox associated with an Cthulhu setting. -# When this option is enabled, Cthulhu will spell out the current error in addition -# to speaking it. For example, if the misspelled word is "foo," enabling this -# setting would cause Cthulhu to speak "f o o" after speaking "foo". -SPELL_CHECK_SPELL_ERROR = _("Spell _error") - -# Translators: This is a label for a checkbox associated with an Cthulhu setting. -# When this option is enabled, Cthulhu will spell out the current suggestion in -# addition to speaking it. For example, if the misspelled word is "foo," and -# the first suggestion is "for" enabling this setting would cause Cthulhu to speak -# "f o r" after speaking "for". -SPELL_CHECK_SPELL_SUGGESTION = _("Spell _suggestion") - -# Translators: This is a label for a checkbox associated with an Cthulhu setting. -# When this option is enabled, Cthulhu will present the context (surrounding text, -# typically the sentence or line) in which the mistake occurred. -SPELL_CHECK_PRESENT_CONTEXT = _("Present _context of error") - -# Translators: This is a label for an option to tell Cthulhu whether or not it -# should speak the coordinates of the current spreadsheet cell. Coordinates are -# the row and column position within the spreadsheet (i.e. A1, B1, C2 ...) -SPREADSHEET_SPEAK_CELL_COORDINATES = _("Speak spreadsheet cell coordinates") - -# Translators: This is a label for an option which controls what Cthulhu speaks when -# presenting selection changes in a spreadsheet. By default, Cthulhu will speak just -# what changed. For instance, if cells A1 through A8 are already selected, and the -# user adds A9 to the selection, Cthulhu by default would just say "A9 selected." -# Some users, however, prefer to have Cthulhu always announce the entire selected range, -# i.e. in the same scenario say "A1 through A9 selected." Those users should enable -# this option. -SPREADSHEET_SPEAK_SELECTED_RANGE = _("Always speak selected spreadsheet range") - -# Translators: This is a label for an option for whether or not to speak the -# header of a table cell in document content. -TABLE_ANNOUNCE_CELL_HEADER = _("Announce cell _header") - -# Translators: This is the title of a panel containing options for specifying -# how to navigate tables in document content. -TABLE_NAVIGATION = _("Table Navigation") - -# Translators: This is a label for an option to tell Cthulhu to skip over empty/ -# blank cells when navigating tables in document content. -TABLE_SKIP_BLANK_CELLS = _("Skip _blank cells") - -# Translators: When users are navigating a table, they sometimes want the entire -# row of a table read; other times they want just the current cell presented to -# them. This label is associated with the default presentation to be used. -TABLE_SPEAK_CELL = _("Speak _cell") - -# Translators: This is a label for an option to tell Cthulhu whether or not it -# should speak table cell coordinates in document content. -TABLE_SPEAK_CELL_COORDINATES = _("Speak _cell coordinates") - -# Translators: This is a label for an option to tell Cthulhu whether or not it -# should speak the span size of a table cell (e.g., how many rows and columns -# a particular table cell spans in a table). -TABLE_SPEAK_CELL_SPANS = _("Speak _multiple cell spans") - -# Translators: This is a table column header. "Attribute" here refers to text -# attributes such as bold, underline, family-name, etc. -TEXT_ATTRIBUTE_NAME = _("Attribute Name") - -# Translators: Gecko native caret navigation is where Firefox itself controls -# how the arrow keys move the caret around HTML content. It's often broken, so -# Cthulhu needs to provide its own support. As such, Cthulhu offers the user the -# ability to switch between the Firefox mode and the Cthulhu mode. This is the -# label of a checkbox in which users can indicate their default preference. -USE_CARET_NAVIGATION = _("Control caret navigation") - -# Translators: Cthulhu provides keystrokes to navigate HTML content in a structural -# manner: go to previous/next header, list item, table, etc. This is the label -# of a checkbox in which users can indicate their default preference. -USE_STRUCTURAL_NAVIGATION = _("Enable _structural navigation") - -# Translators: This is the label for a combo box in the preferences dialog -# where users can select a sound theme. A sound theme is a collection of -# audio files that Cthulhu plays for various events. -SOUND_THEME = _("Sound _theme:") - -# Translators: This is the label for a combo box in the preferences dialog -# where users can choose which audio backend Cthulhu should use. -SOUND_BACKEND = _("Audio _backend:") - -# Translators: This is a sound backend option which lets Cthulhu choose a -# backend automatically. -SOUND_BACKEND_AUTO = _("Automatic") - -# Translators: This is a sound backend option which forces PipeWire. -SOUND_BACKEND_PIPEWIRE = _("PipeWire") - -# Translators: This is a sound backend option which forces PulseAudio. -SOUND_BACKEND_PULSE = _("PulseAudio") - -# Translators: This is a sound backend option which forces ALSA. -SOUND_BACKEND_ALSA = _("ALSA") - -# Translators: This is the title of a frame in the preferences dialog -# containing sound options. -SOUND_THEME_TITLE = _("Sound") - -# Translators: This refers to the amount of information Cthulhu provides about a -# particular object that receives focus. -VERBOSITY_LEVEL_BRIEF = _("Brie_f") - -def notifications_count(count): - """Returns the gui label representing the notifications count.""" - - # Translators: Cthulhu has a feature to list all of the notification messages - # received, similar to the functionality gnome-shell provides when you press - # Super+M, but it works in all desktop environments. This string is the title - # of the dialog that contains the list of notification messages. The string - # substitution is for the number of messages in the list. - return ngettext("%d notification", "%d notifications", count) % count diff --git a/src/cthulhu/hardwarefactory.py b/src/cthulhu/hardwarefactory.py deleted file mode 100644 index d0fc025..0000000 --- a/src/cthulhu/hardwarefactory.py +++ /dev/null @@ -1,571 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides a Cthulhu speech server for hardware serial synthesizers. - -Ports Fenrir's hardware serial drivers (LiteTalk/DoubleTalk/TripleTalk, -Dectalk) to Cthulhu's SpeechServer interface. -""" - -from __future__ import annotations - -import os -import termios -import threading -import tty -from queue import Empty, Queue - -from . import debug -from . import guilabels -from . import messages -from . import settings -from . import speechserver -from .acss import ACSS - - -class _SpeakQueue(Queue): - """Queue with a clear() method.""" - - def clear(self): - try: - while True: - self.get_nowait() - except Empty: - pass - - -class _HardwareSerialDriver: - """Base class for hardware serial speech synthesizers. - - Ported from Fenrir's hardwareSerialDriver.py. - """ - - cancel_command = b"" - default_baud_rate = 9600 - - def __init__(self, device: str, baud_rate: int): - self.device = device - self.baud_rate = baud_rate - self.serial_port: int | None = None - self.text_queue = _SpeakQueue() - self.lock = threading.Lock() - self.worker_thread: threading.Thread | None = None - self._stop_worker = False - self._is_initialized = False - - def initialize(self) -> bool: - self._open_serial_port() - self._is_initialized = self.serial_port is not None - if self._is_initialized: - self._stop_worker = False - self.worker_thread = threading.Thread(target=self._worker, daemon=True) - self.worker_thread.start() - return self._is_initialized - - def shutdown(self) -> None: - if not self._is_initialized: - return - self._stop_worker = True - self.clear_buffer() - self.text_queue.put(None) - if self.worker_thread: - self.worker_thread.join(timeout=0.5) - self._close_serial_port() - self._is_initialized = False - - def speak(self, text: str, interrupt: bool = True) -> None: - if not self._is_initialized: - return - if interrupt: - self.stop() - if not isinstance(text, str) or text == "": - return - self.text_queue.put(text) - - def stop(self) -> None: - if not self._is_initialized: - return - self.clear_buffer() - if self.cancel_command: - self._write_bytes(self.cancel_command, "cancel") - - def clear_buffer(self) -> None: - if not self._is_initialized: - return - self.text_queue.clear() - - def set_rate(self, rate: float) -> None: - if not self._is_initialized: - return - self._write_bytes(self._rate_command(rate), "rate") - - def set_pitch(self, pitch: float) -> None: - if not self._is_initialized: - return - self._write_bytes(self._pitch_command(pitch), "pitch") - - def set_volume(self, volume: float) -> None: - if not self._is_initialized: - return - self._write_bytes(self._volume_command(volume), "volume") - - def _worker(self) -> None: - while not self._stop_worker: - text = self.text_queue.get() - if text is None: - return - try: - data = self._speak_bytes(text) - self._write_bytes(data, "speech") - except Exception as error: - msg = f"HARDWARE SPEECH: worker failed: {error}" - debug.printMessage(debug.LEVEL_ERROR, msg, True) - - def _open_serial_port(self) -> None: - if not self.device or self.device == "auto": - msg = "HARDWARE SPEECH: requires an explicit serial device" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return - - port = self._open_configured_serial_port(self.device) - if port is not None: - self._activate_serial_port(self.device, port) - - def _open_configured_serial_port(self, device: str) -> int | None: - port = None - try: - port = os.open(device, os.O_RDWR | os.O_NOCTTY) - tty.setraw(port) - attrs = termios.tcgetattr(port) - attrs[2] |= termios.CLOCAL | termios.CREAD - baud_rate = self._termios_baud_rate(self.baud_rate) - attrs[4] = baud_rate - attrs[5] = baud_rate - attrs[6][termios.VMIN] = 0 - attrs[6][termios.VTIME] = 0 - attrs[0] &= ~(termios.IXON | termios.IXOFF | termios.IXANY) - termios.tcsetattr(port, termios.TCSANOW, attrs) - return port - except (OSError, termios.error) as error: - self._close_port(port) - msg = f"HARDWARE SPEECH: device open failed: {device}: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return None - - def _activate_serial_port(self, device: str, port: int) -> None: - self.serial_port = port - self.device = device - msg = f"HARDWARE SPEECH: device opened: {device}, baud_rate={self.baud_rate}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _close_serial_port(self) -> None: - with self.lock: - if self.serial_port is None: - return - self._close_port(self.serial_port) - self.serial_port = None - - def _close_port(self, port: int | None) -> None: - if port is None: - return - try: - os.close(port) - except OSError as error: - msg = f"HARDWARE SPEECH: device close failed: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - - def _write_bytes(self, data: bytes, description: str = "data") -> None: - if not data: - return - with self.lock: - if self.serial_port is None: - return - try: - total_written = 0 - while total_written < len(data): - bytes_written = os.write(self.serial_port, data[total_written:]) - if bytes_written == 0: - raise OSError("serial write returned 0 bytes") - total_written += bytes_written - preview = self._format_bytes_preview(data) - msg = f"HARDWARE SPEECH: wrote {total_written} {description} bytes: {preview}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - except OSError as error: - msg = f"HARDWARE SPEECH: write failed: {error}" - debug.printMessage(debug.LEVEL_ERROR, msg, True) - - def _termios_baud_rate(self, baud_rate: int) -> int: - baud_name = f"B{baud_rate}" - if hasattr(termios, baud_name): - return getattr(termios, baud_name) - msg = f"HARDWARE SPEECH: unsupported baud rate {baud_rate}; using 9600" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return termios.B9600 - - @staticmethod - def _clean_text(text: str) -> str: - text = text.replace("\r", " ").replace("\n", " ") - return "".join(char if 0x20 <= ord(char) <= 0x7E else " " for char in text) - - @staticmethod - def _scale(value: float, minimum: int, maximum: int) -> int: - value = max(0.0, min(1.0, value)) - return int(round(minimum + value * (maximum - minimum))) - - @staticmethod - def _format_bytes_preview(data: bytes, limit: int = 32) -> str: - preview = data[:limit] - hex_preview = " ".join(f"{byte:02x}" for byte in preview) - ascii_preview = "".join( - chr(byte) if 0x20 <= byte <= 0x7E else "." for byte in preview - ) - suffix = "" if len(data) <= limit else " ..." - return f"hex=[{hex_preview}{suffix}] ascii=[{ascii_preview}{suffix}]" - - def _speak_bytes(self, text: str) -> bytes: - raise NotImplementedError - - def _rate_command(self, rate: float) -> bytes: - return b"" - - def _pitch_command(self, pitch: float) -> bytes: - return b"" - - def _volume_command(self, volume: float) -> bytes: - return b"" - - -class _LiteTalkDriver(_HardwareSerialDriver): - """LiteTalk-compatible serial driver.""" - - cancel_command = b"\x18" - - def _speak_bytes(self, text: str) -> bytes: - return self._clean_text(text).encode("ascii", errors="replace") + b"\r" - - def _rate_command(self, rate: float) -> bytes: - return self._setting_command(self._scale(rate, 0, 9), b"S") - - def _pitch_command(self, pitch: float) -> bytes: - return self._setting_command(self._scale(pitch, 0, 99), b"P") - - def _volume_command(self, volume: float) -> bytes: - return self._setting_command(self._scale(volume, 0, 9), b"V") - - @staticmethod - def _setting_command(value: int, command: bytes) -> bytes: - return b"\x01" + str(value).encode("ascii") + command - - -class _DectalkDriver(_HardwareSerialDriver): - """Dectalk serial driver.""" - - cancel_command = b"\x18" - - def _speak_bytes(self, text: str) -> bytes: - return self._clean_text(text).encode("ascii", errors="replace") + b"\x01" - - def _rate_command(self, rate: float) -> bytes: - return self._setting_command("ra", self._scale(rate, 75, 650)) - - def _pitch_command(self, pitch: float) -> bytes: - return self._setting_command("dv ap", self._scale(pitch, 50, 180)) - - def _volume_command(self, volume: float) -> bytes: - return self._setting_command("vo", self._scale(volume, 0, 100)) - - @staticmethod - def _setting_command(command: str, value: int) -> bytes: - return f"[:{command} {value}]".encode("ascii") - - -_DRIVER_MAP: dict[str, type[_HardwareSerialDriver]] = { - "litetalk": _LiteTalkDriver, - "doubletalk": _LiteTalkDriver, - "tripletalk": _LiteTalkDriver, - "dectalk": _DectalkDriver, -} - -_SYNTH_DISPLAY_NAMES = { - "litetalk": guilabels.HARDWARE_LITETALK, - "doubletalk": guilabels.HARDWARE_DOUBLETALK, - "tripletalk": guilabels.HARDWARE_TRIPLETALK, - "dectalk": guilabels.HARDWARE_DECTALK, -} - - -class SpeechServer(speechserver.SpeechServer): - """Hardware serial speech server implementation for Cthulhu.""" - - _active_servers: dict[str, SpeechServer] = {} - - @staticmethod - def getFactoryName() -> str: - """Returns a localized name describing this factory.""" - return guilabels.HARDWARE_SPEECH - - @staticmethod - def getSpeechServers() -> list[SpeechServer]: - """Gets available speech servers as a list.""" - return [ - SpeechServer(server_id, initialize=False, register=False) - for server_id in _DRIVER_MAP - ] - - @classmethod - def _getSpeechServer(cls, server_id: str) -> SpeechServer | None: - """Return an active server for the given id.""" - active_server = cls._active_servers.get(server_id) - if active_server is not None: - if active_server._matches_current_settings(): - return active_server - active_server.shutdown() - - cls(server_id) - return cls._active_servers.get(server_id) - - @staticmethod - def getSpeechServer(info: list[str] | None = None) -> SpeechServer | None: - """Gets a given SpeechServer based upon the info.""" - if info and len(info) >= 2: - server_id = info[1] - else: - server_id = "litetalk" - return SpeechServer._getSpeechServer(server_id) - - @staticmethod - def shutdownActiveServers() -> None: - """Cleans up and shuts down this factory.""" - servers = list(SpeechServer._active_servers.values()) - for server in servers: - server.shutdown() - - def __init__( - self, - server_id: str, - initialize: bool = True, - register: bool = True, - ): - super().__init__() - self._id = server_id - self._driver: _HardwareSerialDriver | None = None - self._info: list[str] = [] - self._device = "" - self._baud_rate = settings.hardwareSpeechBaudRate - - driver_class = _DRIVER_MAP.get(server_id) - if driver_class is None: - msg = f"HARDWARE SPEECH: unknown synth type: {server_id}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return - - display_name = _SYNTH_DISPLAY_NAMES.get(server_id, server_id) - self._info = [display_name, server_id] - - if not initialize: - return - - self._device = settings.hardwareSpeechDevice - self._baud_rate = settings.hardwareSpeechBaudRate - self._driver = driver_class(self._device, self._baud_rate) - if self._driver.initialize(): - if register: - SpeechServer._active_servers[server_id] = self - msg = f"HARDWARE SPEECH: server initialized: {server_id} on {self._device}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - msg = f"HARDWARE SPEECH: server initialization failed: {server_id}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - self._driver = None - - def _matches_current_settings(self) -> bool: - return ( - self._driver is not None - and self._device == settings.hardwareSpeechDevice - and self._baud_rate == settings.hardwareSpeechBaudRate - ) - - def getInfo(self) -> list[str]: - """Returns [name, id].""" - return self._info - - def getVoiceFamilies(self) -> list[dict[str, str]]: - """Returns a list of VoiceFamily instances.""" - return [] - - def speakCharacter(self, character: str, acss: dict | None = None) -> None: - """Speaks a single character immediately.""" - if self._driver: - self._apply_acss(acss) - self._driver.speak(character, interrupt=True) - - def speakKeyEvent(self, event, acss: dict | None = None) -> None: - """Speaks a key event immediately.""" - event_string = event.getKeyName() - locking_state_string = event.getLockingStateString() - text = f"{event_string} {locking_state_string}".strip() - self.speak(text, acss=acss) - - def speak( - self, - text: str | None = None, - acss: dict | None = None, - interrupt: bool = True, - ) -> None: - """Speaks all queued text immediately.""" - if not self._driver or text is None: - return - self._apply_acss(acss) - self._driver.speak(text, interrupt=interrupt) - - def sayAll(self, utteranceIterator, progressCallback) -> None: - """Iterates through the given utteranceIterator, speaking each utterance.""" - for context, acss in utteranceIterator: - self.speak(context.utterance, acss=acss, interrupt=False) - - def increaseSpeechRate(self, step: int = 5) -> None: - self._change_default_speech_rate(step) - - def decreaseSpeechRate(self, step: int = 5) -> None: - self._change_default_speech_rate(step, decrease=True) - - def increaseSpeechPitch(self, step: float = 0.5) -> None: - self._change_default_speech_pitch(step) - - def decreaseSpeechPitch(self, step: float = 0.5) -> None: - self._change_default_speech_pitch(step, decrease=True) - - def increaseSpeechVolume(self, step: float = 0.5) -> None: - self._change_default_speech_volume(step) - - def decreaseSpeechVolume(self, step: float = 0.5) -> None: - self._change_default_speech_volume(step, decrease=True) - - def updateCapitalizationStyle(self) -> None: - pass - - def updatePunctuationLevel(self) -> None: - pass - - def stop(self) -> None: - if self._driver: - self._driver.stop() - - def shutdown(self) -> None: - if self._driver: - self._driver.shutdown() - self._driver = None - if self._id in SpeechServer._active_servers: - del SpeechServer._active_servers[self._id] - - def reset(self, text: str | None = None, acss: dict | None = None) -> None: - if self._driver: - self._driver.shutdown() - self._driver = None - - driver_class = _DRIVER_MAP.get(self._id) - if driver_class is None: - return - - self._device = settings.hardwareSpeechDevice - self._baud_rate = settings.hardwareSpeechBaudRate - self._driver = driver_class(self._device, self._baud_rate) - if not self._driver.initialize(): - self._driver = None - - def _apply_acss(self, acss: dict | None) -> None: - if not self._driver or not acss: - return - try: - rate = acss.get(ACSS.RATE) - if rate is not None: - normalized = max(0.0, min(99.0, float(rate))) / 99.0 - self._driver.set_rate(normalized) - except Exception: - pass - try: - pitch = acss.get(ACSS.AVERAGE_PITCH) - if pitch is not None: - normalized = max(0.0, min(9.0, float(pitch))) / 9.0 - self._driver.set_pitch(normalized) - except Exception: - pass - try: - volume = acss.get(ACSS.GAIN) - if volume is not None: - normalized = max(0.0, min(9.0, float(volume))) / 9.0 - self._driver.set_volume(normalized) - except Exception: - pass - - def _change_default_speech_rate(self, step: float, decrease: bool = False) -> None: - acss = settings.voices[settings.DEFAULT_VOICE] - delta = step * (-1 if decrease else 1) - try: - rate = acss[ACSS.RATE] - except KeyError: - rate = 50.0 - acss[ACSS.RATE] = max(0, min(99, rate + delta)) - msg = f"HARDWARE SPEECH: rate set to {acss[ACSS.RATE]}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if self._driver: - normalized = acss[ACSS.RATE] / 99.0 - self._driver.set_rate(normalized) - self.speak( - messages.SPEECH_SLOWER if decrease else messages.SPEECH_FASTER, - acss=acss - ) - - def _change_default_speech_pitch(self, step: float, decrease: bool = False) -> None: - acss = settings.voices[settings.DEFAULT_VOICE] - delta = step * (-1 if decrease else 1) - try: - pitch = acss[ACSS.AVERAGE_PITCH] - except KeyError: - pitch = 5.0 - acss[ACSS.AVERAGE_PITCH] = max(0, min(9, pitch + delta)) - msg = f"HARDWARE SPEECH: pitch set to {acss[ACSS.AVERAGE_PITCH]}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if self._driver: - normalized = acss[ACSS.AVERAGE_PITCH] / 9.0 - self._driver.set_pitch(normalized) - self.speak( - messages.SPEECH_LOWER if decrease else messages.SPEECH_HIGHER, - acss=acss - ) - - def _change_default_speech_volume(self, step: float, decrease: bool = False) -> None: - acss = settings.voices[settings.DEFAULT_VOICE] - delta = step * (-1 if decrease else 1) - try: - volume = acss[ACSS.GAIN] - except KeyError: - volume = 10.0 - acss[ACSS.GAIN] = max(0, min(9, volume + delta)) - msg = f"HARDWARE SPEECH: volume set to {acss[ACSS.GAIN]}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if self._driver: - normalized = acss[ACSS.GAIN] / 9.0 - self._driver.set_volume(normalized) - self.speak( - messages.SPEECH_SOFTER if decrease else messages.SPEECH_LOUDER, - acss=acss - ) diff --git a/src/cthulhu/highlighter.py b/src/cthulhu/highlighter.py deleted file mode 100644 index 961f0b8..0000000 --- a/src/cthulhu/highlighter.py +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Module for drawing highlights over an area of interest.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -from . import debug - -try: - import cairo - import gi - gi.require_version('Gtk', '3.0') - from gi.repository import Gtk - CAIRO_AVAILABLE = True -except Exception as error: - tokens = ["HIGHLIGHTER: GtkHighlighter unavailable:", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - CAIRO_AVAILABLE = False - -class Highlighter: - """Base class of all highlighters supported by Cthulhu.""" - - HIGHLIGHT = "highlight" - RECTANGLE = "rectangle" - UNDERLINE = "underline" - - RED = (1, 0, 0) - BLUE = (0, 0, 1) - GREEN = (0, 1, 0) - YELLOW = (1, 1, 0) - PURPLE = (0.5, 0, 0.5) - ORANGE = (1, 0.5, 0) - PINK = (1, 0.75, 0.8) - CYAN = (0, 1, 1) - MAGENTA = (1, 0, 1) - LIME = (0.5, 1, 0) - NAVY = (0, 0, 0.5) - TEAL = (0, 0.5, 0.5) - BLACK = (0, 0, 0) - WHITE = (1, 1, 1) - - def __init__(self, highlight_type, color, alpha, thickness, padding, fill_color, fill_alpha): - self._highlight_type = highlight_type - self._color = color - self._alpha = alpha - self._thickness = thickness - self._padding = padding - self._fill_color = fill_color - self._fill_alpha = fill_alpha - self._gui = self._create_gui() - - def _create_gui(self): - """Creates the gui for the overlay.""" - return None - - def _draw_highlight(self, painter): - """Called by highlight to draw a highlight over the item.""" - pass - - def _draw_rectangle(self, painter): - """Called by highlight to draw a rectangle around the item.""" - pass - - def _draw_underline(self, painter): - """Called by highlight to draw an underline under the item.""" - pass - - def highlight(self, x, y, width, height): - """Draws the desired indicator over the specified box.""" - pass - - def quit(self): - """Quits the highlighter.""" - pass - - -class GtkHighlighter(Highlighter): - """Highlighter that uses a GtkWindow to highlight items.""" - - def __init__(self, - highlight_type=Highlighter.UNDERLINE, - color=Highlighter.GREEN, - alpha=1.0, - thickness=5, - padding=5, - fill_color=None, - fill_alpha=None): - if not CAIRO_AVAILABLE: - msg = "GTK HIGHLIGHTER: Unavailable. Is Cairo installed?" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - super().__init__(highlight_type, color, alpha, thickness, padding, fill_color, fill_alpha) - self._drawing_area = None - - def _create_gui(self): - """Creates the gui for the overlay.""" - - gui = Gtk.Window() - gui.set_decorated(False) - gui.set_accept_focus(False) - gui.set_app_paintable(True) - gui.set_skip_taskbar_hint(True) - gui.set_skip_pager_hint(True) - - screen = gui.get_screen() - visual = screen.get_rgba_visual() - if visual and screen.is_composited(): - gui.set_visual(visual) - - self._drawing_area = Gtk.DrawingArea() - self._drawing_area.connect("draw", self._on_draw) - gui.add(self._drawing_area) - return gui - - def _on_draw(self, widget, painter): - """Signal handler for the 'draw' event.""" - - if self._highlight_type == self.HIGHLIGHT: - self._draw_highlight(painter) - elif self._highlight_type == self.RECTANGLE: - self._draw_rectangle(painter) - elif self._highlight_type == self.UNDERLINE: - self._draw_underline(painter) - - def _draw_highlight(self, painter): - """Called by highlight to draw a highlight over the item.""" - - if self._fill_color is None: - self._fill_color = self.YELLOW - if self._fill_alpha is None: - self._fill_alpha = 0.3 - - fill = (*self._fill_color, self._fill_alpha) - painter.set_source_rgba(*fill) - painter.set_operator(cairo.OPERATOR_SOURCE) - painter.paint() - painter.set_operator(cairo.OPERATOR_OVER) - - def _draw_rectangle(self, painter): - """Called by highlight to draw a rectangle around the item.""" - - x = self._padding - y = self._padding - width = self._gui.get_allocated_width() - 2 * self._padding - height = self._gui.get_allocated_height() - 2 * self._padding - - if self._fill_color is not None and self._fill_alpha is not None: - fill = (*self._fill_color, self._fill_alpha * 255) - painter.set_source_rgba(*fill) - painter.rectangle(x, y, width, height) - painter.fill() - - line = (*self._color, self._alpha) - painter.set_source_rgba(*line) - painter.set_line_width(self._thickness) - painter.rectangle(x, y, width, height) - painter.stroke() - - def _draw_underline(self, painter): - """Called by highlight to draw an underline under the item.""" - - line = (*self._color, self._alpha) - painter.set_source_rgba(*line) - painter.set_line_width(self._thickness) - painter.move_to(0, self._gui.get_allocated_height() - 5) - painter.line_to(self._gui.get_allocated_width(), self._gui.get_allocated_height() - 5) - painter.stroke() - - def highlight(self, x, y, width, height): - """Draws the desired indicator over the specified box.""" - - msg = f"GTK HIGHLIGHTER: x:{x}, y:{y}, width:{width}, height:{height}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - try: - self._gui.move(x - self._padding, y - self._padding) - self._gui.resize(width + 2 * self._padding, height + 2 * self._padding) - except Exception as exc: - error_tokens = ["GTK HIGHLIGHTER: Exception:", exc] - debug.printTokens(debug.LEVEL_INFO, error_tokens, True) - else: - self._gui.show_all() - - def quit(self): - """Quits the highlighter.""" - - msg = "GTK HIGHLIGHTER: Quitting." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._gui.destroy() - self._drawing_area = None - self._gui = None diff --git a/src/cthulhu/input_event.py b/src/cthulhu/input_event.py deleted file mode 100644 index 3ee95e9..0000000 --- a/src/cthulhu/input_event.py +++ /dev/null @@ -1,1234 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides support for handling input events.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2011-2016 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -gi.require_version("Gdk", "3.0") -from gi.repository import Atspi - -import math -import time -from typing import Optional, Any -from gi.repository import Gdk -from gi.repository import GLib - -from . import debug -from . import keybindings -from . import keynames -from . import messages -from . import cthulhu -from . import cthulhu_modifier_manager -from . import cthulhu_state -from . import script_manager -from . import settings -from .ax_object import AXObject -from .ax_utilities import AXUtilities - -KEYBOARD_EVENT: str = "keyboard" -BRAILLE_EVENT: str = "braille" -MOUSE_BUTTON_EVENT: str = "mouse:button" -REMOTE_CONTROLLER_EVENT: str = "remote controller" - -class InputEvent: - - def __init__(self, eventType: str) -> None: - """Creates a new KEYBOARD_EVENT, BRAILLE_EVENT, or MOUSE_BUTTON_EVENT.""" - - self.type: str = eventType - self.time: float = time.time() - self._clickCount: int = 0 - - def get_click_count(self) -> int: - """Return the count of the number of clicks a user has made.""" - - return self._clickCount - - def set_click_count(self, count: Optional[int] = None) -> None: - """Updates the count of the number of clicks a user has made.""" - - if count is None: - return - - self._clickCount = count - -class KeyboardEvent(InputEvent): - stickyKeys: bool = False - - duplicateCount: int = 0 - cthulhuModifierPressed: bool = False - - # Whether last press of the Cthulhu modifier was alone - lastCthulhuModifierAlone: bool = False - lastCthulhuModifierAloneTime: Optional[float] = None - # Whether the current press of the Cthulhu modifier is alone - currentCthulhuModifierAlone: bool = False - currentCthulhuModifierAloneTime: Optional[float] = None - # When the second cthulhu press happened - secondCthulhuModifierTime: Optional[float] = None - # Sticky modifiers state, to be applied to the next keyboard event - cthulhuStickyModifiers: int = 0 - - TYPE_UNKNOWN = "unknown" - TYPE_PRINTABLE = "printable" - TYPE_MODIFIER = "modifier" - TYPE_LOCKING = "locking" - TYPE_FUNCTION = "function" - TYPE_ACTION = "action" - TYPE_NAVIGATION = "navigation" - TYPE_DIACRITICAL = "diacritical" - TYPE_ALPHABETIC = "alphabetic" - TYPE_NUMERIC = "numeric" - TYPE_PUNCTUATION = "punctuation" - TYPE_SPACE = "space" - - GDK_PUNCTUATION_KEYS = [Gdk.KEY_acute, - Gdk.KEY_ampersand, - Gdk.KEY_apostrophe, - Gdk.KEY_asciicircum, - Gdk.KEY_asciitilde, - Gdk.KEY_asterisk, - Gdk.KEY_at, - Gdk.KEY_backslash, - Gdk.KEY_bar, - Gdk.KEY_braceleft, - Gdk.KEY_braceright, - Gdk.KEY_bracketleft, - Gdk.KEY_bracketright, - Gdk.KEY_brokenbar, - Gdk.KEY_cedilla, - Gdk.KEY_cent, - Gdk.KEY_colon, - Gdk.KEY_comma, - Gdk.KEY_copyright, - Gdk.KEY_currency, - Gdk.KEY_degree, - Gdk.KEY_diaeresis, - Gdk.KEY_dollar, - Gdk.KEY_EuroSign, - Gdk.KEY_equal, - Gdk.KEY_exclam, - Gdk.KEY_exclamdown, - Gdk.KEY_grave, - Gdk.KEY_greater, - Gdk.KEY_guillemotleft, - Gdk.KEY_guillemotright, - Gdk.KEY_hyphen, - Gdk.KEY_less, - Gdk.KEY_macron, - Gdk.KEY_minus, - Gdk.KEY_notsign, - Gdk.KEY_numbersign, - Gdk.KEY_paragraph, - Gdk.KEY_parenleft, - Gdk.KEY_parenright, - Gdk.KEY_percent, - Gdk.KEY_period, - Gdk.KEY_periodcentered, - Gdk.KEY_plus, - Gdk.KEY_plusminus, - Gdk.KEY_question, - Gdk.KEY_questiondown, - Gdk.KEY_quotedbl, - Gdk.KEY_quoteleft, - Gdk.KEY_quoteright, - Gdk.KEY_registered, - Gdk.KEY_section, - Gdk.KEY_semicolon, - Gdk.KEY_slash, - Gdk.KEY_sterling, - Gdk.KEY_underscore, - Gdk.KEY_yen] - - GDK_ACCENTED_LETTER_KEYS = [Gdk.KEY_Aacute, - Gdk.KEY_aacute, - Gdk.KEY_Acircumflex, - Gdk.KEY_acircumflex, - Gdk.KEY_Adiaeresis, - Gdk.KEY_adiaeresis, - Gdk.KEY_Agrave, - Gdk.KEY_agrave, - Gdk.KEY_Aring, - Gdk.KEY_aring, - Gdk.KEY_Atilde, - Gdk.KEY_atilde, - Gdk.KEY_Ccedilla, - Gdk.KEY_ccedilla, - Gdk.KEY_Eacute, - Gdk.KEY_eacute, - Gdk.KEY_Ecircumflex, - Gdk.KEY_ecircumflex, - Gdk.KEY_Ediaeresis, - Gdk.KEY_ediaeresis, - Gdk.KEY_Egrave, - Gdk.KEY_egrave, - Gdk.KEY_Iacute, - Gdk.KEY_iacute, - Gdk.KEY_Icircumflex, - Gdk.KEY_icircumflex, - Gdk.KEY_Idiaeresis, - Gdk.KEY_idiaeresis, - Gdk.KEY_Igrave, - Gdk.KEY_igrave, - Gdk.KEY_Ntilde, - Gdk.KEY_ntilde, - Gdk.KEY_Oacute, - Gdk.KEY_oacute, - Gdk.KEY_Ocircumflex, - Gdk.KEY_ocircumflex, - Gdk.KEY_Odiaeresis, - Gdk.KEY_odiaeresis, - Gdk.KEY_Ograve, - Gdk.KEY_ograve, - Gdk.KEY_Ooblique, - Gdk.KEY_ooblique, - Gdk.KEY_Otilde, - Gdk.KEY_otilde, - Gdk.KEY_Uacute, - Gdk.KEY_uacute, - Gdk.KEY_Ucircumflex, - Gdk.KEY_ucircumflex, - Gdk.KEY_Udiaeresis, - Gdk.KEY_udiaeresis, - Gdk.KEY_Ugrave, - Gdk.KEY_ugrave, - Gdk.KEY_Yacute, - Gdk.KEY_yacute] - - def __init__(self, pressed, keycode, keysym, modifiers, text): - """Creates a new InputEvent of type KEYBOARD_EVENT. - - Arguments: - - pressed: True if key is pressed, False if released - - keycode: hardware keycode - - keysym: keysym value - - modifiers: modifier mask - - text: text representation of the key - """ - - super().__init__(KEYBOARD_EVENT) - self.id = keysym - self.type = Atspi.EventType.KEY_PRESSED_EVENT if pressed else Atspi.EventType.KEY_RELEASED_EVENT - self.hw_code = keycode - self.modifiers = modifiers & Gdk.ModifierType.MODIFIER_MASK - if modifiers & (1 << Atspi.ModifierType.NUMLOCK): - self.modifiers |= (1 << Atspi.ModifierType.NUMLOCK) - self.event_string = text - self.keyval_name = Gdk.keyval_name(keysym) - if self.event_string == "": - self.event_string = self.keyval_name - self.timestamp = time.time() * 1000 # Convert to milliseconds - self.is_duplicate = False # Will be set by InputEventManager - self._script = None - self._app = None - self._window = None - self._obj = None - self._handler = None - self._consumer = None - self._should_consume = None - self._consume_reason = None - self._did_consume = None - self._result_reason = None - self._bypassCthulhu = None - self._is_kp_with_numlock = False - - # Some implementors don't populate this field at all. More often than not, - # the event_string and the keyval_name coincide for input events. - if not self.event_string: - self.event_string = self.keyval_name - - # Some implementors do populate the field, but with the keyname rather than - # the printable character. This messes us up with punctuation and other symbols. - if len(self.event_string) > 1 \ - and (self.id in KeyboardEvent.GDK_PUNCTUATION_KEYS or \ - self.id in KeyboardEvent.GDK_ACCENTED_LETTER_KEYS): - self.event_string = chr(self.id) - - # Some implementors don't include numlock in the modifiers. Unfortunately, - # trying to heuristically hack around this just by looking at the event - # is not reliable. Ditto regarding asking Gdk for the numlock state. - if self.keyval_name.startswith("KP"): - if modifiers & (1 << Atspi.ModifierType.NUMLOCK): - self._is_kp_with_numlock = True - - self.keyType = None - self.shouldEcho = False - - # InputEventManager will call _finalize_initialization after setting - # script/object/window to ensure shouldConsume uses correct context. - - def _finalize_initialization(self): - """Finalize initialization after object creation. - This is separated to allow InputEventManager to set additional properties first.""" - - if self.is_duplicate: - KeyboardEvent.duplicateCount += 1 - else: - KeyboardEvent.duplicateCount = 0 - - _isPressed = self.type == Atspi.EventType.KEY_PRESSED_EVENT - role = AXObject.get_role(self._obj) if self._obj else None - _mayEcho = _isPressed or role == Atspi.Role.TERMINAL - - if KeyboardEvent.stickyKeys and not self.isCthulhuModifier() \ - and not KeyboardEvent.lastCthulhuModifierAlone: - doubleEvent = self._getDoubleClickCandidate() - if doubleEvent and \ - doubleEvent.modifiers & keybindings.CTHULHU_MODIFIER_MASK: - # this is the second event of a double-click, and sticky Cthulhu - # affected the first, so copy over the modifiers to the second - KeyboardEvent.cthulhuStickyModifiers = doubleEvent.modifiers - - if not self.isCthulhuModifier(): - if KeyboardEvent.cthulhuModifierPressed: - KeyboardEvent.currentCthulhuModifierAlone = False - KeyboardEvent.currentCthulhuModifierAloneTime = None - else: - KeyboardEvent.lastCthulhuModifierAlone = False - KeyboardEvent.lastCthulhuModifierAloneTime = None - - if self.isNavigationKey(): - self.keyType = KeyboardEvent.TYPE_NAVIGATION - self.shouldEcho = _mayEcho and settings.enableNavigationKeys - elif self.isActionKey(): - self.keyType = KeyboardEvent.TYPE_ACTION - self.shouldEcho = _mayEcho and settings.enableActionKeys - elif self.is_modifier_key(): - self.keyType = KeyboardEvent.TYPE_MODIFIER - self.shouldEcho = _mayEcho and settings.enableModifierKeys - if self.isCthulhuModifier() and not self.is_duplicate: - now = time.time() - if KeyboardEvent.lastCthulhuModifierAlone: - if _isPressed: - KeyboardEvent.secondCthulhuModifierTime = now - if (KeyboardEvent.secondCthulhuModifierTime is not None and - KeyboardEvent.lastCthulhuModifierAloneTime is not None and - KeyboardEvent.secondCthulhuModifierTime < - KeyboardEvent.lastCthulhuModifierAloneTime + 0.5): - # double-cthulhu, let the real action happen - if self.event_string in ["Caps_Lock", "Shift_Lock"]: - cthulhu_modifier_manager.getManager().toggleModifier(self) - else: - self._bypassCthulhu = True - if not _isPressed: - KeyboardEvent.lastCthulhuModifierAlone = False - KeyboardEvent.lastCthulhuModifierAloneTime = False - else: - KeyboardEvent.cthulhuModifierPressed = _isPressed - if _isPressed: - KeyboardEvent.currentCthulhuModifierAlone = True - KeyboardEvent.currentCthulhuModifierAloneTime = now - else: - KeyboardEvent.lastCthulhuModifierAlone = \ - KeyboardEvent.currentCthulhuModifierAlone - KeyboardEvent.lastCthulhuModifierAloneTime = \ - KeyboardEvent.currentCthulhuModifierAloneTime - elif self.isFunctionKey(): - self.keyType = KeyboardEvent.TYPE_FUNCTION - self.shouldEcho = _mayEcho and settings.enableFunctionKeys - elif self.isDiacriticalKey(): - self.keyType = KeyboardEvent.TYPE_DIACRITICAL - self.shouldEcho = _mayEcho and settings.enableDiacriticalKeys - elif self.isLockingKey(): - self.keyType = KeyboardEvent.TYPE_LOCKING - self.shouldEcho = settings.presentLockingKeys - if self.shouldEcho is None: - self.shouldEcho = not settings.onlySpeakDisplayedText - self.shouldEcho = self.shouldEcho and _isPressed - elif self.isAlphabeticKey(): - self.keyType = KeyboardEvent.TYPE_ALPHABETIC - self.shouldEcho = _mayEcho \ - and (settings.enableAlphabeticKeys or settings.enableEchoByCharacter) - elif self.isNumericKey(): - self.keyType = KeyboardEvent.TYPE_NUMERIC - self.shouldEcho = _mayEcho \ - and (settings.enableNumericKeys or settings.enableEchoByCharacter) - elif self.isPunctuationKey(): - self.keyType = KeyboardEvent.TYPE_PUNCTUATION - self.shouldEcho = _mayEcho \ - and (settings.enablePunctuationKeys or settings.enableEchoByCharacter) - elif self.isSpace(): - self.keyType = KeyboardEvent.TYPE_SPACE - self.shouldEcho = _mayEcho \ - and (settings.enableSpace or settings.enableEchoByCharacter) - else: - self.keyType = KeyboardEvent.TYPE_UNKNOWN - self.shouldEcho = False - - if not self.isLockingKey(): - self.shouldEcho = self.shouldEcho and settings.enableKeyEcho - - if not self.is_modifier_key(): - self.set_click_count() - - if cthulhu_state.bypassNextCommand and _isPressed: - KeyboardEvent.cthulhuModifierPressed = False - - if KeyboardEvent.cthulhuModifierPressed: - self.modifiers |= keybindings.CTHULHU_MODIFIER_MASK - - if KeyboardEvent.stickyKeys: - # apply all recorded sticky modifiers - self.modifiers |= KeyboardEvent.cthulhuStickyModifiers - if self.is_modifier_key(): - # add this modifier to the sticky ones - KeyboardEvent.cthulhuStickyModifiers |= self.modifiers - else: - # Non-modifier key, so clear the sticky modifiers. If the user - # actually double-presses that key, the modifiers of this event - # will be copied over to the second event, see earlier in this - # function. - KeyboardEvent.cthulhuStickyModifiers = 0 - - self._should_consume, self._consume_reason = self.shouldConsume() - - def _getDoubleClickCandidate(self): - lastEvent = cthulhu_state.lastNonModifierKeyEvent - if isinstance(lastEvent, KeyboardEvent) \ - and lastEvent.event_string == self.event_string \ - and self.time - lastEvent.time <= settings.doubleClickTimeout: - return lastEvent - return None - - def set_click_count(self, count=None): - """Updates the count of the number of clicks a user has made. - - If count is provided, sets the click count to that value. - Otherwise, calculates the click count based on event timing.""" - - if count is not None: - self._clickCount = count - return - - doubleEvent = self._getDoubleClickCandidate() - if not doubleEvent: - self._clickCount = 1 - return - - self._clickCount = doubleEvent.get_click_count() - if self.is_duplicate: - return - - if self.type == Atspi.EventType.KEY_RELEASED_EVENT: - return - - if self._clickCount < 3: - self._clickCount += 1 - return - - self._clickCount = 1 - - def __eq__(self, other): - if not other: - return False - - if self.type == other.type and self.hw_code == other.hw_code: - return self.timestamp == other.timestamp - - return False - - def __str__(self): - if self._shouldObscure(): - keyid = hw_code = modifiers = event_string = keyval_name = key_type = "*" - else: - keyid = self.id - hw_code = self.hw_code - modifiers = self.modifiers - event_string = self.event_string - keyval_name = self.keyval_name - key_type = self.keyType - - return (f"KEYBOARD_EVENT: type={self.type.value_name.upper()}\n") \ - + f" id={keyid}\n" \ - + f" hw_code={hw_code}\n" \ - + f" modifiers={modifiers}\n" \ - + f" event_string=({event_string})\n" \ - + f" keyval_name=({keyval_name})\n" \ - + (" timestamp=%d\n" % self.timestamp) \ - + f" time={time.time():f}\n" \ - + f" keyType={key_type}\n" \ - + f" clickCount={self._clickCount}\n" \ - + f" shouldEcho={self.shouldEcho}\n" - - def _shouldObscure(self): - if not AXUtilities.is_password_text(self._obj): - return False - - if not self.is_printable_key(): - return False - - if self.modifiers & keybindings.CTRL_MODIFIER_MASK \ - or self.modifiers & keybindings.ALT_MODIFIER_MASK \ - or self.modifiers & keybindings.CTHULHU_MODIFIER_MASK: - return False - - return True - - def _isReleaseForLastNonModifierKeyEvent(self): - last = cthulhu_state.lastNonModifierKeyEvent - if not last: - return False - - if not last.is_pressed_key() or self.is_pressed_key(): - return False - - if self.id == last.id and self.hw_code == last.hw_code: - return self.modifiers == last.modifiers - - return False - - def isReleaseFor(self, other): - """Return True if this is the release event for other.""" - - if not other: - return False - - if not other.is_pressed_key() or self.is_pressed_key(): - return False - - return self.id == other.id \ - and self.hw_code == other.hw_code \ - and self.modifiers == other.modifiers \ - and self.event_string == other.event_string \ - and self.keyval_name == other.keyval_name \ - and self.keyType == other.keyType \ - and self._clickCount == other._clickCount - - def isNavigationKey(self): - """Return True if this is a navigation key.""" - - if self.keyType: - return self.keyType == KeyboardEvent.TYPE_NAVIGATION - - return self.event_string in \ - ["Left", "Right", "Up", "Down", "Home", "End"] - - def isActionKey(self): - """Return True if this is an action key.""" - - if self.keyType: - return self.keyType == KeyboardEvent.TYPE_ACTION - - return self.event_string in \ - ["Return", "Escape", "Tab", "BackSpace", "Delete", - "Page_Up", "Page_Down"] - - def isAlphabeticKey(self): - """Return True if this is an alphabetic key.""" - - if self.keyType: - return self.keyType == KeyboardEvent.TYPE_ALPHABETIC - - if not len(self.event_string) == 1: - return False - - return self.event_string.isalpha() - - def isDiacriticalKey(self): - """Return True if this is a non-spacing diacritical key.""" - - if self.keyType: - return self.keyType == KeyboardEvent.TYPE_DIACRITICAL - - return self.event_string.startswith("dead_") - - def isFunctionKey(self): - """Return True if this is a function key.""" - - if self.keyType: - return self.keyType == KeyboardEvent.TYPE_FUNCTION - - return self.event_string in \ - ["F1", "F2", "F3", "F4", "F5", "F6", - "F7", "F8", "F9", "F10", "F11", "F12"] - - def isLockingKey(self): - """Return True if this is a locking key.""" - - if self.keyType: - return self.keyType in KeyboardEvent.TYPE_LOCKING - - lockingKeys = ["Caps_Lock", "Shift_Lock", "Num_Lock", "Scroll_Lock"] - if self.event_string not in lockingKeys: - return False - - if not cthulhu_state.bypassNextCommand and not self._bypassCthulhu: - return self.event_string not in settings.cthulhuModifierKeys - - return True - - def is_modifier_key(self): - """Return True if this is a modifier key.""" - - if self.keyType: - return self.keyType == KeyboardEvent.TYPE_MODIFIER - - if self.isCthulhuModifier(): - return True - - return self.event_string in \ - ['Alt_L', 'Alt_R', 'Control_L', 'Control_R', - 'Shift_L', 'Shift_R', 'Meta_L', 'Meta_R', - 'ISO_Level3_Shift'] - - def isNumericKey(self): - """Return True if this is a numeric key.""" - - if self.keyType: - return self.keyType == KeyboardEvent.TYPE_NUMERIC - - if not len(self.event_string) == 1: - return False - - return self.event_string.isnumeric() - - def isCthulhuModifier(self, checkBypassMode=True): - """Return True if this is the Cthulhu modifier key.""" - - if checkBypassMode and cthulhu_state.bypassNextCommand: - return False - - if self.event_string in settings.cthulhuModifierKeys: - return True - - if self.keyval_name == "KP_0" \ - and "KP_Insert" in settings.cthulhuModifierKeys \ - and self.modifiers & keybindings.SHIFT_MODIFIER_MASK: - return True - - return False - - def isCthulhuModified(self): - """Return True if this key is Cthulhu modified.""" - - if cthulhu_state.bypassNextCommand: - return False - - return self.modifiers & keybindings.CTHULHU_MODIFIER_MASK - - def isKeyPadKeyWithNumlockOn(self): - """Return True if this is a key pad key with numlock on.""" - - return self._is_kp_with_numlock - - def is_printable_key(self): - """Return True if this is a printable key.""" - - if self.event_string in ["space", " "]: - return True - - if not len(self.event_string) == 1: - return False - - return self.event_string.isprintable() - - def is_pressed_key(self): - """Returns True if the key is pressed""" - - return self.type == Atspi.EventType.KEY_PRESSED_EVENT - - def isPunctuationKey(self): - """Return True if this is a punctuation key.""" - - if self.keyType: - return self.keyType == KeyboardEvent.TYPE_PUNCTUATION - - if not len(self.event_string) == 1: - return False - - if self.isAlphabeticKey() or self.isNumericKey(): - return False - - return self.event_string.isprintable() and not self.event_string.isspace() - - def isSpace(self): - """Return True if this is the space key.""" - - if self.keyType: - return self.keyType == KeyboardEvent.TYPE_SPACE - - return self.event_string in ["space", " "] - - def isFromApplication(self, app): - """Return True if this is associated with the specified app.""" - - return self._app == app - - def isCharacterEchoable(self): - """Returns True if the script will echo this event as part of - character echo. We do this to not double-echo a given printable - character.""" - - if not self.is_printable_key(): - return False - - script = cthulhu_state.activeScript - return script and script.utilities.willEchoCharacter(self) - - def getLockingState(self): - """Returns True if the event locked a locking key, False if the - event unlocked a locking key, and None if we do not know or this - is not a locking key.""" - - if not self.isLockingKey(): - return None - - if self.event_string == "Caps_Lock": - mod = Atspi.ModifierType.SHIFTLOCK - elif self.event_string == "Shift_Lock": - mod = Atspi.ModifierType.SHIFT - elif self.event_string == "Num_Lock": - mod = Atspi.ModifierType.NUMLOCK - else: - return None - - return not self.modifiers & (1 << mod) - - def getLockingStateString(self): - """Returns the string which reflects the locking state we wish to - include when presenting a locking key.""" - - locked = self.getLockingState() - if locked is None: - return '' - - if not locked: - return messages.LOCKING_KEY_STATE_OFF - - return messages.LOCKING_KEY_STATE_ON - - def getKeyName(self): - """Returns the string to be used for presenting the key to the user.""" - - return keynames.getKeyName(self.event_string) - - def get_object(self): - """Returns the object believed to be associated with this key event.""" - - return self._obj - - def set_object(self, obj): - """Sets the object believed to be associated with this key event.""" - - self._obj = obj - - def get_window(self): - """Returns the window associated with this key event.""" - - return self._window - - def set_window(self, window): - """Sets the window associated with this key event.""" - - self._window = window - - def get_script(self): - """Returns the script associated with this key event.""" - - return self._script - - def set_script(self, script): - """Sets the script associated with this key event.""" - - self._script = script - if script: - self._app = script.app - - def get_click_count(self): - """Returns the click count for this event.""" - - return self._clickCount - - def as_single_line_string(self): - """Returns a single-line string representation of this event.""" - - return f"KeyboardEvent({self.keyval_name}, pressed={self.is_pressed_key()}, modifiers={self.modifiers})" - - def getHandler(self): - """Returns the handler associated with this key event.""" - - return self._handler - - def _resolveHandler(self): - """Resolve handler for this event, returning True if a global handler was used.""" - - if not self._handler and self._script: - self._handler = self._script.keyBindings.getInputHandler(self) - - if not self._handler: - globalHandler = self._getGlobalHandler() - if globalHandler: - self._handler = globalHandler - return True - - return False - - def shouldConsume(self): - """Returns True if this event should be consumed.""" - - # Debug logging to understand handler matching - debug.print_log( - debug.LEVEL_INFO, - "INPUT EVENT", - f"shouldConsume: key='{self.event_string}' hw_code={self.hw_code} modifiers={self.modifiers}", - timestamp=True, - ) - - if not self.timestamp: - return False, 'No timestamp' - - globalHandlerUsed = False - if not self._script: - globalHandler = self._getGlobalHandler() - if globalHandler: - self._handler = globalHandler - self._script = script_manager.get_manager().get_default_script() - globalHandlerUsed = True - else: - debug.print_log(debug.LEVEL_INFO, "INPUT EVENT", - "shouldConsume: No active script", - reason="no-active-script", timestamp=True) - return False, 'No active script when received' - - debug.print_log(debug.LEVEL_INFO, "INPUT EVENT", - f"shouldConsume: Active script={self._script.__class__.__name__}", - timestamp=True) - - if self.is_duplicate: - return False, 'Is duplicate' - - if cthulhu_state.capturingKeys: - return False, 'Capturing keys' - - if cthulhu_state.bypassNextCommand: - return False, 'Bypass next command' - - globalHandlerUsed = globalHandlerUsed or self._resolveHandler() - - if self._handler: - debug.print_log(debug.LEVEL_INFO, "INPUT EVENT", - f"shouldConsume: Handler found: {self._handler.description}", - timestamp=True) - else: - debug.print_log(debug.LEVEL_INFO, "INPUT EVENT", - "shouldConsume: No handler found", - reason="no-handler", timestamp=True) - - if self._isSleepModeActive(): - if self._isSleepModeToggleHandler(): - return True, 'Sleep mode toggle command' - return False, 'Sleep mode active' - - self._script.updateKeyboardEventState(self, self._handler) - scriptConsumes = self._script.shouldConsumeKeyboardEvent(self, self._handler) - if globalHandlerUsed: - scriptConsumes = True - debug.print_log(debug.LEVEL_INFO, "INPUT EVENT", - f"shouldConsume: scriptConsumes={scriptConsumes}", - timestamp=True) - - if self._isReleaseForLastNonModifierKeyEvent(): - return scriptConsumes, 'Is release for last non-modifier keyevent' - - if self._script.learnModePresenter.is_active(): - self._consumer = self._script.learnModePresenter.handle_event - return True, 'In Learn Mode' - - if self.is_modifier_key(): - if not self.isCthulhuModifier(): - return False, 'Non-Cthulhu modifier not in Learn Mode' - return True, 'Cthulhu modifier' - - if not self._handler: - if scriptConsumes: - return True, 'Script consumed without handler' - return False, 'No handler' - - return scriptConsumes, 'Script indication' - - def _getGlobalHandler(self): - try: - plugin_manager = cthulhu.cthulhuApp.getPluginSystemManager() - except Exception: - return None - if not plugin_manager: - return None - global_bindings = plugin_manager.get_global_keybindings() - if not global_bindings: - return None - return global_bindings.getInputHandler(self) - - def _isSleepModeActive(self): - """Returns True if the script for this event is in sleep mode.""" - - if not self._script: - return False - - if "scripts.sleepmode" in self._script.__module__: - return True - - app = getattr(self._script, "app", None) - if app is None: - return False - - try: - from . import sleep_mode_manager - manager = sleep_mode_manager.getManager() - return bool(manager and manager.isActiveForApp(app)) - except Exception: - return False - - def _isSleepModeToggleHandler(self): - """Returns True if the resolved handler toggles sleep mode.""" - - if not self._handler or not self._handler.function: - return False - - functionName = getattr(self._handler.function, "__name__", "") - return "toggleSleepMode" in functionName - - def didConsume(self): - """Returns True if this event was consumed.""" - - if self._did_consume is not None: - return self._did_consume - - return False - - def isHandledBy(self, method): - if not self._handler: - return False - - return method.__func__ == self._handler.function - - def _should_interrupt_presentation_on_press(self): - if not settings.gameMode: - return True - - if cthulhu_state.bypassNextCommand and not self.is_modifier_key(): - return False - - if self._handler or self._consumer: - return True - - if self.isCthulhuModifier(): - return True - - return False - - def _present(self, inputEvent=None): - if self.is_pressed_key(): - if self._should_interrupt_presentation_on_press(): - self._script.presentationInterrupt() - - if self._script.learnModePresenter.is_active(): - return False - - return self._script.presentKeyboardEvent(self) - - def process(self): - """Processes this input event.""" - - startTime = time.time() - if not self._shouldObscure(): - data = "'%s' (%d)" % (self.event_string, self.hw_code) - else: - data = "(obscured)" - - if self.is_duplicate: - data = '%s DUPLICATE EVENT #%i' % (data, KeyboardEvent.duplicateCount) - - msg = f'\nvvvvv PROCESS {self.type.value_name.upper()}: {data} vvvvv' - debug.printMessage(debug.LEVEL_INFO, msg, False) - - tokens = ["HOST_APP:", self._app] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - tokens = ["WINDOW:", self._window] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - tokens = ["LOCATION:", self._obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - tokens = ["CONSUME:", self._should_consume, self._consume_reason] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self._did_consume, self._result_reason = self._process() - - if self._should_consume != self._did_consume: - tokens = ["CONSUMED:", self._did_consume, self._result_reason] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if debug.LEVEL_INFO >= debug.debugLevel and cthulhu_state.activeScript: - attributes = cthulhu_state.activeScript.getTransferableAttributes() - for key, value in attributes.items(): - msg = f"INPUT EVENT: {key}: {value}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - msg = f"TOTAL PROCESSING TIME: {time.time() - startTime:.4f}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - msg = f"^^^^^ PROCESS {self.type.value_name.upper()}: {data} ^^^^^\n" - debug.printMessage(debug.LEVEL_INFO, msg, False) - - return self._did_consume - - def _process(self): - """Processes this input event.""" - - if self._bypassCthulhu: - if (self.event_string == "Caps_Lock" \ - or self.event_string == "Shift_Lock") \ - and self.type == Atspi.EventType.KEY_PRESSED_EVENT: - self.keyType = KeyboardEvent.TYPE_LOCKING - self._present() - return False, 'Bypassed cthulhu modifier' - - cthulhu_state.lastInputEvent = self - if not self.is_modifier_key(): - cthulhu_state.lastNonModifierKeyEvent = self - - if not self._script: - return False, 'No active script' - - if self.is_duplicate: - return False, 'Is duplicate' - - self._present() - - if not self.is_pressed_key(): - return self._should_consume, 'Consumed based on handler' - - if cthulhu_state.capturingKeys: - return False, 'Capturing keys' - - if self.isCthulhuModifier(): - return True, 'Cthulhu modifier' - - if cthulhu_state.bypassNextCommand: - if not self.is_modifier_key(): - cthulhu_state.bypassNextCommand = False - cthulhu_modifier_manager.getManager().refreshCthulhuModifiers("Bypass next command disabled") - self._script.addKeyGrabs() - return False, 'Bypass next command' - - if not self._should_consume: - return False, 'Should not consume' - - if not (self._consumer or self._handler): - return True, 'Consumed during shouldConsume' - - if self._consumer or self._handler.function: - GLib.timeout_add(1, self._consume) - return True, 'Will be consumed' - - return False, 'Unaddressed case' - - def _consume(self): - startTime = time.time() - data = "'%s' (%d)" % (self.event_string, self.hw_code) - msg = f'vvvvv CONSUME {self.type.value_name.upper()}: {data} vvvvv' - debug.printMessage(debug.LEVEL_INFO, msg, False) - - if self._consumer: - msg = f'INFO: Consumer is {self._consumer.__name__}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._consumer(self) - elif self._handler.function: - msg = f'INFO: Handler is {self._handler.description}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._handler.function(self._script, self) - else: - msg = 'INFO: No handler or consumer' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - msg = f'TOTAL PROCESSING TIME: {time.time() - startTime:.4f}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - msg = f'^^^^^ CONSUME {self.type.value_name.upper()}: {data} ^^^^^' - debug.printMessage(debug.LEVEL_INFO, msg, False) - - return False - -class BrailleEvent(InputEvent): - - def __init__(self, event): - """Creates a new InputEvent of type BRAILLE_EVENT. - - Arguments: - - event: the integer BrlTTY command for this event. - """ - super().__init__(BRAILLE_EVENT) - self.event = event - -class MouseButtonEvent(InputEvent): - - try: - display = Gdk.Display.get_default() - seat = Gdk.Display.get_default_seat(display) - _pointer = seat.get_pointer() - except Exception: - _pointer = None - - def __init__(self, event): - """Creates a new InputEvent of type MOUSE_BUTTON_EVENT.""" - - super().__init__(MOUSE_BUTTON_EVENT) - self.x = event.detail1 - self.y = event.detail2 - self.pressed = event.type.endswith('p') - self.button = event.type[len("mouse:button:"):-1] - self._script = cthulhu_state.activeScript - self.window = cthulhu_state.activeWindow - self.obj = None - - if self.pressed: - self._validateCoordinates() - - if not self._script: - return - - if not self._script.utilities.canBeActiveWindow(self.window): - self.window = self._script.utilities.activeWindow() - - if not self.window: - return - - self.obj = self._script.utilities.descendantAtPoint( - self.window, self.x, self.y, event.any_data) - - def _validateCoordinates(self): - if not self._pointer: - return - - screen, x, y = self._pointer.get_position() - if math.sqrt((self.x - x)**2 + (self.y - y)**2) < 25: - return - - msg = ( - f"WARNING: Event coordinates ({self.x}, {self.y}) may be bogus. " - f"Updating to ({x}, {y})" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.x, self.y = x, y - - def set_click_count(self, count=None): - """Updates the count of the number of clicks a user has made.""" - - if count is not None: - self._clickCount = count - return - - if not self.pressed: - return - - lastInputEvent = cthulhu_state.lastInputEvent - if not isinstance(lastInputEvent, MouseButtonEvent): - self._clickCount = 1 - return - - if self.time - lastInputEvent.time < settings.doubleClickTimeout \ - and lastInputEvent.button == self.button: - if self._clickCount < 2: - self._clickCount += 1 - return - - self._clickCount = 1 - - -class RemoteControllerEvent(InputEvent): - """A simple input event whose main purpose is identification of the origin.""" - - def __init__(self): - super().__init__(REMOTE_CONTROLLER_EVENT) - - -class InputEventHandler: - - def __init__(self, function, description, learnModeEnabled=True, enabled=True): - """Creates a new InputEventHandler instance. All bindings - (e.g., key bindings and braille bindings) will be handled - by an instance of an InputEventHandler. - - Arguments: - - function: the function to call with an InputEvent instance as its - sole argument. The function is expected to return True - if it consumes the event; otherwise it should return - False - - description: a localized string describing what this InputEvent - does - - learnModeEnabled: if True, the description will be spoken and - brailled if learn mode is enabled. If False, - the function will be called no matter what. - """ - - self.function = function - self.description = description - self.learnModeEnabled = learnModeEnabled - self._enabled = enabled - - def is_enabled(self): - """Returns True if this handler is enabled.""" - return self._enabled - - def set_enabled(self, enabled): - """Sets enabled state of this handler.""" - self._enabled = enabled - - def __eq__(self, other): - """Compares one input handler to another.""" - - if not other: - return False - - return (self.function == other.function) - - def processInputEvent(self, script, inputEvent): - """Processes an input event. - - This function is expected to return True if it consumes the - event; otherwise it is expected to return False. - - Arguments: - - script: the script (if any) associated with this event - - inputEvent: the input event to pass to the function bound - to this InputEventHandler instance. - """ - - consumed = False - try: - consumed = self.function(script, inputEvent) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - return consumed diff --git a/src/cthulhu/input_event_manager.py b/src/cthulhu/input_event_manager.py deleted file mode 100644 index 6830299..0000000 --- a/src/cthulhu/input_event_manager.py +++ /dev/null @@ -1,2230 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright 2024 Igalia, S.L. -# Copyright 2024 GNOME Foundation Inc. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -# pylint: disable=wrong-import-position -# pylint: disable=too-many-public-methods -# pylint: disable=too-many-lines - -"""Provides utilities for managing input events.""" - -# This has to be the first non-docstring line in the module to make linters happy. -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Igalia, S.L." \ - "Copyright (c) 2024 GNOME Foundation Inc." -__license__ = "LGPL" - -import os -from typing import TYPE_CHECKING, Optional, Union, Tuple, List, Dict, Any - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import GLib - -from . import debug -from . import focus_manager -from . import input_event -from . import script_manager -from . import settings -from . import cthulhu_state -from .wnck_support import load_wnck -from .ax_object import AXObject -from .ax_utilities import AXUtilities -from .ax_utilities_application import AXUtilitiesApplication - -if TYPE_CHECKING: - from . import keybindings - -_X11_SHIFT_MASK = 1 << int(Atspi.ModifierType.SHIFT) -_X11_SHIFT_LOCK_MASK = 1 << int(Atspi.ModifierType.SHIFTLOCK) -_X11_NUM_LOCK_MASK = 1 << int(Atspi.ModifierType.NUMLOCK) -_X11_CONSUMABLE_MODIFIER_MASKS = ( - 0, - _X11_SHIFT_MASK, - _X11_SHIFT_LOCK_MASK, - _X11_SHIFT_MASK | _X11_SHIFT_LOCK_MASK, - _X11_NUM_LOCK_MASK, - _X11_SHIFT_MASK | _X11_NUM_LOCK_MASK, - _X11_SHIFT_LOCK_MASK | _X11_NUM_LOCK_MASK, - _X11_SHIFT_MASK | _X11_SHIFT_LOCK_MASK | _X11_NUM_LOCK_MASK, -) -_X11_CONSUMABLE_EVENT_TYPES = ( - (1 << int(Atspi.EventType.KEY_PRESSED_EVENT)) - | (1 << int(Atspi.EventType.KEY_RELEASED_EVENT)) -) -_X11_CONSUMABLE_SYNC_TYPE = ( - Atspi.KeyListenerSyncType.SYNCHRONOUS - | Atspi.KeyListenerSyncType.CANCONSUME -) -_X11_CONSUMABLE_KEYSYMS = ( - "a", "b", "c", "d", "e", "f", "g", "h", "i", "k", "l", "m", - "o", "p", "q", "r", "s", "t", "u", "v", "x", "y", - "1", "2", "3", "4", "5", "6", "comma", -) -def _get_x11_consumable_key_set() -> List[Atspi.KeyDefinition]: - """Returns AT-SPI definitions for unmodified structural-navigation keys.""" - - # Importing here avoids a module-level cycle: keybindings obtains this - # manager lazily when bindings install their AT-SPI grabs. - from . import keybindings # pylint: disable=import-outside-toplevel - - keycodes = sorted({ - keycode - for keysym in _X11_CONSUMABLE_KEYSYMS - if (keycode := keybindings.get_keycodes(keysym)[1]) - }) - keySet = [] - for keycode in keycodes: - definition = Atspi.KeyDefinition() - definition.keycode = keycode - keySet.append(definition) - return keySet - - -class InputEventManager: - """Provides utilities for managing input events.""" - - def __init__(self) -> None: - self._last_input_event: Optional[input_event.InputEvent] = None - self._last_non_modifier_key_event: Optional[input_event.KeyboardEvent] = None - self._device: Optional[Atspi.Device] = None - self._key_pressed_id: int = 0 - self._key_released_id: int = 0 - self._selective_legacy_listener_active: bool = False - self._selective_legacy_listener: Optional[Atspi.DeviceListener] = None - self._selective_legacy_registered_masks: List[int] = [] - self._selective_legacy_key_set: List[Atspi.KeyDefinition] = [] - self._selective_legacy_keycodes: set[int] = set() - self._pointer_moved_id: int = 0 - self._mapped_keycodes: List[int] = [] - self._mapped_keysyms: List[int] = [] - self._grabbed_bindings: Dict[int, keybindings.KeyBinding] = {} - self._paused: bool = False - self._secure_input_active: bool = False - self._wnck = None - self._did_attempt_wnck_load: bool = False - self._x11Display = None - self._x11Root = None - self._netActiveWindowAtom = None - self._x11AnyPropertyType = None - self._didAttemptX11Display: bool = False - self._lastEwmhReadWindowId: Optional[int] = None - self._lastEwmhActiveWindowId: Optional[int] = None - self._lastEwmhXtermMatch: Optional[bool] = None - self._scriptWithSuspendedGrabsForXterm = None - self._xtermFocusScreen = None - self._xtermFocusHandlerId: int = 0 - self._xtermRecoverySourceId: int = 0 - self._xtermRecoveryPollCount: int = 0 - self._xtermHandoffHistory: List[str] = [] - self._compositorStateAdapter: Optional[Any] = None - - def set_compositor_state_adapter(self, adapter: Optional[Any]) -> None: - """Stores the compositor adapter used to refresh XTerm handoff state.""" - - self._compositorStateAdapter = adapter - - def activate_device(self) -> Atspi.Device: - """Creates and returns the AT-SPI device used by this manager.""" - - if self._device is not None: - return self._device - - if Atspi.get_version() >= (2, 55, 90): - self._device = Atspi.Device.new_full("org.stormux.Cthulhu") - else: - self._device = Atspi.Device.new() - - return self._device - - def get_device(self) -> Optional[Atspi.Device]: - """Returns the active AT-SPI device, if any.""" - - return self._device - - def start_key_watcher(self) -> None: - """Starts the watcher for keyboard input events.""" - - msg = "INPUT EVENT MANAGER: Starting key watcher." - debug.print_message(debug.LEVEL_INFO, msg, True) - device = self.activate_device() - atspiVersion = Atspi.get_version() - if atspiVersion[0] > 2 or atspiVersion[1] >= 60: - msg = "INPUT EVENT MANAGER: Using AT-SPI key signals." - debug.print_message(debug.LEVEL_INFO, msg, True) - self._key_pressed_id = device.connect("key-pressed", self._on_key_pressed) - self._key_released_id = device.connect("key-released", self._on_key_released) - if os.environ.get("XDG_SESSION_TYPE", "").lower() == "x11": - self._selective_legacy_key_set = _get_x11_consumable_key_set() - if self._selective_legacy_key_set: - self._selective_legacy_keycodes = { - definition.keycode for definition in self._selective_legacy_key_set - } - msg = "INPUT EVENT MANAGER: Adding selective consumable X11 key listener." - debug.print_message(debug.LEVEL_INFO, msg, True) - self._register_selective_legacy_key_listener() - else: - msg = "INPUT EVENT MANAGER: Using legacy AT-SPI key watcher." - debug.print_message(debug.LEVEL_INFO, msg, True) - device.add_key_watcher(self.process_keyboard_event) - - if os.environ.get("XDG_SESSION_TYPE", "").lower() == "x11": - self._initialize_xterm_handoff() - - def stop_key_watcher(self) -> None: - """Stops the watcher for keyboard input events.""" - - msg = "INPUT EVENT MANAGER: Stopping key watcher." - debug.print_message(debug.LEVEL_INFO, msg, True) - self._deregister_selective_legacy_key_listener() - if self._device is not None: - for handlerId in (self._key_pressed_id, self._key_released_id): - if handlerId: - self._device.disconnect(handlerId) - self._key_pressed_id = 0 - self._key_released_id = 0 - self._device = None - self._stop_xterm_focus_monitor() - self._stop_xterm_recovery_timer() - self._close_x11_display() - self._didAttemptX11Display = False - self._scriptWithSuspendedGrabsForXterm = None - - def get_debug_snapshot(self) -> Dict[str, object]: - """Returns read-only counters useful for long-uptime diagnostics.""" - - return { - "device_active": self._device is not None, - "pointer_watcher_active": self._pointer_moved_id != 0, - "mapped_keycodes": len(self._mapped_keycodes), - "mapped_keysyms": len(self._mapped_keysyms), - "grabbed_bindings": len(self._grabbed_bindings), - "paused": self._paused, - "secure_input_active": self._secure_input_active, - "suspended_xterm_script_present": self._scriptWithSuspendedGrabsForXterm is not None, - "xterm_focus_monitor_active": self._xtermFocusHandlerId != 0, - "xterm_recovery_timer_active": self._xtermRecoverySourceId != 0, - "xterm_recovery_source_present": self._xterm_recovery_source_is_present(), - "xterm_recovery_poll_count": self._xtermRecoveryPollCount, - "xterm_handoff_history": " | ".join(self._xtermHandoffHistory), - "last_ewmh_read_window_id": ( - hex(self._lastEwmhReadWindowId) - if self._lastEwmhReadWindowId is not None - else "" - ), - "last_ewmh_active_window_id": ( - hex(self._lastEwmhActiveWindowId) - if self._lastEwmhActiveWindowId is not None - else "" - ), - "last_ewmh_xterm_match": self._lastEwmhXtermMatch, - "last_input_event_present": self._last_input_event is not None, - "last_non_modifier_key_event_present": self._last_non_modifier_key_event is not None, - } - - def enable_pointer_monitoring(self) -> bool: - """Enables pointer monitoring on the current device, if possible.""" - - device = self.get_device() - if device is None: - return False - - deviceCapability = getattr(Atspi, "DeviceCapability", None) - if deviceCapability is None: - return False - - pointerMonitor = getattr(deviceCapability, "POINTER_MONITOR", None) - if pointerMonitor is None: - return False - - setCapabilities = getattr(device, "set_capabilities", None) - if not callable(setCapabilities): - return False - - currentCapabilities = 0 - getCapabilities = getattr(device, "get_capabilities", None) - if callable(getCapabilities): - currentCapabilities = getCapabilities() - - try: - grantedCapabilities = setCapabilities(currentCapabilities | pointerMonitor) - except GLib.GError: - return False - - if isinstance(grantedCapabilities, bool): - return grantedCapabilities - - try: - return bool(int(grantedCapabilities) & int(pointerMonitor)) - except (TypeError, ValueError): - return False - - def start_pointer_watcher(self, callback) -> None: - """Starts the watcher for pointer movement events.""" - - device = self.get_device() - if device is None: - return - - self._pointer_moved_id = device.connect("pointer-moved", callback) - - def stop_pointer_watcher(self) -> None: - """Stops the watcher for pointer movement events.""" - - device = self.get_device() - if device is None or not self._pointer_moved_id: - self._pointer_moved_id = 0 - return - - device.disconnect(self._pointer_moved_id) - self._pointer_moved_id = 0 - - def pause_key_watcher(self, pause: bool = True, reason: str = "") -> None: - """Pauses processing of keyboard input events.""" - - msg = f"INPUT EVENT MANAGER: Pause queueing: {pause}. {reason}" - debug.print_message(debug.LEVEL_INFO, msg, True) - self._paused = pause - - def set_secure_input_active(self, active: bool, reason: str = "") -> None: - """Suppresses ordinary keyboard processing while a trusted lock screen is active.""" - - if self._secure_input_active == active: - return - - self._secure_input_active = active - self._last_input_event = None - self._last_non_modifier_key_event = None - msg = f"INPUT EVENT MANAGER: Secure input active: {active}. {reason}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - def check_grabbed_bindings(self) -> None: - """Checks the grabbed key bindings.""" - - msg = f"INPUT EVENT MANAGER: {len(self._grabbed_bindings)} grabbed key bindings." - debug.print_message(debug.LEVEL_INFO, msg, True) - for grab_id, binding in self._grabbed_bindings.items(): - msg = f"INPUT EVENT MANAGER: {grab_id} for: {binding}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - def add_grabs_for_keybinding(self, binding: keybindings.KeyBinding) -> List[int]: - """Adds grabs for binding if it is enabled, returns grab IDs.""" - - if not (binding.is_enabled() and binding.is_bound()): - return [] - - if binding.has_grabs(): - tokens = ["INPUT EVENT MANAGER:", binding, "already has grabs."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - if self._device is None: - tokens = ["INPUT EVENT MANAGER: No device to add grab for", binding] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return [] - - grab_ids = [] - try: - for kd in binding.key_definitions(): - definitionKeycode = kd.keycode or binding.keycode - if self._signal_event_uses_selective_legacy_listener( - definitionKeycode, kd.modifiers - ): - continue - grab_id = self._device.add_key_grab(kd, None) - if grab_id == 0: - continue - grab_ids.append(grab_id) - self._grabbed_bindings[grab_id] = binding - except Exception: - for grab_id in grab_ids: - try: - self._device.remove_key_grab(grab_id) - except Exception as error: - msg = f"INPUT EVENT MANAGER: Could not roll back key grab {grab_id}: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - self._grabbed_bindings.pop(grab_id, None) - raise - - return grab_ids - - def remove_grabs_for_keybinding(self, binding: keybindings.KeyBinding) -> None: - """Removes grabs for binding.""" - - if self._device is None: - tokens = ["INPUT EVENT MANAGER: No device to remove grab from", binding] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return - - grab_ids = binding.get_grab_ids() - if not grab_ids: - tokens = ["INPUT EVENT MANAGER:", binding, "doesn't have grabs to remove."] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return - - for grab_id in grab_ids: - self._device.remove_key_grab(grab_id) - removed = self._grabbed_bindings.pop(grab_id, None) - if removed is None: - msg = f"INPUT EVENT MANAGER: No key binding for grab id {grab_id}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - def remove_grab_by_id(self, grab_id: int) -> None: - """Removes a grab by id.""" - - if self._device is None: - msg = f"INPUT EVENT MANAGER: No device to remove grab id {grab_id}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - self._device.remove_key_grab(grab_id) - binding = self._grabbed_bindings.pop(grab_id, None) - if binding and grab_id in binding._grab_ids: - binding._grab_ids.remove(grab_id) - if binding: - tokens = ["INPUT EVENT MANAGER: Removed grab", grab_id, "for", binding] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - def map_keysym_to_modifier(self, keysym: int) -> int: - """Maps keysym as a modifier, returns the newly-mapped modifier.""" - - if self._device is None: - msg = f"INPUT EVENT MANAGER: No device to map keysym {keysym} to modifier" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0 - - self._mapped_keysyms.append(keysym) - return self._device.map_keysym_modifier(keysym) - - def map_keycode_to_modifier(self, keycode: int) -> int: - """Maps keycode as a modifier, returns the newly-mapped modifier.""" - - if self._device is None: - msg = f"INPUT EVENT MANAGER: No device to map keycode {keycode} to modifier" - debug.print_message(debug.LEVEL_INFO, msg, True) - return 0 - - self._mapped_keycodes.append(keycode) - return self._device.map_modifier(keycode) - - def unmap_all_modifiers(self) -> None: - """Unmaps all previously mapped modifiers.""" - - if self._device is None: - msg = "INPUT EVENT MANAGER: No device to unmap all modifiers from" - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - for keycode in self._mapped_keycodes: - self._device.unmap_modifier(keycode) - - for keysym in self._mapped_keysyms: - self._device.unmap_keysym_modifier(keysym) - - self._mapped_keycodes.clear() - self._mapped_keysyms.clear() - - def add_grab_for_modifier(self, modifier: str, keysym: int, keycode: int) -> int: - """Adds grab for modifier, returns grab id.""" - - if self._device is None: - msg = f"INPUT EVENT MANAGER: No device to add grab for {modifier}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1 - - kd = Atspi.KeyDefinition() - kd.keysym = keysym - kd.keycode = keycode - kd.modifiers = 0 - grab_id = self._device.add_key_grab(kd) - - msg = f"INPUT EVENT MANAGER: Grab id for {modifier}: {grab_id}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return grab_id - - def remove_grab_for_modifier(self, modifier: str, grab_id: int) -> None: - """Removes grab for modifier.""" - - if self._device is None: - msg = f"INPUT EVENT MANAGER: No device to remove grab from {modifier}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - self._device.remove_key_grab(grab_id) - msg = f"INPUT EVENT MANAGER: Grab id removed for {modifier}: {grab_id}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - def grab_keyboard(self, reason: str = "") -> None: - """Grabs the keyboard, e.g. when entering learn mode.""" - - msg = "INPUT EVENT MANAGER: Grabbing keyboard" - if reason: - msg += f" Reason: {reason}" - debug.print_message(debug.LEVEL_INFO, msg, True) - Atspi.Device.grab_keyboard(self._device) - - def ungrab_keyboard(self, reason: str = "") -> None: - """Removes keyboard grab, e.g. when exiting learn mode.""" - - msg = "INPUT EVENT MANAGER: Ungrabbing keyboard" - if reason: - msg += f" Reason: {reason}" - debug.print_message(debug.LEVEL_INFO, msg, True) - Atspi.Device.ungrab_keyboard(self._device) - - def process_braille_event(self, event: Atspi.Event) -> bool: - """Processes this Braille event.""" - - braille_event = input_event.BrailleEvent(event) - result = braille_event.process() - self._last_input_event = braille_event - self._last_non_modifier_key_event = None - return result - - def process_mouse_button_event(self, event: Atspi.Event) -> None: - """Processes this Mouse event.""" - - mouse_event = input_event.MouseButtonEvent(event) - mouse_event.set_click_count(self._determine_mouse_event_click_count(mouse_event)) - self._last_input_event = mouse_event - - def process_remote_controller_event(self, event: input_event.RemoteControllerEvent) -> None: - """Processes this RemoteController event.""" - - # TODO - JD: It probably makes sense to process remote controller events here rather - # than just updating state. - self._last_input_event = event - self._last_non_modifier_key_event = None - - @staticmethod - def _get_top_level_window(obj: Optional[Atspi.Accessible]) -> Optional[Atspi.Accessible]: - """Returns the top-level window containing obj, if one can be found.""" - - if obj is None: - return None - - if AXUtilities.is_frame(obj) or AXUtilities.is_window(obj) or AXUtilities.is_dialog_or_alert(obj): - return obj - - return AXObject.find_ancestor( - obj, - lambda x: AXUtilities.is_frame(x) - or AXUtilities.is_window(x) - or AXUtilities.is_dialog_or_alert(x), - ) - - def _get_wnck(self): - """Returns Wnck when available for X11 active-window checks.""" - - if not self._did_attempt_wnck_load: - self._did_attempt_wnck_load = True - try: - self._wnck = load_wnck() - except Exception as error: - msg = f"INPUT EVENT MANAGER: Wnck unavailable for active-window check: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - self._wnck = None - - return self._wnck - - def _get_active_x11_window(self, ewmhWindowId: Optional[int] = None) -> Optional[Any]: - """Returns the EWMH active X11 window, using Wnck for its metadata.""" - - wnck = self._get_wnck() - if wnck is None: - return None - - try: - screen = wnck.Screen.get_default() - if screen is None: - return None - self._ensure_xterm_focus_monitor(screen) - screen.force_update() - windowId = ewmhWindowId - if windowId is None: - windowId = self._get_ewmh_active_x11_window_id() - if windowId is not None: - window = wnck.Window.get(windowId) - if window is None: - tokens = [ - "INPUT EVENT MANAGER: Wnck has no window for EWMH active X11 id", - hex(windowId), - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return window - return screen.get_active_window() - except Exception as error: - msg = f"INPUT EVENT MANAGER: Could not obtain active X11 window: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - - def _get_ewmh_active_x11_window_id(self) -> Optional[int]: - """Returns _NET_ACTIVE_WINDOW from the X11 root window when available.""" - - if not self._ensure_x11_display(): - return None - - try: - propertyData = self._x11Root.get_full_property( - self._netActiveWindowAtom, - self._x11AnyPropertyType, - ) - if propertyData is None or not propertyData.value: - return None - windowId = int(propertyData.value[0]) - return windowId if windowId > 0 else None - except Exception as error: - msg = f"INPUT EVENT MANAGER: Could not read EWMH active window: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - self._close_x11_display() - self._didAttemptX11Display = False - return None - - def _ensure_x11_display(self) -> bool: - """Initializes the optional exact-X11 metadata connection.""" - - if self._x11Display is not None: - return True - - if not self._didAttemptX11Display: - self._didAttemptX11Display = True - try: - from Xlib import X # pylint: disable=import-outside-toplevel - from Xlib import display as xDisplay # pylint: disable=import-outside-toplevel - - self._x11Display = xDisplay.Display() - self._x11Root = self._x11Display.screen().root - self._netActiveWindowAtom = self._x11Display.intern_atom("_NET_ACTIVE_WINDOW") - self._x11AnyPropertyType = X.AnyPropertyType - except Exception as error: - msg = f"INPUT EVENT MANAGER: EWMH active-window lookup unavailable: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - self._close_x11_display() - - return ( - self._x11Display is not None - and self._x11Root is not None - and self._netActiveWindowAtom is not None - ) - - def _close_x11_display(self) -> None: - """Closes the optional X11 display used for EWMH focus lookup.""" - - x11Display = self._x11Display - self._x11Display = None - self._x11Root = None - self._netActiveWindowAtom = None - self._x11AnyPropertyType = None - self._lastEwmhReadWindowId = None - self._lastEwmhActiveWindowId = None - self._lastEwmhXtermMatch = None - if x11Display is None: - return - - try: - x11Display.close() - except Exception as error: - msg = f"INPUT EVENT MANAGER: Could not close EWMH display: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - def _get_active_x11_window_pid(self) -> int: - """Returns the PID of the active X11 window if Wnck can provide it.""" - - window = self._get_active_x11_window() - if window is None: - return -1 - - try: - return int(window.get_pid()) - except Exception as error: - msg = f"INPUT EVENT MANAGER: Could not obtain active X11 window PID: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return -1 - - @staticmethod - def _identifier_is_xterm(value: Any) -> bool: - """Returns True if value identifies XTerm.""" - - if not isinstance(value, str): - return False - - identifier = os.path.basename(value.strip().lower()) - return identifier == "xterm" - - @staticmethod - def _safe_call(window: Any, attrName: str) -> Optional[Any]: - """Returns attrName() for window, or None when unavailable.""" - - attr = getattr(window, attrName, None) - if not callable(attr): - return None - - try: - return attr() - except Exception: - return None - - def _log_active_x11_window_for_xterm_check(self, window: Any) -> None: - """Logs X11 window details used for XTerm pass-through decisions.""" - - classGroup = self._safe_call(window, "get_class_group") - classGroupName = None - classGroupResClass = None - if classGroup is not None: - classGroupName = self._safe_call(classGroup, "get_name") - classGroupResClass = self._safe_call(classGroup, "get_res_class") - - tokens = [ - "INPUT EVENT MANAGER: Active X11 window for XTerm check:", - "name", - self._safe_call(window, "get_name"), - "class group", - self._safe_call(window, "get_class_group_name") or classGroupName, - "class group res class", - classGroupResClass, - "class instance", - self._safe_call(window, "get_class_instance_name"), - "pid", - self._safe_call(window, "get_pid"), - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - def _stop_xterm_focus_monitor(self) -> None: - """Stops monitoring X11 focus changes used for XTerm grab recovery.""" - - screen = self._xtermFocusScreen - handlerId = self._xtermFocusHandlerId - self._xtermFocusScreen = None - self._xtermFocusHandlerId = 0 - if screen is None or not handlerId: - return - - try: - screen.disconnect(handlerId) - except Exception as error: - msg = f"INPUT EVENT MANAGER: Could not stop XTerm focus monitor: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - def _ensure_xterm_focus_monitor(self, screen: Any) -> None: - """Monitors X11 focus so suspended grabs recover without another key event.""" - - if screen is self._xtermFocusScreen and self._xtermFocusHandlerId: - return - - self._stop_xterm_focus_monitor() - try: - handlerId = screen.connect( - "active-window-changed", - self._on_active_x11_window_changed, - ) - except Exception as error: - msg = f"INPUT EVENT MANAGER: Could not start XTerm focus monitor: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - self._xtermFocusScreen = screen - self._xtermFocusHandlerId = handlerId - - def _initialize_xterm_handoff(self) -> None: - """Initializes X11 focus monitoring and suspends immediately for XTerm.""" - - match = self._active_x11_window_xterm_match() - tokens = ["INPUT EVENT MANAGER: Initial XTerm handoff matcher returned", match] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if match is True: - self._suspend_key_grabs_for_xterm() - self._ensure_xterm_recovery_timer() - - def _stop_xterm_recovery_timer(self) -> None: - """Stops the fallback timer used to recover XTerm-suspended grabs.""" - - sourceId = self._xtermRecoverySourceId - self._xtermRecoverySourceId = 0 - if not sourceId: - return - - try: - GLib.source_remove(sourceId) - except GLib.GError as error: - msg = f"INPUT EVENT MANAGER: Could not stop XTerm recovery timer: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - - def _ensure_xterm_recovery_timer(self) -> None: - """Starts generic X11 polling when focus notifications are insufficient.""" - - if self._device is None or self._xtermRecoverySourceId: - return - - self._xtermRecoverySourceId = GLib.timeout_add( - 100, - self._poll_xterm_grab_recovery, - ) - - def _xterm_recovery_source_is_present(self) -> bool: - """Returns whether GLib still owns the recorded recovery source.""" - - if not self._xtermRecoverySourceId: - return False - - try: - context = GLib.MainContext.default() - return context.find_source_by_id(self._xtermRecoverySourceId) is not None - except Exception: - return False - - def _poll_xterm_grab_recovery(self) -> bool: - """Updates XTerm handoff state from the authoritative EWMH active window.""" - - self._xtermRecoveryPollCount += 1 - if self._device is None: - self._xtermRecoverySourceId = 0 - return False - - try: - match = self._active_x11_window_xterm_match() - if match is True: - self._suspend_key_grabs_for_xterm() - elif match is False: - self._restore_key_grabs_after_xterm() - except Exception as error: - msg = f"INPUT EVENT MANAGER: XTerm recovery poll failed: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - def _record_xterm_handoff_action(self, action: str) -> None: - """Retains a short history of XTerm focus and grab-state transitions.""" - - if self._xtermHandoffHistory and self._xtermHandoffHistory[-1] == action: - return - - self._xtermHandoffHistory.append(action) - self._xtermHandoffHistory = self._xtermHandoffHistory[-12:] - - def _on_active_x11_window_changed(self, screen: Any, _previousWindow: Any) -> None: - """Updates grab suspension as soon as X11 focus changes.""" - - del screen - match = self._active_x11_window_xterm_match() - tokens = ["INPUT EVENT MANAGER: XTerm focus-change matcher returned", match] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if match is True: - self._suspend_key_grabs_for_xterm() - elif match is False: - self._restore_key_grabs_after_xterm() - elif self._scriptWithSuspendedGrabsForXterm is not None: - self._ensure_xterm_recovery_timer() - - def _active_x11_window_xterm_match(self) -> Optional[bool]: - """Returns whether the active X11 window is XTerm, or None when unknown.""" - - snapshot = cthulhu_state.compositorSnapshot - usingI3Context = snapshot is not None and snapshot.backend_name == "i3-ipc" - if usingI3Context and self._lastEwmhXtermMatch is True: - adapter = self._compositorStateAdapter - refreshContext = getattr(adapter, "refresh_workspace_context", None) - if callable(refreshContext): - snapshot = refreshContext("xterm-handoff-check") - usingI3Context = snapshot is not None and snapshot.backend_name == "i3-ipc" - if usingI3Context and snapshot.focused_workspace_empty is True: - self._record_xterm_handoff_action("i3:confirmed-empty-workspace") - self._lastEwmhReadWindowId = None - self._lastEwmhActiveWindowId = None - self._lastEwmhXtermMatch = False - return False - - if usingI3Context and snapshot.focused_window_id is not None: - windowId = snapshot.focused_window_id - else: - windowId = self._get_ewmh_active_x11_window_id() - - previousWindowId = self._lastEwmhReadWindowId - if windowId != previousWindowId: - previousText = hex(previousWindowId) if previousWindowId is not None else "unknown" - currentText = hex(windowId) if windowId is not None else "unknown" - self._record_xterm_handoff_action(f"ewmh:{previousText}->{currentText}") - self._lastEwmhReadWindowId = windowId - if ( - windowId is not None - and windowId == self._lastEwmhActiveWindowId - and self._lastEwmhXtermMatch is not None - ): - return self._lastEwmhXtermMatch - - if windowId is None: - return None - - match = self._x11_window_id_xterm_match(windowId) - if windowId is not None and match is not None: - self._lastEwmhActiveWindowId = windowId - self._lastEwmhXtermMatch = match - return match - - def _x11_window_xterm_match(self, window: Any) -> Optional[bool]: - """Returns whether window is XTerm, or None when it cannot be identified.""" - - if window is None: - msg = "INPUT EVENT MANAGER: XTerm matcher cannot identify active X11 window." - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - - self._log_active_x11_window_for_xterm_check(window) - sawIdentifier = False - for attrName in ("get_class_group_name", "get_class_instance_name", "get_name"): - value = self._safe_call(window, attrName) - if self._identifier_is_xterm(value): - return True - if isinstance(value, str) and value.strip(): - sawIdentifier = True - - classGroup = self._safe_call(window, "get_class_group") - if classGroup is not None: - - for attrName in ("get_name", "get_res_class"): - value = self._safe_call(classGroup, attrName) - if self._identifier_is_xterm(value): - return True - if isinstance(value, str) and value.strip(): - sawIdentifier = True - - try: - pid = int(window.get_pid()) - except Exception: - pid = -1 - if pid < 1: - if not sawIdentifier: - msg = ( - "INPUT EVENT MANAGER: XTerm matcher cannot identify active X11 window; " - "no usable identifiers or pid." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - return False - - try: - with open(f"/proc/{pid}/cmdline", "rb") as cmdlineFile: - executable = cmdlineFile.read().split(b"\0", 1)[0].decode(errors="ignore") - except OSError: - if not sawIdentifier: - msg = ( - "INPUT EVENT MANAGER: XTerm matcher cannot identify active X11 window; " - "pid disappeared before cmdline lookup." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - return False - - return self._identifier_is_xterm(executable) - - def _get_x11_window_metadata( - self, - windowId: int, - ) -> Optional[Tuple[List[str], int]]: - """Returns identifiers and pid directly from the exact X11 window id.""" - - if not self._ensure_x11_display(): - return None - - try: - window = self._x11Display.create_resource_object("window", windowId) - identifiers = [ - value - for value in (window.get_wm_class() or ()) - if isinstance(value, str) and value.strip() - ] - - name = window.get_wm_name() - if isinstance(name, str) and name.strip(): - identifiers.append(name) - - netWmNameAtom = self._x11Display.intern_atom("_NET_WM_NAME") - utf8StringAtom = self._x11Display.intern_atom("UTF8_STRING") - nameProperty = window.get_full_property(netWmNameAtom, utf8StringAtom) - if nameProperty is not None and nameProperty.value: - value = nameProperty.value - if isinstance(value, bytes): - value = value.decode(errors="ignore") - if isinstance(value, str) and value.strip(): - identifiers.append(value) - - netWmPidAtom = self._x11Display.intern_atom("_NET_WM_PID") - pidProperty = window.get_full_property( - netWmPidAtom, - self._x11AnyPropertyType, - ) - pid = -1 - if pidProperty is not None and pidProperty.value: - pid = int(pidProperty.value[0]) - except Exception as error: - msg = ( - "INPUT EVENT MANAGER: Could not read metadata for X11 window " - f"{hex(windowId)}: {error}" - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - return None - - return identifiers, pid - - def _x11_window_id_xterm_match(self, windowId: int) -> Optional[bool]: - """Returns whether the exact EWMH X11 window id identifies XTerm.""" - - metadata = self._get_x11_window_metadata(windowId) - if metadata is None: - return None - - identifiers, pid = metadata - if any(self._identifier_is_xterm(value) for value in identifiers): - return True - - if pid > 0: - try: - with open(f"/proc/{pid}/cmdline", "rb") as cmdlineFile: - executable = cmdlineFile.read().split(b"\0", 1)[0].decode(errors="ignore") - if self._identifier_is_xterm(executable): - return True - except OSError: - pass - - if identifiers or pid > 0: - return False - - return None - - def _active_x11_window_is_xterm(self) -> bool: - """Returns True when the active X11 window appears to be XTerm.""" - - return self._active_x11_window_xterm_match() is True - - def should_suppress_atspi_events_for_xterm(self, refresh: bool = False) -> bool: - """Returns True while the XTerm handoff should suppress AT-SPI events.""" - - suspendedScript = self._scriptWithSuspendedGrabsForXterm - if suspendedScript is None: - return False - - if not refresh: - return True - - match = self._active_x11_window_xterm_match() - tokens = ["INPUT EVENT MANAGER: XTerm AT-SPI suppression matcher returned", match] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if match is False: - self._restore_key_grabs_after_xterm() - return False - - return True - - def _find_active_x11_atspi_window(self) -> Optional[Atspi.Accessible]: - """Returns the focused AT-SPI window for the active X11 PID, if possible.""" - - x11Pid = self._get_active_x11_window_pid() - if x11Pid < 1: - return None - - app = AXUtilitiesApplication.get_application_with_pid(x11Pid) - if app is None: - return None - - candidates = [ - child for child in AXObject.iter_children(app) - if AXUtilities.is_frame(child) - or AXUtilities.is_window(child) - or AXUtilities.is_dialog_or_alert(child) - ] - if not candidates: - tokens = ["INPUT EVENT MANAGER: No AT-SPI windows found for active X11 pid", x11Pid] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - focusedCandidates = [] - for window in candidates: - if AXUtilities.is_focused(window) or AXUtilities.get_focused_object(window) is not None: - focusedCandidates.append(window) - - if len(focusedCandidates) == 1: - tokens = [ - "INPUT EVENT MANAGER: Recovered active AT-SPI window from X11 pid", - x11Pid, - focusedCandidates[0], - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return focusedCandidates[0] - - if focusedCandidates: - tokens = [ - "INPUT EVENT MANAGER: Multiple focused AT-SPI windows for active X11 pid", - x11Pid, - focusedCandidates, - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return focusedCandidates[0] - - tokens = [ - "INPUT EVENT MANAGER: Active X11 pid", - x11Pid, - "has AT-SPI windows but none report focus", - candidates, - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return None - - def _active_x11_window_differs_from(self, obj: Optional[Atspi.Accessible]) -> bool: - """Returns True when X11 focus is known to be outside the AT-SPI context.""" - - if obj is None: - return False - - x11Pid = self._get_active_x11_window_pid() - if x11Pid < 1: - return False - - axPid = AXObject.get_process_id(obj) - if axPid < 1: - return False - - result = x11Pid != axPid - if result: - tokens = [ - "INPUT EVENT MANAGER: Active X11 window PID", - x11Pid, - "differs from AT-SPI active window PID", - axPid, - "for", - obj, - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - - return result - - def _clear_stale_atspi_context(self, manager: Any) -> None: - """Clears cached input context after X11 positively contradicts AT-SPI.""" - - reason = "active X11 window not found in AT-SPI" - msg = ( - "INPUT EVENT MANAGER: Clearing stale AT-SPI focus context; " - "X11 focus moved to an untracked window." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - script_manager.get_manager().set_active_script(None, reason) - manager.clear_state(reason) - self._last_input_event = None - self._last_non_modifier_key_event = None - - @staticmethod - def _get_active_script_app() -> Optional[Atspi.Accessible]: - """Returns the app for the active script, if one is available.""" - - script = script_manager.get_manager().get_active_script() - if script is None: - return None - - return getattr(script, "app", None) - - @staticmethod - def _lacks_atspi_context( - window: Optional[Atspi.Accessible], - focus: Optional[Atspi.Accessible], - pendingFocus: Optional[Atspi.Accessible], - ) -> bool: - """Returns True when Cthulhu has no meaningful AT-SPI input context.""" - - if window is not None or focus is not None or pendingFocus is not None: - return False - - return True - - def _should_pass_through_for_active_xterm( - self, - window: Optional[Atspi.Accessible], - focus: Optional[Atspi.Accessible], - pendingFocus: Optional[Atspi.Accessible], - ) -> bool: - """Returns True when XTerm is active and Cthulhu lacks matching AT-SPI context.""" - - match = self._active_x11_window_xterm_match() - tokens = ["INPUT EVENT MANAGER: XTerm matcher returned", match] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - if match is True: - return True - if pendingFocus is not None: - msg = "INPUT EVENT MANAGER: XTerm matcher false; pending focus exists." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - if match is None and self._scriptWithSuspendedGrabsForXterm is not None: - msg = ( - "INPUT EVENT MANAGER: Keeping XTerm key-grab suspension; " - "active X11 window is temporarily unknown." - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def _suspend_key_grabs_for_xterm(self) -> None: - """Suspends active-script key grabs so XTerm/Fenrir can receive them.""" - - script = script_manager.get_manager().get_active_script() - if script is None: - self._record_xterm_handoff_action("suspend:skipped-no-active-script") - return - - if script is self._scriptWithSuspendedGrabsForXterm: - grabIds = getattr(script, "grab_ids", []) - scriptGrabCount = len(grabIds) if isinstance(grabIds, list) else -1 - self._record_xterm_handoff_action( - f"suspend:already-marked:script-grabs={scriptGrabCount}:" - f"all-grabs={len(self._grabbed_bindings)}" - ) - return - - if self._scriptWithSuspendedGrabsForXterm is not None: - self._restore_key_grabs_after_xterm() - - removeGrabs = getattr(script, "removeKeyGrabs", None) - if not callable(removeGrabs): - return - - tokens = [ - "INPUT EVENT MANAGER: Removing active script key grabs while XTerm is focused:", - script, - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - removeGrabs() - self._scriptWithSuspendedGrabsForXterm = script - self._record_xterm_handoff_action( - f"suspend:success:all-grabs={len(self._grabbed_bindings)}" - ) - self._ensure_xterm_recovery_timer() - - def _restore_key_grabs_after_xterm(self) -> None: - """Restores key grabs after leaving XTerm.""" - - script = self._scriptWithSuspendedGrabsForXterm - if script is None: - return - - activeScript = script_manager.get_manager().get_active_script() - if script is not activeScript: - self._record_xterm_handoff_action("restore:dropped-active-script-changed") - tokens = [ - "INPUT EVENT MANAGER: Not restoring XTerm-suspended key grabs; active script changed:", - script, - activeScript, - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - self._scriptWithSuspendedGrabsForXterm = None - return - - addGrabs = getattr(script, "addKeyGrabs", None) - if not callable(addGrabs): - return - - tokens = [ - "INPUT EVENT MANAGER: Restoring active script key grabs after leaving XTerm:", - script, - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - try: - addGrabs() - except Exception as error: - self._record_xterm_handoff_action(f"restore:failed:{type(error).__name__}") - msg = f"INPUT EVENT MANAGER: Could not restore XTerm-suspended key grabs: {error}" - debug.print_message(debug.LEVEL_INFO, msg, True) - removeGrabs = getattr(script, "removeKeyGrabs", None) - if callable(removeGrabs): - try: - removeGrabs() - except Exception as rollbackError: - msg = ( - "INPUT EVENT MANAGER: Could not roll back partial XTerm grab " - f"restoration: {rollbackError}" - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - self._scriptWithSuspendedGrabsForXterm = None - return - self._ensure_xterm_recovery_timer() - return - - self._scriptWithSuspendedGrabsForXterm = None - self._record_xterm_handoff_action( - f"restore:success:all-grabs={len(self._grabbed_bindings)}" - ) - - # pylint: disable=too-many-arguments - # pylint: disable=too-many-positional-arguments - def _register_selective_legacy_key_listener(self) -> bool: - """Registers the consumable X11 listener directly through libatspi.""" - - self._selective_legacy_listener = Atspi.DeviceListener.new( - self._process_selective_legacy_keyboard_event, - None, - ) - if self._selective_legacy_listener is None: - msg = "INPUT EVENT MANAGER: Could not create selective consumable X11 listener." - debug.print_message(debug.LEVEL_WARNING, msg, True) - self._deregister_selective_legacy_key_listener() - return False - - for modifierMask in _X11_CONSUMABLE_MODIFIER_MASKS: - try: - registered = Atspi.register_keystroke_listener( - self._selective_legacy_listener, - self._selective_legacy_key_set, - modifierMask, - _X11_CONSUMABLE_EVENT_TYPES, - _X11_CONSUMABLE_SYNC_TYPE, - ) - except GLib.GError as error: - msg = ( - "INPUT EVENT MANAGER: Could not register selective consumable " - f"X11 listener for modifier mask {modifierMask}: {error}" - ) - debug.print_message(debug.LEVEL_WARNING, msg, True) - registered = False - - if not registered: - msg = ( - "INPUT EVENT MANAGER: Selective consumable X11 listener registration " - f"failed for modifier mask {modifierMask}." - ) - debug.print_message(debug.LEVEL_WARNING, msg, True) - self._deregister_selective_legacy_key_listener() - return False - - self._selective_legacy_registered_masks.append(modifierMask) - - self._selective_legacy_listener_active = True - return True - - def _deregister_selective_legacy_key_listener(self) -> None: - """Deregisters all masks associated with the consumable X11 listener.""" - - listener = self._selective_legacy_listener - failedMasks = [] - if listener is not None: - for modifierMask in self._selective_legacy_registered_masks: - try: - deregistered = Atspi.deregister_keystroke_listener( - listener, - self._selective_legacy_key_set, - modifierMask, - _X11_CONSUMABLE_EVENT_TYPES, - ) - except GLib.GError as error: - msg = ( - "INPUT EVENT MANAGER: Could not deregister selective consumable " - f"X11 listener for modifier mask {modifierMask}: {error}" - ) - debug.print_message(debug.LEVEL_WARNING, msg, True) - deregistered = False - - if not deregistered: - failedMasks.append(modifierMask) - - self._selective_legacy_registered_masks = failedMasks - if failedMasks: - self._selective_legacy_listener_active = True - msg = ( - "INPUT EVENT MANAGER: Preserving selective consumable X11 listener " - f"for {len(failedMasks)} failed deregistration(s)." - ) - debug.print_message(debug.LEVEL_WARNING, msg, True) - return - - self._selective_legacy_listener_active = False - self._selective_legacy_listener = None - self._selective_legacy_key_set = [] - self._selective_legacy_keycodes.clear() - - def _process_selective_legacy_keyboard_event( - self, - event: Atspi.DeviceEvent, - _userData: object = None, - ) -> bool: - """Returns an X11 consume decision for unmodified browse-navigation keys.""" - - pressed = event.type == Atspi.EventType.KEY_PRESSED_EVENT - return self.process_keyboard_event( - self._device, - pressed, - event.hw_code, - event.id, - event.modifiers, - event.event_string or "", - ) - - def _signal_event_uses_selective_legacy_listener(self, keycode: int, modifiers: int) -> bool: - """Returns True if the X11 compatibility listener owns this event.""" - - return ( - self._selective_legacy_listener_active - and keycode in self._selective_legacy_keycodes - and modifiers in _X11_CONSUMABLE_MODIFIER_MASKS - ) - - def _on_key_pressed( - self, - device: Atspi.Device, - keycode: int, - keysym: int, - modifiers: int, - text: str, - ) -> None: - """Processes a key-pressed signal from AT-SPI 2.60 and later.""" - - if self._signal_event_uses_selective_legacy_listener(keycode, modifiers): - msg = "INPUT EVENT MANAGER: Deferring key-pressed signal to X11 consumable listener." - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - self.process_keyboard_event(device, True, keycode, keysym, modifiers, text) - - def _on_key_released( - self, - device: Atspi.Device, - keycode: int, - keysym: int, - modifiers: int, - text: str, - ) -> None: - """Processes a key-released signal from AT-SPI 2.60 and later.""" - - if self._signal_event_uses_selective_legacy_listener(keycode, modifiers): - msg = "INPUT EVENT MANAGER: Deferring key-released signal to X11 consumable listener." - debug.print_message(debug.LEVEL_INFO, msg, True) - return - - self.process_keyboard_event(device, False, keycode, keysym, modifiers, text) - - def process_keyboard_event( - self, - _device: Atspi.Device, - pressed: bool, - keycode: int, - keysym: int, - modifiers: int, - text: str - ) -> bool: - """Processes this Atspi keyboard event.""" - - if self._secure_input_active: - msg = "INPUT EVENT MANAGER: Ignoring keyboard event during secure screen lock." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - if self._paused: - msg = "INPUT EVENT MANAGER: Keyboard event processing is paused." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - if cthulhu_state.capturingKeys: - msg = "INPUT EVENT MANAGER: Capturing keys; ignoring keyboard event." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - event = input_event.KeyboardEvent(pressed, keycode, keysym, modifiers, text) - if event in [self._last_input_event, self._last_non_modifier_key_event]: - msg = "INPUT EVENT MANAGER: Received duplicate event." - debug.print_message(debug.LEVEL_INFO, msg, True) - return False - - manager = focus_manager.get_manager() - pendingFocus = cthulhu_state.pendingSelfHostedFocus - if pendingFocus is not None: - tokens = ["INPUT EVENT MANAGER: Using pending self-hosted focus for keyboard event:", pendingFocus] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - window = manager.get_active_window() - focus = manager.get_locus_of_focus() - if self._should_pass_through_for_active_xterm(window, focus, pendingFocus): - msg = "INPUT EVENT MANAGER: Passing through keyboard event; active XTerm is focused." - debug.print_message(debug.LEVEL_INFO, msg, True) - self._suspend_key_grabs_for_xterm() - return False - self._restore_key_grabs_after_xterm() - if pressed: - if not AXUtilities.can_be_active_window(window, clear_cache=True): - new_window = AXUtilities.find_active_window() - if new_window is None: - new_window = self._find_active_x11_atspi_window() - if new_window is not None: - window = new_window - tokens = ["INPUT EVENT MANAGER: Updating window and active window to", window] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - manager.set_active_window(window) - else: - focus_window = self._get_top_level_window(pendingFocus or manager.get_locus_of_focus()) - staleContext = focus_window or window or self._get_active_script_app() - if self._active_x11_window_differs_from(staleContext): - self._clear_stale_atspi_context(manager) - return False - - if focus_window is not None: - window = focus_window - tokens = [ - "INPUT EVENT MANAGER: Recovering active window from locus of focus:", - window, - ] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - manager.set_active_window(window) - else: - # One example: Brave's popup menus live in frames which lack the active - # state. Failing to revalidate the window on a key press is inconclusive; - # do not wipe out the last known window and focus state. - tokens = [ - "WARNING:", - window, - "cannot be confirmed as active. No alternative found; preserving existing context.", - ] - debug.print_tokens(debug.LEVEL_WARNING, tokens, True) - event.set_window(window) - event.set_object(pendingFocus or manager.get_locus_of_focus()) - event.set_script(script_manager.get_manager().get_active_script()) - elif self.last_event_was_keyboard(): - assert isinstance(self._last_input_event, input_event.KeyboardEvent) - event.set_window(self._last_input_event.get_window()) - event.set_object(self._last_input_event.get_object()) - event.set_script(self._last_input_event.get_script()) - else: - event.set_window(manager.get_active_window()) - event.set_object(pendingFocus or manager.get_locus_of_focus()) - event.set_script(script_manager.get_manager().get_active_script()) - - event._finalize_initialization() - event.set_click_count(self._determine_keyboard_event_click_count(event)) - consumed = event.process() - - if event.is_modifier_key(): - if self.is_release_for(event, self._last_input_event): - msg = "INPUT EVENT MANAGER: Clearing last non modifier key event" - debug.print_message(debug.LEVEL_INFO, msg, True) - self._last_non_modifier_key_event = None - else: - self._last_non_modifier_key_event = event - self._last_input_event = event - return consumed - - # pylint: enable=too-many-arguments - # pylint: enable=too-many-positional-arguments - - def _determine_keyboard_event_click_count(self, event: input_event.KeyboardEvent) -> int: - """Determines the click count of event.""" - - if not self.last_event_was_keyboard(): - return 1 - - if event.is_modifier_key(): - last_event = self._last_input_event - else: - last_event = self._last_non_modifier_key_event or self._last_input_event - - assert isinstance(last_event, input_event.KeyboardEvent) - if (event.time - last_event.time > settings.doubleClickTimeout) or \ - (event.keyval_name != last_event.keyval_name) or \ - (event.get_object() != last_event.get_object()): - return 1 - - last_count = last_event.get_click_count() - if not event.is_pressed_key(): - return last_count - if last_event.is_pressed_key(): - return last_count - if (event.is_modifier_key() and last_count == 2) or last_count == 3: - return 1 - return last_count + 1 - - def _determine_mouse_event_click_count(self, event: input_event.MouseButtonEvent) -> int: - """Determines the click count of event.""" - - if not self.last_event_was_mouse_button(): - return 1 - - assert isinstance(self._last_input_event, input_event.MouseButtonEvent) - if not event.pressed: - return self._last_input_event.get_click_count() - if self._last_input_event.button != event.button: - return 1 - if event.time - self._last_input_event.time > settings.doubleClickTimeout: - return 1 - - return self._last_input_event.get_click_count() + 1 - - def last_event_was_keyboard(self) -> bool: - """Returns True if the last event is a keyboard event.""" - - return isinstance(self._last_input_event, input_event.KeyboardEvent) - - def last_event_was_mouse_button(self) -> bool: - """Returns True if the last event is a mouse button event.""" - - return isinstance(self._last_input_event, input_event.MouseButtonEvent) - - def is_release_for(self, event1: Optional[input_event.InputEvent], event2: Optional[input_event.InputEvent]) -> bool: - """Returns True if event1 is a release for event2.""" - - if event1 is None or event2 is None: - return False - - if not isinstance(event1, input_event.KeyboardEvent) \ - or not isinstance(event2, input_event.KeyboardEvent): - return False - - if event1.is_pressed_key() or not event2.is_pressed_key(): - return False - - result = event1.id == event2.id \ - and event1.hw_code == event2.hw_code \ - and event1.keyval_name == event2.keyval_name - - if result and not event1.is_modifier_key(): - result = event1.modifiers == event2.modifiers - - msg = ( - f"INPUT EVENT MANAGER: {event1.as_single_line_string()} " - f"is release for {event2.as_single_line_string()}: {result}" - ) - debug.print_message(debug.LEVEL_INFO, msg, True) - return result - - def last_event_equals_or_is_release_for_event(self, event: Optional[input_event.InputEvent]) -> bool: - """Returns True if the last event equals the provided event, or is the release for it.""" - - if self._last_input_event is event: - return True - - if not self.last_event_was_keyboard(): - return False - - if self._last_non_modifier_key_event is None: - return False - - if event == self._last_non_modifier_key_event: - return True - - return self.is_release_for(self._last_non_modifier_key_event, event) - - def _last_key_and_modifiers(self) -> Tuple[str, int]: - """Returns the last keyval name and modifiers""" - - if self._last_non_modifier_key_event is None: - return "", 0 - - if not self.last_event_was_keyboard(): - return "", 0 - - if self._last_input_event is None: - return self._last_non_modifier_key_event.keyval_name, 0 - - return self._last_non_modifier_key_event.keyval_name, self._last_input_event.modifiers - - def last_event_was_command(self) -> bool: - """Returns True if the last event is believed to be a command.""" - - if bool(self._last_key_and_modifiers()[1] & 1 << Atspi.ModifierType.CONTROL): - msg = "INPUT EVENT MANAGER: Last event was command." - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - return False - - def last_event_was_shortcut_for(self, obj: Atspi.Accessible) -> bool: - """Returns True if the last event is believed to be a shortcut key for obj.""" - - string = self._last_key_and_modifiers()[0] - if not string: - return False - - rv = False - keys = AXObject.get_action_key_binding(obj, 0).split(";") - for key in keys: - if key.endswith(string.upper()): - rv = True - break - - if rv: - tokens = ["INPUT EVENT MANAGER: Last event was shortcut for", obj] - debug.print_tokens(debug.LEVEL_INFO, tokens, True) - return rv - - def last_event_was_printable_key(self) -> bool: - """Returns True if the last event is believed to be a printable key.""" - - if not self.last_event_was_keyboard(): - return False - - assert isinstance(self._last_input_event, input_event.KeyboardEvent) - if self._last_input_event.is_printable_key(): - msg = "INPUT EVENT MANAGER: Last event was printable key" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - - return False - - def last_event_was_caret_navigation(self) -> bool: - """Returns True if the last event is believed to be caret navigation.""" - - return self.last_event_was_character_navigation() \ - or self.last_event_was_word_navigation() \ - or self.last_event_was_line_navigation() \ - or self.last_event_was_line_boundary_navigation() \ - or self.last_event_was_file_boundary_navigation() \ - or self.last_event_was_page_navigation() - - def last_event_was_caret_selection(self) -> bool: - """Returns True if the last event is believed to be caret selection.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Home", "End", "Up", "Down", "Left", "Right"]: - rv = False - else: - rv = bool(mods & 1 << Atspi.ModifierType.SHIFT) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was caret selection" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_backward_caret_navigation(self) -> bool: - """Returns True if the last event is believed to be backward caret navigation.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Up", "Left"]: - rv = False - else: - rv = not mods & 1 << Atspi.ModifierType.SHIFT - - if rv: - msg = "INPUT EVENT MANAGER: Last event was backward caret navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_forward_caret_navigation(self) -> bool: - """Returns True if the last event is believed to be forward caret navigation.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Down", "Right"]: - rv = False - else: - rv = not mods & 1 << Atspi.ModifierType.SHIFT - - if rv: - msg = "INPUT EVENT MANAGER: Last event was forward caret navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_forward_caret_selection(self) -> bool: - """Returns True if the last event is believed to be forward caret selection.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Down", "Right"]: - rv = False - else: - rv = bool(mods & 1 << Atspi.ModifierType.SHIFT) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was forward caret selection" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_character_navigation(self) -> bool: - """Returns True if the last event is believed to be character navigation.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Left", "Right"]: - rv = False - elif mods & 1 << Atspi.ModifierType.CONTROL or mods & 1 << Atspi.ModifierType.ALT: - rv = False - else: - rv = True - - if rv: - msg = "INPUT EVENT MANAGER: Last event was character navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_word_navigation(self) -> bool: - """Returns True if the last event is believed to be word navigation.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Left", "Right"]: - rv = False - else: - rv = bool(mods & 1 << Atspi.ModifierType.CONTROL) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was word navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_previous_word_navigation(self) -> bool: - """Returns True if the last event is believed to be previous-word navigation.""" - - string, mods = self._last_key_and_modifiers() - if string != "Left": - rv = False - else: - rv = bool(mods & 1 << Atspi.ModifierType.CONTROL) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was previous-word navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_next_word_navigation(self) -> bool: - """Returns True if the last event is believed to be next-word navigation.""" - - string, mods = self._last_key_and_modifiers() - if string != "Right": - rv = False - else: - rv = bool(mods & 1 << Atspi.ModifierType.CONTROL) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was next-word navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_line_navigation(self) -> bool: - """Returns True if the last event is believed to be line navigation.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Up", "Down"]: - rv = False - elif mods & 1 << Atspi.ModifierType.CONTROL: - rv = False - else: - focus = focus_manager.get_manager().get_locus_of_focus() - if AXUtilities.is_single_line(focus): - rv = False - else: - rv = not AXUtilities.is_widget_controlled_by_line_navigation(focus) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was line navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_paragraph_navigation(self) -> bool: - """Returns True if the last event is believed to be paragraph navigation.""" - - string, mods = self._last_key_and_modifiers() - if not (string in ["Up", "Down"] and mods & 1 << Atspi.ModifierType.CONTROL): - rv = False - else: - rv = not mods & 1 << Atspi.ModifierType.SHIFT - - if rv: - msg = "INPUT EVENT MANAGER: Last event was paragraph navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_line_boundary_navigation(self) -> bool: - """Returns True if the last event is believed to be navigation to start/end of line.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Home", "End"]: - rv = False - else: - rv = not mods & 1 << Atspi.ModifierType.CONTROL - - if rv: - msg = "INPUT EVENT MANAGER: Last event was line boundary navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_file_boundary_navigation(self) -> bool: - """Returns True if the last event is believed to be navigation to top/bottom of file.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Home", "End"]: - rv = False - else: - rv = bool(mods & 1 << Atspi.ModifierType.CONTROL) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was file boundary navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_page_navigation(self) -> bool: - """Returns True if the last event is believed to be page navigation.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Page_Up", "Page_Down"]: - rv = False - elif mods & 1 << Atspi.ModifierType.CONTROL: - rv = False - else: - focus = focus_manager.get_manager().get_locus_of_focus() - if AXUtilities.is_single_line(focus): - rv = False - else: - rv = not AXUtilities.is_widget_controlled_by_line_navigation(focus) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was page navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_page_switch(self) -> bool: - """Returns True if the last event is believed to be a page switch.""" - - string, mods = self._last_key_and_modifiers() - if string.isnumeric(): - rv = bool(mods & 1 << Atspi.ModifierType.ALT) - elif string in ["Page_Up", "Page_Down"]: - rv = bool(mods & 1 << Atspi.ModifierType.CONTROL) - else: - rv = False - - if rv: - msg = "INPUT EVENT MANAGER: Last event was page switch" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_tab_navigation(self) -> bool: - """Returns True if the last event is believed to be Tab navigation.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Tab", "ISO_Left_Tab"]: - rv = False - elif mods & 1 << Atspi.ModifierType.CONTROL or mods & 1 << Atspi.ModifierType.ALT: - rv = False - else: - rv = True - - if rv: - msg = "INPUT EVENT MANAGER: Last event was Tab navigation" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_table_sort(self) -> bool: - """Returns True if the last event is believed to be a table sort.""" - - focus = focus_manager.get_manager().get_locus_of_focus() - if not AXUtilities.is_table_header(focus): - rv = False - elif self.last_event_was_mouse_button(): - rv = self.last_event_was_primary_click() - elif self.last_event_was_keyboard(): - rv = self.last_event_was_return_or_space() - else: - rv = False - - if rv: - msg = "INPUT EVENT MANAGER: Last event was table sort" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_unmodified_arrow(self) -> bool: - """Returns True if the last event is an unmodified arrow.""" - - string, mods = self._last_key_and_modifiers() - if string not in ["Left", "Right", "Up", "Down"]: - return False - - if mods & 1 << Atspi.ModifierType.CONTROL \ - or mods & 1 << Atspi.ModifierType.SHIFT \ - or mods & 1 << Atspi.ModifierType.ALT: - return False - - # TODO: JD - 8 is the value of keybindings.MODIFIER_ORCA, but we need to - # avoid a circular import. - if mods & 1 << 8: - return False - - return True - - def last_event_was_alt_modified(self) -> bool: - """Returns True if the last event was alt-modified.""" - - mods = self._last_key_and_modifiers()[-1] - return bool(mods & 1 << Atspi.ModifierType.ALT) - - def last_event_was_backspace(self) -> bool: - """Returns True if the last event is BackSpace.""" - - return self._last_key_and_modifiers()[0] == "BackSpace" - - def last_event_was_down(self) -> bool: - """Returns True if the last event is Down.""" - - return self._last_key_and_modifiers()[0] == "Down" - - def last_event_was_f1(self) -> bool: - """Returns True if the last event is F1.""" - - return self._last_key_and_modifiers()[0] == "F1" - - def last_event_was_left(self) -> bool: - """Returns True if the last event is Left.""" - - return self._last_key_and_modifiers()[0] == "Left" - - def last_event_was_left_or_right(self) -> bool: - """Returns True if the last event is Left or Right.""" - - return self._last_key_and_modifiers()[0] in ["Left", "Right"] - - def last_event_was_page_up_or_page_down(self) -> bool: - """Returns True if the last event is Page_Up or Page_Down.""" - - return self._last_key_and_modifiers()[0] in ["Page_Up", "Page_Down"] - - def last_event_was_right(self) -> bool: - """Returns True if the last event is Right.""" - - return self._last_key_and_modifiers()[0] == "Right" - - def last_event_was_return(self) -> bool: - """Returns True if the last event is Return.""" - - return self._last_key_and_modifiers()[0] == "Return" - - def last_event_was_return_or_space(self) -> bool: - """Returns True if the last event is Return or space.""" - - return self._last_key_and_modifiers()[0] in ["Return", "space", " "] - - def last_event_was_return_tab_or_space(self) -> bool: - """Returns True if the last event is Return, Tab, or space.""" - - return self._last_key_and_modifiers()[0] in ["Return", "Tab", "space", " "] - - def last_event_was_space(self) -> bool: - """Returns True if the last event is space.""" - - return self._last_key_and_modifiers()[0] in [" ", "space"] - - def last_event_was_tab(self) -> bool: - """Returns True if the last event is Tab.""" - - return self._last_key_and_modifiers()[0] == "Tab" - - def last_event_was_up(self) -> bool: - """Returns True if the last event is Up.""" - - return self._last_key_and_modifiers()[0] == "Up" - - def last_event_was_up_or_down(self) -> bool: - """Returns True if the last event is Up or Down.""" - - return self._last_key_and_modifiers()[0] in ["Up", "Down"] - - def last_event_was_delete(self) -> bool: - """Returns True if the last event is believed to be delete.""" - - string, mods = self._last_key_and_modifiers() - if string in ["Delete", "KP_Delete"]: - rv = True - elif string.lower() == "d": - rv = bool(mods & 1 << Atspi.ModifierType.CONTROL) - else: - rv = False - - if rv: - msg = "INPUT EVENT MANAGER: Last event was delete" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_cut(self) -> bool: - """Returns True if the last event is believed to be the cut command.""" - - string, mods = self._last_key_and_modifiers() - if string.lower() != "x": - return False - - if mods & 1 << Atspi.ModifierType.CONTROL and not mods & 1 << Atspi.ModifierType.SHIFT: - msg = "INPUT EVENT MANAGER: Last event was cut" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def last_event_was_copy(self) -> bool: - """Returns True if the last event is believed to be the copy command.""" - - string, mods = self._last_key_and_modifiers() - if string.lower() != "c" or not mods & 1 << Atspi.ModifierType.CONTROL: - rv = False - elif AXUtilities.is_terminal(self._last_input_event.get_object()): - rv = bool(mods & 1 << Atspi.ModifierType.SHIFT) - else: - rv = not bool(mods & 1 << Atspi.ModifierType.SHIFT) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was copy" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_paste(self) -> bool: - """Returns True if the last event is believed to be the paste command.""" - - string, mods = self._last_key_and_modifiers() - if string.lower() != "v" or not mods & 1 << Atspi.ModifierType.CONTROL: - rv = False - elif AXUtilities.is_terminal(self._last_input_event.get_object()): - rv = bool(mods & 1 << Atspi.ModifierType.SHIFT) - else: - rv = not bool(mods & 1 << Atspi.ModifierType.SHIFT) - - if rv: - msg = "INPUT EVENT MANAGER: Last event was paste" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_undo(self) -> bool: - """Returns True if the last event is believed to be the undo command.""" - - string, mods = self._last_key_and_modifiers() - if string.lower() != "z": - return False - if mods & 1 << Atspi.ModifierType.CONTROL and not mods & 1 << Atspi.ModifierType.SHIFT: - msg = "INPUT EVENT MANAGER: Last event was undo" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def last_event_was_redo(self) -> bool: - """Returns True if the last event is believed to be the redo command.""" - - string, mods = self._last_key_and_modifiers() - if string.lower() == "z": - rv = bool(mods & 1 << Atspi.ModifierType.CONTROL and mods & 1 << Atspi.ModifierType.SHIFT) - elif string.lower() == "y": - # LibreOffice - rv = bool(mods & 1 << Atspi.ModifierType.CONTROL \ - and not mods & 1 << Atspi.ModifierType.SHIFT) - else: - rv = False - - if rv: - msg = "INPUT EVENT MANAGER: Last event was redo" - debug.print_message(debug.LEVEL_INFO, msg, True) - return rv - - def last_event_was_select_all(self) -> bool: - """Returns True if the last event is believed to be the select all command.""" - - string, mods = self._last_key_and_modifiers() - if string.lower() != "a": - return False - - if (mods & 1 << Atspi.ModifierType.CONTROL and not mods & 1 << Atspi.ModifierType.SHIFT): - msg = "INPUT EVENT MANAGER: Last event was select all" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def last_event_was_primary_click(self) -> bool: - """Returns True if the last event is a primary mouse click.""" - - if not self.last_event_was_mouse_button(): - return False - - if self._last_input_event.button == "1" and self._last_input_event.pressed: - msg = "INPUT EVENT MANAGER: Last event was primary click" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def last_event_was_primary_release(self) -> bool: - """Returns True if the last event is a primary mouse release.""" - - if not self.last_event_was_mouse_button(): - return False - - if self._last_input_event.button == "1" and not self._last_input_event.pressed: - msg = "INPUT EVENT MANAGER: Last event was primary release" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def last_event_was_primary_click_or_release(self) -> bool: - """Returns True if the last event is a primary mouse click or release.""" - - if not self.last_event_was_mouse_button(): - return False - - if self._last_input_event.button == "1": - msg = "INPUT EVENT MANAGER: Last event was primary click or release" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def last_event_was_middle_click(self) -> bool: - """Returns True if the last event is a middle mouse click.""" - - if not self.last_event_was_mouse_button(): - return False - - if self._last_input_event.button == "2" and self._last_input_event.pressed: - msg = "INPUT EVENT MANAGER: Last event was middle click" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def last_event_was_middle_release(self) -> bool: - """Returns True if the last event is a middle mouse release.""" - - if not self.last_event_was_mouse_button(): - return False - - if self._last_input_event.button == "2" and not self._last_input_event.pressed: - msg = "INPUT EVENT MANAGER: Last event was middle release" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def last_event_was_secondary_click(self) -> bool: - """Returns True if the last event is a secondary mouse click.""" - - if not self.last_event_was_mouse_button(): - return False - - if self._last_input_event.button == "3" and self._last_input_event.pressed: - msg = "INPUT EVENT MANAGER: Last event was secondary click" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - def last_event_was_secondary_release(self) -> bool: - """Returns True if the last event is a secondary mouse release.""" - - if not self.last_event_was_mouse_button(): - return False - - if self._last_input_event.button == "3" and not self._last_input_event.pressed: - msg = "INPUT EVENT MANAGER: Last event was secondary release" - debug.print_message(debug.LEVEL_INFO, msg, True) - return True - return False - - -_manager: Optional[InputEventManager] = None -if _manager is None: - _manager = InputEventManager() - -def get_manager() -> InputEventManager: - """Returns the Input Event Manager singleton.""" - return _manager diff --git a/src/cthulhu/keybindings.py b/src/cthulhu/keybindings.py deleted file mode 100644 index d16f380..0000000 --- a/src/cthulhu/keybindings.py +++ /dev/null @@ -1,599 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides support for defining keybindings and matching them to input -events.""" - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -import gi -gi.require_version('Gdk', '3.0') -gi.require_version('Atspi', '2.0') -from gi.repository import Gdk -from gi.repository import Atspi - -import functools -from typing import TYPE_CHECKING - -from . import debug -from . import settings -from . import cthulhu_state - -from .cthulhu_i18n import _ - -if TYPE_CHECKING: - from .input_event import KeyboardEvent, InputEventHandler - -_keysymsCache = {} -_keycodeCache = {} - -MODIFIER_CTHULHU = 8 -NO_MODIFIER_MASK = 0 -ALT_MODIFIER_MASK = 1 << Atspi.ModifierType.ALT -CTRL_MODIFIER_MASK = 1 << Atspi.ModifierType.CONTROL -CTHULHU_MODIFIER_MASK = 1 << MODIFIER_CTHULHU -CTHULHU_ALT_MODIFIER_MASK = (1 << MODIFIER_CTHULHU | - 1 << Atspi.ModifierType.ALT) -CTHULHU_CTRL_MODIFIER_MASK = (1 << MODIFIER_CTHULHU | - 1 << Atspi.ModifierType.CONTROL) -CTHULHU_CTRL_ALT_MODIFIER_MASK = (1 << MODIFIER_CTHULHU | - 1 << Atspi.ModifierType.CONTROL | - 1 << Atspi.ModifierType.ALT) -CTHULHU_SHIFT_MODIFIER_MASK = (1 << MODIFIER_CTHULHU | - 1 << Atspi.ModifierType.SHIFT) -SHIFT_MODIFIER_MASK = 1 << Atspi.ModifierType.SHIFT -SHIFT_ALT_MODIFIER_MASK = (1 << Atspi.ModifierType.SHIFT | - 1 << Atspi.ModifierType.ALT) -CTRL_ALT_MODIFIER_MASK = (1 << Atspi.ModifierType.CONTROL | - 1 << Atspi.ModifierType.ALT) -COMMAND_MODIFIER_MASK = (1 << Atspi.ModifierType.ALT | - 1 << Atspi.ModifierType.CONTROL | - 1 << Atspi.ModifierType.META2 | - 1 << Atspi.ModifierType.META3) -NON_LOCKING_MODIFIER_MASK = (1 << Atspi.ModifierType.SHIFT | - 1 << Atspi.ModifierType.ALT | - 1 << Atspi.ModifierType.CONTROL | - 1 << Atspi.ModifierType.META2 | - 1 << Atspi.ModifierType.META3 | - 1 << MODIFIER_CTHULHU) -defaultModifierMask = NON_LOCKING_MODIFIER_MASK - -CAN_USE_KEYSYMS = Atspi.get_version() >= (2, 55, 0) - -def get_keycodes(keysym): - """Converts an XKeysym string to a (keyval, keycode) tuple.""" - if not keysym: - return (0, 0) - - if keysym not in _keycodeCache: - keymap = Gdk.Keymap.get_default() - keyval = Gdk.keyval_from_name(keysym) - if keyval == 0: - return (0, 0) - - _keycodeCache[keysym] = (keyval, 0) - _success, entries = keymap.get_entries_for_keyval(keyval) - - for entry in entries: - if entry.group == 0: - _keycodeCache[keysym] = (keyval, entry.keycode) - break - if _keycodeCache[keysym] == (keyval, 0): - _keycodeCache[keysym] = (keyval, entries[0].keycode) - - return _keycodeCache[keysym] - -def getKeycode(keysym): - """Converts an XKeysym string to a keycode. Legacy wrapper.""" - return get_keycodes(keysym)[1] - -def getModifierNames(mods): - """Gets the modifier names of a numeric modifier mask as a human - consumable string. - """ - - text = "" - if mods & CTHULHU_MODIFIER_MASK: - if settings.keyboardLayout == settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP: - # Translators: this is presented in a GUI to represent the - # "insert" key when used as the Cthulhu modifier. - text += _("Insert") + "+" - else: - # Translators: this is presented in a GUI to represent the - # "caps lock" modifier. - text += _("Caps_Lock") + "+" - elif mods & (1 << Atspi.ModifierType.SHIFTLOCK): - # Translators: this is presented in a GUI to represent the - # "caps lock" modifier. - # - text += _("Caps_Lock") + "+" - #if mods & (1 << Atspi.ModifierType.NUMLOCK): - # text += _("Num_Lock") + "+" - if mods & 128: - # Translators: this is presented in a GUI to represent the - # "right alt" modifier. - # - text += _("Alt_R") + "+" - if mods & (1 << Atspi.ModifierType.META3): - # Translators: this is presented in a GUI to represent the - # "super" modifier. - # - text += _("Super") + "+" - if mods & (1 << Atspi.ModifierType.META2): - # Translators: this is presented in a GUI to represent the - # "meta 2" modifier. - # - text += _("Meta2") + "+" - #if mods & (1 << Atspi.ModifierType.META): - # text += _("Meta") + "+" - if mods & ALT_MODIFIER_MASK: - # Translators: this is presented in a GUI to represent the - # "left alt" modifier. - # - text += _("Alt_L") + "+" - if mods & CTRL_MODIFIER_MASK: - # Translators: this is presented in a GUI to represent the - # "control" modifier. - # - text += _("Ctrl") + "+" - if mods & SHIFT_MODIFIER_MASK: - # Translators: this is presented in a GUI to represent the - # "shift " modifier. - # - text += _("Shift") + "+" - return text - -def get_click_countString(count): - """Returns a human-consumable string representing the number of - clicks, such as 'double click' and 'triple click'.""" - - if count == 2: - # Translators: Cthulhu keybindings support double - # and triple "clicks" or key presses, similar to - # using a mouse. - # - return _("double click") - if count == 3: - # Translators: Cthulhu keybindings support double - # and triple "clicks" or key presses, similar to - # using a mouse. - # - return _("triple click") - return "" - -def create_key_definitions(keycode, keyval, modifiers): - """Returns a list of Atspi key definitions for the given keycode, keyval, and modifiers.""" - ret = [] - if modifiers & CTHULHU_MODIFIER_MASK: - modifier_list = [] - other_modifiers = modifiers & ~CTHULHU_MODIFIER_MASK - from . import input_event_manager - manager = input_event_manager.get_manager() - for key in settings.cthulhuModifierKeys: - mod_keyval, mod_keycode = get_keycodes(key) - if mod_keycode == 0 and key == "Shift_Lock": - mod_keyval, mod_keycode = get_keycodes("Caps_Lock") - if CAN_USE_KEYSYMS: - mod = manager.map_keysym_to_modifier(mod_keyval) - else: - mod = manager.map_keycode_to_modifier(mod_keycode) - if mod: - modifier_list.append(mod | other_modifiers) - else: - modifier_list = [modifiers] - for mod in modifier_list: - kd = Atspi.KeyDefinition() - if CAN_USE_KEYSYMS: - kd.keysym = keyval - else: - kd.keycode = keycode - kd.modifiers = mod - ret.append(kd) - return ret - -class KeyBinding: - """A single key binding, consisting of a keycode, a modifier mask, - and the InputEventHandler. - """ - - def __init__(self, keysymstring, modifier_mask, modifiers, handler, - click_count = 1, enabled=True): - """Creates a new key binding. - - Arguments: - - keysymstring: the keysymstring - this is typically a string - from /usr/include/X11/keysymdef.h with the preceding 'XK_' - removed (e.g., XK_KP_Enter becomes the string 'KP_Enter'). - - modifier_mask: bit mask where a set bit tells us what modifiers - we care about (see Atspi.ModifierType.*) - - modifiers: the state the modifiers we care about must be in for - this key binding to match an input event (see also - Atspi.ModifierType.*) - - handler: the InputEventHandler for this key binding - """ - - self.keysymstring = keysymstring - self.modifier_mask = modifier_mask - self.modifiers = modifiers - self.handler = handler - self.click_count = click_count - self.keycode = 0 - self.keyval = 0 - self._enabled = enabled - self._grab_ids = [] - - def matches(self, keyval, keycode, modifiers): - """Returns true if this key binding matches the given keyval/keycode and modifier state.""" - - if not self.keycode: - self.keyval, self.keycode = get_keycodes(self.keysymstring) - - if self.keycode == keycode or self.keyval == keyval: - result = modifiers & self.modifier_mask - return result == self.modifiers - - return False - - def description(self): - """Returns the description of this binding's functionality.""" - - try: - return self.handler.description - except Exception: - return '' - - def asString(self): - """Returns a more human-consumable string representing this binding.""" - - mods = getModifierNames(self.modifiers) - clickCount = get_click_countString(self.click_count) - keysym = self.keysymstring - string = f'{mods}{keysym} {clickCount}' - - return string.strip() - - def is_bound(self): - """Returns True if this KeyBinding is bound to a key.""" - return bool(self.keysymstring) - - def is_enabled(self): - """Returns True if this KeyBinding is enabled.""" - return self._enabled - - def set_enabled(self, enabled): - """Set this KeyBinding's enabled state.""" - self._enabled = enabled - - def get_grab_ids(self): - """Returns the grab IDs for this KeyBinding.""" - return self._grab_ids - - def has_grabs(self): - """Returns True if there are existing grabs associated with this KeyBinding.""" - return bool(self._grab_ids) - - def add_grabs(self): - """Adds key grabs for this KeyBinding.""" - from . import input_event_manager - self._grab_ids = input_event_manager.get_manager().add_grabs_for_keybinding(self) - - def remove_grabs(self): - """Removes key grabs for this KeyBinding.""" - from . import input_event_manager - input_event_manager.get_manager().remove_grabs_for_keybinding(self) - self._grab_ids = [] - - def key_definitions(self): - """Return a list of Atspi key definitions for the given binding.""" - ret = [] - if not self.keycode: - self.keyval, self.keycode = get_keycodes(self.keysymstring) - ret.extend(create_key_definitions(self.keycode, self.keyval, self.modifiers)) - if CAN_USE_KEYSYMS and self.modifiers & SHIFT_MODIFIER_MASK: - upper_keyval = Gdk.keyval_to_upper(self.keyval) - if upper_keyval != self.keyval: - ret.extend(create_key_definitions(self.keycode, upper_keyval, self.modifiers)) - return ret - - def keyDefs(self): - """Legacy wrapper. Use key_definitions() instead.""" - return self.key_definitions() - -class KeyBindings: - """Structure that maintains a set of KeyBinding instances. - """ - - def __init__(self): - self.keyBindings = [] - - def __str__(self): - result = "[\n" - for keyBinding in self.keyBindings: - result += " [%x %x %s %d %s]\n" % \ - (keyBinding.modifier_mask, - keyBinding.modifiers, - keyBinding.keysymstring, - keyBinding.click_count, - keyBinding.handler.description) - result += "]" - return result - - def add(self, keyBinding, include_grabs=False): - """Adds the given KeyBinding instance to this set of keybindings. - """ - - if keyBinding.keysymstring and self.hasKeyBinding(keyBinding, "keysNoMask"): - msg = ( - f"KEYBINDINGS: '{keyBinding.asString()}' " - f"({keyBinding.description()}) already in keybindings" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self.keyBindings.append(keyBinding) - if include_grabs: - keyBinding.add_grabs() - - def remove(self, keyBinding, include_grabs=False): - """Removes the given KeyBinding instance from this set of keybindings. - """ - - if keyBinding not in self.keyBindings: - candidates = self.getBindingsForHandler(keyBinding.handler) - if not candidates: - return - for candidate in self.getBindingsForHandler(keyBinding.handler): - self.remove(candidate, include_grabs) - return - - if keyBinding.has_grabs(): - if include_grabs: - keyBinding.remove_grabs() - - try: - self.keyBindings.remove(keyBinding) - except ValueError: - pass - - def removeByHandler(self, handler): - """Removes the given KeyBinding instance from this set of keybindings. - """ - i = len(self.keyBindings) - while i > 0: - if self.keyBindings[i - 1].handler == handler: - del self.keyBindings[i - 1] - i = i - 1 - - def add_key_grabs(self, reason=""): - """Adds grabs for all enabled bindings in this set of keybindings.""" - msg = "KEYBINDINGS: Adding key grabs" - if reason: - msg += f": {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - count = 0 - for binding in self.keyBindings: - if binding.is_enabled() and not binding.has_grabs(): - count += 1 - binding.add_grabs() - - msg = f"KEYBINDINGS: {count} key grabs added (total bindings: {len(self.keyBindings)})." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def remove_key_grabs(self, reason=""): - """Removes all grabs for this set of keybindings.""" - msg = "KEYBINDINGS: Removing key grabs" - if reason: - msg += f": {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - count = 0 - for binding in self.keyBindings: - if binding.has_grabs(): - count += 1 - binding.remove_grabs() - - msg = f"KEYBINDINGS: {count} key grabs removed (total bindings: {len(self.keyBindings)})." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def hasKeyBinding (self, newKeyBinding, typeOfSearch="strict"): - """Return True if keyBinding is already in self.keyBindings. - - The typeOfSearch can be: - "strict": matches description, modifiers, key, and - click count - "description": matches only description. - "keys": matches the modifiers, key, and modifier mask, - and click count - "keysNoMask": matches the modifiers, key, and click count - """ - - hasIt = False - - for keyBinding in self.keyBindings: - if typeOfSearch == "strict": - if (keyBinding.handler.description \ - == newKeyBinding.handler.description) \ - and (keyBinding.keysymstring \ - == newKeyBinding.keysymstring) \ - and (keyBinding.modifier_mask \ - == newKeyBinding.modifier_mask) \ - and (keyBinding.modifiers \ - == newKeyBinding.modifiers) \ - and (keyBinding.click_count \ - == newKeyBinding.click_count): - hasIt = True - elif typeOfSearch == "description": - if keyBinding.handler.description \ - == newKeyBinding.handler.description: - hasIt = True - elif typeOfSearch == "keys": - if (keyBinding.keysymstring \ - == newKeyBinding.keysymstring) \ - and (keyBinding.modifier_mask \ - == newKeyBinding.modifier_mask) \ - and (keyBinding.modifiers \ - == newKeyBinding.modifiers) \ - and (keyBinding.click_count \ - == newKeyBinding.click_count): - hasIt = True - elif typeOfSearch == "keysNoMask": - if (keyBinding.keysymstring \ - == newKeyBinding.keysymstring) \ - and (keyBinding.modifiers \ - == newKeyBinding.modifiers) \ - and (keyBinding.click_count \ - == newKeyBinding.click_count): - hasIt = True - - return hasIt - - def getBoundBindings(self, uniqueOnly=False): - """Returns the KeyBinding instances which are bound to a keystroke. - - Arguments: - - uniqueOnly: Should alternative bindings for the same handler be - filtered out (default: False) - """ - - bound = [kb for kb in self.keyBindings if kb.keysymstring] - if uniqueOnly: - handlers = [kb.handler.description for kb in bound] - bound = [bound[i] for i in map(handlers.index, set(handlers))] - - bindings = {} - for kb in bound: - string = kb.asString() - match = bindings.get(string) - if match is not None: - tokens = ["WARNING: '", string, "' (", kb.description(), ") also matches:", match] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - bindings[string] = kb.description() - - return bound - - def getBindingsForHandler(self, handler): - """Returns the KeyBinding instances associated with handler.""" - - return [kb for kb in self.keyBindings if kb.handler == handler] - - def has_enabled_handler(self, handler): - """Returns True if the handler is found in this set of keybindings and is enabled.""" - for binding in self.keyBindings: - if binding.handler == handler and binding.is_enabled(): - return True - return False - - def _checkMatchingBindings(self, keyboardEvent, result): - if debug.debugLevel > debug.LEVEL_INFO: - return - - # If we don't have multiple matches, we're good. - if len(result) <= 1: - return - - # If we have multiple matches, but they have unique click counts, we're good. - if len(set(map(lambda x: x.click_count, result))) == len(result): - return - - def toString(x): - return "%s (%ix)" % (x.handler.description, x.click_count) - - msg = ( - f"KEYBINDINGS: '{keyboardEvent.event_string}' " - f"matches multiple handlers: {', '.join(map(toString, result))}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def getInputHandler(self, keyboardEvent): - """Returns the input handler of the key binding that matches the - given keycode and modifiers, or None if no match exists. - """ - - matches = [] - candidates = [] - clickCount = keyboardEvent.get_click_count() - for keyBinding in self.keyBindings: - if keyBinding.matches(keyboardEvent.id, keyboardEvent.hw_code, keyboardEvent.modifiers): - if (keyboardEvent.modifiers & keyBinding.modifier_mask) == keyBinding.modifiers and \ - keyBinding.click_count == clickCount: - matches.append(keyBinding) - # If there's no keysymstring, it's unbound and cannot be - # a match. - # - if keyBinding.keysymstring: - candidates.append(keyBinding) - - self._checkMatchingBindings(keyboardEvent, matches) - if matches: - return matches[0].handler - - if keyboardEvent.isKeyPadKeyWithNumlockOn(): - return None - - # If we're still here, we don't have an exact match. Prefer - # the one whose click count is closest to, but does not exceed, - # the actual click count. - # - candidates.sort(key=functools.cmp_to_key(lambda x, y: y.click_count - x.click_count)) - self._checkMatchingBindings(keyboardEvent, candidates) - for candidate in candidates: - if candidate.click_count <= clickCount: - return candidate.handler - - return None - - def load(self, keymap, handlers): - """ Takes the keymappings and tries to find a matching named - function in handlers. - keymap is a list of lists, each list contains 5 elements - If addUnbound is set to true, then at the end of loading all the - keybindings, any remaining functions will be unbound. - """ - - # TODO - JD: This won't be needed once the remaining bindings have - # been removed from the keymap files. - - for i in keymap: - keysymstring = i[0] - modifierMask = i[1] - modifiers = i[2] - handler = i[3] - try: - clickCount = i[4] - except Exception: - clickCount = 1 - - if handler in handlers: - self.add(KeyBinding( - keysymstring, modifierMask, modifiers, handlers[handler], clickCount)) - else: - tokens = ["KEYBINDINGS: Could not find", handler, "handler for keybinding."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) diff --git a/src/cthulhu/keynames.py b/src/cthulhu/keynames.py deleted file mode 100644 index 642c236..0000000 --- a/src/cthulhu/keynames.py +++ /dev/null @@ -1,340 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Exposes a dictionary, keynames, that maps key events -into localized words.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2006-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -from . import chnames - -from .cthulhu_i18n import _ -from .cthulhu_i18n import C_ - -# __keynames is a dictionary where the keys represent a UTF-8 -# string for a keyboard key and the values represent the common -# phrase used to describe the key. -# -__keynames = {} - -# Translators: this is how someone would speak the name of the shift key -# -__keynames["Shift"] = C_("keyboard", "Shift") - -# Translators: this is how someone would speak the name of the alt key -# -__keynames["Alt"] = C_("keyboard", "Alt") - -# Translators: this is how someone would speak the name of the control key -# -__keynames["Control"] = C_("keyboard", "Control") - -# Translators: this is how someone would speak the name of the left shift key -# -__keynames["Shift_L"] = _("left shift") - -# Translators: this is how someone would speak the name of the left alt key -# -__keynames["Alt_L"] = _("left alt") - -# Translators: this is how someone would speak the name of the left ctrl key -# -__keynames["Control_L"] = _("left control") - -# Translators: this is how someone would speak the name of the right shift key -# -__keynames["Shift_R"] = _("right shift") - -# Translators: this is how someone would speak the name of the right alt key -# -__keynames["Alt_R"] = _("right alt") - -# Translators: this is how someone would speak the name of the right ctrl key -# -__keynames["Control_R"] = _("right control") - -# Translators: this is how someone would speak the name of the left meta key -# -__keynames["Meta_L"] = _("left meta") - -# Translators: this is how someone would speak the name of the right meta key -# -__keynames["Meta_R"] = _("right meta") - -# Translators: this is how someone would speak the name of the num lock key -# -__keynames["Num_Lock"] = _("num lock") - -# Translators: this is how someone would speak the name of the caps lock key -# -__keynames["Caps_Lock"] = _("caps lock") - -# Translators: this is how someone would speak the name of the shift lock key -# There is no reason to make it different from the translation for "caps lock" -# -__keynames["Shift_Lock"] = _("shift lock") - -# Translators: this is how someone would speak the name of the scroll lock key -# -__keynames["Scroll_Lock"] = _("scroll lock") - -# Translators: this is how someone would speak the name of the page up key -# -__keynames["Page_Up"] = _("page up") - -# Translators: this is how someone would speak the name of the page up key -# -__keynames["KP_Page_Up"] = _("page up") - -# Translators: this is how someone would speak the name of the page up key -# -__keynames["Prior"] = _("page up") - -# Translators: this is how someone would speak the name of the page up key -# -__keynames["KP_Prior"] = _("page up") - -# Translators: this is how someone would speak the name of the page down key -# -__keynames["Page_Down"] = _("page down") - -# Translators: this is how someone would speak the name of the page down key -# -__keynames["KP_Page_Down"] = _("page down") - -# Translators: this is how someone would speak the name of the page down key -# -__keynames["Next"] = _("page down") - -# Translators: this is how someone would speak the name of the page down key -# -__keynames["KP_Next"] = _("page down") - -# Translators: this is how someone would speak the name of the tab key -# -__keynames["Tab"] = _("tab") - -# Translators: this is how someone would speak the name of the left tab key -# -__keynames["ISO_Left_Tab"] = _("left tab") - -# Translators: this is the spoken word for the space character -# -__keynames["space"] = _("space") - -# Translators: this is how someone would speak the name of the backspace key -# -__keynames["BackSpace"] = _("backspace") - -# Translators: this is how someone would speak the name of the return key -# -__keynames["Return"] = _("return") - -# Translators: this is how someone would speak the name of the enter key -# -__keynames["KP_Enter"] = _("enter") - -# Translators: this is how someone would speak the name of the up arrow key -# -__keynames["Up"] = _("up") - -# Translators: this is how someone would speak the name of the up arrow key -# -__keynames["KP_Up"] = _("up") - -# Translators: this is how someone would speak the name of the down arrow key -# -__keynames["Down"] = _("down") - -# Translators: this is how someone would speak the name of the down arrow key -# -__keynames["KP_Down"] = _("down") - -# Translators: this is how someone would speak the name of the left arrow key -# -__keynames["Left"] = _("left") - -# Translators: this is how someone would speak the name of the left arrow key -# -__keynames["KP_Left"] = _("left") - -# Translators: this is how someone would speak the name of the right arrow key -# -__keynames["Right"] = _("right") - -# Translators: this is how someone would speak the name of the right arrow key -# -__keynames["KP_Right"] = _("right") - -# Translators: this is how someone would speak the name of the left super key -# -__keynames["Super_L"] = _("left super") - -# Translators: this is how someone would speak the name of the right super key -# -__keynames["Super_R"] = _("right super") - -# Translators: this is how someone would speak the name of the menu key -# -__keynames["Menu"] = _("menu") - -# Translators: this is how someone would speak the name of the ISO shift key -# -__keynames["ISO_Level3_Shift"] = _("Alt Gr") - -# Translators: this is how someone would speak the name of the help key -# -__keynames["Help"] = _("help") - -# Translators: this is how someone would speak the name of the multi key -# -__keynames["Multi_key"] = _("multi") - -# Translators: this is how someone would speak the name of the mode switch key -# -__keynames["Mode_switch"] = _("mode switch") - -# Translators: this is how someone would speak the name of the escape key -# -__keynames["Escape"] = _("escape") - -# Translators: this is how someone would speak the name of the insert key -# -__keynames["Insert"] = _("insert") - -# Translators: this is how someone would speak the name of the insert key -# -__keynames["KP_Insert"] = _("insert") - -# Translators: this is how someone would speak the name of the delete key -# -__keynames["Delete"] = _("delete") - -# Translators: this is how someone would speak the name of the delete key -# -__keynames["KP_Delete"] = _("delete") - -# Translators: this is how someone would speak the name of the home key -# -__keynames["Home"] = _("home") - -# Translators: this is how someone would speak the name of the home key -# -__keynames["KP_Home"] = _("home") - -# Translators: this is how someone would speak the name of the end key -# -__keynames["End"] = _("end") - -# Translators: this is how someone would speak the name of the end key -# -__keynames["KP_End"] = _("end") - -# Translators: this is how someone would speak the name of the begin key -# -__keynames["KP_Begin"] = _("begin") - -# Translators: this is how someone would speak the name of the -# non-spacing diacritical key for the grave glyph -# -__keynames["dead_grave"] = _("grave") - -# Translators: this is how someone would speak the name of the -# non-spacing diacritical key for the acute glyph -# -__keynames["dead_acute"] = _("acute") - -# Translators: this is how someone would speak the name of the -# non-spacing diacritical key for the circumflex glyph -# -__keynames["dead_circumflex"] = _("circumflex") - -# Translators: this is how someone would speak the name of the -# non-spacing diacritical key for the tilde glyph -# -__keynames["dead_tilde"] = _("tilde") - -# Translators: this is how someone would speak the name of the -# non-spacing diacritical key for the diaeresis glyph -# -__keynames["dead_diaeresis"] = _("diaeresis") - -# Translators: this is how someone would speak the name of the -# non-spacing diacritical key for the ring glyph -# -__keynames["dead_abovering"] = _("ring") - -# Translators: this is how someone would speak the name of the -# non-spacing diacritical key for the cedilla glyph -# -__keynames["dead_cedilla"] = _("cedilla") - -# Translators: this is how someone would speak the name of the -# non-spacing diacritical key for the stroke glyph -# -__keynames["dead_stroke"] = _("stroke") - -# Translators: this is how someone would speak the name of the minus key -# -__keynames["minus"] = _("minus") - -# Translators: this is how someone would speak the name of the plus key -# -__keynames["plus"] = _("plus") - - -def getKeyName(key): - """Given a keyboard key, return its name as people might refer to it - in ordinary conversation. - - Arguments: - - key: the key to get the name for - - Returns a string representing the name for the key - """ - - return __keynames.get(key, chnames.getCharacterName(key)) - -def localizeKeySequence(keys): - """Given a sequence of keys, such as 'Shift Control A', localize the - full sequence. - - Arguments: - - keys: the key sequence to localize - - Returns a string representing the localized version to present to the - user - """ - - keyList = keys.split() - for key in keyList: - keyName = getKeyName(key) - keys = keys.replace(key, keyName) - - return keys diff --git a/src/cthulhu/label_inference.py b/src/cthulhu/label_inference.py deleted file mode 100644 index f0384ea..0000000 --- a/src/cthulhu/label_inference.py +++ /dev/null @@ -1,591 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Heuristic means to infer the functional/displayed label of a widget.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (C) 2011-2013 Igalia, S.L." -__license__ = "LGPL" - -from . import debug -from .ax_component import AXComponent -from .ax_hypertext import AXHypertext -from .ax_object import AXObject -from .ax_table import AXTable -from .ax_text import AXText -from .ax_utilities import AXUtilities - -class LabelInference: - - def __init__(self, script): - """Creates an instance of the LabelInference class. - - Arguments: - - script: the script with which this instance is associated. - """ - - self._script = script - self._lineCache = {} - self._extentsCache = {} - self._isWidgetCache = {} - - def infer(self, obj, focusedOnly=True): - """Attempt to infer the functional/displayed label of obj. - - Arguments - - obj: the unlabeled widget - - focusedOnly: If True, only infer if the widget has focus. - - Returns the text which we think is the label, or None. - """ - - tokens = ["LABEL INFERENCE: Infer label for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if not obj: - return None, [] - - if focusedOnly and not AXUtilities.is_focused(obj): - tokens = ["LABEL INFERENCE:", obj, "is not focused"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None, [] - - result, objects = None, [] - if not result: - result, objects = self.inferFromTextLeft(obj) - debug.printMessage(debug.LEVEL_INFO, f"LABEL INFERENCE: Text Left: '{result}'", True) - if not result or self._preferRight(obj): - rightResult = self.inferFromTextRight(obj) - if rightResult[0] is not None: - result, objects = rightResult - debug.printMessage(debug.LEVEL_INFO, f"LABEL INFERENCE: Text Right: '{result}'", True) - if not result: - result, objects = self.inferFromTable(obj) - debug.printMessage(debug.LEVEL_INFO, f"LABEL INFERENCE: Table: '{result}'", True) - if not result: - result, objects = self.inferFromTextAbove(obj) - debug.printMessage(debug.LEVEL_INFO, f"LABEL INFERENCE: Text Above: '{result}'", True) - if not result: - result, objects = self.inferFromTextBelow(obj) - debug.printMessage(debug.LEVEL_INFO, f"LABEL INFERENCE: Text Below: '{result}'", True) - - # TODO - We probably do not wish to "infer" from these. Instead, we - # should ensure that this content gets presented as part of the widget. - # (i.e. the label is something on screen. Widget name and description - # are each something other than a label.) - if not result: - result, objects = AXObject.get_name(obj), [] - debug.printMessage(debug.LEVEL_INFO, f"LABEL INFERENCE: Name: '{result}'", True) - - if result: - result = result.strip() - result = result.replace("\n", " ") - - # Desperate times call for desperate measures.... - if not result: - result, objects = self.inferFromTextLeft(obj, proximity=200) - debug.printMessage( - debug.LEVEL_INFO, - f"LABEL INFERENCE: Text Left with proximity of 200: '{result}'", True) - - self.clearCache() - return result, objects - - def clearCache(self): - """Dumps whatever we've stored for performance purposes.""" - - self._lineCache = {} - self._extentsCache = {} - self._isWidgetCache = {} - - def _preferRight(self, obj): - """Returns True if we should prefer text on the right, rather than the - left, for the object obj.""" - - return AXUtilities.is_check_box(obj) or AXUtilities.is_radio_button(obj) - - def _preventRight(self, obj): - """Returns True if we should not permit inference based on text to - the right for the object obj.""" - - return AXUtilities.is_combo_box(obj) or AXUtilities.is_list_box(obj) - - def _preferTop(self, obj): - """Returns True if we should prefer text above, rather than below for - the object obj.""" - - return AXUtilities.is_combo_box(obj) or AXUtilities.is_list_box(obj) - - def _preventBelow(self, obj): - """Returns True if we should not permit inference based on text below - the object obj.""" - - return not AXUtilities.is_text_input(obj) - - def _isSimpleObject(self, obj): - """Returns True if the given object has 'simple' contents, such as text - without embedded objects or a single embedded object without text.""" - - if obj is None: - return False - - def isMatch(x): - return AXUtilities.is_web_element(x) and not AXUtilities.is_link(x) - - children = list(AXObject.iter_children(obj, isMatch)) - if len(children) > 1: - return False - - string = AXText.get_all_text(obj).strip() - if string.count(self._script.EMBEDDED_OBJECT_CHARACTER) > 1: - return False - - return True - - def _cannotLabel(self, obj): - """Returns True if the given object should not be treated as a label.""" - - if obj is None: - return True - - if AXUtilities.is_heading(obj) or AXUtilities.is_list_item(obj): - return True - - return self._isWidget(obj) - - def _isWidget(self, obj): - """Returns True if the given object is a widget.""" - - if obj is None: - return False - - rv = self._isWidgetCache.get(hash(obj)) - if rv is not None: - return rv - - isWidget = AXUtilities.is_widget(obj) or AXUtilities.is_menu_related(obj) - if not isWidget and AXUtilities.is_editable(obj): - isWidget = True - - self._isWidgetCache[hash(obj)] = isWidget - return isWidget - - def _getExtents(self, obj, startOffset=0, endOffset=-1): - """Returns (x, y, width, height) of the text at the given offsets - if the object implements accessible text, or just the extents of - the object if it doesn't implement accessible text.""" - - if not obj: - return 0, 0, 0, 0 - - rv = self._extentsCache.get((hash(obj), startOffset, endOffset)) - if rv: - return rv - - extents = 0, 0, 0, 0 - if AXObject.supports_text(obj) and not AXUtilities.is_text_input(obj): - if endOffset == -1: - endOffset = AXText.get_character_count(obj) - rect = AXText.get_range_rect(obj, startOffset, endOffset) - extents = rect.x, rect.y, rect.width, rect.height - - if not (extents[2] and extents[3]): - rect = AXComponent.get_rect(obj) - extents = rect.x, rect.y, rect.width, rect.height - - self._extentsCache[(hash(obj), startOffset, endOffset)] = extents - return extents - - def _createLabelFromContents(self, obj): - """Gets the functional label text associated with the object obj.""" - - if not self._isSimpleObject(obj): - return None, [] - - if self._cannotLabel(obj): - return None, [] - - contents = self._script.utilities.get_objectContentsAtOffset(obj, useCache=False) - objects = [content[0] for content in contents] - if list(filter(self._isWidget, objects)): - return None, [] - - strings = [content[3] for content in contents] - return ''.join(strings), objects - - def _getLineContents(self, obj, start=0): - """Get the (obj, startOffset, endOffset, string) tuples for the line - containing the object, obj.""" - - rv = self._lineCache.get(hash(obj)) - if rv: - return rv - - key = hash(obj) - if self._isWidget(obj): - start = AXHypertext.get_link_start_offset(obj) - obj = AXObject.get_parent(obj) - - rv = self._script.utilities.getLineContentsAtOffset(obj, start, True, False) - if rv is None: - rv = [] - self._lineCache[key] = rv - - return rv - - def inferFromTextLeft(self, obj, proximity=75): - """Attempt to infer the functional/displayed label of obj by - looking at the contents of the current line, which are to the - left of this object - - Arguments - - obj: the unlabeled widget - - proximity: pixels expected for a match - - Returns the text which we think is the label, or None. - """ - - extents = self._getExtents(obj) - contents = self._getLineContents(obj) - content = [o for o in contents if o[0] == obj] - try: - index = contents.index(content[0]) - except IndexError: - index = len(contents) - - onLeft = contents[0:index] - start = 0 - for i in range(len(onLeft) - 1, -1, -1): - lObj, lStart, lEnd, lString = onLeft[i] - lExtents = self._getExtents(lObj) - if lExtents[0] > extents[0] or self._cannotLabel(lObj): - start = i + 1 - break - - onLeft = onLeft[start:] - if not (onLeft and onLeft[0]): - return None, [] - - lObj, start, end, string = onLeft[-1] - lExtents = self._getExtents(lObj, start, end) - distance = extents[0] - (lExtents[0] + lExtents[2]) - if 0 <= distance <= proximity: - strings = [content[3] for content in onLeft] - result = ''.join(strings).strip() - if result: - return result, [content[0] for content in onLeft] - - return None, [] - - def inferFromTextRight(self, obj, proximity=25): - """Attempt to infer the functional/displayed label of obj by - looking at the contents of the current line, which are to the - right of this object - - Arguments - - obj: the unlabeled widget - - proximity: pixels expected for a match - - Returns the text which we think is the label, or None. - """ - - if self._preventRight(obj): - return None, [] - - extents = self._getExtents(obj) - contents = self._getLineContents(obj) - content = [o for o in contents if o[0] == obj] - try: - index = contents.index(content[0]) - except IndexError: - index = len(contents) - - onRight = contents[min(len(contents), index+1):] - end = len(onRight) - for i, item in enumerate(onRight): - if self._cannotLabel(item[0]): - if not self._preferRight(obj): - return None, [] - end = i + 1 - break - - onRight = onRight[0:end] - if not (onRight and onRight[0]): - return None, [] - - rObj, start, end, string = onRight[0] - rExtents = self._getExtents(rObj, start, end) - distance = rExtents[0] - (extents[0] + extents[2]) - if distance <= proximity or self._preferRight(obj): - strings = [content[3] for content in onRight] - result = ''.join(strings).strip() - if result: - return result, [content[0] for content in onRight] - - return None, [] - - def inferFromTextAbove(self, obj, proximity=20): - """Attempt to infer the functional/displayed label of obj by - looking at the contents of the line above the line containing - the object obj. - - Arguments - - obj: the unlabeled widget - - proximity: pixels expected for a match - - Returns the text which we think is the label, or None. - """ - - thisLine = self._getLineContents(obj) - content = [o for o in thisLine if o[0] == obj] - try: - index = thisLine.index(content[0]) - except IndexError: - return None, [] - if index > 0: - return None, [] - - prevObj, prevOffset = self._script.utilities.previousContext( - thisLine[0][0], thisLine[0][1], True) - prevLine = self._getLineContents(prevObj, prevOffset) - if len(prevLine) != 1: - return None, [] - - prevObj, start, end, string = prevLine[0] - if self._cannotLabel(prevObj): - return None, [] - - if string.endswith("\n"): - string = string[:-1] - end -= 1 - - if string.strip(): - x, y, width, height = self._getExtents(prevObj, start, end) - objX, objY, objWidth, objHeight = self._getExtents(obj) - distance = objY - (y + height) - if 0 <= distance <= proximity and x <= objX: - return string.strip(), [prevObj] - - return None, [] - - def inferFromTextBelow(self, obj, proximity=20): - """Attempt to infer the functional/displayed label of obj by - looking at the contents of the line above the line containing - the object obj. - - Arguments - - obj: the unlabeled widget - - proximity: pixels expected for a match - - Returns the text which we think is the label, or None. - """ - - if self._preventBelow(obj): - return None, [] - - thisLine = self._getLineContents(obj) - content = [o for o in thisLine if o[0] == obj] - try: - index = thisLine.index(content[0]) - except IndexError: - return None, [] - if index > 0: - return None, [] - - nextObj, nextOffset = self._script.utilities.nextContext( - thisLine[-1][0], thisLine[-1][2] - 1, True) - nextLine = self._getLineContents(nextObj, nextOffset) - if len(nextLine) != 1: - return None, [] - - nextObj, start, end, string = nextLine[0] - if self._cannotLabel(nextObj): - return None, [] - - if string.strip(): - x, y, width, height = self._getExtents(nextObj, start, end) - objX, objY, objWidth, objHeight = self._getExtents(obj) - distance = y - (objY + objHeight) - if 0 <= distance <= proximity: - return string.strip(), [nextObj] - - return None, [] - - def _isTable(self, obj): - if AXUtilities.is_table(obj): - return True - - return self._getTag(obj) == 'table' - - def _isRow(self, obj): - if AXUtilities.is_table_row(obj): - return True - - return self._getTag(obj) == 'tr' - - def _isCell(self, obj): - if AXUtilities.is_table_cell(obj): - return True - - return self._getTag(obj) in ['td', 'th'] - - def _getCellFromTable(self, table, rowindex, colindex): - if not AXObject.supports_table(table): - return None - - if rowindex < 0 or colindex < 0: - return None - - rows = AXTable.get_row_count(table, prefer_attribute=False) - cols = AXTable.get_column_count(table, prefer_attribute=False) - if rowindex >= rows or colindex >= cols: - return None - - return AXTable.get_cell_at(table, rowindex, colindex) - - def _getCellFromRow(self, row, colindex): - if 0 <= colindex < AXObject.get_child_count(row): - return row[colindex] - - return None - - def _getTag(self, obj): - attrs = self._script.utilities.objectAttributes(obj) - return attrs.get('tag') - - def inferFromTable(self, obj, proximityForRight=50): - """Attempt to infer the functional/displayed label of obj by looking - at the contents of the surrounding table cells. Note that this approach - assumes a simple table in which the widget is the sole occupant of its - cell. - - Arguments - - obj: the unlabeled widget - - Returns the text which we think is the label, or None. - """ - - cell = AXObject.find_ancestor(obj, self._isCell) - if not self._isSimpleObject(cell): - return None, [] - - parent = AXObject.get_parent(obj) - if cell not in [parent, AXObject.get_parent(parent)]: - return None, [] - - grid = AXObject.find_ancestor(cell, self._isTable) - if not grid: - return None, [] - - cellLeft = cellRight = cellAbove = cellBelow = None - gridrow = AXObject.find_ancestor(cell, self._isRow) - rowindex, colindex = AXTable.get_cell_coordinates(cell, prefer_attribute=False) - if colindex > -1: - cellLeft = self._getCellFromTable(grid, rowindex, colindex - 1) - cellRight = self._getCellFromTable(grid, rowindex, colindex + 1) - cellAbove = self._getCellFromTable(grid, rowindex - 1, colindex) - cellBelow = self._getCellFromTable(grid, rowindex + 1, colindex) - elif gridrow and AXObject.get_parent(cell) == gridrow: - cellindex = AXObject.get_index_in_parent(cell) - cellLeft = self._getCellFromRow(gridrow, cellindex - 1) - cellRight = self._getCellFromRow(gridrow, cellindex + 1) - rowindex = AXObject.get_index_in_parent(gridrow) - gridrowParent = AXObject.get_parent(gridrow) - if rowindex > 0: - rowAbove = AXObject.get_child(gridrowParent, rowindex - 1) - cellAbove = self._getCellFromRow(rowAbove, cellindex) - if rowindex + 1 < AXObject.get_child_count(grid): - rowBelow = AXObject.get_child(gridrowParent, rowindex + 1) - cellBelow = self._getCellFromRow(rowBelow, cellindex) - - if cellLeft and not self._preferRight(obj): - label, sources = self._createLabelFromContents(cellLeft) - if label: - return label.strip(), sources - - objX, objY, objWidth, objHeight = self._getExtents(obj) - - if cellRight and not self._preventRight(obj): - x, y, width, height = self._getExtents(cellRight) - distance = x - (objX + objWidth) - if distance <= proximityForRight or self._preferRight(obj): - label, sources = self._createLabelFromContents(cellRight) - if label: - return label.strip(), sources - - labelAbove = labelBelow = None - if cellAbove: - labelAbove, sourcesAbove = self._createLabelFromContents(cellAbove) - if labelAbove and self._preferTop(obj): - return labelAbove.strip(), sourcesAbove - - if cellBelow and not self._preventBelow(obj): - labelBelow, sourcesBelow = self._createLabelFromContents(cellBelow) - - if labelAbove and labelBelow: - aboveX, aboveY, aboveWidth, aboveHeight = self._getExtents(cellAbove) - belowX, belowY, belowWidth, belowHeight = self._getExtents(cellBelow) - dAbove = objY - (aboveY + aboveHeight) - dBelow = belowY - (objY + objHeight) - if dAbove <= dBelow: - return labelAbove.strip(), sourcesAbove - return labelBelow.strip(), sourcesBelow - - if labelAbove: - return labelAbove.strip(), sourcesAbove - if labelBelow: - return labelBelow.strip(), sourcesBelow - - # None of the cells immediately surrounding this cell seem to be serving - # as a functional label. Therefore, see if this table looks like a grid - # of widgets with the functional labels in the first row. - - rows = AXTable.get_row_count(grid, prefer_attribute=False) - cols = AXTable.get_column_count(grid, prefer_attribute=False) - if rows <= 0 or cols <= 0: - return None, [] - - firstRow = [AXTable.get_cell_at(grid, 0, i) for i in range(cols)] - if not firstRow or list(filter(self._isWidget, firstRow)): - return None, [] - - if colindex < 0: - return None, [] - - def isMatch(x): - if not AXObject.get_child_count(x): - return False - return not AXUtilities.have_same_role(AXObject.get_child(x, 0), obj) - - cells = [AXTable.get_cell_at(grid, i, colindex) for i in range(1, rows)] - if list(filter(isMatch, cells)): - return None, [] - - label, sources = self._createLabelFromContents(firstRow[colindex]) - if label: - return label.strip(), sources - - return None, [] diff --git a/src/cthulhu/laptop_keyboardmap.py b/src/cthulhu/laptop_keyboardmap.py deleted file mode 100644 index fbfa2c8..0000000 --- a/src/cthulhu/laptop_keyboardmap.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -""" A list of common keybindings and unbound keys - pulled out from default.py: __getLaptopBindings() - with the goal of being more readable and less monolithic. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs, Mesar Hameed." -__license__ = "LGPL" - -from . import keybindings - -# Storing values -defaultModifierMask = keybindings.defaultModifierMask -CTHULHU_MODIFIER_MASK = keybindings.CTHULHU_MODIFIER_MASK -NO_MODIFIER_MASK = keybindings.NO_MODIFIER_MASK -CTHULHU_SHIFT_MODIFIER_MASK = keybindings.CTHULHU_SHIFT_MODIFIER_MASK -CTHULHU_CTRL_MODIFIER_MASK = keybindings.CTHULHU_CTRL_MODIFIER_MASK - -keymap = ( - - ("9", defaultModifierMask, CTHULHU_MODIFIER_MASK, - "routePointerToItemHandler"), - - # We want the user to be able to combine modifiers with the - # mouse click (e.g. to Shift+Click and select), therefore we - # do not "care" about the modifiers (other than the Cthulhu - # modifier). - # - - ("7", CTHULHU_MODIFIER_MASK, CTHULHU_MODIFIER_MASK, - "leftClickReviewItemHandler"), - - ("8", CTHULHU_MODIFIER_MASK, CTHULHU_MODIFIER_MASK, - "rightClickReviewItemHandler"), - - ("semicolon", defaultModifierMask, CTHULHU_MODIFIER_MASK, - "sayAllHandler", 1), - - ("bracketleft", defaultModifierMask, CTHULHU_MODIFIER_MASK, - "findHandler"), - - ("bracketright", defaultModifierMask, CTHULHU_MODIFIER_MASK, - "findNextHandler"), - - ("bracketright", defaultModifierMask, CTHULHU_CTRL_MODIFIER_MASK, - "findPreviousHandler"), - -) diff --git a/src/cthulhu/learn_mode_presenter.py b/src/cthulhu/learn_mode_presenter.py deleted file mode 100644 index c8a32f3..0000000 --- a/src/cthulhu/learn_mode_presenter.py +++ /dev/null @@ -1,407 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Module for learn mode""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2016-2023 Igalia, S.L." -__license__ = "LGPL" - -import gi - -gi.require_version("Atspi", "2.0") -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") -gi.require_version("Gio", "2.0") -from gi.repository import Atspi -from gi.repository import Gdk -from gi.repository import Gio -from gi.repository import GLib -from gi.repository import GObject -from gi.repository import Gtk - -from . import cmdnames -from . import debug -from . import guilabels -from . import input_event -from . import keybindings -from . import messages -from . import cthulhu_state -from . import settings -from . import settings_manager -from .ax_object import AXObject - - -class LearnModePresenter: - """Provides implementation of learn mode""" - - def __init__(self, app): - self.app = app - self._handlers = self._setup_handlers() - self._bindings = self._setup_bindings() - self._is_active = False - self._gui = None - - def is_active(self): - """Returns True if we're in learn mode""" - - return self._is_active - - def get_bindings(self): - """Returns the learn-mode-presenter keybindings.""" - - return self._bindings - - def get_handlers(self): - """Returns the learn-mode-presenter handlers.""" - - return self._handlers - - def _setup_handlers(self): - """Sets up and returns the learn-mode-presenter input event handlers.""" - - handlers = {} - - handlers["enterLearnModeHandler"] = \ - input_event.InputEventHandler( - self.start, - cmdnames.ENTER_LEARN_MODE) - - return handlers - - def _setup_bindings(self): - """Sets up and returns the learn-mode-presenter key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "h", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("enterLearnModeHandler"))) - - return bindings - - def start(self, script=None, event=None): - """Starts learn mode.""" - - if self._is_active: - msg = "LEARN MODE PRESENTER: Start called when already active" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if script is None: - script = cthulhu_state.activeScript - - if script is not None: - script.presentMessage(messages.VERSION) - script.speakMessage(messages.LEARN_MODE_START_SPEECH) - script.displayBrailleMessage(messages.LEARN_MODE_START_BRAILLE) - - if cthulhu_state.device is not None: - msg = "LEARN MODE PRESENTER: Grabbing keyboard" - debug.printMessage(debug.LEVEL_INFO, msg, True) - Atspi.Device.grab_keyboard(cthulhu_state.device) - - msg = "LEARN MODE PRESENTER: Is now active" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._is_active = True - return True - - def quit(self, script=None, event=None): - """Quits learn mode.""" - - if not self._is_active: - msg = "LEARN MODE PRESENTER: Quit called when already inactive" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if script is None: - script = cthulhu_state.activeScript - - if script is not None: - script.presentMessage(messages.LEARN_MODE_STOP) - - if cthulhu_state.device is not None: - msg = "LEARN MODE PRESENTER: Ungrabbing keyboard" - debug.printMessage(debug.LEVEL_INFO, msg, True) - Atspi.Device.ungrab_keyboard(cthulhu_state.device) - - msg = "LEARN MODE PRESENTER: Is now inactive" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._is_active = False - return True - - def handle_event(self, event=None): - """Handles the event if learn mode is active.""" - - if not self._is_active: - return False - - if not isinstance(event, input_event.KeyboardEvent): - return False - - cthulhu_state.activeScript.speakKeyEvent(event) - if event.is_printable_key() and event.get_click_count() == 2 \ - and event.getHandler() is None: - cthulhu_state.activeScript.phoneticSpellCurrentItem(event.event_string) - - key_name = event.keyval_name or event.event_string - if key_name == "Escape": - self.quit(script=None, event=event) - return True - - if event.event_string == "F1" and not event.modifiers: - self.show_help(cthulhu_state.activeScript, event) - return True - - if event.event_string in ["F2", "F3"] and not event.modifiers: - self.list_cthulhu_shortcuts(cthulhu_state.activeScript, event) - return True - - self.present_command(event) - return True - - def present_command(self, event=None): - """Presents the command bound to event.""" - - if not isinstance(event, input_event.KeyboardEvent): - return True - - handler = event.getHandler() - if handler is None: - debug.printMessage(debug.LEVEL_INFO, "LEARN MODE PRESENTER: No handler found for event", True) - return True - - debug.printMessage(debug.LEVEL_INFO, f"LEARN MODE PRESENTER: Handler found: {handler}", True) - debug.printMessage(debug.LEVEL_INFO, f"LEARN MODE PRESENTER: Handler description: {getattr(handler, 'description', 'No description')}", True) - debug.printMessage(debug.LEVEL_INFO, f"LEARN MODE PRESENTER: Handler learnModeEnabled: {getattr(handler, 'learnModeEnabled', 'No learnModeEnabled')}", True) - - if handler.learnModeEnabled and handler.description: - debug.printMessage(debug.LEVEL_INFO, f"LEARN MODE PRESENTER: Presenting message: {handler.description}", True) - cthulhu_state.activeScript.presentMessage(handler.description) - else: - debug.printMessage(debug.LEVEL_INFO, "LEARN MODE PRESENTER: Handler missing required properties for learn mode", True) - - return True - - def list_cthulhu_shortcuts(self, script, event=None): - """Shows a simple gui listing Cthulhu's bound commands.""" - - if event is None: - event = cthulhu_state.lastNonModifierKeyEvent - - layout = self.app.getSettingsManager().getSetting("keyboardLayout") - is_desktop = layout == settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP - - items = 0 - bindings = {} - if event is None or event.event_string == "F2": - bound = script.getLearnModePresenter().get_bindings().getBoundBindings() - bindings[guilabels.KB_GROUP_LEARN_MODE] = bound - items += len(bound) - - bound = script.getDefaultKeyBindings().getBoundBindings() - bindings[guilabels.KB_GROUP_DEFAULT] = bound - items += len(bound) - - bound = script.getWhereAmIPresenter().get_bindings(is_desktop).getBoundBindings() - bindings[guilabels.KB_GROUP_WHERE_AM_I] = bound - items += len(bound) - - bound = script.getSpeechAndVerbosityManager().get_bindings().getBoundBindings() - bindings[guilabels.KB_GROUP_SPEECH_VERBOSITY] = bound - items += len(bound) - - bound = script.getFlatReviewPresenter().get_bindings(is_desktop).getBoundBindings() - bindings[guilabels.KB_GROUP_FLAT_REVIEW] = bound - items += len(bound) - - bound = script.get_objectNavigator().get_bindings().getBoundBindings() - bindings[guilabels.KB_GROUP_OBJECT_NAVIGATION] = bound - items += len(bound) - - bound = script.getDateAndTimePresenter().get_bindings().getBoundBindings() - bindings[guilabels.KB_GROUP_DATE_AND_TIME] = bound - items += len(bound) - - bound = script.getNotificationPresenter().get_bindings().getBoundBindings() - bindings[guilabels.KB_GROUP_NOTIFICATIONS] = bound - items += len(bound) - - bound = script.getBookmarks().get_bindings().getBoundBindings() - bindings[guilabels.KB_GROUP_BOOKMARKS] = bound - items += len(bound) - - bound = script.getMouseReviewer().get_bindings().getBoundBindings() - bindings[guilabels.KB_GROUP_MOUSE_REVIEW] = bound - items += len(bound) - - bound = script.getActionPresenter().get_bindings().getBoundBindings() - bindings[guilabels.KB_GROUP_ACTIONS] = bound - items += len(bound) - - # Add plugin keybindings - try: - debug.printMessage(debug.LEVEL_INFO, "LEARN MODE PRESENTER: Getting plugin keybindings", True) - plugin_bindings = script.getPluginKeyBindings() - debug.printMessage(debug.LEVEL_INFO, f"LEARN MODE PRESENTER: Got plugin bindings object: {plugin_bindings}", True) - bound = plugin_bindings.getBoundBindings() - debug.printMessage(debug.LEVEL_INFO, f"LEARN MODE PRESENTER: Got {len(bound)} bound plugin keybindings", True) - if bound: - bindings["Plugins"] = bound - items += len(bound) - debug.printMessage(debug.LEVEL_INFO, f"LEARN MODE PRESENTER: Added {len(bound)} plugin keybindings to learn mode", True) - except Exception as e: - msg = f"LEARN MODE PRESENTER: Could not get plugin keybindings: {e}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - import traceback - debug.printMessage(debug.LEVEL_INFO, traceback.format_exc(), True) - - title = messages.shortcutsFoundCthulhu(items) - else: - app_name = AXObject.get_name(script.app) or messages.APPLICATION_NO_NAME - bound = script.getAppKeyBindings().getBoundBindings() - bound.extend(script.getToolkitKeyBindings().getBoundBindings()) - if bound: - bindings[app_name] = bound - title = messages.shortcutsFoundApp(len(bound), app_name) - - if not bindings: - script.presentMessage(title) - return True - - self.quit(script, event) - column_headers = [guilabels.KB_HEADER_FUNCTION, guilabels.KB_HEADER_KEY_BINDING] - self._gui = CommandListGUI(script, title, column_headers, bindings) - self._gui.show_gui() - return True - - def show_help(self, script=None, event=None, page=""): - """Displays Cthulhu's documentation.""" - - self.quit(script, event) - uri = "help:cthulhu" - if page: - uri += f"/{page}" - try: - Gtk.show_uri(Gdk.Screen.get_default(), uri, Gtk.get_current_event_time()) - return True - except GLib.GError as error: - msg = f"LEARN MODE PRESENTER: Failed to open help URI {uri}: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - - try: - Gio.AppInfo.launch_default_for_uri(uri, None) - return True - except GLib.GError as error: - msg = f"LEARN MODE PRESENTER: Failed to launch help URI {uri}: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - - if script: - script.presentMessage(messages.HELP_NOT_AVAILABLE) - return True - -class CommandListGUI: - """Shows a list of commands and their bindings.""" - - def __init__(self, script, title, column_headers, bindings_dict): - self._script = script - self._model = None - self._gui = self._create_dialog(title, column_headers, bindings_dict) - - def _create_dialog(self, title, column_headers, bindings_dict): - """Creates the commands-list dialog.""" - - dialog = Gtk.Dialog(title, - None, - Gtk.DialogFlags.MODAL, - (Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)) - dialog.set_default_size(1000, 800) - - grid = Gtk.Grid() - content_area = dialog.get_content_area() - content_area.add(grid) - - scrolled_window = Gtk.ScrolledWindow() - grid.add(scrolled_window) - - tree = Gtk.TreeView() - tree.set_hexpand(True) - tree.set_vexpand(True) - scrolled_window.add(tree) - - cols = len(column_headers) * [GObject.TYPE_STRING] - for i, header in enumerate(column_headers): - cell = Gtk.CellRendererText() - column = Gtk.TreeViewColumn(header, cell, text=i) - tree.append_column(column) - if header: - column.set_sort_column_id(i) - - self._model = Gtk.TreeStore(*cols) - - for group, bindings in bindings_dict.items(): - if not bindings: - continue - group_iter = self._model.append(None, [group, ""]) - for binding in bindings: - self._model.append(group_iter, [binding.handler.description, binding.asString()]) - - tree.set_model(self._model) - tree.expand_all() - dialog.connect("response", self.on_response) - return dialog - - def on_response(self, dialog, response): - """Handler for the 'response' signal.""" - - if response == Gtk.ResponseType.CLOSE: - self._gui.destroy() - return - - def show_gui(self): - """Shows the dialog.""" - - self._gui.show_all() - time_stamp = cthulhu_state.lastInputEvent.timestamp - if time_stamp == 0: - time_stamp = Gtk.get_current_event_time() - self._gui.present_with_time(time_stamp) - -_presenter = None -def getPresenter(): - """Returns the Learn Mode Presenter""" - - global _presenter - if _presenter is None: - from . import cthulhu - _presenter = LearnModePresenter(cthulhu.cthulhuApp) - return _presenter - diff --git a/src/cthulhu/liveregions.py b/src/cthulhu/liveregions.py deleted file mode 100644 index 5f9e773..0000000 --- a/src/cthulhu/liveregions.py +++ /dev/null @@ -1,611 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import bisect -import copy -import time -from gi.repository import GLib - -from . import cthulhu # Need access to cthulhuApp -from . import cmdnames -from . import chnames -from . import debug -from . import keybindings -from . import messages -from . import input_event -from . import cthulhu_state -from . import settings_manager -from .ax_collection import AXCollection -from .ax_object import AXObject -from .ax_text import AXText -from .ax_utilities_relation import AXUtilitiesRelation - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -# define 'live' property types -LIVE_OFF = -1 -LIVE_NONE = 0 -LIVE_POLITE = 1 -LIVE_ASSERTIVE = 2 -LIVE_RUDE = 3 - -# Seconds a message is held in the queue before it is discarded -MSG_KEEPALIVE_TIME = 45 # in seconds - -# The number of messages that are cached and can later be reviewed via -# LiveRegionManager.reviewLiveAnnouncement. -CACHE_SIZE = 9 # corresponds to one of nine key bindings - -class PriorityQueue: - """ This class represents a thread **UNSAFE** priority queue where priority - is determined by the given integer priority. The entries are also - maintained in chronological order. - - TODO: experiment with Queue.Queue to make thread safe - """ - def __init__(self): - self.queue = [] - - def enqueue(self, data, priority, obj): - """ Add a new element to the queue according to 1) priority and - 2) timestamp. """ - bisect.insort_left(self.queue, (priority, time.time(), data, obj)) - - def dequeue(self): - """get the highest priority element from the queue. """ - return self.queue.pop(0) - - def clear(self): - """ Clear the queue """ - self.queue = [] - - def purgeByKeepAlive(self): - """ Purge items from the queue that are older than the keepalive time """ - currenttime = time.time() - - def myfilter(item): - return item and item[1] + MSG_KEEPALIVE_TIME > currenttime - - self.queue = list(filter(myfilter, self.queue)) - - def purgeByPriority(self, priority): - """ Purge items from the queue that have a lower than or equal priority - than the given argument """ - - def myfilter(item): - return item and item[0] > priority - - self.queue = list(filter(myfilter, self.queue)) - - def __len__(self): - """ Return the length of the queue """ - return len(self.queue) - - -class LiveRegionManager: - def __init__(self, script): - self._script = script - # message priority queue - self.msg_queue = PriorityQueue() - - self.inputEventHandlers = self._getInputEventHandlers() - self.keyBindings = self._getKeyBindings() - - # This is temporary. - self.functions = [self.advancePoliteness, - self.setLivePolitenessOff, - self.toggleMonitoring, - self.reviewLiveAnnouncement] - - # Message cache. Used to store up to 9 previous messages so user can - # review if desired. - self.msg_cache = [] - - # User overrides for politeness settings. - self._politenessOverrides = None - self._restoreOverrides = None - - # last live obj to be announced - self.lastliveobj = None - - # Used to track whether a user wants to monitor all live regions - # Not to be confused with the global Gecko.liveRegionsOn which - # completely turns off live region support. This one is based on - # a user control by changing politeness levels to LIVE_OFF or back - # to the bookmark or markup politeness value. - self.monitoring = True - - # Set up politeness level overrides and subscribe to bookmarks - # for load and save user events. - # We are initialized after bookmarks so call the load handler once - # to get initialized. - # - self.bookmarkLoadHandler() - script.bookmarks.addSaveObserver(self.bookmarkSaveHandler) - script.bookmarks.addLoadObserver(self.bookmarkLoadHandler) - - def _getInputEventHandlers(self): - handlers = {} - - handlers["advanceLivePoliteness"] = \ - input_event.InputEventHandler( - self.advancePoliteness, - cmdnames.LIVE_REGIONS_ADVANCE_POLITENESS) - - handlers["setLivePolitenessOff"] = \ - input_event.InputEventHandler( - self.setLivePolitenessOff, - cmdnames.LIVE_REGIONS_SET_POLITENESS_OFF) - - handlers["monitorLiveRegions"] = \ - input_event.InputEventHandler( - self.toggleMonitoring, - cmdnames.LIVE_REGIONS_MONITOR) - - handlers["reviewLiveAnnouncement"] = \ - input_event.InputEventHandler( - self.reviewLiveAnnouncement, - cmdnames.LIVE_REGIONS_REVIEW) - - return handlers - - def _getKeyBindings(self): - keyBindings = keybindings.KeyBindings() - - keyBindings.add( - keybindings.KeyBinding( - "backslash", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self.inputEventHandlers.get("advanceLivePoliteness"))) - - keyBindings.add( - keybindings.KeyBinding( - "backslash", - keybindings.defaultModifierMask, - keybindings.SHIFT_MODIFIER_MASK, - self.inputEventHandlers.get("setLivePolitenessOff"))) - - keyBindings.add( - keybindings.KeyBinding( - "backslash", - keybindings.defaultModifierMask, - keybindings.CTHULHU_SHIFT_MODIFIER_MASK, - self.inputEventHandlers.get("monitorLiveRegions"))) - - for key in ["F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"]: - keyBindings.add( - keybindings.KeyBinding( - key, - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers.get("reviewLiveAnnouncement"))) - - return keyBindings - - def reset(self): - # First we will purge our politeness override dictionary of LIVE_NONE - # objects that are not registered for this page - newpoliteness = {} - currenturi = self._script.bookmarks.getURIKey() - for key, value in self._politenessOverrides.items(): - if key[0] == currenturi or value != LIVE_NONE: - newpoliteness[key] = value - self._politenessOverrides = newpoliteness - - def bookmarkSaveHandler(self): - """Bookmark save callback""" - self._script.bookmarks.saveBookmarksToDisk(self._politenessOverrides, - filename='politeness') - - def bookmarkLoadHandler(self): - """Bookmark load callback""" - # readBookmarksFromDisk() returns None on error. Just initialize to an - # empty dictionary if this is the case. - self._politenessOverrides = \ - self._script.bookmarks.readBookmarksFromDisk(filename='politeness') \ - or {} - - def handleEvent(self, event): - """Main live region event handler""" - politeness = self._getLiveType(event.source) - if politeness == LIVE_OFF: - return - if politeness == LIVE_NONE: - # All the 'registered' LIVE_NONE objects will be set to off - # if not monitoring. We will ignore LIVE_NONE objects that - # arrive after the user switches off monitoring. - if not self.monitoring: - return - elif politeness == LIVE_POLITE: - # Nothing to do for now - pass - elif politeness == LIVE_ASSERTIVE: - self.msg_queue.purgeByPriority(LIVE_POLITE) - elif politeness == LIVE_RUDE: - self.msg_queue.purgeByPriority(LIVE_ASSERTIVE) - - message = self._getMessage(event) - if message: - if len(self.msg_queue) == 0: - GLib.timeout_add(100, self.pumpMessages) - self.msg_queue.enqueue(message, politeness, event.source) - - def pumpMessages(self): - """ Main gobject callback for live region support. Handles both - purging the message queue and outputting any queued messages that - were queued up in the handleEvent() method. - """ - - if len(self.msg_queue) > 0: - debug.printMessage(debug.eventDebugLevel, "\nvvvvv PRESENT LIVE REGION MESSAGE vvvvv") - self.msg_queue.purgeByKeepAlive() - politeness, timestamp, message, obj = self.msg_queue.dequeue() - # Form output message. No need to repeat labels and content. - # TODO: really needs to be tested in real life cases. Perhaps - # a verbosity setting? - if message['labels'] == message['content']: - utts = message['content'] - else: - utts = message['labels'] + message['content'] - - if self.monitoring: - # Live region content is user-generated text, not system messages. - # Use resetStyles=False to preserve the user's punctuation settings. - self._script.presentMessage(utts, resetStyles=False) - else: - msg = "INFO: Not presenting message because monitoring is off" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - # set the last live obj to be announced - self.lastliveobj = obj - - # cache our message - self._cacheMessage(utts) - - # We still want to maintain our queue if we are not monitoring - if not self.monitoring: - self.msg_queue.purgeByKeepAlive() - - msg = f'LIVE REGIONS: messages in queue: {len(self.msg_queue)}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - debug.printMessage(debug.eventDebugLevel, "^^^^^ PRESENT LIVE REGION MESSAGE ^^^^^\n") - - # See you again soon, stay in event loop if we still have messages. - return len(self.msg_queue) > 0 - - def getLiveNoneObjects(self): - """Return the live objects that are registered and have a politeness - of LIVE_NONE. """ - retval = [] - currenturi = self._script.bookmarks.getURIKey() - for uri, objectid in self._politenessOverrides: - if uri == currenturi and isinstance(objectid, tuple): - retval.append(self._script.bookmarks.pathToObj(objectid)) - return retval - - def advancePoliteness(self, script, inputEvent): - """Advance the politeness level of the given object""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('inferLiveRegions'): - self._script.presentMessage(messages.LIVE_REGIONS_OFF) - return - - obj = cthulhu_state.locusOfFocus - objectid = self._get_objectId(obj) - uri = self._script.bookmarks.getURIKey() - - try: - # The current priority is either a previous override or the - # live property. If an exception is thrown, an override for - # this object has never occurred and the object does not have - # live markup. In either case, set the override to LIVE_NONE. - cur_priority = self._politenessOverrides[(uri, objectid)] - except KeyError: - cur_priority = self._liveStringToType(obj) - - if cur_priority == LIVE_OFF or cur_priority == LIVE_NONE: - self._politenessOverrides[(uri, objectid)] = LIVE_POLITE - self._script.presentMessage(messages.LIVE_REGIONS_LEVEL_POLITE) - elif cur_priority == LIVE_POLITE: - self._politenessOverrides[(uri, objectid)] = LIVE_ASSERTIVE - self._script.presentMessage(messages.LIVE_REGIONS_LEVEL_ASSERTIVE) - elif cur_priority == LIVE_ASSERTIVE: - self._politenessOverrides[(uri, objectid)] = LIVE_RUDE - self._script.presentMessage(messages.LIVE_REGIONS_LEVEL_RUDE) - elif cur_priority == LIVE_RUDE: - self._politenessOverrides[(uri, objectid)] = LIVE_OFF - self._script.presentMessage(messages.LIVE_REGIONS_LEVEL_OFF) - - - def goLastLiveRegion(self): - """Move the caret to the last announced live region and speak the - contents of that object""" - if self.lastliveobj: - self._script.utilities.setCaretPosition(self.lastliveobj, 0) - self._script.speakContents(self._script.utilities.get_objectContentsAtOffset( - self.lastliveobj, 0)) - - def reviewLiveAnnouncement(self, script, inputEvent): - """Speak the given number cached message""" - - msgnum = int(inputEvent.event_string[1:]) - if not cthulhu.cthulhuApp.settingsManager.getSetting('inferLiveRegions'): - self._script.presentMessage(messages.LIVE_REGIONS_OFF) - return - - if msgnum > len(self.msg_cache): - self._script.presentMessage(messages.LIVE_REGIONS_NO_MESSAGE) - else: - self._script.presentMessage(self.msg_cache[-msgnum]) - - def setLivePolitenessOff(self, script, inputEvent): - """User toggle to set all live regions to LIVE_OFF or back to their - original politeness.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('inferLiveRegions'): - self._script.presentMessage(messages.LIVE_REGIONS_OFF) - return - - # start at the document frame - docframe = self._script.utilities.documentFrame() - # get the URI of the page. It is used as a partial key. - uri = self._script.bookmarks.getURIKey() - - # The user is currently monitoring live regions but now wants to - # change all live region politeness on page to LIVE_OFF - if self.monitoring: - self._script.presentMessage(messages.LIVE_REGIONS_ALL_OFF) - self.msg_queue.clear() - - # First we'll save off a copy for quick restoration - self._restoreOverrides = copy.copy(self._politenessOverrides) - - # Set all politeness overrides to LIVE_OFF. - for override in self._politenessOverrides.keys(): - self._politenessOverrides[override] = LIVE_OFF - - # look through all the objects on the page and set/add to - # politeness overrides. This only adds live regions with good - # markup. - matches = self.getAllLiveRegions(docframe) - for match in matches: - objectid = self._get_objectId(match) - self._politenessOverrides[(uri, objectid)] = LIVE_OFF - - # Toggle our flag - self.monitoring = False - - # The user wants to restore politeness levels - else: - for key, value in self._restoreOverrides.items(): - self._politenessOverrides[key] = value - self._script.presentMessage(messages.LIVE_REGIONS_ALL_RESTORED) - # Toggle our flag - self.monitoring = True - - def getAllLiveRegions(self, document): - attrs = [] - levels = ["off", "polite", "assertive"] - for level in levels: - attrs.append('container-live:' + level) - - rule = AXCollection.create_match_rule(attributes=attrs) - result = AXCollection.get_all_matches(document, rule) - - msg = f'LIVE REGIONS: {len(result)} regions found' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return result - - def generateLiveRegionDescription(self, obj, **args): - """Used in conjunction with whereAmI to output description and - politeness of the given live region object""" - objectid = self._get_objectId(obj) - uri = self._script.bookmarks.getURIKey() - - results = [] - - # get the description if there is one. - describedBy = AXUtilitiesRelation.get_is_described_by(obj) - if describedBy: - targetobj = describedBy[0] - if AXObject.supports_text(targetobj): - # We will add on descriptions if they don't duplicate - # what's already in the object's description. - # See http://bugzilla.gnome.org/show_bug.cgi?id=568467 - # for more information. - # - description = AXText.get_all_text(targetobj) - if description.strip() != AXObject.get_description(obj).strip(): - results.append(description) - - # get the politeness level as a string - try: - livepriority = self._politenessOverrides[(uri, objectid)] - liveprioritystr = self._liveTypeToString(livepriority) - except KeyError: - liveprioritystr = 'none' - - # We will only output useful information - # - if results or liveprioritystr != 'none': - results.append(messages.LIVE_REGIONS_LEVEL % liveprioritystr) - - return results - - def _findContainer(self, obj): - def isContainer(x): - return self._getAttrDictionary(x).get('atomic') - - if isContainer(obj): - return obj - - return AXObject.find_ancestor(obj, isContainer) - - def _getMessage(self, event): - """Gets the message associated with a given live event.""" - attrs = self._getAttrDictionary(event.source) - content = "" - labels = "" - - # A message is divided into two parts: labels and content. We - # will first try to get the content. If there is None, - # assume it is an invalid message and return None - if event.type.startswith('object:children-changed:add'): - if attrs.get('container-atomic') == 'true': - content = self._script.utilities.expandEOCs(event.source) - else: - content = self._script.utilities.expandEOCs(event.any_data) - - elif event.type.startswith('object:text-changed:insert'): - if attrs.get('container-atomic') != 'true': - if "\ufffc" not in event.any_data: - content = event.any_data - else: - content = self._script.utilities.expandEOCs( - event.source, event.detail1, event.detail1 + event.detail2) - else: - container = self._findContainer(event.source) - content = self._script.utilities.expandEOCs(container) - - if not content: - return None - - content = content.strip() - if len(content) == 1: - content = chnames.getCharacterName(content) - - # Proper live regions typically come with proper aria labels. These - # labels are typically exposed as names. Failing that, descriptions. - # Looking for actual labels seems a non-performant waste of time. - name = (AXObject.get_name(event.source) or AXObject.get_description(event.source)).strip() - if name and name != content: - labels = name - - # instantly send out notify messages - if attrs.get('channel') == 'notify': - utts = labels + content - self._script.presentationInterrupt() - self._script.presentMessage(utts) - return None - - return {'content':[content], 'labels':[labels]} - - def flushMessages(self): - self.msg_queue.clear() - - def _cacheMessage(self, utts): - """Cache a message in our cache list of length CACHE_SIZE""" - self.msg_cache.append(utts) - if len(self.msg_cache) > CACHE_SIZE: - self.msg_cache.pop(0) - - def _getLiveType(self, obj): - """Returns the live politeness setting for a given object. Also, - registers LIVE_NONE objects in politeness overrides when monitoring.""" - objectid = self._get_objectId(obj) - uri = self._script.bookmarks.getURIKey() - if (uri, objectid) in self._politenessOverrides: - # look to see if there is a user politeness override - return self._politenessOverrides[(uri, objectid)] - else: - livetype = self._liveStringToType(obj) - # We'll save off a reference to LIVE_NONE if we are monitoring - # to give the user a chance to change the politeness level. It - # is done here for performance sake (objectid, uri are expensive) - if livetype == LIVE_NONE and self.monitoring: - self._politenessOverrides[(uri, objectid)] = livetype - return livetype - - def _get_objectId(self, obj): - """Returns the HTML 'id' or a path to the object is an HTML id is - unavailable""" - attrs = self._getAttrDictionary(obj) - if attrs is None: - return self._getPath(obj) - try: - return attrs['id'] - except KeyError: - return self._getPath(obj) - - def _liveStringToType(self, obj, attributes=None): - """Returns the politeness enum for a given object""" - attrs = attributes or self._getAttrDictionary(obj) - try: - if attrs['container-live'] == 'off': - return LIVE_OFF - elif attrs['container-live'] == 'polite': - return LIVE_POLITE - elif attrs['container-live'] == 'assertive': - return LIVE_ASSERTIVE - elif attrs['container-live'] == 'rude': - return LIVE_RUDE - else: - return LIVE_NONE - except KeyError: - return LIVE_NONE - - def _liveTypeToString(self, politeness): - """Returns the politeness level as a string given a politeness enum""" - if politeness == LIVE_OFF: - return 'off' - elif politeness == LIVE_POLITE: - return 'polite' - elif politeness == LIVE_ASSERTIVE: - return 'assertive' - elif politeness == LIVE_RUDE: - return 'rude' - elif politeness == LIVE_NONE: - return 'none' - else: - return 'unknown' - - def _getAttrDictionary(self, obj): - return self._script.utilities.objectAttributes(obj) - - def _getPath(self, obj): - """ Returns, as a tuple of integers, the path from the given object - to the document frame.""" - docframe = self._script.utilities.documentFrame() - path = [] - while True: - if obj == docframe or AXObject.get_parent(obj) is None: - path.reverse() - return tuple(path) - path.append(AXObject.get_index_in_parent(obj)) - obj = AXObject.get_parent(obj) - - def toggleMonitoring(self, script, inputEvent): - if not cthulhu.cthulhuApp.settingsManager.getSetting('inferLiveRegions'): - cthulhu.cthulhuApp.settingsManager.setSetting('inferLiveRegions', True) - self._script.presentMessage(messages.LIVE_REGIONS_MONITORING_ON) - else: - cthulhu.cthulhuApp.settingsManager.setSetting('inferLiveRegions', False) - self.flushMessages() - self._script.presentMessage(messages.LIVE_REGIONS_MONITORING_OFF) diff --git a/src/cthulhu/logger.py b/src/cthulhu/logger.py deleted file mode 100644 index 2b85eff..0000000 --- a/src/cthulhu/logger.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Output logger for regression testing.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2012 Igalia, S.L." -__license__ = "LGPL" - -import io -import logging - -class Logger: - - def __init__(self): - self._logs = {} - - def getLogNames(self): - return self._logs.keys() - - def newLog(self, name, level=logging.INFO): - log = logging.getLogger(name) - log.setLevel(level) - - handler = logging.StreamHandler(io.StringIO()) - handler.setFormatter(logging.Formatter('%(message)s')) - log.addHandler(handler) - - self._logs[name] = handler.stream - return log - - def clearLog(self, name): - stream = self._logs.get(name) - if stream: - stream.truncate(0) - stream.seek(0) - - def getLogContent(self, name): - stream = self._logs.get(name) - if stream: - return stream.getvalue() - - return "" - - def shutdown(self): - for name in self._logs.keys(): - stream = self._logs.get(name) - stream.close() - diff --git a/src/cthulhu/mako_notification_monitor.py b/src/cthulhu/mako_notification_monitor.py deleted file mode 100644 index 066b102..0000000 --- a/src/cthulhu/mako_notification_monitor.py +++ /dev/null @@ -1,419 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# - -"""Core support for speaking mako notifications via D-Bus.""" - -from __future__ import annotations - -import html -import re -from typing import Any, Optional - -from gi.repository import Gio, GLib - -from . import cthulhu_state -from . import debug -from . import messages -from . import notification_presenter -from . import settings - - -class MakoNotificationMonitor: - """Tracks mako's live D-Bus queue and presents new notifications.""" - - BUS_NAME = "org.freedesktop.Notifications" - OBJECT_PATH = "/fr/emersion/Mako" - INTERFACE_NAME = "fr.emersion.Mako" - SOURCE_NAME = "mako" - - def __init__(self, app) -> None: - self._app = app - self._presenter = None - self._connection: Optional[Gio.DBusConnection] = None - self._watch_id: int = 0 - self._properties_subscription_id: int = 0 - self._known_ids: set[int] = set() - self._is_running: bool = False - self._is_available: bool = False - self._generation: int = 0 - self._tag_pattern = re.compile(r"<[^>]+>") - self._whitespace_pattern = re.compile(r"\s+") - - def start(self) -> None: - """Starts watching the session bus for mako.""" - - if self._is_running: - return - - try: - self._connection = Gio.bus_get_sync(Gio.BusType.SESSION, None) - except Exception as error: - msg = f"MAKO MONITOR: Failed to connect to session bus: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - self._watch_id = Gio.bus_watch_name_on_connection( - self._connection, - self.BUS_NAME, - Gio.BusNameWatcherFlags.NONE, - self._on_name_appeared, - self._on_name_vanished, - ) - self._is_running = True - debug.printMessage(debug.LEVEL_INFO, "MAKO MONITOR: Started", True) - - def stop(self, reset_live_state: bool = True) -> None: - """Stops watching the session bus for mako.""" - - if self._properties_subscription_id and self._connection is not None: - self._connection.signal_unsubscribe(self._properties_subscription_id) - self._properties_subscription_id = 0 - - if self._watch_id: - Gio.bus_unwatch_name(self._watch_id) - self._watch_id = 0 - - if reset_live_state: - self._get_presenter().mark_source_unavailable(self.SOURCE_NAME) - - self._known_ids.clear() - self._is_available = False - self._is_running = False - self._connection = None - debug.printMessage(debug.LEVEL_INFO, "MAKO MONITOR: Stopped", True) - - def refresh(self, announce_new: bool = False) -> bool: - """Refreshes mako's live queue and optionally speaks new notifications.""" - - if self._connection is None or not self._is_available: - return False - - live_notifications = self._fetch_live_notifications() - if live_notifications is None: - return False - - self._sync_notifications(live_notifications, announce_new) - return True - - def dismiss_notification(self, notification_id: int) -> bool: - """Dismisses a live mako notification by ID.""" - - if self._connection is None or not self._is_available: - return False - - try: - options = { - "id": GLib.Variant("u", notification_id), - "group": GLib.Variant("b", False), - "history": GLib.Variant("b", True), - "all": GLib.Variant("b", False), - } - self._connection.call_sync( - self.BUS_NAME, - self.OBJECT_PATH, - self.INTERFACE_NAME, - "DismissNotifications", - GLib.Variant("(a{sv})", (options,)), - None, - Gio.DBusCallFlags.NONE, - -1, - None, - ) - except Exception as error: - msg = f"MAKO MONITOR: Failed to dismiss notification {notification_id}: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - self.refresh(announce_new=False) - return True - - def invoke_action(self, notification_id: int, action_key: str) -> bool: - """Invokes a live mako notification action.""" - - if self._connection is None or not self._is_available: - return False - - try: - self._connection.call_sync( - self.BUS_NAME, - self.OBJECT_PATH, - self.INTERFACE_NAME, - "InvokeAction", - GLib.Variant("(us)", (notification_id, action_key)), - None, - Gio.DBusCallFlags.NONE, - -1, - None, - ) - except Exception as error: - msg = ( - f"MAKO MONITOR: Failed to invoke action {action_key} " - f"for notification {notification_id}: {error}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - self.refresh(announce_new=False) - return True - - def is_current_entry(self, entry) -> bool: - """Returns True if entry belongs to the current mako session.""" - - return ( - self._is_available - and entry.source == self.SOURCE_NAME - and entry.source_generation == self._generation - ) - - def get_generation(self) -> int: - """Returns the current mako session generation.""" - - return self._generation - - def _get_presenter(self): - presenter = self._presenter or notification_presenter.getPresenter() - if presenter is not self._presenter: - self._presenter = presenter - - if getattr(presenter, "_mako_monitor", None) is not self: - presenter.set_mako_monitor(self) - - return presenter - - def _on_name_appeared( - self, - connection: Gio.DBusConnection, - name: str, - name_owner: str, - user_data: Optional[Any] = None, - ) -> None: - msg = f"MAKO MONITOR: {name} appeared as {name_owner}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self._connection = connection - self._subscribe_to_properties() - - live_notifications = self._fetch_live_notifications() - if live_notifications is None: - self._unsubscribe_from_properties() - self._get_presenter().mark_source_unavailable(self.SOURCE_NAME) - self._known_ids.clear() - self._is_available = False - debug.printMessage( - debug.LEVEL_INFO, - "MAKO MONITOR: Notification daemon is not exposing the mako interface", - True, - ) - return - - self._generation += 1 - self._is_available = True - self._known_ids.clear() - self._sync_notifications(live_notifications, announce_new=False) - - def _on_name_vanished( - self, - connection: Gio.DBusConnection, - name: str, - user_data: Optional[Any] = None, - ) -> None: - msg = f"MAKO MONITOR: {name} vanished" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._unsubscribe_from_properties() - self._get_presenter().mark_source_unavailable(self.SOURCE_NAME) - self._known_ids.clear() - self._is_available = False - - def _subscribe_to_properties(self) -> None: - if self._connection is None or self._properties_subscription_id: - return - - self._properties_subscription_id = self._connection.signal_subscribe( - self.BUS_NAME, - "org.freedesktop.DBus.Properties", - "PropertiesChanged", - self.OBJECT_PATH, - self.INTERFACE_NAME, - Gio.DBusSignalFlags.NONE, - self._on_properties_changed, - ) - - def _unsubscribe_from_properties(self) -> None: - if self._connection is None or not self._properties_subscription_id: - return - - self._connection.signal_unsubscribe(self._properties_subscription_id) - self._properties_subscription_id = 0 - - def _on_properties_changed( - self, - connection: Gio.DBusConnection, - sender_name: Optional[str], - object_path: str, - interface_name: str, - signal_name: str, - parameters: GLib.Variant, - user_data: Optional[Any] = None, - ) -> None: - del connection, sender_name, object_path, interface_name, signal_name, parameters, user_data - self.refresh(announce_new=True) - - def _fetch_live_notifications(self) -> Optional[list[dict[str, Any]]]: - if self._connection is None: - return None - - try: - reply = self._connection.call_sync( - self.BUS_NAME, - self.OBJECT_PATH, - self.INTERFACE_NAME, - "ListNotifications", - None, - None, - Gio.DBusCallFlags.NONE, - -1, - None, - ) - except Exception as error: - msg = f"MAKO MONITOR: Failed to list notifications: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return None - - try: - unpacked = reply.unpack() - except Exception as error: - msg = f"MAKO MONITOR: Failed to unpack notification list: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return None - - if not unpacked: - return [] - - return list(unpacked[0]) - - def _sync_notifications( - self, - live_notifications: list[dict[str, Any]], - announce_new: bool, - ) -> None: - live_by_id: dict[int, dict[str, Any]] = {} - ordered_ids: list[int] = [] - - for notification in live_notifications: - parsed = self._parse_notification(notification) - notification_id = parsed.get("notification_id") - if notification_id is None: - continue - live_by_id[notification_id] = parsed - ordered_ids.append(notification_id) - - self._get_presenter().sync_live_notifications( - self.SOURCE_NAME, - live_by_id, - self._generation, - ) - - if announce_new: - for notification_id in ordered_ids: - if notification_id in self._known_ids: - continue - self._announce_notification(live_by_id[notification_id]) - - self._known_ids = set(live_by_id) - - def _announce_notification(self, notification: dict[str, Any]) -> None: - message = notification.get("message") or "" - if not message: - return - - self._get_presenter().save_notification( - message, - source=self.SOURCE_NAME, - source_generation=self._generation, - notification_id=notification.get("notification_id"), - live=True, - actions=notification.get("actions"), - app_name=notification.get("app_name", ""), - summary=notification.get("summary", ""), - body=notification.get("body", ""), - urgency=notification.get("urgency", -1), - desktop_entry=notification.get("desktop_entry", ""), - ) - - script = cthulhu_state.activeScript or self._app.getScriptManager().get_default_script() - if script is None: - return - - voice = script.speechGenerator.voice(string=message) - script.speakMessage(message, voice=voice) - script.displayBrailleMessage(message, flashTime=settings.brailleFlashTime) - - def _parse_notification(self, notification: dict[str, Any]) -> dict[str, Any]: - actions = notification.get("actions") or {} - if not isinstance(actions, dict): - actions = {} - - app_name = self._normalize_text(notification.get("app-name", "")) - summary = self._normalize_text(notification.get("summary", "")) - body = self._normalize_text(notification.get("body", "")) - desktop_entry = self._normalize_text(notification.get("desktop-entry", "")) - urgency = notification.get("urgency", -1) - notification_id = notification.get("id") - - return { - "notification_id": notification_id if isinstance(notification_id, int) else None, - "actions": { - str(key): self._normalize_text(value) or str(key) - for key, value in actions.items() - }, - "app_name": app_name, - "summary": summary, - "body": body, - "urgency": urgency if isinstance(urgency, int) else -1, - "desktop_entry": desktop_entry, - "message": self._build_message(app_name, summary, body, desktop_entry), - } - - def _build_message( - self, - app_name: str, - summary: str, - body: str, - desktop_entry: str, - ) -> str: - parts = [messages.NOTIFICATION] - if summary: - parts.append(summary) - if body and body != summary: - parts.append(body) - if len(parts) == 1: - fallback = app_name or desktop_entry - if fallback: - parts.append(fallback) - return " ".join(part for part in parts if part).strip() - - def _normalize_text(self, text: Any) -> str: - if not isinstance(text, str): - return "" - - text = html.unescape(text) - text = self._tag_pattern.sub(" ", text) - text = self._whitespace_pattern.sub(" ", text) - return text.strip() diff --git a/src/cthulhu/mathsymbols.py b/src/cthulhu/mathsymbols.py deleted file mode 100644 index d3f482c..0000000 --- a/src/cthulhu/mathsymbols.py +++ /dev/null @@ -1,2332 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Igalia, S.L." -__license__ = "LGPL" - -import re -import unicodedata - -from .cthulhu_i18n import C_ - -fallbackOnUnicodeData = False - -SPEAK_NEVER = 1 -SPEAK_ALWAYS = 2 -SPEAK_FOR_CHARS = 3 -speakStyle = SPEAK_ALWAYS - -_all = {} -_alnum = {} -_arrows = {} -_operators = {} -_shapes = {} -_combining = {} - -# Note that the following are to help us identify what is likely a math symbol -# (as opposed to one serving the function of an image in "This way up.") -_arrows.update(dict.fromkeys(map(chr, range(0x2190, 0x2200)))) -_arrows.update(dict.fromkeys(map(chr, range(0x2750, 0x2800)))) -_arrows.update(dict.fromkeys(map(chr, range(0x2b30, 0x2b50)))) -_operators.update(dict.fromkeys(map(chr, range(0x2220, 0x2300)))) -_operators.update(dict.fromkeys(map(chr, range(0x2a00, 0x2b00)))) -_shapes.update(dict.fromkeys(map(chr, range(0x25a0, 0x2600)))) - -# Unicode has a huge number of individual symbols to include styles, such as -# bold, italic, double-struck, etc. These are so far not supported by speech -# synthesizers. So we'll maintain a dictionary of equivalent symbols which -# speech synthesizers should know along with lists of the various styles. -_alnum['\u2102'] = 'C' -_alnum['\u210a'] = 'g' -_alnum['\u210b'] = 'H' -_alnum['\u210c'] = 'H' -_alnum['\u210d'] = 'H' -_alnum['\u210e'] = 'h' -_alnum['\u2110'] = 'I' -_alnum['\u2111'] = 'I' -_alnum['\u2112'] = 'L' -_alnum['\u2113'] = 'l' -_alnum['\u2115'] = 'N' -_alnum['\u2119'] = 'P' -_alnum['\u211a'] = 'Q' -_alnum['\u211b'] = 'R' -_alnum['\u211c'] = 'R' -_alnum['\u211d'] = 'R' -_alnum['\u2124'] = 'Z' -_alnum['\u2128'] = 'Z' -_alnum['\u212c'] = 'B' -_alnum['\u212d'] = 'C' -_alnum['\u212f'] = 'e' -_alnum['\u2130'] = 'E' -_alnum['\u2131'] = 'F' -_alnum['\u2133'] = 'M' -_alnum['\u2134'] = 'o' -_alnum['\U0001d400'] = 'A' -_alnum['\U0001d401'] = 'B' -_alnum['\U0001d402'] = 'C' -_alnum['\U0001d403'] = 'D' -_alnum['\U0001d404'] = 'E' -_alnum['\U0001d405'] = 'F' -_alnum['\U0001d406'] = 'G' -_alnum['\U0001d407'] = 'H' -_alnum['\U0001d408'] = 'I' -_alnum['\U0001d409'] = 'J' -_alnum['\U0001d40a'] = 'K' -_alnum['\U0001d40b'] = 'L' -_alnum['\U0001d40c'] = 'M' -_alnum['\U0001d40d'] = 'N' -_alnum['\U0001d40e'] = 'O' -_alnum['\U0001d40f'] = 'P' -_alnum['\U0001d410'] = 'Q' -_alnum['\U0001d411'] = 'R' -_alnum['\U0001d412'] = 'S' -_alnum['\U0001d413'] = 'T' -_alnum['\U0001d414'] = 'U' -_alnum['\U0001d415'] = 'V' -_alnum['\U0001d416'] = 'W' -_alnum['\U0001d417'] = 'X' -_alnum['\U0001d418'] = 'Y' -_alnum['\U0001d419'] = 'Z' -_alnum['\U0001d41a'] = 'a' -_alnum['\U0001d41b'] = 'b' -_alnum['\U0001d41c'] = 'c' -_alnum['\U0001d41d'] = 'd' -_alnum['\U0001d41e'] = 'e' -_alnum['\U0001d41f'] = 'f' -_alnum['\U0001d420'] = 'g' -_alnum['\U0001d421'] = 'h' -_alnum['\U0001d422'] = 'i' -_alnum['\U0001d423'] = 'j' -_alnum['\U0001d424'] = 'k' -_alnum['\U0001d425'] = 'l' -_alnum['\U0001d426'] = 'm' -_alnum['\U0001d427'] = 'n' -_alnum['\U0001d428'] = 'o' -_alnum['\U0001d429'] = 'p' -_alnum['\U0001d42a'] = 'q' -_alnum['\U0001d42b'] = 'r' -_alnum['\U0001d42c'] = 's' -_alnum['\U0001d42d'] = 't' -_alnum['\U0001d42e'] = 'u' -_alnum['\U0001d42f'] = 'v' -_alnum['\U0001d430'] = 'w' -_alnum['\U0001d431'] = 'x' -_alnum['\U0001d432'] = 'y' -_alnum['\U0001d433'] = 'z' -_alnum['\U0001d434'] = 'A' -_alnum['\U0001d435'] = 'B' -_alnum['\U0001d436'] = 'C' -_alnum['\U0001d437'] = 'D' -_alnum['\U0001d438'] = 'E' -_alnum['\U0001d439'] = 'F' -_alnum['\U0001d43a'] = 'G' -_alnum['\U0001d43b'] = 'H' -_alnum['\U0001d43c'] = 'I' -_alnum['\U0001d43d'] = 'J' -_alnum['\U0001d43e'] = 'K' -_alnum['\U0001d43f'] = 'L' -_alnum['\U0001d440'] = 'M' -_alnum['\U0001d441'] = 'N' -_alnum['\U0001d442'] = 'O' -_alnum['\U0001d443'] = 'P' -_alnum['\U0001d444'] = 'Q' -_alnum['\U0001d445'] = 'R' -_alnum['\U0001d446'] = 'S' -_alnum['\U0001d447'] = 'T' -_alnum['\U0001d448'] = 'U' -_alnum['\U0001d449'] = 'V' -_alnum['\U0001d44a'] = 'W' -_alnum['\U0001d44b'] = 'X' -_alnum['\U0001d44c'] = 'Y' -_alnum['\U0001d44d'] = 'Z' -_alnum['\U0001d44e'] = 'a' -_alnum['\U0001d44f'] = 'b' -_alnum['\U0001d450'] = 'c' -_alnum['\U0001d451'] = 'd' -_alnum['\U0001d452'] = 'e' -_alnum['\U0001d453'] = 'f' -_alnum['\U0001d454'] = 'g' -_alnum['\U0001d456'] = 'i' -_alnum['\U0001d457'] = 'j' -_alnum['\U0001d458'] = 'k' -_alnum['\U0001d459'] = 'l' -_alnum['\U0001d45a'] = 'm' -_alnum['\U0001d45b'] = 'n' -_alnum['\U0001d45c'] = 'o' -_alnum['\U0001d45d'] = 'p' -_alnum['\U0001d45e'] = 'q' -_alnum['\U0001d45f'] = 'r' -_alnum['\U0001d460'] = 's' -_alnum['\U0001d461'] = 't' -_alnum['\U0001d462'] = 'u' -_alnum['\U0001d463'] = 'v' -_alnum['\U0001d464'] = 'w' -_alnum['\U0001d465'] = 'x' -_alnum['\U0001d466'] = 'y' -_alnum['\U0001d467'] = 'z' -_alnum['\U0001d468'] = 'A' -_alnum['\U0001d469'] = 'B' -_alnum['\U0001d46a'] = 'C' -_alnum['\U0001d46b'] = 'D' -_alnum['\U0001d46c'] = 'E' -_alnum['\U0001d46d'] = 'F' -_alnum['\U0001d46e'] = 'G' -_alnum['\U0001d46f'] = 'H' -_alnum['\U0001d470'] = 'I' -_alnum['\U0001d471'] = 'J' -_alnum['\U0001d472'] = 'K' -_alnum['\U0001d473'] = 'L' -_alnum['\U0001d474'] = 'M' -_alnum['\U0001d475'] = 'N' -_alnum['\U0001d476'] = 'O' -_alnum['\U0001d477'] = 'P' -_alnum['\U0001d478'] = 'Q' -_alnum['\U0001d479'] = 'R' -_alnum['\U0001d47a'] = 'S' -_alnum['\U0001d47b'] = 'T' -_alnum['\U0001d47c'] = 'U' -_alnum['\U0001d47d'] = 'V' -_alnum['\U0001d47e'] = 'W' -_alnum['\U0001d47f'] = 'X' -_alnum['\U0001d480'] = 'Y' -_alnum['\U0001d481'] = 'Z' -_alnum['\U0001d482'] = 'a' -_alnum['\U0001d483'] = 'b' -_alnum['\U0001d484'] = 'c' -_alnum['\U0001d485'] = 'd' -_alnum['\U0001d486'] = 'e' -_alnum['\U0001d487'] = 'f' -_alnum['\U0001d488'] = 'g' -_alnum['\U0001d489'] = 'h' -_alnum['\U0001d48a'] = 'i' -_alnum['\U0001d48b'] = 'j' -_alnum['\U0001d48c'] = 'k' -_alnum['\U0001d48d'] = 'l' -_alnum['\U0001d48e'] = 'm' -_alnum['\U0001d48f'] = 'n' -_alnum['\U0001d490'] = 'o' -_alnum['\U0001d491'] = 'p' -_alnum['\U0001d492'] = 'q' -_alnum['\U0001d493'] = 'r' -_alnum['\U0001d494'] = 's' -_alnum['\U0001d495'] = 't' -_alnum['\U0001d496'] = 'u' -_alnum['\U0001d497'] = 'v' -_alnum['\U0001d498'] = 'w' -_alnum['\U0001d499'] = 'x' -_alnum['\U0001d49a'] = 'y' -_alnum['\U0001d49b'] = 'z' -_alnum['\U0001d49c'] = 'A' -_alnum['\U0001d49e'] = 'C' -_alnum['\U0001d49f'] = 'D' -_alnum['\U0001d4a2'] = 'G' -_alnum['\U0001d4a5'] = 'J' -_alnum['\U0001d4a6'] = 'K' -_alnum['\U0001d4a9'] = 'N' -_alnum['\U0001d4aa'] = 'O' -_alnum['\U0001d4ab'] = 'P' -_alnum['\U0001d4ac'] = 'Q' -_alnum['\U0001d4ae'] = 'S' -_alnum['\U0001d4af'] = 'T' -_alnum['\U0001d4b0'] = 'U' -_alnum['\U0001d4b1'] = 'V' -_alnum['\U0001d4b2'] = 'W' -_alnum['\U0001d4b3'] = 'X' -_alnum['\U0001d4b4'] = 'Y' -_alnum['\U0001d4b5'] = 'Z' -_alnum['\U0001d4b6'] = 'a' -_alnum['\U0001d4b7'] = 'b' -_alnum['\U0001d4b8'] = 'c' -_alnum['\U0001d4b9'] = 'd' -_alnum['\U0001d4bb'] = 'f' -_alnum['\U0001d4bd'] = 'h' -_alnum['\U0001d4be'] = 'i' -_alnum['\U0001d4bf'] = 'j' -_alnum['\U0001d4c0'] = 'k' -_alnum['\U0001d4c1'] = 'l' -_alnum['\U0001d4c2'] = 'm' -_alnum['\U0001d4c3'] = 'n' -_alnum['\U0001d4c5'] = 'p' -_alnum['\U0001d4c6'] = 'q' -_alnum['\U0001d4c7'] = 'r' -_alnum['\U0001d4c8'] = 's' -_alnum['\U0001d4c9'] = 't' -_alnum['\U0001d4ca'] = 'u' -_alnum['\U0001d4cb'] = 'v' -_alnum['\U0001d4cc'] = 'w' -_alnum['\U0001d4cd'] = 'x' -_alnum['\U0001d4ce'] = 'y' -_alnum['\U0001d4cf'] = 'z' -_alnum['\U0001d4d0'] = 'A' -_alnum['\U0001d4d1'] = 'B' -_alnum['\U0001d4d2'] = 'C' -_alnum['\U0001d4d3'] = 'D' -_alnum['\U0001d4d4'] = 'E' -_alnum['\U0001d4d5'] = 'F' -_alnum['\U0001d4d6'] = 'G' -_alnum['\U0001d4d7'] = 'H' -_alnum['\U0001d4d8'] = 'I' -_alnum['\U0001d4d9'] = 'J' -_alnum['\U0001d4da'] = 'K' -_alnum['\U0001d4db'] = 'L' -_alnum['\U0001d4dc'] = 'M' -_alnum['\U0001d4dd'] = 'N' -_alnum['\U0001d4de'] = 'O' -_alnum['\U0001d4df'] = 'P' -_alnum['\U0001d4e0'] = 'Q' -_alnum['\U0001d4e1'] = 'R' -_alnum['\U0001d4e2'] = 'S' -_alnum['\U0001d4e3'] = 'T' -_alnum['\U0001d4e4'] = 'U' -_alnum['\U0001d4e5'] = 'V' -_alnum['\U0001d4e6'] = 'W' -_alnum['\U0001d4e7'] = 'X' -_alnum['\U0001d4e8'] = 'Y' -_alnum['\U0001d4e9'] = 'Z' -_alnum['\U0001d4ea'] = 'a' -_alnum['\U0001d4eb'] = 'b' -_alnum['\U0001d4ec'] = 'c' -_alnum['\U0001d4ed'] = 'd' -_alnum['\U0001d4ee'] = 'e' -_alnum['\U0001d4ef'] = 'f' -_alnum['\U0001d4f0'] = 'g' -_alnum['\U0001d4f1'] = 'h' -_alnum['\U0001d4f2'] = 'i' -_alnum['\U0001d4f3'] = 'j' -_alnum['\U0001d4f4'] = 'k' -_alnum['\U0001d4f5'] = 'l' -_alnum['\U0001d4f6'] = 'm' -_alnum['\U0001d4f7'] = 'n' -_alnum['\U0001d4f8'] = 'o' -_alnum['\U0001d4f9'] = 'p' -_alnum['\U0001d4fa'] = 'q' -_alnum['\U0001d4fb'] = 'r' -_alnum['\U0001d4fc'] = 's' -_alnum['\U0001d4fd'] = 't' -_alnum['\U0001d4fe'] = 'u' -_alnum['\U0001d4ff'] = 'v' -_alnum['\U0001d500'] = 'w' -_alnum['\U0001d501'] = 'x' -_alnum['\U0001d502'] = 'y' -_alnum['\U0001d503'] = 'z' -_alnum['\U0001d504'] = 'A' -_alnum['\U0001d505'] = 'B' -_alnum['\U0001d507'] = 'D' -_alnum['\U0001d508'] = 'E' -_alnum['\U0001d509'] = 'F' -_alnum['\U0001d50a'] = 'G' -_alnum['\U0001d50d'] = 'J' -_alnum['\U0001d50e'] = 'K' -_alnum['\U0001d50f'] = 'L' -_alnum['\U0001d510'] = 'M' -_alnum['\U0001d511'] = 'N' -_alnum['\U0001d512'] = 'O' -_alnum['\U0001d513'] = 'P' -_alnum['\U0001d514'] = 'Q' -_alnum['\U0001d516'] = 'S' -_alnum['\U0001d517'] = 'T' -_alnum['\U0001d518'] = 'U' -_alnum['\U0001d519'] = 'V' -_alnum['\U0001d51a'] = 'W' -_alnum['\U0001d51b'] = 'X' -_alnum['\U0001d51c'] = 'Y' -_alnum['\U0001d51e'] = 'a' -_alnum['\U0001d51f'] = 'b' -_alnum['\U0001d520'] = 'c' -_alnum['\U0001d521'] = 'd' -_alnum['\U0001d522'] = 'e' -_alnum['\U0001d523'] = 'f' -_alnum['\U0001d524'] = 'g' -_alnum['\U0001d525'] = 'h' -_alnum['\U0001d526'] = 'i' -_alnum['\U0001d527'] = 'j' -_alnum['\U0001d528'] = 'k' -_alnum['\U0001d529'] = 'l' -_alnum['\U0001d52a'] = 'm' -_alnum['\U0001d52b'] = 'n' -_alnum['\U0001d52c'] = 'o' -_alnum['\U0001d52d'] = 'p' -_alnum['\U0001d52e'] = 'q' -_alnum['\U0001d52f'] = 'r' -_alnum['\U0001d530'] = 's' -_alnum['\U0001d531'] = 't' -_alnum['\U0001d532'] = 'u' -_alnum['\U0001d533'] = 'v' -_alnum['\U0001d534'] = 'w' -_alnum['\U0001d535'] = 'x' -_alnum['\U0001d536'] = 'y' -_alnum['\U0001d537'] = 'z' -_alnum['\U0001d538'] = 'A' -_alnum['\U0001d539'] = 'B' -_alnum['\U0001d53b'] = 'D' -_alnum['\U0001d53c'] = 'E' -_alnum['\U0001d53d'] = 'F' -_alnum['\U0001d53e'] = 'G' -_alnum['\U0001d540'] = 'I' -_alnum['\U0001d541'] = 'J' -_alnum['\U0001d542'] = 'K' -_alnum['\U0001d543'] = 'L' -_alnum['\U0001d544'] = 'M' -_alnum['\U0001d546'] = 'O' -_alnum['\U0001d54a'] = 'S' -_alnum['\U0001d54b'] = 'T' -_alnum['\U0001d54c'] = 'U' -_alnum['\U0001d54d'] = 'V' -_alnum['\U0001d54e'] = 'W' -_alnum['\U0001d54f'] = 'X' -_alnum['\U0001d550'] = 'Y' -_alnum['\U0001d552'] = 'a' -_alnum['\U0001d553'] = 'b' -_alnum['\U0001d554'] = 'c' -_alnum['\U0001d555'] = 'd' -_alnum['\U0001d556'] = 'e' -_alnum['\U0001d557'] = 'f' -_alnum['\U0001d558'] = 'g' -_alnum['\U0001d559'] = 'h' -_alnum['\U0001d55a'] = 'i' -_alnum['\U0001d55b'] = 'j' -_alnum['\U0001d55c'] = 'k' -_alnum['\U0001d55d'] = 'l' -_alnum['\U0001d55e'] = 'm' -_alnum['\U0001d55f'] = 'n' -_alnum['\U0001d560'] = 'o' -_alnum['\U0001d561'] = 'p' -_alnum['\U0001d562'] = 'q' -_alnum['\U0001d563'] = 'r' -_alnum['\U0001d564'] = 's' -_alnum['\U0001d565'] = 't' -_alnum['\U0001d566'] = 'u' -_alnum['\U0001d567'] = 'v' -_alnum['\U0001d568'] = 'w' -_alnum['\U0001d569'] = 'x' -_alnum['\U0001d56a'] = 'y' -_alnum['\U0001d56b'] = 'z' -_alnum['\U0001d56c'] = 'A' -_alnum['\U0001d56d'] = 'B' -_alnum['\U0001d56e'] = 'C' -_alnum['\U0001d56f'] = 'D' -_alnum['\U0001d570'] = 'E' -_alnum['\U0001d571'] = 'F' -_alnum['\U0001d572'] = 'G' -_alnum['\U0001d573'] = 'H' -_alnum['\U0001d574'] = 'I' -_alnum['\U0001d575'] = 'J' -_alnum['\U0001d576'] = 'K' -_alnum['\U0001d577'] = 'L' -_alnum['\U0001d578'] = 'M' -_alnum['\U0001d579'] = 'N' -_alnum['\U0001d57a'] = 'O' -_alnum['\U0001d57b'] = 'P' -_alnum['\U0001d57c'] = 'Q' -_alnum['\U0001d57d'] = 'R' -_alnum['\U0001d57e'] = 'S' -_alnum['\U0001d57f'] = 'T' -_alnum['\U0001d580'] = 'U' -_alnum['\U0001d581'] = 'V' -_alnum['\U0001d582'] = 'W' -_alnum['\U0001d583'] = 'X' -_alnum['\U0001d584'] = 'Y' -_alnum['\U0001d585'] = 'Z' -_alnum['\U0001d586'] = 'a' -_alnum['\U0001d587'] = 'b' -_alnum['\U0001d588'] = 'c' -_alnum['\U0001d589'] = 'd' -_alnum['\U0001d58a'] = 'e' -_alnum['\U0001d58b'] = 'f' -_alnum['\U0001d58c'] = 'g' -_alnum['\U0001d58d'] = 'h' -_alnum['\U0001d58e'] = 'i' -_alnum['\U0001d58f'] = 'j' -_alnum['\U0001d590'] = 'k' -_alnum['\U0001d591'] = 'l' -_alnum['\U0001d592'] = 'm' -_alnum['\U0001d593'] = 'n' -_alnum['\U0001d594'] = 'o' -_alnum['\U0001d595'] = 'p' -_alnum['\U0001d596'] = 'q' -_alnum['\U0001d597'] = 'r' -_alnum['\U0001d598'] = 's' -_alnum['\U0001d599'] = 't' -_alnum['\U0001d59a'] = 'u' -_alnum['\U0001d59b'] = 'v' -_alnum['\U0001d59c'] = 'w' -_alnum['\U0001d59d'] = 'x' -_alnum['\U0001d59e'] = 'y' -_alnum['\U0001d59f'] = 'z' -_alnum['\U0001d5a0'] = 'A' -_alnum['\U0001d5a1'] = 'B' -_alnum['\U0001d5a2'] = 'C' -_alnum['\U0001d5a3'] = 'D' -_alnum['\U0001d5a4'] = 'E' -_alnum['\U0001d5a5'] = 'F' -_alnum['\U0001d5a6'] = 'G' -_alnum['\U0001d5a7'] = 'H' -_alnum['\U0001d5a8'] = 'I' -_alnum['\U0001d5a9'] = 'J' -_alnum['\U0001d5aa'] = 'K' -_alnum['\U0001d5ab'] = 'L' -_alnum['\U0001d5ac'] = 'M' -_alnum['\U0001d5ad'] = 'N' -_alnum['\U0001d5ae'] = 'O' -_alnum['\U0001d5af'] = 'P' -_alnum['\U0001d5b0'] = 'Q' -_alnum['\U0001d5b1'] = 'R' -_alnum['\U0001d5b2'] = 'S' -_alnum['\U0001d5b3'] = 'T' -_alnum['\U0001d5b4'] = 'U' -_alnum['\U0001d5b5'] = 'V' -_alnum['\U0001d5b6'] = 'W' -_alnum['\U0001d5b7'] = 'X' -_alnum['\U0001d5b8'] = 'Y' -_alnum['\U0001d5b9'] = 'Z' -_alnum['\U0001d5ba'] = 'a' -_alnum['\U0001d5bb'] = 'b' -_alnum['\U0001d5bc'] = 'c' -_alnum['\U0001d5bd'] = 'd' -_alnum['\U0001d5be'] = 'e' -_alnum['\U0001d5bf'] = 'f' -_alnum['\U0001d5c0'] = 'g' -_alnum['\U0001d5c1'] = 'h' -_alnum['\U0001d5c2'] = 'i' -_alnum['\U0001d5c3'] = 'j' -_alnum['\U0001d5c4'] = 'k' -_alnum['\U0001d5c5'] = 'l' -_alnum['\U0001d5c6'] = 'm' -_alnum['\U0001d5c7'] = 'n' -_alnum['\U0001d5c8'] = 'o' -_alnum['\U0001d5c9'] = 'p' -_alnum['\U0001d5ca'] = 'q' -_alnum['\U0001d5cb'] = 'r' -_alnum['\U0001d5cc'] = 's' -_alnum['\U0001d5cd'] = 't' -_alnum['\U0001d5ce'] = 'u' -_alnum['\U0001d5cf'] = 'v' -_alnum['\U0001d5d0'] = 'w' -_alnum['\U0001d5d1'] = 'x' -_alnum['\U0001d5d2'] = 'y' -_alnum['\U0001d5d3'] = 'z' -_alnum['\U0001d5d4'] = 'A' -_alnum['\U0001d5d5'] = 'B' -_alnum['\U0001d5d6'] = 'C' -_alnum['\U0001d5d7'] = 'D' -_alnum['\U0001d5d8'] = 'E' -_alnum['\U0001d5d9'] = 'F' -_alnum['\U0001d5da'] = 'G' -_alnum['\U0001d5db'] = 'H' -_alnum['\U0001d5dc'] = 'I' -_alnum['\U0001d5dd'] = 'J' -_alnum['\U0001d5de'] = 'K' -_alnum['\U0001d5df'] = 'L' -_alnum['\U0001d5e0'] = 'M' -_alnum['\U0001d5e1'] = 'N' -_alnum['\U0001d5e2'] = 'O' -_alnum['\U0001d5e3'] = 'P' -_alnum['\U0001d5e4'] = 'Q' -_alnum['\U0001d5e5'] = 'R' -_alnum['\U0001d5e6'] = 'S' -_alnum['\U0001d5e7'] = 'T' -_alnum['\U0001d5e8'] = 'U' -_alnum['\U0001d5e9'] = 'V' -_alnum['\U0001d5ea'] = 'W' -_alnum['\U0001d5eb'] = 'X' -_alnum['\U0001d5ec'] = 'Y' -_alnum['\U0001d5ed'] = 'Z' -_alnum['\U0001d5ee'] = 'a' -_alnum['\U0001d5ef'] = 'b' -_alnum['\U0001d5f0'] = 'c' -_alnum['\U0001d5f1'] = 'd' -_alnum['\U0001d5f2'] = 'e' -_alnum['\U0001d5f3'] = 'f' -_alnum['\U0001d5f4'] = 'g' -_alnum['\U0001d5f5'] = 'h' -_alnum['\U0001d5f6'] = 'i' -_alnum['\U0001d5f7'] = 'j' -_alnum['\U0001d5f8'] = 'k' -_alnum['\U0001d5f9'] = 'l' -_alnum['\U0001d5fa'] = 'm' -_alnum['\U0001d5fb'] = 'n' -_alnum['\U0001d5fc'] = 'o' -_alnum['\U0001d5fd'] = 'p' -_alnum['\U0001d5fe'] = 'q' -_alnum['\U0001d5ff'] = 'r' -_alnum['\U0001d600'] = 's' -_alnum['\U0001d601'] = 't' -_alnum['\U0001d602'] = 'u' -_alnum['\U0001d603'] = 'v' -_alnum['\U0001d604'] = 'w' -_alnum['\U0001d605'] = 'x' -_alnum['\U0001d606'] = 'y' -_alnum['\U0001d607'] = 'z' -_alnum['\U0001d608'] = 'A' -_alnum['\U0001d609'] = 'B' -_alnum['\U0001d60a'] = 'C' -_alnum['\U0001d60b'] = 'D' -_alnum['\U0001d60c'] = 'E' -_alnum['\U0001d60d'] = 'F' -_alnum['\U0001d60e'] = 'G' -_alnum['\U0001d60f'] = 'H' -_alnum['\U0001d610'] = 'I' -_alnum['\U0001d611'] = 'J' -_alnum['\U0001d612'] = 'K' -_alnum['\U0001d613'] = 'L' -_alnum['\U0001d614'] = 'M' -_alnum['\U0001d615'] = 'N' -_alnum['\U0001d616'] = 'O' -_alnum['\U0001d617'] = 'P' -_alnum['\U0001d618'] = 'Q' -_alnum['\U0001d619'] = 'R' -_alnum['\U0001d61a'] = 'S' -_alnum['\U0001d61b'] = 'T' -_alnum['\U0001d61c'] = 'U' -_alnum['\U0001d61d'] = 'V' -_alnum['\U0001d61e'] = 'W' -_alnum['\U0001d61f'] = 'X' -_alnum['\U0001d620'] = 'Y' -_alnum['\U0001d621'] = 'Z' -_alnum['\U0001d622'] = 'a' -_alnum['\U0001d623'] = 'b' -_alnum['\U0001d624'] = 'c' -_alnum['\U0001d625'] = 'd' -_alnum['\U0001d626'] = 'e' -_alnum['\U0001d627'] = 'f' -_alnum['\U0001d628'] = 'g' -_alnum['\U0001d629'] = 'h' -_alnum['\U0001d62a'] = 'i' -_alnum['\U0001d62b'] = 'j' -_alnum['\U0001d62c'] = 'k' -_alnum['\U0001d62d'] = 'l' -_alnum['\U0001d62e'] = 'm' -_alnum['\U0001d62f'] = 'n' -_alnum['\U0001d630'] = 'o' -_alnum['\U0001d631'] = 'p' -_alnum['\U0001d632'] = 'q' -_alnum['\U0001d633'] = 'r' -_alnum['\U0001d634'] = 's' -_alnum['\U0001d635'] = 't' -_alnum['\U0001d636'] = 'u' -_alnum['\U0001d637'] = 'v' -_alnum['\U0001d638'] = 'w' -_alnum['\U0001d639'] = 'x' -_alnum['\U0001d63a'] = 'y' -_alnum['\U0001d63b'] = 'z' -_alnum['\U0001d63c'] = 'A' -_alnum['\U0001d63d'] = 'B' -_alnum['\U0001d63e'] = 'C' -_alnum['\U0001d63f'] = 'D' -_alnum['\U0001d640'] = 'E' -_alnum['\U0001d641'] = 'F' -_alnum['\U0001d642'] = 'G' -_alnum['\U0001d643'] = 'H' -_alnum['\U0001d644'] = 'I' -_alnum['\U0001d645'] = 'J' -_alnum['\U0001d646'] = 'K' -_alnum['\U0001d647'] = 'L' -_alnum['\U0001d648'] = 'M' -_alnum['\U0001d649'] = 'N' -_alnum['\U0001d64a'] = 'O' -_alnum['\U0001d64b'] = 'P' -_alnum['\U0001d64c'] = 'Q' -_alnum['\U0001d64d'] = 'R' -_alnum['\U0001d64e'] = 'S' -_alnum['\U0001d64f'] = 'T' -_alnum['\U0001d650'] = 'U' -_alnum['\U0001d651'] = 'V' -_alnum['\U0001d652'] = 'W' -_alnum['\U0001d653'] = 'X' -_alnum['\U0001d654'] = 'Y' -_alnum['\U0001d655'] = 'Z' -_alnum['\U0001d656'] = 'a' -_alnum['\U0001d657'] = 'b' -_alnum['\U0001d658'] = 'c' -_alnum['\U0001d659'] = 'd' -_alnum['\U0001d65a'] = 'e' -_alnum['\U0001d65b'] = 'f' -_alnum['\U0001d65c'] = 'g' -_alnum['\U0001d65d'] = 'h' -_alnum['\U0001d65e'] = 'i' -_alnum['\U0001d65f'] = 'j' -_alnum['\U0001d660'] = 'k' -_alnum['\U0001d661'] = 'l' -_alnum['\U0001d662'] = 'm' -_alnum['\U0001d663'] = 'n' -_alnum['\U0001d664'] = 'o' -_alnum['\U0001d665'] = 'p' -_alnum['\U0001d666'] = 'q' -_alnum['\U0001d667'] = 'r' -_alnum['\U0001d668'] = 's' -_alnum['\U0001d669'] = 't' -_alnum['\U0001d66a'] = 'u' -_alnum['\U0001d66b'] = 'v' -_alnum['\U0001d66c'] = 'w' -_alnum['\U0001d66d'] = 'x' -_alnum['\U0001d66e'] = 'y' -_alnum['\U0001d66f'] = 'z' -_alnum['\U0001d670'] = 'A' -_alnum['\U0001d671'] = 'B' -_alnum['\U0001d672'] = 'C' -_alnum['\U0001d673'] = 'D' -_alnum['\U0001d674'] = 'E' -_alnum['\U0001d675'] = 'F' -_alnum['\U0001d676'] = 'G' -_alnum['\U0001d677'] = 'H' -_alnum['\U0001d678'] = 'I' -_alnum['\U0001d679'] = 'J' -_alnum['\U0001d67a'] = 'K' -_alnum['\U0001d67b'] = 'L' -_alnum['\U0001d67c'] = 'M' -_alnum['\U0001d67d'] = 'N' -_alnum['\U0001d67e'] = 'O' -_alnum['\U0001d67f'] = 'P' -_alnum['\U0001d680'] = 'Q' -_alnum['\U0001d681'] = 'R' -_alnum['\U0001d682'] = 'S' -_alnum['\U0001d683'] = 'T' -_alnum['\U0001d684'] = 'U' -_alnum['\U0001d685'] = 'V' -_alnum['\U0001d686'] = 'W' -_alnum['\U0001d687'] = 'X' -_alnum['\U0001d688'] = 'Y' -_alnum['\U0001d689'] = 'Z' -_alnum['\U0001d68a'] = 'a' -_alnum['\U0001d68b'] = 'b' -_alnum['\U0001d68c'] = 'c' -_alnum['\U0001d68d'] = 'd' -_alnum['\U0001d68e'] = 'e' -_alnum['\U0001d68f'] = 'f' -_alnum['\U0001d690'] = 'g' -_alnum['\U0001d691'] = 'h' -_alnum['\U0001d692'] = 'i' -_alnum['\U0001d693'] = 'j' -_alnum['\U0001d694'] = 'k' -_alnum['\U0001d695'] = 'l' -_alnum['\U0001d696'] = 'm' -_alnum['\U0001d697'] = 'n' -_alnum['\U0001d698'] = 'o' -_alnum['\U0001d699'] = 'p' -_alnum['\U0001d69a'] = 'q' -_alnum['\U0001d69b'] = 'r' -_alnum['\U0001d69c'] = 's' -_alnum['\U0001d69d'] = 't' -_alnum['\U0001d69e'] = 'u' -_alnum['\U0001d69f'] = 'v' -_alnum['\U0001d6a0'] = 'w' -_alnum['\U0001d6a1'] = 'x' -_alnum['\U0001d6a2'] = 'y' -_alnum['\U0001d6a3'] = 'z' -_alnum['\U0001d6a4'] = 'i' -_alnum['\U0001d6a5'] = 'j' -_alnum['\U0001d6a8'] = 'Α' -_alnum['\U0001d6a9'] = 'Β' -_alnum['\U0001d6aa'] = 'Γ' -_alnum['\U0001d6ab'] = 'Δ' -_alnum['\U0001d6ac'] = 'Ε' -_alnum['\U0001d6ad'] = 'Ζ' -_alnum['\U0001d6ae'] = 'Η' -_alnum['\U0001d6af'] = 'ϴ' -_alnum['\U0001d6b0'] = 'Ι' -_alnum['\U0001d6b1'] = 'Κ' -_alnum['\U0001d6b2'] = 'Λ' -_alnum['\U0001d6b3'] = 'Μ' -_alnum['\U0001d6b4'] = 'Ν' -_alnum['\U0001d6b5'] = 'Ξ' -_alnum['\U0001d6b6'] = 'Ο' -_alnum['\U0001d6b7'] = 'Π' -_alnum['\U0001d6b8'] = 'Ρ' -_alnum['\U0001d6b9'] = 'ϴ' -_alnum['\U0001d6ba'] = 'Σ' -_alnum['\U0001d6bb'] = 'Τ' -_alnum['\U0001d6bc'] = 'Υ' -_alnum['\U0001d6bd'] = 'Φ' -_alnum['\U0001d6be'] = 'Χ' -_alnum['\U0001d6bf'] = 'Ψ' -_alnum['\U0001d6c0'] = 'Ω' -_alnum['\U0001d6c1'] = '∇' -_alnum['\U0001d6c2'] = 'α' -_alnum['\U0001d6c3'] = 'β' -_alnum['\U0001d6c4'] = 'γ' -_alnum['\U0001d6c5'] = 'δ' -_alnum['\U0001d6c6'] = 'ε' -_alnum['\U0001d6c7'] = 'ζ' -_alnum['\U0001d6c8'] = 'η' -_alnum['\U0001d6c9'] = 'θ' -_alnum['\U0001d6ca'] = 'ι' -_alnum['\U0001d6cb'] = 'κ' -_alnum['\U0001d6cc'] = 'λ' -_alnum['\U0001d6cd'] = 'μ' -_alnum['\U0001d6ce'] = 'ν' -_alnum['\U0001d6cf'] = 'ξ' -_alnum['\U0001d6d0'] = 'ο' -_alnum['\U0001d6d1'] = 'π' -_alnum['\U0001d6d2'] = 'ρ' -_alnum['\U0001d6d3'] = 'ς' -_alnum['\U0001d6d4'] = 'σ' -_alnum['\U0001d6d5'] = 'τ' -_alnum['\U0001d6d6'] = 'υ' -_alnum['\U0001d6d7'] = 'φ' -_alnum['\U0001d6d8'] = 'χ' -_alnum['\U0001d6d9'] = 'ψ' -_alnum['\U0001d6da'] = 'ω' -_alnum['\U0001d6db'] = '∂' -_alnum['\U0001d6dc'] = 'ϵ' -_alnum['\U0001d6dd'] = 'ϑ' -_alnum['\U0001d6de'] = 'ϰ' -_alnum['\U0001d6df'] = 'ϕ' -_alnum['\U0001d6e0'] = 'ϱ' -_alnum['\U0001d6e1'] = 'ϖ' -_alnum['\U0001d6e2'] = 'Α' -_alnum['\U0001d6e3'] = 'Β' -_alnum['\U0001d6e4'] = 'Γ' -_alnum['\U0001d6e5'] = 'Δ' -_alnum['\U0001d6e6'] = 'Ε' -_alnum['\U0001d6e7'] = 'Ζ' -_alnum['\U0001d6e8'] = 'Η' -_alnum['\U0001d6e9'] = 'ϴ' -_alnum['\U0001d6ea'] = 'Ι' -_alnum['\U0001d6eb'] = 'Κ' -_alnum['\U0001d6ec'] = 'Λ' -_alnum['\U0001d6ed'] = 'Μ' -_alnum['\U0001d6ee'] = 'Ν' -_alnum['\U0001d6ef'] = 'Ξ' -_alnum['\U0001d6f0'] = 'Ο' -_alnum['\U0001d6f1'] = 'Π' -_alnum['\U0001d6f2'] = 'Ρ' -_alnum['\U0001d6f3'] = 'ϴ' -_alnum['\U0001d6f4'] = 'Σ' -_alnum['\U0001d6f5'] = 'Τ' -_alnum['\U0001d6f6'] = 'Υ' -_alnum['\U0001d6f7'] = 'Φ' -_alnum['\U0001d6f8'] = 'Χ' -_alnum['\U0001d6f9'] = 'Ψ' -_alnum['\U0001d6fa'] = 'Ω' -_alnum['\U0001d6fb'] = '∇' -_alnum['\U0001d6fc'] = 'α' -_alnum['\U0001d6fd'] = 'β' -_alnum['\U0001d6fe'] = 'γ' -_alnum['\U0001d6ff'] = 'δ' -_alnum['\U0001d700'] = 'ε' -_alnum['\U0001d701'] = 'ζ' -_alnum['\U0001d702'] = 'η' -_alnum['\U0001d703'] = 'θ' -_alnum['\U0001d704'] = 'ι' -_alnum['\U0001d705'] = 'κ' -_alnum['\U0001d706'] = 'λ' -_alnum['\U0001d707'] = 'μ' -_alnum['\U0001d708'] = 'ν' -_alnum['\U0001d709'] = 'ξ' -_alnum['\U0001d70a'] = 'ο' -_alnum['\U0001d70b'] = 'π' -_alnum['\U0001d70c'] = 'ρ' -_alnum['\U0001d70d'] = 'ς' -_alnum['\U0001d70e'] = 'σ' -_alnum['\U0001d70f'] = 'τ' -_alnum['\U0001d710'] = 'υ' -_alnum['\U0001d711'] = 'φ' -_alnum['\U0001d712'] = 'χ' -_alnum['\U0001d713'] = 'ψ' -_alnum['\U0001d714'] = 'ω' -_alnum['\U0001d715'] = '∂' -_alnum['\U0001d716'] = 'ϵ' -_alnum['\U0001d717'] = 'ϑ' -_alnum['\U0001d718'] = 'ϰ' -_alnum['\U0001d719'] = 'ϕ' -_alnum['\U0001d71a'] = 'ϱ' -_alnum['\U0001d71b'] = 'ϖ' -_alnum['\U0001d71c'] = 'Α' -_alnum['\U0001d71d'] = 'Β' -_alnum['\U0001d71e'] = 'Γ' -_alnum['\U0001d71f'] = 'Δ' -_alnum['\U0001d720'] = 'Ε' -_alnum['\U0001d721'] = 'Ζ' -_alnum['\U0001d722'] = 'Η' -_alnum['\U0001d723'] = 'ϴ' -_alnum['\U0001d724'] = 'Ι' -_alnum['\U0001d725'] = 'Κ' -_alnum['\U0001d726'] = 'Λ' -_alnum['\U0001d727'] = 'Μ' -_alnum['\U0001d728'] = 'Ν' -_alnum['\U0001d729'] = 'Ξ' -_alnum['\U0001d72a'] = 'Ο' -_alnum['\U0001d72b'] = 'Π' -_alnum['\U0001d72c'] = 'Ρ' -_alnum['\U0001d72d'] = 'ϴ' -_alnum['\U0001d72e'] = 'Σ' -_alnum['\U0001d72f'] = 'Τ' -_alnum['\U0001d730'] = 'Υ' -_alnum['\U0001d731'] = 'Φ' -_alnum['\U0001d732'] = 'Χ' -_alnum['\U0001d733'] = 'Ψ' -_alnum['\U0001d734'] = 'Ω' -_alnum['\U0001d735'] = '∇' -_alnum['\U0001d736'] = 'α' -_alnum['\U0001d737'] = 'β' -_alnum['\U0001d738'] = 'γ' -_alnum['\U0001d739'] = 'δ' -_alnum['\U0001d73a'] = 'ε' -_alnum['\U0001d73b'] = 'ζ' -_alnum['\U0001d73c'] = 'η' -_alnum['\U0001d73d'] = 'θ' -_alnum['\U0001d73e'] = 'ι' -_alnum['\U0001d73f'] = 'κ' -_alnum['\U0001d740'] = 'λ' -_alnum['\U0001d741'] = 'μ' -_alnum['\U0001d742'] = 'ν' -_alnum['\U0001d743'] = 'ξ' -_alnum['\U0001d744'] = 'ο' -_alnum['\U0001d745'] = 'π' -_alnum['\U0001d746'] = 'ρ' -_alnum['\U0001d747'] = 'ς' -_alnum['\U0001d748'] = 'σ' -_alnum['\U0001d749'] = 'τ' -_alnum['\U0001d74a'] = 'υ' -_alnum['\U0001d74b'] = 'φ' -_alnum['\U0001d74c'] = 'χ' -_alnum['\U0001d74d'] = 'ψ' -_alnum['\U0001d74e'] = 'ω' -_alnum['\U0001d74f'] = '∂' -_alnum['\U0001d750'] = 'ϵ' -_alnum['\U0001d751'] = 'ϑ' -_alnum['\U0001d752'] = 'ϰ' -_alnum['\U0001d753'] = 'ϕ' -_alnum['\U0001d754'] = 'ϱ' -_alnum['\U0001d755'] = 'ϖ' -_alnum['\U0001d756'] = 'Α' -_alnum['\U0001d757'] = 'Β' -_alnum['\U0001d758'] = 'Γ' -_alnum['\U0001d759'] = 'Δ' -_alnum['\U0001d75a'] = 'Ε' -_alnum['\U0001d75b'] = 'Ζ' -_alnum['\U0001d75c'] = 'Η' -_alnum['\U0001d75d'] = 'ϴ' -_alnum['\U0001d75e'] = 'Ι' -_alnum['\U0001d75f'] = 'Κ' -_alnum['\U0001d760'] = 'Λ' -_alnum['\U0001d761'] = 'Μ' -_alnum['\U0001d762'] = 'Ν' -_alnum['\U0001d763'] = 'Ξ' -_alnum['\U0001d764'] = 'Ο' -_alnum['\U0001d765'] = 'Π' -_alnum['\U0001d766'] = 'Ρ' -_alnum['\U0001d767'] = 'ϴ' -_alnum['\U0001d768'] = 'Σ' -_alnum['\U0001d769'] = 'Τ' -_alnum['\U0001d76a'] = 'Υ' -_alnum['\U0001d76b'] = 'Φ' -_alnum['\U0001d76c'] = 'Χ' -_alnum['\U0001d76d'] = 'Ψ' -_alnum['\U0001d76e'] = 'Ω' -_alnum['\U0001d76f'] = '∇' -_alnum['\U0001d770'] = 'α' -_alnum['\U0001d771'] = 'β' -_alnum['\U0001d772'] = 'γ' -_alnum['\U0001d773'] = 'δ' -_alnum['\U0001d774'] = 'ε' -_alnum['\U0001d775'] = 'ζ' -_alnum['\U0001d776'] = 'η' -_alnum['\U0001d777'] = 'θ' -_alnum['\U0001d778'] = 'ι' -_alnum['\U0001d779'] = 'κ' -_alnum['\U0001d77a'] = 'λ' -_alnum['\U0001d77b'] = 'μ' -_alnum['\U0001d77c'] = 'ν' -_alnum['\U0001d77d'] = 'ξ' -_alnum['\U0001d77e'] = 'ο' -_alnum['\U0001d77f'] = 'π' -_alnum['\U0001d780'] = 'ρ' -_alnum['\U0001d781'] = 'ς' -_alnum['\U0001d782'] = 'σ' -_alnum['\U0001d783'] = 'τ' -_alnum['\U0001d784'] = 'υ' -_alnum['\U0001d785'] = 'φ' -_alnum['\U0001d786'] = 'χ' -_alnum['\U0001d787'] = 'ψ' -_alnum['\U0001d788'] = 'ω' -_alnum['\U0001d789'] = '∂' -_alnum['\U0001d78a'] = 'ϵ' -_alnum['\U0001d78b'] = 'ϑ' -_alnum['\U0001d78c'] = 'ϰ' -_alnum['\U0001d78d'] = 'ϕ' -_alnum['\U0001d78e'] = 'ϱ' -_alnum['\U0001d78f'] = 'ϖ' -_alnum['\U0001d790'] = 'Α' -_alnum['\U0001d791'] = 'Β' -_alnum['\U0001d792'] = 'Γ' -_alnum['\U0001d793'] = 'Δ' -_alnum['\U0001d794'] = 'Ε' -_alnum['\U0001d795'] = 'Ζ' -_alnum['\U0001d796'] = 'Η' -_alnum['\U0001d797'] = 'ϴ' -_alnum['\U0001d798'] = 'Ι' -_alnum['\U0001d799'] = 'Κ' -_alnum['\U0001d79a'] = 'Λ' -_alnum['\U0001d79b'] = 'Μ' -_alnum['\U0001d79c'] = 'Ν' -_alnum['\U0001d79d'] = 'Ξ' -_alnum['\U0001d79e'] = 'Ο' -_alnum['\U0001d79f'] = 'Π' -_alnum['\U0001d7a0'] = 'Ρ' -_alnum['\U0001d7a1'] = 'ϴ' -_alnum['\U0001d7a2'] = 'Σ' -_alnum['\U0001d7a3'] = 'Τ' -_alnum['\U0001d7a4'] = 'Υ' -_alnum['\U0001d7a5'] = 'Φ' -_alnum['\U0001d7a6'] = 'Χ' -_alnum['\U0001d7a7'] = 'Ψ' -_alnum['\U0001d7a8'] = 'Ω' -_alnum['\U0001d7a9'] = '∇' -_alnum['\U0001d7aa'] = 'α' -_alnum['\U0001d7ab'] = 'β' -_alnum['\U0001d7ac'] = 'γ' -_alnum['\U0001d7ad'] = 'δ' -_alnum['\U0001d7ae'] = 'ε' -_alnum['\U0001d7af'] = 'ζ' -_alnum['\U0001d7b0'] = 'η' -_alnum['\U0001d7b1'] = 'θ' -_alnum['\U0001d7b2'] = 'ι' -_alnum['\U0001d7b3'] = 'κ' -_alnum['\U0001d7b4'] = 'λ' -_alnum['\U0001d7b5'] = 'μ' -_alnum['\U0001d7b6'] = 'ν' -_alnum['\U0001d7b7'] = 'ξ' -_alnum['\U0001d7b8'] = 'ο' -_alnum['\U0001d7b9'] = 'π' -_alnum['\U0001d7ba'] = 'ρ' -_alnum['\U0001d7bb'] = 'ς' -_alnum['\U0001d7bc'] = 'σ' -_alnum['\U0001d7bd'] = 'τ' -_alnum['\U0001d7be'] = 'υ' -_alnum['\U0001d7bf'] = 'φ' -_alnum['\U0001d7c0'] = 'χ' -_alnum['\U0001d7c1'] = 'ψ' -_alnum['\U0001d7c2'] = 'ω' -_alnum['\U0001d7c3'] = '∂' -_alnum['\U0001d7c4'] = 'ϵ' -_alnum['\U0001d7c5'] = 'ϑ' -_alnum['\U0001d7c6'] = 'ϰ' -_alnum['\U0001d7c7'] = 'ϕ' -_alnum['\U0001d7c8'] = 'ϱ' -_alnum['\U0001d7c9'] = 'ϖ' -_alnum['\U0001d7ca'] = 'Ϝ' -_alnum['\U0001d7cb'] = 'ϝ' -_alnum['\U0001d7ce'] = '0' -_alnum['\U0001d7cf'] = '1' -_alnum['\U0001d7d0'] = '2' -_alnum['\U0001d7d1'] = '3' -_alnum['\U0001d7d2'] = '4' -_alnum['\U0001d7d3'] = '5' -_alnum['\U0001d7d4'] = '6' -_alnum['\U0001d7d5'] = '7' -_alnum['\U0001d7d6'] = '8' -_alnum['\U0001d7d7'] = '9' -_alnum['\U0001d7d8'] = '0' -_alnum['\U0001d7d9'] = '1' -_alnum['\U0001d7da'] = '2' -_alnum['\U0001d7db'] = '3' -_alnum['\U0001d7dc'] = '4' -_alnum['\U0001d7dd'] = '5' -_alnum['\U0001d7de'] = '6' -_alnum['\U0001d7df'] = '7' -_alnum['\U0001d7e0'] = '8' -_alnum['\U0001d7e1'] = '9' -_alnum['\U0001d7e2'] = '0' -_alnum['\U0001d7e3'] = '1' -_alnum['\U0001d7e4'] = '2' -_alnum['\U0001d7e5'] = '3' -_alnum['\U0001d7e6'] = '4' -_alnum['\U0001d7e7'] = '5' -_alnum['\U0001d7e8'] = '6' -_alnum['\U0001d7e9'] = '7' -_alnum['\U0001d7ea'] = '8' -_alnum['\U0001d7eb'] = '9' -_alnum['\U0001d7ec'] = '0' -_alnum['\U0001d7ed'] = '1' -_alnum['\U0001d7ee'] = '2' -_alnum['\U0001d7ef'] = '3' -_alnum['\U0001d7f0'] = '4' -_alnum['\U0001d7f1'] = '5' -_alnum['\U0001d7f2'] = '6' -_alnum['\U0001d7f3'] = '7' -_alnum['\U0001d7f4'] = '8' -_alnum['\U0001d7f5'] = '9' -_alnum['\U0001d7f6'] = '0' -_alnum['\U0001d7f7'] = '1' -_alnum['\U0001d7f8'] = '2' -_alnum['\U0001d7f9'] = '3' -_alnum['\U0001d7fa'] = '4' -_alnum['\U0001d7fb'] = '5' -_alnum['\U0001d7fc'] = '6' -_alnum['\U0001d7fd'] = '7' -_alnum['\U0001d7fe'] = '8' -_alnum['\U0001d7ff'] = '9' - -_bold = range(0x1d400, 0x1d434) -_italic = range(0x1d434, 0x1d468) -_boldItalic = range(0x1d468, 0x1d49c) -_script = range(0x1d49c, 0x1d4d0) -_boldScript = range(0x1d4d0, 0x1d504) -_fraktur = range(0x1d504, 0x1d538) -_doubleStruck = range(0x1d538, 0x1d56c) -_boldFraktur = range(0x1d56c, 0x1d5a0) -_sansSerif = range(0x1d5a0, 0x1d5d4) -_sansSerifBold = range(0x1d5d4, 0x1d608) -_sansSerifItalic = range(0x1d608, 0x1d63c) -_sansSerifBoldItalic = range(0x1d63c, 0x1d670) -_monospace = range(0x1d670, 0x1d6a4) -_dotless = range(0x1d6a4, 0x1d6a8) -_boldGreek = range(0x1d6a8, 0x1d6e2) -_italicGreek = range(0x1d6e2, 0x1d71c) -_boldItalicGreek = range(0x1d71c, 0x1d756) -_sansSerifBoldGreek = range(0x1d756, 0x1d790) -_sansSerifBoldItalicGreek = range(0x1d790, 0x1d7ca) -_boldGreekDigamma = range(0x1d7ca, 0x1d7cc) -_boldDigits = range(0x1d7ce, 0x1d7d8) -_doubleStruckDigits = range(0x1d7d8, 0x1d7e2) -_sansSerifDigits = range(0x1d7e2, 0x1d7ec) -_sansSerifBoldDigits = range(0x1d7ec, 0x1d7f6) -_monospaceDigits = range(0x1d7f6, 0x1d800) -_otherDoubleStruck = [0x2102, 0x210d, 0x2115, 0x2119, 0x211a, 0x211d, 0x2124] -_otherFraktur = [0x212d, 0x210c, 0x2111, 0x211c, 0x2128] -_otherItalic = [0x210e] -_otherScript = [0x212c, - 0x2130, - 0x2131, - 0x210b, - 0x2110, - 0x2112, - 0x2133, - 0x211b, - 0x212f, - 0x210a, - 0x2134] - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -BOLD = C_('math symbol', 'bold %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -ITALIC = C_('math symbol', 'italic %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -BOLD_ITALIC = C_('math symbol', 'bold italic %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -SCRIPT = C_('math symbol', 'script %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -BOLD_SCRIPT = C_('math symbol', 'bold script %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -FRAKTUR = C_('math symbol', 'fraktur %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -DOUBLE_STRUCK = C_('math symbol', 'double-struck %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -BOLD_FRAKTUR = C_('math symbol', 'bold fraktur %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -SANS_SERIF = C_('math symbol', 'sans-serif %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -SANS_SERIF_BOLD = C_('math symbol', 'sans-serif bold %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -SANS_SERIF_ITALIC = C_('math symbol', 'sans-serif italic %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -SANS_SERIF_BOLD_ITALIC = C_('math symbol', 'sans-serif bold italic %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -MONOSPACE = C_('math symbol', 'monospace %s') - -# Translators: Unicode has a large set of characters consisting of a common -# alphanumeric symbol and a style. For instance, character 1D400 is a bold A, -# 1D468 is a bold italic A, 1D4D0 is a bold script A,, etc., etc. These styles -# can have specific meanings in mathematics and thus should be spoken along -# with the alphanumeric character. However, given the vast quantity of these -# characters, string substitution is being used with the substituted string -# being a single alphanumeric character. The full set of symbols can be found -# at http://www.unicode.org/charts/PDF/U1D400.pdf. -DOTLESS = C_('math symbol', 'dotless %s') - -# Translators: this is the spoken representation for the character '←' (U+2190) -_arrows['\u2190'] = C_('math symbol', 'left arrow') - -# Translators: this is the spoken representation for the character '↑' (U+2191) -_arrows['\u2191'] = C_('math symbol', 'up arrow') - -# Translators: this is the spoken representation for the character '→' (U+2192) -_arrows['\u2192'] = C_('math symbol', 'right arrow') - -# Translators: this is the spoken representation for the character '↓' (U+2193) -_arrows['\u2193'] = C_('math symbol', 'down arrow') - -# Translators: this is the spoken representation for the character '↔' (U+2194) -_arrows['\u2194'] = C_('math symbol', 'left right arrow') - -# Translators: this is the spoken representation for the character '↕' (U+2195) -_arrows['\u2195'] = C_('math symbol', 'up down arrow') - -# Translators: this is the spoken representation for the character '↖' (U+2196) -_arrows['\u2196'] = C_('math symbol', 'north west arrow') - -# Translators: this is the spoken representation for the character '↗' (U+2197) -_arrows['\u2197'] = C_('math symbol', 'north east arrow') - -# Translators: this is the spoken representation for the character '↘' (U+2198) -_arrows['\u2198'] = C_('math symbol', 'south east arrow') - -# Translators: this is the spoken representation for the character '↤' (U+21a4) -_arrows['\u21a4'] = C_('math symbol', 'left arrow from bar') - -# Translators: this is the spoken representation for the character '↥' (U+21a5) -_arrows['\u21a5'] = C_('math symbol', 'up arrow from bar') - -# Translators: this is the spoken representation for the character '↦' (U+21a6) -_arrows['\u21a6'] = C_('math symbol', 'right arrow from bar') - -# Translators: this is the spoken representation for the character '↧' (U+21a7) -_arrows['\u21a7'] = C_('math symbol', 'down arrow from bar') - -# Translators: this is the spoken representation for the character '⇐' (U+21d0) -_arrows['\u21d0'] = C_('math symbol', 'left double arrow') - -# Translators: this is the spoken representation for the character '⇑' (U+21d1) -_arrows['\u21d1'] = C_('math symbol', 'up double arrow') - -# Translators: this is the spoken representation for the character '⇒' (U+21d2) -_arrows['\u21d2'] = C_('math symbol', 'right double arrow') - -# Translators: this is the spoken representation for the character '⇓' (U+21d3) -_arrows['\u21d3'] = C_('math symbol', 'down double arrow') - -# Translators: this is the spoken representation for the character '⇔' (U+21d4) -_arrows['\u21d4'] = C_('math symbol', 'left right double arrow') - -# Translators: this is the spoken representation for the character '⇕' (U+21d5) -_arrows['\u21d5'] = C_('math symbol', 'up down double arrow') - -# Translators: this is the spoken representation for the character '⇖' (U+21d6) -_arrows['\u21d6'] = C_('math symbol', 'north west double arrow') - -# Translators: this is the spoken representation for the character '⇗' (U+21d7) -_arrows['\u21d7'] = C_('math symbol', 'north east double arrow') - -# Translators: this is the spoken representation for the character '⇘' (U+21d8) -_arrows['\u21d8'] = C_('math symbol', 'south east double arrow') - -# Translators: this is the spoken representation for the character '⇙' (U+21d9) -_arrows['\u21d9'] = C_('math symbol', 'south west double arrow') - -# Translators: this is the spoken representation for the character '➔' (U+2794) -_arrows['\u2794'] = C_('math symbol', 'right-pointing arrow') - -# Translators: this is the spoken representation for the character '➢' (U+27a2) -_arrows['\u27a2'] = C_('math symbol', 'right-pointing arrowhead') - -# Translators: this is the spoken word for the character '-' (U+002d) when used -# as a MathML operator. -_operators["\u002d"] = C_('math symbol', 'minus') - -# Translators: this is the spoken word for the character '<' (U+003c) when used -# as a MathML operator. -_operators["\u003c"] = C_('math symbol', 'less than') - -# Translators: this is the spoken word for the character '>' (U+003e) when used -# as a MathML operator. -_operators["\u003e"] = C_('math symbol', 'greater than') - -# Translators: this is the spoken word for the character '^' (U+005e) when used -# as a MathML operator. -_operators['\u005e'] = C_('math symbol', 'circumflex') - -# Translators: this is the spoken word for the character 'ˇ' (U+02c7) when used -# as a MathML operator. -_operators['\u02c7'] = C_('math symbol', 'háček') - -# Translators: this is the spoken word for the character '˘' (U+02d8) when used -# as a MathML operator. -_operators['\u02d8'] = C_('math symbol', 'breve') - -# Translators: this is the spoken word for the character '˙' (U+02d9) when used -# as a MathML operator. -_operators['\u02d9'] = C_('math symbol', 'dot') - -# Translators: this is the spoken word for the character '‖' (U+2016) when used -# as a MathML operator. -_operators['\u2016'] = C_('math symbol', 'double vertical line') - -# Translators: this is the spoken representation for the character '…' (U+2026) -_operators['\u2026'] = C_('math symbol', 'horizontal ellipsis') - -# Translators: this is the spoken representation for the character '∀' (U+2200) -_operators['\u2200'] = C_('math symbol', 'for all') - -# Translators: this is the spoken representation for the character '∁' (U+2201) -_operators['\u2201'] = C_('math symbol', 'complement') - -# Translators: this is the spoken representation for the character '∂' (U+2202) -_operators['\u2202'] = C_('math symbol', 'partial differential') - -# Translators: this is the spoken representation for the character '∃' (U+2203) -_operators['\u2203'] = C_('math symbol', 'there exists') - -# Translators: this is the spoken representation for the character '∄' (U+2204) -_operators['\u2204'] = C_('math symbol', 'there does not exist') - -# Translators: this is the spoken representation for the character '∅' (U+2205) -_operators['\u2205'] = C_('math symbol', 'empty set') - -# Translators: this is the spoken representation for the character '∆' (U+2206) -_operators['\u2206'] = C_('math symbol', 'increment') - -# Translators: this is the spoken representation for the character '∇' (U+2207) -_operators['\u2207'] = C_('math symbol', 'nabla') - -# Translators: this is the spoken representation for the character '∈' (U+2208) -_operators['\u2208'] = C_('math symbol', 'element of') - -# Translators: this is the spoken representation for the character '∉' (U+2209) -_operators['\u2209'] = C_('math symbol', 'not an element of') - -# Translators: this is the spoken representation for the character '∊' (U+220a) -_operators['\u220a'] = C_('math symbol', 'small element of') - -# Translators: this is the spoken representation for the character '∋' (U+220b) -_operators['\u220b'] = C_('math symbol', 'contains as a member') - -# Translators: this is the spoken representation for the character '∌' (U+220c) -_operators['\u220c'] = C_('math symbol', 'does not contain as a member') - -# Translators: this is the spoken representation for the character '∍' (U+220d) -_operators['\u220d'] = C_('math symbol', 'small contains as a member') - -# Translators: this is the spoken representation for the character '∎' (U+220e) -_operators['\u220e'] = C_('math symbol', 'end of proof') - -# Translators: this is the spoken representation for the character '∏' (U+220f) -_operators['\u220f'] = C_('math symbol', 'product') - -# Translators: this is the spoken representation for the character '∐' (U+2210) -_operators['\u2210'] = C_('math symbol', 'coproduct') - -# Translators: this is the spoken representation for the character '∑' (U+2211) -_operators['\u2211'] = C_('math symbol', 'sum') - -# Translators: this is the spoken representation for the character '−' (U+2212) -_operators['\u2212'] = C_('math symbol', 'minus') - -# Translators: this is the spoken representation for the character '∓' (U+2213) -_operators['\u2213'] = C_('math symbol', 'minus or plus') - -# Translators: this is the spoken representation for the character '∔' (U+2214) -_operators['\u2214'] = C_('math symbol', 'dot plus') - -# Translators: this is the spoken representation for the character '∕' (U+2215) -_operators['\u2215'] = C_('math symbol', 'division slash') - -# Translators: this is the spoken representation for the character '∖' (U+2216) -_operators['\u2216'] = C_('math symbol', 'set minus') - -# Translators: this is the spoken representation for the character '∗' (U+2217) -_operators['\u2217'] = C_('math symbol', 'asterisk operator') - -# Translators: this is the spoken representation for the character '∘' (U+2218) -_operators['\u2218'] = C_('math symbol', 'ring operator') - -# Translators: this is the spoken representation for the character '∙' (U+2219) -_operators['\u2219'] = C_('math symbol', 'bullet operator') - -# Translators: this is the spoken representation for the character '√' (U+221a) -_operators['\u221a'] = C_('math symbol', 'square root') - -# Translators: this is the spoken representation for the character '∛' (U+221b) -_operators['\u221b'] = C_('math symbol', 'cube root') - -# Translators: this is the spoken representation for the character '∜' (U+221c) -_operators['\u221c'] = C_('math symbol', 'fourth root') - -# Translators: this is the spoken representation for the character '∝' (U+221d) -_operators['\u221d'] = C_('math symbol', 'proportional to') - -# Translators: this is the spoken representation for the character '∞' (U+221e) -_operators['\u221e'] = C_('math symbol', 'infinity') - -# Translators: this is the spoken representation for the character '∟' (U+221f) -_operators['\u221f'] = C_('math symbol', 'right angle') - -# Translators: this is the spoken representation for the character '∠' (U+2220) -_operators['\u2220'] = C_('math symbol', 'angle') - -# Translators: this is the spoken representation for the character '∡' (U+2221) -_operators['\u2221'] = C_('math symbol', 'measured angle') - -# Translators: this is the spoken representation for the character '∢' (U+2222) -_operators['\u2222'] = C_('math symbol', 'spherical angle') - -# Translators: this is the spoken representation for the character '∣' (U+2223) -_operators['\u2223'] = C_('math symbol', 'divides') - -# Translators: this is the spoken representation for the character '∤' (U+2224) -_operators['\u2224'] = C_('math symbol', 'does not divide') - -# Translators: this is the spoken representation for the character '∥' (U+2225) -_operators['\u2225'] = C_('math symbol', 'parallel to') - -# Translators: this is the spoken representation for the character '∦' (U+2226) -_operators['\u2226'] = C_('math symbol', 'not parallel to') - -# Translators: this is the spoken representation for the character '∧' (U+2227) -_operators['\u2227'] = C_('math symbol', 'logical and') - -# Translators: this is the spoken representation for the character '∨' (U+2228) -_operators['\u2228'] = C_('math symbol', 'logical or') - -# Translators: this is the spoken representation for the character '∩' (U+2229) -_operators['\u2229'] = C_('math symbol', 'intersection') - -# Translators: this is the spoken representation for the character '∪' (U+222a) -_operators['\u222a'] = C_('math symbol', 'union') - -# Translators: this is the spoken representation for the character '∫' (U+222b) -_operators['\u222b'] = C_('math symbol', 'integral') - -# Translators: this is the spoken representation for the character '∬' (U+222c) -_operators['\u222c'] = C_('math symbol', 'double integral') - -# Translators: this is the spoken representation for the character '∭' (U+222d) -_operators['\u222d'] = C_('math symbol', 'triple integral') - -# Translators: this is the spoken representation for the character '∮' (U+222e) -_operators['\u222e'] = C_('math symbol', 'contour integral') - -# Translators: this is the spoken representation for the character '∯' (U+222f) -_operators['\u222f'] = C_('math symbol', 'surface integral') - -# Translators: this is the spoken representation for the character '∰' (U+2230) -_operators['\u2230'] = C_('math symbol', 'volume integral') - -# Translators: this is the spoken representation for the character '∱' (U+2231) -_operators['\u2231'] = C_('math symbol', 'clockwise integral') - -# Translators: this is the spoken representation for the character '∲' (U+2232) -_operators['\u2232'] = C_('math symbol', 'clockwise contour integral') - -# Translators: this is the spoken representation for the character '∳' (U+2233) -_operators['\u2233'] = C_('math symbol', 'anticlockwise contour integral') - -# Translators: this is the spoken representation for the character '∴' (U+2234) -_operators['\u2234'] = C_('math symbol', 'therefore') - -# Translators: this is the spoken representation for the character '∵' (U+2235) -_operators['\u2235'] = C_('math symbol', 'because') - -# Translators: this is the spoken representation for the character '∶' (U+2236) -_operators['\u2236'] = C_('math symbol', 'ratio') - -# Translators: this is the spoken representation for the character '∷' (U+2237) -_operators['\u2237'] = C_('math symbol', 'proportion') - -# Translators: this is the spoken representation for the character '∸' (U+2238) -_operators['\u2238'] = C_('math symbol', 'dot minus') - -# Translators: this is the spoken representation for the character '∹' (U+2239) -_operators['\u2239'] = C_('math symbol', 'excess') - -# Translators: this is the spoken representation for the character '∺' (U+223a) -_operators['\u223a'] = C_('math symbol', 'geometric proportion') - -# Translators: this is the spoken representation for the character '∻' (U+223b) -_operators['\u223b'] = C_('math symbol', 'homothetic') - -# Translators: this is the spoken representation for the character '∼' (U+223c) -_operators['\u223c'] = C_('math symbol', 'tilde') - -# Translators: this is the spoken representation for the character '∽' (U+223d) -_operators['\u223d'] = C_('math symbol', 'reversed tilde') - -# Translators: this is the spoken representation for the character '∾' (U+223e) -_operators['\u223e'] = C_('math symbol', 'inverted lazy S') - -# Translators: this is the spoken representation for the character '∿' (U+223f) -_operators['\u223f'] = C_('math symbol', 'sine wave') - -# Translators: this is the spoken representation for the character '≀' (U+2240) -_operators['\u2240'] = C_('math symbol', 'wreath product') - -# Translators: this is the spoken representation for the character '≁' (U+2241) -_operators['\u2241'] = C_('math symbol', 'not tilde') - -# Translators: this is the spoken representation for the character '≂' (U+2242) -_operators['\u2242'] = C_('math symbol', 'minus tilde') - -# Translators: this is the spoken representation for the character '≃' (U+2243) -_operators['\u2243'] = C_('math symbol', 'asymptotically equal to') - -# Translators: this is the spoken representation for the character '≄' (U+2244) -_operators['\u2244'] = C_('math symbol', 'not asymptotically equal to') - -# Translators: this is the spoken representation for the character '≅' (U+2245) -_operators['\u2245'] = C_('math symbol', 'approximately equal to') - -# Translators: this is the spoken representation for the character '≆' (U+2246) -_operators['\u2246'] = C_('math symbol', 'approximately but not actually equal to') - -# Translators: this is the spoken representation for the character '≇' (U+2247) -_operators['\u2247'] = C_('math symbol', 'neither approximately nor actually equal to') - -# Translators: this is the spoken representation for the character '≈' (U+2248) -_operators['\u2248'] = C_('math symbol', 'almost equal to') - -# Translators: this is the spoken representation for the character '≉' (U+2249) -_operators['\u2249'] = C_('math symbol', 'not almost equal to') - -# Translators: this is the spoken representation for the character '≊' (U+224a) -_operators['\u224a'] = C_('math symbol', 'almost equal or equal to') - -# Translators: this is the spoken representation for the character '≋' (U+224b) -_operators['\u224b'] = C_('math symbol', 'triple tilde') - -# Translators: this is the spoken representation for the character '≌' (U+224c) -_operators['\u224c'] = C_('math symbol', 'all equal to') - -# Translators: this is the spoken representation for the character '≍' (U+224d) -_operators['\u224d'] = C_('math symbol', 'equivalent to') - -# Translators: this is the spoken representation for the character '≎' (U+224e) -_operators['\u224e'] = C_('math symbol', 'geometrically equivalent to') - -# Translators: this is the spoken representation for the character '≏' (U+224f) -_operators['\u224f'] = C_('math symbol', 'difference between') - -# Translators: this is the spoken representation for the character '≐' (U+2250) -_operators['\u2250'] = C_('math symbol', 'approaches the limit') - -# Translators: this is the spoken representation for the character '≑' (U+2251) -_operators['\u2251'] = C_('math symbol', 'geometrically equal to') - -# Translators: this is the spoken representation for the character '≒' (U+2252) -_operators['\u2252'] = C_('math symbol', 'approximately equal to or the image of') - -# Translators: this is the spoken representation for the character '≓' (U+2253) -_operators['\u2253'] = C_('math symbol', 'image of or approximately equal to') - -# Translators: this is the spoken representation for the character '≔' (U+2254) -_operators['\u2254'] = C_('math symbol', 'colon equals') - -# Translators: this is the spoken representation for the character '≕' (U+2255) -_operators['\u2255'] = C_('math symbol', 'equals colon') - -# Translators: this is the spoken representation for the character '≖' (U+2256) -_operators['\u2256'] = C_('math symbol', 'ring in equal to') - -# Translators: this is the spoken representation for the character '≗' (U+2257) -_operators['\u2257'] = C_('math symbol', 'ring equal to') - -# Translators: this is the spoken representation for the character '≘' (U+2258) -_operators['\u2258'] = C_('math symbol', 'corresponds to') - -# Translators: this is the spoken representation for the character '≙' (U+2259) -_operators['\u2259'] = C_('math symbol', 'estimates') - -# Translators: this is the spoken representation for the character '≚' (U+225a) -_operators['\u225a'] = C_('math symbol', 'equiangular to') - -# Translators: this is the spoken representation for the character '≛' (U+225b) -_operators['\u225b'] = C_('math symbol', 'star equals') - -# Translators: this is the spoken representation for the character '≜' (U+225c) -_operators['\u225c'] = C_('math symbol', 'delta equal to') - -# Translators: this is the spoken representation for the character '≝' (U+225d) -_operators['\u225d'] = C_('math symbol', 'equal to by definition') - -# Translators: this is the spoken representation for the character '≞' (U+225e) -_operators['\u225e'] = C_('math symbol', 'measured by') - -# Translators: this is the spoken representation for the character '≟' (U+225f) -_operators['\u225f'] = C_('math symbol', 'questioned equal to') - -# Translators: this is the spoken representation for the character '≠' (U+2260) -_operators['\u2260'] = C_('math symbol', 'not equal to') - -# Translators: this is the spoken representation for the character '≡' (U+2261) -_operators['\u2261'] = C_('math symbol', 'identical to') - -# Translators: this is the spoken representation for the character '≢' (U+2262) -_operators['\u2262'] = C_('math symbol', 'not identical to') - -# Translators: this is the spoken representation for the character '≣' (U+2263) -_operators['\u2263'] = C_('math symbol', 'strictly equivalent to') - -# Translators: this is the spoken representation for the character '≤' (U+2264) -_operators['\u2264'] = C_('math symbol', 'less than or equal to') - -# Translators: this is the spoken representation for the character '≥' (U+2265) -_operators['\u2265'] = C_('math symbol', 'greater than or equal to') - -# Translators: this is the spoken representation for the character '≦' (U+2266) -_operators['\u2266'] = C_('math symbol', 'less than over equal to') - -# Translators: this is the spoken representation for the character '≧' (U+2267) -_operators['\u2267'] = C_('math symbol', 'greater than over equal to') - -# Translators: this is the spoken representation for the character '≨' (U+2268) -_operators['\u2268'] = C_('math symbol', 'less than but not equal to') - -# Translators: this is the spoken representation for the character '≩' (U+2269) -_operators['\u2269'] = C_('math symbol', 'greater than but not equal to') - -# Translators: this is the spoken representation for the character '≪' (U+226a) -_operators['\u226a'] = C_('math symbol', 'much less than') - -# Translators: this is the spoken representation for the character '≫' (U+226b) -_operators['\u226b'] = C_('math symbol', 'much greater than') - -# Translators: this is the spoken representation for the character '≬' (U+226c) -_operators['\u226c'] = C_('math symbol', 'between') - -# Translators: this is the spoken representation for the character '≭' (U+226d) -_operators['\u226d'] = C_('math symbol', 'not equivalent to') - -# Translators: this is the spoken representation for the character '≮' (U+226e) -_operators['\u226e'] = C_('math symbol', 'not less than') - -# Translators: this is the spoken representation for the character '≯' (U+226f) -_operators['\u226f'] = C_('math symbol', 'not greater than') - -# Translators: this is the spoken representation for the character '≰' (U+2270) -_operators['\u2270'] = C_('math symbol', 'neither less than nor equal to') - -# Translators: this is the spoken representation for the character '≱' (U+2271) -_operators['\u2271'] = C_('math symbol', 'neither greater than nor equal to') - -# Translators: this is the spoken representation for the character '≲' (U+2272) -_operators['\u2272'] = C_('math symbol', 'less than or equivalent to') - -# Translators: this is the spoken representation for the character '≳' (U+2273) -_operators['\u2273'] = C_('math symbol', 'greater than or equivalent to') - -# Translators: this is the spoken representation for the character '≴' (U+2274) -_operators['\u2274'] = C_('math symbol', 'neither less than nor equivalent to') - -# Translators: this is the spoken representation for the character '≵' (U+2275) -_operators['\u2275'] = C_('math symbol', 'neither greater than nor equivalent to') - -# Translators: this is the spoken representation for the character '≶' (U+2276) -_operators['\u2276'] = C_('math symbol', 'less than or greater than') - -# Translators: this is the spoken representation for the character '≷' (U+2277) -_operators['\u2277'] = C_('math symbol', 'greater than or less than') - -# Translators: this is the spoken representation for the character '≸' (U+2278) -_operators['\u2278'] = C_('math symbol', 'neither less than nor greater than') - -# Translators: this is the spoken representation for the character '≹' (U+2279) -_operators['\u2279'] = C_('math symbol', 'neither greater than nor less than') - -# Translators: this is the spoken representation for the character '≺' (U+227a) -_operators['\u227a'] = C_('math symbol', 'precedes') - -# Translators: this is the spoken representation for the character '≻' (U+227b) -_operators['\u227b'] = C_('math symbol', 'succeeds') - -# Translators: this is the spoken representation for the character '≼' (U+227c) -_operators['\u227c'] = C_('math symbol', 'precedes or equal to') - -# Translators: this is the spoken representation for the character '≽' (U+227d) -_operators['\u227d'] = C_('math symbol', 'succeeds or equal to') - -# Translators: this is the spoken representation for the character '≾' (U+227e) -_operators['\u227e'] = C_('math symbol', 'precedes or equivalent to') - -# Translators: this is the spoken representation for the character '≿' (U+227f) -_operators['\u227f'] = C_('math symbol', 'succeeds or equivalent to') - -# Translators: this is the spoken representation for the character '⊀' (U+2280) -_operators['\u2280'] = C_('math symbol', 'does not precede') - -# Translators: this is the spoken representation for the character '⊁' (U+2281) -_operators['\u2281'] = C_('math symbol', 'does not succeed') - -# Translators: this is the spoken representation for the character '⊂' (U+2282) -_operators['\u2282'] = C_('math symbol', 'subset of') - -# Translators: this is the spoken representation for the character '⊃' (U+2283) -_operators['\u2283'] = C_('math symbol', 'superset of') - -# Translators: this is the spoken representation for the character '⊄' (U+2284) -_operators['\u2284'] = C_('math symbol', 'not a subset of') - -# Translators: this is the spoken representation for the character '⊅' (U+2285) -_operators['\u2285'] = C_('math symbol', 'not a superset of') - -# Translators: this is the spoken representation for the character '⊆' (U+2286) -_operators['\u2286'] = C_('math symbol', 'subset of or equal to') - -# Translators: this is the spoken representation for the character '⊇' (U+2287) -_operators['\u2287'] = C_('math symbol', 'superset of or equal to') - -# Translators: this is the spoken representation for the character '⊈' (U+2288) -_operators['\u2288'] = C_('math symbol', 'neither a subset of nor equal to') - -# Translators: this is the spoken representation for the character '⊉' (U+2289) -_operators['\u2289'] = C_('math symbol', 'neither a superset of nor equal to') - -# Translators: this is the spoken representation for the character '⊊' (U+228a) -_operators['\u228a'] = C_('math symbol', 'subset of with not equal to') - -# Translators: this is the spoken representation for the character '⊋' (U+228b) -_operators['\u228b'] = C_('math symbol', 'superset of with not equal to') - -# Translators: this is the spoken representation for the character '⊌' (U+228c) -_operators['\u228c'] = C_('math symbol', 'multiset') - -# Translators: this is the spoken representation for the character '⊍' (U+228d) -_operators['\u228d'] = C_('math symbol', 'multiset multiplication') - -# Translators: this is the spoken representation for the character '⊎' (U+228e) -_operators['\u228e'] = C_('math symbol', 'multiset union') - -# Translators: this is the spoken representation for the character '⊏' (U+228f) -_operators['\u228f'] = C_('math symbol', 'square image of') - -# Translators: this is the spoken representation for the character '⊐' (U+2290) -_operators['\u2290'] = C_('math symbol', 'square original of') - -# Translators: this is the spoken representation for the character '⊑' (U+2291) -_operators['\u2291'] = C_('math symbol', 'square image of or equal to') - -# Translators: this is the spoken representation for the character '⊒' (U+2292) -_operators['\u2292'] = C_('math symbol', 'square original of or equal to') - -# Translators: this is the spoken representation for the character '⊓' (U+2293) -_operators['\u2293'] = C_('math symbol', 'square cap') - -# Translators: this is the spoken representation for the character '⊔' (U+2294) -_operators['\u2294'] = C_('math symbol', 'square cup') - -# Translators: this is the spoken representation for the character '⊕' (U+2295) -_operators['\u2295'] = C_('math symbol', 'circled plus') - -# Translators: this is the spoken representation for the character '⊖' (U+2296) -_operators['\u2296'] = C_('math symbol', 'circled minus') - -# Translators: this is the spoken representation for the character '⊗' (U+2297) -_operators['\u2297'] = C_('math symbol', 'circled times') - -# Translators: this is the spoken representation for the character '⊘' (U+2298) -_operators['\u2298'] = C_('math symbol', 'circled division slash') - -# Translators: this is the spoken representation for the character '⊙' (U+2299) -_operators['\u2299'] = C_('math symbol', 'circled dot operator') - -# Translators: this is the spoken representation for the character '⊚' (U+229a) -_operators['\u229a'] = C_('math symbol', 'circled ring operator') - -# Translators: this is the spoken representation for the character '⊛' (U+229b) -_operators['\u229b'] = C_('math symbol', 'circled asterisk operator') - -# Translators: this is the spoken representation for the character '⊜' (U+229c) -_operators['\u229c'] = C_('math symbol', 'circled equals') - -# Translators: this is the spoken representation for the character '⊝' (U+229d) -_operators['\u229d'] = C_('math symbol', 'circled dash') - -# Translators: this is the spoken representation for the character '⊞' (U+229e) -_operators['\u229e'] = C_('math symbol', 'squared plus') - -# Translators: this is the spoken representation for the character '⊟' (U+229f) -_operators['\u229f'] = C_('math symbol', 'squared minus') - -# Translators: this is the spoken representation for the character '⊠' (U+22a0) -_operators['\u22a0'] = C_('math symbol', 'squared times') - -# Translators: this is the spoken representation for the character '⊡' (U+22a1) -_operators['\u22a1'] = C_('math symbol', 'squared dot operator') - -# Translators: this is the spoken representation for the character '⊢' (U+22a2) -_operators['\u22a2'] = C_('math symbol', 'right tack') - -# Translators: this is the spoken representation for the character '⊣' (U+22a3) -_operators['\u22a3'] = C_('math symbol', 'left tack') - -# Translators: this is the spoken representation for the character '⊤' (U+22a4) -_operators['\u22a4'] = C_('math symbol', 'down tack') - -# Translators: this is the spoken representation for the character '⊥' (U+22a5) -_operators['\u22a5'] = C_('math symbol', 'up tack') - -# Translators: this is the spoken representation for the character '⊦' (U+22a6) -_operators['\u22a6'] = C_('math symbol', 'assertion') - -# Translators: this is the spoken representation for the character '⊧' (U+22a7) -_operators['\u22a7'] = C_('math symbol', 'models') - -# Translators: this is the spoken representation for the character '⊨' (U+22a8) -_operators['\u22a8'] = C_('math symbol', 'true') - -# Translators: this is the spoken representation for the character '⊩' (U+22a9) -_operators['\u22a9'] = C_('math symbol', 'forces') - -# Translators: this is the spoken representation for the character '⊪' (U+22aa) -_operators['\u22aa'] = C_('math symbol', 'triple vertical bar right turnstile') - -# Translators: this is the spoken representation for the character '⊫' (U+22ab) -_operators['\u22ab'] = C_('math symbol', 'double vertical bar double right turnstile') - -# Translators: this is the spoken representation for the character '⊬' (U+22ac) -_operators['\u22ac'] = C_('math symbol', 'does not prove') - -# Translators: this is the spoken representation for the character '⊭' (U+22ad) -_operators['\u22ad'] = C_('math symbol', 'not true') - -# Translators: this is the spoken representation for the character '⊮' (U+22ae) -_operators['\u22ae'] = C_('math symbol', 'does not force') - -# Translators: this is the spoken representation for the character '⊯' (U+22af) -_operators['\u22af'] = C_('math symbol', 'negated double vertical bar double right turnstile') - -# Translators: this is the spoken representation for the character '⊰' (U+22b0) -_operators['\u22b0'] = C_('math symbol', 'precedes under relation') - -# Translators: this is the spoken representation for the character '⊱' (U+22b1) -_operators['\u22b1'] = C_('math symbol', 'succeeds under relation') - -# Translators: this is the spoken representation for the character '⊲' (U+22b2) -_operators['\u22b2'] = C_('math symbol', 'normal subgroup of') - -# Translators: this is the spoken representation for the character '⊳' (U+22b3) -_operators['\u22b3'] = C_('math symbol', 'contains as normal subgroup') - -# Translators: this is the spoken representation for the character '⊴' (U+22b4) -_operators['\u22b4'] = C_('math symbol', 'normal subgroup of or equal to') - -# Translators: this is the spoken representation for the character '⊵' (U+22b5) -_operators['\u22b5'] = C_('math symbol', 'contains as normal subgroup of or equal to') - -# Translators: this is the spoken representation for the character '⊶' (U+22b6) -_operators['\u22b6'] = C_('math symbol', 'original of') - -# Translators: this is the spoken representation for the character '⊷' (U+22b7) -_operators['\u22b7'] = C_('math symbol', 'image of') - -# Translators: this is the spoken representation for the character '⊸' (U+22b8) -_operators['\u22b8'] = C_('math symbol', 'multimap') - -# Translators: this is the spoken representation for the character '⊹' (U+22b9) -_operators['\u22b9'] = C_('math symbol', 'hermitian conjugate matrix') - -# Translators: this is the spoken representation for the character '⊺' (U+22ba) -_operators['\u22ba'] = C_('math symbol', 'intercalate') - -# Translators: this is the spoken representation for the character '⊻' (U+22bb) -_operators['\u22bb'] = C_('math symbol', 'xor') - -# Translators: this is the spoken representation for the character '⊼' (U+22bc) -_operators['\u22bc'] = C_('math symbol', 'nand') - -# Translators: this is the spoken representation for the character '⊽' (U+22bd) -_operators['\u22bd'] = C_('math symbol', 'nor') - -# Translators: this is the spoken representation for the character '⊾' (U+22be) -_operators['\u22be'] = C_('math symbol', 'right angle with arc') - -# Translators: this is the spoken representation for the character '⊿' (U+22bf) -_operators['\u22bf'] = C_('math symbol', 'right triangle') - -# Translators: this is the spoken representation for the character '⋀' (U+22c0) -_operators['\u22c0'] = C_('math symbol', 'logical and') - -# Translators: this is the spoken representation for the character '⋁' (U+22c1) -_operators['\u22c1'] = C_('math symbol', 'logical or') - -# Translators: this is the spoken representation for the character '⋂' (U+22c2) -_operators['\u22c2'] = C_('math symbol', 'intersection') - -# Translators: this is the spoken representation for the character '⋃' (U+22c3) -_operators['\u22c3'] = C_('math symbol', 'union') - -# Translators: this is the spoken representation for the character '⋄' (U+22c4) -_operators['\u22c4'] = C_('math symbol', 'diamond operator') - -# Translators: this is the spoken representation for the character '⋅' (U+22c5) -_operators['\u22c5'] = C_('math symbol', 'dot operator') - -# Translators: this is the spoken representation for the character '⋆' (U+22c6) -_operators['\u22c6'] = C_('math symbol', 'star operator') - -# Translators: this is the spoken representation for the character '⋇' (U+22c7) -_operators['\u22c7'] = C_('math symbol', 'division times') - -# Translators: this is the spoken representation for the character '⋈' (U+22c8) -_operators['\u22c8'] = C_('math symbol', 'bowtie') - -# Translators: this is the spoken representation for the character '⋉' (U+22c9) -_operators['\u22c9'] = C_('math symbol', 'left normal factor semidirect product') - -# Translators: this is the spoken representation for the character '⋊' (U+22ca) -_operators['\u22ca'] = C_('math symbol', 'right normal factor semidirect product') - -# Translators: this is the spoken representation for the character '⋋' (U+22cb) -_operators['\u22cb'] = C_('math symbol', 'left semidirect product') - -# Translators: this is the spoken representation for the character '⋌' (U+22cc) -_operators['\u22cc'] = C_('math symbol', 'right semidirect product') - -# Translators: this is the spoken representation for the character '⋍' (U+22cd) -_operators['\u22cd'] = C_('math symbol', 'reversed tilde equals') - -# Translators: this is the spoken representation for the character '⋎' (U+22ce) -_operators['\u22ce'] = C_('math symbol', 'curly logical or') - -# Translators: this is the spoken representation for the character '⋏' (U+22cf) -_operators['\u22cf'] = C_('math symbol', 'curly logical and') - -# Translators: this is the spoken representation for the character '⋐' (U+22d0) -_operators['\u22d0'] = C_('math symbol', 'double subset') - -# Translators: this is the spoken representation for the character '⋑' (U+22d1) -_operators['\u22d1'] = C_('math symbol', 'double superset') - -# Translators: this is the spoken representation for the character '⋒' (U+22d2) -_operators['\u22d2'] = C_('math symbol', 'double intersection') - -# Translators: this is the spoken representation for the character '⋓' (U+22d3) -_operators['\u22d3'] = C_('math symbol', 'double union') - -# Translators: this is the spoken representation for the character '⋔' (U+22d4) -_operators['\u22d4'] = C_('math symbol', 'pitchfork') - -# Translators: this is the spoken representation for the character '⋕' (U+22d5) -_operators['\u22d5'] = C_('math symbol', 'equal and parallel to') - -# Translators: this is the spoken representation for the character '⋖' (U+22d6) -_operators['\u22d6'] = C_('math symbol', 'less than with dot') - -# Translators: this is the spoken representation for the character '⋗' (U+22d7) -_operators['\u22d7'] = C_('math symbol', 'greater than with dot') - -# Translators: this is the spoken representation for the character '⋘' (U+22d8) -_operators['\u22d8'] = C_('math symbol', 'very much less than') - -# Translators: this is the spoken representation for the character '⋙' (U+22d9) -_operators['\u22d9'] = C_('math symbol', 'very much greater than') - -# Translators: this is the spoken representation for the character '⋚' (U+22da) -_operators['\u22da'] = C_('math symbol', 'less than equal to or greater than') - -# Translators: this is the spoken representation for the character '⋛' (U+22db) -_operators['\u22db'] = C_('math symbol', 'greater than equal to or less than') - -# Translators: this is the spoken representation for the character '⋜' (U+22dc) -_operators['\u22dc'] = C_('math symbol', 'equal to or less than') - -# Translators: this is the spoken representation for the character '⋝' (U+22dd) -_operators['\u22dd'] = C_('math symbol', 'equal to or greater than') - -# Translators: this is the spoken representation for the character '⋝' (U+22de) -_operators['\u22de'] = C_('math symbol', 'equal to or precedes') - -# Translators: this is the spoken representation for the character '⋝' (U+22df) -_operators['\u22df'] = C_('math symbol', 'equal to or succeeds') - -# Translators: this is the spoken representation for the character '⋠' (U+22e0) -_operators['\u22e0'] = C_('math symbol', 'does not precede or equal') - -# Translators: this is the spoken representation for the character '⋡' (U+22e1) -_operators['\u22e1'] = C_('math symbol', 'does not succeed or equal') - -# Translators: this is the spoken representation for the character '⋢' (U+22e2) -_operators['\u22e2'] = C_('math symbol', 'not square image of or equal to') - -# Translators: this is the spoken representation for the character '⋣' (U+22e3) -_operators['\u22e3'] = C_('math symbol', 'not square original of or equal to') - -# Translators: this is the spoken representation for the character '⋤' (U+22e4) -_operators['\u22e4'] = C_('math symbol', 'square image of or not equal to') - -# Translators: this is the spoken representation for the character '⋥' (U+22e5) -_operators['\u22e5'] = C_('math symbol', 'square original of or not equal to') - -# Translators: this is the spoken representation for the character '⋦' (U+22e6) -_operators['\u22e6'] = C_('math symbol', 'less than but not equivalent to') - -# Translators: this is the spoken representation for the character '⋧' (U+22e7) -_operators['\u22e7'] = C_('math symbol', 'greater than but not equivalent to') - -# Translators: this is the spoken representation for the character '⋨' (U+22e8) -_operators['\u22e8'] = C_('math symbol', 'precedes but not equivalent to') - -# Translators: this is the spoken representation for the character '⋩' (U+22e9) -_operators['\u22e9'] = C_('math symbol', 'succeeds but not equivalent to') - -# Translators: this is the spoken representation for the character '⋪' (U+22ea) -_operators['\u22ea'] = C_('math symbol', 'not normal subgroup of') - -# Translators: this is the spoken representation for the character '⋫' (U+22eb) -_operators['\u22eb'] = C_('math symbol', 'does not contain as normal subgroup') - -# Translators: this is the spoken representation for the character '⋬' (U+22ec) -_operators['\u22ec'] = C_('math symbol', 'not normal subgroup of or equal to') - -# Translators: this is the spoken representation for the character '⋭' (U+22ed) -_operators['\u22ed'] = C_('math symbol', 'does not contain as normal subgroup or equal') - -# Translators: this is the spoken representation for the character '⋮' (U+22ee) -_operators['\u22ee'] = C_('math symbol', 'vertical ellipsis') - -# Translators: this is the spoken representation for the character '⋯' (U+22ef) -_operators['\u22ef'] = C_('math symbol', 'midline horizontal ellipsis') - -# Translators: this is the spoken representation for the character '⋰' (U+22f0) -_operators['\u22f0'] = C_('math symbol', 'up right diagonal ellipsis') - -# Translators: this is the spoken representation for the character '⋱' (U+22f1) -_operators['\u22f1'] = C_('math symbol', 'down right diagonal ellipsis') - -# Translators: this is the spoken representation for the character '⋲' (U+22f2) -_operators['\u22f2'] = C_('math symbol', 'element of with long horizontal stroke') - -# Translators: this is the spoken representation for the character '⋳' (U+22f3) -_operators['\u22f3'] = C_('math symbol', - 'element of with vertical bar at end of horizontal stroke') - -# Translators: this is the spoken representation for the character '⋴' (U+22f4) -_operators['\u22f4'] = C_('math symbol', - 'small element of with vertical bar at end of horizontal stroke') - -# Translators: this is the spoken representation for the character '⋵' (U+22f5) -_operators['\u22f5'] = C_('math symbol', 'element of with dot above') - -# Translators: this is the spoken representation for the character '⋶' (U+22f6) -_operators['\u22f6'] = C_('math symbol', 'element of with overbar') - -# Translators: this is the spoken representation for the character '⋷' (U+22f7) -_operators['\u22f7'] = C_('math symbol', 'small element of with overbar') - -# Translators: this is the spoken representation for the character '⋸' (U+22f8) -_operators['\u22f8'] = C_('math symbol', 'element of with underbar') - -# Translators: this is the spoken representation for the character '⋹' (U+22f9) -_operators['\u22f9'] = C_('math symbol', 'element of with two horizontal strokes') - -# Translators: this is the spoken representation for the character '⋺' (U+22fa) -_operators['\u22fa'] = C_('math symbol', 'contains with long horizontal stroke') - -# Translators: this is the spoken representation for the character '⋻' (U+22fb) -_operators['\u22fb'] = C_('math symbol', 'contains with vertical bar at end of horizontal stroke') - -# Translators: this is the spoken representation for the character '⋼' (U+22fc) -_operators['\u22fc'] = C_('math symbol', - 'small contains with vertical bar at end of horizontal stroke') - -# Translators: this is the spoken representation for the character '⋽' (U+22fd) -_operators['\u22fd'] = C_('math symbol', 'contains with overbar') - -# Translators: this is the spoken representation for the character '⋾' (U+22fe) -_operators['\u22fe'] = C_('math symbol', 'small contains with overbar') - -# Translators: this is the spoken representation for the character '⋿' (U+22ff) -_operators['\u22ff'] = C_('math symbol', 'z notation bag membership') - -# Translators: this is the spoken representation for the character '⌈' (U+2308) -_operators['\u2308'] = C_('math symbol', 'left ceiling') - -# Translators: this is the spoken representation for the character '⌉' (U+2309) -_operators['\u2309'] = C_('math symbol', 'right ceiling') - -# Translators: this is the spoken representation for the character '⌊' (U+230a) -_operators['\u230a'] = C_('math symbol', 'left floor') - -# Translators: this is the spoken representation for the character '⌋' (U+230b) -_operators['\u230b'] = C_('math symbol', 'right floor') - -# Translators: this is the spoken representation for the character '⏞' (U+23de) -_operators['\u23de'] = C_('math symbol', 'top brace') - -# Translators: this is the spoken representation for the character '⏟' (U+23df) -_operators['\u23df'] = C_('math symbol', 'bottom brace') - -# Translators: this is the spoken representation for the character '⟨' (U+27e8) -_operators['\u27e8'] = C_('math symbol', 'left angle bracket') - -# Translators: this is the spoken representation for the character '⟩' (U+27e9) -_operators['\u27e9'] = C_('math symbol', 'right angle bracket') - -# Translators: this is the spoken representation for the character '⨀' (U+2a00) -_operators['\u2a00'] = C_('math symbol', 'circled dot') - -# Translators: this is the spoken representation for the character '⨁' (U+2a01) -_operators['\u2a01'] = C_('math symbol', 'circled plus') - -# Translators: this is the spoken representation for the character '⨂' (U+2a02) -_operators['\u2a02'] = C_('math symbol', 'circled times') -# Translators: this is the spoken representation for the character '⨃' (U+2a03) -_operators['\u2a03'] = C_('math symbol', 'union with dot') -# Translators: this is the spoken representation for the character '⨄' (U+2a04) -_operators['\u2a04'] = C_('math symbol', 'union with plus') -# Translators: this is the spoken representation for the character '⨅' (U+2a05) -_operators['\u2a05'] = C_('math symbol', 'square intersection') -# Translators: this is the spoken representation for the character '⨆' (U+2a06) -_operators['\u2a06'] = C_('math symbol', 'square union') - -# Translators: this is the spoken representation for the character '■' (U+25a0) -# when used as a geometric shape (i.e. as opposed to a bullet in a list). -_shapes['\u25a0'] = C_('math symbol', 'black square') - -# Translators: this is the spoken representation for the character '□' (U+25a1) -# when used as a geometric shape (i.e. as opposed to a bullet in a list). -_shapes['\u25a1'] = C_('math symbol', 'white square') - -# Translators: this is the spoken representation for the character '◆' (U+25c6) -# when used as a geometric shape (i.e. as opposed to a bullet in a list). -_shapes['\u25c6'] = C_('math symbol', 'black diamond') - -# Translators: this is the spoken representation for the character '○' (U+25cb) -# when used as a geometric shape (i.e. as opposed to a bullet in a list). -_shapes['\u25cb'] = C_('math symbol', 'white circle') - -# Translators: this is the spoken representation for the character '●' (U+25cf) -# when used as a geometric shape (i.e. as opposed to a bullet in a list). -_shapes['\u25cf'] = C_('math symbol', 'black circle') - -# Translators: this is the spoken representation for the character '◦' (U+25e6) -_shapes['\u25e6'] = C_('math symbol', 'white bullet') - -# Translators: this is the spoken representation for the character '◾' (U+25fe) -# when used as a geometric shape (i.e. as opposed to a bullet in a list). -_shapes['\u25fe'] = C_('math symbol', 'black medium small square') - -# Translators: this is the spoken representation for the character '̱' (U+0331) -# which combines with the preceding character. '%s' is a placeholder for the -# preceding character. Some examples of combined symbols can be seen in this -# table: http://www.w3.org/TR/MathML3/appendixc.html#oper-dict.entries-table. -_combining['\u0331'] = C_('math symbol', '%s with underline') - -# Translators: this is the spoken representation for the character '̸' (U+0338) -# which combines with the preceding character. '%s' is a placeholder for the -# preceding character. Some examples of combined symbols can be seen in this -# table: http://www.w3.org/TR/MathML3/appendixc.html#oper-dict.entries-table. -_combining['\u0338'] = C_('math symbol', '%s with slash') - -# Translators: this is the spoken representation for the character '⃒' (U+20D2) -# which combines with the preceding character. '%s' is a placeholder for the -# preceding character. Some examples of combined symbols can be seen in this -# table: http://www.w3.org/TR/MathML3/appendixc.html#oper-dict.entries-table. -_combining['\u20D2'] = C_('math symbol', '%s with vertical line') - -_all.update(_alnum) -_all.update(_arrows) -_all.update(_operators) -_all.update(_shapes) -_RE = None -_RE_COMBINING = None - -def __compileRE(): - global _RE - try: - _RE = re.compile(f"[{''.join(list(_all.keys()))}]", re.UNICODE) - except Exception: - _RE = None - -def __compileRE_COMBINING(): - global _RE_COMBINING - try: - _RE_COMBINING = re.compile(f".[{''.join(list(_combining.keys()))}]", - re.UNICODE) - except Exception: - _RE_COMBINING = None - -def _getStyleString(symbol): - o = ord(symbol) - if o in _bold or o in _boldGreek or o in _boldDigits: - return BOLD - if o in _italic or o in _italicGreek or o in _otherItalic: - return ITALIC - if o in _boldItalic or o in _boldItalicGreek: - return BOLD_ITALIC - if o in _script or o in _otherScript: - return SCRIPT - if o in _boldScript: - return BOLD_SCRIPT - if o in _fraktur or o in _otherFraktur: - return FRAKTUR - if o in _doubleStruck or o in _doubleStruckDigits or o in _otherDoubleStruck: - return DOUBLE_STRUCK - if o in _boldFraktur: - return BOLD_FRAKTUR - if o in _sansSerif or o in _sansSerifDigits: - return SANS_SERIF - if o in _sansSerifBold or o in _sansSerifBoldGreek or o in _sansSerifBoldDigits: - return SANS_SERIF_BOLD - if o in _sansSerifItalic: - return SANS_SERIF_ITALIC - if o in _sansSerifBoldItalic or o in _sansSerifBoldItalicGreek: - return SANS_SERIF_BOLD_ITALIC - if o in _monospace or o in _monospaceDigits: - return MONOSPACE - if o in _dotless: - return DOTLESS - - return "%s" - -def updateSymbols(symbolDict): - global _all - _all.update(symbolDict) - -def _getSpokenName(symbol, includeStyle): - if symbol not in _all: - return "" - - name = _all.get(symbol) - if not name and fallbackOnUnicodeData: - name = unicodedata.name(symbol).lower() - updateSymbols({symbol: name}) - return name - - if includeStyle and symbol in _alnum: - name = _getStyleString(symbol) % name - - return name - -def getCharacterName(symbol): - return _getSpokenName(symbol, speakStyle != SPEAK_NEVER) - -def adjustForSpeech(string): - if _RE is None: - __compileRE() - - if _RE_COMBINING is None: - __compileRE_COMBINING() - - if _RE_COMBINING is not None: - combiningPairs = set(re.findall(_RE_COMBINING, string)) - for pair in combiningPairs: - name = _combining.get(pair[1]) - if name: - string = re.sub(pair, f" {name % pair[0]} ", string) - - if _RE is not None: - chars = set(re.findall(_RE, string)) - includeStyle = speakStyle == SPEAK_ALWAYS - for char in chars: - name = _getSpokenName(char, includeStyle) - if name: - string = re.sub(char, f" {name} ", string) - - return string diff --git a/src/cthulhu/meson.build b/src/cthulhu/meson.build deleted file mode 100644 index 3c9a005..0000000 --- a/src/cthulhu/meson.build +++ /dev/null @@ -1,189 +0,0 @@ -# Python sources to install -cthulhu_python_sources = files([ - '__init__.py', - 'acss.py', - 'action_presenter.py', - 'ax_collection.py', - 'ax_component.py', - 'ax_document.py', - 'ax_document_selection.py', - 'ax_event_synthesizer.py', - 'ax_hypertext.py', - 'ax_object.py', - 'ax_selection.py', - 'ax_table.py', - 'ax_text.py', - 'ax_utilities_application.py', - 'ax_utilities.py', - 'ax_utilities_collection.py', - 'ax_utilities_debugging.py', - 'ax_utilities_event.py', - 'ax_utilities_relation.py', - 'ax_utilities_role.py', - 'ax_utilities_state.py', - 'ax_value.py', - 'bookmarks.py', - 'braille.py', - 'braille_generator.py', - 'braille_rolenames.py', - 'brlmon.py', - 'brltablenames.py', - 'caret_navigation.py', - 'chat.py', - 'chnames.py', - 'cmdnames.py', - 'colornames.py', - 'compositor_state_adapter.py', - 'compositor_state_i3.py', - 'compositor_state_types.py', - 'compositor_state_wayland.py', - 'common_keyboardmap.py', - 'cthulhuVersion.py', - 'cthulhu_modifier_manager.py', - 'cthulhu_state.py', - 'date_and_time_presenter.py', - 'dbus_service.py', - 'debug.py', - 'desktop_keyboardmap.py', - 'dynamic_api_manager.py', - 'event_manager.py', - 'find.py', - 'flat_review.py', - 'flat_review_presenter.py', - 'formatting.py', - 'focus_manager.py', - 'generator.py', - 'gstreamer_support.py', - 'guilabels.py', - 'highlighter.py', - 'input_event.py', - 'input_event_manager.py', - 'keybindings.py', - 'keynames.py', - 'label_inference.py', - 'laptop_keyboardmap.py', - 'learn_mode_presenter.py', - 'liveregions.py', - 'logger.py', - 'mako_notification_monitor.py', - 'mathsymbols.py', - 'messages.py', - 'mouse_review.py', - 'notification_presenter.py', - 'object_navigator.py', - 'object_properties.py', - 'cthulhu.py', - 'cthulhu_gtkbuilder.py', - 'cthulhu_gui_find.py', - 'cthulhu_gui_navlist.py', - 'cthulhu_gui_prefs.py', - 'cthulhu_gui_profile.py', - 'phonnames.py', - 'plugin.py', - 'plugin_system_manager.py', - 'pronunciation_dict.py', - 'punctuation_settings.py', - 'resource_manager.py', - 'role_keys.py', - 'script.py', - 'script_manager.py', - 'script_utilities.py', - 'screen_lock_monitor.py', - 'settings.py', - 'settings_manager.py', - 'signal_manager.py', - 'sleep_mode_manager.py', - 'sound.py', - 'sound_helper.py', - 'sound_sink.py', - 'sound_generator.py', - 'sound_theme_manager.py', - 'speech_and_verbosity_manager.py', - 'speech_history.py', - 'speech.py', - 'spellcheck.py', - 'speechdispatcherfactory.py', - 'hardwarefactory.py', - 'speech_generator.py', - 'speechserver.py', - 'piperfactory.py', - 'piper_voice_manager.py', - 'piper_audio_player.py', - 'structural_navigation.py', - 'text_attribute_names.py', - 'translation_context.py', - 'translation_manager.py', - 'tutorialgenerator.py', - 'typing_echo_presenter.py', - 'wnck_support.py', - 'where_am_i_presenter.py', - 'wine_access_manager.py', -]) - -# Note: Main executable (cthulhu) is installed from src/cthulhu.py - -# Install Python sources -python3.install_sources( - cthulhu_python_sources, - subdir: 'cthulhu' -) - -# Install generated Python sources -cthulhu_bin_py = configure_file( - input: 'cthulhu_bin.py.in', - output: 'cthulhu_bin.py', - configuration: { - 'PLATFORM_PATH': ':/usr/bin:/usr/sbin:/bin', - 'prefix': get_option('prefix'), - 'bindir': get_option('bindir'), - 'libdir': get_option('libdir'), - 'datadir': get_option('datadir'), - 'PYTHON': python3.full_path(), - 'PYTHON_PREFIX': python3.get_install_dir(), - 'pythondir': python3.get_install_dir(), - } -) - -cthulhu_i18n_py = configure_file( - input: 'cthulhu_i18n.py.in', - output: 'cthulhu_i18n.py', - configuration: { - 'GETTEXT_PACKAGE': 'cthulhu', - 'prefix': get_option('prefix'), - 'datadir': get_option('datadir'), - 'localedir': get_option('datadir') / 'locale', - } -) - -cthulhu_platform_py = configure_file( - input: 'cthulhu_platform.py.in', - output: 'cthulhu_platform.py', - configuration: { - 'prefix': get_option('prefix'), - 'bindir': get_option('bindir'), - 'libdir': get_option('libdir'), - 'datadir': get_option('prefix') / get_option('datadir'), - 'sysconfdir': get_option('sysconfdir'), - 'localstatedir': get_option('localstatedir'), - 'PACKAGE': 'cthulhu', - 'REVISION': run_command('git', 'rev-parse', '--short', 'HEAD', check: false).stdout().strip(), - 'LOUIS_TABLE_DIR': '/usr/share/liblouis/tables', - } -) - -python3.install_sources( - [cthulhu_bin_py, cthulhu_i18n_py, cthulhu_platform_py], - subdir: 'cthulhu' -) - -# UI files -install_data( - ['cthulhu-find.ui', 'cthulhu-setup.ui'], - install_dir: get_option('datadir') / 'cthulhu' / 'ui' -) - -# Subdirectories -subdir('backends') -subdir('scripts') -subdir('wayland_protocols') -subdir('plugins') diff --git a/src/cthulhu/messages.py b/src/cthulhu/messages.py deleted file mode 100644 index 4b5e259..0000000 --- a/src/cthulhu/messages.py +++ /dev/null @@ -1,2937 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Messages which Cthulhu presents in speech and/or braille. These -have been put in their own module so that we can present them in -the correct language when users change the synthesizer language -on the fly without having to reload a bunch of modules.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2013 The Cthulhu Team" -__license__ = "LGPL" - -from .cthulhu_i18n import _, C_, ngettext -from .cthulhu_platform import version - -# Translators: Sometimes when we attempt to get the name of an accessible -# software application, we fail because the app or one of its elements is -# defunct. This is a generic name so that we can still refer to this element -# in messages. -APPLICATION_NO_NAME = C_("generic name", "application") - -# Translators: This is presented when the user has navigated to an empty line. -BLANK = _("blank") - -# Translators: This refers to font weight. -BOLD = _("bold") - -# Translators: Cthulhu has a feature in which users can store/save a particular -# location in an application window and return to it later by pressing a -# keystroke. These stored/saved locations are "bookmarks". This string is -# presented to the user when a new bookmark has been entered into the list -# of bookmarks. -BOOKMARK_ENTERED = _("bookmark entered") - -# Translators: Cthulhu has a feature in which users can store/save a particular -# location in an application window and return to it later by pressing a -# keystroke. These stored/saved locations are "bookmarks". This string is -# presented to the user when the active list of bookmarks have been saved to -# disk. -BOOKMARKS_SAVED = _("bookmarks saved") - -# Translators: Cthulhu has a feature in which users can store/save a particular -# location in an application window and return to it later by pressing a -# keystroke. These stored/saved locations are "bookmarks". This string is -# presented to the user when an error was encountered, preventing the active -# list of bookmarks being saved to disk. -BOOKMARKS_SAVED_FAILURE = _("bookmarks could not be saved") - -# Translators: Cthulhu has a feature in which users can store/save a particular -# location in an application window and return to it later by pressing a -# keystroke. These stored/saved locations are "bookmarks". This string is -# presented to the user when they try to go to a bookmark, but don't have -# any bookmarks. -BOOKMARKS_NOT_FOUND = _("No bookmarks found.") - -# Translators: Cthulhu has a feature in which users can store/save a particular -# location in an application window and return to it later by pressing a -# keystroke. These stored/saved locations are "bookmarks". This string is -# presented to the user when they try to go to a bookmark at a particular -# index (e.g. bookmark 1 or bookmark 2) but there is no bookmark stored at -# that index. -BOOKMARK_NOT_FOUND = _("Bookmark not found.") - -# Translators: Cthulhu normally intercepts all keyboard commands and only passes -# them along to the current application when they are not Cthulhu commands. This -# command causes the next command issued to be passed along to the current -# application, bypassing Cthulhu's interception of it. -BYPASS_MODE_ENABLED = _("Bypass mode enabled.") - -# Translators: this is an indication that Cthulhu is unable to obtain the display/ -# results area of the calculator being used (e.g. gcalctool). -CALCULATOR_DISPLAY_NOT_FOUND = _("Unable to get calculator display") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via -# text-to-speech. Speech Dispatcher has a feature to control how capital -# letters are presented: Do nothing at all, say the word 'capital' prior to -# presenting a capital letter, or play a tone which Speech Dispatcher refers -# to as a sound 'icon'. This string to be translated refers to the brief/ -# non-verbose output presented in response to the use of an Cthulhu command which -# makes it possible for users to quickly cycle amongst these alternatives -# without having to get into a GUI. -CAPITALIZATION_ICON_BRIEF = C_("capitalization style", "icon") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via -# text-to-speech. Speech Dispatcher has a feature to control how capital -# letters are presented: Do nothing at all, say the word 'capital' prior to -# presenting a capital letter, or play a tone which Speech Dispatcher refers -# to as a sound 'icon'. This string to be translated refers to the full/verbose -# output presented in response to the use of an Cthulhu command which makes it -# possible for users to quickly cycle amongst these alternatives without having -# to get into a GUI. -CAPITALIZATION_ICON_FULL = _("Capitalization style set to icon.") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via -# text-to-speech. Speech Dispatcher has a feature to control how capital -# letters are presented: Do nothing at all, say the word 'capital' prior to -# presenting a capital letter, or play a tone which Speech Dispatcher refers -# to as a sound 'icon'. This string to be translated refers to the brief/ -# non-verbose output presented in response to the use of an Cthulhu command which -# makes it possible for users to quickly cycle amongst these alternatives -# without having to get into a GUI. -CAPITALIZATION_NONE_BRIEF = C_("capitalization style", "none") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via -# text-to-speech. Speech Dispatcher has a feature to control how capital -# letters are presented: Do nothing at all, say the word 'capital' prior to -# presenting a capital letter, or play a tone which Speech Dispatcher refers -# to as a sound 'icon'. This string to be translated refers to the full/verbose -# output presented in response to the use of an Cthulhu command which makes it -# possible for users to quickly cycle amongst these alternatives without having -# to get into a GUI. -CAPITALIZATION_NONE_FULL = _("Capitalization style set to none.") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via -# text-to-speech. Speech Dispatcher has a feature to control how capital -# letters are presented: Do nothing at all, say the word 'capital' prior to -# presenting a capital letter, or play a tone which Speech Dispatcher refers -# to as a sound 'icon'. This string to be translated refers to the brief/ -# non-verbose output presented in response to the use of an Cthulhu command which -# makes it possible for users to quickly cycle amongst these alternatives -# without having to get into a GUI. -CAPITALIZATION_SPELL_BRIEF = C_("capitalization style", "spell") - -# Translators: Cthulhu uses Speech Dispatcher to present content to users via -# text-to-speech. Speech Dispatcher has a feature to control how capital -# letters are presented: Do nothing at all, say the word 'capital' prior to -# presenting a capital letter, or play a tone which Speech Dispatcher refers -# to as a sound 'icon'. This string to be translated refers to the full/verbose -# output presented in response to the use of an Cthulhu command which makes it -# possible for users to quickly cycle amongst these alternatives without having -# to get into a GUI. -CAPITALIZATION_SPELL_FULL = _("Capitalization style set to spell.") - -# Translators: Native application caret navigation does not always work as the -# Cthulhu user wants. As such, Cthulhu offers the user the ability to toggle between -# the application controlling the caret and Cthulhu controlling it. This message -# is presented to indicate that the application's native caret navigation is -# active / not being overridden by Cthulhu. -CARET_CONTROL_APP = _("The application is controlling the caret.") - -# Translators: Gecko native caret navigation is where Firefox (or Thunderbird) -# itself controls how the arrow keys move the caret around HTML content. It's -# often broken, so Cthulhu needs to provide its own support. As such, Cthulhu offers -# the user the ability to toggle which application is controlling the caret. -CARET_CONTROL_CTHULHU = _("Cthulhu is controlling the caret.") - -# Translators: this is the name of a cell in a spreadsheet. -CELL = _("Cell %s") - -# Translators: this message is spoken to announce that a table cell just became -# selected (e.g as a result of navigation via Shift + Arrows). The string -# substitution is the cell name. In the case of a spreadsheet the cell name -# will be something like "B3". -CELL_SELECTED = C_("cell", "%s selected") - -# Translators: this message is spoken to announce that multiple table cells just -# became selected (e.g as a result of navigation via Shift + Arrows). The first -# string substitution is the name of the first cell in the range. The second string -# substitution is for the name of the last cell in the range. An example message -# for Calc would be "A1 through A30 selected". -CELL_RANGE_SELECTED = C_("cell", "%s through %s selected") - -# Translators: this message is spoken to announce that multiple table cells just -# became unselected (e.g as a result of navigation via Shift + Arrows). The first -# string substitution is the name of the first cell in the range. The second string -# substitution is for the name of the last cell in the range. An example message -# for Calc would be "A1 through A30 unselected". -CELL_RANGE_UNSELECTED = C_("cell", "%s through %s unselected") - -# Translators: this message is spoken to announce that a table cell just became -# unselected (e.g as a result of navigation via Shift + Arrows). The string -# substitution is the cell name. In the case of a spreadsheet the cell name -# will be something like "B3". -CELL_UNSELECTED = C_("cell", "%s unselected") - -# Translators: This is the description of command line option '-d, --disable' -# which allows the user to specify an option to disable as Cthulhu is started. -CLI_DISABLE_OPTION = _("Prevent use of option") - -# Translators: this is the description of command line option '-e, --enable' -# which allows the user to specify an option to enable as Cthulhu is started. -CLI_ENABLE_OPTION = _("Force use of option") - -# Translators: This string indicates to the user what should be provided when -# using the '-e, --enable' or '-d, --disable' command line options. -CLI_OPTION = _("OPTION") - -# Translators: This string appears when using 'Cthulhu -h' at the command line. -# It serves as a sort of title and is followed by a detailed list of Cthulhu's -# optional command-line arguments. -CLI_OPTIONAL_ARGUMENTS = _("Optional arguments") - -# Translators: This string appears when using 'Cthulhu -h' at the command line. -# It is followed by a brief list of Cthulhu's optional command-line arguments. -CLI_USAGE = _("Usage: ") - -# Translators: This message is displayed when the user starts Cthulhu from the -# command line and includes an invalid option or argument. After the message, -# the list of invalid items, as typed by the user, is displayed. -CLI_INVALID_OPTIONS = _("The following are not valid: ") - -# Translators: This is the description of command line option '-l, --list-apps' -# which prints the names of running applications which can be seen by assistive -# technologies such as Cthulhu and Accerciser. -CLI_LIST_APPS = _("Print the known running applications") - -# Translators: This is the description of command line option '-p, --profile' -# which allows you to specify a profile to be loaded. A profile stores a group -# of Cthulhu settings configured by the user for a particular purpose, such as a -# 'Spanish' profile which would include Spanish braille and text-to-speech. -# An Cthulhu settings file contains one or more profiles. -CLI_LOAD_PROFILE = _("Load profile") - -# Translators: This message is presented to the user when the specified profile -# could not be loaded. A profile stores a group of Cthulhu settings configured for -# a particular purpose, such as a Spanish profile which would include Spanish -# braille and Spanish text-to-speech. The string substituted in is the user- -# provided profile name. -CLI_LOAD_PROFILE_ERROR = _("Profile could not be loaded: %s") - -# Translators: This message is presented to the user who attempts to launch Cthulhu -# from some other environment than the graphical desktop. -CLI_NO_DESKTOP_ERROR = \ - _("Cannot start Cthulhu because it cannot connect to the Desktop.") - -# Translators: This message is presented to the user who attempts to launch Cthulhu -# but the launch fails due to an error related to the settings manager. -CLI_SETTINGS_MANAGER_ERROR = \ - _("Could not activate the settings manager. Exiting.") - -# Translators: This message is presented to the user when he/she tries to launch -# Cthulhu, but Cthulhu is already running. -CLI_OTHER_CTHULHUS_ERROR = \ - _('Another Cthulhu process is already running for this ' \ - 'session.\nRun “cthulhu --replace” to replace that ' \ - 'process with a new one.') - -# Translators: This string indicates to the user what should be provided when -# using the '-p, --profile' command line option. -CLI_PROFILE_NAME = _("NAME") - -# Translators: This is the description of command line option '-u, --user-prefs' -# that allows you to specify an alternate location from which to load the user -# preferences. -CLI_LOAD_PREFS = _("Use alternate directory for user preferences") - -# Translators: This string indicates to the user what should be provided when -# using the '-u, --user-prefs' command line option. -CLI_PREFS_DIR = _("DIR") - -# Translators: This is the description of command line option '-v, --version' -# which prints the version of Cthulhu. E.g. '1.23.4'. -CLI_VERSION = _("Version of this application") - -# Translators: This is the description of command line option '-r, --replace' -# which tells Cthulhu to replace any existing Cthulhu process that might be running. -CLI_REPLACE = _("Replace a currently running instance of Cthulhu") - -# Translators: this is the description of command line option '-h, --help' -# which lists all the available command line options. -CLI_HELP = _("Show this help message and exit") - -# Translators: This is the description of command line option '--debug' which -# causes debugging output for Cthulhu to be sent to a file. The YYYY-MM-DD-HH:MM:SS -# portion of the string indicates the file name will be formed from the current -# date and time with 'debug' in front and '.out' at the end. The 'debug' and -# '.out' portions of this string should not be translated (i.e. it should always -# start with 'debug' and end with '.out', regardless of the locale.). -CLI_ENABLE_DEBUG = _("Send debug output to debug-YYYY-MM-DD-HH:MM:SS.out") - -# Translators: This is the description of command line option '--debug-startup' -# which causes Cthulhu to print concise startup timing information without -# enabling the full debug output stream. -CLI_ENABLE_STARTUP_DEBUG = _("Send concise startup timing output") - -# Translators: This is the description of command line option '--debug-file' -# which allows the user to override the default date-based name of the debugging -# output file. -CLI_DEBUG_FILE = _("Send debug output to the specified file") - -# Translators: This string indicates to the user what should be provided when -# using the '--debug-file' command line option. -CLI_DEBUG_FILE_NAME = _("FILE") - -# Translators: This is the description of command line option '-t, --text-setup' -# that will initially display a list of questions in text form, that the user -# will need to answer, before Cthulhu will startup. For this to happen properly, -# Cthulhu will need to be run from a terminal window. -CLI_SETUP = _("Set up user preferences (text version)") - -# Translators: This is the description of command line option '-s, --setup' -# that will place the user in Cthulhu's GUI preferences dialog. -CLI_GUI_SETUP = _("Set up user preferences (GUI version)") - -# Translators: This text is the description displayed when Cthulhu is launched -# from the command line and the help text is displayed. -CLI_EPILOG = _("Report bugs to https://groups.io/g/stormux.") - -# Translators: Cthulhu normal speaks the text which was just deleted from a -# document via command. Depending on the circumstances, that might be a -# large string. Therefore, if the text which has just been deleted from a -# document matches the clipboard contents, Cthulhu will indicate that fact -# instead of presenting the full string which was just deleted. This message -# is the full/verbose indication. -CLIPBOARD_CUT_FULL = _("Cut selection to clipboard.") - -# Translators: Cthulhu normal speaks the text which was just deleted from a -# document via command. Depending on the circumstances, that might be a -# large string. Therefore, if the text which has just been deleted from a -# document matches the clipboard contents, Cthulhu will indicate that fact -# instead of presenting the full string which was just deleted. This message -# is the brief indication. -CLIPBOARD_CUT_BRIEF = C_("clipboard", "cut") - -# Translators: This message is the detailed message presented when the contents -# of the clipboard have changed and match the current selection. -CLIPBOARD_COPIED_FULL = _("Copied selection to clipboard.") - -# Translators: This message is the brief message presented when the contents -# of the clipboard have changed and match the current selection. -CLIPBOARD_COPIED_BRIEF = C_("clipboard", "copied") - -# Translators: Cthulhu normal speaks the text which was just inserted into a -# document via command. Depending on the circumstances, that might be a -# large string. Therefore, if the text which has just been inserted into a -# document matches the clipboard contents, Cthulhu will indicate that fact -# instead of presenting the full string which was just inserted. This message -# is the full/verbose indication. -CLIPBOARD_PASTED_FULL = _("Pasted contents from clipboard.") - -# Translators: Cthulhu normal speaks the text which was just inserted into a -# document via command. Depending on the circumstances, that might be a -# large string. Therefore, if the text which has just been inserted into a -# document matches the clipboard contents, Cthulhu will indicate that fact -# instead of presenting the full string which was just inserted. This message -# is the brief indication. -CLIPBOARD_PASTED_BRIEF = C_("clipboard", "pasted") - -# Translators: In chat applications, it is often possible to see that a "buddy" -# is typing currently (e.g. via a keyboard icon or status text). Some users like -# to have this typing status announced by Cthulhu; others find that announcement -# unpleasant. Therefore, it is a setting in Cthulhu. This string to be translated -# is presented when the value of the setting is toggled. -CHAT_BUDDY_TYPING_OFF = _("Do not announce when your buddies are typing.") - -# Translators: In chat applications, it is often possible to see that a "buddy" -# is typing currently (e.g. via a keyboard icon or status text). Some users like -# to have this typing status announced by Cthulhu; others find that announcement -# unpleasant. Therefore, it is a setting in Cthulhu. This string to be translated -# is presented when the value of the setting is toggled. -CHAT_BUDDY_TYPING_ON = _("announce when your buddies are typing.") - -# Translators: In chat applications, Cthulhu automatically presents incoming -# messages in speech and braille. If a user is in multiple conversations or -# channels at the same time, it can be confusing to know what room or channel -# a given message came from just from hearing/reading it. This string to be -# translated is presented to the user to clarify where an incoming message -# came from. The name of the chat room is the string substitution. -CHAT_MESSAGE_FROM_ROOM = _("Message from chat room %s") - -# Translators: This message is presented to inform the user that a new chat -# conversation has been added to the existing conversations. The "tab" here -# refers to the tab which contains the label for a GtkNotebook page. The -# label on the tab is the string substitution. -CHAT_NEW_TAB = _("New chat tab %s") - -# Translators: In chat applications, Cthulhu automatically presents incoming -# messages in speech and braille. If a user is in multiple conversations or -# channels at the same time, it can be confusing to know what room or channel -# a given message came from just from hearing/reading it. For this reason, Cthulhu -# has an option to present the name of the room first ("#a11y hello!" -# instead of " hello!"). This string to be translated is presented when -# the value of the setting is toggled. -CHAT_ROOM_NAME_PREFIX_OFF = _("Do not speak chat room name.") - -# Translators: In chat applications, Cthulhu automatically presents incoming -# messages in speech and braille. If a user is in multiple conversations or -# channels at the same time, it can be confusing to know what room or channel -# a given message came from just from hearing/reading it. For this reason, Cthulhu -# has an option to present the name of the room first ("#a11y hello!" -# instead of " hello!"). This string to be translated is presented when -# the value of the setting is toggled. -CHAT_ROOM_NAME_PREFIX_ON = _("speak chat room name.") - -# Translators: Cthulhu has a command to review previous chat room messages in -# speech and braille. Some users prefer to have this message history combined -# (e.g. the last ten messages which came in, no matter what room they came -# from). Other users prefer to have specific room history (e.g. the last ten -# messages from #a11y). Therefore, this is a setting in Cthulhu. This string to be -# translated is presented when the value of the setting is toggled. -CHAT_SEPARATE_HISTORIES_OFF = \ - _("Do not provide chat room specific message histories.") - -# Translators: Cthulhu has a command to review previous chat room messages in -# speech and braille. Some users prefer to have this message history combined -# (e.g. the last ten messages which came in, no matter what room they came -# from). Other users prefer to have specific room history (e.g. the last ten -# messages from #a11y). Therefore, this is a setting in Cthulhu. This string to be -# translated is presented when the value of the setting is toggled. -CHAT_SEPARATE_HISTORIES_ON = _("Provide chat room specific message histories.") - -DATE_FORMAT_LOCALE = "%x" -DATE_FORMAT_NUMBERS_DM = "%d/%m" -DATE_FORMAT_NUMBERS_MD = "%m/%d" -DATE_FORMAT_NUMBERS_DMY = "%d/%m/%Y" -DATE_FORMAT_NUMBERS_MDY = "%m/%d/%Y" -DATE_FORMAT_NUMBERS_YMD = "%Y/%m/%d" -DATE_FORMAT_FULL_DM = "%A, %-d %B" -DATE_FORMAT_FULL_MD = "%A, %B %-d" -DATE_FORMAT_FULL_DMY = "%A, %-d %B, %Y" -DATE_FORMAT_FULL_MDY = "%A, %B %-d, %Y" -DATE_FORMAT_FULL_YMD = "%Y. %B %-d, %A" -DATE_FORMAT_ABBREVIATED_DM = "%a, %-d %b" -DATE_FORMAT_ABBREVIATED_MD = "%a, %b %-d" -DATE_FORMAT_ABBREVIATED_DMY = "%a, %-d %b, %Y" -DATE_FORMAT_ABBREVIATED_MDY = "%a, %b %-d, %Y" -DATE_FORMAT_ABBREVIATED_YMD = "%Y. %b %-d, %a" - -# Translators: This phrase is spoken to inform the user that what is about to -# be said is content marked for deletion in a document, such as content which -# is inside an HTML 'del' element, or the removed code in a diff. -CONTENT_DELETION_START = C_("content", "deletion start") - -# Translators: This phrase is spoken to inform the user that they have reached -# the end of content marked for deletion in a document, such as content which -# is inside an HTML 'del' element, or the removed code in a diff. -CONTENT_DELETION_END = C_("content", "deletion end") - -# Translators: This phrase is spoken to inform the user that what is about to -# be said is content marked for insertion in a document, such as content which -# is inside an HTML 'ins' element, or the added code in a diff. -CONTENT_INSERTION_START = C_("content", "insertion start") - -# Translators: This phrase is spoken to inform the user that they have reached -# the end of content marked for deletion in a document, such as content which -# is inside an HTML 'ins' element, or the added code in a diff. -CONTENT_INSERTION_END = C_("content", "insertion end") - -# Translators: This phrase is spoken to inform the user that what is about to -# be said is content marked/highlighted in a document, such as content which -# is inside an HTML 'mark' element. -CONTENT_MARK_START = C_("content", "highlight start") - -# Translators: This phrase is spoken to inform the user that they have reached -# the end of content marked/highlighted in a document, such as content which -# is inside an HTML 'mark' element. -CONTENT_MARK_END = C_("content", "highlight end") - -# Translators: This phrase is spoken to inform the user that the content being -# presented is the end of an inline suggestion a document. A "suggestion" is a -# proposed change. This change can include the insertion and/or deletion -# of content, and would typically be seen in a collaborative editor, such as -# in Google Docs. -CONTENT_SUGGESTION_END = C_("content", "suggestion end") - -# Translators: This is for navigating document content by moving to the start -# or end of a container. Examples of containers include tables, lists, and -# blockquotes. When moving to the end of a container, Cthulhu attempts to place -# the caret at the content which follows that container. If this is cannot be -# done (e.g. because the container is the last element on the page), Cthulhu will -# instead present this message as an indication that the container was not -# exited as expected. -CONTAINER_END = _("End of container.") - -# Translators: This is for navigating document content by moving to the start -# or end of a container. Examples of containers include tables, lists, and -# blockquotes. If the user attempts to use this command in an object which is -# not a container, this message will be presented. -CONTAINER_NOT_IN_A = _("Not in a container.") - -# Translators: This message is presented when the user selects all of the items -# in a container that supports selection, such as a GUI table or a list of icons. -CONTAINER_SELECTED_ALL = _("all items selected") - -# Translators: The "default" button in a dialog box is the button that gets -# activated when Enter is pressed anywhere within that dialog box. The string -# substitution is the name of the button (e.g. "OK" or "Close"). -DEFAULT_BUTTON_IS = _("Default button is %s") - -# Translators: The "default" button in a dialog box is the button that gets -# activated when Enter is pressed anywhere within that dialog box. This -# message is presented when the default button was found but is insensitive / -# grayed out / cannot be activated. The string substitution is the name of -# the button (e.g. "OK" or "Close"). When translating "Grayed," please use -# the same word used for the string in object_properties.py. -DEFAULT_BUTTON_IS_GRAYED = _("Default button is %s. Grayed") - -# Translators: The "default" button in a dialog box is the button that gets -# activated when Enter is pressed anywhere within that dialog box. Cthulhu has -# a command to present the default button. This is the message Cthulhu will -# present if it could not find the default button. -DEFAULT_BUTTON_NOT_FOUND = _("Default button not found") - -# Translators: This string is part of the presentation of an item that includes -# one or several consecutive subscripted characters. For example, 'X' followed -# by 'subscript 2' followed by 'subscript 3' should be presented to the user as -# 'X subscript 23'. -DIGITS_SUBSCRIPT = _(" subscript %s") - -# Translators: This string is part of the presentation of an item that includes -# one or several consecutive superscripted characters. For example, 'X' followed -# by 'superscript 2' followed by 'superscript 3' should be presented to the user -# as 'X superscript 23'. -DIGITS_SUPERSCRIPT = _(" superscript %s") - -# Translators: this message is presented when the user tries to perform a command -# specific to dialog boxes, such as presenting the default button, but is not in -# a dialog. -DIALOG_NOT_IN_A = _("Not in a dialog") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects the entire -# document by pressing Ctrl+A. -DOCUMENT_SELECTED_ALL = _("entire document selected") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the entire document had been -# selected but the user presses a key (e.g. an arrow key) causing the -# selection to be completely removed. -DOCUMENT_UNSELECTED_ALL = _("entire document unselected") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the end of the document by pressing Ctrl+Shift+End. -DOCUMENT_SELECTED_DOWN = _("document selected from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user unselects previously -# selected text by pressing Ctrl+Shift+End. -DOCUMENT_UNSELECTED_DOWN = _("document unselected from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the start of the document by pressing Ctrl+Shift+Home. -DOCUMENT_SELECTED_UP = _("document selected to cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user unselects previously -# selected text by pressing Ctrl+Shift+Home. -DOCUMENT_UNSELECTED_UP = _("document unselected to cursor position") - -# Translators: Cthulhu allows you to dynamically define which row of a spreadsheet -# or table should be treated as containing column headers. This message is -# presented when the user sets the row to a particular row number. -DYNAMIC_COLUMN_HEADER_SET = _("Dynamic column header set for row %d") - -# Translators: Cthulhu allows you to dynamically define which row of a spreadsheet -# or table should be treated as containing column headers. This message is -# presented when the user unsets the row so it is no longer treated as if it -# contained column headers. -DYNAMIC_COLUMN_HEADER_CLEARED = _("Dynamic column header cleared.") - -# Translators: Cthulhu allows you to dynamically define which column of a -# spreadsheet or table should be treated as containing column headers. This -# message is presented when the user sets the column to a particular column -# number. -DYNAMIC_ROW_HEADER_SET = _("Dynamic row header set for column %s") - -# Translators: Cthulhu allows you to dynamically define which column of a -# spreadsheet or table should be treated as containing column headers. This -# message is presented when the user unsets the column so it is no longer -# treated as if it contained row headers. -DYNAMIC_ROW_HEADER_CLEARED = _("Dynamic row header cleared.") - -# Translators: this is used to announce that the current input line in a -# spreadsheet is blank/empty. -EMPTY = _("empty") - -# Translators: This is the size of a file in kilobytes -FILE_SIZE_KB = _("%.2f kilobytes") - -# Translators: This is the size of a file in megabytes -FILE_SIZE_MB = _("%.2f megabytes") - -# Translators: This message is presented to the user after performing a file -# search to indicate there were no matches. -FILES_NOT_FOUND = _("No files found.") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. This message is presented to -# let the user know that he/she successfully appended the contents under -# flat review onto the existing contents of the clipboard. -FLAT_REVIEW_APPENDED = _("Appended contents to clipboard.") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. This message is presented to -# let the user know that he/she successfully copied the contents under flat -# review to the clipboard. -FLAT_REVIEW_COPIED = _("Copied contents to clipboard.") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. This message is presented to -# let the user know that he/she attempted to use a flat review command when -# not using flat review. -FLAT_REVIEW_NOT_IN = _("Not using flat review.") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. This message is presented to -# let the user know he/she just entered flat review. -FLAT_REVIEW_START = _("Entering flat review.") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. This message is presented to -# let the user know he/she just entered flat review. -FLAT_REVIEW_STOP = _("Leaving flat review.") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. This message is presented to -# let the user know that flat review is being restricted to the current -# object of interest. -FLAT_REVIEW_RESTRICTED = _("Flat review restricted to the current object") - -# Translators: the 'flat review' feature of Cthulhu allows the blind user to -# explore the text in a window in a 2D fashion. That is, Cthulhu treats all -# the text from all objects in a window (e.g., buttons, labels, etc.) as a -# sequence of words in a sequence of lines. This message is presented to -# let the user know that flat review is unrestricted, -# that is, the entire window can be explored. -FLAT_REVIEW_UNRESTRICTED = _("Flat review unrestricted") - -# Translators: this means a particular cell in a spreadsheet has a formula -# (e.g., "=sum(a1:d1)") -HAS_FORMULA = _("has formula") - -# Translators: this message will be presented to indicate the focused object -# will cause a dialog to appear if activated. -HAS_POPUP_DIALOG = _("opens dialog") - -# Translators: this message will be presented to indicate the focused object -# will cause a grid to appear if activated. A grid is an interactive table. -HAS_POPUP_GRID = _("opens grid") - -# Translators: this message will be presented to indicate the focused object -# will cause a listbox to appear if activated. -HAS_POPUP_LISTBOX = _("opens listbox") - -# Translators: this message will be presented to indicate the focused object -# will cause a menu to appear if activated. -HAS_POPUP_MENU = _("opens menu") - -# Translators: this message will be presented to indicate the focused object -# will cause a tree to appear if activated. A tree is a list with sub-levels -# which can be expanded or collapsed, similar to the list of folders in an -# email client. -HAS_POPUP_TREE = _("opens tree") - -# Translators: The following string is spoken to let the user know that he/she -# is on a link within an image map. An image map is an image/graphic which has -# been divided into regions. Each region can be clicked on and has an associated -# link. Please see http://en.wikipedia.org/wiki/Imagemap for more information -# and examples. -IMAGE_MAP_LINK = _("image map link") - -# Translators: This is a spoken and/or brailled message letting the user know -# that the key combination (e.g., Ctrl+Alt+f) they just entered has already been -# bound to another command and is thus unavailable. The string substituted in is -# the name of the command which already has the binding. -KB_ALREADY_BOUND = _("The key entered is already bound to %s") - -# Translators: This is a spoken and/or brailled message letting the user know -# that Cthulhu has recorded a new key combination (e.g. Alt+Ctrl+g) as a result of -# their input. The string substituted in is the new key combination. -KB_CAPTURED = _("Key captured: %s. Press enter to confirm.") - -# Translators: This is a spoken and/or brailled message letting the user know -# that Cthulhu has assigned a new key combination (e.g. Alt+Ctrl+g) as a result of -# their input. The string substituted in is the new key combination. -KB_CAPTURED_CONFIRMATION = _("The new key is: %s") - -# Translators: This is a spoken and/or brailled message letting the user know -# Cthulhu is about to delete an existing key combination (e.g. Alt+Ctrl+g) as a -# result of their input. -KB_DELETED = _("Key binding deleted. Press enter to confirm.") - -# Translators: This is a spoken and/or brailled message letting the user know -# Cthulhu has deleted an existing key combination (e.g. Alt+Ctrl+g) as a result of -# their input. -KB_DELETED_CONFIRMATION = _("The keybinding has been removed.") - -# Translators: This is a spoken and/or brailled message asking the user to press -# a new key combination (e.g., Alt+Ctrl+g) to create a new key binding for an -# Cthulhu command. -KB_ENTER_NEW_KEY = _("enter new key") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. The -# following string is a brief message which will be presented to the user who -# is cycling amongst the various echo options. -KEY_ECHO_KEY_BRIEF = C_("key echo", "key") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. -KEY_ECHO_KEY_FULL = _("Echo set to key.") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. The -# following string is a brief message which will be presented to the user who -# is cycling amongst the various echo options. -KEY_ECHO_NONE_BRIEF = C_("key echo", "None") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. -KEY_ECHO_NONE_FULL = _("Echo set to None.") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. The -# following string is a brief message which will be presented to the user who -# is cycling amongst the various echo options. -KEY_ECHO_KEY_AND_WORD_BRIEF = C_("key echo", "key and word") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. -KEY_ECHO_KEY_AND_WORD_FULL = _("Echo set to key and word.") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. The -# following string is a brief message which will be presented to the user who -# is cycling amongst the various echo options. -KEY_ECHO_SENTENCE_BRIEF = C_("key echo", "sentence") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. -KEY_ECHO_SENTENCE_FULL = _("Echo set to sentence.") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. The -# following string is a brief message which will be presented to the user who -# is cycling amongst the various echo options. -KEY_ECHO_WORD_BRIEF = C_("key echo", "word") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. -KEY_ECHO_WORD_FULL = _("Echo set to word.") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. The -# following string is a brief message which will be presented to the user who -# is cycling amongst the various echo options. -KEY_ECHO_WORD_AND_SENTENCE_BRIEF = C_("key echo", "word and sentence") - -# Translators: Cthulhu has an "echo" setting which allows the user to configure -# what is spoken in response to a key press. Given a user who typed "Hello -# world.": -# - key echo: "H e l l o space w o r l d period" -# - word echo: "Hello" spoken when the space is pressed; -# "world" spoken when the period is pressed. -# - sentence echo: "Hello world" spoken when the period -# is pressed. -# A user can choose to have no echo, one type of echo, or multiple types of -# echo and can cycle through the various levels quickly via a command. -KEY_ECHO_WORD_AND_SENTENCE_FULL = _("Echo set to word and sentence.") - -# Translators: This phrase is spoken to inform the user of all of the MathML -# enclosure notations associated with a given mathematical expression. For -# instance, the expression x+y could be enclosed by a box, or enclosed by a -# circle. It could also be enclosed by a box and a circle and long division -# sign and have a line on the left and on the right and a vertical strike. -# (Though let's hope not.) Given that we do not know the enclosures, their -# order, or their combination, we'll present them as a list. The string -# substitution is for that list of enclosure types. For more information -# about the MathML 'menclose' element and its notation types, see: -# http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_ENCLOSED_BY = C_("math enclosure", "Enclosed by: %s") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_ACTUARIAL = C_("math enclosure", "an actuarial symbol") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_BOX = C_("math enclosure", "a box") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_CIRCLE = C_("math enclosure", "a circle") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_LONGDIV = C_("math enclosure", "a long division sign") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_RADICAL = C_("math enclosure", "a radical") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_ROUNDEDBOX = C_("math enclosure", "a rounded box") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_HORIZONTALSTRIKE = C_("math enclosure", "a horizontal strike") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_VERTICALSTRIKE = C_("math enclosure", "a vertical strike") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_DOWNDIAGONALSTRIKE = C_("math enclosure", "a down diagonal strike") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_UPDIAGONALSTRIKE = C_("math enclosure", "an up diagonal strike") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_NORTHEASTARROW = C_("math enclosure", "a northeast arrow") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_BOTTOM = C_("math enclosure", "a line at the bottom") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_LEFT = C_("math enclosure", "a line on the left") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_RIGHT = C_("math enclosure", "a line on the right") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_TOP = C_("math enclosure", "a line at the top") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_PHASOR_ANGLE = C_("math enclosure", "a phasor angle") - -# Translators: This phrase is spoken to describe one MathML enclosure notation -# associated with a mathematical expression. Because an expression, such as -# x+y, can have one or many enclosure notations (box, circle, long division, -# line on the left, vertical strike), we present them as a list of notations. -# For more information about the MathML 'menclose' element and its notation -# types, see: http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -# This particular string is for the "madruwb" notation type. -MATH_ENCLOSURE_MADRUWB = C_("math enclosure", "an arabic factorial symbol") - -# Translators: This phrase is spoken to inform the user of all of the MathML -# enclosure notations associated with a given mathematical expression. For -# instance, the expression x+y could be enclosed by a box, or enclosed by a -# circle. It could also be enclosed by a box and a circle and long division -# sign and have a line on the left and on the right and a vertical strike. -# (Though let's hope not.) Given that we do not know the enclosures, their -# order, or their combination, we'll present them as a list. This string -# will be inserted before the final item in the list if there is more than -# one enclosure notation. For more information about the MathML 'menclose' -# element and its notation types, see: -# http://www.w3.org/TR/MathML3/chapter3.html#presm.menclose -MATH_ENCLOSURE_AND = C_("math enclosure", "and") - -# Translators: This phrase is spoken to inform the user that what is about to -# be said is part of a mathematical fraction. For instance, given x+1/y+2, Cthulhu -# would say "fraction start, x+1 over y+2, fraction end." -MATH_FRACTION_START = _("fraction start") - -# Translators: This phrase is spoken to inform the user that what is about to -# be said is part of a mathematical fraction whose bar is not displayed. See -# https://en.wikipedia.org/wiki/Combination for an example. Note that the -# comma is inserted here to cause a very brief pause in the speech. Otherwise, -# in English, the resulting speech sounds like we have a fraction which lacks -# the start of the bar. If this is a non-issue for your language, the comma and -# the pause which results is not needed. You should be able to test this with -# "spd-say " in a terminal on a machine where speech-dispatcher -# is installed. -MATH_FRACTION_WITHOUT_BAR_START = _("fraction without bar, start") - -# Translators: This word refers to the line separating the numerator from the -# denominator in a mathematical fraction. For instance, given x+1/y+2, Cthulhu -# would would say "fraction start, x+1 over y+2, fraction end." -MATH_FRACTION_LINE = C_("math fraction", "over") - -# Translators: This phrase is spoken to inform the user that the last spoken -# phrase is the end of a mathematical fraction. For instance, given x+1/y+2, -# Cthulhu would would say "fraction start, x+1 over y+2, fraction end." -MATH_FRACTION_END = _("fraction end") - -# Translators: This phrase is spoken to inform the user that what is about to -# be spoken is a square root. For instance, for √9 Cthulhu would say "square root -# of 9, root end" (assuming the user settings indicate that root endings should -# be spoken). Note that the radicand, which follows the "of", is unknown and -# might not even be a simple string; it might be the square root of another -# expression such as a fraction. -MATH_SQUARE_ROOT_OF = _("square root of") - -# Translators: This phrase is spoken to inform the user that what is about to -# be spoken is a cube root. For instance, for the cube root of 9 Cthulhu would -# say "cube root of 9, root end" (assuming the user settings indicate that root -# endings should be spoken). Note that the radicand, which follows the "of", -# is unknown and might not even be a simple string; it might be the cube root -# of another expression such as a fraction. -MATH_CUBE_ROOT_OF = _("cube root of") - -# Translators: This phrase is spoken to inform the user that what is about to -# be spoken is an nth root. https://en.wikipedia.org/wiki/Nth_root. For instance, -# for the fourth root of 9, Cthulhu would say "fourth root of 9, root end" (assuming -# the user settings indicate that root endings should be spoken). Note that the -# index, which precedes this string, is unknown and might not even be a simple -# expression like "fourth"; the index might instead be a fraction. -MATH_ROOT_OF = _("root of") - -# Translators: This phrase is spoken to inform the user that what is about to -# be said is part of a mathematical root (square root, cube root, nth root). -# It is primarily intended to be spoken when the index of the root is not a -# simple expression. For instance, for the fourth root of 9, simply speaking -# "fourth root of 9" may be sufficient for the user. But if the index is not -# 4, but instead the fraction x/4, beginning the phrase with "root start" can -# help the user better understand that x/4 is the index of the root. -MATH_ROOT_START = _("root start") - -# Translators: This phrase is spoken to inform the user that the last spoken -# phrase is the end of a mathematical root (square root, cube root, nth root). -# For instance, for the cube root of 9, Cthulhu would say "cube root of 9, root -# end" (assuming the user settings indicate that root endings should be spoken). -MATH_ROOT_END = _("root end") - -# Translators: This phrase is spoken to inform the user that what is about to -# be spoken is subscripted text in a mathematical expression. Note that the -# subscript might be simple text or may itself be a mathematical expression, -# and in this instance we have no additional context through which a more user- -# friendly word or phrase can reliably be chosen. -MATH_SUBSCRIPT = C_("math script generic", "subscript") - -# Translators: This phrase is spoken to inform the user that what is about to -# be spoken is superscripted text in a mathematical expression. Note that the -# superscript might be simple text or may itself be a mathematical expression, -# and in this instance we have no additional context through which a more user- -# friendly word or phrase can reliably be chosen. -MATH_SUPERSCRIPT = C_("math script generic", "superscript") - -# Translators: This phrase is spoken to inform the user that what is about to -# be spoken is subscripted text which precedes the base in a mathematical -# expression. See, for instance, the MathML mmultiscripts element: -# http://www.w3.org/TR/MathML3/chapter3.html#presm.mmultiscripts -# https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mmultiscripts -MATH_PRE_SUBSCRIPT = C_("math script", "pre-subscript") - -# Translators: This phrase is spoken to inform the user that what is about to -# be spoken is superscripted text which precedes the base in a mathematical -# expression. See, for instance, the MathML mmultiscripts element: -# http://www.w3.org/TR/MathML3/chapter3.html#presm.mmultiscripts -# https://developer.mozilla.org/en-US/docs/Web/MathML/Element/mmultiscripts -MATH_PRE_SUPERSCRIPT = C_("math script", "pre-superscript") - -# Translators: This phrase is spoken to inform the user that what is about to -# be spoken is underscripted text in a mathematical expression. Note that the -# underscript might be simple text or may itself be a mathematical expression, -# and in this instance we have no additional context through which a more user- -# friendly word or phrase can reliably be chosen. Examples of underscripts: -# http://www.w3.org/TR/MathML/chapter3.html#presm.munder -# https://reference.wolfram.com/language/ref/Underscript.html -MATH_UNDERSCRIPT = C_("math script generic", "underscript") - -# Translators: This phrase is spoken to inform the user that what is about to -# be spoken is overscripted text in a mathematical expression. Note that the -# overscript might be simple text or may itself be a mathematical expression, -# and in this instance we have no additional context through which a more user- -# friendly word or phrase can reliably be chosen. Examples of overscripts: -# http://www.w3.org/TR/MathML/chapter3.html#presm.mover -# https://reference.wolfram.com/language/ref/Overscript.html -MATH_OVERSCRIPT = C_("math script generic", "overscript") - -# Translators: This phrase is spoken to inform the user that the last spoken -# phrase is the end of a mathematical table. -MATH_TABLE_END = C_("math table", "table end") - -# Translators: This phrase is spoken to inform the user that the last spoken -# phrase is the end of a mathematical table which is nested inside another -# mathematical table. -MATH_NESTED_TABLE_END = C_("math table", "nested table end") - -# Translators: Inaccessible means that the application cannot be read by Cthulhu. -# This usually means the application is not friendly to the assistive technology -# infrastructure. -INACCESSIBLE = _("inaccessible") - -# Translators: This brief message indicates that indentation and -# justification will be spoken. -INDENTATION_JUSTIFICATION_OFF_BRIEF = \ - C_("indentation and justification", "Disabled") - -# Translators: This detailed message indicates that indentation and -# justification will not be spoken. -INDENTATION_JUSTIFICATION_OFF_FULL = \ - _("Speaking of indentation and justification disabled.") - -# Translators: This brief message indicates that indentation and -# justification will be spoken. -INDENTATION_JUSTIFICATION_ON_BRIEF = \ - C_("indentation and justification", "Enabled") - -# Translators: This detailed message indicates that indentation and -# justification will be spoken. -INDENTATION_JUSTIFICATION_ON_FULL = \ - _("Speaking of indentation and justification enabled.") - -# Translators: Cthulhu has a "Learn Mode" that will allow the user to type any key -# on the keyboard and hear what the effects of that key would be. The effects -# might be what Cthulhu would do if it had a handler for the particular key -# combination, or they might just be to echo the name of the key if Cthulhu doesn't -# have a handler. This message is what is presented on the braille display when -# entering Learn Mode. -LEARN_MODE_START_BRAILLE = _("Learn mode. Press escape to exit.") - -# Translators: Cthulhu has a "Learn Mode" that will allow the user to type any key -# on the keyboard and hear what the effects of that key would be. The effects -# might be what Cthulhu would do if it had a handler for the particular key -# combination, or they might just be to echo the name of the key if Cthulhu doesn't -# have a handler. This message is what is spoken to the user when entering Learn -# Mode. -LEARN_MODE_START_SPEECH = \ - _("Entering learn mode. Press any key to hear its function. " \ - "To view Cthulhu’s documentation, press F1. " \ - "To get a list of Cthulhu’s default shortcuts, press F2. " \ - "To get a list of Cthulhu’s shortcuts for the current application, " \ - "press F3. " \ - "To exit learn mode, press the escape key.") - -# Translators: This message is presented when a user is navigating within a -# blockquote and then navigates out of it. -LEAVING_BLOCKQUOTE = _("leaving blockquote.") - -# Translators: In web content, authors can identify an element which contains -# detailed information about another element. For instance, for a password -# field, there may be a list of requirements (number of characters, number of -# special symbols, etc.). For an image, there may be an extended description -# before or after the image. Often there are visual clues connecting the -# detailed information to its related object. We need to convey this non-visually. -# This message is presented when a user just navigated out of a container holding -# detailed information about another object. -# See https://w3c.github.io/aria/#aria-details -LEAVING_DETAILS = _("leaving details.") - -# Translators: This message is presented when a user is navigating within -# an object and then navigates out of it. The word or phrase that follows -# "leaving" should be consistent with the translation provided for the -# corresponding term with context "role" found in object_properties.py -LEAVING_FEED = C_("role", "leaving feed.") - -# Translators: This message is presented when a user is navigating within -# an object and then navigates out of it. The word or phrase that follows -# "leaving" should be consistent with the translation provided for the -# corresponding term with context "role" found in object_properties.py -LEAVING_FIGURE = C_("role", "leaving figure.") - -# Translators: This message is presented when a user is navigating within a -# form and then navigates out of it. -LEAVING_FORM = _("leaving form.") - -# Translators: This message is presented when a user is navigating within -# a type of landmark and then navigates out of it. The word or phrase that -# follows "leaving" should be consistent with the translation provided for -# the corresponding term with context "role" found in object_properties.py -LEAVING_LANDMARK_BANNER = C_("role", "leaving banner.") - -# Translators: This message is presented when a user is navigating within -# a type of landmark and then navigates out of it. The word or phrase that -# follows "leaving" should be consistent with the translation provided for -# the corresponding term with context "role" found in object_properties.py -LEAVING_LANDMARK_COMPLEMENTARY = C_("role", "leaving complementary content.") - -# Translators: This message is presented when a user is navigating within -# a type of landmark and then navigates out of it. The word or phrase that -# follows "leaving" should be consistent with the translation provided for -# the corresponding term with context "role" found in object_properties.py -LEAVING_LANDMARK_CONTENTINFO = C_("role", "leaving information.") - -# Translators: This message is presented when a user is navigating within -# a type of landmark and then navigates out of it. The word or phrase that -# follows "leaving" should be consistent with the translation provided for -# the corresponding term with context "role" found in object_properties.py -LEAVING_LANDMARK_MAIN = C_("role", "leaving main content.") - -# Translators: This message is presented when a user is navigating within -# a type of landmark and then navigates out of it. The word or phrase that -# follows "leaving" should be consistent with the translation provided for -# the corresponding term with context "role" found in object_properties.py -LEAVING_LANDMARK_NAVIGATION = C_("role", "leaving navigation.") - -# Translators: This message is presented when a user is navigating within -# a type of landmark and then navigates out of it. The word or phrase that -# follows "leaving" should be consistent with the translation provided for -# the corresponding term with context "role" found in object_properties.py -LEAVING_LANDMARK_REGION = C_("role", "leaving region.") - -# Translators: This message is presented when a user is navigating within -# a type of landmark and then navigates out of it. The word or phrase that -# follows "leaving" should be consistent with the translation provided for -# the corresponding term with context "role" found in object_properties.py -LEAVING_LANDMARK_SEARCH = C_("role", "leaving search.") - -# Translators: This message is presented when a user is navigating within a -# list and then navigates out of it. -LEAVING_LIST = _("leaving list.") - -# Translators: This message is presented when a user is navigating within a -# panel and then navigates out of it. A panel is a generic container of -# objects, such as a group of related form fields. -LEAVING_PANEL = _("leaving panel.") - -# Translators: This message is presented when a user is navigating within a -# table and then navigates out of it. -LEAVING_TABLE = _("leaving table.") - -# Translators: This message is presented when a user is navigating within a -# tooltip in a web application and then navigates out of it. -LEAVING_TOOL_TIP = _("leaving tooltip.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_ABSTRACT = C_("role", "leaving abstract.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_ACKNOWLEDGMENTS = C_("role", "leaving acknowledgments.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_AFTERWORD = C_("role", "leaving afterword.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_APPENDIX = C_("role", "leaving appendix.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_BIBLIOGRAPHY = C_("role", "leaving bibliography.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_CHAPTER = C_("role", "leaving chapter.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_COLOPHON = C_("role", "leaving colophon.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_CONCLUSION = C_("role", "leaving conclusion.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_CREDIT = C_("role", "leaving credit.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_CREDITS = C_("role", "leaving credits.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_DEDICATION = C_("role", "leaving dedication.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_ENDNOTES = C_("role", "leaving endnotes.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_EPIGRAPH = C_("role", "leaving epigraph.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_EPILOGUE = C_("role", "leaving epilogue.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_ERRATA = C_("role", "leaving errata.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_EXAMPLE = C_("role", "leaving example.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_FOREWORD = C_("role", "leaving foreword.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_GLOSSARY = C_("role", "leaving glossary.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_INDEX = C_("role", "leaving index.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_INTRODUCTION = C_("role", "leaving introduction.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_PAGELIST = C_("role", "leaving page list.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_PART = C_("role", "leaving part.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_PREFACE = C_("role", "leaving preface.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_PROLOGUE = C_("role", "leaving prologue.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_PULLQUOTE = C_("role", "leaving pullquote.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_QNA = C_("role", "leaving QNA.") - -# Translators: This message is presented when a user is navigating within a -# suggestion and then navigates out of it. A "suggestion" is a container with -# a proposed change. This change can include the insertion and/or deletion -# of content, and would typically be seen in a collaborative editor, such as -# in Google Docs. -LEAVING_SUGGESTION = C_("role", "leaving suggestion.") - -# Translators: This message is presented when a user is navigating within -# a document container and then navigates out of it. The word or phrase -# that follows "leaving" should be consistent with the translation provided -# for the corresponding term with context "role" found in object_properties.py -LEAVING_TOC = C_("role", "leaving table of contents.") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the end of the line by pressing Shift+Down. -LINE_SELECTED_DOWN = _("line selected down from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the start of the line by pressing Shift+Up. -LINE_SELECTED_UP = _("line selected up from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user unselects previously -# selected text from the current location to the end of the paragraph by -# pressing Shift+Down. -LINE_UNSELECTED_DOWN = _("line unselected down from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user unselects previously -# selected text from the current location to the start of the paragraph by -# pressing Shift+Up. -LINE_UNSELECTED_UP = _("line unselected up from cursor position") - -# Translators: Cthulhu has a "Learn Mode" that will allow the user to type any key -# on the keyboard and hear what the effects of that key would be. The effects -# might be what Cthulhu would do if it had a handler for the particular key -# combination, or they might just be to echo the name of the key if Cthulhu doesn't -# have a handler. This message is what is presented in speech and braille when -# exiting Learn Mode. -LEARN_MODE_STOP = _("Exiting learn mode.") - -# Translators: This message is presented when help cannot be opened. -HELP_NOT_AVAILABLE = _("Help is not available.") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the start of the line by pressing Ctrl+Shift+Page_Up. -LINE_SELECTED_LEFT = _("line selected from start to previous cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the end of the line by pressing Ctrl+Shift+Page_Down. -LINE_SELECTED_RIGHT = _("line selected to end from previous cursor position") - -# Translators: this indicates that this piece of text is a hypertext link. -LINK = _("link") - -# Translators: this is an indication that a given link points to an object -# that is on the same page. -LINK_SAME_PAGE = _("same page") - -# Translators: this is an indication that a given link points to an object -# that is at the same site (but not on the same page as the link). -LINK_SAME_SITE = _("same site") - -# Translators: this is an indication that a given link points to an object -# that is at a different site than that of the link. -LINK_DIFFERENT_SITE = _("different site") - -# Translators: this refers to a link to a file, where the first item is the -# protocol (ftp, ftps, or file) and the second item the name of the file being -# linked to. -LINK_TO_FILE = _("%(uri)s link to %(file)s") - -# Translators: this message conveys the protocol of a link eg. http, mailto. -LINK_WITH_PROTOCOL = _("%s link") - -# Translators: this message conveys the protocol of a link eg. http, mailto. -# along with the visited state of that link. -LINK_WITH_PROTOCOL_VISITED = _("visited %s link") - -# Translators: The following string instructs the user how to navigate amongst -# the list of commands presented in learn mode, as well as how to exit the list -# when finished. -LIST_NAVIGATION = \ - _("Use Up and Down Arrow to navigate the list. Press Escape to exit.") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# The "politeness" level is an indication of when the user wishes to be notified -# about a change to live region content. Examples include: never ("off"), when -# idle ("polite"), and when there is a change ("assertive"). Cthulhu has several -# features to facilitate accessing live regions. This message is presented to -# inform the user that Cthulhu's live region's "politeness" level has changed to -# "off" for all of the live regions. -LIVE_REGIONS_ALL_OFF = _("All live regions set to off") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# The "politeness" level is an indication of when the user wishes to be notified -# about a change to live region content. Examples include: never ("off"), when -# idle ("polite"), and when there is a change ("assertive"). Cthulhu has several -# features to facilitate accessing live regions. This message is presented to -# inform the user that Cthulhu's live region's "politeness" level for all live -# regions has been restored to their original values. -LIVE_REGIONS_ALL_RESTORED = _("live regions politeness levels restored") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# The "politeness" level is an indication of when the user wishes to be notified -# about a change to live region content. Examples include: never ("off"), when -# idle ("polite"), and when there is a change ("assertive"). Cthulhu has several -# features to facilitate accessing live regions. This message is presented to -# inform the user of the "politeness" level for the current live region. -LIVE_REGIONS_LEVEL = _("politeness level %s") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# The "politeness" level is an indication of when the user wishes to be notified -# about a change to live region content. Examples include: never ("off"), when -# idle ("polite"), and when there is a change ("assertive"). Cthulhu has several -# features to facilitate accessing live regions. This message is presented to -# inform the user that Cthulhu's live region's "politeness" level has changed for -# the current live region. -LIVE_REGIONS_LEVEL_ASSERTIVE = _("setting live region to assertive") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# The "politeness" level is an indication of when the user wishes to be notified -# about a change to live region content. Examples include: never ("off"), when -# idle ("polite"), and when there is a change ("assertive"). Cthulhu has several -# features to facilitate accessing live regions. This message is presented to -# inform the user that Cthulhu's live region's "politeness" level has changed for -# the current live region. -LIVE_REGIONS_LEVEL_OFF = _("setting live region to off") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# The "politeness" level is an indication of when the user wishes to be notified -# about a change to live region content. Examples include: never ("off"), when -# idle ("polite"), and when there is a change ("assertive"). Cthulhu has several -# features to facilitate accessing live regions. This message is presented to -# inform the user that Cthulhu's live region's "politeness" level has changed for -# the current live region. -LIVE_REGIONS_LEVEL_POLITE = _("setting live region to polite") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# The "politeness" level is an indication of when the user wishes to be notified -# about a change to live region content. Examples include: never ("off"), when -# idle ("polite"), and when there is a change ("assertive"). Cthulhu has several -# features to facilitate accessing live regions. This message is presented to -# inform the user that Cthulhu's live region's "politeness" level has changed for -# the current live region. -LIVE_REGIONS_LEVEL_RUDE = _("setting live region to rude") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# Cthulhu has several features to facilitate accessing live regions. This message -# is presented in response to a command that toggles whether or not Cthulhu pays -# attention to changes in live regions. Note that turning off monitoring of live -# events is NOT the same as turning the politeness level to "off". The user can -# opt to have no notifications presented (politeness level of "off") and still -# manually review recent updates to live regions via Cthulhu commands for doing so -# -- as long as the monitoring of live regions is enabled. -LIVE_REGIONS_MONITORING_OFF = _("Live regions monitoring off") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# Cthulhu has several features to facilitate accessing live regions. This message -# is presented in response to a command that toggles whether or not Cthulhu pays -# attention to changes in live regions. Note that turning off monitoring of live -# events is NOT the same as turning the politeness level to "off". The user can -# opt to have no notifications presented (politeness level of "off") and still -# manually review recent updates to live regions via Cthulhu commands for doing so -# -- as long as the monitoring of live regions is enabled. -LIVE_REGIONS_MONITORING_ON = _("Live regions monitoring on") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# Cthulhu has several features to facilitate accessing live regions. This message -# is presented to inform the user that a cached message is not available for the -# the current live region. -LIVE_REGIONS_NO_MESSAGE = _("no live message saved") - -# Translators: A live region is an area of a web page that is periodically -# updated, e.g. stock ticker. http://www.w3.org/TR/wai-aria/terms#def_liveregion -# Cthulhu has several features to facilitate accessing live regions. This message -# is presented to inform the user that Cthulhu's live region features have been -# turned off. -LIVE_REGIONS_OFF = _("Live region support is off") - -# Translators: Cthulhu has a command that allows the user to move the mouse pointer -# to the current object. This is a brief message which will be presented if for -# some reason Cthulhu cannot identify/find the current location. -LOCATION_NOT_FOUND_BRIEF = C_("location", "Not found") - -# Translators: Cthulhu has a command that allows the user to move the mouse pointer -# to the current object. This is a detailed message which will be presented if -# for some reason Cthulhu cannot identify/find the current location. -LOCATION_NOT_FOUND_FULL = _("Could not find current location.") - -# Translators: This string is used to present the state of a locking key, such -# as Caps Lock. If Caps Lock is "off", then letters typed will appear in -# lowercase; if Caps Lock is "on", they will instead appear in uppercase. This -# string is also applied to Num Lock and potentially will be applied to similar -# keys in the future. -LOCKING_KEY_STATE_OFF = C_("locking key state", "off") - -# Translators: This string is used to present the state of a locking key, such -# as Caps Lock. If Caps Lock is "off", then letters typed will appear in -# lowercase; if Caps Lock is "on", they will instead appear in uppercase. This -# string is also applied to Num Lock and potentially will be applied to similar -# keys in the future. -LOCKING_KEY_STATE_ON = C_("locking key state", "on") - -# Translators: This is to inform the user of the presence of the red squiggly -# line which indicates that a given word is not spelled correctly. -MISSPELLED = _("misspelled") - -# Translators: Cthulhu tries to provide more compelling output of the spell check -# dialog in some applications. The first thing it does is let the user know -# what the misspelled word is. -MISSPELLED_WORD = _("Misspelled word: %s") - -# Translators: Cthulhu tries to provide more compelling output of the spell check -# dialog in some applications. The second thing it does is give the phrase -# containing the misspelled word in the document. This is known as the context. -MISSPELLED_WORD_CONTEXT = _("Context is %s") - -# Translators: Cthulhu has a number of commands that override the default -# behavior within an application. For instance, on a web page, "h" moves -# you to the next heading. What should happen when you press an "h" in -# an entry on a web page depends: If you want to resume reading content, -# "h" should move to the next heading; if you want to enter text, "h" -# should not move you to the next heading. Similarly, if you are -# at the bottom of an entry and press Down arrow, should you leave the -# entry? Again, it depends on if you want to resume reading content or -# if you are editing the text in the entry. Because Cthulhu doesn't know -# what you want to do, it has two modes: In browse mode, Cthulhu treats -# key presses as commands to read the content; in focus mode, Cthulhu treats -# key presses as something that should be handled by the focused widget. -# This string is the message presented when Cthulhu switches to browse mode. -MODE_BROWSE = _("Browse mode") - -# Translators: Cthulhu has a number of commands that override the default -# behavior within an application. For instance, on a web page, "h" moves -# you to the next heading. What should happen when you press an "h" in -# an entry on a web page depends: If you want to resume reading content, -# "h" should move to the next heading; if you want to enter text, "h" -# should not move you to the next heading. Similarly, if you are -# at the bottom of an entry and press Down arrow, should you leave the -# entry? Again, it depends on if you want to resume reading content or -# if you are editing the text in the entry. Because Cthulhu doesn't know -# what you want to do, it has two modes: In browse mode, Cthulhu treats -# key presses as commands to read the content; in focus mode, Cthulhu treats -# key presses as something that should be handled by the focused widget. -# This string is the message presented when Cthulhu switches to focus mode. -MODE_FOCUS = _("Focus mode") - -# Translators: Cthulhu has a number of commands that override the default -# behavior within an application. For instance, on a web page, "h" moves -# you to the next heading. What should happen when you press an "h" in -# an entry on a web page depends: If you want to resume reading content, -# "h" should move to the next heading; if you want to enter text, "h" -# should not move you to the next heading. Similarly, if you are -# at the bottom of an entry and press Down arrow, should you leave the -# entry? Again, it depends on if you want to resume reading content or -# if you are editing the text in the entry. Because Cthulhu doesn't know -# what you want to do, it has two modes: In browse mode, Cthulhu treats -# key presses as commands to read the content; in focus mode, Cthulhu treats -# key presses as something that should be handled by the focused widget. -# This string is a tutorial message presented to the user who has just -# navigated to a widget in browse mode to inform them of the keystroke -# they must press to enable focus mode for the purposes of interacting -# with the widget. The substituted string is a human-consumable keybinding -# such as "Alt+Shift+A." -MODE_FOCUS_TUTORIAL = _("To enable focus mode press %s.") - -# Translators: (Please see the previous, detailed translator notes about -# Focus mode and Browse mode.) In order to minimize the amount of work Cthulhu -# users need to do to switch between focus mode and browse mode, Cthulhu attempts -# to automatically switch to the mode which is appropriate to the current -# web element. Sometimes, however, this automatic mode switching is not what -# the user wants. A good example being web apps which have their own keyboard -# navigation and use interaction model. As a result, Cthulhu has a command which -# enables setting a "sticky" focus mode which disables all automatic toggling. -# This string is the message presented when Cthulhu switches to sticky focus mode. -MODE_FOCUS_IS_STICKY = _("Focus mode is sticky.") - -# Translators: (Please see the previous, detailed translator notes about -# Focus mode and Browse mode.) In order to minimize the amount of work Cthulhu -# users need to do to switch between focus mode and browse mode, Cthulhu attempts -# to automatically switch to the mode which is appropriate to the current -# web element. Sometimes, however, this automatic mode switching is not what -# the user wants. A good example being web apps which have their own keyboard -# navigation and use interaction model. As a result, Cthulhu has a command which -# enables setting a "sticky" browse mode which disables all automatic toggling. -# This string is the message presented when Cthulhu switches to sticky browse mode. -MODE_BROWSE_IS_STICKY = _("Browse mode is sticky.") - -# Translators: When presenting the content of a line on a web page, Cthulhu by -# default presents the full line, including any links or form fields on that -# line, in order to reflect the on-screen layout as seen by sighted users. -# Not all users like this presentation, however, and prefer to have objects -# treated as if they were on individual lines, such as is done by Windows -# screen readers, so that unrelated objects (e.g. links in a navbar) are not -# all jumbled together. As a result, this is now configurable. If layout mode -# is enabled, Cthulhu will present the full line as it appears on the screen; if -# it is disabled, Cthulhu will treat each object as if it were on a separate line, -# both for presentation and navigation. This string is presented when the user -# switches to layout mode via an Cthulhu command. -MODE_LAYOUT = _("Layout mode.") - -# Translators: When presenting the content of a line on a web page, Cthulhu by -# default presents the full line, including any links or form fields on that -# line, in order to reflect the on-screen layout as seen by sighted users. -# Not all users like this presentation, however, and prefer to have objects -# treated as if they were on individual lines, such as is done by Windows -# screen readers, so that unrelated objects (e.g. links in a navbar) are not -# all jumbled together. As a result, this is now configurable. If layout mode -# is enabled, Cthulhu will present the full line as it appears on the screen; if -# it is disabled, Cthulhu will treat each object as if it were on a separate line, -# both for presentation and navigation. This string is presented when the user -# toggles layout mode off via an Cthulhu command and switches to the aforementioned -# object-based presentation. -MODE_OBJECT = _("Object mode.") - -# Translators: This message is presented to the user when the command to move -# the mouse pointer to a particular object is believed to have succeeded. -MOUSE_MOVED_SUCCESS = _("Pointer moved to object.") - -# Translators: Hovering the mouse over certain objects on a web page causes a -# new object to appear such as a pop-up menu. Cthulhu has a command will move the -# user to the object which just appeared as a result of the user hovering the -# mouse. If this command fails, Cthulhu will present this message. -MOUSE_OVER_NOT_FOUND = _("Mouse over object not found.") - -# Translators: Cthulhu has a feature to speak the item under the pointer. This feature, -# known as mouse review, can be enabled and disabled via command. The following is -# the message which Cthulhu will present when mouse review is toggled off via command. -MOUSE_REVIEW_DISABLED = _("Mouse review disabled.") - -# Translators: Cthulhu has a feature to speak the item under the pointer. This feature, -# known as mouse review, can be enabled and disabled via command. The following is -# the message which Cthulhu will present when mouse review is toggled on via command. -MOUSE_REVIEW_ENABLED = _("Mouse review enabled.") - -# Translators: Cthulhu has a command that presents a list of structural navigation -# objects in a dialog box so that users can navigate more quickly than they -# could with native keyboard navigation. This is a message that will be -# presented to the user when an error (such as the operation timing out) kept us -# from getting these objects. -NAVIGATION_DIALOG_ERROR = _("Error: Could not create list of objects.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. This message is spoken when the current node in the hierarchy -# has no children. -NAVIGATOR_NO_CHILDREN = _("No children.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. This message is spoken when the current node in the hierarchy -# has no next sibling. -NAVIGATOR_NO_NEXT = _("No next.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. This message is spoken when the current node in the hierarchy -# has no parent. -NAVIGATOR_NO_PARENT = _("No parent.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. This message is spoken when the current node in the hierarchy -# has no previous sibling. -NAVIGATOR_NO_PREVIOUS = _("No previous.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. This hierarchy can be simplified to aid with navigation. This -# message is spoken when the simplified view is enabled. -NAVIGATOR_SIMPLIFIED_ENABLED = _("Simplified navigation enabled.") - -# Translators: the object navigator allows users to explore UI objects presented -# as a hierarchy. This hierarchy can be simplified to aid with navigation. This -# message is spoken when the simplified view is disabled. -NAVIGATOR_SIMPLIFIED_DISABLED = _("Simplified navigation disabled.") - -# Translators: This message describes a list item in a document. Nesting level -# is how "deep" the item is (e.g., a level of 2 represents a list item inside a -# list that's inside another list). -NESTING_LEVEL = _("Nesting level %d") - -# Translators: Cthulhu has a command that moves the mouse pointer to the current -# location on a web page. If moving the mouse pointer caused an item to appear -# such as a pop-up menu, we want to present that fact. -NEW_ITEM_ADDED = _("New item has been added") - -# Translators: Cthulhu has a command which presents a menu with accessible actions -# that can be performed on the current object. This is the message that Cthulhu -# presents when the object has no actions. The string substitution will be the -# name of the object if it has a name (e.g. "OK" or "Close") or it's accessible, -# localized rolename if it does not. -NO_ACTIONS_FOUND_ON = _("No actions found on: %s") - -# Translators: This is intended to be a short phrase to present the fact that no -# no accessible component has keyboard focus. -NO_FOCUS = _("No focus") - -# Translators: This message presents the fact that no accessible application has -# has keyboard focus. -NO_FOCUSED_APPLICATION = _("No application has focus.") - -# Translators: This is for navigating document content by moving from blockquote -# to blockquote. This is a detailed message which will be presented to the user -# if no more blockquotes can be found. -NO_MORE_BLOCKQUOTES = _("No more blockquotes.") - -# Translators: This is for navigating document content by moving from button -# to button. This is a detailed message which will be presented to the user -# if no more buttons can be found. -NO_MORE_BUTTONS = _("No more buttons.") - -# Translators: This is for navigating document content by moving from check -# box to check box. This is a detailed message which will be presented to the -# user if no more check boxes can be found. -NO_MORE_CHECK_BOXES = _("No more check boxes.") - -# Translators: This is for navigating document content by moving from 'large -# object' to 'large object'. A 'large object' is a logical chunk of text, -# such as a paragraph, a list, a table, etc. This is a detailed message which -# will be presented to the user if no more check boxes can be found. -NO_MORE_CHUNKS = _("No more large objects.") - -# Translators: This is for navigating document content by moving amongst web -# elements which have an "onClick" action. This is a detailed message which -# will be presented to the user if no more clickable elements can be found. -NO_MORE_CLICKABLES = _("No more clickables.") - -# Translators: This is for navigating document content by moving from combo -# box to combo box. This is a detailed message which will be presented to the -# user if no more combo boxes can be found. -NO_MORE_COMBO_BOXES = _("No more combo boxes.") - -# Translators: This is for navigating document content by moving from entry -# to entry. This is a detailed message which will be presented to the user -# if no more entries can be found. -NO_MORE_ENTRIES = _("No more entries.") - -# Translators: This is for navigating document content by moving from form -# field to form field. This is a detailed message which will be presented to -# the user if no more form fields can be found. -NO_MORE_FORM_FIELDS = _("No more form fields.") - -# Translators: This is for navigating document content by moving from heading -# to heading. This is a detailed message which will be presented to the user -# if no more headings can be found. -NO_MORE_HEADINGS = _("No more headings.") - -# Translators: This is for navigating document content by moving from heading -# to heading at a particular level (i.e. only

or only

, etc.). This -# is a detailed message which will be presented to the user if no more headings -# at the desired level can be found. -NO_MORE_HEADINGS_AT_LEVEL = _("No more headings at level %d.") - -# Translators: This is for navigating document content by moving from iframe -# to iframe. This is a detailed message which will be presented to the user -# if no more iframes can be found. -NO_MORE_IFRAMES = _("No more internal frames.") - -# Translators: This is for navigating document content by moving from image -# to image. This is a detailed message which will be presented to the user -# if no more images can be found. -NO_MORE_IMAGES = _("No more images.") - -# Translators: this is for navigating to the previous ARIA role landmark. -# ARIA role landmarks are the W3C defined HTML tag attribute 'role' used to -# identify important part of webpage like banners, main context, search etc. -# This is an indication that one was not found. -NO_LANDMARK_FOUND = _("No landmark found.") - -# Translators: This is for navigating document content by moving from link to -# link (regardless of visited state). This is a detailed message which will be -# presented to the user if no more links can be found. -NO_MORE_LINKS = _("No more links.") - -# Translators: This is for navigating document content by moving from bulleted/ -# numbered list to bulleted/numbered list. This is a detailed message which will -# be presented to the user if no more lists can be found. -NO_MORE_LISTS = _("No more lists.") - -# Translators: This is for navigating document content by moving from bulleted/ -# numbered list item to bulleted/numbered list item. This is a detailed message -# which will be presented to the user if no more list items can be found. -NO_MORE_LIST_ITEMS = _("No more list items.") - -# Translators: This is for navigating document content by moving from live -# region to live region. A live region is an area of a web page that is -# periodically updated, e.g. stock ticker. This is a detailed message which -# will be presented to the user if no more live regions can be found. For -# more info, see http://www.w3.org/TR/wai-aria/terms#def_liveregion -NO_MORE_LIVE_REGIONS = _("No more live regions.") - -# Translators: This is for navigating document content by moving from paragraph -# to paragraph. This is a detailed message which will be presented to the user -# if no more paragraphs can be found. -NO_MORE_PARAGRAPHS = _("No more paragraphs.") - -# Translators: This is for navigating document content by moving from radio -# button to radio button. This is a detailed message which will be presented to -# the user if no more radio buttons can be found. -NO_MORE_RADIO_BUTTONS = _("No more radio buttons.") - -# Translators: This is for navigating document content by moving from separator -# to separator (e.g.
tags). This is a detailed message which will be -# presented to the user if no more separators can be found. -NO_MORE_SEPARATORS = _("No more separators.") - -# Translators: This is for navigating document content by moving from table to -# to table. This is a detailed message which will be presented to the user if -# no more tables can be found. -NO_MORE_TABLES = _("No more tables.") - -# Translators: This is for navigating document content by moving from unvisited -# link to unvisited link. This is a detailed message which will be presented to -# the user if no more unvisited links can be found. -NO_MORE_UNVISITED_LINKS = _("No more unvisited links.") - -# Translators: This is for navigating document content by moving from visited -# link to visited link. This is a detailed message which will be presented to -# the user if no more visited links can be found. -NO_MORE_VISITED_LINKS = _("No more visited links.") - -# Translators: Cthulhu has a dedicated command to speak the currently-selected -# text. This message is what Cthulhu will present if the user performs this -# command when no text is selected. -NO_SELECTED_TEXT = _("No selected text.") - -# Translators: Cthulhu has a dedicated command to speak detailed information -# about the currently-focused link. This message is what Cthulhu will present -# if the user performs this command when not on a link. -NOT_ON_A_LINK = _("Not on a link.") - -# Translators: This message alerts the user to the fact that what will be -# presented next came from a notification. -NOTIFICATION = _("Notification") - -# Translators: This is a brief message presented to the user when the bottom of -# the list of notifications is reached. -NOTIFICATION_LIST_BOTTOM = C_("notification", "Bottom") - -# Translators: This is a brief message presented to the user when the top of the -# list of notifications is reached. -NOTIFICATION_LIST_TOP = C_("notification", "Top") - -# Translators: This message is presented when a live notification can no longer -# be controlled because it has already been closed or replaced. -NOTIFICATION_UNAVAILABLE = _("Notification is no longer available") - -# Translators: This message is presented when the selected live notification -# does not expose any actions. -NOTIFICATION_NO_ACTIONS = _("No notification actions available") - -# Translators: This message is presented after dismissing a live notification. -NOTIFICATION_DISMISSED = _("Notification dismissed") - -# Translators: This message is presented after invoking an action on a live -# notification. -NOTIFICATION_ACTION_INVOKED = _("Notification action invoked") - -# Translators: This message is presented to the user when the notifications list -# is empty. -NOTIFICATION_NO_MESSAGES = _("No notification messages") - -# Translators: Cthulhu has a setting through which users can control how a number is -# spoken. The options are digits ("1 2 3") and words ("one hundred and twenty -# three"). There is an associated Cthulhu command for quickly toggling between the -# two options. This string to be translated is the brief message spoken when the -# user has enabled speaking numbers as digits. -NUMBER_STYLE_DIGITS_BRIEF = C_("number style", "digits") - -# Translators: Cthulhu has a setting through which users can control how a number is -# spoken. The options are digits ("1 2 3") and words ("one hundred and twenty -# three"). There is an associated Cthulhu command for quickly toggling between the -# two options. This string to be translated is the verbose message spoken when -# the user has enabled speaking numbers as digits. -NUMBER_STYLE_DIGITS_FULL = _("Speak numbers as digits.") - -# Translators: Cthulhu has a setting through which users can control how a number is -# spoken. The options are digits ("1 2 3") and words ("one hundred and twenty -# three"). There is an associated Cthulhu command for quickly toggling between the -# two options. This string to be translated is the brief message spoken when the -# user has enabled speaking numbers as words. -NUMBER_STYLE_WORDS_BRIEF = C_("number style", "words") - -# Translators: Cthulhu has a setting through which users can control how a number is -# spoken. The options are digits ("1 2 3") and words ("one hundred and twenty -# three"). There is an associated Cthulhu command for quickly toggling between the -# two options. This string to be translated is the verbose message spoken when -# the user has enabled speaking numbers as words. -NUMBER_STYLE_WORDS_FULL = _("Speak numbers as words.") - -# Translators: This brief message is presented to indicate the state of widgets -# (checkboxes, push buttons, toggle buttons) on a toolbar which are associated -# with text formatting (bold, italics, underlining, justification, etc.). -OFF = _("off") - -# Translators: This brief message is presented to indicate the state of widgets -# (checkboxes, push buttons, toggle buttons) on a toolbar which are associated -# with text formatting (bold, italics, underlining, justification, etc.). -ON = _("on") - -# Translators: This message is presented to the user when a web page or similar -# item has started loading. -PAGE_LOADING_START = _("Loading. Please wait.") - -# Translators: This message is presented to the user when a web page or similar -# item has finished loading. -PAGE_LOADING_END = _("Finished loading.") - -# Translators: This message is presented to the user when a web page or similar -# item has finished loading. The string substitution is for the name of the -# object which has just finished loading (most likely the page's title). -PAGE_LOADING_END_NAMED = _("Finished loading %s.") - -# Translators: When the user loads a new web page, they can optionally have Cthulhu -# automatically summarize details about the page, such as the number of elements -# (landmarks, forms, links, tables, etc.). The following string precedes the -# presentation of the summary. The string substitution is a list of items, such -# as "10 headings, 1 form, 52 links". -PAGE_SUMMARY_PREFIX = _("Page has %s.") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the end of the page by pressing Shift+Page_Down. -PAGE_SELECTED_DOWN = _("page selected from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the start of the page by pressing Shift+Page_Up. -PAGE_SELECTED_UP = _("page selected to cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user unselects a previously -# selected page by pressing Shift+Page_Down. -PAGE_UNSELECTED_DOWN = _("page unselected from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user unselects a previously -# selected page by pressing Shift+Page_Up. -PAGE_UNSELECTED_UP = _("page unselected to cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the end of the paragraph by pressing Ctrl+Shift+Down. -PARAGRAPH_SELECTED_DOWN = _("paragraph selected down from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user selects from the -# current location to the start of the paragraph by pressing Ctrl+Shift+UP. -PARAGRAPH_SELECTED_UP = _("paragraph selected up from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user unselects previously -# selected text from the current location to the end of the paragraph by -# pressing Ctrl+Shift+Down. -PARAGRAPH_UNSELECTED_DOWN = _("paragraph unselected down from cursor position") - -# Translators: when the user selects (highlights) or unselects text in a -# document, Cthulhu will speak information about what they have selected or -# unselected. This message is presented when the user unselects previously -# selected text from the current location to the start of the paragraph by -# pressing Ctrl+Shift+UP. -PARAGRAPH_UNSELECTED_UP = _("paragraph unselected up from cursor position") - -# Translators: This message appears in a warning dialog when the user performs -# the command to get into Cthulhu's preferences dialog when the preferences dialog -# is already open. -PREFERENCES_WARNING_DIALOG = \ - _('You already have an instance of an Cthulhu preferences dialog ' \ - 'open.\nPlease close it before opening a new one.') - -# Translators: This message is an indication of the position of the focused -# slide and the total number of slides in the presentation. -PRESENTATION_SLIDE_POSITION = _("slide %(position)d of %(count)d") - -# Translators: This is a detailed message which will be presented as the user -# cycles amongst his/her saved profiles. A "profile" is a collection of settings -# which apply to a given task, such as a "Spanish" profile which would use -# Spanish text-to-speech and Spanish braille and selected when reading Spanish -# content. The string representing the profile name is created by the user. -PROFILE_CHANGED = _("Profile set to %s.") - -# Translators: This is an error message presented when the user attempts to -# cycle among his/her saved profiles, but no profiles can be found. A profile -# is a collection of settings which apply to a given task, such as a "Spanish" -# profile which would use Spanish text-to-speech and Spanish braille and -# selected when reading Spanish content. -PROFILE_NOT_FOUND = _("No profiles found.") - -# Translators: this is an index value so that we can present value changes -# regarding a specific progress bar in environments where there are multiple -# progress bars (e.g. in the Firefox downloads dialog). -PROGRESS_BAR_NUMBER = _("Progress bar %d.") - -# Translators: This brief message will be presented as the user cycles -# through the different levels of spoken punctuation. The options are: -# All punctuation marks will be spoken, None will be spoken, Most will be -# spoken, or Some will be spoken. -PUNCTUATION_ALL_BRIEF = C_("spoken punctuation", "All") - -# Translators: This detailed message will be presented as the user cycles -# through the different levels of spoken punctuation. The options are: -# All punctuation marks will be spoken, None will be spoken, Most will be -# spoken, or Some will be spoken. -PUNCTUATION_ALL_FULL = _("Punctuation level set to all.") - -# Translators: This brief message will be presented as the user cycles -# through the different levels of spoken punctuation. The options are: -# All punctuation marks will be spoken, None will be spoken, Most will be -# spoken, or Some will be spoken. -PUNCTUATION_MOST_BRIEF = C_("spoken punctuation", "Most") - -# Translators: This detailed message will be presented as the user cycles -# through the different levels of spoken punctuation. The options are: -# All punctuation marks will be spoken, None will be spoken, Most will be -# spoken, or Some will be spoken. -PUNCTUATION_MOST_FULL = _("Punctuation level set to most.") - -# Translators: This brief message will be presented as the user cycles -# through the different levels of spoken punctuation. The options are: -# All punctuation marks will be spoken, None will be spoken, Most will be -# spoken, or Some will be spoken. -PUNCTUATION_NONE_BRIEF = C_("spoken punctuation", "None") - -# Translators: This detailed message will be presented as the user cycles -# through the different levels of spoken punctuation. The options are: -# All punctuation marks will be spoken, None will be spoken, Most will be -# spoken, or Some will be spoken. -PUNCTUATION_NONE_FULL = _("Punctuation level set to none.") - -# Translators: This brief message will be presented as the user cycles -# through the different levels of spoken punctuation. The options are: -# All punctuation marks will be spoken, None will be spoken, Most will be -# spoken, or Some will be spoken. -PUNCTUATION_SOME_BRIEF = C_("spoken punctuation", "Some") - -# Translators: This detailed message will be presented as the user cycles -# through the different levels of spoken punctuation. The options are: -# All punctuation marks will be spoken, None will be spoken, Most will be -# spoken, or Some will be spoken. -PUNCTUATION_SOME_FULL = _("Punctuation level set to some.") - -# Translators: This message is presented to indicate that a search has begun -# or is still taking place. -SEARCHING = _("Searching.") - -# Translators: This message is presented to indicate a search executed by the -# user has been completed. -SEARCH_COMPLETE = _("Search complete.") - -# Translators: This message is presented to the user when Cthulhu's preferences -# have been reloaded. -SETTINGS_RELOADED = _("Cthulhu settings reloaded.") - -# Translators: Cthulhu has a dedicated command to speak the currently-selected -# text. This message is spoken by Cthulhu before speaking the text which is -# selected. The string substitution is for the selected text. -SELECTED_TEXT_IS = _("Selected text is: %s") - -# Translators: Cthulhu normal speaks the text which was just deleted from a -# document via command. Depending on the circumstances, that might be a -# large string. Therefore, if the text which has just been deleted from a -# document matches the previously-selected contents, Cthulhu will indicate that -# fact instead of presenting the full string which was just deleted. -SELECTION_DELETED = _("Selection deleted.") - -# Translators: Cthulhu normal speaks the text which was just inserted into a -# document via command. Depending on the circumstances, that might be a -# large string. Therefore, if the text which has just been inserted into a -# document is also already selected, it is likely that the insertion is -# due to having been restored (e.g. the user selected text, deleted it, -# and then pressed Ctrl+Z to undo that deletion). In this instance, Cthulhu -# will indicate the restoration rather than presenting the full string -# which was just inserted. -SELECTION_RESTORED = _("Selection restored.") - -# Translators: This message is presented to the user when text had been -# selected in a document and no longer is, e.g. as the result of navigating -# without holding down the shift key. -SELECTION_REMOVED = _("Text unselected.") - -# Translators: Cthulhu has a command which presents the size and position of the -# current object in pixels. This string refers to the brief/non-verbose output -# presented in response to the command. The string substitutions are all for -# quantities (in pixels). -SIZE_AND_POSITION_BRIEF = _("Size: %d, %d. Location: %d, %d.") - -# Translators: Cthulhu has a command which presents the size and position of the -# current object in pixels. This string refers to the full/verbose output -# presented in response to the command. The string substitutions are all for -# quantities (in pixels). -SIZE_AND_POSITION_FULL = _("Width: %d. Height: %d. %d from left. %d from top.") - -# Translators: This message is presented to the user when speech synthesis -# has been temporarily turned off. -SPEECH_DISABLED = _("Speech disabled.") - -# Translators: This message is presented to the user when speech synthesis -# has been turned back on. -SPEECH_ENABLED = _("Speech enabled.") - -# Translators: This string announces speech rate change. -SPEECH_FASTER = _("faster.") - -# Translators: This string announces speech rate change. -SPEECH_SLOWER = _("slower.") - -# Translators: This string announces speech pitch change. -SPEECH_HIGHER = _("higher.") - -# Translators: This string announces speech pitch change. -SPEECH_LOWER = _("lower.") - -# Translators: This string announces speech volume change. -SPEECH_LOUDER = _("louder.") - -# Translators: This string announces speech volume change. -SPEECH_SOFTER = _("softer.") - -# Translators: This string announces the current speech rate value. -SPEECH_RATE_VALUE = _("Rate %d") - -# Translators: This string announces the current speech pitch value. -SPEECH_PITCH_VALUE = _("Pitch %s") - -# Translators: This string announces the current speech volume value. -SPEECH_VOLUME_VALUE = _("Volume %s") - -# Translators: This string announces the current speech-dispatcher module. -SPEECH_MODULE_VALUE = _("Speech-dispatcher module %s") - -# Translators: This string announces the current speech-dispatcher voice. -SPEECH_VOICE_VALUE = _("Speech-dispatcher voice %s") - -# Translators: This string announces the current voice for non-speech-dispatcher engines. -SPEECH_VOICE_VALUE_GENERIC = _("Voice %s") - -# Translators: This string is presented when speech-dispatcher modules are unavailable. -SPEECH_MODULES_UNAVAILABLE = _("No speech-dispatcher modules available") - -# Translators: This string is presented when speech-dispatcher voices are unavailable. -SPEECH_VOICES_UNAVAILABLE = _("No speech-dispatcher voices available") - -# Translators: This string is presented when voices are unavailable for non-speech-dispatcher engines. -SPEECH_VOICES_UNAVAILABLE_GENERIC = _("No voices available") - -# Translators: This string confirms speech settings have been saved. -SPEECH_SETTINGS_SAVED = _("Speech settings saved") - -# Translators: This string is presented when speech settings cannot be saved. -SPEECH_SETTINGS_SAVE_FAILED = _("Speech settings could not be saved") - -# Translators: Cthulhu's verbosity levels control how much (or how little) -# Cthulhu will speak when presenting objects as the user navigates within -# applications and reads content. The two levels are "brief" and "verbose". -# The following string is a message spoken to the user upon toggling -# this setting via command. -SPEECH_VERBOSITY_BRIEF = C_("Speech", "Verbosity level: brief") - -# Translators: Cthulhu's verbosity levels control how much (or how little) -# Cthulhu will speak when presenting objects as the user navigates within -# applications and reads content. The two levels are "brief" and "verbose". -# The following string is a message spoken to the user upon toggling -# this setting via command. -SPEECH_VERBOSITY_VERBOSE = C_("Speech", "Verbosity level: verbose") - -# Translators: We replace the ellipses (both manual and UTF-8) with a spoken -# string. The extra space you see at the beginning is because we need the -# speech synthesis engine to speak the new string well. For example, "Open..." -# turns into "Open dot dot dot". -SPOKEN_ELLIPSIS = _(" dot dot dot") - -# Translators: This message is presented to the user when Cthulhu is launched. -START_CTHULHU = _("Cthulhu welcomes you.") - -# Translators: This message is presented to the user when Cthulhu is quit. -STOP_CTHULHU = _("Cthulhu lurks beneath the waves.") - -# Sleep Mode -# Translators: This message is presented to the user when Cthulhu enters or leaves sleep mode. -SLEEP_MODE_ENABLED_FOR = _("Sleep mode enabled for %s") -SLEEP_MODE_DISABLED_FOR = _("Sleep mode disabled for %s") - -# Translators: This message is presented to the user when game mode is enabled. -GAME_MODE_ENABLED = _("Game mode enabled") - -# Translators: This message is presented to the user when game mode is disabled. -GAME_MODE_DISABLED = _("Game mode disabled") - -# Translators: This message means speech synthesis is not installed or working. -SPEECH_UNAVAILABLE = _("Speech is unavailable.") - -# Translators: Cthulhu has a command to present the contents of the status bar. -# This is a brief message which will be presented if Cthulhu cannot find the -# status bar (e.g. because there isn't one). -STATUS_BAR_NOT_FOUND_BRIEF = C_("status bar", "Not found") - -# Translators: Cthulhu has a command to present the contents of the status bar. -# This is a detailed message which will be presented if Cthulhu cannot find the -# status bar (e.g. because there isn't one). -STATUS_BAR_NOT_FOUND_FULL = _("Status bar not found") - -# Translators: the Cthulhu "Find" dialog allows a user to search for text in a -# window and then move focus to that text. For example, they may want to find -# the "OK" button. This message lets them know a string they were searching -# for was not found. -STRING_NOT_FOUND = _("string not found") - -# Translators: The structural navigation keys are designed to move the caret -# around document content by object type. H moves you to the next heading, -# Shift H to the previous heading, T to the next table, and so on. Some users -# prefer to turn this off to use Firefox's search when typing feature. This -# message is presented when the user toggles the structural navigation feature -# of Cthulhu. It should be a brief informative message. -STRUCTURAL_NAVIGATION_KEYS_OFF = _("Structural navigation keys off.") - -# Translators: The structural navigation keys are designed to move the caret -# around document content by object type. H moves you to the next heading, -# Shift H to the previous heading, T to the next table, and so on. Some users -# prefer to turn this off to use Firefox's search when typing feature. This -# message is presented when the user toggles the structural navigation feature -# of Cthulhu. It should be a brief informative message. -STRUCTURAL_NAVIGATION_KEYS_ON = _("Structural navigation keys on.") - -# Translators: Cthulhu has a command that allows the user to move to the next -# structural navigation object. In Cthulhu, "structural navigation" refers to -# quickly moving through a document by jumping amongst objects of a given -# type, such as from link to link, or from heading to heading, or from form -# field to form field. This is a brief message which will be presented to the -# user if the desired structural navigation object could not be found. -STRUCTURAL_NAVIGATION_NOT_FOUND = C_("structural navigation", "Not found") - -# Translators: This message describes the (row, col) position of a table cell. -TABLE_CELL_COORDINATES = _("Row %(row)d, column %(column)d.") - -# Translators: This message is presented to indicate the user is in the last -# cell of a table in a document. -TABLE_END = _("End of table") - -# Translators: When users are navigating a table, they sometimes want the entire -# row of a table read; other times they want just the current cell presented. -# This string is a message presented to the user when this setting is toggled. -TABLE_MODE_CELL = _("Speak cell") - -# Translators: When users are navigating a table, they sometimes want the entire -# row of a table read; other times they want just the current cell presented. -# This string is a message presented to the user when this setting is toggled. -TABLE_MODE_ROW = _("Speak row") - -# Translators: a uniform table is one in which each table cell occupies one row -# and one column (i.e. a perfect grid). In contrast, a non-uniform table is one -# in which at least one table cell occupies more than one row and/or column. -TABLE_NON_UNIFORM = _("Non-uniform") - -# Translators: This is for navigating document content by moving from table cell -# to table cell. If the user gives a table navigation command but is not in a -# table, presents this message. -TABLE_NOT_IN_A = _("Not in a table.") - -# Translators: This is a message presented to users when the columns in a table -# have been reordered. -TABLE_REORDERED_COLUMNS = _("Columns reordered") - -# Translators: This is a message presented to users when the rows in a table -# have been reordered. -TABLE_REORDERED_ROWS = _("Rows reordered") - -# Translators: this is in reference to a column in a table. The substitution -# is the index (e.g. the first column is "column 1"). -TABLE_COLUMN = _("column %d") - -# Translators: this is in reference to a column in a table. If the user is in -# the first column of a table with five columns, the position is "column 1 of 5" -TABLE_COLUMN_DETAILED = _("column %(index)d of %(total)d") - -# Translators: This is for navigating document content by moving from table cell -# to table cell. This is the message presented when the user attempts to move to -# the cell below the current cell and is already in the last row. -TABLE_COLUMN_BOTTOM = _("Bottom of column.") - -# Translators: This is for navigating document content by moving from table cell -# to table cell. This is the message presented when the user attempts to move to -# the cell above the current cell and is already in the first row. -TABLE_COLUMN_TOP = _("Top of column.") - -# Translators: this message is spoken to announce that a table column just became -# selected (e.g as a result of navigation via Shift + Arrows). The string substitution -# is the column label (e.g. "B"). -TABLE_COLUMN_SELECTED = _("Column %s selected") - -# Translators: this message is spoken to announce that multiple table columns just -# became selected (e.g as a result of navigation via Shift + Arrows). The first -# string substitution is the label of the first column in the range. The second string -# substitution is the label in the last column in the range. An example message for -# Calc would be "Columns B through F selected". -TABLE_COLUMN_RANGE_SELECTED = _("Columns %s through %s selected") - -# Translators: this message is spoken to announce that multiple table columns just -# became unselected (e.g as a result of navigation via Shift + Arrows). The first -# string substitution is the label of the first column in the range. The second string -# substitution is the label in the last column in the range. An example message for -# Calc would be "Columns B through F unselected". -TABLE_COLUMN_RANGE_UNSELECTED = _("Columns %s through %s unselected") - -# Translators: this message is spoken to announce that a table column just became -# unselected (e.g as a result of navigation via Shift + Arrows). The string substitution -# is the column label (e.g. "B"). -TABLE_COLUMN_UNSELECTED = _("Column %s unselected") - -# Translators: this is in reference to a row in a table. The substitution is -# the index (e.g. the first row is "row 1"). -TABLE_ROW = _("row %d") - -# Translators: this is in reference to a row in a table. If the user is in the -# the first row of a table with five rows, the position is "row 1 of 5" -TABLE_ROW_DETAILED = _("row %(index)d of %(total)d") - -# Translators: This is for navigating document content by moving from table cell -# to table cell. This is the message presented when the user attempts to move to -# the left of the current cell and is already in the first column. -TABLE_ROW_BEGINNING = _("Beginning of row.") - -# Translators: This is for navigating document content by moving from table cell -# to table cell. This is the message presented when the user attempts to move to -# the right of the current cell and is already in the last column. -TABLE_ROW_END = _("End of row.") - -# Translators: This message is presented to the user to confirm that he/she just -# deleted a table row. -TABLE_ROW_DELETED = _("Row deleted.") - -# Translators: This message is presented to the user to confirm that he/she just -# deleted the last row of a table. -TABLE_ROW_DELETED_FROM_END = _("Last row deleted.") - -# Translators: This message is presented to the user to confirm that he/she just -# inserted a table row. -TABLE_ROW_INSERTED = _("Row inserted.") - -# Translators: This message is presented to the user to confirm that he/she just -# inserted a table row at the end of the table. This typically happens when the -# user presses Tab from within the last cell of the table. -TABLE_ROW_INSERTED_AT_END = _("Row inserted at the end of the table.") - -# Translators: this message is spoken to announce that a table row just became selected -# (e.g as a result of navigation via Shift + Arrows). The string substitution is the row -# label (e.g. "2"). -TABLE_ROW_SELECTED = _("Row %s selected") - -# Translators: this message is spoken to announce that multiple table rows just -# became selected (e.g as a result of navigation via Shift + Arrows). The first -# string substitution is the label of the first row in the range. The second string -# substitution is the label of the last row in the range. An example message for -# Calc would be "Rows 2 through 10 selected". -TABLE_ROW_RANGE_SELECTED = _("Rows %s through %s selected") - -# Translators: this message is spoken to announce that multiple table rows just -# became unselected (e.g as a result of navigation via Shift + Arrows). The first -# string substitution is the label of the first row in the range. The second string -# substitution is the label of the last row in the range. An example message for -# Calc would be "Rows 2 through 10 unselected". -TABLE_ROW_RANGE_UNSELECTED = _("Rows %s through %s unselected") - -# Translators: this message is spoken to announce that a table row just became -# unselected (e.g as a result of navigation via Shift + Arrows). The string -# substitution is the row label (e.g. "2"). -TABLE_ROW_UNSELECTED = _("Row %s unselected") - -# Translators: when the user selects (highlights) text in a document, Cthulhu lets -# them know. -TEXT_SELECTED = C_("text", "selected") - -# Translators: when the user unselects (un-highlights) text in a document, Cthulhu -# lets them know. -TEXT_UNSELECTED = C_("text", "unselected") - -TIME_FORMAT_LOCALE = "%X" -TIME_FORMAT_24_HMS = "%H:%M:%S" -TIME_FORMAT_24_HM = "%H:%M" -TIME_FORMAT_12_HM = "%I:%M %p" -TIME_FORMAT_12_HMS = "%I:%M:%S %p" - -# Translators: Cthulhu has a feature to speak the time when the user presses a -# shortcut key. This is one of the alternative formats that the user may wish -# it to be presented with. -TIME_FORMAT_24_HMS_WITH_WORDS = _("%H hours, %M minutes and %S seconds") - -# Translators: Cthulhu has a feature to speak the time when the user presses a -# shortcut key. This is one of the alternative formats that the user may wish -# it to be presented with. -TIME_FORMAT_24_HM_WITH_WORDS = _("%H hours and %M minutes") - -# Translators: this is information about a unicode character reported to the -# user. The value is the unicode number value of this character in hex. -UNICODE = _("Unicode %s") - -# Translators: This string is presented when an application's undo command is -# used in a document resulting in a change to that document's contents. -UNDO = C_("command", "undo") - -# Translators: This string is presented when an application's redo command is -# used in a document resulting in a change to that document's contents. -REDO = C_("command", "redo") - -# Translators: This message presents the Cthulhu version number. -VERSION = _("Cthulhu version %s.") % version - -# Translators: This is presented when the user has navigated to a line with only -# whitespace characters (space, tab, etc.) on it. -WHITE_SPACE = _("white space") - -# Translators: when the user is attempting to locate a particular object and the -# top of a page or list is reached without that object being found, we "wrap" to -# the bottom and continue looking upwards. We need to inform the user when this -# is taking place. -WRAPPING_TO_BOTTOM = _("Wrapping to bottom.") - -# Translators: when the user is attempting to locate a particular object and the -# bottom of a page or list is reached without that object being found, we "wrap" -# to the top and continue looking downwards. We need to inform the user when -# this is taking place. -WRAPPING_TO_TOP = _("Wrapping to top.") - -# Translators, normally layered panes and tables have items in them. Thus it is -# noteworthy when this is not the case. This message is presented to the user to -# indicate the current layered pane or table contains zero items. -ZERO_ITEMS = _("0 items") - -def cellSpan(rowspan, colspan): - spanString = "" - if (colspan > 1) and (rowspan > 1): - # Translators: The cell here refers to a cell within a table within a - # document. We need to announce when the cell occupies or "spans" more - # than a single row and/or column. - spanString = ngettext("Cell spans %d row", - "Cell spans %d rows", - rowspan) % rowspan - - # Translators: this represents the number of columns in a table. - spanString += ngettext(" %d column", - " %d columns", - colspan) % colspan - elif (colspan > 1): - # Translators: The cell here refers to a cell within a table within a - # document. We need to announce when the cell occupies or "spans" more - # than a single row and/or column. - spanString = ngettext("Cell spans %d column", - "Cell spans %d columns", - colspan) % colspan - elif (rowspan > 1): - # Translators: The cell here refers to a cell within a table within a - # document. We need to announce when the cell occupies or "spans" more - # than a single row and/or column. - spanString = ngettext("Cell spans %d row", - "Cell spans %d rows", - rowspan) % rowspan - - return spanString - -def charactersTooLong(count): - # Translators: People can enter a string of text that is too wide to be - # fully displayed in a spreadsheet cell. This message will be spoken if - # such a cell is encountered. - return ngettext("%d character too long", - "%d characters too long", - count) % count - -def dialogCountBraille(count): - # Translators: This message informs the user how many unfocused alert and - # dialog windows a newly (re)focused application has. It is added at the - # end of a braille message containing the app which just claimed focus. - return ngettext("(%d dialog)", "(%d dialogs)", count) % count - -def dialogCountSpeech(count): - # Translators: This message informs the user how many unfocused alert and - # dialog windows a newly (re)focused application has. It is added at the - # end of a spoken message containing the app which just claimed focus. - return ngettext("%d unfocused dialog", "%d unfocused dialogs", count) % count - -def fileSizeBytes(size): - # Translators: This is the size of a file in bytes - return ngettext("%d byte", "%d bytes", size) % size - -def filesFound(count): - # Translators: This message informs the user who many files were found as - # a result of a search. - return ngettext("%d file found", "%d files found", count) % count - -def formCount(count, onlyIfFound=True): - if not count and onlyIfFound: - return "" - - # Translators: This message presents the number of forms in a document. - return ngettext("%d form", "%d forms", count) % count - -def headingCount(count, onlyIfFound=True): - if not count and onlyIfFound: - return "" - - # Translators: This message presents the number of headings in a document. - return ngettext("%d heading", "%d headings", count) % count - -def itemCount(count): - # Translators: This message presents the number of items in a layered pane - # or table. - return ngettext("%d item", "%d items", count) % count - -def landmarkCount(count, onlyIfFound=True): - if not count and onlyIfFound: - return "" - - # Translators: This message presents the number of landmarks in a document. - # ARIA role landmarks are the W3C defined HTML tag attribute 'role' used to - # identify important part of webpage like banners, main context, search etc. - return ngettext("%d landmark", "%d landmarks", count) % count - -def itemsFound(count): - # Translators: Cthulhu has several commands that search for, and present a list - # of, objects based on one or more criteria. This is a message that will be - # presented to the user to indicate how many matching items were found. - return ngettext("%d item found", "%d items found", count) % count - -def leavingNBlockquotes(count): - # Translators: This message is presented when a user is navigating within a - # series of nested blockquotes, such as can be seen in deep email threads, - # and then navigates out of several levels at once. - return ngettext("Leaving %d blockquote.", "Leaving %d blockquotes.", count) % count - -def leavingNLists(count): - # Translators: This message is presented when a user is navigating within a - # series of nested lists and then navigates out of several levels at once. - return ngettext("Leaving %d list.", "Leaving %d lists.", count) % count - -def listItemCount(count): - if count == -1: - # Translators: This message describes a list in web content for which the - # size is unknown. Examples include unlimited scrolling news/article feeds - # on social media sites, and message lists on services such as gmail where - # you're currently viewing messages 1-100 out of some huge, unspecified - # number. Normally Cthulhu announces "list with n items" when the count is - # known. This is the corresponding message for the unknown-count scenario. - return _("List of unknown size") - - # Translators: This message describes a bulleted or numbered list. - return ngettext("List with %d item", "List with %d items", count) % count - -def feedArticleCount(count): - if count == -1: - # Translators: This message describes a news/article feed whose size is - # unknown, such as can be found on social media sites that have unlimited - # scrolling, adding and/or removing items as the user moves up or down. - # Normally Cthulhu announces "feed with n articles" when the count is known. - # This is the corresponding message for the unknown-count scenario. - return _("Feed of unknown size") - - # Translators: This message describes the number of articles (news items, - # social media posts, etc.) in a feed. - return ngettext("Feed with %d article", "Feed with %d articles", count) % count - -def descriptionListTermCount(count): - # Translators: This message describes a description list. - # See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl - # Note that the "term" here corresponds to the "dt" element - return ngettext("Description list with %d term", - "Description list with %d terms", count) % count - -def valueCountForTerm(count): - # Translators: This message describes a description list. - # A given term ("dt" element) can have 0 or more values ("dd" elements). - # This message presents the number values a particular term has. - # See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl - return ngettext("%d value", "%d values", count) % count - -def mathTableSize(nRows, nColumns): - # Translators: this represents the number of rows in a mathematical table. - # See http://www.w3.org/TR/MathML3/chapter3.html#presm.mtable - rowString = ngettext("math table with %d row", - "math table with %d rows", - nRows) % nRows - # Translators: this represents the number of columns in a mathematical table. - # See http://www.w3.org/TR/MathML3/chapter3.html#presm.mtable - colString = ngettext("%d column", - "%d columns", - nColumns) % nColumns - - return rowString + " " + colString - -def mathNestedTableSize(nRows, nColumns): - # Translators: this represents the number of rows in a mathematical table - # which is nested inside another mathematical table. - # See http://www.w3.org/TR/MathML3/chapter3.html#presm.mtable - rowString = ngettext("nested math table with %d row", - "nested math table with %d rows", - nRows) % nRows - # Translators: this represents the number of rows in a mathematic table - # which is nested inside another mathematical table. - # See http://www.w3.org/TR/MathML3/chapter3.html#presm.mtable - colString = ngettext("%d column", - "%d columns", - nColumns) % nColumns - - return rowString + " " + colString - -def messagesCount(count): - # Translators: This message is presented to inform the user of the number of - # messages in a list. - return ngettext("%d message.\n", "%d messages.\n", count) % count - -def percentage(value): - # Translators: This message is presented to inform the user of the value of - # a slider, progress bar, or other such component. - return ngettext("%d percent.", "%d percent.", value) % value - -def percentRead(value): - # Translators: This message announces the percentage of the document that - # has been read. The value is calculated by knowing the index of the current - # position divided by the total number of objects on the page. - return ngettext ("%d percent of document read", - "%d percent of document read", - value) % value - -def pixelCount(nPixels): - # Translators: this represents a text attribute expressed in pixels, such as - # a margin, indentation, font size, etc. - return ngettext("%d pixel", "%d pixels", nPixels) % nPixels - -def repeatedCharCount(repeatChar, count): - # Translators: Cthulhu will tell you how many characters are repeated on a line - # of text. For example: "22 space characters". The %d is the number and the - # %s is the spoken word for the character. - return ngettext("%(count)d %(repeatChar)s character", - "%(count)d %(repeatChar)s characters", - count) % {"count" : count, "repeatChar": repeatChar} - -def selectedItemsCount(selected, total): - # Translators: This message is presented to indicate the number of selected - # objects (e.g. icons) and the total number of those objects. - return ngettext("%(index)d of %(total)d item selected", - "%(index)d of %(total)d items selected", - total) % {"index" : selected, "total" : total} - -def shortcutsFoundCthulhu(count): - # Translators: This message is presented when the user is in a list of - # shortcuts associated with Cthulhu commands which are not specific to the - # current application. It appears as the title of the dialog containing - # the list. - return ngettext("%d Screen reader default shortcut found.", - "%d Screen reader default shortcuts found.", - count) % count - -def shortcutsFoundApp(count, appName): - # Translators: This message is presented when the user is in a list of - # shortcuts associated with Cthulhu commands specific to the current - # application. It appears as the title of the dialog containing the list. - return ngettext("%(count)d Screen reader shortcut for %(application)s found.", - "%(count)d Screen reader shortcuts for %(application)s found.", - count) % {"count" : count, "application" : appName} - -def spacesCount(count): - # Translators: This message is presented to inform the user of the number of - # space characters in a string. - return ngettext("%d space", "%d spaces", count) % count - -def tabsCount(count): - # Translators: This message is presented to inform the user of the number of - # tab characters in a string. - return ngettext("%d tab", "%d tabs", count) % count - -def indentationLevelCount(count): - # Translators: This message is presented to inform the user of the - # indentation level for a line of text. - return ngettext("indentation level %d", "indentation level %d", count) % count - -def indentationColumnCount(count): - # Translators: This message is presented to inform the user of the number - # of indentation columns for a line of text. - return ngettext("indentation %d column", "indentation %d columns", count) % count - -def tableCount(count, onlyIfFound=True): - if not count and onlyIfFound: - return "" - - # Translators: This message presents the number of tables in a document. - return ngettext("%d table", "%d tables", count) % count - -def tableSize(nRows, nColumns): - if nRows == -1: - if nColumns == -1: - # Translators: This message describes a table for which both the - # number of rows and the number of columns are unknown. Normally - # Cthulhu announces the table dimensions (e.g. "table with 100 rows - # 15 columns"). When both counts are unknown, it presents this. - return _("table of unknown size") - - # Translators: This message describes a table for which the number of - # rows is unknown, but the number of columns is known. This might occur - # in a vertically infinitely scrollable table or grid on the web. - return ngettext("table with %d column, row count unknown", - "table with %d columns, row count unknown", - nColumns) % nColumns - - if nColumns == -1: - # Translators: This message describes a table for which the number of - # columns is unknown, but the number of rows is known. This might occur - # in a horizontally infinitely scrollable table or grid on the web. - return ngettext("table with %d row, column count unknown", - "table with %d rows, column count unknown", - nRows) % nRows - - # Translators: this represents the number of rows in a table. - rowString = ngettext("table with %d row", - "table with %d rows", - nRows) % nRows - - # Translators: this represents the number of columns in a table. - colString = ngettext("%d column", - "%d columns", - nColumns) % nColumns - - return rowString + " " + colString - -def secondsAgo(count): - # Translators: This message informs the user how long ago something took - # place in terms of seconds. - return ngettext("%d second ago", "%d seconds ago", count) % count - -def minutesAgo(count): - # Translators: This message informs the user how long ago something took - # place in terms of minutes. - return ngettext("%d minute ago", "%d minutes ago", count) % count - -def hoursAgo(count): - # Translators: This message informs the user how long ago something took - # place in terms of hours. - return ngettext("%d hour ago", "%d hours ago", count) % count - -def daysAgo(count): - # Translators: This message informs the user how long ago something took - # place in terms of days. - return ngettext("%d day ago", "%d days ago", count) % count - -def unvisitedLinkCount(count, onlyIfFound=True): - if not count and onlyIfFound: - return "" - - # Translators: This message presents the number of unvisited links in a - # document. - return ngettext("%d unvisited link", "%d unvisited links", count) % count - -def visitedLinkCount(count, onlyIfFound=True): - if not count and onlyIfFound: - return "" - - # Translators: This message presents the number of visited links in a - # document. - return ngettext("%d visited link", "%d visited links", count) % count diff --git a/src/cthulhu/mouse_review.py b/src/cthulhu/mouse_review.py deleted file mode 100644 index 569c8fe..0000000 --- a/src/cthulhu/mouse_review.py +++ /dev/null @@ -1,833 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Mouse review mode.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2008 Eitan Isaacson" \ - "Copyright (c) 2016 Igalia, S.L." -__license__ = "LGPL" - -from collections import deque - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi, GLib - -import math -import time - -from gi.repository import Gdk -from .wnck_support import load_wnck - -Wnck = load_wnck() - -from . import cmdnames -from . import debug -from . import keybindings -from . import input_event -from . import input_event_manager -from . import messages -from . import cthulhu -from . import cthulhu_state -from . import script_manager -from . import settings_manager -from .ax_component import AXComponent -from .ax_object import AXObject -from .ax_text import AXText -from .ax_utilities import AXUtilities - -# Removed global cthulhu.cthulhuApp.scriptManager and cthulhu.cthulhuApp.settingsManager - -class _StringContext: - """The textual information associated with an _ItemContext.""" - - def __init__(self, obj, script=None, string="", start=0, end=0): - """Initialize the _StringContext. - - Arguments: - - string: The human-consumable string - - obj: The accessible object associated with this string - - start: The start offset with respect to entire text, if one exists - - end: The end offset with respect to the entire text, if one exists - - script: The script associated with the accessible object - """ - - self._obj = obj - self._script = script - self._string = string - self._start = start - self._end = end - self._boundingBox = 0, 0, 0, 0 - if AXObject.supports_text(obj): - rect = AXText.get_range_rect(obj, start, end) - self._boundingBox = rect.x, rect.y, rect.width, rect.height - - def __eq__(self, other): - return other is not None \ - and self._obj == other._obj \ - and self._string == other._string \ - and self._start == other._start \ - and self._end == other._end - - def isSubstringOf(self, other): - """Returns True if this is a substring of other.""" - - if other is None: - return False - - if not (self._obj and other._obj): - return False - - thisBox = self.getBoundingBox() - if thisBox == (0, 0, 0, 0): - return False - - otherBox = other.getBoundingBox() - if otherBox == (0, 0, 0, 0): - return False - - # We get various and sundry results for the bounding box if the implementor - # included newline characters as part of the word or line at offset. Try to - # detect this and adjust the bounding boxes before getting the intersection. - if thisBox[3] != otherBox[3] and self._obj == other._obj: - thisNewLineCount = self._string.count("\n") - if thisNewLineCount and thisBox[3] / thisNewLineCount == otherBox[3]: - thisBox = *thisBox[0:3], otherBox[3] - - if self._script.utilities.intersection(thisBox, otherBox) != thisBox: - return False - - if not (self._string and self._string.strip() in other._string): - return False - - tokens = ["MOUSE REVIEW: '", self._string, "' is substring of '", other._string, "'"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - def getBoundingBox(self): - """Returns the bounding box associated with this context's range.""" - - return self._boundingBox - - def getString(self): - """Returns the string associated with this context.""" - - return self._string - - def present(self): - """Presents this context to the user.""" - - if not self._script: - msg = "MOUSE REVIEW: Not presenting due to lack of script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if not self._string: - msg = "MOUSE REVIEW: Not presenting due to lack of string" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - voice = self._script.speechGenerator.voice(obj=self._obj, string=self._string) - string = self._script.utilities.adjustForRepeats(self._string) - - cthulhu.emitRegionChanged(self._obj, self._start, self._end, cthulhu.MOUSE_REVIEW) - self._script.speakMessage(string, voice=voice, interrupt=False) - self._script.displayBrailleMessage(self._string, -1) - return True - - -class _ItemContext: - """Holds all the information of the item at a specified point.""" - - def __init__(self, x=0, y=0, obj=None, boundary=None, frame=None, script=None): - """Initialize the _ItemContext. - - Arguments: - - x: The X coordinate - - y: The Y coordinate - - obj: The accessible object of interest at that coordinate - - boundary: The accessible-text boundary type - - frame: The containing accessible object (often a top-level window) - - script: The script associated with the accessible object - """ - - self._x = x - self._y = y - self._obj = obj - self._boundary = boundary - self._frame = frame - self._script = script - self._string = self._getStringContext() - self._time = time.time() - self._boundingBox = 0, 0, 0, 0 - if AXObject.supports_component(obj): - rect = AXComponent.get_rect(obj) - self._boundingBox = rect.x, rect.y, rect.width, rect.height - - def __eq__(self, other): - return other is not None \ - and self._frame == other._frame \ - and self._obj == other._obj \ - and self._string == other._string - - def _treatAsDuplicate(self, prior): - if self._obj != prior._obj or self._frame != prior._frame: - msg = "MOUSE REVIEW: Not a duplicate: different objects" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if self.getString() and prior.getString() and not self._isSubstringOf(prior): - msg = "MOUSE REVIEW: Not a duplicate: not a substring of" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if self._x == prior._x and self._y == prior._y: - msg = "MOUSE REVIEW: Treating as duplicate: mouse didn't move" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - interval = self._time - prior._time - if interval > 0.5: - msg = f"MOUSE REVIEW: Not a duplicate: was {interval:.2f}s ago" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - msg = "MOUSE REVIEW: Treating as duplicate" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - def _treatAsSingleObject(self): - if not AXObject.supports_text(self._obj): - return True - - if not AXText.get_character_count(self._obj): - return True - - return False - - def _getStringContext(self): - """Returns the _StringContext associated with the specified point.""" - - if not (self._script and self._obj): - return _StringContext(self._obj) - - if self._treatAsSingleObject(): - return _StringContext(self._obj, self._script) - - string, start, end = self._script.utilities.textAtPoint( - self._obj, - self._x, - self._y, - coordType=Atspi.CoordType.WINDOW, - boundary=self._boundary, - ) - if string: - string = self._script.utilities.expandEOCs(self._obj, start, end) - - return _StringContext(self._obj, self._script, string, start, end) - - def _getContainer(self): - roles = [Atspi.Role.DIALOG, - Atspi.Role.FRAME, - Atspi.Role.LAYERED_PANE, - Atspi.Role.MENU, - Atspi.Role.PAGE_TAB, - Atspi.Role.TOOL_BAR, - Atspi.Role.WINDOW] - return AXObject.find_ancestor(self._obj, lambda x: AXObject.get_role(x) in roles) - - def _isSubstringOf(self, other): - """Returns True if this is a substring of other.""" - - return self._string.isSubstringOf(other._string) - - def get_object(self): - """Returns the accessible object associated with this context.""" - - return self._obj - - def getBoundingBox(self): - """Returns the bounding box associated with this context.""" - - x, y, width, height = self._string.getBoundingBox() - if not (width or height): - return self._boundingBox - - return x, y, width, height - - def getString(self): - """Returns the string associated with this context.""" - - return self._string.getString() - - def getTime(self): - """Returns the time associated with this context.""" - - return self._time - - def _isInlineChild(self, prior): - if not self._obj or not prior._obj: - return False - - if AXObject.get_parent(prior._obj) != self._obj: - return False - - if self._treatAsSingleObject(): - return False - - return AXUtilities.is_link(prior._obj) - - def present(self, prior): - """Presents this context to the user.""" - - if self == prior or self._treatAsDuplicate(prior): - msg = "MOUSE REVIEW: Not presenting due to no change" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - interrupt = self._obj and self._obj != prior._obj \ - or math.sqrt((self._x - prior._x)**2 + (self._y - prior._y)**2) > 25 - - if interrupt: - self._script.presentationInterrupt() - - if self._frame and self._frame != prior._frame: - self._script.presentObject(self._frame, - alreadyFocused=True, - inMouseReview=True, - interrupt=True) - - if self._script.utilities.containsOnlyEOCs(self._obj): - msg = "MOUSE REVIEW: Not presenting object which contains only EOCs" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if self._obj and self._obj != prior._obj and not self._isInlineChild(prior): - priorObj = prior._obj or self._getContainer() - cthulhu.emitRegionChanged(self._obj, mode=cthulhu.MOUSE_REVIEW) - self._script.presentObject(self._obj, priorObj=priorObj, inMouseReview=True) - if self._string.getString() == AXObject.get_name(self._obj): - return True - if not self._script.utilities.isEditableTextArea(self._obj): - return True - if AXUtilities.is_table_cell(self._obj) \ - and self._string.getString() == self._script.utilities.displayedText(self._obj): - return True - - if self._string != prior._string and self._string.present(): - return True - - return True - - -class MouseReviewer: - """Main class for the mouse-review feature.""" - - def __init__(self, app): - self.app = app - self._active = self.app.getSettingsManager().getSetting("enableMouseReview") - self._currentMouseOver = _ItemContext() - self._pointer = None - self._workspace = None - self._windows = [] - self._all_windows = [] - self._handlerIds = {} - self._eventListener = Atspi.EventListener.new(self._listener) - self.inMouseEvent = False - self._eventQueue = deque() - self._mouseReviewCapable = False - self._useAtspi = False - self._handlers = self._setup_handlers() - self._bindings = self._setup_bindings() - - atspiVersion = Atspi.get_version() - capabilityEnum = getattr(Atspi, "DeviceCapability", None) - pointerMonitor = getattr(capabilityEnum, "POINTER_MONITOR", 0) if capabilityEnum else 0 - atspiSupported = pointerMonitor and ( - atspiVersion[0] > 2 - or atspiVersion[1] >= 60 - or (atspiVersion[0] == 2 and atspiVersion[1] == 59 and atspiVersion[2] >= 90) - ) - - try: - if atspiSupported: - manager = input_event_manager.get_manager() - manager.activate_device() - if manager.enable_pointer_monitoring(): - self._useAtspi = True - self._mouseReviewCapable = True - else: - self._mouseReviewCapable = Wnck is not None - else: - self._mouseReviewCapable = Wnck is not None - except Exception: - self._mouseReviewCapable = False - - if not self._mouseReviewCapable: - msg = ( - "MOUSE REVIEW ERROR: Not supported by AT-SPI device" - if atspiSupported - else "MOUSE REVIEW ERROR: Wnck or at-spi2-core >= 2.60 required" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if not self._useAtspi: - display = Gdk.Display.get_default() - try: - seat = Gdk.Display.get_default_seat(display) - self._pointer = seat.get_pointer() - except AttributeError: - msg = "MOUSE REVIEW ERROR: Gtk+ 3.20 is not available" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._mouseReviewCapable = False - return - except Exception: - msg = "MOUSE REVIEW ERROR: Exception getting pointer for default seat." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._mouseReviewCapable = False - return - - if not self._pointer: - msg = "MOUSE REVIEW ERROR: No pointer for default seat." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._mouseReviewCapable = False - return - - if not self._active: - return - - self.activate() - - def get_bindings(self): - """Returns the mouse-review keybindings.""" - - return self._bindings - - def get_handlers(self): - """Returns the mouse-review handlers.""" - - return self._handlers - - def _setup_handlers(self): - """Sets up and returns the mouse-review input event handlers.""" - - handlers = {} - - handlers["toggleMouseReviewHandler"] = \ - input_event.InputEventHandler( - self.toggle, - cmdnames.MOUSE_REVIEW_TOGGLE) - - return handlers - - def _setup_bindings(self): - """Sets up and returns the mouse-review key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("toggleMouseReviewHandler"))) - - return bindings - - def activate(self): - """Activates mouse review.""" - - if not self._mouseReviewCapable: - msg = ( - "MOUSE REVIEW ERROR: Not supported by AT-SPI device" - if self._useAtspi - else "MOUSE REVIEW ERROR: Wnck or at-spi2-core >= 2.60 required" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._active = False - return - - # Set up the initial object as the one with the focus to avoid - # presenting irrelevant info the first time. - obj = cthulhu_state.locusOfFocus - script = None - frame = None - if obj: - script = self.app.getScriptManager().get_script(AXObject.get_application(obj), obj) - if script: - frame = script.utilities.topLevelObject(obj) - self._currentMouseOver = _ItemContext(obj=obj, frame=frame, script=script) - - if self._useAtspi: - input_event_manager.get_manager().start_pointer_watcher(self._on_pointer_moved) - self._active = True - return - - self._eventListener.register("mouse:abs") - screen = Wnck.Screen.get_default() - if screen: - # On first startup windows and workspace are likely to be None, - # but the signals we connect to will get emitted when proper values - # become available; but in case we got disabled and re-enabled we - # have to get the initial values manually. - stacked = screen.get_windows_stacked() - if stacked: - stacked.reverse() - self._all_windows = stacked - self._workspace = screen.get_active_workspace() - if self._workspace: - self._update_workspace_windows() - - i = screen.connect("window-stacking-changed", self._on_stacking_changed) - self._handlerIds[i] = screen - i = screen.connect("active-workspace-changed", self._on_workspace_changed) - self._handlerIds[i] = screen - - self._active = True - - def deactivate(self): - """Deactivates mouse review.""" - - if self._useAtspi: - input_event_manager.get_manager().stop_pointer_watcher() - else: - try: - self._eventListener.deregister("mouse:abs") - except GLib.GError as error: - msg = f"MOUSE REVIEW: Exception deregistering 'mouse:abs' listener: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - for key, value in self._handlerIds.items(): - value.disconnect(key) - self._handlerIds = {} - self._workspace = None - self._windows = [] - self._all_windows = [] - - self._eventQueue.clear() - self._active = False - - def getCurrentItem(self): - """Returns the accessible object being reviewed.""" - - if not self._mouseReviewCapable: - return None - - if not self._active: - return None - - obj = self._currentMouseOver.get_object() - - if time.time() - self._currentMouseOver.getTime() > 0.1: - tokens = ["MOUSE REVIEW: Treating", obj, "as stale"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - return obj - - def toggle(self, script=None, event=None): - """Toggle mouse reviewing on or off.""" - - if not self._mouseReviewCapable: - return - - self._active = not self._active - self.app.getSettingsManager().setSetting("enableMouseReview", self._active) - - if not self._active: - self.deactivate() - msg = messages.MOUSE_REVIEW_DISABLED - else: - self.activate() - msg = messages.MOUSE_REVIEW_ENABLED - - if cthulhu_state.activeScript: - cthulhu_state.activeScript.presentMessage(msg) - - def _update_workspace_windows(self): - """Refresh cached windows for the current workspace.""" - - if not self._workspace: - self._windows = [] - return - - windows = [] - for w in self._all_windows: - try: - if w and w.is_on_workspace(self._workspace): - windows.append(w) - except TypeError: - # Seen when Wnck hands us None/invalid workspace references mid-switch. - continue - - self._windows = windows - - def _on_stacking_changed(self, screen): - """Callback for Wnck's window-stacking-changed signal.""" - - stacked = screen.get_windows_stacked() - stacked.reverse() - self._all_windows = stacked - if self._workspace: - self._update_workspace_windows() - - def _on_workspace_changed(self, screen, prev_ws=None): - """Callback for Wnck's active-workspace-changed signal.""" - - self._workspace = screen.get_active_workspace() - self._update_workspace_windows() - - def _contains_point(self, obj, x, y, coordType=None): - if coordType is None: - coordType = Atspi.CoordType.SCREEN - - if not AXObject.supports_component(obj): - return False - - try: - return Atspi.Component.contains(obj, x, y, coordType) - except Exception: - return False - - def _has_bounds(self, obj, bounds, coordType=None): - """Returns True if the bounding box of obj is bounds.""" - - if coordType is None: - coordType = Atspi.CoordType.SCREEN - - if not AXObject.supports_component(obj): - return False - - try: - extents = Atspi.Component.get_extents(obj, coordType) - except Exception: - return False - - return [extents.x, extents.y, extents.width, extents.height] == list(bounds) - - def _accessible_window_at_point_deprecated(self, pX, pY): - """Returns the accessible window and local coordinates for screen coordinates.""" - - window = None - for w in self._windows: - if w.is_minimized(): - continue - - x, y, width, height = w.get_client_window_geometry() - if x <= pX <= x + width and y <= pY <= y + height: - window = w - break - - if not window: - return None, -1, -1 - - windowApp = window.get_application() - app = AXUtilities.get_application_with_pid(windowApp.get_pid()) if windowApp else None - if not app: - return None, -1, -1 - - windowX = pX - x - windowY = pY - y - - candidates = [o for o in AXObject.iter_children( - app, lambda obj: self._contains_point(obj, windowX, windowY, Atspi.CoordType.WINDOW))] - if len(candidates) == 1: - return candidates[0], windowX, windowY - - name = window.get_name() - matches = [o for o in candidates if AXObject.get_name(o) == name] - if len(matches) == 1: - return matches[0], windowX, windowY - - matches = [o for o in candidates if AXUtilities.is_active(o)] - if len(matches) == 1: - return matches[0], windowX, windowY - - return None, -1, -1 - - def _accessible_window_at_point(self, app, pX, pY): - """Returns the accessible window and local coordinates for pointer-moved events.""" - - def getTuple(obj, x, y): - rect = AXComponent.get_rect(obj) - return obj, x - rect.x, y - rect.y - - candidates = [o for o in AXObject.iter_children( - app, lambda obj: self._contains_point(obj, pX, pY, Atspi.CoordType.WINDOW))] - if len(candidates) == 1: - return getTuple(candidates[0], pX, pY) - - matches = [o for o in candidates if AXUtilities.is_active(o)] - if len(matches) == 1: - return getTuple(matches[0], pX, pY) - - return None, -1, -1 - - def _mouse_moved_common(self, window, pX, pY): - tokens = [f"MOUSE REVIEW: Window at ({pX}, {pY}) is", window] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if not window: - return - - script = self.app.getScriptManager().get_script(AXObject.get_application(window)) - if not script: - return - - if AXObject.is_dead(cthulhu_state.locusOfFocus): - menu = None - elif AXUtilities.is_menu(cthulhu_state.locusOfFocus): - menu = cthulhu_state.locusOfFocus - else: - menu = AXObject.find_ancestor(cthulhu_state.locusOfFocus, AXUtilities.is_menu) - - obj = None - if menu: - obj = script.utilities.descendantAtPoint(menu, pX, pY, Atspi.CoordType.WINDOW) - tokens = ["MOUSE REVIEW: Object in", menu, f"at ({pX}, {pY}) is", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if obj is None: - obj = script.utilities.descendantAtPoint(window, pX, pY, Atspi.CoordType.WINDOW) - tokens = ["MOUSE REVIEW: Object in", window, f"at ({pX}, {pY}) is", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - script = self.app.getScriptManager().get_script(AXObject.get_application(window), obj) - if menu and obj and not AXObject.find_ancestor(obj, AXUtilities.is_menu): - if script.utilities.intersectingRegion(obj, menu) != (0, 0, 0, 0): - tokens = ["MOUSE REVIEW:", obj, "believed to be under", menu] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - objDocument = script.utilities.getTopLevelDocumentForObject(obj) - if objDocument and script.utilities.inDocumentContent(): - document = script.utilities.activeDocument() - if document != objDocument: - tokens = ["MOUSE REVIEW:", obj, "is not in active document", document] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - if len(self._eventQueue): - msg = "MOUSE REVIEW: Mouse moved again." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - boundary = None - x, y, width, height = self._currentMouseOver.getBoundingBox() - if y <= pY <= y + height and self._currentMouseOver.getString(): - boundary = Atspi.TextBoundaryType.WORD_START - elif obj == self._currentMouseOver.get_object(): - boundary = Atspi.TextBoundaryType.LINE_START - elif AXUtilities.is_selectable(obj): - boundary = Atspi.TextBoundaryType.LINE_START - elif script.utilities.isMultiParagraphObject(obj): - boundary = Atspi.TextBoundaryType.LINE_START - - new = _ItemContext(pX, pY, obj, boundary, window, script) - if new.present(self._currentMouseOver): - self._currentMouseOver = new - - def _on_mouse_moved_deprecated(self, event): - """Callback for mouse:abs events.""" - - pX, pY = event.detail1, event.detail2 - window, windowX, windowY = self._accessible_window_at_point_deprecated(pX, pY) - self._mouse_moved_common(window, windowX, windowY) - - def _on_mouse_moved(self, obj, pX, pY): - """Callback for pointer-moved events.""" - - if AXObject.get_role(obj) == Atspi.Role.APPLICATION: - window, windowX, windowY = self._accessible_window_at_point(obj, pX, pY) - self._mouse_moved_common(window, windowX, windowY) - return - - self._mouse_moved_common(obj, pX, pY) - - def _process_event_deprecated(self): - if not self._eventQueue: - return - - event = self._eventQueue.popleft() - if len(self._eventQueue): - return - - startTime = time.time() - tokens = ["\nvvvvv PROCESS OBJECT EVENT", event.type, "vvvvv"] - debug.printTokens(debug.LEVEL_INFO, tokens, False) - - self.inMouseEvent = True - self._on_mouse_moved_deprecated(event) - self.inMouseEvent = False - - msg = f"TOTAL PROCESSING TIME: {time.time() - startTime:.4f}\n" - msg += f"^^^^^ PROCESS OBJECT EVENT {event.type} ^^^^^\n" - debug.printMessage(debug.LEVEL_INFO, msg, False) - - def _process_pointer_event(self): - if not self._eventQueue: - return - - obj, x, y = self._eventQueue.popleft() - if len(self._eventQueue): - return - - startTime = time.time() - tokens = ["\nvvvvv PROCESS POINTER-MOVED EVENT", "vvvvv"] - debug.printTokens(debug.LEVEL_INFO, tokens, False) - - self.inMouseEvent = True - self._on_mouse_moved(obj, x, y) - self.inMouseEvent = False - - msg = f"TOTAL PROCESSING TIME: {time.time() - startTime:.4f}\n" - msg += "^^^^^ PROCESS POINTER-MOVED EVENT ^^^^^\n" - debug.printMessage(debug.LEVEL_INFO, msg, False) - - def _listener(self, event): - """Generic listener, mainly to output debugging info.""" - - if event.type.startswith("mouse:abs"): - self._eventQueue.append(event) - GLib.timeout_add(50, self._process_event_deprecated) - - def _on_pointer_moved(self, _device, obj, x, y): - """Listener for pointer-moved events from devices.""" - - self._eventQueue.append([obj, x, y]) - GLib.timeout_add(50, self._process_pointer_event) - -_reviewer = None -def getReviewer(): - """Returns the Mouse Reviewer""" - - global _reviewer - if _reviewer is None: - from . import cthulhu - _reviewer = MouseReviewer(cthulhu.cthulhuApp) - return _reviewer diff --git a/src/cthulhu/notification_presenter.py b/src/cthulhu/notification_presenter.py deleted file mode 100644 index 7eaf451..0000000 --- a/src/cthulhu/notification_presenter.py +++ /dev/null @@ -1,767 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Module for notification messages.""" - -from dataclasses import dataclass, field -import time -from typing import Optional, Dict, List, Any, Callable - -import gi - -gi.require_version("Gtk", "3.0") -from gi.repository import GObject -from gi.repository import Gtk -from gi.repository import Gdk - -from . import cmdnames -from . import debug -from . import guilabels -from . import input_event -from . import keybindings -from . import messages - - -@dataclass -class NotificationEntry: - """Represents a notification saved in Cthulhu's history.""" - - message: str - timestamp: float - source: str = "generic" - source_generation: int = 0 - notification_id: Optional[int] = None - live: bool = False - actions: Dict[str, str] = field(default_factory=dict) - app_name: str = "" - summary: str = "" - body: str = "" - urgency: int = -1 - desktop_entry: str = "" - - -class NotificationPresenter: - """Provides access to the notification history.""" - - def __init__(self) -> None: - self._gui: Optional[Any] = None - self._mako_monitor: Optional[Any] = None - self._handlers: Dict[str, Callable] = self._setup_handlers() - self._bindings: keybindings.KeyBindings = self._setup_bindings() - self._max_size: int = 55 - - # The list is arranged with the most recent message being at the end of - # the list. The current index is relative to, and used directly, with the - # python list, i.e. self._notifications[-3] would return the third-to-last - # notification message. - self._notifications: List[NotificationEntry] = [] - self._current_index: int = -1 - - def get_bindings(self) -> keybindings.KeyBindings: - """Returns the notification-presenter keybindings.""" - - return self._bindings - - def get_handlers(self) -> Dict[str, Callable]: - """Returns the notification-presenter handlers.""" - - return self._handlers - - def set_mako_monitor(self, monitor: Any) -> None: - """Associates the mako D-Bus monitor with this presenter.""" - - self._mako_monitor = monitor - - def save_notification( - self, - message: str, - source: str = "generic", - source_generation: int = 0, - notification_id: Optional[int] = None, - live: bool = False, - actions: Optional[Dict[str, str]] = None, - app_name: str = "", - summary: str = "", - body: str = "", - urgency: int = -1, - desktop_entry: str = "", - ) -> NotificationEntry: - """Adds message to the list of notification messages.""" - - tokens = ["NOTIFICATION PRESENTER: Adding '", message, "'."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - to_remove = max(len(self._notifications) - self._max_size + 1, 0) - self._notifications = self._notifications[to_remove:] - entry = NotificationEntry( - message=message, - timestamp=time.time(), - source=source, - source_generation=source_generation, - notification_id=notification_id, - live=live, - actions=dict(actions or {}), - app_name=app_name, - summary=summary, - body=body, - urgency=urgency, - desktop_entry=desktop_entry, - ) - self._notifications.append(entry) - return entry - - def clear_list(self) -> None: - """Clears the notifications list.""" - - msg = "NOTIFICATION PRESENTER: Clearing list." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._notifications = [] - self._current_index = -1 - - def remove_entry(self, entry: Optional[NotificationEntry]) -> bool: - """Removes entry from the notification history.""" - - if entry is None: - return False - - try: - index = self._notifications.index(entry) - except ValueError: - return False - - del self._notifications[index] - if not self._notifications: - self._current_index = -1 - return True - - if self._current_index == -1: - return True - - if index < self._current_index: - self._current_index -= 1 - elif index == self._current_index and self._current_index >= len(self._notifications): - self._current_index = -1 - - return True - - def refresh_live_notifications(self) -> bool: - """Refreshes live mako state without announcing new notifications.""" - - if self._mako_monitor is None: - return False - - return self._mako_monitor.refresh(announce_new=False) - - def sync_live_notifications( - self, - source: str, - live_notifications: Dict[int, Dict[str, Any]], - source_generation: int, - ) -> None: - """Synchronizes current live notification metadata with history.""" - - live_ids = set(live_notifications) - for entry in self._notifications: - if entry.source != source or entry.source_generation != source_generation: - continue - - if entry.notification_id in live_ids: - metadata = live_notifications[entry.notification_id] - entry.live = True - entry.message = metadata.get("message", entry.message) - entry.actions = dict(metadata.get("actions") or {}) - entry.app_name = metadata.get("app_name", entry.app_name) - entry.summary = metadata.get("summary", entry.summary) - entry.body = metadata.get("body", entry.body) - entry.urgency = metadata.get("urgency", entry.urgency) - entry.desktop_entry = metadata.get("desktop_entry", entry.desktop_entry) - elif entry.live: - entry.live = False - - def mark_source_unavailable(self, source: str) -> None: - """Marks all live notifications from source as no longer live.""" - - for entry in self._notifications: - if entry.source == source and entry.live: - entry.live = False - - def can_control_entry(self, entry: Optional[NotificationEntry]) -> bool: - """Returns True if entry can still be controlled through mako.""" - - if entry is None or not entry.live or entry.notification_id is None: - return False - - if self._mako_monitor is None: - return False - - return self._mako_monitor.is_current_entry(entry) - - def get_actions_for_entry(self, entry: Optional[NotificationEntry]) -> Dict[str, str]: - """Returns the live action map for entry, if it is controllable.""" - - if not self.can_control_entry(entry): - return {} - - return dict(entry.actions) - - def dismiss_entry(self, script: Any, entry: Optional[NotificationEntry]) -> bool: - """Dismisses the live notification represented by entry.""" - - if not self.can_control_entry(entry) or self._mako_monitor is None: - return False - - result = self._mako_monitor.dismiss_notification(entry.notification_id) - if result: - entry.live = False - self.remove_entry(entry) - script.presentMessage(messages.NOTIFICATION_DISMISSED) - return result - - def invoke_action_for_entry( - self, - script: Any, - entry: Optional[NotificationEntry], - action_key: str, - ) -> bool: - """Invokes action_key for the live notification represented by entry.""" - - if not self.can_control_entry(entry) or self._mako_monitor is None: - return False - - result = self._mako_monitor.invoke_action(entry.notification_id, action_key) - if result: - script.presentMessage(messages.NOTIFICATION_ACTION_INVOKED) - return result - - def _setup_handlers(self) -> Dict[str, Callable]: - """Sets up and returns the notification-presenter input event handlers.""" - - handlers = {} - - handlers["present_last_notification"] = input_event.InputEventHandler( - self._present_last_notification, - cmdnames.NOTIFICATION_MESSAGES_LAST, - ) - - handlers["present_next_notification"] = input_event.InputEventHandler( - self._present_next_notification, - cmdnames.NOTIFICATION_MESSAGES_NEXT, - ) - - handlers["present_previous_notification"] = input_event.InputEventHandler( - self._present_previous_notification, - cmdnames.NOTIFICATION_MESSAGES_PREVIOUS, - ) - - handlers["show_notification_list"] = input_event.InputEventHandler( - self._show_notification_list, - cmdnames.NOTIFICATION_MESSAGES_LIST, - ) - - return handlers - - def _setup_bindings(self): - """Sets up and returns the notification-presenter key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "n", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("present_last_notification"), - ) - ) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("present_next_notification"), - ) - ) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("present_previous_notification"), - ) - ) - - bindings.add( - keybindings.KeyBinding( - "n", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("show_notification_list"), - ) - ) - - return bindings - - def _timestamp_to_string(self, timestamp): - diff = time.time() - timestamp - if diff < 60: - return messages.secondsAgo(diff) - - if diff < 3600: - minutes = round(diff / 60) - return messages.minutesAgo(minutes) - - if diff < 86400: - hours = round(diff / 3600) - return messages.hoursAgo(hours) - - days = round(diff / 86400) - return messages.daysAgo(days) - - def _entry_to_string(self, entry: NotificationEntry) -> str: - return f"{entry.message} {self._timestamp_to_string(entry.timestamp)}" - - def _present_last_notification(self, script, event=None): - """Presents the last notification.""" - - if not self._notifications: - script.presentMessage(messages.NOTIFICATION_NO_MESSAGES) - return True - - msg = "NOTIFICATION PRESENTER: Presenting last notification." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - entry = self._notifications[-1] - script.presentMessage(self._entry_to_string(entry)) - self._current_index = -1 - return True - - def _present_previous_notification(self, script, event=None): - """Presents the previous notification.""" - - if not self._notifications: - script.presentMessage(messages.NOTIFICATION_NO_MESSAGES) - return True - - msg = ( - f"NOTIFICATION PRESENTER: Presenting previous notification. " - f"Current index: {self._current_index}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if self._current_index == 0: - script.presentMessage(messages.NOTIFICATION_LIST_TOP) - entry = self._notifications[self._current_index] - else: - try: - index = self._current_index - 1 - entry = self._notifications[index] - self._current_index -= 1 - except IndexError: - msg = "NOTIFICATION PRESENTER: Handling IndexError exception." - debug.printMessage(debug.LEVEL_INFO, msg, True) - script.presentMessage(messages.NOTIFICATION_LIST_TOP) - entry = self._notifications[self._current_index] - - script.presentMessage(self._entry_to_string(entry)) - return True - - def _present_next_notification(self, script, event=None): - """Presents the next notification.""" - - if not self._notifications: - script.presentMessage(messages.NOTIFICATION_NO_MESSAGES) - return True - - msg = ( - f"NOTIFICATION PRESENTER: Presenting next notification. " - f"Current index: {self._current_index}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if self._current_index == -1: - script.presentMessage(messages.NOTIFICATION_LIST_BOTTOM) - entry = self._notifications[self._current_index] - else: - try: - index = self._current_index + 1 - entry = self._notifications[index] - self._current_index += 1 - except IndexError: - msg = "NOTIFICATION PRESENTER: Handling IndexError exception." - debug.printMessage(debug.LEVEL_INFO, msg, True) - script.presentMessage(messages.NOTIFICATION_LIST_BOTTOM) - entry = self._notifications[self._current_index] - - script.presentMessage(self._entry_to_string(entry)) - return True - - def _show_notification_list(self, script, event=None): - """Opens a dialog with a list of the notifications.""" - - self.refresh_live_notifications() - if not self._notifications: - script.presentMessage(messages.NOTIFICATION_NO_MESSAGES) - return True - - msg = "NOTIFICATION PRESENTER: Showing notification list." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - entries = list(reversed(self._notifications)) - title = guilabels.notifications_count(len(self._notifications)) - column_headers = [ - guilabels.NOTIFICATIONS_COLUMN_HEADER, - guilabels.NOTIFICATIONS_RECEIVED_TIME, - ] - self._gui = NotificationListGUI(self, script, title, column_headers, entries) - self._gui.show_gui() - return True - - def on_dialog_destroyed(self): - """Handler for the dialog being destroyed.""" - - self._gui = None - - -class NotificationListGUI: - """The dialog containing the notifications list.""" - - RESPONSE_COPY = 1 - RESPONSE_DISMISS = 2 - - def __init__(self, presenter, script, title, column_headers, entries): - self._presenter = presenter - self._script = script - self._model = None - self._tree = None - self._selection = None - self._dismiss_button = None - self._actions_box = None - self._actions_status_label = None - self._gui = self._create_dialog(title, column_headers, entries) - - def _create_dialog(self, title, column_headers, entries): - dialog = Gtk.Dialog(title, None, Gtk.DialogFlags.MODAL) - dialog.set_default_size(600, 400) - dialog.add_button(Gtk.STOCK_COPY, self.RESPONSE_COPY) - self._dismiss_button = dialog.add_button( - guilabels.NOTIFICATIONS_DISMISS_BUTTON, - self.RESPONSE_DISMISS, - ) - dialog.add_button(Gtk.STOCK_CLEAR, Gtk.ResponseType.APPLY) - dialog.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) - dialog.set_default_response(Gtk.ResponseType.CLOSE) - - grid = Gtk.Grid() - grid.set_row_spacing(12) - content_area = dialog.get_content_area() - content_area.add(grid) - - scrolled_window = Gtk.ScrolledWindow() - scrolled_window.set_hexpand(True) - scrolled_window.set_vexpand(True) - grid.add(scrolled_window) - - tree = Gtk.TreeView() - tree.set_hexpand(True) - tree.set_vexpand(True) - tree_accessible = tree.get_accessible() - if tree_accessible: - tree_accessible.set_name(title) - scrolled_window.add(tree) - - cols = (GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_PYOBJECT) - for i, header in enumerate(column_headers): - cell = Gtk.CellRendererText() - column = Gtk.TreeViewColumn(header, cell, text=i) - tree.append_column(column) - if header: - column.set_sort_column_id(i) - - self._model = Gtk.ListStore(*cols) - for entry in entries: - row_iter = self._model.append(None) - self._model.set_value(row_iter, 0, entry.message) - self._model.set_value( - row_iter, - 1, - self._presenter._timestamp_to_string(entry.timestamp), - ) - self._model.set_value(row_iter, 2, entry) - - tree.set_model(self._model) - selection = tree.get_selection() - selection.set_mode(Gtk.SelectionMode.SINGLE) - selection.connect("changed", self._on_selection_changed) - if self._model.iter_n_children(None) > 0: - selection.select_path(0) - self._selection = selection - self._tree = tree - - actions_frame = Gtk.Frame(label=guilabels.NOTIFICATIONS_ACTIONS_TITLE) - actions_frame.set_label_align(0.0, 0.5) - actions_accessible = actions_frame.get_accessible() - if actions_accessible: - actions_accessible.set_name(guilabels.NOTIFICATIONS_ACTIONS_TITLE) - grid.attach_next_to(actions_frame, scrolled_window, Gtk.PositionType.BOTTOM, 1, 1) - - actions_content = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) - actions_content.set_margin_top(6) - actions_content.set_margin_bottom(6) - actions_content.set_margin_start(6) - actions_content.set_margin_end(6) - actions_frame.add(actions_content) - - self._actions_status_label = Gtk.Label(xalign=0) - self._actions_status_label.set_line_wrap(True) - self._actions_status_label.set_no_show_all(True) - actions_content.pack_start(self._actions_status_label, False, False, 0) - - self._actions_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) - actions_content.pack_start(self._actions_box, False, False, 0) - - dialog.connect("response", self.on_response) - dialog.connect("destroy", self._on_destroy) - self._update_action_buttons() - return dialog - - def on_response(self, dialog, response): - """The handler for the 'response' signal.""" - - if response == Gtk.ResponseType.CLOSE: - self._gui.destroy() - return - - if response == self.RESPONSE_COPY: - self._copy_selected_notification() - return - - if response == self.RESPONSE_DISMISS: - self._dismiss_selected_notification() - return - - if response == Gtk.ResponseType.APPLY and self._model is not None: - self._model.clear() - self._presenter.clear_list() - self._script.presentMessage(messages.NOTIFICATION_NO_MESSAGES) - time.sleep(1) - self._gui.destroy() - - def show_gui(self): - """Shows the notifications list dialog.""" - - self._gui.show_all() - time_stamp = Gtk.get_current_event_time() - if not time_stamp or time_stamp > 0xFFFFFFFF: - time_stamp = Gdk.CURRENT_TIME - self._gui.present_with_time(int(time_stamp)) - - def _on_destroy(self, widget): - self._presenter.on_dialog_destroyed() - - def _on_selection_changed(self, selection): - self._presenter.refresh_live_notifications() - self._update_action_buttons() - - def _get_selected_entry(self) -> Optional[NotificationEntry]: - if self._selection is None or self._model is None: - return None - - model, paths = self._selection.get_selected_rows() - if not paths and self._model.iter_n_children(None) > 0: - self._selection.select_path(0) - model, paths = self._selection.get_selected_rows() - - if not paths: - return None - - iter_for_path = model.get_iter(paths[0]) - if iter_for_path is None: - return None - - return model.get_value(iter_for_path, 2) - - def _update_action_buttons(self) -> None: - entry = self._get_selected_entry() - can_control = self._presenter.can_control_entry(entry) - actions = self._presenter.get_actions_for_entry(entry) - - if self._dismiss_button is not None: - self._dismiss_button.set_sensitive(can_control) - - self._clear_inline_action_buttons() - - if not can_control: - self._set_inline_action_status(messages.NOTIFICATION_UNAVAILABLE) - return - - if not actions: - self._set_inline_action_status(messages.NOTIFICATION_NO_ACTIONS) - return - - self._set_inline_action_status("") - for action_key, label_text in actions.items(): - self._add_inline_action_button(entry, action_key, label_text) - - def _clear_inline_action_buttons(self) -> None: - if self._actions_box is None: - return - - for child in self._actions_box.get_children(): - self._actions_box.remove(child) - - def _set_inline_action_status(self, text: str) -> None: - if self._actions_status_label is None: - return - - self._actions_status_label.set_text(text) - self._actions_status_label.set_visible(bool(text)) - - def _add_inline_action_button( - self, - entry: Optional[NotificationEntry], - action_key: str, - label_text: str, - ) -> None: - if self._actions_box is None: - return - - button = Gtk.Button(label=label_text or action_key) - button.connect("clicked", self._on_inline_action_clicked, entry, action_key) - self._actions_box.pack_start(button, False, False, 0) - self._actions_box.show_all() - - def _on_inline_action_clicked( - self, - button: Gtk.Button, - entry: Optional[NotificationEntry], - action_key: str, - ) -> None: - del button - self._presenter.refresh_live_notifications() - if not self._presenter.can_control_entry(entry): - self._script.presentMessage(messages.NOTIFICATION_UNAVAILABLE) - self._update_action_buttons() - return - - if not self._presenter.invoke_action_for_entry(self._script, entry, action_key): - self._script.presentMessage(messages.NOTIFICATION_UNAVAILABLE) - - self._update_action_buttons() - - def _copy_selected_notification(self): - entry = self._get_selected_entry() - if entry is None: - return - - timestamp = self._presenter._timestamp_to_string(entry.timestamp) - if timestamp: - text = f"{entry.message}\t{timestamp}" - else: - text = f"{entry.message}" - - clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) - clipboard.set_text(text, -1) - clipboard.store() - self._script.presentMessage(messages.CLIPBOARD_COPIED_FULL) - - def _dismiss_selected_notification(self) -> None: - self._presenter.refresh_live_notifications() - entry = self._get_selected_entry() - if not self._presenter.can_control_entry(entry): - self._script.presentMessage(messages.NOTIFICATION_UNAVAILABLE) - self._update_action_buttons() - return - - if not self._presenter.dismiss_entry(self._script, entry): - self._script.presentMessage(messages.NOTIFICATION_UNAVAILABLE) - else: - self._remove_selected_row() - - self._update_action_buttons() - - def _remove_selected_row(self) -> None: - if self._selection is None or self._model is None: - return - - model, paths = self._selection.get_selected_rows() - if not paths: - return - - row_iter = model.get_iter(paths[0]) - if row_iter is None: - return - - model.remove(row_iter) - if self._model.iter_n_children(None) == 0: - return - - row_index = self._path_to_index(paths[0]) - if row_index is None: - self._selection.select_path(0) - return - - next_index = min(row_index, self._model.iter_n_children(None) - 1) - self._selection.select_path(next_index) - - def _path_to_index(self, path: Any) -> Optional[int]: - if isinstance(path, int): - return path - - get_indices = getattr(path, "get_indices", None) - if callable(get_indices): - indices = get_indices() - if indices: - return indices[0] - - try: - return path[0] - except (TypeError, IndexError, KeyError): - return None - - -_presenter = None - - -def getPresenter(): - """Returns the Notification Presenter.""" - - global _presenter - if _presenter is None: - _presenter = NotificationPresenter() - - if _presenter._mako_monitor is None: - try: - from . import cthulhu - - app = getattr(cthulhu, "cthulhuApp", None) - if app is not None: - monitor = getattr(app, "makoNotificationMonitor", None) - if monitor is not None: - _presenter.set_mako_monitor(monitor) - except Exception: - pass - - return _presenter diff --git a/src/cthulhu/object_navigator.py b/src/cthulhu/object_navigator.py deleted file mode 100644 index 6459160..0000000 --- a/src/cthulhu/object_navigator.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides ability to navigate objects hierarchically.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 The Cthulhu Team" -__license__ = "LGPL" - -from . import cmdnames -from . import debug -from . import input_event -from . import keybindings -from . import messages -from . import cthulhu -from . import cthulhu_state -from .ax_event_synthesizer import AXEventSynthesizer -from .ax_object import AXObject -from .ax_utilities import AXUtilities - - -class ObjectNavigator: - """Provides ability to navigate objects hierarchically.""" - - def __init__(self): - self._navigator_focus = None - self._last_navigator_focus = None - self._last_locus_of_focus = None - self._simplify = True - self._handlers = self._setup_handlers() - self._bindings = self._setup_bindings() - - def get_bindings(self): - """Returns the object-navigator keybindings.""" - - return self._bindings - - def get_handlers(self): - """Returns the object-navigator handlers.""" - - return self._handlers - - def _setup_bindings(self): - """Sets up and returns the object-navigator key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "Up", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("object_navigator_up"))) - - bindings.add( - keybindings.KeyBinding( - "Down", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("object_navigator_down"))) - - bindings.add( - keybindings.KeyBinding( - "Right", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("object_navigator_next"))) - - bindings.add( - keybindings.KeyBinding( - "Left", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("object_navigator_previous"))) - - bindings.add( - keybindings.KeyBinding( - "Return", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("object_navigator_perform_action"))) - - bindings.add( - keybindings.KeyBinding( - "s", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK, - self._handlers.get("object_navigator_toggle_simplify"))) - - return bindings - - def _setup_handlers(self): - """Sets up and returns the object-navigator input event handlers.""" - - handlers = {} - - handlers["object_navigator_up"] = \ - input_event.InputEventHandler( - self.up, - cmdnames.NAVIGATOR_UP) - - handlers["object_navigator_down"] = \ - input_event.InputEventHandler( - self.down, - cmdnames.NAVIGATOR_DOWN) - - handlers["object_navigator_next"] = \ - input_event.InputEventHandler( - self.next, - cmdnames.NAVIGATOR_NEXT) - - handlers["object_navigator_previous"] = \ - input_event.InputEventHandler( - self.previous, - cmdnames.NAVIGATOR_PREVIOUS) - - handlers["object_navigator_perform_action"] = \ - input_event.InputEventHandler( - self.perform_action, - cmdnames.NAVIGATOR_PERFORM_ACTION) - - handlers["object_navigator_toggle_simplify"] = \ - input_event.InputEventHandler( - self.toggle_simplify, - cmdnames.NAVIGATOR_TOGGLE_SIMPLIFIED) - - return handlers - - def _include_in_simple_navigation(self, obj): - """Returns True if obj should be included in simple navigation.""" - - return AXUtilities.is_paragraph(obj) - - def _exclude_from_simple_navigation(self, script, obj): - """Returns True if obj should be excluded from simple navigation.""" - - if self._include_in_simple_navigation(obj): - tokens = ["OBJECT NAVIGATOR: Not excluding", obj, ": explicit inclusion"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - # isLayoutOnly should catch things that really should be skipped. - # - # You do not want to exclude all sections because they may be focusable, e.g. - #
foo
should not be excluded, despite the poor authoring. - # - # You do not want to exclude table cells and headers because it will make the - # selectable items in tables non-navigable (e.g. the mail folders in Evolution) - if script.utilities.isLayoutOnly(obj): - tokens = ["OBJECT NAVIGATOR: Excluding", obj, ": is layout only"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - tokens = ["OBJECT NAVIGATOR: Not excluding", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - def _children(self, script, obj): - """Returns a list of children for obj, taking simple navigation into account.""" - - if not AXObject.get_child_count(obj): - return [] - - children = list(AXObject.iter_children(obj)) - if not self._simplify: - return children - - # Add the children of excluded objects to our list of children. - functional_children = [] - for child in children: - if self._exclude_from_simple_navigation(script, child): - functional_children.extend(self._children(script, child)) - else: - functional_children.append(child) - - return functional_children - - def _parent(self, script, obj): - """Returns the parent for obj, taking simple navigation into account.""" - - parent = AXObject.get_parent(obj) - if not self._simplify: - return parent - - # The first non-excluded ancestor is the functional parent. - while parent is not None and self._exclude_from_simple_navigation(script, parent): - parent = AXObject.get_parent(parent) - - return parent - - def _set_navigator_focus(self, obj): - """Changes the navigator focus, storing the previous focus.""" - - self._last_navigator_focus = self._navigator_focus - self._navigator_focus = obj - - def update(self): - """Updates the navigator focus to Cthulhu's object of interest.""" - - mode, region = cthulhu.getActiveModeAndObjectOfInterest() - obj = region or cthulhu_state.locusOfFocus - if self._last_locus_of_focus == obj or (region is None and mode == cthulhu.FLAT_REVIEW): - return - - self._navigator_focus = obj - self._last_locus_of_focus = obj - - def present(self, script): - """Presents the current navigator focus to the user.""" - - tokens = ["OBJECT NAVIGATOR: Presenting", self._navigator_focus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.emitRegionChanged(self._navigator_focus, mode=cthulhu.OBJECT_NAVIGATOR) - script.presentObject(self._navigator_focus, priorObj=self._last_navigator_focus) - - def up(self, script, event=None): - """Moves the navigator focus to the parent of the current focus.""" - - self.update() - parent = self._parent(script, self._navigator_focus) - if parent is not None: - self._set_navigator_focus(parent) - self.present(script) - else: - script.presentMessage(messages.NAVIGATOR_NO_PARENT) - - def down(self, script, event=None): - """Moves the navigator focus to the first child of the current focus.""" - - self.update() - children = self._children(script, self._navigator_focus) - if not children: - script.presentMessage(messages.NAVIGATOR_NO_CHILDREN) - return - - self._set_navigator_focus(children[0]) - self.present(script) - - def next(self, script, event=None): - """Moves the navigator focus to the next sibling of the current focus.""" - - self.update() - parent = self._parent(script, self._navigator_focus) - if parent is None: - script.presentMessage(messages.NAVIGATOR_NO_NEXT) - return - - siblings = self._children(script, parent) - if self._navigator_focus in siblings: - index = siblings.index(self._navigator_focus) - if index < len(siblings) - 1: - self._set_navigator_focus(siblings[index+1]) - self.present(script) - else: - script.presentMessage(messages.NAVIGATOR_NO_NEXT) - else: - self._set_navigator_focus(parent) - self.present(script) - - def previous(self, script, event=None): - """Moves the navigator focus to the previous sibling of the current focus.""" - - self.update() - parent = self._parent(script, self._navigator_focus) - if parent is None: - script.presentMessage(messages.NAVIGATOR_NO_PREVIOUS) - return - - siblings = self._children(script, parent) - if self._navigator_focus in siblings: - index = siblings.index(self._navigator_focus) - if index > 0: - self._set_navigator_focus(siblings[index-1]) - self.present(script) - else: - script.presentMessage(messages.NAVIGATOR_NO_PREVIOUS) - else: - self._set_navigator_focus(parent) - self.present(script) - - def toggle_simplify(self, script, event=None): - """Toggles simplified navigation.""" - - self._simplify = not self._simplify - if self._simplify: - script.presentMessage(messages.NAVIGATOR_SIMPLIFIED_ENABLED) - else: - script.presentMessage(messages.NAVIGATOR_SIMPLIFIED_DISABLED) - return True - - def perform_action(self, script, event=None): - """Attempts to click on the current focus.""" - if AXEventSynthesizer.try_all_clickable_actions(self._navigator_focus): - return True - - AXEventSynthesizer.click_object(self._navigator_focus, 1) - return True - - -_navigator = None -def getNavigator(): - """Returns the Object Navigator""" - - global _navigator - if _navigator is None: - _navigator = ObjectNavigator() - return _navigator diff --git a/src/cthulhu/object_properties.py b/src/cthulhu/object_properties.py deleted file mode 100644 index 0c8e87b..0000000 --- a/src/cthulhu/object_properties.py +++ /dev/null @@ -1,672 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Propeerties of accessible objects. These have been put in their own module -so that we can present them in the correct language when users change the -language on the fly without having to reload a bunch of modules.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2013 The Cthulhu Team" -__license__ = "LGPL" - -from .cthulhu_i18n import _, C_ - -# Translators: this is the action name for the 'toggle' action. It must be the -# same string used in the *.po file for gail. -ACTION_TOGGLE = _("toggle") - -# Translators: this is a indication of the focused icon and the count of the -# total number of icons within an icon panel. An example of an icon panel is -# the Nautilus folder view. -ICON_INDEX_SPEECH = _("on %(index)d of %(total)d") - -# Translators: this refers to the position of an item in a list or group of -# objects, such as menu items in a menu, radio buttons in a radio button group, -# combobox item in a combobox, etc. -GROUP_INDEX_SPEECH = _("%(index)d of %(total)d") - -# Translators: this refers to the position of an item in a list for which the -# size is unknown. Examples include unlimited scrolling news/article feeds -# on social media sites, and message lists on services such as gmail where -# you're currently viewing messages 1-100 out of some huge, unspecified -# number. Normally Cthulhu announces both the position of the item and the -# total number (e.g. "3 of 5"). This is the corresponding message for the -# unknown-count scenario. -GROUP_INDEX_TOTAL_UNKNOWN_SPEECH = _("item %(index)d") - -# Translators: This message describes a list item in a document. Nesting level -# is how "deep" the item is (e.g., a level of 2 represents a list item inside a -# list that's inside another list). -NESTING_LEVEL_SPEECH = _("Nesting level %d") - -# Translators: This message describes a list item in a document. Nesting level -# is how "deep" the item is (e.g., a level of 2 represents a list item inside a -# list that's inside another list). This string is specifically for braille. -# Because braille displays lack real estate, we're using a shorter string than -# we use for speech. -NESTING_LEVEL_BRAILLE = _("LEVEL %d") - -# Translators: This represents the depth of a node in a TreeView (i.e. how many -# ancestors the node has). This is the spoken version. -NODE_LEVEL_SPEECH = _("tree level %d") - -# Translators: This represents the depth of a node in a TreeView (i.e. how many -# ancestors the node has). This is the braille version. -NODE_LEVEL_BRAILLE = _("TREE LEVEL %d") - -# Translators: In web content, authors can identify an element which contains -# detailed information about another element. For instance, for a password -# field, there may be a list of requirements (number of characters, number of -# special symbols, etc.). For an image, there may be an extended description -# before or after the image. Often there are visual clues connecting the -# detailed information to its related object. We need to convey this non-visually. -# This relationship will be presented for the object containing the details, e.g. -# when arrowing into or out of it. The string substitution is for the object to -# which the detailed information applies. For instance, when navigating into -# the details for an image named Pythagorean Theorem, Cthulhu would present: -# "details for Pythagorean Theorem image". -# See https://w3c.github.io/aria/#aria-details -RELATION_DETAILS_FOR = _("details for %s") - -# Translators: In web content, authors can identify an element which contains -# detailed information about another element. For instance, for a password -# field, there may be a list of requirements (number of characters, number of -# special symbols, etc.). For an image, there may be an extended description -# before or after the image. Often there are visual clues connecting the -# detailed information to its related object. We need to convey this non-visually. -# This relationship will be presented for the object which has details to tell -# the user the type of object where the details can be found so that they can -# more quickly navigate to it. The string substitution is for the object to -# which the detailed information applies. For instance, when navigating to -# a password field which has details in a list named "Requirements", Cthulhu would -# present: "has details in Requirements list". -# See https://w3c.github.io/aria/#aria-details -RELATION_HAS_DETAILS = _("has details in %s") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a container with a proposed change. This change can -# include the insertion and/or deletion of content, and would typically be seen -# in a collaborative editor, such as in Google Docs. -ROLE_CONTENT_SUGGESTION = C_("role", "suggestion") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The reason for including the editable state as part of the role is to make it -# possible for users to quickly identify combo boxes in which a value can be -# typed or arrowed to. -ROLE_EDITABLE_COMBO_BOX = _("editable combo box") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role is to describe elements in web content which have the contenteditable -# attribute set to true, indicating that the element can be edited by the user. -ROLE_EDITABLE_CONTENT = _("editable content") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The feed role is a scrollable list of articles where scrolling may cause -# articles to be added to or removed from either end of the list. -# https://w3c.github.io/aria/#feed -ROLE_FEED = C_("role", "feed") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The figure role is a perceivable section of content that typically contains a -# graphical document, images, code snippets, or example text. -# https://w3c.github.io/aria/#figure -ROLE_FIGURE = C_("role", "figure") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the abstract in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-abstract -ROLE_ABSTRACT = C_("role", "abstract") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the acknowledgments in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-acknowledgments -ROLE_ACKNOWLEDGMENTS = C_("role", "acknowledgments") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the afterword in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-afterword -ROLE_AFTERWORD = C_("role", "afterword") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the appendix in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-appendix -ROLE_APPENDIX = C_("role", "appendix") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a bibliography entry in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-biblioentry -ROLE_BIBLIOENTRY = C_("role", "bibliography entry") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the bibliography in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-bibliography -ROLE_BIBLIOGRAPHY = C_("role", "bibliography") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a chapter in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-chapter -ROLE_CHAPTER = C_("role", "chapter") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the colophon in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-colophon -ROLE_COLOPHON = C_("role", "colophon") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the conclusion in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-conclusion -ROLE_CONCLUSION = C_("role", "conclusion") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the cover in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-cover -ROLE_COVER = C_("role", "cover") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a single credit in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-credit -ROLE_CREDIT = C_("role", "credit") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the credits in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-credits -ROLE_CREDITS = C_("role", "credits") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the dedication in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-dedication -ROLE_DEDICATION = C_("role", "dedication") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a single endnote in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-endnote -ROLE_ENDNOTE = C_("role", "endnote") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the endnotes in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-endnotes -ROLE_ENDNOTES = C_("role", "endnotes") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the epigraph in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-epigraph -ROLE_EPIGRAPH = C_("role", "epigraph") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the epilogue in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-epilogue -ROLE_EPILOGUE = C_("role", "epilogue") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the errata in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-errata -ROLE_ERRATA = C_("role", "errata") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to an example in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-example -ROLE_EXAMPLE = C_("role", "example") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the foreword in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-foreword -ROLE_FOREWORD = C_("role", "foreword") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the glossary in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-glossary -ROLE_GLOSSARY = C_("role", "glossary") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the index in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-index -ROLE_INDEX = C_("role", "index") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the introduction in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-introduction -ROLE_INTRODUCTION = C_("role", "introduction") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a pagebreak in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-pagebreak -ROLE_PAGEBREAK = C_("role", "page break") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a page list in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-pagelist -ROLE_PAGELIST = C_("role", "page list") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a named part in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-part -ROLE_PART = C_("role", "part") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the preface in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-preface -ROLE_PREFACE = C_("role", "preface") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the prologue in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-prologue -ROLE_PROLOGUE = C_("role", "prologue") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a pullquote in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-pullquote -ROLE_PULLQUOTE = C_("role", "pullquote") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to a questions-and-answers section in a digitally-published -# document. https://w3c.github.io/dpub-aria/#doc-qna -# In English, "QNA" is generally recognized by native speakers. If your language -# lacks the equivalent, please prefer the shortest phrase which clearly conveys -# the meaning. -ROLE_QNA = C_("role", "QNA") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the subtitle in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-subtitle -ROLE_SUBTITLE = C_("role", "subtitle") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# This role refers to the table of contents in a digitally-published document. -# https://w3c.github.io/dpub-aria/#doc-toc -ROLE_TOC = C_("role", "table of contents") - -# Translators: The 'h' in this string represents a heading level attribute for -# content that you might find in something such as HTML content (e.g.,

). -# The translated form is meant to be a single character followed by a numeric -# heading level, where the single character is to indicate 'heading'. -ROLE_HEADING_LEVEL_BRAILLE = _("h%d") - -# Translators: The %(level)d is in reference to a heading level in HTML (e.g., -# For

, the level is 3) and the %(role)s is in reference to a previously -# translated rolename for the heading. -ROLE_HEADING_LEVEL_SPEECH = _("%(role)s level %(level)d") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The reason we include the orientation as part of the role is because in some -# applications and toolkits, it can dictate which keyboard keys should be used -# to modify the value of the widget. -ROLE_SCROLL_BAR_HORIZONTAL = _("horizontal scroll bar") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The reason we include the orientation as part of the role is because in some -# applications and toolkits, it can dictate which keyboard keys should be used -# to modify the value of the widget. -ROLE_SCROLL_BAR_VERTICAL = _("vertical scroll bar") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# A slider is a widget which looks like a bar and displays a value as a range. -# A common example of a slider can be found in UI for modifying volume levels. -# The reason we include the orientation as part of the role is because in some -# applications and toolkits, it can dictate which keyboard keys should be used -# to modify the value of the widget. -ROLE_SLIDER_HORIZONTAL = _("horizontal slider") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# A slider is a widget which looks like a bar and displays a value as a range. -# A common example of a slider can be found in UI for modifying volume levels. -# The reason we include the orientation as part of the role is because in some -# applications and toolkits, it can dictate which keyboard keys should be used -# to modify the value of the widget. -ROLE_SLIDER_VERTICAL = _("vertical slider") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# A splitter is a bar that divides a container into two parts. It is often, but -# not necessarily, user resizable. A common example of a splitter can be found -# in email applications, where there is a container on the left which holds a -# list of all the mail folders and a container on the right which lists all of -# the messages in the selected folder. The bar which you click on and drag to -# resize these containers is the splitter. The reason we include the orientation -# as part of the role is because in some applications and toolkits, it can -# dictate which keyboard keys should be used to modify the value of the widget. -ROLE_SPLITTER_HORIZONTAL = _("horizontal splitter") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# A splitter is a bar that divides a container into two parts. It is often, but -# not necessarily, user resizable. A common example of a splitter can be found -# in email applications, where there is a container on the left which holds a -# list of all the mail folders and a container on the right which lists all of -# the messages in the selected folder. The bar which you click on and drag to -# resize these containers is the splitter. The reason we include the orientation -# as part of the role is because in some applications and toolkits, it can -# dictate which keyboard keys should be used to modify the value of the widget. -ROLE_SPLITTER_VERTICAL = _("vertical splitter") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The "switch" role is a "light switch" style toggle, such as can be seen in -# https://developer.gnome.org/gtk3/stable/GtkSwitch.html -ROLE_SWITCH = C_("role", "switch") - -# Translators: This is an alternative name for the parent object of a series -# of icons. -ROLE_ICON_PANEL = _("Icon panel") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The "banner" role is defined in the ARIA specification as "A region that -# contains mostly site-oriented content, rather than page-specific content." -# See https://www.w3.org/TR/wai-aria-1.1/#banner -ROLE_LANDMARK_BANNER = C_("role", "banner") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The "complementary" role is defined in the ARIA specification as "A supporting -# section of the document, designed to be complementary to the main content at a -# similar level in the DOM hierarchy, but remains meaningful when separated from -# the main content." See https://www.w3.org/TR/wai-aria-1.1/#complementary -ROLE_LANDMARK_COMPLEMENTARY = C_("role", "complementary content") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The "contentinfo" role is defined in the ARIA specification as "A large -# perceivable region that contains information about the parent document. -# Examples of information included in this region of the page are copyrights and -# links to privacy statements." See https://www.w3.org/TR/wai-aria-1.1/#contentinfo -ROLE_LANDMARK_CONTENTINFO = C_("role", "information") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The "main" role is defined in the ARIA specification as "The main content of -# a document." See https://www.w3.org/TR/wai-aria-1.1/#main -ROLE_LANDMARK_MAIN = C_("role", "main content") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The "navigation" role is defined in the ARIA specification as "A collection of -# navigational elements (usually links) for navigating the document or related -# documents." See https://www.w3.org/TR/wai-aria-1.1/#navigation -ROLE_LANDMARK_NAVIGATION = C_("role", "navigation") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The "region" role is defined in the ARIA specification as "A perceivable -# section containing content that is relevant to a specific, author-specified -# purpose and sufficiently important that users will likely want to be able to -# navigate to the section easily and to have it listed in a summary of the page." -# See https://www.w3.org/TR/wai-aria-1.1/#region -ROLE_LANDMARK_REGION = C_("role", "region") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The "search" role is defined in the ARIA specification as "A landmark region -# that contains a collection of items and objects that, as a whole, combine to -# create a search facility." See https://www.w3.org/TR/wai-aria-1.1/#search -ROLE_LANDMARK_SEARCH = C_("role", "search") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# The reason for including the visited state as part of the role is to make it -# possible for users to quickly identify if the link is associated with content -# already read. -ROLE_VISITED_LINK = _("visited link") - -# Translators: This string should be treated as a role describing an object. -# Examples of roles include "checkbox", "radio button", "paragraph", and "link." -# A menu button is button widget that causes a menu to appear when the user -# activates the button. -ROLE_MENU_BUTTON = _("menu button") - -# Translators: This string refers to a row or column whose sort-order has been set -# to ascending. -SORT_ORDER_ASCENDING = _("sorted ascending") - -# Translators: This string refers to a row or column whose sort-order has been set -# to descending. -SORT_ORDER_DESCENDING = _("sorted descending") - -# Translators: This string refers to a row or column whose sort-order has been set, -# but the nature of the sort order is unknown or something other than ascending or -# descending. -SORT_ORDER_OTHER = _("sorted") - -# Translators: This is a state which applies to elements in document content -# which have an "onClick" action. -STATE_CLICKABLE = _("clickable") - -# Translators: This is a state which applies to items which can be expanded -# or collapsed such as combo boxes and nodes/groups in a treeview. Collapsed -# means the item's children are not showing; expanded means they are. -STATE_COLLAPSED = _("collapsed") - -# Translators: This is a state which applies to items which can be expanded -# or collapsed such as combo boxes and nodes/groups in a treeview. Collapsed -# means the item's children are not showing; expanded means they are. -STATE_EXPANDED = _("expanded") - -# Translators: This is a state which applies to elements in document content -# which have a longdesc attribute. http://www.w3.org/TR/WCAG20-TECHS/H45.html -STATE_HAS_LONGDESC = _("has long description") - -# Translators: This is a state which applies to the orientation of widgets -# such as sliders and scroll bars. -STATE_HORIZONTAL = _("horizontal") - -# Translators: This is a state which applies to the orientation of widgets -# such as sliders and scroll bars. -STATE_VERTICAL = _("vertical") - -# Translators: This is a state which applies to a check box. -STATE_CHECKED = C_("checkbox", "checked") - -# Translators: This is a state which applies to a check box. -STATE_NOT_CHECKED = C_("checkbox", "not checked") - -# Translators: This is a state which applies to a switch. For an example of -# a switch, see https://developer.gnome.org/gtk3/stable/GtkSwitch.html -STATE_ON_SWITCH = C_("switch", "on") - -# Translators: This is a state which applies to a switch. For an example of -# a switch, see https://developer.gnome.org/gtk3/stable/GtkSwitch.html -STATE_OFF_SWITCH = C_("switch", "off") - -# Translators: This is a state which applies to a check box. -STATE_PARTIALLY_CHECKED = C_("checkbox", "partially checked") - -# Translators: This is a state which applies to a toggle button. -STATE_PRESSED = C_("togglebutton", "pressed") - -# Translators: This is a state which applies to a toggle button. -STATE_NOT_PRESSED = C_("togglebutton", "not pressed") - -# Translators: This is a state which applies to an item or option -# in a selectable list. -STATE_UNSELECTED_LIST_ITEM = C_("listitem", "not selected") - -# Translators: This is a state which applies to a radio button. -STATE_SELECTED_RADIO_BUTTON = C_("radiobutton", "selected") - -# Translators: This is a state which applies to a radio button. -STATE_UNSELECTED_RADIO_BUTTON = C_("radiobutton", "not selected") - -# Translators: This is a state which applies to a table cell. -STATE_UNSELECTED_TABLE_CELL = C_("tablecell", "not selected") - -# Translators: This is a state which applies to a link. -STATE_VISITED = C_("link state", "visited") - -# Translators: This is a state which applies to a link. -STATE_UNVISITED = C_("link state", "unvisited") - -# Translators: This state represents an item on the screen that has been set -# insensitive (or grayed out). -STATE_INSENSITIVE_SPEECH = _("grayed") - -# Translators: This state represents an item on the screen that has been set -# insensitive (or grayed out). -STATE_INSENSITIVE_BRAILLE = _("grayed") - -# Translators: Certain objects (such as form controls on web pages) can have -# STATE_EDITABLE set to inform the user that this field can be filled out. -# It is assumed that form fields will be editable; if they lack this state, -# we need to present that information to the user. This string is the spoken -# version. -STATE_READ_ONLY_SPEECH = C_("text", "read only") - -# Translators: Certain objects (such as form controls on web pages) can have -# STATE_EDITABLE set to inform the user that this field can be filled out. -# It is assumed that form fields will be editable; if they lack this state, -# we need to present that information to the user. This string is the braille -# version. (Because braille displays have limited real estate, we abbreviate.) -STATE_READ_ONLY_BRAILLE = C_("text", "rdonly") - -# Translators: Certain objects (such as form controls on web pages) can have -# STATE_REQUIRED set to inform the user that this field must be filled out. -STATE_REQUIRED_SPEECH = _("required") - -# Translators: Certain objects (such as form controls on web pages) can have -# STATE_REQUIRED set to inform the user that this field must be filled out. -STATE_REQUIRED_BRAILLE = _("required") - -# Translators: "multi-select" refers to a web form list in which more than -# one item can be selected at a time. -STATE_MULTISELECT_SPEECH = _("multi-select") - -# Translators: STATE_INVALID_ENTRY indicates that the associated object, such -# as a form field, has an error. The following string is spoken when all we -# know is that an error has occurred, but not the type of error. -STATE_INVALID_SPEECH = C_("error", "invalid entry") - -# Translators: STATE_INVALID_ENTRY indicates that the associated object, such -# as a form field, has an error. The following string is displayed in braille -# when all we know is that an error has occurred, but not the type of error. -# We prefer a smaller string than in speech because braille displays have a -# limited size. -STATE_INVALID_BRAILLE = C_("error", "invalid") - -# Translators: STATE_INVALID_ENTRY indicates that the associated object, such -# as a form field, has an error. The following string is spoken when the error -# is related to spelling. -STATE_INVALID_SPELLING_SPEECH = C_("error", "invalid spelling") - -# Translators: STATE_INVALID_ENTRY indicates that the associated object, such -# as a form field, has an error. The following string is displayed in braille -# when the error is related to spelling. We prefer a smaller string than in -# speech because braille displays have a limited size. -STATE_INVALID_SPELLING_BRAILLE = C_("error", "spelling") - -# Translators: STATE_INVALID_ENTRY indicates that the associated object, such -# as a form field, has an error. The following string is spoken when the error -# is related to grammar. -STATE_INVALID_GRAMMAR_SPEECH = C_("error", "invalid grammar") - -# Translators: STATE_INVALID_ENTRY indicates that the associated object, such -# as a form field, has an error. The following string is displayed in braille -# when the error is related to grammar. We prefer a smaller string than in -# speech because braille displays have a limited size. -STATE_INVALID_GRAMMAR_BRAILLE = C_("error", "grammar") - -# TODO: Look at why we're doing this as lists. - -CHECK_BOX_INDICATORS_SPEECH = \ - [STATE_NOT_CHECKED, STATE_CHECKED, STATE_PARTIALLY_CHECKED] -EXPANSION_INDICATORS_SPEECH = \ - [STATE_COLLAPSED, STATE_EXPANDED] -INVALID_INDICATORS_SPEECH = \ - [STATE_INVALID_SPEECH, - STATE_INVALID_SPELLING_SPEECH, - STATE_INVALID_GRAMMAR_SPEECH] -RADIO_BUTTON_INDICATORS_SPEECH = \ - [STATE_UNSELECTED_RADIO_BUTTON, STATE_SELECTED_RADIO_BUTTON] - -SWITCH_INDICATORS_SPEECH = [STATE_OFF_SWITCH, STATE_ON_SWITCH] -TOGGLE_BUTTON_INDICATORS_SPEECH = \ - [STATE_NOT_PRESSED, STATE_PRESSED] - -CHECK_BOX_INDICATORS_BRAILLE = ["< >", "", "<->"] -EXPANSION_INDICATORS_BRAILLE = [STATE_COLLAPSED, STATE_EXPANDED] -INVALID_INDICATORS_BRAILLE = [STATE_INVALID_BRAILLE, - STATE_INVALID_SPELLING_BRAILLE, - STATE_INVALID_GRAMMAR_BRAILLE] -RADIO_BUTTON_INDICATORS_BRAILLE = ["& y", "&=y"] -SWITCH_INDICATORS_BRAILLE = ["& y", "&=y"] -TOGGLE_BUTTON_INDICATORS_BRAILLE = ["& y", "&=y"] - -TABLE_CELL_DELIMITER_BRAILLE = " " -EOL_INDICATOR_BRAILLE = " $l" - -CHECK_BOX_INDICATORS_SOUND = ["not_checked", "checked", "partially_checked"] -EXPANSION_INDICATORS_SOUND = ["collapsed", "expanded"] -INVALID_INDICATORS_SOUND = ["invalid", "invalid_spelling", "invalid_grammar"] -RADIO_BUTTON_INDICATORS_SOUND = ["unselected", "selected"] -SWITCH_INDICATORS_SOUND = ["off", "on"] -TOGGLE_BUTTON_INDICATORS_SOUND = ["not_pressed", "pressed"] -STATE_CLICKABLE_SOUND = "clickable" -STATE_HAS_LONGDESC_SOUND = "haslongdesc" -STATE_INSENSITIVE_SOUND = "insensitive" -STATE_MULTISELECT_SOUND = "multiselect" -STATE_READ_ONLY_SOUND = "readonly" -STATE_REQUIRED_SOUND = "required" -STATE_VISITED_SOUND = "visited" diff --git a/src/cthulhu/phonnames.py b/src/cthulhu/phonnames.py deleted file mode 100644 index ad76f0c..0000000 --- a/src/cthulhu/phonnames.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides getPhoneticName method that maps each letter of the -alphabet into its localized phonetic equivalent.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2006-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -from .cthulhu_i18n import _ - -# Translators: this is a structure to assist in the generation of -# spoken military-style spelling. For example, 'abc' becomes 'alpha -# bravo charlie'. -# -# It is a simple structure that consists of pairs of -# -# letter : word(s) -# -# where the letter and word(s) are separate by colons and each -# pair is separated by commas. For example, we see: -# -# a : alpha, b : bravo, c : charlie, -# -# And so on. The complete set should consist of all the letters from -# the alphabet for your language paired with the common -# military/phonetic word(s) used to describe that letter. -# -# The Wikipedia entry -# http://en.wikipedia.org/wiki/NATO_phonetic_alphabet has a few -# interesting tidbits about local conventions in the sections -# "Additions in German, Danish and Norwegian" and "Variants". -# -__phonlist = _("a : alpha, b : bravo, c : charlie, " - "d : delta, e : echo, f : foxtrot, " - "g : golf, h : hotel, i : india, " - "j : juliet, k : kilo, l : lima, " - "m : mike, n : november, o : oscar, " - "p : papa, q : quebec, r : romeo, " - "s : sierra, t : tango, u : uniform, " - "v : victor, w : whiskey, x : xray, " - "y : yankee, z : zulu") - -__phonnames = {} - -for __pair in __phonlist.split(','): - __w = __pair.split(':') - __phonnames [__w[0].strip()] = __w[1].strip() - -def getPhoneticName(character): - """Given a character, return its phonetic name, which is typically - the 'military' term used for the character. - - Arguments: - - character: the character to get the military name for - - Returns a string representing the military name for the character - """ - - return __phonnames.get(character, character) diff --git a/src/cthulhu/piper_audio_player.py b/src/cthulhu/piper_audio_player.py deleted file mode 100644 index 667edaa..0000000 --- a/src/cthulhu/piper_audio_player.py +++ /dev/null @@ -1,307 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""GStreamer-based audio player for Piper TTS synthesis output.""" - -__id__ = "$Id:$" -__version__ = "$Revision:$" -__date__ = "$Date:$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import threading - -import gi -from gi.repository import GLib -from . import debug -from . import gstreamer_support -from . import sound_sink - -try: - gi.require_version('Gst', '1.0') - from gi.repository import Gst -except Exception: - _gstreamerAvailable = False -else: - _gstreamerAvailable = gstreamer_support.gst_init_check_available(Gst) - - -class PiperAudioPlayer: - """GStreamer-based audio player for Piper TTS output. - - Handles raw PCM audio data from Piper synthesis and plays it through - a GStreamer pipeline with volume control. - """ - - def __init__(self, sampleRate=22050): - """Initialize the audio player. - - Arguments: - - sampleRate: Audio sample rate in Hz (default 22050, common for Piper) - """ - self._sampleRate = sampleRate - self._pipeline = None - self._appsrc = None - self._volume = None - self._initialized = False - self._playing = False - self._lock = threading.Lock() - self._completionCallback = None - - if not _gstreamerAvailable: - msg = 'PIPER AUDIO: GStreamer is not available' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return - - self._init() - - def _init(self): - """Initialize the GStreamer pipeline.""" - if self._initialized: - return True - - if not _gstreamerAvailable: - return False - - self._resetPipeline() - - try: - self._pipeline = Gst.Pipeline.new("piper-audio") - configuredSink = sound_sink.get_configured_sound_sink() - - self._appsrc = Gst.ElementFactory.make("appsrc", "source") - if self._appsrc is None: - msg = 'PIPER AUDIO: Failed to create appsrc element' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - - self._appsrc.set_property("format", Gst.Format.TIME) - self._appsrc.set_property("is-live", False) - self._appsrc.set_property("block", False) - - caps = Gst.Caps.from_string( - f"audio/x-raw,format=S16LE,channels=1," - f"rate={self._sampleRate},layout=interleaved" - ) - self._appsrc.set_property("caps", caps) - - convert = Gst.ElementFactory.make("audioconvert", "convert") - resample = Gst.ElementFactory.make("audioresample", "resample") - - self._volume = Gst.ElementFactory.make("volume", "volume") - if self._volume is None: - msg = 'PIPER AUDIO: Failed to create volume element' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - - sink, sinkName, sinkError = sound_sink.create_audio_sink("sink", configuredSink) - if sink is None: - msg = f'PIPER AUDIO: {sinkError or "Failed to create audio sink"}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - - for element in [self._appsrc, convert, resample, self._volume, sink]: - self._pipeline.add(element) - - if not self._appsrc.link(convert): - msg = 'PIPER AUDIO: Failed to link appsrc to convert' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - if not convert.link(resample): - msg = 'PIPER AUDIO: Failed to link convert to resample' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - if not resample.link(self._volume): - msg = 'PIPER AUDIO: Failed to link resample to volume' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - if not self._volume.link(sink): - msg = 'PIPER AUDIO: Failed to link volume to sink' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - - bus = self._pipeline.get_bus() - bus.add_signal_watch() - bus.connect("message", self._onMessage) - - self._initialized = True - msg = ( - f'PIPER AUDIO: Pipeline initialized successfully using ' - f'{sinkName} (soundSink={configuredSink})' - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - except Exception as e: - msg = f'PIPER AUDIO: Failed to initialize pipeline: {e}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - - def _resetPipeline(self): - """Reset the GStreamer pipeline and related elements.""" - if self._pipeline is not None: - self._pipeline.set_state(Gst.State.NULL) - self._pipeline = None - self._appsrc = None - self._volume = None - self._initialized = False - - def _onMessage(self, bus, message): - """Handle GStreamer bus messages.""" - if message.type == Gst.MessageType.EOS: - self._pipeline.set_state(Gst.State.NULL) - with self._lock: - self._playing = False - if self._completionCallback: - GLib.idle_add(self._completionCallback) - self._completionCallback = None - elif message.type == Gst.MessageType.ERROR: - self._pipeline.set_state(Gst.State.NULL) - with self._lock: - self._playing = False - error, info = message.parse_error() - msg = f'PIPER AUDIO ERROR: {error}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - - def setSampleRate(self, sampleRate): - """Update the sample rate for the audio stream. - - Arguments: - - sampleRate: New sample rate in Hz - """ - if sampleRate != self._sampleRate: - self._sampleRate = sampleRate - self.stop() - self._resetPipeline() - self._init() - - def setVolume(self, volumeLevel): - """Set the playback volume. - - Arguments: - - volumeLevel: Volume level from 0.0 to 1.0 - """ - if self._volume is not None: - volume = max(0.0, min(1.0, volumeLevel)) - self._volume.set_property("volume", volume) - - def play(self, audioData, interrupt=True, completionCallback=None): - """Play raw PCM audio data. - - Arguments: - - audioData: Raw PCM audio data as bytes (16-bit signed, little-endian) - - interrupt: If True, stop any current playback first - - completionCallback: Optional callback to invoke when playback completes - """ - if not self._initialized: - if not self._init(): - msg = 'PIPER AUDIO: Cannot play - not initialized' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - - if interrupt: - self.stop() - - with self._lock: - self._playing = True - - self._completionCallback = completionCallback - - self._pipeline.set_state(Gst.State.PLAYING) - - buf = Gst.Buffer.new_wrapped(audioData) - result = self._appsrc.emit("push-buffer", buf) - if result != Gst.FlowReturn.OK: - msg = f'PIPER AUDIO: Failed to push buffer: {result}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - - self._appsrc.emit("end-of-stream") - return True - - def playStream(self, audioGenerator, interrupt=True, completionCallback=None): - """Play audio from a streaming generator. - - Arguments: - - audioGenerator: Iterator/generator yielding audio chunks as bytes - - interrupt: If True, stop any current playback first - - completionCallback: Optional callback when playback completes - """ - if not self._initialized: - if not self._init(): - msg = 'PIPER AUDIO: Cannot play stream - not initialized' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - - if interrupt: - self.stop() - - with self._lock: - self._playing = True - - self._completionCallback = completionCallback - - self._pipeline.set_state(Gst.State.PLAYING) - - def feedThread(): - try: - for audioChunk in audioGenerator: - with self._lock: - if not self._playing: - break - - buf = Gst.Buffer.new_wrapped(bytes(audioChunk)) - result = self._appsrc.emit("push-buffer", buf) - if result != Gst.FlowReturn.OK: - msg = f'PIPER AUDIO: Stream push failed: {result}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - break - except Exception as e: - msg = f'PIPER AUDIO: Stream feed error: {e}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - finally: - self._appsrc.emit("end-of-stream") - - thread = threading.Thread(target=feedThread, daemon=True) - thread.start() - return True - - def isPlaying(self): - """Check if audio is currently playing. - - Returns True if playback is in progress. - """ - with self._lock: - return self._playing - - def stop(self): - """Stop any current playback.""" - with self._lock: - self._playing = False - - if self._pipeline is not None: - self._pipeline.set_state(Gst.State.NULL) - - self._completionCallback = None - - def shutdown(self): - """Shut down the audio player and release resources.""" - self.stop() - self._resetPipeline() diff --git a/src/cthulhu/piper_voice_manager.py b/src/cthulhu/piper_voice_manager.py deleted file mode 100644 index c68e01a..0000000 --- a/src/cthulhu/piper_voice_manager.py +++ /dev/null @@ -1,347 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Voice discovery and management for Piper TTS.""" - -__id__ = "$Id:$" -__version__ = "$Revision:$" -__date__ = "$Date:$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import json -import os -import re -from dataclasses import dataclass, field -from pathlib import Path -from typing import Dict, List, Optional - -from . import debug -from . import speechserver - - -@dataclass -class PiperVoiceInfo: - """Metadata for a Piper voice model.""" - - name: str - language: str - dialect: str - quality: str - modelPath: Path - configPath: Path - sampleRate: int = 22050 - speakers: Dict[int, str] = field(default_factory=dict) - - @property - def key(self) -> str: - """Return a unique key for this voice.""" - dialectPart = f"-{self.dialect}" if self.dialect else "" - return f"{self.language}{dialectPart}-{self.name}-{self.quality}" - - @property - def displayName(self) -> str: - """Return a human-readable display name.""" - dialectPart = f" ({self.dialect})" if self.dialect else "" - return f"{self.name} - {self.language}{dialectPart} [{self.quality}]" - - @property - def isMultiSpeaker(self) -> bool: - """Return True if this is a multi-speaker model.""" - return len(self.speakers) > 1 - - -class PiperVoiceManager: - """Discovers and manages Piper voice models. - - Searches standard paths for Piper voice models (.onnx files with - companion .onnx.json config files) and provides methods to list - and load them. - """ - - VOICE_SEARCH_PATHS = [ - "~/.local/share/piper/voices", - "~/.local/share/piper-voices", - "~/.local/share/piper-tts/voices", - "~/.config/piper/voices", - "~/.config/piper-tts/voices", - "$XDG_DATA_HOME/piper/voices", - "$XDG_DATA_HOME/piper-voices", - "$XDG_DATA_HOME/piper-tts/voices", - "$XDG_DATA_HOME/cthulhu/piper-voices", - "/usr/share/piper/voices", - "/usr/share/piper-voices", - "/usr/share/piper-tts/voices", - "/usr/local/share/piper/voices", - "/usr/local/share/piper-voices", - "/usr/local/share/piper-tts/voices", - ] - - VOICE_FILENAME_PATTERN = re.compile( - r'^(?P[a-z]{2})(?:_(?P[A-Z]{2}))?' - r'-(?P[a-zA-Z0-9_]+)' - r'-(?Plow|medium|high|x_low)\.onnx$' - ) - - def __init__(self, customPath=None): - """Initialize the voice manager. - - Arguments: - - customPath: Optional additional path to search for voices - """ - self._customPath = customPath - self._voices = [] - self._voiceCache = {} - - def discoverVoices(self) -> List[PiperVoiceInfo]: - """Discover all available Piper voices. - - Searches standard paths and returns a list of PiperVoiceInfo - objects for each valid voice found. - """ - self._voices = [] - searchPaths = self._getSearchPaths() - - for searchPath in searchPaths: - path = Path(os.path.expandvars(os.path.expanduser(searchPath))) - if not path.exists(): - continue - - msg = f'PIPER VOICES: Searching {path}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - for onnxFile in path.rglob("*.onnx"): - configFile = Path(str(onnxFile) + ".json") - if not configFile.exists(): - configFile = onnxFile.with_suffix(".onnx.json") - - if configFile.exists(): - try: - voice = self._parseVoice(onnxFile, configFile) - if voice: - self._voices.append(voice) - msg = f'PIPER VOICES: Found voice {voice.displayName}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - except Exception as e: - msg = f'PIPER VOICES: Failed to parse {onnxFile}: {e}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - else: - voice = self._parseVoiceFromFilename(onnxFile) - if voice: - self._voices.append(voice) - msg = f'PIPER VOICES: Found voice {voice.displayName} (no config)' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self._voices.sort(key=lambda v: (v.language, v.name, v.quality)) - - msg = f'PIPER VOICES: Discovered {len(self._voices)} voice(s)' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - return self._voices - - def getVoices(self) -> List[PiperVoiceInfo]: - """Get the list of discovered voices. - - Returns cached list; call discoverVoices() first to refresh. - """ - if not self._voices: - self.discoverVoices() - return self._voices - - def getVoiceByKey(self, key: str) -> Optional[PiperVoiceInfo]: - """Get a voice by its unique key. - - Arguments: - - key: Voice key (e.g., "en_US-lessac-medium") - """ - for voice in self.getVoices(): - if voice.key == key: - return voice - return None - - def getVoiceByName(self, name: str) -> Optional[PiperVoiceInfo]: - """Get a voice by name (first match). - - Arguments: - - name: Voice name (e.g., "lessac") - """ - for voice in self.getVoices(): - if voice.name == name: - return voice - return None - - def getVoicesForLanguage(self, lang: str) -> List[PiperVoiceInfo]: - """Get all voices for a specific language. - - Arguments: - - lang: Language code (e.g., "en") - """ - return [v for v in self.getVoices() if v.language == lang] - - def voiceToVoiceFamily(self, voiceInfo: PiperVoiceInfo) -> speechserver.VoiceFamily: - """Convert a PiperVoiceInfo to a Cthulhu VoiceFamily. - - Arguments: - - voiceInfo: The PiperVoiceInfo to convert - """ - return speechserver.VoiceFamily({ - speechserver.VoiceFamily.NAME: voiceInfo.displayName, - speechserver.VoiceFamily.LANG: voiceInfo.language, - speechserver.VoiceFamily.DIALECT: voiceInfo.dialect or "", - speechserver.VoiceFamily.VARIANT: voiceInfo.quality, - }) - - def _getSearchPaths(self) -> List[str]: - """Get the list of paths to search for voices.""" - paths = list(self.VOICE_SEARCH_PATHS) - - if self._customPath: - paths.insert(0, self._customPath) - - xdgDataHome = os.environ.get("XDG_DATA_HOME", "~/.local/share") - paths = [p.replace("$XDG_DATA_HOME", xdgDataHome) for p in paths] - - return paths - - def _parseVoice(self, modelPath: Path, configPath: Path) -> Optional[PiperVoiceInfo]: - """Parse a voice from its model and config files. - - Arguments: - - modelPath: Path to the .onnx model file - - configPath: Path to the .json config file - """ - try: - with open(configPath, 'r', encoding='utf-8') as f: - config = json.load(f) - except (json.JSONDecodeError, IOError) as e: - msg = f'PIPER VOICES: Failed to read config {configPath}: {e}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return None - - language = "" - dialect = "" - name = modelPath.stem - quality = "medium" - sampleRate = 22050 - speakers = {} - - if "language" in config: - langInfo = config["language"] - if isinstance(langInfo, dict): - language = langInfo.get("code", "") - if "_" in language: - parts = language.split("_") - language = parts[0] - dialect = parts[1] if len(parts) > 1 else "" - elif isinstance(langInfo, str): - if "_" in langInfo: - parts = langInfo.split("_") - language = parts[0] - dialect = parts[1] if len(parts) > 1 else "" - else: - language = langInfo - - if "audio" in config: - sampleRate = config["audio"].get("sample_rate", 22050) - - if "speaker_id_map" in config: - speakers = {v: k for k, v in config["speaker_id_map"].items()} - - match = self.VOICE_FILENAME_PATTERN.match(modelPath.name) - if match: - if not language: - language = match.group("lang") - if not dialect: - dialect = match.group("dialect") or "" - name = match.group("name") - quality = match.group("quality").replace("x_low", "x-low") - else: - stem = modelPath.stem - for q in ["low", "medium", "high", "x_low", "x-low"]: - if stem.endswith(f"-{q}"): - quality = q.replace("x_low", "x-low") - stem = stem[:-len(q)-1] - break - - parts = stem.split("-") - if parts: - langPart = parts[0] - if "_" in langPart: - langParts = langPart.split("_") - if not language: - language = langParts[0] - if not dialect: - dialect = langParts[1] if len(langParts) > 1 else "" - elif not language: - language = langPart - - if len(parts) > 1: - name = parts[1] - - if not language: - language = "unknown" - - return PiperVoiceInfo( - name=name, - language=language, - dialect=dialect, - quality=quality, - modelPath=modelPath, - configPath=configPath, - sampleRate=sampleRate, - speakers=speakers - ) - - def _parseVoiceFromFilename(self, modelPath: Path) -> Optional[PiperVoiceInfo]: - """Parse voice info from filename only (no config file). - - Arguments: - - modelPath: Path to the .onnx model file - """ - match = self.VOICE_FILENAME_PATTERN.match(modelPath.name) - if not match: - return None - - return PiperVoiceInfo( - name=match.group("name"), - language=match.group("lang"), - dialect=match.group("dialect") or "", - quality=match.group("quality").replace("x_low", "x-low"), - modelPath=modelPath, - configPath=modelPath.with_suffix(".onnx.json"), - sampleRate=22050, - speakers={} - ) - - -_manager = None - - -def getManager(customPath=None) -> PiperVoiceManager: - """Get the singleton voice manager instance. - - Arguments: - - customPath: Optional custom path to search for voices - """ - global _manager - if _manager is None: - _manager = PiperVoiceManager(customPath) - return _manager diff --git a/src/cthulhu/piperfactory.py b/src/cthulhu/piperfactory.py deleted file mode 100644 index b0696e1..0000000 --- a/src/cthulhu/piperfactory.py +++ /dev/null @@ -1,752 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides a Cthulhu speech server for Piper TTS backend.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import io -import os -import sys -import threading -import time -import wave -from concurrent.futures import ThreadPoolExecutor - -from gi.repository import GLib - -from . import chnames -from . import debug -from . import guilabels -from . import messages -from . import settings -from . import speechserver -from . import cthulhu_state -from .acss import ACSS -from . import piper_voice_manager -from . import piper_audio_player - -def _getPipxSitePackages(): - pipxHome = os.environ.get("PIPX_HOME", os.path.expanduser("~/.local/pipx")) - pythonVersion = f"python{sys.version_info.major}.{sys.version_info.minor}" - sitePackages = os.path.join( - pipxHome, - "venvs", - "piper-tts", - "lib", - pythonVersion, - "site-packages" - ) - if os.path.isdir(sitePackages): - return sitePackages - return None - - -def _tryImportPiper(): - try: - from piper.voice import PiperVoice - return PiperVoice - except ImportError: - pass - - sitePackages = _getPipxSitePackages() - if not sitePackages: - return None - - addedPath = False - if sitePackages not in sys.path: - sys.path.insert(0, sitePackages) - addedPath = True - - try: - from piper.voice import PiperVoice - msg = f'PIPER: Loaded piper-tts from pipx venv ({sitePackages})' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return PiperVoice - except ImportError: - if addedPath: - try: - sys.path.remove(sitePackages) - except ValueError: - pass - return None - - -PiperVoice = _tryImportPiper() -_piperAvailable = PiperVoice is not None -if _piperAvailable: - try: - from piper.config import SynthesisConfig as _PiperSynthesisConfig - except Exception: - _PiperSynthesisConfig = None -else: - _PiperSynthesisConfig = None -if not _piperAvailable: - msg = 'PIPER: piper-tts library not available' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - -class SpeechServer(speechserver.SpeechServer): - """Piper TTS speech server implementation. - - Provides speech synthesis using Piper neural text-to-speech, - implementing the Cthulhu SpeechServer interface. - """ - - _active_servers = {} - - DEFAULT_SERVER_ID = 'piper-default' - - @staticmethod - def getFactoryName(): - """Returns a localized name describing this factory.""" - return guilabels.PIPER_TTS - - @staticmethod - def getSpeechServers(): - """Gets available speech servers as a list.""" - servers = [] - - if not _piperAvailable: - msg = 'PIPER: Cannot list servers - piper-tts not installed' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return servers - - manager = piper_voice_manager.getManager() - voices = manager.discoverVoices() - - if not voices: - msg = 'PIPER: No voice models found' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return servers - - server = SpeechServer._getSpeechServer(SpeechServer.DEFAULT_SERVER_ID) - if server is not None: - servers.append(server) - - return servers - - @classmethod - def _getSpeechServer(cls, serverId): - """Return an active server for given id. - - Attempt to create the server if it doesn't exist yet. - Returns None when it is not possible to create the server. - """ - if serverId not in cls._active_servers: - cls(serverId) - return cls._active_servers.get(serverId) - - @staticmethod - def getSpeechServer(info=None): - """Gets a given SpeechServer based upon the info.""" - thisId = info[1] if info is not None else SpeechServer.DEFAULT_SERVER_ID - return SpeechServer._getSpeechServer(thisId) - - @staticmethod - def shutdownActiveServers(): - """Cleans up and shuts down this factory.""" - servers = list(SpeechServer._active_servers.values()) - for server in servers: - server.shutdown() - - def __init__(self, serverId): - """Initialize the Piper speech server. - - Arguments: - - serverId: Identifier for this server instance - """ - super(SpeechServer, self).__init__() - self._id = serverId - self._voice = None - self._voiceInfo = None - self._voiceManager = piper_voice_manager.getManager() - self._audioPlayer = None - self._executor = None - self._currentFuture = None - self._stopEvent = threading.Event() - self._lock = threading.Lock() - self._speakGeneration = 0 - - self._currentVoiceProperties = {} - self._acssManipulators = ( - (ACSS.RATE, self._setRate), - (ACSS.AVERAGE_PITCH, self._setPitch), - (ACSS.GAIN, self._setVolume), - (ACSS.FAMILY, self._setFamily), - ) - - self._rate = 50 - self._pitch = 5.0 - self._volume = 1.0 - - if not _piperAvailable: - msg = 'PIPER: piper-tts library not available' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return - - try: - self._init() - except Exception as e: - debug.printException(debug.LEVEL_WARNING) - msg = f'PIPER: Failed to initialize server: {e}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - else: - SpeechServer._active_servers[serverId] = self - - def _init(self): - """Initialize the speech server components.""" - voices = self._voiceManager.getVoices() - if not voices: - raise RuntimeError("No Piper voices found") - - self._voiceInfo = voices[0] - self._loadVoice(self._voiceInfo) - - self._audioPlayer = piper_audio_player.PiperAudioPlayer( - self._voiceInfo.sampleRate - ) - - self._executor = ThreadPoolExecutor( - max_workers=1, - thread_name_prefix="piper" - ) - - msg = f'PIPER: Initialized with voice {self._voiceInfo.displayName}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _loadVoice(self, voiceInfo): - """Load a Piper voice model. - - Arguments: - - voiceInfo: PiperVoiceInfo for the voice to load - """ - msg = f'PIPER: Loading voice {voiceInfo.displayName}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self._voice = PiperVoice.load(str(voiceInfo.modelPath)) - self._voiceInfo = voiceInfo - detectedRate = self._getVoiceSampleRate(self._voice, voiceInfo) - if detectedRate and detectedRate != self._voiceInfo.sampleRate: - msg = ( - f'PIPER: Using detected sample rate {detectedRate} ' - f'for {voiceInfo.displayName}' - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._voiceInfo.sampleRate = detectedRate - - if self._audioPlayer: - self._audioPlayer.setSampleRate(voiceInfo.sampleRate) - - def _getVoiceSampleRate(self, voice, voiceInfo): - if voice is None: - return voiceInfo.sampleRate if voiceInfo else None - - for attr in ("sample_rate", "sampleRate"): - value = getattr(voice, attr, None) - if isinstance(value, (int, float)) and value > 0: - return int(value) - - config = getattr(voice, "config", None) - sampleRate = None - if isinstance(config, dict): - audio = config.get("audio") - if isinstance(audio, dict): - sampleRate = audio.get("sample_rate") - elif audio is not None and hasattr(audio, "sample_rate"): - sampleRate = getattr(audio, "sample_rate", None) - if sampleRate is None: - sampleRate = config.get("sample_rate") - else: - if hasattr(config, "audio"): - audio = getattr(config, "audio") - if isinstance(audio, dict): - sampleRate = audio.get("sample_rate") - elif audio is not None and hasattr(audio, "sample_rate"): - sampleRate = getattr(audio, "sample_rate", None) - if sampleRate is None and hasattr(config, "sample_rate"): - sampleRate = getattr(config, "sample_rate", None) - - try: - sampleRate = int(sampleRate) if sampleRate is not None else None - except (TypeError, ValueError): - sampleRate = None - - if sampleRate and sampleRate > 0: - return sampleRate - - return voiceInfo.sampleRate if voiceInfo else None - - def _mapRate(self, acssRate): - """Map ACSS rate (0-100) to Piper length_scale. - - ACSS rate 50 (default) = length_scale 1.0 - Higher ACSS rate = lower length_scale (faster) - Lower ACSS rate = higher length_scale (slower) - - Arguments: - - acssRate: Rate value from 0-100 - """ - rate = acssRate if acssRate is not None else 50 - rate = max(0.0, min(100.0, float(rate))) - if rate <= 50.0: - return 2.0 - (rate / 50.0) - - return 1.0 - ((rate - 50.0) / 50.0) * 0.75 - - def _mapPitch(self, acssPitch): - """Map ACSS pitch (0-9) to pitch adjustment factor. - - Note: Piper's native pitch control is limited. - This maps to a factor that could be used for post-processing. - - Arguments: - - acssPitch: Pitch value from 0-9 - """ - pitch = acssPitch if acssPitch is not None else 5.0 - pitch = max(0, min(9, pitch)) - return pitch - - def _mapVolume(self, acssGain): - """Map ACSS gain (0-9) to volume (0.0-1.0). - - Arguments: - - acssGain: Gain value from 0-9 - """ - gain = acssGain if acssGain is not None else 10 - gain = max(0, min(10, gain)) - return gain / 10.0 - - def _setRate(self, acssRate): - """Set the speech rate. - - Arguments: - - acssRate: ACSS rate value (0-99) - """ - self._rate = acssRate if acssRate is not None else 50 - msg = f'PIPER: Rate set to {self._rate}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _setPitch(self, acssPitch): - """Set the speech pitch. - - Arguments: - - acssPitch: ACSS pitch value (0-9) - """ - self._pitch = acssPitch if acssPitch is not None else 5.0 - msg = f'PIPER: Pitch set to {self._pitch}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _setVolume(self, acssGain): - """Set the speech volume. - - Arguments: - - acssGain: ACSS gain value (0-9) - """ - self._volume = self._mapVolume(acssGain) - if self._audioPlayer: - self._audioPlayer.setVolume(self._volume) - msg = f'PIPER: Volume set to {self._volume}' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _setFamily(self, acssFamily): - """Set the voice family. - - Arguments: - - acssFamily: ACSS family dict with voice info - """ - if not acssFamily: - return - - name = acssFamily.get(speechserver.VoiceFamily.NAME) - if not name: - return - - for voice in self._voiceManager.getVoices(): - if voice.displayName == name: - if voice != self._voiceInfo: - try: - self._loadVoice(voice) - except Exception as e: - msg = f'PIPER: Failed to load voice {name}: {e}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - break - - def _applyAcss(self, acss): - """Apply ACSS voice settings. - - Arguments: - - acss: ACSS settings to apply - """ - if acss is None: - acss = settings.voices[settings.DEFAULT_VOICE] - - with self._lock: - current = self._currentVoiceProperties - for acssProperty, method in self._acssManipulators: - value = acss.get(acssProperty) - if value is not None: - if current.get(acssProperty) != value: - method(value) - current[acssProperty] = value - elif acssProperty == ACSS.AVERAGE_PITCH: - method(5.0) - current[acssProperty] = 5.0 - elif acssProperty == ACSS.GAIN: - method(10) - current[acssProperty] = 10 - elif acssProperty == ACSS.RATE: - method(50) - current[acssProperty] = 50 - - def _synthesize(self, text): - """Synthesize text to audio data. - - Arguments: - - text: Text to synthesize - - Returns raw PCM audio data as bytes. - """ - if not self._voice or not text: - return None - - lengthScale = self._mapRate(self._rate) - - if _PiperSynthesisConfig is not None: - try: - synConfig = _PiperSynthesisConfig(length_scale=lengthScale) - audioChunks = self._voice.synthesize(text, syn_config=synConfig) - audioParts = [] - sampleRate = None - for chunk in audioChunks: - if sampleRate is None: - sampleRate = chunk.sample_rate - audioParts.append(chunk.audio_int16_bytes) - if sampleRate and sampleRate != self._voiceInfo.sampleRate: - self._voiceInfo.sampleRate = sampleRate - if self._audioPlayer: - self._audioPlayer.setSampleRate(sampleRate) - audioData = b"".join(audioParts) - return audioData if audioData else None - except TypeError: - pass - - wavBuffer = io.BytesIO() - with wave.open(wavBuffer, 'wb') as wavFile: - wavFile.setnchannels(1) - wavFile.setsampwidth(2) - wavFile.setframerate(self._voiceInfo.sampleRate) - - self._voice.synthesize( - text, - wavFile, - length_scale=lengthScale - ) - - wavBuffer.seek(44) - return wavBuffer.read() - - def _synthesizeAndPlay(self, text, acss, completionCallback=None, generation=0): - """Synthesize and play text (runs in worker thread). - - Arguments: - - text: Text to synthesize - - acss: ACSS settings - - completionCallback: Optional callback when complete - """ - try: - if self._stopEvent.is_set() or generation != self._speakGeneration: - return - - self._applyAcss(acss) - - audioData = self._synthesize(text) - if not audioData or self._stopEvent.is_set() or generation != self._speakGeneration: - return - - if self._audioPlayer: - self._audioPlayer.play(audioData, False) - while self._audioPlayer.isPlaying(): - if self._stopEvent.is_set() or generation != self._speakGeneration: - self._audioPlayer.stop() - return - time.sleep(0.01) - - if completionCallback and not self._stopEvent.is_set() and generation == self._speakGeneration: - GLib.idle_add(completionCallback) - - except Exception as e: - msg = f'PIPER: Synthesis error: {e}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) - - def getInfo(self): - """Returns [name, id].""" - return [guilabels.PIPER_TTS, self._id] - - def getVoiceFamilies(self): - """Returns a list of VoiceFamily instances.""" - families = [] - for voice in self._voiceManager.getVoices(): - family = self._voiceManager.voiceToVoiceFamily(voice) - families.append(family) - return families - - def speak(self, text=None, acss=None, interrupt=True): - """Speaks the given text. - - Arguments: - - text: Text to speak - - acss: ACSS voice settings - - interrupt: If True, stop any current speech first - """ - if not text or not self._voice: - return - - if interrupt: - self.stop() - - with self._lock: - self._stopEvent.clear() - generation = self._speakGeneration - - msg = f"PIPER: Speaking '{text}'" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self._currentFuture = self._executor.submit( - self._synthesizeAndPlay, text, acss, None, generation - ) - - def sayAll(self, utteranceIterator, progressCallback): - """Iterates through utterances, speaking each one. - - Arguments: - - utteranceIterator: Iterator yielding [SayAllContext, acss] tuples - - progressCallback: Called with progress updates - """ - with self._lock: - self._stopEvent.clear() - self._speakGeneration += 1 - generation = self._speakGeneration - GLib.idle_add(self._sayAllWorker, utteranceIterator, progressCallback, generation) - - def _sayAllWorker(self, iterator, callback, generation): - """Process one utterance at a time (called via GLib.idle_add). - - Arguments: - - iterator: Utterance iterator - - callback: Progress callback - """ - with self._lock: - if self._stopEvent.is_set() or generation != self._speakGeneration: - return False - - try: - context, acss = next(iterator) - except StopIteration: - return False - - def onComplete(): - with self._lock: - if self._stopEvent.is_set() or generation != self._speakGeneration: - return False - context.currentOffset = context.endOffset - callback(context.copy(), speechserver.SayAllContext.COMPLETED) - GLib.idle_add(self._sayAllWorker, iterator, callback, generation) - return False - - context.currentOffset = context.startOffset - callback(context.copy(), speechserver.SayAllContext.PROGRESS) - - self._currentFuture = self._executor.submit( - self._synthesizeAndPlay, context.utterance, acss, onComplete, generation - ) - - return False - - def speakCharacter(self, character, acss=None): - """Speaks a single character immediately. - - Arguments: - - character: Character to speak - - acss: ACSS voice settings - """ - name = chnames.getCharacterName(character) - if name and name != character: - if cthulhu_state.activeScript: - name = cthulhu_state.activeScript.utilities.adjustForPronunciation(name) - self.speak(name, acss) - else: - self.speak(character, acss) - - def speakKeyEvent(self, event, acss=None): - """Speaks a key event immediately. - - Arguments: - - event: The KeyboardEvent to speak - - acss: ACSS voice settings - """ - eventString = event.getKeyName() - lockingStateString = event.getLockingStateString() - eventString = f"{eventString} {lockingStateString}".strip() - self.speak(eventString, acss) - - def _changeDefaultSpeechRate(self, step, decrease=False): - """Change the default speech rate. - - Arguments: - - step: Amount to change - - decrease: If True, decrease rate; otherwise increase - """ - acss = settings.voices[settings.DEFAULT_VOICE] - delta = step * (-1 if decrease else 1) - try: - rate = acss[ACSS.RATE] - except KeyError: - rate = 50 - acss[ACSS.RATE] = max(0, min(100, rate + delta)) - msg = f"PIPER: Rate set to {acss[ACSS.RATE]}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.speak( - messages.SPEECH_SLOWER if decrease else messages.SPEECH_FASTER, - acss=acss - ) - - def _changeDefaultSpeechPitch(self, step, decrease=False): - """Change the default speech pitch. - - Arguments: - - step: Amount to change - - decrease: If True, decrease pitch; otherwise increase - """ - acss = settings.voices[settings.DEFAULT_VOICE] - delta = step * (-1 if decrease else 1) - try: - pitch = acss[ACSS.AVERAGE_PITCH] - except KeyError: - pitch = 5 - acss[ACSS.AVERAGE_PITCH] = max(0, min(9, pitch + delta)) - msg = f"PIPER: Pitch set to {acss[ACSS.AVERAGE_PITCH]}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.speak( - messages.SPEECH_LOWER if decrease else messages.SPEECH_HIGHER, - acss=acss - ) - - def _changeDefaultSpeechVolume(self, step, decrease=False): - """Change the default speech volume. - - Arguments: - - step: Amount to change - - decrease: If True, decrease volume; otherwise increase - """ - acss = settings.voices[settings.DEFAULT_VOICE] - delta = step * (-1 if decrease else 1) - try: - volume = acss[ACSS.GAIN] - except KeyError: - volume = 10 - acss[ACSS.GAIN] = max(0, min(9, volume + delta)) - msg = f"PIPER: Volume set to {acss[ACSS.GAIN]}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.speak( - messages.SPEECH_SOFTER if decrease else messages.SPEECH_LOUDER, - acss=acss - ) - - def increaseSpeechRate(self, step=5): - """Increases the speech rate.""" - self._changeDefaultSpeechRate(step) - - def decreaseSpeechRate(self, step=5): - """Decreases the speech rate.""" - self._changeDefaultSpeechRate(step, decrease=True) - - def increaseSpeechPitch(self, step=0.5): - """Increases the speech pitch.""" - self._changeDefaultSpeechPitch(step) - - def decreaseSpeechPitch(self, step=0.5): - """Decreases the speech pitch.""" - self._changeDefaultSpeechPitch(step, decrease=True) - - def increaseSpeechVolume(self, step=0.5): - """Increases the speech volume.""" - self._changeDefaultSpeechVolume(step) - - def decreaseSpeechVolume(self, step=0.5): - """Decreases the speech volume.""" - self._changeDefaultSpeechVolume(step, decrease=True) - - def updateCapitalizationStyle(self): - """Updates the capitalization style used by the speech server.""" - pass - - def updatePunctuationLevel(self): - """Punctuation level changed, inform this speechServer.""" - pass - - def stop(self): - """Stops ongoing speech and flushes the queue.""" - with self._lock: - self._speakGeneration += 1 - self._stopEvent.set() - - if self._currentFuture: - self._currentFuture.cancel() - self._currentFuture = None - - if self._audioPlayer: - self._audioPlayer.stop() - - def shutdown(self): - """Shuts down the speech engine.""" - self.stop() - - if self._executor: - self._executor.shutdown(wait=False) - self._executor = None - - if self._audioPlayer: - self._audioPlayer.shutdown() - self._audioPlayer = None - - self._voice = None - self._voiceInfo = None - - if self._id in SpeechServer._active_servers: - del SpeechServer._active_servers[self._id] - - msg = 'PIPER: Server shutdown complete' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def reset(self, text=None, acss=None): - """Resets the speech engine.""" - self.stop() - if self._voiceInfo: - try: - self._loadVoice(self._voiceInfo) - except Exception as e: - msg = f'PIPER: Failed to reset voice: {e}' - debug.printMessage(debug.LEVEL_WARNING, msg, True) diff --git a/src/cthulhu/plugin.py b/src/cthulhu/plugin.py deleted file mode 100644 index a9e0eca..0000000 --- a/src/cthulhu/plugin.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Base class for Cthulhu plugins using pluggy.""" - -import os -import logging - -import pluggy - -# Import pluggy for hook specifications -cthulhu_hookimpl = pluggy.HookimplMarker("cthulhu") - - -logger = logging.getLogger(__name__) - -class Plugin: - """Base class for Cthulhu plugins.""" - - def __init__(self): - """Initialize the plugin with default attributes.""" - self.app = None - self.plugin_info = None - self.module_name = '' - self.name = '' - self.version = '' - self.description = '' - self._bindings = None - self._gestureBindings = {} - - def set_app(self, app): - """Set the application reference.""" - self.app = app - - def set_plugin_info(self, plugin_info): - """Set plugin information and extract relevant attributes.""" - self.plugin_info = plugin_info - if plugin_info: - self.module_name = getattr(plugin_info, 'module_name', '') - self.name = plugin_info.get_name() - self.version = plugin_info.get_version() - self.description = plugin_info.get_description() - - def get_dbus_module_name(self): - """Return the D-Bus module name for this plugin, or an empty string to opt out.""" - if not self.module_name: - return '' - return f"Plugin_{self.module_name}" - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the plugin. Override this in subclasses.""" - if plugin is not None and plugin is not self: - return - logger.info(f"Activating plugin: {self.name}") - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the plugin. Override this in subclasses.""" - if plugin is not None and plugin is not self: - return - logger.info(f"Deactivating plugin: {self.name}") - - def get_bindings(self): - """Get keybindings for this plugin. Override in subclasses.""" - return self._bindings - - def getPreferencesGUI(self): - """Return a Gtk widget for plugin preferences, or None if not provided.""" - return None - - def getPreferencesFromGUI(self): - """Return a dict of plugin preferences from the GUI.""" - return {} - - def registerGestureByString(self, function, name, gestureString, learnModeEnabled=True, globalBinding=True): - """Register a gesture by string.""" - if self.app: - api_helper = self.app.getAPIHelper() - if api_helper: - binding = api_helper.registerGestureByString( - function, - name, - gestureString, - 'default', - 'cthulhu', - learnModeEnabled, - globalBinding=globalBinding, - contextName=self.module_name - ) - - # Also store the binding locally so get_bindings() can use it - if binding: - if not self._bindings: - from . import keybindings - self._bindings = keybindings.KeyBindings() - self._bindings.add(binding) - - return binding - return None diff --git a/src/cthulhu/plugin_system_manager.py b/src/cthulhu/plugin_system_manager.py deleted file mode 100644 index 55d5488..0000000 --- a/src/cthulhu/plugin_system_manager.py +++ /dev/null @@ -1,1126 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Plugin System Manager for Cthulhu using pluggy.""" - -import configparser -import hashlib -import importlib.util -import inspect -import logging -import os -import re -import shutil -import subprocess -from enum import IntEnum -from typing import Optional, Dict, List, Any - -import pluggy -from . import dbus_service -from . import input_event_manager -from . import keybindings # Added import - -# Set to True for more detailed plugin loading debug info -PLUGIN_DEBUG: bool = True - -logger: logging.Logger = logging.getLogger(__name__) -if PLUGIN_DEBUG: - logger.setLevel(logging.DEBUG) - -LEGACY_PLUGIN_NAME_ALIASES: Dict[str, str] = { - "ocrdesktop": "OCR", -} - -OBSOLETE_PLUGIN_NAMES = { - "pluginmanager", -} - -LEGACY_PLUGIN_DIR_ALIASES: Dict[str, str] = { - "OCRDesktop": "OCR", -} - -_manager: Optional['PluginSystemManager'] = None - -def getManager() -> Optional['PluginSystemManager']: - """Return the shared PluginSystemManager instance.""" - return _manager - -class PluginType(IntEnum): - """Types of plugins we support.""" - SYSTEM = 1 - USER = 2 - - def get_root_dir(self) -> str: - """Returns the directory where this type of plugins can be found.""" - if self.value == PluginType.SYSTEM: - current_file = inspect.getfile(inspect.currentframe()) - current_dir = os.path.dirname(os.path.realpath(os.path.abspath(current_file))) - return os.path.join(current_dir, 'plugins') - elif self.value == PluginType.USER: - return os.path.expanduser('~/.local/share/cthulhu/plugins') - - -class PluginInfo: - """Information about a plugin.""" - - def __init__( - self, - name: str, - module_name: str, - module_dir: str, - metadata: Optional[Dict[str, Any]] = None, - canonical_name: Optional[str] = None, - source_id: Optional[str] = None, - origin: Optional[str] = None - ) -> None: - self.name: str = name - self.module_name: str = module_name - self.module_dir: str = module_dir - self.metadata: Dict[str, Any] = metadata or {} - self.canonical_name: str = canonical_name or module_name - self.source_id: str = source_id or "unknown" - self.origin: str = origin or "unknown" - self.preferred_alias: bool = False - self.builtin: bool = False - self.hidden: bool = False - self.module: Optional[Any] = None - self.instance: Optional[Any] = None - self.loaded: bool = False - - def get_module_name(self) -> str: - return self.module_name - - def get_canonical_name(self) -> str: - return self.canonical_name - - def get_name(self) -> str: - return self.metadata.get('name', self.name) - - def get_version(self) -> str: - return self.metadata.get('version', '0.0.0') - - def get_description(self) -> str: - return self.metadata.get('description', '') - - def get_source_id(self) -> str: - return self.source_id - - def get_origin(self) -> str: - return self.origin - - def get_source_label(self) -> str: - if self.origin == "sources": - return self.source_id - return self.origin - - def get_module_dir(self) -> str: - return self.module_dir - - -class PluginSystemManager: - """Cthulhu Plugin Manager using pluggy.""" - - def __init__(self, app: Any) -> None: # app is CthulhuApp instance - global _manager - self.app: Any = app - logger.info("Initializing PluginSystemManager") - _manager = self - - # Initialize plugin manager - logger.info("Setting up plugin manager") - self.plugin_manager: pluggy.PluginManager = pluggy.PluginManager("cthulhu") - - # Define hook specifications - hook_spec = pluggy.HookspecMarker("cthulhu") - - class CthulhuHookSpecs: - @hook_spec - def activate(self, plugin: Optional[Any] = None) -> None: - """Called when the plugin is activated.""" - pass - - @hook_spec - def deactivate(self, plugin: Optional[Any] = None) -> None: - """Called when the plugin is deactivated.""" - pass - - logger.info("Adding hook specifications to plugin manager") - self.plugin_manager.add_hookspecs(CthulhuHookSpecs) - - # Plugin storage - self._plugins: Dict[str, PluginInfo] = {} # module_name -> PluginInfo - self._plugin_name_index: Dict[str, List[str]] = {} # canonical_name -> [module_name] - self._active_plugins: List[str] = [] - self._plugin_keybindings: Dict[str, List[Any]] = {} # plugin_name -> [KeyBinding] - self._global_keybindings: keybindings.KeyBindings = keybindings.KeyBindings() - self._global_bindings: List[Any] = [] # List[KeyBinding] - self._last_active_script: Optional[Any] = None # Optional[Script] - - # Create plugin directories - self._setup_plugin_dirs() - - # Log available plugins directory paths - logger.info(f"System plugins directory: {PluginType.SYSTEM.get_root_dir()}") - logger.info(f"User plugins directory: {PluginType.USER.get_root_dir()}") - - # Connect to active-script-changed signal - self.app.getSignalManager().connectSignal( - 'active-script-changed', self._on_active_script_changed, 'default') - - def add_keybinding(self, plugin_name: str, binding: Any, global_binding: bool = False) -> None: # binding: KeyBinding - """Add a keybinding associated with a specific plugin.""" - if plugin_name not in self._plugin_keybindings: - self._plugin_keybindings[plugin_name] = [] - self._plugin_keybindings[plugin_name].append(binding) - logger.debug(f"Added keybinding '{binding.asString()}' for plugin '{plugin_name}'") - if global_binding: - if binding not in self._global_bindings: - self._global_bindings.append(binding) - self._global_keybindings.add(binding) - grab_ids = input_event_manager.get_manager().add_grabs_for_keybinding(binding) - if grab_ids: - binding._global_grab_ids = grab_ids - else: - logger.warning(f"Failed to create global key grab for {binding.keysymstring}") - - def activate_keybindings_for_plugin(self, plugin_name: str) -> None: - """Activates keybindings for a single plugin with the active script.""" - plugin_info = self._plugins.get(plugin_name) - if not plugin_info or not plugin_info.loaded: - return - self._activate_plugin_keybindings(plugin_info) - - def remove_keybinding(self, plugin_name: str, binding: Any) -> None: # binding: KeyBinding - """Remove a keybinding associated with a specific plugin.""" - if plugin_name in self._plugin_keybindings: - if binding in self._plugin_keybindings[plugin_name]: - self._plugin_keybindings[plugin_name].remove(binding) - - if binding in self._global_bindings: - if hasattr(binding, '_global_grab_ids'): - for grab_id in binding._global_grab_ids: - input_event_manager.get_manager().remove_grab_by_id(grab_id) - del binding._global_grab_ids - if binding in self._global_bindings: - self._global_bindings.remove(binding) - self._global_keybindings.remove(binding) - return - - from . import cthulhu_state - if cthulhu_state.activeScript: - active_script = cthulhu_state.activeScript - if active_script.getKeyBindings().hasKeyBinding(binding, "keysNoMask"): - active_script.getKeyBindings().remove(binding) - input_event_manager.get_manager().remove_grabs_for_keybinding(binding) - - def _activate_plugin_keybindings(self, plugin_info: PluginInfo) -> None: - """Activates all keybindings for a given plugin with the active script.""" - from . import cthulhu_state # Import here to avoid circular dependency - if not cthulhu_state.activeScript: - logger.warning(f"No active script to activate keybindings for plugin: {plugin_info.get_module_name()}") - return - - plugin_name = plugin_info.get_module_name() - if plugin_name in self._plugin_keybindings: - active_script = cthulhu_state.activeScript - input_manager = input_event_manager.get_manager() - for binding in self._plugin_keybindings[plugin_name]: - if binding in self._global_bindings: - continue - if not active_script.getKeyBindings().hasKeyBinding(binding, "keysNoMask"): - active_script.getKeyBindings().add(binding) - grab_ids = input_event_manager.get_manager().add_grabs_for_keybinding(binding) - if grab_ids: - binding._grab_ids = grab_ids - else: - logger.warning(f"Failed to create key grab for {binding.keysymstring} for plugin {plugin_name}") - logger.debug(f"Activated keybinding '{binding.asString()}' for plugin '{plugin_name}'") - - def _deactivate_plugin_keybindings(self, plugin_info: PluginInfo) -> None: - """Deactivates all keybindings for a given plugin from the active script.""" - from . import cthulhu_state # Import here to avoid circular dependency - if not cthulhu_state.activeScript: - logger.warning(f"No active script to deactivate keybindings for plugin: {plugin_info.get_module_name()}") - return - - plugin_name = plugin_info.get_module_name() - if plugin_name in self._plugin_keybindings: - active_script = cthulhu_state.activeScript - for binding in self._plugin_keybindings[plugin_name]: - if binding in self._global_bindings: - if hasattr(binding, '_global_grab_ids'): - for grab_id in binding._global_grab_ids: - self.app.removeKeyGrab(grab_id) - del binding._global_grab_ids - if binding in self._global_bindings: - self._global_bindings.remove(binding) - self._global_keybindings.remove(binding) - continue - if active_script.getKeyBindings().hasKeyBinding(binding, "keysNoMask"): - active_script.getKeyBindings().remove(binding) - input_manager.remove_grabs_for_keybinding(binding) - logger.debug(f"Deactivated keybinding '{binding.asString()}' for plugin '{plugin_name}'") - - def refresh_active_script_keybindings(self) -> None: - """Public method to refresh keybindings for the currently active script.""" - from . import cthulhu_state - if cthulhu_state.activeScript: - self._on_active_script_changed(self.app, cthulhu_state.activeScript) - - def get_global_keybindings(self) -> keybindings.KeyBindings: - return self._global_keybindings - - def _on_active_script_changed(self, app: Any, new_script: Optional[Any]) -> None: - """Called when the active script changes. Re-applies keybindings for all active plugins.""" - logger.info(f"Active script changed to {new_script.name if new_script else 'None'}. Re-applying plugin keybindings.") - - # First, remove all existing plugin keybindings from the old script - # This requires iterating through all plugins, not just active ones, to ensure cleanup - old_script = self._last_active_script - if old_script: - input_manager = input_event_manager.get_manager() - for plugin_name, bindings in self._plugin_keybindings.items(): - for binding in bindings: - if binding in self._global_bindings: - continue - if old_script.getKeyBindings().hasKeyBinding(binding, "keysNoMask"): - old_script.getKeyBindings().remove(binding) - input_manager.remove_grabs_for_keybinding(binding) - logger.debug(f"Removed keybinding '{binding.asString()}' from old script for plugin '{plugin_name}'") - - # Now, if there's a new active script, apply keybindings for currently active plugins - self._last_active_script = new_script - if new_script: - for plugin_name in self._active_plugins: - plugin_info = self._plugins.get(plugin_name) - if plugin_info and plugin_info.loaded: - self._activate_plugin_keybindings(plugin_info) - - def _setup_plugin_dirs(self) -> None: - """Ensure plugin directories exist.""" - os.makedirs(PluginType.SYSTEM.get_root_dir(), exist_ok=True) - os.makedirs(PluginType.USER.get_root_dir(), exist_ok=True) - os.makedirs(self._get_plugin_sources_root(), exist_ok=True) - - def _get_plugin_sources_root(self) -> str: - return os.path.expanduser('~/.local/share/cthulhu/plugin-sources') - - def _get_additional_plugin_dirs(self) -> List[str]: - return [os.path.expanduser('~/.local/share/plugins')] - - def _path_under_root(self, path: str, root: str) -> bool: - try: - return os.path.commonpath([os.path.abspath(path), os.path.abspath(root)]) == os.path.abspath(root) - except ValueError: - return False - - def _sanitize_source_id(self, source_id: str) -> str: - return re.sub(r'[^a-zA-Z0-9._-]+', '-', source_id).strip('-') or "source" - - def _get_origin_info(self, plugin_dir: str) -> tuple[str, str]: - system_root = PluginType.SYSTEM.get_root_dir() - user_root = PluginType.USER.get_root_dir() - local_root = os.path.expanduser('~/.local/share/plugins') - sources_root = self._get_plugin_sources_root() - - if self._path_under_root(plugin_dir, system_root): - return ("system", "system") - if self._path_under_root(plugin_dir, user_root): - return ("user", "user") - if self._path_under_root(plugin_dir, local_root): - return ("local", "local") - if self._path_under_root(plugin_dir, sources_root): - rel_path = os.path.relpath(plugin_dir, sources_root) - source_id = rel_path.split(os.sep, 1)[0] - return ("sources", self._sanitize_source_id(source_id)) - - return ("unknown", "unknown") - - def _make_unique_plugin_id(self, canonical_name, source_id): - base_id = canonical_name - if canonical_name in self._plugin_name_index: - base_id = f"{canonical_name}@{self._sanitize_source_id(source_id)}" - - unique_id = base_id - suffix = 2 - while unique_id in self._plugins: - unique_id = f"{base_id}-{suffix}" - suffix += 1 - return unique_id - - @property - def plugins(self): - """Get all available plugins.""" - return list(self._plugins.values()) - - def getApp(self): - return self.app - - def rescanPlugins(self): - """Scan for plugins in the plugin directories.""" - old_plugins = self._plugins.copy() - self._plugins = {} - self._plugin_name_index = {} - - # Scan system and user plugins - self._scan_plugins_in_directory(PluginType.SYSTEM.get_root_dir()) - self._scan_plugins_in_directory(PluginType.USER.get_root_dir(), max_depth=1) - for plugin_dir in self._get_additional_plugin_dirs(): - if os.path.isdir(plugin_dir): - self._scan_plugins_in_directory(plugin_dir, max_depth=1) - self._scan_plugins_in_directory(self._get_plugin_sources_root(), max_depth=1) - - # Preserve state for already loaded plugins - for name, old_info in old_plugins.items(): - if name in self._plugins and old_info.loaded: - self._plugins[name].loaded = True - self._plugins[name].instance = old_info.instance - self._plugins[name].module = old_info.module - - def _scan_plugins_in_directory(self, directory, max_depth=0, _depth=0): - """Scan for plugins in a directory.""" - if not os.path.exists(directory) or not os.path.isdir(directory): - if _depth == 0: - logger.warning(f"Plugin directory not found or not a directory: {directory}") - return - - if _depth == 0: - logger.info(f"Scanning for plugins in directory: {directory}") - - for item in sorted(os.listdir(directory)): - if item.startswith('.'): - continue - plugin_dir = os.path.join(directory, item) - if not os.path.isdir(plugin_dir): - continue - - if self._register_plugin_from_directory(plugin_dir): - continue - - if _depth < max_depth: - self._scan_plugins_in_directory(plugin_dir, max_depth=max_depth, _depth=_depth + 1) - elif max_depth == 0: - logger.warning(f"No plugin file found in directory: {plugin_dir}") - - def _register_plugin_from_directory(self, plugin_dir): - item = os.path.basename(plugin_dir) - plugin_file = os.path.join(plugin_dir, "plugin.py") - metadata_file = os.path.join(plugin_dir, "plugin.info") - - if not os.path.isfile(plugin_file): - alternative_plugin_file = os.path.join(plugin_dir, f"{item}.py") - if os.path.isfile(alternative_plugin_file): - plugin_file = alternative_plugin_file - logger.info(f"Using alternative plugin file: {alternative_plugin_file}") - - if not os.path.isfile(plugin_file): - return False - - canonical_name = os.path.basename(plugin_dir) - canonical_override = LEGACY_PLUGIN_DIR_ALIASES.get(canonical_name) - if canonical_override: - if canonical_override in self._plugin_name_index: - logger.info( - f"Skipping deprecated plugin directory {canonical_name} because " - f"{canonical_override} is already registered." - ) - return True - logger.info( - f"Registering deprecated plugin directory {canonical_name} as {canonical_override}." - ) - canonical_name = canonical_override - origin, source_id = self._get_origin_info(plugin_dir) - module_name = self._make_unique_plugin_id(canonical_name, source_id) - if canonical_name != module_name: - logger.warning( - "Duplicate plugin name detected: " - f"{canonical_name} (origin={origin}, source={source_id}). " - f"Registering as {module_name}." - ) - logger.info(f"Found plugin: {canonical_name} in {plugin_dir}") - metadata = self._load_plugin_metadata(metadata_file) - - plugin_info = PluginInfo( - metadata.get('name', canonical_name), - module_name, - plugin_dir, - metadata, - canonical_name=canonical_name, - source_id=source_id, - origin=origin, - ) - - plugin_info.builtin = metadata.get('builtin', 'false').lower() == 'true' - plugin_info.hidden = metadata.get('hidden', 'false').lower() == 'true' - - if canonical_name not in self._plugin_name_index: - plugin_info.preferred_alias = True - self._plugin_name_index[canonical_name] = [] - self._plugin_name_index[canonical_name].append(module_name) - - logger.info(f"Adding plugin to registry: {module_name}") - self._plugins[module_name] = plugin_info - return True - - def _plugin_source_dir(self, source_url): - base_name = source_url.rstrip('/').split('/')[-1] or 'plugin-source' - if base_name.endswith('.git'): - base_name = base_name[:-4] - base_name = re.sub(r'[^a-zA-Z0-9._-]+', '-', base_name).strip('-') or 'plugin-source' - digest = hashlib.sha1(source_url.encode('utf-8')).hexdigest()[:8] - return os.path.join(self._get_plugin_sources_root(), f"{base_name}-{digest}") - - def syncPluginSources(self, sources, progress_callback=None): - """Clone or update plugin source repositories.""" - if not sources: - return - - git_path = shutil.which("git") - if not git_path: - logger.error("Git not available; cannot sync plugin sources.") - return - - os.makedirs(self._get_plugin_sources_root(), exist_ok=True) - total = len(sources) - for index, source in enumerate(sources, start=1): - source = source.strip() - if not source: - continue - dest_dir = self._plugin_source_dir(source) - if os.path.isdir(dest_dir): - try: - subprocess.run( - [git_path, "-C", dest_dir, "pull", "--ff-only"], - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - logger.info(f"Updated plugin source: {source}") - if progress_callback: - progress_callback(index, total, f"Updated {source}") - except subprocess.CalledProcessError as exc: - logger.error(f"Failed to update plugin source {source}: {exc.stderr.decode('utf-8', 'ignore')}") - if progress_callback: - progress_callback(index, total, f"Failed to update {source}") - else: - try: - subprocess.run( - [git_path, "clone", source, dest_dir], - check=True, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - logger.info(f"Installed plugin source: {source}") - if progress_callback: - progress_callback(index, total, f"Installed {source}") - except subprocess.CalledProcessError as exc: - logger.error(f"Failed to clone plugin source {source}: {exc.stderr.decode('utf-8', 'ignore')}") - if progress_callback: - progress_callback(index, total, f"Failed to clone {source}") - - def removePluginSources(self, sources): - """Remove plugin source repositories.""" - if not sources: - return - - sources_root = self._get_plugin_sources_root() - for source in sources: - source = source.strip() - if not source: - continue - dest_dir = self._plugin_source_dir(source) - if not os.path.isdir(dest_dir): - continue - if os.path.commonpath([dest_dir, sources_root]) != sources_root: - logger.warning(f"Skipping removal outside plugin sources root: {dest_dir}") - continue - try: - shutil.rmtree(dest_dir) - logger.info(f"Removed plugin source: {source}") - except Exception as exc: - logger.error(f"Failed to remove plugin source {source}: {exc}") - - def _load_plugin_metadata(self, metadata_file): - """Load plugin metadata from a file.""" - metadata = {} - - if os.path.isfile(metadata_file): - try: - with open(metadata_file, 'r', encoding='utf-8') as f: - contents = f.read() - - has_section_header = False - for line in contents.splitlines(): - stripped = line.strip() - if not stripped or stripped.startswith('#') or stripped.startswith(';'): - continue - if stripped.startswith('[') and stripped.endswith(']'): - has_section_header = True - break - - if has_section_header: - parser = configparser.ConfigParser() - try: - parser.read_string(contents) - if parser.sections(): - for section in parser.sections(): - for key, value in parser[section].items(): - metadata[key.strip().lower()] = value.strip() - return metadata - except configparser.Error as e: - logger.warning(f"Plugin metadata INI parse failed for {metadata_file}: {e}") - - for line in contents.splitlines(): - line = line.strip() - if not line or line.startswith('#') or line.startswith(';') or line.startswith('['): - continue - - if '=' in line: - key, value = line.split('=', 1) - metadata[key.strip().lower()] = value.strip() - except Exception as e: - logger.error(f"Error loading plugin metadata: {e}") - - return metadata - - def getActivePlugins(self): - """Get the list of active plugin names.""" - return self._active_plugins - - def get_active_plugins(self): - """Get the list of active plugin instances.""" - active_instances = [] - for plugin_name in self._active_plugins: - if plugin_name in self._plugins: - plugin_info = self._plugins[plugin_name] - if plugin_info.loaded and plugin_info.instance: - active_instances.append(plugin_info.instance) - return active_instances - - def _resolve_plugin_info(self, plugin_name): - if not plugin_name: - return None - - if not self._plugins: - self.rescanPlugins() - - plugin_name_lower = plugin_name.lower() - candidates = [] - - for info in self.plugins: - module_name = info.get_module_name() - canonical_name = info.get_canonical_name() - if plugin_name == module_name: - return info - if plugin_name_lower == module_name.lower(): - candidates.append(info) - elif plugin_name_lower == canonical_name.lower(): - candidates.append(info) - - if not candidates: - return None - - for info in candidates: - if info.builtin: - return info - for info in candidates: - if info.preferred_alias: - return info - return candidates[0] - - def _get_plugin_dbus_module_name(self, plugin_info, plugin_instance): - if not plugin_info or not plugin_instance: - return '' - if hasattr(plugin_instance, "get_dbus_module_name"): - module_name = plugin_instance.get_dbus_module_name() - else: - module_name = f"Plugin_{plugin_info.get_module_name()}" - return module_name or '' - - def _register_plugin_dbus_module(self, plugin_info): - if not plugin_info or not plugin_info.instance: - return - - module_name = self._get_plugin_dbus_module_name(plugin_info, plugin_info.instance) - if not module_name: - return - - try: - controller = dbus_service.get_remote_controller() - controller.register_decorated_module(module_name, plugin_info.instance) - logger.info(f"Registered D-Bus module for plugin {plugin_info.get_module_name()}: {module_name}") - except Exception as error: - logger.error(f"Failed to register D-Bus module for plugin {plugin_info.get_module_name()}: {error}") - - def _deregister_plugin_dbus_module(self, plugin_info): - if not plugin_info or not plugin_info.instance: - return - - module_name = self._get_plugin_dbus_module_name(plugin_info, plugin_info.instance) - if not module_name: - return - - try: - controller = dbus_service.get_remote_controller() - controller.deregister_module_commands(module_name) - logger.info(f"Deregistered D-Bus module for plugin {plugin_info.get_module_name()}: {module_name}") - except Exception as error: - logger.error(f"Failed to deregister D-Bus module for plugin {plugin_info.get_module_name()}: {error}") - - @dbus_service.command - def list_plugins(self) -> list[str]: - """Returns a list of available plugin module names.""" - if not self._plugins: - self.rescanPlugins() - return [info.get_module_name() for info in self.plugins] - - @dbus_service.command - def list_active_plugins(self) -> list[str]: - """Returns a list of currently active plugin module names.""" - return [info.get_module_name() for info in self.plugins if info.loaded] - - @dbus_service.parameterized_command - def is_plugin_active(self, plugin_name: str) -> bool: - """Returns True if the specified plugin is active.""" - plugin_info = self._resolve_plugin_info(plugin_name) - if not plugin_info: - return False - return self.isPluginActive(plugin_info) - - @dbus_service.parameterized_command - def set_plugin_active(self, plugin_name: str, active: bool) -> bool: - """Enable or disable a plugin for this session only.""" - plugin_info = self._resolve_plugin_info(plugin_name) - if not plugin_info: - return False - - if plugin_info.builtin and not active: - logger.warning(f"Plugin {plugin_info.get_module_name()} is builtin and cannot be disabled") - return False - - self.setPluginActive(plugin_info, active) - if active: - return plugin_info.loaded - return not plugin_info.loaded - - @dbus_service.command - def rescan_plugins(self): - """Rescans plugin directories and refreshes the plugin list.""" - self.rescanPlugins() - return True - - def setActivePlugins(self, activePlugins): - """Set active plugins and sync their state.""" - logger.info(f"PLUGIN SYSTEM: setActivePlugins called with: {activePlugins}") - logger.info(f"Setting active plugins: {activePlugins}") - - original_active = list(activePlugins or []) - normalized_requested = [] - for name in original_active: - if not name: - continue - name_lower = name.lower() - if name_lower in OBSOLETE_PLUGIN_NAMES: - logger.info(f"Dropping obsolete plugin name {name}") - continue - alias = LEGACY_PLUGIN_NAME_ALIASES.get(name_lower) - if alias: - logger.info(f"Mapping legacy plugin name {name} to {alias}") - name = alias - normalized_requested.append(name) - activePlugins = normalized_requested - if activePlugins != original_active: - try: - from . import settings as settings_module - settings_module.activePlugins = list(activePlugins) - except Exception: - logger.debug("Unable to normalize settings.activePlugins for legacy plugin aliases.") - - # Make sure we have scanned for plugins first - if not self._plugins: - logger.info("No plugins found, rescanning...") - self.rescanPlugins() - - plugin_by_id = {info.get_module_name(): info for info in self.plugins} - plugin_by_id_lower = {name.lower(): info for name, info in plugin_by_id.items()} - preferred_by_canonical = { - info.get_canonical_name().lower(): info.get_module_name() - for info in self.plugins if info.preferred_alias - } - canonical_with_builtin = { - info.get_canonical_name().lower() - for info in self.plugins if info.builtin - } - - normalized_active = [] - seen_canonicals = set() - unknown_active = [] - - for name in activePlugins: - if not name: - continue - name_lower = name.lower() - plugin_info = plugin_by_id.get(name) or plugin_by_id_lower.get(name_lower) - if plugin_info: - canonical_lower = plugin_info.get_canonical_name().lower() - if canonical_lower in canonical_with_builtin and not plugin_info.builtin: - logger.warning( - f"Skipping plugin {plugin_info.get_module_name()} because builtin plugin " - f"uses name {plugin_info.get_canonical_name()}" - ) - continue - if canonical_lower in seen_canonicals: - logger.warning( - f"Skipping plugin {plugin_info.get_module_name()} because another plugin " - f"with name {plugin_info.get_canonical_name()} is already active" - ) - continue - normalized_active.append(plugin_info.get_module_name()) - seen_canonicals.add(canonical_lower) - continue - - preferred_id = preferred_by_canonical.get(name_lower) - if preferred_id: - preferred_info = plugin_by_id.get(preferred_id) - canonical_lower = name_lower - if preferred_info and canonical_lower in canonical_with_builtin and not preferred_info.builtin: - logger.warning( - f"Skipping plugin {preferred_id} because builtin plugin uses name {preferred_info.get_canonical_name()}" - ) - continue - if canonical_lower in seen_canonicals: - logger.warning( - f"Skipping plugin {preferred_id} because another plugin with name {name} is already active" - ) - continue - normalized_active.append(preferred_id) - seen_canonicals.add(canonical_lower) - continue - - unknown_active.append(name) - - self._active_plugins = normalized_active + unknown_active - - # Log active vs available plugins - available_plugins = [p.get_module_name() for p in self.plugins] - available_aliases = [p.get_canonical_name() for p in self.plugins if p.preferred_alias] - available_plugins_lower = {p.lower() for p in available_plugins} - available_aliases_lower = {p.lower() for p in available_aliases} - logger.info(f"Available plugins: {available_plugins}") - logger.info(f"Active plugins: {self._active_plugins}") - - # Check specifically for DisplayVersion - if 'DisplayVersion' in self._active_plugins: - logger.info("DisplayVersion is in active plugins list!") - else: - logger.warning("DisplayVersion is NOT in active plugins list!") - - # Find missing plugins - missing_plugins = [ - p for p in self._active_plugins - if p not in available_plugins - and p not in available_aliases - and p.lower() not in available_plugins_lower - and p.lower() not in available_aliases_lower - ] - if missing_plugins: - logger.warning(f"Active plugins not found: {missing_plugins}") - - self.syncAllPluginsActive() - logger.info("=== PluginSystemManager.setActivePlugins completed ===") - - def setPluginActive(self, pluginInfo, active): - """Set the active state of a plugin.""" - if pluginInfo.builtin: - active = True - - pluginName = pluginInfo.get_module_name() - - if active: - if pluginName not in self.getActivePlugins(): - if self.loadPlugin(pluginInfo): - self._active_plugins.append(pluginName) - else: - if pluginName in self.getActivePlugins(): - if self.unloadPlugin(pluginInfo): - self._active_plugins.remove(pluginName) - - def isPluginActive(self, pluginInfo): - """Check if a plugin is active.""" - module_name = pluginInfo.get_module_name() - canonical_name = pluginInfo.get_canonical_name() - - # Builtin plugins are always active - if pluginInfo.builtin: - logger.debug(f"Plugin {module_name} is builtin, active by default") - return True - - # If a plugin is already loaded, it's active - if pluginInfo.loaded: - logger.debug(f"Plugin {module_name} is already loaded, considered active") - return True - - # Check case-insensitive match in active plugins list - active_plugins = self.getActivePlugins() - - # Try exact match first - if module_name in active_plugins: - logger.debug(f"Plugin {module_name} found in active plugins list") - return True - - if pluginInfo.preferred_alias and canonical_name in active_plugins: - logger.debug(f"Plugin {module_name} matched canonical name {canonical_name}") - return True - - # Try case-insensitive match - module_name_lower = module_name.lower() - canonical_lower = canonical_name.lower() - is_active = any(plugin.lower() == module_name_lower for plugin in active_plugins) - if not is_active and pluginInfo.preferred_alias: - is_active = any(plugin.lower() == canonical_lower for plugin in active_plugins) - - if is_active: - logger.debug(f"Plugin {module_name} found in active plugins list (case-insensitive match)") - else: - logger.debug(f"Plugin {module_name} not found in active plugins list") - - return is_active - - def syncAllPluginsActive(self): - """Sync the active state of all plugins.""" - logger.info("Syncing active state of all plugins") - - # Log plugin status before syncing - if PLUGIN_DEBUG: - for pluginInfo in self.plugins: - is_active = self.isPluginActive(pluginInfo) - is_loaded = pluginInfo.loaded - logger.debug(f"Plugin {pluginInfo.get_module_name()}: active={is_active}, loaded={is_loaded}") - - # First unload inactive plugins - for pluginInfo in self.plugins: - if not self.isPluginActive(pluginInfo) and pluginInfo.loaded: - logger.info(f"Unloading inactive plugin: {pluginInfo.get_module_name()}") - self.unloadPlugin(pluginInfo) - - # Then load active plugins - for pluginInfo in self.plugins: - if self.isPluginActive(pluginInfo) and not pluginInfo.loaded: - logger.info(f"Loading active plugin: {pluginInfo.get_module_name()}") - result = self.loadPlugin(pluginInfo) - logger.info(f"Plugin {pluginInfo.get_module_name()} load result: {result}") - - # Log final plugin status - active_plugins = [p.get_module_name() for p in self.plugins if p.loaded] - logger.info(f"Active plugins after sync: {active_plugins}") - inactive_plugins = [p.get_module_name() for p in self.plugins if not p.loaded] - logger.info(f"Inactive plugins after sync: {inactive_plugins}") - - @staticmethod - def _lifecycle_accepts_plugin_instance(method: Any) -> bool: - """Return True if the bound lifecycle method expects a plugin argument.""" - - try: - parameters = list(inspect.signature(method).parameters.values()) - except (TypeError, ValueError): - return True - - if any(parameter.kind == inspect.Parameter.VAR_POSITIONAL for parameter in parameters): - return True - - positional_parameters = [ - parameter for parameter in parameters - if parameter.kind in ( - inspect.Parameter.POSITIONAL_ONLY, - inspect.Parameter.POSITIONAL_OR_KEYWORD, - ) - ] - return bool(positional_parameters) - - def _callPluginLifecycle(self, pluginInstance: Any, methodName: str) -> None: - """Call a plugin lifecycle method without replaying it through pluggy.""" - - method = getattr(pluginInstance, methodName) - if self._lifecycle_accepts_plugin_instance(method): - method(pluginInstance) - return - - method() - - def loadPlugin(self, pluginInfo): - """Load a plugin.""" - module_name = pluginInfo.get_module_name() - logger.info(f"=== PluginSystemManager.loadPlugin starting for: {module_name} ===") - - try: - # Already loaded? - if pluginInfo.loaded: - logger.info(f"Plugin {module_name} already loaded, skipping") - return True - - # Try to find the plugin file - module_name = pluginInfo.get_module_name() - plugin_dir = pluginInfo.get_module_dir() - - # Check for plugin.py first (standard format) - plugin_file = os.path.join(plugin_dir, "plugin.py") - - # Fall back to [PluginName].py if plugin.py doesn't exist - if not os.path.exists(plugin_file): - canonical_name = pluginInfo.get_canonical_name() - alternative_plugin_file = os.path.join(plugin_dir, f"{canonical_name}.py") - if os.path.exists(alternative_plugin_file): - plugin_file = alternative_plugin_file - logger.info(f"Using alternative plugin file: {alternative_plugin_file}") - - if not os.path.exists(plugin_file): - logger.error(f"Plugin file not found: {plugin_file}") - return False - - logger.info(f"Loading plugin from: {plugin_file}") - spec = importlib.util.spec_from_file_location(module_name, plugin_file) - if spec is None: - logger.error(f"Failed to create spec for plugin: {module_name}") - return False - - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - pluginInfo.module = module - - # Find Plugin class - plugin_class = None - for attr_name in dir(module): - attr = getattr(module, attr_name) - if (inspect.isclass(attr) and - attr.__module__ == module.__name__ and - hasattr(attr, 'activate')): - plugin_class = attr - logger.info(f"Found plugin class: {attr.__name__} in {module_name}") - break - - if not plugin_class: - logger.error(f"No plugin class found in {module_name}") - return False - - # Create and initialize plugin instance - logger.info(f"Creating instance of plugin class: {plugin_class.__name__}") - plugin_instance = plugin_class() - pluginInfo.instance = plugin_instance - - # Ensure plugins have a reference to the app - plugin_instance.app = self.getApp() - logger.info(f"Set app reference for plugin: {module_name}") - - if hasattr(plugin_instance, 'set_app'): - plugin_instance.set_app(self.getApp()) - logger.info(f"Called set_app() for plugin: {module_name}") - - if hasattr(plugin_instance, 'set_plugin_info'): - plugin_instance.set_plugin_info(pluginInfo) - logger.info(f"Called set_plugin_info() for plugin: {module_name}") - - # Register with pluggy and activate - if self.plugin_manager is None: - logger.error(f"Plugin manager is None when loading {module_name}") - return False - - logger.info(f"Registering plugin with pluggy: {module_name}") - self.plugin_manager.register(plugin_instance) - - try: - logger.info(f"Activating plugin: {module_name}") - # Lifecycle is per-plugin. Broadcasting through pluggy replays - # activate() on every previously-registered plugin. - self._callPluginLifecycle(plugin_instance, "activate") - except Exception as e: - logger.error(f"Error activating plugin {module_name}: {e}") - import traceback - logger.error(traceback.format_exc()) - return False - - pluginInfo.loaded = True - logger.info(f"Successfully loaded plugin: {module_name}") - - self._register_plugin_dbus_module(pluginInfo) - - # Activate plugin-specific keybindings - self._activate_plugin_keybindings(pluginInfo) - - return True - - except Exception as e: - logger.error(f"Failed to load plugin {module_name}: {e}") - import traceback - logger.error(traceback.format_exc()) - return False - - def unloadPlugin(self, pluginInfo): - """Unload a plugin.""" - if pluginInfo.builtin: - return False - - module_name = pluginInfo.get_module_name() - - try: - # Not loaded? - if not pluginInfo.loaded: - return True - - # Deactivate plugin - plugin_instance = pluginInfo.instance - if plugin_instance: - try: - # Mirror targeted activation and only deactivate the plugin - # instance being unloaded. - self._callPluginLifecycle(plugin_instance, "deactivate") - except Exception as e: - logger.error(f"Error deactivating plugin {module_name}: {e}") - - self._deregister_plugin_dbus_module(pluginInfo) - - # Unregister from pluggy - self.plugin_manager.unregister(plugin_instance) - - # Clean up - pluginInfo.instance = None - pluginInfo.loaded = False - - logger.info(f"Unloaded plugin: {module_name}") - return True - - except Exception as e: - logger.error(f"Failed to unload plugin {module_name}: {e}") - return False - - def unloadAllPlugins(self, ForceAllPlugins=False): - """Unload all plugins.""" - for pluginInfo in self.plugins: - if ForceAllPlugins or pluginInfo.loaded: - self.unloadPlugin(pluginInfo) - - def get_debug_snapshot(self) -> Dict[str, object]: - """Returns read-only counters useful for long-uptime diagnostics.""" - - loadedPlugins = [info for info in self._plugins.values() if info.loaded] - try: - pluggyRegisteredPlugins = len(self.plugin_manager.get_plugins()) - except Exception: - pluggyRegisteredPlugins = -1 - - return { - "scanned_plugins": len(self._plugins), - "active_plugins": len(self._active_plugins), - "loaded_plugins": len(loadedPlugins), - "builtin_plugins": sum(1 for info in self._plugins.values() if info.builtin), - "hidden_plugins": sum(1 for info in self._plugins.values() if info.hidden), - "plugin_keybinding_contexts": len(self._plugin_keybindings), - "plugin_keybindings": sum(len(bindings) for bindings in self._plugin_keybindings.values()), - "global_keybindings": len(self._global_bindings), - "last_active_script_present": self._last_active_script is not None, - "pluggy_registered_plugins": pluggyRegisteredPlugins, - } diff --git a/src/cthulhu/plugins/AIAssistant/__init__.py b/src/cthulhu/plugins/AIAssistant/__init__.py deleted file mode 100644 index 34733fd..0000000 --- a/src/cthulhu/plugins/AIAssistant/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -"""AI Assistant plugin package.""" - -from .plugin import AIAssistant \ No newline at end of file diff --git a/src/cthulhu/plugins/AIAssistant/ai_providers.py b/src/cthulhu/plugins/AIAssistant/ai_providers.py deleted file mode 100644 index a668466..0000000 --- a/src/cthulhu/plugins/AIAssistant/ai_providers.py +++ /dev/null @@ -1,740 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""AI providers for the AI Assistant plugin.""" - -import logging -import json -import requests -from abc import ABC, abstractmethod - -logger = logging.getLogger(__name__) - -class AIProvider(ABC): - """Abstract base class for AI providers.""" - - def __init__(self, api_key=None, model=None, **kwargs): - self.api_key = api_key - self.model = model - self.kwargs = kwargs - - @abstractmethod - def describe_screen(self, screenshot_data, accessibility_data): - """Generate a description of the current screen.""" - pass - - @abstractmethod - def answer_question(self, question, screenshot_data, accessibility_data): - """Answer a question about the current screen/focus.""" - pass - - @abstractmethod - def suggest_actions(self, request, screenshot_data, accessibility_data): - """Suggest actions to accomplish a user's request.""" - pass - - @abstractmethod - def analyze_images(self, user_question, screenshot_data, accessibility_data): - """Analyze images visible on screen, focusing on visual content rather than UI elements.""" - pass - - def _prepare_system_prompt(self, task_type): - """Prepare system prompt based on task type.""" - if task_type == "image": - base_prompt = """You are an AI assistant helping a screen reader user analyze image files. You have access to a single image file that the user has selected for analysis. - -The user is using the Cthulhu screen reader, so they cannot see images visually. Your task is to provide detailed visual descriptions of the image content to make it accessible. - -""" - else: - base_prompt = """You are an AI assistant helping a screen reader user navigate and interact with computer applications. You have access to: - -1. A screenshot of the current screen -2. Detailed accessibility tree information about UI elements -3. Information about the currently focused element - -The user is using the Cthulhu screen reader, so they cannot see the screen visually. Your responses should be clear, concise, and focused on accessibility. -**Critical**: If there are any codes, or information like an ID, be sure to include it in your output. - -""" - - if task_type == "describe": - return base_prompt + """Your task: Provide a clear, structured description of what's on the screen. Focus on: -- Main UI elements and their layout -- Current focus location -- Available actions and navigation options -- Any important visual information not captured in accessibility data - -Keep descriptions concise but informative.""" - - elif task_type == "question": - return base_prompt + """Your task: Answer the user's question about the current screen or focused element. Use both the screenshot and accessibility data to provide accurate, helpful information. - -Be specific and actionable in your responses.""" - - elif task_type == "action": - return base_prompt + """Your task: I WILL EXECUTE THE ACTION IMMEDIATELY - provide the structured response format only. - -🚨 CRITICAL RULES: -- I am the action execution system - I WILL perform the action, not give instructions -- NEVER provide programming code, implementation steps, or "how to" instructions -- NEVER mention ASCII codes, KEY_DOWN events, or technical implementation details -- Always use ACTION TYPE: COPY, TYPE, CLICK, SCROLL, or NAVIGATE -- Be direct about what I will do - -STRICT ACTION TYPE MAPPING: -- "find [element] and enter [text]" → ACTION TYPE: TYPE (I will locate element and type text) -- "type [text]" → ACTION TYPE: TYPE (I will type the specified text) -- "copy [text] to clipboard" → ACTION TYPE: COPY (I will copy to clipboard) -- "click [element]" → ACTION TYPE: CLICK (I will click the element) - -MANDATORY RESPONSE FORMAT: - -**ACTION ANALYSIS**: I will [specific action] -**TARGET ELEMENT**: [element description] -**ACTION TYPE**: [TYPE/COPY/CLICK/SCROLL/NAVIGATE] -**SAFETY CHECK**: [any concerns] -**STEP-BY-STEP**: What I will execute (NO CODE, NO IMPLEMENTATION DETAILS) - -Example for "find edit box and enter text": -**ACTION ANALYSIS**: I will locate the edit box and type the specified text into it -**TARGET ELEMENT**: Text input field ("What's on your mind?" edit box) -**ACTION TYPE**: TYPE -**SAFETY CHECK**: This will input text into the focused text field -**STEP-BY-STEP**: -1. Locate the edit box in the interface -2. Focus on the edit box -3. Type the requested text into the field - -🚨 NEVER GIVE PROGRAMMING CODE OR TECHNICAL INSTRUCTIONS""" - - elif task_type == "image": - return base_prompt + """Your task: Analyze and describe any images visible on the screen, focusing on visual content rather than UI elements. - -IMPORTANT IMAGE ANALYSIS GUIDELINES: -- Focus ONLY on the visual content of images (photos, diagrams, graphics, artwork) -- IGNORE UI elements like buttons, menus, toolbars, window frames -- Describe what you see IN the images: objects, people, scenes, colors, text within images -- If multiple images are visible, describe each one separately -- For photographs: describe the scene, subjects, lighting, composition -- For diagrams/charts: describe the data, relationships, labels shown -- For screenshots within images: describe the content being shown -- Be detailed about visual elements that a screen reader user cannot access - -If no images are clearly visible on screen, say so clearly. - -Keep descriptions informative and well-structured.""" - - return base_prompt - - - -class ClaudeCodeProvider(AIProvider): - """Claude Code CLI provider - uses installed Claude Code application.""" - - def __init__(self, **kwargs): - super().__init__(**kwargs) - # No API key needed - uses Claude Code CLI directly - - def describe_screen(self, screenshot_data, accessibility_data): - """Generate a description using Claude Code CLI.""" - try: - prompt = self._build_prompt("describe", None, accessibility_data) - return self._call_claude_code(prompt) - except Exception as e: - logger.error(f"Claude Code describe error: {e}") - return f"Error getting screen description: {e}" - - def answer_question(self, question, screenshot_data, accessibility_data): - """Answer a question using Claude Code CLI.""" - try: - prompt = self._build_prompt("question", question, accessibility_data) - return self._call_claude_code(prompt) - except Exception as e: - logger.error(f"Claude Code question error: {e}") - return f"Error answering question: {e}" - - def suggest_actions(self, request, screenshot_data, accessibility_data): - """Suggest actions using Claude Code CLI.""" - try: - prompt = self._build_prompt("action", request, accessibility_data) - return self._call_claude_code(prompt) - except Exception as e: - logger.error(f"Claude Code action error: {e}") - return f"Error suggesting actions: {e}" - - def analyze_images(self, user_question, screenshot_data, accessibility_data): - """Analyze images visible on screen using Claude Code CLI.""" - try: - prompt = self._build_prompt("image", user_question, accessibility_data) - - # If we have image data, save it to a temporary file for Claude Code - temp_image_path = None - if screenshot_data: - import tempfile - import base64 - import os - - # Create temporary file with appropriate extension - image_format = screenshot_data.get('format', 'png') - suffix = f".{image_format}" - - with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file: - # Decode base64 image data and write to temp file - image_data = base64.b64decode(screenshot_data['data']) - temp_file.write(image_data) - temp_image_path = temp_file.name - - try: - # Call Claude Code with the image file path - result = self._call_claude_code(prompt, temp_image_path) - return result - finally: - # Clean up temporary file - if os.path.exists(temp_image_path): - os.unlink(temp_image_path) - else: - # No image data, just call with text prompt - return self._call_claude_code(prompt) - - except Exception as e: - logger.error(f"Claude Code image analysis error: {e}") - return f"Error analyzing images: {e}" - - def _build_prompt(self, task_type, user_input, accessibility_data): - """Build the complete prompt for Claude Code.""" - import json - - system_prompt = self._get_system_prompt(task_type) - - if task_type == "image": - # For image analysis, minimize accessibility data weight - if user_input == "ANALYZE_SINGLE_IMAGE_FILE": - prompt = f"{system_prompt}\n\nAnalyze and describe the single image file provided. Focus on visual content only - describe what you see in the image: objects, people, scenery, colors, text, composition, and any other visual details." - else: - prompt = f"{system_prompt}\n\nCurrent screen context (focus on images):\n" - if user_input: - prompt += f"User question about images: {user_input}\n\n" - prompt += "Analyze and describe any images visible on this screen. Focus on visual content, not UI elements." - else: - # Standard prompt with full accessibility data - prompt = f"{system_prompt}\n\nCurrent accessibility information:\n```json\n{json.dumps(accessibility_data, indent=2)}\n```\n\n" - - if task_type == "describe": - prompt += "Please describe what's on this screen." - elif task_type == "question": - prompt += f"User question: {user_input}" - elif task_type == "action": - prompt += f"User wants to: {user_input}\n\nProvide the action analysis in the required format." - - return prompt - - def _call_claude_code(self, prompt, image_path=None): - """Call Claude Code CLI with the prompt and optional image.""" - import subprocess - import tempfile - import os - - try: - # Build the command - cmd = ['claude', '--print', '--output-format', 'text'] - - # For accessibility analysis, skip permission checks to allow automatic access - cmd.append('--dangerously-skip-permissions') - - # If we have an image path, include it in the prompt - if image_path: - prompt = f"Please analyze and describe the image at {image_path}. {prompt}" - - # Add the prompt - cmd.append(prompt) - - # Call Claude Code CLI - result = subprocess.run( - cmd, - capture_output=True, - text=True, - timeout=120 # Longer timeout for image analysis - ) - - if result.returncode == 0: - return result.stdout.strip() - else: - error_msg = f"Claude Code CLI error: {result.stderr}" - logger.error(error_msg) - return error_msg - - except subprocess.TimeoutExpired: - error_msg = "Claude Code CLI timed out" - logger.error(error_msg) - return error_msg - except Exception as e: - error_msg = f"Error calling Claude Code CLI: {e}" - logger.error(error_msg) - return error_msg - - def _get_system_prompt(self, task_type): - """Get system prompt for Claude Code.""" - if task_type == "image": - base_prompt = """You are Claude Code helping a screen reader user analyze image files. You have access to a single image file that the user has selected for analysis. - -The user is using the Cthulhu screen reader and cannot see images visually. Provide detailed visual descriptions of the image content to make it accessible. - -""" - else: - base_prompt = """You are Claude Code helping a screen reader user navigate and interact with computer applications. You have expert understanding of terminal commands, programming, and accessibility. - -The user is using the Cthulhu screen reader and cannot see the screen visually. Provide expert technical assistance. - -""" - - if task_type == "action": - return base_prompt + """CRITICAL: I WILL EXECUTE THE ACTION IMMEDIATELY. - -🚨 EXPERT COMMAND UNDERSTANDING: -- "type echo 'hello world'" → Extract exactly: echo 'hello world' -- "run ls -la" → Extract exactly: ls -la -- "execute ./configure --prefix=/usr" → Extract exactly: ./configure --prefix=/usr - -MANDATORY FORMAT: -**ACTION ANALYSIS**: I will [specific action] -**TARGET ELEMENT**: [element description] -**ACTION TYPE**: [TYPE/COPY/CLICK/SCROLL/NAVIGATE] -**SAFETY CHECK**: [assessment] -**STEP-BY-STEP**: What I will execute""" - - elif task_type == "describe": - return base_prompt + "Provide technical descriptions focusing on development tools, terminals, and accessibility elements." - - elif task_type == "question": - return base_prompt + "Answer with expert technical knowledge about programming, terminals, and system operations." - - elif task_type == "image": - return base_prompt + """Your task: Analyze and describe any images visible on the screen, focusing on visual content rather than UI elements. - -IMPORTANT IMAGE ANALYSIS GUIDELINES: -- Focus ONLY on the visual content of images (photos, diagrams, graphics, artwork) -- IGNORE UI elements like buttons, menus, toolbars, window frames -- Describe what you see IN the images: objects, people, scenes, colors, text within images -- If multiple images are visible, describe each one separately -- For photographs: describe the scene, subjects, lighting, composition -- For diagrams/charts: describe the data, relationships, labels shown -- For screenshots within images: describe the content being shown -- Be detailed about visual elements that a screen reader user cannot access - -If no images are clearly visible on screen, say so clearly. - -Keep descriptions informative and well-structured.""" - - return base_prompt - - -class CodexProvider(AIProvider): - """Codex CLI provider - uses installed Codex CLI.""" - - def __init__(self, codex_path=None, **kwargs): - super().__init__(**kwargs) - self.codex_path = codex_path or self._resolve_codex_path() - - def describe_screen(self, screenshot_data, accessibility_data): - """Generate a description using Codex CLI.""" - try: - prompt = self._build_prompt("describe", None, accessibility_data) - return self._call_codex(prompt, screenshot_data) - except Exception as e: - logger.error(f"Codex describe error: {e}") - return f"Error getting screen description: {e}" - - def answer_question(self, question, screenshot_data, accessibility_data): - """Answer a question using Codex CLI.""" - try: - prompt = self._build_prompt("question", question, accessibility_data) - return self._call_codex(prompt, screenshot_data) - except Exception as e: - logger.error(f"Codex question error: {e}") - return f"Error answering question: {e}" - - def suggest_actions(self, request, screenshot_data, accessibility_data): - """Suggest actions using Codex CLI.""" - try: - prompt = self._build_prompt("action", request, accessibility_data) - return self._call_codex(prompt, screenshot_data) - except Exception as e: - logger.error(f"Codex action error: {e}") - return f"Error suggesting actions: {e}" - - def analyze_images(self, user_question, screenshot_data, accessibility_data): - """Analyze images visible on screen using Codex CLI.""" - try: - prompt = self._build_prompt("image", user_question, accessibility_data) - return self._call_codex(prompt, screenshot_data) - except Exception as e: - logger.error(f"Codex image analysis error: {e}") - return f"Error analyzing images: {e}" - - def _build_prompt(self, task_type, user_input, accessibility_data): - """Build the complete prompt for Codex CLI.""" - system_prompt = self._prepare_system_prompt(task_type) - - if task_type == "image": - if user_input == "ANALYZE_SINGLE_IMAGE_FILE": - prompt = ( - f"{system_prompt}\n\nAnalyze and describe the single image file provided. " - "Focus on visual content only - describe what you see in the image: objects, " - "people, scenery, colors, text, composition, and any other visual details." - ) - else: - prompt = f"{system_prompt}\n\nCurrent screen context (focus on images):\n" - if user_input: - prompt += f"User question about images: {user_input}\n\n" - prompt += "Analyze and describe any images visible on this screen. Focus on visual content, not UI elements." - else: - prompt = ( - f"{system_prompt}\n\nCurrent accessibility information:\n" - f"```json\n{json.dumps(accessibility_data, indent=2)}\n```\n\n" - ) - - if task_type == "describe": - prompt += "Please describe what's on this screen." - elif task_type == "question": - prompt += f"User question: {user_input}" - elif task_type == "action": - prompt += f"User wants to: {user_input}\n\nProvide the action analysis in the required format." - - return prompt - - def _resolve_codex_path(self): - import shutil - import os - - codex_path = shutil.which('codex') - if not codex_path and os.path.isfile('/usr/bin/codex'): - codex_path = '/usr/bin/codex' - return codex_path - - def _call_codex(self, prompt, screenshot_data): - """Call Codex CLI with the prompt and optional image.""" - import subprocess - import tempfile - import os - import base64 - - if not self.codex_path: - return "Codex CLI not found" - - output_path = None - image_path = None - try: - # Write screenshot to a temp file if available - if screenshot_data: - image_format = screenshot_data.get('format', 'png') - suffix = f".{image_format}" - with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file: - image_data = base64.b64decode(screenshot_data['data']) - temp_file.write(image_data) - image_path = temp_file.name - - with tempfile.NamedTemporaryFile(delete=False) as output_file: - output_path = output_file.name - - cmd = [ - self.codex_path, - 'exec', - '--skip-git-repo-check', - '--color', - 'never', - '--output-last-message', - output_path, - '-' - ] - - if image_path: - cmd.extend(['-i', image_path]) - - result = subprocess.run( - cmd, - input=prompt, - capture_output=True, - text=True, - timeout=120 - ) - - if result.returncode != 0: - error_msg = result.stderr.strip() or result.stdout.strip() or "Codex CLI error" - logger.error(error_msg) - return f"Codex CLI error: {error_msg}" - - response_text = "" - if output_path and os.path.exists(output_path): - with open(output_path, 'r') as f: - response_text = f.read().strip() - - if not response_text: - response_text = result.stdout.strip() - - return response_text or "No response from Codex" - - except subprocess.TimeoutExpired: - error_msg = "Codex CLI timed out" - logger.error(error_msg) - return error_msg - except Exception as e: - error_msg = f"Error calling Codex CLI: {e}" - logger.error(error_msg) - return error_msg - finally: - if image_path and os.path.exists(image_path): - try: - os.unlink(image_path) - except Exception: - pass - if output_path and os.path.exists(output_path): - try: - os.unlink(output_path) - except Exception: - pass - - -class OllamaProvider(AIProvider): - """Ollama local AI provider.""" - - def __init__(self, model="llama3.2-vision", base_url="http://localhost:11434", **kwargs): - super().__init__(model=model, **kwargs) - self.base_url = base_url - - def describe_screen(self, screenshot_data, accessibility_data): - """Generate a description using Ollama.""" - try: - prompt = self._build_prompt("describe", None, accessibility_data) - return self._make_request(prompt, screenshot_data) - except Exception as e: - logger.error(f"Ollama describe error: {e}") - return f"Error getting screen description: {e}" - - def answer_question(self, question, screenshot_data, accessibility_data): - """Answer a question using Ollama.""" - try: - prompt = self._build_prompt("question", question, accessibility_data) - return self._make_request(prompt, screenshot_data) - except Exception as e: - logger.error(f"Ollama question error: {e}") - return f"Error answering question: {e}" - - def suggest_actions(self, request, screenshot_data, accessibility_data): - """Suggest actions using Ollama.""" - try: - prompt = self._build_prompt("action", request, accessibility_data) - return self._make_request(prompt, screenshot_data) - except Exception as e: - logger.error(f"Ollama action error: {e}") - return f"Error suggesting actions: {e}" - - def analyze_images(self, user_question, screenshot_data, accessibility_data): - """Analyze images visible on screen using Ollama.""" - try: - prompt = self._build_prompt("image", user_question, accessibility_data) - return self._make_request(prompt, screenshot_data) - except Exception as e: - logger.error(f"Ollama image analysis error: {e}") - return f"Error analyzing images: {e}" - - def _build_prompt(self, task_type, user_input, accessibility_data): - """Build the complete prompt for Ollama.""" - system_prompt = self._prepare_system_prompt(task_type) - - if task_type == "image": - # For image analysis, minimize accessibility data weight - if user_input == "ANALYZE_SINGLE_IMAGE_FILE": - prompt = f"{system_prompt}\n\nAnalyze and describe the single image file provided. Focus on visual content only - describe what you see in the image: objects, people, scenery, colors, text, composition, and any other visual details." - else: - prompt = f"{system_prompt}\n\nCurrent screen context (focus on images):\n" - if user_input: - prompt += f"User question about images: {user_input}\n\n" - prompt += "Analyze and describe any images visible on this screen. Focus on visual content, not UI elements." - else: - # Standard prompt with full accessibility data - prompt = f"{system_prompt}\n\nCurrent accessibility information:\n```json\n{json.dumps(accessibility_data, indent=2)}\n```\n\n" - - if task_type == "describe": - prompt += "Please describe what's on this screen." - elif task_type == "question": - prompt += f"User question: {user_input}" - elif task_type == "action": - prompt += f"User wants to: {user_input}\n\nPlease suggest specific steps to accomplish this." - - return prompt - - def _make_request(self, prompt, screenshot_data): - """Make request to Ollama API.""" - try: - # For Ollama, we'll use the generate endpoint - payload = { - "model": self.model, - "prompt": prompt, - "stream": False - } - - # Add image data if available and model supports vision - if screenshot_data and "vision" in self.model.lower(): - payload["images"] = [screenshot_data['data']] - - # Use longer timeout for vision models as they're much slower - timeout = 180 if screenshot_data and "vision" in self.model.lower() else 60 - - response = requests.post( - f"{self.base_url}/api/generate", - json=payload, - timeout=timeout - ) - - if response.status_code == 200: - result = response.json() - return result.get('response', 'No response from Ollama') - else: - error_msg = f"Ollama API error {response.status_code}: {response.text}" - logger.error(error_msg) - return error_msg - - except requests.RequestException as e: - error_msg = f"Network error contacting Ollama: {e}" - logger.error(error_msg) - return error_msg - except Exception as e: - error_msg = f"Unexpected error with Ollama API: {e}" - logger.error(error_msg) - return error_msg - - -class GeminiProvider(AIProvider): - """Google Gemini AI provider using Google's Gemini API.""" - - def __init__(self, api_key, model="gemini-1.5-flash", **kwargs): - super().__init__(api_key, model, **kwargs) - self.base_url = f"https://generativelanguage.googleapis.com/v1beta/models/{self.model}:generateContent" - - def describe_screen(self, screenshot_data, accessibility_data): - """Generate a description using Gemini.""" - try: - prompt = self._build_prompt("describe", None, accessibility_data) - return self._make_request(prompt, screenshot_data) - except Exception as e: - logger.error(f"Gemini describe error: {e}") - return f"Error getting screen description: {e}" - - def answer_question(self, question, screenshot_data, accessibility_data): - """Answer a question using Gemini.""" - try: - prompt = self._build_prompt("question", question, accessibility_data) - return self._make_request(prompt, screenshot_data) - except Exception as e: - logger.error(f"Gemini question error: {e}") - return f"Error answering question: {e}" - - def suggest_actions(self, request, screenshot_data, accessibility_data): - """Suggest actions using Gemini.""" - try: - prompt = self._build_prompt("action", request, accessibility_data) - return self._make_request(prompt, screenshot_data) - except Exception as e: - logger.error(f"Gemini action error: {e}") - return f"Error suggesting actions: {e}" - - def analyze_images(self, user_question, screenshot_data, accessibility_data): - """Analyze images visible on screen using Gemini.""" - try: - prompt = self._build_prompt("image", user_question, accessibility_data) - return self._make_request(prompt, screenshot_data) - except Exception as e: - logger.error(f"Gemini image analysis error: {e}") - return f"Error analyzing images: {e}" - - def _build_prompt(self, task_type, user_input, accessibility_data): - """Build the complete prompt for Gemini.""" - system_prompt = self._prepare_system_prompt(task_type) - - if task_type == "image": - if user_input == "ANALYZE_SINGLE_IMAGE_FILE": - prompt = f"{system_prompt}\n\nAnalyze and describe the single image file provided. Focus on visual content only - describe what you see in the image: objects, people, scenery, colors, text, composition, and any other visual details." - else: - prompt = f"{system_prompt}\n\nCurrent screen context (focus on images):\n" - if user_input: - prompt += f"User question about images: {user_input}\n\n" - prompt += "Analyze and describe any images visible on this screen. Focus on visual content, not UI elements." - else: - prompt = f"{system_prompt}\n\nCurrent accessibility information:\n```json\n{json.dumps(accessibility_data, indent=2)}\n```\n\n" - - if task_type == "describe": - prompt += "Please describe what's on this screen." - elif task_type == "question": - prompt += f"User question: {user_input}" - elif task_type == "action": - prompt += f"User wants to: {user_input}\n\nPlease suggest specific steps to accomplish this." - - return prompt - - def _make_request(self, prompt, screenshot_data): - """Make request to Gemini API.""" - try: - parts = [{"text": prompt}] - - # Add image if available - if screenshot_data: - parts.append({ - "inline_data": { - "mime_type": f"image/{screenshot_data['format']}", - "data": screenshot_data['data'] - } - }) - - payload = { - "contents": [{ - "parts": parts - }] - } - - response = requests.post( - f"{self.base_url}?key={self.api_key}", - headers={"Content-Type": "application/json"}, - json=payload, - timeout=30 - ) - - if response.status_code == 200: - result = response.json() - if 'candidates' in result and len(result['candidates']) > 0: - return result['candidates'][0]['content']['parts'][0]['text'] - else: - return "No response from Gemini" - else: - error_msg = f"Gemini API error {response.status_code}: {response.text}" - logger.error(error_msg) - return error_msg - - except requests.RequestException as e: - error_msg = f"Network error contacting Gemini: {e}" - logger.error(error_msg) - return error_msg - except Exception as e: - error_msg = f"Unexpected error with Gemini API: {e}" - logger.error(error_msg) - return error_msg - - -def create_provider(provider_type, **kwargs): - """Factory function to create AI providers.""" - if provider_type == "claude_code": - return ClaudeCodeProvider(**kwargs) - elif provider_type == "codex": - return CodexProvider(**kwargs) - elif provider_type == "ollama": - return OllamaProvider(**kwargs) - elif provider_type == "gemini": - return GeminiProvider(**kwargs) - else: - raise ValueError(f"Unknown provider type: {provider_type}") diff --git a/src/cthulhu/plugins/AIAssistant/meson.build b/src/cthulhu/plugins/AIAssistant/meson.build deleted file mode 100644 index 0d65b03..0000000 --- a/src/cthulhu/plugins/AIAssistant/meson.build +++ /dev/null @@ -1,15 +0,0 @@ -aiassistant_python_sources = files([ - '__init__.py', - 'plugin.py', - 'ai_providers.py' -]) - -python3.install_sources( - aiassistant_python_sources, - subdir: 'cthulhu/plugins/AIAssistant' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'AIAssistant' -) \ No newline at end of file diff --git a/src/cthulhu/plugins/AIAssistant/plugin.info b/src/cthulhu/plugins/AIAssistant/plugin.info deleted file mode 100644 index d954059..0000000 --- a/src/cthulhu/plugins/AIAssistant/plugin.info +++ /dev/null @@ -1,7 +0,0 @@ -[Plugin] -Name = AI Assistant -Module = AIAssistant -Description = AI-powered accessibility assistant for analyzing screens and taking actions -Authors = Stormux -Version = 2.0.0 -Category = Accessibility diff --git a/src/cthulhu/plugins/AIAssistant/plugin.py b/src/cthulhu/plugins/AIAssistant/plugin.py deleted file mode 100644 index 6a64018..0000000 --- a/src/cthulhu/plugins/AIAssistant/plugin.py +++ /dev/null @@ -1,2331 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""AI Assistant plugin for Cthulhu screen reader.""" - -import logging -import os -import json -import base64 -from io import BytesIO - -import gi -gi.require_version('Gdk', '3.0') -gi.require_version('GdkPixbuf', '2.0') -gi.require_version('Atspi', '2.0') -gi.require_version('Gtk', '3.0') -from gi.repository import Gdk, GdkPixbuf, Atspi, Gtk - -from cthulhu.plugin import Plugin, cthulhu_hookimpl -from cthulhu import settings -from cthulhu import settings_manager -from cthulhu import cthulhu_state -from cthulhu import ax_object -from cthulhu.ax_text import AXText -from cthulhu.ax_value import AXValue -from cthulhu import ax_utilities -from cthulhu.ax_utilities_state import AXUtilitiesState -from cthulhu.plugins.AIAssistant.ai_providers import create_provider - -logger = logging.getLogger(__name__) - -class AIAssistant(Plugin): - """AI-powered accessibility assistant plugin. - - Provides AI-enhanced accessibility features including: - - Screen analysis using screenshots and AT-SPI data - - Natural language queries about UI elements - - Safe action assistance with user confirmation - - Multi-provider AI support (Claude, ChatGPT, Gemini, Ollama) - """ - - def __init__(self, *args, **kwargs): - """Initialize the AI Assistant plugin.""" - super().__init__(*args, **kwargs) - - logger.info("AI ASSISTANT: Plugin __init__ starting") - logger.info("AI ASSISTANT: Plugin initialized successfully") - - # Menu and keybinding storage - self._kb_binding_menu = None - self._menu_gui = None - - # AI provider and settings - self._provider_type = None - self._ai_provider = None - self._api_key = None - self._ollama_model = None - self._ollama_endpoint = None - self._settings_manager = settings_manager.getManager() - - # Plugin enabled state - self._enabled = False - - # Pre-captured screen data (to avoid capturing dialog itself) - self._current_screen_data = None - self._prefs_grid = None - self._prefs_widgets = {} - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the AI Assistant plugin.""" - if plugin is not None and plugin is not self: - return - - # Prevent multiple activations - if self._enabled: - logger.info("AI ASSISTANT: Already activated, skipping") - return - - try: - logger.info("AI ASSISTANT: === Plugin activation starting ===") - - # Check if AI Assistant is enabled in settings - enabled = self._settings_manager.getSetting('aiAssistantEnabled') - logger.info(f"AI ASSISTANT: Enabled setting: {enabled}") - if not enabled: - logger.info("AI Assistant is disabled in settings, skipping activation") - return - - # Load AI settings - self._load_ai_settings() - - # Check if we have valid configuration - config_valid = self._validate_configuration() - logger.info(f"AI Assistant configuration valid: {config_valid}") - - # Initialize AI provider (may fail but we still want menu access) - if config_valid: - provider_init = self._initialize_ai_provider() - else: - logger.warning("AI Assistant configuration invalid, menu will show error messages") - provider_init = False - - # Always register keybindings so menu is accessible even with config issues - self._register_keybindings() - - self._enabled = True - logger.info("AI Assistant plugin activated successfully") - - except Exception as e: - logger.error(f"Error activating AI Assistant plugin: {e}") - import traceback - logger.error(traceback.format_exc()) - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the AI Assistant plugin.""" - if plugin is not None and plugin is not self: - return - - logger.info("Deactivating AI Assistant plugin") - - # Unregister keybindings - self._unregister_keybindings() - - self._enabled = False - - def getPreferencesGUI(self): - if not self._prefs_grid: - self._prefs_grid = self._build_preferences_gui() - self._load_preferences_into_widgets() - return self._prefs_grid, "AI Assistant" - - def getPreferencesFromGUI(self): - if not self._prefs_widgets: - return {} - - provider_values = self._prefs_widgets.get("provider_values", []) - quality_values = self._prefs_widgets.get("quality_values", []) - provider_index = self._prefs_widgets["provider_combo"].get_active() - quality_index = self._prefs_widgets["quality_combo"].get_active() - - if provider_index < 0 or provider_index >= len(provider_values): - provider = settings.aiProvider - else: - provider = provider_values[provider_index] - - if quality_index < 0 or quality_index >= len(quality_values): - screenshot_quality = settings.aiScreenshotQuality - else: - screenshot_quality = quality_values[quality_index] - - return { - "aiAssistantEnabled": self._prefs_widgets["enable_check"].get_active(), - "aiProvider": provider, - "aiApiKeyFile": self._prefs_widgets["api_key_entry"].get_text().strip(), - "aiOllamaModel": self._prefs_widgets["ollama_model_entry"].get_text().strip(), - "aiOllamaEndpoint": self._prefs_widgets["ollama_endpoint_entry"].get_text().strip(), - "aiConfirmationRequired": self._prefs_widgets["confirmation_check"].get_active(), - "aiScreenshotQuality": screenshot_quality, - } - - def _build_preferences_gui(self): - grid = Gtk.Grid( - row_spacing=6, - column_spacing=12, - margin_left=12, - margin_right=12, - margin_top=12, - margin_bottom=12, - ) - - row = 0 - - enable_check = Gtk.CheckButton(label="Enable AI Assistant") - enable_check.connect("toggled", self._on_ai_enabled_toggled) - grid.attach(enable_check, 0, row, 2, 1) - row += 1 - - provider_label = Gtk.Label(label="_Provider:") - provider_label.set_use_underline(True) - provider_label.set_halign(Gtk.Align.START) - - provider_combo = Gtk.ComboBoxText() - provider_combo.set_hexpand(True) - provider_values = [ - settings.AI_PROVIDER_CLAUDE_CODE, - settings.AI_PROVIDER_CODEX, - settings.AI_PROVIDER_GEMINI, - settings.AI_PROVIDER_OLLAMA, - ] - provider_labels = ["Claude Code", "Codex", "Gemini", "Ollama"] - for label in provider_labels: - provider_combo.append_text(label) - provider_combo.connect("changed", self._on_provider_changed) - provider_label.set_mnemonic_widget(provider_combo) - - grid.attach(provider_label, 0, row, 1, 1) - grid.attach(provider_combo, 1, row, 1, 1) - row += 1 - - api_key_label = Gtk.Label(label="API _Key File:") - api_key_label.set_use_underline(True) - api_key_label.set_halign(Gtk.Align.START) - api_key_entry = Gtk.Entry() - api_key_entry.set_hexpand(True) - api_key_label.set_mnemonic_widget(api_key_entry) - - grid.attach(api_key_label, 0, row, 1, 1) - grid.attach(api_key_entry, 1, row, 1, 1) - row += 1 - - ollama_model_label = Gtk.Label(label="_Ollama Model:") - ollama_model_label.set_use_underline(True) - ollama_model_label.set_halign(Gtk.Align.START) - ollama_model_entry = Gtk.Entry() - ollama_model_entry.set_hexpand(True) - ollama_model_label.set_mnemonic_widget(ollama_model_entry) - - grid.attach(ollama_model_label, 0, row, 1, 1) - grid.attach(ollama_model_entry, 1, row, 1, 1) - row += 1 - - ollama_endpoint_label = Gtk.Label(label="Ollama _Endpoint:") - ollama_endpoint_label.set_use_underline(True) - ollama_endpoint_label.set_halign(Gtk.Align.START) - ollama_endpoint_entry = Gtk.Entry() - ollama_endpoint_entry.set_hexpand(True) - ollama_endpoint_label.set_mnemonic_widget(ollama_endpoint_entry) - - grid.attach(ollama_endpoint_label, 0, row, 1, 1) - grid.attach(ollama_endpoint_entry, 1, row, 1, 1) - row += 1 - - confirmation_check = Gtk.CheckButton(label="Require confirmation before actions") - grid.attach(confirmation_check, 0, row, 2, 1) - row += 1 - - quality_label = Gtk.Label(label="Screenshot _Quality:") - quality_label.set_use_underline(True) - quality_label.set_halign(Gtk.Align.START) - quality_combo = Gtk.ComboBoxText() - quality_combo.set_hexpand(True) - quality_values = [ - settings.AI_SCREENSHOT_QUALITY_LOW, - settings.AI_SCREENSHOT_QUALITY_MEDIUM, - settings.AI_SCREENSHOT_QUALITY_HIGH, - ] - quality_labels = ["Low", "Medium", "High"] - for label in quality_labels: - quality_combo.append_text(label) - quality_label.set_mnemonic_widget(quality_combo) - - grid.attach(quality_label, 0, row, 1, 1) - grid.attach(quality_combo, 1, row, 1, 1) - - self._prefs_widgets = { - "enable_check": enable_check, - "provider_combo": provider_combo, - "provider_values": provider_values, - "api_key_entry": api_key_entry, - "ollama_model_entry": ollama_model_entry, - "ollama_endpoint_entry": ollama_endpoint_entry, - "confirmation_check": confirmation_check, - "quality_combo": quality_combo, - "quality_values": quality_values, - } - - return grid - - def _load_preferences_into_widgets(self): - if not self._prefs_widgets: - return - - enabled = self._settings_manager.getSetting("aiAssistantEnabled") - if enabled is None: - enabled = settings.aiAssistantEnabled - self._prefs_widgets["enable_check"].set_active(enabled) - - provider = self._settings_manager.getSetting("aiProvider") or settings.aiProvider - provider_values = self._prefs_widgets.get("provider_values", []) - try: - provider_index = provider_values.index(provider) - except ValueError: - provider_index = 0 - self._prefs_widgets["provider_combo"].set_active(provider_index) - - api_key_file = self._settings_manager.getSetting("aiApiKeyFile") or settings.aiApiKeyFile - self._prefs_widgets["api_key_entry"].set_text(api_key_file or "") - - ollama_model = self._settings_manager.getSetting("aiOllamaModel") or settings.aiOllamaModel - self._prefs_widgets["ollama_model_entry"].set_text(ollama_model or "") - - ollama_endpoint = self._settings_manager.getSetting("aiOllamaEndpoint") or settings.aiOllamaEndpoint - self._prefs_widgets["ollama_endpoint_entry"].set_text(ollama_endpoint or "") - - confirmation_required = self._settings_manager.getSetting("aiConfirmationRequired") - if confirmation_required is None: - confirmation_required = settings.aiConfirmationRequired - self._prefs_widgets["confirmation_check"].set_active(confirmation_required) - - screenshot_quality = self._settings_manager.getSetting("aiScreenshotQuality") or settings.aiScreenshotQuality - quality_values = self._prefs_widgets.get("quality_values", []) - try: - quality_index = quality_values.index(screenshot_quality) - except ValueError: - quality_index = 0 - self._prefs_widgets["quality_combo"].set_active(quality_index) - - self._update_preferences_sensitivity() - - def _on_ai_enabled_toggled(self, widget): - self._update_preferences_sensitivity() - - def _on_provider_changed(self, widget): - self._update_preferences_sensitivity() - - def _update_preferences_sensitivity(self): - if not self._prefs_widgets: - return - - provider_values = self._prefs_widgets.get("provider_values", []) - provider_index = self._prefs_widgets["provider_combo"].get_active() - provider = provider_values[provider_index] if 0 <= provider_index < len(provider_values) else settings.aiProvider - - is_gemini = provider == settings.AI_PROVIDER_GEMINI - is_ollama = provider == settings.AI_PROVIDER_OLLAMA - - # Keep preferences editable even when the feature is disabled so users - # can prepare configuration before turning AI assistant on. - self._prefs_widgets["provider_combo"].set_sensitive(True) - self._prefs_widgets["api_key_entry"].set_sensitive(is_gemini) - self._prefs_widgets["ollama_model_entry"].set_sensitive(is_ollama) - self._prefs_widgets["ollama_endpoint_entry"].set_sensitive(is_ollama) - self._prefs_widgets["confirmation_check"].set_sensitive(True) - self._prefs_widgets["quality_combo"].set_sensitive(True) - - def refresh_settings(self): - """Refresh plugin settings and reinitialize provider. Called when settings change.""" - try: - logger.info("AI Assistant: Refreshing settings") - - # Reload settings - self._load_ai_settings() - - # Validate new configuration - config_valid = self._validate_configuration() - - # Reinitialize provider if configuration is valid - if config_valid: - old_provider = self._ai_provider - provider_init = self._initialize_ai_provider() - if provider_init: - logger.info(f"AI Assistant provider changed to: {self._provider_type}") - else: - logger.warning("Failed to initialize new provider") - self._ai_provider = None - else: - logger.warning("New configuration invalid, clearing provider") - self._ai_provider = None - - except Exception as e: - logger.error(f"Error refreshing AI Assistant settings: {e}") - - def _load_ai_settings(self): - """Load AI Assistant settings from Cthulhu configuration.""" - try: - # Get provider - provider = self._settings_manager.getSetting('aiProvider') - self._provider_type = provider or settings.AI_PROVIDER_CLAUDE_CODE - - # Load API key from file - api_key_file = self._settings_manager.getSetting('aiApiKeyFile') - if api_key_file and os.path.isfile(api_key_file): - with open(api_key_file, 'r') as f: - self._api_key = f.read().strip() - else: - self._api_key = None - - # Load Ollama model and endpoint - self._ollama_model = self._settings_manager.getSetting('aiOllamaModel') - if not self._ollama_model: - self._ollama_model = settings.aiOllamaModel - - self._ollama_endpoint = self._settings_manager.getSetting('aiOllamaEndpoint') - if not self._ollama_endpoint: - self._ollama_endpoint = settings.aiOllamaEndpoint - - logger.info(f"AI settings loaded: provider={self._provider_type}, " - f"api_key_configured={bool(self._api_key)}, " - f"ollama_model={self._ollama_model}, " - f"ollama_endpoint={self._ollama_endpoint}") - - except Exception as e: - logger.error(f"Error loading AI settings: {e}") - - def _validate_configuration(self): - """Validate AI Assistant configuration.""" - logger.info(f"Validating AI configuration - provider_type: {self._provider_type}") - if not self._provider_type: - logger.warning("No AI provider configured") - return False - - # Check provider-specific requirements - if self._provider_type == settings.AI_PROVIDER_OLLAMA: - logger.info("Checking Ollama availability") - return self._check_ollama_availability() - elif self._provider_type == settings.AI_PROVIDER_CLAUDE_CODE: - logger.info("Checking Claude Code availability") - result = self._check_claude_code_availability() - logger.info(f"Claude Code availability check result: {result}") - return result - elif self._provider_type == settings.AI_PROVIDER_CODEX: - logger.info("Checking Codex CLI availability") - result = self._check_codex_availability() - logger.info(f"Codex CLI availability check result: {result}") - return result - elif self._provider_type == settings.AI_PROVIDER_GEMINI: - logger.info("Checking Gemini API key") - if not self._api_key: - logger.warning("No API key configured for Gemini") - return False - logger.info("Gemini configuration validated") - return True - else: - logger.warning(f"Unknown provider type: {self._provider_type}") - return False - - def _check_ollama_availability(self): - """Check if Ollama is available and has vision models.""" - try: - import requests - # Check if Ollama is running at the configured endpoint - endpoint_url = f"{self._ollama_endpoint}/api/version" - response = requests.get(endpoint_url, timeout=5) - if response.status_code == 200: - logger.info(f"Ollama service is available at {self._ollama_endpoint}") - return True - else: - logger.warning(f"Ollama service not responding at {self._ollama_endpoint}") - return False - except Exception as e: - logger.warning(f"Ollama not available at {self._ollama_endpoint}: {e}") - return False - - def _check_claude_code_availability(self): - """Check if Claude Code CLI is available.""" - try: - import subprocess - import shutil - - # First check if claude command exists in PATH - if not shutil.which('claude'): - logger.warning("Claude Code CLI not found in PATH") - return False - - # Quick test to see if it responds - result = subprocess.run(['claude', '--version'], - capture_output=True, text=True, timeout=5) - if result.returncode == 0: - logger.info("Claude Code CLI is available") - return True - else: - logger.warning(f"Claude Code CLI not responding: {result.stderr}") - return False - except subprocess.TimeoutExpired: - logger.warning("Claude Code CLI timeout") - return False - except Exception as e: - logger.warning(f"Claude Code CLI not available: {e}") - return False - - def _check_codex_availability(self): - """Check if Codex CLI is available.""" - try: - import subprocess - import shutil - - codex_path = shutil.which('codex') - if not codex_path and os.path.isfile('/usr/bin/codex'): - codex_path = '/usr/bin/codex' - - if not codex_path: - logger.warning("Codex CLI not found in PATH") - return False - - result = subprocess.run([codex_path, '--version'], - capture_output=True, text=True, timeout=5) - if result.returncode == 0: - logger.info("Codex CLI is available") - return True - else: - logger.warning(f"Codex CLI not responding: {result.stderr}") - return False - except subprocess.TimeoutExpired: - logger.warning("Codex CLI timeout") - return False - except Exception as e: - logger.warning(f"Codex CLI not available: {e}") - return False - - def _initialize_ai_provider(self): - """Initialize the AI provider based on settings.""" - try: - if self._provider_type == settings.AI_PROVIDER_CLAUDE_CODE: - self._ai_provider = create_provider("claude_code") - elif self._provider_type == settings.AI_PROVIDER_CODEX: - self._ai_provider = create_provider("codex") - elif self._provider_type == settings.AI_PROVIDER_OLLAMA: - self._ai_provider = create_provider("ollama", model=self._ollama_model, base_url=self._ollama_endpoint) - elif self._provider_type == settings.AI_PROVIDER_GEMINI: - self._ai_provider = create_provider("gemini", api_key=self._api_key) - else: - logger.error(f"Unsupported provider type: {self._provider_type}") - return False - - logger.info(f"AI provider initialized: {self._provider_type}") - return True - - except Exception as e: - logger.error(f"Error initializing AI provider: {e}") - return False - - def _register_keybindings(self): - """Register AI Assistant menu keybinding.""" - try: - # Single keybinding to show AI Assistant menu - self._kb_binding_menu = self.registerGestureByString( - self._show_ai_menu, - "Show AI Assistant menu", - 'kb:cthulhu+shift+control+a' - ) - - logger.info("AI Assistant menu keybinding registered") - - except Exception as e: - logger.error(f"Error registering AI menu keybinding: {e}") - - def _unregister_keybindings(self): - """Unregister AI Assistant keybindings.""" - # Keybindings are automatically cleaned up when plugin deactivates - self._kb_binding_menu = None - self._menu_gui = None - - def _show_ai_menu(self, script=None, inputEvent=None): - """Show the AI Assistant menu.""" - try: - logger.info("AI ASSISTANT: _show_ai_menu called!") - - # IMPORTANT: Capture screen data BEFORE showing menu - # This ensures we get the actual screen content, not the menu itself - self._pre_menu_screen_data = self._collect_ai_data() - logger.info("Pre-captured screen data for menu actions") - - # Now show the menu - self._menu_gui = AIAssistantMenu(self._handle_menu_selection) - self._menu_gui.show_gui() - return True - except Exception as e: - logger.error(f"Error showing AI menu: {e}") - import traceback - traceback.print_exc() - return False - - def _handle_menu_selection(self, action_id): - """Handle AI Assistant menu selection.""" - try: - logger.info(f"AI menu selection: {action_id}") - - if action_id == "ask_question": - self._handle_ai_question_with_data(self._pre_menu_screen_data) - elif action_id == "describe_screen": - self._handle_ai_describe_with_data(self._pre_menu_screen_data) - elif action_id == "request_action": - self._handle_ai_activate_with_data(self._pre_menu_screen_data) - elif action_id == "analyze_images": - self._handle_ai_image_analysis_with_data(self._pre_menu_screen_data) - elif action_id == "browse_image_file": - self._handle_browse_image_file() - else: - logger.warning(f"Unknown AI menu action: {action_id}") - - except Exception as e: - logger.error(f"Error handling menu selection {action_id}: {e}") - - def _handle_ai_image_analysis_with_data(self, data): - """Handle AI image analysis request with pre-captured data.""" - try: - logger.info("AI image analysis requested with pre-captured data") - - if not self._enabled: - self._present_message("AI Assistant is not enabled") - return True - - if not self._ai_provider: - self._present_message("AI provider not available. Check configuration.") - return True - - if not data: - self._present_message("No screen data available for image analysis") - return True - - provider_name = self._provider_type.replace('_', ' ').title() - self._present_message(f"AI Assistant ({provider_name}) analyzing images...") - - # Use AI to analyze images on screen - try: - response = self._ai_provider.analyze_images(None, - data.get("screenshot"), - data.get("accessibility")) - self._show_description_dialog(response) - except Exception as e: - logger.error(f"Error getting AI image analysis: {e}") - self._present_message(f"Error getting AI image analysis: {e}") - - return True - - except Exception as e: - logger.error(f"Error in image analysis with data: {e}") - self._present_message(f"Error analyzing images: {e}") - return False - - def _handle_browse_image_file(self): - """Handle browsing for an image file to analyze.""" - try: - logger.info("AI image file browsing requested") - - if not self._enabled: - self._present_message("AI Assistant is not enabled") - return True - - if not self._ai_provider: - self._present_message("AI provider not available. Check configuration.") - return True - - # Show file chooser dialog - image_file = self._show_image_file_chooser() - - if image_file: - provider_name = self._provider_type.replace('_', ' ').title() - self._present_message(f"AI Assistant ({provider_name}) analyzing selected image...") - - # Load and analyze the image file - try: - image_data = self._load_image_file(image_file) - if image_data: - # For file browsing, use a special prompt to avoid confusion - response = self._ai_provider.analyze_images("ANALYZE_SINGLE_IMAGE_FILE", image_data, {}) - self._show_description_dialog(response) - else: - self._present_message("Could not load the selected image file") - except Exception as e: - logger.error(f"Error analyzing image file: {e}") - self._present_message(f"Error analyzing image file: {e}") - else: - self._present_message("No image file selected") - - return True - - except Exception as e: - logger.error(f"Error in browse image file: {e}") - self._present_message(f"Error browsing for image file: {e}") - return False - - def _handle_ai_describe_with_data(self, data): - """Handle AI screen description request with pre-captured data.""" - try: - logger.info("AI screen description requested with pre-captured data") - - if not self._enabled: - self._present_message("AI Assistant is not enabled") - return True - - # Use AI to describe the current screen - if not self._ai_provider: - self._present_message("AI provider not available. Check configuration.") - return True - - provider_name = self._provider_type.replace('_', ' ').title() - self._present_message(f"AI Assistant ({provider_name}) analyzing screen...") - - # Use pre-captured data - if data: - try: - response = self._ai_provider.describe_screen( - data.get('screenshot'), - data.get('accessibility') - ) - self._show_description_dialog(response) - except Exception as e: - logger.error(f"Error getting AI screen description: {e}") - self._present_message(f"Error getting AI screen description: {e}") - else: - self._present_message("Could not collect screen data for analysis") - - return True - except Exception as e: - logger.error(f"Error in AI describe handler: {e}") - return False - - def _handle_ai_question_with_data(self, data): - """Handle AI question request with pre-captured data.""" - try: - logger.info("AI question requested with pre-captured data") - - if not self._enabled: - self._present_message("AI Assistant is not enabled") - return True - - if not self._ai_provider: - self._present_message("AI provider not available. Check configuration.") - return True - - # Store the pre-captured data for use by the question dialog - self._current_screen_data = data - - # Show question dialog - self._show_question_dialog() - return True - except Exception as e: - logger.error(f"Error in AI question handler: {e}") - return False - - def _handle_ai_activate_with_data(self, data): - """Handle AI action request with pre-captured data.""" - try: - logger.info("AI action requested with pre-captured data") - - if not self._enabled: - self._present_message("AI Assistant is not enabled") - return True - - if not self._ai_provider: - self._present_message("AI provider not available. Check configuration.") - return True - - # Store the pre-captured data for use by the action dialog - self._current_screen_data = data - - # Show action dialog - self._show_action_dialog() - return True - except Exception as e: - logger.error(f"Error in AI action handler: {e}") - return False - - def _handle_ai_activate(self, script=None, inputEvent=None): - """Handle main AI Assistant activation - now shows action dialog.""" - try: - logger.info("AI Assistant activation requested") - - if not self._enabled: - self._present_message("AI Assistant is not enabled") - return True - - if not self._ai_provider: - self._present_message("AI provider not available. Check configuration.") - return True - - # NEW: Show action request dialog for Phase 5 - self._present_message("AI Assistant capturing screen data for action...") - self._current_screen_data = self._collect_ai_data() - - if not self._current_screen_data: - self._present_message("Could not collect screen data for action") - return True - - # Show action request dialog - self._show_action_dialog() - - return True - - except Exception as e: - logger.error(f"Error in AI activate handler: {e}") - return False - - def _handle_ai_question(self, script=None, inputEvent=None): - """Handle AI question request.""" - try: - logger.info("AI question requested") - - if not self._enabled: - self._present_message("AI Assistant is not enabled") - return True - - if not self._ai_provider: - self._present_message("AI provider not available. Check configuration.") - return True - - # IMPORTANT: Collect screen data BEFORE opening dialog - # This captures the actual window the user is asking about - self._present_message("AI Assistant capturing screen data...") - self._current_screen_data = self._collect_ai_data() - - if not self._current_screen_data: - self._present_message("Could not collect screen data for analysis") - return True - - # Now show question dialog - self._show_question_dialog() - - return True - - except Exception as e: - logger.error(f"Error in AI question handler: {e}") - return False - - def _handle_ai_describe(self, script=None, inputEvent=None): - """Handle AI screen description request.""" - try: - logger.info("AI screen description requested") - - if not self._enabled: - self._present_message("AI Assistant is not enabled") - return True - - # Use AI to describe the current screen - if not self._ai_provider: - self._present_message("AI provider not available. Check configuration.") - return True - - provider_name = self._provider_type.replace('_', ' ').title() - self._present_message(f"AI Assistant ({provider_name}) analyzing screen...") - - # Collect data and get AI description - data = self._collect_ai_data() - if data: - try: - response = self._ai_provider.describe_screen( - data.get('screenshot'), - data.get('accessibility') - ) - self._show_description_dialog(response) - except Exception as e: - logger.error(f"Error getting AI screen description: {e}") - self._present_message(f"Error getting AI screen description: {e}") - else: - self._present_message("Could not collect screen data for analysis") - - return True - - except Exception as e: - logger.error(f"Error in AI describe handler: {e}") - return False - - def _present_message(self, message): - """Present a message to the user via speech.""" - try: - if self.app: - state = self.app.getDynamicApiManager().getAPI('CthulhuState') - if state and state.activeScript: - state.activeScript.presentMessage(message, resetStyles=False) - else: - logger.warning("No active script available for message presentation") - else: - logger.warning("No app reference available for message presentation") - except Exception as e: - logger.error(f"Error presenting message: {e}") - - def _capture_screenshot(self): - """Capture a screenshot of the current display.""" - try: - # Get the default display and root window - display = Gdk.Display.get_default() - if not display: - logger.error("No display available for screenshot") - return None - - screen = display.get_default_screen() - root_window = screen.get_root_window() - - # Get screen dimensions - width = screen.get_width() - height = screen.get_height() - - # Capture the screenshot - pixbuf = Gdk.pixbuf_get_from_window(root_window, 0, 0, width, height) - - if not pixbuf: - logger.error("Failed to capture screenshot") - return None - - # Convert to base64 for AI transmission - success, buffer = pixbuf.save_to_bufferv("png", [], []) - if not success: - logger.error("Failed to save pixbuf to buffer") - return None - image_data = base64.b64encode(buffer).decode('utf-8') - - logger.info(f"Screenshot captured: {width}x{height}") - return { - 'format': 'png', - 'width': width, - 'height': height, - 'data': image_data - } - - except Exception as e: - logger.error(f"Error capturing screenshot: {e}") - return None - - def _get_accessibility_tree(self): - """Get accessibility tree information for the current focus.""" - try: - # Get the current focus object - focus_obj = cthulhu_state.locusOfFocus - if not focus_obj: - logger.warning("No focus object available") - return None - - # Collect accessibility information - tree_data = { - 'focus': self._serialize_ax_object(focus_obj), - 'context': [], - 'actionable_elements': [] # New: For action system - } - - # Get parent context (up to 3 levels) - parent = ax_object.AXObject.get_parent(focus_obj) - level = 0 - while parent and level < 3: - tree_data['context'].append(self._serialize_ax_object(parent)) - parent = ax_object.AXObject.get_parent(parent) - level += 1 - - # Get children of focus (if any) - child_count = ax_object.AXObject.get_child_count(focus_obj) - if child_count > 0: - children = [] - for i in range(min(child_count, 10)): # Limit to first 10 - child = ax_object.AXObject.get_child(focus_obj, i) - if child: - children.append(self._serialize_ax_object(child)) - if children: - tree_data['children'] = children - - # NEW: Collect actionable elements for AI actions - tree_data['actionable_elements'] = self._collect_actionable_elements() - - logger.info(f"Accessibility tree collected for {ax_object.AXObject.get_name(focus_obj) or 'unnamed object'}") - return tree_data - - except Exception as e: - logger.error(f"Error getting accessibility tree: {e}") - return None - - def _serialize_ax_object(self, obj, include_actions=False): - """Serialize an accessibility object to JSON-compatible format.""" - try: - if not obj: - return None - - data = { - 'name': ax_object.AXObject.get_name(obj) or '', - 'role': ax_object.AXObject.get_role_name(obj) or '', - 'description': ax_object.AXObject.get_description(obj) or '', - 'text': self._get_object_text(obj), - 'value': self._get_object_value(obj), - 'states': self._get_object_states(obj), - 'attributes': self._get_object_attributes(obj), - 'position': self._get_object_position(obj) - } - - # Include action information for actionable elements - if include_actions: - data['actions'] = self._get_object_actions(obj) - data['is_actionable'] = self._is_actionable_element(obj) - data['action_coordinates'] = self._get_action_coordinates(obj) - - return data - - except Exception as e: - logger.error(f"Error serializing accessibility object: {e}") - return None - - def _get_object_text(self, obj): - """Get text content from an accessibility object.""" - try: - # Use script utilities to get displayed text if available - if cthulhu_state.activeScript and hasattr(cthulhu_state.activeScript, 'utilities'): - try: - text = cthulhu_state.activeScript.utilities.displayedText(obj) - if text: - return text.strip() - except: - pass - - # Fallback: try direct AT-SPI text interface - if ax_object.AXObject.supports_text(obj): - text = AXText.get_all_text(obj) - if text: - return text.strip() - - return "" - - except Exception as e: - logger.error(f"Error getting object text: {e}") - return "" - - def _get_object_value(self, obj): - """Get value from an accessibility object.""" - try: - if ax_object.AXObject.supports_value(obj): - value = AXValue.get_current_value(obj) - return str(value) if value is not None else "" - return "" - - except Exception as e: - logger.error(f"Error getting object value: {e}") - return "" - - def _get_object_states(self, obj): - """Get state information from an accessibility object.""" - try: - states = [] - if AXUtilitiesState.is_focused(obj): - states.append("focused") - if AXUtilitiesState.is_selected(obj): - states.append("selected") - if AXUtilitiesState.is_expanded(obj): - states.append("expanded") - if AXUtilitiesState.is_checked(obj): - states.append("checked") - if AXUtilitiesState.is_sensitive(obj): - states.append("sensitive") - if AXUtilitiesState.is_showing(obj): - states.append("showing") - if AXUtilitiesState.is_visible(obj): - states.append("visible") - - return states - - except Exception as e: - logger.error(f"Error getting object states: {e}") - return [] - - def _get_object_attributes(self, obj): - """Get attributes from an accessibility object.""" - try: - attrs = {} - - # Get object attributes from AT-SPI - try: - if hasattr(obj, 'get_attributes'): - obj_attrs = obj.get_attributes() - if obj_attrs: - attrs['object_attributes'] = dict(obj_attrs) - except: - pass - - return attrs - - except Exception as e: - logger.error(f"Error getting object attributes: {e}") - return {} - - def _get_object_position(self, obj): - """Get position and size information from an accessibility object.""" - try: - if ax_object.AXObject.supports_component(obj): - extents = Atspi.Component.get_extents(obj, Atspi.CoordType.SCREEN) - return { - 'x': extents.x, - 'y': extents.y, - 'width': extents.width, - 'height': extents.height - } - return None - - except Exception as e: - logger.error(f"Error getting object position: {e}") - return None - - def _collect_ai_data(self): - """Collect both screenshot and accessibility data for AI analysis.""" - try: - logger.info("Collecting AI data (screenshot + accessibility tree)") - - # Collect both types of data - screenshot = self._capture_screenshot() - accessibility_tree = self._get_accessibility_tree() - - data = { - 'timestamp': __import__('time').time(), - 'screenshot': screenshot, - 'accessibility': accessibility_tree - } - - # Add current application context - if cthulhu_state.activeScript: - app_name = getattr(cthulhu_state.activeScript, 'name', 'unknown') - data['application'] = app_name - - logger.info("AI data collection completed") - return data - - except Exception as e: - logger.error(f"Error collecting AI data: {e}") - return None - - def _show_question_dialog(self): - """Show a dialog for the user to enter their question.""" - try: - provider_name = self._provider_type.replace('_', ' ').title() - dialog = Gtk.Dialog( - title=f"AI Assistant Question ({provider_name})", - parent=None, - flags=Gtk.DialogFlags.MODAL, - buttons=( - Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, - Gtk.STOCK_OK, Gtk.ResponseType.OK - ) - ) - - dialog.set_default_size(500, 200) - - # Create the question entry - content_area = dialog.get_content_area() - - label = Gtk.Label(label="Enter your question about the current screen:") - label.set_halign(Gtk.Align.START) - content_area.pack_start(label, False, False, 10) - - entry = Gtk.Entry() - entry.set_placeholder_text("What would you like to know?") - entry.set_activates_default(True) - content_area.pack_start(entry, False, False, 10) - - dialog.set_default_response(Gtk.ResponseType.OK) - # Show all widgets including buttons - dialog.show_all() - - # Set focus to the entry - entry.grab_focus() - - response = dialog.run() - - if response == Gtk.ResponseType.OK: - question = entry.get_text().strip() - if question: - # Transform dialog to show processing and response - self._transform_dialog_for_response(dialog, question) - else: - dialog.destroy() - self._present_message("No question entered") - else: - dialog.destroy() - self._present_message("Question cancelled") - - except Exception as e: - logger.error(f"Error showing question dialog: {e}") - self._present_message(f"Error showing question dialog: {e}") - - def _transform_dialog_for_response(self, dialog, question): - """Transform the question dialog to show AI processing and response.""" - try: - # Clear existing content - content_area = dialog.get_content_area() - for child in content_area.get_children(): - content_area.remove(child) - - # Remove existing buttons - for child in dialog.get_action_area().get_children(): - dialog.get_action_area().remove(child) - - # Change title - provider_name = self._provider_type.replace('_', ' ').title() - dialog.set_title(f"AI Assistant Response ({provider_name})") - - # Show question and processing message - question_label = Gtk.Label() - question_label.set_markup(f"Question: {question}") - question_label.set_line_wrap(True) - question_label.set_halign(Gtk.Align.START) - content_area.pack_start(question_label, False, False, 10) - - # Create scrollable text view for response (same as description dialog) - scrolled_window = Gtk.ScrolledWindow() - scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - scrolled_window.set_shadow_type(Gtk.ShadowType.IN) - - self._response_text_view = Gtk.TextView() - self._response_text_view.set_editable(False) # Read-only - self._response_text_view.set_cursor_visible(True) # Allow cursor navigation for screen readers - self._response_text_view.set_wrap_mode(Gtk.WrapMode.WORD) - - # Set initial processing text - text_buffer = self._response_text_view.get_buffer() - text_buffer.set_text("Processing your question...") - - scrolled_window.add(self._response_text_view) - content_area.pack_start(scrolled_window, True, True, 10) - - # Add close button - close_button = dialog.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) - dialog.set_default_response(Gtk.ResponseType.CLOSE) - - # Resize for response content - dialog.set_default_size(600, 400) - dialog.show_all() - - # Focus the response text view so screen reader announces it - self._response_text_view.grab_focus() - - # Process question asynchronously - self._process_user_question_async(dialog, question) - - except Exception as e: - logger.error(f"Error transforming dialog: {e}") - dialog.destroy() - self._present_message(f"Error showing response: {e}") - - def _process_user_question_async(self, dialog, question): - """Process the user's question and update dialog with response.""" - try: - # Use the pre-captured screen data (captured before dialog opened) - data = self._current_screen_data - if data: - try: - response = self._ai_provider.answer_question( - question, - data.get('screenshot'), - data.get('accessibility') - ) - - # Update the response text view - text_buffer = self._response_text_view.get_buffer() - text_buffer.set_text(f"Response:\n{response}") - - # Also speak the response - self._present_message(response) - - # Set up dialog close handler - def on_response(dialog, response_id): - dialog.destroy() - - dialog.connect("response", on_response) - - except Exception as e: - logger.error(f"Error getting AI response: {e}") - text_buffer = self._response_text_view.get_buffer() - text_buffer.set_text(f"Error: {e}") - self._present_message(f"Error getting AI response: {e}") - else: - text_buffer = self._response_text_view.get_buffer() - text_buffer.set_text("Error: No screen data available") - self._present_message("No screen data available") - - except Exception as e: - logger.error(f"Error processing user question: {e}") - text_buffer = self._response_text_view.get_buffer() - text_buffer.set_text(f"Error: {e}") - self._present_message(f"Error processing question: {e}") - - # ============================================================================ - def _show_description_dialog(self, description): - """Show a read-only dialog with the screen description.""" - try: - provider_name = self._provider_type.replace('_', ' ').title() - dialog = Gtk.Dialog( - title=f"AI Screen Description ({provider_name})", - parent=None, - flags=Gtk.DialogFlags.MODAL, - buttons=(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) - ) - - dialog.set_default_size(600, 400) - - content_area = dialog.get_content_area() - - # Create scrollable text view - scrolled_window = Gtk.ScrolledWindow() - scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - scrolled_window.set_shadow_type(Gtk.ShadowType.IN) - - text_view = Gtk.TextView() - text_view.set_editable(False) # Read-only - text_view.set_cursor_visible(True) # Allow cursor navigation for screen readers - text_view.set_wrap_mode(Gtk.WrapMode.WORD) - - # Set the description text - text_buffer = text_view.get_buffer() - text_buffer.set_text(description) - - scrolled_window.add(text_view) - content_area.pack_start(scrolled_window, True, True, 10) - - dialog.set_default_response(Gtk.ResponseType.CLOSE) - dialog.show_all() - - # Focus the text view so screen reader reads the content - text_view.grab_focus() - - # Show dialog and wait for user to close - response = dialog.run() - dialog.destroy() - - except Exception as e: - logger.error(f"Error showing description dialog: {e}") - self._present_message(f"Error showing description: {e}") - - # NEW: Action System Methods for Phase 5 - # ============================================================================ - - def _collect_actionable_elements(self): - """Collect all actionable elements in the current window for AI analysis.""" - try: - logger.info("Collecting actionable elements for action system") - actionable_elements = [] - - # Get the current application's window - if not cthulhu_state.activeScript: - return actionable_elements - - # Start from the application root - app = cthulhu_state.activeScript.app - if not app: - return actionable_elements - - # Recursively find actionable elements - self._find_actionable_elements_recursive(app, actionable_elements, max_depth=5) - - logger.info(f"Found {len(actionable_elements)} actionable elements") - return actionable_elements - - except Exception as e: - logger.error(f"Error collecting actionable elements: {e}") - return [] - - def _find_actionable_elements_recursive(self, obj, actionable_elements, current_depth=0, max_depth=5): - """Recursively find actionable elements in the accessibility tree.""" - try: - if current_depth >= max_depth: - return - - if not obj: - return - - # Check if this element is actionable - if self._is_actionable_element(obj): - element_data = self._serialize_ax_object(obj, include_actions=True) - if element_data and element_data.get('is_actionable'): - actionable_elements.append(element_data) - - # Recurse through children - try: - child_count = ax_object.AXObject.get_child_count(obj) - for i in range(min(child_count, 20)): # Limit children to prevent overflow - child = ax_object.AXObject.get_child(obj, i) - if child: - self._find_actionable_elements_recursive( - child, actionable_elements, current_depth + 1, max_depth - ) - except: - pass - - except Exception as e: - logger.debug(f"Error in recursive element search: {e}") - - def _is_actionable_element(self, obj): - """Determine if an accessibility object is actionable for AI operations.""" - try: - if not obj: - return False - - # Get role and states - role = ax_object.AXObject.get_role_name(obj) - states = self._get_object_states(obj) - - # Define actionable roles - actionable_roles = { - 'push button', 'button', 'toggle button', 'radio button', 'check box', - 'menu item', 'list item', 'tree item', 'tab', 'link', 'entry', 'text', - 'password text', 'combo box', 'spin button', 'slider', 'scroll bar' - } - - # Check if role is actionable - if role and role.lower() in actionable_roles: - # Additional checks for enabled/visible states - if states: - state_names = [state.lower() for state in states] - # Element must be enabled and visible - if 'enabled' in state_names and 'visible' in state_names: - return True - - # Check for specific action interfaces - try: - actions = self._get_object_actions(obj) - if actions and len(actions) > 0: - return True - except: - pass - - return False - - except Exception as e: - logger.debug(f"Error checking if element is actionable: {e}") - return False - - def _get_object_actions(self, obj): - """Get available actions for an accessibility object.""" - try: - actions = [] - - # Check for AT-SPI action interface - if ax_object.AXObject.supports_action(obj): - try: - action_count = Atspi.Action.get_n_actions(obj) - except Exception: - action_count = 0 - for i in range(action_count): - try: - action_name = Atspi.Action.get_name(obj, i) - except Exception: - action_name = "" - try: - action_desc = Atspi.Action.get_description(obj, i) - except Exception: - action_desc = "" - actions.append({ - 'name': action_name or '', - 'description': action_desc or '', - 'index': i - }) - - return actions - - except Exception as e: - logger.debug(f"Error getting object actions: {e}") - return [] - - def _get_action_coordinates(self, obj): - """Get coordinates for performing actions on an object.""" - try: - position = self._get_object_position(obj) - if position and 'x' in position and 'y' in position: - # Calculate center point for clicking - center_x = position['x'] + (position.get('width', 0) // 2) - center_y = position['y'] + (position.get('height', 0) // 2) - - return { - 'center_x': center_x, - 'center_y': center_y, - 'bounds': position - } - - return None - - except Exception as e: - logger.debug(f"Error getting action coordinates: {e}") - return None - - # ============================================================================ - # Action Dialog and Execution Methods - # ============================================================================ - - def _show_action_dialog(self): - """Show dialog for entering action requests or analyzing images.""" - try: - # Create dialog without parent first - dialog = Gtk.Dialog( - title="AI Assistant Actions", - flags=Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, - buttons=( - Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, - "Analyze", Gtk.ResponseType.OK - ) - ) - - # Make dialog fully accessible - dialog.set_resizable(True) - dialog.set_modal(True) - dialog.set_type_hint(Gdk.WindowTypeHint.DIALOG) - - dialog.set_default_size(600, 350) - - content_area = dialog.get_content_area() - - # Mode selection radio buttons - mode_label = Gtk.Label() - mode_label.set_markup("Choose analysis mode:") - mode_label.set_halign(Gtk.Align.START) - content_area.pack_start(mode_label, False, False, 10) - - # Action mode radio button (default) - action_radio = Gtk.RadioButton(label="Request an action") - action_radio.set_active(True) - content_area.pack_start(action_radio, False, False, 5) - - # Image analysis mode radio button - image_radio = Gtk.RadioButton.new_with_label_from_widget(action_radio, "Analyze image content") - content_area.pack_start(image_radio, False, False, 5) - - # Instruction label - instruction_label = Gtk.Label() - instruction_label.set_markup("Tell the AI what you want to do:\n" + - "Examples: 'Click the Continue button', 'Enter storm into username field', " + - "'Copy this text to clipboard'") - instruction_label.set_line_wrap(True) - instruction_label.set_halign(Gtk.Align.START) - content_area.pack_start(instruction_label, False, False, 10) - - # Action entry - entry = Gtk.Entry() - entry.set_placeholder_text("What would you like me to do?") - entry.set_activates_default(True) - content_area.pack_start(entry, False, False, 10) - - # Update UI based on radio button selection - def on_radio_toggled(radio_button): - if action_radio.get_active(): - instruction_label.set_markup("Tell the AI what you want to do:\n" + - "Examples: 'Click the Continue button', 'Enter storm into username field', " + - "'Copy this text to clipboard'") - entry.set_placeholder_text("What would you like me to do?") - entry.set_sensitive(True) - else: # image mode - instruction_label.set_markup("Image Analysis Mode:\n" + - "The AI will focus on describing visual content in images on the screen, " + - "ignoring UI elements. Leave text field empty or add specific questions.") - entry.set_placeholder_text("Optional: Ask specific questions about images (leave empty for general description)") - entry.set_sensitive(True) - - action_radio.connect("toggled", on_radio_toggled) - image_radio.connect("toggled", on_radio_toggled) - - dialog.set_default_response(Gtk.ResponseType.OK) - dialog.show_all() - - entry.grab_focus() - - response = dialog.run() - - if response == Gtk.ResponseType.OK: - if image_radio.get_active(): - # Image analysis mode - user_question = entry.get_text().strip() - dialog.destroy() - self._handle_image_analysis(user_question) - else: - # Action request mode - action_request = entry.get_text().strip() - if action_request: - dialog.destroy() - self._show_action_confirmation_dialog(action_request) - else: - dialog.destroy() - self._present_message("No action request entered") - else: - dialog.destroy() - self._present_message("Action request cancelled") - - except Exception as e: - logger.error(f"Error showing action dialog: {e}") - self._present_message(f"Error showing action dialog: {e}") - - def _handle_image_analysis(self, user_question=None): - """Handle image analysis request.""" - try: - logger.info(f"Image analysis requested with question: '{user_question}'") - - self._present_message("AI Assistant analyzing images on screen...") - - # Use existing screen data or collect fresh data - screen_data = self._current_screen_data - if not screen_data: - screen_data = self._collect_ai_data() - - if not screen_data: - self._present_message("Could not collect screen data for image analysis") - return - - # Get image analysis from AI provider - if user_question: - # User has a specific question about images - result = self._ai_provider.analyze_images(user_question, - screen_data.get("screenshot"), - screen_data.get("accessibility")) - else: - # General image description - result = self._ai_provider.analyze_images(None, - screen_data.get("screenshot"), - screen_data.get("accessibility")) - - # Present the result - self._present_message(f"Image analysis complete: {result}") - - except Exception as e: - logger.error(f"Error in image analysis: {e}") - self._present_message(f"Error analyzing images: {e}") - - def _show_action_confirmation_dialog(self, action_request): - """Show a fresh confirmation dialog for the action.""" - try: - # Create completely new dialog - dialog = Gtk.Dialog( - title="AI Assistant - Confirm Action", - flags=Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT - ) - - # Add buttons directly during dialog creation - cancel_button = dialog.add_button("Cancel", Gtk.ResponseType.CANCEL) - execute_button = dialog.add_button("Execute Action", Gtk.ResponseType.ACCEPT) - - # Configure dialog - dialog.set_default_size(600, 400) - dialog.set_resizable(True) - dialog.set_type_hint(Gdk.WindowTypeHint.DIALOG) - - # Configure buttons - execute_button.set_sensitive(False) # Disabled until analysis complete - execute_button.set_can_focus(True) - execute_button.set_can_default(True) - cancel_button.set_can_focus(True) - - dialog.set_default_response(Gtk.ResponseType.ACCEPT) - - content_area = dialog.get_content_area() - - # Status label - status_label = Gtk.Label(label="AI is analyzing your request...") - status_label.set_halign(Gtk.Align.START) - content_area.pack_start(status_label, False, False, 10) - - # Analysis text view - scrolled = Gtk.ScrolledWindow() - scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - scrolled.set_size_request(550, 300) - - text_view = Gtk.TextView() - text_view.set_editable(False) - text_view.set_wrap_mode(Gtk.WrapMode.WORD) - scrolled.add(text_view) - content_area.pack_start(scrolled, True, True, 10) - - # Store references for updating - self._action_dialog = dialog - self._action_status_label = status_label - self._action_text_view = text_view - self._action_execute_button = execute_button - self._current_action_request = action_request - - # Show everything - dialog.show_all() - - # Set up response handler - def on_response(dialog, response_id): - if response_id == Gtk.ResponseType.ACCEPT: - # Execute the confirmed action - if hasattr(self, '_parsed_action'): - # Close dialog FIRST, then execute action - dialog.destroy() - # Add small delay to let dialog close - from gi.repository import GLib - GLib.timeout_add(500, lambda: self._execute_confirmed_action(self._parsed_action)) - else: - dialog.destroy() - - dialog.connect("response", on_response) - - # Start AI analysis in background - import threading - analysis_thread = threading.Thread( - target=self._analyze_action_request, - args=(action_request,) - ) - analysis_thread.daemon = True - analysis_thread.start() - - # Show dialog (non-blocking) - dialog.present() - - except Exception as e: - logger.error(f"Error showing confirmation dialog: {e}") - self._present_message(f"Error showing confirmation dialog: {e}") - - def _transform_dialog_for_action_analysis(self, dialog, action_request): - """Transform action dialog to show AI analysis and confirmation.""" - try: - # Clear existing content - content_area = dialog.get_content_area() - for child in content_area.get_children(): - content_area.remove(child) - - # Clear existing buttons and add new ones - action_area = dialog.get_action_area() - for child in action_area.get_children(): - child.destroy() # Use destroy instead of remove - - # Add new buttons with proper accessibility - cancel_button = Gtk.Button.new_with_label("Cancel") - execute_button = Gtk.Button.new_with_label("Execute Action") - - # Set up button responses - cancel_button.connect("clicked", lambda b: dialog.response(Gtk.ResponseType.CANCEL)) - execute_button.connect("clicked", lambda b: dialog.response(Gtk.ResponseType.ACCEPT)) - - # Add buttons to action area - action_area.pack_start(cancel_button, False, False, 0) - action_area.pack_start(execute_button, False, False, 0) - - # Make buttons accessible and focusable - cancel_button.set_can_focus(True) - execute_button.set_can_focus(True) - execute_button.set_sensitive(False) # Disabled until analysis complete - - # Set default response for Enter key - dialog.set_default_response(Gtk.ResponseType.ACCEPT) - execute_button.set_can_default(True) - execute_button.grab_default() - - # Status label - status_label = Gtk.Label(label="AI is analyzing your request...") - status_label.set_halign(Gtk.Align.START) - content_area.pack_start(status_label, False, False, 10) - - # Analysis text view - scrolled = Gtk.ScrolledWindow() - scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - scrolled.set_size_request(550, 200) - - text_view = Gtk.TextView() - text_view.set_editable(False) - text_view.set_wrap_mode(Gtk.WrapMode.WORD) - scrolled.add(text_view) - content_area.pack_start(scrolled, True, True, 10) - - # Store references for updating - self._action_dialog = dialog - self._action_status_label = status_label - self._action_text_view = text_view - self._action_execute_button = execute_button - self._current_action_request = action_request - - # Show all widgets including new buttons - cancel_button.show() - execute_button.show() - dialog.show_all() - - # Start AI analysis in background - import threading - analysis_thread = threading.Thread( - target=self._analyze_action_request, - args=(action_request,) - ) - analysis_thread.daemon = True - analysis_thread.start() - - # Set up response handlers - def on_response(dialog, response_id): - if response_id == Gtk.ResponseType.ACCEPT: - # Execute the confirmed action - if hasattr(self, '_parsed_action'): - self._execute_confirmed_action(self._parsed_action) - dialog.destroy() - - dialog.connect("response", on_response) - - except Exception as e: - logger.error(f"Error transforming action dialog: {e}") - dialog.destroy() - self._present_message(f"Error in action dialog: {e}") - - def _analyze_action_request(self, action_request): - """Analyze action request using AI (runs in background thread).""" - try: - logger.info(f"Analyzing action request: {action_request}") - - # Use AI to analyze the request - analysis = self._ai_provider.suggest_actions( - action_request, - self._current_screen_data.get('screenshot'), - self._current_screen_data.get('accessibility') - ) - - # Update UI on main thread - from gi.repository import GLib - GLib.idle_add(self._update_action_analysis, analysis) - - except Exception as e: - logger.error(f"Error analyzing action request: {e}") - from gi.repository import GLib - GLib.idle_add(self._update_action_analysis, f"Error analyzing request: {e}") - - def _update_action_analysis(self, analysis): - """Update action dialog with AI analysis results.""" - try: - if not hasattr(self, '_action_dialog'): - return False - - # Update status - self._action_status_label.set_text("AI Analysis Complete:") - - # Update analysis text - buffer = self._action_text_view.get_buffer() - buffer.set_text(analysis) - - # Enable execute button if analysis looks successful - if not analysis.startswith("Error"): - self._action_execute_button.set_sensitive(True) - self._parsed_action = self._parse_action_response(analysis) - # Set focus to execute button so user can press Enter - self._action_execute_button.grab_focus() - self._action_execute_button.grab_default() - logger.info("Execute button enabled and focused") - else: - logger.error(f"Analysis failed: {analysis}") - - self._present_message("Action analysis complete. Review and confirm in dialog. Press Tab to navigate, Enter to execute, Escape to cancel.") - - except Exception as e: - logger.error(f"Error updating action analysis: {e}") - - return False # Don't repeat idle callback - - def _parse_action_response(self, analysis): - """Parse AI action response into executable commands.""" - try: - # Look for structured ACTION TYPE in AI response - action_data = { - 'type': 'unknown', - 'target': None, - 'value': None, - 'coordinates': None, - 'description': analysis - } - - analysis_lower = analysis.lower() - - # Look for explicit ACTION TYPE markers first - if '**action type**:' in analysis_lower: - import re - action_type_match = re.search(r'\*\*action type\*\*:\s*(\w+)', analysis_lower) - if action_type_match: - action_type = action_type_match.group(1).lower() - if action_type in ['click', 'type', 'copy', 'scroll', 'navigate']: - action_data['type'] = action_type - logger.info(f"Detected action type from AI response: {action_type}") - return action_data - - # Fallback: Look for action keywords in the original user request - if hasattr(self, '_current_action_request'): - request_lower = self._current_action_request.lower() - logger.info(f"Parsing user request: {self._current_action_request}") - - # Check user request directly - if 'copy' in request_lower and 'clipboard' in request_lower: - action_data['type'] = 'copy' - logger.info("Detected COPY action from user request") - elif 'type' in request_lower or 'enter' in request_lower: - action_data['type'] = 'type' - logger.info("Detected TYPE action from user request") - elif 'click' in request_lower: - action_data['type'] = 'click' - logger.info("Detected CLICK action from user request") - - # Final fallback: analyze AI response content - if action_data['type'] == 'unknown': - if 'click' in analysis_lower: - action_data['type'] = 'click' - elif 'type' in analysis_lower or 'typewrite' in analysis_lower: - action_data['type'] = 'type' - elif 'copy' in analysis_lower or 'clipboard' in analysis_lower: - action_data['type'] = 'copy' - - logger.info(f"Final parsed action type: {action_data['type']}") - return action_data - - except Exception as e: - logger.error(f"Error parsing action response: {e}") - return {'type': 'error', 'description': str(e)} - - def _execute_confirmed_action(self, action_data): - """Execute the user-confirmed action.""" - try: - logger.info(f"Executing confirmed action: {action_data}") - - action_type = action_data.get('type', 'unknown') - - if action_type == 'click': - result = self._perform_click_action(action_data) - elif action_type == 'type': - result = self._perform_type_action(action_data) - elif action_type == 'copy': - result = self._perform_copy_action(action_data) - else: - result = f"Unknown action type: {action_type}" - - self._present_message(f"Action result: {result}") - - except Exception as e: - logger.error(f"Error executing action: {e}") - self._present_message(f"Error executing action: {e}") - - def _perform_click_action(self, action_data): - """Perform a click action on a UI element.""" - try: - # Try PyAutoGUI for universal clicking - import pyautogui - - # Extract coordinates from action_data or current screen data - coords = action_data.get('coordinates') - if not coords and hasattr(self, '_current_screen_data'): - # Look for actionable elements in the collected data - actionable_elements = self._current_screen_data.get('accessibility', {}).get('actionable_elements', []) - # For now, just click center of screen as fallback - coords = {'center_x': 640, 'center_y': 360} - - if coords: - x, y = coords.get('center_x', 640), coords.get('center_y', 360) - pyautogui.click(x, y) - return f"Clicked at coordinates ({x}, {y})" - else: - return "Could not determine click coordinates" - - except ImportError: - return "PyAutoGUI not available - install with: pip install pyautogui" - except Exception as e: - return f"Click failed: {e}" - - def _perform_type_action(self, action_data): - """Perform a text typing action.""" - try: - import pyautogui - - # Extract text to type from the action description - text_to_type = self._extract_text_from_action(action_data) - logger.info(f"Attempting to type: '{text_to_type}'") - - if text_to_type: - import time - - # Simple approach: Just wait a moment for dialogs to settle, then type - # Since PyAutoGUI works fine when terminal is focused, let's not overthink it - logger.info("Waiting briefly for focus to settle before typing") - time.sleep(1.0) # Give time for any dialogs to close and focus to return - - # Disable PyAutoGUI failsafe for this operation - pyautogui.FAILSAFE = False - - logger.info(f"Starting to type '{text_to_type}' to focused application") - - # Type the text with more reasonable timing - pyautogui.typewrite(text_to_type, interval=0.05) - - # Check if we should press Enter - request_lower = getattr(self, '_current_action_request', '').lower() - description_lower = action_data.get('description', '').lower() - - if ('press enter' in request_lower or 'hit enter' in request_lower or - 'and enter' in request_lower or 'press enter' in description_lower): - time.sleep(0.1) - pyautogui.press('return') - logger.info("Pressed Enter after typing") - return f"Typed '{text_to_type}' and pressed Enter" - else: - return f"Typed '{text_to_type}'" - else: - return "Could not determine text to type" - - except ImportError: - return "PyAutoGUI not available - install with: pip install pyautogui" - except Exception as e: - logger.error(f"Type action failed: {e}") - return f"Type action failed: {e}" - - def _perform_copy_action(self, action_data): - """Perform a copy to clipboard action.""" - try: - # Extract the specific text to copy from the user's request - text_to_copy = self._extract_text_to_copy(action_data) - - if text_to_copy: - # Use direct clipboard manipulation instead of Ctrl+C - import subprocess - - # Use xclip on Linux (works on both X11 and Wayland via XWayland) - try: - process = subprocess.Popen(['xclip', '-selection', 'clipboard'], - stdin=subprocess.PIPE, - text=True) - process.communicate(input=text_to_copy) - return f"Copied '{text_to_copy}' to clipboard" - except FileNotFoundError: - # Fallback to wl-copy for pure Wayland - try: - process = subprocess.Popen(['wl-copy'], - stdin=subprocess.PIPE, - text=True) - process.communicate(input=text_to_copy) - return f"Copied '{text_to_copy}' to clipboard" - except FileNotFoundError: - return "Neither xclip nor wl-copy available for clipboard operations" - else: - # Fallback: try to copy whatever is currently selected - import pyautogui - pyautogui.hotkey('ctrl', 'c') - return "Copied current selection to clipboard" - - except ImportError: - return "Required clipboard tools not available" - except Exception as e: - return f"Copy action failed: {e}" - - def _extract_text_to_copy(self, action_data): - """Extract the specific text to copy from the user request.""" - try: - if hasattr(self, '_current_action_request'): - request = self._current_action_request - request_lower = request.lower() - - # Special case: summarize and copy requests - if 'summar' in request_lower and ('clipboard' in request_lower or 'copy' in request_lower): - summary = self._generate_screen_summary() - if summary: - logger.info("Generated screen summary for clipboard") - return summary - - # Look for quoted text - import re - quoted_matches = re.findall(r'["\']([^"\']+)["\']', request) - if quoted_matches: - return quoted_matches[0] - - # Look for text after "copy" - copy_matches = re.findall(r'copy\s+(.+?)\s+to\s+clipboard', request, re.IGNORECASE) - if copy_matches: - return copy_matches[0].strip('"\'') - - return None - - except Exception as e: - logger.error(f"Error extracting text to copy: {e}") - return None - - def _generate_screen_summary(self): - """Generate a summary of the current screen for clipboard operations.""" - try: - if hasattr(self, '_current_screen_data') and self._current_screen_data: - accessibility_data = self._current_screen_data.get('accessibility', {}) - - # Build a simple summary - summary_parts = [] - - # Application info - app_name = self._current_screen_data.get('application', 'Unknown Application') - summary_parts.append(f"Application: {app_name}") - - # Focus info - focus_info = accessibility_data.get('focus', {}) - if focus_info: - focus_name = focus_info.get('name', '') - focus_role = focus_info.get('role', '') - if focus_name or focus_role: - summary_parts.append(f"Current focus: {focus_name} ({focus_role})") - - # Context info - context = accessibility_data.get('context', []) - if context and len(context) > 0: - parent_info = context[0] - parent_name = parent_info.get('name', '') - parent_role = parent_info.get('role', '') - if parent_name or parent_role: - summary_parts.append(f"In: {parent_name} ({parent_role})") - - # Actionable elements count - actionable_elements = accessibility_data.get('actionable_elements', []) - if actionable_elements: - summary_parts.append(f"Available actions: {len(actionable_elements)} interactive elements") - - if summary_parts: - return '\n'.join(summary_parts) - else: - return f"Screen summary for {app_name} - focused on accessible content" - - return "Unable to generate screen summary - no data available" - - except Exception as e: - logger.error(f"Error generating screen summary: {e}") - return f"Screen summary generation failed: {e}" - - def _extract_text_from_action(self, action_data): - """Extract text to type from action description.""" - try: - # First try the original user request (most reliable) - if hasattr(self, '_current_action_request'): - request = self._current_action_request - logger.info(f"Extracting text from user request: {request}") - - import re - - # Enhanced extraction for commands like "type echo 'hello world'" - if request.lower().startswith('type '): - # Remove "type " from the beginning - text = request[5:].strip() - - # Remove trailing conditions like "and press enter", "in the terminal" - text = re.sub(r'\s+and\s+(press\s+)?enter.*$', '', text, flags=re.IGNORECASE) - text = re.sub(r'\s+in\s+.+$', '', text, flags=re.IGNORECASE) - - logger.info(f"Extracted command after 'type ': '{text}'") - return text - - # Look for quoted text in various formats - quoted_patterns = [ - r'"([^"]*)"', # Double quotes - r"'([^']*)'", # Single quotes - r'`([^`]*)`' # Backticks - ] - - for pattern in quoted_patterns: - matches = re.findall(pattern, request) - if matches: - text = matches[0] - logger.info(f"Found quoted text: '{text}'") - return text - - # Look for text after "type" with flexible matching - type_patterns = [ - r'type\s+(.+?)(?:\s+and\s+|\s+in\s+|\s*$)', # type X and... or type X in... - r'enter\s+(.+?)(?:\s+into\s+|\s*$)', # enter X into... - ] - - for pattern in type_patterns: - matches = re.findall(pattern, request, re.IGNORECASE) - if matches: - text = matches[0].strip() - logger.info(f"Found text with pattern '{pattern}': '{text}'") - return text - - # Fallback: try the AI description for quoted text - description = action_data.get('description', '') - if description: - import re - quoted_matches = re.findall(r'"([^"]*)"', description) - if quoted_matches: - logger.info(f"Found text in AI description: '{quoted_matches[0]}'") - return quoted_matches[0] - - logger.warning("Could not extract text to type") - return None - - except Exception as e: - logger.error(f"Error extracting text from action: {e}") - return None - - def _show_image_file_chooser(self): - """Show a file chooser dialog for selecting an image file.""" - try: - dialog = Gtk.FileChooserDialog( - title="Select Image File", - parent=None, - action=Gtk.FileChooserAction.OPEN - ) - - # Add buttons - dialog.add_button("Cancel", Gtk.ResponseType.CANCEL) - dialog.add_button("Open", Gtk.ResponseType.OK) - - # Set up image file filters - filter_images = Gtk.FileFilter() - filter_images.set_name("Image files") - filter_images.add_mime_type("image/png") - filter_images.add_mime_type("image/jpeg") - filter_images.add_mime_type("image/jpg") - filter_images.add_mime_type("image/gif") - filter_images.add_mime_type("image/bmp") - filter_images.add_mime_type("image/webp") - filter_images.add_pattern("*.png") - filter_images.add_pattern("*.jpg") - filter_images.add_pattern("*.jpeg") - filter_images.add_pattern("*.gif") - filter_images.add_pattern("*.bmp") - filter_images.add_pattern("*.webp") - dialog.add_filter(filter_images) - - # Add "All files" filter as backup - filter_all = Gtk.FileFilter() - filter_all.set_name("All files") - filter_all.add_pattern("*") - dialog.add_filter(filter_all) - - # Run the dialog - response = dialog.run() - - filename = None - if response == Gtk.ResponseType.OK: - filename = dialog.get_filename() - logger.info(f"Selected image file: {filename}") - - dialog.destroy() - return filename - - except Exception as e: - logger.error(f"Error showing image file chooser: {e}") - return None - - def _load_image_file(self, image_path): - """Load an image file and convert it to base64 for AI analysis.""" - try: - import base64 - import os - - # Read the image file - with open(image_path, 'rb') as image_file: - image_data = image_file.read() - - # Convert to base64 - base64_data = base64.b64encode(image_data).decode('utf-8') - - # Determine format from file extension - _, ext = os.path.splitext(image_path.lower()) - format_map = { - '.png': 'png', - '.jpg': 'jpeg', - '.jpeg': 'jpeg', - '.gif': 'gif', - '.bmp': 'bmp', - '.webp': 'webp' - } - image_format = format_map.get(ext, 'png') # Default to png - - logger.info(f"Loaded image file: {image_path} ({len(image_data)} bytes, format: {image_format})") - - # Return same structure as _capture_screenshot - return { - 'format': image_format, - 'width': 0, # We don't know dimensions, but AI doesn't need them - 'height': 0, - 'data': base64_data - } - - except Exception as e: - logger.error(f"Error loading image file {image_path}: {e}") - return None - - -class AIAssistantMenu(Gtk.Dialog): - """A dialog containing AI Assistant options.""" - - def __init__(self, handler): - super().__init__(title="AI Assistant", transient_for=None, flags=0) - self.on_option_selected = handler - - # Set dialog properties for better screen reader accessibility - self.set_modal(True) - self.set_position(Gtk.WindowPosition.CENTER) - self.set_default_size(350, 250) - - # Add OK and Cancel buttons - self.add_button("OK", Gtk.ResponseType.OK) - self.add_button("Cancel", Gtk.ResponseType.CANCEL) - - # Connect response signal - self.connect("response", self._on_response) - - # Add content to dialog - content_area = self.get_content_area() - - # Add label - label = Gtk.Label(label="Choose an AI Assistant action:") - content_area.pack_start(label, False, False, 10) - - # Create radio button group for options - self.radio_ask = Gtk.RadioButton.new_with_label(None, "Ask Question") - self.radio_describe = Gtk.RadioButton.new_with_label_from_widget(self.radio_ask, "Describe Screen") - self.radio_action = Gtk.RadioButton.new_with_label_from_widget(self.radio_ask, "Request Action") - self.radio_image = Gtk.RadioButton.new_with_label_from_widget(self.radio_ask, "Analyze Images") - self.radio_browse = Gtk.RadioButton.new_with_label_from_widget(self.radio_ask, "Browse for Image File") - - # Pack radio buttons - content_area.pack_start(self.radio_ask, False, False, 5) - content_area.pack_start(self.radio_describe, False, False, 5) - content_area.pack_start(self.radio_action, False, False, 5) - content_area.pack_start(self.radio_image, False, False, 5) - content_area.pack_start(self.radio_browse, False, False, 5) - - # Set first option as selected by default - self.radio_ask.set_active(True) - - # Connect keyboard events for Enter key handling - self.connect("key-press-event", self._on_key_press) - - def _on_response(self, dialog, response_id): - """Handler for dialog response.""" - if response_id == Gtk.ResponseType.OK: - # Determine which radio button is selected - if self.radio_ask.get_active(): - action_id = "ask_question" - elif self.radio_describe.get_active(): - action_id = "describe_screen" - elif self.radio_action.get_active(): - action_id = "request_action" - elif self.radio_image.get_active(): - action_id = "analyze_images" - elif self.radio_browse.get_active(): - action_id = "browse_image_file" - else: - action_id = None - - if action_id: - self.on_option_selected(action_id) - - self.destroy() - - def _on_key_press(self, widget, event): - """Handle key press events.""" - # Allow Enter key to activate OK button - if event.keyval == 65293: # Enter key - self.response(Gtk.ResponseType.OK) - return True - return False - - def show_gui(self): - """Shows the AI Assistant dialog.""" - try: - self.show_all() - - # Present the dialog to ensure it gets focus - self.present() - - except Exception as e: - logger.error(f"Error in show_gui: {e}") - import traceback - traceback.print_exc() diff --git a/src/cthulhu/plugins/ByeCthulhu/__init__.py b/src/cthulhu/plugins/ByeCthulhu/__init__.py deleted file mode 100644 index 301e5ea..0000000 --- a/src/cthulhu/plugins/ByeCthulhu/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - diff --git a/src/cthulhu/plugins/ByeCthulhu/meson.build b/src/cthulhu/plugins/ByeCthulhu/meson.build deleted file mode 100644 index cbbf2ae..0000000 --- a/src/cthulhu/plugins/ByeCthulhu/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -byecthulhu_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - byecthulhu_python_sources, - subdir: 'cthulhu/plugins/ByeCthulhu' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'ByeCthulhu' -) \ No newline at end of file diff --git a/src/cthulhu/plugins/ByeCthulhu/plugin.info b/src/cthulhu/plugins/ByeCthulhu/plugin.info deleted file mode 100644 index dc61076..0000000 --- a/src/cthulhu/plugins/ByeCthulhu/plugin.info +++ /dev/null @@ -1,8 +0,0 @@ -name = Bye Cthulhu -version = 1.0.0 -description = Says goodbye when Cthulhu is shutting down -authors = Stormux -website = https://stormux.org -copyright = Copyright 2025 -builtin = false -hidden = false \ No newline at end of file diff --git a/src/cthulhu/plugins/ByeCthulhu/plugin.py b/src/cthulhu/plugins/ByeCthulhu/plugin.py deleted file mode 100644 index 95cb249..0000000 --- a/src/cthulhu/plugins/ByeCthulhu/plugin.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Bye Cthulhu plugin for Cthulhu.""" - -import logging -import time -from cthulhu.plugin import Plugin, cthulhu_hookimpl - -logger = logging.getLogger(__name__) - -class ByeCthulhu(Plugin): - """Plugin that speaks a goodbye message when Cthulhu is shutting down.""" - - def __init__(self, *args, **kwargs): - """Initialize the plugin.""" - super().__init__(*args, **kwargs) - logger.info("ByeCthulhu plugin initialized") - self._signal_handler_id = None - self._is_connected = False - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the plugin.""" - # Skip if this activation call isn't for us - if plugin is not None and plugin is not self: - return - - logger.info("Activating ByeCthulhu plugin") - try: - if not self._is_connected: - signal_manager = self.app.getSignalManager() - self._signal_handler_id = signal_manager.connectSignal( - "stop-application-completed", - self.process, - "default" # Add profile parameter - ) - self._is_connected = True - except Exception as e: - logger.error(f"Error activating ByeCthulhu plugin: {e}") - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the plugin.""" - # Skip if this deactivation call isn't for us - if plugin is not None and plugin is not self: - return - - logger.info("Deactivating ByeCthulhu plugin") - try: - if self._is_connected and self._signal_handler_id is not None: - signal_manager = self.app.getSignalManager() - # Use disconnectSignalByFunction instead since disconnectSignal doesn't exist - signal_manager.disconnectSignalByFunction( - self.process - ) - self._signal_handler_id = None - self._is_connected = False - except Exception as e: - logger.error(f"Error deactivating ByeCthulhu plugin: {e}") - - def process(self, app): - """Process the stop-application-completed signal.""" - try: - messages = app.getDynamicApiManager().getAPI('Messages') - state = app.getDynamicApiManager().getAPI('CthulhuState') - if state.activeScript: - state.activeScript.presentationInterrupt() - state.activeScript.presentMessage(messages.STOP_CTHULHU, resetStyles=False) - except Exception as e: - logger.error(f"Error in ByeCthulhu process: {e}") diff --git a/src/cthulhu/plugins/Clipboard/__init__.py b/src/cthulhu/plugins/Clipboard/__init__.py deleted file mode 100644 index f4d7c3a..0000000 --- a/src/cthulhu/plugins/Clipboard/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Clipboard plugin package.""" - -from .plugin import Clipboard - -__all__ = ['Clipboard'] diff --git a/src/cthulhu/plugins/Clipboard/meson.build b/src/cthulhu/plugins/Clipboard/meson.build deleted file mode 100644 index cf6ba90..0000000 --- a/src/cthulhu/plugins/Clipboard/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -clipboard_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - clipboard_python_sources, - subdir: 'cthulhu/plugins/Clipboard' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'Clipboard' -) \ No newline at end of file diff --git a/src/cthulhu/plugins/Clipboard/plugin.info b/src/cthulhu/plugins/Clipboard/plugin.info deleted file mode 100644 index 0e15232..0000000 --- a/src/cthulhu/plugins/Clipboard/plugin.info +++ /dev/null @@ -1,7 +0,0 @@ -[Plugin] -Name = Clipboard -Module = Clipboard -Description = Present the content of the current clipboard -Authors = Storm Dragon -Version = 1.0 -Category = Utilities diff --git a/src/cthulhu/plugins/Clipboard/plugin.py b/src/cthulhu/plugins/Clipboard/plugin.py deleted file mode 100644 index 6054c62..0000000 --- a/src/cthulhu/plugins/Clipboard/plugin.py +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Clipboard plugin for Cthulhu.""" - -import os -import logging -import gettext -import gi - -gi.require_version("Gtk", "3.0") -from gi.repository import Gtk, Gdk - -from cthulhu.plugin import Plugin, cthulhu_hookimpl - -# Set up translation function -_ = gettext.gettext - -logger = logging.getLogger(__name__) - -class Clipboard(Plugin): - """Plugin to read the clipboard contents.""" - - def __init__(self, *args, **kwargs): - """Initialize the plugin.""" - super().__init__(*args, **kwargs) - logger.info("Clipboard plugin initialized") - self._signal_handler_id = None - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the plugin.""" - # Skip if this activation call isn't for us - if plugin is not None and plugin is not self: - return - - logger.info("Activating Clipboard plugin") - try: - # Register keyboard shortcut - self.registerGestureByString(self.speakClipboard, _('clipboard'), 'kb:cthulhu+shift+c') - logger.debug("Registered shortcut for clipboard") - except Exception as e: - logger.error(f"Error activating Clipboard plugin: {e}") - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the plugin.""" - # Skip if this deactivation call isn't for us - if plugin is not None and plugin is not self: - return - - logger.info("Deactivating Clipboard plugin") - # Note: Currently no unregister method needed as keybindings are managed by APIHelper - - def speakClipboard(self, script=None, inputEvent=None): - """Present the contents of the clipboard.""" - try: - message = self.getClipboard() - - state = self.app.getDynamicApiManager().getAPI('CthulhuState') - if state and state.activeScript: - state.activeScript.presentMessage(message, resetStyles=False) - logger.debug("Presented clipboard contents") - else: - logger.warning("Could not present clipboard: no active script") - - return True - except Exception as e: - logger.error(f"Error in speakClipboard: {e}") - return False - - def getClipboard(self): - """Get the contents of the clipboard.""" - try: - message = "" - found_clipboard_content = False - - # Get Clipboard - clipboard_obj = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) - - clipboard_text = clipboard_obj.wait_for_text() - clipboard_image = clipboard_obj.wait_for_image() - clipboard_uri = clipboard_obj.wait_for_uris() - - if clipboard_text is not None: - found_clipboard_content = True - - if clipboard_obj.wait_is_uris_available(): - no_of_objects = 0 - no_of_folder = 0 - no_of_files = 0 - no_of_disks = 0 - no_of_links = 0 - - for uri in clipboard_uri: - if uri == '': - continue - - no_of_objects += 1 - uri_without_protocol = uri[uri.find('://') + 3:] - message += " " + uri[uri.rfind('/') + 1:] + " " - - if os.path.isdir(uri_without_protocol): - no_of_folder += 1 - message = message + _("Folder") - - if os.path.isfile(uri_without_protocol): - no_of_files += 1 - message = message + _("File") - - if os.path.ismount(uri_without_protocol): - no_of_disks += 1 - message = message + _("Disk") - - if os.path.islink(uri_without_protocol): - no_of_links += 1 - message = message + _("Link") - - if no_of_objects > 1: - message = str(no_of_objects) + _(" Objects in clipboard ") + message - else: - message = str(no_of_objects) + _(" Object in clipboard ") + message - else: - message = _("Text in clipboard ") + clipboard_text - - if clipboard_image is not None: - found_clipboard_content = True - message = _("The clipboard contains a image") - - if not found_clipboard_content: - message = _("The clipboard is empty") - - return message - except Exception as e: - logger.error(f"Error getting clipboard content: {e}") - return _("Error accessing clipboard") diff --git a/src/cthulhu/plugins/CthulhuRemote/README.md b/src/cthulhu/plugins/CthulhuRemote/README.md deleted file mode 100644 index 994accb..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/README.md +++ /dev/null @@ -1,206 +0,0 @@ -# Cthulhu Remote - -Cthulhu Remote is an NVDA Remote-style assistive technology relay plugin. It is -intended for remote help between screen reader users: one user can control -another user's desktop through keyboard input and receive the remote screen -reader's speech feedback. - -This is not graphical screen sharing. It does not forward a framebuffer, window -image, VNC/RDP session, or screenshots. The useful channel is screen reader -output and remote input. - -## Current Status - -### Working - -- Plugin installs and loads as `CthulhuRemote`. -- The plugin is registered as a D-Bus module when loaded. -- The transport connects outbound to NVDA Remote-compatible relay servers over - TLS. -- The default relay port is `6837`. -- Protocol version `2` is used. -- `cthulhuremote://` URLs are parsed. -- `nvdaremote://` URLs are accepted and rewritten to `cthulhuremote://`. -- `master` and `slave` connection modes are represented. -- Random connection keys can be generated. -- Invite URLs can be copied for the opposite role. -- The local clipboard can be pushed to connected peers. -- Incoming remote speech is spoken through Cthulhu. -- Incoming remote speech is suppressed from speech monitor callbacks to avoid - echo loops. -- In `slave` mode, local Cthulhu speech is forwarded to the relay as `speak` - messages. -- In `slave` mode, incoming remote key messages are mapped from common Windows - virtual-key codes or keysyms to AT-SPI key events. -- Disconnect and mute gestures are registered: - - `cthulhu+alt+page_down`: disconnect - - `cthulhu+alt+delete`: mute or unmute incoming remote output - - `cthulhu+control+shift+c`: push clipboard text - -### Partially Implemented - -- NVDA Remote compatibility is intentional at the relay-message level, but - cross-client interoperability with NVDA has not been verified. -- Remote key injection exists on the controlled/slave side, but master-side key - capture and forwarding is not implemented yet. -- Braille message types exist, but braille routing is not implemented. -- TLS certificate verification is enabled by default, and an insecure mode - exists, but there is no trust-on-first-use certificate workflow. -- Connection state is exposed, but there is no complete user-facing connection - dialog. - -### Not Implemented - -- Graphical screen sharing. -- Screenshot forwarding. -- VNC/RDP integration. -- Master-side keyboard forwarding. -- Remote braille display output. -- Remote braille input routing. -- Tone, wave, and other non-speech remote audio events. -- Ping/keepalive handling. -- Relay error presentation beyond basic logging/messages. -- Preferences UI for host, port, key, mode, certificate trust, and invite - management. - -## Intended User Model - -The typical assistive remote-support flow is: - -1. The person needing help runs Cthulhu and connects as `slave`. -2. The helper runs Cthulhu and connects as `master`. -3. The helper sends keyboard commands through the relay. -4. The controlled desktop receives those keys locally. -5. The controlled machine's Cthulhu speech is sent back to the helper. - -Examples this is meant to support: - -- Teaching someone how to use a program. -- Helping with a stuck dialog or inaccessible workflow. -- Typing into the remote user's editor or terminal. -- Navigating menus and controls with speech feedback. - -Things it does not solve by itself: - -- Visual captchas that require seeing an image. -- Visual inspection of a remote screen. -- Mouse-driven visual troubleshooting without another channel. - -## Implementation Checklist - -### Core Protocol - -- [x] Define protocol constants and message types. -- [x] Serialize and parse newline-delimited JSON messages. -- [x] Connect to relay servers over TLS. -- [x] Send `protocol_version` and `join` messages after connecting. -- [x] Dispatch inbound messages on the GLib main loop. -- [ ] Add ping/keepalive handling. -- [ ] Present relay `error` and `nvda_not_connected` messages clearly. -- [ ] Verify exact payload compatibility with current NVDA Remote clients. - -### Connection Management - -- [x] Parse `cthulhuremote://` URLs. -- [x] Accept `nvdaremote://` URLs. -- [x] Support host, port, key, mode, and insecure TLS fields. -- [x] Track connection states. -- [x] Expose D-Bus commands for connect, disconnect, state, key generation, and - invite URL copying. -- [ ] Add an accessible GTK connection dialog. -- [ ] Add saved/recent relay configuration if desired. -- [ ] Add trust-on-first-use certificate handling or a clear certificate trust - workflow. -- [ ] Add better reconnect/backoff status reporting. - -### Speech - -- [x] Speak incoming remote `speak` messages locally. -- [x] Support muting incoming remote speech. -- [x] Prevent inbound remote speech from being echoed back to the relay. -- [x] Forward local speech to the relay in `slave` mode. -- [ ] Decide whether master mode should ever forward local speech. -- [ ] Preserve richer speech sequence details if needed instead of flattening to - plain text. -- [ ] Verify behavior with speech interruption and cancellation across two live - clients. - -### Keyboard Control - -- [x] Receive remote key messages in `slave` mode. -- [x] Map common Windows virtual-key codes to Linux keysyms. -- [x] Inject remote key presses/releases with AT-SPI. -- [ ] Capture local keyboard events in `master` mode. -- [ ] Forward master key events as remote `key` messages. -- [ ] Prevent forwarded keys from also acting on the master's local desktop, - unless intentionally passed through. -- [ ] Preserve modifier press/release ordering. -- [ ] Verify Xorg behavior. -- [ ] Verify Wayland behavior without weakening Xorg support. -- [ ] Add tests for key payload generation and modifier handling. - -### Clipboard - -- [x] Push local clipboard text to connected peers. -- [x] Receive remote clipboard text into the local clipboard. -- [ ] Add a command or dialog control for pull/request clipboard if protocol - support is available. -- [ ] Decide how to handle large clipboard payloads. -- [ ] Add tests for empty, plain text, and multiline clipboard text. - -### Braille - -- [ ] Route incoming remote `display` messages to Cthulhu braille output. -- [ ] Implement `set_display_size`. -- [ ] Implement `set_braille_info` if required for compatibility. -- [ ] Route local braille input as remote `braille_input` messages when acting - as master. -- [ ] Verify routing keys and cursor-routing behavior. -- [ ] Add tests around braille payload parsing and ignored/unsupported fields. - -### Audio And Miscellaneous Messages - -- [ ] Implement or intentionally ignore `tone`. -- [ ] Implement or intentionally ignore `wave`. -- [ ] Decide whether `index` is relevant to Cthulhu speech. -- [ ] Handle `send_SAS` with a clear Linux-specific message. -- [ ] Log unsupported message types at debug level without spamming users. - -### User Interface - -- [x] Register basic gestures for disconnect, mute, and clipboard push. -- [ ] Add connect/disconnect controls to plugin preferences. -- [ ] Add host, port, key, mode, and insecure TLS fields. -- [ ] Add generate-key and copy-invite controls. -- [ ] Add connection status text suitable for screen reader users. -- [ ] Ensure Tab and Shift+Tab navigate the entire dialog. -- [ ] Associate GTK labels with their controls. - -### Tests And Verification - -- [x] Test URL parsing. -- [x] Test serializer message type values. -- [x] Test common key mapping. -- [x] Test plugin loading through the plugin manager. -- [x] Test additive speech monitor callbacks. -- [x] Test remote speech echo suppression. -- [x] Test slave-mode local speech forwarding. -- [x] Test that master mode does not forward local speech. -- [ ] Add transport tests with a fake relay socket. -- [ ] Add connection-state transition tests. -- [ ] Add D-Bus introspection or command exposure tests for the plugin module. -- [ ] Test against a live NVDA Remote-compatible relay. -- [ ] Test Cthulhu-to-Cthulhu master/slave operation. -- [ ] Test NVDA master to Cthulhu slave. -- [ ] Test Cthulhu master to NVDA slave after master key forwarding exists. - -## Suggested Next Steps - -1. Add an accessible connection dialog so the plugin can be used without manual - D-Bus calls. -2. Implement ping/error handling to improve relay behavior and diagnostics. -3. Design master-side key forwarding carefully around Cthulhu's existing input - event manager. -4. Add fake-relay tests before broad live testing. -5. Perform live two-client testing and record exact compatibility gaps. - diff --git a/src/cthulhu/plugins/CthulhuRemote/__init__.py b/src/cthulhu/plugins/CthulhuRemote/__init__.py deleted file mode 100644 index d0212af..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Cthulhu Remote plugin package.""" diff --git a/src/cthulhu/plugins/CthulhuRemote/connection_info.py b/src/cthulhu/plugins/CthulhuRemote/connection_info.py deleted file mode 100644 index 763b988..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/connection_info.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Connection metadata and URL parsing for Cthulhu Remote.""" - -from dataclasses import dataclass -from enum import Enum -from urllib.parse import parse_qs, urlencode, urlparse, urlunparse - -from .protocol import SERVER_PORT, URL_PREFIX -from .socket_utils import host_port_to_address - - -class URLParsingError(Exception): - """Raised when a remote connection URL is incomplete or invalid.""" - - -class ConnectionMode(Enum): - """Remote session role.""" - - MASTER = "master" - SLAVE = "slave" - - -class ConnectionState(Enum): - """Remote session connection state.""" - - CONNECTED = "connected" - CONNECTING = "connecting" - DISCONNECTED = "disconnected" - DISCONNECTING = "disconnecting" - - -@dataclass -class ConnectionInfo: - """Relay connection settings.""" - - hostname: str - mode: ConnectionMode - key: str - port: int = SERVER_PORT - insecure: bool = False - - def __post_init__(self) -> None: - self.port = self.port or SERVER_PORT - self.mode = ConnectionMode(self.mode) - - @classmethod - def from_url(cls, url: str) -> "ConnectionInfo": - parsedUrl = urlparse(url) - parsedQuery = parse_qs(parsedUrl.query) - hostname = parsedUrl.hostname - port = parsedUrl.port or SERVER_PORT - key = parsedQuery.get("key", [""])[0] - mode = parsedQuery.get("mode", [""])[0].lower() - insecure = parsedQuery.get("insecure", ["false"])[0].lower() == "true" - if not hostname: - raise URLParsingError("No hostname provided") - if not key: - raise URLParsingError("No key provided") - if not mode: - raise URLParsingError("No mode provided") - try: - ConnectionMode(mode) - except ValueError as error: - raise URLParsingError(f"Invalid mode provided: {mode!r}") from error - return cls(hostname=hostname, mode=ConnectionMode(mode), key=key, port=port, insecure=insecure) - - def get_address(self) -> str: - return host_port_to_address((self.hostname, self.port)) - - def get_url(self, mode: ConnectionMode | None = None) -> str: - mode = mode or self.mode - query = {"key": self.key, "mode": mode.value} - if self.insecure: - query["insecure"] = "true" - return urlunparse((URL_PREFIX.split("://", 1)[0], self.get_address(), "", "", urlencode(query), "")) - - def get_url_to_connect(self) -> str: - mode = ConnectionMode.SLAVE if self.mode == ConnectionMode.MASTER else ConnectionMode.MASTER - return self.get_url(mode) diff --git a/src/cthulhu/plugins/CthulhuRemote/local_machine.py b/src/cthulhu/plugins/CthulhuRemote/local_machine.py deleted file mode 100644 index eeb5021..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/local_machine.py +++ /dev/null @@ -1,157 +0,0 @@ -"""Linux desktop integration for Cthulhu Remote commands.""" - -from __future__ import annotations - -import logging -from typing import Any - -import gi - -gi.require_version("Atspi", "2.0") -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") -from gi.repository import Atspi, Gdk, GLib, Gtk - -from cthulhu import speech - -logger = logging.getLogger(__name__) - - -WINDOWS_VK_TO_ATSPI_KEYSYM = { - 0x08: "BackSpace", - 0x09: "Tab", - 0x0D: "Return", - 0x10: "Shift_L", - 0x11: "Control_L", - 0x12: "Alt_L", - 0x13: "Pause", - 0x14: "Caps_Lock", - 0x1B: "Escape", - 0x20: "space", - 0x21: "Page_Up", - 0x22: "Page_Down", - 0x23: "End", - 0x24: "Home", - 0x25: "Left", - 0x26: "Up", - 0x27: "Right", - 0x28: "Down", - 0x2D: "Insert", - 0x2E: "Delete", - 0x5B: "Super_L", - 0x5C: "Super_R", - 0x60: "KP_0", - 0x61: "KP_1", - 0x62: "KP_2", - 0x63: "KP_3", - 0x64: "KP_4", - 0x65: "KP_5", - 0x66: "KP_6", - 0x67: "KP_7", - 0x68: "KP_8", - 0x69: "KP_9", - 0x6A: "KP_Multiply", - 0x6B: "KP_Add", - 0x6D: "KP_Subtract", - 0x6E: "KP_Decimal", - 0x6F: "KP_Divide", -} - -for _digit in range(0x30, 0x3A): - WINDOWS_VK_TO_ATSPI_KEYSYM[_digit] = chr(_digit) -for _letter in range(0x41, 0x5B): - WINDOWS_VK_TO_ATSPI_KEYSYM[_letter] = chr(_letter).lower() -for _functionKey in range(1, 25): - WINDOWS_VK_TO_ATSPI_KEYSYM[0x6F + _functionKey] = f"F{_functionKey}" - - -class LocalMachine: - """Apply incoming remote commands to the local Linux desktop.""" - - def __init__(self, presenter) -> None: - self._presenter = presenter - self.isMuted = False - - def speak(self, sequence: Any = None, **kwargs: Any) -> None: - if self.isMuted: - return - text = self._speech_sequence_to_text(sequence) - if text: - with speech.suppress_monitor_callbacks(): - speech.speak(text, interrupt=False) - - def cancel_speech(self, **kwargs: Any) -> None: - if not self.isMuted: - speech.stop() - - def pause_speech(self, switch: bool = False, **kwargs: Any) -> None: - if switch: - speech.stop() - - def set_clipboard_text(self, text: str = "", **kwargs: Any) -> None: - clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) - clipboard.set_text(text, -1) - clipboard.store() - self._presenter("Remote clipboard received") - - def send_key( - self, - vk_code: int | None = None, - keysym: str | None = None, - pressed: bool | None = True, - **kwargs: Any, - ) -> None: - keyval = self._resolve_keyval(vk_code=vk_code, keysym=keysym) - if keyval is None: - logger.debug("Ignoring unmapped remote key: vk_code=%r keysym=%r", vk_code, keysym) - return - eventType = Atspi.KeySynthType.PRESS if pressed else Atspi.KeySynthType.RELEASE - GLib.idle_add(self._generate_key_event, keyval, eventType) - - def display(self, cells: list[int] | None = None, **kwargs: Any) -> None: - logger.debug("Remote braille display update ignored until braille routing is implemented: %r", cells) - - def braille_input(self, **kwargs: Any) -> None: - logger.debug("Remote braille input ignored until braille routing is implemented: %r", kwargs) - - def set_braille_display_size(self, **kwargs: Any) -> None: - logger.debug("Remote braille size negotiation ignored until braille routing is implemented: %r", kwargs) - - def send_secure_attention_sequence(self, **kwargs: Any) -> None: - self._presenter("Ctrl Alt Delete is not available on Linux desktops") - - def _generate_key_event(self, keyval: int, eventType: Atspi.KeySynthType) -> bool: - try: - Atspi.generate_keyboard_event(keyval, None, eventType) - except Exception: - logger.exception("Failed to generate remote key event") - return False - - def _resolve_keyval(self, vk_code: int | None, keysym: str | None) -> int | None: - if keysym: - keyval = Gdk.keyval_from_name(keysym) - return keyval if keyval else None - if vk_code is None: - return None - mappedKeysym = WINDOWS_VK_TO_ATSPI_KEYSYM.get(int(vk_code)) - if not mappedKeysym: - return None - keyval = Gdk.keyval_from_name(mappedKeysym) - return keyval if keyval else None - - def _speech_sequence_to_text(self, sequence: Any) -> str: - if sequence is None: - return "" - if isinstance(sequence, str): - return sequence - if not isinstance(sequence, list): - return str(sequence) - parts = [] - for item in sequence: - if isinstance(item, str): - parts.append(item) - elif isinstance(item, list): - nested = self._speech_sequence_to_text(item) - if nested: - parts.append(nested) - return " ".join(parts) diff --git a/src/cthulhu/plugins/CthulhuRemote/meson.build b/src/cthulhu/plugins/CthulhuRemote/meson.build deleted file mode 100644 index cf579c2..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/meson.build +++ /dev/null @@ -1,20 +0,0 @@ -cthulhu_remote_python_sources = files([ - '__init__.py', - 'connection_info.py', - 'local_machine.py', - 'plugin.py', - 'protocol.py', - 'serializer.py', - 'socket_utils.py', - 'transport.py' -]) - -python3.install_sources( - cthulhu_remote_python_sources, - subdir: 'cthulhu/plugins/CthulhuRemote' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'CthulhuRemote' -) diff --git a/src/cthulhu/plugins/CthulhuRemote/plugin.info b/src/cthulhu/plugins/CthulhuRemote/plugin.info deleted file mode 100644 index aae2024..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/plugin.info +++ /dev/null @@ -1,7 +0,0 @@ -[Plugin] -Name = Cthulhu Remote -Module = CthulhuRemote -Description = Remote access plugin compatible with NVDA Remote relay servers -Authors = Storm Dragon -Version = 0.1 -Category = Utilities diff --git a/src/cthulhu/plugins/CthulhuRemote/plugin.py b/src/cthulhu/plugins/CthulhuRemote/plugin.py deleted file mode 100644 index 26fb7b8..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/plugin.py +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Cthulhu Remote plugin.""" - -from __future__ import annotations - -import logging -import secrets -from typing import Any - -import gi - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") -from gi.repository import Gdk, Gtk - -from cthulhu import dbus_service -from cthulhu import speech -from cthulhu.plugin import Plugin, cthulhu_hookimpl - -from cthulhu.plugins.CthulhuRemote.connection_info import ( - ConnectionInfo, - ConnectionMode, - ConnectionState, - URLParsingError, -) -from cthulhu.plugins.CthulhuRemote.local_machine import LocalMachine -from cthulhu.plugins.CthulhuRemote.protocol import RemoteMessageType, SERVER_PORT -from cthulhu.plugins.CthulhuRemote.serializer import JSONSerializer -from cthulhu.plugins.CthulhuRemote.socket_utils import address_to_host_port -from cthulhu.plugins.CthulhuRemote.transport import RelayTransport - -logger = logging.getLogger(__name__) - - -class CthulhuRemote(Plugin): - """Remote access plugin compatible with NVDA Remote relay servers.""" - - def __init__(self) -> None: - super().__init__() - self._transport: RelayTransport | None = None - self._connectionInfo: ConnectionInfo | None = None - self._connectionState = ConnectionState.DISCONNECTED - self._localMachine = LocalMachine(self._present_message) - self._muted = False - self._speechMonitorRegistered = False - - @cthulhu_hookimpl - def activate(self, plugin=None): - if plugin is not None and plugin is not self: - return - self.registerGestureByString( - self.disconnect, - "Disconnect Cthulhu Remote", - "kb:cthulhu+alt+page_down", - ) - self.registerGestureByString( - self.toggle_mute, - "Toggle Cthulhu Remote mute", - "kb:cthulhu+alt+delete", - ) - self.registerGestureByString( - self.push_clipboard, - "Push clipboard to Cthulhu Remote peers", - "kb:cthulhu+control+shift+c", - ) - logger.info("Cthulhu Remote activated") - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - if plugin is not None and plugin is not self: - return - self.disconnect(notify_user=False) - logger.info("Cthulhu Remote deactivated") - - @dbus_service.parameterized_command - def connect( - self, - host: str, - key: str, - mode: str = "master", - port: int = SERVER_PORT, - insecure: bool = False, - notify_user: bool = True, - ) -> bool: - """Connect to a Cthulhu Remote relay server.""" - - if not host or not key: - if notify_user: - self._present_message("Cthulhu Remote requires host and key") - return False - try: - connectionInfo = ConnectionInfo( - hostname=host, - port=port, - key=key, - mode=ConnectionMode(mode.lower()), - insecure=insecure, - ) - except ValueError: - if notify_user: - self._present_message("Cthulhu Remote mode must be master or slave") - return False - return self._connect(connectionInfo, notify_user=notify_user) - - @dbus_service.parameterized_command - def connect_to_address( - self, - address: str, - key: str, - mode: str = "master", - insecure: bool = False, - notify_user: bool = True, - ) -> bool: - """Connect using host[:port] address text.""" - - host, port = address_to_host_port(address) - return self.connect(host, key, mode=mode, port=port, insecure=insecure, notify_user=notify_user) - - @dbus_service.parameterized_command - def connect_to_url(self, url: str, notify_user: bool = True) -> bool: - """Connect using a cthulhuremote:// or nvdaremote:// URL.""" - - if url.startswith("nvdaremote://"): - url = "cthulhuremote://" + url.split("://", 1)[1] - try: - connectionInfo = ConnectionInfo.from_url(url) - except URLParsingError as error: - logger.warning("Invalid Cthulhu Remote URL: %s", error) - if notify_user: - self._present_message("Invalid Cthulhu Remote URL") - return False - return self._connect(connectionInfo, notify_user=notify_user) - - @dbus_service.command - def disconnect(self, script=None, inputEvent=None, notify_user: bool = True) -> bool: - """Disconnect the current Cthulhu Remote session.""" - - if self._transport is not None: - self._connectionState = ConnectionState.DISCONNECTING - self._transport.close() - self._transport = None - self._deregister_speech_monitor() - self._connectionState = ConnectionState.DISCONNECTED - if notify_user: - self._present_message("Cthulhu Remote disconnected") - return True - - @dbus_service.command - def toggle_mute(self, script=None, inputEvent=None) -> bool: - """Mute or unmute incoming remote output.""" - - self._muted = not self._muted - self._localMachine.isMuted = self._muted - self._present_message("Cthulhu Remote muted" if self._muted else "Cthulhu Remote unmuted") - return True - - @dbus_service.command - def push_clipboard(self, script=None, inputEvent=None) -> bool: - """Push local clipboard text to connected remote peers.""" - - if not self._transport or not self._transport.connected: - self._present_message("Cthulhu Remote is not connected") - return True - clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) - text = clipboard.wait_for_text() - if not text: - self._present_message("Clipboard does not contain text") - return True - self._transport.send(RemoteMessageType.set_clipboard_text, text=text) - self._present_message("Clipboard pushed") - return True - - @dbus_service.command - def copy_invite_url(self, script=None, inputEvent=None) -> bool: - """Copy a remote invite URL for the opposite connection role.""" - - if not self._connectionInfo: - self._present_message("Cthulhu Remote is not connected") - return True - clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) - clipboard.set_text(self._connectionInfo.get_url_to_connect(), -1) - clipboard.store() - self._present_message("Cthulhu Remote invite copied") - return True - - @dbus_service.command - def generate_key(self) -> str: - """Generate a random remote connection key.""" - - return secrets.token_urlsafe(18) - - @dbus_service.getter - def get_state(self) -> str: - """Return the Cthulhu Remote connection state.""" - - return self._connectionState.value - - @dbus_service.getter - def get_connection_url(self) -> str: - """Return the current connection URL, if connected.""" - - if not self._connectionInfo: - return "" - return self._connectionInfo.get_url() - - def _connect(self, connectionInfo: ConnectionInfo, notify_user: bool = True) -> bool: - self.disconnect(notify_user=False) - serializer = JSONSerializer() - transport = RelayTransport.create(connectionInfo, serializer) - self._register_transport_handlers(transport, connectionInfo.mode) - transport.transportConnected.register(self._handle_transport_connected) - transport.transportDisconnected.register(self._handle_transport_disconnected) - transport.transportConnectionFailed.register(self._handle_transport_failed) - transport.transportCertificateAuthenticationFailed.register(self._handle_certificate_failed) - self._transport = transport - self._connectionInfo = connectionInfo - self._connectionState = ConnectionState.CONNECTING - self._register_speech_monitor(connectionInfo.mode) - transport.start() - if notify_user: - self._present_message("Cthulhu Remote connecting") - return True - - def _register_speech_monitor(self, mode: ConnectionMode) -> None: - if mode != ConnectionMode.SLAVE or self._speechMonitorRegistered: - return - - speech.add_monitor_callback(self._send_local_speech) - self._speechMonitorRegistered = True - - def _deregister_speech_monitor(self) -> None: - if not self._speechMonitorRegistered: - return - - speech.remove_monitor_callback(self._send_local_speech) - self._speechMonitorRegistered = False - - def _send_local_speech(self, text: str) -> None: - if not text or not text.strip(): - return - if not self._connectionInfo or self._connectionInfo.mode != ConnectionMode.SLAVE: - return - if not self._transport or not self._transport.connected: - return - - self._transport.send(RemoteMessageType.speak, sequence=[text]) - - def _register_transport_handlers(self, transport: RelayTransport, mode: ConnectionMode) -> None: - transport.register_inbound(RemoteMessageType.speak, self._localMachine.speak) - transport.register_inbound(RemoteMessageType.cancel, self._localMachine.cancel_speech) - transport.register_inbound(RemoteMessageType.pause_speech, self._localMachine.pause_speech) - transport.register_inbound(RemoteMessageType.set_clipboard_text, self._localMachine.set_clipboard_text) - transport.register_inbound(RemoteMessageType.motd, self._handle_motd) - transport.register_inbound(RemoteMessageType.version_mismatch, self._handle_version_mismatch) - transport.register_inbound(RemoteMessageType.channel_joined, self._handle_channel_joined) - transport.register_inbound(RemoteMessageType.client_joined, self._handle_client_joined) - transport.register_inbound(RemoteMessageType.client_left, self._handle_client_left) - if mode == ConnectionMode.SLAVE: - transport.register_inbound(RemoteMessageType.key, self._localMachine.send_key) - transport.register_inbound(RemoteMessageType.braille_input, self._localMachine.braille_input) - transport.register_inbound( - RemoteMessageType.send_SAS, - self._localMachine.send_secure_attention_sequence, - ) - else: - transport.register_inbound(RemoteMessageType.display, self._localMachine.display) - transport.register_inbound( - RemoteMessageType.set_display_size, - self._localMachine.set_braille_display_size, - ) - - def _handle_transport_connected(self, **kwargs: Any) -> None: - self._connectionState = ConnectionState.CONNECTED - self._present_message("Cthulhu Remote connected") - - def _handle_transport_disconnected(self, **kwargs: Any) -> None: - if self._connectionState != ConnectionState.DISCONNECTING: - self._connectionState = ConnectionState.DISCONNECTED - self._present_message("Cthulhu Remote disconnected") - - def _handle_transport_failed(self, **kwargs: Any) -> None: - self._connectionState = ConnectionState.DISCONNECTED - self._present_message("Cthulhu Remote connection failed") - - def _handle_certificate_failed(self, **kwargs: Any) -> None: - self._connectionState = ConnectionState.DISCONNECTED - fingerprint = self._transport.lastFailFingerprint if self._transport else None - if fingerprint: - logger.warning("Cthulhu Remote certificate fingerprint: %s", fingerprint) - self._present_message("Cthulhu Remote certificate verification failed") - - def _handle_motd(self, motd: str = "", **kwargs: Any) -> None: - if motd: - self._present_message(motd) - - def _handle_version_mismatch(self, **kwargs: Any) -> None: - self._present_message("Cthulhu Remote relay protocol mismatch") - self.disconnect(notify_user=False) - - def _handle_channel_joined(self, **kwargs: Any) -> None: - logger.info("Cthulhu Remote channel joined: %r", kwargs) - - def _handle_client_joined(self, client: dict[str, Any] | None = None, **kwargs: Any) -> None: - logger.info("Cthulhu Remote client joined: %r", client or kwargs) - self._present_message("Cthulhu Remote client joined") - - def _handle_client_left(self, client: dict[str, Any] | None = None, **kwargs: Any) -> None: - logger.info("Cthulhu Remote client left: %r", client or kwargs) - self._present_message("Cthulhu Remote client left") - - def _present_message(self, message: str) -> None: - if not self.app: - return - try: - state = self.app.getDynamicApiManager().getAPI("CthulhuState") - if state and state.activeScript: - state.activeScript.presentMessage(message, resetStyles=False) - except Exception: - logger.exception("Failed to present Cthulhu Remote message") diff --git a/src/cthulhu/plugins/CthulhuRemote/protocol.py b/src/cthulhu/plugins/CthulhuRemote/protocol.py deleted file mode 100644 index 428d53b..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/protocol.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Protocol constants for Cthulhu Remote. - -The wire protocol is intentionally compatible with NVDA Remote protocol -version 2 so relay servers can be shared. -""" - -from enum import Enum - - -PROTOCOL_VERSION = 2 -SERVER_PORT = 6837 -URL_PREFIX = "cthulhuremote://" - - -class RemoteMessageType(Enum): - """Message types used by the remote relay protocol.""" - - protocol_version = "protocol_version" - join = "join" - channel_joined = "channel_joined" - client_joined = "client_joined" - client_left = "client_left" - generate_key = "generate_key" - key = "key" - speak = "speak" - cancel = "cancel" - pause_speech = "pause_speech" - tone = "tone" - wave = "wave" - send_SAS = "send_SAS" - index = "index" - display = "display" - braille_input = "braille_input" - set_braille_info = "set_braille_info" - set_display_size = "set_display_size" - set_clipboard_text = "set_clipboard_text" - motd = "motd" - version_mismatch = "version_mismatch" - ping = "ping" - error = "error" - nvda_not_connected = "nvda_not_connected" diff --git a/src/cthulhu/plugins/CthulhuRemote/serializer.py b/src/cthulhu/plugins/CthulhuRemote/serializer.py deleted file mode 100644 index 2f54e80..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/serializer.py +++ /dev/null @@ -1,20 +0,0 @@ -"""JSON message serialization for Cthulhu Remote.""" - -import json -from enum import Enum -from typing import Any - - -class JSONSerializer: - """Serialize newline-delimited JSON remote messages.""" - - separator = b"\n" - - def serialize(self, messageType=None, **payload: Any) -> bytes: - if isinstance(messageType, Enum): - messageType = messageType.value - payload["type"] = messageType - return json.dumps(payload).encode("utf-8") + self.separator - - def deserialize(self, data: bytes) -> dict[str, Any]: - return json.loads(data.decode("utf-8")) diff --git a/src/cthulhu/plugins/CthulhuRemote/socket_utils.py b/src/cthulhu/plugins/CthulhuRemote/socket_utils.py deleted file mode 100644 index c7e71c9..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/socket_utils.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Socket address helpers for Cthulhu Remote.""" - -import urllib.parse - -from .protocol import SERVER_PORT - - -def address_to_host_port(address: str) -> tuple[str, int]: - """Convert host[:port] text to a host, port tuple.""" - - parsedAddress = urllib.parse.urlparse("//" + address) - return parsedAddress.hostname or "", parsedAddress.port or SERVER_PORT - - -def host_port_to_address(hostPort: tuple[str, int]) -> str: - """Convert a host, port tuple to compact host[:port] text.""" - - host, port = hostPort - if ":" in host: - host = f"[{host}]" - if port != SERVER_PORT: - return f"{host}:{port}" - return host diff --git a/src/cthulhu/plugins/CthulhuRemote/transport.py b/src/cthulhu/plugins/CthulhuRemote/transport.py deleted file mode 100644 index 766c201..0000000 --- a/src/cthulhu/plugins/CthulhuRemote/transport.py +++ /dev/null @@ -1,269 +0,0 @@ -"""Threaded TLS transport for Cthulhu Remote relay connections.""" - -from __future__ import annotations - -import hashlib -import logging -import queue -import select -import socket -import ssl -import threading -import time -from collections.abc import Callable -from enum import Enum -from typing import Any - -from gi.repository import GLib - -from .connection_info import ConnectionInfo -from .protocol import PROTOCOL_VERSION, RemoteMessageType -from .serializer import JSONSerializer -from .socket_utils import host_port_to_address - -logger = logging.getLogger(__name__) - - -class Action: - """Small callback registrar used by the transport layer.""" - - def __init__(self) -> None: - self._handlers: list[Callable[..., Any]] = [] - self._lock = threading.Lock() - - def register(self, handler: Callable[..., Any]) -> None: - with self._lock: - if handler not in self._handlers: - self._handlers.append(handler) - - def unregister(self, handler: Callable[..., Any]) -> None: - with self._lock: - if handler in self._handlers: - self._handlers.remove(handler) - - def notify(self, **kwargs: Any) -> None: - with self._lock: - handlers = list(self._handlers) - for handler in handlers: - handler(**kwargs) - - -class RelayTransport: - """Connect to an NVDA Remote compatible relay server over TLS.""" - - def __init__( - self, - serializer: JSONSerializer, - address: tuple[str, int], - channel: str, - connectionType: str, - insecure: bool = False, - timeout: int = 0, - protocolVersion: int = PROTOCOL_VERSION, - ) -> None: - self.serializer = serializer - self.address = address - self.channel = channel - self.connectionType = connectionType - self.insecure = insecure - self.timeout = timeout - self.protocolVersion = protocolVersion - self.connected = False - self.closed = True - self.successfulConnects = 0 - self.lastFailFingerprint: str | None = None - self._buffer = b"" - self._socket: ssl.SSLSocket | None = None - self._socketLock = threading.Lock() - self._sendQueue: queue.Queue[bytes | None] = queue.Queue() - self._sendThread: threading.Thread | None = None - self._connectorThread: threading.Thread | None = None - self._running = threading.Event() - self._handlers: dict[RemoteMessageType, Action] = {} - self.transportConnected = Action() - self.transportDisconnected = Action() - self.transportCertificateAuthenticationFailed = Action() - self.transportConnectionFailed = Action() - self.transportClosing = Action() - self.transportConnected.register(self._send_join_messages) - - @classmethod - def create(cls, connectionInfo: ConnectionInfo, serializer: JSONSerializer) -> "RelayTransport": - return cls( - serializer=serializer, - address=(connectionInfo.hostname, connectionInfo.port), - channel=connectionInfo.key, - connectionType=connectionInfo.mode.value, - insecure=connectionInfo.insecure, - ) - - def start(self) -> None: - if self._connectorThread and self._connectorThread.is_alive(): - return - self.closed = False - self._running.set() - self._connectorThread = threading.Thread( - target=self._connector_loop, - name="CthulhuRemoteConnector", - daemon=True, - ) - self._connectorThread.start() - - def close(self) -> None: - self.transportClosing.notify() - self.closed = True - self._running.clear() - self._disconnect() - - def register_inbound(self, messageType: RemoteMessageType, handler: Callable[..., Any]) -> None: - self._handlers.setdefault(messageType, Action()).register(handler) - - def unregister_inbound(self, messageType: RemoteMessageType, handler: Callable[..., Any]) -> None: - if messageType in self._handlers: - self._handlers[messageType].unregister(handler) - - def send(self, messageType: str | Enum, **payload: Any) -> None: - if not self.connected: - logger.debug("Dropping remote message while disconnected: %r", messageType) - return - self._sendQueue.put(self.serializer.serialize(messageType=messageType, **payload)) - - def _connector_loop(self) -> None: - while self._running.is_set(): - try: - self._run_once() - except ssl.SSLCertVerificationError: - logger.warning("Cthulhu Remote certificate verification failed") - except OSError as error: - logger.info("Cthulhu Remote connection failed: %s", error) - except Exception: - logger.exception("Cthulhu Remote connector failed") - if self._running.is_set(): - time.sleep(5) - - def _run_once(self) -> None: - try: - self._socket = self._create_socket() - self._socket.connect(self.address) - except ssl.SSLCertVerificationError: - self._capture_failed_fingerprint() - self.transportCertificateAuthenticationFailed.notify() - raise - except Exception: - self.transportConnectionFailed.notify() - raise - - self.connected = True - self.successfulConnects += 1 - self.transportConnected.notify() - self._sendThread = threading.Thread(target=self._send_loop, name="CthulhuRemoteSend", daemon=True) - self._sendThread.start() - - try: - while self._running.is_set() and self._socket is not None: - readers, _, errors = select.select([self._socket], [], [self._socket], 1.0) - if errors: - break - if readers: - self._read_available() - finally: - self.connected = False - self.transportDisconnected.notify() - self._disconnect() - - def _create_socket(self, insecure: bool | None = None) -> ssl.SSLSocket: - insecure = self.insecure if insecure is None else insecure - host, port = self.address - family, socktype, proto, _, _ = socket.getaddrinfo(host, port)[0] - plainSocket = socket.socket(family, socktype, proto) - if self.timeout: - plainSocket.settimeout(self.timeout) - plainSocket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - plainSocket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - context = ssl._create_unverified_context() if insecure else ssl.create_default_context() - return context.wrap_socket(plainSocket, server_hostname=host) - - def _capture_failed_fingerprint(self) -> None: - try: - socketForCert = self._create_socket(insecure=True) - socketForCert.connect(self.address) - certificate = socketForCert.getpeercert(binary_form=True) - socketForCert.close() - if certificate: - self.lastFailFingerprint = hashlib.sha256(certificate).hexdigest().lower() - except Exception: - self.lastFailFingerprint = None - - def _send_join_messages(self) -> None: - self.send(RemoteMessageType.protocol_version, version=self.protocolVersion) - self.send(RemoteMessageType.join, channel=self.channel, connection_type=self.connectionType) - - def _read_available(self) -> None: - if self._socket is None: - return - with self._socketLock: - self._socket.setblocking(False) - try: - data = self._buffer + self._socket.recv(16384) - except ssl.SSLWantReadError: - return - finally: - self._socket.setblocking(True) - self._buffer = b"" - if not data: - self._disconnect() - return - while b"\n" in data: - line, _, data = data.partition(b"\n") - self._parse_line(line) - self._buffer = data - - def _parse_line(self, line: bytes) -> None: - try: - message = self.serializer.deserialize(line) - messageType = RemoteMessageType(message.pop("type")) - except Exception: - logger.exception("Ignoring invalid remote message: %r", line) - return - action = self._handlers.get(messageType) - if action is None: - logger.debug("No handler registered for remote message type: %s", messageType.value) - return - GLib.idle_add(self._notify_action, action, message) - - def _notify_action(self, action: Action, payload: dict[str, Any]) -> bool: - action.notify(**payload) - return False - - def _send_loop(self) -> None: - while True: - item = self._sendQueue.get() - if item is None: - return - try: - with self._socketLock: - if self._socket is not None: - self._socket.sendall(item) - except OSError: - return - - def _disconnect(self) -> None: - if self._sendThread is not None: - self._sendQueue.put(None) - self._sendThread.join(timeout=2) - self._sendThread = None - self._clear_send_queue() - if self._socket is not None: - try: - self._socket.close() - except OSError: - pass - self._socket = None - self._buffer = b"" - - def _clear_send_queue(self) -> None: - try: - while True: - self._sendQueue.get_nowait() - except queue.Empty: - pass diff --git a/src/cthulhu/plugins/DisplayVersion/__init__.py b/src/cthulhu/plugins/DisplayVersion/__init__.py deleted file mode 100644 index 301e5ea..0000000 --- a/src/cthulhu/plugins/DisplayVersion/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - diff --git a/src/cthulhu/plugins/DisplayVersion/meson.build b/src/cthulhu/plugins/DisplayVersion/meson.build deleted file mode 100644 index e82de95..0000000 --- a/src/cthulhu/plugins/DisplayVersion/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -displayversion_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - displayversion_python_sources, - subdir: 'cthulhu/plugins/DisplayVersion' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'DisplayVersion' -) \ No newline at end of file diff --git a/src/cthulhu/plugins/DisplayVersion/plugin.info b/src/cthulhu/plugins/DisplayVersion/plugin.info deleted file mode 100644 index 1ed4e67..0000000 --- a/src/cthulhu/plugins/DisplayVersion/plugin.info +++ /dev/null @@ -1,8 +0,0 @@ -name = Display Version -version = 1.0.0 -description = Announces the Cthulhu version with Cthulhu+Shift+V -authors = Stormux -website = https://stormux.org -copyright = Copyright 2025 -builtin = false -hidden = false \ No newline at end of file diff --git a/src/cthulhu/plugins/DisplayVersion/plugin.py b/src/cthulhu/plugins/DisplayVersion/plugin.py deleted file mode 100644 index b12dd57..0000000 --- a/src/cthulhu/plugins/DisplayVersion/plugin.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Display Version plugin for Cthulhu.""" - -import logging -import os - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu.plugin import Plugin, cthulhu_hookimpl -from cthulhu import cthulhuVersion -from cthulhu import cthulhu_platform -from cthulhu import debug - -logger = logging.getLogger(__name__) - -class DisplayVersion(Plugin): - """Plugin that announces the current Cthulhu version.""" - - def __init__(self, *args, **kwargs): - """Initialize the plugin.""" - super().__init__(*args, **kwargs) - debug.printMessage(debug.LEVEL_INFO, "DisplayVersion: Plugin initialized", True) - self._kb_binding = None - self._activated = False - - def _get_version_string(self): - """Generate the full version string with AT-SPI and session information.""" - version_suffix = f'-{cthulhuVersion.codeName}' if cthulhuVersion.codeName else '' - msg = f'Cthulhu screen reader version {cthulhuVersion.version}{version_suffix}' - if cthulhu_platform.revision: - msg += f' revision {cthulhu_platform.revision}' - - atspi_version = Atspi.get_version() - msg += f', AT-SPI2 version {atspi_version[0]}.{atspi_version[1]}.{atspi_version[2]}' - - session_type = os.environ.get('XDG_SESSION_TYPE') or '' - session_desktop = os.environ.get('XDG_SESSION_DESKTOP') or '' - session = f'{session_type} {session_desktop}'.strip() - if session: - msg += f', Session {session}' - - return msg - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the plugin.""" - # Skip if this activation call isn't for us - if plugin is not None and plugin is not self: - return - - # Prevent duplicate activation - if self._activated: - debug.printMessage(debug.LEVEL_INFO, "DisplayVersion: Already activated, skipping", True) - return - - try: - # Use debug.printMessage to ensure it goes to the main debug log - debug.printMessage(debug.LEVEL_INFO, "DisplayVersion: Plugin activation starting", True) - debug.printMessage(debug.LEVEL_INFO, f"DisplayVersion: Plugin name: {self.name}", True) - - # Check if we have access to the API helper - if not self.app: - debug.printMessage(debug.LEVEL_INFO, "DisplayVersion: ERROR - No app reference available!", True) - return - - # Register keyboard shortcut - gesture_string = 'kb:cthulhu+shift+v' - debug.printMessage(debug.LEVEL_INFO, f"DisplayVersion: Registering gesture: {gesture_string}", True) - - version_message = self._get_version_string() - self._kb_binding = self.registerGestureByString( - self.speakText, - version_message, - gesture_string - ) - - if self._kb_binding: - debug.printMessage(debug.LEVEL_INFO, f"DisplayVersion: Keybinding registered successfully", True) - else: - debug.printMessage(debug.LEVEL_INFO, "DisplayVersion: ERROR - Failed to create keybinding!", True) - - self._activated = True - debug.printMessage(debug.LEVEL_INFO, "DisplayVersion: Plugin activation completed", True) - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"DisplayVersion: ERROR activating plugin: {e}", True) - import traceback - debug.printMessage(debug.LEVEL_INFO, f"DisplayVersion: {traceback.format_exc()}", True) - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the plugin.""" - # Skip if this deactivation call isn't for us - if plugin is not None and plugin is not self: - return - - self._activated = False - debug.printMessage(debug.LEVEL_INFO, "DisplayVersion: Plugin deactivated", True) - - def speakText(self, script=None, inputEvent=None): - """Speak the Cthulhu version when shortcut is pressed.""" - try: - debug.printMessage(debug.LEVEL_INFO, "DisplayVersion: speakText called", True) - if self.app: - state = self.app.getDynamicApiManager().getAPI('CthulhuState') - if state.activeScript: - version_message = self._get_version_string() - state.activeScript.presentMessage( - version_message, - resetStyles=False - ) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"DisplayVersion: ERROR in speakText: {e}", True) - return False diff --git a/src/cthulhu/plugins/GameMode/__init__.py b/src/cthulhu/plugins/GameMode/__init__.py deleted file mode 100644 index cb0c944..0000000 --- a/src/cthulhu/plugins/GameMode/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""GameMode plugin package.""" - -from .plugin import GameMode - -__all__ = ['GameMode'] diff --git a/src/cthulhu/plugins/GameMode/meson.build b/src/cthulhu/plugins/GameMode/meson.build deleted file mode 100644 index 4b80c49..0000000 --- a/src/cthulhu/plugins/GameMode/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -gamemode_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - gamemode_python_sources, - subdir: 'cthulhu/plugins/GameMode' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'GameMode' -) diff --git a/src/cthulhu/plugins/GameMode/plugin.info b/src/cthulhu/plugins/GameMode/plugin.info deleted file mode 100644 index 753c0d4..0000000 --- a/src/cthulhu/plugins/GameMode/plugin.info +++ /dev/null @@ -1,8 +0,0 @@ -name = GameMode -version = 1.0.0 -description = Reduces speech interruptions while holding keys -authors = Stormux -website = https://git.stormux.org/storm/cthulhu -copyright = Copyright 2025 -builtin = false -hidden = false diff --git a/src/cthulhu/plugins/GameMode/plugin.py b/src/cthulhu/plugins/GameMode/plugin.py deleted file mode 100644 index 428856a..0000000 --- a/src/cthulhu/plugins/GameMode/plugin.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""GameMode plugin for Cthulhu - reduce speech interruption while gaming.""" - -from cthulhu.plugin import Plugin, cthulhu_hookimpl -from cthulhu import debug -from cthulhu import messages -from cthulhu import settings_manager - -settingsManager = settings_manager.getManager() - - -class GameMode(Plugin): - """Plugin that reduces speech interruption while holding keys.""" - - def __init__(self, *args, **kwargs): - """Initialize the GameMode plugin.""" - super().__init__(*args, **kwargs) - self._activated = False - self._kbBinding = None - - debug.printMessage(debug.LEVEL_INFO, "GameMode: Plugin initialized", True) - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the GameMode plugin.""" - if plugin is not None and plugin is not self: - return - - if self._activated: - debug.printMessage(debug.LEVEL_INFO, "GameMode: Already activated, skipping", True) - return - - try: - debug.printMessage(debug.LEVEL_INFO, "GameMode: Plugin activation starting", True) - self._register_keybinding() - self._activated = True - debug.printMessage(debug.LEVEL_INFO, "GameMode: Plugin activated successfully", True) - return True - except Exception as error: - debug.printMessage(debug.LEVEL_INFO, f"GameMode: ERROR activating plugin: {error}", True) - return False - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the GameMode plugin.""" - if plugin is not None and plugin is not self: - return - - try: - debug.printMessage(debug.LEVEL_INFO, "GameMode: Plugin deactivation starting", True) - settingsManager.setSetting('gameMode', False) - self._activated = False - debug.printMessage(debug.LEVEL_INFO, "GameMode: Plugin deactivated successfully", True) - return True - except Exception as error: - debug.printMessage(debug.LEVEL_INFO, f"GameMode: ERROR deactivating plugin: {error}", True) - return False - - def _register_keybinding(self): - """Register the Cthulhu+Control+G keybinding for toggling game mode.""" - try: - if not self.app: - debug.printMessage(debug.LEVEL_INFO, "GameMode: No app reference for keybinding", True) - return - - gestureString = "kb:cthulhu+control+g" - description = "Toggle game mode" - self._kbBinding = self.registerGestureByString( - self._toggle_game_mode, - description, - gestureString, - globalBinding=True - ) - if self._kbBinding: - debug.printMessage(debug.LEVEL_INFO, f"GameMode: Registered keybinding {gestureString}", True) - else: - debug.printMessage(debug.LEVEL_INFO, f"GameMode: Failed to register keybinding {gestureString}", True) - except Exception as error: - debug.printMessage(debug.LEVEL_INFO, f"GameMode: Error registering keybinding: {error}", True) - - def _toggle_game_mode(self, script, inputEvent=None): - """Toggle game mode on or off.""" - currentValue = bool(settingsManager.getSetting('gameMode')) - newValue = not currentValue - settingsManager.setSetting('gameMode', newValue) - - message = messages.GAME_MODE_ENABLED if newValue else messages.GAME_MODE_DISABLED - if script: - script.presentMessage(message) - return True diff --git a/src/cthulhu/plugins/HelloCthulhu/__init__.py b/src/cthulhu/plugins/HelloCthulhu/__init__.py deleted file mode 100644 index 301e5ea..0000000 --- a/src/cthulhu/plugins/HelloCthulhu/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - diff --git a/src/cthulhu/plugins/HelloCthulhu/meson.build b/src/cthulhu/plugins/HelloCthulhu/meson.build deleted file mode 100644 index 5f6badb..0000000 --- a/src/cthulhu/plugins/HelloCthulhu/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -hellocthulhu_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - hellocthulhu_python_sources, - subdir: 'cthulhu/plugins/HelloCthulhu' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'HelloCthulhu' -) \ No newline at end of file diff --git a/src/cthulhu/plugins/HelloCthulhu/plugin.info b/src/cthulhu/plugins/HelloCthulhu/plugin.info deleted file mode 100644 index f1faf33..0000000 --- a/src/cthulhu/plugins/HelloCthulhu/plugin.info +++ /dev/null @@ -1,7 +0,0 @@ -[Plugin] -Name = Cthulhu say hello -Module = HelloCthulhu -Description = Startup announcement for Cthulhu -Authors = Storm Dragon -Version = 1.0 -Category = Interaction diff --git a/src/cthulhu/plugins/HelloCthulhu/plugin.py b/src/cthulhu/plugins/HelloCthulhu/plugin.py deleted file mode 100644 index a790757..0000000 --- a/src/cthulhu/plugins/HelloCthulhu/plugin.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# - -"""Hello Cthulhu plugin for Cthulhu.""" - -import logging -import weakref -from cthulhu.plugin import Plugin, cthulhu_hookimpl - -logger = logging.getLogger(__name__) - -# Class-level variable to track if the greeting has been presented -# This ensures the greeting is only shown once even if multiple instances exist -_greeting_shown = False - -class HelloCthulhu(Plugin): - """Plugin that speaks a welcome message when Cthulhu starts up.""" - - def __init__(self, *args, **kwargs): - """Initialize the plugin.""" - super().__init__(*args, **kwargs) - logger.info("HelloCthulhu plugin initialized") - self._signal_handler_id = None - self._is_connected = False - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the plugin.""" - # Skip if this activation call isn't for us - if plugin is not None and plugin is not self: - return - - logger.info("Activating HelloCthulhu plugin") - try: - # Only connect the signal if we haven't already - if not self._is_connected: - signal_manager = self.app.getSignalManager() - self._signal_handler_id = signal_manager.connectSignal( - "start-application-completed", - self.process, - "default" # Add profile parameter - ) - self._is_connected = True - logger.debug("Connected to start-application-completed signal") - except Exception as e: - logger.error(f"Error activating HelloCthulhu plugin: {e}") - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the plugin.""" - # Skip if this deactivation call isn't for us - if plugin is not None and plugin is not self: - return - - logger.info("Deactivating HelloCthulhu plugin") - try: - # Only disconnect if we're connected - if self._is_connected and self._signal_handler_id is not None: - signal_manager = self.app.getSignalManager() - signal_manager.disconnectSignalByFunction( - self.process - ) - self._signal_handler_id = None - self._is_connected = False - logger.debug("Disconnected from start-application-completed signal") - except Exception as e: - logger.error(f"Error deactivating HelloCthulhu plugin: {e}") - - def process(self, app): - """Process the start-application-completed signal.""" - global _greeting_shown - - # Only present the message if it hasn't been shown yet - if _greeting_shown: - logger.debug("Greeting already shown, skipping") - return - - try: - messages = app.getDynamicApiManager().getAPI('Messages') - state = app.getDynamicApiManager().getAPI('CthulhuState') - if state.activeScript: - state.activeScript.presentMessage(messages.START_CTHULHU, resetStyles=False) - _greeting_shown = True - logger.info("Greeting message presented") - - # Disconnect the signal after presenting the message - if self._is_connected and self._signal_handler_id is not None: - signal_manager = app.getSignalManager() - signal_manager.disconnectSignalByFunction( - self.process - ) - self._signal_handler_id = None - self._is_connected = False - logger.debug("Disconnected signal after presenting greeting") - except Exception as e: - logger.error(f"Error in HelloCthulhu process: {e}") diff --git a/src/cthulhu/plugins/OCR/README.md b/src/cthulhu/plugins/OCR/README.md deleted file mode 100644 index 0c0d007..0000000 --- a/src/cthulhu/plugins/OCR/README.md +++ /dev/null @@ -1,319 +0,0 @@ -# OCR Plugin for Cthulhu Screen Reader - -A powerful OCR (Optical Character Recognition) plugin that enables Cthulhu users to extract text from visual content and interact with it through precise coordinate mapping. Originally based on the ocrdesktop project by Chrys, this plugin has been enhanced with interactive features and comprehensive settings integration. - -## Features - -### 🔍 **OCR Operations** -- **Window OCR**: Extract text from the currently active window -- **Desktop OCR**: Extract text from the entire desktop screen -- **Clipboard OCR**: Extract text from images copied to the clipboard -- **Interactive OCR**: OCR with coordinate mapping for clicking and navigation - -### 🎯 **Interactive Coordinate Mapping** -- **Precise Clicking**: Click any text found in OCR results using exact coordinates -- **Dual View Modes**: Toggle between text view and interactive coordinate table -- **Safety Confirmation**: Preview click coordinates before executing -- **Real-time Navigation**: Browse OCR results and click immediately - -### ⚙️ **Comprehensive Settings** -- **Language Configuration**: Support for all Tesseract language packs -- **Image Processing**: Grayscale, invert, black/white, and scaling options -- **Clipboard Integration**: Automatic copying of OCR results to clipboard -- **Quality Tuning**: Adjustable parameters for optimal OCR accuracy - -### 🖥️ **Accessibility Integration** -- **Voice Announcements**: Clear audio feedback for all operations -- **Keyboard Navigation**: Full keyboard control of interactive features -- **Settings GUI**: Integrated settings tab in Cthulhu preferences -- **Non-blocking Processing**: Multi-threaded operation with progress tracking - -## Keybindings - -| Key Combination | Action | Description | -|----------------|--------|-------------| -| `Cthulhu+Control+W` | OCR Active Window | Performs OCR on the currently focused window | -| `Cthulhu+Control+D` | OCR Desktop | Performs OCR on the entire desktop screen | -| `Cthulhu+Control+Shift+C` | OCR Clipboard | Performs OCR on image data from clipboard | -| `Cthulhu+Control+F` | **Interactive OCR** | **Opens OCR results window with coordinate mapping** | - -### Interactive OCR Window Controls -| Key | Action | Description | -|-----|--------|-------------| -| `Alt+V` | Toggle View | Switch between text view and coordinate table | -| `Enter` | Click Selected | Click the text at the selected coordinates | -| `Escape` | Close Window | Close the OCR results window | -| `Arrow Keys` | Navigate | Move through OCR results in table view | - -## Dependencies - -### Required Dependencies -- **python3-pillow** (PIL) - Image processing library -- **python-pytesseract** - Python wrapper for Tesseract OCR -- **tesseract** - OCR engine (with language packs) -- **GTK3/GDK/Wnck** - For screenshot capture (usually pre-installed) - -### Installation Commands - -#### Arch Linux -```bash -sudo pacman -S python-pillow python-pytesseract tesseract tesseract-data-eng -``` - -#### Ubuntu/Debian -```bash -sudo apt install python3-pil python3-pytesseract tesseract-ocr tesseract-ocr-eng -``` - -#### Fedora -```bash -sudo dnf install python3-pillow python3-pytesseract tesseract tesseract-langpack-eng -``` - -### Additional Language Support -To add support for other languages, install additional Tesseract language packs: - -```bash -# Examples for different distributions: -# Arch: sudo pacman -S tesseract-data-fra tesseract-data-deu tesseract-data-spa -# Ubuntu: sudo apt install tesseract-ocr-fra tesseract-ocr-deu tesseract-ocr-spa -# Fedora: sudo dnf install tesseract-langpack-fra tesseract-langpack-deu tesseract-langpack-spa -``` - -## Usage - -1. **Enable the Plugin**: The OCR plugin is enabled by default in Cthulhu. If disabled, you can enable it through: - - Cthulhu Preferences → Plugins → Select "OCR Desktop" and choose "Enabled" - - Or add `OCR` to your `activePlugins` preference - -2. **Basic OCR Workflow**: - - Navigate to content you want to OCR - - Press the appropriate key combination - - Listen for "Performing OCR on [window/desktop/clipboard]" - - Wait for processing to complete - - OCR results will be announced via speech - -3. **Interactive OCR Workflow**: - - Press `Cthulhu+Control+F` to open OCR results window - - Wait for "Performing OCR on window for interactive results" - - Use `Alt+V` to toggle between text and coordinate table views - - Navigate with arrow keys in table view to find desired text - - Press `Enter` to click on the selected text location - - Confirm the click action in the safety dialog - -4. **Best Practices**: - - Ensure good contrast between text and background for better results - - Use window OCR for focused content (faster processing) - - Use desktop OCR for content spanning multiple windows - - Use clipboard OCR for images from web browsers or image viewers - - Enable "Copy Results to Clipboard" for easy text retrieval - - Adjust scale factor for small or blurry text (try 5-7) - -## Configuration - -### OCR Settings GUI -Access comprehensive OCR settings through Cthulhu Preferences: - -1. **Open Cthulhu Preferences**: `~/.local/bin/cthulhu -s` -2. **Navigate to OCR Tab**: Use keyboard navigation to find the OCR settings tab (only shown when the plugin is active) -3. **Configure Settings**: Adjust all OCR parameters through the accessible interface - -### Available Settings - -#### **Language Configuration** -- **Language Code**: Tesseract language pack to use (default: 'eng') - - Examples: 'fra' (French), 'deu' (German), 'spa' (Spanish) - - Use '+' for multiple languages: 'eng+fra' for English and French - -#### **Image Processing** -- **Scale Factor**: Image scaling multiplier (1-10, default: 3) - - Higher values improve OCR accuracy for small text - - Lower values process faster but may miss details -- **Grayscale Image**: Convert to grayscale for better text recognition -- **Invert Image**: Invert colors (useful for white text on dark backgrounds) -- **Black and White Image**: Convert to pure black/white with threshold -- **Black/White Threshold**: Threshold value for black/white conversion (0-255, default: 200) - -#### **Advanced Features** -- **Analyze Colors**: Extract color information from OCR regions (requires scipy/webcolors) -- **Copy Results to Clipboard**: Automatically copy all OCR results to system clipboard - -### Configuration File -Settings are automatically stored in Cthulhu's configuration system: -- **Global Settings**: `~/.local/share/cthulhu/user-settings.toml` -- **Application Settings**: `~/.local/share/cthulhu/app-settings/.toml` - -### Example Configuration Values -```toml -ocrLanguageCode = "eng" -ocrScaleFactor = 3 -ocrGrayscaleImg = false -ocrInvertImg = false -ocrBlackWhiteImg = false -ocrBlackWhiteImgValue = 200 -ocrColorCalculation = false -ocrCopyToClipboard = true -``` - -## Troubleshooting - -### Common Issues - -#### "No text found in OCR scan" -- **Cause**: Poor image quality, unsupported language, or no text in captured area -- **Solutions**: - - Try different OCR mode (window vs desktop) - - Ensure text has good contrast - - Check if correct language pack is installed - - Verify text is actually visible in the captured area - -#### "Missing dependencies" message -- **Cause**: Required Python packages or Tesseract not installed -- **Solution**: Install missing packages using commands above - -#### OCR taking too long -- **Cause**: Large desktop screenshots or complex images -- **Solutions**: - - Use window OCR instead of desktop OCR when possible - - Close unnecessary windows before desktop OCR - - Consider adjusting `_scaleFactor` (lower = faster) - -#### No speech output -- **Cause**: Cthulhu speech settings or audio issues -- **Solutions**: - - Check Cthulhu speech settings - - Test other Cthulhu speech functions - - Verify audio system is working - -#### Interactive OCR window doesn't open -- **Cause**: GTK dependencies missing or display issues -- **Solutions**: - - Ensure GTK3 development packages are installed - - Check display/Wayland/X11 compatibility - - Verify Cthulhu GUI components are working - -#### Click coordinates are inaccurate -- **Cause**: Window movement, scaling, or coordinate calculation errors -- **Solutions**: - - Ensure window hasn't moved since OCR capture - - Try recapturing with `Cthulhu+Control+F` - - Check display scaling settings - - Verify no window decoration changes occurred - -#### Clipboard copy not working -- **Cause**: Clipboard setting disabled or GTK clipboard issues -- **Solutions**: - - Enable "Copy Results to Clipboard" in OCR settings - - Test clipboard functionality with other applications - - Check GTK clipboard permissions - -### Debug Information -OCR plugin debug messages are logged to Cthulhu's debug output. To enable debug logging: - -```bash -cthulhu --debug > ocr_debug.log 2>&1 -``` - -Look for messages starting with "OCRDesktop:" in the log file. - -## Technical Details - -### Architecture -- **Base Class**: Extends `cthulhu.plugin.Plugin` -- **Threading**: Uses Python threading for non-blocking OCR processing -- **Image Processing**: PIL/Pillow for image manipulation and enhancement -- **OCR Engine**: Tesseract via pytesseract wrapper -- **Integration**: Uses Cthulhu's speech system for output - -### Image Processing Pipeline -1. **Capture**: Screenshot via GDK pixbuf system -2. **Scale**: Enlarge image by scale factor (default 3x) -3. **Transform**: Apply filters (grayscale, invert, etc.) if enabled -4. **OCR**: Process with Tesseract OCR engine -5. **Cleanup**: Remove extra whitespace and format text -6. **Present**: Announce results via Cthulhu speech - -### Text Post-Processing -The plugin automatically cleans OCR output by: -- Removing multiple consecutive spaces -- Eliminating empty lines -- Trimming leading/trailing whitespace -- Removing trailing newlines - -## Development - -### Plugin Structure -``` -src/cthulhu/plugins/OCR/ -├── __init__.py # Package import -├── plugin.py # Main plugin implementation -├── plugin.info # Plugin metadata -├── meson.build # Build system integration -└── README.md # This documentation -``` - -### Key Methods -- `_ocrActiveWindow()`: Captures and OCRs active window -- `_ocrDesktop()`: Captures and OCRs entire desktop -- `_ocrClipboard()`: OCRs image from clipboard -- `_showOCRResultsWindow()`: **NEW** - Interactive OCR with coordinate mapping -- `_performOCR()`: Core OCR processing with coordinate extraction -- `_presentOCRResult()`: Announces results via speech and clipboard -- `_createOCRResultsWindow()`: **NEW** - Creates interactive GTK results window -- `_clickSelectedText()`: **NEW** - Executes click at OCR coordinates - -### Interactive Features Architecture -- **Coordinate Mapping**: Uses `pytesseract.image_to_data()` to extract word positions -- **Screen Transformation**: Converts OCR coordinates to actual screen coordinates -- **GTK Interface**: Accessible results window with text and table views -- **Click Safety**: Confirmation dialogs before executing click actions -- **Settings Integration**: Full integration with Cthulhu's preferences system - -### Extending the Plugin -To add new OCR modes or features: - -1. Add new keybinding in `_registerKeybindings()` -2. Create handler method following pattern `_ocrNewMode()` -3. Implement image capture logic for new mode -4. Use existing `_performOCR()` and `_presentOCRResult()` methods -5. For interactive features, extend `_createOCRResultsWindow()` functionality - -## Version History - -### Version 2.0 (Enhanced Interactive Features) -- **Interactive OCR Window**: `Cthulhu+Control+F` for coordinate mapping -- **Precise Clicking**: Click any text found in OCR results -- **Settings Integration**: Full GUI settings tab in Cthulhu preferences -- **Clipboard Integration**: Automatic copying with toggle setting -- **Dual View Modes**: Text view and coordinate table with Alt+V toggle -- **Safety Features**: Click confirmation dialogs -- **Enhanced Processing**: Coordinate extraction with quality metrics - -### Version 1.0 (Original Implementation) -- Basic OCR for window, desktop, and clipboard -- Text extraction and speech output -- Multi-threading support -- Text cleanup and formatting - -## Credits - -- **Original ocrdesktop**: Created by Chrys (chrys87@users.noreply.github.com) -- **Cthulhu Integration**: Adapted by Storm Dragon for Cthulhu plugin system -- **Interactive Features**: Enhanced coordinate mapping and GUI integration -- **Cthulhu Screen Reader**: https://git.stormux.org/storm/cthulhu -- **Tesseract OCR**: https://github.com/tesseract-ocr/tesseract - -## License - -This plugin is distributed under the GNU Lesser General Public License (LGPL) version 2.1 or later, consistent with the Cthulhu screen reader project. - -## Support - -For issues, questions, or contributions: -- **Cthulhu Repository**: https://git.stormux.org/storm/cthulhu -- **Community**: IRC #stormux on irc.stormux.org -- **Email**: storm_dragon@stormux.org - ---- - -*Part of the Cthulhu Screen Reader project - Making the desktop accessible for everyone.* diff --git a/src/cthulhu/plugins/OCR/__init__.py b/src/cthulhu/plugins/OCR/__init__.py deleted file mode 100644 index 55b30a0..0000000 --- a/src/cthulhu/plugins/OCR/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# Copyright (c) 2022 Chrys (original ocrdesktop) -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -"""OCRDesktop plugin package.""" - -from .plugin import OCRDesktop \ No newline at end of file diff --git a/src/cthulhu/plugins/OCR/meson.build b/src/cthulhu/plugins/OCR/meson.build deleted file mode 100644 index 4dffac5..0000000 --- a/src/cthulhu/plugins/OCR/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -ocrdesktop_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - ocrdesktop_python_sources, - subdir: 'cthulhu/plugins/OCR' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'OCR' -) diff --git a/src/cthulhu/plugins/OCR/plugin.info b/src/cthulhu/plugins/OCR/plugin.info deleted file mode 100644 index 4066b71..0000000 --- a/src/cthulhu/plugins/OCR/plugin.info +++ /dev/null @@ -1,8 +0,0 @@ -name = OCR Desktop -version = 4.0.0 -description = OCR accessibility tool for reading inaccessible windows and dialogs using Tesseract OCR -authors = Storm Dragon -website = https://github.com/chrys87/ocrdesktop -copyright = Copyright 2022 Chrys, Copyright 2025 Stormux -builtin = false -hidden = false \ No newline at end of file diff --git a/src/cthulhu/plugins/OCR/plugin.py b/src/cthulhu/plugins/OCR/plugin.py deleted file mode 100644 index ef0c631..0000000 --- a/src/cthulhu/plugins/OCR/plugin.py +++ /dev/null @@ -1,854 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# Copyright (c) 2022 Chrys (original ocrdesktop) -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""OCRDesktop plugin for Cthulhu screen reader.""" - -import logging -import os -import sys -import locale -import time -import re -import tempfile -import threading -from mimetypes import MimeTypes - -import gi -gi.require_version('Atspi', '2.0') -from gi.repository import Atspi - -from cthulhu.plugin import Plugin, cthulhu_hookimpl -from cthulhu import debug -from cthulhu import settings_manager -from cthulhu.wnck_support import load_wnck - -# Note: Removed complex beep system - simple announcements work perfectly! - -# PIL -try: - from PIL import Image - from PIL import ImageOps - PIL_AVAILABLE = True -except ImportError: - PIL_AVAILABLE = False - -# pytesseract -try: - import pytesseract - from pytesseract import Output - PYTESSERACT_AVAILABLE = True -except ImportError: - PYTESSERACT_AVAILABLE = False - -# GTK/GDK -try: - gi.require_version("Gtk", "3.0") - gi.require_version("Gdk", "3.0") - from gi.repository import Gtk, Gdk - GTK_AVAILABLE = True -except Exception: - GTK_AVAILABLE = False - -Wnck = load_wnck() -WNCK_AVAILABLE = Wnck is not None - -logger = logging.getLogger(__name__) - -class OCRDesktop(Plugin): - """OCR Desktop accessibility plugin for reading inaccessible windows.""" - - def __init__(self, *args, **kwargs): - """Initialize the plugin.""" - super().__init__(*args, **kwargs) - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Plugin initialized", True) - - # Keybinding storage - self._kb_binding_window = None - self._kb_binding_desktop = None - self._kb_binding_clipboard = None - self._kb_binding_results_window = None - - # Settings manager - self._settings_manager = settings_manager.getManager() - - # OCR settings (will be loaded from settings) - self._languageCode = 'eng' - self._scaleFactor = 3 - self._grayscaleImg = False - self._invertImg = False - self._blackWhiteImg = False - self._blackWhiteImgValue = 200 - self._colorCalculation = False - self._colorCalculationMax = 3 - self._copyToClipboard = False - - # Internal state - self._img = [] - self._modifiedImg = [] - self._OCRText = '' - self._OCRWords = {} - self._OCRWordList = [] - self._offsetXpos = 0 - self._offsetYpos = 0 - self._activated = False - - # OCR Results Window - self._results_window = None - self._results_tree = None - self._results_textview = None - self._current_view_mode = 0 # 0 = text, 1 = tree - - # Progress feedback - self._is_processing = False - - # Color analysis - self._kdtDB = None - self.colorNames = [] - self.colorCache = {} - - # Set locale for tesseract - locale.setlocale(locale.LC_ALL, 'C') - - # Load OCR settings from configuration - self._loadOCRSettings() - - # Check dependencies - self._checkDependencies() - - def _checkDependencies(self): - """Check if required dependencies are available.""" - missing_deps = [] - - if not PIL_AVAILABLE: - missing_deps.append("python3-pillow") - if not PYTESSERACT_AVAILABLE: - missing_deps.append("python-pytesseract") - if not GTK_AVAILABLE: - missing_deps.append("GTK3/GDK") - - if missing_deps: - debug.printMessage(debug.LEVEL_INFO, - f"OCRDesktop: Missing dependencies: {', '.join(missing_deps)}", True) - return False - return True - - def _loadOCRSettings(self): - """Load OCR settings from Cthulhu configuration.""" - try: - self._languageCode = self._settings_manager.getSetting('ocrLanguageCode') or 'eng' - self._scaleFactor = self._settings_manager.getSetting('ocrScaleFactor') or 3 - self._grayscaleImg = self._settings_manager.getSetting('ocrGrayscaleImg') or False - self._invertImg = self._settings_manager.getSetting('ocrInvertImg') or False - self._blackWhiteImg = self._settings_manager.getSetting('ocrBlackWhiteImg') or False - self._blackWhiteImgValue = self._settings_manager.getSetting('ocrBlackWhiteImgValue') or 200 - self._colorCalculation = self._settings_manager.getSetting('ocrColorCalculation') or False - self._colorCalculationMax = self._settings_manager.getSetting('ocrColorCalculationMax') or 3 - self._copyToClipboard = self._settings_manager.getSetting('ocrCopyToClipboard') or False - - debug.printMessage(debug.LEVEL_INFO, f"OCR settings loaded: lang={self._languageCode}, scale={self._scaleFactor}, clipboard={self._copyToClipboard}", True) - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCR settings load error: {e}, using defaults", True) - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the plugin.""" - if plugin is not None and plugin is not self: - return - - if self._activated: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Already activated", True) - return - - try: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Plugin activation starting", True) - - if not self.app: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: ERROR - No app reference", True) - return - - if not self._checkDependencies(): - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Cannot activate - missing dependencies", True) - return - - # Register keybindings - self._registerKeybindings() - - self._activated = True - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Plugin activated successfully", True) - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error activating: {e}", True) - import traceback - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: {traceback.format_exc()}", True) - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the plugin.""" - if plugin is not None and plugin is not self: - return - - self._activated = False - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Plugin deactivated", True) - - def refresh_settings(self): - """Refresh plugin settings when configuration changes.""" - try: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Refreshing settings", True) - - # Reload OCR settings from configuration - self._loadOCRSettings() - - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Settings refreshed successfully", True) - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error refreshing settings: {e}", True) - - def _registerKeybindings(self): - """Register plugin keybindings.""" - try: - # OCR active window - self._kb_binding_window = self.registerGestureByString( - self._ocrActiveWindow, - "OCR read active window", - 'kb:cthulhu+control+w' - ) - - # OCR entire desktop - self._kb_binding_desktop = self.registerGestureByString( - self._ocrDesktop, - "OCR read entire desktop", - 'kb:cthulhu+control+d' - ) - - # OCR from clipboard - self._kb_binding_clipboard = self.registerGestureByString( - self._ocrClipboard, - "OCR read image from clipboard", - 'kb:cthulhu+control+shift+c' - ) - - # OCR results window - self._kb_binding_results_window = self.registerGestureByString( - self._showOCRResultsWindow, - "Show OCR results window for current window", - 'kb:cthulhu+control+f' - ) - - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Keybindings registered", True) - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error registering keybindings: {e}", True) - - - def _announceOCRStart(self, ocr_type): - """Announce the start of OCR operation.""" - try: - message = f"Performing OCR on {ocr_type}" - if self.app: - state = self.app.getDynamicApiManager().getAPI('CthulhuState') - if state and state.activeScript: - state.activeScript.presentMessage(message, resetStyles=False) - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: {message}", True) - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error announcing OCR start: {e}", True) - - def _ocrActiveWindow(self, script=None, inputEvent=None): - """OCR the active window.""" - try: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: OCR active window requested", True) - - if self._is_processing: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Already processing, ignoring request", True) - return True - - self._is_processing = True - self._announceOCRStart("window") - - try: - if self._screenShotWindow(): - self._performOCR() - self._presentOCRResult() - finally: - self._is_processing = False - - return True - except Exception as e: - self._is_processing = False - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error in OCR window: {e}", True) - return False - - def _ocrDesktop(self, script=None, inputEvent=None): - """OCR the entire desktop.""" - try: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: OCR desktop requested", True) - - if self._is_processing: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Already processing, ignoring request", True) - return True - - self._is_processing = True - self._announceOCRStart("desktop") - - try: - if self._screenShotDesktop(): - self._performOCR() - self._presentOCRResult() - finally: - self._is_processing = False - - return True - except Exception as e: - self._is_processing = False - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error in OCR desktop: {e}", True) - return False - - def _ocrClipboard(self, script=None, inputEvent=None): - """OCR image from clipboard.""" - try: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: OCR clipboard requested", True) - - if self._is_processing: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Already processing, ignoring request", True) - return True - - self._is_processing = True - self._announceOCRStart("clipboard") - - try: - if self._readClipboard(): - self._performOCR() - self._presentOCRResult() - finally: - self._is_processing = False - - return True - except Exception as e: - self._is_processing = False - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error in OCR clipboard: {e}", True) - return False - - def _screenShotWindow(self): - """Take screenshot of active window.""" - if not GTK_AVAILABLE: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: GTK not available for screenshots", True) - return False - - if not WNCK_AVAILABLE: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Wnck not available for active window screenshots", True) - return False - - try: - time.sleep(0.3) # Brief delay - gdkCurrDesktop = Gdk.get_default_root_window() - - currWnckScreen = Wnck.Screen.get_default() - currWnckScreen.force_update() - currWnckWindow = currWnckScreen.get_active_window() - - if not currWnckWindow: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: No active window found", True) - return False - - self._offsetXpos, self._offsetYpos, wnckWidth, wnckHeight = currWnckWindow.get_geometry() - pixBuff = Gdk.pixbuf_get_from_window(gdkCurrDesktop, self._offsetXpos, self._offsetYpos, wnckWidth, wnckHeight) - - if pixBuff: - self._img = [self._pixbuf2image(pixBuff)] - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Window screenshot captured", True) - return True - else: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Failed to capture window screenshot", True) - return False - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error taking window screenshot: {e}", True) - return False - - def _screenShotDesktop(self): - """Take screenshot of entire desktop.""" - if not GTK_AVAILABLE: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: GTK not available for screenshots", True) - return False - - try: - time.sleep(0.3) # Brief delay - currDesktop = Gdk.get_default_root_window() - pixBuff = Gdk.pixbuf_get_from_window(currDesktop, 0, 0, currDesktop.get_width(), currDesktop.get_height()) - - if pixBuff: - self._img = [self._pixbuf2image(pixBuff)] - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Desktop screenshot captured", True) - return True - else: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Failed to capture desktop screenshot", True) - return False - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error taking desktop screenshot: {e}", True) - return False - - def _readClipboard(self): - """Read image from clipboard.""" - if not GTK_AVAILABLE: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: GTK not available for clipboard", True) - return False - - try: - clipboardObj = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) - pixBuff = clipboardObj.wait_for_image() - - if pixBuff: - self._img = [self._pixbuf2image(pixBuff)] - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Image read from clipboard", True) - return True - else: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: No image found in clipboard", True) - return False - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error reading clipboard: {e}", True) - return False - - def _pixbuf2image(self, pix): - """Convert GdkPixbuf to PIL Image.""" - data = pix.get_pixels() - w = pix.props.width - h = pix.props.height - stride = pix.props.rowstride - mode = "RGB" - if pix.props.has_alpha: - mode = "RGBA" - im = Image.frombytes(mode, (w, h), data, "raw", mode, stride) - return im - - def _scaleImg(self, img): - """Scale image for better OCR results.""" - width_screen, height_screen = img.size - width_screen = width_screen * self._scaleFactor - height_screen = height_screen * self._scaleFactor - scaledImg = img.resize((width_screen, height_screen), Image.Resampling.BICUBIC) - return scaledImg - - def _transformImg(self, img): - """Transform image with various filters for better OCR.""" - modifiedImg = self._scaleImg(img) - - if self._invertImg: - modifiedImg = ImageOps.invert(modifiedImg) - if self._grayscaleImg: - modifiedImg = ImageOps.grayscale(modifiedImg) - if self._blackWhiteImg: - lut = [255 if v > self._blackWhiteImgValue else 0 for v in range(256)] - modifiedImg = modifiedImg.point(lut) - - return modifiedImg - - def _performOCR(self): - """Perform OCR on captured images with coordinate data extraction.""" - if not PYTESSERACT_AVAILABLE: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Tesseract not available", True) - return - - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Starting OCR", True) - self._OCRText = '' - self._OCRWords = {} - self._OCRWordList = [] - - for img in self._img: - modifiedImg = self._transformImg(img) - try: - # Extract coordinate data using image_to_data - from pytesseract import Output - OCRWords = pytesseract.image_to_data(modifiedImg, output_type=Output.DICT, - lang=self._languageCode, config='--psm 4') - self._appendToOCRWords(OCRWords) - self._processOCRWords(OCRWords, modifiedImg) - - # Also extract simple text for speech output - text = pytesseract.image_to_string(modifiedImg, lang=self._languageCode, config='--psm 4') - self._OCRText += text + '\n' - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: OCR error: {e}", True) - - # Clean up text - self._cleanOCRText() - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: OCR completed", True) - - def _cleanOCRText(self): - """Clean up OCR text output.""" - # Remove multiple spaces - regexSpace = re.compile(r'[^\S\r\n]{2,}') - self._OCRText = regexSpace.sub(' ', self._OCRText) - - # Remove empty lines - regexSpace = re.compile(r'\n\s*\n') - self._OCRText = regexSpace.sub('\n', self._OCRText) - - # Remove trailing spaces - regexSpace = re.compile(r'\s*\n') - self._OCRText = regexSpace.sub('\n', self._OCRText) - - # Remove leading spaces - regexSpace = re.compile(r'^\s') - self._OCRText = regexSpace.sub('', self._OCRText) - - # Remove trailing newlines - self._OCRText = self._OCRText.strip() - - def _presentOCRResult(self): - """Present OCR result to user via speech and optionally copy to clipboard.""" - try: - if not self._OCRText.strip(): - message = "No text found in OCR scan" - else: - message = f"OCR result: {self._OCRText}" - - # Copy to clipboard if enabled - if self._copyToClipboard: - self._copyTextToClipboard(self._OCRText) - message += " (copied to clipboard)" - - if self.app: - state = self.app.getDynamicApiManager().getAPI('CthulhuState') - if state and state.activeScript: - state.activeScript.presentMessage(message, resetStyles=False) - - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Presented result: {len(self._OCRText)} characters", True) - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error presenting result: {e}", True) - - def _appendToOCRWords(self, OCRWords): - """Append OCR words to the main OCR data structure.""" - for k, v in OCRWords.items(): - try: - x = self._OCRWords[k] - if isinstance(v, list): - self._OCRWords[k].extend(v) - except KeyError: - self._OCRWords[k] = v - - def _processOCRWords(self, OCRWords, img): - """Process OCR words to extract coordinate data.""" - boxCounter = len(OCRWords['level']) - if boxCounter == 0: - return False - - lastPage = -1 - lastBlock = -1 - lastPar = -1 - lastLine = -1 - - for i in range(boxCounter): - if (len(OCRWords['text'][i]) == 0) or OCRWords['text'][i].isspace(): - continue - - # Add word to coordinate list - self._OCRWordList.append([ - OCRWords['text'][i], # Text - round(OCRWords['height'][i] / 3 * 0.78, 0), # Calculated fontsize - self._getColorString(OCRWords, i, img), # Color info - 'text', # Object type - int(OCRWords['width'][i] / 2 + OCRWords['left'][i]), # X coordinate (center) - int(OCRWords['height'][i] / 2 + OCRWords['top'][i]), # Y coordinate (center) - int(float(OCRWords['conf'][i])) # Confidence - ]) - - lastPage = OCRWords['page_num'][i] - lastBlock = OCRWords['block_num'][i] - lastPar = OCRWords['par_num'][i] - lastLine = OCRWords['line_num'][i] - - return True - - def _getColorString(self, box, index, img): - """Get color information for OCR text (simplified version).""" - if not self._colorCalculation: - return 'unknown' - - # Simplified color calculation - just return "unknown" for now - # Full implementation would require the color analysis from ocrdesktop - return 'unknown' - - def _showOCRResultsWindow(self, script=None, inputEvent=None): - """Show OCR results window for current window with coordinate mapping.""" - try: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: OCR results window requested", True) - - if self._is_processing: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Already processing, ignoring request", True) - return True - - self._is_processing = True - self._announceOCRStart("window for interactive results") - - try: - if self._screenShotWindow(): - self._performOCR() - self._createOCRResultsWindow() - finally: - self._is_processing = False - - return True - except Exception as e: - self._is_processing = False - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error in OCR results window: {e}", True) - return False - - def _createOCRResultsWindow(self): - """Create and show the OCR results window with coordinate mapping.""" - if not GTK_AVAILABLE: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: GTK not available for results window", True) - return - - try: - # Create main window - self._results_window = Gtk.Window(title="OCR Results - Cthulhu") - self._results_window.set_default_size(800, 600) - self._results_window.set_modal(True) - - # Create main container - vbox = Gtk.VBox() - - # Create menu bar - menubar = self._createResultsMenuBar() - vbox.pack_start(menubar, False, False, 0) - - # Create text view for OCR text - scrolled_text = Gtk.ScrolledWindow() - self._results_textview = Gtk.TextView() - self._results_textview.set_editable(False) - buffer = self._results_textview.get_buffer() - buffer.set_text(self._OCRText) - scrolled_text.add(self._results_textview) - - # Create tree view for coordinate data - scrolled_tree = Gtk.ScrolledWindow() - self._results_tree = self._createResultsTreeView() - scrolled_tree.add(self._results_tree) - - # Add both views to container - vbox.pack_start(scrolled_text, True, True, 0) - vbox.pack_start(scrolled_tree, True, True, 0) - - # Set initial view (text only) - scrolled_tree.hide() - - self._results_window.add(vbox) - self._results_window.connect("destroy", self._onResultsWindowDestroy) - self._results_window.connect("key-press-event", self._onResultsKeyPress) - - # Show window - self._results_window.show_all() - scrolled_tree.hide() # Hide tree initially - - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Results window created", True) - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error creating results window: {e}", True) - - def _createResultsMenuBar(self): - """Create menu bar for results window.""" - menubar = Gtk.MenuBar() - - # View menu - view_menu = Gtk.Menu() - view_item = Gtk.MenuItem(label="View") - view_item.set_submenu(view_menu) - - # Toggle view option - toggle_item = Gtk.MenuItem(label="Toggle View (Alt+V)") - toggle_item.connect("activate", self._toggleResultsView) - view_menu.append(toggle_item) - - menubar.append(view_item) - - # Actions menu - actions_menu = Gtk.Menu() - actions_item = Gtk.MenuItem(label="Actions") - actions_item.set_submenu(actions_menu) - - # Click action - click_item = Gtk.MenuItem(label="Click Selected (Enter)") - click_item.connect("activate", self._clickSelectedText) - actions_menu.append(click_item) - - menubar.append(actions_item) - - return menubar - - def _createResultsTreeView(self): - """Create tree view for OCR results with coordinates.""" - # Create list store - store = Gtk.ListStore(str, str, int, str, str, int, int, int) - - # Create tree view - tree = Gtk.TreeView(model=store) - tree.set_search_column(0) - - # Add columns - columns = [ - ("Text", 0), - ("Font Size", 2), - ("Color", 3), - ("Type", 4), - ("X Position", 5), - ("Y Position", 6), - ("Confidence", 7) - ] - - for title, col_id in columns: - renderer = Gtk.CellRendererText() - column = Gtk.TreeViewColumn(title, renderer, text=col_id) - column.set_sort_column_id(col_id) - tree.append_column(column) - - # Populate with OCR data - for row in self._OCRWordList: - # Transform coordinates back to screen coordinates - x_coord = int(row[4] / self._scaleFactor + self._offsetXpos) - y_coord = int(row[5] / self._scaleFactor + self._offsetYpos) - - store.append([ - row[0], # Text - str(row[1]), # Font size (as string for display) - int(row[1]), # Font size (as int for sorting) - row[2], # Color - row[3], # Type - x_coord, # X coordinate (screen) - y_coord, # Y coordinate (screen) - row[6] # Confidence - ]) - - tree.connect("row-activated", self._onTreeRowActivated) - - return tree - - def _toggleResultsView(self, widget): - """Toggle between text and tree view.""" - if not self._results_window: - return - - # Get the container - vbox = self._results_window.get_child() - scrolled_text = vbox.get_children()[1] # Second child (after menubar) - scrolled_tree = vbox.get_children()[2] # Third child - - if self._current_view_mode == 0: # Currently showing text - scrolled_text.hide() - scrolled_tree.show() - self._current_view_mode = 1 - self._results_tree.grab_focus() - else: # Currently showing tree - scrolled_tree.hide() - scrolled_text.show() - self._current_view_mode = 0 - self._results_textview.grab_focus() - - def _onTreeRowActivated(self, tree, path, column): - """Handle double-click or Enter on tree row.""" - self._clickSelectedText(None) - - def _clickSelectedText(self, widget): - """Click at the coordinates of the selected text.""" - if not self._results_tree: - return - - selection = self._results_tree.get_selection() - if not selection: - return - - model, tree_iter = selection.get_selected() - if not tree_iter: - return - - # Get coordinates - x_coord = model.get_value(tree_iter, 5) # X position - y_coord = model.get_value(tree_iter, 6) # Y position - text = model.get_value(tree_iter, 0) # Text for confirmation - - # Confirm click action - dialog = Gtk.MessageDialog( - self._results_window, - Gtk.DialogFlags.MODAL, - Gtk.MessageType.QUESTION, - Gtk.ButtonsType.YES_NO, - f"Click at coordinates ({x_coord}, {y_coord}) for text '{text}'?" - ) - - response = dialog.run() - dialog.destroy() - - if response == Gtk.ResponseType.YES: - try: - # Hide window before clicking - self._results_window.hide() - - # Perform click using AT-SPI2 - time.sleep(0.5) # Brief delay - Atspi.generate_mouse_event(x_coord, y_coord, "b1c") - - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Clicked at ({x_coord}, {y_coord})", True) - - # Destroy window after successful click - self._results_window.destroy() - self._results_window = None - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error clicking: {e}", True) - # Show window again on error - self._results_window.show() - - def _onResultsKeyPress(self, widget, event): - """Handle key presses in results window.""" - keyval = event.keyval - state = event.state - - # Alt+V to toggle view - if (keyval == Gdk.KEY_v or keyval == Gdk.KEY_V) and (state & Gdk.ModifierType.MOD1_MASK): - self._toggleResultsView(None) - return True - - # Enter to click selected - if keyval == Gdk.KEY_Return or keyval == Gdk.KEY_KP_Enter: - if self._current_view_mode == 1: # Tree view - self._clickSelectedText(None) - return True - - # Escape to close - if keyval == Gdk.KEY_Escape: - self._results_window.destroy() - return True - - return False - - def _onResultsWindowDestroy(self, widget): - """Handle results window destruction.""" - self._results_window = None - self._results_tree = None - self._results_textview = None - self._current_view_mode = 0 - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: Results window destroyed", True) - - def _copyTextToClipboard(self, text): - """Copy text to system clipboard.""" - if not GTK_AVAILABLE: - debug.printMessage(debug.LEVEL_INFO, "OCRDesktop: GTK not available for clipboard", True) - return False - - try: - clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) - clipboard.set_text(text, -1) - clipboard.store() - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Copied {len(text)} characters to clipboard", True) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"OCRDesktop: Error copying to clipboard: {e}", True) - return False diff --git a/src/cthulhu/plugins/SSIPProxy/__init__.py b/src/cthulhu/plugins/SSIPProxy/__init__.py deleted file mode 100644 index f099bac..0000000 --- a/src/cthulhu/plugins/SSIPProxy/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# SSIPProxy plugin - SSIP protocol proxy for Cthulhu -from .plugin import * diff --git a/src/cthulhu/plugins/SSIPProxy/meson.build b/src/cthulhu/plugins/SSIPProxy/meson.build deleted file mode 100644 index 0c5f8b7..0000000 --- a/src/cthulhu/plugins/SSIPProxy/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -ssipproxy_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - ssipproxy_python_sources, - subdir: 'cthulhu/plugins/SSIPProxy' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'SSIPProxy' -) diff --git a/src/cthulhu/plugins/SSIPProxy/plugin.info b/src/cthulhu/plugins/SSIPProxy/plugin.info deleted file mode 100644 index 9c2d297..0000000 --- a/src/cthulhu/plugins/SSIPProxy/plugin.info +++ /dev/null @@ -1,11 +0,0 @@ -[Plugin] -name=SSIP Proxy -module_name=SSIPProxy -version=1.0.0 -description=SSIP protocol proxy for speech-dispatcher TCP clients. Allows applications like Say the Spire (Slay the Spire accessibility mod) to have their speech output go through Cthulhu for both speech and braille support. -authors=Stormux -copyright=Copyright (c) 2024-2025 Stormux -website=https://stormux.org -icon_name=audio-speakers -builtin=false -hidden=false diff --git a/src/cthulhu/plugins/SSIPProxy/plugin.py b/src/cthulhu/plugins/SSIPProxy/plugin.py deleted file mode 100644 index ea79179..0000000 --- a/src/cthulhu/plugins/SSIPProxy/plugin.py +++ /dev/null @@ -1,587 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024-2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# - -"""SSIP Proxy plugin for Cthulhu screen reader. - -This plugin acts as a speech-dispatcher SSIP server, allowing applications -that use speech-dispatcher's TCP interface (like Say the Spire for Slay the Spire) -to have their speech output go through Cthulhu for both speech and braille support. -""" - -import logging -import select -import socket -import threading -from threading import Thread, Lock -from cthulhu.plugin import Plugin, cthulhu_hookimpl -from cthulhu import debug - -logger = logging.getLogger(__name__) - -# Default speech-dispatcher TCP port -SSIP_PORT = 6560 - -# SSIP Response codes -RESP_OK = "200 OK" -RESP_CLIENT_NAME_SET = "208 OK CLIENT NAME SET" -RESP_RECEIVING_DATA = "230 OK RECEIVING DATA" -RESP_MSG_QUEUED = "225 OK MESSAGE QUEUED" -RESP_BYE = "231 HAPPY HACKING" -RESP_ERR_INVALID = "300 ERR INVALID COMMAND" - - -class SSIPConnection: - """Handles a single SSIP client connection.""" - - def __init__(self, clientSocket, plugin): - """Initialize the connection handler. - - Args: - clientSocket: The client socket connection - plugin: Reference to the parent plugin - """ - self.socket = clientSocket - self.plugin = plugin - self.clientName = None - self.receivingData = False - self.dataBuffer = [] - self.msgId = 0 - - def send(self, message): - """Send a response to the client. - - Args: - message: The response message to send - """ - try: - response = message + "\r\n" - self.socket.sendall(response.encode("utf-8")) - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"SSIP send error: {e}", True) - - def sendMessageQueued(self, msgId): - """Send a message queued response with message ID. - - Sends both lines in a single write to avoid race conditions. - - Args: - msgId: The message ID to include - """ - self.sendMultiLine(f"225-{msgId}", "225 OK MESSAGE QUEUED") - - def sendMultiLine(self, line1, line2): - """Send a two-line response in a single write. - - This avoids race conditions where the client reads between lines. - - Args: - line1: First line of response - line2: Second line of response - """ - try: - response = f"{line1}\r\n{line2}\r\n" - self.socket.sendall(response.encode("utf-8")) - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"SSIP send error: {e}", True) - - def handleLine(self, line): - """Process a single line from the client. - - Args: - line: The line to process - - Returns: - True to continue, False to close connection - """ - line = line.strip() - if not line: - return True - - logger.debug(f"SSIP <<< {line}") - - # If we're receiving SPEAK data - if self.receivingData: - return self.handleDataLine(line) - - # Parse command - parts = line.split(None, 1) - if not parts: - return True - - cmd = parts[0].upper() - args = parts[1] if len(parts) > 1 else "" - - if cmd == "SET": - return self.handleSet(args) - elif cmd == "SPEAK": - return self.handleSpeak() - elif cmd == "STOP": - return self.handleStop(args) - elif cmd == "CANCEL": - return self.handleCancel(args) - elif cmd == "PAUSE": - self.send(RESP_OK) - return True - elif cmd == "RESUME": - self.send(RESP_OK) - return True - elif cmd == "QUIT": - self.send(RESP_BYE) - return False - elif cmd == "HELP": - self.send("299-SSIP Proxy for Cthulhu") - self.send("299 OK HELP SENT") - return True - elif cmd == "GET": - return self.handleGet(args) - elif cmd == "LIST": - return self.handleList(args) - elif cmd == "HISTORY": - return self.handleHistory(args) - elif cmd == "CHAR": - # Character speaking - extract and speak the character - if args: - char = args.strip() - if char.lower() == "space": - char = " " - self.plugin.outputMessage(char) - self.msgId += 1 - self.sendMessageQueued(self.msgId) - return True - elif cmd == "KEY": - # Key speaking - speak the key name - if args: - self.plugin.outputMessage(args.strip()) - self.msgId += 1 - self.sendMessageQueued(self.msgId) - return True - elif cmd == "SOUND_ICON": - # Sound icon - acknowledge but ignore - self.msgId += 1 - self.sendMessageQueued(self.msgId) - return True - else: - logger.debug(f"Unknown SSIP command: {cmd}") - self.send(RESP_OK) - return True - - def handleGet(self, args): - """Handle GET command. - - Args: - args: Command arguments - - Returns: - True to continue - """ - param = args.strip().upper() if args else "" - - if param == "VERSION": - self.send("240-speechd-ssip-proxy 0.1") - self.send("240 OK VERSION SENT") - elif param == "OUTPUT_MODULES": - self.send("250-cthulhu") - self.send("250 OK MODULES LIST SENT") - elif param == "VOICES": - self.send("251-cthulhu\tdefault\tnone") - self.send("251 OK VOICES LIST SENT") - elif param == "RATE" or param == "PITCH" or param == "VOLUME": - self.send("251-0") - self.send("251 OK GET RETURNED") - else: - logger.debug(f"Unknown GET parameter: {param}") - self.send("260-unknown") - self.send("260 OK GET RETURNED") - - return True - - def handleList(self, args): - """Handle LIST command. - - Args: - args: Command arguments - - Returns: - True to continue - """ - param = args.strip().upper() if args else "" - - if param == "OUTPUT_MODULES": - self.send("250-cthulhu") - self.send("250 OK MODULES LIST SENT") - elif param == "VOICES": - self.send("251-cthulhu\tdefault\tnone") - self.send("251 OK VOICE LIST SENT") - else: - self.send("250 OK LIST SENT") - - return True - - def handleHistory(self, args): - """Handle HISTORY command. - - Args: - args: Command arguments - - Returns: - True to continue - """ - parts = args.split() if args else [] - - if len(parts) >= 2 and parts[0].upper() == "GET": - subCmd = parts[1].upper() - if subCmd == "CLIENT_ID": - # Return a client ID - send both lines in single write - self.sendMultiLine("240-1", "240 OK CLIENT ID SENT") - elif subCmd == "MESSAGE_ID": - self.sendMultiLine(f"240-{self.msgId}", "240 OK MESSAGE ID SENT") - else: - self.sendMultiLine("240-0", "240 OK HISTORY GET") - elif len(parts) >= 1 and parts[0].upper() == "CURSOR": - self.send("200 OK CURSOR SET") - elif len(parts) >= 1 and parts[0].upper() == "SAY": - # History say - acknowledge - self.msgId += 1 - self.sendMessageQueued(self.msgId) - else: - self.send("200 OK HISTORY") - - return True - - def handleSet(self, args): - """Handle SET command. - - Args: - args: Command arguments - - Returns: - True to continue - """ - parts = args.split(None, 2) - if len(parts) < 2: - self.send(RESP_OK) - return True - - scope = parts[0].lower() - param = parts[1].upper() - value = parts[2] if len(parts) > 2 else "" - - if param == "CLIENT_NAME": - self.clientName = value - logger.info(f"SSIP client connected: {value}") - self.send(RESP_CLIENT_NAME_SET) - elif param == "PRIORITY": - self.send(f"200 OK PRIORITY SET") - elif param == "RATE": - self.send(f"200 OK RATE SET") - elif param == "PITCH": - self.send(f"200 OK PITCH SET") - elif param == "VOLUME": - self.send(f"200 OK VOLUME SET") - elif param == "VOICE_TYPE": - self.send(f"200 OK VOICE SET") - elif param == "LANGUAGE": - self.send(f"200 OK LANGUAGE SET") - elif param == "SSML_MODE": - self.send(f"200 OK SSML MODE SET") - elif param == "PUNCTUATION": - self.send(f"200 OK PUNCTUATION SET") - elif param == "SPELLING": - self.send(f"200 OK SPELLING SET") - elif param == "CAP_LET_RECOGN": - self.send(f"200 OK CAP LET RECOGNITION SET") - elif param == "OUTPUT_MODULE": - self.send(f"200 OK OUTPUT MODULE SET") - else: - logger.debug(f"Unknown SET parameter: {param}") - self.send(RESP_OK) - - return True - - def handleSpeak(self): - """Handle SPEAK command. - - Returns: - True to continue - """ - self.receivingData = True - self.dataBuffer = [] - self.send(RESP_RECEIVING_DATA) - return True - - def handleDataLine(self, line): - """Handle a line of SPEAK data. - - Args: - line: The data line - - Returns: - True to continue - """ - # Check for end-of-data marker (single dot) - if line == ".": - # End of data - process the message - self.receivingData = False - text = "\n".join(self.dataBuffer) - self.dataBuffer = [] - - # Send message ID and queued response together - self.msgId += 1 - self.sendMessageQueued(self.msgId) - - # Forward to Cthulhu - if text.strip(): - self.plugin.outputMessage(text.strip()) - - return True - - # Handle dot-escaping (lines starting with . have extra dot) - if line.startswith(".."): - line = line[1:] - - self.dataBuffer.append(line) - return True - - def handleStop(self, args): - """Handle STOP command. - - Args: - args: Command arguments - - Returns: - True to continue - """ - # Don't explicitly stop - let speech.speak(interrupt=True) handle it - # Calling stop() followed by speak() can cause race conditions - # where speech-dispatcher drops the new message - self.send(RESP_OK) - return True - - def handleCancel(self, args): - """Handle CANCEL command. - - Args: - args: Command arguments - - Returns: - True to continue - """ - self.send(RESP_OK) - return True - - -class SSIPProxy(Plugin): - """Plugin that provides an SSIP server interface for external applications.""" - - def __init__(self): - """Initialize the plugin.""" - super().__init__() - self.lock = Lock() - self.active = False - self.serverThread = None - self.serverSocket = None - self.clientSockets = [] # Track active client connections - self.clientLock = Lock() # Lock for client list - - @cthulhu_hookimpl - def activate(self): - """Activate the SSIP proxy plugin.""" - super().activate() - logger.info("Activating SSIP Proxy Plugin") - self.activateServer() - - @cthulhu_hookimpl - def deactivate(self): - """Deactivate the SSIP proxy plugin.""" - logger.info("Deactivating SSIP Proxy Plugin") - self.deactivateServer() - super().deactivate() - - def activateServer(self): - """Start the SSIP server thread.""" - with self.lock: - self.active = True - - # Only start if not already running - if self.serverThread is None or not self.serverThread.is_alive(): - self.serverThread = Thread(target=self.serverWorker) - self.serverThread.daemon = True - self.serverThread.start() - - def deactivateServer(self): - """Stop the SSIP server thread.""" - with self.lock: - self.active = False - - # Close all client connections first - with self.clientLock: - for clientSocket in self.clientSockets: - try: - clientSocket.close() - except Exception: - pass - self.clientSockets.clear() - - # Close the server socket to interrupt accept() - if self.serverSocket: - try: - self.serverSocket.close() - except Exception: - pass - - # Try to join the thread if it's alive, with a timeout - if self.serverThread and self.serverThread.is_alive(): - try: - self.serverThread.join(timeout=2.0) - except Exception as e: - logger.warning(f"Error stopping server thread: {e}") - - def isActive(self): - """Check if the server is active.""" - with self.lock: - return self.active - - def outputMessage(self, message): - """Output a message through Cthulhu's speech and braille systems. - - Args: - message: The message to output - """ - try: - # Use speech.speak directly for more reliable rapid-fire messages - from cthulhu import speech - speech.speak(message, interrupt=True) - - # Also update braille if possible - try: - scriptManager = self.app.getDynamicApiManager().getAPI('ScriptManager') - manager = scriptManager.get_manager() - script = manager.get_default_script() - if script: - # Flash message to braille - from cthulhu import braille - braille.displayMessage(message) - except Exception: - pass # Braille is optional - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, - f"SSIP output error: {e} for: {message}", True) - - def serverWorker(self): - """Worker thread that runs the SSIP server.""" - try: - # Create TCP socket - self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - try: - self.serverSocket.bind(("127.0.0.1", SSIP_PORT)) - except OSError as e: - logger.error(f"Cannot bind to port {SSIP_PORT}: {e}") - logger.error("Another process may be using this port.") - return - - self.serverSocket.listen(5) - debug.printMessage(debug.LEVEL_INFO, - f"SSIP Proxy listening on 127.0.0.1:{SSIP_PORT}", True) - - while self.isActive(): - # Check for new connections with timeout - try: - ready, _, _ = select.select([self.serverSocket], [], [], 0.8) - except (select.error, ValueError): - break - - if not ready: - continue - - try: - clientSocket, addr = self.serverSocket.accept() - debug.printMessage(debug.LEVEL_INFO, - f"SSIP client connected from {addr}", True) - - # Handle this client in a separate thread - clientThread = Thread( - target=self.handleClient, - args=(clientSocket,) - ) - clientThread.daemon = True - clientThread.start() - except Exception as e: - if self.isActive(): - logger.error(f"Error accepting connection: {e}") - - except Exception as e: - logger.error(f"SSIP server error: {e}") - finally: - if self.serverSocket: - try: - self.serverSocket.close() - except Exception: - pass - logger.info("SSIP Proxy server stopped") - - def handleClient(self, clientSocket): - """Handle a client connection. - - Args: - clientSocket: The client socket - """ - # Track this client socket - with self.clientLock: - self.clientSockets.append(clientSocket) - - # Disable Nagle's algorithm for immediate sending - clientSocket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) - clientSocket.settimeout(30.0) - connection = SSIPConnection(clientSocket, self) - buffer = "" - - try: - while self.isActive(): - try: - data = clientSocket.recv(4096) - if not data: - break - - buffer += data.decode("utf-8") - - # Process complete lines - while "\n" in buffer: - line, buffer = buffer.split("\n", 1) - line = line.rstrip("\r") - if not connection.handleLine(line): - return - except socket.timeout: - continue - except Exception as e: - logger.debug(f"Client read error: {e}") - break - finally: - # Remove from tracking list - with self.clientLock: - if clientSocket in self.clientSockets: - self.clientSockets.remove(clientSocket) - - try: - clientSocket.close() - except Exception: - pass - debug.printMessage(debug.LEVEL_INFO, "SSIP client disconnected", True) diff --git a/src/cthulhu/plugins/SimplePluginSystem/__init__.py b/src/cthulhu/plugins/SimplePluginSystem/__init__.py deleted file mode 100644 index 301e5ea..0000000 --- a/src/cthulhu/plugins/SimplePluginSystem/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - diff --git a/src/cthulhu/plugins/SimplePluginSystem/meson.build b/src/cthulhu/plugins/SimplePluginSystem/meson.build deleted file mode 100644 index d855a3c..0000000 --- a/src/cthulhu/plugins/SimplePluginSystem/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -simplepluginsystem_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - simplepluginsystem_python_sources, - subdir: 'cthulhu/plugins/SimplePluginSystem' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'SimplePluginSystem' -) \ No newline at end of file diff --git a/src/cthulhu/plugins/SimplePluginSystem/plugin.info b/src/cthulhu/plugins/SimplePluginSystem/plugin.info deleted file mode 100644 index cd4aad3..0000000 --- a/src/cthulhu/plugins/SimplePluginSystem/plugin.info +++ /dev/null @@ -1,9 +0,0 @@ -[Plugin] -Name = Simple Plugin System -Module = SimplePluginSystem -Description = Simple plugin system implementation for Cthulhu -Authors = Storm Dragon -Copyright = Copyright (c) 2025 Stormux -Website = https://git.stormux.org/storm/cthulhu -Version = 1.0 -Category = System diff --git a/src/cthulhu/plugins/SimplePluginSystem/plugin.py b/src/cthulhu/plugins/SimplePluginSystem/plugin.py deleted file mode 100644 index cc7d5a5..0000000 --- a/src/cthulhu/plugins/SimplePluginSystem/plugin.py +++ /dev/null @@ -1,408 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# - -"""Simple Plugin System for Cthulhu.""" - -import glob -import os -import importlib.util -import random -import string -import _thread -import logging -from subprocess import Popen, PIPE -import gettext - -from cthulhu.plugin import Plugin, cthulhu_hookimpl - -# Set up translation function -_ = gettext.gettext - -logger = logging.getLogger(__name__) - -# Global variables for API access -settings = None -speech = None -braille = None -input_event = None - -def outputMessage(Message): - """Output a message via speech and/or braille depending on settings.""" - if (settings.enableSpeech): - speech.speak(Message) - if (settings.enableBraille): - braille.displayMessage(Message) - -class SimplePluginSystem(Plugin): - """Simple plugin system implementation for Cthulhu. - - This plugin allows loading and managing simple script-based plugins - from a designated directory. - """ - - def __init__(self, *args, **kwargs): - """Initialize the plugin system.""" - super().__init__(*args, **kwargs) - logger.info("SimplePluginSystem plugin initialized") - self.plugin_list = [] - self.loaded = False - self.plugin_repo = os.path.expanduser('~') + "/.local/share/cthulhu/simple-plugins-enabled/" - self._signal_handler_id = None - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the plugin system.""" - # Skip if this activation call isn't for us - if plugin is not None and plugin is not self: - return - - logger.info("Activating SimplePluginSystem plugin") - try: - global settings - global speech - global braille - global input_event - - settings = self.app.getDynamicApiManager().getAPI('Settings') - speech = self.app.getDynamicApiManager().getAPI('Speech') - braille = self.app.getDynamicApiManager().getAPI('Braille') - input_event = self.app.getDynamicApiManager().getAPI('InputEvent') - - if not self.loaded: - self.load_plugins() - - except Exception as e: - logger.error(f"Error activating SimplePluginSystem plugin: {e}") - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the plugin system.""" - # Skip if this deactivation call isn't for us - if plugin is not None and plugin is not self: - return - - logger.info("Deactivating SimplePluginSystem plugin") - try: - # Remove all registered keybindings - for plugin in self.plugin_list: - self.unregisterShortcut(plugin['function'], plugin['shortcut']) - self.loaded = False - self.plugin_list = [] - except Exception as e: - logger.error(f"Error deactivating SimplePluginSystem plugin: {e}") - - def SetupShortcutAndHandle(self, currPluginSetting): - """Set up keyboard shortcuts for a plugin.""" - shortcut = '' - # just the modifier - if not currPluginSetting['shiftkey'] and not currPluginSetting['ctrlkey'] and not currPluginSetting['altkey']: - shortcut = 'kb:cthulhu+' + currPluginSetting['key'] - # cthulhu + alt - if not currPluginSetting['shiftkey'] and not currPluginSetting['ctrlkey'] and currPluginSetting['altkey']: - shortcut = 'kb:cthulhu+alt+' + currPluginSetting['key'] - # cthulhu + CTRL - if not currPluginSetting['shiftkey'] and currPluginSetting['ctrlkey'] and not currPluginSetting['altkey']: - shortcut = 'kb:cthulhu+control+' + currPluginSetting['key'] - # cthulhu + alt + CTRL - if not currPluginSetting['shiftkey'] and currPluginSetting['ctrlkey'] and currPluginSetting['altkey']: - shortcut = 'kb:cthulhu+alt+control+ ' + currPluginSetting['key'] - # cthulhu + shift - if currPluginSetting['shiftkey'] and not currPluginSetting['ctrlkey'] and not currPluginSetting['altkey']: - shortcut = 'kb:cthulhu+shift+' + currPluginSetting['key'] - # alt + shift - if currPluginSetting['shiftkey'] and not currPluginSetting['ctrlkey'] and currPluginSetting['altkey']: - shortcut = 'kb:alt+shift+' + currPluginSetting['key'] - if shortcut != '': - logger.debug(f"Registering shortcut: {shortcut}") - currPluginSetting['shortcut'] = shortcut - try: - # Try to use the translation function, fall back to plain text if it fails - plugin_name = _(currPluginSetting['pluginname']) - except Exception: - # If translation fails, use the original name - plugin_name = currPluginSetting['pluginname'] - logger.warning(f"Translation failed for plugin: {currPluginSetting['pluginname']}") - - self.registerGestureByString(currPluginSetting['function'], plugin_name, shortcut) - return currPluginSetting - - def id_generator(self, size=7, chars=string.ascii_letters): - """Generate a random ID string.""" - return ''.join(random.choice(chars) for _ in range(size)) - - def initSettings(self): - """Initialize default settings for a plugin.""" - currPluginSetting = { - 'pluginname': '', - 'functionname': '', - 'key': '', - 'shiftkey': False, - 'ctrlkey': False, - 'altkey': False, - 'startnotify': False, - 'stopnotify': False, - 'blockcall': False, - 'error': False, - 'exec': False, - 'parameters': '', - 'function': None, - 'inputeventhandler': None, - 'valid': False, - 'supressoutput': False, - 'shortcut': '' - } - return currPluginSetting - - def getPluginSettings(self, filepath, currPluginSetting): - """Parse plugin settings from filename and content.""" - try: - currPluginSetting['file'] = filepath - fileName, fileExtension = os.path.splitext(filepath) - if (fileExtension and (fileExtension != '')): # if there is an extension - currPluginSetting['loadable'] = (fileExtension.lower() == '.py') # only python is loadable - filename = os.path.basename(filepath) # filename - filename = os.path.splitext(filename)[0] # remove extension if we have one - # remove pluginname seperated by __-__ - filenamehelper = filename.split('__-__') - filename = filenamehelper[len(filenamehelper) - 1] - currPluginSetting['permission'] = os.access(filepath, os.X_OK) - currPluginSetting['pluginname'] = 'NoNameAvailable' - if len(filenamehelper) == 2: - currPluginSetting['pluginname'] = filenamehelper[0] - # now get shortcuts seperated by __+__ - filenamehelper = filename.split('__+__') - if len([y for y in filenamehelper if 'parameters_' in y.lower()]) == 1 and\ - len([y for y in filenamehelper if 'parameters_' in y.lower()][0]) > 11: - currPluginSetting['parameters'] = [y for y in filenamehelper if 'parameters_' in y.lower()][0][11:] - if len([y for y in filenamehelper if 'key_' in y.lower()]) == 1 and\ - len([y for y in filenamehelper if 'key_' in y.lower()][0]) > 4: - currPluginSetting['key'] = [y for y in filenamehelper if 'key_' in y.lower()][0][4] - if currPluginSetting['key'] == '': - settcurrPluginSetting = 'shift' in map(str.lower, filenamehelper) - currPluginSetting['ctrlkey'] = 'control' in map(str.lower, filenamehelper) - currPluginSetting['altkey'] = 'alt' in map(str.lower, filenamehelper) - currPluginSetting['startnotify'] = 'startnotify' in map(str.lower, filenamehelper) - currPluginSetting['stopnotify'] = 'stopnotify' in map(str.lower, filenamehelper) - currPluginSetting['blockcall'] = 'blockcall' in map(str.lower, filenamehelper) - currPluginSetting['error'] = 'error' in map(str.lower, filenamehelper) - currPluginSetting['supressoutput'] = 'supressoutput' in map(str.lower, filenamehelper) - currPluginSetting['exec'] = 'exec' in map(str.lower, filenamehelper) - currPluginSetting['loadmodule'] = 'loadmodule' in map(str.lower, filenamehelper) - currPluginSetting = self.readSettingsFromPlugin(currPluginSetting) - if not currPluginSetting['loadmodule']: - if not currPluginSetting['permission']: # subprocessing only works with exec permission - return self.initSettings() - if currPluginSetting['loadmodule'] and not currPluginSetting['loadable']: # sorry.. its not loadable only .py is loadable - return self.initSettings() - if (len(currPluginSetting['key']) > 1): # no shortcut - if not currPluginSetting['exec']: # and no exec -> the plugin make no sense because it isnt hooked anywhere - return self.initSettings() # so not load it (sets valid = False) - else: - currPluginSetting['key'] = '' # there is a strange key, but exec? ignore the key.. - currPluginSetting['valid'] = True # we could load everything - return currPluginSetting - except Exception as e: - logger.error(f"Error getting plugin settings: {e}") - return self.initSettings() - - def readSettingsFromPlugin(self, currPluginSetting): - """Read settings from plugin file content.""" - if not os.access(currPluginSetting['file'], os.R_OK): - return currPluginSetting - fileName, fileExtension = os.path.splitext(currPluginSetting['file']) - if (fileExtension and (fileExtension != '')): # if there is an extension - if (fileExtension.lower() != '.py') and \ - (fileExtension.lower() != '.sh'): - return currPluginSetting - else: - return currPluginSetting - - try: - with open(currPluginSetting['file'], "r") as pluginFile: - for line in pluginFile: - currPluginSetting['shiftkey'] = ('sopsproperty:shift' in line.lower().replace(" ", "")) or currPluginSetting['shiftkey'] - currPluginSetting['ctrlkey'] = ('sopsproperty:control' in line.lower().replace(" ", "")) or currPluginSetting['ctrlkey'] - currPluginSetting['altkey'] = ('sopsproperty:alt' in line.lower().replace(" ", "")) or currPluginSetting['altkey'] - currPluginSetting['startnotify'] = ('sopsproperty:startnotify' in line.lower().replace(" ", "")) or currPluginSetting['startnotify'] - currPluginSetting['stopnotify'] = ('sopsproperty:stopnotify' in line.lower().replace(" ", "")) or currPluginSetting['stopnotify'] - currPluginSetting['blockcall'] = ('sopsproperty:blockcall' in line.lower().replace(" ", "")) or currPluginSetting['blockcall'] - currPluginSetting['error'] = ('sopsproperty:error' in line.lower().replace(" ", "")) or currPluginSetting['error'] - currPluginSetting['supressoutput'] = ('sopsproperty:supressoutput' in line.lower().replace(" ", "")) or currPluginSetting['supressoutput'] - currPluginSetting['exec'] = ('sopsproperty:exec' in line.lower().replace(" ", "")) or currPluginSetting['exec'] - currPluginSetting['loadmodule'] = ('sopsproperty:loadmodule' in line.lower().replace(" ", "")) or currPluginSetting['loadmodule'] - except Exception as e: - logger.error(f"Error reading plugin file: {e}") - - return currPluginSetting - - def buildPluginSubprocess(self, currPluginSetting): - """Build a function to execute a plugin as a subprocess.""" - currplugin = "\'\"" + currPluginSetting['file'] + "\" " + currPluginSetting['parameters'] + "\'" - pluginname = currPluginSetting['pluginname'] - if currPluginSetting['blockcall']: - pluginname = "blocking " + pluginname - fun_body = "global " + currPluginSetting['functionname'] + "\n" - fun_body += "def " + currPluginSetting['functionname'] + "(script=None, inputEvent=None):\n" - if currPluginSetting['startnotify']: - fun_body += " outputMessage('start " + pluginname + "')\n" - fun_body += " p = Popen(" + currplugin + ", stdout=PIPE, stderr=PIPE, shell=True)\n" - fun_body += " stdout, stderr = p.communicate()\n" - fun_body += " message = ''\n" - fun_body += " if not " + str(currPluginSetting['supressoutput']) + " and stdout:\n" - fun_body += " message += str(stdout, \"utf-8\")\n" - fun_body += " if " + str(currPluginSetting['error']) + " and stderr:\n" - fun_body += " message += ' error: ' + str(stderr, \"utf-8\")\n" - fun_body += " outputMessage(message)\n" - if currPluginSetting['stopnotify']: - fun_body += " outputMessage('finish " + pluginname + "')\n" - fun_body += " return True\n\n" - fun_body += "global " + currPluginSetting['functionname'] + "T\n" - fun_body += "def " + currPluginSetting['functionname'] + "T(script=None, inputEvent=None):\n" - fun_body += " _thread.start_new_thread(" + currPluginSetting['functionname'] + ",(script, inputEvent))\n\n" - return fun_body - - def buildPluginExec(self, currPluginSetting): - """Build a function to execute a plugin as a Python module.""" - pluginname = currPluginSetting['pluginname'] - if currPluginSetting['blockcall']: - pluginname = "blocking " + pluginname - fun_body = "global " + currPluginSetting['functionname'] + "\n" - fun_body += "def " + currPluginSetting['functionname'] + "(script=None, inputEvent=None):\n" - if currPluginSetting['startnotify']: - fun_body += " outputMessage('start " + pluginname + "')\n" - fun_body += " try:\n" - fun_body += " spec = importlib.util.spec_from_file_location(\"" + currPluginSetting['functionname'] + "\",\"" + currPluginSetting['file'] + "\")\n" - fun_body += " " + currPluginSetting['functionname'] + "Module = importlib.util.module_from_spec(spec)\n" - fun_body += " spec.loader.exec_module(" + currPluginSetting['functionname'] + "Module)\n" - fun_body += " except Exception as e:\n" - fun_body += " logger.error(f\"Error executing plugin {pluginname}: {e}\")\n" - if currPluginSetting['error']: - fun_body += " outputMessage(\"Error while executing " + pluginname + "\")\n" - if currPluginSetting['stopnotify']: - fun_body += " outputMessage('finish " + pluginname + "')\n" - fun_body += " return True\n\n" - fun_body += "global " + currPluginSetting['functionname'] + "T\n" - fun_body += "def " + currPluginSetting['functionname'] + "T(script=None, inputEvent=None):\n" - fun_body += " _thread.start_new_thread(" + currPluginSetting['functionname'] + ",(script, inputEvent))\n\n" - return fun_body - - def getFunctionName(self, currPluginSetting): - """Generate a unique function name for a plugin.""" - currPluginSetting['functionname'] = '' - while currPluginSetting['functionname'] == '' or currPluginSetting['functionname'] + 'T' in globals() or currPluginSetting['functionname'] in globals(): - currPluginSetting['functionname'] = self.id_generator() - return currPluginSetting - - def registerGestureByString(self, function, description, shortcut, globalBinding=True): - """Register a keyboard shortcut for a function. - - This is a compatibility wrapper for the new plugin system. - """ - try: - if self.app: - api_helper = self.app.getAPIHelper() - if api_helper: - api_helper.registerGestureByString( - function, - description, - shortcut, - 'default', - 'cthulhu', - True, - globalBinding=globalBinding, - contextName=self.module_name - ) - logger.debug(f"Registered shortcut {shortcut} for {description}") - return True - else: - logger.error("Could not get APIHelper") - else: - logger.error("No app reference available") - except Exception as e: - logger.error(f"Error registering shortcut {shortcut}: {e}") - - def unregisterShortcut(self, function, shortcut): - """Unregister a keyboard shortcut for a function. - - This is a compatibility wrapper for the new plugin system. - """ - try: - if self.app: - api_helper = self.app.getAPIHelper() - if api_helper and hasattr(api_helper, 'unregisterShortcut'): - api_helper.unregisterShortcut(shortcut) - logger.debug(f"Unregistered shortcut {shortcut}") - return True - else: - logger.error("Could not get APIHelper or unregisterShortcut method") - else: - logger.error("No app reference available") - except Exception as e: - logger.error(f"Error unregistering shortcut {shortcut}: {e}") - - def load_plugins(self): - """Load and setup all plugins in the plugin repository.""" - if not self.loaded: - try: - logger.info(f"Loading plugins from {self.plugin_repo}") - plugin_files = glob.glob(self.plugin_repo + '*') - self.plugin_list = [] # Reset the plugin list to avoid confusion - - for currplugin in plugin_files: - try: - # Ensure currplugin is a valid path string - if not isinstance(currplugin, (str, bytes, os.PathLike)): - logger.error(f"Invalid plugin path: {type(currplugin)}") - continue - - currPluginSetting = self.initSettings() - currPluginSetting = self.getPluginSettings(currplugin, currPluginSetting) - - if not currPluginSetting['valid']: - logger.debug(f"Skipping invalid plugin: {currplugin}") - continue - - currPluginSetting = self.getFunctionName(currPluginSetting) - - if currPluginSetting['loadmodule']: - exec(self.buildPluginExec(currPluginSetting)) # load as python module - else: - exec(self.buildPluginSubprocess(currPluginSetting)) # run as subprocess - - if currPluginSetting['blockcall']: - currPluginSetting['function'] = globals()[currPluginSetting['functionname']] # non threaded - else: - currPluginSetting['function'] = globals()[currPluginSetting['functionname'] + "T"] # T = Threaded - - if currPluginSetting['exec']: # exec on load if we want - currPluginSetting['function']() - - if not currPluginSetting['key'] == '': - currPluginSetting = self.SetupShortcutAndHandle(currPluginSetting) - - logger.debug(f"Loaded plugin: {currPluginSetting['pluginname']}") - self.plugin_list.append(currPluginSetting) # store in a list - except Exception as e: - logger.error(f"Error loading plugin {currplugin}: {e}") - - self.loaded = True - logger.info(f"Loaded {len(self.plugin_list)} plugins") - except Exception as e: - logger.error(f"Error in load_plugins: {e}") diff --git a/src/cthulhu/plugins/SpeechHistory/__init__.py b/src/cthulhu/plugins/SpeechHistory/__init__.py deleted file mode 100644 index 08c77bb..0000000 --- a/src/cthulhu/plugins/SpeechHistory/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .plugin import SpeechHistory - diff --git a/src/cthulhu/plugins/SpeechHistory/meson.build b/src/cthulhu/plugins/SpeechHistory/meson.build deleted file mode 100644 index 75dd195..0000000 --- a/src/cthulhu/plugins/SpeechHistory/meson.build +++ /dev/null @@ -1,15 +0,0 @@ -speechhistory_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - speechhistory_python_sources, - subdir: 'cthulhu/plugins/SpeechHistory' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'SpeechHistory' -) - diff --git a/src/cthulhu/plugins/SpeechHistory/plugin.info b/src/cthulhu/plugins/SpeechHistory/plugin.info deleted file mode 100644 index 3e3a156..0000000 --- a/src/cthulhu/plugins/SpeechHistory/plugin.info +++ /dev/null @@ -1,8 +0,0 @@ -name = Speech History -version = 1.2.0 -description = Shows speech history and a live floating monitor of spoken text from Cthulhu -authors = Stormux -website = https://git.stormux.org/storm/cthulhu -copyright = Copyright 2025 Stormux -builtin = false -hidden = false diff --git a/src/cthulhu/plugins/SpeechHistory/plugin.py b/src/cthulhu/plugins/SpeechHistory/plugin.py deleted file mode 100644 index ba476f8..0000000 --- a/src/cthulhu/plugins/SpeechHistory/plugin.py +++ /dev/null @@ -1,541 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Speech history and speech monitor plugin for Cthulhu.""" - -import logging - -import gi -gi.require_version("Gtk", "3.0") -from gi.repository import Gtk, Gdk, GLib - -from cthulhu.plugin import Plugin, cthulhu_hookimpl -from cthulhu import debug -from cthulhu import speech -from cthulhu import speech_history - -logger = logging.getLogger(__name__) - - -class SpeechHistory(Plugin): - """Plugin that provides speech history and a live speech monitor.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._activated = False - self._kbOpenWindow = None - self._kbToggleMonitor = None - - # Speech history window state - self._window = None - self._filterEntry = None - self._filterText = "" - self._listStore = None - self._filterModel = None - self._treeView = None - self._capturePaused = False - - # Live monitor window state - self._monitorWindow = None - self._monitorTextView = None - self._monitorTextBuffer = None - self._monitorEndMark = None - self._monitorLineCount = 0 - self._monitorMaxLines = 500 - - @cthulhu_hookimpl - def activate(self, plugin=None): - if plugin is not None and plugin is not self: - return - - if self._activated: - return True - - try: - self._register_keybindings() - self._activated = True - return True - except Exception: - logger.exception("Error activating SpeechHistory plugin") - return False - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - if plugin is not None and plugin is not self: - return - - try: - self._close_window() - self._disable_monitor() - self._kbOpenWindow = None - self._kbToggleMonitor = None - self._activated = False - return True - except Exception: - logger.exception("Error deactivating SpeechHistory plugin") - return False - - def _register_keybindings(self): - if not self.app: - debug.printMessage( - debug.LEVEL_INFO, - "SpeechHistory: No app reference; cannot register keybindings", - True, - ) - return - - historyGesture = "kb:cthulhu+control+h" - historyDescription = "Open speech history" - self._kbOpenWindow = self.registerGestureByString( - self._open_window, - historyDescription, - historyGesture, - ) - - monitorGesture = "kb:cthulhu+shift+d" - monitorDescription = "Toggle speech monitor" - self._kbToggleMonitor = self.registerGestureByString( - self._toggle_monitor, - monitorDescription, - monitorGesture, - ) - - if not self._kbOpenWindow: - debug.printMessage( - debug.LEVEL_INFO, - f"SpeechHistory: Failed to register keybinding {historyGesture}", - True, - ) - - if not self._kbToggleMonitor: - debug.printMessage( - debug.LEVEL_INFO, - f"SpeechHistory: Failed to register keybinding {monitorGesture}", - True, - ) - - # Live monitor methods - - def _toggle_monitor(self, script=None, inputEvent=None): - try: - if self._monitorWindow is not None: - self._disable_monitor() - self._present_message("Speech monitor disabled.") - return True - - self._enable_monitor() - self._present_message("Speech monitor enabled.") - return True - except Exception: - logger.exception("Error toggling speech monitor") - self._disable_monitor() - self._present_message("Error toggling speech monitor.") - return False - - def _enable_monitor(self): - if self._monitorWindow is not None: - self._monitorWindow.show_all() - return - - self._create_monitor_window() - speech.set_monitor_callbacks(writeText=self._on_spoken_text) - self._monitorWindow.show_all() - - def _disable_monitor(self): - speech.set_monitor_callbacks(writeText=None) - - if self._monitorWindow is not None: - self._monitorWindow.destroy() - - def _create_monitor_window(self): - self._monitorWindow = Gtk.Window(title="Speech Monitor - Cthulhu") - self._monitorWindow.set_default_size(900, 320) - self._monitorWindow.set_modal(False) - self._monitorWindow.set_border_width(8) - self._monitorWindow.set_keep_above(True) - self._monitorWindow.set_accept_focus(False) - self._monitorWindow.set_focus_on_map(False) - self._monitorWindow.set_skip_taskbar_hint(True) - self._monitorWindow.set_skip_pager_hint(True) - self._monitorWindow.set_type_hint(Gdk.WindowTypeHint.UTILITY) - - self._monitorWindow.connect("destroy", self._on_monitor_window_destroy) - self._monitorWindow.connect("key-press-event", self._on_monitor_window_key_press) - - mainBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8) - - scrolledWindow = Gtk.ScrolledWindow() - scrolledWindow.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) - - self._monitorTextView = Gtk.TextView() - self._monitorTextView.set_editable(False) - self._monitorTextView.set_cursor_visible(False) - self._monitorTextView.set_can_focus(False) - self._monitorTextView.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) - self._monitorTextView.set_accepts_tab(False) - self._monitorTextView.set_left_margin(6) - self._monitorTextView.set_right_margin(6) - self._monitorTextView.set_top_margin(6) - self._monitorTextView.set_bottom_margin(6) - - textAccessible = self._monitorTextView.get_accessible() - if textAccessible: - textAccessible.set_name("Speech monitor output") - - self._monitorTextBuffer = self._monitorTextView.get_buffer() - self._monitorEndMark = self._monitorTextBuffer.create_mark( - "monitorEnd", - self._monitorTextBuffer.get_end_iter(), - False, - ) - self._monitorLineCount = 0 - - scrolledWindow.add(self._monitorTextView) - mainBox.pack_start(scrolledWindow, True, True, 0) - - buttonRow = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8) - buttonRow.set_halign(Gtk.Align.END) - - clearButton = Gtk.Button(label="Clear") - closeButton = Gtk.Button(label="Close") - clearButton.connect("clicked", self._on_monitor_clear_clicked) - closeButton.connect("clicked", self._on_monitor_close_clicked) - - buttonRow.pack_start(clearButton, False, False, 0) - buttonRow.pack_start(closeButton, False, False, 0) - mainBox.pack_start(buttonRow, False, False, 0) - - self._monitorWindow.add(mainBox) - - def _on_monitor_close_clicked(self, button): - self._disable_monitor() - - def _on_monitor_clear_clicked(self, button): - if self._monitorTextBuffer is None: - return - - self._monitorTextBuffer.set_text("") - self._monitorLineCount = 0 - - def _on_monitor_window_destroy(self, widget): - speech.set_monitor_callbacks(writeText=None) - - self._monitorWindow = None - self._monitorTextView = None - self._monitorTextBuffer = None - self._monitorEndMark = None - self._monitorLineCount = 0 - - def _on_monitor_window_key_press(self, widget, event): - if event.keyval == Gdk.KEY_Escape: - self._disable_monitor() - return True - - return False - - def _on_spoken_text(self, text): - if not text or not isinstance(text, str): - return - - GLib.idle_add(self._append_text_on_main_thread, text) - - def _append_text_on_main_thread(self, text): - if self._monitorTextBuffer is None: - return False - - self._monitorTextBuffer.insert(self._monitorTextBuffer.get_end_iter(), f"{text}\n") - self._monitorLineCount += 1 - - if self._monitorLineCount > self._monitorMaxLines: - excess = self._monitorLineCount - self._monitorMaxLines - startIter = self._monitorTextBuffer.get_start_iter() - cutIter = self._monitorTextBuffer.get_iter_at_line(excess) - self._monitorTextBuffer.delete(startIter, cutIter) - self._monitorLineCount = self._monitorMaxLines - - if self._monitorEndMark is not None and self._monitorTextView is not None: - self._monitorTextBuffer.move_mark( - self._monitorEndMark, - self._monitorTextBuffer.get_end_iter(), - ) - self._monitorTextView.scroll_mark_onscreen(self._monitorEndMark) - - return False - - # Speech history methods - - def _open_window(self, script=None, inputEvent=None): - try: - if self._window: - self._window.present() - return True - - self._pause_capture() - - self._create_window() - self._window.show_all() - if self._treeView and len(self._filterModel) > 0: - self._treeView.grab_focus() - self._treeView.set_cursor(Gtk.TreePath.new_first()) - elif self._filterEntry: - self._filterEntry.grab_focus() - - return True - except Exception: - logger.exception("Error opening SpeechHistory window") - self._resume_capture() - return False - - def _create_window(self): - self._window = Gtk.Window(title="Speech History - Cthulhu") - self._window.set_default_size(700, 420) - self._window.set_modal(True) - self._window.set_border_width(10) - - self._window.connect("destroy", self._on_window_destroy) - self._window.connect("key-press-event", self._on_window_key_press) - - mainBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) - - self._filterText = "" - - filterRow = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) - filterLabel = Gtk.Label(label="_Filter:") - filterLabel.set_use_underline(True) - filterLabel.set_halign(Gtk.Align.START) - - self._filterEntry = Gtk.Entry() - self._filterEntry.set_hexpand(True) - filterLabel.set_mnemonic_widget(self._filterEntry) - self._filterEntry.connect("changed", self._on_filter_changed) - - filterRow.pack_start(filterLabel, False, False, 0) - filterRow.pack_start(self._filterEntry, True, True, 0) - mainBox.pack_start(filterRow, False, False, 0) - - self._listStore = Gtk.ListStore(str) - self._filterModel = self._listStore.filter_new() - self._filterModel.set_visible_func(self._filter_visible_func) - - self._treeView = Gtk.TreeView(model=self._filterModel) - self._treeView.set_headers_visible(True) - - selection = self._treeView.get_selection() - selection.set_mode(Gtk.SelectionMode.SINGLE) - - textRenderer = Gtk.CellRendererText() - textRenderer.set_property("wrap-width", 640) - textRenderer.set_property("wrap-mode", 2) - textColumn = Gtk.TreeViewColumn("Spoken Text", textRenderer, text=0) - textColumn.set_resizable(True) - textColumn.set_expand(True) - self._treeView.append_column(textColumn) - - scrolled = Gtk.ScrolledWindow() - scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) - scrolled.add(self._treeView) - mainBox.pack_start(scrolled, True, True, 0) - - buttonRow = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) - buttonRow.set_halign(Gtk.Align.END) - - copyButton = Gtk.Button(label="Copy to clipboard") - removeButton = Gtk.Button(label="Remove from history") - closeButton = Gtk.Button(label="Close") - - copyButton.connect("clicked", self._on_copy_clicked) - removeButton.connect("clicked", self._on_remove_clicked) - closeButton.connect("clicked", self._on_close_clicked) - - buttonRow.pack_start(copyButton, False, False, 0) - buttonRow.pack_start(removeButton, False, False, 0) - buttonRow.pack_start(closeButton, False, False, 0) - mainBox.pack_start(buttonRow, False, False, 0) - - self._window.add(mainBox) - - self._refresh_list(selectFirst=True) - - def _on_filter_changed(self, entry): - try: - self._filterText = entry.get_text() or "" - if self._filterModel: - self._filterModel.refilter() - except Exception: - logger.exception("Error updating speech history filter") - - def _filter_visible_func(self, model, treeIter, data=None): - try: - filterText = (self._filterText or "").strip().lower() - if not filterText: - return True - - spokenText = model[treeIter][0] or "" - return spokenText.lower().startswith(filterText) - except Exception: - return True - - def _refresh_list(self, selectFirst=False): - try: - if not self._listStore: - return - - self._listStore.clear() - - items = speech_history.get_items() - for item in items: - self._listStore.append([item]) - - if self._filterModel: - self._filterModel.refilter() - - if selectFirst and self._treeView and len(self._filterModel) > 0: - selection = self._treeView.get_selection() - selection.select_path(Gtk.TreePath.new_first()) - except Exception: - logger.exception("Error refreshing speech history list") - - def _get_selected_text(self): - try: - if not self._treeView: - return None - - selection = self._treeView.get_selection() - model, treeIter = selection.get_selected() - if not treeIter: - return None - - return model[treeIter][0] - except Exception: - logger.exception("Error getting selected speech history item") - return None - - def _on_copy_clicked(self, button): - try: - selectedText = self._get_selected_text() - if not selectedText: - self._present_message("No speech history item selected.") - return - - clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) - clipboard.set_text(selectedText, -1) - clipboard.store() - - self._present_message("Copied to clipboard.") - except Exception: - logger.exception("Error copying speech history item to clipboard") - self._present_message("Error copying to clipboard.") - - def _on_remove_clicked(self, button): - try: - selectedText = self._get_selected_text() - if not selectedText: - self._present_message("No speech history item selected.") - return - - removed = speech_history.remove(selectedText) - if removed: - self._refresh_list(selectFirst=True) - self._present_message("Removed from history.") - else: - self._present_message("Item not found in history.") - except Exception: - logger.exception("Error removing speech history item") - self._present_message("Error removing item from history.") - - def _on_close_clicked(self, button): - self._close_window() - - def _close_window(self): - try: - if self._window: - self._window.destroy() - except Exception: - logger.exception("Error closing SpeechHistory window") - self._resume_capture() - - def _on_window_destroy(self, widget): - self._window = None - self._filterEntry = None - self._listStore = None - self._filterModel = None - self._treeView = None - self._filterText = "" - self._resume_capture() - - def _on_window_key_press(self, widget, event): - try: - if event.keyval == Gdk.KEY_Escape: - self._close_window() - return True - - if not self._filterEntry or self._filterEntry.is_focus(): - return False - - if event.keyval == Gdk.KEY_BackSpace: - currentText = self._filterEntry.get_text() or "" - if currentText: - self._filterEntry.set_text(currentText[:-1]) - self._filterEntry.set_position(-1) - return True - return False - - modifierMask = ( - Gdk.ModifierType.CONTROL_MASK - | Gdk.ModifierType.MOD1_MASK - | Gdk.ModifierType.SUPER_MASK - | Gdk.ModifierType.META_MASK - ) - if event.state & modifierMask: - return False - - keyUnicode = Gdk.keyval_to_unicode(event.keyval) - if not keyUnicode: - return False - - charTyped = chr(keyUnicode) - if not charTyped.isprintable(): - return False - - self._filterEntry.grab_focus() - currentText = self._filterEntry.get_text() or "" - self._filterEntry.set_text(currentText + charTyped) - self._filterEntry.set_position(-1) - return True - except Exception: - logger.exception("Error handling key press in SpeechHistory window") - return False - - def _pause_capture(self): - if self._capturePaused: - return - - speech_history.pause_capture(reason="SpeechHistory window open") - self._capturePaused = True - - def _resume_capture(self): - if not self._capturePaused: - return - - speech_history.resume_capture(reason="SpeechHistory window closed") - self._capturePaused = False - - def _present_message(self, message): - try: - if not self.app: - debug.printMessage(debug.LEVEL_INFO, f"SpeechHistory: {message}", True) - return - - state = self.app.getDynamicApiManager().getAPI("CthulhuState") - if state and state.activeScript: - state.activeScript.presentMessage(message, resetStyles=False) - else: - debug.printMessage(debug.LEVEL_INFO, f"SpeechHistory: {message}", True) - except Exception: - logger.exception("Error presenting message from SpeechHistory") diff --git a/src/cthulhu/plugins/WindowTitleReader/__init__.py b/src/cthulhu/plugins/WindowTitleReader/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/cthulhu/plugins/WindowTitleReader/meson.build b/src/cthulhu/plugins/WindowTitleReader/meson.build deleted file mode 100644 index 39cb587..0000000 --- a/src/cthulhu/plugins/WindowTitleReader/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -windowtitlereader_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - windowtitlereader_python_sources, - subdir: 'cthulhu/plugins/WindowTitleReader' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'WindowTitleReader' -) diff --git a/src/cthulhu/plugins/WindowTitleReader/plugin.info b/src/cthulhu/plugins/WindowTitleReader/plugin.info deleted file mode 100644 index 4f9edb0..0000000 --- a/src/cthulhu/plugins/WindowTitleReader/plugin.info +++ /dev/null @@ -1,8 +0,0 @@ -name = Window Title Reader -version = 1.0.0 -description = Toggle window title reader, including Wine Desktop titles -authors = Stormux -website = https://git.stormux.org/storm/cthulhu -copyright = Copyright 2026 -builtin = false -hidden = false diff --git a/src/cthulhu/plugins/WindowTitleReader/plugin.py b/src/cthulhu/plugins/WindowTitleReader/plugin.py deleted file mode 100644 index b1c55ff..0000000 --- a/src/cthulhu/plugins/WindowTitleReader/plugin.py +++ /dev/null @@ -1,619 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# - -"""Window Title Reader plugin for Cthulhu.""" - -import logging - -from gi.repository import GLib - -from cthulhu.ax_object import AXObject -from cthulhu import debug -from cthulhu import dbus_service -from cthulhu.plugin import Plugin, cthulhu_hookimpl - -xlibAvailable = True -xlibImportError = None -try: - from Xlib import X - from Xlib import display as xDisplay - from Xlib import error as xError -except Exception as error: - xlibAvailable = False - xlibImportError = error - X = None - xDisplay = None - xError = None - -pluginLogger = logging.getLogger(__name__) - - -class WindowTitleReader(Plugin): - """Speak the active window title when toggled on.""" - - def __init__(self, *positionalArgs, **keywordArgs): - super().__init__(*positionalArgs, **keywordArgs) - self._activated = False - self._enabled = False - self._pollSourceId = None - self._pollIntervalMs = 100 - self._fallbackDelayMs = 250 - self._pendingFallbackSourceId = None - self._lastActiveWindowId = None - self._lastTitle = None - self._display = None - self._root = None - self._atoms = {} - self._wineDesktopLabel = "Wine Desktop" - self._kbToggleTracking = None - debug.printMessage(debug.LEVEL_INFO, "WindowTitleReader: Plugin initialized", True) - - @cthulhu_hookimpl - def activate(self, plugin=None): - if plugin is not None and plugin is not self: - return - - if self._activated: - debug.printMessage(debug.LEVEL_INFO, "WindowTitleReader: Already activated", True) - return True - - self._register_keybinding() - self.app.getDynamicApiManager().registerAPI( - "WindowTitleReader", - self, - overwrite=True, - ) - if xlibAvailable or self._get_i3_title_context() is not None: - self._start_tracking() - self._activated = True - debug.printMessage(debug.LEVEL_INFO, "WindowTitleReader: Activated", True) - return True - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - if plugin is not None and plugin is not self: - return - - self._stop_tracking() - if self.app: - self.app.getDynamicApiManager().unregisterAPI("WindowTitleReader") - self._activated = False - debug.printMessage(debug.LEVEL_INFO, "WindowTitleReader: Deactivated", True) - return True - - def _register_keybinding(self): - if not self.app: - debug.printMessage( - debug.LEVEL_INFO, - "WindowTitleReader: No app reference; cannot register keybinding", - True, - ) - return - - gestureString = "kb:cthulhu+control+shift+w" - description = "Toggle window title reader" - - self._kbToggleTracking = self.registerGestureByString( - self._toggle_tracking, - description, - gestureString, - ) - - if self._kbToggleTracking: - debug.printMessage( - debug.LEVEL_INFO, - f"WindowTitleReader: Registered keybinding {gestureString}", - True, - ) - else: - debug.printMessage( - debug.LEVEL_INFO, - f"WindowTitleReader: Failed to register keybinding {gestureString}", - True, - ) - - def _toggle_tracking(self, script=None, inputEvent=None): - if self._enabled: - self._enabled = False - self._lastTitle = None - self._present_message("Window title reader off") - return True - - if not xlibAvailable and self._get_i3_title_context() is None: - self._present_message("Window title reader unavailable") - debug.printMessage( - debug.LEVEL_INFO, - f"WindowTitleReader: python-xlib unavailable: {xlibImportError}", - True, - ) - return True - - if self._start_tracking(): - self._enabled = True - self._poll_window_title() - self._present_message("Window title reader on") - else: - self._present_message("Window title reader unavailable") - return True - - @dbus_service.parameterized_command - def set_enabled( - self, - enabled: bool, - notify_user: bool = True - ) -> bool: - """Enable or disable window title reader tracking.""" - - if enabled: - if self._enabled: - if notify_user: - self._present_message("Window title reader on") - return True - - if not xlibAvailable and self._get_i3_title_context() is None: - if notify_user: - self._present_message("Window title reader unavailable") - debug.printMessage( - debug.LEVEL_INFO, - f"WindowTitleReader: python-xlib unavailable: {xlibImportError}", - True, - ) - return False - - if self._start_tracking(): - self._enabled = True - self._poll_window_title() - if notify_user: - self._present_message("Window title reader on") - return True - - if notify_user: - self._present_message("Window title reader unavailable") - return False - - if self._enabled: - self._enabled = False - self._lastTitle = None - - if notify_user: - self._present_message("Window title reader off") - return True - - @dbus_service.getter - def get_enabled(self) -> bool: - """Returns True if the window title reader is enabled.""" - - return self._enabled - - def _present_message(self, messageText): - if not self.app: - return - - try: - appState = self.app.getDynamicApiManager().getAPI("CthulhuState") - if appState and appState.activeScript: - appState.activeScript.presentMessage(messageText, resetStyles=False) - except Exception: - pluginLogger.exception("WindowTitleReader: Failed to present message") - - def _start_tracking(self): - if self._pollSourceId is not None: - return True - - try: - if self._get_i3_title_context() is None: - if not self._ensure_x11_display(): - return False - self._pollSourceId = GLib.timeout_add(self._pollIntervalMs, self._poll_window_title) - self._poll_window_title() - return True - except Exception as error: - debug.printMessage( - debug.LEVEL_INFO, - f"WindowTitleReader: Failed to start tracking: {error}", - True, - ) - pluginLogger.exception("WindowTitleReader: Failed to start tracking") - self._stop_tracking() - return False - - def _stop_tracking(self): - if self._pendingFallbackSourceId is not None: - GLib.source_remove(self._pendingFallbackSourceId) - self._pendingFallbackSourceId = None - - if self._pollSourceId is not None: - GLib.source_remove(self._pollSourceId) - self._pollSourceId = None - - self._enabled = False - self._lastActiveWindowId = None - self._lastTitle = None - self._cleanup_display() - - def _cleanup_display(self): - if self._display is None: - return - - try: - self._display.close() - except Exception: - pluginLogger.exception("WindowTitleReader: Failed to close display") - - self._display = None - self._root = None - self._atoms = {} - - def _init_atoms(self): - self._atoms = { - "NET_ACTIVE_WINDOW": self._display.intern_atom("_NET_ACTIVE_WINDOW"), - "NET_WM_NAME": self._display.intern_atom("_NET_WM_NAME"), - "WM_NAME": self._display.intern_atom("WM_NAME"), - } - - def _poll_window_title(self): - if self._pollSourceId is None: - return False - - try: - i3Context = self._get_i3_title_context() - if i3Context is not None: - activeWindowId, windowTitle = i3Context - else: - if not self._ensure_x11_display(): - self._lastTitle = None - return True - activeWindow = self._get_active_window() - if not activeWindow: - self._lastTitle = None - return True - activeWindowId = activeWindow.id - windowTitle = self._get_current_title(activeWindow) - - if activeWindowId is None or not windowTitle: - self._lastTitle = None - return True - - if self._lastActiveWindowId is None: - self._lastActiveWindowId = activeWindowId - elif activeWindowId != self._lastActiveWindowId: - self._lastActiveWindowId = activeWindowId - self._schedule_fallback_title() - - if self._enabled and windowTitle != self._lastTitle: - self._present_title(windowTitle) - self._lastTitle = windowTitle - except Exception as error: - debug.printMessage(debug.LEVEL_INFO, f"WindowTitleReader: Poll error: {error}", True) - pluginLogger.exception("WindowTitleReader: Poll failed") - - return True - - def _schedule_fallback_title(self): - if self._enabled: - return - - if self._pendingFallbackSourceId is not None: - GLib.source_remove(self._pendingFallbackSourceId) - - self._pendingFallbackSourceId = GLib.timeout_add( - self._fallbackDelayMs, - self._present_pending_fallback_title, - ) - - def _present_pending_fallback_title(self): - self._pendingFallbackSourceId = None - titleText = self.get_fallback_title() - if titleText: - self._present_title(titleText) - return False - - def get_fallback_title(self, atspiTitle=None): - """Returns the X11 title when AT-SPI has not exposed an equivalent title.""" - - i3Context = self._get_i3_title_context() - if i3Context is not None: - _windowId, titleText = i3Context - if not titleText: - return "" - if atspiTitle is None: - atspiTitle = self._get_atspi_title() - if self._titles_match(atspiTitle, titleText): - return "" - return titleText - - if not xlibAvailable and self._display is None: - return "" - - startedTracking = self._pollSourceId is not None - if not startedTracking and not self._start_tracking(): - return "" - if not self._ensure_x11_display(): - return "" - - activeWindow = self._get_active_window() - titleText = self._get_current_title(activeWindow) if activeWindow else "" - if not titleText: - return "" - - if atspiTitle is None: - atspiTitle = self._get_atspi_title() - - if self._titles_match(atspiTitle, titleText): - return "" - - return titleText - - def _get_i3_title_context(self): - """Returns authoritative i3 window id/title, or None when i3 is not active.""" - - if not self.app: - return None - - try: - adapter = self.app.getCompositorStateAdapter() - snapshot = adapter.get_snapshot() if adapter else None - except Exception: - return None - - if snapshot is None or getattr(snapshot, "backend_name", "") != "i3-ipc": - return None - - if getattr(snapshot, "focused_workspace_empty", None) is True: - return (None, "") - - windowId = getattr(snapshot, "focused_window_id", None) - titleText = str(getattr(snapshot, "focused_window_title", "") or "").strip() - if windowId is None: - return None - - if not titleText or self._is_wine_desktop_title(titleText): - if not self._ensure_x11_display(): - return None - try: - activeWindow = self._display.create_resource_object("window", windowId) - except Exception: - return None - titleText = self._get_current_title(activeWindow) - if not titleText: - return None - - return (windowId, titleText) - - def _ensure_x11_display(self): - """Lazily opens the generic X11 title source when i3 IPC is unavailable.""" - - if self._display is not None: - return True - if not xlibAvailable: - return False - - try: - self._display = xDisplay.Display() - self._root = self._display.screen().root - self._init_atoms() - except Exception as error: - debug.printMessage( - debug.LEVEL_INFO, - f"WindowTitleReader: Failed to open X11 fallback: {error}", - True, - ) - self._cleanup_display() - return False - - return True - - def _get_atspi_title(self): - if not self.app: - return "" - - appState = self.app.getDynamicApiManager().getAPI("CthulhuState") - if not appState: - return "" - - return AXObject.get_name(appState.activeWindow) or "" - - def _titles_match(self, atspiTitle, fallbackTitle): - if not atspiTitle or not fallbackTitle: - return False - - if self._is_wine_desktop_title(atspiTitle): - return False - - normalizedAtspiTitle = " ".join(atspiTitle.casefold().split()) - normalizedFallbackTitle = " ".join(fallbackTitle.casefold().split()) - return normalizedAtspiTitle in normalizedFallbackTitle \ - or normalizedFallbackTitle in normalizedAtspiTitle - - def _present_title(self, titleText): - if not self.app: - return - - try: - appState = self.app.getDynamicApiManager().getAPI("CthulhuState") - if appState and appState.activeScript: - appState.activeScript.presentMessage(titleText, resetStyles=False) - except Exception: - pluginLogger.exception("WindowTitleReader: Failed to present title") - - def _get_current_title(self, activeWindow): - activeTitle = self._get_window_title(activeWindow) - if not activeTitle: - return "" - - if self._is_wine_desktop_title(activeTitle): - return self._get_wine_desktop_title(activeWindow) - - return activeTitle - - def _get_wine_desktop_title(self, desktopWindow): - focusWindow = self._get_focus_window() - if focusWindow \ - and focusWindow.id != desktopWindow.id \ - and self._window_is_descendant_of(focusWindow, desktopWindow): - focusTitle = self._get_window_title(focusWindow) - if self._is_usable_wine_child_title(focusWindow, focusTitle): - return focusTitle - - return self._find_child_title(desktopWindow) - - def _find_child_title(self, rootWindow): - try: - childQueue = list(rootWindow.query_tree().children) - except xError.XError: - return "" - - checkedCount = 0 - while childQueue and checkedCount < 200: - window = childQueue.pop(0) - checkedCount += 1 - titleText = self._get_window_title(window) - if self._is_usable_wine_child_title(window, titleText): - return titleText - - try: - childQueue.extend(window.query_tree().children) - except xError.XError: - continue - - return "" - - def _window_is_descendant_of(self, window, ancestor): - if not window or not ancestor: - return False - - current = window - for _hop in range(64): - if current.id == ancestor.id: - return True - try: - parent = current.query_tree().parent - except xError.XError: - return False - if not parent or parent.id == current.id: - return False - current = parent - - return False - - def _is_usable_wine_child_title(self, window, titleText): - if not titleText or self._is_wine_desktop_title(titleText): - return False - - normalizedTitle = " ".join(titleText.casefold().split()) - if normalizedTitle in ("default ime", "program manager"): - return False - - try: - windowClass = window.get_wm_class() or () - except xError.XError: - windowClass = () - normalizedClass = { - str(value or "").strip().casefold() - for value in windowClass - } - if "cthulhu-wine-access.exe" in normalizedClass: - return False - if normalizedTitle == "nvda" and "nvda.exe" in normalizedClass: - return False - - return True - - def _is_wine_desktop_title(self, titleText): - return self._wineDesktopLabel.lower() in titleText.lower() - - def _get_window_title(self, window): - if not window: - return "" - - netTitle = self._get_text_property(window, "NET_WM_NAME") - if netTitle: - return netTitle - - return self._get_text_property(window, "WM_NAME") - - def _get_text_property(self, window, atomName): - atom = self._atoms.get(atomName) - if not atom: - return "" - - try: - propertyData = window.get_full_property(atom, X.AnyPropertyType) - except xError.XError: - return "" - - if not propertyData or propertyData.value is None: - return "" - - value = propertyData.value - if isinstance(value, str): - return value.strip("\x00") - - try: - rawBytes = bytes(value) - except Exception: - return "" - - decodedText = self._decode_property_bytes(rawBytes) - return decodedText.strip("\x00") - - def _decode_property_bytes(self, rawBytes): - for encoding in ("utf-8", "latin-1"): - try: - return rawBytes.decode(encoding, errors="replace") - except Exception: - continue - return "" - - def _get_active_window(self): - if not self._root: - return None - - try: - propertyData = self._root.get_full_property( - self._atoms["NET_ACTIVE_WINDOW"], - X.AnyPropertyType, - ) - except xError.XError: - propertyData = None - - if propertyData and propertyData.value: - try: - windowId = int(propertyData.value[0]) - return self._display.create_resource_object("window", windowId) - except Exception: - pass - - return self._get_focus_window() - - def _get_focus_window(self): - if not self._display: - return None - - try: - focusInfo = self._display.get_input_focus() - focusWindow = focusInfo.focus - if not focusWindow or focusWindow.id == 0: - return None - if self._root and focusWindow.id == self._root.id: - return None - return focusWindow - except Exception: - return None diff --git a/src/cthulhu/plugins/WineAccessibility/__init__.py b/src/cthulhu/plugins/WineAccessibility/__init__.py deleted file mode 100644 index b4ce8e6..0000000 --- a/src/cthulhu/plugins/WineAccessibility/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Wine accessibility integration plugin.""" - -from .plugin import WineAccessibility - -__all__ = ["WineAccessibility"] diff --git a/src/cthulhu/plugins/WineAccessibility/meson.build b/src/cthulhu/plugins/WineAccessibility/meson.build deleted file mode 100644 index 99267cb..0000000 --- a/src/cthulhu/plugins/WineAccessibility/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -python3.install_sources( - files('__init__.py', 'plugin.py'), - subdir: 'cthulhu/plugins/WineAccessibility' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'WineAccessibility' -) diff --git a/src/cthulhu/plugins/WineAccessibility/plugin.info b/src/cthulhu/plugins/WineAccessibility/plugin.info deleted file mode 100644 index 224f7cd..0000000 --- a/src/cthulhu/plugins/WineAccessibility/plugin.info +++ /dev/null @@ -1,8 +0,0 @@ -name = Wine Accessibility -version = 1.0.0 -description = Provides screen reader access to standard Wine and Proton applications -authors = Stormux -website = https://git.stormux.org/storm/cthulhu -copyright = Copyright 2026 -builtin = false -hidden = false diff --git a/src/cthulhu/plugins/WineAccessibility/plugin.py b/src/cthulhu/plugins/WineAccessibility/plugin.py deleted file mode 100644 index 4d8e661..0000000 --- a/src/cthulhu/plugins/WineAccessibility/plugin.py +++ /dev/null @@ -1,104 +0,0 @@ -"""Automatically manages Cthulhu's Wine accessibility helper.""" - -from gi.repository import GLib, Gtk - -from cthulhu import settings -from cthulhu import settings_manager -from cthulhu.plugin import Plugin, cthulhu_hookimpl -from cthulhu.wine_access_manager import WineAccessManager - - -class WineAccessibility(Plugin): - """Starts one helper for each active same-user Wine or Proton prefix.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.settingsManager = settings_manager.getManager() - self.manager = WineAccessManager() - self.pollSourceId = 0 - self.prefsGrid = None - self.prefsWidgets = {} - - @cthulhu_hookimpl - def activate(self, plugin=None): - if plugin is not None and plugin is not self: - return - self._refresh_manager_settings() - if self._setting("wineAccessibilityEnabled") and self._setting( - "wineAccessibilityAutoManage" - ) and self.manager.helperPath: - self.manager.poll() - self.pollSourceId = GLib.timeout_add(self.manager.POLL_INTERVAL_MS, self.manager.poll) - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - if plugin is not None and plugin is not self: - return - if self.pollSourceId: - GLib.source_remove(self.pollSourceId) - self.pollSourceId = 0 - self.manager.shutdown() - - def _setting(self, name): - value = self.settingsManager.getSetting(name) - return getattr(settings, name) if value is None else value - - def _refresh_manager_settings(self): - self.manager.dialogReaderEnabled = bool(self._setting("wineAccessibilityDialogReader")) - self.manager.controllerEnabled = bool(self._setting("wineAccessibilityController")) - - def getPreferencesGUI(self): - if self.prefsGrid is None: - self.prefsGrid = Gtk.Grid( - row_spacing=6, - column_spacing=12, - margin_left=12, - margin_right=12, - margin_top=12, - margin_bottom=12, - ) - labels = ( - ("enabled", "Enable Wine accessibility"), - ("auto", "Automatically manage Wine and Proton prefixes"), - ("dialogs", "Read standard Wine controls"), - ("controller", "Enable NVDA Controller and Tolk compatibility"), - ) - for row, (name, label) in enumerate(labels): - widget = Gtk.CheckButton(label=label) - if name == "enabled": - widget.connect("toggled", self._update_preferences_sensitivity) - self.prefsGrid.attach(widget, 0, row, 1, 1) - self.prefsWidgets[name] = widget - values = { - "enabled": "wineAccessibilityEnabled", - "auto": "wineAccessibilityAutoManage", - "dialogs": "wineAccessibilityDialogReader", - "controller": "wineAccessibilityController", - } - for name, settingName in values.items(): - self.prefsWidgets[name].set_active(bool(self._setting(settingName))) - self._update_preferences_sensitivity() - return self.prefsGrid, "Wine Accessibility" - - def getPreferencesFromGUI(self): - if not self.prefsWidgets: - return {} - return { - "wineAccessibilityEnabled": self.prefsWidgets["enabled"].get_active(), - "wineAccessibilityAutoManage": self.prefsWidgets["auto"].get_active(), - "wineAccessibilityDialogReader": self.prefsWidgets["dialogs"].get_active(), - "wineAccessibilityController": self.prefsWidgets["controller"].get_active(), - } - - def _update_preferences_sensitivity(self, _widget=None): - if not self.prefsWidgets: - return - enabled = self.prefsWidgets["enabled"].get_active() - for name in ("auto", "dialogs", "controller"): - self.prefsWidgets[name].set_sensitive(enabled) - - def refresh_settings(self): - """Applies settings saved from the plugin preferences page.""" - - self.deactivate() - self.activate() diff --git a/src/cthulhu/plugins/hello_world/README.md b/src/cthulhu/plugins/hello_world/README.md deleted file mode 100644 index ba11cf6..0000000 --- a/src/cthulhu/plugins/hello_world/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Hello World Plugin for Cthulhu - -This is a simple test plugin for the Cthulhu screen reader that demonstrates how to use the pluggy-based plugin system. - -## Features - -- Registers a keyboard shortcut (Cthulhu+z) that speaks "hello world" when pressed -- Demonstrates how to use the Plugin base class -- Shows how to use cthulhu_hookimpl for hook implementation - -## Implementation Details - -The plugin uses the following key features: -- `pluggy` for hook specification and implementation -- The `Plugin` base class from cthulhu.plugin -- The `cthulhu_hookimpl` decorator to mark functions as plugin hooks -- The `registerGestureByString` method to register keyboard shortcuts - -## Structure - -- `plugin.py`: The main plugin implementation -- `plugin.info`: Metadata about the plugin - -## Requirements - -Requires the pluggy package to be installed: -``` -pip install pluggy -``` - -## Usage - -Enable the plugin in Cthulhu Preferences → Plugins to load it at startup. You can also add it to your -`activePlugins` preference. - -## Preferences Pages (Optional) - -Plugins can add their own Preferences tab by implementing: -- `getPreferencesGUI()` → returns a Gtk widget (or `(widget, label)`). -- `getPreferencesFromGUI()` → returns a dict of settings to save. - -Tabs are only shown when the plugin is active. diff --git a/src/cthulhu/plugins/hello_world/__init__.py b/src/cthulhu/plugins/hello_world/__init__.py deleted file mode 100644 index 301e5ea..0000000 --- a/src/cthulhu/plugins/hello_world/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - diff --git a/src/cthulhu/plugins/hello_world/meson.build b/src/cthulhu/plugins/hello_world/meson.build deleted file mode 100644 index be25f26..0000000 --- a/src/cthulhu/plugins/hello_world/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -helloworld_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - helloworld_python_sources, - subdir: 'cthulhu/plugins/hello_world' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'hello_world' -) \ No newline at end of file diff --git a/src/cthulhu/plugins/hello_world/plugin.info b/src/cthulhu/plugins/hello_world/plugin.info deleted file mode 100644 index 50e52cc..0000000 --- a/src/cthulhu/plugins/hello_world/plugin.info +++ /dev/null @@ -1,8 +0,0 @@ -name = Hello World -version = 1.0.0 -description = Test plugin for Cthulhu -authors = Storm Dragon storm_dragon@stormux.org -website = https://stormux.org -copyright = Copyright 2025 -builtin = false -hidden = false diff --git a/src/cthulhu/plugins/hello_world/plugin.py b/src/cthulhu/plugins/hello_world/plugin.py deleted file mode 100644 index 0876922..0000000 --- a/src/cthulhu/plugins/hello_world/plugin.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Hello World plugin for Cthulhu.""" - -import logging -from cthulhu.plugin import Plugin, cthulhu_hookimpl - -logger = logging.getLogger(__name__) - -class HelloWorld(Plugin): - """Hello World plugin.""" - - def __init__(self, *args, **kwargs): - """Initialize the plugin.""" - super().__init__(*args, **kwargs) - print("Plugin hello world initialized.") - logger.info("HelloWorld plugin initialized") - - @cthulhu_hookimpl - def activate(self, plugin=None): - """Activate the plugin.""" - # Skip if this activation call isn't for us - if plugin is not None and plugin is not self: - return - - try: - logger.info("Activating Hello World plugin") - - # Register our keyboard shortcut - self.registerGestureByString( - self.speakTest, - "hello world", - "kb:cthulhu+z", - learnModeEnabled=True - ) - except Exception as e: - logger.error(f"Error activating Hello World plugin: {e}") - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - """Deactivate the plugin.""" - # Skip if this deactivation call isn't for us - if plugin is not None and plugin is not self: - return - - try: - logger.info("Deactivating Hello World plugin") - except Exception as e: - logger.error(f"Error deactivating Hello World plugin: {e}") - - def speakTest(self, script=None, inputEvent=None): - """Speak a test message.""" - try: - if self.app: - self.app.getDynamicApiManager().getAPI('CthulhuState').activeScript.presentMessage( - 'hello world', - resetStyles=False - ) - - return True - except Exception as e: - logger.error(f"Error in speakTest: {e}") - return False diff --git a/src/cthulhu/plugins/meson.build b/src/cthulhu/plugins/meson.build deleted file mode 100644 index be4200e..0000000 --- a/src/cthulhu/plugins/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -# Plugin subdirectories -subdir('AIAssistant') -subdir('ByeCthulhu') -subdir('Clipboard') -subdir('CthulhuRemote') -subdir('DisplayVersion') -subdir('HelloCthulhu') -subdir('GameMode') -subdir('nvda2cthulhu') -subdir('OCR') -subdir('SpeechHistory') -subdir('SimplePluginSystem') -subdir('hello_world') -subdir('self_voice') -subdir('SSIPProxy') -subdir('WindowTitleReader') -subdir('WineAccessibility') diff --git a/src/cthulhu/plugins/nvda2cthulhu/README.md b/src/cthulhu/plugins/nvda2cthulhu/README.md deleted file mode 100644 index 6a5f0ad..0000000 --- a/src/cthulhu/plugins/nvda2cthulhu/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# NVDA to Cthulhu plugin - -This plugin starts a local WebSocket server that accepts nvda2cthulhu messages -and speaks/brailles them through Cthulhu. - -## Dependencies - -These are optional and only needed when the plugin is enabled: - -- python-msgpack -- python-tornado - -If they are missing, the plugin will announce that dependencies are missing and -will not start the server. - -## Usage - -- Enable the plugin in Cthulhu's Plugin Manager. -- The server listens on 127.0.0.1 and uses the port from NVDA2SPEECHD_HOST - if set; otherwise it defaults to 3457. -- Toggle interrupt/no-interrupt mode with cthulhu+shift+n. -- Toggle translation with cthulhu+control+shift+t (requires translate-shell). -- Translation defaults to your system locale; override with `NVDA2CTHULHU_TRANSLATE_TARGET` - (e.g., `NVDA2CTHULHU_TRANSLATE_TARGET=en`). diff --git a/src/cthulhu/plugins/nvda2cthulhu/__init__.py b/src/cthulhu/plugins/nvda2cthulhu/__init__.py deleted file mode 100644 index 294e379..0000000 --- a/src/cthulhu/plugins/nvda2cthulhu/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""NVDA to Cthulhu bridge plugin.""" - -from .plugin import Nvda2Cthulhu - -__all__ = ['Nvda2Cthulhu'] diff --git a/src/cthulhu/plugins/nvda2cthulhu/meson.build b/src/cthulhu/plugins/nvda2cthulhu/meson.build deleted file mode 100644 index 56a553c..0000000 --- a/src/cthulhu/plugins/nvda2cthulhu/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -nvda2cthulhu_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - nvda2cthulhu_python_sources, - subdir: 'cthulhu/plugins/nvda2cthulhu' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'nvda2cthulhu' -) diff --git a/src/cthulhu/plugins/nvda2cthulhu/plugin.info b/src/cthulhu/plugins/nvda2cthulhu/plugin.info deleted file mode 100644 index e00d8a4..0000000 --- a/src/cthulhu/plugins/nvda2cthulhu/plugin.info +++ /dev/null @@ -1,8 +0,0 @@ -name = NVDA to Cthulhu -version = 1.0.0 -description = WebSocket listener that accepts nvda2cthulhu messages and speaks them through Cthulhu -authors = Storm Dragon storm_dragon@stormux.org -website = https://stormux.org -copyright = Copyright 2026 -builtin = false -hidden = false diff --git a/src/cthulhu/plugins/nvda2cthulhu/plugin.py b/src/cthulhu/plugins/nvda2cthulhu/plugin.py deleted file mode 100644 index a2c89e5..0000000 --- a/src/cthulhu/plugins/nvda2cthulhu/plugin.py +++ /dev/null @@ -1,494 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# - -"""NVDA to Cthulhu bridge plugin.""" - -import asyncio -import locale -import logging -import os -import shutil -from collections import OrderedDict -import subprocess -import threading -import urllib.parse -from typing import Any, Callable - -from gi.repository import GLib - -try: - import msgpack -except Exception: # pragma: no cover - optional dependency - msgpack = None - -try: - import tornado - import tornado.httpserver - import tornado.ioloop - import tornado.web - import tornado.websocket - from tornado.platform.asyncio import AsyncIOMainLoop -except Exception: # pragma: no cover - optional dependency - tornado = None - -from cthulhu.plugin import Plugin, cthulhu_hookimpl -from cthulhu import braille -from cthulhu import debug -from cthulhu import speech -from cthulhu import settings_manager - -logger = logging.getLogger(__name__) - -DEFAULT_PORT = 3457 -TRANSLATE_COMMAND = ("trans", "-no-autocorrect", "-no-warn", "-brief") -TRANSLATE_TIMEOUT = 5.0 -TRANSLATE_CACHE_MAX = 512 - - -def _coerce_text(value): - if value is None: - return '' - if isinstance(value, bytes): - try: - return value.decode('utf-8') - except Exception: - return value.decode('utf-8', errors='replace') - return str(value) - - -if tornado is None: - class Nvda2CthulhuSocket: # pragma: no cover - optional dependency - """Placeholder when tornado is not available.""" - pass -else: - class Nvda2CthulhuSocket(tornado.websocket.WebSocketHandler): - """WebSocket handler for NVDA to Cthulhu messages.""" - - def initialize(self, plugin): - self.plugin = plugin - - def check_origin(self, origin): - return True - - def on_message(self, message): - self.plugin.handle_message(message) - - -class Nvda2Cthulhu(Plugin): - """Bridge server that accepts NVDA to Cthulhu messages.""" - - def __init__(self): - logger.info("NVDA to Cthulhu __init__() called") - try: - super().__init__() - logger.info("NVDA to Cthulhu super().__init__() completed") - self.settingsManager = settings_manager.getManager() - self.interruptEnabled = True - self.serverThread = None - self.serverLock = threading.Lock() - self.httpServer = None - self.ioLoop = None - self.asyncioLoop = None - self.translationCache = OrderedDict() - self.translationCacheLock = threading.Lock() - logger.info("NVDA to Cthulhu __init__() completed successfully") - except Exception as e: - logger.error(f"NVDA to Cthulhu __init__() failed: {e}") - raise - - @cthulhu_hookimpl - def activate(self, plugin=None): - logger.info(f"NVDA to Cthulhu activate() called with plugin={plugin}, self={self}") - if plugin is not None and plugin is not self: - logger.info(f"NVDA to Cthulhu activate() early return: plugin is not self") - return - - logger.info("Activating NVDA to Cthulhu plugin") - self.registerGestureByString( - self.toggle_interrupt, - "NVDA to Cthulhu interrupt mode", - "kb:cthulhu+shift+n", - learnModeEnabled=True - ) - self.registerGestureByString( - self.toggle_translation, - "NVDA to Cthulhu translation", - "kb:cthulhu+control+shift+t", - learnModeEnabled=True, - globalBinding=True - ) - if not self._dependencies_available(): - self._present_message("NVDA to Cthulhu missing dependencies: python-msgpack and python-tornado") - logger.warning("NVDA to Cthulhu dependencies missing: msgpack or tornado") - return - self.start_server() - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - if plugin is not None and plugin is not self: - return - - logger.info("Deactivating NVDA to Cthulhu plugin") - self.stop_server() - - def start_server(self): - with self.serverLock: - if self.serverThread and self.serverThread.is_alive(): - return - self.serverThread = threading.Thread( - target=self._server_main, - name="Nvda2CthulhuServer", - daemon=True - ) - self.serverThread.start() - - def stop_server(self): - with self.serverLock: - ioLoop = self.ioLoop - httpServer = self.httpServer - - if ioLoop is None: - return - - def _stop(): - if httpServer: - httpServer.stop() - ioLoop.stop() - - try: - ioLoop.add_callback(_stop) - except Exception as exc: - logger.warning(f"NVDA to Cthulhu: failed to stop server cleanly: {exc}") - - if self.serverThread and self.serverThread.is_alive(): - try: - self.serverThread.join(timeout=2.0) - except Exception as exc: - logger.warning(f"NVDA to Cthulhu: failed to join server thread: {exc}") - - def toggle_interrupt(self, script=None, inputEvent=None): - self.interruptEnabled = not self.interruptEnabled - mode = "interrupt" if self.interruptEnabled else "no interrupt" - self._present_message(f"NVDA to Cthulhu {mode}") - return True - - def toggle_translation(self, script=None, inputEvent=None): - if not self.settingsManager and self.app: - self.settingsManager = self.app.getSettingsManager() - if not self.settingsManager: - return False - if not self._translation_command_available(): - self._present_message("NVDA to Cthulhu translation unavailable (missing translate-shell)") - return True - currentValue = bool(self.settingsManager.getSetting('nvda2cthulhuTranslateEnabled')) - newValue = not currentValue - self.settingsManager.setSetting('nvda2cthulhuTranslateEnabled', newValue) - mode = "translation enabled" if newValue else "translation disabled" - self._present_message(f"NVDA to Cthulhu {mode}") - return True - - def handle_message(self, message): - try: - request = self._parse_request(message) - except Exception as exc: - logger.warning(f"NVDA to Cthulhu: failed to parse message: {exc}") - debug.printException(debug.LEVEL_WARNING) - return - - if not request: - return - - try: - requestType, payload = request - if requestType == "SpeakText": - self._handle_speak(payload) - elif requestType == "BrailleText": - self._schedule_on_main_thread(self._handle_braille, payload) - elif requestType == "CancelSpeech": - self._schedule_on_main_thread(self._handle_cancel_speech) - except Exception as exc: - logger.warning(f"NVDA to Cthulhu: failed to handle message: {exc}") - debug.printException(debug.LEVEL_WARNING) - - def _server_main(self): - if not self._dependencies_available(): - return - address, port = self._get_bind_address() - try: - self.asyncioLoop = asyncio.new_event_loop() - asyncio.set_event_loop(self.asyncioLoop) - AsyncIOMainLoop().install() - - app = tornado.web.Application([ - (r"/", Nvda2CthulhuSocket, {"plugin": self}), - ]) - - self.httpServer = tornado.httpserver.HTTPServer(app) - self.httpServer.listen(port, address=address) - self.ioLoop = tornado.ioloop.IOLoop.current() - logger.info(f"NVDA to Cthulhu listening on {address}:{port}") - self.ioLoop.start() - except Exception as exc: - logger.error(f"NVDA to Cthulhu failed to start server: {exc}") - self._schedule_on_main_thread(self._present_message, "NVDA to Cthulhu server failed to start") - finally: - self.httpServer = None - if self.ioLoop: - try: - self.ioLoop.stop() - except Exception: - pass - self.ioLoop = None - self.asyncioLoop = None - - def _get_bind_address(self): - port = DEFAULT_PORT - host = os.environ.get("NVDA2SPEECHD_HOST") - if host: - try: - parsed = urllib.parse.urlparse(host) - if parsed.port: - port = parsed.port - except Exception: - logger.warning(f"NVDA to Cthulhu: invalid NVDA2SPEECHD_HOST: {host}") - return "127.0.0.1", port - - def _parse_request(self, message): - if not self._dependencies_available(): - return None - if isinstance(message, str): - return self._parse_payload(message) - - if not isinstance(message, (bytes, bytearray)): - return None - - try: - payload = msgpack.unpackb(message, raw=False) - except Exception as exc: - logger.warning(f"NVDA to Cthulhu: failed to decode msgpack: {exc}") - return None - - return self._parse_payload(payload) - - def _parse_payload(self, payload): - if isinstance(payload, str): - if payload == "CancelSpeech": - return "CancelSpeech", None - return "SpeakText", payload - - if isinstance(payload, dict): - if len(payload) != 1: - return None - key, value = next(iter(payload.items())) - key = _coerce_text(key) - if key == "SpeakText": - return "SpeakText", _coerce_text(value) - if key == "BrailleText": - return "BrailleText", _coerce_text(value) - if key == "CancelSpeech": - return "CancelSpeech", None - return None - - if isinstance(payload, (list, tuple)): - if not payload: - return None - key = _coerce_text(payload[0]) - if key == "CancelSpeech": - return "CancelSpeech", None - if len(payload) < 2: - return None - value = _coerce_text(payload[1]) - if key == "SpeakText": - return "SpeakText", value - if key == "BrailleText": - return "BrailleText", value - return None - - return None - - def _handle_speak(self, text): - if not text or not text.strip(): - return - if self._translation_enabled(): - logger.info(f"NVDA to Cthulhu: translating text: {text[:50]}") - translated = self._translate_text(text) - logger.info(f"NVDA to Cthulhu: translated to: {translated[:50]}") - text = translated - self._schedule_on_main_thread(self._speak_text, text, self.interruptEnabled) - - def _speak_text(self, text: str, interrupt: bool) -> None: - speech.speak(text, interrupt=interrupt) - - def _handle_cancel_speech(self) -> None: - speech.stop() - - def _handle_braille(self, text): - if not text or not text.strip(): - return - if not self._braille_enabled(): - return - duration = self._get_braille_flash_time() - braille.displayMessage(text, flashTime=duration) - - def _braille_enabled(self): - if not self.settingsManager: - return False - enableBraille = self.settingsManager.getSetting('enableBraille') - enableMonitor = self.settingsManager.getSetting('enableBrailleMonitor') - enableFlash = self.settingsManager.getSetting('enableFlashMessages') - return bool((enableBraille or enableMonitor) and enableFlash) - - def _get_braille_flash_time(self): - if not self.settingsManager: - return 0 - if self.settingsManager.getSetting('flashIsPersistent'): - return -1 - return self.settingsManager.getSetting('brailleFlashTime') - - def _present_message(self, message): - try: - scriptManager = self.app.getScriptManager() - scriptManager.get_default_script().presentMessage(message, resetStyles=False) - except Exception: - logger.info(message) - - def _schedule_on_main_thread(self, callback: Callable[..., Any], *args: Any) -> bool: - try: - GLib.idle_add(self._run_on_main_thread, callback, args) - return True - except Exception as exc: - logger.warning(f"NVDA to Cthulhu: failed to queue main-loop callback: {exc}") - debug.printException(debug.LEVEL_WARNING) - return False - - def _run_on_main_thread(self, callback: Callable[..., Any], args: tuple[Any, ...]) -> bool: - try: - callback(*args) - except Exception as exc: - logger.warning(f"NVDA to Cthulhu: main-loop callback failed: {exc}") - debug.printException(debug.LEVEL_WARNING) - return False - - def _dependencies_available(self): - return msgpack is not None and tornado is not None - - def _translation_enabled(self): - if not self.settingsManager: - return False - return bool(self.settingsManager.getSetting('nvda2cthulhuTranslateEnabled')) - - def _translation_command_available(self): - return shutil.which(TRANSLATE_COMMAND[0]) is not None - - def _get_target_language(self): - """Get the target language code from system locale.""" - try: - # Get system locale (e.g., 'en_US.UTF-8') - system_locale = locale.getdefaultlocale()[0] - if system_locale: - # Extract language code (e.g., 'en' from 'en_US') - lang_code = system_locale.split('_')[0] - return lang_code - except Exception as exc: - logger.warning(f"NVDA to Cthulhu: failed to get system locale: {exc}") - - # Fallback to environment variable - try: - lang_env = os.environ.get('LANG', '') - if lang_env: - # Extract language code from LANG (e.g., 'en' from 'en_US.UTF-8') - lang_code = lang_env.split('_')[0] - if lang_code: - return lang_code - except Exception: - pass - - return None - - def _get_translate_target(self): - env_target = os.environ.get("NVDA2CTHULHU_TRANSLATE_TARGET") - if env_target: - return env_target - return self._get_target_language() - - def _translate_text(self, text): - cached = self._get_cached_translation(text) - if cached is not None: - logger.info(f"NVDA to Cthulhu: using cached translation") - return cached - if not self._translation_command_available(): - logger.warning("NVDA to Cthulhu translation failed: translate-shell not available") - return text - - translate_target = self._get_translate_target() - command = list(TRANSLATE_COMMAND) - if translate_target: - command.append(f":{translate_target}") - - logger.info(f"NVDA to Cthulhu: running trans command on: {text[:50]}") - try: - result = subprocess.run( - command, - input=text, - text=True, - encoding="utf-8", - errors="replace", - capture_output=True, - check=False, - timeout=TRANSLATE_TIMEOUT - ) - except subprocess.TimeoutExpired: - logger.warning("NVDA to Cthulhu translation failed: timed out") - debug.printMessage(debug.LEVEL_INFO, "NVDA to Cthulhu translation failed: timed out", True) - return text - except Exception as exc: - logger.warning(f"NVDA to Cthulhu translation failed: {exc}") - debug.printMessage(debug.LEVEL_INFO, f"NVDA to Cthulhu translation failed: {exc}", True) - return text - - if result.returncode != 0: - stderr = result.stderr.strip() - if stderr: - logger.warning(f"NVDA to Cthulhu translation failed: {stderr}") - debug.printMessage(debug.LEVEL_INFO, f"NVDA to Cthulhu translation failed: {stderr}", True) - return text - - output = result.stdout.strip() - logger.info(f"NVDA to Cthulhu: trans output: {output[:50]}") - if not output: - return text - self._set_cached_translation(text, output) - return output - - def _get_cached_translation(self, text): - with self.translationCacheLock: - cached = self.translationCache.get(text) - if cached is None: - return None - self.translationCache.move_to_end(text) - return cached - - def _set_cached_translation(self, text, translated): - with self.translationCacheLock: - if text in self.translationCache: - self.translationCache.move_to_end(text) - self.translationCache[text] = translated - while len(self.translationCache) > TRANSLATE_CACHE_MAX: - self.translationCache.popitem(last=False) diff --git a/src/cthulhu/plugins/self_voice/__init__.py b/src/cthulhu/plugins/self_voice/__init__.py deleted file mode 100644 index 301e5ea..0000000 --- a/src/cthulhu/plugins/self_voice/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - diff --git a/src/cthulhu/plugins/self_voice/meson.build b/src/cthulhu/plugins/self_voice/meson.build deleted file mode 100644 index c3d6e4d..0000000 --- a/src/cthulhu/plugins/self_voice/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -selfvoice_python_sources = files([ - '__init__.py', - 'plugin.py' -]) - -python3.install_sources( - selfvoice_python_sources, - subdir: 'cthulhu/plugins/self_voice' -) - -install_data( - 'plugin.info', - install_dir: python3.get_install_dir() / 'cthulhu' / 'plugins' / 'self_voice' -) \ No newline at end of file diff --git a/src/cthulhu/plugins/self_voice/plugin.info b/src/cthulhu/plugins/self_voice/plugin.info deleted file mode 100644 index 9ebe67d..0000000 --- a/src/cthulhu/plugins/self_voice/plugin.info +++ /dev/null @@ -1,12 +0,0 @@ -[Plugin] -name=Self Voice -module_name=self_voice -version=1.0.0 -description=Use Cthulhu speech and braille from external applications via Unix sockets -authors=Stormux -copyright=Copyright (c) 2024 Stormux -website=https://stormux.org -icon_name=audio-speakers -builtin=false -hidden=false -help_uri=https://stormux.org diff --git a/src/cthulhu/plugins/self_voice/plugin.py b/src/cthulhu/plugins/self_voice/plugin.py deleted file mode 100644 index db51b8e..0000000 --- a/src/cthulhu/plugins/self_voice/plugin.py +++ /dev/null @@ -1,198 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# - -"""Self Voice plugin for Cthulhu screen reader.""" - -import os -import socket -import select -import logging -import threading -from threading import Thread, Lock -from typing import Optional -from cthulhu.plugin import Plugin, cthulhu_hookimpl - -logger = logging.getLogger(__name__) - -# Special codes for message handling -APPEND_CODE = '<#APPEND#>' -PERSISTENT_CODE = '<#PERSISTENT#>' - -def _get_socket_file() -> Optional[str]: - runtimeDir = os.environ.get('XDG_RUNTIME_DIR') - if not runtimeDir: - return None - - return os.path.join(runtimeDir, 'cthulhu.sock') - -class SelfVoice(Plugin): - """Plugin that provides a socket interface for external applications to send text to Cthulhu.""" - - def __init__(self): - """Initialize the plugin.""" - super().__init__() - self.lock = Lock() - self.active = False - self.voiceThread = Thread(target=self.voiceWorker) - self.voiceThread.daemon = True # Make thread exit when main thread exits - - @cthulhu_hookimpl - def activate(self): - """Activate the self-voice plugin.""" - super().activate() - logger.info("Activating Self Voice Plugin") - self.activateWorker() - - @cthulhu_hookimpl - def deactivate(self): - """Deactivate the self-voice plugin.""" - logger.info("Deactivating Self Voice Plugin") - self.deactivateWorker() - super().deactivate() - - def activateWorker(self): - """Start the voice worker thread.""" - with self.lock: - self.active = True - - # Only start if not already running - if not self.voiceThread.is_alive(): - self.voiceThread = Thread(target=self.voiceWorker) - self.voiceThread.daemon = True - self.voiceThread.start() - - def deactivateWorker(self): - """Stop the voice worker thread.""" - with self.lock: - self.active = False - - # Try to join the thread if it's alive, with a timeout - if self.voiceThread.is_alive(): - try: - self.voiceThread.join(timeout=2.0) - except Exception as e: - logger.warning(f"Error stopping voice worker thread: {e}") - - def isActive(self): - """Check if the worker is active.""" - with self.lock: - return self.active - - def outputMessage(self, message): - """Output a message through Cthulhu's speech and braille systems. - - Args: - message: The message to output. May include special codes. - """ - # Process special codes - append = message.startswith(APPEND_CODE) - if append: - message = message[len(APPEND_CODE):] - - persistent = False - if message.endswith(PERSISTENT_CODE): - message = message[:len(message)-len(PERSISTENT_CODE)] - persistent = True - - # Output through appropriate channel - if persistent: - # Use the APIHelper for persistent messages - self.app.getAPIHelper().outputMessage(message, not append) - else: - # Use the script manager for standard messages - script_manager = self.app.getDynamicApiManager().getAPI('ScriptManager') - scriptManager = script_manager.get_manager() - scriptManager.get_default_script().presentMessage(message, resetStyles=False) - - def voiceWorker(self): - """Worker thread that listens on a socket for messages to speak.""" - socketFile = _get_socket_file() - if not socketFile: - logger.error("XDG_RUNTIME_DIR is not set; Self Voice plugin cannot create its socket") - return - - # Clean up any existing socket file - if os.path.exists(socketFile): - try: - os.unlink(socketFile) - except Exception as e: - logger.error(f"Error removing existing socket file: {e}") - return - - try: - # Create and set up the socket - cthulhu_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - cthulhu_sock.bind(socketFile) - os.chmod(socketFile, 0o222) # Write-only for everyone - cthulhu_sock.listen(1) - - logger.info(f"Self Voice plugin listening on {socketFile}") - - # Main loop - listen for connections - while self.isActive(): - # Check if data is available with a timeout - try: - r, _, _ = select.select([cthulhu_sock], [], [], 0.8) - except select.error as e: - logger.error(f"Select error: {e}") - break - - if not r: # No data available - continue - - # Accept connection - if cthulhu_sock in r: - try: - client_sock, _ = cthulhu_sock.accept() - client_sock.settimeout(0.5) # Set a timeout for receiving data - - try: - # Receive and process data - raw_data = client_sock.recv(8192) - if raw_data: - data = raw_data.decode("utf-8").strip() - if data: - self.outputMessage(data) - except socket.timeout: - pass - except Exception as e: - logger.error(f"Error receiving data: {e}") - finally: - client_sock.close() - except Exception as e: - logger.error(f"Error accepting connection: {e}") - - except Exception as e: - logger.error(f"Socket error: {e}") - finally: - # Clean up - if 'cthulhu_sock' in locals(): - try: - cthulhu_sock.close() - except Exception: - pass - - if os.path.exists(socketFile): - try: - os.unlink(socketFile) - except Exception as e: - logger.error(f"Error removing socket file: {e}") - - logger.info("Self Voice plugin socket closed") diff --git a/src/cthulhu/pronunciation_dict.py b/src/cthulhu/pronunciation_dict.py deleted file mode 100644 index d6c75fd..0000000 --- a/src/cthulhu/pronunciation_dict.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Exposes a dictionary, pronunciation_dict, that maps words to what -they sound like.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2006-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -def getPronunciation(word, pronunciations=None): - """Given a word, return a string that represents what this word - sounds like. Note: This code does not handle the pronunciation - of character names. If you want a character name to be spoken, - treat it as a punctuation character at LEVEL_NONE in - punctuation_settings.py. See, for example, the left_arrow and - right_arrow characters. - - Arguments: - - word: the word to get the "sounds like" representation for. - - pronunciations: an optional dictionary used to get the pronunciation - from. - - Returns a string that represents what this word sounds like, or - the word if there is no representation. - """ - - lowerWord = word.lower() - dictionary = pronunciations or pronunciation_dict - entry = dictionary.get(lowerWord, [word, word]) - - return entry[1] - -def setPronunciation(word, replacementString, pronunciations=None): - """Given an actual word, and a replacement string, set a key/value - pair in a pronunciation dictionary. - - Arguments: - - word: the word to be pronunced. - - replacementString: the replacement string to use instead. - - pronunciations: an optional dictionary used to set the pronunciation - into. - """ - - key = word.lower() - if pronunciations is not None: - pronunciations[key] = [ word, replacementString ] - else: - pronunciation_dict[key] = [ word, replacementString ] - -# pronunciation_dict is a dictionary where the keys are words and the -# values represent word the pronunciation of that word (in other words, -# what the word sounds like). -# -pronunciation_dict = {} diff --git a/src/cthulhu/punctuation_settings.py b/src/cthulhu/punctuation_settings.py deleted file mode 100644 index f825685..0000000 --- a/src/cthulhu/punctuation_settings.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Punctuation Verbosity settings. -The Cthulhu punctuation settings are broken up into 4 modes. - -These modes are None, Some, Most and All. - -They are defined by a group of radio buttons on the speech -page of the configuration user interface. - -Each mode is defined below. The 4 bits of information listed here are: - - - The actual printed symbol. - - - How the symbol should be pronounced (in the chnames dictionary in - chnames.py keyed by symbol). - - - The level at which the symbol should be spoken. Note that this - denotes the level containing all lower levels. - - - Whether or not the spoken name for the symbol should replace the - actual symbol or be inserted before the symbol. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -from . import settings - -# Whether or not the spoken name for the symbol should replace the -# actual symbol or be inserted before the symbol. -# -PUNCTUATION_REPLACE = 0 -PUNCTUATION_INSERT = 1 - -# The lowest level at which the spoken name should be spoken. Thus a symbol -# with a level of LEVEL_MOST will be spoken at LEVEL_MOST and LEVEL_ALL. -# -LEVEL_ALL = settings.PUNCTUATION_STYLE_ALL -LEVEL_MOST = settings.PUNCTUATION_STYLE_MOST -LEVEL_SOME = settings.PUNCTUATION_STYLE_SOME -LEVEL_NONE = settings.PUNCTUATION_STYLE_NONE - -# Bullets and bullet-like characters -# -middle_dot = '\u00b7' -bullet = '\u2022' -triangular_bullet = '\u2023' -hyphen_bullet = '\u2043' -black_square = '\u25a0' -white_square = '\u25a1' -white_bullet = '\u25e6' -white_circle = '\u25cb' -black_diamond = '\u25c6' -black_circle = '\u25cf' -check_mark = '\u2713' -heavy_check_mark = '\u2714' -x_shaped_bullet = '\u2717' -heavy_right_arrow = '\u2794' -right_arrowhead = '\u27a2' - -# StarOffice/OOo's special-purpose bullet chararacters -# -SO_black_square = '\ue00a' -SO_black_diamond = '\ue00c' - -# Miscellaneous other symbols -# -cent = '\u00a2' -pound = '\u00a3' -yen = '\u00a5' -section = '\u00a7' -copyright_sign = '\u00a9' -left_double_angle = '\u00ab' -not_sign = '\u00ac' -registered = '\u00ae' -degree = '\u00b0' -plus_minus = '\u00b1' -right_double_angle = '\u00bb' -one_quarter = '\u00bc' -one_half = '\u00bd' -three_quarters = '\u00be' -multiply = '\u00d7' -divide = '\u00f7' -en_dash = '\u2013' -left_single_quote = '\u2018' -right_single_quote = '\u2019' -single_low_quote = '\u201a' -left_double_quote = '\u201c' -right_double_quote = '\u201d' -double_low_quote = '\u201e' -dagger = '\u2020' -double_dagger = '\u2021' -per_mille = '\u2030' -prime = '\u2032' -double_prime = '\u2033' -euro = '\u20ac' -trademark = '\u2122' -left_arrow = '\u2190' -right_arrow = '\u2192' -infinity = '\u221e' -almost_equal = '\u2248' -not_equal = '\u2260' -lt_or_equal = '\u2264' -gt_or_equal = '\u2265' -square_root = '\u221a' -cube_root = '\u221b' - -superscript_zero = '\u2070' -superscript1 = '\u00b9' -superscript2 = '\u00b2' -superscript3 = '\u00b3' -superscript4 = '\u2074' -superscript5 = '\u2075' -superscript6 = '\u2076' -superscript7 = '\u2077' -superscript8 = '\u2078' -superscript9 = '\u2079' -superscript_plus = '\u207a' -superscript_minus = '\u207b' -superscript_equals = '\u207c' -superscript_left_paren = '\u207d' -superscript_right_paren = '\u207e' -superscriptn = '\u207f' -subscript_zero = '\u2080' -subscript1 = '\u2081' -subscript2 = '\u2082' -subscript3 = '\u2083' -subscript4 = '\u2084' -subscript5 = '\u2085' -subscript6 = '\u2086' -subscript7 = '\u2087' -subscript8 = '\u2088' -subscript9 = '\u2089' -subscript_plus = '\u208a' -subscript_minus = '\u208b' -subscript_equals = '\u208c' -subscript_left_paren = '\u208d' -subscript_right_paren = '\u208e' - -# punctuation is a dictionary where the keys represent a unicode -# character and the values are a list of two elements where the -# first represents the punctuation style and the second represents -# the action to take. -# -punctuation = {} - -punctuation["!"] = [ LEVEL_ALL, PUNCTUATION_INSERT ] -punctuation["'"] = [ LEVEL_ALL, PUNCTUATION_REPLACE ] -punctuation[","] = [ LEVEL_ALL, PUNCTUATION_INSERT ] -punctuation["."] = [ LEVEL_ALL, PUNCTUATION_INSERT ] -punctuation["?"] = [ LEVEL_ALL, PUNCTUATION_INSERT ] -punctuation[right_single_quote] = [ LEVEL_ALL, PUNCTUATION_REPLACE ] - -punctuation["\""] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["("] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[")"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["-"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["_"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[":"] = [ LEVEL_MOST, PUNCTUATION_INSERT ] -punctuation[";"] = [ LEVEL_MOST, PUNCTUATION_INSERT ] -punctuation["<"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[">"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["["] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["]"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["\\"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["|"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["`"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["~"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["{"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["}"] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[left_single_quote] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[left_double_quote] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[right_double_quote] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[en_dash] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[double_low_quote] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[single_low_quote] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[left_double_angle] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation[right_double_angle] = [ LEVEL_MOST, PUNCTUATION_REPLACE ] -punctuation["#"] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation["$"] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation["%"] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation["&"] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation["*"] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation["+"] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation["/"] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation["="] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation["@"] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation["^"] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[cent] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[pound] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[yen] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[euro] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[not_sign] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[copyright_sign] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[registered] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[trademark] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[degree] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[plus_minus] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[multiply] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[divide] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[infinity] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[almost_equal] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[not_equal] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[lt_or_equal] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[gt_or_equal] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[square_root] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[cube_root] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[dagger] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[double_dagger] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[section] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[prime] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[double_prime] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] -punctuation[per_mille] = [ LEVEL_SOME, PUNCTUATION_REPLACE ] - -punctuation[left_arrow] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[right_arrow] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[middle_dot] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[bullet] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[triangular_bullet] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[hyphen_bullet] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[black_square] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[white_square] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[white_bullet] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[white_circle] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[black_diamond] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[black_circle] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[check_mark] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[heavy_check_mark] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[x_shaped_bullet] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[heavy_right_arrow] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[right_arrowhead] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[SO_black_square] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[SO_black_diamond] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[one_quarter] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[one_half] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[three_quarters] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] - -punctuation[superscript_zero] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript1] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript2] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript3] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript4] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript5] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript6] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript7] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript8] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript9] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript_plus] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript_minus] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript_equals] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript_left_paren] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscript_right_paren] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[superscriptn] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript_zero] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript1] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript2] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript3] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript4] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript5] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript6] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript7] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript8] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript9] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript_plus] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript_minus] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript_equals] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript_left_paren] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] -punctuation[subscript_right_paren] = [ LEVEL_NONE, PUNCTUATION_REPLACE ] - -def getPunctuationInfo(character): - """Given a punctuation character, return the value - [punctuation_style, punctuation_action] or None - - Arguments: - - character: the punctuation character to get the information for - - Returns return the value [punctuation_style, punctuation_action] - or None - """ - - return punctuation.get(character) diff --git a/src/cthulhu/resource_manager.py b/src/cthulhu/resource_manager.py deleted file mode 100644 index 2c461df..0000000 --- a/src/cthulhu/resource_manager.py +++ /dev/null @@ -1,374 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import traceback - -class TryFunction(): - def __init__(self, function): - self.function = function - def runSignal(self, app, *args): - try: - return self.function(app, *args) - except Exception as e: - print('try signal',e , traceback.print_exc()) - def runInputEvent(self, script=None, inputEvent=None): - try: - return self.function(script, inputEvent) - except Exception as e: - print('try input event',e , traceback.print_exc()) - def getFunction(self): - return self.function - def setFunction(self, function): - self.function = function - -class ResourceEntry(): - def __init__(self, entryType, resource1 = None, function = None, tryFunction= None, resourceText = '', resource2 = None, resource3 = None, resource4 = None): - # function based init - self.entryType = entryType # 'keyboard' = Keyboard, 'subscription' = Subscription, 'signal' = Signal, 'api'= Dynamic API, 'settings' = gSetttings - self.resource1 = resource1 - self.resource2 = resource2 - self.resource3 = resource3 - self.resource4 = resource4 - self.function = function - self.tryFunction = tryFunction - self.resourceText = resourceText - - def getEntryType(self): - return self.entryType - def getResourceText(self): - return self.resourceText - def getResource1(self): - return self.resource1 - def getResource2(self): - return self.resource2 - def getResource3(self): - return self.resource3 - def getResource4(self): - return self.resource4 - def getFunction(self): - return self.function - def getTryFunction(self): - return self.tryFunction - -class ResourceContext(): - def __init__(self, app, name): - self.app = app - self.name = name - self.gestures = {} # gestures added by the context - self.subscriptions = {} # subscription to signals by the context - self.apis = {} - self.signals = {} - self.settings = {} - - def getName(self): - return self.name - def getGestures(self): - return self.gestures - def getSubscriptions(self): - return self.subscriptions - def getSignals(self): - return self.signals - def getAPIs(self): - return self.apis - def getSettings(self): - return self.settings - def hasSettings(self, profile, application, sub_setting_name): - try: - d = self.getSettings()[profile][application][sub_setting_name] - return True - except KeyError: - return False - def addSetting(self, profile, application, sub_setting_name, entry): - # add profile - try: - d = self.settings[profile] - except KeyError: - self.settings[profile]= {} - # add application - try: - d = self.settings[profile][application] - except KeyError: - self.settings[profile][application] = {} - # add entry - self.settings[profile][application][sub_setting_name] = entry - - print('add', 'settings', self.getName(), profile, application, entry.getResourceText()) - - - def hasAPI(self, application, api): - try: - d = self.getAPIs()[application][api] - return True - except KeyError: - return False - def addAPI(self, application, api, entry): - # add application - try: - d = self.apis[application] - except KeyError: - self.apis[application] = {} - # add entry - self.apis[application][api] = entry - print('add', 'api', self.getName(), application, api) - - def removeAPI(self, application, api): - try: - del self.apis[application][api] - except KeyError as e: - print(e) - try: - if len(self.getAPIs()[application]) == 0: - del self.apis[application] - except KeyError: - pass - print('remove', 'apis', self.getName(), application, api) - - def addGesture(self, profile, application, gesture, entry): - # add profile - try: - d = self.gestures[profile] - except KeyError: - self.gestures[profile]= {} - # add application - try: - d = self.gestures[profile][application] - except KeyError: - self.gestures[profile][application] = {} - # add entry - self.gestures[profile][application][gesture] = entry - print('add', 'gesture', self.getName(), profile, application, entry.getResourceText()) - def removeGesture(self, gesture): - gestureCopy = self.getGestures().copy() - for profile, applicationDict in gestureCopy.items(): - for application, keyDict in applicationDict.copy().items(): - try: - del self.getGestures()[profile][application][gesture] - if len(self.getGestures()[profile][application]) == 0: - del self.getGestures()[profile][application] - if len(self.getGestures()[profile]) == 0: - del self.getGestures()[profile] - except KeyError: - pass - - print('remove', 'gesture', self.getName(), profile, application, gesture) - - def addSubscription(self, signalName, function, entry): - # add entry - try: - e = self.subscriptions[signalName] - except KeyError: - self.subscriptions[signalName] = {} - self.subscriptions[signalName][function] = entry - print('add', 'subscription', self.getName(), entry.getResourceText(), entry.function) - - def removeSubscriptionByFunction(self, function): - for signalName, functionDict in self.getSubscriptions().copy().items(): - for functionKey, entry in functionDict.copy().items(): - try: - if function == entry.function: - del self.getSubscriptions()[signalName][entry.function] - elif function == entry.tryFunction: - del self.getSubscriptions()[signalName][entry.function] - except KeyError as e: - print(e) - try: - if len(self.getSubscriptions()[signalName]) == 0: - del self.getSubscriptions()[signalName] - except KeyError: - pass - print('remove', 'subscription', self.getName(), function) - def addSignal(self, signal, entry): - # add entry - self.signals[signal] = entry - print('add', 'signal', self.getName(), entry.getResourceText()) - def removeSignal(self, signal): - print('remove', 'signal', self.getName(), entry.getResourceText()) - - def unregisterAllResources(self): - try: - self.unregisterAllGestures() - self.unregisterAllSubscriptions() - self.unregisterAllSignals() - self.unregisterAllAPI() - except Exception as e: - print(e) - - def unregisterAllAPI(self): - dynamicApiManager = self.app.getDynamicApiManager() - for application, value in self.getAPIs().copy().items(): - for key, entry in value.copy().items(): - try: - dynamicApiManager.unregisterAPI(key, application, self.getName()) - except Exception as e: - print(e) - print('unregister api ', self.getName(), entry.getEntryType(), entry.getResourceText()) - def unregisterAllGestures(self): - APIHelper = self.app.getAPIHelper() - - for profile, profileValue in self.getGestures().copy().items(): - for application, applicationValue in profileValue.copy().items(): - for gesture, entry in applicationValue.copy().items(): - if entry.getEntryType() == 'keyboard': - try: - APIHelper.unregisterShortcut(entry.getResource1(), self.getName()) - except Exception as e: - print(e) - print('unregister gesture', self.getName(), entry.getEntryType(), profile, application, entry.getResourceText()) - def unregisterAllSignals(self): - pass - # how to remove signals???? - - def unregisterAllSubscriptions(self): - SignalManager = self.app.getSignalManager() - - for signalName, entryDict in self.getSubscriptions().copy().items(): - for function, entry in entryDict.copy().items(): - try: - SignalManager.disconnectSignalByFunction(entry.tryFunction, self.getName()) - except Exception as e: - print(e) - print('unregister subscription', self.getName(), entry.getEntryType(), entry.getResourceText()) - -class ResourceManager(): - def __init__(self, app): - self.app = app - self.resourceContextDict = {} - def getResourceContextDict(self): - return self.resourceContextDict - - def addResourceContext(self, contextName, overwrite = False): - if not contextName: - return - resourceContext = self.getResourceContext(contextName) - if resourceContext: - if not overwrite: - return - resourceContext = ResourceContext(self.app, contextName) - self.resourceContextDict[contextName] = resourceContext - print('add {}'.format(contextName)) - - def removeResourceContext(self, contextName): - if not contextName: - return - - try: - self.resourceContextDict[contextName].unregisterAllResources() - except: - pass - - # temp - try: - print('_________', 'summery', self.resourceContextDict[contextName].getName(), '_________') - print('api', self.resourceContextDict[contextName].getAPIs()) - print('signals', self.resourceContextDict[contextName].getSignals()) - print('subscriptions', self.resourceContextDict[contextName].getSubscriptions()) - print('gestrues ', self.resourceContextDict[contextName].getGestures()) - print('_________', self.resourceContextDict[contextName].getName(), '_________') - except: - pass - # temp - try: - del self.resourceContextDict[contextName] - except KeyError: - pass - print('rm {}'.format(contextName)) - - def getResourceContext(self, contextName): - if not contextName: - return None - try: - return self.resourceContextDict[contextName] - except KeyError: - return None - - def addAPI(self, application, api, contextName = None): - if not contextName: - return - resourceContext = self.getResourceContext(contextName) - if not resourceContext: - return - entry = None - resourceContext.addAPI(application, api, entry) - def removeAPI(self, application, api, contextName = None): - if not contextName: - return - resourceContext = self.getResourceContext(contextName) - if not resourceContext: - return - resourceContext.removeAPI(application, api) - def addGesture(self, profile, application, gesture, entry, contextName = None): - if not contextName: - return - resourceContext = self.getResourceContext(contextName) - if not resourceContext: - return - entry = None - resourceContext.addGesture(profile, application, gesture, entry) - def removeGesture(self, gesture, contextName = None): - if not contextName: - return - resourceContext = self.getResourceContext(contextName) - if not resourceContext: - return - resourceContext.removeGesture(gesture) - def addSubscription(self, subscription, entry, contextName = None): - if not contextName: - return - resourceContext = self.getResourceContext(contextName) - if not resourceContext: - return - entry = None - resourceContext.addSubscription(subscription, entry) - def removeSubscriptionByFunction(self, function, contextName = None): - if not contextName: - return - resourceContext = self.getResourceContext(contextName) - if not resourceContext: - return - resourceContext.removeSubscriptionByFunction(function) - def addSignal(self, signal, entry, contextName = None): - if not contextName: - return - resourceContext = self.getResourceContext(contextName) - if not resourceContext: - return - entry = None - resourceContext.addSignal(signal, entry) - def removeSignal(self, signal, contextName = None): - if not contextName: - return - resourceContext = self.getResourceContext(contextName) - if not resourceContext: - return - resourceContext.removeSignal(signal) - def printContext(self): - for k, v in self.resourceContextDict.items(): - print('plugin', k) - for k1, v1 in v.getGestures().items(): - print(' profile', k1) - for k2, v2 in v1.items(): - print(' application', k2) - for k3, v3 in v2.items(): - print(' value', k3, v3) diff --git a/src/cthulhu/role_keys.py b/src/cthulhu/role_keys.py deleted file mode 100644 index 617ccf8..0000000 --- a/src/cthulhu/role_keys.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Shared role key constants for formatting and generators.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -# Custom role keys used by formatting and role override logic. -ROLE_ARTICLE_IN_FEED = 'ROLE_ARTICLE_IN_FEED' -ROLE_CONTENT_DELETION = 'ROLE_CONTENT_DELETION' -ROLE_CONTENT_ERROR = 'ROLE_CONTENT_ERROR' -ROLE_CONTENT_INSERTION = 'ROLE_CONTENT_INSERTION' -ROLE_CONTENT_MARK = 'ROLE_CONTENT_MARK' -ROLE_CONTENT_SUGGESTION = 'ROLE_CONTENT_SUGGESTION' -ROLE_DPUB_LANDMARK = 'ROLE_DPUB_LANDMARK' -ROLE_DPUB_SECTION = 'ROLE_DPUB_SECTION' -ROLE_FEED = 'ROLE_FEED' -ROLE_MATH_ENCLOSED = 'ROLE_MATH_ENCLOSED' -ROLE_MATH_FENCED = 'ROLE_MATH_FENCED' -ROLE_MATH_MULTISCRIPT = 'ROLE_MATH_MULTISCRIPT' -ROLE_MATH_SCRIPT_SUBSUPER = 'ROLE_MATH_SCRIPT_SUBSUPER' -ROLE_MATH_SCRIPT_UNDEROVER = 'ROLE_MATH_SCRIPT_UNDEROVER' -ROLE_MATH_TABLE = 'ROLE_MATH_TABLE' -ROLE_MATH_TABLE_ROW = 'ROLE_MATH_TABLE_ROW' -ROLE_REGION = 'ROLE_REGION' -ROLE_SWITCH = 'ROLE_SWITCH' -ROLE_SPREADSHEET_CELL = 'ROLE_SPREADSHEET_CELL' - -# Formatting override keys (not real Atspi roles). -REAL_ROLE_TABLE_CELL = 'REAL_ROLE_TABLE_CELL' -REAL_ROLE_SCROLL_PANE = 'REAL_ROLE_SCROLL_PANE' diff --git a/src/cthulhu/screen_lock_monitor.py b/src/cthulhu/screen_lock_monitor.py deleted file mode 100644 index 7b41e58..0000000 --- a/src/cthulhu/screen_lock_monitor.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Tracks the lifetime of I38Lock's secure accessibility-feedback worker.""" - -from __future__ import annotations - -import os -from typing import Any, Optional - -from gi.repository import Gio, GLib - -from . import debug - - -class ScreenLockMonitor: - """Enters secure screen-reader mode while I38Lock owns its session-bus name.""" - - BUS_NAME = "org.stormux.I38Lock1" - TRUSTED_EXECUTABLE = "i38lock" - - def __init__(self, app: Any) -> None: - self._app = app - self._connection: Optional[Gio.DBusConnection] = None - self._watch_id: int = 0 - self._is_running: bool = False - self._is_active: bool = False - - def start(self) -> None: - """Starts watching the session bus for I38Lock.""" - - if self._is_running: - return - - try: - self._connection = Gio.bus_get_sync(Gio.BusType.SESSION, None) - except Exception as error: - msg = f"SCREEN LOCK MONITOR: Failed to connect to session bus: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return - - self._watch_id = Gio.bus_watch_name_on_connection( - self._connection, - self.BUS_NAME, - Gio.BusNameWatcherFlags.NONE, - self._on_name_appeared, - self._on_name_vanished, - ) - self._is_running = True - debug.printMessage(debug.LEVEL_INFO, "SCREEN LOCK MONITOR: Started", True) - - def stop(self) -> None: - """Stops watching I38Lock and releases any active secure state.""" - - if self._watch_id: - Gio.bus_unwatch_name(self._watch_id) - self._watch_id = 0 - - if self._is_active: - self._set_active(False, schedule_focus_resync=False) - - self._connection = None - self._is_running = False - debug.printMessage(debug.LEVEL_INFO, "SCREEN LOCK MONITOR: Stopped", True) - - def is_running(self) -> bool: - """Returns whether the D-Bus name watcher is running.""" - - return self._is_running - - def is_active(self) -> bool: - """Returns whether I38Lock currently owns its secure-state bus name.""" - - return self._is_active - - def _set_active(self, active: bool, schedule_focus_resync: bool = True) -> None: - if self._is_active == active: - return - - self._is_active = active - self._app.eventManager.set_screen_lock_active( - active, - schedule_focus_resync=schedule_focus_resync, - ) - - def _get_name_owner_pid( - self, - connection: Gio.DBusConnection, - name_owner: str, - ) -> Optional[int]: - try: - result = connection.call_sync( - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "GetConnectionUnixProcessID", - GLib.Variant("(s)", (name_owner,)), - GLib.VariantType("(u)"), - Gio.DBusCallFlags.NONE, - 500, - None, - ) - return result.unpack()[0] - except Exception as error: - msg = f"SCREEN LOCK MONITOR: Failed to get owner PID for {name_owner}: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return None - - def _is_trusted_owner(self, connection: Gio.DBusConnection, name_owner: str) -> bool: - pid = self._get_name_owner_pid(connection, name_owner) - if pid is None: - return False - - try: - executable = os.path.basename(os.readlink(f"/proc/{pid}/exe")) - except OSError as error: - msg = f"SCREEN LOCK MONITOR: Failed to inspect owner PID {pid}: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - - if executable != self.TRUSTED_EXECUTABLE: - msg = f"SCREEN LOCK MONITOR: Ignoring untrusted owner executable {executable}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return False - - return True - - def _on_name_appeared( - self, - connection: Gio.DBusConnection, - name: str, - name_owner: str, - _user_data: Optional[Any] = None, - ) -> None: - msg = f"SCREEN LOCK MONITOR: {name} appeared as {name_owner}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if not self._is_trusted_owner(connection, name_owner): - return - self._set_active(True) - - def _on_name_vanished( - self, - _connection: Gio.DBusConnection, - name: str, - _user_data: Optional[Any] = None, - ) -> None: - msg = f"SCREEN LOCK MONITOR: {name} vanished" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._set_active(False) diff --git a/src/cthulhu/script.py b/src/cthulhu/script.py deleted file mode 100644 index f298fb8..0000000 --- a/src/cthulhu/script.py +++ /dev/null @@ -1,637 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Each script maintains a set of key bindings, braille bindings, and -AT-SPI event listeners. The key bindings are an instance of -KeyBindings. The braille bindings are also a dictionary where the -keys are BrlTTY command integers and the values are instances of -InputEventHandler. The listeners field is a dictionary where the keys -are AT-SPI event names and the values are function pointers. - -Instances of scripts are intended to be created solely by the -script manager. - -This Script class is not intended to be instantiated directly. -Instead, it is expected that subclasses of the Script class will be -created in their own module. The module defining the Script subclass -is also required to have a 'get_script(app)' method that returns an -instance of the Script subclass. See default.py for an example.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import cthulhu # Need access to cthulhuApp -from . import ax_event_synthesizer -from . import action_presenter -from . import braille_generator -from . import date_and_time_presenter -from . import debug -from . import event_manager -from . import flat_review_presenter -from . import formatting -from . import keybindings -from . import label_inference -from . import learn_mode_presenter -from . import mouse_review -from . import notification_presenter -from . import object_navigator -from . import cthulhu_state -from . import script_manager -from . import script_utilities -from . import settings -from . import settings_manager -from . import sleep_mode_manager -from . import sound_generator -from . import speech_and_verbosity_manager -from . import speech_generator -from . import structural_navigation -from . import bookmarks -from . import tutorialgenerator -from . import where_am_i_presenter -from .ax_object import AXObject - -# Old global variables removed - scripts now access via cthulhuApp or self._app - -class Script: - """The specific focus tracking scripts for applications. - """ - - def __init__(self, app): - """Creates a script for the given application, if necessary. - This method should not be called by anyone except the - script manager. - - Arguments: - - app: the Python Accessible application to create a script for - """ - self.app = app - - if app: - self.name = AXObject.get_name(self.app) or "default" - else: - self.name = "default" - - self.name += " (module=" + self.__module__ + ")" - - self.listeners = self.getListeners() - - # By default, handle events for non-active applications. - # - self.presentIfInactive = True - - self.utilities = self.getUtilities() - self.labelInference = self.getLabelInference() - self.structuralNavigation = self.getStructuralNavigation() - self.caretNavigation = self.getCaretNavigation() - self.bookmarks = self.getBookmarks() - self.liveRegionManager = self.getLiveRegionManager() - self.notificationPresenter = self.getNotificationPresenter() - self.flatReviewPresenter = self.getFlatReviewPresenter() - self.speechAndVerbosityManager = self.getSpeechAndVerbosityManager() - self.dateAndTimePresenter = self.getDateAndTimePresenter() - self.objectNavigator = self.get_objectNavigator() - self.whereAmIPresenter = self.getWhereAmIPresenter() - self.learnModePresenter = self.getLearnModePresenter() - self.mouseReviewer = self.getMouseReviewer() - self.eventSynthesizer = self.get_event_synthesizer() - self.actionPresenter = self.getActionPresenter() - - self.chat = self.getChat() - self.inputEventHandlers = {} - self.pointOfReference = {} - self.setupInputEventHandlers() - self.keyBindings = self.getKeyBindings() - self.brailleBindings = self.getBrailleBindings() - - self.formatting = self.getFormatting() - self.brailleGenerator = self.getBrailleGenerator() - self.soundGenerator = self.getSoundGenerator() - self.speechGenerator = self.getSpeechGenerator() - self.generatorCache = {} - self.eventCache = {} - self.spellcheck = self.getSpellCheck() - self.tutorialGenerator = self.getTutorialGenerator() - - self.findCommandRun = False - self._lastCommandWasStructNav = False - - msg = f'SCRIPT: {self.name} initialized' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def __str__(self): - return f"{self.name}" - - def getListeners(self): - """Sets up the AT-SPI event listeners for this script. - - Returns a dictionary where the keys are AT-SPI event names - and the values are script methods. - """ - return {} - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for this script that can be - called by the key and braille bindings.""" - pass - - def getKeyBindings(self): - """Defines the key bindings for this script. - - Returns an instance of keybindings.KeyBindings. - """ - return keybindings.KeyBindings() - - def getToolkitKeyBindings(self): - """Returns the toolkit-specific keybindings for this script.""" - - return keybindings.KeyBindings() - - def getAppKeyBindings(self): - """Returns the application-specific keybindings for this script.""" - - return keybindings.KeyBindings() - - def getPluginKeyBindings(self): - """Returns the plugin keybindings for this script.""" - - from . import debug - debug.printMessage(debug.LEVEL_INFO, "SCRIPT: getPluginKeyBindings() called", True) - - plugin_bindings = keybindings.KeyBindings() - - # Get the plugin system manager - try: - from . import plugin_system_manager - manager = plugin_system_manager.getManager() - debug.printMessage(debug.LEVEL_INFO, f"SCRIPT: Plugin manager: {manager}", True) - if manager: - # Get all active plugins - active_plugins = manager.get_active_plugins() - debug.printMessage(debug.LEVEL_INFO, f"SCRIPT: Found {len(active_plugins)} active plugins", True) - for plugin in active_plugins: - # Get bindings from each plugin - bindings = plugin.get_bindings() - debug.printMessage(debug.LEVEL_INFO, f"SCRIPT: Plugin {plugin.name} has bindings: {bindings}", True) - if bindings: - # Add each binding from the plugin to our collection - for binding in bindings.keyBindings: - plugin_bindings.add(binding) - debug.printMessage(debug.LEVEL_INFO, f"SCRIPT: Added plugin binding: {binding.asString()}", True) - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"Could not get plugin keybindings: {e}", True) - import traceback - debug.printMessage(debug.LEVEL_INFO, traceback.format_exc(), True) - - debug.printMessage(debug.LEVEL_INFO, f"SCRIPT: Returning {len(plugin_bindings.keyBindings)} plugin bindings", True) - return plugin_bindings - - def getBrailleBindings(self): - """Defines the braille bindings for this script. - - Returns a dictionary where the keys are BrlTTY commands and the - values are InputEventHandler instances. - """ - return {} - - def getFormatting(self): - """Returns the formatting strings for this script.""" - return formatting.Formatting(self) - - def getBrailleGenerator(self): - """Returns the braille generator for this script. - """ - return braille_generator.BrailleGenerator(self) - - def getSoundGenerator(self): - """Returns the sound generator for this script.""" - return sound_generator.SoundGenerator(self) - - def getSpeechGenerator(self): - """Returns the speech generator for this script. - """ - return speech_generator.SpeechGenerator(self) - - def getTutorialGenerator(self): - """Returns the tutorial generator for this script. - """ - return tutorialgenerator.TutorialGenerator(self) - - def getChat(self): - """Returns the 'chat' class for this script. - """ - return None - - def getSpellCheck(self): - """Returns the spellcheck support for this script.""" - return None - - def getCaretNavigation(self): - """Returns the caret navigation support for this script.""" - return None - - def getUtilities(self): - """Returns the utilities for this script.""" - return script_utilities.Utilities(self) - - def getLabelInference(self): - """Returns the label inference functionality for this script.""" - return label_inference.LabelInference(self) - - def getEnabledStructuralNavigationTypes(self): - """Returns a list of the structural navigation object types - enabled in this script. - """ - return [] - - def getStructuralNavigation(self): - """Returns the 'structural navigation' class for this script.""" - types = self.getEnabledStructuralNavigationTypes() - enable = cthulhu.cthulhuApp.settingsManager.getSetting('structuralNavigationEnabled') - return structural_navigation.StructuralNavigation(self, types, enable) - - def getLiveRegionManager(self): - """Returns the live region support for this script.""" - return None - - def getNotificationPresenter(self): - return notification_presenter.getPresenter() - - def getFlatReviewPresenter(self): - return flat_review_presenter.getPresenter() - - def getDateAndTimePresenter(self): - return date_and_time_presenter.getPresenter() - - def get_objectNavigator(self): - return object_navigator.getNavigator() - - def getSpeechAndVerbosityManager(self): - return speech_and_verbosity_manager.getManager() - - def getWhereAmIPresenter(self): - return where_am_i_presenter.getPresenter() - - def getLearnModePresenter(self): - return learn_mode_presenter.getPresenter() - - def getActionPresenter(self): - return action_presenter.getPresenter() - - def getMouseReviewer(self): - return mouse_review.getReviewer() - - def get_event_synthesizer(self): - return ax_event_synthesizer.get_synthesizer() - - def useStructuralNavigationModel(self, debugOutput=True): - """Returns True if we should use structural navigation. Most - scripts will have no need to override this. Gecko does however - because within an HTML document there are times when we do want - to use it and times when we don't even though it is enabled, - e.g. in a form field. - """ - return self.structuralNavigation.enabled - - def getBookmarks(self): - """Returns the "bookmarks" class for this script. - """ - try: - return self.bookmarks - except AttributeError: - self.bookmarks = bookmarks.Bookmarks(self) - return self.bookmarks - - def getAppPreferencesGUI(self): - """Return a GtkGrid containing the application unique configuration - GUI items for the current application. - """ - return None - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - return {} - - def registerEventListeners(self): - """Tells the event manager to start listening for all the event types - of interest to the script. - - Arguments: - - script: the script. - """ - - cthulhu.cthulhuApp.eventManager.registerScriptListeners(self) - - def deregisterEventListeners(self): - """Tells the event manager to stop listening for all the event types - of interest to the script. - - Arguments: - - script: the script. - """ - - cthulhu.cthulhuApp.eventManager.deregisterScriptListeners(self) - - def processObjectEvent(self, event): - """Processes all AT-SPI object events of interest to this - script. The interest in events is specified via the - 'listeners' field that was defined during the construction of - this script. - - Note that this script may be passed events it doesn't care - about, so it needs to react accordingly. - - Arguments: - - event: the Event - """ - - role = AXObject.get_role(event.source) - if role == Atspi.Role.INVALID: - msg = 'ERROR: Not processing object event for invalid object' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - # Check to see if we really want to process this event. - # - processEvent = (cthulhu_state.activeScript == self \ - or self.presentIfInactive) - if role == Atspi.Role.PROGRESS_BAR \ - and not processEvent \ - and settings.progressBarVerbosity == settings.PROGRESS_BAR_ALL: - processEvent = True - - if not processEvent: - return - - if self.skipObjectEvent(event): - return - - # Clear the generator cache for each event. - # - self.generatorCache = {} - - # This calls the first listener it finds whose key *begins with* or is - # the same as the event.type. The reason we do this is that the event - # type in the listeners dictionary may not be as specific as the event - # type we received (e.g., the listeners dictionary might contain the - # key "object:state-changed:" and the event.type might be - # "object:state-changed:focused". [[[TODO: WDW - the order of the - # keys is *not* deterministic, and is not guaranteed to be related - # to the order in which they were added. So...we need to do something - # different here. Logged as bugzilla bug 319781.]]] - # - for key in self.listeners.keys(): - if event.type.startswith(key): - self.listeners[key](event) - - def _getQueuedEvent(self, eventType, detail1=None, detail2=None, any_data=None): - cachedEvent, eventTime = self.eventCache.get(eventType, [None, 0]) - if not cachedEvent: - tokens = ["SCRIPT: No queued event of type", eventType] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - if detail1 is not None and detail1 != cachedEvent.detail1: - tokens = ["SCRIPT: Queued event's detail1 (", cachedEvent.detail1, - ") doesn't match", detail1] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - if detail2 is not None and detail2 != cachedEvent.detail2: - tokens = ["SCRIPT: Queued event's detail2 (", cachedEvent.detail2, - ") doesn't match", detail2] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - if any_data is not None and any_data != cachedEvent.any_data: - tokens = ["SCRIPT: Queued event's any_data (", - cachedEvent.any_data, ") doesn't match", any_data] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - tokens = ["SCRIPT: Found matching queued event:", cachedEvent] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return cachedEvent - - def skipObjectEvent(self, event): - """Gives us, and scripts, the ability to decide an event isn't - worth taking the time to process under the current circumstances. - - Arguments: - - event: the Event - - Returns True if we shouldn't bother processing this object event. - """ - - cachedEvent, eventTime = self.eventCache.get(event.type, [None, 0]) - if not cachedEvent or cachedEvent == event: - return False - - focus = ["object:state-changed:focused"] - typing = ["object:text-changed:insert", "object:text-changed:delete"] - arrowing = ["object:text-caret-moved", "object:text-selection-changed", - "object:selection-changed", "object:active-descendant-changed"] - - skip = False - if (event.type in arrowing or event.type in typing) \ - and event.source == cachedEvent.source: - skip = True - reason = "more recent event of the same type in the same object" - elif event.type in focus and event.source != cachedEvent.source \ - and event.type == cachedEvent.type \ - and event.detail1 == cachedEvent.detail1: - skip = True - reason = "more recent event of the same type in a different object" - elif event.type.endswith("system") and event.source == cachedEvent.source: - skip = True - reason = "more recent system event in the same object" - elif event.type.startswith("object:state-changed") \ - and event.type == cachedEvent.type \ - and event.source == cachedEvent.source \ - and event.detail1 == cachedEvent.detail1: - skip = True - reason = "appears to be duplicate state-changed event" - - if skip: - tokens = ["SCRIPT: Skipping object event:", reason, cachedEvent] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return skip - - def consumesKeyboardEvent(self, keyboardEvent): - """Called when a key is pressed on the keyboard. - - Arguments: - - keyboardEvent: an instance of input_event.KeyboardEvent - - Returns True if the event is of interest. - """ - - handler = self.keyBindings.getInputHandler(keyboardEvent) - self.updateKeyboardEventState(keyboardEvent, handler) - return self.shouldConsumeKeyboardEvent(keyboardEvent, handler) - - def updateKeyboardEventState(self, keyboardEvent, handler): - """Update internal state for a keyboard event without deciding consumption.""" - pass - - def shouldConsumeKeyboardEvent(self, keyboardEvent, handler): - """Returns True if the script will consume this keyboard event.""" - consumes = False - self._lastCommandWasStructNav = False - if handler and handler.function in self.structuralNavigation.functions: - consumes = self.useStructuralNavigationModel() - if consumes: - self._lastCommandWasStructNav = True - else: - consumes = handler is not None - return consumes - - def consumesBrailleEvent(self, brailleEvent): - """Called when a key is pressed on the braille display. - - Arguments: - - brailleEvent: an instance of input_event.KeyboardEvent - - Returns True if the event is of interest. - """ - user_bindings = None - user_bindings_map = settings.brailleBindingsMap - if self.__module__ in user_bindings_map: - user_bindings = user_bindings_map[self.__module__] - elif "default" in user_bindings_map: - user_bindings = user_bindings_map["default"] - - command = brailleEvent.event["command"] - consumes = False - if user_bindings: - consumes = command in user_bindings - if not consumes: - consumes = command in self.brailleBindings - return consumes - - def processBrailleEvent(self, brailleEvent): - """Called whenever a key is pressed on the Braille display. - - This method will primarily use the brailleBindings field of - this script instance see if this script has an interest in the - event. - - NOTE: there is latent, but unsupported, logic for allowing - the user's user-settings.py file to extend and/or override - the brailleBindings for a script. - - Arguments: - - brailleEvent: an instance of input_event.BrailleEvent - """ - - # We'll annotate the event with a reference to this script. - # This will allow external scripts to muck with the script - # instance if they wish. - # - brailleEvent.script = self - - # We'll let the user bindings take precedence. First, we'll - # check to see if they have bindings specific for the particular - # application, then we'll check to see if they have any default - # bindings to use. - # - # [[[TODO: WDW - for performance, these bindings should probably - # be conflated at initialization time.]]] - # - consumed = False - user_bindings = None - command = brailleEvent.event["command"] - - user_bindings_map = settings.brailleBindingsMap - if self.name in user_bindings_map: - user_bindings = user_bindings_map[self.name] - elif "default" in user_bindings_map: - user_bindings = user_bindings_map["default"] - - if user_bindings and command in user_bindings: - handler = user_bindings[command] - consumed = handler.processInputEvent(self, brailleEvent) - - if (not consumed) and command in self.brailleBindings: - handler = self.brailleBindings[command] - consumed = handler.processInputEvent(self, brailleEvent) - - return consumed - - def locus_of_focus_changed(self, event, oldLocusOfFocus, newLocusOfFocus): - """Called when the visual object with focus changes. - - The primary purpose of this method is to present locus of focus - information to the user. - - NOTE: scripts should not call this method directly. Instead, - a script should call cthulhu.setLocusOfFocus, which will eventually - result in this method being called. - - Arguments: - - event: if not None, the Event that caused the change - - oldLocusOfFocus: Accessible that is the old locus of focus - - newLocusOfFocus: Accessible that is the new locus of focus - """ - pass - - def isActivatableEvent(self, event): - """Returns True if the given event is one that should cause this - script to become the active script. This is only a hint to - the focus tracking manager and it is not guaranteed this - request will be honored. Note that by the time the focus - tracking manager calls this method, it thinks the script - should become active. This is an opportunity for the script - to say it shouldn't. - """ - return True - - def forceScriptActivation(self, event): - """Allows scripts to insist that they should become active.""" - - return False - - def activate(self): - """Called when this script is activated.""" - pass - - def deactivate(self): - """Called when this script is deactivated.""" - pass - - def getSleepModeManager(self): - """Returns the sleep mode manager for this script.""" - return sleep_mode_manager.getManager() - - def getTransferableAttributes(self): - return {} diff --git a/src/cthulhu/script_manager.py b/src/cthulhu/script_manager.py deleted file mode 100644 index b393745..0000000 --- a/src/cthulhu/script_manager.py +++ /dev/null @@ -1,502 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2011. Cthulhu Team." -__license__ = "LGPL" - -import importlib -from typing import TYPE_CHECKING, Optional, Dict, Any, List, Union - -from . import debug -from . import cthulhu_state -from .ax_object import AXObject -from .scripts import apps, toolkits - -if TYPE_CHECKING: - from gi.repository import Atspi - from .cthulhu import Cthulhu - from .script import Script - from .input_event import InputEvent - -# Forward references to avoid circular imports -# Script is defined in script.py -# Atspi.Accessible comes from AT-SPI - -def _get_ax_utilities() -> Any: - # Avoid circular import with ax_utilities -> ax_utilities_event -> focus_manager -> braille -> settings_manager -> script_manager. - from .ax_utilities import AXUtilities - return AXUtilities - -def _log(message: str, reason: Optional[str] = None, timestamp: bool = True, stack: bool = False) -> None: - debug.print_log(debug.LEVEL_INFO, "SCRIPT MANAGER", message, reason, timestamp, stack) - -def _log_tokens(tokens: list[Any], reason: Optional[str] = None, timestamp: bool = True, stack: bool = False) -> None: - debug.print_log_tokens(debug.LEVEL_INFO, "SCRIPT MANAGER", tokens, reason, timestamp, stack) - -class ScriptManager: - - def __init__(self, app: Cthulhu) -> None: - _log("Initializing") - self.app: Cthulhu = app # Store app instance - self.appScripts: Dict[Atspi.Accessible, Script] = {} - self.toolkitScripts: Dict[Atspi.Accessible, Dict[str, Script]] = {} - self.customScripts: Dict[Atspi.Accessible, Dict[str, Script]] = {} - self._sleepModeScripts: Dict[Atspi.Accessible, Script] = {} - self._appModules: List[str] = apps.__all__ - self._toolkitModules: List[str] = toolkits.__all__ - self._defaultScript: Optional[Script] = None - self._scriptPackages: List[str] = \ - ["cthulhu-scripts", - "cthulhu.scripts", - "cthulhu.scripts.apps", - "cthulhu.scripts.toolkits"] - self._appNames: Dict[str, str] = \ - {'Icedove': 'Thunderbird', - 'Nereid': 'Banshee', - 'gnome-calculator': 'gcalctool', - 'Steam': 'steamwebhelper', - 'Steam Web Helper': 'steamwebhelper', - 'gtk-window-decorator': 'switcher', - 'marco': 'switcher', - 'xfce4-notifyd': 'notification-daemon', - 'mate-notification-daemon': 'notification-daemon', - 'metacity': 'switcher', - 'pluma': 'gedit', - } - self._toolkitNames: Dict[str, str] = \ - {'WebKitGTK': 'WebKitGtk', 'GTK': 'gtk'} - - self.set_active_script(None, "lifecycle: init") - self._active: bool = False - _log("Initialized") - - def activate(self) -> None: - """Called when this script manager is activated.""" - - _log("Activating") - self._defaultScript = self.get_script(None) - if self._defaultScript: - self._defaultScript.registerEventListeners() - self.set_active_script(self._defaultScript, "lifecycle: activate") - self._active = True - _log("Activated") - - def deactivate(self) -> None: - """Called when this script manager is deactivated.""" - - _log("Deactivating") - if self._defaultScript: - self._defaultScript.deregisterEventListeners() - self._defaultScript = None - self.set_active_script(None, "lifecycle: deactivate") - self.appScripts = {} - self.toolkitScripts = {} - self.customScripts = {} - self._active = False - _log("Deactivated") - - def get_module_name(self, app: Optional[Atspi.Accessible]) -> Optional[str]: - """Returns the module name of the script to use for application app.""" - - if app is None: - _log("Cannot get module name for null app", "null-app") - return None - - name = AXObject.get_name(app) - if not name: - _log("Cannot get module name for nameless app", "nameless-app") - return None - - pid = AXObject.get_process_id(app) - if pid != -1: - cmdline = debug.getCmdline(pid) - if "steamwebhelper" in cmdline: - return "steamwebhelper" - - altNames = list(self._appNames.keys()) - if name.endswith(".py") or name.endswith(".bin"): - name = name.split('.')[0] - elif name.startswith("org.") or name.startswith("com."): - name = name.split('.')[-1] - - names = [n for n in altNames if n.lower() == name.lower()] - if names: - name = self._appNames.get(names[0]) - else: - for nameList in (self._appModules, self._toolkitModules): - names = [n for n in nameList if n.lower() == name.lower()] - if names: - name = names[0] - break - - _log_tokens(["Mapped", app, "to", name]) - return name - - def _toolkit_for_object(self, obj: Optional[Atspi.Accessible]) -> Optional[str]: - """Returns the name of the toolkit associated with obj.""" - if obj is None: - return None - name = AXObject.get_attribute(obj, 'toolkit') - return self._toolkitNames.get(name, name) - - def _script_for_role(self, obj: Optional[Atspi.Accessible]) -> str: - if _get_ax_utilities().is_terminal(obj): - return 'terminal' - - return '' - - def _new_named_script(self, app: Optional[Atspi.Accessible], name: Optional[str]) -> Optional[Script]: - """Attempts to locate and load the named module. If successful, returns - a script based on this module.""" - - if not (app and name): - return None - - script = None - for package in self._scriptPackages: - moduleName = '.'.join((package, name)) - try: - module = importlib.import_module(moduleName) - except ImportError: - continue - except OSError: - debug.examineProcesses() - - _log_tokens(["Found", moduleName]) - try: - if hasattr(module, 'get_script'): - script = module.get_script(app) - else: - script = module.Script(app) - break - except Exception as error: - _log_tokens(["Could not load", moduleName, ":", error], "load-failed") - - return script - - def _create_script(self, app: Optional[Atspi.Accessible], obj: Optional[Atspi.Accessible] = None) -> Script: - """For the given application, create a new script instance.""" - - moduleName = self.get_module_name(app) - script = self._new_named_script(app, moduleName) - if script: - return script - - objToolkit = self._toolkit_for_object(obj) - script = self._new_named_script(app, objToolkit) - if script: - return script - - toolkitName = _get_ax_utilities().get_application_toolkit_name(app) - if app and toolkitName: - script = self._new_named_script(app, toolkitName) - - if not script: - script = self.get_default_script(app) - _log_tokens(["Default script created for", app, "(obj:", obj, ")"]) - - return script - - def get_default_script(self, app: Optional[Atspi.Accessible] = None) -> Script: - if not app and self._defaultScript: - return self._defaultScript - - from .scripts import default - script = default.Script(app) - - if not app: - self._defaultScript = script - - return script - - def sanity_check_script(self, script: Script) -> Script: - if not self._active: - return script - - if _get_ax_utilities().is_application_in_desktop(script.app): - return script - - newScript = self._get_script_for_app_replicant(script.app) - if newScript: - return newScript - - _log_tokens(["Failed to get a replacement script for", script.app], "replacement-missing") - return script - - def get_script_for_mouse_button_event(self, event: Any) -> Script: - # Note: event type unspecified in original code, likely InputEvent or similar - isActive = _get_ax_utilities().is_active(cthulhu_state.activeWindow) - _log_tokens([cthulhu_state.activeWindow, "is active:", isActive]) - - if isActive and cthulhu_state.activeScript: - return cthulhu_state.activeScript - - script = self.get_default_script() - activeWindow = script.utilities.activeWindow() - if not activeWindow: - return script - - focusedObject = _get_ax_utilities().get_focused_object(activeWindow) - if focusedObject: - return self.get_script(AXObject.get_application(focusedObject), focusedObject) - - return self.get_script(AXObject.get_application(activeWindow), activeWindow) - - def get_active_script(self) -> Optional[Script]: - return cthulhu_state.activeScript - - def get_script(self, app: Optional[Atspi.Accessible], obj: Optional[Atspi.Accessible] = None, sanity_check: bool = False) -> Script: - """Get a script for an app (and make it if necessary). This is used - instead of a simple calls to Script's constructor. - - Arguments: - - app: the Python app - - Returns an instance of a Script. - """ - - if app: - try: - from . import sleep_mode_manager - sleepModeManager = sleep_mode_manager.getManager() - sleepModeManager.refreshAutoSleepConfig() - if sleepModeManager and sleepModeManager.isActiveForApp(app): - return self.get_or_create_sleep_mode_script(app) - except Exception as error: - _log_tokens(["Could not check sleep mode for", app, ":", error], "sleep-mode-check-failed") - - customScript = None - appScript = None - toolkitScript = None - - roleName = self._script_for_role(obj) - if roleName: - customScripts = self.customScripts.get(app, {}) # type: ignore - customScript = customScripts.get(roleName) - if not customScript: - customScript = self._new_named_script(app, roleName) - if customScript: - customScripts[roleName] = customScript - if app: - self.customScripts[app] = customScripts - - objToolkit = self._toolkit_for_object(obj) - if objToolkit: - toolkitScripts = self.toolkitScripts.get(app, {}) # type: ignore - toolkitScript = toolkitScripts.get(objToolkit) - if not toolkitScript: - toolkitScript = self._create_script(app, obj) - toolkitScripts[objToolkit] = toolkitScript - if app: - self.toolkitScripts[app] = toolkitScripts - - try: - if not app: - appScript = self.get_default_script() - elif app in self.appScripts: - appScript = self.appScripts[app] - else: - appScript = self._create_script(app, None) - self.appScripts[app] = appScript - except Exception as error: - _log_tokens(["Exception getting app script for", app, ":", error], "app-script-error") - appScript = self.get_default_script() - - if customScript: - return customScript - - # Only defer to the toolkit script for this object if the app script - # is based on a different toolkit. - if toolkitScript and not (_get_ax_utilities().is_frame(obj) or _get_ax_utilities().is_status_bar(obj)) \ - and not issubclass(appScript.__class__, toolkitScript.__class__): - return toolkitScript - - if app and sanity_check: - appScript = self.sanity_check_script(appScript) - - return appScript - - def get_or_create_sleep_mode_script(self, app: Atspi.Accessible) -> Script: - """Gets or creates the sleep mode script.""" - script = self._sleepModeScripts.get(app) - if script is not None: - return script - - # Import sleepmode dynamically to avoid circular imports - from .scripts import sleepmode - script = sleepmode.Script(app) - self._sleepModeScripts[app] = script - return script - - def set_active_script(self, newScript: Optional[Script], reason: Optional[str] = None) -> None: - """Set the new active script. - - Arguments: - - newScript: the new script to be made active. - """ - - if cthulhu_state.activeScript == newScript: - return - - if cthulhu_state.activeScript: - cthulhu_state.activeScript.deactivate() - - cthulhu_state.activeScript = newScript - if not newScript: - self._log_active_state(reason) - return - - newScript.activate() - - # Emit signal that active script has changed, so PluginSystemManager can update keybindings - from . import cthulhu - if cthulhu.cthulhuApp: - cthulhu.cthulhuApp.getSignalManager().emitSignal('active-script-changed', newScript) - - _log_tokens(["Setting active script to", newScript], reason) - self._log_active_state(reason) - - def activate_script_for_context(self, app: Optional[Atspi.Accessible], obj: Optional[Atspi.Accessible], reason: Optional[str] = None) -> Script: - script = self.get_script(app, obj) - self.set_active_script(script, reason) - return script - - def _log_active_state(self, reason: Optional[str] = None) -> None: - _log_tokens( - ["Active state:", "window", cthulhu_state.activeWindow, - "focus", cthulhu_state.locusOfFocus, - "script", cthulhu_state.activeScript], - reason - ) - - def get_debug_snapshot(self) -> Dict[str, object]: - """Returns read-only counters useful for long-uptime diagnostics.""" - - activeScript = cthulhu_state.activeScript - activeApp = getattr(activeScript, "app", None) - activeAppName = "" - if activeApp is not None: - try: - activeAppName = AXObject.get_name(activeApp) or "" - except Exception: - activeAppName = "[unavailable]" - - return { - "active": self._active, - "active_script": activeScript.__class__.__name__ if activeScript else "", - "active_script_app": activeAppName, - "default_script_present": self._defaultScript is not None, - "app_scripts": len(self.appScripts), - "toolkit_script_apps": len(self.toolkitScripts), - "toolkit_scripts": sum(len(scripts) for scripts in self.toolkitScripts.values()), - "custom_script_apps": len(self.customScripts), - "custom_scripts": sum(len(scripts) for scripts in self.customScripts.values()), - "sleep_mode_scripts": len(self._sleepModeScripts), - } - - def _get_script_for_app_replicant(self, app: Atspi.Accessible) -> Optional[Script]: - if not self._active: - return None - - pid = AXObject.get_process_id(app) - if pid == -1: - return None - - items = self.appScripts.items() - for a, script in items: - if AXObject.get_process_id(a) != pid: - continue - if a != app and _get_ax_utilities().is_application_in_desktop(a): - if script.app is None: - script.app = a - _log_tokens(["Script for app replicant:", script, script.app]) - return script - - return None - - def reclaim_scripts(self) -> None: - """Compares the list of known scripts to the list of known apps, - deleting any scripts as necessary. - """ - - _log("Checking and cleaning up scripts.") - - appList = list(self.appScripts.keys()) - for app in appList: - if _get_ax_utilities().is_application_in_desktop(app): - continue - - try: - appScript = self.appScripts.pop(app) - except KeyError: - _log_tokens([app, "not found in appScripts"]) - continue - - _log_tokens(["Old script for app found:", appScript, appScript.app]) - - newScript = self._get_script_for_app_replicant(app) - if newScript: - _log_tokens(["Transferring attributes:", newScript, newScript.app]) - attrs = appScript.getTransferableAttributes() - for attr, value in attrs.items(): - _log_tokens(["Setting", attr, "to", value]) - setattr(newScript, attr, value) - - del appScript - - try: - toolkitScripts = self.toolkitScripts.pop(app) - except KeyError: - pass - else: - for toolkitScript in toolkitScripts.values(): - del toolkitScript - - try: - customScripts = self.customScripts.pop(app) - except KeyError: - pass - else: - for customScript in customScripts.values(): - del customScript - - del app - -_manager: Optional[ScriptManager] = None - -def get_manager() -> Optional[ScriptManager]: - """Returns the Script Manager""" - - global _manager - if _manager is None: - from . import cthulhu - if cthulhu.cthulhuApp: - _manager = cthulhu.cthulhuApp.scriptManager - return _manager diff --git a/src/cthulhu/script_utilities.py b/src/cthulhu/script_utilities.py deleted file mode 100644 index 2304046..0000000 --- a/src/cthulhu/script_utilities.py +++ /dev/null @@ -1,5801 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Commonly-required utility methods needed by -- and potentially - customized by -- application and toolkit scripts. They have - been pulled out from the scripts because certain scripts had - gotten way too large as a result of including these methods.""" - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." -__license__ = "LGPL" - -import functools -import gi -import locale -import math -import re -import time -from difflib import SequenceMatcher -from typing import Any, Callable, Generator, Optional, TYPE_CHECKING - -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import Gdk -from gi.repository import Gtk - -from . import chnames -from . import colornames -from . import debug -from . import keynames -from . import keybindings -from . import input_event -from . import input_event_manager -from . import mathsymbols -from . import messages -from . import cthulhu -from . import cthulhu_state -from . import object_properties -from . import pronunciation_dict -from . import settings -from . import settings_manager -from . import text_attribute_names -from .ax_component import AXComponent -from .ax_document_selection import AXDocumentSelection -from .ax_object import AXObject -from .ax_selection import AXSelection -from .ax_table import AXTable -from .ax_text import AXText -from .ax_hypertext import AXHypertext -from .ax_value import AXValue -from .ax_utilities import AXUtilities -from .ax_utilities_relation import AXUtilitiesRelation - -if TYPE_CHECKING: - from .script import Script - -_settingsManager: Optional[Any] = None # Removed - use cthulhu.cthulhuApp.settingsManager - -# Try to import sound system for indentation beeps -try: - from . import sound - from .sound_generator import Tone - _SOUND_AVAILABLE: bool = True -except ImportError: - _SOUND_AVAILABLE: bool = False - -############################################################################# -# # -# Utilities # -# # -############################################################################# - -class Utilities: - - _last_clipboard_update: float = time.time() - - EMBEDDED_OBJECT_CHARACTER: str = '\ufffc' - ZERO_WIDTH_NO_BREAK_SPACE: str = '\ufeff' - SUPERSCRIPT_DIGITS: list[str] = \ - ['\u2070', '\u00b9', '\u00b2', '\u00b3', '\u2074', - '\u2075', '\u2076', '\u2077', '\u2078', '\u2079'] - SUBSCRIPT_DIGITS: list[str] = \ - ['\u2080', '\u2081', '\u2082', '\u2083', '\u2084', - '\u2085', '\u2086', '\u2087', '\u2088', '\u2089'] - MENU_ROLES_IN_OPEN_MENU: set[Atspi.Role] = { - Atspi.Role.MENU, - Atspi.Role.MENU_ITEM, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.SEPARATOR, - } - ZOMBIE_TOP_LEVEL_ROLES: set[Atspi.Role] = { - Atspi.Role.APPLICATION, - Atspi.Role.ALERT, - Atspi.Role.DIALOG, - Atspi.Role.LABEL, # For Unity Panel Service bug - Atspi.Role.PAGE, # For Evince bug - Atspi.Role.WINDOW, - Atspi.Role.FRAME, - } - DISPLAYED_TEXT_DIRECT_NAME_ROLES: set[Atspi.Role] = { - Atspi.Role.PUSH_BUTTON, - Atspi.Role.LABEL, - } - DISPLAYED_TEXT_SKIP_NAME_ROLES: set[Atspi.Role] = { - Atspi.Role.COMBO_BOX, - Atspi.Role.SPIN_BUTTON, - } - DISPLAYED_TEXT_LABEL_FALLBACK_ROLES: set[Atspi.Role] = { - Atspi.Role.PUSH_BUTTON, - Atspi.Role.LIST_ITEM, - } - - flags: re.RegexFlag = re.UNICODE - WORDS_RE: re.Pattern[str] = re.compile(r"(\W+)", flags) - SUPERSCRIPTS_RE: re.Pattern[str] = re.compile(f"[{''.join(SUPERSCRIPT_DIGITS)}]+", flags) - SUBSCRIPTS_RE: re.Pattern[str] = re.compile(f"[{''.join(SUBSCRIPT_DIGITS)}]+", flags) - PUNCTUATION: re.Pattern[str] = re.compile(r"[^\w\s]", flags) - - # generatorCache - # - DISPLAYED_DESCRIPTION: str = 'displayedDescription' - DISPLAYED_LABEL: str = 'displayedLabel' - DISPLAYED_TEXT: str = 'displayedText' - KEY_BINDING: str = 'keyBinding' - NESTING_LEVEL: str = 'nestingLevel' - NODE_LEVEL: str = 'nodeLevel' - - def __init__(self, script: Script) -> None: - """Creates an instance of the Utilities class. - - Arguments: - - script: the script with which this instance is associated. - """ - - self._script: Script = script - self._clipboardHandlerId: Optional[int] = None - self._lastIndentationData: dict[Any, Any] = {} - self._selectedMenuBarMenu: dict[Any, Any] = {} - self._documentSelectionAdapter = AXDocumentSelection(self) - - ######################################################################### - # # - # Utilities for finding, identifying, and comparing accessibles # - # # - ######################################################################### - - def _isActiveAndShowingAndNotIconified(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_active(obj): - tokens = ["SCRIPT UTILITIES:", obj, "lacks state active"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if AXUtilities.is_iconified(obj): - tokens = ["SCRIPT UTILITIES:", obj, "has state iconified"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if not AXUtilities.is_showing(obj): - tokens = ["SCRIPT UTILITIES:", obj, "lacks state showing"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return True - - @staticmethod - def _getAppCommandLine(app: Optional[Atspi.Accessible]) -> str: - if not app: - return "" - - try: - pid = app.get_process_id() - except Exception: - tokens = ["SCRIPT UTILITIES: Exception getting process id of", app, ". May be defunct."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return "" - - try: - with open(f"/proc/{pid}/cmdline", "rb") as cmdline_file: - cmdline = cmdline_file.read().decode("utf-8", errors="replace") - except Exception: - return "" - - return cmdline.replace("\x00", " ") - - def canBeActiveWindow(self, window: Optional[Atspi.Accessible], clearCache: bool = False) -> bool: - if not window: - return False - - app = AXObject.get_application(window) - tokens = ["SCRIPT UTILITIES: Looking at", window, "from", app] - if debug.debugLevel <= debug.LEVEL_INFO: - tokens.append(self._getAppCommandLine(app)) - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if clearCache: - AXObject.clear_cache(window) - - if not self._isActiveAndShowingAndNotIconified(window): - tokens = ["SCRIPT UTILITIES:", window, "is not active and showing, or is iconified"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["SCRIPT UTILITIES:", window, "can be active window"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - def activeWindow(self, *apps: Atspi.Accessible) -> Optional[Atspi.Accessible]: - """Tries to locate the active window; may or may not succeed.""" - - candidates = [] - apps = apps or AXUtilities.get_all_applications(must_have_window=True) - for app in apps: - candidates.extend([c for c in AXObject.iter_children(app, self.canBeActiveWindow)]) - - if not candidates: - tokens = ["SCRIPT UTILITIES: Unable to find active window from", apps] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - if len(candidates) == 1: - tokens = ["SCRIPT UTILITIES: Active window is", candidates[0]] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return candidates[0] - - tokens = ["SCRIPT UTILITIES: These windows all claim to be active:", candidates] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - filtered = [] - for candidate in candidates: - if self.isDesktop(candidate): - tokens = ["SCRIPT UTILITIES: Rejecting", candidate, ": it's the desktop frame"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - elif AXObject.get_name(AXObject.get_application(candidate)) == "mutter-x11-frames": - tokens = ["SCRIPT UTILITIES: Rejecting", candidate, ": app is mutter-x11-frames"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - filtered.append(candidate) - - if len(filtered) == 1: - tokens = ["SCRIPT UTILITIES: Active window is believed to be", filtered[0]] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return filtered[0] - - # Some electron apps running in the background claim to be active even when they - # are not. Slack is one such example. We can add others as we go. - suspect_app_names = ["slack", - "discord", - "outline-client", - "whatsapp-desktop-linux"] - refiltered = [] - for frame in filtered: - if AXObject.get_name(AXObject.get_application(frame)) in suspect_app_names: - tokens = ["SCRIPT UTILITIES: Suspecting", frame, "is a non-active Electron app"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - refiltered.append(frame) - - if len(refiltered) == 1: - tokens = ["SCRIPT UTILITIES: Active window is believed to be", refiltered[0]] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return refiltered[0] - - guess = None - if refiltered: - tokens = ["SCRIPT UTILITIES: Still have multiple active windows:", refiltered] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - guess = refiltered[0] - - tokens = ["SCRIPT UTILITIES: Active window is:", guess] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return guess - - def objectAttributes(self, obj: Atspi.Accessible, useCache: bool = True) -> dict[str, str]: - return AXObject.get_attributes_dict(obj) - - def cellIndex(self, obj: Atspi.Accessible) -> int: - """Returns the index of the cell which should be used with the - table interface. This is necessary because in some apps we - cannot count on the index in parent being the index we need. - - Arguments: - -obj: the table cell whose index we need. - """ - - attrs = self.objectAttributes(obj) - index = attrs.get('table-cell-index') - if index: - return int(index) - - obj = AXObject.find_ancestor(obj, AXUtilities.is_table_cell_or_header) or obj - return AXObject.get_index_in_parent(obj) - - def childNodes(self, obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Gets all of the children that have RELATION_NODE_CHILD_OF pointing - to this expanded table cell. - - Arguments: - -obj: the Accessible Object - - Returns: a list of all the child nodes - """ - - parent = AXObject.get_parent(obj) - table = AXTable.get_table(parent) - if table is None: - return [] - - if not AXUtilities.is_expanded(obj): - return [] - - # First see if this accessible implements RELATION_NODE_PARENT_OF. - # If it does, the full target list are the nodes. If it doesn't - # we'll do an old-school, row-by-row search for child nodes. - def pred(x: Atspi.Accessible) -> bool: - return AXObject.get_index_in_parent(x) >= 0 - - nodes = [x for x in AXUtilitiesRelation.get_is_node_parent_of(obj) if pred(x)] - tokens = ["SCRIPT UTILITIES:", len(nodes), "child nodes for", obj, "via node-parent-of"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if nodes: - return nodes - - # Candidates will be in the rows beneath the current row. - # Only check in the current column and stop checking as - # soon as the node level of a candidate is equal or less - # than our current level. - # - row, col = self.coordinatesForCell(obj) - nodeLevel = self.nodeLevel(obj) - for i in range(row + 1, AXTable.get_row_count(table, prefer_attribute=False)): - cell = AXTable.get_cell_at(table, i, col) - if not cell: - continue - nodeOf = AXUtilitiesRelation.get_is_node_child_of(cell) - if not nodeOf: - continue - nodeOf = nodeOf[0] - if self.isSameObject(obj, nodeOf): - nodes.append(cell) - elif self.nodeLevel(nodeOf) <= nodeLevel: - break - - tokens = ["SCRIPT UTILITIES:", len(nodes), "child nodes for", obj, "via node-child-of"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return nodes - - def commonAncestor(self, a: Optional[Atspi.Accessible], b: Optional[Atspi.Accessible]) -> Optional[Atspi.Accessible]: - """Finds the common ancestor between Accessible a and Accessible b. - - Arguments: - - a: Accessible - - b: Accessible - """ - - tokens = ["SCRIPT UTILITIES: Looking for common ancestor of", a, "and", b] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # Don't do any Zombie checks here, as tempting and logical as it - # may seem as it can lead to chattiness. - if not (a and b): - return None - - if a == b: - return a - - aParents = [a] - parent = AXObject.get_parent_checked(a) - while parent: - aParents.append(parent) - parent = AXObject.get_parent_checked(parent) - aParents.reverse() - - bParents = [b] - parent = AXObject.get_parent_checked(b) - while parent: - bParents.append(parent) - parent = AXObject.get_parent_checked(parent) - bParents.reverse() - - commonAncestor = None - maxSearch = min(len(aParents), len(bParents)) - i = 0 - while i < maxSearch: - if self.isSameObject(aParents[i], bParents[i]): - commonAncestor = aParents[i] - i += 1 - else: - break - - tokens = ["SCRIPT UTILITIES: Common ancestor of", a, "and", b, "is", commonAncestor] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return commonAncestor - - def displayedLabel(self, obj: Atspi.Accessible) -> Optional[str]: - """If there is an object labelling the given object, return the - text being displayed for the object labelling this object. - Otherwise, return None. - - Argument: - - obj: the object in question - - Returns the string of the object labelling this object, or None - if there is nothing of interest here. - """ - - try: - return self._script.generatorCache[self.DISPLAYED_LABEL][obj] - except Exception: - if self.DISPLAYED_LABEL not in self._script.generatorCache: - self._script.generatorCache[self.DISPLAYED_LABEL] = {} - labelString = None - - labels = self.labelsForObject(obj) - for label in labels: - labelString = \ - self.appendString(labelString, self.displayedText(label)) - - self._script.generatorCache[self.DISPLAYED_LABEL][obj] = labelString - return self._script.generatorCache[self.DISPLAYED_LABEL][obj] - - def preferDescriptionOverName(self, obj: Atspi.Accessible) -> bool: - return False - - def descriptionsForObject(self, obj: Atspi.Accessible) -> list[Atspi.Accessible]: - """Return a list of objects describing obj.""" - - descriptions = AXUtilitiesRelation.get_is_described_by(obj) - if not descriptions: - return [] - - labels = AXUtilitiesRelation.get_is_labelled_by(obj) - if descriptions == labels: - tokens = ["SCRIPT UTILITIES:", obj, - "'s described-by targets are the same as labelled-by targets"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - return descriptions - - def detailsContentForObject(self, obj: Atspi.Accessible) -> list[str]: - details = self.detailsForObject(obj) - return list(map(self.displayedText, details)) - - def detailsForObject(self, obj: Atspi.Accessible, textOnly: bool = True) -> list[Atspi.Accessible]: - """Return a list of objects containing details for obj.""" - - details = AXUtilitiesRelation.get_details(obj) - if not details and AXUtilities.is_toggle_button(obj) \ - and AXUtilities.is_expanded(obj): - details = [child for child in AXObject.iter_children(obj)] - - if not textOnly: - return details - - textObjects = [] - for detail in details: - textObjects.extend(self.findAllDescendants(detail, self.queryNonEmptyText)) - - return textObjects - - def displayedDescription(self, obj: Atspi.Accessible) -> str: - """Returns the text being displayed for the object describing obj.""" - - try: - return self._script.generatorCache[self.DISPLAYED_DESCRIPTION][obj] - except Exception: - if self.DISPLAYED_DESCRIPTION not in self._script.generatorCache: - self._script.generatorCache[self.DISPLAYED_DESCRIPTION] = {} - - string = " ".join(map(self.displayedText, self.descriptionsForObject(obj))) - self._script.generatorCache[self.DISPLAYED_DESCRIPTION][obj] = string - return self._script.generatorCache[self.DISPLAYED_DESCRIPTION][obj] - - def displayedText(self, obj: Atspi.Accessible) -> Optional[str]: - """Returns the text being displayed for an object. - - Arguments: - - obj: the object - - Returns the text being displayed for an object or None if there isn't - any text being shown. - """ - - # NOTE: Legacy behavior; removal requires thorough testing. - - try: - return self._script.generatorCache[self.DISPLAYED_TEXT][obj] - except Exception: - displayedText = None - - name = AXObject.get_name(obj) - role = AXObject.get_role(obj) - - directText = self._getDisplayedTextDirectName(role, name) - if directText is not None: - return directText - - displayedText = self._getDisplayedTextFromText(obj) - if not displayedText: - displayedText = self._getDisplayedTextFallbackName(role, name) - if not displayedText: - displayedText = self._getDisplayedTextFromLabels(obj, role) - - if self.DISPLAYED_TEXT not in self._script.generatorCache: - self._script.generatorCache[self.DISPLAYED_TEXT] = {} - - self._script.generatorCache[self.DISPLAYED_TEXT][obj] = displayedText - return self._script.generatorCache[self.DISPLAYED_TEXT][obj] - - def _getDisplayedTextDirectName(self, role: Atspi.Role, name: str) -> Optional[str]: - if role in self.DISPLAYED_TEXT_DIRECT_NAME_ROLES and name: - return name - return None - - def _getDisplayedTextFromText(self, obj: Atspi.Accessible) -> Optional[str]: - if not AXObject.supports_text(obj): - return None - - displayedText = AXText.get_all_text(obj) - if self.EMBEDDED_OBJECT_CHARACTER in displayedText: - return None - - return displayedText - - def _getDisplayedTextFallbackName(self, role: Atspi.Role, name: str) -> Optional[str]: - # NOTE: Legacy fallback; removal requires thorough testing. - if name and role not in self.DISPLAYED_TEXT_SKIP_NAME_ROLES: - return name - - return None - - def _getDisplayedTextFromLabels(self, obj: Atspi.Accessible, role: Atspi.Role) -> Optional[str]: - if role not in self.DISPLAYED_TEXT_LABEL_FALLBACK_ROLES: - return None - - labels = self.unrelatedLabels(obj, minimumWords=1) - if not labels: - labels = self.unrelatedLabels(obj, onlyShowing=False, minimumWords=1) - return " ".join(map(self.displayedText, labels)) - - def documentFrame(self, obj: Optional[Atspi.Accessible] = None) -> Optional[Atspi.Accessible]: - """Returns the document frame which is displaying the content. - Note that this is intended primarily for web content.""" - - if not obj: - obj, offset = self.getCaretContext() - - document = AXObject.find_ancestor(obj, AXUtilities.is_document) - if not document and AXUtilities.is_document(cthulhu_state.locusOfFocus): - return cthulhu_state.locusOfFocus - - return document - - def documentFrameURI(self, documentFrame: Optional[Atspi.Accessible] = None) -> Optional[str]: - """Returns the URI of the document frame that is active.""" - - return None - - def frameAndDialog(self, obj: Optional[Atspi.Accessible]) -> list[Optional[Atspi.Accessible]]: - """Returns the frame and (possibly) the dialog containing obj.""" - - results = [None, None] - - obj = obj or cthulhu_state.locusOfFocus - if not obj: - msg = "SCRIPT UTILITIES: frameAndDialog() called without valid object" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return results - - topLevel = self.topLevelObject(obj) - if topLevel is None: - tokens = ["SCRIPT UTILITIES: could not find top-level object for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return results - - dialog_roles = [Atspi.Role.DIALOG, Atspi.Role.FILE_CHOOSER] - if self._treatAlertsAsDialogs(): - dialog_roles.append(Atspi.Role.ALERT) - - role = AXObject.get_role(topLevel) - if role in dialog_roles: - results[1] = topLevel - else: - if role in [Atspi.Role.FRAME, Atspi.Role.WINDOW]: - results[0] = topLevel - - def isDialog(x: Atspi.Accessible) -> bool: - return AXObject.get_role(x) in dialog_roles - - if isDialog(obj): - results[1] = obj - else: - results[1] = AXObject.find_ancestor(obj, isDialog) - - tokens = ["SCRIPT UTILITIES:", obj, "is in frame", results[0], "and dialog", results[1]] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return results - - def presentEventFromNonShowingObject(self, event: Any) -> bool: - if event.source == cthulhu_state.locusOfFocus: - return True - - return False - - def grabFocusBeforeRouting(self, obj: Atspi.Accessible) -> bool: - """Whether or not we should perform a grabFocus before routing - the cursor via the braille cursor routing keys. - - Arguments: - - obj: the accessible object where the cursor should be routed - - Returns True if we should do an explicit grabFocus on obj prior - to routing the cursor. - """ - - return AXUtilities.is_combo_box(obj) \ - and not self.isSameObject(obj, cthulhu_state.locusOfFocus) - - def hasMatchingHierarchy(self, obj: Atspi.Accessible, rolesList: list[Atspi.Role]) -> bool: - """Called to determine if the given object and it's hierarchy of - parent objects, each have the desired roles. Please note: You - should strongly consider an alternative means for determining - that a given object is the desired item. Failing that, you should - include only enough of the hierarchy to make the determination. - If the developer of the application you are providing access to - does so much as add an Adjustment to reposition a widget, this - method can fail. You have been warned. - - Arguments: - - obj: the accessible object to check. - - rolesList: the list of desired roles for the components and the - hierarchy of its parents. - - Returns True if all roles match. - """ - - current = obj - for role in rolesList: - if current is None: - return False - - if not isinstance(role, list): - role = [role] - - if isinstance(role[0], str): - current_role = AXObject.get_role_name(current) - else: - current_role = AXObject.get_role(current) - - if current_role not in role: - return False - - current = AXObject.get_parent_checked(current) - - return True - - def inFindContainer(self, obj: Optional[Atspi.Accessible] = None) -> bool: - if obj is None: - obj = cthulhu_state.locusOfFocus - - if not AXUtilities.is_entry(obj): - return False - - return AXObject.find_ancestor(obj, AXUtilities.is_tool_bar) is not None - - def getFindResultsCount(self, root: Optional[Atspi.Accessible] = None) -> str: - return "" - - def isAnchor(self, obj: Atspi.Accessible) -> bool: - return False - - def isCode(self, obj: Atspi.Accessible) -> bool: - return False - - def isCodeDescendant(self, obj: Atspi.Accessible) -> bool: - return False - - def isDockedFrame(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_frame(obj): - return False - - attrs = self.objectAttributes(obj) - return attrs.get('window-type') == 'dock' - - def isDesktop(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_frame(obj): - return False - - attrs = self.objectAttributes(obj) - return attrs.get('is-desktop') == 'true' - - def isComboBoxWithToggleDescendant(self, obj: Atspi.Accessible) -> bool: - return False - - def isToggleDescendantOfComboBox(self, obj: Atspi.Accessible) -> bool: - return False - - def isTypeahead(self, obj: Atspi.Accessible) -> bool: - return False - - def isOrDescendsFrom(self, obj: Atspi.Accessible, ancestor: Atspi.Accessible) -> bool: - if obj == ancestor: - return True - - return AXObject.find_ancestor(obj, lambda x: x and x == ancestor) - - def isFunctionalDialog(self, obj: Atspi.Accessible) -> bool: - """Returns True if the window is a functioning as a dialog. - This method should be subclassed by application scripts as - needed. - """ - - return False - - def isComment(self, obj: Atspi.Accessible) -> bool: - return False - - def isContentDeletion(self, obj: Atspi.Accessible) -> bool: - return False - - def isContentError(self, obj: Atspi.Accessible) -> bool: - return False - - def isContentInsertion(self, obj: Atspi.Accessible) -> bool: - return False - - def isContentMarked(self, obj: Atspi.Accessible) -> bool: - return False - - def isContentSuggestion(self, obj: Atspi.Accessible) -> bool: - return False - - def isInlineSuggestion(self, obj: Atspi.Accessible) -> bool: - return False - - def isFirstItemInInlineContentSuggestion(self, obj: Atspi.Accessible) -> bool: - return False - - def isLastItemInInlineContentSuggestion(self, obj: Atspi.Accessible) -> bool: - return False - - def isEmpty(self, obj: Atspi.Accessible) -> bool: - return False - - def isHidden(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPub(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubAbstract(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubAcknowledgments(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubAfterword(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubAppendix(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubBibliography(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubBacklink(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubBiblioref(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubChapter(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubColophon(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubConclusion(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubCover(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubCredit(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubCredits(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubDedication(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubEndnote(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubEndnotes(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubEpigraph(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubEpilogue(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubErrata(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubExample(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubFootnote(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubForeword(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubGlossary(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubGlossref(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubIndex(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubIntroduction(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubPagelist(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubPagebreak(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubPart(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubPreface(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubPrologue(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubPullquote(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubQna(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubSubtitle(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubToc(self, obj: Atspi.Accessible) -> bool: - return False - - def isFeed(self, obj: Atspi.Accessible) -> bool: - return False - - def isFeedArticle(self, obj: Atspi.Accessible) -> bool: - return False - - def isFigure(self, obj: Atspi.Accessible) -> bool: - return False - - def isGrid(self, obj: Atspi.Accessible) -> bool: - return False - - def isGridCell(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmark(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmarkWithoutType(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmarkBanner(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmarkComplementary(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmarkContentInfo(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmarkForm(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmarkMain(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmarkNavigation(self, obj: Atspi.Accessible) -> bool: - return False - - def isDPubNoteref(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmarkRegion(self, obj: Atspi.Accessible) -> bool: - return False - - def isLandmarkSearch(self, obj: Atspi.Accessible) -> bool: - return False - - def isSVG(self, obj: Atspi.Accessible) -> bool: - return False - - def speakMathSymbolNames(self, obj: Optional[Atspi.Accessible] = None) -> bool: - return False - - def isInMath(self) -> bool: - return False - - def isMath(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathLayoutOnly(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathMultiline(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathEnclosed(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathFenced(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathFractionWithoutBar(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathPhantom(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathMultiScript(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathSubOrSuperScript(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathUnderOrOverScript(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathSquareRoot(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathTable(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathTableRow(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathTableCell(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathToken(self, obj: Atspi.Accessible) -> bool: - return False - - def isMathTopLevel(self, obj: Atspi.Accessible) -> bool: - return False - - def getMathDenominator(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - return None - - def getMathNumerator(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - return None - - def getMathRootBase(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - return None - - def getMathRootIndex(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - return None - - def getMathScriptBase(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - return None - - def getMathScriptSubscript(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - return None - - def getMathScriptSuperscript(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - return None - - def getMathScriptUnderscript(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - return None - - def getMathScriptOverscript(self, obj: Atspi.Accessible) -> Optional[Atspi.Accessible]: - return None - - def getMathPrescripts(self, obj: Atspi.Accessible) -> list[Atspi.Accessible]: - return [] - - def getMathPostscripts(self, obj: Atspi.Accessible) -> list[Atspi.Accessible]: - return [] - - def getMathEnclosures(self, obj: Atspi.Accessible) -> list[str]: - return [] - - def getMathFencedSeparators(self, obj: Atspi.Accessible) -> list[str]: - return [''] - - def getMathFences(self, obj: Atspi.Accessible) -> list[str]: - return ['', ''] - - def getMathNestingLevel(self, obj: Atspi.Accessible, test: Optional[Callable[[Atspi.Accessible], bool]] = None) -> int: - return 0 - - def getLandmarkTypes(self) -> list[str]: - return ["banner", - "complementary", - "contentinfo", - "doc-acknowledgments", - "doc-afterword", - "doc-appendix", - "doc-bibliography", - "doc-chapter", - "doc-conclusion", - "doc-credits", - "doc-endnotes", - "doc-epilogue", - "doc-errata", - "doc-foreword", - "doc-glossary", - "doc-index", - "doc-introduction", - "doc-pagelist", - "doc-part", - "doc-preface", - "doc-prologue", - "doc-toc", - "form", - "main", - "navigation", - "region", - "search"] - - def isProgressBar(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_progress_bar(obj): - return False - - if not AXObject.supports_value(obj): - tokens = ["SCRIPT UTILITIES:", obj, "doesn't implement AtspiValue"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - min_value = AXValue.get_minimum_value(obj) - max_value = AXValue.get_maximum_value(obj) - if max_value == min_value: - tokens = ["SCRIPT UTILITIES:", obj, "is busy indicator"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return True - - def isProgressBarUpdate(self, obj: Atspi.Accessible) -> bool: - if not cthulhu.cthulhuApp.settingsManager.getSetting('speakProgressBarUpdates') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('brailleProgressBarUpdates') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('beepProgressBarUpdates'): - return False, "Updates not enabled" - - if not self.isProgressBar(obj): - return False, "Is not progress bar" - - if self.hasNoSize(obj): - return False, "Has no size" - - if cthulhu.cthulhuApp.settingsManager.getSetting('ignoreStatusBarProgressBars'): - if AXObject.find_ancestor(obj, AXUtilities.is_status_bar): - return False, "Is status bar descendant" - - verbosity = cthulhu.cthulhuApp.settingsManager.getSetting('progressBarVerbosity') - if verbosity == settings.PROGRESS_BAR_ALL: - return True, "Verbosity is all" - - if verbosity == settings.PROGRESS_BAR_WINDOW: - topLevel = self.topLevelObject(obj) - if topLevel == cthulhu_state.activeWindow: - return True, "Verbosity is window" - return False, f"Window {topLevel} is not {cthulhu_state.activeWindow}" - - if verbosity == settings.PROGRESS_BAR_APPLICATION: - app = AXObject.get_application(obj) - if app == cthulhu_state.activeScript.app: - return True, "Verbosity is app" - return False, f"App {app} is not {cthulhu_state.activeScript.app}" - - return True, "Not handled by any other case" - - def getValueAsPercent(self, obj: Atspi.Accessible) -> Optional[Any]: - if not AXObject.supports_value(obj): - tokens = ["SCRIPT UTILITIES:", obj, "doesn't implement AtspiValue"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - val = AXValue.get_current_value(obj) - minval = AXValue.get_minimum_value(obj) - maxval = AXValue.get_maximum_value(obj) - - if AXUtilities.is_indeterminate(obj): - tokens = ["SCRIPT UTILITIES:", obj, "has state indeterminate and value of", val] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if val <= 0: - return None - - if maxval == minval == val: - if 1 <= val <= 100: - return int(val) - return None - - return int((val / (maxval - minval)) * 100) - - def isBlockquote(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_block_quote(obj) - - def isDescriptionList(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_description_list(obj) - - def isDescriptionListTerm(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_description_term(obj) - - def isDescriptionListDescription(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_description_value(obj) - - def descriptionListTerms(self, obj: Atspi.Accessible) -> list[Any]: - if not self.isDescriptionList(obj): - return [] - - _include = self.isDescriptionListTerm - _exclude = self.isDescriptionList - return self.findAllDescendants(obj, _include, _exclude) - - def isDocumentList(self, obj: Atspi.Accessible) -> bool: - if AXObject.get_role(obj) not in [Atspi.Role.LIST, Atspi.Role.DESCRIPTION_LIST]: - return False - return AXObject.find_ancestor(obj, AXUtilities.is_document) is not None - - def isDocumentPanel(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_panel(obj): - return False - return AXObject.find_ancestor(obj, AXUtilities.is_document) is not None - - def isDocument(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_document(obj) - - def inDocumentContent(self, obj: Optional[Atspi.Accessible] = None) -> Optional[Atspi.Accessible]: - obj = obj or cthulhu_state.locusOfFocus - return self.getDocumentForObject(obj) is not None - - def activeDocument(self, window: Optional[Atspi.Accessible] = None) -> Optional[Atspi.Accessible]: - return self.getTopLevelDocumentForObject(cthulhu_state.locusOfFocus) - - def isTopLevelDocument(self, obj: Atspi.Accessible) -> bool: - return self.isDocument(obj) and not AXObject.find_ancestor(obj, self.isDocument) - - def getTopLevelDocumentForObject(self, obj: Atspi.Accessible) -> Any: - if self.isTopLevelDocument(obj): - return obj - - return AXObject.find_ancestor(obj, self.isTopLevelDocument) - - def getDocumentForObject(self, obj: Atspi.Accessible) -> Optional[Any]: - if not obj: - return None - - if self.isDocument(obj): - return obj - - return AXObject.find_ancestor(obj, self.isDocument) - - def getModalDialog(self, obj: Atspi.Accessible) -> bool: - if not obj: - return False - - if AXUtilities.is_modal_dialog(obj): - return obj - - return AXObject.find_ancestor(obj, AXUtilities.is_modal_dialog) - - def isModalDialogDescendant(self, obj: Atspi.Accessible) -> bool: - if not obj: - return False - - return self.getModalDialog(obj) is not None - - def getTable(self, obj: Atspi.Accessible) -> Optional[Any]: - if not obj: - return None - - def isTable(x: Atspi.Accessible) -> bool: - if AXUtilities.is_table(x) or AXUtilities.is_tree_table(x) or AXUtilities.is_tree(x): - return AXObject.supports_table(x) - return False - - if isTable(obj): - return obj - - return AXObject.find_ancestor(obj, isTable) - - def isTextDocumentTable(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_table(obj): - return False - - doc = self.getDocumentForObject(obj) - return doc is not None and not AXUtilities.is_document_spreadsheet(doc) - - def isGUITable(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_table(obj) and self.getDocumentForObject(obj) is None - - def isSpreadSheetTable(self, obj: Atspi.Accessible) -> bool: - if not (AXUtilities.is_table(obj) and AXObject.supports_table(obj)): - return False - - doc = self.getDocumentForObject(obj) - if doc is None: - return False - if AXUtilities.is_document_spreadsheet(doc): - return True - - return AXTable.get_row_count(obj, prefer_attribute=False) > 65536 - - def isTextDocumentCell(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_table_cell_or_header(obj): - return False - return AXObject.find_ancestor(obj, self.isTextDocumentTable) - - def isSpreadSheetCell(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_table_cell_or_header(obj): - return False - return AXObject.find_ancestor(obj, self.isSpreadSheetTable) - - def cellColumnChanged(self, cell: Any) -> bool: - row, column = self.coordinatesForCell(cell) - if column == -1: - return False - - lastColumn = self._script.pointOfReference.get("lastColumn") - return column != lastColumn - - def cellRowChanged(self, cell: Any) -> bool: - row, column = self.coordinatesForCell(cell) - if row == -1: - return False - - lastRow = self._script.pointOfReference.get("lastRow") - return row != lastRow - - def shouldReadFullRow(self, obj: Atspi.Accessible) -> bool: - if self._script.inSayAll(): - return False - - if not self.cellRowChanged(obj): - return False - - table = self.getTable(obj) - if not table: - return False - - if not self.getDocumentForObject(table): - return cthulhu.cthulhuApp.settingsManager.getSetting('readFullRowInGUITable') - - if self.isSpreadSheetTable(table): - return cthulhu.cthulhuApp.settingsManager.getSetting('readFullRowInSpreadSheet') - - return cthulhu.cthulhuApp.settingsManager.getSetting('readFullRowInDocumentTable') - - def isSorted(self, obj: Atspi.Accessible) -> bool: - return False - - def isAscending(self, obj: Atspi.Accessible) -> bool: - return False - - def isDescending(self, obj: Atspi.Accessible) -> bool: - return False - - def getSortOrderDescription(self, obj: Atspi.Accessible, includeName: Any = False) -> str: - if not (obj and self.isSorted(obj)): - return "" - - if self.isAscending(obj): - result = object_properties.SORT_ORDER_ASCENDING - elif self.isDescending(obj): - result = object_properties.SORT_ORDER_DESCENDING - else: - result = object_properties.SORT_ORDER_OTHER - - if includeName and AXObject.get_name(obj): - result = f"{AXObject.get_name(obj)}. {result}" - - return result - - def isFocusableLabel(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_label(obj) and AXUtilities.is_focusable(obj) - - def isNonFocusableList(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_list(obj) and not AXUtilities.is_focusable(obj) - - def isStatusBarNotification(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_notification(obj): - return False - return AXObject.find_ancestor(obj, AXUtilities.is_status_bar) is not None - - def getNotificationContent(self, obj: Atspi.Accessible) -> str: - if not AXUtilities.is_notification(obj): - return "" - - tokens = [] - name = AXObject.get_name(obj) - if name: - tokens.append(name) - text = self.expandEOCs(obj) - if text and text not in tokens: - tokens.append(text) - else: - labels = " ".join(map(self.displayedText, self.unrelatedLabels(obj, False, 1))) - if labels and labels not in tokens: - tokens.append(labels) - - if not tokens: - description = AXObject.get_description(obj) - if description: - tokens.append(description) - - return " ".join(tokens) - - def isTreeDescendant(self, obj: Atspi.Accessible) -> bool: - if obj is None: - return False - - if AXUtilities.is_tree_item(obj): - return True - - return AXObject.find_ancestor(obj, AXUtilities.is_tree_or_tree_table) is not None - - def isLayoutOnly(self, obj: Atspi.Accessible) -> bool: - """Returns True if the given object is a container which has - no presentable information (label, name, displayed text, etc.).""" - - layoutOnly = False - - if AXObject.is_dead(obj) or self.isZombie(obj): - return True - - attrs = self.objectAttributes(obj) - role = AXObject.get_role(obj) - parentRole = AXObject.get_role(AXObject.get_parent(obj)) - firstChild = AXObject.get_child(obj, 0) - - topLevelRoles = self._topLevelRoles() - ignorePanelParent = [Atspi.Role.MENU, - Atspi.Role.MENU_ITEM, - Atspi.Role.LIST_ITEM, - Atspi.Role.TREE_ITEM] - - if role == Atspi.Role.TABLE and attrs.get('layout-guess') != 'true': - if not AXObject.supports_table(obj): - tokens = ["SCRIPT UTILITIES: Table", obj, "does not implement table interface"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - layoutOnly = True - else: - rows = AXTable.get_row_count(obj, prefer_attribute=False) - cols = AXTable.get_column_count(obj, prefer_attribute=False) - if not (rows and cols): - layoutOnly = not AXUtilities.is_focused(obj) - elif attrs.get('xml-roles') == 'table' or attrs.get('tag') == 'table': - layoutOnly = False - elif not (AXObject.get_name(obj) or self.displayedLabel(obj)): - layoutOnly = not (AXTable.has_column_headers(obj) or AXTable.has_row_headers(obj)) - elif role == Atspi.Role.TABLE_CELL and AXObject.get_child_count(obj): - if parentRole == Atspi.Role.TREE_TABLE: - layoutOnly = not AXObject.get_name(obj) - elif AXUtilities.is_table_cell(firstChild): - layoutOnly = True - elif parentRole == Atspi.Role.TABLE: - layoutOnly = self.isLayoutOnly(AXObject.get_parent(obj)) - elif role == Atspi.Role.SECTION: - layoutOnly = not self.isBlockquote(obj) - elif role == Atspi.Role.BLOCK_QUOTE: - layoutOnly = False - elif role == Atspi.Role.FILLER: - layoutOnly = True - elif role == Atspi.Role.SCROLL_PANE: - layoutOnly = True - elif role == Atspi.Role.LAYERED_PANE: - layoutOnly = self.isDesktop(self.topLevelObject(obj)) - elif role == Atspi.Role.AUTOCOMPLETE: - layoutOnly = True - elif role in [Atspi.Role.TEAROFF_MENU_ITEM, Atspi.Role.SEPARATOR]: - layoutOnly = True - elif role in [Atspi.Role.LIST_BOX, Atspi.Role.TREE_TABLE]: - layoutOnly = False - elif role in topLevelRoles: - layoutOnly = False - elif role == Atspi.Role.MENU: - layoutOnly = parentRole == Atspi.Role.COMBO_BOX - elif role == Atspi.Role.COMBO_BOX: - layoutOnly = False - elif role == Atspi.Role.LIST: - layoutOnly = False - elif role == Atspi.Role.FORM: - layoutOnly = False - elif role in [Atspi.Role.PUSH_BUTTON, Atspi.Role.TOGGLE_BUTTON]: - layoutOnly = False - elif role in [Atspi.Role.TEXT, Atspi.Role.PASSWORD_TEXT, Atspi.Role.ENTRY]: - layoutOnly = False - elif role == Atspi.Role.LIST_ITEM and parentRole == Atspi.Role.LIST_BOX: - layoutOnly = False - elif role in [Atspi.Role.REDUNDANT_OBJECT, Atspi.Role.UNKNOWN]: - layoutOnly = True - elif self.isTableRow(obj): - layoutOnly = not (AXUtilities.is_focusable(obj) or AXUtilities.is_selectable(obj)) - elif role == Atspi.Role.PANEL and AXObject.get_role(firstChild) in ignorePanelParent: - layoutOnly = True - elif role == Atspi.Role.PANEL \ - and AXObject.has_same_non_empty_name(obj, AXObject.get_application(obj)): - layoutOnly = True - elif AXObject.get_child_count(obj) == 1 \ - and AXObject.has_same_non_empty_name(obj, firstChild): - layoutOnly = True - elif self.isHidden(obj): - layoutOnly = True - else: - if not (self.displayedText(obj) or self.displayedLabel(obj)): - layoutOnly = True - - if layoutOnly: - tokens = ["SCRIPT UTILITIES:", obj, "is deemed to be layout only"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return layoutOnly - - def isInActiveApp(self, obj: Atspi.Accessible) -> bool: - """Returns True if the given object is from the same application that - currently has keyboard focus. - - Arguments: - - obj: an Accessible object - """ - - if not obj or not cthulhu_state.locusOfFocus: - return False - - return AXObject.get_application(cthulhu_state.locusOfFocus) == AXObject.get_application(obj) - - def isLink(self, obj: Atspi.Accessible) -> bool: - """Returns True if obj is a link.""" - - return AXUtilities.is_link(obj) - - def isReadOnlyTextArea(self, obj: Atspi.Accessible) -> bool: - """Returns True if obj is a text entry area that is read only.""" - - if not self.isTextArea(obj): - return False - - if AXUtilities.is_read_only(obj): - return True - - return AXUtilities.is_focusable(obj) and not AXUtilities.is_editable(obj) - - def isSwitch(self, obj: Atspi.Accessible) -> bool: - return False - - def get_objectFromPath(self, path: int) -> Any: - start = self._script.app - rv = None - for p in path: - if p == -1: - continue - try: - start = start[p] - except Exception: - break - else: - rv = start - - return rv - - def _hasSamePath(self, obj1: Any, obj2: Any) -> bool: - path1 = AXObject.get_path(obj1) - path2 = AXObject.get_path(obj2) - if len(path1) != len(path2): - return False - - if not (path1 and path2): - return False - - # The first item in all paths, even valid ones, is -1. - path1 = path1[1:] - path2 = path2[1:] - - # If the object is being destroyed and the replacement is too, which - # sadly can happen in at least Firefox, both will have an index of -1. - # If the rest of the paths are valid and match, it's probably ok. - if path1[-1] == -1 and path2[-1] == -1: - path1 = path1[:-1] - path2 = path2[:-1] - - # If both have invalid child indices, all bets are off. - if path1.count(-1) and path2.count(-1): - return False - - try: - index = path1.index(-1) - except ValueError: - try: - index = path2.index(-1) - except ValueError: - index = len(path2) - - return path1[0:index] == path2[0:index] - - def isSameObject(self, obj1: Optional[Atspi.Accessible], obj2: Optional[Atspi.Accessible], - comparePaths: bool = False, ignoreNames: bool = False, - ignoreDescriptions: bool = True) -> bool: - if obj1 == obj2: - return True - - if obj1 is None or obj2 is None: - return False - - if not AXUtilities.have_same_role(obj1, obj2): - return False - - if not ignoreNames and AXObject.get_name(obj1) != AXObject.get_name(obj2): - return False - - if not ignoreDescriptions \ - and AXObject.get_description(obj1) != AXObject.get_description(obj2): - return False - - if comparePaths and self._hasSamePath(obj1, obj2): - return True - - try: - # Comparing the extents of objects which claim to be different - # addresses both managed descendants and implementations which - # recreate accessibles for the same widget. - if not AXObject.supports_component(obj1) or not AXObject.supports_component(obj2): - return False - extents1 = Atspi.Component.get_extents(obj1, Atspi.CoordType.WINDOW) - extents2 = Atspi.Component.get_extents(obj2, Atspi.CoordType.WINDOW) - - # Objects which claim to be different and which are in different - # locations are almost certainly not recreated objects. - if extents1 != extents2: - return False - - # Objects which claim to have the same role, the same name, and - # the same size and position are highly likely to be the same - # functional object -- if they have valid, on-screen extents. - if extents1.x >= 0 and extents1.y >= 0 and extents1.width > 0 \ - and extents1.height > 0: - return True - except Exception as error: - tokens = ["SCRIPT UTILITIES: Exception in isSameObject (", - obj1, "vs", obj2, "):", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return False - - def isTextArea(self, obj: Atspi.Accessible) -> bool: - """Returns True if obj is a GUI component that is for entering text. - - Arguments: - - obj: an accessible - """ - - if self.isLink(obj): - return False - - return self._isTextAreaByType(obj) - - def _isTextAreaByType(self, obj: Atspi.Accessible) -> Any: - # NOTE: This is legacy and may need more checks now. - return AXUtilities.is_text_input(obj) \ - or AXUtilities.is_text(obj) \ - or AXUtilities.is_paragraph(obj) - - def labelsForObject(self, obj: Atspi.Accessible) -> Any: - """Return a list of the labels for this object.""" - - def isNotAncestor(acc: Atspi.Accessible) -> bool: - return not AXObject.find_ancestor(obj, lambda x: x == acc) - - result = AXUtilitiesRelation.get_is_labelled_by(obj) - return list(filter(isNotAncestor, result)) - - def linkBasenameToName(self, obj: Atspi.Accessible) -> str: - basename = self.linkBasename(obj) - if not basename: - return "" - - basename = re.sub(r"[-_]", " ", basename) - tokens = basename.split() - for token in tokens: - if not token.isalpha(): - return "" - - return basename - - def linkBasename(self, obj: Atspi.Accessible) -> Any: - """Returns the relevant information from the URI. The idea is - to attempt to strip off all prefix and suffix, much like the - basename command in a shell.""" - - basename = None - uri = AXHypertext.get_link_uri(obj) - if uri and len(uri): - # Sometimes the URI is an expression that includes a URL. - # Currently that can be found at the bottom of safeway.com. - # It can also be seen in the backwards.html test file. - # - expression = uri.split(',') - if len(expression) > 1: - for item in expression: - if item.find('://') >=0: - if not item[0].isalnum(): - item = item[1:-1] - if not item[-1].isalnum(): - item = item[0:-2] - uri = item - break - - # We're assuming that there IS a base name to be had. - # What if there's not? See backwards.html. - # - uri = uri.split('://')[-1] - if not uri: - return basename - - # Get the last thing after all the /'s, unless it ends - # in a /. If it ends in a /, we'll look to the stuff - # before the ending /. - # - if uri[-1] == "/": - basename = uri[0:-1] - basename = basename.split('/')[-1] - elif not uri.count("/"): - basename = uri - else: - basename = uri.split('/')[-1] - if basename.startswith("index"): - basename = uri.split('/')[-2] - - # Now, try to strip off the suffixes. - # - basename = basename.split('.')[0] - basename = basename.split('?')[0] - basename = basename.split('#')[0] - basename = basename.split('%')[0] - - return basename - - def linkIndex(self, obj: Atspi.Accessible, characterIndex: int) -> int: - """A brute force method to see if an offset is a link. This - is provided because not all Accessible Hypertext implementations - properly support the getLinkIndex method. Returns an index of - 0 or greater of the characterIndex is on a hyperlink. - - Arguments: - -obj: the object with the Accessible Hypertext specialization - -characterIndex: the text position to check - """ - - if not obj: - return -1 - - if not AXObject.supports_text(obj): - return -1 - - if not AXObject.supports_hypertext(obj): - return -1 - - for i, link in enumerate(AXHypertext.get_all_links(obj)): - start = AXHypertext.get_link_start_offset(link) - end = AXHypertext.get_link_end_offset(link) - if (characterIndex >= start) and (characterIndex <= end): - return i - - return -1 - - def nestingLevel(self, obj: Atspi.Accessible) -> int: - """Determines the nesting level of this object. - - Arguments: - -obj: the Accessible object - """ - - if obj is None: - return 0 - - try: - return self._script.generatorCache[self.NESTING_LEVEL][obj] - except Exception: - if self.NESTING_LEVEL not in self._script.generatorCache: - self._script.generatorCache[self.NESTING_LEVEL] = {} - - def pred(x: Atspi.Accessible) -> bool: - if self.isBlockquote(obj): - return self.isBlockquote(x) - if AXUtilities.is_list_item(obj): - return AXUtilities.is_list(AXObject.get_parent(x)) - return AXUtilities.have_same_role(obj, x) - - ancestors = [] - ancestor = AXObject.find_ancestor(obj, pred) - while ancestor: - ancestors.append(ancestor) - ancestor = AXObject.find_ancestor(ancestor, pred) - - nestingLevel = len(ancestors) - self._script.generatorCache[self.NESTING_LEVEL][obj] = nestingLevel - return self._script.generatorCache[self.NESTING_LEVEL][obj] - - def nodeLevel(self, obj: Atspi.Accessible) -> int: - """Determines the node level of this object if it is in a tree - relation, with 0 being the top level node. If this object is - not in a tree relation, then -1 will be returned. - - Arguments: - -obj: the Accessible object - """ - - if not self.isTreeDescendant(obj): - return -1 - - try: - return self._script.generatorCache[self.NODE_LEVEL][obj] - except Exception: - if self.NODE_LEVEL not in self._script.generatorCache: - self._script.generatorCache[self.NODE_LEVEL] = {} - - nodes = [] - node = obj - done = False - while not done: - nodeOf = AXUtilitiesRelation.get_is_node_child_of(node) - node = nodeOf[0] if nodeOf else None - - # We want to avoid situations where something gives us an - # infinite cycle of nodes. Bon Echo has been seen to do - # this (see bug 351847). - if nodes.count(node): - tokens = ["SCRIPT UTILITIES:", node, "is already in the list of nodes for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - done = True - if len(nodes) > 100: - tokens = ["SCRIPT UTILITIES: More than 100 nodes found for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - done = True - elif node: - nodes.append(node) - else: - done = True - - self._script.generatorCache[self.NODE_LEVEL][obj] = len(nodes) - 1 - return self._script.generatorCache[self.NODE_LEVEL][obj] - - def isOnScreen(self, obj: Atspi.Accessible, boundingbox: Any = None) -> bool: - if AXObject.is_dead(obj): - return False - - if self.isHidden(obj): - return False - - if not self.isShowingAndVisible(obj): - tokens = ["SCRIPT UTILITIES:", obj, "is not showing and visible"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if not AXObject.supports_component(obj): - tokens = ["SCRIPT UTILITIES:", obj, "does not support component interface"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - try: - box = Atspi.Component.get_extents(obj, Atspi.CoordType.SCREEN) - except Exception: - tokens = ["SCRIPT UTILITIES: Exception getting extents for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["SCRIPT UTILITIES: Extents for", obj, "are:", box] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - boxTuple = self._extentsToTuple(box) - x, y, width, height = boxTuple - - if x > 10000 or y > 10000: - tokens = ["SCRIPT UTILITIES:", obj, "seems to have bogus coordinates"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if x < 0 and y < 0 and boxTuple != (-1, -1, -1, -1): - tokens = ["SCRIPT UTILITIES:", obj, "has negative coordinates"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if not (width or height): - if not AXObject.get_child_count(obj): - tokens = ["SCRIPT UTILITIES:", obj, "has no size and no children"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - if AXUtilities.is_menu(obj): - tokens = ["SCRIPT UTILITIES:", obj, "has no size"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return True - - if boundingbox is None or not self._boundsIncludeChildren(AXObject.get_parent(obj)): - return True - - boundingbox = self._extentsToTuple(boundingbox) - if not self.containsRegion(boxTuple, boundingbox) and boxTuple != (-1, -1, -1, -1): - tokens = ["SCRIPT UTILITIES:", obj, box, "not in", boundingbox] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return True - - def selectedMenuBarMenu(self, menubar: Any) -> Optional[Any]: - if not AXUtilities.is_menu_bar(menubar): - return None - - if AXObject.supports_selection(menubar): - selected = self.selectedChildren(menubar) - if selected: - return selected[0] - return None - - for menu in AXObject.iter_children(menubar): - AXObject.clear_cache(menu) - if AXUtilities.is_expanded(menu) or AXUtilities.is_selected(menu): - return menu - - return - - def isInOpenMenuBarMenu(self, obj: Atspi.Accessible) -> bool: - if obj is None: - return False - - menubar = AXObject.find_ancestor(obj, AXUtilities.is_menu_bar) - if menubar is None: - return False - - selectedMenu = self._selectedMenuBarMenu.get(hash(menubar)) - if selectedMenu is None: - selectedMenu = self.selectedMenuBarMenu(menubar) - - if selectedMenu is None: - return False - - def inSelectedMenu(x: Atspi.Accessible) -> bool: - return x == selectedMenu - - if inSelectedMenu(obj): - return True - - return AXObject.find_ancestor(obj, inSelectedMenu) is not None - - def isStaticTextLeaf(self, obj: Atspi.Accessible) -> bool: - return False - - def isListItemMarker(self, obj: Atspi.Accessible) -> bool: - return False - - def hasPresentableText(self, obj: Atspi.Accessible) -> bool: - if self.isStaticTextLeaf(obj): - return False - - if not AXObject.supports_text(obj): - return False - - return bool(re.search(r"\w+", AXText.get_all_text(obj))) - - def getOnScreenObjects(self, root: Any, extents: Any = None) -> list[Any]: - if not self.isOnScreen(root, extents): - return [] - - if AXObject.get_role(root) == Atspi.Role.INVALID: - return [] - - if AXUtilities.is_button(root) or AXUtilities.is_combo_box(root): - return [root] - - if AXUtilities.is_menu_bar(root): - self._selectedMenuBarMenu[hash(root)] = self.selectedMenuBarMenu(root) - - if AXUtilities.is_menu_bar(AXObject.get_parent(root)) \ - and not self.isInOpenMenuBarMenu(root): - return [root] - - if AXUtilities.is_filler(root) and not AXObject.get_child_count(root): - tokens = ["SCRIPT UTILITIES:", root, "is empty filler. Clearing cache."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - AXObject.clear_cache(root, recursive=True) - tokens = ["SCRIPT UTILITIES:", root, "now reports", - AXObject.get_child_count(root), "children"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if extents is None: - if AXObject.supports_component(root): - try: - extents = Atspi.Component.get_extents(root, Atspi.CoordType.SCREEN) - except Exception: - tokens = ["SCRIPT UTILITIES: Exception getting extents of", root] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - extents = Atspi.Rect() - else: - extents = Atspi.Rect() - - if AXObject.supports_table(root) and AXObject.supports_selection(root): - visibleCells = self.getVisibleTableCells(root) - if visibleCells: - return visibleCells - - objects = [] - hasNameOrDesc = AXObject.get_name(root) or AXObject.get_description(root) - if hasNameOrDesc and (AXUtilities.is_page_tab(root) or AXUtilities.is_image(root)): - objects.append(root) - elif self.hasPresentableText(root): - objects.append(root) - - def pred(x: Atspi.Accessible) -> bool: - return x is not None and not self.isStaticTextLeaf(x) - - for child in AXObject.iter_children(root, pred): - objects.extend(self.getOnScreenObjects(child, extents)) - - if AXUtilities.is_menu_bar(root): - self._selectedMenuBarMenu[hash(root)] = None - - if objects: - return objects - - if AXUtilities.is_label(root) and not hasNameOrDesc and not self.queryNonEmptyText(root): - return [] - - containers = [Atspi.Role.CANVAS, - Atspi.Role.FILLER, - Atspi.Role.IMAGE, - Atspi.Role.LINK, - Atspi.Role.LIST_BOX, - Atspi.Role.PANEL, - Atspi.Role.SECTION, - Atspi.Role.SCROLL_PANE, - Atspi.Role.VIEWPORT] - if AXObject.get_role(root) in containers and not hasNameOrDesc: - return [] - - return [root] - - def isTableRow(self, obj: Atspi.Accessible) -> bool: - """Determines if obj is a table row -- real or functionally.""" - - childCount = AXObject.get_child_count(obj) - if not childCount: - return False - - if AXObject.get_parent(obj) is None: - return False - - if AXUtilities.is_table_row(obj): - return True - - if AXUtilities.is_table_cell_or_header(obj): - return False - - if not AXUtilities.is_table(AXObject.get_parent(obj)): - return False - - cells = [x for x in AXObject.iter_children(obj, AXUtilities.is_table_cell_or_header)] - if len(cells) == childCount: - return True - - return False - - def realActiveAncestor(self, obj: Atspi.Accessible) -> Any: - if AXUtilities.is_focused(obj): - return obj - - def pred(x: Atspi.Accessible) -> bool: - return AXUtilities.is_table_cell_or_header(x) or AXUtilities.is_list_item(x) - - ancestor = AXObject.find_ancestor(obj, pred) - if ancestor is not None \ - and not self._script.utilities.isLayoutOnly(AXObject.get_parent(ancestor)): - obj = ancestor - - return obj - - def realActiveDescendant(self, obj: Atspi.Accessible) -> Optional[Any]: - """Given an object that should be a child of an object that - manages its descendants, return the child that is the real - active descendant carrying useful information. - - Arguments: - - obj: an object that should be a child of an object that - manages its descendants. - """ - - if AXObject.is_dead(obj): - return None - - if not AXUtilities.is_table_cell(obj): - return obj - - if AXObject.get_name(obj): - return obj - - def pred(x: Atspi.Accessible) -> bool: - return AXObject.get_name(x) or AXText.get_all_text(x) - - child = AXObject.find_descendant(obj, pred) - if child is not None: - return child - - return obj - - def isStatusBarDescendant(self, obj: Atspi.Accessible) -> bool: - if obj is None: - return False - - return AXObject.find_ancestor(obj, AXUtilities.is_status_bar) is not None - - def statusBarItems(self, obj: Atspi.Accessible) -> list[Any]: - if not AXUtilities.is_status_bar(obj): - return [] - - start = time.time() - items = self._script.pointOfReference.get('statusBarItems') - if not items: - - def include(x: Atspi.Accessible) -> bool: - return not AXUtilities.is_status_bar(x) - - items = list(filter(include, self.getOnScreenObjects(obj))) - self._script.pointOfReference['statusBarItems'] = items - - end = time.time() - msg = f"SCRIPT UTILITIES: Time getting status bar items: {end - start:.4f}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - return items - - def infoBar(self, root: Any) -> Optional[Any]: - return None - - def _topLevelRoles(self) -> Any: - roles = [Atspi.Role.DIALOG, - Atspi.Role.FILE_CHOOSER, - Atspi.Role.FRAME, - Atspi.Role.WINDOW] - if self._treatAlertsAsDialogs(): - roles.append(Atspi.Role.ALERT) - return roles - - def _locusOfFocusIsTopLevelObject(self) -> bool: - if not cthulhu_state.locusOfFocus: - return False - - rv = cthulhu_state.locusOfFocus == self.topLevelObject(cthulhu_state.locusOfFocus) - tokens = ["SCRIPT UTILITIES:", cthulhu_state.locusOfFocus, "is top-level object:", rv] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - def _findWindowWithDescendant(self, child: Any) -> Optional[Any]: - """Searches each frame/window/dialog of an application to find the one - which contains child. This is extremely non-performant and should only - be used to work around broken accessibility trees where topLevelObject - fails.""" - - app = AXObject.get_application(child) - if app is None: - return None - - for i in range(AXObject.get_child_count(app)): - window = AXObject.get_child(app, i) - if AXObject.find_descendant(window, lambda x: x == child) is not None: - tokens = ["SCRIPT UTILITIES:", window, "contains", child] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return window - - tokens = ["SCRIPT UTILITIES:", window, "does not contain", child] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return None - - def _isTopLevelObject(self, obj: Atspi.Accessible) -> Any: - return AXObject.get_role(obj) in self._topLevelRoles() \ - and AXObject.get_role(AXObject.get_parent(obj)) == Atspi.Role.APPLICATION - - def topLevelObject(self, obj: Atspi.Accessible, useFallbackSearch: bool = False) -> Any: - """Returns the top-level object (frame, dialog ...) containing obj, - or None if obj is not inside a top-level object. - - Arguments: - - obj: the Accessible object - """ - - if self._isTopLevelObject(obj): - rv = obj - else: - rv = AXObject.find_ancestor(obj, self._isTopLevelObject) - - tokens = ["SCRIPT UTILITIES:", rv, "is top-level object for:", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if rv is None and useFallbackSearch: - msg = "SCRIPT UTILITIES: Attempting to find top-level object via fallback search" - debug.printMessage(debug.LEVEL_INFO, msg, True) - rv = self._findWindowWithDescendant(obj) - - return rv - - def topLevelObjectIsActiveAndCurrent(self, obj: Optional[Atspi.Accessible] = None) -> bool: - obj = obj or cthulhu_state.locusOfFocus - topLevel = self.topLevelObject(obj) - if not topLevel: - return False - - AXObject.clear_cache(topLevel) - if not AXUtilities.is_active(topLevel) or AXUtilities.is_defunct(topLevel): - return False - - if not self.isSameObject(topLevel, cthulhu_state.activeWindow): - return False - - return True - - def onSameLine(self, obj1: Atspi.Accessible, obj2: Atspi.Accessible, delta: int = 0) -> bool: - """Determines if obj1 and obj2 are on the same line.""" - - if not AXObject.supports_component(obj1) or not AXObject.supports_component(obj2): - return False - - try: - bbox1 = Atspi.Component.get_extents(obj1, Atspi.CoordType.SCREEN) - bbox2 = Atspi.Component.get_extents(obj2, Atspi.CoordType.SCREEN) - except Exception: - return False - - center1 = bbox1.y + bbox1.height / 2 - center2 = bbox2.y + bbox2.height / 2 - - return abs(center1 - center2) <= delta - - def pathComparison(self, path1: int, path2: int) -> int: - """Compares the two paths and returns -1, 0, or 1 to indicate if path1 - is before, the same, or after path2.""" - - if path1 == path2: - return 0 - - size = max(len(path1), len(path2)) - path1 = (path1 + [-1] * size)[:size] - path2 = (path2 + [-1] * size)[:size] - - for x in range(min(len(path1), len(path2))): - if path1[x] < path2[x]: - return -1 - if path1[x] > path2[x]: - return 1 - - return 0 - - def sizeComparison(self, obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> Any: - width1, height1 = 0, 0 - width2, height2 = 0, 0 - - if AXObject.supports_component(obj1): - try: - bbox = Atspi.Component.get_extents(obj1, Atspi.CoordType.SCREEN) - width1, height1 = bbox.width, bbox.height - except Exception: - pass - - if AXObject.supports_component(obj2): - try: - bbox = Atspi.Component.get_extents(obj2, Atspi.CoordType.SCREEN) - width2, height2 = bbox.width, bbox.height - except Exception: - pass - - return (width1 * height1) - (width2 * height2) - - def spatialComparison(self, obj1: Atspi.Accessible, obj2: Atspi.Accessible) -> Any: - """Compares the physical locations of obj1 and obj2 and returns -1, - 0, or 1 to indicate if obj1 physically is before, is in the same - place as, or is after obj2.""" - - x1, y1 = 0, 0 - x2, y2 = 0, 0 - - if AXObject.supports_component(obj1): - try: - bbox = Atspi.Component.get_extents(obj1, Atspi.CoordType.SCREEN) - x1, y1 = bbox.x, bbox.y - except Exception: - pass - - if AXObject.supports_component(obj2): - try: - bbox = Atspi.Component.get_extents(obj2, Atspi.CoordType.SCREEN) - x2, y2 = bbox.x, bbox.y - except Exception: - pass - - rv = y1 - y2 or x1 - x2 - - # If the objects claim to have the same coordinates, there is either - # a horrible design crime or we've been given bogus extents. Fall back - # on the index in the parent. This is seen with GtkListBox items which - # had been scrolled off-screen. - if not rv and AXObject.get_parent(obj1) == AXObject.get_parent(obj2): - rv = AXObject.get_index_in_parent(obj1) - AXObject.get_index_in_parent(obj2) - - rv = max(rv, -1) - rv = min(rv, 1) - - return rv - - def getTextBoundingBox(self, obj: Atspi.Accessible, start: int, end: int) -> int: - if not AXObject.supports_text(obj): - return -1, -1, 0, 0 - - try: - extents = Atspi.Text.get_range_extents(obj, start, end, Atspi.CoordType.SCREEN) - except Exception: - tokens = ["SCRIPT UTILITIES: Exception getting range extents of", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return -1, -1, 0, 0 - - return extents - - def getBoundingBox(self, obj: Atspi.Accessible) -> int: - if not AXObject.supports_component(obj): - return -1, -1, 0, 0 - - try: - extents = Atspi.Component.get_extents(obj, Atspi.CoordType.SCREEN) - except Exception: - tokens = ["SCRIPT UTILITIES: Exception getting extents of", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return -1, -1, 0, 0 - - return extents.x, extents.y, extents.width, extents.height - - def hasNoSize(self, obj: Atspi.Accessible) -> bool: - if not obj: - return False - - if AXUtilities.is_application(obj): - return False - - if not AXObject.supports_component(obj): - return True - - try: - extents = Atspi.Component.get_extents(obj, Atspi.CoordType.SCREEN) - except Exception: - tokens = ["SCRIPT UTILITIES: Exception getting extents for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return not (extents.width and extents.height) - - def findAllDescendants(self, root: Any, includeIf: Any = None, excludeIf: Any = None) -> Any: - return AXObject.find_all_descendants(root, includeIf, excludeIf) - - def unrelatedLabels(self, root: Any, onlyShowing: Any = True, minimumWords: Any = 3) -> list[Any]: - """Returns a list containing all the unrelated (i.e., have no - relations to anything and are not a fundamental element of a - more atomic component like a combo box) labels under the given - root. Note that the labels must also be showing on the display. - - Arguments: - - root: the Accessible object to traverse - - onlyShowing: if True, only return labels with STATE_SHOWING - - Returns a list of unrelated labels under the given root. - """ - - if self._script.spellcheck and self._script.spellcheck.isCheckWindow(root): - return [] - - labelRoles = [Atspi.Role.LABEL, Atspi.Role.STATIC] - skipRoles = [Atspi.Role.COMBO_BOX, - Atspi.Role.LIST_BOX, - Atspi.Role.MENU, - Atspi.Role.MENU_BAR, - Atspi.Role.SCROLL_PANE, - Atspi.Role.SPLIT_PANE, - Atspi.Role.TABLE, - Atspi.Role.TREE, - Atspi.Role.TREE_TABLE] - - def _include(x: Atspi.Accessible) -> bool: - if not (x and AXObject.get_role(x) in labelRoles): - return False - if AXUtilitiesRelation.get_relations(x): - return False - if onlyShowing and not AXUtilities.is_showing(x): - return False - return True - - def _exclude(x: Atspi.Accessible) -> bool: - if not x or AXObject.get_role(x) in skipRoles: - return True - if onlyShowing and not AXUtilities.is_showing(x): - return True - return False - - labels = self.findAllDescendants(root, _include, _exclude) - - rootName = AXObject.get_name(root) - - # Eliminate duplicates and things suspected to be labels for widgets - d = {} - for label in labels: - name = AXObject.get_name(label) or self.displayedText(label) - if name and name in [rootName, AXObject.get_name(AXObject.get_parent(label))]: - continue - if len(name.split()) < minimumWords: - continue - if rootName.find(name) >= 0: - continue - d[name] = label - labels = list(d.values()) - - return sorted(labels, key=functools.cmp_to_key(self.spatialComparison)) - - def _treatAlertsAsDialogs(self) -> bool: - return True - - def unfocusedAlertAndDialogCount(self, obj: Atspi.Accessible) -> Any: - """If the current application has one or more alert or dialog - windows and the currently focused window is not an alert or a dialog, - return a count of the number of alert and dialog windows, otherwise - return a count of zero. - - Arguments: - - obj: the Accessible object - - Returns the alert and dialog count. - """ - - roles = [Atspi.Role.DIALOG] - if self._treatAlertsAsDialogs(): - roles.append(Atspi.Role.ALERT) - - def isDialog(x: Atspi.Accessible) -> bool: - return AXObject.get_role(x) in roles or self.isFunctionalDialog(x) - - dialogs = [x for x in AXObject.iter_children(AXObject.get_application(obj), isDialog)] - dialogs.extend([x for x in AXObject.iter_children(self.topLevelObject(obj), isDialog)]) - - def isPresentable(x: Atspi.Accessible) -> bool: - return self.isShowingAndVisible(x) \ - and (AXObject.get_name(x) or AXObject.get_child_count(x)) - - def cannotBeActiveWindow(x: Atspi.Accessible) -> bool: - return not self.canBeActiveWindow(x) - - presentable = list(filter(isPresentable, set(dialogs))) - unfocused = list(filter(cannotBeActiveWindow, presentable)) - return len(unfocused) - - def uri(self, obj: Atspi.Accessible) -> Any: - """Return the URI for a given link object. - - Arguments: - - obj: the Accessible object. - """ - - uri = AXHypertext.get_link_uri(obj) - return uri or None - - ######################################################################### - # # - # Utilities for working with the accessible text interface # - # # - ######################################################################### - - def _getSelectionAdapter(self) -> AXDocumentSelection: - adapter = getattr(self, "_documentSelectionAdapter", None) - if adapter is None: - adapter = AXDocumentSelection(self) - self._documentSelectionAdapter = adapter - return adapter - - def _getSelectionState(self) -> dict[Any, Any]: - state = self._script.pointOfReference.get('selectionState') - if state is None: - state = {'textSelections': {}} - self._script.pointOfReference['selectionState'] = state - state.setdefault('textSelections', {}) - return state - - def _getCachedSelectionData(self, obj: Atspi.Accessible) -> dict[str, Any]: - if not obj: - return {'ranges': [], 'start': 0, 'end': 0, 'string': ''} - - cached = self._getSelectionState().get('textSelections', {}).get(hash(obj), {}) - return { - 'ranges': list(cached.get('ranges', [])), - 'start': cached.get('start', 0), - 'end': cached.get('end', 0), - 'string': cached.get('string', ''), - } - - def _cacheSelectionData(self, obj: Atspi.Accessible, data: dict[str, Any]) -> None: - textSelections = self._getSelectionState().setdefault('textSelections', {}) - - if hash(obj) in textSelections: - value = textSelections.pop(hash(obj)) - for x in [k for k in textSelections.keys() if textSelections.get(k) == value]: - textSelections.pop(x) - - textSelections[hash(obj)] = { - 'ranges': list(data.get('ranges', [])), - 'start': data.get('start', 0), - 'end': data.get('end', 0), - 'string': data.get('string', ''), - } - - def _getSelectionTextFragment(self, obj: Atspi.Accessible, start: int, end: int) -> str: - text = self.expandEOCs(obj, start, end) - if text: - return text - - fallback = AXText.get_substring(obj, start, end) - if fallback: - tokens = [ - "SCRIPT UTILITIES: Falling back to raw substring for selection text in", - obj, - f"({start}, {end})", - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return fallback - - return "" - - def _getLocalSelectionData(self, obj: Atspi.Accessible) -> dict[str, Any]: - if not AXObject.supports_text(obj): - return {'ranges': [], 'start': 0, 'end': 0, 'string': ''} - - textContents = "" - startOffset = endOffset = 0 - ranges = AXText.get_selected_ranges(obj) - for start, end in ranges: - if start == end: - continue - selectedText = self._getSelectionTextFragment(obj, start, end) - if textContents: - textContents += " " - textContents += selectedText - if startOffset == endOffset == 0: - startOffset = start - endOffset = end - - return { - 'ranges': ranges, - 'start': startOffset, - 'end': endOffset, - 'string': textContents, - } - - def _getSelectionData( - self, - obj: Atspi.Accessible, - snapshot: Any = None, - ) -> dict[str, Any]: - if not AXObject.supports_text(obj): - return {'ranges': [], 'start': 0, 'end': 0, 'string': ''} - - snapshot = snapshot if snapshot is not None else self._getSelectionAdapter().refresh_snapshot(obj) - if snapshot.is_authoritative: - projected = self._getSelectionAdapter().get_projected_selection(obj, snapshot) - return { - 'ranges': list(projected.local_ranges), - 'start': projected.start_offset, - 'end': projected.end_offset, - 'string': projected.text, - } - - return self._getLocalSelectionData(obj) - - @staticmethod - def _rangesToCharSet(ranges: list[tuple[int, int]]) -> set[int]: - chars = set() - for start, end in ranges: - chars.update(range(start, end)) - return chars - - @staticmethod - def _charSetToRanges(chars: set[int]) -> list[tuple[int, int]]: - if not chars: - return [] - - change = sorted(chars) - ranges = [] - startOffset = change[0] - endOffset = change[0] + 1 - for offset in change[1:]: - if offset == endOffset: - endOffset += 1 - continue - ranges.append((startOffset, endOffset)) - startOffset = offset - endOffset = offset + 1 - - ranges.append((startOffset, endOffset)) - return ranges - - def adjustTextSelection(self, obj: Atspi.Accessible, offset: int) -> None: - """Adjusts the end point of a text selection - - Arguments: - - obj: the Accessible object. - - offset: the new end point - can be to the left or to the right - depending on the direction of selection - """ - - if not AXObject.supports_text(obj): - return - - if self._getSelectionAdapter().adjust_selection(obj, offset): - return - - selections = AXText.get_selected_ranges(obj) - if not selections: - caretOffset = AXText.get_caret_offset(obj) - startOffset = min(offset, caretOffset) - endOffset = max(offset, caretOffset) - else: - startOffset, endOffset = selections[0] - if offset < startOffset: - startOffset = offset - else: - endOffset = offset - - AXText.set_selected_text(obj, startOffset, endOffset) - - def findPreviousObject(self, obj: Atspi.Accessible) -> Optional[Any]: - """Finds the object before this one.""" - - if not obj or self.isZombie(obj): - return None - - flowsFrom = AXUtilitiesRelation.get_flows_from(obj) - if flowsFrom: - return flowsFrom[0] - - return AXUtilities.get_previous_object(obj) - - def findNextObject(self, obj: Atspi.Accessible) -> Optional[Any]: - """Finds the object after this one.""" - - if not obj or self.isZombie(obj): - return None - - flowsTo = AXUtilitiesRelation.get_flows_to(obj) - if flowsTo: - return flowsTo[0] - - return AXUtilities.get_next_object(obj) - - def allSelectedText(self, obj: Atspi.Accessible) -> Any: - """Get all the text applicable text selections for the given object. - including any previous or next text objects that also have - selected text and add in their text contents. - - Arguments: - - obj: the text object to start extracting the selected text from. - - Returns: all the selected text contents plus the start and end - offsets within the text for the given object. - """ - - snapshot = self._getSelectionAdapter().refresh_snapshot(obj) - if snapshot.is_authoritative: - return self._getSelectionAdapter().get_all_selected_text(obj, snapshot) - - textContents, startOffset, endOffset = self.selectedText(obj) - if textContents and self._script.pointOfReference.get('entireDocumentSelected'): - return textContents, startOffset, endOffset - - if self.isSpreadSheetCell(obj): - return textContents, startOffset, endOffset - - prevObj = self.findPreviousObject(obj) - while prevObj: - if self.queryNonEmptyText(prevObj): - selection, start, end = self.selectedText(prevObj) - if not selection: - break - textContents = f"{selection} {textContents}" - prevObj = self.findPreviousObject(prevObj) - - nextObj = self.findNextObject(obj) - while nextObj: - if self.queryNonEmptyText(nextObj): - selection, start, end = self.selectedText(nextObj) - if not selection: - break - textContents = f"{textContents} {selection}" - nextObj = self.findNextObject(nextObj) - - return textContents, startOffset, endOffset - - def allTextSelections(self, obj: Atspi.Accessible) -> Any: - """Get a list of text selections in the given accessible object, - equivalent to getNSelections()*texti.getSelection() - - Arguments: - - obj: An accessible. - - Returns list of start and end offsets for multiple selections, or an - empty list if nothing is selected or if the accessible does not support - the text interface. - """ - - snapshot = self._getSelectionAdapter().refresh_snapshot(obj) - if snapshot.is_authoritative: - return self._getSelectionAdapter().get_projected_selection(obj, snapshot).local_ranges - - return AXText.get_selected_ranges(obj) - - def getChildAtOffset(self, obj: Atspi.Accessible, offset: Any) -> Optional[Any]: - child = AXHypertext.get_child_at_offset(obj, offset) - if not child: - return None - - tokens = ["SCRIPT UTILITIES: Hyperlink object at offset", offset, "for", obj, "is", child] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return child - - def findChildAtOffset(self, obj: Atspi.Accessible, offset: int) -> Any: - """Attempts to correct for off-by-one brokenness in hypertext implementations. - - We're seeing off-by-one errors in (at least) Chromium where the text - at a given offset is an embedded object character, but retrieving the - child at that offset returns None. - - This method handles this condition by checking for the child at the - previous and next offsets. If there's a child, and its offset in parent - matches the desired offset, return that child. - """ - - if child := self.getChildAtOffset(obj, offset): - return child - - if child_before := self.getChildAtOffset(obj, offset - 1): - offset_in_parent = self.characterOffsetInParent(child_before) - if offset_in_parent == offset: - tokens = [f"SCRIPT UTILITIES: Corrected child at offset {offset} in", obj, "is", - child_before, f"at offset {offset - 1}"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return child_before - - if child_after := self.getChildAtOffset(obj, offset + 1): - offset_in_parent = self.characterOffsetInParent(child_after) - if offset_in_parent == offset: - tokens = [f"SCRIPT UTILITIES: Corrected child at offset {offset} in", obj, "is", - child_after, f"at offset {offset + 1}"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return child_after - - return None - - def characterOffsetInParent(self, obj: Atspi.Accessible) -> Any: - """Returns the character offset of the embedded object - character for this object in its parent's accessible text. - - Arguments: - - obj: an Accessible that should implement the accessible - hyperlink specialization. - - Returns an integer representing the character offset of the - embedded object character for this hyperlink in its parent's - accessible text, or -1 something was amuck. - """ - - offset = -1 - # We need to make sure that this is an embedded object in - # some accessible text (as opposed to an imagemap link). - # - parent = AXObject.get_parent(obj) - if AXObject.supports_text(parent): - offset = AXHypertext.get_link_start_offset(obj) - else: - tokens = ["SCRIPT UTILITIES: Exception getting startIndex for", - obj, "in parent", parent] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - tokens = ["SCRIPT UTILITIES: startIndex of", obj, f"is {offset}"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return offset - - def clearTextSelection(self, obj: Atspi.Accessible) -> None: - """Clears the text selection if the object supports it. - - Arguments: - - obj: the Accessible object. - """ - - if not AXObject.supports_text(obj): - return - - if self._getSelectionAdapter().clear_selection(obj): - self._script.pointOfReference['entireDocumentSelected'] = False - self._getSelectionState()['textSelections'] = {} - return - - for i in range(AXText._get_n_selections(obj)): - AXText._remove_selection(obj, i) - - def containsOnlyEOCs(self, obj: Atspi.Accessible) -> Any: - string = AXText.get_all_text(obj) - return string and not re.search(r"[^\ufffc]", string) - - def expandEOCs(self, obj: Atspi.Accessible, startOffset: Any = 0, endOffset: Any = -1) -> str: - """Expands the current object replacing EMBEDDED_OBJECT_CHARACTERS - with their text. - - Arguments - - obj: the object whose text should be expanded - - startOffset: the offset of the first character to be included - - endOffset: the offset of the last character to be included - - Returns the fully expanded text for the object. - """ - - try: - string = self.substring(obj, startOffset, endOffset) - except Exception: - return "" - - if self.EMBEDDED_OBJECT_CHARACTER not in string: - return string - - blockRoles = [Atspi.Role.HEADING, - Atspi.Role.LIST, - Atspi.Role.LIST_ITEM, - Atspi.Role.PARAGRAPH, - Atspi.Role.SECTION, - Atspi.Role.TABLE, - Atspi.Role.TABLE_CELL, - Atspi.Role.TABLE_ROW] - - toBuild = list(string) - for i, char in enumerate(toBuild): - if char == self.EMBEDDED_OBJECT_CHARACTER: - child = self.findChildAtOffset(obj, i + startOffset) - result = self.expandEOCs(child) - if child and AXObject.get_role(child) in blockRoles: - result += " " - toBuild[i] = result - - return "".join(toBuild) - - def isWordMisspelled(self, obj: Atspi.Accessible, offset: Any) -> bool: - """Identifies if the current word is flagged as misspelled by the - application. Different applications and toolkits flag misspelled - words differently. Thus each script will likely need to implement - its own version of this method. - - Arguments: - - obj: An accessible which implements the accessible text interface. - - offset: Offset in the accessible's text for which to retrieve the - attributes. - - Returns True if the word is flagged as misspelled. - """ - - attributes, start, end = self.textAttributes(obj, offset, True) - if attributes.get("invalid") == "spelling": - return True - if attributes.get("text-spelling") == "misspelled": - return True - if attributes.get("underline") in ["error", "spelling"]: - return True - - return False - - def getError(self, obj: Atspi.Accessible) -> Any: - return AXUtilities.is_invalid_entry(obj) - - def getErrorMessage(self, obj: Atspi.Accessible) -> str: - return "" - - def isErrorMessage(self, obj: Atspi.Accessible) -> bool: - return False - - def getCharacterAtOffset(self, obj: Atspi.Accessible, offset: int = None) -> Any: - if AXObject.supports_text(obj): - if offset is None: - offset = AXText.get_caret_offset(obj) - return AXText.get_substring(obj, offset, offset + 1) - - return "" - - def queryNonEmptyText(self, obj: Atspi.Accessible) -> Optional[Any]: - """Get the text interface associated with an object, if it is - non-empty. - - Arguments: - - obj: an accessible object - """ - - if not AXObject.supports_text(obj): - return None - - charCount = AXText.get_character_count(obj) - if charCount: - return obj - - return None - - def deletedText(self, event: Any) -> Any: - return event.any_data - - def insertedText(self, event: Any) -> Any: - if event.any_data: - return event.any_data - - msg = "SCRIPT UTILITIES: Broken text insertion event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - fallbackText = self._getFallbackInsertedText(event) - if fallbackText: - return fallbackText - - msg = "FAIL: Unable to correct broken text insertion event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return "" - - def _getFallbackInsertedText(self, event: Any) -> str: - if not AXUtilities.is_password_text(event.source): - return "" - - text = self.queryNonEmptyText(event.source) - if not text: - return "" - - string = AXText.get_all_text(event.source) - if not string: - return "" - - tokens = ["HACK: Returning last char in '", string, "'"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return string[-1] - - def selectedText(self, obj: Atspi.Accessible) -> Any: - """Get the text selection for the given object. - - Arguments: - - obj: the text object to extract the selected text from. - - Returns: the selected text contents plus the start and end - offsets within the text. - """ - - selectionData = self._getSelectionData(obj) - return [selectionData['string'], selectionData['start'], selectionData['end']] - - def getCaretContext(self) -> Any: - obj = cthulhu_state.locusOfFocus - if AXObject.supports_text(obj): - offset = AXText.get_caret_offset(obj) - else: - offset = -1 - - return obj, offset - - def getFirstCaretPosition(self, obj: Atspi.Accessible) -> Any: - return obj, 0 - - def setCaretPosition(self, obj: Atspi.Accessible, offset: int, documentFrame: Any = None) -> Any: - cthulhu.setLocusOfFocus(None, obj, False) - self.setCaretOffset(obj, offset) - - def setCaretOffset(self, obj: Atspi.Accessible, offset: int) -> Any: - """Set the caret offset on a given accessible. Similar to - Accessible.setCaretOffset() - - Arguments: - - obj: Given accessible object. - - offset: Offset to hich to set the caret. - """ - AXText.set_caret_offset(obj, offset) - - def substring(self, obj: Atspi.Accessible, startOffset: Any, endOffset: Any) -> Any: - """Returns the substring of the given object's text specialization. - - Arguments: - - obj: an accessible supporting the accessible text specialization - - startOffset: the starting character position - - endOffset: the ending character position. Note that an end offset - of -1 means the last character - """ - - return AXText.get_substring(obj, startOffset, endOffset) - - def getAppNameForAttribute(self, attribName: Any) -> Any: - """Converts the given Atk attribute name into the application's - equivalent. This is necessary because an application or toolkit - (e.g. Gecko) might invent entirely new names for the same text - attributes. - - Arguments: - - attribName: The name of the text attribute - - Returns the application's equivalent name if found or attribName - otherwise. - """ - - for key, value in self._script.attributeNamesDict.items(): - if value == attribName: - return key - - return attribName - - def getAtkNameForAttribute(self, attribName: Any) -> Any: - """Converts the given attribute name into the Atk equivalent. This - is necessary because an application or toolkit (e.g. Gecko) might - invent entirely new names for the same attributes. - - Arguments: - - attribName: The name of the text attribute - - Returns the Atk equivalent name if found or attribName otherwise. - """ - - return self._script.attributeNamesDict.get(attribName, attribName) - - def getAllTextAttributesForObject(self, obj: Atspi.Accessible, startOffset: Any = 0, endOffset: Any = -1) -> list[Any]: - """Returns a list of (start, end, attrsDict) tuples for obj.""" - if not AXObject.supports_text(obj): - return [] - - if endOffset == -1: - endOffset = AXText.get_character_count(obj) - - tokens = ["SCRIPT UTILITIES: Getting text attributes for", obj, - f"chars: {startOffset}-{endOffset}"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - startTime = time.time() - - rv = [] - offset = startOffset - while offset < endOffset: - attrs, start, end = AXText.get_text_attributes_at_offset(obj, offset) - tokens = [f"SCRIPT UTILITIES: At {offset}:", attrs, f"({start}, {end})"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv.append((max(start, offset), end, attrs)) - offset = max(end, offset + 1) - - endTime = time.time() - msg = f"SCRIPT UTILITIES: {len(rv)} attribute ranges found in {endTime - startTime:.4f}s" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return rv - - def textAttributes(self, acc: Any, offset: Any = None, get_defaults: Any = False) -> dict[Any, Any]: - """Get the text attributes run for a given offset in a given accessible - - Arguments: - - acc: An accessible. - - offset: Offset in the accessible's text for which to retrieve the - attributes. - - get_defaults: Get the default attributes as well as the unique ones. - Default is True - - Returns a dictionary of attributes, a start offset where the attributes - begin, and an end offset. Returns ({}, 0, 0) if the accessible does not - supprt the text attribute. - """ - - if not AXObject.supports_text(acc): - return {}, 0, 0 - - if offset is None: - offset = AXText.get_caret_offset(acc) - - attrs, start, end = AXText.get_text_attributes_at_offset(acc, offset) - return attrs, min(start, offset), max(end, offset + 1) - - def localizeTextAttribute(self, key: Any, value: Any) -> Any: - if key == "weight" and (value == "bold" or int(value) > 400): - return messages.BOLD - - if key.endswith("spelling") or value == "spelling": - return messages.MISSPELLED - - localizedKey = text_attribute_names.getTextAttributeName(key, self._script) - - if key == "family-name": - localizedValue = value.split(",")[0].strip().strip('"') - elif value and value.endswith("px"): - value = value.split("px")[0] - if locale.localeconv()["decimal_point"] in value: - localizedValue = messages.pixelCount(float(value)) - else: - localizedValue = messages.pixelCount(int(value)) - elif key.endswith("color"): - r, g, b = self.rgbFromString(value) - if settings.useColorNames: - localizedValue = colornames.rgbToName(r, g, b) - else: - localizedValue = "%i %i %i" % (r, g, b) - else: - localizedValue = text_attribute_names.getTextAttributeName(value, self._script) - - return f"{localizedKey}: {localizedValue}" - - def splitSubstringByLanguage(self, obj: Atspi.Accessible, start: int, end: int) -> Any: - """Returns a list of (start, end, string, language, dialect) tuples.""" - - rv = [] - allSubstrings = self.getLanguageAndDialectFromTextAttributes(obj, start, end) - for startOffset, endOffset, language, dialect in allSubstrings: - if start >= endOffset: - continue - if end <= startOffset: - break - startOffset = max(start, startOffset) - endOffset = min(end, endOffset) - string = self.substring(obj, startOffset, endOffset) - rv.append([startOffset, endOffset, string, language, dialect]) - - return rv - - def getLanguageAndDialectForSubstring(self, obj: Atspi.Accessible, start: int, end: int) -> Any: - """Returns a (language, dialect) tuple. If multiple languages apply to - the substring, language and dialect will be empty strings. Callers must - do any preprocessing to avoid that condition.""" - - allSubstrings = self.getLanguageAndDialectFromTextAttributes(obj, start, end) - for startOffset, endOffset, language, dialect in allSubstrings: - if startOffset <= start and endOffset >= end: - return language, dialect - - return "", "" - - def getLanguageAndDialectFromTextAttributes(self, obj: Atspi.Accessible, startOffset: Any = 0, endOffset: Any = -1) -> Any: - """Returns a list of (start, end, language, dialect) tuples for obj - based on what is exposed via text attributes.""" - - rv = [] - attributeSet = self.getAllTextAttributesForObject(obj, startOffset, endOffset) - lastLanguage = lastDialect = "" - for (start, end, attrs) in attributeSet: - language = attrs.get("language", "") - dialect = "" - if "-" in language: - language, dialect = language.split("-", 1) - if rv and lastLanguage == language and lastDialect == dialect: - rv[-1] = rv[-1][0], end, language, dialect - else: - rv.append((start, end, language, dialect)) - lastLanguage, lastDialect = language, dialect - - return rv - - def willEchoCharacter(self, event: Any) -> bool: - """Given a keyboard event containing an alphanumeric key, - determine if the script is likely to echo it as a character. - """ - - if not cthulhu_state.locusOfFocus or not settings.enableEchoByCharacter: - return False - - if len(event.event_string) != 1 \ - or event.modifiers & keybindings.CTHULHU_CTRL_MODIFIER_MASK: - return False - - if AXUtilities.is_password_text(cthulhu_state.locusOfFocus): - return False - - if AXUtilities.is_editable(cthulhu_state.locusOfFocus): - return True - - return False - - ######################################################################### - # # - # Miscellaneous Utilities # - # # - ######################################################################### - - def _addRepeatSegment(self, segment: Any, line: Any, respectPunctuation: Any = True) -> Any: - """Add in the latest line segment, adjusting for repeat characters - and punctuation. - - Arguments: - - segment: the segment of repeated characters. - - line: the current built-up line to characters to speak. - - respectPunctuation: if False, ignore punctuation level. - - Returns: the current built-up line plus the new segment, after - adjusting for repeat character counts and punctuation. - """ - - from . import punctuation_settings - - style = settings.verbalizePunctuationStyle - isPunctChar = True - try: - level, action = punctuation_settings.getPunctuationInfo(segment[0]) - except Exception: - isPunctChar = False - count = len(segment) - if (count >= settings.repeatCharacterLimit) \ - and (segment[0] not in self._script.whitespace): - if (not respectPunctuation) \ - or (isPunctChar and (style <= level)): - repeatChar = chnames.getCharacterName(segment[0]) - repeatSegment = messages.repeatedCharCount(repeatChar, count) - line = f"{line} {repeatSegment}" - else: - line += segment - else: - line += segment - - return line - - def shouldVerbalizeAllPunctuation(self, obj: Atspi.Accessible) -> bool: - if not (self.isCode(obj) or self.isCodeDescendant(obj)): - return False - - # If the user has set their punctuation level to All, then the synthesizer will - # do the work for us. If the user has set their punctuation level to None, then - # they really don't want punctuation and we mustn't override that. - style = cthulhu.cthulhuApp.settingsManager.getSetting("verbalizePunctuationStyle") - if style in [settings.PUNCTUATION_STYLE_ALL, settings.PUNCTUATION_STYLE_NONE]: - return False - - return True - - def verbalizeAllPunctuation(self, string: Any) -> Any: - result = string - for symbol in set(re.findall(self.PUNCTUATION, result)): - charName = f" {chnames.getCharacterName(symbol)} " - result = re.sub(r"\%s" % symbol, charName, result) - - return result - - def adjustForLinks(self, obj: Atspi.Accessible, line: Any, startOffset: Any) -> Any: - """Adjust line to include the word "link" after any hypertext links. - - Arguments: - - obj: the accessible object that this line came from. - - line: the string to adjust for links. - - startOffset: the caret offset at the start of the line. - - Returns: a new line adjusted to add the speaking of "link" after - text which is also a link. - """ - - from . import punctuation_settings - - endOffset = startOffset + len(line) - links = AXHypertext.get_all_links(obj) if AXObject.supports_hypertext(obj) else [] - - adjustedLine = list(line) - for link in reversed(links): - start_index = AXHypertext.get_link_start_offset(link) - end_index = AXHypertext.get_link_end_offset(link) - if start_index < 0 or end_index < 0: - continue - - # We only care about links in the string, line: - # - if startOffset < end_index <= endOffset: - index = end_index - startOffset - elif startOffset <= start_index < endOffset: - index = len(line) - if end_index < endOffset: - index -= 1 - else: - continue - - linkString = " " + messages.LINK - - # If the link was not followed by a whitespace or punctuation - # character, then add in a space to make it more presentable. - # - nextChar = "" - if index < len(line): - nextChar = adjustedLine[index] - if not (nextChar in self._script.whitespace \ - or punctuation_settings.getPunctuationInfo(nextChar)): - linkString += " " - adjustedLine[index:index] = linkString - - return "".join(adjustedLine) - - def getLinkIndicatorPresentation(self, obj: Atspi.Accessible, line: Any, startOffset: Any): - """Return the spoken text and any link icons for a line fragment.""" - - spoken = self.adjustForLinks(obj, line, startOffset) - roleSoundPresentation = cthulhu.cthulhuApp.settingsManager.getSetting('roleSoundPresentation') - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SPEECH_ONLY: - return spoken, [] - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableSound'): - return spoken, [] - - if not AXObject.supports_hypertext(obj): - return spoken, [] - - from . import sound_theme_manager - - manager = sound_theme_manager.getManager() - if manager is None: - return spoken, [] - - endOffset = startOffset + len(line) - icons = [] - missingIcon = False - for link in AXHypertext.get_all_links(obj): - start_index = AXHypertext.get_link_start_offset(link) - end_index = AXHypertext.get_link_end_offset(link) - if start_index < 0 or end_index < 0: - continue - - if startOffset < end_index <= endOffset: - pass - elif startOffset <= start_index < endOffset: - pass - else: - continue - - icon = manager.getLinkSoundIcon(visited=AXUtilities.is_visited(link)) - if icon: - rect = None - if cthulhu.cthulhuApp.settingsManager.getSetting('spatializeObjectSounds'): - rect = AXText.get_range_rect(obj, start_index, end_index) - self.spatializeSoundIcon(icon, link, rect) - icons.append(icon) - else: - missingIcon = True - - if not icons: - return spoken, [] - - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY and not missingIcon: - return line, icons - - return spoken, icons - - def spatializeSoundIcon( - self, - icon: Any, - obj: Optional[Atspi.Accessible], - rect: Optional[Any] = None, - ) -> Any: - """Attach an optional stereo pan value to an icon based on object position.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('spatializeObjectSounds'): - return icon - - pan = self.getSoundPanForObject(obj, rect) - if pan is None: - return icon - - try: - icon.pan = pan - except Exception: - pass - return icon - - def getSoundPanForObject( - self, - obj: Optional[Atspi.Accessible], - rect: Optional[Any] = None, - ) -> Optional[float]: - """Return a conservative left/right pan value for obj, or None if unknown.""" - - if obj is None and rect is None: - return None - - rect = rect or AXComponent.get_rect(obj) - width = getattr(rect, "width", 0) - if width <= 0: - return None - - frame, dialog = self.frameAndDialog(obj) - reference = dialog or frame or self.activeWindow() - if reference is None: - return None - - referenceRect = AXComponent.get_rect(reference) - referenceWidth = getattr(referenceRect, "width", 0) - if referenceWidth <= 0: - return None - - centerX = getattr(rect, "x", 0) + width / 2 - left = getattr(referenceRect, "x", 0) - position = (centerX - left) / referenceWidth - position = max(0.0, min(1.0, position)) - - edge = 0.05 - if position <= edge: - return -1.0 - if position >= 1.0 - edge: - return 1.0 - - return ((position - edge) / (1.0 - (2 * edge)) * 2.0) - 1.0 - - def _processMultiCaseString(self, string: Any) -> Any: - return re.sub(r'(?<=[a-z])(?=[A-Z])', ' ', string) - - def _convertWordToDigits(self, word: Any) -> Any: - if not word.isnumeric(): - return word - - return ' '.join(list(word)) - - def adjustForPronunciation(self, line: Any) -> Any: - """Adjust the line to replace words in the pronunciation dictionary, - with what those words actually sound like. - - Arguments: - - line: the string to adjust for words in the pronunciation dictionary. - - Returns: a new line adjusted for words found in the pronunciation - dictionary. - """ - - if settings.speakMultiCaseStringsAsWords: - line = self._processMultiCaseString(line) - - if self.speakMathSymbolNames(): - line = mathsymbols.adjustForSpeech(line) - - if settings.speakNumbersAsDigits: - words = self.WORDS_RE.split(line) - line = ''.join(map(self._convertWordToDigits, words)) - - if len(line) == 1 and not self._script.inSayAll(): - charname = chnames.getCharacterName(line) - if charname != line: - return charname - - if not settings.usePronunciationDictionary: - return line - - newLine = "" - words = self.WORDS_RE.split(line) - newLine = ''.join(map(pronunciation_dict.getPronunciation, words)) - - if settings.speakMultiCaseStringsAsWords: - newLine = self._processMultiCaseString(newLine) - - return newLine - - def adjustForRepeats(self, line: Any) -> Any: - """Adjust line to include repeat character counts. As some people - will want this and others might not, there is a setting in - settings.py that determines whether this functionality is enabled. - - repeatCharacterLimit = - - If is 0, then there would be no repeat characters. - Otherwise would be the number of same characters (or more) - in a row that cause the repeat character count output. - If the value is set to 1, 2 or 3 then it's treated as if it was - zero. In other words, no repeat character count is given. - - Arguments: - - line: the string to adjust for repeat character counts. - - Returns: a new line adjusted for repeat character counts (if enabled). - """ - - if (len(line) < 4) or (settings.repeatCharacterLimit < 4): - return line - - newLine = '' - segment = lastChar = line[0] - - multipleChars = False - for i in range(1, len(line)): - if line[i] == lastChar: - segment += line[i] - else: - multipleChars = True - newLine = self._addRepeatSegment(segment, newLine) - segment = line[i] - - lastChar = line[i] - - return self._addRepeatSegment(segment, newLine, multipleChars) - - def adjustForDigits(self, string: Any) -> Any: - """Adjusts the string to convert digit-like text, such as subscript - and superscript numbers, into actual digits. - - Arguments: - - string: the string to be adjusted - - Returns: a new string which contains actual digits. - """ - - subscripted = set(re.findall(self.SUBSCRIPTS_RE, string)) - superscripted = set(re.findall(self.SUPERSCRIPTS_RE, string)) - - for number in superscripted: - new = [str(self.SUPERSCRIPT_DIGITS.index(d)) for d in number] - newString = messages.DIGITS_SUPERSCRIPT % "".join(new) - string = re.sub(number, newString, string) - - for number in subscripted: - new = [str(self.SUBSCRIPT_DIGITS.index(d)) for d in number] - newString = messages.DIGITS_SUBSCRIPT % "".join(new) - string = re.sub(number, newString, string) - - return string - - # Hardcoded indentation audio parameters - _INDENTATION_TAB_WIDTH = 4 - _INDENTATION_BASE_FREQUENCY = 200 - _INDENTATION_STEP_FREQUENCY = 30 - _INDENTATION_MAX_FREQUENCY = 2700 - _INDENTATION_DURATION = 0.15 - _INDENTATION_VOLUME = 0.7 - - def _get_indentation_key(self, obj: Atspi.Accessible) -> Any: - if obj is None: - return "global" - - try: - return id(obj) - except Exception: - return str(obj) - - def _extract_indentation(self, line: Any) -> str: - if not line: - return "" - - line = line.replace("\u00a0", " ") - end = re.search("[^ \t]", line) - if end: - return line[:end.start()] - - return line - - def _get_indentation_columns(self, indentation: Any, tabWidth: Any) -> Any: - columns = 0 - tabWidth = max(1, tabWidth) - for char in indentation: - if char == "\t": - columns += tabWidth - (columns % tabWidth) - else: - columns += 1 - - return columns - - def _get_indentation_data(self, line: Any) -> Any: - indentation = self._extract_indentation(line) - columns = self._get_indentation_columns(indentation, self._INDENTATION_TAB_WIDTH) - return { - "indentation": indentation, - "columns": columns, - } - - def _remember_indentation(self, obj: Atspi.Accessible, data: Any) -> bool: - key = self._get_indentation_key(obj) - self._lastIndentationData[key] = { - "signature": data["indentation"], - "columns": data["columns"], - } - - def _indentation_has_changed(self, obj: Atspi.Accessible, data: Any) -> bool: - key = self._get_indentation_key(obj) - previous = self._lastIndentationData.get(key) - self._remember_indentation(obj, data) - if previous is None: - return True, 0 - - changed = previous.get("signature") != data["indentation"] - previousColumns = previous.get("columns", 0) - return changed, previousColumns - - def _indentation_enabled(self) -> bool: - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return False - return cthulhu.cthulhuApp.settingsManager.getSetting('enableIndentation') - - def _indentation_speech_enabled(self) -> bool: - if not self._indentation_enabled(): - return False - - presentationMode = cthulhu.cthulhuApp.settingsManager.getSetting('indentationPresentationMode') \ - or settings.indentationPresentationMode - return presentationMode in ( - settings.INDENTATION_PRESENTATION_SPEECH, - settings.INDENTATION_PRESENTATION_SPEECH_AND_BEEPS, - ) - - def _indentation_beeps_enabled(self) -> bool: - if not self._indentation_enabled(): - return False - - presentationMode = cthulhu.cthulhuApp.settingsManager.getSetting('indentationPresentationMode') \ - or settings.indentationPresentationMode - return presentationMode in ( - settings.INDENTATION_PRESENTATION_BEEPS, - settings.INDENTATION_PRESENTATION_SPEECH_AND_BEEPS, - ) - - def _play_indentation_tone(self, columns: Any, previousColumns: Any) -> None: - """Play an audio tone indicating indentation level.""" - if not _SOUND_AVAILABLE: - return - - try: - player = sound.getPlayer() - if not player: - return - - frequency = min( - self._INDENTATION_BASE_FREQUENCY + (columns * self._INDENTATION_STEP_FREQUENCY), - self._INDENTATION_MAX_FREQUENCY - ) - - # Add directional cue - if columns > previousColumns: - frequency += 50 - elif columns < previousColumns: - frequency = max(frequency - 50, 100) - - tone = Tone( - duration=self._INDENTATION_DURATION, - frequency=frequency, - volumeMultiplier=self._INDENTATION_VOLUME, - wave=Tone.SINE_WAVE - ) - player.play(tone, interrupt=False) - debug.printMessage(debug.LEVEL_INFO, - f"INDENTATION: played tone freq={frequency}Hz columns={columns}", True) - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, - f"INDENTATION: error playing tone: {e}", True) - - def get_indentation_presentation(self, line: Any, obj: Optional[Atspi.Accessible] = None) -> str: - data = self._get_indentation_data(line) - hasIndentation = bool(data["indentation"]) - presentationMode = cthulhu.cthulhuApp.settingsManager.getSetting('indentationPresentationMode') \ - or settings.indentationPresentationMode - indentDebug = data["indentation"].replace("\t", "\\t").replace(" ", ".") - - if not self._indentation_enabled(): - self._remember_indentation(obj, data) - msg = ( - f"INDENTATION: disabled mode={presentationMode} " - f"columns={data['columns']} indent='{indentDebug}'" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return "", hasIndentation - - changed, previousColumns = self._indentation_has_changed(obj, data) - - if not changed: - msg = ( - f"INDENTATION: unchanged mode={presentationMode} " - f"columns={data['columns']} indent='{indentDebug}'" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return "", hasIndentation - - # Play beep if beeps are enabled - if self._indentation_beeps_enabled(): - self._play_indentation_tone(data["columns"], previousColumns) - - # Return speech description if speech is enabled - if self._indentation_speech_enabled(): - description = messages.indentationColumnCount(data["columns"]) - msg = ( - f"INDENTATION: speaking '{description}' mode={presentationMode} " - f"columns={data['columns']} indent='{indentDebug}'" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return description, hasIndentation - - return "", hasIndentation - - def should_strip_indentation(self, line: Any) -> bool: - if not self._indentation_enabled(): - return False - - data = self._get_indentation_data(line) - return bool(data["indentation"]) - - def indentationDescription(self, line: Any, obj: Optional[Atspi.Accessible] = None) -> Any: - description, _hasIndentation = self.get_indentation_presentation(line, obj=obj) - return description - - def absoluteMouseCoordinates(self) -> Any: - """Gets the absolute position of the mouse pointer.""" - - from gi.repository import Gtk - rootWindow = Gtk.Window().get_screen().get_root_window() - window, x, y, modifiers = rootWindow.get_pointer() - - return x, y - - def appendString(self, text: Any, newText: Any, delimiter: Any = " ") -> Any: - """Appends the newText to the given text with the delimiter in between - and returns the new string. Edge cases, such as no initial text or - no newText, are handled gracefully.""" - - if not newText: - return text - if not text: - return newText - - return text + delimiter + newText - - def treatAsDuplicateEvent(self, event1: Any, event2: Any) -> bool: - if not (event1 and event2): - return False - - # The goal is to find event spam so we can ignore the event. - if event1 == event2: - return False - - return event1.source == event2.source \ - and event1.type == event2.type \ - and event1.detail1 == event2.detail1 \ - and event1.detail2 == event2.detail2 \ - and event1.any_data == event2.any_data - - def isAutoTextEvent(self, event: Any) -> bool: - """Returns True if event is associated with text being autocompleted - or autoinserted or autocorrected or autosomethingelsed. - - Arguments: - - event: the accessible event being examined - """ - - if event.type.startswith("object:text-changed:insert"): - if not event.any_data or not event.source: - return False - - if not AXUtilities.is_editable(event.source): - return False - if not AXUtilities.is_showing(event.source): - return False - if AXUtilities.is_focusable(event.source): - AXObject.clear_cache(event.source) - if not AXUtilities.is_focused(event.source): - return False - - lastKey, mods = self.lastKeyAndModifiers() - if lastKey == "Tab" and event.any_data != "\t": - return True - if lastKey == "Return" and event.any_data != "\n": - return True - if lastKey in ["Up", "Down", "Page_Up", "Page_Down"]: - return self.isEditableDescendantOfComboBox(event.source) - if not self.lastInputEventWasPrintableKey(): - return False - - string = AXText.get_all_text(event.source) - if string.endswith(event.any_data): - selection, start, end = self.selectedText(event.source) - if selection == event.any_data: - return True - if string == event.any_data and string.endswith(selection): - beginning = string[:string.find(selection)] - return beginning.lower().endswith(lastKey.lower()) - - return False - - def isSentenceDelimiter(self, currentChar: Any, previousChar: Any) -> bool: - """Returns True if we are positioned at the end of a sentence. - This is determined by checking if the current character is a - white space character and the previous character is one of the - normal end-of-sentence punctuation characters. - - Arguments: - - currentChar: the current character - - previousChar: the previous character - - Returns True if the given character is a sentence delimiter. - """ - - if currentChar == '\r' or currentChar == '\n': - return True - - return currentChar in self._script.whitespace \ - and previousChar in '!.?:;' - - def isWordDelimiter(self, character: Any) -> Any: - """Returns True if the given character is a word delimiter. - - Arguments: - - character: the character in question - - Returns True if the given character is a word delimiter. - """ - - return character in self._script.whitespace \ - or character in r'!*+,-./:;<=>?@[\]^_{|}' \ - or character == self._script.NO_BREAK_SPACE_CHARACTER - - def intersectingRegion(self, obj1: Any, obj2: Any, coordType: Any = None) -> int: - """Returns the extents of the intersection of obj1 and obj2.""" - - if coordType is None: - coordType = Atspi.CoordType.SCREEN - - if not AXObject.supports_component(obj1) or not AXObject.supports_component(obj2): - return 0, 0, 0, 0 - - try: - extents1 = Atspi.Component.get_extents(obj1, coordType) - extents2 = Atspi.Component.get_extents(obj2, coordType) - except Exception: - return 0, 0, 0, 0 - - return self.intersection(extents1, extents2) - - def intersection(self, extents1: Any, extents2: Any) -> int: - def _toTuple(extents: Any) -> tuple[int, int, int, int]: - if extents is None: - return 0, 0, 0, 0 - if hasattr(extents, "x") and hasattr(extents, "y") \ - and hasattr(extents, "width") and hasattr(extents, "height"): - return extents.x, extents.y, extents.width, extents.height - return extents - - extents1 = _toTuple(extents1) - extents2 = _toTuple(extents2) - x1, y1, width1, height1 = extents1 - x2, y2, width2, height2 = extents2 - - xPoints1 = range(x1, x1 + width1 + 1) - xPoints2 = range(x2, x2 + width2 + 1) - xIntersection = sorted(set(xPoints1).intersection(set(xPoints2))) - - yPoints1 = range(y1, y1 + height1 + 1) - yPoints2 = range(y2, y2 + height2 + 1) - yIntersection = sorted(set(yPoints1).intersection(set(yPoints2))) - - if not (xIntersection and yIntersection): - return 0, 0, 0, 0 - - x = xIntersection[0] - y = yIntersection[0] - width = xIntersection[-1] - x - height = yIntersection[-1] - y - - return x, y, width, height - - def containsRegion(self, extents1: Any, extents2: Any) -> Any: - return self.intersection(extents1, extents2) != (0, 0, 0, 0) - - def _extentsToTuple(self, extents: Any) -> int: - if extents is None: - return 0, 0, 0, 0 - if hasattr(extents, "x") and hasattr(extents, "y") \ - and hasattr(extents, "width") and hasattr(extents, "height"): - return extents.x, extents.y, extents.width, extents.height - return tuple(extents) - - def _allNamesForKeyCode(self, keycode: Any) -> Any: - keymap = Gdk.Keymap.get_default() - entries = keymap.get_entries_for_keycode(keycode)[-1] - return list(map(Gdk.keyval_name, set(entries))) - - def _lastKeyCodeAndModifiers(self) -> int: - if not isinstance(cthulhu_state.lastInputEvent, input_event.KeyboardEvent): - return 0, 0 - - event = cthulhu_state.lastNonModifierKeyEvent - if event: - return event.hw_code, event.modifiers - - return 0, 0 - - def lastKeyAndModifiers(self) -> Any: - """Convenience method which returns a tuple containing the event - string and modifiers of the last non-modifier key event or ("", 0) - if there is no such event.""" - - if isinstance(cthulhu_state.lastInputEvent, input_event.KeyboardEvent) \ - and cthulhu_state.lastNonModifierKeyEvent: - event = cthulhu_state.lastNonModifierKeyEvent - if event.keyval_name in ["BackSpace", "Delete"]: - eventStr = event.keyval_name - else: - eventStr = event.event_string - mods = cthulhu_state.lastInputEvent.modifiers - else: - eventStr = "" - mods = 0 - - return (eventStr, mods) - - def labelFromKeySequence(self, sequence: Any) -> Any: - """Turns a key sequence into a user-presentable label.""" - - try: - from gi.repository import Gtk - key, mods = Gtk.accelerator_parse(sequence) - newSequence = Gtk.accelerator_get_label(key, mods) - if newSequence and \ - (not newSequence.endswith('+') or newSequence.endswith('++')): - sequence = newSequence - except Exception: - if sequence.endswith(" "): - sequence += chnames.getCharacterName(" ") - sequence = sequence.replace("<", "") - sequence = sequence.replace(">", " ").strip() - - return keynames.localizeKeySequence(sequence) - - def mnemonicShortcutAccelerator(self, obj: Atspi.Accessible) -> Any: - """Gets the mnemonic, accelerator string and possibly shortcut - for the given object. These are based upon the first accessible - action for the object. - - Arguments: - - obj: the Accessible object - - Returns: list containing strings: [mnemonic, shortcut, accelerator] - """ - - try: - return self._script.generatorCache[self.KEY_BINDING][obj] - except Exception: - if self.KEY_BINDING not in self._script.generatorCache: - self._script.generatorCache[self.KEY_BINDING] = {} - - keybinding = AXObject.get_action_key_binding(obj, 0) - if not keybinding: - self._script.generatorCache[self.KEY_BINDING][obj] = ["", "", ""] - return self._script.generatorCache[self.KEY_BINDING][obj] - - # Action is a string in the format, where the mnemonic and/or - # accelerator can be missing. - # - # ;; - # - # The keybindings in should be separated by ":" - # - - bindingStrings = keybinding.split(';') - if len(bindingStrings) == 3: - mnemonic = bindingStrings[0] - fullShortcut = bindingStrings[1] - accelerator = bindingStrings[2] - elif len(bindingStrings) > 0: - mnemonic = "" - fullShortcut = bindingStrings[0] - try: - accelerator = bindingStrings[1] - except Exception: - accelerator = "" - else: - mnemonic = "" - fullShortcut = "" - accelerator = "" - - fullShortcut = fullShortcut.replace(":", " ").strip() - fullShortcut = self.labelFromKeySequence(fullShortcut) - mnemonic = self.labelFromKeySequence(mnemonic) - accelerator = self.labelFromKeySequence(accelerator) - - if self.KEY_BINDING not in self._script.generatorCache: - self._script.generatorCache[self.KEY_BINDING] = {} - - self._script.generatorCache[self.KEY_BINDING][obj] = \ - [mnemonic, fullShortcut, accelerator] - return self._script.generatorCache[self.KEY_BINDING][obj] - - def stringToKeysAndDict(self, string: Any) -> list[Any]: - """Converts a string made up of a series of :; pairs - into a dictionary of keys and values. Text before the colon is the - key and text afterwards is the value. The final semi-colon, if - found, is ignored. - - Arguments: - - string: the string of tokens containing :; pairs. - - Returns a list containing two items: - A list of the keys in the order they were extracted from the - string and a dictionary of key/value items. - """ - - try: - items = [s.strip() for s in string.split(";")] - items = [item for item in items if len(item.split(':')) == 2] - keys = [item.split(':')[0].strip() for item in items] - dictionary = dict([item.split(':') for item in items]) - except Exception: - return [], {} - - return [keys, dictionary] - - def textForValue(self, obj: Atspi.Accessible) -> Any: - """Returns the text to be displayed for the object's current value. - - Arguments: - - obj: the Accessible object that may or may not have a value. - - Returns a string representing the value. - """ - - attrs = self.objectAttributes(obj, False) - valuetext = attrs.get("valuetext") - if valuetext: - return valuetext - - if not AXObject.supports_value(obj): - return "" - - currentValue = AXValue.get_current_value(obj) - - # "The reports of my implementation are greatly exaggerated." - maxValue = AXValue.get_maximum_value(obj) - minValue = AXValue.get_minimum_value(obj) - try: - minIncrement = Atspi.Value.get_minimum_increment(obj) - except Exception as error: - minIncrement = (maxValue - minValue) / 100.0 - tokens = ["SCRIPT UTILITIES: Could not get minimum increment for", obj, ":", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if minIncrement != 0.0: - try: - decimalPlaces = math.ceil(max(0, -math.log10(minIncrement))) - except ValueError as error: - tokens = ["SCRIPT UTILITIES: Could not calculate decimal places for", - obj, ":", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return "" - elif abs(currentValue) < 1: - decimalPlaces = 1 - else: - decimalPlaces = 0 - - formatter = "%%.%df" % decimalPlaces - return formatter % currentValue - - def unicodeValueString(self, character: Any) -> Any: - """ Returns a four hex digit representation of the given character - - Arguments: - - The character to return representation - - Returns a string representaition of the given character unicode vlue - """ - - try: - return f"{ord(character):04x}" - except Exception: - debug.printException(debug.LEVEL_WARNING) - return "" - - def getLinesForRange(self, obj: Atspi.Accessible, startOffset: Any, endOffset: Any) -> list[Any]: - if not AXObject.supports_text(obj): - return [] - - lines = [] - offset = startOffset - maxOffset = min(endOffset, AXText.get_character_count(obj)) - while offset < maxOffset: - line, start, end = AXText.get_line_at_offset(obj, offset) - if line and (line, start, end) not in lines: - lines.append((line, start, end)) - offset = max(end, offset + 1) - - return lines - - def getLineContentsAtOffset(self, obj: Atspi.Accessible, offset: Any, layoutMode: Any = True, useCache: Any = True) -> list[Any]: - return [] - - def get_objectContentsAtOffset(self, obj: Atspi.Accessible, offset: Any = 0, useCache: Any = True) -> list[Any]: - return [] - - def previousContext(self, obj: Optional[Atspi.Accessible] = None, offset: int = -1, skipSpace: Any = False) -> Any: - if not obj: - obj, offset = self.getCaretContext() - - return obj, offset - 1 - - def nextContext(self, obj: Optional[Atspi.Accessible] = None, offset: int = -1, skipSpace: Any = False) -> Any: - if not obj: - obj, offset = self.getCaretContext() - - return obj, offset + 1 - - def lastContext(self, root: Any) -> Any: - offset = 0 - text = self.queryNonEmptyText(root) - if text: - offset = AXText.get_character_count(root) - 1 - - return root, offset - - def getHyperlinkRange(self, obj: Atspi.Accessible) -> int: - """Returns the text range in parent associated with obj.""" - - start = AXHypertext.get_link_start_offset(obj) - end = AXHypertext.get_link_end_offset(obj) - if start < 0 or end < 0: - tokens = ["SCRIPT UTILITIES: Exception getting hyperlink indices for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return -1, -1 - - return start, end - - def selectedChildren(self, obj: Atspi.Accessible) -> Any: - children = AXSelection.get_selected_children(obj) - if children: - return children - - msg = "SCRIPT UTILITIES: Selected children not retrieved via selection interface." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - role = AXObject.get_role(obj) - if role == Atspi.Role.MENU and not children: - children = self.findAllDescendants(obj, AXUtilities.is_selected) - - if role == Atspi.Role.COMBO_BOX \ - and children and AXObject.get_role(children[0]) == Atspi.Role.MENU: - children = self.selectedChildren(children[0]) - name = AXObject.get_name(obj) - if not children and name: - def pred(x: Atspi.Accessible) -> bool: - return AXObject.get_name(x) == name - - children = self.findAllDescendants(obj, pred) - - return children - - def speakSelectedCellRange(self, obj: Atspi.Accessible) -> bool: - return False - - def getSelectionContainer(self, obj: Atspi.Accessible) -> Optional[Any]: - if not obj: - return None - - if AXObject.supports_selection(obj): - return obj - - rolemap = { - Atspi.Role.CANVAS: [Atspi.Role.LAYERED_PANE], - Atspi.Role.ICON: [Atspi.Role.LAYERED_PANE], - Atspi.Role.LIST_ITEM: [Atspi.Role.LIST_BOX], - Atspi.Role.TREE_ITEM: [Atspi.Role.TREE, Atspi.Role.TREE_TABLE], - Atspi.Role.TABLE_CELL: [Atspi.Role.TABLE, Atspi.Role.TREE_TABLE], - Atspi.Role.TABLE_ROW: [Atspi.Role.TABLE, Atspi.Role.TREE_TABLE], - } - - matchingRoles = rolemap.get(AXObject.get_role(obj)) - def isMatch(x: Atspi.Accessible) -> bool: - if matchingRoles and AXObject.get_role(x) not in matchingRoles: - return False - return AXObject.supports_selection(x) - - return AXObject.find_ancestor(obj, isMatch) - - def selectableChildCount(self, obj: Atspi.Accessible) -> int: - if not AXObject.supports_selection(obj): - return 0 - - if AXObject.supports_table(obj): - rows, cols = self.rowAndColumnCount(obj) - return max(0, rows) - - rolemap = { - Atspi.Role.LIST_BOX: [Atspi.Role.LIST_ITEM], - Atspi.Role.TREE: [Atspi.Role.TREE_ITEM], - } - - role = AXObject.get_role(obj) - if role not in rolemap: - return AXObject.get_child_count(obj) - - def isMatch(x: Atspi.Accessible) -> bool: - return AXObject.get_role(x) in rolemap.get(role) - - return len(self.findAllDescendants(obj, isMatch)) - - def selectedChildCount(self, obj: Atspi.Accessible) -> Any: - if AXObject.supports_table(obj): - count = AXTable.get_selected_row_count(obj) - if count: - return count - - return AXSelection.get_selected_child_count(obj) - - def popupMenuFor(self, obj: Atspi.Accessible) -> Optional[Any]: - if obj is None: - return None - - menus = [child for child in AXObject.iter_children(obj, AXUtilities.is_menu)] - for menu in menus: - if AXUtilities.is_enabled(menu): - return menu - - return None - - def isButtonWithPopup(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_button(obj) and AXUtilities.has_popup(obj) - - def isPopupMenuForCurrentItem(self, obj: Atspi.Accessible) -> bool: - if obj == cthulhu_state.locusOfFocus: - return False - - if not AXUtilities.is_menu(obj): - return False - - name = AXObject.get_name(obj) - if not name: - return False - - return name == AXObject.get_name(cthulhu_state.locusOfFocus) - - def isMenuWithNoSelectedChild(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_menu(obj) and not self.selectedChildCount(obj) - - def isMenuButton(self, obj: Atspi.Accessible) -> bool: - return AXUtilities.is_button(obj) and self.popupMenuFor(obj) is not None - - def inMenu(self, obj: Optional[Atspi.Accessible] = None) -> bool: - obj = obj or cthulhu_state.locusOfFocus - if obj is None: - return False - - if AXUtilities.is_menu_item_of_any_kind(obj) or AXUtilities.is_menu(obj): - return True - - if AXUtilities.is_panel(obj) or AXUtilities.is_separator(obj): - return AXObject.find_ancestor(obj, AXUtilities.is_menu) is not None - - return False - - def inContextMenu(self, obj: Optional[Atspi.Accessible] = None) -> bool: - obj = obj or cthulhu_state.locusOfFocus - if not self.inMenu(obj): - return False - - return AXObject.find_ancestor(obj, self.isContextMenu) is not None - - def _contextMenuParentRoles(self) -> Any: - return Atspi.Role.FRAME, Atspi.Role.WINDOW - - def isContextMenu(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_menu(obj): - return False - - return AXObject.get_role(AXObject.get_parent(obj)) in self._contextMenuParentRoles() - - def isTopLevelMenu(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_menu(obj): - return False - return AXObject.get_parent(obj) == self.topLevelObject(obj) - - def isSingleLineAutocompleteEntry(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_entry(obj): - return False - if not AXUtilities.supports_autocompletion(obj): - return False - return AXUtilities.is_single_line(obj) - - def isEntryCompletionPopupItem(self, obj: Atspi.Accessible) -> bool: - return False - - def getEntryForEditableComboBox(self, obj: Atspi.Accessible) -> Optional[Any]: - if not AXUtilities.is_combo_box(obj): - return None - - children = [x for x in AXObject.iter_children(obj, self.isEditableTextArea)] - if len(children) == 1: - return children[0] - - return None - - def isEditableComboBox(self, obj: Atspi.Accessible) -> bool: - return self.getEntryForEditableComboBox(obj) is not None - - def isEditableDescendantOfComboBox(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_editable(obj): - return False - - return AXObject.find_ancestor(obj, AXUtilities.is_combo_box) is not None - - def getComboBoxValue(self, obj: Atspi.Accessible) -> Any: - if not AXObject.get_child_count(obj): - return self.displayedText(obj) - - entry = self.getEntryForEditableComboBox(obj) - if entry: - return self.displayedText(entry) - - selected = self._script.utilities.selectedChildren(obj) - selected = selected or self._script.utilities.selectedChildren(AXObject.get_child(obj, 0)) - if len(selected) == 1: - return selected[0].name or self.displayedText(selected[0]) - - return self.displayedText(obj) - - def isPopOver(self, obj: Atspi.Accessible) -> bool: - return False - - def isNonModalPopOver(self, obj: Atspi.Accessible) -> bool: - if not self.isPopOver(obj): - return False - return not AXUtilities.is_modal(obj) - - def isUselessPanel(self, obj: Atspi.Accessible) -> bool: - return False - - def rgbFromString(self, attributeValue: Any) -> Any: - regex = re.compile(r"rgb|[^\w,]", re.IGNORECASE) - string = re.sub(regex, "", attributeValue) - red, green, blue = string.split(",") - - return int(red), int(green), int(blue) - - def isClickableElement(self, obj: Atspi.Accessible) -> bool: - return False - - def hasLongDesc(self, obj: Atspi.Accessible) -> bool: - return False - - def hasDetails(self, obj: Atspi.Accessible) -> bool: - return False - - def isDetails(self, obj: Atspi.Accessible) -> bool: - return False - - def detailsFor(self, obj: Atspi.Accessible) -> list[Any]: - return [] - - def hasVisibleCaption(self, obj: Atspi.Accessible) -> bool: - return False - - def popupType(self, obj: Atspi.Accessible) -> str: - return '' - - def headingLevel(self, obj: Atspi.Accessible) -> int: - if not AXUtilities.is_heading(obj): - return 0 - - attrs = self.objectAttributes(obj) - - try: - value = int(attrs.get('level', '0')) - except ValueError: - tokens = ["SCRIPT UTILITIES: Exception getting value for", obj, "(", attrs, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return 0 - - return value - - def hasMeaningfulToggleAction(self, obj: Atspi.Accessible) -> Any: - return AXObject.has_action(obj, "toggle") \ - or AXObject.has_action(obj, object_properties.ACTION_TOGGLE) - - def containingTableHeader(self, obj: Atspi.Accessible) -> Any: - if AXUtilities.is_table_header(obj): - return obj - - return AXObject.find_ancestor(obj, AXUtilities.is_table_header) - - def columnHeadersForCell(self, obj: Atspi.Accessible) -> Any: - result = self._columnHeadersForCell(obj) - # There either are no headers, or we got all of them. - if len(result) != 1: - return result - - others = self._columnHeadersForCell(result[0]) - while len(others) == 1 and others[0] not in result: - result.insert(0, others[0]) - others = self._columnHeadersForCell(result[0]) - - return result - - def _columnHeadersForCell(self, obj: Atspi.Accessible) -> list[Any]: - if not obj: - msg = "SCRIPT UTILITIES: Attempted to get column headers for null cell" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return [] - - return AXTable.get_column_headers(obj) - - def rowHeadersForCell(self, obj: Atspi.Accessible) -> Any: - result = self._rowHeadersForCell(obj) - # There either are no headers, or we got all of them. - if len(result) != 1: - return result - - others = self._rowHeadersForCell(result[0]) - while len(others) == 1 and others[0] not in result: - result.insert(0, others[0]) - others = self._rowHeadersForCell(result[0]) - - return result - - def _rowHeadersForCell(self, obj: Atspi.Accessible) -> list[Any]: - if not obj: - msg = "SCRIPT UTILITIES: Attempted to get row headers for null cell" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return [] - - return AXTable.get_row_headers(obj) - - def columnHeaderForCell(self, obj: Atspi.Accessible) -> Any: - headers = self.columnHeadersForCell(obj) - if headers: - return headers[0] - - return None - - def rowHeaderForCell(self, obj: Atspi.Accessible) -> Any: - headers = self.rowHeadersForCell(obj) - if headers: - return headers[0] - - return None - - def _shouldUseTableCellInterfaceForCoordinates(self) -> bool: - return True - - def coordinatesForCell(self, obj: Atspi.Accessible, preferAttribute: Any = True, findCellAncestor: Any = False) -> Any: - return AXTable.get_cell_coordinates( - obj, prefer_attribute=preferAttribute, find_cell=findCellAncestor) - - def rowAndColumnSpan(self, obj: Atspi.Accessible) -> int: - if not AXUtilities.is_table_cell_or_header(obj): - return -1, -1 - return AXTable.get_cell_spans(obj, prefer_attribute=True) - - def setSizeUnknown(self, obj: Atspi.Accessible) -> Any: - return AXUtilities.is_indeterminate(obj) - - def rowOrColumnCountUnknown(self, obj: Atspi.Accessible) -> Any: - return AXUtilities.is_indeterminate(obj) - - def rowAndColumnCount(self, obj: Atspi.Accessible, preferAttribute: Any = True) -> int: - if not AXObject.supports_table(obj): - return -1, -1 - - rows = AXTable.get_row_count(obj, prefer_attribute=preferAttribute) - cols = AXTable.get_column_count(obj, prefer_attribute=preferAttribute) - return rows, cols - - def _objectBoundsMightBeBogus(self, obj: Atspi.Accessible) -> bool: - return False - - def _objectMightBeBogus(self, obj: Atspi.Accessible) -> bool: - return False - - def containsPoint(self, obj: Atspi.Accessible, x: Any, y: Any, coordType: Any, margin: Any = 2) -> bool: - if self._objectBoundsMightBeBogus(obj) \ - and self.textAtPoint(obj, x, y, coordType) == ("", 0, 0): - return False - - if self._objectMightBeBogus(obj): - return False - - if not AXObject.supports_component(obj): - return False - - if coordType is None: - coordType = Atspi.CoordType.SCREEN - - try: - if Atspi.Component.contains(obj, x, y, coordType): - return True - - x1, y1 = x + margin, y + margin - if Atspi.Component.contains(obj, x1, y1, coordType): - tokens = ["SCRIPT UTILITIES: ", obj, f"contains ({x1},{y1}); not ({x},{y}"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - except Exception: - return False - - return False - - def _boundsIncludeChildren(self, obj: Atspi.Accessible) -> bool: - if obj is None: - return False - - if self.hasNoSize(obj): - return False - - return not (AXUtilities.is_menu(obj) or AXUtilities.is_page_tab(obj)) - - def treatAsEntry(self, obj: Atspi.Accessible) -> bool: - return False - - def _treatAsLeafNode(self, obj: Atspi.Accessible) -> bool: - if obj is None or AXObject.is_dead(obj): - return False - - if not AXObject.get_child_count(obj): - return True - - if AXUtilities.is_autocomplete(obj) or AXUtilities.is_table_row(obj): - return False - - if AXUtilities.is_combo_box(obj): - return AXObject.find_descendant(obj, AXUtilities.is_entry) is None - - if AXUtilities.is_link(obj) and AXObject.get_name(obj): - return True - - if AXUtilities.is_expandable(obj): - return not AXUtilities.is_expanded(obj) - - if AXUtilities.is_button(obj): - return True - - return False - - def accessibleAtPoint(self, root: Any, x: Any, y: Any, coordType: Any = None) -> Optional[Any]: - if self.isHidden(root): - return None - - if not AXObject.supports_component(root): - tokens = ["SCRIPT UTILITIES:", root, "does not support component interface"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - if coordType is None: - coordType = Atspi.CoordType.SCREEN - - try: - result = Atspi.Component.get_accessible_at_point(root, x, y, coordType) - except Exception: - tokens = ["SCRIPT UTILITIES: Exception getting accessible at point for", root] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return None - - tokens = ["SCRIPT UTILITIES: ", result, "is descendant of", root, f"at ({x}, {y})"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return result - - def descendantAtPoint(self, root: Any, x: Any, y: Any, coordType: Any = None) -> Optional[Any]: - if not root: - return None - - if not self.isShowingAndVisible(root): - return None - - if coordType is None: - coordType = Atspi.CoordType.SCREEN - - if self.containsPoint(root, x, y, coordType): - if self._treatAsLeafNode(root) or not self._boundsIncludeChildren(root): - return root - elif self._treatAsLeafNode(root) or self._boundsIncludeChildren(root): - return None - - if AXObject.supports_table(root): - child = self.accessibleAtPoint(root, x, y, coordType) - if child and child != root: - cell = self.descendantAtPoint(child, x, y, coordType) - if cell: - return cell - return child - - candidates_showing = [] - candidates = [] - for child in AXObject.iter_children(root): - obj = self.descendantAtPoint(child, x, y, coordType) - if obj: - return obj - if not self.containsPoint(child, x, y, coordType): - continue - if self.queryNonEmptyText(child): - string = AXText.get_all_text(child) - if re.search(r"[^\ufffc\s]", string): - candidates.append(child) - if AXUtilities.is_showing(child): - candidates_showing.append(child) - - if len(candidates_showing) == 1: - return candidates_showing[0] - if len(candidates) == 1: - # It should have had state "showing" actually - return candidates[0] - - return None - - def _adjustPointForObj(self, obj: Atspi.Accessible, x: Any, y: Any, coordType: Any) -> Any: - return x, y - - def isMultiParagraphObject(self, obj: Atspi.Accessible) -> bool: - if not obj: - return False - - if not AXObject.supports_text(obj): - return False - - string = AXText.get_all_text(obj) - chunks = list(filter(lambda x: x.strip(), string.split("\n\n"))) - return len(chunks) > 1 - - def getWordAtOffsetAdjustedForNavigation(self, obj: Atspi.Accessible, offset: Any = None) -> str: - if not AXObject.supports_text(obj): - return "", 0, 0 - - if offset is None: - offset = AXText.get_caret_offset(obj) - - word, start, end = self.getWordAtOffset(obj, offset) - prevObj, prevOffset = self._script.pointOfReference.get( - "penultimateCursorPosition", (None, -1)) - if prevObj != obj: - return word, start, end - - # If we're in an ongoing series of native navigation-by-word commands, just present the - # newly-traversed string. - prevWord, prevStart, prevEnd = self.getWordAtOffset(prevObj, prevOffset) - if self._script.pointOfReference.get("lastTextUnitSpoken") == "word": - if self.lastInputEventWasPrevWordNav(): - start = offset - end = prevOffset - elif self.lastInputEventWasNextWordNav(): - start = prevOffset - end = offset - - word = AXText.get_substring(obj, start, end) - debugString = word.replace("\n", "\\n") - msg = ( - f"SCRIPT UTILITIES: Adjusted word at offset {offset} for ongoing word nav is " - f"'{debugString}' ({start}-{end})" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return word, start, end - - # Otherwise, attempt some smarts so that the user winds up with the same presentation - # they would get were this an ongoing series of native navigation-by-word commands. - if self.lastInputEventWasPrevWordNav(): - # If we moved left via native nav, this should be the start of a native-navigation - # word boundary, regardless of what ATK/AT-SPI2 tells us. - start = offset - - # The ATK/AT-SPI2 word typically ends in a space; if the ending is neither a space, - # nor an alphanumeric character, then suspect that character is a navigation boundary - # where we would have landed before via the native previous word command. - if not (word[-1].isspace() or word[-1].isalnum()): - end -= 1 - - elif self.lastInputEventWasNextWordNav(): - # If we moved right via native nav, this should be the end of a native-navigation - # word boundary, regardless of what ATK/AT-SPI2 tells us. - end = offset - - # This suggests we just moved to the end of the previous word. - if word != prevWord and prevStart < offset <= prevEnd: - start = prevStart - - # If the character to the left of our present position is neither a space, nor - # an alphanumeric character, then suspect that character is a navigation boundary - # where we would have landed before via the native next word command. - lastChar = AXText.get_substring(obj, offset - 1, offset) - if not (lastChar.isspace() or lastChar.isalnum()): - start = offset - 1 - - word = AXText.get_substring(obj, start, end) - - # We only want to present the newline character when we cross a boundary moving from one - # word to another. If we're in the same word, strip it out. - if "\n" in word and word == prevWord: - if word.startswith("\n"): - start += 1 - elif word.endswith("\n"): - end -= 1 - word = AXText.get_substring(obj, start, end) - - word = AXText.get_substring(obj, start, end) - debugString = word.replace("\n", "\\n") - msg = ( - f"SCRIPT UTILITIES: Adjusted word at offset {offset} for new word nav is " - f"'{debugString}' ({start}-{end})" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return word, start, end - - def getWordAtOffset(self, obj: Atspi.Accessible, offset: Any = None) -> str: - if not AXObject.supports_text(obj): - return "", 0, 0 - - if offset is None: - offset = AXText.get_caret_offset(obj) - - word, start, end = AXText.get_word_at_offset(obj, offset) - debugString = word.replace("\n", "\\n") - msg = ( - f"SCRIPT UTILITIES: Word at offset {offset} is " - f"'{debugString}' ({start}-{end})" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return word, start, end - - def textAtPoint(self, obj: Atspi.Accessible, x: Any, y: Any, coordType: Any = None, boundary: Any = None) -> str: - text = self.queryNonEmptyText(obj) - if not text: - return "", 0, 0 - - if coordType is None: - coordType = Atspi.CoordType.SCREEN - - if boundary is None: - boundary = Atspi.TextBoundaryType.LINE_START - - x, y = self._adjustPointForObj(obj, x, y, coordType) - try: - offset = Atspi.Text.get_offset_at_point(obj, x, y, coordType) - except Exception: - return "", 0, 0 - - if not 0 <= offset < AXText.get_character_count(obj): - return "", 0, 0 - - if boundary == Atspi.TextBoundaryType.CHAR: - string, start, end = AXText.get_character_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.WORD_START: - string, start, end = AXText.get_word_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.LINE_START: - string, start, end = AXText.get_line_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.SENTENCE_START: - string, start, end = AXText.get_sentence_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.PARAGRAPH_START: - string, start, end = AXText.get_paragraph_at_offset(obj, offset) - else: - try: - result = Atspi.Text.get_string_at_offset(obj, offset, boundary) - except Exception: - return "", 0, 0 - if result is None: - return "", 0, 0 - string = result.content - start = result.start_offset - end = result.end_offset - - if not string: - return "", start, end - - if boundary == Atspi.TextBoundaryType.WORD_START and not string.strip(): - return "", 0, 0 - - try: - extents = Atspi.Text.get_range_extents(obj, start, end, coordType) - except Exception: - return "", 0, 0 - - if not self.containsRegion(extents, (x, y, 1, 1)) and string != "\n": - return "", 0, 0 - - if not string.endswith("\n") or string == "\n": - return string, start, end - - if boundary == Atspi.TextBoundaryType.CHAR: - return string, start, end - - char = self.textAtPoint(obj, x, y, coordType, Atspi.TextBoundaryType.CHAR) - if char[0] == "\n" and char[2] - char[1] == 1: - return char - - return string, start, end - - def visibleRows(self, obj: Atspi.Accessible, boundingbox: Any) -> list[Any]: - if not AXObject.supports_table(obj): - return [] - - nRows = AXTable.get_row_count(obj, prefer_attribute=False) - if nRows < 0: - return [] - - tokens = ["SCRIPT UTILITIES: ", obj, f"has {nRows} rows"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - x, y, width, height = boundingbox.x, boundingbox.y, boundingbox.width, boundingbox.height - cell = self.descendantAtPoint(obj, x, y + 1) - row, col = self.coordinatesForCell(cell) - startIndex = max(0, row) - tokens = ["SCRIPT UTILITIES: First cell:", cell, f"(row: {row}"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # Just in case the row above is a static header row in a scrollable table. - if cell and AXObject.supports_component(cell): - try: - extents = Atspi.Component.get_extents(cell, Atspi.CoordType.SCREEN) - cell = self.descendantAtPoint(obj, x, y + extents.height + 1) - row, col = self.coordinatesForCell(cell) - nextIndex = max(startIndex, row) - tokens = ["SCRIPT UTILITIES: Next cell:", cell, f"(row: {row}"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - except Exception: - nextIndex = startIndex - else: - nextIndex = startIndex - - cell = self.descendantAtPoint(obj, x, y + height - 1) - row, col = self.coordinatesForCell(cell) - tokens = ["SCRIPT UTILITIES: Last cell:", cell, f"(row: {row}"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if row == -1: - row = nRows - endIndex = row - - rows = list(range(nextIndex, endIndex)) - if startIndex not in rows: - rows.insert(0, startIndex) - - return rows - - def getVisibleTableCells(self, obj: Atspi.Accessible) -> list[Any]: - if not AXObject.supports_table(obj): - return [] - - if not AXObject.supports_component(obj): - return [] - - try: - extents = Atspi.Component.get_extents(obj, Atspi.CoordType.SCREEN) - except Exception: - tokens = ["SCRIPT UTILITIES: Exception getting extents of", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - rows = self.visibleRows(obj, extents) - if not rows: - return [] - - colStartIndex, colEndIndex = self._getTableRowRange(obj) - if colStartIndex == colEndIndex: - return [] - - cells = [] - for col in range(colStartIndex, colEndIndex): - try: - colHeader = Atspi.Table.get_column_header(obj, col) - if colHeader: - cells.append(colHeader) - except Exception: - pass - for row in rows: - try: - cell = Atspi.Table.get_accessible_at(obj, row, col) - except Exception: - continue - if cell and self.isOnScreen(cell): - cells.append(cell) - - return cells - - def _getTableRowRange(self, obj: Atspi.Accessible) -> Any: - rowCount, columnCount = self.rowAndColumnCount(obj) - startIndex, endIndex = 0, columnCount - if not self.isSpreadSheetCell(obj): - return startIndex, endIndex - - parent = self.getTable(obj) - if not parent or not AXObject.supports_component(parent): - tokens = ["SCRIPT UTILITIES:", parent, "does not support component interface"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return startIndex, endIndex - - try: - extents = Atspi.Component.get_extents(parent, Atspi.CoordType.SCREEN) - x, y, width, height = extents.x, extents.y, extents.width, extents.height - except Exception: - tokens = ["SCRIPT UTILITIES: Exception getting extents of", parent] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return startIndex, endIndex - - try: - cell = Atspi.Component.get_accessible_at_point(parent, x+1, y, Atspi.CoordType.SCREEN) - if cell: - row, column = self.coordinatesForCell(cell) - startIndex = column - except Exception: - pass - - try: - cell = Atspi.Component.get_accessible_at_point(parent, x+width-1, y, Atspi.CoordType.SCREEN) - if cell: - row, column = self.coordinatesForCell(cell) - endIndex = column + 1 - except Exception: - pass - - return startIndex, endIndex - - def getShowingCellsInSameRow(self, obj: Atspi.Accessible, forceFullRow: Any = False) -> list[Any]: - parent = self.getTable(obj) - if not parent or not AXObject.supports_table(parent): - tokens = ["SCRIPT UTILITIES: Exception querying table interface of", parent] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - row, column = self.coordinatesForCell(obj, False) - if row == -1: - return [] - - if forceFullRow: - startIndex, endIndex = 0, AXTable.get_column_count(parent, prefer_attribute=False) - else: - startIndex, endIndex = self._getTableRowRange(obj) - if startIndex == endIndex: - return [] - - cells = [] - for i in range(startIndex, endIndex): - cell = AXTable.get_cell_at(parent, row, i) - if cell and AXUtilities.is_showing(cell): - cells.append(cell) - - return cells - - def cellForCoordinates(self, obj: Atspi.Accessible, row: Any, column: Any, showingOnly: Any = False) -> Optional[Any]: - if not AXObject.supports_table(obj): - return None - - cell = AXTable.get_cell_at(obj, row, column) - if not showingOnly: - return cell - - if AXUtilities.is_showing(cell): - return cell - - return None - - def isLastCell(self, obj: Atspi.Accessible) -> bool: - if not AXUtilities.is_table_cell(obj): - return False - - table = AXTable.get_table(obj) - if table is None: - return False - - row, col = self.coordinatesForCell(obj) - rows = AXTable.get_row_count(table, prefer_attribute=False) - cols = AXTable.get_column_count(table, prefer_attribute=False) - return row + 1 == rows and col + 1 == cols - - def isNonUniformTable(self, obj: Atspi.Accessible, maxRows: Any = 25, maxCols: Any = 25) -> bool: - if not AXObject.supports_table(obj): - return False - - return AXTable.is_non_uniform_table(obj, maxRows, maxCols) - - def isShowingAndVisible(self, obj: Atspi.Accessible) -> bool: - if AXUtilities.is_showing(obj) and AXUtilities.is_visible(obj): - return True - - # NOTE: This likely belongs in toolkit scripts, but it's shared across - # toolkits (Gtk, Firefox, Chrome, LO, Eclipse) and might be an AT-SPI2 - # issue, so we keep it here for now. - if self._is_open_menu_bar_menu_role(obj): - tokens = ["HACK: Treating", obj, "as showing and visible"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - def _is_open_menu_bar_menu_role(self, obj: Atspi.Accessible) -> bool: - if AXObject.get_role(obj) not in self.MENU_ROLES_IN_OPEN_MENU: - return False - return self.isInOpenMenuBarMenu(obj) - - def isZombie(self, obj: Atspi.Accessible) -> bool: - index = AXObject.get_index_in_parent(obj) - role = AXObject.get_role(obj) - tokens = ["SCRIPT UTILITIES: ", obj, "is zombie:"] - if index == -1 and role not in self.ZOMBIE_TOP_LEVEL_ROLES: - tokens.append("index is -1") - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - if AXUtilities.is_defunct(obj): - tokens.append("is defunct") - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - if AXUtilities.is_invalid_state(obj): - tokens.append("has invalid state") - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - if AXUtilities.is_invalid_role(obj): - tokens.append("has invalid role") - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - def findReplicant(self, root: Any, obj: Atspi.Accessible) -> Optional[Any]: - tokens = ["SCRIPT UTILITIES: Searching for replicant for", obj, "in", root] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if not (root and obj): - return None - - if AXUtilities.is_table(root) or AXUtilities.is_embedded(root): - return None - - def isSame(x: Atspi.Accessible) -> bool: - return self.isSameObject(x, obj, comparePaths=True, ignoreNames=True) - - if isSame(root): - replicant = root - else: - replicant = AXObject.find_descendant(root, isSame) - - tokens = ["HACK: Returning", replicant, "as replicant for Zombie", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return replicant - - def getFunctionalChildCount(self, obj: Atspi.Accessible) -> Any: - nodeParents = AXUtilitiesRelation.get_is_node_parent_of(obj) - if nodeParents: - return len(nodeParents) - return AXObject.get_child_count(obj) - - def getFunctionalChildren(self, obj: Atspi.Accessible, sibling: Any = None) -> Any: - result = AXUtilitiesRelation.get_is_node_parent_of(obj) - if result: - return result - if self.isDescriptionListTerm(sibling): - return self.descriptionListTerms(obj) - if self.isDescriptionListDescription(sibling): - return self.valuesForTerm(self.termForValue(sibling)) - return [x for x in AXObject.iter_children(obj)] - - def getFunctionalParent(self, obj: Atspi.Accessible) -> Any: - nodeChildren = AXUtilitiesRelation.get_is_node_child_of(obj) - if nodeChildren: - return nodeChildren[0] - return AXObject.get_parent(obj) - - def getPositionAndSetSize(self, obj: Atspi.Accessible, **args: Any) -> int: - if obj is None: - return -1, -1 - - if AXUtilities.is_table_cell(obj) and args.get("readingRow"): - row, col = self.coordinatesForCell(obj) - rowcount, colcount = self.rowAndColumnCount(self.getTable(obj)) - return row, rowcount - - if AXUtilities.is_combo_box(obj): - selected = self.selectedChildren(obj) - if selected: - obj = selected[0] - else: - def isMenu(x: Atspi.Accessible) -> bool: - return AXUtilities.is_menu(x) or AXUtilities.is_list_box(x) - - selected = self.selectedChildren(AXObject.find_descendant(obj, isMenu)) - if selected: - obj = selected[0] - else: - return -1, -1 - - parent = self.getFunctionalParent(obj) - childCount = self.getFunctionalChildCount(parent) - if childCount > 100 and parent == AXObject.get_parent(obj): - return AXObject.get_index_in_parent(obj), childCount - - siblings = self.getFunctionalChildren(parent, obj) - if len(siblings) < 100 and not AXObject.find_ancestor(obj, AXUtilities.is_combo_box): - layoutRoles = [Atspi.Role.SEPARATOR, Atspi.Role.TEAROFF_MENU_ITEM] - - def isNotLayoutOnly(x: Atspi.Accessible) -> bool: - return not (self.isZombie(x) or AXObject.get_role(x) in layoutRoles) - - siblings = list(filter(isNotLayoutOnly, siblings)) - - if not (siblings and obj in siblings): - return -1, -1 - - if self.isFocusableLabel(obj): - siblings = list(filter(self.isFocusableLabel, siblings)) - if len(siblings) == 1: - return -1, -1 - - position = siblings.index(obj) - setSize = len(siblings) - return position, setSize - - def termForValue(self, obj: Atspi.Accessible) -> Optional[Any]: - if not self.isDescriptionListDescription(obj): - return None - - while obj and not self.isDescriptionListTerm(obj): - obj = AXObject.get_previous_sibling(obj) - - return obj - - def valuesForTerm(self, obj: Atspi.Accessible) -> list[Any]: - if not self.isDescriptionListTerm(obj): - return [] - - values = [] - obj = AXObject.get_next_sibling(obj) - while obj and self.isDescriptionListDescription(obj): - values.append(obj) - obj = AXObject.get_next_sibling(obj) - - return values - - def getValueCountForTerm(self, obj: Atspi.Accessible) -> Any: - return len(self.valuesForTerm(obj)) - - def getRoleDescription(self, obj: Atspi.Accessible, isBraille: Any = False) -> str: - return "" - - def getCachedTextSelection(self, obj: Atspi.Accessible) -> Any: - cached = self._getCachedSelectionData(obj) - start, end, string = cached['start'], cached['end'], cached['string'] - tokens = ["SCRIPT UTILITIES: Cached selection for", obj, f"is '{string}' ({start}, {end})"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return start, end, string - - def updateCachedTextSelection(self, obj: Atspi.Accessible) -> Any: - if not AXObject.supports_text(obj): - tokens = ["SCRIPT UTILITIES:", obj, "doesn't implement AtspiText"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._cacheSelectionData(obj, {'ranges': [], 'start': 0, 'end': 0, 'string': ''}) - return - - if self._script.pointOfReference.get('entireDocumentSelected'): - selectedText, selectedStart, selectedEnd = self.allSelectedText(obj) - if not selectedText: - self._script.pointOfReference['entireDocumentSelected'] = False - self._getSelectionState()['textSelections'] = {} - - snapshot = self._getSelectionAdapter().refresh_snapshot(obj) - selectionData = self._getSelectionData(obj, snapshot) - if snapshot.is_authoritative and not snapshot.ranges: - self._script.pointOfReference['entireDocumentSelected'] = False - self._getSelectionState()['textSelections'] = {} - - tokens = [ - "SCRIPT UTILITIES: New selection for", - obj, - f"is '{selectionData['string']}' ({selectionData['start']}, {selectionData['end']})", - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._cacheSelectionData(obj, selectionData) - - def _getSingleSelectionText(self, obj: Atspi.Accessible) -> Any: - # NOTE: Does not handle multiple non-contiguous selections. - string, start, end = AXText.get_selected_text(obj) - if string: - string = self._getSelectionTextFragment(obj, start, end) - return string, start, end - - def onClipboardContentsChanged(self, *args: Any) -> None: - script = cthulhu_state.activeScript - if not script: - msg = "SCRIPT UTILITIES: Clipboard contents changed with no active script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if time.time() - Utilities._last_clipboard_update < 0.05: - msg = "SCRIPT UTILITIES: Clipboard contents change believed to be duplicate" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - Utilities._last_clipboard_update = time.time() - tokens = ["SCRIPT UTILITIES: Clipboard contents changed for", script] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - script.onClipboardContentsChanged(*args) - - def connectToClipboard(self) -> None: - if self._clipboardHandlerId is not None: - return - - clipboard = Gtk.Clipboard.get(Gdk.Atom.intern("CLIPBOARD", False)) - self._clipboardHandlerId = clipboard.connect( - 'owner-change', self.onClipboardContentsChanged) - - def disconnectFromClipboard(self) -> None: - if self._clipboardHandlerId is None: - return - - clipboard = Gtk.Clipboard.get(Gdk.Atom.intern("CLIPBOARD", False)) - clipboard.disconnect(self._clipboardHandlerId) - - def getClipboardContents(self) -> Any: - clipboard = Gtk.Clipboard.get(Gdk.Atom.intern("CLIPBOARD", False)) - return clipboard.wait_for_text() - - def setClipboardText(self, text: Any) -> bool: - clipboard = Gtk.Clipboard.get(Gdk.Atom.intern("CLIPBOARD", False)) - clipboard.set_text(text, -1) - - def appendTextToClipboard(self, text: Any) -> bool: - clipboard = Gtk.Clipboard.get(Gdk.Atom.intern("CLIPBOARD", False)) - clipboard.request_text(self._appendTextToClipboardCallback, text) - - def _appendTextToClipboardCallback(self, clipboard: Any, text: Any, newText: Any, separator: Any = "\n") -> bool: - text = text.rstrip("\n") - text = f"{text}{separator}{newText}" - clipboard.set_text(text, -1) - - def lastInputEventCameFromThisApp(self) -> bool: - if not isinstance(cthulhu_state.lastInputEvent, input_event.KeyboardEvent): - return False - - event = cthulhu_state.lastNonModifierKeyEvent - return event and event.isFromApplication(self._script.app) - - def lastInputEventWasPrintableKey(self) -> Any: - return input_event_manager.get_manager().last_event_was_printable_key() - - def lastInputEventWasCommand(self) -> Any: - return input_event_manager.get_manager().last_event_was_command() - - def lastInputEventWasPageSwitch(self) -> Any: - return input_event_manager.get_manager().last_event_was_page_switch() - - def lastInputEventWasUnmodifiedArrow(self) -> Any: - return input_event_manager.get_manager().last_event_was_unmodified_arrow() - - def lastInputEventWasCaretNav(self) -> Any: - return input_event_manager.get_manager().last_event_was_caret_navigation() - - def lastInputEventWasCharNav(self) -> Any: - return input_event_manager.get_manager().last_event_was_character_navigation() - - def lastInputEventWasWordNav(self) -> Any: - return input_event_manager.get_manager().last_event_was_word_navigation() - - def lastInputEventWasPrevWordNav(self) -> Any: - return input_event_manager.get_manager().last_event_was_previous_word_navigation() - - def lastInputEventWasNextWordNav(self) -> Any: - return input_event_manager.get_manager().last_event_was_next_word_navigation() - - def lastInputEventWasLineNav(self) -> bool: - if not input_event_manager.get_manager().last_event_was_line_navigation(): - return False - - if self.isEditableDescendantOfComboBox(cthulhu_state.locusOfFocus): - return False - - return True - - def lastInputEventWasLineBoundaryNav(self) -> Any: - return input_event_manager.get_manager().last_event_was_line_boundary_navigation() - - def lastInputEventWasPageNav(self) -> bool: - if not input_event_manager.get_manager().last_event_was_page_navigation(): - return False - - if self.isEditableDescendantOfComboBox(cthulhu_state.locusOfFocus): - return False - - return True - - def lastInputEventWasFileBoundaryNav(self) -> Any: - return input_event_manager.get_manager().last_event_was_file_boundary_navigation() - - def lastInputEventWasCaretNavWithSelection(self) -> Any: - return input_event_manager.get_manager().last_event_was_caret_selection() - - def lastInputEventWasUndo(self) -> Any: - return input_event_manager.get_manager().last_event_was_undo() - - def lastInputEventWasRedo(self) -> Any: - return input_event_manager.get_manager().last_event_was_redo() - - def lastInputEventWasCut(self) -> Any: - return input_event_manager.get_manager().last_event_was_cut() - - def lastInputEventWasCopy(self) -> Any: - return input_event_manager.get_manager().last_event_was_copy() - - def lastInputEventWasPaste(self) -> Any: - return input_event_manager.get_manager().last_event_was_paste() - - def lastInputEventWasSelectAll(self) -> Any: - return input_event_manager.get_manager().last_event_was_select_all() - - def lastInputEventWasDelete(self) -> Any: - return input_event_manager.get_manager().last_event_was_delete() - - def lastInputEventWasTab(self) -> Any: - return input_event_manager.get_manager().last_event_was_tab() - - def lastInputEventWasMouseButton(self) -> Any: - return input_event_manager.get_manager().last_event_was_mouse_button() - - def lastInputEventWasPrimaryMouseClick(self) -> Any: - return input_event_manager.get_manager().last_event_was_primary_click() - - def lastInputEventWasMiddleMouseClick(self) -> Any: - return input_event_manager.get_manager().last_event_was_middle_click() - - def lastInputEventWasSecondaryMouseClick(self) -> Any: - return input_event_manager.get_manager().last_event_was_secondary_click() - - def lastInputEventWasPrimaryMouseRelease(self) -> Any: - return input_event_manager.get_manager().last_event_was_primary_release() - - def lastInputEventWasMiddleMouseRelease(self) -> Any: - return input_event_manager.get_manager().last_event_was_middle_release() - - def lastInputEventWasSecondaryMouseRelease(self) -> Any: - return input_event_manager.get_manager().last_event_was_secondary_release() - - def lastInputEventWasTableSort(self, delta: Any = 0.5) -> bool: - if not input_event_manager.get_manager().last_event_was_table_sort(): - return False - - event = cthulhu_state.lastInputEvent - if not event: - return False - - now = time.time() - if now - event.time > delta: - return False - - lastSortTime = self._script.pointOfReference.get('last-table-sort-time', 0.0) - if now - lastSortTime < delta: - return False - - if isinstance(event, input_event.MouseButtonEvent): - if not self.lastInputEventWasPrimaryMouseRelease(): - return False - elif isinstance(event, input_event.KeyboardEvent): - if not event.isHandledBy(self._script.leftClickReviewItem): - keyString, mods = self.lastKeyAndModifiers() - if keyString not in ["Return", "space", " "]: - return False - - return AXUtilities.is_table_header(cthulhu_state.locusOfFocus) - - def isPresentableExpandedChangedEvent(self, event: Any) -> bool: - if self.isSameObject(event.source, cthulhu_state.locusOfFocus): - return True - - if AXUtilities.is_table_row(event.source) or AXUtilities.is_list_box(event.source): - return True - - if AXUtilities.is_combo_box(event.source) or AXUtilities.is_button(event.source): - return AXUtilities.is_focused(event.source) - - return False - - def isPresentableTextChangedEventForLocusOfFocus(self, event: Any) -> bool: - if not event.type.startswith("object:text-changed:") \ - and not event.type.startswith("object:text-attributes-changed"): - return False - - if AXUtilities.is_menu_related(event.source) \ - or AXUtilities.is_slider(event.source) \ - or AXUtilities.is_spin_button(event.source) \ - or AXUtilities.is_label(event.source): - msg = "SCRIPT UTILITIES: Event is not being presented due to role" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if AXUtilities.is_focused(event.source): - if self.isTypeahead(event.source): - return True - if AXUtilities.is_password_text(event.source): - return True - if AXObject.is_dead(cthulhu_state.locusOfFocus): - return True - elif AXUtilities.is_table_cell(event.source) and not AXUtilities.is_selected(event.source): - msg = "SCRIPT UTILITIES: Event is not being presented due to role and states" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if cthulhu_state.locusOfFocus in [event.source, AXObject.get_parent(event.source)]: - return True - - msg = "SCRIPT UTILITIES: Event is not being presented due to lack of cause" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - def isBackSpaceCommandTextDeletionEvent(self, event: Any) -> bool: - if not event.type.startswith("object:text-changed:delete"): - return False - - if self.isHidden(event.source): - return False - - keyString, mods = self.lastKeyAndModifiers() - if keyString == "BackSpace": - return True - - return False - - def isDeleteCommandTextDeletionEvent(self, event: Any) -> bool: - if not event.type.startswith("object:text-changed:delete"): - return False - - return self.lastInputEventWasDelete() - - def isUndoCommandTextDeletionEvent(self, event: Any) -> bool: - if not event.type.startswith("object:text-changed:delete"): - return False - - if not self.lastInputEventWasUndo(): - return False - - start, end, string = self.getCachedTextSelection(event.source) - return not string - - def isSelectedTextDeletionEvent(self, event: Any) -> bool: - if not event.type.startswith("object:text-changed:delete"): - return False - - if self.lastInputEventWasPaste(): - return False - - start, end, string = self.getCachedTextSelection(event.source) - return string and string.strip() == event.any_data.strip() - - def isSelectedTextInsertionEvent(self, event: Any) -> bool: - if not event.type.startswith("object:text-changed:insert"): - return False - - self.updateCachedTextSelection(event.source) - start, end, string = self.getCachedTextSelection(event.source) - return string and string == event.any_data and start == event.detail1 - - def isSelectedTextRestoredEvent(self, event: Any) -> bool: - if not self.lastInputEventWasUndo(): - return False - - if self.isSelectedTextInsertionEvent(event): - return True - - return False - - def isMiddleMouseButtonTextInsertionEvent(self, event: Any) -> bool: - if not event.type.startswith("object:text-changed:insert"): - return False - - return self.lastInputEventWasMiddleMouseClick() - - def isEchoableTextInsertionEvent(self, event: Any) -> bool: - if not event.type.startswith("object:text-changed:insert"): - return False - - if not cthulhu.cthulhuApp.settingsManager.getSetting("enableKeyEcho"): - return False - - if AXUtilities.is_focusable(event.source) \ - and not AXUtilities.is_focused(event.source) \ - and event.source != cthulhu_state.locusOfFocus: - msg = "SCRIPT UTILITIES: Not echoable text insertion event: " \ - "focusable source is not focused" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if AXUtilities.is_password_text(event.source): - return cthulhu.cthulhuApp.settingsManager.getSetting("enableKeyEcho") - - if len(event.any_data.strip()) == 1: - return cthulhu.cthulhuApp.settingsManager.getSetting("enableEchoByCharacter") - - return False - - def isEditableTextArea(self, obj: Atspi.Accessible) -> bool: - if not self.isTextArea(obj): - return False - return AXUtilities.is_editable(obj) - - def isClipboardTextChangedEvent(self, event: Any) -> bool: - if not event.type.startswith("object:text-changed"): - return False - - if not self.lastInputEventWasCommand() or self.lastInputEventWasUndo(): - return False - - if self.isBackSpaceCommandTextDeletionEvent(event): - return False - - if "delete" in event.type and self.lastInputEventWasPaste(): - return False - - if not self.isEditableTextArea(event.source): - return False - - contents = self.getClipboardContents() - if not contents: - return False - if event.any_data == contents: - return True - if bool(re.search(r"\w", event.any_data)) != bool(re.search(r"\w", contents)): - return False - - if self._isParagraphClipboardEvent(event, contents): - return True - - return False - - def _isParagraphClipboardEvent(self, event: Any, contents: Any) -> bool: - # NOTE: Paragraph-per-object toolkits can emit per-paragraph events. - if "\n" in contents and event.any_data.rstrip() in contents: - return True - - return False - - def objectContentsAreInClipboard(self, obj: Optional[Atspi.Accessible] = None) -> bool: - obj = obj or cthulhu_state.locusOfFocus - if not obj or AXObject.is_dead(obj): - return False - - contents = self.getClipboardContents() - if not contents: - return False - - string, _, _ = self.allSelectedText(obj) - if string and string in contents: - return True - - string, start, end = self.selectedText(obj) - if string and string in contents: - return True - - obj = self.realActiveDescendant(obj) or obj - if AXObject.is_dead(obj): - return False - - name = AXObject.get_name(obj) - if obj and name in contents: - return True - - return False - - def clearCachedCommandState(self) -> bool: - self._script.pointOfReference['undo'] = False - self._script.pointOfReference['redo'] = False - self._script.pointOfReference['paste'] = False - self._script.pointOfReference['last-selection-message'] = '' - - def handleUndoTextEvent(self, event: Any) -> bool: - if self.lastInputEventWasUndo(): - if not self._script.pointOfReference.get('undo'): - self._script.presentMessage(messages.UNDO) - self._script.pointOfReference['undo'] = True - self.updateCachedTextSelection(event.source) - return True - - if self.lastInputEventWasRedo(): - if not self._script.pointOfReference.get('redo'): - self._script.presentMessage(messages.REDO) - self._script.pointOfReference['redo'] = True - self.updateCachedTextSelection(event.source) - return True - - return False - - def handleUndoLocusOfFocusChange(self) -> bool: - if self._locusOfFocusIsTopLevelObject(): - return False - - if self.lastInputEventWasUndo(): - if not self._script.pointOfReference.get('undo'): - self._script.presentMessage(messages.UNDO) - self._script.pointOfReference['undo'] = True - return True - - if self.lastInputEventWasRedo(): - if not self._script.pointOfReference.get('redo'): - self._script.presentMessage(messages.REDO) - self._script.pointOfReference['redo'] = True - return True - - return False - - def handlePasteLocusOfFocusChange(self) -> bool: - if self._locusOfFocusIsTopLevelObject(): - return False - - if self.lastInputEventWasPaste(): - if not self._script.pointOfReference.get('paste'): - self._script.presentMessage( - messages.CLIPBOARD_PASTED_FULL, messages.CLIPBOARD_PASTED_BRIEF) - self._script.pointOfReference['paste'] = True - return True - - return False - - def eventIsUserTriggered(self, event: Any) -> bool: - if not cthulhu_state.lastInputEvent: - msg = "SCRIPT UTILITIES: Not user triggered: No last input event." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - delta = time.time() - cthulhu_state.lastInputEvent.time - if delta > 1: - msg = f"SCRIPT UTILITIES: Not user triggered: Last input event {delta:.2f}s ago." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if self.isKeyGrabEvent(event): - msg = "INFO: Last key was consumed. Probably a bogus event from a key grab" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - return True - - def isKeyGrabEvent(self, event: Any) -> bool: - """ Returns True if this event appears to be a side-effect of an - X11 key grab. """ - if not isinstance(cthulhu_state.lastInputEvent, input_event.KeyboardEvent): - return False - return cthulhu_state.lastInputEvent.didConsume() and not cthulhu_state.openingDialog - - def presentFocusChangeReason(self) -> bool: - if self.handleUndoLocusOfFocusChange(): - return True - if self.handlePasteLocusOfFocusChange(): - return True - return False - - def allItemsSelected(self, obj: Atspi.Accessible) -> bool: - if not AXObject.supports_selection(obj): - return False - - if AXUtilities.is_expandable(obj) and not AXUtilities.is_expanded(obj): - return False - - if AXUtilities.is_combo_box(obj) or AXUtilities.is_menu(obj): - return False - - childCount = AXObject.get_child_count(obj) - if childCount == AXSelection.get_selected_child_count(obj): - # The selection interface gives us access to what is selected, which might - # not actually be a direct child. - child = AXSelection.get_selected_child(obj, 0) - if AXObject.get_parent(child) != obj: - return False - - msg = f"SCRIPT UTILITIES: All {childCount} children believed to be selected" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not AXObject.supports_table(obj): - return False - - rows = AXTable.get_row_count(obj, prefer_attribute=False) - cols = AXTable.get_column_count(obj, prefer_attribute=False) - selected_rows = AXTable.get_selected_row_count(obj) - selected_cols = AXTable.get_selected_column_count(obj) - - if selected_rows == rows: - msg = f"SCRIPT UTILITIES: All {rows} rows believed to be selected" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if selected_cols == cols: - msg = f"SCRIPT UTILITIES: All {cols} columns believed to be selected" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def handleContainerSelectionChange(self, obj: Atspi.Accessible) -> bool: - allAlreadySelected = self._script.pointOfReference.get('allItemsSelected') - allCurrentlySelected = self.allItemsSelected(obj) - if allAlreadySelected and allCurrentlySelected: - return True - - self._script.pointOfReference['allItemsSelected'] = allCurrentlySelected - if self.lastInputEventWasSelectAll() and allCurrentlySelected: - self._script.presentMessage(messages.CONTAINER_SELECTED_ALL) - cthulhu.setLocusOfFocus(None, obj, False) - return True - - return False - - def handleTextSelectionChange(self, obj: Atspi.Accessible, speakMessage: Any = True) -> bool: - # Note: This guesswork to figure out what actually changed with respect - # to text selection will get eliminated once the new text-selection API - # is added to ATK and implemented by the toolkits. (BGO 638378) - - if not AXObject.supports_text(obj): - return False - - oldSelection = self._getCachedSelectionData(obj) - oldStart = oldSelection['start'] - oldEnd = oldSelection['end'] - oldString = oldSelection['string'] - oldRanges = oldSelection['ranges'] - - snapshot = self._getSelectionAdapter().refresh_snapshot(obj) - newSelection = self._getSelectionData(obj, snapshot) - self._cacheSelectionData(obj, newSelection) - newStart = newSelection['start'] - newEnd = newSelection['end'] - newString = newSelection['string'] - newRanges = newSelection['ranges'] - - if self._speakTextSelectionState(len(newString)): - return True - - # Even though we present a message, treat it as unhandled so the new location is - # still presented. - if not self.lastInputEventWasCaretNavWithSelection() and oldString and not newString: - self._script.speakMessage(messages.SELECTION_REMOVED) - return False - - changes = [] - oldChars = self._rangesToCharSet(oldRanges) - newChars = self._rangesToCharSet(newRanges) - if not oldChars.union(newChars): - return False - - for start, end in self._charSetToRanges(oldChars - newChars): - changes.append([start, end, messages.TEXT_UNSELECTED]) - - for start, end in self._charSetToRanges(newChars - oldChars): - changes.append([start, end, messages.TEXT_SELECTED]) - - if not changes: - return False - - speakMessage = speakMessage and not cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText') - maxFragments = 3 - for start, end, message in changes[:maxFragments]: - string = AXText.get_substring(obj, start, end) - endsWithChild = string.endswith(self.EMBEDDED_OBJECT_CHARACTER) - if endsWithChild: - end -= 1 - - self._script.sayPhrase(obj, start, end) - if speakMessage and not endsWithChild: - self._script.speakMessage(message, interrupt=False) - - if endsWithChild: - child = self.findChildAtOffset(obj, end) - self.handleTextSelectionChange(child, speakMessage) - - remaining = changes[maxFragments:] - if speakMessage and remaining: - selectedCount = sum(1 for x in remaining if x[2] == messages.TEXT_SELECTED) - unselectedCount = sum(1 for x in remaining if x[2] == messages.TEXT_UNSELECTED) - if selectedCount and not unselectedCount: - self._script.speakMessage(f"{selectedCount} more ranges selected", interrupt=False) - elif unselectedCount and not selectedCount: - self._script.speakMessage(f"{unselectedCount} more ranges unselected", interrupt=False) - else: - self._script.speakMessage(f"{len(remaining)} more selection changes", interrupt=False) - - return True - - def _getCtrlShiftSelectionsStrings(self) -> Any: - """Hacky and to-be-obsoleted method.""" - return [messages.PARAGRAPH_SELECTED_DOWN, - messages.PARAGRAPH_UNSELECTED_DOWN, - messages.PARAGRAPH_SELECTED_UP, - messages.PARAGRAPH_UNSELECTED_UP] - - def _speakTextSelectionState(self, nSelections: Any) -> bool: - """Hacky and to-be-obsoleted method.""" - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return False - - eventStr, mods = self.lastKeyAndModifiers() - isControlKey = mods & keybindings.CTRL_MODIFIER_MASK - isShiftKey = mods & keybindings.SHIFT_MODIFIER_MASK - selectedText = nSelections > 0 - - line = None - if (eventStr == "Page_Down") and isShiftKey and isControlKey: - line = messages.LINE_SELECTED_RIGHT - elif (eventStr == "Page_Up") and isShiftKey and isControlKey: - line = messages.LINE_SELECTED_LEFT - elif (eventStr == "Page_Down") and isShiftKey and not isControlKey: - if selectedText: - line = messages.PAGE_SELECTED_DOWN - else: - line = messages.PAGE_UNSELECTED_DOWN - elif (eventStr == "Page_Up") and isShiftKey and not isControlKey: - if selectedText: - line = messages.PAGE_SELECTED_UP - else: - line = messages.PAGE_UNSELECTED_UP - elif (eventStr == "Down") and isShiftKey and isControlKey: - strings = self._getCtrlShiftSelectionsStrings() - if selectedText: - line = strings[0] - else: - line = strings[1] - elif (eventStr == "Up") and isShiftKey and isControlKey: - strings = self._getCtrlShiftSelectionsStrings() - if selectedText: - line = strings[2] - else: - line = strings[3] - elif (eventStr == "Home") and isShiftKey and isControlKey: - if selectedText: - line = messages.DOCUMENT_SELECTED_UP - else: - line = messages.DOCUMENT_UNSELECTED_UP - elif (eventStr == "End") and isShiftKey and isControlKey: - if selectedText: - line = messages.DOCUMENT_SELECTED_DOWN - else: - line = messages.DOCUMENT_SELECTED_UP - elif self.lastInputEventWasSelectAll() and selectedText: - if not self._script.pointOfReference.get('entireDocumentSelected'): - self._script.pointOfReference['entireDocumentSelected'] = True - line = messages.DOCUMENT_SELECTED_ALL - else: - return True - - if not line: - return False - - if line != self._script.pointOfReference.get('last-selection-message'): - self._script.pointOfReference['last-selection-message'] = line - self._script.speakMessage(line) - - return True - - def shouldInterruptForLocusOfFocusChange(self, oldLocusOfFocus: Any, newLocusOfFocus: Any, event: Any = None) -> bool: - msg = "SCRIPT UTILITIES: Not interrupting for locusOfFocus change: " - if event is None: - msg += "event is None" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if event is not None and event.type.startswith("object:active-descendant-changed"): - return self._script.stopSpeechOnActiveDescendantChanged(event) - - if AXUtilities.is_table_cell(oldLocusOfFocus) and AXUtilities.is_text(newLocusOfFocus) \ - and AXUtilities.is_editable(newLocusOfFocus): - msg += "suspected editable cell" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if not AXUtilities.is_menu_related(newLocusOfFocus) \ - and (AXUtilities.is_check_menu_item(oldLocusOfFocus) \ - or AXUtilities.is_radio_menu_item(oldLocusOfFocus)): - msg += "suspected menuitem state change" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if AXObject.is_ancestor(newLocusOfFocus, oldLocusOfFocus): - msg += "old locusOfFocus is ancestor of new locusOfFocus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if oldLocusOfFocus in AXUtilitiesRelation.get_is_controller_for(newLocusOfFocus): - msg += "new locusOfFocus controls old locusOfFocus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - if newLocusOfFocus in AXUtilitiesRelation.get_is_controller_for(oldLocusOfFocus): - msg += "old locusOfFocus controls new locusOfFocus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - return True - - def stringsAreRedundant(self, str1: Any, str2: Any, threshold: Any = 0.5) -> bool: - if not (str1 and str2): - return False - - similarity = round(SequenceMatcher(None, str1.lower(), str2.lower()).ratio(), 2) - msg = ( - f"SCRIPT UTILITIES: Similarity between '{str1}', '{str2}': {similarity} " - f"(threshold: {threshold})" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return similarity >= threshold diff --git a/src/cthulhu/scripts/__init__.py b/src/cthulhu/scripts/__init__.py deleted file mode 100644 index 301e5ea..0000000 --- a/src/cthulhu/scripts/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - diff --git a/src/cthulhu/scripts/apps/Banshee/__init__.py b/src/cthulhu/scripts/apps/Banshee/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/apps/Banshee/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/apps/Banshee/meson.build b/src/cthulhu/scripts/apps/Banshee/meson.build deleted file mode 100644 index 763e34a..0000000 --- a/src/cthulhu/scripts/apps/Banshee/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -banshee_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - banshee_python_sources, - subdir: 'cthulhu/scripts/apps/Banshee' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/Banshee/script.py b/src/cthulhu/scripts/apps/Banshee/script.py deleted file mode 100644 index 21f71f2..0000000 --- a/src/cthulhu/scripts/apps/Banshee/script.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import cthulhu.scripts.default as default -import cthulhu.cthulhu_state as cthulhu_state -from cthulhu.ax_value import AXValue - -from .script_utilities import Utilities - -class Script(default.Script): - - def __init__(self, app): - """Creates a new script for the given application. - - Arguments: - - app: the application to create a script for. - """ - default.Script.__init__(self, app) - self._last_seek_value = 0 - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def onValueChanged(self, event): - obj = event.source - if self.utilities.isSeekSlider(obj): - current_value = int(AXValue.get_current_value(obj)) / 1000 - if current_value in range(self._last_seek_value, self._last_seek_value + 4): - if self.utilities.isSameObject(obj, cthulhu_state.locusOfFocus): - self.updateBraille(obj) - return - - self._last_seek_value = current_value - - default.Script.onValueChanged(self, event) diff --git a/src/cthulhu/scripts/apps/Banshee/script_utilities.py b/src/cthulhu/scripts/apps/Banshee/script_utilities.py deleted file mode 100644 index f113449..0000000 --- a/src/cthulhu/scripts/apps/Banshee/script_utilities.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import cthulhu.script_utilities as script_utilities -from cthulhu.ax_object import AXObject -from cthulhu.ax_value import AXValue -from cthulhu.ax_utilities import AXUtilities - - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - """Creates an instance of the Utilities class. - - Arguments: - - script: the script with which this instance is associated. - """ - - script_utilities.Utilities.__init__(self, script) - - def _formatDuration(self, s): - seconds = '%02d' % (s%60) - minutes = '%02d' % (s/60) - hours = '%02d' % (s/3600) - duration = [minutes, seconds] - if hours != '00': - duration.insert(0, hours) - - return ':'.join(duration) - - def isSeekSlider(self, obj): - return AXObject.find_ancestor(obj, AXUtilities.is_tool_bar) is not None - - def textForValue(self, obj): - if not self.isSeekSlider(obj): - return script_utilities.Utilities.textForValue(self, obj) - - if not AXObject.supports_value(obj): - return script_utilities.Utilities.textForValue(self, obj) - - return self._formatDuration(int(AXValue.get_current_value(obj)) / 1000) diff --git a/src/cthulhu/scripts/apps/Eclipse/__init__.py b/src/cthulhu/scripts/apps/Eclipse/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/apps/Eclipse/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/apps/Eclipse/meson.build b/src/cthulhu/scripts/apps/Eclipse/meson.build deleted file mode 100644 index 4e313c6..0000000 --- a/src/cthulhu/scripts/apps/Eclipse/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -eclipse_python_sources = files([ - '__init__.py', - 'script.py', -]) - -python3.install_sources( - eclipse_python_sources, - subdir: 'cthulhu/scripts/apps/Eclipse' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/Eclipse/script.py b/src/cthulhu/scripts/apps/Eclipse/script.py deleted file mode 100644 index 1060ace..0000000 --- a/src/cthulhu/scripts/apps/Eclipse/script.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Eclipse.""" -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Informal Informatica LTDA." -__license__ = "LGPL" - - -import cthulhu.debug as debug -import cthulhu.cthulhu as cthulhu -import cthulhu.scripts.toolkits.GAIL as GAIL -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -######################################################################## -# # -# The Eclipse script class. # -# # -######################################################################## -class Script(GAIL.Script): - - def __init__(self, app): - """Creates a new script for the given application.""" - GAIL.Script.__init__(self, app) - self.movementKeys = ["Up", "Down", "Left", "Right", "Page_Up", - "Page_Down", "Home", "End"] - - def _presentTextAtNewCaretPosition(self, event, otherObj=None): - """Updates braille and outputs speech for the event.source or the - otherObj. Overridden here so that we can give more feedback to user. - """ - - # Let the default script's normal behavior do its thing - # - GAIL.Script._presentTextAtNewCaretPosition(self, event, otherObj) - - # check if the obj was spoken in the default script - lastKey, mods = self.utilities.lastKeyAndModifiers() - if lastKey in self.movementKeys: - # already spoken in default script - return - - obj = otherObj or event.source - if AXUtilities.is_single_line(obj): - return - - # if Tab key is pressed and there is text selected, we must announce - # the text selected because probably we are in a parameter list - # and we are jumping between the parameters with the tab key. - hasSelection = False - if lastKey in ["Tab", "ISO_Left_Tab"]: - [text, startOffset, endOffset] = self.utilities.selectedText(obj) - hasSelection = endOffset > 0 - - if hasSelection: - self.sayPhrase(obj, startOffset, endOffset) - else: - self.sayLine(obj) - - self._saveLastTextPosition(obj) - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - # NOTE: This event type is deprecated and Cthulhu should no longer use it. - # This callback remains just to handle bugs in applications and toolkits. - if AXUtilities.is_panel(event.source): - cthulhu.setLocusOfFocus(event, event.source) - return - - if AXUtilities.is_text(event.source) \ - and self.utilities.lastInputEventWasUnmodifiedArrow() \ - and self.utilities.inMenu(): - msg = "ECLIPSE: Ignoring event. In menu." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - super().onFocus(event) - - def onTextInserted(self, event): - """Called whenever text is inserted into an object. Overridden here - so that we can avoid speaking text when caret moves after new text - is inserted. - - Arguments: - - event: the Event - """ - - if self.utilities.isTextArea(event.source): - length = AXText.get_character_count(event.source) - if event.detail1 == 0 and event.detail2 == length: - # seems to be generated by a reformat (ctrl+shift+f) - # or by commenting some block (ctrl+/). - # if not discarded, cthulhu will speak all the text of the file. - return - # Let the default script's normal behavior do its thing - GAIL.Script.onTextInserted(self, event) - self._saveLastTextPosition(event.source) - - def onTextDeleted(self, event): - """Called whenever text is deleted from an object. Overridden here - so that we can avoid speaking text when caret moves after new text - is deleted. - - Arguments: - - event: the Event - """ - - # Let the default script's normal behavior do its thing - # - GAIL.Script.onTextDeleted(self, event) - self._saveLastTextPosition(event.source) - - def _saveLastTextPosition(self, obj): - if self.utilities.isTextArea(obj): - self._saveLastCursorPosition(obj, AXText.get_caret_offset(obj)) - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - # Sometimes Eclipse fires an object:selection-changed event for non-focused - # containers. We don't want to present those. The exception is the MenuBar. - if not (AXUtilities.is_focused(event.source) or AXUtilities.is_menu_bar(event.source)): - return - - GAIL.Script.onSelectionChanged(self, event) diff --git a/src/cthulhu/scripts/apps/Mumble/__init__.py b/src/cthulhu/scripts/apps/Mumble/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/apps/Mumble/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/apps/Mumble/chat.py b/src/cthulhu/scripts/apps/Mumble/chat.py deleted file mode 100644 index eccd2a8..0000000 --- a/src/cthulhu/scripts/apps/Mumble/chat.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom chat module for Mumble.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux." -__license__ = "LGPL" - -import re - -import cthulhu.chat as chat -import cthulhu.keybindings as keybindings -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.settings_manager as settings_manager -from cthulhu.ax_object import AXObject -from cthulhu.ax_selection import AXSelection -from cthulhu.ax_utilities import AXUtilities - -_settingsManager = settings_manager.getManager() - - -class Chat(chat.Chat): - """Mumble-specific chat helpers.""" - - def __init__(self, script): - super().__init__(script, []) - - # Mumble can have more than nine recent messages that are useful to review. - self.messageKeys = [ - "F1", "F2", "F3", "F4", "F5", "F6", - "F7", "F8", "F9", "F10", "F11", "F12", - ] - self.messageKeyModifier = keybindings.CTHULHU_MODIFIER_MASK - self.inputEventHandlers = {} - self.setupInputEventHandlers() - self.keyBindings = self.getKeyBindings() - self.messageListLength = len(self.messageKeys) - self._conversationList = chat.ConversationList(self.messageListLength) - - self._channelTree = None - - def isChatRoomMsg(self, obj): - if not obj: - return False - - name = AXObject.get_name(obj) - if name != "Activity log": - return False - - if AXUtilities.is_label(obj) or AXUtilities.is_text(obj): - return True - - return False - - def getMessageFromEvent(self, event): - message = event.any_data or "" - message = message.replace("\u2028", " ") - message = re.sub(r"[\ufdd0-\ufdef]", "", message) - message = " ".join(message.split()) - if not message: - return "" - - if re.match(r"^\[\d{2}:\d{2}:\d{2}\]$", message): - return "" - - message = re.sub(r"^\[\d{2}:\d{2}:\d{2}\]\s*", "", message) - return message.strip() - - def _get_message_for_index(self, index): - messageNumber = self.messageListLength - (index + 1) - message, chatRoomName = None, None - - if _settingsManager.getSetting('chatRoomHistories'): - conversation = self.getConversation(cthulhu_state.locusOfFocus) - if conversation: - message = conversation.getNthMessage(messageNumber) - chatRoomName = conversation.name - - if not message: - message, chatRoomName = \ - self._conversationList.getNthMessageAndName(messageNumber) - - return message, chatRoomName - - def getChatRoomName(self, obj): - channelName = self._get_selected_channel_name() - return channelName or "Mumble" - - def _get_selected_channel_name(self): - channelTree = self._get_channel_tree() - if not channelTree: - return "" - - selectedChildren = AXSelection.get_selected_children(channelTree) - for child in selectedChildren: - childName = AXObject.get_name(child) - if not childName: - continue - if childName.lower().startswith("channel "): - return childName.replace("channel ", "", 1).strip() - - for child in selectedChildren: - channelAncestor = AXObject.find_ancestor( - child, - lambda x: (AXObject.get_name(x) or "").lower().startswith("channel ") - ) - if channelAncestor: - ancestorName = AXObject.get_name(channelAncestor) - return ancestorName.replace("channel ", "", 1).strip() - - return "" - - def _get_channel_tree(self): - if self._channelTree and not AXUtilities.is_defunct(self._channelTree): - return self._channelTree - - activeWindow = cthulhu_state.activeWindow - if not activeWindow: - return None - - def is_channels_tree(obj): - return AXUtilities.is_tree(obj) and AXObject.get_name(obj) == "Channels and users" - - self._channelTree = AXObject.find_descendant(activeWindow, is_channels_tree) - return self._channelTree diff --git a/src/cthulhu/scripts/apps/Mumble/meson.build b/src/cthulhu/scripts/apps/Mumble/meson.build deleted file mode 100644 index 9e83272..0000000 --- a/src/cthulhu/scripts/apps/Mumble/meson.build +++ /dev/null @@ -1,11 +0,0 @@ -mumble_python_sources = files([ - '__init__.py', - 'chat.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - mumble_python_sources, - subdir: 'cthulhu/scripts/apps/Mumble' -) diff --git a/src/cthulhu/scripts/apps/Mumble/script.py b/src/cthulhu/scripts/apps/Mumble/script.py deleted file mode 100644 index 7452184..0000000 --- a/src/cthulhu/scripts/apps/Mumble/script.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Mumble.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux." -__license__ = "LGPL" - -import time - -import cthulhu.debug as debug -import cthulhu.scripts.toolkits.Qt.script as Qt -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -from .chat import Chat -from .script_utilities import Utilities - - -class Script(Qt.Script): - """Mumble-specific script tweaks.""" - - def __init__(self, app): - self._lastConnectFocusName = "" - self._lastConnectFocusRole = None - self._lastConnectFocusTime = 0.0 - self._lastMessageDialogId = None - - super().__init__(app) - - def getChat(self): - return Chat(self) - - def getUtilities(self): - return Utilities(self) - - def setupInputEventHandlers(self): - super().setupInputEventHandlers() - self.inputEventHandlers.update(self.chat.inputEventHandlers) - - def getAppKeyBindings(self): - return self.chat.keyBindings - - def getAppPreferencesGUI(self): - return self.chat.getAppPreferencesGUI() - - def getPreferencesFromGUI(self): - return self.chat.getPreferencesFromGUI() - - def onTextInserted(self, event): - if self.chat.presentInsertedText(event): - return - - super().onTextInserted(event) - - def onFocusedChanged(self, event): - if self._should_ignore_connect_dialog_focus(event): - return - - super().onFocusedChanged(event) - - def onCaretMoved(self, event): - super().onCaretMoved(event) - self._maybe_announce_message_dialog_input(event.source) - - def _should_ignore_connect_dialog_focus(self, event): - if not event.detail1: - return False - - obj = event.source - if not self._is_in_connect_dialog(obj): - return False - - objName = AXObject.get_name(obj) or "" - if not objName: - return False - - role = AXObject.get_role(obj) - now = time.time() - if self._lastConnectFocusName == objName \ - and self._lastConnectFocusRole == role \ - and (now - self._lastConnectFocusTime) < 0.35: - msg = "MUMBLE: Ignoring duplicate focus event in connect dialog" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - self._lastConnectFocusName = objName - self._lastConnectFocusRole = role - self._lastConnectFocusTime = now - return False - - def _is_in_connect_dialog(self, obj): - dialog = AXObject.find_ancestor(obj, AXUtilities.is_dialog) - return bool(dialog) and AXObject.get_name(dialog) == "Mumble Server Connect" - - def _maybe_announce_message_dialog_input(self, obj): - if not obj or not AXUtilities.is_text(obj): - return - - if not AXUtilities.is_editable(obj): - return - - if AXObject.get_name(obj): - return - - dialog = AXObject.find_ancestor(obj, AXUtilities.is_dialog) - if not dialog: - return - - dialogName = AXObject.get_name(dialog) or "" - if not dialogName.startswith("Sending message to "): - return - - dialogHash = hash(dialog) - if dialogHash == self._lastMessageDialogId: - return - - self._lastMessageDialogId = dialogHash - label = "Message" - voice = self.speechGenerator.voice(string=label) - self.speakMessage(label, voice=voice) diff --git a/src/cthulhu/scripts/apps/Mumble/script_utilities.py b/src/cthulhu/scripts/apps/Mumble/script_utilities.py deleted file mode 100644 index 9405c72..0000000 --- a/src/cthulhu/scripts/apps/Mumble/script_utilities.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script utilities for Mumble.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux." -__license__ = "LGPL" - -import cthulhu.scripts.toolkits.Qt.script_utilities as Qt -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - - -class Utilities(Qt.Utilities): - """Mumble-specific script utilities.""" - - def shouldReadFullRow(self, obj): - if self._is_connect_server_list_cell(obj): - return False - - return super().shouldReadFullRow(obj) - - def _is_connect_server_list_cell(self, obj): - if not AXUtilities.is_table_cell_or_header(obj): - return False - - dialog = AXObject.find_ancestor(obj, AXUtilities.is_dialog) - if not dialog or AXObject.get_name(dialog) != "Mumble Server Connect": - return False - - tree = AXObject.find_ancestor( - obj, - lambda x: AXUtilities.is_tree(x) and AXObject.get_name(x) == "Server list" - ) - return tree is not None diff --git a/src/cthulhu/scripts/apps/SeaMonkey/__init__.py b/src/cthulhu/scripts/apps/SeaMonkey/__init__.py deleted file mode 100644 index ca4874a..0000000 --- a/src/cthulhu/scripts/apps/SeaMonkey/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for SeaMonkey.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script - diff --git a/src/cthulhu/scripts/apps/SeaMonkey/meson.build b/src/cthulhu/scripts/apps/SeaMonkey/meson.build deleted file mode 100644 index e3b6b3d..0000000 --- a/src/cthulhu/scripts/apps/SeaMonkey/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -seamonkey_python_sources = files([ - '__init__.py', - 'script.py', -]) - -python3.install_sources( - seamonkey_python_sources, - subdir: 'cthulhu/scripts/apps/SeaMonkey' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/SeaMonkey/script.py b/src/cthulhu/scripts/apps/SeaMonkey/script.py deleted file mode 100644 index 2322e0a..0000000 --- a/src/cthulhu/scripts/apps/SeaMonkey/script.py +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for SeaMonkey.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2016 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu import cmdnames -from cthulhu import debug -from cthulhu import input_event -from cthulhu import cthulhu_state -from cthulhu.ax_object import AXObject -from cthulhu.scripts.toolkits import Gecko - - -class Script(Gecko.Script): - - def __init__(self, app): - super().__init__(app) - - def setupInputEventHandlers(self): - super().setupInputEventHandlers() - - self.inputEventHandlers["togglePresentationModeHandler"] = \ - input_event.InputEventHandler( - Script.togglePresentationMode, - cmdnames.TOGGLE_PRESENTATION_MODE) - - self.inputEventHandlers["enableStickyFocusModeHandler"] = \ - input_event.InputEventHandler( - Script.enableStickyFocusMode, - cmdnames.SET_FOCUS_MODE_STICKY) - - self.inputEventHandlers["enableStickyBrowseModeHandler"] = \ - input_event.InputEventHandler( - Script.enableStickyBrowseMode, - cmdnames.SET_BROWSE_MODE_STICKY) - - def onBusyChanged(self, event): - """Callback for object:state-changed:busy accessibility events.""" - - if self.utilities.isContentEditableWithEmbeddedObjects(event.source): - msg = "SEAMONKEY: Ignoring, event source is content editable" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - table = self.utilities.getTable(cthulhu_state.locusOfFocus) - if table and not self.utilities.isTextDocumentTable(table): - tokens = ["SEAMONKEY: Ignoring, locusOfFocus is", cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - super().onBusyChanged(event) - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - # We should get proper state-changed events for these. - if self.utilities.inDocumentContent(event.source): - return - - focusRole = AXObject.get_role(cthulhu_state.locusOfFocus) - if focusRole != Atspi.Role.ENTRY or not self.utilities.inDocumentContent(): - super().onFocus(event) - return - - if AXObject.get_role(event.source) == Atspi.Role.MENU: - msg = "SEAMONKEY: Non-document menu claimed focus from document entry" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if self.utilities.lastInputEventWasPrintableKey(): - msg = "SEAMONKEY: Ignoring, believed to be result of printable input" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - super().onFocus(event) - - def useFocusMode(self, obj, prevObj=None): - if self.utilities.isEditableMessage(obj): - tokens = ["SEAMONKEY: Using focus mode for editable message", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - tokens = ["SEAMONKEY:", obj, "is not an editable message."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return super().useFocusMode(obj, prevObj) - - def enableStickyBrowseMode(self, inputEvent, forceMessage=False): - if self.utilities.isEditableMessage(cthulhu_state.locusOfFocus): - return - - super().enableStickyBrowseMode(inputEvent, forceMessage) - - def enableStickyFocusMode(self, inputEvent, forceMessage=False): - if self.utilities.isEditableMessage(cthulhu_state.locusOfFocus): - return - - super().enableStickyFocusMode(inputEvent, forceMessage) - - def togglePresentationMode(self, inputEvent, documentFrame=None): - if self._inFocusMode \ - and self.utilities.isEditableMessage(cthulhu_state.locusOfFocus): - return - - super().togglePresentationMode(inputEvent, documentFrame) - - def useStructuralNavigationModel(self, debugOutput=True): - if self.utilities.isEditableMessage(cthulhu_state.locusOfFocus): - return False - - return super().useStructuralNavigationModel(debugOutput) diff --git a/src/cthulhu/scripts/apps/Thunderbird/__init__.py b/src/cthulhu/scripts/apps/Thunderbird/__init__.py deleted file mode 100644 index 88b431a..0000000 --- a/src/cthulhu/scripts/apps/Thunderbird/__init__.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -""" Custom script for Thunderbird 3. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script diff --git a/src/cthulhu/scripts/apps/Thunderbird/meson.build b/src/cthulhu/scripts/apps/Thunderbird/meson.build deleted file mode 100644 index 56489ce..0000000 --- a/src/cthulhu/scripts/apps/Thunderbird/meson.build +++ /dev/null @@ -1,11 +0,0 @@ -thunderbird_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', - 'spellcheck.py', -]) - -python3.install_sources( - thunderbird_python_sources, - subdir: 'cthulhu/scripts/apps/Thunderbird' -) diff --git a/src/cthulhu/scripts/apps/Thunderbird/script.py b/src/cthulhu/scripts/apps/Thunderbird/script.py deleted file mode 100644 index 1503c7f..0000000 --- a/src/cthulhu/scripts/apps/Thunderbird/script.py +++ /dev/null @@ -1,404 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Thunderbird.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -import cthulhu.cthulhu as cthulhu -import cthulhu.cmdnames as cmdnames -import cthulhu.debug as debug -import cthulhu.input_event as input_event -import cthulhu.scripts.default as default -import cthulhu.settings_manager as settings_manager -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.scripts.toolkits.Gecko as Gecko -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -from .spellcheck import SpellCheck -from .script_utilities import Utilities - -_settingsManager = settings_manager.getManager() - -######################################################################## -# # -# The Thunderbird script class. # -# # -######################################################################## - -class Script(Gecko.Script): - """The script for Thunderbird.""" - - def __init__(self, app): - """ Creates a new script for the given application. - - Arguments: - - app: the application to create a script for. - """ - - # Store the last autocompleted string for the address fields - # so that we're not too 'chatty'. See bug #533042. - # - self._lastAutoComplete = "" - - if _settingsManager.getSetting('sayAllOnLoad') is None: - _settingsManager.setSetting('sayAllOnLoad', False) - if _settingsManager.getSetting('pageSummaryOnLoad') is None: - _settingsManager.setSetting('pageSummaryOnLoad', False) - - super().__init__(app) - - def setupInputEventHandlers(self): - super().setupInputEventHandlers() - - self.inputEventHandlers["togglePresentationModeHandler"] = \ - input_event.InputEventHandler( - Script.togglePresentationMode, - cmdnames.TOGGLE_PRESENTATION_MODE) - - self.inputEventHandlers["enableStickyFocusModeHandler"] = \ - input_event.InputEventHandler( - Script.enableStickyFocusMode, - cmdnames.SET_FOCUS_MODE_STICKY) - - self.inputEventHandlers["enableStickyBrowseModeHandler"] = \ - input_event.InputEventHandler( - Script.enableStickyBrowseMode, - cmdnames.SET_BROWSE_MODE_STICKY) - - def getSpellCheck(self): - """Returns the spellcheck support for this script.""" - - return SpellCheck(self) - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def getAppPreferencesGUI(self): - """Return a GtkGrid containing the application unique configuration - GUI items for the current application.""" - - grid = super().getAppPreferencesGUI() - - self._sayAllOnLoadCheckButton.set_active( - _settingsManager.getSetting('sayAllOnLoad')) - self._pageSummaryOnLoadCheckButton.set_active( - _settingsManager.getSetting('pageSummaryOnLoad')) - - spellcheck = self.spellcheck.getAppPreferencesGUI() - grid.attach(spellcheck, 0, len(grid.get_children()), 1, 1) - grid.show_all() - - return grid - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - prefs = super().getPreferencesFromGUI() - prefs['sayAllOnLoad'] = self._sayAllOnLoadCheckButton.get_active() - prefs['pageSummaryOnLoad'] = self._pageSummaryOnLoadCheckButton.get_active() - prefs.update(self.spellcheck.getPreferencesFromGUI()) - - return prefs - - def locus_of_focus_changed(self, event, oldFocus, newFocus): - """Handles changes of focus of interest to the script.""" - - if self.spellcheck.isSuggestionsItem(newFocus): - includeLabel = not self.spellcheck.isSuggestionsItem(oldFocus) - cthulhu.emitRegionChanged(newFocus) - self.updateBraille(newFocus) - self.spellcheck.presentSuggestionListItem(includeLabel=includeLabel) - return - - super().locus_of_focus_changed(event, oldFocus, newFocus) - - def useFocusMode(self, obj, prevObj=None): - if self.utilities.isEditableMessage(obj): - tokens = ["THUNDERBIRD: Using focus mode for editable message", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - tokens = ["THUNDERBIRD:", obj, "is not an editable message."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return super().useFocusMode(obj, prevObj) - - def enableStickyBrowseMode(self, inputEvent, forceMessage=False): - if self.utilities.isEditableMessage(cthulhu_state.locusOfFocus): - return - - super().enableStickyBrowseMode(inputEvent, forceMessage) - - def enableStickyFocusMode(self, inputEvent, forceMessage=False): - if self.utilities.isEditableMessage(cthulhu_state.locusOfFocus): - return - - super().enableStickyFocusMode(inputEvent, forceMessage) - - def togglePresentationMode(self, inputEvent, documentFrame=None): - if self._inFocusMode and self.utilities.isEditableMessage(cthulhu_state.locusOfFocus): - return - - super().togglePresentationMode(inputEvent, documentFrame) - - def useStructuralNavigationModel(self, debugOutput=True): - """Returns True if structural navigation should be enabled here.""" - - if self.utilities.isEditableMessage(cthulhu_state.locusOfFocus): - return False - - return super().useStructuralNavigationModel(debugOutput) - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if not event.detail1: - return - - self._lastAutoComplete = "" - obj = event.source - if self.spellcheck.isAutoFocusEvent(event): - cthulhu.setLocusOfFocus(event, event.source, False) - self.updateBraille(cthulhu_state.locusOfFocus) - - if not self.utilities.inDocumentContent(obj): - super().onFocusedChanged(event) - return - - if self.utilities.isEditableMessage(obj): - super().onFocusedChanged(event) - return - - super().onFocusedChanged(event) - - def onBusyChanged(self, event): - """Callback for object:state-changed:busy accessibility events.""" - - if self.utilities.isEditableMessage(event.source): - return - - if self.inFocusMode(): - return - - obj = event.source - if self.utilities.isDocument(obj) and not event.detail1: - if AXObject.get_name(cthulhu_state.locusOfFocus) \ - and (AXUtilities.is_frame(cthulhu_state.locusOfFocus) \ - or AXUtilities.is_page_tab(cthulhu_state.locusOfFocus)): - cthulhu.setLocusOfFocus(event, event.source, False) - - if self.utilities.inDocumentContent(): - self.speakMessage(AXObject.get_name(obj)) - self._presentMessage(obj) - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - if self.utilities.isEditableMessage(event.source): - if event.detail1 == -1: - return - self.spellcheck.setDocumentPosition(event.source, event.detail1) - if self.spellcheck.isActive(): - return - - super().onCaretMoved(event) - - def onSelectionChanged(self, event): - """Callback for object:state-changed:showing accessibility events.""" - - # We present changes when the list has focus via focus-changed events. - if event.source == self.spellcheck.getSuggestionsList(): - return - - parent = AXObject.get_parent(event.source) - if AXUtilities.is_combo_box(parent) and not AXUtilities.is_focused(parent): - return - - super().onSelectionChanged(event) - - def onSensitiveChanged(self, event): - """Callback for object:state-changed:sensitive accessibility events.""" - - if event.source == self.spellcheck.getChangeToEntry() \ - and self.spellcheck.presentCompletionMessage(): - return - - super().onSensitiveChanged(event) - - def onShowingChanged(self, event): - """Callback for object:state-changed:showing accessibility events.""" - - # TODO - JD: Once there are separate scripts for the Gecko toolkit - # and the Firefox browser, this method can be deleted. It's here - # right now just to prevent the Gecko script from presenting non- - # existent browsery autocompletes for Thunderbird. - - if event.detail1 and self.utilities.isMenuWithNoSelectedChild(event.source) \ - and cthulhu_state.activeWindow == self.utilities.topLevelObject(event.source): - self.presentObject(event.source) - cthulhu.setLocusOfFocus(event, event.source, False) - return - - default.Script.onShowingChanged(self, event) - - def onTextDeleted(self, event): - """Called whenever text is from an object. - - Arguments: - - event: the Event - """ - - if AXUtilities.is_label(event.source) \ - and AXUtilities.is_status_bar(AXObject.get_parent(event.source)): - return - - super().onTextDeleted(event) - - def onTextInserted(self, event): - """Callback for object:text-changed:insert accessibility events.""" - - parent = AXObject.get_parent(event.source) - if AXUtilities.is_label(event.source) and AXUtilities.is_status_bar(parent): - return - - if len(event.any_data) > 1 and event.source == self.spellcheck.getChangeToEntry(): - return - - isSystemEvent = event.type.endswith("system") - - # Try to stop unwanted chatter when a message is being replied to. - # See bgo#618484. - if isSystemEvent and self.utilities.isEditableMessage(event.source): - return - - # Speak the autocompleted text, but only if it is different - # address so that we're not too "chatty." See bug #533042. - if AXUtilities.is_autocomplete(parent): - if len(event.any_data) == 1: - default.Script.onTextInserted(self, event) - return - - if self._lastAutoComplete and self._lastAutoComplete in event.any_data: - return - - # Mozilla cannot seem to get their ":system" suffix right - # to save their lives, so we'll add yet another sad hack. - # Intentional object-local check: autocomplete selection lives in this entry. - selections = AXText.get_selected_ranges(event.source) - hasSelection = bool(selections) - if hasSelection or isSystemEvent: - voice = self.speechGenerator.voice(obj=event.source, string=event.any_data) - self.speakMessage(event.any_data, voice=voice) - self._lastAutoComplete = event.any_data - return - - super().onTextInserted(event) - - def onTextSelectionChanged(self, event): - """Callback for object:text-selection-changed accessibility events.""" - - obj = event.source - spellCheckEntry = self.spellcheck.getChangeToEntry() - if obj == spellCheckEntry: - return - - if self.utilities.isEditableMessage(obj) and self.spellcheck.isActive(): - # Intentional object-local check: spellcheck position is tracked within this entry. - selections = AXText.get_selected_ranges(obj) - if selections: - selStart, selEnd = selections[0] - self.spellcheck.setDocumentPosition(obj, selStart) - return - - super().onTextSelectionChanged(event) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - if AXObject.get_name(event.source) == self.spellcheck.getMisspelledWord(): - self.spellcheck.presentErrorDetails() - return - - if not self.utilities.lastInputEventWasDelete() \ - or not self.utilities.isDocument(event.source): - return - - super().onNameChanged(event) - - def _presentMessage(self, documentFrame): - """Presents the first line of the message, or the entire message, - depending on the user's sayAllOnLoad setting.""" - - [obj, offset] = self.utilities.findFirstCaretContext(documentFrame, 0) - self.utilities.setCaretPosition(obj, offset) - self.updateBraille(obj) - if obj and self._navSuspended and self.utilities.inDocumentContent(obj): - self._setNavigationSuspended(False, "message content loaded") - - if _settingsManager.getSetting('pageSummaryOnLoad'): - tokens = ["THUNDERBIRD: Getting page summary for obj", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - summary = self.utilities.getPageSummary(obj) - if summary: - self.presentMessage(summary) - - if not _settingsManager.getSetting('sayAllOnLoad'): - msg = "THUNDERBIRD: SayAllOnLoad is False. Presenting line." - debug.printMessage(debug.LEVEL_INFO, msg, True) - contents = self.utilities.getLineContentsAtOffset(obj, offset) - self.speakContents(contents) - return - - if _settingsManager.getSetting('enableSpeech'): - msg = "THUNDERBIRD: SayAllOnLoad is True and speech is enabled" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.sayAll(None) - - def onWindowActivated(self, event): - """Callback for window:activate accessibility events.""" - - super().onWindowActivated(event) - if not self.spellcheck.isCheckWindow(event.source): - self.spellcheck.deactivate() - return - - self.spellcheck.presentErrorDetails() - cthulhu.setLocusOfFocus(None, self.spellcheck.getChangeToEntry(), False) - self.updateBraille(cthulhu_state.locusOfFocus) - - def onWindowDeactivated(self, event): - """Callback for window:deactivate accessibility events.""" - - super().onWindowDeactivated(event) - self.spellcheck.deactivate() - self.utilities.clearContentCache() diff --git a/src/cthulhu/scripts/apps/Thunderbird/script_utilities.py b/src/cthulhu/scripts/apps/Thunderbird/script_utilities.py deleted file mode 100644 index f09daa5..0000000 --- a/src/cthulhu/scripts/apps/Thunderbird/script_utilities.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Thunderbird-specific utility overrides.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." -__license__ = "LGPL" - -import cthulhu.debug as debug -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu.scripts.toolkits.Gecko.script_utilities import Utilities as GeckoUtilities - - -class Utilities(GeckoUtilities): - - def __init__(self, script): - super().__init__(script) - - def getDocumentForObject(self, obj): - document = super().getDocumentForObject(obj) - if document: - return document - - documentFrame = self._messageDocumentFrameFor(obj) - if not documentFrame: - return None - - tokens = ["THUNDERBIRD: Treating document frame as document:", documentFrame] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return documentFrame - - def getTopLevelDocumentForObject(self, obj): - document = super().getTopLevelDocumentForObject(obj) - if document: - return document - - documentFrame = self._messageDocumentFrameFor(obj) - if not documentFrame: - return None - - tokens = ["THUNDERBIRD: Treating document frame as top-level document:", documentFrame] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return documentFrame - - def _messageDocumentFrameFor(self, obj): - if not obj: - return None - - if AXUtilities.is_document_frame(obj) and self._isMessageDocumentFrame(obj): - return obj - - documentFrame = AXObject.find_ancestor(obj, AXUtilities.is_document_frame) - if documentFrame and self._isMessageDocumentFrame(documentFrame): - return documentFrame - - return None - - def _isMessageDocumentFrame(self, obj): - if not obj or not AXUtilities.is_document_frame(obj): - return False - - uri = self.documentFrameURI(obj) - if uri: - for prefix in ("about:message", "mailbox:", "imap:", "imaps:", - "news:", "nntp:", "pop:", "pop3:", - "smtp:", "smtps:"): - if uri.startswith(prefix): - return True - - name = (AXObject.get_name(obj) or "").lower() - return "message" in name diff --git a/src/cthulhu/scripts/apps/Thunderbird/spellcheck.py b/src/cthulhu/scripts/apps/Thunderbird/spellcheck.py deleted file mode 100644 index 1752d2f..0000000 --- a/src/cthulhu/scripts/apps/Thunderbird/spellcheck.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Customized support for spellcheck in Thunderbird.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.spellcheck as spellcheck -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_relation import AXUtilitiesRelation - - -class SpellCheck(spellcheck.SpellCheck): - - def __init__(self, script): - super(SpellCheck, self).__init__(script) - - def isAutoFocusEvent(self, event): - if event.source != self._changeToEntry: - return False - - if not AXUtilities.is_push_button(cthulhu_state.locusOfFocus): - return False - - lastKey, mods = self._script.utilities.lastKeyAndModifiers() - keys = self._script.utilities.mnemonicShortcutAccelerator(cthulhu_state.locusOfFocus) - for key in keys: - if key.endswith(lastKey.upper()): - return True - - return False - - def _isCandidateWindow(self, window): - # Check for dialog or modal window (Thunderbird may use either) - if not (AXUtilities.is_dialog(window) or AXUtilities.is_modal(window)): - tokens = ["THUNDERBIRD SPELL CHECK:", window, "is not a dialog or modal window"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - def isNonSpellCheckChild(x): - return AXUtilities.is_page_tab_list(x) or AXUtilities.is_split_pane(x) - - if AXObject.find_descendant(window, isNonSpellCheckChild): - return False - - return True - - def _findChangeToEntry(self, root): - def isSingleLineEntry(x): - return AXUtilities.is_entry(x) and AXUtilities.is_single_line(x) - - return AXObject.find_descendant(root, isSingleLineEntry) - - def _findErrorWidget(self, root): - def isError(x): - return AXUtilities.is_label(x) \ - and ":" not in AXObject.get_name(x) \ - and not AXUtilitiesRelation.get_relations(x) - - return AXObject.find_descendant(root, isError) - - def _findSuggestionsList(self, root): - def isList(x): - if not AXObject.supports_selection(x): - return False - return AXUtilities.is_list_box(x) or AXUtilities.is_list(x) - - return AXObject.find_descendant(root, isList) - - def _getSuggestionIndexAndPosition(self, suggestion): - attrs = self._script.utilities.objectAttributes(suggestion) - index = attrs.get("posinset") - total = attrs.get("setsize") - if index is None or total is None: - return super()._getSuggestionIndexAndPosition(suggestion) - - return int(index), int(total) diff --git a/src/cthulhu/scripts/apps/__init__.py b/src/cthulhu/scripts/apps/__init__.py deleted file mode 100644 index c28d24d..0000000 --- a/src/cthulhu/scripts/apps/__init__.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__all__ = ['Banshee', - 'Eclipse', - 'Mumble', - 'epiphany', - 'evince', - 'evolution', - 'gajim', - 'gcalctool', - 'gedit', - 'gnome-documents', - 'gnome-shell', - 'kwin', - 'notification-daemon', - 'notify-osd', - 'pidgin', - 'soffice', - 'SeaMonkey', - 'smuxi-frontend-gnome', - 'steamwebhelper', - 'Thunderbird', - 'xfwm4'] diff --git a/src/cthulhu/scripts/apps/epiphany/__init__.py b/src/cthulhu/scripts/apps/epiphany/__init__.py deleted file mode 100644 index 9f97092..0000000 --- a/src/cthulhu/scripts/apps/epiphany/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for epiphany.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 - -from .script import Script - diff --git a/src/cthulhu/scripts/apps/epiphany/meson.build b/src/cthulhu/scripts/apps/epiphany/meson.build deleted file mode 100644 index a902813..0000000 --- a/src/cthulhu/scripts/apps/epiphany/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -epiphany_python_sources = files([ - '__init__.py', - 'script.py', -]) - -python3.install_sources( - epiphany_python_sources, - subdir: 'cthulhu/scripts/apps/epiphany' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/epiphany/script.py b/src/cthulhu/scripts/apps/epiphany/script.py deleted file mode 100644 index 6792b8c..0000000 --- a/src/cthulhu/scripts/apps/epiphany/script.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for epiphany.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.cthulhu as cthulhu -import cthulhu.scripts.toolkits.gtk as gtk -import cthulhu.scripts.toolkits.WebKitGtk as WebKitGtk - -class Script(WebKitGtk.Script): - - def __init__(self, app): - WebKitGtk.Script.__init__(self, app) - - def onWindowActivated(self, event): - """Callback for window:activate accessibility events.""" - - gtk.Script.onWindowActivated(self, event) - - obj, offset = self.utilities.getCaretContext() - if obj: - cthulhu.setLocusOfFocus(None, obj) - - def onWindowDeactivated(self, event): - """Callback for window:deactivate accessibility events.""" - - gtk.Script.onWindowDeactivated(self, event) - diff --git a/src/cthulhu/scripts/apps/evince/__init__.py b/src/cthulhu/scripts/apps/evince/__init__.py deleted file mode 100644 index 18e4096..0000000 --- a/src/cthulhu/scripts/apps/evince/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for evince.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script diff --git a/src/cthulhu/scripts/apps/evince/meson.build b/src/cthulhu/scripts/apps/evince/meson.build deleted file mode 100644 index 9c37e45..0000000 --- a/src/cthulhu/scripts/apps/evince/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -evince_python_sources = files([ - '__init__.py', - 'script.py', -]) - -python3.install_sources( - evince_python_sources, - subdir: 'cthulhu/scripts/apps/evince' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/evince/script.py b/src/cthulhu/scripts/apps/evince/script.py deleted file mode 100644 index c0bd333..0000000 --- a/src/cthulhu/scripts/apps/evince/script.py +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for evince.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013 The Cthulhu Team." -__license__ = "LGPL" - -import cthulhu.keybindings as keybindings -import cthulhu.cthulhu as cthulhu -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.scripts.toolkits.gtk as gtk -from cthulhu.ax_utilities import AXUtilities -from cthulhu.structural_navigation import StructuralNavigation - - -######################################################################## -# # -# The evince script class. # -# # -######################################################################## - -class Script(gtk.Script): - - def __init__(self, app): - """Creates a new script for the given application. - - Arguments: - - app: the application to create a script for. - """ - - gtk.Script.__init__(self, app) - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for this script that can be - called by the key and braille bindings.""" - - gtk.Script.setupInputEventHandlers(self) - self.inputEventHandlers.update( - self.structuralNavigation.inputEventHandlers) - - def getAppKeyBindings(self): - """Returns the application-specific keybindings for this script.""" - - keyBindings = keybindings.KeyBindings() - bindings = self.structuralNavigation.keyBindings - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - return keyBindings - - def getStructuralNavigation(self): - """Returns the 'structural navigation' class for this script.""" - - types = self.getEnabledStructuralNavigationTypes() - return StructuralNavigation(self, types, True) - - def getEnabledStructuralNavigationTypes(self): - """Returns a list of the structural navigation object types - enabled in this script.""" - - enabledTypes = [StructuralNavigation.BUTTON, - StructuralNavigation.CHECK_BOX, - StructuralNavigation.COMBO_BOX, - StructuralNavigation.ENTRY, - StructuralNavigation.FORM_FIELD, - StructuralNavigation.HEADING, - StructuralNavigation.LINK, - StructuralNavigation.LIST, - StructuralNavigation.LIST_ITEM, - StructuralNavigation.PARAGRAPH, - StructuralNavigation.RADIO_BUTTON, - StructuralNavigation.TABLE, - StructuralNavigation.TABLE_CELL, - StructuralNavigation.UNVISITED_LINK, - StructuralNavigation.VISITED_LINK] - - return enabledTypes - - def useStructuralNavigationModel(self, debugOutput=True): - """Returns True if we should do our own structural navigation.""" - - if not self.structuralNavigation.enabled: - return False - - if AXUtilities.is_editable(cthulhu_state.locusOfFocus): - return False - - return True - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - obj = event.source - if AXUtilities.is_focused(obj): - cthulhu.setLocusOfFocus(event, event.source, False) - - gtk.Script.onCaretMoved(self, event) diff --git a/src/cthulhu/scripts/apps/evolution/__init__.py b/src/cthulhu/scripts/apps/evolution/__init__.py deleted file mode 100644 index 2570c89..0000000 --- a/src/cthulhu/scripts/apps/evolution/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Evolution.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script diff --git a/src/cthulhu/scripts/apps/evolution/braille_generator.py b/src/cthulhu/scripts/apps/evolution/braille_generator.py deleted file mode 100644 index 462d467..0000000 --- a/src/cthulhu/scripts/apps/evolution/braille_generator.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2015 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.braille as braille -import cthulhu.braille_generator as braille_generator -import cthulhu.scripts.toolkits.WebKitGtk as WebKitGtk - -class BrailleGenerator(WebKitGtk.BrailleGenerator, braille_generator.BrailleGenerator): - - def __init__(self, script): - super().__init__(script) - self._cache = {} - - def _isMessageListToggleCell(self, obj): - cached = self._cache.get(hash(obj), {}) - rv = cached.get("isMessageListToggleCell") - if rv is None: - rv = self._script.utilities.isMessageListToggleCell(obj) - cached["isMessageListToggleCell"] = rv - self._cache[hash(obj)] = cached - - return rv - - def _generateRealActiveDescendantDisplayedText(self, obj, **args): - if self._isMessageListToggleCell(obj): - return [] - - return super()._generateRealActiveDescendantDisplayedText(obj, **args) - - def generateBraille(self, obj, **args): - self._cache = {} - result, focusedRegion = super().generateBraille(obj, **args) - self._cache = {} - - if not result or focusedRegion != result[0]: - return [result, focusedRegion] - - def hasObj(x): - return isinstance(x, (braille.Component, braille.Text)) - - def isObj(x): - return self._script.utilities.isSameObject(obj, x.accessible) - - matches = [r for r in result if hasObj(r) and isObj(r)] - if matches: - focusedRegion = matches[0] - - return [result, focusedRegion] diff --git a/src/cthulhu/scripts/apps/evolution/meson.build b/src/cthulhu/scripts/apps/evolution/meson.build deleted file mode 100644 index d5209ed..0000000 --- a/src/cthulhu/scripts/apps/evolution/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -evolution_python_sources = files([ - '__init__.py', - 'braille_generator.py', - 'script.py', - 'script_utilities.py', - 'speech_generator.py', -]) - -python3.install_sources( - evolution_python_sources, - subdir: 'cthulhu/scripts/apps/evolution' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/evolution/script.py b/src/cthulhu/scripts/apps/evolution/script.py deleted file mode 100644 index d716712..0000000 --- a/src/cthulhu/scripts/apps/evolution/script.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Evolution.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2013 Igalia, S.L." -__license__ = "LGPL" - - -import cthulhu.debug as debug -import cthulhu.cthulhu as cthulhu -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.scripts.toolkits.gtk as gtk -import cthulhu.scripts.toolkits.WebKitGtk as WebKitGtk -import cthulhu.settings_manager as settings_manager -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -from .braille_generator import BrailleGenerator -from .speech_generator import SpeechGenerator -from .script_utilities import Utilities - -_settingsManager = settings_manager.getManager() - -######################################################################## -# # -# The Evolution script class. # -# # -######################################################################## - -class Script(WebKitGtk.Script, gtk.Script): - - def __init__(self, app): - """Creates a new script for the given application. - - Arguments: - - app: the application to create a script for. - """ - - if _settingsManager.getSetting('sayAllOnLoad') is None: - _settingsManager.setSetting('sayAllOnLoad', False) - - super().__init__(app) - self.presentIfInactive = False - - def getBrailleGenerator(self): - return BrailleGenerator(self) - - def getSpeechGenerator(self): - return SpeechGenerator(self) - - def getUtilities(self): - return Utilities(self) - - def isActivatableEvent(self, event): - """Returns True if the given event is one that should cause this - script to become the active script. This is only a hint to - the focus tracking manager and it is not guaranteed this - request will be honored. Note that by the time the focus - tracking manager calls this method, it thinks the script - should become active. This is an opportunity for the script - to say it shouldn't. - """ - - if event.type.startswith("focus:") and AXUtilities.is_menu(event.source): - return True - - window = self.utilities.topLevelObject(event.source) - if not AXUtilities.is_active(window): - return False - - return True - - def stopSpeechOnActiveDescendantChanged(self, event): - """Whether or not speech should be stopped prior to setting the - locusOfFocus in onActiveDescendantChanged. - - Arguments: - - event: the Event - - Returns True if speech should be stopped; False otherwise. - """ - - return False - - ######################################################################## - # # - # AT-SPI OBJECT EVENT HANDLERS # - # # - ######################################################################## - - def onActiveDescendantChanged(self, event): - """Callback for object:active-descendant-changed accessibility events.""" - - if not event.any_data: - msg = "EVOLUTION: Ignoring event. No any_data." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.utilities.isComposeAutocomplete(event.source): - if AXUtilities.is_selected(event.any_data): - msg = "EVOLUTION: Source is compose autocomplete with selected child." - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.any_data) - else: - msg = "EVOLUTION: Source is compose autocomplete without selected child." - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source) - return - - if AXUtilities.is_table_cell(cthulhu_state.locusOfFocus): - table = AXObject.find_ancestor( - cthulhu_state.locusOfFocus, AXUtilities.is_tree_or_tree_table) - if table is not None and table != event.source: - msg = "EVOLUTION: Event is from a different tree or tree table." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - child = AXObject.get_active_descendant_checked(event.source, event.any_data) - if child is not None and child != event.any_data: - tokens = ["EVOLUTION: Bogus any_data suspected. Setting focus to", child] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, child) - return - - msg = "EVOLUTION: Passing event to super class for processing." - debug.printMessage(debug.LEVEL_INFO, msg, True) - super().onActiveDescendantChanged(event) - - def onBusyChanged(self, event): - """Callback for object:state-changed:busy accessibility events.""" - pass - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - if self.utilities.isWebKitGtk(event.source): - return - - # This is some mystery child of the 'Messages' panel which fails to show - # up in the hierarchy or emit object:state-changed:focused events. - if AXUtilities.is_layered_pane(event.source): - obj = self.utilities.realActiveDescendant(event.source) - cthulhu.setLocusOfFocus(event, obj) - return - - gtk.Script.onFocus(self, event) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - if self.utilities.isWebKitGtk(event.source): - return - - gtk.Script.onNameChanged(self, event) - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - if AXUtilities.is_combo_box(event.source) \ - and not AXUtilities.is_focused(event.source): - return - - gtk.Script.onSelectionChanged(self, event) diff --git a/src/cthulhu/scripts/apps/evolution/script_utilities.py b/src/cthulhu/scripts/apps/evolution/script_utilities.py deleted file mode 100644 index 54bc9ab..0000000 --- a/src/cthulhu/scripts/apps/evolution/script_utilities.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2015 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.scripts.toolkits.gtk as gtk -import cthulhu.scripts.toolkits.WebKitGtk as WebKitGtk -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - - -class Utilities(WebKitGtk.Utilities, gtk.Utilities): - - def __init__(self, script): - super().__init__(script) - - def isComposeMessageBody(self, obj): - if not AXUtilities.is_editable(obj): - return False - - return self.isEmbeddedDocument(obj) - - def isReceivedMessage(self, obj): - if AXUtilities.is_editable(obj): - return False - - return self.isEmbeddedDocument(obj) - - def isReceivedMessageHeader(self, obj): - if not AXUtilities.is_table(obj): - return False - - return self.isReceivedMessage(AXObject.get_parent(obj)) - - def isReceivedMessageContent(self, obj): - if not AXUtilities.is_section(obj): - return False - - return self.isReceivedMessage(AXObject.get_parent(obj)) - - def isComposeAutocomplete(self, obj): - if not AXUtilities.is_table(obj): - return False - - if not AXUtilities.manages_descendants(obj): - return False - - return AXUtilities.is_window(self.topLevelObject(obj)) - - def findMessageBodyChild(self, root): - candidate = AXObject.find_descendant(root, self.isDocument) - if self.isEmbeddedDocument(candidate): - return self.findMessageBodyChild(candidate) - - return candidate - - def isMessageListStatusCell(self, obj): - if not self.isMessageListToggleCell(obj): - return False - - header = self.columnHeaderForCell(obj) - return header and AXObject.get_name(header) != AXObject.get_name(obj) - - def isMessageListToggleCell(self, obj): - if self.isWebKitGtk(obj): - return False - - if not gtk.Utilities.hasMeaningfulToggleAction(self, obj): - return False - - if not AXObject.get_name(obj): - return False - - return True - - def realActiveDescendant(self, obj): - if self.isWebKitGtk(obj): - return super().realActiveDescendant(obj) - - # This is some mystery child of the 'Messages' panel which fails to show - # up in the hierarchy or emit object:state-changed:focused events. - if AXUtilities.is_layered_pane(obj): - return AXObject.find_descendant(obj, AXUtilities.is_tree_table) or obj - - return gtk.Utilities.realActiveDescendant(self, obj) - - def setCaretAtStart(self, obj): - if self.isReceivedMessageContent(obj): - obj = self.findMessageBodyChild(obj) or obj - - child, index = super().setCaretAtStart(obj) - if child and index == -1: - child, index = super().setCaretAtStart(child) - - return child, index - - def treatAsBrowser(self, obj): - if not self.isEmbeddedDocument(obj): - return False - - if AXObject.find_ancestor(obj, AXUtilities.is_split_pane) is not None: - return False - - return True diff --git a/src/cthulhu/scripts/apps/evolution/speech_generator.py b/src/cthulhu/scripts/apps/evolution/speech_generator.py deleted file mode 100644 index 9157133..0000000 --- a/src/cthulhu/scripts/apps/evolution/speech_generator.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2015 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.scripts.toolkits.WebKitGtk as WebKitGtk -import cthulhu.speech_generator as speech_generator -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - - -class SpeechGenerator(WebKitGtk.SpeechGenerator, speech_generator.SpeechGenerator): - - def __init__(self, script): - super().__init__(script) - self._cache = {} - - def _isTreeTableCell(self, obj): - cached = self._cache.get(hash(obj), {}) - rv = cached.get("isTreeTableCell") - if rv is None: - rv = AXUtilities.is_tree_table(AXObject.get_parent(obj)) - cached["isTreeTableCell"] = rv - self._cache[hash(obj)] = cached - - return rv - - def _isMessageListStatusCell(self, obj): - cached = self._cache.get(hash(obj), {}) - rv = cached.get("isMessageListStatusCell") - if rv is None: - rv = self._script.utilities.isMessageListStatusCell(obj) - cached["isMessageListStatusCell"] = rv - self._cache[hash(obj)] = cached - - return rv - - def _isMessageListToggleCell(self, obj): - cached = self._cache.get(hash(obj), {}) - rv = cached.get("isMessageListToggleCell") - if rv is None: - rv = self._script.utilities.isMessageListToggleCell(obj) - cached["isMessageListToggleCell"] = rv - self._cache[hash(obj)] = cached - - return rv - - def _isFocused(self, obj): - cached = self._cache.get(hash(obj), {}) - rv = cached.get("isFocused") - if rv is None: - rv = AXUtilities.is_focused(obj) - cached["isFocused"] = rv - self._cache[hash(obj)] = cached - - return rv - - def _isChecked(self, obj): - cached = self._cache.get(hash(obj), {}) - rv = cached.get("isChecked") - if rv is None: - rv = AXUtilities.is_checked(obj) - cached["isChecked"] = rv - self._cache[hash(obj)] = cached - - return rv - - def _isInNewRow(self, obj): - cached = self._cache.get(hash(obj), {}) - rv = cached.get("isInNewRow") - if rv is None: - row, column = self._script.utilities.coordinatesForCell(obj) - lastRow = self._script.pointOfReference.get("lastRow") - rv = row != lastRow - cached["isInNewRow"] = rv - self._cache[hash(obj)] = cached - - return rv - - def _generateCellCheckedState(self, obj, **args): - if self._isMessageListStatusCell(obj): - return [] - - if self._isMessageListToggleCell(obj): - if self._isInNewRow(obj) or not self._isFocused(obj): - return [] - - return super()._generateCellCheckedState(obj, **args) - - def _generateLabel(self, obj, **args): - if self._isMessageListToggleCell(obj): - return [] - - return super()._generateLabel(obj, **args) - - def _generateName(self, obj, **args): - if self._isMessageListToggleCell(obj) \ - and not self._isMessageListStatusCell(obj): - return [] - - return super()._generateName(obj, **args) - - def _generateLabelOrName(self, obj, **args): - if self._isMessageListToggleCell(obj) \ - and not self._isMessageListStatusCell(obj): - return [] - - return super()._generateLabelOrName(obj, **args) - - def _generateRealActiveDescendantDisplayedText(self, obj, **args): - if self._isMessageListToggleCell(obj) \ - and not self._isMessageListStatusCell(obj): - if not self._isChecked(obj): - return [] - if self._isFocused(obj) and not self._isInNewRow(obj): - return [] - - return super()._generateRealActiveDescendantDisplayedText(obj, **args) - - def _generateRoleName(self, obj, **args): - if self._isMessageListToggleCell(obj) and not self._isFocused(obj): - return [] - - return super()._generateRoleName(obj, **args) - - def _generateUnselectedCell(self, obj, **args): - if self._isMessageListToggleCell(obj) or self._isTreeTableCell(obj): - return [] - - return super()._generateUnselectedCell(obj, **args) - - def generateSpeech(self, obj, **args): - self._cache = {} - results = super().generateSpeech(obj, **args) - self._cache = {} - - return results diff --git a/src/cthulhu/scripts/apps/gajim/__init__.py b/src/cthulhu/scripts/apps/gajim/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/apps/gajim/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/apps/gajim/meson.build b/src/cthulhu/scripts/apps/gajim/meson.build deleted file mode 100644 index 99e7ba7..0000000 --- a/src/cthulhu/scripts/apps/gajim/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -gajim_python_sources = files([ - '__init__.py', - 'script.py', -]) - -python3.install_sources( - gajim_python_sources, - subdir: 'cthulhu/scripts/apps/gajim' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/gajim/script.py b/src/cthulhu/scripts/apps/gajim/script.py deleted file mode 100644 index 4161f08..0000000 --- a/src/cthulhu/scripts/apps/gajim/script.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Gajim.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.chat as chat -import cthulhu.scripts.default as default -from cthulhu.ax_utilities import AXUtilities - -######################################################################## -# # -# The Empathy script class. # -# # -######################################################################## - -class Script(default.Script): - - def __init__(self, app): - """Creates a new script for the given application.""" - - # So we can take an educated guess at identifying the buddy list. - # - self._buddyListAncestries = [[Atspi.Role.TABLE, - Atspi.Role.SCROLL_PANE, - Atspi.Role.FILLER, - Atspi.Role.SPLIT_PANE, - Atspi.Role.FILLER, - Atspi.Role.FRAME]] - - default.Script.__init__(self, app) - - def getChat(self): - """Returns the 'chat' class for this script.""" - - return chat.Chat(self, self._buddyListAncestries) - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for this script that can be - called by the key and braille bindings. Here we need to add the - handlers for chat functionality. - """ - - default.Script.setupInputEventHandlers(self) - self.inputEventHandlers.update(self.chat.inputEventHandlers) - - def getAppKeyBindings(self): - """Returns the application-specific keybindings for this script.""" - - return self.chat.keyBindings - - def getAppPreferencesGUI(self): - """Return a GtkGrid containing the application unique configuration - GUI items for the current application. The chat-related options get - created by the chat module.""" - - return self.chat.getAppPreferencesGUI() - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - return self.chat.getPreferencesFromGUI() - - def onTextInserted(self, event): - """Called whenever text is added to an object.""" - - if self.chat.presentInsertedText(event): - return - - default.Script.onTextInserted(self, event) - - def onWindowActivated(self, event): - """Called whenever a toplevel window is activated.""" - - # Hack to "tickle" the accessible hierarchy. Otherwise, the - # events we need to present text added to the chatroom are - # missing. - AXUtilities.find_all_page_tabs(event.source) - default.Script.onWindowActivated(self, event) diff --git a/src/cthulhu/scripts/apps/gcalctool/__init__.py b/src/cthulhu/scripts/apps/gcalctool/__init__.py deleted file mode 100644 index 2570c89..0000000 --- a/src/cthulhu/scripts/apps/gcalctool/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Evolution.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script diff --git a/src/cthulhu/scripts/apps/gcalctool/meson.build b/src/cthulhu/scripts/apps/gcalctool/meson.build deleted file mode 100644 index 8f1c370..0000000 --- a/src/cthulhu/scripts/apps/gcalctool/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -gcalctool_python_sources = files([ - '__init__.py', - 'script.py', -]) - -python3.install_sources( - gcalctool_python_sources, - subdir: 'cthulhu/scripts/apps/gcalctool' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/gcalctool/script.py b/src/cthulhu/scripts/apps/gcalctool/script.py deleted file mode 100644 index c09b460..0000000 --- a/src/cthulhu/scripts/apps/gcalctool/script.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides a custom script for gcalctool.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.scripts.toolkits.gtk as gtk -import cthulhu.messages as messages -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -######################################################################## -# # -# The GCalcTool script class. # -# # -######################################################################## - -class Script(gtk.Script): - - def __init__(self, app): - """Creates a new script for the given application. Callers - should use the get_script factory method instead of calling - this constructor directly. - - Arguments: - - app: the application to create a script for. - """ - - gtk.Script.__init__(self, app) - - self._resultsDisplay = None - self._statusLine = None - - def onWindowActivated(self, event): - """Called whenever one of gcalctool's toplevel windows is activated. - - Arguments: - - event: the window activated Event - """ - - if self._resultsDisplay and self._statusLine: - gtk.Script.onWindowActivated(self, event) - return - - if AXObject.get_role(event.source) != Atspi.Role.FRAME: - gtk.Script.onWindowActivated(self, event) - return - - self._resultsDisplay = AXObject.find_descendant(event.source, AXUtilities.is_editbar) - if not self._resultsDisplay: - self.presentMessage(messages.CALCULATOR_DISPLAY_NOT_FOUND) - - def isStatusLine(x): - return AXObject.get_role(x) == Atspi.Role.TEXT and not AXUtilities.is_editable(x) - - self._statusLine = AXObject.find_descendant(event.source, isStatusLine) - gtk.Script.onWindowActivated(self, event) - - def onTextInserted(self, event): - """Called whenever text is inserted into gcalctool's text display. - - Arguments: - - event: the text inserted Event - """ - - if self.utilities.isSameObject(event.source, self._statusLine): - self.presentMessage(self.utilities.displayedText(self._statusLine)) - return - - gtk.Script.onTextInserted(self, event) diff --git a/src/cthulhu/scripts/apps/gedit/__init__.py b/src/cthulhu/scripts/apps/gedit/__init__.py deleted file mode 100644 index 7dc74c9..0000000 --- a/src/cthulhu/scripts/apps/gedit/__init__.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for gedit.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script diff --git a/src/cthulhu/scripts/apps/gedit/meson.build b/src/cthulhu/scripts/apps/gedit/meson.build deleted file mode 100644 index 13b7ad1..0000000 --- a/src/cthulhu/scripts/apps/gedit/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -gedit_python_sources = files([ - '__init__.py', - 'script.py', - 'spellcheck.py', -]) - -python3.install_sources( - gedit_python_sources, - subdir: 'cthulhu/scripts/apps/gedit' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/gedit/script.py b/src/cthulhu/scripts/apps/gedit/script.py deleted file mode 100644 index 371eaec..0000000 --- a/src/cthulhu/scripts/apps/gedit/script.py +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for gedit.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -import cthulhu.cthulhu as cthulhu -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.scripts.toolkits.gtk as gtk -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from .spellcheck import SpellCheck - -class Script(gtk.Script): - - def __init__(self, app): - """Creates a new script for the given application.""" - - gtk.Script.__init__(self, app) - - def getSpellCheck(self): - """Returns the spellcheck for this script.""" - - return SpellCheck(self) - - def getAppPreferencesGUI(self): - """Returns a GtkGrid containing the application unique configuration - GUI items for the current application.""" - - from gi.repository import Gtk - - grid = Gtk.Grid() - grid.set_border_width(12) - grid.attach(self.spellcheck.getAppPreferencesGUI(), 0, 0, 1, 1) - grid.show_all() - - return grid - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - return self.spellcheck.getPreferencesFromGUI() - - def locus_of_focus_changed(self, event, oldFocus, newFocus): - """Handles changes of focus of interest to the script.""" - - if self.spellcheck.isSuggestionsItem(newFocus): - includeLabel = not self.spellcheck.isSuggestionsItem(oldFocus) - cthulhu.emitRegionChanged(newFocus) - self.updateBraille(newFocus) - self.spellcheck.presentSuggestionListItem(includeLabel=includeLabel) - return - - super().locus_of_focus_changed(event, oldFocus, newFocus) - - def onActiveDescendantChanged(self, event): - """Callback for object:active-descendant-changed accessibility events.""" - - if event.source == self.spellcheck.getSuggestionsList(): - return - - gtk.Script.onActiveDescendantChanged(self, event) - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - if AXUtilities.is_multi_line(event.source): - self.spellcheck.setDocumentPosition(event.source, event.detail1) - - gtk.Script.onCaretMoved(self, event) - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if not event.detail1: - return - - gtk.Script.onFocusedChanged(self, event) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - if not self.spellcheck.isActive(): - gtk.Script.onNameChanged(self, event) - return - - name = AXObject.get_name(event.source) - if name == self.spellcheck.getMisspelledWord(): - self.spellcheck.presentErrorDetails() - return - - parent = AXObject.get_parent(event.source) - if parent != self.spellcheck.getSuggestionsList() \ - or not AXUtilities.is_focused(parent): - return - - entry = self.spellcheck.getChangeToEntry() - if name != self.utilities.displayedText(entry): - return - - # If we're here, the locusOfFocus was in the selection list when - # that list got destroyed and repopulated. Focus is still there. - cthulhu.setLocusOfFocus(event, event.source, False) - self.updateBraille(cthulhu_state.locusOfFocus) - - def onSensitiveChanged(self, event): - """Callback for object:state-changed:sensitive accessibility events.""" - - if event.source == self.spellcheck.getChangeToEntry() \ - and self.spellcheck.presentCompletionMessage(): - return - - gtk.Script.onSensitiveChanged(self, event) - - def onTextSelectionChanged(self, event): - """Callback for object:text-selection-changed accessibility events.""" - - if event.source == cthulhu_state.locusOfFocus: - gtk.Script.onTextSelectionChanged(self, event) - return - - if not self.utilities.isSearchEntry(cthulhu_state.locusOfFocus, True): - return - - if not self.utilities.isShowingAndVisible(event.source): - return - - # To avoid extreme chattiness. - keyString, mods = self.utilities.lastKeyAndModifiers() - if keyString in ["BackSpace", "Delete"]: - return - - self.sayLine(event.source) - - def onWindowActivated(self, event): - """Callback for window:activate accessibility events.""" - - gtk.Script.onWindowActivated(self, event) - if not self.spellcheck.isCheckWindow(event.source): - return - - self.spellcheck.presentErrorDetails() - cthulhu.setLocusOfFocus(None, self.spellcheck.getChangeToEntry(), False) - self.updateBraille(cthulhu_state.locusOfFocus) - - def onWindowDeactivated(self, event): - """Callback for window:deactivate accessibility events.""" - - gtk.Script.onWindowDeactivated(self, event) - self.spellcheck.deactivate() diff --git a/src/cthulhu/scripts/apps/gedit/spellcheck.py b/src/cthulhu/scripts/apps/gedit/spellcheck.py deleted file mode 100644 index 6e81441..0000000 --- a/src/cthulhu/scripts/apps/gedit/spellcheck.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Customized support for spellcheck in Gedit.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.spellcheck as spellcheck -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_relation import AXUtilitiesRelation - - -class SpellCheck(spellcheck.SpellCheck): - - def __init__(self, script): - super(SpellCheck, self).__init__(script) - - def _isCandidateWindow(self, window): - if not window: - return False - - role = AXObject.get_role(window) - if role == Atspi.Role.DIALOG: - return True - if role != Atspi.Role.FRAME: - return False - - if AXObject.find_descendant(window, AXUtilities.is_split_pane): - return False - - return True - - def _findChangeToEntry(self, root): - def isEntry(x): - return AXUtilities.is_text(x) and AXUtilities.is_single_line(x) - - return AXObject.find_descendant(root, isEntry) - - def _findErrorWidget(self, root): - panel = AXObject.find_ancestor(self._changeToEntry, AXUtilities.is_panel) - if panel is None: - return None - - def isError(x): - return AXUtilities.is_label(x) \ - and ":" not in AXObject.get_name(x) and not AXUtilitiesRelation.get_relations(x) - - return AXObject.find_descendant(panel, isError) - - def _findSuggestionsList(self, root): - def isTable(x): - return AXUtilities.is_table(x) and AXObject.supports_selection(x) - - return AXObject.find_descendant(root, isTable) - - def _getSuggestionIndexAndPosition(self, suggestion): - index, total = self._script.utilities.getPositionAndSetSize(suggestion) - total -= 1 - return index, total diff --git a/src/cthulhu/scripts/apps/gnome-documents/__init__.py b/src/cthulhu/scripts/apps/gnome-documents/__init__.py deleted file mode 100644 index 7020fea..0000000 --- a/src/cthulhu/scripts/apps/gnome-documents/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for gnome-documents.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script -from .script_utilities import Utilities diff --git a/src/cthulhu/scripts/apps/gnome-documents/meson.build b/src/cthulhu/scripts/apps/gnome-documents/meson.build deleted file mode 100644 index e3e115e..0000000 --- a/src/cthulhu/scripts/apps/gnome-documents/meson.build +++ /dev/null @@ -1,11 +0,0 @@ -gnome_documents_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', - 'speech_generator.py', -]) - -python3.install_sources( - gnome_documents_python_sources, - subdir: 'cthulhu/scripts/apps/gnome-documents' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/gnome-documents/script.py b/src/cthulhu/scripts/apps/gnome-documents/script.py deleted file mode 100644 index 8a0bba5..0000000 --- a/src/cthulhu/scripts/apps/gnome-documents/script.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for gnome-documents.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013 The Cthulhu Team" -__license__ = "LGPL" - -import cthulhu.scripts.toolkits.gtk as gtk -import cthulhu.cthulhu_state as cthulhu_state -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -from .speech_generator import SpeechGenerator -from .script_utilities import Utilities - -class Script(gtk.Script): - - def __init__(self, app): - """Creates a new script for the given application. - - Arguments: - - app: the application to create a script for. - """ - - gtk.Script.__init__(self, app) - - def getSpeechGenerator(self): - """Returns the speech generator for this script.""" - - return SpeechGenerator(self) - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def onNameChanged(self, event): - """Callback for accessible name change events.""" - - # Present page changes in the previewer. - if AXUtilities.is_label(event.source) \ - and self.utilities.isDocument(cthulhu_state.locusOfFocus): - self.presentMessage(event.any_data) - - # HACK: Reposition the caret offset from the last character to the - # first so that SayAll will say all. - if AXObject.supports_text(cthulhu_state.locusOfFocus): - AXText.set_caret_offset(cthulhu_state.locusOfFocus, 0) - return self.sayAll(None) - - gtk.Script.onNameChanged(self, event) diff --git a/src/cthulhu/scripts/apps/gnome-documents/script_utilities.py b/src/cthulhu/scripts/apps/gnome-documents/script_utilities.py deleted file mode 100644 index 6080a9c..0000000 --- a/src/cthulhu/scripts/apps/gnome-documents/script_utilities.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013 The Cthulhu Team." -__license__ = "LGPL" - -import cthulhu.scripts.toolkits.gtk as gtk - -class Utilities(gtk.Utilities): - - def __init__(self, script): - gtk.Utilities.__init__(self, script) - - def isReadOnlyTextArea(self, obj): - if self.isDocument(obj): - return False - - return gtk.Utilities.isReadOnlyTextArea(self, obj) - - def isTextArea(self, obj): - if self.isDocument(obj): - return True - - return gtk.Utilities.isTextArea(self, obj) diff --git a/src/cthulhu/scripts/apps/gnome-documents/speech_generator.py b/src/cthulhu/scripts/apps/gnome-documents/speech_generator.py deleted file mode 100644 index 050193a..0000000 --- a/src/cthulhu/scripts/apps/gnome-documents/speech_generator.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom speech generator for gnome-documents.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013 The Cthulhu Team" -__license__ = "LGPL" - -import cthulhu.speech_generator as speech_generator - -class SpeechGenerator(speech_generator.SpeechGenerator): - - def __init__(self, script): - speech_generator.SpeechGenerator.__init__(self, script) - - def _generateUnselectedCell(self, obj, **args): - # There are a number of objects in gnome-documents which claim to - # be selectable, but cannot actually be selected. Until we find and - # fix those issues, this will keep Cthulhu from constantly tacking on - # "not selected" when presenting these objects. - return [] diff --git a/src/cthulhu/scripts/apps/gnome-shell/__init__.py b/src/cthulhu/scripts/apps/gnome-shell/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/apps/gnome-shell/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/apps/gnome-shell/formatting.py b/src/cthulhu/scripts/apps/gnome-shell/formatting.py deleted file mode 100644 index 1893347..0000000 --- a/src/cthulhu/scripts/apps/gnome-shell/formatting.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013 Igalia, S.L." -__license__ = "LGPL" - -# If we were to adhere to the line-length requirements of 100 characters, -# this file would be even more cumbersome to look at than it already is. -# We shall respect the line-length requirements for all files that are not -# formatting.py. -# ruff: noqa: E501 - -import copy -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.formatting -import cthulhu.settings - -formatting = { - 'speech': { - Atspi.Role.MENU_ITEM: { - 'focused': 'expandableState', - 'unfocused': 'labelAndName + pause + unrelatedLabels + pause + menuItemCheckedState + expandableState + availability + ' + cthulhu.formatting.MNEMONIC + ' + accelerator + pause + positionInList', - 'basicWhereAmI': 'ancestors + pause + labelAndName + pause + unrelatedLabels + pause + accelerator + pause + positionInList + ' + cthulhu.formatting.MNEMONIC - }, - }, - 'braille': { - Atspi.Role.MENU_ITEM: { - 'unfocused': '[Component(obj,\ - asString(label + (displayedText or unrelatedLabels) + expandableState + availability) + asString(accelerator),\ - indicator=asString(menuItemCheckedState))]' - }, - } -} - -class Formatting(cthulhu.formatting.Formatting): - def __init__(self, script): - cthulhu.formatting.Formatting.__init__(self, script) - self.update(copy.deepcopy(formatting)) - self._defaultFormatting = cthulhu.formatting.Formatting(script) - - def getFormat(self, **args): - if args.get('useDefaultFormatting', False): - return self._defaultFormatting.getFormat(**args) - else: - return cthulhu.formatting.Formatting.getFormat(self, **args) diff --git a/src/cthulhu/scripts/apps/gnome-shell/meson.build b/src/cthulhu/scripts/apps/gnome-shell/meson.build deleted file mode 100644 index 8a0ea2e..0000000 --- a/src/cthulhu/scripts/apps/gnome-shell/meson.build +++ /dev/null @@ -1,11 +0,0 @@ -gnome_shell_python_sources = files([ - '__init__.py', - 'formatting.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - gnome_shell_python_sources, - subdir: 'cthulhu/scripts/apps/gnome-shell' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/gnome-shell/script.py b/src/cthulhu/scripts/apps/gnome-shell/script.py deleted file mode 100644 index 75dd8d2..0000000 --- a/src/cthulhu/scripts/apps/gnome-shell/script.py +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010-2013 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.cthulhu as cthulhu -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.scripts.toolkits.clutter as clutter -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -from .formatting import Formatting -from .script_utilities import Utilities - -class Script(clutter.Script): - - def __init__(self, app): - clutter.Script.__init__(self, app) - - def getFormatting(self): - """Returns the formatting strings for this script.""" - return Formatting(self) - - def getUtilities(self): - return Utilities(self) - - def deactivate(self): - """Called when this script is deactivated.""" - - self.utilities.clearCachedObjects() - super().deactivate() - - def skipObjectEvent(self, event): - """Determines whether or not this event should be skipped due to - being redundant, part of an event flood, etc.""" - - if AXUtilities.is_window(event.source): - return self.utilities.isBogusWindowFocusClaim(event) - - return clutter.Script.skipObjectEvent(self, event) - - def locus_of_focus_changed(self, event, oldFocus, newFocus): - if event is not None and event.type == "window:activate" \ - and newFocus is not None and not AXObject.get_name(newFocus): - queuedEvent = self._getQueuedEvent("object:state-changed:focused", True) - if queuedEvent and queuedEvent.source != event.source: - msg = "GNOME SHELL: Have matching focused event. Not announcing nameless window." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - super().locus_of_focus_changed(event, oldFocus, newFocus) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - if not AXUtilities.is_label(event.source): - clutter.Script.onNameChanged(self, event) - return - - # If we're already in a dialog, and a label inside that dialog changes its name, - # present the new name. Example: the "Command not found" label in the Run dialog. - dialog = AXObject.find_ancestor(cthulhu_state.locusOfFocus, AXUtilities.is_dialog) - tokens = ["GNOME SHELL: focus", cthulhu_state.locusOfFocus, "is in dialog:", dialog] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if dialog and AXObject.is_ancestor(event.source, dialog): - msg = "GNOME SHELL: Label changed name in current dialog. Presenting." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.presentMessage(AXObject.get_name(event.source)) - - def onSelectedChanged(self, event): - """Callback for object:state-changed:selected accessibility events.""" - - # Some buttons, like the Wikipedia button, claim to be selected but - # lack STATE_SELECTED. The other buttons, such as in the Dash and - # event switcher, seem to have the right state. Since the ones with - # the wrong state seem to be things we don't want to present anyway - # we'll stop doing so and hope we are right. - if event.detail1: - if AXUtilities.is_panel(event.source): - AXObject.clear_cache(event.source) - if AXUtilities.is_selected(event.source): - cthulhu.setLocusOfFocus(event, event.source) - return - - clutter.Script.onSelectedChanged(self, event) - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if not event.detail1: - return - - # We're getting a spurious focus claim from the gnome-shell window after - # the window switcher is used. - if AXUtilities.is_window(event.source): - return - - if not AXObject.get_name(event.source) and AXUtilities.is_menu_item(event.source) \ - and not self.utilities.labelsForObject(event.source): - descendant = AXObject.find_descendant(event.source, AXUtilities.is_slider) - if descendant is not None: - cthulhu.setLocusOfFocus(event, descendant) - return - - clutter.Script.onFocusedChanged(self, event) - - def echoPreviousWord(self, obj, offset=None): - if not AXObject.supports_text(obj): - return False - - if not offset: - caretOffset = AXText.get_caret_offset(obj) - if caretOffset == -1: - offset = AXText.get_character_count(obj) - 1 - else: - offset = caretOffset - 1 - - if offset == 0: - return False - - return super().echoPreviousWord(obj, offset) - - def isActivatableEvent(self, event): - if event.type.startswith('object:state-changed:selected') and event.detail1: - return True - - if self.utilities.isBogusWindowFocusClaim(event): - return False - - return super().isActivatableEvent(event) diff --git a/src/cthulhu/scripts/apps/gnome-shell/script_utilities.py b/src/cthulhu/scripts/apps/gnome-shell/script_utilities.py deleted file mode 100644 index 4e3da5d..0000000 --- a/src/cthulhu/scripts/apps/gnome-shell/script_utilities.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.script_utilities as script_utilities -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_selection import AXSelection -from cthulhu.ax_utilities import AXUtilities - - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - script_utilities.Utilities.__init__(self, script) - self._isLayoutOnly = {} - - def clearCachedObjects(self): - self._isLayoutOnly = {} - - def selectedChildren(self, obj): - if AXObject.supports_selection(obj): - return AXSelection.get_selected_children(obj) - - # This is a workaround for bgo#738705. - if not AXUtilities.is_panel(obj): - return [] - - return AXUtilities.find_all_selected_objects(obj) - - def insertedText(self, event): - if event.any_data: - return event.any_data - - if event.detail1 == -1: - msg = "GNOME SHELL: Broken text insertion event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - text = self.queryNonEmptyText(event.source) - if text: - string = AXText.get_all_text(event.source) - if string: - msg = f"GNOME SHELL: Returning last char in '{string}'" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return string[-1] - - msg = "GNOME SHELL: Unable to correct broken text insertion event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - return "" - - def selectedText(self, obj): - string, start, end = super().selectedText(obj) - if -1 not in [start, end]: - return string, start, end - - tokens = [f"GNOME SHELL: Bogus selection range ({start}, {end}) for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - text = self.queryNonEmptyText(obj) - # Intentional object-local fallback for GNOME Shell's broken selection ranges. - if AXText.get_selected_ranges(obj): - string = AXText.get_all_text(obj) - start, end = 0, len(string) - - tokens = [f"GNOME SHELL: Returning '{string}' ({start}, {end}) for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return string, start, end - - def unrelatedLabels(self, root, onlyShowing=True, minimumWords=3): - if not root: - return [] - - def hasRole(x): - return AXUtilities.is_dialog(x) \ - or AXUtilities.is_notification(x) \ - or AXUtilities.is_menu_item(x) - - if not hasRole(root) and AXObject.find_ancestor(root, hasRole) is None: - tokens = ["GNOME SHELL: Not seeking unrelated labels for", root] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - return super().unrelatedLabels(root, onlyShowing, minimumWords) - - def isLayoutOnly(self, obj): - rv = self._isLayoutOnly.get(hash(obj)) - if rv is not None: - return rv - - rv = super().isLayoutOnly(obj) - if not rv and AXUtilities.is_panel(obj) and AXObject.get_child_count(obj) == 1: - child = AXObject.get_child(obj, 0) - if self.displayedLabel(obj) == AXObject.get_name(child) \ - and not AXUtilities.is_label(child): - rv = True - tokens = ["GNOME SHELL:", obj, "is deemed to be layout only"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self._isLayoutOnly[hash(obj)] = rv - return rv - - - def isBogusWindowFocusClaim(self, event): - if event.type.startswith('object:state-changed:focused') and event.detail1 \ - and AXUtilities.is_window(event.source) \ - and not self.canBeActiveWindow(event.source): - msg = "GNOME SHELL: Event is believed to be bogus window focus claim" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False diff --git a/src/cthulhu/scripts/apps/kwin/__init__.py b/src/cthulhu/scripts/apps/kwin/__init__.py deleted file mode 100644 index 99c9ba5..0000000 --- a/src/cthulhu/scripts/apps/kwin/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for kwin.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script - diff --git a/src/cthulhu/scripts/apps/kwin/meson.build b/src/cthulhu/scripts/apps/kwin/meson.build deleted file mode 100644 index 2aadccf..0000000 --- a/src/cthulhu/scripts/apps/kwin/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -kwin_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - kwin_python_sources, - subdir: 'cthulhu/scripts/apps/kwin' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/kwin/script.py b/src/cthulhu/scripts/apps/kwin/script.py deleted file mode 100644 index dd05c9a..0000000 --- a/src/cthulhu/scripts/apps/kwin/script.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for kwin.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2019 Igalia, S.L." -__license__ = "LGPL" - -from cthulhu.scripts import switcher -from cthulhu.scripts.toolkits import Qt - -from .script_utilities import Utilities - - -class Script(switcher.Script, Qt.Script): - - def __init__(self, app): - """Creates a new script for the given application.""" - - super().__init__(app) - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) diff --git a/src/cthulhu/scripts/apps/kwin/script_utilities.py b/src/cthulhu/scripts/apps/kwin/script_utilities.py deleted file mode 100644 index 5c9dcf5..0000000 --- a/src/cthulhu/scripts/apps/kwin/script_utilities.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2019 Igalia, S.L." -__license__ = "LGPL" - -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu.scripts import switcher - - -class Utilities(switcher.Utilities): - - def __init__(self, script): - super().__init__(script) - - def isSwitcherContainer(self, obj): - """Returns True if obj is the switcher container.""" - - return AXUtilities.is_filler(obj) and AXUtilities.is_focused(obj) - - def isSwitcherSelectionChangeEventType(self, event): - """Returns True if this event is the one we use to present changes.""" - - if event.type.startswith("object:state-changed:focused"): - return event.detail1 - - return False - - def getSelectionName(self, container): - """Returns the name of the currently-selected item.""" - - if self.isSwitcherContainer(container): - return AXObject.get_name(container) - - return "" diff --git a/src/cthulhu/scripts/apps/meson.build b/src/cthulhu/scripts/apps/meson.build deleted file mode 100644 index 39b1438..0000000 --- a/src/cthulhu/scripts/apps/meson.build +++ /dev/null @@ -1,30 +0,0 @@ -apps_python_sources = files([ - '__init__.py', -]) - -python3.install_sources( - apps_python_sources, - subdir: 'cthulhu/scripts/apps' -) - -subdir('Banshee') -subdir('Eclipse') -subdir('Mumble') -subdir('SeaMonkey') -subdir('Thunderbird') -subdir('epiphany') -subdir('evince') -subdir('evolution') -subdir('gajim') -subdir('gcalctool') -subdir('gedit') -subdir('gnome-documents') -subdir('gnome-shell') -subdir('kwin') -subdir('notification-daemon') -subdir('notify-osd') -subdir('pidgin') -subdir('soffice') -subdir('smuxi-frontend-gnome') -subdir('steamwebhelper') -subdir('xfwm4') diff --git a/src/cthulhu/scripts/apps/notification-daemon/__init__.py b/src/cthulhu/scripts/apps/notification-daemon/__init__.py deleted file mode 100644 index 0fa412f..0000000 --- a/src/cthulhu/scripts/apps/notification-daemon/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -""" Custom script for notification daemon.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script - diff --git a/src/cthulhu/scripts/apps/notification-daemon/meson.build b/src/cthulhu/scripts/apps/notification-daemon/meson.build deleted file mode 100644 index 552fa98..0000000 --- a/src/cthulhu/scripts/apps/notification-daemon/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -notification_daemon_python_sources = files([ - '__init__.py', - 'script.py', -]) - -python3.install_sources( - notification_daemon_python_sources, - subdir: 'cthulhu/scripts/apps/notification-daemon' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/notification-daemon/script.py b/src/cthulhu/scripts/apps/notification-daemon/script.py deleted file mode 100644 index 6c98acf..0000000 --- a/src/cthulhu/scripts/apps/notification-daemon/script.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -""" Custom script for The notification daemon.""" - -__id__ = "" -__version__ = "" -__date__ = "" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -import cthulhu.messages as messages -import cthulhu.scripts.default as default -import cthulhu.settings as settings -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - - -######################################################################## -# # -# The notification-daemon script class. # -# # -######################################################################## - -class Script(default.Script): - - def onWindowCreated(self, event): - """Callback for window:create accessibility events.""" - - allLabels = AXUtilities.find_all_labels(event.source) - texts = [] - for acc in allLabels: - text = self.utilities.displayedText(acc) or AXObject.get_name(acc) - if text: - texts.append(text) - - text = messages.NOTIFICATION - if texts: - text = f"{text} {' '.join(texts)}" - - voice = self.speechGenerator.voice(obj=event.source, string=text) - self.speakMessage(text, voice=voice) - self.displayBrailleMessage(text, flashTime=settings.brailleFlashTime) - self.notificationPresenter.save_notification(text) diff --git a/src/cthulhu/scripts/apps/notify-osd/__init__.py b/src/cthulhu/scripts/apps/notify-osd/__init__.py deleted file mode 100644 index 6696eff..0000000 --- a/src/cthulhu/scripts/apps/notify-osd/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -""" Custom script for The notify-osd""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script - diff --git a/src/cthulhu/scripts/apps/notify-osd/meson.build b/src/cthulhu/scripts/apps/notify-osd/meson.build deleted file mode 100644 index 130381b..0000000 --- a/src/cthulhu/scripts/apps/notify-osd/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -notify_osd_python_sources = files([ - '__init__.py', - 'script.py', -]) - -python3.install_sources( - notify_osd_python_sources, - subdir: 'cthulhu/scripts/apps/notify-osd' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/notify-osd/script.py b/src/cthulhu/scripts/apps/notify-osd/script.py deleted file mode 100644 index 6c48018..0000000 --- a/src/cthulhu/scripts/apps/notify-osd/script.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -""" Custom script for The notify-osd""" - -__id__ = "" -__version__ = "" -__date__ = "" -__copyright__ = "Copyright (c) 2009 Eitan Isaacson" -__license__ = "LGPL" - -import cthulhu.messages as messages -import cthulhu.scripts.default as default -import cthulhu.settings as settings -import cthulhu.settings_manager as settings_manager -from cthulhu.ax_object import AXObject -from cthulhu.ax_value import AXValue - -_settingsManager = None # Removed - use cthulhuApp.settingsManager - -######################################################################## -# # -# The notify-osd script class. # -# # -######################################################################## - -class Script(default.Script): - def onValueChanged(self, event): - if AXObject.supports_value(event.source): - value = int(AXValue.get_current_value(event.source)) - else: - value = -1 - - if value >= 0: - string = str(value) - voice = self.speechGenerator.voice(obj=event.source, string=string) - self.speakMessage(string, voice=voice) - self.displayBrailleMessage(string, - flashTime=settings.brailleFlashTime) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - if AXObject.supports_value(event.source): - value = AXValue.get_current_value(event.source) - else: - value = -1 - - message = "" - if value < 0: - self.speakMessage(messages.NOTIFICATION) - message = '%s %s' % (AXObject.get_name(event.source), - AXObject.get_description(event.source)) - else: - # A gauge notification, e.g. the Ubuntu volume notification that - # appears when you press the multimedia keys. - # - message = '%s %d' % (AXObject.get_name(event.source), value) - self.speakMessage(message) - - voice = self.speechGenerator.voice(obj=event.source, string=message) - self.speakMessage(message, voice=voice) - self.displayBrailleMessage(message, flashTime=settings.brailleFlashTime) - self.notificationPresenter.save_notification(message) diff --git a/src/cthulhu/scripts/apps/pidgin/__init__.py b/src/cthulhu/scripts/apps/pidgin/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/apps/pidgin/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/apps/pidgin/chat.py b/src/cthulhu/scripts/apps/pidgin/chat.py deleted file mode 100644 index 2c92b70..0000000 --- a/src/cthulhu/scripts/apps/pidgin/chat.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom chat module for Pidgin.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." -__license__ = "LGPL" - -import cthulhu.chat as chat - -######################################################################## -# # -# The Pidgin chat class. # -# # -######################################################################## - -class Chat(chat.Chat): - - def __init__(self, script, buddyListAncestries): - - chat.Chat.__init__(self, script, buddyListAncestries) - - def isTypingStatusChangedEvent(self, event): - """Returns True if event is associated with a change in typing status. - - Arguments: - - event: the accessible event being examined - """ - - if not event.type.startswith("object:text-changed:insert"): - return False - - # Bit of a hack. Pidgin inserts text into the chat history when the - # user is typing. We seem able to (more or less) reliably distinguish - # this text via its attributes because these attributes are absent - # from user inserted text -- no matter how that text is formatted. - # - attr, start, end = \ - self._script.utilities.textAttributes(event.source, event.detail1) - - if float(attr.get('scale', '1')) < 1 \ - or int(attr.get('weight', '400')) < 400: - return True - - return False diff --git a/src/cthulhu/scripts/apps/pidgin/meson.build b/src/cthulhu/scripts/apps/pidgin/meson.build deleted file mode 100644 index 03f4543..0000000 --- a/src/cthulhu/scripts/apps/pidgin/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -pidgin_python_sources = files([ - '__init__.py', - 'chat.py', - 'script.py', - 'script_utilities.py', - 'speech_generator.py', -]) - -python3.install_sources( - pidgin_python_sources, - subdir: 'cthulhu/scripts/apps/pidgin' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/pidgin/script.py b/src/cthulhu/scripts/apps/pidgin/script.py deleted file mode 100644 index 046ce21..0000000 --- a/src/cthulhu/scripts/apps/pidgin/script.py +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for pidgin.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.debug as debug -import cthulhu.messages as messages -import cthulhu.scripts.toolkits.GAIL as GAIL -import cthulhu.settings as settings -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -from .chat import Chat -from .script_utilities import Utilities -from .speech_generator import SpeechGenerator - -######################################################################## -# # -# The Pidgin script class. # -# # -######################################################################## - -class Script(GAIL.Script): - - def __init__(self, app): - """Creates a new script for the given application. - - Arguments: - - app: the application to create a script for. - """ - - # So we can take an educated guess at identifying the buddy list. - # - self._buddyListAncestries = [[Atspi.Role.TREE_TABLE, - Atspi.Role.SCROLL_PANE, - Atspi.Role.FILLER, - Atspi.Role.PAGE_TAB, - Atspi.Role.PAGE_TAB_LIST, - Atspi.Role.FILLER, - Atspi.Role.FRAME]] - - GAIL.Script.__init__(self, app) - - def getChat(self): - """Returns the 'chat' class for this script.""" - - return Chat(self, self._buddyListAncestries) - - def getSpeechGenerator(self): - """Returns the speech generator for this script. """ - - return SpeechGenerator(self) - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for this script that can be - called by the key and braille bindings. Here we need to add the - handlers for chat functionality. - """ - - GAIL.Script.setupInputEventHandlers(self) - self.inputEventHandlers.update(self.chat.inputEventHandlers) - - def getAppKeyBindings(self): - """Returns the application-specific keybindings for this script.""" - - return self.chat.keyBindings - - def getAppPreferencesGUI(self): - """Return a GtkGrid containing the application unique configuration - GUI items for the current application. The chat-related options get - created by the chat module.""" - - return self.chat.getAppPreferencesGUI() - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - return self.chat.getPreferencesFromGUI() - - def onChildrenAdded(self, event): - """Callback for object:children-changed:add accessibility events.""" - - AXObject.clear_cache_now("children-changed event.") - - # Check to see if a new chat room tab has been created and if it - # has, then announce its name. See bug #469098 for more details. - # - if event.type.startswith("object:children-changed:add"): - rolesList = [Atspi.Role.PAGE_TAB_LIST, - Atspi.Role.FILLER, - Atspi.Role.FRAME] - if self.utilities.hasMatchingHierarchy(event.source, rolesList): - # As it's possible to get this component hierarchy in other - # places than the chat room (i.e. the Preferences dialog), - # we check to see if the name of the frame is the same as one - # of its children. If it is, then it's a chat room tab event. - # For a final check, we only announce the new chat tab if the - # last child has a name. - # - nameFound = False - frame = AXObject.find_ancestor(event.source, - lambda x: AXObject.get_role(x) == Atspi.Role.FRAME) - frameName = AXObject.get_name(frame) - if not frameName: - return - for child in AXObject.iter_children(event.source): - if frameName == AXObject.get_name(child): - nameFound = True - break - if nameFound: - child = AXObject.get_child(event.source, -1) - childName = AXObject.get_name(child) - if childName: - line = messages.CHAT_NEW_TAB % childName - voice = self.speechGenerator.voice(obj=child, string=line) - self.speakMessage(line, voice=voice) - - def onNameChanged(self, event): - """Called whenever a property on an object changes. - - Arguments: - - event: the Event - """ - - if self.chat.isInBuddyList(event.source): - return - else: - GAIL.Script.onNameChanged(self, event) - - def onTextDeleted(self, event): - """Called whenever text is deleted from an object. - - Arguments: - - event: the Event - """ - - if self.chat.isInBuddyList(event.source): - return - else: - GAIL.Script.onTextDeleted(self, event) - - def onTextInserted(self, event): - """Called whenever text is added to an object.""" - - if self.chat.presentInsertedText(event): - return - - GAIL.Script.onTextInserted(self, event) - - def onValueChanged(self, event): - """Called whenever an object's value changes. Currently, the - value changes for non-focused objects are ignored. - - Arguments: - - event: the Event - """ - - if self.chat.isInBuddyList(event.source): - return - else: - GAIL.Script.onValueChanged(self, event) - - def onWindowActivated(self, event): - """Called whenever a toplevel window is activated.""" - - if not settings.enableSadPidginHack: - msg = "PIDGIN: Hack for missing events disabled" - debug.printMessage(debug.LEVEL_INFO, msg, True) - GAIL.Script.onWindowActivated(self, event) - return - - msg = "PIDGIN: Starting hack for missing events" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - # Hack to "tickle" the accessible hierarchy. Otherwise, the - # events we need to present text added to the chatroom are - # missing. - AXUtilities.find_all_page_tabs(event.source) - - msg = "PIDGIN: Hack to work around missing events complete" - debug.printMessage(debug.LEVEL_INFO, msg, True) - GAIL.Script.onWindowActivated(self, event) - - def onExpandedChanged(self, event): - """Callback for object:state-changed:expanded accessibility events.""" - - # Overridden here because the event.source is in a hidden column. - obj = event.source - if self.chat.isInBuddyList(obj): - obj = AXObject.get_next_sibling(obj) - self.presentObject(obj, alreadyFocused=True) - return - - GAIL.Script.onExpandedChanged(self, event) diff --git a/src/cthulhu/scripts/apps/pidgin/script_utilities.py b/src/cthulhu/scripts/apps/pidgin/script_utilities.py deleted file mode 100644 index fab236e..0000000 --- a/src/cthulhu/scripts/apps/pidgin/script_utilities.py +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Commonly-required utility methods needed by -- and potentially - customized by -- application and toolkit scripts. They have - been pulled out from the scripts because certain scripts had - gotten way too large as a result of including these methods.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.debug as debug -import cthulhu.script_utilities as script_utilities -from cthulhu.ax_object import AXObject -from cthulhu.ax_table import AXTable -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_relation import AXUtilitiesRelation - -############################################################################# -# # -# Utilities # -# # -############################################################################# - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - """Creates an instance of the Utilities class. - - Arguments: - - script: the script with which this instance is associated. - """ - - script_utilities.Utilities.__init__(self, script) - - ######################################################################### - # # - # Utilities for finding, identifying, and comparing accessibles # - # # - ######################################################################### - - def childNodes(self, obj): - """Gets all of the children that have RELATION_NODE_CHILD_OF pointing - to this expanded table cell. Overridden here because the object - which contains the relation is in a hidden column and thus doesn't - have a column number (necessary for using getAccessibleAt()). - - Arguments: - -obj: the Accessible Object - - Returns: a list of all the child nodes - """ - - if not self._script.chat.isInBuddyList(obj): - return script_utilities.Utilities.childNodes(self, obj) - - parent = AXObject.get_parent(obj) - table = AXTable.get_table(parent) - if table is None: - return [] - - if not AXUtilities.is_expanded(obj): - return [] - - nodes = [] - row, col = AXTable.get_cell_coordinates(obj, prefer_attribute=False) - if row < 0 or col < 0: - return [] - col += 1 - nodeLevel = self.nodeLevel(obj) - - # Candidates will be in the rows beneath the current row. - # Only check in the current column and stop checking as - # soon as the node level of a candidate is equal or less - # than our current level. - # - for i in range(row + 1, AXTable.get_row_count(table, prefer_attribute=False)): - cell = AXTable.get_cell_at(table, i, col) - if not cell: - continue - nodeCell = AXObject.get_previous_sibling(cell) - nodeOf = AXUtilitiesRelation.get_is_node_child_of(nodeCell) - if not nodeOf: - continue - - nodeOf = nodeOf[0] - if self.isSameObject(obj, nodeOf): - nodes.append(cell) - elif self.nodeLevel(nodeOf) <= nodeLevel: - break - - return nodes - - def nodeLevel(self, obj): - """Determines the node level of this object if it is in a tree - relation, with 0 being the top level node. If this object is - not in a tree relation, then -1 will be returned. Overridden - here because the accessible we need is in a hidden column. - - Arguments: - -obj: the Accessible object - """ - - if not obj: - return -1 - - if not self._script.chat.isInBuddyList(obj): - return script_utilities.Utilities.nodeLevel(self, obj) - - obj = AXObject.get_previous_sibling(obj) - parent = AXObject.get_parent(obj) - if AXTable.get_table(parent) is None: - return -1 - - nodes = [] - node = obj - done = False - while not done: - nodeOf = AXUtilitiesRelation.get_is_node_child_of(node) - node = nodeOf[0] if nodeOf else None - - # We want to avoid situations where something gives us an - # infinite cycle of nodes. Bon Echo has been seen to do - # this (see bug 351847). - # - if (len(nodes) > 100) or nodes.count(node): - debug.printMessage(debug.LEVEL_WARNING, "PIDGIN: Detected a cycle of nodes") - done = True - elif node: - nodes.append(node) - else: - done = True - - return len(nodes) - 1 - - ######################################################################### - # # - # Utilities for working with the accessible text interface # - # # - ######################################################################### - - - - ######################################################################### - # # - # Miscellaneous Utilities # - # # - ######################################################################### - - def isZombie(self, obj): - if not super().isZombie(obj): - return False - - if AXObject.get_role(obj) != Atspi.Role.TOGGLE_BUTTON: - return True - - tokens = ["PIDGIN: Hacking around broken index in parent for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return AXObject.get_index_in_parent(obj) != -1 diff --git a/src/cthulhu/scripts/apps/pidgin/speech_generator.py b/src/cthulhu/scripts/apps/pidgin/speech_generator.py deleted file mode 100644 index ccf0978..0000000 --- a/src/cthulhu/scripts/apps/pidgin/speech_generator.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import cthulhu.speech_generator as speech_generator -from cthulhu.ax_object import AXObject - -######################################################################## -# # -# Custom SpeechGenerator # -# # -######################################################################## - -class SpeechGenerator(speech_generator.SpeechGenerator): - """Overrides _generateExpandableState so that we can provide access - to the expanded/collapsed state and node count for the buddy list. - """ - - def __init__(self, script): - speech_generator.SpeechGenerator.__init__(self, script) - - def _generateExpandableState(self, obj, **args): - result = [] - if self._script.chat.isInBuddyList(obj): - # The Pidgin buddy list consists of two columns. The - # column which is set as the expander column and which - # also contains the node relationship is hidden. Hidden - # columns are not included among a table's columns. The - # hidden object of interest seems to always immediately - # precede the visible object. - # - expanderCell = AXObject.get_previous_sibling(obj) - if expanderCell: - result.extend( - speech_generator.SpeechGenerator._generateExpandableState( - self, expanderCell, **args)) - else: - result.extend( - speech_generator.SpeechGenerator._generateExpandableState( - self, obj, **args)) - else: - result.extend( - speech_generator.SpeechGenerator._generateExpandableState( - self, obj, **args)) - return result - - def _generateNumberOfChildren(self, obj, **args): - result = [] - if self._script.chat.isInBuddyList(obj): - # The Pidgin buddy list consists of two columns. The - # column which is set as the expander column and which - # also contains the node relationship is hidden. Hidden - # columns are not included among a table's columns. The - # hidden object of interest seems to always immediately - # precede the visible object. - # - expanderCell = AXObject.get_previous_sibling(obj) - if expanderCell: - result.extend( - speech_generator.SpeechGenerator._generateNumberOfChildren( - self, expanderCell, **args)) - else: - result.extend( - speech_generator.SpeechGenerator._generateNumberOfChildren( - self, obj, **args)) - else: - result.extend( - speech_generator.SpeechGenerator._generateNumberOfChildren( - self, obj, **args)) - return result diff --git a/src/cthulhu/scripts/apps/smuxi-frontend-gnome/__init__.py b/src/cthulhu/scripts/apps/smuxi-frontend-gnome/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/apps/smuxi-frontend-gnome/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/apps/smuxi-frontend-gnome/chat.py b/src/cthulhu/scripts/apps/smuxi-frontend-gnome/chat.py deleted file mode 100644 index b307c99..0000000 --- a/src/cthulhu/scripts/apps/smuxi-frontend-gnome/chat.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom chat module for Smuxi.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2018 Igalia, S.L." -__license__ = "LGPL" - - -import cthulhu.chat as chat -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - - -class Chat(chat.Chat): - - def __init__(self, script, buddyListAncestries): - super().__init__(script, buddyListAncestries) - - def isFocusedChat(self, obj): - """Returns True if we plan to treat this chat as focused.""" - - pageTab = AXObject.find_ancestor(obj, AXUtilities.is_page_tab) - if pageTab is None: - return super().isFocusedChat(obj) - - return AXUtilities.is_showing(pageTab) diff --git a/src/cthulhu/scripts/apps/smuxi-frontend-gnome/meson.build b/src/cthulhu/scripts/apps/smuxi-frontend-gnome/meson.build deleted file mode 100644 index 140df8d..0000000 --- a/src/cthulhu/scripts/apps/smuxi-frontend-gnome/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -smuxi_frontend_gnome_python_sources = files([ - '__init__.py', - 'chat.py', - 'script.py', -]) - -python3.install_sources( - smuxi_frontend_gnome_python_sources, - subdir: 'cthulhu/scripts/apps/smuxi-frontend-gnome' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/smuxi-frontend-gnome/script.py b/src/cthulhu/scripts/apps/smuxi-frontend-gnome/script.py deleted file mode 100644 index 0118954..0000000 --- a/src/cthulhu/scripts/apps/smuxi-frontend-gnome/script.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Smuxi.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2018 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.scripts.toolkits.GAIL as GAIL -from .chat import Chat - -class Script(GAIL.Script): - - def __init__(self, app): - """Creates a new script for the given application.""" - - # So we can take an educated guess at identifying the buddy list. - self._buddyListAncestries = [[Atspi.Role.TREE_TABLE, - Atspi.Role.SCROLL_PANE, - Atspi.Role.SPLIT_PANE, - Atspi.Role.SPLIT_PANE, - Atspi.Role.FILLER, - Atspi.Role.FRAME]] - - super().__init__(app) - - def getChat(self): - """Returns the 'chat' class for this script.""" - - return Chat(self, self._buddyListAncestries) - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for this script.""" - - super().setupInputEventHandlers() - self.inputEventHandlers.update(self.chat.inputEventHandlers) - - def getAppKeyBindings(self): - """Returns the application-specific keybindings for this script.""" - - return self.chat.keyBindings - - def getAppPreferencesGUI(self): - """Return a GtkGrid containing the application unique configuration.""" - - return self.chat.getAppPreferencesGUI() - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - return self.chat.getPreferencesFromGUI() - - def onTextInserted(self, event): - """Called whenever text is added to an object.""" - - if self.chat.presentInsertedText(event): - return - - super().onTextInserted(event) diff --git a/src/cthulhu/scripts/apps/soffice/__init__.py b/src/cthulhu/scripts/apps/soffice/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/apps/soffice/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/apps/soffice/braille_generator.py b/src/cthulhu/scripts/apps/soffice/braille_generator.py deleted file mode 100644 index c205d2b..0000000 --- a/src/cthulhu/scripts/apps/soffice/braille_generator.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for StarOffice and OpenOffice.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.braille as braille -import cthulhu.braille_generator as braille_generator -import cthulhu.object_properties as object_properties -import cthulhu.settings_manager as settings_manager -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -_settingsManager = None # Removed - use cthulhuApp.settingsManager - -class BrailleGenerator(braille_generator.BrailleGenerator): - - def __init__(self, script): - super().__init__(script) - - def _generateRoleName(self, obj, **args): - if self._script.utilities.isDocument(obj): - return [] - - if self._script.utilities.isFocusableLabel(obj): - return [] - - return super()._generateRoleName(obj, **args) - - def _generateRowHeader(self, obj, **args): - """Returns an array of strings that represent the row header for an - object that is in a table, if it exists. Otherwise, an empty - array is returned. Overridden here so that we can get the - dynamic row header(s). - """ - - newOnly = args.get('newOnly', False) - rowHeader, columnHeader = \ - self._script.utilities.getDynamicHeadersForCell(obj, newOnly) - if not rowHeader: - return [] - - text = self._script.utilities.displayedText(rowHeader) - if text: - return [text] - - return [] - - def _generateColumnHeader(self, obj, **args): - """Returns an array of strings that represent the column header for an - object that is in a table, if it exists. Otherwise, an empty - array is returned. Overridden here so that we can get the - dynamic column header(s). - """ - - newOnly = args.get('newOnly', False) - rowHeader, columnHeader = \ - self._script.utilities.getDynamicHeadersForCell(obj, newOnly) - if not columnHeader: - return [] - - text = self._script.utilities.displayedText(columnHeader) - if text: - return [text] - - return [] - - def _generateRealTableCell(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateRealTableCell(obj, **args) - - if not AXObject.get_child_count(obj): - result = super()._generateRealTableCell(obj, **args) - else: - result = [] - formatType = args.get('formatType') - args['formatType'] = 'focused' - for child in AXObject.iter_children(obj): - result.extend(self.generate(child, **args)) - args['formatType'] = formatType - - if not self._script.utilities.isSpreadSheetCell(obj): - return result - - try: - objectText = self._script.utilities.substring(obj, 0, -1) - cellName = self._script.utilities.spreadSheetCellName(obj) - except Exception: - return [] - - return [braille.Component(obj, " ".join((objectText, cellName)))] - - def _generateTableCellDelimiter(self, obj, **args): - return braille.Region(object_properties.TABLE_CELL_DELIMITER_BRAILLE) - - def _generateTableCellRow(self, obj, **args): - if not self._script.utilities.shouldReadFullRow(obj): - return self._generateRealTableCell(obj, **args) - - if not self._script.utilities.isSpreadSheetCell(obj): - return super()._generateTableCellRow(obj, **args) - - cells = self._script.utilities.getShowingCellsInSameRow(obj) - if not cells: - return [] - - result = [] - for cell in cells: - cellResult = self._generateRealTableCell(cell, **args) - if cellResult and result: - result.append(self._generateTableCellDelimiter(obj, **args)) - result.extend(cellResult) - - return result - - def _generateChildTab(self, obj, **args): - """If we are in the slide presentation scroll pane, also announce the - current page tab. See bug #538056 for more details. - """ - result = [] - rolesList = [Atspi.Role.SCROLL_PANE, \ - Atspi.Role.PANEL, \ - Atspi.Role.PANEL, \ - Atspi.Role.ROOT_PANE, \ - Atspi.Role.FRAME, \ - Atspi.Role.APPLICATION] - if self._script.utilities.hasMatchingHierarchy(obj, rolesList): - parent = AXObject.get_parent(obj) - for child in AXObject.iter_children(parent, AXUtilities.is_page_tab_list): - for tab in AXObject.iter_children(child, AXUtilities.is_selected): - args['role'] = AXObject.get_role(tab) - result.extend(self.generate(tab, **args)) - return result - - def _generateAncestors(self, obj, **args): - if self._script._lastCommandWasStructNav: - return [] - - return super()._generateAncestors(obj, **args) - - def _generateIncludeContext(self, obj, **args): - if self._script._lastCommandWasStructNav: - return False - - return super()._generateIncludeContext(obj, **args) - - def generateBraille(self, obj, **args): - args['useDefaultFormatting'] = self._script.utilities.isNonFocusableList(obj) - oldRole = self._overrideRole(self._getAlternativeRole(obj, **args), args) - - result = super().generateBraille(obj, **args) - - del args['useDefaultFormatting'] - self._restoreRole(oldRole, args) - return result diff --git a/src/cthulhu/scripts/apps/soffice/formatting.py b/src/cthulhu/scripts/apps/soffice/formatting.py deleted file mode 100644 index 74fbfaf..0000000 --- a/src/cthulhu/scripts/apps/soffice/formatting.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom formatting for OpenOffice and StarOffice.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -# If we were to adhere to the line-length requirements of 100 characters, -# this file would be even more cumbersome to look at than it already is. -# We shall respect the line-length requirements for all files that are not -# formatting.py. -# ruff: noqa: E501 - -import copy -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.formatting -import cthulhu.role_keys -import cthulhu.settings - -formatting = { - 'speech': { - Atspi.Role.TABLE_CELL: { - 'focused': 'endOfTableIndicator + pause + tableCellRow + pause', - 'unfocused': 'endOfTableIndicator + pause + tableCellRow + pause', - 'basicWhereAmI': 'parentRoleName + pause + columnHeader + pause + rowHeader + pause + roleName + pause + cellCheckedState + pause + (realActiveDescendantDisplayedText or imageDescription + image) + pause + columnAndRow + pause + expandableState + pause + nodeLevel + pause', - 'detailedWhereAmI': 'parentRoleName + pause + columnHeader + pause + rowHeader + pause + roleName + pause + cellCheckedState + pause + (realActiveDescendantDisplayedText or imageDescription + image) + pause + columnAndRow + pause + tableCellRow + pause + expandableState + pause + nodeLevel + pause' - }, - cthulhu.role_keys.REAL_ROLE_TABLE_CELL: { - 'focused': 'newRowHeader + newColumnHeader + realActiveDescendantDisplayedText', - 'unfocused': 'newRowHeader + newColumnHeader + realActiveDescendantDisplayedText', - }, - cthulhu.role_keys.ROLE_SPREADSHEET_CELL: { - # We treat spreadsheet cells differently from other table cells in - # whereAmI. - # - 'basicWhereAmI': 'roleName + pause + column + pause + columnHeader + pause + row + pause + rowHeader + pause + (textContent or realTableCell) + pause + anyTextSelection + pause' - }, - }, - 'braille': { - Atspi.Role.LIST: { - 'unfocused': '[Component(obj,\ - asString(labelOrName + roleName + required))]' - }, - Atspi.Role.SCROLL_PANE: { - 'unfocused': 'asPageTabOrScrollPane\ - + (childTab\ - and ([Region(" ")] + childTab) or [])' - } - } -} - -class Formatting(cthulhu.formatting.Formatting): - def __init__(self, script): - cthulhu.formatting.Formatting.__init__(self, script) - self.update(copy.deepcopy(formatting)) - self._defaultFormatting = cthulhu.formatting.Formatting(script) - - def getFormat(self, **args): - if args.get('useDefaultFormatting', False): - return self._defaultFormatting.getFormat(**args) - else: - return cthulhu.formatting.Formatting.getFormat(self, **args) diff --git a/src/cthulhu/scripts/apps/soffice/meson.build b/src/cthulhu/scripts/apps/soffice/meson.build deleted file mode 100644 index 78662f3..0000000 --- a/src/cthulhu/scripts/apps/soffice/meson.build +++ /dev/null @@ -1,14 +0,0 @@ -soffice_python_sources = files([ - '__init__.py', - 'braille_generator.py', - 'formatting.py', - 'script.py', - 'script_utilities.py', - 'speech_generator.py', - 'spellcheck.py', -]) - -python3.install_sources( - soffice_python_sources, - subdir: 'cthulhu/scripts/apps/soffice' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/soffice/script.py b/src/cthulhu/scripts/apps/soffice/script.py deleted file mode 100644 index b6dab74..0000000 --- a/src/cthulhu/scripts/apps/soffice/script.py +++ /dev/null @@ -1,992 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for LibreOffice.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2013 The Cthulhu Team." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import Gtk - -import cthulhu.cmdnames as cmdnames -import cthulhu.debug as debug -import cthulhu.scripts.default as default -import cthulhu.guilabels as guilabels -import cthulhu.keybindings as keybindings -import cthulhu.input_event as input_event -import cthulhu.messages as messages -import cthulhu.cthulhu as cthulhu -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.settings_manager as settings_manager -import cthulhu.structural_navigation as structural_navigation -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -from .braille_generator import BrailleGenerator -from .formatting import Formatting -from .script_utilities import Utilities -from .spellcheck import SpellCheck -from .speech_generator import SpeechGenerator - -_settingsManager = settings_manager.getManager() - -class Script(default.Script): - - def __init__(self, app): - """Creates a new script for the given application. - - Arguments: - - app: the application to create a script for. - """ - - default.Script.__init__(self, app) - - self.speakSpreadsheetCoordinatesCheckButton = None - self.alwaysSpeakSelectedSpreadsheetRangeCheckButton = None - self.skipBlankCellsCheckButton = None - self.speakCellCoordinatesCheckButton = None - self.speakCellHeadersCheckButton = None - self.speakCellSpanCheckButton = None - - # The spreadsheet input line. - # - self.inputLineForCell = None - - # Dictionaries for the calc and writer dynamic row and column headers. - # - self.dynamicColumnHeaders = {} - self.dynamicRowHeaders = {} - - def getBrailleGenerator(self): - """Returns the braille generator for this script. - """ - return BrailleGenerator(self) - - def getSpeechGenerator(self): - """Returns the speech generator for this script. - """ - return SpeechGenerator(self) - - def getSpellCheck(self): - """Returns the spellcheck for this script.""" - - return SpellCheck(self) - - def getFormatting(self): - """Returns the formatting strings for this script.""" - return Formatting(self) - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def getStructuralNavigation(self): - """Returns the 'structural navigation' class for this script. - """ - types = self.getEnabledStructuralNavigationTypes() - return structural_navigation.StructuralNavigation(self, types, enabled=False) - - def getEnabledStructuralNavigationTypes(self): - """Returns a list of the structural navigation object types - enabled in this script. - """ - - enabledTypes = [structural_navigation.StructuralNavigation.TABLE_CELL] - - return enabledTypes - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for this script that can be - called by the key and braille bindings. In this particular case, - we just want to be able to add a handler to return the contents of - the input line. - """ - - default.Script.setupInputEventHandlers(self) - self.inputEventHandlers.update( - self.structuralNavigation.inputEventHandlers) - - self.inputEventHandlers["presentInputLineHandler"] = \ - input_event.InputEventHandler( - Script.presentInputLine, - cmdnames.PRESENT_INPUT_LINE) - - self.inputEventHandlers["setDynamicColumnHeadersHandler"] = \ - input_event.InputEventHandler( - Script.setDynamicColumnHeaders, - cmdnames.DYNAMIC_COLUMN_HEADER_SET) - - self.inputEventHandlers["clearDynamicColumnHeadersHandler"] = \ - input_event.InputEventHandler( - Script.clearDynamicColumnHeaders, - cmdnames.DYNAMIC_COLUMN_HEADER_CLEAR) - - self.inputEventHandlers["setDynamicRowHeadersHandler"] = \ - input_event.InputEventHandler( - Script.setDynamicRowHeaders, - cmdnames.DYNAMIC_ROW_HEADER_SET) - - self.inputEventHandlers["clearDynamicRowHeadersHandler"] = \ - input_event.InputEventHandler( - Script.clearDynamicRowHeaders, - cmdnames.DYNAMIC_ROW_HEADER_CLEAR) - - self.inputEventHandlers["panBrailleLeftHandler"] = \ - input_event.InputEventHandler( - Script.panBrailleLeft, - cmdnames.PAN_BRAILLE_LEFT, - False) # Do not enable learn mode for this action - - self.inputEventHandlers["panBrailleRightHandler"] = \ - input_event.InputEventHandler( - Script.panBrailleRight, - cmdnames.PAN_BRAILLE_RIGHT, - False) # Do not enable learn mode for this action - - def getAppKeyBindings(self): - """Returns the application-specific keybindings for this script.""" - - keyBindings = keybindings.KeyBindings() - - keyBindings.add( - keybindings.KeyBinding( - "a", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers["presentInputLineHandler"])) - - keyBindings.add( - keybindings.KeyBinding( - "r", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers["setDynamicColumnHeadersHandler"], - 1)) - - keyBindings.add( - keybindings.KeyBinding( - "r", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers["clearDynamicColumnHeadersHandler"], - 2)) - - keyBindings.add( - keybindings.KeyBinding( - "c", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers["setDynamicRowHeadersHandler"], - 1)) - - keyBindings.add( - keybindings.KeyBinding( - "c", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers["clearDynamicRowHeadersHandler"], - 2)) - - bindings = self.structuralNavigation.keyBindings - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - return keyBindings - - def getAppPreferencesGUI(self): - """Return a GtkGrid containing the application unique configuration - GUI items for the current application.""" - - grid = Gtk.Grid() - grid.set_border_width(12) - - label = guilabels.SPREADSHEET_SPEAK_CELL_COORDINATES - value = _settingsManager.getSetting('speakSpreadsheetCoordinates') - self.speakSpreadsheetCoordinatesCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self.speakSpreadsheetCoordinatesCheckButton.set_active(value) - grid.attach(self.speakSpreadsheetCoordinatesCheckButton, 0, 0, 1, 1) - - label = guilabels.SPREADSHEET_SPEAK_SELECTED_RANGE - value = _settingsManager.getSetting('alwaysSpeakSelectedSpreadsheetRange') - self.alwaysSpeakSelectedSpreadsheetRangeCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self.alwaysSpeakSelectedSpreadsheetRangeCheckButton.set_active(value) - grid.attach(self.alwaysSpeakSelectedSpreadsheetRangeCheckButton, 0, 1, 1, 1) - - tableFrame = Gtk.Frame() - grid.attach(tableFrame, 0, 2, 1, 1) - - label = Gtk.Label(label=f"{guilabels.TABLE_NAVIGATION}") - label.set_use_markup(True) - tableFrame.set_label_widget(label) - - tableAlignment = Gtk.Alignment.new(0.5, 0.5, 1, 1) - tableAlignment.set_padding(0, 0, 12, 0) - tableFrame.add(tableAlignment) - tableGrid = Gtk.Grid() - tableAlignment.add(tableGrid) - - label = guilabels.TABLE_SPEAK_CELL_COORDINATES - value = _settingsManager.getSetting('speakCellCoordinates') - self.speakCellCoordinatesCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self.speakCellCoordinatesCheckButton.set_active(value) - tableGrid.attach(self.speakCellCoordinatesCheckButton, 0, 0, 1, 1) - - label = guilabels.TABLE_SPEAK_CELL_SPANS - value = _settingsManager.getSetting('speakCellSpan') - self.speakCellSpanCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self.speakCellSpanCheckButton.set_active(value) - tableGrid.attach(self.speakCellSpanCheckButton, 0, 1, 1, 1) - - label = guilabels.TABLE_ANNOUNCE_CELL_HEADER - value = _settingsManager.getSetting('speakCellHeaders') - self.speakCellHeadersCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self.speakCellHeadersCheckButton.set_active(value) - tableGrid.attach(self.speakCellHeadersCheckButton, 0, 2, 1, 1) - - label = guilabels.TABLE_SKIP_BLANK_CELLS - value = _settingsManager.getSetting('skipBlankCells') - self.skipBlankCellsCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self.skipBlankCellsCheckButton.set_active(value) - tableGrid.attach(self.skipBlankCellsCheckButton, 0, 3, 1, 1) - - spellcheck = self.spellcheck.getAppPreferencesGUI() - grid.attach(spellcheck, 0, len(grid.get_children()), 1, 1) - grid.show_all() - - return grid - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - prefs = { - 'speakCellSpan': - self.speakCellSpanCheckButton.get_active(), - 'speakCellHeaders': - self.speakCellHeadersCheckButton.get_active(), - 'skipBlankCells': - self.skipBlankCellsCheckButton.get_active(), - 'speakCellCoordinates': - self.speakCellCoordinatesCheckButton.get_active(), - 'speakSpreadsheetCoordinates': - self.speakSpreadsheetCoordinatesCheckButton.get_active(), - 'alwaysSpeakSelectedSpreadsheetRange': - self.alwaysSpeakSelectedSpreadsheetRangeCheckButton.get_active(), - } - - prefs.update(self.spellcheck.getPreferencesFromGUI()) - return prefs - - def panBrailleLeft(self, inputEvent=None, panAmount=0): - """In document content, we want to use the panning keys to browse the - entire document. - """ - - if self.flatReviewPresenter.is_active() \ - or not self.isBrailleBeginningShowing() \ - or self.utilities.isSpreadSheetCell(cthulhu_state.locusOfFocus) \ - or not self.utilities.isTextArea(cthulhu_state.locusOfFocus): - return default.Script.panBrailleLeft(self, inputEvent, panAmount) - - if not AXObject.supports_text(cthulhu_state.locusOfFocus): - return default.Script.panBrailleLeft(self, inputEvent, panAmount) - - caretOffset = AXText.get_caret_offset(cthulhu_state.locusOfFocus) - string, startOffset, endOffset = AXText.get_line_at_offset( - cthulhu_state.locusOfFocus, caretOffset) - if 0 < startOffset: - AXText.set_caret_offset(cthulhu_state.locusOfFocus, startOffset - 1) - return True - - obj = self.utilities.findPreviousObject(cthulhu_state.locusOfFocus) - if AXObject.supports_text(obj): - cthulhu.setLocusOfFocus(None, obj, notifyScript=False) - AXText.set_caret_offset(obj, AXText.get_character_count(obj)) - return True - - return default.Script.panBrailleLeft(self, inputEvent, panAmount) - - def panBrailleRight(self, inputEvent=None, panAmount=0): - """In document content, we want to use the panning keys to browse the - entire document. - """ - - if self.flatReviewPresenter.is_active() \ - or not self.isBrailleEndShowing() \ - or self.utilities.isSpreadSheetCell(cthulhu_state.locusOfFocus) \ - or not self.utilities.isTextArea(cthulhu_state.locusOfFocus): - return default.Script.panBrailleRight(self, inputEvent, panAmount) - - if not AXObject.supports_text(cthulhu_state.locusOfFocus): - return default.Script.panBrailleRight(self, inputEvent, panAmount) - - caretOffset = AXText.get_caret_offset(cthulhu_state.locusOfFocus) - string, startOffset, endOffset = AXText.get_line_at_offset( - cthulhu_state.locusOfFocus, caretOffset) - if endOffset < AXText.get_character_count(cthulhu_state.locusOfFocus): - AXText.set_caret_offset(cthulhu_state.locusOfFocus, endOffset) - return True - - obj = self.utilities.findNextObject(cthulhu_state.locusOfFocus) - if AXObject.supports_text(obj): - cthulhu.setLocusOfFocus(None, obj, notifyScript=False) - AXText.set_caret_offset(obj, 0) - return True - - return default.Script.panBrailleRight(self, inputEvent, panAmount) - - def presentInputLine(self, inputEvent): - """Presents the contents of the spread sheet input line (assuming we - have a handle to it - generated when we first focus on a spread - sheet table cell. - - This will be either the contents of the table cell that has focus - or the formula associated with it. - - Arguments: - - inputEvent: if not None, the input event that caused this action. - """ - - if not self.utilities.isSpreadSheetCell(cthulhu_state.locusOfFocus): - return - - inputLine = self.utilities.locateInputLine(cthulhu_state.locusOfFocus) - if not inputLine: - return - - text = self.utilities.displayedText(inputLine) - if not text: - text = messages.EMPTY - - self.presentMessage(text) - - def setDynamicColumnHeaders(self, inputEvent): - """Set the row for the dynamic header columns to use when speaking - calc cell entries. In order to set the row, the user should first set - focus to the row that they wish to define and then press Insert-r. - - Once the user has defined the row, it will be used to first speak - this header when moving between columns. - - Arguments: - - inputEvent: if not None, the input event that caused this action. - """ - - cell = cthulhu_state.locusOfFocus - parent = AXObject.get_parent(cell) - if AXObject.get_role(parent) == Atspi.Role.TABLE_CELL: - cell = parent - - row, column, table = self.utilities.getRowColumnAndTable(cell) - if table: - self.dynamicColumnHeaders[hash(table)] = row - self.presentMessage(messages.DYNAMIC_COLUMN_HEADER_SET % (row+1)) - - return True - - def clearDynamicColumnHeaders(self, inputEvent): - """Clear the dynamic header column. - - Arguments: - - inputEvent: if not None, the input event that caused this action. - """ - - cell = cthulhu_state.locusOfFocus - parent = AXObject.get_parent(cell) - if AXObject.get_role(parent) == Atspi.Role.TABLE_CELL: - cell = parent - - row, column, table = self.utilities.getRowColumnAndTable(cell) - try: - del self.dynamicColumnHeaders[hash(table)] - self.presentationInterrupt() - self.presentMessage(messages.DYNAMIC_COLUMN_HEADER_CLEARED) - except Exception: - pass - - return True - - def setDynamicRowHeaders(self, inputEvent): - """Set the column for the dynamic header rows to use when speaking - calc cell entries. In order to set the column, the user should first - set focus to the column that they wish to define and then press - Insert-c. - - Once the user has defined the column, it will be used to first speak - this header when moving between rows. - - Arguments: - - inputEvent: if not None, the input event that caused this action. - """ - - cell = cthulhu_state.locusOfFocus - parent = AXObject.get_parent(cell) - if AXObject.get_role(parent) == Atspi.Role.TABLE_CELL: - cell = parent - - row, column, table = self.utilities.getRowColumnAndTable(cell) - if table: - self.dynamicRowHeaders[hash(table)] = column - self.presentMessage( - messages.DYNAMIC_ROW_HEADER_SET % self.utilities.columnConvert(column+1)) - - return True - - def clearDynamicRowHeaders(self, inputEvent): - """Clear the dynamic row headers. - - Arguments: - - inputEvent: if not None, the input event that caused this action. - """ - - cell = cthulhu_state.locusOfFocus - parent = AXObject.get_parent(cell) - if AXObject.get_role(parent) == Atspi.Role.TABLE_CELL: - cell = parent - - row, column, table = self.utilities.getRowColumnAndTable(cell) - try: - del self.dynamicRowHeaders[hash(table)] - self.presentationInterrupt() - self.presentMessage(messages.DYNAMIC_ROW_HEADER_CLEARED) - except Exception: - pass - - return True - - def locus_of_focus_changed(self, event, oldLocusOfFocus, newLocusOfFocus): - """Called when the visual object with focus changes. - - Arguments: - - event: if not None, the Event that caused the change - - oldLocusOfFocus: Accessible that is the old locus of focus - - newLocusOfFocus: Accessible that is the new locus of focus - """ - - # Check to see if this is this is for the find command. See - # comment #18 of bug #354463. - # - if self.findCommandRun and \ - event.type.startswith("object:state-changed:focused"): - self.findCommandRun = False - self.find() - return - - if self.flatReviewPresenter.is_active(): - self.flatReviewPresenter.quit() - - if self.spellcheck.isSuggestionsItem(newLocusOfFocus) \ - and not self.spellcheck.isSuggestionsItem(oldLocusOfFocus): - cthulhu.emitRegionChanged(newLocusOfFocus) - self.updateBraille(newLocusOfFocus) - self.spellcheck.presentSuggestionListItem(includeLabel=True) - return - - # TODO - JD: Sad hack that wouldn't be needed if LO were fixed. - # If we are in the slide presentation scroll pane, also announce - # the current page tab. See bug #538056 for more details. - # - rolesList = [Atspi.Role.SCROLL_PANE, - Atspi.Role.PANEL, - Atspi.Role.PANEL, - Atspi.Role.ROOT_PANE, - Atspi.Role.FRAME, - Atspi.Role.APPLICATION] - if self.utilities.hasMatchingHierarchy(newLocusOfFocus, rolesList): - parent = AXObject.get_parent(newLocusOfFocus) - for child in AXObject.iter_children(parent, AXUtilities.is_page_tab_list): - for tab in AXObject.iter_children(child, AXUtilities.is_selected): - self.presentObject(tab) - - # TODO - JD: This is a hack that needs to be done better. For now it - # fixes the broken echo previous word on Return. - elif newLocusOfFocus and oldLocusOfFocus \ - and AXObject.get_role(newLocusOfFocus) == Atspi.Role.PARAGRAPH \ - and AXObject.get_role(oldLocusOfFocus) == Atspi.Role.PARAGRAPH \ - and newLocusOfFocus != oldLocusOfFocus: - lastKey, mods = self.utilities.lastKeyAndModifiers() - if lastKey == "Return" and _settingsManager.getSetting('enableEchoByWord'): - self.echoPreviousWord(oldLocusOfFocus) - return - - # TODO - JD: And this hack is another one that needs to be done better. - # But this will get us to speak the entire paragraph when navigation by - # paragraph has occurred. - event_string, mods = self.utilities.lastKeyAndModifiers() - isControlKey = mods & keybindings.CTRL_MODIFIER_MASK - isShiftKey = mods & keybindings.SHIFT_MODIFIER_MASK - if event_string in ["Up", "Down"] and isControlKey and not isShiftKey: - string = self.utilities.displayedText(newLocusOfFocus) - if string: - voice = self.speechGenerator.voice(obj=newLocusOfFocus, string=string) - self.speakMessage(string, voice=voice) - self.updateBraille(newLocusOfFocus) - if AXObject.supports_text(newLocusOfFocus): - self._saveLastCursorPosition( - newLocusOfFocus, AXText.get_caret_offset(newLocusOfFocus)) - return - - # Pass the event onto the parent class to be handled in the default way. - default.Script.locus_of_focus_changed(self, event, - oldLocusOfFocus, newLocusOfFocus) - if not newLocusOfFocus: - return - - parent = AXObject.get_parent(newLocusOfFocus) - if parent is None: - return - - cell = None - if self.utilities.isTextDocumentCell(newLocusOfFocus): - cell = newLocusOfFocus - elif self.utilities.isTextDocumentCell(parent): - cell = parent - if cell: - row, column = self.utilities.coordinatesForCell(cell) - self.pointOfReference['lastRow'] = row - self.pointOfReference['lastColumn'] = column - - def onNameChanged(self, event): - """Called whenever a property on an object changes. - - Arguments: - - event: the Event - """ - - if self.spellcheck.isCheckWindow(event.source): - return - - # Impress slide navigation. - # - if self.utilities.isInImpress(event.source) \ - and self.utilities.isDrawingView(event.source): - title, position, count = \ - self.utilities.slideTitleAndPosition(event.source) - if title: - title += "." - - msg = messages.PRESENTATION_SLIDE_POSITION % \ - {"position" : position, "count" : count} - msg = self.utilities.appendString(title, msg) - self.presentMessage(msg) - - default.Script.onNameChanged(self, event) - - def onActiveChanged(self, event): - """Callback for object:state-changed:active accessibility events.""" - - if not AXObject.get_parent(event.source): - msg = "SOFFICE: Event source lacks parent" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - # Prevent this events from activating the find operation. - # See comment #18 of bug #354463. - if self.findCommandRun: - return - - default.Script.onActiveChanged(self, event) - - def onActiveDescendantChanged(self, event): - """Called when an object who manages its own descendants detects a - change in one of its children. - - Arguments: - - event: the Event - """ - - if self.utilities.isSameObject(event.any_data, cthulhu_state.locusOfFocus): - return - - if event.source == self.spellcheck.getSuggestionsList(): - if AXUtilities.is_focused(event.source): - cthulhu.setLocusOfFocus(event, event.any_data, False) - self.updateBraille(cthulhu_state.locusOfFocus) - self.spellcheck.presentSuggestionListItem() - else: - self.spellcheck.presentErrorDetails() - return - - if self.utilities.isSpreadSheetCell(event.any_data) \ - and not AXUtilities.is_focused(event.any_data) \ - and not AXUtilities.is_focused(event.source) : - msg = "SOFFICE: Neither source nor child have focused state. Clearing cache on table." - debug.printMessage(debug.LEVEL_INFO, msg, True) - AXObject.clear_cache(event.source) - - default.Script.onActiveDescendantChanged(self, event) - - def onChildrenAdded(self, event): - """Callback for object:children-changed:add accessibility events.""" - - AXObject.clear_cache_now("children-changed event.") - - if self.utilities.isSpreadSheetCell(event.any_data): - cthulhu.setLocusOfFocus(event, event.any_data) - return - - if self.utilities.isLastCell(event.any_data): - activeRow = self.pointOfReference.get('lastRow', -1) - activeCol = self.pointOfReference.get('lastColumn', -1) - if activeRow < 0 or activeCol < 0: - return - - if AXObject.is_dead(cthulhu_state.locusOfFocus): - cthulhu.setLocusOfFocus(event, event.source, False) - - self.utilities.handleUndoTextEvent(event) - rowCount, colCount = self.utilities.rowAndColumnCount(event.source) - if activeRow == rowCount: - full = messages.TABLE_ROW_DELETED_FROM_END - brief = messages.TABLE_ROW_DELETED - else: - full = messages.TABLE_ROW_INSERTED_AT_END - brief = messages.TABLE_ROW_INSERTED - self.presentMessage(full, brief) - return - - default.Script.onChildrenAdded(self, event) - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - # NOTE: This event type is deprecated and Cthulhu should no longer use it. - # This callback remains just to handle bugs in applications and toolkits - # during the remainder of the unstable (3.11) development cycle. - - if self.utilities.isSameObject(cthulhu_state.locusOfFocus, event.source): - return - - if self.utilities.isFocusableLabel(event.source): - cthulhu.setLocusOfFocus(event, event.source) - return - - role = AXObject.get_role(event.source) - - if self.utilities.isZombie(event.source) \ - or role in [Atspi.Role.TEXT, Atspi.Role.LIST]: - comboBox = self.utilities.containingComboBox(event.source) - if comboBox: - cthulhu.setLocusOfFocus(event, comboBox, True) - return - - # This seems to be something we inherit from Gtk+ - if role in [Atspi.Role.TEXT, Atspi.Role.PASSWORD_TEXT]: - cthulhu.setLocusOfFocus(event, event.source) - return - - # Ditto. - if role == Atspi.Role.PUSH_BUTTON: - cthulhu.setLocusOfFocus(event, event.source) - return - - # Ditto. - if role == Atspi.Role.TOGGLE_BUTTON: - cthulhu.setLocusOfFocus(event, event.source) - return - - # Ditto. - if role == Atspi.Role.COMBO_BOX: - cthulhu.setLocusOfFocus(event, event.source) - return - - # Ditto. - if role == Atspi.Role.PANEL and AXObject.get_name(event.source): - cthulhu.setLocusOfFocus(event, event.source) - return - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if self._inSayAll: - return - - if self._lastCommandWasStructNav: - return - - if not event.detail1: - return - - if self.utilities.isAnInputLine(event.source): - msg = "SOFFICE: Event ignored: spam from inputLine" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if AXObject.get_child_count(event.source) \ - and self.utilities.isAnInputLine(AXObject.get_child(event.source, 0)): - msg = "SOFFICE: Event ignored: spam from inputLine parent" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - role = AXObject.get_role(event.source) - if role in [Atspi.Role.TEXT, Atspi.Role.LIST]: - comboBox = self.utilities.containingComboBox(event.source) - if comboBox: - cthulhu.setLocusOfFocus(event, comboBox, True) - return - - parent = AXObject.get_parent(event.source) - if parent and AXObject.get_role(parent) == Atspi.Role.TOOL_BAR: - default.Script.onFocusedChanged(self, event) - return - - # TODO - JD: Verify this is still needed - ignoreRoles = [Atspi.Role.FILLER, Atspi.Role.PANEL] - if role in ignoreRoles: - return - - # We will present this when the selection changes. - if role == Atspi.Role.MENU: - return - - if self.utilities._flowsFromOrToSelection(event.source): - return - - if role == Atspi.Role.PARAGRAPH: - obj, offset = self.pointOfReference.get("lastCursorPosition", (None, -1)) - start, end, string = self.utilities.getCachedTextSelection(obj) - if start != end: - return - - keyString, mods = self.utilities.lastKeyAndModifiers() - if keyString in ["Left", "Right"]: - cthulhu.setLocusOfFocus(event, event.source, False) - return - - if self.utilities.isSpreadSheetTable(event.source) and cthulhu_state.locusOfFocus: - if AXObject.is_dead(cthulhu_state.locusOfFocus): - msg = "SOFFICE: Event believed to be post-editing focus claim. Dead locusOfFocus." - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source, False) - return - if AXUtilities.is_paragraph(cthulhu_state.locusOfFocus) \ - or AXUtilities.is_table_cell(cthulhu_state.locusOfFocus): - msg = "SOFFICE: Event believed to be post-editing focus claim based on role." - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source, False) - return - - default.Script.onFocusedChanged(self, event) - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - if event.detail1 == -1: - return - - if AXObject.get_role(event.source) == Atspi.Role.PARAGRAPH \ - and not AXUtilities.is_focused(event.source): - AXObject.clear_cache(event.source) - if AXUtilities.is_focused(event.source): - msg = "SOFFICE: Clearing cache was needed due to missing state-changed event." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if self.utilities._flowsFromOrToSelection(event.source): - return - - if self._lastCommandWasStructNav: - return - - if self.utilities.isSpreadSheetCell(cthulhu_state.locusOfFocus): - tokens = ["SOFFICE: locusOfFocus", cthulhu_state.locusOfFocus, "is spreadsheet cell"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not self.utilities.isCellBeingEdited(event.source): - msg = "SOFFICE: Event ignored: Source is not cell being edited." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - super().onCaretMoved(event) - - def onCheckedChanged(self, event): - """Callback for object:state-changed:checked accessibility events.""" - - obj = event.source - role = AXObject.get_role(obj) - parentRole = AXObject.get_role(AXObject.get_parent(obj)) - if role not in [Atspi.Role.TOGGLE_BUTTON, Atspi.Role.PUSH_BUTTON] \ - or not parentRole == Atspi.Role.TOOL_BAR: - default.Script.onCheckedChanged(self, event) - return - - sourceWindow = self.utilities.topLevelObject(obj) - focusWindow = self.utilities.topLevelObject(cthulhu_state.locusOfFocus) - if sourceWindow != focusWindow: - return - - # Announce when the toolbar buttons are toggled if we just toggled - # them; not if we navigated to some text. - weToggledIt = False - if isinstance(cthulhu_state.lastInputEvent, input_event.MouseButtonEvent): - x = cthulhu_state.lastInputEvent.x - y = cthulhu_state.lastInputEvent.y - if AXObject.supports_component(obj): - weToggledIt = Atspi.Component.contains(obj, x, y, Atspi.CoordType.SCREEN) - else: - weToggledIt = False - elif AXUtilities.is_focused(obj): - weToggledIt = True - else: - keyString, mods = self.utilities.lastKeyAndModifiers() - navKeys = ["Up", "Down", "Left", "Right", "Page_Up", "Page_Down", - "Home", "End", "N"] - wasCommand = mods & keybindings.COMMAND_MODIFIER_MASK - weToggledIt = wasCommand and keyString not in navKeys - if weToggledIt: - self.presentObject(obj, alreadyFocused=True, interrupt=True) - - def onSelectedChanged(self, event): - """Callback for object:state-changed:selected accessibility events.""" - - full, brief = "", "" - if self.utilities.isSelectedTextDeletionEvent(event): - msg = "SOFFICE: Change is believed to be due to deleting selected text" - debug.printMessage(debug.LEVEL_INFO, msg, True) - full = messages.SELECTION_DELETED - elif self.utilities.isSelectedTextRestoredEvent(event): - msg = "SOFFICE: Selection is believed to be due to restoring selected text" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if self.utilities.handleUndoTextEvent(event): - full = messages.SELECTION_RESTORED - - if full or brief: - self.presentMessage(full, brief) - self.utilities.updateCachedTextSelection(event.source) - return - - super().onSelectedChanged(event) - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - if self.utilities.isSpreadSheetTable(event.source): - if _settingsManager.getSetting('onlySpeakDisplayedText'): - return - if _settingsManager.getSetting('alwaysSpeakSelectedSpreadsheetRange'): - self.utilities.speakSelectedCellRange(event.source) - return - if self.utilities.handleRowAndColumnSelectionChange(event.source): - return - self.utilities.handleCellSelectionChange(event.source) - return - - if event.source == self.spellcheck.getSuggestionsList(): - if cthulhu_state.locusOfFocus == cthulhu_state.activeWindow: - msg = "SOFFICE: Not presenting because locusOfFocus is window" - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif AXUtilities.is_focused(event.source): - cthulhu.setLocusOfFocus(event, event.any_data, False) - self.updateBraille(cthulhu_state.locusOfFocus) - self.spellcheck.presentSuggestionListItem() - else: - self.spellcheck.presentErrorDetails() - return - - if not self.utilities.isComboBoxSelectionChange(event): - super().onSelectionChanged(event) - return - - selectedChildren = self.utilities.selectedChildren(event.source) - if len(selectedChildren) == 1 \ - and self.utilities.containingComboBox(event.source) == \ - self.utilities.containingComboBox(cthulhu_state.locusOfFocus): - cthulhu.setLocusOfFocus(event, selectedChildren[0], True) - - def onTextSelectionChanged(self, event): - """Callback for object:text-selection-changed accessibility events.""" - - if self.utilities.isComboBoxNoise(event): - msg = "SOFFICE: Event is believed to be combo box noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if AXObject.is_dead(event.source): - msg = "SOFFICE: Ignoring event from dead source." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if event.source != cthulhu_state.locusOfFocus \ - and AXUtilities.is_focused(event.source): - cthulhu.setLocusOfFocus(event, event.source, False) - - super().onTextSelectionChanged(event) - - def getTextLineAtCaret(self, obj, offset=None, startOffset=None, endOffset=None): - """To-be-removed. Returns the string, caretOffset, startOffset.""" - - if AXObject.get_role(AXObject.get_parent(obj)) == Atspi.Role.COMBO_BOX: - if not AXObject.supports_text(obj): - return ["", 0, 0] - - if AXText.get_caret_offset(obj) < 0: - lineString, startOffset, endOffset = AXText.get_line_at_offset(obj, 0) - - # Sometimes we get the trailing line-feed -- remove it - # - if lineString[-1:] == "\n": - lineString = lineString[:-1] - - return [lineString, 0, startOffset] - - textLine = super().getTextLineAtCaret(obj, offset, startOffset, endOffset) - if not AXUtilities.is_focused(obj): - textLine[0] = self.utilities.displayedText(obj) - - return textLine - - def onWindowActivated(self, event): - """Callback for window:activate accessibility events.""" - - super().onWindowActivated(event) - if not self.spellcheck.isCheckWindow(event.source): - return - - child = AXObject.get_child(event.source, 0) - if AXObject.get_role(child) == Atspi.Role.DIALOG: - cthulhu.setLocusOfFocus(event, child, False) - - self.spellcheck.presentErrorDetails() - - def onWindowDeactivated(self, event): - """Callback for window:deactivate accessibility events.""" - - self._lastCommandWasStructNav = False - - super().onWindowDeactivated(event) - self.spellcheck.deactivate() diff --git a/src/cthulhu/scripts/apps/soffice/script_utilities.py b/src/cthulhu/scripts/apps/soffice/script_utilities.py deleted file mode 100644 index 34cc320..0000000 --- a/src/cthulhu/scripts/apps/soffice/script_utilities.py +++ /dev/null @@ -1,802 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Commonly-required utility methods needed by -- and potentially - customized by -- application and toolkit scripts. They have - been pulled out from the scripts because certain scripts had - gotten way too large as a result of including these methods.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.debug as debug -import cthulhu.keybindings as keybindings -import cthulhu.messages as messages -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.script_utilities as script_utilities -from cthulhu.ax_object import AXObject -from cthulhu.ax_table import AXTable -from cthulhu.ax_selection import AXSelection -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_relation import AXUtilitiesRelation - - -############################################################################# -# # -# Utilities # -# # -############################################################################# - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - """Creates an instance of the Utilities class. - - Arguments: - - script: the script with which this instance is associated. - """ - - script_utilities.Utilities.__init__(self, script) - - self._calcSelectedCells = [] - self._calcSelectedRows = [] - self._calcSelectedColumns = [] - - ######################################################################### - # # - # Utilities for finding, identifying, and comparing accessibles # - # # - ######################################################################### - - def displayedText(self, obj): - """Returns the text being displayed for an object. Overridden here - because OpenOffice uses symbols (e.g. ">>" for buttons but exposes - more useful information via the accessible's name. - - Arguments: - - obj: the object - - Returns the text being displayed for an object or None if there isn't - any text being shown. - """ - - name = AXObject.get_name(obj) - if name and AXUtilities.is_push_button(obj): - return name - - if AXUtilities.is_table_cell(obj): - strings = list(map(self.displayedText, [x for x in AXObject.iter_children(obj)])) - text = "\n".join(strings) - if text.strip(): - return text - - try: - text = super().displayedText(obj) - except Exception: - return "" - - # TODO - JD: This is needed because the default behavior is to fall - # back on the name, which is bogus. Once that has been fixed, this - # hack can go. - if AXUtilities.is_table_cell(obj) and text == name \ - and (self.isSpreadSheetCell(obj) or self.isTextDocumentCell(obj)): - return "" - - # More bogusness from (at least) Calc combined with the aforementioned - # fallback-to-name behavior.... - if self.isDocument(obj) and text == name and text.startswith("file:///"): - return "" - - return text - - def isCellBeingEdited(self, obj): - parent = AXObject.get_parent(obj) - if AXUtilities.is_panel(parent) or AXUtilities.is_extended(parent): - return self.spreadSheetCellName(parent) - - return False - - def spreadSheetCellName(self, cell): - nameList = AXObject.get_name(cell).split() - for name in nameList: - name = name.replace('.', '') - if not name.isalpha() and name.isalnum(): - return name - - return '' - - def getRowColumnAndTable(self, cell): - """Returns the (row, column, table) tuple for cell.""" - - if not AXUtilities.is_table_cell(cell): - return -1, -1, None - - cellParent = AXObject.get_parent(cell) - if AXUtilities.is_table_cell(cellParent): - cell = cellParent - cellParent = AXObject.get_parent(cell) - - table = cellParent - if table is not None and not AXUtilities.is_table(table): - table = AXObject.get_parent(table) - - table = AXTable.get_table(table) - if table is None: - return -1, -1, None - - row, column = AXTable.get_cell_coordinates(cell, prefer_attribute=False) - return row, column, table - - def rowHeadersForCell(self, obj): - rowHeader, colHeader = self.getDynamicHeadersForCell(obj) - if rowHeader: - return [rowHeader] - - return super().rowHeadersForCell(obj) - - def columnHeadersForCell(self, obj): - rowHeader, colHeader = self.getDynamicHeadersForCell(obj) - if colHeader: - return [colHeader] - - return super().columnHeadersForCell(obj) - - def getDynamicHeadersForCell(self, obj, onlyIfNew=False): - if not (self._script.dynamicRowHeaders or self._script.dynamicColumnHeaders): - return None, None - - objRow, objCol, table = self.getRowColumnAndTable(obj) - if not table: - return None, None - - headersRow = self._script.dynamicColumnHeaders.get(hash(table)) - headersCol = self._script.dynamicRowHeaders.get(hash(table)) - if headersRow == objRow or headersCol == objCol: - return None, None - - getRowHeader = headersCol is not None - getColHeader = headersRow is not None - if onlyIfNew: - getRowHeader = \ - getRowHeader and objRow != self._script.pointOfReference.get("lastRow") - getColHeader = \ - getColHeader and objCol!= self._script.pointOfReference.get("lastColumn") - - rowHeader, colHeader = None, None - if getColHeader: - colHeader = AXTable.get_cell_at(table, headersRow, objCol) - - if getRowHeader: - rowHeader = AXTable.get_cell_at(table, objRow, headersCol) - - return rowHeader, colHeader - - def isSameObject(self, obj1, obj2, comparePaths=False, ignoreNames=False, - ignoreDescriptions=True): - if obj1 == obj2: - return True - - if not AXUtilities.have_same_role(obj1, obj2): - return False - - if AXUtilities.is_paragraph(obj1): - return False - - name = AXObject.get_name(obj1) - if name == AXObject.get_name(obj2): - if AXUtilities.is_frame(obj1): - return True - if AXUtilities.is_table_cell(obj1) and not name: - if self.isZombie(obj1) and self.isZombie(obj2): - return False - - return super().isSameObject(obj1, obj2, comparePaths, ignoreNames) - - def isLayoutOnly(self, obj): - """Returns True if the given object is a container which has - no presentable information (label, name, displayed text, etc.).""" - - if AXUtilities.is_list(obj): - if AXUtilities.is_combo_box(AXObject.get_parent(obj)): - return True - return super().isLayoutOnly(obj) - - name = AXObject.get_name(obj) - if not name: - return super().isLayoutOnly(obj) - - if AXUtilities.is_frame(obj): - return name == AXObject.get_name(cthulhu_state.activeWindow) - - if AXUtilities.is_panel(obj) and AXObject.get_child_count(obj): - if AXObject.get_name(AXObject.get_child(obj, 0)) == name: - return True - - return super().isLayoutOnly(obj) - - def isAnInputLine(self, obj): - if not obj: - return False - if obj == self.locateInputLine(obj): - return True - - parent = AXObject.get_parent(obj) - if AXUtilities.is_panel(parent) or AXUtilities.is_extended(parent): - if self.spreadSheetCellName(parent): - return False - - parent = AXObject.get_parent(parent) - if AXUtilities.is_text(parent): - return True - - return False - - def locateInputLine(self, obj): - """Return the spread sheet input line. This only needs to be found - the very first time a spread sheet table cell gets focus. We use the - table cell to work back up the component hierarchy until we have found - the common panel that both it and the input line reside in. We then - use that as the base component to search for a component which has a - paragraph role. This will be the input line. - - Arguments: - - obj: the spread sheet table cell that has just got focus. - - Returns the spread sheet input line component. - """ - - if self._script.inputLineForCell is not None: - topLevel = self.topLevelObject(self._script.inputLineForCell) - if self.isSameObject(cthulhu_state.activeWindow, topLevel): - return self._script.inputLineForCell - - scrollPane = AXObject.find_ancestor(obj, AXUtilities.is_scroll_pane) - if scrollPane is None: - return None - - toolbar = None - for child in AXObject.iter_children(AXObject.get_parent(scrollPane), - AXUtilities.is_tool_bar): - toolbar = child - break - - if toolbar is None: - msg = "ERROR: Calc inputline toolbar not found." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return None - - allParagraphs = self.findAllDescendants(toolbar, AXUtilities.is_paragraph) - if len(allParagraphs) == 1: - self._script.inputLineForCell = allParagraphs[0] - - return self._script.inputLineForCell - - def frameAndDialog(self, obj): - """Returns the frame and (possibly) the dialog containing - the object. Overridden here for presentation of the title - bar information: If the locusOfFocus is a spreadsheet cell, - 1) we are not in a dialog and 2) we need to present both the - frame name and the sheet name. So we might as well return the - sheet in place of the dialog so that the default code can do - its thing. - """ - - if not self.isSpreadSheetCell(obj): - return script_utilities.Utilities.frameAndDialog(self, obj) - - results = [None, None] - - parent = AXObject.get_parent_checked(obj) - while parent: - if AXObject.get_role(parent) == Atspi.Role.FRAME: - results[0] = parent - if AXObject.get_role(parent) == Atspi.Role.TABLE: - results[1] = parent - parent = AXObject.get_parent_checked(parent) - - return results - - @staticmethod - def _flowsFromOrToSelection(obj): - relationSet = AXUtilitiesRelation.get_relations(obj) - flows = [Atspi.RelationType.FLOWS_FROM, Atspi.RelationType.FLOWS_TO] - relations = filter(lambda r: r.getRelationType() in flows, relationSet) - targets = [r.getTarget(0) for r in relations] - for target in targets: - # Intentional object-local probe: we only care whether this related object - # itself currently exposes selected text. - if AXText.get_selected_ranges(target): - return True - - return False - - def objectContentsAreInClipboard(self, obj=None): - obj = obj or cthulhu_state.locusOfFocus - if not obj: - return False - - if self.isSpreadSheetCell(obj): - contents = self.getClipboardContents() - string = self.displayedText(obj) or "\n" - return string in contents - - return super().objectContentsAreInClipboard(obj) - - ######################################################################### - # # - # Impress-Specific Utilities # - # # - ######################################################################### - - def drawingView(self, obj=cthulhu_state.locusOfFocus): - """Attempts to locate the Impress drawing view, which is the - area in which slide editing occurs.""" - - return AXObject.find_descendant(self.topLevelObject(obj), self.isDrawingView) - - def isDrawingView(self, obj): - """Returns True if obj is the Impress Drawing View.""" - - if self.isDocument(obj): - name = AXObject.get_name(obj) - return ":" in name and "/" in name - - return False - - def isInImpress(self, obj=cthulhu_state.locusOfFocus): - """Returns True if obj is in OOo Impress.""" - - # Having checked English, Spanish, and Arabic, it would seem - # that the Frame name will end with "Impress", unlocalized. - # - if obj: - try: - topLevel = self.topLevelObject(obj) - except Exception: - tokens = ["ERROR: Exception getting top-level object for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - if not topLevel: - return False - if AXObject.is_dead(topLevel): - tokens = ["SOFFICE: Top level object", topLevel, "is dead."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - if AXObject.get_name(topLevel).endswith("Impress"): - return True - - return False - - def slideAndTaskPanes(self, obj=cthulhu_state.locusOfFocus): - """Attempts to locate the Impress slide pane and task pane.""" - - drawingView = self.drawingView(obj) - if not drawingView: - return None, None - - parent = AXObject.get_parent(drawingView) - if parent: - parent = AXObject.get_parent(parent) - if not parent: - return None, None - - panes = self.findAllDescendants(parent, AXUtilities.is_split_pane) - if not panes: - return None, None - - slidePane = taskPane = None - if self.findAllDescendants(panes[0], self.isDocument): - slidePane = panes[0] - if len(panes) == 2: - taskPane = panes[1] - else: - taskPane = panes[0] - if len(panes) == 2: - slidePane = panes[1] - - return slidePane, taskPane - - def slideTitleAndPosition(self, obj): - """Attempts to obtain the title, position of the slide which contains - or is represented by obj. - - Returns a (title, position, count) tuple. - """ - - dv = self.getDocumentForObject(obj) - if not dv or not self.isDrawingView(dv): - return "", 0, 0 - - positionAndCount = AXObject.get_name(dv).split(":")[1] - position, count = positionAndCount.split("/") - title = "" - for child in dv: - childCount = AXObject.get_child_count(child) - if not childCount: - continue - # We want an actual Title. - # - if AXObject.get_name(child).startswith("ImpressTitle"): - title = self.displayedText(AXObject.get_child(child, 0)) - break - # But we'll live with a Subtitle if we can't find a title. - # Unlike Titles, a single subtitle can be made up of multiple - # accessibles. - # - elif AXObject.get_name(child).startswith("ImpressSubtitle"): - for i in range(childCount): - line = AXObject.get_child(child, i) - title = self.appendString(title, self.displayedText(line)) - - return title, int(position), int(count) - - ######################################################################### - # # - # Miscellaneous Utilities # - # # - ######################################################################### - - def isAutoTextEvent(self, event): - """Returns True if event is associated with text being autocompleted - or autoinserted or autocorrected or autosomethingelsed. - - Arguments: - - event: the accessible event being examined - """ - - if AXObject.get_role(event.source) != Atspi.Role.PARAGRAPH: - return False - - lastKey, mods = self.lastKeyAndModifiers() - if event.type.startswith("object:text-changed:insert"): - if not event.any_data: - return False - - if lastKey == "Tab" and event.any_data != "\t": - return True - - if lastKey in ["BackSpace", "ISO_Left_Tab"]: - return True - - if event.type.startswith("focus:"): - if lastKey == "Return": - return AXText.get_character_count(event.source) > 0 - - return False - - def containingComboBox(self, obj): - if AXUtilities.is_combo_box(obj): - comboBox = obj - else: - comboBox = AXObject.find_ancestor(obj, AXUtilities.is_combo_box) - - if not comboBox: - return None - - if not self.isZombie(comboBox): - return comboBox - - parent = AXObject.get_parent(comboBox) - if not parent: - return comboBox - - replicant = self.findReplicant(parent, comboBox) - if replicant and not self.isZombie(replicant): - comboBox = replicant - - return comboBox - - def isComboBoxSelectionChange(self, event): - comboBox = self.containingComboBox(event.source) - if not comboBox: - return False - - lastKey, mods = self.lastKeyAndModifiers() - if lastKey not in ["Down", "Up"]: - return False - - return True - - def isComboBoxNoise(self, event): - role = AXObject.get_role(event.source) - if role == Atspi.Role.TEXT and event.type.startswith("object:text-"): - return self.isComboBoxSelectionChange(event) - - return False - - def isPresentableTextChangedEventForLocusOfFocus(self, event): - if self.isComboBoxNoise(event): - msg = "SOFFICE: Event is believed to be combo box noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - return super().isPresentableTextChangedEventForLocusOfFocus(event) - - def isReadOnlyTextArea(self, obj): - if not super().isReadOnlyTextArea(obj): - return False - - return not self.inDocumentContent(obj) - - def isSelectedTextDeletionEvent(self, event): - if event.type.startswith("object:state-changed:selected") and not event.detail1: - return AXObject.is_dead(cthulhu_state.locusOfFocus) and self.lastInputEventWasDelete() - - return super().isSelectedTextDeletionEvent(event) - - def lastInputEventWasRedo(self): - if super().lastInputEventWasRedo(): - return True - - keyString, mods = self.lastKeyAndModifiers() - if mods & keybindings.COMMAND_MODIFIER_MASK and keyString.lower() == 'y': - return not (mods & keybindings.SHIFT_MODIFIER_MASK) - - return False - - def selectedChildren(self, obj): - # TODO - JD: Are these overrides still needed? They appear to be - # quite old. - - if obj is None: - return [] - - if not AXObject.supports_selection(obj) and AXUtilities.is_combo_box(obj): - child = AXObject.find_descendant(obj, AXObject.supports_selection) - if child: - return super().selectedChildren(child) - - # Things only seem broken for certain tables, e.g. the Paths table. - # TODO - JD: File the LibreOffice bugs and reference them here. - if not AXUtilities.is_table(obj): - return super().selectedChildren(obj) - - # We will need to special case this due to the possibility of there - # being lots of children (which may also prove to be zombie objects). - # This is why we can't have nice things. - if self.isSpreadSheetTable(obj): - return [] - - return AXSelection.get_selected_children(obj) - - def getFirstCaretPosition(self, obj): - if not AXObject.supports_text(obj): - if AXObject.get_child_count(obj): - return self.getFirstCaretPosition(AXObject.get_child(obj, 0)) - - return obj, 0 - - def getWordAtOffsetAdjustedForNavigation(self, obj, offset=None): - return self.getWordAtOffset(obj, offset) - - def shouldReadFullRow(self, obj): - if self._script._lastCommandWasStructNav: - return False - - lastKey, mods = self.lastKeyAndModifiers() - if lastKey in ["Tab", "ISO_Left_Tab"]: - return False - - return super().shouldReadFullRow(obj) - - def presentEventFromNonShowingObject(self, event): - return self.inDocumentContent(event.source) - - def columnConvert(self, column): - """ Convert a spreadsheet column into it's column label.""" - - base26 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - - if column <= len(base26): - return base26[column-1] - - res = "" - while column > 0: - digit = column % len(base26) - res = " " + base26[digit-1] + res - column = int(column / len(base26)) - - return res - - def _getCellNameForCoordinates(self, obj, row, col, includeContents=False): - if not AXObject.supports_table(obj): - tokens = ["SOFFICE: Exception querying Table interface of", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - cell = AXTable.get_cell_at(obj, row, col) - if not cell: - tokens = [f"SOFFICE: Exception getting cell ({row},{col}) of", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - name = self.spreadSheetCellName(cell) - if includeContents: - text = self.displayedText(cell) - name = f"{text} {name}" - - return name.strip() - - def _getCoordinatesForSelectedRange(self, obj): - if not (AXObject.supports_table(obj) and AXObject.supports_selection(obj)): - tokens = ["SOFFICE:", obj, "does not implement both selection and table"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return (-1, -1), (-1, -1) - - first = AXSelection.get_selected_child(obj, 0) - last = AXSelection.get_selected_child(obj, -1) - firstCoords = self.coordinatesForCell(first) - lastCoords = self.coordinatesForCell(last) - return firstCoords, lastCoords - - def getSelectionContainer(self, obj): - # Writer implements the selection interface on the document and all its - # children. The former is interesting, but interferes with our presentation - # of selected text. The latter is just weird. - if AXUtilities.is_document_text(obj): - return None - if AXObject.find_ancestor(obj, AXUtilities.is_document_text): - return None - return super().getSelectionContainer(obj) - - def speakSelectedCellRange(self, obj): - firstCoords, lastCoords = self._getCoordinatesForSelectedRange(obj) - if firstCoords == (-1, -1) or lastCoords == (-1, -1): - return False - - self._script.presentationInterrupt() - - if firstCoords == lastCoords: - cell = self._getCellNameForCoordinates(obj, *firstCoords, True) - self._script.speakMessage(messages.CELL_SELECTED % cell) - return True - - cell1 = self._getCellNameForCoordinates(obj, *firstCoords, True) - cell2 = self._getCellNameForCoordinates(obj, *lastCoords, True) - self._script.speakMessage(messages.CELL_RANGE_SELECTED % (cell1, cell2)) - return True - - def handleCellSelectionChange(self, obj): - firstCoords, lastCoords = self._getCoordinatesForSelectedRange(obj) - if firstCoords == (-1, -1) or lastCoords == (-1, -1): - return True - - current = [] - for r in range(firstCoords[0], lastCoords[0]+1): - current.extend((r, c) for c in range(firstCoords[1], lastCoords[1]+1)) - - current = set(current) - previous = set(self._calcSelectedCells) - current.discard((-1, -1)) - previous.discard((-1, -1)) - - unselected = sorted(previous.difference(current)) - selected = sorted(current.difference(previous)) - focusCoords = tuple(self.coordinatesForCell(cthulhu_state.locusOfFocus)) - if focusCoords in selected: - selected.remove(focusCoords) - - self._calcSelectedCells = sorted(current) - - msgs = [] - if len(unselected) == 1: - cell = self._getCellNameForCoordinates(obj, *unselected[0], True) - msgs.append(messages.CELL_UNSELECTED % cell) - elif len(unselected) > 1: - cell1 = self._getCellNameForCoordinates(obj, *unselected[0], True) - cell2 = self._getCellNameForCoordinates(obj, *unselected[-1], True) - msgs.append(messages.CELL_RANGE_UNSELECTED % (cell1, cell2)) - - if len(selected) == 1: - cell = self._getCellNameForCoordinates(obj, *selected[0], True) - msgs.append(messages.CELL_SELECTED % cell) - elif len(selected) > 1: - cell1 = self._getCellNameForCoordinates(obj, *selected[0], True) - cell2 = self._getCellNameForCoordinates(obj, *selected[-1], True) - msgs.append(messages.CELL_RANGE_SELECTED % (cell1, cell2)) - - if msgs: - self._script.presentationInterrupt() - - for msg in msgs: - self._script.speakMessage(msg, interrupt=False) - - return bool(len(msgs)) - - def handleRowAndColumnSelectionChange(self, obj): - if not (AXObject.supports_table(obj) and AXObject.supports_selection(obj)): - return True - - cols = set(AXTable.get_selected_columns(obj)) - rows = set(AXTable.get_selected_rows(obj)) - total_cols = AXTable.get_column_count(obj, prefer_attribute=False) - - selectedCols = sorted(cols.difference(set(self._calcSelectedColumns))) - unselectedCols = sorted(set(self._calcSelectedColumns).difference(cols)) - - def convertColumn(x): - return self.columnConvert(x+1) - - def convertRow(x): - return x + 1 - - selectedCols = list(map(convertColumn, selectedCols)) - unselectedCols = list(map(convertColumn, unselectedCols)) - - selectedRows = sorted(rows.difference(set(self._calcSelectedRows))) - unselectedRows = sorted(set(self._calcSelectedRows).difference(rows)) - - selectedRows = list(map(convertRow, selectedRows)) - unselectedRows = list(map(convertRow, unselectedRows)) - - self._calcSelectedColumns = list(cols) - self._calcSelectedRows = list(rows) - - if len(cols) == total_cols: - self._script.speakMessage(messages.DOCUMENT_SELECTED_ALL) - return True - - if not len(cols) and len(unselectedCols) == total_cols: - self._script.speakMessage(messages.DOCUMENT_UNSELECTED_ALL) - return True - - msgs = [] - if len(unselectedCols) == 1: - msgs.append(messages.TABLE_COLUMN_UNSELECTED % unselectedCols[0]) - elif len(unselectedCols) > 1: - msgs.append(messages.TABLE_COLUMN_RANGE_UNSELECTED % \ - (unselectedCols[0], unselectedCols[-1])) - - if len(unselectedRows) == 1: - msgs.append(messages.TABLE_ROW_UNSELECTED % unselectedRows[0]) - elif len(unselectedRows) > 1: - msgs.append(messages.TABLE_ROW_RANGE_UNSELECTED % \ - (unselectedRows[0], unselectedRows[-1])) - - if len(selectedCols) == 1: - msgs.append(messages.TABLE_COLUMN_SELECTED % selectedCols[0]) - elif len(selectedCols) > 1: - msgs.append(messages.TABLE_COLUMN_RANGE_SELECTED % (selectedCols[0], selectedCols[-1])) - - if len(selectedRows) == 1: - msgs.append(messages.TABLE_ROW_SELECTED % selectedRows[0]) - elif len(selectedRows) > 1: - msgs.append(messages.TABLE_ROW_RANGE_SELECTED % (selectedRows[0], selectedRows[-1])) - - if msgs: - self._script.presentationInterrupt() - - for msg in msgs: - self._script.speakMessage(msg, interrupt=False) - - return bool(len(msgs)) diff --git a/src/cthulhu/scripts/apps/soffice/speech_generator.py b/src/cthulhu/scripts/apps/soffice/speech_generator.py deleted file mode 100644 index e94f2ba..0000000 --- a/src/cthulhu/scripts/apps/soffice/speech_generator.py +++ /dev/null @@ -1,524 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for StarOffice and OpenOffice.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.messages as messages -import cthulhu.role_keys as role_keys -import cthulhu.settings_manager as settings_manager -import cthulhu.speech_generator as speech_generator -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -_settingsManager = settings_manager.getManager() - -class SpeechGenerator(speech_generator.SpeechGenerator): - def __init__(self, script): - speech_generator.SpeechGenerator.__init__(self, script) - - def __overrideParagraph(self, obj, **args): - # Treat a paragraph which is serving as a text entry in a dialog - # as a text object. - # - role = args.get('role', AXObject.get_role(obj)) - if role == "text frame": - return True - if role != Atspi.Role.PARAGRAPH: - return False - return AXObject.find_ancestor(obj, AXUtilities.is_dialog) is not None - - def _generateRoleName(self, obj, **args): - result = [] - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.TOGGLE_BUTTON \ - and AXObject.get_role(AXObject.get_parent(obj)) == Atspi.Role.TOOL_BAR: - pass - else: - # Treat a paragraph which is serving as a text entry in a dialog - # as a text object. - # - override = self.__overrideParagraph(obj, **args) - if override: - oldRole = self._overrideRole(Atspi.Role.TEXT, args) - # Treat a paragraph which is inside of a spreadsheet cell as - # a spreadsheet cell. - # - elif role == role_keys.ROLE_SPREADSHEET_CELL: - oldRole = self._overrideRole(Atspi.Role.TABLE_CELL, args) - override = True - result.extend(speech_generator.SpeechGenerator._generateRoleName( - self, obj, **args)) - if override: - self._restoreRole(oldRole, args) - return result - - def _generateTextRole(self, obj, **args): - result = [] - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.TEXT \ - and AXObject.get_role(AXObject.get_parent(obj)) == Atspi.Role.COMBO_BOX: - return [] - - if role != Atspi.Role.PARAGRAPH \ - or self.__overrideParagraph(obj, **args): - result.extend(self._generateRoleName(obj, **args)) - return result - - def _generateLabel(self, obj, **args): - """Returns the label for an object as an array of strings (and - possibly voice and audio specifications). The label is - determined by the displayedLabel method of the script utility, - and an empty array will be returned if no label can be found. - """ - result = [] - override = self.__overrideParagraph(obj, **args) - label = self._script.utilities.displayedLabel(obj) or "" - if not label and override: - label = self._script.utilities.displayedLabel(AXObject.get_parent(obj)) or "" - if label: - result.append(label.strip()) - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - return result - - def _generateName(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the name of the object. If the object is directly - displaying any text, that text will be treated as the name. - Otherwise, the accessible name of the object will be used. If - there is no accessible name, then the description of the - object will be used. This method will return an empty array - if nothing can be found. - """ - - # TODO - JD: This should be the behavior by default. But the default - # generators call displayedText(). Once that is corrected, this method - # can be removed. - if AXObject.get_name(obj): - result = [AXObject.get_name(obj)] - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - return result - - return super()._generateName(obj, **args) - - def _generateLabelAndName(self, obj, **args): - if AXObject.get_role(obj) != Atspi.Role.COMBO_BOX: - return super()._generateLabelAndName(obj, **args) - - # TODO - JD: This should be the behavior by default because many - # toolkits use the label for the name. - result = [] - label = self._script.utilities.displayedLabel(obj) or AXObject.get_name(obj) - if label: - result.append(label) - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - - name = AXObject.get_name(obj) - if label == name or not name: - selected = self._script.utilities.selectedChildren(obj) - if selected: - name = AXObject.get_name(selected[0]) - - if name: - result.append(name) - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - - return result - - def _generateLabelOrName(self, obj, **args): - """Gets the label or the name if the label is not preset.""" - - result = [] - override = self.__overrideParagraph(obj, **args) - # Treat a paragraph which is serving as a text entry in a dialog - # as a text object. - # - if override: - result.extend(self._generateLabel(obj, **args)) - if len(result) == 0 and AXObject.get_parent(obj): - parentLabel = self._generateLabel(AXObject.get_parent(obj), **args) - # If we aren't already focused, we will have spoken the - # parent as part of the speech context and do not want - # to repeat it. - # - alreadyFocused = args.get('alreadyFocused', False) - if alreadyFocused: - result.extend(parentLabel) - # If we still don't have a label, look to the name. - # - if not parentLabel: - name = AXObject.get_name(obj) - if name: - result.append(name) - if result: - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - else: - result.extend(speech_generator.SpeechGenerator._generateLabelOrName( - self, obj, **args)) - return result - - def _generateAnyTextSelection(self, obj, **args): - comboBoxEntry = self._script.utilities.getEntryForEditableComboBox(obj) - if comboBoxEntry: - return super()._generateAnyTextSelection(comboBoxEntry) - - return super()._generateAnyTextSelection(obj, **args) - - def _generateAvailability(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the grayed/sensitivity/availability state of the - object, but only if it is insensitive (i.e., grayed out and - inactive). Otherwise, and empty array will be returned. - """ - - result = [] - if not self._script.utilities.isSpreadSheetCell(obj): - result.extend(speech_generator.SpeechGenerator.\ - _generateAvailability(self, obj, **args)) - - return result - - def _generateDescription(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the description of the object, - if that description is different from that of the name and - label. - """ - if _settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not _settingsManager.getSetting('speakDescription'): - return [] - - if not args.get('formatType', '').endswith('WhereAmI'): - return [] - - result = [] - description = AXObject.get_description(obj) - if description: - # The description of some OOo paragraphs consists of the name - # and the displayed text, with punctuation added. Try to spot - # this and, if found, ignore the description. - # - text = self._script.utilities.displayedText(obj) or "" - desc = description.replace(text, "") - for item in AXObject.get_name(obj).split(): - desc = desc.replace(item, "") - for char in desc.strip(): - if char.isalnum(): - result.append(description) - break - - if result: - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - def _generateCurrentLineText(self, obj, **args): - if self._script.utilities.isTextDocumentCell(AXObject.get_parent(obj)): - priorObj = args.get('priorObj', None) - if priorObj and AXObject.get_parent(priorObj) != AXObject.get_parent(obj): - return [] - - if AXObject.get_role(obj) == Atspi.Role.COMBO_BOX: - entry = self._script.utilities.getEntryForEditableComboBox(obj) - if entry: - return super()._generateCurrentLineText(entry) - return [] - - # TODO - JD: The SayLine, etc. code should be generated and not put - # together in the scripts. In addition, the voice crap needs to go - # here. Then it needs to be removed from the scripts. - [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj) - if not text: - result = [messages.BLANK] - result.extend(self.voice(string=text, obj=obj, **args)) - return result - - return super()._generateCurrentLineText(obj, **args) - - def _generateToggleState(self, obj, **args): - """Treat toggle buttons in the toolbar specially. This is so we can - have more natural sounding speech such as "bold on", "bold off", etc.""" - result = [] - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.TOGGLE_BUTTON \ - and AXObject.get_role(AXObject.get_parent(obj)) == Atspi.Role.TOOL_BAR: - if AXUtilities.is_checked(obj): - result.append(messages.ON) - else: - result.append(messages.OFF) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - elif role == Atspi.Role.TOGGLE_BUTTON: - result.extend(speech_generator.SpeechGenerator._generateToggleState( - self, obj, **args)) - return result - - def _generateRowHeader(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the row header for an object - that is in a table, if it exists. Otherwise, an empty array - is returned. Overridden here so that we can get the dynamic - row header(s). - """ - - if self._script.utilities.shouldReadFullRow(obj): - return [] - - newOnly = args.get('newOnly', False) - rowHeader, columnHeader = \ - self._script.utilities.getDynamicHeadersForCell(obj, newOnly) - if not rowHeader: - return super()._generateRowHeader(obj, **args) - - result = [] - text = self._script.utilities.displayedText(rowHeader) - if text: - result.append(text) - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - - return result - - def _generateColumnHeader(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the column header for an object - that is in a table, if it exists. Otherwise, an empty array - is returned. Overridden here so that we can get the dynamic - column header(s). - """ - - newOnly = args.get('newOnly', False) - rowHeader, columnHeader = \ - self._script.utilities.getDynamicHeadersForCell(obj, newOnly) - if not columnHeader: - return super()._generateColumnHeader(obj, **args) - - result = [] - text = self._script.utilities.displayedText(columnHeader) - if text: - result.append(text) - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - - return result - - def _generateTooLong(self, obj, **args): - """If there is text in this spread sheet cell, compare the size of - the text within the table cell with the size of the actual table - cell and report back to the user if it is larger. - - Returns an indication of how many characters are greater than the size - of the spread sheet cell, or None if the message fits. - """ - if _settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - if AXObject.supports_text(obj): - objectText = self._script.utilities.substring(obj, 0, -1) - extents = None - if AXObject.supports_component(obj): - try: - extents = Atspi.Component.get_extents(obj, Atspi.CoordType.SCREEN) - except Exception: - extents = None - - if extents is not None: - tooLongCount = 0 - for i in range(0, len(objectText)): - rect = Atspi.Text.get_range_extents( - obj, i, i + 1, Atspi.CoordType.SCREEN) - x = rect.x - width = rect.width - if x < extents.x: - tooLongCount += 1 - elif (x + width) > extents.x + extents.width: - tooLongCount += len(objectText) - i - break - if tooLongCount > 0: - result = [messages.charactersTooLong(tooLongCount)] - if result: - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - def _generateHasFormula(self, obj, **args): - inputLine = self._script.utilities.locateInputLine(obj) - if not inputLine: - return [] - - text = self._script.utilities.displayedText(inputLine) - if text and text.startswith("="): - result = [messages.HAS_FORMULA] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - return [] - - def _generateRealTableCell(self, obj, **args): - """Get the speech for a table cell. If this isn't inside a - spread sheet, just return the utterances returned by the default - table cell speech handler. - - Arguments: - - obj: the table cell - - Returns a list of utterances to be spoken for the object. - """ - - if self._script.inSayAll(): - return [] - - result = super()._generateRealTableCell(obj, **args) - - if not self._script.utilities.isSpreadSheetCell(obj): - if self._script._lastCommandWasStructNav: - return result - - if _settingsManager.getSetting('speakCellCoordinates'): - result.append(AXObject.get_name(obj)) - return result - - isBasicWhereAmI = args.get('formatType') == 'basicWhereAmI' - speakCoordinates = _settingsManager.getSetting('speakSpreadsheetCoordinates') - if speakCoordinates and not isBasicWhereAmI: - result.append(self._script.utilities.spreadSheetCellName(obj)) - - if self._script.utilities.shouldReadFullRow(obj): - row, col, table = self._script.utilities.getRowColumnAndTable(obj) - lastRow = self._script.pointOfReference.get("lastRow") - if row != lastRow: - return result - - tooLong = self._generateTooLong(obj, **args) - if tooLong: - result.extend(self._generatePause(obj, **args)) - result.extend(tooLong) - - hasFormula = self._generateHasFormula(obj, **args) - if hasFormula: - result.extend(self._generatePause(obj, **args)) - result.extend(hasFormula) - - return result - - def _generateTableCellRow(self, obj, **args): - if not self._script.utilities.shouldReadFullRow(obj): - return self._generateRealTableCell(obj, **args) - - if not self._script.utilities.isSpreadSheetCell(obj): - return super()._generateTableCellRow(obj, **args) - - cells = self._script.utilities.getShowingCellsInSameRow(obj) - if not cells: - return [] - - result = [] - for cell in cells: - result.extend(self._generateRealTableCell(cell, **args)) - - return result - - def _generateEndOfTableIndicator(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) indicating that this cell is the last cell - in the table. Overridden here because Cthulhu keeps saying "end - of table" in certain lists (e.g. the Templates and Documents - dialog). - """ - - if self._script._lastCommandWasStructNav or self._script.inSayAll(): - return [] - - topLevel = self._script.utilities.topLevelObject(obj) - if topLevel and AXObject.get_role(topLevel) == Atspi.Role.DIALOG: - return [] - - return super()._generateEndOfTableIndicator(obj, **args) - - def _generateNewAncestors(self, obj, **args): - priorObj = args.get('priorObj', None) - if not priorObj or AXObject.get_role_name(priorObj) == 'text frame': - return [] - - if self._script.utilities.isSpreadSheetCell(obj) \ - and self._script.utilities.isDocumentPanel(AXObject.get_parent(priorObj)): - return [] - - return super()._generateNewAncestors(obj, **args) - - def _generateOldAncestors(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the text of the ancestors for - the object being left.""" - - if AXObject.get_role_name(obj) == 'text frame': - return [] - - priorObj = args.get('priorObj', None) - if self._script.utilities.isSpreadSheetCell(priorObj): - return [] - - return super()._generateOldAncestors(obj, **args) - - def _generateUnselectedCell(self, obj, **args): - if self._script.utilities.isSpreadSheetCell(obj): - return [] - - if self._script._lastCommandWasStructNav: - return [] - - return super()._generateUnselectedCell(obj, **args) - - def generateSpeech(self, obj, **args): - result = [] - if args.get('formatType', 'unfocused') == 'basicWhereAmI' \ - and self._script.utilities.isSpreadSheetCell(obj): - oldRole = self._overrideRole(role_keys.ROLE_SPREADSHEET_CELL, args) - # In addition, if focus is in a cell being edited, we cannot - # query the accessible table interface for coordinates and the - # like because we're temporarily in an entirely different object - # which is outside of the table. This makes things difficult. - # However, odds are that if we're doing a whereAmI in a cell - # which we are editing, we have some pointOfReference info - # we can use to guess the coordinates. - # - args['guessCoordinates'] = AXObject.get_role(obj) == Atspi.Role.PARAGRAPH - result.extend(super().generateSpeech(obj, **args)) - del args['guessCoordinates'] - self._restoreRole(oldRole, args) - else: - oldRole = self._overrideRole(self._getAlternativeRole(obj, **args), args) - result.extend(super().generateSpeech(obj, **args)) - self._restoreRole(oldRole, args) - - return result diff --git a/src/cthulhu/scripts/apps/soffice/spellcheck.py b/src/cthulhu/scripts/apps/soffice/spellcheck.py deleted file mode 100644 index 00ca72c..0000000 --- a/src/cthulhu/scripts/apps/soffice/spellcheck.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Customized support for spellcheck in LibreOffice.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2015 Igalia, S.L." -__license__ = "LGPL" - -from cthulhu import debug -from cthulhu import messages -from cthulhu import spellcheck -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -class SpellCheck(spellcheck.SpellCheck): - - def __init__(self, script): - super().__init__(script, hasChangeToEntry=False) - self._windows = {} - - def _findChildDialog(self, root): - if root is None: - return None - - if AXUtilities.is_dialog(root): - return root - - return self._findChildDialog(AXObject.get_child(root, 0)) - - def _isCandidateWindow(self, window): - if AXObject.is_dead(window): - tokens = ["SOFFICE:", window, "is not spellcheck window because it's dead."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - rv = self._windows.get(hash(window)) - if rv is not None: - tokens = ["SOFFICE:", window, "is spellcheck window:", rv] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - dialog = self._findChildDialog(window) - if not dialog: - self._windows[hash(window)] = False - tokens = ["SOFFICE:", window, - "is not spellcheck window because the dialog was not found."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if AXObject.find_descendant(dialog, AXUtilities.is_page_tab_list) is not None: - self._windows[hash(window)] = False - self._windows[hash(dialog)] = False - tokens = ["SOFFICE:", dialog, - "is not spellcheck dialog because a page tab list was found."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - rv = AXObject.find_descendant(dialog, AXUtilities.is_combo_box) is not None - tokens = ["SOFFICE:", dialog, "is spellcheck dialog based on combobox descendant:", rv] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._windows[hash(dialog)] = rv - return rv - - def _findErrorWidget(self, root): - def isError(x): - if not AXObject.supports_editable_text(x): - return False - return AXUtilities.is_focusable(x) and AXUtilities.is_multi_line(x) - - rv = AXObject.find_descendant(root, isError) - tokens = ["SOFFICE: Error widget for:", root, "is:", rv] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - def _findSuggestionsList(self, root): - def isSelectableList(x): - if not AXObject.supports_selection(x): - return False - return AXUtilities.is_list(x) \ - or AXUtilities.is_list_box(x) \ - or AXUtilities.is_tree_table(x) - - rv = AXObject.find_descendant(root, isSelectableList) - tokens = ["SOFFICE: Suggestions list for:", root, "is:", rv] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - def _getSuggestionIndexAndPosition(self, suggestion): - index, total = self._script.utilities.getPositionAndSetSize(suggestion) - return index + 1, total - - def getMisspelledWord(self): - if not AXObject.supports_text(self._errorWidget): - return "" - - offset, string = 0, "" - char_count = AXText.get_character_count(self._errorWidget) - while 0 <= offset < char_count: - attrs, start, end = AXText.get_text_attributes_at_offset(self._errorWidget, offset) - if attrs.get("fg-color", "").replace(" ", "") == "255,0,0": - return AXText.get_substring(self._errorWidget, start, end) - offset = max(end, offset + 1) - - return string - - def presentContext(self): - if not self.isActive(): - return False - - if not AXObject.supports_text(self._errorWidget): - return False - - string = AXText.get_all_text(self._errorWidget) - if not string: - return False - - msg = messages.MISSPELLED_WORD_CONTEXT % string - voice = self._script.speechGenerator.voice(string=msg) - self._script.speakMessage(msg, voice=voice) - return True diff --git a/src/cthulhu/scripts/apps/steamwebhelper/__init__.py b/src/cthulhu/scripts/apps/steamwebhelper/__init__.py deleted file mode 100644 index 585c964..0000000 --- a/src/cthulhu/scripts/apps/steamwebhelper/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .script import Script diff --git a/src/cthulhu/scripts/apps/steamwebhelper/meson.build b/src/cthulhu/scripts/apps/steamwebhelper/meson.build deleted file mode 100644 index 17c4477..0000000 --- a/src/cthulhu/scripts/apps/steamwebhelper/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -steamwebhelper_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - steamwebhelper_python_sources, - subdir: 'cthulhu/scripts/apps/steamwebhelper' -) diff --git a/src/cthulhu/scripts/apps/steamwebhelper/script.py b/src/cthulhu/scripts/apps/steamwebhelper/script.py deleted file mode 100644 index 3f3626b..0000000 --- a/src/cthulhu/scripts/apps/steamwebhelper/script.py +++ /dev/null @@ -1,1178 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Steam Web Helper (Steam client UI).""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import time -import re -from typing import Any - -from gi.repository import GLib - -from cthulhu import debug -from cthulhu import input_event_manager -from cthulhu import settings -from cthulhu import cthulhu_state -from cthulhu import settings_manager -from cthulhu import structural_navigation -from cthulhu.ax_object import AXObject -from cthulhu.ax_selection import AXSelection -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_relation import AXUtilitiesRelation -from cthulhu.ax_utilities_role import AXUtilitiesRole -from cthulhu.scripts.toolkits import Chromium -from .script_utilities import Utilities - -settingsManager = settings_manager.getManager() - - -class SteamStructuralNavigation(structural_navigation.StructuralNavigation): - def _headingGetter(self, document, arg=None): - def isUsefulHeading(candidate): - if not self._script.utilities.inDocumentContent(candidate): - return False - - text = self._script.utilities.displayedText(candidate) or AXObject.get_name(candidate) - if not text: - return False - - return not text.strip().isdigit() - - if arg is None: - return super()._headingGetter(document, arg) - - headings = super()._headingGetter(document, None) - headings = [heading for heading in headings if isUsefulHeading(heading)] - return [heading for heading in headings if self._script.utilities.headingLevel(heading) == arg] - - -class Script(Chromium.Script): - """Script for Steam Web Helper with background notification support.""" - - def __init__(self, app): - """Creates a new script for the Steam Web Helper application. - - Arguments: - - app: the application to create a script for. - """ - super().__init__(app) - # CRITICAL: Enable background event processing for notifications - # This allows Steam notifications to be spoken even when Steam - # is not the focused application. - self.presentIfInactive = True - self._lastSteamNotification = ("", 0.0) - self._steamPendingNotification = None - self._steamNotificationDelayMs = 500 - self._lastSteamOverlaySelection = ("", 0.0) - self._steamActiveQuickAccessTab = "" - self._steamFriendsPanelActivationTarget = (None, "", 0.0) - self._steamFriendsPanelActivationTargetMaxAge = 10.0 - self._steamRelativeTimePattern = re.compile( - r"^(?:just now|now|\d+\s+(?:second|minute|hour|day|week|month|year)s?\s+ago)$", - re.IGNORECASE - ) - - def shouldConsumeKeyboardEvent(self, keyboardEvent, handler) -> bool: - consumes = super().shouldConsumeKeyboardEvent(keyboardEvent, handler) - if consumes: - return True - - return self._trySteamButtonActivation(keyboardEvent) - - def onShowingChanged(self, event): - """Callback for object:state-changed:showing accessibility events.""" - - # Check if this is a Steam notification/alert becoming visible - if event.detail1 and self._isSteamNotification(event.source): - self._presentSteamNotification(event.source) - return - - # Fall through to Chromium/web handling - super().onShowingChanged(event) - - def getUtilities(self): - return Utilities(self) - - def onChildrenAdded(self, event): - """Callback for object:children-changed:add accessibility events.""" - - # Check if a notification element was added - if self._isSteamNotification(event.any_data): - self._presentSteamNotification(event.any_data) - return - - if self._presentSteamFriendsPanelNavigation(event): - return True - - if self._handleSteamVirtualizedListMutation(event): - return True - - super().onChildrenAdded(event) - - def onChildrenRemoved(self, event): - """Callback for object:children-changed:removed accessibility events.""" - - if self._handleSteamVirtualizedListMutation(event): - return True - - return super().onChildrenRemoved(event) - - def getStructuralNavigation(self): - types = self.getEnabledStructuralNavigationTypes() - enable = settingsManager.getSetting('structuralNavigationEnabled') - return SteamStructuralNavigation(self, types, enable) - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if event.detail1 and AXUtilities.is_document_web(event.source): - prevDocument = self.utilities.getDocumentForObject(cthulhu_state.locusOfFocus) - if prevDocument and AXUtilities.is_embedded(prevDocument) \ - and self.utilities.inDocumentContent(cthulhu_state.locusOfFocus): - msg = "STEAM: Ignoring focus event for top-level document while in embedded content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if event.detail1 \ - and AXUtilitiesRole.is_button(event.source) \ - and cthulhu_state.locusOfFocus in AXUtilitiesRelation.get_is_labelled_by(event.source): - msg = "STEAM: Ignoring focus event for labelled button" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return super().onFocusedChanged(event) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - self._logSteamNavigationEvent("name-changed", event) - if self._presentSteamFriendsPanelNavigation(event): - return True - - return super().onNameChanged(event) - - def onTextInserted(self, event): - """Callback for object:text-changed:insert accessibility events.""" - - if self._presentSteamLiveRegionText(event): - return - - if self._presentSteamFriendsPanelNavigation(event): - return True - - super().onTextInserted(event) - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - if self._isSteamLoadingSpinnerCaretEvent(event): - msg = "STEAM: Ignoring caret event from transient loading spinner" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return super().onCaretMoved(event) - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - self._logSteamNavigationEvent("selection-changed", event) - if self._presentSteamOverlaySelection(event): - return True - return super().onSelectionChanged(event) - - def onSelectedChanged(self, event): - """Callback for object:state-changed:selected accessibility events.""" - - self._logSteamNavigationEvent("selected-changed", event) - if self._presentSteamOverlaySelection(event): - return True - return super().onSelectedChanged(event) - - def onActiveDescendantChanged(self, event): - """Callback for object:active-descendant-changed accessibility events.""" - - self._logSteamNavigationEvent("active-descendant-changed", event) - return super().onActiveDescendantChanged(event) - - def _handleSteamVirtualizedListMutation(self, event): - if not event or not self.utilities.isSteamVirtualizedList(event.source): - return False - - focus = cthulhu_state.locusOfFocus - if not focus or AXObject.is_dead(focus): - return False - - if not AXObject.find_ancestor(focus, lambda x: x == event.source): - return False - - AXObject.clear_cache_now("children-changed event.") - self.utilities.clearSteamVirtualizedListCaches() - msg = "STEAM: Skipping generic web cache dump for virtualized list churn near focus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - def _presentSteamOverlaySelection(self, event) -> bool: - if not event: - return False - - eventType = getattr(event, "type", "") - if not isinstance(eventType, str) or not ( - eventType.startswith("object:selection-changed") - or eventType.startswith("object:state-changed:selected") - ): - return False - - if not self._activeX11WindowIsSteamSelectionContext(): - return False - - if not self._steamOverlaySelectionWasUserInitiated(): - return False - - obj = self._getSteamOverlaySelectionObject(event) - if not obj or not self._isSteamOverlaySelectionObject(obj): - return False - - text = self._getSteamOverlaySelectionText(obj) - if not text: - return False - - if AXUtilities.is_page_tab(obj): - self._steamActiveQuickAccessTab = text - self._clearSteamFriendsPanelActivationTarget() - - if self._isDuplicateSteamOverlaySelection(text): - msg = f"STEAM: Suppressing duplicate overlay selection: {text}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - self.presentMessage(text, force=True, interrupt=True) - msg = f"STEAM: Presented overlay selection: {text}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - def _getSteamOverlaySelectionObject(self, event): - if event.type.startswith("object:state-changed:selected"): - if not event.detail1: - return None - return event.source - - if not event.type.startswith("object:selection-changed"): - return None - - for child in AXSelection.get_selected_children(event.source): - if child: - return child - - anyData = event.any_data - if anyData is not None and not isinstance(anyData, (bool, int, float, str)): - return anyData - - return event.source - - def _isSteamOverlaySelectionObject(self, obj) -> bool: - if not obj: - return False - - try: - if not self.utilities.inDocumentContent(obj): - return False - except Exception: - return False - - if not self._hasSteamOverlaySelectionContext(obj): - return False - - if not ( - AXUtilities.is_page_tab(obj) - or AXUtilities.is_list_item(obj) - or AXUtilities.is_menu_item(obj) - or AXUtilities.is_button(obj) - or AXUtilities.is_push_button(obj) - ): - return False - - return bool(self._getSteamOverlaySelectionText(obj)) - - def _getSteamOverlaySelectionText(self, obj) -> str: - text = self.utilities.displayedText(obj) or AXObject.get_name(obj) or "" - text = self._normalizeSteamNotificationText(text) - if text: - return text - - return self._getSteamQuickAccessTabLabel(obj) - - def _getSteamQuickAccessTabLabel(self, obj) -> str: - if not AXUtilities.is_page_tab(obj): - return "" - - if not self._hasSteamQuickAccessMarker(obj): - return "" - - tabId = AXObject.get_attribute(obj, "id") or "" - quickAccessTabLabels = { - "quickaccess_tab_3": "Friends", - } - label = quickAccessTabLabels.get(tabId, "") - if label: - msg = f"STEAM: Inferred QuickAccess tab label: {label}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - return label - - def _presentSteamFriendsPanelNavigation(self, event) -> bool: - if not self._steamFriendsPanelNavigationIsExpected(event): - return False - - obj = self._getSteamFriendsPanelNavigationObject(event) - if not obj or not self._isSteamFriendsPanelNavigationObject(obj): - return False - - text = self._getSteamFriendsPanelNavigationText(obj) - if not text: - return False - - self._rememberSteamFriendsPanelActivationTarget(obj, text) - if self._isDuplicateSteamOverlaySelection(text): - msg = f"STEAM: Suppressing duplicate Friends panel item: {text}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - self.presentMessage(text, force=True, interrupt=True) - msg = f"STEAM: Presented Friends panel item: {text}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - def _steamFriendsPanelNavigationIsExpected(self, event) -> bool: - if not event: - return False - - eventType = getattr(event, "type", "") - if not isinstance(eventType, str) or not eventType.startswith(( - "object:property-change:accessible-name", - "object:active-descendant-changed", - )): - return False - - if getattr(self, "_steamActiveQuickAccessTab", "") != "Friends": - return False - - if not self._activeX11WindowIsSteamSelectionContext(): - return False - - return self._steamOverlaySelectionWasUserInitiated() - - @staticmethod - def _getSteamFriendsPanelNavigationObject(event): - anyData = getattr(event, "any_data", None) - if anyData is not None and not isinstance(anyData, (bool, int, float, str, bytes)): - return anyData - - return getattr(event, "source", None) - - def _isSteamFriendsPanelNavigationObject(self, obj) -> bool: - try: - if not self._hasSteamQuickAccessMarker(obj): - return False - except Exception: - return False - - if AXUtilities.is_page_tab(obj) or AXUtilities.is_page_tab_list(obj): - return False - - if self._isIgnoredSteamFriendsPanelObject(obj): - return False - - return ( - AXUtilities.is_list_item(obj) - or AXUtilities.is_button(obj) - or AXUtilities.is_push_button(obj) - or AXUtilities.is_table_row(obj) - ) - - def _isIgnoredSteamFriendsPanelObject(self, obj) -> bool: - def isIgnored(candidate) -> bool: - if candidate is None: - return False - - className = AXObject.get_attribute(candidate, "class") or "" - accessibleId = AXObject.get_attribute(candidate, "id") or "" - searchable = f"{className} {accessibleId}".casefold() - ignoredMarkers = ( - "addfriendbutton", - "chathistorycontainer", - "chatdialogs", - "chatwindow", - "chatentry", - "chatmessage", - "messagelist", - "messageinput", - "textarea", - ) - return any(marker in searchable for marker in ignoredMarkers) - - try: - return AXObject.find_ancestor_inclusive(obj, isIgnored) is not None - except Exception: - return False - - def _getSteamFriendsPanelNavigationText(self, obj) -> str: - text = self._getSteamFriendsPanelReadableText(obj) - if self._isUsefulSteamFriendsPanelText(text): - return text - - return "" - - def _rememberSteamFriendsPanelActivationTarget(self, obj: Any, text: str) -> None: - self._steamFriendsPanelActivationTarget = (obj, text, time.monotonic()) - - def _clearSteamFriendsPanelActivationTarget(self) -> None: - self._steamFriendsPanelActivationTarget = (None, "", 0.0) - - def _getSteamFriendsPanelActivationTarget(self) -> Any: - if getattr(self, "_steamActiveQuickAccessTab", "") != "Friends": - return None - - if not self._activeX11WindowIsSteamSelectionContext(): - return None - - obj, text, timestamp = getattr( - self, - "_steamFriendsPanelActivationTarget", - (None, "", 0.0), - ) - if not obj or not text: - return None - - maxAge = getattr(self, "_steamFriendsPanelActivationTargetMaxAge", 10.0) - if time.monotonic() - timestamp > maxAge: - msg = f"STEAM: Clearing stale Friends panel activation target: {text}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._clearSteamFriendsPanelActivationTarget() - return None - - try: - if AXObject.is_dead(obj): - self._clearSteamFriendsPanelActivationTarget() - return None - except Exception: - self._clearSteamFriendsPanelActivationTarget() - return None - - if not self._isSteamFriendsPanelNavigationObject(obj): - self._clearSteamFriendsPanelActivationTarget() - return None - - return obj - - def _getSteamFriendsPanelReadableText(self, obj) -> str: - text = "" - try: - text = self.utilities.displayedText(obj) or AXObject.get_name(obj) or "" - except Exception: - try: - text = AXObject.get_name(obj) or "" - except Exception: - text = "" - - text = self._normalizeSteamFriendsPanelText(text) - if text: - return text - - try: - if AXObject.supports_text(obj): - text = AXText.get_all_text(obj) or "" - except Exception: - text = "" - - return self._normalizeSteamFriendsPanelText(text) - - def _normalizeSteamFriendsPanelText(self, text: str) -> str: - if not text: - return "" - - text = text.replace(self.EMBEDDED_OBJECT_CHARACTER, " ") - text = text.replace("[OBJ]", " ") - return " ".join(text.split()) - - @staticmethod - def _isUsefulSteamFriendsPanelText(text: str) -> bool: - if not text: - return False - - textLower = text.casefold() - if textLower in {"friends", "add friend", "unlabeled image"}: - return False - - ignoredFragments = ( - "loading older messages", - "hold to send a quick message", - "is typing a message", - ) - if any(fragment in textLower for fragment in ignoredFragments): - return False - - return not text.isdigit() - - def _hasSteamQuickAccessMarker(self, obj) -> bool: - def hasMarker(candidate) -> bool: - if candidate is None: - return False - - name = AXObject.get_name(candidate) or "" - if name.startswith("QuickAccess_uid"): - return True - - accessibleId = AXObject.get_attribute(candidate, "id") or "" - if accessibleId.startswith("quickaccess_"): - return True - - className = AXObject.get_attribute(candidate, "class") or "" - return "quickaccess" in className.casefold() - - return AXObject.find_ancestor_inclusive(obj, hasMarker) is not None - - def _hasSteamOverlaySelectionContext(self, obj) -> bool: - if self._hasSteamQuickAccessMarker(obj): - return True - - return self._isSteamBigPictureDocumentObject(obj) - - def _isSteamBigPictureDocumentObject(self, obj) -> bool: - try: - document = self.utilities.getTopLevelDocumentForObject(obj) - if not document: - document = self.utilities.getDocumentForObject(obj) - except Exception: - return False - - if not document: - return False - - try: - uri = self.utilities.documentFrameURI(document) or "" - except Exception: - uri = "" - - if "steamloopback.host" in uri.casefold(): - return True - - name = AXObject.get_name(document) or "" - return name.strip() == "Steam Big Picture Mode" - - def _steamOverlaySelectionWasUserInitiated(self) -> bool: - event = cthulhu_state.lastNonModifierKeyEvent or cthulhu_state.lastInputEvent - if event is None: - return False - - modifiers = getattr(event, "modifiers", 0) or 0 - if modifiers: - return False - - key = getattr(event, "event_string", None) or getattr(event, "keyval_name", "") - return key in {"Left", "Right", "Up", "Down", "Return", "KP_Enter", "space", " "} - - def _activeX11WindowIsSteamGame(self) -> bool: - window = input_event_manager.get_manager()._get_active_x11_window() - return self._x11WindowHasSteamGameClass(window) - - def _activeX11WindowIsSteamSelectionContext(self) -> bool: - window = input_event_manager.get_manager()._get_active_x11_window() - return self._x11WindowHasSteamGameClass(window) or self._x11WindowIsSteamBigPicture(window) - - @classmethod - def _x11WindowHasSteamGameClass(cls, window) -> bool: - if window is None: - return False - - identifiers = [ - cls._safeSteamWindowCall(window, "get_class_group_name"), - cls._safeSteamWindowCall(window, "get_class_instance_name"), - ] - classGroup = cls._safeSteamWindowCall(window, "get_class_group") - if classGroup is not None: - identifiers.extend([ - cls._safeSteamWindowCall(classGroup, "get_name"), - cls._safeSteamWindowCall(classGroup, "get_res_class"), - ]) - - return any(cls._isSteamGameWindowIdentifier(identifier) for identifier in identifiers) - - @classmethod - def _x11WindowIsSteamBigPicture(cls, window) -> bool: - if window is None: - return False - - name = cls._safeSteamWindowCall(window, "get_name") - if not isinstance(name, str) or name.strip() != "Steam Big Picture Mode": - return False - - identifiers = [ - cls._safeSteamWindowCall(window, "get_class_group_name"), - cls._safeSteamWindowCall(window, "get_class_instance_name"), - ] - classGroup = cls._safeSteamWindowCall(window, "get_class_group") - if classGroup is not None: - identifiers.extend([ - cls._safeSteamWindowCall(classGroup, "get_name"), - cls._safeSteamWindowCall(classGroup, "get_res_class"), - ]) - - normalized = { - identifier.strip().casefold() - for identifier in identifiers - if isinstance(identifier, str) - } - return bool(normalized.intersection({"steam", "steamwebhelper"})) - - @staticmethod - def _safeSteamWindowCall(window: Any, attrName: str): - attr = getattr(window, attrName, None) - if not callable(attr): - return None - - try: - return attr() - except Exception: - return None - - @staticmethod - def _isSteamGameWindowIdentifier(identifier) -> bool: - if not isinstance(identifier, str): - return False - return identifier.strip().casefold().startswith("steam_app_") - - def _isDuplicateSteamOverlaySelection(self, text: str) -> bool: - lastText, lastTime = getattr(self, "_lastSteamOverlaySelection", ("", 0.0)) - now = time.monotonic() - if text == lastText and now - lastTime < 0.75: - return True - - self._lastSteamOverlaySelection = (text, now) - return False - - def _isSteamLoadingSpinnerCaretEvent(self, event) -> bool: - if not (event and event.type.startswith("object:text-caret-moved")): - return False - - source = getattr(event, "source", None) - if not source or not self.utilities.inDocumentContent(source): - return False - - if AXObject.get_name(source): - return False - - try: - children = list(AXObject.iter_children(source)) - except Exception: - return False - - if not children: - return False - - for child in children: - if not AXUtilities.is_image_or_canvas(child): - continue - name = AXObject.get_name(child) or "" - if name.strip().casefold() == "steam spinner": - return True - - return False - - def _trySteamButtonActivation(self, keyboardEvent) -> bool: - if keyboardEvent.event_string not in ["Return", "KP_Enter"]: - return False - - if not keyboardEvent.is_pressed_key(): - return False - - if getattr(keyboardEvent, "modifiers", 0): - return False - - friendsPanelTarget = self._getSteamFriendsPanelActivationTarget() - obj = friendsPanelTarget or self._getClickableActivationTarget() - if not obj: - return False - - try: - if not self.utilities.inDocumentContent(obj): - return False - except Exception: - return False - - if not (AXUtilities.is_button(obj) or AXUtilities.is_push_button(obj)): - return False - - if not any( - AXObject.has_action(obj, actionName) - for actionName in ["press", "click", "click-ancestor", "activate", "open", "jump"] - ): - return False - - if self._performClickableAction(obj): - self._logSteamFriendsPanelActivation(friendsPanelTarget) - return True - - from cthulhu import ax_event_synthesizer - result = ax_event_synthesizer.AXEventSynthesizer.click_object(obj) - if result: - self._logSteamFriendsPanelActivation(friendsPanelTarget) - self._restoreFocusAfterClick(obj) - return True - - return False - - def _logSteamFriendsPanelActivation(self, obj: Any) -> None: - if obj is None: - return - - target, text, _timestamp = getattr( - self, - "_steamFriendsPanelActivationTarget", - (None, "", 0.0), - ) - if obj is not target or not text: - return - - msg = f"STEAM: Activated Friends panel item: {text}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _isSteamNotification(self, obj): - """Detect if object is a Steam notification. - - Arguments: - - obj: the accessible object to check - - Returns True if obj appears to be a notification element. - """ - if obj is None: - return False - - # Check for NOTIFICATION or ALERT roles - if AXUtilities.is_notification(obj) or AXUtilities.is_alert(obj): - msg = "STEAM: Found notification/alert role" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - # Check for live region with assertive/polite politeness - # (Steam may use ARIA live regions for toasts) - liveAttr = AXObject.get_attribute(obj, 'live') - containerLive = AXObject.get_attribute(obj, 'container-live') - if liveAttr in ['assertive', 'polite'] or containerLive in ['assertive', 'polite']: - politeness = liveAttr or containerLive - msg = f"STEAM: Found live region with politeness: {politeness}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - def isNotificationCandidate(candidate): - if AXUtilities.is_notification(candidate) or AXUtilities.is_alert(candidate): - return True - candidateLive = AXObject.get_attribute(candidate, 'live') - candidateContainerLive = AXObject.get_attribute(candidate, 'container-live') - return candidateLive in ['assertive', 'polite'] or candidateContainerLive in ['assertive', 'polite'] - - ancestor = AXObject.find_ancestor(obj, isNotificationCandidate) - if ancestor: - msg = "STEAM: Found notification ancestor" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def _findSteamNotificationRoot(self, obj): - if obj is None: - return None - - if AXUtilities.is_notification(obj) or AXUtilities.is_alert(obj): - return obj - - def isNotificationRole(candidate): - return AXUtilities.is_notification(candidate) or AXUtilities.is_alert(candidate) - - ancestorNotification = AXObject.find_ancestor(obj, isNotificationRole) - if ancestorNotification: - return ancestorNotification - - liveAttr = AXObject.get_attribute(obj, 'live') - containerLive = AXObject.get_attribute(obj, 'container-live') - if liveAttr in ['assertive', 'polite'] or containerLive in ['assertive', 'polite']: - return obj - - def isLiveRegionCandidate(candidate): - candidateLive = AXObject.get_attribute(candidate, 'live') - candidateContainerLive = AXObject.get_attribute(candidate, 'container-live') - return candidateLive in ['assertive', 'polite'] or candidateContainerLive in ['assertive', 'polite'] - - return AXObject.find_ancestor(obj, isLiveRegionCandidate) - - def _presentSteamNotification(self, obj): - """Speak and save the notification. - - Arguments: - - obj: the notification accessible object - """ - text = self._getNotificationText(obj) - if not text: - msg = "STEAM: Notification had no text content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - self._presentSteamNotificationText(text, obj) - - def _logSteamNavigationEvent(self, label, event): - if not event: - return - - sourceInfo = self._describeSteamObject(event.source) - anyDataInfo = self._describeSteamEventAnyData(event.any_data) - msg = f"STEAM: {label}: source={sourceInfo}; any_data={anyDataInfo}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _describeSteamEventAnyData(self, anyData): - if isinstance(anyData, str): - text = self._normalizeSteamNotificationText(anyData) - if not text: - return "string('')" - return f"string('{text}')" - if anyData is None: - return "None" - if isinstance(anyData, (bool, int, float)): - return repr(anyData) - return self._describeSteamObject(anyData) - - def _describeSteamObject(self, obj): - if obj is None: - return "None" - - try: - name = AXObject.get_name(obj) or "" - description = AXObject.get_description(obj) or "" - roleName = AXObject.get_role_name(obj) or "" - text = self.utilities.displayedText(obj) or "" - path = AXObject.get_path(obj) - - name = self._normalizeSteamNotificationText(name) - description = self._normalizeSteamNotificationText(description) - text = self._normalizeSteamNotificationText(text) - - return ( - f"role='{roleName}' " - f"name='{name}' " - f"description='{description}' " - f"text='{text}' " - f"path={path}" - ) - except Exception as error: - return ( - f"uninspectable(type={type(obj).__name__}, " - f"value={obj!r}, error={error})" - ) - - def _presentSteamLiveRegionText(self, event): - if not isinstance(event.any_data, str): - return False - - text = event.any_data.strip() - if not text: - return False - - if not self._isSteamLiveRegion(event.source): - return False - - notificationRoot = self._findSteamNotificationRoot(event.source) - sourceObj = notificationRoot or event.source - if notificationRoot: - fullText = self._getNotificationText(notificationRoot) - if fullText: - text = fullText - - msg = f"STEAM: Live region text inserted: {text}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._presentSteamNotificationText(text, sourceObj) - return True - - def _isSteamLiveRegion(self, obj): - if not obj: - return False - - liveAttr = AXObject.get_attribute(obj, 'live') - containerLive = AXObject.get_attribute(obj, 'container-live') - if liveAttr in ['assertive', 'polite'] or containerLive in ['assertive', 'polite']: - return True - - def isLiveRegion(candidate): - candidateLive = AXObject.get_attribute(candidate, 'live') - candidateContainerLive = AXObject.get_attribute(candidate, 'container-live') - return candidateLive in ['assertive', 'polite'] \ - or candidateContainerLive in ['assertive', 'polite'] - - return AXObject.find_ancestor(obj, isLiveRegion) is not None - - def _presentSteamNotificationText(self, text, obj): - self._queueSteamNotification(text, obj) - - def _isDuplicateSteamNotification(self, text): - lastText, lastTime = self._lastSteamNotification - now = time.monotonic() - if text == lastText and (now - lastTime) < 1.0: - return True - - self._lastSteamNotification = (text, now) - return False - - def _presentSteamNotificationTextNow(self, text, obj): - if self._isDuplicateSteamNotification(text): - msg = "STEAM: Suppressing duplicate notification" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - notificationMsg = f"Steam: {text}" - - # Speak the notification - voice = self.speechGenerator.voice(obj=obj, string=notificationMsg) - self.speakMessage(notificationMsg, voice=voice) - - # Display on braille - self.displayBrailleMessage(notificationMsg, flashTime=settings.brailleFlashTime) - - # Save to notification history - self.notificationPresenter.save_notification(notificationMsg) - - msg = f"STEAM: Presented notification: {text}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _normalizeSteamNotificationText(self, text): - if not text: - return "" - return " ".join(text.split()) - - def _isSteamRelativeTimestamp(self, text): - text = self._normalizeSteamNotificationText(text) - if not text: - return False - return self._steamRelativeTimePattern.match(text) is not None - - def _appendSteamTimestamp(self, baseText, timestampText): - if not baseText: - return timestampText - if baseText[-1] in ".!?": - return f"{baseText} {timestampText}" - return f"{baseText}. {timestampText}" - - def _getSteamNotificationIdentity(self, obj): - if obj is None: - return None - - try: - path = AXObject.get_path(obj) - except Exception: - path = None - - if path is not None: - return tuple(path) - - try: - return hash(obj) - except TypeError: - return id(obj) - - def _combineSteamNotificationFragments(self, firstText, secondText): - combined = f"{firstText} {secondText}" - return self._normalizeSteamNotificationText(combined) - - def _steamTextContains(self, text, other): - textNorm = self._normalizeSteamNotificationText(text).lower() - otherNorm = self._normalizeSteamNotificationText(other).lower() - if not textNorm or not otherNorm: - return False - if len(otherNorm) < 4: - return textNorm == otherNorm - return otherNorm in textNorm - - def _queueSteamNotification(self, text, obj): - text = self._normalizeSteamNotificationText(text) - if not text: - return - sourceKey = self._getSteamNotificationIdentity(obj) - - pending = self._steamPendingNotification - if self._isSteamRelativeTimestamp(text): - if pending: - if pending.get("timestampOnly"): - pending["text"] = text - else: - pending["text"] = self._appendSteamTimestamp(pending["text"], text) - if obj: - pending["obj"] = obj - pending["sourceKey"] = sourceKey - self._resetSteamPendingTimer() - return - - self._steamPendingNotification = { - "text": text, - "obj": obj, - "timerId": None, - "timestampOnly": True, - "sourceKey": sourceKey - } - self._resetSteamPendingTimer() - return - - if pending: - pendingText = pending["text"] - if pending.get("timestampOnly"): - pending["text"] = self._appendSteamTimestamp(text, pendingText) - pending["timestampOnly"] = False - if obj: - pending["obj"] = obj - pending["sourceKey"] = sourceKey - self._resetSteamPendingTimer() - return - - if text == pendingText: - if obj: - pending["obj"] = obj - pending["sourceKey"] = sourceKey - return - - if self._steamTextContains(text, pendingText): - pending["text"] = text - if obj: - pending["obj"] = obj - pending["sourceKey"] = sourceKey - self._resetSteamPendingTimer() - return - - if self._steamTextContains(pendingText, text): - if obj: - pending["obj"] = obj - pending["sourceKey"] = sourceKey - return - - # Steam often emits multi-line toasts as separate live-region fragments. - # Keep fragments from the same toast together instead of speaking the first - # line immediately and the complete toast later. - if sourceKey is not None and sourceKey == pending.get("sourceKey"): - pending["text"] = self._combineSteamNotificationFragments(pendingText, text) - if obj: - pending["obj"] = obj - pending["sourceKey"] = sourceKey - self._resetSteamPendingTimer() - return - - self._flushSteamPendingNotification(fromTimer=False) - - self._steamPendingNotification = { - "text": text, - "obj": obj, - "timerId": None, - "timestampOnly": False, - "sourceKey": sourceKey - } - self._resetSteamPendingTimer() - - def _resetSteamPendingTimer(self): - pending = self._steamPendingNotification - if not pending: - return - timerId = pending.get("timerId") - if timerId is not None: - GLib.source_remove(timerId) - pending["timerId"] = GLib.timeout_add( - self._steamNotificationDelayMs, - self._onSteamPendingTimeout - ) - - def _onSteamPendingTimeout(self): - self._flushSteamPendingNotification(fromTimer=True) - return False - - def _flushSteamPendingNotification(self, fromTimer): - pending = self._steamPendingNotification - if not pending: - return - timerId = pending.get("timerId") - if not fromTimer and timerId is not None: - GLib.source_remove(timerId) - self._steamPendingNotification = None - if pending.get("timestampOnly"): - msg = "STEAM: Dropping timestamp-only notification" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - self._presentSteamNotificationTextNow(pending["text"], pending["obj"]) - - def _getNotificationText(self, obj): - """Extract text from notification element. - - Arguments: - - obj: the notification accessible object - - Returns the text content of the notification, or empty string if none found. - """ - def getText(candidate): - name = AXObject.get_name(candidate) - if name: - return name - return self.utilities.displayedText(candidate) - - # Try getting name directly - text = getText(obj) - if text: - return text - - # Try getting all text from labels/text elements - texts = [] - for label in AXUtilities.find_all_labels(obj): - text = getText(label) - if text: - texts.append(text) - - if texts: - return ' '.join(texts) - - def isNamedButton(candidate): - if not AXUtilitiesRole.is_button(candidate): - return False - return bool(getText(candidate)) - - descendantButton = AXObject.find_descendant(obj, isNamedButton) - if descendantButton: - return getText(descendantButton) - - ancestorButton = AXObject.find_ancestor(obj, isNamedButton) - if ancestorButton: - return getText(ancestorButton) - - def hasReadableText(candidate): - return bool(getText(candidate)) - - descendantText = AXObject.find_descendant(obj, hasReadableText) - if descendantText: - return getText(descendantText) - - # Fall back to displayed text of the object itself - return "" diff --git a/src/cthulhu/scripts/apps/steamwebhelper/script_utilities.py b/src/cthulhu/scripts/apps/steamwebhelper/script_utilities.py deleted file mode 100644 index cfba0c8..0000000 --- a/src/cthulhu/scripts/apps/steamwebhelper/script_utilities.py +++ /dev/null @@ -1,240 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Steam-specific utility helpers.""" - -from __future__ import annotations - -from typing import Optional - -from cthulhu import debug -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities -from cthulhu.scripts.toolkits.Chromium.script_utilities import Utilities as ChromiumUtilities - - -class Utilities(ChromiumUtilities): - def __init__(self, script) -> None: - super().__init__(script) - self._steamInferredButtonLabels: dict[int, str] = {} - - def clearCachedObjects(self) -> None: - super().clearCachedObjects() - self._steamInferredButtonLabels = {} - - def clearSteamVirtualizedListCaches(self) -> None: - self.clearContentCache() - self._steamInferredButtonLabels = {} - self._isUselessImage = {} - self._shouldFilter = {} - - def isSteamVirtualizedList(self, obj) -> bool: - if not (obj and self.inDocumentContent(obj)): - return False - - if not AXUtilities.is_list(obj): - return False - - className = AXObject.get_attribute(obj, "class") or "" - return "ReactVirtualized__Grid__innerScrollContainer" in className - - def displayedLabel(self, obj): - label = super().displayedLabel(obj) - if label or not self._shouldInferSteamButtonLabel(obj): - return label - - inferredLabel = self._getSteamInferredButtonLabel(obj) - if inferredLabel: - self._displayedLabelText[hash(obj)] = inferredLabel - return inferredLabel - - def displayedText(self, obj): - text = super().displayedText(obj) - if text or not self._shouldInferSteamButtonLabel(obj): - return text - - inferredLabel = self._getSteamInferredButtonLabel(obj) - if inferredLabel: - cache = self._script.generatorCache.setdefault(self.DISPLAYED_TEXT, {}) - cache[obj] = inferredLabel - return inferredLabel - - def isUselessImage(self, obj) -> bool: - if not (obj and self.inDocumentContent(obj)): - return super().isUselessImage(obj) - - cached = self._isUselessImage.get(hash(obj)) - if cached is not None: - return cached - - rv = super().isUselessImage(obj) - if not rv: - rv = self._isRedundantSteamImage(obj) - - self._isUselessImage[hash(obj)] = rv - return rv - - def _shouldInferSteamButtonLabel(self, obj) -> bool: - if not (obj and self.inDocumentContent(obj)): - return False - - if AXObject.get_name(obj): - return False - - if not (AXUtilities.is_button(obj) or AXUtilities.is_push_button(obj)): - return False - - className = AXObject.get_attribute(obj, "class") or "" - return "FriendsListTab" in className or "AddFriendButton" in className - - def _getSteamInferredButtonLabel(self, obj) -> str: - cached = self._steamInferredButtonLabels.get(hash(obj)) - if cached is not None: - return cached - - className = AXObject.get_attribute(obj, "class") or "" - inferredLabel = self._getSteamButtonLabelFromClass(className) - if not inferredLabel: - inferredLabel = self._getSteamNearbyButtonLabel(obj) - - inferredLabel = inferredLabel or "" - self._steamInferredButtonLabels[hash(obj)] = inferredLabel - if inferredLabel: - tokens = ["STEAM: Inferred label for", obj, ":", inferredLabel] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return inferredLabel - - @staticmethod - def _getSteamButtonLabelFromClass(className: str) -> str: - if "AddFriendButton" in className: - return "Add Friend" - return "" - - def _isRedundantSteamImage(self, obj) -> bool: - if not AXUtilities.is_image_or_canvas(obj): - return False - - if AXObject.get_name(obj) or AXObject.get_description(obj): - return False - - if AXObject.get_child_count(obj): - return False - - if AXUtilities.is_focusable(obj): - return False - - if not AXObject.has_action(obj, "click-ancestor"): - return False - - roleDescription = self._normalizeSteamLabelText(AXObject.get_role_description(obj) or "") - if roleDescription and roleDescription.casefold() not in ["unlabeled image", "image"]: - return False - - nearbyLabel = self._getSteamNearbyImageLabel(obj) - if not self._isUsefulSteamLabel(nearbyLabel): - return False - - tokens = ["STEAM: Treating redundant image as useless:", obj, "(label:", nearbyLabel, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - def _getSteamNearbyButtonLabel(self, obj) -> str: - parent = AXObject.get_parent(obj) - if parent is None: - return "" - - siblingLabel = self._getSteamLabelFromChildren(parent, ignore=obj) - if siblingLabel: - return siblingLabel - - parentLabel = self._getSteamReadableText(parent) - if self._isUsefulSteamLabel(parentLabel): - return parentLabel - - grandParent = AXObject.get_parent(parent) - if grandParent is None: - return "" - - return self._getSteamLabelFromChildren(grandParent, ignore=parent) - - def _getSteamNearbyImageLabel(self, obj) -> str: - parent = AXObject.get_parent(obj) - if parent is None: - return "" - - siblingLabel = self._getSteamLabelFromChildren(parent, ignore=obj) - if siblingLabel: - return siblingLabel - - parentLabel = self._getSteamReadableText(parent) - if self._isUsefulSteamLabel(parentLabel): - return parentLabel - - grandParent = AXObject.get_parent(parent) - if grandParent is None: - return "" - - return self._getSteamLabelFromChildren(grandParent, ignore=parent) - - def _getSteamLabelFromChildren(self, obj, ignore=None) -> str: - for child in AXObject.iter_children(obj): - if child == ignore: - continue - if AXUtilities.is_button(child) or AXUtilities.is_push_button(child): - continue - - label = self._getSteamReadableText(child) - if self._isUsefulSteamLabel(label): - return label - - return "" - - def _getSteamReadableText(self, obj) -> str: - if obj is None: - return "" - - name = self._normalizeSteamLabelText(AXObject.get_name(obj) or "") - if self._isUsefulSteamLabel(name): - return name - - if not AXObject.supports_text(obj): - return "" - - text = AXText.get_all_text(obj) or "" - text = text.replace(self.EMBEDDED_OBJECT_CHARACTER, " ") - text = self._normalizeSteamLabelText(text) - if self._isUsefulSteamLabel(text): - return text - - return "" - - @staticmethod - def _normalizeSteamLabelText(text: str) -> str: - return " ".join(text.split()) - - @staticmethod - def _isUsefulSteamLabel(text: Optional[str]) -> bool: - if not text: - return False - - return not text.isdigit() and text.casefold() != "unlabeled image" diff --git a/src/cthulhu/scripts/apps/xfwm4/__init__.py b/src/cthulhu/scripts/apps/xfwm4/__init__.py deleted file mode 100644 index a2a1c8a..0000000 --- a/src/cthulhu/scripts/apps/xfwm4/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for xfwm4.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script - diff --git a/src/cthulhu/scripts/apps/xfwm4/meson.build b/src/cthulhu/scripts/apps/xfwm4/meson.build deleted file mode 100644 index 468dca7..0000000 --- a/src/cthulhu/scripts/apps/xfwm4/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -xfwm4_python_sources = files([ - '__init__.py', - 'script.py', -]) - -python3.install_sources( - xfwm4_python_sources, - subdir: 'cthulhu/scripts/apps/xfwm4' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/apps/xfwm4/script.py b/src/cthulhu/scripts/apps/xfwm4/script.py deleted file mode 100644 index 98ffc95..0000000 --- a/src/cthulhu/scripts/apps/xfwm4/script.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for xfwm4.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2011 The Cthulhu Team." -__license__ = "LGPL" - -import cthulhu.scripts.default as default -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -######################################################################## -# # -# The xfwm4 script class. # -# # -######################################################################## - -class Script(default.Script): - - def __init__(self, app): - """Creates a new script for the given application. - - Arguments: - - app: the application to create a script for. - """ - - default.Script.__init__(self, app) - - def onTextInserted(self, event): - """Called whenever text is inserted into an object. Overridden - here so that we will speak each item as the user is switching - windows. - - Arguments: - - event: the Event - """ - - if not AXUtilities.is_label(event.source): - default.Script.onTextInserted(self, event) - return - - self.presentMessage(AXObject.get_name(event.source)) - - def onTextDeleted(self, event): - """Called whenever text is deleted from an object. Overridden - here because we wish to ignore text deletion events associated - with window switching. - - Arguments: - - event: the Event - """ - - if not AXUtilities.is_label(event.source): - default.Script.onTextDeleted(self, event) diff --git a/src/cthulhu/scripts/default.py b/src/cthulhu/scripts/default.py deleted file mode 100644 index 2cf258f..0000000 --- a/src/cthulhu/scripts/default.py +++ /dev/null @@ -1,4050 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""The default Script for presenting information to the user using -both speech and Braille. This is based primarily on the de-facto -standard implementation of the AT-SPI, which is the GAIL support -for GTK.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010 Joanmarie Diggs" -__license__ = "LGPL" - -import gi -gi.require_version('Atspi', '2.0') -gi.require_version('Gdk', '3.0') -from gi.repository import Atspi -from gi.repository import Gdk -from gi.repository import GLib - -import re -import time - -import cthulhu.acss as acss -import cthulhu.braille as braille -import cthulhu.cmdnames as cmdnames -import cthulhu.dbus_service as dbus_service -import cthulhu.debug as debug -import cthulhu.find as find -import cthulhu.flat_review as flat_review -import cthulhu.input_event as input_event -import cthulhu.input_event_manager as input_event_manager -import cthulhu.keybindings as keybindings -import cthulhu.messages as messages -from cthulhu import cthulhu -import cthulhu.cthulhu_modifier_manager as cthulhu_modifier_manager -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.phonnames as phonnames -import cthulhu.script as script -import cthulhu.script_manager as script_manager -import cthulhu.settings as settings -import cthulhu.settings_manager as settings_manager -import cthulhu.sound as sound -import cthulhu.speech as speech -import cthulhu.speechserver as speechserver -import cthulhu.wnck_support as wnck_support -from cthulhu.ax_object import AXObject -from cthulhu.ax_value import AXValue -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_relation import AXUtilitiesRelation - -_scriptManager = None # Removed - use cthulhu.cthulhuApp.scriptManager -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -######################################################################## -# # -# The Default script class. # -# # -######################################################################## - -class Script(script.Script): - - EMBEDDED_OBJECT_CHARACTER = '\ufffc' - NO_BREAK_SPACE_CHARACTER = '\u00a0' - KEYBOARD_CLIPBOARD_CHECK_DELAY_MS = 100 - KEYBOARD_CLIPBOARD_MAX_CHECKS = 10 - KEYBOARD_CLIPBOARD_RELEASE_MAX_AGE_S = 1.0 - - # generatorCache - # - DISPLAYED_LABEL = 'displayedLabel' - DISPLAYED_TEXT = 'displayedText' - KEY_BINDING = 'keyBinding' - NESTING_LEVEL = 'nestingLevel' - NODE_LEVEL = 'nodeLevel' - REAL_ACTIVE_DESCENDANT = 'realActiveDescendant' - - def __init__(self, app): - """Creates a new script for the given application. - - Arguments: - - app: the application to create a script for. - """ - script.Script.__init__(self, app) - - self.targetCursorCell = None - - self.justEnteredFlatReviewMode = False - - self.digits = '0123456789' - self.whitespace = ' \t\n\r\v\f' - - # A dictionary of non-standardly-named text attributes and their - # Atk equivalents. - # - self.attributeNamesDict = {} - - # Keep track of the last time we issued a mouse routing command - # so that we can guess if a change resulted from our moving the - # pointer. - # - self.lastMouseRoutingTime = None - - # The last location of the mouse, which we might want if routing - # the pointer elsewhere. - # - self.oldMouseCoordinates = [0, 0] - - self._lastWordCheckedForSpelling = "" - - self._inSayAll = False - self._sayAllIsInterrupted = False - self._sayAllContexts = [] - self.grab_ids = [] - self._modifierGrabIds = [] - self._pendingKeyboardClipboardCommand = None - self._pendingKeyboardClipboardRelease = None - self._keyboardClipboardCommandGeneration = 0 - self._sessionType = None - - if app: - Atspi.Accessible.set_cache_mask( - app, Atspi.Cache.DEFAULT ^ Atspi.Cache.NAME ^ Atspi.Cache.DESCRIPTION) - - # Register D-Bus commands if available - try: - controller = dbus_service.get_remote_controller() - if controller: - tokens = ["DEFAULT: Registering D-Bus commands for default script"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - controller.register_decorated_module("DefaultScript", self) - except Exception as error: - tokens = ["DEFAULT: Exception registering D-Bus commands:", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for this script that can be - called by the key and braille bindings.""" - - self.inputEventHandlers["routePointerToItemHandler"] = \ - input_event.InputEventHandler( - Script.routePointerToItem, - cmdnames.ROUTE_POINTER_TO_ITEM) - - self.inputEventHandlers["leftClickReviewItemHandler"] = \ - input_event.InputEventHandler( - Script.leftClickReviewItem, - cmdnames.LEFT_CLICK_REVIEW_ITEM) - - self.inputEventHandlers["rightClickReviewItemHandler"] = \ - input_event.InputEventHandler( - Script.rightClickReviewItem, - cmdnames.RIGHT_CLICK_REVIEW_ITEM) - - self.inputEventHandlers["sayAllHandler"] = \ - input_event.InputEventHandler( - Script.sayAll, - cmdnames.SAY_ALL) - - self.inputEventHandlers["findHandler"] = \ - input_event.InputEventHandler( - cthulhu.showFindGUI, - cmdnames.SHOW_FIND_GUI) - - self.inputEventHandlers["findNextHandler"] = \ - input_event.InputEventHandler( - Script.findNext, - cmdnames.FIND_NEXT) - - self.inputEventHandlers["findPreviousHandler"] = \ - input_event.InputEventHandler( - Script.findPrevious, - cmdnames.FIND_PREVIOUS) - - self.inputEventHandlers["panBrailleLeftHandler"] = \ - input_event.InputEventHandler( - Script.panBrailleLeft, - cmdnames.PAN_BRAILLE_LEFT, - False) # Do not enable learn mode for this action - - self.inputEventHandlers["panBrailleRightHandler"] = \ - input_event.InputEventHandler( - Script.panBrailleRight, - cmdnames.PAN_BRAILLE_RIGHT, - False) # Do not enable learn mode for this action - - self.inputEventHandlers["goBrailleHomeHandler"] = \ - input_event.InputEventHandler( - Script.goBrailleHome, - cmdnames.GO_BRAILLE_HOME) - - self.inputEventHandlers["contractedBrailleHandler"] = \ - input_event.InputEventHandler( - Script.setContractedBraille, - cmdnames.SET_CONTRACTED_BRAILLE) - - self.inputEventHandlers["processRoutingKeyHandler"] = \ - input_event.InputEventHandler( - Script.processRoutingKey, - cmdnames.PROCESS_ROUTING_KEY) - - self.inputEventHandlers["processBrailleCutBeginHandler"] = \ - input_event.InputEventHandler( - Script.processBrailleCutBegin, - cmdnames.PROCESS_BRAILLE_CUT_BEGIN) - - self.inputEventHandlers["processBrailleCutLineHandler"] = \ - input_event.InputEventHandler( - Script.processBrailleCutLine, - cmdnames.PROCESS_BRAILLE_CUT_LINE) - - self.inputEventHandlers["toggleSleepModeHandler"] = \ - input_event.InputEventHandler( - Script.toggleSleepMode, - cmdnames.TOGGLE_SLEEP_MODE) - - self.inputEventHandlers["shutdownHandler"] = \ - input_event.InputEventHandler( - cthulhu.quitCthulhu, - cmdnames.QUIT_CTHULHU) - - self.inputEventHandlers["preferencesSettingsHandler"] = \ - input_event.InputEventHandler( - cthulhu.showPreferencesGUI, - cmdnames.SHOW_PREFERENCES_GUI) - - self.inputEventHandlers["appPreferencesSettingsHandler"] = \ - input_event.InputEventHandler( - cthulhu.showAppPreferencesGUI, - cmdnames.SHOW_APP_PREFERENCES_GUI) - - self.inputEventHandlers["cycleSettingsProfileHandler"] = \ - input_event.InputEventHandler( - Script.cycleSettingsProfile, - cmdnames.CYCLE_SETTINGS_PROFILE) - - self.inputEventHandlers["cycleDebugLevelHandler"] = \ - input_event.InputEventHandler( - Script.cycleDebugLevel, - cmdnames.CYCLE_DEBUG_LEVEL) - - self.inputEventHandlers["bypassNextCommandHandler"] = \ - input_event.InputEventHandler( - Script.bypassNextCommand, - cmdnames.BYPASS_NEXT_COMMAND) - - self.inputEventHandlers.update(self.notificationPresenter.get_handlers()) - self.inputEventHandlers.update(self.flatReviewPresenter.get_handlers()) - self.inputEventHandlers.update(self.speechAndVerbosityManager.get_handlers()) - self.inputEventHandlers.update(self.dateAndTimePresenter.get_handlers()) - self.inputEventHandlers.update(self.bookmarks.get_handlers()) - self.inputEventHandlers.update(self.objectNavigator.get_handlers()) - self.inputEventHandlers.update(self.whereAmIPresenter.get_handlers()) - self.inputEventHandlers.update(self.learnModePresenter.get_handlers()) - self.inputEventHandlers.update(self.mouseReviewer.get_handlers()) - self.inputEventHandlers.update(self.actionPresenter.get_handlers()) - cthulhu.getManager().getDynamicApiManager().registerAPI('inputEventHandlers',self.inputEventHandlers, overwrite=True) - cthulhu.getManager().getSignalManager().emitSignal('setup-inputeventhandlers-completed') - - def getInputEventHandlerKey(self, inputEventHandler): - """Returns the name of the key that contains an inputEventHadler - passed as argument - """ - - for keyName, handler in self.inputEventHandlers.items(): - if handler == inputEventHandler: - return keyName - - return None - - def getListeners(self): - """Sets up the AT-SPI event listeners for this script. - """ - listeners = script.Script.getListeners(self) - listeners["focus:"] = \ - self.onFocus - #listeners["keyboard:modifiers"] = \ - # self.noOp - listeners["document:reload"] = \ - self.onDocumentReload - listeners["document:load-complete"] = \ - self.onDocumentLoadComplete - listeners["document:load-stopped"] = \ - self.onDocumentLoadStopped - listeners["mouse:button"] = \ - self.onMouseButton - listeners["object:announcement"] = \ - self.onAnnouncement - listeners["object:property-change:accessible-name"] = \ - self.onNameChanged - listeners["object:property-change:accessible-description"] = \ - self.onDescriptionChanged - listeners["object:text-caret-moved"] = \ - self.onCaretMoved - listeners["object:text-changed:delete"] = \ - self.onTextDeleted - listeners["object:text-changed:insert"] = \ - self.onTextInserted - listeners["object:active-descendant-changed"] = \ - self.onActiveDescendantChanged - listeners["object:children-changed:add"] = \ - self.onChildrenAdded - listeners["object:children-changed:remove"] = \ - self.onChildrenRemoved - listeners["object:state-changed:active"] = \ - self.onActiveChanged - listeners["object:state-changed:busy"] = \ - self.onBusyChanged - listeners["object:state-changed:focused"] = \ - self.onFocusedChanged - listeners["object:state-changed:showing"] = \ - self.onShowingChanged - listeners["object:state-changed:checked"] = \ - self.onCheckedChanged - listeners["object:state-changed:pressed"] = \ - self.onPressedChanged - listeners["object:state-changed:indeterminate"] = \ - self.onIndeterminateChanged - listeners["object:state-changed:expanded"] = \ - self.onExpandedChanged - listeners["object:state-changed:selected"] = \ - self.onSelectedChanged - listeners["object:state-changed:sensitive"] = \ - self.onSensitiveChanged - listeners["object:text-attributes-changed"] = \ - self.onTextAttributesChanged - listeners["object:text-selection-changed"] = \ - self.onTextSelectionChanged - listeners["object:selection-changed"] = \ - self.onSelectionChanged - listeners["object:property-change:accessible-value"] = \ - self.onValueChanged - listeners["object:value-changed"] = \ - self.onValueChanged - listeners["object:column-reordered"] = \ - self.onColumnReordered - listeners["object:row-reordered"] = \ - self.onRowReordered - listeners["window:activate"] = \ - self.onWindowActivated - listeners["window:deactivate"] = \ - self.onWindowDeactivated - listeners["window:create"] = \ - self.onWindowCreated - listeners["window:destroy"] = \ - self.onWindowDestroyed - - return listeners - - def __getDesktopBindings(self): - """Returns an instance of keybindings.KeyBindings that use the - numeric keypad for focus tracking and flat review. - """ - - import cthulhu.desktop_keyboardmap as desktop_keyboardmap - keyBindings = keybindings.KeyBindings() - keyBindings.load(desktop_keyboardmap.keymap, self.inputEventHandlers) - return keyBindings - - def __getLaptopBindings(self): - """Returns an instance of keybindings.KeyBindings that use the - the main keyboard keys for focus tracking and flat review. - """ - - import cthulhu.laptop_keyboardmap as laptop_keyboardmap - keyBindings = keybindings.KeyBindings() - keyBindings.load(laptop_keyboardmap.keymap, self.inputEventHandlers) - return keyBindings - - def getExtensionBindings(self): - keyBindings = keybindings.KeyBindings() - - bindings = self.notificationPresenter.get_bindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - layout = cthulhu.cthulhuApp.settingsManager.getSetting('keyboardLayout') - isDesktop = layout == settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP - bindings = self.flatReviewPresenter.get_bindings(isDesktop) - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.whereAmIPresenter.get_bindings(isDesktop) - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.learnModePresenter.get_bindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.speechAndVerbosityManager.get_bindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.dateAndTimePresenter.get_bindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.objectNavigator.get_bindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.bookmarks.get_bindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.mouseReviewer.get_bindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.actionPresenter.get_bindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - # Add plugin keybindings from APIHelper storage - try: - if hasattr(cthulhu, 'cthulhuApp') and cthulhu.cthulhuApp: - api_helper = cthulhu.cthulhuApp.getAPIHelper() - if api_helper and hasattr(api_helper, '_gestureBindings'): - for context_name, context_bindings in api_helper._gestureBindings.items(): - for binding in context_bindings: - keyBindings.add(binding) - except Exception as e: - import cthulhu.debug as debug - debug.printMessage(debug.LEVEL_WARNING, f"Failed to add plugin bindings: {e}", True) - - return keyBindings - - def getKeyBindings(self): - """Defines the key bindings for this script. - - Returns an instance of keybindings.KeyBindings. - """ - - keyBindings = script.Script.getKeyBindings(self) - - bindings = self.getDefaultKeyBindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.getToolkitKeyBindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.getAppKeyBindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - bindings = self.getExtensionBindings() - for keyBinding in bindings.keyBindings: - keyBindings.add(keyBinding) - - try: - keyBindings = cthulhu.cthulhuApp.settingsManager.overrideKeyBindings(self, keyBindings) - except Exception as error: - tokens = ["DEFAULT: Exception when overriding keybindings in", self, ":", error] - debug.printTokens(debug.LEVEL_WARNING, tokens, True) - - return keyBindings - - def getDefaultKeyBindings(self): - """Returns the default script's keybindings, i.e. without any of - the toolkit or application specific commands added.""" - - keyBindings = keybindings.KeyBindings() - - layout = cthulhu.cthulhuApp.settingsManager.getSetting('keyboardLayout') - if layout == settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP: - for keyBinding in self.__getDesktopBindings().keyBindings: - keyBindings.add(keyBinding) - else: - for keyBinding in self.__getLaptopBindings().keyBindings: - keyBindings.add(keyBinding) - - import cthulhu.common_keyboardmap as common_keyboardmap - keyBindings.load(common_keyboardmap.keymap, self.inputEventHandlers) - - return keyBindings - - def getBrailleBindings(self): - """Defines the braille bindings for this script. - - Returns a dictionary where the keys are BrlTTY commands and the - values are InputEventHandler instances. - """ - - msg = 'DEFAULT: Getting braille bindings.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - brailleBindings = script.Script.getBrailleBindings(self) - try: - brailleBindings[braille.brlapi.KEY_CMD_HWINLT] = \ - self.inputEventHandlers["panBrailleLeftHandler"] - brailleBindings[braille.brlapi.KEY_CMD_FWINLT] = \ - self.inputEventHandlers["panBrailleLeftHandler"] - brailleBindings[braille.brlapi.KEY_CMD_FWINLTSKIP] = \ - self.inputEventHandlers["panBrailleLeftHandler"] - brailleBindings[braille.brlapi.KEY_CMD_HWINRT] = \ - self.inputEventHandlers["panBrailleRightHandler"] - brailleBindings[braille.brlapi.KEY_CMD_FWINRT] = \ - self.inputEventHandlers["panBrailleRightHandler"] - brailleBindings[braille.brlapi.KEY_CMD_FWINRTSKIP] = \ - self.inputEventHandlers["panBrailleRightHandler"] - brailleBindings[braille.brlapi.KEY_CMD_HOME] = \ - self.inputEventHandlers["goBrailleHomeHandler"] - brailleBindings[braille.brlapi.KEY_CMD_SIXDOTS] = \ - self.inputEventHandlers["contractedBrailleHandler"] - brailleBindings[braille.brlapi.KEY_CMD_ROUTE] = \ - self.inputEventHandlers["processRoutingKeyHandler"] - brailleBindings[braille.brlapi.KEY_CMD_CUTBEGIN] = \ - self.inputEventHandlers["processBrailleCutBeginHandler"] - brailleBindings[braille.brlapi.KEY_CMD_CUTLINE] = \ - self.inputEventHandlers["processBrailleCutLineHandler"] - brailleBindings[braille.brlapi.KEY_CMD_HOME] = \ - self.inputEventHandlers["goBrailleHomeHandler"] - except AttributeError: - tokens = ["DEFAULT: Braille bindings unavailable in", self] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - except Exception as error: - tokens = ["DEFAULT: Exception getting braille bindings in", self, ":", error] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - reviewBindings = self.flatReviewPresenter.get_braille_bindings() - brailleBindings.update(reviewBindings) - - msg = 'DEFAULT: Finished getting braille bindings.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - return brailleBindings - - def deactivate(self): - """Called when this script is deactivated.""" - - self._inSayAll = False - self._sayAllIsInterrupted = False - self.pointOfReference = {} - - self.removeKeyGrabs() - - def getEnabledKeyBindings(self): - """ Returns the key bindings that are currently active. """ - return self.getKeyBindings().getBoundBindings() - - def addKeyGrabs(self): - """ Sets up the key grabs currently needed by this script. """ - if cthulhu_state.device is None: - return - msg = "DEFAULT: adding key grabs" - debug.printMessage(debug.LEVEL_INFO, msg, True) - bound = self.getEnabledKeyBindings() - for b in bound: - for id in cthulhu.addKeyGrab(b): - self.grab_ids.append(id) - self._addModifierGrabs() - - def removeKeyGrabs(self): - """ Removes this script's AT-SPI key grabs. """ - msg = "DEFAULT: removing key grabs" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if cthulhu_state.device is None: - self.grab_ids = [] - self._modifierGrabIds = [] - return - for id in self.grab_ids: - cthulhu.removeKeyGrab(id) - self.grab_ids = [] - self._removeModifierGrabs() - - def _addModifierGrabs(self): - if cthulhu_state.device is None: - return - - if self._modifierGrabIds: - return - - manager = input_event_manager.get_manager() - for modifier in settings.cthulhuModifierKeys: - if modifier not in ["Insert", "KP_Insert"]: - continue - keyval = Gdk.keyval_from_name(modifier) - keycode = keybindings.getKeycode(modifier) - if not keyval or not keycode: - continue - grabId = manager.add_grab_for_modifier(modifier, keyval, keycode) - if grabId != -1: - self._modifierGrabIds.append((modifier, grabId)) - - def _removeModifierGrabs(self): - if not self._modifierGrabIds: - return - - manager = input_event_manager.get_manager() - for modifier, grabId in self._modifierGrabIds: - manager.remove_grab_for_modifier(modifier, grabId) - self._modifierGrabIds = [] - - def refreshKeyGrabs(self): - """ Refreshes the enabled key grabs for this script. """ - # TODO: Should probably avoid removing key grabs and re-adding them. - # Otherwise, a key could conceivably leak through while the script is - # in the process of updating the bindings. - self.removeKeyGrabs() - self.addKeyGrabs() - - def registerEventListeners(self): - super().registerEventListeners() - self.utilities.connectToClipboard() - - def deregisterEventListeners(self): - super().deregisterEventListeners() - self.utilities.disconnectFromClipboard() - - @staticmethod - def _normalizeKeyboardCommandKeyName(keyboardEvent): - for value in [ - getattr(keyboardEvent, "keyval_name", ""), - getattr(keyboardEvent, "event_string", ""), - ]: - keyName = (value or "").lower() - if not keyName: - continue - - if len(keyName) == 1: - codePoint = ord(keyName) - if 1 <= codePoint <= 26: - return chr(ord("a") + codePoint - 1) - return keyName - - if keyName.startswith("0x"): - try: - codePoint = int(keyName, 16) - except ValueError: - continue - if 1 <= codePoint <= 26: - return chr(ord("a") + codePoint - 1) - - return keyName - - return "" - - @staticmethod - def _getKeyboardClipboardCommandType(keyboardEvent): - keyName = Script._normalizeKeyboardCommandKeyName(keyboardEvent) - modifiers = getattr(keyboardEvent, "modifiers", 0) - control = bool(modifiers & 1 << Atspi.ModifierType.CONTROL) - shift = bool(modifiers & 1 << Atspi.ModifierType.SHIFT) - obj = keyboardEvent.get_object() - - if not control: - return None - - if keyName == "c": - if AXUtilities.is_terminal(obj): - return "copy" if shift else None - return None if shift else "copy" - - if keyName == "x": - return None if shift else "cut" - - return None - - def _rememberKeyboardClipboardCommand(self, commandType, sourceObj): - self._keyboardClipboardCommandGeneration += 1 - capturedSelectionText = self._getKeyboardClipboardSelectionText(sourceObj) - expectedContents = self._getKeyboardClipboardExpectedContents(sourceObj) - self._pendingKeyboardClipboardCommand = { - "generation": self._keyboardClipboardCommandGeneration, - "command": commandType, - "source": sourceObj, - "clipboard": self.utilities.getClipboardContents(), - "capturedSelectionText": capturedSelectionText, - "expectedContents": expectedContents, - "callbackSeen": False, - "presented": False, - "checksRemaining": self.KEYBOARD_CLIPBOARD_MAX_CHECKS, - "scheduled": False, - } - tokens = ["DEFAULT: Tracking keyboard clipboard command", commandType, "from", sourceObj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - tokens = [ - "DEFAULT: Captured keyboard clipboard expectations", - self._describeClipboardContents(expectedContents), - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - def _getKeyboardClipboardExpectedContents(self, sourceObj): - expectedContents = [] - - for getter in [self.utilities.allSelectedText, self.utilities.selectedText]: - try: - result = getter(sourceObj) - except Exception: - continue - - if not isinstance(result, tuple) or not result: - continue - - string = result[0] - if string and string not in expectedContents: - expectedContents.append(string) - - try: - name = AXObject.get_name(sourceObj) - except Exception: - name = "" - - if name and name not in expectedContents: - expectedContents.append(name) - - return expectedContents - - def _getKeyboardClipboardSelectionText(self, sourceObj): - for getter in [self.utilities.allSelectedText, self.utilities.selectedText]: - try: - result = getter(sourceObj) - except Exception: - continue - - if not isinstance(result, tuple) or not result: - continue - - string = result[0] - if string: - return string - - return "" - - @staticmethod - def _clipboardContentsMatchExpectedContents(currentContents, expectedContents): - if not currentContents: - return False - - for string in expectedContents or []: - if string and string in currentContents: - return True - - return False - - @staticmethod - def _describeClipboardContents(contents): - if isinstance(contents, (list, tuple)): - return [Script._describeClipboardContents(item) for item in contents] - - if contents is None: - return {"len": 0, "text": ""} - - string = str(contents) - if len(string) > 80: - string = f"{string[:77]}..." - string = string.replace("\n", "\\n") - return {"len": len(str(contents)), "text": string} - - def _clipboardMatchesPendingKeyboardCommand(self, pending, currentContents): - if self._clipboardContentsMatchExpectedContents( - currentContents, pending.get("expectedContents") - ): - tokens = ["DEFAULT: Keyboard clipboard fallback matched captured contents for", - pending.get("source")] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - sourceObj = pending.get("source") - if bool(currentContents) and self.utilities.objectContentsAreInClipboard(sourceObj): - return True - - if sourceObj and self.utilities.isInActiveApp(sourceObj) \ - and bool(currentContents) and self.utilities.objectContentsAreInClipboard(): - tokens = ["DEFAULT: Keyboard clipboard fallback matched locusOfFocus after source", - "mismatch", sourceObj, cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - def _schedulePendingKeyboardClipboardCheck(self): - pending = self._pendingKeyboardClipboardCommand - if not pending or pending.get("scheduled"): - return - - pending["scheduled"] = True - GLib.timeout_add( - self.KEYBOARD_CLIPBOARD_CHECK_DELAY_MS, - self._checkPendingKeyboardClipboardCommand, - pending["generation"], - ) - - def _scheduleImmediateKeyboardClipboardPresentation(self): - pending = self._pendingKeyboardClipboardCommand - if not pending or pending.get("immediateScheduled") or pending.get("presented"): - return - - pending["immediateScheduled"] = True - GLib.idle_add( - self._presentPendingKeyboardClipboardCommandIdle, - pending["generation"], - ) - - def _getSessionType(self): - sessionType = getattr(self, "_sessionType", None) - if sessionType is None: - sessionType = wnck_support.get_session_type() - self._sessionType = sessionType - return sessionType - - def _shouldUseImmediateKeyboardClipboardPolicy(self, pending): - if not pending or self._getSessionType() != "wayland": - return False - - if pending.get("command") not in ["copy", "cut"]: - return False - - if not pending.get("capturedSelectionText") and not pending.get("expectedContents"): - return False - - if pending.get("command") == "cut": - sourceObj = pending.get("source") - if AXUtilities.is_editable(sourceObj): - return False - - return True - - def _rememberKeyboardClipboardRelease(self, commandType): - self._pendingKeyboardClipboardRelease = { - "command": commandType, - "time": time.time(), - } - - def _consumePendingKeyboardClipboardRelease(self, commandType): - pending = getattr(self, "_pendingKeyboardClipboardRelease", None) - self._pendingKeyboardClipboardRelease = None - if not pending or pending.get("command") != commandType: - return False - - return time.time() - pending.get("time", 0.0) <= self.KEYBOARD_CLIPBOARD_RELEASE_MAX_AGE_S - - def _presentPendingKeyboardClipboardCommand(self, pending, reason): - sourceObj = pending.get("source") - if pending.get("command") == "cut": - if AXUtilities.is_editable(sourceObj): - pending["scheduled"] = False - pending["immediateScheduled"] = False - self._pendingKeyboardClipboardCommand = None - return - self.presentMessage(messages.CLIPBOARD_CUT_FULL, messages.CLIPBOARD_CUT_BRIEF) - else: - self.presentMessage(messages.CLIPBOARD_COPIED_FULL, messages.CLIPBOARD_COPIED_BRIEF) - - tokens = ["DEFAULT: Presented keyboard clipboard", reason, "for", pending.get("command")] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - pending["scheduled"] = False - pending["immediateScheduled"] = False - pending["presented"] = True - - def _presentPendingKeyboardClipboardCommandIdle(self, generation): - pending = self._pendingKeyboardClipboardCommand - if not pending or pending.get("generation") != generation: - return False - - if pending.get("presented"): - pending["immediateScheduled"] = False - return False - - self._presentPendingKeyboardClipboardCommand(pending, "immediately") - return False - - def _checkPendingKeyboardClipboardCommand(self, generation): - pending = self._pendingKeyboardClipboardCommand - if not pending or pending.get("generation") != generation: - return False - - if pending.get("presented"): - pending["scheduled"] = False - self._pendingKeyboardClipboardCommand = None - return False - - pending["checksRemaining"] = max(pending.get("checksRemaining", 1) - 1, 0) - currentContents = self.utilities.getClipboardContents() - sourceObj = pending.get("source") - tokens = [ - "DEFAULT: Keyboard clipboard retry snapshot", - { - "command": pending.get("command"), - "source": sourceObj, - "clipboard": self._describeClipboardContents(currentContents), - "expected": self._describeClipboardContents(pending.get("expectedContents")), - "checksRemaining": pending.get("checksRemaining"), - }, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - clipboardMatchesSource = self._clipboardMatchesPendingKeyboardCommand( - pending, currentContents - ) - selectionFallback = False - if not clipboardMatchesSource: - selectionFallback = self._shouldPresentKeyboardClipboardSelectionFallback( - pending, currentContents - ) - if selectionFallback: - msg = "DEFAULT: Keyboard clipboard fallback matched captured selection without clipboard access" - debug.printMessage(debug.LEVEL_INFO, msg, True) - clipboardMatchesSource = True - - if not clipboardMatchesSource: - if pending.get("checksRemaining", 0): - tokens = ["DEFAULT: Keyboard clipboard fallback retrying", pending.get("command"), - "for", sourceObj, "checks remaining", pending.get("checksRemaining")] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - tokens = ["DEFAULT: Keyboard clipboard fallback did not match", sourceObj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - pending["scheduled"] = False - self._pendingKeyboardClipboardCommand = None - return False - - if not selectionFallback and currentContents == pending.get("clipboard"): - if pending.get("command") != "copy": - msg = "DEFAULT: Keyboard clipboard fallback found no clipboard change" - debug.printMessage(debug.LEVEL_INFO, msg, True) - pending["scheduled"] = False - self._pendingKeyboardClipboardCommand = None - return False - - msg = "DEFAULT: Keyboard clipboard fallback matched unchanged clipboard for copy" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if pending.get("command") == "cut": - if AXUtilities.is_editable(sourceObj): - pending["scheduled"] = False - self._pendingKeyboardClipboardCommand = None - return False - self._presentPendingKeyboardClipboardCommand(pending, "fallback") - return False - - @staticmethod - def _shouldPresentKeyboardClipboardSelectionFallback(pending, currentContents): - if pending.get("command") != "copy": - return False - - if currentContents: - return False - - return bool(pending.get("capturedSelectionText")) - - def updateKeyboardEventState(self, keyboardEvent, handler): - super().updateKeyboardEventState(keyboardEvent, handler) - - commandType = self._getKeyboardClipboardCommandType(keyboardEvent) - if not commandType: - return - - if keyboardEvent.is_pressed_key(): - self._rememberKeyboardClipboardCommand(commandType, keyboardEvent.get_object()) - pending = self._pendingKeyboardClipboardCommand - if self._shouldUseImmediateKeyboardClipboardPolicy(pending): - self._consumePendingKeyboardClipboardRelease(commandType) - msg = "DEFAULT: Scheduling keyboard clipboard immediate presentation on press" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._scheduleImmediateKeyboardClipboardPresentation() - return - - if self._consumePendingKeyboardClipboardRelease(commandType): - if self._shouldUseImmediateKeyboardClipboardPolicy(pending): - msg = "DEFAULT: Scheduling keyboard clipboard immediate presentation after out-of-order release" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._scheduleImmediateKeyboardClipboardPresentation() - else: - msg = "DEFAULT: Scheduling keyboard clipboard fallback after out-of-order release" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._schedulePendingKeyboardClipboardCheck() - return - - pending = self._pendingKeyboardClipboardCommand - if self._getSessionType() == "wayland": - if pending is None: - return - - if pending.get("command") == commandType and pending.get("immediateScheduled"): - msg = "DEFAULT: Ignoring keyboard clipboard release while immediate presentation is pending" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if pending.get("command") == commandType and pending.get("presented"): - msg = "DEFAULT: Ignoring keyboard clipboard release after immediate presentation" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._pendingKeyboardClipboardCommand = None - return - - if not pending or pending.get("command") != commandType: - self._rememberKeyboardClipboardRelease(commandType) - return - - if self._shouldUseImmediateKeyboardClipboardPolicy(pending): - msg = "DEFAULT: Scheduling keyboard clipboard immediate presentation" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._scheduleImmediateKeyboardClipboardPresentation() - return - - self._schedulePendingKeyboardClipboardCheck() - - def _saveFocusedObjectInfo(self, obj): - """Saves some basic information about obj. Note that this method is - intended to be called primarily (if not only) by locus_of_focus_changed(). - It is expected that accessible event callbacks will update the point - of reference data specific to that event. The goal here is to weed - out duplicate events.""" - - if not obj: - return - - # We want to save the name because some apps and toolkits emit name - # changes after the focus or selection has changed, even though the - # name has not. - name = AXObject.get_name(obj) - names = self.pointOfReference.get('names', {}) - names[hash(obj)] = name - if cthulhu_state.activeWindow: - names[hash(cthulhu_state.activeWindow)] = AXObject.get_name(cthulhu_state.activeWindow) - self.pointOfReference['names'] = names - - descriptions = self.pointOfReference.get('descriptions', {}) - descriptions[hash(obj)] = AXObject.get_description(obj) - self.pointOfReference['descriptions'] = descriptions - - # We want to save the offset for text objects because some apps and - # toolkits emit caret-moved events immediately after a text object - # gains focus, even though the caret has not actually moved. - if AXObject.supports_text(obj): - caretOffset = AXText.get_caret_offset(obj) - if caretOffset >= 0: - self._saveLastCursorPosition(obj, max(0, caretOffset)) - self.utilities.updateCachedTextSelection(obj) - - # We want to save the current row and column of a newly focused - # or selected table cell so that on subsequent cell focus/selection - # we only present the changed location. - row, column = self.utilities.coordinatesForCell(obj, findCellAncestor=True) - self.pointOfReference['lastColumn'] = column - self.pointOfReference['lastRow'] = row - - self.pointOfReference['checkedChange'] = hash(obj), AXUtilities.is_checked(obj) - self.pointOfReference['selectedChange'] = hash(obj), AXUtilities.is_selected(obj) - self.pointOfReference['expandedChange'] = hash(obj), AXUtilities.is_expanded(obj) - - def locus_of_focus_changed(self, event, oldLocusOfFocus, newLocusOfFocus): - """Called when the visual object with focus changes. - - Arguments: - - event: if not None, the Event that caused the change - - oldLocusOfFocus: Accessible that is the old locus of focus - - newLocusOfFocus: Accessible that is the new locus of focus - """ - - self.utilities.presentFocusChangeReason() - - if not newLocusOfFocus: - cthulhu_state.noFocusTimeStamp = time.time() - return - - if AXUtilities.is_defunct(newLocusOfFocus): - return - - if oldLocusOfFocus == newLocusOfFocus: - msg = 'DEFAULT: old focus == new focus' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - # Don't apply the is-same-object heuristic in the case of table cells. - # One scenario is email client message lists. When you delete a message - # and land on the next one, the cells likely occupy the same space, - # have the same role, and might even have the same name, same path, etc. - if not AXUtilities.is_table_cell(oldLocusOfFocus) \ - and not AXUtilities.is_table_cell(newLocusOfFocus) \ - and self.utilities.isSameObject(oldLocusOfFocus, newLocusOfFocus): - tokens = ["DEFAULT: old focus", oldLocusOfFocus, - "believed to be same as new focus", newLocusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - try: - if self.findCommandRun: - # Then the Cthulhu Find dialog has just given up focus - # to the original window. We don't want to speak - # the window title, current line, etc. - return - except Exception: - pass - - if self.flatReviewPresenter.is_active(): - self.flatReviewPresenter.quit() - - if self.learnModePresenter.is_active(): - self.learnModePresenter.quit() - - topLevel = self.utilities.topLevelObject(newLocusOfFocus) - if cthulhu_state.activeWindow != topLevel: - cthulhu.setActiveWindow(topLevel) - - self.updateBraille(newLocusOfFocus) - - utterances = self.speechGenerator.generateSpeech( - newLocusOfFocus, - priorObj=oldLocusOfFocus) - - self.interrupt_presentation_for_focus_change( - oldLocusOfFocus, - newLocusOfFocus, - event, - ) - speech.speak(utterances, interrupt=False) - cthulhu.emitRegionChanged(newLocusOfFocus) - self._saveFocusedObjectInfo(newLocusOfFocus) - - def activate(self): - """Called when this script is activated.""" - - tokens = ["DEFAULT: Activating script for", self.app] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - cthulhu.cthulhuApp.settingsManager.loadAppSettings(self) - braille.checkBrailleSetting() - braille.setupKeyRanges(self.brailleBindings.keys()) - speech.checkSpeechSetting() - self.speechAndVerbosityManager.update_punctuation_level() - self.speechAndVerbosityManager.update_capitalization_style() - - self.addKeyGrabs() - - tokens = ["DEFAULT: Script for", self.app, "activated"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - def updateBraille(self, obj, **args): - """Updates the braille display to show the give object. - - Arguments: - - obj: the Accessible - """ - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - debug.printMessage(debug.LEVEL_INFO, "BRAILLE: update disabled", True) - return - - if not obj: - return - - result, focusedRegion = self.brailleGenerator.generateBraille(obj, **args) - if not result: - return - - self.clearBraille() - line = self.getNewBrailleLine() - braille.addLine(line) - self.addBrailleRegionsToLine(result, line) - - extraRegion = args.get('extraRegion') - if extraRegion: - self.addBrailleRegionToLine(extraRegion, line) - self.setBrailleFocus(extraRegion) - else: - self.setBrailleFocus(focusedRegion) - - self.refreshBraille(True) - - ######################################################################## - # # - # INPUT EVENT HANDLERS (AKA CTHULHU COMMANDS) # - # # - ######################################################################## - - def toggleSleepMode(self, input_event=None): - """Toggles between sleep mode and regular mode.""" - # Sleep mode is now handled by the sleep mode manager - sleepModeManager = self.getSleepModeManager() - sleepModeManager.toggleSleepMode(self) - return True - - - def bypassNextCommand(self, inputEvent=None): - """Causes the next keyboard command to be ignored by Cthulhu - and passed along to the current application. - - Returns True to indicate the input event has been consumed. - """ - - self.presentMessage(messages.BYPASS_MODE_ENABLED) - cthulhu_state.bypassNextCommand = True - cthulhu_modifier_manager.getManager().unsetCthulhuModifiers("Bypass next command enabled") - self.removeKeyGrabs() - return True - - def findNext(self, inputEvent): - """Searches forward for the next instance of the string - searched for via the Cthulhu Find dialog. Other than direction - and the starting point, the search options initially specified - (case sensitivity, window wrap, and full/partial match) are - preserved. - """ - - lastQuery = find.getLastQuery() - if lastQuery: - lastQuery.searchBackwards = False - lastQuery.startAtTop = False - self.find(lastQuery) - else: - cthulhu.showFindGUI() - - def findPrevious(self, inputEvent): - """Searches backwards for the next instance of the string - searched for via the Cthulhu Find dialog. Other than direction - and the starting point, the search options initially specified - (case sensitivity, window wrap, and full/or partial match) are - preserved. - """ - - lastQuery = find.getLastQuery() - if lastQuery: - lastQuery.searchBackwards = True - lastQuery.startAtTop = False - self.find(lastQuery) - else: - cthulhu.showFindGUI() - - def panBrailleLeft(self, inputEvent=None, panAmount=0): - """Pans the braille display to the left. If panAmount is non-zero, - the display is panned by that many cells. If it is 0, the display - is panned one full display width. In flat review mode, panning - beyond the beginning will take you to the end of the previous line. - - In focus tracking mode, the cursor stays at its logical position. - In flat review mode, the review cursor moves to character - associated with cell 0.""" - - if isinstance(inputEvent, input_event.KeyboardEvent) \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - msg = "DEFAULT: panBrailleLeft command requires braille or braille monitor" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.flatReviewPresenter.is_active(): - if self.isBrailleBeginningShowing(): - self.flatReviewPresenter.go_start_of_line(self, inputEvent) - self.flatReviewPresenter.go_previous_character(self, inputEvent) - else: - self.panBrailleInDirection(panAmount, panToLeft=True) - - self._setFlatReviewContextToBeginningOfBrailleDisplay() - self.targetCursorCell = 1 - self.updateBrailleReview(self.targetCursorCell) - elif self.isBrailleBeginningShowing() and cthulhu_state.locusOfFocus \ - and self.utilities.isTextArea(cthulhu_state.locusOfFocus): - - # If we're at the beginning of a line of a multiline text - # area, then force it's caret to the end of the previous - # line. The assumption here is that we're currently - # viewing the line that has the caret -- which is a pretty - # good assumption for focus tacking mode. When we set the - # caret position, we will get a caret event, which will - # then update the braille. - # - obj = cthulhu_state.locusOfFocus - if not AXObject.supports_text(obj): - return True - caretOffset = AXText.get_caret_offset(obj) - lineString, startOffset, endOffset = AXText.get_line_at_offset(obj, caretOffset) - movedCaret = False - if startOffset > 0: - movedCaret = AXText.set_caret_offset(obj, startOffset - 1) - - # If we didn't move the caret and we're in a terminal, we - # jump into flat review to review the text. See - # http://bugzilla.gnome.org/show_bug.cgi?id=482294. - # - if not movedCaret and AXUtilities.is_terminal(cthulhu_state.locusOfFocus): - context = self.getFlatReviewContext() - context.goBegin(flat_review.Context.LINE) - self.flatReviewPresenter.go_previous_character(self, inputEvent) - else: - self.panBrailleInDirection(panAmount, panToLeft=True) - # We might be panning through a flashed message. - # - braille.resetFlashTimer() - self.refreshBraille(False, stopFlash=False) - - return True - - def panBrailleLeftOneChar(self, inputEvent=None): - """Nudges the braille display one character to the left. - - In focus tracking mode, the cursor stays at its logical position. - In flat review mode, the review cursor moves to character - associated with cell 0.""" - - self.panBrailleLeft(inputEvent, 1) - - def panBrailleRight(self, inputEvent=None, panAmount=0): - """Pans the braille display to the right. If panAmount is non-zero, - the display is panned by that many cells. If it is 0, the display - is panned one full display width. In flat review mode, panning - beyond the end will take you to the beginning of the next line. - - In focus tracking mode, the cursor stays at its logical position. - In flat review mode, the review cursor moves to character - associated with cell 0.""" - - if isinstance(inputEvent, input_event.KeyboardEvent) \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - msg = "DEFAULT: panBrailleRight command requires braille or braille monitor" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.flatReviewPresenter.is_active(): - if self.isBrailleEndShowing(): - self.flatReviewPresenter.go_end_of_line(self, inputEvent) - # Reviewing the next character also updates the braille output - # and refreshes the display. - self.flatReviewPresenter.go_next_character(self, inputEvent) - return - self.panBrailleInDirection(panAmount, panToLeft=False) - self._setFlatReviewContextToBeginningOfBrailleDisplay() - self.targetCursorCell = 1 - self.updateBrailleReview(self.targetCursorCell) - elif self.isBrailleEndShowing() and cthulhu_state.locusOfFocus \ - and self.utilities.isTextArea(cthulhu_state.locusOfFocus): - # If we're at the end of a line of a multiline text area, then - # force it's caret to the beginning of the next line. The - # assumption here is that we're currently viewing the line that - # has the caret -- which is a pretty good assumption for focus - # tacking mode. When we set the caret position, we will get a - # caret event, which will then update the braille. - # - obj = cthulhu_state.locusOfFocus - if not AXObject.supports_text(obj): - return True - caretOffset = AXText.get_caret_offset(obj) - lineString, startOffset, endOffset = AXText.get_line_at_offset(obj, caretOffset) - if endOffset < AXText.get_character_count(obj): - AXText.set_caret_offset(obj, endOffset) - else: - self.panBrailleInDirection(panAmount, panToLeft=False) - # We might be panning through a flashed message. - # - braille.resetFlashTimer() - self.refreshBraille(False, stopFlash=False) - - return True - - def panBrailleRightOneChar(self, inputEvent=None): - """Nudges the braille display one character to the right. - - In focus tracking mode, the cursor stays at its logical position. - In flat review mode, the review cursor moves to character - associated with cell 0.""" - - self.panBrailleRight(inputEvent, 1) - - def goBrailleHome(self, inputEvent=None): - """Returns to the component with focus.""" - - if self.flatReviewPresenter.is_active(): - self.flatReviewPresenter.quit() - return True - - return braille.returnToRegionWithFocus(inputEvent) - - def setContractedBraille(self, inputEvent=None): - """Toggles contracted braille.""" - - self._setContractedBraille(inputEvent) - return True - - def processRoutingKey(self, inputEvent=None): - """Processes a cursor routing key.""" - - braille.processRoutingKey(inputEvent) - return True - - def processBrailleCutBegin(self, inputEvent=None): - """Clears the selection and moves the caret offset in the currently - active text area. - """ - - obj, caretOffset = self.getBrailleCaretContext(inputEvent) - - if caretOffset >= 0: - self.utilities.clearTextSelection(obj) - self.utilities.setCaretOffset(obj, caretOffset) - - return True - - def processBrailleCutLine(self, inputEvent=None): - """Extends the text selection in the currently active text - area and also copies the selected text to the system clipboard.""" - - obj, caretOffset = self.getBrailleCaretContext(inputEvent) - - if caretOffset >= 0: - self.utilities.adjustTextSelection(obj, caretOffset) - selectedText, startOffset, endOffset = self.utilities.allSelectedText(obj) - if selectedText: - self.utilities.setClipboardText(selectedText) - - return True - - def routePointerToItem(self, inputEvent=None): - """Moves the mouse pointer to the current item.""" - - # Store the original location for scripts which want to restore - # it later. - # - self.oldMouseCoordinates = self.utilities.absoluteMouseCoordinates() - self.lastMouseRoutingTime = time.time() - if self.flatReviewPresenter.is_active(): - self.flatReviewPresenter.route_pointer_to_object(self, inputEvent) - return True - - if self.eventSynthesizer.route_to_character(cthulhu_state.locusOfFocus) \ - or self.eventSynthesizer.route_to_object(cthulhu_state.locusOfFocus): - self.presentMessage(messages.MOUSE_MOVED_SUCCESS) - return True - - full = messages.LOCATION_NOT_FOUND_FULL - brief = messages.LOCATION_NOT_FOUND_BRIEF - self.presentMessage(full, brief) - return False - - def leftClickReviewItem(self, inputEvent=None): - """Performs a left mouse button click on the current item.""" - - if self.flatReviewPresenter.is_active(): - obj = self.flatReviewPresenter.get_current_object(self, inputEvent) - if self.eventSynthesizer.try_all_clickable_actions(obj): - return True - return self.flatReviewPresenter.left_click_on_object(self, inputEvent) - - if self.eventSynthesizer.try_all_clickable_actions(cthulhu_state.locusOfFocus): - return True - - if self.utilities.queryNonEmptyText(cthulhu_state.locusOfFocus): - if self.eventSynthesizer.click_character(cthulhu_state.locusOfFocus, 1): - return True - - if self.eventSynthesizer.click_object(cthulhu_state.locusOfFocus, 1): - return True - - full = messages.LOCATION_NOT_FOUND_FULL - brief = messages.LOCATION_NOT_FOUND_BRIEF - self.presentMessage(full, brief) - return False - - def rightClickReviewItem(self, inputEvent=None): - """Performs a right mouse button click on the current item.""" - - if self.flatReviewPresenter.is_active(): - self.flatReviewPresenter.right_click_on_object(self, inputEvent) - return True - - if self.eventSynthesizer.click_character(cthulhu_state.locusOfFocus, 3): - return True - - if self.eventSynthesizer.click_object(cthulhu_state.locusOfFocus, 3): - return True - - full = messages.LOCATION_NOT_FOUND_FULL - brief = messages.LOCATION_NOT_FOUND_BRIEF - self.presentMessage(full, brief) - return False - - def spellCurrentItem(self, itemString): - """Spell the current flat review word or line. - - Arguments: - - itemString: the string to spell. - """ - - for character in itemString: - self.speakCharacter(character) - - def _diagnostic_object_summary(self, obj): - if obj is None: - return "None" - - try: - if AXObject.is_dead(obj): - return "dead" - except Exception: - pass - - try: - name = AXObject.get_name(obj) or "" - except Exception: - name = "" - - try: - role = AXObject.get_role_name(obj) or "" - except Exception: - role = "" - - try: - pid = AXObject.get_process_id(obj) - except Exception: - pid = "" - - return f"name={name!r}, role={role!r}, pid={pid}" - - def _diagnostic_callable_value(self, obj, methodName): - method = getattr(obj, methodName, None) - if not callable(method): - return "" - try: - return method() - except Exception as error: - return f"" - - @dbus_service.command - def get_diagnostic_state(self, script=None, event=None, notify_user=True) -> str: - """Dumps runtime state useful for diagnosing sluggish web-app behavior.""" - - app = cthulhu.cthulhuApp - activeScript = cthulhu_state.activeScript - eventManager = getattr(app, "eventManager", None) - compositor = getattr(app, "compositorStateAdapter", None) - inputManager = getattr(eventManager, "_inputEventManager", None) - - lines = [ - f"timestamp={time.strftime('%Y-%m-%d %H:%M:%S')}", - f"default-script={self.__class__.__module__}.{self.__class__.__name__}", - f"active-script={activeScript.__class__.__module__}.{activeScript.__class__.__name__}" if activeScript else "active-script=None", - f"active-window={self._diagnostic_object_summary(cthulhu_state.activeWindow)}", - f"locus-of-focus={self._diagnostic_object_summary(cthulhu_state.locusOfFocus)}", - f"pending-self-hosted-focus={self._diagnostic_object_summary(getattr(cthulhu_state, 'pendingSelfHostedFocus', None))}", - ] - - if eventManager is not None: - eventQueue = getattr(eventManager, "_eventQueue", None) - try: - queueSize = eventQueue.qsize() if eventQueue is not None else "" - except Exception as error: - queueSize = f"" - prioritizedEvent = getattr(eventManager, "_prioritizedEvent", None) - lines.extend([ - f"event-manager-active={getattr(eventManager, '_active', '')}", - f"event-queue-size={queueSize}", - f"events-suspended={getattr(eventManager, '_eventsSuspended', '')}", - f"churn-suppressed={getattr(eventManager, '_churnSuppressed', '')}", - f"state-pause-atspi-churn={cthulhu_state.pauseAtspiChurn}", - f"prioritized-context-token={getattr(eventManager, '_prioritizedContextToken', None)}", - f"state-prioritized-context-token={cthulhu_state.prioritizedDesktopContextToken}", - f"prioritized-event-type={getattr(prioritizedEvent, 'type', None)}", - f"gidle-id={getattr(eventManager, '_gidleId', '')}", - f"prioritized-idle-id={getattr(eventManager, '_prioritizedIdleId', '')}", - ]) - - if inputManager is not None: - lines.extend([ - f"key-handling-active={getattr(eventManager, '_keyHandlingActive', '')}", - f"input-manager-device={getattr(inputManager, '_device', None)}", - f"input-manager-watcher={getattr(inputManager, '_keyWatcher', None)}", - ]) - - if compositor is not None: - snapshot = self._diagnostic_callable_value(compositor, "get_snapshot") - lines.append(f"compositor-snapshot={snapshot}") - - if activeScript is not None: - lines.extend([ - f"active-script-focus-mode={self._diagnostic_callable_value(activeScript, 'inFocusMode')}", - f"active-script-focus-sticky={self._diagnostic_callable_value(activeScript, 'focusModeIsSticky')}", - f"active-script-browse-sticky={self._diagnostic_callable_value(activeScript, 'browseModeIsSticky')}", - f"active-script-structural-navigation={getattr(getattr(activeScript, 'structuralNavigation', None), 'enabled', '')}", - ]) - - report = "\n".join(lines) - debug.printMessage(debug.LEVEL_INFO, "CTHULHU DIAGNOSTIC STATE:\n" + report, True) - if notify_user and script is not None: - script.presentMessage("Cthulhu diagnostic state written to debug log.") - return report - - @dbus_service.command - def sayAll(self, inputEvent, obj=None, offset=None, notify_user=True): - """Speaks the entire document or text, starting from the current position.""" - obj = obj or cthulhu_state.locusOfFocus - if not obj or AXObject.is_dead(obj): - self.presentMessage(messages.LOCATION_NOT_FOUND_FULL) - return True - - if not AXObject.supports_text(obj): - utterances = self.speechGenerator.generateSpeech(obj) - utterances.extend(self.tutorialGenerator.getTutorial(obj, False)) - speech.speak(utterances) - else: - if offset is None: - offset = AXText.get_caret_offset(obj) - speech.sayAll(self.textLines(obj, offset), - self.__sayAllProgressCallback) - - return True - - def cycleSettingsProfile(self, inputEvent=None): - """Cycle through the user's existing settings profiles.""" - - profiles = cthulhu.cthulhuApp.settingsManager.availableProfiles() - if not (profiles and profiles[0]): - self.presentMessage(messages.PROFILE_NOT_FOUND) - return True - - def isMatch(x): - return x is not None and x[1] == cthulhu.cthulhuApp.settingsManager.getProfile() - - current = list(filter(isMatch, profiles))[0] - try: - name, profileID = profiles[profiles.index(current) + 1] - except IndexError: - name, profileID = profiles[0] - - cthulhu.cthulhuApp.settingsManager.setProfile(profileID, updateLocale=True) - - braille.checkBrailleSetting() - - speech.shutdown() - speech.init() - - # TODO: This is another "too close to code freeze" hack to cause the - # command names to be presented in the correct language. - self.setupInputEventHandlers() - - self.presentMessage(messages.PROFILE_CHANGED % name, name) - return True - - def cycleDebugLevel(self, inputEvent=None): - levels = [debug.LEVEL_ALL, "all", - debug.LEVEL_FINEST, "finest", - debug.LEVEL_FINER, "finer", - debug.LEVEL_FINE, "fine", - debug.LEVEL_CONFIGURATION, "configuration", - debug.LEVEL_INFO, "info", - debug.LEVEL_WARNING, "warning", - debug.LEVEL_SEVERE, "severe", - debug.LEVEL_OFF, "off"] - - try: - levelIndex = levels.index(debug.debugLevel) + 2 - except Exception: - levelIndex = 0 - else: - if levelIndex >= len(levels): - levelIndex = 0 - - debug.debugLevel = levels[levelIndex] - briefMessage = levels[levelIndex + 1] - fullMessage = f"Debug level {briefMessage}." - self.presentMessage(fullMessage, briefMessage) - - return True - - ######################################################################## - # # - # AT-SPI OBJECT EVENT HANDLERS # - # # - ######################################################################## - - def noOp(self, event): - """Just here to capture events. - - Arguments: - - event: the Event - """ - pass - - def onActiveChanged(self, event): - """Callback for object:state-changed:active accessibility events.""" - - window = event.source - if AXUtilities.is_application(AXObject.get_parent(event.source)): - window = AXObject.find_real_app_and_window_for(event.source)[1] - - if AXUtilities.is_dialog_or_alert(window) or AXUtilities.is_frame(window): - if event.detail1 and not self.utilities.canBeActiveWindow(window): - return - - sourceIsActiveWindow = self.utilities.isSameObject(window, cthulhu_state.activeWindow) - if sourceIsActiveWindow and not event.detail1: - if self.utilities.inMenu(): - msg = "DEFAULT: Ignoring event. In menu." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if not self.utilities.eventIsUserTriggered(event): - msg = "DEFAULT: Not clearing state. Event is not user triggered." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - msg = "DEFAULT: Event is for active window. Clearing state." - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setActiveWindow(None) - return - - if not sourceIsActiveWindow and event.detail1: - msg = "DEFAULT: Updating active window." - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setActiveWindow(window, alsoSetLocusOfFocus=True, notifyScript=True) - - if self.findCommandRun: - self.findCommandRun = False - self.find() - - def onActiveDescendantChanged(self, event): - """Callback for object:active-descendant-changed accessibility events.""" - - if not event.any_data: - msg = "DEFAULT: Ignoring event. No any_data." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if not AXUtilities.is_focused(event.source) \ - and not AXUtilities.is_focused(event.any_data): - msg = "DEFAULT: Ignoring event. Neither source nor child have focused state." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.stopSpeechOnActiveDescendantChanged(event): - self.presentationInterrupt() - - tokens = ["DEFAULT: Setting locus of focus to any_data", event.any_data] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, event.any_data) - - def onBusyChanged(self, event): - """Callback for object:state-changed:busy accessibility events.""" - pass - - def onCheckedChanged(self, event): - """Callback for object:state-changed:checked accessibility events.""" - - if not self.utilities.isSameObject(event.source, cthulhu_state.locusOfFocus): - return - - if AXUtilities.is_expandable(event.source): - return - - # Radio buttons normally change their state when you arrow to them, - # so we handle the announcement of their state changes in the focus - # handling code. However, we do need to handle radio buttons where - # the user needs to press the space key to select them. - if AXObject.get_role(event.source) == Atspi.Role.RADIO_BUTTON: - eventString, mods = self.utilities.lastKeyAndModifiers() - if eventString not in [" ", "space"]: - return - - oldObj, oldState = self.pointOfReference.get('checkedChange', (None, 0)) - if hash(oldObj) == hash(event.source) and oldState == event.detail1: - return - - self.presentObject(event.source, alreadyFocused=True, interrupt=True) - self.pointOfReference['checkedChange'] = hash(event.source), event.detail1 - - def onChildrenAdded(self, event): - """Callback for object:children-changed:add accessibility events.""" - - AXObject.clear_cache_now("children-changed event.") - - def onChildrenRemoved(self, event): - """Callback for object:children-changed:remove accessibility events.""" - - AXObject.clear_cache_now("children-changed event.") - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - obj, offset = self.pointOfReference.get("lastCursorPosition", (None, -1)) - if offset == event.detail1 and obj == event.source: - msg = "DEFAULT: Event is for last saved cursor position" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if not AXUtilities.is_showing(event.source): - msg = "DEFAULT: Event source is not showing. Clearing cache." - debug.printMessage(debug.LEVEL_INFO, msg, True) - AXObject.clear_cache(obj) - if not AXUtilities.is_showing(event.source): - msg = "DEFAULT: Event source is still not showing." - debug.printMessage(debug.LEVEL_INFO, msg, True) - if not self.utilities.presentEventFromNonShowingObject(event): - return - - if event.source != cthulhu_state.locusOfFocus and AXUtilities.is_focused(event.source): - topLevelObject = self.utilities.topLevelObject(event.source) - if self.utilities.isSameObject(cthulhu_state.activeWindow, topLevelObject): - tokens = ["DEFAULT: Updating locusOfFocus from", cthulhu_state.locusOfFocus, - "to", event.source] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, event.source, False) - else: - tokens = ["DEFAULT: Source window (", topLevelObject, ") is not active window (", - cthulhu_state.activeWindow] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if event.source != cthulhu_state.locusOfFocus: - tokens = ["DEFAULT: Event source (", event.source, ") is not locusOfFocus (", - cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - if self.flatReviewPresenter.is_active(): - self.flatReviewPresenter.quit() - - if not AXObject.supports_text(event.source): - return - - caretOffset = AXText.get_caret_offset(event.source) - if caretOffset < 0: - tokens = ["DEFAULT: Invalid caretOffset for", event.source] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - self._saveLastCursorPosition(event.source, caretOffset) - if self.utilities.allTextSelections(event.source): - msg = "DEFAULT: Event source has text selections" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.utilities.handleTextSelectionChange(event.source) - return - else: - start, end, string = self.utilities.getCachedTextSelection(obj) - if string and self.utilities.handleTextSelectionChange(obj): - msg = "DEFAULT: Event handled as text selection change" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - msg = "DEFAULT: Presenting text at new caret position" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._presentTextAtNewCaretPosition(event) - - def onDescriptionChanged(self, event): - """Callback for object:property-change:accessible-description events.""" - - obj = event.source - descriptions = self.pointOfReference.get('description', {}) - oldDescription = descriptions.get(hash(obj)) - if oldDescription == event.any_data: - tokens = ["DEFAULT: Old description (", oldDescription, ") is the same as new one"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - if obj != cthulhu_state.locusOfFocus: - msg = "DEFAULT: Event is for object other than the locusOfFocus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - descriptions[hash(obj)] = event.any_data - self.pointOfReference['descriptions'] = descriptions - if event.any_data: - self.presentMessage(event.any_data) - - def onDocumentReload(self, event): - """Callback for document:reload accessibility events.""" - - pass - - def onDocumentLoadComplete(self, event): - """Callback for document:load-complete accessibility events.""" - - pass - - def onDocumentLoadStopped(self, event): - """Callback for document:load-stopped accessibility events.""" - - pass - - def onExpandedChanged(self, event): - """Callback for object:state-changed:expanded accessibility events.""" - - if not self.utilities.isPresentableExpandedChangedEvent(event): - return - - obj = event.source - oldObj, oldState = self.pointOfReference.get('expandedChange', (None, 0)) - if hash(oldObj) == hash(obj) and oldState == event.detail1: - return - - self.presentObject(obj, alreadyFocused=True, interrupt=True) - self.pointOfReference['expandedChange'] = hash(obj), event.detail1 - - details = self.utilities.detailsContentForObject(obj) - for detail in details: - self.speakMessage(detail, interrupt=False) - - def onIndeterminateChanged(self, event): - """Callback for object:state-changed:indeterminate accessibility events.""" - - # If this state is cleared, the new state will become checked or unchecked - # and we should get object:state-changed:checked events for those cases. - # Therefore, if the state is not now indeterminate/partially checked, - # ignore this event. - if not event.detail1: - return - - obj = event.source - if not self.utilities.isSameObject(obj, cthulhu_state.locusOfFocus): - return - - oldObj, oldState = self.pointOfReference.get('indeterminateChange', (None, 0)) - if hash(oldObj) == hash(obj) and oldState == event.detail1: - return - - self.presentObject(obj, alreadyFocused=True, interrupt=True) - self.pointOfReference['indeterminateChange'] = hash(obj), event.detail1 - - def onMouseButton(self, event): - """Callback for mouse:button events.""" - - mouseEvent = input_event.MouseButtonEvent(event) - cthulhu_state.lastInputEvent = mouseEvent - if not mouseEvent.pressed: - return - - windowChanged = cthulhu_state.activeWindow != mouseEvent.window - if windowChanged: - cthulhu.setActiveWindow(mouseEvent.window, alsoSetLocusOfFocus=True) - - self.presentationInterrupt() - if AXUtilities.is_focused(mouseEvent.obj): - cthulhu.setLocusOfFocus(None, mouseEvent.obj, windowChanged) - - def onAnnouncement(self, event): - """Callback for object:announcement events.""" - - if isinstance(event.any_data, str): - # AT-SPI announcements contain application content, not system messages. - # Use resetStyles=False to preserve the user's punctuation settings. - self.presentMessage(event.any_data, resetStyles=False) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - names = self.pointOfReference.get('names', {}) - oldName = names.get(hash(event.source)) - if oldName == event.any_data: - tokens = ["DEFAULT: Old name (", oldName, ") is the same as new name"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - if AXUtilities.is_combo_box(event.source) or AXUtilities.is_table_cell(event.source): - msg = "DEFAULT: Event is redundant notification for this role" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if AXUtilities.is_frame(event.source): - if event.source != cthulhu_state.activeWindow: - msg = "DEFAULT: Event is for frame other than the active window" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - elif event.source != cthulhu_state.locusOfFocus: - msg = "DEFAULT: Event is for object other than the locusOfFocus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - names[hash(event.source)] = event.any_data - self.pointOfReference['names'] = names - if event.any_data: - self.presentMessage(event.any_data) - - def onPressedChanged(self, event): - """Callback for object:state-changed:pressed accessibility events.""" - - obj = event.source - if not self.utilities.isSameObject(obj, cthulhu_state.locusOfFocus): - return - - oldObj, oldState = self.pointOfReference.get('pressedChange', (None, 0)) - if hash(oldObj) == hash(obj) and oldState == event.detail1: - return - - self.presentObject(obj, alreadyFocused=True, interrupt=True) - self.pointOfReference['pressedChange'] = hash(obj), event.detail1 - - def onSelectedChanged(self, event): - """Callback for object:state-changed:selected accessibility events.""" - - AXObject.clear_cache(event.source) - if not AXUtilities.is_focused(event.source): - msg = "DEFAULT: Event is not toggling of currently-focused object" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if not self.utilities.isSameObject(cthulhu_state.locusOfFocus, event.source): - tokens = ["DEFAULT: Event is not for locusOfFocus", cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return - - isSelected = AXUtilities.is_selected(event.source) - if isSelected != event.detail1: - msg = "DEFAULT: Bogus event: detail1 doesn't match state" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - oldObj, oldState = self.pointOfReference.get('selectedChange', (None, 0)) - if hash(oldObj) == hash(event.source) and oldState == event.detail1: - msg = "DEFAULT: Duplicate or spam event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - announceState = False - keyString, mods = self.utilities.lastKeyAndModifiers() - if keyString == "space": - announceState = True - elif keyString in ["Down", "Up"] and AXUtilities.is_table_cell(event.source): - announceState = isSelected - - if not announceState: - return - - # TODO - JD: Unlike the other state-changed callbacks, it seems unwise - # to call generateSpeech() here because that also will present the - # expandable state if appropriate for the object type. The generators - # need to gain some smarts w.r.t. state changes. - - if event.detail1: - self.speakMessage(messages.TEXT_SELECTED, interrupt=False) - else: - self.speakMessage(messages.TEXT_UNSELECTED, interrupt=False) - - self.pointOfReference['selectedChange'] = hash(event.source), event.detail1 - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - if self.utilities.handlePasteLocusOfFocusChange(): - if self.utilities.topLevelObjectIsActiveAndCurrent(event.source): - cthulhu.setLocusOfFocus(event, event.source, False) - elif self.utilities.handleContainerSelectionChange(event.source): - return - elif AXUtilities.manages_descendants(event.source): - return - - # If the current item's selection is toggled, we'll present that - # via the state-changed event. - keyString, mods = self.utilities.lastKeyAndModifiers() - if keyString == "space": - return - - if AXUtilities.is_combo_box(event.source) and not AXUtilities.is_expanded(event.source): - if AXUtilities.is_focused(self.utilities.getEntryForEditableComboBox(event.source)): - return - elif AXUtilities.is_page_tab_list(event.source) and self.flatReviewPresenter.is_active(): - # If a wizard-like notebook page being reviewed changes, we might not get - # any events to update the locusOfFocus. As a result, subsequent flat - # review commands will continue to present the stale content. - # TODO - JD: We can potentially do some automatic reading here. - self.flatReviewPresenter.quit() - - mouseReviewItem = self.mouseReviewer.getCurrentItem() - selectedChildren = self.utilities.selectedChildren(event.source) - for child in selectedChildren: - if AXObject.find_ancestor(cthulhu_state.locusOfFocus, lambda x: x == child): - tokens = ["DEFAULT: Child", child, "is ancestor of locusOfFocus"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._saveFocusedObjectInfo(cthulhu_state.locusOfFocus) - return - - if child == mouseReviewItem: - tokens = ["DEFAULT: Child", child, "is current mouse review item"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - continue - - if AXUtilities.is_page_tab(child) and cthulhu_state.locusOfFocus \ - and AXObject.get_name(child) == AXObject.get_name(cthulhu_state.locusOfFocus) \ - and not AXUtilities.is_focused(event.source): - tokens = ["DEFAULT:", child, "'s selection redundant to", cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - break - - if not self.utilities.isLayoutOnly(child): - cthulhu.setLocusOfFocus(event, child) - break - - def onSensitiveChanged(self, event): - """Callback for object:state-changed:sensitive accessibility events.""" - pass - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - pass - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if not event.detail1: - return - - if not AXUtilities.is_focused(event.source): - return - - obj = event.source - window, dialog = self.utilities.frameAndDialog(obj) - clearCache = window != cthulhu_state.activeWindow - if window and not self.utilities.canBeActiveWindow(window, clearCache) and not dialog: - return - - if AXObject.get_child_count(obj) and not AXUtilities.is_combo_box(obj): - selectedChildren = self.utilities.selectedChildren(obj) - if selectedChildren: - obj = selectedChildren[0] - - cthulhu.setLocusOfFocus(event, obj) - - def onShowingChanged(self, event): - """Callback for object:state-changed:showing accessibility events.""" - - obj = event.source - role = AXObject.get_role(obj) - if role == Atspi.Role.NOTIFICATION: - if not event.detail1: - return - - speech.speak(self.speechGenerator.generateSpeech(obj)) - msg = self.utilities.getNotificationContent(obj) - self.displayBrailleMessage(msg, flashTime=settings.brailleFlashTime) - self.notificationPresenter.save_notification(msg) - return - - if role == Atspi.Role.TOOL_TIP: - keyString, mods = self.utilities.lastKeyAndModifiers() - if keyString != "F1" \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('presentToolTips'): - return - if event.detail1: - self.presentObject(obj, interrupt=True) - return - - if cthulhu_state.locusOfFocus and keyString == "F1": - obj = cthulhu_state.locusOfFocus - self.presentObject(obj, priorObj=event.source, interrupt=True) - return - - def onTextAttributesChanged(self, event): - """Callback for object:text-attributes-changed accessibility events.""" - - if not self.utilities.isPresentableTextChangedEventForLocusOfFocus(event): - return - - text = self.utilities.queryNonEmptyText(event.source) - if not text: - msg = "DEFAULT: Querying non-empty text returned None" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if cthulhu.cthulhuApp.settingsManager.getSetting('speakMisspelledIndicator'): - offset = AXText.get_caret_offset(event.source) - if not AXText.get_substring(event.source, offset, offset + 1).isalnum(): - offset -= 1 - if self.utilities.isWordMisspelled(event.source, offset-1) \ - or self.utilities.isWordMisspelled(event.source, offset+1): - self.speakMessage(messages.MISSPELLED) - - def onTextDeleted(self, event): - """Callback for object:text-changed:delete accessibility events.""" - - if not self.utilities.isPresentableTextChangedEventForLocusOfFocus(event): - return - - self.utilities.handleUndoTextEvent(event) - - cthulhu.setLocusOfFocus(event, event.source, False) - self.updateBraille(event.source) - - full, brief = "", "" - if self.utilities.isClipboardTextChangedEvent(event): - msg = "DEFAULT: Deletion is believed to be due to clipboard cut" - debug.printMessage(debug.LEVEL_INFO, msg, True) - full, brief = messages.CLIPBOARD_CUT_FULL, messages.CLIPBOARD_CUT_BRIEF - elif self.utilities.isSelectedTextDeletionEvent(event): - msg = "DEFAULT: Deletion is believed to be due to deleting selected text" - debug.printMessage(debug.LEVEL_INFO, msg, True) - full = messages.SELECTION_DELETED - - if full or brief: - self.presentMessage(full, brief) - self.utilities.updateCachedTextSelection(event.source) - return - - string = self.utilities.deletedText(event) - if self.utilities.isDeleteCommandTextDeletionEvent(event): - msg = "DEFAULT: Deletion is believed to be due to Delete command" - debug.printMessage(debug.LEVEL_INFO, msg, True) - string = self.utilities.getCharacterAtOffset(event.source) - elif self.utilities.isBackSpaceCommandTextDeletionEvent(event): - msg = "DEFAULT: Deletion is believed to be due to BackSpace command" - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - msg = "DEFAULT: Event is not being presented due to lack of cause" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if len(string) == 1: - self.speakCharacter(string) - else: - voice = self.speechGenerator.voice(string=string) - string = self.utilities.adjustForRepeats(string) - self.speakMessage(string, voice) - - def onTextInserted(self, event): - """Callback for object:text-changed:insert accessibility events.""" - - if not self.utilities.isPresentableTextChangedEventForLocusOfFocus(event): - return - - self.utilities.handleUndoTextEvent(event) - - if event.source == cthulhu_state.locusOfFocus and self.utilities.isAutoTextEvent(event): - self._saveFocusedObjectInfo(event.source) - cthulhu.setLocusOfFocus(event, event.source, False) - self.updateBraille(event.source) - - full, brief = "", "" - if self.utilities.isClipboardTextChangedEvent(event): - msg = "DEFAULT: Insertion is believed to be due to clipboard paste" - debug.printMessage(debug.LEVEL_INFO, msg, True) - full, brief = messages.CLIPBOARD_PASTED_FULL, messages.CLIPBOARD_PASTED_BRIEF - elif self.utilities.isSelectedTextRestoredEvent(event): - msg = "DEFAULT: Insertion is believed to be due to restoring selected text" - debug.printMessage(debug.LEVEL_INFO, msg, True) - full = messages.SELECTION_RESTORED - - if full or brief: - self.presentMessage(full, brief) - self.utilities.updateCachedTextSelection(event.source) - return - - speakString = True - - # Because some implementations are broken. - string = self.utilities.insertedText(event) - - if self.utilities.lastInputEventWasPageSwitch(): - msg = "DEFAULT: Insertion is believed to be due to page switch" - debug.printMessage(debug.LEVEL_INFO, msg, True) - speakString = False - elif self.utilities.lastInputEventWasCommand(): - msg = "DEFAULT: Insertion is believed to be due to command" - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif self.utilities.isMiddleMouseButtonTextInsertionEvent(event): - msg = "DEFAULT: Insertion is believed to be due to middle mouse button" - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif self.utilities.isEchoableTextInsertionEvent(event): - msg = "DEFAULT: Insertion is believed to be echoable" - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif self.utilities.isAutoTextEvent(event): - msg = "DEFAULT: Insertion is believed to be auto text event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif self.utilities.isSelectedTextInsertionEvent(event): - msg = "DEFAULT: Insertion is also selected" - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - msg = "DEFAULT: Not speaking inserted string due to lack of cause" - debug.printMessage(debug.LEVEL_INFO, msg, True) - speakString = False - - if speakString: - if len(string) == 1: - self.speakCharacter(string) - else: - voice = self.speechGenerator.voice(obj=event.source, string=string) - string = self.utilities.adjustForRepeats(string) - self.speakMessage(string, voice) - - if len(string) != 1: - return - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableKeyEcho'): - return - - if cthulhu.cthulhuApp.settingsManager.getSetting('enableEchoBySentence') \ - and self.echoPreviousSentence(event.source): - return - - if cthulhu.cthulhuApp.settingsManager.getSetting('enableEchoByWord'): - self.echoPreviousWord(event.source) - - def onTextSelectionChanged(self, event): - """Callback for object:text-selection-changed accessibility events.""" - - obj = event.source - - # We won't handle undo here as it can lead to double-presentation. - # If there is an application for which text-changed events are - # missing upon undo, handle them in an app or toolkit script. - - self.utilities.handleTextSelectionChange(obj) - self.updateBraille(obj) - - def onColumnReordered(self, event): - """Callback for object:column-reordered accessibility events.""" - - if not self.utilities.lastInputEventWasTableSort(): - return - - if event.source != self.utilities.getTable(cthulhu_state.locusOfFocus): - return - - self.pointOfReference['last-table-sort-time'] = time.time() - self.presentMessage(messages.TABLE_REORDERED_COLUMNS) - - def onRowReordered(self, event): - """Callback for object:row-reordered accessibility events.""" - - if not self.utilities.lastInputEventWasTableSort(): - return - - if event.source != self.utilities.getTable(cthulhu_state.locusOfFocus): - return - - self.pointOfReference['last-table-sort-time'] = time.time() - self.presentMessage(messages.TABLE_REORDERED_ROWS) - - def onValueChanged(self, event): - """Called whenever an object's value changes. Currently, the - value changes for non-focused objects are ignored. - - Arguments: - - event: the Event - """ - - obj = event.source - role = AXObject.get_role(obj) - - if not AXObject.supports_value(obj): - tokens = ["DEFAULT:", obj, "doesn't implement AtspiValue"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - currentValue = AXValue.get_current_value(obj) - - if "oldValue" in self.pointOfReference \ - and (currentValue == self.pointOfReference["oldValue"]): - return - - isProgressBarUpdate, msg = self.utilities.isProgressBarUpdate(obj) - tokens = ["DEFAULT: Is progress bar update:", isProgressBarUpdate, ",", msg] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not isProgressBarUpdate and obj != cthulhu_state.locusOfFocus: - tokens = ["DEFAULT: Source != locusOfFocus (", cthulhu_state.locusOfFocus, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - if role == Atspi.Role.SPIN_BUTTON: - self._saveFocusedObjectInfo(event.source) - - self.pointOfReference["oldValue"] = currentValue - self.updateBraille(obj, isProgressBarUpdate=isProgressBarUpdate) - speech.speak(self.speechGenerator.generateSpeech( - obj, alreadyFocused=True, isProgressBarUpdate=isProgressBarUpdate)) - self.__play(self.soundGenerator.generateSound( - obj, alreadyFocused=True, isProgressBarUpdate=isProgressBarUpdate)) - - def onWindowActivated(self, event): - """Called whenever a toplevel window is activated. - - Arguments: - - event: the Event - """ - - window = AXObject.find_real_app_and_window_for(event.source)[1] - if not self.utilities.canBeActiveWindow(window, False): - return - - if self.utilities.isSameObject(window, cthulhu_state.activeWindow): - msg = "DEFAULT: Event is for active window." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - self.pointOfReference = {} - - cthulhu.setActiveWindow(window) - - app = AXObject.get_application(window) - appName = (AXObject.get_name(app) or "").lower() - if appName == "cthulhu": - msg = "DEFAULT: Self-hosted window activated. Waiting for focused child event." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.utilities.isKeyGrabEvent(event): - msg = "DEFAULT: Ignoring event. Likely from key grab." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if AXObject.get_child_count(window) == 1: - child = AXObject.get_child(window, 0) - if AXObject.get_role(child) == Atspi.Role.MENU: - cthulhu.setLocusOfFocus(event, child) - return - - cthulhu.setLocusOfFocus(event, cthulhu_state.activeWindow) - - def onWindowCreated(self, event): - """Callback for window:create accessibility events.""" - - pass - - def onWindowDestroyed(self, event): - """Callback for window:destroy accessibility events.""" - - pass - - def onWindowDeactivated(self, event): - """Called whenever a toplevel window is deactivated. - - Arguments: - - event: the Event - """ - - if self.utilities.inMenu(): - msg = "DEFAULT: Ignoring event. In menu." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if event.source != cthulhu_state.activeWindow: - tokens = ["DEFAULT: Ignoring event. Not for active window", - cthulhu_state.activeWindow, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - if self.utilities.isKeyGrabEvent(event): - msg = "DEFAULT: Ignoring event. Likely from key grab." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - # Some toolkits emit transient window:deactivate/window:activate pairs - # while the same window remains active. Treat those as noise so we do - # not clear state and force a full script/settings reactivation. - AXObject.clear_cache(event.source) - if AXUtilities.is_active(event.source): - msg = "DEFAULT: Ignoring event. Source window still active." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.flatReviewPresenter.is_active(): - self.flatReviewPresenter.quit() - - if self.learnModePresenter.is_active(): - self.learnModePresenter.quit() - - self.pointOfReference = {} - - if not self.utilities.eventIsUserTriggered(event): - msg = "DEFAULT: Not clearing state. Event is not user triggered." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - msg = "DEFAULT: Clearing state." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - cthulhu.setLocusOfFocus(event, None) - cthulhu.setActiveWindow(None) - cthulhu.cthulhuApp.scriptManager.set_active_script(None, "focus: window-deactivated") - - def onClipboardContentsChanged(self, *args): - pending = self._pendingKeyboardClipboardCommand - currentContents = self.utilities.getClipboardContents() - tokens = [ - "DEFAULT: Clipboard callback snapshot", - self._describeClipboardContents(currentContents), - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if pending is not None: - pending["callbackSeen"] = True - if pending.get("presented"): - self._pendingKeyboardClipboardCommand = None - return - - if self.flatReviewPresenter.is_active(): - return - - if pending is not None: - clipboardMatchesSource = self._clipboardMatchesPendingKeyboardCommand( - pending, currentContents - ) - else: - clipboardMatchesSource = False - - if not clipboardMatchesSource and not self.utilities.objectContentsAreInClipboard(): - return - - if not self.utilities.topLevelObjectIsActiveAndCurrent(): - return - - if self.utilities.lastInputEventWasCopy(): - self.presentMessage(messages.CLIPBOARD_COPIED_FULL, messages.CLIPBOARD_COPIED_BRIEF) - if self._pendingKeyboardClipboardCommand is pending: - self._pendingKeyboardClipboardCommand = None - return - - if not self.utilities.lastInputEventWasCut(): - return - - if AXUtilities.is_editable(cthulhu_state.locusOfFocus): - return - - self.presentMessage(messages.CLIPBOARD_CUT_FULL, messages.CLIPBOARD_CUT_BRIEF) - if self._pendingKeyboardClipboardCommand is pending: - self._pendingKeyboardClipboardCommand = None - - ######################################################################## - # # - # Methods for presenting content # - # # - ######################################################################## - - def _presentTextAtNewCaretPosition(self, event, otherObj=None): - obj = otherObj or event.source - self.updateBrailleForNewCaretPosition(obj) - if self._inSayAll: - msg = "DEFAULT: Not presenting text because SayAll is active" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.utilities.lastInputEventWasLineNav(): - msg = "DEFAULT: Presenting result of line nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.sayLine(obj) - return - - if self.utilities.lastInputEventWasWordNav(): - msg = "DEFAULT: Presenting result of word nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.sayWord(obj) - return - - if self.utilities.lastInputEventWasCharNav(): - msg = "DEFAULT: Presenting result of char nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.sayCharacter(obj) - return - - if self.utilities.lastInputEventWasPageNav(): - msg = "DEFAULT: Presenting result of page nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.sayLine(obj) - return - - if self.utilities.lastInputEventWasLineBoundaryNav(): - msg = "DEFAULT: Presenting result of line boundary nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.sayCharacter(obj) - return - - if self.utilities.lastInputEventWasFileBoundaryNav(): - msg = "DEFAULT: Presenting result of file boundary nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.sayLine(obj) - return - - if self.utilities.lastInputEventWasPrimaryMouseClick() \ - or self.utilities.lastInputEventWasPrimaryMouseRelease(): - start, end, string = self.utilities.getCachedTextSelection(event.source) - if not string: - msg = "DEFAULT: Presenting result of primary mouse button event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.sayLine(obj) - return - - def _rewindSayAll(self, context, minCharCount=10): - if not cthulhu.cthulhuApp.settingsManager.getSetting('rewindAndFastForwardInSayAll'): - return False - - index = self._sayAllContexts.index(context) - self._sayAllContexts = self._sayAllContexts[0:index] - while self._sayAllContexts: - context = self._sayAllContexts.pop() - if context.endOffset - context.startOffset > minCharCount: - break - - if AXObject.supports_text(context.obj): - cthulhu.setLocusOfFocus(None, context.obj, notifyScript=False) - AXText.set_caret_offset(context.obj, context.startOffset) - - self.sayAll(None, context.obj, context.startOffset) - return True - - def _fastForwardSayAll(self, context): - if not cthulhu.cthulhuApp.settingsManager.getSetting('rewindAndFastForwardInSayAll'): - return False - - if AXObject.supports_text(context.obj): - cthulhu.setLocusOfFocus(None, context.obj, notifyScript=False) - AXText.set_caret_offset(context.obj, context.endOffset) - - self.sayAll(None, context.obj, context.endOffset) - return True - - def __sayAllProgressCallback(self, context, progressType): - # [[[TODO: WDW - this needs work. Need to be able to manage - # the monitoring of progress and couple that with both updating - # the visual progress of what is being spoken as well as - # positioning the cursor when speech has stopped.]]] - # - if not AXObject.supports_text(context.obj): - return - char = AXText.get_substring(context.obj, context.currentOffset, context.currentOffset + 1) - - # Setting the caret at the offset of an embedded object results in - # focus changes. - if char == self.EMBEDDED_OBJECT_CHARACTER: - return - - if progressType == speechserver.SayAllContext.PROGRESS: - cthulhu.emitRegionChanged( - context.obj, context.currentOffset, context.currentEndOffset, cthulhu.SAY_ALL) - return - - if progressType == speechserver.SayAllContext.INTERRUPTED: - if isinstance(cthulhu_state.lastInputEvent, input_event.KeyboardEvent): - self._sayAllIsInterrupted = True - lastKey = cthulhu_state.lastInputEvent.event_string - if lastKey == "Down" and self._fastForwardSayAll(context): - return - elif lastKey == "Up" and self._rewindSayAll(context): - return - - self._inSayAll = False - self._sayAllContexts = [] - cthulhu.emitRegionChanged(context.obj, context.currentOffset) - AXText.set_caret_offset(context.obj, context.currentOffset) - elif progressType == speechserver.SayAllContext.COMPLETED: - cthulhu.setLocusOfFocus(None, context.obj, notifyScript=False) - cthulhu.emitRegionChanged(context.obj, context.currentOffset, mode=cthulhu.SAY_ALL) - AXText.set_caret_offset(context.obj, context.currentOffset) - - # If there is a selection, clear it. See bug #489504 for more details. - # - if self.utilities.allTextSelections(context.obj): - self.utilities.clearTextSelection(context.obj) - - def inSayAll(self, treatInterruptedAsIn=True): - if self._inSayAll: - msg = "DEFAULT: In SayAll" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self._sayAllIsInterrupted: - msg = "DEFAULT: SayAll is interrupted" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return treatInterruptedAsIn - - msg = "DEFAULT: Not in SayAll" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - def echoPreviousSentence(self, obj): - """Speaks the sentence prior to the caret, as long as there is - a sentence prior to the caret and there is no intervening sentence - delimiter between the caret and the end of the sentence. - - The entry condition for this method is that the character - prior to the current caret position is a sentence delimiter, - and it's what caused this method to be called in the first - place. - - Arguments: - - obj: an Accessible object that implements the AccessibleText - interface. - """ - - if not AXObject.supports_text(obj): - return False - - caretOffset = AXText.get_caret_offset(obj) - offset = caretOffset - 1 - previousOffset = caretOffset - 2 - if (offset < 0 or previousOffset < 0): - return False - - currentChar, _, _ = AXText.get_character_at_offset(obj, offset) - previousChar, _, _ = AXText.get_character_at_offset(obj, previousOffset) - if not self.utilities.isSentenceDelimiter(currentChar, previousChar): - return False - - # OK - we seem to be cool so far. So...starting with what - # should be the last character in the sentence (caretOffset - 2), - # work our way to the beginning of the sentence, stopping when - # we hit another sentence delimiter. - # - sentenceEndOffset = caretOffset - 2 - sentenceStartOffset = sentenceEndOffset - - while sentenceStartOffset >= 0: - currentChar, _, _ = AXText.get_character_at_offset(obj, sentenceStartOffset) - if sentenceStartOffset - 1 >= 0: - previousChar, _, _ = AXText.get_character_at_offset(obj, sentenceStartOffset - 1) - else: - previousChar = "" - if self.utilities.isSentenceDelimiter(currentChar, previousChar): - break - else: - sentenceStartOffset -= 1 - - # If we came across a sentence delimiter before hitting any - # text, we really don't have a previous sentence. - # - # Otherwise, get the sentence. Remember we stopped when we - # hit a sentence delimiter, so the sentence really starts at - # sentenceStartOffset + 1. getText also does not include - # the character at sentenceEndOffset, so we need to adjust - # for that, too. - # - if sentenceStartOffset == sentenceEndOffset: - return False - else: - sentence = self.utilities.substring(obj, sentenceStartOffset + 1, - sentenceEndOffset + 1) - - sentence = self.utilities.adjustForRepeats(sentence) - if self._shouldUseCustomEchoVoice("sentence"): - speech.speakEchoText(sentence, self._getCustomEchoVoice()) - else: - voice = self.speechGenerator.voice(obj=obj, string=sentence) - self.speakMessage(sentence, voice) - return True - - def echoPreviousWord(self, obj, offset=None): - """Speaks the word prior to the caret, as long as there is - a word prior to the caret and there is no intervening word - delimiter between the caret and the end of the word. - - The entry condition for this method is that the character - prior to the current caret position is a word delimiter, - and it's what caused this method to be called in the first - place. - - Arguments: - - obj: an Accessible object that implements the AccessibleText - interface. - - offset: if not None, the offset within the text to use as the - end of the word. - """ - - if not AXObject.supports_text(obj): - return False - - if not offset: - caretOffset = AXText.get_caret_offset(obj) - if caretOffset == -1: - offset = AXText.get_character_count(obj) - else: - offset = caretOffset - 1 - - if (offset < 0): - return False - - char, _, _ = AXText.get_character_at_offset(obj, offset) - if not self.utilities.isWordDelimiter(char): - return False - - # OK - we seem to be cool so far. So...starting with what - # should be the last character in the word (caretOffset - 2), - # work our way to the beginning of the word, stopping when - # we hit another word delimiter. - # - wordEndOffset = offset - 1 - wordStartOffset = wordEndOffset - - while wordStartOffset >= 0: - char, _, _ = AXText.get_character_at_offset(obj, wordStartOffset) - if self.utilities.isWordDelimiter(char): - break - else: - wordStartOffset -= 1 - - # If we came across a word delimiter before hitting any - # text, we really don't have a previous word. - # - # Otherwise, get the word. Remember we stopped when we - # hit a word delimiter, so the word really starts at - # wordStartOffset + 1. getText also does not include - # the character at wordEndOffset, so we need to adjust - # for that, too. - # - if wordStartOffset == wordEndOffset: - return False - else: - word = self.utilities.\ - substring(obj, wordStartOffset + 1, wordEndOffset + 1) - - word = self.utilities.adjustForRepeats(word) - if self._shouldUseCustomEchoVoice("word"): - speech.speakEchoText(word, self._getCustomEchoVoice()) - else: - voice = self.speechGenerator.voice(obj=obj, string=word) - self.speakMessage(word, voice) - return True - - def sayCharacter(self, obj): - """Speak the character at the caret. - - Arguments: - - obj: an Accessible object that implements the AccessibleText - interface - """ - - if not AXObject.supports_text(obj): - return - - offset = AXText.get_caret_offset(obj) - - # If we have selected text and the last event was a move to the - # right, then speak the character to the left of where the text - # caret is (i.e. the selected character). - # - eventString, mods = self.utilities.lastKeyAndModifiers() - if (mods & keybindings.SHIFT_MODIFIER_MASK) \ - and eventString in ["Right", "Down"]: - offset -= 1 - - character, startOffset, endOffset = AXText.get_character_at_offset(obj, offset) - cthulhu.emitRegionChanged(obj, startOffset, endOffset, cthulhu.CARET_TRACKING) - - if not character or character == '\r': - character = "\n" - - speakBlankLines = cthulhu.cthulhuApp.settingsManager.getSetting('speakBlankLines') - if character == "\n": - line, _, _ = AXText.get_line_at_offset(obj, max(0, offset)) - if not line or line == "\n": - # This is a blank line. Announce it if the user requested - # that blank lines be spoken. - if speakBlankLines: - self.speakMessage(messages.BLANK, interrupt=False) - return - - if character in ["\n", "\r\n"]: - # This is a blank line. Announce it if the user requested - # that blank lines be spoken. - if speakBlankLines: - self.speakMessage(messages.BLANK, interrupt=False) - return - else: - self.speakMisspelledIndicator(obj, offset) - self.speakCharacter(character) - - self.pointOfReference["lastTextUnitSpoken"] = "char" - - def sayLine(self, obj): - """Speaks the line of an AccessibleText object that contains the - caret, unless the line is empty in which case it's ignored. - - Arguments: - - obj: an Accessible object that implements the AccessibleText - interface - """ - - [line, caretOffset, startOffset] = self.getTextLineAtCaret(obj) - if len(line) and line != "\n": - indentationDescription, hasIndentation = \ - self.utilities.get_indentation_presentation(line, obj=obj) - if indentationDescription: - self.speakMessage(indentationDescription) - stripIndentation = hasIndentation and self.utilities.should_strip_indentation(line) - - endOffset = startOffset + len(line) - cthulhu.emitRegionChanged(obj, startOffset, endOffset, cthulhu.CARET_TRACKING) - - utterance = [] - split = self.utilities.splitSubstringByLanguage(obj, startOffset, endOffset) - for start, end, string, language, dialect in split: - if not string: - continue - - voice = self.speechGenerator.voice( - obj=obj, string=string, language=language, dialect=dialect) - string, linkIcons = self.utilities.getLinkIndicatorPresentation(obj, string, start) - string = self.utilities.adjustForRepeats(string) - if self.utilities.shouldVerbalizeAllPunctuation(obj): - string = self.utilities.verbalizeAllPunctuation(string) - - # Some synthesizers will verbalize the whitespace, so if we've already - # described it, prevent double-presentation by stripping it off. - if not utterance and stripIndentation: - string = string.lstrip() - - result = [string] - result.extend(voice) - result.extend(linkIcons) - utterance.append(result) - speech.speak(utterance) - else: - # Speak blank line if appropriate. - # - self.sayCharacter(obj) - - self.pointOfReference["lastTextUnitSpoken"] = "line" - - def sayPhrase(self, obj, startOffset, endOffset): - """Speaks the text of an Accessible object between the start and - end offsets, unless the phrase is empty in which case it's ignored. - - Arguments: - - obj: an Accessible object that implements the AccessibleText - interface - - startOffset: the start text offset. - - endOffset: the end text offset. - """ - - phrase = self.utilities.expandEOCs(obj, startOffset, endOffset) - if not phrase: - return - - if len(phrase) > 1 or phrase.isalnum(): - indentationDescription, hasIndentation = \ - self.utilities.get_indentation_presentation(phrase, obj=obj) - if indentationDescription: - self.speakMessage(indentationDescription) - - cthulhu.emitRegionChanged(obj, startOffset, endOffset, cthulhu.CARET_TRACKING) - - voice = self.speechGenerator.voice(obj=obj, string=phrase) - if hasIndentation and self.utilities.should_strip_indentation(phrase): - phrase = phrase.lstrip() - phrase = self.utilities.adjustForRepeats(phrase) - if self.utilities.shouldVerbalizeAllPunctuation(obj): - phrase = self.utilities.verbalizeAllPunctuation(phrase) - - utterance = [phrase] - utterance.extend(voice) - speech.speak(utterance) - else: - self.speakCharacter(phrase) - - self.pointOfReference["lastTextUnitSpoken"] = "phrase" - - def sayWord(self, obj): - """Speaks the word at the caret, taking into account the previous caret position.""" - - if not AXObject.supports_text(obj): - self.sayCharacter(obj) - return - - offset = AXText.get_caret_offset(obj) - - word, startOffset, endOffset = \ - self.utilities.getWordAtOffsetAdjustedForNavigation(obj, offset) - - # Announce when we cross a hard line boundary. - if "\n" in word: - if cthulhu.cthulhuApp.settingsManager.getSetting('enableSpeechIndentation'): - self.speakCharacter("\n") - if word.startswith("\n"): - startOffset += 1 - elif word.endswith("\n"): - endOffset -= 1 - word = AXText.get_substring(obj, startOffset, endOffset) - - # sayPhrase is useful because it handles punctuation verbalization, but we don't want - # to trigger its whitespace presentation. - matches = list(re.finditer(r"\S+", word)) - if matches: - startOffset += matches[0].start() - endOffset -= len(word) - matches[-1].end() - word = AXText.get_substring(obj, startOffset, endOffset) - - string = word.replace("\n", "\\n") - msg = ( - f"DEFAULT: Final word at offset {offset} is '{string}' " - f"({startOffset}-{endOffset})" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self.speakMisspelledIndicator(obj, startOffset) - self.sayPhrase(obj, startOffset, endOffset) - self.pointOfReference["lastTextUnitSpoken"] = "word" - - def presentObject(self, obj, **args): - has_interrupt_request = "interrupt" in args - interrupt = self.should_interrupt_for_object_presentation( - args.get("interrupt", False), - args.pop("interrupt_already_handled", False), - ) - if has_interrupt_request: - args["interrupt"] = interrupt - tokens = ["DEFAULT: Presenting object", obj, ". Interrupt:", interrupt] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not args.get("speechonly", False): - self.updateBraille(obj, **args) - utterances = self.speechGenerator.generateSpeech(obj, **args) - speech.speak(utterances, interrupt=interrupt) - - def stopSpeechOnActiveDescendantChanged(self, event): - """Whether or not speech should be stopped prior to setting the - locusOfFocus in onActiveDescendantChanged. - - Arguments: - - event: the Event - - Returns True if speech should be stopped; False otherwise. - """ - - if not event.any_data: - return True - - # In an object which manages its descendants, the - # 'descendants' may really be a single object which changes - # its name. If the name-change occurs followed by the active - # descendant changing (to the same object) we won't present - # the locusOfFocus because it hasn't changed. Thus we need to - # be sure not to cut of the presentation of the name-change - # event. - - if cthulhu_state.locusOfFocus == event.any_data: - names = self.pointOfReference.get('names', {}) - oldName = names.get(hash(cthulhu_state.locusOfFocus), '') - if not oldName or AXObject.get_name(event.any_data) == oldName: - return False - - if event.source == cthulhu_state.locusOfFocus == AXObject.get_parent(event.any_data): - return False - - return True - - def getFlatReviewContext(self): - """Returns the flat review context, creating one if necessary.""" - - return self.flatReviewPresenter.get_or_create_context(self) - - def updateBrailleReview(self, targetCursorCell=0): - """Obtains the braille regions for the current flat review line - and displays them on the braille display. If the targetCursorCell - is non-0, then an attempt will be made to position the review cursor - at that cell. Otherwise, we will pan in display-sized increments - to show the review cursor.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - debug.printMessage(debug.LEVEL_INFO, "BRAILLE: update review disabled", True) - return - - [regions, regionWithFocus] = self.flatReviewPresenter.get_braille_regions(self) - if not regions: - regions = [] - regionWithFocus = None - - line = self.getNewBrailleLine() - self.addBrailleRegionsToLine(regions, line) - braille.setLines([line]) - self.setBrailleFocus(regionWithFocus, False) - if regionWithFocus and not targetCursorCell: - offset = regionWithFocus.brailleOffset + regionWithFocus.cursorOffset - tokens = ["DEFAULT: Update to", offset, "in", regionWithFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.panBrailleToOffset(offset) - - if self.justEnteredFlatReviewMode: - self.refreshBraille(True, self.targetCursorCell) - self.justEnteredFlatReviewMode = False - else: - self.refreshBraille(True, targetCursorCell) - - def _setFlatReviewContextToBeginningOfBrailleDisplay(self): - """Sets the character of interest to be the first character showing - at the beginning of the braille display.""" - - # The first character on the flat review line has to be in object with text. - def isTextOrComponent(x): - return isinstance(x, (braille.ReviewText, braille.ReviewComponent)) - - regions = self.flatReviewPresenter.get_braille_regions(self)[0] - regions = list(filter(isTextOrComponent, regions)) - tokens = ["DEFAULT: Text/Component regions on line:"] - for region in regions: - tokens.extend(["\n", region]) - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # TODO - JD: The current code was stopping on the first region which met the - # following condition. Is that definitely the right thing to do? Assume so for now. - # Also: Should the default script be accessing things like the viewport directly?? - def isMatch(x): - return x is not None and x.brailleOffset + len(x.string) > braille.viewport[0] - - regions = list(filter(isMatch, regions)) - if not regions: - msg = "DEFAULT: Could not find review region to move to start of display" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - tokens = ["DEFAULT: Candidates for start of display:"] - for region in regions: - tokens.extend(["\n", region]) - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - - # TODO - JD: Again, for now we're preserving the original behavior of choosing the first. - region = regions[0] - position = max(region.brailleOffset, braille.viewport[0]) - if region.contracted: - offset = region.inPos[position - region.brailleOffset] - else: - offset = position - region.brailleOffset - if isinstance(region.zone, flat_review.TextZone): - offset += region.zone.startOffset - msg = f"DEFAULT: Offset for region: {offset}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - [word, charOffset] = region.zone.getWordAtOffset(offset) - if word: - tokens = ["DEFAULT: Setting start of display to", word, ", ", charOffset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - context = self.getFlatReviewContext() - context.setCurrent( - word.zone.line.index, - word.zone.index, - word.index, - charOffset) - else: - tokens = ["DEFAULT: Setting start of display to", region.zone] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - context = self.getFlatReviewContext() - context.setCurrent( - region.zone.line.index, - region.zone.index, - 0, # word index - 0) # character index - - def find(self, query=None): - """Searches for the specified query. If no query is specified, - it searches for the query specified in the Cthulhu Find dialog. - - Arguments: - - query: The search query to find. - """ - - if not query: - query = find.getLastQuery() - if query: - context = self.getFlatReviewContext() - location = query.findQuery(context) - if not location: - self.presentMessage(messages.STRING_NOT_FOUND) - else: - context.setCurrent(location.lineIndex, location.zoneIndex, \ - location.wordIndex, location.charIndex) - self.flatReviewPresenter.present_item(self) - self.targetCursorCell = self.getBrailleCursorCell() - - def textLines(self, obj, offset=None): - """Creates a generator that can be used to iterate over each line - of a text object, starting at the caret offset. - - Arguments: - - obj: an Accessible that has a text specialization - - Returns an iterator that produces elements of the form: - [SayAllContext, acss], where SayAllContext has the text to be - spoken and acss is an ACSS instance for speaking the text. - """ - - self._sayAllIsInterrupted = False - if not AXObject.supports_text(obj): - self._inSayAll = False - self._sayAllContexts = [] - return - - self._inSayAll = True - length = AXText.get_character_count(obj) - if offset is None: - offset = AXText.get_caret_offset(obj) - - # Determine the correct "say all by" mode to use. - # - sayAllStyle = cthulhu.cthulhuApp.settingsManager.getSetting('sayAllStyle') - if sayAllStyle == settings.SAYALL_STYLE_SENTENCE: - mode = "sentence" - elif sayAllStyle == settings.SAYALL_STYLE_LINE: - mode = "line" - else: - mode = "line" - - priorObj = obj - - # Get the next line of text to read - # - done = False - while not done: - speech.speak(self.speechGenerator.generateContext(obj, priorObj=priorObj)) - - lastEndOffset = -1 - while offset < length: - if mode == "sentence": - lineString, startOffset, endOffset = AXText.get_sentence_at_offset(obj, offset) - else: - lineString, startOffset, endOffset = AXText.get_line_at_offset(obj, offset) - - # Some applications that don't support sentence boundaries - # will provide the line boundary results instead; others - # will return nothing. - # - if not lineString: - mode = "line" - lineString, startOffset, endOffset = AXText.get_line_at_offset(obj, offset) - - if endOffset > length: - tokens = ["DEFAULT: end offset", endOffset, " > character count", - length, - "resulting from getTextAtOffset(", offset, mode, ") for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - endOffset = length - - # [[[WDW - HACK: this is here because getTextAtOffset - # tends not to be implemented consistently across toolkits. - # Sometimes it behaves properly (i.e., giving us an endOffset - # that is the beginning of the next line), sometimes it - # doesn't (e.g., giving us an endOffset that is the end of - # the current line). So...we hack. The whole 'max' deal - # is to account for lines that might be a brazillion lines - # long.]]] - # - if endOffset == lastEndOffset: - offset = max(offset + 1, lastEndOffset + 1) - lastEndOffset = endOffset - continue - - lastEndOffset = endOffset - offset = endOffset - - voice = self.speechGenerator.voice(obj=obj, string=lineString) - if voice and isinstance(voice, list): - voice = voice[0] - - lineString = \ - self.utilities.adjustForLinks(obj, lineString, startOffset) - lineString = self.utilities.adjustForRepeats(lineString) - - context = speechserver.SayAllContext( - obj, lineString, startOffset, endOffset) - tokens = ["DEFAULT:", context] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._sayAllContexts.append(context) - self.eventSynthesizer.scroll_into_view(obj, startOffset, endOffset) - yield [context, voice] - - moreLines = False - flowsTo = AXUtilitiesRelation.get_flows_to(obj) - if flowsTo: - priorObj = obj - obj = flowsTo[0] - - if not AXObject.supports_text(obj): - return - - length = AXText.get_character_count(obj) - offset = 0 - moreLines = True - break - if not moreLines: - done = True - - self._inSayAll = False - self._sayAllContexts = [] - - msg = "DEFAULT: textLines complete. Verifying SayAll status" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.inSayAll() - - def getTextLineAtCaret(self, obj, offset=None, startOffset=None, endOffset=None): - """To-be-removed. Returns the string, caretOffset, startOffset.""" - - if not AXObject.supports_text(obj): - return ["", 0, 0] - - offset = AXText.get_caret_offset(obj) - characterCount = AXText.get_character_count(obj) - if characterCount == 0: - return ["", 0, 0] - - if startOffset is not None and endOffset is not None: - return [AXText.get_substring(obj, startOffset, endOffset), offset, startOffset] - - targetOffset = startOffset - if targetOffset is None: - targetOffset = max(0, offset) - - if targetOffset == characterCount: - fixedTargetOffset = max(0, targetOffset - 1) - character, _, _ = AXText.get_character_at_offset(obj, fixedTargetOffset) - else: - fixedTargetOffset = targetOffset - character = None - - if (targetOffset == characterCount) and (character == "\n"): - lineString = "" - startOffset = fixedTargetOffset - else: - if characterCount == 1: - lineString = AXText.get_substring(obj, fixedTargetOffset, fixedTargetOffset + 1) - startOffset = fixedTargetOffset - else: - if fixedTargetOffset == -1: - fixedTargetOffset = characterCount - lineString, startOffset, endOffset = AXText.get_line_at_offset(obj, fixedTargetOffset) - - if 0 <= fixedTargetOffset < startOffset: - backup_offset = fixedTargetOffset - 1 - tokens = [f"DEFAULT: Start offset {startOffset} is greater than target offset {fixedTargetOffset}. Trying with offset {backup_offset}"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - lineString, startOffset, endOffset = AXText.get_line_at_offset(obj, backup_offset) - - lineString = lineString.rstrip('\n') - lineString = lineString.rstrip('\r') - - return [lineString, offset, startOffset] - - def phoneticSpellCurrentItem(self, itemString): - """Phonetically spell the current flat review word or line. - - Arguments: - - itemString: the string to phonetically spell. - """ - - for (charIndex, character) in enumerate(itemString): - voice = self.speechGenerator.voice(string=character) - phoneticString = phonnames.getPhoneticName(character.lower()) - self.speakMessage(phoneticString, voice) - - def _saveLastCursorPosition(self, obj, caretOffset): - """Save away the current text cursor position for next time. - - Arguments: - - obj: the current accessible - - caretOffset: the cursor position within this object - """ - - prevObj, prevOffset = self.pointOfReference.get("lastCursorPosition", (None, -1)) - self.pointOfReference["penultimateCursorPosition"] = prevObj, prevOffset - self.pointOfReference["lastCursorPosition"] = obj, caretOffset - - def systemBeep(self): - """Rings the system bell. This is really a hack. Ideally, we want - a method that will present an earcon (any sound designated for the - purpose of representing an error, event etc) - """ - - print("\a") - - def speakMisspelledIndicator(self, obj, offset): - """Speaks an announcement indicating that a given word is misspelled. - - Arguments: - - obj: An accessible which implements the accessible text interface. - - offset: Offset in the accessible's text for which to retrieve the - attributes. - """ - - if cthulhu.cthulhuApp.settingsManager.getSetting('speakMisspelledIndicator'): - if not AXObject.supports_text(obj): - return - # If we're on whitespace, we cannot be on a misspelled word. - # - char, _, _ = AXText.get_character_at_offset(obj, offset) - if not char.strip() or self.utilities.isWordDelimiter(char): - self._lastWordCheckedForSpelling = char - return - - word, _, _ = AXText.get_word_at_offset(obj, offset) - if self.utilities.isWordMisspelled(obj, offset) \ - and word != self._lastWordCheckedForSpelling: - self.speakMessage(messages.MISSPELLED) - # Store this word so that we do not continue to present the - # presence of the red squiggly as the user arrows amongst - # the characters. - # - self._lastWordCheckedForSpelling = word - - ############################################################################ - # # - # Presentation methods # - # (scripts should not call methods in braille.py or speech.py directly) # - # # - ############################################################################ - - def presentationInterrupt(self): - """Convenience method to interrupt presentation of whatever is being - presented at the moment.""" - - msg = "DEFAULT: Interrupting presentation" - debug.printMessage(debug.LEVEL_INFO, msg, True) - speech.stop() - braille.killFlash() - - def interrupt_presentation_for_focus_change( - self, - oldFocus: object, - newFocus: object, - event: object | None = None, - ) -> None: - """Interrupts presentation when a focus change requires it.""" - - if self.utilities.shouldInterruptForLocusOfFocusChange(oldFocus, newFocus, event): - self.presentationInterrupt() - - def should_interrupt_for_object_presentation( - self, - requested: bool, - already_handled: bool = False, - ) -> bool: - """Returns whether object presentation should interrupt prior output.""" - - if requested and already_handled: - msg = "DEFAULT: Object presentation interruption already handled by input dispatch" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - return requested - - def should_interrupt_for_mode_announcement( - self, - requested: bool, - already_handled: bool = False, - ) -> bool: - """Returns whether a mode announcement should interrupt prior output.""" - - if requested and already_handled: - msg = "DEFAULT: Mode announcement interruption already handled by input dispatch" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - return requested - - def presentKeyboardEvent(self, event): - """Convenience method to present the KeyboardEvent event. Returns True - if we fully present the event; False otherwise.""" - - if not event.is_pressed_key(): - self._sayAllIsInterrupted = False - self.utilities.clearCachedCommandState() - - if not event.shouldEcho or event.isCthulhuModified(): - return False - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableKeyEcho'): - return False - - role = AXObject.get_role(cthulhu_state.locusOfFocus) - if role in [Atspi.Role.DIALOG, Atspi.Role.FRAME, Atspi.Role.WINDOW]: - focusedObject = AXUtilities.get_focused_object(cthulhu_state.activeWindow) - if focusedObject: - cthulhu.setLocusOfFocus(None, focusedObject, False) - role = AXObject.get_role(focusedObject) - - if role == Atspi.Role.PASSWORD_TEXT and not event.isLockingKey(): - return False - - if not event.is_pressed_key(): - return False - - braille.displayKeyEvent(event) - cthulhuModifierPressed = event.isCthulhuModifier() and event.is_pressed_key() - if event.isCharacterEchoable() and not cthulhuModifierPressed: - return False - - msg = "DEFAULT: Presenting keyboard event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.speakKeyEvent(event) - return True - - def presentMessage(self, fullMessage, briefMessage=None, voice=None, resetStyles=True, - force=False, interrupt=False): - """Convenience method to speak a message and 'flash' it in braille. - - Arguments: - - fullMessage: This can be a string or a list. This will be presented - as the message for users whose flash or message verbosity level is - verbose. - - briefMessage: This can be a string or a list. This will be presented - as the message for users whose flash or message verbosity level is - brief. Note that providing no briefMessage will result in the full - message being used for either. Callers wishing to present nothing as - the briefMessage should set briefMessage to an empty string. - - voice: The voice to use when speaking this message. By default, the - "system" voice will be used. - - interrupt: If True, any current speech should be interrupted - prior to speaking the new text. The default queues the message. - """ - - if not fullMessage: - return - - if briefMessage is None: - briefMessage = fullMessage - - if cthulhu.cthulhuApp.settingsManager.getSetting('enableSpeech'): - if not cthulhu.cthulhuApp.settingsManager.getSetting('messagesAreDetailed'): - message = briefMessage - else: - message = fullMessage - if message: - self.speakMessage( - message, - voice=voice, - interrupt=interrupt, - resetStyles=resetStyles, - force=force, - ) - - if (cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - or cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor')) \ - and cthulhu.cthulhuApp.settingsManager.getSetting('enableFlashMessages'): - if not cthulhu.cthulhuApp.settingsManager.getSetting('flashIsDetailed'): - message = briefMessage - else: - message = fullMessage - if not message: - return - - if isinstance(message[0], list): - message = message[0] - if isinstance(message, list): - message = [i for i in message if isinstance(i, str)] - message = " ".join(message) - - if cthulhu.cthulhuApp.settingsManager.getSetting('flashIsPersistent'): - duration = -1 - else: - duration = cthulhu.cthulhuApp.settingsManager.getSetting('brailleFlashTime') - - braille.displayMessage(message, flashTime=duration) - - def idleMessage(self): - """Convenience method to tell speech and braille engines to hand off - control to other screen readers.""" - - braille.disableBraille() - - @staticmethod - def __play(sounds, interrupt=True): - if not sounds: - return - - if not isinstance(sounds, list): - sounds = [sounds] - - _player = sound.getPlayer() - _player.play(sounds[0], interrupt) - for i in range(1, len(sounds)): - sound.play(sounds[i], interrupt=False) - - @staticmethod - def addBrailleRegionToLine(region, line): - """Adds the braille region to the line. - - Arguments: - - region: a braille.Region (e.g. what is returned by the braille - generator's generateBraille() method. - - line: a braille.Line - """ - - line.addRegion(region) - - @staticmethod - def addBrailleRegionsToLine(regions, line): - """Adds the braille region to the line. - - Arguments: - - regions: a series of braille.Region instances (a single instance - being what is returned by the braille generator's generateBraille() - method. - - line: a braille.Line - """ - - line.addRegions(regions) - - @staticmethod - def addToLineAsBrailleRegion(string, line): - """Creates a Braille Region out of string and adds it to the line. - - Arguments: - - string: the string to be displayed - - line: a braille.Line - """ - - line.addRegion(braille.Region(string)) - - @staticmethod - def brailleRegionsFromStrings(strings): - """Creates a list of braille regions from the list of strings. - - Arguments: - - strings: a list of strings from which to create the list of - braille Region instances - - Returns the list of braille Region instances - """ - - brailleRegions = [] - for string in strings: - brailleRegions.append(braille.Region(string)) - - return brailleRegions - - @staticmethod - def clearBraille(): - """Clears the logical structure, but keeps the Braille display as is - (until a refresh operation).""" - - braille.clear() - - @staticmethod - def displayBrailleMessage(message, cursor=-1, flashTime=0): - """Displays a single line, setting the cursor to the given position, - ensuring that the cursor is in view. - - Arguments: - - message: the string to display - - cursor: the 0-based cursor position, where -1 (default) means no - cursor - - flashTime: if non-0, the number of milliseconds to display the - regions before reverting back to what was there before. A 0 means - to not do any flashing. A negative number means to display the - message until some other message comes along or the user presses - a cursor routing key. - """ - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - debug.printMessage(debug.LEVEL_INFO, "BRAILLE: display message disabled", True) - return - - braille.displayMessage(message, cursor, flashTime) - - @staticmethod - def displayBrailleRegions(regionInfo, flashTime=0): - """Displays a list of regions on a single line, setting focus to the - specified region. The regionInfo parameter is something that is - typically returned by a call to braille_generator.generateBraille. - - Arguments: - - regionInfo: a list where the first element is a list of regions - to display and the second element is the region with focus (must - be in the list from element 0) - - flashTime: if non-0, the number of milliseconds to display the - regions before reverting back to what was there before. A 0 means - to not do any flashing. A negative number means to display the - message until some other message comes along or the user presses - a cursor routing key. - """ - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - debug.printMessage(debug.LEVEL_INFO, "BRAILLE: display regions disabled", True) - return - - braille.displayRegions(regionInfo, flashTime) - - def displayBrailleForObject(self, obj): - """Convenience method for scripts combining the call to the braille - generator for the script with the call to displayBrailleRegions. - - Arguments: - - obj: the accessible object to display in braille - """ - - regions = self.brailleGenerator.generateBraille(obj) - self.displayBrailleRegions(regions) - - @staticmethod - def getBrailleCaretContext(event): - """Gets the accesible and caret offset associated with the given - event. The event should have a BrlAPI event that contains an - argument value that corresponds to a cell on the display. - - Arguments: - - event: an instance of input_event.BrailleEvent. event.event is - the dictionary form of the expanded BrlAPI event. - """ - - return braille.getCaretContext(event) - - @staticmethod - def getBrailleCursorCell(): - """Returns the value of position of the braille cell which has the - cursor. A value of 0 means no cell has the cursor.""" - - return braille.cursorCell - - @staticmethod - def getNewBrailleLine(clearBraille=False, addLine=False): - """Creates a new braille Line. - - Arguments: - - clearBraille: Whether the display should be cleared. - - addLine: Whether the line should be added to the logical display - for painting. - - Returns the new Line. - """ - - if clearBraille: - braille.clear() - line = braille.Line() - if addLine: - braille.addLine(line) - - return line - - @staticmethod - def getNewBrailleComponent(accessible, string, cursorOffset=0, - indicator='', expandOnCursor=False): - """Creates a new braille Component. - - Arguments: - - accessible: the accessible associated with this region - - string: the string to be displayed - - cursorOffset: a 0-based index saying where to draw the cursor - for this Region if it gets focus - - Returns the new Component. - """ - - return braille.Component(accessible, string, cursorOffset, - indicator, expandOnCursor) - - @staticmethod - def getNewBrailleRegion(string, cursorOffset=0, expandOnCursor=False): - """Creates a new braille Region. - - Arguments: - - string: the string to be displayed - - cursorOffset: a 0-based index saying where to draw the cursor - for this Region if it gets focus - - Returns the new Region. - """ - - return braille.Region(string, cursorOffset, expandOnCursor) - - @staticmethod - def getNewBrailleText(accessible, label="", eol="", startOffset=None, - endOffset=None): - - """Creates a new braille Text region. - - Arguments: - - accessible: the accessible associated with this region and which - implements AtkText - - label: an optional label to display - - eol: the endOfLine indicator - - Returns the new Text region. - """ - - return braille.Text(accessible, label, eol, startOffset, endOffset) - - @staticmethod - def isBrailleBeginningShowing(): - """If True, the beginning of the line is showing on the braille - display.""" - - return braille.beginningIsShowing - - @staticmethod - def isBrailleEndShowing(): - """If True, the end of the line is showing on the braille display.""" - - return braille.endIsShowing - - @staticmethod - def panBrailleInDirection(panAmount=0, panToLeft=True): - """Pans the display to the left, limiting the pan to the beginning - of the line being displayed. - - Arguments: - - panAmount: the amount to pan. A value of 0 means the entire - width of the physical display. - - panToLeft: if True, pan to the left; otherwise to the right - - Returns True if a pan actually happened. - """ - - if panToLeft: - return braille.panLeft(panAmount) - else: - return braille.panRight(panAmount) - - @staticmethod - def panBrailleToOffset(offset): - """Automatically pan left or right to make sure the current offset - is showing.""" - - braille.panToOffset(offset) - - @staticmethod - def presentItemsInBraille(items): - """Method to braille a list of items. Scripts should call this - method rather than handling the creation and displaying of a - braille line directly. - - Arguments: - - items: a list of strings to be presented - """ - - line = braille.getShowingLine() - for item in items: - line.addRegion(braille.Region(" " + item)) - - braille.refresh() - - def updateBrailleForNewCaretPosition(self, obj): - """Try to reposition the cursor without having to do a full update.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - debug.printMessage(debug.LEVEL_INFO, "BRAILLE: update caret disabled", True) - return - - brailleNeedsRepainting = True - line = braille.getShowingLine() - for region in line.regions: - if isinstance(region, braille.Text) and region.accessible == obj: - if region.repositionCursor(): - self.refreshBraille(True) - brailleNeedsRepainting = False - break - - if brailleNeedsRepainting: - self.updateBraille(obj) - - @staticmethod - def refreshBraille(panToCursor=True, targetCursorCell=0, getLinkMask=True, - stopFlash=True): - """This is the method scripts should use to refresh braille rather - than calling self.refreshBraille() directly. The intent is to centralize - such calls into as few places as possible so that we can easily and - safely not perform braille-related functions for users who do not - have braille and/or the braille monitor enabled. - - Arguments: - - - panToCursor: if True, will adjust the viewport so the cursor is - showing. - - targetCursorCell: Only effective if panToCursor is True. - 0 means automatically place the cursor somewhere on the display so - as to minimize movement but show as much of the line as possible. - A positive value is a 1-based target cell from the left side of - the display and a negative value is a 1-based target cell from the - right side of the display. - - getLinkMask: Whether or not we should take the time to get the - attributeMask for links. Reasons we might not want to include - knowing that we will fail and/or it taking an unreasonable - amount of time (AKA Gecko). - - stopFlash: if True, kill any flashed message that may be showing. - """ - - braille.refresh(panToCursor, targetCursorCell, getLinkMask, stopFlash) - - @staticmethod - def setBrailleFocus(region, panToFocus=True, getLinkMask=True): - """Specififes the region with focus. This region will be positioned - at the home position if panToFocus is True. - - Arguments: - - region: the given region, which much be in a line that has been - added to the logical display - - panToFocus: whether or not to position the region at the home - position - - getLinkMask: Whether or not we should take the time to get the - attributeMask for links. Reasons we might not want to include - knowing that we will fail and/or it taking an unreasonable - amount of time (AKA Gecko). - """ - - braille.setFocus(region, panToFocus, getLinkMask) - - @staticmethod - def _setContractedBraille(event): - """Turns contracted braille on or off based upon the event. - - Arguments: - - event: an instance of input_event.BrailleEvent. event.event is - the dictionary form of the expanded BrlAPI event. - """ - - braille.setContractedBraille(event) - - ######################################################################## - # # - # Speech methods # - # (scripts should not call methods in speech.py directly) # - # # - ######################################################################## - - def _shouldUseCustomEchoVoice(self, echoType): - """Returns True if custom echo settings should be used for the given type.""" - - settingForType = { - "key": "useCustomEchoForKey", - "character": "useCustomEchoForCharacter", - "word": "useCustomEchoForWord", - "sentence": "useCustomEchoForSentence", - } - - settingName = settingForType.get(echoType) - if not settingName: - return False - - settingsManager = cthulhu.cthulhuApp.settingsManager - if not settingsManager.getSetting("enableKeyEcho"): - return False - - if not settingsManager.getSetting("useCustomEchoVoice"): - return False - - return settingsManager.getSetting(settingName) - - def _getCustomEchoVoice(self): - """Returns the effective ACSS voice for custom echo output.""" - - settingsManager = cthulhu.cthulhuApp.settingsManager - voices = settingsManager.getSetting("voices") or {} - defaultVoice = acss.ACSS(voices.get(settings.DEFAULT_VOICE, {})) - - echoVoice = settingsManager.getSetting("echoVoice") - if not echoVoice: - return defaultVoice - - try: - defaultVoice.update(acss.ACSS(echoVoice)) - except Exception: - debug.printException(debug.LEVEL_INFO) - - return defaultVoice - - def speakKeyEvent(self, event): - """Method to speak a keyboard event. Scripts should use this method - rather than calling speech.speakKeyEvent directly.""" - - string = None - if event.is_printable_key(): - string = event.event_string - - if self._shouldUseCustomEchoVoice("key"): - speech.speakEchoKeyEvent(event, self._getCustomEchoVoice()) - return - - voice = self.speechGenerator.voice(string=string) - speech.speakKeyEvent(event, voice) - - def speakCharacter(self, character): - """Method to speak a single character. Scripts should use this - method rather than calling speech.speakCharacter directly.""" - - if self._shouldUseCustomEchoVoice("character"): - speech.speakEchoCharacter(character, self._getCustomEchoVoice()) - return - - voice = self.speechGenerator.voice(string=character) - speech.speakCharacter(character, voice) - - def speakMessage(self, string, voice=None, interrupt=False, resetStyles=True, force=False): - """Method to speak a single string. Scripts should use this - method rather than calling speech.speak directly. - - - string: The string to be spoken. - - voice: The voice to use. By default, the "system" voice will - be used. - - interrupt: If True, any current speech should be interrupted - prior to speaking the new text. The default queues the message. - """ - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableSpeech') \ - or (cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText') and not force): - return - - voices = cthulhu.cthulhuApp.settingsManager.getSetting('voices') - systemVoice = voices.get(settings.SYSTEM_VOICE) - - voice = voice or systemVoice - if voice == systemVoice and resetStyles: - capStyle = cthulhu.cthulhuApp.settingsManager.getSetting('capitalizationStyle') - cthulhu.cthulhuApp.settingsManager.setSetting('capitalizationStyle', settings.CAPITALIZATION_STYLE_NONE) - self.speechAndVerbosityManager.update_capitalization_style() - - punctStyle = cthulhu.cthulhuApp.settingsManager.getSetting('verbalizePunctuationStyle') - cthulhu.cthulhuApp.settingsManager.setSetting('verbalizePunctuationStyle', - settings.PUNCTUATION_STYLE_NONE) - self.speechAndVerbosityManager.update_punctuation_level() - - speech.speak(string, voice, interrupt) - - if voice == systemVoice and resetStyles: - cthulhu.cthulhuApp.settingsManager.setSetting('capitalizationStyle', capStyle) - self.speechAndVerbosityManager.update_capitalization_style() - - cthulhu.cthulhuApp.settingsManager.setSetting('verbalizePunctuationStyle', punctStyle) - self.speechAndVerbosityManager.update_punctuation_level() - - @staticmethod - def presentItemsInSpeech(items): - """Method to speak a list of items. Scripts should call this - method rather than handling the creation and speaking of - utterances directly. - - Arguments: - - items: a list of strings to be presented - """ - - utterances = [] - for item in items: - utterances.append(item) - - speech.speak(utterances) - - def speakUnicodeCharacter(self, character): - """ Speaks some information about an unicode character. - At the moment it just announces the character unicode number but - this information may be changed in the future - - Arguments: - - character: the character to speak information of - """ - speech.speak(messages.UNICODE % \ - self.utilities.unicodeValueString(character)) diff --git a/src/cthulhu/scripts/meson.build b/src/cthulhu/scripts/meson.build deleted file mode 100644 index 0bb71ee..0000000 --- a/src/cthulhu/scripts/meson.build +++ /dev/null @@ -1,17 +0,0 @@ -scripts_python_sources = files([ - '__init__.py', - 'default.py', - 'self_voicing.py', -]) - -python3.install_sources( - scripts_python_sources, - subdir: 'cthulhu/scripts' -) - -subdir('apps') -subdir('toolkits') -subdir('sleepmode') -subdir('switcher') -subdir('terminal') -subdir('web') \ No newline at end of file diff --git a/src/cthulhu/scripts/self_voicing.py b/src/cthulhu/scripts/self_voicing.py deleted file mode 100644 index 20f0dc7..0000000 --- a/src/cthulhu/scripts/self_voicing.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""A script to do nothing. This is for self-voicing apps.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -import cthulhu.scripts.default as default - -class Script(default.Script): - """A script to do nothing. This is for self-voicing apps.""" - - def __init__(self, app): - """Creates a script for the given application, if necessary. - This method should not be called by anyone except the - script manager. - - Arguments: - - app: the Python Accessible application to create a script for - """ - - default.Script.__init__(self, app) - - def getBrailleGenerator(self): - """Returns the braille generator for this script. - """ - return None - - def getSpeechGenerator(self): - """Returns the speech generator for this script. - """ - return None - - def processObjectEvent(self, event): - """Does nothing. - - Arguments: - - event: the Event - """ - pass - - def processBrailleEvent(self, brailleEvent): - """Does nothing. - - Arguments: - - brailleEvent: an instance of input_event.BrailleEvent - - Returns False to indicate the event was not consumed. - """ - return False diff --git a/src/cthulhu/scripts/sleepmode/__init__.py b/src/cthulhu/scripts/sleepmode/__init__.py deleted file mode 100644 index bb5107e..0000000 --- a/src/cthulhu/scripts/sleepmode/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Sleep mode script for Cthulhu.""" - -from .script import Script, get_script - -# Ensure get_script is available at module level -__all__ = ['Script', 'get_script'] \ No newline at end of file diff --git a/src/cthulhu/scripts/sleepmode/braille_generator.py b/src/cthulhu/scripts/sleepmode/braille_generator.py deleted file mode 100644 index 4edf484..0000000 --- a/src/cthulhu/scripts/sleepmode/braille_generator.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Braille Generator for Sleep Mode. Does nothing.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.braille_generator as braille_generator - -class BrailleGenerator(braille_generator.BrailleGenerator): - """Braille Generator for Sleep Mode. Does nothing.""" - - def generateBraille(self, obj, **args): - """Generates braille for the given object. Returns empty list in sleep mode.""" - msg = "SLEEP MODE BRAILLE GENERATOR: Generating nothing." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return [] \ No newline at end of file diff --git a/src/cthulhu/scripts/sleepmode/meson.build b/src/cthulhu/scripts/sleepmode/meson.build deleted file mode 100644 index aa90dfb..0000000 --- a/src/cthulhu/scripts/sleepmode/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -sleepmode_python_sources = files([ - '__init__.py', - 'braille_generator.py', - 'script.py', - 'script_utilities.py', - 'speech_generator.py', -]) - -python3.install_sources( - sleepmode_python_sources, - subdir: 'cthulhu/scripts/sleepmode' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/sleepmode/script.py b/src/cthulhu/scripts/sleepmode/script.py deleted file mode 100644 index 3a684e5..0000000 --- a/src/cthulhu/scripts/sleepmode/script.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Script for sleep mode where Cthulhu ignores events and commands. - -This script is now a minimal implementation that relies on the global -sleep mode flag in cthulhu_state.sleepMode to block speech and braille -at the system level. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import cthulhu.scripts.default as default -import cthulhu.debug as debug -import cthulhu.cthulhu_modifier_manager as cthulhu_modifier_manager -import cthulhu.sleep_mode_manager as sleep_mode_manager - -class Script(default.Script): - """The sleep mode script. - - This script now relies on the global sleep mode flag for blocking - speech and braille output at the system level. It only handles - keybinding management and basic event blocking. - """ - - def __init__(self, app): - super().__init__(app) - - def activate(self): - """Called when this script is activated.""" - - debug.printMessage(debug.LEVEL_INFO, "SLEEP MODE SCRIPT: Activating", True) - super().activate() - cthulhu_modifier_manager.getManager().unsetCthulhuModifiers("Entering sleep mode.") - - # Get the manager and add its bindings and handlers - manager = sleep_mode_manager.getManager() - managerBindings = manager.getBindings() - if hasattr(managerBindings, 'keyBindings'): - for binding in managerBindings.keyBindings: - self.keyBindings.add(binding) - self.inputEventHandlers.update(manager.getHandlers()) - - # Remove most key grabs except sleep mode toggle - self.removeKeyGrabs() - - debug.printMessage(debug.LEVEL_INFO, "SLEEP MODE SCRIPT: Activated successfully", True) - - def deactivate(self): - """Called when this script is deactivated.""" - - debug.printMessage(debug.LEVEL_INFO, "SLEEP MODE SCRIPT: Deactivating", True) - cthulhu_modifier_manager.getManager().refreshCthulhuModifiers("Exiting sleep mode.") - - super().deactivate() - - def removeKeyGrabs(self): - """Remove key grabs except for sleep mode toggle.""" - - try: - # First remove all grabs inherited from default activation, - # including modifier grabs. - super().removeKeyGrabs() - - self.grab_ids = [] - for keyBinding in self.keyBindings.keyBindings: - if hasattr(keyBinding, 'handler') and hasattr(keyBinding.handler, 'function'): - if hasattr(keyBinding.handler.function, '__name__'): - if 'toggleSleepMode' in keyBinding.handler.function.__name__: - # Keep sleep mode toggle - try: - import cthulhu - grabIds = cthulhu.addKeyGrab(keyBinding) - if grabIds: - for grabId in grabIds: - self.grab_ids.append(grabId) - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Kept sleep toggle key grab: {grabId}", True) - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Error keeping key grab: {e}", True) - else: - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Skipping key grab for {keyBinding.handler.function.__name__}", True) - - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Error in removeKeyGrabs: {e}", True) - - # Block common event handlers as an additional layer of protection - def onCaretMoved(self, event): - """Block caret movement events.""" - debug.printMessage(debug.LEVEL_INFO, "SLEEP MODE: Blocking onCaretMoved", True) - return True - - def onTextDeleted(self, event): - """Block text deletion events.""" - debug.printMessage(debug.LEVEL_INFO, "SLEEP MODE: Blocking onTextDeleted", True) - return True - - def onTextInserted(self, event): - """Block text insertion events.""" - debug.printMessage(debug.LEVEL_INFO, "SLEEP MODE: Blocking onTextInserted", True) - return True - - def onFocusChanged(self, event): - """Block focus change events.""" - debug.printMessage(debug.LEVEL_INFO, "SLEEP MODE: Blocking onFocusChanged", True) - return True - - def onWindowActivated(self, event): - """Block window activation events.""" - debug.printMessage(debug.LEVEL_INFO, "SLEEP MODE: Blocking onWindowActivated", True) - return True - - -def get_script(app): - """Returns the script for the given application.""" - return Script(app) diff --git a/src/cthulhu/scripts/sleepmode/script_utilities.py b/src/cthulhu/scripts/sleepmode/script_utilities.py deleted file mode 100644 index 0744a41..0000000 --- a/src/cthulhu/scripts/sleepmode/script_utilities.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Utilities for Sleep Mode. Helps ensure we do nothing. When nothing is done, nothing is left undone.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.script_utilities as script_utilities - -class Utilities(script_utilities.Utilities): - """Utilities class for the sleep-mode script.""" - - def willEchoCharacter(self, event): - """Returns True if we'll echo this character.""" - - msg = "SLEEP MODE: Will not echo character." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - def displayRegionChanged(self, obj, start, end, mode): - """Don't track changes in sleep mode.""" - - msg = "SLEEP MODE: Will not track display changes." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - def shouldPresentContext(self): - """Don't present context in sleep mode.""" - - msg = "SLEEP MODE: Will not present context." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False diff --git a/src/cthulhu/scripts/sleepmode/speech_generator.py b/src/cthulhu/scripts/sleepmode/speech_generator.py deleted file mode 100644 index 37da1df..0000000 --- a/src/cthulhu/scripts/sleepmode/speech_generator.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2023 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Speech Generator for Sleep Mode. Does nothing.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.speech_generator as speech_generator - -class SpeechGenerator(speech_generator.SpeechGenerator): - """Speech Generator for Sleep Mode. Does nothing.""" - - def generateSpeech(self, obj, **args): - """Generates speech for the given object. Returns empty list in sleep mode.""" - msg = "SLEEP MODE SPEECH GENERATOR: Generating nothing." - debug.printMessage(debug.LEVEL_INFO, msg, True) - print("DEBUG: SLEEP MODE SPEECH GENERATOR CALLED!") - return [] - - def generateSelectedItems(self, obj, **args): - """Override selected items generation.""" - msg = "SLEEP MODE SPEECH GENERATOR: generateSelectedItems - generating nothing." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return [] - - def generateContext(self, obj, **args): - """Override context generation.""" - msg = "SLEEP MODE SPEECH GENERATOR: generateContext - generating nothing." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return [] - - def generateTitle(self, obj, **args): - """Override title generation.""" - msg = "SLEEP MODE SPEECH GENERATOR: generateTitle - generating nothing." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return [] \ No newline at end of file diff --git a/src/cthulhu/scripts/switcher/__init__.py b/src/cthulhu/scripts/switcher/__init__.py deleted file mode 100644 index 348807d..0000000 --- a/src/cthulhu/scripts/switcher/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for basic switchers like Metacity.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script -from .script_utilities import Utilities diff --git a/src/cthulhu/scripts/switcher/meson.build b/src/cthulhu/scripts/switcher/meson.build deleted file mode 100644 index 3f288bd..0000000 --- a/src/cthulhu/scripts/switcher/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -switcher_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - switcher_python_sources, - subdir: 'cthulhu/scripts/switcher' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/switcher/script.py b/src/cthulhu/scripts/switcher/script.py deleted file mode 100644 index e3e40a7..0000000 --- a/src/cthulhu/scripts/switcher/script.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for basic switchers like Metacity.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2019 Igalia, S.L." -__license__ = "LGPL" - -from cthulhu import debug -from cthulhu import cthulhu -from cthulhu.scripts import default - -from .script_utilities import Utilities - - -class Script(default.Script): - - def __init__(self, app): - """Creates a new script for the given application.""" - - super().__init__(app) - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def forceScriptActivation(self, event): - """Allows scripts to insist that they should become active.""" - - if self.utilities.isSwitcherSelectionChangeEventType(event): - return True - - return super().forceScriptActivation(event) - - def _handleSwitcherEvent(self, event): - """Presents the currently selected item, if appropriate.""" - - if not self.utilities.isSwitcherContainer(event.source): - msg = "SWITCHER: Event is not from switcher container" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if not self.utilities.isSwitcherSelectionChangeEventType(event): - msg = "SWITCHER: Not treating event as selection change." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - msg = "SWITCHER: Treating event as selection change" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self.presentationInterrupt() - cthulhu.setActiveWindow(self.utilities.topLevelObject(event.source)) - cthulhu.setLocusOfFocus(event, event.source, False) - self.presentMessage(self.utilities.getSelectionName(event.source), - resetStyles=False, force=True) - return True - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if self._handleSwitcherEvent(event): - return - - super().onFocusedChanged(event) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - if self._handleSwitcherEvent(event): - return - - super().onNameChanged(event) - - def onSelectedChanged(self, event): - """Callback for object:state-changed:selected accessibility events.""" - - if self._handleSwitcherEvent(event): - return - - super().onSelectedChanged(event) - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - if self._handleSwitcherEvent(event): - return - - super().onSelectionChanged(event) - - def onShowingChanged(self, event): - """Callback for object:state-changed:showing accessibility events.""" - - if self._handleSwitcherEvent(event): - return - - super().onShowingChanged(event) - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - if self._handleSwitcherEvent(event): - return - - super().onCaretMoved(event) - - def onTextDeleted(self, event): - """Callback for object:text-changed:delete accessibility events.""" - - if self._handleSwitcherEvent(event): - return - - super().onTextDeleted(event) - - def onTextInserted(self, event): - """Callback for object:text-changed:insert accessibility events.""" - - if self._handleSwitcherEvent(event): - return - - super().onTextInserted(event) diff --git a/src/cthulhu/scripts/switcher/script_utilities.py b/src/cthulhu/scripts/switcher/script_utilities.py deleted file mode 100644 index cc4d21a..0000000 --- a/src/cthulhu/scripts/switcher/script_utilities.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2019 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu import debug -from cthulhu import script_utilities -from cthulhu.ax_object import AXObject - - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - super().__init__(script) - - def isSwitcherContainer(self, obj): - """Returns True if obj is the switcher container.""" - - return obj and AXObject.get_role(obj) == Atspi.Role.STATUS_BAR - - def isSwitcherSelectionChangeEventType(self, event): - """Returns True if this event is the one we use to present changes.""" - - if event.type.startswith("object:text-changed:insert"): - return True - - if event.type.startswith("object:state-changed:showing"): - return event.detail1 - - return False - - def getSelectionName(self, container): - """Returns the name of the currently-selected item.""" - - if self.isSwitcherContainer(container): - return AXObject.get_name(container) - - return "" - - def isZombie(self, obj): - if not super().isZombie(obj): - return False - - if AXObject.get_index_in_parent(obj) >= 0: - return True - - AXObject.clear_cache(obj) - - if self.isShowingAndVisible(obj): - tokens = ["SWITCHER: Ignoring bad index of", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["SWITCHER:", obj, "has bad index and isn't showing and visible"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True diff --git a/src/cthulhu/scripts/terminal/__init__.py b/src/cthulhu/scripts/terminal/__init__.py deleted file mode 100644 index 57ee8c8..0000000 --- a/src/cthulhu/scripts/terminal/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .braille_generator import BrailleGenerator -from .script import Script -from .speech_generator import SpeechGenerator -from .script_utilities import Utilities - diff --git a/src/cthulhu/scripts/terminal/braille_generator.py b/src/cthulhu/scripts/terminal/braille_generator.py deleted file mode 100644 index 1854e20..0000000 --- a/src/cthulhu/scripts/terminal/braille_generator.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2016 Igalia, S.L." -__license__ = "LGPL" - -from cthulhu import braille_generator - - -class BrailleGenerator(braille_generator.BrailleGenerator): - - def __init__(self, script): - super().__init__(script) - - def _generateDescription(self, obj, **args): - # The text in the description is the same as the text in the page - # tab and similar to (and sometimes the same as) the prompt. - return [] diff --git a/src/cthulhu/scripts/terminal/meson.build b/src/cthulhu/scripts/terminal/meson.build deleted file mode 100644 index 3dd24b2..0000000 --- a/src/cthulhu/scripts/terminal/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -terminal_python_sources = files([ - '__init__.py', - 'braille_generator.py', - 'script.py', - 'script_utilities.py', - 'speech_generator.py', -]) - -python3.install_sources( - terminal_python_sources, - subdir: 'cthulhu/scripts/terminal' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/terminal/script.py b/src/cthulhu/scripts/terminal/script.py deleted file mode 100644 index f098fcd..0000000 --- a/src/cthulhu/scripts/terminal/script.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2016 Igalia, S.L." -__license__ = "LGPL" - -from cthulhu import debug -from cthulhu import cthulhu -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.scripts import default - -from .braille_generator import BrailleGenerator -from .speech_generator import SpeechGenerator -from .script_utilities import Utilities - - -class Script(default.Script): - - def __init__(self, app): - super().__init__(app) - self.presentIfInactive = False - - def deactivate(self): - """Called when this script is deactivated.""" - - self.utilities.clearCache() - super().deactivate() - - def getBrailleGenerator(self): - """Returns the braille generator for this script.""" - - return BrailleGenerator(self) - - def getSpeechGenerator(self): - """Returns the speech generator for this script.""" - - return SpeechGenerator(self) - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - # https://bugzilla.gnome.org/show_bug.cgi?id=748311 - cthulhu.setLocusOfFocus(event, event.source) - - def onTextDeleted(self, event): - """Callback for object:text-changed:delete accessibility events.""" - - if self.utilities.treatEventAsNoise(event): - msg = "TERMINAL: Deletion is believed to be noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - super().onTextDeleted(event) - - def onTextInserted(self, event): - """Callback for object:text-changed:insert accessibility events.""" - - if not self.utilities.treatEventAsCommand(event): - msg = "TERMINAL: Passing along event to default script." - debug.printMessage(debug.LEVEL_INFO, msg, True) - super().onTextInserted(event) - return - - msg = "TERMINAL: Insertion is believed to be due to terminal command" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self.updateBraille(event.source) - - newString = self.utilities.insertedText(event) - if len(newString) == 1: - self.speakCharacter(newString) - else: - voice = self.speechGenerator.voice(obj=event.source, string=newString) - self.speakMessage(newString, voice=voice) - - if self.flatReviewPresenter.is_active(): - msg = "TERMINAL: Flat review presenter is active. Ignoring insertion" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if AXObject.supports_text(event.source): - self._saveLastCursorPosition(event.source, AXText.get_caret_offset(event.source)) - self.utilities.updateCachedTextSelection(event.source) - - def presentKeyboardEvent(self, event): - if not event.is_printable_key(): - return super().presentKeyboardEvent(event) - - if event.is_pressed_key(): - return False - - self._sayAllIsInterrupted = False - self.utilities.clearCachedCommandState() - if not event.shouldEcho or event.isCthulhuModified() or event.isCharacterEchoable(): - return False - - # We have no reliable way of knowing a password is being entered into - # a terminal -- other than the fact that the text typed isn't there. - if not AXObject.supports_text(event.get_object()): - return False - - offset = AXText.get_caret_offset(event.get_object()) - prevChar = AXText.get_substring(event.get_object(), offset - 1, offset) - char = AXText.get_substring(event.get_object(), offset, offset + 1) - - string = event.event_string - if string not in [prevChar, "space", char]: - return False - - tokens = ["TERMINAL: Presenting keyboard event", string] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.speakKeyEvent(event) - return True - - def skipObjectEvent(self, event): - if event.type == "object:text-changed:insert": - return False - - newEvent, newTime = None, 0 - if event.type == "object:text-changed:delete": - if self.utilities.isBackSpaceCommandTextDeletionEvent(event): - return False - - newEvent, newTime = self.eventCache.get("object:text-changed:insert", [None, 0]) - - if newEvent is None or newEvent.source != event.source: - return super().skipObjectEvent(event) - - if event.detail1 != newEvent.detail1: - return False - - data = "\n%s%s" % (" " * 11, str(newEvent).replace("\t", " " * 11)) - tokens = ["TERMINAL: Skipping due to more recent event at offset", data] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True diff --git a/src/cthulhu/scripts/terminal/script_utilities.py b/src/cthulhu/scripts/terminal/script_utilities.py deleted file mode 100644 index b61d9f7..0000000 --- a/src/cthulhu/scripts/terminal/script_utilities.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2016 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import re - -from cthulhu import debug -from cthulhu import cthulhu -from cthulhu import keybindings -from cthulhu import cthulhu_state -from cthulhu import script_utilities -from cthulhu import settings_manager -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - super().__init__(script) - - def clearCache(self): - pass - - def deletedText(self, event): - match = re.search("\n~", event.any_data) - if not match: - return event.any_data - - adjusted = event.any_data[:match.start()] - tokens = ["TERMINAL: Adjusted deletion: '", adjusted, "'"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return adjusted - - def insertedText(self, event): - if len(event.any_data) == 1: - return event.any_data - - if self.isAutoTextEvent(event): - return event.any_data - - if self.isClipboardTextChangedEvent(event): - return event.any_data - - if not AXObject.supports_text(event.source): - return event.any_data - - start, end = event.detail1, event.detail1 + len(event.any_data) - firstLine = AXText.get_line_at_offset(event.source, start) - tokens = ["TERMINAL: First line of insertion:", firstLine] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - lastLine = AXText.get_line_at_offset(event.source, end - 1) - tokens = ["TERMINAL: Last line of insertion:", firstLine] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if firstLine == lastLine: - msg = "TERMINAL: Not adjusting single-line insertion." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return event.any_data - - currentLine = AXText.get_line_at_offset(event.source, AXText.get_caret_offset(event.source)) - tokens = ["TERMINAL: Current line:", firstLine] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if firstLine != ("", 0, 0): - start = firstLine[1] - - if currentLine not in (("", 0, 0), firstLine, lastLine): - lastLine = currentLine - - if lastLine != ("", 0, 0): - end = lastLine[2] - if lastLine[0].endswith("\n"): - end -= 1 - - adjusted = AXText.get_substring(event.source, start, end) - if adjusted: - tokens = ["TERMINAL: Adjusted insertion: '", adjusted, "'"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - msg = "TERMINAL: Adjustment failed. Returning any_data." - debug.printMessage(debug.LEVEL_INFO, msg, True) - adjusted = event.any_data - - return adjusted - - def insertionEndsAtCaret(self, event): - if not AXObject.supports_text(event.source): - return False - - return AXText.get_caret_offset(event.source) == event.detail1 + event.detail2 - - def isEditableTextArea(self, obj): - if AXUtilities.is_terminal(obj): - return True - - return super().isEditableTextArea(obj) - - def isTextArea(self, obj): - if AXUtilities.is_terminal(obj): - return True - - return super().isTextArea(obj) - - def isAutoTextEvent(self, event): - if not event.type.startswith("object:text-changed:insert"): - return False - - if not event.any_data or not event.source: - return False - - if len(event.any_data) <= 1: - return False - - lastKey, mods = self.lastKeyAndModifiers() - if lastKey == "Tab": - return event.any_data != "\t" - if lastKey == "Return" and event.any_data.startswith("\n"): - return event.any_data.strip() and not event.any_data.count("\n~") - - return False - - def lastInputEventWasCopy(self): - keycode, mods = self._lastKeyCodeAndModifiers() - keynames = self._allNamesForKeyCode(keycode) - if 'c' not in keynames: - return False - - if mods & keybindings.CTRL_MODIFIER_MASK: - return mods & keybindings.SHIFT_MODIFIER_MASK - - return False - - def lastInputEventWasPaste(self): - keycode, mods = self._lastKeyCodeAndModifiers() - keynames = self._allNamesForKeyCode(keycode) - if 'v' not in keynames: - return False - - if mods & keybindings.CTRL_MODIFIER_MASK: - return mods & keybindings.SHIFT_MODIFIER_MASK - - return False - - def treatEventAsCommand(self, event): - if event.source != cthulhu_state.locusOfFocus: - return False - - if event.type.startswith("object:text-changed:insert") and event.any_data.strip(): - # To let default script handle presentation. - if self.lastInputEventWasPaste(): - return False - - if event.any_data.count("\n~"): - return False - - keyString, mods = self.lastKeyAndModifiers() - if keyString in ["Return", "Tab", "space", " "]: - return re.search(r"[^\d\s]", event.any_data) - if mods & keybindings.ALT_MODIFIER_MASK: - return True - if self.lastInputEventWasPrintableKey(): - return len(event.any_data) > 1 - if self.insertionEndsAtCaret(event): - return True - - return False - - def treatEventAsNoise(self, event): - if self.lastInputEventWasCommand(): - return False - - if event.type.startswith("object:text-changed:delete") and event.any_data.strip(): - keyString, mods = self.lastKeyAndModifiers() - if keyString in ["Return", "Tab", "space", " "]: - return True - if mods & keybindings.ALT_MODIFIER_MASK: - return True - if len(event.any_data) > 1 and self.lastInputEventWasPrintableKey(): - return True - - return False - - def willEchoCharacter(self, event): - if not cthulhu.cthulhuApp.settingsManager.getSetting("enableEchoByCharacter"): - return False - - if len(event.event_string) != 1 \ - or event.modifiers & keybindings.CTHULHU_CTRL_MODIFIER_MASK: - return False - - return True diff --git a/src/cthulhu/scripts/terminal/speech_generator.py b/src/cthulhu/scripts/terminal/speech_generator.py deleted file mode 100644 index 76b4708..0000000 --- a/src/cthulhu/scripts/terminal/speech_generator.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2016 Igalia, S.L." -__license__ = "LGPL" - -from cthulhu import speech_generator - - -class SpeechGenerator(speech_generator.SpeechGenerator): - - def __init__(self, script): - super().__init__(script) - - def _generateDescription(self, obj, **args): - # The text in the description is the same as the text in the page - # tab and similar to (and sometimes the same as) the prompt. - return [] diff --git a/src/cthulhu/scripts/toolkits/Chromium/__init__.py b/src/cthulhu/scripts/toolkits/Chromium/__init__.py deleted file mode 100644 index 44f2022..0000000 --- a/src/cthulhu/scripts/toolkits/Chromium/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Chromium.""" - -# https://git.stormux.org/storm/cthulhu -# ruff: noqa: F401 -from .script import Script diff --git a/src/cthulhu/scripts/toolkits/Chromium/braille_generator.py b/src/cthulhu/scripts/toolkits/Chromium/braille_generator.py deleted file mode 100644 index fb1ddfa..0000000 --- a/src/cthulhu/scripts/toolkits/Chromium/braille_generator.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom braille generator for Chromium.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2018-2019 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu import debug -from cthulhu.scripts import web -from cthulhu.ax_object import AXObject - - -class BrailleGenerator(web.BrailleGenerator): - - def __init__(self, script): - super().__init__(script) - - def _generateLabelOrName(self, obj, **args): - if AXObject.get_role(obj) == Atspi.Role.FRAME: - document = self._script.utilities.activeDocument(obj) - if document and not self._script.utilities.documentFrameURI(document): - # Eliminates including "untitled" in the frame name. - return super()._generateLabelOrName(AXObject.get_parent(obj)) - - return super()._generateLabelOrName(obj) - - def generateBraille(self, obj, **args): - if self._script.utilities.inDocumentContent(obj): - return super().generateBraille(obj, **args) - - oldRole = None - if self._script.utilities.treatAsMenu(obj): - tokens = ["CHROMIUM: HACK? Displaying menu item as menu", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - oldRole = self._overrideRole(Atspi.Role.MENU, args) - - result = super().generateBraille(obj, **args) - if oldRole is not None: - self._restoreRole(oldRole, args) - - return result diff --git a/src/cthulhu/scripts/toolkits/Chromium/meson.build b/src/cthulhu/scripts/toolkits/Chromium/meson.build deleted file mode 100644 index 038f32b..0000000 --- a/src/cthulhu/scripts/toolkits/Chromium/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -chromium_python_sources = files([ - '__init__.py', - 'braille_generator.py', - 'script.py', - 'script_utilities.py', - 'speech_generator.py', -]) - -python3.install_sources( - chromium_python_sources, - subdir: 'cthulhu/scripts/toolkits/Chromium' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/toolkits/Chromium/script.py b/src/cthulhu/scripts/toolkits/Chromium/script.py deleted file mode 100644 index db52607..0000000 --- a/src/cthulhu/scripts/toolkits/Chromium/script.py +++ /dev/null @@ -1,545 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for Chromium.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2018-2019 Igalia, S.L." -__license__ = "LGPL" - -from cthulhu import debug -from cthulhu import cthulhu -from cthulhu import cthulhu_state -from cthulhu import keybindings -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu.scripts import default -from cthulhu.scripts import web -from cthulhu.scripts.web.event_router import RouteResult -from .braille_generator import BrailleGenerator -from .script_utilities import Utilities -from .speech_generator import SpeechGenerator - - -class Script(web.Script): - - def __init__(self, app): - super().__init__(app) - - self.presentIfInactive = False - self._lastAutocompletePopupItem = None - - def getBrailleGenerator(self): - """Returns the braille generator for this script.""" - - return BrailleGenerator(self) - - def getSpeechGenerator(self): - """Returns the speech generator for this script.""" - - return SpeechGenerator(self) - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def isActivatableEvent(self, event): - """Returns True if this event should activate this script.""" - - if event.type == "window:activate": - return self.utilities.canBeActiveWindow(event.source) - - return super().isActivatableEvent(event) - - def locus_of_focus_changed(self, event, oldFocus, newFocus): - """Handles changes of focus of interest to the script.""" - - if super().locus_of_focus_changed(event, oldFocus, newFocus): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.locus_of_focus_changed(self, event, oldFocus, newFocus) - - def onActiveChanged(self, event): - """Callback for object:state-changed:active accessibility events.""" - - if super().onActiveChanged(event): - return - - if event.detail1 and AXUtilities.is_frame(event.source) \ - and not self.utilities.canBeActiveWindow(event.source): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onActiveChanged(self, event) - - def onActiveDescendantChanged(self, event): - """Callback for object:active-descendant-changed accessibility events.""" - - if super().onActiveDescendantChanged(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onActiveDescendantChanged(self, event) - - def onBusyChanged(self, event): - """Callback for object:state-changed:busy accessibility events.""" - - if self.utilities.hasNoSize(event.source): - msg = "CHROMIUM: Ignoring event from page with no size." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if not self.utilities.documentFrameURI(event.source): - msg = "CHROMIUM: Ignoring event from page with no URI." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onBusyChanged(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onBusyChanged(self, event) - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - if self.utilities.isStaticTextLeaf(event.source): - msg = "CHROMIUM: Ignoring event from static-text leaf" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.utilities.isRedundantAutocompleteEvent(event): - msg = "CHROMIUM: Ignoring redundant autocomplete event" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onCaretMoved(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onCaretMoved(self, event) - - def onCheckedChanged(self, event): - """Callback for object:state-changed:checked accessibility events.""" - - def handle_shared_web(routed_event: object) -> RouteResult: - handled = web.Script.onCheckedChanged(self, routed_event) - return RouteResult.HANDLED if handled else RouteResult.CONTINUE - - self._eventRouter.route_event( - event, - application_handler=None, - toolkit_handler=None, - web_handler=handle_shared_web, - default_handler=lambda routed_event: default.Script.onCheckedChanged( - self, - routed_event, - ), - ) - - def onColumnReordered(self, event): - """Callback for object:column-reordered accessibility events.""" - - def handle_shared_web(routed_event: object) -> RouteResult: - handled = web.Script.onColumnReordered(self, routed_event) - return RouteResult.HANDLED if handled else RouteResult.CONTINUE - - self._eventRouter.route_event( - event, - application_handler=None, - toolkit_handler=None, - web_handler=handle_shared_web, - default_handler=lambda routed_event: default.Script.onColumnReordered( - self, - routed_event, - ), - ) - - def onChildrenAdded(self, event): - """Callback for object:children-changed:add accessibility events.""" - - if self.utilities.isStaticTextLeaf(event.any_data): - msg = "CHROMIUM: Ignoring because child is static text leaf" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onChildrenAdded(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onChildrenAdded(self, event) - - def onChildrenRemoved(self, event): - """Callback for object:children-changed:removed accessibility events.""" - - if self.utilities.isStaticTextLeaf(event.any_data): - msg = "CHROMIUM: Ignoring because child is static text leaf" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onChildrenRemoved(event): - return - - msg = "Chromium: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onChildrenRemoved(self, event) - - def onDocumentLoadComplete(self, event): - """Callback for document:load-complete accessibility events.""" - - if not self.utilities.documentFrameURI(event.source): - msg = "CHROMIUM: Ignoring event from page with no URI." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onDocumentLoadComplete(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onDocumentLoadComplete(self, event) - - def onDocumentLoadStopped(self, event): - """Callback for document:load-stopped accessibility events.""" - - if not self.utilities.documentFrameURI(event.source): - msg = "CHROMIUM: Ignoring event from page with no URI." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onDocumentLoadStopped(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onDocumentLoadStopped(self, event) - - def onDocumentReload(self, event): - """Callback for document:reload accessibility events.""" - - if not self.utilities.documentFrameURI(event.source): - msg = "CHROMIUM: Ignoring event from page with no URI." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onDocumentReload(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onDocumentReload(self, event) - - def onExpandedChanged(self, event): - """Callback for object:state-changed:expanded accessibility events.""" - - def handle_shared_web(routed_event: object) -> RouteResult: - handled = web.Script.onExpandedChanged(self, routed_event) - return RouteResult.HANDLED if handled else RouteResult.CONTINUE - - self._eventRouter.route_event( - event, - application_handler=None, - toolkit_handler=None, - web_handler=handle_shared_web, - default_handler=lambda routed_event: default.Script.onExpandedChanged( - self, - routed_event, - ), - ) - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - # This event is deprecated. We should get object:state-changed:focused - # events instead. - - if super().onFocus(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onFocus(self, event) - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if self.utilities.isDocument(event.source) \ - and not self.utilities.documentFrameURI(event.source): - msg = "CHROMIUM: Ignoring event from document with no URI." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onFocusedChanged(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onFocusedChanged(self, event) - - def onMouseButton(self, event): - """Callback for mouse:button accessibility events.""" - - if super().onMouseButton(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onMouseButton(self, event) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - if super().onNameChanged(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onNameChanged(self, event) - - def onRowReordered(self, event): - """Callback for object:row-reordered accessibility events.""" - - def handle_shared_web(routed_event: object) -> RouteResult: - handled = web.Script.onRowReordered(self, routed_event) - return RouteResult.HANDLED if handled else RouteResult.CONTINUE - - self._eventRouter.route_event( - event, - application_handler=None, - toolkit_handler=None, - web_handler=handle_shared_web, - default_handler=lambda routed_event: default.Script.onRowReordered( - self, - routed_event, - ), - ) - - def onSelectedChanged(self, event): - """Callback for object:state-changed:selected accessibility events.""" - - if super().onSelectedChanged(event): - return - - if event.detail1 and not self.utilities.inDocumentContent(event.source): - # The popup for an input with autocomplete on is a listbox child of a nameless frame. - # It lives outside of the document and also doesn't fire selection-changed events. - if listbox := AXObject.find_ancestor_inclusive(event.source, AXUtilities.is_list_box): - parent = AXObject.get_parent(listbox) - if AXUtilities.is_frame(parent) and not AXObject.get_name(parent): - msg = "CHROMIUM: Event source believed to be in autocomplete popup" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if event.source != self._lastAutocompletePopupItem: - self.presentObject(event.source, interrupt=True) - self._lastAutocompletePopupItem = event.source - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onSelectedChanged(self, event) - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - if super().onSelectionChanged(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onSelectionChanged(self, event) - - def onShowingChanged(self, event): - """Callback for object:state-changed:showing accessibility events.""" - - if event.detail1 and self.utilities.isMenuWithNoSelectedChild(event.source): - topLevel = self.utilities.topLevelObject(event.source) - if self.utilities.canBeActiveWindow(topLevel): - cthulhu.setActiveWindow(topLevel) - self.presentObject(event.source) - cthulhu.setLocusOfFocus(event, event.source, False) - return - - if super().onShowingChanged(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onShowingChanged(self, event) - - def onTextAttributesChanged(self, event): - """Callback for object:text-attributes-changed accessibility events.""" - - if super().onTextAttributesChanged(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onTextAttributesChanged(self, event) - - def onTextDeleted(self, event): - """Callback for object:text-changed:delete accessibility events.""" - - if super().onTextDeleted(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onTextDeleted(self, event) - - def onTextInserted(self, event): - """Callback for object:text-changed:insert accessibility events.""" - - if super().onTextInserted(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onTextInserted(self, event) - - def onTextSelectionChanged(self, event): - """Callback for object:text-selection-changed accessibility events.""" - - if self.utilities.isStaticTextLeaf(event.source): - msg = "CHROMIUM: Ignoring event from static-text leaf" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.utilities.isListItemMarker(event.source): - msg = "CHROMIUM: Ignoring event from list item marker" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onTextSelectionChanged(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onTextSelectionChanged(self, event) - - def onWindowActivated(self, event): - """Callback for window:activate accessibility events.""" - - if not self.utilities.canBeActiveWindow(event.source): - return - - autocomplete = self.utilities.autocompletePopupForFrame(event.source) - if autocomplete: - msg = "CHROMIUM: Treating nameless listbox frame as autocomplete popup" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - selected = self.utilities.selectedChildren(autocomplete) - activeItem = selected[0] if len(selected) == 1 else None - if activeItem is None: - activeItem = AXUtilities.get_focused_object(autocomplete) - activeItem = activeItem or autocomplete - tokens = ["CHROMIUM: Presenting active autocomplete popup item", activeItem] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.presentObject(activeItem, interrupt=True) - self._lastAutocompletePopupItem = activeItem - return - - # If this is a frame for a popup menu, we don't want to treat - # it like a proper window:activate event because it's not as - # far as the end-user experience is concerned. - menu = self.utilities.popupMenuForFrame(event.source) - if menu: - cthulhu.setActiveWindow(event.source) - - activeItem = None - selected = self.utilities.selectedChildren(menu) - if len(selected) == 1: - activeItem = selected[0] - - if activeItem: - # If this is the popup menu for the locusOfFocus, we don't want to - # present the popup menu as part of the new ancestry of activeItem. - if self.utilities.isPopupMenuForCurrentItem(menu): - cthulhu.setLocusOfFocus(event, menu, False) - - tokens = ["CHROMIUM: Setting locusOfFocus to active item", activeItem] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, activeItem) - return - - tokens = ["CHROMIUM: Setting locusOfFocus to popup menu", menu] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, menu) - - if super().onWindowActivated(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onWindowActivated(self, event) - - # Right now we don't get accessibility events for alerts which are - # already showing at the time of window activation. If that changes, - # we should store presented alerts so we don't double-present them. - for child in AXObject.iter_children(event.source): - if AXUtilities.is_alert(child): - self.presentObject(child) - - def onWindowDeactivated(self, event): - """Callback for window:deactivate accessibility events.""" - - if self.utilities.autocompletePopupForFrame(event.source): - msg = "CHROMIUM: Ignoring autocomplete popup deactivation" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._lastAutocompletePopupItem = None - return - - focus = cthulhu_state.locusOfFocus - isAutocompleteCombo = AXUtilities.is_combo_box(focus) \ - and AXUtilities.supports_autocompletion(focus) - if isAutocompleteCombo: - lastKey, mods = self.utilities.lastKeyAndModifiers() - if lastKey in ("Down", "Up") and mods & keybindings.ALT_MODIFIER_MASK: - msg = "CHROMIUM: Preserving state while opening autocomplete popup" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - app = AXObject.get_application(event.source) - for child in AXObject.iter_children(app): - popup = self.utilities.autocompletePopupForFrame(child) - if popup and AXUtilities.is_showing(child): - msg = "CHROMIUM: Preserving state during autocomplete popup activation" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onWindowDeactivated(event): - return - - msg = "CHROMIUM: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onWindowDeactivated(self, event) diff --git a/src/cthulhu/scripts/toolkits/Chromium/script_utilities.py b/src/cthulhu/scripts/toolkits/Chromium/script_utilities.py deleted file mode 100644 index 7ae2954..0000000 --- a/src/cthulhu/scripts/toolkits/Chromium/script_utilities.py +++ /dev/null @@ -1,453 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script utilities for Chromium""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2018-2019 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -import re - -from cthulhu import debug -from cthulhu import cthulhu_state -from cthulhu.scripts import web -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_relation import AXUtilitiesRelation - - -class Utilities(web.Utilities): - - def __init__(self, script): - super().__init__(script) - self._isStaticTextLeaf = {} - self._isPseudoElement = {} - self._isListItemMarker = {} - self._topLevelObject = {} - - def clearCachedObjects(self): - super().clearCachedObjects() - self._isStaticTextLeaf = {} - self._isPseudoElement = {} - self._isListItemMarker = {} - self._topLevelObject = {} - - def isStaticTextLeaf(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isStaticTextLeaf(obj) - - if AXObject.get_child_count(obj): - return False - - if self.isListItemMarker(obj): - return False - - rv = self._isStaticTextLeaf.get(hash(obj)) - if rv is not None: - return rv - - roles = [Atspi.Role.STATIC, Atspi.Role.TEXT] - rv = AXObject.get_role(obj) in roles and self._getTag(obj) in (None, "", "br") - if rv: - tokens = ["CHROMIUM:", obj, "believed to be static text leaf"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self._isStaticTextLeaf[hash(obj)] = rv - return rv - - def isPseudoElement(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isPseudoElement(obj) - - rv = self._isPseudoElement.get(hash(obj)) - if rv is not None: - return rv - - rv = self._getTag(obj) in ["", ""] - if rv: - tokens = ["CHROMIUM:", obj, "believed to be pseudo element"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self._isPseudoElement[hash(obj)] = rv - return rv - - def isListItemMarker(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isListItemMarker.get(hash(obj)) - if rv is not None: - return rv - - rv = False - parent = AXObject.get_parent(obj) - if AXUtilities.is_list_item(parent): - tag = self._getTag(obj) - if tag == "::marker": - rv = True - elif tag: - rv = False - elif AXObject.get_child_count(parent) > 1: - rv = AXObject.get_child(parent, 0) == obj - else: - rv = AXObject.get_name(obj) != self.displayedText(parent) - - self._isListItemMarker[hash(obj)] = rv - return rv - - def isMenuInCollapsedSelectElement(self, obj): - if not AXUtilities.is_menu(obj): - return False - - parent = AXObject.get_parent(obj) - if self._getTag(parent) != 'select': - return False - - return not AXUtilities.is_expanded(parent) - - def treatAsMenu(self, obj): - # Unlike other apps and toolkits, submenus in Chromium have the menu item - # role rather than the menu role, but we can identify them as submenus via - # the has-popup state. - return AXUtilities.is_menu_item(obj) and AXUtilities.has_popup(obj) - - def isPopupMenuForCurrentItem(self, obj): - # When a submenu is closed, it has role menu item. But when that submenu - # is opened/expanded, a menu with that same name appears. It would be - # nice if there were a connection (parent/child or an accessible relation) - # between the two.... - return self.treatAsMenu(cthulhu_state.locusOfFocus) and super().isPopupMenuForCurrentItem(obj) - - def isFrameForPopupMenu(self, obj): - # The ancestry of a popup menu appears to be a menu bar (even though - # one is not actually showing) contained in a nameless frame. It would - # be nice if these things were pruned from the accessibility tree.... - if not AXUtilities.is_frame(obj): - return False - if AXObject.get_name(obj): - return False - if AXObject.get_child_count(obj) != 1: - return False - return AXUtilities.is_menu_bar(AXObject.get_child(obj, 0)) - - def isTopLevelMenu(self, obj): - return AXUtilities.is_menu(obj) and self.isFrameForPopupMenu(self.topLevelObject(obj)) - - def popupMenuForFrame(self, obj): - if not self.isFrameForPopupMenu(obj): - return None - - menu = AXObject.find_descendant(obj, AXUtilities.is_menu) - tokens = ["CHROMIUM: Popup menu for", obj, ":", menu] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return menu - - def autocompletePopupForFrame(self, obj): - """Returns the listbox in a Chromium autocomplete popup frame.""" - - if not AXUtilities.is_frame(obj) or AXObject.get_name(obj): - return None - - # Native datalist/autofill popups are exposed as a direct listbox child - # of a separate nameless frame, without a popup-for relation. - if AXObject.get_child_count(obj) != 1: - return None - - child = AXObject.get_child(obj, 0) - return child if AXUtilities.is_list_box(child) else None - - def topLevelObject(self, obj, useFallbackSearch=False): - if not obj: - return None - - result = super().topLevelObject(obj) - if AXObject.get_role(result) in self._topLevelRoles(): - if not self.isFindContainer(result): - return result - else: - parent = AXObject.get_parent(result) - tokens = ["CHROMIUM: Top level object for", obj, "is", parent] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return parent - - cached = self._topLevelObject.get(hash(obj)) - if cached is not None: - return cached - - tokens = ["CHROMIUM: WARNING: Top level object for", obj, "is", result] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # The only (known) object giving us a broken ancestry is the omnibox popup. - if not (AXUtilities.is_list_item(obj or AXUtilities.is_list_box(obj))): - return result - - listbox = obj - if AXUtilities.is_list_item(obj): - listbox = AXObject.get_parent(listbox) - - if listbox is None: - return result - - # The listbox sometimes claims to be a redundant object rather than a listbox. - # Clearing the AT-SPI2 cache seems to be the trigger. - if not AXUtilities.is_list_box(listbox): - if AXUtilities.is_redundant_object(listbox): - tokens = ["CHROMIUM: WARNING: Suspected bogus role on listbox", listbox] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - return result - - autocomplete = self.autocompleteForPopup(listbox) - if autocomplete: - result = self.topLevelObject(autocomplete) - tokens = ["CHROMIUM: Top level object for", autocomplete, "is", result] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self._topLevelObject[hash(obj)] = result - return result - - def autocompleteForPopup(self, obj): - targets = AXUtilitiesRelation.get_is_popup_for(obj) - if not targets: - return None - - target = targets[0] - if AXUtilities.is_autocomplete(target): - return target - - return None - - def isBrowserAutocompletePopup(self, obj): - if not obj or self.inDocumentContent(obj): - return False - - return self.autocompleteForPopup(obj) is not None - - def isRedundantAutocompleteEvent(self, event): - if not AXUtilities.is_autocomplete(event.source): - return False - - if event.type.startswith("object:text-caret-moved"): - lastKey, mods = self.lastKeyAndModifiers() - if lastKey in ["Down", "Up"]: - return True - - return False - - def setCaretPosition(self, obj, offset, documentFrame=None): - super().setCaretPosition(obj, offset, documentFrame) - - link = AXObject.find_ancestor(obj, AXUtilities.is_link) - if link is not None: - tokens = ["CHROMIUM: HACK: Grabbing focus on", obj, "'s ancestor", link] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.grabFocus(link) - - def handleAsLiveRegion(self, event): - if not super().handleAsLiveRegion(event): - return False - - if not event.type.startswith("object:children-changed:add"): - return True - - # At least some of the time, we're getting text insertion events immediately - # followed by children-changed events to tell us that the object whose text - # changed is now being added to the accessibility tree. Furthermore the - # additions are not always coming to us in presentational order, whereas - # the text changes appear to be. So most of the time, we can ignore the - # children-changed events. Except for when we can't. - if AXUtilities.is_table(event.any_data): - return True - - msg = "CHROMIUM: Event is believed to be redundant live region notification" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - def getFindResultsCount(self, root=None): - root = root or self._findContainer - if not root: - return "" - - statusBars = AXUtilities.find_all_status_bars(root) - if len(statusBars) != 1: - return "" - - bar = statusBars[0] - AXObject.clear_cache(bar) - if len(re.findall(r"\d+", AXObject.get_name(bar))) == 2: - return AXObject.get_name(bar) - - return "" - - def isFindContainer(self, obj): - if not obj or self.inDocumentContent(obj): - return False - - if obj == self._findContainer: - return True - - if not AXUtilities.is_dialog(obj): - return False - - result = self.getFindResultsCount(obj) - if result: - tokens = ["CHROMIUM:", obj, "believed to be find-in-page container (", result, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._findContainer = obj - return True - - # When there are no results due to the absence of a search term, the status - # bar lacks a name. When there are no results due to lack of match, the name - # of the status bar is "No results" (presumably localized). Therefore fall - # back on the widgets. TODO: This would be far easier if Chromium gave us an - # object attribute we could look for.... - - if len(AXUtilities.find_all_entries(obj)) != 1: - tokens = ["CHROMIUM:", obj, "not believed to be find-in-page container (entry count)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if len(AXUtilities.find_all_push_buttons(obj)) != 3: - tokens = ["CHROMIUM:", obj, "not believed to be find-in-page container (button count)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if len(AXUtilities.find_all_separators(obj)) != 1: - tokens = ["CHROMIUM:", obj, - "not believed to be find-in-page container (separator count)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["CHROMIUM:", obj, "believed to be find-in-page container (accessibility tree)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._findContainer = obj - return True - - def inFindContainer(self, obj=None): - obj = obj or cthulhu_state.locusOfFocus - if not (AXUtilities.is_entry(obj) or AXUtilities.is_push_button(obj)): - return False - if self.inDocumentContent(obj): - return False - - result = self.isFindContainer(AXObject.find_ancestor(obj, AXUtilities.is_dialog)) - if result: - tokens = ["CHROMIUM:", obj, "believed to be find-in-page widget"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return result - - def isHidden(self, obj): - if not super().isHidden(obj): - return False - - if self.isMenuInCollapsedSelectElement(obj): - return False - - return True - - def findAllDescendants(self, root, includeIf=None, excludeIf=None): - if not root: - return [] - - # Don't bother if the root is a 'pre' or 'code' element. Those often have - # nothing but a TON of static text leaf nodes, which we want to ignore. - if self._getTag(root) in ('pre', 'code'): - tokens = ["CHROMIUM: Returning 0 descendants for pre/code", root] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - return super().findAllDescendants(root, includeIf, excludeIf) - - def accessibleAtPoint(self, root, x, y, coordType=None): - result = super().accessibleAtPoint(root, x, y, coordType) - - # Chromium cannot do a hit test of web content synchronously. So what it - # does is return a guess, then fire off an async hit test. The next time - # one calls it, Chromium returns the previous async hit test result if - # the point is still within its bounds. Therefore, we need to call - # accessibleAtPoint() twice to be safe. - msg = "CHROMIUM: Getting accessibleAtPoint again due to async hit test result." - debug.printMessage(debug.LEVEL_INFO, msg, True) - result = super().accessibleAtPoint(root, x, y, coordType) - return result - - def _isActiveAndShowingAndNotIconified(self, obj): - if super()._isActiveAndShowingAndNotIconified(obj): - return True - - if obj and AXObject.get_application(obj) != self._script.app: - return False - - # FIXME: This can potentially be non-performant because AT-SPI2 will recursively - # clear the cache of all descendants. This is an attempt to work around what may - # be a lack of window:activate and object:state-changed events from Chromium - # windows in at least some environments. - try: - tokens = ["CHROMIUM: Clearing cache for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - AXObject.clear_cache(obj) - except Exception: - tokens = ["CHROMIUM: Exception clearing cache for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if super()._isActiveAndShowingAndNotIconified(obj): - tokens = ["CHROMIUM:", obj, "deemed to be active and showing after cache clear"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - def _shouldCalculatePositionAndSetSize(self, obj): - # Chromium calculates posinset and setsize for description lists based on the - # number of terms present. If we want to present the number of values associated - # with a given term, we need to work those values out ourselves. - if self.isDescriptionListDescription(obj): - return True - - if self.inDocumentContent(obj): - return super()._shouldCalculatePositionAndSetSize(obj) - - # Chromium has accessible menu items which are not focusable and therefore do not - # have a posinset and setsize calculated. But they may claim to be the selected - # item when an accessible child is selected (e.g. "zoom" when "+" or "-" gains focus. - # Normally we calculate posinset and setsize when the application hasn't provided it. - # We don't want to do that in the case of menu items like "zoom" because our result - # will not jibe with the values of its siblings. Thus if a sibling has a value, - # assume that the missing attributes are missing on purpose. - for sibling in AXObject.iter_children(AXObject.get_parent(obj)): - if self.getPositionInSet(sibling) is not None: - tokens = ["CHROMIUM:", obj, "'s sibling", sibling, "has posinset."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return True diff --git a/src/cthulhu/scripts/toolkits/Chromium/speech_generator.py b/src/cthulhu/scripts/toolkits/Chromium/speech_generator.py deleted file mode 100644 index 5ee0e38..0000000 --- a/src/cthulhu/scripts/toolkits/Chromium/speech_generator.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom speech generator for Chromium.""" - -# Please note: ATK support in Chromium needs much work. Until that work has been -# done, Cthulhu will not be able to provide access to Chromium. This generator is a -# work in progress. - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2018-2019 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu import debug -from cthulhu.scripts import web -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - - -class SpeechGenerator(web.SpeechGenerator): - - def __init__(self, script): - super().__init__(script) - - def _generateNewAncestors(self, obj, **args): - # Likely a refocused submenu whose functional child was just collapsed. - # The new ancestors might technically be new, but they are not as far - # as the user is concerned. - if self._script.utilities.treatAsMenu(obj): - tokens = ["CHROMIUM: Not generating new ancestors for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - return super()._generateNewAncestors(obj, **args) - - def _generateListBoxItemWidgets(self, obj, **args): - # The list which descends from a combobox should be a menu, and its children - # menuitems. We can remove this once that change is made in Chromium. - if AXObject.find_ancestor(obj, AXUtilities.is_combo_box): - tokens = ["CHROMIUM: Not generating listbox item widgets for combobox child", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - return super()._generateListBoxItemWidgets(obj, **args) - - def _generateLabelOrName(self, obj, **args): - if AXUtilities.is_frame(obj): - document = self._script.utilities.activeDocument(obj) - if document and not self._script.utilities.documentFrameURI(document): - # Eliminates including "untitled" in the frame name. - return super()._generateLabelOrName(AXObject.get_parent(obj)) - - return super()._generateLabelOrName(obj, **args) - - def _generateRoleName(self, obj, **args): - if self._script.utilities.isListItemMarker(obj): - return [] - - return super()._generateRoleName(obj, **args) - - def generateSpeech(self, obj, **args): - if self._script.utilities.inDocumentContent(obj): - return super().generateSpeech(obj, **args) - - oldRole = None - if self._script.utilities.treatAsMenu(obj): - tokens = ["CHROMIUM: HACK? Speaking menu item as menu", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - oldRole = self._overrideRole(Atspi.Role.MENU, args) - - result = super().generateSpeech(obj, **args) - if oldRole is not None: - self._restoreRole(oldRole, args) - - return result diff --git a/src/cthulhu/scripts/toolkits/GAIL/__init__.py b/src/cthulhu/scripts/toolkits/GAIL/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/toolkits/GAIL/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/toolkits/GAIL/meson.build b/src/cthulhu/scripts/toolkits/GAIL/meson.build deleted file mode 100644 index 6e43025..0000000 --- a/src/cthulhu/scripts/toolkits/GAIL/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -gail_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - gail_python_sources, - subdir: 'cthulhu/scripts/toolkits/GAIL' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/toolkits/GAIL/script.py b/src/cthulhu/scripts/toolkits/GAIL/script.py deleted file mode 100644 index 30b9dcd..0000000 --- a/src/cthulhu/scripts/toolkits/GAIL/script.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013-2014 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.cthulhu as cthulhu -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.scripts.default as default -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -from .script_utilities import Utilities - -class Script(default.Script): - - def __init__(self, app): - default.Script.__init__(self, app) - - def getUtilities(self): - return Utilities(self) - - def locus_of_focus_changed(self, event, oldFocus, newFocus): - """Handles changes of focus of interest to the script.""" - - if self.utilities.isInOpenMenuBarMenu(newFocus): - window = self.utilities.topLevelObject(newFocus) - windowChanged = window and cthulhu_state.activeWindow != window - if windowChanged: - cthulhu.setActiveWindow(window) - - super().locus_of_focus_changed(event, oldFocus, newFocus) - - def onActiveDescendantChanged(self, event): - """Callback for object:active-descendant-changed accessibility events.""" - - if not self.utilities.isTypeahead(cthulhu_state.locusOfFocus): - super().onActiveDescendantChanged(event) - return - - msg = "GAIL: locusOfFocus believed to be typeahead. Presenting change." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.presentObject(event.any_data, interrupt=True) - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - # NOTE: This event type is deprecated and Cthulhu should no longer use it. - # This callback remains just to handle bugs in applications and toolkits - # that fail to reliably emit object:state-changed:focused events. - if self.utilities.isLayoutOnly(event.source): - return - - if self.utilities.isTypeahead(cthulhu_state.locusOfFocus) \ - and AXObject.supports_table(event.source) \ - and not AXUtilities.is_focused(event.source): - return - - ancestor = AXObject.find_ancestor(cthulhu_state.locusOfFocus, lambda x: x == event.source) - if not ancestor: - cthulhu.setLocusOfFocus(event, event.source) - return - - if AXObject.supports_table(ancestor): - return - - if AXUtilities.is_menu(ancestor) \ - and not AXObject.find_ancestor(ancestor, AXUtilities.is_menu): - return - - cthulhu.setLocusOfFocus(event, event.source) - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - isFocused = AXUtilities.is_focused(event.source) - if not isFocused and self.utilities.isTypeahead(cthulhu_state.locusOfFocus): - msg = "GAIL: locusOfFocus believed to be typeahead. Presenting change." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - selectedChildren = self.utilities.selectedChildren(event.source) - for child in selectedChildren: - if not self.utilities.isLayoutOnly(child): - self.presentObject(child) - return - - if AXUtilities.is_layered_pane(event.source) \ - and self.utilities.selectedChildCount(event.source) > 1: - return - - super().onSelectionChanged(event) - - def onTextSelectionChanged(self, event): - """Callback for object:text-selection-changed accessibility events.""" - - obj = event.source - if not self.utilities.isSameObject(obj, cthulhu_state.locusOfFocus): - return - - default.Script.onTextSelectionChanged(self, event) diff --git a/src/cthulhu/scripts/toolkits/GAIL/script_utilities.py b/src/cthulhu/scripts/toolkits/GAIL/script_utilities.py deleted file mode 100644 index d1ff789..0000000 --- a/src/cthulhu/scripts/toolkits/GAIL/script_utilities.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Igalia, S.L." -__license__ = "LGPL" - -import re - -import cthulhu.debug as debug -import cthulhu.script_utilities as script_utilities -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - super().__init__(script) - self._isTypeahead = {} - self._isLayoutOnly = {} - - def clearCachedObjects(self): - self._isTypeahead = {} - self._isLayoutOnly = {} - - def isTypeahead(self, obj): - if not AXUtilities.is_text(obj): - return False - - rv = self._isTypeahead.get(hash(obj)) - if rv is not None: - return rv - - parent = AXObject.get_parent(obj) - while parent and self.isLayoutOnly(parent): - parent = AXObject.get_parent(parent) - - rv = AXUtilities.is_window(parent) - self._isTypeahead[hash(obj)] = rv - return rv - - def rgbFromString(self, attributeValue): - regex = re.compile(r"rgb|[^\w,]", re.IGNORECASE) - string = re.sub(regex, "", attributeValue) - red, green, blue = string.split(",") - - return int(red) >> 8, int(green) >> 8, int(blue) >> 8 - - def isLayoutOnly(self, obj): - rv = self._isLayoutOnly.get(hash(obj)) - if rv is not None: - if rv: - tokens = ["GTK:", obj, "is deemed to be layout only"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - rv = super().isLayoutOnly(obj) - self._isLayoutOnly[hash(obj)] = rv - return rv diff --git a/src/cthulhu/scripts/toolkits/Gecko/__init__.py b/src/cthulhu/scripts/toolkits/Gecko/__init__.py deleted file mode 100644 index fec8f65..0000000 --- a/src/cthulhu/scripts/toolkits/Gecko/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script -from .script_utilities import Utilities diff --git a/src/cthulhu/scripts/toolkits/Gecko/meson.build b/src/cthulhu/scripts/toolkits/Gecko/meson.build deleted file mode 100644 index 0b76d35..0000000 --- a/src/cthulhu/scripts/toolkits/Gecko/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -gecko_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - gecko_python_sources, - subdir: 'cthulhu/scripts/toolkits/Gecko' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/toolkits/Gecko/script.py b/src/cthulhu/scripts/toolkits/Gecko/script.py deleted file mode 100644 index ba0b1eb..0000000 --- a/src/cthulhu/scripts/toolkits/Gecko/script.py +++ /dev/null @@ -1,418 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010 Cthulhu Team." \ - "Copyright (c) 2014-2015 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu import debug -from cthulhu import cthulhu -from cthulhu import cthulhu_state -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu.scripts import default -from cthulhu.scripts import web -from cthulhu.scripts.web.event_router import RouteResult -from .script_utilities import Utilities - - -class Script(web.Script): - - def __init__(self, app): - super().__init__(app) - - self.presentIfInactive = False - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def isActivatableEvent(self, event): - if event.type == "window:activate": - return self.utilities.canBeActiveWindow(event.source) - - return super().isActivatableEvent(event) - - def locus_of_focus_changed(self, event, oldFocus, newFocus): - """Handles changes of focus of interest to the script.""" - - if super().locus_of_focus_changed(event, oldFocus, newFocus): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.locus_of_focus_changed(self, event, oldFocus, newFocus) - - def onActiveChanged(self, event): - """Callback for object:state-changed:active accessibility events.""" - - if super().onActiveChanged(event): - return - - if event.detail1 and AXObject.get_role(event.source) == Atspi.Role.FRAME \ - and not self.utilities.canBeActiveWindow(event.source): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onActiveChanged(self, event) - - def onActiveDescendantChanged(self, event): - """Callback for object:active-descendant-changed accessibility events.""" - - if super().onActiveDescendantChanged(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onActiveDescendantChanged(self, event) - - def onBusyChanged(self, event): - """Callback for object:state-changed:busy accessibility events.""" - - if self.utilities.isNotRealDocument(event.source): - msg = "GECKO: Ignoring: Event source is not real document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onBusyChanged(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onBusyChanged(self, event) - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - if super().onCaretMoved(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onCaretMoved(self, event) - - def onCheckedChanged(self, event): - """Callback for object:state-changed:checked accessibility events.""" - - def handle_shared_web(routed_event: object) -> RouteResult: - handled = web.Script.onCheckedChanged(self, routed_event) - return RouteResult.HANDLED if handled else RouteResult.CONTINUE - - self._eventRouter.route_event( - event, - application_handler=None, - toolkit_handler=None, - web_handler=handle_shared_web, - default_handler=lambda routed_event: default.Script.onCheckedChanged( - self, - routed_event, - ), - ) - - def onColumnReordered(self, event): - """Callback for object:column-reordered accessibility events.""" - - def handle_shared_web(routed_event: object) -> RouteResult: - handled = web.Script.onColumnReordered(self, routed_event) - return RouteResult.HANDLED if handled else RouteResult.CONTINUE - - self._eventRouter.route_event( - event, - application_handler=None, - toolkit_handler=None, - web_handler=handle_shared_web, - default_handler=lambda routed_event: default.Script.onColumnReordered( - self, - routed_event, - ), - ) - - def onChildrenAdded(self, event): - """Callback for object:children-changed:add accessibility events.""" - - if super().onChildrenAdded(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onChildrenAdded(self, event) - - def onChildrenRemoved(self, event): - """Callback for object:children-changed:removed accessibility events.""" - - if super().onChildrenRemoved(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onChildrenRemoved(self, event) - - def onDocumentLoadComplete(self, event): - """Callback for document:load-complete accessibility events.""" - - if self.utilities.isNotRealDocument(event.source): - msg = "GECKO: Ignoring: Event source is not real document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if super().onDocumentLoadComplete(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onDocumentLoadComplete(self, event) - - def onDocumentLoadStopped(self, event): - """Callback for document:load-stopped accessibility events.""" - - if super().onDocumentLoadStopped(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onDocumentLoadStopped(self, event) - - def onDocumentReload(self, event): - """Callback for document:reload accessibility events.""" - - if super().onDocumentReload(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onDocumentReload(self, event) - - def onExpandedChanged(self, event): - """Callback for object:state-changed:expanded accessibility events.""" - - def handle_shared_web(routed_event: object) -> RouteResult: - handled = web.Script.onExpandedChanged(self, routed_event) - return RouteResult.HANDLED if handled else RouteResult.CONTINUE - - self._eventRouter.route_event( - event, - application_handler=None, - toolkit_handler=None, - web_handler=handle_shared_web, - default_handler=lambda routed_event: default.Script.onExpandedChanged( - self, - routed_event, - ), - ) - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - # This event is deprecated. We should get object:state-changed:focused - # events instead. - - if super().onFocus(event): - return - - if self.utilities.isLayoutOnly(event.source): - return - - if event.source == cthulhu_state.activeWindow: - msg = "GECKO: Ignoring event for active window." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - # NOTE: This event type is deprecated and Cthulhu should no longer use it. - # This callback remains just to handle bugs in applications and toolkits - # in which object:state-changed:focused events are missing. And in the - # case of Gecko dialogs, that seems to happen a lot. - cthulhu.setLocusOfFocus(event, event.source) - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if super().onFocusedChanged(event): - return - - if AXObject.get_role(event.source) == Atspi.Role.PANEL: - if cthulhu_state.locusOfFocus == cthulhu_state.activeWindow: - msg = "GECKO: Ignoring event believed to be noise." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - # We're sometimes getting a spurious focus claim from the Firefox/Thunderbird - # window after opening a file from file manager. - if AXObject.get_role(event.source) == Atspi.Role.FRAME: - msg = "GECKO: Ignoring event believed to be noise." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onFocusedChanged(self, event) - - def onMouseButton(self, event): - """Callback for mouse:button accessibility events.""" - - if super().onMouseButton(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onMouseButton(self, event) - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - if super().onNameChanged(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onNameChanged(self, event) - - def onRowReordered(self, event): - """Callback for object:row-reordered accessibility events.""" - - def handle_shared_web(routed_event: object) -> RouteResult: - handled = web.Script.onRowReordered(self, routed_event) - return RouteResult.HANDLED if handled else RouteResult.CONTINUE - - self._eventRouter.route_event( - event, - application_handler=None, - toolkit_handler=None, - web_handler=handle_shared_web, - default_handler=lambda routed_event: default.Script.onRowReordered( - self, - routed_event, - ), - ) - - def onSelectedChanged(self, event): - """Callback for object:state-changed:selected accessibility events.""" - - if super().onSelectedChanged(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onSelectedChanged(self, event) - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - if super().onSelectionChanged(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onSelectionChanged(self, event) - - def onShowingChanged(self, event): - """Callback for object:state-changed:showing accessibility events.""" - - if super().onShowingChanged(event): - return - - # Set focus to newly shown menus outside of document content - if event.detail1 and AXUtilities.is_menu(event.source) \ - and not self.utilities.inDocumentContent(event.source): - msg = "GECKO: Setting locus of focus to newly shown menu." - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source) - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onShowingChanged(self, event) - - def onTextAttributesChanged(self, event): - """Callback for object:text-attributes-changed accessibility events.""" - - if super().onTextAttributesChanged(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onTextAttributesChanged(self, event) - - def onTextDeleted(self, event): - """Callback for object:text-changed:delete accessibility events.""" - - if super().onTextDeleted(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onTextDeleted(self, event) - - def onTextInserted(self, event): - """Callback for object:text-changed:insert accessibility events.""" - - if super().onTextInserted(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onTextInserted(self, event) - - def onTextSelectionChanged(self, event): - """Callback for object:text-selection-changed accessibility events.""" - - if super().onTextSelectionChanged(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onTextSelectionChanged(self, event) - - def onWindowActivated(self, event): - """Callback for window:activate accessibility events.""" - - if not self.utilities.canBeActiveWindow(event.source): - return - - if super().onWindowActivated(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onWindowActivated(self, event) - - def onWindowDeactivated(self, event): - """Callback for window:deactivate accessibility events.""" - - if super().onWindowDeactivated(event): - return - - msg = "GECKO: Passing along event to default script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - default.Script.onWindowDeactivated(self, event) diff --git a/src/cthulhu/scripts/toolkits/Gecko/script_utilities.py b/src/cthulhu/scripts/toolkits/Gecko/script_utilities.py deleted file mode 100644 index 4f59e28..0000000 --- a/src/cthulhu/scripts/toolkits/Gecko/script_utilities.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Commonly-required utility methods needed by -- and potentially - customized by -- application and toolkit scripts. They have - been pulled out from the scripts because certain scripts had - gotten way too large as a result of including these methods.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." \ - "Copyright (c) 2014-2015 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import re -import time - -from cthulhu import debug -from cthulhu import cthulhu_state -from cthulhu.scripts import web -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - - -class Utilities(web.Utilities): - - def __init__(self, script): - super().__init__(script) - self._lastAutoTextObjectEvent = None - self._lastAutoTextInputEvent = None - self._lastAutoTextEventTime = 0 - - def _attemptBrokenTextRecovery(self, obj, **args): - boundary = args.get('boundary') - - # Gecko fails to implement this boundary type. - return boundary == Atspi.TextBoundaryType.SENTENCE_START - - def _treatAsLeafNode(self, obj): - if AXUtilities.is_table_row(obj): - return not AXObject.get_child_count(obj) - - return super()._treatAsLeafNode(obj) - - def containsPoint(self, obj, x, y, coordType, margin=2): - if not super().containsPoint(obj, x, y, coordType, margin): - return False - - if (AXUtilities.is_menu(obj) or AXUtilities.is_tool_tip(obj)) \ - and self.topLevelObject(obj) == AXObject.get_parent(obj): - tokens = ["GECKO:", obj, "is suspected to be off screen object"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return True - - def isLayoutOnly(self, obj): - if super().isLayoutOnly(obj): - return True - - if AXUtilities.is_tool_bar(obj) and AXObject.get_child_count(obj): - return AXUtilities.is_page_tab_list(AXObject.get_child(obj, 0)) - - return False - - def isSameObject(self, obj1, obj2, comparePaths=False, ignoreNames=False, - ignoreDescriptions=True): - if super().isSameObject(obj1, obj2, comparePaths, ignoreNames, ignoreDescriptions): - return True - - roles = self._topLevelRoles() - if not (AXObject.get_role(obj1) in roles and AXObject.get_role(obj2) in roles): - return False - - rv = AXObject.get_name(obj1) == AXObject.get_name(obj2) - tokens = ["GECKO: Treating", obj1, "and", obj2, "as same object:", rv] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - def isOnScreen(self, obj, boundingbox=None): - if not super().isOnScreen(obj, boundingbox): - return False - if not AXUtilities.is_unknown(obj): - return True - - if self.topLevelObject(obj) == AXObject.get_parent(obj): - tokens = ["INFO:", obj, "is suspected to be off screen object"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return True - - def getOnScreenObjects(self, root, extents=None): - objects = super().getOnScreenObjects(root, extents) - - # For things like Thunderbird's "Select columns to display" button - if AXUtilities.is_tree_table(root) and AXObject.get_child_count(root): - - def isExtra(x): - return not AXUtilities.is_column_header(x) - - child = AXObject.get_child(root, 0) - objects.extend([x for x in AXObject.iter_children(child, isExtra)]) - - return objects - - def isEditableMessage(self, obj): - """Returns True if this is an editable message.""" - - if not AXUtilities.is_editable(obj): - return False - - document = self.getDocumentForObject(obj) - if AXUtilities.is_editable(document): - tokens = ["GECKO:", obj, "is in an editable document:", document] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - tokens = ["GECKO: Editable", obj, "not in an editable document"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - def isNotRealDocument(self, obj): - name = AXObject.get_name(obj) - if name.startswith("moz-extension"): - return True - - if "self-repair.mozilla.org" in name: - return True - - uri = self.documentFrameURI(obj) - if uri.startswith("moz-extension"): - return True - - if not uri and "pixels" in name: - return True - - return False - - def _objectMightBeBogus(self, obj): - if AXUtilities.is_section(obj) and AXUtilities.is_frame(AXObject.get_parent(obj)): - tokens = ["GECKO:", obj, "is believed to be a bogus object"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - def canBeActiveWindow(self, window, clearCache=False): - # We apparently having missing events from Gecko requiring - # we update the cache. This is not performant. :( - return super().canBeActiveWindow(window, True) - - def treatAsEntry(self, obj): - if not obj or self.inDocumentContent(obj): - return super().treatAsEntry(obj) - - # Firefox seems to have turned its accessible location widget into a - # childless editable combobox. - if not AXUtilities.is_combo_box(obj): - return False - - if AXObject.get_child_count(obj): - return False - - if not AXUtilities.is_focused(obj): - return False - - if not AXObject.supports_editable_text(obj): - return False - - tokens = ["GECKO: Treating", obj, "as entry"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - def _isQuickFind(self, obj): - if not obj or self.inDocumentContent(obj): - return False - - if obj == self._findContainer: - return True - - if not AXUtilities.is_tool_bar(obj): - return False - - # TODO: This would be far easier if Gecko gave us an object attribute to look for.... - - if len(AXUtilities.find_all_entries(obj)) != 1: - tokens = ["GECKO:", obj, "not believed to be quick-find container (entry count)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if len(AXUtilities.find_all_push_buttons(obj)) != 1: - tokens = ["GECKO:", obj, "not believed to be quick-find container (button count)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["GECKO:", obj, "believed to be quick-find container (accessibility tree)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._findContainer = obj - return True - - def isFindContainer(self, obj): - if not obj or self.inDocumentContent(obj): - return False - - if obj == self._findContainer: - return True - - if not AXUtilities.is_tool_bar(obj): - return False - - result = self.getFindResultsCount(obj) - if result: - tokens = ["GECKO:", obj, "believed to be find-in-page container (", result, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._findContainer = obj - return True - - # TODO: This would be far easier if Gecko gave us an object attribute to look for.... - - if len(AXUtilities.find_all_entries(obj)) != 1: - tokens = ["GECKO:", obj, "not believed to be find-in-page container (entry count)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if len(AXUtilities.find_all_push_buttons(obj)) < 5: - tokens = ["GECKO:", obj, "not believed to be find-in-page container (button count)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - tokens = ["GECKO:", obj, "believed to be find-in-page container (accessibility tree)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._findContainer = obj - return True - - def inFindContainer(self, obj=None): - if not obj: - obj = cthulhu_state.locusOfFocus - - if not obj or self.inDocumentContent(obj): - return False - - if not (AXUtilities.is_entry(obj) or AXUtilities.is_push_button(obj)): - return False - - toolbar = AXObject.find_ancestor(obj, AXUtilities.is_tool_bar) - result = self.isFindContainer(toolbar) - if result: - tokens = ["GECKO:", obj, "believed to be find-in-page widget (toolbar)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if self._isQuickFind(toolbar): - tokens = ["GECKO:", obj, "believed to be find-in-page widget (quick find)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - def getFindResultsCount(self, root=None): - root = root or self._findContainer - if not root: - return "" - - def isMatch(x): - return len(re.findall(r"\d+", AXObject.get_name(x))) == 2 - - labels = AXUtilities.find_all_labels(root, isMatch) - if len(labels) != 1: - return "" - - label = labels[0] - AXObject.clear_cache(label) - return AXObject.get_name(label) - - def isAutoTextEvent(self, event): - if not super().isAutoTextEvent(event): - return False - - if self.inDocumentContent(event.source): - return True - - if self.treatAsDuplicateEvent(self._lastAutoTextObjectEvent, event) \ - and time.time() - self._lastAutoTextEventTime < 0.5 \ - and cthulhu_state.lastInputEvent.isReleaseFor(self._lastAutoTextInputEvent): - msg = "GECKO: Event believed to be duplicate auto text event." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - self._lastAutoTextObjectEvent = event - self._lastAutoTextInputEvent = cthulhu_state.lastInputEvent - self._lastAutoTextEventTime = time.time() - return True - - def localizeTextAttribute(self, key, value): - value = value.replace("-moz-", "") - return super().localizeTextAttribute(key, value) - - def unrelatedLabels(self, root, onlyShowing=True, minimumWords=3): - return super().unrelatedLabels(root, onlyShowing, minimumWords=1) - - def _shouldUseTableCellInterfaceForCoordinates(self): - # https://bugzilla.mozilla.org/show_bug.cgi?id=1794100 - return False diff --git a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/__init__.py b/src/cthulhu/scripts/toolkits/J2SE-access-bridge/__init__.py deleted file mode 100644 index 26d05ee..0000000 --- a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script -from .speech_generator import SpeechGenerator diff --git a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/formatting.py b/src/cthulhu/scripts/toolkits/J2SE-access-bridge/formatting.py deleted file mode 100644 index 5af62ff..0000000 --- a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/formatting.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom formatting for Java Swing.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc., " \ - "Copyright (c) 2010 Joanmarie Diggs" -__license__ = "LGPL" - -# If we were to adhere to the line-length requirements of 100 characters, -# this file would be even more cumbersome to look at than it already is. -# We shall respect the line-length requirements for all files that are not -# formatting.py. -# ruff: noqa: E501 - -import copy -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.formatting - -formatting = { - 'speech': { - # In Java, tree objects are labels, so we need to look at their - # states in order to tell whether they are expanded or collapsed. - # - Atspi.Role.LABEL: { - 'unfocused': '(displayedText or roleName) + expandableState + numberOfChildren', - 'focused': 'expandableState + numberOfChildren', - 'basicWhereAmI': '(displayedText or roleName) + expandableState + numberOfChildren + nodeLevel', - }, - }, - 'braille': { - Atspi.Role.LABEL: { - 'unfocused': '[Component(obj, asString(displayedText + expandableState))]' - }, - } -} - -class Formatting(cthulhu.formatting.Formatting): - def __init__(self, script): - cthulhu.formatting.Formatting.__init__(self, script) - self.update(copy.deepcopy(formatting)) diff --git a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/meson.build b/src/cthulhu/scripts/toolkits/J2SE-access-bridge/meson.build deleted file mode 100644 index 135cbb8..0000000 --- a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -j2se_access_bridge_python_sources = files([ - '__init__.py', - 'formatting.py', - 'script.py', - 'script_utilities.py', - 'speech_generator.py', -]) - -python3.install_sources( - j2se_access_bridge_python_sources, - subdir: 'cthulhu/scripts/toolkits/J2SE-access-bridge' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/script.py b/src/cthulhu/scripts/toolkits/J2SE-access-bridge/script.py deleted file mode 100644 index 6b21134..0000000 --- a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/script.py +++ /dev/null @@ -1,200 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc., " \ - "Copyright (c) 2010 Joanmarie Diggs" -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.scripts.default as default -import cthulhu.input_event as input_event -import cthulhu.cthulhu as cthulhu -import cthulhu.cthulhu_state as cthulhu_state -from cthulhu.ax_object import AXObject -from cthulhu.ax_selection import AXSelection -from cthulhu.ax_utilities import AXUtilities - -from .script_utilities import Utilities -from .speech_generator import SpeechGenerator -from .formatting import Formatting - -######################################################################## -# # -# The Java script class. # -# # -######################################################################## - -class Script(default.Script): - - def __init__(self, app): - """Creates a new script for Java applications. - - Arguments: - - app: the application to create a script for. - """ - default.Script.__init__(self, app) - - # Some objects which issue descendant changed events lack - # STATE_MANAGES_DESCENDANTS. As a result, onSelectionChanged - # doesn't ignore these objects. That in turn causes Cthulhu to - # double-speak some items and/or set the locusOfFocus to a - # parent it shouldn't. See bgo#616582. [[[TODO - JD: remove - # this hack if and when we get a fix for that bug]]] - # - self.lastDescendantChangedSource = None - - def getSpeechGenerator(self): - """Returns the speech generator for this script.""" - return SpeechGenerator(self) - - def getFormatting(self): - """Returns the formatting strings for this script.""" - return Formatting(self) - - def getUtilities(self): - """Returns the utilities for this script.""" - return Utilities(self) - - def onCaretMoved(self, event): - # Java's SpinButtons are the most caret movement happy thing - # I've seen to date. If you Up or Down on the keyboard to - # change the value, they typically emit three caret movement - # events, first to the beginning, then to the end, and then - # back to the beginning. It's a very excitable little widget. - # Luckily, it only issues one value changed event. So, we'll - # ignore caret movement events caused by value changes and - # just process the single value changed event. - # - isSpinBox = self.utilities.hasMatchingHierarchy( - event.source, [Atspi.Role.TEXT, - Atspi.Role.PANEL, - Atspi.Role.SPIN_BUTTON]) - if isSpinBox: - eventStr, mods = self.utilities.lastKeyAndModifiers() - if eventStr in ["Up", "Down"] or isinstance( - cthulhu_state.lastInputEvent, input_event.MouseButtonEvent): - return - - default.Script.onCaretMoved(self, event) - - def onSelectionChanged(self, event): - """Called when an object's selection changes. - - Arguments: - - event: the Event - """ - - # Avoid doing this with objects that manage their descendants - # because they'll issue a descendant changed event. (Note: This - # equality check is intentional; utilities.isSameObject() is - # especially thorough with trees and tables, which is not - # performant. - # - if event.source == self.lastDescendantChangedSource: - return - - # We treat selected children as the locus of focus. When the - # selection changes in a list we want to update the locus of - # focus. If there is no selection, we default the locus of - # focus to the containing object. - # - if (AXUtilities.is_list(event.source) \ - or AXUtilities.is_page_tab_list(event.source) \ - or AXUtilities.is_tree(event.source)) \ - and AXUtilities.is_focused(event.source): - newFocus = AXSelection.get_selected_child(event.source, 0) or event.source - cthulhu.setLocusOfFocus(event, newFocus) - else: - default.Script.onSelectionChanged(self, event) - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if not event.detail1: - return - - # Accessibility support for menus in Java is badly broken: Missing - # events, missing states, bogus events from other objects, etc. - # Therefore if we get an event, however broken, for menus or their - # their items that suggests they are selected, we'll just cross our - # fingers and hope that's true. - if AXUtilities.is_menu_related(event.source) \ - or AXUtilities.is_menu_related(AXObject.get_parent(event.source)): - cthulhu.setLocusOfFocus(event, event.source) - return - - if AXUtilities.is_root_pane(event.source) \ - and AXUtilities.is_menu_related(cthulhu_state.locusOfFocus): - return - - default.Script.onFocusedChanged(self, event) - - def onValueChanged(self, event): - """Called whenever an object's value changes. - - Arguments: - - event: the Event - """ - - # We'll ignore value changed events for Java's toggle buttons since - # they also send a redundant object:state-changed:checked event. - if AXUtilities.is_toggle_button(event.source) \ - or AXUtilities.is_radio_button(event.source) \ - or AXUtilities.is_check_box(event.source): - return - - # Java's SpinButtons are the most caret movement happy thing - # I've seen to date. If you Up or Down on the keyboard to - # change the value, they typically emit three caret movement - # events, first to the beginning, then to the end, and then - # back to the beginning. It's a very excitable little widget. - # Luckily, it only issues one value changed event. So, we'll - # ignore caret movement events caused by value changes and - # just process the single value changed event. - # - if AXUtilities.is_spin_button(event.source): - parent = AXObject.get_parent(cthulhu_state.locusOfFocus) - grandparent = AXObject.get_parent(parent) - if grandparent == event.source: - self._presentTextAtNewCaretPosition(event, cthulhu_state.locusOfFocus) - return - - default.Script.onValueChanged(self, event) - - def skipObjectEvent(self, event): - - # Accessibility support for menus in Java is badly broken. One problem - # is bogus focus claims following menu-related focus claims. Therefore - # in this particular toolkit, we mustn't skip events for menus. - if AXUtilities.is_menu_related(event.source): - return False - - return default.Script.skipObjectEvent(self, event) diff --git a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/script_utilities.py b/src/cthulhu/scripts/toolkits/J2SE-access-bridge/script_utilities.py deleted file mode 100644 index 1773dad..0000000 --- a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/script_utilities.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Commonly-required utility methods needed by -- and potentially - customized by -- application and toolkit scripts. They have - been pulled out from the scripts because certain scripts had - gotten way too large as a result of including these methods.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.script_utilities as script_utilities -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -############################################################################# -# # -# Utilities # -# # -############################################################################# - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - """Creates an instance of the Utilities class. - - Arguments: - - script: the script with which this instance is associated. - """ - - script_utilities.Utilities.__init__(self, script) - - ######################################################################### - # # - # Utilities for finding, identifying, and comparing accessibles # - # # - ######################################################################### - - def isSameObject(self, obj1, obj2, comparePaths=False, ignoreNames=False, - ignoreDescriptions=True): - """Compares two objects to determine if they are functionally - the same object. This is needed because some applications and - toolkits kill and replace accessibles.""" - - if obj1 == obj2: - return True - if obj1 is None or obj2 is None: - return False - if not ignoreNames and AXObject.get_name(obj1) != AXObject.get_name(obj2): - return False - if AXObject.get_child_count(obj1) != AXObject.get_child_count(obj2): - return False - - # This is to handle labels in trees. In some cases the default - # script's method gives us false positives; other times false - # negatives. - # - if AXUtilities.is_label(obj1) and AXUtilities.is_label(obj2): - if AXObject.supports_component(obj1) and AXObject.supports_component(obj2): - try: - ext1 = Atspi.Component.get_extents(obj1, Atspi.CoordType.SCREEN) - ext2 = Atspi.Component.get_extents(obj2, Atspi.CoordType.SCREEN) - if ext1.x == ext2.x and ext1.y == ext2.y \ - and ext1.width == ext2.width and ext1.height == ext2.height: - return True - except Exception: - pass - - # In java applications, TRANSIENT state is missing for tree items - # (fix for bug #352250) - # - parent1 = obj1 - parent2 = obj2 - while AXUtilities.is_label(parent1) and AXUtilities.is_label(parent2): - if AXObject.get_index_in_parent(parent1) != AXObject.get_index_in_parent(parent2): - return False - parent1 = AXObject.get_parent(parent1) - parent2 = AXObject.get_parent(parent2) - if parent1 and parent2 and parent1 == parent2: - return True - - return script_utilities.Utilities.isSameObject( - self, obj1, obj2, comparePaths, ignoreNames, ignoreDescriptions) - - def nodeLevel(self, obj): - """Determines the node level of this object if it is in a tree - relation, with 0 being the top level node. If this object is - not in a tree relation, then -1 will be returned. - - Arguments: - -obj: the Accessible object - """ - - newObj = obj - if newObj and self.isZombie(newObj): - newObj = self.findReplicant(self._script.lastDescendantChangedSource, obj) - - if not newObj: - return script_utilities.Utilities.nodeLevel(self, obj) - - count = 0 - while newObj: - if AXUtilities.is_expandable(newObj) or AXUtilities.is_collapsed(newObj): - if AXUtilities.is_visible(newObj): - count += 1 - newObj = AXObject.get_parent(newObj) - else: - break - - return count - 1 diff --git a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/speech_generator.py b/src/cthulhu/scripts/toolkits/J2SE-access-bridge/speech_generator.py deleted file mode 100644 index 0ed6fdc..0000000 --- a/src/cthulhu/scripts/toolkits/J2SE-access-bridge/speech_generator.py +++ /dev/null @@ -1,170 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc., " \ - "Copyright (c) 2010 Joanmarie Diggs" -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.messages as messages -import cthulhu.settings as settings -import cthulhu.settings_manager as settings_manager -import cthulhu.speech_generator as speech_generator -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -_settingsManager = settings_manager.getManager() - -######################################################################## -# # -# Speech Generator # -# # -######################################################################## - -class SpeechGenerator(speech_generator.SpeechGenerator): - - def __init__(self, script): - speech_generator.SpeechGenerator.__init__(self, script) - - def _generateAncestors(self, obj, **args): - """The Swing toolkit has labelled panels that do not implement the - AccessibleText interface, but displayedText returns a meaningful - string that needs to be used if displayedLabel returns None. - """ - args['requireText'] = False - result = speech_generator.SpeechGenerator._generateAncestors( - self, obj, **args) - del args['requireText'] - return result - - def _generateNewAncestors(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the text of the ancestors for - the object. This is typically used to present the context for - an object (e.g., the names of the window, the panels, etc., - that the object is contained in). If the 'priorObj' attribute - of the args dictionary is set, only the differences in - ancestry between the 'priorObj' and the current obj will be - computed. Otherwise, no ancestry will be computed. The - 'priorObj' is typically set by Cthulhu to be the previous object - with focus. - """ - result = [] - if args.get('role', AXObject.get_role(obj)) == Atspi.Role.MENU: - # We're way too chatty here -- at least with the Swing2 - # demo. Users entering a menu want to know they've gone - # into a menu; not a huge ancestry. - # - return result - result.extend(speech_generator.SpeechGenerator.\ - _generateNewAncestors(self, obj, **args)) - return result - - def _generateNumberOfChildren(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represents the number of children the - object has.""" - - if _settingsManager.getSetting('onlySpeakDisplayedText') \ - or _settingsManager.getSetting('speechVerbosityLevel') == settings.VERBOSITY_LEVEL_BRIEF: - return [] - - result = [] - childCount = AXObject.get_child_count(obj) - if childCount and AXUtilities.is_label(obj) \ - and AXUtilities.is_expanded(obj): - result.append(messages.itemCount(childCount)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - else: - result.extend(speech_generator.SpeechGenerator.\ - _generateNumberOfChildren(self, obj, **args)) - - return result - - def _generatePositionInList(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the relative position of an - object in a list. - """ - - if _settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - listObj = None - if AXUtilities.is_combo_box(obj): - allLists = AXUtilities.find_all_lists(obj) - if len(allLists) == 1: - listObj = allLists[0] - - if listObj is None: - return speech_generator.SpeechGenerator._generatePositionInList( - self, obj, **args) - - result = [] - name = self._generateName(obj) - position = -1 - index = total = 0 - - for child in AXObject.iter_children(listObj): - nextName = self._generateName(child) - if not nextName or nextName[0] in ["", "Empty", "separator"] \ - or not AXUtilities.is_visible(child): - continue - - index += 1 - total += 1 - - if nextName == name: - position = index - - if (_settingsManager.getSetting('enablePositionSpeaking') \ - or args.get('forceList', False)) \ - and position >= 0: - result.append(self._script.formatting.getString( - mode='speech', stringType='groupindex') \ - % {"index" : position, "total" : total}) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - def generateSpeech(self, obj, **args): - result = [] - if AXUtilities.is_check_box(obj) and AXUtilities.is_menu(AXObject.get_parent(obj)): - oldRole = self._overrideRole(Atspi.Role.CHECK_MENU_ITEM, args) - result.extend(speech_generator.SpeechGenerator.\ - generateSpeech(self, obj, **args)) - self._restoreRole(oldRole, args) - - if args.get('formatType', 'unfocused') == 'basicWhereAmI' and AXUtilities.is_text(obj): - spinbox = AXObject.find_ancestor(obj, AXUtilities.is_spin_button) - if spinbox is not None: - obj = spinbox - result.extend(speech_generator.SpeechGenerator.generateSpeech(self, obj, **args)) - return result diff --git a/src/cthulhu/scripts/toolkits/Qt/__init__.py b/src/cthulhu/scripts/toolkits/Qt/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/toolkits/Qt/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/toolkits/Qt/meson.build b/src/cthulhu/scripts/toolkits/Qt/meson.build deleted file mode 100644 index 07151a7..0000000 --- a/src/cthulhu/scripts/toolkits/Qt/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -qt_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - qt_python_sources, - subdir: 'cthulhu/scripts/toolkits/Qt' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/toolkits/Qt/script.py b/src/cthulhu/scripts/toolkits/Qt/script.py deleted file mode 100644 index e61c975..0000000 --- a/src/cthulhu/scripts/toolkits/Qt/script.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013-2019 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.cthulhu as cthulhu -import cthulhu.scripts.default as default -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -from .script_utilities import Utilities - -class Script(default.Script): - - def __init__(self, app): - super().__init__(app) - - def getUtilities(self): - return Utilities(self) - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - if AXUtilities.is_accelerator_label(event.source): - msg = "QT: Ignoring event due to role." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - super().onCaretMoved(event) - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if not event.detail1: - return - - if AXUtilities.is_accelerator_label(event.source): - msg = "QT: Ignoring event due to role." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - frame = self.utilities.topLevelObject(event.source) - if not frame: - msg = "QT: Ignoring event because we couldn't find an ancestor window." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - isActive = AXUtilities.is_active(frame) - if not isActive: - tokens = ["QT: Event came from inactive top-level object", frame] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - AXObject.clear_cache(frame) - isActive = AXUtilities.is_active(frame) - tokens = ["QT: Cleared cache of", frame, ". Frame is now active:", isActive] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if AXUtilities.is_focused(event.source): - super().onFocusedChanged(event) - return - - msg = "QT: WARNING - source lacks focused state. Setting focus anyway." - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source) diff --git a/src/cthulhu/scripts/toolkits/Qt/script_utilities.py b/src/cthulhu/scripts/toolkits/Qt/script_utilities.py deleted file mode 100644 index adc84b1..0000000 --- a/src/cthulhu/scripts/toolkits/Qt/script_utilities.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2023 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.script_utilities as script_utilities - -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - super().__init__(script) - - def _isTopLevelObject(self, obj): - # This is needed because Qt apps might insert some junk (e.g. a filler) in - # between the window/frame/dialog and the application. - return AXUtilities.is_application(AXObject.get_parent(obj)) - - def topLevelObject(self, obj, useFallbackSearch=False): - # The fallback search is needed because sometimes we can ascend the accessibility - # tree all the way to the top; other times, we cannot get the parent, but can still - # get the children. The fallback search handles the latter scenario. - result = super().topLevelObject(obj, useFallbackSearch=True) - if result is not None and AXObject.get_role(result) not in self._topLevelRoles(): - tokens = ["QT: Top level object", result, "lacks expected role."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return result - - def frameAndDialog(self, obj): - """Returns the frame and (possibly) the dialog containing obj.""" - - frame, dialog = super().frameAndDialog(obj) - if frame or dialog: - return frame, dialog - - tokens = ["QT: Could not find frame or dialog for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - topLevel = self.topLevelObject(obj, True) - - tokens = ["QT: Returning", topLevel, "as frame for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return topLevel, None - - def hasMeaningfulToggleAction(self, obj): - """Returns True if obj has a meaningful toggle action.""" - - # https://bugreports.qt.io/browse/QTBUG-116204 - if AXUtilities.is_table_cell_or_header(obj): - tokens = ["QT: Ignoring toggle action on", obj, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return super().hasMeaningfulToggleAction(obj) diff --git a/src/cthulhu/scripts/toolkits/VCL.py b/src/cthulhu/scripts/toolkits/VCL.py deleted file mode 100644 index 11f7e16..0000000 --- a/src/cthulhu/scripts/toolkits/VCL.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Custom script for VCL toolkit (OpenOffice) applications""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -import cthulhu.scripts.default - -class Script(cthulhu.default.Script): - pass diff --git a/src/cthulhu/scripts/toolkits/WebKitGtk/__init__.py b/src/cthulhu/scripts/toolkits/WebKitGtk/__init__.py deleted file mode 100644 index 0ecdbf7..0000000 --- a/src/cthulhu/scripts/toolkits/WebKitGtk/__init__.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script -from .speech_generator import SpeechGenerator -from .braille_generator import BrailleGenerator -from .script_utilities import Utilities diff --git a/src/cthulhu/scripts/toolkits/WebKitGtk/braille_generator.py b/src/cthulhu/scripts/toolkits/WebKitGtk/braille_generator.py deleted file mode 100644 index 53804cc..0000000 --- a/src/cthulhu/scripts/toolkits/WebKitGtk/braille_generator.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs" \ - "Copyright (c) 2011-2012 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.object_properties as object_properties -import cthulhu.braille_generator as braille_generator -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -######################################################################## -# # -# Custom BrailleGenerator # -# # -######################################################################## - -class BrailleGenerator(braille_generator.BrailleGenerator): - """Provides a braille generator specific to WebKitGtk.""" - - def __init__(self, script): - braille_generator.BrailleGenerator.__init__(self, script) - - def __generateHeadingRole(self, obj): - result = [] - level = self._script.utilities.headingLevel(obj) - result.append(object_properties.ROLE_HEADING_LEVEL_BRAILLE % level) - - return result - - def _generateRoleName(self, obj, **args): - """Prevents some roles from being displayed.""" - - doNotDisplay = [Atspi.Role.FORM, - Atspi.Role.SECTION, - Atspi.Role.UNKNOWN] - if not AXUtilities.is_focusable(obj): - doNotDisplay.extend([Atspi.Role.LIST, - Atspi.Role.LIST_ITEM, - Atspi.Role.PANEL]) - - result = [] - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.HEADING: - result.extend(self.__generateHeadingRole(obj)) - elif role not in doNotDisplay: - result.extend(braille_generator.BrailleGenerator._generateRoleName( - self, obj, **args)) - parent = AXObject.get_parent(obj) - if AXObject.get_role(parent) == Atspi.Role.HEADING: - result.extend(self.__generateHeadingRole(parent)) - - return result - - def _generateAncestors(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the text of the ancestors for - the object. This is typically used to present the context for - an object (e.g., the names of the window, the panels, etc., - that the object is contained in). If the 'priorObj' attribute - of the args dictionary is set, only the differences in - ancestry between the 'priorObj' and the current obj will be - computed. The 'priorObj' is typically set by Cthulhu to be the - previous object with focus. - """ - - if self._script.utilities.isWebKitGtk(obj): - return [] - - return braille_generator.BrailleGenerator._generateAncestors( - self, obj, **args) - - def _generateEol(self, obj, **args): - if self._script.utilities.isWebKitGtk(obj) \ - and AXObject.get_role(obj) == Atspi.Role.PARAGRAPH \ - and not AXUtilities.is_editable(obj): - return [] - - return braille_generator.BrailleGenerator._generateEol( - self, obj, **args) diff --git a/src/cthulhu/scripts/toolkits/WebKitGtk/meson.build b/src/cthulhu/scripts/toolkits/WebKitGtk/meson.build deleted file mode 100644 index de0cb3b..0000000 --- a/src/cthulhu/scripts/toolkits/WebKitGtk/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -webkitgtk_python_sources = files([ - '__init__.py', - 'braille_generator.py', - 'script.py', - 'speech_generator.py', - 'script_utilities.py', -]) - -python3.install_sources( - webkitgtk_python_sources, - subdir: 'cthulhu/scripts/toolkits/WebKitGtk' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/toolkits/WebKitGtk/script.py b/src/cthulhu/scripts/toolkits/WebKitGtk/script.py deleted file mode 100644 index 748d8b6..0000000 --- a/src/cthulhu/scripts/toolkits/WebKitGtk/script.py +++ /dev/null @@ -1,681 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (C) 2010-2011 The Cthulhu Team" \ - "Copyright (C) 2011-2012 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.scripts.default as default -import cthulhu.cmdnames as cmdnames -import cthulhu.debug as debug -import cthulhu.guilabels as guilabels -import cthulhu.input_event as input_event -import cthulhu.messages as messages -import cthulhu.cthulhu as cthulhu -import cthulhu.settings as settings -import cthulhu.settings_manager as settings_manager -import cthulhu.speechserver as speechserver -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.speech as speech -import cthulhu.structural_navigation as structural_navigation -from cthulhu.ax_object import AXObject -from cthulhu.ax_hypertext import AXHypertext -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -from .braille_generator import BrailleGenerator -from .speech_generator import SpeechGenerator -from .script_utilities import Utilities - -_settingsManager = settings_manager.getManager() - -######################################################################## -# # -# The WebKitGtk script class. # -# # -######################################################################## - -class Script(default.Script): - - def __init__(self, app): - """Creates a new script for WebKitGtk applications. - - Arguments: - - app: the application to create a script for. - """ - - super().__init__(app) - self._loadingDocumentContent = False - self._lastCaretContext = None, -1 - self.sayAllOnLoadCheckButton = None - - if _settingsManager.getSetting('sayAllOnLoad') is None: - _settingsManager.setSetting('sayAllOnLoad', True) - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for this script that can be - called by the key and braille bindings.""" - - default.Script.setupInputEventHandlers(self) - self.inputEventHandlers.update( - self.structuralNavigation.inputEventHandlers) - - self.inputEventHandlers["sayAllHandler"] = \ - input_event.InputEventHandler( - Script.sayAll, - cmdnames.SAY_ALL) - - self.inputEventHandlers["panBrailleLeftHandler"] = \ - input_event.InputEventHandler( - Script.panBrailleLeft, - cmdnames.PAN_BRAILLE_LEFT, - False) # Do not enable learn mode for this action - - self.inputEventHandlers["panBrailleRightHandler"] = \ - input_event.InputEventHandler( - Script.panBrailleRight, - cmdnames.PAN_BRAILLE_RIGHT, - False) # Do not enable learn mode for this action - - def getToolkitKeyBindings(self): - """Returns the toolkit-specific keybindings for this script.""" - - return self.structuralNavigation.keyBindings - - def getAppPreferencesGUI(self): - """Return a GtkGrid containing the application unique configuration - GUI items for the current application.""" - - from gi.repository import Gtk - - grid = Gtk.Grid() - grid.set_border_width(12) - - label = guilabels.READ_PAGE_UPON_LOAD - self.sayAllOnLoadCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self.sayAllOnLoadCheckButton.set_active( - _settingsManager.getSetting('sayAllOnLoad')) - grid.attach(self.sayAllOnLoadCheckButton, 0, 0, 1, 1) - - grid.show_all() - - return grid - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - return {'sayAllOnLoad': self.sayAllOnLoadCheckButton.get_active()} - - def getBrailleGenerator(self): - """Returns the braille generator for this script.""" - - return BrailleGenerator(self) - - def getSpeechGenerator(self): - """Returns the speech generator for this script.""" - - return SpeechGenerator(self) - - def getEnabledStructuralNavigationTypes(self): - """Returns a list of the structural navigation object types - enabled in this script.""" - - return [structural_navigation.StructuralNavigation.BLOCKQUOTE, - structural_navigation.StructuralNavigation.BUTTON, - structural_navigation.StructuralNavigation.CHECK_BOX, - structural_navigation.StructuralNavigation.CHUNK, - structural_navigation.StructuralNavigation.CLICKABLE, - structural_navigation.StructuralNavigation.COMBO_BOX, - structural_navigation.StructuralNavigation.CONTAINER, - structural_navigation.StructuralNavigation.ENTRY, - structural_navigation.StructuralNavigation.FORM_FIELD, - structural_navigation.StructuralNavigation.HEADING, - structural_navigation.StructuralNavigation.IFRAME, - structural_navigation.StructuralNavigation.IMAGE, - structural_navigation.StructuralNavigation.LANDMARK, - structural_navigation.StructuralNavigation.LINK, - structural_navigation.StructuralNavigation.LIST, - structural_navigation.StructuralNavigation.LIST_ITEM, - structural_navigation.StructuralNavigation.LIVE_REGION, - structural_navigation.StructuralNavigation.PARAGRAPH, - structural_navigation.StructuralNavigation.RADIO_BUTTON, - structural_navigation.StructuralNavigation.SEPARATOR, - structural_navigation.StructuralNavigation.TABLE, - structural_navigation.StructuralNavigation.TABLE_CELL, - structural_navigation.StructuralNavigation.UNVISITED_LINK, - structural_navigation.StructuralNavigation.VISITED_LINK] - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - if self._inSayAll: - return - - if not self.utilities.isWebKitGtk(event.source): - super().onCaretMoved(event) - return - - lastKey, mods = self.utilities.lastKeyAndModifiers() - if lastKey in ['Tab', 'ISO_Left_Tab']: - return - - if lastKey == 'Down' \ - and cthulhu_state.locusOfFocus == AXObject.get_parent(event.source) \ - and AXObject.get_index_in_parent(event.source) == 0 \ - and AXUtilities.is_link(cthulhu_state.locusOfFocus): - self.updateBraille(event.source) - return - - self.utilities.setCaretContext(event.source, event.detail1) - super().onCaretMoved(event) - - def onDocumentReload(self, event): - """Callback for document:reload accessibility events.""" - - if self.utilities.treatAsBrowser(event.source): - self._loadingDocumentContent = True - - def onDocumentLoadComplete(self, event): - """Callback for document:load-complete accessibility events.""" - - if not self.utilities.treatAsBrowser(event.source): - return - - self._loadingDocumentContent = False - - # TODO: We need to see what happens in Epiphany on pages where focus - # is grabbed rather than set the caret at the start. But for simple - # content in both Yelp and Epiphany this is alright for now. - obj, offset = self.utilities.setCaretAtStart(event.source) - self.utilities.setCaretContext(obj, offset) - - self.updateBraille(obj) - if _settingsManager.getSetting('sayAllOnLoad') \ - and _settingsManager.getSetting('enableSpeech'): - self.sayAll(None) - - def onDocumentLoadStopped(self, event): - """Callback for document:load-stopped accessibility events.""" - - if self.utilities.treatAsBrowser(event.source): - self._loadingDocumentContent = False - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if self._inSayAll or not event.detail1: - return - - if not self.utilities.isWebKitGtk(event.source): - super().onFocusedChanged(event) - return - - contextObj, offset = self.utilities.getCaretContext() - if event.source == contextObj: - return - - obj = event.source - role = AXObject.get_role(obj) - textRoles = [Atspi.Role.HEADING, - Atspi.Role.PANEL, - Atspi.Role.PARAGRAPH, - Atspi.Role.SECTION, - Atspi.Role.TABLE_CELL] - if role in textRoles \ - or (role == Atspi.Role.LIST_ITEM and AXObject.get_child_count(obj)): - return - - super().onFocusedChanged(event) - - def onBusyChanged(self, event): - """Callback for object:state-changed:busy accessibility events.""" - - if not self.utilities.treatAsBrowser(event.source): - return - - if event.detail1: - self.presentMessage(messages.PAGE_LOADING_START) - return - - name = AXObject.get_name(event.source) - if name: - self.presentMessage(messages.PAGE_LOADING_END_NAMED % name) - else: - self.presentMessage(messages.PAGE_LOADING_END) - - def sayCharacter(self, obj): - """Speak the character at the caret. - - Arguments: - - obj: an Accessible object that implements the AccessibleText interface - """ - - if AXUtilities.is_entry(obj): - default.Script.sayCharacter(self, obj) - return - - boundary = Atspi.TextBoundaryType.CHAR - objects = self.utilities.get_objectsFromEOCs(obj, boundary=boundary) - for (obj, start, end, string) in objects: - if string: - self.speakCharacter(string) - else: - speech.speak(self.speechGenerator.generateSpeech(obj)) - - self.pointOfReference["lastTextUnitSpoken"] = "char" - - def sayWord(self, obj): - """Speaks the word at the caret. - - Arguments: - - obj: an Accessible object that implements the AccessibleText interface - """ - - if AXUtilities.is_entry(obj): - default.Script.sayWord(self, obj) - return - - boundary = Atspi.TextBoundaryType.WORD_START - objects = self.utilities.get_objectsFromEOCs(obj, boundary=boundary) - for (obj, start, end, string) in objects: - self.sayPhrase(obj, start, end) - - self.pointOfReference["lastTextUnitSpoken"] = "word" - - def sayLine(self, obj): - """Speaks the line at the caret. - - Arguments: - - obj: an Accessible object that implements the AccessibleText interface - """ - - if AXUtilities.is_entry(obj): - default.Script.sayLine(self, obj) - return - - boundary = Atspi.TextBoundaryType.LINE_START - objects = self.utilities.get_objectsFromEOCs(obj, boundary=boundary) - for (obj, start, end, string) in objects: - self.sayPhrase(obj, start, end) - - # TODO: Move these next items into the speech generator. - if AXUtilities.is_panel(obj) and AXObject.get_index_in_parent(obj) == 0: - obj = AXObject.get_parent(obj) - - rolesToSpeak = [Atspi.Role.HEADING, Atspi.Role.LINK] - if AXObject.get_role(obj) in rolesToSpeak: - speech.speak(self.speechGenerator.getRoleName(obj)) - - self.pointOfReference["lastTextUnitSpoken"] = "line" - - def sayPhrase(self, obj, startOffset, endOffset): - """Speaks the text of an Accessible object between the given offsets. - - Arguments: - - obj: an Accessible object that implements the AccessibleText interface - - startOffset: the start text offset. - - endOffset: the end text offset. - """ - - if AXUtilities.is_entry(obj): - default.Script.sayPhrase(self, obj, startOffset, endOffset) - return - - phrase = self.utilities.substring(obj, startOffset, endOffset) - if len(phrase) and phrase != "\n": - voice = self.speechGenerator.voice(obj=obj, string=phrase) - phrase = self.utilities.adjustForRepeats(phrase) - links = [x for x in AXObject.iter_children(obj, AXUtilities.is_link)] - if links: - phrase = self.utilities.adjustForLinks(obj, phrase, startOffset) - speech.speak(phrase, voice) - else: - # Speak blank line if appropriate. - # - self.sayCharacter(obj) - - self.pointOfReference["lastTextUnitSpoken"] = "phrase" - - def skipObjectEvent(self, event): - """Gives us, and scripts, the ability to decide an event isn't - worth taking the time to process under the current circumstances. - - Arguments: - - event: the Event - - Returns True if we shouldn't bother processing this object event. - """ - - if event.type.startswith('object:state-changed:focused') and event.detail1 \ - and AXUtilities.is_link(event.source): - return False - - return default.Script.skipObjectEvent(self, event) - - def useStructuralNavigationModel(self, debugOutput=True): - """Returns True if we should do our own structural navigation. - This should return False if we're in a form field, or not in - document content. - """ - - doNotHandleRoles = [Atspi.Role.ENTRY, - Atspi.Role.TEXT, - Atspi.Role.PASSWORD_TEXT, - Atspi.Role.LIST, - Atspi.Role.LIST_ITEM, - Atspi.Role.MENU_ITEM] - - if not self.structuralNavigation.enabled: - return False - - if not self.utilities.isWebKitGtk(cthulhu_state.locusOfFocus): - return False - - if AXUtilities.is_editable(cthulhu_state.locusOfFocus): - return False - - role = AXObject.get_role(cthulhu_state.locusOfFocus) - if role in doNotHandleRoles: - if role == Atspi.Role.LIST_ITEM: - return not AXUtilities.is_selectable(cthulhu_state.locusOfFocus) - - if AXUtilities.is_focused(cthulhu_state.locusOfFocus): - return False - - return True - - def panBrailleLeft(self, inputEvent=None, panAmount=0): - """In document content, we want to use the panning keys to browse the - entire document. - """ - - if self.flatReviewPresenter.is_active() \ - or not self.isBrailleBeginningShowing() \ - or not self.utilities.isWebKitGtk(cthulhu_state.locusOfFocus): - return default.Script.panBrailleLeft(self, inputEvent, panAmount) - - obj = self.utilities.findPreviousObject(cthulhu_state.locusOfFocus) - cthulhu.setLocusOfFocus(None, obj, notifyScript=False) - self.updateBraille(obj) - - # Hack: When panning to the left in a document, we want to start at - # the right/bottom of each new object. For now, we'll pan there. - # When time permits, we'll give our braille code some smarts. - while self.panBrailleInDirection(panToLeft=False): - pass - self.refreshBraille(False) - - return True - - def panBrailleRight(self, inputEvent=None, panAmount=0): - """In document content, we want to use the panning keys to browse the - entire document. - """ - - if self.flatReviewPresenter.is_active() \ - or not self.isBrailleEndShowing() \ - or not self.utilities.isWebKitGtk(cthulhu_state.locusOfFocus): - return default.Script.panBrailleRight(self, inputEvent, panAmount) - - obj = self.utilities.findNextObject(cthulhu_state.locusOfFocus) - cthulhu.setLocusOfFocus(None, obj, notifyScript=False) - self.updateBraille(obj) - - # Hack: When panning to the right in a document, we want to start at - # the left/top of each new object. For now, we'll pan there. When time - # permits, we'll give our braille code some smarts. - while self.panBrailleInDirection(panToLeft=True): - pass - self.refreshBraille(False) - - return True - - def sayAll(self, inputEvent, obj=None, offset=None): - """Speaks the contents of the document beginning with the present - location. Overridden in this script because the sayAll could have - been started on an object without text (such as an image). - """ - - obj = obj or cthulhu_state.locusOfFocus - if not self.utilities.isWebKitGtk(obj): - return default.Script.sayAll(self, inputEvent, obj, offset) - - speech.sayAll(self.textLines(obj, offset), - self.__sayAllProgressCallback) - - return True - - def getTextSegments(self, obj, boundary, offset=0): - segments = [] - if not AXObject.supports_text(obj): - return segments - - length = AXText.get_character_count(obj) - if boundary == Atspi.TextBoundaryType.CHAR: - string, start, end = AXText.get_character_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.WORD_START: - string, start, end = AXText.get_word_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.LINE_START: - string, start, end = AXText.get_line_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.SENTENCE_START: - string, start, end = AXText.get_sentence_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.PARAGRAPH_START: - string, start, end = AXText.get_paragraph_at_offset(obj, offset) - else: - string, start, end = "", 0, 0 - while string and offset < length: - string = self.utilities.adjustForRepeats(string) - voice = self.speechGenerator.getVoiceForString(obj, string) - string = self.utilities.adjustForLinks(obj, string, start) - # Incrementing the offset should cause us to eventually reach - # the end of the text as indicated by a 0-length string and - # start and end offsets of 0. Sometimes WebKitGtk returns the - # final text segment instead. - if segments and [string, start, end, voice] == segments[-1]: - break - - segments.append([string, start, end, voice]) - offset = end + 1 - if boundary == Atspi.TextBoundaryType.CHAR: - string, start, end = AXText.get_character_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.WORD_START: - string, start, end = AXText.get_word_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.LINE_START: - string, start, end = AXText.get_line_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.SENTENCE_START: - string, start, end = AXText.get_sentence_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.PARAGRAPH_START: - string, start, end = AXText.get_paragraph_at_offset(obj, offset) - else: - string, start, end = "", 0, 0 - return segments - - def textLines(self, obj, offset=None): - """Creates a generator that can be used to iterate over each line - of a text object, starting at the caret offset. - - Arguments: - - obj: an Accessible that has a text specialization - - Returns an iterator that produces elements of the form: - [SayAllContext, acss], where SayAllContext has the text to be - spoken and acss is an ACSS instance for speaking the text. - """ - - self._sayAllIsInterrupted = False - self._inSayAll = False - if not obj: - return - - if AXObject.get_role(obj) == Atspi.Role.LINK: - obj = AXObject.get_parent(obj) - - document = self.utilities.getDocumentForObject(obj) - if not document or AXUtilities.is_busy(document): - return - - allTextObjs = self.utilities.findAllDescendants( - document, lambda x: AXObject.supports_text(x)) - allTextObjs = allTextObjs[allTextObjs.index(obj):len(allTextObjs)] - textObjs = [x for x in allTextObjs if AXObject.get_parent(x) not in allTextObjs] - if not textObjs: - return - - boundary = Atspi.TextBoundaryType.LINE_START - sayAllStyle = _settingsManager.getSetting('sayAllStyle') - if sayAllStyle == settings.SAYALL_STYLE_SENTENCE: - boundary = Atspi.TextBoundaryType.SENTENCE_START - - voices = _settingsManager.getSetting('voices') - systemVoice = voices.get(settings.SYSTEM_VOICE) - - self._inSayAll = True - offset = AXText.get_caret_offset(textObjs[0]) - for textObj in textObjs: - textSegments = self.getTextSegments(textObj, boundary, offset) - roleName = self.speechGenerator.getRoleName(textObj) - if roleName: - textSegments.append([roleName, 0, -1, systemVoice]) - - for (string, start, end, voice) in textSegments: - context = speechserver.SayAllContext(textObj, string, start, end) - self._sayAllContexts.append(context) - self.eventSynthesizer.scroll_into_view(obj, start, end) - yield [context, voice] - - offset = 0 - - self._inSayAll = False - self._sayAllContexts = [] - - def __sayAllProgressCallback(self, context, progressType): - if progressType == speechserver.SayAllContext.PROGRESS: - cthulhu.emitRegionChanged( - context.obj, context.currentOffset, context.currentEndOffset, cthulhu.SAY_ALL) - return - - obj = context.obj - cthulhu.setLocusOfFocus(None, obj, notifyScript=False) - - offset = context.currentOffset - if progressType == speechserver.SayAllContext.INTERRUPTED: - self._sayAllIsInterrupted = True - if isinstance(cthulhu_state.lastInputEvent, input_event.KeyboardEvent): - lastKey = cthulhu_state.lastInputEvent.event_string - if lastKey == "Down" and self._fastForwardSayAll(context): - return - elif lastKey == "Up" and self._rewindSayAll(context): - return - - self._inSayAll = False - self._sayAllContexts = [] - if not self._lastCommandWasStructNav: - if AXObject.supports_text(obj): - AXText.set_caret_offset(obj, offset) - cthulhu.emitRegionChanged(obj, offset) - return - - # SayAllContext.COMPLETED doesn't necessarily mean done with SayAll; - # just done with the current object. If we're still in SayAll, we do - # not want to set the caret (and hence set focus) in a link we just - # passed by. - if AXObject.supports_hypertext(obj): - links = AXHypertext.get_all_links(obj) - if [link for link in links - if AXHypertext.get_link_start_offset(link) - <= offset <= AXHypertext.get_link_end_offset(link)]: - return - - cthulhu.emitRegionChanged(obj, offset, mode=cthulhu.SAY_ALL) - if AXObject.supports_text(obj): - AXText.set_caret_offset(obj, offset) - - def getTextLineAtCaret(self, obj, offset=None, startOffset=None, endOffset=None): - """To-be-removed. Returns the string, caretOffset, startOffset.""" - - textLine = super().getTextLineAtCaret(obj, offset, startOffset, endOffset) - string = textLine[0] - if string and string.find(self.EMBEDDED_OBJECT_CHARACTER) == -1 \ - and AXUtilities.is_focused(obj): - return textLine - - textLine[0] = self.utilities.displayedText(obj) - if AXObject.supports_text(obj): - textLine[1] = min(textLine[1], AXText.get_character_count(obj)) - - return textLine - - def updateBraille(self, obj, **args): - """Updates the braille display to show the given object. - - Arguments: - - obj: the Accessible - """ - - if not _settingsManager.getSetting('enableBraille') \ - and not _settingsManager.getSetting('enableBrailleMonitor'): - debug.printMessage(debug.LEVEL_INFO, "BRAILLE: update disabled", True) - return - - if not obj: - return - - if not self.utilities.isWebKitGtk(obj) \ - or (not self.utilities.isInlineContainer(obj) \ - and not self.utilities.isTextListItem(obj)): - default.Script.updateBraille(self, obj, **args) - return - - brailleLine = self.getNewBrailleLine(clearBraille=True, addLine=True) - for child in AXObject.iter_children(obj): - if not self.utilities.onSameLine(child, AXObject.get_child(obj, 0)): - break - [regions, fRegion] = self.brailleGenerator.generateBraille(child) - self.addBrailleRegionsToLine(regions, brailleLine) - - if not brailleLine.regions: - [regions, fRegion] = self.brailleGenerator.generateBraille( - obj, role=Atspi.Role.PARAGRAPH) - self.addBrailleRegionsToLine(regions, brailleLine) - self.setBrailleFocus(fRegion) - - extraRegion = args.get('extraRegion') - if extraRegion: - self.addBrailleRegionToLine(extraRegion, brailleLine) - - self.refreshBraille() diff --git a/src/cthulhu/scripts/toolkits/WebKitGtk/script_utilities.py b/src/cthulhu/scripts/toolkits/WebKitGtk/script_utilities.py deleted file mode 100644 index 7efa861..0000000 --- a/src/cthulhu/scripts/toolkits/WebKitGtk/script_utilities.py +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." \ - "Copyright (c) 2011-2012 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -import re - -import cthulhu.script_utilities as script_utilities -import cthulhu.keybindings as keybindings -import cthulhu.cthulhu as cthulhu -import cthulhu.cthulhu_state as cthulhu_state -from cthulhu.ax_object import AXObject -from cthulhu.ax_hypertext import AXHypertext -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -############################################################################# -# # -# Utilities # -# # -############################################################################# - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - """Creates an instance of the Utilities class. - - Arguments: - - script: the script with which this instance is associated. - """ - super().__init__(script) - - def isWebKitGtk(self, obj): - """Returns True if this object is a WebKitGtk object.""" - - if not obj: - return False - - attrs = self.objectAttributes(obj) - return attrs.get('toolkit', '') in ['WebKitGtk', 'WebKitGTK'] - - def getCaretContext(self): - # TODO - JD: This is private, but it's only here temporarily until we - # have the shared web content support. - obj, offset = self._script._lastCaretContext - if not obj and self.isWebKitGtk(cthulhu_state.locusOfFocus): - obj, offset = super().getCaretContext() - - return obj, offset - - def setCaretContext(self, obj, offset): - # TODO - JD: This is private, but it's only here temporarily until we - # have the shared web content support. - self._script._lastCaretContext = obj, offset - cthulhu.setLocusOfFocus(None, obj, notifyScript=False) - - def setCaretPosition(self, obj, offset): - self.setCaretContext(obj, offset) - self.setCaretOffset(obj, offset) - - def isReadOnlyTextArea(self, obj): - """Returns True if obj is a text entry area that is read only.""" - - if not AXUtilities.is_entry(obj): - return False - - if AXUtilities.is_read_only(obj): - return True - - return AXUtilities.is_focusable(obj) and not AXUtilities.is_editable(obj) - - def displayedText(self, obj): - """Returns the text being displayed for an object. - - Arguments: - - obj: the object - - Returns the text being displayed for an object or None if there isn't - any text being shown. - """ - - text = script_utilities.Utilities.displayedText(self, obj) - if text and text != self.EMBEDDED_OBJECT_CHARACTER: - return text - - if AXUtilities.is_link(obj) or AXUtilities.is_list_item(obj): - children = [x for x in AXObject.iter_children(obj)] - text = ' '.join(map(self.displayedText, children)) - if not text: - text = self.linkBasename(obj) - - return text - - def getLineContentsAtOffset(self, obj, offset, layoutMode=True, useCache=True): - return self.get_objectsFromEOCs( - obj, offset, Atspi.TextBoundaryType.LINE_START) - - def get_objectContentsAtOffset(self, obj, offset=0, useCache=True): - return self.get_objectsFromEOCs(obj, offset) - - def get_objectsFromEOCs(self, obj, offset=None, boundary=None): - """Breaks the string containing a mixture of text and embedded object - characters into a list of (obj, startOffset, endOffset, string) tuples. - - Arguments - - obj: the object whose EOCs we need to expand into tuples - - offset: the character offset. If None, use the current offset. - - boundary: the text boundary type. If None, get all text. - - Returns a list of (obj, startOffset, endOffset, string) tuples. - """ - - if not AXObject.supports_text(obj): - return [(obj, 0, 1, '')] - - if not AXObject.supports_hypertext(obj): - return [(obj, 0, 1, '')] - - string = AXText.get_all_text(obj) - if not string: - return [(obj, 0, 1, '')] - - if offset is None: - offset = AXText.get_caret_offset(obj) - if boundary is None: - start = 0 - end = AXText.get_character_count(obj) - else: - if boundary == Atspi.TextBoundaryType.CHAR: - key, mods = self.lastKeyAndModifiers() - if (mods & keybindings.SHIFT_MODIFIER_MASK) and key == 'Right': - offset -= 1 - if boundary == Atspi.TextBoundaryType.CHAR: - segment, start, end = AXText.get_character_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.WORD_START: - segment, start, end = AXText.get_word_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.LINE_START: - segment, start, end = AXText.get_line_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.SENTENCE_START: - segment, start, end = AXText.get_sentence_at_offset(obj, offset) - elif boundary == Atspi.TextBoundaryType.PARAGRAPH_START: - segment, start, end = AXText.get_paragraph_at_offset(obj, offset) - else: - segment, start, end = "", 0, 0 - - pattern = re.compile(self.EMBEDDED_OBJECT_CHARACTER) - offsets = [m.start(0) for m in re.finditer(pattern, string)] - offsets = [x for x in offsets if start <= x < end] - - objects = [] - objs = [] - for offset in offsets: - if child := AXHypertext.get_child_at_offset(obj, offset): - objs.append(child) - - ranges = [self.getHyperlinkRange(x) for x in objs] - for i, (first, last) in enumerate(ranges): - objects.append((obj, start, first, string[start:first])) - objects.append((objs[i], first, last, '')) - start = last - objects.append((obj, start, end, string[start:end])) - objects = [x for x in objects if x[1] < x[2]] - - return objects - - def findPreviousObject(self, obj): - """Finds the object before this one.""" - - if obj is None: - return None - - if AXUtilities.is_link(obj): - obj = AXObject.get_parent(obj) - - prevObj = AXUtilities.get_previous_object(obj) - if AXUtilities.is_list(prevObj) and AXObject.get_child_count(prevObj): - child = AXObject.get_child(prevObj, -1) - if self.isTextListItem(child): - prevObj = child - - return prevObj - - def findNextObject(self, obj): - """Finds the object after this one.""" - - if obj is None: - return None - - if AXUtilities.is_link(obj): - obj = AXObject.get_parent(obj) - - nextObj = AXUtilities.get_next_object(obj) - if AXUtilities.is_list(nextObj) and AXObject.get_child_count(nextObj): - child = AXObject.get_child(nextObj, 0) - if self.isTextListItem(child): - nextObj = child - - return nextObj - - def isTextListItem(self, obj): - """Returns True if obj is an item in a non-selectable list.""" - - if not AXUtilities.is_list_item(obj): - return False - - parent = AXObject.get_parent(obj) - if parent is None: - return False - - return not AXUtilities.is_focusable(parent) - - def isInlineContainer(self, obj): - """Returns True if obj is an inline/non-wrapped container.""" - - if AXUtilities.is_section(obj): - if AXObject.get_child_count(obj) > 1: - return self.onSameLine(AXObject.get_child(obj, 0), AXObject.get_child(obj, 1)) - return False - - if AXUtilities.is_list(obj): - if AXUtilities.is_focusable(obj): - return False - childCount = AXObject.get_child_count(obj) - if not childCount: - return AXObject.supports_text(obj) - if childCount == 1: - return False - return self.onSameLine(AXObject.get_child(obj, 0), AXObject.get_child(obj, 1)) - - return False - - def isEmbeddedDocument(self, obj): - if not self.isWebKitGtk(obj): - return False - - if not AXUtilities.is_document(obj): - return False - - parent = AXObject.get_parent(obj) - if not (parent and self.isWebKitGtk(parent)): - return False - - parent = AXObject.get_parent(parent) - if not (parent and not self.isWebKitGtk(parent)): - return False - - return True - - def setCaretAtStart(self, obj): - def implementsText(obj): - return not AXUtilities.is_list(obj) and AXObject.supports_text(obj) - - child = obj - if not implementsText(obj): - child = AXObject.find_descendant(obj, implementsText) - if not child: - return None, -1 - - index = -1 - char_count = AXText.get_character_count(child) - for i in range(char_count): - if AXText.set_caret_offset(child, i): - index = i - break - - return child, index - - def treatAsBrowser(self, obj): - return self.isEmbeddedDocument(obj) - - def inDocumentContent(self, obj=None): - obj = obj or cthulhu_state.locusOfFocus - return self.isWebKitGtk(obj) diff --git a/src/cthulhu/scripts/toolkits/WebKitGtk/speech_generator.py b/src/cthulhu/scripts/toolkits/WebKitGtk/speech_generator.py deleted file mode 100644 index 3ffb46b..0000000 --- a/src/cthulhu/scripts/toolkits/WebKitGtk/speech_generator.py +++ /dev/null @@ -1,203 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs" \ - "Copyright (c) 2011-2012 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import cthulhu.keynames as keynames -import cthulhu.object_properties as object_properties -import cthulhu.settings as settings -import cthulhu.settings_manager as settings_manager -import cthulhu.speech_generator as speech_generator -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -_settingsManager = settings_manager.getManager() - -######################################################################## -# # -# Custom SpeechGenerator # -# # -######################################################################## - -class SpeechGenerator(speech_generator.SpeechGenerator): - """Provides a speech generator specific to WebKitGtk widgets.""" - - def __init__(self, script): - speech_generator.SpeechGenerator.__init__(self, script) - - def getVoiceForString(self, obj, string, **args): - voice = settings.voices[settings.DEFAULT_VOICE] - if string.isupper(): - voice = settings.voices[settings.UPPERCASE_VOICE] - - return voice - - def _generateLabel(self, obj, **args): - result = super()._generateLabel(obj, **args) - if result or not self._script.utilities.isWebKitGtk(obj): - return result - - role = args.get('role', AXObject.get_role(obj)) - inferRoles = [Atspi.Role.CHECK_BOX, - Atspi.Role.COMBO_BOX, - Atspi.Role.ENTRY, - Atspi.Role.LIST, - Atspi.Role.PASSWORD_TEXT, - Atspi.Role.RADIO_BUTTON] - if role not in inferRoles: - return result - - label, objects = self._script.labelInference.infer(obj) - if label: - result.append(label) - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - - return result - - def __generateHeadingRole(self, obj): - result = [] - role = Atspi.Role.HEADING - level = self._script.utilities.headingLevel(obj) - if level: - result.append(object_properties.ROLE_HEADING_LEVEL_SPEECH % { - 'role': self.getLocalizedRoleName(obj, role=role), - 'level': level}) - else: - result.append(self.getLocalizedRoleName(obj, role=role)) - - return result - - def _generateRoleName(self, obj, **args): - if _settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - role = args.get('role', AXObject.get_role(obj)) - force = args.get('force', False) - - doNotSpeak = [Atspi.Role.UNKNOWN] - if not force: - doNotSpeak.extend([Atspi.Role.FORM, - Atspi.Role.LABEL, - Atspi.Role.MENU_ITEM, - Atspi.Role.LIST_ITEM, - Atspi.Role.PARAGRAPH, - Atspi.Role.SECTION, - Atspi.Role.TABLE_CELL]) - - if role not in doNotSpeak: - if role == Atspi.Role.IMAGE: - link = AXObject.find_ancestor(obj, AXUtilities.is_link) - if link: - result.append(self.getLocalizedRoleName(link)) - elif role == Atspi.Role.HEADING: - result.extend(self.__generateHeadingRole(obj)) - else: - result.append(self.getLocalizedRoleName(obj, role=role)) - if AXObject.get_role(AXObject.get_parent(obj)) == Atspi.Role.HEADING: - result.extend(self.__generateHeadingRole(AXObject.get_parent(obj))) - - if result: - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - if role == Atspi.Role.LINK and AXObject.get_child_count(obj): - child = AXObject.get_child(obj, 0) - if not AXObject.get_role(child) == Atspi.Role.IMAGE: - return result - # If this is a link with a child which is an image, we - # want to indicate that. - # - result.append(self.getLocalizedRoleName(child)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - return result - - def _generateAncestors(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the text of the ancestors for - the object. This is typically used to present the context for - an object (e.g., the names of the window, the panels, etc., - that the object is contained in). If the 'priorObj' attribute - of the args dictionary is set, only the differences in - ancestry between the 'priorObj' and the current obj will be - computed. The 'priorObj' is typically set by Cthulhu to be the - previous object with focus. - """ - - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.LINK: - return [] - - args['stopAtRoles'] = [Atspi.Role.DOCUMENT_FRAME, - Atspi.Role.DOCUMENT_WEB, - Atspi.Role.EMBEDDED, - Atspi.Role.INTERNAL_FRAME, - Atspi.Role.FORM, - Atspi.Role.MENU_BAR, - Atspi.Role.TOOL_BAR] - args['skipRoles'] = [Atspi.Role.PARAGRAPH, - Atspi.Role.LIST_ITEM, - Atspi.Role.TEXT] - - return speech_generator.SpeechGenerator._generateAncestors( - self, obj, **args) - - def _generateMnemonic(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the mnemonic for the object, or - an empty array if no mnemonic can be found. - """ - - if _settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not (_settingsManager.getSetting('enableMnemonicSpeaking') \ - or args.get('forceMnemonic', False)): - return [] - - if not self._script.utilities.isWebKitGtk(obj): - return speech_generator.SpeechGenerator._generateMnemonic( - self, obj, **args) - - result = [] - mnemonic, shortcut, accelerator = \ - self._script.utilities.mnemonicShortcutAccelerator(obj) - if shortcut: - if _settingsManager.getSetting('speechVerbosityLevel') == \ - settings.VERBOSITY_LEVEL_VERBOSE: - shortcut = f'Alt Shift {shortcut}' - result = [keynames.localizeKeySequence(shortcut)] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - return result diff --git a/src/cthulhu/scripts/toolkits/__init__.py b/src/cthulhu/scripts/toolkits/__init__.py deleted file mode 100644 index 0b6f488..0000000 --- a/src/cthulhu/scripts/toolkits/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__all__ = ['clutter', - 'Chromium', - 'gtk', - 'GAIL', - 'Gecko', - 'J2SE-access-bridge', - 'Qt', - 'VCL.py', - 'WebKitGtk'] diff --git a/src/cthulhu/scripts/toolkits/clutter/__init__.py b/src/cthulhu/scripts/toolkits/clutter/__init__.py deleted file mode 100644 index b006f6c..0000000 --- a/src/cthulhu/scripts/toolkits/clutter/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script diff --git a/src/cthulhu/scripts/toolkits/clutter/meson.build b/src/cthulhu/scripts/toolkits/clutter/meson.build deleted file mode 100644 index d57cce0..0000000 --- a/src/cthulhu/scripts/toolkits/clutter/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -clutter_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - clutter_python_sources, - subdir: 'cthulhu/scripts/toolkits/clutter' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/toolkits/clutter/script.py b/src/cthulhu/scripts/toolkits/clutter/script.py deleted file mode 100644 index 20d6331..0000000 --- a/src/cthulhu/scripts/toolkits/clutter/script.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010-2013 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.scripts.default as default -from .script_utilities import Utilities - - -class Script(default.Script): - - def __init__(self, app): - default.Script.__init__(self, app) - - def getUtilities(self): - return Utilities(self) diff --git a/src/cthulhu/scripts/toolkits/clutter/script_utilities.py b/src/cthulhu/scripts/toolkits/clutter/script_utilities.py deleted file mode 100644 index cdf87d5..0000000 --- a/src/cthulhu/scripts/toolkits/clutter/script_utilities.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.script_utilities as script_utilities - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - script_utilities.Utilities.__init__(self, script) - - def willEchoCharacter(self, event): - """Given a keyboard event containing an alphanumeric key, - determine if the script is likely to echo it as a character.""" - - # There is currently a bug in which we don't get the inserted text - # from the object:text-changed:insert event. We cannot echo what we - # don't receive. - return False diff --git a/src/cthulhu/scripts/toolkits/gtk/__init__.py b/src/cthulhu/scripts/toolkits/gtk/__init__.py deleted file mode 100644 index fec8f65..0000000 --- a/src/cthulhu/scripts/toolkits/gtk/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script -from .script_utilities import Utilities diff --git a/src/cthulhu/scripts/toolkits/gtk/meson.build b/src/cthulhu/scripts/toolkits/gtk/meson.build deleted file mode 100644 index ec195ff..0000000 --- a/src/cthulhu/scripts/toolkits/gtk/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -gtk_python_sources = files([ - '__init__.py', - 'script.py', - 'script_utilities.py', -]) - -python3.install_sources( - gtk_python_sources, - subdir: 'cthulhu/scripts/toolkits/gtk' -) \ No newline at end of file diff --git a/src/cthulhu/scripts/toolkits/gtk/script.py b/src/cthulhu/scripts/toolkits/gtk/script.py deleted file mode 100644 index 8234918..0000000 --- a/src/cthulhu/scripts/toolkits/gtk/script.py +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013-2014 Igalia, S.L." -__license__ = "LGPL" - -import cthulhu.debug as debug -import cthulhu.cthulhu as cthulhu -import cthulhu.cthulhu_state as cthulhu_state -import cthulhu.scripts.default as default -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - -from .script_utilities import Utilities - -class Script(default.Script): - - def __init__(self, app): - default.Script.__init__(self, app) - - def getUtilities(self): - return Utilities(self) - - def deactivate(self): - """Called when this script is deactivated.""" - - self.utilities.clearCachedObjects() - super().deactivate() - - def locus_of_focus_changed(self, event, oldFocus, newFocus): - """Handles changes of focus of interest to the script.""" - - if self.utilities.isToggleDescendantOfComboBox(newFocus): - newFocus = AXObject.find_ancestor(newFocus, AXUtilities.is_combo_box) or newFocus - cthulhu.setLocusOfFocus(event, newFocus, False) - elif self.utilities.isInOpenMenuBarMenu(newFocus): - window = self.utilities.topLevelObject(newFocus) - windowChanged = window and cthulhu_state.activeWindow != window - if windowChanged: - cthulhu.setActiveWindow(window) - - super().locus_of_focus_changed(event, oldFocus, newFocus) - - def onActiveDescendantChanged(self, event): - """Callback for object:active-descendant-changed accessibility events.""" - - if not self.utilities.isTypeahead(cthulhu_state.locusOfFocus): - msg = "GTK: locusOfFocus is not typeahead. Passing along to default script." - debug.printMessage(debug.LEVEL_INFO, msg, True) - super().onActiveDescendantChanged(event) - return - - msg = "GTK: locusOfFocus believed to be typeahead. Presenting change." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.presentObject(event.any_data, interrupt=True) - - def onCheckedChanged(self, event): - """Callback for object:state-changed:checked accessibility events.""" - - obj = event.source - if self.utilities.isSameObject(obj, cthulhu_state.locusOfFocus): - default.Script.onCheckedChanged(self, event) - return - - # Present changes of child widgets of GtkListBox items - if not AXObject.find_ancestor(obj, AXUtilities.is_list_box): - return - - self.presentObject(obj, alreadyFocused=True, interrupt=True) - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - # NOTE: This event type is deprecated and Cthulhu should no longer use it. - # This callback remains just to handle bugs in applications and toolkits - # that fail to reliably emit object:state-changed:focused events. - - if self.utilities.eventIsCanvasNoise(event): - return - - if self.utilities.isLayoutOnly(event.source): - return - - if event.source == self.mouseReviewer.getCurrentItem(): - msg = "GTK: Event source is current mouse review item" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - if self.utilities.isTypeahead(cthulhu_state.locusOfFocus) \ - and AXObject.supports_table(event.source) \ - and not AXUtilities.is_focused(event.source): - return - - ancestor = AXObject.find_ancestor(cthulhu_state.locusOfFocus, lambda x: x == event.source) - if not ancestor: - cthulhu.setLocusOfFocus(event, event.source) - return - - if AXObject.supports_table(ancestor): - return - - if AXUtilities.is_menu(ancestor): - if AXUtilities.is_selected(cthulhu_state.locusOfFocus): - msg = "GTK: Event source is ancestor of selected focus. Ignoring." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - msg = "GTK: Event source is ancestor of unselected focus. Updating focus." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - cthulhu.setLocusOfFocus(event, event.source) - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if self.utilities.isUselessPanel(event.source): - msg = "GTK: Event source believed to be useless panel" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - super().onFocusedChanged(event) - - def onSelectedChanged(self, event): - """Callback for object:state-changed:selected accessibility events.""" - - if self.utilities.isEntryCompletionPopupItem(event.source): - if event.detail1: - cthulhu.setLocusOfFocus(event, event.source) - return - if cthulhu_state.locusOfFocus == event.source: - cthulhu.setLocusOfFocus(event, None) - return - - if AXUtilities.is_icon_or_canvas(event.source) \ - and self.utilities.handleContainerSelectionChange(AXObject.get_parent(event.source)): - return - - super().onSelectedChanged(event) - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - if self.utilities.isComboBoxWithToggleDescendant(event.source) \ - and self.utilities.isOrDescendsFrom(cthulhu_state.locusOfFocus, event.source): - super().onSelectionChanged(event) - return - - isFocused = AXUtilities.is_focused(event.source) - if AXUtilities.is_combo_box(event.source) and not isFocused: - return - - if not isFocused and self.utilities.isTypeahead(cthulhu_state.locusOfFocus): - msg = "GTK: locusOfFocus believed to be typeahead. Presenting change." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - selectedChildren = self.utilities.selectedChildren(event.source) - for child in selectedChildren: - if not self.utilities.isLayoutOnly(child): - self.presentObject(child) - return - - if AXUtilities.is_layered_pane(event.source) \ - and self.utilities.selectedChildCount(event.source) > 1: - return - - super().onSelectionChanged(event) - - def onShowingChanged(self, event): - """Callback for object:state-changed:showing accessibility events.""" - - if not event.detail1: - super().onShowingChanged(event) - return - - if self.utilities.isPopOver(event.source) \ - or AXUtilities.is_alert(event.source) \ - or AXUtilities.is_info_bar(event.source): - if AXUtilities.is_application(AXObject.get_parent(event.source)): - return - self.presentObject(event.source, interrupt=True) - return - - super().onShowingChanged(event) - - def onTextDeleted(self, event): - """Callback for object:text-changed:delete accessibility events.""" - - if not self.utilities.isShowingAndVisible(event.source): - tokens = ["GTK:", event.source, "is not showing and visible"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - super().onTextDeleted(event) - - def onTextInserted(self, event): - """Callback for object:text-changed:insert accessibility events.""" - - if not self.utilities.isShowingAndVisible(event.source): - tokens = ["GTK:", event.source, "is not showing and visible"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - super().onTextInserted(event) - - def onTextSelectionChanged(self, event): - """Callback for object:text-selection-changed accessibility events.""" - - obj = event.source - if not self.utilities.isSameObject(obj, cthulhu_state.locusOfFocus): - return - - default.Script.onTextSelectionChanged(self, event) - - def isActivatableEvent(self, event): - if self.utilities.eventIsCanvasNoise(event): - return False - - if self.utilities.isUselessPanel(event.source): - return False - - return super().isActivatableEvent(event) diff --git a/src/cthulhu/scripts/toolkits/gtk/script_utilities.py b/src/cthulhu/scripts/toolkits/gtk/script_utilities.py deleted file mode 100644 index 449c22f..0000000 --- a/src/cthulhu/scripts/toolkits/gtk/script_utilities.py +++ /dev/null @@ -1,249 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2013-2014 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -import re - -import cthulhu.debug as debug -import cthulhu.script_utilities as script_utilities -import cthulhu.cthulhu_state as cthulhu_state -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_relation import AXUtilitiesRelation - - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - super().__init__(script) - self._isComboBoxWithToggleDescendant = {} - self._isToggleDescendantOfComboBox = {} - self._isTypeahead = {} - self._isUselessPanel = {} - self._isLayoutOnly = {} - - def clearCachedObjects(self): - self._isComboBoxWithToggleDescendant = {} - self._isToggleDescendantOfComboBox = {} - self._isTypeahead = {} - self._isUselessPanel = {} - self._isLayoutOnly = {} - - def infoBar(self, root): - return AXObject.find_descendant(root, AXUtilities.is_info_bar) - - def isComboBoxWithToggleDescendant(self, obj): - if not AXUtilities.is_combo_box(obj): - return False - - rv = self._isComboBoxWithToggleDescendant.get(hash(obj)) - if rv is not None: - return rv - - for child in AXObject.iter_children(obj): - if not AXUtilities.is_filler(child): - continue - - toggle = AXObject.find_descendant(child, AXUtilities.is_toggle_button) - rv = toggle is not None - if toggle: - self._isToggleDescendantOfComboBox[hash(toggle)] = True - break - - self._isComboBoxWithToggleDescendant[hash(obj)] = rv - return rv - - def isLayoutOnly(self, obj): - rv = self._isLayoutOnly.get(hash(obj)) - if rv is not None: - if rv: - tokens = ["GTK:", obj, "is deemed to be layout only"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - rv = super().isLayoutOnly(obj) - self._isLayoutOnly[hash(obj)] = rv - return rv - - def isToggleDescendantOfComboBox(self, obj): - if not AXUtilities.is_toggle_button(obj): - return False - - rv = self._isToggleDescendantOfComboBox.get(hash(obj)) - if rv is not None: - return rv - - comboBox = AXObject.find_ancestor(obj, AXUtilities.is_combo_box) - if comboBox: - self._isComboBoxWithToggleDescendant[hash(comboBox)] = True - - rv = comboBox is not None - self._isToggleDescendantOfComboBox[hash(obj)] = rv - return rv - - def isTypeahead(self, obj): - if not obj or AXObject.is_dead(obj): - return False - - if not AXUtilities.is_text(obj): - return False - - rv = self._isTypeahead.get(hash(obj)) - if rv is not None: - return rv - - parent = AXObject.get_parent(obj) - while parent and self.isLayoutOnly(parent): - parent = AXObject.get_parent(parent) - - rv = AXUtilities.is_window(parent) - self._isTypeahead[hash(obj)] = rv - return rv - - def isSearchEntry(self, obj, focusedOnly=False): - # Another example of why we need subrole support in ATK and AT-SPI2. - if not (AXObject.get_name(obj) and AXUtilities.is_single_line(obj)): - return False - - if focusedOnly and not AXUtilities.is_focused(obj): - return False - - icons = [x for x in AXObject.iter_children(obj, AXUtilities.is_icon)] - if icons: - return True - - return False - - def isEntryCompletionPopupItem(self, obj): - return AXUtilities.is_table_cell(obj) \ - and AXObject.find_ancestor(obj, AXUtilities.is_window) is not None - - def isPopOver(self, obj): - return bool(AXUtilitiesRelation.get_is_popup_for(obj)) - - def isSameObject(self, obj1, obj2, comparePaths=False, ignoreNames=False, - ignoreDescriptions=True): - return super().isSameObject(obj1, obj2, comparePaths, ignoreNames, False) - - def isUselessPanel(self, obj): - if not AXUtilities.is_panel(obj): - return False - - rv = self._isUselessPanel.get(hash(obj)) - if rv is not None: - return rv - - childCount = AXObject.get_child_count(obj) - name = AXObject.get_name(obj) - rv = not (name or childCount or AXObject.supports_text(obj)) - self._isUselessPanel[hash(obj)] = rv - return rv - - def rgbFromString(self, attributeValue): - regex = re.compile(r"rgb|[^\w,]", re.IGNORECASE) - string = re.sub(regex, "", attributeValue) - red, green, blue = string.split(",") - - return int(red) >> 8, int(green) >> 8, int(blue) >> 8 - - def isZombie(self, obj): - rv = super().isZombie(obj) - if rv and self.isLink(obj) and AXObject.get_index_in_parent(obj) == -1: - tokens = ["GTK: Hacking around bug 759736 for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return rv - - def eventIsCanvasNoise(self, event): - if not AXUtilities.is_canvas(event.source): - return False - - if not cthulhu_state.activeWindow: - msg = "GTK: No active window" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - topLevel = self.topLevelObject(event.source) - if not self.isSameObject(topLevel, cthulhu_state.activeWindow): - msg = "GTK: Event is believed to be canvas noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def _adjustPointForObj(self, obj, x, y, coordType): - if not AXUtilities.is_single_line(obj) \ - or not AXObject.supports_editable_text(obj): - return x, y - - text = self.queryNonEmptyText(obj) - if not text: - return x, y - - if not AXObject.supports_component(obj): - return x, y - - objBox = Atspi.Component.get_extents(obj, coordType) - stringBox = Atspi.Text.get_range_extents( - obj, 0, AXText.get_character_count(obj), coordType) - if self.intersection(objBox, stringBox) != (0, 0, 0, 0): - return x, y - - tokens = ["GTK: text bounds", stringBox, "not in obj bounds", objBox] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # This is where the string starts; not the widget. - boxX, boxY = stringBox[0], stringBox[1] - - # Window Coordinates should be relative to the window; not the widget. - # But broken interface is broken, and this appears to be what is being - # exposed. And we need this information to get the widget's x and y. - charExtents = Atspi.Text.get_character_extents(obj, 0, Atspi.CoordType.WINDOW) - if 0 < charExtents[0] < charExtents[2]: - boxX -= charExtents[0] - if 0 < charExtents[1] < charExtents[3]: - boxY -= charExtents[1] - - # The point relative to the widget: - relX = x - objBox[0] - relY = y - objBox[1] - - # The point relative to our adjusted bounding box: - newX = boxX + relX - newY = boxY + relY - - msg = f"GTK: Adjusted ({x}, {y}) to ({newX}, {newY})" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return newX, newY diff --git a/src/cthulhu/scripts/toolkits/meson.build b/src/cthulhu/scripts/toolkits/meson.build deleted file mode 100644 index 28b4128..0000000 --- a/src/cthulhu/scripts/toolkits/meson.build +++ /dev/null @@ -1,18 +0,0 @@ -toolkits_python_sources = files([ - '__init__.py', - 'VCL.py', -]) - -python3.install_sources( - toolkits_python_sources, - subdir: 'cthulhu/scripts/toolkits' -) - -subdir('Chromium') -subdir('GAIL') -subdir('Gecko') -subdir('J2SE-access-bridge') -subdir('Qt') -subdir('WebKitGtk') -subdir('clutter') -subdir('gtk') \ No newline at end of file diff --git a/src/cthulhu/scripts/web/__init__.py b/src/cthulhu/scripts/web/__init__.py deleted file mode 100644 index 2fc8955..0000000 --- a/src/cthulhu/scripts/web/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -from .script import Script -from .speech_generator import SpeechGenerator -from .braille_generator import BrailleGenerator -from .script_utilities import Utilities -from .tutorial_generator import TutorialGenerator diff --git a/src/cthulhu/scripts/web/bookmarks.py b/src/cthulhu/scripts/web/bookmarks.py deleted file mode 100644 index 9fb790f..0000000 --- a/src/cthulhu/scripts/web/bookmarks.py +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -from cthulhu import bookmarks -from cthulhu import messages - - -class Bookmarks(bookmarks.Bookmarks): - - def __init__(self, script): - super().__init__(script) - self._currentbookmarkindex = {} - - def addBookmark(self, script, inputEvent): - """Add an in-page accessible object bookmark for this key and URI.""" - - index = (inputEvent.hw_code, self.getURIKey()) - obj, characterOffset = self._script.utilities.getCaretContext() - path = self._objToPath() - self._bookmarks[index] = path, characterOffset - self._script.presentMessage(messages.BOOKMARK_ENTERED) - - def goToBookmark(self, script, inputEvent, index=None): - """Go to the bookmark indexed at this key and this page's URI.""" - - index = index or (inputEvent.hw_code, self.getURIKey()) - try: - path, offset = self._bookmarks[index] - except KeyError: - self._script.systemBeep() - return - - obj = self.pathToObj(path) - if not obj: - self._script.systemBeep() - return - - self._script.utilities.setCaretPosition(obj, offset) - contents = self._script.utilities.get_objectContentsAtOffset(obj, offset) - self._script.speakContents(contents) - self._script.displayContents(contents) - self._currentbookmarkindex[index[1]] = index[0] - - def saveBookmarks(self, script, inputEvent): - """Save the bookmarks for this script.""" - - saved = {} - for index, bookmark in self._bookmarks.items(): - saved[index] = bookmark[0], bookmark[1] - - try: - self.saveBookmarksToDisk(saved) - self._script.presentMessage(messages.BOOKMARKS_SAVED) - except IOError: - self._script.presentMessage(messages.BOOKMARKS_SAVED_FAILURE) - - for o in self._saveObservers: - o() - - def goToNextBookmark(self, script, inputEvent): - """Go to the next bookmark location.""" - - # The convenience of using a dictionary to add/goto a bookmark is offset - # by the difficulty in finding the next bookmark. We will need to sort - # our keys to determine the next bookmark on a page-by-page basis. - bm_keys = list(self._bookmarks.keys()) - current_uri = self.getURIKey() - - # mine out the hardware keys for this page and sort them - thispage_hwkeys = [] - for bm_key in bm_keys: - if bm_key[1] == current_uri: - thispage_hwkeys.append(bm_key[0]) - thispage_hwkeys.sort() - - if len(thispage_hwkeys) == 0: - self._script.systemBeep() - return - - if len(thispage_hwkeys) == 1 or current_uri not in self._currentbookmarkindex: - self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri)) - return - - try: - index = thispage_hwkeys.index(self._currentbookmarkindex[current_uri]) - self.goToBookmark(None, index=(thispage_hwkeys[index+1], current_uri)) - except (ValueError, KeyError, IndexError): - self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri)) - - def goToPrevBookmark(self, script, inputEvent): - """Go to the previous bookmark location.""" - - bm_keys = list(self._bookmarks.keys()) - current_uri = self.getURIKey() - - # mine out the hardware keys for this page and sort them - thispage_hwkeys = [] - for bm_key in bm_keys: - if bm_key[1] == current_uri: - thispage_hwkeys.append(bm_key[0]) - thispage_hwkeys.sort() - - if len(thispage_hwkeys) == 0: - self._script.systemBeep() - return - - if len(thispage_hwkeys) == 1 or current_uri not in self._currentbookmarkindex: - self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri)) - return - - try: - index = thispage_hwkeys.index(self._currentbookmarkindex[current_uri]) - self.goToBookmark(None, index=(thispage_hwkeys[index-1], current_uri)) - except (ValueError, KeyError, IndexError): - self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri)) diff --git a/src/cthulhu/scripts/web/braille_generator.py b/src/cthulhu/scripts/web/braille_generator.py deleted file mode 100644 index af91208..0000000 --- a/src/cthulhu/scripts/web/braille_generator.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2011 Cthulhu Team" \ - "Copyright (c) 2011-2015 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu import braille -from cthulhu import braille_generator -from cthulhu import debug -from cthulhu import messages -from cthulhu import object_properties -from cthulhu import cthulhu_state -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities - - -class BrailleGenerator(braille_generator.BrailleGenerator): - - def __init__(self, script): - super().__init__(script) - - def getLocalizedRoleName(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super().getLocalizedRoleName(obj, **args) - - roledescription = self._script.utilities.getRoleDescription(obj, True) - if roledescription: - return roledescription - - return super().getLocalizedRoleName(obj, **args) - - def _generateRoleName(self, obj, **args): - """Prevents some roles from being displayed.""" - - if not self._script.utilities.inDocumentContent(obj): - return super()._generateRoleName(obj, **args) - - roledescription = self._script.utilities.getRoleDescription(obj, True) - if roledescription: - return [roledescription] - - doNotDisplay = [Atspi.Role.FORM, - Atspi.Role.PARAGRAPH, - Atspi.Role.STATIC, - Atspi.Role.SECTION, - Atspi.Role.REDUNDANT_OBJECT, - Atspi.Role.UNKNOWN] - - if not AXUtilities.is_focusable(obj): - doNotDisplay.extend([Atspi.Role.LIST, - Atspi.Role.LIST_ITEM, - Atspi.Role.COLUMN_HEADER, - Atspi.Role.ROW_HEADER, - Atspi.Role.TABLE_CELL, - Atspi.Role.PANEL]) - - if args.get('startOffset') is not None and args.get('endOffset') is not None: - doNotDisplay.append(Atspi.Role.ALERT) - - result = [] - role = args.get('role', AXObject.get_role(obj)) - - if role == Atspi.Role.HEADING: - level = self._script.utilities.headingLevel(obj) - result.append(object_properties.ROLE_HEADING_LEVEL_BRAILLE % level) - - elif self._script.utilities.isLink(obj) and obj == cthulhu_state.locusOfFocus: - if AXUtilities.is_image(AXObject.get_parent(obj)): - result.append(messages.IMAGE_MAP_LINK) - - elif role not in doNotDisplay: - label = self._script.utilities.labelForCellCoordinates(obj) - if label: - result.append(label) - else: - result = super()._generateRoleName(obj, **args) - - index = args.get('index', 0) - total = args.get('total', 1) - if index == total - 1 and role != Atspi.Role.HEADING \ - and (role == Atspi.Role.IMAGE or self._script.utilities.queryNonEmptyText(obj)): - heading = AXObject.find_ancestor(obj, AXUtilities.is_heading) - if heading is not None: - result.extend(self._generateRoleName(heading)) - - return result - - def _generateLabelOrName(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateLabelOrName(obj, **args) - - if self._script.utilities.isTextBlockElement(obj): - return [] - - if AXUtilities.is_editable(obj) \ - and self._script.utilities.isCodeDescendant(obj): - return [] - - return self._generateName(obj, **args) - - def _generateLabel(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateLabel(obj, **args) - - label, objects = self._script.utilities.inferLabelFor(obj) - if label: - return [label] - - return super()._generateLabel(obj, **args) - - def _generateLabelAndName(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateLabelAndName(obj, **args) - - if self._script.utilities.isTextBlockElement(obj): - return [] - - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.LABEL and AXObject.supports_text(obj): - return [] - - return super()._generateLabelAndName(obj, **args) - - def _generateDescription(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateDescription(obj, **args) - - if self._script.utilities.preferDescriptionOverName(obj): - return [] - - return super()._generateDescription(obj, **args) - - def _generateName(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateName(obj, **args) - - brailleLabel = self._script.utilities.objectAttributes(obj).get("braillelabel") - if brailleLabel: - return [brailleLabel] - - if self._script.utilities.preferDescriptionOverName(obj): - return [AXObject.get_description(obj)] - - if AXObject.get_name(obj) and not self._script.utilities.hasValidName(obj): - return [] - - result = super()._generateName(obj, **args) - if result and result[0] and not self._script.utilities.hasExplicitName(obj): - result[0] = result[0].strip() - elif not result and AXUtilities.is_check_box(obj): - gridCell = AXObject.find_ancestor(obj, self._script.utilities.isGridCell) - if gridCell: - return super()._generateName(gridCell, **args) - - return result - - def _generateExpandedEOCs(self, obj, **args): - """Returns the expanded embedded object characters for an object.""" - - if not self._script.utilities.inDocumentContent(obj): - return super()._generateExpandedEOCs(obj, **args) - - result = [] - startOffset = args.get('startOffset', 0) - endOffset = args.get('endOffset', -1) - text = self._script.utilities.expandEOCs(obj, startOffset, endOffset) - if text: - result.append(text) - - return result - - def _generateRealActiveDescendantDisplayedText(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateRealActiveDescendantDisplayedText(obj, **args) - - rad = self._script.utilities.realActiveDescendant(obj) - return self._generateDisplayedText(rad, **args) - - def _generateTableCellRow(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateTableCellRow(obj, **args) - - if not self._script.utilities.shouldReadFullRow(obj): - return self._generateRealTableCell(obj, **args) - - row = AXObject.find_ancestor(obj, AXUtilities.is_table_row) - if row and AXObject.get_name(row) and not self._script.utilities.isLayoutOnly(row): - return self.generate(row, includeContext=False) - - return super()._generateTableCellRow(obj, **args) - - def generateBraille(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - tokens = ["WEB:", obj, "is not in document content. Calling default braille generator."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return super().generateBraille(obj, **args) - - tokens = ["WEB: Generating braille for document object", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - result = [] - - args['includeContext'] = not self._script.utilities.inDocumentContent(obj) - oldRole = None - if self._script.utilities.isClickableElement(obj) \ - or self._script.utilities.isLink(obj): - oldRole = self._overrideRole(Atspi.Role.LINK, args) - elif self._script.utilities.isCustomImage(obj): - oldRole = self._overrideRole(Atspi.Role.IMAGE, args) - elif self._script.utilities.isAnchor(obj): - oldRole = self._overrideRole(Atspi.Role.STATIC, args) - elif self._script.utilities.treatAsDiv(obj, offset=args.get('startOffset')): - oldRole = self._overrideRole(Atspi.Role.SECTION, args) - elif self._script.utilities.treatAsEntry(obj): - oldRole = self._overrideRole(Atspi.Role.ENTRY, args) - - if AXUtilities.is_menu_item(obj): - comboBox = AXObject.find_ancestor(obj, AXUtilities.is_combo_box) - if comboBox and not AXUtilities.is_expanded(comboBox): - obj = comboBox - result.extend(super().generateBraille(obj, **args)) - del args['includeContext'] - if oldRole: - self._restoreRole(oldRole, args) - - return result - - def _generateEol(self, obj, **args): - if self._script.utilities.isContentEditableWithEmbeddedObjects(obj): - return [] - - if AXUtilities.is_editable(obj) \ - or not self._script.utilities.inDocumentContent(obj): - return super()._generateEol(obj, **args) - - return [] - - def generateContents(self, contents, **args): - if not len(contents): - return [] - - result = [] - contents = self._script.utilities.filterContentsForPresentation(contents, True) - - document = args.get("documentFrame") - obj, offset = self._script.utilities.getCaretContext(documentFrame=document) - index = self._script.utilities.findObjectInContents(obj, offset, contents) - - lastRegion = None - focusedRegion = None - for i, content in enumerate(contents): - acc, start, end, string = content - regions, fRegion = self.generateBraille( - acc, startOffset=start, endOffset=end, string=string, - index=i, total=len(contents)) - if not regions: - continue - - if i == index: - focusedRegion = fRegion - - if lastRegion and regions: - if lastRegion.string: - lastChar = lastRegion.string[-1] - else: - lastChar = "" - if regions[0].string: - nextChar = regions[0].string[0] - else: - nextChar = "" - if self._script.utilities.needsSeparator(lastChar, nextChar): - regions.insert(0, braille.Region(" ")) - - lastRegion = regions[-1] - result.append(regions) - - return result, focusedRegion diff --git a/src/cthulhu/scripts/web/event_router.py b/src/cthulhu/scripts/web/event_router.py deleted file mode 100644 index f126bd0..0000000 --- a/src/cthulhu/scripts/web/event_router.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -"""Defines the ownership contract for routing web accessibility events. - -Handlers run in application, toolkit, and shared-web order. A handler returns -``HANDLED`` to claim the event, ``CONTINUE`` to offer it to the next layer, or -``DEFER_DEFAULT`` to skip directly to the default script. Invalid results and -handler exceptions fail safely by reaching the default handler exactly once. - -This module defines the Phase 2 routing boundary. Existing event families must -be migrated individually; creating a router does not activate parallel routing. -""" - -from __future__ import annotations - -import enum -from collections.abc import Callable - -from cthulhu import debug - - -class RouteResult(enum.Enum): - """A routing layer's explicit decision for one accessibility event.""" - - HANDLED = enum.auto() - CONTINUE = enum.auto() - DEFER_DEFAULT = enum.auto() - - -class RoutingLayer(enum.Enum): - """The layer which ultimately owns an accessibility event.""" - - APPLICATION = enum.auto() - TOOLKIT = enum.auto() - SHARED_WEB = enum.auto() - DEFAULT = enum.auto() - - -RouteHandler = Callable[[object], RouteResult] -DefaultHandler = Callable[[object], object] - - -class WebEventRouter: - """Routes one event to at most one owning presentation layer.""" - - def route_event( - self, - event: object, - *, - application_handler: RouteHandler | None, - toolkit_handler: RouteHandler | None, - web_handler: RouteHandler | None, - default_handler: DefaultHandler, - ) -> RoutingLayer: - """Route ``event`` in application-first order and return its owner.""" - - handlers = ( - (RoutingLayer.APPLICATION, application_handler), - (RoutingLayer.TOOLKIT, toolkit_handler), - (RoutingLayer.SHARED_WEB, web_handler), - ) - for layer, handler in handlers: - if handler is None: - continue - - try: - result = handler(event) - except Exception as error: # pylint: disable=broad-except - message = ( - f"WEB EVENT ROUTER: {layer.name} raised " - f"{type(error).__name__}; deferring to DEFAULT" - ) - debug.printMessage(debug.LEVEL_WARNING, message, True) - return self._route_to_default(event, default_handler) - - if not isinstance(result, RouteResult): - message = ( - f"WEB EVENT ROUTER: {layer.name} returned invalid result " - f"{type(result).__name__}; deferring to DEFAULT" - ) - debug.printMessage(debug.LEVEL_WARNING, message, True) - return self._route_to_default(event, default_handler) - - message = f"WEB EVENT ROUTER: {layer.name} -> {result.name}" - debug.printMessage(debug.LEVEL_INFO, message, True) - if result is RouteResult.HANDLED: - return layer - if result is RouteResult.DEFER_DEFAULT: - return self._route_to_default(event, default_handler) - - return self._route_to_default(event, default_handler) - - @staticmethod - def _route_to_default( - event: object, - default_handler: DefaultHandler, - ) -> RoutingLayer: - debug.printMessage( - debug.LEVEL_INFO, - "WEB EVENT ROUTER: DEFAULT -> HANDLED", - True, - ) - default_handler(event) - return RoutingLayer.DEFAULT diff --git a/src/cthulhu/scripts/web/meson.build b/src/cthulhu/scripts/web/meson.build deleted file mode 100644 index 5823f84..0000000 --- a/src/cthulhu/scripts/web/meson.build +++ /dev/null @@ -1,16 +0,0 @@ -web_python_sources = files([ - '__init__.py', - 'bookmarks.py', - 'braille_generator.py', - 'event_router.py', - 'script.py', - 'script_utilities.py', - 'sound_generator.py', - 'speech_generator.py', - 'tutorial_generator.py', -]) - -python3.install_sources( - web_python_sources, - subdir: 'cthulhu/scripts/web' -) diff --git a/src/cthulhu/scripts/web/script.py b/src/cthulhu/scripts/web/script.py deleted file mode 100644 index 1c03126..0000000 --- a/src/cthulhu/scripts/web/script.py +++ /dev/null @@ -1,3304 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010 Cthulhu Team." \ - "Copyright (c) 2014-2015 Igalia, S.L." -__license__ = "LGPL" - -import time - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -from gi.repository import Gtk - -from cthulhu import caret_navigation -from cthulhu import cmdnames -from cthulhu import keybindings -from cthulhu import debug -from cthulhu import guilabels -from cthulhu import input_event -from cthulhu import input_event_manager -from cthulhu import liveregions -from cthulhu import messages -from cthulhu import cthulhu -from cthulhu import cthulhu_state -from cthulhu import settings -from cthulhu import settings_manager -from cthulhu import speech -from cthulhu import speechserver -from cthulhu import structural_navigation -from cthulhu import sound_theme_manager -from cthulhu.acss import ACSS -from cthulhu.scripts import default -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_event import AXUtilitiesEvent, TextEventReason - -from .bookmarks import Bookmarks -from .braille_generator import BrailleGenerator -from .event_router import WebEventRouter -from .sound_generator import SoundGenerator -from .speech_generator import SpeechGenerator -from .tutorial_generator import TutorialGenerator -from .script_utilities import Utilities - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -def _log(message, reason=None, timestamp=True, stack=False): - debug.print_log(debug.LEVEL_INFO, "WEB", message, reason, timestamp, stack) - -def _log_tokens(tokens, reason=None, timestamp=True, stack=False): - debug.print_log_tokens(debug.LEVEL_INFO, "WEB", tokens, reason, timestamp, stack) - - -class Script(default.Script): - - _eventRouter = WebEventRouter() - - def __init__(self, app): - super().__init__(app) - - self._sayAllContents = [] - self._inSayAll = False - self._sayAllIsInterrupted = False - self._loadingDocumentContent = False - self._madeFindAnnouncement = False - self._lastCommandWasCaretNav = False - self._lastCommandWasStructNav = False - self._lastCommandWasMouseButton = False - self._lastMouseButtonContext = None, -1 - self._lastMouseOverObject = None - self._preMouseOverContext = None, -1 - self._inMouseOverObject = False - self._inFocusMode = False - self._focusModeIsSticky = False - self._browseModeIsSticky = False - self._navSuspended = False - self._structNavWasEnabled = None - - if cthulhu.cthulhuApp.settingsManager.getSetting('caretNavigationEnabled') is None: - cthulhu.cthulhuApp.settingsManager.setSetting('caretNavigationEnabled', True) - if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllOnLoad') is None: - cthulhu.cthulhuApp.settingsManager.setSetting('sayAllOnLoad', True) - if cthulhu.cthulhuApp.settingsManager.getSetting('pageSummaryOnLoad') is None: - cthulhu.cthulhuApp.settingsManager.setSetting('pageSummaryOnLoad', True) - - self._changedLinesOnlyCheckButton = None - self._controlCaretNavigationCheckButton = None - self._minimumFindLengthAdjustment = None - self._minimumFindLengthLabel = None - self._minimumFindLengthSpinButton = None - self._pageSummaryOnLoadCheckButton = None - self._sayAllOnLoadCheckButton = None - self._skipBlankCellsCheckButton = None - self._speakCellCoordinatesCheckButton = None - self._speakCellHeadersCheckButton = None - self._speakCellSpanCheckButton = None - self._speakResultsDuringFindCheckButton = None - self._structuralNavigationCheckButton = None - self._autoFocusModeStructNavCheckButton = None - self._autoFocusModeCaretNavCheckButton = None - self._autoFocusModeNativeNavCheckButton = None - self._layoutModeCheckButton = None - - self.attributeNamesDict["invalid"] = "text-spelling" - self.attributeNamesDict["text-align"] = "justification" - self.attributeNamesDict["text-indent"] = "indent" - - @staticmethod - def _selectionContentKey(content): - obj, start, end, string = content - return hash(obj), start, end, string - - def _clearSyntheticWebSelection(self): - pointOfReference = getattr(self, "pointOfReference", None) - if isinstance(pointOfReference, dict): - pointOfReference.pop("syntheticWebSelection", None) - - def _compareCaretContexts(self, firstObj, firstOffset, secondObj, secondOffset): - if firstObj == secondObj: - if firstOffset < secondOffset: - return -1 - if firstOffset > secondOffset: - return 1 - return 0 - - return self.utilities.pathComparison(AXObject.get_path(firstObj), AXObject.get_path(secondObj)) - - def _getContentsBetweenCaretContexts(self, startObj, startOffset, endObj, endOffset): - contents = [] - currentObj, currentOffset = startObj, startOffset - seen = set() - - while currentObj and (currentObj, currentOffset) != (endObj, endOffset): - key = (hash(currentObj), currentOffset) - if key in seen: - break - seen.add(key) - - contents.extend(self.utilities.getCharacterContentsAtOffset(currentObj, currentOffset)) - currentObj, currentOffset = self.utilities.nextContext(currentObj, currentOffset) - - return contents - - def _presentSyntheticCaretSelection( - self, - event, - document, - obj, - offset, - focusOverride=None, - isCaretSelection: bool | None = None, - ) -> bool: - if isCaretSelection is None: - isCaretSelection = self.utilities.lastInputEventWasCaretNavWithSelection() - - if not isCaretSelection: - return False - - if focusOverride is not None: - focusObj, focusOffset = focusOverride - else: - manager = input_event_manager.get_manager() - if manager.last_event_was_forward_caret_selection(): - focusObj, focusOffset = self.utilities.nextContext(obj, offset) - elif manager.last_event_was_backward_caret_selection(): - focusObj, focusOffset = self.utilities.previousContext(obj, offset) - else: - return False - - if not focusObj: - return False - - selectionState = self.pointOfReference.get("syntheticWebSelection", {}) - if selectionState.get("document") == document: - anchorObj = selectionState.get("anchorObj", obj) - anchorOffset = selectionState.get("anchorOffset", offset) - oldContents = selectionState.get("contents", []) - else: - anchorObj, anchorOffset = obj, offset - oldContents = [] - - if self._compareCaretContexts(anchorObj, anchorOffset, focusObj, focusOffset) <= 0: - startObj, startOffset = anchorObj, anchorOffset - endObj, endOffset = focusObj, focusOffset - else: - startObj, startOffset = focusObj, focusOffset - endObj, endOffset = anchorObj, anchorOffset - - newContents = self._getContentsBetweenCaretContexts(startObj, startOffset, endObj, endOffset) - self.utilities.setCaretContext(focusObj, focusOffset, document) - cthulhu.setLocusOfFocus(event, focusObj, False, True) - self.updateBraille(focusObj) - - if not newContents: - self._clearSyntheticWebSelection() - if oldContents: - self.speakContents(oldContents) - self.speakMessage(messages.TEXT_UNSELECTED) - return True - - self.pointOfReference["syntheticWebSelection"] = { - "document": document, - "anchorObj": anchorObj, - "anchorOffset": anchorOffset, - "focusObj": focusObj, - "focusOffset": focusOffset, - "contents": newContents, - "string": "".join(item[3] for item in newContents), - } - - oldKeys = [self._selectionContentKey(item) for item in oldContents] - newKeys = [self._selectionContentKey(item) for item in newContents] - deltaContents = newContents - message = messages.TEXT_SELECTED - - if oldContents: - if len(newKeys) >= len(oldKeys) and newKeys[:len(oldKeys)] == oldKeys: - deltaContents = newContents[len(oldContents):] - elif len(newKeys) >= len(oldKeys) and newKeys[-len(oldKeys):] == oldKeys: - deltaContents = newContents[:-len(oldContents)] - elif len(oldKeys) >= len(newKeys) and oldKeys[:len(newKeys)] == newKeys: - deltaContents = oldContents[len(newContents):] - message = messages.TEXT_UNSELECTED - elif len(oldKeys) >= len(newKeys) and oldKeys[-len(newKeys):] == newKeys: - deltaContents = oldContents[:-len(newContents)] - message = messages.TEXT_UNSELECTED - - if deltaContents: - self.speakContents(deltaContents) - self.speakMessage(message) - - return True - - def activate(self): - """Called when this script is activated.""" - - _log_tokens(["Activating script for", self.app]) - - focus = cthulhu_state.locusOfFocus - inApp = AXObject.get_application(focus) == self.app if focus else False - inDoc = self._focusInDocumentContent() - suspend = not (inDoc and inApp) - reason = "activation-outside-document" if suspend else "activation-in-document" - - self._setNavigationSuspended(suspend, reason) - - super().activate() - - def deactivate(self): - """Called when this script is deactivated.""" - - self._sayAllContents = [] - self._inSayAll = False - self._sayAllIsInterrupted = False - self._loadingDocumentContent = False - self._madeFindAnnouncement = False - self._lastCommandWasCaretNav = False - self._lastCommandWasStructNav = False - self._lastCommandWasMouseButton = False - self._lastMouseButtonContext = None, -1 - self._lastMouseOverObject = None - self._preMouseOverContext = None, -1 - self._inMouseOverObject = False - self.utilities.clearCachedObjects() - # Ensure navigation commands are re-enabled for the next activation. - self._setNavigationSuspended(False, "script deactivation") - self.removeKeyGrabs() - - def _setNavigationSuspended(self, suspend, reason=""): - """Suspend or resume navigation command handling (caret & structural).""" - - if suspend == self._navSuspended: - return - - self._navSuspended = suspend - - # Structural navigation has an enabled flag we can toggle. - if suspend: - self._structNavWasEnabled = self.structuralNavigation.enabled - self.structuralNavigation.enabled = False - else: - if self._structNavWasEnabled is not None: - self.structuralNavigation.enabled = self._structNavWasEnabled - self._structNavWasEnabled = None - - _log_tokens(["Navigation suspended:", suspend], reason) - - def _focusInDocumentContent(self): - focus = cthulhu_state.locusOfFocus - if not focus or AXObject.is_dead(focus): - return False - - return self.utilities.getDocumentForObject(focus) is not None - - def getAppKeyBindings(self): - """Returns the application-specific keybindings for this script.""" - - keyBindings = keybindings.KeyBindings() - - structNavBindings = self.structuralNavigation.keyBindings - for keyBinding in structNavBindings.keyBindings: - keyBindings.add(keyBinding) - - caretNavBindings = self.caretNavigation.get_bindings() - for keyBinding in caretNavBindings.keyBindings: - keyBindings.add(keyBinding) - - liveRegionBindings = self.liveRegionManager.keyBindings - for keyBinding in liveRegionBindings.keyBindings: - keyBindings.add(keyBinding) - - keyBindings.add( - keybindings.KeyBinding( - "a", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers.get("togglePresentationModeHandler"))) - - keyBindings.add( - keybindings.KeyBinding( - "a", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers.get("enableStickyFocusModeHandler"), - 2)) - - keyBindings.add( - keybindings.KeyBinding( - "a", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers.get("enableStickyBrowseModeHandler"), - 3)) - - keyBindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self.inputEventHandlers.get("toggleLayoutModeHandler"))) - - - layout = cthulhu.cthulhuApp.settingsManager.getSetting('keyboardLayout') - if layout == settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP: - key = "KP_Multiply" - else: - key = "0" - - keyBindings.add( - keybindings.KeyBinding( - key, - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers.get("moveToMouseOverHandler"))) - - return keyBindings - - def setupInputEventHandlers(self): - """Defines InputEventHandlers for this script.""" - - super().setupInputEventHandlers() - self.inputEventHandlers.update( - self.structuralNavigation.inputEventHandlers) - - self.inputEventHandlers.update( - self.caretNavigation.get_handlers()) - - self.inputEventHandlers.update( - self.liveRegionManager.inputEventHandlers) - - self.inputEventHandlers["sayAllHandler"] = \ - input_event.InputEventHandler( - Script.sayAll, - cmdnames.SAY_ALL) - - self.inputEventHandlers["panBrailleLeftHandler"] = \ - input_event.InputEventHandler( - Script.panBrailleLeft, - cmdnames.PAN_BRAILLE_LEFT, - False) # Do not enable learn mode for this action - - self.inputEventHandlers["panBrailleRightHandler"] = \ - input_event.InputEventHandler( - Script.panBrailleRight, - cmdnames.PAN_BRAILLE_RIGHT, - False) # Do not enable learn mode for this action - - self.inputEventHandlers["moveToMouseOverHandler"] = \ - input_event.InputEventHandler( - Script.moveToMouseOver, - cmdnames.MOUSE_OVER_MOVE) - - self.inputEventHandlers["togglePresentationModeHandler"] = \ - input_event.InputEventHandler( - Script.togglePresentationMode, - cmdnames.TOGGLE_PRESENTATION_MODE) - - self.inputEventHandlers["enableStickyFocusModeHandler"] = \ - input_event.InputEventHandler( - Script.enableStickyFocusMode, - cmdnames.SET_FOCUS_MODE_STICKY) - - self.inputEventHandlers["enableStickyBrowseModeHandler"] = \ - input_event.InputEventHandler( - Script.enableStickyBrowseMode, - cmdnames.SET_BROWSE_MODE_STICKY) - - self.inputEventHandlers["toggleLayoutModeHandler"] = \ - input_event.InputEventHandler( - Script.toggleLayoutMode, - cmdnames.TOGGLE_LAYOUT_MODE) - - self.inputEventHandlers["activateClickableHandler"] = \ - input_event.InputEventHandler( - Script.activateClickableElement, - "Activate clickable element") - - - def getBookmarks(self): - """Returns the "bookmarks" class for this script.""" - - try: - return self.bookmarks - except AttributeError: - self.bookmarks = Bookmarks(self) - return self.bookmarks - - def getBrailleGenerator(self): - """Returns the braille generator for this script.""" - - return BrailleGenerator(self) - - def getCaretNavigation(self): - """Returns the caret navigation support for this script.""" - - return caret_navigation.CaretNavigation(self) - - def getEnabledStructuralNavigationTypes(self): - """Returns the structural navigation object types for this script.""" - - return [structural_navigation.StructuralNavigation.BLOCKQUOTE, - structural_navigation.StructuralNavigation.BUTTON, - structural_navigation.StructuralNavigation.CHECK_BOX, - structural_navigation.StructuralNavigation.CHUNK, - structural_navigation.StructuralNavigation.CLICKABLE, - structural_navigation.StructuralNavigation.COMBO_BOX, - structural_navigation.StructuralNavigation.CONTAINER, - structural_navigation.StructuralNavigation.ENTRY, - structural_navigation.StructuralNavigation.FORM_FIELD, - structural_navigation.StructuralNavigation.HEADING, - structural_navigation.StructuralNavigation.IFRAME, - structural_navigation.StructuralNavigation.IMAGE, - structural_navigation.StructuralNavigation.LANDMARK, - structural_navigation.StructuralNavigation.LINK, - structural_navigation.StructuralNavigation.LIST, - structural_navigation.StructuralNavigation.LIST_ITEM, - structural_navigation.StructuralNavigation.LIVE_REGION, - structural_navigation.StructuralNavigation.PARAGRAPH, - structural_navigation.StructuralNavigation.RADIO_BUTTON, - structural_navigation.StructuralNavigation.SEPARATOR, - structural_navigation.StructuralNavigation.TABLE, - structural_navigation.StructuralNavigation.TABLE_CELL, - structural_navigation.StructuralNavigation.UNVISITED_LINK, - structural_navigation.StructuralNavigation.VISITED_LINK] - - def getLiveRegionManager(self): - """Returns the live region support for this script.""" - - return liveregions.LiveRegionManager(self) - - def getSoundGenerator(self): - """Returns the sound generator for this script.""" - - return SoundGenerator(self) - - def getSpeechGenerator(self): - """Returns the speech generator for this script.""" - - return SpeechGenerator(self) - - def getTutorialGenerator(self): - """Returns the tutorial generator for this script.""" - - return TutorialGenerator(self) - - def getUtilities(self): - """Returns the utilities for this script.""" - - return Utilities(self) - - def getAppPreferencesGUI(self): - """Return a GtkGrid containing app-unique configuration items.""" - - grid = Gtk.Grid() - grid.set_border_width(12) - - generalFrame = Gtk.Frame() - grid.attach(generalFrame, 0, 0, 1, 1) - - label = Gtk.Label(label=f"{guilabels.PAGE_NAVIGATION}") - label.set_use_markup(True) - generalFrame.set_label_widget(label) - - generalAlignment = Gtk.Alignment.new(0.5, 0.5, 1, 1) - generalAlignment.set_padding(0, 0, 12, 0) - generalFrame.add(generalAlignment) - generalGrid = Gtk.Grid() - generalAlignment.add(generalGrid) - - label = guilabels.USE_CARET_NAVIGATION - value = cthulhu.cthulhuApp.settingsManager.getSetting('caretNavigationEnabled') - self._controlCaretNavigationCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self._controlCaretNavigationCheckButton.set_active(value) - generalGrid.attach(self._controlCaretNavigationCheckButton, 0, 0, 1, 1) - - label = guilabels.AUTO_FOCUS_MODE_CARET_NAV - value = cthulhu.cthulhuApp.settingsManager.getSetting('caretNavTriggersFocusMode') - self._autoFocusModeCaretNavCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self._autoFocusModeCaretNavCheckButton.set_active(value) - generalGrid.attach(self._autoFocusModeCaretNavCheckButton, 0, 1, 1, 1) - - label = guilabels.USE_STRUCTURAL_NAVIGATION - value = self.structuralNavigation.enabled - self._structuralNavigationCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self._structuralNavigationCheckButton.set_active(value) - generalGrid.attach(self._structuralNavigationCheckButton, 0, 2, 1, 1) - - label = guilabels.AUTO_FOCUS_MODE_STRUCT_NAV - value = cthulhu.cthulhuApp.settingsManager.getSetting('structNavTriggersFocusMode') - self._autoFocusModeStructNavCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self._autoFocusModeStructNavCheckButton.set_active(value) - generalGrid.attach(self._autoFocusModeStructNavCheckButton, 0, 3, 1, 1) - - label = guilabels.AUTO_FOCUS_MODE_NATIVE_NAV - value = cthulhu.cthulhuApp.settingsManager.getSetting('nativeNavTriggersFocusMode') - self._autoFocusModeNativeNavCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self._autoFocusModeNativeNavCheckButton.set_active(value) - generalGrid.attach(self._autoFocusModeNativeNavCheckButton, 0, 4, 1, 1) - - label = guilabels.READ_PAGE_UPON_LOAD - value = cthulhu.cthulhuApp.settingsManager.getSetting('sayAllOnLoad') - self._sayAllOnLoadCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self._sayAllOnLoadCheckButton.set_active(value) - generalGrid.attach(self._sayAllOnLoadCheckButton, 0, 5, 1, 1) - - label = guilabels.PAGE_SUMMARY_UPON_LOAD - value = cthulhu.cthulhuApp.settingsManager.getSetting('pageSummaryOnLoad') - self._pageSummaryOnLoadCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self._pageSummaryOnLoadCheckButton.set_active(value) - generalGrid.attach(self._pageSummaryOnLoadCheckButton, 0, 6, 1, 1) - - label = guilabels.CONTENT_LAYOUT_MODE - value = cthulhu.cthulhuApp.settingsManager.getSetting('layoutMode') - self._layoutModeCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self._layoutModeCheckButton.set_active(value) - generalGrid.attach(self._layoutModeCheckButton, 0, 7, 1, 1) - - tableFrame = Gtk.Frame() - grid.attach(tableFrame, 0, 1, 1, 1) - - label = Gtk.Label(label=f"{guilabels.TABLE_NAVIGATION}") - label.set_use_markup(True) - tableFrame.set_label_widget(label) - - tableAlignment = Gtk.Alignment.new(0.5, 0.5, 1, 1) - tableAlignment.set_padding(0, 0, 12, 0) - tableFrame.add(tableAlignment) - tableGrid = Gtk.Grid() - tableAlignment.add(tableGrid) - - label = guilabels.TABLE_SPEAK_CELL_COORDINATES - value = cthulhu.cthulhuApp.settingsManager.getSetting('speakCellCoordinates') - self._speakCellCoordinatesCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self._speakCellCoordinatesCheckButton.set_active(value) - tableGrid.attach(self._speakCellCoordinatesCheckButton, 0, 0, 1, 1) - - label = guilabels.TABLE_SPEAK_CELL_SPANS - value = cthulhu.cthulhuApp.settingsManager.getSetting('speakCellSpan') - self._speakCellSpanCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self._speakCellSpanCheckButton.set_active(value) - tableGrid.attach(self._speakCellSpanCheckButton, 0, 1, 1, 1) - - label = guilabels.TABLE_ANNOUNCE_CELL_HEADER - value = cthulhu.cthulhuApp.settingsManager.getSetting('speakCellHeaders') - self._speakCellHeadersCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self._speakCellHeadersCheckButton.set_active(value) - tableGrid.attach(self._speakCellHeadersCheckButton, 0, 2, 1, 1) - - label = guilabels.TABLE_SKIP_BLANK_CELLS - value = cthulhu.cthulhuApp.settingsManager.getSetting('skipBlankCells') - self._skipBlankCellsCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self._skipBlankCellsCheckButton.set_active(value) - tableGrid.attach(self._skipBlankCellsCheckButton, 0, 3, 1, 1) - - findFrame = Gtk.Frame() - grid.attach(findFrame, 0, 2, 1, 1) - - label = Gtk.Label(label=f"{guilabels.FIND_OPTIONS}") - label.set_use_markup(True) - findFrame.set_label_widget(label) - - findAlignment = Gtk.Alignment.new(0.5, 0.5, 1, 1) - findAlignment.set_padding(0, 0, 12, 0) - findFrame.add(findAlignment) - findGrid = Gtk.Grid() - findAlignment.add(findGrid) - - verbosity = cthulhu.cthulhuApp.settingsManager.getSetting('findResultsVerbosity') - - label = guilabels.FIND_SPEAK_RESULTS - value = verbosity != settings.FIND_SPEAK_NONE - self._speakResultsDuringFindCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self._speakResultsDuringFindCheckButton.set_active(value) - findGrid.attach(self._speakResultsDuringFindCheckButton, 0, 0, 1, 1) - - label = guilabels.FIND_ONLY_SPEAK_CHANGED_LINES - value = verbosity == settings.FIND_SPEAK_IF_LINE_CHANGED - self._changedLinesOnlyCheckButton = \ - Gtk.CheckButton.new_with_mnemonic(label) - self._changedLinesOnlyCheckButton.set_active(value) - findGrid.attach(self._changedLinesOnlyCheckButton, 0, 1, 1, 1) - - hgrid = Gtk.Grid() - findGrid.attach(hgrid, 0, 2, 1, 1) - - self._minimumFindLengthLabel = \ - Gtk.Label(label=guilabels.FIND_MINIMUM_MATCH_LENGTH) - self._minimumFindLengthLabel.set_alignment(0, 0.5) - hgrid.attach(self._minimumFindLengthLabel, 0, 0, 1, 1) - - self._minimumFindLengthAdjustment = \ - Gtk.Adjustment(cthulhu.cthulhuApp.settingsManager.getSetting( - 'findResultsMinimumLength'), 0, 20, 1) - self._minimumFindLengthSpinButton = Gtk.SpinButton() - self._minimumFindLengthSpinButton.set_adjustment( - self._minimumFindLengthAdjustment) - hgrid.attach(self._minimumFindLengthSpinButton, 1, 0, 1, 1) - self._minimumFindLengthLabel.set_mnemonic_widget( - self._minimumFindLengthSpinButton) - - grid.show_all() - return grid - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - if not self._speakResultsDuringFindCheckButton.get_active(): - verbosity = settings.FIND_SPEAK_NONE - elif self._changedLinesOnlyCheckButton.get_active(): - verbosity = settings.FIND_SPEAK_IF_LINE_CHANGED - else: - verbosity = settings.FIND_SPEAK_ALL - - return { - 'findResultsVerbosity': verbosity, - 'findResultsMinimumLength': self._minimumFindLengthSpinButton.get_value(), - 'sayAllOnLoad': self._sayAllOnLoadCheckButton.get_active(), - 'pageSummaryOnLoad': self._pageSummaryOnLoadCheckButton.get_active(), - 'structuralNavigationEnabled': self._structuralNavigationCheckButton.get_active(), - 'structNavTriggersFocusMode': self._autoFocusModeStructNavCheckButton.get_active(), - 'caretNavigationEnabled': self._controlCaretNavigationCheckButton.get_active(), - 'caretNavTriggersFocusMode': self._autoFocusModeCaretNavCheckButton.get_active(), - 'nativeNavTriggersFocusMode': self._autoFocusModeNativeNavCheckButton.get_active(), - 'speakCellCoordinates': self._speakCellCoordinatesCheckButton.get_active(), - 'layoutMode': self._layoutModeCheckButton.get_active(), - 'speakCellSpan': self._speakCellSpanCheckButton.get_active(), - 'speakCellHeaders': self._speakCellHeadersCheckButton.get_active(), - 'skipBlankCells': self._skipBlankCellsCheckButton.get_active() - } - - def skipObjectEvent(self, event): - """Returns True if this object event should be skipped.""" - - if event.type.startswith('object:state-changed:focused') and event.detail1: - if AXUtilities.is_link(event.source): - return False - elif event.type.startswith('object:children-changed'): - if AXUtilities.is_dialog(event.any_data): - return False - - return super().skipObjectEvent(event) - - def presentationInterrupt(self): - super().presentationInterrupt() - msg = "WEB: Flushing live region messages" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.liveRegionManager.flushMessages() - - def updateKeyboardEventState(self, keyboardEvent, handler): - """Update internal state for a keyboard event without deciding consumption.""" - - # We need to do this here. Cthulhu caret and structural navigation - # often result in the user being repositioned without our getting - # a corresponding AT-SPI event. Without an AT-SPI event, script.py - # won't know to dump the generator cache. See bgo#618827. - self.generatorCache = {} - self._lastMouseButtonContext = None, -1 - super().updateKeyboardEventState(keyboardEvent, handler) - - def shouldConsumeKeyboardEvent(self, keyboardEvent, handler): - """Returns True if the script will consume this keyboard event.""" - - if handler and self.caretNavigation.handles_navigation(handler): - consumes = self.useCaretNavigationModel(keyboardEvent) - self._lastCommandWasCaretNav = consumes - self._lastCommandWasStructNav = False - self._lastCommandWasMouseButton = False - return consumes - - if handler and handler.function in self.structuralNavigation.functions: - consumes = self.useStructuralNavigationModel() - self._lastCommandWasCaretNav = False - self._lastCommandWasStructNav = consumes - self._lastCommandWasMouseButton = False - return consumes - - if handler and handler.function in self.liveRegionManager.functions: - # This is temporary. - consumes = self.useStructuralNavigationModel() - self._lastCommandWasCaretNav = False - self._lastCommandWasStructNav = consumes - self._lastCommandWasMouseButton = False - return consumes - - if not keyboardEvent.is_modifier_key(): - self._lastCommandWasCaretNav = False - self._lastCommandWasStructNav = False - self._lastCommandWasMouseButton = False - - # Check parent first - consumes = super().shouldConsumeKeyboardEvent(keyboardEvent, handler) - - # If parent doesn't consume Return key, try our clickable fallback - if not consumes and keyboardEvent.event_string == "Return": - return self._tryClickableActivation(keyboardEvent) - - return consumes - - def getEnabledKeyBindings(self): - all = super().getEnabledKeyBindings() - ret = [] - for b in all: - if b.handler and self.caretNavigation.handles_navigation(b.handler): - if self.useCaretNavigationModel(None, False): - ret.append(b) - elif b.handler and b.handler.function in self.structuralNavigation.functions: - if self.useStructuralNavigationModel(False): - ret.append(b) - elif b.handler and b.handler.function in self.liveRegionManager.functions: - # This is temporary. - if self.useStructuralNavigationModel(False): - ret.append(b) - else: - ret.append(b) - return ret - - def consumesBrailleEvent(self, brailleEvent): - """Returns True if the script will consume this braille event.""" - - self._lastCommandWasCaretNav = False - self._lastCommandWasStructNav = False - self._lastCommandWasMouseButton = False - return super().consumesBrailleEvent(brailleEvent) - - # TODO - JD: This needs to be moved out of the scripts. - def textLines(self, obj, offset=None): - """Creates a generator that can be used to iterate document content.""" - - if not self.utilities.inDocumentContent(): - tokens = ["WEB: textLines called for non-document content", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - super().textLines(obj, offset) - return - - self._sayAllIsInterrupted = False - - sayAllStyle = cthulhu.cthulhuApp.settingsManager.getSetting('sayAllStyle') - sayAllBySentence = sayAllStyle == settings.SAYALL_STYLE_SENTENCE - if offset is None: - obj, characterOffset = self.utilities.getCaretContext() - else: - characterOffset = offset - priorObj, priorOffset = self.utilities.getPriorContext() - - # TODO - JD: This is sad, but it's better than the old, broken - # clumpUtterances(). We really need to fix the speechservers' - # SayAll support. In the meantime, the generators should be - # providing one ACSS per string. - def _parseUtterances(utterances): - elements, voices = [], [] - for u in utterances: - if isinstance(u, list): - e, v = _parseUtterances(u) - elements.extend(e) - voices.extend(v) - elif isinstance(u, str): - elements.append(u) - elif isinstance(u, ACSS): - voices.append(u) - return elements, voices - - self._inSayAll = True - done = False - while not done: - if sayAllBySentence: - contents = self.utilities.getSentenceContentsAtOffset(obj, characterOffset) - else: - contents = self.utilities.getLineContentsAtOffset(obj, characterOffset) - self._sayAllContents = contents - for i, content in enumerate(contents): - obj, startOffset, endOffset, text = content - tokens = ["WEB SAY ALL CONTENT:", - i, ". ", obj, "'", text, "' (", startOffset, "-", endOffset, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if self.utilities.isInferredLabelForContents(content, contents): - continue - - if startOffset == endOffset: - continue - - if self.utilities.isLabellingInteractiveElement(obj): - continue - - if self.utilities.isLinkAncestorOfImageInContents(obj, contents): - continue - - utterances = self.speechGenerator.generateContents( - [content], eliminatePauses=True, priorObj=priorObj) - priorObj = obj - - elements, voices = _parseUtterances(utterances) - if len(elements) != len(voices): - continue - - for i, element in enumerate(elements): - context = speechserver.SayAllContext( - obj, element, startOffset, endOffset) - tokens = ["WEB", context] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._sayAllContexts.append(context) - self.eventSynthesizer.scroll_into_view(obj, startOffset, endOffset) - yield [context, voices[i]] - - lastObj, lastOffset = contents[-1][0], contents[-1][2] - obj, characterOffset = self.utilities.findNextCaretInOrder(lastObj, lastOffset - 1) - if obj == lastObj and characterOffset <= lastOffset: - obj, characterOffset = self.utilities.findNextCaretInOrder(lastObj, lastOffset) - if obj == lastObj and characterOffset <= lastOffset: - tokens = ["WEB: Cycle within object detected in textLines. Last:", - lastObj, ", ", lastOffset, "Next:", obj, ", ", characterOffset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - break - - done = obj is None - - self._inSayAll = False - self._sayAllContents = [] - self._sayAllContexts = [] - - msg = "WEB: textLines complete. Verifying SayAll status" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.inSayAll() - - def presentFindResults(self, obj, offset): - """Updates the context and presents the find results if appropriate.""" - - text = self.utilities.queryNonEmptyText(obj) - selections = self.utilities.allTextSelections(obj) if text else [] - if not selections: - return - - document = self.utilities.getDocumentForObject(obj) - if not document: - return - - context = self.utilities.getCaretContext(documentFrame=document) - start, end = selections[0] - offset = max(offset, start) - self.utilities.setCaretContext(obj, offset, documentFrame=document) - if end - start < cthulhu.cthulhuApp.settingsManager.getSetting('findResultsMinimumLength'): - return - - verbosity = cthulhu.cthulhuApp.settingsManager.getSetting('findResultsVerbosity') - if verbosity == settings.FIND_SPEAK_NONE: - return - - if self._madeFindAnnouncement \ - and verbosity == settings.FIND_SPEAK_IF_LINE_CHANGED \ - and self.utilities.contextsAreOnSameLine(context, (obj, offset)): - return - - contents = self.utilities.getLineContentsAtOffset(obj, offset) - self.speakContents(contents) - self.updateBraille(obj) - - resultsCount = self.utilities.getFindResultsCount() - if resultsCount: - self.presentMessage(resultsCount) - - self._madeFindAnnouncement = True - - def sayAll(self, inputEvent, obj=None, offset=None): - """Speaks the contents of the document beginning with the present - location. Overridden in this script because the sayAll could have - been started on an object without text (such as an image). - """ - - if not self.utilities.inDocumentContent(): - tokens = ["WEB: SayAll called for non-document content", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return super().sayAll(inputEvent, obj, offset) - - obj = obj or cthulhu_state.locusOfFocus - tokens = ["WEB: SayAll called for document content", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - speech.sayAll(self.textLines(obj, offset), self.__sayAllProgressCallback) - return True - - def _rewindSayAll(self, context, minCharCount=10): - if not self.utilities.inDocumentContent(): - return super()._rewindSayAll(context, minCharCount) - - if not cthulhu.cthulhuApp.settingsManager.getSetting('rewindAndFastForwardInSayAll'): - return False - - try: - obj, start, end, string = self._sayAllContents[0] - except IndexError: - return False - - cthulhu.setLocusOfFocus(None, obj, notifyScript=False) - self.utilities.setCaretContext(obj, start) - - prevObj, prevOffset = self.utilities.findPreviousCaretInOrder(obj, start) - self.sayAll(None, prevObj, prevOffset) - return True - - def _fastForwardSayAll(self, context): - if not self.utilities.inDocumentContent(): - return super()._fastForwardSayAll(context) - - if not cthulhu.cthulhuApp.settingsManager.getSetting('rewindAndFastForwardInSayAll'): - return False - - try: - obj, start, end, string = self._sayAllContents[-1] - except IndexError: - return False - - cthulhu.setLocusOfFocus(None, obj, notifyScript=False) - self.utilities.setCaretContext(obj, end) - - nextObj, nextOffset = self.utilities.findNextCaretInOrder(obj, end) - self.sayAll(None, nextObj, nextOffset) - return True - - def __sayAllProgressCallback(self, context, progressType): - if not self.utilities.inDocumentContent(): - super().__sayAllProgressCallback(context, progressType) - return - - if progressType == speechserver.SayAllContext.INTERRUPTED: - if isinstance(cthulhu_state.lastInputEvent, input_event.KeyboardEvent): - self._sayAllIsInterrupted = True - lastKey = cthulhu_state.lastInputEvent.event_string - if lastKey == "Down" and self._fastForwardSayAll(context): - return - elif lastKey == "Up" and self._rewindSayAll(context): - return - elif not self._lastCommandWasStructNav: - cthulhu.emitRegionChanged(context.obj, context.currentOffset) - self.utilities.setCaretPosition(context.obj, context.currentOffset) - self.updateBraille(context.obj) - - self._inSayAll = False - self._sayAllContents = [] - self._sayAllContexts = [] - return - - cthulhu.setLocusOfFocus(None, context.obj, notifyScript=False) - cthulhu.emitRegionChanged( - context.obj, context.currentOffset, context.currentEndOffset, cthulhu.SAY_ALL) - self.utilities.setCaretContext(context.obj, context.currentOffset) - - def inFocusMode(self): - """ Returns True if we're in focus mode.""" - - return self._inFocusMode - - def focusModeIsSticky(self): - """Returns True if we're in 'sticky' focus mode.""" - - return self._focusModeIsSticky - - def browseModeIsSticky(self): - """Returns True if we're in 'sticky' browse mode.""" - - return self._browseModeIsSticky - - def useFocusMode(self, obj, prevObj=None): - """Returns True if we should use focus mode in obj.""" - - if self._focusModeIsSticky: - _log("Using focus mode", "focus-mode-sticky") - return True - - if self._browseModeIsSticky: - _log("Not using focus mode", "browse-mode-sticky") - return False - - if self.inSayAll(): - _log("Not using focus mode", "say-all") - return False - - if not cthulhu.cthulhuApp.settingsManager.getSetting('structNavTriggersFocusMode') \ - and self._lastCommandWasStructNav: - _log("Not using focus mode", "struct-nav-settings") - return False - - if prevObj and AXObject.is_dead(prevObj): - prevObj = None - - if not cthulhu.cthulhuApp.settingsManager.getSetting('caretNavTriggersFocusMode') \ - and self._lastCommandWasCaretNav \ - and not self.utilities.isNavigableToolTipDescendant(prevObj): - _log("Not using focus mode", "caret-nav-settings") - return False - - if not cthulhu.cthulhuApp.settingsManager.getSetting('nativeNavTriggersFocusMode') \ - and not (self._lastCommandWasStructNav or self._lastCommandWasCaretNav): - _log("Not changing focus/browse mode", "native-nav-settings") - return self._inFocusMode - - if self.utilities.isFocusModeWidget(obj): - _log_tokens(["Using focus mode for", obj], "focus-mode-widget") - return True - - doNotToggle = AXUtilities.is_link(obj) or AXUtilities.is_radio_button(obj) - if self._inFocusMode and doNotToggle and self.utilities.lastInputEventWasUnmodifiedArrow(): - _log_tokens(["Staying in focus mode due to arrowing in role of", obj], "arrowing") - return True - - if self._inFocusMode and self.utilities.isWebAppDescendant(obj): - if self.utilities.forceBrowseModeForWebAppDescendant(obj): - _log_tokens(["Forcing browse mode for web app descendant", obj], "web-app-forced-browse") - return False - - _log("Staying in focus mode because we're inside a web application", "web-app-context") - return True - - _log_tokens(["Not using focus mode for", obj], "no-cause") - return False - - def speakContents(self, contents, **args): - """Speaks the specified contents.""" - - utterances = self.speechGenerator.generateContents(contents, **args) - speech.speak(utterances, interrupt=args.get("interrupt", False)) - - def sayCharacter(self, obj): - """Speaks the character at the current caret position.""" - - if not self._lastCommandWasCaretNav \ - and not self.utilities.isContentEditableWithEmbeddedObjects(obj): - super().sayCharacter(obj) - return - - document = self.utilities.getTopLevelDocumentForObject(obj) - obj, offset = self.utilities.getCaretContext(documentFrame=document) - if not obj: - return - - contents = None - if self.utilities.treatAsEndOfLine(obj, offset) and AXObject.supports_text(obj): - char = AXText.get_substring(obj, offset, offset + 1) - if char == self.EMBEDDED_OBJECT_CHARACTER: - char = "" - contents = [[obj, offset, offset + 1, char]] - else: - contents = self.utilities.getCharacterContentsAtOffset(obj, offset) - - if not contents: - return - - obj, start, end, string = contents[0] - if start > 0: - string = string or "\n" - - if string: - self.speakMisspelledIndicator(obj, start) - self.speakCharacter(string) - else: - self.speakContents(contents) - - self.pointOfReference["lastTextUnitSpoken"] = "char" - - def sayWord(self, obj): - """Speaks the word at the current caret position.""" - - isEditable = self.utilities.isContentEditableWithEmbeddedObjects(obj) - if not self._lastCommandWasCaretNav and not isEditable: - super().sayWord(obj) - return - - document = self.utilities.getTopLevelDocumentForObject(obj) - obj, offset = self.utilities.getCaretContext(documentFrame=document) - if input_event_manager.get_manager().last_event_was_right(): - offset -= 1 - - wordContents = self.utilities.getWordContentsAtOffset(obj, offset, useCache=True) - textObj, startOffset, endOffset, word = wordContents[0] - self.speakMisspelledIndicator(textObj, startOffset) - self.speakContents(wordContents) - self.pointOfReference["lastTextUnitSpoken"] = "word" - - def sayLine(self, obj): - """Speaks the line at the current caret position.""" - - isNativeMultilineEditable = ( - self.utilities.inDocumentContent(obj) - and AXUtilities.is_editable(obj) - and AXUtilities.is_multi_line(obj) - ) - isEditable = self.utilities.isContentEditableWithEmbeddedObjects(obj) \ - or isNativeMultilineEditable - if not (self._lastCommandWasCaretNav or self._lastCommandWasStructNav) and not isEditable: - super().sayLine(obj) - return - - document = self.utilities.getTopLevelDocumentForObject(obj) - priorObj = None - if self._lastCommandWasCaretNav or isEditable: - priorObj, priorOffset = self.utilities.getPriorContext(documentFrame=document) - - obj, offset = self.utilities.getCaretContext(documentFrame=document) - contents = self.utilities.getLineContentsAtOffset(obj, offset, useCache=True) - if isNativeMultilineEditable: - self.speakContents(contents, priorObj=priorObj, alreadyFocused=True) - else: - self.speakContents(contents, priorObj=priorObj) - self.pointOfReference["lastTextUnitSpoken"] = "line" - - def presentObject(self, obj, **args): - if not self.utilities.inDocumentContent(obj) or AXUtilities.is_document(obj): - super().presentObject(obj, **args) - return - - if AXUtilities.is_status_bar(obj): - super().presentObject(obj, **args) - return - - priorObj = args.get("priorObj") - if self._lastCommandWasCaretNav or args.get("includeContext") \ - or self.utilities.getTable(obj): - priorObj, priorOffset = self.utilities.getPriorContext() - args["priorObj"] = priorObj - - if AXUtilities.is_entry(obj): - super().presentObject(obj, **args) - return - - has_interrupt_request = "interrupt" in args - interrupt = self.should_interrupt_for_object_presentation( - args.get("interrupt", False), - args.pop("interrupt_already_handled", False), - ) - if has_interrupt_request: - args["interrupt"] = interrupt - tokens = ["WEB: Presenting object", obj, ". Interrupt:", interrupt] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # We shouldn't use cache in this method, because if the last thing we presented - # included this object and offset (e.g. a Say All or Mouse Review), we're in - # danger of presented irrelevant context. - useCache = False - offset = args.get("offset", 0) - contents = self.utilities.get_objectContentsAtOffset(obj, offset, useCache) - self.displayContents(contents) - self.speakContents(contents, **args) - - def updateBrailleForNewCaretPosition(self, obj): - """Try to reposition the cursor without having to do a full update.""" - - text = self.utilities.queryNonEmptyText(obj) - if text and self.EMBEDDED_OBJECT_CHARACTER in AXText.get_all_text(obj): - self.updateBraille(obj) - return - - super().updateBrailleForNewCaretPosition(obj) - - def updateBraille(self, obj, **args): - """Updates the braille display to show the given object.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - debug.printMessage(debug.LEVEL_INFO, "BRAILLE: disabled", True) - return - - if self._inFocusMode: - tokens = ["WEB: updating braille in focus mode", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - super().updateBraille(obj, **args) - return - - document = args.get("documentFrame", self.utilities.getTopLevelDocumentForObject(obj)) - if not document: - tokens = ["WEB: updating braille for non-document object", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - super().updateBraille(obj, **args) - return - - isContentEditable = self.utilities.isContentEditableWithEmbeddedObjects(obj) - - if not self._lastCommandWasCaretNav \ - and not self._lastCommandWasStructNav \ - and not isContentEditable \ - and not self.utilities.isPlainText() \ - and not self.utilities.lastInputEventWasCaretNavWithSelection(): - tokens = ["WEB: updating braille for unhandled navigation type", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - super().updateBraille(obj, **args) - return - - obj, offset = self.utilities.getCaretContext( - documentFrame=document, getZombieReplicant=True) - if offset > 0 and isContentEditable: - text = self.utilities.queryNonEmptyText(obj) - if text: - offset = min(offset, AXText.get_character_count(obj)) - - contents = self.utilities.getLineContentsAtOffset(obj, offset) - self.displayContents(contents, documentFrame=document) - - def displayContents(self, contents, **args): - """Displays contents in braille.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableBraille') \ - and not cthulhu.cthulhuApp.settingsManager.getSetting('enableBrailleMonitor'): - debug.printMessage(debug.LEVEL_INFO, "BRAILLE: disabled", True) - return - - line = self.getNewBrailleLine(clearBraille=True, addLine=True) - document = args.get("documentFrame") - contents = self.brailleGenerator.generateContents(contents, documentFrame=document) - if not contents: - return - - regions, focusedRegion = contents - for region in regions: - self.addBrailleRegionsToLine(region, line) - - if line.regions: - line.regions[-1].string = line.regions[-1].string.rstrip(" ") - - self.setBrailleFocus(focusedRegion, getLinkMask=False) - self.refreshBraille(panToCursor=True, getLinkMask=False) - - def panBrailleLeft(self, inputEvent=None, panAmount=0): - """Pans braille to the left.""" - - if self.flatReviewPresenter.is_active() \ - or not self.utilities.inDocumentContent() \ - or not self.isBrailleBeginningShowing(): - super().panBrailleLeft(inputEvent, panAmount) - return - - contents = self.utilities.getPreviousLineContents() - if not contents: - return - - obj, start, end, string = contents[0] - self.utilities.setCaretPosition(obj, start) - self.updateBraille(obj) - - # Hack: When panning to the left in a document, we want to start at - # the right/bottom of each new object. For now, we'll pan there. - # When time permits, we'll give our braille code some smarts. - while self.panBrailleInDirection(panToLeft=False): - pass - - self.refreshBraille(False) - return True - - def panBrailleRight(self, inputEvent=None, panAmount=0): - """Pans braille to the right.""" - - if self.flatReviewPresenter.is_active() \ - or not self.utilities.inDocumentContent() \ - or not self.isBrailleEndShowing(): - super().panBrailleRight(inputEvent, panAmount) - return - - contents = self.utilities.getNextLineContents() - if not contents: - return - - obj, start, end, string = contents[0] - self.utilities.setCaretPosition(obj, start) - self.updateBraille(obj) - - # Hack: When panning to the right in a document, we want to start at - # the left/top of each new object. For now, we'll pan there. When time - # permits, we'll give our braille code some smarts. - while self.panBrailleInDirection(panToLeft=True): - pass - - self.refreshBraille(False) - return True - - def useCaretNavigationModel(self, keyboardEvent, debugOutput=True): - """Returns True if caret navigation should be used.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('caretNavigationEnabled'): - if debugOutput: - _log("Not using caret navigation", "disabled") - return False - - if self._inFocusMode: - if debugOutput: - _log("Not using caret navigation", "focus-mode") - return False - - inDoc = self._focusInDocumentContent() - - if self._navSuspended: - if inDoc: - self._setNavigationSuspended(False, "focus confirmed in document content") - else: - if debugOutput: - _log("Not using caret navigation", "suspended") - return False - - if not inDoc: - if debugOutput: - _log_tokens( - ["Not using caret navigation because locusOfFocus", cthulhu_state.locusOfFocus, - "is not in document content."], - "focus-not-document" - ) - return False - - if keyboardEvent and keyboardEvent.modifiers & keybindings.SHIFT_MODIFIER_MASK: - if debugOutput: - _log("Not using caret navigation", "shift-modifier") - return False - - if debugOutput: - _log_tokens( - ["Using caret navigation with locusOfFocus", cthulhu_state.locusOfFocus, - "in document content."], - "enabled" - ) - return True - - def useStructuralNavigationModel(self, debugOutput=True): - """Returns True if structural navigation should be used.""" - - if not self.structuralNavigation.enabled: - if debugOutput: - _log("Not using structural navigation", "disabled") - return False - - if self._inFocusMode: - if debugOutput: - _log("Not using structural navigation", "focus-mode") - return False - - inDoc = self._focusInDocumentContent() - - if self._navSuspended: - if inDoc: - self._setNavigationSuspended(False, "focus confirmed in document content") - else: - if debugOutput: - _log("Not using structural navigation", "suspended") - return False - - if not inDoc: - if debugOutput: - _log_tokens( - ["Not using structural navigation because locusOfFocus", - cthulhu_state.locusOfFocus, "is not in document content."], - "focus-not-document" - ) - return False - - if debugOutput: - _log_tokens( - ["Using structural navigation with locusOfFocus", cthulhu_state.locusOfFocus, - "in document content."], - "enabled" - ) - return True - - def getTextLineAtCaret(self, obj, offset=None, startOffset=None, endOffset=None): - """To-be-removed. Returns the string, caretOffset, startOffset.""" - - if self._inFocusMode or not self.utilities.inDocumentContent(obj) \ - or self.utilities.isFocusModeWidget(obj): - return super().getTextLineAtCaret(obj, offset, startOffset, endOffset) - - text = self.utilities.queryNonEmptyText(obj) - if offset is None: - offset = max(0, AXText.get_caret_offset(obj)) - - if text and startOffset is not None and endOffset is not None: - return AXText.get_substring(obj, startOffset, endOffset), offset, startOffset - - contextObj, contextOffset = self.utilities.getCaretContext(documentFrame=None) - if contextObj == obj: - caretOffset = contextOffset - else: - caretOffset = offset - - contents = self.utilities.getLineContentsAtOffset(obj, offset) - contents = list(filter(lambda x: x[0] == obj, contents)) - if len(contents) == 1: - index = 0 - else: - index = self.utilities.findObjectInContents(obj, offset, contents) - - if index > -1: - candidate, startOffset, endOffset, string = contents[index] - if self.EMBEDDED_OBJECT_CHARACTER not in string: - return string, caretOffset, startOffset - - return "", 0, 0 - - def moveToMouseOver(self, inputEvent): - """Moves the context to/from the mouseover which has just appeared.""" - - if not self._lastMouseOverObject: - self.presentMessage(messages.MOUSE_OVER_NOT_FOUND) - return - - if self._inMouseOverObject: - x, y = self.oldMouseCoordinates - self.eventSynthesizer.route_to_point(x, y) - self.restorePreMouseOverContext() - return - - obj = self._lastMouseOverObject - obj, offset = self.utilities.findFirstCaretContext(obj, 0) - if not obj: - return - - if AXUtilities.is_focusable(obj) and AXObject.supports_component(obj): - Atspi.Component.grab_focus(obj) - - contents = self.utilities.get_objectContentsAtOffset(obj, offset) - self.utilities.setCaretPosition(obj, offset) - self.speakContents(contents) - self.updateBraille(obj) - self._inMouseOverObject = True - - def restorePreMouseOverContext(self): - """Cleans things up after a mouse-over object has been hidden.""" - - obj, offset = self._preMouseOverContext - self.utilities.setCaretPosition(obj, offset) - self.speakContents(self.utilities.get_objectContentsAtOffset(obj, offset)) - self.updateBraille(obj) - self._inMouseOverObject = False - self._lastMouseOverObject = None - - def enableStickyBrowseMode(self, inputEvent, forceMessage=False): - if not self._browseModeIsSticky or forceMessage: - self.presentMessage(messages.MODE_BROWSE_IS_STICKY) - - self._inFocusMode = False - self._focusModeIsSticky = False - self._browseModeIsSticky = True - self.refreshKeyGrabs() - - def enableStickyFocusMode(self, inputEvent, forceMessage=False): - if not self._focusModeIsSticky or forceMessage: - self.presentMessage(messages.MODE_FOCUS_IS_STICKY) - - self._inFocusMode = True - self._focusModeIsSticky = True - self._browseModeIsSticky = False - self.refreshKeyGrabs() - - def toggleLayoutMode(self, inputEvent): - layoutMode = not cthulhu.cthulhuApp.settingsManager.getSetting('layoutMode') - if layoutMode: - self.presentMessage(messages.MODE_LAYOUT) - else: - self.presentMessage(messages.MODE_OBJECT) - cthulhu.cthulhuApp.settingsManager.setSetting('layoutMode', layoutMode) - - def togglePresentationMode(self, inputEvent, documentFrame=None): - [obj, characterOffset] = self.utilities.getCaretContext(documentFrame) - if self._inFocusMode: - parent = AXObject.get_parent(obj) - if AXUtilities.is_list_box(parent): - self.utilities.setCaretContext(parent, -1) - elif AXUtilities.is_menu(parent): - self.utilities.setCaretContext(AXObject.get_parent(parent), -1) - if not self._loadingDocumentContent: - if inputEvent is not None: - interrupt = self.should_interrupt_for_mode_announcement( - True, - already_handled=True, - ) - self.presentMessage(messages.MODE_BROWSE, interrupt=interrupt) - else: - self.presentMessage(messages.MODE_BROWSE) - if not self._shouldSuppressBrowseModeSound(obj, inputEvent): - sound_theme_manager.getManager().playBrowseModeSound() - else: - if not self.utilities.grabFocusWhenSettingCaret(obj) \ - and (self._lastCommandWasCaretNav \ - or self._lastCommandWasStructNav \ - or inputEvent): - self.utilities.grabFocus(obj) - - if inputEvent is not None: - interrupt = self.should_interrupt_for_mode_announcement( - True, - already_handled=True, - ) - self.presentMessage(messages.MODE_FOCUS, interrupt=interrupt) - else: - self.presentMessage(messages.MODE_FOCUS) - sound_theme_manager.getManager().playFocusModeSound() - self._inFocusMode = not self._inFocusMode - self._focusModeIsSticky = False - self._browseModeIsSticky = False - self.refreshKeyGrabs() - - def _shouldSuppressBrowseModeSound(self, obj, inputEvent): - if inputEvent is not None: - return False - - if cthulhu.cthulhuApp.settingsManager.getSetting('roleSoundPresentation') \ - == settings.ROLE_SOUND_PRESENTATION_SPEECH_ONLY: - return False - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableSound'): - return False - - icon = self._getControlSoundIcon(obj) - return icon is not None and icon.isValid() - - def _getControlSoundIcon(self, obj): - if not obj: - return None - - role = AXObject.get_role(obj) - if self.utilities.isSwitch(obj): - role = Atspi.Role.SWITCH - manager = sound_theme_manager.getManager() - icon = manager.getRoleSoundIcon(role) - if icon: - return icon - - stateKey = None - if AXUtilities.is_checkable(obj) or AXUtilities.is_check_menu_item(obj): - if AXUtilities.is_indeterminate(obj): - stateKey = "mixed" - elif AXUtilities.is_checked(obj): - stateKey = "checked" - else: - stateKey = "unchecked" - elif AXUtilities.is_radio_button(obj): - stateKey = "checked" if AXUtilities.is_checked(obj) else "unchecked" - elif AXUtilities.is_toggle_button(obj) or AXUtilities.is_switch(obj): - stateKey = "checked" if (AXUtilities.is_checked(obj) or AXUtilities.is_pressed(obj)) \ - else "unchecked" - - if stateKey: - return manager.getRoleStateSoundIcon(role, stateKey) - - return None - - def _getClickableActivationTarget(self): - obj = cthulhu_state.locusOfFocus - if self.inFocusMode(): - return obj - - if not self.utilities.inDocumentContent(obj): - return obj - - contextObj, _ = self.utilities.getCaretContext(searchIfNeeded=False) - if contextObj and self.utilities.inDocumentContent(contextObj): - return contextObj - - return obj - - def _performClickableAction(self, obj): - from cthulhu import ax_object - - actionNames = ["click", "click-ancestor", "press", "jump", "open", "activate"] - for actionName in actionNames: - if not ax_object.AXObject.has_action(obj, actionName): - continue - if ax_object.AXObject.do_named_action(obj, actionName): - return True - - return False - - def _tryClickableActivation(self, keyboardEvent): - """Try to activate clickable element - returns True if we should consume the event.""" - - obj = self._getClickableActivationTarget() - if not obj or not self.utilities.inDocumentContent(obj): - return False - - # Skip form controls where Return should have normal behavior - from cthulhu import ax_utilities - if (ax_utilities.AXUtilities.is_entry(obj) or - ax_utilities.AXUtilities.is_text(obj) or - ax_utilities.AXUtilities.is_password_text(obj) or - ax_utilities.AXUtilities.is_combo_box(obj) or - ax_utilities.AXUtilities.is_button(obj) or - ax_utilities.AXUtilities.is_push_button(obj) or - ax_utilities.AXUtilities.is_link(obj)): - return False - - # Try clickable activation for non-standard clickable elements - # Store focus information before clicking for potential restoration - original_focus = obj - - # First try the standard clickable detection - if self.utilities.isClickableElement(obj): - self.presentMessage("Activating...") - result = self._performClickableAction(obj) - if result: - return True - - from cthulhu import ax_event_synthesizer - result = ax_event_synthesizer.AXEventSynthesizer.click_object(obj) - if result: - self._restoreFocusAfterClick(original_focus) - return True - - # If that didn't work, try a more permissive approach for any element with click action - from cthulhu import ax_object - if ax_object.AXObject.has_action(obj, "click") \ - or ax_object.AXObject.has_action(obj, "click-ancestor"): - self.presentMessage("Activating...") - result = self._performClickableAction(obj) - if result: - return True - - from cthulhu import ax_event_synthesizer - result = ax_event_synthesizer.AXEventSynthesizer.click_object(obj) - if result: - self._restoreFocusAfterClick(original_focus) - return True - - return False - - def _restoreFocusAfterClick(self, original_focus): - """Try to restore focus after a click action that may have caused DOM changes.""" - try: - from gi.repository import GObject - from cthulhu import ax_object - - # Store the document and caret position to restore navigation context - document = None - caret_offset = -1 - try: - # Find the document root - obj = original_focus - while obj and not ax_object.AXObject.is_dead(obj): - if self.utilities.isDocument(obj): - document = obj - break - parent = ax_object.AXObject.get_parent(obj) - if parent == obj: # Avoid infinite loops - break - obj = parent - - # Get current caret position if available - if document: - try: - caret_offset = ax_object.AXObject.get_caret_offset(document) - except Exception: - pass - - except Exception: - pass - - def restore_focus(): - try: - # First try direct focus restoration if object still exists - if not ax_object.AXObject.is_dead(original_focus): - original_focus.grabFocus() - return False - - # If we have document and caret info, try to restore position - if document and not ax_object.AXObject.is_dead(document) and caret_offset >= 0: - try: - # Set caret back to where it was - ax_object.AXObject.set_caret_offset(document, caret_offset) - # Focus the document to make sure screen reader tracks properly - document.grabFocus() - return False - except Exception: - pass - - # Last resort: try to focus the document if we have it - if document and not ax_object.AXObject.is_dead(document): - document.grabFocus() - - except Exception: - pass # Focus restoration is best effort - return False # Don't repeat the timeout - - # Delay restoration to allow JavaScript and DOM changes to complete - GObject.timeout_add(150, restore_focus) # 150ms delay for DOM changes - - except Exception: - pass # Focus restoration is best effort - - def _presentDelayedMessage(self, message, delay_ms): - """Present a message after a specified delay in milliseconds.""" - try: - from gi.repository import GObject - - def present_message(): - self.presentMessage(message) - return False # Don't repeat - - GObject.timeout_add(delay_ms, present_message) - except Exception: - # If delay fails, present immediately - self.presentMessage(message) - - def activateClickableElement(self, inputEvent): - """Activates clickable element at current focus via Return key.""" - return self._tryClickableActivation(inputEvent) - - def locus_of_focus_changed(self, event, oldFocus, newFocus): - """Handles changes of focus of interest to the script.""" - - if newFocus and self.utilities.isZombie(newFocus): - tokens = ["WEB: New focus is Zombie:", newFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if newFocus and AXObject.is_dead(newFocus): - msg = "WEB: New focus is dead" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - document = self.utilities.getTopLevelDocumentForObject(newFocus) - if not document and self.utilities.isDocument(newFocus): - document = newFocus - - if not document: - msg = "WEB: Locus of focus changed to non-document obj" - self._madeFindAnnouncement = False - if not self._focusModeIsSticky: - self._inFocusMode = False - self._setNavigationSuspended(True, "focus left document content") - debug.printMessage(debug.LEVEL_INFO, msg, True) - oldDocument = self.utilities.getTopLevelDocumentForObject(oldFocus) - if not oldDocument and self.utilities.isDocument(oldFocus): - oldDocument = oldFocus - - if oldFocus and not oldDocument: - msg = "WEB: Not refreshing grabs because we weren't in a document before" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - tokens = ["WEB: Refreshing grabs because we left document", oldDocument] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.refreshKeyGrabs() - return False - - # Focus is in document content - unsuspend navigation if it was suspended - if self._navSuspended: - self._setNavigationSuspended(False, "focus entered document content") - - if self._focusModeIsSticky and not self._inFocusMode: - msg = "WEB: Restoring sticky focus mode after returning to document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._inFocusMode = True - self.presentMessage(messages.MODE_FOCUS_IS_STICKY) - self.refreshKeyGrabs() - elif self._browseModeIsSticky and self._inFocusMode: - msg = "WEB: Restoring sticky browse mode after returning to document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._inFocusMode = False - self.presentMessage(messages.MODE_BROWSE_IS_STICKY) - self.refreshKeyGrabs() - - if self.flatReviewPresenter.is_active(): - self.flatReviewPresenter.quit() - - caretOffset = 0 - if self.utilities.inFindContainer(oldFocus) \ - or (self.utilities.isDocument(newFocus) and oldFocus == cthulhu_state.activeWindow): - contextObj, contextOffset = self.utilities.getCaretContext(documentFrame=document) - if contextObj and not self.utilities.isZombie(contextObj): - newFocus, caretOffset = contextObj, contextOffset - - if AXUtilities.is_unknown_or_redundant(newFocus): - msg = "WEB: Event source has bogus role. Likely browser bug." - debug.printMessage(debug.LEVEL_INFO, msg, True) - newFocus, offset = self.utilities.findFirstCaretContext(newFocus, 0) - - text = self.utilities.queryNonEmptyText(newFocus) - if text: - textOffset = AXText.get_caret_offset(newFocus) - if 0 <= textOffset <= AXText.get_character_count(newFocus): - caretOffset = textOffset - - self.utilities.setCaretContext(newFocus, caretOffset, document) - self.updateBraille(newFocus, documentFrame=document) - cthulhu.emitRegionChanged(newFocus, caretOffset) - - contents = None - args = {} - if self._lastCommandWasMouseButton and event \ - and event.type.startswith("object:text-caret-moved"): - msg = "WEB: Last input event was mouse button. Generating line." - debug.printMessage(debug.LEVEL_INFO, msg, True) - contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset) - args['priorObj'] = oldFocus - elif self.utilities.isContentEditableWithEmbeddedObjects(newFocus) \ - and (self._lastCommandWasCaretNav or self._lastCommandWasStructNav) \ - and not (AXUtilities.is_table_cell(newFocus) and AXObject.get_name(newFocus)): - # Check if we're entering the content editable from outside (e.g. down arrow - # from a message list into a message entry). In that case, generate full object - # speech (with label and role) rather than just line contents. - enteredFromOutside = oldFocus is not None \ - and oldFocus != newFocus \ - and not AXObject.find_ancestor(oldFocus, lambda x: x == newFocus) - if enteredFromOutside: - tokens = ["WEB: New focus", newFocus, - "content editable entered from outside. Generating speech."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - args['priorObj'] = oldFocus - else: - tokens = ["WEB: New focus", newFocus, "content editable. Generating line."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset) - elif self.utilities.isAnchor(newFocus): - tokens = ["WEB: New focus", newFocus, "is anchor. Generating line."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.utilities.getLineContentsAtOffset(newFocus, 0) - elif self.utilities.lastInputEventWasPageNav() \ - and not self.utilities.getTable(newFocus) \ - and not self.utilities.isFeedArticle(newFocus): - tokens = ["WEB: New focus", newFocus, "was scrolled to. Generating line."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset) - elif self.utilities.isFocusedWithMathChild(newFocus): - tokens = ["WEB: New focus", newFocus, "has math child. Generating line."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset) - elif AXUtilities.is_heading(newFocus): - tokens = ["WEB: New focus", newFocus, "is heading. Generating object."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.utilities.get_objectContentsAtOffset(newFocus, 0) - elif self.utilities.caretMovedToSamePageFragment(event, oldFocus): - tokens = ["WEB: Source", event.source, "is same page fragment. Generating line."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.utilities.getLineContentsAtOffset(newFocus, 0) - elif event and event.type.startswith("object:children-changed:remove") \ - and self.utilities.isFocusModeWidget(newFocus): - tokens = ["WEB: New focus", newFocus, - "is recovery from removed child. Generating speech."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - elif self.utilities.lastInputEventWasLineNav() and self.utilities.isZombie(oldFocus): - msg = "WEB: Last input event was line nav; oldFocus is zombie. Generating line." - debug.printMessage(debug.LEVEL_INFO, msg, True) - contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset) - elif self.utilities.lastInputEventWasLineNav() and event \ - and event.type.startswith("object:children-changed"): - msg = "WEB: Last input event was line nav and children changed. Generating line." - debug.printMessage(debug.LEVEL_INFO, msg, True) - contents = self.utilities.getLineContentsAtOffset(newFocus, caretOffset) - else: - tokens = ["WEB: New focus", newFocus, "is not a special case. Generating speech."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - args['priorObj'] = oldFocus - - if newFocus and AXObject.is_dead(newFocus): - msg = "WEB: New focus has since died" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if self._getQueuedEvent("object:state-changed:focused", True): - msg = "WEB: Have matching focused event. Not speaking contents" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - self.interrupt_presentation_for_focus_change(oldFocus, newFocus, event) - - args["interrupt"] = False - if contents: - self.speakContents(contents, **args) - else: - utterances = self.speechGenerator.generateSpeech(newFocus, **args) - speech.speak(utterances, interrupt=False) - - self._saveFocusedObjectInfo(newFocus) - - if not self._focusModeIsSticky \ - and not self._browseModeIsSticky \ - and self.useFocusMode(newFocus, oldFocus) != self._inFocusMode: - self.togglePresentationMode(None, document) - - if not self.utilities.inDocumentContent(oldFocus): - self.refreshKeyGrabs() - - return True - - def onActiveChanged(self, event): - """Callback for object:state-changed:active accessibility events.""" - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if not event.detail1: - msg = "WEB: Ignoring because event source is now inactive" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if AXUtilities.is_dialog_or_alert(event.source): - msg = "WEB: Event handled: Setting locusOfFocus to event source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source) - return True - - return False - - def onActiveDescendantChanged(self, event): - """Callback for object:active-descendant-changed accessibility events.""" - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - return True - - def onBusyChanged(self, event): - """Callback for object:state-changed:busy accessibility events.""" - - if event.detail1 and self._loadingDocumentContent: - msg = "WEB: Ignoring: Already loading document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if not AXUtilities.is_document_web(event.source) \ - and not self.utilities.isOrDescendsFrom(cthulhu_state.locusOfFocus, event.source): - msg = "WEB: Ignoring: Not document and not something we're in" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - self.structuralNavigation.clearCache() - - if self.utilities.getDocumentForObject(AXObject.get_parent(event.source)): - msg = "WEB: Ignoring: Event source is nested document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - obj, offset = self.utilities.getCaretContext() - if not obj or self.utilities.isZombie(obj): - self.utilities.clearCaretContext() - - shouldPresent = True - if not (AXUtilities.is_showing(event.source) or AXUtilities.is_visible(event.source)): - shouldPresent = False - msg = "WEB: Not presenting because source is not showing or visible" - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif not self.utilities.documentFrameURI(event.source): - shouldPresent = False - msg = "WEB: Not presenting because source lacks URI" - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif not event.detail1 and self._inFocusMode and not self.utilities.isZombie(obj): - shouldPresent = False - tokens = ["WEB: Not presenting due to focus mode for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText') and shouldPresent: - if event.detail1: - self.presentMessage(messages.PAGE_LOADING_START) - elif AXObject.get_name(event.source): - msg = messages.PAGE_LOADING_END_NAMED % AXObject.get_name(event.source) - self.presentMessage(msg, resetStyles=False) - else: - self.presentMessage(messages.PAGE_LOADING_END) - - activeDocument = self.utilities.activeDocument() - if activeDocument and activeDocument != event.source: - msg = "WEB: Ignoring: Event source is not active document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - self._loadingDocumentContent = event.detail1 - if event.detail1: - return True - - self.utilities.clearCachedObjects() - if AXObject.is_dead(obj): - obj = None - - if not AXObject.is_dead(cthulhu_state.locusOfFocus) \ - and not self.utilities.inDocumentContent(cthulhu_state.locusOfFocus) \ - and AXUtilities.is_focused(cthulhu_state.locusOfFocus): - msg = "WEB: Not presenting content, focus is outside of document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if cthulhu.cthulhuApp.settingsManager.getSetting('pageSummaryOnLoad') and shouldPresent: - obj = obj or event.source - tokens = ["WEB: Getting page summary for obj", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - summary = self.utilities.getPageSummary(obj) - if summary: - self.presentMessage(summary) - - obj, offset = self.utilities.getCaretContext() - if self.useFocusMode(obj) != self._inFocusMode: - self.togglePresentationMode(None) - - if not obj: - msg = "WEB: Could not get caret context" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.isFocusModeWidget(obj): - tokens = ["WEB: Setting locus of focus to focusModeWidget", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, obj) - return True - - if self.utilities.isLink(obj) and AXUtilities.is_focused(obj): - tokens = ["WEB: Setting locus of focus to focused link", obj, ". No SayAll."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, obj) - return True - - if offset > 0: - tokens = ["WEB: Setting locus of focus to context obj", obj, ". No SayAll"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, obj) - return True - - if not AXUtilities.is_focused(cthulhu_state.locusOfFocus): - tokens = ["WEB: Setting locus of focus to context obj", obj, "(no notification)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, obj, False) - - self.updateBraille(obj) - if self.utilities.documentFragment(event.source): - msg = "WEB: Not doing SayAll due to page fragment" - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif not cthulhu.cthulhuApp.settingsManager.getSetting('sayAllOnLoad'): - msg = "WEB: Not doing SayAll due to sayAllOnLoad being False" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.speakContents(self.utilities.getLineContentsAtOffset(obj, offset)) - elif cthulhu.cthulhuApp.settingsManager.getSetting('enableSpeech'): - msg = "WEB: Doing SayAll" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.sayAll(None) - else: - msg = "WEB: Not doing SayAll due to enableSpeech being False" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - return True - - def onCaretMoved(self, event): - """Callback for object:text-caret-moved accessibility events.""" - - self.utilities.sanityCheckActiveWindow() - - if self.utilities.isZombie(event.source): - msg = "WEB: Event source is Zombie" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - document = self.utilities.getTopLevelDocumentForObject(event.source) - if not document: - if self.utilities.eventIsBrowserUINoise(event): - msg = "WEB: Ignoring event believed to be browser UI noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsBrowserUIAutocompleteNoise(event): - msg = "WEB: Ignoring event believed to be browser UI autocomplete noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - reason = AXUtilitiesEvent.get_text_event_reason(event) - obj, offset = self.utilities.getCaretContext(document, False, False) - tokens = ["WEB: Context: ", obj, ", ", offset, "(focus: ", cthulhu_state.locusOfFocus, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if self.utilities.lastInputEventWasCaretNavWithSelection() and event.detail1 < 0: - if self._presentSyntheticCaretSelection(event, document, obj, offset): - msg = "WEB: Event handled: synthetic caret selection" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - else: - self._clearSyntheticWebSelection() - - if self.utilities.lastInputEventWasCharNav() and (event.source, event.detail1) == (obj, offset): - msg = "WEB: Event ignored: Character navigation already presented this context" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self._lastCommandWasCaretNav: - msg = "WEB: Event ignored: Last command was caret nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self._lastCommandWasStructNav: - msg = "WEB: Event ignored: Last command was struct nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self._lastCommandWasMouseButton: - msg = "WEB: Last command was mouse button" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if (event.source, event.detail1) == (obj, offset): - msg = "WEB: Event is for current caret context." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if (event.source, event.detail1) == self._lastMouseButtonContext: - msg = "WEB: Event is for last mouse button context." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - self._lastMouseButtonContext = event.source, event.detail1 - - msg = "WEB: Event handled: Last command was mouse button" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.utilities.setCaretContext(event.source, event.detail1) - notify = not self.utilities.isEntryDescendant(event.source) - cthulhu.setLocusOfFocus(event, event.source, notify, True) - if cthulhu_state.locusOfFocus == event.source: - self.updateBraille(event.source) - return True - - if reason == TextEventReason.FOCUS_CHANGE: - msg = "WEB: Event ignored: Caret moved due to focus change." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.inFindContainer(): - msg = "WEB: Event handled: Presenting find results" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.presentFindResults(event.source, event.detail1) - self._saveFocusedObjectInfo(cthulhu_state.locusOfFocus) - return True - - if not self.utilities.eventIsFromLocusOfFocusDocument(event): - msg = "WEB: Event ignored: Not from locus of focus document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - typingReasons = (TextEventReason.TYPING, TextEventReason.TYPING_ECHOABLE) - if reason in typingReasons \ - and event.source == cthulhu_state.locusOfFocus \ - and AXUtilities.is_editable(event.source): - msg = f"WEB: Event handled: Updating position due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._saveLastCursorPosition(event.source, event.detail1) - return True - - deletionReasons = (TextEventReason.BACKSPACE, TextEventReason.DELETE) - if reason in deletionReasons and AXUtilities.is_editable(event.source): - msg = f"WEB: Event handled: Updating position due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._saveLastCursorPosition(event.source, event.detail1) - return True - - if self.utilities.isItemForEditableComboBox(cthulhu_state.locusOfFocus, event.source) \ - and not self.utilities.lastInputEventWasCharNav() \ - and not self.utilities.lastInputEventWasLineBoundaryNav(): - msg = "WEB: Event ignored: Editable combobox noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsAutocompleteNoise(event, document): - msg = "WEB: Event ignored: Autocomplete noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self._inFocusMode and self.utilities.caretMovedOutsideActiveGrid(event): - msg = "WEB: Event ignored: Caret moved outside active grid during focus mode" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.treatEventAsSpinnerValueChange(event): - msg = "WEB: Event handled as the value-change event we wish we'd get" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.updateBraille(event.source) - self._presentTextAtNewCaretPosition(event) - return True - - if not self.utilities.queryNonEmptyText(event.source) \ - and not AXUtilities.is_editable(event.source): - msg = "WEB: Event ignored: Was for non-editable object we're treating as textless" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - obj, offset = self.utilities.findFirstCaretContext(event.source, event.detail1) - notify = force = handled = False - AXObject.clear_cache(event.source) - - if self.utilities.lastInputEventWasPageNav(): - msg = "WEB: Caret moved due to scrolling." - debug.printMessage(debug.LEVEL_INFO, msg, True) - notify = force = handled = True - - elif self.utilities.caretMovedToSamePageFragment(event): - msg = "WEB: Caret moved to fragment." - debug.printMessage(debug.LEVEL_INFO, msg, True) - notify = force = handled = True - - elif self.utilities.lastInputEventWasCaretNav(): - msg = "WEB: Caret moved due to native caret navigation." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - elif self.utilities.isTextField(event.source) \ - and AXUtilities.is_focused(event.source) \ - and event.source != cthulhu_state.locusOfFocus: - msg = "WEB: Focused text field is not (yet) the locus of focus." - debug.printMessage(debug.LEVEL_INFO, msg, True) - notify = force = handled = True - - tokens = ["WEB: Setting context and focus to: ", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.utilities.setCaretContext(obj, offset, document) - cthulhu.setLocusOfFocus(event, obj, notify, force) - return handled - - def onCheckedChanged(self, event): - """Callback for object:state-changed:checked accessibility events.""" - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - obj, offset = self.utilities.getCaretContext() - if obj != event.source: - msg = "WEB: Event source is not context object" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - oldObj, oldState = self.pointOfReference.get('checkedChange', (None, 0)) - if hash(oldObj) == hash(obj) and oldState == event.detail1: - msg = "WEB: Ignoring event, state hasn't changed" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not (self._lastCommandWasCaretNav and AXUtilities.is_radio_button(obj)): - msg = "WEB: Event is something default can handle" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - self.presentObject(obj, alreadyFocused=True, interrupt=True) - self.pointOfReference['checkedChange'] = hash(obj), event.detail1 - return True - - def onChildrenAdded(self, event): - """Callback for object:children-changed:add accessibility events.""" - - AXObject.clear_cache_now("children-changed event.") - if self.utilities.eventIsBrowserUINoise(event): - msg = "WEB: Ignoring event believed to be browser UI noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - isLiveRegion = self.utilities.isLiveRegion(event.source) - document = self.utilities.getTopLevelDocumentForObject(event.source) - if document and not isLiveRegion: - if event.source == cthulhu_state.locusOfFocus: - tokens = ["WEB: Dumping cache and context: source is focus", - cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.utilities.dumpCache( - document, - preserveContext=not AXObject.is_dead(event.source), - ) - elif AXObject.is_dead(cthulhu_state.locusOfFocus): - msg = "WEB: Dumping cache: dead focus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.utilities.dumpCache(document, preserveContext=True) - elif AXObject.find_ancestor(cthulhu_state.locusOfFocus, lambda x: x == event.source): - tokens = ["WEB: Dumping cache: source is ancestor of focus", - cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.utilities.dumpCache(document, preserveContext=True) - else: - tokens = ["WEB: Not dumping full cache. Focus is", cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.utilities.clearCachedObjects() - - elif isLiveRegion: - if self.utilities.handleAsLiveRegion(event): - msg = "WEB: Event to be handled as live region" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.liveRegionManager.handleEvent(event) - else: - msg = "WEB: Ignoring because live region event not to be handled." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - else: - msg = "WEB: Could not get document for event source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if self._loadingDocumentContent: - msg = "WEB: Ignoring because document content is being loaded." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.isZombie(document): - tokens = ["WEB: Ignoring because", document, "is zombified."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if AXUtilities.is_busy(document): - tokens = ["WEB: Ignoring because", document, "is busy."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if not event.any_data or self.utilities.isZombie(event.any_data): - msg = "WEB: Ignoring because any data is null or zombified." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.handleEventFromContextReplicant(event, event.any_data): - msg = "WEB: Event handled by updating locusOfFocus and context to child." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if AXUtilities.is_alert(event.any_data): - if event.any_data == self.utilities.lastQueuedLiveRegion(): - tokens = ["WEB: Ignoring", event.any_data, "(is last queued live region)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - msg = "WEB: Presenting event.any_data" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.presentObject(event.any_data, interrupt=True) - - focused = AXUtilities.get_focused_object(event.any_data) - if focused: - notify = self.utilities.queryNonEmptyText(focused) is None - tokens = ["WEB: Setting locusOfFocus and caret context to", focused] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, focused, notify) - self.utilities.setCaretContext(focused, 0) - return True - - if self.lastMouseRoutingTime and 0 < time.time() - self.lastMouseRoutingTime < 1: - utterances = [] - utterances.append(messages.NEW_ITEM_ADDED) - utterances.extend(self.speechGenerator.generateSpeech(event.any_data, force=True)) - speech.speak(utterances) - self._lastMouseOverObject = event.any_data - self.preMouseOverContext = self.utilities.getCaretContext() - return True - - return False - - def onChildrenRemoved(self, event): - """Callback for object:children-changed:removed accessibility events.""" - - AXObject.clear_cache_now("children-changed event.") - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if self._loadingDocumentContent: - msg = "WEB: Ignoring because document content is being loaded." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.isLiveRegion(event.source): - if self.utilities.handleEventForRemovedChild(event): - msg = "WEB: Event handled for removed live-region child." - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - msg = "WEB: Ignoring removal from live region." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - document = self.utilities.getTopLevelDocumentForObject(event.source) - if document: - if event.source == cthulhu_state.locusOfFocus: - tokens = ["WEB: Dumping cache and context: source is focus", - cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.utilities.dumpCache( - document, - preserveContext=not AXObject.is_dead(event.source), - ) - elif AXObject.is_dead(cthulhu_state.locusOfFocus): - msg = "WEB: Dumping cache: dead focus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.utilities.dumpCache(document, preserveContext=True) - elif AXObject.find_ancestor(cthulhu_state.locusOfFocus, lambda x: x == event.source): - tokens = ["WEB: Dumping cache: source is ancestor of focus", - cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.utilities.dumpCache(document, preserveContext=True) - else: - tokens = ["WEB: Not dumping full cache. Focus is", cthulhu_state.locusOfFocus] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.utilities.clearCachedObjects() - - if self.utilities.handleEventForRemovedChild(event): - msg = "WEB: Event handled for removed child." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def onColumnReordered(self, event): - """Callback for object:column-reordered accessibility events.""" - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if event.source != self.utilities.getTable(cthulhu_state.locusOfFocus): - tokens = ["WEB: locusOfFocus (", cthulhu_state.locusOfFocus, ") is not in this table"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - self.pointOfReference['last-table-sort-time'] = time.time() - self.presentMessage(messages.TABLE_REORDERED_COLUMNS) - header = self.utilities.containingTableHeader(cthulhu_state.locusOfFocus) - if header: - self.presentMessage(self.utilities.getSortOrderDescription(header, True)) - - return True - - def onDocumentLoadComplete(self, event): - """Callback for document:load-complete accessibility events.""" - - if self.utilities.getDocumentForObject(AXObject.get_parent(event.source)): - msg = "WEB: Ignoring: Event source is nested document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - msg = "WEB: Updating loading state and resetting live regions" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._loadingDocumentContent = False - self.liveRegionManager.reset() - return True - - def onDocumentLoadStopped(self, event): - """Callback for document:load-stopped accessibility events.""" - - if self.utilities.getDocumentForObject(AXObject.get_parent(event.source)): - msg = "WEB: Ignoring: Event source is nested document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - msg = "WEB: Updating loading state" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._loadingDocumentContent = False - return True - - def onDocumentReload(self, event): - """Callback for document:reload accessibility events.""" - - if self.utilities.getDocumentForObject(AXObject.get_parent(event.source)): - msg = "WEB: Ignoring: Event source is nested document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - msg = "WEB: Updating loading state" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._loadingDocumentContent = True - return True - - def onExpandedChanged(self, event): - """Callback for object:state-changed:expanded accessibility events.""" - - if self.utilities.isZombie(event.source): - msg = "WEB: Event source is Zombie" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - obj, offset = self.utilities.getCaretContext(searchIfNeeded=False) - tokens = ["WEB: Caret context is", obj, ", ", offset, - "(focus: ", cthulhu_state.locusOfFocus, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if not obj or self.utilities.isZombie(obj) and event.source == cthulhu_state.locusOfFocus: - msg = "WEB: Setting caret context to event source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.utilities.setCaretContext(event.source, 0) - - return False - - def onFocus(self, event): - """Callback for focus: accessibility events.""" - - # We should get proper state-changed events for these. - if self.utilities.inDocumentContent(event.source): - if self._getQueuedEvent("object:state-changed:focused", True): - msg = "WEB: Ignoring because object:state-changed-focused expected." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - msg = "WEB: Handling focus event in document content; focused event missing." - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source) - return True - - return False - - def onFocusedChanged(self, event): - """Callback for object:state-changed:focused accessibility events.""" - - if not event.detail1: - msg = "WEB: Ignoring because event source lost focus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.isZombie(event.source): - msg = "WEB: Event source is Zombie" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - document = self.utilities.getDocumentForObject(event.source) - if not document: - msg = "WEB: Could not get document for event source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - prevDocument = self.utilities.getDocumentForObject(cthulhu_state.locusOfFocus) - if prevDocument != document: - tokens = ["WEB: document changed from", prevDocument, "to", document] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - elif document == event.source: - msg = "WEB: Ignoring focus change to document ancestor of focus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.isWebAppDescendant(event.source): - if self._browseModeIsSticky: - msg = "WEB: Web app descendant claimed focus, but browse mode is sticky" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - elif AXUtilities.is_tool_tip(event.source) \ - and AXObject.find_ancestor(cthulhu_state.locusOfFocus, lambda x: x == event.source): - msg = "WEB: Event believed to be side effect of tooltip navigation." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - else: - msg = "WEB: Event handled: Setting locusOfFocus to web app descendant" - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source) - return True - - if AXUtilities.is_editable(event.source): - msg = "WEB: Event source is editable" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if AXUtilities.is_dialog_or_alert(event.source): - msg = "WEB: Event handled: Setting locusOfFocus to event source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source) - return True - - if self.utilities.handleEventFromContextReplicant(event, event.source): - msg = "WEB: Event handled by updating locusOfFocus and context to source." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - obj, offset = self.utilities.getCaretContext() - tokens = ["WEB: Caret context is", obj, ", ", offset, - "(focus: ", cthulhu_state.locusOfFocus, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not obj or self.utilities.isZombie(obj) or prevDocument != document: - tokens = ["WEB: Clearing context - obj", obj, "is null or zombie or document changed"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.utilities.clearCaretContext() - - obj, offset = self.utilities.searchForCaretContext(event.source) - if obj: - notify = self.utilities.inFindContainer(cthulhu_state.locusOfFocus) - tokens = ["WEB: Updating focus and context to", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, obj, notify) - if not notify and prevDocument is None: - self.refreshKeyGrabs() - self.utilities.setCaretContext(obj, offset) - else: - msg = "WEB: Search for caret context failed" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if AXUtilities.is_focusable(event.source) \ - and AXUtilities.is_focused(event.source) \ - and self.utilities.inDocumentContent(event.source): - msg = "WEB: Falling back to focused event source as caret context" - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, event.source, False) - self.utilities.setCaretContext(event.source, 0) - obj, offset = event.source, 0 - - if self._lastCommandWasCaretNav: - msg = "WEB: Event ignored: Last command was caret nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self._lastCommandWasStructNav: - msg = "WEB: Event ignored: Last command was struct nav" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not (AXUtilities.is_focusable(event.source) and AXUtilities.is_focused(event.source)): - msg = "WEB: Event ignored: Source is not focusable or focused" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not AXUtilities.is_document(event.source): - msg = "WEB: Deferring to other scripts for handling non-document source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if not obj: - msg = "WEB: Unable to get non-null, non-zombie context object" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if self.utilities.lastInputEventWasPageNav(): - msg = "WEB: Event handled: Focus changed due to scrolling" - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(event, obj) - self.utilities.setCaretContext(obj, offset) - return True - - wasFocused = AXUtilities.is_focused(obj) - AXObject.clear_cache(obj) - isFocused = AXUtilities.is_focused(obj) - if wasFocused != isFocused: - tokens = ["WEB: Focused state of", obj, "changed to", isFocused] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if self.utilities.isAnchor(obj): - cause = "Context is anchor" - elif not (self.utilities.isLink(obj) and not isFocused): - cause = "Context is not a non-focused link" - elif self.utilities.isChildOfCurrentFragment(obj): - cause = "Context is child of current fragment" - elif document == event.source and self.utilities.documentFragment(event.source): - cause = "Document URI is fragment" - else: - return False - - tokens = ["WEB: Event handled: Setting locusOfFocus to", obj, "(", cause, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, obj) - return True - - def onMouseButton(self, event): - """Callback for mouse:button accessibility events.""" - - self._lastCommandWasCaretNav = False - self._lastCommandWasStructNav = False - self._lastCommandWasMouseButton = True - return False - - def onDescriptionChanged(self, event): - """Callback for object:property-change:accessible-description events.""" - - if self.utilities.eventIsBrowserUINoise(event): - msg = "WEB: Ignoring event believed to be browser UI noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - obj = event.source - if not self.utilities.inDocumentContent(obj): - return False - - descriptions = self.pointOfReference.get('descriptions', {}) - oldDescription = descriptions.get(hash(obj)) - if oldDescription == event.any_data: - tokens = ["WEB: Old description (", oldDescription, ") is the same as new one"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - descriptions[hash(obj)] = event.any_data - self.pointOfReference['descriptions'] = descriptions - if obj != cthulhu_state.locusOfFocus: - msg = "WEB: Description change is for object other than locusOfFocus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not event.any_data: - return True - - name = AXObject.get_name(obj) - if self.utilities.stringsAreRedundant(name, event.any_data): - tokens = ["WEB: Description change is redundant with name for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - self.presentMessage(event.any_data) - return True - - def onNameChanged(self, event): - """Callback for object:property-change:accessible-name events.""" - - if self.utilities.eventIsBrowserUINoise(event): - msg = "WEB: Ignoring event believed to be browser UI noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return True - - def onRowReordered(self, event): - """Callback for object:row-reordered accessibility events.""" - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if event.source != self.utilities.getTable(cthulhu_state.locusOfFocus): - tokens = ["WEB: locusOfFocus (", cthulhu_state.locusOfFocus, ") is not in this table"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - self.pointOfReference['last-table-sort-time'] = time.time() - self.presentMessage(messages.TABLE_REORDERED_ROWS) - header = self.utilities.containingTableHeader(cthulhu_state.locusOfFocus) - if header: - self.presentMessage(self.utilities.getSortOrderDescription(header, True)) - - return True - - def onSelectedChanged(self, event): - """Callback for object:state-changed:selected accessibility events.""" - - if self.utilities.eventIsBrowserUIAutocompleteNoise(event): - msg = "WEB: Ignoring event believed to be browser UI autocomplete noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsBrowserUIPageSwitch(event): - msg = "WEB: Event believed to be browser UI page switch" - debug.printMessage(debug.LEVEL_INFO, msg, True) - if event.detail1: - # Work around stale cache when switching tabs. - AXObject.clear_cache(event.source, False, "Work around Chromium page switch.") - AXUtilities.clear_all_cache_now(reason=msg) - self.utilities.clearCaretContext() - self.presentObject(event.source, priorObj=cthulhu_state.locusOfFocus, interrupt=True) - return True - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if cthulhu_state.locusOfFocus != event.source: - msg = "WEB: Ignoring because event source is not locusOfFocus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def onSelectionChanged(self, event): - """Callback for object:selection-changed accessibility events.""" - - if self.utilities.eventIsBrowserUIAutocompleteNoise(event): - msg = "WEB: Ignoring event believed to be browser UI autocomplete noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsBrowserUIPageSwitch(event): - msg = "WEB: Ignoring event believed to be browser UI page switch" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if not self.utilities.inDocumentContent(cthulhu_state.locusOfFocus): - tokens = ["WEB: Event ignored: locusOfFocus", cthulhu_state.locusOfFocus, - "is not in document content"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if not self.utilities.eventIsFromLocusOfFocusDocument(event): - msg = "WEB: Event ignored: Not from locus of focus document" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.isWebAppDescendant(event.source): - if self._inFocusMode: - # Because we cannot count on the app firing the right state-changed events - # for descendants. - AXObject.clear_cache(event.source) - msg = "WEB: Event source is web app descendant and we're in focus mode" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - msg = "WEB: Event source is web app descendant and we're in browse mode" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsIrrelevantSelectionChangedEvent(event): - msg = "WEB: Event ignored: Irrelevant" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - obj, offset = self.utilities.getCaretContext() - ancestor = self.utilities.commonAncestor(obj, event.source) - if ancestor and self.utilities.isTextBlockElement(ancestor): - msg = "WEB: Ignoring: Common ancestor of context and event source is text block" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def onShowingChanged(self, event): - """Callback for object:state-changed:showing accessibility events.""" - - if event.detail1 and self.utilities.isTopLevelBrowserUIAlert(event.source): - msg = "WEB: Event handled: Presenting event source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.presentObject(event.source, interrupt=True) - return True - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - return True - - def onTextAttributesChanged(self, event): - """Callback for object:text-attributes-changed accessibility events.""" - - msg = "WEB: Clearing cached text attributes" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._currentTextAttrs = {} - return False - - def onTextDeleted(self, event: Atspi.Event) -> bool: - """Callback for object:text-changed:delete accessibility events.""" - - if self.utilities.isZombie(event.source): - msg = "WEB: Event source is Zombie" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - reason = AXUtilitiesEvent.get_text_event_reason(event) - if reason == TextEventReason.PAGE_SWITCH: - msg = f"WEB: Deletion is due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - # UI and live-region classification precedes page-switch classification. - # Preserve page-switch ownership when those conditions overlap. - if self.utilities.lastInputEventWasPageSwitch(): - msg = "WEB: Deletion is due to legacy page-switch fallback" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if reason == TextEventReason.LIVE_REGION_UPDATE: - msg = f"WEB: Ignoring deletion due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - # Preserve web-specific live-region detection for values the shared - # classifier does not currently identify. - if self.utilities.isLiveRegion(event.source): - msg = "WEB: Ignoring deletion from legacy live-region fallback" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if reason == TextEventReason.UI_UPDATE: - msg = f"WEB: Ignoring browser UI event due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsBrowserUINoise(event): - msg = "WEB: Ignoring event believed to be browser UI noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - if reason == TextEventReason.SPIN_BUTTON_VALUE_CHANGE: - msg = f"WEB: Ignoring event due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsSpinnerNoise(event): - msg = "WEB: Ignoring: Event believed to be spinner noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsAutocompleteNoise(event): - msg = "WEB: Ignoring event believed to be autocomplete noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - msg = "WEB: Clearing content cache due to text deletion" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.utilities.clearContentCache() - - deletionReasons = (TextEventReason.BACKSPACE, TextEventReason.DELETE) - if reason in deletionReasons \ - and AXUtilities.is_editable(event.source) \ - and (reason == TextEventReason.DELETE or not self.utilities.isHidden(event.source)): - msg = f"WEB: Event is due to editable text deletion: {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - inputEvent = cthulhu_state.lastNonModifierKeyEvent - unmodifiedPrintableInput = \ - isinstance(cthulhu_state.lastInputEvent, input_event.KeyboardEvent) \ - and inputEvent \ - and inputEvent.is_printable_key() \ - and not inputEvent.modifiers - typingReasons = (TextEventReason.TYPING, TextEventReason.TYPING_ECHOABLE) - if reason in typingReasons \ - and event.source == cthulhu_state.locusOfFocus \ - and AXUtilities.is_editable(event.source) \ - and unmodifiedPrintableInput: - msg = f"WEB: Ignoring insertion-caused deletion: {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - obj, offset = self.utilities.getCaretContext(getZombieReplicant=False) - if obj and obj != event.source \ - and not AXObject.find_ancestor(obj, lambda x: x == event.source): - tokens = ["WEB: Ignoring event because it isn't", obj, "or its ancestor"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if self.utilities.isZombie(obj): - if self.utilities.isLink(obj): - msg = "WEB: Focused link deleted. Taking no further action." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - obj, offset = self.utilities.getCaretContext(getZombieReplicant=True) - if obj: - cthulhu.setLocusOfFocus(event, obj, notifyScript=False) - - if self.utilities.isZombie(obj): - msg = "WEB: Unable to get non-null, non-zombie context object" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - document = self.utilities.getDocumentForObject(event.source) - if document: - tokens = ["WEB: Clearing structural navigation cache for", document] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.structuralNavigation.clearCache(document) - - if not AXUtilities.is_editable(event.source) \ - and not self.utilities.isContentEditableWithEmbeddedObjects(event.source): - if self._inMouseOverObject \ - and self.utilities.isZombie(self._lastMouseOverObject): - msg = "WEB: Restoring pre-mouseover context" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.restorePreMouseOverContext() - - msg = "WEB: Done processing non-editable source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def onTextInserted(self, event): - """Callback for object:text-changed:insert accessibility events.""" - - if self.utilities.isZombie(event.source): - msg = "WEB: Event source is Zombie" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - reason = AXUtilitiesEvent.get_text_event_reason(event) - if reason == TextEventReason.PAGE_SWITCH: - msg = f"WEB: Insertion is due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - # UI and live-region classification precedes page-switch classification. - # Preserve page-switch ownership when those conditions overlap. - if self.utilities.lastInputEventWasPageSwitch(): - msg = "WEB: Insertion is due to legacy page-switch fallback" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if reason == TextEventReason.LIVE_REGION_UPDATE: - if self.utilities.handleAsLiveRegion(event): - msg = f"WEB: Event handled as {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.liveRegionManager.handleEvent(event) - else: - msg = f"WEB: Ignoring unpresented {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - # Preserve web-specific live-region detection for values the shared - # classifier does not currently identify, such as container-live=off. - if self.utilities.handleAsLiveRegion(event): - msg = "WEB: Event handled by legacy live-region fallback" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.liveRegionManager.handleEvent(event) - return True - - if self.utilities.isLiveRegion(event.source): - msg = "WEB: Ignoring because live region event not to be handled." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if reason == TextEventReason.CHILDREN_CHANGE: - msg = f"WEB: Ignoring event due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - # Preserve the broader legacy match for whitespace plus embedded - # object characters until the shared classifier owns that pattern. - if self.utilities.eventIsEOCAdded(event): - msg = "WEB: Ignoring: Event was for embedded object char" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if reason == TextEventReason.UI_UPDATE: - msg = f"WEB: Ignoring browser UI event due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsBrowserUINoise(event): - msg = "WEB: Ignoring event believed to be browser UI noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - if reason == TextEventReason.SPIN_BUTTON_VALUE_CHANGE: - msg = f"WEB: Ignoring event due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsSpinnerNoise(event): - msg = "WEB: Ignoring: Event believed to be spinner noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsAutocompleteNoise(event): - msg = "WEB: Ignoring: Event believed to be autocomplete noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if reason == TextEventReason.AUTO_INSERTION_PRESENTABLE: - msg = f"WEB: Deferring presentable event due to {reason}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - msg = "WEB: Clearing content cache due to text insertion" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.utilities.clearContentCache() - - document = self.utilities.getTopLevelDocumentForObject(event.source) - if AXObject.is_dead(cthulhu_state.locusOfFocus): - msg = "WEB: Dumping cache: dead focus" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.utilities.dumpCache(document, preserveContext=True) - - if AXUtilities.is_focused(event.source): - msg = "WEB: Event handled: Setting locusOfFocus to event source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(None, event.source, force=True) - return True - - else: - tokens = ["WEB: Clearing structural navigation cache for", document] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.structuralNavigation.clearCache(document) - - text = self.utilities.queryNonEmptyText(event.source) - if not text: - msg = "WEB: Ignoring: Event source is not a text object" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not AXUtilities.is_editable(event.source): - if event.source != cthulhu_state.locusOfFocus: - msg = "WEB: Done processing non-editable, non-locusOfFocus source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.isClickableElement(event.source): - msg = "WEB: Event handled: Re-setting locusOfFocus to changed clickable" - debug.printMessage(debug.LEVEL_INFO, msg, True) - cthulhu.setLocusOfFocus(None, event.source, force=True) - return True - - if AXUtilities.is_text_input(event.source) \ - and AXUtilities.is_focused(event.source) \ - and event.source != cthulhu_state.locusOfFocus: - msg = "WEB: Focused entry is not the locus of focus. Waiting for focus event." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def onTextSelectionChanged(self, event): - """Callback for object:text-selection-changed accessibility events.""" - - self._clearSyntheticWebSelection() - - if self.utilities.isZombie(event.source): - msg = "WEB: Event source is Zombie" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsBrowserUINoise(event): - msg = "WEB: Ignoring event believed to be browser UI noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if not self.utilities.inDocumentContent(event.source): - msg = "WEB: Event source is not in document content" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - reason = AXUtilitiesEvent.get_text_event_reason(event) - - if not self.utilities.inDocumentContent(cthulhu_state.locusOfFocus): - tokens = ["WEB: Event ignored: locusOfFocus", cthulhu_state.locusOfFocus, - "is not in document content"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if self.utilities.eventIsAutocompleteNoise(event): - msg = "WEB: Ignoring: Event believed to be autocomplete noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.eventIsSpinnerNoise(event): - msg = "WEB: Ignoring: Event believed to be spinner noise" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.textEventIsForNonNavigableTextObject(event): - msg = "WEB: Ignoring event for non-navigable text object" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - text = self.utilities.queryNonEmptyText(event.source) - if not text: - msg = "WEB: Ignoring: Event source is not a text object" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - selectionReasons = ( - TextEventReason.SELECTION_BY_CHARACTER, - TextEventReason.SELECTION_BY_LINE, - TextEventReason.SELECTION_BY_PARAGRAPH, - TextEventReason.SELECTION_BY_PAGE, - TextEventReason.SELECTION_BY_WORD, - TextEventReason.SELECTION_TO_FILE_BOUNDARY, - TextEventReason.SELECTION_TO_LINE_BOUNDARY, - TextEventReason.UNSPECIFIED_SELECTION, - ) - isSelectionReason = reason in selectionReasons - if isSelectionReason and not AXText.get_selected_ranges(event.source): - document = self.utilities.getTopLevelDocumentForObject(event.source) - obj, offset = self.utilities.getCaretContext(document, False, False) - focusOffset = AXText.get_caret_offset(event.source) - if self._presentSyntheticCaretSelection( - event, - document, - obj, - offset, - focusOverride=(event.source, focusOffset), - isCaretSelection=True, - ): - msg = "WEB: Event handled: synthetic selection from event source" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if AXUtilities.is_text_input(event.source) \ - and AXUtilities.is_focused(event.source) \ - and event.source != cthulhu_state.locusOfFocus: - msg = "WEB: Focused entry is not the locus of focus. Waiting for focus event." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - if self.utilities.isContentEditableWithEmbeddedObjects(event.source): - msg = "WEB: In content editable with embedded objects" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - offset = AXText.get_caret_offset(event.source) - char = AXText.get_substring(event.source, offset, offset + 1) - if char == self.EMBEDDED_OBJECT_CHARACTER \ - and not isSelectionReason \ - and not self.utilities.lastInputEventWasCommand(): - msg = "WEB: Ignoring: Not selecting and event offset is at embedded object" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def onWindowActivated(self, event): - """Callback for window:activate accessibility events.""" - - msg = "WEB: Deferring to app/toolkit script" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - def onWindowDeactivated(self, event): - """Callback for window:deactivate accessibility events.""" - - msg = "WEB: Clearing command state" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._clearSyntheticWebSelection() - self._lastCommandWasCaretNav = False - self._lastCommandWasStructNav = False - self._lastCommandWasMouseButton = False - self._lastMouseButtonContext = None, -1 - return False - - def getTransferableAttributes(self): - return {"_lastCommandWasCaretNav": self._lastCommandWasCaretNav, - "_lastCommandWasStructNav": self._lastCommandWasStructNav, - "_lastCommandWasMouseButton": self._lastCommandWasMouseButton, - "_inFocusMode": self._inFocusMode, - "_focusModeIsSticky": self._focusModeIsSticky, - "_browseModeIsSticky": self._browseModeIsSticky, - } diff --git a/src/cthulhu/scripts/web/script_utilities.py b/src/cthulhu/scripts/web/script_utilities.py deleted file mode 100644 index 7dd3420..0000000 --- a/src/cthulhu/scripts/web/script_utilities.py +++ /dev/null @@ -1,5698 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Joanmarie Diggs." \ - "Copyright (c) 2014-2015 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import functools -import re -import time -import urllib - -from cthulhu import debug -from cthulhu import input_event_manager -from cthulhu import messages -from cthulhu import cthulhu -from cthulhu import cthulhu_state -from cthulhu import script_utilities -from cthulhu import script_manager -from cthulhu import settings_manager -from cthulhu.ax_collection import AXCollection -from cthulhu.ax_component import AXComponent -from cthulhu.ax_document import AXDocument -from cthulhu.ax_hypertext import AXHypertext -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities -from cthulhu.ax_utilities_relation import AXUtilitiesRelation -from cthulhu import speech_and_verbosity_manager - -_scriptManager = None # Removed - use cthulhu.cthulhuApp.scriptManager -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - - -class Utilities(script_utilities.Utilities): - - def __init__(self, script): - super().__init__(script) - - self._objectAttributes = {} - self._currentTextAttrs = {} - self._caretContexts = {} - self._priorContexts = {} - self._canHaveCaretContextDecision = {} - self._contextPathsRolesAndNames = {} - self._paths = {} - self._inDocumentContent = {} - self._inTopLevelWebApp = {} - self._isTextBlockElement = {} - self._isContentEditableWithEmbeddedObjects = {} - self._isCodeDescendant = {} - self._isEntryDescendant = {} - self._hasGridDescendant = {} - self._isGridDescendant = {} - self._isLabelDescendant = {} - self._isModalDialogDescendant = {} - self._isMenuDescendant = {} - self._isNavigableToolTipDescendant = {} - self._isToolBarDescendant = {} - self._isWebAppDescendant = {} - self._isLayoutOnly = {} - self._isFocusableWithMathChild = {} - self._mathNestingLevel = {} - self._isOffScreenLabel = {} - self._labelIsAncestorOfLabelled = {} - self._elementLinesAreSingleChars= {} - self._elementLinesAreSingleWords= {} - self._hasNoSize = {} - self._hasLongDesc = {} - self._hasVisibleCaption = {} - self._hasDetails = {} - self._isDetails = {} - self._isNonInteractiveDescendantOfControl = {} - self._isClickableElement = {} - self._isAnchor = {} - self._isEditableComboBox = {} - self._isErrorMessage = {} - self._isInlineIframeDescendant = {} - self._isInlineListItem = {} - self._isInlineListDescendant = {} - self._isLandmark = {} - self._isLink = {} - self._isListDescendant = {} - self._isNonNavigablePopup = {} - self._isNonEntryTextWidget = {} - self._isCustomImage = {} - self._isUselessImage = {} - self._isRedundantSVG = {} - self._isUselessEmptyElement = {} - self._hasNameAndActionAndNoUsefulChildren = {} - self._isNonNavigableEmbeddedDocument = {} - self._isParentOfNullChild = {} - self._inferredLabels = {} - self._labelsForObject = {} - self._labelTargets = {} - self._descriptionListTerms = {} - self._valuesForTerm = {} - self._displayedLabelText = {} - self._mimeType = {} - self._preferDescriptionOverName = {} - self._shouldFilter = {} - self._shouldInferLabelFor = {} - self._treatAsTextObject = {} - self._treatAsDiv = {} - self._currentObjectContents = None - self._currentSentenceContents = None - self._currentLineContents = None - self._currentWordContents = None - self._currentCharacterContents = None - self._lastQueuedLiveRegionEvent = None - self._findContainer = None - self._validChildRoles = {Atspi.Role.LIST: [Atspi.Role.LIST_ITEM]} - - def _cleanupContexts(self): - toRemove = [] - for key, [obj, offset] in self._caretContexts.items(): - if self.isZombie(obj): - toRemove.append(key) - - for key in toRemove: - self._caretContexts.pop(key, None) - - def dumpCache(self, documentFrame=None, preserveContext=False): - if not documentFrame or self.isZombie(documentFrame): - documentFrame = self.documentFrame() - - documentFrameParent = AXObject.get_parent(documentFrame) - context = self._caretContexts.get(hash(documentFrameParent)) - - tokens = ["WEB: Clearing all cached info for", documentFrame] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self._script.structuralNavigation.clearCache(documentFrame) - self.clearCaretContext(documentFrame) - self.clearCachedObjects() - - if preserveContext and context: - tokens = ["WEB: Preserving context of", context[0], ",", context[1]] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._caretContexts[hash(documentFrameParent)] = context - - def clearCachedObjects(self): - debug.printMessage(debug.LEVEL_INFO, "WEB: cleaning up cached objects", True) - self._objectAttributes = {} - self._inDocumentContent = {} - self._inTopLevelWebApp = {} - self._isTextBlockElement = {} - self._isContentEditableWithEmbeddedObjects = {} - self._isCodeDescendant = {} - self._isEntryDescendant = {} - self._hasGridDescendant = {} - self._isGridDescendant = {} - self._isLabelDescendant = {} - self._isMenuDescendant = {} - self._isModalDialogDescendant = {} - self._isNavigableToolTipDescendant = {} - self._isToolBarDescendant = {} - self._isWebAppDescendant = {} - self._isLayoutOnly = {} - self._isFocusableWithMathChild = {} - self._mathNestingLevel = {} - self._isOffScreenLabel = {} - self._labelIsAncestorOfLabelled = {} - self._elementLinesAreSingleChars= {} - self._elementLinesAreSingleWords= {} - self._hasNoSize = {} - self._hasLongDesc = {} - self._hasVisibleCaption = {} - self._hasDetails = {} - self._isDetails = {} - self._isNonInteractiveDescendantOfControl = {} - self._isClickableElement = {} - self._isAnchor = {} - self._isEditableComboBox = {} - self._isErrorMessage = {} - self._isInlineIframeDescendant = {} - self._isInlineListItem = {} - self._isInlineListDescendant = {} - self._isLandmark = {} - self._isLink = {} - self._isListDescendant = {} - self._isNonNavigablePopup = {} - self._isNonEntryTextWidget = {} - self._isCustomImage = {} - self._isUselessImage = {} - self._isRedundantSVG = {} - self._isUselessEmptyElement = {} - self._hasNameAndActionAndNoUsefulChildren = {} - self._isNonNavigableEmbeddedDocument = {} - self._isParentOfNullChild = {} - self._inferredLabels = {} - self._labelsForObject = {} - self._labelTargets = {} - self._descriptionListTerms = {} - self._valuesForTerm = {} - self._displayedLabelText = {} - self._mimeType = {} - self._preferDescriptionOverName = {} - self._shouldFilter = {} - self._shouldInferLabelFor = {} - self._treatAsTextObject = {} - self._treatAsDiv = {} - self.clearContentCache() - self._paths = {} - self._contextPathsRolesAndNames = {} - self._canHaveCaretContextDecision = {} - self._cleanupContexts() - self._priorContexts = {} - self._lastQueuedLiveRegionEvent = None - self._findContainer = None - - def clearContentCache(self): - self._currentObjectContents = None - self._currentSentenceContents = None - self._currentLineContents = None - self._currentWordContents = None - self._currentCharacterContents = None - self._currentTextAttrs = {} - - def isDocument(self, obj, excludeDocumentFrame=True): - if AXUtilities.is_document_web(obj) or AXUtilities.is_embedded(obj): - return True - - if not excludeDocumentFrame: - return AXUtilities.is_document_frame(obj) - - return False - - def inDocumentContent(self, obj=None): - if not obj: - obj = cthulhu_state.locusOfFocus - - if self.isDocument(obj): - return True - - rv = self._inDocumentContent.get(hash(obj)) - if rv is not None: - return rv - - document = self.getDocumentForObject(obj) - rv = document is not None - self._inDocumentContent[hash(obj)] = rv - return rv - - def _getDocumentsEmbeddedBy(self, frame): - return [x for x in AXUtilitiesRelation.get_embeds(frame) if self.isDocument(x)] - - def sanityCheckActiveWindow(self): - app = self._script.app - if app is None: - app = AXObject.get_application(cthulhu_state.activeWindow) \ - or AXObject.get_application(cthulhu_state.locusOfFocus) - if app is not None: - tokens = ["WEB: recovered script app for active window check:", app] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._script.app = app - - if AXObject.get_parent(cthulhu_state.activeWindow) == app: - return True - - tokens = ["WARNING:", cthulhu_state.activeWindow, "is not child of", app] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # TODO - JD: Is this exception handling still needed? - try: - script = cthulhu.cthulhuApp.scriptManager.get_script(app, cthulhu_state.activeWindow) - tokens = ["WEB: Script for active Window is", script] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - except Exception: - msg = "ERROR: Exception getting script for active window" - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - if isinstance(script, type(self._script)): - attrs = script.getTransferableAttributes() - for attr, value in attrs.items(): - tokens = ["WEB: Setting", attr, "to", value] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - setattr(self._script, attr, value) - - window = self.activeWindow(app) - if window is None: - tokens = [ - "WARNING: WEB could not confirm a replacement active window; preserving", - cthulhu_state.activeWindow, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return cthulhu_state.activeWindow is not None - - self._script.app = AXObject.get_application(window) - tokens = ["WEB: updating script's app to", self._script.app] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - cthulhu.setActiveWindow(window) - return True - - def activeDocument(self, window=None): - window = window or cthulhu_state.activeWindow - documents = self._getDocumentsEmbeddedBy(window) - documents = list(filter(AXUtilities.is_showing, documents)) - - def documentHasUri(document): - return bool(AXDocument.get_uri(document)) - - def findDocumentWithUri(searchRoot): - if not searchRoot: - return None - return AXObject.find_descendant( - searchRoot, - lambda obj: AXUtilities.is_document_web(obj) - and AXUtilities.is_showing(obj) - and AXDocument.get_uri(obj) - ) - - focusDoc = self.getTopLevelDocumentForObject(cthulhu_state.locusOfFocus) - if focusDoc and AXObject.is_dead(focusDoc): - focusDoc = None - - if len(documents) == 1: - document = documents[0] - if focusDoc and focusDoc != document and documentHasUri(focusDoc): - tokens = ["WEB: Single showing document differs; using focus-based document:", - focusDoc] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return focusDoc - if documentHasUri(document): - return document - - fallback = findDocumentWithUri(window) - if fallback and fallback != document: - tokens = ["WEB: Using fallback active document with URI:", fallback] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return fallback - - if focusDoc and documentHasUri(focusDoc): - tokens = ["WEB: Single showing document lacks URI, using focus-based document:", focusDoc] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return focusDoc - - return document - - # If multiple documents are showing (e.g., multi-tab browser), use the - # locus of focus to determine which document is currently active. - if documents: - if focusDoc in documents and documentHasUri(focusDoc): - tokens = ["WEB: Multiple showing documents, using focus-based document:", focusDoc] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return focusDoc - - uriDoc = next((doc for doc in documents if documentHasUri(doc)), None) - if uriDoc and uriDoc != focusDoc: - tokens = ["WEB: Multiple showing documents, using URI-based document:", uriDoc] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return uriDoc - - if focusDoc in documents: - tokens = ["WEB: Multiple showing documents, using focus-based document:", focusDoc] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return focusDoc - - fallback = findDocumentWithUri(window) - if fallback: - tokens = ["WEB: Multiple showing documents, using fallback document:", fallback] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return fallback - - if window: - fallback = findDocumentWithUri(window) - if fallback: - tokens = ["WEB: Using fallback document:", fallback] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return fallback - - return None - - def documentFrame(self, obj=None): - if not obj and self.sanityCheckActiveWindow(): - document = self.activeDocument() - if document: - return document - - return self.getDocumentForObject(obj or cthulhu_state.locusOfFocus) - - def documentFrameURI(self, documentFrame=None): - documentFrame = documentFrame or self.documentFrame() - if documentFrame: - uri = AXDocument.get_uri(documentFrame) - if uri: - return uri - - return "" - - def isPlainText(self, documentFrame=None): - return self.mimeType(documentFrame) == "text/plain" - - def mimeType(self, documentFrame=None): - documentFrame = documentFrame or self.documentFrame() - rv = self._mimeType.get(hash(documentFrame)) - if rv is not None: - return rv - - rv = AXDocument.get_mime_type(documentFrame) - tokens = ["WEB: MimeType of", documentFrame, "is '", rv, "'"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._mimeType[hash(documentFrame)] = rv - - return rv - - def grabFocusWhenSettingCaret(self, obj): - # To avoid triggering popup lists. - if AXUtilities.is_entry(obj): - return False - - if AXUtilities.is_image(obj): - return AXObject.find_ancestor(obj, AXUtilities.is_link) is not None - - if AXUtilities.is_heading(obj) and AXObject.get_child_count(obj) == 1: - return self.isLink(AXObject.get_child(obj, 0)) - - return AXUtilities.is_focusable(obj) - - def grabFocus(self, obj): - if not AXObject.supports_component(obj): - tokens = ["WEB:", obj, "does not support the component interface"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return - - try: - Atspi.Component.grab_focus(obj) - except Exception: - tokens = ["WEB: Exception grabbing focus on", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - def setCaretPosition(self, obj, offset, documentFrame=None): - if self._script.flatReviewPresenter.is_active(): - self._script.flatReviewPresenter.quit() - grabFocus = self.grabFocusWhenSettingCaret(obj) - - obj, offset = self.findFirstCaretContext(obj, offset) - self.setCaretContext(obj, offset, documentFrame) - if self._script.focusModeIsSticky(): - return - - oldFocus = cthulhu_state.locusOfFocus - self.clearTextSelection(oldFocus) - cthulhu.setLocusOfFocus(None, obj, notifyScript=False) - if grabFocus: - self.grabFocus(obj) - - # Don't use queryNonEmptyText() because we need to try to force-update focus. - if AXObject.supports_text(obj): - if AXText.set_caret_offset(obj, offset): - tokens = ["WEB: Caret set to", offset, "in", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - tokens = ["WEB: Exception setting caret to", offset, "in", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if self._script.useFocusMode(obj, oldFocus) != self._script.inFocusMode(): - self._script.togglePresentationMode(None) - - if obj: - AXObject.clear_cache(obj) - - # TODO - JD: This is private. - self._script._saveFocusedObjectInfo(obj) - - def getNextObjectInDocument(self, obj, documentFrame): - if not obj: - return None - - flowsTo = AXUtilitiesRelation.get_flows_to(obj) - if flowsTo: - return flowsTo[0] - - if obj == documentFrame: - obj, offset = self.getCaretContext(documentFrame) - for child in AXObject.iter_children(documentFrame): - if self.characterOffsetInParent(child) > offset: - return child - - if AXObject.get_child_count(obj): - return AXObject.get_child(obj, 0) - - while obj and obj != documentFrame: - nextObj = AXObject.get_next_sibling(obj) - if nextObj: - return nextObj - obj = AXObject.get_parent(obj) - - return None - - def getLastObjectInDocument(self, documentFrame): - return AXObject.find_deepest_descendant(documentFrame) - - def objectAttributes(self, obj, useCache=True): - if not (obj and self.inDocumentContent(obj)): - return super().objectAttributes(obj) - - if useCache: - rv = self._objectAttributes.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.get_attributes_dict(obj) - self._objectAttributes[hash(obj)] = rv - return rv - - def getRoleDescription(self, obj, isBraille=False): - attrs = self.objectAttributes(obj) - rv = attrs.get('roledescription', '') - if isBraille: - rv = attrs.get('brailleroledescription', rv) - - return rv - - def nodeLevel(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().nodeLevel(obj) - - rv = -1 - if not (self.inMenu(obj) or AXUtilities.is_heading(obj)): - attrs = self.objectAttributes(obj) - # ARIA levels are 1-based; non-web content is 0-based. Be consistent. - rv = int(attrs.get('level', 0)) -1 - - return rv - - def _shouldCalculatePositionAndSetSize(self, obj): - return True - - def getPositionAndSetSize(self, obj, **args): - posinset = self.getPositionInSet(obj) - setsize = self.getSetSize(obj) - if posinset is not None and setsize is not None: - # ARIA posinset is 1-based - return posinset - 1, setsize - - if self._shouldCalculatePositionAndSetSize(obj): - return super().getPositionAndSetSize(obj, **args) - - return -1, -1 - - def getPositionInSet(self, obj): - attrs = self.objectAttributes(obj, False) - position = attrs.get('posinset') - if position is not None: - return int(position) - - if AXUtilities.is_table_row(obj): - rowindex = attrs.get('rowindex') - if rowindex is None and AXObject.get_child_count(obj): - cell = AXObject.find_descendant(obj, AXUtilities.is_table_cell_or_header) - rowindex = self.objectAttributes(cell, False).get('rowindex') - - if rowindex is not None: - return int(rowindex) - - return None - - def getSetSize(self, obj): - attrs = self.objectAttributes(obj, False) - setsize = attrs.get('setsize') - if setsize is not None: - return int(setsize) - - if AXUtilities.is_table_row(obj): - rows, cols = self.rowAndColumnCount(self.getTable(obj)) - if rows != -1: - return rows - - return None - - def _getID(self, obj): - attrs = self.objectAttributes(obj) - return attrs.get('id') - - def _getDisplayStyle(self, obj): - attrs = self.objectAttributes(obj) - return attrs.get('display', '') - - def _getTag(self, obj): - attrs = self.objectAttributes(obj) - return attrs.get('tag') - - def _getXMLRoles(self, obj): - attrs = self.objectAttributes(obj) - return attrs.get('xml-roles', '').split() - - def inFindContainer(self, obj=None): - if not obj: - obj = cthulhu_state.locusOfFocus - - if self.inDocumentContent(obj): - return False - - return super().inFindContainer(obj) - - def isEmpty(self, obj): - if not self.isTextBlockElement(obj): - return False - - if AXObject.get_name(obj): - return False - - return self.queryNonEmptyText(obj, False) is None - - def isHidden(self, obj): - hiddenValues = {"true", "1", "yes"} - hiddenStyles = {"none", "hidden", "collapse"} - - current = obj - while current and self.inDocumentContent(current): - attrs = self.objectAttributes(current, False) - hidden = str(attrs.get("hidden", "")).lower() - display = str(attrs.get("display", "")).lower() - visibility = str(attrs.get("visibility", "")).lower() - if hidden in hiddenValues or display in hiddenStyles or visibility in hiddenStyles: - return True - - parent = AXObject.get_parent(current) - if parent == current: - break - current = parent - - return False - - def _isOrIsIn(self, child, parent): - if not (child and parent): - return False - - if child == parent: - return True - - return AXObject.find_ancestor(child, lambda x: x == parent) - - def isShowingAndVisible(self, obj): - rv = super().isShowingAndVisible(obj) - if rv or not self.inDocumentContent(obj): - return rv - - if not self._script.mouseReviewer.inMouseEvent: - if not self._isOrIsIn(cthulhu_state.locusOfFocus, obj): - return rv - - tokens = ["WEB:", obj, "contains locusOfFocus but not showing and visible"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - AXObject.clear_cache(obj) - rv = super().isShowingAndVisible(obj) - if rv: - tokens = ["WEB: Clearing cache fixed state of", obj, ". Missing event?"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return rv - - def isTextArea(self, obj): - if not self.inDocumentContent(obj): - return super().isTextArea(obj) - - if self.isLink(obj): - return False - - if AXUtilities.is_combo_box(obj) \ - and AXUtilities.is_editable(obj) \ - and not AXObject.get_child_count(obj): - return True - - if AXObject.get_role(obj) in self._textBlockElementRoles(): - document = self.getDocumentForObject(obj) - if AXUtilities.is_editable(document): - return True - - return super().isTextArea(obj) - - def isReadOnlyTextArea(self, obj): - # NOTE: This method is deliberately more conservative than isTextArea. - if not AXUtilities.is_entry(obj): - return False - - if AXUtilities.is_read_only(obj): - return True - - return AXUtilities.is_focusable(obj) and not AXUtilities.is_editable(obj) - - def setCaretOffset(self, obj, characterOffset): - self.setCaretPosition(obj, characterOffset) - self._script.updateBraille(obj) - - def nextContext(self, obj=None, offset=-1, skipSpace=False): - if not obj: - obj, offset = self.getCaretContext() - - nextobj, nextoffset = self.findNextCaretInOrder(obj, offset) - if skipSpace: - seen = {(nextobj, nextoffset)} - while self.treatAsTextObject(nextobj) \ - and AXText.get_character_at_offset(nextobj, nextoffset)[0].isspace(): - nextobj, nextoffset = self.findNextCaretInOrder(nextobj, nextoffset) - if (nextobj, nextoffset) in seen: - msg = "WEB: Cycle detected in nextContext skipSpace. Breaking." - debug.printMessage(debug.LEVEL_INFO, msg, True) - break - seen.add((nextobj, nextoffset)) - - return nextobj, nextoffset - - def previousContext(self, obj=None, offset=-1, skipSpace=False): - if not obj: - obj, offset = self.getCaretContext() - - prevobj, prevoffset = self.findPreviousCaretInOrder(obj, offset) - if skipSpace: - seen = {(prevobj, prevoffset)} - while self.treatAsTextObject(prevobj) \ - and AXText.get_character_at_offset(prevobj, prevoffset)[0].isspace(): - prevobj, prevoffset = self.findPreviousCaretInOrder(prevobj, prevoffset) - if (prevobj, prevoffset) in seen: - msg = "WEB: Cycle detected in previousContext skipSpace. Breaking." - debug.printMessage(debug.LEVEL_INFO, msg, True) - break - seen.add((prevobj, prevoffset)) - - return prevobj, prevoffset - - def getSyntheticSelection(self, obj=None): - obj = obj or cthulhu_state.locusOfFocus - state = self._script.pointOfReference.get("syntheticWebSelection") - if not state or not state.get("string"): - return None - - if obj and self.inDocumentContent(obj): - document = self.getTopLevelDocumentForObject(obj) - if document != state.get("document"): - return None - - return state - - def allSelectedText(self, obj): - result = super().allSelectedText(obj) - if result[0] or not self.inDocumentContent(obj): - return result - - state = self.getSyntheticSelection(obj) - if not state: - return result - - string = state.get("string", "") - if not string: - return result - - return [string, 0, len(string)] - - def lastContext(self, root): - offset = 0 - text = self.queryNonEmptyText(root) - if text: - offset = AXText.get_character_count(root) - 1 - - def _isInRoot(o): - return o == root or AXObject.find_ancestor(o, lambda x: x == root) - - obj = root - while obj: - lastobj, lastoffset = self.nextContext(obj, offset) - if not (lastobj and _isInRoot(lastobj)): - break - obj, offset = lastobj, lastoffset - - return obj, offset - - def contextsAreOnSameLine(self, a, b): - if a == b: - return True - - aObj, aOffset = a - bObj, bOffset = b - aExtents = self.getExtents(aObj, aOffset, aOffset + 1) - bExtents = self.getExtents(bObj, bOffset, bOffset + 1) - return self.extentsAreOnSameLine(aExtents, bExtents) - - @staticmethod - def extentsAreOnSameLine(a, b, pixelDelta=5): - if a == b: - return True - - aX, aY, aWidth, aHeight = a - bX, bY, bWidth, bHeight = b - - if aWidth == 0 and aHeight == 0: - return bY <= aY <= bY + bHeight - if bWidth == 0 and bHeight == 0: - return aY <= bY <= aY + aHeight - - highestBottom = min(aY + aHeight, bY + bHeight) - lowestTop = max(aY, bY) - if lowestTop >= highestBottom: - return False - - aMiddle = aY + aHeight / 2 - bMiddle = bY + bHeight / 2 - if abs(aMiddle - bMiddle) > pixelDelta: - return False - - return True - - @staticmethod - def getExtents(obj, startOffset, endOffset): - if not obj: - return [0, 0, 0, 0] - - if AXObject.supports_text(obj) and 0 <= startOffset < endOffset: - rect = AXText.get_range_rect(obj, startOffset, endOffset) - result = [rect.x, rect.y, rect.width, rect.height] - if not (result[0] and result[1] and result[2] == 0 and result[3] == 0 - and AXText.get_substring(obj, startOffset, endOffset).strip()): - return result - - tokens = ["WEB: Suspected bogus range extents for", - obj, "(chars:", startOffset, ",", endOffset, "):", result] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - parent = AXObject.get_parent(obj) - if (AXUtilities.is_menu(obj) or AXUtilities.is_list_item(obj)) \ - and (AXUtilities.is_combo_box(parent) or AXUtilities.is_list_box(parent)): - extents = AXComponent.get_rect(parent) - else: - extents = AXComponent.get_rect(obj) - - return [extents.x, extents.y, extents.width, extents.height] - - def descendantAtPoint(self, root, x, y, coordType=None): - if coordType is None: - coordType = Atspi.CoordType.SCREEN - - result = None - if self.isDocument(root): - result = self.accessibleAtPoint(root, x, y, coordType) - - if result is None: - result = super().descendantAtPoint(root, x, y, coordType) - - if self.isListItemMarker(result) or self.isStaticTextLeaf(result): - return AXObject.get_parent(result) - - return result - - def _preserveTree(self, obj): - if not (obj and AXObject.get_child_count(obj)): - return False - - if self.isMathTopLevel(obj): - return True - - return False - - def expandEOCs(self, obj, startOffset=0, endOffset=-1): - if not self.inDocumentContent(obj): - return super().expandEOCs(obj, startOffset, endOffset) - - if self.hasGridDescendant(obj): - tokens = ["WEB: not expanding EOCs:", obj, "has grid descendant"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return "" - - text = self.queryNonEmptyText(obj) - if not text: - return "" - - if self._preserveTree(obj): - utterances = self._script.speechGenerator.generateSpeech(obj) - return self._script.speechGenerator.utterancesToString(utterances) - - return super().expandEOCs(obj, startOffset, endOffset).strip() - - def substring(self, obj, startOffset, endOffset): - if not self.inDocumentContent(obj): - return super().substring(obj, startOffset, endOffset) - - text = self.queryNonEmptyText(obj) - if text: - return AXText.get_substring(obj, startOffset, endOffset) - - return "" - - def textAttributes(self, acc, offset, get_defaults=False): - attrsForObj = self._currentTextAttrs.get(hash(acc)) or {} - if offset in attrsForObj: - return attrsForObj.get(offset) - - attrs = super().textAttributes(acc, offset, get_defaults) - objAttributes = self.objectAttributes(acc, False) - for key in self._script.attributeNamesDict.keys(): - value = objAttributes.get(key) - if value is not None: - attrs[0][key] = value - - self._currentTextAttrs[hash(acc)] = {offset:attrs} - return attrs - - def localizeTextAttribute(self, key, value): - if key == "justification" and value == "justify": - value = "fill" - - return super().localizeTextAttribute(key, value) - - def adjustContentsForLanguage(self, contents): - rv = [] - for content in contents: - split = self.splitSubstringByLanguage(*content[0:3]) - for start, end, string, language, dialect in split: - rv.append([content[0], start, end, string]) - - return rv - - def getLanguageAndDialectFromTextAttributes(self, obj, startOffset=0, endOffset=-1): - rv = super().getLanguageAndDialectFromTextAttributes(obj, startOffset, endOffset) - if rv or obj is None: - return rv - - # Embedded objects such as images and certain widgets won't implement the text interface - # and thus won't expose text attributes. Therefore try to get the info from the parent. - parent = AXObject.get_parent(obj) - if parent is None: - return rv - - start, end = self.getHyperlinkRange(obj) - language, dialect = self.getLanguageAndDialectForSubstring(parent, start, end) - rv.append((0, 1, language, dialect)) - - return rv - - def findObjectInContents(self, obj, offset, contents, usingCache=False): - if not obj or not contents: - return -1 - - offset = max(0, offset) - matches = [x for x in contents if x[0] == obj] - match = [x for x in matches if x[1] <= offset < x[2]] - if match and match[0] and match[0] in contents: - return contents.index(match[0]) - if not usingCache: - match = [x for x in matches if offset == x[2]] - if match and match[0] and match[0] in contents: - return contents.index(match[0]) - - if not self.isTextBlockElement(obj): - return -1 - - child = AXHypertext.find_child_at_offset(obj, offset) - if child and not self.isTextBlockElement(child): - matches = [x for x in contents if x[0] == child] - if len(matches) == 1: - return contents.index(matches[0]) - - return -1 - - def findPreviousObject(self, obj): - result = super().findPreviousObject(obj) - if not (obj and self.inDocumentContent(obj)): - return result - - if not (result and self.inDocumentContent(result)): - return None - - if self.getTopLevelDocumentForObject(result) != self.getTopLevelDocumentForObject(obj): - return None - - tokens = ["WEB: Previous object for", obj, "is", result, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return result - - def findNextObject(self, obj): - result = super().findNextObject(obj) - if not (obj and self.inDocumentContent(obj)): - return result - - if not (result and self.inDocumentContent(result)): - return None - - if self.getTopLevelDocumentForObject(result) != self.getTopLevelDocumentForObject(obj): - return None - - tokens = ["WEB: Next object for", obj, "is", result, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return result - - def isNonEntryTextWidget(self, obj): - rv = self._isNonEntryTextWidget.get(hash(obj)) - if rv is not None: - return rv - - roles = [Atspi.Role.CHECK_BOX, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.MENU, - Atspi.Role.MENU_ITEM, - Atspi.Role.PAGE_TAB, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.RADIO_BUTTON, - Atspi.Role.PUSH_BUTTON, - Atspi.Role.TOGGLE_BUTTON] - - role = AXObject.get_role(obj) - if role in roles: - rv = True - elif role == Atspi.Role.LIST_ITEM: - rv = not AXUtilities.is_list(AXObject.get_parent(obj)) - elif role == Atspi.Role.TABLE_CELL: - if AXUtilities.is_editable(obj): - rv = False - else: - rv = not self.isTextBlockElement(obj) - - self._isNonEntryTextWidget[hash(obj)] = rv - return rv - - def treatAsTextObject(self, obj, excludeNonEntryTextWidgets=True): - if not obj or AXObject.is_dead(obj): - return False - - rv = self._treatAsTextObject.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.supports_text(obj) - if not rv: - tokens = ["WEB:", obj, "does not implement text interface"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not self.inDocumentContent(obj): - return rv - - if rv and self._treatObjectAsWhole(obj, -1) and AXObject.get_name(obj) \ - and not self.isCellWithNameFromHeader(obj): - tokens = ["WEB: Treating", obj, "as non-text: named object treated as whole."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - - elif rv and not self.isLiveRegion(obj): - doNotQuery = [Atspi.Role.LIST_BOX, Atspi.Role.TABLE, Atspi.Role.TABLE_ROW] - role = AXObject.get_role(obj) - if rv and role in doNotQuery: - tokens = ["WEB: Treating", obj, "as non-text due to role."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - if rv and excludeNonEntryTextWidgets and self.isNonEntryTextWidget(obj): - tokens = ["WEB: Treating", obj, "as non-text: is non-entry text widget."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - if rv and (self.isHidden(obj) or self.isOffScreenLabel(obj)): - tokens = ["WEB: Treating", obj, "as non-text: is hidden or off-screen label."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - if rv and self.isNonNavigableEmbeddedDocument(obj): - tokens = ["WEB: Treating", obj, "as non-text: is non-navigable embedded document."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - if rv and self.isFakePlaceholderForEntry(obj): - tokens = ["WEB: Treating", obj, "as non-text: is fake placeholder for entry."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - - self._treatAsTextObject[hash(obj)] = rv - return rv - - def queryNonEmptyText(self, obj, excludeNonEntryTextWidgets=True): - if self._script.browseModeIsSticky(): - return super().queryNonEmptyText(obj) - - if not self.treatAsTextObject(obj, excludeNonEntryTextWidgets): - return None - - return super().queryNonEmptyText(obj) - - def hasNameAndActionAndNoUsefulChildren(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._hasNameAndActionAndNoUsefulChildren.get(hash(obj)) - if rv is not None: - return rv - - rv = False - if self.hasExplicitName(obj) and AXObject.supports_action(obj): - for child in AXObject.iter_children(obj): - if not self.isUselessEmptyElement(child) or self.isUselessImage(child): - break - else: - rv = True - - if rv: - tokens = ["WEB:", obj, "has name and action and no useful children"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self._hasNameAndActionAndNoUsefulChildren[hash(obj)] = rv - return rv - - def isNonInteractiveDescendantOfControl(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isNonInteractiveDescendantOfControl.get(hash(obj)) - if rv is not None: - return rv - - role = AXObject.get_role(obj) - rv = False - roles = self._textBlockElementRoles() - roles.extend([Atspi.Role.IMAGE, Atspi.Role.CANVAS]) - if role in roles and not AXUtilities.is_focusable(obj): - controls = [Atspi.Role.CHECK_BOX, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.LIST_BOX, - Atspi.Role.MENU_ITEM, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.RADIO_BUTTON, - Atspi.Role.PUSH_BUTTON, - Atspi.Role.TOGGLE_BUTTON, - Atspi.Role.TREE_ITEM] - rv = AXObject.find_ancestor(obj, lambda x: AXObject.get_role(x) in controls) - - self._isNonInteractiveDescendantOfControl[hash(obj)] = rv - return rv - - def _treatObjectAsWhole(self, obj, offset=None): - always = [Atspi.Role.CHECK_BOX, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.LIST_BOX, - Atspi.Role.MENU_ITEM, - Atspi.Role.PAGE_TAB, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.RADIO_BUTTON, - Atspi.Role.PUSH_BUTTON, - Atspi.Role.TOGGLE_BUTTON] - - descendable = [Atspi.Role.MENU, - Atspi.Role.MENU_BAR, - Atspi.Role.TOOL_BAR, - Atspi.Role.TREE_ITEM] - - role = AXObject.get_role(obj) - if role in always: - return True - - if role in descendable: - if self._script.inFocusMode(): - return True - - # This should cause us to initially stop at the large containers before - # allowing the user to drill down into them in browse mode. - return offset == -1 - - if role == Atspi.Role.ENTRY: - if AXObject.get_child_count(obj) == 1 \ - and self.isFakePlaceholderForEntry(AXObject.get_child(obj, 0)): - return True - return False - - if AXUtilities.is_editable(obj): - return False - - if role == Atspi.Role.TABLE_CELL: - if self.isFocusModeWidget(obj): - return not self._script.browseModeIsSticky() - if self.hasNameAndActionAndNoUsefulChildren(obj): - return True - - if role in [Atspi.Role.COLUMN_HEADER, Atspi.Role.ROW_HEADER] \ - and self.hasExplicitName(obj): - return True - - if role == Atspi.Role.COMBO_BOX: - return True - - if role in [Atspi.Role.EMBEDDED, Atspi.Role.TREE, Atspi.Role.TREE_TABLE]: - return not self._script.browseModeIsSticky() - - if role == Atspi.Role.LINK: - return self.hasExplicitName(obj) or self.hasUselessCanvasDescendant(obj) - - if self.isNonNavigableEmbeddedDocument(obj): - return True - - if self.isFakePlaceholderForEntry(obj): - return True - - if self.isCustomImage(obj): - return True - - return False - - def __findRange(self, obj, offset, start, end, boundary): - # We should not have to do any of this. Seriously. This is why - # We can't have nice things. - - allText = AXText.get_all_text(obj) - if boundary == Atspi.TextBoundaryType.CHAR: - try: - string = allText[offset] - except IndexError: - string = "" - - return string, offset, offset + 1 - - extents = list(Atspi.Text.get_range_extents( - obj, offset, offset + 1, Atspi.CoordType.SCREEN)) - - def _inThisSpan(span): - return span[0] <= offset <= span[1] - - def _onThisLine(span): - start, end = span - startExtents = list(Atspi.Text.get_range_extents( - obj, start, start + 1, Atspi.CoordType.SCREEN)) - endExtents = list(Atspi.Text.get_range_extents( - obj, end - 1, end, Atspi.CoordType.SCREEN)) - delta = max(startExtents[3], endExtents[3]) - if not self.extentsAreOnSameLine(startExtents, endExtents, delta): - tokens = ["FAIL: Start", startExtents, "and end", endExtents, - "of '", allText[start:end], "' not on same line"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - startExtents = endExtents - - return self.extentsAreOnSameLine(extents, startExtents) - - spans = [] - charCount = AXText.get_character_count(obj) - if boundary == Atspi.TextBoundaryType.SENTENCE_START: - spans = [m.span() for m in re.finditer( - r"\S*[^\.\?\!]+((? 0 and self.treatAsEndOfLine(obj, offset): - extents = self.getExtents(obj, offset - 1, offset) - else: - extents = self.getExtents(obj, offset, offset + 1) - - if self.isInlineListDescendant(obj): - container = self.listForInlineListDescendant(obj) - if container: - extents = self.getExtents(container, 0, 1) - - objBanner = AXObject.find_ancestor(obj, self.isLandmarkBanner) - objRow = AXObject.find_ancestor(obj, AXUtilities.is_table_row) - - def _include(x): - if x in objects: - return False - - xObj, xStart, xEnd, xString = x - if xStart == xEnd: - return False - - xExtents = self.getExtents(xObj, xStart, xStart + 1) - - if obj != xObj: - if self.isLandmark(obj) and self.isLandmark(xObj): - return False - if self.isLink(obj) and self.isLink(xObj): - xObjBanner = AXObject.find_ancestor(xObj, self.isLandmarkBanner) - if (objBanner or xObjBanner) and objBanner != xObjBanner: - return False - if abs(extents[0] - xExtents[0]) <= 1 and abs(extents[1] - xExtents[1]) <= 1: - # This happens with dynamic skip links such as found on Wikipedia. - return False - elif self.isBlockListDescendant(obj) != self.isBlockListDescendant(xObj): - return False - elif AXUtilities.is_tree_related(obj) and AXUtilities.is_tree_related(xObj): - return False - elif AXUtilities.is_heading(obj) and self.hasNoSize(obj): - return False - elif AXUtilities.is_heading(xObj) and self.hasNoSize(xObj): - return False - - if self.isMathTopLevel(xObj) or self.isMath(obj): - onSameLine = self.extentsAreOnSameLine(extents, xExtents, extents[3]) - elif self.isTextSubscriptOrSuperscript(xObj): - onSameLine = self.extentsAreOnSameLine(extents, xExtents, xExtents[3]) - else: - onSameLine = self.extentsAreOnSameLine(extents, xExtents) - return onSameLine - - boundary = Atspi.TextBoundaryType.LINE_START - objects = self._getContentsForObj(obj, offset, boundary) - if not layoutMode: - if useCache: - self._currentLineContents = objects - - self._debugContentsInfo(obj, offset, objects, "Line (not layout mode)") - return objects - - if self.isLink(obj) and objects and objects[0][0] == obj and objects[0][1] > 0: - if useCache: - self._currentLineContents = objects - - self._debugContentsInfo(obj, offset, objects, "Line (wrapped link)") - return objects - - firstObj, firstStart, firstEnd, firstString = objects[0] - if (extents[2] == 0 and extents[3] == 0) or self.isMath(firstObj): - extents = self.getExtents(firstObj, firstStart, firstEnd) - - lastObj, lastStart, lastEnd, lastString = objects[-1] - if self.isMathTopLevel(lastObj): - lastObj, lastEnd = self.lastContext(lastObj) - lastEnd += 1 - - document = self.getDocumentForObject(obj) - prevObj, pOffset = self.findPreviousCaretInOrder(firstObj, firstStart) - nextObj, nOffset = self.findNextCaretInOrder(lastObj, lastEnd - 1) - - # If we're inside an editable, don't expand line contents beyond its - # boundaries (e.g. don't include an adjacent button just because it's - # on the same visual line). - editableBoundary = self._getEditableLineBoundary(obj) - - # Check for things on the same line to the left of this object. - prevStartTime = time.time() - while prevObj and self.getDocumentForObject(prevObj) == document: - text = self.queryNonEmptyText(prevObj) - if text and AXText.get_substring(prevObj, pOffset, pOffset + 1) in [" ", "\xa0"]: - prevObj, pOffset = self.findPreviousCaretInOrder(prevObj, pOffset) - - if text and AXText.get_substring(prevObj, pOffset, pOffset + 1) == "\n" \ - and firstObj == prevObj: - break - - if objRow != AXObject.find_ancestor(prevObj, AXUtilities.is_table_row): - break - - if editableBoundary and prevObj != editableBoundary \ - and not AXObject.find_ancestor(prevObj, lambda x: x == editableBoundary): - break - - onLeft = self._getContentsForObj(prevObj, pOffset, boundary) - onLeft = list(filter(_include, onLeft)) - if not onLeft: - break - - if self._contentIsSubsetOf(objects[0], onLeft[-1]): - objects.pop(0) - - objects[0:0] = onLeft - firstObj, firstStart = objects[0][0], objects[0][1] - prevObj, pOffset = self.findPreviousCaretInOrder(firstObj, firstStart) - - prevEndTime = time.time() - msg = f"INFO: Time to get line contents on left: {prevEndTime - prevStartTime:.4f}s" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - # Check for things on the same line to the right of this object. - nextStartTime = time.time() - while nextObj and self.getDocumentForObject(nextObj) == document: - text = self.queryNonEmptyText(nextObj) - if text and AXText.get_substring(nextObj, nOffset, nOffset + 1) in [" ", "\xa0"]: - nextObj, nOffset = self.findNextCaretInOrder(nextObj, nOffset) - - if text and AXText.get_substring(nextObj, nOffset, nOffset + 1) == "\n" \ - and lastObj == nextObj: - break - - if objRow != AXObject.find_ancestor(nextObj, AXUtilities.is_table_row): - break - - if editableBoundary and nextObj != editableBoundary \ - and not AXObject.find_ancestor(nextObj, lambda x: x == editableBoundary): - break - - onRight = self._getContentsForObj(nextObj, nOffset, boundary) - if onRight and self._contentIsSubsetOf(objects[0], onRight[-1]): - onRight = onRight[0:-1] - - onRight = list(filter(_include, onRight)) - if not onRight: - break - - objects.extend(onRight) - lastObj, lastEnd = objects[-1][0], objects[-1][2] - if self.isMathTopLevel(lastObj): - lastObj, lastEnd = self.lastContext(lastObj) - lastEnd += 1 - - nextObj, nOffset = self.findNextCaretInOrder(lastObj, lastEnd - 1) - - nextEndTime = time.time() - msg = f"INFO: Time to get line contents on right: {nextEndTime - nextStartTime:.4f}s" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - firstObj, firstStart, firstEnd, firstString = objects[0] - if firstString == "\n" and len(objects) > 1: - objects.pop(0) - - if useCache: - self._currentLineContents = objects - - msg = f"INFO: Time to get line contents: {time.time() - startTime:.4f}s" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self._debugContentsInfo(obj, offset, objects, "Line (layout mode)") - - self._canHaveCaretContextDecision = {} - return objects - - def getPreviousLineContents(self, obj=None, offset=-1, layoutMode=None, useCache=True): - if obj is None: - obj, offset = self.getCaretContext() - - tokens = ["WEB: Current context is: ", obj, ", ", offset, - "(focus: ", cthulhu_state.locusOfFocus, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if obj and self.isZombie(obj): - tokens = ["WEB: Current context obj", obj, "is zombie. Clearing cache."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.clearCachedObjects() - - obj, offset = self.getCaretContext() - tokens = ["WEB: Now Current context is: ", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - line = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache) - if not (line and line[0]): - return [] - - firstObj, firstOffset = line[0][0], line[0][1] - tokens = ["WEB: First context on line is: ", firstObj, ", ", firstOffset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - skipSpace = not speech_and_verbosity_manager.getManager().get_speak_blank_lines() - obj, offset = self.previousContext(firstObj, firstOffset, skipSpace) - if not obj and firstObj: - tokens = ["WEB: Previous context is: ", obj, ", ", offset, ". Trying again."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.clearCachedObjects() - obj, offset = self.previousContext(firstObj, firstOffset, skipSpace) - - tokens = ["WEB: Previous context is: ", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if obj == firstObj and 0 <= offset < firstOffset and self.isLink(obj): - contents = self.getLineContentsAtOffset(obj, offset, layoutMode=False, useCache=False) - if contents and contents != line: - msg = "WEB: Using same-link non-layout previous line contents." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return contents - - contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache) - if not contents: - tokens = ["WEB: Could not get line contents for ", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - if line == contents: - obj, offset = self.previousContext(obj, offset, True) - tokens = ["WEB: Got same line. Trying again with ", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache) - - if line == contents: - start, end = self.getHyperlinkRange(obj) - parent = AXObject.get_parent(obj) - tokens = ["WEB: Got same line. ", obj, "has range in", parent, "of", start, "-", end] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if start >= 0: - obj, offset = self.previousContext(parent, start, True) - tokens = ["WEB: Trying again with", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache) - - return contents - - def getNextLineContents(self, obj=None, offset=-1, layoutMode=None, useCache=True): - if obj is None: - obj, offset = self.getCaretContext() - - tokens = ["WEB: Current context is: ", obj, ", ", offset, - "(focus: ", cthulhu_state.locusOfFocus, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if obj and self.isZombie(obj): - tokens = ["WEB: Current context obj", obj, "is zombie. Clearing cache."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.clearCachedObjects() - - obj, offset = self.getCaretContext() - tokens = ["WEB: Now Current context is: ", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - line = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache) - if not (line and line[0]): - return [] - - lastObj, lastOffset = line[-1][0], line[-1][2] - 1 - math = self.getMathAncestor(lastObj) - if math: - lastObj, lastOffset = self.lastContext(math) - - tokens = ["WEB: Last context on line is: ", lastObj, ", ", lastOffset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - skipSpace = not speech_and_verbosity_manager.getManager().get_speak_blank_lines() - obj, offset = self.nextContext(lastObj, lastOffset, skipSpace) - if not obj and lastObj: - tokens = ["WEB: Next context is: ", obj, ", ", offset, ". Trying again."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.clearCachedObjects() - obj, offset = self.nextContext(lastObj, lastOffset, skipSpace) - - tokens = ["WEB: Next context is: ", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if obj == lastObj and offset > lastOffset and self.isLink(obj): - contents = self.getLineContentsAtOffset(obj, offset, layoutMode=False, useCache=False) - if contents and contents != line: - msg = "WEB: Using same-link non-layout next line contents." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return contents - - if self.isLink(lastObj): - start, end = self.getHyperlinkRange(lastObj) - if obj == AXObject.get_parent(lastObj) and end >= 0 and offset >= end: - contents = self.getLineContentsAtOffset(obj, offset, layoutMode=False, useCache=False) - contents = self._trimContentsBeforeEmbeddedObjectBoundary(contents, obj, offset) - if contents and contents != line: - msg = "WEB: Using non-layout line after split link." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return contents - - contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache) - if line == contents: - obj, offset = self.nextContext(obj, offset, True) - tokens = ["WEB: Got same line. Trying again with ", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache) - - if line == contents: - start, end = self.getHyperlinkRange(obj) - parent = AXObject.get_parent(obj) - tokens = ["WEB: Got same line. ", obj, "has range in", parent, "of", start, "-", end] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if end >= 0: - obj, offset = self.nextContext(parent, end, True) - tokens = ["WEB: Trying again with", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache) - - if not contents: - tokens = ["WEB: Could not get line contents for ", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - return contents - - def updateCachedTextSelection(self, obj): - if not self.inDocumentContent(obj): - super().updateCachedTextSelection(obj) - return - - if self.hasPresentableText(obj): - super().updateCachedTextSelection(obj) - - def _findSelectionBoundaryObject(self, root, findStart=True): - if not AXObject.supports_text(root): - return None - - string, start, end = AXText.get_selected_text(root) - if not string: - return None - - if findStart and not string.startswith(self.EMBEDDED_OBJECT_CHARACTER): - return root - - if not findStart and not string.endswith(self.EMBEDDED_OBJECT_CHARACTER): - return root - - indices = list(range(AXObject.get_child_count(root))) - if not findStart: - indices.reverse() - - for i in indices: - result = self._findSelectionBoundaryObject(root[i], findStart) - if result: - return result - - return None - - def _getSelectionAnchorAndFocus(self, root): - obj1 = self._findSelectionBoundaryObject(root, True) - obj2 = self._findSelectionBoundaryObject(root, False) - return obj1, obj2 - - def _getSubtree(self, startObj, endObj): - if not (startObj and endObj): - return [] - - if AXObject.is_dead(startObj): - msg = "INFO: Cannot get subtree: Start object is dead." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return [] - - def _include(x): - return x is not None - - def _exclude(x): - return self.isStaticTextLeaf(x) - - subtree = [] - startObjParent = AXObject.get_parent(startObj) - for i in range(AXObject.get_index_in_parent(startObj), - AXObject.get_child_count(startObjParent)): - child = AXObject.get_child(startObjParent, i) - if self.isStaticTextLeaf(child): - continue - subtree.append(child) - subtree.extend(self.findAllDescendants(child, _include, _exclude)) - if endObj in subtree: - break - - if endObj == startObj: - return subtree - - if endObj not in subtree: - subtree.append(endObj) - subtree.extend(self.findAllDescendants(endObj, _include, _exclude)) - - endObjParent = AXObject.get_parent(endObj) - endObjIndex = AXObject.get_index_in_parent(endObj) - lastObj = AXObject.get_child(endObjParent, endObjIndex + 1) or endObj - - try: - endIndex = subtree.index(lastObj) - except ValueError: - pass - else: - if lastObj == endObj: - endIndex += 1 - subtree = subtree[:endIndex] - - return subtree - - def handleTextSelectionChange(self, obj, speakMessage=True): - if not self.inDocumentContent(obj): - return super().handleTextSelectionChange(obj) - - adapter = self._getSelectionAdapter() - oldSnapshot = adapter.get_cached_snapshot(obj) - newSnapshot = adapter.refresh_snapshot(obj) - - def _cmp(obj1, obj2): - return self.pathComparison(AXObject.get_path(obj1), AXObject.get_path(obj2)) - - descendants = [] - seen = set() - for descendant in adapter.get_selected_objects(oldSnapshot) + adapter.get_selected_objects(newSnapshot): - if hash(descendant) in seen: - continue - seen.add(hash(descendant)) - descendants.append(descendant) - - descendants.sort(key=functools.cmp_to_key(_cmp)) - - if not descendants: - return super().handleTextSelectionChange(obj, speakMessage) - - for descendant in descendants: - super().handleTextSelectionChange(descendant, speakMessage) - - return True - - def inPDFViewer(self, obj=None): - uri = self.documentFrameURI() - return uri.lower().endswith(".pdf") - - def inTopLevelWebApp(self, obj=None): - if not obj: - obj = cthulhu_state.locusOfFocus - - rv = self._inTopLevelWebApp.get(hash(obj)) - if rv is not None: - return rv - - document = self.getDocumentForObject(obj) - if not document and self.isDocument(obj): - document = obj - - rv = self.isTopLevelWebApp(document) - self._inTopLevelWebApp[hash(obj)] = rv - return rv - - def isTopLevelWebApp(self, obj): - if AXUtilities.is_embedded(obj) \ - and not self.getDocumentForObject(AXObject.get_parent(obj)): - uri = self.documentFrameURI() - rv = bool(uri and uri.startswith("http")) - tokens = ["WEB:", obj, "is top-level web application:", rv, "(URI:", uri, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - return False - - def forceBrowseModeForWebAppDescendant(self, obj): - if not self.isWebAppDescendant(obj): - return False - - if AXUtilities.is_tool_tip(obj): - return AXUtilities.is_focused(obj) - - if AXUtilities.is_document_web(obj): - return not self.isFocusModeWidget(obj) - - return False - - def isFocusModeWidget(self, obj): - if AXUtilities.is_editable(obj): - tokens = ["WEB:", obj, "is focus mode widget because it's editable"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if AXUtilities.is_expandable(obj) and AXUtilities.is_focusable(obj) \ - and not AXUtilities.is_link(obj): - tokens = ["WEB:", obj, "is focus mode widget because it's expandable and focusable"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - alwaysFocusModeRoles = [Atspi.Role.COMBO_BOX, - Atspi.Role.ENTRY, - Atspi.Role.LIST_BOX, - Atspi.Role.MENU, - Atspi.Role.MENU_ITEM, - Atspi.Role.CHECK_MENU_ITEM, - Atspi.Role.RADIO_MENU_ITEM, - Atspi.Role.PAGE_TAB, - Atspi.Role.PASSWORD_TEXT, - Atspi.Role.PROGRESS_BAR, - Atspi.Role.SLIDER, - Atspi.Role.SPIN_BUTTON, - Atspi.Role.TOOL_BAR, - Atspi.Role.TREE_ITEM, - Atspi.Role.TREE_TABLE, - Atspi.Role.TREE] - - role = AXObject.get_role(obj) - if role in alwaysFocusModeRoles: - tokens = ["WEB:", obj, "is focus mode widget due to its role"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if role in [Atspi.Role.TABLE_CELL, Atspi.Role.TABLE] \ - and self.isLayoutOnly(self.getTable(obj)): - tokens = ["WEB:", obj, "is not focus mode widget because it's layout only"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if AXUtilities.is_list_item(obj): - rv = AXObject.find_ancestor(obj, AXUtilities.is_list_box) - if rv: - tokens = ["WEB:", obj, "is focus mode widget because it's a listbox descendant"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - if self.isButtonWithPopup(obj): - tokens = ["WEB:", obj, "is focus mode widget because it's a button with popup"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - focusModeRoles = [Atspi.Role.EMBEDDED, - Atspi.Role.TABLE_CELL, - Atspi.Role.TABLE] - - if role in focusModeRoles \ - and not self.isTextBlockElement(obj) \ - and not self.hasNameAndActionAndNoUsefulChildren(obj) \ - and not self.inPDFViewer(obj): - tokens = ["WEB:", obj, "is focus mode widget based on presumed functionality"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if self.isGridDescendant(obj): - tokens = ["WEB:", obj, "is focus mode widget because it's a grid descendant"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if self.isMenuDescendant(obj): - tokens = ["WEB:", obj, "is focus mode widget because it's a menu descendant"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if self.isToolBarDescendant(obj): - tokens = ["WEB:", obj, "is focus mode widget because it's a toolbar descendant"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - if self.isContentEditableWithEmbeddedObjects(obj): - tokens = ["WEB:", obj, "is focus mode widget because it's content editable"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - def _textBlockElementRoles(self): - roles = [Atspi.Role.ARTICLE, - Atspi.Role.CAPTION, - Atspi.Role.COLUMN_HEADER, - Atspi.Role.COMMENT, - Atspi.Role.DEFINITION, - Atspi.Role.DESCRIPTION_LIST, - Atspi.Role.DESCRIPTION_TERM, - Atspi.Role.DESCRIPTION_VALUE, - Atspi.Role.DOCUMENT_FRAME, - Atspi.Role.DOCUMENT_WEB, - Atspi.Role.FOOTER, - Atspi.Role.FORM, - Atspi.Role.HEADING, - Atspi.Role.LIST, - Atspi.Role.LIST_ITEM, - Atspi.Role.PARAGRAPH, - Atspi.Role.ROW_HEADER, - Atspi.Role.SECTION, - Atspi.Role.STATIC, - Atspi.Role.TEXT, - Atspi.Role.TABLE_CELL] - - # Remove this check when we bump dependencies to 2.34 - try: - roles.append(Atspi.Role.CONTENT_DELETION) - roles.append(Atspi.Role.CONTENT_INSERTION) - except Exception: - pass - - # Remove this check when we bump dependencies to 2.36 - try: - roles.append(Atspi.Role.MARK) - roles.append(Atspi.Role.SUGGESTION) - except Exception: - pass - - return roles - - def mnemonicShortcutAccelerator(self, obj): - attrs = self.objectAttributes(obj) - keys = map(lambda x: x.replace("+", " "), attrs.get("keyshortcuts", "").split(" ")) - keys = map(lambda x: x.replace(" ", "+"), map(self.labelFromKeySequence, keys)) - rv = ["", " ".join(keys), ""] - if list(filter(lambda x: x, rv)): - return rv - - return super().mnemonicShortcutAccelerator(obj) - - def unrelatedLabels(self, root, onlyShowing=True, minimumWords=3): - if not (root and self.inDocumentContent(root)): - return super().unrelatedLabels(root, onlyShowing, minimumWords) - - return [] - - def isFocusableWithMathChild(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isFocusableWithMathChild.get(hash(obj)) - if rv is not None: - return rv - - rv = False - if AXUtilities.is_focusable(obj) \ - and not self.isDocument(obj): - for child in AXObject.iter_children(obj, self.isMathTopLevel): - rv = True - break - - self._isFocusableWithMathChild[hash(obj)] = rv - return rv - - def isFocusedWithMathChild(self, obj): - if not self.isFocusableWithMathChild(obj): - return False - return AXUtilities.is_focused(obj) - - def isTextBlockElement(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isTextBlockElement.get(hash(obj)) - if rv is not None: - return rv - - role = AXObject.get_role(obj) - textBlockElements = self._textBlockElementRoles() - if role not in textBlockElements: - rv = False - elif not AXObject.supports_text(obj): - rv = False - elif AXUtilities.is_editable(obj): - rv = False - elif self.isGridCell(obj): - rv = False - elif AXUtilities.is_document(obj): - rv = True - elif self.isCustomImage(obj): - rv = False - elif not AXUtilities.is_focusable(obj): - rv = not self.hasNameAndActionAndNoUsefulChildren(obj) - else: - rv = False - - self._isTextBlockElement[hash(obj)] = rv - return rv - - def _advanceCaretInEmptyObject(self, obj): - if AXUtilities.is_table_cell(obj) and not self.queryNonEmptyText(obj): - return not self._script._lastCommandWasStructNav - - return True - - def textAtPoint(self, obj, x, y, coordType=None, boundary=None): - if coordType is None: - coordType = Atspi.CoordType.SCREEN - - if boundary is None: - boundary = Atspi.TextBoundaryType.LINE_START - - string, start, end = super().textAtPoint(obj, x, y, coordType, boundary) - if string == self.EMBEDDED_OBJECT_CHARACTER: - child = AXHypertext.find_child_at_offset(obj, start) - if child: - return self.textAtPoint(child, x, y, coordType, boundary) - - return string, start, end - - def _treatAlertsAsDialogs(self): - return False - - def treatAsDiv(self, obj, offset=None): - if not (obj and self.inDocumentContent(obj)): - return False - - if self.isDescriptionList(obj): - return False - - if AXUtilities.is_list(obj) and offset is not None: - string = self.substring(obj, offset, offset + 1) - if string and string != self.EMBEDDED_OBJECT_CHARACTER: - return True - - childCount = AXObject.get_child_count(obj) - if AXUtilities.is_panel(obj) and not childCount: - return True - - rv = self._treatAsDiv.get(hash(obj)) - if rv is not None: - return rv - - validRoles = self._validChildRoles.get(AXObject.get_role(obj)) - if validRoles: - if not childCount: - rv = True - else: - def pred1(x): - return x is not None and AXObject.get_role(x) not in validRoles - - rv = bool([x for x in AXObject.iter_children(obj, pred1)]) - - if not rv: - parent = AXObject.get_parent(obj) - validRoles = self._validChildRoles.get(parent) - if validRoles: - def pred2(x): - return x is not None and AXObject.get_role(x) not in validRoles - - rv = bool([x for x in AXObject.iter_children(parent, pred2)]) - - self._treatAsDiv[hash(obj)] = rv - return rv - - def isAriaAlert(self, obj): - return 'alert' in self._getXMLRoles(obj) - - def isBlockquote(self, obj): - if super().isBlockquote(obj): - return True - - return self._getTag(obj) == 'blockquote' - - def isComment(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isComment(obj) - - if AXUtilities.is_comment(obj): - return True - - return 'comment' in self._getXMLRoles(obj) - - def isContentDeletion(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isContentDeletion(obj) - - if AXUtilities.is_content_deletion(obj): - return True - - return 'deletion' in self._getXMLRoles(obj) or 'del' == self._getTag(obj) - - def isContentError(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isContentError(obj) - - if AXObject.get_role(obj) not in self._textBlockElementRoles(): - return False - - return AXUtilities.is_invalid_entry(obj) - - def isContentInsertion(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isContentInsertion(obj) - - if AXUtilities.is_content_insertion(obj): - return True - - return 'insertion' in self._getXMLRoles(obj) or 'ins' == self._getTag(obj) - - def isContentMarked(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isContentMarked(obj) - - if AXUtilities.is_mark(obj): - return True - - return 'mark' in self._getXMLRoles(obj) or 'mark' == self._getTag(obj) - - def isContentSuggestion(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isContentSuggestion(obj) - - if AXUtilities.is_suggestion(obj): - return True - - return 'suggestion' in self._getXMLRoles(obj) - - def isCustomElement(self, obj): - tag = self._getTag(obj) - return tag and '-' in tag - - def isInlineIframe(self, obj): - if not AXUtilities.is_internal_frame(obj): - return False - - displayStyle = self._getDisplayStyle(obj) - if "inline" not in displayStyle: - return False - - return self.getDocumentForObject(obj) is not None - - def isInlineIframeDescendant(self, obj): - if not obj: - return False - - rv = self._isInlineIframeDescendant.get(hash(obj)) - if rv is not None: - return rv - - ancestor = AXObject.find_ancestor(obj, self.isInlineIframe) - rv = ancestor is not None - self._isInlineIframeDescendant[hash(obj)] = rv - return rv - - def isInlineSuggestion(self, obj): - if not self.isContentSuggestion(obj): - return False - - displayStyle = self._getDisplayStyle(obj) - return "inline" in displayStyle - - def isSVG(self, obj): - return 'svg' == self._getTag(obj) - - def isTextField(self, obj): - if AXUtilities.is_text_input(obj): - return True - - if AXUtilities.is_combo_box(obj): - return self.isEditableComboBox(obj) - - return False - - def isFirstItemInInlineContentSuggestion(self, obj): - suggestion = AXObject.find_ancestor(obj, self.isInlineSuggestion) - if not (suggestion and AXObject.get_child_count(suggestion)): - return False - - return suggestion[0] == obj - - def isLastItemInInlineContentSuggestion(self, obj): - suggestion = AXObject.find_ancestor(obj, self.isInlineSuggestion) - if not (suggestion and AXObject.get_child_count(suggestion)): - return False - - return suggestion[-1] == obj - - def speakMathSymbolNames(self, obj=None): - obj = obj or cthulhu_state.locusOfFocus - return self.isMath(obj) - - def isInMath(self): - return self.isMath(cthulhu_state.locusOfFocus) - - def isMath(self, obj): - tag = self._getTag(obj) - rv = tag in ['math', - 'maction', - 'maligngroup', - 'malignmark', - 'menclose', - 'merror', - 'mfenced', - 'mfrac', - 'mglyph', - 'mi', - 'mlabeledtr', - 'mlongdiv', - 'mmultiscripts', - 'mn', - 'mo', - 'mover', - 'mpadded', - 'mphantom', - 'mprescripts', - 'mroot', - 'mrow', - 'ms', - 'mscarries', - 'mscarry', - 'msgroup', - 'msline', - 'mspace', - 'msqrt', - 'msrow', - 'mstack', - 'mstyle', - 'msub', - 'msup', - 'msubsup', - 'mtable', - 'mtd', - 'mtext', - 'mtr', - 'munder', - 'munderover'] - - return rv - - def isNoneElement(self, obj): - return self._getTag(obj) == 'none' - - def isMathLayoutOnly(self, obj): - return self._getTag(obj) in ['mrow', 'mstyle', 'merror', 'mpadded'] - - def isMathMultiline(self, obj): - return self._getTag(obj) in ['mtable', 'mstack', 'mlongdiv'] - - def isMathEnclose(self, obj): - return self._getTag(obj) == 'menclose' - - def isMathFenced(self, obj): - return self._getTag(obj) == 'mfenced' - - def isMathFractionWithoutBar(self, obj): - if not AXUtilities.is_math_fraction(obj): - return False - - attrs = self.objectAttributes(obj) - linethickness = attrs.get('linethickness') - if not linethickness: - return False - - for char in linethickness: - if char.isnumeric() and char != '0': - return False - - return True - - def isMathPhantom(self, obj): - return self._getTag(obj) == 'mphantom' - - def isMathMultiScript(self, obj): - return self._getTag(obj) == 'mmultiscripts' - - def _isMathPrePostScriptSeparator(self, obj): - return self._getTag(obj) == 'mprescripts' - - def isMathSubOrSuperScript(self, obj): - return self._getTag(obj) in ['msub', 'msup', 'msubsup'] - - def isMathTable(self, obj): - return self._getTag(obj) == 'mtable' - - def isMathTableRow(self, obj): - return self._getTag(obj) in ['mtr', 'mlabeledtr'] - - def isMathTableCell(self, obj): - return self._getTag(obj) == 'mtd' - - def isMathUnderOrOverScript(self, obj): - return self._getTag(obj) in ['mover', 'munder', 'munderover'] - - def _isMathSubElement(self, obj): - return self._getTag(obj) == 'msub' - - def _isMathSupElement(self, obj): - return self._getTag(obj) == 'msup' - - def _isMathSubsupElement(self, obj): - return self._getTag(obj) == 'msubsup' - - def _isMathUnderElement(self, obj): - return self._getTag(obj) == 'munder' - - def _isMathOverElement(self, obj): - return self._getTag(obj) == 'mover' - - def _isMathUnderOverElement(self, obj): - return self._getTag(obj) == 'munderover' - - def isMathSquareRoot(self, obj): - return self._getTag(obj) == 'msqrt' - - def isMathToken(self, obj): - return self._getTag(obj) in ['mi', 'mn', 'mo', 'mtext', 'ms', 'mspace'] - - def isMathTopLevel(self, obj): - return AXUtilities.is_math(obj) - - def getMathAncestor(self, obj): - if not self.isMath(obj): - return None - - if self.isMathTopLevel(obj): - return obj - - return AXObject.find_ancestor(obj, self.isMathTopLevel) - - def getMathDenominator(self, obj): - return AXObject.get_child(obj, 1) - - def getMathNumerator(self, obj): - return AXObject.get_child(obj, 0) - - def getMathRootBase(self, obj): - if self.isMathSquareRoot(obj): - return obj - - return AXObject.get_child(obj, 0) - - def getMathRootIndex(self, obj): - return AXObject.get_child(obj, 1) - - def getMathScriptBase(self, obj): - if self.isMathSubOrSuperScript(obj) \ - or self.isMathUnderOrOverScript(obj) \ - or self.isMathMultiScript(obj): - return AXObject.get_child(obj, 0) - - return None - - def getMathScriptSubscript(self, obj): - if self._isMathSubElement(obj) or self._isMathSubsupElement(obj): - return AXObject.get_child(obj, 1) - - return None - - def getMathScriptSuperscript(self, obj): - if self._isMathSupElement(obj): - return AXObject.get_child(obj, 1) - - if self._isMathSubsupElement(obj): - return AXObject.get_child(obj, 2) - - return None - - def getMathScriptUnderscript(self, obj): - if self._isMathUnderElement(obj) or self._isMathUnderOverElement(obj): - return AXObject.get_child(obj, 1) - - return None - - def getMathScriptOverscript(self, obj): - if self._isMathOverElement(obj): - return AXObject.get_child(obj, 1) - - if self._isMathUnderOverElement(obj): - return AXObject.get_child(obj, 2) - - return None - - def _getMathPrePostScriptSeparator(self, obj): - for child in AXObject.iter_children(obj): - if self._isMathPrePostScriptSeparator(child): - return child - - return None - - def getMathPrescripts(self, obj): - separator = self._getMathPrePostScriptSeparator(obj) - if not separator: - return [] - - children = [] - child = AXObject.get_next_sibling(separator) - while child: - children.append(child) - child = AXObject.get_next_sibling(child) - - return children - - def getMathPostscripts(self, obj): - separator = self._getMathPrePostScriptSeparator(obj) - children = [] - child = AXObject.get_child(obj, 1) - while child and child != separator: - children.append(child) - child = AXObject.get_next_sibling(child) - - return children - - def getMathEnclosures(self, obj): - if not self.isMathEnclose(obj): - return [] - - attrs = self.objectAttributes(obj) - return attrs.get('notation', 'longdiv').split() - - def getMathFencedSeparators(self, obj): - if not self.isMathFenced(obj): - return [''] - - attrs = self.objectAttributes(obj) - return list(attrs.get('separators', ',')) - - def getMathFences(self, obj): - if not self.isMathFenced(obj): - return ['', ''] - - attrs = self.objectAttributes(obj) - return [attrs.get('open', '('), attrs.get('close', ')')] - - def getMathNestingLevel(self, obj, test=None): - rv = self._mathNestingLevel.get(hash(obj)) - if rv is not None: - return rv - - def pred(x): - if test is not None: - return test(x) - return self._getTag(x) == self._getTag(obj) - - rv = -1 - ancestor = obj - while ancestor: - ancestor = AXObject.find_ancestor(ancestor, pred) - rv += 1 - - self._mathNestingLevel[hash(obj)] = rv - return rv - - def filterContentsForPresentation(self, contents, inferLabels=False): - def _include(x): - obj, start, end, string = x - if not obj or AXObject.is_dead(obj): - return False - - rv = self._shouldFilter.get(hash(obj)) - if rv is not None: - return rv - - displayedText = string or AXObject.get_name(obj) - rv = True - if ((self.isTextBlockElement(obj) or self.isLink(obj)) and not displayedText) \ - or (self.isContentEditableWithEmbeddedObjects(obj) and not string.strip()) \ - or self.isEmptyAnchor(obj) \ - or (self.hasNoSize(obj) and not displayedText) \ - or self.isHidden(obj) \ - or self.isOffScreenLabel(obj) \ - or self.isUselessImage(obj) \ - or self.isErrorForContents(obj, contents) \ - or self.isLabellingContents(obj, contents): - rv = False - elif AXUtilities.is_table_row(obj): - rv = self.hasExplicitName(obj) - else: - widget = self.isInferredLabelForContents(x, contents) - alwaysFilter = [Atspi.Role.RADIO_BUTTON, Atspi.Role.CHECK_BOX] - if widget and (inferLabels or AXObject.get_role(widget) in alwaysFilter): - rv = False - - self._shouldFilter[hash(obj)] = rv - return rv - - if len(contents) == 1: - return contents - - rv = list(filter(_include, contents)) - self._shouldFilter = {} - return rv - - def needsSeparator(self, lastChar, nextChar): - if lastChar.isspace() or nextChar.isspace(): - return False - - openingPunctuation = ["(", "[", "{", "<"] - closingPunctuation = [".", "?", "!", ":", ",", ";", ")", "]", "}", ">"] - if lastChar in closingPunctuation or nextChar in openingPunctuation: - return True - if lastChar in openingPunctuation or nextChar in closingPunctuation: - return False - - return lastChar.isalnum() - - def supportsSelectionAndTable(self, obj): - return AXObject.supports_table(obj) and AXObject.supports_selection(obj) - - def hasGridDescendant(self, obj): - if not obj: - return False - - rv = self._hasGridDescendant.get(hash(obj)) - if rv is not None: - return rv - - if not AXObject.get_child_count(obj): - rv = False - else: - document = self.documentFrame(obj) - if obj != document: - document_has_grids = self.hasGridDescendant(document) - if not document_has_grids: - rv = False - - if rv is None: - grids = AXUtilities.find_all_grids(obj) - rv = bool(grids) - - self._hasGridDescendant[hash(obj)] = rv - return rv - - def isGridDescendant(self, obj): - if not obj: - return False - - rv = self._isGridDescendant.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.find_ancestor(obj, self.supportsSelectionAndTable) is not None - self._isGridDescendant[hash(obj)] = rv - return rv - - def isSorted(self, obj): - attrs = self.objectAttributes(obj, False) - return attrs.get("sort") not in ("none", None) - - def isAscending(self, obj): - attrs = self.objectAttributes(obj, False) - return attrs.get("sort") == "ascending" - - def isDescending(self, obj): - attrs = self.objectAttributes(obj, False) - return attrs.get("sort") == "descending" - - def _rowAndColumnIndices(self, obj): - rowindex = colindex = None - - attrs = self.objectAttributes(obj) - rowindex = attrs.get('rowindex') - colindex = attrs.get('colindex') - if rowindex is not None and colindex is not None: - return rowindex, colindex - - row = AXObject.find_ancestor(obj, AXUtilities.is_table_row) - if row is None: - return rowindex, colindex - - attrs = self.objectAttributes(row) - rowindex = attrs.get('rowindex', rowindex) - colindex = attrs.get('colindex', colindex) - return rowindex, colindex - - def isCellWithNameFromHeader(self, obj): - if not AXUtilities.is_table_cell(obj): - return False - - name = AXObject.get_name(obj) - if not name: - return False - - header = self.columnHeaderForCell(obj) - if header and AXObject.get_name(header) == name: - return True - - header = self.rowHeaderForCell(obj) - if header and AXObject.get_name(header) == name: - return True - - return False - - def labelForCellCoordinates(self, obj): - attrs = self.objectAttributes(obj) - - # The ARIA feature is still in the process of being discussed. - collabel = attrs.get('colindextext', attrs.get('coltext')) - rowlabel = attrs.get('rowindextext', attrs.get('rowtext')) - if collabel is not None and rowlabel is not None: - return f'{collabel}{rowlabel}' - - row = AXObject.find_ancestor(obj, AXUtilities.is_table_row) - if row is None: - return '' - - attrs = self.objectAttributes(row) - collabel = attrs.get('colindextext', attrs.get('coltext', collabel)) - rowlabel = attrs.get('rowindextext', attrs.get('rowtext', rowlabel)) - if collabel is not None and rowlabel is not None: - return f'{collabel}{rowlabel}' - - return '' - - def coordinatesForCell(self, obj, preferAttribute=True, findCellAncestor=False): - if not AXUtilities.is_table_cell_or_header(obj): - if not findCellAncestor: - return -1, -1 - - cell = AXObject.find_ancestor(obj, AXUtilities.is_table_cell_or_header) - return self.coordinatesForCell(cell, preferAttribute, False) - - if not preferAttribute: - return super().coordinatesForCell(obj, preferAttribute) - - rvRow = rvCol = None - rowindex, colindex = self._rowAndColumnIndices(obj) - if rowindex is None or colindex is None: - nativeRowindex, nativeColindex = super().coordinatesForCell(obj, False) - if rowindex is not None: - rvRow = int(rowindex) - 1 - else: - rvRow = nativeRowindex - if colindex is not None: - rvCol = int(colindex) - 1 - else: - rvCol = nativeColindex - - return rvRow, rvCol - - def setSizeUnknown(self, obj): - if super().setSizeUnknown(obj): - return True - - attrs = self.objectAttributes(obj) - return attrs.get('setsize') == '-1' - - def rowOrColumnCountUnknown(self, obj): - if super().rowOrColumnCountUnknown(obj): - return True - - attrs = self.objectAttributes(obj) - return attrs.get('rowcount') == '-1' or attrs.get('colcount') == '-1' - - def rowAndColumnCount(self, obj, preferAttribute=True): - rows, cols = super().rowAndColumnCount(obj) - if not preferAttribute: - return rows, cols - - attrs = self.objectAttributes(obj) - rows = attrs.get('rowcount', rows) - cols = attrs.get('colcount', cols) - return int(rows), int(cols) - - def shouldReadFullRow(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().shouldReadFullRow(obj) - - if not super().shouldReadFullRow(obj): - return False - - if self.isGridDescendant(obj): - return not self._script.inFocusMode() - - if self.lastInputEventWasLineNav(): - return False - - if self.lastInputEventWasMouseButton(): - return False - - return True - - def isEntryDescendant(self, obj): - if not obj: - return False - - rv = self._isEntryDescendant.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.find_ancestor(obj, AXUtilities.is_entry) is not None - self._isEntryDescendant[hash(obj)] = rv - return rv - - def isLabelDescendant(self, obj): - if not obj: - return False - - rv = self._isLabelDescendant.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.find_ancestor(obj, AXUtilities.is_label_or_caption) is not None - self._isLabelDescendant[hash(obj)] = rv - return rv - - def isMenuInCollapsedSelectElement(self, obj): - return False - - def isMenuDescendant(self, obj): - if not obj: - return False - - rv = self._isMenuDescendant.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.find_ancestor(obj, AXUtilities.is_menu) is not None - self._isMenuDescendant[hash(obj)] = rv - return rv - - def isModalDialogDescendant(self, obj): - if not obj: - return False - - rv = self._isModalDialogDescendant.get(hash(obj)) - if rv is not None: - return rv - - rv = super().isModalDialogDescendant(obj) - self._isModalDialogDescendant[hash(obj)] = rv - return rv - - def isNavigableToolTipDescendant(self, obj): - if not obj: - return False - - rv = self._isNavigableToolTipDescendant.get(hash(obj)) - if rv is not None: - return rv - - if AXUtilities.is_tool_tip(obj): - ancestor = obj - else: - ancestor = AXObject.find_ancestor(obj, AXUtilities.is_tool_tip) - rv = ancestor and not self.isNonNavigablePopup(ancestor) - self._isNavigableToolTipDescendant[hash(obj)] = rv - return rv - - def isTime(self, obj): - return 'time' in self._getXMLRoles(obj) or 'time' == self._getTag(obj) - - def isToolBarDescendant(self, obj): - if not obj: - return False - - rv = self._isToolBarDescendant.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.find_ancestor(obj, AXUtilities.is_tool_bar) is not None - self._isToolBarDescendant[hash(obj)] = rv - return rv - - def isWebAppDescendant(self, obj): - if not obj: - return False - - rv = self._isWebAppDescendant.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.find_ancestor(obj, AXUtilities.is_embedded) is not None - self._isWebAppDescendant[hash(obj)] = rv - return rv - - def isLayoutOnly(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isLayoutOnly(obj) - - rv = self._isLayoutOnly.get(hash(obj)) - if rv is not None: - if rv: - tokens = ["WEB:", obj, "is deemed to be layout only"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - if AXUtilities.is_list(obj): - rv = self.treatAsDiv(obj) - elif self.isDescriptionList(obj): - rv = False - elif self.isDescriptionListTerm(obj): - rv = False - elif self.isDescriptionListDescription(obj): - rv = False - elif self.isMath(obj): - rv = False - elif self.isLandmark(obj): - rv = False - elif self.isContentDeletion(obj): - rv = False - elif self.isContentInsertion(obj): - rv = False - elif self.isContentMarked(obj): - rv = False - elif self.isContentSuggestion(obj): - rv = False - elif self.isDPub(obj): - rv = False - elif self.isFeed(obj): - rv = False - elif self.isFigure(obj): - rv = False - elif self.isGrid(obj): - rv = False - elif AXUtilities.is_table_header(obj): - rv = False - elif AXUtilities.is_separator(obj): - rv = False - elif AXUtilities.is_panel(obj): - rv = not self.hasExplicitName(obj) - elif AXUtilities.is_table_row(obj) and not AXUtilities.is_expandable(obj): - rv = not self.hasExplicitName(obj) - elif self.isCustomImage(obj): - rv = False - else: - rv = super().isLayoutOnly(obj) - - if rv: - tokens = ["WEB:", obj, "is deemed to be layout only"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self._isLayoutOnly[hash(obj)] = rv - return rv - - def elementIsPreformattedText(self, obj): - if self._getTag(obj) in ["pre", "code"]: - return True - - if "code" in self._getXMLRoles(obj): - return True - - return False - - def elementLinesAreSingleWords(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - if self.elementIsPreformattedText(obj): - return False - - rv = self._elementLinesAreSingleWords.get(hash(obj)) - if rv is not None: - return rv - - text = self.queryNonEmptyText(obj) - if not text: - return False - - nChars = AXText.get_character_count(obj) - - if not nChars: - return False - - # If we have a series of embedded object characters, there's a reasonable chance - # they'll look like the one-word-per-line CSSified text we're trying to detect. - # We don't want that false positive. By the same token, the one-word-per-line - # CSSified text we're trying to detect can have embedded object characters. So - # if we have more than 30% EOCs, don't use this workaround. (The 30% is based on - # testing with problematic text.) - eocs = re.findall(self.EMBEDDED_OBJECT_CHARACTER, AXText.get_all_text(obj)) - if len(eocs)/nChars > 0.3: - return False - - AXObject.clear_cache(obj) - tokens = list(filter(lambda x: x, re.split(r"[\s\ufffc]", AXText.get_all_text(obj)))) - - # Note: We cannot check for the editable-text interface, because Gecko - # seems to be exposing that for non-editable things. Thanks Gecko. - rv = not AXUtilities.is_editable(obj) and len(tokens) > 1 - if rv: - boundary = Atspi.TextBoundaryType.LINE_START - i = 0 - while i < nChars: - string, start, end = AXText.get_line_at_offset(obj, i) - if len(string.split()) != 1: - rv = False - break - i = max(i+1, end) - - self._elementLinesAreSingleWords[hash(obj)] = rv - return rv - - def elementLinesAreSingleChars(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._elementLinesAreSingleChars.get(hash(obj)) - if rv is not None: - return rv - - text = self.queryNonEmptyText(obj) - if not text: - return False - - nChars = AXText.get_character_count(obj) - - if not nChars: - return False - - # If we have a series of embedded object characters, there's a reasonable chance - # they'll look like the one-char-per-line CSSified text we're trying to detect. - # We don't want that false positive. By the same token, the one-char-per-line - # CSSified text we're trying to detect can have embedded object characters. So - # if we have more than 30% EOCs, don't use this workaround. (The 30% is based on - # testing with problematic text.) - eocs = re.findall(self.EMBEDDED_OBJECT_CHARACTER, AXText.get_all_text(obj)) - if len(eocs)/nChars > 0.3: - return False - - AXObject.clear_cache(obj) - - # Note: We cannot check for the editable-text interface, because Gecko - # seems to be exposing that for non-editable things. Thanks Gecko. - rv = not AXUtilities.is_editable(obj) - if rv: - for i in range(nChars): - char = AXText.get_substring(obj, i, i + 1) - if char.isspace() or char in ["\ufffc", "\ufffd"]: - continue - - string, start, end = AXText.get_line_at_offset(obj, i) - if len(string.strip()) > 1: - rv = False - break - - self._elementLinesAreSingleChars[hash(obj)] = rv - return rv - - def labelIsAncestorOfLabelled(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._labelIsAncestorOfLabelled.get(hash(obj)) - if rv is not None: - return rv - - rv = False - for target in self.targetsForLabel(obj): - if AXObject.find_ancestor(target, lambda x: x == obj): - rv = True - break - - self._labelIsAncestorOfLabelled[hash(obj)] = rv - return rv - - def isOffScreenLabel(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isOffScreenLabel.get(hash(obj)) - if rv is not None: - return rv - - if self.labelIsAncestorOfLabelled(obj): - return False - - rv = False - targets = self.labelTargets(obj) - if targets: - end = AXText.get_character_count(obj) if AXObject.supports_text(obj) else 1 - x, y, width, height = self.getExtents(obj, 0, end) - if x < 0 or y < 0: - rv = True - - self._isOffScreenLabel[hash(obj)] = rv - return rv - - def isDetachedDocument(self, obj): - if AXUtilities.is_document(obj): - parent = AXObject.get_parent(obj) - if parent is None or self.isZombie(parent): - tokens = ["WEB:", obj, "is a detached document"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False - - def iframeForDetachedDocument(self, obj, root=None): - root = root or self.documentFrame() - for iframe in AXUtilities.find_all_internal_frames(root): - if AXObject.get_parent(obj) == iframe: - tokens = ["WEB: Returning", iframe, "as iframe parent of detached", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return iframe - - return None - - def _objectBoundsMightBeBogus(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super()._objectBoundsMightBeBogus(obj) - - if not AXUtilities.is_link(obj) or not AXObject.supports_text(obj): - return False - - try: - char_count = AXText.get_character_count(obj) - start = list(Atspi.Text.get_range_extents(obj, 0, 1, Atspi.CoordType.SCREEN)) - end = list(Atspi.Text.get_range_extents( - obj, max(0, char_count - 1), char_count, Atspi.CoordType.SCREEN)) - except Exception: - return False - if self.extentsAreOnSameLine(start, end): - return False - - if not self.hasPresentableText(AXObject.get_parent(obj)): - return False - - tokens = ["WEB: Objects bounds of", obj, "might be bogus"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - def targetsForLabel(self, obj): - return AXUtilitiesRelation.get_is_label_for(obj) - - def labelTargets(self, obj): - if not (obj and self.inDocumentContent(obj)): - return [] - - rv = self._labelTargets.get(hash(obj)) - if rv is not None: - return rv - - rv = [hash(t) for t in self.targetsForLabel(obj)] - self._labelTargets[hash(obj)] = rv - return rv - - def isLinkAncestorOfImageInContents(self, link, contents): - if not self.isLink(link): - return False - - for obj, start, end, string in contents: - if not AXUtilities.is_image(obj): - continue - if AXObject.find_ancestor(obj, lambda x: x == link): - return True - - return False - - def isInferredLabelForContents(self, content, contents): - obj, start, end, string = content - objs = list(filter(self.shouldInferLabelFor, [x[0] for x in contents])) - if not objs: - return None - - for o in objs: - label, sources = self.inferLabelFor(o) - if obj in sources and label.strip() == string.strip(): - return o - - return None - - def isLabellingInteractiveElement(self, obj): - if self._labelTargets.get(hash(obj)) == []: - return False - - targets = self.targetsForLabel(obj) - for target in targets: - if AXUtilities.is_focusable(target): - return True - - return False - - def isLabellingContents(self, obj, contents=[]): - if self.isFocusModeWidget(obj): - return False - - targets = self.labelTargets(obj) - if not contents: - return bool(targets) or self.isLabelDescendant(obj) - - for acc, start, end, string in contents: - if hash(acc) in targets: - return True - - if not self.isTextBlockElement(obj): - return False - - if not self.isLabelDescendant(obj): - return False - - for acc, start, end, string in contents: - if not self.isLabelDescendant(acc) or self.isTextBlockElement(acc): - continue - - if AXUtilities.is_label_or_caption(self.commonAncestor(acc, obj)): - return True - - return False - - def isAnchor(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isAnchor.get(hash(obj)) - if rv is not None: - return rv - - rv = False - if AXUtilities.is_link(obj) \ - and not AXUtilities.is_focusable(obj) \ - and not AXObject.has_action(obj, "jump") \ - and not self._getXMLRoles(obj): - rv = True - - self._isAnchor[hash(obj)] = rv - return rv - - def isEmptyAnchor(self, obj): - if not self.isAnchor(obj): - return False - - return self.queryNonEmptyText(obj) is None - - def isEmptyToolTip(self, obj): - return AXUtilities.is_tool_tip(obj) and self.queryNonEmptyText(obj) is None - - def isBrowserUIAlert(self, obj): - if not AXUtilities.is_alert(obj): - return False - - if self.inDocumentContent(obj): - return False - - return True - - def isTopLevelBrowserUIAlert(self, obj): - if not self.isBrowserUIAlert(obj): - return False - - parent = AXObject.get_parent(obj) - while parent and self.isLayoutOnly(parent): - parent = AXObject.get_parent(parent) - - return AXUtilities.is_frame(parent) - - def isClickableElement(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isClickableElement.get(hash(obj)) - if rv is not None: - return rv - - if self.labelIsAncestorOfLabelled(obj): - return False - - if self.hasGridDescendant(obj): - tokens = ["WEB:", obj, "is not clickable: has grid descendant"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return "" - - rv = False - if not self.isFocusModeWidget(obj): - if not AXUtilities.is_focusable(obj): - rv = AXObject.has_action(obj, "click") - else: - rv = AXObject.has_action(obj, "click-ancestor") - - if rv and not AXObject.get_name(obj) and AXObject.supports_text(obj): - string = AXText.get_all_text(obj) - if not string.replace("\ufffc", ""): - tokens = ["WEB:", obj, "is not clickable: its text is just EOCs"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif not string.strip(): - rv = not (AXUtilities.is_static(obj) or AXUtilities.is_link(obj)) - - self._isClickableElement[hash(obj)] = rv - return rv - - def isCodeDescendant(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isCodeDescendant(obj) - - rv = self._isCodeDescendant.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.find_ancestor(obj, self.isCode) is not None - self._isCodeDescendant[hash(obj)] = rv - return rv - - def isCode(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isCode(obj) - - return self._getTag(obj) == "code" or "code" in self._getXMLRoles(obj) - - def isDescriptionList(self, obj): - if super().isDescriptionList(obj): - return True - - return self._getTag(obj) == "dl" - - def isDescriptionListTerm(self, obj): - if super().isDescriptionListTerm(obj): - return True - - return self._getTag(obj) == "dt" - - def isDescriptionListDescription(self, obj): - if super().isDescriptionListDescription(obj): - return True - - return self._getTag(obj) == "dd" - - def descriptionListTerms(self, obj): - if not obj: - return [] - - rv = self._descriptionListTerms.get(hash(obj)) - if rv is not None: - return rv - - rv = super().descriptionListTerms(obj) - if not self.inDocumentContent(obj): - return rv - - self._descriptionListTerms[hash(obj)] = rv - return rv - - def valuesForTerm(self, obj): - if not obj: - return [] - - rv = self._valuesForTerm.get(hash(obj)) - if rv is not None: - return rv - - rv = super().valuesForTerm(obj) - if not self.inDocumentContent(obj): - return rv - - self._valuesForTerm[hash(obj)] = rv - return rv - - def getComboBoxValue(self, obj): - attrs = self.objectAttributes(obj, False) - return attrs.get("valuetext", super().getComboBoxValue(obj)) - - def isEditableComboBox(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isEditableComboBox(obj) - - rv = self._isEditableComboBox.get(hash(obj)) - if rv is not None: - return rv - - rv = False - if AXUtilities.is_combo_box(obj): - rv = AXUtilities.is_editable(obj) - - self._isEditableComboBox[hash(obj)] = rv - return rv - - def getEditableComboBoxForItem(self, item): - if not AXUtilities.is_list_item(item): - return None - - listbox = AXObject.find_ancestor(item, AXUtilities.is_list_box) - if listbox is None: - return None - - targets = [x for x in AXUtilitiesRelation.get_is_controlled_by(listbox) - if self.isEditableComboBox(x)] - if len(targets) == 1: - return targets[0] - - return AXObject.find_ancestor(listbox, self.isEditableComboBox) - - def isItemForEditableComboBox(self, item, comboBox): - if not AXUtilities.is_list_item(item): - return False - if not self.isEditableComboBox(comboBox): - return False - - rv = self.getEditableComboBoxForItem(item) == comboBox - tokens = ["WEB:", item, "is item of", comboBox, ":", rv] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - def isDPub(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - roles = self._getXMLRoles(obj) - rv = bool(list(filter(lambda x: x.startswith("doc-"), roles))) - return rv - - def isDPubAbstract(self, obj): - return 'doc-abstract' in self._getXMLRoles(obj) - - def isDPubAcknowledgments(self, obj): - return 'doc-acknowledgments' in self._getXMLRoles(obj) - - def isDPubAfterword(self, obj): - return 'doc-afterword' in self._getXMLRoles(obj) - - def isDPubAppendix(self, obj): - return 'doc-appendix' in self._getXMLRoles(obj) - - def isDPubBacklink(self, obj): - return 'doc-backlink' in self._getXMLRoles(obj) - - def isDPubBiblioref(self, obj): - return 'doc-biblioref' in self._getXMLRoles(obj) - - def isDPubBibliography(self, obj): - return 'doc-bibliography' in self._getXMLRoles(obj) - - def isDPubChapter(self, obj): - return 'doc-chapter' in self._getXMLRoles(obj) - - def isDPubColophon(self, obj): - return 'doc-colophon' in self._getXMLRoles(obj) - - def isDPubConclusion(self, obj): - return 'doc-conclusion' in self._getXMLRoles(obj) - - def isDPubCover(self, obj): - return 'doc-cover' in self._getXMLRoles(obj) - - def isDPubCredit(self, obj): - return 'doc-credit' in self._getXMLRoles(obj) - - def isDPubCredits(self, obj): - return 'doc-credits' in self._getXMLRoles(obj) - - def isDPubDedication(self, obj): - return 'doc-dedication' in self._getXMLRoles(obj) - - def isDPubEndnote(self, obj): - return 'doc-endnote' in self._getXMLRoles(obj) - - def isDPubEndnotes(self, obj): - return 'doc-endnotes' in self._getXMLRoles(obj) - - def isDPubEpigraph(self, obj): - return 'doc-epigraph' in self._getXMLRoles(obj) - - def isDPubEpilogue(self, obj): - return 'doc-epilogue' in self._getXMLRoles(obj) - - def isDPubErrata(self, obj): - return 'doc-errata' in self._getXMLRoles(obj) - - def isDPubExample(self, obj): - return 'doc-example' in self._getXMLRoles(obj) - - def isDPubFootnote(self, obj): - return 'doc-footnote' in self._getXMLRoles(obj) - - def isDPubForeword(self, obj): - return 'doc-foreword' in self._getXMLRoles(obj) - - def isDPubGlossary(self, obj): - return 'doc-glossary' in self._getXMLRoles(obj) - - def isDPubGlossref(self, obj): - return 'doc-glossref' in self._getXMLRoles(obj) - - def isDPubIndex(self, obj): - return 'doc-index' in self._getXMLRoles(obj) - - def isDPubIntroduction(self, obj): - return 'doc-introduction' in self._getXMLRoles(obj) - - def isDPubNoteref(self, obj): - return 'doc-noteref' in self._getXMLRoles(obj) - - def isDPubPagelist(self, obj): - return 'doc-pagelist' in self._getXMLRoles(obj) - - def isDPubPagebreak(self, obj): - return 'doc-pagebreak' in self._getXMLRoles(obj) - - def isDPubPart(self, obj): - return 'doc-part' in self._getXMLRoles(obj) - - def isDPubPreface(self, obj): - return 'doc-preface' in self._getXMLRoles(obj) - - def isDPubPrologue(self, obj): - return 'doc-prologue' in self._getXMLRoles(obj) - - def isDPubPullquote(self, obj): - return 'doc-pullquote' in self._getXMLRoles(obj) - - def isDPubQna(self, obj): - return 'doc-qna' in self._getXMLRoles(obj) - - def isDPubSubtitle(self, obj): - return 'doc-subtitle' in self._getXMLRoles(obj) - - def isDPubToc(self, obj): - return 'doc-toc' in self._getXMLRoles(obj) - - def isErrorMessage(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isErrorMessage(obj) - - rv = self._isErrorMessage.get(hash(obj)) - if rv is not None: - return rv - - rv = bool(AXUtilitiesRelation.get_is_error_for(obj)) - self._isErrorMessage[hash(obj)] = rv - return rv - - def isFakePlaceholderForEntry(self, obj): - if not (obj and self.inDocumentContent(obj) and AXObject.get_parent(obj)): - return False - - if AXUtilities.is_editable(obj): - return False - - entryName = AXObject.get_name(AXObject.find_ancestor(obj, AXUtilities.is_entry)) - if not entryName: - return False - - def _isMatch(x): - if not AXObject.supports_text(x): - return False - string = AXText.get_all_text(x).strip() - if entryName != string: - return False - return AXUtilities.is_section(x) or AXUtilities.is_static(x) - - if _isMatch(obj): - return True - - return AXObject.find_descendant(obj, _isMatch) is not None - - def isGrid(self, obj): - return 'grid' in self._getXMLRoles(obj) - - def isGridCell(self, obj): - return 'gridcell' in self._getXMLRoles(obj) - - def isInlineListItem(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isInlineListItem.get(hash(obj)) - if rv is not None: - return rv - - if not AXUtilities.is_list_item(obj): - rv = False - else: - displayStyle = self._getDisplayStyle(obj) - rv = displayStyle and "inline" in displayStyle - - self._isInlineListItem[hash(obj)] = rv - return rv - - def isBlockListDescendant(self, obj): - if not self.isListDescendant(obj): - return False - - return not self.isInlineListDescendant(obj) - - def isListDescendant(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isListDescendant.get(hash(obj)) - if rv is not None: - return rv - - ancestor = AXObject.find_ancestor(obj, AXUtilities.is_list) - rv = ancestor is not None - self._isListDescendant[hash(obj)] = rv - return rv - - def isInlineListDescendant(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isInlineListDescendant.get(hash(obj)) - if rv is not None: - return rv - - if self.isInlineListItem(obj): - rv = True - else: - ancestor = AXObject.find_ancestor(obj, self.isInlineListItem) - rv = ancestor is not None - - self._isInlineListDescendant[hash(obj)] = rv - return rv - - def listForInlineListDescendant(self, obj): - if not self.isInlineListDescendant(obj): - return None - - return AXObject.find_ancestor(obj, AXUtilities.is_list) - - def isFeed(self, obj): - return 'feed' in self._getXMLRoles(obj) - - def isFeedArticle(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - if not AXUtilities.is_article(obj): - return False - - return AXObject.find_ancestor(obj, self.isFeed) is not None - - def isFigure(self, obj): - return 'figure' in self._getXMLRoles(obj) or self._getTag(obj) == 'figure' - - def isLandmark(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isLandmark.get(hash(obj)) - if rv is not None: - return rv - - if AXUtilities.is_landmark(obj): - rv = True - elif self.isLandmarkRegion(obj): - rv = bool(AXObject.get_name(obj)) - else: - roles = self._getXMLRoles(obj) - rv = bool(list(filter(lambda x: x in self.getLandmarkTypes(), roles))) - - self._isLandmark[hash(obj)] = rv - return rv - - def isLandmarkWithoutType(self, obj): - roles = self._getXMLRoles(obj) - return not roles - - def isLandmarkBanner(self, obj): - return 'banner' in self._getXMLRoles(obj) - - def isLandmarkComplementary(self, obj): - return 'complementary' in self._getXMLRoles(obj) - - def isLandmarkContentInfo(self, obj): - return 'contentinfo' in self._getXMLRoles(obj) - - def isLandmarkForm(self, obj): - return 'form' in self._getXMLRoles(obj) - - def isLandmarkMain(self, obj): - return 'main' in self._getXMLRoles(obj) - - def isLandmarkNavigation(self, obj): - return 'navigation' in self._getXMLRoles(obj) - - def isLandmarkRegion(self, obj): - return 'region' in self._getXMLRoles(obj) - - def isLandmarkSearch(self, obj): - return 'search' in self._getXMLRoles(obj) - - def isLiveRegion(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - attrs = self.objectAttributes(obj) - return 'container-live' in attrs - - def isLink(self, obj): - if not obj: - return False - - rv = self._isLink.get(hash(obj)) - if rv is not None: - return rv - - if AXUtilities.is_link(obj) and not self.isAnchor(obj): - rv = True - elif AXUtilities.is_static(obj) \ - and AXUtilities.is_link(AXObject.get_parent(obj)) \ - and AXObject.has_same_non_empty_name(obj, AXObject.get_parent(obj)): - rv = True - else: - rv = False - - self._isLink[hash(obj)] = rv - return rv - - def isNonNavigablePopup(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isNonNavigablePopup.get(hash(obj)) - if rv is not None: - return rv - - rv = AXUtilities.is_tool_tip(obj) \ - and not AXUtilities.is_focusable(obj) - - self._isNonNavigablePopup[hash(obj)] = rv - return rv - - def hasUselessCanvasDescendant(self, obj): - return len(AXUtilities.find_all_canvases(obj, self.isUselessImage)) > 0 - - def isTextSubscriptOrSuperscript(self, obj): - if self.isMath(obj): - return False - - return AXUtilities.is_subscript_or_superscript(obj) - - def isSwitch(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isSwitch(obj) - - if AXObject.get_role(obj) == Atspi.Role.SWITCH: - return True - - return 'switch' in self._getXMLRoles(obj) - - def isNonNavigableEmbeddedDocument(self, obj): - rv = self._isNonNavigableEmbeddedDocument.get(hash(obj)) - if rv is not None: - return rv - - rv = False - if self.isDocument(obj) and self.getDocumentForObject(obj): - try: - name = AXObject.get_name(obj) - except Exception: - rv = True - else: - rv = "doubleclick" in name - - self._isNonNavigableEmbeddedDocument[hash(obj)] = rv - return rv - - def isRedundantSVG(self, obj): - if not self.isSVG(obj) or AXObject.get_child_count(AXObject.get_parent(obj)) == 1: - return False - - rv = self._isRedundantSVG.get(hash(obj)) - if rv is not None: - return rv - - rv = False - parent = AXObject.get_parent(obj) - children = [x for x in AXObject.iter_children(parent, self.isSVG)] - if len(children) == AXObject.get_child_count(parent): - sortedChildren = sorted(children, key=functools.cmp_to_key(self.sizeComparison)) - if obj != sortedChildren[-1]: - objExtents = self.getExtents(obj, 0, -1) - largestExtents = self.getExtents(sortedChildren[-1], 0, -1) - rv = self.intersection(objExtents, largestExtents) == tuple(objExtents) - - self._isRedundantSVG[hash(obj)] = rv - return rv - - def isCustomImage(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isCustomImage.get(hash(obj)) - if rv is not None: - return rv - - rv = False - if self.isCustomElement(obj) and self.hasExplicitName(obj) \ - and AXUtilities.is_section(obj) \ - and AXObject.supports_text(obj) \ - and not re.search(r'[^\s\ufffc]', AXText.get_all_text(obj)): - for child in AXObject.iter_children(obj): - if not (AXUtilities.is_image_or_canvas(child) or self.isSVG(child)): - break - else: - rv = True - - self._isCustomImage[hash(obj)] = rv - return rv - - def isUselessImage(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isUselessImage.get(hash(obj)) - if rv is not None: - return rv - - rv = True - if not (AXUtilities.is_image_or_canvas(obj) or self.isSVG(obj)): - rv = False - if rv and (AXObject.get_name(obj) \ - or AXObject.get_description(obj) \ - or self.hasLongDesc(obj)): - rv = False - if rv and (self.isClickableElement(obj) and not self.hasExplicitName(obj)): - rv = False - if rv and AXUtilities.is_focusable(obj): - rv = False - if rv and AXUtilities.is_link(AXObject.get_parent(obj)) and not self.hasExplicitName(obj): - uri = self.uri(AXObject.get_parent(obj)) - if uri and not uri.startswith('javascript'): - rv = False - if rv and AXObject.supports_image(obj): - if AXObject.get_image_description(obj): - rv = False - elif not self.hasExplicitName(obj) and not self.isRedundantSVG(obj): - width, height = AXObject.get_image_size(obj) - if width > 25 and height > 25: - rv = False - if rv and AXObject.supports_text(obj): - rv = self.queryNonEmptyText(obj) is None - if rv and AXObject.get_child_count(obj): - for i in range(min(AXObject.get_child_count(obj), 50)): - if not self.isUselessImage(AXObject.get_child(obj, i)): - rv = False - break - - self._isUselessImage[hash(obj)] = rv - return rv - - def hasValidName(self, obj): - name = AXObject.get_name(obj) - if not name: - return False - - if len(name.split()) > 1: - return True - - parsed = urllib.parse.parse_qs(name) - if len(parsed) > 2: - tokens = ["WEB: name of", obj, "is suspected query string"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if len(name) == 1 and ord(name) in range(0xe000, 0xf8ff): - tokens = ["WEB: name of", obj, "is in unicode private use area"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - return True - - def isUselessEmptyElement(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isUselessEmptyElement.get(hash(obj)) - if rv is not None: - return rv - - roles = [Atspi.Role.PARAGRAPH, - Atspi.Role.SECTION, - Atspi.Role.STATIC, - Atspi.Role.TABLE_ROW] - role = AXObject.get_role(obj) - if role not in roles and not self.isAriaAlert(obj): - rv = False - elif AXUtilities.is_focusable(obj): - rv = False - elif AXUtilities.is_editable(obj): - rv = False - elif self.hasValidName(obj) \ - or AXObject.get_description(obj) or AXObject.get_child_count(obj): - rv = False - elif AXObject.supports_text(obj) and AXText.get_character_count(obj) \ - and AXText.get_all_text(obj) != AXObject.get_name(obj): - rv = False - elif AXObject.supports_action(obj): - names = AXObject.get_action_names(obj) - ignore = ["click-ancestor", "show-context-menu", "do-default"] - names = list(filter(lambda x: x not in ignore, names)) - rv = not names - else: - rv = True - - self._isUselessEmptyElement[hash(obj)] = rv - return rv - - def isParentOfNullChild(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isParentOfNullChild.get(hash(obj)) - if rv is not None: - return rv - - rv = False - childCount = AXObject.get_child_count(obj) - if childCount and AXObject.get_child(obj, 0) is None: - tokens = ["ERROR: ", obj, "reports", childCount, - "children, but AXObject.get_child(obj, 0) is None"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = True - - self._isParentOfNullChild[hash(obj)] = rv - return rv - - def hasExplicitName(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - attrs = self.objectAttributes(obj) - return attrs.get('explicit-name') == 'true' - - def hasLongDesc(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._hasLongDesc.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.has_action(obj, "showlongdesc") - self._hasLongDesc[hash(obj)] = rv - return rv - - def hasVisibleCaption(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().hasVisibleCaption(obj) - - if not (self.isFigure(obj) or AXObject.supports_table(obj)): - return False - - rv = self._hasVisibleCaption.get(hash(obj)) - if rv is not None: - return rv - - labels = self.labelsForObject(obj) - - def isVisibleCaption(x): - return AXUtilities.is_caption(x) and self.isShowingAndVisible(x) - - rv = bool(list(filter(isVisibleCaption, labels))) - self._hasVisibleCaption[hash(obj)] = rv - return rv - - def hasDetails(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().hasDetails(obj) - - rv = self._hasDetails.get(hash(obj)) - if rv is not None: - return rv - - rv = bool(AXUtilitiesRelation.get_details(obj)) - self._hasDetails[hash(obj)] = rv - return rv - - def detailsIn(self, obj): - if not self.hasDetails(obj): - return [] - - return AXUtilitiesRelation.get_details(obj) - - def isDetails(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().isDetails(obj) - - rv = self._isDetails.get(hash(obj)) - if rv is not None: - return rv - - rv = bool(AXUtilitiesRelation.get_is_details_for(obj)) - self._isDetails[hash(obj)] = rv - return rv - - def detailsFor(self, obj): - if not self.isDetails(obj): - return [] - - return AXUtilitiesRelation.get_is_details_for(obj) - - def popupType(self, obj): - if not (obj and self.inDocumentContent(obj)): - return 'false' - - attrs = self.objectAttributes(obj) - return attrs.get('haspopup', 'false').lower() - - def inferLabelFor(self, obj): - if not self.shouldInferLabelFor(obj): - return None, [] - - rv = self._inferredLabels.get(hash(obj)) - if rv is not None: - return rv - - rv = self._script.labelInference.infer(obj, False) - self._inferredLabels[hash(obj)] = rv - return rv - - def shouldInferLabelFor(self, obj): - if not self.inDocumentContent() or self.isWebAppDescendant(obj): - return False - - rv = self._shouldInferLabelFor.get(hash(obj)) - if rv and not self._script._lastCommandWasCaretNav: - return not self._script.inSayAll() - if rv is False: - return rv - - role = AXObject.get_role(obj) - name = AXObject.get_name(obj) - if name: - rv = False - elif self._getXMLRoles(obj): - rv = False - elif not rv: - roles = [Atspi.Role.CHECK_BOX, - Atspi.Role.COMBO_BOX, - Atspi.Role.ENTRY, - Atspi.Role.LIST_BOX, - Atspi.Role.PASSWORD_TEXT, - Atspi.Role.RADIO_BUTTON] - get_disp = getattr(AXUtilities, "get_displayed_label", lambda _o: None) - displayed = get_disp(obj) or self.displayedLabel(obj) - rv = role in roles and not displayed - - self._shouldInferLabelFor[hash(obj)] = rv - - # TODO - JD: This is private. - if self._script._lastCommandWasCaretNav \ - and role not in [Atspi.Role.RADIO_BUTTON, Atspi.Role.CHECK_BOX]: - return False - - return rv - - def displayedLabel(self, obj): - """Return the author-visible label, preferring toolkit-displayed text when available.""" - - if not (obj and self.inDocumentContent(obj)): - return super().displayedLabel(obj) - - rv = self._displayedLabelText.get(hash(obj)) - if rv is not None: - return rv - - # Prefer toolkit-provided displayed label (covers aria-labelledby/displayed text cases). - rv = getattr(AXUtilities, "get_displayed_label", lambda _o: None)(obj) or "" - if not rv: - labels = self.labelsForObject(obj) - strings = [AXObject.get_name(label) or self.displayedText(label) - for label in labels if label is not None] - rv = " ".join(strings) - - self._displayedLabelText[hash(obj)] = rv - return rv - - def labelsForObject(self, obj): - if not obj: - return [] - - rv = self._labelsForObject.get(hash(obj)) - if rv is not None: - return rv - - rv = super().labelsForObject(obj) - if not self.inDocumentContent(obj): - return rv - - self._labelsForObject[hash(obj)] = rv - return rv - - def isSpinnerEntry(self, obj): - if not self.inDocumentContent(obj): - return False - - if not AXUtilities.is_editable(obj): - return False - - if AXUtilities.is_spin_button(obj) or AXUtilities.is_spin_button(AXObject.get_parent(obj)): - return True - - return False - - def eventIsSpinnerNoise(self, event): - if not self.isSpinnerEntry(event.source): - return False - - if event.type.startswith("object:text-changed") \ - or event.type.startswith("object:text-selection-changed"): - if input_event_manager.get_manager().last_event_was_up_or_down(): - return True - - return False - - def treatEventAsSpinnerValueChange(self, event): - if event.type.startswith("object:text-caret-moved") and self.isSpinnerEntry(event.source): - if input_event_manager.get_manager().last_event_was_up_or_down(): - obj, offset = self.getCaretContext() - return event.source == obj - - return False - - def eventIsBrowserUINoise(self, event): - if self.inDocumentContent(event.source): - return False - - if event.type.startswith("object:text-") \ - and self.isSingleLineAutocompleteEntry(event.source): - return input_event_manager.get_manager().last_event_was_return() - if event.type.startswith("object:text-") or event.type.endswith("accessible-name"): - return AXUtilities.is_status_bar(event.source) or AXUtilities.is_label(event.source) - if event.type.startswith("object:children-changed"): - return True - - return False - - def eventIsAutocompleteNoise(self, event, documentFrame=None): - inContent = documentFrame or self.inDocumentContent(event.source) - if not inContent: - return False - - def isListBoxItem(x): - return AXUtilities.is_list_box(AXObject.get_parent(x)) - - def isMenuItem(x): - return AXUtilities.is_menu(AXObject.get_parent(x)) - - def isComboBoxItem(x): - return AXUtilities.is_combo_box(AXObject.get_parent(x)) - - if AXUtilities.is_editable(event.source) \ - and event.type.startswith("object:text-"): - obj, offset = self.getCaretContext(documentFrame) - if isListBoxItem(obj) or isMenuItem(obj): - return True - - if obj == event.source and isComboBoxItem(obj): - if input_event_manager.get_manager().last_event_was_up_or_down(): - return True - - return False - - def eventIsBrowserUIAutocompleteNoise(self, event): - if self.inDocumentContent(event.source): - return False - - if self._eventIsBrowserUIAutocompleteTextNoise(event): - return True - - return self._eventIsBrowserUIAutocompleteSelectionNoise(event) - - def _eventIsBrowserUIAutocompleteSelectionNoise(self, event): - selection = ["object:selection-changed", "object:state-changed:selected"] - if event.type not in selection: - return False - - if AXUtilities.is_menu_related(event.source) \ - and AXUtilities.is_entry(cthulhu_state.locusOfFocus) \ - and AXUtilities.is_focused(cthulhu_state.locusOfFocus): - if not input_event_manager.get_manager().last_event_was_up_or_down(): - return True - - return False - - def _eventIsBrowserUIAutocompleteTextNoise(self, event): - if not event.type.startswith("object:text-") \ - or not cthulhu_state.locusOfFocus \ - or not self.isSingleLineAutocompleteEntry(event.source): - return False - - if not AXUtilities.is_selectable(cthulhu_state.locusOfFocus): - return False - - if AXUtilities.is_menu_item_of_any_kind(cthulhu_state.locusOfFocus) \ - or AXUtilities.is_list_item(cthulhu_state.locusOfFocus): - return input_event_manager.get_manager().last_event_was_up_or_down() - - return False - - def eventIsBrowserUIPageSwitch(self, event): - selection = ["object:selection-changed", "object:state-changed:selected"] - if event.type not in selection: - return False - - if not AXUtilities.is_page_tab_list_related(event.source): - return False - - if self.inDocumentContent(event.source): - return False - - if not self.inDocumentContent(cthulhu_state.locusOfFocus): - return False - - return True - - def eventIsFromLocusOfFocusDocument(self, event): - if cthulhu_state.locusOfFocus == cthulhu_state.activeWindow: - focus = self.activeDocument() - source = self.getTopLevelDocumentForObject(event.source) - else: - focus = self.getDocumentForObject(cthulhu_state.locusOfFocus) - source = self.getDocumentForObject(event.source) - - tokens = ["WEB: Event doc:", source, ". Focus doc:", focus, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not (source and focus): - return False - - if source == focus: - return True - - if self.isZombie(focus) and not self.isZombie(source): - if self.activeDocument() == source: - msg = "WEB: Treating active doc as locusOfFocus doc" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - return False - - def eventIsIrrelevantSelectionChangedEvent(self, event): - if event.type != "object:selection-changed": - return False - if not cthulhu_state.locusOfFocus: - msg = "WEB: Selection changed event is relevant (no locusOfFocus)" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - if event.source == cthulhu_state.locusOfFocus: - msg = "WEB: Selection changed event is relevant (is locusOfFocus)" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - if AXObject.find_ancestor(cthulhu_state.locusOfFocus, lambda x: x == event.source): - msg = "WEB: Selection changed event is relevant (ancestor of locusOfFocus)" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - # There may be other roles where we need to do this. For now, solve the known one. - if AXUtilities.is_page_tab_list(event.source): - tokens = ["WEB: Selection changed event is irrelevant (unrelated", - AXObject.get_role_name(event.source), ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - msg = "WEB: Selection changed event is relevant (no reason found to ignore it)" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - def textEventIsForNonNavigableTextObject(self, event): - if not event.type.startswith("object:text-"): - return False - - return self._treatObjectAsWhole(event.source) - - def eventIsEOCAdded(self, event): - if not self.inDocumentContent(event.source): - return False - - if event.type.startswith("object:text-changed:insert") \ - and self.EMBEDDED_OBJECT_CHARACTER in event.any_data: - return not re.match(r"[^\s\ufffc]", event.any_data) - - return False - - def caretMovedOutsideActiveGrid(self, event, oldFocus=None): - if not (event and event.type.startswith("object:text-caret-moved")): - return False - - oldFocus = oldFocus or cthulhu_state.locusOfFocus - if not self.isGridDescendant(oldFocus): - return False - - return not self.isGridDescendant(event.source) - - def caretMovedToSamePageFragment(self, event, oldFocus=None): - if not (event and event.type.startswith("object:text-caret-moved")): - return False - - if AXUtilities.is_editable(event.source): - return False - - docURI = self.documentFrameURI() - fragment = urllib.parse.urlparse(docURI).fragment - if not fragment: - return False - - sourceID = self._getID(event.source) - if sourceID and fragment == sourceID: - return True - - oldFocus = oldFocus or cthulhu_state.locusOfFocus - if self.isLink(oldFocus): - link = oldFocus - else: - link = AXObject.find_ancestor(oldFocus, self.isLink) - - return link and self.uri(link) == docURI - - def isChildOfCurrentFragment(self, obj): - parseResult = urllib.parse.urlparse(self.documentFrameURI()) - if not parseResult.fragment: - return False - - def isSameFragment(x): - return self._getID(x) == parseResult.fragment - - return AXObject.find_ancestor(obj, isSameFragment) is not None - - def documentFragment(self, documentFrame): - parseResult = urllib.parse.urlparse(self.documentFrameURI(documentFrame)) - return parseResult.fragment - - def isContentEditableWithEmbeddedObjects(self, obj): - if not (obj and self.inDocumentContent(obj)): - return False - - rv = self._isContentEditableWithEmbeddedObjects.get(hash(obj)) - if rv is not None: - return rv - - rv = False - def hasTextBlockRole(x): - return AXObject.get_role(x) in self._textBlockElementRoles() \ - and not self.isFakePlaceholderForEntry(x) and not self.isStaticTextLeaf(x) - - if self._getTag(obj) in ["input", "textarea"]: - rv = False - elif AXUtilities.is_multi_line_entry(obj): - rv = AXObject.find_descendant(obj, hasTextBlockRole) - elif AXUtilities.is_editable(obj): - rv = hasTextBlockRole(obj) or self.isLink(obj) - elif not self.isDocument(obj): - document = self.getDocumentForObject(obj) - rv = self.isContentEditableWithEmbeddedObjects(document) - - self._isContentEditableWithEmbeddedObjects[hash(obj)] = rv - return rv - - def characterOffsetInParent(self, obj): - start, end, length = self._rangeInParentWithLength(obj) - return start - - def _rangeInParentWithLength(self, obj): - if not obj: - return -1, -1, 0 - - text = self.queryNonEmptyText(AXObject.get_parent(obj)) - if not text: - return -1, -1, 0 - - start, end = self.getHyperlinkRange(obj) - return start, end, AXText.get_character_count(AXObject.get_parent(obj)) - - def getError(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().getError(obj) - - if not AXUtilities.is_invalid_entry(obj): - return False - - try: - self._currentTextAttrs.pop(hash(obj)) - except Exception: - pass - - attrs, start, end = self.textAttributes(obj, 0, True) - error = attrs.get("invalid") - if error == "false": - return False - if error not in ["spelling", "grammar"]: - return True - - return error - - def _getErrorMessageContainer(self, obj): - if not (obj and self.inDocumentContent(obj)): - return None - - if not self.getError(obj): - return None - - errorMessages = AXUtilitiesRelation.get_error_message(obj) - if errorMessages: - return errorMessages[0] - - return None - - def getErrorMessage(self, obj): - return self.expandEOCs(self._getErrorMessageContainer(obj)) - - def isErrorForContents(self, obj, contents=[]): - if not self.isErrorMessage(obj): - return False - - for acc, start, end, string in contents: - if self._getErrorMessageContainer(acc) == obj: - return True - - return False - - def hasNoSize(self, obj): - if not (obj and self.inDocumentContent(obj)): - return super().hasNoSize(obj) - - rv = self._hasNoSize.get(hash(obj)) - if rv is not None: - return rv - - rv = super().hasNoSize(obj) - self._hasNoSize[hash(obj)] = rv - return rv - - def _canHaveCaretContext(self, obj): - rv = self._canHaveCaretContextDecision.get(hash(obj)) - if rv is not None: - return rv - - if obj is None: - return False - if AXObject.is_dead(obj): - msg = "WEB: Dead object cannot have caret context" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - if self.isZombie(obj): - tokens = ["WEB: Zombie object cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - startTime = time.time() - rv = None - if AXUtilities.is_focusable(obj): - if self.isHidden(obj): - tokens = ["WEB: Hidden object cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - else: - tokens = ["WEB: Focusable object can have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = True - elif AXUtilities.is_editable(obj): - if self.isHidden(obj): - tokens = ["WEB: Hidden object cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - else: - tokens = ["WEB: Editable object can have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = True - elif AXUtilities.is_landmark(obj): - tokens = ["WEB: Landmark can have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = True - elif AXUtilities.is_table_related(obj, True): - tokens = ["WEB: Table-related object can have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = True - elif self.isStaticTextLeaf(obj): - tokens = ["WEB: Static text leaf cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isUselessEmptyElement(obj): - tokens = ["WEB: Useless empty element cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isOffScreenLabel(obj): - tokens = ["WEB: Off-screen label cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isNonNavigablePopup(obj): - tokens = ["WEB: Non-navigable popup cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isUselessImage(obj): - tokens = ["WEB: Useless image cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isEmptyAnchor(obj): - tokens = ["WEB: Empty anchor cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isEmptyToolTip(obj): - tokens = ["WEB: Empty tool tip cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isParentOfNullChild(obj): - tokens = ["WEB: Parent of null child cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isPseudoElement(obj): - tokens = ["WEB: Pseudo element cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isFakePlaceholderForEntry(obj): - tokens = ["WEB: Fake placeholder for entry cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isNonInteractiveDescendantOfControl(obj): - tokens = ["WEB: Non interactive descendant of control cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.isHidden(obj): - # We try to do this check only if needed because getting object attributes is - # not as performant, and we cannot use the cached attribute because aria-hidden - # can change frequently depending on the app. - tokens = ["WEB: Hidden object cannot have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = False - elif self.hasNoSize(obj): - tokens = ["WEB: Allowing sizeless object to have caret context", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = True - else: - tokens = ["WEB: ", obj, f"can have caret context. ({time.time() - startTime:.4f}s)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = True - - self._canHaveCaretContextDecision[hash(obj)] = rv - msg = f"INFO: _canHaveCaretContext took {time.time() - startTime:.4f}s" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return rv - - def isPseudoElement(self, obj): - return False - - def searchForCaretContext(self, obj): - tokens = ["WEB: Searching for caret context in", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - container = obj - contextObj, contextOffset = None, -1 - while obj: - offset = AXText.get_caret_offset(obj) - if offset < 0: - tokens = ["WEB: Exception getting caret offset of", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - obj = None - continue - - contextObj, contextOffset = obj, offset - child = AXHypertext.find_child_at_offset(obj, offset) - if child: - obj = child - else: - break - - if contextObj and not self.isHidden(contextObj): - return self.findNextCaretInOrder(contextObj, max(-1, contextOffset - 1)) - - if self.isDocument(container): - return container, 0 - - return None, -1 - - def _getCaretContextViaLocusOfFocus(self): - obj = cthulhu_state.locusOfFocus - tokens = ["WEB: Getting caret context via locusOfFocus", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if not self.inDocumentContent(obj): - return None, -1 - - if AXObject.supports_text(obj): - offset = AXText.get_caret_offset(obj) - else: - offset = 0 - - if offset < 0: - offset = 0 - - return obj, offset - - def getCaretContext(self, documentFrame=None, getZombieReplicant=False, searchIfNeeded=True): - tokens = ["WEB: Getting caret context for", documentFrame] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not documentFrame or self.isZombie(documentFrame): - documentFrame = self.documentFrame() - tokens = ["WEB: Now getting caret context for", documentFrame] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not documentFrame: - if not searchIfNeeded: - msg = "WEB: Returning None, -1: No document and no search requested." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return None, -1 - - obj, offset = self._getCaretContextViaLocusOfFocus() - tokens = ["WEB: Returning", obj, ", ", offset, "(from locusOfFocus)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return obj, offset - - context = self._caretContexts.get(hash(AXObject.get_parent(documentFrame))) - if context is not None: - tokens = ["WEB: Cached context of", documentFrame, "is", context[0], ", ", context[1]] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - tokens = ["WEB: No cached context for", documentFrame, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - obj, offset = None, -1 - - if not context or not self.isTopLevelDocument(documentFrame): - if not searchIfNeeded: - msg = "WEB: Returning None, -1: No top-level document with context " \ - "and no search requested." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return None, -1 - obj, offset = self.searchForCaretContext(documentFrame) - elif not getZombieReplicant: - obj, offset = context - elif self.isZombie(context[0]): - msg = "WEB: Context is Zombie. Searching for replicant." - debug.printMessage(debug.LEVEL_INFO, msg, True) - obj, offset = self.findContextReplicant() - if obj: - caretObj, caretOffset = self.searchForCaretContext(AXObject.get_parent(obj)) - if caretObj and not self.isZombie(caretObj): - obj, offset = caretObj, caretOffset - else: - obj, offset = context - - tokens = ["WEB: Result context of", documentFrame, "is", obj, ", ", offset, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.setCaretContext(obj, offset, documentFrame) - return obj, offset - - def getCaretContextPathRoleAndName(self, documentFrame=None): - documentFrame = documentFrame or self.documentFrame() - if not documentFrame: - return [-1], None, None - - rv = self._contextPathsRolesAndNames.get(hash(AXObject.get_parent(documentFrame))) - if not rv: - return [-1], None, None - - return rv - - def clearCaretContext(self, documentFrame=None): - self.clearContentCache() - documentFrame = documentFrame or self.documentFrame() - if not documentFrame: - return - - parent = AXObject.get_parent(documentFrame) - self._caretContexts.pop(hash(parent), None) - self._priorContexts.pop(hash(parent), None) - - def handleEventFromContextReplicant(self, event, replicant): - if AXObject.is_dead(replicant): - msg = "WEB: Context replicant is dead." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if not AXObject.is_dead(cthulhu_state.locusOfFocus) \ - and not self.isSameObject(replicant, cthulhu_state.locusOfFocus, True, True): - tokens = ["WEB: Not event from context replicant. locusOfFocus", - cthulhu_state.locusOfFocus, "is not dead."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - path, role, name = self.getCaretContextPathRoleAndName() - replicantPath = AXObject.get_path(replicant) - if path != replicantPath: - tokens = ["WEB: Not event from context replicant. Path", path, - " != replicant path", replicantPath] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - replicantRole = AXObject.get_role(replicant) - if role != replicantRole: - tokens = ["WEB: Not event from context replicant. Role", role, - " != replicant role", replicantRole] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - notify = AXObject.get_name(replicant) != name - documentFrame = self.documentFrame() - obj, offset = self._caretContexts.get(hash(AXObject.get_parent(documentFrame))) - - tokens = ["WEB: Is event from context replicant. Notify:", notify] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - cthulhu.setLocusOfFocus(event, replicant, notify) - self.setCaretContext(replicant, offset, documentFrame) - return True - - def _handleEventForRemovedListBoxChild(self, event): - if AXUtilities.is_list_box(event.source): - listBox = event.source - else: - listBox = AXObject.find_ancestor(event.source, AXUtilities.is_list_box) - if listBox is None: - msg = "WEB: Could not find listbox to recover from removed child." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - tokens = ["WEB: Checking", listBox, "for focused child."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - AXObject.clear_cache(listBox) - item = AXUtilities.get_focused_object(listBox) - if not AXUtilities.is_list_item(item): - msg = "WEB: Could not find focused list item to recover from removed child." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - names = self._script.pointOfReference.get('names', {}) - oldName = names.get(hash(cthulhu_state.locusOfFocus)) - notify = AXObject.get_name(item) != oldName - - tokens = ["WEB: Recovered from removed child. New focus is: ", item, "0"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(event, item, notify) - self.setCaretContext(item, 0) - return True - - def handleEventForRemovedChild(self, event): - if event.any_data == cthulhu_state.locusOfFocus: - msg = "WEB: Removed child is locusOfFocus." - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif AXObject.find_ancestor(cthulhu_state.locusOfFocus, lambda x: x == event.any_data): - msg = "WEB: Removed child is ancestor of locusOfFocus." - debug.printMessage(debug.LEVEL_INFO, msg, True) - elif self.isSameObject(event.any_data, cthulhu_state.locusOfFocus, True, True): - msg = "WEB: Removed child appears to be replicant of locusOfFocus." - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - return False - - if event.detail1 == -1: - msg = "WEB: Event detail1 is useless." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if self._handleEventForRemovedListBoxChild(event): - return True - - obj, offset = None, -1 - notify = True - manager = input_event_manager.get_manager() - lastWasUp = manager.last_event_was_up() - lastWasDown = manager.last_event_was_down() - childCount = AXObject.get_child_count(event.source) - if lastWasUp: - if event.detail1 >= childCount: - msg = "WEB: Last child removed. Getting new location from end of parent." - debug.printMessage(debug.LEVEL_INFO, msg, True) - obj, offset = self.previousContext(event.source, -1) - elif 0 <= event.detail1 - 1 < childCount: - child = AXObject.get_child(event.source, event.detail1 - 1) - tokens = ["WEB: Getting new location from end of previous child", child, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - obj, offset = self.previousContext(child, -1) - else: - prevObj = self.findPreviousObject(event.source) - tokens = ["WEB: Getting new location from end of source's previous object", - prevObj, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - obj, offset = self.previousContext(prevObj, -1) - - elif lastWasDown: - if event.detail1 == 0: - msg = "WEB: First child removed. Getting new location from start of parent." - debug.printMessage(debug.LEVEL_INFO, msg, True) - obj, offset = self.nextContext(event.source, -1) - elif 0 < event.detail1 < childCount: - child = AXObject.get_child(event.source, event.detail1) - tokens = ["WEB: Getting new location from start of child", event.detail1, - child, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - obj, offset = self.nextContext(child, -1) - else: - nextObj = self.findNextObject(event.source) - tokens = ["WEB: Getting new location from start of source's next object", - nextObj, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - obj, offset = self.nextContext(nextObj, -1) - - else: - notify = False - AXObject.clear_cache(event.source) - obj, offset = self.searchForCaretContext(event.source) - if obj is None: - obj = AXUtilities.get_focused_object(event.source) - - # Risk "chattiness" if the locusOfFocus is dead and the object we've found is - # focused and has a different name than the last known focused object. - if obj and AXObject.is_dead(cthulhu_state.locusOfFocus) \ - and AXUtilities.is_focused(obj): - names = self._script.pointOfReference.get('names', {}) - oldName = names.get(hash(cthulhu_state.locusOfFocus)) - notify = AXObject.get_name(obj) != oldName - - if obj: - msg = "WEB: Setting locusOfFocus and context to: %s, %i" % (obj, offset) - cthulhu.setLocusOfFocus(event, obj, notify) - self.setCaretContext(obj, offset) - return True - - tokens = ["WEB: Unable to find context for child removed from", event.source] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - def findContextReplicant(self, documentFrame=None, matchRole=True, matchName=True): - path, oldRole, oldName = self.getCaretContextPathRoleAndName(documentFrame) - obj = self.get_objectFromPath(path) - if obj and matchRole: - if AXObject.get_role(obj) != oldRole: - obj = None - if obj and matchName: - if AXObject.get_name(obj) != oldName: - obj = None - if not obj: - return None, -1 - - obj, offset = self.findFirstCaretContext(obj, 0) - tokens = ["WEB: Context replicant is", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return obj, offset - - def getPriorContext(self, documentFrame=None): - if not documentFrame or self.isZombie(documentFrame): - documentFrame = self.documentFrame() - - if documentFrame: - context = self._priorContexts.get(hash(AXObject.get_parent(documentFrame))) - if context: - return context - - return None, -1 - - def _getPath(self, obj): - rv = self._paths.get(hash(obj)) - if rv is not None: - return rv - - rv = AXObject.get_path(obj) or [-1] - self._paths[hash(obj)] = rv - return rv - - def setCaretContext(self, obj=None, offset=-1, documentFrame=None): - documentFrame = documentFrame or self.documentFrame() - if not documentFrame: - return - - parent = AXObject.get_parent(documentFrame) - oldObj, oldOffset = self._caretContexts.get(hash(parent), (obj, offset)) - self._priorContexts[hash(parent)] = oldObj, oldOffset - self._caretContexts[hash(parent)] = obj, offset - - path = self._getPath(obj) - role = AXObject.get_role(obj) - name = AXObject.get_name(obj) - self._contextPathsRolesAndNames[hash(parent)] = path, role, name - - def findFirstCaretContext(self, obj, offset): - self._canHaveCaretContextDecision = {} - rv = self._findFirstCaretContext(obj, offset) - self._canHaveCaretContextDecision = {} - return rv - - def _findFirstCaretContext(self, obj, offset): - tokens = ["WEB: Looking for first caret context for", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - role = AXObject.get_role(obj) - lookInChild = [Atspi.Role.LIST, - Atspi.Role.INTERNAL_FRAME, - Atspi.Role.TABLE, - Atspi.Role.TABLE_ROW] - if role in lookInChild \ - and AXObject.get_child_count(obj) and not self.treatAsDiv(obj, offset): - firstChild = AXObject.get_child(obj, 0) - tokens = ["WEB: Will look in child", firstChild, "for first caret context"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return self._findFirstCaretContext(firstChild, 0) - - text = self.queryNonEmptyText(obj) - if not text and self._canHaveCaretContext(obj): - tokens = ["WEB: First caret context for non-text context is", obj, "0"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return obj, 0 - - if text: - char_count = AXText.get_character_count(obj) - else: - char_count = 0 - - if text and offset >= char_count: - if self.isContentEditableWithEmbeddedObjects(obj) and self.lastInputEventWasCharNav(): - nextObj, nextOffset = self.nextContext(obj, char_count) - if not nextObj: - tokens = ["WEB: No next object found at end of contenteditable", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - elif not self.isContentEditableWithEmbeddedObjects(nextObj): - tokens = ["WEB: Next object", nextObj, - "found at end of contenteditable", obj, "is not editable"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - tokens = ["WEB: First caret context at end of contenteditable", obj, - "is next context", nextObj, ", ", nextOffset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return nextObj, nextOffset - - tokens = ["WEB: First caret context at end of", obj, ", ", offset, "is", - obj, ", ", char_count] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return obj, char_count - - offset = max(0, offset) - if text: - allText = AXText.get_all_text(obj) - if allText[offset] != self.EMBEDDED_OBJECT_CHARACTER or role == Atspi.Role.ENTRY: - msg = "WEB: First caret context is unchanged" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return obj, offset - - # Descending an element that we're treating as whole can lead to looping/getting stuck. - if self.elementLinesAreSingleChars(obj): - msg = "WEB: EOC in single-char-lines element. Returning context unchanged." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return obj, offset - - child = AXHypertext.find_child_at_offset(obj, offset) - if not child: - msg = "WEB: Child at offset is null. Returning context unchanged." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return obj, offset - - if self.isDocument(obj): - while self.isUselessEmptyElement(child): - tokens = ["WEB: Child", child, "of", obj, "at offset", offset, "cannot be context."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - offset += 1 - child = AXHypertext.find_child_at_offset(obj, offset) - - if self.isListItemMarker(child): - tokens = ["WEB: First caret context is next offset in", obj, ":", - offset + 1, "(skipping list item marker child)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return obj, offset + 1 - - if self.isEmptyAnchor(child): - nextObj, nextOffset = self.nextContext(obj, offset) - if nextObj: - tokens = ["WEB: First caret context at end of empty anchor", obj, - "is next context", nextObj, ", ", nextOffset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return nextObj, nextOffset - - if not self._canHaveCaretContext(child): - tokens = ["WEB: Child", child, "cannot be context. Returning", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return obj, offset - - tokens = ["WEB: Looking in child", child, "for first caret context for", obj, ", ", offset] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return self._findFirstCaretContext(child, 0) - - def findNextCaretInOrder(self, obj=None, offset=-1): - startTime = time.time() - rv = self._findNextCaretInOrder(obj, offset) - tokens = ["WEB: Next caret in order for", obj, ", ", offset, ":", - rv[0], ", ", rv[1], f"({time.time() - startTime:.4f}s)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - def _findNextCaretInOrder(self, obj=None, offset=-1): - if not obj: - obj, offset = self.getCaretContext() - - if not obj or not self.inDocumentContent(obj): - return None, -1 - - if self._canHaveCaretContext(obj): - text = self.queryNonEmptyText(obj) - if text: - allText = AXText.get_all_text(obj) - for i in range(offset + 1, len(allText)): - child = AXHypertext.find_child_at_offset(obj, i) - if child and allText[i] != self.EMBEDDED_OBJECT_CHARACTER: - tokens = ["ERROR: Child", child, "found at offset with char '", - allText[i].replace("\n", "\\n"), "'"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if offset == self.characterOffsetInParent(child): - tokens = ["WEB: Handling error by returning", obj, i] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return obj, i - if self._canHaveCaretContext(child): - if self._treatObjectAsWhole(child, -1): - return child, 0 - return self._findNextCaretInOrder(child, -1) - if allText[i] not in ( - self.EMBEDDED_OBJECT_CHARACTER, self.ZERO_WIDTH_NO_BREAK_SPACE): - return obj, i - elif AXObject.get_child_count(obj) and not self._treatObjectAsWhole(obj, offset): - return self._findNextCaretInOrder(AXObject.get_child(obj, 0), -1) - elif offset < 0 and not self.isTextBlockElement(obj): - return obj, 0 - - # If we're here, start looking up the tree, up to the document. - if self.isTopLevelDocument(obj): - return None, -1 - - while obj and AXObject.get_parent(obj): - if self.isDetachedDocument(AXObject.get_parent(obj)): - obj = self.iframeForDetachedDocument(AXObject.get_parent(obj)) - continue - - parent = AXObject.get_parent(obj) - if self.isZombie(parent): - msg = "WEB: Finding next caret in order. Parent is Zombie." - debug.printMessage(debug.LEVEL_INFO, msg, True) - replicant = self.findReplicant(self.documentFrame(), parent) - if replicant and not self.isZombie(replicant): - parent = replicant - elif AXObject.get_parent(parent): - obj = parent - continue - else: - break - - start, end, length = self._rangeInParentWithLength(obj) - if start + 1 == end and 0 <= start < end <= length: - return self._findNextCaretInOrder(parent, start) - - child = AXObject.get_next_sibling(obj) - if child: - return self._findNextCaretInOrder(child, -1) - obj = parent - - return None, -1 - - def findPreviousCaretInOrder(self, obj=None, offset=-1): - startTime = time.time() - rv = self._findPreviousCaretInOrder(obj, offset) - tokens = ["WEB: Previous caret in order for", obj, ", ", offset, ":", - rv[0], ", ", rv[1], f"({time.time() - startTime:.4f}s)"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return rv - - def _findPreviousCaretInOrder(self, obj=None, offset=-1): - if not obj: - obj, offset = self.getCaretContext() - - if not obj or not self.inDocumentContent(obj): - return None, -1 - - if self._canHaveCaretContext(obj): - text = self.queryNonEmptyText(obj) - if text: - allText = AXText.get_all_text(obj) - if offset == -1 or offset > len(allText): - offset = len(allText) - for i in range(offset - 1, -1, -1): - child = AXHypertext.find_child_at_offset(obj, i) - if child and allText[i] != self.EMBEDDED_OBJECT_CHARACTER: - tokens = ["ERROR: Child", child, "found at offset with char '", - allText[i].replace("\n", "\\n"), "'"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if self._canHaveCaretContext(child): - if self._treatObjectAsWhole(child, -1): - return child, 0 - return self._findPreviousCaretInOrder(child, -1) - if allText[i] not in ( - self.EMBEDDED_OBJECT_CHARACTER, self.ZERO_WIDTH_NO_BREAK_SPACE): - return obj, i - elif AXObject.get_child_count(obj) and not self._treatObjectAsWhole(obj, offset): - return self._findPreviousCaretInOrder( - AXObject.get_child(obj, AXObject.get_child_count(obj) - 1), -1) - elif offset < 0 and not self.isTextBlockElement(obj): - return obj, 0 - - # If we're here, start looking up the tree, up to the document. - if self.isTopLevelDocument(obj): - return None, -1 - - while obj and AXObject.get_parent(obj): - if self.isDetachedDocument(AXObject.get_parent(obj)): - obj = self.iframeForDetachedDocument(AXObject.get_parent(obj)) - continue - - parent = AXObject.get_parent(obj) - if self.isZombie(parent): - msg = "WEB: Finding previous caret in order. Parent is Zombie." - debug.printMessage(debug.LEVEL_INFO, msg, True) - replicant = self.findReplicant(self.documentFrame(), parent) - if replicant and not self.isZombie(replicant): - parent = replicant - elif AXObject.get_parent(parent): - obj = parent - continue - else: - break - - start, end, length = self._rangeInParentWithLength(obj) - if start + 1 == end and 0 <= start < end <= length: - return self._findPreviousCaretInOrder(parent, start) - - child = AXObject.get_previous_sibling(obj) - if child: - return self._findPreviousCaretInOrder(child, -1) - obj = parent - - return None, -1 - - def lastQueuedLiveRegion(self): - if self._lastQueuedLiveRegionEvent is None: - return None - - if self._lastQueuedLiveRegionEvent.type.startswith("object:text-changed:insert"): - return self._lastQueuedLiveRegionEvent.source - - if self._lastQueuedLiveRegionEvent.type.startswith("object:children-changed:add"): - return self._lastQueuedLiveRegionEvent.any_data - - return None - - def handleAsLiveRegion(self, event): - if not cthulhu.cthulhuApp.settingsManager.getSetting('inferLiveRegions'): - return False - - if not self.isLiveRegion(event.source): - return False - - if not cthulhu.cthulhuApp.settingsManager.getSetting('presentLiveRegionFromInactiveTab') \ - and self.getTopLevelDocumentForObject(event.source) != self.activeDocument(): - msg = "WEB: Live region source is not in active tab." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if event.type.startswith("object:text-changed:insert"): - alert = AXObject.find_ancestor(event.source, self.isAriaAlert) - if alert and AXUtilities.get_focused_object(alert) == event.source: - msg = "WEB: Focused source will be presented as part of alert" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if self._lastQueuedLiveRegionEvent \ - and self._lastQueuedLiveRegionEvent.type == event.type \ - and self._lastQueuedLiveRegionEvent.any_data == event.any_data: - msg = "WEB: Event is believed to be duplicate message" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - if isinstance(event.any_data, Atspi.Accessible): - if AXUtilities.is_unknown_or_redundant(event.any_data) \ - and self._getTag(event.any_data) in ["", None, "br"]: - tokens = ["WEB: Child has unknown role and no tag", event.any_data] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if self.lastQueuedLiveRegion() == event.any_data \ - and self._lastQueuedLiveRegionEvent.type != event.type: - msg = "WEB: Event is believed to be redundant live region notification" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - self._lastQueuedLiveRegionEvent = event - return True - - def getPageObjectCount(self, obj): - result = {'landmarks': 0, - 'headings': 0, - 'forms': 0, - 'tables': 0, - 'visitedLinks': 0, - 'unvisitedLinks': 0} - - docframe = self.documentFrame(obj) - tokens = ["WEB: Document frame for", obj, "is", docframe] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - roles = [Atspi.Role.HEADING, - Atspi.Role.LINK, - Atspi.Role.TABLE, - Atspi.Role.FORM, - Atspi.Role.LANDMARK] - - rule = AXCollection.create_match_rule(roles=roles) - matches = AXCollection.get_all_matches(docframe, rule) - - for obj in matches: - if AXUtilities.is_heading(obj): - result['headings'] += 1 - elif AXUtilities.is_form(obj): - result['forms'] += 1 - elif AXUtilities.is_table(obj) and not self.isLayoutOnly(obj): - result['tables'] += 1 - elif AXUtilities.is_link(obj): - if self.isLink(obj): - if AXUtilities.is_visited(obj): - result['visitedLinks'] += 1 - else: - result['unvisitedLinks'] += 1 - elif self.isLandmark(obj): - result['landmarks'] += 1 - - return result - - def getPageSummary(self, obj, onlyIfFound=True): - result = [] - counts = self.getPageObjectCount(obj) - result.append(messages.landmarkCount(counts.get('landmarks', 0), onlyIfFound)) - result.append(messages.headingCount(counts.get('headings', 0), onlyIfFound)) - result.append(messages.formCount(counts.get('forms', 0), onlyIfFound)) - result.append(messages.tableCount(counts.get('tables', 0), onlyIfFound)) - result.append(messages.visitedLinkCount(counts.get('visitedLinks', 0), onlyIfFound)) - result.append(messages.unvisitedLinkCount(counts.get('unvisitedLinks', 0), onlyIfFound)) - result = list(filter(lambda x: x, result)) - if not result: - return "" - - return messages.PAGE_SUMMARY_PREFIX % ", ".join(result) - - def preferDescriptionOverName(self, obj): - if not self.inDocumentContent(obj): - return super().preferDescriptionOverName(obj) - - rv = self._preferDescriptionOverName.get(hash(obj)) - if rv is not None: - return rv - - name = AXObject.get_name(obj) - if len(name) == 1 and ord(name) in range(0xe000, 0xf8ff): - tokens = ["WEB: name of", obj, "is in unicode private use area"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = True - elif AXObject.get_description(obj): - rv = AXUtilities.is_push_button(obj) and len(name) == 1 - else: - rv = False - - self._preferDescriptionOverName[hash(obj)] = rv - return rv - - def _getCtrlShiftSelectionsStrings(self): - """Hacky and to-be-obsoleted method.""" - return [messages.LINE_SELECTED_DOWN, - messages.LINE_UNSELECTED_DOWN, - messages.LINE_SELECTED_UP, - messages.LINE_UNSELECTED_UP] - - def lastInputEventWasCopy(self): - if super().lastInputEventWasCopy(): - return True - - if not self.inDocumentContent(): - return False - - if not self.topLevelObjectIsActiveAndCurrent(): - return False - - if AXObject.supports_action(cthulhu_state.locusOfFocus): - tokens = ["WEB: Treating", cthulhu_state.locusOfFocus, "as source of copy"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - return False diff --git a/src/cthulhu/scripts/web/sound_generator.py b/src/cthulhu/scripts/web/sound_generator.py deleted file mode 100644 index ed2213e..0000000 --- a/src/cthulhu/scripts/web/sound_generator.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Utilities for obtaining sounds to be presented for objects.""" - -__id__ = "$Id:$" -__version__ = "$Revision:$" -__date__ = "$Date:$" -__copyright__ = "Copyright (c) 2016 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu import cthulhu -from cthulhu import settings_manager -from cthulhu import sound_generator - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - - -class SoundGenerator(sound_generator.SoundGenerator): - - def __init__(self, script): - super().__init__(script) - - def _generateClickable(self, obj, **args): - """Returns an array of sounds indicating obj is clickable.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - if not self._script.utilities.inDocumentContent(obj): - return [] - - if not args.get('mode', None): - args['mode'] = self._mode - - args['stringType'] = 'clickable' - if self._script.utilities.isClickableElement(obj): - filenames = [self._script.formatting.getString(**args)] - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateHasLongDesc(self, obj, **args): - """Returns an array of sounds indicating obj has a longdesc.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - if not self._script.utilities.inDocumentContent(obj): - return [] - - if not args.get('mode', None): - args['mode'] = self._mode - - args['stringType'] = 'haslongdesc' - if self._script.utilities.hasLongDesc(obj): - filenames = [self._script.formatting.getString(**args)] - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def generateSound(self, obj, **args): - """Returns an array of sounds for the complete presentation of obj.""" - - if not self._script.utilities.inDocumentContent(obj): - return super().generateSound(obj, **args) - - result = [] - if args.get('formatType') == 'detailedWhereAmI': - oldRole = self._overrideRole('default', args) - elif self._script.utilities.isLink(obj): - oldRole = self._overrideRole(Atspi.Role.LINK, args) - elif self._script.utilities.treatAsDiv(obj): - oldRole = self._overrideRole(Atspi.Role.SECTION, args) - else: - oldRole = self._overrideRole(self._getAlternativeRole(obj, **args), args) - - result.extend(super().generateSound(obj, **args)) - result = list(filter(lambda x: x, result)) - self._restoreRole(oldRole, args) - - return result - - def generateContents(self, contents, **args): - """Returns an array of an array of sounds for the contents.""" - - if not len(contents): - return [] - - result = [] - contents = self._script.utilities.filterContentsForPresentation(contents, False) - for i, content in enumerate(contents): - obj, start, end, string = content - icon = self.generateSound( - obj, startOffset=start, endOffset=end, string=string, - index=i, total=len(contents), **args) - result.append(icon) - - return result diff --git a/src/cthulhu/scripts/web/speech_generator.py b/src/cthulhu/scripts/web/speech_generator.py deleted file mode 100644 index c715cf2..0000000 --- a/src/cthulhu/scripts/web/speech_generator.py +++ /dev/null @@ -1,898 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2011 Cthulhu Team" \ - "Copyright (c) 2011-2015 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi -import urllib - -from cthulhu import cthulhu -from cthulhu import debug -from cthulhu import input_event_manager -from cthulhu import messages -from cthulhu import object_properties -from cthulhu import role_keys -from cthulhu import cthulhu_state -from cthulhu import settings -from cthulhu import settings_manager -from cthulhu import sound_theme_manager -from cthulhu import speech_generator -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - - -class SpeechGenerator(speech_generator.SpeechGenerator): - - def __init__(self, script): - super().__init__(script) - - def _generateOldAncestors(self, obj, **args): - if args.get('index', 0) > 0: - return [] - - priorObj = args.get('priorObj') - if self._script.utilities.isInlineIframeDescendant(priorObj): - return [] - - return super()._generateOldAncestors(obj, **args) - - def _generateNewAncestors(self, obj, **args): - if args.get('index', 0) > 0 \ - and not self._script.utilities.isListDescendant(obj): - return [] - - if self._script.utilities.isInlineIframeDescendant(obj): - return [] - - return super()._generateNewAncestors(obj, **args) - - def _generateAncestors(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateAncestors(obj, **args) - - result = [] - priorObj = args.get('priorObj') - if priorObj and self._script.utilities.inDocumentContent(priorObj): - priorDoc = self._script.utilities.getDocumentForObject(priorObj) - doc = self._script.utilities.getDocumentForObject(obj) - if priorDoc != doc and not self._script.utilities.getDocumentForObject(doc): - result = [super()._generateName(doc)] - - if not self._script.utilities.getTable(obj) \ - and (self._script.utilities.isLink(obj) \ - or self._script.utilities.isLandmark(obj) \ - or self._script.utilities.isMath(obj) \ - or AXUtilities.is_tool_tip(obj) \ - or AXUtilities.is_status_bar(obj)): - return result - - if self._script.utilities.isItemForEditableComboBox(obj, priorObj): - return result - - args['stopAtRoles'] = [Atspi.Role.DOCUMENT_WEB, - Atspi.Role.EMBEDDED, - Atspi.Role.INTERNAL_FRAME, - Atspi.Role.MATH, - Atspi.Role.MENU_BAR] - args['skipRoles'] = [Atspi.Role.PARAGRAPH, - Atspi.Role.HEADING, - Atspi.Role.LABEL, - Atspi.Role.LINK, - Atspi.Role.LIST_ITEM, - Atspi.Role.TEXT] - args['stopAfterRoles'] = [Atspi.Role.TOOL_BAR] - - if self._script.utilities.isEditableDescendantOfComboBox(obj): - args['skipRoles'].append(Atspi.Role.COMBO_BOX) - - result.extend(super()._generateAncestors(obj, **args)) - - return result - - def _generateAllTextSelection(self, obj, **args): - if self._script.utilities.isZombie(obj) \ - or obj != cthulhu_state.locusOfFocus: - return [] - - # TODO - JD: These (and the default script's) need to - # call utility methods rather than generate it. - return super()._generateAllTextSelection(obj, **args) - - def _generateAnyTextSelection(self, obj, **args): - if self._script.utilities.isZombie(obj) \ - or obj != cthulhu_state.locusOfFocus: - return [] - - # TODO - JD: These (and the default script's) need to - # call utility methods rather than generate it. - return super()._generateAnyTextSelection(obj, **args) - - def _generateHasPopup(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not self._script.utilities.inDocumentContent(obj): - return [] - - result = [] - popupType = self._script.utilities.popupType(obj) - if popupType == 'dialog': - result = [messages.HAS_POPUP_DIALOG] - elif popupType == 'grid': - result = [messages.HAS_POPUP_GRID] - elif popupType == 'listbox': - result = [messages.HAS_POPUP_LISTBOX] - elif popupType in ('menu', 'true'): - result = [messages.HAS_POPUP_MENU] - elif popupType == 'tree': - result = [messages.HAS_POPUP_TREE] - - if result: - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - return result - - def _generateClickable(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not self._script.utilities.inDocumentContent(obj): - return [] - - if self._script.utilities.isFeedArticle(obj): - return [] - - if not args.get('mode', None): - args['mode'] = self._mode - - args['stringType'] = 'clickable' - if self._script.utilities.isClickableElement(obj): - result = [self._script.formatting.getString(**args)] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - return [] - - def _generateDescription(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not self._script.utilities.inDocumentContent(obj): - return super()._generateDescription(obj, **args) - - if self._script.utilities.isZombie(obj): - return [] - - if self._script.utilities.preferDescriptionOverName(obj): - return [] - - role = args.get('role', AXObject.get_role(obj)) - if obj != cthulhu_state.locusOfFocus: - if role in [Atspi.Role.ALERT, Atspi.Role.DIALOG]: - return super()._generateDescription(obj, **args) - if not args.get('inMouseReview'): - return [] - - formatType = args.get('formatType') - if formatType == 'basicWhereAmI' and self._script.utilities.isLiveRegion(obj): - return self._script.liveRegionManager.generateLiveRegionDescription(obj, **args) - - if role == Atspi.Role.TEXT and formatType != 'basicWhereAmI': - return [] - - # TODO - JD: This is private. - if role == Atspi.Role.LINK and self._script._lastCommandWasCaretNav: - return [] - - return super()._generateDescription(obj, **args) - - def _generateHasLongDesc(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not self._script.utilities.inDocumentContent(obj): - return [] - - if not args.get('mode', None): - args['mode'] = self._mode - - args['stringType'] = 'haslongdesc' - if self._script.utilities.hasLongDesc(obj): - result = [self._script.formatting.getString(**args)] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - return [] - - def _generateHasDetails(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not self._script.utilities.inDocumentContent(obj): - return super()._generateHasDetails(obj, **args) - - objs = self._script.utilities.detailsIn(obj) - if not objs: - return [] - - def objString(x): - return str.strip(f"{AXObject.get_name(x)} {self.getLocalizedRoleName(x)}") - - toPresent = ", ".join(set(map(objString, objs))) - - args['stringType'] = 'hasdetails' - result = [self._script.formatting.getString(**args) % toPresent] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - def _generateAllDetails(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - objs = self._script.utilities.detailsIn(obj) - if not objs: - container = AXObject.find_ancestor(obj, self._script.utilities.hasDetails) - objs = self._script.utilities.detailsIn(container) - - if not objs: - return [] - - args['stringType'] = 'hasdetails' - result = [self._script.formatting.getString(**args) % ""] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - result = [] - for o in objs: - result.append(self.getLocalizedRoleName(o)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - string = self._script.utilities.expandEOCs(o) - if not string.strip(): - continue - - result.append(string) - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - result.extend(self._generatePause(o)) - - return result - - def _generateDetailsFor(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not self._script.utilities.inDocumentContent(obj): - return super()._generateDetailsFor(obj, **args) - - objs = self._script.utilities.detailsFor(obj) - if not objs: - return [] - - if args.get('leaving'): - return [] - - manager = input_event_manager.get_manager() - if (manager.last_event_was_forward_caret_navigation() or self._script.inSayAll()) \ - and args.get('startOffset'): - return [] - if manager.last_event_was_backward_caret_navigation(): - if self._script.utilities.treatAsTextObject(obj) \ - and args.get('endOffset') not in [None, AXText.get_character_count(obj)]: - return [] - - result = [] - objArgs = {'stringType': 'detailsfor', 'mode': args.get('mode')} - for o in objs: - string = self._script.utilities.displayedText(o) or self.getLocalizedRoleName(o) - words = string.split() - if len(words) > 5: - words = words[0:5] + ['...'] - - result.append(self._script.formatting.getString(**objArgs) % " ".join(words)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - result.extend(self._generatePause(o, **objArgs)) - - return result - - def _generateLabelOrName(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateLabelOrName(obj, **args) - - if self._script.utilities.isTextBlockElement(obj) \ - and not self._script.utilities.isLandmark(obj) \ - and not self._script.utilities.isDocument(obj) \ - and not self._script.utilities.isDPub(obj) \ - and not self._script.utilities.isContentSuggestion(obj): - return [] - - priorObj = args.get("priorObj") - if obj == priorObj: - return [] - - if priorObj and priorObj in self._script.utilities.labelsForObject(obj): - return [] - - objName = AXObject.get_name(obj) - descendant = args.get("ancestorOf") - if descendant and priorObj and objName and objName == AXObject.get_name(priorObj): - tokens = ["WEB: ", descendant, "'s ancestor", obj, "has same name as priorObj", - priorObj, ". Not generating labelOrName."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.MENU and self._script.utilities.isPopupMenuForCurrentItem(obj): - tokens = ["WEB: ", obj, "is popup menu for current item."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - if self._script.utilities.isContentEditableWithEmbeddedObjects(obj) \ - or self._script.utilities.isDocument(obj): - if input_event_manager.get_manager().last_event_was_caret_navigation(): - # Still generate the label if we just entered this object from outside - # (e.g. down arrow from message list into message entry in Discord). - enteredFromOutside = priorObj is not None \ - and priorObj != obj \ - and not AXObject.find_ancestor(priorObj, lambda x: x == obj) - if not enteredFromOutside: - return [] - - if AXUtilities.is_page_tab(priorObj) and AXObject.get_name(priorObj) == objName: - return [] - - if objName: - name = objName - if not self._script.utilities.hasExplicitName(obj): - name = name.strip() - - if self._script.utilities.shouldVerbalizeAllPunctuation(obj): - name = self._script.utilities.verbalizeAllPunctuation(name) - - name = self._stripRoleFromNameIfNeeded(obj, name, role) - result = [name] - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - return result - - if AXUtilities.is_check_box(obj): - gridCell = AXObject.find_ancestor(obj, self._script.utilities.isGridCell) - if gridCell: - return super()._generateLabelOrName(gridCell, **args) - - return super()._generateLabelOrName(obj, **args) - - def _generateName(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateName(obj, **args) - - if self._script.utilities.isTextBlockElement(obj) \ - and not self._script.utilities.isLandmark(obj) \ - and not self._script.utilities.isDPub(obj) \ - and not args.get('inFlatReview'): - return [] - - if self._script.utilities.hasVisibleCaption(obj): - return [] - - if self._script.utilities.isFigure(obj) and args.get('ancestorOf'): - caption = args.get('ancestorOf') - if not AXUtilities.is_caption(caption): - caption = AXObject.find_ancestor(caption, AXUtilities.is_caption) - if caption and hash(obj) in self._script.utilities.labelTargets(caption): - return [] - - role = args.get('role', AXObject.get_role(obj)) - - # TODO - JD: Once the formatting strings are vastly cleaned up - # or simply removed, hacks like this won't be needed. - if role in [Atspi.Role.COMBO_BOX, Atspi.Role.SPIN_BUTTON]: - return super()._generateName(obj, **args) - - if AXObject.get_name(obj): - if self._script.utilities.preferDescriptionOverName(obj): - result = [AXObject.get_description(obj)] - elif self._script.utilities.isLink(obj) \ - and not self._script.utilities.hasExplicitName(obj): - return [] - else: - name = AXObject.get_name(obj) - if not self._script.utilities.hasExplicitName(obj): - name = name.strip() - name = self._stripRoleFromNameIfNeeded(obj, name, role) - result = [name] - - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - return result - - return super()._generateName(obj, **args) - - def _generateLabel(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateLabel(obj, **args) - - if self._script.utilities.isTextBlockElement(obj): - return [] - - label, objects = self._script.utilities.inferLabelFor(obj) - if label: - role = args.get('role', AXObject.get_role(obj)) - label = self._stripRoleFromNameIfNeeded(obj, label, role) - result = [label] - result.extend(self.voice(speech_generator.DEFAULT, obj=obj, **args)) - return result - - return super()._generateLabel(obj, **args) - - def _generateNewNodeLevel(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if self._script.utilities.isTextBlockElement(obj) \ - or self._script.utilities.isLink(obj): - return [] - - return super()._generateNewNodeLevel(obj, **args) - - def _generateLeaving(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not args.get('leaving'): - return [] - - if self._script.utilities.inDocumentContent(obj) \ - and not self._script.utilities.inDocumentContent(cthulhu_state.locusOfFocus): - result = [''] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - return super()._generateLeaving(obj, **args) - - def _generateNewRadioButtonGroup(self, obj, **args): - # TODO - JD: The default speech generator's method determines group membership - # via the member-of relation. We cannot count on that here. Plus, radio buttons - # on the web typically live in a group which is labelled. Thus the new-ancestor - # presentation accomplishes the same thing. Unless this can be further sorted out, - # try to filter out some of the noise.... - return [] - - def _generateNumberOfChildren(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText') \ - or cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') == settings.VERBOSITY_LEVEL_BRIEF: - return [] - - # We handle things even for non-document content due to issues in - # other toolkits (e.g. exposing list items to us that are not - # exposed to sighted users) - roles = [Atspi.Role.DESCRIPTION_LIST, - Atspi.Role.LIST, - Atspi.Role.LIST_BOX, - role_keys.ROLE_FEED] - role = args.get('role', AXObject.get_role(obj)) - if role not in roles: - return super()._generateNumberOfChildren(obj, **args) - - setsize = self._script.utilities.getSetSize(AXObject.get_child(obj, 0)) - if setsize is None: - children = [] - if self._script.utilities.isDescriptionList(obj): - children = self._script.utilities.descriptionListTerms(obj) - elif role in [Atspi.Role.LIST, Atspi.Role.LIST_BOX]: - children = [x for x in AXObject.iter_children(obj, AXUtilities.is_list_item)] - setsize = len(children) - - if not setsize: - return [] - - if self._script.utilities.isDescriptionList(obj): - result = [messages.descriptionListTermCount(setsize)] - elif role == role_keys.ROLE_FEED: - result = [messages.feedArticleCount(setsize)] - else: - result = [messages.listItemCount(setsize)] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - # TODO - JD: Yet another dumb generator method we should kill. - def _generateTextRole(self, obj, **args): - return self._generateRoleName(obj, **args) - - def getLocalizedRoleName(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super().getLocalizedRoleName(obj, **args) - - roledescription = self._script.utilities.getRoleDescription(obj) - if roledescription: - return roledescription - - return super().getLocalizedRoleName(obj, **args) - - def _generateRealActiveDescendantDisplayedText(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateRealActiveDescendantDisplayedText(obj, **args) - - rad = self._script.utilities.realActiveDescendant(obj) - return self._generateDisplayedText(rad, **args) - - def _generateRoleName(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not self._script.utilities.inDocumentContent(obj): - return super()._generateRoleName(obj, **args) - - if obj == args.get('priorObj'): - return [] - - result = [] - roledescription = self._script.utilities.getRoleDescription(obj) - if roledescription: - result = [roledescription] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - # aria-roledescription replaces the standard role name, so return - # early to avoid announcing both (e.g. "Message" + "article"). - return result - - role = args.get('role', AXObject.get_role(obj)) - roleSoundPresentation = cthulhu.cthulhuApp.settingsManager.getSetting('roleSoundPresentation') - soundEnabled = cthulhu.cthulhuApp.settingsManager.getSetting('enableSound') - roleSoundIcon = None - if roleSoundPresentation != settings.ROLE_SOUND_PRESENTATION_SPEECH_ONLY \ - and soundEnabled: - roleSoundIcon = self._getRoleSoundIcon(obj, role) - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY \ - and soundEnabled: - # Stateful controls present their role via state sounds; suppress - # spoken role names here even if no dedicated role icon exists. - if AXUtilities.is_check_box(obj) \ - or AXUtilities.is_check_menu_item(obj) \ - or AXUtilities.is_radio_button(obj) \ - or AXUtilities.is_radio_menu_item(obj) \ - or AXUtilities.is_toggle_button(obj) \ - or AXUtilities.is_switch(obj): - return [] - enabled, disabled = self._getEnabledAndDisabledContextRoles() - if role in disabled: - return [] - - force = args.get('force', False) - start = args.get('startOffset') - end = args.get('endOffset') - index = args.get('index', 0) - total = args.get('total', 1) - - if not force: - doNotSpeak = [Atspi.Role.FOOTER, - Atspi.Role.FORM, - Atspi.Role.LABEL, - Atspi.Role.MENU_ITEM, - Atspi.Role.PARAGRAPH, - Atspi.Role.SECTION, - Atspi.Role.REDUNDANT_OBJECT, - Atspi.Role.UNKNOWN] - else: - doNotSpeak = [Atspi.Role.UNKNOWN] - - if not force: - doNotSpeak.append(Atspi.Role.TABLE_CELL) - doNotSpeak.append(Atspi.Role.TEXT) - doNotSpeak.append(Atspi.Role.STATIC) - if args.get('string'): - doNotSpeak.append(role_keys.ROLE_CONTENT_SUGGESTION) - if args.get('formatType', 'unfocused') != 'basicWhereAmI': - doNotSpeak.append(Atspi.Role.LIST_ITEM) - doNotSpeak.append(Atspi.Role.LIST) - if (start or end): - doNotSpeak.append(Atspi.Role.DOCUMENT_FRAME) - doNotSpeak.append(Atspi.Role.DOCUMENT_WEB) - doNotSpeak.append(Atspi.Role.ALERT) - if self._script.utilities.isAnchor(obj): - doNotSpeak.append(AXObject.get_role(obj)) - if total > 1: - doNotSpeak.append(Atspi.Role.ROW_HEADER) - if self._script.utilities.isMenuInCollapsedSelectElement(obj): - doNotSpeak.append(Atspi.Role.MENU) - - isEditable = AXUtilities.is_editable(obj) - - if isEditable and not self._script.utilities.isContentEditableWithEmbeddedObjects(obj): - manager = input_event_manager.get_manager() - if (manager.last_event_was_forward_caret_navigation() or self._script.inSayAll()) \ - and start: - return [] - if manager.last_event_was_backward_caret_navigation(): - text = self._script.utilities.queryNonEmptyText(obj) - if text and end not in [None, AXText.get_character_count(obj)]: - return [] - if role not in doNotSpeak: - result.append(self.getLocalizedRoleName(obj, **args)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - elif isEditable and self._script.utilities.isDocument(obj): - parent = AXObject.get_parent(obj) - if parent and not AXUtilities.is_editable(parent) \ - and not input_event_manager.get_manager().last_event_was_caret_navigation(): - result.append(object_properties.ROLE_EDITABLE_CONTENT) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - elif role == Atspi.Role.HEADING: - if index == total - 1 or not self._script.utilities.isFocusableWithMathChild(obj): - level = self._script.utilities.headingLevel(obj) - if level: - result.append(object_properties.ROLE_HEADING_LEVEL_SPEECH % { - 'role': self.getLocalizedRoleName(obj, **args), - 'level': level}) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - else: - result.append(self.getLocalizedRoleName(obj, **args)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - elif self._script.utilities.isLink(obj): - if AXUtilities.is_image(AXObject.get_parent(obj)): - result.append(messages.IMAGE_MAP_LINK) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - else: - if self._script.utilities.hasUselessCanvasDescendant(obj): - result.append(self.getLocalizedRoleName(obj, role=Atspi.Role.IMAGE)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - if index == total - 1 or not self._script.utilities.isFocusableWithMathChild(obj): - result.append(self.getLocalizedRoleName(obj, **args)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - elif role not in doNotSpeak and args.get('priorObj') != obj: - result.append(self.getLocalizedRoleName(obj, **args)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - if self._script.utilities.isMath(obj) and not self._script.utilities.isMathTopLevel(obj): - return result - - def speakRoles(x): - return AXUtilities.is_heading(x) or AXUtilities.is_link(x) - - ancestor = AXObject.find_ancestor(obj, speakRoles) - if ancestor and AXObject.get_role(ancestor) != role \ - and (index == total - 1 or AXObject.get_name(obj) == AXObject.get_name(ancestor)): - result.extend(self._generateRoleName(ancestor)) - - if not result: - return result - - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SPEECH_ONLY: - return result - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableSound'): - return result - - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY: - if roleSoundIcon: - return [roleSoundIcon] - return result - - if not roleSoundIcon: - return result - - return [roleSoundIcon] + result - - def _generatePageSummary(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return [] - - onlyIfFound = args.get('formatType') != 'detailedWhereAmI' - - string = self._script.utilities.getPageSummary(obj, onlyIfFound) - if not string: - return [] - - result = [string] - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - def _generateSiteDescription(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return [] - - link_uri = self._script.utilities.uri(obj) - if not link_uri: - return [] - - link_uri_info = urllib.parse.urlparse(link_uri) - doc_uri = self._script.utilities.documentFrameURI() - if not doc_uri: - return [] - - result = [] - doc_uri_info = urllib.parse.urlparse(doc_uri) - if link_uri_info[1] == doc_uri_info[1]: - if link_uri_info[2] == doc_uri_info[2]: - result.append(messages.LINK_SAME_PAGE) - else: - result.append(messages.LINK_SAME_SITE) - else: - linkdomain = link_uri_info[1].split('.') - docdomain = doc_uri_info[1].split('.') - if len(linkdomain) > 1 and len(docdomain) > 1 \ - and linkdomain[-1] == docdomain[-1] \ - and linkdomain[-2] == docdomain[-2]: - result.append(messages.LINK_SAME_SITE) - else: - result.append(messages.LINK_DIFFERENT_SITE) - - if result: - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - return result - - def _generateExpandedEOCs(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateExpandedEOCs(obj, **args) - - result = [] - startOffset = args.get('startOffset', 0) - endOffset = args.get('endOffset', -1) - text = self._script.utilities.expandEOCs(obj, startOffset, endOffset) - if text: - result.append(text) - return result - - def _generatePositionInList(self, obj, **args): - if AXUtilities.is_list_item(obj): - thisObjIndex = args.get('index', 0) - objCount = args.get('total', 1) - if thisObjIndex + 1 < objCount: - return [] - - if args.get('formatType') not in ['basicWhereAmI', 'detailedWhereAmI']: - if args.get('priorObj') == obj: - return [] - - return super()._generatePositionInList(obj, **args) - - def _generateUnselectedCell(self, obj, **args): - if not self._script.inFocusMode(): - return [] - - return super()._generateUnselectedCell(obj, **args) - - def _generateRealTableCell(self, obj, **args): - result = super()._generateRealTableCell(obj, **args) - if not self._script.inFocusMode(): - return result - - if cthulhu.cthulhuApp.settingsManager.getSetting('speakCellCoordinates'): - label = self._script.utilities.labelForCellCoordinates(obj) - if label: - result.append(label) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - return result - - row, col = self._script.utilities.coordinatesForCell(obj) - if self._script.utilities.cellRowChanged(obj): - result.append(messages.TABLE_ROW % (row + 1)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - if self._script.utilities.cellColumnChanged(obj): - result.append(messages.TABLE_COLUMN % (col + 1)) - result.extend(self.voice(speech_generator.SYSTEM, obj=obj, **args)) - - return result - - def _generateTableCellRow(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - return super()._generateTableCellRow(obj, **args) - - if not self._script.utilities.shouldReadFullRow(obj): - return self._generateRealTableCell(obj, **args) - - row = AXObject.find_ancestor(obj, AXUtilities.is_table_row) - if row and AXObject.get_name(row) and not self._script.utilities.isLayoutOnly(row): - return self.generate(row) - - return super()._generateTableCellRow(obj, **args) - - def _generateRowHeader(self, obj, **args): - if self._script.utilities.lastInputEventWasLineNav(): - return [] - - return super()._generateRowHeader(obj) - - def generateSpeech(self, obj, **args): - if not self._script.utilities.inDocumentContent(obj): - tokens = ["WEB:", obj, "is not in document content. Calling default speech generator."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return super().generateSpeech(obj, **args) - - tokens = ["WEB: Generating speech for document object", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - result = [] - if args.get('formatType') == 'detailedWhereAmI': - oldRole = self._overrideRole('default', args) - elif self._script.utilities.isLink(obj): - oldRole = self._overrideRole(Atspi.Role.LINK, args) - elif self._script.utilities.isCustomImage(obj): - oldRole = self._overrideRole(Atspi.Role.IMAGE, args) - elif self._script.utilities.treatAsDiv(obj, offset=args.get('startOffset')): - oldRole = self._overrideRole(Atspi.Role.SECTION, args) - else: - oldRole = self._overrideRole(self._getAlternativeRole(obj, **args), args) - - if 'priorObj' not in args: - document = self._script.utilities.getTopLevelDocumentForObject(obj) - args['priorObj'] = self._script.utilities.getPriorContext(document)[0] - - start = args.get("startOffset", 0) - end = args.get("endOffset", -1) - args["language"], args["dialect"] = \ - self._script.utilities.getLanguageAndDialectForSubstring(obj, start, end) - - if not result: - result = list(filter(lambda x: x, super().generateSpeech(obj, **args))) - - self._restoreRole(oldRole, args) - tokens = ["WEB: Speech generation for document object", obj, "complete."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return result - - def generateContents(self, contents, **args): - if not len(contents): - return [] - - result = [] - contents = self._script.utilities.filterContentsForPresentation(contents, True) - tokens = ["WEB: Generating speech contents (length:", len(contents), ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - for i, content in enumerate(contents): - obj, start, end, string = content - tokens = ["ITEM", i, ": ", obj, "start: ", start, ", end: ", end, "'", string, "'"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - utterance = self.generateSpeech( - obj, startOffset=start, endOffset=end, string=string, - index=i, total=len(contents), **args) - if isinstance(utterance, list): - def isNotEmptyList(x): - return not (isinstance(x, list) and not x) - - utterance = list(filter(isNotEmptyList, utterance)) - if utterance and utterance[0]: - result.append(utterance) - args['priorObj'] = obj - - if not result: - if self._script.inSayAll(treatInterruptedAsIn=False) \ - or not cthulhu.cthulhuApp.settingsManager.getSetting('speakBlankLines') \ - or args.get('formatType') == 'ancestor': - string = "" - else: - string = messages.BLANK - result = [string, self.voice(speech_generator.DEFAULT, **args)] - - return result diff --git a/src/cthulhu/scripts/web/tutorial_generator.py b/src/cthulhu/scripts/web/tutorial_generator.py deleted file mode 100644 index bf17e0a..0000000 --- a/src/cthulhu/scripts/web/tutorial_generator.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Cthulhu Team." -__license__ = "LGPL" - -from cthulhu import messages -from cthulhu import tutorialgenerator - - -class TutorialGenerator(tutorialgenerator.TutorialGenerator): - def __init__(self, script): - super().__init__(script) - - def _getFocusModeTutorial(self, obj, alreadyFocused, forceTutorial): - binding = self._getBindingsForHandler("togglePresentationModeHandler") - if not binding: - return [] - - return [messages.MODE_FOCUS_TUTORIAL % binding] - - def _getModeTutorial(self, obj, alreadyFocused, forceTutorial): - if self._script.utilities.isFocusModeWidget(obj) \ - and not self._script.useFocusMode(obj): - return self._getFocusModeTutorial(obj, alreadyFocused, forceTutorial) - - return super()._getModeTutorial(obj, alreadyFocused, forceTutorial) diff --git a/src/cthulhu/settings.py b/src/cthulhu/settings.py deleted file mode 100644 index dede460..0000000 --- a/src/cthulhu/settings.py +++ /dev/null @@ -1,542 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Manages the settings for Cthulhu. This will defer to user settings first, but -fallback to local settings if the user settings doesn't exist (e.g., in the -case of gdm) or doesn't have the specified attribute.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -from . import messages -from .acss import ACSS - -userCustomizableSettings = [ - "cthulhuModifierKeys", - "enableSpeech", - "onlySpeakDisplayedText", - "speechServerFactory", - "speechServerInfo", - "hardwareSpeechDevice", - "hardwareSpeechBaudRate", - "voices", - "speechVerbosityLevel", - "readFullRowInGUITable", - "readFullRowInDocumentTable", - "readFullRowInSpreadSheet", - "enableIndentation", - "indentationPresentationMode", - "enableEchoByCharacter", - "enableEchoByWord", - "enableEchoBySentence", - "enableKeyEcho", - "useCustomEchoVoice", - "useCustomEchoSpeechServer", - "echoSpeechServerInfo", - "echoVoice", - "useCustomEchoForKey", - "useCustomEchoForCharacter", - "useCustomEchoForWord", - "useCustomEchoForSentence", - "gameMode", - "nvda2cthulhuTranslateEnabled", - "wineAccessibilityEnabled", - "wineAccessibilityAutoManage", - "wineAccessibilityDialogReader", - "wineAccessibilityController", - "enableAlphabeticKeys", - "enableNumericKeys", - "enablePunctuationKeys", - "enableSpace", - "enableModifierKeys", - "enableFunctionKeys", - "enableActionKeys", - "enableNavigationKeys", - "enableDiacriticalKeys", - "enablePauseBreaks", - "enableTutorialMessages", - "enableMnemonicSpeaking", - "enablePositionSpeaking", - "enableBraille", - "enableBrailleContext", - "disableBrailleEOL", - "brailleVerbosityLevel", - "brailleRolenameStyle", - "brailleSelectorIndicator", - "brailleLinkIndicator", - "enableSound", - "soundVolume", - "soundSink", - "playSoundForRole", - "playSoundForState", - "playSoundForPositionInSet", - "playSoundForValue", - "spatializeObjectSounds", - "roleSoundPresentation", - "soundTheme", - "verbalizePunctuationStyle", - "presentToolTips", - "sayAllStyle", - "keyboardLayout", - "speakBlankLines", - "speakMultiCaseStringsAsWords", - "speakNumbersAsDigits", - "speakMisspelledIndicator", - "enabledSpokenTextAttributes", - "enabledBrailledTextAttributes", - "textAttributesBrailleIndicator", - "profile", - "speakProgressBarUpdates", - "brailleProgressBarUpdates", - "beepProgressBarUpdates", - "progressBarUpdateInterval", - "progressBarBeepInterval", - "progressBarVerbosity", - "ignoreStatusBarProgressBars", - "enableBrailleWordWrap", - "enableContractedBraille", - "brailleContractionTable", - "enableMouseReview", - "speakCellCoordinates", - "speakSpreadsheetCoordinates", - "alwaysSpeakSelectedSpreadsheetRange", - "speakCellSpan", - "speakCellHeaders", - "skipBlankCells", - "largeObjectTextLength", - "structuralNavigationEnabled", - "wrappedStructuralNavigation", - "chatMessageVerbosity", - "chatSpeakRoomName", - "chatAnnounceBuddyTyping", - "chatRoomHistories", - "enableFlashMessages", - "brailleFlashTime", - "flashIsPersistent", - "flashIsDetailed", - "messagesAreDetailed", - "presentDateFormat", - "presentTimeFormat", - "activeProfile", - "activePlugins", - "pluginSources", - "startingProfile", - "spellcheckSpellError", - "spellcheckSpellSuggestion", - "spellcheckPresentContext", - "useColorNames", - "capitalizationStyle", - "findResultsVerbosity", - "findResultsMinimumLength", - "structNavTriggersFocusMode", - "caretNavTriggersFocusMode", - "layoutMode", - "nativeNavTriggersFocusMode", - "rewindAndFastForwardInSayAll", - "structNavInSayAll", - "speakDescription", - "speakContextBlockquote", - "speakContextPanel", - "speakContextLandmark", - "speakContextNonLandmarkForm", - "speakContextList", - "speakContextTable", - "sayAllContextBlockquote", - "sayAllContextPanel", - "sayAllContextLandmark", - "sayAllContextNonLandmarkForm", - "sayAllContextList", - "sayAllContextTable", - "aiAssistantEnabled", - "aiProvider", - "aiApiKeyFile", - "aiOllamaModel", - "aiOllamaEndpoint", - "aiConfirmationRequired", - "aiActionTimeout", - "aiScreenshotQuality", - "aiMaxContextLength", - "ocrLanguageCode", - "ocrScaleFactor", - "ocrGrayscaleImg", - "ocrInvertImg", - "ocrBlackWhiteImg", - "ocrBlackWhiteImgValue", - "ocrColorCalculation", - "ocrColorCalculationMax", - "ocrCopyToClipboard" -] - -GENERAL_KEYBOARD_LAYOUT_DESKTOP = 1 -GENERAL_KEYBOARD_LAYOUT_LAPTOP = 2 - -DESKTOP_MODIFIER_KEYS = ["Insert", "KP_Insert"] -LAPTOP_MODIFIER_KEYS = ["Caps_Lock", "Shift_Lock"] - -VERBOSITY_LEVEL_BRIEF = 0 -VERBOSITY_LEVEL_VERBOSE = 1 - -BRAILLE_UNDERLINE_NONE = 0x00 # 00000000 -BRAILLE_UNDERLINE_7 = 0x40 # 01000000 -BRAILLE_UNDERLINE_8 = 0x80 # 10000000 -BRAILLE_UNDERLINE_BOTH = 0xc0 # 11000000 - -BRAILLE_ROLENAME_STYLE_SHORT = 0 # three letter abbreviations -BRAILLE_ROLENAME_STYLE_LONG = 1 # full rolename - -PUNCTUATION_STYLE_NONE = 3 -PUNCTUATION_STYLE_SOME = 2 -PUNCTUATION_STYLE_MOST = 1 -PUNCTUATION_STYLE_ALL = 0 - -CAPITALIZATION_STYLE_NONE = "none" -CAPITALIZATION_STYLE_SPELL = "spell" -CAPITALIZATION_STYLE_ICON = "icon" - -SAYALL_STYLE_LINE = 0 -SAYALL_STYLE_SENTENCE = 1 - -PROGRESS_BAR_ALL = 0 -PROGRESS_BAR_APPLICATION = 1 -PROGRESS_BAR_WINDOW = 2 - -CHAT_SPEAK_ALL = 0 -CHAT_SPEAK_ALL_IF_FOCUSED = 1 -CHAT_SPEAK_FOCUSED_CHANNEL = 2 - -# AI Assistant constants - simplified to providers that don't need complex API key management -AI_PROVIDER_CLAUDE_CODE = "claude_code" -AI_PROVIDER_CODEX = "codex" -AI_PROVIDER_GEMINI = "gemini" -AI_PROVIDER_OLLAMA = "ollama" - -AI_SCREENSHOT_QUALITY_LOW = "low" -AI_SCREENSHOT_QUALITY_MEDIUM = "medium" -AI_SCREENSHOT_QUALITY_HIGH = "high" - -# Indentation presentation modes -INDENTATION_PRESENTATION_OFF = "off" -INDENTATION_PRESENTATION_SPEECH = "speech" -INDENTATION_PRESENTATION_BEEPS = "beeps" -INDENTATION_PRESENTATION_SPEECH_AND_BEEPS = "speech_and_beeps" - -DEFAULT_VOICE = "default" -UPPERCASE_VOICE = "uppercase" -HYPERLINK_VOICE = "hyperlink" -SYSTEM_VOICE = "system" - -voicesKeys = { -"DEFAULT_VOICE" : "default", -"UPPERCASE_VOICE" : "uppercase", -"HYPERLINK_VOICE" : "hyperlink", -"SYSTEM_VOICE" : "system" -} - - -voices = { - DEFAULT_VOICE: ACSS({}), - UPPERCASE_VOICE: ACSS({ACSS.AVERAGE_PITCH : 7.0}), - HYPERLINK_VOICE: ACSS({}), - SYSTEM_VOICE: ACSS({}), -} - -# Profiles -startingProfile = ['Default', 'default'] -activeProfile = ['Default', 'default'] -profile = ['Default', 'default'] - -# Speech -speechFactoryModules = ["speechdispatcherfactory", "piperfactory", "hardwarefactory"] -speechServerFactory = "speechdispatcherfactory" -speechServerInfo = None # None means let the factory decide. -hardwareSpeechDevice = "" -hardwareSpeechBaudRate = 9600 -enableSpeech = True -silenceSpeech = False -enableTutorialMessages = False -enableMnemonicSpeaking = False -enablePositionSpeaking = False -enableIndentation = False -indentationPresentationMode = INDENTATION_PRESENTATION_SPEECH -onlySpeakDisplayedText = False -presentToolTips = False -speakBlankLines = True -repeatCharacterLimit = 4 -readFullRowInGUITable = True -readFullRowInDocumentTable = True -readFullRowInSpreadSheet = False -speakCellCoordinates = True -speakCellSpan = True -speakCellHeaders = True -speakSpreadsheetCoordinates = True -alwaysSpeakSelectedSpreadsheetRange = False -speakMultiCaseStringsAsWords = False -speakNumbersAsDigits = False -speakMisspelledIndicator = True -useColorNames = True -usePronunciationDictionary = True -sayAllStyle = SAYALL_STYLE_SENTENCE -capitalizationStyle = CAPITALIZATION_STYLE_NONE -verbalizePunctuationStyle = PUNCTUATION_STYLE_MOST -speechVerbosityLevel = VERBOSITY_LEVEL_VERBOSE -messagesAreDetailed = True -enablePauseBreaks = True -gameMode = False -nvda2cthulhuTranslateEnabled = False -wineAccessibilityEnabled = True -wineAccessibilityAutoManage = True -wineAccessibilityDialogReader = True -wineAccessibilityController = True -speakDescription = True -speakContextBlockquote = True -speakContextPanel = True -speakContextNonLandmarkForm = True -speakContextLandmark = True -speakContextList = True -speakContextTable = True -sayAllContextBlockquote = True -sayAllContextPanel = True -sayAllContextNonLandmarkForm = True -sayAllContextLandmark = True -sayAllContextList = True -sayAllContextTable = True - -# Braille -enableBraille = True -enableBrailleMonitor = False -enableBrailleContext = True -enableFlashMessages = True -brailleFlashTime = 5000 -flashIsPersistent = False -flashIsDetailed = True -enableBrailleWordWrap = False -enableContractedBraille = False -brailleContractionTable = '' -disableBrailleEOL = False -brailleRolenameStyle = BRAILLE_ROLENAME_STYLE_LONG -brailleSelectorIndicator = BRAILLE_UNDERLINE_BOTH -brailleLinkIndicator = BRAILLE_UNDERLINE_BOTH -textAttributesBrailleIndicator = BRAILLE_UNDERLINE_NONE -brailleVerbosityLevel = VERBOSITY_LEVEL_VERBOSE - -# Sound -ROLE_SOUND_PRESENTATION_SOUND_AND_SPEECH = "sound_and_speech" -ROLE_SOUND_PRESENTATION_SPEECH_ONLY = "speech_only" -ROLE_SOUND_PRESENTATION_SOUND_ONLY = "sound_only" -SOUND_SINK_AUTO = "auto" -SOUND_SINK_PIPEWIRE = "pipewire" -SOUND_SINK_PULSE = "pulse" -SOUND_SINK_ALSA = "alsa" -SOUND_SINK_VALUES = ( - SOUND_SINK_AUTO, - SOUND_SINK_PIPEWIRE, - SOUND_SINK_PULSE, - SOUND_SINK_ALSA, -) - -enableSound = True -soundVolume = 0.5 -soundSink = SOUND_SINK_AUTO -playSoundForRole = False -playSoundForState = False -playSoundForPositionInSet = False -playSoundForValue = False -spatializeObjectSounds = False -roleSoundPresentation = ROLE_SOUND_PRESENTATION_SOUND_AND_SPEECH -soundTheme = "default" - -# Keyboard and Echo -keyboardLayout = GENERAL_KEYBOARD_LAYOUT_DESKTOP -cthulhuModifierKeys = DESKTOP_MODIFIER_KEYS -doubleClickTimeout = 0.5 -enableKeyEcho = True -enableAlphabeticKeys = True -enableNumericKeys = True -enablePunctuationKeys = True -enableSpace = True -enableModifierKeys = True -enableFunctionKeys = True -enableActionKeys = True -enableNavigationKeys = False -enableDiacriticalKeys = False -enableEchoByCharacter = False -enableEchoByWord = False -enableEchoBySentence = False -useCustomEchoVoice = False -useCustomEchoSpeechServer = False -echoSpeechServerInfo = None -echoVoice = ACSS({}) -useCustomEchoForKey = True -useCustomEchoForCharacter = True -useCustomEchoForWord = False -useCustomEchoForSentence = False -presentLockingKeys = None - -# Mouse review -enableMouseReview = False - -# Flat review -flatReviewIsRestricted = False - -# Progressbars -speakProgressBarUpdates = True -brailleProgressBarUpdates = False -beepProgressBarUpdates = False -progressBarUpdateInterval = 10 -progressBarSpeechInterval = None -progressBarBrailleInterval = None -progressBarBeepInterval = 0 -progressBarVerbosity = PROGRESS_BAR_APPLICATION -ignoreStatusBarProgressBars = True - -# Structural navigation -structuralNavigationEnabled = True -skipBlankCells = False -largeObjectTextLength = 75 -wrappedStructuralNavigation = True -inferLiveRegions = True - -# Chat -chatMessageVerbosity = CHAT_SPEAK_ALL -chatSpeakRoomName = False -chatAnnounceBuddyTyping = False -chatRoomHistories = False - -# Spellcheck -spellcheckSpellError = True -spellcheckSpellSuggestion = True -spellcheckPresentContext = True - -# Day and time -presentDateFormat = messages.DATE_FORMAT_LOCALE -presentTimeFormat = messages.TIME_FORMAT_LOCALE - -# App search support -FIND_SPEAK_NONE = 0 -FIND_SPEAK_IF_LINE_CHANGED = 1 -FIND_SPEAK_ALL = 2 -findResultsVerbosity = FIND_SPEAK_ALL -findResultsMinimumLength = 4 - -# The complete list of possible text attributes. -allTextAttributes = \ - "bg-color:; bg-full-height:; bg-stipple:; direction:; editable:; " \ - "family-name:; fg-color:; fg-stipple:; font-effect:none; indent:0; " \ - "invisible:; justification:left; language:; left-margin:; " \ - "line-height:100%; paragraph-style:Default; pixels-above-lines:; " \ - "pixels-below-lines:; pixels-inside-wrap:; right-margin:; rise:; " \ - "scale:; size:; stretch:; strikethrough:false; style:normal; " \ - "text-decoration:none; text-rotation:0; text-shadow:none; " \ - "text-spelling:none; underline:none; variant:; " \ - "vertical-align:baseline; weight:400; wrap-mode:; writing-mode:lr-tb;" - -# The default set of text attributes to speak to the user. Specific -# application scripts (or individual users can override these values if -# so desired. Each of these text attributes is of the form :; -# The part will be the "default" value for that attribute. In -# other words, if the attribute for a given piece of text has that value, -# it won't be spoken. If no value part is given, then that attribute will -# always be spoken. -enabledSpokenTextAttributes = \ - "size:; family-name:; weight:400; indent:0; underline:none; " \ - "strikethrough:false; justification:left; style:normal; " \ - "paragraph-style:; text-spelling:none; fg-color:; bg-color:;" - -# The default set of text attributes to be brailled for the user. Specific -# application scripts (or individual users can override these values if -# so desired. Each of these text attributes is of the form :; -# The part will be the "default" value for that attribute. In -# other words, if the attribute for a given piece of text has that value, -# it won't be spoken. If no value part is given, then that attribute will -# always be brailled. -enabledBrailledTextAttributes = \ - "size:; family-name:; weight:400; indent:0; underline:none; " \ - "strikethrough:false; justification:left; style:normal; " \ - "text-spelling:none;" - -# Latent support to allow the user to override/define keybindings -# and braille bindings. Unsupported and undocumented for now. -# Use at your own risk. -# -brailleBindingsMap = {} - -# TODO - JD: Is this still needed now that AT-SPI has its own timeout? -timeoutTime = 10 # a value of 0 means don't do hang checking -timeoutCallback = None # Set by cthulhu.py:init to cthulhu.timeout - -structNavTriggersFocusMode = False -caretNavTriggersFocusMode = False -nativeNavTriggersFocusMode = True - -layoutMode = False - -rewindAndFastForwardInSayAll = False -structNavInSayAll = False - -# N.B. The following are experimental and may change or go away at any time. -enableSadPidginHack = False -presentChatRoomLast = False -presentLiveRegionFromInactiveTab = False - -# Plugins -activePlugins = [ - 'ByeCthulhu', - 'Clipboard', - 'HelloCthulhu', - 'DisplayVersion', - 'GameMode', - 'nvda2cthulhu', - 'OCR', - 'SpeechHistory', - 'SSIPProxy', - 'WindowTitleReader', - 'WineAccessibility' -] -pluginSources = [] - -# AI Assistant settings (disabled by default for opt-in behavior) -aiAssistantEnabled = False -aiProvider = AI_PROVIDER_OLLAMA -aiApiKeyFile = "" -aiOllamaModel = "llama3.2-vision" -aiOllamaEndpoint = "http://localhost:11434" -aiConfirmationRequired = True -aiActionTimeout = 30 -aiScreenshotQuality = AI_SCREENSHOT_QUALITY_MEDIUM -aiMaxContextLength = 4000 - -# OCR Plugin settings -ocrLanguageCode = 'eng' -ocrScaleFactor = 3 -ocrGrayscaleImg = False -ocrInvertImg = False -ocrBlackWhiteImg = False -ocrBlackWhiteImgValue = 200 -ocrColorCalculation = False -ocrColorCalculationMax = 3 -ocrCopyToClipboard = False diff --git a/src/cthulhu/settings_manager.py b/src/cthulhu/settings_manager.py deleted file mode 100644 index ebe02fa..0000000 --- a/src/cthulhu/settings_manager.py +++ /dev/null @@ -1,918 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Settings manager module. This will load/save user settings from a -defined settings backend.""" - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2010 Consorcio Fernando de los Rios." -__license__ = "LGPL" - -import copy -import importlib -import os -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union - -from gi.repository import Gio, GLib -from tomlkit import parse - -from . import debug -from . import cthulhu_i18n -from . import settings -from . import pronunciation_dict -from .acss import ACSS -from .ax_object import AXObject -from .keybindings import KeyBinding - -if TYPE_CHECKING: - from .cthulhu import Cthulhu - from .script import Script - from .input_event import InputEventHandler - -# Removed global cthulhuApp.scriptManager declaration. -# Note: Do not import cthulhu module here to avoid circular import - -class SettingsManager(object): - """Settings backend manager. This class manages cthulhu user's settings - using different backends""" - - def __init__(self, app: Cthulhu, backend: str = 'toml') -> None: # Modified signature - - debug.printMessage(debug.LEVEL_INFO, 'SETTINGS MANAGER: Initializing', True) - self.app: Cthulhu = app # Store app instance - - # Move _proxy initialization here - try: - self._proxy: Optional[Gio.DBusProxy] = Gio.DBusProxy.new_for_bus_sync( - Gio.BusType.SESSION, - Gio.DBusProxyFlags.NONE, - None, - 'org.a11y.Bus', - '/org/a11y/bus', - 'org.freedesktop.DBus.Properties', - None) - except Exception: - self._proxy = None - - self.backendModule: Optional[Any] = None - self._backend: Optional[Any] = None - self.profile: Optional[str] = None - self.backendName: str = backend - self._prefsDir: Optional[str] = None - - # Dictionaries for store the default values - # The keys and values are defined at cthulhu.settings - # - self.defaultGeneral: Dict[str, Any] = {} - self.defaultPronunciations: Dict[str, Any] = {} - self.defaultKeybindings: Dict[str, Any] = {} - - # Dictionaries that store the key:value pairs which values are - # different from the current profile and the default ones - # - self.profileGeneral: Dict[str, Any] = {} - self.profilePronunciations: Dict[str, Any] = {} - self.profileKeybindings: Dict[str, Any] = {} - - # Dictionaries that store the current settings. - # They are result to overwrite the default values with - # the ones from the current active profile - self.general: Dict[str, Any] = {} - self.pronunciations: Dict[str, Any] = {} - self.keybindings: Dict[str, Any] = {} - - self._activeApp: str = "" - self._appGeneral: Dict[str, Any] = {} - self._appPronunciations: Dict[str, Any] = {} - self._appKeybindings: Dict[str, Any] = {} - self._lastRoleSoundPresentation: Optional[Any] = None - self._session_settings: Dict[str, Any] = {} - - if not self._loadBackend(): - raise Exception('SettingsManager._loadBackend failed.') - - self.customizedSettings: Dict[str, Any] = {} - self._customizationCompleted: bool = False - - # For handling the currently-"classic" application settings - self.settingsPackages: List[str] = ["app-settings"] - - debug.printMessage(debug.LEVEL_INFO, 'SETTINGS MANAGER: Initialized', True) - - def activate(self, prefsDir: Optional[str] = None, customSettings: Dict[str, Any] = {}) -> None: - debug.printMessage(debug.LEVEL_INFO, 'SETTINGS MANAGER: Activating', True) - - self.customizedSettings.update(customSettings) - self._prefsDir = prefsDir \ - or os.path.join(GLib.get_user_data_dir(), "cthulhu") - - # Load the backend and the default values - if self.backendModule: - self._backend = self.backendModule.Backend(self._prefsDir) - self._setDefaultGeneral() - self._setDefaultPronunciations() - self._setDefaultKeybindings() - self.general = self.defaultGeneral.copy() - if not self.isFirstStart() and self._backend: - self.general.update(self._backend.getGeneral()) - self.pronunciations = self.defaultPronunciations.copy() - self.keybindings = self.defaultKeybindings.copy() - - # If this is the first time we launch Cthulhu, there is no user settings - # yet, so we need to create the user config directories and store the - # initial default settings - # - self._createDefaults() - - debug.printMessage(debug.LEVEL_INFO, 'SETTINGS MANAGER: Activated', True) - - # Set the active profile and load its stored settings - tokens = ["SETTINGS MANAGER: Current profile is", self.profile] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if self.profile is None: - self.profile = self.general.get('startingProfile')[1] # type: ignore - tokens = ["SETTINGS MANAGER: Current profile is now", self.profile] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if self.profile: - self.setProfile(self.profile) - - def _loadBackend(self) -> bool: - """Load specific backend for manage user settings""" - - try: - backend = f'.backends.{self.backendName}_backend' - self.backendModule = importlib.import_module(backend, 'cthulhu') - return True - except Exception: - return False - - def _createDefaults(self) -> None: - """Let the active backend to create the initial structure - for storing the settings and save the default ones from - cthulhu.settings""" - def _createDir(dirName: str) -> None: - if not os.path.isdir(dirName): - os.makedirs(dirName) - - if not self._prefsDir: - return - - # Set up the user's preferences directory - # ($XDG_DATA_HOME/cthulhu by default). - # - cthulhuDir = self._prefsDir - _createDir(cthulhuDir) - - # Set up $XDG_DATA_HOME/cthulhu/cthulhu-scripts as a Python package - # - cthulhuScriptDir = os.path.join(cthulhuDir, "cthulhu-scripts") - _createDir(cthulhuScriptDir) - initFile = os.path.join(cthulhuScriptDir, "__init__.py") - if not os.path.exists(initFile): - os.close(os.open(initFile, os.O_CREAT, 0o700)) - - cthulhuSettingsDir = os.path.join(cthulhuDir, "app-settings") - _createDir(cthulhuSettingsDir) - - cthulhuSoundsDir = os.path.join(cthulhuDir, "sounds") - _createDir(cthulhuSoundsDir) - - # Set up $XDG_DATA_HOME/cthulhu/cthulhu-customizations.py empty file and - # define cthulhuDir as a Python package. - initFile = os.path.join(cthulhuDir, "__init__.py") - if not os.path.exists(initFile): - os.close(os.open(initFile, os.O_CREAT, 0o700)) - - userCustomFile = os.path.join(cthulhuDir, "cthulhu-customizations.py") - if not os.path.exists(userCustomFile): - os.close(os.open(userCustomFile, os.O_CREAT, 0o700)) - - sleepConfigFile = os.path.join(cthulhuDir, "sleep.toml") - if not os.path.exists(sleepConfigFile): - sleepTemplate = ( - "# Cthulhu auto-sleep apps\n" - "#\n" - "# List current app names with:\n" - "# cthulhu --list-apps\n" - "# Use the middle app-name column from that output.\n" - "#\n" - "# Add app names to auto-enable sleep mode:\n" - "# apps = [\"qemu\"]\n" - "#\n" - "# Or use a section:\n" - "# [sleep]\n" - "# apps = [\"qemu\"]\n" - ) - with open(sleepConfigFile, "w", encoding="utf-8") as configFile: - configFile.write(sleepTemplate) - - if self.isFirstStart() and self._backend: - self._backend.saveDefaultSettings(self.defaultGeneral, - self.defaultPronunciations, - self.defaultKeybindings) - - def _setDefaultPronunciations(self) -> None: - """Get the pronunciations by default from cthulhu.settings""" - self.defaultPronunciations = {} - - def _setDefaultKeybindings(self) -> None: - """Get the keybindings by default from cthulhu.settings""" - self.defaultKeybindings = {} - - def _setDefaultGeneral(self) -> None: - """Get the general settings by default from cthulhu.settings""" - self._getCustomizedSettings() - self.defaultGeneral = {} - for key in settings.userCustomizableSettings: - value = self.customizedSettings.get(key) - if value is None: - try: - value = getattr(settings, key) - except Exception: - pass - try: - value = copy.deepcopy(value) - except Exception: - pass - self.defaultGeneral[key] = value - default_active_plugins = copy.deepcopy(self.defaultGeneral.get("activePlugins")) - overrides = self._load_default_general_overrides() - if overrides: - for key, value in overrides.items(): - if key not in self.defaultGeneral: - continue - if key == "activePlugins": - continue - self.defaultGeneral[key] = value - if default_active_plugins is not None: - self.defaultGeneral["activePlugins"] = default_active_plugins - - def _load_default_general_overrides(self) -> Dict[str, Any]: - if not self._prefsDir: - return {} - - settings_path = os.path.join(self._prefsDir, "user-settings.toml") - if not os.path.exists(settings_path): - return {} - - try: - with open(settings_path, "r", encoding="utf-8") as settings_file: - prefs = parse(settings_file.read()) - except Exception as error: - msg = f"SETTINGS MANAGER: Unable to read default settings from {settings_path}: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - return {} - - general = prefs.get("general") - if not isinstance(general, dict): - return {} - - if self._backend and hasattr(self._backend, "_migrateSettings"): - try: - general = self._backend._migrateSettings(dict(general)) - except Exception as error: - msg = f"SETTINGS MANAGER: Unable to migrate default settings: {error}" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - general = dict(general) - else: - general = dict(general) - - voices = general.get("voices") - if isinstance(voices, dict): - converted_voices = {} - for voice_type, voice_def in voices.items(): - try: - converted_voices[voice_type] = ACSS(voice_def) - except Exception: - converted_voices[voice_type] = voice_def - general["voices"] = converted_voices - - echo_voice = general.get("echoVoice") - if isinstance(echo_voice, dict): - try: - general["echoVoice"] = ACSS(echo_voice) - except Exception: - general["echoVoice"] = echo_voice - - return general - - def getDefaultSetting(self, settingName: str) -> Any: - if settingName in self.defaultGeneral: - return self.defaultGeneral.get(settingName) - return getattr(settings, settingName, None) - - def _getCustomizedSettings(self) -> Dict[str, Any]: - if self._customizationCompleted: - return self.customizedSettings - - originalSettings = {} - for key, value in settings.__dict__.items(): - originalSettings[key] = value - - self._customizationCompleted = self._loadUserCustomizations() - - for key, value in originalSettings.items(): - customValue = settings.__dict__.get(key) - if value != customValue: - self.customizedSettings[key] = customValue - - return self.customizedSettings - - def _loadUserCustomizations(self) -> bool: - """Attempt to load the user's cthulhu-customizations. Returns a boolean - indicating our success at doing so, where success is measured by the - likelihood that the results won't be different if we keep trying.""" - - success = False - if not self._prefsDir: - return False - - pathList = [self._prefsDir] - tokens = ["SETTINGS MANAGER: Attempt to load cthulhu-customizations"] - module_path = pathList[0] + "/cthulhu-customizations.py" - - try: - spec = importlib.util.spec_from_file_location("cthulhu-customizations", module_path) - if spec is not None and spec.loader: - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - tokens.extend(["from", module_path, "succeeded."]) - success = True - else: - tokens.extend(["from", module_path, "failed. Spec not found."]) - except FileNotFoundError: - tokens.extend(["from", module_path, "failed. File not found."]) - except Exception as error: - # Treat this failure as a "success" so that we don't stomp on the existing file. - success = True - tokens.extend(["failed due to:", str(error), ". Not loading customizations."]) - - debug.printTokens(debug.LEVEL_ALL, tokens, True) - return success - - def getPrefsDir(self) -> Optional[str]: - return self._prefsDir - - def setSetting(self, settingName: str, settingValue: Any) -> None: - self._setSettingsRuntime({settingName:settingValue}) - - def set_session_setting(self, setting_name: str, setting_value: Any) -> None: - """Set a process-lifetime setting which survives application changes.""" - - self._session_settings[setting_name] = copy.deepcopy(setting_value) - self._setSettingsRuntime({setting_name: setting_value}) - - def getSetting(self, settingName: str) -> Any: - return getattr(settings, settingName, None) - - def _getListSetting(self, settingName: str) -> List[str]: - value = self.getSetting(settingName) - if isinstance(value, (list, tuple)): - return [item for item in value if isinstance(item, str)] - return [] - - def _ensurePluginPersistenceSettings(self, general: Dict[str, Any]) -> None: - if 'activePlugins' not in general: - general['activePlugins'] = self._getListSetting('activePlugins') - if 'pluginSources' not in general: - general['pluginSources'] = self._getListSetting('pluginSources') - - def getVoiceLocale(self, voice: str = 'default') -> str: - voices = self.getSetting('voices') - v = ACSS(voices.get(voice, {})) - lang = v.getLocale() - dialect = v.getDialect() - if dialect and len(str(dialect)) == 2: - lang = f"{lang}_{dialect.upper()}" - return lang - - def getSpeechServerFactories(self) -> List[Any]: - """Imports all known SpeechServer factory modules.""" - - factories = [] - for moduleName in self.getSetting('speechFactoryModules'): - try: - module = importlib.import_module(f'cthulhu.{moduleName}') - factories.append(module) - tokens = ["SETTINGS MANAGER: Valid speech server factory:", moduleName] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - except Exception: - tokens = ["SETTINGS MANAGER: Invalid speech server factory:", moduleName] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return factories - - def _loadProfileSettings(self, profile: Optional[str] = None) -> None: - """Get from the active backend all the settings for the current - profile and store them in the object's attributes. - A profile can be passed as a parameter. This could be useful for - change from one profile to another.""" - - tokens = ["SETTINGS MANAGER: Loading settings for", profile, "profile"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if profile is None: - profile = self.profile - - if profile: - self.profileGeneral = self.getGeneralSettings(profile) or {} - self.profilePronunciations = self.getPronunciations(profile) or {} - self.profileKeybindings = self.getKeybindings(profile) or {} - - tokens = ["SETTINGS MANAGER: Settings for", profile, "profile loaded"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - def _mergeSettings(self) -> None: - """Update the changed values on the profile settings - over the current and active settings""" - - msg = 'SETTINGS MANAGER: Merging settings.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self.profileGeneral.update(self._appGeneral) - self.profilePronunciations.update(self._appPronunciations) - self.profileKeybindings.update(self._appKeybindings) - - self.general.update(self.profileGeneral) - self.pronunciations.update(self.profilePronunciations) - self.keybindings.update(self.profileKeybindings) - - msg = 'SETTINGS MANAGER: Settings merged.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _enableAccessibility(self) -> bool: - """Enables the desktop accessibility bus flag when available. - - Returns True if an action was taken (i.e., accessibility was not - set prior to this call). - """ - - alreadyEnabled = self.isAccessibilityEnabled() - if not alreadyEnabled: - self.setAccessibility(True) - - return not alreadyEnabled - - def isAccessibilityEnabled(self) -> bool: - msg = 'SETTINGS MANAGER: Checking if accessibility is enabled.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - msg = 'SETTINGS MANAGER: Accessibility enabled: ' - rv = False - if not self._proxy: - rv = False - msg += 'Error (no proxy)' - else: - try: - rv = self._proxy.Get('(ss)', 'org.a11y.Status', 'IsEnabled') - msg += str(rv) - except Exception: - rv = False - msg += 'Error calling DBus' - - debug.printMessage(debug.LEVEL_INFO, msg, True) - return rv - - def setAccessibility(self, enable: bool) -> Union[bool, None]: - msg = f'SETTINGS MANAGER: Attempting to set accessibility to {enable}.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if not self._proxy: - msg = 'SETTINGS MANAGER: Error (no proxy)' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - try: - vEnable = GLib.Variant('b', enable) - self._proxy.Set('(ssv)', 'org.a11y.Status', 'IsEnabled', vEnable) - except Exception: - pass - - msg = f'SETTINGS MANAGER: Finished setting accessibility to {enable}.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return None - - def isScreenReaderServiceEnabled(self) -> bool: - """Returns True if the screen reader service is enabled. Note that - this does not necessarily mean that Cthulhu (or any other screen reader) - is running at the moment.""" - - msg = 'SETTINGS MANAGER: Is screen reader service enabled? ' - - rv = False - if not self._proxy: - rv = False - msg += 'Error (no proxy)' - else: - try: - rv = self._proxy.Get('(ss)', 'org.a11y.Status', 'ScreenReaderEnabled') - msg += str(rv) - except Exception: - rv = False - - debug.printMessage(debug.LEVEL_INFO, msg, True) - return rv - - def setStartingProfile(self, profile: Optional[tuple] = None) -> None: - if profile is None: - profile = settings.profile - if self._backend: - self._backend._setProfileKey('startingProfile', profile) - - def getProfile(self) -> Optional[str]: - return self.profile - - def setProfile(self, profile: str = 'default', updateLocale: bool = False) -> None: - """Set a specific profile as the active one. - Also the settings from that profile will be loading - and updated the current settings with them.""" - - tokens = ["SETTINGS MANAGER: Setting profile to:", profile] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - oldVoiceLocale = self.getVoiceLocale('default') - self.profile = profile - self._loadProfileSettings(profile) - self._mergeSettings() - self._setSettingsRuntime(self.general) - - if not updateLocale: - return - - newVoiceLocale = self.getVoiceLocale('default') - if oldVoiceLocale != newVoiceLocale: - cthulhu_i18n.setLocaleForNames(newVoiceLocale) - cthulhu_i18n.setLocaleForMessages(newVoiceLocale) - cthulhu_i18n.setLocaleForGUI(newVoiceLocale) - - tokens = ["SETTINGS MANAGER: Profile set to:", profile] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - def removeProfile(self, profile: str) -> None: - if self._backend: - self._backend.removeProfile(profile) - - def _setSettingsRuntime(self, settingsDict: Dict[str, Any]) -> None: - msg = 'SETTINGS MANAGER: Setting runtime settings.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - for key, value in settingsDict.items(): - setattr(settings, str(key), value) - self._getCustomizedSettings() - for key, value in self.customizedSettings.items(): - setattr(settings, str(key), value) - for key, value in self._session_settings.items(): - setattr(settings, str(key), copy.deepcopy(value)) - - msg = 'SETTINGS MANAGER: Runtime settings set.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._logRoleSoundPresentationChange() - - def _logRoleSoundPresentationChange(self) -> None: - current = getattr(settings, "roleSoundPresentation", None) - if current == self._lastRoleSoundPresentation: - return - - msg = ( - "SETTINGS MANAGER: roleSoundPresentation changed to " - f"{current} profile={self.profile} app={self._activeApp}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._lastRoleSoundPresentation = current - - def _setPronunciationsRuntime(self, pronunciationsDict: Dict[str, Any]) -> None: - pronunciation_dict.pronunciation_dict = {} - for key, value in pronunciationsDict.values(): - if key and value: - pronunciation_dict.setPronunciation(key, value) - - def getGeneralSettings(self, profile: str = 'default') -> Dict[str, Any]: - """Return the current general settings. - Those settings comes from updating the default settings - with the profiles' ones""" - general = self.defaultGeneral.copy() - if self._backend: - general.update(self._backend.getGeneral(profile)) - return general - - def getPronunciations(self, profile: str = 'default') -> Dict[str, Any]: - """Return the current pronunciations settings. - Those settings comes from updating the default settings - with the profiles' ones""" - if self._backend: - return self._backend.getPronunciations(profile) - return {} - - def getKeybindings(self, profile: str = 'default') -> Dict[str, Any]: - """Return the current keybindings settings. - Those settings comes from updating the default settings - with the profiles' ones""" - if self._backend: - return self._backend.getKeybindings(profile) - return {} - - def _setProfileGeneral(self, general: Dict[str, Any]) -> None: - """Set the changed general settings from the defaults' ones - as the profile's.""" - - msg = 'SETTINGS MANAGER: Setting general settings for profile' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self.profileGeneral = {} - alwaysPersistKeys = { - 'useCustomEchoVoice', - 'useCustomEchoSpeechServer', - 'useCustomEchoForKey', - 'useCustomEchoForCharacter', - 'useCustomEchoForWord', - 'useCustomEchoForSentence', - } - - for key, value in general.items(): - if key in ['startingProfile', 'activeProfile']: - continue - elif key == 'profile': - self.profileGeneral[key] = value - elif key in ['activePlugins', 'pluginSources']: - self.profileGeneral[key] = copy.deepcopy(value) - elif key in alwaysPersistKeys: - self.profileGeneral[key] = copy.deepcopy(value) - elif value != self.defaultGeneral.get(key): - self.profileGeneral[key] = value - elif self.general.get(key) != value: - self.profileGeneral[key] = value - - msg = 'SETTINGS MANAGER: General settings for profile set' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def saveProfileSettings( - self, - general: Dict[str, Any], - pronunciations: Optional[Dict[str, Any]] = None, - keybindings: Optional[Dict[str, Any]] = None, - ) -> None: - profileName: Optional[str] = self.profile - profileSetting = general.get('profile') - if isinstance(profileSetting, (list, tuple)) and len(profileSetting) > 1: - profileName = profileSetting[1] - elif not profileName: - defaultProfile = settings.profile - if isinstance(defaultProfile, (list, tuple)) and len(defaultProfile) > 1: - profileName = defaultProfile[1] - else: - profileName = 'default' - - self.profile = profileName - generalCopy = dict(general) - self._ensurePluginPersistenceSettings(generalCopy) - self._setProfileGeneral(generalCopy) - - if self.profile is None: - return - - profileName = self.profile - if pronunciations is None: - pronunciations = self.getPronunciations(profileName) or {} - if keybindings is None: - keybindings = self.getKeybindings(profileName) or {} - - self._setProfilePronunciations(pronunciations) - self._setProfileKeybindings(keybindings) - - if self._backend: - self._backend.saveProfileSettings(self.profile, - self.profileGeneral, - self.profilePronunciations, - self.profileKeybindings) - - def _setProfilePronunciations(self, pronunciations: Dict[str, Any]) -> None: - """Set the changed pronunciations settings from the defaults' ones - as the profile's.""" - - msg = 'SETTINGS MANAGER: Setting pronunciation settings for profile.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self.profilePronunciations = self.defaultPronunciations.copy() - self.profilePronunciations.update(pronunciations) - - msg = 'SETTINGS MANAGER: Pronunciation settings for profile set.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _setProfileKeybindings(self, keybindings: Dict[str, Any]) -> None: - """Set the changed keybindings settings from the defaults' ones - as the profile's.""" - - msg = 'SETTINGS MANAGER: Setting keybindings settings for profile.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - self.profileKeybindings = self.defaultKeybindings.copy() - self.profileKeybindings.update(keybindings) - - msg = 'SETTINGS MANAGER: Keybindings settings for profile set.' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _saveAppSettings(self, appName: str, general: Dict[str, Any], pronunciations: Dict[str, Any], keybindings: Dict[str, Any]) -> None: - if not self._backend: - return - - profileScopedKeys = {'activePlugins', 'pluginSources'} - appGeneral = {} - profileGeneral = self.getGeneralSettings(self.profile) if self.profile else {} - for key, value in general.items(): - if key in profileScopedKeys: - continue - if value != profileGeneral.get(key): - appGeneral[key] = value - - appPronunciations = {} - profilePronunciations = self.getPronunciations(self.profile) if self.profile else {} - for key, value in pronunciations.items(): - if value != profilePronunciations.get(key): - appPronunciations[key] = value - - appKeybindings = {} - profileKeybindings = self.getKeybindings(self.profile) if self.profile else {} - for key, value in keybindings.items(): - if value != profileKeybindings.get(key): - appKeybindings[key] = value - - self._backend.saveAppSettings(appName, - self.profile, - appGeneral, - appPronunciations, - appKeybindings) - - def saveSettings(self, script: Script, general: Dict[str, Any], pronunciations: Dict[str, Any], keybindings: Dict[str, Any]) -> Optional[bool]: - """Save the settings provided for the script provided.""" - - tokens = ["SETTINGS MANAGER: Saving settings for", script, "(app:", script.app, ")"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - app = script.app - if app: - appName = AXObject.get_name(app) - if appName: - self._saveAppSettings(appName, general, pronunciations, keybindings) - return None - - # Assign current profile - _profile = general.get('profile', settings.profile) - currentProfile = _profile[1] - - self.profile = currentProfile - self._ensurePluginPersistenceSettings(general) - - # Elements that need to stay updated in main configuration. - self.defaultGeneral['startingProfile'] = general.get('startingProfile', - _profile) - - self.saveProfileSettings(general, pronunciations, keybindings) - - tokens = ["SETTINGS MANAGER: Saving for backend", self._backend] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - tokens = ["SETTINGS MANAGER: Settings for", script, "(app:", script.app, ") saved"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return self._enableAccessibility() - - def _adjustBindingTupleValues(self, bindingTuple: tuple) -> tuple: - """Converts the values of bindingTuple into KeyBinding-ready values.""" - - keysym, mask, mods, clicks = bindingTuple - if not keysym: - bindingTuple = ('', 0, 0, 0) - else: - bindingTuple = (keysym, int(mask), int(mods), int(clicks)) - - return bindingTuple - - def overrideKeyBindings(self, script: Script, scriptKeyBindings: Any) -> Any: - keybindingsSettings = self.profileKeybindings - for handlerString, bindingTuples in keybindingsSettings.items(): - handler: Optional[InputEventHandler] = script.inputEventHandlers.get(handlerString) - if not handler: - continue - - scriptKeyBindings.removeByHandler(handler) - for bindingTuple in bindingTuples: - bindingTuple = self._adjustBindingTupleValues(bindingTuple) - keysym, mask, mods, clicks = bindingTuple - newBinding = KeyBinding(keysym, mask, mods, handler, clicks) - scriptKeyBindings.add(newBinding) - - return scriptKeyBindings - - def isFirstStart(self) -> bool: - """Check if the firstStart key is True or false""" - if self._backend: - return self._backend.isFirstStart() - return False - - def setFirstStart(self, value: bool = False) -> None: - """Set firstStart. This user-configurable setting is primarily - intended to serve as an indication as to whether or not initial - configuration is needed.""" - if self._backend: - self._backend.setFirstStart(value) - - def availableProfiles(self) -> List[str]: - """Get available profiles from active backend""" - if self._backend: - return self._backend.availableProfiles() - return [] - - def getAppSetting(self, app: Any, settingName: str, fallbackOnDefault: bool = True) -> Any: - if not app or not self._backend: - return None - - appPrefs = self._backend.getAppSettings(AXObject.get_name(app)) - profiles = appPrefs.get('profiles', {}) - profilePrefs = profiles.get(self.profile, {}) - general = profilePrefs.get('general', {}) - appSetting = general.get(settingName) - if appSetting is None and fallbackOnDefault and self.profile: - general = self._backend.getGeneral(self.profile) - appSetting = general.get(settingName) - - return appSetting - - def loadAppSettings(self, script: Script) -> None: - """Load the users application specific settings for an app. - - Arguments: - - script: the current active script. - """ - - if not (script and script.app): - return - - if not self._backend: - return - - for key in list(self._appPronunciations.keys()): - if key in self.pronunciations: - self.pronunciations.pop(key) - - prefs = self._backend.getAppSettings(AXObject.get_name(script.app)) - profiles = prefs.get('profiles', {}) - profilePrefs = profiles.get(self.profile, {}) - - self._appGeneral = profilePrefs.get('general', {}) - self._appKeybindings = profilePrefs.get('keybindings', {}) - self._appPronunciations = profilePrefs.get('pronunciations', {}) - self._activeApp = AXObject.get_name(script.app) or "" - - self._loadProfileSettings() - self._mergeSettings() - self._setSettingsRuntime(self.general) - self._setPronunciationsRuntime(self.pronunciations) - script.keyBindings = self.overrideKeyBindings(script, script.getKeyBindings()) - -_managerInstance: Optional[SettingsManager] = None - -def getManager() -> Optional[SettingsManager]: - """Get the settings manager instance. Compatibility function. - - This function provides backward compatibility for existing code that uses - settings_manager.getManager(). Returns None during initial import phase, - and the actual instance once cthulhuApp is initialized. - - Code should check for None or call this lazily when actually needed. - """ - global _managerInstance - if _managerInstance is None: - try: - from . import cthulhu - if cthulhu.cthulhuApp: - _managerInstance = cthulhu.cthulhuApp.settingsManager - except (ImportError, AttributeError): - # During import phase, cthulhuApp may not exist yet - pass - return _managerInstance diff --git a/src/cthulhu/signal_manager.py b/src/cthulhu/signal_manager.py deleted file mode 100644 index 762e3a6..0000000 --- a/src/cthulhu/signal_manager.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import gi -from gi.repository import GObject -from typing import Optional, Any, Callable, Tuple - -from cthulhu import resource_manager - -class SignalManager: - def __init__(self, app: Any) -> None: # app is CthulhuApp instance - self.app: Any = app - self.resourceManager: Any = self.app.getResourceManager() # ResourceManager - - def registerSignal( - self, - signalName: str, - signalFlag: GObject.SignalFlags = GObject.SignalFlags.RUN_LAST, - closure: Any = GObject.TYPE_NONE, - accumulator: Tuple = (), - contextName: Optional[str] = None - ) -> bool: - # register signal - ok = False - if not self.signalExist(signalName): - GObject.signal_new(signalName, self.app, signalFlag, closure, accumulator) - ok = True - resourceContext = self.resourceManager.getResourceContext(contextName) - if resourceContext: - resourceEntry = resource_manager.ResourceEntry('signal', signalName, signalName, signalName, signalName) - resourceContext.addSignal(signalName, resourceEntry) - return ok - - def signalExist(self, signalName: str) -> bool: - return GObject.signal_lookup(signalName, self.app) != 0 - - def connectSignal( - self, - signalName: str, - function: Callable, - profile: Any, - param: Optional[Any] = None, - contextName: Optional[str] = None - ) -> Optional[int]: - signalID = None - try: - if self.signalExist(signalName): - tryFunction = resource_manager.TryFunction(function) - signalID = self.app.connect(signalName, tryFunction.runSignal) - resourceContext = self.resourceManager.getResourceContext(contextName) - if resourceContext: - resourceEntry = resource_manager.ResourceEntry('subscription', signalID, function, tryFunction, signalName) - resourceContext.addSubscription(signalName, function, resourceEntry) - else: - print('signal {} does not exist'.format(signalName)) - except Exception as e: - print(e) - - return signalID - - def disconnectSignalByFunction(self, function: Callable, contextName: Optional[str] = None) -> bool: - ok = False - try: - self.app.disconnect_by_func(function) - ok = True - except: - pass - resourceContext = self.resourceManager.getResourceContext(contextName) - if resourceContext: - resourceContext.removeSubscriptionByFunction(function) - return ok - - def emitSignal(self, signalName: str, *args: Any) -> None: - # emit a signal with optional arguments - try: - self.app.emit(signalName, *args) - print('after Emit Signal: {}'.format(signalName)) - except: - print('Signal "{}" does not exist.'.format(signalName)) diff --git a/src/cthulhu/sleep_mode_manager.py b/src/cthulhu/sleep_mode_manager.py deleted file mode 100644 index 75c3f45..0000000 --- a/src/cthulhu/sleep_mode_manager.py +++ /dev/null @@ -1,303 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2024 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Module for sleep mode management.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import time -import os -from gi.repository import GLib -from tomlkit import parse -import cthulhu.braille as braille -import cthulhu.cmdnames as cmdnames -import cthulhu.debug as debug -import cthulhu.input_event as input_event -import cthulhu.keybindings as keybindings -import cthulhu.messages as messages -import cthulhu.script_manager as script_manager -from cthulhu.ax_object import AXObject - -class SleepModeManager: - """Provides sleep mode implementation.""" - - def __init__(self): - self._handlers = self.getHandlers(True) - self._bindings = keybindings.KeyBindings() - self._apps = set() - self._disabledAutoSleepApps = set() - self._autoSleepAppNames = set() - self._autoSleepPath = self._getAutoSleepPath() - self._autoSleepConfigMTime = None - self._loadAutoSleepConfig() - self._lastToggleTime = 0 - self._toggleDebounceDelay = 0.1 # 100ms debounce (reduced for better responsiveness) - - def getBindings(self, refresh=False, isDesktop=True): - """Returns the sleep-mode-manager keybindings.""" - - if refresh: - msg = f"SLEEP MODE MANAGER: Refreshing bindings. Is desktop: {isDesktop}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._setupBindings() - elif len(self._bindings.keyBindings) == 0: - self._setupBindings() - - return self._bindings - - def getHandlers(self, refresh=False): - """Returns the sleep-mode-manager handlers.""" - - if refresh: - msg = "SLEEP MODE MANAGER: Refreshing handlers." - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._setupHandlers() - - return self._handlers - - def isActiveForApp(self, app): - """Returns True if sleep mode is active for app.""" - - if not app: - return False - - appHash = hash(app) - result = appHash in self._apps - if not result and self._isAutoSleepConfiguredForApp(app): - result = appHash not in self._disabledAutoSleepApps - - if result: - tokens = ["SLEEP MODE MANAGER: Is active for", app] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return result - - def _getAutoSleepPath(self): - prefsDir = os.path.join(GLib.get_user_data_dir(), "cthulhu") - try: - from . import cthulhu - app = cthulhu.cthulhuApp - if app and app.settingsManager: - configuredDir = app.settingsManager.getPrefsDir() - if configuredDir: - prefsDir = configuredDir - except Exception: - pass - return os.path.join(prefsDir, "sleep.toml") - - def _refreshAutoSleepPath(self): - latestPath = self._getAutoSleepPath() - if latestPath != self._autoSleepPath: - self._autoSleepPath = latestPath - self._autoSleepConfigMTime = None - self._loadAutoSleepConfig() - return - - try: - latestMTime = os.path.getmtime(self._autoSleepPath) - except OSError: - latestMTime = None - - if latestMTime != self._autoSleepConfigMTime: - self._loadAutoSleepConfig() - - def refreshAutoSleepConfig(self): - """Refresh auto-sleep config if prefs directory has changed.""" - - self._refreshAutoSleepPath() - - def _loadAutoSleepConfig(self): - self._autoSleepAppNames = set() - self._autoSleepConfigMTime = None - - if not os.path.isfile(self._autoSleepPath): - msg = f"SLEEP MODE MANAGER: No sleep config at {self._autoSleepPath}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - try: - self._autoSleepConfigMTime = os.path.getmtime(self._autoSleepPath) - except OSError: - self._autoSleepConfigMTime = None - - try: - with open(self._autoSleepPath, "r", encoding="utf-8") as configFile: - config = parse(configFile.read() or "") - except Exception as error: - tokens = ["SLEEP MODE MANAGER: Failed to parse", self._autoSleepPath, ":", error] - debug.printTokens(debug.LEVEL_WARNING, tokens, True) - return - - appNames = [] - topLevelApps = config.get("apps", []) - if isinstance(topLevelApps, list): - appNames.extend(topLevelApps) - - sleepSection = config.get("sleep", {}) - if isinstance(sleepSection, dict): - sectionApps = sleepSection.get("apps", []) - if isinstance(sectionApps, list): - appNames.extend(sectionApps) - - for appName in appNames: - if not isinstance(appName, str): - continue - normalizedName = appName.strip().lower() - if normalizedName: - self._autoSleepAppNames.add(normalizedName) - - msg = f"SLEEP MODE MANAGER: Loaded {len(self._autoSleepAppNames)} auto-sleep apps from {self._autoSleepPath}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _isAutoSleepConfiguredForApp(self, app): - if not app: - return False - - if not self._autoSleepAppNames: - return False - - appName = (AXObject.get_name(app) or "").strip().lower() - return bool(appName and appName in self._autoSleepAppNames) - - def _setupHandlers(self): - """Sets up and returns the sleep-mode-manager input event handlers.""" - - self._handlers = {} - - self._handlers["toggleSleepMode"] = \ - input_event.InputEventHandler( - self.toggleSleepMode, - cmdnames.TOGGLE_SLEEP_MODE) - - msg = "SLEEP MODE MANAGER: Handlers set up." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _setupBindings(self): - """Sets up and returns the sleep-mode-manager key bindings.""" - - self._bindings = keybindings.KeyBindings() - - self._bindings.add( - keybindings.KeyBinding( - "q", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK | keybindings.SHIFT_MODIFIER_MASK, - self._handlers["toggleSleepMode"])) - - msg = "SLEEP MODE MANAGER: Bindings set up." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def toggleSleepMode(self, script, inputEvent=None, notifyUser=True): - """Toggles sleep mode for the active application.""" - - tokens = ["SLEEP MODE MANAGER: toggleSleepMode. Script:", script, - "Event:", inputEvent, "notifyUser:", notifyUser] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # Debounce rapid key presses - currentTime = time.time() - timeSinceLastToggle = currentTime - self._lastToggleTime - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Toggle attempt - time since last: {timeSinceLastToggle:.3f}s", True) - - if timeSinceLastToggle < self._toggleDebounceDelay: - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Ignoring rapid toggle (delay: {timeSinceLastToggle:.3f}s < {self._toggleDebounceDelay}s)", True) - return True - - self._lastToggleTime = currentTime - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Processing toggle - app: {AXObject.get_name(script.app) if script and script.app else 'None'}", True) - - if not (script and script.app): - return True - - self.refreshAutoSleepConfig() - - scriptManager = script_manager.get_manager() - - if self.isActiveForApp(script.app): - # Turning OFF sleep mode - appHash = hash(script.app) - self._apps.discard(appHash) - if self._isAutoSleepConfiguredForApp(script.app): - self._disabledAutoSleepApps.add(appHash) - newScript = scriptManager.get_script(script.app) - if notifyUser: - newScript.presentMessage( - messages.SLEEP_MODE_DISABLED_FOR % AXObject.get_name(script.app)) - scriptManager.set_active_script(newScript, "sleep: off") - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Disabled for {AXObject.get_name(script.app)}", True) - # Reset debounce timer after successful toggle - self._lastToggleTime = 0 - return True - - # Turning ON sleep mode - braille.clear() - if notifyUser: - # Announce BEFORE switching to sleep mode script - script.presentMessage(messages.SLEEP_MODE_ENABLED_FOR % AXObject.get_name(script.app)) - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Scheduling delayed activation for {AXObject.get_name(script.app)}", True) - # Use a small delay to ensure the message is spoken before switching scripts - GLib.timeout_add(250, self._enableSleepModeDelayed, script, scriptManager) - else: - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Immediate activation for {AXObject.get_name(script.app)}", True) - self._enableSleepModeDelayed(script, scriptManager) - - return True - - def _enableSleepModeDelayed(self, script, scriptManager): - """Enable sleep mode after a small delay to allow announcement.""" - - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: _enableSleepModeDelayed called for {AXObject.get_name(script.app) if script and script.app else 'None'}", True) - - try: - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Getting sleep script for {AXObject.get_name(script.app)}", True) - sleepScript = scriptManager.get_or_create_sleep_mode_script(script.app) - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Got sleep script: {sleepScript}", True) - - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Setting active script", True) - scriptManager.set_active_script(sleepScript, "sleep: on") - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Active script set successfully", True) - - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Adding app to sleep list", True) - appHash = hash(script.app) - self._disabledAutoSleepApps.discard(appHash) - self._apps.add(appHash) - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Enabled for {AXObject.get_name(script.app)} (delayed)", True) - # Reset debounce timer after successful toggle - self._lastToggleTime = 0 - except Exception as e: - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Error enabling delayed: {e}", True) - import traceback - debug.printMessage(debug.LEVEL_INFO, f"SLEEP MODE: Exception traceback: {traceback.format_exc()}", True) - - return False # Don't repeat the timeout - - -_manager = SleepModeManager() - -def getManager(): - """Returns the Sleep Mode Manager singleton.""" - return _manager diff --git a/src/cthulhu/sound.py b/src/cthulhu/sound.py deleted file mode 100644 index bf44a6a..0000000 --- a/src/cthulhu/sound.py +++ /dev/null @@ -1,628 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Utilities for playing sounds.""" - -__id__ = "$Id:$" -__version__ = "$Revision:$" -__date__ = "$Date:$" -__copyright__ = "Copyright (c) 2016 Cthulhu Team" -__license__ = "LGPL" - -import json -import os -import subprocess -import sys -import threading -from typing import Any, Optional, Tuple - -import gi -from . import debug -from . import gstreamer_support -from . import settings -from . import sound_sink -from .sound_generator import Icon, Tone - -try: - gi.require_version('Gst', '1.0') - from gi.repository import Gst -except Exception: - _gstreamerAvailable: bool = False -else: - _gstreamerAvailable = gstreamer_support.gst_init_check_available(Gst) - -_soundSystemFailureReason: Optional[str] = None - - -class _PendingResponse: - def __init__(self) -> None: - self.event = threading.Event() - self.response: Optional[dict[str, Any]] = None - - -class Player: - """Plays Icons and Tones through a persistent worker process.""" - - def __init__(self) -> None: - self._initialized = False - self._workerProcess: Optional[subprocess.Popen[str]] = None - self._workerSink: Optional[str] = None - self._workerRestartRequired = False - self._workerRestartReason: Optional[str] = None - self._workerLock = threading.RLock() - self._responseLock = threading.Lock() - self._pendingResponses: dict[int, _PendingResponse] = {} - self._nextRequestId = 1 - - if not _gstreamerAvailable: - debug.printMessage(debug.LEVEL_INFO, 'SOUND ERROR: Gstreamer is not available', True) - return - - @staticmethod - def _get_configured_volume() -> float: - """Returns the configured sound volume with a safe fallback.""" - - try: - from . import cthulhu - if cthulhu.cthulhuApp is not None: - volume = cthulhu.cthulhuApp.settingsManager.getSetting('soundVolume') - return max(0.0, float(volume)) - except Exception: - pass - - return max(0.0, float(settings.soundVolume)) - - def init(self) -> None: - """(Re)Initializes the persistent worker.""" - - if not _gstreamerAvailable: - return - - with self._workerLock: - if self._ensureWorkerLocked(): - self._initialized = True - clearSoundSystemFailure() - - def play(self, item: Any, interrupt: bool = True) -> None: - """Plays a sound, interrupting the current play first unless specified.""" - - if isinstance(item, Icon): - self._playIcon(item, interrupt) - elif isinstance(item, Tone): - self._playTone(item, interrupt) - else: - debug.printTokens(debug.LEVEL_INFO, ["SOUND ERROR:", item, "is not an Icon or Tone"], True) - - def playAndWait(self, item: Any, interrupt: bool = True, timeout_seconds: int = 10) -> bool: - """Plays a sound and blocks until completion or timeout.""" - - if isinstance(item, Icon): - return self._playIconAndWait(item, interrupt=interrupt, timeout_seconds=timeout_seconds) - if isinstance(item, Tone): - return self._playToneAndWait(item, interrupt=interrupt, timeout_seconds=timeout_seconds) - self.play(item, interrupt) - return False - - def stop(self, _element: Any = None) -> None: - """Stops current sound playback.""" - - with self._workerLock: - if self._workerProcess is None or self._workerProcess.poll() is not None: - return - - self._sendWorkerCommand({"action": "stop"}, waitForResponse=False) - - def shutdown(self) -> None: - """Shuts down the sound utilities.""" - - if not _gstreamerAvailable: - return - - with self._workerLock: - self._stopWorkerLocked("Sound system shutdown") - self._initialized = False - - def get_debug_snapshot(self) -> dict[str, Any]: - """Returns read-only sound worker state for runtime diagnostics.""" - - with self._workerLock: - process = self._workerProcess - workerExitStatus: Any = "" - workerAlive = False - workerPid = 0 - if process is not None: - workerPid = process.pid - workerExitStatus = process.poll() - workerAlive = workerExitStatus is None - - with self._responseLock: - pendingResponseCount = len(self._pendingResponses) - - return { - "gstreamer_available": _gstreamerAvailable, - "sound_system_available": isSoundSystemAvailable(), - "failure_reason": getSoundSystemFailureReason() or "", - "initialized": self._initialized, - "worker_present": process is not None, - "worker_alive": workerAlive, - "worker_pid": workerPid, - "worker_exit_status": workerExitStatus if workerExitStatus is not None else "", - "worker_sink": self._workerSink or "", - "worker_restart_required": self._workerRestartRequired, - "worker_restart_reason": self._workerRestartReason or "", - "pending_responses": pendingResponseCount, - } - - def _playIcon(self, icon: Icon, interrupt: bool = True) -> None: - if not icon.isValid(): - return - - success, reason = self._sendWorkerCommand( - { - "action": "play_file", - "path": icon.path, - "volume": self._get_configured_volume(), - "interrupt": interrupt, - "pan": getattr(icon, "pan", 0.0), - }, - waitForResponse=False, - ) - if not success and reason: - debug.printMessage(debug.LEVEL_INFO, f"SOUND ERROR: {reason}", True) - - def _playIconAndWait( - self, - icon: Icon, - interrupt: bool = True, - timeout_seconds: Optional[int] = 10, - ) -> bool: - if not icon.isValid(): - return False - - timeout = float((timeout_seconds or 10) + 2) - success, reason = self._sendWorkerCommand( - { - "action": "play_file", - "path": icon.path, - "volume": self._get_configured_volume(), - "interrupt": interrupt, - "pan": getattr(icon, "pan", 0.0), - }, - waitForResponse=True, - timeout=timeout, - ) - if not success and reason: - debug.printMessage(debug.LEVEL_INFO, f"SOUND ERROR: {reason}", True) - return success - - def _playTone(self, tone: Tone, interrupt: bool = True) -> None: - success, reason = self._sendWorkerCommand( - self._buildToneCommand(tone, interrupt), - waitForResponse=False, - ) - if not success and reason: - debug.printMessage(debug.LEVEL_INFO, f"SOUND ERROR: {reason}", True) - - def _playToneAndWait( - self, - tone: Tone, - interrupt: bool = True, - timeout_seconds: Optional[int] = 10, - ) -> bool: - timeout = max(float(timeout_seconds or 10), float(tone.duration) + 2.0) - success, reason = self._sendWorkerCommand( - self._buildToneCommand(tone, interrupt), - waitForResponse=True, - timeout=timeout, - ) - if not success and reason: - debug.printMessage(debug.LEVEL_INFO, f"SOUND ERROR: {reason}", True) - return success - - def _buildToneCommand(self, tone: Tone, interrupt: bool) -> dict[str, Any]: - return { - "action": "play_tone", - "duration": tone.duration, - "frequency": tone.frequency, - "volume": tone.volume, - "wave": tone.wave, - "pan": getattr(tone, "pan", 0.0), - "interrupt": interrupt, - } - - def _ensureWorkerLocked(self) -> bool: - configuredSink = sound_sink.get_configured_sound_sink() - - if self._workerProcess is not None and self._workerProcess.poll() is None: - if self._workerRestartRequired: - reason = self._consumeWorkerRestartReason() - debug.printMessage( - debug.LEVEL_INFO, - f"SOUND: Restarting persistent worker after recovery request: {reason}", - True, - ) - self._stopWorkerLocked(reason) - elif self._workerSink == configuredSink: - return True - else: - debug.printMessage( - debug.LEVEL_INFO, - f"SOUND: Restarting persistent worker for soundSink={configuredSink}", - True, - ) - self._stopWorkerLocked("Sound sink changed") - - return self._startWorkerLocked(configuredSink) - - def _startWorkerLocked(self, configuredSink: str) -> bool: - environment = _buildSoundHelperEnvironment() - command = [ - sys.executable, - "-m", - "cthulhu.sound_helper", - "--worker", - "--sound-sink", - configuredSink, - ] - - try: - process = subprocess.Popen( - command, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - bufsize=1, - env=environment, - ) - except Exception as error: - reason = f"Failed to start persistent sound worker: {error}" - disableSoundSystem(reason) - debug.printMessage(debug.LEVEL_INFO, f"SOUND ERROR: {reason}", True) - return False - - if process.stdin is None or process.stdout is None or process.stderr is None: - try: - process.terminate() - except Exception: - pass - reason = "Persistent sound worker is missing stdio pipes" - disableSoundSystem(reason) - debug.printMessage(debug.LEVEL_INFO, f"SOUND ERROR: {reason}", True) - return False - - self._workerProcess = process - self._workerSink = configuredSink - self._workerRestartRequired = False - self._workerRestartReason = None - self._startWorkerThreads(process) - - success, reason = self._sendWorkerCommandLocked( - {"action": "ping"}, - waitForResponse=True, - timeout=2.0, - allowRestart=False, - ) - if not success: - self._stopWorkerLocked(reason or "Persistent sound worker failed to initialize") - disableSoundSystem(reason or "Persistent sound worker failed to initialize") - if reason: - debug.printMessage(debug.LEVEL_INFO, f"SOUND ERROR: {reason}", True) - return False - - debug.printMessage( - debug.LEVEL_INFO, - f"SOUND: Using persistent worker for icon playback (soundSink={configuredSink})", - True, - ) - debug.printMessage( - debug.LEVEL_INFO, - f"SOUND: Using persistent worker for tone playback (soundSink={configuredSink})", - True, - ) - return True - - def _startWorkerThreads(self, process: subprocess.Popen[str]) -> None: - threading.Thread( - target=self._readWorkerStdout, - args=(process,), - daemon=True, - ).start() - threading.Thread( - target=self._readWorkerStderr, - args=(process,), - daemon=True, - ).start() - threading.Thread( - target=self._watchWorkerExit, - args=(process,), - daemon=True, - ).start() - - def _readWorkerStdout(self, process: subprocess.Popen[str]) -> None: - assert process.stdout is not None - for line in process.stdout: - line = line.strip() - if not line: - continue - try: - response = json.loads(line) - except Exception: - debug.printMessage(debug.LEVEL_INFO, f"SOUND ERROR: Invalid worker response: {line}", True) - continue - - requestId = response.get("id") - if requestId is None: - continue - - with self._responseLock: - pending = self._pendingResponses.pop(int(requestId), None) - - if pending is None: - continue - - pending.response = response - pending.event.set() - - def _readWorkerStderr(self, process: subprocess.Popen[str]) -> None: - assert process.stderr is not None - for line in process.stderr: - message = line.strip() - if message: - self._handleWorkerDiagnostic(message) - debug.printMessage(debug.LEVEL_INFO, f"SOUND WORKER: {message}", True) - - def _watchWorkerExit(self, process: subprocess.Popen[str]) -> None: - returnCode = process.wait() - reason = _formatWorkerFailure(returnCode) - - with self._workerLock: - if self._workerProcess is process: - self._workerProcess = None - self._workerSink = None - - self._failPendingResponses(reason) - - if returnCode != 0: - debug.printMessage(debug.LEVEL_INFO, f"SOUND ERROR: {reason}", True) - - def _failPendingResponses(self, reason: str) -> None: - with self._responseLock: - pendingResponses = list(self._pendingResponses.values()) - self._pendingResponses.clear() - - for pending in pendingResponses: - pending.response = {"ok": False, "error": reason} - pending.event.set() - - def _stopWorkerLocked(self, reason: str) -> None: - process = self._workerProcess - self._workerProcess = None - self._workerSink = None - self._workerRestartRequired = False - self._workerRestartReason = None - - if process is None: - return - - if process.poll() is None: - try: - assert process.stdin is not None - process.stdin.write(json.dumps({"action": "shutdown"}) + "\n") - process.stdin.flush() - process.wait(timeout=1.0) - except Exception: - try: - process.terminate() - process.wait(timeout=1.0) - except Exception: - try: - process.kill() - process.wait(timeout=1.0) - except Exception: - pass - - self._failPendingResponses(reason) - - def _sendWorkerCommand( - self, - command: dict[str, Any], - waitForResponse: bool, - timeout: float = 2.0, - ) -> Tuple[bool, Optional[str]]: - with self._workerLock: - return self._sendWorkerCommandLocked(command, waitForResponse, timeout) - - def _sendWorkerCommandLocked( - self, - command: dict[str, Any], - waitForResponse: bool, - timeout: float = 2.0, - allowRestart: bool = True, - ) -> Tuple[bool, Optional[str]]: - if not self._ensureWorkerLocked(): - return False, getSoundSystemFailureReason() or "Persistent sound worker is unavailable" - - process = self._workerProcess - if process is None or process.stdin is None: - if allowRestart: - self._stopWorkerLocked("Worker pipes disappeared") - if self._ensureWorkerLocked(): - return self._sendWorkerCommandLocked(command, waitForResponse, timeout, allowRestart=False) - return False, "Persistent sound worker stdin is unavailable" - - requestId: Optional[int] = None - pending: Optional[_PendingResponse] = None - payload = dict(command) - - if waitForResponse: - requestId = self._allocateRequestId() - pending = _PendingResponse() - payload["id"] = requestId - with self._responseLock: - self._pendingResponses[requestId] = pending - - try: - process.stdin.write(json.dumps(payload) + "\n") - process.stdin.flush() - except Exception as error: - if requestId is not None: - with self._responseLock: - self._pendingResponses.pop(requestId, None) - if allowRestart: - self._stopWorkerLocked(f"Worker write failed: {error}") - if self._ensureWorkerLocked(): - return self._sendWorkerCommandLocked(command, waitForResponse, timeout, allowRestart=False) - return False, f"Worker write failed: {error}" - - if not waitForResponse or pending is None: - return True, None - - if pending.event.wait(timeout): - response = pending.response or {"ok": False, "error": "No worker response"} - if not bool(response.get("ok")): - self._maybeMarkWorkerRestartRequired(response.get("error")) - return bool(response.get("ok")), response.get("error") - - with self._responseLock: - self._pendingResponses.pop(requestId, None) - - if allowRestart and (self._workerProcess is None or self._workerProcess.poll() is not None): - self._stopWorkerLocked("Worker exited while waiting for response") - if self._ensureWorkerLocked(): - return self._sendWorkerCommandLocked(command, waitForResponse, timeout, allowRestart=False) - - reason = f"Persistent sound worker timed out after {timeout:.1f} seconds" - self._markWorkerRestartRequired(reason) - return False, reason - - def _allocateRequestId(self) -> int: - with self._responseLock: - requestId = self._nextRequestId - self._nextRequestId += 1 - return requestId - - def _handleWorkerDiagnostic(self, message: str) -> None: - normalizedMessage = str(message).strip() - if not normalizedMessage.startswith("RECOVERY REQUIRED:"): - return - - reason = normalizedMessage.split(":", 1)[1].strip() or "Worker requested recovery" - self._markWorkerRestartRequired(reason) - - def _markWorkerRestartRequired(self, reason: Optional[str]) -> None: - normalizedReason = str(reason or "").strip() or "Worker requested recovery" - with self._workerLock: - self._workerRestartRequired = True - self._workerRestartReason = normalizedReason - - def _consumeWorkerRestartReason(self) -> str: - reason = self._workerRestartReason or "Worker requested recovery" - self._workerRestartRequired = False - self._workerRestartReason = None - return reason - - def _maybeMarkWorkerRestartRequired(self, reason: Optional[str]) -> None: - normalizedReason = str(reason or "").strip().lower() - if normalizedReason in {"", "interrupted", "stopped", "shutdown", "stdin closed"}: - return - - self._markWorkerRestartRequired(reason) - - -def disableSoundSystem(reason: str) -> None: - global _soundSystemFailureReason - - if _soundSystemFailureReason == reason: - return - - _soundSystemFailureReason = reason - debug.printMessage(debug.LEVEL_INFO, f"SOUND: Disabling sound system. Reason: {reason}", True) - - -def getSoundSystemFailureReason() -> Optional[str]: - return _soundSystemFailureReason - - -def isSoundSystemAvailable() -> bool: - return _soundSystemFailureReason is None - - -def clearSoundSystemFailure() -> None: - global _soundSystemFailureReason - _soundSystemFailureReason = None - - -def _buildSoundHelperEnvironment() -> dict[str, str]: - pythonPathEntries = [] - for path in sys.path: - if not path: - path = os.getcwd() - if os.path.isdir(path) and path not in pythonPathEntries: - pythonPathEntries.append(path) - - environment = os.environ.copy() - if pythonPathEntries: - environment["PYTHONPATH"] = os.pathsep.join(pythonPathEntries) - environment.setdefault("ORC_CODE", "backup") - return environment - - -def _formatWorkerFailure(returnCode: int) -> str: - if returnCode < 0: - return f"Sound worker exited via signal {-returnCode}" - return f"Sound worker exited with status {returnCode}" - - -_player = Player() - - -def getPlayer() -> Player: - return _player - - -def get_debug_snapshot() -> dict[str, Any]: - return _player.get_debug_snapshot() - - -def play(item: Any, interrupt: bool = True) -> None: - _player.play(item, interrupt) - - -def playIconSafely(icon: Icon, timeoutSeconds: int = 10) -> Tuple[bool, Optional[str]]: - if not icon.isValid(): - return False, f"Invalid sound icon: {icon.path}" - - return _player._sendWorkerCommand( - { - "action": "play_file", - "path": icon.path, - "volume": Player._get_configured_volume(), - "interrupt": True, - "pan": getattr(icon, "pan", 0.0), - }, - waitForResponse=True, - timeout=max(0.1, float(timeoutSeconds)), - ) diff --git a/src/cthulhu/sound_generator.py b/src/cthulhu/sound_generator.py deleted file mode 100644 index 411a7b7..0000000 --- a/src/cthulhu/sound_generator.py +++ /dev/null @@ -1,405 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Utilities for obtaining sounds to be presented for objects.""" - -__id__ = "$Id:$" -__version__ = "$Revision:$" -__date__ = "$Date:$" -__copyright__ = "Copyright (c) 2016 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version('Atspi', '2.0') -from gi.repository import Atspi - -import os - -from . import cthulhu # Need access to cthulhuApp -from . import generator -from . import role_keys -from . import settings_manager -from .ax_object import AXObject -from .ax_utilities import AXUtilities - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -METHOD_PREFIX = "_generate" - - -class Icon: - """Sound file representing a particular aspect of an object.""" - - def __init__(self, location, filename, pan=0.0): - self.path = os.path.join(location, filename) - self.pan = max(-1.0, min(1.0, float(pan))) - - def __str__(self): - return f'Icon(path: {self.path}, isValid: {self.isValid()})' - - def isValid(self): - return os.path.isfile(self.path) - -class Tone: - """Tone representing a particular aspect of an object.""" - - SINE_WAVE = 0 - SQUARE_WAVE = 1 - SAW_WAVE = 2 - TRIANGLE_WAVE = 3 - SILENCE = 4 - WHITE_UNIFORM_NOISE = 5 - PINK_NOISE = 6 - SINE_WAVE_USING_TABLE = 7 - PERIODIC_TICKS = 8 - WHITE_GAUSSIAN_NOISE = 9 - RED_NOISE = 10 - INVERTED_PINK_NOISE = 11 - INVERTED_RED_NOISE = 12 - - def __init__(self, duration, frequency, volumeMultiplier=1, wave=SINE_WAVE): - self.duration = duration - self.frequency = min(max(0, frequency), 20000) - self.volume = cthulhu.cthulhuApp.settingsManager.getSetting('soundVolume') * volumeMultiplier - self.wave = wave - self.pan = 0.0 - - def __str__(self): - return 'Tone(duration: %s, frequency: %s, volume: %s, wave: %s)' \ - % (self.duration, self.frequency, self.volume, self.wave) - -class SoundGenerator(generator.Generator): - """Takes accessible objects and produces the sound(s) to be played.""" - - def __init__(self, script): - super().__init__(script, 'sound') - self._sounds = os.path.join(cthulhu.cthulhuApp.settingsManager.getPrefsDir(), 'sounds') - - def _convertFilenameToIcon(self, filename): - icon = Icon(self._sounds, filename) - if icon.isValid(): - return icon - - return None - - def generateSound(self, obj, **args): - """Returns an array of sounds for the complete presentation of obj.""" - - result = self.generate(obj, **args) - return self._spatializeSounds(result, obj) - - def _spatializeSounds(self, sounds, obj): - if not cthulhu.cthulhuApp.settingsManager.getSetting('spatializeObjectSounds'): - return sounds - - spatialize = getattr(self._script.utilities, "spatializeSoundIcon", None) - if spatialize is None: - return sounds - - result = [] - for sound in sounds or []: - if isinstance(sound, list): - result.append(self._spatializeSounds(sound, obj)) - else: - result.append(spatialize(sound, obj)) - return result - - ##################################################################### - # # - # State information # - # # - ##################################################################### - - def _generateAvailability(self, obj, **args): - """Returns an array of sounds indicating obj is grayed out.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateAvailability(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateCheckedState(self, obj, **args): - """Returns an array of sounds indicating the checked state of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateCheckedState(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateClickable(self, obj, **args): - """Returns an array of sounds indicating obj is clickable.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateClickable(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateExpandableState(self, obj, **args): - """Returns an array of sounds indicating the expanded state of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateExpandableState(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateHasLongDesc(self, obj, **args): - """Returns an array of sounds indicating obj has a longdesc.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateHasLongDesc(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateMenuItemCheckedState(self, obj, **args): - """Returns an array of sounds indicating the checked state of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateMenuItemCheckedState(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateMultiselectableState(self, obj, **args): - """Returns an array of sounds indicating obj is multiselectable.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateMultiselectableState(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateRadioState(self, obj, **args): - """Returns an array of sounds indicating the selected state of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateRadioState(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateReadOnly(self, obj, **args): - """Returns an array of sounds indicating obj is read only.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateReadOnly(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateRequired(self, obj, **args): - """Returns an array of sounds indicating obj is required.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateRequired(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateSwitchState(self, obj, **args): - """Returns an array of sounds indicating the on/off state of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateSwitchState(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateToggleState(self, obj, **args): - """Returns an array of sounds indicating the toggled state of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - filenames = super()._generateToggleState(obj, **args) - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - def _generateVisitedState(self, obj, **args): - """Returns an array of sounds indicating the visited state of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForState'): - return [] - - if not args.get('mode', None): - args['mode'] = self._mode - - args['stringType'] = 'visited' - if AXUtilities.is_visited(obj): - filenames = [self._script.formatting.getString(**args)] - result = list(map(self._convertFilenameToIcon, filenames)) - if result: - return result - - return [] - - ##################################################################### - # # - # Value interface information # - # # - ##################################################################### - - def _generatePercentage(self, obj, **args): - """Returns an array of sounds reflecting the percentage of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForValue'): - return [] - - percent = self._script.utilities.getValueAsPercent(obj) - if percent is None: - return [] - - return [] - - def _generateProgressBarValue(self, obj, **args): - """Returns an array of sounds representing the progress bar value.""" - - if args.get('isProgressBarUpdate'): - if not self._shouldPresentProgressBarUpdate(obj, **args): - return [] - elif not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForValue'): - return [] - - percent = self._script.utilities.getValueAsPercent(obj) - if percent is None: - return [] - - # To better indicate the progress completion. - if percent >= 99: - duration = 1 - else: - duration = 0.075 - - # Reduce volume as pitch increases. - volumeMultiplier = 1 - (percent / 120) - - # Adjusting so that the initial beeps are not too deep. - if percent < 7: - frequency = int(98 + percent * 5.4) - else: - frequency = int(percent * 22) - - return [Tone(duration, frequency, volumeMultiplier, Tone.SINE_WAVE)] - - def _getProgressBarUpdateInterval(self): - interval = cthulhu.cthulhuApp.settingsManager.getSetting('progressBarBeepInterval') - if interval is None: - return super()._getProgressBarUpdateInterval() - - return int(interval) - - def _shouldPresentProgressBarUpdate(self, obj, **args): - if not cthulhu.cthulhuApp.settingsManager.getSetting('beepProgressBarUpdates'): - return False - - return super()._shouldPresentProgressBarUpdate(obj, **args) - - ##################################################################### - # # - # Role and hierarchical information # - # # - ##################################################################### - - def _generatePositionInSet(self, obj, **args): - """Returns an array of sounds reflecting the set position of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForPositionInSet'): - return [] - - # TODO: Implement the result. - # position, setSize = self._script.utilities.getPositionAndSetSize(obj) - # percent = int((position / setSize) * 100) - - return [] - - def _generateRoleName(self, obj, **args): - """Returns an array of sounds indicating the role of obj.""" - - if not cthulhu.cthulhuApp.settingsManager.getSetting('playSoundForRole'): - return [] - - role = args.get('role', AXObject.get_role(obj)) - if isinstance(role, str): - if role == role_keys.ROLE_SWITCH: - role = Atspi.Role.SWITCH - else: - return [] - filename = Atspi.role_get_name(role).replace(' ', '_') - result = self._convertFilenameToIcon(filename) - if result: - return [result] - - return [] diff --git a/src/cthulhu/sound_helper.py b/src/cthulhu/sound_helper.py deleted file mode 100644 index e287232..0000000 --- a/src/cthulhu/sound_helper.py +++ /dev/null @@ -1,466 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -"""Persistent sound helper used to isolate theme and tone playback crashes.""" - -import argparse -from collections import deque -import json -import pathlib -import sys -import threading -from typing import Any, Optional - -import gi - -gi.require_version('GLib', '2.0') -gi.require_version('Gst', '1.0') -from gi.repository import GLib, Gst - -from . import gstreamer_support -from . import settings -from . import sound_sink - - -def _clamp_volume(volume: Any) -> float: - try: - return max(0.0, float(volume)) - except Exception: - return 1.0 - - -def _clamp_pan(pan: Any) -> float: - try: - return max(-1.0, min(1.0, float(pan))) - except Exception: - return 0.0 - - -def _write_json_line(payload: dict[str, Any]) -> None: - sys.stdout.write(json.dumps(payload) + "\n") - sys.stdout.flush() - - -def _report_recovery_required(message: str) -> None: - print(f"RECOVERY REQUIRED: {message}", file=sys.stderr, flush=True) - - -def _create_file_player( - playerId: str, - soundSink: Optional[str] = None, -) -> tuple[Optional[Any], Optional[Any], Optional[str], Optional[str]]: - player = Gst.ElementFactory.make("playbin", playerId) - if player is None: - return None, None, None, "Failed to create playbin for file playback" - - panorama = Gst.ElementFactory.make("audiopanorama", f"{playerId}-panorama") - if panorama is not None: - player.set_property("audio-filter", panorama) - - configuredSink = sound_sink.normalize_sound_sink_choice(soundSink) - if configuredSink == settings.SOUND_SINK_AUTO: - return player, panorama, "playbin-default", None - - audioSink, sinkName, sinkError = sound_sink.create_audio_sink( - f"{playerId}-output", - configuredSink, - ) - if audioSink is None: - return None, panorama, sinkName, sinkError or f"Failed to create audio sink for {configuredSink}" - - player.set_property("audio-sink", audioSink) - return player, panorama, sinkName or configuredSink, None - - -class SoundWorker: - """Runs a long-lived GStreamer worker for icon and tone playback.""" - - def __init__(self, soundSink: Optional[str] = None) -> None: - available = gstreamer_support.gst_init_check_available(Gst) - if not available: - raise RuntimeError("GStreamer is not available") - - self._loop = GLib.MainLoop() - self._queue: deque[dict[str, Any]] = deque() - self._currentCommand: Optional[dict[str, Any]] = None - self._toneTimeoutId = 0 - - self._filePlayer, self._filePanorama, fileSinkName, fileSinkError = _create_file_player( - "cthulhu-sound-worker-file", - soundSink, - ) - if self._filePlayer is None: - raise RuntimeError(fileSinkError or "Failed to create file playback player") - - fileBus = self._filePlayer.get_bus() - if fileBus is None: - raise RuntimeError("No bus available for file playback player") - fileBus.add_signal_watch() - fileBus.connect("message", self._onFileMessage) - - self._tonePipeline = Gst.Pipeline.new('cthulhu-sound-worker-tone') - if self._tonePipeline is None: - raise RuntimeError("Failed to create tone pipeline") - - self._toneSource = Gst.ElementFactory.make('audiotestsrc', 'cthulhu-sound-worker-source') - self._toneVolume = Gst.ElementFactory.make('volume', 'cthulhu-sound-worker-volume') - self._tonePanorama = Gst.ElementFactory.make('audiopanorama', 'cthulhu-sound-worker-panorama') - toneSink, toneSinkName, toneSinkError = sound_sink.create_audio_sink( - 'cthulhu-sound-worker-tone-output', - soundSink - ) - if self._toneSource is None or toneSink is None: - raise RuntimeError(toneSinkError or "Failed to create tone playback pipeline") - - self._toneSink = toneSink - self._tonePipeline.add(self._toneSource) - if self._toneVolume is not None: - self._tonePipeline.add(self._toneVolume) - if self._tonePanorama is not None: - self._tonePipeline.add(self._tonePanorama) - self._tonePipeline.add(self._toneSink) - toneElements = [self._toneSource] - if self._toneVolume is not None: - toneElements.append(self._toneVolume) - if self._tonePanorama is not None: - toneElements.append(self._tonePanorama) - toneElements.append(self._toneSink) - for source, target in zip(toneElements, toneElements[1:]): - if not source.link(target): - raise RuntimeError("Failed to link tone playback pipeline") - - toneBus = self._tonePipeline.get_bus() - if toneBus is None: - raise RuntimeError("No bus available for tone pipeline") - toneBus.add_signal_watch() - toneBus.connect("message", self._onToneMessage) - - self._fileSinkName = fileSinkName or "unknown" - self._toneSinkName = toneSinkName or "unknown" - - def run(self) -> int: - self._report_worker_ready() - readerThread = threading.Thread(target=self._read_commands, daemon=True) - readerThread.start() - try: - self._loop.run() - return 0 - finally: - self._clear_tone_timeout() - self._filePlayer.set_state(Gst.State.NULL) - self._tonePipeline.set_state(Gst.State.NULL) - - def _report_worker_ready(self) -> None: - print( - f"Persistent sound worker ready: file={self._fileSinkName} tone={self._toneSinkName}", - file=sys.stderr, - flush=True, - ) - - def _read_commands(self) -> None: - try: - for line in sys.stdin: - line = line.strip() - if not line: - continue - try: - command = json.loads(line) - except Exception as error: - print(f"Invalid worker command: {error}", file=sys.stderr, flush=True) - continue - GLib.idle_add(self._handle_command, command) - finally: - GLib.idle_add(self._quit_from_stdin_close) - - def _quit_from_stdin_close(self) -> bool: - self._interrupt_current("stdin closed") - self._interrupt_queued("stdin closed") - self._loop.quit() - return False - - def _handle_command(self, command: dict[str, Any]) -> bool: - action = str(command.get("action", "")).strip().lower() - requestId = command.get("id") - - if action == "ping": - self._respond(requestId, True) - return False - - if action == "shutdown": - self._interrupt_current("shutdown") - self._interrupt_queued("shutdown") - self._respond(requestId, True) - self._loop.quit() - return False - - if action == "stop": - self._interrupt_current("stopped") - self._interrupt_queued("stopped") - self._respond(requestId, True) - return False - - if action not in {"play_file", "play_tone"}: - self._respond(requestId, False, f"Unknown worker action: {action}") - return False - - interrupt = bool(command.get("interrupt", True)) - if interrupt: - self._interrupt_current("interrupted") - self._interrupt_queued("interrupted") - elif self._currentCommand is not None: - self._queue.append(command) - return False - - if self._currentCommand is None: - self._start_command(command) - else: - self._queue.appendleft(command) - - return False - - def _start_command(self, command: dict[str, Any]) -> None: - action = command["action"] - if action == "play_file": - self._start_file_command(command) - return - if action == "play_tone": - self._start_tone_command(command) - return - self._respond(command.get("id"), False, f"Unsupported worker action: {action}") - self._start_next_command() - - def _start_file_command(self, command: dict[str, Any]) -> None: - soundPath = pathlib.Path(str(command.get("path", ""))).expanduser() - if not soundPath.is_file(): - self._respond(command.get("id"), False, f"Missing sound file: {soundPath}") - self._start_next_command() - return - - self._clear_tone_timeout() - self._tonePipeline.set_state(Gst.State.NULL) - self._filePlayer.set_state(Gst.State.NULL) - - self._currentCommand = command - self._filePlayer.set_property("uri", soundPath.resolve().as_uri()) - self._filePlayer.set_property("volume", _clamp_volume(command.get("volume", 1.0))) - if self._filePanorama is not None: - self._filePanorama.set_property("panorama", _clamp_pan(command.get("pan", 0.0))) - stateChange = self._filePlayer.set_state(Gst.State.PLAYING) - if stateChange == Gst.StateChangeReturn.FAILURE: - self._currentCommand = None - reason = f"Failed to start playback for {soundPath}" - _report_recovery_required(reason) - self._respond(command.get("id"), False, reason) - self._start_next_command() - - def _start_tone_command(self, command: dict[str, Any]) -> None: - self._filePlayer.set_state(Gst.State.NULL) - self._tonePipeline.set_state(Gst.State.NULL) - self._clear_tone_timeout() - - try: - durationSeconds = max(0.0, float(command.get("duration", 0.0))) - frequency = max(0, min(20000, int(command.get("frequency", 0)))) - wave = int(command.get("wave", 0)) - except Exception as error: - self._respond(command.get("id"), False, f"Invalid tone request: {error}") - self._start_next_command() - return - - self._currentCommand = command - if self._toneVolume is not None: - self._toneVolume.set_property('volume', _clamp_volume(command.get("volume", 1.0))) - self._toneSource.set_property('volume', 1.0) - else: - self._toneSource.set_property('volume', _clamp_volume(command.get("volume", 1.0))) - if self._tonePanorama is not None: - self._tonePanorama.set_property("panorama", _clamp_pan(command.get("pan", 0.0))) - self._toneSource.set_property('freq', frequency) - self._toneSource.set_property('wave', wave) - - stateChange = self._tonePipeline.set_state(Gst.State.PLAYING) - if stateChange == Gst.StateChangeReturn.FAILURE: - self._currentCommand = None - reason = "Failed to start tone playback" - _report_recovery_required(reason) - self._respond(command.get("id"), False, reason) - self._start_next_command() - return - - durationMs = max(1, int(durationSeconds * 1000)) - self._toneTimeoutId = GLib.timeout_add(durationMs, self._finish_tone_playback) - - def _finish_tone_playback(self) -> bool: - self._toneTimeoutId = 0 - self._tonePipeline.set_state(Gst.State.NULL) - self._finish_current(True) - return False - - def _clear_tone_timeout(self) -> None: - if self._toneTimeoutId: - GLib.source_remove(self._toneTimeoutId) - self._toneTimeoutId = 0 - - def _interrupt_current(self, reason: str) -> None: - if self._currentCommand is None: - self._filePlayer.set_state(Gst.State.NULL) - self._tonePipeline.set_state(Gst.State.NULL) - self._clear_tone_timeout() - return - - current = self._currentCommand - self._currentCommand = None - self._filePlayer.set_state(Gst.State.NULL) - self._tonePipeline.set_state(Gst.State.NULL) - self._clear_tone_timeout() - self._respond(current.get("id"), False, reason) - - def _interrupt_queued(self, reason: str) -> None: - while self._queue: - queued = self._queue.popleft() - self._respond(queued.get("id"), False, reason) - - def _finish_current(self, success: bool, error: Optional[str] = None) -> None: - current = self._currentCommand - self._currentCommand = None - if current is not None: - self._respond(current.get("id"), success, error) - self._start_next_command() - - def _start_next_command(self) -> None: - if self._currentCommand is not None or not self._queue: - return - self._start_command(self._queue.popleft()) - - def _respond(self, requestId: Any, success: bool, error: Optional[str] = None) -> None: - if requestId is None: - return - - payload: dict[str, Any] = { - "id": requestId, - "ok": bool(success), - } - if error: - payload["error"] = str(error) - _write_json_line(payload) - - def _onFileMessage(self, _bus: Any, message: Any) -> None: - if self._currentCommand is None or self._currentCommand.get("action") != "play_file": - return - - if message.type == Gst.MessageType.EOS: - self._filePlayer.set_state(Gst.State.NULL) - self._finish_current(True) - return - - if message.type == Gst.MessageType.ERROR: - self._filePlayer.set_state(Gst.State.NULL) - error, _info = message.parse_error() - _report_recovery_required(str(error)) - print(str(error), file=sys.stderr, flush=True) - self._finish_current(False, str(error)) - - def _onToneMessage(self, _bus: Any, message: Any) -> None: - if self._currentCommand is None or self._currentCommand.get("action") != "play_tone": - return - - if message.type != Gst.MessageType.ERROR: - return - - self._tonePipeline.set_state(Gst.State.NULL) - self._clear_tone_timeout() - error, _info = message.parse_error() - _report_recovery_required(str(error)) - print(str(error), file=sys.stderr, flush=True) - self._finish_current(False, str(error)) - - -def play_file_once( - soundPath: str, - timeoutSeconds: int = 10, - soundSink: Optional[str] = None, - volume: float = 1.0, -) -> int: - available = gstreamer_support.gst_init_check_available(Gst) - if not available: - print("GStreamer is not available", file=sys.stderr) - return 1 - - player, panorama, sinkName, sinkError = _create_file_player( - "cthulhu-sound-helper-once", - soundSink, - ) - if player is None: - print(sinkError or "Failed to create one-shot file playback player", file=sys.stderr) - return 1 - - player.set_property("uri", pathlib.Path(soundPath).resolve().as_uri()) - player.set_property("volume", _clamp_volume(volume)) - if panorama is not None: - panorama.set_property("panorama", 0.0) - player.set_state(Gst.State.PLAYING) - - bus = player.get_bus() - if bus is None: - player.set_state(Gst.State.NULL) - print("No bus available for one-shot playback", file=sys.stderr) - return 1 - - timeoutNs = int(timeoutSeconds * Gst.SECOND) - try: - message = bus.timed_pop_filtered( - timeoutNs, - Gst.MessageType.EOS | Gst.MessageType.ERROR - ) - if message is None: - print( - f"Sound helper timed out after {timeoutSeconds} seconds on sink {sinkName}", - file=sys.stderr - ) - return 1 - if message.type == Gst.MessageType.ERROR: - error, _info = message.parse_error() - print(str(error), file=sys.stderr) - return 1 - return 0 - finally: - player.set_state(Gst.State.NULL) - - -def main() -> int: - parser = argparse.ArgumentParser(add_help=False) - parser.add_argument("--worker", action="store_true") - parser.add_argument("--play-file") - parser.add_argument("--sound-sink") - parser.add_argument("--volume", type=float, default=1.0) - parser.add_argument("--timeout-seconds", type=int, default=10) - args, _unknown = parser.parse_known_args() - - if args.worker: - worker = SoundWorker(args.sound_sink) - return worker.run() - - if args.play_file: - return play_file_once( - args.play_file, - args.timeout_seconds, - args.sound_sink, - args.volume, - ) - - return 0 - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/src/cthulhu/sound_sink.py b/src/cthulhu/sound_sink.py deleted file mode 100644 index 6305cb2..0000000 --- a/src/cthulhu/sound_sink.py +++ /dev/null @@ -1,115 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. - -"""Utilities for selecting GStreamer audio sinks.""" - -from __future__ import annotations - -from typing import Any, Optional, Tuple - -import gi -from . import gstreamer_support -from . import settings - -try: - gi.require_version('Gst', '1.0') - from gi.repository import Gst -except Exception: - _gstreamerAvailable: bool = False -else: - _gstreamerAvailable = gstreamer_support.gst_init_check_available(Gst) - -_SINK_ELEMENT_BY_SETTING = { - settings.SOUND_SINK_PIPEWIRE: "pipewiresink", - settings.SOUND_SINK_PULSE: "pulsesink", - settings.SOUND_SINK_ALSA: "alsasink", -} - -_AUTO_SINK_ELEMENTS = [ - "autoaudiosink", - "pipewiresink", - "pulsesink", - "alsasink", -] - - -def normalize_sound_sink_choice(soundSink: Optional[str]) -> str: - """Return a valid sound sink setting value.""" - - if soundSink is None: - return settings.SOUND_SINK_AUTO - - choice = str(soundSink).strip().lower() - if choice in settings.SOUND_SINK_VALUES: - return choice - - return settings.SOUND_SINK_AUTO - - -def get_configured_sound_sink() -> str: - """Return the configured sound sink, falling back to defaults.""" - - try: - from . import cthulhu - if cthulhu.cthulhuApp is not None: - configured = cthulhu.cthulhuApp.settingsManager.getSetting("soundSink") - return normalize_sound_sink_choice(configured) - except Exception: - pass - - return normalize_sound_sink_choice(getattr(settings, "soundSink", settings.SOUND_SINK_AUTO)) - - -def _get_sink_element_candidates(soundSink: str) -> list[str]: - if soundSink == settings.SOUND_SINK_AUTO: - return list(_AUTO_SINK_ELEMENTS) - - elementName = _SINK_ELEMENT_BY_SETTING.get(soundSink) - if elementName: - return [elementName] - - return list(_AUTO_SINK_ELEMENTS) - - -def create_audio_sink( - sinkId: str, - soundSink: Optional[str] = None, -) -> Tuple[Optional[Any], Optional[str], Optional[str]]: - """Create a configured GStreamer audio sink.""" - - if not _gstreamerAvailable: - return None, None, "GStreamer is not available" - - configuredSink = normalize_sound_sink_choice(soundSink or get_configured_sound_sink()) - triedCandidates = [] - - for elementName in _get_sink_element_candidates(configuredSink): - factory = Gst.ElementFactory.find(elementName) - if factory is None: - triedCandidates.append(f"{elementName} (unavailable)") - continue - - sink = Gst.ElementFactory.make(elementName, sinkId) - if sink is None: - triedCandidates.append(f"{elementName} (failed to create)") - continue - - return sink, elementName, None - - triedText = ", ".join(triedCandidates) if triedCandidates else "none" - reason = ( - f"No usable audio sink for soundSink={configuredSink}. " - f"Tried: {triedText}" - ) - return None, None, reason diff --git a/src/cthulhu/sound_theme_manager.py b/src/cthulhu/sound_theme_manager.py deleted file mode 100644 index f7987c7..0000000 --- a/src/cthulhu/sound_theme_manager.py +++ /dev/null @@ -1,448 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Sound Theme Manager for Cthulhu screen reader. - -Handles discovery and playback of sound theme files from: -- System: /usr/share/cthulhu/sounds/{theme_name}/ -- Local: ~/.local/share/cthulhu/sounds/{theme_name}/ -- User themes: Same as local, user can add custom folders - -Themes are simply folders containing sound files. The folder name is the theme name. -""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2024 Stormux" -__license__ = "LGPL" - -import os - -from gi.repository import GLib -from gi.repository import Atspi - -from . import debug -from . import role_keys -from . import sound -from .sound_generator import Icon - -# Sound event constants - add new events here for easy extensibility -SOUND_FOCUS_MODE = "focus_mode" -SOUND_BROWSE_MODE = "browse_mode" -SOUND_BUTTON = "button" -SOUND_START = "start" -SOUND_STOP = "stop" - -ROLE_SOUND_ALIASES = { - Atspi.Role.PUSH_BUTTON: ["button", "push_button"], - Atspi.Role.TOGGLE_BUTTON: ["toggle_button", "button"], - Atspi.Role.RADIO_BUTTON: ["radio_button", "radio"], - Atspi.Role.CHECK_BOX: ["checkbox", "check_box"], - Atspi.Role.COMBO_BOX: ["combobox", "combo_box"], -} - -ROLE_STATE_SOUND_BASES = { - Atspi.Role.CHECK_BOX: ["checkbox", "check_box"], - Atspi.Role.CHECK_MENU_ITEM: ["checkbox", "check_box"], - Atspi.Role.RADIO_BUTTON: ["radiobutton", "radio_button"], - Atspi.Role.RADIO_MENU_ITEM: ["radiobutton", "radio_button"], - Atspi.Role.TOGGLE_BUTTON: ["togglebutton", "toggle_button"], - Atspi.Role.SWITCH: ["switch"], -} - -STATE_SOUND_SUFFIXES = { - "checked": ["checked", "on", "pressed", "selected"], - "unchecked": ["unchecked", "off", "not_pressed", "unselected"], - "mixed": ["mixed", "partially_checked", "indeterminate"], -} - -# Special theme name for no sounds -THEME_NONE = "none" - - -class SoundThemeManager: - """Manages sound themes for Cthulhu.""" - - def __init__(self, app): - self.app = app - self._systemSoundsDir = None - self._userSoundsDir = None - - def _deriveDatadirFromModulePath(self): - """Derive the datadir from where this module is actually installed. - - If module is at /usr/local/lib/python3.x/site-packages/cthulhu/, - then datadir should be /usr/local/share. - """ - try: - modulePath = os.path.dirname(os.path.abspath(__file__)) - # Walk up looking for lib/python* pattern - currentPath = modulePath - for _ in range(10): # Limit iterations to avoid infinite loop - parent = os.path.dirname(currentPath) - if parent == currentPath: - break - dirName = os.path.basename(currentPath) - # Check if we're in a lib directory - if dirName == 'lib' or dirName.startswith('lib64'): - # Parent of lib is the prefix - prefix = parent - datadir = os.path.join(prefix, 'share') - if os.path.isdir(datadir): - return datadir - currentPath = parent - except Exception: - pass - return None - - def getSystemSoundsDir(self): - """Get system sounds directory from platform settings. - - First tries cthulhu_platform.datadir, then derives from module location. - """ - if self._systemSoundsDir is None: - datadir = None - - # First try the configured datadir from cthulhu_platform - try: - from . import cthulhu_platform - datadir = getattr(cthulhu_platform, 'datadir', None) - except ImportError: - pass - - # If datadir points to user home, it's likely wrong - try to derive it - if datadir and (datadir.startswith(os.path.expanduser('~')) or - '/home/' in datadir): - derivedDatadir = self._deriveDatadirFromModulePath() - if derivedDatadir: - datadir = derivedDatadir - - # Fallback to /usr/share if nothing else works - if not datadir: - datadir = '/usr/share' - - self._systemSoundsDir = os.path.join(datadir, 'cthulhu', 'sounds') - return self._systemSoundsDir - - def getUserSoundsDir(self): - """Get user sounds directory (XDG_DATA_HOME/cthulhu/sounds).""" - if self._userSoundsDir is None: - self._userSoundsDir = os.path.join( - GLib.get_user_data_dir(), 'cthulhu', 'sounds' - ) - return self._userSoundsDir - - def getAvailableThemes(self): - """Discover all available sound themes. - - Returns list of theme names (folder names) from both system and user dirs. - User themes with same name as system themes will override system themes. - Also checks standard fallback paths. - """ - themes = set() - - # Check configured paths plus standard fallback locations - # /usr/share is standard, /usr/local/share is non-standard - searchDirs = [ - self.getUserSoundsDir(), - self.getSystemSoundsDir(), - '/usr/share/cthulhu/sounds', - '/usr/local/share/cthulhu/sounds', - ] - - for baseDir in searchDirs: - if os.path.isdir(baseDir): - try: - for entry in os.listdir(baseDir): - entryPath = os.path.join(baseDir, entry) - if os.path.isdir(entryPath): - themes.add(entry) - except OSError as e: - tokens = ["SOUND THEME: Error listing directory:", baseDir, str(e)] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return sorted(list(themes)) - - def getThemePath(self, themeName): - """Get the path to a theme directory. - - User themes take precedence over system themes. - Checks multiple standard locations as fallbacks. - """ - # Check user directory first - userPath = os.path.join(self.getUserSoundsDir(), themeName) - if os.path.isdir(userPath): - return userPath - - # Check the configured system directory - systemPath = os.path.join(self.getSystemSoundsDir(), themeName) - if os.path.isdir(systemPath): - return systemPath - - # Fallback: check standard system paths in case cthulhu_platform.datadir - # doesn't match where sounds are actually installed - # Check /usr/share first (standard), then /usr/local/share (non-standard) - fallbackPaths = [ - '/usr/share/cthulhu/sounds', - '/usr/local/share/cthulhu/sounds', - ] - for fallbackDir in fallbackPaths: - fallbackPath = os.path.join(fallbackDir, themeName) - if os.path.isdir(fallbackPath): - return fallbackPath - - return None - - def getSoundPath(self, themeName, soundName): - """Get path to a specific sound file. - - Checks for common audio file extensions: .wav, .ogg, .mp3, .flac. - User themes are checked first, then system themes as fallback so - partial user themes can inherit missing sounds. - """ - themePaths = [] - - userPath = os.path.join(self.getUserSoundsDir(), themeName) - if os.path.isdir(userPath): - themePaths.append(userPath) - - systemPath = os.path.join(self.getSystemSoundsDir(), themeName) - if os.path.isdir(systemPath): - themePaths.append(systemPath) - - fallbackDirs = [ - '/usr/share/cthulhu/sounds', - '/usr/local/share/cthulhu/sounds', - ] - for fallbackDir in fallbackDirs: - fallbackPath = os.path.join(fallbackDir, themeName) - if os.path.isdir(fallbackPath) and fallbackPath not in themePaths: - themePaths.append(fallbackPath) - - if not themePaths: - return None - - for themePath in themePaths: - for ext in ['.wav', '.ogg', '.mp3', '.flac']: - soundPath = os.path.join(themePath, soundName + ext) - if os.path.isfile(soundPath): - return soundPath - - return None - - def _getRoleSoundCandidates(self, role): - """Return candidate sound names for a given role.""" - role = self._normalizeRole(role) - if role is None: - return [] - candidates = ROLE_SOUND_ALIASES.get(role, []) - if candidates: - return candidates - - roleName = Atspi.role_get_name(role) - if roleName: - return [roleName.replace(' ', '_')] - - return [] - - def _normalizeRole(self, role): - if isinstance(role, str): - if role == role_keys.ROLE_SWITCH: - return Atspi.Role.SWITCH - return None - return role - - def _getRoleStateSoundCandidates(self, role, stateKey): - """Return candidate sound names for a given role/state pair.""" - role = self._normalizeRole(role) - if role is None: - return [] - bases = ROLE_STATE_SOUND_BASES.get(role, []) - if not bases: - return [] - - suffixes = STATE_SOUND_SUFFIXES.get(stateKey, []) - if not suffixes: - return [] - - candidates = [] - for base in bases: - for suffix in suffixes: - candidates.append(f"{base}_{suffix}") - return candidates - - def getRoleSoundIcon(self, role, themeName=None): - """Return an Icon for the role sound from the current theme, if any.""" - themeName = themeName or self.app.getSettingsManager().getSetting('soundTheme') or 'default' - if themeName == THEME_NONE: - return None - - for candidate in self._getRoleSoundCandidates(role): - soundPath = self.getSoundPath(themeName, candidate) - if soundPath: - return Icon(os.path.dirname(soundPath), os.path.basename(soundPath)) - - return None - - def getLinkSoundIcon(self, visited=False, themeName=None): - """Return an Icon for a plain or visited link sound from the current theme.""" - - themeName = themeName or self.app.getSettingsManager().getSetting('soundTheme') or 'default' - if themeName == THEME_NONE: - return None - - candidates = ["link"] - if visited: - candidates.insert(0, "link_visited") - - for candidate in candidates: - soundPath = self.getSoundPath(themeName, candidate) - if soundPath: - return Icon(os.path.dirname(soundPath), os.path.basename(soundPath)) - - return None - - def getRoleStateSoundIcon(self, role, stateKey, themeName=None): - """Return an Icon for the role/state sound from the current theme, if any.""" - themeName = themeName or self.app.getSettingsManager().getSetting('soundTheme') or 'default' - if themeName == THEME_NONE: - return None - - for candidate in self._getRoleStateSoundCandidates(role, stateKey): - soundPath = self.getSoundPath(themeName, candidate) - if soundPath: - return Icon(os.path.dirname(soundPath), os.path.basename(soundPath)) - - return None - - def _playThemeSound(self, soundName, interrupt=True, wait=False, - requireSoundSetting=False, timeoutSeconds=10): - """Play a themed sound with optional gating and blocking. - - Args: - soundName: The name of the sound file (without extension) - interrupt: Whether to interrupt currently playing sounds - wait: Whether to block until the sound finishes playing - requireSoundSetting: Honor enableSound setting - - Returns: - True if sound was played, False otherwise - """ - if requireSoundSetting and not self.app.getSettingsManager().getSetting('enableSound'): - return False - - themeName = self.app.getSettingsManager().getSetting('soundTheme') - if not themeName: - themeName = 'default' - - # "none" theme means no sounds - if themeName == THEME_NONE: - return False - - soundPath = self.getSoundPath(themeName, soundName) - if not soundPath: - tokens = ["SOUND THEME: Sound not found:", soundName, "in theme:", themeName] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - try: - icon = Icon(os.path.dirname(soundPath), os.path.basename(soundPath)) - if icon.isValid(): - if wait: - success, reason = sound.playIconSafely(icon, timeoutSeconds=timeoutSeconds) - if not success: - failureReason = reason or f"Failed to play sound '{soundName}'" - msg = ( - "SOUND THEME: Failed to play helper-isolated sound " - f"'{soundName}'. Continuing with sound enabled. Reason: {failureReason}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return success - player = sound.getPlayer() - player.play(icon, interrupt=interrupt) - return True - except Exception as e: - tokens = ["SOUND THEME: Error playing sound:", str(e)] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - return False - - def playSound(self, soundName, interrupt=True, wait=False, timeoutSeconds=10): - """Play a sound from the current theme if enabled. - - Args: - soundName: The name of the sound file (without extension) - interrupt: Whether to interrupt currently playing sounds - wait: Whether to block until the sound finishes playing - - Returns: - True if sound was played, False otherwise - """ - return self._playThemeSound( - soundName, - interrupt=interrupt, - wait=wait, - requireSoundSetting=True, - timeoutSeconds=timeoutSeconds - ) - - def playFocusModeSound(self): - """Play sound for entering focus mode.""" - return self.playSound(SOUND_FOCUS_MODE) - - def playBrowseModeSound(self): - """Play sound for entering browse mode.""" - return self.playSound(SOUND_BROWSE_MODE) - - def playButtonSound(self): - """Play sound for button focus (future use).""" - return self.playSound(SOUND_BUTTON) - - def playStartSound(self, wait=False, timeoutSeconds=10): - """Play sound for application startup.""" - return self._playThemeSound( - SOUND_START, - interrupt=True, - wait=wait, - requireSoundSetting=True, - timeoutSeconds=timeoutSeconds - ) - - def playStopSound(self, wait=False, timeoutSeconds=10): - """Play sound for application shutdown.""" - return self._playThemeSound( - SOUND_STOP, - interrupt=True, - wait=wait, - requireSoundSetting=True, - timeoutSeconds=timeoutSeconds - ) - -_manager = None -def getManager(): - """Returns the Sound Theme Manager""" - - global _manager - if _manager is None: - from . import cthulhu - _manager = SoundThemeManager(cthulhu.cthulhuApp) - return _manager diff --git a/src/cthulhu/speech.py b/src/cthulhu/speech.py deleted file mode 100644 index 5226c38..0000000 --- a/src/cthulhu/speech.py +++ /dev/null @@ -1,747 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Manages the default speech server for cthulhu. A script can use this -as its speech server, or it can feel free to create one of its own.""" - -from __future__ import annotations - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import importlib -import time -from contextlib import contextmanager -from typing import TYPE_CHECKING, Optional, List, Dict, Any, Union, Callable - -from . import debug -from . import logger -from . import settings -from . import speech_generator -from . import sound -from .sound_generator import Icon -from .speechserver import VoiceFamily - -from .acss import ACSS -from . import speech_history - -if TYPE_CHECKING: - from .speechserver import SpeechServer - from .logger import Logger - -# Lazy initialization to avoid circular imports -_logger: Optional[Logger] = None -log: Optional[Any] = None # Logger.newLog returns a log object, keeping Any for now as logger isn't typed - -def _ensureLogger() -> None: - """Ensure logger is initialized.""" - global _logger, log - if _logger is None: - from . import cthulhu - if cthulhu.cthulhuApp: - _logger = cthulhu.cthulhuApp.logger - log = _logger.newLog("speech") - -# The speech server to use for all speech operations. -# -_speechserver: Optional[SpeechServer] = None -_echoSpeechserver: Optional[SpeechServer] = None - -# The last time something was spoken. -_timestamp: float = 0.0 - -# Optional callback for live monitoring of spoken text. -_monitorWriteTextCallback: Optional[Callable[[str], None]] = None -_monitorWriteTextListeners: List[Callable[[str], None]] = [] -_monitorSuppressionDepth = 0 - -def _isSpeechDispatcherFactory(moduleName: Optional[str]) -> bool: - if not moduleName: - return False - return moduleName.split(".")[-1] == "speechdispatcherfactory" - -def _matchesVoiceFamily(candidateFamily: Any, targetFamily: Any) -> bool: - if not candidateFamily or not targetFamily: - return False - - for key in (VoiceFamily.NAME, VoiceFamily.LANG, VoiceFamily.DIALECT, VoiceFamily.VARIANT): - if candidateFamily.get(key) != targetFamily.get(key): - return False - - return True - -def _resolveSpeechDispatcherServerInfo( - moduleName: Optional[str], - speechServerInfo: Optional[Any], - voice: Optional[Any] = None, - fallbackServerInfo: Optional[Any] = None, -) -> Optional[Any]: - - if not _isSpeechDispatcherFactory(moduleName): - return speechServerInfo - - if speechServerInfo and len(speechServerInfo) >= 2 and speechServerInfo[1] != "default": - return speechServerInfo - - if fallbackServerInfo and len(fallbackServerInfo) >= 2 and fallbackServerInfo[1] != "default": - tokens = [ - "SPEECH: Resolving Speech Dispatcher server via fallback server info:", - fallbackServerInfo, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return fallbackServerInfo - - family = None - if voice: - try: - family = ACSS(voice).get(ACSS.FAMILY) - except Exception: - debug.printException(debug.LEVEL_INFO) - - if not family: - try: - family = ACSS(settings.voices.get(settings.DEFAULT_VOICE, {})).get(ACSS.FAMILY) - except Exception: - debug.printException(debug.LEVEL_INFO) - family = None - - if not family: - return speechServerInfo - - factory = None - try: - factory = importlib.import_module(f"cthulhu.{moduleName}") - except Exception: - try: - factory = importlib.import_module(moduleName) - except Exception: - debug.printException(debug.LEVEL_INFO) - - if factory is None: - return speechServerInfo - - try: - servers = factory.SpeechServer.getSpeechServers() # type: ignore[attr-defined] - except Exception: - debug.printException(debug.LEVEL_INFO) - return speechServerInfo - - for server in servers: - try: - info = server.getInfo() - except Exception: - debug.printException(debug.LEVEL_INFO) - continue - - if not info or len(info) < 2 or info[1] == "default": - continue - - try: - families = server.getVoiceFamilies() or [] - except Exception: - debug.printException(debug.LEVEL_INFO) - continue - - for candidate in families: - if not _matchesVoiceFamily(candidate, family): - continue - - tokens = [ - "SPEECH: Resolved Speech Dispatcher server info", - info, - "for voice family", - family, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return info - - tokens = [ - "SPEECH: Could not resolve Speech Dispatcher server info for voice family", - family, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return speechServerInfo - -def _initSpeechServer(moduleName: Optional[str], speechServerInfo: Optional[Any]) -> SpeechServer: - - if not moduleName: - raise Exception("ERROR: No speech server module name provided") - - factory = None - try: - factory = importlib.import_module(f'cthulhu.{moduleName}') - except Exception: - try: - factory = importlib.import_module(moduleName) - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - # Now, get the speech server we care about. - # - speech_server = None - if factory: - if speechServerInfo: - speech_server = factory.SpeechServer.getSpeechServer(speechServerInfo) # type: ignore - - if not speech_server: - speech_server = factory.SpeechServer.getSpeechServer() # type: ignore - if speechServerInfo: - tokens = ["SPEECH: Invalid speechServerInfo:", speechServerInfo] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if not speech_server: - raise Exception(f"ERROR: No speech server for factory: {moduleName}") - - return speech_server - -def _refreshEchoSpeechServer() -> None: - global _echoSpeechserver - _echoSpeechserver = None - - if not settings.enableSpeech or not settings.useCustomEchoSpeechServer: - return - - if not _isSpeechDispatcherFactory(settings.speechServerFactory): - return - - try: - resolvedInfo = _resolveSpeechDispatcherServerInfo( - settings.speechServerFactory, - settings.echoSpeechServerInfo, - settings.echoVoice, - settings.speechServerInfo, - ) - if resolvedInfo != settings.echoSpeechServerInfo: - tokens = [ - "SPEECH: Updating echo speech server info from", - settings.echoSpeechServerInfo, - "to", - resolvedInfo, - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - settings.echoSpeechServerInfo = resolvedInfo - _echoSpeechserver = _initSpeechServer( - settings.speechServerFactory, - resolvedInfo - ) - except Exception: - debug.printException(debug.LEVEL_INFO) - _echoSpeechserver = None - -def init() -> None: - global _speechserver - debug.printMessage(debug.LEVEL_INFO, 'SPEECH: Initializing', True) - if _speechserver: - debug.printMessage(debug.LEVEL_INFO, 'SPEECH: Already initialized', True) - _refreshEchoSpeechServer() - return - - chosenModuleName = settings.speechServerFactory - try: - _speechserver = _initSpeechServer(chosenModuleName, settings.speechServerInfo) - except Exception: - moduleNames = settings.speechFactoryModules - for moduleName in moduleNames: - if moduleName != settings.speechServerFactory: - try: - _speechserver = _initSpeechServer(moduleName, None) - if _speechserver: - chosenModuleName = moduleName - break - except Exception: - debug.printException(debug.LEVEL_SEVERE) - - if _speechserver: - if chosenModuleName != settings.speechServerFactory: - settings.speechServerFactory = chosenModuleName - settings.speechServerInfo = None - tokens = [ - "SPEECH: Falling back to speech server factory:", - chosenModuleName - ] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - tokens = ["SPEECH: Using speech server factory:", chosenModuleName] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - else: - msg = 'SPEECH: Not available' - debug.printMessage(debug.LEVEL_INFO, msg, True) - - _refreshEchoSpeechServer() - debug.printMessage(debug.LEVEL_INFO, 'SPEECH: Initialized', True) - -def checkSpeechSetting() -> None: - msg = "SPEECH: Checking speech setting." - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if not settings.enableSpeech: - if _speechserver: - shutdown() - return - - if not _speechserver: - init() - return - - _refreshEchoSpeechServer() - -def getSpeechServer() -> Optional[SpeechServer]: - """Returns the speech server instance.""" - return _speechserver - -def setSpeechServer(speechServer: SpeechServer) -> None: - """Sets the speech server to be used. - - Arguments: - - speechServer: the speech server to use. - """ - global _speechserver - _speechserver = speechServer - _refreshEchoSpeechServer() - -def set_monitor_callbacks(writeText: Optional[Callable[[str], None]] = None) -> None: - """Sets runtime callbacks for live speech monitoring.""" - global _monitorWriteTextCallback - _monitorWriteTextCallback = writeText - -def add_monitor_callback(writeText: Callable[[str], None]) -> None: - """Adds a runtime callback for live speech monitoring.""" - if writeText not in _monitorWriteTextListeners: - _monitorWriteTextListeners.append(writeText) - -def remove_monitor_callback(writeText: Callable[[str], None]) -> None: - """Removes a runtime callback for live speech monitoring.""" - if writeText in _monitorWriteTextListeners: - _monitorWriteTextListeners.remove(writeText) - -@contextmanager -def suppress_monitor_callbacks(): - """Temporarily suppresses live speech monitoring callbacks.""" - global _monitorSuppressionDepth - _monitorSuppressionDepth += 1 - try: - yield - finally: - _monitorSuppressionDepth = max(0, _monitorSuppressionDepth - 1) - -def _write_to_monitor(text: str) -> None: - """Writes text to the active speech monitor callback if set.""" - if _monitorSuppressionDepth: - return - - callbacks = [] - if _monitorWriteTextCallback is not None: - callbacks.append(_monitorWriteTextCallback) - callbacks.extend( - callback for callback in _monitorWriteTextListeners - if callback != _monitorWriteTextCallback - ) - - for callback in callbacks: - try: - callback(text) - except Exception: - debug.printException(debug.LEVEL_INFO) - -def __resolveACSS(acss: Optional[Any] = None) -> ACSS: - if isinstance(acss, ACSS): - family = acss.get(acss.FAMILY) - try: - family = VoiceFamily(family) - except Exception: - family = VoiceFamily({}) - acss[acss.FAMILY] = family - return acss - elif isinstance(acss, list) and len(acss) == 1: - return ACSS(acss[0]) - elif isinstance(acss, dict): - return ACSS(acss) - else: - voices = settings.voices - return ACSS(voices[settings.DEFAULT_VOICE]) - -def sayAll(utteranceIterator: Any, progressCallback: Any) -> None: - _ensureLogger() - if settings.silenceSpeech: - return - if _speechserver: - def _speechHistorySayAllWrapper() -> Any: - for [context, acss] in utteranceIterator: - try: - utterance = getattr(context, "utterance", None) - if isinstance(utterance, str) and utterance.strip(): - speech_history.add(utterance, source="sayAll") # type: ignore - except Exception: - debug.printException(debug.LEVEL_INFO) - yield [context, acss] - - _speechserver.sayAll(_speechHistorySayAllWrapper(), progressCallback) # type: ignore - else: - if log: - for [context, acss] in utteranceIterator: - logLine = f"SPEECH OUTPUT: '{context.utterance}'" - debug.printMessage(debug.LEVEL_INFO, logLine, True) - log.info(logLine) - try: - utterance = getattr(context, "utterance", None) - if isinstance(utterance, str) and utterance.strip(): - speech_history.add(utterance, source="sayAll-fallback") # type: ignore - except Exception: - debug.printException(debug.LEVEL_INFO) - -def _speak(text: str, acss: Optional[Any], interrupt: bool) -> None: - """Speaks the individual string using the given ACSS.""" - - _ensureLogger() - - # Block speech for applications in sleep mode, except sleep mode status messages - from . import cthulhu_state - from . import sleep_mode_manager - if cthulhu_state.activeScript and hasattr(cthulhu_state.activeScript, 'app'): - sleepModeManager = sleep_mode_manager.getManager() - if sleepModeManager and sleepModeManager.isActiveForApp(cthulhu_state.activeScript.app): - # Allow sleep mode status messages to get through - if "Sleep mode enabled" in text or "Sleep mode disabled" in text: - debug.printMessage(debug.LEVEL_INFO, f"SPEECH: Allowing sleep mode status: '{text}'", True) - else: - debug.printMessage(debug.LEVEL_INFO, f"SPEECH: Blocked by sleep mode: '{text}'", True) - return - - try: - speech_history.add(text, source="speak") # type: ignore - except Exception: - debug.printException(debug.LEVEL_INFO) - - _write_to_monitor(text) - - if not _speechserver: - logLine = f"SPEECH OUTPUT: '{text}' {acss}" - debug.printMessage(debug.LEVEL_INFO, logLine, True) - if log: - log.info(logLine) - return - - voice = ACSS(settings.voices.get(settings.DEFAULT_VOICE)) - try: - voice.update(__resolveACSS(acss)) - except Exception as error: - msg = f"SPEECH: Exception updated voice with {acss}: {error}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - resolvedVoice = __resolveACSS(voice) - msg = f"SPEECH OUTPUT: '{text}' {resolvedVoice}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - _speechserver.speak(text, resolvedVoice, interrupt) # type: ignore - -def speak(content: Union[str, List[Any]], acss: Optional[Any] = None, interrupt: bool = False) -> None: - """Speaks the given content. The content can be either a simple - string or an array of arrays of objects returned by a speech - generator. Speech queues by default; callers that need to cancel - current output should pass interrupt=True or call presentationInterrupt().""" - - if settings.silenceSpeech: - return - - # Block speech for applications in sleep mode, except sleep mode status messages - from . import cthulhu_state - from . import sleep_mode_manager - if cthulhu_state.activeScript and hasattr(cthulhu_state.activeScript, 'app'): - sleepModeManager = sleep_mode_manager.getManager() - if sleepModeManager and sleepModeManager.isActiveForApp(cthulhu_state.activeScript.app): - # Allow sleep mode status messages to get through - if isinstance(content, str): - if "Sleep mode enabled" in content or "Sleep mode disabled" in content: - debug.printMessage(debug.LEVEL_INFO, f"SPEECH: Allowing sleep mode status: '{content}'", True) - else: - debug.printMessage(debug.LEVEL_INFO, f"SPEECH: Blocked by sleep mode: '{content}'", True) - return - elif isinstance(content, list): - # Check if any element in the content list contains sleep mode messages - content_str = str(content) - if "Sleep mode enabled" in content_str or "Sleep mode disabled" in content_str: - debug.printMessage(debug.LEVEL_INFO, f"SPEECH: Allowing sleep mode status list: '{content_str}'", True) - else: - debug.printMessage(debug.LEVEL_INFO, f"SPEECH: Blocked by sleep mode list: '{content_str}'", True) - return - else: - debug.printMessage(debug.LEVEL_INFO, f"SPEECH: Blocked by sleep mode: '{content}'", True) - return - - validTypes = (str, list, speech_generator.Pause, - speech_generator.LineBreak, ACSS, Icon) - error = "SPEECH: bad content sent to speak(): '%s'" - if not isinstance(content, validTypes): # type: ignore - debug.printMessage(debug.LEVEL_INFO, error % content, True) - return - - global _timestamp - if _timestamp: - msg = f"SPEECH: Last spoke {time.time() - _timestamp:.4f} seconds ago" - debug.printMessage(debug.LEVEL_INFO, msg, True) - _timestamp = time.time() - - if isinstance(content, str): - msg = f"SPEECH: Speak '{content}' acss: {acss}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - tokens = ["SPEECH: Speak", content, ", acss:", acss] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - if isinstance(content, str): - _speak(content, acss, interrupt) - if not isinstance(content, list): - return - - shouldInterrupt = interrupt - toSpeak: List[str] = [] - activeVoice = acss - if acss is not None: - activeVoice = ACSS(acss) - - for element in content: - if not isinstance(element, validTypes): # type: ignore - debug.printMessage(debug.LEVEL_INFO, error % element, True) - elif isinstance(element, list): - speak(element, acss, shouldInterrupt) - shouldInterrupt = False - elif isinstance(element, str): - if len(element): - toSpeak.append(element) - elif isinstance(element, Icon): - if toSpeak: - string = " ".join(toSpeak) - _speak(string, activeVoice, shouldInterrupt) - shouldInterrupt = False - toSpeak = [] - if element.isValid(): - player = sound.getPlayer() - if player: - # Role/state icons are short UI cues. Speech can be queued, but - # sound cues should not pile up behind stale or previous sounds. - player.play(element, interrupt=True) - elif toSpeak: - newVoice = ACSS(acss) - newItemsToSpeak = [] - if isinstance(element, speech_generator.Pause): - if toSpeak[-1] and toSpeak[-1][-1].isalnum(): - toSpeak[-1] += '.' - elif isinstance(element, ACSS): - newVoice.update(element) - if activeVoice is None: - activeVoice = newVoice - if newVoice == activeVoice: - continue - tokens = ["SPEECH: New voice", newVoice, " != active voice", activeVoice] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - newItemsToSpeak.append(toSpeak.pop()) - - if toSpeak: - string = " ".join(toSpeak) - _speak(string, activeVoice, shouldInterrupt) - shouldInterrupt = False - activeVoice = newVoice - toSpeak = newItemsToSpeak - - if toSpeak: - string = " ".join(toSpeak) - _speak(string, activeVoice, shouldInterrupt) - -def speakKeyEvent(event: Any, acss: Optional[Any] = None) -> None: - """Speaks a key event immediately. - - Arguments: - - event: input_event.KeyboardEvent to speak. - """ - - _ensureLogger() - - if settings.silenceSpeech: - return - - global _timestamp - if _timestamp: - msg = f"SPEECH: Last spoke {time.time() - _timestamp:.4f} seconds ago" - debug.printMessage(debug.LEVEL_INFO, msg, True) - _timestamp = time.time() - - keyname = event.getKeyName() - lockingStateString = event.getLockingStateString() - acss = __resolveACSS(acss) - msg = f"{keyname} {lockingStateString}" - logLine = f"SPEECH OUTPUT: '{msg.strip()}' {acss}" - debug.printMessage(debug.LEVEL_INFO, logLine, True) - if log: - log.info(logLine) - - _write_to_monitor(msg.strip()) - - if _speechserver: - _speechserver.speakKeyEvent(event, acss) # type: ignore - -def speakEchoKeyEvent(event: Any, acss: Optional[Any] = None) -> None: - """Speaks a key event for key/typing echo using echo speech settings.""" - - _ensureLogger() - - if settings.silenceSpeech: - return - - global _timestamp - if _timestamp: - msg = f"SPEECH: Last spoke {time.time() - _timestamp:.4f} seconds ago" - debug.printMessage(debug.LEVEL_INFO, msg, True) - _timestamp = time.time() - - keyname = event.getKeyName() - lockingStateString = event.getLockingStateString() - acss = __resolveACSS(acss) - msg = f"{keyname} {lockingStateString}" - logLine = f"SPEECH ECHO OUTPUT: '{msg.strip()}' {acss}" - debug.printMessage(debug.LEVEL_INFO, logLine, True) - if log: - log.info(logLine) - - _write_to_monitor(msg.strip()) - - server = _echoSpeechserver or _speechserver - if server: - server.speakKeyEvent(event, acss) # type: ignore - -def speakCharacter(character: str, acss: Optional[Any] = None) -> None: - """Speaks a single character immediately. - - Arguments: - - character: text to be spoken - - acss: acss.ACSS instance; if None, - the default voice settings will be used. - Otherwise, the acss settings will be - used to augment/override the default - voice settings. - """ - - _ensureLogger() - - if settings.silenceSpeech: - return - - global _timestamp - if _timestamp: - msg = f"SPEECH: Last spoke {time.time() - _timestamp:.4f} seconds ago" - debug.printMessage(debug.LEVEL_INFO, msg, True) - _timestamp = time.time() - - acss = __resolveACSS(acss) - tokens = [f"SPEECH OUTPUT: '{character}'", acss] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if log: - log.info(f"SPEECH OUTPUT: '{character}'") - - _write_to_monitor(character) - - if _speechserver: - _speechserver.speakCharacter(character, acss=acss) # type: ignore - -def speakEchoCharacter(character: str, acss: Optional[Any] = None) -> None: - """Speaks a single character for key/typing echo using echo speech settings.""" - - _ensureLogger() - - if settings.silenceSpeech: - return - - global _timestamp - if _timestamp: - msg = f"SPEECH: Last spoke {time.time() - _timestamp:.4f} seconds ago" - debug.printMessage(debug.LEVEL_INFO, msg, True) - _timestamp = time.time() - - acss = __resolveACSS(acss) - tokens = [f"SPEECH ECHO OUTPUT: '{character}'", acss] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if log: - log.info(f"SPEECH ECHO OUTPUT: '{character}'") - - _write_to_monitor(character) - - server = _echoSpeechserver or _speechserver - if server: - server.speakCharacter(character, acss=acss) # type: ignore - -def speakEchoText(text: str, acss: Optional[Any] = None, interrupt: bool = True) -> None: - """Speaks text for typing echo using echo speech settings.""" - - _ensureLogger() - - if settings.silenceSpeech: - return - - global _timestamp - if _timestamp: - msg = f"SPEECH: Last spoke {time.time() - _timestamp:.4f} seconds ago" - debug.printMessage(debug.LEVEL_INFO, msg, True) - _timestamp = time.time() - - acss = __resolveACSS(acss) - logLine = f"SPEECH ECHO OUTPUT: '{text}' {acss}" - debug.printMessage(debug.LEVEL_INFO, logLine, True) - if log: - log.info(logLine) - - _write_to_monitor(text) - - server = _echoSpeechserver or _speechserver - if server: - server.speak(text, acss, interrupt) # type: ignore - -def getInfo() -> Optional[Any]: - info = None - if _speechserver: - info = _speechserver.getInfo() # type: ignore - - return info - -def stop() -> None: - if _speechserver: - _speechserver.stop() # type: ignore - if _echoSpeechserver and _echoSpeechserver != _speechserver: - _echoSpeechserver.stop() # type: ignore - player = sound.getPlayer() - player.stop() - -def shutdown() -> None: - debug.printMessage(debug.LEVEL_INFO, 'SPEECH: Shutting down', True) - global _speechserver, _echoSpeechserver - if _speechserver: - _speechserver.shutdownActiveServers() # type: ignore - _speechserver = None - elif _echoSpeechserver: - _echoSpeechserver.shutdownActiveServers() # type: ignore - _echoSpeechserver = None - -def reset(text: Optional[str] = None, acss: Optional[Any] = None) -> None: - if _speechserver: - _speechserver.reset(text, acss) # type: ignore diff --git a/src/cthulhu/speech_and_verbosity_manager.py b/src/cthulhu/speech_and_verbosity_manager.py deleted file mode 100644 index 0729f48..0000000 --- a/src/cthulhu/speech_and_verbosity_manager.py +++ /dev/null @@ -1,1948 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Module for configuring speech and verbosity settings.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2016-2023 Igalia, S.L." -__license__ = "LGPL" - -from . import cmdnames -from . import cthulhu -from . import dbus_service -from . import debug -from . import guilabels -from . import input_event -from . import keybindings -from . import messages -from . import cthulhu_state -from . import script_manager -from . import speechserver -from . import settings -from . import settings_manager -from . import speech - -# Removed global _settings_manager - -class SpeechAndVerbosityManager: - """Configures speech and verbosity settings.""" - - def __init__(self, app): - self.app = app - self._speech_settings_order = [ - "rate", - "pitch", - "volume", - "module", - "voice", - ] - self._current_speech_setting_index = 0 - self._rate_step = 1 - self._pitch_step = 0.1 - self._volume_step = 0.1 - self._handlers = self._setup_handlers() - self._bindings = self._setup_bindings() - - # Register with D-Bus - msg = "SPEECH AND VERBOSITY MANAGER: Registering D-Bus commands." - debug.printMessage(debug.LEVEL_INFO, msg, True) - controller = dbus_service.get_remote_controller() - if controller: - controller.register_decorated_module("SpeechAndVerbosityManager", self) - - def get_bindings(self): - """Returns the notification-presenter keybindings.""" - - return self._bindings - - def get_handlers(self): - """Returns the notification-presenter handlers.""" - - return self._handlers - - def _setup_handlers(self): - """Sets up and returns the speech and verbosity input event handlers.""" - - handlers = {} - - handlers["cycleCapitalizationStyleHandler"] = \ - input_event.InputEventHandler( - self.cycle_capitalization_style, - cmdnames.CYCLE_CAPITALIZATION_STYLE) - - handlers["cycleSpeakingPunctuationLevelHandler"] = \ - input_event.InputEventHandler( - self.cycle_punctuation_level, - cmdnames.CYCLE_PUNCTUATION_LEVEL) - - handlers["cycleSynthesizerHandler"] = \ - input_event.InputEventHandler( - self.cycle_synthesizer, - cmdnames.CYCLE_SYNTHESIZER) - - handlers["cycleKeyEchoHandler"] = \ - input_event.InputEventHandler( - self.cycle_key_echo, - cmdnames.CYCLE_KEY_ECHO) - - handlers["changeNumberStyleHandler"] = \ - input_event.InputEventHandler( - self.change_number_style, - cmdnames.CHANGE_NUMBER_STYLE) - - handlers["toggleSilenceSpeechHandler"] = \ - input_event.InputEventHandler( - self.toggle_speech, - cmdnames.TOGGLE_SPEECH) - - handlers["toggleSpeechVerbosityHandler"] = \ - input_event.InputEventHandler( - self.toggle_verbosity, - cmdnames.TOGGLE_SPEECH_VERBOSITY) - - handlers["toggleSpeakingIndentationJustificationHandler"] = \ - input_event.InputEventHandler( - self.toggle_indentation_and_justification, - cmdnames.TOGGLE_SPOKEN_INDENTATION_AND_JUSTIFICATION) - - handlers["toggleTableCellReadModeHandler"] = \ - input_event.InputEventHandler( - self.toggle_table_cell_reading_mode, - cmdnames.TOGGLE_TABLE_CELL_READ_MODE) - - handlers["decreaseSpeechRateHandler"] = \ - input_event.InputEventHandler( - self.decrease_rate, - cmdnames.DECREASE_SPEECH_RATE) - - handlers["increaseSpeechRateHandler"] = \ - input_event.InputEventHandler( - self.increase_rate, - cmdnames.INCREASE_SPEECH_RATE) - - handlers["decreaseSpeechPitchHandler"] = \ - input_event.InputEventHandler( - self.decrease_pitch, - cmdnames.DECREASE_SPEECH_PITCH) - - handlers["increaseSpeechPitchHandler"] = \ - input_event.InputEventHandler( - self.increase_pitch, - cmdnames.INCREASE_SPEECH_PITCH) - - handlers["decreaseSpeechVolumeHandler"] = \ - input_event.InputEventHandler( - self.decrease_volume, - cmdnames.DECREASE_SPEECH_VOLUME) - - handlers["increaseSpeechVolumeHandler"] = \ - input_event.InputEventHandler( - self.increase_volume, - cmdnames.INCREASE_SPEECH_VOLUME) - - handlers["selectPreviousSpeechSettingHandler"] = \ - input_event.InputEventHandler( - self.select_previous_speech_setting, - cmdnames.SPEECH_SETTING_PREVIOUS) - - handlers["selectNextSpeechSettingHandler"] = \ - input_event.InputEventHandler( - self.select_next_speech_setting, - cmdnames.SPEECH_SETTING_NEXT) - - handlers["decreaseCurrentSpeechSettingHandler"] = \ - input_event.InputEventHandler( - self.decrease_current_speech_setting, - cmdnames.SPEECH_SETTING_DECREASE) - - handlers["increaseCurrentSpeechSettingHandler"] = \ - input_event.InputEventHandler( - self.increase_current_speech_setting, - cmdnames.SPEECH_SETTING_INCREASE) - - handlers["saveSpeechSettingsHandler"] = \ - input_event.InputEventHandler( - self.save_speech_settings, - cmdnames.SPEECH_SETTINGS_SAVE) - - return handlers - - def _setup_bindings(self): - """Sets up and returns the speech and verbosity key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("cycleCapitalizationStyleHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("cycleSpeakingPunctuationLevelHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("cycleSynthesizerHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("cycleKeyEchoHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("changeNumberStyleHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("decreaseSpeechRateHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("increaseSpeechRateHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("decreaseSpeechPitchHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("increaseSpeechPitchHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("decreaseSpeechVolumeHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("increaseSpeechVolumeHandler"))) - - bindings.add( - keybindings.KeyBinding( - "Left", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("selectPreviousSpeechSettingHandler"))) - - bindings.add( - keybindings.KeyBinding( - "Right", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("selectNextSpeechSettingHandler"))) - - bindings.add( - keybindings.KeyBinding( - "Down", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("decreaseCurrentSpeechSettingHandler"))) - - bindings.add( - keybindings.KeyBinding( - "Up", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("increaseCurrentSpeechSettingHandler"))) - - bindings.add( - keybindings.KeyBinding( - "s", - keybindings.defaultModifierMask, - keybindings.CTHULHU_CTRL_MODIFIER_MASK | keybindings.SHIFT_MODIFIER_MASK, - self._handlers.get("saveSpeechSettingsHandler"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("toggleSpeakingIndentationJustificationHandler"))) - - bindings.add( - keybindings.KeyBinding( - "s", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("toggleSilenceSpeechHandler"))) - - bindings.add( - keybindings.KeyBinding( - "v", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("toggleSpeechVerbosityHandler"))) - - bindings.add( - keybindings.KeyBinding( - "F11", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("toggleTableCellReadModeHandler"))) - - return bindings - - def _get_server(self): - return speech.getSpeechServer() - - def _format_number(self, value): - if isinstance(value, float): - if value.is_integer(): - return str(int(value)) - return f"{value:.1f}".rstrip("0").rstrip(".") - return str(value) - - def _present_message(self, script, message, voice=None): - if script: - script.presentMessage(message, voice=voice) - else: - speech.speak(message, voice) - - def _get_default_voice(self): - from . import acss - default_voice = settings.voices.get(settings.DEFAULT_VOICE) - if default_voice is None: - default_voice = acss.ACSS({}) - settings.voices[settings.DEFAULT_VOICE] = default_voice - return default_voice - - def _set_default_voice_family(self, family): - from . import acss - default_voice = self._get_default_voice() - if family is None: - default_voice.pop(acss.ACSS.FAMILY, None) - else: - family_dict = { - key: value for key, value in dict(family).items() - if value is not None - } - default_voice[acss.ACSS.FAMILY] = family_dict - default_voice['established'] = True - self.app.getSettingsManager().set_session_setting("voices", settings.voices) - - def _get_current_speech_setting(self): - order = self._get_speech_settings_order() - if not order: - return "" - if self._current_speech_setting_index < 0: - self._current_speech_setting_index = 0 - elif self._current_speech_setting_index >= len(order): - self._current_speech_setting_index = len(order) - 1 - return order[self._current_speech_setting_index] - - def _get_speech_settings_order(self): - order = ["rate", "pitch", "volume"] - server = self._get_server() - if server and hasattr(server, "list_output_modules") and hasattr(server, "getOutputModule"): - order.append("module") - if server and hasattr(server, "getVoiceFamilies"): - order.append("voice") - return order - - def _get_rate_value(self): - from . import acss - default_voice = self._get_default_voice() - return int(default_voice.get(acss.ACSS.RATE, 50)) - - def _set_rate_value(self, value): - from . import acss - default_voice = self._get_default_voice() - default_voice[acss.ACSS.RATE] = int(value) - default_voice['established'] = True - self.app.getSettingsManager().set_session_setting("voices", settings.voices) - - def _get_pitch_value(self): - from . import acss - default_voice = self._get_default_voice() - return float(default_voice.get(acss.ACSS.AVERAGE_PITCH, 5.0)) - - def _set_pitch_value(self, value): - from . import acss - default_voice = self._get_default_voice() - default_voice[acss.ACSS.AVERAGE_PITCH] = float(value) - default_voice['established'] = True - self.app.getSettingsManager().set_session_setting("voices", settings.voices) - - def _get_volume_value(self): - from . import acss - default_voice = self._get_default_voice() - return float(default_voice.get(acss.ACSS.GAIN, 10.0)) - - def _set_volume_value(self, value): - from . import acss - default_voice = self._get_default_voice() - default_voice[acss.ACSS.GAIN] = float(value) - default_voice['established'] = True - self.app.getSettingsManager().set_session_setting("voices", settings.voices) - - def _get_current_voice_name(self, server=None): - from . import acss - default_voice = self._get_default_voice() - family = default_voice.get(acss.ACSS.FAMILY, {}) or {} - name = family.get(speechserver.VoiceFamily.NAME) - if name and server: - voices = self._get_available_voices(server) - if voices: - for voice in voices: - if voice.get(speechserver.VoiceFamily.NAME) == name: - return name - self._set_default_voice_family(voices[0]) - return voices[0].get(speechserver.VoiceFamily.NAME) - if name: - return name - if server: - voices = self._get_available_voices(server) - if voices: - self._set_default_voice_family(voices[0]) - return voices[0].get(speechserver.VoiceFamily.NAME) - return "" - - def _get_voice_messages(self, server): - if server and hasattr(server, "list_output_modules"): - return messages.SPEECH_VOICE_VALUE, messages.SPEECH_VOICES_UNAVAILABLE - return messages.SPEECH_VOICE_VALUE_GENERIC, messages.SPEECH_VOICES_UNAVAILABLE_GENERIC - - def _get_available_modules(self, server): - if server is None or not hasattr(server, 'list_output_modules'): - return [] - try: - modules = list(server.list_output_modules() or []) - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error getting output modules: {e}", True) - return [] - return modules - - def _get_available_voices(self, server): - if server is None or not hasattr(server, 'getVoiceFamilies'): - return [] - try: - voices = server.getVoiceFamilies() or [] - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error getting voices: {e}", True) - return [] - filtered = [] - for voice in voices: - if voice.get(speechserver.VoiceFamily.NAME): - filtered.append(voice) - if not filtered: - return [] - - if hasattr(server, "getOutputModule"): - try: - module = server.getOutputModule() or "" - except Exception: - module = "" - if module: - default_name = guilabels.SPEECH_DEFAULT_VOICE % module - real_voices = [ - voice for voice in filtered - if voice.get(speechserver.VoiceFamily.NAME) != default_name - ] - if real_voices: - filtered = real_voices - - if not self._should_filter_voices_by_locale(server): - return filtered - - language, dialect = self._get_system_language_and_dialect() - if not language: - return filtered - - language_filtered = [] - for voice in filtered: - voice_lang = (voice.get(speechserver.VoiceFamily.LANG) or "").lower() - voice_dialect = (voice.get(speechserver.VoiceFamily.DIALECT) or "").lower() - if voice_lang != language: - continue - if dialect and voice_dialect and voice_dialect != dialect: - continue - language_filtered.append(voice) - - if language_filtered: - msg = ( - "SPEECH AND VERBOSITY MANAGER: " - f"Filtered voices to locale {language}" - f"{('-' + dialect) if dialect else ''}: " - f"{len(language_filtered)} of {len(filtered)}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return language_filtered - - msg = ( - "SPEECH AND VERBOSITY MANAGER: " - f"No voices for locale {language}" - f"{('-' + dialect) if dialect else ''}; using all voices." - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return filtered - - def _should_filter_voices_by_locale(self, server): - if server is None or not hasattr(server, "getOutputModule"): - return False - try: - module = (server.getOutputModule() or "").lower() - except Exception: - return False - return "espeak-ng" in module - - def _get_system_language_and_dialect(self): - import locale - locale_value = None - try: - locale_value = locale.getlocale(locale.LC_MESSAGES)[0] - except Exception: - locale_value = None - if not locale_value: - try: - locale_value = locale.getdefaultlocale()[0] - except Exception: - locale_value = None - - if not locale_value: - return "", "" - - if "_" in locale_value: - language, dialect = locale_value.split("_", 1) - elif "-" in locale_value: - language, dialect = locale_value.split("-", 1) - else: - language, dialect = locale_value, "" - - return language.lower(), dialect.lower() - - def _announce_current_speech_setting(self, script=None): - setting = self._get_current_speech_setting() - debug.printMessage(debug.LEVEL_INFO, - f"SPEECH AND VERBOSITY MANAGER: Current setting {setting}", - True) - if setting == "rate": - value = self._get_rate_value() - message = messages.SPEECH_RATE_VALUE % value - elif setting == "pitch": - value = self._format_number(self._get_pitch_value()) - message = messages.SPEECH_PITCH_VALUE % value - elif setting == "volume": - value = self._format_number(self._get_volume_value()) - message = messages.SPEECH_VOLUME_VALUE % value - elif setting == "module": - server = self._get_server() - if server is None or not hasattr(server, 'getOutputModule'): - message = messages.SPEECH_MODULES_UNAVAILABLE - else: - module = server.getOutputModule() or "" - if module: - message = messages.SPEECH_MODULE_VALUE % module - else: - message = messages.SPEECH_MODULES_UNAVAILABLE - elif setting == "voice": - server = self._get_server() - voices = self._get_available_voices(server) - voice_value_message, voice_unavailable_message = self._get_voice_messages(server) - if not voices: - message = voice_unavailable_message - else: - name = self._get_current_voice_name(server) - message = voice_value_message % name - else: - message = "" - - if message: - voice = self._get_default_voice() if setting in ("voice", "module") else None - self._present_message(script, message, voice=voice) - - @dbus_service.command - def select_previous_speech_setting(self, script=None, event=None): - order = self._get_speech_settings_order() - if not order: - return True - if self._current_speech_setting_index >= len(order): - self._current_speech_setting_index = len(order) - 1 - elif self._current_speech_setting_index > 0: - self._current_speech_setting_index -= 1 - self._announce_current_speech_setting(script) - return True - - @dbus_service.command - def select_next_speech_setting(self, script=None, event=None): - order = self._get_speech_settings_order() - if not order: - return True - if self._current_speech_setting_index < len(order) - 1: - self._current_speech_setting_index += 1 - self._announce_current_speech_setting(script) - return True - - @dbus_service.command - def decrease_current_speech_setting(self, script=None, event=None): - return self._adjust_current_speech_setting(script, decrease=True) - - @dbus_service.command - def increase_current_speech_setting(self, script=None, event=None): - return self._adjust_current_speech_setting(script, decrease=False) - - def _adjust_current_speech_setting(self, script, decrease=False): - setting = self._get_current_speech_setting() - if setting == "rate": - return self._adjust_rate(script, decrease) - if setting == "pitch": - return self._adjust_pitch(script, decrease) - if setting == "volume": - return self._adjust_volume(script, decrease) - if setting == "module": - return self._adjust_module(script, decrease) - if setting == "voice": - return self._adjust_voice(script, decrease) - return True - - def _adjust_rate(self, script, decrease): - delta = -self._rate_step if decrease else self._rate_step - value = self._get_rate_value() + delta - value = max(0, min(100, value)) - self._set_rate_value(value) - msg = f"SPEECH AND VERBOSITY MANAGER: Rate set to {value}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._announce_current_speech_setting(script) - return True - - def _adjust_pitch(self, script, decrease): - delta = -self._pitch_step if decrease else self._pitch_step - value = round(self._get_pitch_value() + delta, 1) - value = max(0.0, min(10.0, value)) - self._set_pitch_value(value) - msg = f"SPEECH AND VERBOSITY MANAGER: Pitch set to {value}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._announce_current_speech_setting(script) - return True - - def _adjust_volume(self, script, decrease): - delta = -self._volume_step if decrease else self._volume_step - value = round(self._get_volume_value() + delta, 1) - value = max(0.0, min(10.0, value)) - self._set_volume_value(value) - msg = f"SPEECH AND VERBOSITY MANAGER: Volume set to {value}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._announce_current_speech_setting(script) - return True - - def _adjust_module(self, script, decrease): - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - modules = self._get_available_modules(server) - if not modules: - self._present_message(script, messages.SPEECH_MODULES_UNAVAILABLE) - return True - - current = server.getOutputModule() if hasattr(server, 'getOutputModule') else "" - try: - index = modules.index(current) - except ValueError: - index = 0 - - delta = -1 if decrease else 1 - new_index = max(0, min(len(modules) - 1, index + delta)) - new_module = modules[new_index] - - if new_module != current: - try: - server.setOutputModule(new_module) - msg = f"SPEECH AND VERBOSITY MANAGER: Output module set to {new_module}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting output module: {e}", True) - return True - settings.speechServerInfo = [new_module, new_module] - self.app.getSettingsManager().set_session_setting( - "speechServerInfo", - settings.speechServerInfo, - ) - msg = f"SPEECH AND VERBOSITY MANAGER: speechServerInfo set to {settings.speechServerInfo}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - voices = self._get_available_voices(server) - if voices: - self._set_default_voice_family(voices[0]) - else: - self._set_default_voice_family({}) - - self._present_message( - script, - messages.SPEECH_MODULE_VALUE % new_module, - voice=self._get_default_voice(), - ) - return True - - def _adjust_voice(self, script, decrease): - server = self._get_server() - voices = self._get_available_voices(server) - if not voices: - _, voice_unavailable_message = self._get_voice_messages(server) - self._present_message(script, voice_unavailable_message) - return True - - current_name = self._get_current_voice_name(server) - index = 0 - for idx, voice in enumerate(voices): - if voice.get(speechserver.VoiceFamily.NAME) == current_name: - index = idx - break - - delta = -1 if decrease else 1 - new_index = max(0, min(len(voices) - 1, index + delta)) - new_voice = voices[new_index] - self._set_default_voice_family(new_voice) - name = new_voice.get(speechserver.VoiceFamily.NAME, "") - msg = f"SPEECH AND VERBOSITY MANAGER: Voice set to {name}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - voice_value_message, _ = self._get_voice_messages(server) - self._present_message(script, voice_value_message % name, voice=self._get_default_voice()) - return True - - @dbus_service.command - def save_speech_settings(self, script=None, event=None): - try: - server = self._get_server() - if server and hasattr(server, "getOutputModule"): - module = server.getOutputModule() or "" - if module: - settings.speechServerInfo = [module, module] - msg = f"SPEECH AND VERBOSITY MANAGER: Saving speechServerInfo {settings.speechServerInfo}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - - general = {} - for key in settings.userCustomizableSettings: - general[key] = getattr(settings, key) - - current_profile = self.app.getSettingsManager().profile - pronunciations = self.app.getSettingsManager().getPronunciations(current_profile) - keybindings = self.app.getSettingsManager().getKeybindings(current_profile) - - default_script = self.app.getScriptManager().get_default_script() - self.app.getSettingsManager().saveSettings(default_script, - general, - pronunciations, - keybindings) - self._present_message(script, messages.SPEECH_SETTINGS_SAVED) - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error saving speech settings: {e}", True) - self._present_message(script, messages.SPEECH_SETTINGS_SAVE_FAILED) - return True - - # ======================================================================== - # D-Bus Speech Server Controls - # ======================================================================== - - @dbus_service.getter - def get_current_server(self) -> str: - """Returns the name of the current speech server (Speech Dispatcher or Spiel).""" - server = self._get_server() - if server is None: - return "" - return server.getFactoryName() if hasattr(server, 'getFactoryName') else "" - - @dbus_service.getter - def get_available_servers(self) -> list: - """Returns a list of available speech servers.""" - # TODO: Implement multi-server support if needed - return ["speechdispatcher"] - - @dbus_service.getter - def get_current_synthesizer(self) -> str: - """Returns the current synthesizer of the speech server.""" - server = self._get_server() - if server is None: - return "" - return server.getOutputModule() if hasattr(server, 'getOutputModule') else "" - - @dbus_service.setter - def set_current_synthesizer(self, value: str) -> bool: - """Sets the current synthesizer of the active speech server.""" - server = self._get_server() - if server is None: - return False - try: - if hasattr(server, 'setOutputModule'): - server.setOutputModule(value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting synthesizer: {e}", True) - return False - - @dbus_service.getter - def get_available_synthesizers(self) -> list: - """Returns a list of available synthesizers of the speech server.""" - server = self._get_server() - if server is None: - return [] - try: - if hasattr(server, 'list_output_modules'): - return server.list_output_modules() - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error getting synthesizers: {e}", True) - return [] - - # ======================================================================== - # D-Bus Voice Controls - # ======================================================================== - - @dbus_service.getter - def get_available_voices(self) -> list: - """Returns a list of available voices for the current synthesizer.""" - server = self._get_server() - if server is None: - return [] - try: - if hasattr(server, 'getVoiceFamilies'): - voices = server.getVoiceFamilies() - return [v.get('name', '') for v in voices if v.get('name')] - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error getting voices: {e}", True) - return [] - - @dbus_service.getter - def get_current_voice(self) -> str: - """Returns the current voice name.""" - server = self._get_server() - if server is None: - return "" - try: - if hasattr(server, 'getVoiceFamily'): - family = server.getVoiceFamily() - if family: - return family.get('name', '') - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error getting current voice: {e}", True) - return "" - - @dbus_service.setter - def set_current_voice(self, voice_name: str) -> bool: - """Sets the current voice for the active synthesizer.""" - server = self._get_server() - if server is None: - return False - try: - if hasattr(server, 'getVoiceFamilies') and hasattr(server, 'setVoiceFamily'): - voices = server.getVoiceFamilies() - for voice_family in voices: - if voice_family.get('name') == voice_name: - server.setVoiceFamily(voice_family) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting voice: {e}", True) - return False - - # ======================================================================== - # D-Bus Rate/Pitch/Volume Controls - # ======================================================================== - - @dbus_service.getter - def get_rate(self) -> int: - """Returns the current speech rate.""" - from . import acss - result = 50 - default_voice = settings.voices.get(settings.DEFAULT_VOICE) - if default_voice and acss.ACSS.RATE in default_voice: - result = default_voice[acss.ACSS.RATE] - return result - - @dbus_service.setter - def set_rate(self, value: int) -> bool: - """Sets the current speech rate (0-100, default: 50).""" - try: - from . import acss - default_voice = settings.voices.get(settings.DEFAULT_VOICE) - if default_voice and acss.ACSS.RATE in default_voice: - default_voice[acss.ACSS.RATE] = value - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting rate: {e}", True) - return False - - @dbus_service.getter - def get_pitch(self) -> float: - """Returns the current speech pitch.""" - from . import acss - result = 5.0 - default_voice = settings.voices.get(settings.DEFAULT_VOICE) - if default_voice and acss.ACSS.AVERAGE_PITCH in default_voice: - result = default_voice[acss.ACSS.AVERAGE_PITCH] - return result - - @dbus_service.setter - def set_pitch(self, value: float) -> bool: - """Sets the current speech pitch (0.0-10.0, default: 5.0).""" - try: - from . import acss - default_voice = settings.voices.get(settings.DEFAULT_VOICE) - if default_voice and acss.ACSS.AVERAGE_PITCH in default_voice: - default_voice[acss.ACSS.AVERAGE_PITCH] = value - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting pitch: {e}", True) - return False - - @dbus_service.getter - def get_volume(self) -> float: - """Returns the current speech volume.""" - from . import acss - result = 10.0 - default_voice = settings.voices.get(settings.DEFAULT_VOICE) - if default_voice and acss.ACSS.GAIN in default_voice: - result = default_voice[acss.ACSS.GAIN] - return result - - @dbus_service.setter - def set_volume(self, value: float) -> bool: - """Sets the current speech volume (0.0-10.0, default: 10.0).""" - try: - from . import acss - default_voice = settings.voices.get(settings.DEFAULT_VOICE) - if default_voice and acss.ACSS.GAIN in default_voice: - default_voice[acss.ACSS.GAIN] = value - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting volume: {e}", True) - return False - - # ======================================================================== - # D-Bus Speech Enable/Mute Controls - # ======================================================================== - - @dbus_service.getter - def get_speech_is_muted(self) -> bool: - """Returns whether speech output is temporarily muted.""" - return self.app.getSettingsManager().getSetting('silenceSpeech') - - @dbus_service.setter - def set_speech_is_muted(self, value: bool) -> bool: - """Sets whether speech output is temporarily muted.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('silenceSpeech', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speech mute: {e}", True) - return False - - @dbus_service.getter - def get_verbosity_level(self) -> str: - """Returns the current speech verbosity level.""" - level = cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') - if level == settings.VERBOSITY_LEVEL_BRIEF: - return "brief" - else: - return "verbose" - - @dbus_service.setter - def set_verbosity_level(self, value: str) -> bool: - """Sets the speech verbosity level.""" - try: - if value.lower() == "brief": - cthulhu.cthulhuApp.settingsManager.setSetting('speechVerbosityLevel', settings.VERBOSITY_LEVEL_BRIEF) - elif value.lower() == "verbose": - cthulhu.cthulhuApp.settingsManager.setSetting('speechVerbosityLevel', settings.VERBOSITY_LEVEL_VERBOSE) - else: - return False - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting verbosity level: {e}", True) - return False - - @dbus_service.getter - def get_speak_numbers_as_digits(self) -> bool: - """Returns whether numbers are spoken as digits.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakNumbersAsDigits') - - @dbus_service.setter - def set_speak_numbers_as_digits(self, value: bool) -> bool: - """Sets whether numbers are spoken as digits.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakNumbersAsDigits', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak numbers as digits: {e}", True) - return False - - @dbus_service.getter - def get_only_speak_displayed_text(self) -> bool: - """Returns whether only displayed text should be spoken.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText') - - @dbus_service.setter - def set_only_speak_displayed_text(self, value: bool) -> bool: - """Sets whether only displayed text should be spoken.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('onlySpeakDisplayedText', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting only speak displayed text: {e}", True) - return False - - @dbus_service.getter - def get_speak_indentation_and_justification(self) -> bool: - """Returns whether speaking of indentation and justification is enabled.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('enableSpeechIndentation') - - def _sync_indentation_presentation_mode(self, enable_speech): - mode = self.app.getSettingsManager().getSetting('indentationPresentationMode') \ - or settings.indentationPresentationMode - if enable_speech: - if mode == settings.INDENTATION_PRESENTATION_OFF: - mode = settings.INDENTATION_PRESENTATION_SPEECH - elif mode == settings.INDENTATION_PRESENTATION_BEEPS: - mode = settings.INDENTATION_PRESENTATION_SPEECH_AND_BEEPS - else: - if mode == settings.INDENTATION_PRESENTATION_SPEECH: - mode = settings.INDENTATION_PRESENTATION_OFF - elif mode == settings.INDENTATION_PRESENTATION_SPEECH_AND_BEEPS: - mode = settings.INDENTATION_PRESENTATION_BEEPS - - self.app.getSettingsManager().setSetting('indentationPresentationMode', mode) - - @dbus_service.setter - def set_speak_indentation_and_justification(self, value: bool) -> bool: - """Sets whether speaking of indentation and justification is enabled.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('enableSpeechIndentation', value) - self._sync_indentation_presentation_mode(value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak indentation: {e}", True) - return False - - @dbus_service.getter - def get_punctuation_level(self) -> str: - """Returns the current punctuation level.""" - level = cthulhu.cthulhuApp.settingsManager.getSetting('verbalizePunctuationStyle') - if level == settings.PUNCTUATION_STYLE_NONE: - return "none" - elif level == settings.PUNCTUATION_STYLE_SOME: - return "some" - elif level == settings.PUNCTUATION_STYLE_MOST: - return "most" - elif level == settings.PUNCTUATION_STYLE_ALL: - return "all" - else: - return "some" - - @dbus_service.setter - def set_punctuation_level(self, value: str) -> bool: - """Sets the punctuation level.""" - try: - value_lower = value.lower() - if value_lower == "none": - cthulhu.cthulhuApp.settingsManager.setSetting('verbalizePunctuationStyle', settings.PUNCTUATION_STYLE_NONE) - elif value_lower == "some": - cthulhu.cthulhuApp.settingsManager.setSetting('verbalizePunctuationStyle', settings.PUNCTUATION_STYLE_SOME) - elif value_lower == "most": - cthulhu.cthulhuApp.settingsManager.setSetting('verbalizePunctuationStyle', settings.PUNCTUATION_STYLE_MOST) - elif value_lower == "all": - cthulhu.cthulhuApp.settingsManager.setSetting('verbalizePunctuationStyle', settings.PUNCTUATION_STYLE_ALL) - else: - return False - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting punctuation level: {e}", True) - return False - - @dbus_service.getter - def get_capitalization_style(self) -> str: - """Returns the current capitalization style.""" - style = cthulhu.cthulhuApp.settingsManager.getSetting('capitalizationStyle') - if style == settings.CAPITALIZATION_STYLE_NONE: - return "none" - elif style == settings.CAPITALIZATION_STYLE_ICON: - return "icon" - elif style == settings.CAPITALIZATION_STYLE_SPELL: - return "spell" - else: - return "none" - - @dbus_service.setter - def set_capitalization_style(self, value: str) -> bool: - """Sets the capitalization style.""" - try: - value_lower = value.lower() - if value_lower == "none": - cthulhu.cthulhuApp.settingsManager.setSetting('capitalizationStyle', settings.CAPITALIZATION_STYLE_NONE) - elif value_lower == "icon": - cthulhu.cthulhuApp.settingsManager.setSetting('capitalizationStyle', settings.CAPITALIZATION_STYLE_ICON) - elif value_lower == "spell": - cthulhu.cthulhuApp.settingsManager.setSetting('capitalizationStyle', settings.CAPITALIZATION_STYLE_SPELL) - else: - return False - self.update_capitalization_style() - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting capitalization style: {e}", True) - return False - - # ======================================================================== - # D-Bus Verbosity Settings - # ======================================================================== - - @dbus_service.getter - def get_speak_misspelled_indicator(self) -> bool: - """Returns whether the misspelled indicator is spoken.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakMisspelledIndicator') - - @dbus_service.setter - def set_speak_misspelled_indicator(self, value: bool) -> bool: - """Sets whether the misspelled indicator is spoken.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakMisspelledIndicator', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak misspelled indicator: {e}", True) - return False - - @dbus_service.getter - def get_speak_description(self) -> bool: - """Returns whether object descriptions are spoken.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakDescription') - - @dbus_service.setter - def set_speak_description(self, value: bool) -> bool: - """Sets whether object descriptions are spoken.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakDescription', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak description: {e}", True) - return False - - @dbus_service.getter - def get_speak_position_in_set(self) -> bool: - """Returns whether the position and set size of objects are spoken.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('enablePositionSpeaking') - - @dbus_service.setter - def set_speak_position_in_set(self, value: bool) -> bool: - """Sets whether the position and set size of objects are spoken.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('enablePositionSpeaking', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak position in set: {e}", True) - return False - - @dbus_service.getter - def get_speak_widget_mnemonic(self) -> bool: - """Returns whether widget mnemonics are spoken.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('enableMnemonicSpeaking') - - @dbus_service.setter - def set_speak_widget_mnemonic(self, value: bool) -> bool: - """Sets whether widget mnemonics are spoken.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('enableMnemonicSpeaking', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak widget mnemonic: {e}", True) - return False - - @dbus_service.getter - def get_speak_tutorial_messages(self) -> bool: - """Returns whether tutorial messages are spoken.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('enableTutorialMessages') - - @dbus_service.setter - def set_speak_tutorial_messages(self, value: bool) -> bool: - """Sets whether tutorial messages are spoken.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('enableTutorialMessages', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak tutorial messages: {e}", True) - return False - - @dbus_service.getter - def get_insert_pauses_between_utterances(self) -> bool: - """Returns whether pauses are inserted between utterances, e.g. between name and role.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('enablePauseBreaks') - - @dbus_service.setter - def set_insert_pauses_between_utterances(self, value: bool) -> bool: - """Sets whether pauses are inserted between utterances, e.g. between name and role.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('enablePauseBreaks', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting insert pauses: {e}", True) - return False - - @dbus_service.getter - def get_repeated_character_limit(self) -> int: - """Returns the count at which repeated, non-alphanumeric symbols will be described.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('repeatCharacterLimit') - - @dbus_service.setter - def set_repeated_character_limit(self, value: int) -> bool: - """Sets the count at which repeated, non-alphanumeric symbols will be described.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('repeatCharacterLimit', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting repeated character limit: {e}", True) - return False - - @dbus_service.getter - def get_use_pronunciation_dictionary(self) -> bool: - """Returns whether the user's pronunciation dictionary should be applied.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('usePronunciationDictionary') - - @dbus_service.setter - def set_use_pronunciation_dictionary(self, value: bool) -> bool: - """Sets whether the user's pronunciation dictionary should be applied.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('usePronunciationDictionary', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting use pronunciation dictionary: {e}", True) - return False - - @dbus_service.getter - def get_messages_are_detailed(self) -> bool: - """Returns whether informative messages will be detailed or brief.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('messagesAreDetailed') - - @dbus_service.setter - def set_messages_are_detailed(self, value: bool) -> bool: - """Sets whether informative messages will be detailed or brief.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('messagesAreDetailed', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting messages are detailed: {e}", True) - return False - - @dbus_service.getter - def get_speak_indentation_only_if_changed(self) -> bool: - """Returns whether indentation will be announced only if it has changed.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakIndentationOnlyIfChanged') - - @dbus_service.setter - def set_speak_indentation_only_if_changed(self, value: bool) -> bool: - """Sets whether indentation will be announced only if it has changed.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakIndentationOnlyIfChanged', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak indentation only if changed: {e}", True) - return False - - # ======================================================================== - # D-Bus Table Reading Settings - # ======================================================================== - - @dbus_service.getter - def get_speak_blank_lines(self) -> bool: - """Returns whether blank lines will be spoken.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakBlankLines') - - @dbus_service.setter - def set_speak_blank_lines(self, value: bool) -> bool: - """Sets whether blank lines will be spoken.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakBlankLines', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak blank lines: {e}", True) - return False - - @dbus_service.getter - def get_speak_row_in_gui_table(self) -> bool: - """Returns whether Up/Down in GUI tables speaks the row or just the cell.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('readFullRowInGUITable') - - @dbus_service.setter - def set_speak_row_in_gui_table(self, value: bool) -> bool: - """Sets whether Up/Down in GUI tables speaks the row or just the cell.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('readFullRowInGUITable', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak row in GUI table: {e}", True) - return False - - @dbus_service.getter - def get_speak_row_in_document_table(self) -> bool: - """Returns whether Up/Down in text-document tables speaks the row or just the cell.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('readFullRowInDocumentTable') - - @dbus_service.setter - def set_speak_row_in_document_table(self, value: bool) -> bool: - """Sets whether Up/Down in text-document tables speaks the row or just the cell.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('readFullRowInDocumentTable', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak row in document table: {e}", True) - return False - - @dbus_service.getter - def get_speak_row_in_spreadsheet(self) -> bool: - """Returns whether Up/Down in spreadsheets speaks the row or just the cell.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('readFullRowInSpreadSheet') - - @dbus_service.setter - def set_speak_row_in_spreadsheet(self, value: bool) -> bool: - """Sets whether Up/Down in spreadsheets speaks the row or just the cell.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('readFullRowInSpreadSheet', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speak row in spreadsheet: {e}", True) - return False - - @dbus_service.getter - def get_announce_cell_span(self) -> bool: - """Returns whether cell spans are announced when greater than 1.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakCellSpan') - - @dbus_service.setter - def set_announce_cell_span(self, value: bool) -> bool: - """Sets whether cell spans are announced when greater than 1.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakCellSpan', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce cell span: {e}", True) - return False - - @dbus_service.getter - def get_announce_cell_coordinates(self) -> bool: - """Returns whether (non-spreadsheet) cell coordinates are announced.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakCellCoordinates') - - @dbus_service.setter - def set_announce_cell_coordinates(self, value: bool) -> bool: - """Sets whether (non-spreadsheet) cell coordinates are announced.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakCellCoordinates', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce cell coordinates: {e}", True) - return False - - @dbus_service.getter - def get_announce_spreadsheet_cell_coordinates(self) -> bool: - """Returns whether spreadsheet cell coordinates are announced.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakSpreadsheetCoordinates') - - @dbus_service.setter - def set_announce_spreadsheet_cell_coordinates(self, value: bool) -> bool: - """Sets whether spreadsheet cell coordinates are announced.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakSpreadsheetCoordinates', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce spreadsheet cell coordinates: {e}", True) - return False - - @dbus_service.getter - def get_always_announce_selected_range_in_spreadsheet(self) -> bool: - """Returns whether the selected range in spreadsheets is always announced.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('alwaysSpeakSelectedSpreadsheetRange') - - @dbus_service.setter - def set_always_announce_selected_range_in_spreadsheet(self, value: bool) -> bool: - """Sets whether the selected range in spreadsheets is always announced.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('alwaysSpeakSelectedSpreadsheetRange', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting always announce selected range: {e}", True) - return False - - @dbus_service.getter - def get_announce_cell_headers(self) -> bool: - """Returns whether cell headers are announced.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakCellHeaders') - - @dbus_service.setter - def set_announce_cell_headers(self, value: bool) -> bool: - """Sets whether cell headers are announced.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakCellHeaders', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce cell headers: {e}", True) - return False - - # ======================================================================== - # D-Bus Context Announcement Settings - # ======================================================================== - - @dbus_service.getter - def get_announce_blockquote(self) -> bool: - """Returns whether blockquotes are announced when entered.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakContextBlockquote') - - @dbus_service.setter - def set_announce_blockquote(self, value: bool) -> bool: - """Sets whether blockquotes are announced when entered.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakContextBlockquote', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce blockquote: {e}", True) - return False - - @dbus_service.getter - def get_announce_form(self) -> bool: - """Returns whether non-landmark forms are announced when entered.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakContextNonLandmarkForm') - - @dbus_service.setter - def set_announce_form(self, value: bool) -> bool: - """Sets whether non-landmark forms are announced when entered.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakContextNonLandmarkForm', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce form: {e}", True) - return False - - @dbus_service.getter - def get_announce_grouping(self) -> bool: - """Returns whether groupings are announced when entered.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakContextPanel') - - @dbus_service.setter - def set_announce_grouping(self, value: bool) -> bool: - """Sets whether groupings are announced when entered.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakContextPanel', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce grouping: {e}", True) - return False - - @dbus_service.getter - def get_announce_landmark(self) -> bool: - """Returns whether landmarks are announced when entered.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakContextLandmark') - - @dbus_service.setter - def set_announce_landmark(self, value: bool) -> bool: - """Sets whether landmarks are announced when entered.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakContextLandmark', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce landmark: {e}", True) - return False - - @dbus_service.getter - def get_announce_list(self) -> bool: - """Returns whether lists are announced when entered.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakContextList') - - @dbus_service.setter - def set_announce_list(self, value: bool) -> bool: - """Sets whether lists are announced when entered.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakContextList', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce list: {e}", True) - return False - - @dbus_service.getter - def get_announce_table(self) -> bool: - """Returns whether tables are announced when entered.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('speakContextTable') - - @dbus_service.setter - def set_announce_table(self, value: bool) -> bool: - """Sets whether tables are announced when entered.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('speakContextTable', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting announce table: {e}", True) - return False - - @dbus_service.getter - def get_use_color_names(self) -> bool: - """Returns whether colors are announced by name or as RGB values.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('useColorNames') - - @dbus_service.setter - def set_use_color_names(self, value: bool) -> bool: - """Sets whether colors are announced by name or as RGB values.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('useColorNames', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting use color names: {e}", True) - return False - - # ======================================================================== - # D-Bus Speech Control Commands - # ======================================================================== - - @dbus_service.command - def start_speech(self, script=None, event=None) -> bool: - """Starts the speech server.""" - try: - speech.init() - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error starting speech: {e}", True) - return False - - @dbus_service.command - def interrupt_speech(self, script=None, event=None) -> bool: - """Interrupts the speech server.""" - try: - server = self._get_server() - if server: - server.stop() - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error interrupting speech: {e}", True) - return False - - @dbus_service.command - def shutdown_speech(self, script=None, event=None) -> bool: - """Shuts down the speech server.""" - try: - server = self._get_server() - if server: - server.shutdownActiveServers() - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error shutting down speech: {e}", True) - return False - - @dbus_service.command - def refresh_speech(self, script=None, event=None) -> bool: - """Shuts down and re-initializes speech.""" - try: - self.shutdown_speech() - self.start_speech() - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error refreshing speech: {e}", True) - return False - - @dbus_service.setter - def set_speech_is_enabled(self, value: bool) -> bool: - """Sets whether the speech server is enabled. See also is-muted.""" - try: - cthulhu.cthulhuApp.settingsManager.setSetting('enableSpeech', value) - if value: - self.start_speech() - else: - self.shutdown_speech() - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting speech enabled: {e}", True) - return False - - @dbus_service.getter - def get_speech_is_enabled(self) -> bool: - """Returns whether the speech server is enabled. See also is-muted.""" - return cthulhu.cthulhuApp.settingsManager.getSetting('enableSpeech') - - @dbus_service.command - def decrease_rate(self, script=None, event=None): - """Decreases the speech rate""" - - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - server.decreaseSpeechRate() - if script: - script.presentMessage(messages.SPEECH_SLOWER) - return True - - @dbus_service.command - def increase_rate(self, script=None, event=None): - """Increases the speech rate""" - - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - server.increaseSpeechRate() - if script: - script.presentMessage(messages.SPEECH_FASTER) - return True - - @dbus_service.command - def decrease_pitch(self, script=None, event=None): - """Decreases the speech pitch""" - - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - server.decreaseSpeechPitch() - if script: - script.presentMessage(messages.SPEECH_LOWER) - return True - - @dbus_service.command - def increase_pitch(self, script=None, event=None): - """Increase the speech pitch""" - - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - server.increaseSpeechPitch() - if script: - script.presentMessage(messages.SPEECH_HIGHER) - return True - - @dbus_service.command - def decrease_volume(self, script=None, event=None): - """Decreases the speech volume""" - - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - server.decreaseSpeechVolume() - if script: - script.presentMessage(messages.SPEECH_SOFTER) - return True - - @dbus_service.command - def increase_volume(self, script=None, event=None): - """Increases the speech volume""" - - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - server.increaseSpeechVolume() - if script: - script.presentMessage(messages.SPEECH_LOUDER) - return True - - def update_capitalization_style(self): - """Updates the capitalization style based on the value in settings.""" - - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - server.updateCapitalizationStyle() - return True - - def update_punctuation_level(self): - """Updates the punctuation level based on the value in settings.""" - - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - server.updatePunctuationLevel() - return True - - @dbus_service.command - def cycle_synthesizer(self, script=None, event=None): - """Cycle through the speech-dispatcher's available output modules.""" - - server = self._get_server() - if server is None: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - available = server.list_output_modules() - if not available: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get output modules." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - current = server.getOutputModule() - if not current: - msg = "SPEECH AND VERBOSITY MANAGER: Cannot get current output module." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - index = available.index(current) + 1 - if index == len(available): - index = 0 - - server.setOutputModule(available[index]) - if script: - script.presentMessage(available[index]) - return True - - @dbus_service.command - def cycle_capitalization_style(self, script=None, event=None): - """Cycle through the speech-dispatcher capitalization styles.""" - - current_style = cthulhu.cthulhuApp.settingsManager.getSetting('capitalizationStyle') - if current_style == settings.CAPITALIZATION_STYLE_NONE: - new_style = settings.CAPITALIZATION_STYLE_SPELL - full = messages.CAPITALIZATION_SPELL_FULL - brief = messages.CAPITALIZATION_SPELL_BRIEF - elif current_style == settings.CAPITALIZATION_STYLE_SPELL: - new_style = settings.CAPITALIZATION_STYLE_ICON - full = messages.CAPITALIZATION_ICON_FULL - brief = messages.CAPITALIZATION_ICON_BRIEF - else: - new_style = settings.CAPITALIZATION_STYLE_NONE - full = messages.CAPITALIZATION_NONE_FULL - brief = messages.CAPITALIZATION_NONE_BRIEF - - cthulhu.cthulhuApp.settingsManager.setSetting('capitalizationStyle', new_style) - if script: - script.presentMessage(full, brief) - self.update_capitalization_style() - return True - - @dbus_service.command - def cycle_punctuation_level(self, script=None, event=None): - """Cycle through the punctuation levels for speech.""" - - current_level = cthulhu.cthulhuApp.settingsManager.getSetting('verbalizePunctuationStyle') - if current_level == settings.PUNCTUATION_STYLE_NONE: - new_level = settings.PUNCTUATION_STYLE_SOME - full = messages.PUNCTUATION_SOME_FULL - brief = messages.PUNCTUATION_SOME_BRIEF - elif current_level == settings.PUNCTUATION_STYLE_SOME: - new_level = settings.PUNCTUATION_STYLE_MOST - full = messages.PUNCTUATION_MOST_FULL - brief = messages.PUNCTUATION_MOST_BRIEF - elif current_level == settings.PUNCTUATION_STYLE_MOST: - new_level = settings.PUNCTUATION_STYLE_ALL - full = messages.PUNCTUATION_ALL_FULL - brief = messages.PUNCTUATION_ALL_BRIEF - else: - new_level = settings.PUNCTUATION_STYLE_NONE - full = messages.PUNCTUATION_NONE_FULL - brief = messages.PUNCTUATION_NONE_BRIEF - - cthulhu.cthulhuApp.settingsManager.setSetting('verbalizePunctuationStyle', new_level) - if script: - script.presentMessage(full, brief) - self.update_punctuation_level() - return True - - @dbus_service.command - def cycle_key_echo(self, script=None, event=None): - """Cycle through the key echo levels.""" - (new_key, new_word, new_sentence) = (False, False, False) - key = cthulhu.cthulhuApp.settingsManager.getSetting('enableKeyEcho') - word = cthulhu.cthulhuApp.settingsManager.getSetting('enableEchoByWord') - sentence = cthulhu.cthulhuApp.settingsManager.getSetting('enableEchoBySentence') - - if (key, word, sentence) == (False, False, False): - (new_key, new_word, new_sentence) = (True, False, False) - full = messages.KEY_ECHO_KEY_FULL - brief = messages.KEY_ECHO_KEY_BRIEF - elif (key, word, sentence) == (True, False, False): - (new_key, new_word, new_sentence) = (False, True, False) - full = messages.KEY_ECHO_WORD_FULL - brief = messages.KEY_ECHO_WORD_BRIEF - elif (key, word, sentence) == (False, True, False): - (new_key, new_word, new_sentence) = (False, False, True) - full = messages.KEY_ECHO_SENTENCE_FULL - brief = messages.KEY_ECHO_SENTENCE_BRIEF - elif (key, word, sentence) == (False, False, True): - (new_key, new_word, new_sentence) = (True, True, False) - full = messages.KEY_ECHO_KEY_AND_WORD_FULL - brief = messages.KEY_ECHO_KEY_AND_WORD_BRIEF - elif (key, word, sentence) == (True, True, False): - (new_key, new_word, new_sentence) = (False, True, True) - full = messages.KEY_ECHO_WORD_AND_SENTENCE_FULL - brief = messages.KEY_ECHO_WORD_AND_SENTENCE_BRIEF - else: - (new_key, new_word, new_sentence) = (False, False, False) - full = messages.KEY_ECHO_NONE_FULL - brief = messages.KEY_ECHO_NONE_BRIEF - - cthulhu.cthulhuApp.settingsManager.setSetting('enableKeyEcho', new_key) - cthulhu.cthulhuApp.settingsManager.setSetting('enableEchoByWord', new_word) - cthulhu.cthulhuApp.settingsManager.setSetting('enableEchoBySentence', new_sentence) - if script: - script.presentMessage(full, brief) - return True - - @dbus_service.command - def change_number_style(self, script=None, event=None): - """Changes spoken number style between digits and words.""" - - speak_digits = cthulhu.cthulhuApp.settingsManager.getSetting('speakNumbersAsDigits') - if speak_digits: - brief = messages.NUMBER_STYLE_WORDS_BRIEF - full = messages.NUMBER_STYLE_WORDS_FULL - else: - brief = messages.NUMBER_STYLE_DIGITS_BRIEF - full = messages.NUMBER_STYLE_DIGITS_FULL - - cthulhu.cthulhuApp.settingsManager.setSetting('speakNumbersAsDigits', not speak_digits) - if script: - script.presentMessage(full, brief) - return True - - @dbus_service.command - def toggle_speech(self, script, event=None): - """Toggles speech.""" - - script.presentationInterrupt() - if self.app.getSettingsManager().getSetting('silenceSpeech'): - self.app.getSettingsManager().setSetting('silenceSpeech', False) - script.presentMessage(messages.SPEECH_ENABLED) - elif not self.app.getSettingsManager().getSetting('enableSpeech'): - self.app.getSettingsManager().setSetting('enableSpeech', True) - speech.init() - script.presentMessage(messages.SPEECH_ENABLED) - else: - script.presentMessage(messages.SPEECH_DISABLED) - self.app.getSettingsManager().setSetting('silenceSpeech', True) - return True - - @dbus_service.command - def toggle_verbosity(self, script, event=None): - """Toggles speech verbosity level between verbose and brief.""" - - value = self.app.getSettingsManager().getSetting('speechVerbosityLevel') - if value == settings.VERBOSITY_LEVEL_BRIEF: - script.presentMessage(messages.SPEECH_VERBOSITY_VERBOSE) - self.app.getSettingsManager().setSetting('speechVerbosityLevel', settings.VERBOSITY_LEVEL_VERBOSE) - else: - script.presentMessage(messages.SPEECH_VERBOSITY_BRIEF) - self.app.getSettingsManager().setSetting('speechVerbosityLevel', settings.VERBOSITY_LEVEL_BRIEF) - return True - - @dbus_service.command - def toggle_indentation_and_justification(self, script=None, event=None): - """Toggles the speaking of indentation and justification.""" - - value = self.app.getSettingsManager().getSetting('enableSpeechIndentation') - self.app.getSettingsManager().setSetting('enableSpeechIndentation', not value) - self._sync_indentation_presentation_mode(not value) - if self.app.getSettingsManager().getSetting('enableSpeechIndentation'): - full = messages.INDENTATION_JUSTIFICATION_ON_FULL - brief = messages.INDENTATION_JUSTIFICATION_ON_BRIEF - else: - full = messages.INDENTATION_JUSTIFICATION_OFF_FULL - brief = messages.INDENTATION_JUSTIFICATION_OFF_BRIEF - if script: - script.presentMessage(full, brief) - return True - - @dbus_service.command - def toggle_table_cell_reading_mode(self, script=None, event=None): - """Toggles between speak cell and speak row.""" - - if not script: - return False - - table = script.utilities.getTable(cthulhu_state.locusOfFocus) - if not table: - script.presentMessage(messages.TABLE_NOT_IN_A) - return True - - if not script.utilities.getDocumentForObject(table): - setting_name = 'readFullRowInGUITable' - elif script.utilities.isSpreadSheetTable(table): - setting_name = 'readFullRowInSpreadSheet' - else: - setting_name = 'readFullRowInDocumentTable' - - speak_row = cthulhu.cthulhuApp.settingsManager.getSetting(setting_name) - cthulhu.cthulhuApp.settingsManager.setSetting(setting_name, not speak_row) - - if not speak_row: - msg = messages.TABLE_MODE_ROW - else: - msg = messages.TABLE_MODE_CELL - - script.presentMessage(msg) - return True - -_manager = None -def getManager(): - """Returns the Speech and Verbosity Manager""" - - global _manager - if _manager is None: - from . import cthulhu - _manager = SpeechAndVerbosityManager(cthulhu.cthulhuApp) - return _manager diff --git a/src/cthulhu/speech_generator.py b/src/cthulhu/speech_generator.py deleted file mode 100644 index 284bba7..0000000 --- a/src/cthulhu/speech_generator.py +++ /dev/null @@ -1,3118 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Utilities for obtaining speech utterances for objects.""" - -__id__ = "$Id:$" -__version__ = "$Revision:$" -__date__ = "$Date:$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import functools -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import urllib.parse -import urllib.request -import urllib.error -import urllib.parse - -from . import acss -from . import chnames -from . import cthulhu -from . import debug -from . import generator -from . import messages -from . import object_properties -from . import role_keys -from . import settings -from . import settings_manager -from . import sound_theme_manager -from . import speech -from . import text_attribute_names -from .ax_object import AXObject -from .ax_table import AXTable -from .ax_text import AXText -from .ax_utilities import AXUtilities -from .ax_utilities_relation import AXUtilitiesRelation - -class Pause: - """A dummy class to indicate we want to insert a pause into an - utterance.""" - def __init__(self): - pass - - def __str__(self): - return "PAUSE" - -PAUSE = [Pause()] - -class LineBreak: - """A dummy class to indicate we want to break an utterance into - separate calls to speak.""" - def __init__(self): - pass - - def __str__(self): - return "LINE BREAK" - -LINE_BREAK = [LineBreak()] - -# [[[WDW - general note -- for all the _generate* methods, it would be great if -# we could return an empty array if we can determine the method does not -# apply to the object. This would allow us to reduce the number of strings -# needed in formatting.py.]]] - -# The prefix to use for the individual generator methods -# -METHOD_PREFIX = "_generate" - -DEFAULT = "default" -UPPERCASE = "uppercase" -HYPERLINK = "hyperlink" -SYSTEM = "system" -STATE = "state" # Candidate for sound -VALUE = "value" # Candidate for sound - -voiceType = { - DEFAULT: settings.DEFAULT_VOICE, - UPPERCASE: settings.UPPERCASE_VOICE, - HYPERLINK: settings.HYPERLINK_VOICE, - SYSTEM: settings.SYSTEM_VOICE, - STATE: settings.SYSTEM_VOICE, # Users may prefer DEFAULT_VOICE here - VALUE: settings.SYSTEM_VOICE, # Users may prefer DEFAULT_VOICE here -} - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -class SpeechGenerator(generator.Generator): - """Takes accessible objects and produces a string to speak for - those objects. See the generateSpeech method, which is the primary - entry point. Subclasses can feel free to override/extend the - speechGenerators instance field as they see fit.""" - - def __init__(self, script): - generator.Generator.__init__(self, script, "speech") - - def _getRoleSoundIcon(self, obj, role): - """Return the themed sound icon for obj's role, if any.""" - - if role == Atspi.Role.LINK or AXUtilities.is_link(obj): - icon = sound_theme_manager.getManager().getLinkSoundIcon( - visited=AXUtilities.is_visited(obj) - ) - return self._spatializeRoleSoundIcon(icon, obj) - - icon = sound_theme_manager.getManager().getRoleSoundIcon(role) - return self._spatializeRoleSoundIcon(icon, obj) - - def _spatializeRoleSoundIcon(self, icon, obj): - """Spatialize icon if the experimental object sound setting is enabled.""" - - try: - enabled = cthulhu.cthulhuApp.settingsManager.getSetting('spatializeObjectSounds') - except Exception: - enabled = False - - if not enabled: - return icon - - spatialize = getattr(self._script.utilities, "spatializeSoundIcon", None) - if spatialize is None: - return icon - - return spatialize(icon, obj) - - def _addGlobals(self, globalsDict): - """Other things to make available from the formatting string. - """ - generator.Generator._addGlobals(self, globalsDict) - globalsDict['voice'] = self.voice - - def generateSpeech(self, obj, **args): - rv = self.generate(obj, **args) - if rv and not list(filter(lambda x: not isinstance(x, Pause), rv)): - tokens = ["SPEECH GENERATOR: Results for", obj, "are pauses only"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - rv = [] - - return rv - - def _resultElementToString(self, element, includeAll=True): - if isinstance(element, acss.ACSS) and not includeAll: - return "" - - if isinstance(element, list): - rv = [self._resultElementToString(x, includeAll) for x in element] - return " ".join(filter(lambda x: x, rv)) - - return super()._resultElementToString(element, includeAll) - - ##################################################################### - # # - # Name, role, and label information # - # # - ##################################################################### - - def _generateName(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the name of the object. If the object is directly - displaying any text, that text will be treated as the name. - Otherwise, the accessible name of the object will be used. If - there is no accessible name, then the description of the - object will be used. This method will return an empty array - if nothing can be found. [[[WDW - I wonder if we should just - have _generateName, _generateDescription, - _generateDisplayedText, etc., that don't do any fallback. - Then, we can allow the formatting to do the fallback (e.g., - 'displayedText or name or description'). [[[JD to WDW - I - needed a _generateDescription for whereAmI. :-) See below. - """ - - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.LAYERED_PANE \ - and cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateName(self, obj, **args) - if result: - if isinstance(result[0], str): - result[0] = self._stripRoleFromNameIfNeeded(obj, result[0], role) - if role == Atspi.Role.LAYERED_PANE: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - else: - result.extend(self.voice(DEFAULT, obj=obj, **args)) - - return result - - def _generateLabel(self, obj, **args): - """Returns the label for an object as an array of strings for use by - speech and braille. The label is determined by the displayedLabel - method of the script utility, and an empty array will be returned if - no label can be found. - """ - - result = generator.Generator._generateLabel(self, obj, **args) - if result: - role = args.get('role', AXObject.get_role(obj)) - if isinstance(result[0], str): - result[0] = self._stripRoleFromNameIfNeeded(obj, result[0], role) - result.extend(self.voice(DEFAULT, obj=obj, **args)) - return result - - def _generateLabelOrName(self, obj, **args): - """Returns the label as an array of strings for speech and braille. - If the label cannot be found, the name will be used instead. - If the name cannot be found, an empty array will be returned. - """ - - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.MENU and self._script.utilities.isPopupMenuForCurrentItem(obj): - tokens = ["SPEECH GENERATOR:", obj, "is popup menu for current item."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - result = [] - result.extend(self._generateLabel(obj, **args)) - if not result: - name = AXObject.get_name(obj) - if name: - name = self._stripRoleFromNameIfNeeded(obj, name, role) - result.append(name) - result.extend(self.voice(DEFAULT, obj=obj, **args)) - if result: - return result - - parent = AXObject.get_parent(obj) - if AXUtilities.is_autocomplete(parent): - result = self._generateLabelOrName(parent, **args) - - return result - - def _stripRoleFromNameIfNeeded(self, obj, name, role=None): - if not name: - return name - - roleSoundPresentation = cthulhu.cthulhuApp.settingsManager.getSetting('roleSoundPresentation') - if roleSoundPresentation != settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY: - return name - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableSound'): - return name - - if not self._shouldStripRoleFromName(obj): - return name - - candidates = self._getRoleNameStripCandidates(obj, role) - if not candidates: - return name - - strippedName = name.strip() - strippedNameLower = strippedName.casefold() - for candidate in candidates: - candidate = candidate.strip() - if not candidate: - continue - - candidateLower = candidate.casefold() - if strippedNameLower == candidateLower: - continue - - suffix = f" {candidateLower}" - if strippedNameLower.endswith(suffix): - return strippedName[:-(len(candidateLower) + 1)].rstrip() - - suffix = f" ({candidateLower})" - if strippedNameLower.endswith(suffix): - return strippedName[:-(len(candidateLower) + 3)].rstrip() - - return name - - def _shouldStripRoleFromName(self, obj): - return AXUtilities.is_check_box(obj) \ - or AXUtilities.is_check_menu_item(obj) \ - or AXUtilities.is_combo_box(obj) \ - or AXUtilities.is_push_button(obj) \ - or AXUtilities.is_radio_button(obj) \ - or AXUtilities.is_radio_menu_item(obj) \ - or AXUtilities.is_toggle_button(obj) \ - or AXUtilities.is_switch(obj) - - def _getRoleNameStripCandidates(self, obj, role=None): - normalizedRole = role - if isinstance(normalizedRole, str): - if normalizedRole == role_keys.ROLE_SWITCH: - normalizedRole = Atspi.Role.SWITCH - else: - normalizedRole = None - - candidates = [] - if normalizedRole is None and isinstance(role, str): - localizedRoleName = self.getLocalizedRoleName(obj) - else: - localizedRoleName = self.getLocalizedRoleName(obj, role=normalizedRole or role) - if localizedRoleName: - candidates.append(localizedRoleName) - if " " in localizedRoleName: - candidates.append(localizedRoleName.replace(" ", "")) - - if normalizedRole is not None and not isinstance(normalizedRole, str): - roleName = Atspi.role_get_name(normalizedRole) - if roleName: - candidates.append(roleName) - if " " in roleName: - candidates.append(roleName.replace(" ", "")) - - if AXUtilities.is_push_button(obj): - candidates.append("button") - - return list(dict.fromkeys(candidates)) - - def _generatePlaceholderText(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the 'placeholder' text. This is typically text that - serves as a functional label and is found in a text widget until - that widget is given focus at which point the text is removed, - the assumption being that the user was able to see the text prior - to giving the widget focus. - """ - - result = generator.Generator._generatePlaceholderText(self, obj, **args) - if result: - result.extend(self.voice(DEFAULT, obj=obj, **args)) - return result - - def _generateAlertText(self, obj, **args): - result = self._generateExpandedEOCs(obj, **args) \ - or self._generateUnrelatedLabels(obj, **args) - if result: - self._script.pointOfReference['usedDescriptionForAlert'] = False - return result - - args['alerttext'] = True - result = self._generateDescription(obj, **args) - if result: - self._script.pointOfReference['usedDescriptionForAlert'] = True - - return result - - def _generateDescription(self, obj, **args): - """Returns an array of strings fo use by speech and braille that - represent the description of the object, if that description - is different from that of the name and label. - """ - - alreadyUsed = False - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.ALERT: - try: - alreadyUsed = self._script.pointOfReference.pop('usedDescriptionForAlert') - except Exception: - pass - else: - try: - alreadyUsed = self._script.pointOfReference.pop('usedDescriptionForUnrelatedLabels') - except Exception: - pass - - if alreadyUsed: - return [] - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not cthulhu.cthulhuApp.settingsManager.getSetting('speakDescription') and not args.get('alerttext'): - return [] - - if args.get('inMouseReview') and not cthulhu.cthulhuApp.settingsManager.getSetting('presentToolTips'): - return [] - - priorObj = args.get('priorObj') - if AXUtilities.is_tool_tip(priorObj): - return [] - - if priorObj == obj: - return [] - - result = generator.Generator._generateDescription(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateImageDescription(self, obj, **args ): - """Returns an array of strings for use by speech and braille that - represent the description of the image on the object.""" - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not cthulhu.cthulhuApp.settingsManager.getSetting('speakDescription'): - return [] - - result = generator.Generator._generateImageDescription(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateReadOnly(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the read only state of this object, but only if it - is read only (i.e., it is a text area that cannot be edited). - """ - - result = generator.Generator._generateReadOnly(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateHasPopup(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText') \ - or cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') \ - == settings.VERBOSITY_LEVEL_BRIEF: - return [] - - result = generator.Generator._generateHasPopup(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateClickable(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText') \ - or cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') \ - == settings.VERBOSITY_LEVEL_BRIEF: - return [] - - result = generator.Generator._generateClickable(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateHasLongDesc(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateHasLongDesc(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateHasDetails(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateHasDetails(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateDetailsFor(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateDetailsFor(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateAllDetails(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateAllDetails(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateDeletionStart(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - startOffset = args.get('startOffset', 0) - if startOffset != 0: - return [] - - result = [] - if self._script.utilities.isFirstItemInInlineContentSuggestion(obj): - result.extend([object_properties.ROLE_CONTENT_SUGGESTION]) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - result.extend(self._generatePause(obj, **args)) - - result.extend([messages.CONTENT_DELETION_START]) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateDeletionEnd(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - endOffset = args.get('endOffset') - if endOffset is not None: - if self._script.utilities.queryNonEmptyText(obj) \ - and AXText.get_character_count(obj) != endOffset: - return [] - - result = [messages.CONTENT_DELETION_END] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - if self._script.utilities.isLastItemInInlineContentSuggestion(obj): - result.extend(self._generatePause(obj, **args)) - result.extend([messages.CONTENT_SUGGESTION_END]) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - container = AXObject.find_ancestor(obj, self._script.utilities.hasDetails) - if self._script.utilities.isContentSuggestion(container): - result.extend(self._generatePause(obj, **args)) - result.extend(self._generateHasDetails(container, mode=args.get('mode'))) - - return result - - def _generateInsertionStart(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - startOffset = args.get('startOffset', 0) - if startOffset != 0: - return [] - - result = [] - if self._script.utilities.isFirstItemInInlineContentSuggestion(obj): - result.extend([object_properties.ROLE_CONTENT_SUGGESTION]) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - result.extend(self._generatePause(obj, **args)) - - result.extend([messages.CONTENT_INSERTION_START]) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateInsertionEnd(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - endOffset = args.get('endOffset') - if endOffset is not None: - if self._script.utilities.queryNonEmptyText(obj) \ - and AXText.get_character_count(obj) != endOffset: - return [] - - result = [messages.CONTENT_INSERTION_END] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - if self._script.utilities.isLastItemInInlineContentSuggestion(obj): - result.extend(self._generatePause(obj, **args)) - result.extend([messages.CONTENT_SUGGESTION_END]) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - container = AXObject.find_ancestor(obj, self._script.utilities.hasDetails) - if self._script.utilities.isContentSuggestion(container): - result.extend(self._generatePause(obj, **args)) - result.extend(self._generateHasDetails(container, mode=args.get('mode'))) - - return result - - def _generateMarkStart(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - startOffset = args.get('startOffset', 0) - if startOffset != 0: - return [] - - result = [] - roledescription = self._script.utilities.getRoleDescription(obj) - if roledescription: - result.append(roledescription) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - result.extend(self._generatePause(obj, **args)) - - result.append(messages.CONTENT_MARK_START) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateMarkEnd(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - endOffset = args.get('endOffset') - if endOffset is not None: - if self._script.utilities.queryNonEmptyText(obj) \ - and AXText.get_character_count(obj) != endOffset: - return [] - - result = [messages.CONTENT_MARK_END] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateAvailability(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateAvailability(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateInvalid(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateInvalid(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateRequired(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateRequired(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateTable(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if args.get("leaving"): - return[] - - if self._script.utilities.isTextDocumentTable(obj): - role = args.get('role', AXObject.get_role(obj)) - enabled, disabled = self._getEnabledAndDisabledContextRoles() - if role in disabled: - return [] - - if cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') == settings.VERBOSITY_LEVEL_BRIEF: - return self._generateRoleName(obj, **args) - - result = generator.Generator._generateTable(self, obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateTextRole(self, obj, **args): - """A convenience method to prevent the Atspi.Role.PARAGRAPH role - from being spoken. In the case of a Atspi.Role.PARAGRAPH - role, an empty array will be returned. In all other cases, the - role name will be returned as an array of strings (and - possibly voice and audio specifications). Note that a 'role' - attribute in args will override the accessible role of the - obj. [[[WDW - I wonder if this should be moved to - _generateRoleName. Or, maybe make a 'do not speak roles' attribute - of a speech generator that we can update and the user can - override.]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - role = args.get('role', AXObject.get_role(obj)) - if role != Atspi.Role.PARAGRAPH: - result.extend(self._generateRoleName(obj, **args)) - return result - - def _generateRoleName(self, obj, **args): - """Returns the role name for the object in an array of strings (and - possibly voice and audio specifications), with the exception - that the Atspi.Role.UNKNOWN role will yield an empty array. - Note that a 'role' attribute in args will override the - accessible role of the obj. - """ - # Prevent role repetition when object is same as prior object - if obj == args.get("priorObj"): - return [] - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if self._script.utilities.isStatusBarNotification(obj): - return [] - - if self._script.utilities.isDesktop(obj): - return [] - - if self._script.utilities.isDockedFrame(obj): - return [] - - result = [] - role = args.get('role', AXObject.get_role(obj)) - roleSoundPresentation = cthulhu.cthulhuApp.settingsManager.getSetting('roleSoundPresentation') - soundEnabled = cthulhu.cthulhuApp.settingsManager.getSetting('enableSound') - roleSoundIcon = None - if roleSoundPresentation != settings.ROLE_SOUND_PRESENTATION_SPEECH_ONLY \ - and soundEnabled: - roleSoundIcon = self._getRoleSoundIcon(obj, role) - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY \ - and soundEnabled: - # Stateful controls present their role via state sounds; suppress - # spoken role names here even if no dedicated role icon exists. - if AXUtilities.is_check_box(obj) \ - or AXUtilities.is_check_menu_item(obj) \ - or AXUtilities.is_radio_button(obj) \ - or AXUtilities.is_radio_menu_item(obj) \ - or AXUtilities.is_toggle_button(obj) \ - or AXUtilities.is_switch(obj): - return [] - - doNotPresent = [Atspi.Role.UNKNOWN, - Atspi.Role.REDUNDANT_OBJECT, - Atspi.Role.FILLER, - Atspi.Role.EXTENDED] - - parent = AXObject.get_parent(obj) - if role == Atspi.Role.MENU and AXUtilities.is_combo_box(parent): - return self._generateRoleName(parent) - - if self._script.utilities.isSingleLineAutocompleteEntry(obj): - result.append(self.getLocalizedRoleName(obj, role=Atspi.Role.AUTOCOMPLETE)) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - if role == Atspi.Role.PANEL \ - and AXUtilities.is_selected(obj): - return [] - - # egg-list-box-style containers can expose selected panels as list items. - if AXUtilities.is_list_box(parent): - doNotPresent.append(AXObject.get_role(obj)) - - if self._script.utilities.isStatusBarDescendant(obj): - doNotPresent.append(Atspi.Role.LABEL) - - if cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') \ - == settings.VERBOSITY_LEVEL_BRIEF: - doNotPresent.extend([Atspi.Role.ICON, Atspi.Role.CANVAS]) - - if role == Atspi.Role.HEADING: - level = self._script.utilities.headingLevel(obj) - if level: - result.append(object_properties.ROLE_HEADING_LEVEL_SPEECH % { - 'role': self.getLocalizedRoleName(obj, **args), - 'level': level}) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - if role not in doNotPresent and not result: - result.append(self.getLocalizedRoleName(obj, **args)) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY: - if roleSoundIcon: - return [roleSoundIcon] - return result - - if result and roleSoundIcon: - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_AND_SPEECH: - return [roleSoundIcon] + result - - return result - - def getRoleName(self, obj, **args): - """Returns the role name for the object in an array of strings (and - possibly voice and audio specifications), with the exception - that the Atspi.Role.UNKNOWN role will yield an empty array. - Note that a 'role' attribute in args will override the - accessible role of the obj. This is provided mostly as a - method for scripts to call. - """ - generated = self._generateRoleName(obj, **args) - return self._getFirstString(generated) - - def getName(self, obj, **args): - generated = self._generateName(obj, **args) - return self._getFirstString(generated) - - def _getFirstString(self, generated): - for item in generated or []: - if isinstance(item, str): - return item - if isinstance(item, list): - nestedString = self._getFirstString(item) - if nestedString: - return nestedString - - return "" - - def getLocalizedRoleName(self, obj, **args): - """Returns the localized name of the given Accessible object; the name - is suitable to be spoken. - - Arguments: - - obj: an Accessible object - """ - - if self._script.utilities.isEditableComboBox(obj) \ - or self._script.utilities.isEditableDescendantOfComboBox(obj): - return object_properties.ROLE_EDITABLE_COMBO_BOX - - role = args.get('role', AXObject.get_role(obj)) - if role == Atspi.Role.LINK and AXUtilities.is_visited(obj): - return object_properties.ROLE_VISITED_LINK - - return super().getLocalizedRoleName(obj, **args) - - def _generateUnrelatedLabels(self, obj, **args): - """Returns, as an array of strings (and possibly voice - specifications), all the labels which are underneath the obj's - hierarchy and which are not in a label for or labelled by - relation. - """ - result = [] - visibleOnly = not self._script.utilities.isStatusBarNotification(obj) - - minimumWords = 1 - role = args.get('role', AXObject.get_role(obj)) - if role in [Atspi.Role.DIALOG, Atspi.Role.PANEL]: - minimumWords = 3 - - labels = self._script.utilities.unrelatedLabels(obj, visibleOnly, minimumWords) - for label in labels: - name = self._generateName(label, **args) - if name and len(name[0]) == 1: - charname = chnames.getCharacterName(name[0]) - if charname: - name[0] = charname - result.extend(name) - if result: - result.extend(self.voice(DEFAULT, obj=obj, **args)) - return result - - ##################################################################### - # # - # State information # - # # - ##################################################################### - - def _applyStateSound(self, result, role, stateKey, obj=None): - if not result: - return result - - roleSoundPresentation = cthulhu.cthulhuApp.settingsManager.getSetting('roleSoundPresentation') - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SPEECH_ONLY: - return result - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableSound'): - return result - - icon = sound_theme_manager.getManager().getRoleStateSoundIcon(role, stateKey) - if not icon: - return result - icon = self._spatializeRoleSoundIcon(icon, obj) - - if roleSoundPresentation == settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY: - return [icon] - - return [icon] + result - - def _generateCheckedState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the checked state of the object. This is typically - for check boxes. [[[WDW - should we return an empty array if - we can guarantee we know this thing is not checkable?]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateCheckedState(self, obj, **args) - if result: - result.extend(self.voice(STATE, obj=obj, **args)) - role = args.get('role', AXObject.get_role(obj)) - if AXUtilities.is_checkable(obj) or AXUtilities.is_check_menu_item(obj): - role = Atspi.Role.CHECK_BOX - if AXUtilities.is_indeterminate(obj): - stateKey = "mixed" - elif AXUtilities.is_checked(obj): - stateKey = "checked" - else: - stateKey = "unchecked" - result = self._applyStateSound(result, role, stateKey, obj) - return result - - def _generateExpandableState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the expanded/collapsed state of an object, such as a - tree node. If the object is not expandable, an empty array - will be returned. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateExpandableState(self, obj, **args) - if result: - result.extend(self.voice(STATE, obj=obj, **args)) - return result - - def _generateCheckedStateIfCheckable(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = super()._generateCheckedStateIfCheckable(obj, **args) - if result: - result.extend(self.voice(STATE, obj=obj, **args)) - return result - - def _generateMenuItemCheckedState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the checked state of the menu item, only if it is - checked. Otherwise, and empty array will be returned. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator.\ - _generateMenuItemCheckedState(self, obj, **args) - if result: - result.extend(self.voice(STATE, obj=obj, **args)) - result = self._applyStateSound( - result, - Atspi.Role.CHECK_MENU_ITEM, - "checked", - obj, - ) - return result - - def _generateMultiselectableState(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the multiselectable state of - the object. This is typically for list boxes. If the object - is not multiselectable, an empty array will be returned. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = super()._generateMultiselectableState(obj, **args) - if result: - result.extend(self.voice(STATE, obj=obj, **args)) - return result - - def _generateRadioState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the checked state of the object. This is typically - for check boxes. [[[WDW - should we return an empty array if - we can guarantee we know this thing is not checkable?]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateRadioState(self, obj, **args) - if result: - result.extend(self.voice(STATE, obj=obj, **args)) - stateKey = "checked" if AXUtilities.is_checked(obj) else "unchecked" - role = args.get('role', AXObject.get_role(obj)) - result = self._applyStateSound(result, role, stateKey, obj) - return result - - def _generateSwitchState(self, obj, **args): - """Returns an array of strings indicating the on/off state of obj.""" - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateSwitchState(self, obj, **args) - if result: - result.extend(self.voice(STATE, obj=obj, **args)) - stateKey = "checked" if (AXUtilities.is_checked(obj) or AXUtilities.is_pressed(obj)) \ - else "unchecked" - role = args.get('role', AXObject.get_role(obj)) - result = self._applyStateSound(result, role, stateKey, obj) - return result - - def _generateToggleState(self, obj, **args): - """Returns an array of strings for use by speech and braille that - represent the checked state of the object. This is typically - for check boxes. [[[WDW - should we return an empty array if - we can guarantee we know this thing is not checkable?]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = generator.Generator._generateToggleState(self, obj, **args) - if result: - result.extend(self.voice(STATE, obj=obj, **args)) - stateKey = "checked" if (AXUtilities.is_checked(obj) or AXUtilities.is_pressed(obj)) \ - else "unchecked" - role = args.get('role', AXObject.get_role(obj)) - result = self._applyStateSound(result, role, stateKey, obj) - return result - - ##################################################################### - # # - # Link information # - # # - ##################################################################### - - def _generateLinkInfo(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the protocol of the URI of - the link associated with obj. - """ - result = [] - # Get the URI for the link of interest and parse it. The parsed - # URI is returned as a tuple containing six components: - # scheme://netloc/path;parameters?query#fragment. - # - link_uri = self._script.utilities.uri(obj) - if not link_uri: - # [[[TODO - JD: For some reason, this is failing for certain - # links. The current whereAmI code says, "It might be an anchor. - # Try to speak the text." and passes things off to whereAmI's - # _speakText method. That won't work in the new world order. - # Therefore, for now, I will hack in some code to do that - # work here so that the before and after end results match.]]] - # - result.extend(self._generateLabel(obj)) - result.extend(self._generateRoleName(obj)) - result.append(self._script.utilities.displayedText(obj)) - else: - link_uri_info = urllib.parse.urlparse(link_uri) - if link_uri_info[0] in ["ftp", "ftps", "file"]: - fileName = link_uri_info[2].split('/') - result.append(messages.LINK_TO_FILE \ - % {"uri" : link_uri_info[0], - "file" : fileName[-1]}) - else: - linkOutput = messages.LINK_WITH_PROTOCOL % link_uri_info[0] - text = self._script.utilities.displayedText(obj) - isVisited = AXUtilities.is_visited(obj) - if not isVisited: - linkOutput = messages.LINK_WITH_PROTOCOL % link_uri_info[0] - else: - linkOutput = messages.LINK_WITH_PROTOCOL_VISITED % link_uri_info[0] - if not text: - # If there's no text for the link, expose part of the - # URI to the user. - # - text = self._script.utilities.linkBasename(obj) - if text: - linkOutput += " " + text - result.append(linkOutput) - child = AXObject.get_child(obj, 0) - if AXUtilities.is_image(child): - result.extend(self._generateRoleName(child)) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateSiteDescription(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that describe the site (same or different) - pointed to by the URI of the link associated with obj. - """ - result = [] - link_uri = self._script.utilities.uri(obj) - if link_uri: - link_uri_info = urllib.parse.urlparse(link_uri) - else: - return result - doc_uri = self._script.utilities.documentFrameURI() - if doc_uri: - doc_uri_info = urllib.parse.urlparse(doc_uri) - if link_uri_info[1] == doc_uri_info[1]: - if link_uri_info[2] == doc_uri_info[2]: - result.append(messages.LINK_SAME_PAGE) - else: - result.append(messages.LINK_SAME_SITE) - else: - # check for different machine name on same site - # - linkdomain = link_uri_info[1].split('.') - docdomain = doc_uri_info[1].split('.') - if len(linkdomain) > 1 and len(docdomain) > 1 \ - and linkdomain[-1] == docdomain[-1] \ - and linkdomain[-2] == docdomain[-2]: - result.append(messages.LINK_SAME_SITE) - else: - result.append(messages.LINK_DIFFERENT_SITE) - - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateFileSize(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the size (Content-length) of - the file pointed to by the URI of the link associated with - obj. - """ - result = [] - sizeString = "" - uri = self._script.utilities.uri(obj) - if not uri: - return result - try: - x = urllib.request.urlopen(uri) - try: - sizeString = x.info()['Content-length'] - except KeyError: - pass - except (ValueError, urllib.error.URLError, OSError): - pass - if sizeString: - size = int(sizeString) - if size < 10000: - result.append(messages.fileSizeBytes(size)) - elif size < 1000000: - result.append(messages.FILE_SIZE_KB % (float(size) * .001)) - elif size >= 1000000: - result.append(messages.FILE_SIZE_MB % (float(size) * .000001)) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - ##################################################################### - # # - # Image information # - # # - ##################################################################### - - def _generateImage(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the image on the object, if - it exists. Otherwise, an empty array is returned. - """ - result = [] - if AXObject.supports_image(obj): - args['role'] = Atspi.Role.IMAGE - result.extend(self.generate(obj, **args)) - result.extend(self.voice(DEFAULT, obj=obj, **args)) - return result - - ##################################################################### - # # - # Table interface information # - # # - ##################################################################### - - def _generateColumnHeader(self, obj, **args): - if self._script.inSayAll(): - return [] - - result = super()._generateColumnHeader(obj, **args) - if result: - result.extend(self.voice(DEFAULT, obj=obj, **args)) - - return result - - def _generateRowHeader(self, obj, **args): - if self._script.inSayAll(): - return [] - - result = super()._generateRowHeader(obj, **args) - if result: - result.extend(self.voice(DEFAULT, obj=obj, **args)) - - return result - - def _generateSortOrder(self, obj, **args): - result = super()._generateSortOrder(obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - return result - - def _generateNewRowHeader(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the row header for an object - that is in a table, if it exists and if it is different from - the previous row header. Otherwise, an empty array is - returned. The previous row header is determined by looking at - the row header for the 'priorObj' attribute of the args - dictionary. The 'priorObj' is typically set by Cthulhu to be the - previous object with focus. - """ - - if not self._script.utilities.cellRowChanged(obj): - return [] - - if args.get('readingRow'): - return [] - - if not cthulhu.cthulhuApp.settingsManager.getSetting('speakCellHeaders'): - return [] - - if args.get('inMouseReview') and args.get('priorObj'): - thisrow, thiscol = self._script.utilities.coordinatesForCell(obj) - lastrow, lastcol = self._script.utilities.coordinatesForCell(args.get('priorObj')) - if thisrow == lastrow: - return [] - - args['newOnly'] = True - return self._generateRowHeader(obj, **args) - - def _generateNewColumnHeader(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the column header for an object - that is in a table, if it exists and if it is different from - the previous column header. Otherwise, an empty array is - returned. The previous column header is determined by looking - at the column header for the 'priorObj' attribute of the args - dictionary. The 'priorObj' is typically set by Cthulhu to be the - previous object with focus. - """ - - if not self._script.utilities.cellColumnChanged(obj): - return [] - - if args.get('readingRow'): - return [] - - if not cthulhu.cthulhuApp.settingsManager.getSetting('speakCellHeaders'): - return [] - - if args.get('inMouseReview') and args.get('priorObj'): - thisrow, thiscol = self._script.utilities.coordinatesForCell(obj) - lastrow, lastcol = self._script.utilities.coordinatesForCell(args.get('priorObj')) - if thiscol == lastcol: - return [] - - args['newOnly'] = True - return self._generateColumnHeader(obj, **args) - - def _generateRealTableCell(self, obj, **args): - """Cthulhu has a feature to automatically read an entire row of a table - as the user arrows up/down the roles. This leads to complexity in - the code. This method is used to return an array of strings - (and possibly voice and audio specifications) for a single table - cell itself. The string, 'blank', is added for empty cells. - """ - result = [] - oldRole = self._overrideRole(role_keys.REAL_ROLE_TABLE_CELL, args) - result.extend(self.generate(obj, **args)) - self._restoreRole(oldRole, args) - if not (result and result[0]) \ - and cthulhu.cthulhuApp.settingsManager.getSetting('speakBlankLines') \ - and not args.get('readingRow', False) \ - and args.get('formatType') != 'ancestor': - result.append(messages.BLANK) - if result: - result.extend(self.voice(DEFAULT, obj=obj, **args)) - - return result - - def _generateUnselectedStateIfSelectable(self, obj, **args): - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if args.get('inMouseReview'): - return [] - - if not obj: - return [] - - if not AXObject.supports_selection(AXObject.get_parent(obj)): - return [] - - if AXUtilities.is_selected(obj): - return [] - - result = [object_properties.STATE_UNSELECTED_LIST_ITEM] - result.extend(self.voice(STATE, obj=obj, **args)) - - return result - - def _generateUnselectedCell(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) if this is an icon within an layered pane or a - table cell within a table or a tree table and the item is - focused but not selected. Otherwise, an empty array is - returned. [[[WDW - I wonder if this string should be moved to - settings.py.]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if args.get('inMouseReview'): - return [] - - if not obj: - return [] - - parent = AXObject.get_parent(obj) - if not AXObject.supports_selection(parent): - return [] - - if AXUtilities.is_selected(obj): - return [] - - if AXUtilities.is_text(obj): - return [] - - table = self._script.utilities.getTable(obj) - if table: - lastKey, mods = self._script.utilities.lastKeyAndModifiers() - if lastKey in ["Left", "Right"]: - return [] - if self._script.utilities.isLayoutOnly(table): - return [] - elif AXUtilities.is_layered_pane(parent): - if obj in self._script.utilities.selectedChildren(parent): - return [] - else: - return [] - - result = [object_properties.STATE_UNSELECTED_TABLE_CELL] - result.extend(self.voice(STATE, obj=obj, **args)) - - return result - - def _generateNewColumn(self, obj, **args): - if not self._script.utilities.cellColumnChanged(obj): - return [] - - if args.get('readingRow'): - return [] - - if not cthulhu.cthulhuApp.settingsManager.getSetting('speakCellCoordinates'): - return [] - - return self._generateColumn(obj, **args) - - def _generateColumn(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) reflecting the column number of a cell. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - col = -1 - parent = AXObject.get_parent(obj) - if AXUtilities.is_table_cell(parent): - obj = parent - row, col = self._script.utilities.coordinatesForCell(obj, False) - if col < 0 and args.get('guessCoordinates', False): - col = self._script.pointOfReference.get('lastColumn', -1) - if col >= 0: - result.append(messages.TABLE_COLUMN % (col + 1)) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateNewRow(self, obj, **args): - if not self._script.utilities.cellRowChanged(obj): - return [] - - if args.get('readingRow'): - return [] - - if not cthulhu.cthulhuApp.settingsManager.getSetting('speakCellCoordinates'): - return [] - - return self._generateRow(obj, **args) - - def _generateRow(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) reflecting the row number of a cell. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - row = -1 - parent = AXObject.get_parent(obj) - if AXUtilities.is_table_cell(parent): - obj = parent - row, col = self._script.utilities.coordinatesForCell(obj, False) - if row < 0 and args.get('guessCoordinates', False): - row = self._script.pointOfReference.get('lastRow', -1) - if row >= 0: - result.append(messages.TABLE_ROW % (row + 1)) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateColumnAndRow(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) reflecting the position of the cell in terms - of its column number, the total number of columns, its row, - and the total number of rows. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - parent = AXObject.get_parent(obj) - if AXUtilities.is_table_cell(parent): - obj = parent - table = self._script.utilities.getTable(obj) - if table: - row, col = self._script.utilities.coordinatesForCell(obj, False) - rows, cols = self._script.utilities.rowAndColumnCount(table, False) - if row >= 0 and col >= 0 and rows > 0 and cols > 0: - result.append(messages.TABLE_COLUMN_DETAILED \ - % {"index" : (col + 1), - "total" : cols}) - result.append(messages.TABLE_ROW_DETAILED \ - % {"index" : (row + 1), - "total" : rows}) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateEndOfTableIndicator(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) indicating that this cell is the last cell - in the table. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') \ - != settings.VERBOSITY_LEVEL_VERBOSE: - return [] - - if self._script.utilities.isLastCell(obj): - result = [messages.TABLE_END] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - return [] - - ##################################################################### - # # - # Text interface information # - # # - ##################################################################### - - def _generateCurrentLineText(self, obj, **args): - """Returns an array of strings for use by speech and braille - that represents the current line of text, if - this is a text object. [[[WDW - consider returning an empty - array if this is not a text object.]]] - """ - - if args.get('inMouseReview') \ - and AXUtilities.is_editable(obj): - return [] - - result = self._generateSubstring(obj, **args) - if result and result[0]: - return result - - [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj) - if text == '\n' and cthulhu.cthulhuApp.settingsManager.getSetting('speakBlankLines') \ - and not self._script.inSayAll() and args.get('total', 1) == 1 \ - and args.get('formatType') != 'ancestor': - result = [messages.BLANK] - result.extend(self.voice(string=text, obj=obj, **args)) - return result - - result = [] - endOffset = startOffset + len(text) - split = self._script.utilities.splitSubstringByLanguage(obj, startOffset, endOffset) - for start, end, string, language, dialect in split: - string = string.replace(self._script.EMBEDDED_OBJECT_CHARACTER, "") - if not string: - continue - args["language"], args["dialect"] = language, dialect - if "string" in args: - msg = f"INFO: Found existing string '{args.get('string')}'; using '{string}'" - debug.printMessage(debug.LEVEL_INFO, msg, True) - args.pop("string") - - voice = self.voice(string=string, obj=obj, **args) - string, linkIcons = self._script.utilities.getLinkIndicatorPresentation(obj, string, start) - rv = [self._script.utilities.adjustForRepeats(string)] - rv.extend(voice) - rv.extend(linkIcons) - - # TODO - JD: speech.speak() has a bug which causes a list of utterances to - # be presented before a string+voice pair that comes first. Until we can - # fix speak() properly, we'll avoid triggering it here. - # result.append(rv) - result.extend(rv) - - return result - - def _generateDisplayedText(self, obj, **args): - result = self._generateSubstring(obj, **args) - if result and result[0]: - return result - - result = generator.Generator._generateDisplayedText(self, obj, **args) - if not (result and result[0]): - return [] - - string = result[0].strip() - if len(string) == 1 and self._script.utilities.isMath(obj): - charname = chnames.getCharacterName(string, preferMath=True) - if charname and charname != string: - result[0] = charname - - result.extend(self.voice(DEFAULT, obj=obj, **args)) - return result - - def _getCharacterAttributes(self, - obj, - text, - textOffset, - lineIndex, - keys=["style", "weight", "underline"]): - """Helper function that returns a string containing the - given attributes from keys for the given character. - """ - attribStr = "" - - attributesDictionary, _, _ = AXText.get_text_attributes_at_offset(obj, textOffset) - - if attributesDictionary: - for key in keys: - localizedKey = text_attribute_names.getTextAttributeName( - key, self._script) - if key in attributesDictionary: - attribute = attributesDictionary[key] - localizedValue = text_attribute_names.getTextAttributeName( - attribute, self._script) - if attribute: - # If it's the 'weight' attribute and greater than 400, - # just speak it as bold, otherwise speak the weight. - # - if key == "weight": - if int(attribute) > 400: - attribStr += f" {messages.BOLD}" - elif key == "underline": - if attribute != "none": - attribStr += f" {localizedKey}" - elif key == "style": - if attribute != "normal": - attribStr += f" {localizedValue}" - else: - attribStr += " " - attribStr += (localizedKey + " " + localizedValue) - - # Also check to see if this is a hypertext link. - # - if self._script.utilities.linkIndex(obj, textOffset) >= 0: - attribStr += f" {messages.LINK}" - - return attribStr - - def _getTextInformation(self, obj): - """Returns [textContents, startOffset, endOffset, selected] as - follows: - - A. if no text on the current line is selected, the current line - B. if text is selected, the selected text - C. if the current line is blank/empty, 'blank' - - Also sets up a 'textInformation' attribute in - self._script.generatorCache to prevent computing this - information repeatedly while processing a single event. - """ - - try: - return self._script.generatorCache['textInformation'] - except Exception: - pass - - if not AXObject.supports_text(obj): - self._script.generatorCache['textInformation'] = ["", 0, 0, False] - return self._script.generatorCache['textInformation'] - - caretOffset = AXText.get_caret_offset(obj) - - textContents, startOffset, endOffset = self._script.utilities.allSelectedText(obj) - selected = textContents != "" - - if not selected: - # Get the line containing the caret - # - [line, startOffset, endOffset] = AXText.get_line_at_offset(obj, caretOffset) - if len(line): - line = self._script.utilities.adjustForRepeats(line) - textContents = line - else: - char, charStart, charEnd = AXText.get_character_at_offset(obj, caretOffset) - if char == "\n" and startOffset == caretOffset: - textContents = char - - if self._script.utilities.shouldVerbalizeAllPunctuation(obj): - textContents = self._script.utilities.verbalizeAllPunctuation(textContents) - - self._script.generatorCache['textInformation'] = \ - [textContents, startOffset, endOffset, selected] - - return self._script.generatorCache['textInformation'] - - def _generateTextContent(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) containing the text content. This requires - _generateTextInformation to have been called prior to this method. - """ - - result = self._generateSubstring(obj, **args) - if result: - return result - - if not AXObject.supports_text(obj): - return [] - - result = [] - [line, startOffset, endOffset, selected] = self._getTextInformation(obj) - - # The empty string seems to be messing with using 'or' in - # formatting strings. - # - if line: - result.append(line) - result.extend(self.voice(DEFAULT, obj=obj, **args)) - - return result - - def _generateTextContentWithAttributes(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) containing the text content, obtained from the - 'textInformation' value, with character attribute information - mixed in. This requires _generateTextInformation to have been - called prior to this method. - """ - - if not AXObject.supports_text(obj): - return [] - - [line, startOffset, endOffset, selected] = self._getTextInformation(obj) - - newLine = "" - lastAttribs = None - textOffset = startOffset - for i in range(0, len(line)): - attribs = self._getCharacterAttributes(obj, None, textOffset, i) - if attribs and attribs != lastAttribs: - if newLine: - newLine += " ; " - newLine += attribs - newLine += " " - lastAttribs = attribs - newLine += line[i] - textOffset += 1 - - attribs = self._getCharacterAttributes(obj, - None, - startOffset, - 0, - ["paragraph-style"]) - - if attribs: - if newLine: - newLine += " ; " - newLine += attribs - - result = [newLine] - result.extend(self.voice(DEFAULT, obj=obj, **args)) - return result - - def _generateAnyTextSelection(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that says if any of the text for the entire - object is selected. [[[WDW - I wonder if this string should be - moved to settings.py.]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if not AXObject.supports_text(obj): - return [] - - result = [] - [line, startOffset, endOffset, selected] = self._getTextInformation(obj) - - if selected: - result.append(messages.TEXT_SELECTED) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateAllTextSelection(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that says if all the text for the entire - object is selected. [[[WDW - I wonder if this string should be - moved to settings.py.]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - if AXObject.supports_text(obj): - selections = self._script.utilities.allTextSelections(obj) - if len(selections) == 1: - startOffset, endOffset = selections[0] - if startOffset == 0 and endOffset >= AXText.get_character_count(obj): - result = [messages.TEXT_SELECTED] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateSubstring(self, obj, **args): - result = super()._generateSubstring(obj, **args) - if not (result and result[0]): - return [] - - result.extend(self.voice(DEFAULT, obj=obj, **args)) - if result[0] in ['\n', ''] and cthulhu.cthulhuApp.settingsManager.getSetting('speakBlankLines') \ - and not self._script.inSayAll() and args.get('total', 1) == 1 \ - and args.get('formatType') != 'ancestor': - result[0] = messages.BLANK - - if self._script.utilities.shouldVerbalizeAllPunctuation(obj): - result[0] = self._script.utilities.verbalizeAllPunctuation(result[0]) - - return result - - def _generateTextIndentation(self, obj, **args): - """Speaks a summary of the number of spaces and/or tabs at the - beginning of the given line. - - Arguments: - - obj: the text object. - """ - - if not cthulhu.cthulhuApp.settingsManager.getSetting('enableSpeechIndentation'): - return [] - - line, caretOffset, startOffset = self._script.getTextLineAtCaret(obj) - description, _hasIndentation = \ - self._script.utilities.get_indentation_presentation(line, obj=obj) - if not description: - return [] - - result = [description] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateNestingLevel(self, obj, **args): - result = super()._generateNestingLevel(obj, **args) - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - return result - - ##################################################################### - # # - # Tree interface information # - # # - ##################################################################### - - def _generateNewNodeLevel(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represents the tree node level of the - object, or an empty array if the object is not a tree node or - if the node level is not different from the 'priorObj' - 'priorObj' attribute of the args dictionary. The 'priorObj' - is typically set by Cthulhu to be the previous object with - focus. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - oldLevel = self._script.utilities.nodeLevel(args.get('priorObj', None)) - newLevel = self._script.utilities.nodeLevel(obj) - if (oldLevel != newLevel) and (newLevel >= 0): - result.extend(self._generateNodeLevel(obj, **args)) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - ##################################################################### - # # - # Value interface information # - # # - ##################################################################### - - def _generateValue(self, obj, **args): - result = super()._generateValue(obj, **args) - if result: - result.extend(self.voice(DEFAULT, obj=obj, **args)) - - return result - - def _generatePercentage(self, obj, **args ): - """Returns an array of strings (and possibly voice and audio - specifications) that represents the percentage value of the - object. This is typically for progress bars. [[[WDW - we - should consider returning an empty array if there is no value. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - percentValue = self._script.utilities.getValueAsPercent(obj) - if percentValue is not None: - result = [messages.percentage(percentValue)] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - return [] - - ##################################################################### - # # - # Hierarchy and related dialog information # - # # - ##################################################################### - - def _generateNewRadioButtonGroup(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represents the radio button group label - of the object, or an empty array if the object has no such - label or if the radio button group is not different from the - 'priorObj' 'priorObj' attribute of the args dictionary. The - 'priorObj' is typically set by Cthulhu to be the previous object - with focus. - """ - - if not AXUtilities.is_radio_button(obj): - return [] - - result = super()._generateRadioButtonGroup(obj, **args) - if not result: - return [] - - result.extend(self.voice(DEFAULT, obj=obj, **args)) - priorObj = args.get('priorObj', None) - if not AXUtilities.is_radio_button(priorObj): - return result - - # TODO - JD: We need other ways to determine group membership. Not all - # implementations expose the member-of relation. Gtk3 does. Others are TBD. - members = AXUtilitiesRelation.get_is_member_of(obj) - if priorObj not in members: - return result - - return [] - - def _generateTermValueCount(self, obj, **args): - count = self._script.utilities.getValueCountForTerm(obj) - # If we have a simple 1-term, 1-value situation, this announcment is chatty. - if count in (-1, 1): - return [] - - result = [messages.valueCountForTerm(count)] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateNumberOfChildren(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represents the number of children the - object has. [[[WDW - can we always return an empty array if - this doesn't apply?]]] [[[WDW - I wonder if this string should - be moved to settings.py.]]] - """ - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText') \ - or cthulhu.cthulhuApp.settingsManager.getSetting('speechVerbosityLevel') == settings.VERBOSITY_LEVEL_BRIEF: - return [] - - result = [] - childNodes = self._script.utilities.childNodes(obj) - children = len(childNodes) - if children: - result.append(messages.itemCount(children)) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - role = args.get('role', AXObject.get_role(obj)) - if role in [Atspi.Role.LIST, Atspi.Role.LIST_BOX]: - children = [x for x in AXObject.iter_children(obj, AXUtilities.is_list_item)] - setsize = len(children) - if not setsize: - return [] - - result = [messages.listItemCount(setsize)] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - return result - - def _generateNoShowingChildren(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that says if this object has no showing - children (e.g., it's an empty table or list). object has. - [[[WDW - can we always return an empty array if this doesn't - apply?]]] [[[WDW - I wonder if this string should be moved to - settings.py.]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - hasItems = any(True for _ in AXObject.iter_children(obj, AXUtilities.is_showing)) - if not hasItems: - result.append(messages.ZERO_ITEMS) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateNoChildren(self, obj, **args ): - """Returns an array of strings (and possibly voice and audio - specifications) that says if this object has no children at - all (e.g., it's an empty table or list). object has. [[[WDW - - can we always return an empty array if this doesn't - apply?]]] [[[WDW - I wonder if this string should be moved to - settings.py.]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - if not AXObject.get_child_count(obj): - result.append(messages.ZERO_ITEMS) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateFocusedItem(self, obj, **args): - result = [] - role = args.get('role', AXObject.get_role(obj)) - if role not in [Atspi.Role.LIST, Atspi.Role.LIST_BOX]: - return result - - if AXObject.supports_selection(obj): - items = self._script.utilities.selectedChildren(obj) - else: - items = [AXUtilities.get_focused_object(obj)] - if not (items and items[0]): - return result - - for item in map(self._generateName, items): - result.extend(item) - - return result - - def _generateSelectedItemCount(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) indicating how many items are selected in this - and the position of the current item. This object will be an icon - panel or a layered pane. - """ - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - container = obj - if not AXObject.supports_selection(container): - container = AXObject.get_parent(obj) - if not AXObject.supports_selection(container): - return [] - - result = [] - childCount = AXObject.get_child_count(container) - selectedCount = len(self._script.utilities.selectedChildren(container)) - result.append(messages.selectedItemsCount(selectedCount, childCount)) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - result.append(self._script.formatting.getString( - mode='speech', - stringType='iconindex') \ - % {"index" : AXObject.get_index_in_parent(obj) + 1, - "total" : childCount}) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateSelectedItems(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) containing the names of all the selected items. - This object will be an icon panel or a layered pane. - """ - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - container = obj - if not AXObject.supports_selection(container): - container = AXObject.get_parent(obj) - if not AXObject.supports_selection(container): - return [] - - selectedItems = self._script.utilities.selectedChildren(container) - return list(map(self._generateLabelAndName, selectedItems)) - - def generateSelectedItems(self, obj, **args): - return self._generateSelectedItems(obj, **args) - - def _generateUnfocusedDialogCount(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that says how many unfocused alerts and - dialogs are associated with the application for this object. - [[[WDW - I wonder if this string should be moved to - settings.py.]]] - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - # If this application has more than one unfocused alert or - # dialog window, then speak ' unfocused dialogs' - # to let the user know. - # - try: - alertAndDialogCount = \ - self._script.utilities.unfocusedAlertAndDialogCount(obj) - except Exception: - alertAndDialogCount = 0 - if alertAndDialogCount > 0: - result.append(messages.dialogCountSpeech(alertAndDialogCount)) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _getEnabledAndDisabledContextRoles(self): - allRoles = [Atspi.Role.BLOCK_QUOTE, - role_keys.ROLE_CONTENT_DELETION, - role_keys.ROLE_CONTENT_INSERTION, - role_keys.ROLE_CONTENT_MARK, - role_keys.ROLE_CONTENT_SUGGESTION, - role_keys.ROLE_DPUB_LANDMARK, - role_keys.ROLE_DPUB_SECTION, - Atspi.Role.DESCRIPTION_LIST, - role_keys.ROLE_FEED, - Atspi.Role.FORM, - Atspi.Role.LANDMARK, - Atspi.Role.LIST, - Atspi.Role.PANEL, - role_keys.ROLE_REGION, - Atspi.Role.TABLE, - Atspi.Role.TOOL_TIP] - - enabled, disabled = [], [] - if self._script.inSayAll(): - if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextBlockquote'): - enabled.append(Atspi.Role.BLOCK_QUOTE) - if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextLandmark'): - enabled.extend([Atspi.Role.LANDMARK, role_keys.ROLE_DPUB_LANDMARK]) - if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextList'): - enabled.append(Atspi.Role.LIST) - enabled.append(Atspi.Role.DESCRIPTION_LIST) - enabled.append(role_keys.ROLE_FEED) - if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextPanel'): - enabled.extend([Atspi.Role.PANEL, - Atspi.Role.TOOL_TIP, - role_keys.ROLE_CONTENT_DELETION, - role_keys.ROLE_CONTENT_INSERTION, - role_keys.ROLE_CONTENT_MARK, - role_keys.ROLE_CONTENT_SUGGESTION, - role_keys.ROLE_DPUB_SECTION]) - if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextNonLandmarkForm'): - enabled.append(Atspi.Role.FORM) - if cthulhu.cthulhuApp.settingsManager.getSetting('sayAllContextTable'): - enabled.append(Atspi.Role.TABLE) - else: - if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextBlockquote'): - enabled.append(Atspi.Role.BLOCK_QUOTE) - if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextLandmark'): - enabled.extend([Atspi.Role.LANDMARK, role_keys.ROLE_DPUB_LANDMARK, - role_keys.ROLE_REGION]) - if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextList'): - enabled.append(Atspi.Role.LIST) - enabled.append(Atspi.Role.DESCRIPTION_LIST) - enabled.append(role_keys.ROLE_FEED) - if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextPanel'): - enabled.extend([Atspi.Role.PANEL, - Atspi.Role.TOOL_TIP, - role_keys.ROLE_CONTENT_DELETION, - role_keys.ROLE_CONTENT_INSERTION, - role_keys.ROLE_CONTENT_MARK, - role_keys.ROLE_CONTENT_SUGGESTION, - role_keys.ROLE_DPUB_SECTION]) - if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextNonLandmarkForm'): - enabled.append(Atspi.Role.FORM) - if cthulhu.cthulhuApp.settingsManager.getSetting('speakContextTable'): - enabled.append(Atspi.Role.TABLE) - - disabled = list(set(allRoles).symmetric_difference(enabled)) - return enabled, disabled - - def _generateLeaving(self, obj, **args): - if not args.get('leaving'): - return [] - - role = args.get('role', AXObject.get_role(obj)) - enabled, disabled = self._getEnabledAndDisabledContextRoles() - if not (role in enabled or self._script.utilities.isDetails(obj)): - return [] - - count = args.get('count', 1) - - result = [] - if self._script.utilities.isDetails(obj): - result.append(messages.LEAVING_DETAILS) - elif role == Atspi.Role.BLOCK_QUOTE: - if count > 1: - result.append(messages.leavingNBlockquotes(count)) - else: - result.append(messages.LEAVING_BLOCKQUOTE) - elif role in [Atspi.Role.LIST, Atspi.Role.DESCRIPTION_LIST] \ - and self._script.utilities.isDocumentList(obj): - if count > 1: - result.append(messages.leavingNLists(count)) - else: - result.append(messages.LEAVING_LIST) - elif role == role_keys.ROLE_FEED: - result.append(messages.LEAVING_FEED) - elif role == Atspi.Role.PANEL: - if self._script.utilities.isFigure(obj): - result.append(messages.LEAVING_FIGURE) - elif self._script.utilities.isDocumentPanel(obj): - result.append(messages.LEAVING_PANEL) - else: - result = [''] - elif role == Atspi.Role.TABLE and self._script.utilities.isTextDocumentTable(obj): - result.append(messages.LEAVING_TABLE) - elif role == role_keys.ROLE_DPUB_LANDMARK: - if self._script.utilities.isDPubAcknowledgments(obj): - result.append(messages.LEAVING_ACKNOWLEDGMENTS) - elif self._script.utilities.isDPubAfterword(obj): - result.append(messages.LEAVING_AFTERWORD) - elif self._script.utilities.isDPubAppendix(obj): - result.append(messages.LEAVING_APPENDIX) - elif self._script.utilities.isDPubBibliography(obj): - result.append(messages.LEAVING_BIBLIOGRAPHY) - elif self._script.utilities.isDPubChapter(obj): - result.append(messages.LEAVING_CHAPTER) - elif self._script.utilities.isDPubConclusion(obj): - result.append(messages.LEAVING_CONCLUSION) - elif self._script.utilities.isDPubCredits(obj): - result.append(messages.LEAVING_CREDITS) - elif self._script.utilities.isDPubEndnotes(obj): - result.append(messages.LEAVING_ENDNOTES) - elif self._script.utilities.isDPubEpilogue(obj): - result.append(messages.LEAVING_EPILOGUE) - elif self._script.utilities.isDPubErrata(obj): - result.append(messages.LEAVING_ERRATA) - elif self._script.utilities.isDPubForeword(obj): - result.append(messages.LEAVING_FOREWORD) - elif self._script.utilities.isDPubGlossary(obj): - result.append(messages.LEAVING_GLOSSARY) - elif self._script.utilities.isDPubIndex(obj): - result.append(messages.LEAVING_INDEX) - elif self._script.utilities.isDPubIntroduction(obj): - result.append(messages.LEAVING_INTRODUCTION) - elif self._script.utilities.isDPubPagelist(obj): - result.append(messages.LEAVING_PAGELIST) - elif self._script.utilities.isDPubPart(obj): - result.append(messages.LEAVING_PART) - elif self._script.utilities.isDPubPreface(obj): - result.append(messages.LEAVING_PREFACE) - elif self._script.utilities.isDPubPrologue(obj): - result.append(messages.LEAVING_PROLOGUE) - elif self._script.utilities.isDPubToc(obj): - result.append(messages.LEAVING_TOC) - elif role == role_keys.ROLE_DPUB_SECTION: - if self._script.utilities.isDPubAbstract(obj): - result.append(messages.LEAVING_ABSTRACT) - elif self._script.utilities.isDPubColophon(obj): - result.append(messages.LEAVING_COLOPHON) - elif self._script.utilities.isDPubCredit(obj): - result.append(messages.LEAVING_CREDIT) - elif self._script.utilities.isDPubDedication(obj): - result.append(messages.LEAVING_DEDICATION) - elif self._script.utilities.isDPubEpigraph(obj): - result.append(messages.LEAVING_EPIGRAPH) - elif self._script.utilities.isDPubExample(obj): - result.append(messages.LEAVING_EXAMPLE) - elif self._script.utilities.isDPubPullquote(obj): - result.append(messages.LEAVING_PULLQUOTE) - elif self._script.utilities.isDPubQna(obj): - result.append(messages.LEAVING_QNA) - elif self._script.utilities.isLandmark(obj): - if self._script.utilities.isLandmarkBanner(obj): - result.append(messages.LEAVING_LANDMARK_BANNER) - elif self._script.utilities.isLandmarkComplementary(obj): - result.append(messages.LEAVING_LANDMARK_COMPLEMENTARY) - elif self._script.utilities.isLandmarkContentInfo(obj): - result.append(messages.LEAVING_LANDMARK_CONTENTINFO) - elif self._script.utilities.isLandmarkMain(obj): - result.append(messages.LEAVING_LANDMARK_MAIN) - elif self._script.utilities.isLandmarkNavigation(obj): - result.append(messages.LEAVING_LANDMARK_NAVIGATION) - elif self._script.utilities.isLandmarkRegion(obj): - result.append(messages.LEAVING_LANDMARK_REGION) - elif self._script.utilities.isLandmarkSearch(obj): - result.append(messages.LEAVING_LANDMARK_SEARCH) - elif self._script.utilities.isLandmarkForm(obj): - result.append(messages.LEAVING_FORM) - else: - result = [''] - elif role == Atspi.Role.FORM: - result.append(messages.LEAVING_FORM) - elif role == Atspi.Role.TOOL_TIP: - result.append(messages.LEAVING_TOOL_TIP) - elif role == role_keys.ROLE_CONTENT_DELETION: - result.append(messages.CONTENT_DELETION_END) - elif role == role_keys.ROLE_CONTENT_INSERTION: - result.append(messages.CONTENT_INSERTION_END) - elif role == role_keys.ROLE_CONTENT_MARK: - result.append(messages.CONTENT_MARK_END) - elif role == role_keys.ROLE_CONTENT_SUGGESTION \ - and not self._script.utilities.isInlineSuggestion(obj): - result.append(messages.LEAVING_SUGGESTION) - else: - result = [''] - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - return result - - def _generateAncestors(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the text of the ancestors for - the object. This is typically used to present the context for - an object (e.g., the names of the window, the panels, etc., - that the object is contained in). If the 'priorObj' attribute - of the args dictionary is set, only the differences in - ancestry between the 'priorObj' and the current obj will be - computed. The 'priorObj' is typically set by Cthulhu to be the - previous object with focus. - """ - result = [] - - leaving = args.get('leaving') - if leaving and args.get('priorObj'): - priorObj = obj - obj = args.get('priorObj') - else: - priorObj = args.get('priorObj') - - if priorObj and AXObject.is_dead(priorObj): - return [] - - if AXUtilities.is_tool_tip(priorObj): - return [] - - if priorObj and AXObject.get_parent(priorObj) == AXObject.get_parent(obj): - return [] - - if self._script.utilities.isTypeahead(priorObj): - return [] - - if AXUtilities.is_page_tab(obj): - return [] - - if AXUtilities.is_tool_tip(obj): - return [] - - commonAncestor = self._script.utilities.commonAncestor(priorObj, obj) - if obj == commonAncestor: - return [] - - includeOnly = args.get('includeOnly', []) - - skipRoles = args.get('skipRoles', []) - skipRoles.append(Atspi.Role.TREE_ITEM) - enabled, disabled = self._getEnabledAndDisabledContextRoles() - skipRoles.extend(disabled) - - stopAtRoles = args.get('stopAtRoles', []) - stopAtRoles.extend([Atspi.Role.APPLICATION, Atspi.Role.MENU_BAR]) - - stopAfterRoles = args.get('stopAfterRoles', []) - stopAfterRoles.extend([Atspi.Role.TOOL_TIP]) - - presentOnce = [Atspi.Role.BLOCK_QUOTE, Atspi.Role.LIST] - - presentCommonAncestor = False - if commonAncestor and not leaving: - commonRole = self._getAlternativeRole(commonAncestor) - if commonRole in presentOnce: - def pred(x): - return self._getAlternativeRole(x) == commonRole - objAncestor = AXObject.find_ancestor(obj, pred) - priorAncestor = AXObject.find_ancestor(priorObj, pred) - objLevel = self._script.utilities.nestingLevel(objAncestor) - priorLevel = self._script.utilities.nestingLevel(priorAncestor) - presentCommonAncestor = objLevel != priorLevel - - ancestors, ancestorRoles = [], [] - parent = AXObject.get_parent_checked(obj) - while parent: - parentRole = self._getAlternativeRole(parent) - if parentRole in stopAtRoles: - break - if parentRole in skipRoles: - pass - elif includeOnly and parentRole not in includeOnly: - pass - elif self._script.utilities.isLayoutOnly(parent): - pass - elif self._script.utilities.isButtonWithPopup(parent): - pass - elif parent != commonAncestor or presentCommonAncestor: - ancestors.append(parent) - ancestorRoles.append(parentRole) - - if parent == commonAncestor or parentRole in stopAfterRoles: - break - - parent = AXObject.get_parent_checked(parent) - - presentedRoles = [] - for i, x in enumerate(ancestors): - altRole = ancestorRoles[i] - if altRole in presentOnce and altRole in presentedRoles: - continue - - presentedRoles.append(altRole) - count = ancestorRoles.count(altRole) - self._overrideRole(altRole, args) - result.append( - self.generate(x, formatType='ancestor', role=altRole, - leaving=leaving, count=count, ancestorOf=obj, priorObj=priorObj)) - self._restoreRole(altRole, args) - - if not leaving: - result.reverse() - return result - - def _generateOldAncestors(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the text of the ancestors for - the object being left.""" - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if self._script.utilities.inFindContainer(): - return [] - - priorObj = args.get('priorObj') - if not priorObj or obj == priorObj or self._script.utilities.isZombie(priorObj): - return [] - - if AXUtilities.is_page_tab(obj): - return [] - - if AXObject.get_application(obj) != AXObject.get_application(priorObj) \ - or AXObject.find_ancestor(obj, lambda x: x == priorObj): - return [] - - frame, dialog = self._script.utilities.frameAndDialog(obj) - if dialog: - return [] - - args['leaving'] = True - args['includeOnly'] = [Atspi.Role.BLOCK_QUOTE, - Atspi.Role.DESCRIPTION_LIST, - Atspi.Role.FORM, - Atspi.Role.LANDMARK, - role_keys.ROLE_CONTENT_DELETION, - role_keys.ROLE_CONTENT_INSERTION, - role_keys.ROLE_CONTENT_MARK, - role_keys.ROLE_CONTENT_SUGGESTION, - role_keys.ROLE_DPUB_LANDMARK, - role_keys.ROLE_DPUB_SECTION, - role_keys.ROLE_FEED, - Atspi.Role.LIST, - Atspi.Role.PANEL, - role_keys.ROLE_REGION, - Atspi.Role.TABLE, - Atspi.Role.TOOL_TIP] - - result = [] - if self._script.utilities.isBlockquote(priorObj): - oldRole = self._getAlternativeRole(priorObj) - self._overrideRole(oldRole, args) - result.extend(self.generate( - priorObj, role=oldRole, formatType='focused', leaving=True)) - self._restoreRole(oldRole, args) - - result.extend(self._generateAncestors(obj, **args)) - args.pop('leaving') - args.pop('includeOnly') - - return result - - def _generateNewAncestors(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the text of the ancestors for - the object. This is typically used to present the context for - an object (e.g., the names of the window, the panels, etc., - that the object is contained in). If the 'priorObj' attribute - of the args dictionary is set, only the differences in - ancestry between the 'priorObj' and the current obj will be - computed. Otherwise, no ancestry will be computed. The - 'priorObj' is typically set by Cthulhu to be the previous object - with focus. - """ - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - if self._script.utilities.inFindContainer(): - return [] - - priorObj = args.get('priorObj') - if priorObj == obj: - return [] - - role = args.get('role', AXObject.get_role(obj)) - if role in [Atspi.Role.FRAME, Atspi.Role.WINDOW]: - return [] - - if role == Atspi.Role.MENU_ITEM and (not priorObj or AXUtilities.is_window(priorObj)): - return [] - - if priorObj is not None: - return self._generateAncestors(obj, **args) - - frame, dialog = self._script.utilities.frameAndDialog(obj) - topLevel = dialog or frame - if AXUtilities.is_dialog_or_alert(topLevel): - return self._generateAncestors(obj, **args) - - return [] - - def generateContext(self, obj, **args): - if args.get('priorObj') == obj: - return [] - - result = self._generateOldAncestors(obj, **args) - result.append(self._generateNewAncestors(obj, **args)) - return result - - def _generateParentRoleName(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) containing the role name of the parent of obj. - """ - if args.get('role', AXObject.get_role(obj)) == Atspi.Role.ICON \ - and args.get('formatType', None) \ - in ['basicWhereAmI', 'detailedWhereAmI']: - return [object_properties.ROLE_ICON_PANEL] - - parent = AXObject.get_parent(obj) - if AXUtilities.is_table_cell(parent) or AXUtilities.is_menu(parent): - obj = parent - return self._generateRoleName(AXObject.get_parent(obj)) - - def _generateToolbar(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) containing the name and role of the toolbar - which contains obj. - """ - result = [] - ancestor = AXObject.find_ancestor(obj, AXUtilities.is_tool_bar) - if ancestor: - result.extend(self._generateLabelAndName(ancestor)) - result.extend(self._generateRoleName(ancestor)) - return result - - def _generatePositionInGroup(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the relative position of an - object in a group. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - # TODO - JD: We need other ways to determine group membership. Not all - # implementations expose the member-of relation. Gtk3 does. Others are TBD. - members = [m for m in AXUtilitiesRelation.get_is_member_of(obj) if AXUtilities.is_showing(m)] - if obj not in members: - return [] - - result = [] - - # TODO - JD: We used to adjust the position on the basis of this particular - # relation "tending to be given in the reverse order". But there's no reason - # that should be the case. And doesn't always appear to be the case in Gtk3. - # Until we sort out the position in group/list mess, try a more reliable - # "adjustment." - def cmp(x, y): - return AXObject.get_index_in_parent(y) - AXObject.get_index_in_parent(x) - - members = sorted(members, key=functools.cmp_to_key(cmp)) - result.append(self._script.formatting.getString( - mode='speech', - stringType='groupindex') \ - % {"index" : members.index(obj) + 1, - "total" : len(members)}) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generatePositionInList(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the relative position of an - object in a list. - """ - - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText') \ - or not (cthulhu.cthulhuApp.settingsManager.getSetting('enablePositionSpeaking') \ - or args.get('forceList', False)): - return [] - - if self._script.utilities.isTopLevelMenu(obj): - return [] - - if self._script.utilities.isEditableComboBox(obj): - return [] - - result = [] - position, total = self._script.utilities.getPositionAndSetSize(obj, **args) - if position < 0: - return [] - - stringType = 'groupindex' - if total < 0: - if not self._script.utilities.setSizeUnknown(obj): - return [] - stringType += 'totalunknown' - - if total == 1 and AXUtilities.is_menu(obj): - return [] - - position += 1 - result.append(self._script.formatting.getString( - mode='speech', - stringType=stringType) \ - % {"index" : position, - "total" : total}) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateProgressBarIndex(self, obj, **args): - if not args.get('isProgressBarUpdate') \ - or not self._shouldPresentProgressBarUpdate(obj, **args): - return [] - - result = [] - acc, updateTime, updateValue = self._getMostRecentProgressBarUpdate() - if acc != obj: - number, count = self.getProgressBarNumberAndCount(obj) - result = [messages.PROGRESS_BAR_NUMBER % (number)] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - return result - - def _generateProgressBarValue(self, obj, **args): - if args.get('isProgressBarUpdate') \ - and not self._shouldPresentProgressBarUpdate(obj, **args): - return [''] - - result = [] - percent = self._script.utilities.getValueAsPercent(obj) - if percent is not None: - result.append(messages.percentage(percent)) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - return result - - def _getProgressBarUpdateInterval(self): - interval = cthulhu.cthulhuApp.settingsManager.getSetting('progressBarSpeechInterval') - if interval is None: - interval = super()._getProgressBarUpdateInterval() - - return int(interval) - - def _shouldPresentProgressBarUpdate(self, obj, **args): - if not cthulhu.cthulhuApp.settingsManager.getSetting('speakProgressBarUpdates'): - return False - - return super()._shouldPresentProgressBarUpdate(obj, **args) - - def _generateStatusBar(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the status bar of a window. - """ - - if not AXUtilities.is_status_bar(obj): - return [] - - items = self._script.utilities.statusBarItems(obj) - if not items or items == [obj]: - return [] - - result = [] - for child in items: - if child == obj: - continue - - childResult = self.generate(child, includeContext=False) - if childResult: - result.extend(childResult) - if not isinstance(childResult[-1], Pause): - result.extend(self._generatePause(child, **args)) - - return result - - def generateTitle(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the title of the window, obj. - containing the object, along with information associated with - any unfocused dialog boxes. - """ - result = [] - frame, dialog = self._script.utilities.frameAndDialog(obj) - if frame: - frameResult = self._generateLabelAndName(frame) - if not frameResult: - frameResult = self._generateRoleName(frame) - result.append(frameResult) - - if dialog: - result.append(self._generateLabelAndName(dialog)) - - alertAndDialogCount = self._script.utilities.unfocusedAlertAndDialogCount(obj) - if alertAndDialogCount > 0: - dialogs = [messages.dialogCountSpeech(alertAndDialogCount)] - dialogs.extend(self.voice(DEFAULT, obj=obj, **args)) - result.append(dialogs) - return result - - def _generateListBoxItemWidgets(self, obj, **args): - if not AXUtilities.is_list_box(AXObject.get_parent(obj)): - return [] - - result = [] - widgets = AXUtilities.get_all_widgets(obj) - for widget in widgets: - result.append(self.generate(widget, includeContext=False)) - return result - - ##################################################################### - # # - # Keyboard shortcut information # - # # - ##################################################################### - - def _generateAccelerator(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the accelerator for the object, - or an empty array if no accelerator can be found. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - [mnemonic, shortcut, accelerator] = \ - self._script.utilities.mnemonicShortcutAccelerator(obj) - if accelerator: - result.append(accelerator) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - return result - - def _generateMnemonic(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the mnemonic for the object, or - an empty array if no mnemonic can be found. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - if cthulhu.cthulhuApp.settingsManager.getSetting('enableMnemonicSpeaking') \ - or args.get('forceMnemonic', False): - [mnemonic, shortcut, accelerator] = \ - self._script.utilities.mnemonicShortcutAccelerator(obj) - if mnemonic: - mnemonic = mnemonic[-1] # we just want a single character - if not mnemonic and shortcut: - mnemonic = shortcut - if mnemonic: - result = [mnemonic] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - return result - - ##################################################################### - # # - # Tutorial information # - # # - ##################################################################### - - def _generateTutorial(self, obj, **args): - """Returns an array of strings (and possibly voice and audio - specifications) that represent the tutorial for the object. - The tutorial will only be generated if the user has requested - tutorials, and will then be generated according to the - tutorial generator. A tutorial can be forced by setting the - 'forceTutorial' attribute of the args dictionary to True. - """ - if cthulhu.cthulhuApp.settingsManager.getSetting('onlySpeakDisplayedText'): - return [] - - result = [] - alreadyFocused = args.get('alreadyFocused', False) - forceTutorial = args.get('forceTutorial', False) - role = args.get('role', AXObject.get_role(obj)) - result.extend(self._script.tutorialGenerator.getTutorial( - obj, - alreadyFocused, - forceTutorial, - role)) - if args.get('role', AXObject.get_role(obj)) == Atspi.Role.ICON \ - and args.get('formatType', 'unfocused') == 'basicWhereAmI': - frame, dialog = self._script.utilities.frameAndDialog(obj) - if frame: - result.extend(self._script.tutorialGenerator.getTutorial( - frame, - alreadyFocused, - forceTutorial)) - if result and result[0]: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - # Math - - def _generateMath(self, obj, **args): - result = [] - children = [child for child in AXObject.iter_children(obj)] - if not children and not self._script.utilities.isMathTopLevel(obj): - children = [obj] - - for child in children: - if self._script.utilities.isMathLayoutOnly(child) and AXObject.get_child_count(child): - result.extend(self._generateMath(child)) - continue - - oldRole = self._getAlternativeRole(child) - self._overrideRole(oldRole, args) - result.extend(self.generate(child, role=oldRole)) - self._restoreRole(oldRole, args) - - return result - - def _generateEnclosedBase(self, obj, **args): - return self._generateMath(obj, **args) - - def _generateEnclosedEnclosures(self, obj, **args): - strings = [] - enclosures = self._script.utilities.getMathEnclosures(obj) - if 'actuarial' in enclosures: - strings.append(messages.MATH_ENCLOSURE_ACTUARIAL) - if 'box' in enclosures: - strings.append(messages.MATH_ENCLOSURE_BOX) - if 'circle' in enclosures: - strings.append(messages.MATH_ENCLOSURE_CIRCLE) - if 'longdiv' in enclosures: - strings.append(messages.MATH_ENCLOSURE_LONGDIV) - if 'radical' in enclosures: - strings.append(messages.MATH_ENCLOSURE_RADICAL) - if 'roundedbox' in enclosures: - strings.append(messages.MATH_ENCLOSURE_ROUNDEDBOX) - if 'horizontalstrike' in enclosures: - strings.append(messages.MATH_ENCLOSURE_HORIZONTALSTRIKE) - if 'verticalstrike' in enclosures: - strings.append(messages.MATH_ENCLOSURE_VERTICALSTRIKE) - if 'downdiagonalstrike' in enclosures: - strings.append(messages.MATH_ENCLOSURE_DOWNDIAGONALSTRIKE) - if 'updiagonalstrike' in enclosures: - strings.append(messages.MATH_ENCLOSURE_UPDIAGONALSTRIKE) - if 'northeastarrow' in enclosures: - strings.append(messages.MATH_ENCLOSURE_NORTHEASTARROW) - if 'bottom' in enclosures: - strings.append(messages.MATH_ENCLOSURE_BOTTOM) - if 'left' in enclosures: - strings.append(messages.MATH_ENCLOSURE_LEFT) - if 'right' in enclosures: - strings.append(messages.MATH_ENCLOSURE_RIGHT) - if 'top' in enclosures: - strings.append(messages.MATH_ENCLOSURE_TOP) - if 'phasorangle' in enclosures: - strings.append(messages.MATH_ENCLOSURE_PHASOR_ANGLE) - if 'madruwb' in enclosures: - strings.append(messages.MATH_ENCLOSURE_MADRUWB) - if not strings: - tokens = ["SPEECH GENERATOR: Could not get enclosure message for", enclosures] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - if len(strings) == 1: - result = [messages.MATH_ENCLOSURE_ENCLOSED_BY % strings[0]] - else: - strings.insert(-1, messages.MATH_ENCLOSURE_AND) - if len(strings) == 3: - result = [messages.MATH_ENCLOSURE_ENCLOSED_BY % " ".join(strings)] - else: - result = [messages.MATH_ENCLOSURE_ENCLOSED_BY % ", ".join(strings)] - - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateFencedStart(self, obj, **args): - fenceStart, fenceEnd = self._script.utilities.getMathFences(obj) - if fenceStart: - result = [chnames.getCharacterName(fenceStart)] - result.extend(self.voice(DEFAULT, obj=obj, **args)) - return result - - return [] - - def _generateFencedContents(self, obj, **args): - result = [] - separators = self._script.utilities.getMathFencedSeparators(obj) - for x in range(len(separators), AXObject.get_child_count(obj)-1): - separators.append(separators[-1]) - separators.append('') - - for i, child in enumerate(obj): - result.extend(self._generateMath(child, **args)) - separatorName = chnames.getCharacterName(separators[i]) - result.append(separatorName) - result.extend(self.voice(DEFAULT, obj=obj, **args)) - if separatorName: - result.extend(self._generatePause(obj, **args)) - - return result - - def _generateFencedEnd(self, obj, **args): - fenceStart, fenceEnd = self._script.utilities.getMathFences(obj) - if fenceEnd: - result = [chnames.getCharacterName(fenceEnd)] - result.extend(self.voice(DEFAULT, obj=obj, **args)) - return result - - return [] - - def _generateFractionStart(self, obj, **args): - if self._script.utilities.isMathFractionWithoutBar(obj): - result = [messages.MATH_FRACTION_WITHOUT_BAR_START] - else: - result = [messages.MATH_FRACTION_START] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateFractionNumerator(self, obj, **args): - numerator = self._script.utilities.getMathNumerator(obj) - if self._script.utilities.isMathLayoutOnly(numerator): - return self._generateMath(numerator) - - oldRole = self._getAlternativeRole(numerator) - self._overrideRole(oldRole, args) - result = self.generate(numerator, role=oldRole) - self._restoreRole(oldRole, args) - return result - - def _generateFractionDenominator(self, obj, **args): - denominator = self._script.utilities.getMathDenominator(obj) - if self._script.utilities.isMathLayoutOnly(denominator): - return self._generateMath(denominator) - - oldRole = self._getAlternativeRole(denominator) - self._overrideRole(oldRole, args) - result = self.generate(denominator, role=oldRole) - self._restoreRole(oldRole, args) - return result - - def _generateFractionLine(self, obj, **args): - result = [messages.MATH_FRACTION_LINE] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateFractionEnd(self, obj, **args): - result = [messages.MATH_FRACTION_END] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateRootStart(self, obj, **args): - result = [] - if self._script.utilities.isMathSquareRoot(obj): - result = [messages.MATH_SQUARE_ROOT_OF] - else: - index = self._script.utilities.getMathRootIndex(obj) - string = self._script.utilities.displayedText(index) - if string == "2": - result = [messages.MATH_SQUARE_ROOT_OF] - elif string == "3": - result = [messages.MATH_CUBE_ROOT_OF] - elif string: - result = [string] - result.extend([messages.MATH_ROOT_OF]) - elif self._script.utilities.isMathLayoutOnly(index): - result = self._generateMath(index) - result.extend([messages.MATH_ROOT_OF]) - else: - oldRole = self._getAlternativeRole(index) - self._overrideRole(oldRole, args) - result.extend(self.generate(index, role=oldRole)) - self._restoreRole(oldRole, args) - result.extend([messages.MATH_ROOT_OF]) - - if result: - result.extend(self.voice(SYSTEM, obj=obj, **args)) - - return result - - def _generateRootBase(self, obj, **args): - base = self._script.utilities.getMathRootBase(obj) - if not base: - return [] - - if self._script.utilities.isMathSquareRoot(obj) \ - or self._script.utilities.isMathToken(base) \ - or self._script.utilities.isMathLayoutOnly(base): - return self._generateMath(base) - - result = [self._generatePause(obj, **args)] - oldRole = self._getAlternativeRole(base) - self._overrideRole(oldRole, args) - result.extend(self.generate(base, role=oldRole)) - self._restoreRole(oldRole, args) - - return result - - def _generateRootEnd(self, obj, **args): - result = [messages.MATH_ROOT_END] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateScriptBase(self, obj, **args): - base = self._script.utilities.getMathScriptBase(obj) - if not base: - return [] - - return self._generateMath(base) - - def _generateScriptScript(self, obj, **args): - if self._script.utilities.isMathLayoutOnly(obj): - return self._generateMath(obj) - - oldRole = self._getAlternativeRole(obj) - self._overrideRole(oldRole, args) - result = self.generate(obj, role=oldRole) - self._restoreRole(oldRole, args) - - return result - - def _generateScriptSubscript(self, obj, **args): - subscript = self._script.utilities.getMathScriptSubscript(obj) - if not subscript: - return [] - - result = [messages.MATH_SUBSCRIPT] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - result.extend(self._generateScriptScript(subscript)) - - return result - - def _generateScriptSuperscript(self, obj, **args): - superscript = self._script.utilities.getMathScriptSuperscript(obj) - if not superscript: - return [] - - result = [messages.MATH_SUPERSCRIPT] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - result.extend(self._generateScriptScript(superscript)) - - return result - - def _generateScriptUnderscript(self, obj, **args): - underscript = self._script.utilities.getMathScriptUnderscript(obj) - if not underscript: - return [] - - result = [messages.MATH_UNDERSCRIPT] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - result.extend(self._generateScriptScript(underscript)) - - return result - - def _generateScriptOverscript(self, obj, **args): - overscript = self._script.utilities.getMathScriptOverscript(obj) - if not overscript: - return [] - - result = [messages.MATH_OVERSCRIPT] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - result.extend(self._generateScriptScript(overscript)) - - return result - - def _generateScriptPrescripts(self, obj, **args): - result = [] - prescripts = self._script.utilities.getMathPrescripts(obj) - for i, script in enumerate(prescripts): - if self._script.utilities.isNoneElement(script): - continue - if i % 2: - rv = [messages.MATH_PRE_SUPERSCRIPT] - else: - rv = [messages.MATH_PRE_SUBSCRIPT] - rv.extend(self.voice(SYSTEM, obj=obj, **args)) - rv.extend(self._generateScriptScript(script)) - result.append(rv) - - return result - - def _generateScriptPostscripts(self, obj, **args): - result = [] - postscripts = self._script.utilities.getMathPostscripts(obj) - for i, script in enumerate(postscripts): - if self._script.utilities.isNoneElement(script): - continue - if i % 2: - rv = [messages.MATH_SUPERSCRIPT] - else: - rv = [messages.MATH_SUBSCRIPT] - rv.extend(self.voice(SYSTEM, obj=obj, **args)) - rv.extend(self._generateScriptScript(script)) - result.append(rv) - - return result - - def _generateMathTableStart(self, obj, **args): - nestingLevel = self._script.utilities.getMathNestingLevel(obj) - rows = AXTable.get_row_count(obj, prefer_attribute=False) - cols = AXTable.get_column_count(obj, prefer_attribute=False) - if rows < 0 or cols < 0: - return [] - if nestingLevel > 0: - result = [messages.mathNestedTableSize(rows, cols)] - else: - result = [messages.mathTableSize(rows, cols)] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - def _generateMathTableRows(self, obj, **args): - result = [] - for row in AXObject.iter_children(obj): - oldRole = self._getAlternativeRole(row) - self._overrideRole(oldRole, args) - result.extend(self.generate(row, role=oldRole)) - self._restoreRole(oldRole, args) - - return result - - def _generateMathRow(self, obj, **args): - result = [] - - result.append(messages.TABLE_ROW % (AXObject.get_index_in_parent(obj) + 1)) - result.extend(self.voice(SYSTEM, obj=obj, **args)) - result.extend(self._generatePause(obj, **args)) - - for child in AXObject.iter_children(obj): - result.extend(self._generateMath(child)) - result.extend(self._generatePause(child, **args)) - - return result - - def _generateMathTableEnd(self, obj, **args): - nestingLevel = self._script.utilities.getMathNestingLevel(obj) - if nestingLevel > 0: - result = [messages.MATH_NESTED_TABLE_END] - else: - result = [messages.MATH_TABLE_END] - result.extend(self.voice(SYSTEM, obj=obj, **args)) - return result - - ##################################################################### - # # - # Other things for prosody and voice selection # - # # - ##################################################################### - - def _generatePause(self, obj, **args): - if not cthulhu.cthulhuApp.settingsManager.getSetting('enablePauseBreaks') \ - or args.get('eliminatePauses', False): - return [] - - if cthulhu.cthulhuApp.settingsManager.getSetting('verbalizePunctuationStyle') == \ - settings.PUNCTUATION_STYLE_ALL: - return [] - - return PAUSE - - def _generateLineBreak(self, obj, **args): - return LINE_BREAK - - def voice(self, key=None, **args): - """Returns an array containing a voice. The key is a value - to be used to look up the voice in the settings.py:voices - dictionary. Other arguments can be passed in for future - decision making. - """ - - voicename = voiceType.get(key) or voiceType.get(DEFAULT) - voices = cthulhu.cthulhuApp.settingsManager.getSetting('voices') - voice = acss.ACSS(voices.get(voiceType.get(DEFAULT), {})) - - language = args.get('language') - dialect = args.get('dialect', '') - msg = ( - f"SPEECH GENERATOR: {key} voice requested with " - f"language='{language}', dialect='{dialect}'" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - # This is purely for debugging. The code needed to actually switch voices - # does not yet exist due to some problems which need to be debugged and - # fixed. - checkVoicesForLanguage = False - if language and checkVoicesForLanguage: - server = speech.getSpeechServer() - server.shouldChangeVoiceForLanguage(language, dialect) - - if key in [None, DEFAULT]: - string = args.get('string', '') - obj = args.get('obj') - if AXUtilities.is_link(obj): - voice.update(voices.get(voiceType.get(HYPERLINK), {})) - elif isinstance(string, str) and string.isupper() and string.strip().isalpha(): - voice.update(voices.get(voiceType.get(UPPERCASE), {})) - else: - override = voices.get(voicename) - if override and override.get('established', True): - voice.update(override) - - return [voice] - - def utterancesToString(self, utterances): - string = "" - for u in utterances: - if isinstance(u, str): - string += f" {u}" - elif isinstance(u, Pause) and string and string[-1].isalnum(): - string += "." - - return string.strip() diff --git a/src/cthulhu/speech_history.py b/src/cthulhu/speech_history.py deleted file mode 100644 index cf54dcd..0000000 --- a/src/cthulhu/speech_history.py +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Shared speech history buffer. - -This module records the last N unique utterances spoken by Cthulhu. - -Uniqueness is enforced only within the current history window. If an item -falls off the end, it may be added again later. -""" - -from __future__ import annotations - -from typing import Optional -import threading -from collections import deque - -from . import debug - -_loggerPrefix = "SpeechHistory:" - -_maxHistorySize = 50 -_historyItems = deque() -_historySet = set() - -_lock = threading.Lock() -_pauseCount = 0 -_pausedIgnoreCount = 0 - - -def pause_capture(reason: str = "") -> None: - """Pause capture so speech produced while paused is not recorded.""" - global _pauseCount - with _lock: - _pauseCount += 1 - global _pausedIgnoreCount - _pausedIgnoreCount = 0 - debug.printMessage( - debug.LEVEL_INFO, - f"{_loggerPrefix} capture paused (count={_pauseCount}) reason='{reason}'", - True, - ) - - -def resume_capture(reason: str = "") -> None: - """Resume capture after a pause_capture().""" - global _pauseCount - with _lock: - if _pauseCount <= 0: - _pauseCount = 0 - debug.printMessage( - debug.LEVEL_INFO, - f"{_loggerPrefix} resume requested while not paused reason='{reason}'", - True, - ) - return - - _pauseCount -= 1 - if _pauseCount == 0: - global _pausedIgnoreCount - _pausedIgnoreCount = 0 - debug.printMessage( - debug.LEVEL_INFO, - f"{_loggerPrefix} capture resumed (count={_pauseCount}) reason='{reason}'", - True, - ) - - -def is_capture_paused() -> bool: - with _lock: - return _pauseCount > 0 - - -def add(text: Optional[str], source: str = "") -> bool: - """Add text to speech history if it's not already present. - - Returns True if the item was added; False otherwise. - """ - if text is None: - return False - - try: - cleanText = text.strip() - except Exception: - return False - - if not cleanText: - return False - - with _lock: - if _pauseCount > 0: - global _pausedIgnoreCount - _pausedIgnoreCount += 1 - if _pausedIgnoreCount in (1, 25, 50, 100): - debug.printMessage( - debug.LEVEL_INFO, - f"{_loggerPrefix} ignoring speech while paused (ignored={_pausedIgnoreCount}) source='{source}' text='{cleanText[:80]}'", - True, - ) - return False - - if cleanText in _historySet: - debug.printMessage( - debug.LEVEL_INFO, - f"{_loggerPrefix} duplicate ignored source='{source}' text='{cleanText[:80]}'", - True, - ) - return False - - _historyItems.appendleft(cleanText) - _historySet.add(cleanText) - - evictedText = None - if len(_historyItems) > _maxHistorySize: - evictedText = _historyItems.pop() - _historySet.discard(evictedText) - - debug.printMessage( - debug.LEVEL_INFO, - f"{_loggerPrefix} added source='{source}' size={len(_historyItems)} text='{cleanText[:80]}'", - True, - ) - if evictedText: - debug.printMessage( - debug.LEVEL_INFO, - f"{_loggerPrefix} evicted size={len(_historyItems)} text='{evictedText[:80]}'", - True, - ) - - return True - - -def get_items() -> list[str]: - """Return a snapshot of history items, newest-first.""" - with _lock: - return list(_historyItems) - - -def remove(text: Optional[str]) -> bool: - """Remove an item from the history (if present).""" - if text is None: - return False - - try: - cleanText = text.strip() - except Exception: - return False - - if not cleanText: - return False - - with _lock: - if cleanText not in _historySet: - debug.printMessage( - debug.LEVEL_INFO, - f"{_loggerPrefix} remove ignored (not found) text='{cleanText[:80]}'", - True, - ) - return False - - global _historyItems - _historyItems = deque(item for item in _historyItems if item != cleanText) - _historySet.discard(cleanText) - - debug.printMessage( - debug.LEVEL_INFO, - f"{_loggerPrefix} removed size={len(_historyItems)} text='{cleanText[:80]}'", - True, - ) - return True diff --git a/src/cthulhu/speechdispatcherfactory.py b/src/cthulhu/speechdispatcherfactory.py deleted file mode 100644 index 355611c..0000000 --- a/src/cthulhu/speechdispatcherfactory.py +++ /dev/null @@ -1,855 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides an Cthulhu speech server for Speech Dispatcher backend.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__author__ = "Tomas Cerha " -__copyright__ = "Copyright (c) 2006-2008 Brailcom, o.p.s." -__license__ = "LGPL" - -from gi.repository import GLib -import re -import time - -from . import chnames -from . import cthulhu -from . import debug -from . import guilabels -from . import messages -from . import speechserver -from . import settings -from . import cthulhu_state -from . import punctuation_settings -from . import settings_manager -from .acss import ACSS - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -try: - import speechd -except Exception: - _speechd_available = False -else: - _speechd_available = True - try: - getattr(speechd, "CallbackType") - except AttributeError: - _speechd_version_ok = False - else: - _speechd_version_ok = True - -PUNCTUATION = re.compile(r'[^\w\s]', re.UNICODE) -ELLIPSIS = re.compile('(\342\200\246|(? debug.LEVEL_INFO: - return - - try: - sd_rate = self._send_command(self._client.get_rate, treat_none_as_error=True) - sd_pitch = self._send_command(self._client.get_pitch, treat_none_as_error=True) - sd_volume = self._send_command(self._client.get_volume, treat_none_as_error=True) - sd_language = self._send_command(self._client.get_language, treat_none_as_error=True) - except Exception: - sd_rate = sd_pitch = sd_volume = sd_language = "(exception occurred)" - - family = self._current_voice_properties.get(ACSS.FAMILY) - - styles = {settings.PUNCTUATION_STYLE_NONE: "NONE", - settings.PUNCTUATION_STYLE_SOME: "SOME", - settings.PUNCTUATION_STYLE_MOST: "MOST", - settings.PUNCTUATION_STYLE_ALL: "ALL"} - - msg = ( - f"SPEECH DISPATCHER: {prefix}\n" - f"CTHULHU rate {self._current_voice_properties.get(ACSS.RATE)}, " - f"pitch {self._current_voice_properties.get(ACSS.AVERAGE_PITCH)}, " - f"volume {self._current_voice_properties.get(ACSS.GAIN)}, " - f"language {self._get_language_and_dialect(family)[0]}, " - f"punctuation: " - f"{styles.get(cthulhu.cthulhuApp.settingsManager.getSetting('verbalizePunctuationStyle'))}\n" - f"SD rate {sd_rate}, pitch {sd_pitch}, volume {sd_volume}, language {sd_language}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - def _apply_acss(self, acss): - if acss is None: - acss = settings.voices[settings.DEFAULT_VOICE] - current = self._current_voice_properties - for acss_property, method in self._acss_manipulators: - value = acss.get(acss_property) - if value is not None: - if current.get(acss_property) != value: - method(value) - current[acss_property] = value - elif acss_property == ACSS.AVERAGE_PITCH: - method(5.0) - current[acss_property] = 5.0 - elif acss_property == ACSS.GAIN: - method(10) - current[acss_property] = 5.0 - elif acss_property == ACSS.RATE: - method(50) - current[acss_property] = 5.0 - elif acss_property == ACSS.FAMILY: - method({}) - current[acss_property] = {} - - def __addVerbalizedPunctuation(self, oldText): - """Depending upon the users verbalized punctuation setting, - adjust punctuation symbols in the given text to their pronounced - equivalents. The pronounced text will either replace the - punctuation symbol or be inserted before it. In the latter case, - this is to retain spoken prosity. - - Arguments: - - oldText: text to be parsed for punctuation. - - Returns a text string with the punctuation symbols adjusted accordingly. - """ - - style = cthulhu.cthulhuApp.settingsManager.getSetting("verbalizePunctuationStyle") - if style == settings.PUNCTUATION_STYLE_NONE: - return oldText - - spokenEllipsis = messages.SPOKEN_ELLIPSIS + " " - newText = re.sub(ELLIPSIS, spokenEllipsis, oldText) - symbols = set(re.findall(PUNCTUATION, newText)) - for symbol in symbols: - try: - level, action = punctuation_settings.getPunctuationInfo(symbol) - except Exception: - continue - - if level != punctuation_settings.LEVEL_NONE: - # Speech Dispatcher should handle it. - # - continue - - charName = f" {chnames.getCharacterName(symbol)} " - if action == punctuation_settings.PUNCTUATION_INSERT: - charName += symbol - newText = re.sub(symbol, charName, newText) - - if cthulhu_state.activeScript: - newText = cthulhu_state.activeScript.utilities.adjustForDigits(newText) - - return newText - - def _speak(self, text, acss, **kwargs): - if isinstance(text, ACSS): - text = '' - - # Mark beginning of words with U+E000 (private use) and record the - # string offsets - # Note: we need to do this before disturbing the text offsets - # Note2: we assume that text mangling below leave U+E000 untouched - last_begin = None - is_numeric = None - marks_offsets = [] - marks_endoffsets = [] - marked_text = "" - - for i in range(len(text)): - c = text[i] - if c == '\ue000': - # Original text already contains U+E000. But syntheses will not - # know what to do of it anyway, so discard it - continue - - if not c.isspace() and last_begin is None: - # Word begin - marked_text += '\ue000' - last_begin = i - is_numeric = c.isnumeric() - - elif c.isspace() and last_begin is not None: - # Word end - if is_numeric: - # We had a wholy numeric word, possibly next word is as well. - # Skip to next word - for j in range(i+1, len(text)): - if not text[j].isspace(): - break - else: - is_numeric = False - # Check next word - while is_numeric and j < len(text) and not text[j].isspace(): - if not text[j].isnumeric(): - is_numeric = False - j += 1 - - if not is_numeric: - # add a mark - marks_offsets.append(last_begin) - marks_endoffsets.append(i) - last_begin = None - is_numeric = None - - elif is_numeric and not c.isnumeric(): - is_numeric = False - - marked_text += c - - if last_begin is not None: - # Finished with a word - marks_offsets.append(last_begin) - marks_endoffsets.append(i + 1) - - text = marked_text - - text = self.__addVerbalizedPunctuation(text) - if cthulhu_state.activeScript: - text = cthulhu_state.activeScript.\ - utilities.adjustForPronunciation(text) - - # Replace no break space characters with plain spaces since some - # synthesizers cannot handle them. See bug #591734. - # - text = text.replace('\u00a0', ' ') - - # Replace newline followed by full stop, since - # this seems to crash sd, see bgo#618334. - # - text = text.replace('\n.', '\n') - - # Transcribe to SSML, translating U+E000 into marks - # Note: we need to do this after all mangling otherwise the ssml markup - # would get mangled too - ssml = "" - i = 0 - for c in text: - if c == '\ue000': - if i >= len(marks_offsets): - # This is really not supposed to happen - msg = f"{i}th U+E000 does not have corresponding index" - debug.printMessage(debug.LEVEL_WARNING, msg, True) - else: - ssml += '' % (marks_offsets[i], marks_endoffsets[i]) - i += 1 - # Disable for now, until speech dispatcher properly parses them (version 0.8.9 or later) - #elif c == '"': - # ssml += '"' - #elif c == "'": - # ssml += ''' - elif c == '<': - ssml += '<' - elif c == '>': - ssml += '>' - elif c == '&': - ssml += '&' - else: - ssml += c - ssml += "" - - self._apply_acss(acss) - self._debug_sd_values(f"Speaking '{ssml}' ") - self._send_command(self._client.speak, ssml, **kwargs) - - def _say_all(self, iterator, cthulhu_callback, generation): - """Process another sayAll chunk. - - Called by the gidle thread. - - """ - if generation != self._say_all_generation: - return False - - if generation == self._cancelled_say_all_generation: - return False - - try: - context, acss = next(iterator) - except StopIteration: - pass - else: - def dispatch_callback(context_copy, progress_type, allow_interrupted=False): - if not allow_interrupted and generation != self._say_all_generation: - return False - cthulhu_callback(context_copy, progress_type) - return False - - def callback(callbackType, index_mark=None): - # This callback is called in Speech Dispatcher listener thread. - # No subsequent Speech Dispatcher interaction is allowed here, - # so we pass the calls to the gidle thread. - t = self._CALLBACK_TYPE_MAP[callbackType] - if generation != self._say_all_generation: - return - if generation == self._cancelled_say_all_generation: - if t == speechserver.SayAllContext.INTERRUPTED: - self._say_all_generation += 1 - self._cancelled_say_all_generation = None - GLib.idle_add(dispatch_callback, context.copy(), t, True) - return - if t == speechserver.SayAllContext.PROGRESS: - if index_mark: - index = index_mark.split(':') - if len(index) >= 2: - start, end = index[0:2] - context.currentOffset = context.startOffset + int(start) - context.currentEndOffset = context.startOffset + int(end) - msg = ( - f"SPEECH DISPATCHER: Got mark " - f"{context.currentOffset}:{context.currentEndOffset} / " - f"{context.startOffset}:{context.endOffset}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - else: - context.currentOffset = context.startOffset - context.currentEndOffset = None - elif t == speechserver.SayAllContext.COMPLETED: - context.currentOffset = context.endOffset - context.currentEndOffset = None - GLib.idle_add(dispatch_callback, context.copy(), t) - if t == speechserver.SayAllContext.COMPLETED: - GLib.idle_add(self._say_all, iterator, cthulhu_callback, generation) - self._speak(context.utterance, acss, callback=callback, - event_types=list(self._CALLBACK_TYPE_MAP.keys())) - return False # to indicate, that we don't want to be called again. - - def _cancel(self): - self._cancelled_say_all_generation = self._say_all_generation - self._send_command(self._client.cancel) - - def _change_default_speech_rate(self, step, decrease=False): - acss = settings.voices[settings.DEFAULT_VOICE] - delta = step * (decrease and -1 or +1) - try: - rate = acss[ACSS.RATE] - except KeyError: - rate = 50 - acss[ACSS.RATE] = max(0, min(99, rate + delta)) - msg = f"SPEECH DISPATCHER: Rate set to {rate}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.speak(decrease and messages.SPEECH_SLOWER \ - or messages.SPEECH_FASTER, acss=acss) - - def _change_default_speech_pitch(self, step, decrease=False): - acss = settings.voices[settings.DEFAULT_VOICE] - delta = step * (decrease and -1 or +1) - try: - pitch = acss[ACSS.AVERAGE_PITCH] - except KeyError: - pitch = 5 - acss[ACSS.AVERAGE_PITCH] = max(0, min(9, pitch + delta)) - msg = f"SPEECH DISPATCHER: Pitch set to {pitch}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.speak(decrease and messages.SPEECH_LOWER \ - or messages.SPEECH_HIGHER, acss=acss) - - def _change_default_speech_volume(self, step, decrease=False): - acss = settings.voices[settings.DEFAULT_VOICE] - delta = step * (decrease and -1 or +1) - try: - volume = acss[ACSS.GAIN] - except KeyError: - volume = 10 - acss[ACSS.GAIN] = max(0, min(9, volume + delta)) - msg = f"SPEECH DISPATCHER: Volume set to {volume}" - debug.printMessage(debug.LEVEL_INFO, msg, True) - self.speak(decrease and messages.SPEECH_SOFTER \ - or messages.SPEECH_LOUDER, acss=acss) - - def getInfo(self): - return [self._SERVER_NAMES.get(self._id, self._id), self._id] - - def getVoiceFamilies(self): - # Always offer the configured default voice with a language - # set according to the current locale. - from locale import getlocale, LC_MESSAGES - locale = getlocale(LC_MESSAGES)[0] - if locale is None or '_' not in locale: - locale_language = None - else: - locale_lang, locale_dialect = locale.split('_') - locale_language = locale_lang + '-' + locale_dialect - voices = () - try: - # This command is not available with older SD versions. - list_synthesis_voices = self._client.list_synthesis_voices - except AttributeError: - pass - else: - try: - voices += self._send_command(list_synthesis_voices) - except Exception: - pass - - default_lang = "" - if locale_language: - # Check whether how it appears in the server list - for name, lang, variant in voices: - if lang == locale_language: - default_lang = locale_language - break - if not default_lang: - for name, lang, variant in voices: - if lang == locale_lang: - default_lang = locale_lang - if not default_lang: - default_lang = locale_language - - current_module = "" - try: - current_module = self.getOutputModule() or "" - except Exception: - current_module = "" - default_name = guilabels.SPEECH_DEFAULT_VOICE % (current_module or self._id) - voices = ((default_name, default_lang, None),) + voices - - families = [] - for name, lang, variant in voices: - - families.append(speechserver.VoiceFamily({ \ - speechserver.VoiceFamily.NAME: name, - #speechserver.VoiceFamily.GENDER: speechserver.VoiceFamily.MALE, - speechserver.VoiceFamily.LANG: lang.partition("-")[0], - speechserver.VoiceFamily.DIALECT: lang.partition("-")[2], - speechserver.VoiceFamily.VARIANT: variant})) - - return families - - def speak(self, text=None, acss=None, interrupt=False): - if not text: - return - - # "We will not interrupt a key echo in progress." (Said the comment in - # speech.py where these next two lines used to live. But the code here - # suggests we haven't been doing anything with the lastKeyEchoTime in - # years. TODO - JD: Dig into this and if it's truly useless, kill it.) - if self._lastKeyEchoTime: - interrupt = interrupt and (time.time() - self._lastKeyEchoTime) > 0.5 - - if interrupt: - self._cancel() - - if len(text) == 1: - tokens = ["SPEECH DISPATCHER: Speaking '", text.replace("\n", "\\n"), "' as char"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._apply_acss(acss) - self._send_command(self._client.char, text) - else: - tokens = ["SPEECH DISPATCHER: Speaking '", text, "' as string"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._speak(text, acss) - - def sayAll(self, utteranceIterator, progressCallback): - self._say_all_generation += 1 - self._cancelled_say_all_generation = None - GLib.idle_add( - self._say_all, - utteranceIterator, - progressCallback, - self._say_all_generation, - ) - - def speakCharacter(self, character, acss=None): - self._apply_acss(acss) - name = chnames.getCharacterName(character) - if not name or name == character: - tokens = ["SPEECH DISPATCHER: Speaking '", character.replace("\n", "\\n"), "' as char"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._send_command(self._client.char, character) - return - - if cthulhu_state.activeScript: - name = cthulhu_state.activeScript.\ - utilities.adjustForPronunciation(name) - self.speak(name, acss) - - def speakKeyEvent(self, event, acss=None): - event_string = event.getKeyName() - lockingStateString = event.getLockingStateString() - event_string = f"{event_string} {lockingStateString}".strip() - if len(event_string) == 1: - tokens = ["SPEECH DISPATCHER: Speaking '", event_string, "' as key"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self._apply_acss(acss) - self._send_command(self._client.key, event_string) - else: - tokens = ["SPEECH DISPATCHER: Speaking '", event_string, "' as string"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - self.speak(event_string, acss=acss) - self._lastKeyEchoTime = time.time() - - def increaseSpeechRate(self, step=5): - self._change_default_speech_rate(step) - - def decreaseSpeechRate(self, step=5): - self._change_default_speech_rate(step, decrease=True) - - def increaseSpeechPitch(self, step=0.5): - self._change_default_speech_pitch(step) - - def decreaseSpeechPitch(self, step=0.5): - self._change_default_speech_pitch(step, decrease=True) - - def increaseSpeechVolume(self, step=0.5): - self._change_default_speech_volume(step) - - def decreaseSpeechVolume(self, step=0.5): - self._change_default_speech_volume(step, decrease=True) - - def getLanguage(self): - """Returns the current language.""" - - return self._client.get_language() - - def setLanguage(self, language, dialect): - """Sets the current language""" - - if not language: - return - - self._client.set_language(language) - if dialect: - self._client.set_language(language + "-" + dialect) - - def _normalizedLanguageAndDialect(self, language, dialect=""): - """Attempts to ensure consistency across inconsistent formats.""" - - if "-" in language: - normalized_language = language.split("-", 1)[0].lower() - normalized_dialect = language.split("-", 1)[-1].lower() - else: - normalized_language = language.lower() - normalized_dialect = dialect.lower() - - return normalized_language, normalized_dialect - - def getVoiceFamiliesForLanguage(self, language, dialect, maximum=None): - """Returns the families for language available in the current synthesizer.""" - - start = time.time() - target_language, target_dialect = self._normalizedLanguageAndDialect(language, dialect) - - result = [] - voices = self._client.list_synthesis_voices() - - for voice in voices: - normalized_language, normalized_dialect = self._normalizedLanguageAndDialect(voice[1]) - if normalized_language != target_language: - continue - if normalized_dialect == target_dialect: - result.append(voice) - elif not normalized_dialect and target_dialect == normalized_language: - result.append(voice) - if maximum is not None and len(result) >= maximum: - break - - msg = ( - f"SPEECH DISPATCHER: Found {len(result)} match(es) for language='{language}' " - f"dialect='{dialect}' in {time.time() - start:.4f}s." - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - return result - - def shouldChangeVoiceForLanguage(self, language, dialect=""): - """Returns True if we should change the voice for the specified language.""" - - current_language, current_dialect = self._normalizedLanguageAndDialect(self.getLanguage()) - other_language, other_dialect = self._normalizedLanguageAndDialect(language, dialect) - - msg = ( - f"SPEECH DISPATCHER: Should change voice for language? " - f"Current: '{current_language}' '{current_dialect}' " - f"New: '{other_language}' '{other_dialect}'" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - - if current_language == other_language and current_dialect == other_dialect: - msg ="SPEECH DISPATCHER: No. Language and dialect are the same." - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - families = self.getVoiceFamiliesForLanguage(other_language, other_dialect, maximum=1) - if families: - tokens = ["SPEECH DISPATCHER: Yes. Found matching family", families[0], "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - tokens = ["SPEECH DISPATCHER: No. No matching family in", self.getOutputModule(), "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return True - - def getOutputModule(self): - return self._client.get_output_module() - - def setOutputModule(self, module): - self._client.set_output_module(module) - self._default_voice_name = guilabels.SPEECH_DEFAULT_VOICE % module - self._current_voice_properties.pop(ACSS.FAMILY, None) - - def stop(self): - self._cancel() - - def shutdown(self): - self._client.close() - del SpeechServer._active_servers[self._id] - - def reset(self, text=None, acss=None): - self._client.close() - self._init() - - def list_output_modules(self): - """Return names of available output modules as a tuple of strings. - - This method is not a part of Cthulhu speech API, but is used internally - by the Speech Dispatcher backend. - - The returned tuple can be empty if the information can not be - obtained (e.g. with an older Speech Dispatcher version). - - """ - try: - return self._send_command(self._client.list_output_modules) - except AttributeError: - return () - except speechd.SSIPCommandError: - return () diff --git a/src/cthulhu/speechserver.py b/src/cthulhu/speechserver.py deleted file mode 100644 index eb95d82..0000000 --- a/src/cthulhu/speechserver.py +++ /dev/null @@ -1,246 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides an abtract class for working with speech servers. - -A speech server (class SpeechServer) provides the ability to tell the -machine to speak. Each speech server provides a set of known -voices (identified by name) which can be combined with various -attributes to create aural style sheets.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." -__license__ = "LGPL" - -class VoiceFamily(dict): - """Holds the family description for a voice.""" - - NAME = "name" - GENDER = "gender" - LANG = "lang" - DIALECT = "dialect" - VARIANT = "variant" - - MALE = "male" - FEMALE = "female" - - settings = { - NAME : None, - GENDER : None, - LANG : None, - DIALECT: None, - VARIANT: None, - } - - def __init__(self, props): - """Create and initialize VoiceFamily.""" - dict.__init__(self) - - self.update(VoiceFamily.settings) - if props: - self.update(props) - -class SayAllContext: - - PROGRESS = 0 - INTERRUPTED = 1 - COMPLETED = 2 - - def __init__(self, obj, utterance, startOffset=-1, endOffset=-1): - """Creates a new SayAllContext that will be passed to the - SayAll callback handler for progress updates on speech. - If the object does not have an accessible text specialization, - then startOffset and endOffset parameters are meaningless. - If the object does have an accessible text specialization, - then values >= 0 for startOffset and endOffset indicate - where in the text the utterance has come from. - - Arguments: - -obj: the Accessible being spoken - -utterance: the actual utterance being spoken - -startOffset: the start offset of the Accessible's text - -endOffset: the end offset of the Accessible's text - """ - self.obj = obj - self.utterance = utterance - self.startOffset = startOffset - self.endOffset = endOffset - self.currentOffset = startOffset - self.currentEndOffset = None - - def __str__(self): - return "SAY ALL: %s '%s' (%i-%i, current: %i)" % \ - (self.obj, self.utterance, self.startOffset, self.endOffset, self.currentOffset) - - def copy(self): - new = SayAllContext(self.obj, self.utterance, - self.startOffset, self.endOffset) - new.currentOffset = self.currentOffset - new.currentEndOffset = self.currentEndOffset - return new - - def __eq__(self, other): - return (self.startOffset == other.startOffset and - self.endOffset == other.endOffset and - self.obj == other.obj and - self.utterance == other.utterance) - - -class SpeechServer(object): - """Provides speech server abstraction.""" - - @staticmethod - def getFactoryName(): - """Returns a localized name describing this factory.""" - pass - - @staticmethod - def getSpeechServers(): - """Gets available speech servers as a list. The caller - is responsible for calling the shutdown() method of each - speech server returned. - """ - pass - - @staticmethod - def getSpeechServer(info): - """Gets a given SpeechServer based upon the info. - See SpeechServer.getInfo() for more info. - """ - pass - - @staticmethod - def shutdownActiveServers(): - """Cleans up and shuts down this factory. - """ - pass - - def __init__(self): - pass - - def getInfo(self): - """Returns [name, id] - """ - pass - - def getVoiceFamilies(self): - """Returns a list of VoiceFamily instances representing all - voice families known by the speech server.""" - pass - - def speakCharacter(self, character, acss=None): - """Speaks a single character immediately. - - Arguments: - - character: text to be spoken - - acss: acss.ACSS instance; if None, - the default voice settings will be used. - Otherwise, the acss settings will be - used to augment/override the default - voice settings. - """ - pass - - def speakKeyEvent(self, event, acss=None): - """Speaks a key event immediately. - - Arguments: - - event: the input_event.KeyboardEvent. - """ - pass - - def speak(self, text=None, acss=None, interrupt=True): - """Speaks all queued text immediately. If text is not None, - it is added to the queue before speaking. - - Arguments: - - text: optional text to add to the queue before speaking - - acss: acss.ACSS instance; if None, - the default voice settings will be used. - Otherwise, the acss settings will be - used to augment/override the default - voice settings. - - interrupt: if True, stops any speech in progress before - speaking the text - """ - pass - - def sayAll(self, utteranceIterator, progressCallback): - """Iterates through the given utteranceIterator, speaking - each utterance one at a time. Subclasses may postpone - getting a new element until the current element has been - spoken. - - Arguments: - - utteranceIterator: iterator/generator whose next() function - returns a [SayAllContext, acss] tuple - - progressCallback: called as speech progress is made - has a - signature of (SayAllContext, type), where - type is one of PROGRESS, INTERRUPTED, or - COMPLETED. - """ - pass - - def increaseSpeechRate(self, step=5): - """Increases the speech rate. - """ - pass - - def decreaseSpeechRate(self, step=5): - """Decreases the speech rate. - """ - pass - - def increaseSpeechPitch(self, step=0.5): - """Increases the speech pitch. - """ - pass - - def decreaseSpeechPitch(self, step=0.5): - """Decreases the speech pitch. - """ - pass - - def updateCapitalizationStyle(self): - """Updates the capitalization style used by the speech server.""" - pass - - def updatePunctuationLevel(self): - """Punctuation level changed, inform this speechServer.""" - pass - - def stop(self): - """Stops ongoing speech and flushes the queue.""" - pass - - def shutdown(self): - """Shuts down the speech engine.""" - pass - - def reset(self, text=None, acss=None): - """Resets the speech engine.""" - pass diff --git a/src/cthulhu/spellcheck.py b/src/cthulhu/spellcheck.py deleted file mode 100644 index 4e91219..0000000 --- a/src/cthulhu/spellcheck.py +++ /dev/null @@ -1,339 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Script-customizable support for application spellcheckers.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2014 Igalia, S.L." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -import re - -from cthulhu import debug -from cthulhu import guilabels -from cthulhu import messages -from cthulhu import object_properties -from cthulhu import cthulhu_state -from cthulhu import settings_manager -from cthulhu.ax_object import AXObject -from cthulhu.ax_text import AXText -from cthulhu.ax_utilities import AXUtilities - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -class SpellCheck: - - def __init__(self, script, hasChangeToEntry=True): - self._script = script - self._hasChangeToEntry = hasChangeToEntry - self._window = None - self._errorWidget = None - self._changeToEntry = None - self._suggestionsList = None - self._activated = False - self._documentPosition = None, -1 - - self.spellErrorCheckButton = None - self.spellSuggestionCheckButton = None - self.presentContextCheckButton = None - - def activate(self, window): - tokens = ["SPELL CHECK: Attempting activation for", window] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - if not self._isCandidateWindow(window): - tokens = ["SPELL CHECK:", window, "is not spellcheck window"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return False - - if self._hasChangeToEntry: - self._changeToEntry = self._findChangeToEntry(window) - if not self._changeToEntry: - msg = 'SPELL CHECK: Change-to entry not found' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - self._errorWidget = self._findErrorWidget(window) - if not self._errorWidget: - msg = 'SPELL CHECK: Error widget not found' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - self._suggestionsList = self._findSuggestionsList(window) - if not self._suggestionsList: - msg = 'SPELL CHECK: Suggestions list not found' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return False - - self._window = window - self._activated = True - msg = 'SPELL CHECK: Activation complete' - debug.printMessage(debug.LEVEL_INFO, msg, True) - return True - - def deactivate(self): - self._clearState() - - def getDocumentPosition(self): - return self._documentPosition - - def setDocumentPosition(self, obj, offset): - self._documentPosition = obj, offset - - def getErrorWidget(self): - return self._errorWidget - - def getMisspelledWord(self): - if not self._errorWidget: - return "" - - return self._script.utilities.displayedText(self._errorWidget) - - def getCompletionMessage(self): - if not self._errorWidget: - return "" - - return self._script.utilities.displayedText(self._errorWidget) - - def getChangeToEntry(self): - return self._changeToEntry - - def getSuggestionsList(self): - return self._suggestionsList - - def isActive(self): - return self._activated - - def isCheckWindow(self, window): - if window and window == self._window: - return True - - return self.activate(window) - - def isComplete(self): - return not AXUtilities.is_sensitive(self._changeToEntry) - - def isAutoFocusEvent(self, event): - return False - - def isSuggestionsItem(self, obj): - if not self._suggestionsList: - return False - - return obj and AXObject.get_parent(obj) == self._suggestionsList - - def presentContext(self): - if not self.isActive(): - return False - - obj, offset = self._documentPosition - if not (obj and offset >= 0): - return False - - # This should work, but some toolkits are broken. - if not AXObject.supports_text(obj): - return False - - string, start, end = AXText.get_sentence_at_offset(obj, offset) - - if not string: - string, start, end = AXText.get_line_at_offset(obj, offset) - sentences = re.split(r'(?:\.|\!|\?)', string) - word = self.getMisspelledWord() - if string.count(word) == 1: - match = list(filter(lambda x: x.count(word), sentences)) - string = match[0] - - if not string: - return False - - msg = messages.MISSPELLED_WORD_CONTEXT % string - voice = self._script.speechGenerator.voice(string=msg) - self._script.speakMessage(msg, voice=voice) - return True - - def presentCompletionMessage(self): - if not (self.isActive() and self.isComplete()): - return False - - self._script.clearBraille() - msg = self.getCompletionMessage() - voice = self._script.speechGenerator.voice(string=msg) - self._script.presentMessage(msg, voice=voice) - return True - - def presentErrorDetails(self, detailed=False): - if self.isComplete(): - return False - - if self.presentMistake(detailed): - self.presentSuggestion(detailed) - if detailed or cthulhu.cthulhuApp.settingsManager.getSetting('spellcheckPresentContext'): - self.presentContext() - return True - - return False - - def presentMistake(self, detailed=False): - if not self.isActive(): - return False - - word = self.getMisspelledWord() - if not word: - return False - - msg = messages.MISSPELLED_WORD % word - voice = self._script.speechGenerator.voice(string=msg) - self._script.speakMessage(msg, voice=voice) - if detailed or cthulhu.cthulhuApp.settingsManager.getSetting('spellcheckSpellError'): - self._script.spellCurrentItem(word) - - return True - - def presentSuggestion(self, detailed=False): - if not self._hasChangeToEntry: - return self.presentSuggestionListItem(detailed, includeLabel=True) - - if not self.isActive(): - return False - - entry = self._changeToEntry - if not entry: - return False - - label = self._script.utilities.displayedLabel(entry) or AXObject.get_name(entry) - string = self._script.utilities.substring(entry, 0, -1) - msg = f"{label} {string}" - voice = self._script.speechGenerator.voice(string=msg) - self._script.speakMessage(msg, voice=voice) - if detailed or cthulhu.cthulhuApp.settingsManager.getSetting('spellcheckSpellSuggestion'): - self._script.spellCurrentItem(string) - - return True - - def presentSuggestionListItem(self, detailed=False, includeLabel=False): - if not self.isActive(): - return False - - suggestions = self._suggestionsList - if not suggestions: - return False - - items = self._script.utilities.selectedChildren(suggestions) - if not len(items) == 1: - return False - - if includeLabel: - label = self._script.utilities.displayedLabel(suggestions) \ - or AXObject.get_name(suggestions) - else: - label = "" - string = AXObject.get_name(items[0]) - - msg = f"{label} {string}" - voice = self._script.speechGenerator.voice(string=msg) - self._script.speakMessage(msg.strip(), voice=voice) - if detailed or cthulhu.cthulhuApp.settingsManager.getSetting('spellcheckSpellSuggestion'): - self._script.spellCurrentItem(string) - - if cthulhu.cthulhuApp.settingsManager.getSetting('enablePositionSpeaking') \ - and items[0] == cthulhu_state.locusOfFocus: - index, total = self._getSuggestionIndexAndPosition(items[0]) - msg = object_properties.GROUP_INDEX_SPEECH % {"index": index, "total": total} - self._script.speakMessage(msg) - - return True - - def _clearState(self): - self._window = None - self._errorWidget = None - self._changeToEntry = None - self._suggestionsList = None - self._activated = False - - def _isCandidateWindow(self, window): - return False - - def _findChangeToEntry(self, root): - return None - - def _findErrorWidget(self, root): - return None - - def _findSuggestionsList(self, root): - return None - - def _getSuggestionIndexAndPosition(self, suggestion): - return -1, -1 - - def getAppPreferencesGUI(self): - - from gi.repository import Gtk - - frame = Gtk.Frame() - label = Gtk.Label(label=f"{guilabels.SPELL_CHECK}") - label.set_use_markup(True) - frame.set_label_widget(label) - - alignment = Gtk.Alignment.new(0.5, 0.5, 1, 1) - alignment.set_padding(0, 0, 12, 0) - frame.add(alignment) - - grid = Gtk.Grid() - alignment.add(grid) - - label = guilabels.SPELL_CHECK_SPELL_ERROR - value = cthulhu.cthulhuApp.settingsManager.getSetting('spellcheckSpellError') - self.spellErrorCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self.spellErrorCheckButton.set_active(value) - grid.attach(self.spellErrorCheckButton, 0, 0, 1, 1) - - label = guilabels.SPELL_CHECK_SPELL_SUGGESTION - value = cthulhu.cthulhuApp.settingsManager.getSetting('spellcheckSpellSuggestion') - self.spellSuggestionCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self.spellSuggestionCheckButton.set_active(value) - grid.attach(self.spellSuggestionCheckButton, 0, 1, 1, 1) - - label = guilabels.SPELL_CHECK_PRESENT_CONTEXT - value = cthulhu.cthulhuApp.settingsManager.getSetting('spellcheckPresentContext') - self.presentContextCheckButton = Gtk.CheckButton.new_with_mnemonic(label) - self.presentContextCheckButton.set_active(value) - grid.attach(self.presentContextCheckButton, 0, 2, 1, 1) - - return frame - - def getPreferencesFromGUI(self): - """Returns a dictionary with the app-specific preferences.""" - - return { - 'spellcheckSpellError': self.spellErrorCheckButton.get_active(), - 'spellcheckSpellSuggestion': self.spellSuggestionCheckButton.get_active(), - 'spellcheckPresentContext': self.presentContextCheckButton.get_active() - } diff --git a/src/cthulhu/structural_navigation.py b/src/cthulhu/structural_navigation.py deleted file mode 100644 index 6f30e0c..0000000 --- a/src/cthulhu/structural_navigation.py +++ /dev/null @@ -1,2441 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Implements structural navigation.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc." \ - "Copyright (c) 2010-2013 The Cthulhu Team" -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import cmdnames -from . import cthulhu -from . import dbus_service -from . import debug -from . import guilabels -from . import input_event -from . import keybindings -from . import messages -from . import object_properties -from . import cthulhu_gui_navlist -from . import cthulhu_state -from . import settings -from . import settings_manager -from .ax_collection import AXCollection -from .ax_event_synthesizer import AXEventSynthesizer -from .ax_object import AXObject -from .ax_table import AXTable -from .ax_text import AXText -from .ax_selection import AXSelection -from .ax_utilities import AXUtilities - -_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager - -########################################################################### -# # -# StructuralNavigationObject # -# # -########################################################################### - -class StructuralNavigationObject: - """Represents a document object which has identifiable characteristics - which can be used for the purpose of navigation to and among instances - of that object. These characteristics may be something as simple as a - role and/or a state of interest. Or they may be something more complex - such as character counts, text attributes, and other object attributes. - """ - def __init__(self, structuralNavigation, objType, bindings, predicate, - criteria, presentation, dialogData, getter): - """Creates a new structural navigation object. - - Arguments: - - structuralNavigation: the StructuralNavigation class associated - with this object. - - objType: the type (e.g. BLOCKQUOTE) associated with this object. - - bindings: a dictionary of all of the possible bindings for this - object. In the case of all but the "atLevel" bindings, each - binding takes the form of [keysymstring, modifiers, description]. - The goPreviousAtLevel and goNextAtLevel bindings are each a list - of bindings in that form. - - predicate: the method to use to verify if a given accessible - matches this structural navigation object. Used only when the - collection interface does not provide a way for us to specify - needed condition(s). - - criteria: a method which returns a MatchRule object which is used - to find all matching objects via AtspiCollection. - - presentation: the method which should be called after performing - the search for the structural navigation object. - - dialogData: the method which returns the title, column headers, - and row data which should be included in the "list of" dialog for - the structural navigation object. - - getter: The function which should be used instead of the criteria - and predicate. - """ - - self.structuralNavigation = structuralNavigation - self.objType = objType - self.bindings = bindings - self.predicate = predicate - self.criteria = criteria - self.present = presentation - self._dialogData = dialogData - self.getter = getter - - self.inputEventHandlers = {} - self.keyBindings = keybindings.KeyBindings() - self.functions = [] - self._setUpHandlersAndBindings() - - def _setUpHandlersAndBindings(self): - """Adds the inputEventHandlers and keyBindings for this object.""" - - # Set up the basic handlers. These are our traditional goPrevious - # and goNext functions. - # - previousBinding = self.bindings.get("previous") - if previousBinding: - [keysymstring, modifiers, description] = previousBinding - handlerName = f"{self.objType}GoPrevious" - self.inputEventHandlers[handlerName] = \ - input_event.InputEventHandler(self.goPrevious, description) - - self.keyBindings.add( - keybindings.KeyBinding( - keysymstring, - keybindings.defaultModifierMask, - modifiers, - self.inputEventHandlers[handlerName])) - - self.functions.append(self.goPrevious) - - nextBinding = self.bindings.get("next") - if nextBinding: - [keysymstring, modifiers, description] = nextBinding - handlerName = f"{self.objType}GoNext" - self.inputEventHandlers[handlerName] = \ - input_event.InputEventHandler(self.goNext, description) - - self.keyBindings.add( - keybindings.KeyBinding( - keysymstring, - keybindings.defaultModifierMask, - modifiers, - self.inputEventHandlers[handlerName])) - - self.functions.append(self.goNext) - - listBinding = self.bindings.get("list") - if listBinding: - [keysymstring, modifiers, description] = listBinding - handlerName = f"{self.objType}ShowList" - self.inputEventHandlers[handlerName] = \ - input_event.InputEventHandler(self.showList, description) - - self.keyBindings.add( - keybindings.KeyBinding( - keysymstring, - keybindings.defaultModifierMask, - modifiers, - self.inputEventHandlers[handlerName])) - - self.functions.append(self.showList) - - # Set up the "at level" handlers (e.g. to navigate among headings - # at the specified level). - # - previousAtLevel = self.bindings.get("previousAtLevel") or [] - for i, binding in enumerate(previousAtLevel): - level = i + 1 - handler = self.goPreviousAtLevelFactory(level) - handlerName = "%sGoPreviousLevel%dHandler" % (self.objType, level) - keysymstring, modifiers, description = binding - - self.inputEventHandlers[handlerName] = \ - input_event.InputEventHandler(handler, description) - - self.keyBindings.add( - keybindings.KeyBinding( - keysymstring, - keybindings.defaultModifierMask, - modifiers, - self.inputEventHandlers[handlerName])) - - self.functions.append(handler) - - nextAtLevel = self.bindings.get("nextAtLevel") or [] - for i, binding in enumerate(nextAtLevel): - level = i + 1 - handler = self.goNextAtLevelFactory(level) - handlerName = "%sGoNextLevel%dHandler" % (self.objType, level) - keysymstring, modifiers, description = binding - - self.inputEventHandlers[handlerName] = \ - input_event.InputEventHandler(handler, description) - - self.keyBindings.add( - keybindings.KeyBinding( - keysymstring, - keybindings.defaultModifierMask, - modifiers, - self.inputEventHandlers[handlerName])) - - self.functions.append(handler) - - listAtLevel = self.bindings.get("listAtLevel") or [] - for i, binding in enumerate(listAtLevel): - level = i + 1 - handler = self.showListAtLevelFactory(level) - handlerName = "%sShowListAtLevel%dHandler" % (self.objType, level) - keysymstring, modifiers, description = binding - - self.inputEventHandlers[handlerName] = \ - input_event.InputEventHandler(handler, description) - - self.keyBindings.add( - keybindings.KeyBinding( - keysymstring, - keybindings.defaultModifierMask, - modifiers, - self.inputEventHandlers[handlerName])) - - self.functions.append(handler) - - # Set up the "directional" handlers (e.g. for table cells. Live - # region support has a handler to go to the last live region, - # so we'll handle that here as well). - # - directions = {} - directions["Left"] = self.bindings.get("left") - directions["Right"] = self.bindings.get("right") - directions["Up"] = self.bindings.get("up") - directions["Down"] = self.bindings.get("down") - directions["First"] = self.bindings.get("first") - directions["Last"] = self.bindings.get("last") - directions["Start"] = self.bindings.get("start") - directions["End"] = self.bindings.get("end") - - for direction in directions: - binding = directions.get(direction) - if not binding: - continue - - handler = self.goDirectionFactory(direction) - handlerName = f"{self.objType}Go{direction}" - keysymstring, modifiers, description = binding - - self.inputEventHandlers[handlerName] = \ - input_event.InputEventHandler(handler, description) - - self.keyBindings.add( - keybindings.KeyBinding( - keysymstring, - keybindings.defaultModifierMask, - modifiers, - self.inputEventHandlers[handlerName])) - - self.functions.append(handler) - - def addHandlerAndBinding(self, binding, handlerName, function): - """Adds a custom inputEventHandler and keybinding to the object's - handlers and bindings. Right now this is unused, but here in - case a creator of a StructuralNavigationObject had some other - desired functionality in mind. - - Arguments: - - binding: [keysymstring, modifiers, description] - - handlerName: a string uniquely identifying the handler - - function: the function associated with the binding - """ - - [keysymstring, modifiers, description] = binding - handler = input_event.InputEventHandler(function, description) - keyBinding = keybindings.KeyBinding( - keysymstring, - keybindings.defaultModifierMask, - modifiers, - handler) - - self.inputEventHandlers[handlerName] = handler - self.structuralNavigation.inputEventHandlers[handlerName] = handler - - self.functions.append(function) - self.structuralNavigation.functions.append(function) - - self.keyBindings.add(keyBinding) - self.structuralNavigation.keyBindings.add(keyBinding) - - def goPrevious(self, script, inputEvent): - """Go to the previous object.""" - self.structuralNavigation.goObject(self, False) - - def goNext(self, script, inputEvent): - """Go to the next object.""" - self.structuralNavigation.goObject(self, True) - - def showList(self, script, inputEvent): - """Show a list of all the items with this object type.""" - - objects = self.structuralNavigation._getAll(self) - - def _isValidMatch(x): - if AXObject.is_dead(x): - return False - return not (script.utilities.isHidden(x) or script.utilities.isEmpty(x)) - - objects = list(filter(_isValidMatch, objects)) - - if self.predicate is not None: - objects = list(filter(self.predicate, objects)) - - if self._dialogData is None: - msg = "STRUCTURAL NAVIGATION: Cannot show list without dialog data" - debug.printMessage(debug.LEVEL_INFO, msg, True) - return - - title, columnHeaders, rowData = self._dialogData() - count = len(objects) - title = f"{title}: {messages.itemsFound(count)}" - if not count: - script.presentMessage(title) - return - - currentObject, offset = script.utilities.getCaretContext() - try: - index = objects.index(currentObject) - except Exception: - index = 0 - - rows = [[obj, -1] + rowData(obj) for obj in objects] - cthulhu_gui_navlist.showUI(title, columnHeaders, rows, index) - - def goPreviousAtLevelFactory(self, level): - """Generates a goPrevious method for the specified level. Right - now, this is just for headings, but it may have applicability - for other objects such as list items (i.e. for level-based - navigation in an outline or other multi-tiered list. - - Arguments: - - level: the desired level of the object as an int. - """ - - def goPreviousAtLevel(script, inputEvent): - self.structuralNavigation.goObject(self, False, arg=level) - return goPreviousAtLevel - - def goNextAtLevelFactory(self, level): - """Generates a goNext method for the specified level. Right - now, this is just for headings, but it may have applicability - for other objects such as list items (i.e. for level-based - navigation in an outline or other multi-tiered list. - - Arguments: - - level: the desired level of the object as an int. - - """ - - def goNextAtLevel(script, inputEvent): - self.structuralNavigation.goObject(self, True, arg=level) - return goNextAtLevel - - def showListAtLevelFactory(self, level): - """Generates a showList method for the specified level. Right - now, this is just for headings, but it may have applicability - for other objects such as list items (i.e. for level-based - navigation in an outline or other multi-tiered list. - - Arguments: - - level: the desired level of the object as an int. - """ - - def showListAtLevel(script, inputEvent): - objects = self.structuralNavigation._getAll(self, arg=level) - - def _isValidMatch(x): - return not (script.utilities.isHidden(x) or script.utilities.isEmpty(x)) - - objects = list(filter(_isValidMatch, objects)) - if self.predicate is not None: - objects = list(filter(self.predicate, objects)) - - title, columnHeaders, rowData = self._dialogData(arg=level) - count = len(objects) - title = f"{title}: {messages.itemsFound(count)}" - if not count: - script.presentMessage(title) - return - - currentObject, offset = script.utilities.getCaretContext() - try: - index = objects.index(currentObject) - except Exception: - index = 0 - - rows = [[obj, -1] + rowData(obj) for obj in objects] - cthulhu_gui_navlist.showUI(title, columnHeaders, rows, index) - - return showListAtLevel - - def goDirectionFactory(self, direction): - """Generates the methods for navigation in a particular direction - (i.e. left, right, up, down, first, last). Right now, this is - primarily for table cells, but it may have applicability for other - objects. For example, when navigating in an outline, one might - want the ability to navigate to the next item at a given level, - but then work his/her way up/down in the hierarchy. - - Arguments: - - direction: the direction in which to navigate as a string. - """ - - def goCell(script, inputEvent): - obj, offset = script.utilities.getCaretContext() - thisCell = self.structuralNavigation.getCellForObj(obj) - currentCoordinates = self.structuralNavigation.getCellCoordinates(thisCell, False) - if direction == "Left": - desiredCoordinates = [currentCoordinates[0], - currentCoordinates[1] - 1] - elif direction == "Right": - desiredCoordinates = [currentCoordinates[0], - currentCoordinates[1] + 1] - elif direction == "Up": - desiredCoordinates = [currentCoordinates[0] - 1, - currentCoordinates[1]] - elif direction == "Down": - desiredCoordinates = [currentCoordinates[0] + 1, - currentCoordinates[1]] - elif direction == "First": - desiredCoordinates = [0, 0] - else: - desiredCoordinates = [-1, -1] - table = self.structuralNavigation.getTableForCell(thisCell) - if table: - nRows, nColumns = script.utilities.rowAndColumnCount(table, False) - lastRow = nRows - 1 - lastCol = nColumns - 1 - desiredCoordinates = [lastRow, lastCol] - self.structuralNavigation.goCell(self, - thisCell, - currentCoordinates, - desiredCoordinates) - - def goLastLiveRegion(script, inputEvent): - """Go to the last liveRegion.""" - if settings.inferLiveRegions: - script.liveRegionManager.goLastLiveRegion() - else: - script.presentMessage(messages.LIVE_REGIONS_OFF) - - def goContainerEdge(script, inputEvent): - isStart = direction == "Start" - self.structuralNavigation.goEdge(self, isStart) - - if self.objType == StructuralNavigation.CONTAINER: - return goContainerEdge - if self.objType == StructuralNavigation.TABLE_CELL: - return goCell - elif self.objType == StructuralNavigation.LIVE_REGION \ - and direction == "Last": - return goLastLiveRegion - -############################################################################# -# # -# StructuralNavigation # -# # -############################################################################# - -class StructuralNavigation: - """This class implements the structural navigation functionality which - is available to scripts. Scripts interested in implementing structural - navigation need to override getEnabledStructuralNavigationTypes() and - return a list of StructuralNavigation object types which should be - enabled. - """ - - # The available object types. - # - # Convenience methods have been put into place whereby one can - # create an object (FOO = "foo"), and then provide the following - # methods: _fooBindings(), _fooPredicate(), _fooCriteria(), and - # _fooPresentation(). With these in place, and with the object - # FOO included among the object types returned by the script's - # getEnabledStructuralNavigationTypes(), the StructuralNavigation - # object should be created and set up automagically. At least that - # is the idea. :-) This hopefully will also enable easy re-definition - # of existing StructuralNavigationObjects on a script-by-script basis. - # For instance, in the soffice script, overriding _blockquotePredicate - # should be all that is needed to implement navigation by blockquote - # in OOo Writer documents. - # - BLOCKQUOTE = "blockquote" - BUTTON = "button" - CHECK_BOX = "checkBox" - CHUNK = "chunk" - CLICKABLE = "clickable" - COMBO_BOX = "comboBox" - CONTAINER = "container" - ENTRY = "entry" - FORM_FIELD = "formField" - HEADING = "heading" - IMAGE = "image" - IFRAME = "iframe" - LANDMARK = "landmark" - LINK = "link" - LIST = "list" # Bulleted/numbered lists - LIST_ITEM = "listItem" # Bulleted/numbered list items - LIVE_REGION = "liveRegion" - PARAGRAPH = "paragraph" - RADIO_BUTTON = "radioButton" - SEPARATOR = "separator" - TABLE = "table" - TABLE_CELL = "tableCell" - UNVISITED_LINK = "unvisitedLink" - VISITED_LINK = "visitedLink" - - # Roles which are recognized as being potential "large objects" - # or "chunks." Note that this refers to AT-SPI roles. - # - OBJECT_ROLES = [Atspi.Role.HEADING, - Atspi.Role.LIST_ITEM, - Atspi.Role.MATH, - Atspi.Role.PARAGRAPH, - Atspi.Role.STATIC, - Atspi.Role.COLUMN_HEADER, - Atspi.Role.ROW_HEADER, - Atspi.Role.TABLE_CELL, - Atspi.Role.TABLE_ROW, - Atspi.Role.TEXT, - Atspi.Role.SECTION, - Atspi.Role.ARTICLE, - Atspi.Role.DESCRIPTION_TERM, - Atspi.Role.DESCRIPTION_VALUE, - Atspi.Role.DOCUMENT_EMAIL, - Atspi.Role.DOCUMENT_FRAME, - Atspi.Role.DOCUMENT_PRESENTATION, - Atspi.Role.DOCUMENT_SPREADSHEET, - Atspi.Role.DOCUMENT_TEXT, - Atspi.Role.DOCUMENT_WEB] - - CONTAINER_ROLES = [Atspi.Role.BLOCK_QUOTE, - Atspi.Role.DESCRIPTION_LIST, - Atspi.Role.FORM, - Atspi.Role.FOOTER, - Atspi.Role.HEADER, - Atspi.Role.LANDMARK, - Atspi.Role.LOG, - Atspi.Role.LIST, - Atspi.Role.MARQUEE, - Atspi.Role.PANEL, - Atspi.Role.SECTION, - Atspi.Role.TABLE, - Atspi.Role.TREE, - Atspi.Role.TREE_TABLE] - - def __init__(self, script, enabledTypes, enabled=False): - """Creates an instance of the StructuralNavigation class. - - Arguments: - - script: the script which which this instance is associated. - - enabledTypes: a list of StructuralNavigation object types - which the script is interested in supporting. - - enabled: Whether structural navigation should start out - enabled. For instance, in Gecko by default we do what it - enabled; in soffice, we would want to start out with it - disabled and have the user enable it via a keystroke when - desired. - """ - - self._script = script - self.enabled = enabled - - # Create all of the StructuralNavigationObject's in which the - # script is interested, using the convenience method - # - self.enabledObjects = {} - for objType in enabledTypes: - self.enabledObjects[objType] = \ - self.structuralNavigationObjectCreator(objType) - - self.functions = [] - self.inputEventHandlers = {} - self.setupInputEventHandlers() - self.keyBindings = self.getKeyBindings() - - # When navigating in a non-uniform table, one can move to a - # cell which spans multiple rows and/or columns. When moving - # beyond that cell, into a cell that does NOT span multiple - # rows/columns, we want to be sure we land in the right place. - # Therefore, we'll store the coordinates from "our perspective." - # - self.lastTableCell = [-1, -1] - - self._inModalDialog = False - - def clearCache(self, document=None): - """No-op for backwards compatibility. Caching has been removed.""" - pass - - def structuralNavigationObjectCreator(self, name): - """This convenience method creates a StructuralNavigationObject - with the specified name and associated characteristics. (See the - "Objects" section of code near the end of this class. Creators - of StructuralNavigationObject's can still do things the old - fashioned way should they so choose, by creating the instance - and then adding it via addObject(). - - Arguments: - - name: the name/objType associated with this object. - """ - - # Bindings and presentation are mandatory. - bindings = eval(f"self._{name}Bindings()") - presentation = eval(f"self._{name}Presentation") - - # Predicates should be the exception; not the rule. - try: - predicate = eval(f"self._{name}Predicate") - except Exception: - predicate = None - - # Dialogs are nice, but we shouldn't insist upon them. - try: - dialogData = eval(f"self._{name}DialogData") - except Exception: - dialogData = None - - # Criteria is the present, but being phased out. - try: - criteria = eval(f"self._{name}Criteria") - except Exception: - criteria = None - - # Getters are the future! - try: - getter = eval(f"self._{name}Getter") - except Exception: - getter = None - - return StructuralNavigationObject(self, name, bindings, predicate, - criteria, presentation, dialogData, getter) - - def addObject(self, objType, structuralNavigationObject): - """Adds structuralNavigationObject to the dictionary of enabled - objects. - - Arguments: - - objType: the name/object type of the StructuralNavigationObject. - - structuralNavigationObject: the StructuralNavigationObject to - add. - """ - - self.enabledObjects[objType] = structuralNavigationObject - - def setupInputEventHandlers(self): - """Defines InputEventHandler fields for a script.""" - - if not len(self.enabledObjects): - return - - self.inputEventHandlers["toggleStructuralNavigationHandler"] = \ - input_event.InputEventHandler( - self.toggleStructuralNavigation, - cmdnames.STRUCTURAL_NAVIGATION_TOGGLE) - - for structuralNavigationObject in self.enabledObjects.values(): - self.inputEventHandlers.update(\ - structuralNavigationObject.inputEventHandlers) - self.functions.extend(structuralNavigationObject.functions) - - def getKeyBindings(self): - """Defines the structural navigation key bindings for a script. - - Returns: an instance of keybindings.KeyBindings. - """ - - keyBindings = keybindings.KeyBindings() - - if not len(self.enabledObjects): - return keyBindings - - keyBindings.add( - keybindings.KeyBinding( - "z", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self.inputEventHandlers["toggleStructuralNavigationHandler"])) - - for structuralNavigationObject in self.enabledObjects.values(): - bindings = structuralNavigationObject.keyBindings.keyBindings - for keybinding in bindings: - keyBindings.add(keybinding) - - return keyBindings - - ######################################################################### - # # - # Input Event Handler Methods # - # # - ######################################################################### - - def toggleStructuralNavigation(self, script, inputEvent, presentMessage=True): - """Toggles structural navigation keys.""" - - self.enabled = not self.enabled - - if self.enabled: - string = messages.STRUCTURAL_NAVIGATION_KEYS_ON - else: - string = messages.STRUCTURAL_NAVIGATION_KEYS_OFF - - if presentMessage: - self._script.presentMessage(string) - - ######################################################################### - # # - # Methods for Moving to Objects # - # # - ######################################################################### - - def goCell(self, structuralNavigationObject, thisCell, - currentCoordinates, desiredCoordinates): - """The method used for navigation among cells in a table. - - Arguments: - - structuralNavigationObject: the StructuralNavigationObject which - represents the table cell. - - thisCell: the accessible TABLE_CELL we're currently in - - currentCoordinates: the [row, column] of thisCell. Note, we - cannot just get the coordinates because in table cells which - span multiple rows and/or columns, the value returned by - table.getRowAtIndex() is the first row the cell spans. Likewise, - the value returned by table.getColumnAtIndex() is the left-most - column. Therefore, we keep track of the row and column from - our perspective to ensure we stay in the correct row and column. - - desiredCoordinates: the [row, column] where we think we'd like to - be. - """ - - table = self.getTableForCell(thisCell) - if not table: - self._script.presentMessage(messages.TABLE_NOT_IN_A) - return None - - currentRow, currentCol = currentCoordinates - desiredRow, desiredCol = desiredCoordinates - rowDiff = desiredRow - currentRow - colDiff = desiredCol - currentCol - - nRows, nColumns = self._script.utilities.rowAndColumnCount(table, False) - cell = thisCell - while cell: - cell = self._script.utilities.cellForCoordinates(table, desiredRow, desiredCol) - if not cell: - if desiredCol < 0: - self._script.presentMessage(messages.TABLE_ROW_BEGINNING) - desiredCol = 0 - elif desiredCol > nColumns - 1: - self._script.presentMessage(messages.TABLE_ROW_END) - desiredCol = nColumns - 1 - if desiredRow < 0: - self._script.presentMessage(messages.TABLE_COLUMN_TOP) - desiredRow = 0 - elif desiredRow > nRows - 1: - self._script.presentMessage(messages.TABLE_COLUMN_BOTTOM) - desiredRow = nRows - 1 - elif (thisCell == cell and (colDiff or rowDiff)) \ - or (settings.skipBlankCells and self._isBlankCell(cell)): - if colDiff < 0: - desiredCol -= 1 - elif colDiff > 0: - desiredCol += 1 - if rowDiff < 0: - desiredRow -= 1 - elif rowDiff > 0: - desiredRow += 1 - else: - break - - self.lastTableCell = [desiredRow, desiredCol] - if cell: - oldRowHeaders = self._script.utilities.rowHeadersForCell(thisCell) - oldColHeaders = self._script.utilities.columnHeadersForCell(thisCell) - arg = [rowDiff, colDiff, oldRowHeaders, oldColHeaders] - structuralNavigationObject.present(cell, arg) - - def _getAll(self, structuralNavigationObject, arg=None): - """Returns all the instances of structuralNavigationObject. - - Queries fresh each time without caching to ensure accurate results - when returning to a page after switching applications. - """ - - modalDialog = self._script.utilities.getModalDialog(cthulhu_state.locusOfFocus) - inModalDialog = bool(modalDialog) - if self._inModalDialog != inModalDialog: - msg = ( - f"STRUCTURAL NAVIGATION: in modal dialog has changed from " - f"{self._inModalDialog} to {inModalDialog}" - ) - debug.printMessage(debug.LEVEL_INFO, msg, True) - self._inModalDialog = inModalDialog - - document = self._script.utilities.documentFrame() - if not document: - return [] - - if structuralNavigationObject.getter: - matches = structuralNavigationObject.getter(document, arg) - elif not structuralNavigationObject.criteria: - return [] - elif not AXObject.supports_collection(document): - tokens = ["STRUCTURAL NAVIGATION:", document, "does not support collection"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - else: - rule = structuralNavigationObject.criteria(arg) - matches = AXCollection.get_all_matches(document, rule) - - if inModalDialog: - originalSize = len(matches) - matches = [m for m in matches if AXObject.find_ancestor(m, lambda x: x == modalDialog)] - tokens = ["STRUCTURAL NAVIGATION: Removed", originalSize - len(matches), - "objects outside of modal dialog", modalDialog] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - # Filter out zombie objects and return - return [m for m in matches if not self._script.utilities.isZombie(m)] - - def goEdge(self, structuralNavigationObject, isStart, container=None, arg=None): - if container is None: - obj, offset = self._script.utilities.getCaretContext() - container = self.getContainerForObject(obj) - - if container is None or AXObject.is_dead(container): - structuralNavigationObject.present(None, arg) - return - - if isStart: - obj, offset = self._script.utilities.nextContext(container, -1) - structuralNavigationObject.present(obj, offset) - return - - # Unlike going to the start of the container, when we move to the next edge - # we pass beyond it on purpose. This makes us consistent with NVDA. - obj, offset = self._script.utilities.lastContext(container) - newObj, newOffset = self._script.utilities.nextContext(obj, offset) - if not newObj: - document = self._script.utilities.getDocumentForObject(obj) - newObj = self._script.utilities.getNextObjectInDocument(obj, document) - - newContainer = self.getContainerForObject(newObj) - if newObj and newContainer != container: - structuralNavigationObject.present(newObj, newOffset) - return - - if obj == container: - obj = AXObject.get_child(obj, -1) - - structuralNavigationObject.present(obj, sameContainer=True) - - def goObject(self, structuralNavigationObject, isNext, obj=None, arg=None): - """The method used for navigation among StructuralNavigationObjects - which are not table cells. - - Arguments: - - structuralNavigationObject: the StructuralNavigationObject which - represents the object of interest. - - isNext: If True, we're interested in the next accessible object - which matches structuralNavigationObject. If False, we're - interested in the previous accessible object which matches. - - obj: the current object (typically the locusOfFocus). - - arg: optional arguments which may need to be passed along to - the predicate, presentation method, etc. For instance, in the - case of navigating amongst headings at a given level, the level - is needed and passed in as arg. - """ - - matches = self._getAll(structuralNavigationObject, arg) - if not matches: - structuralNavigationObject.present(None, arg) - return - - if not isNext: - matches.reverse() - - def _isValidMatch(obj): - if AXObject.is_dead(obj): - return False - if self._script.utilities.isZombie(obj): - return False - if self._script.utilities.isHidden(obj) or self._script.utilities.isEmpty(obj): - return False - if structuralNavigationObject.predicate is None: - return True - return structuralNavigationObject.predicate(obj) - - def _getMatchingObjAndIndex(obj): - while obj: - if obj in matches: - return obj, matches.index(obj) - obj = AXObject.get_parent(obj) - - return None, -1 - - offset = 0 - if not obj: - obj, offset = self._script.utilities.getCaretContext() - thisObj, index = _getMatchingObjAndIndex(obj) - if thisObj: - matches = matches[index:] - obj = thisObj - - currentPath = AXObject.get_path(obj) - for i, match in enumerate(matches): - if not _isValidMatch(match): - continue - - if AXObject.get_parent(match) == obj: - comparison = self._script.utilities.characterOffsetInParent(match) - offset - else: - path = AXObject.get_path(match) - comparison = self._script.utilities.pathComparison(path, currentPath) - if (comparison > 0 and isNext) or (comparison < 0 and not isNext): - structuralNavigationObject.present(match, arg) - return - - if not settings.wrappedStructuralNavigation: - structuralNavigationObject.present(None, arg) - return - - if not isNext: - wrapMessage = messages.WRAPPING_TO_BOTTOM - else: - wrapMessage = messages.WRAPPING_TO_TOP - - matches = self._getAll(structuralNavigationObject, arg) - if not isNext: - matches.reverse() - - for match in matches: - if _isValidMatch(match): - structuralNavigationObject.present(match, arg) - self._script.presentMessage(wrapMessage) - return - - structuralNavigationObject.present(None, arg) - - ######################################################################### - # # - # Methods for Presenting Objects # - # # - ######################################################################### - - def _getListDescription(self, obj): - children = [x for x in AXObject.iter_children(obj, AXUtilities.is_list_item)] - if not children: - return "" - - return messages.listItemCount(len(children)) - - def _getTableCaption(self, obj): - """Returns a string which contains the table caption, or - None if a caption could not be found. - - Arguments: - - obj: the accessible table whose caption we want. - """ - - caption = AXTable.get_caption(obj) - if not caption: - return None - - return AXText.get_all_text(caption) - - def _getTableDescription(self, obj): - """Returns a string which describes the table.""" - - nonUniformString = "" - nonUniform = self._script.utilities.isNonUniformTable(obj) - if nonUniform: - nonUniformString = messages.TABLE_NON_UNIFORM + " " - - nRows, nColumns = self._script.utilities.rowAndColumnCount(obj, True) - sizeString = messages.tableSize(nRows, nColumns) - return (nonUniformString + sizeString) - - def getCellForObj(self, obj): - """Looks for a table cell in the ancestry of obj, if obj is not a - table cell. - - Arguments: - - obj: the accessible object of interest. - """ - - if not AXUtilities.is_table_cell_or_header(obj): - obj = AXObject.find_ancestor(obj, AXUtilities.is_table_cell_or_header) - - while obj and self._script.utilities.isLayoutOnly(self.getTableForCell(obj)): - cell = AXObject.find_ancestor(obj, AXUtilities.is_table_cell_or_header) - if cell is None: - break - obj = cell - - return obj - - def _isContainer(self, obj): - role = AXObject.get_role(obj) - if role not in self.CONTAINER_ROLES: - return False - - if role == Atspi.Role.SECTION \ - and not self._script.utilities.isLandmark(obj) \ - and not self._script.utilities.isBlockquote(obj): - return False - - return self._script.utilities.inDocumentContent(obj) - - def getContainerForObject(self, obj): - if not obj: - return None - - if self._isContainer(obj): - return obj - - return AXObject.find_ancestor(obj, self._isContainer) - - def getTableForCell(self, obj): - """Looks for a table in the ancestry of obj, if obj is not a table. - - Arguments: - - obj: the accessible object of interest. - """ - - if obj and not AXUtilities.is_table(obj): - obj = AXObject.find_ancestor(obj, AXUtilities.is_table) - - return obj - - def _isBlankCell(self, obj): - """Returns True if the table cell is empty or consists of whitespace. - - Arguments: - - obj: the accessible table cell to examine - """ - - if obj and (AXObject.get_name(obj) or AXObject.get_child_count(obj)): - return False - - if AXObject.supports_text(obj): - if AXText.get_all_text(obj).strip(): - return False - - return True - - def _getCellText(self, obj): - """Looks at the table cell and tries to get its text. - - Arguments: - - obj: the accessible table cell to examine - """ - - text = "" - if obj and not AXObject.get_child_count(obj): - text = self._script.utilities.displayedText(obj) - else: - for child in AXObject.iter_children(obj): - childText = self._script.utilities.displayedText(child) - text = self._script.utilities.appendString(text, childText) - - return text - - def _presentCellHeaders(self, cell, oldCellInfo): - """Speaks the headers of the accessible table cell, cell. - - Arguments: - - cell: the accessible table cell whose headers we wish to - present. - - oldCellInfo: [rowDiff, colDiff, oldRowHeaders, oldColHeaders] - """ - - if not cell or not oldCellInfo: - return - - rowDiff, colDiff, oldRowHeaders, oldColHeaders = oldCellInfo - if not (oldRowHeaders or oldColHeaders): - return - - if rowDiff: - rowHeaders = self._script.utilities.rowHeadersForCell(cell) - for header in rowHeaders: - if header not in oldRowHeaders: - text = self._getCellText(header) - voice = self._script.speechGenerator.voice(string=text) - self._script.speakMessage(text, voice=voice, force=True) - - if colDiff: - colHeaders = self._script.utilities.columnHeadersForCell(cell) - for header in colHeaders: - if header not in oldColHeaders: - text = self._getCellText(header) - voice = self._script.speechGenerator.voice(string=text) - self._script.speakMessage(text, voice=voice, force=True) - - def getCellCoordinates(self, obj, preferAttribute=True): - """Returns the [row, col] of a ROLE_TABLE_CELL or [-1, -1] - if the coordinates cannot be found. - - Arguments: - - obj: the accessible table cell whose coordinates we want. - - preferAttribute: If True, prefer object attribute over table interface - """ - - cell = self.getCellForObj(obj) - table = self.getTableForCell(cell) - thisRow, thisCol = self._script.utilities.coordinatesForCell(cell, preferAttribute) - - # If preferAttribute is True, we are getting coordinates to be spoken, - # and not to deal with the logic below. - if preferAttribute: - return thisRow, thisCol - - # If we're in a cell that spans multiple rows and/or columns, - # thisRow and thisCol will refer to the upper left cell in - # the spanned range(s). We're storing the lastTableCell that - # we're aware of in order to facilitate more linear movement. - # Therefore, if the lastTableCell and this table cell are the - # same cell, we'll go with the stored coordinates. - lastRow, lastCol = self.lastTableCell - lastCell = self._script.utilities.cellForCoordinates(table, lastRow, lastCol) - if lastCell == cell: - return lastRow, lastCol - - return thisRow, thisCol - - def _getCaretPosition(self, obj): - """Returns the [obj, characterOffset] where the caret should be - positioned. For most scripts, the object should not change and - the offset should be 0. That's not always the case with Gecko. - - Arguments: - - obj: the accessible object in which the caret should be - positioned. - """ - - return self._script.utilities.getFirstCaretPosition(obj) - - def _setCaretPosition(self, obj, characterOffset): - """Sets the caret at the specified offset within obj.""" - - objPath = AXObject.get_path(obj) - objRole = AXObject.get_role(obj) - if objRole == Atspi.Role.INVALID: - return None, characterOffset - - self._script.utilities.setCaretPosition(obj, characterOffset) - AXObject.clear_cache(obj) - if not AXUtilities.is_defunct(obj) and not self._script.utilities.isZombie(obj): - return obj, characterOffset - - tokens = ["STRUCTURAL NAVIGATION:", obj, "became defunct after setting caret position"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - replicant = self._script.utilities.get_objectFromPath(objPath) - if replicant and AXObject.get_role(replicant) == objRole \ - and not self._script.utilities.isZombie(replicant): - tokens = ["STRUCTURAL NAVIGATION: Updating obj to replicant", replicant] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - obj = replicant - return obj, characterOffset - - document = getattr(self._script.utilities, "documentFrame", None) - searchForCaretContext = getattr(self._script.utilities, "searchForCaretContext", None) - if document and searchForCaretContext: - documentFrame = document() - if documentFrame and not self._script.utilities.isZombie(documentFrame): - fallbackObj, fallbackOffset = searchForCaretContext(documentFrame) - if fallbackObj and not self._script.utilities.isZombie(fallbackObj): - tokens = ["STRUCTURAL NAVIGATION: Recovering focus to", fallbackObj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cthulhu.setLocusOfFocus(None, fallbackObj, notifyScript=False) - self._script.utilities.setCaretContext( - fallbackObj, fallbackOffset, documentFrame) - - return None, characterOffset - - def _presentLine(self, obj, offset): - """Presents the first line of the object to the user. - - Arguments: - - obj: the accessible object to be presented. - - offset: the character offset within obj. - """ - - if not obj: - return - - if self._presentWithSayAll(obj, offset): - return - - self._script.updateBraille(obj) - self._script.sayLine(obj) - - def _presentObject(self, obj, offset, priorObj=None): - """Presents the entire object to the user. - - Arguments: - - obj: the accessible object to be presented. - - offset: the character offset within obj. - """ - - if not obj: - return - - if self._presentWithSayAll(obj, offset): - return - - AXEventSynthesizer.scroll_to_top_edge(obj) - self._script.presentObject( - obj, - offset=offset, - priorObj=priorObj, - interrupt=True, - interrupt_already_handled=True, - ) - - def _presentWithSayAll(self, obj, offset): - if self._script.inSayAll() \ - and cthulhu.cthulhuApp.settingsManager.getSetting('structNavInSayAll'): - self._script.sayAll(obj, offset) - return True - - return False - - def _getRoleName(self, obj): - # Another case where we'll do this for now, and clean it up when - # object presentation is refactored. - return self._script.speechGenerator.getLocalizedRoleName(obj) - - def _getSelectedItem(self, obj): - # Another case where we'll do this for now, and clean it up when - # object presentation is refactored. - if AXUtilities.is_combo_box(obj): - obj = AXObject.get_child(obj, 0) - - if not AXObject.supports_selection(obj): - return None - - return AXSelection.get_selected_child(obj, 0) - - def _getText(self, obj): - # Another case where we'll do this for now, and clean it up when - # object presentation is refactored. - text = self._script.utilities.displayedText(obj) - if not text: - text = self._script.utilities.expandEOCs(obj) - if not text: - item = self._getSelectedItem(obj) - if item: - text = AXObject.get_name(item) - if not text and AXUtilities.is_image(obj): - text = AXObject.get_image_description(obj) or AXObject.get_description(obj) - if not text: - parent = AXObject.get_parent(obj) - if AXUtilities.is_link(parent): - text = self._script.utilities.linkBasename(parent) - if not text and AXUtilities.is_list(obj): - children = [x for x in AXObject.iter_children(obj, AXUtilities.is_list_item)] - text = " ".join(list(map(self._getText, children))) - - return text - - def _getLabel(self, obj): - # Another case where we'll do this for now, and clean it up when - # object presentation is refactored. - label = self._script.utilities.displayedLabel(obj) - if not label: - label, objects = self._script.labelInference.infer( - obj, focusedOnly=False) - - return label - - def _getState(self, obj): - # Another case where we'll do this for now, and clean it up when - # object presentation is refactored. - - # For now, we'll just grab the spoken indicator from settings. - # When object presentation is refactored, we can clean this up. - if AXUtilities.is_check_box(obj): - unchecked, checked, partially = object_properties.CHECK_BOX_INDICATORS_SPEECH - if AXUtilities.is_indeterminate(obj): - return partially - if AXUtilities.is_checked(obj): - return checked - return unchecked - - if AXUtilities.is_radio_button(obj): - unselected, selected = object_properties.RADIO_BUTTON_INDICATORS_SPEECH - if AXUtilities.is_checked(obj): - return selected - return unselected - - if AXUtilities.is_link(obj): - if AXUtilities.is_visited(obj): - return object_properties.STATE_VISITED - else: - return object_properties.STATE_UNVISITED - - return '' - - def _getValue(self, obj): - # Another case where we'll do this for now, and clean it up when - # object presentation is refactored. - return self._getState(obj) or self._getText(obj) - - ######################################################################### - # # - # Objects # - # # - ######################################################################### - - # All structural navigation objects have the following essential - # characteristics: - # - # 1. Keybindings for goPrevious, goNext, and other such methods. - # This is a dictionary. See _setUpHandlersAndBindings() for - # supported values. But "previous", "next", and "list" are - # typically what you'll need. - # 2. A means of identification: MatchCriteria and optional predicate. - # The MatchCriteria is required. For ATK implementations, AT-SPI2 - # implements Collection. Applications and toolkits which implement - # AT-SPI2 directly should provide the implementation because our - # getting all objects via a tree dive is extremely non-performant. - # The predicate is only needed if Collection lacks something we - # need to identify the object is really the thing we want. Usually - # the predicate is not needed and can remain undefined. - # 3. A definition of how the object should be presented (both when - # another instance of that object is found as well as when it is - # not). This function should do the presentation. - # 4. Details needed to populate the dialog with the object list is - # presented. - # - # Convenience methods have been put into place whereby one can - # create an object (FOO = "foo"), and then provide the following - # methods: _fooBindings(), _fooPredicate(), _fooCriteria(), and - # _fooPresentation(). With these in place, and with the object - # FOO included among the StructuralNavigation.enabledTypes for - # the script, the structural navigation object should be created - # and set up automagically. At least that is the idea. :-) This - # hopefully will also enable easy re-definition of existing - # objects on a script-by-script basis. - - ######################## - # # - # Blockquotes # - # # - ######################## - - def _blockquoteBindings(self): - bindings = {} - prevDesc = cmdnames.BLOCKQUOTE_PREV - bindings["previous"] = ["q", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.BLOCKQUOTE_NEXT - bindings["next"] = ["q", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.BLOCKQUOTE_LIST - bindings["list"] = ["q", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _blockquoteGetter(self, document, arg=None): - return AXUtilities.find_all_block_quotes(document) - - def _blockquotePresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_BLOCKQUOTES - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _blockquoteDialogData(self): - columnHeaders = [guilabels.SN_HEADER_BLOCKQUOTE] - - def rowData(obj): - return [self._getText(obj)] - - return guilabels.SN_TITLE_BLOCKQUOTE, columnHeaders, rowData - - ######################## - # # - # Buttons # - # # - ######################## - - def _buttonBindings(self): - bindings = {} - prevDesc = cmdnames.BUTTON_PREV - bindings["previous"] = ["b", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.BUTTON_NEXT - bindings["next"] = ["b", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.BUTTON_LIST - bindings["list"] = ["b", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _buttonGetter(self, document, arg=None): - return AXUtilities.find_all_buttons(document) - - def _buttonPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_BUTTONS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _buttonDialogData(self): - columnHeaders = [guilabels.SN_HEADER_BUTTON] - - def rowData(obj): - return [self._getText(obj)] - - return guilabels.SN_TITLE_BUTTON, columnHeaders, rowData - - ######################## - # # - # Check boxes # - # # - ######################## - - def _checkBoxBindings(self): - bindings = {} - prevDesc = cmdnames.CHECK_BOX_PREV - bindings["previous"] = ["x", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.CHECK_BOX_NEXT - bindings["next"] = ["x", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.CHECK_BOX_LIST - bindings["list"] = ["x", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _checkBoxGetter(self, document, arg=None): - return AXUtilities.find_all_check_boxes(document) - - def _checkBoxPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_CHECK_BOXES - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _checkBoxDialogData(self): - columnHeaders = [guilabels.SN_HEADER_CHECK_BOX] - columnHeaders.append(guilabels.SN_HEADER_STATE) - - def rowData(obj): - return [self._getLabel(obj), self._getState(obj)] - - return guilabels.SN_TITLE_CHECK_BOX, columnHeaders, rowData - - ######################## - # # - # Chunks/Large Objects # - # # - ######################## - - def _chunkBindings(self): - bindings = {} - prevDesc = cmdnames.LARGE_OBJECT_PREV - bindings["previous"] = ["o", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.LARGE_OBJECT_NEXT - bindings["next"] = ["o", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.LARGE_OBJECT_LIST - bindings["list"] = ["o", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _chunkCriteria(self, arg=None): - return AXCollection.create_match_rule(roles=self.OBJECT_ROLES + self.CONTAINER_ROLES) - - def _chunkPredicate(self, obj: Atspi.Accessible, arg=None) -> bool: - if AXUtilities.is_heading(obj): - return True - if AXUtilities.is_list(obj): - return True - if AXUtilities.is_table(obj): - return True - - text = self._script.utilities.queryNonEmptyText(obj) - if not text: - return False - - char_count = AXText.get_character_count(obj) - if char_count <= settings.largeObjectTextLength: - return False - - string = AXText.get_all_text(obj) - eocs = string.count(self._script.EMBEDDED_OBJECT_CHARACTER) - if char_count and eocs/char_count < 0.05: - return True - - return False - - def _chunkPresentation(self, obj, arg=None): - if obj is not None: - [newObj, characterOffset] = self._getCaretPosition(obj) - self._setCaretPosition(newObj, characterOffset) - self._presentObject(obj, 0) - else: - full = messages.NO_MORE_CHUNKS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _chunkDialogData(self): - columnHeaders = [guilabels.SN_HEADER_OBJECT] - columnHeaders.append(guilabels.SN_HEADER_ROLE) - - def rowData(obj): - return [self._getText(obj), self._getRoleName(obj)] - - return guilabels.SN_TITLE_LARGE_OBJECT, columnHeaders, rowData - - ######################## - # # - # Combo Boxes # - # # - ######################## - - def _comboBoxBindings(self): - bindings = {} - prevDesc = cmdnames.COMBO_BOX_PREV - bindings["previous"] = ["c", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.COMBO_BOX_NEXT - bindings["next"] = ["c", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.COMBO_BOX_LIST - bindings["list"] = ["c", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _comboBoxGetter(self, document, arg=None): - return AXUtilities.find_all_combo_boxes(document) - - def _comboBoxPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_COMBO_BOXES - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _comboBoxDialogData(self): - columnHeaders = [guilabels.SN_HEADER_COMBO_BOX] - columnHeaders.append(guilabels.SN_HEADER_SELECTED_ITEM) - - def rowData(obj): - return [self._getLabel(obj), self._getText(obj)] - - return guilabels.SN_TITLE_COMBO_BOX, columnHeaders, rowData - - ######################## - # # - # Entries # - # # - ######################## - - def _entryBindings(self): - bindings = {} - prevDesc = cmdnames.ENTRY_PREV - bindings["previous"] = ["e", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.ENTRY_NEXT - bindings["next"] = ["e", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.ENTRY_LIST - bindings["list"] = ["e", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _entryGetter(self, document, arg=None): - def parent_is_not_editable(obj): - parent = AXObject.get_parent(obj) - return parent is not None and not AXUtilities.is_editable(parent) - return AXUtilities.find_all_editable_objects(document, pred=parent_is_not_editable) - - def _entryPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_ENTRIES - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _entryDialogData(self): - columnHeaders = [guilabels.SN_HEADER_LABEL] - columnHeaders.append(guilabels.SN_HEADER_TEXT) - - def rowData(obj): - return [self._getLabel(obj), self._getText(obj)] - - return guilabels.SN_TITLE_ENTRY, columnHeaders, rowData - - ######################## - # # - # Form Fields # - # # - ######################## - - def _formFieldBindings(self): - bindings = {} - prevDesc = cmdnames.FORM_FIELD_PREV - bindings["previous"] = ["f", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.FORM_FIELD_NEXT - bindings["next"] = ["f", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.FORM_FIELD_LIST - bindings["list"] = ["f", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _formFieldGetter(self, document, arg=None): - def is_not_noneditable_doc_frame(obj): - if AXUtilities.is_document_frame(obj): - return AXUtilities.is_editable(obj) - return True - return AXUtilities.find_all_form_fields(document, pred=is_not_noneditable_doc_frame) - - def _formFieldPresentation(self, obj, arg=None): - if obj is not None: - if AXUtilities.is_text(obj) and AXObject.get_child_count(obj): - obj = AXObject.get_child(obj, 0) - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_FORM_FIELDS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _formFieldDialogData(self): - columnHeaders = [guilabels.SN_HEADER_LABEL] - columnHeaders.append(guilabels.SN_HEADER_ROLE) - columnHeaders.append(guilabels.SN_HEADER_VALUE) - - def rowData(obj): - return [self._getLabel(obj), - self._getRoleName(obj), - self._getValue(obj)] - - return guilabels.SN_TITLE_FORM_FIELD, columnHeaders, rowData - - ######################## - # # - # Headings # - # # - ######################## - - def _headingBindings(self): - bindings = {} - prevDesc = cmdnames.HEADING_PREV - bindings["previous"] = ["h", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.HEADING_NEXT - bindings["next"] = ["h", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.HEADING_LIST - bindings["list"] = ["h", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - - prevAtLevelBindings = [] - nextAtLevelBindings = [] - listAtLevelBindings = [] - minLevel, maxLevel = self._headingLevels() - for i in range(minLevel, maxLevel + 1): - prevDesc = cmdnames.HEADING_AT_LEVEL_PREV % i - prevAtLevelBindings.append([str(i), - keybindings.SHIFT_MODIFIER_MASK, - prevDesc]) - - nextDesc = cmdnames.HEADING_AT_LEVEL_NEXT % i - nextAtLevelBindings.append([str(i), - keybindings.NO_MODIFIER_MASK, - nextDesc]) - - listDesc = cmdnames.HEADING_AT_LEVEL_LIST %i - listAtLevelBindings.append([str(i), - keybindings.SHIFT_ALT_MODIFIER_MASK, - listDesc]) - - bindings["previousAtLevel"] = prevAtLevelBindings - bindings["nextAtLevel"] = nextAtLevelBindings - bindings["listAtLevel"] = listAtLevelBindings - - return bindings - - def _headingLevels(self): - return [1, 6] - - def _headingGetter(self, document, arg=None): - if arg is not None: - return AXUtilities.find_all_headings_at_level(document, level=arg) - return AXUtilities.find_all_headings(document) - - def _headingPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - elif arg is None: - full = messages.NO_MORE_HEADINGS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - else: - full = messages.NO_MORE_HEADINGS_AT_LEVEL % arg - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _headingDialogData(self, arg=None): - columnHeaders = [guilabels.SN_HEADER_HEADING] - - if not arg: - title = guilabels.SN_TITLE_HEADING - columnHeaders.append(guilabels.SN_HEADER_LEVEL) - - def rowData(obj): - return [self._getText(obj), - str(self._script.utilities.headingLevel(obj))] - - else: - title = guilabels.SN_TITLE_HEADING_AT_LEVEL % arg - - def rowData(obj): - return [self._getText(obj)] - - return title, columnHeaders, rowData - - ######################## - # # - # Iframes # - # # - ######################## - - def _iframeBindings(self): - bindings = {} - prevDesc = cmdnames.IFRAME_PREV - bindings["previous"] = ["", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.IFRAME_NEXT - bindings["next"] = ["", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.IFRAME_LIST - bindings["list"] = ["", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _iframeGetter(self, document, arg=None): - return AXUtilities.find_all_internal_frames(document) - - def _iframePresentation(self, obj, arg=None): - if obj is not None: - [newObj, characterOffset] = self._getCaretPosition(obj) - self._setCaretPosition(newObj, characterOffset) - self._presentObject(obj, 0) - else: - full = messages.NO_MORE_IFRAMES - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _iframeDialogData(self): - columnHeaders = [guilabels.SN_HEADER_IFRAME] - - def rowData(obj): - name = AXObject.get_name(obj) - if not name and AXObject.get_child_count(obj): - name = AXObject.get_name(AXObject.get_child(obj, 0)) - return [name or self._getRoleName(obj)] - - return guilabels.SN_TITLE_IFRAME, columnHeaders, rowData - - ######################## - # # - # Images # - # # - ######################## - - def _imageBindings(self): - bindings = {} - prevDesc = cmdnames.IMAGE_PREV - bindings["previous"] = ["g", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.IMAGE_NEXT - bindings["next"] = ["g", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.IMAGE_LIST - bindings["list"] = ["g", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _imageGetter(self, document, arg=None): - return AXUtilities.find_all_images_and_image_maps(document) - - def _imagePresentation(self, obj, arg=None): - if obj is not None: - [newObj, characterOffset] = self._getCaretPosition(obj) - self._setCaretPosition(newObj, characterOffset) - self._presentObject(obj, 0) - else: - full = messages.NO_MORE_IMAGES - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _imageDialogData(self): - columnHeaders = [guilabels.SN_HEADER_IMAGE] - - def rowData(obj): - return [self._getText(obj) or self._getRoleName(obj)] - - return guilabels.SN_TITLE_IMAGE, columnHeaders, rowData - - ######################## - # # - # Landmarks # - # # - ######################## - - def _landmarkBindings(self): - bindings = {} - prevDesc = cmdnames.LANDMARK_PREV - bindings["previous"] = ["m", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.LANDMARK_NEXT - bindings["next"] = ["m", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.LANDMARK_LIST - bindings["list"] = ["m", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _landmarkGetter(self, document, arg=None): - return AXUtilities.find_all_landmarks(document) - - def _landmarkPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._script.presentMessage(AXObject.get_name(obj)) - self._presentLine(obj, characterOffset) - else: - full = messages.NO_LANDMARK_FOUND - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _landmarkDialogData(self): - columnHeaders = [guilabels.SN_HEADER_LANDMARK] - columnHeaders.append(guilabels.SN_HEADER_ROLE) - - def rowData(obj): - return [AXObject.get_name(obj), self._getRoleName(obj)] - - return guilabels.SN_TITLE_LANDMARK, columnHeaders, rowData - - ######################## - # # - # Lists # - # # - ######################## - - def _listBindings(self): - bindings = {} - prevDesc = cmdnames.LIST_PREV - bindings["previous"] = ["l", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.LIST_NEXT - bindings["next"] = ["l", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.LIST_LIST - bindings["list"] = ["l", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _listGetter(self, document, arg=None): - return AXUtilities.find_all_lists(document) - - def _listPresentation(self, obj, arg=None): - if obj is not None: - self._script.speakMessage(self._getListDescription(obj)) - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentLine(obj, characterOffset) - else: - full = messages.NO_MORE_LISTS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _listDialogData(self): - columnHeaders = [guilabels.SN_HEADER_LIST] - - def rowData(obj): - return [self._getText(obj)] - - return guilabels.SN_TITLE_LIST, columnHeaders, rowData - - ######################## - # # - # List Items # - # # - ######################## - - def _listItemBindings(self): - bindings = {} - prevDesc = cmdnames.LIST_ITEM_PREV - bindings["previous"] = ["i", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.LIST_ITEM_NEXT - bindings["next"] = ["i", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.LIST_ITEM_LIST - bindings["list"] = ["i", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _listItemGetter(self, document, arg=None): - return AXUtilities.find_all_list_items(document) - - def _listItemPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentLine(obj, characterOffset) - else: - full = messages.NO_MORE_LIST_ITEMS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _listItemDialogData(self): - columnHeaders = [guilabels.SN_HEADER_LIST_ITEM] - - def rowData(obj): - return [self._getText(obj)] - - return guilabels.SN_TITLE_LIST_ITEM, columnHeaders, rowData - - ######################## - # # - # Live Regions # - # # - ######################## - - def _liveRegionBindings(self): - bindings = {} - prevDesc = cmdnames.LIVE_REGION_PREV - bindings["previous"] = ["d", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.LIVE_REGION_NEXT - bindings["next"] = ["d", keybindings.NO_MODIFIER_MASK, nextDesc] - - desc = cmdnames.LIVE_REGION_LAST - bindings["last"] = ["y", keybindings.NO_MODIFIER_MASK, desc] - return bindings - - def _liveRegionGetter(self, document, arg=None): - return AXUtilities.find_all_live_regions(document) - - def _liveRegionPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_LIVE_REGIONS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - ######################## - # # - # Paragraphs # - # # - ######################## - - def _paragraphBindings(self): - bindings = {} - prevDesc = cmdnames.PARAGRAPH_PREV - bindings["previous"] = ["p", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.PARAGRAPH_NEXT - bindings["next"] = ["p", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.PARAGRAPH_LIST - bindings["list"] = ["p", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _paragraphGetter(self, document, arg=None): - def has_at_least_three_characters(obj): - if AXUtilities.is_heading(obj): - return True - - if not AXObject.supports_text(obj): - return False - - # We're choosing 3 characters as the minimum because some - # paragraphs contain a single image or link and a text - # of length 2: An embedded object character and a space. - # We want to skip these. - return AXText.get_character_count(obj) > 2 - - return AXUtilities.find_all_paragraphs(document, True, has_at_least_three_characters) - - def _paragraphPresentation(self, obj, arg=None): - if obj is not None: - [newObj, characterOffset] = self._getCaretPosition(obj) - self._setCaretPosition(newObj, characterOffset) - self._presentObject(obj, 0) - else: - full = messages.NO_MORE_PARAGRAPHS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _paragraphDialogData(self): - columnHeaders = [guilabels.SN_HEADER_PARAGRAPH] - - def rowData(obj): - return [self._getText(obj)] - - return guilabels.SN_TITLE_PARAGRAPH, columnHeaders, rowData - - ######################## - # # - # Radio Buttons # - # # - ######################## - - def _radioButtonBindings(self): - bindings = {} - prevDesc = cmdnames.RADIO_BUTTON_PREV - bindings["previous"] = ["r", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.RADIO_BUTTON_NEXT - bindings["next"] = ["r", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.RADIO_BUTTON_LIST - bindings["list"] = ["r", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _radioButtonGetter(self, document, arg=None): - return AXUtilities.find_all_radio_buttons(document) - - def _radioButtonPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_RADIO_BUTTONS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _radioButtonDialogData(self): - columnHeaders = [guilabels.SN_HEADER_RADIO_BUTTON] - columnHeaders.append(guilabels.SN_HEADER_STATE) - - def rowData(obj): - return [self._getLabel(obj), self._getState(obj)] - - return guilabels.SN_TITLE_RADIO_BUTTON, columnHeaders, rowData - - ######################## - # # - # Separators # - # # - ######################## - - def _separatorBindings(self): - bindings = {} - prevDesc = cmdnames.SEPARATOR_PREV - bindings["previous"] = ["s", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.SEPARATOR_NEXT - bindings["next"] = ["s", keybindings.NO_MODIFIER_MASK, nextDesc] - return bindings - - def _separatorGetter(self, document, arg=None): - return AXUtilities.find_all_separators(document) - - def _separatorPresentation(self, obj, arg=None): - if obj is not None: - [newObj, characterOffset] = self._getCaretPosition(obj) - self._setCaretPosition(newObj, characterOffset) - self._presentObject(obj, 0) - else: - full = messages.NO_MORE_SEPARATORS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - ######################## - # # - # Tables # - # # - ######################## - - def _tableBindings(self): - bindings = {} - prevDesc = cmdnames.TABLE_PREV - bindings["previous"] = ["t", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.TABLE_NEXT - bindings["next"] = ["t", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.TABLE_LIST - bindings["list"] = ["t", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _tableGetter(self, document, arg=None): - def is_not_layout_or_empty(obj): - if not AXObject.get_child_count(obj): - return False - - # This should no longer be needed once Atspi 2.8.4 is released. - attrs = self._script.utilities.objectAttributes(obj) - if attrs.get('layout-guess') == 'true': - return False - - if not AXObject.supports_table(obj): - return False - - return AXTable.get_row_count(obj, prefer_attribute=False) > 0 - - return AXUtilities.find_all_tables(document, is_not_layout_or_empty) - - def _tablePresentation(self, obj, arg=None): - if obj is not None: - caption = self._getTableCaption(obj) - if caption: - self._script.presentMessage(caption) - self._script.presentMessage(self._getTableDescription(obj)) - cell = AXTable.get_cell_at(obj, 0, 0) - if not cell: - tokens = ["STRUCTURAL NAVIGATION: Broken table interface for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - cell = AXObject.find_descendant(obj, AXUtilities.is_table_cell) - if cell: - tokens = ["STRUCTURAL NAVIGATION: Located", cell, "for first cell"] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - self.lastTableCell = [0, 0] - self._presentObject(cell, 0, priorObj=obj) - [cell, characterOffset] = self._getCaretPosition(cell) - self._setCaretPosition(cell, characterOffset) - else: - full = messages.NO_MORE_TABLES - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _tableDialogData(self): - columnHeaders = [guilabels.SN_HEADER_CAPTION] - columnHeaders.append(guilabels.SN_HEADER_DESCRIPTION) - - def rowData(obj): - return [self._getTableCaption(obj) or '', - self._getTableDescription(obj)] - - return guilabels.SN_TITLE_TABLE, columnHeaders, rowData - - ######################## - # # - # Table Cells # - # # - ######################## - - def _tableCellBindings(self): - bindings = {} - desc = cmdnames.TABLE_CELL_LEFT - bindings["left"] = ["Left", keybindings.SHIFT_ALT_MODIFIER_MASK, desc] - - desc = cmdnames.TABLE_CELL_RIGHT - bindings["right"] = ["Right", keybindings.SHIFT_ALT_MODIFIER_MASK, desc] - - desc = cmdnames.TABLE_CELL_UP - bindings["up"] = ["Up", keybindings.SHIFT_ALT_MODIFIER_MASK, desc] - - desc = cmdnames.TABLE_CELL_DOWN - bindings["down"] = ["Down", keybindings.SHIFT_ALT_MODIFIER_MASK, desc] - - desc = cmdnames.TABLE_CELL_FIRST - bindings["first"] = ["Home", keybindings.SHIFT_ALT_MODIFIER_MASK, desc] - - desc = cmdnames.TABLE_CELL_LAST - bindings["last"] = ["End", keybindings.SHIFT_ALT_MODIFIER_MASK, desc] - return bindings - - def _tableCellGetter(self, document, arg=None): - # TODO - JD: It would be more performant to set the root to the table. - # Actually, this doesn't seem to be getting used. Either use it or delete it. - return AXUtilities.find_all_table_cells_and_headers(document) - - def _tableCellPresentation(self, cell, arg): - if cell is None: - return - - if settings.speakCellHeaders: - self._presentCellHeaders(cell, arg) - - [obj, characterOffset] = self._getCaretPosition(cell) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._script.updateBraille(obj) - - blank = self._isBlankCell(cell) - if not blank: - self._presentObject(cell, 0) - else: - self._script.speakMessage(messages.BLANK) - - if settings.speakCellCoordinates: - [row, col] = self.getCellCoordinates(cell) - self._script.presentMessage( - messages.TABLE_CELL_COORDINATES % {"row": row + 1, "column": col + 1} - ) - - rowspan, colspan = self._script.utilities.rowAndColumnSpan(cell) - spanString = messages.cellSpan(rowspan, colspan) - if spanString and settings.speakCellSpan: - self._script.presentMessage(spanString) - - ######################## - # # - # Unvisited Links # - # # - ######################## - - def _unvisitedLinkBindings(self): - bindings = {} - prevDesc = cmdnames.UNVISITED_LINK_PREV - bindings["previous"] = ["u", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.UNVISITED_LINK_NEXT - bindings["next"] = ["u", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.UNVISITED_LINK_LIST - bindings["list"] = ["u", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - - return bindings - - def _unvisitedLinkGetter(self, document, arg=None): - return AXUtilities.find_all_unvisited_links(document) - - def _unvisitedLinkPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_UNVISITED_LINKS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _unvisitedLinkDialogData(self): - columnHeaders = [guilabels.SN_HEADER_LINK] - columnHeaders.append(guilabels.SN_HEADER_URI) - - def rowData(obj): - return [self._getText(obj), self._script.utilities.uri(obj)] - - return guilabels.SN_TITLE_UNVISITED_LINK, columnHeaders, rowData - - ######################## - # # - # Visited Links # - # # - ######################## - - def _visitedLinkBindings(self): - bindings = {} - prevDesc = cmdnames.VISITED_LINK_PREV - bindings["previous"] = ["v", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.VISITED_LINK_NEXT - bindings["next"] = ["v", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.VISITED_LINK_LIST - bindings["list"] = ["v", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - - return bindings - - def _visitedLinkGetter(self, document, arg=None): - return AXUtilities.find_all_visited_links(document) - - def _visitedLinkPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_VISITED_LINKS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _visitedLinkDialogData(self): - columnHeaders = [guilabels.SN_HEADER_LINK] - columnHeaders.append(guilabels.SN_HEADER_URI) - - def rowData(obj): - return [self._getText(obj), self._script.utilities.uri(obj)] - - return guilabels.SN_TITLE_VISITED_LINK, columnHeaders, rowData - - ######################## - # # - # Plain ol' Links # - # # - ######################## - - def _linkBindings(self): - bindings = {} - prevDesc = cmdnames.LINK_PREV - bindings["previous"] = ["k", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.LINK_NEXT - bindings["next"] = ["k", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.LINK_LIST - bindings["list"] = ["k", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _linkGetter(self, document, arg=None): - return AXUtilities.find_all_links(document) - - def _linkPresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - else: - full = messages.NO_MORE_LINKS - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _linkDialogData(self): - columnHeaders = [guilabels.SN_HEADER_LINK] - columnHeaders.append(guilabels.SN_HEADER_STATE) - columnHeaders.append(guilabels.SN_HEADER_URI) - - def rowData(obj): - return [self._getText(obj), - self._getState(obj), - self._script.utilities.uri(obj)] - - return guilabels.SN_TITLE_LINK, columnHeaders, rowData - - ######################## - # # - # Clickables # - # # - ######################## - - def _clickableBindings(self): - bindings = {} - prevDesc = cmdnames.CLICKABLE_PREV - bindings["previous"] = ["a", keybindings.SHIFT_MODIFIER_MASK, prevDesc] - - nextDesc = cmdnames.CLICKABLE_NEXT - bindings["next"] = ["a", keybindings.NO_MODIFIER_MASK, nextDesc] - - listDesc = cmdnames.CLICKABLE_LIST - bindings["list"] = ["a", keybindings.SHIFT_ALT_MODIFIER_MASK, listDesc] - return bindings - - def _clickableCriteria(self, arg=None): - return AXCollection.create_match_rule( - interfaces=["action"], - interface_match_type=Atspi.CollectionMatchType.ANY) - - def _clickablePredicate(self, obj, arg=None): - return self._script.utilities.isClickableElement(obj) - - def _clickablePresentation(self, obj, arg=None): - if obj is not None: - [obj, characterOffset] = self._getCaretPosition(obj) - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentObject(obj, characterOffset) - elif not arg: - full = messages.NO_MORE_CLICKABLES - brief = messages.STRUCTURAL_NAVIGATION_NOT_FOUND - self._script.presentMessage(full, brief) - - def _clickableDialogData(self): - columnHeaders = [guilabels.SN_HEADER_CLICKABLE] - columnHeaders.append(guilabels.SN_HEADER_ROLE) - - def rowData(obj): - return [self._getText(obj), self._getRoleName(obj)] - - return guilabels.SN_TITLE_CLICKABLE, columnHeaders, rowData - - ######################## - # # - # Containers # - # # - ######################## - - def _containerBindings(self): - bindings = {} - desc = cmdnames.CONTAINER_START - bindings["start"] = ["comma", keybindings.SHIFT_MODIFIER_MASK, desc] - - desc = cmdnames.CONTAINER_END - bindings["end"] = ["comma", keybindings.NO_MODIFIER_MASK, desc] - - return bindings - - def _containerCriteria(self, arg=None): - return AXCollection.create_match_rule(roles=self.CONTAINER_ROLES) - - def _containerPredicate(self, obj, arg=None): - return self._isContainer(obj) - - def _containerPresentation(self, obj, arg=None, **kwargs): - if obj is None: - self._script.presentMessage(messages.CONTAINER_NOT_IN_A) - return - - if kwargs.get("sameContainer"): - self._script.presentMessage(messages.CONTAINER_END) - - characterOffset = arg - if characterOffset is None: - obj, characterOffset = self._getCaretPosition(obj) - - obj, characterOffset = self._setCaretPosition(obj, characterOffset) - self._presentLine(obj, characterOffset) diff --git a/src/cthulhu/text_attribute_names.py b/src/cthulhu/text_attribute_names.py deleted file mode 100644 index 78ecfbe..0000000 --- a/src/cthulhu/text_attribute_names.py +++ /dev/null @@ -1,784 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Provides getTextAttributeName method that maps each text attribute -into its localized equivalent.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2008 Sun Microsystems Inc." -__license__ = "LGPL" - -from .cthulhu_i18n import C_ - -# Translators: this is a structure to assist in the generation of -# localized strings for the various text attributes. -# -# Information can be found in the Atk documentation at: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -# The at-spi IDL documentation for Accessibility_Text.idl also provides -# the following information: -# -# Attributes relevant to localization should be provided in accordance -# with the w3c "Internationalization and Localization Markup Requirements", -# http://www.w3.org/TR/2005/WD-itsreq-20051122/ -# -# Other text attributes should choose their names and value semantics in -# accordance with relevant standards such as: -# CSS level 2 (http://www.w3.org/TR/1998/REC-CSS2-19980512), -# XHTML 1.0 (http://www.w3.org/TR/2002/REC-xhtml1-20020801), and -# WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/). -# -# Where possible, specific URL references will also be given below for -# each text attribute. -# - -_textAttributeTable = {} - -# Translators: this attribute specifies the background color of the text. -# The value is an RGB value of the format "u,u,u". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["bg-color"] = C_("textattr", "background color") - -# Translators: this attribute specifies whether to make the background -# color for each character the height of the highest font used on the -# current line, or the height of the font used for the current character. -# It will be a "true" or "false" value. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["bg-full-height"] = C_("textattr", "background full height") - -# Translators: this attribute specifies whether a GdkBitmap is set for -# stippling the background color. It will be a "true" or "false" value. -# See -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["bg-stipple"] = C_("textattr", "background stipple") - -# Translators: this attribute specifies the direction of the text. -# Values are "none", "ltr" or "rtl". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["direction"] = C_("textattr", "direction") - -# Translators: this attribute specifies whether the text is editable. -# It will be a "true" or "false" value. -# See -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["editable"] = C_("textattr", "editable") - -# Translators: this attribute specifies the font family name of the text. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["family-name"] = C_("textattr", "family name") - -# Translators: this attribute specifies the foreground color of the text. -# The value is an RGB value of the format "u,u,u". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["fg-color"] = C_("textattr", "foreground color") - -# Translators: this attribute specifies whether a GdkBitmap is set for -# stippling the foreground color. It will be a "true" or "false" value. -# See -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["fg-stipple"] = C_("textattr", "foreground stipple") - -# Translators: this attribute specifies the effect applied to the font -# used by the text. -# See: -# http://www.w3.org/TR/2002/WD-css3-fonts-20020802/#font-effect -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["font-effect"] = C_("textattr", "font effect") - -# Translators: this attribute specifies the indentation of the text -# (in pixels). -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["indent"] = C_("textattr", "indent") - -# Translators: this attribute specifies there is something "wrong" with -# the text, such as it being a misspelled word. See: -# https://developer.mozilla.org/en/Accessibility/AT-APIs/Gecko/TextAttrs -# -_textAttributeTable["invalid"] = C_("textattr", "mistake") -# Translators: this attribute specifies there is something "wrong" with -# the text, such as it being a misspelled word. See: -# https://developer.mozilla.org/en/Accessibility/AT-APIs/Gecko/TextAttrs -# - -# Translators: this attribute specifies whether the text is invisible. -# It will be a "true" or "false" value. -# See -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["invisible"] = C_("textattr", "invisible") - -# Translators: this attribute specifies how the justification of the text. -# Values are "left", "right", "center" or "fill". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["justification"] = C_("textattr", "justification") - -# Translators: this attribute specifies the language that the text is -# written in. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["language"] = C_("textattr", "language") - -# Translators: this attribute specifies the pixel width of the left margin. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["left-margin"] = C_("textattr", "left margin") - -# Translators: this attribute specifies the height of the line of text. -# See: -# http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-line-height -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["line-height"] = C_("textattr", "line height") - -# Translators: this attribute refers to the named style which is associated -# with the entire paragraph and which controls the default formatting -# (font, text size, alignment, etc.) of that paragraph. Examples of -# paragraph styles include "Heading 1", "Heading 2", "Caption", "Footnote", -# "Text Body", "Title", and "Subtitle". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["paragraph-style"] = C_("textattr", "paragraph style") - -# Translators: this attribute specifies the pixels of blank space to -# leave above each newline-terminated line. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["pixels-above-lines"] = C_("textattr", "pixels above lines") - -# Translators: this attribute specifies the pixels of blank space to -# leave below each newline-terminated line. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["pixels-below-lines"] = C_("textattr", "pixels below lines") - -# Translators: this attribute specifies the pixels of blank space to -# leave between wrapped lines inside the same newline-terminated line -# (paragraph). -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["pixels-inside-wrap"] = C_("textattr", "pixels inside wrap") - -# Translators: this attribute specifies the pixel width of the right margin. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["right-margin"] = C_("textattr", "right margin") - -# Translators: this attribute specifies the number of pixels that the -# text characters are risen above the baseline. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["rise"] = C_("textattr", "rise") - -# Translators: this attribute specifies the scale of the characters. The -# value is a string representation of a double. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["scale"] = C_("textattr", "scale") - -# Translators: this attribute specifies the size of the text. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["size"] = C_("textattr", "size") - -# Translators: this attribute specifies the stretch of he text, if set. -# Values are "ultra_condensed", "extra_condensed", "condensed", -# "semi_condensed", "normal", "semi_expanded", "expanded", -# "extra_expanded" or "ultra_expanded". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["stretch"] = C_("textattr", "stretch") - -# Translators: this attribute specifies whether the text is strike though -# (in other words, whether there is a line drawn through it). Values are -# "true" or "false". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["strikethrough"] = C_("textattr", "strike through") - -# Translators: this attribute specifies the slant style of the text, -# if set. Values are "normal", "oblique" or "italic". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["style"] = C_("textattr", "style") - -# Translators: this attribute specifies the decoration of the text. -# See: -# http://www.w3.org/TR/1998/REC-CSS2-19980512/text.html#propdef-text-decoration -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["text-decoration"] = C_("textattr", "text decoration") - -# Translators: this attribute specifies the angle at which the text is -# displayed (i.e. rotated from the norm) and is represented in degrees -# of rotation. -# See: -# http://www.w3.org/TR/2003/CR-css3-text-20030514/#glyph-orientation-horizontal -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["text-rotation"] = C_("textattr", "text rotation") - -# Translators: this attribute specifies the shadow effects applied to the text. -# See: -# http://www.w3.org/TR/1998/REC-CSS2-19980512/text.html#propdef-text-shadow -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["text-shadow"] = C_("textattr", "text shadow") - -# Translators: this attributes specifies whether the text is underlined. -# Values are "none", "single", "double" or "low". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["underline"] = C_("textattr", "underline") - -# Translators: this attribute specifies the capitalization variant of -# the text, if set. Values are "normal" or "small_caps". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["variant"] = C_("textattr", "variant") - -# Translators: this attributes specifies what vertical alignment property -# has been applied to the text. -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# -_textAttributeTable["vertical-align"] = C_("textattr", "vertical align") - -# Translators: this attribute specifies the weight of the text. -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# http://www.w3.org/TR/1998/REC-CSS2-19980512/fonts.html#propdef-font-weight -# -_textAttributeTable["weight"] = C_("textattr", "weight") - -# Translators: this attribute specifies the wrap mode of the text, if any. -# Values are "none", "char" or "word". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["wrap-mode"] = C_("textattr", "wrap mode") - -# Translators: this attribute specifies the way the text is written. -# Values are "lr-tb", "rl-tb", "tb-rl", "tb-lr", "bt-rl", "bt-lr", "lr", -# "rl" and "tb". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["writing-mode"] = C_("textattr", "writing mode") - - -# The following are the known values of some of these text attributes. -# These values were found in the Atk documentation at: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# No doubt there will be more, and as they are found, they can be added -# to this table so they can be translated. -# - -# Translators: this is one of the text attribute values for the following -# text attributes: "invisible", "editable", bg-full-height", "strikethrough", -# "bg-stipple" and "fg-stipple". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["true"] = C_("textattr", "true") - -# Translators: this is one of the text attribute values for the following -# text attributes: "invisible", "editable", bg-full-height", "strikethrough", -# "bg-stipple" and "fg-stipple". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["false"] = C_("textattr", "false") - -# Translators: this is one of the text attribute values for the following -# text attributes: "font-effect", "underline", "text-shadow", "wrap mode" -# and "direction". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["none"] = C_("textattr", "none") - -# Translators: this is one of the text attribute values for the following -# text attributes: "font-effect". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["engrave"] = C_("textattr", "engrave") - -# Translators: this is one of the text attribute values for the following -# text attributes: "font-effect". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["emboss"] = C_("textattr", "emboss") - -# Translators: this is one of the text attribute values for the following -# text attributes: "font-effect". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["outline"] = C_("textattr", "outline") - -# Translators: this is one of the text attribute values for the following -# text attributes: "text-decoration". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["overline"] = C_("textattr", "overline") - -# Translators: this is one of the text attribute values for the following -# text attributes: "text-decoration". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["line-through"] = C_("textattr", "line through") - -# Translators: this is one of the text attribute values for the following -# text attributes: "text-decoration". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["blink"] = C_("textattr", "blink") - -# Translators: this is one of the text attribute values for the following -# text attributes: "text-shadow". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["black"] = C_("textattr", "black") - -# Translators: this is one of the text attribute values for the following -# text attributes: "underline". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["single"] = C_("textattr", "single") - -# Translators: this is one of the text attribute values for the following -# text attributes: "underline". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["double"] = C_("textattr", "double") - -# Translators: this is one of the text attribute values for the following -# text attributes: "underline". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["low"] = C_("textattr", "low") - -# Translators: this is one of the text attribute values for the following -# text attributes: "wrap mode". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["char"] = C_("textattr", "char") - -# Translators: this is one of the text attribute values for the following -# text attributes: "wrap mode". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["word"] = C_("textattr", "word") - -# Translators: this is one of the text attribute values for the following -# text attributes: "wrap mode." It corresponds to GTK_WRAP_WORD_CHAR, -# defined in the Gtk documentation as "Wrap text, breaking lines in -# between words, or if that is not enough, also between graphemes." -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# http://library.gnome.org/devel/gtk/stable/GtkTextTag.html#GtkWrapMode -# -_textAttributeTable["word_char"] = C_("textattr", "word char") - -# Translators: this is one of the text attribute values for the following -# text attributes: "direction". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["ltr"] = C_("textattr", "ltr") - -# Translators: this is one of the text attribute values for the following -# text attributes: "direction". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["rtl"] = C_("textattr", "rtl") - -# Translators: this is one of the text attribute values for the following -# text attributes: "justification". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["left"] = C_("textattr", "left") - -# Translators: this is one of the text attribute values for the following -# text attributes: "justification". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["right"] = C_("textattr", "right") - -# Translators: this is one of the text attribute values for the following -# text attributes: "justification". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["center"] = C_("textattr", "center") - -# Translators: this is one of the text attribute values for the following -# text attributes: "justification". In Gecko, when no justification has -# be explicitly set, they report a justification of "start". -# -_textAttributeTable["start"] = C_("textattr", "no justification") - -# Translators: this is one of the text attribute values for the following -# text attributes: "justification". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["fill"] = C_("textattr", "fill") - -# Translators: this is one of the text attribute values for the following -# text attributes: "stretch". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["ultra_condensed"] = C_("textattr", "ultra condensed") - -# Translators: this is one of the text attribute values for the following -# text attributes: "stretch". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["extra_condensed"] = C_("textattr", "extra condensed") - -# Translators: this is one of the text attribute values for the following -# text attributes: "stretch". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["condensed"] = C_("textattr", "condensed") - -# Translators: this is one of the text attribute values for the following -# text attributes: "stretch". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["semi_condensed"] = C_("textattr", "semi condensed") - -# Translators: this is one of the text attribute values for the following -# text attributes: "stretch" and "variant". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["normal"] = C_("textattr", "normal") - -# Translators: this is one of the text attribute values for the following -# text attributes: "stretch". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["semi_expanded"] = C_("textattr", "semi expanded") - -# Translators: this is one of the text attribute values for the following -# text attributes: "stretch". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["expanded"] = C_("textattr", "expanded") - -# Translators: this is one of the text attribute values for the following -# text attributes: "stretch". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["extra_expanded"] = C_("textattr", "extra expanded") - -# Translators: this is one of the text attribute values for the following -# text attributes: "stretch". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["ultra_expanded"] = C_("textattr", "ultra expanded") - -# Translators: this is one of the text attribute values for the following -# text attributes: "variant". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["small_caps"] = C_("textattr", "small caps") - -# Translators: this is one of the text attribute values for the following -# text attributes: "style". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["oblique"] = C_("textattr", "oblique") - -# Translators: this is one of the text attribute values for the following -# text attributes: "style". -# See: -# http://developer.gnome.org/atk/stable/AtkText.html#AtkTextAttribute -# -_textAttributeTable["italic"] = C_("textattr", "italic") - -# Translators: this is one of the text attribute values for the following -# text attributes: "paragraph-style". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["Default"] = C_("textattr", "Default") - -# Translators: this is one of the text attribute values for the following -# text attributes: "paragraph-style". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["Text body"] = C_("textattr", "Text body") - -# Translators: this is one of the text attribute values for the following -# text attributes: "paragraph-style". -# See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["Heading"] = C_("textattr", "Heading") - -# Translators: this is one of the text attribute values for the following -# text attributes: "vertical-align". -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["baseline"] = C_("textattr", "baseline") - -# Translators: this is one of the text attribute values for the following -# text attributes: "vertical-align". -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# -_textAttributeTable["sub"] = C_("textattr", "sub") - -# Translators: this is one of the text attribute values for the following -# text attributes: "vertical-align". -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# -_textAttributeTable["super"] = C_("textattr", "super") - -# Translators: this is one of the text attribute values for the following -# text attributes: "vertical-align". -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# -_textAttributeTable["top"] = C_("textattr", "top") - -# Translators: this is one of the text attribute values for the following -# text attributes: "vertical-align". -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# -_textAttributeTable["text-top"] = C_("textattr", "text-top") - -# Translators: this is one of the text attribute values for the following -# text attributes: "vertical-align". -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# -_textAttributeTable["middle"] = C_("textattr", "middle") - -# Translators: this is one of the text attribute values for the following -# text attributes: "vertical-align". -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# -_textAttributeTable["bottom"] = C_("textattr", "bottom") - -# Translators: this is one of the text attribute values for the following -# text attributes: "vertical-align". -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# -_textAttributeTable["text-bottom"] = C_("textattr", "text-bottom") - -# Translators: this is one of the text attribute values for the following -# text attributes: "vertical-align" and "writing-mode". -# See: -#http://www.w3.org/TR/1998/REC-CSS2-19980512/visudet.html#propdef-vertical-align -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["inherit"] = C_("textattr", "inherit") - -# Translators: this is one of the text attribute values for the following -# text attributes: "writing-mode". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["lr-tb"] = C_("textattr", "lr-tb") - -# Translators: this is one of the text attribute values for the following -# text attributes: "writing-mode". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["rl-tb"] = C_("textattr", "rl-tb") - -# Translators: this is one of the text attribute values for the following -# text attributes: "writing-mode". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["tb-rl"] = C_("textattr", "tb-rl") - -# Translators: this is one of the text attribute values for the following -# text attributes: "writing-mode". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["tb-lr"] = C_("textattr", "tb-lr") - -# Translators: this is one of the text attribute values for the following -# text attributes: "writing-mode". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["bt-rl"] = C_("textattr", "bt-rl") - -# Translators: this is one of the text attribute values for the following -# text attributes: "writing-mode". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["bt-lr"] = C_("textattr", "bt-lr") - -# Translators: this is one of the text attribute values for the following -# text attributes: "writing-mode". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["lr"] = C_("textattr", "lr") - -# Translators: this is one of the text attribute values for the following -# text attributes: "writing-mode". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["rl"] = C_("textattr", "rl") - -# Translators: this is one of the text attribute values for the following -# text attributes: "writing-mode". -# See: -# http://www.w3.org/TR/2001/WD-css3-text-20010517/#PrimaryTextAdvanceDirection -# -_textAttributeTable["tb"] = C_("textattr", "tb") - -# Translators: this is one of the text attribute values for the following -# text attributes: "strikethrough." It refers to the line style. -# -_textAttributeTable["solid"] = C_("textattr", "solid") - -# Translators: this is one of the text attribute values for the following -# text attributes: "invalid". It is an indication that the text is not -# spelled correctly. See: -# https://developer.mozilla.org/en/Accessibility/AT-APIs/Gecko/TextAttrs -# -_textAttributeTable["spelling"] = C_("textattr", "spelling") - -# Translators: This is the text-spelling attribute. See: -# http://wiki.services.openoffice.org/wiki/Accessibility/TextAttributes -# -_textAttributeTable["text-spelling"] = C_("textattr", "spelling") - -def getTextAttributeKey(localizedTextAttr): - """Given a localized text attribute, return the original text - attribute, (i.e. the key value). - - Arguments: - - localizedTextAttr: the localized text attribute. - - Returns a string representing the original text attribute key for the - localized text attribute. - """ - - for key, value in _textAttributeTable.items(): - if value == localizedTextAttr: - return key - - return localizedTextAttr - -def getTextAttributeName(textAttr, script=None): - """Given a text attribute, returns its localized equivalent. - - Arguments: - - textAttr: the text attribute to get the localized equivalent of. - - Returns a string representing the localized equivalent for the text - attribute. - """ - - # Normalize the name to an Atk name before attempting to look it up. - # - if script: - textAttr = script.utilities.getAtkNameForAttribute(textAttr) - - return _textAttributeTable.get(textAttr, textAttr) diff --git a/src/cthulhu/translation_context.py b/src/cthulhu/translation_context.py deleted file mode 100644 index 6e6fe9c..0000000 --- a/src/cthulhu/translation_context.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import gi, os, locale, gettext -from gi.repository import GObject -import gettext - -from cthulhu import cthulhu_i18n - -class TranslationContext(): - def __init__(self, app): - self.app = app - self.localeDir = cthulhu_i18n.localedir - self.domain = 'cthulhu' - self.language = 'en' - self.fallbackToCthulhuTranslation = True - self.domainTranslation = None - self.cthulhuMainTranslation = None - - def setDomain(self, domain): - self.domain = domain - def setLanguage(self, language): - self.language = language - def setLocaleDir(self, localeDir): - self.localeDir = localeDir - def getCurrentDefaultLocale(self): - return locale.getdefaultlocale()[0] - def setFallbackToCthulhuTranslation(self, fallback): - self.fallback = fallback - def getFallbackToCthulhuTranslation(self): - return self.fallback - def getLocaleDir(self): - return self.localeDir - def getLanguage(self): - return self.language - def getDomain(self): - return self.domain - def getDomainTranslation(self): - return self.domainTranslation - def getCthulhuMainTranslation(self): - return self.cthulhuMainTranslation - def setDomainTranslation(self, domainTranslation): - self.domainTranslation = domainTranslation - def setCthulhuMainTranslation(self, cthulhuMainTranslation): - self.cthulhuMainTranslation = cthulhuMainTranslation - def updateTranslation(self): - self.setDomainTranslation(None) - self.setCthulhuMainTranslation(None) - - try: - self.setLanguage(self.getCurrentDefaultLocale()) - except: - self.setLanguage('en') - print(e) - if self.getFallbackToCthulhuTranslation(): - cthulhuaMainTranslation = cthulhu_i18n - self.setCthulhuMainTranslation(cthulhuaMainTranslation) - try: - domainTranslation = gettext.translation(self.getDomain(), self.getLocaleDir(), languages=[self.getLanguage()]) - self.setDomainTranslation(domainTranslation) - except Exception as e: - print(e) - - def gettext(self, text): - translatedText = text - if self.getDomainTranslation() != None: - try: - translatedText = self.getDomainTranslation().gettext(text) - except Exception as e: - print(e) - if translatedText == text: - if self.getFallbackToCthulhuTranslation() or self.getDomainTranslation() == None: - if self.getCthulhuMainTranslation() != None: - try: - translatedText = self.getCthulhuMainTranslation().cgettext(text) # gettext from cthulhu_i18n - except Exception as e: - print(e) - return translatedText - - def ngettext(self, singular, plural, n): - translatedText = singular - if n > 1: - translatedText = plural - if self.getDomainTranslation() != None: - try: - translatedText = self.getDomainTranslation().ngettext(singular, plural, n) - except: - pass - if translatedText in [singular, plural]: # not translated - if self.getFallbackToCthulhuTranslation() or self.getDomainTranslation() == None: - if self.getCthulhuMainTranslation() != None: - try: - translatedText = self.getCthulhuMainTranslation().ngettext(singular, plural, n) - except: - pass - return translatedText diff --git a/src/cthulhu/translation_manager.py b/src/cthulhu/translation_manager.py deleted file mode 100644 index b5394ec..0000000 --- a/src/cthulhu/translation_manager.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -import gi, os, locale, gettext -from gi.repository import GObject -import gettext - -from cthulhu import cthulhu_i18n -from cthulhu import translation_context - -class TranslationManager(): - def __init__(self, app): - self.app = app - self.translatioContextnDict = {} - def initTranslation(self, name, domain = None, localeDir = None, language = None, fallbackToCthulhuTranslation = True): - translationContext = translation_context.TranslationContext(self.app) - if os.path.isdir(localeDir): - translationContext.setDomain(domain) - translationContext.setLocaleDir(localeDir) - translationContext.setLanguage(language) - translationContext.setFallbackToCthulhuTranslation(fallbackToCthulhuTranslation) - translationContext.updateTranslation() - self.addTranslationDict(name, translationContext) - return translationContext - def addTranslationDict(self, name, translationContext): - self.translatioContextnDict[name] = translationContext - def getTranslationContextByName(name): - try: - return self.translatioContextnDict[name] - except KeyError: - return self.translatioContextnDict['cthulhu'] - #def getTranslationsInstance(self, domain='cthulhu'): - """ Gets the gettext translation instance for this add-on. - \\locale will be used to find .mo files, if exists. - If a translation file is not found the default fallback null translation is returned. - @param domain: the translation domain to retrieve. The 'Cthulhu' default should be used in most cases. - @returns: the gettext translation class. - """ - # localedir = os.path.join(self.path, "locale") - # return gettext.translation(domain, localedir=localedir, languages=[languageHandler.getLanguage()], fallback=True) -""" - def initTranslation(): - addon = getCodeAddon(frameDist=2) - translations = addon.getTranslationsInstance() - # Point _ to the translation object in the globals namespace of the caller frame - # FIXME: should we retrieve the caller module object explicitly? - try: - callerFrame = inspect.currentframe().f_back - callerFrame.f_globals['_'] = translations.gettext - # Install our pgettext function. - callerFrame.f_globals['pgettext'] = languageHandler.makePgettext(translations) - finally: - del callerFrame # Avoid reference problems with frames (per python docs) -""" - diff --git a/src/cthulhu/tutorialgenerator.py b/src/cthulhu/tutorialgenerator.py deleted file mode 100644 index 670ee71..0000000 --- a/src/cthulhu/tutorialgenerator.py +++ /dev/null @@ -1,797 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Utilities for obtaining tutorial utterances for objects. In general, -there probably should be a singleton instance of the TutorialGenerator -class. For those wishing to override the generators, however, -one can create a new instance and replace/extend the tutorial generators -as they see fit.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2008-2009 Sun Microsystems Inc." -__license__ = "LGPL" - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from . import debug -from . import cthulhu_state -from . import settings - -from .ax_object import AXObject -from .ax_table import AXTable -from .ax_utilities import AXUtilities -from .cthulhu_i18n import _ # for gettext support - -class TutorialGenerator: - """Takes accessible objects and produces a tutorial string to speak - for those objects. See the getTutorialString method, which is the - primary entry point. Subclasses can feel free to override/extend - the getTutorialGenerators instance field as they see fit.""" - - def __init__(self, script): - - # The script that created us. This allows us to ask the - # script for information if we need it. - # - self._script = script - # storing the last spoken message. - self.lastTutorial = "" - - self.lastRole = None - - # Set up a dictionary that maps role names to functions - # that generate tutorial strings for objects that implement that role. - # - self.tutorialGenerators = {} - self.tutorialGenerators[Atspi.Role.CHECK_BOX] = \ - self._getTutorialForCheckBox - self.tutorialGenerators[Atspi.Role.COMBO_BOX] = \ - self._getTutorialForComboBox - self.tutorialGenerators[Atspi.Role.FRAME] = \ - self._getTutorialForFrame - self.tutorialGenerators[Atspi.Role.ICON] = \ - self._getTutorialForIcon - self.tutorialGenerators[Atspi.Role.LAYERED_PANE] = \ - self._getTutorialForLayeredPane - self.tutorialGenerators[Atspi.Role.LIST] = \ - self._getTutorialForList - self.tutorialGenerators[Atspi.Role.LIST_ITEM] = \ - self._getTutorialForListItem - self.tutorialGenerators[Atspi.Role.PAGE_TAB] = \ - self._getTutorialForPageTab - self.tutorialGenerators[Atspi.Role.PARAGRAPH] = \ - self._getTutorialForText - self.tutorialGenerators[Atspi.Role.PASSWORD_TEXT] = \ - self._getTutorialForText - self.tutorialGenerators[Atspi.Role.ENTRY] = \ - self._getTutorialForText - self.tutorialGenerators[Atspi.Role.PUSH_BUTTON] = \ - self._getTutorialForPushButton - self.tutorialGenerators[Atspi.Role.SPIN_BUTTON] = \ - self._getTutorialForSpinButton - self.tutorialGenerators[Atspi.Role.TABLE_CELL] = \ - self._getTutorialForTableCellRow - self.tutorialGenerators[Atspi.Role.TEXT] = \ - self._getTutorialForText - self.tutorialGenerators[Atspi.Role.TOGGLE_BUTTON] = \ - self._getTutorialForCheckBox - self.tutorialGenerators[Atspi.Role.RADIO_BUTTON] = \ - self._getTutorialForRadioButton - self.tutorialGenerators[Atspi.Role.MENU] = \ - self._getTutorialForMenu - self.tutorialGenerators[Atspi.Role.CHECK_MENU_ITEM] = \ - self._getTutorialForCheckBox - self.tutorialGenerators[Atspi.Role.MENU_ITEM] = \ - self._getTutorialForMenuItem - self.tutorialGenerators[Atspi.Role.RADIO_MENU_ITEM] = \ - self._getTutorialForCheckBox - self.tutorialGenerators[Atspi.Role.SLIDER] = \ - self._getTutorialForSlider - - def _debugGenerator(self, generatorName, obj, alreadyFocused, utterances): - """Prints debug.LEVEL_FINER information regarding - the tutorial generator. - - Arguments: - - generatorName: the name of the generator - - obj: the object being presented - - alreadyFocused: False if object just received focus - - utterances: the generated text - """ - - debug.println(debug.LEVEL_FINER, - f"GENERATOR: {generatorName}") - debug.println(debug.LEVEL_FINER, - f" obj = {AXObject.get_name(obj)}") - debug.println(debug.LEVEL_FINER, - f" role = {AXObject.get_role_name(obj)}") - debug.println(debug.LEVEL_FINER, - f" alreadyFocused = {alreadyFocused}") - debug.println(debug.LEVEL_FINER, - " utterances:") - for text in utterances: - debug.println(debug.LEVEL_FINER, - f" ({text})") - - def _getDefaultTutorial( - self, obj, alreadyFocused, forceTutorial, role=None): - """The default tutorial generator returns the empty tutorial string - because We have no associated tutorial function for the object. - - Arguments: - - obj: an Accessible - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - role: A role that should be used instead of the Accessible's - possible role. - - Returns the empty list [] - """ - - return [] - - - def _getTutorialForCheckBox(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a check box. - - Arguments: - - obj: the check box - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of tutorial utterances to be spoken for the object. - """ - - utterances = [] - # Translators: this is a tip for the user on how to toggle a checkbox. - msg = _("Press space to toggle.") - - if (not alreadyFocused and self.lastTutorial != [msg]) \ - or forceTutorial: - utterances.append(msg) - - self._debugGenerator("_getTutorialForCheckBox", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForComboBox(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a combobox. - - Arguments: - - obj: the combo box - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of tutorial utterances to be spoken for the object. - """ - - utterances = [] - # Translators: this is a tip for the user on how to interact - # with a combobox. - msg = _("Press space to expand, and use up and down to select an item.") - - if (not alreadyFocused and self.lastTutorial != [msg]) \ - or forceTutorial: - utterances.append(msg) - - self._debugGenerator("_getTutorialForComboBox", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForFrame(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a frame. - - Arguments: - - obj: the frame - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of tutorial utterances to be spoken for the object. - """ - - utterances = [] - - # Translators: If this application has more than one unfocused alert or - # dialog window, inform user of how to refocus these. - childWindowsMsg = _("Press alt+f6 to give focus to child windows.") - - # If this application has more than one unfocused alert or - # dialog window, tell user how to give them focus. - try: - alertAndDialogCount = \ - self._script.utilities.unfocusedAlertAndDialogCount(obj) - except Exception: - alertAndDialogCount = 0 - if alertAndDialogCount > 0: - utterances.append(childWindowsMsg) - - self._debugGenerator("_getTutorialForFrame", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForIcon(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for an icon. - - Arguments: - - obj: the icon - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of tutorial utterances to be spoken for the object. - """ - - parent = AXObject.get_parent(obj) - if AXUtilities.is_layered_pane(parent): - utterances = self._getTutorialForLayeredPane(parent, - alreadyFocused, - forceTutorial) - else: - utterances = self._getDefaultTutorial(obj, - alreadyFocused, - forceTutorial) - - self._debugGenerator("_getTutorialForIcon", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForLayeredPane(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a layered pane. - - Arguments: - - obj: the layered pane - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of tutorial utterances to be spoken for the object. - """ - - utterances = [] - - # Translators: this gives tips on how to navigate items in a - # layered pane. - msg = _("To move to items, use either " \ - "the arrow keys or type ahead searching.") - utterances.append(msg) - - # Translators: this is the tutorial string for when first landing - # on the desktop, describing how to access the system menus. - desktopMsg = _("To get to the system menus press the alt+f1 key.") - - scriptName = self._script.name - sibling = AXObject.get_child(AXObject.get_parent(obj), 0) - if 'nautilus' in scriptName and obj == sibling: - utterances.append(desktopMsg) - - if (not alreadyFocused and self.lastTutorial != utterances) \ - or forceTutorial: - pass - else: - utterances = [] - - self._debugGenerator("_getTutorialForLayeredPane", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForList(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a list. - - Arguments: - - obj: the list - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of tutorial utterances to be spoken for the object. - """ - - utterances = [] - - # Translators: this is the tutorial string when navigating lists. - msg = _("Use up and down to select an item.") - - if (not alreadyFocused and self.lastTutorial != [msg]) \ - or forceTutorial: - utterances.append(msg) - - self._debugGenerator("_getTutorialForList", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForListItem(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a listItem. - - Arguments: - - obj: the listitem - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of tutorial utterances to be spoken for the object. - """ - - utterances = [] - - # Translators: this represents the state of a node in a tree. - # 'expanded' means the children are showing. - # 'collapsed' means the children are not showing. - # this string informs the user how to collapse the node. - expandedMsg = _("To collapse, press shift plus left.") - - # Translators: this represents the state of a node in a tree. - # 'expanded' means the children are showing. - # 'collapsed' means the children are not showing. - # this string informs the user how to expand the node. - collapsedMsg = _("To expand, press shift plus right.") - - - # If already in focus then the tree probably collapsed or expanded - if AXUtilities.is_expandable(obj): - if AXUtilities.is_expanded(obj): - if (self.lastTutorial != [expandedMsg]) or forceTutorial: - utterances.append(expandedMsg) - else: - if (self.lastTutorial != [collapsedMsg]) or forceTutorial: - utterances.append(collapsedMsg) - - self._debugGenerator("_getTutorialForListItem", - obj, - alreadyFocused, - utterances) - return utterances - - def _getTutorialForMenuItem(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a menu item - - Arguments: - - obj: the menu item - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of utterances to be spoken for the object. - """ - - utterances = [] - # Translators: this is the tutorial string for activating a menu item - msg = _("To activate press return.") - - if (not alreadyFocused and self.lastTutorial != [msg]) \ - or forceTutorial: - utterances.append(msg) - - self._debugGenerator("_getTutorialForMenuItem", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForText(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a text object. - - Arguments: - - obj: the text component - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of tutorial utterances to be spoken for the object. - """ - - if not AXUtilities.is_editable(obj): - return [] - - utterances = [] - # Translators: This is the tutorial string for when landing - # on text fields. - msg = _("Type in text.") - - if (not alreadyFocused or forceTutorial) and \ - not self._script.utilities.isReadOnlyTextArea(obj): - utterances.append(msg) - - self._debugGenerator("_getTutorialForText", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForPageTab(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a page tab. - - Arguments: - - obj: the page tab - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of tutorial utterances to be spoken for the object. - """ - - utterances = [] - # Translators: this is the tutorial string for landing - # on a page tab, we are informing the - # user how to navigate these. - msg = _("Use left and right to view other tabs.") - - if (self.lastTutorial != [msg]) or forceTutorial: - utterances.append(msg) - - self._debugGenerator("_getTutorialForPageTabList", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForPushButton(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a push button - - Arguments: - - obj: the push button - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of utterances to be spoken for the object. - """ - - utterances = [] - # Translators: this is the tutorial string for activating a push button. - msg = _("To activate press space.") - - if (not alreadyFocused and self.lastTutorial != [msg]) \ - or forceTutorial: - utterances.append(msg) - - self._debugGenerator("_getTutorialForPushButton", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForSpinButton(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a spin button. If the object already has - focus, then no tutorial is given. - - Arguments: - - obj: the spin button - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of utterances to be spoken for the object. - """ - - utterances = [] - # Translators: this is the tutorial string for when landing - # on a spin button. - msg = _("Use up or down arrow to select value." \ - " Or type in the desired numerical value.") - - if (not alreadyFocused and self.lastTutorial != [msg]) \ - or forceTutorial: - utterances.append(msg) - - self._debugGenerator("_getTutorialForSpinButton", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForTableCell(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial utterances for a single table cell - - Arguments: - - obj: the table - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of utterances to be spoken for the object. - """ - - utterances = [] - - # Translators: this represents the state of a node in a tree. - # 'expanded' means the children are showing. - # 'collapsed' means the children are not showing. - # this string informs the user how to collapse the node. - expandedMsg = _("To collapse, press shift plus left.") - - # Translators: this represents the state of a node in a tree. - # 'expanded' means the children are showing. - # 'collapsed' means the children are not showing. - # this string informs the user how to expand the node. - collapsedMsg = _("To expand, press shift plus right.") - - # If this table cell has 2 children and one of them has a - # 'toggle' action and the other does not, then present this - # as a checkbox where: - # 1) we get the checked state from the cell with the 'toggle' action - # 2) we get the label from the other cell. - # See Cthulhu bug #376015 for more details. - # - if AXObject.get_child_count(obj) == 2: - cellOrder = [] - hasToggle = [ False, False ] - for i, child in enumerate(obj): - if self._script.utilities.hasMeaningfulToggleAction(child): - hasToggle[i] = True - break - if hasToggle[0] and not hasToggle[1]: - cellOrder = [ 1, 0 ] - elif not hasToggle[0] and hasToggle[1]: - cellOrder = [ 0, 1 ] - if cellOrder: - for i in cellOrder: - # Don't speak the label if just the checkbox state has - # changed. - # - if alreadyFocused and not hasToggle[i]: - pass - else: - utterances.extend( \ - self._getTutorialForTableCell(AXObject.get_child(obj, i), - alreadyFocused, forceTutorial)) - return utterances - - # [[[TODO: WDW - Attempt to infer the cell type. There's a - # bunch of stuff we can do here, such as check the EXPANDABLE - # state, check the NODE_CHILD_OF relation, etc. Logged as - # bugzilla bug 319750.]]] - # - if self._script.utilities.hasMeaningfulToggleAction(obj): - utterances = self._getTutorialForCheckBox( - obj, alreadyFocused, forceTutorial) - - if AXUtilities.is_expandable(obj): - if AXUtilities.is_expanded(obj): - if self.lastTutorial != [expandedMsg] or forceTutorial: - utterances.append(expandedMsg) - else: - if self.lastTutorial != [collapsedMsg] or forceTutorial: - utterances.append(collapsedMsg) - - self._debugGenerator("_getTutorialForTableCell", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForTableCellRow(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for the active table cell in the table row. - - Arguments: - - obj: the table - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of utterances to be spoken for the object. - """ - - utterances = [] - - if (not alreadyFocused): - parent = AXObject.get_parent(obj) - parent_table = AXTable.get_table(parent) - readFullRow = self._script.utilities.shouldReadFullRow(obj) - if readFullRow and parent_table and not self._script.utilities.isLayoutOnly(parent): - utterances.extend(self._getTutorialForTableCell(obj, - alreadyFocused, forceTutorial)) - else: - utterances = self._getTutorialForTableCell(obj, alreadyFocused, forceTutorial) - else: - utterances = self._getTutorialForTableCell(obj, alreadyFocused, \ - forceTutorial) - - self._debugGenerator("_getTutorialForTableCellRow", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getTutorialForRadioButton(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a radio button. - - Arguments: - - obj: the radio button - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of utterances to be spoken for the object. - """ - - utterances = [] - # Translators: this is a tip for the user, how to navigate radiobuttons. - msg = _("Use arrow keys to change.") - - if (not alreadyFocused and self.lastTutorial != [msg]) \ - or forceTutorial: - utterances.append(msg) - - self._debugGenerator("_getTutorialForRadioButton", - obj, - alreadyFocused, - utterances) - return utterances - - def _getTutorialForMenu(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a menu. - - Arguments: - - obj: the menu - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of utterances to be spoken for the object. - """ - - utterances = [] - # Translators: this is a tip for the user, how to navigate menus. - mainMenuMsg = _("To navigate, press left or right arrow. " \ - "To move through items press up or down arrow.") - - # Translators: this is a tip for the user, how to - # navigate into sub menus. - subMenuMsg = _("To enter sub menu, press right arrow.") - - # Checking if we are a submenu, - # we can't rely on our parent being just a menu. - # TODO - JD: What exactly are the __class__ checks for? All accessible objects - # have the same class. Should this be checking the role instead? - parent = AXObject.get_parent(obj) - if AXObject.get_name(parent) and parent.__class__ == obj.__class__: - if (self.lastTutorial != [subMenuMsg]) or forceTutorial: - utterances.append(subMenuMsg) - else: - if (self.lastTutorial != [mainMenuMsg]) or forceTutorial: - utterances.append(mainMenuMsg) - - self._debugGenerator("_getTutorialForMenu", - obj, - alreadyFocused, - utterances) - return utterances - - def _getTutorialForSlider(self, obj, alreadyFocused, forceTutorial): - """Get the tutorial string for a slider. If the object already has - focus, then no tutorial is given. - - Arguments: - - obj: the slider - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - Returns a list of utterances to be spoken for the object. - """ - - utterances = [] - # Translators: this is the tutorial string for when landing - # on a slider. - msg = _("To decrease press left arrow, to increase press right arrow." \ - " To go to minimum press home, and for maximum press end.") - - if (not alreadyFocused and self.lastTutorial != [msg]) \ - or forceTutorial: - utterances.append(msg) - - self._debugGenerator("_getTutorialForSlider", - obj, - alreadyFocused, - utterances) - - return utterances - - def _getBindingsForHandler(self, handlerName): - handler = self._script.inputEventHandlers.get(handlerName) - if not handler: - return None - - bindings = self._script.keyBindings.getBindingsForHandler(handler) - if not bindings: - return None - - binding = bindings[0] - return binding.asString() - - def _getModeTutorial(self, obj, alreadyFocused, forceTutorial): - return [] - - def getTutorial(self, obj, alreadyFocused, forceTutorial=False, role=None): - """Get the tutorial for an Accessible object. This will look - first to the specific tutorial generators and if this - does not exist then return the empty tutorial. - This method is the primary method - that external callers of this class should use. - - Arguments: - - obj: the object - - alreadyFocused: False if object just received focus - - forceTutorial: used for when whereAmI really needs the tutorial string - - role: Alternative role to use - - Returns a list of utterances to be spoken. - """ - - if not settings.enableTutorialMessages: - return [] - - if not (obj and obj == cthulhu_state.locusOfFocus): - return [] - - # Widgets in document content don't necessarily have the same interaction - # as native toolkits. Because we can't know for certain what a keystroke - # will do, better to say nothing than to risk confusing the user with - # bogus info. - if self._script.utilities.inDocumentContent(obj): - tokens = ["INFO: Not generating tutorial for document object", obj, "."] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return [] - - utterances = [] - role = role or AXObject.get_role(obj) - msg = self._getModeTutorial(obj, alreadyFocused, forceTutorial) - if not msg: - if role in self.tutorialGenerators: - generator = self.tutorialGenerators[role] - else: - generator = self._getDefaultTutorial - msg = generator(obj, alreadyFocused, forceTutorial) - if msg == self.lastTutorial and role == self.lastRole \ - and not forceTutorial: - msg = [] - if msg: - utterances = [" ".join(msg)] - self.lastTutorial = msg - self.lastRole = role - if forceTutorial: - self.lastTutorial = "" - self.lastRole = None - - self._debugGenerator("getTutorial", - obj, - alreadyFocused, - utterances) - return utterances diff --git a/src/cthulhu/typing_echo_presenter.py b/src/cthulhu/typing_echo_presenter.py deleted file mode 100644 index 4a19798..0000000 --- a/src/cthulhu/typing_echo_presenter.py +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/env python3 -# Cthulhu -# -# Copyright 2005-2008 Sun Microsystems Inc. -# Copyright 2011-2025 Igalia, S.L. -# Copyright 2025 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -"""Provides typing echo support with D-Bus controls.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2011-2025 Igalia, S.L." -__license__ = "LGPL" - -import string -from typing import TYPE_CHECKING - -from . import braille -from . import cmdnames -from . import dbus_service -from . import debug -from . import input_event -from . import keybindings -from . import messages -from . import settings -from . import settings_manager -from . import speech - -if TYPE_CHECKING: - from . import default - -_settings_manager = settings_manager.getManager() - -class TypingEchoPresenter: - """Provides typing echo functionality with D-Bus remote control support.""" - - def __init__(self): - """Initialize the typing echo presenter.""" - debug.printMessage(debug.LEVEL_INFO, "TYPING ECHO PRESENTER: Initializing", True) - - # D-Bus getters and setters for key echo settings - @dbus_service.getter - def get_key_echo_enabled(self) -> bool: - """Returns whether echo of key presses is enabled.""" - return _settings_manager.getSetting('enableKeyEcho') - - @dbus_service.setter - def set_key_echo_enabled(self, value: bool) -> bool: - """Sets whether echo of key presses is enabled.""" - try: - _settings_manager.setSetting('enableKeyEcho', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting key echo: {e}", True) - return False - - @dbus_service.getter - def get_character_echo_enabled(self) -> bool: - """Returns whether echo of inserted characters is enabled.""" - return _settings_manager.getSetting('enableEchoByCharacter') - - @dbus_service.setter - def set_character_echo_enabled(self, value: bool) -> bool: - """Sets whether echo of inserted characters is enabled.""" - try: - _settings_manager.setSetting('enableEchoByCharacter', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting character echo: {e}", True) - return False - - @dbus_service.getter - def get_word_echo_enabled(self) -> bool: - """Returns whether word echo is enabled.""" - return _settings_manager.getSetting('enableEchoByWord') - - @dbus_service.setter - def set_word_echo_enabled(self, value: bool) -> bool: - """Sets whether word echo is enabled.""" - try: - _settings_manager.setSetting('enableEchoByWord', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting word echo: {e}", True) - return False - - @dbus_service.getter - def get_sentence_echo_enabled(self) -> bool: - """Returns whether sentence echo is enabled.""" - return _settings_manager.getSetting('enableEchoBySentence') - - @dbus_service.setter - def set_sentence_echo_enabled(self, value: bool) -> bool: - """Sets whether sentence echo is enabled.""" - try: - _settings_manager.setSetting('enableEchoBySentence', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting sentence echo: {e}", True) - return False - - @dbus_service.getter - def get_alphabetic_keys_enabled(self) -> bool: - """Returns whether alphabetic keys will be echoed when key echo is enabled.""" - return _settings_manager.getSetting('enableAlphabeticKeys') - - @dbus_service.setter - def set_alphabetic_keys_enabled(self, value: bool) -> bool: - """Sets whether alphabetic keys will be echoed when key echo is enabled.""" - try: - _settings_manager.setSetting('enableAlphabeticKeys', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting alphabetic keys: {e}", True) - return False - - @dbus_service.getter - def get_numeric_keys_enabled(self) -> bool: - """Returns whether numeric keys will be echoed when key echo is enabled.""" - return _settings_manager.getSetting('enableNumericKeys') - - @dbus_service.setter - def set_numeric_keys_enabled(self, value: bool) -> bool: - """Sets whether numeric keys will be echoed when key echo is enabled.""" - try: - _settings_manager.setSetting('enableNumericKeys', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting numeric keys: {e}", True) - return False - - @dbus_service.getter - def get_punctuation_keys_enabled(self) -> bool: - """Returns whether punctuation keys will be echoed when key echo is enabled.""" - return _settings_manager.getSetting('enablePunctuationKeys') - - @dbus_service.setter - def set_punctuation_keys_enabled(self, value: bool) -> bool: - """Sets whether punctuation keys will be echoed when key echo is enabled.""" - try: - _settings_manager.setSetting('enablePunctuationKeys', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting punctuation keys: {e}", True) - return False - - @dbus_service.getter - def get_space_enabled(self) -> bool: - """Returns whether space key will be echoed when key echo is enabled.""" - return _settings_manager.getSetting('enableSpace') - - @dbus_service.setter - def set_space_enabled(self, value: bool) -> bool: - """Sets whether space key will be echoed when key echo is enabled.""" - try: - _settings_manager.setSetting('enableSpace', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting space key: {e}", True) - return False - - @dbus_service.getter - def get_modifier_keys_enabled(self) -> bool: - """Returns whether modifier keys will be echoed when key echo is enabled.""" - return _settings_manager.getSetting('enableModifierKeys') - - @dbus_service.setter - def set_modifier_keys_enabled(self, value: bool) -> bool: - """Sets whether modifier keys will be echoed when key echo is enabled.""" - try: - _settings_manager.setSetting('enableModifierKeys', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting modifier keys: {e}", True) - return False - - @dbus_service.getter - def get_function_keys_enabled(self) -> bool: - """Returns whether function keys will be echoed when key echo is enabled.""" - return _settings_manager.getSetting('enableFunctionKeys') - - @dbus_service.setter - def set_function_keys_enabled(self, value: bool) -> bool: - """Sets whether function keys will be echoed when key echo is enabled.""" - try: - _settings_manager.setSetting('enableFunctionKeys', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting function keys: {e}", True) - return False - - @dbus_service.getter - def get_action_keys_enabled(self) -> bool: - """Returns whether action keys will be echoed when key echo is enabled.""" - return _settings_manager.getSetting('enableActionKeys') - - @dbus_service.setter - def set_action_keys_enabled(self, value: bool) -> bool: - """Sets whether action keys will be echoed when key echo is enabled.""" - try: - _settings_manager.setSetting('enableActionKeys', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting action keys: {e}", True) - return False - - @dbus_service.getter - def get_navigation_keys_enabled(self) -> bool: - """Returns whether navigation keys will be echoed when key echo is enabled.""" - return _settings_manager.getSetting('enableNavigationKeys') - - @dbus_service.setter - def set_navigation_keys_enabled(self, value: bool) -> bool: - """Sets whether navigation keys will be echoed when key echo is enabled.""" - try: - _settings_manager.setSetting('enableNavigationKeys', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting navigation keys: {e}", True) - return False - - @dbus_service.getter - def get_diacritical_keys_enabled(self) -> bool: - """Returns whether diacritical keys will be echoed when key echo is enabled.""" - return _settings_manager.getSetting('enableDiacriticalKeys') - - @dbus_service.setter - def set_diacritical_keys_enabled(self, value: bool) -> bool: - """Sets whether diacritical keys will be echoed when key echo is enabled.""" - try: - _settings_manager.setSetting('enableDiacriticalKeys', value) - return True - except Exception as e: - debug.printMessage(debug.LEVEL_WARNING, f"Error setting diacritical keys: {e}", True) - return False - - @dbus_service.command - def cycle_key_echo(self, script: 'default.Script', event=None): - """Cycles through key echo modes.""" - if not _settings_manager.getSetting('enableKeyEcho'): - _settings_manager.setSetting('enableKeyEcho', True) - script.presentMessage(messages.KEY_ECHO_ENABLED) - else: - _settings_manager.setSetting('enableKeyEcho', False) - script.presentMessage(messages.KEY_ECHO_DISABLED) - return True - - def should_echo_keyboard_event(self, event: input_event.KeyboardEvent) -> bool: - """Returns whether the given keyboard event should be echoed.""" - if not _settings_manager.getSetting('enableKeyEcho'): - return False - - if event.event_string in ["shift", "control", "alt", "meta"]: - return _settings_manager.getSetting('enableModifierKeys') - - if event.event_string.startswith("f") and event.event_string[1:].isdigit(): - return _settings_manager.getSetting('enableFunctionKeys') - - if event.event_string in ["return", "enter", "tab", "escape", "backspace", "delete"]: - return _settings_manager.getSetting('enableActionKeys') - - if event.event_string in ["up", "down", "left", "right", "home", "end", "page_up", "page_down"]: - return _settings_manager.getSetting('enableNavigationKeys') - - if event.event_string == "space": - return _settings_manager.getSetting('enableSpace') - - if len(event.event_string) == 1: - char = event.event_string - if char.isalpha(): - return _settings_manager.getSetting('enableAlphabeticKeys') - elif char.isdigit(): - return _settings_manager.getSetting('enableNumericKeys') - elif char in string.punctuation: - return _settings_manager.getSetting('enablePunctuationKeys') - - return False - - def is_character_echoable(self, event: input_event.KeyboardEvent) -> bool: - """Returns True if the script will echo this event as part of character echo.""" - if not _settings_manager.getSetting('enableEchoByCharacter'): - return False - - # Character echo is for printable characters being inserted - if len(event.event_string) == 1 and event.event_string.isprintable(): - return True - - return False - - def echo_keyboard_event(self, script: 'default.Script', event: input_event.KeyboardEvent) -> None: - """Presents the KeyboardEvent event.""" - if self.should_echo_keyboard_event(event): - if event.event_string == "space": - script.presentMessage(messages.SPACE) - elif event.event_string == "tab": - script.presentMessage(messages.TAB) - elif event.event_string == "return" or event.event_string == "enter": - script.presentMessage(messages.ENTER) - elif event.event_string == "backspace": - script.presentMessage(messages.BACKSPACE) - elif event.event_string == "delete": - script.presentMessage(messages.DELETE) - else: - # For simple characters and other keys, just speak the event string - script.presentMessage(event.event_string) - -# Global instance -_manager = None - -def getManager(): - """Get the typing echo presenter manager.""" - global _manager - if not _manager: - _manager = TypingEchoPresenter() - return _manager \ No newline at end of file diff --git a/src/cthulhu/wayland_protocols/__init__.py b/src/cthulhu/wayland_protocols/__init__.py deleted file mode 100644 index 5083127..0000000 --- a/src/cthulhu/wayland_protocols/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Runtime-optional Wayland protocol compatibility wrappers.""" - -from . import ext_workspace_v1 - -__all__ = ["ext_workspace_v1"] diff --git a/src/cthulhu/wayland_protocols/ext_workspace_v1.py b/src/cthulhu/wayland_protocols/ext_workspace_v1.py deleted file mode 100644 index c3d2a46..0000000 --- a/src/cthulhu/wayland_protocols/ext_workspace_v1.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Local ext-workspace protocol wrapper built on top of base pywayland.""" - -from __future__ import annotations - -import importlib -from types import ModuleType -from typing import Any - -INTERFACE_NAME = "ext_workspace_manager_v1" -INTERFACE_VERSION = 1 -ACTIVE_STATE_VALUE = 1 -WORKSPACE_HANDLE_INTERFACE_NAME = "ext_workspace_handle_v1" - - -def _load_module(module_names: list[str]) -> ModuleType | None: - for moduleName in module_names: - try: - return importlib.import_module(moduleName) - except ImportError: - continue - return None - - -def _first_attribute(module: ModuleType | None, attribute_names: list[str]) -> Any: - if module is None: - return None - - for attributeName in attribute_names: - if hasattr(module, attributeName): - return getattr(module, attributeName) - return None - - -_pywaylandClientModule = _load_module( - [ - "pywayland.client", - "pywayland.client.display", - ] -) -Display = _first_attribute(_pywaylandClientModule, ["Display"]) - - -class _LocalProtocolProxy: - """Minimal local proxy descriptor with a dispatcher-compatible shape.""" - - interface_name = "" - version = 1 - event_names: tuple[str, ...] = () - - def __init__(self, *args: Any, **kwargs: Any) -> None: - try: - super().__init__(*args, **kwargs) - except Exception: - pass - self.dispatcher = getattr(self, "dispatcher", {}) or {} - - -class ExtWorkspaceManagerV1(_LocalProtocolProxy): - interface_name = INTERFACE_NAME - version = INTERFACE_VERSION - event_names = ("workspace", "done", "finished") - - -class ExtWorkspaceHandleV1(_LocalProtocolProxy): - interface_name = WORKSPACE_HANDLE_INTERFACE_NAME - version = INTERFACE_VERSION - event_names = ("name", "coordinates", "state", "removed") - - -def get_display_class() -> Any: - return Display - - -def has_runtime_support() -> bool: - return Display is not None - - -def bind_workspace_manager(registry: Any, global_name: int, version: int) -> Any: - bind = getattr(registry, "bind", None) - if not callable(bind): - return None - - for bindArgs in ( - (global_name, ExtWorkspaceManagerV1, version), - (global_name, version, ExtWorkspaceManagerV1), - (global_name, INTERFACE_NAME, version), - (global_name, version, INTERFACE_NAME), - ): - try: - proxy = bind(*bindArgs) - return _ensure_dispatcher(proxy) - except TypeError: - continue - - return None - - -def _ensure_dispatcher(proxy: Any) -> Any: - if proxy is None: - return None - - if getattr(proxy, "dispatcher", None) is None: - try: - proxy.dispatcher = {} - except Exception: - pass - return proxy - - -__all__ = [ - "ACTIVE_STATE_VALUE", - "Display", - "ExtWorkspaceHandleV1", - "ExtWorkspaceManagerV1", - "INTERFACE_NAME", - "INTERFACE_VERSION", - "WORKSPACE_HANDLE_INTERFACE_NAME", - "bind_workspace_manager", - "get_display_class", - "has_runtime_support", -] diff --git a/src/cthulhu/wayland_protocols/meson.build b/src/cthulhu/wayland_protocols/meson.build deleted file mode 100644 index 71f53e6..0000000 --- a/src/cthulhu/wayland_protocols/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -wayland_protocol_python_sources = files([ - '__init__.py', - 'ext_workspace_v1.py', -]) - -python3.install_sources( - wayland_protocol_python_sources, - subdir: 'cthulhu/wayland_protocols' -) diff --git a/src/cthulhu/where_am_i_presenter.py b/src/cthulhu/where_am_i_presenter.py deleted file mode 100644 index 6cfdaa8..0000000 --- a/src/cthulhu/where_am_i_presenter.py +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2024 Stormux -# Copyright (c) 2010-2012 The Orca Team -# Copyright (c) 2012 Igalia, S.L. -# Copyright (c) 2005-2010 Sun Microsystems Inc. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. -# -# Forked from Orca screen reader. -# Cthulhu project: https://git.stormux.org/storm/cthulhu - -"""Module for commands related to the current accessible object.""" - -__id__ = "$Id$" -__version__ = "$Revision$" -__date__ = "$Date$" -__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \ - "Copyright (c) 2016-2023 Igalia, S.L." -__license__ = "LGPL" - -from . import cmdnames -from . import cthulhu -from . import debug -from . import input_event -from . import keybindings -from . import messages -from . import cthulhu_state -from . import settings_manager -from .ax_object import AXObject -from .ax_utilities import AXUtilities - -_settingsManager = settings_manager.getManager() - -class WhereAmIPresenter: - """Module for commands related to the current accessible object.""" - - def __init__(self): - self._handlers = self._setup_handlers() - self._desktop_bindings = self._setup_desktop_bindings() - self._laptop_bindings = self._setup_laptop_bindings() - - def get_bindings(self, is_desktop): - """Returns the where-am-i-presenter keybindings.""" - - if is_desktop: - return self._desktop_bindings - return self._laptop_bindings - - def get_handlers(self): - """Returns the where-am-i-presenter handlers.""" - - return self._handlers - - def _setup_handlers(self): - """Sets up and returns the where-am-i-presenter input event handlers.""" - - handlers = {} - - handlers["readCharAttributesHandler"] = \ - input_event.InputEventHandler( - self.present_character_attributes, - cmdnames.READ_CHAR_ATTRIBUTES) - - handlers["presentSizeAndPositionHandler"] = \ - input_event.InputEventHandler( - self.present_size_and_position, - cmdnames.PRESENT_SIZE_AND_POSITION) - - handlers["getTitleHandler"] = \ - input_event.InputEventHandler( - self.present_title, - cmdnames.PRESENT_TITLE) - - handlers["getStatusBarHandler"] = \ - input_event.InputEventHandler( - self.present_status_bar, - cmdnames.PRESENT_STATUS_BAR) - - handlers["present_default_button"] = \ - input_event.InputEventHandler( - self.present_default_button, - cmdnames.PRESENT_DEFAULT_BUTTON) - - handlers["whereAmIBasicHandler"] = \ - input_event.InputEventHandler( - self.where_am_i_basic, - cmdnames.WHERE_AM_I_BASIC) - - handlers["whereAmIDetailedHandler"] = \ - input_event.InputEventHandler( - self.where_am_i_detailed, - cmdnames.WHERE_AM_I_DETAILED) - - handlers["whereAmILinkHandler"] = \ - input_event.InputEventHandler( - self.present_link, - cmdnames.WHERE_AM_I_LINK) - - handlers["whereAmISelectionHandler"] = \ - input_event.InputEventHandler( - self.present_selection, - cmdnames.WHERE_AM_I_SELECTION) - - return handlers - - def _setup_desktop_bindings(self): - """Sets up and returns the where-am-i-presenter desktop key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "f", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("readCharAttributesHandler"))) - - bindings.add( - keybindings.KeyBinding( - "e", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("present_default_button"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("presentSizeAndPositionHandler"))) - - bindings.add( - keybindings.KeyBinding( - "KP_Enter", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("getTitleHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "KP_Enter", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("getStatusBarHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "KP_Enter", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("whereAmIBasicHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "KP_Enter", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("whereAmIDetailedHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("whereAmILinkHandler"))) - - bindings.add( - keybindings.KeyBinding( - "Up", - keybindings.defaultModifierMask, - keybindings.CTHULHU_SHIFT_MODIFIER_MASK, - self._handlers.get("whereAmISelectionHandler"))) - - return bindings - - def _setup_laptop_bindings(self): - """Sets up and returns the where-am-i-presenter laptop key bindings.""" - - bindings = keybindings.KeyBindings() - - bindings.add( - keybindings.KeyBinding( - "f", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("readCharAttributesHandler"))) - - bindings.add( - keybindings.KeyBinding( - "e", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("present_default_button"))) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("presentSizeAndPositionHandler"))) - - bindings.add( - keybindings.KeyBinding( - "slash", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("getTitleHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "slash", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("getStatusBarHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "Return", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("whereAmIBasicHandler"), - 1)) - - bindings.add( - keybindings.KeyBinding( - "Return", - keybindings.defaultModifierMask, - keybindings.CTHULHU_MODIFIER_MASK, - self._handlers.get("whereAmIDetailedHandler"), - 2)) - - bindings.add( - keybindings.KeyBinding( - "", - keybindings.defaultModifierMask, - keybindings.NO_MODIFIER_MASK, - self._handlers.get("whereAmILinkHandler"))) - - bindings.add( - keybindings.KeyBinding( - "Up", - keybindings.defaultModifierMask, - keybindings.CTHULHU_SHIFT_MODIFIER_MASK, - self._handlers.get("whereAmISelectionHandler"))) - - return bindings - - def present_character_attributes(self, script, event=None): - """Presents the font and formatting details for the current character.""" - - attrs = script.utilities.textAttributes(cthulhu_state.locusOfFocus, None, True)[0] - - # Get a dictionary of text attributes that the user cares about. - [user_attr_list, user_attr_dict] = script.utilities.stringToKeysAndDict( - _settingsManager.getSetting('enabledSpokenTextAttributes')) - - null_values = ['0', '0mm', 'none', 'false'] - for key in user_attr_list: - # Convert the standard key into the non-standard implementor variant. - app_key = script.utilities.getAppNameForAttribute(key) - value = attrs.get(app_key) - ignore_if_value = user_attr_dict.get(key) - if value in null_values and ignore_if_value in null_values: - continue - - if value and value != ignore_if_value: - script.speakMessage(script.utilities.localizeTextAttribute(key, value)) - - return True - - def present_size_and_position(self, script, event=None): - """Presents the size and position of the current object.""" - - if script.flatReviewPresenter.is_active(): - obj = script.flatReviewPresenter.get_current_object(script, event) - else: - obj = cthulhu_state.locusOfFocus - - x_coord, y_coord, width, height = script.utilities.getBoundingBox(obj) - if (x_coord, y_coord, width, height) == (-1, -1, 0, 0): - full = messages.LOCATION_NOT_FOUND_FULL - brief = messages.LOCATION_NOT_FOUND_BRIEF - script.presentMessage(full, brief) - return True - - full = messages.SIZE_AND_POSITION_FULL % (width, height, x_coord, y_coord) - brief = messages.SIZE_AND_POSITION_BRIEF % (width, height, x_coord, y_coord) - script.presentMessage(full, brief) - return True - - def present_title(self, script, event=None): - """Presents the title of the current window.""" - - obj = cthulhu_state.locusOfFocus - if AXObject.is_dead(obj): - obj = cthulhu_state.activeWindow - - if obj is None or AXObject.is_dead(obj): - script.presentMessage(messages.LOCATION_NOT_FOUND_FULL) - return True - - title = script.speechGenerator.generateTitle(obj) - fallbackTitle = self._get_fallback_title(title) - if fallbackTitle: - script.presentMessage(fallbackTitle) - return True - - for (string, voice) in title: - script.presentMessage(string, voice=voice) - return True - - @staticmethod - def _get_fallback_title(generatedTitle): - """Returns a non-AT-SPI title when the active title reader can provide one.""" - - try: - reader = cthulhu.getManager().getDynamicApiManager().getAPI("WindowTitleReader") - except Exception: - return "" - - if reader is None: - return "" - - atspiTitle = " ".join( - str(item[0]) for item in generatedTitle - if isinstance(item, (list, tuple)) and item - ) - return reader.get_fallback_title(atspiTitle) - - def _present_default_button(self, script, event=None, dialog=None, error_messages=True): - """Presents the default button of the current dialog.""" - - obj = cthulhu_state.locusOfFocus - frame, dialog = script.utilities.frameAndDialog(obj) - if dialog is None: - if error_messages: - script.presentMessage(messages.DIALOG_NOT_IN_A) - return True - - button = AXUtilities.get_default_button(dialog) - if button is None: - if error_messages: - script.presentMessage(messages.DEFAULT_BUTTON_NOT_FOUND) - return True - - name = AXObject.get_name(button) - if not AXUtilities.is_sensitive(button): - script.presentMessage(messages.DEFAULT_BUTTON_IS_GRAYED % name) - return True - - script.presentMessage(messages.DEFAULT_BUTTON_IS % name) - return True - - def present_status_bar(self, script, event=None): - """Presents the status bar of the current window.""" - - obj = cthulhu_state.locusOfFocus - frame, dialog = script.utilities.frameAndDialog(obj) - if frame: - statusbar = AXUtilities.get_status_bar(frame) - if statusbar: - script.pointOfReference['statusBarItems'] = None - script.presentObject(statusbar, interrupt=True) - script.pointOfReference['statusBarItems'] = None - else: - full = messages.STATUS_BAR_NOT_FOUND_FULL - brief = messages.STATUS_BAR_NOT_FOUND_BRIEF - script.presentMessage(full, brief) - - infobar = script.utilities.infoBar(frame) - if infobar: - script.presentObject(infobar, interrupt=statusbar is None) - - # TODO - JD: Pending user feedback, this should be removed. - if dialog: - self._present_default_button(script, event, dialog, False) - - return True - - def present_default_button(self, script, event=None): - """Presents the default button of the current window.""" - - return self._present_default_button(script, event) - - def present_link(self, script, event=None, link=None): - """Presents details about the current link.""" - - link = link or cthulhu_state.locusOfFocus - if not script.utilities.isLink(link): - script.presentMessage(messages.NOT_ON_A_LINK) - return True - - return self._do_where_am_i(script, event, True, link) - - def present_selected_text(self, script, event=None, obj=None): - """Presents the selected text.""" - - obj = obj or cthulhu_state.locusOfFocus - if obj is None: - script.speakMessage(messages.LOCATION_NOT_FOUND_FULL) - return True - - text = script.utilities.allSelectedText(obj)[0] - if not text: - script.speakMessage(messages.NO_SELECTED_TEXT) - return True - - if script.utilities.shouldVerbalizeAllPunctuation(obj): - text = script.utilities.verbalizeAllPunctuation(text) - - msg = messages.SELECTED_TEXT_IS % text - script.speakMessage(msg) - return True - - def present_selection(self, script, event=None, obj=None): - """Presents the selected text or selected objects.""" - - obj = obj or cthulhu_state.locusOfFocus - if obj is None: - script.speakMessage(messages.LOCATION_NOT_FOUND_FULL) - return True - - tokens = ["WHERE AM I PRESENTER: presenting selection for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - - spreadsheet = AXObject.find_ancestor(obj, script.utilities.isSpreadSheetTable) - if spreadsheet is not None and script.utilities.speakSelectedCellRange(spreadsheet): - return True - - container = script.utilities.getSelectionContainer(obj) - if container is None: - tokens = ["WHERE AM I PRESENTER: Selection container not found for", obj] - debug.printTokens(debug.LEVEL_INFO, tokens, True) - return self.present_selected_text(script, event, obj) - - selected_count = script.utilities.selectedChildCount(container) - child_count = script.utilities.selectableChildCount(container) - script.presentMessage(messages.selectedItemsCount(selected_count, child_count)) - if not selected_count: - return True - - selected_items = script.utilities.selectedChildren(container) - item_names = ",".join(map(AXObject.get_name, selected_items)) - script.speakMessage(item_names) - return True - - def _do_where_am_i(self, script, event=None, basic_only=True, obj=None): - """Presents details about the current location at the specified level.""" - - if script.spellcheck and script.spellcheck.isActive(): - script.spellcheck.presentErrorDetails(not basic_only) - - if obj is None: - obj = cthulhu_state.locusOfFocus - if AXObject.is_dead(obj): - obj = cthulhu_state.activeWindow - - if obj is None or AXObject.is_dead(obj): - script.presentMessage(messages.LOCATION_NOT_FOUND_FULL) - return True - - if basic_only: - format_type = 'basicWhereAmI' - else: - format_type = 'detailedWhereAmI' - - script.presentObject( - script.utilities.realActiveAncestor(obj), - alreadyFocused=True, - formatType=format_type, - forceMnemonic=True, - forceList=True, - forceTutorial=True, - speechOnly=True) - - return True - - def where_am_i_basic(self, script, event=None): - """Presents basic information about the current location.""" - - return self._do_where_am_i(script, event) - - def where_am_i_detailed(self, script, event=None): - """Presents detailed information about the current location.""" - - # TODO - JD: For some reason, we are starting the basic where am I - # in response to the first click. Then we do the detailed one in - # response to the second click. Until that's fixed, interrupt the - # first one. - script.presentationInterrupt() - return self._do_where_am_i(script, event, False) - -_presenter = None -def getPresenter(): - """Returns the Where Am I Presenter""" - - global _presenter - if _presenter is None: - _presenter = WhereAmIPresenter() - return _presenter diff --git a/src/cthulhu/wine_access_manager.py b/src/cthulhu/wine_access_manager.py deleted file mode 100644 index b6bd72e..0000000 --- a/src/cthulhu/wine_access_manager.py +++ /dev/null @@ -1,223 +0,0 @@ -"""Manages one Cthulhu Wine accessibility helper per active prefix.""" - -from __future__ import annotations - -import os -from pathlib import Path -import shutil -import subprocess -import time -from typing import Optional - -from . import debug -from . import cthulhu_platform - - -class PrefixProcess: - """Tracks a helper process and restart state for one Wine prefix.""" - - def __init__(self) -> None: - self.process: Optional[subprocess.Popen] = None - self.lastSeen = 0.0 - self.startedAt = 0.0 - self.failures = 0 - self.nextStart = 0.0 - - -class WineAccessManager: - """Discovers Wine processes and supervises prefix-scoped helpers.""" - - POLL_INTERVAL_MS = 2000 - IDLE_GRACE_SECONDS = 10.0 - MAX_BACKOFF_SECONDS = 60.0 - MANAGED_ENVIRONMENT_KEY = "CTHULHU_WINE_ACCESS_MANAGED" - - def __init__(self, helperPath: Optional[str] = None) -> None: - self.helperPath = helperPath or self._find_helper() - self.prefixes: dict[str, PrefixProcess] = {} - self.dialogReaderEnabled = True - self.controllerEnabled = True - - @staticmethod - def _find_helper() -> Optional[str]: - configured = os.environ.get("CTHULHU_WINE_ACCESS_HELPER") - if configured and os.access(configured, os.X_OK): - return configured - installed = os.path.join( - cthulhu_platform.prefix, - "libexec", - "cthulhu", - "wine", - "cthulhu-wine-access.exe", - ) - if os.access(installed, os.X_OK): - return installed - return shutil.which("cthulhu-wine-access.exe") - - @staticmethod - def _read_environ(pid: int) -> dict[str, str]: - try: - raw = Path(f"/proc/{pid}/environ").read_bytes() - except (OSError, PermissionError): - return {} - result = {} - for entry in raw.split(b"\0"): - if b"=" not in entry: - continue - key, value = entry.split(b"=", 1) - result[key.decode(errors="replace")] = value.decode(errors="replace") - return result - - @staticmethod - def _prefix_from_environ(environment: dict[str, str]) -> Optional[str]: - prefix = environment.get("WINEPREFIX") - if not prefix: - compatPath = environment.get("STEAM_COMPAT_DATA_PATH") - if compatPath: - prefix = os.path.join(compatPath, "pfx") - if not prefix: - return None - return os.path.realpath(os.path.expanduser(prefix)) - - @staticmethod - def _loader_for_process(pid: int, environment: dict[str, str]) -> Optional[str]: - configured = environment.get("WINELOADER") - if configured and os.access(configured, os.X_OK): - return configured - try: - executable = os.readlink(f"/proc/{pid}/exe") - except OSError: - return None - name = os.path.basename(executable).lower() - if name in {"wine", "wine64"}: - return executable - if name in {"wine-preloader", "wine64-preloader"}: - loaderName = name.removesuffix("-preloader") - loader = os.path.join(os.path.dirname(executable), loaderName) - if os.access(loader, os.X_OK): - return loader - return None - - def discover_prefixes(self) -> dict[str, tuple[dict[str, str], Optional[str]]]: - """Returns active prefixes with the environment and loader that created them.""" - - discovered = {} - ownUid = os.getuid() - helperPids = { - state.process.pid - for state in self.prefixes.values() - if state.process is not None and state.process.poll() is None - } - for entry in Path("/proc").iterdir(): - if not entry.name.isdigit(): - continue - try: - if entry.stat().st_uid != ownUid: - continue - except OSError: - continue - pid = int(entry.name) - if pid in helperPids: - continue - environment = self._read_environ(pid) - if environment.get(self.MANAGED_ENVIRONMENT_KEY) == "1": - continue - prefix = self._prefix_from_environ(environment) - if prefix is None: - continue - loader = self._loader_for_process(pid, environment) - if loader is None: - continue - previous = discovered.get(prefix) - if previous is None: - discovered[prefix] = (environment, loader) - return discovered - - def poll(self) -> bool: - """Reconciles helper processes with currently active Wine prefixes.""" - - if not self.helperPath: - return True - now = time.monotonic() - discovered = self.discover_prefixes() - for prefix, (environment, loader) in discovered.items(): - state = self.prefixes.setdefault(prefix, PrefixProcess()) - state.lastSeen = now - self._ensure_running(prefix, state, environment, loader, now) - for prefix, state in list(self.prefixes.items()): - self._record_exit(state, now) - if prefix not in discovered and now - state.lastSeen >= self.IDLE_GRACE_SECONDS: - self._stop(state) - del self.prefixes[prefix] - return True - - def _ensure_running( - self, - prefix: str, - state: PrefixProcess, - sourceEnvironment: dict[str, str], - loader: Optional[str], - now: float, - ) -> None: - self._record_exit(state, now) - if state.process is not None or now < state.nextStart: - return - environment = os.environ.copy() - for key in ("DISPLAY", "WAYLAND_DISPLAY", "XDG_RUNTIME_DIR", "DBUS_SESSION_BUS_ADDRESS"): - if sourceEnvironment.get(key): - environment[key] = sourceEnvironment[key] - environment["WINEPREFIX"] = prefix - environment[self.MANAGED_ENVIRONMENT_KEY] = "1" - if loader: - environment["WINELOADER"] = loader - command = [self.helperPath] - if not self.dialogReaderEnabled: - command.append("--no-dialog-reader") - if not self.controllerEnabled: - command.append("--no-controller") - try: - state.process = subprocess.Popen( - command, - env=environment, - stdin=subprocess.DEVNULL, - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - start_new_session=True, - ) - state.startedAt = now - debug.print_message( - debug.LEVEL_INFO, f"WINE ACCESS: Started helper for {prefix}", True - ) - except OSError as error: - state.failures += 1 - state.nextStart = now + min(2 ** state.failures, self.MAX_BACKOFF_SECONDS) - debug.print_message( - debug.LEVEL_WARNING, f"WINE ACCESS: Failed to start helper: {error}", True - ) - - def _record_exit(self, state: PrefixProcess, now: float) -> None: - if state.process is None or state.process.poll() is None: - return - runtime = now - state.startedAt - state.process = None - state.failures = state.failures + 1 if runtime < 10.0 else 0 - state.nextStart = now + min(2 ** state.failures, self.MAX_BACKOFF_SECONDS) - - @staticmethod - def _stop(state: PrefixProcess) -> None: - if state.process is None or state.process.poll() is not None: - state.process = None - return - state.process.terminate() - try: - state.process.wait(timeout=2.0) - except subprocess.TimeoutExpired: - state.process.kill() - state.process = None - - def shutdown(self) -> None: - """Stops all managed helper processes.""" - - for state in self.prefixes.values(): - self._stop(state) - self.prefixes.clear() diff --git a/src/cthulhu/wnck_support.py b/src/cthulhu/wnck_support.py deleted file mode 100644 index 107c60b..0000000 --- a/src/cthulhu/wnck_support.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2026 Stormux -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. - -"""Helpers for loading Wnck only when the session can support it.""" - -from __future__ import annotations - -import importlib -import os -from types import ModuleType - - -def get_session_type() -> str: - sessionType = (os.environ.get("XDG_SESSION_TYPE") or "").strip().lower() - if sessionType: - return sessionType - if os.environ.get("WAYLAND_DISPLAY"): - return "wayland" - if os.environ.get("DISPLAY"): - return "x11" - return "unknown" - - -def can_use_wnck(session_type: str | None = None) -> bool: - return (session_type or get_session_type()).strip().lower() == "x11" - - -def load_wnck(session_type: str | None = None) -> ModuleType | None: - if not can_use_wnck(session_type): - return None - - gi = importlib.import_module("gi") - gi.require_version("Wnck", "3.0") - return importlib.import_module("gi.repository.Wnck") diff --git a/src/louis/.gitignore b/src/louis/.gitignore deleted file mode 100644 index 9da2e75..0000000 --- a/src/louis/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -Makefile.in -Makefile -constants.py -.deps diff --git a/src/meson.build b/src/meson.build deleted file mode 100644 index aa391a3..0000000 --- a/src/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -# Main executable script -install_data( - 'cthulhu.py', - rename: 'cthulhu', - install_dir: get_option('bindir'), - install_mode: 'rwxr-xr-x' -) - -subdir('cthulhu') \ No newline at end of file diff --git a/test-local.sh b/test-local.sh deleted file mode 100755 index a48dfee..0000000 --- a/test-local.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -# Test script for local Cthulhu installation - -set -e - -# Colors -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -RED='\033[0;31m' -NC='\033[0m' - -LOCAL_PREFIX="$HOME/.local" -CTHULHU_BIN="${LOCAL_PREFIX}/bin/cthulhu" - -echo -e "${GREEN}=== Testing Local Cthulhu Installation ===${NC}" - -# Check if binary exists -if [[ ! -f "$CTHULHU_BIN" ]]; then - echo -e "${RED}Error: Cthulhu binary not found at $CTHULHU_BIN${NC}" - echo -e "${YELLOW}Run ./build-local.sh first${NC}" - exit 1 -fi - -echo -e "${YELLOW}Testing basic functionality...${NC}" - -# Test version -echo -n "Version check: " -if "$CTHULHU_BIN" --version >/dev/null 2>&1; then - echo -e "${GREEN}✓${NC}" -else - echo -e "${RED}✗${NC}" -fi - -# Test help -echo -n "Help option: " -if "$CTHULHU_BIN" --help >/dev/null 2>&1; then - echo -e "${GREEN}✓${NC}" -else - echo -e "${RED}✗${NC}" -fi - -# Test D-Bus service import -echo -n "D-Bus service: " -if PYTHONPATH="${LOCAL_PREFIX}/lib/python3.*/site-packages" python3 -c " -import sys -sys.path.insert(0, '${LOCAL_PREFIX}/lib/python3.13/site-packages') -try: - import cthulhu.dbus_service - controller = cthulhu.dbus_service.get_remote_controller() - print('D-Bus available:', controller._dasbus_available, file=sys.stderr) - print('SUCCESS') -except Exception as e: - print('ERROR:', e, file=sys.stderr) - sys.exit(1) -" 2>/dev/null; then - echo -e "${GREEN}✓${NC}" -else - echo -e "${YELLOW}~ (expected during development)${NC}" -fi - -echo "" -echo -e "${GREEN}Local build test complete!${NC}" -echo -e "${YELLOW}To run Cthulhu: ${CTHULHU_BIN}${NC}" \ No newline at end of file diff --git a/testdata/parity-ledger.csv b/testdata/parity-ledger.csv new file mode 100644 index 0000000..588f3dd --- /dev/null +++ b/testdata/parity-ledger.csv @@ -0,0 +1,69 @@ +id,python_source,subsystem,behavior,owner,go_destination,status,automated_evidence,x11_evidence,wayland_evidence,speech_evidence,braille_evidence,notes +gtk-alert-message,src/cthulhu/speech_generator.py;src/cthulhu/script_utilities.py,speech,Read a GTK alert message before its first focused button,,internal/atspi internal/app,in-progress,go test ./internal/app ./internal/atspi -count=1; python3 tests/native_alert.py,Private GTK/Xvfb/AT-SPI fixture captured the complete question on 2026-09-26.,,Physical FastSMRW listening pending.,,Alert window creation captures its label text; activation does not interrupt the message; the first button appends and later buttons use ordinary focus speech. +yad-simple-prompt,src/cthulhu/formatting.py;src/cthulhu/scripts/default.py,speech,Read a simple YAD frame question before its first focused button,,internal/atspi internal/app,implemented,go test ./internal/app ./internal/atspi -count=1; python3 tests/native_alert.py,Private YAD/Xvfb/AT-SPI fixture captured the exact question on frame activation or first button focus. The live 2026-09-27 log showed a third path where activation targets the focused button; an event-loop regression covers its speech order.,,Maintainer confirmed the YAD question was spoken on the updated build on 2026-09-27.,,YAD exposes the prompt as a frame with layout nodes and a label plus buttons. The generic Python frame format appears to omit the label; this Go addition follows the user's explicit example. A strict simple prompt shape limits frame text capture and bounded first-button refresh handles late labels. +radio-group-focus,src/cthulhu/generator.py;src/cthulhu/speech_generator.py,speech,Speak the radio group question with a focused option,,internal/atspi internal/presentation internal/preferences,implemented,go test ./internal/presentation ./internal/atspi ./internal/preferences -count=1; python3 tests/native_alert.py,Private GTK radio group focus captured Punctuation Level.,,Physical preferences speech pending.,,A named panel or labelled-by relation supplies the group question; each focused radio presents that name before its option. The Braille verbosity radios now have a named frame. +yad-list-prompt,src/cthulhu/formatting.py;src/cthulhu/scripts/default.py,speech,Read a simple YAD list question when its window opens,,internal/atspi internal/app,implemented,go test ./internal/app ./internal/atspi -count=1; python3 tests/native_alert.py,Private YAD power list captured Power options after ordinary or synthesized window activation.,,Physical I38 power menu listening pending.,,The I38 list has a labelled question above its choices; foreground recovery and direct activation both capture the same bounded prompt shape. +web-live-region-announcements,src/cthulhu/scripts/web/script.py; src/cthulhu/liveregions.py,web,Automatically speak active-tab polite and assertive live region updates,Storm Dragon,internal/atspi internal/app,implemented,go test ./internal/app ./internal/atspi -count=1; CTHULHU_NATIVE_BROWSER_TESTS=live python3 tests/native_browser.py; CTHULHU_NATIVE_BROWSER_TESTS=live-atomic python3 tests/native_browser.py,Private Brave/Xvfb fixture captures the Skald-style status update and real child text; physical Skald Xorg test pending.,,Maintainer confirms extensive live browser testing passes in Firefox and Chromium-based browsers on 2026-10-22; element lists and jumping to selected items are explicitly confirmed. See docs/testing/release-acceptance.md.,,Go captures inherited live metadata and child text for text insertions and child additions. A Chromium placeholder update is suppressed. Off regions and inactive documents are filtered. Complete Python live-region review commands and politeness overrides remain pending. October 24 audit fixes resolve atomic ancestors and defer established busy live regions until completion. Private Chromium atomic text/child updates non-atomic updates and busy release without a new insertion pass. Provider metadata limits and pending physical checks are documented in docs/testing/browser-audit-fixes.md. +core-startup,src/cthulhu/cthulhu.py,core,Orchestrate runtime service startup and graceful shutdown,Storm Dragon,internal/app,in-progress,go test ./internal/app ./internal/atspi ./internal/lifecycle -count=1; CTHULHU_XRECORD_TEST=/tmp/cthulhu-xrecord.test python3 tests/native_x11.py,Maintainer accepted the Stage 1 physical Xorg shutdown checklist on 2026-09-11; post-fix cthulhu.sh returned to the prompt with complete shutdown records on Xorg using its LXTerminal test application. The private Xvfb/D-Bus native proof with XRecord also passed.,,,,"Lifecycle and service orchestration only; see lifecycle-welcome-message, lifecycle-farewell-message, lifecycle-start-sound, and lifecycle-stop-sound for the four user-visible deliveries. General startup or shutdown parity is not claimed." +lifecycle-welcome-message,src/cthulhu/plugins/HelloCthulhu/plugin.py,speech,Speak a randomly selected startup welcome message,Storm Dragon,internal/app,in-progress,go test ./internal/app -run '^(TestRunSpeaksFocusEventsAndStops|TestRandomString)$' -count=1,Maintainer accepted welcome speech in the Stage 1 physical Xorg checklist on 2026-09-11 and confirmed the randomized message wiring worked on 2026-09-12.,,,Maintainer heard the startup welcome message during the accepted Stage 1 physical Xorg checklist on 2026-09-11 and confirmed the randomized message wiring worked on 2026-09-12.,Python presents Cthulhu welcomes you. once through HelloCthulhu after start-application-completed and only while an active script exists. Go creates its speech worker only when enableSpeech is true and randomly selects from a small startup list after service startup without an active-script or once-only gate; delivery is not waited for and has no per-message deadline. The extra variants are an intentional Go behavior extension. General startup parity is not claimed. +lifecycle-farewell-message,src/cthulhu/plugins/ByeCthulhu/plugin.py,speech,Speak a randomly selected graceful-shutdown farewell message,Storm Dragon,internal/app,in-progress,go test ./internal/app -run '^(TestRunSpeaksFocusEventsAndStops|TestRandomString)$' -count=1,Maintainer heard the post-fix farewell speech through cthulhu.sh on Xorg using its LXTerminal test application on 2026-09-11 and confirmed the randomized message wiring worked on 2026-09-12; the launcher returned to the prompt and completed final shutdown records.,,,Maintainer heard the post-fix farewell speech through cthulhu.sh on Xorg on 2026-09-11 and confirmed the randomized message wiring worked on 2026-09-12.,"Python presents Cthulhu lurks beneath the waves. through ByeCthulhu only while an active script exists. Go randomly selects from a small shutdown list only when enableSpeech is true, interrupts owned speech, and waits up to 2 seconds for the backend result before native cleanup; timeout cancels the active request. The extra variants are an intentional Go behavior extension. audit-required: active-script gating, speech-disabled presentation semantics, and Python's overall shutdown watchdog versus Go's per-message deadline are not directly aligned by the named evidence." +lifecycle-start-sound,src/cthulhu/sound_theme_manager.py,sound,Play the startup sound cue,Storm Dragon,internal/sound,in-progress,go test ./internal/sound -run '^(TestBundledSoundsDecodeInProcess|TestSoundWorkerBoundsQueueAndStopsActiveCue|TestStopPlaysShutdownCueAfterStartupCueOverflow)$' -count=1,Maintainer heard the startup cue during the 2026-09-11 physical Xorg preview; the desktop and window manager were not recorded.,,,,"Python plays the start cue from the configured theme when enableSound is true and the theme is not none; startup uses a nonblocking, interrupting, best-effort helper command with no per-cue deadline at this call. Go creates the sound service only when enableSound is true, theme is not none, and volume is greater than zero; it enqueues start after service startup into a bounded 8-cue queue, with a 3-second playback deadline, and can drop the startup cue on overflow. audit-required: Python helper-process and Go in-process queue saturation are not directly compared by live evidence. September 25 review: nonblocking queue drains prevent a consumer/producer deadlock during cue replacement and live reconfiguration; concurrent regression and race checks pass." +lifecycle-stop-sound,src/cthulhu/sound_theme_manager.py,sound,Play the graceful-shutdown sound cue,Storm Dragon,internal/sound,in-progress,go test ./internal/sound -run '^(TestBundledSoundsDecodeInProcess|TestSoundWorkerBoundsQueueAndStopsActiveCue|TestStopPlaysShutdownCueAfterStartupCueOverflow|TestStopTimeoutPreservesShutdownCueForRetry)$' -count=1; go test ./internal/app -run '^(TestRunReachesSoundStopAfterEarlierServiceStopError|TestRunReportsSoundStopError)$' -count=1,Maintainer heard the post-fix stop cue through cthulhu.sh on Xorg using its LXTerminal test application on 2026-09-11; the launcher returned to the prompt and completed final shutdown records.,,,,"Python plays stop only when enableSound is true and the theme is not none; it interrupts current sound, waits up to 1 second through the helper, then continues shutdown. Go runs stop as the final reverse lifecycle service with its own 3-second deadline, cancels active cues, discards pending cues, and preserves a timed-out stop cue for one retry. audit-required: Python helper-isolation versus Go in-process cancellation and retry ordering are not directly aligned by the named evidence." +focus-events,src/cthulhu/event_manager.py,focus,Receive focus events and capture immutable accessible snapshots with stable object paths,Storm Dragon,internal/atspi,implemented,go test ./internal/atspi ./internal/app ./internal/logging -count=1,GTK yad Zenity and LXTerminal live tests passed 2026-09-10; post-fix AT-SPI shutdown passed through cthulhu.sh with its LXTerminal test application on Xorg 2026-09-11.,,,,Queue overflow duplicate-object suppression and nonblocking diagnostics have automated coverage; physical diagnostics saturation remains pending. +background-event-filtering,Orca src/orca/event_manager.py,focus,Reject routine background updates before selected-child and content capture,,internal/atspi,in-progress,go test ./... -count=1; private background flood and notification checks; docs/testing/background-events.md,Private GTK floods from another provider and same-provider sibling produce zero selection/table/text/value queries; GTK Qt Brave ownership and browser checks pass,Private Wayland policy check preserves AT-SPI ownership without X11 authority,Actual FastSMRW and Brave listening pending,Physical Braille pending,Existing lifecycle notification menu autocomplete and detached-document validation paths are preserved; unrelated providers no longer clear owned text-line caches. +xterm-focus-handoff,src/cthulhu/input_event_manager.py,input,Suspend Cthulhu while XTerm owns focus and restore when a known non-XTerm window takes focus,Storm Dragon,internal/app internal/atspi internal/platform/xorg,implemented,NO_COLOR=1 GOCACHE=/tmp/cthulhu-build-cache go test ./internal/app -run '^(TestXTermFocus|TestProcessEvents)' -count=1; NO_COLOR=1 GOCACHE=/tmp/cthulhu-build-cache go test ./internal/platform/xorg -count=1; python3 tests/native_x11.py,Private Xvfb/D-Bus proof passes: XTerm focus suspends speech and command grabs; Insert+Q reaches a real XTerm; an unknown active window remains suspended; a known non-XTerm window restores all existing command and release checks. Maintainer confirms constant live use of XTerm handoff and recovery with good results on 2026-10-22.,,Maintainer confirms XTerm handoff and recovery work very well during constant use on 2026-10-22. See docs/testing/release-acceptance.md.,,Follow-up gates delegated modifier interruption and echo; commands dispatch on press with balanced shutdown draining. Go retains the existing XTerm identity matching focus monitoring grab suspension and event suppression boundary. Notifications bypass suppression. Unknown active windows remain suspended so an incomplete match cannot strand a delegated terminal reader; live XTerm handoff and recovery are accepted by the maintainer on 2026-10-22. +focus-speech,src/cthulhu/scripts/default.py,speech,Speak the focused accessible object including common control states and range values,Storm Dragon,internal/atspi internal/presentation internal/app,implemented,go test ./internal/atspi ./internal/presentation ./internal/app -count=1,Maintainer accepted post-change YAD value and LibreOffice focus value and menu behavior on physical Xorg on 2026-09-12. The combined log had no accessibility-event speech or sound queue overflow; 599 debug diagnostics were dropped during a LibreOffice state-event burst.,,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,,Focus presentation includes common states and range values. Focused value changes speak only the value; non-focused state and value events are filtered; menu selection and table-cell verbosity are reduced. Relations position context background progress updates complete role-specific formatting and diagnostics saturation acceptance remain pending. Parity review corrections and remaining physical gates: docs/testing/parity-review-follow-up.md. September 25 review: window-owned title tracking suppresses repeated name events and preserves empty-to-restored title changes; event-loop regression passes. Combo selection follow-up: focus/name/value event regressions verify selection-only speech without repeated combo cues and restore the cue on re-entry; focused app/presentation race checks pass. Current general native focus listening is accepted by the maintainer on 2026-10-22. +terminal-caret-character,src/cthulhu/scripts/default.py,terminal,Speak the character at the caret,Storm Dragon,internal/app,implemented,go test ./internal/atspi ./internal/presentation ./internal/app -count=1,Maintainer accepted terminal caret behavior in the launcher's LXTerminal test application on Xorg during the Stage 1 physical checklist on 2026-09-11.,,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,,Uses AT-SPI character granularity with line fallback debounces caret movement and suppresses unchanged path-and-announcement combinations; the maintainer confirms thorough native and terminal live testing on 2026-10-22. +terminal-text-change-echo,src/cthulhu/scripts/terminal/script.py,terminal,Speak sanitized inserted or deleted text from terminals and editable text controls,Storm Dragon,internal/app,implemented,go test ./internal/atspi ./internal/presentation ./internal/app -count=1,"Maintainer accepted terminal insertion in LXTerminal on Xorg on 2026-09-11, accepted the post-change LibreOffice Writer typing behavior on physical Xorg on 2026-09-12, and confirmed YAD close-and-prompt coalescing on physical Xorg on 2026-09-13. Physical acceptance of terminal deletion-redraw coalescing is pending.",,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,,"Text changes are limited to terminals and editable text or paragraph roles. A change suppresses the next caret event from the same object so typing does not replay the line. Same-terminal insertion within the event-coalescing window suppresses a redundant interrupting terminal-focus presentation. A terminal deletion waits 50 ms and is suppressed only when the same terminal inserts replacement text at the same AT-SPI offset; standalone and different-offset deletions remain presentable. Debug speech delivery records retain the final utterance with cause and policy metadata; normal logging omits speech content. Broader application coverage remains incomplete. Focusable writable browser editors also own their editable paragraph events, preventing rejected insertions from replaying the growing line through caret speech. Private Chromium coverage and live acceptance steps are in docs/testing/browser-editor.md; original-page ChatGPT listening and physical Braille acceptance remain pending." +managed-descendant-presentation,src/cthulhu/scripts/default.py,focus,Resolve focused container selection and active-descendant changes to the managed child,Storm Dragon,internal/atspi internal/app,implemented,go test ./internal/atspi ./internal/app -count=1; python3 tests/native_x11.py; python3 tests/native_atspi.py --table-only,The isolated GTK/Xvfb/D-Bus selection fixture and physical I38 run-dialog completion selection speech passed on 2026-09-12 without regressing X11 pass-through command consumption release ordering lock states lifecycle or grab cleanup.,,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,,The generic adapter registers both selection and active-descendant events resolves their managed child preserves the originating container path and filters events unless the container or child owns focus. Duplicate target presentations are suppressed. No I38-specific workaround was added. Broader GTK and Qt managed-descendant coverage remains pending. October 17: GTK controls with list role and Table interface retain selected-cell focus and table ownership without normalizing ordinary lists or choosing among multiple selected rows. Private native focus and recorded-speech tests cover first Down and genuine Shift+Tab exit; activation descriptions are not repeated on first row selection. Current physical listening and Braille acceptance remain pending. See docs/testing/gui-list-tables.md. +ssip-speak-cancel,src/cthulhu/speechdispatcherfactory.py,speech,Send speech and cancellation through SSIP,Storm Dragon,internal/speech,in-progress,go test ./internal/speech -count=1,Maintainer accepted audible non-consuming Control/Shift interruption in the Stage 1 physical Xorg checklist on 2026-09-11.,,Maintainer heard lifecycle and terminal speech plus Control/Shift interruption during the accepted Stage 1 physical Xorg checklist on 2026-09-11.,,Protocol replies 230 and 225 were confirmed against the local service; broader backend and X11 coverage remains pending. +web-structural-navigation,src/cthulhu/scripts/web/script.py,web,Move by headings and other document structure,Storm Dragon,internal/input internal/review internal/app,implemented,go test -race ./... -count=1; python3 tests/native_browser.py,Private Brave/Xvfb structural and mode/chrome sequences pass on 2026-09-20.,,Maintainer confirms extensive live browser testing passes in Firefox and Chromium-based browsers on 2026-10-22; element lists and jumping to selected items are explicitly confirmed. See docs/testing/release-acceptance.md.,,Structural navigation follows native caret movement. Echo suppression ends on subsequent input. Failed same-object context capture retries. Delayed document carets cannot override editable focus and stale results cannot overwrite unresolved unrelated focus. All 27 browse symbols pass through after routing is disabled. Complete Python structural settings and dialogs remain pending. Parity review corrections and remaining physical gates: docs/testing/parity-review-follow-up.md. +web-document-recapture,src/cthulhu/ax_object.py,web,Recover heading navigation after browser document replacement,Storm Dragon,internal/atspi internal/review internal/app,implemented,go test -race ./... -count=1; python3 tests/native_browser.py,Private Brave/Xvfb passes immediate H after loading a new page and after activating its return link on 2026-09-20.,,Maintainer confirms extensive live browser testing passes in Firefox and Chromium-based browsers on 2026-10-22; element lists and jumping to selected items are explicitly confirmed. See docs/testing/release-acceptance.md.,,Native caches refresh on recapture. Load completion retains the new root and resets browser context and pending reading. Worker page epochs retire queued and in-flight results across reused paths. Native reload and mode/chrome tests remain covered. Installed Go preview and Brave Origin are not verified. On 2026-09-21 semantic invalidation was scoped to captured objects so browser chrome and other applications cannot discard the document. Focused race tests and the full private Brave suite pass; heading/link jumps assert capture reuse. Large-page latency and logged stale-object failures still require physical retesting. September 22 log regressions: native invalid text-end recovery and bounded embedded text expansion; web name-event suppression; background load preserves verified chrome focus. Focused race tests and private Brave proofs pass. See docs/testing/chromium-browser.md for reference behavior and remaining physical gates. September 23 ownership correction rejects loads outside the current application or known window and after owner loss; accepted loads update the focus owner for correct defunct recovery. Five event-loop regressions and app race tests pass; physical acceptance remains pending. September 24 same-geometry window recovery now requires fresh active/showing/non-iconified state before foreground correlation; private recovery regression fails on the earlier preview and passes on the rebuilt one. Address changes outside the owned field are suppressed; popup-associated typing remains supported. September 25 review: recovery now checks the fresh tree when text/geometry recapture discovers a removed focus; deterministic regression and focused race checks pass. +web-caret-line-reading,src/cthulhu/scripts/web/script.py,web,Read displayed document content at the browser caret,Storm Dragon,internal/atspi internal/review internal/app internal/presentation,implemented,"go test -race ./... -count=1; python3 tests/native_browser.py; go test -race ./internal/atspi ./internal/review ./internal/app -count=1; CTHULHU_NATIVE_BROWSER_TESTS=generatedlinks,replacement,tooltips,fragments,namedlinks,linkedheadings python3 tests/native_browser.py",Private Brave/Xvfb H/Down/H and expanded page transition sequences pass on 2026-09-20. On 2026-10-22 the maintainer confirmed reading the entire original Techrights article in Brave without looping after the generated-link recovery fix. See docs/testing/browser-release-review.md#generated-link-recovery-acceptance-2026-10-22.,,Maintainer confirms extensive live browser testing passes in Firefox and Chromium-based browsers on 2026-10-22; element lists and jumping to selected items are explicitly confirmed. See docs/testing/release-acceptance.md. Original Techrights full-article reading accepted after the generated-link fix on 2026-10-22; see docs/testing/browser-release-review.md#generated-link-recovery-acceptance-2026-10-22.,,Captured and assembled document lines use role/state sound categories and speech fallback. Unit tests cover visited links and per-object cue deduplication and sound-only versus speech-only policy. Character and word intents remain separate. Ordinary caret movement updates structural position. Initial read-all is implemented; braille and complete line-presentation parity remain pending. September 22 log regressions: native invalid text-end recovery and bounded embedded text expansion; web name-event suppression; background load preserves verified chrome focus. Focused race tests and private Brave proofs pass. See docs/testing/chromium-browser.md for reference behavior and remaining physical gates. September 24 prerequisite review: pending caret/terminal timers extracted under the same event-loop owner; adjacent-character word navigation and whitespace and embedded-marker traversal corrected; whole caret movement deadline added. Full race and isolated Brave/X11/ownership proofs pass; physical and installed-preview gates remain pending. See docs/testing/chromium-browser.md for dependency order. September 24 log correction: browse word and line speech includes link and heading ancestors with role sound policy; character output retains character granularity. Native Brave assertions cover link words and document-start heading level. See docs/testing/chromium-browser.md. September 25 review: trailing non-text objects no longer cause false stale-location errors for line/document-edge movement; focused regression and private Brave suite pass. Physical listening remains open. Explicitly named links retain whole-label line speech while character and word review use accessible-label offsets independently of native text. Generic unit and private Brave named-link regressions cover empty native text and badges plus both directions across following punctuation. Live speech and physical Braille acceptance remain pending. October 22 generated-link regression verifies exact prefix/body text with forward/reverse lines and Read All in private Brave. The maintainer accepted full-article reading on the original Techrights page after the fix; other live gates remain scoped to their named workflows. See docs/testing/browser-release-review.md#generated-link-recovery-acceptance-2026-10-22. October 24 audit fixes validate dirty hypertext ancestors before crossing objects; refreshed retries include inserted parent text. Word whitespace uses bounded native character blocks and caret ranges have indexed lookup. Existing native navigation regressions pass; see docs/testing/browser-audit-fixes.md for limitations and remaining work. +config-read-preview,src/cthulhu/backends/toml_backend.py,settings,Read existing Cthulhu TOML and merge the startup profile,Storm Dragon,internal/config,implemented,go test ./internal/config ./cmd/cthulhu -count=1,,,,,Read-only preview bridge available only through explicit --config selection. The Go-native schema and default path are intentionally separate; the one-shot importer remains Phase 8 work. +config-speech-preview,src/cthulhu/speechdispatcherfactory.py,speech,Apply supported active-profile speech settings,Storm Dragon,internal/config internal/speech internal/app,implemented,go test ./internal/config ./internal/speech ./internal/presentation ./internal/app -count=1,,,Maintainer confirms speech preferences; previews; Apply and Cancel; saved settings; and interruption-key settings work in live testing on 2026-10-22. See docs/testing/release-acceptance.md.,,Applies enablement description punctuation capitalization and default voice settings. +typing-printable-key-echo,src/cthulhu/typing_echo_presenter.py,input,Apply printable typing-echo category settings to terminal and editable text insertions,Storm Dragon,internal/config internal/atspi internal/presentation internal/app,implemented,go test ./internal/config ./internal/atspi ./internal/presentation ./internal/app -count=1,Maintainer reported the configured printable echo settings worked in minimal physical Xorg tests on 2026-09-12; broader application coverage remains pending.,,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,,Single-character terminal and editable AT-SPI insertions honor enableKeyEcho enableEchoByCharacter and alphabetic numeric punctuation space and diacritical categories. Multi-character insertions remain presentation events. Preferences offer disabled enabled and edit-fields-only radio choices; edit-fields-only uses native editable metadata and Wine editor focus while preserving configured echo voices. Automated focus and persistence checks pass; live speech and physical Braille acceptance for the new mode remain pending. +typing-nonprintable-boundary-echo,src/cthulhu/typing_echo_presenter.py,input,Apply non-printable key and word or sentence echo settings,Storm Dragon,internal/config internal/input internal/platform/xorg internal/atspi internal/presentation internal/app,implemented,go test ./internal/config ./internal/input ./internal/platform/xorg ./internal/atspi ./internal/presentation ./internal/app -count=1,Pending physical Xorg category chord and pass-through matrix,,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,,XRecord copies stable non-printable names from the active keymap and suppresses configured Cthulhu modifier chords. Word and sentence echo use bounded text before the caret and retain the prior line across a newline. Printable delivery remains AT-SPI based to avoid duplicate XRecord speech. Parity review corrections and remaining physical gates: docs/testing/parity-review-follow-up.md. +keyboard-speech-interrupt,src/cthulhu/input_event.py,input,Interrupt speech on non-consuming Control or Shift press,Storm Dragon,internal/input internal/platform/xorg internal/app,in-progress,go test ./internal/input ./internal/platform/xorg ./internal/app -count=1,Maintainer accepted Control and Shift interruption without stolen or stuck keys in the Stage 1 physical Xorg checklist on 2026-09-11.,,Speech interruption was audible during the accepted physical Xorg checklist.,,XRecord observation and speech-worker wiring are implemented; broader X11 matrix remains pending. +where-am-i-basic,src/cthulhu/where_am_i_presenter.py,command,Repeat basic information about the current focused accessible,Storm Dragon,internal/input internal/platform/xorg internal/app internal/presentation,in-progress,go test ./internal/input ./internal/platform/xorg ./internal/app -count=1; python3 tests/native_x11.py,Private X11 proof covers unmodified desktop KP_Enter consumption and balanced replay of desktop Cthulhu+Return; maintainer accepted the corrected physical desktop binding on Xorg on 2026-09-13,,Maintainer confirmed both the basic spoken result and corrected desktop binding on 2026-09-13,,Uses the latest accepted immutable focus or managed-descendant snapshot and the Python no-location message. keyboardLayout selects desktop KP_Enter or laptop Cthulhu+Return. Detailed context repeated-press behavior and selection details remain pending. +owned-object-tree,src/cthulhu/ax_object.py,review,Own stable accessible identities and navigate a validated tree without retaining native objects,Storm Dragon,internal/atspi internal/review internal/app,in-progress,go test ./internal/atspi ./internal/review ./internal/app -count=1; python3 tests/native_atspi.py,Private Xvfb D-Bus and GTK automation captures the desktop invalidates a removed defunct object recaptures into the same owned tree and invalidates references on adapter shutdown.,,,,Identity combines the AT-SPI application bus name and object path. Complete-tree replacement preserves live references; subtree invalidation detaches removed nodes and makes old references stale. Parent child sibling malformed oversized concurrent and structural-event policy cases have unit coverage. The runtime worker follows the latest focus keeps capture off event and command loops recaptures stale state and presents semantic movement or Python boundary messages. Capture waits honor context and individual libatspi calls use explicit 800 ms ordinary and startup timeouts. GtkBox native addition delivery and recapture pass alongside the original ListBox defunct proof. Incomplete child lists trigger one worker recapture preserving live independent review position; failure changed-focus and repeated-invalidation tests pass. Physical dynamic-container recovery native ambiguous removal simplified navigation and text ranges remain pending. Component geometry is recorded separately. Object-navigation key acceptance is recorded separately. +object-navigation,src/cthulhu/object_navigator.py,review,Navigate the owned accessible hierarchy and present each object or boundary,Storm Dragon,internal/review internal/app internal/input internal/platform/xorg,implemented,go test ./internal/review ./internal/app ./internal/input ./internal/platform/xorg -count=1; python3 tests/native_x11.py,Private X11 proof covers all four Cthulhu Control Arrow bindings with balanced consumption and no application leakage plus Insert-first and Control-first ordering for Up. Maintainer accepted physical Xorg press release behavior with no leaked or stuck keys on 2026-09-14.,,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,,Runtime commands and asynchronous capture presentation are bound to Python's parent first-child previous-sibling and next-sibling gestures. Python simplified navigation filtering action invocation and toggle remain pending. Desktop numpad belongs to flat review and is intentionally not aliased to hierarchical object navigation. +clipboard-present-command,src/cthulhu/plugins/Clipboard/plugin.py,command,Present clipboard text URI objects image presence empty state or access errors with Cthulhu+Shift+C,Storm Dragon,internal/input internal/clipboard internal/app internal/platform/xorg,implemented,go test ./internal/clipboard ./internal/input ./internal/app ./internal/platform/xorg -count=1; isolated Xvfb clipboard helper and native command test,Private X11 proof covers Cthulhu+Shift+C press dispatch and both release orders; isolated GTK clipboard reads confirmed text URI and image formats,,Maintainer confirms date/time; spoken version; window-title; and clipboard-reading commands pass live testing on 2026-10-22. See docs/testing/release-acceptance.md.,,The Go command reads GTK 3 clipboard data in a short lived helper with a three second timeout so a stalled clipboard owner cannot block input or shutdown. It announces text URI object names and types image presence empty state and access errors. URI-only clipboard data is presented even when no text target exists. The maintainer confirms the clipboard-reading command works in live use on 2026-10-22; individual special-case test inputs were not itemized. +display-version-command,src/cthulhu/plugins/DisplayVersion/plugin.py,command,Speak the Cthulhu version plus revision AT-SPI version and session details with Cthulhu+Shift+V,Storm Dragon,internal/input internal/presentation internal/version,implemented,,Pending Cthulhu+Shift+V X11 key-consumption and release gate,,Maintainer confirms date/time; spoken version; window-title; and clipboard-reading commands pass live testing on 2026-10-22. See docs/testing/release-acceptance.md.,,The Go PresentVersion command is bound to Cthulhu+Shift+V in both keyboard layouts. Runtime dispatch presents version.Details with the AT-SPI version and session metadata through the speech queue. The old claim that only command-line version output existed is obsolete; current code and the maintainer's live confirmation establish the spoken command. +game-mode-command,src/cthulhu/plugins/GameMode/plugin.py,input,Toggle reduced speech interruption for ordinary unbound key presses with Cthulhu+Control+G,Storm Dragon,internal/input internal/config internal/presentation,pending,,Pending global Cthulhu+Control+G and unbound-key X11 non-consumption gate,,Pending human listening gate for toggle messages and held-key speech continuity,,Python keeps interruption for handled or consumed commands and Cthulhu modifiers while game mode is enabled and resets the setting on plugin deactivation. The Phase 0 audit also confirmed that plugin.info marks this as a visible non-builtin plugin. The Go preview defaults to interrupting on every observed key press and now offers persistent interruption choices in Speech preferences; the separate Game Mode toggle remains pending. +hello-world-plugin-example,src/cthulhu/plugins/hello_world/plugin.py,extension,Register a learn-mode-aware Cthulhu+Z example command that presents hello world,Storm Dragon,api/lua/v1 docs/contributor,pending,,Pending extension-command X11 key-consumption and release gate,,Pending human listening and learn-mode acceptance,,Python is a visible non-builtin test plugin and directly accesses the active script without checking that it exists. Preserve the user-facing tutorial behavior in the process-isolated Lua extension examples rather than embedding this Python plugin. +self-voice-socket,src/cthulhu/plugins/self_voice/plugin.py,remote,Accept external UTF-8 text over a local Unix socket for speech and braille presentation with append and persistent markers,Storm Dragon,,accepted-omission,,,,,,Decision 0005 omits XDG_RUNTIME_DIR/cthulhu.sock and its <#APPEND#> and <#PERSISTENT#> marker protocol in favor of the established Cthulhu D-Bus self-voice API. No socket bridge or compatibility parser will be implemented. +self-voice-dbus-present,src/cthulhu/dbus_service.py,remote,Present an external message through normal speech and braille output over the session D-Bus service,Storm Dragon,internal/remote internal/app,in-progress,go test ./internal/remote ./internal/app -count=1; CTHULHU_NATIVE_DBUS_TEST=1 go test ./internal/remote -run '^TestNativeSessionBusSelfVoice$' -count=1,Private session-bus and handler tests pass same-user dispatch introspection and output queueing.,,Maintainer confirms native D-Bus integration works in live testing with Toby Doom on 2026-10-22. Individual API calls and output modalities were not itemized. See docs/testing/release-acceptance.md.,Pending PresentMessage braille acceptance,PresentMessage queues speech without interruption and braille when connected; it returns false only if neither output is available. Physical display delivery remains unverified. Maintainer confirms native D-Bus integration works in live testing with Toby Doom on 2026-10-22. Individual API calls and output modalities were not itemized. See docs/testing/release-acceptance.md. +self-voice-dbus-speak,src/cthulhu/dbus_service.py,remote,Speak external plain text with caller-selected interruption over the session D-Bus service,Storm Dragon,internal/remote internal/app,in-progress,go test ./internal/remote ./internal/app -count=1; CTHULHU_NATIVE_DBUS_TEST=1 go test ./internal/remote -run '^TestNativeSessionBusSelfVoice$' -count=1,Private session-bus proof passes same-user dispatch introspection conflict shutdown release and reacquisition.,,Maintainer confirms native D-Bus integration works in live testing with Toby Doom on 2026-10-22. Individual API calls and output modalities were not itemized. See docs/testing/release-acceptance.md.,,Empty and over-64-KiB text is rejected. Noninterrupting text queues; interrupting text clears pending output uses the owned cancellation barrier and then queues the requested text. Maintainer confirms native D-Bus integration works in live testing with Toby Doom on 2026-10-22. Individual API calls and output modalities were not itemized. See docs/testing/release-acceptance.md. +self-voice-dbus-braille,src/cthulhu/dbus_service.py,remote,Display an external persistent braille message over the session D-Bus service,Storm Dragon,internal/remote internal/app,in-progress,go test -tags brlapi ./internal/remote ./internal/app -count=1,Focused tests confirm connected-worker queueing and rejection when disconnected.,,,Pending physical BrailleMessage delivery and persistent-display acceptance,BrailleMessage queues a persistent frame only after the BrlAPI helper reports ready. It rejects empty and over-10-KiB text; physical display and Wine client acceptance remain open. Maintainer confirms native D-Bus integration works in live testing with Toby Doom on 2026-10-22. Individual API calls and output modalities were not itemized. See docs/testing/release-acceptance.md. +self-voice-dbus-cancel,src/cthulhu/dbus_service.py,remote,Cancel current speech at an external application's request over the session D-Bus service,Storm Dragon,internal/remote internal/app,in-progress,go test ./internal/remote ./internal/app -count=1; CTHULHU_NATIVE_DBUS_TEST=1 go test ./internal/remote -run '^TestNativeSessionBusSelfVoice$' -count=1,Private session-bus proof passes same-user dispatch introspection conflict shutdown release and reacquisition.,,Maintainer confirms native D-Bus integration works in live testing with Toby Doom on 2026-10-22. Individual API calls and output modalities were not itemized. See docs/testing/release-acceptance.md.,,CancelSpeech uses the asynchronous owned speech-worker interruption path and returns false when speech is unavailable. Like Python it does not cancel sound output. Maintainer confirms native D-Bus integration works in live testing with Toby Doom on 2026-10-22. Individual API calls and output modalities were not itemized. See docs/testing/release-acceptance.md. +nvda-controller-ssml-rejection,src/cthulhu/dbus_service.py,remote,Reject invalid or unsupported NVDA Controller 2 SSML without claiming mark or completion support,Storm Dragon,internal/remote,implemented,go test ./internal/remote -count=1; CTHULHU_NATIVE_DBUS_TEST=1 go test ./internal/remote -run '^TestNativeSessionBusSelfVoice$' -count=1,Private session-bus proof passes the real SpeakSsml signature and unsupported result.,,,,Malformed XML or a non-speak root returns Windows ERROR_INVALID_PARAMETER 87. Valid speak-root SSML returns ERROR_NOT_SUPPORTED 50 matching Python because mark callbacks and completion semantics are unavailable. +flat-review-keys,src/cthulhu/flat_review_presenter.py,review,Navigate and present content with desktop and laptop review keys,Storm Dragon,internal/input internal/review internal/app internal/platform/xorg,in-progress,DISPLAY=:0 go test -race ./internal/atspi ./internal/review ./internal/app ./internal/input ./internal/platform/xorg ./internal/presentation -count=1; DISPLAY=:0 python3 tests/native_atspi.py; DISPLAY=:0 python3 tests/native_x11.py,Private Xvfb tests pass all nine desktop and laptop sequential review commands; both laptop release orders; NumLock numeric keypad typing; laptop keypad pass-through; existing command and shutdown checks.,,Maintainer reports current flat review working well after the previous day's fixes on 2026-10-22. This is general live-use acceptance rather than confirmation of every parity feature or historical fixture. See docs/testing/release-acceptance.md.,Maintainer reports all Braille behavior testable on Orbit passes on 2026-10-22. The display has no routing keys; physical cursor routing is untested. See docs/testing/release-acceptance.md.,Basic previous/current/next line word and code-point character commands are wired to owned window layout and the existing review worker. Sequential line boundaries announce top or bottom of screen. Capture limits are reported explicitly. Native GTK text navigation and edit recovery pass. Mode toggling same-object caret following after leaving review state/value zones advanced bindings mouse review and full application parity remain pending. See docs/testing/flat-review-robustness.md for the current capture comparison and clipped-text regression. Parity review corrections and remaining physical gates: docs/testing/parity-review-follow-up.md. Numpad 2 supports phonetic double press; Numpad 5 and 8 support literal and phonetic spelling on second and third presses within 500 ms. Shared desktop/laptop routing plus private X11 consumption and OCR cursor tests pass; live spelling listening remains pending. See docs/testing/phonetic-review.md. +preferences-basic-speech,src/cthulhu/cthulhu_gui_prefs.py,settings,Open accessible basic speech preferences and apply or save settings,Storm Dragon,internal/preferences internal/app internal/config,implemented,go test -race ./... -count=1; python3 tests/native_preferences.py; python3 tests/native_x11.py,Private Xvfb GTK and command checks pass; maintainer accepted save shutdown restart and restored settings on physical Xorg on 2026-09-13; broader desktop traversal pending,,Maintainer confirms speech preferences; previews; Apply and Cancel; saved settings; and interruption-key settings work in live testing on 2026-10-22. See docs/testing/release-acceptance.md.,,Apply and OK update the active schema-v2 profile while preserving other profiles and application mappings; Apply stays open and OK closes. Rate pitch and volume sliders are directly editable for every voice type and preview immediately without committing settings; untouched fields retain inheritance and automatic uppercase pitch; optional Speech Dispatcher defaults queries have bounded fallback values; Cancel restores the last applied voice configuration. Independent capital pitch beep and cap checkboxes replace the capitalization style dropdown; default pitch is enabled and all combinations apply to custom echo and spelling. Private GTK traversal and Apply/reload plus SSIP and persistence checks pass; general speech preferences listening is accepted by the maintainer on 2026-10-22; control-specific Braille acceptance was not separately stated. Direct-slider missing-file private reader GTK and SSIP checks are documented in docs/testing/speech-preferences.md; live acceptance of this simplification remains pending. Explicitly selected legacy files remain session-only and cannot be overwritten. Advanced preferences and importer remain pending. Phonetic character hints is an unchecked Speech Reading option; plain Left/Right character navigation can append a cancellable 300 ms phonetic hint. Private GTK default toggle Apply/reload and cancellation checks pass; physical listening remains pending. See docs/testing/phonetic-review.md. +review-component-geometry,src/cthulhu/flat_review.py,review,Capture component screen bounds and visibility for flat-review clipping,Storm Dragon,internal/atspi,implemented,DISPLAY=:0 go test ./internal/atspi -count=1; DISPLAY=:0 python3 tests/native_atspi.py,Private Xvfb D-Bus GtkBox tests verify screen bounds resize invalidation changed dimensions hide invalidation and recapture. Physical acceptance deferred by maintainer on 2026-09-14.,,,,Geometry queries run only during owned-tree capture. Bounds and visibility events invalidate geometry without removing identities. Negative coordinates overflow-safe clipping malformed geometry and concurrent invalidation have unit tests. Component bounds do not establish occlusion text ranges zones reading order or flat-review key support. +review-visible-text,src/cthulhu/flat_review.py,review,Capture bounded visible text with character offsets and screen clipping,Storm Dragon,internal/atspi,in-progress,DISPLAY=:0 go test -race ./internal/atspi ./internal/review ./internal/app ./internal/parity -count=1; DISPLAY=:0 python3 tests/native_atspi.py,Private ListBox and GtkBox capture edit clipping hidden-text and password-exclusion checks pass. Physical acceptance deferred.,,Maintainer reports current flat review working well after the previous day's fixes on 2026-10-22. This is general live-use acceptance rather than confirmation of every parity feature or historical fixture. See docs/testing/release-acceptance.md.,,Exact Unicode offsets and owned ranges include captured caret offsets. Text caret and geometry events invalidate cached text without retiring identities. Capture budgets are 65536 characters and 256 visible spans per object and 1 MiB per tree. Bounded line-rectangle discovery supports large objects without character rectangles; oversized lines use viewport glyph locations and bounded text spans. Zero-area glyphs no longer discard other visible text. Known unavailable objects and child subtrees leave healthy content reviewable with diagnostic omission counts and standard screen-boundary messages. Verified synthetic Text on controls uses accessible names or child content; tabs retain their label beside Close controls. Chromium address-value geometry remains unavailable. Root failures and aggregate layout budgets remain fatal. Private GTK fixtures and worker tests pass; physical speech and Braille acceptance remain pending. See docs/testing/flat-review-robustness.md. +date-time-commands,src/cthulhu/date_and_time_presenter.py,command,Speak local time with Cthulhu+T and date with a double tap using saved formats,Storm Dragon,internal/input internal/app internal/preferences internal/config,implemented,go test ./... -count=1; focused race checks; native keyboard double-tap checks,Private Xvfb press-time and both-release-order checks passed; physical Xorg pending,,Maintainer confirms date/time; spoken version; window-title; and clipboard-reading commands pass live testing on 2026-10-22. See docs/testing/release-acceptance.md.,Pending braille,All 7 Python time and 16 Python date format choices are wired including locale seconds word numeric full and abbreviated variants; see docs/testing/time-date.md. +notifications,src/cthulhu/notification_presenter.py;src/cthulhu/scripts/apps/notification-daemon/script.py;src/cthulhu/scripts/apps/notify-osd/script.py;src/cthulhu/mako_notification_monitor.py,notification,Present provider notifications save history expose mako live actions speak the last notification and open the notification-list GUI,Storm Dragon,internal/notification internal/app internal/notificationui internal/atspi internal/input,implemented,NO_COLOR=1 GOCACHE=/tmp/cthulhu-build-cache go test ./... -count=1; NO_COLOR=1 python3 tests/native_notifications.py,,,Automated speech-queue history list-state and list-action assertions and private GUI checks pass. Maintainer confirms notification announcements and the notification list work in live testing on 2026-10-22. See docs/testing/release-acceptance.md.,Mako notification announcements implement Braille flashes through notificationAnnouncer.Announce. Provider-specific physical display acceptance was not separately stated.,Go registers window-create and accessible-name events maps notification-daemon mate and xfce4 providers handles notify-osd gauge and name events keeps a 55-entry history and adds Cthulhu+N plus Cthulhu+Ctrl+N. The modal accessible list opens in a GTK helper process with sortable rows copy dismiss clear close dynamic actions and mako live refresh. Parity review corrections and remaining physical gates: docs/testing/parity-review-follow-up.md. +ordinary-key-speech-interrupt,src/cthulhu/input_event.py,input,Interrupt speech on an ordinary key press even if focus does not move,,internal/input internal/app,implemented,go test ./internal/input ./internal/app -run TestProcessInputEventsInterruptsSpeechOnKeyPress -count=1,,,,,Python KeyboardEvent._present interrupts on press outside game mode. Go interrupts on every observed press by default; Speech preferences can restrict interruption to common or recorded keys. Physical FastSMRW table-boundary listening remains pending. +table-cell-selection-speech,src/cthulhu/speech_generator.py; src/cthulhu/scripts/default.py,speech,Omit selected from table-cell focus speech and avoid deselection chatter during movement,,internal/presentation internal/app,implemented,go test ./internal/presentation ./internal/app -count=1,,,,,Selected table-cell focus omits the state; a focused selected-state event can still announce selected. Physical FastSMRW listening remains pending. +braille-focused-text-routing,src/cthulhu/braille.py,braille,Route display cells to the native focused text caret,,internal/braille internal/app internal/atspi,in-progress,go test -race -tags brlapi ./internal/braille ./internal/app ./internal/atspi -count=1; python3 tests/native_atspi.py,Private GTK/Xvfb routes Unicode and EOL carets and rejects stale content and old focus. Physical Xorg pending.,,,Physical cursor routing untested: the maintainer's Orbit has no routing keys. General reading and panning pass on Orbit as confirmed on 2026-10-22; BRLTTY ownership recovery remains unverified. See docs/testing/release-acceptance.md.,Frame IDs and panned Unicode offsets return through the helper; the GLib owner revalidates focus and source text. Component actions and mouse fallback; virtual browser carets; contracted and review routing remain pending. See docs/testing/braille.md. +braille-focused-object-formatting,src/cthulhu/formatting.py;src/cthulhu/braille_generator.py;src/cthulhu/object_properties.py,braille,Format focused text and common controls for braille,,internal/app internal/atspi,in-progress,go test ./internal/app ./internal/atspi ./internal/braille -count=1,Private GTK/Xvfb verifies native Unicode capture and caret offsets.,,,Maintainer confirms physical native application reading and panning pass on Orbit on 2026-10-22. This is general live-use acceptance; application-specific parity remains separately tracked. See docs/testing/release-acceptance.md.,Default verbose long-role subset: control indicators; expansion; values; EOL and text state suffixes. Full ancestor/group/table context; labels distinct from names; masks; translation; preferences and application overrides remain pending. Reference inspected at local Python b9dd2eb2bf96143309ba0c724c47f86d978826ef; the original inventory oracle commit is unavailable in that checkout. See docs/testing/braille.md. +editable-text-selection,src/cthulhu/scripts/default.py;src/cthulhu/script_utilities.py,editing,Speak changed selected or unselected text in a focused editable control,,internal/atspi internal/app,implemented,go test ./internal/app ./internal/input -run 'TestTextSelection|TestIntent' -count=1; CTHULHU_NATIVE_BROWSER_TESTS=selection python3 tests/native_browser.py,Private Brave/Xvfb fixture verified native selection offsets and text in the browser input.,,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,Physical selection dots pending.,The Go event loop compares bounded native selection ranges and excludes password text and autocomplete; browse-mode document selection is tracked separately in web-browse-selection. See docs/testing/editing-selection.md. +editable-cut-paste-feedback,src/cthulhu/scripts/default.py;src/cthulhu/script_utilities.py,editing,Announce cut and paste after editable text mutations,,internal/input internal/app,implemented,go test ./internal/app ./internal/input -run 'TestClipboardFeedback|TestIntent' -count=1; CTHULHU_NATIVE_BROWSER_TESTS=selection python3 tests/native_browser.py,Private Brave/Xvfb fixture verified Ctrl+X deletion and Ctrl+V insertion events.,,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,Physical short-message braille pending.,Go says cut or pasted from clipboard once after a matching focused editable mutation; subsequent paste text and caret events do not interrupt the message. Python uses full or brief clipboard messages. See docs/testing/editing-selection.md. +editable-copy-feedback,src/cthulhu/scripts/default.py,editing,Confirm a successful copy to the clipboard,,internal/input internal/platform/xorg internal/app,implemented,go test ./internal/input ./internal/app -run 'TestIntent|TestCopyFeedback' -count=1; CTHULHU_NATIVE_X11=1 go test ./internal/platform/xorg -run TestNativeClipboardOwnerChange -count=1,Private Xvfb observed XFixes clipboard ownership change after copy.,,Maintainer confirms thorough live testing of native application and terminal workflows; typing echo; selection; clipboard feedback; and object navigation on 2026-10-22. These workflows pass. See docs/testing/release-acceptance.md.,Short-message braille pending.,Go says copied to clipboard once after Ctrl+C and an X11 clipboard ownership change; it stays silent if ownership does not change. See docs/testing/editing-selection.md. +web-browse-selection,src/cthulhu/scripts/web/script.py;src/cthulhu/script_utilities.py,web,Select document text with Shift and Ctrl+Shift arrows in browse mode,,internal/review internal/atspi internal/app,implemented,Private Brave modes fixture verifies selected and unselected speech plus braille dots within one page text object and selected speech from a heading into a paragraph.,,,Maintainer confirms correct browser selection and deselection feedback using Shift+arrows and Ctrl+Shift+arrows on 2026-10-22. This supersedes the 2026-10-03 missing-announcement report. See docs/testing/release-acceptance.md.,,The browser can perform native selection without a Go selection command. Go follows native selection within text objects and across the tested heading-to-paragraph transition. The maintainer checks clipboard contents to confirm selection. See docs/testing/reading-selection-diagnostics.md. +web-browse-braille-line,src/cthulhu/caret_navigation.py;src/cthulhu/scripts/web/script.py;src/cthulhu/scripts/web/braille_generator.py,braille,Follow accepted browse-caret and structural navigation with the current native text line and virtual cursor,,internal/atspi internal/review internal/app,implemented,"go test -race ./internal/app ./internal/review ./internal/atspi ./internal/braille -count=1; CTHULHU_NATIVE_BROWSER_TESTS=modes,tables,keys python3 tests/native_browser.py",Private Brave/Xvfb mode/table/key checks pass on 2026-10-02; physical Xorg pending.,,Existing browse speech assertions pass in the private fixture.,Queued native line and cursor frames pass. Maintainer confirms physical browser reading and panning pass on Orbit on 2026-10-22. Physical HumanWare NLS eReader acceptance and cursor routing remain unverified. See docs/testing/release-acceptance.md.,Reads run on the bounded navigation worker only while braille is enabled; preserve spaces and Unicode offsets. Table frames retain existing cell presentation. Complete cross-object visual-line assembly and virtual-caret routing remain open. See docs/testing/braille.md. +web-explicit-link-names,src/cthulhu/scripts/web/script_utilities.py:_treatObjectAsWhole,web,Read explicitly named links as whole objects without losing descendant badges or ordinary link navigation,Storm Dragon,internal/atspi internal/review internal/app,in-progress,"go test -race ./...; CTHULHU_NATIVE_BROWSER_TESTS=namedlinks,browser,live,keys python3 tests/native_browser.py",Private Brave/Xorg named-link and key checks passed,,Maintainer confirms extensive live browser testing passes in Firefox and Chromium-based browsers on 2026-10-22; element lists and jumping to selected items are explicitly confirmed. See docs/testing/release-acceptance.md. Steam-specific named-link and game-card listening remains unconfirmed.,Named-link browse braille uses the full accessible label; physical check pending,docs/testing/steam-browser.md; actual Steam explicit-name exposure and game-card acceptance remain live gates +steam-notifications,src/cthulhu/scripts/apps/steamwebhelper/script.py;tests/test_steam_notification_regressions.py,web,Coalesce verified Steam background toasts and present once through speech braille and notification history,Storm Dragon,internal/webscripts internal/atspi internal/app,implemented,go test -race ./...; python3 tests/native_webscripts.py,Private GTK/AT-SPI process matching and alert-root capture passed,,Event-loop background delivery and Chromium isolation pass. Maintainer confirms Steam notifications work in live testing on 2026-10-22. See docs/testing/release-acceptance.md.,Event-loop flash verified; physical Steam toast display pending,docs/testing/steam-browser.md; independent root and bus queues deliberately prevent unrelated toast timestamps from merging +libreoffice-calc-basic,Orca src/orca/scripts/apps/soffice/script.py; Orca src/orca/ax_utilities_table.py; Orca src/orca/speech_generator.py,libreoffice,Present Calc cells and recover logical focus around editing and sheet changes,Storm Dragon,internal/app internal/atspi internal/presentation,in-progress,GOCACHE=/tmp/cthulhu-go-cache go test -race ./internal/atspi ./internal/app ./internal/presentation -count=1; /usr/bin/python3 tests/native_libreoffice.py,Private real LibreOffice Calc 26.2.6.3 on Xvfb and a private AT-SPI bus validates cell movement blanks F2 typing Escape Enter and sheet changes.,,Recorded speech assertions pass. Maintainer confirms basic cell navigation and editing work in live use on 2026-10-22. Selection and sheet-switching acceptance await real-world testing. See docs/testing/release-acceptance.md.,Recorded value and coordinate frames pass; physical Braille and editor routing acceptance pending.,Current Orca is the primary Office reference. Dedicated application policy follows verified process identity after foreground/security gates; native capture remains bounded. Formula presence and explicit formula/basic Where Am I speech are implemented with bounded uncached cell attributes and recorded real-Calc checks; physical acceptance remains pending. Bounded selection deltas for small ranges and row/column selections plus count summaries for large selections and Select All are implemented. Real Calc checks cover disjoint cells and huge selections; physical speech/input/Braille acceptance remains pending. Dynamic row and column headers now use session choices scoped by provider bus document view window and exact sheet name; native reads are bounded to two cells. Four assignable commands preserve existing shortcuts. Private i3 Calc checks cover heading edits independent axis clearing sheet round trips both workbook-return directions with distinct headings and Find and Replace typing/cancellation. Frame activation and X11 foreground recovery avoid stale descendant searches; physical speech/input/Braille acceptance remains pending. Full-row reading Writer workflows and full topology reporting for large selections remain open. See LIBREOFFICE_SUPPORT.md. +steam-shader-progress,Steam shader dialog AT-SPI events,web,Report Steam Vulkan shader percentages through shared progress output,,internal/webscripts internal/app,in-progress,go test ./internal/app ./internal/webscripts ./internal/presentation ./internal/sound -count=1; python3 tests/native_progress.py; CTHULHU_NATIVE_BROWSER_TESTS=progress python3 tests/native_browser.py,Private GTK and Brave HTML/ARIA progress checks passed.,,Tone requests verified; live Steam listening pending.,Unrelated Braille ownership covered by unit tests; physical check pending.,English static shader-status name changes only; verified steamwebhelper identity; see PROGRESS_BARS.md. +wayland-shared-keyboard-access,src/cthulhu/input_event_manager.py,input,Monitor keys and grab reader shortcuts through the shared accessibility keyboard interface,Storm Dragon,internal/platform/wayland internal/app internal/sessionbus,in-progress,Private dbus-run-session race tests cover wire protocol runtime dispatch configuration rollback secure transitions and cleanup; go test ./... -count=1; python3 tests/check_speech.py,Existing native_x11.py keyboard harness passed; browser tabs and editing passed; browser modes passed on isolated rerun after one failure whose cause was not established.,Shared D-Bus fixture passed without an X display. On 2026-10-22 the maintainer reports minimal live testing and user reports of poorer behavior than native Xorg. Specific compositor and physical key-suppression acceptance remain unverified. See docs/testing/release-acceptance.md.,Minimal live Wayland testing reported by the maintainer on 2026-10-22; broad listening acceptance is not established.,Pending physical Braille on Wayland,No compositor-specific code. See WAYLAND_SUPPORT.md for supported commands limitations and live acceptance. X11 production listeners are unchanged; the suspension probe now links its existing xkbcommon dependency. +web-browse-recovery-activation,Orca src/orca/scripts/web/script_utilities.py; master:src/cthulhu/scripts/web/script.py,web,Recover dynamic browse positions and activate custom clickables silently,,internal/atspi internal/review internal/app,implemented,"go test -race ./... -count=1; python3 tests/native_browser.py; python3 tests/native_browser_navigation.py; python3 tests/native_firefox.py; go test -race ./internal/atspi ./internal/review ./internal/app -count=1; CTHULHU_NATIVE_BROWSER_TESTS=generatedlinks,replacement,tooltips,fragments,namedlinks,linkedheadings python3 tests/native_browser.py",Private Chromium and Firefox fixtures; real-reader changing-page and activation checks use private Xvfb and D-Bus. On 2026-10-22 the maintainer confirmed reading the entire original Techrights article in Brave without looping after the generated-link recovery fix. See docs/testing/browser-release-review.md#generated-link-recovery-acceptance-2026-10-22.,,Maintainer confirms extensive live browser testing passes in Firefox and Chromium-based browsers on 2026-10-22; element lists and jumping to selected items are explicitly confirmed. See docs/testing/release-acceptance.md. Original Techrights full-article reading accepted after the generated-link fix on 2026-10-22; see docs/testing/browser-release-review.md#generated-link-recovery-acceptance-2026-10-22.,Selection-collapse regression and native mode frames covered; physical routing remains pending.,See docs/testing/browser-release-review.md for findings and live acceptance. No full Orca parity claim. October 22 generated-link recovery retains the same parent and adjacent sibling identities; refreshes navigation-defunct child order and disappearing native text; and gives Read All navigation recovery with document-generation rejection. The page-CSS fixture reproduces the first fix failure and passes after correction. Full-article reading on the original Brave page is accepted; separate manual reverse-navigation Read All activation and physical Braille checks were not reported. The separate dynamic-page flat-review failure remains open. +web-structural-lists,Orca src/orca/structural_navigator.py; src/orca/structural_navigator_command_definitions.py,web,List browser elements and move to a selected item,,internal/input internal/review internal/interaction internal/app,implemented,"go test -race ./... -count=1; CTHULHU_NATIVE_BROWSER_TESTS=lists,keys,document,modes,editing python3 tests/native_browser.py; python3 tests/native_internal_ui.py",Private Brave/Xvfb list workflow covers 302 links hidden content current row selection Escape clickables heading level and empty list.,,Maintainer confirms extensive live browser testing passes in Firefox and Chromium-based browsers on 2026-10-22; element lists and jumping to selected items are explicitly confirmed. See docs/testing/release-acceptance.md.,Shared internal UI frames covered; physical Braille acceptance pending.,25 browse shortcuts use Alt+Shift. All Orca list types are registered including unbound annotations internal frames and math. Exact targets and page ownership are validated before selection. See docs/testing/browser-lists.md for manual review and regression checks. +mozilla-leaf-text-reading,Orca src/orca/scripts/web/script_utilities.py,web,Read native heading and link text leaves in Firefox and Thunderbird,,internal/atspi tests/native_mozilla.py,implemented,python3 tests/native_firefox.py; CTHULHU_BINARY=/tmp/cthulhu-mozilla-review /usr/bin/python3 tests/native_mozilla.py; go test -race ./internal/atspi ./internal/review ./internal/presentation ./internal/app -count=1 -timeout=120s,Private Firefox 158.0 and Thunderbird 158.0 sessions each cover 17 navigation commands and Read All with zero native caret synchronization errors.,,Maintainer confirms extensive live browser testing passes in Firefox and Chromium-based browsers on 2026-10-22; element lists and jumping to selected items are explicitly confirmed. See docs/testing/release-acceptance.md.,Shared Chromium selection and routing checks passed; physical Mozilla Braille acceptance pending.,Shared document text metrics now include heading and link roles. Native Firefox metadata assertion failed before the fix. See docs/testing/mozilla-reading.md. Thunderbird folders message lists and composition remain outside this reading baseline. +thunderbird-local-mail-composition,Orca src/orca/scripts/apps/Thunderbird/script.py;src/orca/script_utilities.py,application,Navigate local folders and message tabs; select messages; compose replies and forwards; save and add attachments,,internal/atspi internal/app tests/native_thunderbird.py,implemented,go test -race ./internal/atspi ./internal/app ./internal/review ./internal/presentation -count=1 -timeout=120s; CTHULHU_BINARY=/tmp/cthulhu-mozilla-review /usr/bin/python3 tests/native_thunderbird.py,Private Thunderbird 158.0 HTML and plain-text local mailbox checks cover message-tab return; Subject and body editing; reply and reply-all recipients with Cc; inline forwarding; exact selected rows after Shift and Ctrl navigation; received attachment saving with content verification; and adding a local file to an unsent draft.,,SSIP verifies focus handoff and row roles; selection toggling; Subject and body echo; reply and forward editing; attachment menus and picker return. Maintainer relays third-party confirmation on 2026-10-22 that message reading; replies; forwards; and attachments work well in live testing. See docs/testing/release-acceptance.md.,Event-loop regression checks paragraph cursor and routing metadata; physical display acceptance pending.,Foreground replacement requires a registered application and fresh complete window membership. Editable paragraph events belong only to their focused editable document. Title echoes require owned editable focus and recent editing plus unchanged title prefix/suffix; unrelated status titles still announce. See docs/testing/thunderbird-workflows.md; no sending remote mailbox or page-load-option acceptance claimed. +flatpak-foreground-identity,src/cthulhu/script_utilities.py:canBeActiveWindow,focus,Correlate Flatpak accessibility providers with the X11 foreground across PID namespaces and D-Bus proxies,,internal/platform/xorg internal/atspi,in-progress,go test -race ./internal/platform/xorg ./internal/atspi ./internal/app -count=1; CTHULHU_FOREGROUND_PID=1 python3 tests/native_atspi.py,Private XRes lookup and fallback; real proxy with matching and different synthetic instance metadata; GTK Qt and Brave ownership checks,,Actual Flatpak Steam speech pending,Physical Braille pending; original report also has helper geometry errors,docs/testing/flatpak-foreground.md; preserves active state geometry and sibling ownership checks; no application name exception +present-window-title,Orca src/orca/where_am_i_presenter.py;src/orca/where_am_i_presenter_command_definitions.py,command,Read the foreground window title with Cthulhu+Numpad Enter on desktop or Cthulhu+Slash on laptop,,internal/input internal/app internal/platform/xorg,implemented,go test ./internal/input ./internal/app ./internal/platform/xorg -count=1; focused title command race checks; python3 tests/check_speech.py,Private Xvfb command dispatch verifies both layout bindings and both release orders. Private X11 and AT-SPI event loop repeats the current title with automatic changes disabled.,,Maintainer confirms date/time; spoken version; window-title; and clipboard-reading commands pass live testing on 2026-10-22. See docs/testing/release-acceptance.md.,Braille flash queue assertion passed; physical display acceptance pending.,Reuses copied foreground title metadata and the owned accessible title. Explicit requests bypass automatic-title policy and duplicate suppression without moving focus. Stale native epochs and unrelated native windows cannot supply a title. Lock and terminal handoff remain enforced. Double-press status-bar reading is outside this change. See tests/window_titles.md. +edit-field-relation-labels,src/cthulhu/generator.py:_generateLabel;src/cthulhu/script_utilities.py:displayedLabel,speech,Announce relation-only labels for unnamed edit fields,,internal/atspi internal/presentation,implemented,CTHULHU_NATIVE_EDIT_LABELS=1 python3 tests/native_atspi.py; go test ./... -count=1; go vet ./...,Private GTK/Xvfb verifies single and multiple labels plus existing names and password exclusion. Read-only live irctest capture verifies all three settings labels. Maintainer confirmed installed-reader label speech on physical Xorg on 2026-10-20.,,Formatted speech includes each label. Maintainer confirmed the installed reader speaks irctest settings field labels on 2026-10-20.,Physical Braille check pending.,Direct LABELLED_BY targets supply an empty text or entry or password-field name. Queries and output are bounded; explicit names are preserved. Human diff review remains required before submission. +mozilla-hypertext-reading,src/cthulhu/scripts/web/script.py;src/cthulhu/scripts/web/script_utilities.py,web,Read native heading and link text plus parent text around embedded children without Tab caret echoes interrupting link labels,,internal/atspi internal/review internal/app,implemented,"go test ./... -count=1; go test -race ./internal/review ./internal/atspi ./internal/app -count=1; python3 tests/native_firefox.py; CTHULHU_NATIVE_BROWSER_TESTS=fragments,document,selection,namedlinks python3 tests/native_browser.py",Merge review on 2026-10-20: four parent-text regressions fail against testing before the merge and pass after resolution. Private Firefox baseline and Chromium fragments document selection named-link and editing checks pass.,,Maintainer confirms extensive live browser testing passes in Firefox and Chromium-based browsers on 2026-10-22; element lists and jumping to selected items are explicitly confirmed. See docs/testing/release-acceptance.md. The original Thunderbird regression message was not separately identified.,Repeated parent-fragment cursor and native routing offsets tested; physical Braille pending.,Hypertext traversal retains parent offsets around single-character embedded children; named-link labels retain virtual character and word offsets. Password subtrees remain excluded. Read and Tab through an HTML email; reverse direction; verify Firefox and Chromium links selection and address-bar editing before submission. Human diff review and original-message live acceptance remain required. +speech-interruption-preferences,src/cthulhu/input_event.py,input,"Choose all keys, common stop keys, or recorded individual interruption keys in Speech preferences",,internal/input internal/config internal/preferences internal/app,implemented,go test ./internal/input ./internal/config ./internal/preferences ./internal/app -run 'Interruption|Interrupt' -count=1,"Private GTK/Xvfb test verifies mode selection, focus traversal, special/modifier/Page Up/multimedia recording, finish/cancel, Apply and draft reload.",Physical compositor acceptance pending.,Maintainer confirms speech preferences; previews; Apply and Cancel; saved settings; and interruption-key settings work in live testing on 2026-10-22. See docs/testing/release-acceptance.md.,Physical display acceptance pending.,All keys remains default. Reader commands retain explicit interruption; unselected keys preserve queued speech and Say All. Control+Enter finishes and Control+Escape cancels without recording the finishing modifier. Settings persist per profile. diff --git a/tests/browser-catalog.html b/tests/browser-catalog.html new file mode 100644 index 0000000..13ec048 --- /dev/null +++ b/tests/browser-catalog.html @@ -0,0 +1,26 @@ + +Cthulhu Browser Probe + + +

Video catalog

+
+ + diff --git a/tests/browser-changing.html b/tests/browser-changing.html new file mode 100644 index 0000000..eb28d7c --- /dev/null +++ b/tests/browser-changing.html @@ -0,0 +1,32 @@ + + + +Cthulhu Changing Document Probe + +

Changing document

+
+

Statistics

+

Current total 10000 units

+

Following stable line

+
Visible custom label
+
+ + + + diff --git a/tests/browser-editor.html b/tests/browser-editor.html new file mode 100644 index 0000000..95323f8 --- /dev/null +++ b/tests/browser-editor.html @@ -0,0 +1,7 @@ + +Cthulhu Browser Probe + +

Draft:

Following line

+

Other text

+ + diff --git a/tests/browser-fragments.html b/tests/browser-fragments.html new file mode 100644 index 0000000..619b760 --- /dev/null +++ b/tests/browser-fragments.html @@ -0,0 +1,31 @@ + + + +Cthulhu Browser Probe: fragmented response + + +

Fragmented response

+

One two three.Four five six.

+

Next paragraph.

+

Before ordinary link after.

+

Split heading

+
Code first
+Code second
+

Member rank

+
+

Join Date

+ +

Mixed  text.

+

★

+ +

Embedded suggestion

+
+

Review the code.

Report actionable issues.

+
+

After the suggestion.

+ + diff --git a/tests/browser-lines.html b/tests/browser-lines.html new file mode 100644 index 0000000..ca8e6a7 --- /dev/null +++ b/tests/browser-lines.html @@ -0,0 +1,17 @@ + + + +Cthulhu Browser Probe: logical lines + +

Logical line probe

+ +

What's on your mind?

+
First
+Second
+Code text + +
Truncated preview…
+

First line
猫🐈…

+ + diff --git a/tests/browser-linked-headings.html b/tests/browser-linked-headings.html new file mode 100644 index 0000000..6be5b96 --- /dev/null +++ b/tests/browser-linked-headings.html @@ -0,0 +1,18 @@ + +Cthulhu Linked Headings Probe + + +

Inside heading link

+

Inside destination

+

Outside heading link

+

Outside destination

+

#1 Username Example date

+

Post destination

Date destination

+

Ordinary heading

+
Choose: First link and Second link
+

First destination

Second destination

+
Offscreen first topic
+

First sound destination

+
Offscreen second topic
+

Second sound destination

+ diff --git a/tests/browser-lists.html b/tests/browser-lists.html new file mode 100644 index 0000000..620dc12 --- /dev/null +++ b/tests/browser-lists.html @@ -0,0 +1,20 @@ + +Cthulhu Browser Probe + +

Browser foundation

+

Second heading

+First link +Second link + +
Custom clickable
+

Link destination

+ + + diff --git a/tests/browser-live.html b/tests/browser-live.html new file mode 100644 index 0000000..40ebeb5 --- /dev/null +++ b/tests/browser-live.html @@ -0,0 +1,31 @@ + +Cthulhu Browser Probe + + +
Download status: Waiting
+
Account status:
+
Outer context: Waiting
+
Busy status: Waiting
+ + diff --git a/tests/browser-named-links.html b/tests/browser-named-links.html new file mode 100644 index 0000000..dfdc92e --- /dev/null +++ b/tests/browser-named-links.html @@ -0,0 +1,13 @@ + +Cthulhu Browser Probe + + + +2 +Ordinary multiline link +Useful image label + +Username 🧻 +

After emoji

+. + diff --git a/tests/browser-next.html b/tests/browser-next.html new file mode 100644 index 0000000..730d193 --- /dev/null +++ b/tests/browser-next.html @@ -0,0 +1,7 @@ + +Cthulhu Second Page + +

Fresh page heading

+

Fresh page content.

+Return to browser probe + diff --git a/tests/browser-positions.html b/tests/browser-positions.html new file mode 100644 index 0000000..fa43a8f --- /dev/null +++ b/tests/browser-positions.html @@ -0,0 +1,28 @@ + + + +Cthulhu Browser Probe + +
    +
  • First
  • +
  • Middle
  • +
  • Last
  • +
+
    +
  • Virtual item
  • +
  • Unknown size
  • +
+
+
Nested
+
+
+
First action
+
+
Second action
+
+
+ Choose a value +
First
+
Second
+
+ diff --git a/tests/browser-progress.html b/tests/browser-progress.html new file mode 100644 index 0000000..32ab61a --- /dev/null +++ b/tests/browser-progress.html @@ -0,0 +1,19 @@ + + + +Cthulhu Browser Probe + + + + +
+Processing Vulkan shaders (0%) + + diff --git a/tests/browser-replaced-feed.html b/tests/browser-replaced-feed.html new file mode 100644 index 0000000..4466a36 --- /dev/null +++ b/tests/browser-replaced-feed.html @@ -0,0 +1,12 @@ +Cthulhu Browser Probe + +

Earlier post

Middle post

Later post

+ diff --git a/tests/browser.html b/tests/browser.html new file mode 100644 index 0000000..ab2cdfb --- /dev/null +++ b/tests/browser.html @@ -0,0 +1,45 @@ + +Cthulhu Browser Probe + + +

Browser foundation

+

Reading section

+

Plain document text with Café and 猫.

+
  • Example item
  • Registered: September 2026
+
Section separator
+Example link + + + + +

Link destination

+

Ordinary unfocusable heading

+

Text after the ordinary heading.

+ + + + +
+ + + + + + +
Navigation probe
ItemCount
ApplesFive
Merged total
Last item
+ diff --git a/tests/check_speech.py b/tests/check_speech.py new file mode 100755 index 0000000..5fa1eba --- /dev/null +++ b/tests/check_speech.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +"""Run required speech regressions, or check each commit tip in a Git push.""" + +import json +import os +from pathlib import Path +import subprocess +import sys +import tempfile + +from native_test_session import run_private_session + + +requiredTests = { + "TestSpeechWorkerRadioSelectionDoesNotCancelLabel", + "TestPrivateWineReviewUpdatesPreserveQueuedTitleSpeech", + "TestPrivateWineTitleSurvivesReviewFocusBurst", + "TestAutomaticTitleSurvivesMovementRepeatsBeforeAndAfterDelivery", + "TestAutomaticTitleStillStopsForExplicitInput", + "TestTitleProtectionDoesNotChangeOrdinaryReading", + "TestRepeatTrackerRecognizesNativeSequences", +} + + +def run_checks(sourceRoot: Path) -> None: + testEnv = os.environ.copy() + # Git exports repository paths to hooks. Tests run against the snapshot. + for name in tuple(testEnv): + if name.startswith("GIT_"): + del testEnv[name] + testEnv.pop("DISPLAY", None) + testEnv.pop("WAYLAND_DISPLAY", None) + testEnv["CTHULHU_WINE_TITLE_DBUS"] = "1" + command = [ + "dbus-run-session", "--", "go", "test", "-json", "-race", "-count=1", + "-timeout=60s", "-run", "^Test.*(Title|Repeat|Interrupt)|^Test(SpeechWorker|Cancel|WineReview)", + "./internal/app", "./internal/input", "./internal/speech", "./internal/wine", + ] + print("Checking speech queues, Wine metadata and key interruption...", flush=True) + result = run_private_session(command, cwd=sourceRoot, env=testEnv, text=True, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False) + passedTests = set() + diagnostics = [] + for line in result.stdout.splitlines(): + try: + event = json.loads(line) + except ValueError: + diagnostics.append(line + "\n") + continue + if "Output" in event: + diagnostics.append(event["Output"]) + if event.get("Action") == "pass" and "Test" in event: + passedTests.add(event["Test"]) + missingTests = requiredTests - passedTests + if result.returncode or missingTests: + print("".join(diagnostics), end="", file=sys.stderr) + if missingTests: + print("Required tests did not pass (missing or skipped): " + + ", ".join(sorted(missingTests)), file=sys.stderr) + raise RuntimeError("speech regression check failed") + print("Speech regression checks passed.", flush=True) + + +def check_push(repoRoot: Path) -> None: + checkedCommits = set() + for line in sys.stdin: + localRef, localCommit, remoteRef, remoteCommit = line.split() + if set(localCommit) == {"0"} or localCommit in checkedCommits: + continue + checkedCommits.add(localCommit) + print(f"Checking {localRef} ({localCommit[:12]}) before push...", flush=True) + with tempfile.TemporaryDirectory(prefix="cthulhu-push-") as directory: + sourceRoot = Path(directory) + with tempfile.TemporaryFile() as archive: + subprocess.run(["git", "archive", "--format=tar", localCommit], + cwd=repoRoot, stdout=archive, check=True) + archive.seek(0) + subprocess.run(["tar", "-xf", "-", "-C", str(sourceRoot)], + stdin=archive, check=True) + run_checks(sourceRoot) + + +def main() -> int: + repoRoot = Path(__file__).resolve().parents[1] + try: + if len(sys.argv) > 1 and sys.argv[1] == "--pre-push": + check_push(repoRoot) + else: + run_checks(repoRoot) + except (OSError, ValueError, RuntimeError, subprocess.CalledProcessError) as error: + print(f"Speech check blocked: {error}", file=sys.stderr) + return 1 + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index eada025..0000000 --- a/tests/conftest.py +++ /dev/null @@ -1,65 +0,0 @@ -import importlib.util -import sys -import types -from pathlib import Path - - -REPO_ROOT = Path(__file__).resolve().parents[1] -SRC_ROOT = REPO_ROOT / "src" -BUILD_PACKAGE_ROOT = REPO_ROOT / "_build" / "src" / "cthulhu" - - -def _load_generated_module(module_name): - module_path = BUILD_PACKAGE_ROOT / f"{module_name}.py" - full_name = f"cthulhu.{module_name}" - - if module_path.exists(): - spec = importlib.util.spec_from_file_location(full_name, module_path) - module = importlib.util.module_from_spec(spec) - sys.modules[full_name] = module - spec.loader.exec_module(module) - return module - - module = types.ModuleType(full_name) - if module_name == "cthulhu_i18n": - module._ = lambda text: text - module.ngettext = lambda singular, plural, count: singular if count == 1 else plural - module.cgettext = lambda text: text - module.C_ = lambda _context, text: text - module.localedir = str(REPO_ROOT / "po") - module.setModuleLocale = lambda *_args, **_kwargs: None - module.setLocaleForMessages = lambda *_args, **_kwargs: None - module.setLocaleForNames = lambda *_args, **_kwargs: None - module.setLocaleForGUI = lambda *_args, **_kwargs: None - return module - - if module_name == "cthulhu_platform": - from cthulhu import cthulhuVersion - - module.version = ( - f"Cthulhu screen reader version " - f"{cthulhuVersion.version}-{cthulhuVersion.codeName}" - ) - module.revision = "" - module.prefix = str(REPO_ROOT) - module.package = "cthulhu" - module.datadir = str(REPO_ROOT) - module.tablesdir = "/usr/share/liblouis/tables" - return module - - raise ImportError(f"Unsupported generated module: {module_name}") - - -if str(SRC_ROOT) not in sys.path: - sys.path.insert(0, str(SRC_ROOT)) - -import cthulhu # noqa: E402 - - -for generated_module in ("cthulhu_i18n", "cthulhu_platform"): - if f"cthulhu.{generated_module}" in sys.modules: - continue - - loaded_module = _load_generated_module(generated_module) - sys.modules[f"cthulhu.{generated_module}"] = loaded_module - setattr(cthulhu, generated_module, loaded_module) diff --git a/tests/current_line_fixture.py b/tests/current_line_fixture.py new file mode 100644 index 0000000..5494b18 --- /dev/null +++ b/tests/current_line_fixture.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +"""Private GTK controls for current-line AT-SPI checks.""" +import json +import sys + +import gi +gi.require_version("Gtk", "3.0") +from gi.repository import GLib, Gtk + +window = Gtk.Window(title="Current line fixture") +box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) +window.add(box) +entry = Gtk.Entry() +entry.get_accessible().set_name("Entry") +textView = Gtk.TextView() +textView.get_accessible().set_name("Text") +password = Gtk.Entry() +password.set_visibility(False) +password.get_accessible().set_name("Password") +button = Gtk.Button(label="Example button") +controls = {"entry": entry, "text": textView, "password": password, "button": button} +for control in controls.values(): + box.pack_start(control, True, True, 0) +window.show_all() + + +def command_ready(source, condition): + line = sys.stdin.readline() + if not line: + Gtk.main_quit() + return False + command = json.loads(line) + control = controls[command["control"]] + if command["action"] == "focus": + if isinstance(control, Gtk.Entry): + control.set_text(command["text"]) + control.set_position(command["offset"]) + elif isinstance(control, Gtk.TextView): + buffer = control.get_buffer() + buffer.set_text(command["text"]) + buffer.place_cursor(buffer.get_iter_at_offset(command["offset"])) + window.present() + control.grab_focus() + + def finish_focus(): + if isinstance(control, Gtk.Entry): + control.set_position(command["offset"]) + elif isinstance(control, Gtk.TextView): + buffer = control.get_buffer() + buffer.place_cursor(buffer.get_iter_at_offset(command["offset"])) + print("ready", flush=True) + return False + + GLib.timeout_add(50, finish_focus) + return True + elif command["action"] == "caret": + if isinstance(control, Gtk.Entry): + offset = control.get_position() + else: + buffer = control.get_buffer() + offset = buffer.get_iter_at_mark(buffer.get_insert()).get_offset() + print(offset, flush=True) + print("ready", flush=True) + return True + + +GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, command_ready) +print("ready", flush=True) +Gtk.main() diff --git a/tests/firefox-baseline.html b/tests/firefox-baseline.html new file mode 100644 index 0000000..a3425ba --- /dev/null +++ b/tests/firefox-baseline.html @@ -0,0 +1,11 @@ + + + +Cthulhu Firefox Baseline +

Firefox baseline heading

+

Firefox baseline paragraph.

+Firefox baseline link + +

Firefox baseline destination.

+

Mixed before Inline message link after.

+ diff --git a/tests/gtk_alert.py b/tests/gtk_alert.py new file mode 100644 index 0000000..e6aceea --- /dev/null +++ b/tests/gtk_alert.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +"""GTK message dialog fixture for native alert capture.""" +import gi + +gi.require_version("Gtk", "3.0") +gi.require_version("Gdk", "3.0") +from gi.repository import Gdk, Gtk + + +window = Gtk.Window(title="Cthulhu Alert Probe") +window.connect("destroy", Gtk.main_quit) +window.set_default_size(320, 180) + + +def on_key_press(_window, event): + if event.keyval != Gdk.KEY_u: + return False + dialog = Gtk.MessageDialog( + transient_for=window, + modal=True, + message_type=Gtk.MessageType.QUESTION, + buttons=Gtk.ButtonsType.YES_NO, + text="Version 0.6.0 is available. Open the releases page in your browser?", + ) + dialog.set_title("Check for Updates") + dialog.run() + dialog.destroy() + return True + + +window.connect("key-press-event", on_key_press) +window.show_all() +Gtk.main() diff --git a/tests/gtk_background_events.py b/tests/gtk_background_events.py new file mode 100644 index 0000000..11b0be7 --- /dev/null +++ b/tests/gtk_background_events.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +# Copyright (c) 2026 Storm Dragon +# Authors: Storm Dragon, Angus Kola +# SPDX-License-Identifier: GPL-3.0-or-later +"""Controlled selection flood and same-process sibling window fixture.""" +import os +import sys + +import gi + +gi.require_version("Gtk", "3.0") +gi.require_version("Atk", "1.0") +gi.require_version("GdkX11", "3.0") +from gi.repository import Atk, GdkX11, GLib, Gtk + + +fixtureName = sys.argv[1] +windows = [] +pendingInput = "" + + +def make_window(title): + window = Gtk.Window(title=title) + window.set_default_size(350, 260) + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + window.add(box) + entry = Gtk.Entry() + entry.get_accessible().set_name(title + " entry") + box.add(entry) + store = Gtk.ListStore(str) + for index in range(40): + store.append(["Result " + str(index)]) + table = Gtk.TreeView(model=store) + table.get_accessible().set_name(title + " results") + table.append_column(Gtk.TreeViewColumn("Result", Gtk.CellRendererText(), text=0)) + box.add(table) + marker = Gtk.Label(label="Marker") + marker.get_accessible().set_role(Atk.Role.ALERT) + box.add(marker) + window.show_all() + entry.grab_focus() + windows.append(window) + return window, entry, table, marker + + +window, entry, table, marker = make_window(fixtureName) +sibling = None + + +def receive_command(_source, _condition): + global pendingInput, sibling + content = os.read(sys.stdin.fileno(), 4096) + if not content: + Gtk.main_quit() + return False + pendingInput += content.decode() + while "\n" in pendingInput: + command, pendingInput = pendingInput.split("\n", 1) + if command.startswith("flood "): + generation = command.split()[1] + selection = table.get_selection() + for index in range(300): + selection.select_path(Gtk.TreePath.new_from_indices([index % 40])) + marker.set_text("Flood complete " + generation) + elif command == "sibling": + sibling, _, _, _ = make_window(fixtureName + " sibling") + print("sibling", GdkX11.X11Window.get_xid(sibling.get_window()), flush=True) + elif command == "edit": + entry.set_text("Updated text") + entry.set_position(-1) + elif command == "focus-table": + table.grab_focus() + table.set_cursor(Gtk.TreePath.new_from_indices([1])) + elif command == "quit": + Gtk.main_quit() + return False + return True + + +GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, receive_command) +GLib.idle_add(lambda: print("ready", GdkX11.X11Window.get_xid(window.get_window()), flush=True) or False) +Gtk.main() diff --git a/tests/gtk_edit_labels.py b/tests/gtk_edit_labels.py new file mode 100644 index 0000000..147219f --- /dev/null +++ b/tests/gtk_edit_labels.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +"""Edit fields whose labels are exposed only through AT-SPI relations.""" +import gi + +gi.require_version("Gtk", "3.0") +gi.require_version("Atk", "1.0") +from gi.repository import Atk, Gtk + +window = Gtk.Window(title="Edit label probe") +window.connect("destroy", Gtk.main_quit) +box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8) +window.add(box) + + +def field(identifier, labels, name="", password=False): + entry = Gtk.Entry() + entry.set_text("secret value" if password else "sample value") + entry.set_visibility(not password) + accessible = entry.get_accessible() + accessible.set_name(name) + accessible.set_description(identifier) + for text in labels: + label = Gtk.Label(label=text) + box.pack_start(label, False, False, 0) + accessible.add_relationship(Atk.RelationType.LABELLED_BY, label.get_accessible()) + box.pack_start(entry, False, False, 0) + + +field("related", ["Nickname"]) +field("multiple", ["Account", "identifier"]) +field("named", ["Other label"], name="Explicit name") +field("unlabelled", []) +field("protected", ["Password"], password=True) +window.show_all() +Gtk.main() diff --git a/tests/gtk_progress.py b/tests/gtk_progress.py new file mode 100644 index 0000000..33016ad --- /dev/null +++ b/tests/gtk_progress.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +"""Controlled GTK progress fixture, with keyboard focus on a separate button.""" +import sys +import gi + +gi.require_version("Gtk", "3.0") +from gi.repository import GLib, Gtk + + +window = Gtk.Window(title="Progress probe") +window.set_default_size(400, 200) +box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12) +window.add(box) +progress = Gtk.ProgressBar() +progress.get_accessible().set_name("Download") +box.pack_start(progress, False, False, 0) +button = Gtk.Button(label="Keep focus") +box.pack_start(button, False, False, 0) +other = Gtk.Window(title="Other probe") +other.set_default_size(400, 200) +other.move(450, 0) +other.add(Gtk.Entry()) +window.show_all() +other.show_all() +window.present() +button.grab_focus() + + +def command_received(source, condition): + line = sys.stdin.readline().strip() + if not line: + Gtk.main_quit() + return False + if line.startswith("hide "): + progress.hide() + progress.set_fraction(float(line.split()[1])) + elif line == "show": + progress.show() + else: + progress.set_fraction(float(line)) + return True + + +GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, command_received) +GLib.idle_add(lambda: print("ready", flush=True)) +Gtk.main() diff --git a/tests/gtk_radio_group.py b/tests/gtk_radio_group.py new file mode 100644 index 0000000..0fbaf17 --- /dev/null +++ b/tests/gtk_radio_group.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +"""Small GTK radio group for native accessibility capture.""" +import gi + +gi.require_version("Gtk", "3.0") +from gi.repository import Gtk + +window = Gtk.Window(title="Radio group probe") +window.connect("destroy", Gtk.main_quit) +frame = Gtk.Frame(label="Punctuation Level") +buttons = Gtk.Box(spacing=8) +first = Gtk.RadioButton.new_with_label_from_widget(None, "None") +second = Gtk.RadioButton.new_with_label_from_widget(first, "Some") +buttons.add(first) +buttons.add(second) +frame.add(buttons) +window.add(frame) +window.show_all() +Gtk.main() diff --git a/tests/gtk_selection.py b/tests/gtk_selection.py new file mode 100644 index 0000000..1a3513f --- /dev/null +++ b/tests/gtk_selection.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 +"""Small GTK tree-selection fixture for the isolated native X11 test.""" + +import gi + +gi.require_version("Gtk", "3.0") +from gi.repository import GLib, Gtk + + +window = Gtk.Window(title="Cthulhu Selection Probe") +window.connect("destroy", Gtk.main_quit) + +store = Gtk.ListStore(str) +store.append(("Alpha result",)) +store.append(("Beta result",)) + +view = Gtk.TreeView(model=store) +view.set_headers_visible(False) +view.append_column(Gtk.TreeViewColumn("Result", Gtk.CellRendererText(), text=0)) +view.get_selection().set_mode(Gtk.SelectionMode.SINGLE) +window.add(view) + + +def select_result(path): + view.get_selection().select_path(path) + view.set_cursor(path) + return False + + +window.show_all() +view.grab_focus() +GLib.timeout_add(500, select_result, 0) +GLib.timeout_add(800, select_result, 1) +GLib.timeout_add(2000, Gtk.main_quit) +Gtk.main() diff --git a/tests/gtk_table.py b/tests/gtk_table.py new file mode 100644 index 0000000..3354d5a --- /dev/null +++ b/tests/gtk_table.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +"""Small GTK table with a window description for native speech checks.""" + +import gi +import os + +gi.require_version("Gtk", "3.0") +gi.require_version("Gdk", "3.0") +gi.require_version("Atk", "1.0") +from gi.repository import Atk, Gdk, Gtk + + +window = Gtk.Window(title="Table presentation probe") +window.connect("destroy", Gtk.main_quit) +window.get_accessible().set_description("Select an item and press Enter to open it.") +store = Gtk.ListStore(str, str) +store.append(["Alpha", "Document"]) +store.append(["Beta", "Shortcut"]) +view = Gtk.TreeView(model=store) +view.get_accessible().set_name("Probe items") +name_column = Gtk.TreeViewColumn("Name") +icon_renderer = Gtk.CellRendererPixbuf() +icon_renderer.set_property("icon-name", "text-x-generic") +name_column.pack_start(icon_renderer, False) +name_renderer = Gtk.CellRendererText() +name_column.pack_start(name_renderer, True) +name_column.add_attribute(name_renderer, "text", 0) +view.append_column(name_column) +kind_renderer = Gtk.CellRendererText() +view.append_column(Gtk.TreeViewColumn("Kind", kind_renderer, text=1)) +multi = os.environ.get("CTHULHU_GTK_TABLE_MULTI") == "1" +listRole = os.environ.get("CTHULHU_GTK_TABLE_LIST") == "1" +if multi: + view.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) +if multi or listRole: + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + before = Gtk.Entry() if listRole else Gtk.Button(label="Before table") + if listRole: + before.get_accessible().set_name("Command") + view.get_accessible().set_role(Atk.Role.LIST) + + def on_entry_key_press(_entry, event): + if event.keyval == Gdk.KEY_Down: + view.grab_focus() + view.get_selection().select_path(0) + return True + return False + + before.connect("key-press-event", on_entry_key_press) + box.pack_start(before, False, False, 0) + box.pack_start(view, True, True, 0) + window.add(box) +else: + window.add(view) +view.get_selection().select_path(0) +if listRole and not multi: + view.get_selection().unselect_all() +if multi: + view.get_selection().select_path(1) +window.show_all() +if multi or listRole: + before.grab_focus() +else: + view.grab_focus() +Gtk.main() diff --git a/tests/gtk_tree.py b/tests/gtk_tree.py new file mode 100644 index 0000000..33046b2 --- /dev/null +++ b/tests/gtk_tree.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +"""Mutable GTK tree fixture for the isolated native AT-SPI test.""" +import os + +import gi + +gi.require_version("Gtk", "3.0") +gi.require_version("Gdk", "3.0") +from gi.repository import Gdk, GLib, Gtk, Pango + + +window = Gtk.Window(title="Cthulhu Tree Probe") +window.connect("destroy", Gtk.main_quit) +window.set_default_size(320, 180) +resize_pending = False +activation_window = None +container = ( + Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + if os.environ.get("CTHULHU_TREE_CONTAINER") == "box" + else Gtk.ListBox() +) +container.get_accessible().set_name("Dynamic controls") +window.add(container) + + +def make_row(name): + row = Gtk.ListBoxRow() + row.add(Gtk.Label(label=name)) + return row + + +persistent = make_row("Persistent control") +removable = make_row("Removable control") +container.add(persistent) +container.add(removable) +review_label = Gtk.Label(label="Café 猫\nSecond line") +review_label.get_accessible().set_name("Review text probe") +container.add(review_label) +protected = Gtk.Entry() +protected.set_visibility(False) +protected.set_text("fixture secret") +protected.get_accessible().set_name("Protected text probe") +container.add(protected) +caret_entry = Gtk.Entry() +caret_entry.set_text("Caret 猫 text") +caret_entry.set_position(6) +caret_entry.get_accessible().set_name("Caret review probe") +container.add(caret_entry) +scroller = Gtk.ScrolledWindow() +scroller.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER) +scroller.set_size_request(100, 35) +clipped_label = Gtk.Label(label="Clipped " + "猫" * 60 + " OFFSCREEN") +clipped_label.set_xalign(0) +clipped_label.get_accessible().set_name("Clipped review probe") +scroller.add(clipped_label) +container.add(scroller) + +numeric = Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, -10, 10, 0.01) +numeric.set_digits(2) +numeric.set_value(1.25) +numeric.get_accessible().set_name("Numeric value probe") +container.add(numeric) + +if os.environ.get("CTHULHU_SPEECH_METADATA") == "1": + mnemonic_button = Gtk.Button.new_with_mnemonic("_Activate") + mnemonic_button.get_accessible().set_name("Mnemonic probe") + container.add(mnemonic_button) + indentation_entry = Gtk.Entry() + indentation_entry.set_text("\t Indented É") + indentation_entry.set_position(5) + indentation_entry.get_accessible().set_name("Indentation probe") + container.add(indentation_entry) + color_view = Gtk.TextView() + color_view.get_accessible().set_name("Color attribute probe") + color_view.set_wrap_mode(Gtk.WrapMode.NONE) + color_buffer = color_view.get_buffer() + color_buffer.set_text("Red example") + red_tag = color_buffer.create_tag("red", foreground="#ff0000", underline=Pango.Underline.ERROR) + color_buffer.apply_tag(red_tag, color_buffer.get_start_iter(), color_buffer.get_iter_at_offset(3)) + color_buffer.place_cursor(color_buffer.get_iter_at_offset(1)) + container.add(color_view) + + +def on_key_press(_window, event): + global activation_window, removable, resize_pending + if os.environ.get("CTHULHU_SPEECH_METADATA") == "1": + if event.keyval == Gdk.KEY_F9: + mnemonic_button.grab_focus() + return True + if event.keyval == Gdk.KEY_F10: + indentation_entry.set_editable(not bool(event.state & Gdk.ModifierType.SHIFT_MASK)) + indentation_entry.grab_focus() + return True + if event.keyval == Gdk.KEY_F11: + color_view.grab_focus() + return True + if event.keyval == Gdk.KEY_F6: + caret_entry.grab_focus() + return True + if event.keyval == Gdk.KEY_F7: + protected.grab_focus() + return True + if event.keyval == Gdk.KEY_F8: + numeric.grab_focus() + return True + if event.keyval == Gdk.KEY_Escape: + window.destroy() + return True + if event.keyval == Gdk.KEY_r and removable is not None: + container.remove(removable) + removable = None + window.set_title("Cthulhu Tree Probe Removed") + return True + if event.keyval == Gdk.KEY_v: + review_label.hide() + window.set_title("Cthulhu Tree Probe Text Hidden") + return True + if event.keyval == Gdk.KEY_t: + review_label.set_text("Changed 猫\nNew line") + window.set_title("Cthulhu Tree Probe Text Changed") + return True + if event.keyval == Gdk.KEY_m: + resize_pending = True + window.resize(500, 300) + return True + if event.keyval == Gdk.KEY_h: + persistent.hide() + window.set_title("Cthulhu Tree Probe Hidden") + return True + if event.keyval == Gdk.KEY_a: + container.add(make_row("Added control")) + container.show_all() + window.set_title("Cthulhu Tree Probe Added") + return True + if event.keyval == Gdk.KEY_w: + activation_window = Gtk.Window(title="Cthulhu Activation Probe") + activation_window.set_transient_for(window) + activation_window.set_default_size(240, 100) + activation_button = Gtk.Button(label="Activated control") + activation_window.add(activation_button) + activation_window.show_all() + activation_button.grab_focus() + activation_window.present() + GLib.timeout_add(1000, activation_window.destroy) + return True + return False + + +def on_size_allocate(_window, allocation): + global resize_pending + if resize_pending and allocation.width == 500 and allocation.height == 300: + resize_pending = False + window.set_title("Cthulhu Tree Probe Resized") + + +window.connect("size-allocate", on_size_allocate) +window.connect("key-press-event", on_key_press) +window.show_all() +window.present() +if os.environ.get("CTHULHU_TREE_MANUAL") != "1": + GLib.timeout_add_seconds(20, Gtk.main_quit) +Gtk.main() diff --git a/tests/gtk_web_notification.py b/tests/gtk_web_notification.py new file mode 100644 index 0000000..0c69435 --- /dev/null +++ b/tests/gtk_web_notification.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +"""Controlled AT-SPI toast provider; process names are fixture identities.""" +import ctypes +import gi +import os +import sys + +gi.require_version("Gtk", "3.0") +gi.require_version("Atk", "1.0") +gi.require_version("GdkX11", "3.0") +from gi.repository import Atk, GdkX11, GLib, Gtk + +# PR_SET_NAME changes only this fixture's identity; no Steam process is used. +libc = ctypes.CDLL(None) +if libc.prctl(15, sys.argv[1].encode(), 0, 0, 0) != 0: + raise RuntimeError("Cannot set fixture process identity") + +window = Gtk.Window(title="Web notification fixture") +box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) +window.add(box) +toast = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) +toast.get_accessible().set_role(Atk.Role.ALERT) +toast.set_no_show_all(True) +username = Gtk.Label(label="Username") +body = Gtk.Label(label="Playing: Example Game") +toast.add(username) +toast.add(body) +box.add(toast) +barrier = Gtk.Label(label="Marker") +barrier.get_accessible().set_role(Atk.Role.ALERT) +box.add(barrier) +window.connect("destroy", Gtk.main_quit) +window.show_all() +foreground = Gtk.Window(title="Foreground fixture") +foreground.set_default_size(300, 80) +foreground.move(400, 200) +foreground.add(Gtk.Entry()) +foreground.show_all() + + +pendingInput = "" + + +def receive_command(source: object, condition: object) -> bool: + global pendingInput + content = os.read(sys.stdin.fileno(), 4096) + if not content: + Gtk.main_quit() + return False + pendingInput += content.decode() + while "\n" in pendingInput: + command, pendingInput = pendingInput.split("\n", 1) + if command == "show": + toast.set_no_show_all(False) + toast.show_all() + elif command == "update": + body.set_text("Username is now online") + elif command == "barrier": + barrier.set_text("Notification barrier") + elif command == "destroy": + toast.destroy() + elif command == "add": + addedToast = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + addedToast.get_accessible().set_role(Atk.Role.ALERT) + addedToast.add(Gtk.Label(label="A new toast")) + box.add(addedToast) + addedToast.show_all() + elif command == "quit": + Gtk.main_quit() + return False + return True + + +GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, receive_command) +GLib.idle_add(lambda: print("ready", GdkX11.X11Window.get_xid(foreground.get_window()), flush=True) or False) +Gtk.main() diff --git a/tests/libreoffice.fods b/tests/libreoffice.fods new file mode 100644 index 0000000..dd782a3 --- /dev/null +++ b/tests/libreoffice.fods @@ -0,0 +1,31 @@ + + + + + + + Alpha + 42 + 43 + + two spaces + + + + Beta + + + + + Gamma + + + + + diff --git a/tests/native_alert.py b/tests/native_alert.py new file mode 100644 index 0000000..103ad0f --- /dev/null +++ b/tests/native_alert.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 +"""Private Xvfb/AT-SPI proof for GTK alert message capture.""" +import os +from pathlib import Path +import subprocess +import sys +import tempfile +import time + +sys.dont_write_bytecode = True +from native_test_session import run_private_session + + +def inside(): + fixture = subprocess.Popen([sys.executable, str(Path(__file__).with_name("gtk_alert.py"))]) + try: + deadline = time.monotonic() + 10 + window = "" + while time.monotonic() < deadline: + result = subprocess.run( + ["xdotool", "search", "--onlyvisible", "--name", "^Cthulhu Alert Probe$"], + capture_output=True, text=True, + ) + if result.returncode == 0: + window = result.stdout.splitlines()[0] + break + time.sleep(0.02) + if not window: + raise RuntimeError("GTK alert probe window missing") + environment = dict(os.environ, CTHULHU_ALERT_WINDOW=window) + environment.setdefault("GOCACHE", "/tmp/cthulhu-cache") + subprocess.run( + ["go", "test", "./internal/atspi", "-run", "^TestNativeGTKAlertMessage$", "-count=1", "-timeout=20s"], + cwd=Path(__file__).resolve().parents[1], env=environment, check=True, timeout=25, + ) + environment["CTHULHU_NATIVE_YAD"] = "1" + for name in ("TestNativeYADQuestionMessage", "TestNativeYADListMessage", "TestNativeYADPowerListMessage"): + subprocess.run( + ["go", "test", "./internal/atspi", "-run", f"^{name}$", "-count=1", "-timeout=20s"], + cwd=Path(__file__).resolve().parents[1], env=environment, check=True, timeout=25, + ) + # Keep the radio fixture in the same private X11/AT-SPI session. + environment["CTHULHU_NATIVE_RADIO"] = "1" + subprocess.run( + ["go", "test", "./internal/atspi", "-run", "^TestNativeGTKRadioGroupName$", "-count=1", "-timeout=20s"], + cwd=Path(__file__).resolve().parents[1], env=environment, check=True, timeout=25, + ) + finally: + fixture.terminate() + fixture.wait(timeout=3) + + +def main(): + if len(sys.argv) == 2 and sys.argv[1] == "--inside": + inside() + return + with tempfile.TemporaryDirectory(prefix="cthulhu-alert-"): + read_fd, write_fd = os.pipe() + server = subprocess.Popen( + ["Xvfb", "-displayfd", str(write_fd), "-screen", "0", "800x600x24", "-nolisten", "tcp"], + pass_fds=(write_fd,), stderr=subprocess.DEVNULL, + ) + os.close(write_fd) + try: + with os.fdopen(read_fd) as reader: + display = reader.readline().strip() + if not display: + raise RuntimeError("Xvfb failed to start") + environment = dict(os.environ, DISPLAY=":" + display, XDG_SESSION_TYPE="x11") + environment.pop("DBUS_SESSION_BUS_ADDRESS", None) + environment.pop("AT_SPI_BUS_ADDRESS", None) + environment.pop("WAYLAND_DISPLAY", None) + run_private_session( + ["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), "--inside"], + env=environment, check=True, timeout=50, + ) + finally: + server.terminate() + server.wait(timeout=3) + + +if __name__ == "__main__": + main() diff --git a/tests/native_atspi.py b/tests/native_atspi.py new file mode 100644 index 0000000..335e8c3 --- /dev/null +++ b/tests/native_atspi.py @@ -0,0 +1,308 @@ +#!/usr/bin/env python3 +"""Isolated native AT-SPI tree capture and invalidation proof.""" +import os +import ast +import json +from pathlib import Path +import subprocess +import sys +import tempfile +import time + +from native_test_session import run_private_session + + +def wait_for(check, message, timeout=15): + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + value = check() + if value: + return value + time.sleep(0.02) + raise RuntimeError(message) + + +def run_inside(): + if os.environ.get("CTHULHU_NATIVE_EDIT_LABELS") == "1": + run_edit_label_probe() + return + if os.environ.get("CTHULHU_FOREGROUND_PID") == "1": + if os.environ.get("CTHULHU_FOREGROUND_PROXY") == "1": + run_proxy_probe() + else: + run_probe("list") + return + if os.environ.get("CTHULHU_MOUSE_REVIEW") == "1": + run_probe("list") + return + if os.environ.get("CTHULHU_SPEECH_METADATA") == "1": + run_probe("list") + run_probe("list", echo_focus=True) + return + # Keep the original ListBox defunct proof; GtkBox also forwards additions. + for container in ("list", "box"): + run_probe(container) + run_probe("box", flat=True) + run_probe("box", flat=True, terminal=True) + run_probe("box", flat=True, terminal=True, terminal_mode="large") + run_probe("box", flat=True, terminal=True, terminal_mode="prompt") + run_table_probe() + run_table_probe(multi=True) + run_table_probe(list_role=True) + run_table_probe(multi=True, list_role=True) + run_table_probe(list_role=True, speech=True) + if os.environ.get("CTHULHU_TEST_THUNAR") == "1": + run_thunar_probe() + + +def run_edit_label_probe(): + fixture = subprocess.Popen([sys.executable, str(Path(__file__).with_name("gtk_edit_labels.py"))]) + try: + import pyatspi + + def find_window(): + return any(window.name == "Edit label probe" + for app in pyatspi.Registry.getDesktop(0) for window in app) + + wait_for(find_window, "edit label probe missing") + environment = dict(os.environ, GOCACHE="/tmp/cthulhu-go-cache", GOPROXY="off") + subprocess.run( + ["go", "test", "./internal/atspi", "-run", "^TestNativeEditFieldLabels$", + "-count=1", "-timeout=25s", "-v"], + cwd=Path(__file__).resolve().parents[1], env=environment, check=True, + ) + finally: + fixture.terminate() + fixture.wait(timeout=3) + + +def run_thunar_probe(): + with tempfile.TemporaryDirectory(prefix="cthulhu-thunar-") as temporary: + home = Path(temporary) + folder = home / "Files" + folder.mkdir() + for name in ("Alpha", "Beta"): + (folder / name).write_text("Example content\n", encoding="utf-8") + environment = dict(os.environ, HOME=str(home), XDG_CONFIG_HOME=str(home / ".config"), + XDG_CACHE_HOME=str(home / ".cache"), XDG_DATA_HOME=str(home / ".local/share")) + fixture = subprocess.Popen(["thunar", "--window", str(folder)], env=environment) + try: + def find_window(): + result = subprocess.run( + ["xdotool", "search", "--onlyvisible", "--class", "Thunar"], + capture_output=True, text=True, + ) + return result.stdout.strip().splitlines()[0] if result.stdout.strip() else None + + window = wait_for(find_window, "Thunar window missing") + subprocess.run(["xdotool", "windowfocus", window], check=True) + subprocess.run(["xdotool", "key", "ctrl+2"], check=True) + environment.update(CTHULHU_NATIVE_THUNAR="1", GOCACHE="/tmp/cthulhu-cache") + subprocess.run( + ["go", "test", "./internal/atspi", "-run", "^TestNativeThunarNestedFileCellLabel$", "-count=1", "-timeout=20s"], + cwd=Path(__file__).resolve().parents[1], env=environment, check=True, timeout=25, + ) + finally: + if fixture.poll() is None: + fixture.terminate() + fixture.wait(timeout=3) + + +def run_table_probe(multi: bool = False, screen_lock: bool = False, list_role: bool = False, speech: bool = False) -> None: + fixture_env = dict(os.environ) + if multi: + fixture_env["CTHULHU_GTK_TABLE_MULTI"] = "1" + if list_role: + fixture_env["CTHULHU_GTK_TABLE_LIST"] = "1" + fixture = subprocess.Popen([sys.executable, str(Path(__file__).with_name("gtk_table.py"))], env=fixture_env) + try: + def find_window(): + result = subprocess.run( + ["xdotool", "search", "--onlyvisible", "--name", "^Table presentation probe$"], + capture_output=True, text=True, + ) + return result.stdout.strip().splitlines()[0] if result.stdout.strip() else None + + window = wait_for(find_window, "GTK table probe window missing") + subprocess.run(["xdotool", "windowfocus", window], check=True) + environment = dict(os.environ, CTHULHU_NATIVE_GUI_TABLE="1", CTHULHU_GUI_TABLE_WINDOW=window) + if list_role: + environment["CTHULHU_NATIVE_GUI_LIST_TABLE"] = "1" + if multi: + environment["CTHULHU_NATIVE_GUI_TABLE_MULTI"] = "1" + environment.setdefault("GOCACHE", "/tmp/cthulhu-cache") + test_name = "^TestNativeGUITablePresentation$" + if screen_lock: + test_name = "^TestNativeGUITableScreenLockRecovery$" + elif multi: + test_name = "^TestNativeGUITableMultiselectionFocus$" + elif list_role: + test_name = "^TestNativeGUIListTableSpeech$" if speech else "^TestNativeGUIListTableFocus$" + subprocess.run( + ["go", "test", "./internal/app" if speech else "./internal/atspi", "-v", "-run", test_name, "-count=1", "-timeout=20s"], + cwd=Path(__file__).resolve().parents[1], env=environment, check=True, timeout=25, + ) + finally: + if fixture.poll() is None: + fixture.terminate() + fixture.wait(timeout=3) + + +def run_proxy_probe(): + # Real D-Bus proxy and separate mount namespaces, with the shared instance + # metadata Flatpak gives its application and proxy. No installed Flatpak + # application or running desktop reader is used. + address = ast.literal_eval(subprocess.check_output([ + "gdbus", "call", "--session", "--dest", "org.a11y.Bus", + "--object-path", "/org/a11y/bus", "--method", "org.a11y.Bus.GetAddress", + ], text=True))[0] + with tempfile.TemporaryDirectory(prefix="cthulhu-flatpak-") as directory: + root = Path(directory) + info = root / "info" + info.write_text("[Application]\nname=org.example.AccessibilityProbe\n" + "[Instance]\ninstance-id=12345\n") + # A fresh tmpfs root lets us add the metadata without writing to /. + prefix = ["bwrap", "--die-with-parent"] + for path in ("/usr", "/etc", "/var", "/run", "/tmp", "/home", "/proc", + "/bin", "/sbin", "/lib", "/lib64"): + if Path(path).is_symlink(): + prefix += ["--symlink", os.readlink(path), path] + elif Path(path).exists(): + prefix += ["--ro-bind", path, path] + prefix += ["--dev", "/dev", "--bind", directory, directory, + "--ro-bind", str(info), "/.flatpak-info"] + read_fd, write_fd = os.pipe() + socket = str(root / "bus") + proxy = subprocess.Popen(prefix + ["xdg-dbus-proxy", address, socket, + "--fd=" + str(write_fd)], pass_fds=(write_fd,)) + os.close(write_fd) + try: + with os.fdopen(read_fd, "rb") as ready: + if ready.read(1) != b"x": + raise RuntimeError("Accessibility proxy failed to start") + fixture_prefix = prefix + if os.environ.get("CTHULHU_FOREGROUND_PROXY_OTHER") == "1": + other = root / "other-info" + other.write_text(info.read_text().replace("12345", "67890")) + fixture_prefix = prefix + ["--ro-bind", str(other), "/.flatpak-info"] + run_probe("list", fixture_prefix=fixture_prefix, + fixture_overrides={"AT_SPI_BUS_ADDRESS": "unix:path=" + socket, + "GSETTINGS_BACKEND": "memory"}) + finally: + proxy.terminate() + proxy.wait(timeout=3) + + +def run_probe(container, flat=False, terminal=False, terminal_mode="", echo_focus=False, + fixture_prefix=(), fixture_overrides=None): + environment = dict(os.environ, CTHULHU_TREE_CONTAINER=container) + environment["CTHULHU_VTE_MODE"] = terminal_mode + prefix = list(fixture_prefix) + pass_fds = () + if prefix: + read_fd, write_fd = os.pipe() + prefix += ["--info-fd", str(write_fd)] + pass_fds = (write_fd,) + fixture = subprocess.Popen(prefix + [ + sys.executable, + str(Path(__file__).with_name("vte_terminal.py" if terminal else "gtk_tree.py")), + ], env=dict(environment, **(fixture_overrides or {})), pass_fds=pass_fds) + try: + fixture_pid = fixture.pid + if prefix: + os.close(write_fd) + with os.fdopen(read_fd) as information: + fixture_pid = json.load(information)["child-pid"] + def find_window(): + result = subprocess.run( + ["xdotool", "search", "--onlyvisible", "--name", "^Cthulhu Tree Probe$"], + capture_output=True, + text=True, + ) + return result.stdout.strip().splitlines()[0] if result.stdout.strip() else None + + window = wait_for(find_window, "GTK tree probe window missing") + subprocess.run(["xdotool", "windowfocus", window], check=True) + if os.environ.get("CTHULHU_FOREGROUND_PID") == "1": + environment["CTHULHU_TREE_PID"] = str(fixture_pid) + subprocess.run(["xprop", "-id", window, "-f", "_NET_WM_PID", "32c", + "-set", "_NET_WM_PID", "252"], check=True) + environment.update(CTHULHU_NATIVE_ATSPI="1", CTHULHU_TREE_WINDOW=window) + if os.environ.get("CTHULHU_MOUSE_REVIEW") == "1": + environment["CTHULHU_NATIVE_MOUSE_REVIEW"] = "1" + if flat: + environment["CTHULHU_NATIVE_FLAT"] = "1" + if terminal: + environment["CTHULHU_NATIVE_TERMINAL_FLAT"] = "1" + environment.setdefault("GOCACHE", "/tmp/cthulhu-cache") + subprocess.run( + [ + "go", + "test", + "./internal/review" if flat else "./internal/atspi", + "-run", + "^TestNativeForegroundProcessIdentity$" if os.environ.get("CTHULHU_FOREGROUND_PID") == "1" else + "^TestNativeMouseReviewPointerAndHitTest$" if os.environ.get("CTHULHU_MOUSE_REVIEW") == "1" else + "^TestNativeEchoEditFieldFocus$" if echo_focus else + "^TestNativeSpeechMetadata$" if os.environ.get("CTHULHU_SPEECH_METADATA") == "1" else + "^TestNativeTerminalFlatReview$" if terminal else "^TestNativeFlatReview$" if flat else "^TestNativeTreeCaptureDefunctAndShutdownInvalidation$", + "-count=1", + "-timeout=20s", + ], + cwd=Path(__file__).resolve().parents[1], + env=environment, + check=True, + timeout=25, + ) + finally: + if fixture.poll() is None: + fixture.terminate() + fixture.wait(timeout=3) + + +def main() -> None: + if len(sys.argv) == 2 and sys.argv[1] == "--inside": + run_inside() + return + if len(sys.argv) == 2 and sys.argv[1] == "--inside-screen-lock": + run_table_probe(screen_lock=True) + return + if len(sys.argv) == 2 and sys.argv[1] == "--inside-table": + run_table_probe() + run_table_probe(multi=True) + run_table_probe(list_role=True) + run_table_probe(multi=True, list_role=True) + run_table_probe(list_role=True, speech=True) + return + with tempfile.TemporaryDirectory(prefix="cthulhu-atspi-"): + read_fd, write_fd = os.pipe() + server = subprocess.Popen( + ["Xvfb", "-displayfd", str(write_fd), "-screen", "0", "1920x1080x24", "-nolisten", "tcp"], + pass_fds=(write_fd,), + stderr=subprocess.DEVNULL, + ) + os.close(write_fd) + try: + with os.fdopen(read_fd) as reader: + display = reader.readline().strip() + if not display: + raise RuntimeError("Xvfb failed to start") + environment = dict(os.environ, DISPLAY=":" + display, XDG_SESSION_TYPE="x11") + environment.pop("DBUS_SESSION_BUS_ADDRESS", None) + environment.pop("AT_SPI_BUS_ADDRESS", None) + environment.pop("WAYLAND_DISPLAY", None) + run_private_session( + ["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), + "--inside-screen-lock" if len(sys.argv) == 2 and sys.argv[1] == "--screen-lock" else + "--inside-table" if len(sys.argv) == 2 and sys.argv[1] == "--table-only" else "--inside"], + env=environment, + check=True, + timeout=60, + ) + finally: + server.terminate() + server.wait(timeout=3) + + +if __name__ == "__main__": + main() diff --git a/tests/native_browser.py b/tests/native_browser.py new file mode 100644 index 0000000..beb935f --- /dev/null +++ b/tests/native_browser.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +"""Chromium AT-SPI proof on a private X server, bus, and browser profile.""" +import os +from pathlib import Path +import shutil +import subprocess +import sys +import tempfile +import time + +from native_test_session import run_private_session + + +BROWSER_PROOFS = { + "live-atomic": ("./internal/atspi", "^TestNativeBrowserAtomicLiveRegion$", 30, 35, "browser-live.html"), + "replaced-feed": ("./internal/atspi", "^TestNativeBrowserMissingFeedRefreshesWholeBranch$", 30, 35, "browser-replaced-feed.html"), + "nested-document": ("./internal/app", "^TestNativeBrowserNestedDocumentHeadings$", 40, 45), + "reveal": ("./internal/app", "^TestNativeBrowserRevealedHeadings$", 60, 65), + "flat-chrome": ("./internal/review", "^TestNativeBrowserChromeFlatReview$", 35, 40), + "generatedlinks": ("./internal/app", "^TestNativeBrowserGeneratedLinkNavigation$", 30, 35), + "replacement": ("./internal/app", "^TestNativeBrowserInlineReplacementNavigation$", 30, 35), + "tooltips": ("./internal/app", "^TestNativeBrowserTooltipNavigation$", 30, 35), + "menu": ("./internal/app", "^TestNativeBrowserMenuControls$", 30, 35), + "lists": ("./internal/app", "^TestNativeBrowserLists$", 35, 40, "browser-lists.html"), + "pointer": ("./internal/atspi", "^TestNativePointerInput$", 15, 20), + "progress": ("./internal/app", "^TestNativeBrowserProgress$", 30, 35, "browser-progress.html"), + "fragments": ("./internal/review", "^TestNativeBrowserFragmentLines$", 30, 35, "browser-fragments.html"), + "positions": ("./internal/atspi", "^TestNativeBrowserSetPositions$", 25, 30, "browser-positions.html"), + "tabs": ("./internal/app", "^TestNativeBrowserTabs$", 30, 35), + "namedlinks": ("./internal/app", "^TestNativeBrowserNamedLinks$", 25, 30, "browser-named-links.html"), + "linkedheadings": ("./internal/app", "^TestNativeLinkedHeadings$", 45, 50, "browser-linked-headings.html"), + "catalog": ("./internal/atspi", "^TestNativeBrowserCatalogCapture$", 30, 35, "browser-catalog.html"), + "lines": ("./internal/atspi", "^TestNativeBrowserLogicalLines$", 25, 30, "browser-lines.html"), + "tables": ("./internal/app", "^TestNativeBrowserTables$", 35, 40), + "dynamic": ("./internal/app", "^TestNativeBrowserDynamicNavigation$", 40, 45), + "browser": ("./internal/atspi", "^TestNativeBrowser$", 45, 50), + "live": ("./internal/atspi", "^TestNativeBrowserLiveRegion$", 30, 35), + "document": ("./internal/app", "^TestNativeBrowserDocumentCommands$", 45, 50), + "editing": ("./internal/app", "^TestNativeBrowserEditing$", 45, 50), + "editor": ("./internal/app", "^TestNativeBrowserEditorTyping$", 30, 35, "browser-editor.html"), + "selection": ("./internal/app", "^TestNativeBrowserSelection$", 35, 40), + "modes": ("./internal/app", "^TestNativeBrowserModes$", 45, 50), + "keys": ("./internal/platform/xorg", "^TestNativeBrowseKeyTransitions$", 20, 25), +} + + +def selected_proofs(): + selected = {name.strip() for name in os.environ.get( + "CTHULHU_NATIVE_BROWSER_TESTS", ",".join(BROWSER_PROOFS)).split(",") if name.strip()} + unknown = selected - BROWSER_PROOFS.keys() + if not selected or unknown: + raise ValueError("Select browser proofs from: " + ",".join(BROWSER_PROOFS) + + ("; unknown: " + ",".join(sorted(unknown)) if unknown else "")) + return selected + + +def run_inside(): + browser = os.environ.get("CTHULHU_BROWSER") or shutil.which("brave") + if not browser: + raise RuntimeError("Set CTHULHU_BROWSER to a Chromium-family executable") + selected = selected_proofs() + for name, proof in BROWSER_PROOFS.items(): + if name in selected: + print(f"Running browser proof: {name}", flush=True) + # F7 toggles a profile-wide setting. Each proof must start from + # the same browser state whether run alone or after editing. + run_browser_proof(browser, proof) + + +def run_browser_proof(browser, proof): + with tempfile.TemporaryDirectory(prefix="cthulhu-browser-profile-") as profile: + with tempfile.TemporaryFile() as log: + process = subprocess.Popen([ + browser, "--user-data-dir=" + profile, "--no-first-run", + "--no-default-browser-check", "--disable-background-networking", + "--disable-component-update", "--disable-sync", "--password-store=basic", + "--force-renderer-accessibility", "--ozone-platform=x11", + "--new-window", Path(__file__).with_name(proof[4] if len(proof) > 4 else "browser.html").resolve().as_uri(), + ], stdout=log, stderr=log) + try: + deadline = time.monotonic() + 20 + while time.monotonic() < deadline: + if process.poll() is not None: + raise RuntimeError("Browser exited before the probe") + window_name = "Cthulhu Linked Headings Probe" if proof[1] == "^TestNativeLinkedHeadings$" else "Cthulhu Browser Probe" + result = subprocess.run( + ["xdotool", "search", "--onlyvisible", "--name", window_name], + capture_output=True, text=True) + if result.stdout.strip(): + window = result.stdout.splitlines()[0] + subprocess.run(["xdotool", "windowfocus", window], check=True) + break + time.sleep(0.1) + else: + raise RuntimeError("Browser fixture window missing") + environment = dict(os.environ, CTHULHU_NATIVE_BROWSER="1") + if proof[1] == "^TestNativeLinkedHeadings$": + environment["CTHULHU_NATIVE_LINKED_HEADINGS"] = "1" + environment.setdefault("GOCACHE", "/tmp/cthulhu-cache") + package, expression, testTimeout, runTimeout = proof[:4] + subprocess.run(["go", "test", package, "-run", expression, + "-count=1", "-v", f"-timeout={testTimeout}s"], + env=environment, check=True, timeout=runTimeout, + cwd=Path(__file__).resolve().parents[1]) + finally: + process.terminate() + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + + +def main(): + selected = selected_proofs() + if len(sys.argv) == 2 and sys.argv[1] == "--inside": + run_inside() + return + with tempfile.TemporaryDirectory(prefix="cthulhu-browser-"): + read_fd, write_fd = os.pipe() + server = subprocess.Popen( + ["Xvfb", "-displayfd", str(write_fd), "-screen", "0", "800x600x24", "-nolisten", "tcp"], + pass_fds=(write_fd,), + stderr=subprocess.DEVNULL, + ) + os.close(write_fd) + try: + with os.fdopen(read_fd) as reader: + display = reader.readline().strip() + if not display: + raise RuntimeError("Xvfb failed to start") + environment = dict(os.environ, DISPLAY=":" + display, XDG_SESSION_TYPE="x11") + environment.pop("DBUS_SESSION_BUS_ADDRESS", None) + environment.pop("AT_SPI_BUS_ADDRESS", None) + environment.pop("WAYLAND_DISPLAY", None) + run_private_session( + ["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), "--inside"], + env=environment, + check=True, + # Budget each isolated browser startup, bounded Go run and + # cleanup instead of imposing one 120-second suite limit. + timeout=15 + sum(30 + BROWSER_PROOFS[name][3] for name in selected), + ) + finally: + server.terminate() + server.wait(timeout=3) + + +if __name__ == "__main__": + main() diff --git a/tests/native_browser_navigation.py b/tests/native_browser_navigation.py new file mode 100644 index 0000000..5d12ac6 --- /dev/null +++ b/tests/native_browser_navigation.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python3 +"""Changing-document navigation with a real reader, private X11/bus and SSIP.""" +import json +import os +from pathlib import Path +import shutil +import subprocess +import sys +import tempfile +import time + +sys.dont_write_bytecode = True +from native_echo_preview import PreviewSpeechServer +from native_x11 import wait_for +from native_test_session import run_private_session + + +def run_inside(): + binary = os.environ["CTHULHU_BINARY"] + directory = Path(tempfile.mkdtemp(prefix="cthulhu-browser-navigation-")) + print(f"Evidence: {directory}", flush=True) + server = PreviewSpeechServer(directory / "speech.sock") + config = directory / "settings.toml" + config.write_text('''schema-version = 2 +active-profile = "default" +[profiles.default.speech] +output-module = "main" +[profiles.default.braille] +enabled = false +[profiles.default.sound] +enabled = false +[profiles.default.key-echo] +enabled = false +''') + wmConfig = directory / "i3.config" + wmConfig.write_text(f"font pango:monospace 10\nipc-socket {directory / 'i3.sock'}\n") + processes = [] + report = [] + logPath = directory / "reader.log" + try: + processes.append(subprocess.Popen(["i3", "-c", str(wmConfig)], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)) + wait_for(lambda: "0x" in subprocess.check_output( + ["xprop", "-root", "_NET_SUPPORTING_WM_CHECK"], text=True), "private WM missing") + processes.append(subprocess.Popen([ + binary, "--config", str(config), "--no-tentacles", + "--speech-socket", str(directory / "speech.sock"), "--debug-file", str(logPath)], + stdout=subprocess.DEVNULL, stderr=(directory / "reader-stderr.log").open("w"))) + wait_for(lambda: logPath.exists() and "remote D-Bus service ready" in logPath.read_text(), + "private reader did not start") + browser = os.environ.get("CTHULHU_BROWSER") or shutil.which("brave") + fixture = Path(__file__).with_name("browser-changing.html").resolve() + processes.append(subprocess.Popen([ + browser, "--user-data-dir=" + str(directory / "profile"), "--no-first-run", + "--no-default-browser-check", "--disable-background-networking", + "--disable-component-update", "--disable-sync", "--password-store=basic", + "--force-renderer-accessibility", "--ozone-platform=x11", "--new-window", fixture.as_uri()], + stdout=subprocess.DEVNULL, stderr=(directory / "browser.log").open("w"))) + + def key(chord): + subprocess.run(["xdotool", "key", "--clearmodifiers", chord], check=True) + + def logs(): + result = [] + for line in logPath.read_text().splitlines(): + try: + result.append(json.loads(line)) + except json.JSONDecodeError: + pass # A writer can still be completing the last record. + return result + + wait_for(lambda: subprocess.run([ + "xdotool", "search", "--onlyvisible", "--name", "Cthulhu Changing Document Probe"], + capture_output=True).returncode == 0, "private browser did not open") + subprocess.run(["xdotool", "mousemove", "0", "0"], check=True) + for _ in range(12): + offset = len(server.snapshot()) + key("Tab") + time.sleep(0.2) + if any(record["text"] == "Changing document" for record in server.snapshot()[offset:]): + break + else: + raise AssertionError("first document heading did not receive focus") + + def move(chord, expected, delay=0.2): + logOffset, speechOffset = len(logs()), len(server.snapshot()) + key(chord) + result = wait_for(lambda: next((row for row in logs()[logOffset:] + if row.get("message") in {"document navigation completed", "document caret navigation completed"}), None), + f"reader did not complete {chord}", timeout=5) + assert result.get("moved"), (chord, result) + step = {"key": chord, "result": result} + report.append(step) + wait_for(lambda: any(expected(record["text"]) for record in server.snapshot()[speechOffset:]), + f"missing speech for {chord}", timeout=5) + time.sleep(delay) + speech = [record["text"] for record in server.snapshot()[speechOffset:]] + assert not any("Could not" in text for text in speech), (chord, speech) + headings = [text for text in speech if text.startswith("Section ") or text == "Statistics"] + assert all(expected(text) for text in headings), (chord, "repeated earlier heading", speech) + step["speech"] = speech + + for cycle in range(2): + for index in range(1, 11): + name = f"Section {index}" + move("h", lambda text, name=name: text == name, 1.1 if index == 3 else 0.2) + move("h", lambda text: text == "Statistics") + for index in range(10, 0, -1): + name = f"Section {index}" + move("shift+h", lambda text, name=name: text == name) + move("shift+h", lambda text: text == "Changing document") + # Go directly to the final heading and repeatedly traverse text nodes + # which are replaced while the native caret and selection settle. + move("shift+h", lambda text: text == "Statistics") + for _ in range(4): + move("Down", lambda text: text.startswith("Current total ")) + move("Right", lambda text: text == "u") + move("Home", lambda text: text == "C") + move("ctrl+Right", lambda text: text == "Current") + move("Down", lambda text: text == "Following stable line") + move("Up", lambda text: text.startswith("Current total ")) + move("Up", lambda text: text == "Statistics") + + move("Down", lambda text: text.startswith("Current total ")) + move("Down", lambda text: text == "Following stable line") + logOffset, speechOffset = len(logs()), len(server.snapshot()) + key("Return") + wait_for(lambda: any(row.get("message") == "document activation failed" + for row in logs()[logOffset:]), "plain-text Enter did not complete") + time.sleep(0.2) + assert not server.snapshot()[speechOffset:], "plain-text Enter produced reader feedback" + + move("Down", lambda text: text == "Custom action") + for count in (1, 2): + logOffset, speechOffset = len(logs()), len(server.snapshot()) + key("Return") + wait_for(lambda: any(row.get("message") == "document activation completed" + for row in logs()[logOffset:]), "custom clickable activation failed") + wait_for(lambda: any(record["text"] == f"Action count {count}" + for record in server.snapshot()[speechOffset:]), + "page did not report exactly one activation") + time.sleep(0.2) + speech = [record["text"] for record in server.snapshot()[speechOffset:]] + assert speech == [f"Action count {count}"], ("activation added feedback", speech) + logOffset = len(logs()) + subprocess.run(["xdotool", "click", "1"], check=True) + wait_for(lambda: any(row.get("message") == "released virtual caret for pointer input" + for row in logs()[logOffset:]), "shared pointer signal did not reach the reader") + print(f"PASS: {len(report)} navigation commands with changing text", flush=True) + finally: + for process in reversed(processes): + process.terminate() + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + server.close() + (directory / "report.json").write_text(json.dumps(report, indent=2)) + (directory / "speech.json").write_text(json.dumps(server.snapshot(), indent=2)) + + +def main(): + if sys.argv[1:] == ["--inside"]: + run_inside() + return + readFd, writeFd = os.pipe() + display = subprocess.Popen(["Xvfb", "-displayfd", str(writeFd), "-screen", "0", "1280x900x24", + "-nolisten", "tcp"], pass_fds=(writeFd,), stderr=subprocess.DEVNULL) + os.close(writeFd) + try: + with os.fdopen(readFd) as stream: + number = stream.readline().strip() + if not number: + raise RuntimeError("private X server failed to start") + environment = dict(os.environ, DISPLAY=":" + number, XDG_SESSION_TYPE="x11") + for name in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + environment.pop(name, None) + run_private_session(["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), "--inside"], + env=environment, check=True, timeout=120) + finally: + display.terminate() + display.wait(timeout=5) + + +if __name__ == "__main__": + main() diff --git a/tests/native_clipboard_preferences.py b/tests/native_clipboard_preferences.py new file mode 100644 index 0000000..8804a03 --- /dev/null +++ b/tests/native_clipboard_preferences.py @@ -0,0 +1,222 @@ +#!/usr/bin/env python3 +"""Clipboard bursts and application chooser on a private Xvfb/AT-SPI session.""" +import json +import os +from pathlib import Path +import queue +import subprocess +import sys +import threading + +sys.dont_write_bytecode = True +from native_x11 import wait_for +from native_test_session import run_private_session + + +def owner(): + import gi + gi.require_version("Gtk", "3.0") + gi.require_version("Gdk", "3.0") + gi.require_version("GdkPixbuf", "2.0") + from gi.repository import Gdk, GdkPixbuf, GLib, Gtk + GLib.set_prgname("example-clipboard-app") + GLib.set_application_name("Example Clipboard Application") + window = Gtk.Window(title="Example Clipboard Owner") + window.add(Gtk.Entry()) + window.show_all() + clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + print("ready", flush=True) + + def command(source, condition): + line = source.readline() + if not line: + Gtk.main_quit() + return False + request = json.loads(line) + if "text" in request: + clipboard.set_text(request["text"], -1) + elif request.get("image"): + image = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, False, 8, 2, 2) + image.fill(0) + clipboard.set_image(image) + elif "burst" in request: + texts = iter(request["burst"]) + + def next_text(): + text = next(texts, None) + if text is None: + print("ready", flush=True) + return False + clipboard.set_text(text, -1) + return True + + GLib.timeout_add(20, next_text) + return True + print("ready", flush=True) + return True + + GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, command) + Gtk.main() + + +def inside(): + import pyatspi + binary = os.environ["CTHULHU_BINARY"] + children = [] + + def launch(arguments): + process = subprocess.Popen(arguments, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, text=True) + children.append(process) + return process + + def send(process, value): + process.stdin.write(json.dumps(value) + "\n") + process.stdin.flush() + + def walk(node): + yield node + for child in node: + if child is not None: + yield from walk(child) + + def find_window(name): + for application in pyatspi.Registry.getDesktop(0): + for child in application: + if child is not None and child.name == name: + return child + return None + + def key(*keys): + subprocess.run(["xdotool", "key", "--clearmodifiers", *keys], check=True) + + def focus_window(title): + xid = subprocess.check_output(["xdotool", "search", "--onlyvisible", "--name", "^" + title + "$"], text=True).splitlines()[0] + subprocess.run(["xdotool", "windowfocus", xid], check=True) + + try: + fixture = launch([sys.executable, __file__, "--owner"]) + assert fixture.stdout.readline().strip() == "ready" + wait_for(lambda: find_window("Example Clipboard Owner"), "clipboard fixture missing") + watcher = launch([binary, "--clipboard-watch"]) + replies = queue.Queue() + + def receive(): + for line in watcher.stdout: + replies.put(json.loads(line)) + + threading.Thread(target=receive, daemon=True).start() + assert replies.get(timeout=5)["Ready"] + + def configure(enabled, epoch): + send(watcher, {"Enabled": enabled, "Epoch": epoch}) + response = replies.get(timeout=5) + assert response["Ready"] and response["Epoch"] == epoch, response + + configure(False, 1) + send(fixture, {"text": "Disabled text"}) + assert fixture.stdout.readline().strip() == "ready" + try: + assert False, ("disabled clipboard was read", replies.get(timeout=0.2)) + except queue.Empty: + pass + configure(True, 2) + texts = ["First clipboard", "Second clipboard", "Third clipboard", "Fourth clipboard"] + send(fixture, {"burst": texts}) + assert fixture.stdout.readline().strip() == "ready" + captured = [replies.get(timeout=5) for _ in texts] + assert [value["Text"] for value in captured] == texts, captured + assert all(value["Epoch"] == 2 for value in captured), captured + send(fixture, {"image": True}) + assert fixture.stdout.readline().strip() == "ready" + assert replies.get(timeout=5)["Text"] == "", "image data was read" + uriOwner = launch(["xclip", "-quiet", "-selection", "clipboard", "-target", "text/uri-list", "-in"]) + uriOwner.stdin.write("file:///tmp/example.txt\n") + uriOwner.stdin.close() + assert replies.get(timeout=5)["Text"] == "", "file URI was read" + configure(False, 3) + send(fixture, {"text": "Still disabled"}) + assert fixture.stdout.readline().strip() == "ready" + try: + assert False, ("disabled clipboard was read", replies.get(timeout=0.2)) + except queue.Empty: + pass + watcher.stdin.close() + assert watcher.wait(timeout=5) == 0 + print("PASS: clipboard disabled, four changes 20ms apart in order, image/URI ignored, disable, shutdown", flush=True) + + wine = launch([sys.executable, "-u", str(Path(__file__).with_name("window_title_fixture.py"))]) + json.loads(wine.stdout.readline()) + + def chooser(): + process = launch([binary, "--preferences-ui"]) + send(process, {"ChooseApplication": True}) + window = wait_for(lambda: find_window("Choose Application Preferences"), "application chooser missing") + tableNode = next(node for node in walk(window) if node.name == "Applications" and node.getRole() == pyatspi.ROLE_TABLE) + table = tableNode.queryTable() + names = [table.getAccessibleAt(row, 0).name for row in range(table.nRows)] + assert "game.exe" in names, names + assert "example-clipboard-app" in names, names + assert names.count("game.exe") == 1, names + assert not any(name.lower().startswith("cthulhu") for name in names), names + focus_window("Choose Application Preferences") + assert tableNode.queryComponent().grabFocus() + return process, tableNode, table, names + + process, tableNode, table, names = chooser() + key("Tab") + wait_for(lambda: not any(node.getState().contains(pyatspi.STATE_FOCUSED) for node in walk(tableNode)), "Tab trapped in application list") + key("shift+Tab") + wait_for(lambda: any(node.getState().contains(pyatspi.STATE_FOCUSED) for node in walk(tableNode)), "Shift+Tab did not return to application list") + key("Escape") + assert process.wait(timeout=5) == 0 + assert process.stdout.read() == "", "Escape selected an application" + process, tableNode, table, names = chooser() + row = names.index("game.exe") + assert table.getAccessibleAt(row, 0).queryComponent().grabFocus() + key("Return") + selected = json.loads(process.stdout.readline()) + assert selected["Application"] == "game.exe", selected + send(process, {"Application": "game.exe", "CanSave": True, "Accepted": True, + "Values": {"KeyboardLayout": 1, "CthulhuModifierKeys": ["KP_Insert"], + "TimeFormat": "24-hour", "DateFormat": "numbers-mdy", + "SpeechHistoryLimit": 50, "Punctuation": 1, + "RaisePitchForCapitals": True}}) + wait_for(lambda: find_window("Cthulhu Preferences for game.exe"), "chosen application preferences missing") + focus_window("Cthulhu Preferences for game.exe") + key("Escape") + assert process.wait(timeout=5) == 0 + assert process.stdout.read() == "", "Escape submitted preferences" + print("PASS: AT-SPI/X11/Wine application identities, deduplication, Tab/Shift+Tab, Escape cancels, Enter opens selected preferences", flush=True) + finally: + for process in children: + if process.poll() is None: + process.terminate() + process.wait(timeout=5) + + +def main(): + if "--owner" in sys.argv: + owner() + return + if "--inside" in sys.argv: + inside() + return + readFd, writeFd = os.pipe() + server = subprocess.Popen(["Xvfb", "-displayfd", str(writeFd), "-screen", "0", "1024x768x24", "-nolisten", "tcp"], pass_fds=(writeFd,), stderr=subprocess.DEVNULL) + os.close(writeFd) + try: + with os.fdopen(readFd) as reader: + display = reader.readline().strip() + assert display, "Xvfb failed" + env = dict(os.environ, DISPLAY=":" + display, GDK_BACKEND="x11", GTK_MODULES="gail:atk-bridge", GIO_USE_VFS="local") + for name in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + env.pop(name, None) + run_private_session(["dbus-run-session", "--", sys.executable, __file__, "--inside"], env=env, check=True, timeout=75) + finally: + server.terminate() + server.wait(timeout=5) + + +if __name__ == "__main__": + main() diff --git a/tests/native_echo_preview.py b/tests/native_echo_preview.py new file mode 100644 index 0000000..7fb6997 --- /dev/null +++ b/tests/native_echo_preview.py @@ -0,0 +1,368 @@ +"""Real reader/preferences/GTK flow against a private, completion-aware SSIP server.""" +import json +import os +from pathlib import Path +import socket +import subprocess +import tempfile +import threading +import time + +from native_x11 import wait_for + + +class PreviewSpeechServer: + def __init__(self, path, defaultsSupported=True): + self.listener = socket.socket(socket.AF_UNIX) + self.listener.bind(str(path)) + self.listener.listen() + self.lock = threading.RLock() + self.clients = {} + self.spoken = [] + self.defaultsSupported = defaultsSupported + threading.Thread(target=self.accept_clients, daemon=True).start() + + def accept_clients(self): + while True: + try: + connection, _ = self.listener.accept() + except OSError: + return + with self.lock: + clientId = len(self.clients) + 1 + client = {"socket": connection, "lock": threading.RLock(), "notifications": False, + "module": "main", "voice": "", "active": None, + "settings": {"RATE": 20, "PITCH": -10, "VOLUME": 100}} + self.clients[clientId] = client + threading.Thread(target=self.serve_client, args=(clientId, client), daemon=True).start() + + def reply(self, client, text): + with client["lock"]: + try: + client["socket"].sendall(text.encode()) + except OSError: + pass + + def finish(self, clientId, client, record, canceled=False): + with self.lock: + if client["active"] is not record: + return + client["active"] = None + record["finished"], record["canceled"] = True, canceled + if client["notifications"]: + code = 703 if canceled else 702 + self.reply(client, f"{code}-1\r\n{code}-{clientId}\r\n{code} DONE\r\n") + + def serve_client(self, clientId, client): + try: + with client["socket"].makefile("rb") as stream: + for raw in stream: + command = raw.decode().strip() + response = "200 OK\r\n" + if command == "HISTORY GET CLIENT_ID": + response = f"245-{clientId}\r\n245 OK\r\n" + elif command == "LIST OUTPUT_MODULES": + response = "200-echo-a\r\n200-echo-b\r\n200-main\r\n200 OK\r\n" + elif command == "LIST SYNTHESIS_VOICES": + voice = {"echo-a": "Echo A", "echo-b": "Echo B", "main": "Main"}[client["module"]] + response = f"200-{voice}\ten\tnone\r\n200 OK\r\n" + elif command.startswith("GET "): + field = command.removeprefix("GET ") + response = (f"200-{client['settings'][field]}\r\n200 OK\r\n" + if self.defaultsSupported and field in client["settings"] else "500 UNSUPPORTED\r\n") + elif any(command.startswith("SET SELF " + field + " ") for field in client["settings"]): + _, _, field, value = command.split() + client["settings"][field] = int(value) + elif command.startswith("SET SELF OUTPUT_MODULE "): + client["module"] = command.removeprefix("SET SELF OUTPUT_MODULE ") + elif command.startswith("SET SELF SYNTHESIS_VOICE "): + client["voice"] = command.removeprefix("SET SELF SYNTHESIS_VOICE ") + elif command.startswith("SET SELF NOTIFICATION ALL "): + client["notifications"] = command.endswith(" on") + elif command.startswith("CANCEL "): + with self.lock: + targetId = int(command.split()[1]) + target = self.clients[targetId] + if target["active"] is not None: + self.finish(targetId, target, target["active"], canceled=True) + elif command == "SPEAK" or command.startswith("CHAR "): + parts = [] + if command == "SPEAK": + for line in stream: + if line == b".\r\n": + break + parts.append(line.decode().rstrip("\r\n")) + else: + parts.append(command.removeprefix("CHAR ")) + record = {"text": "\n".join(parts), "module": client["module"], + "voice": client["voice"], "finished": False, "canceled": False, + "settings": dict(client["settings"])} + with self.lock: + self.spoken.append(record) + client["active"] = record + self.reply(client, "230 OK\r\n200 QUEUED\r\n" if command == "SPEAK" else "225 QUEUED\r\n") + if client["notifications"]: + self.reply(client, f"701-1\r\n701-{clientId}\r\n701 BEGIN\r\n") + timer = threading.Timer(0.25, self.finish, args=(clientId, client, record)) + timer.daemon = True + timer.start() + continue + self.reply(client, response) + except (OSError, ValueError): + pass + + def snapshot(self): + with self.lock: + return [dict(record) for record in self.spoken] + + def close(self): + self.listener.close() + for client in self.clients.values(): + client["socket"].close() + + +def check_radio_buttons(controls, tabs, server, readerLog): + import pyatspi + + def radio_cues(): + records = [json.loads(line) for line in readerLog.read_text().splitlines() if line.startswith("{")] + return [record["cue"] for record in records if record.get("message") == "playing object sound" + and record.get("cue", "").startswith("radiobutton_")] + + assert tabs.querySelection().selectChild(0) + assert controls["Desktop"].queryComponent().grabFocus() + wait_for(lambda: radio_cues(), "initial radio sound did not play") + time.sleep(0.35) + for keyName, target in (("Right", "Laptop"), ("Left", "Desktop"), ("Right", "Laptop")): + cueOffset = len(radio_cues()) + speechOffset = len(server.snapshot()) + subprocess.run(["xdotool", "key", "--clearmodifiers", keyName], check=True) + wait_for(lambda: controls[target].getState().contains(pyatspi.STATE_CHECKED), target + " was not selected") + wait_for(lambda: len(radio_cues()) > cueOffset, target + " selection sound did not play") + # Cover the deferred focus cue and duplicate focus event after checking. + time.sleep(0.35) + cues = radio_cues()[cueOffset:] + assert cues == ["radiobutton_checked"], (keyName, target, cues) + assert any(target in record["text"] for record in server.snapshot()[speechOffset:]), target + " label was lost" + records = [json.loads(line) for line in readerLog.read_text().splitlines() if line.startswith("{")] + errors = [record for record in records if record.get("message") == "play sound" + and record.get("cue", "").startswith("radiobutton_") and record.get("error") != "context canceled"] + assert not errors, errors + + +def check_flat_review(tabs, server, readerLog): + def records(): + return [json.loads(line) for line in readerLog.read_text().splitlines() if line.startswith("{")] + + def key(*keys): + subprocess.run(["xdotool", "key", "--clearmodifiers", *keys], check=True) + + assert tabs.querySelection().selectChild(0) + key("ctrl+Page_Down", "ctrl+Page_Up") + wait_for(lambda: any(record["text"] == "General" for record in server.snapshot()) and + server.snapshot()[-1]["finished"], "General tab was not announced") + time.sleep(0.4) + for command in ("KP_Up", "KP_Page_Up", "KP_Right", "KP_Page_Down", "KP_End", "KP_Home"): + logOffset = len(records()) + speechOffset = len(server.snapshot()) + key(command) + def review_delivered(): + return any(record.get("message") == "delivering accessible presentation" and + record.get("cause") == "flat-review" for record in records()[logOffset:]) + wait_for(review_delivered, "flat review did not speak: " + command) + wait_for(lambda: len(server.snapshot()) > speechOffset and server.snapshot()[-1]["finished"], + "review speech did not finish: " + command) + # Include the focus replay after the key grab has been released. + time.sleep(0.4) + deliveries = [record for record in records()[logOffset:] + if record.get("message") == "delivering accessible presentation"] + assert deliveries and all(record.get("cause") == "flat-review" for record in deliveries), deliveries + assert not any(record["canceled"] for record in server.snapshot()[speechOffset:]) + assert tabs.querySelection().getSelectedChild(0).name == "General" + + speechOffset = len(server.snapshot()) + nextTab = tabs[1].name + key("Right") + wait_for(lambda: any(record["text"] == nextTab for record in server.snapshot()[speechOffset:]) and + server.snapshot()[-1]["finished"], "new tab focus was suppressed") + speechOffset = len(server.snapshot()) + key("Tab") + wait_for(lambda: len(server.snapshot()) > speechOffset and server.snapshot()[-1]["finished"], + "Tab into the page did not speak") + speechOffset = len(server.snapshot()) + key("shift+Tab") + wait_for(lambda: any(record["text"] == nextTab for record in server.snapshot()[speechOffset:]) and + server.snapshot()[-1]["finished"], "return to tab header was suppressed") + + +def check_interruption_summary(controls, tabs, server): + import pyatspi + + def key(*keys): + subprocess.run(["xdotool", "key", "--clearmodifiers", *keys], check=True) + + assert tabs.querySelection().selectChild(2) + summary = controls["Defined interruption keys"] + assert summary.queryText().getText(0, -1) == "Tab, Enter" + assert not summary.getState().contains(pyatspi.STATE_EDITABLE) + assert controls["Record interruption keys"].queryComponent().grabFocus() + offset = len(server.snapshot()) + key("Tab") + wait_for(lambda: any(record["text"] == "Tab, Enter" and record["finished"] + for record in server.snapshot()[offset:]), "read-only summary contents were not spoken on focus") + assert any(record["text"] == "Defined interruption keys" for record in server.snapshot()[offset:]) + key("Home") + for keyName, character, caret in (("Right", "a", 1), ("Left", "T", 0)): + offset = len(server.snapshot()) + key(keyName) + wait_for(lambda: summary.queryText().caretOffset == caret, "summary caret did not move for " + keyName) + wait_for(lambda: any(record["text"] == character and record["finished"] + for record in server.snapshot()[offset:]), "summary character was not spoken for " + keyName) + key("shift+Tab") + wait_for(lambda: controls["Record interruption keys"].getState().contains(pyatspi.STATE_FOCUSED), + "read-only summary trapped Shift+Tab") + + +def check_runtime(radioOnly=False, flatReviewOnly=False, interruptionOnly=False, noConfigOnly=False): + import pyatspi + directory = Path(tempfile.mkdtemp(prefix="cthulhu-echo-runtime-")) + binary = os.environ["CTHULHU_BINARY"] + wmConfig = directory / "i3.config" + wmConfig.write_text(f"font pango:monospace 10\nipc-socket {directory / 'i3.sock'}\n") + server = PreviewSpeechServer(directory / "speech.sock", defaultsSupported=os.environ.get("CTHULHU_PREFS_DEFAULTS_UNSUPPORTED") != "1") + wm = subprocess.Popen(["i3", "-c", str(wmConfig)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + reader = None + try: + wait_for(lambda: "0x" in subprocess.check_output(["xprop", "-root", "_NET_SUPPORTING_WM_CHECK"], text=True), "private WM missing") + configPath = directory / "settings.toml" + if not noConfigOnly: + configPath.write_text('''schema-version = 2 +active-profile = "default" +[profiles.default.speech] +output-module = "main" +[profiles.default.braille] +enabled = false +[profiles.default.sound] +enabled = false +[profiles.default.key-echo] +enabled = false +custom-voice = true +custom-speech-server = true +speech-server = "echo-a" +[profiles.default.key-echo.voice] +rate = 50 +average-pitch = 5 +gain = 5 +[profiles.default.key-echo.voice.family] +name = "Echo A" +lang = "en" +''') + if interruptionOnly: + with configPath.open("a") as settingsFile: + settingsFile.write('\n[profiles.default.speech.interruption]\nmode = "custom"\nkeys = ["Tab", "Return"]\n') + if radioOnly: + configPath.write_text(configPath.read_text().replace( + "[profiles.default.sound]\nenabled = false", + '[profiles.default.sound]\nenabled = true\nsink = "auto"\nplay-for-state = true\nrole-presentation-strategy = "sound_only"')) + readerEnv = os.environ.copy() + if noConfigOnly: + # Preferences checks must not launch Wine Access in live prefixes. + readerEnv["CTHULHU_WINE_ACCESS_HELPER"] = "/usr/bin/true" + if radioOnly or noConfigOnly: + import gi + gi.require_version("Gst", "1.0") + from gi.repository import Gst + Gst.init(None) + assert Gst.ElementFactory.find("fakeaudiosink"), "silent GStreamer audio sink is unavailable" + # Only the child reader sees these ranks. Auto audio can choose + # the fake sink; every real audio sink is excluded from discovery. + ranks = [] + for factory in Gst.Registry.get().get_feature_list(Gst.ElementFactory): + kind = factory.get_metadata("klass") or "" + if "Audio" in kind and "Sink" in kind: + rank = "MAX" if factory.get_name() == "fakeaudiosink" else "0" + ranks.append(factory.get_name() + ":" + rank) + readerEnv["GST_PLUGIN_FEATURE_RANK"] = ",".join(ranks) + reader = subprocess.Popen([binary, "--config", str(configPath), "--settings", "--no-tentacles", + "--speech-socket", str(directory / "speech.sock"), + "--debug-file", str(directory / "reader.log")], + env=readerEnv, stdout=subprocess.DEVNULL, stderr=(directory / "stderr.log").open("w")) + def find_window(): + for application in pyatspi.Registry.getDesktop(0): + for window in application: + if window and window.name == "Cthulhu Preferences": + return window + window = wait_for(find_window, "reader's preferences did not open") + def walk(node): + yield node + for child in node: + if child is not None: + yield from walk(child) + controls = {node.name: node for node in walk(window) if node.name} + xid = subprocess.check_output(["xdotool", "search", "--onlyvisible", "--name", "^Cthulhu Preferences$"], text=True).splitlines()[0] + subprocess.run(["xdotool", "windowactivate", "--sync", xid], check=True) + tabs = next(node for node in walk(window) if node.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + if noConfigOnly: + from native_speech_defaults import check_no_config + check_no_config(window, tabs, server, configPath) + print(f"PASS: missing config, editable speech sliders, server defaults/fallback, inheritance, Apply/save/reopen; evidence: {directory}") + return + if interruptionOnly: + check_interruption_summary(controls, tabs, server) + print(f"PASS: real reader speaks read-only interruption summary on focus and character arrows; Tab traversal preserved; evidence: {directory}") + return + if flatReviewOnly: + check_flat_review(tabs, server, directory / "reader.log") + print(f"PASS: notebook flat review has no repeated tab speech; tab changes and focus returns speak; evidence: {directory}") + return + if radioOnly: + check_radio_buttons(controls, tabs, server, directory / "reader.log") + print(f"PASS: real GTK Desktop/Laptop arrows play only the final selected sound and retain labels; evidence: {directory}") + return + assert tabs.querySelection().selectChild(4) + assert controls["Use custom echo voice"].queryComponent().grabFocus() + wait_for(lambda: any(record["text"] == "checked" and record["finished"] + for record in server.snapshot()), "initial checkbox announcement did not finish") + time.sleep(0.3) + def key(*keys): + subprocess.run(["xdotool", "key", "--clearmodifiers", *keys], check=True) + def check_output(keys, expected): + offset = len(server.snapshot()) + key(*keys) + def completed(): + records = server.snapshot()[offset:] + matching = [record for record in records if record["text"] in {text for text, _, _ in expected}] + return len(matching) >= len(expected) and all(record["finished"] for record in matching) + wait_for(completed, f"preview did not complete: {keys}") + # The original delayed menu-item event followed its preview by up + # to 160 ms. Require quiescence beyond that delay, then inspect all + # speech requests, including duplicates in the main voice. + time.sleep(0.25) + records = server.snapshot()[offset:] + got = [(record["text"], record["module"], record["voice"]) for record in records] + assert got == expected, (keys, got, expected) + assert not any(record["canceled"] for record in records), (keys, records) + check_output(("Tab",), [("Key echo speech synthesizer", "main", ""), ("echo-a", "echo-a", "Echo A")]) + check_output(("Down",), [("echo-b", "echo-b", "")]) + check_output(("Tab",), [("Key echo person", "main", ""), ("Default", "echo-b", "")]) + check_output(("Down",), [("Echo B (en)", "echo-b", "Echo B")]) + for control in ("rate", "pitch", "volume"): + value = "50.0" if control == "rate" else "5.0" + check_output(("Tab",), [("Key echo " + control, "main", ""), (value, "echo-b", "Echo B")]) + for control in ("pitch", "rate", "person", "synthesizer"): + value = {"pitch": "5.0", "rate": "50.0", "person": "Echo B (en)", "synthesizer": "echo-b"}[control] + label = "Key echo speech synthesizer" if control == "synthesizer" else "Key echo " + control + check_output(("shift+Tab",), [(label, "main", ""), (value, "echo-b", "Echo B")]) + print(f"PASS: real reader + GTK + SSIP focus/selection previews, voice completion, no duplicate menu-item speech; evidence: {directory}") + finally: + if reader is not None: + reader.terminate() + try: + reader.wait(timeout=5) + except subprocess.TimeoutExpired: + reader.kill() + reader.wait(timeout=5) + wm.terminate() + wm.wait(timeout=5) + server.close() + (directory / "speech.json").write_text(json.dumps(server.snapshot(), indent=2)) diff --git a/tests/native_firefox.py b/tests/native_firefox.py new file mode 100644 index 0000000..122e31b --- /dev/null +++ b/tests/native_firefox.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +"""Firefox AT-SPI baseline on a private X server, bus, and browser profile.""" + +import os +from pathlib import Path +import shutil +import subprocess +import sys +import tempfile +import time + +from native_test_session import run_private_session + + +ROOT = Path(__file__).resolve().parents[1] +PAGE = Path(__file__).with_name("firefox-baseline.html") + + +def run_inside(): + linked = os.environ.get("CTHULHU_FIREFOX_LINKED") == "1" + page = Path(__file__).with_name("browser-linked-headings.html") if linked else PAGE + browser = os.environ.get("CTHULHU_FIREFOX") or shutil.which("firefox") + if not browser: + raise RuntimeError("Firefox executable not found") + with tempfile.TemporaryDirectory(prefix="cthulhu-firefox-profile-") as profile: + Path(profile, "user.js").write_text( + 'user_pref("datareporting.policy.firstRunURL", "");\n' + 'user_pref("browser.startup.homepage_override.mstone", "ignore");\n', + encoding="utf-8", + ) + with tempfile.TemporaryFile() as log: + environment = dict(os.environ, MOZ_ACCESSIBILITY_ENABLED="1") + process = subprocess.Popen( + [browser, "--no-remote", "--profile", profile, "--new-window", page.resolve().as_uri()], + env=environment, stdout=log, stderr=log, + ) + try: + deadline = time.monotonic() + 25 + while time.monotonic() < deadline: + if process.poll() is not None: + log.seek(0) + raise RuntimeError("Firefox exited before the probe: " + log.read().decode(errors="replace")) + result = subprocess.run( + ["xdotool", "search", "--onlyvisible", "--name", "Cthulhu Linked Headings Probe" if linked else "Cthulhu Firefox Baseline"], + capture_output=True, text=True, + ) + if result.stdout.strip(): + window = result.stdout.splitlines()[0] + subprocess.run(["xdotool", "windowfocus", window], check=True) + break + time.sleep(0.1) + else: + raise RuntimeError("Firefox fixture window missing") + environment["CTHULHU_NATIVE_FIREFOX"] = "1" + environment.setdefault("GOCACHE", "/tmp/cthulhu-cache") + if linked: + environment["CTHULHU_NATIVE_LINKED_HEADINGS"] = "1" + subprocess.run( + ["go", "test", "./internal/app", "-run", "^TestNativeLinkedHeadings$", + "-count=1", "-v", "-timeout=45s"], + cwd=ROOT, env=environment, check=True, timeout=50, + ) + return + subprocess.run( + ["go", "test", "./internal/atspi", "-run", "^TestNativeFirefoxBaseline$", + "-count=1", "-v", "-timeout=45s"], + cwd=ROOT, env=environment, check=True, timeout=55, + ) + subprocess.run( + ["go", "test", "./internal/app", "-run", "^TestNativeBrowserTabs$", + "-count=1", "-v", "-timeout=30s"], + cwd=ROOT, env=environment, check=True, timeout=35, + ) + finally: + process.terminate() + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + + +def main(): + if len(sys.argv) == 2 and sys.argv[1] == "--inside": + run_inside() + return + read_fd, write_fd = os.pipe() + server = subprocess.Popen( + ["Xvfb", "-displayfd", str(write_fd), "-screen", "0", "800x600x24", "-nolisten", "tcp"], + pass_fds=(write_fd,), stderr=subprocess.DEVNULL, + ) + os.close(write_fd) + try: + with os.fdopen(read_fd) as reader: + display = reader.readline().strip() + if not display: + raise RuntimeError("Xvfb failed to start") + environment = dict(os.environ, DISPLAY=":" + display, XDG_SESSION_TYPE="x11") + environment.pop("DBUS_SESSION_BUS_ADDRESS", None) + environment.pop("AT_SPI_BUS_ADDRESS", None) + environment.pop("WAYLAND_DISPLAY", None) + run_private_session( + ["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), "--inside"], + env=environment, check=True, timeout=90, + ) + finally: + server.terminate() + server.wait(timeout=3) + + +if __name__ == "__main__": + main() diff --git a/tests/native_internal_ui.py b/tests/native_internal_ui.py new file mode 100644 index 0000000..f480393 --- /dev/null +++ b/tests/native_internal_ui.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python3 +"""Run actions and editable internal controls on a private X11/AT-SPI desktop.""" +import json +import os +from pathlib import Path +import subprocess +import sys +import tempfile +import time + +from native_test_session import run_private_session + + +def run_inside(): + root = Path(__file__).resolve().parents[1] + environment = dict(os.environ, GOCACHE="/tmp/cthulhu-cache", CTHULHU_NATIVE_X11="1", + CTHULHU_NATIVE_BROWSER="1") + probe = subprocess.Popen(["xev", "-name", "Internal UI background", "-event", "keyboard"], + stdout=subprocess.DEVNULL) + try: + deadline = time.monotonic() + 5 + while True: + found = subprocess.run(["xdotool", "search", "--onlyvisible", "--name", "^Internal UI background$"], + capture_output=True, text=True) + if found.returncode == 0: + background = found.stdout.strip().splitlines()[0] + environment["CTHULHU_UI_BACKGROUND"] = background + subprocess.run(["xdotool", "windowfocus", background], check=True) + break + if time.monotonic() >= deadline: + raise RuntimeError("keyboard probe did not open") + time.sleep(0.02) + subprocess.run(["go", "test", "./internal/platform/xorg", "-count=1", "-timeout=60s", + "-run", "^TestNative(InternalUICapturesAndReleases|LearnModeCapturesKeysAndRestoresCommands|CustomBindingsUpdateAndRelease|CommandGrabSuspensionAndRestoration|SecureInputDropsKeysAndRestoresGrabs|BrowseKeyTransitions)$"], + cwd=root, env=environment, check=True) + finally: + probe.terminate() + probe.wait(timeout=5) + with tempfile.TemporaryDirectory(prefix="cthulhu-internal-ui-") as temporary: + marker = Path(temporary) / "state.json" + environment.update(CTHULHU_UI_MARKER=str(marker), CTHULHU_NATIVE_INTERNAL_UI="1") + fixture = subprocess.Popen([sys.executable, __file__, "--fixture"], env=environment) + try: + deadline = time.monotonic() + 10 + window = "" + while time.monotonic() < deadline: + found = subprocess.run(["xdotool", "search", "--onlyvisible", "--name", + "^Internal UI action probe$"], capture_output=True, text=True) + if found.returncode == 0: + window = found.stdout.strip().splitlines()[0] + break + time.sleep(0.02) + if not window: + raise RuntimeError("GTK fixture did not open") + subprocess.run(["xdotool", "windowfocus", "--sync", window], check=True) + subprocess.run(["go", "test", "./internal/app", "-count=1", "-timeout=30s", + "-run", "^TestNative(InternalUIActionsAndEntry|TentacleClipboardTargetsAndTemporaryImage)$"], + cwd=root, env=environment, check=True) + finally: + fixture.terminate() + fixture.wait(timeout=5) + + +def run_fixture(): + import gi + gi.require_version("Gtk", "3.0") + from gi.repository import Gtk + window = Gtk.Window(title="Internal UI action probe") + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + button = Gtk.Button(label="Run action") + entry = Gtk.Entry() + entry.get_accessible().set_name("Application text") + box.pack_start(button, False, False, 0) + box.pack_start(entry, False, False, 0) + lines = Gtk.TextView() + lines.get_accessible().set_name("Transfer text lines") + lines.get_buffer().set_text("First line\nSecond line") + lines.get_buffer().place_cursor(lines.get_buffer().get_start_iter()) + box.pack_start(lines, False, False, 0) + password = Gtk.Entry() + password.set_visibility(False) + password.set_text("private fixture password") + password.get_accessible().set_name("Protected transfer text") + box.pack_start(password, False, False, 0) + window.add(box) + state = {"clicks": 0, "text": ""} + marker = Path(os.environ["CTHULHU_UI_MARKER"]) + + def save(): + replacement = marker.with_suffix(".tmp") + replacement.write_text(json.dumps(state)) + replacement.replace(marker) + + def clicked(_button): + state["clicks"] += 1 + save() + + def changed(_entry): + state["text"] = entry.get_text() + save() + + button.connect("clicked", clicked) + entry.connect("changed", changed) + window.connect("destroy", Gtk.main_quit) + window.show_all() + button.grab_focus() + save() + Gtk.main() + + +if __name__ == "__main__": + if "--fixture" in sys.argv: + run_fixture() + elif "--inside" in sys.argv: + run_inside() + else: + run_private_session(["xvfb-run", "-a", "dbus-run-session", "--", sys.executable, + __file__, "--inside"], check=True, + env=dict(os.environ, GTK_MODULES="gail:atk-bridge", NO_AT_BRIDGE="0")) diff --git a/tests/native_libreoffice.py b/tests/native_libreoffice.py new file mode 100644 index 0000000..5a2c0d3 --- /dev/null +++ b/tests/native_libreoffice.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python3 +"""Real Calc through the production reader, in a private X11/AT-SPI session.""" + +import os +from contextlib import ExitStack +from pathlib import Path +import shutil +import signal +import subprocess +import sys +import tempfile +import time + +from native_test_session import run_private_session + + +def wait_for(check, message, timeout=15): + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + result = check() + if result: + return result + time.sleep(0.05) + raise RuntimeError(message) + + +def run_inside(): + import gi + gi.require_version("Atspi", "2.0") + from gi.repository import Atspi + + with tempfile.TemporaryDirectory(prefix="cthulhu-libreoffice-") as temporary, ExitStack() as cleanup: + root = Path(temporary) + # Workbook and modal-dialog activation need a window manager's focus + # protocol, rather than bare XSetInputFocus on a virtual display. + wmConfig = root / "i3.config" + wmConfig.write_text( + 'font pango:monospace 10\nfocus_follows_mouse no\n' + f'ipc-socket {root / "i3.sock"}\n', encoding="utf-8", + ) + windowManager = subprocess.Popen( + ["i3", "-a", "-c", str(wmConfig)], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, + ) + + def stop_window_manager(): + if windowManager.poll() is None: + windowManager.terminate() + windowManager.wait(timeout=5) + + cleanup.callback(stop_window_manager) + wait_for(lambda: "0x" in subprocess.check_output( + ["xprop", "-root", "_NET_SUPPORTING_WM_CHECK"], text=True), + "Private i3 window manager missing") + profile = root / "profile" / "user" + profile.mkdir(parents=True) + (profile / "registrymodifications.xcu").write_text( + '' + '' + 'false' + 'false' + '', encoding="utf-8", + ) + document = root / "Example.fods" + shutil.copyfile(Path(__file__).with_name("libreoffice.fods"), document) + secondDocument = root / "Other.fods" + shutil.copyfile(document, secondDocument) + environment = dict(os.environ, SAL_USE_VCLPLUGIN="gtk3", + LC_ALL="C.UTF-8", + GTK_MODULES="gail:atk-bridge", NO_AT_BRIDGE="0", + XDG_CONFIG_HOME=str(root / "config"), + XDG_CACHE_HOME=str(root / "cache"), + XDG_DATA_HOME=str(root / "data")) + application = subprocess.Popen( + ["libreoffice", "-env:UserInstallation=" + (root / "profile").as_uri(), + "--norestore", "--nodefault", "--nofirststartwizard", "--calc", str(document)], + env=environment, start_new_session=True, + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, + ) + try: + def find_window(): + result = subprocess.run( + ["xdotool", "search", "--onlyvisible", "--class", "libreoffice-calc"], + capture_output=True, text=True, check=False, + ) + return result.stdout.splitlines()[-1] if result.stdout.strip() else None + + window = wait_for(find_window, "Calc window missing") + # Wait for the actual accessible sheet, without enumerating its + # millions of cells. Dismiss disposable first-run UI if present. + def ready(): + pending = [Atspi.get_desktop(0)] + remaining = 2500 + found = False + while pending and remaining: + node = pending.pop() + remaining -= 1 + role = node.get_role_name() + if role == "table": + parent = node.get_parent() + found |= parent is not None and parent.get_role_name() == "document spreadsheet" + continue + if role == "dialog" and node.get_name() == "Welcome to LibreOffice!": + subprocess.run(["xdotool", "key", "Escape"], check=True) + return False + if role == "table cell": + continue + for index in range(min(node.get_child_count(), 200)): + child = node.get_child_at_index(index) + if child is not None: + pending.append(child) + return found + + wait_for(ready, "Calc accessible sheet missing") + environment.update(CTHULHU_NATIVE_LIBREOFFICE="1", CTHULHU_CALC_WINDOW=window, + CTHULHU_CALC_PROFILE=(root / "profile").as_uri(), + CTHULHU_CALC_SECOND_DOCUMENT=str(secondDocument)) + environment.setdefault("GOCACHE", "/tmp/cthulhu-go-cache") + subprocess.run( + ["go", "test", "./internal/app", "-run", "^TestNativeLibreOfficeCalc$", + "-count=1", "-timeout=80s", "-v"], + cwd=Path(__file__).resolve().parents[1], env=environment, + check=True, timeout=90, + ) + finally: + if application.poll() is None: + os.killpg(application.pid, signal.SIGTERM) + application.wait(timeout=5) + + +def select_disjoint(): + """Mutate only the disposable fixture, without walking sheet cells.""" + if os.environ.get("CTHULHU_NATIVE_LIBREOFFICE") != "1": + raise RuntimeError("Selection helper requires the private Calc harness") + import gi + gi.require_version("Atspi", "2.0") + from gi.repository import Atspi + + pending = [Atspi.get_desktop(0)] + remaining = 2500 + while pending and remaining: + node = pending.pop() + remaining -= 1 + if node.get_role_name() == "table": + if node.get_name() == "Sheet Second": + node.clear_selection() + node.select_child(0) + node.select_child(2) + return + continue + for index in range(min(node.get_child_count(), 200)): + child = node.get_child_at_index(index) + if child is not None: + pending.append(child) + raise RuntimeError("Disposable selection fixture missing") + + +def main(): + if sys.argv[1:] == ["--select-disjoint"]: + select_disjoint() + return + if sys.argv[1:] == ["--inside"]: + run_inside() + return + with tempfile.TemporaryDirectory(prefix="cthulhu-libreoffice-session-") as temporary: + environment = dict(os.environ, XDG_SESSION_TYPE="x11", + XDG_CONFIG_HOME=temporary, XDG_CACHE_HOME=temporary, + XDG_DATA_HOME=temporary) + for name in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY", "I3SOCK"): + environment.pop(name, None) + run_private_session( + ["xvfb-run", "-a", "dbus-run-session", "--", sys.executable, + str(Path(__file__).resolve()), "--inside"], + env=environment, check=True, timeout=120, + ) + + +if __name__ == "__main__": + main() diff --git a/tests/native_mozilla.py b/tests/native_mozilla.py new file mode 100644 index 0000000..a0b89d1 --- /dev/null +++ b/tests/native_mozilla.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python3 +"""Firefox/Thunderbird reading with a private reader, X11, profile and SSIP.""" +import argparse +import json +import os +from pathlib import Path +import shutil +import subprocess +import sys +import tempfile + +sys.dont_write_bytecode = True +from native_echo_preview import PreviewSpeechServer +from native_x11 import wait_for +from native_test_session import run_private_session + + +TITLE = "Cthulhu Mozilla Reading Probe" +CONTENT = ["Reading start", "First readable paragraph.", "Reading section", + "Second readable paragraph.", "Local destination link", "Final readable paragraph."] +HTML = f'''{TITLE} +

{CONTENT[0]}

{CONTENT[1]}

{CONTENT[2]}

+

{CONTENT[3]}

{CONTENT[4]} +

{CONTENT[5]}

''' + + +def write_profile(profile, application): + profile.mkdir() + prefs = {"browser.startup.homepage_override.mstone": "ignore", + "datareporting.policy.firstRunURL": "", + "browser.shell.checkDefaultBrowser": False, + "browser.startup.page": 0, + "browser.newtabpage.enabled": False, + "datareporting.policy.dataSubmissionEnabled": False} + if application == "thunderbird": + (profile / "Mail" / "Local Folders").mkdir(parents=True) + prefs.update({"mail.shell.checkDefaultClient": False, + "mailnews.start_page.enabled": False, + "mail.provider.enabled": False, + "mail.rights.override": True, + "mailnews.database.global.indexer.enabled": False, + "mail.accountmanager.accounts": "account1", + "mail.accountmanager.defaultaccount": "account1", + "mail.accountmanager.localfoldersserver": "server1", + "mail.account.account1.server": "server1", + "mail.account.account1.identities": "id1", + "mail.server.server1.type": "none", + "mail.server.server1.hostname": "Local Folders", + "mail.server.server1.userName": "nobody", + "mail.server.server1.name": "Local Folders", + "mail.server.server1.directory": str(profile / "Mail" / "Local Folders"), + "mail.server.server1.directory-rel": "[ProfD]Mail/Local Folders", + "mail.identity.id1.fullName": "Username", + "mail.identity.id1.useremail": "username@example.invalid", + "mail.identity.id1.valid": True, + "mail.compose.autosave": False}) + (profile / "user.js").write_text("".join( + f"user_pref({json.dumps(key)}, {json.dumps(value)});\n" for key, value in prefs.items())) + + +def walk(node): + if node is not None: + yield node + for child in node: + yield from walk(child) + + +def run_inside(application): + import pyatspi + directory = Path(os.environ["CTHULHU_MOZILLA_EVIDENCE"]) + executable = shutil.which(application) + if not executable: + raise RuntimeError(f"{application} executable missing") + profile = directory / "profile" + write_profile(profile, application) + fixture = directory / "reading.html" + fixture.write_text(HTML) + args = [executable, "--no-remote", "--profile", str(profile), "--new-window", fixture.as_uri()] + if application == "thunderbird": + fixture = directory / "message.eml" + fixture.write_text("From: Username \n" + "To: Recipient \n" + f"Subject: {TITLE}\nMIME-Version: 1.0\n" + "Content-Type: text/html; charset=UTF-8\n\n" + HTML) + args = [executable, "--no-remote", "--profile", str(profile), "-file", str(fixture)] + config = directory / "settings.toml" + config.write_text('''schema-version = 2 +active-profile = "default" +[profiles.default.speech] +output-module = "main" +[profiles.default.braille] +enabled = false +[profiles.default.sound] +enabled = false +[profiles.default.key-echo] +enabled = false +''') + wmConfig = directory / "i3.config" + wmConfig.write_text(f"font pango:monospace 10\nipc-socket {directory / 'i3.sock'}\n") + server = PreviewSpeechServer(directory / "speech.sock") + processes, report = [], [] + logPath = directory / "reader.log" + + def key(chord): + subprocess.run(["xdotool", "key", "--clearmodifiers", chord], check=True) + + def find_document(): + for app in pyatspi.Registry.getDesktop(0): + if app.name.lower() == application: + for node in walk(app): + if node.getRoleName() == "document web" and node.name == TITLE: + return node + + def check(chord, expected): + offset = len(server.snapshot()) + key(chord) + wait_for(lambda: any(row["text"] == expected + for row in server.snapshot()[offset:]), + f"{application}: {chord} did not speak {expected!r}", timeout=8) + # Normal presentation queues several chunks without SSIP end events. + # The recorder completes the final chunk; earlier chunks can remain open. + wait_for(lambda: server.snapshot()[-1]["finished"], "presentation did not settle") + rows = server.snapshot()[offset:] + actual = [row["text"] for row in rows if row["text"] in CONTENT] + assert actual == [expected], (chord, expected, rows) + assert not any("Could not" in row["text"] for row in rows), (chord, rows) + report.append({"key": chord, "expected": expected, "speech": rows}) + + try: + processes.append(subprocess.Popen(["i3", "-c", str(wmConfig)], + stdout=subprocess.DEVNULL, stderr=(directory / "wm.log").open("w"))) + wait_for(lambda: "0x" in subprocess.check_output( + ["xprop", "-root", "_NET_SUPPORTING_WM_CHECK"], text=True), "private WM missing") + processes.append(subprocess.Popen([ + os.environ["CTHULHU_BINARY"], "--config", str(config), "--no-tentacles", + "--speech-socket", str(directory / "speech.sock"), "--debug-file", str(logPath)], + stdout=subprocess.DEVNULL, stderr=(directory / "reader-stderr.log").open("w"))) + wait_for(lambda: logPath.exists() and "remote D-Bus service ready" in logPath.read_text(), + "private reader missing") + processes.append(subprocess.Popen(args, env=dict(os.environ, MOZ_ACCESSIBILITY_ENABLED="1"), + stdout=subprocess.DEVNULL, stderr=(directory / "application.log").open("w"))) + document = wait_for(find_document, "fixture document missing", timeout=25) + window = subprocess.check_output(["xdotool", "search", "--onlyvisible", "--name", TITLE], + text=True).splitlines()[0] + subprocess.run(["xdotool", "windowactivate", "--sync", window], check=True) + assert document.queryComponent().grabFocus(), "document refused focus" + wait_for(lambda: document.getState().contains(pyatspi.STATE_FOCUSED), "document not focused") + wait_for(lambda: server.snapshot() and server.snapshot()[-1]["finished"], + "initial focus presentation did not settle") + check("ctrl+Home", CONTENT[0]) + for text in CONTENT[1:]: + check("Down", text) + for text in reversed(CONTENT[:-1]): + check("Up", text) + check("h", CONTENT[2]) + check("Down", CONTENT[3]) + check("shift+h", CONTENT[2]) + check("shift+h", CONTENT[0]) + check("k", CONTENT[4]) + check("ctrl+Home", CONTENT[0]) + offset = len(server.snapshot()) + key("KP_Add") + wait_for(lambda: any(row["text"] == CONTENT[-1] and row["finished"] + for row in server.snapshot()[offset:]), "Read All did not finish", timeout=12) + rows = server.snapshot()[offset:] + assert [row["text"] for row in rows if row["text"] in CONTENT] == CONTENT, rows + assert not any("Could not" in row["text"] for row in rows), rows + report.append({"key": "KP_Add", "speech": rows}) + print(f"PASS: {application} forward/reverse lines, heading-to-arrow, link and Read All", flush=True) + finally: + for process in reversed(processes): + process.terminate() + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + server.close() + (directory / "report.json").write_text(json.dumps(report, indent=2)) + (directory / "speech.json").write_text(json.dumps(server.snapshot(), indent=2)) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("application", choices=("firefox", "thunderbird", "both"), nargs="?", default="both") + parser.add_argument("--inside", action="store_true", help=argparse.SUPPRESS) + args = parser.parse_args() + if not os.environ.get("CTHULHU_BINARY"): + parser.error("Set CTHULHU_BINARY to a freshly built reader") + if args.inside: + run_inside(args.application) + return + applications = ("firefox", "thunderbird") if args.application == "both" else (args.application,) + for application in applications: + directory = Path(tempfile.mkdtemp(prefix=f"cthulhu-{application}-reading-")) + print(f"{application} evidence: {directory}", flush=True) + environment = dict(os.environ, XDG_SESSION_TYPE="x11", CTHULHU_MOZILLA_EVIDENCE=str(directory)) + for name in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + environment.pop(name, None) + with (directory / "session.log").open("w") as log: + run_private_session(["xvfb-run", "-a", "-s", "-screen 0 1280x900x24", "dbus-run-session", "--", + sys.executable, str(Path(__file__).resolve()), application, "--inside"], + env=environment, stderr=log, check=True, timeout=120) + + +if __name__ == "__main__": + main() diff --git a/tests/native_notifications.py b/tests/native_notifications.py new file mode 100755 index 0000000..a83905d --- /dev/null +++ b/tests/native_notifications.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 +"""Private Xvfb/AT-SPI proof for the Go notification-list helper.""" +import json +import os +from pathlib import Path +import select +import subprocess +import sys + +sys.dont_write_bytecode = True +from native_x11 import wait_for +from native_test_session import run_private_session + + +def inside(): + import pyatspi + + binary = os.environ.get("CTHULHU_BINARY", str(Path(__file__).resolve().parents[1] / "cthulhu")) + process = subprocess.Popen( + [binary, "--notification-list-ui"], stdin=subprocess.PIPE, + stdout=subprocess.PIPE, text=True, + ) + + def send(value): + process.stdin.write(json.dumps(value) + "\n") + process.stdin.flush() + + def request(): + assert select.select([process.stdout], [], [], 5)[0], "no notification-list request" + return json.loads(process.stdout.readline()) + + def walk(node): + yield node + for child in node: + if child is not None: + yield from walk(child) + + def find_window(): + for application in pyatspi.Registry.getDesktop(0): + for node in application: + if node and node.name == "2 notifications": + return node + return None + + def press(node): + assert node.queryComponent().grabFocus(), ("cannot focus", node.name) + subprocess.run(["xdotool", "key", "--clearmodifiers", "space"], check=True) + + def refresh_controls(): + controls.clear() + for node in walk(window): + if node.name: + controls.setdefault(node.name, node) + + def entry(identifier, message, received, can_control=False, actions=None): + return {"id": identifier, "message": message, "received": received, + "canControl": can_control, "actions": actions or []} + + initial = { + "title": "2 notifications", + "selected": "1", + "entries": [ + entry("1", "Live message", "0 seconds ago", True, [ + {"key": "default", "label": "View"}, + {"key": "reply", "label": "Reply"}, + ]), + entry("0", "Older message", "1 minute ago"), + ], + } + try: + send(initial) + window = wait_for(find_window, "notification accessible window missing") + nodes = list(walk(window)) + controls = {} + for node in nodes: + if node.name: + controls.setdefault(node.name, node) + + table = next(node for node in nodes if node.getRole() == pyatspi.ROLE_TABLE) + assert table.name == "2 notifications", table.name + names = {node.name for node in nodes} + for name in ("Live message", "Older message", "0 seconds ago", "1 minute ago", + "Copy", "Dismiss Notification", "Clear", "Close", "View", "Reply"): + assert name in names, ("missing accessible name", name) + interactive_roles = { + pyatspi.ROLE_PUSH_BUTTON, pyatspi.ROLE_TABLE, pyatspi.ROLE_TABLE_CELL, + } + unnamed = sorted(node.getRoleName() for node in nodes + if node.getRole() in interactive_roles and not node.name) + assert not unnamed, ("unnamed interactive controls", unnamed) + assert "Dismiss Notification" in controls + assert controls["Dismiss Notification"].getState().contains(pyatspi.STATE_SENSITIVE) + + xid = subprocess.check_output( + ["xdotool", "search", "--onlyvisible", "--name", "^2 notifications$"], text=True, + ).splitlines()[0] + subprocess.run(["xdotool", "windowfocus", xid], check=True) + assert table.queryComponent().grabFocus(), "cannot focus notification table" + subprocess.run(["xdotool", "key", "--clearmodifiers", "Down"], check=True) + selected = request() + assert selected == {"selection": "0", "row": 1}, selected + send(dict(initial, selected="0")) + + wait_for(lambda: "Notification is no longer available" in { + node.name for node in walk(window) + }, "unavailable action status missing") + assert not controls["Dismiss Notification"].getState().contains(pyatspi.STATE_SENSITIVE) + assert "View" not in {node.name for node in walk(window)} + assert "Reply" not in {node.name for node in walk(window)} + + send(dict(initial, selected="1")) + wait_for(lambda: controls["Dismiss Notification"].getState().contains(pyatspi.STATE_SENSITIVE), + "live selection did not restore controls") + refresh_controls() + press(controls["Reply"]) + invoked = request() + assert invoked == {"action": "reply", "selection": "1", "row": 0}, invoked + send(dict(initial, selected="1")) + refresh_controls() + + press(controls["Copy"]) + copied = request() + assert copied == {"copy": True}, copied + + press(controls["Dismiss Notification"]) + dismissed = request() + assert dismissed == {"dismiss": True, "selection": "1", "row": 0}, dismissed + send({"title": "1 notification", "selected": "0", + "entries": [entry("0", "Older message", "1 minute ago")]}) + refresh_controls() + + press(controls["Clear"]) + cleared = request() + assert cleared == {"clear": True}, cleared + send({"close": True}) + assert process.wait(timeout=5) == 0 + assert process.stdout.read() == "", "clear submitted extra requests" + print("PASS: notification list accessibility, selection refresh, actions, copy, dismiss, clear") + finally: + if process.poll() is None: + process.kill() + process.wait(timeout=5) + + +def main(): + if "--inside" in sys.argv: + inside() + return + read_fd, write_fd = os.pipe() + server = subprocess.Popen( + ["Xvfb", "-displayfd", str(write_fd), "-screen", "0", "1024x768x24", "-nolisten", "tcp"], + pass_fds=(write_fd,), stderr=subprocess.DEVNULL, + ) + os.close(write_fd) + try: + with os.fdopen(read_fd) as reader: + display = reader.readline().strip() + assert display, "Xvfb failed" + environment = dict( + os.environ, DISPLAY=":" + display, GDK_BACKEND="x11", + GTK_MODULES="gail:atk-bridge", GIO_USE_VFS="local", + ) + for key in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + environment.pop(key, None) + run_private_session( + ["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), "--inside"], + env=environment, check=True, timeout=60, + ) + finally: + server.terminate() + server.wait(timeout=5) + + +if __name__ == "__main__": + main() diff --git a/tests/native_ownership.py b/tests/native_ownership.py new file mode 100644 index 0000000..55866ef --- /dev/null +++ b/tests/native_ownership.py @@ -0,0 +1,356 @@ +#!/usr/bin/env python3 +# Copyright (c) 2026 Storm Dragon +# Authors: Storm Dragon, Angus Kola +# SPDX-License-Identifier: GPL-3.0-or-later +"""GTK/Qt keyboard fixture and isolated X11 foreground acceptance proof.""" +import json +import os +from pathlib import Path +import subprocess +import sys +import tempfile + +sys.dont_write_bytecode = True +from native_x11 import wait_for +from native_test_session import run_private_session + + +def fixture(toolkit): + title = "Cthulhu " + toolkit + " Controls" + if toolkit == "GTK": + import gi + gi.require_version("Gtk", "3.0") + gi.require_version("Gdk", "3.0") + from gi.repository import Gdk, Gtk + window = Gtk.Window(title=title) + window.set_default_size(500, 650) + window.connect("destroy", Gtk.main_quit) + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) + window.add(box) + def add(widget, name): + widget.get_accessible().set_name(name) + box.pack_start(widget, False, False, 0) + return widget + button = add(Gtk.Button(label="Open dialog"), "Open dialog") + def dialog(*args): + child = Gtk.Dialog(title="Ownership dialog", transient_for=window, modal=True) + entry = Gtk.Entry() + entry.get_accessible().set_name("Dialog entry") + child.get_content_area().add(entry) + child.add_button("Close", Gtk.ResponseType.CLOSE) + child.show_all() + child.run() + child.destroy() + button.connect("clicked", dialog) + add(Gtk.CheckButton(label="Updates"), "Updates") + radio = add(Gtk.RadioButton.new_with_label(None, "Automatic"), "Automatic") + add(Gtk.RadioButton.new_with_label_from_widget(radio, "Manual"), "Manual") + add(Gtk.Entry(), "Example text") + combo = add(Gtk.ComboBoxText(), "Choice") + for text in ("Alpha", "Beta", "Gamma"): combo.append_text(text) + combo.set_active(0) + add(Gtk.SpinButton.new_with_range(0, 100, 1), "Amount") + add(Gtk.Scale.new_with_range(Gtk.Orientation.HORIZONTAL, 0, 100, 1), "Level") + for tree, name in ((False, "Results"), (True, "Folders")): + store = Gtk.TreeStore(str) if tree else Gtk.ListStore(str) + if tree: + parent = store.append(None, ["Parent folder"]) + store.append(parent, ["Child folder"]) + else: + for text in ("First result", "Second result"): store.append([text]) + view = add(Gtk.TreeView(model=store), name) + view.append_column(Gtk.TreeViewColumn(name, Gtk.CellRendererText(), text=0)) + view.set_size_request(-1, 80) + disabled = add(Gtk.Button(label="Unavailable action"), "Unavailable action") + disabled.set_sensitive(False) + menu = Gtk.MenuBar() + root = Gtk.MenuItem.new_with_mnemonic("_Actions") + submenu = Gtk.Menu() + submenu.append(Gtk.MenuItem(label="Example action")) + unavailable = Gtk.MenuItem(label="Unavailable menu action") + unavailable.set_sensitive(False) + submenu.append(unavailable) + root.set_submenu(submenu) + menu.append(root) + box.pack_start(menu, False, False, 0) + siblings = [] + def on_key(_window, event): + if event.keyval == Gdk.KEY_F7: + popup = Gtk.Menu() + popup.append(Gtk.MenuItem(label="First link")) + popup.append(Gtk.MenuItem(label="Second link")) + popup.show_all() + popup.popup_at_widget(button, Gdk.Gravity.SOUTH_WEST, Gdk.Gravity.NORTH_WEST, None) + return True + if event.keyval != Gdk.KEY_F6: return False + sibling = Gtk.Window(title="Ownership sibling") + sibling.set_default_size(350, 200) + entry = Gtk.Entry() + entry.get_accessible().set_name("Sibling entry") + sibling.add(entry) + sibling.show_all() + sibling.present() + siblings.append(sibling) + return True + window.connect("key-press-event", on_key) + window.show_all() + button.grab_focus() + Gtk.main() + else: + from PySide6 import QtCore, QtWidgets + app = QtWidgets.QApplication([]) + window = QtWidgets.QWidget() + window.setWindowTitle(title) + layout = QtWidgets.QVBoxLayout(window) + def add(widget, name): + widget.setAccessibleName(name) + layout.addWidget(widget) + return widget + button = add(QtWidgets.QPushButton("Open dialog"), "Open dialog") + def dialog(): + child = QtWidgets.QDialog(window) + child.setWindowTitle("Ownership dialog") + content = QtWidgets.QVBoxLayout(child) + entry = QtWidgets.QLineEdit() + entry.setAccessibleName("Dialog entry") + content.addWidget(entry) + close = QtWidgets.QPushButton("Close") + close.clicked.connect(child.accept) + content.addWidget(close) + child.exec() + button.clicked.connect(dialog) + add(QtWidgets.QCheckBox("Updates"), "Updates") + radio = add(QtWidgets.QRadioButton("Automatic"), "Automatic") + radio.setChecked(True) + add(QtWidgets.QRadioButton("Manual"), "Manual") + add(QtWidgets.QLineEdit(), "Example text") + combo = add(QtWidgets.QComboBox(), "Choice") + combo.addItems(["Alpha", "Beta", "Gamma"]) + add(QtWidgets.QSpinBox(), "Amount") + add(QtWidgets.QSlider(QtCore.Qt.Horizontal), "Level") + view = add(QtWidgets.QListWidget(), "Results") + view.addItems(["First result", "Second result"]) + tree = add(QtWidgets.QTreeWidget(), "Folders") + tree.setHeaderLabels(["Folders"]) + parent = QtWidgets.QTreeWidgetItem(tree, ["Parent folder"]) + QtWidgets.QTreeWidgetItem(parent, ["Child folder"]) + table = add(QtWidgets.QTableWidget(2, 2), "Table") + for row in range(2): + for col in range(2): table.setItem(row, col, QtWidgets.QTableWidgetItem(f"Cell {row+1} {col+1}")) + disabled = add(QtWidgets.QPushButton("Unavailable action"), "Unavailable action") + disabled.setEnabled(False) + menu = QtWidgets.QMenuBar() + root = menu.addMenu("&Actions") + root.addAction("Example action") + root.addAction("Unavailable menu action").setEnabled(False) + layout.addWidget(menu) + window.resize(500, 650) + window.show() + button.setFocus() + app.exec() + + +def inside(directory): + root = Path(directory) + processes = [] + log = root / "cthulhu.log" + def run(*args): + return subprocess.check_output(args, text=True).strip() + def records(): + if not log.exists(): return [] + return [json.loads(line) for line in log.read_text().splitlines() if line.endswith("}")] + def wait_record(message, start=0, **fields): + return wait_for(lambda: next((r for r in records()[start:] if r.get("message") == message and all(r.get(k) == v for k,v in fields.items())), None), message + " " + str(fields)) + def key(*keys): run("xdotool", "key", "--clearmodifiers", *keys) + def activate(xid): run("xdotool", "windowactivate", "--sync", xid) + def find(title): + def search(): + p = subprocess.run(["xdotool", "search", "--onlyvisible", "--name", "^"+title+"$"], capture_output=True, text=True) + return p.stdout.strip().splitlines()[0] if p.stdout.strip() else None + return wait_for(search, "missing " + title) + try: + wm_config = root / "i3.conf" + wm_config.write_text('font pango:monospace 10\nfocus_follows_mouse no\n') + processes.append(subprocess.Popen(["i3", "-c", str(wm_config)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)) + wait_for(lambda: subprocess.run(["i3-msg", "-t", "get_workspaces"], capture_output=True).returncode == 0, "i3 startup") + settings = root / "settings.toml" + settings.write_text('[general]\nenableSpeech = false\nenableSound = false\nkeyboardLayout = 1\n') + binary = os.environ["CTHULHU_BINARY"] + reader = subprocess.Popen([binary, "--config", str(settings), "--debug-file", str(log)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + processes.append(reader) + wait_record("listening for focus events") + windows = [] + for toolkit in ("GTK", "Qt"): + initial = len(records()) + processes.append(subprocess.Popen([sys.executable, __file__, "--fixture", toolkit])) + xid = find("Cthulhu " + toolkit + " Controls") + windows.append(xid) + activate(xid) + wait_for(lambda: any(r.get("message") == "queued accessible presentation" and r.get("role") in ("button", "push button") for r in records()[initial:]), "initial button presentation") + start = len(records()) + key("Tab", "space") + wait_record("queued accessible presentation", start, role="check box") + wait_record("queued accessible presentation", start, type="object:state-changed:checked") + # Exercise normal traversal without choosing controls through AT-SPI. + key(*(["Tab"]*12)) + wait_record("queued accessible presentation", start, role="combo box") + wait_record("queued accessible presentation", start, role="spin button") + wait_record("queued accessible presentation", start, role="radio button") + wait_record("queued accessible presentation", start, role="text") + wait_record("queued accessible presentation", start, role="slider") + wait_record("queued accessible presentation", start, role="table cell") + key(*(["shift+Tab"]*12)) + start = len(records()) + key("alt+a", "Down") + wait_for(lambda: any(r.get("message") == "queued accessible presentation" and r.get("role") in ("menu", "menu item") for r in records()[start:]), "menu presentation") + key("Escape", "Escape") + if toolkit == "GTK": + start = len(records()) + key("F7", "Down") + wait_record("queued accessible presentation", start, role="menu item") + key("Escape") + print("PASS:", toolkit, "forward/reverse controls, checked state, and menus") + for xid in windows + windows[::-1]: + start = len(records()) + activate(xid) + key("Tab") + wait_record("queued accessible presentation", start) + # A distinct window in the same process must get its own owner. + activate(windows[0]) + start = len(records()) + key("F6") + sibling = find("Ownership sibling") + wait_record("queued accessible presentation", start, role="text") + owned = wait_record("activated accessible window", start) + expected_window = owned["window_path"] + for xid in (windows[0], sibling, windows[0]): + start = len(records()) + activate(xid) + key("KP_Enter") + wait_record("queued where am I presentation", start) + # Restart with overlapping same-process windows to force recovery to + # distinguish the active sibling from an earlier geometry match. + for xid in (windows[0], sibling): + run("i3-msg", f"[id={xid}] floating enable, border pixel 0, resize set 600 700, move position 100 100") + def geometry(xid): + values = dict(line.split("=", 1) for line in run("xdotool", "getwindowgeometry", "--shell", xid).splitlines()) + return tuple(values[k] for k in ("X", "Y", "WIDTH", "HEIGHT")) + wait_for(lambda: geometry(windows[0]) == geometry(sibling), "identical sibling geometry") + activate(windows[0]) + activate(sibling) + reader.terminate() + assert reader.wait(timeout=5) == 0, "reader restart shutdown failed" + start = len(records()) + reader = subprocess.Popen([binary, "--config", str(settings), "--debug-file", str(log)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + processes.append(reader) + recovered = wait_record("activated accessible window", start) + assert recovered["window_path"] == expected_window, ("recovered inactive same-geometry sibling", recovered, owned) + key("Tab") + wait_record("queued accessible presentation", start, role="text") + print("PASS: recovery selects active same-process, same-geometry sibling") + run("i3-msg", f"[id={sibling}] kill") + # Actual i3 empty workspace, retaining live background applications. + start = len(records()) + run("i3-msg", "workspace 2") + wait_record("X11 foreground ownership changed", start, x_window=0) + key("KP_Enter") + wait_record("queued where am I presentation", start, role="system") + start = len(records()) + run("i3-msg", "workspace 1") + wait_record("queued accessible presentation", start) + # Activate dialog from a predictable keyboard position in a fresh window. + processes.append(subprocess.Popen([sys.executable, __file__, "--fixture", "GTK"])) + new_window = wait_for(lambda: next((w for w in run("xdotool", "search", "--name", "^Cthulhu GTK Controls$").splitlines() if w not in windows), None), "second same-toolkit window") + activate(new_window) + start = len(records()) + key("space") + dialog = find("Ownership dialog") + wait_record("queued accessible presentation", start, role="text") + start = len(records()) + key("Escape") + wait_record("queued accessible presentation", start) + key("KP_Down", "KP_Right", "KP_Left", "Tab") + start = len(records()) + run("i3-msg", f"[id={new_window}] kill") + wait_record("X11 foreground ownership changed", start) + # Brave publishes multiple top-levels on one application bus. Exercise + # the reported browser workflow with both windows at the same bounds. + import shutil + browser = shutil.which("brave") or shutil.which("brave-browser") or shutil.which("chromium") + assert browser, "Chromium browser required for ownership regression" + browser_args = [browser, "--user-data-dir=" + str(root / "browser-profile"), + "--no-first-run", "--no-default-browser-check", + "--disable-background-networking", "--force-renderer-accessibility", + "--ozone-platform=x11", "--new-window"] + start = len(records()) + processes.append(subprocess.Popen(browser_args + [Path(__file__).with_name("browser.html").resolve().as_uri()], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)) + first_browser = find("Cthulhu Browser Probe.*") + activate(first_browser) + wait_record("activated accessible window", start) + start = len(records()) + subprocess.run(browser_args + [Path(__file__).with_name("browser-next.html").resolve().as_uri()], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + second_browser = find("Cthulhu Second Page.*") + activate(second_browser) + expected_browser = wait_record("activated accessible window", start)["window_path"] + for xid in (first_browser, second_browser): + run("i3-msg", f"[id={xid}] floating enable, border pixel 0, resize set 600 700, move position 100 100") + wait_for(lambda: geometry(first_browser) == geometry(second_browser), "identical browser geometry") + activate(second_browser) + reader.terminate() + assert reader.wait(timeout=5) == 0, "browser recovery restart shutdown failed" + start = len(records()) + reader = subprocess.Popen([binary, "--config", str(settings), "--debug-file", str(log)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + processes.append(reader) + recovered = wait_record("activated accessible window", start) + assert recovered["window_path"] == expected_browser, ("recovered inactive browser", recovered, expected_browser) + start = len(records()) + key("ctrl+l") + wait_record("queued accessible presentation", start, role="entry") + print("PASS: Brave same-geometry window recovery and address focus without Alt+Tab") + key("Insert+q") + assert reader.wait(timeout=5) == 0, "reader shutdown failed" + print("PASS: window switching, empty workspace/recovery, dialog/destruction, review-key churn, shutdown") + except Exception: + import pyatspi + for application in pyatspi.Registry.getDesktop(0): + def describe(node, depth=0): + if depth > 4: return + try: + print("AX", depth, node.getRoleName(), repr(node.name), "pid", node.get_process_id(), "bounds", node.queryComponent().getExtents(pyatspi.DESKTOP_COORDS), file=sys.stderr) + except Exception as error: print("AX error", error, file=sys.stderr) + for child in node: + if child: describe(child, depth+1) + describe(application) + print(log.read_text() if log.exists() else "No runtime log", file=sys.stderr) + raise + finally: + for process in reversed(processes): + if process.poll() is None: + process.terminate() + try: process.wait(timeout=3) + except subprocess.TimeoutExpired: + process.kill() + process.wait() + + +def main(): + if len(sys.argv) == 3 and sys.argv[1] == "--fixture": + fixture(sys.argv[2]); return + if len(sys.argv) == 3 and sys.argv[1] == "--inside": + inside(sys.argv[2]); return + with tempfile.TemporaryDirectory(prefix="cthulhu-ownership-") as directory: + read_fd, write_fd = os.pipe() + server = subprocess.Popen(["Xvfb", "-displayfd", str(write_fd), "-screen", "0", "1280x1024x24", "-nolisten", "tcp"], pass_fds=(write_fd,), stderr=subprocess.DEVNULL) + os.close(write_fd) + try: + with os.fdopen(read_fd) as pipe: display = pipe.readline().strip() + assert display, "Xvfb startup failed" + environment = dict(os.environ, DISPLAY=":"+display, XDG_SESSION_TYPE="x11", QT_ACCESSIBILITY="1", QT_LINUX_ACCESSIBILITY_ALWAYS_ON="1") + for name in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY", "I3SOCK"): + environment.pop(name, None) + run_private_session(["dbus-run-session", "--", sys.executable, __file__, "--inside", directory], env=environment, check=True, timeout=100) + finally: + server.terminate(); server.wait(timeout=3) + + +if __name__ == "__main__": main() diff --git a/tests/native_preferences.py b/tests/native_preferences.py new file mode 100644 index 0000000..a7e850c --- /dev/null +++ b/tests/native_preferences.py @@ -0,0 +1,1564 @@ +#!/usr/bin/env python3 +"""Private Xvfb/AT-SPI proof for the Go GTK preferences helper.""" +import json +import os +from pathlib import Path +import select +import subprocess +import sys +import tempfile +import time + +sys.dont_write_bytecode = True +from native_x11 import wait_for +from native_test_session import run_private_session + + +class ResponseReader: + """Read complete JSON lines with one deadline, preserving read-ahead bytes.""" + + def __init__(self, stream): + self.stream = stream + self.pendingData = bytearray() + + def request(self, timeout=5): + deadline = time.monotonic() + timeout + while b"\n" not in self.pendingData: + remaining = deadline - time.monotonic() + if remaining <= 0 or not select.select([self.stream], [], [], remaining)[0]: + raise TimeoutError("no complete preferences request within response timeout") + # Never mix buffered reads with select: TextIO can retain another + # complete reply even when the underlying pipe is empty. + chunk = os.read(self.stream.fileno(), 65536) + if not chunk: + raise EOFError("preferences helper closed stdout before a complete request") + self.pendingData.extend(chunk) + end = self.pendingData.index(b"\n") + 1 + line = self.pendingData[:end] + del self.pendingData[:end] + return json.loads(line) + + def read_remaining(self): + # Used only after helper exit; include any bytes read ahead by request. + remaining = bytes(self.pendingData) + self.stream.buffer.read() + self.pendingData.clear() + return remaining.decode("utf-8") + + +def inside(): + if os.environ.get("CTHULHU_PREFS_NO_CONFIG_ONLY") == "1": + from native_echo_preview import check_runtime + check_runtime(noConfigOnly=True) + return + if os.environ.get("CTHULHU_PREFS_INTERRUPTION_RUNTIME_ONLY") == "1": + from native_echo_preview import check_runtime + check_runtime(interruptionOnly=True) + return + if os.environ.get("CTHULHU_PREFS_FLAT_REVIEW_ONLY") == "1": + from native_echo_preview import check_runtime + check_runtime(flatReviewOnly=True) + return + if os.environ.get("CTHULHU_PREFS_RADIO_RUNTIME_ONLY") == "1": + from native_echo_preview import check_runtime + check_runtime(radioOnly=True) + return + if os.environ.get("CTHULHU_PREFS_ECHO_RUNTIME_ONLY") == "1": + from native_echo_preview import check_runtime + check_runtime() + return + if os.environ.get("CTHULHU_PREFS_ADAPTER_ONLY") == "1": + environment = dict(os.environ, CTHULHU_NATIVE_PREFERENCES="1") + environment.setdefault("GOCACHE", "/tmp/cthulhu-cache") + subprocess.run(["go", "test", "./internal/atspi", "-run", + "^TestNativePreferencesDropdownEscape$", "-count=1", "-v", "-timeout=30s"], + cwd=Path(__file__).resolve().parents[1], env=environment, + check=True, timeout=35) + return + import pyatspi + window_manager = None + reader_process = None + private_directory = None + if os.environ.get("CTHULHU_PREFS_HARDWARE_ONLY") == "1" or os.environ.get("CTHULHU_PREFS_APPLY_ONLY") == "1": + private_directory = tempfile.TemporaryDirectory(prefix="cthulhu-prefs-hardware-") + wm_config = Path(private_directory.name) / "i3.config" + wm_socket = Path(private_directory.name) / "i3.sock" + wm_config.write_text(f"font pango:monospace 10\nipc-socket {wm_socket}\n") + window_manager = subprocess.Popen(["i3", "-c", str(wm_config)], + env=dict(os.environ, I3SOCK=str(wm_socket)), + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + wait_for(lambda: "0x" in subprocess.check_output(["xprop", "-root", "_NET_SUPPORTING_WM_CHECK"], text=True), "private i3 failed to start") + application = os.environ.get("CTHULHU_PREFS_APPLICATION", "") + window_name = "Cthulhu Preferences for " + application if application else "Cthulhu Preferences" + binary = os.environ.get("CTHULHU_BINARY", str(Path(__file__).resolve().parents[1] / "cthulhu")) + process = subprocess.Popen([binary, "--preferences-ui"], stdin=subprocess.PIPE, + stdout=subprocess.PIPE, text=True) + responses = ResponseReader(process.stdout) + initial = {"Values": {"Rate": 50, "Pitch": 5, "Volume": 5, + "SpeechHistoryLimit": 50, + "Reading": {"AutomaticallyReadTitleChanges": True}, + "KeyboardLayout": 1, "CthulhuModifierKeys": ["Insert", "KP_Insert"], + "Punctuation": 1, "RaisePitchForCapitals": True, + "BeepForCapitals": False, "SayCapForCapitals": False, + "TimeFormat": "24-hour", "DateFormat": "ymd", + "EnableSound": True, "SoundVolume": 0.5, + "SpeechVerbosityLevel": 1, + "SayAllStyle": "line", + "SoundSink": "auto", "SoundTheme": "default", + "PlaySoundForRole": True, "PlaySoundForState": True, + "PlaySoundForPositionInSet": True, + "SpatializeObjectSounds": False, + "ProgressBar": {"OutputMode": "beep", "ReportBackground": False, + "BeepPercentageInterval": 1, "SpeechPercentageInterval": 10}, + "RoleSoundPresentation": "sound_and_speech", + "Braille": {"Verbosity": 1, "SelectionIndicator": 192, + "LinkIndicator": 192, "FlashMessages": True, + "FlashTime": 5000, "FlashDetailed": True}, + "Pronunciations": [{"Word": "SQL", "Replacement": "sequel"}], + "TextAttributes": {"Indicator": 0, "Choices": [ + {"Key": key, "Speak": True, "Braille": False} + for key in ("size", "family-name", "weight", "indent", "underline", + "strikethrough", "justification", "style", "paragraph-style", + "text-spelling", "fg-color", "bg-color")]}, + "EnableKeyEcho": True, "EnableAlphabeticKeys": True, + "EnableEchoByWord": True, "UseCustomEchoForKey": True}, + "Catalog": {"": [{"Name": "Test voice", "Language": "en", "Variant": "none"}], + "test-module": [{"Name": "English test voice", "Language": "en", "Variant": "none"}, + {"Name": "Spanish test voice", "Language": "es", "Variant": "none"}]}, + "CanSave": True, "Accepted": True, "Message": "Preferences test ready."} + echoFocusMode = os.environ.get("CTHULHU_PREFS_ECHO_PREVIEW_ONLY") == "1" + echo_mode = os.environ.get("CTHULHU_PREFS_KEY_ECHO_ONLY") or ("custom" if echoFocusMode else None) + if echo_mode: + initial["Catalog"]["echo-module"] = [ + {"Name": "Echo test voice", "Language": "en", "Variant": "none"}] + initial["Values"].update( + SpeechOutputModule="test-module", EchoSpeechServer="echo-module", + UseCustomEchoVoice=echo_mode == "custom", + UseCustomEchoSpeechServer=echo_mode == "custom", + EnableEchoByCharacter=True, EnableEchoBySentence=True, + UseCustomEchoForCharacter=True) + if os.environ.get("CTHULHU_PREFS_SPEECH_ONLY") == "1": + initial["Catalog"]["espeak-ng"] = list(initial["Catalog"]["test-module"]) + if os.environ.get("CTHULHU_PREFS_NUMBERS_ONLY") == "1": + initial["Values"].update(UseCustomEchoVoice=True, + EchoVoice={"Rate": 50, "AveragePitch": 5, "Gain": 5}) + if os.environ.get("CTHULHU_PREFS_LARGE_CATALOG") == "1": + initial["Catalog"]["espeak-ng"].extend( + {"Name": f"Test voice {index}", "Language": "en" if index < 100 else "de", "Variant": "none"} + for index in range(12000)) + initial["Catalog"]["espeak-ng"][-1]["Language"] = "fr" + # Speech Dispatcher also lists its default eSpeak catalog under "". + initial["Catalog"][""] = list(initial["Catalog"]["espeak-ng"]) + initial["Values"].update(UseCustomEchoVoice=True, + EchoVoice={"Family": {"Name": "Spanish test voice", "Lang": "es"}}) + if os.environ.get("CTHULHU_PREFS_TENTACLES_ONLY") == "1": + initial["Tentacles"] = {"Entries": [], "Suppressed": False} + if os.environ.get("CTHULHU_PREFS_TENTACLE_SETTINGS_ONLY") == "1": + initial["Tentacles"] = {"Entries": [{"Entry": {"ID": "probe", "Name": "Settings probe", "Enabled": True}, + "State": "active", "Shortcuts": ["Desktop: Cthulhu+Ctrl+Shift+W (Probe menu)"]}], "Suppressed": False} + if os.environ.get("CTHULHU_PREFS_EXTENSIONS_ONLY") == "1": + from native_tentacle_extensions import probe_pages + initial["ExtensionPages"] = probe_pages() + if application: + initial["Application"] = application + def send(value): + process.stdin.write(json.dumps(value) + "\n") + process.stdin.flush() + def send_initial(value): + if os.environ.get("CTHULHU_PREFS_LARGE_CATALOG") != "1": + send(value) + return + # Exercise the helper's bounded catalog protocol with a full catalog + # larger than one scanner line, including a duplicate default module. + assert len(json.dumps(value)) > 1024 * 1024 + metadata = dict(value, Catalog=None, CatalogPending=True) + send(metadata) + for module, voices in value["Catalog"].items(): + for offset in range(0, len(voices), 128): + send({"Catalog": {module: voices[offset:offset + 128]}, "CatalogPending": True}) + send({"CatalogPending": False}) + def walk(node): + yield node + for child in node: + if child is not None: + yield from walk(child) + def find_window(): + for app in pyatspi.Registry.getDesktop(0): + for node in app: + if node and node.name == window_name: + return node + return None + nodes = [] + controls = {} + def named(name): + return controls[name] + def key(*keys): + subprocess.run(["xdotool", "key", "--clearmodifiers", *keys], check=True) + def focus(node): + assert node.queryComponent().grabFocus(), ("cannot focus", node.name) + wait_for(lambda: any(child.getState().contains(pyatspi.STATE_FOCUSED) for child in walk(node)), "focus missing") + def request(): + while True: + value = responses.request() + if value.get("EchoPreviewFocus") and not echoFocusMode: + send({"Preview": True, "Accepted": True}) + continue + return value + try: + send_initial(initial) + window = wait_for(find_window, "preferences accessible window missing") + nodes = list(walk(window)) + for node in nodes: + if node.name: + controls.setdefault(node.name, node) + xid = subprocess.check_output(["xdotool", "search", "--onlyvisible", "--name", "^" + window_name + "$"], text=True).splitlines()[0] + subprocess.run(["xdotool", "windowfocus", xid], check=True) + assert not any(node.name == "Profiles" for node in nodes), "removed profile controls remain in preferences" + if os.environ.get("CTHULHU_PREFS_INTERRUPTION_ONLY") == "1": + from native_x11 import press_physical_key + tabs = next(node for node in nodes if node.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + assert tabs.querySelection().selectChild(2), "cannot select Speech tab" + allKeys = named("All keys interrupt") + commonKeys = named("Control, Enter, Space, and Escape") + customKeys = named("Define interruption keys") + recordButton = named("Record interruption keys") + summary = named("Defined interruption keys") + history = named("Speech history entries") + statusNode = named(initial["Message"]) + applyCount = 0 + + def is_focused(node): + return any(child.getState().contains(pyatspi.STATE_FOCUSED) for child in walk(node)) + + def apply_interruption(mode, expectedKeys): + nonlocal applyCount + focus(named("Apply")); key("space") + applied = request() + assert applied["Save"] and not applied["Close"], applied + values = applied["Values"] + assert values["SpeechInterruption"] == {"Mode": mode, "Keys": expectedKeys}, values["SpeechInterruption"] + applyCount += 1 + message = f"Interruption settings saved {applyCount}." + send(dict(initial, Values=values, Message=message)) + wait_for(lambda: statusNode.name == message and named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), + "Apply response did not finish reloading the draft") + return values + + def recorder(): + for app in pyatspi.Registry.getDesktop(0): + for child in app: + if child and child.name == "Record interruption keys" and child.getRole() == pyatspi.ROLE_DIALOG: + return child + return None + + def begin_recording(): + focus(recordButton); key("space") + dialog = wait_for(recorder, "key recorder did not open") + dialogID = subprocess.check_output(["xdotool", "search", "--onlyvisible", "--name", "^Record interruption keys$"], text=True).splitlines()[0] + subprocess.run(["xdotool", "windowfocus", dialogID], check=True) + assert "Control+Enter" in dialog.description and "Control+Escape" in dialog.description + return dialog + + assert allKeys.getState().contains(pyatspi.STATE_CHECKED) + assert not recordButton.getState().contains(pyatspi.STATE_SENSITIVE) + apply_interruption("all", None) + focus(named("Verbose")); key("Tab") + wait_for(lambda: is_focused(allKeys), "Tab did not reach interruption group; focused: " + + repr([(node.name, node.getRoleName()) for node in walk(window) if node.getState().contains(pyatspi.STATE_FOCUSED)])) + key("Down") + wait_for(lambda: commonKeys.getState().contains(pyatspi.STATE_CHECKED), "arrow did not select common keys") + apply_interruption("common", None) + focus(commonKeys); key("Down") + wait_for(lambda: customKeys.getState().contains(pyatspi.STATE_CHECKED), "arrow did not select custom keys") + key("Tab") + wait_for(lambda: is_focused(recordButton), "Tab did not reach recording button") + key("Tab") + wait_for(lambda: is_focused(summary), "Tab did not reach defined keys") + key("Home", "Right") + wait_for(lambda: summary.queryText().caretOffset == 1, "read-only summary did not move its caret") + key("Tab") + wait_for(lambda: is_focused(history), "defined keys trapped Tab") + key("shift+Tab", "shift+Tab", "shift+Tab") + wait_for(lambda: is_focused(customKeys), "Shift+Tab did not return through new controls") + dialog = begin_recording() + key("Tab", "Return", "space", "Escape", "Tab") + press_physical_key(0xFFE1) # Left Shift, without synthesized modifiers. + press_physical_key(0xFFE4) # Right Control. + press_physical_key(0xFF55) # Page Up: GTK calls this Page_Up, X11 calls it Prior. + press_physical_key(0x1008FF12) # Audio mute: GTK omits the XF86 prefix. + assert recorder() is not None, "a recordable key closed the recorder" + key("ctrl+Return") + wait_for(lambda: recorder() is None, "Control+Enter did not finish") + wait_for(lambda: is_focused(recordButton), "recording did not return focus to button") + expectedKeys = ["Tab", "Return", "space", "Escape", "Shift_L", "Control_R", "Prior", "XF86AudioMute"] + saved = apply_interruption("custom", expectedKeys) + assert customKeys.getState().contains(pyatspi.STATE_CHECKED), "Apply lost custom mode" + assert "Tab" in summary.queryText().getText(0, -1), "Apply lost displayed keys" + begin_recording(); key("F8", "ctrl+Escape") + wait_for(lambda: recorder() is None, "Control+Escape did not cancel") + wait_for(lambda: is_focused(recordButton), "cancellation did not return focus") + apply_interruption("custom", expectedKeys) + begin_recording(); key("ctrl+Return") + assert recorder() is not None, "empty recording was accepted" + key("F8", "ctrl+Return") + wait_for(lambda: recorder() is None, "replacement recording did not finish") + apply_interruption("custom", ["F8"]) + # Non-custom modes preserve the defined list for later reuse. + focus(customKeys); key("Up", "Up") + wait_for(lambda: allKeys.getState().contains(pyatspi.STATE_CHECKED), "arrows did not return to All keys interrupt") + apply_interruption("all", ["F8"]) + focus(named("Cancel")); key("space") + assert process.wait(timeout=5) == 0 + print("PASS: interruption modes, keyboard traversal, Tab/Enter/Space/Escape and modifier recording, finish/cancel, duplicates, replacement, Apply and draft reload") + return + if echoFocusMode: + tabs = next(n for n in nodes if n.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + assert tabs.querySelection().selectChild(4), "cannot select Key Echo tab" + def check_preview(control, isFocus): + value = request() + assert value["Preview"] and value.get("EchoPreview") == control, value + assert bool(value.get("EchoPreviewFocus")) == isFocus, value + send({"Preview": True, "Accepted": True}) + return value["Values"] + focus(named("Use custom echo voice")) + key("Tab") + check_preview("synthesizer", True) + key("Down") + value = check_preview("synthesizer", False) + assert value["EchoSpeechServer"] == "test-module", value + key("Up") + value = check_preview("synthesizer", False) + assert value["EchoSpeechServer"] == "echo-module", value + key("Tab") + check_preview("person", True) + key("Down") + value = check_preview("person", False) + assert value["EchoVoice"]["Family"]["Name"] == "Echo test voice", value + for control in ("rate", "pitch", "volume"): + key("Tab") + check_preview(control, True) + key("Right") + check_preview(control, False) + for control in ("pitch", "rate", "person", "synthesizer"): + key("shift+Tab") + check_preview(control, True) + # Popup Escape restores the same combo without trapping focus. + key("alt+Down", "Escape", "Tab") + check_preview("person", True) + focus(named("Cancel")); key("space") + assert process.wait(timeout=5) == 0 + print("PASS: all five echo controls preview their current values on Tab/Shift+Tab and changed values on arrows; popup Escape and Cancel") + return + if echo_mode: + assert "Use custom speech synthesizer for key echo" not in controls + assert "Use custom voice for key echo" not in controls + assert "Use the custom voice for:" in controls + tabs = next(n for n in nodes if n.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + assert tabs.querySelection().selectChild(4), "cannot select Key Echo tab" + custom = named("Use custom echo voice") + synth = named("Key echo speech synthesizer") + family = named("Key echo person") + rate = named("Key echo rate") + expected_module = "echo-module" if echo_mode == "custom" else "test-module" + assert synth.querySelection().getSelectedChild(0).name == expected_module + if echo_mode != "custom": + # An unused saved echo module must not override the main one. + assert not synth.getState().contains(pyatspi.STATE_SENSITIVE) + assert not family.getState().contains(pyatspi.STATE_SENSITIVE) + focus(custom); key("space") + wait_for(lambda: synth.getState().contains(pyatspi.STATE_SENSITIVE), + "custom echo did not enable the synthesizer directly") + def focused(node): + return any(child.getState().contains(pyatspi.STATE_FOCUSED) for child in walk(node)) + # GTK's internal combo button does not consistently expose its + # focused state. Exercise the popup, value and following Tab stop. + focus(custom); key("Tab", "alt+Down", "Home", "Down") + if echo_mode != "custom": + key("Down") + key("Return") + wait_for(lambda: synth.description == expected_module, "Tab did not reach echo synthesizer") + key("Tab", "Tab") + wait_for(lambda: focused(rate), "voice selector trapped Tab") + key("shift+Tab", "shift+Tab") + key("shift+Tab") + wait_for(lambda: focused(custom), "synthesizer trapped Shift+Tab") + assert named("Key names").getState().contains(pyatspi.STATE_CHECKED) + assert named("Typed characters").getState().contains(pyatspi.STATE_CHECKED) + for name in ("Key names", "Typed characters", "Words", "Sentences"): + assert named(name).getRole() == pyatspi.ROLE_CHECK_BOX + assert named(name).getState().contains(pyatspi.STATE_SENSITIVE) + focus(named("Words")); key("space") + def apply_echo(): + focus(named("Apply")); key("space") + while True: + applied = request() + if applied["Preview"]: + send({"Preview": True, "Accepted": True}) + continue + assert applied["Save"] and not applied["Close"], applied + values = applied["Values"] + send(dict(initial, Values=values, Message="Echo settings saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), + "echo Apply stayed busy") + return values + saved = apply_echo() + assert saved["SpeechOutputModule"] == "test-module", saved + assert saved["UseCustomEchoVoice"] and saved["UseCustomEchoSpeechServer"], saved + assert saved["EchoSpeechServer"] == expected_module, saved + assert saved["UseCustomEchoForKey"] and saved["UseCustomEchoForCharacter"], saved + assert saved["UseCustomEchoForWord"] and not saved["UseCustomEchoForSentence"], saved + # Select Default first to guarantee a change in either startup + # mode. Only the selected combo value gets an echo preview. + def accept_echo_preview(control, module): + preview = request() + assert preview["Preview"] and preview.get("EchoPreview") == control, preview + assert preview["Values"]["EchoSpeechServer"] == module, preview + send({"Preview": True, "Accepted": True}) + return preview["Values"] + focus(custom); key("Tab", "alt+Down", "Home", "Return") + preview = accept_echo_preview("synthesizer", "") + assert preview["EchoVoice"]["Family"] is None, preview + # Change the synthesizer using its keyboard popup, then select a + # person and verify each sends its newly selected draft voice. + focus(custom); key("Tab", "alt+Down", "Home", "Down", "Return") + accept_echo_preview("synthesizer", "echo-module") + wait_for(lambda: synth.description == "echo-module", "echo synthesizer did not change") + wait_for(lambda: any(child.name == "Echo test voice (en)" for child in walk(family)), + "echo voices did not follow the selected synthesizer") + key("Tab", "alt+Down", "Home", "Down", "Return") + preview = accept_echo_preview("person", "echo-module") + assert preview["EchoVoice"]["Family"]["Name"] == "Echo test voice", preview + saved = apply_echo() + assert saved["EchoSpeechServer"] == "echo-module", saved + assert saved["EchoVoice"]["Family"]["Name"] == "Echo test voice", saved + assert synth.querySelection().getSelectedChild(0).name == "echo-module" + assert family.querySelection().getSelectedChild(0).name == "Echo test voice (en)" + focus(custom); key("space") + wait_for(lambda: not synth.getState().contains(pyatspi.STATE_SENSITIVE), + "custom echo off left the synthesizer enabled") + saved = apply_echo() + assert not saved["UseCustomEchoVoice"] and saved["EchoSpeechServer"] == "echo-module", saved + focus(custom); key("space") + saved = apply_echo() + assert saved["UseCustomEchoVoice"] and saved["EchoSpeechServer"] == "echo-module", saved + assert saved["EchoVoice"]["Family"]["Name"] == "Echo test voice", saved + focus(named("Cancel")); key("space") + assert process.wait(timeout=5) == 0 + print("PASS: echo synthesizer initialization, keyboard navigation, synthesizer/person previews, routing choices, Apply/reload, disable/re-enable") + return + if os.environ.get("CTHULHU_PREFS_EXTENSIONS_ONLY") == "1": + from native_tentacle_extensions import check_page + check_page(pyatspi, process, window, nodes, walk, focus, key, request, send, initial) + return + if os.environ.get("CTHULHU_PREFS_TENTACLE_SETTINGS_ONLY") == "1": + from native_tentacle_settings import check_page + check_page(pyatspi, window, nodes, named, walk, focus, key, request, send, initial) + return + if os.environ.get("CTHULHU_PREFS_TENTACLES_ONLY") == "1": + from native_tentacles import check_page + check_page(pyatspi, process, window, nodes, named, walk, focus, key, + request, send, initial, application) + return + if os.environ.get("CTHULHU_PREFS_OCR_ONLY") == "1": + tabs = next(n for n in nodes if n.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + assert tabs.querySelection().selectChild(8), "cannot select OCR tab" + wait_for(lambda: named("OCR").getState().contains(pyatspi.STATE_SELECTED), "OCR page missing") + language = named("OCR recognition languages") + layout = named("OCR text layout") + scale = named("OCR scale factor") + assert layout.getRole() == pyatspi.ROLE_COMBO_BOX + focus(language); key("Tab", "Tab") + wait_for(lambda: scale.getState().contains(pyatspi.STATE_FOCUSED), + "OCR text layout trapped Tab") + key("shift+Tab", "shift+Tab") + wait_for(lambda: language.getState().contains(pyatspi.STATE_FOCUSED), + "OCR text layout trapped Shift+Tab") + key("Tab", "alt+Down", "Down", "Return") + wait_for(lambda: layout.description == "Single text block", "OCR layout choice did not change") + key("Tab") + wait_for(lambda: scale.getState().contains(pyatspi.STATE_FOCUSED), + "OCR layout popup trapped Tab after selection") + automatic = named("Automatically read the first OCR result") + assert automatic.getRole() == pyatspi.ROLE_CHECK_BOX + assert not automatic.getState().contains(pyatspi.STATE_CHECKED), "automatic reading should default off" + focus(automatic); key("space") + key("Tab") + wait_for(lambda: named("Periodically refresh screen OCR").getState().contains(pyatspi.STATE_FOCUSED), + "Tab did not reach periodic refresh") + key("shift+Tab") + wait_for(lambda: automatic.getState().contains(pyatspi.STATE_FOCUSED), "Shift+Tab did not return to automatic reading") + focus(named("Apply")); key("space") + applied = request() + assert applied["Values"]["OCR"]["AutoReadAll"], applied + assert applied["Values"]["OCR"]["Layout"] == 6, applied + send(dict(initial, Values=applied["Values"])) + wait_for(lambda: automatic.getState().contains(pyatspi.STATE_CHECKED), "applied value was lost") + assert layout.description == "Single text block", "applied OCR layout was lost" + send(initial) + wait_for(lambda: not automatic.getState().contains(pyatspi.STATE_CHECKED), "rollback did not restore automatic reading") + focus(automatic); key("space") + key("Escape") + assert process.wait(timeout=2) == 0, "Escape did not close OCR preferences" + assert responses.read_remaining() == "", "cancel submitted changed OCR settings" + print("PASS: OCR layout Tab/Shift+Tab, popup selection, automatic reading checkbox, Apply, rollback, Cancel") + return + if os.environ.get("CTHULHU_PREFS_TEXT_ONLY") == "1": + tabs = next(n for n in nodes if n.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + assert tabs.querySelection().selectChild(6), "cannot select Pronunciation tab" + wait_for(lambda: named("Pronunciation").getState().contains(pyatspi.STATE_SELECTED), "Pronunciation page missing") + dictionary = named("Pronunciation dictionary").queryTable() + assert dictionary.nRows == 1 and dictionary.getAccessibleAt(0, 0).name == "SQL", dictionary.nRows + focus(named("New entry")); key("space") + wait_for(lambda: dictionary.nRows == 2, "New entry did not add a row") + subprocess.run(["xdotool", "type", "--clearmodifiers", "NVDA"], check=True) + key("Return") + focus(dictionary.getAccessibleAt(1, 1)); key("F2") + subprocess.run(["xdotool", "type", "--clearmodifiers", "en vee dee ay"], check=True) + key("Return") + wait_for(lambda: dictionary.getAccessibleAt(1, 0).name == "NVDA" and + dictionary.getAccessibleAt(1, 1).name == "en vee dee ay", "inline pronunciation editing failed") + focus(named("Delete")); key("space") + wait_for(lambda: dictionary.nRows == 1, "Delete did not remove the selected row") + assert tabs.querySelection().selectChild(7), "cannot select Text Attributes tab" + wait_for(lambda: named("Text Attributes").getState().contains(pyatspi.STATE_SELECTED), "Text Attributes page missing") + table = named("Text attributes").queryTable() + assert table.nRows == 12 and table.nColumns == 3, (table.nRows, table.nColumns) + assert table.getAccessibleAt(0, 0).name == "Font size" + focus(table.getAccessibleAt(0, 1)); key("space") + wait_for(lambda: not table.getAccessibleAt(0, 1).getState().contains(pyatspi.STATE_CHECKED), "Speak did not toggle") + focus(table.getAccessibleAt(0, 2)); key("space") + wait_for(lambda: table.getAccessibleAt(0, 2).getState().contains(pyatspi.STATE_CHECKED), "Braille did not toggle") + focus(named("Move to bottom")); key("space") + wait_for(lambda: table.getAccessibleAt(11, 0).name == "Font size", "Move to bottom did not reorder") + focus(named("Braille indicator: Dot 7")); key("space") + focus(named("Apply")); key("space") + applied = request() + assert applied["Values"]["Pronunciations"] == initial["Values"]["Pronunciations"], applied + attr = applied["Values"]["TextAttributes"] + assert attr["Indicator"] == 64 and attr["Choices"][-1]["Key"] == "size" and not attr["Choices"][-1]["Speak"] and attr["Choices"][-1]["Braille"], attr + send(dict(initial, Values=applied["Values"], Message="Text preferences saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Apply stayed busy") + focus(named("Reset")); key("space") + wait_for(lambda: table.getAccessibleAt(0, 0).name == "Font size", "Reset did not restore order") + focus(named("Cancel")); key("space") + assert process.wait(timeout=2) == 0 + print("PASS: pronunciation and text attribute tables, add/delete, selection, order, indicator, Apply/reload, reset") + return + if os.environ.get("CTHULHU_PREFS_NUMBERS_ONLY") == "1": + focus(named("Desktop")) + key("ctrl+Page_Down", "ctrl+Page_Down") + wait_for(lambda: named("Speech").getState().contains(pyatspi.STATE_SELECTED), "Speech page missing") + values = initial["Values"] + def accept_preview(echoPreview=""): + preview = request() + assert preview["Preview"], preview + assert preview.get("EchoPreview", "") == echoPreview, preview + send({"Preview": True, "Accepted": True}) + return preview["Values"] + for name, field in (("Rate", "Rate"), ("Pitch", "Pitch"), ("Volume", "Volume")): + slider = next(n for n in nodes if n.getRole() == pyatspi.ROLE_SLIDER and n.name.lower().rstrip(":") == name.lower()) + focus(slider) + assert abs(slider.queryValue().minimumIncrement - 0.1) < 1e-8, (name, "accessible increment") + startValue = slider.queryValue().currentValue + for arrow, delta in (("Right", 0.1), ("Up", 1), ("Left", -0.1), ("Down", -1), ("Left", -0.1)): + expected = startValue + delta + key(arrow) + values = accept_preview() + assert abs(slider.queryValue().currentValue - expected) < 1e-8, (name, arrow, expected) + assert abs(values[field] - expected) < 1e-8, (name, arrow, values) + startValue = expected + for bound, arrows in ((0, ("Left", "Down")), + (slider.queryValue().maximumValue, ("Right", "Up"))): + slider.queryValue().currentValue = bound + accept_preview() + key(*arrows) + assert slider.queryValue().currentValue == bound, (name, "boundary", bound) + slider.queryValue().currentValue = startValue + values = accept_preview() + key("Tab") + wait_for(lambda: not slider.getState().contains(pyatspi.STATE_FOCUSED), "Tab trapped on slider") + key("shift+Tab") + wait_for(lambda: slider.getState().contains(pyatspi.STATE_FOCUSED), "Shift+Tab did not return to slider") + focus(named("Raise pitch for capital letters")) + for page in ("Braille", "Key Echo"): + key("ctrl+Page_Down") + wait_for(lambda: named(page).getState().contains(pyatspi.STATE_SELECTED), page + " page missing") + for name, field in (("Key echo rate", "Rate"), ("Key echo pitch", "AveragePitch"), ("Key echo volume", "Gain")): + slider = named(name) + focus(slider) + echoPreview = {"Rate": "rate", "AveragePitch": "pitch", "Gain": "volume"}[field] + assert abs(slider.queryValue().minimumIncrement - 0.1) < 1e-8, (name, "accessible increment") + for arrow, expected in (("Right", 5.1 if field != "Rate" else 50.1), + ("Up", 6.1 if field != "Rate" else 51.1), + ("Left", 6 if field != "Rate" else 51), + ("Down", 5 if field != "Rate" else 50), + ("Left", 4.9 if field != "Rate" else 49.9)): + key(arrow) + values = accept_preview(echoPreview) + wait_for(lambda: abs(slider.queryValue().currentValue - expected) < 1e-8, + f"{name}: {arrow} did not produce {expected}") + assert abs(values["EchoVoice"][field] - expected) < 1e-8, values + finalValue = expected + for bound, arrows in ((0, ("Left", "Down")), + (slider.queryValue().maximumValue, ("Right", "Up"))): + slider.queryValue().currentValue = bound + accept_preview(echoPreview) + key(*arrows) + assert slider.queryValue().currentValue == bound, (name, "boundary", bound) + slider.queryValue().currentValue = finalValue + accept_preview(echoPreview) + focus(named("Apply")); key("space") + applied = request() + assert applied["Save"], applied + for field, expected in (("Rate", 49.9), ("Pitch", 4.9), ("Volume", 4.9)): + assert abs(applied["Values"][field] - expected) < 1e-8, applied + for field, expected in (("Rate", 49.9), ("AveragePitch", 4.9), ("Gain", 4.9)): + assert abs(applied["Values"]["EchoVoice"][field] - expected) < 1e-8, applied + send(dict(initial, Values=applied["Values"], Message="Speech settings saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Apply busy") + for name, expected in (("Key echo rate", 49.9), ("Key echo pitch", 4.9), ("Key echo volume", 4.9)): + assert abs(named(name).queryValue().currentValue - expected) < 1e-8, name + focus(named("Cancel")); key("space") + assert process.wait(timeout=2) == 0 + print("PASS: voice and echo sliders, whole/tenth arrow steps, previews, Tab/Shift+Tab, Apply/reload, Cancel") + return + if os.environ.get("CTHULHU_PREFS_APPLY_ONLY") == "1": + reading_tree = next(node for node in nodes if node.name == "Reading settings" + and node.getRole() == pyatspi.ROLE_TABLE) + reading_table = reading_tree.queryTable() + reader_config = Path(private_directory.name) / "reader.toml" + reader_log = Path(private_directory.name) / "reader.log" + reader_config.write_text('schema-version = 2\nactive-profile = "default"\n' + '[profiles.default.speech]\nenabled = false\n' + '[profiles.default.braille]\nenabled = false\n' + '[profiles.default.sound]\nenabled = false\n') + reader_process = subprocess.Popen([binary, "--config", str(reader_config), + "--debug-file", str(reader_log)], + env=dict(os.environ, NVDA2SPEECHD_HOST="http://127.0.0.1:0"), + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + def reader_rows(): + if not reader_log.exists(): + return [] + rows = [] + for line in reader_log.read_text().splitlines(): + try: + rows.append(json.loads(line)) + except ValueError: + pass # The last log write may still be in flight. + return rows + def reader_focused(node, offset): + return any(row.get("message") == "received accessibility event" and + row.get("type") == "object:state-changed:focused" and + row.get("event_detail1") == 1 and row.get("source_path") == node.path + for row in reader_rows()[offset:]) + wait_for(lambda: any(row.get("message") == "listening for focus events" for row in reader_rows()), + "test reader did not start") + focus(named("Help")) + wait_for(lambda: reader_focused(named("Help"), 0), "reader did not observe helper focus") + status = named(initial["Message"]) + for attempt in range(2): + log_offset = len(reader_rows()) + focus(named("Apply")); key("space") + applied = request() + assert applied["Save"] and not applied["Close"], applied + wait_for(lambda: not named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), + "Apply did not enter busy state") + assert not status.getState().contains(pyatspi.STATE_FOCUSED), "Apply moved focus to status" + assert "Applying settings" not in status.name, status.name + started = time.monotonic() + accepted_values = applied["Values"] + if attempt == 1: + accepted_values["Reading"]["SpeakBlankLines"] = True + send(dict(initial, Values=accepted_values, Message="Settings applied and saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), + "Apply stayed busy after success") + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_FOCUSED), + "successful Apply did not restore its button focus") + assert not status.getState().contains(pyatspi.STATE_FOCUSED), "success focused status" + # GTK alone can respond while the reader is still processing + # hundreds of redundant cell events. Require reader-side focus. + focus(named("Cancel")) + wait_for(lambda: reader_focused(named("Cancel"), log_offset), + "reader did not process post-Apply focus", timeout=30) + elapsed = time.monotonic() - started + cell_events = sum(row.get("type") == "object:property-change:accessible-name" and + row.get("role") == "table cell" for row in reader_rows()[log_offset:]) + print(f"Apply {attempt + 1}: {cell_events} table-cell name events; reader focus in {elapsed:.3f}s", flush=True) + assert cell_events <= 32, ("redundant reading-table name events", cell_events) + assert elapsed < 3, ("post-Apply reader focus was delayed", elapsed) + if attempt == 1: + blank_row = next(row for row in range(reading_table.nRows) + if reading_table.getAccessibleAt(row, 1).name == "Speak blank lines") + blank_cell = reading_table.getAccessibleAt(blank_row, 0) + assert blank_cell.name == "checked" and blank_cell.getState().contains(pyatspi.STATE_CHECKED) + focus(named("Apply")); key("space") + rejected = request() + assert rejected["Values"]["Reading"]["SpeakBlankLines"], "backend change did not reach next draft" + send(dict(initial, Accepted=False, Message="Settings were not applied: test rejection.")) + wait_for(lambda: status.getState().contains(pyatspi.STATE_FOCUSED), "rejection did not focus error") + focus(named("OK")); key("space") + saved = request() + assert saved["Save"] and saved["Close"], saved + send(dict(initial, Values=saved["Values"], Close=True, Message="Settings applied and saved.")) + assert process.wait(timeout=5) == 0, "successful OK did not close" + print("PASS: repeated Apply restores button focus, passive success status, focused rejection, OK closes") + return + if application: + focus(named("Desktop")) + key("Right") + wait_for(lambda: named("Laptop").getState().contains(pyatspi.STATE_CHECKED), "application preferences keyboard layout could not be changed") + focus(named("Cancel")); key("space") + assert process.wait(timeout=5) == 0 + print("PASS: application preferences title, removed profile controls, keyboard focus, Cancel") + return + if os.environ.get("CTHULHU_PREFS_HARDWARE_ONLY") == "1": + focus(named("Desktop")) + for page in ("Sounds", "Speech"): + key("ctrl+Page_Down") + wait_for(lambda page=page: named(page).getState().contains(pyatspi.STATE_SELECTED), page + " missing") + system = named("Speech system") + assert system.querySelection().selectChild(1) + preview = request() + assert preview["Preview"] and preview["Values"]["SpeechServerFactory"] == "hardwarefactory", preview + assert preview["Values"]["SpeechOutputModule"] == "litetalk", preview + send({"Preview": True, "Accepted": True}) + module = named("Speech synthesizer") + wait_for(lambda: any(child.name == "DECtalk" for child in walk(module)), "hardware synthesizers missing") + assert module.querySelection().selectChild(3) + preview = request() + assert preview["Values"]["SpeechOutputModule"] == "dectalk", preview + send({"Preview": True, "Accepted": True}) + device = next(child for child in walk(named("Serial device")) if child.getRole() in (pyatspi.ROLE_ENTRY, pyatspi.ROLE_TEXT)) + assert device.queryEditableText().setTextContents("/dev/ttyTEST0") + preview = request() + assert preview["Values"]["HardwareSpeechDevice"] == "/dev/ttyTEST0", preview + send({"Preview": True, "Accepted": True}) + baud = named("Serial baud rate") + assert baud.querySelection().selectChild(4) + preview = request() + assert preview["Values"]["HardwareSpeechBaudRate"] == 19200, preview + send({"Preview": True, "Accepted": True}) + focus(device) + subprocess.run(["xdotool", "windowfocus", xid], check=True) + key("Tab") + # GTK's internal combo button does not expose STATE_FOCUSED + # reliably. Verify the actual workflow: Tab, change baud with + # Down, and inspect the typed preview request. + key("Down") + preview = request() + assert preview["Values"]["HardwareSpeechBaudRate"] == 38400, preview + send({"Preview": True, "Accepted": True}) + key("shift+Tab") + wait_for(lambda: device.getState().contains(pyatspi.STATE_FOCUSED), "Shift+Tab did not return to serial device") + assert not named("Language").getState().contains(pyatspi.STATE_ENABLED) + assert not named("Person").getState().contains(pyatspi.STATE_ENABLED) + focus(named("Apply")); key("space") + applied = request() + assert applied["Save"] and applied["Values"]["SpeechServerFactory"] == "hardwarefactory", applied + assert applied["Values"]["SpeechOutputModule"] == "dectalk" and applied["Values"]["HardwareSpeechDevice"] == "/dev/ttyTEST0", applied + send({"Values": applied["Values"], "CanSave": True, "Accepted": True, "Message": "Hardware settings applied"}) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "hardware Apply stayed busy") + assert system.querySelection().selectChild(0) + preview = request() + assert preview["Values"]["SpeechServerFactory"] == "speechdispatcherfactory", preview + send({"Preview": True, "Accepted": True}) + focus(named("Cancel")); key("space") + assert process.wait(timeout=5) == 0 + print("PASS: hardware system/synth/device/baud, Apply, software restore, serial keyboard navigation, Cancel") + return + if os.environ.get("CTHULHU_PREFS_CAPITALS_ONLY") == "1": + focus(named("Desktop")) + for page in ("Sounds", "Speech"): + key("ctrl+Page_Down") + wait_for(lambda page=page: named(page).getState().contains(pyatspi.STATE_SELECTED), page + " missing") + labels = ("Raise pitch for capital letters", "Beep for capital letters", "Say “cap” before capital letters") + fields = ("RaisePitchForCapitals", "BeepForCapitals", "SayCapForCapitals") + checks = [named(label) for label in labels] + assert all(check.getRole() == pyatspi.ROLE_CHECK_BOX for check in checks) + assert checks[0].getState().contains(pyatspi.STATE_CHECKED) + assert not any(check.getState().contains(pyatspi.STATE_CHECKED) for check in checks[1:]) + focus(checks[0]) + key("shift+Tab") + previous = next(n for n in nodes if n.getState().contains(pyatspi.STATE_FOCUSED)) + assert previous.getRole() == pyatspi.ROLE_SLIDER and "Rate" in previous.name, previous.name + key("Tab") + for check in checks: + wait_for(lambda check=check: check.getState().contains(pyatspi.STATE_FOCUSED), "capital checkbox Tab order") + key("Tab") + following = next(n for n in nodes if n.getState().contains(pyatspi.STATE_FOCUSED)) + assert following not in checks + for check in reversed(checks): + key("shift+Tab") + wait_for(lambda check=check: check.getState().contains(pyatspi.STATE_FOCUSED), "capital checkbox Shift+Tab order") + for mask in range(8): + for bit, check in enumerate(checks): + if check.getState().contains(pyatspi.STATE_CHECKED) != bool(mask & (1 << bit)): + focus(check); key("space") + focus(named("Apply")); key("space") + applied = request() + assert not applied.get("Preview"), applied + assert all(applied["Values"][field] == bool(mask & (1 << bit)) for bit, field in enumerate(fields)), applied + send(dict(initial, Values=applied["Values"], Message="Capital letter settings saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Apply busy") + for bit, check in enumerate(checks): + assert check.getState().contains(pyatspi.STATE_CHECKED) == bool(mask & (1 << bit)) + focus(named("Cancel")); key("space") + assert process.wait(timeout=5) == 0 + print("PASS: capital checkboxes, default pitch, Tab/Shift+Tab, eight independent combinations, Apply/reload") + return + if os.environ.get("CTHULHU_PREFS_VOICE_TYPES_ONLY") == "1": + focus(named("Desktop")) + for page in ("Sounds", "Speech"): + key("ctrl+Page_Down") + wait_for(lambda page=page: named(page).getState().contains(pyatspi.STATE_SELECTED), page + " missing") + voiceType = named("Voice type") + pitchScale = next(n for n in nodes if n.getRole() == pyatspi.ROLE_SLIDER and "pitch" in n.name.lower()) + def accept_preview(): + preview = request() + assert preview["Preview"], preview + send({"Preview": True, "Accepted": True}) + return preview["Values"] + for index, kind, pitch in ((1, "uppercase", 8), (2, "hyperlink", 3), (3, "system", 2)): + assert voiceType.querySelection().selectChild(index) + values = accept_preview() + assert values["VoiceType"] == kind and values["Pitch"] == 5, values + assert values[kind.capitalize() + "Voice"]["AveragePitch"] is None, values + assert pitchScale.getState().contains(pyatspi.STATE_SENSITIVE) + pitchScale.queryValue().currentValue = pitch + values = accept_preview() + assert values[kind.capitalize() + "Voice"]["AveragePitch"] == pitch, values + assert voiceType.querySelection().selectChild(0) + values = accept_preview() + assert values["Pitch"] == 5, values + assert pitchScale.queryValue().currentValue == 5 + for label, mode in (("Beeps", "beeps"), ("Speech and beeps", "both"), ("Speech", "speech")): + radio = next(n for n in nodes if n.getRole() == pyatspi.ROLE_RADIO_BUTTON and n.name == label) + focus(radio); key("space") + focus(named("Apply")); key("space") + applied = request() + assert not applied["Preview"] and applied["Values"]["Reading"]["IndentationPresentationMode"] == mode, applied + values = applied["Values"] + assert values["Pitch"] == 5 and values["UppercaseVoice"]["AveragePitch"] == 8 + assert values["HyperlinkVoice"]["AveragePitch"] == 3 and values["SystemVoice"]["AveragePitch"] == 2 + send(dict(initial, Values=values, Message="Speech settings saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Apply busy") + assert radio.getState().contains(pyatspi.STATE_CHECKED) + assert voiceType.querySelection().selectChild(1) + values = accept_preview() + assert values["Pitch"] == 5 and pitchScale.queryValue().currentValue == 8 + focus(named("Cancel")); key("space") + assert process.wait(timeout=2) == 0 and responses.read_remaining() == "" + print("PASS: independent voice editors, inheritance, previews, indentation modes, Apply/reload, Cancel") + return + if os.environ.get("CTHULHU_PREFS_SPEECH_ONLY") == "1": + focus(named("Desktop")) + for page in ("Sounds", "Speech"): + key("ctrl+Page_Down") + wait_for(lambda page=page: named(page).getState().contains(pyatspi.STATE_SELECTED), page + " missing") + module = named("Speech synthesizer") + language = named("Language") + person = named("Person") + assert module.querySelection().selectChild(1) + preview = request() + assert preview["Preview"] and preview["Values"]["SpeechOutputModule"] == "espeak-ng", preview + send({"Preview": True, "Accepted": True}) + def person_items(): + return {child.name for child in walk(person) if child.getRole() == pyatspi.ROLE_MENU_ITEM} + wait_for(lambda: "English test voice (en)" in person_items() and + "Spanish test voice (es)" not in person_items(), + "default language did not filter eSpeak voices") + if os.environ.get("CTHULHU_PREFS_LARGE_CATALOG") == "1": + assert len(person_items()) == 102, "other-language catalog voices leaked into Person" + echo_items = {child.name for child in walk(named("Key echo person")) + if child.getRole() == pyatspi.ROLE_MENU_ITEM} + assert len(echo_items) == 103, "default eSpeak catalog flooded the key echo list" + assert named("Key echo person").querySelection().getSelectedChild(0).name == "Spanish test voice (es)", \ + "locale filtering lost the saved foreign-language echo voice" + assert preview["Values"]["EchoVoice"]["Family"]["Name"] == "Spanish test voice", preview + # A language near the end of the old truncated catalog remains + # selectable and its whole list is retained after transport. + assert language.querySelection().selectChild(4) + preview = request() + assert preview["Values"]["SpeechVoiceFamily"]["Lang"] == "fr", preview + send({"Preview": True, "Accepted": True}) + wait_for(lambda: "Test voice 11999 (fr)" in person_items(), + "bounded transfer lost the last French voice") + assert language.querySelection().selectChild(1) + preview = request() + send({"Preview": True, "Accepted": True}) + wait_for(lambda: len(person_items()) == 102, "locale voice list did not recover") + focus(named("Raise pitch for capital letters")) + subprocess.run(["xdotool", "windowfocus", xid], check=True) + key("Escape") + assert process.wait(timeout=2) == 0, "large catalog blocked Escape" + print("PASS: large voice catalog selection, locale filter, preview, Escape") + return + assert language.querySelection().selectChild(2) + preview = request() + assert preview["Preview"] and preview["Values"]["SpeechVoiceFamily"] == { + "Name": "", "Lang": "es", "Dialect": "", "Variant": ""}, preview + send({"Preview": True, "Accepted": True}) + wait_for(lambda: "Spanish test voice (es)" in person_items() and + "English test voice (en)" not in person_items(), "Spanish language did not filter voices") + assert person.querySelection().selectChild(1) + preview = request() + assert preview["Preview"] and preview["Values"]["SpeechVoiceFamily"]["Name"] == "Spanish test voice", preview + send({"Preview": True, "Accepted": True}) + for index, module_name in ((2, "test-module"), (1, "espeak-ng")): + assert module.querySelection().selectChild(index) + preview = request() + assert preview["Preview"] and preview["Values"]["SpeechOutputModule"] == module_name, preview + send({"Preview": True, "Accepted": True}) + wait_for(lambda: language.description == "es" and + "Spanish test voice (es)" in person_items() and + "English test voice (en)" not in person_items(), + "switching synthesizers lost the current language") + assert language.querySelection().selectChild(1) + preview = request() + assert preview["Preview"] and preview["Values"]["SpeechVoiceFamily"] == { + "Name": "", "Lang": "en", "Dialect": "", "Variant": ""}, preview + send({"Preview": True, "Accepted": True}) + wait_for(lambda: "English test voice (en)" in person_items() and + "Spanish test voice (es)" not in person_items(), "language did not filter voices") + assert person.querySelection().selectChild(1) + preview = request() + assert preview["Values"]["SpeechVoiceFamily"]["Name"] == "English test voice", preview + send({"Preview": True, "Accepted": True}) + focus(named("Brief")); key("space") + wait_for(lambda: named("Brief").getState().contains(pyatspi.STATE_CHECKED), + "brief speech verbosity did not select") + say_all = named("Say All by") + assert say_all.querySelection().selectChild(0) + focus(named("Apply")); key("space") + applied = request() + assert applied["Save"] and applied["Values"]["SpeechOutputModule"] == "espeak-ng", applied + assert applied["Values"]["SpeechVoiceFamily"]["Lang"] == "en", applied + assert applied["Values"]["SpeechVerbosityLevel"] == 0, applied + assert applied["Values"]["SayAllStyle"] == "sentence", applied + send(dict(initial, Values=applied["Values"], Message="Speech settings saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Apply busy") + assert module.description == "espeak-ng" + assert person.querySelection().getSelectedChild(0).name == "English test voice (en)" + assert named("Brief").getState().contains(pyatspi.STATE_CHECKED) + assert say_all.description == "Sentence" + focus(named("Enable speech")); key("Tab", "alt+Down", "Escape") + assert process.poll() is None, "dropdown Escape closed the whole preferences window" + key("Escape") + assert process.wait(timeout=2) == 0, "Escape did not close preferences promptly" + assert responses.read_remaining() == "", "Escape submitted changes" + print("PASS: synthesizer and voice previews, locale filtering, language preserved across synthesizers, Apply/reload, dropdown and window Escape") + return + if os.environ.get("CTHULHU_PREFS_READING_ONLY") == "1": + focus(named("Desktop")) + for page in ("Sounds", "Speech"): + key("ctrl+Page_Down") + wait_for(lambda page=page: named(page).getState().contains(pyatspi.STATE_SELECTED), page + " missing") + readingTree = next(node for node in nodes if node.name == "Reading settings" + and node.getRole() == pyatspi.ROLE_TABLE) + readingTable = readingTree.queryTable() + assert readingTable.nColumns == 3 + assert [readingTable.getColumnDescription(column) for column in range(3)] == [ + "Enabled", "Setting", "Description"] + for row in range(readingTable.nRows): + stateCell = readingTable.getAccessibleAt(row, 0) + settingCell = readingTable.getAccessibleAt(row, 1) + descriptionCell = readingTable.getAccessibleAt(row, 2) + assert settingCell.name and settingCell.name not in ("checked", "unchecked"), settingCell.name + assert descriptionCell.name and descriptionCell.name != settingCell.name, settingCell.name + checked = stateCell.getState().contains(pyatspi.STATE_CHECKED) + assert stateCell.name == ("checked" if checked else "unchecked"), stateCell.name + titleRow = next(row for row in range(readingTable.nRows) + if readingTable.getAccessibleAt(row, 1).name == "Automatically read title changes") + titleCell = readingTable.getAccessibleAt(titleRow, 0) + assert titleCell.name == "checked" and titleCell.getState().contains(pyatspi.STATE_CHECKED) + focus(titleCell); key("space") + wait_for(lambda: titleCell.name == "unchecked", "title preference did not toggle") + clipboardRow = next(row for row in range(readingTable.nRows) + if readingTable.getAccessibleAt(row, 1).name == "Automatically read clipboard changes") + clipboardCell = readingTable.getAccessibleAt(clipboardRow, 0) + assert clipboardCell.name == "unchecked" and not clipboardCell.getState().contains(pyatspi.STATE_CHECKED) + focus(clipboardCell); key("space") + wait_for(lambda: clipboardCell.name == "checked", "clipboard preference did not toggle") + hintRow = next(row for row in range(readingTable.nRows) + if readingTable.getAccessibleAt(row, 1).name == "Phonetic character hints") + hintCell = readingTable.getAccessibleAt(hintRow, 0) + assert hintCell.name == "unchecked" and not hintCell.getState().contains(pyatspi.STATE_CHECKED) + hintDescription = readingTable.getAccessibleAt(hintRow, 2).name + assert "Left or Right" in hintDescription and "300 ms" in hintDescription, hintDescription + assert "cancels the hint" in hintDescription, hintDescription + for label, expected in (("Phonetic character hints", "checked"), + ("Announce lists in Say All", "checked"), + ("Present tooltips", "checked"), + ("Speak object under mouse", "checked")): + row = next(row for row in range(readingTable.nRows) + if readingTable.getAccessibleAt(row, 1).name == label) + cell = readingTable.getAccessibleAt(row, 0) + before = cell.name + focus(cell); key("space") + wait_for(lambda cell=cell, expected=expected: cell.name == expected, + f"{label} did not toggle: before={before}, after={cell.name}, row={row}") + focus(readingTree) + key("ctrl+Home", "Left") + stateCell = readingTable.getAccessibleAt(0, 0) + wasChecked = stateCell.getState().contains(pyatspi.STATE_CHECKED) + key("space") + wait_for(lambda: stateCell.name == ("unchecked" if wasChecked else "checked"), "reading checkbox name did not change") + assert stateCell.getState().contains(pyatspi.STATE_CHECKED) != wasChecked + key("Right") + wait_for(lambda: readingTable.getAccessibleAt(0, 1).getState().contains(pyatspi.STATE_FOCUSED), "Right did not focus the setting label") + key("Right") + descriptionCell = readingTable.getAccessibleAt(0, 2) + wait_for(lambda: descriptionCell.getState().contains(pyatspi.STATE_FOCUSED), "Right did not focus the description") + # Space still toggles the selected row from the new text column. + key("space") + wait_for(lambda: stateCell.getState().contains(pyatspi.STATE_CHECKED) == wasChecked, + "Space in the description did not toggle the checkbox") + key("space") + wait_for(lambda: stateCell.getState().contains(pyatspi.STATE_CHECKED) != wasChecked, + "Space in the description did not restore the checkbox") + key("Down") + wait_for(lambda: readingTable.isRowSelected(1), "Down did not select the next reading setting") + key("Up") + wait_for(lambda: readingTable.isRowSelected(0), "Up did not return to the first reading setting") + key("Left") + wait_for(lambda: readingTable.getAccessibleAt(0, 1).getState().contains(pyatspi.STATE_FOCUSED), "Left did not return to the setting label") + key("Left") + wait_for(lambda: readingTable.getAccessibleAt(0, 0).getState().contains(pyatspi.STATE_FOCUSED), "Left did not focus the checkbox") + key("Right", "Right") + wait_for(lambda: descriptionCell.getState().contains(pyatspi.STATE_FOCUSED), "description focus missing before Tab") + key("Tab") + wait_for(lambda: not any(node.getState().contains(pyatspi.STATE_FOCUSED) for node in walk(readingTree)), "Tab did not leave reading settings") + key("shift+Tab") + wait_for(lambda: any(node.getState().contains(pyatspi.STATE_FOCUSED) for node in walk(readingTree)), "Shift+Tab did not return to reading settings") + focus(named("Apply")); key("space") + applied = request() + assert applied["Values"]["Reading"]["OnlySpeakDisplayedText"] != wasChecked, applied + assert not applied["Values"]["Reading"]["AutomaticallyReadTitleChanges"], applied + assert applied["Values"]["Reading"]["AutomaticallyReadClipboardChanges"], applied + assert applied["Values"]["Reading"]["PhoneticCharacterHints"], applied + assert applied["Values"]["Reading"]["SayAllContextList"], applied + assert applied["Values"]["Reading"]["PresentTooltips"], applied + assert applied["Values"]["Reading"]["EnableMouseReview"], applied + send(dict(initial, Values=applied["Values"], Message="Reading settings saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Apply busy") + assert readingTable.getAccessibleAt(0, 0).name == ("unchecked" if wasChecked else "checked") + assert readingTable.getAccessibleAt(titleRow, 0).name == "unchecked" + assert readingTable.getAccessibleAt(clipboardRow, 0).name == "checked" + assert readingTable.getAccessibleAt(hintRow, 0).name == "checked" + assert readingTable.getAccessibleAt(next(row for row in range(readingTable.nRows) + if readingTable.getAccessibleAt(row, 1).name == "Announce lists in Say All"), 0).name == "checked" + assert readingTable.getAccessibleAt(next(row for row in range(readingTable.nRows) + if readingTable.getAccessibleAt(row, 1).name == "Present tooltips"), 0).name == "checked" + assert readingTable.getAccessibleAt(next(row for row in range(readingTable.nRows) + if readingTable.getAccessibleAt(row, 1).name == "Speak object under mouse"), 0).name == "checked" + focus(named("Cancel")); key("space") + assert process.wait(timeout=5) == 0 + assert responses.read_remaining() == "", "Cancel submitted reading changes" + print("PASS: three-column reading table and descriptions, Say All, tooltip and mouse choices, Space, arrows, Tab/Shift+Tab, Apply/reload, Cancel") + return + if os.environ.get("CTHULHU_PREFS_MODIFIERS_ONLY") == "1": + modifierTree = named("Cthulhu modifier keys") + modifierTable = modifierTree.queryTable() + assert modifierTable.nRows == 3 and modifierTable.nColumns == 2 + def assert_modifiers(expected): + for row, label in enumerate(("Insert", "Numpad Insert", "Caps Lock")): + assert modifierTable.getAccessibleAt(row, 1).name == label + cell = modifierTable.getAccessibleAt(row, 0) + checked = label in expected + assert cell.name == ("checked" if checked else "unchecked"), cell.name + assert cell.getState().contains(pyatspi.STATE_CHECKED) == checked, cell.name + def open_bindings(): + focus(named("Desktop")) + for page in ("Sounds", "Speech", "Braille", "Key Echo", "Key Bindings"): + key("ctrl+Page_Down") + wait_for(lambda page=page: named(page).getState().contains(pyatspi.STATE_SELECTED), page + " missing") + def apply_modifiers(layout, keys): + focus(named("Apply")); key("space") + applied = request() + assert applied["Values"]["KeyboardLayout"] == layout, applied + assert applied["Values"]["CthulhuModifierKeys"] == keys, applied + send(dict(initial, Values=applied["Values"], Message="Modifier keys saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Apply busy") + # Existing custom settings survive opening; switching General layout + # chooses defaults, and the binding editor layout stays independent. + assert_modifiers({"Insert", "Numpad Insert"}) + focus(named("Laptop")); key("space") + wait_for(lambda: named("Laptop").getState().contains(pyatspi.STATE_CHECKED), "Laptop not selected") + assert_modifiers({"Caps Lock"}) + open_bindings() + focus(modifierTree); key("ctrl+Home", "space", "Down", "space") + assert_modifiers({"Insert", "Numpad Insert", "Caps Lock"}) + key("Tab") + wait_for(lambda: named("Desktop bindings").getState().contains(pyatspi.STATE_FOCUSED), "Tab did not leave modifier table") + key("shift+Tab") + wait_for(lambda: any(node.getState().contains(pyatspi.STATE_FOCUSED) for node in walk(modifierTree)), "Shift+Tab did not return to modifier table") + apply_modifiers(2, ["Insert", "KP_Insert", "Caps_Lock"]) + assert_modifiers({"Insert", "Numpad Insert", "Caps Lock"}) + # Every checkbox can be cleared; Apply/reload preserves an empty list. + focus(modifierTree); key("ctrl+Home", "space", "Down", "space", "Down", "space") + assert_modifiers(set()) + apply_modifiers(2, []) + assert_modifiers(set()) + focus(named("Desktop")); key("space") + wait_for(lambda: named("Desktop").getState().contains(pyatspi.STATE_CHECKED), "Desktop not selected") + assert_modifiers({"Numpad Insert"}) + apply_modifiers(1, ["KP_Insert"]) + assert_modifiers({"Numpad Insert"}) + focus(modifierTree); key("ctrl+Home", "space") + assert_modifiers({"Insert", "Numpad Insert"}) + focus(named("Cancel")); key("space") + assert process.wait(timeout=5) == 0 + assert responses.read_remaining() == "", "Cancel submitted modifier changes" + print("PASS: modifier checkbox table, accessible states, Space, Tab/Shift+Tab, desktop/laptop defaults, multiple/empty selections, Apply/reload, Cancel") + return + if os.environ.get("CTHULHU_PREFS_BINDINGS_ONLY") == "1": + focus(named("Desktop")) + for page in ("Sounds", "Speech", "Braille", "Key Echo", "Key Bindings"): + key("ctrl+Page_Down") + wait_for(lambda page=page: named(page).getState().contains(pyatspi.STATE_SELECTED), page + " missing") + tree = named("Key bindings") + table = tree.queryTable() + def select_command(label, scope): + for row in range(table.nRows): + if table.getAccessibleAt(row, 0).name == label and table.getAccessibleAt(row, 1).name == scope: + focus(tree) + key("ctrl+Home") + if row: + subprocess.run(["xdotool", "key", "--repeat", str(row), "--delay", "1", "Down"], check=True) + return + raise AssertionError((label, scope)) + status = named(initial["Message"]) + editor = next(node for node in nodes if node.name == "Shortcuts" and node.getRole() == pyatspi.ROLE_TEXT) + def set_binding(text): + editor.queryEditableText().setTextContents(text) + focus(named("Set binding")); key("space") + wait_for(lambda: status.getState().contains(pyatspi.STATE_FOCUSED), "binding status not focused") + select_command("Preferences", "Global") + focus(editor); key("Tab") + wait_for(lambda: named("Set binding").getState().contains(pyatspi.STATE_FOCUSED), "Tab did not leave editor") + key("shift+Tab") + wait_for(lambda: editor.getState().contains(pyatspi.STATE_FOCUSED), "Shift+Tab did not return to editor") + set_binding("Cthulhu+q") + wait_for(lambda: "conflicts" in status.name, "conflict not reported") + set_binding("Cthulhu+Ctrl+F8") + wait_for(lambda: "Binding updated" in status.name, "binding not set") + focus(named("Apply")); key("space") + saved = request() + overrides = saved["Values"]["KeyBindings"] + assert len(overrides) == 1 and overrides[0]["Command"] == "preferences" and overrides[0]["Keys"] == ["Cthulhu+Ctrl+F8"], saved + send(dict(initial, Values=saved["Values"], Message="Bindings saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Apply busy") + select_command("Preferences", "Global") + assert editor.queryText().getText(0, -1) == "Cthulhu+Ctrl+F8" + focus(named("Clear binding")); key("space") + focus(named("Apply")); key("space") + cleared = request() + assert cleared["Values"]["KeyBindings"][0]["Keys"] == [], cleared + send(dict(initial, Values=cleared["Values"], Message="Binding cleared.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Clear busy") + select_command("Preferences", "Global") + assert editor.queryText().getText(0, -1) == "" + focus(named("Restore default binding")); key("space") + focus(named("Apply")); key("space") + reset = request() + assert not reset["Values"]["KeyBindings"], reset + send(dict(initial, Values=reset["Values"], Message="Default restored.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Reset busy") + focus(named("Laptop bindings")); key("space") + wait_for(lambda: named("Laptop bindings").getState().contains(pyatspi.STATE_CHECKED), "laptop layout not selected") + select_command("Document next heading", "Browse mode") + set_binding("F6") + focus(named("Apply")); key("space") + laptop = request() + assert laptop["Values"]["KeyBindings"][0]["Layout"] == 2, laptop + send(dict(initial, Values=laptop["Values"], Message="Laptop saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Laptop busy") + focus(named("Laptop bindings")); key("space") + wait_for(lambda: named("Laptop bindings").getState().contains(pyatspi.STATE_CHECKED), "laptop layout not selected") + focus(named("Restore all bindings for this layout")); key("space") + focus(named("Apply")); key("space") + reset_all = request() + assert not reset_all["Values"]["KeyBindings"], reset_all + send(dict(initial, Values=reset_all["Values"], Message="All restored.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Reset all busy") + select_command("Preferences", "Global") + set_binding("F9") + focus(named("Cancel")); key("space") + assert process.wait(timeout=5) == 0 + assert responses.read_remaining() == "", "Cancel submitted bindings" + print("PASS: accessible binding editor, Tab/Shift+Tab, conflict, save/reload, clear, reset, laptop browse, reset all, Cancel") + return + if os.environ.get("CTHULHU_PREFS_BRAILLE_ONLY") == "1": + focus(named("Desktop")) + for page in ("Sounds", "Speech", "Braille"): + key("ctrl+Page_Down") + wait_for(lambda page=page: named(page).getState().contains(pyatspi.STATE_SELECTED), + page + " page did not open") + combo = named("Contraction table") + assert combo.getRole() == pyatspi.ROLE_COMBO_BOX, combo.getRoleName() + focus(named("Enable contracted braille")) + key("Tab") + key("Tab") + wait_for(lambda: named("Enable word wrap").getState().contains(pyatspi.STATE_FOCUSED), + "Tab did not leave the contraction table") + key("shift+Tab") + key("shift+Tab") + wait_for(lambda: named("Enable contracted braille").getState().contains(pyatspi.STATE_FOCUSED), + "Shift+Tab did not leave the contraction table backwards") + focus(named("Abbreviated role names")); key("space") + focus(named("Disable end of line symbol")); key("space") + focus(named("Enable word wrap")); key("space") + focus(named("Messages are persistent")); key("space") + focus(named("Messages are detailed")); key("space") + braille_brief = [n for n in nodes if n.name == "Brief" and + n.getRole() == pyatspi.ROLE_RADIO_BUTTON][1] + focus(braille_brief); key("space") + focus(named("Selection indicator: Dot 7")); key("space") + focus(named("Link indicator: None")); key("space") + named("Flash message duration").queryValue().currentValue = 3 + selection = combo.querySelection() + assert selection.selectChild(1), "no locale contraction tables" + wait_for(lambda: "en-ueb" in combo.description.lower(), + "US UEB table missing from contraction choices") + focus(named("Apply")); key("space") + applied = request() + braille_values = applied["Values"]["Braille"] + assert braille_values["AbbreviateRoles"] and braille_values["DisableEOL"], applied + assert braille_values["WordWrap"] and braille_values["FlashPersistent"], applied + assert not braille_values["FlashDetailed"] and braille_values["FlashTime"] == 3000, applied + assert braille_values["Verbosity"] == 0 and braille_values["SelectionIndicator"] == 64, applied + assert braille_values["LinkIndicator"] == 0, applied + assert applied["Values"]["BrailleContractionTable"].endswith("en-ueb-g1.ctb"), applied + print("PASS: Braille table chooser and preference protocol") + return + expected_tabs = {"General", "Sounds", "Speech", "Braille", "Key Echo", + "Key Bindings", "Pronunciation", "Text Attributes", "OCR"} + if not application: + expected_tabs.add("Tentacles") + main_tabs = next(n for n in nodes if n.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + tabs = {main_tabs.getChildAtIndex(index).name for index in range(main_tabs.childCount) + if main_tabs.getChildAtIndex(index).getRole() == pyatspi.ROLE_PAGE_TAB} + assert tabs == expected_tabs, ("preferences tabs", tabs) + interactive_roles = { + pyatspi.ROLE_CHECK_BOX, pyatspi.ROLE_COMBO_BOX, pyatspi.ROLE_ENTRY, + pyatspi.ROLE_PAGE_TAB, pyatspi.ROLE_PUSH_BUTTON, pyatspi.ROLE_RADIO_BUTTON, + pyatspi.ROLE_SLIDER, pyatspi.ROLE_SPIN_BUTTON, pyatspi.ROLE_TABLE, + pyatspi.ROLE_TOGGLE_BUTTON, pyatspi.ROLE_TREE_TABLE, + } + unnamed = sorted(n.getRoleName() for n in nodes + if n.getRole() in interactive_roles and not n.name) + assert not unnamed, ("unnamed interactive controls", unnamed) + sliders = [n for n in nodes if n.getRole() == pyatspi.ROLE_SLIDER and + any(word in n.name for word in ("Rate", "Pitch", "Volume"))] + assert len(sliders) == 3, [(n.name, n.getRoleName()) for n in nodes] + desktop = named("Desktop") + assert desktop.getRole() == pyatspi.ROLE_RADIO_BUTTON + assert desktop.getState().contains(pyatspi.STATE_CHECKED), "Desktop radio value missing" + time_format = next(n for n in nodes if n.name == "Time format" and + n.getRole() == pyatspi.ROLE_COMBO_BOX) + time_selection = time_format.querySelection() + assert time_selection.nSelectedChildren == 1 + selected_time = time_selection.getSelectedChild(0).name + assert time_format.description == selected_time, ( + "combo value missing", time_format.description, selected_time) + capital_pitch = named("Raise pitch for capital letters") + capital_beep = named("Beep for capital letters") + capital_cap = named("Say “cap” before capital letters") + assert capital_pitch.getState().contains(pyatspi.STATE_CHECKED) + assert not capital_beep.getState().contains(pyatspi.STATE_CHECKED) + assert not capital_cap.getState().contains(pyatspi.STATE_CHECKED) + date_format = next(n for n in nodes if n.name == "Date format" and + n.getRole() == pyatspi.ROLE_COMBO_BOX) + changed = dict(initial, Values=dict(initial["Values"], BeepForCapitals=True, SayCapForCapitals=True, TimeFormat="12-hour", DateFormat="dmy")) + send(changed) + wait_for(lambda: capital_cap.getState().contains(pyatspi.STATE_CHECKED), + "changed capital checkbox value was not exposed") + assert capital_beep.getState().contains(pyatspi.STATE_CHECKED) + wait_for(lambda: time_format.description == time_selection.getSelectedChild(0).name, + "time format did not initialize") + assert date_format.description == date_format.querySelection().getSelectedChild(0).name + send(initial) + wait_for(lambda: not capital_cap.getState().contains(pyatspi.STATE_CHECKED), + "restored capital checkbox value was not exposed") + progress = named("Progress bar output") + assert progress.description == "Beep", progress.description + background = named("Report background progress bars") + focus(background) + key("shift+Tab", "Down") + wait_for(lambda: progress.description == "Speak", "progress mode keyboard change missing") + key("Tab") + background = named("Report background progress bars") + wait_for(lambda: background.getState().contains(pyatspi.STATE_FOCUSED), + "progress mode trapped Tab") + key("space") + assert background.getState().contains(pyatspi.STATE_CHECKED) + for old_name in ("Beep progress bar updates", "Progress bar updates apply to", "Play sound for value", + "Progress bar beep frequency in seconds", "Progress bar update frequency in seconds", + "Speak progress bar updates", "Braille progress bar updates"): + assert old_name not in controls, "obsolete progress control remains: " + old_name + assert time_selection.selectChild(1) + assert date_format.querySelection().selectChild(2) + wait_for(lambda: time_format.description == time_selection.getSelectedChild(0).name, + "edited time selection missing") + wait_for(lambda: date_format.description == date_format.querySelection().getSelectedChild(0).name, + "edited date selection missing") + focus(desktop) + key("ctrl+Page_Down") + wait_for(lambda: named("Sounds").getState().contains(pyatspi.STATE_SELECTED), + "Sounds page did not open") + for name in ("Enable sounds", "Play sound for role", "Play sound for state", + "Play sound for position in set"): + assert named(name).getState().contains(pyatspi.STATE_CHECKED), name + " default missing" + assert not named("Use stereo position for object sounds").getState().contains( + pyatspi.STATE_CHECKED), "stereo sound placement was enabled by default" + presentation = named("Element presentation") + presentation_selection = presentation.querySelection() + assert presentation_selection.nSelectedChildren == 1 + for index, expected in enumerate(("Sound and speech", "Speech only", "Sound only")): + assert presentation_selection.selectChild(index) + wait_for(lambda expected=expected: presentation.description == expected, + expected + " presentation did not select") + assert presentation_selection.selectChild(0) + wait_for(lambda: presentation.description == "Sound and speech", "mixed presentation did not restore") + spatialize = named("Use stereo position for object sounds") + focus(spatialize); key("space") + wait_for(lambda: spatialize.getState().contains(pyatspi.STATE_CHECKED), + "stereo sound placement did not toggle") + sound_volume = named("Sound volume") + assert sound_volume.queryValue().minimumValue == 0 + assert sound_volume.queryValue().maximumValue == 1 + master_sound = named("Enable sounds") + focus(master_sound); key("space") + wait_for(lambda: not sound_volume.getState().contains(pyatspi.STATE_SENSITIVE), + "sound master did not disable sound controls") + focus(master_sound); key("space") + key("ctrl+Page_Down") + wait_for(lambda: named("Speech").getState().contains(pyatspi.STATE_SELECTED), + "Speech page did not open") + history_limit = named("Speech history entries") + assert history_limit.getRole() == pyatspi.ROLE_SPIN_BUTTON + assert history_limit.queryValue().minimumValue == 1 + assert history_limit.queryValue().maximumValue == 1000 + assert history_limit.queryValue().currentValue == 50 + focus(history_limit) + history_limit.queryValue().currentValue = 75 + for slider in sliders: + relations = slider.getRelationSet() + assert any(r.getRelationType() == pyatspi.RELATION_LABELLED_BY for r in relations), ( + "missing label buddy", slider.name) + assert slider.name, "unnamed slider" + rate = next(n for n in sliders if "Rate" in n.name) + for name in ("Help", "Apply", "Cancel", "OK"): + assert named(name).getRole() == pyatspi.ROLE_PUSH_BUTTON + # Prove the supported controls accept focus, and that the scale does + # not trap forward or reverse keyboard traversal. + assert not any(name.startswith("Use server default") for name in controls) + for name in ("Apply", "Cancel", "OK"): + focus(named(name)) + for slider in sliders: + assert slider.getState().contains(pyatspi.STATE_SENSITIVE) + focus(slider) + pitch = next(n for n in sliders if "Pitch" in n.name) + focus(pitch) + key("Tab") + wait_for(lambda: rate.getState().contains(pyatspi.STATE_FOCUSED), + "Tab did not enter the rate slider") + key("shift+Tab") + wait_for(lambda: pitch.getState().contains(pyatspi.STATE_FOCUSED), + "Shift+Tab did not return to the pitch slider") + focus(named("Some")); key("space") + wait_for(lambda: named("Some").getState().contains(pyatspi.STATE_CHECKED), + "radio activation did not select punctuation") + print("PASS: initial preferences accessibility and keyboard navigation", flush=True) + focus(rate) + rate.queryValue().currentValue = 72 + preview = request() + assert preview["Preview"] and preview["Values"]["Rate"] == 72, preview + send({"Preview": True, "Accepted": True, "Message": "Speech settings previewed."}) + focus(named("Apply")) + key("space") + draft = request() + assert draft["Values"]["SpeechHistoryLimit"] == 75, draft + assert draft["Values"]["TimeFormat"] == "12-hour" and draft["Values"]["DateFormat"] == "numbers-md", draft + assert draft["Values"]["Rate"] == 72 and draft["Save"] and not draft["Close"], draft + assert draft["Values"]["Punctuation"] == 2 and draft["Values"]["Pitch"] == 5, draft + assert draft["Values"]["EnableSound"] and draft["Values"]["PlaySoundForRole"], draft + assert draft["Values"]["PlaySoundForState"] and draft["Values"]["SpatializeObjectSounds"], draft + assert draft["Values"]["ProgressBar"]["OutputMode"] == "speak", draft + assert draft["Values"]["ProgressBar"]["ReportBackground"], draft + expectedProgress = dict(initial["Values"]["ProgressBar"], OutputMode="speak", ReportBackground=True) + assert draft["Values"]["ProgressBar"] == expectedProgress, draft + # Simulated backend failure: restore editing, expose error by focus, + # and preserve the draft for correction. + rejected = dict(initial, Accepted=False, Message="Settings were not applied: test rejection.") + send(rejected) + status = controls[initial["Message"]] + wait_for(lambda: status.name == rejected["Message"], "error status missing") + wait_for(lambda: status.getState().contains(pyatspi.STATE_FOCUSED), "error status was not focused") + assert rate.queryValue().currentValue == 72, "rejection discarded draft" + focus(named("OK")); key("space") + saved = request() + assert saved["Save"] and saved["Close"] and saved["Values"]["Rate"] == 72 + assert saved["Values"]["ProgressBar"] == expectedProgress, saved + # Reload a backend response with custom TOML-only thresholds. Later + # Apply and OK requests must preserve those too. + expectedProgress = dict(expectedProgress, BeepPercentageInterval=3, SpeechPercentageInterval=17) + saved["Values"]["ProgressBar"] = expectedProgress + accepted = dict(initial, Values=saved["Values"], Message="Settings applied and saved.") + send(accepted) + wait_for(lambda: status.name == accepted["Message"], "success status missing") + print("PASS: Apply, rejected draft, OK protocol", flush=True) + # GtkScale consumes Ctrl+Page_Down as a value change. Verify that + # behavior, then navigate the notebook from the capital pitch checkbox. + focus(rate) + previous_rate = rate.queryValue().currentValue + key("ctrl+Page_Down") + wait_for(lambda: rate.queryValue().currentValue != previous_rate, + "slider did not handle Ctrl+Page_Down") + assert named("Speech").getState().contains(pyatspi.STATE_SELECTED) + preview = request() + assert preview["Preview"], preview + send({"Preview": True, "Accepted": True, "Message": "Speech settings previewed."}) + rate.queryValue().currentValue = previous_rate + preview = request() + assert preview["Preview"] and preview["Values"]["Rate"] == previous_rate, preview + send({"Preview": True, "Accepted": True, "Message": "Speech settings previewed."}) + focus(named("Raise pitch for capital letters")) + for page in ("Braille", "Key Echo"): + key("ctrl+Page_Down") + wait_for(lambda: named(page).getState().contains(pyatspi.STATE_SELECTED), + page + " page did not open") + # Verify keyboard access, master sensitivity, and echo protocol values. + master = named("Enable key echo") + disabled = named("Disable key echo") + edit_fields = named("Key echo in edit fields") + for radio in (disabled, master, edit_fields): + assert radio.getRole() == pyatspi.ROLE_RADIO_BUTTON, radio.name + alphabetic = named("Enable alphabetic keys") + assert master.getState().contains(pyatspi.STATE_CHECKED) + assert alphabetic.getState().contains(pyatspi.STATE_CHECKED) + focus(disabled); key("space") + wait_for(lambda: not alphabetic.getState().contains(pyatspi.STATE_SENSITIVE), "master did not disable categories") + focus(named("Apply")); key("space") + off = request() + assert off["Save"] and not off["Close"] and not off["Values"]["EnableKeyEcho"], off + assert off["Values"]["ProgressBar"] == expectedProgress, off + assert off["Values"]["EnableAlphabeticKeys"] and off["Values"]["EnableEchoByWord"], off + send(dict(initial, Values=off["Values"], Message="Echo off saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "Apply stayed busy") + assert not master.getState().contains(pyatspi.STATE_CHECKED) + wait_for(lambda: master.getState().contains(pyatspi.STATE_SENSITIVE), "key echo master stayed insensitive") + focus(master); key("space") + wait_for(lambda: master.getState().contains(pyatspi.STATE_CHECKED), "key echo master did not re-enable") + # The three choices are one keyboard radio group. Tab exits the group, + # Shift+Tab returns to the selected radio, and Apply reloads the mode. + key("Down") + wait_for(lambda: edit_fields.getState().contains(pyatspi.STATE_CHECKED), "Down did not select edit-fields-only") + assert not master.getState().contains(pyatspi.STATE_CHECKED) + key("Tab") + wait_for(lambda: alphabetic.getState().contains(pyatspi.STATE_FOCUSED), "Tab did not leave echo radio group") + key("shift+Tab") + wait_for(lambda: edit_fields.getState().contains(pyatspi.STATE_FOCUSED), "Shift+Tab did not return to selected radio") + focus(named("Apply")); key("space") + edit_only = request() + assert edit_only["Values"]["EnableKeyEcho"] and edit_only["Values"]["KeyEchoInEditFieldsOnly"], edit_only + send(dict(initial, Values=edit_only["Values"], Message="Edit fields echo saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "edit-fields Apply stayed busy") + assert edit_fields.getState().contains(pyatspi.STATE_CHECKED) + assert alphabetic.getState().contains(pyatspi.STATE_SENSITIVE) + focus(named("Use custom echo voice")); key("space") + echo_rate = named("Key echo rate") + wait_for(lambda: echo_rate.getState().contains(pyatspi.STATE_SENSITIVE), "custom voice controls disabled") + # Only one preview may be outstanding. Read and acknowledge each + # changed value before moving focus, which discards stale previews. + for control, field, value in (("rate", "Rate", 83), + ("pitch", "AveragePitch", 7.5), + ("volume", "Gain", 10)): + slider = named("Key echo " + control) + focus(slider) + slider.queryValue().currentValue = value + preview = request() + assert preview["Preview"] and preview.get("EchoPreview") == control, preview + assert preview["Values"]["EchoVoice"][field] == value, preview + send({"Preview": True, "Accepted": True}) + family = named("Key echo person") + # Echo selection previews require keyboard focus in the selector. + focus(named("Use custom echo voice")); key("Tab", "Tab", "Down") + preview = request() + assert preview["Preview"] and preview.get("EchoPreview") == "person", preview + assert preview["Values"]["EchoVoice"]["Family"]["Name"] == "Test voice", preview + assert family.querySelection().getSelectedChild(0).name == "Test voice (en)" + send({"Preview": True, "Accepted": True}) + word_voice = named("Words") + assert not word_voice.getState().contains(pyatspi.STATE_CHECKED) + focus(word_voice); key("space") + wait_for(lambda: word_voice.getState().contains(pyatspi.STATE_CHECKED), + "custom word voice did not become checked") + focus(named("OK")); key("space") + echo_saved = request() + ev = echo_saved["Values"] + assert ev["ProgressBar"] == expectedProgress, ev + assert echo_saved["Save"] and echo_saved["Close"] and ev["EnableKeyEcho"], echo_saved + assert ev["UseCustomEchoVoice"] and ev["UseCustomEchoForWord"] and ev["KeyEchoInEditFieldsOnly"], ev + assert ev["EchoVoice"]["Rate"] == 83 and ev["EchoVoice"]["AveragePitch"] == 7.5 and ev["EchoVoice"]["Gain"] == 10, ev + assert ev["EchoVoice"]["Family"]["Name"] == "Test voice", ev + send(dict(initial, Values=ev, Message="Echo voice saved.")) + wait_for(lambda: named("Apply").getState().contains(pyatspi.STATE_SENSITIVE), "OK stayed busy") + # Present must retain edits. Escape closes promptly while the parent + # restores the live voice preview after helper exit. + rate.queryValue().currentValue = 61 + preview = request() + assert preview["Preview"] and preview["Values"]["Rate"] == 61, preview + send({"Preview": True, "Accepted": True, "Message": "Speech settings previewed."}) + send({"Present": True}) + focus(master) + key("ctrl+Page_Up", "ctrl+Page_Up") + wait_for(lambda: named("Speech").getState().contains(pyatspi.STATE_SELECTED), + "Speech page did not reopen") + focus(named("Raise pitch for capital letters")) + subprocess.run(["xdotool", "windowfocus", xid], check=True) + key("Escape") + assert process.wait(timeout=2) == 0, "Escape did not close preferences promptly" + assert responses.read_remaining() == "", "Escape submitted extra settings" + print("PASS: GTK notebook, roles, label buddies, Tab/Shift+Tab, Apply, failed apply, OK, Escape") + finally: + if reader_process is not None: + reader_process.terminate() + try: + reader_process.wait(timeout=5) + except subprocess.TimeoutExpired: + reader_process.kill() + reader_process.wait(timeout=5) + if process.poll() is None: + process.kill() + process.wait(timeout=5) + if window_manager is not None: + window_manager.terminate() + window_manager.wait(timeout=5) + if private_directory is not None: + private_directory.cleanup() + + +def main(): + if "--inside" in sys.argv: + inside() + return + read_fd, write_fd = os.pipe() + server = subprocess.Popen(["Xvfb", "-displayfd", str(write_fd), "-screen", "0", "1024x768x24", "-nolisten", "tcp"], pass_fds=(write_fd,), stderr=subprocess.DEVNULL) + os.close(write_fd) + try: + with os.fdopen(read_fd) as reader: + display = reader.readline().strip() + assert display, "Xvfb failed" + env = dict(os.environ, DISPLAY=":" + display, GDK_BACKEND="x11", GTK_MODULES="gail:atk-bridge", GIO_USE_VFS="local") + if env.get("CTHULHU_PREFS_SPEECH_ONLY") == "1": + env["LC_ALL"] = "en_US.UTF-8" + for key in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + env.pop(key, None) + run_private_session(["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), "--inside"], env=env, check=True, timeout=90) + finally: + server.terminate() + server.wait(timeout=5) + + +if __name__ == "__main__": + main() diff --git a/tests/native_progress.py b/tests/native_progress.py new file mode 100644 index 0000000..0bf098e --- /dev/null +++ b/tests/native_progress.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Private X11/AT-SPI proof for foreground and background progress output.""" +import os +from pathlib import Path +import subprocess +import sys + +from native_test_session import run_private_session + + +def main(): + if len(sys.argv) == 2 and sys.argv[1] == "--inside": + environment = dict(os.environ, CTHULHU_NATIVE_PROGRESS="1") + environment.setdefault("GOCACHE", "/tmp/cthulhu-cache") + subprocess.run(["go", "test", "./internal/app", "-run", "^TestNativeProgressBars$", + "-count=1", "-v", "-timeout=30s"], + cwd=Path(__file__).resolve().parents[1], env=environment, + check=True, timeout=35) + return + readFd, writeFd = os.pipe() + server = subprocess.Popen(["Xvfb", "-displayfd", str(writeFd), "-screen", "0", + "1024x768x24", "-nolisten", "tcp"], + pass_fds=(writeFd,), stderr=subprocess.DEVNULL) + os.close(writeFd) + try: + with os.fdopen(readFd) as reader: + display = reader.readline().strip() + if not display: + raise RuntimeError("Xvfb failed") + environment = dict(os.environ, DISPLAY=":" + display, XDG_SESSION_TYPE="x11", + GDK_BACKEND="x11", GTK_MODULES="gail:atk-bridge", GIO_USE_VFS="local") + for name in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + environment.pop(name, None) + run_private_session(["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), + "--inside"], env=environment, check=True, timeout=45) + finally: + server.terminate() + server.wait(timeout=3) + + +if __name__ == "__main__": + main() diff --git a/tests/native_qt_controls.py b/tests/native_qt_controls.py new file mode 100644 index 0000000..32d0919 --- /dev/null +++ b/tests/native_qt_controls.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +# Copyright (c) 2026 Storm Dragon +# Authors: Storm Dragon, Angus Kola +# SPDX-License-Identifier: GPL-3.0-or-later +"""Check Qt menu and button states on a private X11/AT-SPI desktop.""" +import os +from pathlib import Path +import subprocess +import sys +import tempfile + +sys.dont_write_bytecode = True +from native_x11 import wait_for +from native_test_session import run_private_session + + +def fixture(version): + if version == '5': + from PyQt5 import QtCore, QtWidgets + else: + from PySide6 import QtCore, QtWidgets + + class ControlWindow(QtWidgets.QMainWindow): + def keyPressEvent(self, event): + nonlocal option + targets = {QtCore.Qt.Key_F6: option, QtCore.Qt.Key_F7: ordinary, + QtCore.Qt.Key_F8: contextOption} + if event.key() in targets: + target = targets[event.key()] + popup = contextMenu if target is contextOption else menu + popup.popup(self.mapToGlobal(QtCore.QPoint(20, 50))) + popup.setActiveAction(target) + elif event.key() == QtCore.Qt.Key_F9: + checkbox.setFocus() + elif event.key() == QtCore.Qt.Key_F10: + toggle.setFocus() + elif event.key() == QtCore.Qt.Key_F11: + menu.removeAction(option) + option.deleteLater() + option = menu.addAction('Optional feature') + elif event.key() == QtCore.Qt.Key_F12: + option.setCheckable(False) + else: + super().keyPressEvent(event) + + application = QtWidgets.QApplication([]) + window = ControlWindow() + window.setWindowTitle('Qt control states probe') + content = QtWidgets.QWidget() + layout = QtWidgets.QVBoxLayout(content) + checkbox = QtWidgets.QCheckBox('Updates') + layout.addWidget(checkbox) + toggle = QtWidgets.QPushButton('Power') + toggle.setCheckable(True) + layout.addWidget(toggle) + window.setCentralWidget(content) + menu = window.menuBar().addMenu('&Actions') + option = menu.addAction('Optional feature') + option.setCheckable(True) + ordinary = menu.addAction('Ordinary action') + contextMenu = QtWidgets.QMenu(window) + contextOption = contextMenu.addAction('Context option') + contextOption.setCheckable(True) + # Shared actions can retain their menu-bar accessibility parent even + # while the context menu emits their focus events. + contextMenu.addAction(ordinary) + contextMenu.addAction('Context command') + contextMenu.addAction(option) + window.resize(400, 250) + window.show() + checkbox.setFocus() + application.exec() + + +def run_inside(): + root = Path(__file__).resolve().parents[1] + for version in ('5', '6'): + process = subprocess.Popen([sys.executable, __file__, '--fixture', version]) + try: + def find_window(): + result = subprocess.run(['xdotool', 'search', '--onlyvisible', '--name', + '^Qt control states probe$'], capture_output=True, text=True) + return result.stdout.strip().splitlines()[0] if result.stdout.strip() else None + + windowId = wait_for(find_window, 'Qt fixture window missing') + subprocess.run(['xdotool', 'windowfocus', windowId], check=True) + from native_x11 import set_active_window + set_active_window(int(windowId)) + subprocess.run(['go', 'test', './internal/app', '-run', '^TestNativeQtControlStates$', + '-count=1', '-v', '-timeout=45s'], cwd=root, check=True, timeout=60, + env=dict(os.environ, CTHULHU_NATIVE_QT_CONTROLS=version, + GOCACHE='/tmp/cthulhu-cache')) + finally: + process.terminate() + process.wait(timeout=5) + + +if __name__ == '__main__': + if '--fixture' in sys.argv: + fixture(sys.argv[-1]) + elif '--inside' in sys.argv: + run_inside() + else: + with tempfile.TemporaryDirectory(prefix='cthulhu-qt-controls-') as temporary: + environment = dict(os.environ, HOME=temporary, XDG_CONFIG_HOME=temporary, + XDG_CACHE_HOME=temporary, XDG_DATA_HOME=temporary, + GOMODCACHE=subprocess.check_output(['go', 'env', 'GOMODCACHE'], text=True).strip(), + QT_QPA_PLATFORM='xcb', QT_LINUX_ACCESSIBILITY_ALWAYS_ON='1', + NO_AT_BRIDGE='0') + environment.pop('AT_SPI_BUS_ADDRESS', None) + run_private_session(['xvfb-run', '-a', 'dbus-run-session', '--', sys.executable, + __file__, '--inside'], env=environment, check=True) diff --git a/tests/native_speech_defaults.py b/tests/native_speech_defaults.py new file mode 100644 index 0000000..bd779f4 --- /dev/null +++ b/tests/native_speech_defaults.py @@ -0,0 +1,114 @@ +"""Missing-file acceptance checks for the real private reader/preferences pair.""" +import json +import subprocess +import tomllib + +from native_x11 import wait_for + + +def check_no_config(window, tabs, server, configPath): + import pyatspi + + def walk(node): + yield node + for child in node: + if child is not None: + yield from walk(child) + + def controls_for(currentWindow): + nodes = list(walk(currentWindow)) + controls = {node.name.rstrip(":"): node for node in nodes if node.name} + controls.update({node.name.rstrip(":"): node for node in nodes + if node.getRole() in (pyatspi.ROLE_SLIDER, pyatspi.ROLE_COMBO_BOX)}) + return controls + + def key(*keys): + subprocess.run(["xdotool", "key", "--clearmodifiers", *keys], check=True) + + def focus(control): + assert control.queryComponent().grabFocus(), control.name + wait_for(lambda: control.getState().contains(pyatspi.STATE_FOCUSED), "focus missing: " + control.name) + + def saved_speech(): + if configPath.exists(): + data = tomllib.loads(configPath.read_text()) + return data["profiles"][data["active-profile"]]["speech"] + + def find_window(): + for application in pyatspi.Registry.getDesktop(0): + for candidate in application: + if candidate and candidate.name == "Cthulhu Preferences": + return candidate + + assert not configPath.exists(), "opening preferences unexpectedly created a configuration" + assert tabs.querySelection().selectChild(2) + controls = controls_for(window) + assert not any(name.startswith(("Use server default", "Use Default voice", "Use automatic uppercase")) + for name in controls) + expected = {"Rate": 59, "Pitch": 4, "Volume": 9} if server.defaultsSupported else {"Rate": 50, "Pitch": 5, "Volume": 5} + for name, value in expected.items(): + slider = controls[name] + assert slider.getRole() == pyatspi.ROLE_SLIDER, (name, slider.getRoleName()) + assert slider.getState().contains(pyatspi.STATE_SENSITIVE), name + assert slider.queryValue().currentValue == value, (name, slider.queryValue().currentValue, value) + for previous, following in (("Volume", "Pitch"), ("Pitch", "Rate")): + focus(controls[previous]); key("Tab") + wait_for(lambda: controls[following].getState().contains(pyatspi.STATE_FOCUSED), "Tab traversal failed") + key("shift+Tab") + wait_for(lambda: controls[previous].getState().contains(pyatspi.STATE_FOCUSED), "Shift+Tab traversal failed") + + voiceType = controls["Voice type"] + assert voiceType.querySelection().selectChild(1) + wait_for(lambda: controls["Pitch"].queryValue().currentValue == 7, "automatic uppercase pitch missing") + assert voiceType.querySelection().selectChild(0) + wait_for(lambda: controls["Pitch"].queryValue().currentValue == expected["Pitch"], "Default pitch did not return") + focus(controls["Apply"]); key("space") + wait_for(lambda: saved_speech() is not None, "Apply did not create the missing config") + speech = saved_speech() + assert not speech.get("default-voice"), speech + assert not speech.get("uppercase-voice"), speech + wait_for(lambda: controls["Apply"].getState().contains(pyatspi.STATE_SENSITIVE), "Apply stayed busy") + + expectedRaw = {} + for name, scale, offset in (("Rate", 2, 98), ("Pitch", 20, 90), ("Volume", 15, 35)): + slider = controls[name] + focus(slider); key("Down" if name == "Volume" else "Up") + expected[name] += -1 if name == "Volume" else 1 + expectedRaw[name.upper()] = int(scale * expected[name] - offset) + wait_for(lambda: slider.queryValue().currentValue == expected[name], name + " did not change directly") + wait_for(lambda: any(all(record["settings"][field] == value for field, value in expectedRaw.items()) + for record in server.snapshot()), name + " preview did not reach speech backend") + focus(controls["Apply"]); key("space") + def saved_values_match(): + voice = saved_speech().get("default-voice", {}) + return all(voice.get(field) == expected[name] for name, field in + (("Rate", "rate"), ("Pitch", "average-pitch"), ("Volume", "gain"))) + wait_for(saved_values_match, "slider values were not saved") + assert not saved_speech().get("uppercase-voice"), saved_speech() + wait_for(lambda: controls["Apply"].getState().contains(pyatspi.STATE_SENSITIVE), "Apply stayed busy") + focus(controls["Cancel"]); key("space") + wait_for(lambda: find_window() is None, "preferences did not close") + key("Insert+space") + reopened = wait_for(find_window, "preferences did not reopen") + controls = controls_for(reopened) + tabs = next(node for node in walk(reopened) if node.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + assert tabs.querySelection().selectChild(2) + for name, value in expected.items(): + assert controls[name].queryValue().currentValue == value, (name, value) + assert controls["Voice type"].querySelection().selectChild(1) + wait_for(lambda: controls["Pitch"].queryValue().currentValue == max(7, expected["Pitch"] + 2), + "untouched Uppercase pitch stopped following Default") + assert controls["Voice type"].querySelection().selectChild(0) + focus(controls["Rate"]); key("Up") + changedRaw = dict(expectedRaw, RATE=expectedRaw["RATE"] + 2) + wait_for(lambda: any(record["settings"] == changedRaw for record in server.snapshot()), "unsaved preview missing") + focus(controls["Cancel"]); key("space") + wait_for(lambda: find_window() is None, "Cancel did not close preferences") + assert saved_values_match(), "Cancel changed the saved settings" + key("Insert+space") + reopened = wait_for(find_window, "preferences did not reopen after Cancel") + controls = controls_for(reopened) + assert controls["Rate"].queryValue().currentValue == expected["Rate"], "Cancel retained the unsaved rate" + (configPath.parent / "speech-defaults.json").write_text(json.dumps({ + "initialConfigMissing": True, "serverDefaultsSupported": server.defaultsSupported, + "savedValues": expected, "savedBackendValues": expectedRaw}, indent=2)) diff --git a/tests/native_speech_history.py b/tests/native_speech_history.py new file mode 100644 index 0000000..9701df6 --- /dev/null +++ b/tests/native_speech_history.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 +"""Private Xvfb/AT-SPI proof for the speech history and monitor helper.""" +import json +import os +from pathlib import Path +import select +import subprocess +import sys + +sys.dont_write_bytecode = True +from native_x11 import wait_for +from native_test_session import run_private_session + + +def inside(): + import pyatspi + + binary = os.environ.get("CTHULHU_BINARY", str(Path(__file__).resolve().parents[1] / "cthulhu")) + + def walk(node): + yield node + for child in node: + if child is not None: + yield from walk(child) + + def window_named(title): + for application in pyatspi.Registry.getDesktop(0): + for node in application: + if node and node.name == title: + return node + return None + + def open_helper(mode, items=None): + process = subprocess.Popen( + [binary, "--speech-history-ui"], stdin=subprocess.PIPE, + stdout=subprocess.PIPE, text=True, + ) + send(process, {"mode": mode, "items": items or []}) + return process + + def send(process, value): + process.stdin.write(json.dumps(value) + "\n") + process.stdin.flush() + + def request(process): + assert select.select([process.stdout], [], [], 5)[0], "no speech history response" + return json.loads(process.stdout.readline()) + + def click(node): + assert node.queryComponent().grabFocus(), ("cannot focus", node.name) + subprocess.run(["xdotool", "key", "--clearmodifiers", "space"], check=True) + + history = open_helper("history", ["Newest speech", "Older speech", "Another line"]) + try: + window = wait_for(lambda: window_named("Speech History - Cthulhu"), "history window missing") + controls = {node.name: node for node in walk(window) if node.name} + for name in ("Filter:", "Newest speech", "Older speech", "Another line", + "Copy to clipboard", "Remove from history", "Close"): + assert name in controls, ("missing history control", name, list(controls)) + table = next(node for node in walk(window) if node.getRole() == pyatspi.ROLE_TABLE) + assert table.queryComponent().grabFocus(), "cannot focus history table" + subprocess.run(["xdotool", "key", "--clearmodifiers", "Down"], check=True) + wait_for(lambda: table.querySelection().getSelectedChild(0).name == "Older speech", + "Down did not select the next history entry") + subprocess.run(["xdotool", "key", "--clearmodifiers", "Up"], check=True) + wait_for(lambda: table.querySelection().getSelectedChild(0).name == "Newest speech", + "Up did not restore the first history entry") + subprocess.run(["xdotool", "key", "--clearmodifiers", "o"], check=True) + wait_for(lambda: table.queryTable().nRows == 1, "typing did not filter by prefix") + subprocess.run(["xdotool", "key", "--clearmodifiers", "BackSpace"], check=True) + wait_for(lambda: table.queryTable().nRows == 3, "backspace did not clear the filter") + assert table.queryComponent().grabFocus(), "cannot refocus history table" + click(controls["Copy to clipboard"]) + assert request(history) == {"action": "copy"} + copied = subprocess.check_output(["xclip", "-selection", "clipboard", "-o"], text=True) + assert copied == "Newest speech", copied + click(controls["Remove from history"]) + removed = request(history) + assert removed == {"action": "remove", "selection": "Newest speech"}, removed + send(history, {"items": ["Older speech", "Another line"]}) + wait_for(lambda: table.queryTable().nRows == 2, "removal did not refresh the list") + click(controls["Remove from history"]) + assert request(history)["selection"] == "Older speech" + send(history, {"items": ["Another line"]}) + wait_for(lambda: table.queryTable().nRows == 1, "second removal did not refresh the list") + click(controls["Remove from history"]) + assert request(history)["selection"] == "Another line" + send(history, {"items": []}) + wait_for(lambda: table.queryTable().nRows == 0, "removing the final item left a row") + click(controls["Close"]) + assert history.wait(timeout=5) == 0 + finally: + if history.poll() is None: + history.kill() + history.wait(timeout=5) + + monitor = open_helper("monitor") + try: + window = wait_for(lambda: window_named("Speech Monitor - Cthulhu"), "monitor window missing") + def monitor_text(): + for node in walk(window): + if node.name == "Speech monitor output": + return node.queryText().getText(0, -1) + return "" + send(monitor, {"append": "Live utterance"}) + wait_for(lambda: "Live utterance" in monitor_text(), "monitor text missing") + controls = {node.name: node for node in walk(window) if node.name} + click(controls["Clear"]) + wait_for(lambda: "Live utterance" not in monitor_text(), "monitor text was not cleared") + click(controls["Close"]) + assert monitor.wait(timeout=5) == 0 + finally: + if monitor.poll() is None: + monitor.kill() + monitor.wait(timeout=5) + print("PASS: speech history accessibility, copy, remove, and live monitor") + + +def main(): + if "--inside" in sys.argv: + inside() + return + read_fd, write_fd = os.pipe() + server = subprocess.Popen( + ["Xvfb", "-displayfd", str(write_fd), "-screen", "0", "1024x768x24", "-nolisten", "tcp"], + pass_fds=(write_fd,), stderr=subprocess.DEVNULL, + ) + os.close(write_fd) + try: + with os.fdopen(read_fd) as reader: + display = reader.readline().strip() + assert display, "Xvfb failed" + environment = dict(os.environ, DISPLAY=":" + display, GDK_BACKEND="x11", + GTK_MODULES="gail:atk-bridge", GIO_USE_VFS="local") + for key in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + environment.pop(key, None) + run_private_session( + ["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), "--inside"], + env=environment, check=True, timeout=60, + ) + finally: + server.terminate() + server.wait(timeout=5) + + +if __name__ == "__main__": + main() diff --git a/tests/native_tentacle_extensions.py b/tests/native_tentacle_extensions.py new file mode 100644 index 0000000..a30cce6 --- /dev/null +++ b/tests/native_tentacle_extensions.py @@ -0,0 +1,100 @@ +"""Private native controls for declarative Tentacle preference pages.""" +import copy +from native_x11 import wait_for + + +def probe_pages(): + return [{"Session": "private-probe", "Revision": 1, + "id": "probe", "title": "Extension probe", "command": "apply", "load": True, + "elements": [{"id": "text", "label": "Extension text", "kind": 2, + "required": True, "max_length": 32}, + {"id": "choice", "label": "Extension choice", "kind": 1, + "items": [{"id": "first", "label": "First choice"}, + {"id": "second", "label": "Second choice"}]}, + {"id": "enabled", "label": "Extension enabled", "kind": 3}], + "values": {"text": {"text": "Initial"}, "choice": {"selected": "first"}, + "enabled": {"checked": False}}}] + + +def check_page(pyatspi, process, window, nodes, walk, focus, key, request, send, initial): + def find(name, role=None): + return next(node for node in nodes if node.name == name and + (role is None or node.getRole() == role)) + + def focused(node): + return any(child.getState().contains(pyatspi.STATE_FOCUSED) for child in walk(node)) + + tabs = next(node for node in nodes if node.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + index = next(index for index, node in enumerate(tabs) if node.name == "Extension probe") + assert tabs.querySelection().selectChild(index) + text = find("Extension text", pyatspi.ROLE_TEXT) + choice = find("Extension choice", pyatspi.ROLE_COMBO_BOX) + enabled = find("Extension enabled", pyatspi.ROLE_CHECK_BOX) + cancelButton = find("Cancel", pyatspi.ROLE_PUSH_BUTTON) + assert text.queryText().getText(0, -1) == "Initial" + labels = [node for node in nodes if node.name == "Extension text" and + node.getRole() == pyatspi.ROLE_LABEL] + assert labels and any(relation.getRelationType() == pyatspi.RELATION_LABEL_FOR + for relation in labels[0].getRelationSet()), "missing label buddy" + status = find(initial["Message"]) + focus(text) + key("Tab") + key("Down") + # GTK focuses an internal toggle button that need not expose FOCUSED in + # AT-SPI. A keyboard selection change proves that Tab reached the combo. + wait_for(lambda: choice.querySelection().getSelectedChild(0).name == "Second choice", + "Tab did not reach the combo or Down did not change its value") + key("Tab") + wait_for(lambda: focused(enabled), "extension combo trapped Tab") + key("space") + key("shift+Tab") + key("Up") + wait_for(lambda: choice.querySelection().getSelectedChild(0).name == "First choice", + "Shift+Tab did not return to the combo") + key("space") + wait_for(lambda: any(node.getRole() == pyatspi.ROLE_MENU and + node.getState().contains(pyatspi.STATE_SHOWING) for node in walk(choice)), + "extension combo popup did not open from the keyboard") + key("End", "Return") + wait_for(lambda: choice.querySelection().getSelectedChild(0).name == "Second choice", + "popup selection was not accepted") + key("shift+Tab") + wait_for(lambda: focused(text), "extension combo trapped Shift+Tab") + key("ctrl+a") + key("e", "d", "i", "t") + wait_for(lambda: text.queryText().getText(0, -1) == "edit", "entry edit missing") + # A status refresh with unchanged revisions must preserve the active draft. + send({"ExtensionsOnly": True, "ExtensionPages": initial["ExtensionPages"]}) + wait_for(lambda: focused(text), "refresh changed focus") + assert text.queryText().getText(0, -1) == "edit" + focus(find("Apply", pyatspi.ROLE_PUSH_BUTTON)); key("space") + draft = request() + page = draft["ExtensionPages"][0] + assert page["Session"] == "private-probe" and page["Revision"] == 1 + assert page["Values"] == {"text": {"text": "edit"}, "choice": {"selected": "second"}, + "enabled": {"checked": True}}, page + send({"Accepted": False, "CanSave": True, "Message": "Probe rejected"}) + wait_for(lambda: status.name == "Probe rejected", "rejection missing") + assert text.queryText().getText(0, -1) == "edit", "rejection discarded draft" + focus(find("Apply", pyatspi.ROLE_PUSH_BUTTON)); key("space") + draft = request() + pages = copy.deepcopy(initial["ExtensionPages"]) + pages[0]["Revision"] = 2 + pages[0]["values"] = draft["ExtensionPages"][0]["Values"] + send({"Accepted": True, "CanSave": True, "Values": draft["Values"], + "ExtensionPages": pages, "Message": "Probe applied"}) + wait_for(lambda: status.name == "Probe applied", "apply response missing") + assert tabs.querySelection().getSelectedChild(0).name == "Extension probe", "Apply changed the selected tab" + nodes = list(walk(window)) + text = find("Extension text", pyatspi.ROLE_TEXT) + assert text.queryText().getText(0, -1) == "edit", "applied values not restored" + # Removing a focused page must leave the core controls usable. + focus(text) + send({"ExtensionsOnly": True, "ExtensionPages": []}) + wait_for(lambda: not any(node.name == "Extension probe" and + node.getRole() == pyatspi.ROLE_PAGE_TAB for node in tabs), + "revoked extension tab survived") + assert tabs.querySelection().getSelectedChild(0).name == "General", "removal did not return to a core page" + focus(cancelButton); key("space") + assert process.wait(timeout=5) == 0 + print("PASS: extension labels, entries, combos, checkboxes, Tab/Shift+Tab, draft retention, Apply rejection/acceptance and focused-page removal", flush=True) diff --git a/tests/native_tentacle_settings.py b/tests/native_tentacle_settings.py new file mode 100644 index 0000000..190bd0d --- /dev/null +++ b/tests/native_tentacle_settings.py @@ -0,0 +1,47 @@ +"""Focused private GTK/AT-SPI checks for Tentacle settings and shortcut labels.""" +from native_x11 import wait_for + + +def check_page(pyatspi, window, nodes, named, walk, focus, key, request, send, initial): + tabs = next(n for n in nodes if n.getRole() == pyatspi.ROLE_PAGE_TAB_LIST) + index = next(i for i, n in enumerate(tabs) if n.name == "Tentacles") + assert tabs.querySelection().selectChild(index) + wait_for(lambda: tabs[index].getState().contains(pyatspi.STATE_SELECTED), "Tentacles page missing") + tree = next(n for n in nodes if n.name == "Tentacles" and + n.getRole() in (pyatspi.ROLE_TABLE, pyatspi.ROLE_TREE_TABLE)) + focus(tree) + key("Home") + shortcut = "Desktop: Cthulhu+Ctrl+Shift+W (Probe menu)" + wait_for(lambda: any(n.name == shortcut for n in walk(tree)), "acknowledged shortcut missing") + settings = named("Settings") + status = named(initial["Message"]) + wait_for(lambda: settings.getState().contains(pyatspi.STATE_SENSITIVE), "Settings is disabled") + focus(settings) + key("Tab") + wait_for(lambda: named("Retry").getState().contains(pyatspi.STATE_FOCUSED), "Tab trapped after Settings") + key("shift+Tab") + wait_for(lambda: settings.getState().contains(pyatspi.STATE_FOCUSED), "Shift+Tab did not return to Settings") + key("Return") + sent = request() + assert sent["Tentacle"]["Action"] == "settings" and sent["Tentacle"]["ID"] == "probe", sent + send({"Accepted": False, "Message": "No settings for this tentacle."}) + wait_for(lambda: status.name == "No settings for this tentacle." and + status.getState().contains(pyatspi.STATE_FOCUSED), + "no-settings status missing") + focus(settings) + key("Return") + assert request()["Tentacle"]["Action"] == "settings" + send({"Accepted": True}) + wait_for(lambda: settings.getState().contains(pyatspi.STATE_FOCUSED), "settings response moved focus") + # A following refresh response must retain the selected tentacle and controls. + focus(named("Refresh status")) + key("Return") + assert request()["Tentacle"]["Action"] == "list" + send({"Accepted": True, "Tentacles": initial["Tentacles"], "Message": "Tentacle status."}) + wait_for(lambda: status.name == "Tentacle status.", "refresh response missing") + focus(settings) + key("Return") + assert request()["Tentacle"]["ID"] == "probe" + send({"Accepted": False, "Message": "No settings for this tentacle."}) + wait_for(lambda: status.name == "No settings for this tentacle.", "status missing") + print("PASS: Settings request, no-settings status, shortcut label, Tab/Shift+Tab and selected-row retention", flush=True) diff --git a/tests/native_terminal.py b/tests/native_terminal.py new file mode 100644 index 0000000..0af789e --- /dev/null +++ b/tests/native_terminal.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python3 +"""Real shell/VTE/reader regression with private X11, AT-SPI and recorded SSIP.""" +import json +import os +from pathlib import Path +import subprocess +import sys +import tempfile + +sys.dont_write_bytecode = True +from native_echo_preview import PreviewSpeechServer +from native_x11 import wait_for +from native_test_session import run_private_session + +TITLE = "Terminal scrolling probe" +PROMPT = "Username@Host> " + + +def run_fixture(): + import gi + gi.require_version("Gtk", "3.0") + gi.require_version("Vte", "2.91") + from gi.repository import GLib, Gtk, Vte + + window = Gtk.Window(title=TITLE) + window.set_default_size(600, 220) + terminal = Vte.Terminal() + terminal.set_scrollback_lines(0) + window.add(terminal) + window.connect("destroy", Gtk.main_quit) + window.show_all() + terminal.grab_focus() + childEnv = [f"HOME={os.environ['HOME']}", "PATH=/usr/bin:/bin", "TERM=xterm", + "LC_ALL=C.UTF-8", "HISTFILE=/dev/null", "PS1=" + PROMPT, "PS2=Continue> "] + terminal.spawn_async(Vte.PtyFlags.DEFAULT, os.environ["HOME"], + ["/bin/bash", "--noprofile", "--norc"], childEnv, + GLib.SpawnFlags.DEFAULT, None, None, -1, None, None, None) + Gtk.main() + + +def run_inside(): + import pyatspi + directory = Path(tempfile.mkdtemp(prefix="cthulhu-terminal-runtime-")) + print(f"Evidence: {directory}", flush=True) + server = PreviewSpeechServer(directory / "speech.sock") + config = directory / "settings.toml" + config.write_text('''schema-version = 2 +active-profile = "default" +[profiles.default.speech] +output-module = "main" +[profiles.default.braille] +enabled = false +[profiles.default.sound] +enabled = false +[profiles.default.key-echo] +enabled = false +''') + wmConfig = directory / "i3.config" + wmConfig.write_text(f"font pango:monospace 10\nipc-socket {directory / 'i3.sock'}\n" + f'for_window [title="^{TITLE}$"] floating enable\n') + logPath = directory / "reader.log" + processes = [] + report = {} + + def key(chord): + subprocess.run(["xdotool", "key", "--clearmodifiers", chord], check=True) + + def type_text(text): + offset = len(logs()) + subprocess.run(["xdotool", "type", "--clearmodifiers", "--delay", "40", "--", text], check=True) + # Wait for the reader to receive VTE's final character event before + # sending another edit; otherwise VTE can merge both redraws. + wait_for(lambda: any(row.get("message") == "received accessibility event" + and row.get("type") == "object:text-caret-moved" + and row.get("native_caret_offset") == terminal.queryText().caretOffset + for row in logs()[offset:]), "typed text did not reach the reader") + + def logs(): + result = [] + for line in logPath.read_text().splitlines(): + try: + result.append(json.loads(line)) + except json.JSONDecodeError: + pass + return result + + def settle(): + wait_for(lambda: server.snapshot() and server.snapshot()[-1]["finished"], + "last speech request did not complete") + + try: + processes.append(subprocess.Popen(["i3", "-c", str(wmConfig)], + stdout=subprocess.DEVNULL, stderr=(directory / "wm.log").open("w"))) + wait_for(lambda: "0x" in subprocess.check_output( + ["xprop", "-root", "_NET_SUPPORTING_WM_CHECK"], text=True), "private WM missing") + processes.append(subprocess.Popen([ + os.environ["CTHULHU_BINARY"], "--config", str(config), "--no-tentacles", + "--speech-socket", str(directory / "speech.sock"), "--debug-file", str(logPath)], + stdout=subprocess.DEVNULL, stderr=(directory / "reader-stderr.log").open("w"))) + wait_for(lambda: logPath.exists() and "listening for focus events" in logPath.read_text(), + "private reader did not start") + processes.append(subprocess.Popen([sys.executable, __file__, "--fixture"], + stdout=subprocess.DEVNULL, stderr=(directory / "fixture.log").open("w"))) + + def find_terminal(): + for application in pyatspi.Registry.getDesktop(0): + for window in application: + if window and window.name == TITLE: + return next((child for child in window if child and child.getRoleName() == "terminal"), None) + + terminal = wait_for(find_terminal, "terminal fixture missing") + text = terminal.queryText() + wait_for(lambda: PROMPT in text.getText(0, -1), "shell prompt missing") + windowId = subprocess.check_output( + ["xdotool", "search", "--onlyvisible", "--name", "^" + TITLE + "$"], text=True).splitlines()[0] + subprocess.run(["xdotool", "windowactivate", "--sync", windowId], check=True) + settle() + logOffset = len(logs()) + speechOffset = len(server.snapshot()) + for row in range(16): + output = f"Output{row:02d}" + type_text("echo " + output) + key("Return") + wait_for(lambda: any(output in item["text"] for item in server.snapshot()[speechOffset:]), + f"command output {output} was not spoken") + wait_for(lambda: text.getText(0, -1).rstrip().endswith(PROMPT.rstrip()), "prompt did not return") + settle() + scrollLogs = logs()[logOffset:] + replay = [row["utterance"] for row in scrollLogs + if row.get("message") == "delivering accessible presentation" + and row.get("cause") == "object:text-changed:delete" + and "Username@Host>" in row.get("utterance", "")] + recorded = [row["text"] for row in server.snapshot()[speechOffset:]] + ignored = sum(row.get("message") == "skipped terminal scrollback deletion" for row in scrollLogs) + report.update(replayed_prompts=replay, ignored_scroll_deletions=ignored) + if "--expect-replay" in sys.argv: + assert replay and any(value in recorded for value in replay), (replay, recorded) + print(f"CONFIRMED: X11 sent {len(replay)} old prompt deletions to SSIP", flush=True) + else: + assert not replay, replay + assert ignored > 0, "fixture did not exercise scroll deletions" + print(f"PASS: {ignored} scroll deletions suppressed; all 16 command outputs reached SSIP", flush=True) + + def check_edit(chord, expected): + offset = len(server.snapshot()) + key(chord) + wait_for(lambda: any(row["text"] == expected for row in server.snapshot()[offset:]), + f"{chord} did not speak {expected!r}") + settle() + report[chord] = [row["text"] for row in server.snapshot()[offset:]] + + type_text("abcd") + check_edit("BackSpace", "d") + check_edit("ctrl+w", "abc") + type_text("abcd") + check_edit("Left", "d") + check_edit("Delete", "d") + wait_for(lambda: text.getText(0, -1).rstrip().endswith(PROMPT + "abc"), "Delete did not remove d") + offset = len(server.snapshot()) + type_text("Z") + key("Return") + wait_for(lambda: any("abcZ" in row["text"] for row in server.snapshot()[offset:]), + "editing command did not reach shell") + settle() + report["editing_command"] = [row["text"] for row in server.snapshot()[offset:]] + # History and flat review must still announce terminal content. + check_edit("Up", "abcZ") + key("ctrl+u") + check_edit("KP_Up", "Username@Host>") + print("PASS: Backspace, Ctrl+W, Left, Delete, history and flat review", flush=True) + finally: + (directory / "speech.json").write_text(json.dumps(server.snapshot(), indent=2)) + (directory / "report.json").write_text(json.dumps(report, indent=2)) + for process in reversed(processes): + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + process.kill() + process.wait() + server.close() + + +if __name__ == "__main__": + if "--fixture" in sys.argv: + run_fixture() + elif "--inside" in sys.argv: + run_inside() + else: + with tempfile.TemporaryDirectory(prefix="cthulhu-terminal-home-") as temporary: + environment = dict(os.environ, HOME=temporary, XDG_CONFIG_HOME=temporary, + XDG_DATA_HOME=temporary, XDG_CACHE_HOME=temporary, + XDG_SESSION_TYPE="x11", GDK_BACKEND="x11", + GTK_MODULES="gail:atk-bridge", GIO_USE_VFS="local") + for name in ("DISPLAY", "WAYLAND_DISPLAY", "DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS"): + environment.pop(name, None) + run_private_session(["xvfb-run", "-a", "dbus-run-session", "--", sys.executable, + __file__, "--inside", *sys.argv[1:]], env=environment, check=True, timeout=100) diff --git a/tests/native_test_session.py b/tests/native_test_session.py new file mode 100644 index 0000000..9999044 --- /dev/null +++ b/tests/native_test_session.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# Copyright (c) 2026 Storm Dragon +# Authors: Storm Dragon, Angus Kola +# SPDX-License-Identifier: GPL-3.0-or-later +"""Launch native tests with disposable runtime sockets and private D-Bus.""" +import os +import subprocess +import sys +import tempfile + + +def run_private_session(command, *, env, **kwargs): + """Keep activated services away from the desktop's runtime sockets.""" + if not command or command[0] not in ("dbus-run-session", "xvfb-run"): + raise ValueError("Start the private session with xvfb-run or dbus-run-session") + if "dbus-run-session" not in command: + raise ValueError("A private session requires dbus-run-session") + if "xvfb-run" in command and command.index("xvfb-run") > command.index("dbus-run-session"): + raise ValueError("Start Xvfb before D-Bus so activated services inherit the private display") + + # Keep this path short: AT-SPI falls back from named sockets if its + # generated socket path is 100 bytes or longer. + with tempfile.TemporaryDirectory(prefix="cth-run-", dir="/tmp") as runtimeDir: + sessionEnv = dict(env, XDG_RUNTIME_DIR=runtimeDir) + for name in ("DBUS_SESSION_BUS_ADDRESS", "DBUS_STARTER_ADDRESS", "DBUS_STARTER_BUS_TYPE", + "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + sessionEnv.pop(name, None) + return subprocess.run(command, env=sessionEnv, **kwargs) + + +def main(): + if len(sys.argv) < 2: + sys.exit("Usage: native_test_session.py COMMAND [ARG ...]") + result = run_private_session( + ["xvfb-run", "-a", "dbus-run-session", "--", *sys.argv[1:]], env=os.environ) + return result.returncode + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/native_thunderbird.py b/tests/native_thunderbird.py new file mode 100644 index 0000000..786c5e8 --- /dev/null +++ b/tests/native_thunderbird.py @@ -0,0 +1,382 @@ +#!/usr/bin/env python3 +"""Local Thunderbird folders, message lists and composition with a private reader.""" +import argparse +from email.message import EmailMessage +import json +import os +from pathlib import Path +import shutil +import subprocess +import sys +import tempfile +import time + +sys.dont_write_bytecode = True +from native_echo_preview import PreviewSpeechServer +from native_mozilla import walk, write_profile +from native_x11 import wait_for +from native_test_session import run_private_session + + +SUBJECTS = ["First test message", "Second test message"] +APPLICATIONS = ("thunderbird", "org.mozilla.thunderbird", "xdg-desktop-portal-gtk") + + +def seed_mailbox(profile, html): + write_profile(profile, "thunderbird") + with (profile / "user.js").open("a") as stream: + stream.write(f'user_pref("mail.identity.id1.compose_html", {str(html).lower()});\n') + stream.write('user_pref("mailnews.default_sort_order", 1);\n') + stream.write('user_pref("mailnews.default_view_flags", 0);\n') + stream.write('user_pref("mail.openMessageBehavior", 2);\n') + stream.write('user_pref("mail.forward_message_mode", 2);\n') + for folder, subjects in {"Inbox": SUBJECTS, "Archive": ["Archived test message"]}.items(): + messages = [] + for index, subject in enumerate(subjects): + message = EmailMessage() + message["From"] = "Sender " + message["To"] = "Username " + message["Cc"] = "Other Recipient " + message["Subject"] = subject + message["Date"] = f"Sat, 17 Oct 2026 12:0{index}:00 +0000" + message["Message-ID"] = f"<{folder}-{index}@example.invalid>" + message.set_content(f"Body of {subject}.\n") + if folder == "Inbox" and index == 0: + message.add_attachment("Synthetic attachment contents.\n", subtype="plain", + filename="test-attachment.txt") + messages.append("From sender@example.invalid Sat Oct 17 12:00:00 2026\n" + + message.as_string() + "\n") + (profile / "Mail" / "Local Folders" / folder).write_text("".join(messages)) + + +def run_inside(html): + import pyatspi + from gi.repository import GLib + directory = Path(os.environ["CTHULHU_THUNDERBIRD_EVIDENCE"]) + executable = shutil.which("thunderbird") + if not executable: + raise RuntimeError("Thunderbird executable missing") + profile = directory / "profile" + seed_mailbox(profile, html) + config = directory / "settings.toml" + config.write_text('''schema-version = 2 +active-profile = "default" +[profiles.default.speech] +output-module = "main" +[profiles.default.braille] +enabled = false +[profiles.default.sound] +enabled = false +[profiles.default.key-echo] +enabled = true +''') + wmConfig = directory / "i3.config" + wmConfig.write_text(f"font pango:monospace 10\nipc-socket {directory / 'i3.sock'}\n") + server = PreviewSpeechServer(directory / "speech.sock") + processes, report = [], [] + logPath = directory / "reader.log" + + def key(chord): + subprocess.run(["xdotool", "key", "--clearmodifiers", chord], check=True) + + def type_text(text): + subprocess.run(["xdotool", "type", "--clearmodifiers", "--delay", "35", "--", text], check=True) + + def find_node(role, name=None, focused=False): + for app in pyatspi.Registry.getDesktop(0): + try: + if app.name.lower() not in APPLICATIONS: + continue + for node in walk(app): + if (node.getRoleName() == role and (name is None or name in node.name) + and node.getState().contains(pyatspi.STATE_SHOWING) + and (not focused or node.getState().contains(pyatspi.STATE_FOCUSED))): + return node + except GLib.Error: + # A closing portal dialog can retire a child during traversal. + # The caller's bounded wait retries against the current tree. + continue + + def expect_focus(role, name=None): + return wait_for(lambda: find_node(role, name, focused=True), + f"native focus missing: {role} {name!r}", timeout=8) + + def check(action, operation, expected, role=None, name=None, exact=False, selected=False): + offset = len(server.snapshot()) + operation() + node = expect_focus(role, name) if role else None + wait_for(lambda: any((expected == row["text"] if exact else expected in row["text"]) + for row in server.snapshot()[offset:]), + f"{action}: missing speech {expected!r}", timeout=8) + wait_for(lambda: server.snapshot()[-1]["finished"], f"{action}: speech did not settle") + rows = server.snapshot()[offset:] + assert not any("Could not" in row["text"] for row in rows), (action, rows) + if node and role in ("tree item", "list item"): + if selected or role == "tree item": + assert node.getState().contains(pyatspi.STATE_SELECTED), (action, "native selection missing") + assert any(row["text"] == role for row in rows), (action, "spoken row role missing", rows) + report.append({"action": action, "expected": expected, + "focus": {"role": node.getRoleName(), "name": node.name} if node else None, + "speech": rows}) + print(f"PASS: {action}", flush=True) + return node + + def read_text(node): + # HTML editors expose their paragraphs as children; plain text can be + # exposed directly on the document. Ignore embedded-object placeholders. + try: + text = node.queryText().getText(0, -1).replace("\ufffc", "") + except NotImplementedError: + text = "" + if text.strip(): + return text + return "\n".join(read_text(child) for child in node) + + def selected_text(node): + for child in walk(node): + try: + text = child.queryText() + if text.getNSelections(): + start, end = text.getSelection(0) + selected = text.getText(start, end).replace("\ufffc", "") + if selected.strip(): + return selected + except NotImplementedError: + continue + return "" + + def selected_messages(): + return [subject for subject in SUBJECTS + if (node := find_node("list item", subject)) is not None + and node.getState().contains(pyatspi.STATE_SELECTED)] + + def discard_composer(): + key("ctrl+w") + discard = wait_for(lambda: find_node("button", "Discard changes"), + "discard confirmation missing") + check("focus discard button", lambda: discard.queryComponent().grabFocus(), + "Discard changes", "button", "Discard changes") + check("discard unsent message", lambda: key("Return"), SUBJECTS[1], + "list item", SUBJECTS[1], selected=True) + + try: + processes.append(subprocess.Popen(["i3", "-c", str(wmConfig)], + stdout=subprocess.DEVNULL, stderr=(directory / "wm.log").open("w"))) + wait_for(lambda: "0x" in subprocess.check_output( + ["xprop", "-root", "_NET_SUPPORTING_WM_CHECK"], text=True), "private WM missing") + processes.append(subprocess.Popen([ + os.environ["CTHULHU_BINARY"], "--config", str(config), "--no-tentacles", + "--speech-socket", str(directory / "speech.sock"), "--debug-file", str(logPath)], + stdout=subprocess.DEVNULL, stderr=(directory / "reader-stderr.log").open("w"))) + wait_for(lambda: logPath.exists() and "remote D-Bus service ready" in logPath.read_text(), + "private reader missing") + processes.append(subprocess.Popen([ + executable, "--no-remote", "--profile", str(profile)], + env=dict(os.environ, MOZ_ACCESSIBILITY_ENABLED="1"), + stdout=subprocess.DEVNULL, stderr=(directory / "application.log").open("w"))) + root = wait_for(lambda: find_node("tree item", "Local Folders"), "folder tree missing", timeout=25) + window = subprocess.check_output([ + "xdotool", "search", "--onlyvisible", "--name", "Local Folders - Mozilla Thunderbird"], + text=True).splitlines()[0] + subprocess.run(["xdotool", "windowactivate", "--sync", window], check=True) + check("focus folder tree", lambda: root.queryComponent().grabFocus(), + "Local Folders", "tree item", "Local Folders") + key("Right") + check("next folder", lambda: key("Down"), "Inbox", "tree item", "Inbox") + check("last folder", lambda: key("End"), "Archive", "tree item", "Archive") + check("first folder", lambda: key("Home"), "Local Folders", "tree item", "Local Folders") + check("return to Inbox", lambda: key("Down"), "Inbox", "tree item", "Inbox") + check("folder to messages", lambda: key("F6"), SUBJECTS[0], "list item", SUBJECTS[0]) + check("next message", lambda: key("Down"), SUBJECTS[1], "list item", SUBJECTS[1], selected=True) + check("previous message", lambda: key("Up"), SUBJECTS[0], "list item", SUBJECTS[0], selected=True) + check("extend message selection", lambda: key("shift+Down"), SUBJECTS[1], + "list item", SUBJECTS[1], selected=True) + wait_for(lambda: selected_messages() == SUBJECTS, "two-message selection missing") + report[-1]["selectedMessages"] = selected_messages() + check("shrink message selection", lambda: key("shift+Up"), SUBJECTS[0], + "list item", SUBJECTS[0], selected=True) + wait_for(lambda: selected_messages() == SUBJECTS[:1], "selection did not shrink") + report[-1]["selectedMessages"] = selected_messages() + check("move without extending selection", lambda: key("ctrl+Down"), SUBJECTS[1], + "list item", SUBJECTS[1]) + wait_for(lambda: selected_messages() == SUBJECTS[:1], "Ctrl+Down changed selection") + check("add focused message to selection", lambda: key("ctrl+space"), "selected", exact=True) + wait_for(lambda: selected_messages() == SUBJECTS, "Ctrl+Space did not add message") + report[-1]["selectedMessages"] = selected_messages() + check("remove focused message from selection", lambda: key("ctrl+space"), "not selected", exact=True) + wait_for(lambda: selected_messages() == SUBJECTS[:1], "Ctrl+Space did not remove message") + report[-1]["selectedMessages"] = selected_messages() + check("return to first selected message", lambda: key("Up"), SUBJECTS[0], + "list item", SUBJECTS[0], selected=True) + check("messages to folders", lambda: key("shift+F6"), "Inbox", "tree item", "Inbox") + check("folders to retained message", lambda: key("F6"), SUBJECTS[0], "list item", SUBJECTS[0]) + + check("open selected message", lambda: key("Return"), SUBJECTS[0]) + check("read opened message", lambda: key("ctrl+Home"), f"Body of {SUBJECTS[0]}.") + check("focus received attachment bar", lambda: key("Tab"), + "test-attachment.txt", "button", "1 attachment") + check("expand received attachments", lambda: key("Return"), "test-attachment.txt", + "list item", "test-attachment", selected=True) + check("received attachment menu", lambda: key("shift+F10"), "menu", "menu") + check("attachment open menu item", lambda: key("Down"), "Open", "menu item", "Open") + check("attachment save menu item", lambda: key("Down"), "Save As", "menu item", "Save As") + check("open attachment save dialog", lambda: key("Return"), "Save Attachment") + key("ctrl+l") + location = expect_focus("text") + savedAttachment = directory / "saved-attachment.txt" + key("ctrl+a") + type_text(str(savedAttachment)) + wait_for(lambda: str(savedAttachment) in location.queryText().getText(0, -1), + "save attachment location missing") + check("save received attachment", lambda: key("Return"), "test-attachment", + "list item", "test-attachment", selected=True) + wait_for(savedAttachment.exists, "attachment was not saved") + assert savedAttachment.read_text().strip() == "Synthetic attachment contents." + check("return to message list", lambda: key("ctrl+w"), SUBJECTS[0], + "list item", SUBJECTS[0], selected=True) + check("next message after return", lambda: key("Down"), SUBJECTS[1], + "list item", SUBJECTS[1], selected=True) + + for action, chord, prefix in (("reply", "ctrl+r", "Re: "), + ("reply all", "ctrl+shift+r", "Re: "), + ("forward", "ctrl+l", "Fwd: ")): + replying = action != "forward" + check(f"open {action}", lambda: key(chord), "Message body" if replying else "To", + "document web" if replying else "entry", + "Message body" if replying else "To") + subject = find_node("entry", "Subject") + assert subject.queryText().getText(0, -1) == prefix + SUBJECTS[1], (action, "subject") + report[-1]["subject"] = subject.queryText().getText(0, -1) + if replying: + assert find_node("section", "Sender : press Enter"), (action, "recipient") + if action == "reply all": + assert find_node("section", "Other Recipient : press Enter"), (action, "Cc") + if action == "forward": + type_text("recipient@example.invalid") + check("commit forward recipient", lambda: key("Tab"), "recipient@example.invalid", + "entry", "To") + check("forward recipient to subject", lambda: key("Tab"), "Subject", "entry", "Subject") + check("forward subject to body", lambda: key("Tab"), "Message body", + "document web", "Message body") + body = expect_focus("document web", "Message body") + wait_for(lambda: f"Body of {SUBJECTS[1]}." in read_text(body), f"{action}: quoted body missing") + originalText = read_text(body) + check(f"{action} character echo", lambda: key("x"), "x", exact=True) + wait_for(lambda: read_text(body) != originalText, f"{action}: typed text missing") + discard_composer() + + check("open composer", lambda: key("ctrl+m"), "To", "entry", "To") + recipient = expect_focus("entry", "To") + type_text("recipient@example.invalid") + wait_for(lambda: recipient.queryText().getText(0, -1) == "recipient@example.invalid", + "recipient text did not reach Thunderbird") + check("commit recipient", lambda: key("Tab"), "recipient@example.invalid", "entry", "To") + subject = check("recipient to subject", lambda: key("Tab"), "Subject", "entry", "Subject") + offset = len(server.snapshot()) + type_text("Draft subject") + wait_for(lambda: subject.queryText().getText(0, -1) == "Draft subject", "subject typing missing") + # Let the title coalescer and SSIP recorder drain after the last key. + # The check must include the final title, not just the typing interval. + time.sleep(0.4) + rows = server.snapshot()[offset:] + assert any(row["text"] == "D" for row in rows), ("subject character echo missing", rows) + assert not any(row["text"].startswith("Write:") for row in rows), ("subject title echo", rows) + report.append({"action": "subject typing without title echo", "speech": rows}) + print("PASS: subject typing without title echo", flush=True) + offset = len(server.snapshot()) + check("subject character deletion", lambda: key("BackSpace"), "t", exact=True) + wait_for(lambda: subject.queryText().getText(0, -1) == "Draft subjec", "subject deletion missing") + time.sleep(0.4) + rows = server.snapshot()[offset:] + assert not any(row["text"].startswith("Write:") for row in rows), ("subject deletion title echo", rows) + type_text("t") + check("subject to body", lambda: key("Tab"), "Message body", "document web", "Message body") + body = expect_focus("document web") + assert body.getState().contains(pyatspi.STATE_EDITABLE), "body is not editable" + check("body character echo", lambda: key("h"), "h", exact=True) + check("body character deletion", lambda: key("BackSpace"), "h", exact=True) + wait_for(lambda: not read_text(body).strip(), "body character deletion missing") + type_text("Draft first line.") + key("Return") + type_text("Draft second line.") + wait_for(lambda: "Draft first line." in read_text(body) and "Draft second line." in read_text(body), + "body text did not reach Thunderbird") + check("body first line", lambda: key("ctrl+Home"), "Draft first line.") + check("body next line", lambda: key("Down"), "Draft second line.") + check("select body word", lambda: (key("Home"), key("ctrl+shift+Right")), "Draft selected", exact=True) + wait_for(lambda: selected_text(body).strip() == "Draft", "native body word selection missing") + check("delete selected word", lambda: key("BackSpace"), "Draft") + wait_for(lambda: "Draft second line." not in read_text(body) and "second line." in read_text(body), + "body selection/deletion did not reach Thunderbird") + check("body back to subject", lambda: key("shift+Tab"), "Subject", "entry", "Subject") + check("subject back to body", lambda: key("Tab"), "Message body", "document web", "Message body") + attachment = directory / "outgoing-attachment.txt" + attachment.write_text("Unsent synthetic attachment.\n") + check("open attachment picker", lambda: key("ctrl+shift+a"), "Attach File") + key("ctrl+l") + location = expect_focus("text") + type_text(str(attachment)) + wait_for(lambda: str(attachment) in location.queryText().getText(0, -1), + "attachment picker location missing") + check("attach local file", lambda: key("Return"), attachment.name, + "list item", attachment.stem, selected=True) + check("clear attachment selection", lambda: key("Escape"), "not selected", exact=True) + wait_for(lambda: not find_node("list item", attachment.stem).getState().contains(pyatspi.STATE_SELECTED), + "attachment selection did not clear") + check("attachment back to body", lambda: key("Escape"), "Message body", + "document web", "Message body") + # No send command is used. Termination below leaves the unsent editor + # in this disposable profile without interacting with a real mailbox. + print(f"PASS: Thunderbird {'HTML' if html else 'plain-text'} local mail workflow", flush=True) + finally: + tree = [] + try: + try: + for app in pyatspi.Registry.getDesktop(0): + if app.name.lower() in APPLICATIONS: + for node in walk(app): + tree.append({"role": node.getRoleName(), "name": node.name, + "showing": node.getState().contains(pyatspi.STATE_SHOWING), + "focused": node.getState().contains(pyatspi.STATE_FOCUSED), + "selected": node.getState().contains(pyatspi.STATE_SELECTED)}) + except Exception as error: + tree.append({"error": str(error)}) + (directory / "tree.json").write_text(json.dumps(tree, indent=2)) + (directory / "report.json").write_text(json.dumps(report, indent=2)) + (directory / "speech.json").write_text(json.dumps(server.snapshot(), indent=2)) + finally: + for process in reversed(processes): + process.terminate() + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + process.kill() + process.wait(timeout=5) + server.close() + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--format", choices=("html", "plain", "both"), default="both") + parser.add_argument("--inside", action="store_true", help=argparse.SUPPRESS) + args = parser.parse_args() + if not os.environ.get("CTHULHU_BINARY"): + parser.error("Set CTHULHU_BINARY to a freshly built reader") + if args.inside: + run_inside(args.format == "html") + return + formats = ("html", "plain") if args.format == "both" else (args.format,) + for composeFormat in formats: + directory = Path(tempfile.mkdtemp(prefix=f"cthulhu-thunderbird-{composeFormat}-")) + print(f"Thunderbird {composeFormat} evidence: {directory}", flush=True) + environment = dict(os.environ, XDG_SESSION_TYPE="x11", CTHULHU_THUNDERBIRD_EVIDENCE=str(directory)) + for name in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + environment.pop(name, None) + with (directory / "session.log").open("w") as log: + run_private_session(["xvfb-run", "-a", "-s", "-screen 0 1280x900x24", "dbus-run-session", "--", + sys.executable, str(Path(__file__).resolve()), "--format", composeFormat, "--inside"], + env=environment, stderr=log, check=True, timeout=120) + + +if __name__ == "__main__": + main() diff --git a/tests/native_webscripts.py b/tests/native_webscripts.py new file mode 100644 index 0000000..75ff024 --- /dev/null +++ b/tests/native_webscripts.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +"""Verify notification metadata on a private X server and accessibility bus.""" +import os +from pathlib import Path +import subprocess +import sys + +from native_test_session import run_private_session + + +def main() -> None: + if sys.argv[1:] == ["--inside"]: + environment = dict(os.environ, CTHULHU_NATIVE_WEBSCRIPTS="1") + environment.setdefault("GOCACHE", "/tmp/cthulhu-cache") + subprocess.run( + ["go", "test", "./internal/atspi", "-run", "^TestNativeWebScriptNotificationCapture$", + "-count=1", "-v", "-timeout=30s"], + cwd=Path(__file__).resolve().parents[1], env=environment, check=True, timeout=35, + ) + return + readFd, writeFd = os.pipe() + server = subprocess.Popen( + ["Xvfb", "-displayfd", str(writeFd), "-screen", "0", "800x600x24", "-nolisten", "tcp"], + pass_fds=(writeFd,), stderr=subprocess.DEVNULL, + ) + os.close(writeFd) + try: + with os.fdopen(readFd) as reader: + display = reader.readline().strip() + if not display: + raise RuntimeError("Xvfb failed to start") + environment = dict(os.environ, DISPLAY=":" + display, XDG_SESSION_TYPE="x11") + for key in ("DBUS_SESSION_BUS_ADDRESS", "AT_SPI_BUS_ADDRESS", "WAYLAND_DISPLAY"): + environment.pop(key, None) + run_private_session( + ["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), "--inside"], + env=environment, check=True, timeout=45, + ) + finally: + server.terminate() + server.wait(timeout=3) + + +if __name__ == "__main__": + main() diff --git a/tests/native_x11.py b/tests/native_x11.py new file mode 100644 index 0000000..38049e8 --- /dev/null +++ b/tests/native_x11.py @@ -0,0 +1,746 @@ +#!/usr/bin/env python3 +"""Isolated X11 command consumption and pass-through proof; never uses desktop DISPLAY.""" +import json +import os +import ctypes +from pathlib import Path +import subprocess +import sys +import tempfile +import time + +from native_test_session import run_private_session + + +def wait_for(check, message, timeout=15): + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + value = check() + if value: + return value + time.sleep(0.02) + raise RuntimeError(message) + + +def count_records(path, *needles): + return sum(all(needle in line for needle in needles) for line in path.read_text().splitlines()) + + +def press_physical_key(symbol): + # xdotool's keysym synthesis can toggle NumLock between press and release. + # XTest the physical keycode without synthesizing any modifier changes. + x11 = ctypes.CDLL('libX11.so.6') + xtst = ctypes.CDLL('libXtst.so.6') + x11.XOpenDisplay.argtypes = [ctypes.c_char_p] + x11.XOpenDisplay.restype = ctypes.c_void_p + x11.XKeysymToKeycode.argtypes = [ctypes.c_void_p, ctypes.c_ulong] + x11.XKeysymToKeycode.restype = ctypes.c_ubyte + x11.XSync.argtypes = [ctypes.c_void_p, ctypes.c_int] + x11.XCloseDisplay.argtypes = [ctypes.c_void_p] + xtst.XTestFakeKeyEvent.argtypes = [ctypes.c_void_p, ctypes.c_uint, ctypes.c_int, ctypes.c_ulong] + display = x11.XOpenDisplay(None) + if not display: + raise RuntimeError('private X11 display unavailable') + try: + code = x11.XKeysymToKeycode(display, symbol) + assert code, 'physical key missing from private keymap' + assert xtst.XTestFakeKeyEvent(display, code, 1, 0) + assert xtst.XTestFakeKeyEvent(display, code, 0, 0) + x11.XSync(display, 0) + finally: + x11.XCloseDisplay(display) + + +def set_active_window(window_id): + x11 = ctypes.CDLL('libX11.so.6') + x11.XOpenDisplay.argtypes = [ctypes.c_char_p] + x11.XOpenDisplay.restype = ctypes.c_void_p + x11.XDefaultRootWindow.argtypes = [ctypes.c_void_p] + x11.XDefaultRootWindow.restype = ctypes.c_ulong + x11.XInternAtom.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int] + x11.XInternAtom.restype = ctypes.c_ulong + x11.XChangeProperty.argtypes = [ + ctypes.c_void_p, + ctypes.c_ulong, + ctypes.c_ulong, + ctypes.c_ulong, + ctypes.c_int, + ctypes.c_int, + ctypes.c_void_p, + ctypes.c_int, + ] + x11.XSync.argtypes = [ctypes.c_void_p, ctypes.c_int] + x11.XCloseDisplay.argtypes = [ctypes.c_void_p] + display = x11.XOpenDisplay(None) + if not display: + raise RuntimeError('private X11 display unavailable') + try: + root = x11.XDefaultRootWindow(display) + property_atom = x11.XInternAtom(display, b'_NET_ACTIVE_WINDOW', False) + window_atom = x11.XInternAtom(display, b'WINDOW', False) + active_window = ctypes.c_ulong(window_id) + x11.XChangeProperty( + display, + root, + property_atom, + window_atom, + 32, + 0, + ctypes.byref(active_window), + 1, + ) + x11.XSync(display, 0) + finally: + x11.XCloseDisplay(display) + + +def set_window_class(window_id, instance_name, class_name): + x11 = ctypes.CDLL('libX11.so.6') + x11.XOpenDisplay.argtypes = [ctypes.c_char_p] + x11.XOpenDisplay.restype = ctypes.c_void_p + x11.XDefaultRootWindow.argtypes = [ctypes.c_void_p] + x11.XDefaultRootWindow.restype = ctypes.c_ulong + x11.XInternAtom.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int] + x11.XInternAtom.restype = ctypes.c_ulong + x11.XChangeProperty.argtypes = [ + ctypes.c_void_p, + ctypes.c_ulong, + ctypes.c_ulong, + ctypes.c_ulong, + ctypes.c_int, + ctypes.c_int, + ctypes.c_void_p, + ctypes.c_int, + ] + x11.XSync.argtypes = [ctypes.c_void_p, ctypes.c_int] + x11.XCloseDisplay.argtypes = [ctypes.c_void_p] + display = x11.XOpenDisplay(None) + if not display: + raise RuntimeError('private X11 display unavailable') + try: + window = ctypes.c_ulong(window_id) + property_atom = x11.XInternAtom(display, b'WM_CLASS', False) + string_atom = x11.XInternAtom(display, b'STRING', False) + class_data = ctypes.create_string_buffer(f'{instance_name}\0{class_name}\0'.encode()) + x11.XChangeProperty( + display, + window, + property_atom, + string_atom, + 8, + 0, + class_data, + len(class_data) - 1, + ) + x11.XSync(display, 0) + finally: + x11.XCloseDisplay(display) + + +def check_speech_mode_shortcut(log, events, modifier): + for modifier_first in (True, False): + before_s = events.read_text().count(', s)') + before_command = count_records(log, '"message":"keyboard command received"', + '"command":"cycle-speech-mode"') + subprocess.run(['xdotool', 'keydown', modifier, 'keydown', 's', 'keydown', 's'], check=True) + release_keys = [modifier, 's'] if modifier_first else ['s', modifier] + subprocess.run(['xdotool', 'keyup', release_keys[0], 'keyup', release_keys[1]], check=True) + wait_for(lambda: count_records(log, '"message":"keyboard command received"', + '"command":"cycle-speech-mode"') == before_command + 1, + 'speech mode shortcut did not dispatch once') + time.sleep(0.05) + assert events.read_text().count(', s)') == before_s, 'speech mode shortcut leaked S' + + +def run_inside(directory): + root = Path(directory) + config = root / "settings.toml" + config.write_text('[general]\nenableSpeech = false\nenableSound = false\nkeyboardLayout = 1\n') + speech_modes_only = os.environ.get('CTHULHU_NATIVE_SPEECH_MODES_ONLY') == '1' + if speech_modes_only: + config.write_text('[general]\nenableSpeech = false\nenableSound = false\nkeyboardLayout = 1\n' + 'cthulhuModifierKeys = ["Insert", "KP_Insert", "Caps_Lock"]\n') + log = root / "cthulhu.log" + events = root / "keys.log" + binary = Path(os.environ.get('CTHULHU_BINARY', str(Path(__file__).resolve().parents[1] / "cthulhu"))) + processes = [] + try: + with events.open("w") as output: + probe = subprocess.Popen(['stdbuf', '-oL', 'xev', '-name', 'CthulhuInputProbe', '-event', 'keyboard'], stdout=output, stderr=subprocess.DEVNULL) + processes.append(probe) + def find_window(): + result = subprocess.run(['xdotool', 'search', '--name', '^CthulhuInputProbe$'], capture_output=True, text=True) + return result.stdout.strip().splitlines()[0] if result.stdout.strip() else None + window = wait_for(find_window, 'probe window missing') + subprocess.run(['xdotool', 'windowfocus', window], check=True) + nativeTest = os.environ.get('CTHULHU_XRECORD_TEST') + if nativeTest: + subprocess.run([nativeTest, '-test.run', '^TestNative(ModifierPressRelease|CommandGrabSuspensionAndRestoration|BrowseKeyTransitions|DispatchBeforeRelease|CustomBindingsUpdateAndRelease|TentacleBindingsUpdateAndRelease|ModifierConfigurationUpdate|LockStatesAndShiftCapsLock|XTermHandoffKeepsKeypadReleased|SuspendedQueuedKey|LearnModeCapturesKeysAndRestoresCommands|SecureInputDropsKeysAndRestoresGrabs)$', '-test.timeout=40s'], env=dict(os.environ, CTHULHU_NATIVE_X11='1', CTHULHU_NATIVE_BROWSER='1'), check=True, timeout=45, cwd=Path(__file__).resolve().parents[1] / 'internal/platform/xorg') + if nativeTest and os.environ.get('CTHULHU_NATIVE_LISTENER_ONLY') == '1': + print('PASS: native command bindings, press/release ordering, browse transitions, suspension, custom updates, and grab rollback') + return + app = subprocess.Popen([str(binary), '--config', str(config), '--debug-file', str(log)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + processes.append(app) + def ready(): + if app.poll() is not None: + raise RuntimeError(log.read_text() if log.exists() else 'Cthulhu exited before logging') + return log.exists() and 'listening for focus events' in log.read_text() + wait_for(ready, 'Cthulhu startup timed out') + if speech_modes_only: + for layout in (1, 2): + for modifier in ('Insert', 'KP_Insert', 'Caps_Lock'): + check_speech_mode_shortcut(log, events, modifier) + before_s = events.read_text().count(', s)') + subprocess.run(['xdotool', 'key', 's'], check=True) + wait_for(lambda: events.read_text().count(', s)') == before_s + 2, + 'ordinary S stayed grabbed after speech mode shortcut') + before_save = count_records(log, '"message":"speech setting command received"', + '"command":"save-speech-settings"') + subprocess.run(['xdotool', 'keydown', 'Insert', 'keydown', 'Control_L', + 'keydown', 'Shift_L', 'key', 's', 'keyup', 'Shift_L', + 'keyup', 'Control_L', 'keyup', 'Insert'], check=True) + wait_for(lambda: count_records(log, '"message":"speech setting command received"', + '"command":"save-speech-settings"') == before_save + 1, + 'speech mode shortcut broke speech settings save') + subprocess.run(['xdotool', 'keydown', 'Insert', 'key', 'q', 'keyup', 'Insert'], check=True) + assert app.wait(timeout=5) == 0, log.read_text() + print(f'PASS: layout {layout} speech-mode shortcut, three modifiers, repeat, release orders, ' + 'ordinary S, speech settings save, and quit') + if layout == 1: + config.write_text('[general]\nenableSpeech = false\nenableSound = false\nkeyboardLayout = 2\n' + 'cthulhuModifierKeys = ["Insert", "KP_Insert", "Caps_Lock"]\n') + log = root / 'speech-mode-laptop.log' + app = subprocess.Popen([str(binary), '--config', str(config), '--debug-file', str(log)], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + processes.append(app) + wait_for(ready, 'laptop startup timed out') + return + selection_probe = subprocess.Popen([ + sys.executable, + str(Path(__file__).with_name('gtk_selection.py')), + ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + processes.append(selection_probe) + def find_selection_window(): + result = subprocess.run( + ['xdotool', 'search', '--name', '^Cthulhu Selection Probe$'], + capture_output=True, + text=True, + ) + return result.stdout.strip().splitlines()[0] if result.stdout.strip() else None + selection_window = wait_for(find_selection_window, 'selection probe window missing') + subprocess.run(['xdotool', 'windowfocus', selection_window], check=True) + try: + wait_for( + lambda: any( + '"message":"queued accessible presentation"' in line + and '"type":"object:selection-changed"' in line + for line in log.read_text().splitlines() + ), + 'focused GTK selection was not presented', + ) + except RuntimeError: + print(log.read_text(), file=sys.stderr) + raise + assert selection_probe.wait(timeout=5) == 0, 'GTK selection probe failed' + print('PASS: focused GTK selection resolved to its selected child') + + xterm = subprocess.Popen( + [ + 'xterm', + '-T', + 'Cthulhu XTerm Handoff', + '-e', + sys.executable, + '-c', + ( + 'import pathlib, sys, tty\n' + 'tty.setcbreak(sys.stdin)\n' + "while sys.stdin.read(1) != 'q':\n" + ' pass\n' + f"pathlib.Path({str(root / 'xterm-key.log')!r}).write_text('q')\n" + ), + ], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + processes.append(xterm) + def find_xterm(): + result = subprocess.run( + ['xdotool', 'search', '--onlyvisible', '--name', '^Cthulhu XTerm Handoff$'], + capture_output=True, + text=True, + ) + return result.stdout.strip().splitlines()[0] if result.stdout else None + xterm_window = wait_for(find_xterm, 'XTerm handoff window missing') + def focus_xterm(): + result = subprocess.run( + ['xdotool', 'windowfocus', '--sync', xterm_window], + capture_output=True, + text=True, + ) + return result.returncode == 0 + wait_for(focus_xterm, 'XTerm handoff window could not be focused') + set_active_window(int(xterm_window)) + wait_for(lambda: xterm.poll() is None, 'XTerm key-recording child exited before focus handoff') + wait_for( + lambda: 'suspended for XTerm focus handoff' in log.read_text(), + 'XTerm focus did not suspend Cthulhu', + ) + subprocess.run(['xdotool', 'keydown', 'Insert', 'key', 'q', 'keyup', 'Insert'], check=True) + xterm_key = root / 'xterm-key.log' + wait_for(lambda: xterm_key.exists(), 'Insert+Q did not reach the focused XTerm') + assert xterm_key.read_text() == 'q', 'XTerm received an unexpected key' + assert app.poll() is None, 'Cthulhu consumed Insert+Q while XTerm owned focus' + print('PASS: XTerm focus suspended Cthulhu and passed through Insert+Q') + + subprocess.run(['xdotool', 'windowfocus', '--sync', window], check=True) + set_active_window(int(window)) + before_unknown_q = events.read_text().count('keysym 0x71, q)') + subprocess.run(['xdotool', 'keydown', 'Insert', 'key', 'q', 'keyup', 'Insert'], check=True) + wait_for( + lambda: events.read_text().count('keysym 0x71, q)') == before_unknown_q + 2, + 'unknown active window restored Cthulhu command grabs', + ) + assert app.poll() is None, 'unknown active window stopped Cthulhu' + print('PASS: unknown active window remained suspended for Fenrir handoff') + + set_window_class( + int(window), + 'CthulhuInputProbe', + 'CthulhuInputProbe', + ) + subprocess.run(['xdotool', 'windowfocus', '--sync', window], check=True) + set_active_window(int(window)) + wait_for( + lambda: 'resumed after XTerm focus handoff' in log.read_text(), + 'leaving XTerm did not restore Cthulhu', + ) + assert app.poll() is None, 'Cthulhu exited while restoring command grabs' + subprocess.run(['xdotool', 'key', 'q', 'h', 'shift+h', 'b', 'x', 'l', 'Tab', 'Control_L', 'Shift_L'], check=True) + wait_for(lambda: 'keysym 0x71, q)' in events.read_text(), 'ordinary q was consumed') + assert app.poll() is None, 'ordinary typing quit Cthulhu' + before = events.read_text().count('keysym 0x71, q)') + assert before >= 2 and before % 2 == 0, ('ordinary q press/release imbalance', before) + + before_x = events.read_text().count('keysym 0x78, x)') + before_insert = events.read_text().count('keysym 0xff63, Insert)') + subprocess.run(['xdotool', 'keydown', 'Insert', 'keydown', 'x', 'keyup', 'Insert', 'keyup', 'x'], check=True) + wait_for(lambda: events.read_text().count('keysym 0x78, x)') == before_x + 2, 'unbound Insert+x did not reach application') + wait_for(lambda: events.read_text().count('keysym 0xff63, Insert)') == before_insert + 2, 'unbound Insert press/release was not balanced') + assert app.poll() is None, 'unbound Insert chord stopped Cthulhu' + + before_return = events.read_text().count('keysym 0xff0d, Return)') + before_insert = events.read_text().count('keysym 0xff63, Insert)') + subprocess.run(['xdotool', 'keydown', 'Insert', 'key', 'Return', 'keyup', 'Insert'], check=True) + wait_for(lambda: events.read_text().count('keysym 0xff0d, Return)') == before_return + 2, 'desktop Insert+Return did not reach application') + wait_for(lambda: events.read_text().count('keysym 0xff63, Insert)') == before_insert + 2, 'desktop Insert+Return was not balanced') + assert log.read_text().count('where am I command received') == 0, 'desktop Insert+Return incorrectly routed Where Am I' + + before_keypad_enter = events.read_text().count('keysym 0xff8d, KP_Enter)') + subprocess.run(['xdotool', 'key', 'KP_Enter'], check=True) + wait_for(lambda: log.read_text().count('where am I command received') == 1, 'desktop KP Enter did not route Where Am I') + time.sleep(0.05) + assert events.read_text().count('keysym 0xff8d, KP_Enter)') == before_keypad_enter, 'desktop Where Am I KP Enter leaked to application' + + subprocess.run(['xdotool', 'key', 'Num_Lock'], check=True) + subprocess.run(['xdotool', 'key', 'KP_Enter'], check=True) + wait_for(lambda: log.read_text().count('where am I command received') == 2, 'NumLock prevented desktop KP Enter Where Am I') + time.sleep(0.05) + assert events.read_text().count('keysym 0xff8d, KP_Enter)') == before_keypad_enter, 'NumLock desktop KP Enter leaked to application' + subprocess.run(['xdotool', 'key', 'Num_Lock'], check=True) + assert app.poll() is None, 'where am I command stopped Cthulhu' + + before_space = events.read_text().count('keysym 0x20, space)') + before_insert = events.read_text().count('keysym 0xff63, Insert)') + subprocess.run(['xdotool', 'keydown', 'Insert', 'keydown', 'space', 'keydown', 'space', 'keyup', 'Insert', 'keyup', 'space'], check=True) + wait_for(lambda: log.read_text().count('preferences command received') == 1, 'preferences command was not routed exactly once') + time.sleep(0.05) + assert events.read_text().count('keysym 0x20, space)') == before_space, 'preferences Space leaked to application' + assert events.read_text().count('keysym 0xff63, Insert)') == before_insert, 'preferences Insert leaked to application' + assert app.poll() is None, 'preferences command stopped Cthulhu' + def preferences_window(): + result = subprocess.run(['xdotool', 'search', '--onlyvisible', '--name', '^Cthulhu Preferences$'], capture_output=True, text=True) + return result.stdout.strip().splitlines()[0] if result.stdout.strip() else None + preferences = wait_for(preferences_window, 'preferences window did not open') + subprocess.run(['xdotool', 'keydown', 'Insert', 'key', 'space', 'keyup', 'Insert'], check=True) + wait_for(lambda: log.read_text().count('preferences command received') == 2, 'second preferences command missing') + assert preferences_window() == preferences, 'repeated command replaced the preferences window' + set_active_window(int(preferences)) + subprocess.run(['xdotool', 'windowfocus', preferences], check=True) + focus_log_offset = len(log.read_text()) + focus_before = log.read_text().count('"type":"object:state-changed:focused"') + def preferences_control(controlName, controlRole): + import pyatspi + def walk(node): + yield node + for child in node: + if child is not None: + yield from walk(child) + for application in pyatspi.Registry.getDesktop(0): + for window in application: + if window is None or window.name != 'Cthulhu Preferences': + continue + for node in walk(window): + if node.name == controlName and node.getRole() == controlRole: + return node + return None + import pyatspi + progressBackground = wait_for(lambda: preferences_control('Report background progress bars', pyatspi.ROLE_CHECK_BOX), 'preferences progress background option missing') + assert progressBackground.queryComponent().grabFocus(), 'cannot focus preferences progress background option' + wait_for(lambda: '"role":"check box"' in log.read_text()[focus_log_offset:], + 'preferences progress background focus event missing') + subprocess.run(['xdotool', 'key', '--delay', '100', *(["Tab"] * 12)], check=True) + try: + wait_for( + lambda: log.read_text().count('"type":"object:state-changed:focused"') >= focus_before + 8, + 'preferences Tab traversal stopped producing focus events', + ) + except RuntimeError: + focused = [ + line for line in log.read_text().splitlines() + if '"type":"object:state-changed:focused"' in line + ] + print("\n".join(focused[-16:]), file=sys.stderr) + raise + focus_log = log.read_text()[focus_log_offset:] + assert '"role":"combo box"' in focus_log, ( + 'preferences combo focused as an internal button', + focus_log, + ) + combo_snapshot_durations = [] + for line in focus_log.splitlines(): + if '"role":"combo box"' not in line or '"type":"object:state-changed:focused"' not in line: + continue + record = json.loads(line) + if 'snapshot_duration' in record: + combo_snapshot_durations.append(record['snapshot_duration']) + assert combo_snapshot_durations, 'preferences combo focus snapshots missing durations' + slowest_combo_snapshot = max(combo_snapshot_durations) + assert slowest_combo_snapshot < 100_000_000, ( + 'preferences combo focus snapshot was slow', + slowest_combo_snapshot, + ) + progress_snapshot_durations = [] + for line in focus_log.splitlines(): + if '"role":"check box"' not in line or '"type":"object:state-changed:focused"' not in line: + continue + record = json.loads(line) + if 'snapshot_duration' in record: + progress_snapshot_durations.append(record['snapshot_duration']) + assert progress_snapshot_durations, 'preferences progress checkbox focus snapshots missing durations' + slowest_progress_snapshot = max(progress_snapshot_durations) + assert slowest_progress_snapshot < 20_000_000, ( + 'preferences progress checkbox focus snapshot was slow', + slowest_progress_snapshot, + ) + # Start at the retained keyboard layout group and verify the + # current General page's actual keyboard path. + desktop = wait_for(lambda: preferences_control('Desktop', pyatspi.ROLE_RADIO_BUTTON), + 'preferences Desktop layout missing') + assert desktop.queryComponent().grabFocus(), 'cannot focus Desktop layout' + # GTK combo focus belongs to its internal button, which is not + # exposed in the combo's AT-SPI children. Check the reader's + # semantic focus events rather than the outer widget's state. + for controlName, expectedRole in ( + ('Time format', 'combo box'), + ('Date format', 'combo box'), + ('Progress bar output', 'combo box'), + ('Report background progress bars', 'check box'), + ): + tabOffset = len(log.read_text()) + subprocess.run(['xdotool', 'key', 'Tab'], check=True) + wait_for(lambda: any( + record.get('type') == 'object:state-changed:focused' and + record.get('role') == expectedRole + for record in (json.loads(line) for line in log.read_text()[tabOffset:].splitlines()) + ), 'Tab did not reach ' + controlName) + set_active_window(int(preferences)) + subprocess.run(['xdotool', 'windowfocus', preferences, 'key', 'Escape'], check=True) + wait_for(lambda: preferences_window() is None, 'Escape did not close preferences') + set_active_window(int(window)) + subprocess.run(['xdotool', 'windowfocus', window], check=True) + print('PASS: Insert+X and desktop Insert+Return passed through; KP Enter routed Where Am I with both NumLock states; repeated Insert+Space routed preferences once') + + object_commands = [ + ('Up', 'parent'), + ('Down', 'first-child'), + ('Left', 'previous-sibling'), + ('Right', 'next-sibling'), + ] + for arrow, direction in object_commands: + before_arrow = events.read_text().count(f', {arrow})') + before_insert = events.read_text().count('keysym 0xff63, Insert)') + before_command = count_records( + log, + '"message":"object review command received"', + f'"direction":"{direction}"', + ) + subprocess.run([ + 'xdotool', 'keydown', 'Insert', 'keydown', 'Control_L', + 'key', arrow, 'keyup', 'Control_L', 'keyup', 'Insert', + ], check=True) + wait_for( + lambda direction=direction, before_command=before_command: count_records( + log, + '"message":"object review command received"', + f'"direction":"{direction}"', + ) == before_command + 1, + f'Insert+Control+{arrow} did not route {direction}', + ) + time.sleep(0.05) + assert events.read_text().count(f', {arrow})') == before_arrow, f'{arrow} object navigation leaked to application' + assert events.read_text().count('keysym 0xff63, Insert)') == before_insert, f'Insert+Control+{arrow} modifier leaked to application' + + before_up = events.read_text().count(', Up)') + before_insert = events.read_text().count('keysym 0xff63, Insert)') + before_parent = count_records( + log, + '"message":"object review command received"', + '"direction":"parent"', + ) + subprocess.run([ + 'xdotool', 'keydown', 'Control_L', 'keydown', 'Insert', + 'key', 'Up', 'keyup', 'Insert', 'keyup', 'Control_L', + ], check=True) + wait_for( + lambda: count_records( + log, + '"message":"object review command received"', + '"direction":"parent"', + ) == before_parent + 1, + 'Control-first Insert+Control+Up did not route parent', + ) + time.sleep(0.05) + assert events.read_text().count(', Up)') == before_up, 'Control-first object navigation leaked Up to application' + assert events.read_text().count('keysym 0xff63, Insert)') == before_insert, 'Control-first object navigation leaked Insert to application' + assert app.poll() is None, 'object navigation command stopped Cthulhu' + print('PASS: Cthulhu+Control+Arrow consumed with balanced Insert-first and Control-first chords') + + for arrow, command in [('Left', 'select-previous-speech-setting'), + ('Right', 'select-next-speech-setting'), + ('Up', 'increase-speech-setting'), + ('Down', 'decrease-speech-setting')]: + before_arrow = events.read_text().count(f', {arrow})') + before_command = count_records(log, '"message":"speech setting command received"', + f'"command":"{command}"') + subprocess.run(['xdotool', 'keydown', 'Insert', 'keydown', arrow, + 'keyup', 'Insert', 'keyup', arrow], check=True) + wait_for(lambda: count_records(log, '"message":"speech setting command received"', + f'"command":"{command}"') == before_command + 1, + 'speech shortcut did not dispatch: ' + command) + time.sleep(0.05) + assert events.read_text().count(f', {arrow})') == before_arrow, 'speech shortcut leaked arrow' + print('PASS: Cthulhu+Arrow speech commands consumed with modifier released first') + + check_speech_mode_shortcut(log, events, 'Insert') + print('PASS: Cthulhu+S consumed once with repeated keydown and both release orders') + + review_keys = [ + ('KP_Home', 'u', 'review-previous-line'), + ('KP_Up', 'i', 'review-current-line'), + ('KP_Page_Up', 'o', 'review-next-line'), + ('KP_Left', 'j', 'review-previous-word'), + ('KP_Begin', 'k', 'review-current-word'), + ('KP_Right', 'l', 'review-next-word'), + ('KP_End', 'm', 'review-previous-character'), + ('KP_Down', 'comma', 'review-current-character'), + ('KP_Page_Down', 'period', 'review-next-character'), + ] + + def flush_probe_events(): + before_f12 = events.read_text().count(', F12)') + subprocess.run(['xdotool', 'key', 'F12'], check=True) + wait_for(lambda: events.read_text().count(', F12)') >= before_f12 + 2, + 'ordinary key did not reach probe after review') + + for desktop_key, _, command in review_keys: + before_key = events.read_text().count(', ' + desktop_key + ')') + before_command = count_records(log, '"message":"flat review command received"', + '"command":"' + command + '"') + subprocess.run(['xdotool', 'key', desktop_key], check=True) + wait_for(lambda: count_records(log, '"message":"flat review command received"', + '"command":"' + command + '"') == before_command + 1, + 'desktop review command missing: ' + command) + flush_probe_events() + assert events.read_text().count(', ' + desktop_key + ')') == before_key, \ + 'desktop review key leaked: ' + desktop_key + for reviewKey, expectedCommands in ( + ('KP_Down', ('review-current-character', 'review-phonetic-character')), + ('KP_Begin', ('review-current-word', 'review-spell-word', 'review-phonetic-word')), + ('KP_Up', ('review-current-line', 'review-spell-line', 'review-phonetic-line'))): + beforeKey = events.read_text().count(', ' + reviewKey + ')') + beforeCommands = {command: count_records(log, '"message":"flat review command received"', + '"command":"' + command + '"') + for command in expectedCommands} + subprocess.run(['xdotool', 'key', '--delay', '80'] + [reviewKey] * len(expectedCommands), check=True) + for expectedCommand in expectedCommands: + wait_for(lambda command=expectedCommand: count_records(log, '"message":"flat review command received"', + '"command":"' + command + '"') == beforeCommands[command] + 1, + 'review multipress missing: ' + expectedCommand) + flush_probe_events() + assert events.read_text().count(', ' + reviewKey + ')') == beforeKey, 'multipress review key leaked' + print('PASS: double character and triple word/line review commands with no application leakage') + for desktop_key, command in [('KP_Home', 'review-window-start'), ('KP_Page_Up', 'review-window-end')]: + before_key = events.read_text().count(', ' + desktop_key + ')') + for modifier_first in (False, True): + before_command = count_records(log, '"message":"flat review command received"', + '"command":"' + command + '"') + releases = ['Insert', desktop_key] if modifier_first else [desktop_key, 'Insert'] + subprocess.run(['xdotool', 'keydown', 'Insert', 'keydown', desktop_key, + 'keyup', releases[0], 'keyup', releases[1]], check=True) + wait_for(lambda: count_records(log, '"message":"flat review command received"', + '"command":"' + command + '"') == before_command + 1, + 'desktop window review command missing: ' + command) + flush_probe_events() + assert events.read_text().count(', ' + desktop_key + ')') == before_key, \ + 'desktop window review key leaked: ' + desktop_key + before_review = count_records(log, '"message":"flat review command received"') + subprocess.run(['xdotool', 'key', 'Num_Lock'], check=True) + before_numeric = events.read_text().count(', KP_7)') + numeric_offset = len(events.read_text()) + press_physical_key(0xff95) # physical keypad 7/Home, with NumLock on + try: + wait_for(lambda: events.read_text().count(', KP_7)') == before_numeric + 2, + 'NumLock numeric keypad was consumed by review') + except RuntimeError: + print(events.read_text()[numeric_offset:], file=sys.stderr) + print('review records before/after:', before_review, + count_records(log, '"message":"flat review command received"'), file=sys.stderr) + raise + assert count_records(log, '"message":"flat review command received"') == before_review + subprocess.run(['xdotool', 'key', 'Num_Lock'], check=True) + print('PASS: all nine desktop flat-review keys plus window start/end consumed; NumLock numeric typing preserved') + + subprocess.run(['xdotool', 'keydown', 'Insert', 'key', 'space', 'keyup', 'Insert'], check=True) + preferences = wait_for(preferences_window, 'preferences did not reopen') + set_active_window(int(preferences)) + subprocess.run(['xdotool', 'windowfocus', preferences], check=True) + + subprocess.run(['xdotool', 'keydown', 'Insert', 'key', 'q'], check=True) + time.sleep(0.1) + assert app.poll() is None, 'quit occurred before modifier release' + subprocess.run(['xdotool', 'keyup', 'Insert'], check=True) + assert app.wait(timeout=10) == 0, log.read_text() + wait_for(lambda: preferences_window() is None, 'quit left preferences running') + assert 'quit command received' in log.read_text(), log.read_text() + time.sleep(0.1) + assert events.read_text().count('keysym 0x71, q)') == before, 'command q leaked to application' + subprocess.run(['xdotool', 'windowfocus', window], check=True) + subprocess.run(['xdotool', 'key', 'q', 'Insert'], check=True) + wait_for(lambda: events.read_text().count('keysym 0x71, q)') == before + 2, 'q grab remained after quit') + assert 'keysym 0xff63, Insert)' in events.read_text(), 'Insert grab remained after quit' + print('PASS: ordinary typing; Insert+Q consumed; release-safe quit; grabs removed') + for modifier, lock, modifierFirst in [('Insert','Num_Lock',True), ('Insert','Caps_Lock',False), ('KP_Insert',None,True)]: + if lock: + subprocess.run(['xdotool','key',lock],check=True) + app = subprocess.Popen([str(binary),'--config',str(config),'--debug-file',str(root / 'next.log')],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL) + processes.append(app) + nextLog = root / 'next.log' + wait_for(lambda: nextLog.exists() and 'listening for focus events' in nextLog.read_text(), 'restart did not become ready') + # Give the startup loop a chance to enter native event dispatch. + time.sleep(0.05) + beforeQ = events.read_text().count('keycode 24 ') + subprocess.run(['xdotool','keydown',modifier,'keydown','q'],check=True) + if modifierFirst: + subprocess.run(['xdotool','keyup',modifier,'keyup','q'],check=True) + else: + subprocess.run(['xdotool','keyup','q','keyup',modifier],check=True) + assert app.wait(timeout=5) == 0, nextLog.read_text() + time.sleep(0.05) + assert events.read_text().count('keycode 24 ') == beforeQ, ('q leaked with lock keys or alternate release order', modifier, lock, modifierFirst, events.read_text()[-1800:]) + if lock: + subprocess.run(['xdotool','key',lock],check=True) + nextLog.unlink() + print('PASS: NumLock, CapsLock, keypad Insert, alternate release order, repeated startup/shutdown') + + config.write_text('[general]\nenableSpeech = false\nenableSound = false\nkeyboardLayout = 2\n') + laptop_log = root / 'laptop.log' + app = subprocess.Popen([str(binary), '--config', str(config), '--debug-file', str(laptop_log)], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + processes.append(app) + wait_for(lambda: laptop_log.exists() and 'listening for focus events' in laptop_log.read_text(), + 'laptop layout did not start') + check_speech_mode_shortcut(laptop_log, events, 'Insert') + for _, laptop_key, command in review_keys: + before_key = events.read_text().count(', ' + laptop_key + ')') + before_insert = events.read_text().count(', Insert)') + for modifier_first in (False, True): + expected_command = command + if modifier_first: + expected_command = { + 'review-current-line': 'review-spell-line', + 'review-current-word': 'review-spell-word', + 'review-current-character': 'review-phonetic-character', + }.get(command, command) + before_command = count_records(laptop_log, '"message":"flat review command received"', + '"command":"' + expected_command + '"') + releases = ['Insert', laptop_key] if modifier_first else [laptop_key, 'Insert'] + subprocess.run(['xdotool', 'keydown', 'Insert', 'keydown', laptop_key, + 'keyup', releases[0], 'keyup', releases[1]], check=True) + wait_for(lambda: count_records(laptop_log, '"message":"flat review command received"', + '"command":"' + expected_command + '"') == before_command + 1, + 'laptop review command missing: ' + expected_command) + flush_probe_events() + assert events.read_text().count(', ' + laptop_key + ')') == before_key, \ + 'laptop review key leaked: ' + laptop_key + assert events.read_text().count(', Insert)') == before_insert, 'laptop Insert leaked' + for laptop_key, command in [('u', 'review-window-start'), ('o', 'review-window-end')]: + for modifier_first in (False, True): + before_key = events.read_text().count(', ' + laptop_key + ')') + before_insert = events.read_text().count(', Insert)') + before_command = count_records(laptop_log, '"message":"flat review command received"', + '"command":"' + command + '"') + subprocess.run(['xdotool', 'keydown', 'Insert', 'keydown', 'Control_L', + 'keydown', laptop_key], check=True) + wait_for(lambda: count_records(laptop_log, '"message":"flat review command received"', + '"command":"' + command + '"') == before_command + 1, + 'laptop window boundary command did not dispatch on press: ' + command) + releases = ['Insert', 'Control_L', laptop_key] if modifier_first else [laptop_key, 'Control_L', 'Insert'] + subprocess.run(['xdotool'] + [part for key in releases for part in ('keyup', key)], check=True) + flush_probe_events() + assert events.read_text().count(', ' + laptop_key + ')') == before_key, 'laptop boundary key leaked' + assert events.read_text().count(', Insert)') == before_insert, 'laptop boundary Insert leaked' + before_keypad = events.read_text().count(', KP_Up)') + subprocess.run(['xdotool', 'key', 'KP_Up'], check=True) + wait_for(lambda: events.read_text().count(', KP_Up)') == before_keypad + 2, + 'laptop layout grabbed desktop review keys') + subprocess.run(['xdotool', 'keydown', 'Insert', 'key', 'q', 'keyup', 'Insert'], check=True) + assert app.wait(timeout=5) == 0, laptop_log.read_text() + print('PASS: all nine laptop flat-review keys plus window start/end; both release orders; desktop keypad pass-through; shutdown') + finally: + for process in reversed(processes): + if process.poll() is None: + process.terminate() + try: + process.wait(timeout=3) + except subprocess.TimeoutExpired: + process.kill() + process.wait() + + +def main(): + if len(sys.argv) == 3 and sys.argv[1] == '--inside': + run_inside(sys.argv[2]) + return + with tempfile.TemporaryDirectory(prefix='cthulhu-x11-') as directory: + readFd, writeFd = os.pipe() + server = subprocess.Popen(['Xvfb', '-displayfd', str(writeFd), '-screen', '0', '800x600x24', '-nolisten', 'tcp'], pass_fds=(writeFd,), stderr=subprocess.DEVNULL) + os.close(writeFd) + try: + with os.fdopen(readFd) as reader: + display = reader.readline().strip() + if not display: + raise RuntimeError('Xvfb failed to start') + environment = dict(os.environ, DISPLAY=':' + display) + environment.pop('DBUS_SESSION_BUS_ADDRESS', None) + environment.pop('AT_SPI_BUS_ADDRESS', None) + environment.pop('WAYLAND_DISPLAY', None) + environment['XDG_SESSION_TYPE'] = 'x11' + run_private_session(['dbus-run-session', '--', sys.executable, str(Path(__file__).resolve()), '--inside', directory], env=environment, check=True, timeout=60) + finally: + server.terminate() + server.wait(timeout=3) + + +if __name__ == '__main__': + main() diff --git a/tests/ocr_capture_fixture.py b/tests/ocr_capture_fixture.py new file mode 100644 index 0000000..6917b6f --- /dev/null +++ b/tests/ocr_capture_fixture.py @@ -0,0 +1,135 @@ +"""Generic painted X11/clipboard sources for an isolated Xvfb session.""" +import json +from pathlib import Path +import sys + +import gi +gi.require_version("Gtk", "3.0") +gi.require_version("Gdk", "3.0") +gi.require_version("GdkPixbuf", "2.0") +from gi.repository import Gdk, GdkPixbuf, GLib, Gtk +from Xlib import X, Xatom, display + + +def main(): + Gtk.init([]) + connection = display.Display() + root = connection.screen().root + activeAtom = connection.intern_atom("_NET_ACTIVE_WINDOW") + clipboardAtom = connection.intern_atom("CLIPBOARD") + pngAtom = connection.intern_atom("image/png") + pngPath = Path(__file__).resolve().parents[1] / "internal/ocr/testdata/painted-text.png" + pendingCapture = None + + def make_window(parent, x, y, width, height, color): + window = parent.create_window(x, y, width, height, 0, + connection.screen().root_depth, + X.InputOutput, X.CopyFromParent, + background_pixel=color) + window.set_wm_name("OCR fixture") + window.set_wm_class("example", "example") + window.map() + return window + + window = make_window(root, 40, 30, 300, 200, 0x336699) + child = make_window(window, 10, 15, 80, 50, 0xABCDEF) + other = make_window(root, 350, 30, 100, 100, 0x992244) + windows = dict(window=window, child=child, other=other) + clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + painted = GdkPixbuf.Pixbuf.new_from_file(str(pngPath)) + clipboard.set_image(painted) + paintedWindow = make_window(root, 40, 270, 640, 220, 0xFFFFFF) + windows["painted"] = paintedWindow + # The private fixture has an Xvfb 24-bit TrueColor root with 32-bit little + # endian pixels. Paint the checked-in image without adding another library. + data = painted.get_pixels() + stride = painted.get_rowstride() + nativeData = bytearray(640 * 220 * 4) + for y in range(220): + for x in range(640): + source = y * stride + x * 3 + destination = (y * 640 + x) * 4 + nativeData[destination:destination + 3] = data[source:source + 3][::-1] + gc = paintedWindow.create_gc() + for y in range(0, 220, 32): + height = min(32, 220 - y) + paintedWindow.put_image(gc, 0, y, 640, height, X.ZPixmap, 24, 0, + bytes(nativeData[y * 640 * 4:(y + height) * 640 * 4])) + gc.free() + + def activate(target): + root.change_property(activeAtom, Xatom.WINDOW, 32, [target.id]) + target.set_input_focus(X.RevertToParent, X.CurrentTime) + + activate(window) + connection.sync() + print(json.dumps({key: value.id for key, value in windows.items()}), flush=True) + loop = GLib.MainLoop() + + def command_ready(_source, condition): + nonlocal pendingCapture + if condition & GLib.IO_HUP: + loop.quit() + return False + line = sys.stdin.readline() + if not line: + loop.quit() + return False + command = json.loads(line) + target = windows.get(command.get("window", "window"), window) + action = command["action"] + if action == "activate": + activate(target) + elif action == "move": + target.configure(x=command["x"], y=command["y"]) + elif action == "resize": + target.configure(width=command["width"], height=command["height"]) + elif action == "hide": + target.unmap() + elif action == "destroy": + target.destroy() + elif action == "overlay": + windows["overlay"] = make_window(root, 40, 30, 30, 30, 0xAA1100) + elif action == "clipboard-text": + clipboard.set_text("Generic clipboard text", -1) + elif action == "clipboard-image": + clipboard.set_image(painted) + elif action == "clipboard-block": + other.set_selection_owner(clipboardAtom, X.CurrentTime) + elif action == "clipboard-release": + if pendingCapture is None: + raise RuntimeError("no pending image transfer") + from Xlib.protocol import event + request = pendingCapture + request.requestor.change_property(request.property, pngAtom, 8, pngPath.read_bytes()) + request.requestor.send_event(event.SelectionNotify( + time=request.time, requestor=request.requestor.id, + selection=request.selection, target=request.target, + property=request.property)) + pendingCapture = None + elif action != "state": + raise ValueError("unknown fixture action") + connection.sync() + focus = connection.get_input_focus().focus + children = root.query_tree().children + print(json.dumps({"focus": focus.id, "windows": len(children)}), flush=True) + return True + + GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, command_ready) + + def x_ready(_source, _condition): + nonlocal pendingCapture + while connection.pending_events(): + request = connection.next_event() + if request.type == X.SelectionRequest and request.target == pngAtom: + pendingCapture = request + print(json.dumps({"capture-request": 1}), flush=True) + return True + + GLib.io_add_watch(connection.fileno(), GLib.IO_IN, x_ready) + loop.run() + connection.close() + + +if __name__ == "__main__": + main() diff --git a/tests/ocr_click_fixture.py b/tests/ocr_click_fixture.py new file mode 100644 index 0000000..6aa4bb9 --- /dev/null +++ b/tests/ocr_click_fixture.py @@ -0,0 +1,34 @@ +"""Private X11 window that reports physical OCR click events.""" +import json +import sys + +from Xlib import X, Xatom, display + + +connection = display.Display() +screen = connection.screen() +root = screen.root +window = root.create_window(20, 20, 240, 140, 0, screen.root_depth, + X.InputOutput, X.CopyFromParent, + event_mask=X.ButtonPressMask | X.ButtonReleaseMask) +window.map() +root.change_property(connection.intern_atom("_NET_ACTIVE_WINDOW"), Xatom.WINDOW, 32, [window.id]) +window.set_input_focus(X.RevertToParent, X.CurrentTime) +connection.sync() +initial_pointer = root.query_pointer() +print(json.dumps({"window": window.id, "width": screen.width_in_pixels, + "height": screen.height_in_pixels, + "pointer": [initial_pointer.root_x, initial_pointer.root_y]}), flush=True) +for line in sys.stdin: + if line.strip() != "events": + break + connection.sync() + events = [] + while connection.pending_events(): + event = connection.next_event() + if event.type in (X.ButtonPress, X.ButtonRelease): + events.append({"pressed": event.type == X.ButtonPress, + "button": event.detail, "x": event.root_x, "y": event.root_y}) + pointer = root.query_pointer() + print(json.dumps({"events": events, "pointer": [pointer.root_x, pointer.root_y]}), flush=True) +connection.close() diff --git a/tests/ocr_geometry_fixture.py b/tests/ocr_geometry_fixture.py new file mode 100644 index 0000000..534754b --- /dev/null +++ b/tests/ocr_geometry_fixture.py @@ -0,0 +1,89 @@ +"""GTK provider geometry paired with independently measured X11 rectangles.""" +import json +import os +import sys +import gi + +gi.require_version('Gtk', '3.0') +gi.require_version('GdkX11', '3.0') +gi.require_version('Gdk', '3.0') +from gi.repository import Gdk, GdkX11, GLib, Gtk +from Xlib import X, Xatom, display + + +def main(): + window = Gtk.Window(title='OCR geometry fixture') + window.set_decorated(False) + window.set_default_size(300, 200) + window.move(40, 30) + fixed = Gtk.Fixed() + window.add(fixed) + painted = Gtk.DrawingArea() + painted.set_size_request(80, 50) + painted.set_can_focus(True) + painted.get_accessible().set_name('Painted target') + + def draw(_widget, context): + context.set_source_rgb(0.2, 0.4, 0.6) + context.paint() + return False + + painted.connect('draw', draw) + fixed.put(painted, 10, 15) + password = Gtk.Entry() + password.set_visibility(False) + password.get_accessible().set_name('Protected target') + fixed.put(password, 10, 90) + window.show_all() + painted.grab_focus() + Gdk.Display.get_default().sync() + connection = display.Display() + root = connection.screen().root + activeAtom = connection.intern_atom('_NET_ACTIVE_WINDOW') + clientId = GdkX11.X11Window.get_xid(window.get_window()) + client = connection.create_resource_object('window', clientId) + root.change_property(activeAtom, Xatom.WINDOW, 32, [clientId]) + client.change_property(connection.intern_atom('_NET_WM_PID'), Xatom.CARDINAL, 32, [os.getpid()]) + client.set_input_focus(X.RevertToParent, X.CurrentTime) + connection.sync() + + def rectangle(widget): + native = connection.create_resource_object('window', GdkX11.X11Window.get_xid(widget.get_window())) + origin = root.translate_coords(native, 0, 0) + geometry = native.get_geometry() + return [origin.x, origin.y, origin.x + geometry.width, origin.y + geometry.height] + + def state(): + connection.sync() + return dict(window=clientId, target=rectangle(painted), focus=connection.get_input_focus().focus.id) + + GLib.idle_add(lambda: (print(json.dumps(state()), flush=True), False)[1]) + + def command_ready(_source, condition): + if condition & GLib.IO_HUP: + Gtk.main_quit() + return False + line = sys.stdin.readline() + if not line: + Gtk.main_quit() + return False + command = json.loads(line) + action = command['action'] + if action == 'hide': + painted.hide() + elif action == 'password': + password.grab_focus() + elif action == 'move': + window.move(100, 60) + elif action != 'state': + raise ValueError('unknown fixture action') + GLib.idle_add(lambda: (print(json.dumps(state()), flush=True), False)[1]) + return True + + GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, command_ready) + Gtk.main() + connection.close() + + +if __name__ == '__main__': + main() diff --git a/tests/ocr_review_fixture.py b/tests/ocr_review_fixture.py new file mode 100644 index 0000000..dcd4419 --- /dev/null +++ b/tests/ocr_review_fixture.py @@ -0,0 +1,101 @@ +"""Private Xorg key sink: focus, delivered keys and conflicting passive grabs.""" +import json +import os +import select +import sys +from Xlib import X, Xatom, XK, display +from Xlib.ext import xtest + + +def main(): + connection = display.Display() + root = connection.screen().root + activeAtom = connection.intern_atom('_NET_ACTIVE_WINDOW') + previousActive = root.get_full_property(activeAtom, X.AnyPropertyType) + pidAtom = connection.intern_atom('_NET_WM_PID') + keys = [] + + def make_window(x): + window = root.create_window(x, 30, 300, 200, 0, + connection.screen().root_depth, + X.InputOutput, X.CopyFromParent, + background_pixel=0xFFFFFF, + event_mask=X.KeyPressMask | X.KeyReleaseMask) + window.set_wm_name('OCR review fixture') + window.set_wm_class('example', 'example') + window.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid()]) + window.map() + return window + + window = make_window(40) + other = make_window(380) + competitor = display.Display() + competitorRoot = competitor.screen().root + conflictCode = competitor.keysym_to_keycode(XK.string_to_keysym('c')) + + def activate(target): + root.change_property(activeAtom, Xatom.WINDOW, 32, [target.id]) + target.set_input_focus(X.RevertToParent, X.CurrentTime) + + def drain(): + connection.sync() + while connection.pending_events(): + event = connection.next_event() + if event.type in (X.KeyPress, X.KeyRelease): + keys.append(dict(pressed=event.type == X.KeyPress, + symbol=connection.keycode_to_keysym(event.detail, 0), + modifiers=event.state, window=event.window.id)) + + activate(window) + connection.sync() + print(json.dumps(dict(window=window.id, other=other.id)), flush=True) + try: + while True: + drain() + readable, _, _ = select.select([sys.stdin, connection.fileno()], [], []) + if sys.stdin not in readable: + continue + line = sys.stdin.readline() + if not line: + break + command = json.loads(line) + action = command['action'] + if action == 'activate': + activate(other if command.get('other') else window) + elif action == 'key': + keyCode = connection.keysym_to_keycode(XK.string_to_keysym(command['name'])) + if not keyCode: + raise ValueError('Unknown fixture key') + xtest.fake_input(connection, X.KeyPress, keyCode) + xtest.fake_input(connection, X.KeyRelease, keyCode) + elif action == 'class': + window.set_wm_class(command['name'], command['name']) + elif action == 'unknown': + root.change_property(activeAtom, Xatom.WINDOW, 32, [X.NONE]) + elif action == 'conflict': + competitorRoot.grab_key(conflictCode, X.ControlMask, False, + X.GrabModeAsync, X.GrabModeAsync) + competitor.sync() + elif action == 'unconflict': + competitorRoot.ungrab_key(conflictCode, X.ControlMask) + competitor.sync() + elif action not in ('state', 'clear'): + raise ValueError('unknown fixture action') + drain() + if action == 'clear': + keys.clear() + print(json.dumps(dict(focus=connection.get_input_focus().focus.id, + keys=keys)), flush=True) + finally: + if previousActive is None: + root.delete_property(activeAtom) + else: + root.change_property(activeAtom, previousActive.property_type, + previousActive.format, previousActive.value) + connection.sync() + competitor.close() + connection.close() + + +if __name__ == '__main__': + main() diff --git a/tests/ocr_session_fixture.py b/tests/ocr_session_fixture.py new file mode 100644 index 0000000..e1813cf --- /dev/null +++ b/tests/ocr_session_fixture.py @@ -0,0 +1,125 @@ +"""Painted OCR text with accessible focus targets on a private Xorg display.""" +import json +import os +from pathlib import Path +import sys +import cairo + +import gi +gi.require_version("Gtk", "3.0") +gi.require_version("Gdk", "3.0") +gi.require_version("GdkX11", "3.0") +gi.require_version("GdkPixbuf", "2.0") +from gi.repository import Gdk, GdkPixbuf, GdkX11, GLib, Gtk +from Xlib import X, Xatom, display + + +def main() -> None: + window = Gtk.Window(title="OCR session fixture") + window.set_decorated(False) + window.move(20, 20) + fixed = Gtk.Fixed() + window.add(fixed) + painted = Gtk.DrawingArea() + painted.set_size_request(640, 220) + painted.set_can_focus(True) + painted.get_accessible().set_name("Painted OCR target") + imagePath = Path(__file__).resolve().parents[1] / "internal/ocr/testdata/painted-text.png" + pixels = GdkPixbuf.Pixbuf.new_from_file(str(imagePath)) + + def draw(_widget: Gtk.Widget, context: object) -> bool: + Gdk.cairo_set_source_pixbuf(context, pixels, 0, 0) + context.paint() + return False + + painted.connect("draw", draw) + fixed.put(painted, 0, 0) + password = Gtk.Entry() + password.set_visibility(False) + password.get_accessible().set_name("Protected OCR focus") + fixed.put(password, 0, 230) + other = Gtk.Button(label="Other OCR focus") + fixed.put(other, 280, 230) + window.show_all() + painted.grab_focus() + clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) + clipboard.set_image(pixels) + connection = display.Display() + root = connection.screen().root + clientId = GdkX11.X11Window.get_xid(window.get_window()) + client = connection.create_resource_object("window", clientId) + root.change_property(connection.intern_atom("_NET_ACTIVE_WINDOW"), Xatom.WINDOW, 32, [clientId]) + client.change_property(connection.intern_atom("_NET_WM_PID"), Xatom.CARDINAL, 32, [os.getpid()]) + client.set_input_focus(X.RevertToParent, X.CurrentTime) + connection.sync() + activeClient = client + rawClient = None + + def show_inaccessible_window() -> None: + nonlocal activeClient, rawClient + # A raw X11 client deliberately has no AT-SPI object or focused widget. + surface = cairo.ImageSurface.create_from_png(str(imagePath)) + width, height = surface.get_width(), surface.get_height() + rawClient = root.create_window(20, 20, width, height, 0, + connection.screen().root_depth, + X.InputOutput, X.CopyFromParent, + background_pixel=0xFFFFFF) + rawClient.set_wm_name("Inaccessible OCR fixture") + rawClient.set_wm_class("example", "example") + rawClient.change_property(connection.intern_atom("_NET_WM_PID"), + Xatom.CARDINAL, 32, [os.getpid()]) + rawClient.map() + rawClient.configure(stack_mode=X.Above) + graphics = rawClient.create_gc() + data = bytes(surface.get_data()) + stride = surface.get_stride() + for row in range(0, height, 16): + rows = min(16, height - row) + rawClient.put_image(graphics, 0, row, width, rows, X.ZPixmap, + connection.screen().root_depth, 0, + data[row * stride:(row + rows) * stride]) + graphics.free() + root.change_property(connection.intern_atom("_NET_ACTIVE_WINDOW"), + Xatom.WINDOW, 32, [rawClient.id]) + rawClient.set_input_focus(X.RevertToParent, X.CurrentTime) + activeClient = rawClient + + def state() -> bool: + connection.sync() + print(json.dumps({"window": activeClient.id, "focus": connection.get_input_focus().focus.id}), flush=True) + return False + + def command_ready(_source: object, condition: int) -> bool: + if condition & GLib.IO_HUP: + Gtk.main_quit() + return False + line = sys.stdin.readline() + if not line: + Gtk.main_quit() + return False + action = json.loads(line)["action"] + if action == "painted": + painted.grab_focus() + elif action == "password": + password.grab_focus() + elif action == "other": + other.grab_focus() + elif action == "clipboard-text": + clipboard.set_text("Generic replacement text", -1) + elif action == "inaccessible": + show_inaccessible_window() + elif action != "state": + raise ValueError("Unknown fixture action") + GLib.idle_add(state) + return True + + GLib.idle_add(state) + GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, command_ready) + Gtk.main() + if rawClient is not None: + rawClient.destroy() + connection.close() + + +if __name__ == "__main__": + main() diff --git a/tests/review_cache_fixture.c b/tests/review_cache_fixture.c new file mode 100644 index 0000000..f70c451 --- /dev/null +++ b/tests/review_cache_fixture.c @@ -0,0 +1,162 @@ +// Copyright (c) 2026 Storm Dragon +// Authors: Storm Dragon, Angus Kola +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include +#include + +static gboolean armed; +static unsigned childQueries; +static gboolean slowRanges; +static gint largestRange; +static GHashTable *measuredRanges; +static guint repeatedRanges; +static gboolean lineGeometryOnly; +static gboolean missingGlyph; +static GtkWidget *reviewScroller; +static AtkObject *brokenSubtree; +static gint (*originalChildCount)(AtkObject *); +static void (*originalRangeExtents)(AtkText *, gint, gint, AtkCoordType, AtkTextRectangle *); + +static void range_extents(AtkText *text, gint start, gint end, AtkCoordType coordinates, AtkTextRectangle *rectangle) { + if (missingGlyph && start == 5 && end == 6) { + memset(rectangle, 0, sizeof(*rectangle)); + return; + } + if (lineGeometryOnly && end - start == 1) { + memset(rectangle, 0, sizeof(*rectangle)); + return; + } + if (slowRanges) { + largestRange = MAX(largestRange, end - start); + guint64 key = ((guint64)(guint32)start << 32) | (guint32)end; + if (g_hash_table_contains(measuredRanges, &key)) repeatedRanges++; + else { + guint64 *stored = g_new(guint64, 1); + *stored = key; + g_hash_table_add(measuredRanges, stored); + } + if (end - start > 128) g_usleep(1200000); + } + originalRangeExtents(text, start, end, coordinates, rectangle); +} + +static gint count_children(AtkObject *object) { + (void)object; + if (armed) { + childQueries++; + // The initial cache already reports this label as a leaf. A redundant + // property query models the temporarily unresponsive live cell. + g_usleep(1200000); + } + return 0; +} + +static gint subtree_child_count(AtkObject *object) { + if (object == brokenSubtree && armed) return -1; + return originalChildCount(object); +} + +static gboolean command_ready(GIOChannel *channel, GIOCondition condition, gpointer label) { + if (condition & G_IO_HUP) { + gtk_main_quit(); + return FALSE; + } + gchar *line = NULL; + if (g_io_channel_read_line(channel, &line, NULL, NULL, NULL) != G_IO_STATUS_NORMAL) + return TRUE; + if (g_str_has_prefix(line, "arm")) { + armed = TRUE; + puts("armed"); + } else if (g_str_has_prefix(line, "count")) { + printf("count %u\n", childQueries); + } else if (g_str_has_prefix(line, "measure")) { + slowRanges = TRUE; + g_hash_table_remove_all(measuredRanges); + repeatedRanges = 0; + puts("measuring"); + } else if (g_str_has_prefix(line, "repeated")) { + printf("repeated %u\n", repeatedRanges); + } else if (g_str_has_prefix(line, "largest")) { + printf("largest %d\n", largestRange); + } else if (g_str_has_prefix(line, "scroll")) { + GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(reviewScroller)); + gtk_adjustment_set_value(adjustment, gtk_adjustment_get_upper(adjustment) * 0.75); + while (gtk_events_pending()) gtk_main_iteration(); + puts("scrolled"); + } else if (g_str_has_prefix(line, "change")) { + armed = FALSE; + gtk_label_set_text(GTK_LABEL(label), "Changed review text"); + puts("changed"); + } + g_free(line); + fflush(stdout); + return TRUE; +} + +int main(int argc, char **argv) { + gboolean boundsMode = argc > 1 && strcmp(argv[1], "bounds") == 0; + gboolean clippedMode = argc > 1 && strcmp(argv[1], "clipped") == 0; + gboolean longMode = argc > 1 && strcmp(argv[1], "long") == 0; + gboolean linesMode = argc > 1 && strcmp(argv[1], "lines") == 0; + gboolean childrenMode = argc > 1 && strcmp(argv[1], "children") == 0; + gboolean glyphsMode = argc > 1 && strcmp(argv[1], "glyphs") == 0; + lineGeometryOnly = linesMode; + missingGlyph = glyphsMode; + gtk_init(&argc, &argv); + measuredRanges = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, NULL); + GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(window), "Review cache probe"); + gtk_window_set_default_size(GTK_WINDOW(window), 300, 100); + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + GtkWidget *label = gtk_label_new("Cached review text"); + // This fixture has one label. Replace its class vfunc before the bridge + // builds the initial cache, then arm the delay explicitly over stdin. + if (!childrenMode) + ATK_OBJECT_GET_CLASS(gtk_widget_get_accessible(label))->get_n_children = count_children; + if (childrenMode) { + GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + GtkWidget *panel = gtk_event_box_new(); + brokenSubtree = gtk_widget_get_accessible(panel); + atk_object_set_name(brokenSubtree, "Broken subtree"); + originalChildCount = ATK_OBJECT_GET_CLASS(brokenSubtree)->get_n_children; + ATK_OBJECT_GET_CLASS(brokenSubtree)->get_n_children = subtree_child_count; + gtk_container_add(GTK_CONTAINER(panel), gtk_label_new("Subtree text")); + gtk_container_add(GTK_CONTAINER(box), label); + gtk_container_add(GTK_CONTAINER(box), panel); + gtk_container_add(GTK_CONTAINER(window), box); + } else if (boundsMode || clippedMode || longMode || linesMode || glyphsMode) { + gchar *content = g_strnfill(linesMode ? 101000 : longMode ? 100001 : clippedMode ? 2020 : 3424, 'x'); + if (longMode) content[100000] = '\n'; + if (linesMode) { + for (int row = 0; row < 1000; row++) content[row * 101 + 100] = '\n'; + gtk_window_set_default_size(GTK_WINDOW(window), 1000, 100); + } + if (clippedMode) { + for (int row = 0; row < 20; row++) content[row * 101 + 100] = '\n'; + gtk_window_set_default_size(GTK_WINDOW(window), 300, 450); + } + gtk_label_set_text(GTK_LABEL(label), content); + g_free(content); + gtk_label_set_xalign(GTK_LABEL(label), 0); + AtkObject *accessible = gtk_widget_get_accessible(label); + atk_object_set_name(accessible, "Long review label"); + originalRangeExtents = ATK_TEXT_GET_IFACE(accessible)->get_range_extents; + if (originalRangeExtents == NULL) g_error("fixture needs native GTK range extents"); + ATK_TEXT_GET_IFACE(accessible)->get_range_extents = range_extents; + GtkWidget *scroller = gtk_scrolled_window_new(NULL, NULL); + reviewScroller = scroller; + gtk_container_add(GTK_CONTAINER(scroller), label); + gtk_container_add(GTK_CONTAINER(window), scroller); + } else { + gtk_container_add(GTK_CONTAINER(window), label); + } + GIOChannel *input = g_io_channel_unix_new(0); + g_io_add_watch(input, G_IO_IN | G_IO_HUP, command_ready, label); + gtk_widget_show_all(window); + gtk_main(); + g_io_channel_unref(input); + g_hash_table_unref(measuredRanges); + return 0; +} diff --git a/tests/run-delegated-reader.sh b/tests/run-delegated-reader.sh new file mode 100644 index 0000000..e3f7eda --- /dev/null +++ b/tests/run-delegated-reader.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Optional cgroup development launcher, independent of any init system. +set -euo pipefail +if (( $# == 0 )); then + echo 'Usage: bash tests/run-delegated-reader.sh /absolute/path/to/cthulhu [reader options]' >&2 + exit 2 +fi +if [[ $1 != /* || ! -x $1 ]]; then + echo 'The reader executable must be an absolute executable path.' >&2 + exit 2 +fi +parent=${CTHULHU_TENTACLE_CGROUP_PARENT:-} +if [[ $parent != /* || ! -d $parent || ! -w $parent ]]; then + echo 'Set CTHULHU_TENTACLE_CGROUP_PARENT to an already delegated, writable cgroup v2 parent.' >&2 + echo 'Ordinary Tentacle use needs no launcher or cgroup setup.' >&2 + exit 2 +fi +exec "$@" --tentacle-cgroup-parent "$parent" diff --git a/tests/steam_big_picture_log.py b/tests/steam_big_picture_log.py new file mode 100644 index 0000000..2453f86 --- /dev/null +++ b/tests/steam_big_picture_log.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +"""Check a fresh, physical arrows-first Steam Big Picture run of Cthulhu.""" + +import argparse +import json +from pathlib import Path + + +def check_log(path: Path) -> None: + records = [json.loads(line) for line in path.read_text().splitlines() if line.strip()] + starts = [index for index, record in enumerate(records) + if record.get("message") == "starting Cthulhu"] + if not starts: + raise ValueError("no Cthulhu startup in log") + records = records[starts[-1]:] + + steam_pid = None + steam_document = False + first_link = None + first_caret = None + tab_focus = False + home = power = confirm = cancel = False + links_before_arrow = set() + for record in records: + message = record.get("message") + if message == "X11 foreground ownership changed": + pid = record.get("pid") or 0 + if first_link is not None and pid and pid != steam_pid and not cancel: + raise ValueError("foreground left Steam before the dialog check finished") + if first_link is None and pid: + steam_pid = pid + continue + if message == "suspended for XTerm focus handoff" and first_link is not None and not cancel: + raise ValueError("focus switched away from Steam before the dialog check finished") + if (message == "delivering accessible presentation" and + record.get("role") == "document web" and + record.get("utterance", "").startswith("Steam Big Picture Mode")): + steam_document = True + if message == "document caret navigation completed" and record.get("moved") is True: + if first_link is not None and first_caret is None: + first_caret = record.get("time") + continue + if message != "delivering accessible presentation" or record.get("cause") != "object:state-changed:focused": + continue + role = record.get("role") + utterance = record.get("utterance", "") + if role == "link" and utterance and steam_document: + if first_link is None: + first_link = record.get("time") + links_before_arrow.add(utterance) + elif first_caret is None: + links_before_arrow.add(utterance) + else: + tab_focus = True + if first_caret is None: + continue + if role == "menu item" and utterance == "Home, menu item": + home = True + elif role == "menu item" and utterance == "Power, menu item": + power = home + elif role == "button" and utterance == "Confirm, button": + confirm = power + elif role == "button" and utterance == "Cancel, button": + cancel = confirm + if cancel: + break + + if not steam_document or first_link is None: + raise ValueError("Steam never exposed its document and an initial focused link") + if len(links_before_arrow) != 1: + raise ValueError("focus moved between links before the first browse arrow; test arrows first") + if first_caret is None: + raise ValueError("no successful browse arrow after Steam became ready") + if not tab_focus: + raise ValueError("no focused link after the first arrow and Tab") + if not home or not power: + raise ValueError("Escape did not expose Home and Power") + if not confirm or not cancel: + raise ValueError("Power did not expose both Confirm and Cancel buttons") + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("log", type=Path, help="fresh Cthulhu debug log") + arguments = parser.parse_args() + try: + check_log(arguments.log) + except (OSError, ValueError, json.JSONDecodeError) as error: + parser.exit(1, f"Steam Big Picture check failed: {error}\n") + print("Steam Big Picture arrows-first focus, menu, and dialog check passed") + + +if __name__ == "__main__": + main() diff --git a/tests/steam_focus_fixture.py b/tests/steam_focus_fixture.py new file mode 100644 index 0000000..1ea3bad --- /dev/null +++ b/tests/steam_focus_fixture.py @@ -0,0 +1,79 @@ +"""Steam-shaped X11 browser and popup fixture for a private X server.""" + +import json +import os +import sys + +from Xlib import X, Xatom, XK, display +from Xlib.xobject.drawable import Window + + +def main() -> None: + connection = display.Display() + root = connection.screen().root + activeAtom = connection.intern_atom("_NET_ACTIVE_WINDOW") + pidAtom = connection.intern_atom("_NET_WM_PID") + + def make_window(parent: Window, width: int, height: int) -> Window: + window = parent.create_window(0, 0, width, height, 0, + connection.screen().root_depth, + event_mask=X.KeyPressMask | X.KeyReleaseMask) + window.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid()]) + window.map() + return window + + steam = make_window(root, 800, 600) + steam.set_wm_class("steamwebhelper", "steam") + mainHost = make_window(steam, 800, 600) + browser = make_window(mainHost, 800, 600) + popupHost = make_window(steam, 300, 600) + popup = make_window(popupHost, 300, 600) + other = make_window(root, 800, 600) + other.set_wm_class("example", "Example") + otherChild = make_window(other, 800, 600) + windows = dict(steam=steam, browser=browser, popup=popup, + popupHost=popupHost, other=other, otherChild=otherChild) + root.change_property(activeAtom, Xatom.WINDOW, 32, [steam.id]) + browser.set_input_focus(X.RevertToParent, X.CurrentTime) + connection.sync() + print(json.dumps({name: window.id for name, window in windows.items()}), flush=True) + for line in sys.stdin: + command = json.loads(line) + action = command["action"] + window = windows[command.get("window", "steam")] + if action == "activate": + root.change_property(activeAtom, Xatom.WINDOW, 32, [window.id]) + window.set_input_focus(X.RevertToParent, X.CurrentTime) + elif action == "focus": + window.set_input_focus(X.RevertToParent, X.CurrentTime) + elif action == "unmap": + window.unmap() + elif action == "map": + window.map() + elif action == "destroy": + window.destroy() + elif action == "class": + window.set_wm_class("example", "Example") + elif action == "xterm": + window.set_wm_class("xterm", "XTerm") + elif action == "unknown": + root.delete_property(activeAtom) + elif action == "pid": + window.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid() + 1]) + elif action == "events": + connection.sync() + events = [] + while connection.pending_events(): + event = connection.next_event() + if event.type in (X.KeyPress, X.KeyRelease): + events.append({"window": event.window.id, "pressed": event.type == X.KeyPress, + "escape": event.detail == connection.keysym_to_keycode(XK.string_to_keysym("Escape"))}) + print(json.dumps(events), flush=True) + continue + connection.sync() + print("ready", flush=True) + connection.close() + + +if __name__ == "__main__": + main() diff --git a/tests/test_arch_pkgbuild_optional_wine.py b/tests/test_arch_pkgbuild_optional_wine.py deleted file mode 100644 index 8d26921..0000000 --- a/tests/test_arch_pkgbuild_optional_wine.py +++ /dev/null @@ -1,147 +0,0 @@ -import re -import unittest -from pathlib import Path - - -class ArchPkgbuildOptionalWineTests(unittest.TestCase): - @classmethod - def setUpClass(cls) -> None: - repository = Path(__file__).resolve().parents[1] - cls.repository = repository - versionContents = ( - repository / "src" / "cthulhu" / "cthulhuVersion.py" - ).read_text(encoding="utf-8") - versionMatch = re.search(r'(?m)^version = "([^"]+)"$', versionContents) - if versionMatch is None: - raise AssertionError("Unable to read the current Cthulhu version") - cls.releaseVersion = versionMatch.group(1) - cls.pkgbuilds = [ - repository / "distro-packages" / "Arch-Linux" / name / "PKGBUILD" - for name in ("cthulhu", "cthulhu-git") - ] - cls.helperPkgbuilds = [ - repository / "distro-packages" / "Arch-Linux" / name / "PKGBUILD" - for name in ("cthulhu-wine-access", "cthulhu-wine-access-git") - ] - - @staticmethod - def _array_contents(contents: str, arrayName: str) -> str: - return contents.split(f"{arrayName}=(", 1)[1].split(")", 1)[0] - - def test_main_packages_disable_wine_helper_build(self) -> None: - for pkgbuild in self.pkgbuilds: - with self.subTest(pkgbuild=pkgbuild): - contents = pkgbuild.read_text(encoding="utf-8") - self.assertIn("-Dwine-access=disabled", contents) - - def test_main_packages_do_not_depend_on_wine(self) -> None: - for pkgbuild in self.pkgbuilds: - with self.subTest(pkgbuild=pkgbuild): - contents = pkgbuild.read_text(encoding="utf-8") - dependencySection = contents.split("source=(", 1)[0] - dependencyLines = { - line.strip().strip("'") - for line in dependencySection.splitlines() - if line.strip() and not line.lstrip().startswith("#") - } - self.assertNotIn("wine", dependencyLines) - - def test_main_packages_advertise_interchangeable_optional_helper(self) -> None: - helperDescription = ( - "'cthulhu-wine-access: Wine, Proton, NVDA Controller, and Tolk integration'" - ) - for pkgbuild in self.pkgbuilds: - with self.subTest(pkgbuild=pkgbuild): - contents = pkgbuild.read_text(encoding="utf-8") - self.assertIn( - helperDescription, - self._array_contents(contents, "optdepends_x86_64"), - ) - self.assertNotIn( - "cthulhu-wine-access", - self._array_contents(contents, "optdepends"), - ) - - def test_stable_packages_use_current_release_version(self) -> None: - for pkgbuild in (self.pkgbuilds[0], self.helperPkgbuilds[0]): - with self.subTest(pkgbuild=pkgbuild): - contents = pkgbuild.read_text(encoding="utf-8") - self.assertRegex( - contents, - rf"(?m)^pkgver={re.escape(self.releaseVersion)}$", - ) - - def test_release_metadata_uses_current_release_version(self) -> None: - mesonContents = (self.repository / "meson.build").read_text(encoding="utf-8") - self.assertRegex( - mesonContents, - rf"(?m)^ version: '{re.escape(self.releaseVersion)}(?:-[^']+)?',$", - ) - - expectedSlackwareVersion = f"VERSION=${{VERSION:-{self.releaseVersion}}}" - for relativePath in ( - ("distro-packages", "Slackware", "cthulhu.SlackBuild"), - ("distro-packages", "Slint", "cthulhu.SlackBuild"), - ): - with self.subTest(relativePath=relativePath): - contents = self.repository.joinpath(*relativePath).read_text( - encoding="utf-8" - ) - self.assertIn(expectedSlackwareVersion, contents) - - slintInfo = ( - self.repository / "distro-packages" / "Slint" / "cthulhu-info" - ).read_text(encoding="utf-8") - self.assertRegex( - slintInfo, - rf'(?m)^VERSION="{re.escape(self.releaseVersion)}"$', - ) - - def test_stable_helper_has_release_contract(self) -> None: - contents = self.helperPkgbuilds[0].read_text(encoding="utf-8") - self.assertRegex(contents, r"(?m)^arch=\(x86_64\)$") - - def test_optional_helpers_do_not_depend_on_main_package(self) -> None: - for pkgbuild in self.helperPkgbuilds: - with self.subTest(pkgbuild=pkgbuild): - contents = pkgbuild.read_text(encoding="utf-8") - dependencies = self._array_contents(contents, "depends") - self.assertNotRegex( - dependencies, - r"(?m)^\s*['\"]?cthulhu(?:-git)?(?:[<>=].*)?['\"]?\s*$", - ) - - def test_git_helper_provides_stable_helper_name(self) -> None: - contents = self.helperPkgbuilds[1].read_text(encoding="utf-8") - self.assertRegex(contents, r"(?m)^provides=\(cthulhu-wine-access\)$") - self.assertRegex(contents, r"(?m)^conflicts=\(cthulhu-wine-access\)$") - - def test_optional_helper_packages_build_only_the_helper(self) -> None: - for pkgbuild in self.helperPkgbuilds: - with self.subTest(pkgbuild=pkgbuild): - contents = pkgbuild.read_text(encoding="utf-8") - self.assertIn('/scripts/build-wine-access.sh"', contents) - self.assertNotIn("arch-meson", contents) - self.assertRegex(contents, r"(?m)^ wine$") - makeDependencies = self._array_contents(contents, "makedepends") - self.assertNotRegex(makeDependencies, r"(?m)^\s*meson\s*$") - - def test_optional_helper_packages_disable_lto(self) -> None: - for pkgbuild in self.helperPkgbuilds: - with self.subTest(pkgbuild=pkgbuild): - contents = pkgbuild.read_text(encoding="utf-8") - self.assertRegex(contents, r"(?m)^options=\(!lto\)$") - - def test_git_sources_declare_git_as_a_build_dependency(self) -> None: - for pkgbuild in self.pkgbuilds + self.helperPkgbuilds: - with self.subTest(pkgbuild=pkgbuild): - contents = pkgbuild.read_text(encoding="utf-8") - self.assertIn("git+", contents) - makeDependencies = contents.split("makedepends=(", 1)[1].split( - ")", 1 - )[0] - self.assertRegex(makeDependencies, r"(?m)^ git$") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_bye_cthulhu_regressions.py b/tests/test_bye_cthulhu_regressions.py deleted file mode 100644 index 3a406ab..0000000 --- a/tests/test_bye_cthulhu_regressions.py +++ /dev/null @@ -1,30 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu.plugins.ByeCthulhu.plugin import ByeCthulhu - - -class ByeCthulhuRegressionTests(unittest.TestCase): - def test_activate_only_connects_stop_signal_once(self): - plugin = ByeCthulhu() - signalManager = mock.Mock() - signalManager.connectSignal.return_value = 42 - plugin.app = mock.Mock() - plugin.app.getSignalManager.return_value = signalManager - - plugin.activate(plugin) - plugin.activate(plugin) - - signalManager.connectSignal.assert_called_once_with( - "stop-application-completed", - plugin.process, - "default", - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_chromium_omnibox_regressions.py b/tests/test_chromium_omnibox_regressions.py deleted file mode 100644 index 20eff48..0000000 --- a/tests/test_chromium_omnibox_regressions.py +++ /dev/null @@ -1,251 +0,0 @@ -import unittest -from unittest import mock - -import gi -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu import ax_object -from cthulhu import cthulhu_state -from cthulhu import focus_manager -from cthulhu.scripts import default -from cthulhu.scripts.toolkits.Chromium import script as chromium_script -from cthulhu.scripts.toolkits.Chromium import script_utilities as chromium_utilities - - -class ChromiumOmniboxRegressionTests(unittest.TestCase): - def tearDown(self): - cthulhu_state.activeWindow = None - cthulhu_state.locusOfFocus = None - - def test_detects_chromium_popup_item_with_broken_ancestry(self): - popupItem = object() - - with ( - mock.patch.object(ax_object.AXObject, "is_dead", return_value=False), - mock.patch.object(ax_object.AXObject, "get_toolkit_name", return_value="chromium"), - mock.patch.object(ax_object.AXObject, "get_role", return_value=Atspi.Role.LIST_ITEM), - mock.patch.object(ax_object.AXObject, "get_parent", return_value=None), - mock.patch.object(ax_object.debug, "print_tokens"), - ): - self.assertTrue(ax_object.AXObject.has_broken_popup_ancestry(popupItem)) - - def test_ignores_chromium_popup_item_with_valid_ancestry(self): - popupItem = object() - parent = object() - - def get_role(obj): - if obj is popupItem: - return Atspi.Role.LIST_ITEM - return Atspi.Role.APPLICATION - - with ( - mock.patch.object(ax_object.AXObject, "is_dead", return_value=False), - mock.patch.object(ax_object.AXObject, "get_toolkit_name", return_value="chromium"), - mock.patch.object(ax_object.AXObject, "get_role", side_effect=get_role), - mock.patch.object(ax_object.AXObject, "get_parent", side_effect=[parent, None]), - ): - self.assertFalse(ax_object.AXObject.has_broken_popup_ancestry(popupItem)) - - def test_preserves_active_window_when_chromium_popup_ancestry_is_broken(self): - activeWindow = object() - popupItem = object() - cthulhu_state.activeWindow = activeWindow - cthulhu_state.locusOfFocus = popupItem - - controller = mock.Mock() - app = mock.Mock() - manager = None - with ( - mock.patch.object(focus_manager.dbus_service, "get_remote_controller", return_value=controller), - mock.patch.object(focus_manager.AXObject, "has_broken_popup_ancestry", return_value=True), - ): - manager = focus_manager.FocusManager(app) - manager.set_active_window(None) - - self.assertIs(manager.get_active_window(), activeWindow) - self.assertIs(cthulhu_state.activeWindow, activeWindow) - - def test_detects_nameless_frame_with_listbox_as_autocomplete_popup(self): - utilities = chromium_utilities.Utilities.__new__(chromium_utilities.Utilities) - frame = object() - listbox = object() - - with ( - mock.patch.object(chromium_utilities.AXUtilities, "is_frame", return_value=True), - mock.patch.object(chromium_utilities.AXObject, "get_name", return_value=""), - mock.patch.object(chromium_utilities.AXObject, "get_child_count", return_value=1), - mock.patch.object(chromium_utilities.AXObject, "get_child", return_value=listbox), - mock.patch.object(chromium_utilities.AXUtilities, "is_list_box", return_value=True), - ): - result = utilities.autocompletePopupForFrame(frame) - - self.assertIs(result, listbox) - - def test_does_not_treat_nested_listbox_as_autocomplete_popup(self): - utilities = chromium_utilities.Utilities.__new__(chromium_utilities.Utilities) - frame = object() - - with ( - mock.patch.object(chromium_utilities.AXUtilities, "is_frame", return_value=True), - mock.patch.object(chromium_utilities.AXObject, "get_name", return_value=""), - mock.patch.object(chromium_utilities.AXObject, "get_child_count", return_value=2), - ): - result = utilities.autocompletePopupForFrame(frame) - - self.assertIsNone(result) - - @staticmethod - def _make_chromium_script(): - testScript = chromium_script.Script.__new__(chromium_script.Script) - testScript.utilities = mock.Mock() - testScript.utilities.canBeActiveWindow.return_value = True - testScript.utilities.autocompletePopupForFrame.return_value = None - testScript.utilities.popupMenuForFrame.return_value = None - testScript._lastAutocompletePopupItem = None - testScript.presentObject = mock.Mock() - return testScript - - def test_autocomplete_popup_activation_presents_item_without_frame_fallback(self): - testScript = self._make_chromium_script() - frame = object() - listbox = object() - item = object() - event = mock.Mock(source=frame) - testScript.utilities.autocompletePopupForFrame.return_value = listbox - testScript.utilities.selectedChildren.return_value = [item] - - with ( - mock.patch.object(chromium_script.AXUtilities, "get_focused_object", return_value=item), - mock.patch.object(chromium_script.cthulhu, "setActiveWindow") as setActiveWindow, - mock.patch.object(chromium_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - mock.patch.object(default.Script, "onWindowActivated") as defaultHandler, - ): - chromium_script.Script.onWindowActivated(testScript, event) - - setActiveWindow.assert_not_called() - setLocusOfFocus.assert_not_called() - testScript.presentObject.assert_called_once_with(item, interrupt=True) - self.assertIs(testScript._lastAutocompletePopupItem, item) - defaultHandler.assert_not_called() - - def test_autocomplete_popup_activation_uses_focused_item_when_none_selected(self): - testScript = self._make_chromium_script() - frame = object() - listbox = object() - item = object() - event = mock.Mock(source=frame) - testScript.utilities.autocompletePopupForFrame.return_value = listbox - testScript.utilities.selectedChildren.return_value = [] - - with mock.patch.object( - chromium_script.AXUtilities, - "get_focused_object", - return_value=item, - ): - chromium_script.Script.onWindowActivated(testScript, event) - - testScript.presentObject.assert_called_once_with(item, interrupt=True) - self.assertIs(testScript._lastAutocompletePopupItem, item) - - def test_autocomplete_popup_selection_is_presented_without_changing_document_focus(self): - testScript = self._make_chromium_script() - comboBox = object() - listbox = object() - frame = object() - item = object() - event = mock.Mock(source=item, detail1=True) - cthulhu_state.locusOfFocus = comboBox - testScript.utilities.inDocumentContent.return_value = False - - with ( - mock.patch.object(chromium_script.web.Script, "onSelectedChanged", return_value=False), - mock.patch.object( - chromium_script.AXObject, - "find_ancestor_inclusive", - return_value=listbox, - ), - mock.patch.object(chromium_script.AXObject, "get_parent", return_value=frame), - mock.patch.object(chromium_script.AXObject, "get_name", return_value=""), - mock.patch.object(chromium_script.AXUtilities, "is_frame", return_value=True), - ): - chromium_script.Script.onSelectedChanged(testScript, event) - chromium_script.Script.onSelectedChanged(testScript, event) - - self.assertIs(cthulhu_state.locusOfFocus, comboBox) - testScript.presentObject.assert_called_once_with(item, interrupt=True) - - def test_main_window_deactivation_for_autocomplete_popup_preserves_state(self): - testScript = self._make_chromium_script() - mainFrame = object() - comboBox = object() - event = mock.Mock(source=mainFrame) - cthulhu_state.locusOfFocus = comboBox - testScript.utilities.lastKeyAndModifiers.return_value = ("Down", 8) - - with ( - mock.patch.object(chromium_script.AXUtilities, "is_combo_box", return_value=True), - mock.patch.object( - chromium_script.AXUtilities, - "supports_autocompletion", - return_value=True, - ), - mock.patch.object(default.Script, "onWindowDeactivated") as defaultHandler, - ): - chromium_script.Script.onWindowDeactivated(testScript, event) - - defaultHandler.assert_not_called() - - def test_unrelated_autocomplete_window_deactivation_reaches_default(self): - testScript = self._make_chromium_script() - mainFrame = object() - comboBox = object() - app = object() - event = mock.Mock(source=mainFrame) - cthulhu_state.locusOfFocus = comboBox - testScript.utilities.lastKeyAndModifiers.return_value = ("w", 4) - - with ( - mock.patch.object(chromium_script.AXUtilities, "is_combo_box", return_value=True), - mock.patch.object( - chromium_script.AXUtilities, - "supports_autocompletion", - return_value=True, - ), - mock.patch.object(chromium_script.AXObject, "get_application", return_value=app), - mock.patch.object(chromium_script.AXObject, "iter_children", return_value=iter(())), - mock.patch.object(chromium_script.web.Script, "onWindowDeactivated", return_value=False), - mock.patch.object(default.Script, "onWindowDeactivated") as defaultHandler, - ): - chromium_script.Script.onWindowDeactivated(testScript, event) - - defaultHandler.assert_called_once_with(testScript, event) - - def test_unmodified_arrow_deactivation_reaches_default(self): - testScript = self._make_chromium_script() - mainFrame = object() - comboBox = object() - app = object() - event = mock.Mock(source=mainFrame) - cthulhu_state.locusOfFocus = comboBox - testScript.utilities.lastKeyAndModifiers.return_value = ("Down", 0) - - with ( - mock.patch.object(chromium_script.AXUtilities, "is_combo_box", return_value=True), - mock.patch.object( - chromium_script.AXUtilities, - "supports_autocompletion", - return_value=True, - ), - mock.patch.object(chromium_script.AXObject, "get_application", return_value=app), - mock.patch.object(chromium_script.AXObject, "iter_children", return_value=iter(())), - mock.patch.object(chromium_script.web.Script, "onWindowDeactivated", return_value=False), - mock.patch.object(default.Script, "onWindowDeactivated") as defaultHandler, - ): - chromium_script.Script.onWindowDeactivated(testScript, event) - - defaultHandler.assert_called_once_with(testScript, event) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_compositor_state_adapter_regressions.py b/tests/test_compositor_state_adapter_regressions.py deleted file mode 100644 index a3f4c37..0000000 --- a/tests/test_compositor_state_adapter_regressions.py +++ /dev/null @@ -1,444 +0,0 @@ -import importlib -import sys -import types -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -import cthulhu as cthulhu_package - -from cthulhu import cthulhu_state -from cthulhu import compositor_state_adapter -from cthulhu import compositor_state_i3 -from cthulhu import compositor_state_types -from cthulhu import compositor_state_wayland - -stubCthulhu = types.ModuleType("cthulhu.cthulhu") -stubCthulhu.cthulhuApp = mock.Mock() -previousCthulhuModule = sys.modules.get("cthulhu.cthulhu") -sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu) - -from cthulhu import event_manager -from cthulhu.wayland_protocols import ext_workspace_v1 - -if previousCthulhuModule is None: - sys.modules.pop("cthulhu.cthulhu", None) - if getattr(cthulhu_package, "cthulhu", None) is stubCthulhu: - delattr(cthulhu_package, "cthulhu") - from cthulhu import cthulhu as restoredCthulhuModule -else: - sys.modules["cthulhu.cthulhu"] = previousCthulhuModule - cthulhu_package.cthulhu = previousCthulhuModule - restoredCthulhuModule = previousCthulhuModule - -event_manager.cthulhu = restoredCthulhuModule - - -class FakeWorkspaceBackend: - def __init__(self, available: bool, name: str) -> None: - self.available = available - self.name = name - self.activate_calls = [] - self.deactivate_calls = [] - self.refresh_calls = [] - - def is_available(self, session_type: str | None = None) -> bool: - return self.available - - def activate(self, emit_signal=None) -> None: - self.activate_calls.append(emit_signal) - - def deactivate(self, emit_signal=None) -> None: - self.deactivate_calls.append(emit_signal) - - def refresh_context(self, reason: str) -> None: - self.refresh_calls.append(reason) - - -class CompositorStateAdapterRegressionTests(unittest.TestCase): - def setUp(self) -> None: - cthulhu_state.compositorSnapshot = None - cthulhu_state.pauseAtspiChurn = False - cthulhu_state.prioritizedDesktopContextToken = None - cthulhu_state.activeWindow = None - cthulhu_state.locusOfFocus = None - - def test_activate_selects_first_available_backend(self) -> None: - unavailableBackend = FakeWorkspaceBackend(False, "unavailable") - selectedBackend = FakeWorkspaceBackend(True, "selected") - adapter = compositor_state_adapter.CompositorStateAdapter( - workspace_backends=[unavailableBackend, selectedBackend] - ) - - adapter.activate() - - self.assertEqual(unavailableBackend.activate_calls, []) - self.assertEqual(len(selectedBackend.activate_calls), 1) - self.assertTrue(callable(selectedBackend.activate_calls[0])) - self.assertEqual(adapter.get_snapshot().backend_name, "selected") - - def test_default_workspace_backends_include_i3_wayland_then_null_backend(self) -> None: - adapter = compositor_state_adapter.CompositorStateAdapter() - - backend_types = [type(backend) for backend in adapter._workspaceBackends] - - self.assertEqual( - backend_types, - [ - compositor_state_i3.I3WorkspaceBackend, - compositor_state_wayland.WaylandSharedProtocolsBackend, - compositor_state_wayland.NullWorkspaceBackend, - ], - ) - - def test_workspace_payload_records_i3_foreground_context(self) -> None: - backend = FakeWorkspaceBackend(True, "i3-ipc") - adapter = compositor_state_adapter.CompositorStateAdapter(workspace_backends=[backend]) - - adapter.activate() - backend.activate_calls[-1]( - compositor_state_types.WORKSPACE_STATE_CHANGED, - {"8"}, - "i3-window-focus", - { - "focused_window_id": 0x200000C, - "focused_window_title": "9 devel", - "focused_workspace_empty": False, - }, - ) - - snapshot = adapter.get_snapshot() - self.assertEqual(snapshot.active_workspace_ids, frozenset({"8"})) - self.assertEqual(snapshot.focused_window_id, 0x200000C) - self.assertEqual(snapshot.focused_window_title, "9 devel") - self.assertFalse(snapshot.focused_workspace_empty) - - def test_refresh_workspace_context_queries_selected_backend(self) -> None: - backend = FakeWorkspaceBackend(True, "i3-ipc") - adapter = compositor_state_adapter.CompositorStateAdapter(workspace_backends=[backend]) - adapter.activate() - - snapshot = adapter.refresh_workspace_context("xterm-handoff-check") - - self.assertEqual(backend.refresh_calls, ["xterm-handoff-check"]) - self.assertIs(snapshot, adapter.get_snapshot()) - - def test_confirmed_empty_workspace_clears_stale_accessible_context(self) -> None: - backend = FakeWorkspaceBackend(True, "i3-ipc") - adapter = compositor_state_adapter.CompositorStateAdapter(workspace_backends=[backend]) - adapter.activate() - adapter._snapshot = compositor_state_types.DesktopContextSnapshot( - session_type="x11", - backend_name="i3-ipc", - active_window_token="42:Browser", - locus_of_focus_token="42:Web content", - active_window_pid=42, - locus_of_focus_pid=42, - active_window_name="Browser", - locus_of_focus_name="Web content", - ) - - backend.activate_calls[-1]( - compositor_state_types.WORKSPACE_STATE_CHANGED, - {"9"}, - "i3-workspace-focus", - { - "focused_window_id": None, - "focused_window_title": "", - "focused_workspace_empty": True, - }, - ) - - snapshot = adapter.get_snapshot() - self.assertEqual(snapshot.active_window_token, "") - self.assertEqual(snapshot.locus_of_focus_token, "") - self.assertEqual(snapshot.active_window_pid, -1) - self.assertEqual(snapshot.locus_of_focus_pid, -1) - self.assertEqual(snapshot.active_window_name, "") - self.assertEqual(snapshot.locus_of_focus_name, "") - - def test_wayland_backend_is_unavailable_without_wayland_session(self) -> None: - backend = compositor_state_wayland.WaylandSharedProtocolsBackend() - - with mock.patch.dict(compositor_state_wayland.os.environ, {}, clear=True): - self.assertFalse(backend.is_available("x11")) - self.assertFalse(backend.is_available("wayland")) - - def test_wayland_backend_installs_dispatch_watch_and_processes_runtime_events(self) -> None: - fakeDisplay = mock.Mock() - fakeRegistry = mock.Mock() - fakeDisplay.connect = mock.Mock() - fakeDisplay.get_registry = mock.Mock(return_value=fakeRegistry) - fakeDisplay.get_fd = mock.Mock(return_value=17) - fakeDisplay.roundtrip = mock.Mock() - fakeDisplay.dispatch = mock.Mock(side_effect=[1, 0]) - fakeProtocols = mock.Mock() - fakeProtocols.INTERFACE_NAME = "ext_workspace_manager_v1" - fakeProtocols.INTERFACE_VERSION = 1 - fakeProtocols.ACTIVE_STATE_VALUE = 1 - fakeProtocols.has_runtime_support.return_value = True - fakeProtocols.get_display_class.return_value = mock.Mock(return_value=fakeDisplay) - emitSignal = mock.Mock() - backend = compositor_state_wayland.WaylandSharedProtocolsBackend( - environment={"WAYLAND_DISPLAY": "wayland-0"}, - protocols=fakeProtocols, - ) - - with ( - mock.patch.object(compositor_state_wayland, "get_session_type", return_value="wayland"), - mock.patch.object(compositor_state_wayland.GLib, "io_add_watch", return_value=41) as ioAddWatch, - mock.patch.object(compositor_state_wayland.GLib, "source_remove") as sourceRemove, - ): - backend.activate(emitSignal) - - ioAddWatch.assert_called_once() - watchCallback = ioAddWatch.call_args.args[3] - self.assertTrue(watchCallback(17, compositor_state_wayland.GLib.IO_IN)) - self.assertEqual(fakeDisplay.dispatch.call_count, 2) - - backend.deactivate() - - sourceRemove.assert_called_once_with(41) - - def test_wayland_backend_logs_activation_failure_reason(self) -> None: - fakeDisplay = mock.Mock() - fakeDisplay.connect.side_effect = ValueError("Unable to connect to display") - fakeProtocols = mock.Mock() - fakeProtocols.has_runtime_support.return_value = True - fakeProtocols.get_display_class.return_value = mock.Mock(return_value=fakeDisplay) - backend = compositor_state_wayland.WaylandSharedProtocolsBackend( - environment={"WAYLAND_DISPLAY": "wayland-0"}, - protocols=fakeProtocols, - ) - - with ( - mock.patch.object(compositor_state_wayland, "get_session_type", return_value="wayland"), - mock.patch.object(compositor_state_wayland.debug, "printMessage") as printMessage, - ): - backend.activate(mock.Mock()) - - printMessage.assert_any_call( - compositor_state_wayland.debug.LEVEL_WARNING, - mock.ANY, - True, - ) - self.assertIn("Unable to connect to display", printMessage.call_args_list[-1].args[1]) - self.assertIsNone(backend._display) - - def test_local_ext_workspace_wrapper_supports_base_pywayland_without_distro_protocol_module(self) -> None: - fakeClientModule = types.ModuleType("pywayland.client") - - class FakeDisplay: - pass - - fakeClientModule.Display = FakeDisplay - - def fake_import(moduleName: str, package=None): - if moduleName in ("pywayland.client", "pywayland.client.display"): - return fakeClientModule - raise ImportError(moduleName) - - try: - with mock.patch("importlib.import_module", side_effect=fake_import): - importlib.reload(ext_workspace_v1) - self.assertTrue(ext_workspace_v1.has_runtime_support()) - self.assertIs(ext_workspace_v1.get_display_class(), FakeDisplay) - self.assertIsNotNone(ext_workspace_v1.ExtWorkspaceManagerV1) - self.assertIsNotNone(ext_workspace_v1.ExtWorkspaceHandleV1) - self.assertEqual( - ext_workspace_v1.ExtWorkspaceManagerV1.interface_name, - "ext_workspace_manager_v1", - ) - self.assertEqual( - ext_workspace_v1.ExtWorkspaceHandleV1.interface_name, - "ext_workspace_handle_v1", - ) - finally: - importlib.reload(ext_workspace_v1) - - def test_wayland_backend_is_selected_when_available(self) -> None: - adapter = compositor_state_adapter.CompositorStateAdapter() - selected_backend = mock.Mock(name="selected-backend") - fallback_backend = mock.Mock(name="fallback-backend") - selected_backend.name = "wayland-shared-protocols" - selected_backend.is_available.return_value = True - fallback_backend.name = "null" - fallback_backend.is_available.return_value = True - adapter._workspaceBackends = [selected_backend, fallback_backend] - - adapter.activate() - - selected_backend.activate.assert_called_once() - fallback_backend.activate.assert_not_called() - self.assertTrue(callable(selected_backend.activate.call_args.args[0])) - self.assertEqual(adapter.get_snapshot().backend_name, "wayland-shared-protocols") - - def test_activate_is_idempotent_and_deactivates_previous_backend(self) -> None: - backend = FakeWorkspaceBackend(True, "selected") - adapter = compositor_state_adapter.CompositorStateAdapter(workspace_backends=[backend]) - - adapter.activate() - adapter.activate() - - self.assertEqual(len(backend.activate_calls), 2) - self.assertTrue(all(callable(call) for call in backend.activate_calls)) - self.assertEqual(len(backend.deactivate_calls), 1) - self.assertEqual(adapter.get_snapshot().backend_name, "selected") - - def test_sync_accessible_context_emits_focus_context_changed_when_active_window_token_changes(self) -> None: - adapter = compositor_state_adapter.CompositorStateAdapter() - events = [] - adapter.add_listener(events.append) - firstWindow = object() - secondWindow = object() - - def get_process_id(obj): - return 111 if obj is firstWindow else 222 - - def get_name(obj): - return "Terminal" - - with ( - mock.patch.object(compositor_state_adapter.AXObject, "get_process_id", side_effect=get_process_id), - mock.patch.object(compositor_state_adapter.AXObject, "get_name", side_effect=get_name), - ): - cthulhu_state.activeWindow = firstWindow - cthulhu_state.locusOfFocus = firstWindow - adapter.sync_accessible_context("startup") - - events.clear() - cthulhu_state.activeWindow = secondWindow - cthulhu_state.locusOfFocus = secondWindow - adapter.sync_accessible_context("workspace transition") - - self.assertIn( - compositor_state_types.DESKTOP_FOCUS_CONTEXT_CHANGED, - [event.type for event in events], - ) - self.assertIn( - compositor_state_types.PRIORITIZE_FOCUS, - [event.type for event in events], - ) - - def test_sync_accessible_context_builds_stable_active_window_tokens(self) -> None: - adapter = compositor_state_adapter.CompositorStateAdapter() - window = object() - - with ( - mock.patch.object(compositor_state_adapter.AXObject, "get_process_id", return_value=4242), - mock.patch.object(compositor_state_adapter.AXObject, "get_name", return_value="Terminal"), - ): - cthulhu_state.activeWindow = window - cthulhu_state.locusOfFocus = window - snapshot = adapter.sync_accessible_context("startup") - - self.assertEqual(snapshot.active_window_token, "4242:Terminal") - self.assertEqual(cthulhu_state.compositorSnapshot.active_window_token, "4242:Terminal") - - def test_workspace_backend_normalizes_initial_done_and_handoff(self) -> None: - adapter = compositor_state_adapter.CompositorStateAdapter(workspace_backends=[]) - events = [] - adapter.add_listener(events.append) - workspace = compositor_state_wayland.WaylandSharedProtocolsBackend() - first_workspace = mock.Mock() - second_workspace = mock.Mock() - first_workspace_token = f"workspace:{id(first_workspace)}" - - adapter._snapshot = compositor_state_types.DesktopContextSnapshot( - session_type="wayland", - backend_name="wayland-shared-protocols", - ) - - with mock.patch.object(workspace, "is_available", return_value=False): - workspace.activate(adapter._handle_workspace_signal) - workspace._handle_workspace_state(first_workspace, "active", True) - workspace._handle_workspace_manager_done() - - self.assertEqual( - [event.type for event in events], - [ - compositor_state_types.DESKTOP_TRANSITION_STARTED, - compositor_state_types.PAUSE_ATSPI_CHURN, - compositor_state_types.WORKSPACE_STATE_CHANGED, - compositor_state_types.DESKTOP_TRANSITION_FINISHED, - compositor_state_types.RESUME_ATSPI_CHURN, - compositor_state_types.FLUSH_STALE_ATSPI_EVENTS, - ], - ) - self.assertEqual(events[0].snapshot.active_workspace_ids, frozenset({first_workspace_token})) - self.assertTrue(events[0].snapshot.workspace_transition_pending) - self.assertEqual(events[2].snapshot.active_workspace_ids, frozenset({first_workspace_token})) - self.assertFalse(adapter.get_snapshot().workspace_transition_pending) - self.assertEqual(adapter.get_snapshot().active_workspace_ids, frozenset({first_workspace_token})) - self.assertEqual(cthulhu_state.compositorSnapshot.active_workspace_ids, frozenset({first_workspace_token})) - - events.clear() - workspace._handle_workspace_id(second_workspace, "ws-2") - workspace._handle_workspace_state(first_workspace, "active", False) - workspace._handle_workspace_state(second_workspace, "active", True) - workspace._handle_workspace_manager_done() - - event_types = [event.type for event in events] - - self.assertEqual( - event_types, - [ - compositor_state_types.DESKTOP_TRANSITION_STARTED, - compositor_state_types.PAUSE_ATSPI_CHURN, - compositor_state_types.WORKSPACE_STATE_CHANGED, - compositor_state_types.DESKTOP_TRANSITION_FINISHED, - compositor_state_types.RESUME_ATSPI_CHURN, - compositor_state_types.FLUSH_STALE_ATSPI_EVENTS, - ], - ) - self.assertTrue(events[0].snapshot.workspace_transition_pending) - self.assertEqual(events[0].snapshot.active_workspace_ids, frozenset()) - self.assertEqual(events[2].snapshot.active_workspace_ids, frozenset({"ws-2"})) - self.assertEqual(adapter.get_snapshot().active_workspace_ids, frozenset({"ws-2"})) - self.assertFalse(adapter.get_snapshot().workspace_transition_pending) - self.assertEqual(cthulhu_state.compositorSnapshot.active_workspace_ids, frozenset({"ws-2"})) - self.assertFalse(cthulhu_state.pauseAtspiChurn) - - def test_event_manager_startup_resyncs_adapter_after_focus_recovery(self) -> None: - adapter = mock.Mock() - adapter.sync_accessible_context = mock.Mock(return_value=None) - listener = mock.Mock() - fakeAtspi = types.SimpleNamespace( - EventListener=types.SimpleNamespace(new=mock.Mock(return_value=listener)), - ) - fakeCthulhu = types.SimpleNamespace( - setActiveWindow=mock.Mock(), - setLocusOfFocus=mock.Mock(), - ) - window = object() - focusedObject = object() - - with ( - mock.patch.object(event_manager, "Atspi", fakeAtspi), - mock.patch.object(event_manager.AXUtilities, "can_be_active_window", return_value=False), - mock.patch.object(event_manager.AXUtilities, "find_active_window", return_value=window), - mock.patch.object(event_manager.AXUtilities, "get_focused_object", return_value=focusedObject), - mock.patch.object(event_manager, "cthulhu", fakeCthulhu), - ): - manager = event_manager.EventManager(mock.Mock()) - manager.set_compositor_state_adapter(adapter) - manager._sync_focus_on_startup() - - fakeCthulhu.setActiveWindow.assert_called_once_with( - window, - alsoSetLocusOfFocus=True, - notifyScript=False, - ) - fakeCthulhu.setLocusOfFocus.assert_called_once_with( - None, - focusedObject, - notifyScript=True, - force=True, - ) - adapter.sync_accessible_context.assert_called_once_with("event-manager-startup") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_compositor_state_i3_regressions.py b/tests/test_compositor_state_i3_regressions.py deleted file mode 100644 index 3f80b14..0000000 --- a/tests/test_compositor_state_i3_regressions.py +++ /dev/null @@ -1,201 +0,0 @@ -import sys -import types -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import compositor_state_i3 -from cthulhu import compositor_state_types - - -class FakeNode: - def __init__( - self, - *, - node_type="con", - name="", - window=None, - window_title=None, - focused=False, - children=None, - ): - self.type = node_type - self.name = name - self.window = window - self.window_title = window_title - self.focused = focused - self.nodes = list(children or []) - self.floating_nodes = [] - self.parent = None - for child in self.nodes: - child.parent = self - - def __iter__(self): - pending = list(self.nodes) + list(self.floating_nodes) - while pending: - node = pending.pop(0) - yield node - pending.extend(node.nodes) - pending.extend(node.floating_nodes) - - def workspaces(self): - return [node for node in self if node.type == "workspace"] - - def find_focused(self): - if self.focused: - return self - return next((node for node in self if node.focused), None) - - def workspace(self): - node = self - while node is not None and node.type != "workspace": - node = node.parent - return node - - -class FakeWorkspaceReply: - def __init__(self, name, focused): - self.name = name - self.focused = focused - - -class FakeConnection: - def __init__(self, tree, workspaces): - self.tree = tree - self.workspaceReplies = workspaces - - def get_tree(self): - return self.tree - - def get_workspaces(self): - return self.workspaceReplies - - -class I3WorkspaceBackendRegressionTests(unittest.TestCase): - def test_query_reports_focused_window_id_title_and_nonempty_workspace(self): - focusedWindow = FakeNode( - name="AT-SPI misses this title", - window=0x200000C, - window_title="Accurate i3 title", - focused=True, - ) - workspace = FakeNode( - node_type="workspace", - name="8", - children=[focusedWindow], - ) - root = FakeNode(node_type="root", children=[workspace]) - connection = FakeConnection(root, [FakeWorkspaceReply("8", True)]) - backend = compositor_state_i3.I3WorkspaceBackend(i3ipc_module=types.SimpleNamespace()) - backend._connection = connection - - workspaceIds, payload = backend._query_context() - - self.assertEqual(workspaceIds, {"8"}) - self.assertEqual(payload["focused_window_id"], 0x200000C) - self.assertEqual(payload["focused_window_title"], "Accurate i3 title") - self.assertFalse(payload["focused_workspace_empty"]) - - def test_query_reports_confirmed_empty_focused_workspace(self): - workspace = FakeNode( - node_type="workspace", - name="9", - focused=True, - ) - root = FakeNode(node_type="root", children=[workspace]) - connection = FakeConnection(root, [FakeWorkspaceReply("9", True)]) - backend = compositor_state_i3.I3WorkspaceBackend(i3ipc_module=types.SimpleNamespace()) - backend._connection = connection - - workspaceIds, payload = backend._query_context() - - self.assertEqual(workspaceIds, {"9"}) - self.assertIsNone(payload["focused_window_id"]) - self.assertEqual(payload["focused_window_title"], "") - self.assertTrue(payload["focused_workspace_empty"]) - - def test_refresh_emits_started_state_and_finished_with_foreground_payload(self): - backend = compositor_state_i3.I3WorkspaceBackend(i3ipc_module=types.SimpleNamespace()) - backend._active = True - backend._emitSignal = mock.Mock() - payload = { - "focused_window_id": None, - "focused_window_title": "", - "focused_workspace_empty": True, - } - - with mock.patch.object(backend, "_query_context", return_value=({"9"}, payload)): - self.assertFalse(backend._refresh_context("workspace-focus", transition=True)) - - self.assertEqual( - backend._emitSignal.call_args_list, - [ - mock.call( - compositor_state_types.DESKTOP_TRANSITION_STARTED, - {"9"}, - "workspace-focus", - payload, - ), - mock.call( - compositor_state_types.WORKSPACE_STATE_CHANGED, - {"9"}, - "workspace-focus", - payload, - ), - mock.call( - compositor_state_types.DESKTOP_TRANSITION_FINISHED, - {"9"}, - "workspace-focus", - payload, - ), - ], - ) - - def test_public_refresh_emits_updated_context_without_transition(self) -> None: - backend = compositor_state_i3.I3WorkspaceBackend(i3ipc_module=types.SimpleNamespace()) - backend._active = True - backend._emitSignal = mock.Mock() - payload = { - "focused_window_id": 0x2600003, - "focused_window_title": "Browser", - "focused_workspace_empty": False, - } - - with mock.patch.object(backend, "_query_context", return_value=({"8"}, payload)): - backend.refresh_context("xterm-handoff-check") - - backend._emitSignal.assert_called_once_with( - compositor_state_types.WORKSPACE_STATE_CHANGED, - {"8"}, - "xterm-handoff-check", - payload, - ) - - def test_query_failure_emits_unknown_instead_of_preserving_stale_i3_context(self): - backend = compositor_state_i3.I3WorkspaceBackend(i3ipc_module=types.SimpleNamespace()) - backend._active = True - backend._emitSignal = mock.Mock() - backend._lastContext = (frozenset({"8"}), 0x200000C, "Browser", False) - - with ( - mock.patch.object(backend, "_query_context", side_effect=OSError("IPC disconnected")), - mock.patch.object(compositor_state_i3.debug, "printMessage"), - ): - self.assertFalse(backend._refresh_context("window-focus", transition=True)) - - backend._emitSignal.assert_called_once_with( - compositor_state_types.WORKSPACE_STATE_CHANGED, - set(), - "window-focus: i3-context-unknown", - { - "focused_window_id": None, - "focused_window_title": "", - "focused_workspace_empty": None, - }, - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_cthulhu_remote_plugin.py b/tests/test_cthulhu_remote_plugin.py deleted file mode 100644 index 17ffab2..0000000 --- a/tests/test_cthulhu_remote_plugin.py +++ /dev/null @@ -1,173 +0,0 @@ -import sys -import types -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -import cthulhu as cthulhuPackage - -missingModule = object() -previousInputEventManagerModule = sys.modules.get( - "cthulhu.input_event_manager", - missingModule, -) -previousInputEventManagerAttribute = getattr( - cthulhuPackage, - "input_event_manager", - missingModule, -) -previousPluginSystemManagerModule = sys.modules.get( - "cthulhu.plugin_system_manager", - missingModule, -) -previousPluginSystemManagerAttribute = getattr( - cthulhuPackage, - "plugin_system_manager", - missingModule, -) -inputEventManagerStub = types.ModuleType("cthulhu.input_event_manager") -inputEventManagerStub.get_manager = mock.Mock(return_value=mock.Mock()) -sys.modules["cthulhu.input_event_manager"] = inputEventManagerStub -cthulhuPackage.input_event_manager = inputEventManagerStub - -try: - from cthulhu import plugin_system_manager - from cthulhu import cthulhu_state - from cthulhu import speech - from cthulhu.plugin_system_manager import PluginSystemManager - from cthulhu.plugins.CthulhuRemote.connection_info import ConnectionInfo, ConnectionMode - from cthulhu.plugins.CthulhuRemote.local_machine import LocalMachine - from cthulhu.plugins.CthulhuRemote.plugin import CthulhuRemote - from cthulhu.plugins.CthulhuRemote.protocol import RemoteMessageType - from cthulhu.plugins.CthulhuRemote.serializer import JSONSerializer -finally: - if previousInputEventManagerModule is missingModule: - sys.modules.pop("cthulhu.input_event_manager", None) - else: - sys.modules["cthulhu.input_event_manager"] = previousInputEventManagerModule - - if previousInputEventManagerAttribute is missingModule: - delattr(cthulhuPackage, "input_event_manager") - else: - cthulhuPackage.input_event_manager = previousInputEventManagerAttribute - - if previousPluginSystemManagerModule is missingModule: - sys.modules.pop("cthulhu.plugin_system_manager", None) - else: - sys.modules["cthulhu.plugin_system_manager"] = previousPluginSystemManagerModule - - if previousPluginSystemManagerAttribute is missingModule: - delattr(cthulhuPackage, "plugin_system_manager") - else: - cthulhuPackage.plugin_system_manager = previousPluginSystemManagerAttribute - - -class CthulhuRemotePluginTests(unittest.TestCase): - def test_connection_info_accepts_nvda_remote_style_fields(self): - info = ConnectionInfo.from_url("cthulhuremote://example.com:1234?key=abc&mode=slave") - - self.assertEqual(info.hostname, "example.com") - self.assertEqual(info.port, 1234) - self.assertEqual(info.key, "abc") - self.assertEqual(info.mode, ConnectionMode.SLAVE) - self.assertEqual( - info.get_url_to_connect(), - "cthulhuremote://example.com:1234?key=abc&mode=master", - ) - - def test_json_serializer_uses_remote_message_type_values(self): - serializer = JSONSerializer() - - payload = serializer.deserialize(serializer.serialize(RemoteMessageType.join, channel="abc")) - - self.assertEqual(payload["type"], "join") - self.assertEqual(payload["channel"], "abc") - - def test_local_machine_maps_common_windows_vk_codes_to_keyvals(self): - machine = LocalMachine(lambda message: None) - - self.assertEqual(machine._resolve_keyval(0x41, None), machine._resolve_keyval(None, "a")) - self.assertEqual(machine._resolve_keyval(0x70, None), machine._resolve_keyval(None, "F1")) - self.assertIsNone(machine._resolve_keyval(0xFF, None)) - - def test_speech_monitor_callbacks_are_additive(self): - primary = mock.Mock() - listener = mock.Mock() - speech.set_monitor_callbacks(writeText=primary) - speech.add_monitor_callback(listener) - self.addCleanup(speech.set_monitor_callbacks, None) - self.addCleanup(speech.remove_monitor_callback, listener) - - speech._write_to_monitor("status") - - primary.assert_called_once_with("status") - listener.assert_called_once_with("status") - - def test_remote_speech_does_not_echo_to_monitor_callbacks(self): - listener = mock.Mock() - speech.add_monitor_callback(listener) - self.addCleanup(speech.remove_monitor_callback, listener) - - with ( - mock.patch.object(speech, "_speechserver", None), - mock.patch.object(speech.speech_history, "add"), - mock.patch.object(cthulhu_state, "activeScript", None), - ): - LocalMachine(lambda message: None).speak(["remote", "status"]) - - listener.assert_not_called() - - def test_slave_mode_forwards_local_speech_to_relay(self): - plugin = CthulhuRemote() - plugin._connectionInfo = ConnectionInfo( - hostname="example.com", - port=1234, - key="abc", - mode=ConnectionMode.SLAVE, - ) - plugin._transport = mock.Mock() - plugin._transport.connected = True - - plugin._send_local_speech("focused button") - - plugin._transport.send.assert_called_once_with( - RemoteMessageType.speak, - sequence=["focused button"], - ) - - def test_master_mode_does_not_forward_local_speech_to_relay(self): - plugin = CthulhuRemote() - plugin._connectionInfo = ConnectionInfo( - hostname="example.com", - port=1234, - key="abc", - mode=ConnectionMode.MASTER, - ) - plugin._transport = mock.Mock() - plugin._transport.connected = True - - plugin._send_local_speech("local status") - - plugin._transport.send.assert_not_called() - - @mock.patch("cthulhu.plugin_system_manager.dbus_service.get_remote_controller") - def test_plugin_manager_can_load_cthulhu_remote(self, remote_controller): - remote_controller.return_value = mock.Mock() - app = mock.Mock() - app.getSignalManager.return_value = mock.Mock() - app.getAPIHelper.return_value = None - manager = PluginSystemManager(app) - manager.rescanPlugins() - plugin_info = manager._resolve_plugin_info("CthulhuRemote") - - self.assertIsNotNone(plugin_info) - self.assertTrue(manager.loadPlugin(plugin_info)) - - self.assertEqual(plugin_info.instance.__class__.__name__, "CthulhuRemote") - self.assertTrue(manager.unloadPlugin(plugin_info)) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_dbus_service_native_interfaces.py b/tests/test_dbus_service_native_interfaces.py deleted file mode 100644 index 9d4c844..0000000 --- a/tests/test_dbus_service_native_interfaces.py +++ /dev/null @@ -1,361 +0,0 @@ -import unittest -from unittest import mock - -from cthulhu import dbus_service - - -class SampleModule: - def __init__(self): - self.enabled = False - self.calls = [] - - @dbus_service.command - def toggle_feature(self, script=None, event=None, notify_user=True): - """Toggles the test feature.""" - self.calls.append((script, event, notify_user)) - return True - - @dbus_service.command - def command_without_notify(self, script=None, event=None): - """Runs a command that does not accept notify_user.""" - self.calls.append((script, event)) - return True - - @dbus_service.command - def list_items(self) -> "list[str]": - """Returns a list from a command.""" - return ["alpha", "beta"] - - @dbus_service.parameterized_command - def speak_text( - self, - text: "str", - count: "int" = 1, - script=None, - event=None, - notify_user=True, - ) -> "str": - """Speaks text a number of times.""" - self.calls.append((text, count, script, event, notify_user)) - return text * count - - @dbus_service.getter - def get_enabled(self) -> "bool": - """Returns whether the feature is enabled.""" - return self.enabled - - @dbus_service.setter - def set_enabled(self, value: "bool"): - """Sets whether the feature is enabled.""" - self.enabled = value - - -class NativeInterfaceBuilderTest(unittest.TestCase): - def test_registration_groups_decorated_members_by_native_names(self): - registration = dbus_service._ModuleRegistration.from_module_instance( - "TestModule", SampleModule() - ) - - self.assertIn("ToggleFeature", registration.get_commands()) - self.assertIn("SpeakText", registration.get_parameterized_commands()) - self.assertIn("Enabled", registration.get_getters()) - self.assertIn("Enabled", registration.get_setters()) - self.assertEqual(registration.total_member_count(), 6) - - def test_interface_builder_exposes_methods_and_properties(self): - registration = dbus_service._ModuleRegistration.from_module_instance( - "TestModule", SampleModule() - ) - interface_class = dbus_service._InterfaceBuilder.build(registration) - - self.assertTrue(hasattr(interface_class, "ToggleFeature")) - self.assertTrue(hasattr(interface_class, "CommandWithoutNotify")) - self.assertTrue(hasattr(interface_class, "ListItems")) - self.assertTrue(hasattr(interface_class, "SpeakText")) - self.assertIsInstance(interface_class.Enabled, property) - self.assertFalse(hasattr(interface_class, "ExecuteCommand")) - self.assertIn("org.stormux.Cthulhu1.TestModule", interface_class.__dbus_xml__) - - def test_generated_command_method_uses_active_or_default_script(self): - module = SampleModule() - registration = dbus_service._ModuleRegistration.from_module_instance("TestModule", module) - interface = dbus_service._InterfaceBuilder.build(registration)() - script = mock.Mock() - manager = mock.Mock() - manager.get_active_script.return_value = None - manager.get_default_script.return_value = script - event_manager = mock.Mock() - event_manager_module = mock.Mock() - event_manager_module.get_manager.return_value = event_manager - - with ( - mock.patch.object(dbus_service.script_manager, "get_manager", return_value=manager), - mock.patch.object( - dbus_service, "_get_input_event_manager", return_value=event_manager_module - ), - ): - self.assertTrue(interface.ToggleFeature(False)) - self.assertTrue(interface.CommandWithoutNotify(False)) - self.assertEqual(interface.ListItems(False), ["alpha", "beta"]) - - self.assertEqual(module.calls[0][0], script) - self.assertFalse(module.calls[0][2]) - self.assertEqual(module.calls[1][0], script) - self.assertEqual(event_manager.process_remote_controller_event.call_count, 3) - - def test_generated_properties_call_getters_and_setters(self): - module = SampleModule() - registration = dbus_service._ModuleRegistration.from_module_instance("TestModule", module) - interface = dbus_service._InterfaceBuilder.build(registration)() - - self.assertFalse(interface.Enabled) - interface.Enabled = True - self.assertTrue(module.enabled) - self.assertTrue(interface.Enabled) - - -class NativeRemoteControllerTest(unittest.TestCase): - def test_controller_uses_versioned_service_name_and_object_path(self): - self.assertEqual(dbus_service.CthulhuRemoteController.SERVICE_NAME, "org.stormux.Cthulhu1.Service") - self.assertEqual(dbus_service.CthulhuRemoteController.OBJECT_PATH, "/org/stormux/Cthulhu1/Service") - - @mock.patch("cthulhu.speech.speak") - def test_speak_text_uses_direct_speech_output(self, speak): - interface = dbus_service.CthulhuDBusServiceInterface() - - self.assertTrue(interface.SpeakText("hello", True)) - speak.assert_called_once_with("hello", interrupt=True) - - @mock.patch("cthulhu.braille.displayMessage") - def test_braille_message_uses_persistent_flash(self, display_message): - interface = dbus_service.CthulhuDBusServiceInterface() - - self.assertTrue(interface.BrailleMessage("hello")) - display_message.assert_called_once_with("hello", flashTime=-1) - - @mock.patch("cthulhu.speech.stop") - def test_cancel_speech_stops_output(self, stop): - interface = dbus_service.CthulhuDBusServiceInterface() - - self.assertTrue(interface.CancelSpeech()) - stop.assert_called_once_with() - - def test_ssml_fails_closed(self): - interface = dbus_service.CthulhuDBusServiceInterface() - - self.assertEqual(interface.SpeakSsml("request", "Hello"), 50) - self.assertEqual(interface.SpeakSsml("request", "not xml"), 87) - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_event_normalizes_useful_fields(self, present_message): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - - result = interface.PresentAccessibleEvent( - "source", "focus", "Open", "button", "", "focused", "", 2, 4, "Settings" - ) - - self.assertTrue(result) - present_message.assert_not_called() - interface._present_pending_accessible_focus() - present_message.assert_called_once_with("Open, button, 2 of 4, Settings") - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_event_ignores_changes_from_unfocused_objects(self, present_message): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - interface.PresentAccessibleEvent( - "control-1", "focus", "Open", "button", "", "", "", 0, 0, "Settings" - ) - present_message.reset_mock() - - result = interface.PresentAccessibleEvent( - "control-2", "value", "Cancel", "button", "", "", "", 0, 0, "Settings" - ) - - self.assertFalse(result) - present_message.assert_not_called() - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_event_presents_focused_value_changes_without_repeating_title( - self, present_message - ): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - interface.PresentAccessibleEvent( - "control-1", "focus", "Version", "combo box", "Windows 10", "", "", 0, 0, - "Wine configuration" - ) - interface._present_pending_accessible_focus() - present_message.reset_mock() - - result = interface.PresentAccessibleEvent( - "control-1", "value", "Version", "combo box", "Windows 11", "", "", 0, 0, - "Wine configuration" - ) - - self.assertTrue(result) - present_message.assert_called_once_with("Version, combo box, Windows 11") - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_event_suppresses_immediate_duplicates(self, present_message): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - - first = interface.PresentAccessibleEvent( - "control-1", "focus", "OK", "button", "", "", "", 0, 0, "Settings" - ) - interface._present_pending_accessible_focus() - second = interface.PresentAccessibleEvent( - "control-1", "focus", "OK", "button", "", "", "", 0, 0, "Settings" - ) - - self.assertTrue(first) - self.assertFalse(second) - present_message.assert_called_once_with("OK, button, Settings") - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_focus_burst_presents_only_final_control(self, present_message): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - - interface.PresentAccessibleEvent( - "control-1", "focus", "Add application", "button", "", "", "", 0, 0, - "Wine configuration" - ) - interface.PresentAccessibleEvent( - "control-2", "focus", "OK", "button", "", "", "", 0, 0, - "Wine configuration" - ) - interface.PresentAccessibleEvent( - "control-1", "focus", "Add application", "button", "", "", "", 0, 0, - "Wine configuration" - ) - - present_message.assert_not_called() - interface._present_pending_accessible_focus() - present_message.assert_called_once_with( - "Add application, button, Wine configuration" - ) - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_focus_duplicate_clears_stale_pending_focus(self, present_message): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - interface.PresentAccessibleEvent( - "control-1", "focus", "Open", "button", "", "", "", 0, 0, - "Settings" - ) - interface._present_pending_accessible_focus() - present_message.reset_mock() - - interface.PresentAccessibleEvent( - "control-2", "focus", "Cancel", "button", "", "", "", 0, 0, - "Settings" - ) - duplicate = interface.PresentAccessibleEvent( - "control-1", "focus", "Open", "button", "", "", "", 0, 0, - "Settings" - ) - interface._present_pending_accessible_focus() - - self.assertFalse(duplicate) - self.assertEqual(interface._wineAccessibleFocusSource, "control-1") - present_message.assert_not_called() - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_focus_presents_new_window_title_without_control_fields( - self, present_message - ): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - - result = interface.PresentAccessibleEvent( - "window", "focus", "", "", "", "", "", 0, 0, "Wine configuration" - ) - interface._present_pending_accessible_focus() - - self.assertTrue(result) - present_message.assert_called_once_with("Wine configuration") - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_event_omits_generic_client_role(self, present_message): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - - interface.PresentAccessibleEvent( - "control-1", "focus", "OK", "client", "", "", "", 0, 0, "Settings" - ) - interface._present_pending_accessible_focus() - - present_message.assert_called_once_with("OK, Settings") - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_event_ignores_name_and_state_noise_on_focused_object( - self, present_message - ): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - interface.PresentAccessibleEvent( - "control-1", "focus", "Windows 10", "client", "", "", "", 0, 0, - "Wine configuration" - ) - interface._present_pending_accessible_focus() - present_message.reset_mock() - - name_result = interface.PresentAccessibleEvent( - "control-1", "name", "OK", "client", "", "", "", 0, 0, - "Wine configuration" - ) - state_result = interface.PresentAccessibleEvent( - "control-1", "state", "OK", "client", "", "focused", "", 0, 0, - "Wine configuration" - ) - - self.assertFalse(name_result) - self.assertFalse(state_result) - present_message.assert_not_called() - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_event_accepts_selection_from_focused_combo_child( - self, present_message - ): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - interface.PresentAccessibleEvent( - "combo", "focus", "Windows 10", "client", "", "", "", 0, 0, - "Wine configuration" - ) - interface._present_pending_accessible_focus() - present_message.reset_mock() - - result = interface.PresentAccessibleEvent( - "combo-item-2", "selection", "Windows 8.1", "client", "", "", "", 0, 0, - "Wine configuration" - ) - - self.assertTrue(result) - present_message.assert_called_once_with("Windows 8.1") - - @mock.patch.object(dbus_service.CthulhuDBusServiceInterface, "PresentMessage") - def test_accessible_event_rejects_selection_from_other_window(self, present_message): - present_message.return_value = True - interface = dbus_service.CthulhuDBusServiceInterface() - interface.PresentAccessibleEvent( - "combo", "focus", "Windows 10", "client", "", "", "", 0, 0, - "Wine configuration" - ) - interface._present_pending_accessible_focus() - present_message.reset_mock() - - result = interface.PresentAccessibleEvent( - "other-item", "selection", "Unrelated", "client", "", "", "", 0, 0, - "Other window" - ) - - self.assertFalse(result) - present_message.assert_not_called() - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_debug_startup_timing.py b/tests/test_debug_startup_timing.py deleted file mode 100644 index ba57be2..0000000 --- a/tests/test_debug_startup_timing.py +++ /dev/null @@ -1,79 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import debug - - -class DebugStartupTimingTests(unittest.TestCase): - def setUp(self) -> None: - self._debugLevel = debug.debugLevel - self._startupTimingEnabled = debug.startupTimingEnabled - self._startupTimingStartTime = debug._startupTimingStartTime - self._startupTimingLastTime = debug._startupTimingLastTime - debug.debugLevel = debug.LEVEL_SEVERE - debug.startupTimingEnabled = False - debug._startupTimingStartTime = None - debug._startupTimingLastTime = None - - def tearDown(self) -> None: - debug.debugLevel = self._debugLevel - debug.startupTimingEnabled = self._startupTimingEnabled - debug._startupTimingStartTime = self._startupTimingStartTime - debug._startupTimingLastTime = self._startupTimingLastTime - - def test_startup_timing_is_silent_when_disabled_and_debug_is_not_enabled(self) -> None: - with mock.patch.object(debug, "println") as println: - debug.print_startup_timing("hidden phase") - - println.assert_not_called() - - def test_startup_timing_logs_when_explicitly_enabled(self) -> None: - with mock.patch.object(debug.time, "monotonic", side_effect=[10.0, 10.25]): - debug.set_startup_timing_enabled(True) - with mock.patch.object(debug, "println") as println: - debug.print_startup_timing("explicit phase") - - println.assert_called_once_with( - debug.LEVEL_SEVERE, - "STARTUP TIMING: explicit phase: +0.250s, total 0.250s", - True, - False, - ) - - def test_startup_timing_logs_when_debug_output_is_enabled(self) -> None: - debug.debugLevel = debug.LEVEL_INFO - with mock.patch.object(debug.time, "monotonic", return_value=20.0): - with mock.patch.object(debug, "println") as println: - debug.print_startup_timing("debug phase") - - println.assert_called_once_with( - debug.LEVEL_INFO, - "STARTUP TIMING: debug phase: +0.000s, total 0.000s", - True, - False, - ) - - def test_startup_timing_context_logs_start_and_end(self) -> None: - with mock.patch.object(debug.time, "monotonic", side_effect=[30.0, 30.1, 30.4]): - debug.set_startup_timing_enabled(True) - with mock.patch.object(debug, "println") as println: - with debug.startup_timing("wrapped phase"): - pass - - self.assertEqual(2, println.call_count) - self.assertEqual( - "STARTUP TIMING: wrapped phase start: +0.100s, total 0.100s", - println.call_args_list[0].args[1], - ) - self.assertEqual( - "STARTUP TIMING: wrapped phase end: +0.300s, total 0.400s", - println.call_args_list[1].args[1], - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_default_script_clipboard_regressions.py b/tests/test_default_script_clipboard_regressions.py deleted file mode 100644 index 92899a3..0000000 --- a/tests/test_default_script_clipboard_regressions.py +++ /dev/null @@ -1,472 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - -gi.require_version("Atspi", "2.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from gi.repository import Atspi - -from cthulhu import messages -from cthulhu.scripts import default - - -CONTROL_MASK = 1 << Atspi.ModifierType.CONTROL - - -class FakeKeyboardEvent: - def __init__(self, pressed, keyval_name, modifiers, obj, event_string=None): - self._pressed = pressed - self.keyval_name = keyval_name - self.modifiers = modifiers - self._obj = obj - self.event_string = keyval_name if event_string is None else event_string - - def get_object(self): - return self._obj - - def is_pressed_key(self): - return self._pressed - - -def run_repeating_timeout(_delay, callback, generation, max_checks=10): - for _ in range(max_checks): - if not callback(generation): - break - - -class DefaultScriptClipboardRegressionTests(unittest.TestCase): - def _make_script(self): - script = object.__new__(default.Script) - script.utilities = mock.Mock() - script.presentMessage = mock.Mock() - script.flatReviewPresenter = mock.Mock() - script.flatReviewPresenter.is_active.return_value = False - script._pendingKeyboardClipboardCommand = None - script._pendingKeyboardClipboardRelease = None - script._keyboardClipboardCommandGeneration = 0 - script._sessionType = "x11" - return script - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_keyboard_copy_fallback_presents_message_when_callback_never_arrives( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", "copied text"] - script.utilities.objectContentsAreInClipboard.return_value = True - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - - script.utilities.objectContentsAreInClipboard.assert_called_once_with(source) - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=run_repeating_timeout, - ) - def test_keyboard_copy_fallback_uses_captured_selection_when_clipboard_stays_empty( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before"] + [""] * 10 - script.utilities.allSelectedText.return_value = ("The quick brown", 0, 15) - script.utilities.selectedText.return_value = ("The quick brown", 0, 15) - script.utilities.objectContentsAreInClipboard.return_value = False - script.utilities.isInActiveApp.return_value = False - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_keyboard_copy_fallback_handles_release_before_press_order( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", ""] - script.utilities.allSelectedText.return_value = ("3086180", 0, 7) - script.utilities.selectedText.return_value = ("3086180", 0, 7) - script.utilities.objectContentsAreInClipboard.return_value = False - script.utilities.isInActiveApp.return_value = False - - script.updateKeyboardEventState( - FakeKeyboardEvent(False, "0x3", CONTROL_MASK, source, "\x03"), - None, - ) - script.updateKeyboardEventState( - FakeKeyboardEvent(True, "0x3", CONTROL_MASK, source, "\x03"), - None, - ) - - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch("cthulhu.scripts.default.GLib.idle_add") - @mock.patch("cthulhu.scripts.default.GLib.timeout_add") - def test_wayland_keyboard_copy_is_presented_immediately( - self, - timeout_add, - idle_add, - _is_terminal, - ): - script = self._make_script() - script._sessionType = "wayland" - source = object() - script.utilities.getClipboardContents.return_value = "" - script.utilities.allSelectedText.return_value = ("The quick brown", 0, 15) - script.utilities.selectedText.return_value = ("The quick brown", 0, 15) - script.utilities.objectContentsAreInClipboard.return_value = False - script.utilities.isInActiveApp.return_value = False - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - - timeout_add.assert_not_called() - idle_add.assert_called_once() - script.presentMessage.assert_not_called() - - callback, generation = idle_add.call_args.args - callback(generation) - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch("cthulhu.scripts.default.GLib.idle_add") - @mock.patch("cthulhu.scripts.default.GLib.timeout_add") - def test_wayland_keyboard_copy_handles_release_before_press_order_immediately( - self, - timeout_add, - idle_add, - _is_terminal, - ): - script = self._make_script() - script._sessionType = "wayland" - source = object() - script.utilities.getClipboardContents.return_value = "" - script.utilities.allSelectedText.return_value = ("3086180", 0, 7) - script.utilities.selectedText.return_value = ("3086180", 0, 7) - script.utilities.objectContentsAreInClipboard.return_value = False - script.utilities.isInActiveApp.return_value = False - - script.updateKeyboardEventState( - FakeKeyboardEvent(False, "0x3", CONTROL_MASK, source, "\x03"), - None, - ) - script.updateKeyboardEventState( - FakeKeyboardEvent(True, "0x3", CONTROL_MASK, source, "\x03"), - None, - ) - - timeout_add.assert_not_called() - idle_add.assert_called_once() - script.presentMessage.assert_not_called() - - callback, generation = idle_add.call_args.args - callback(generation) - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_keyboard_copy_fallback_recognizes_control_character_key_name( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", "copied text"] - script.utilities.objectContentsAreInClipboard.return_value = True - - script.updateKeyboardEventState( - FakeKeyboardEvent(True, "0x3", CONTROL_MASK, source, "\x03"), - None, - ) - script.updateKeyboardEventState( - FakeKeyboardEvent(False, "0x3", CONTROL_MASK, source, "\x03"), - None, - ) - - script.utilities.objectContentsAreInClipboard.assert_called_once_with(source) - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_keyboard_copy_fallback_uses_captured_source_not_current_focus( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", "copied text"] - script.utilities.objectContentsAreInClipboard.return_value = True - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, object()), None) - - script.utilities.objectContentsAreInClipboard.assert_called_once_with(source) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_keyboard_copy_fallback_stays_silent_if_clipboard_is_unchanged( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["same text", "same text"] - script.utilities.objectContentsAreInClipboard.return_value = False - script.utilities.isInActiveApp.return_value = True - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - - self.assertEqual( - script.utilities.objectContentsAreInClipboard.call_args_list, - [mock.call(source), mock.call()], - ) - script.presentMessage.assert_not_called() - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_keyboard_copy_fallback_presents_when_clipboard_unchanged_but_matches_source( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["same text", "same text"] - script.utilities.objectContentsAreInClipboard.return_value = True - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - - script.utilities.objectContentsAreInClipboard.assert_called_once_with(source) - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_keyboard_copy_fallback_uses_current_focus_when_captured_source_no_longer_matches( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", "copied text"] - script.utilities.objectContentsAreInClipboard.side_effect = [False, True] - script.utilities.isInActiveApp.return_value = True - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - - self.assertEqual( - script.utilities.objectContentsAreInClipboard.call_args_list, - [mock.call(source), mock.call()], - ) - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_keyboard_copy_fallback_does_not_probe_current_focus_when_source_left_active_app( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", "copied text"] - script.utilities.objectContentsAreInClipboard.return_value = False - script.utilities.isInActiveApp.return_value = False - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - - script.utilities.objectContentsAreInClipboard.assert_called_once_with(source) - script.presentMessage.assert_not_called() - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=run_repeating_timeout, - ) - def test_keyboard_copy_fallback_retries_until_clipboard_match_appears( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", "before", "copied text"] - script.utilities.objectContentsAreInClipboard.side_effect = [False, True] - script.utilities.isInActiveApp.return_value = False - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - - self.assertEqual( - script.utilities.objectContentsAreInClipboard.call_args_list, - [mock.call(source), mock.call(source)], - ) - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_keyboard_copy_fallback_uses_captured_selected_text_when_live_selection_clears( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", "copied text"] - script.utilities.allSelectedText.return_value = ("copied text", 0, 11) - script.utilities.selectedText.return_value = ("", 0, 0) - script.utilities.objectContentsAreInClipboard.return_value = False - script.utilities.isInActiveApp.return_value = False - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_clipboard_callback_after_fallback_does_not_duplicate_message( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", "copied text", "copied text"] - script.utilities.objectContentsAreInClipboard.return_value = True - script.utilities.topLevelObjectIsActiveAndCurrent.return_value = True - script.utilities.lastInputEventWasCopy.return_value = True - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - script.onClipboardContentsChanged() - - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - @mock.patch("cthulhu.scripts.default.AXUtilities.is_terminal", return_value=False) - @mock.patch( - "cthulhu.scripts.default.GLib.timeout_add", - side_effect=lambda _delay, callback, generation: callback(generation), - ) - def test_clipboard_callback_without_match_does_not_cancel_keyboard_fallback( - self, - _timeout_add, - _is_terminal, - ): - script = self._make_script() - source = object() - script.utilities.getClipboardContents.side_effect = ["before", "copied text", "copied text"] - script.utilities.objectContentsAreInClipboard.side_effect = [False, False, True] - script.utilities.isInActiveApp.return_value = False - - script.updateKeyboardEventState(FakeKeyboardEvent(True, "c", CONTROL_MASK, source), None) - script.onClipboardContentsChanged() - script.updateKeyboardEventState(FakeKeyboardEvent(False, "c", CONTROL_MASK, source), None) - - self.assertEqual( - script.utilities.objectContentsAreInClipboard.call_args_list, - [mock.call(source), mock.call(), mock.call(source)], - ) - script.presentMessage.assert_called_once_with( - messages.CLIPBOARD_COPIED_FULL, - messages.CLIPBOARD_COPIED_BRIEF, - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_default_script_shutdown_regressions.py b/tests/test_default_script_shutdown_regressions.py deleted file mode 100644 index aba083d..0000000 --- a/tests/test_default_script_shutdown_regressions.py +++ /dev/null @@ -1,32 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import cthulhu_state -from cthulhu.scripts import default - - -class DefaultScriptShutdownRegressionTests(unittest.TestCase): - def test_remove_key_grabs_clears_tracking_without_touching_dead_device(self): - script = object.__new__(default.Script) - script.grab_ids = [474, 475] - script._modifierGrabIds = [("Insert", 99)] - - with ( - mock.patch.object(cthulhu_state, "device", None), - mock.patch("cthulhu.scripts.default.cthulhu.removeKeyGrab") as removeKeyGrab, - mock.patch("cthulhu.scripts.default.input_event_manager.get_manager") as getManager, - ): - script.removeKeyGrabs() - - removeKeyGrab.assert_not_called() - getManager.assert_not_called() - self.assertEqual(script.grab_ids, []) - self.assertEqual(script._modifierGrabIds, []) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_document_selection_regressions.py b/tests/test_document_selection_regressions.py deleted file mode 100644 index ad33471..0000000 --- a/tests/test_document_selection_regressions.py +++ /dev/null @@ -1,229 +0,0 @@ -import sys -import types -import unittest -from contextlib import ExitStack -from pathlib import Path -from unittest import mock - -import gi - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -sys.modules.setdefault( - "cthulhu.cthulhu_i18n", - types.SimpleNamespace( - C_=lambda _context, message: message, - _=lambda message: message, - ngettext=lambda singular, plural, count: singular if count == 1 else plural, - ), -) -sys.modules.setdefault( - "cthulhu.cthulhu_platform", - types.SimpleNamespace( - version="test", - revision="", - tablesdir="", - datadir="", - ), -) - -from cthulhu import ax_document_selection -from cthulhu.script_utilities import Utilities - - -class FakeDocument: - def __init__(self): - self.currentSelections = [] - self.setCalls = [] - - -class FakeTextObject: - def __init__(self, name, text, document): - self.name = name - self.text = text - self.document = document - self.next_obj = None - self.prev_obj = None - self.caret_offset = 0 - - def __repr__(self): - return f"" - - -class DocumentSelectionRegressionTests(unittest.TestCase): - def setUp(self): - self.document = FakeDocument() - self.first = FakeTextObject("first", "alpha", self.document) - self.second = FakeTextObject("second", "beta", self.document) - self.first.next_obj = self.second - self.second.prev_obj = self.first - - self.script = types.SimpleNamespace( - pointOfReference={}, - sayPhrase=mock.Mock(), - speakMessage=mock.Mock(), - ) - self.utility = object.__new__(Utilities) - self.utility._script = self.script - self.utility._clipboardHandlerId = None - self.utility.expandEOCs = lambda obj, start=0, end=-1: obj.text[start:len(obj.text) if end == -1 else end] - self.utility.queryNonEmptyText = lambda obj: obj if getattr(obj, "text", "") else None - self.utility.findNextObject = lambda obj: getattr(obj, "next_obj", None) - self.utility.findPreviousObject = lambda obj: getattr(obj, "prev_obj", None) - self.utility.getDocumentForObject = lambda obj: self.document if isinstance(obj, FakeTextObject) else obj if obj is self.document else None - self.utility.isSpreadSheetCell = lambda obj: False - - @staticmethod - def _make_selection(start_object, start_offset, end_object, end_offset, start_is_active=False): - return types.SimpleNamespace( - start_object=start_object, - start_offset=start_offset, - end_object=end_object, - end_offset=end_offset, - start_is_active=start_is_active, - ) - - @staticmethod - def _new_text_selection(): - return types.SimpleNamespace( - start_object=None, - start_offset=0, - end_object=None, - end_offset=0, - start_is_active=False, - ) - - def _patch_environment(self, local_ranges=None): - local_ranges = local_ranges or {} - remove_selection = mock.Mock() - set_selected_text = mock.Mock() - - def get_selected_ranges(obj): - return list(local_ranges.get(obj, [])) - - def get_character_count(obj): - return len(obj.text) - - def get_caret_offset(obj): - return obj.caret_offset - - def get_substring(obj, start, end): - if end == -1: - end = len(obj.text) - return obj.text[start:end] - - def get_text_selections(document): - return list(document.currentSelections) - - def set_text_selections(document, selections): - document.setCalls.append(list(selections)) - document.currentSelections = list(selections) - return True - - stack = ExitStack() - stack.enter_context(mock.patch("cthulhu.script_utilities.AXObject.supports_text", side_effect=lambda obj: isinstance(obj, FakeTextObject))) - stack.enter_context(mock.patch("cthulhu.script_utilities.AXText.get_selected_ranges", side_effect=get_selected_ranges)) - stack.enter_context(mock.patch("cthulhu.script_utilities.AXText.get_character_count", side_effect=get_character_count)) - stack.enter_context(mock.patch("cthulhu.script_utilities.AXText.get_caret_offset", side_effect=get_caret_offset)) - stack.enter_context(mock.patch("cthulhu.script_utilities.AXText.get_substring", side_effect=get_substring)) - stack.enter_context(mock.patch("cthulhu.script_utilities.AXText.set_selected_text", set_selected_text)) - stack.enter_context(mock.patch("cthulhu.script_utilities.AXText._get_n_selections", return_value=1)) - stack.enter_context(mock.patch("cthulhu.script_utilities.AXText._remove_selection", remove_selection)) - fakeAtspi = types.SimpleNamespace( - Document=types.SimpleNamespace( - get_text_selections=mock.Mock(side_effect=get_text_selections), - set_text_selections=mock.Mock(side_effect=set_text_selections), - ), - TextSelection=mock.Mock(side_effect=self._new_text_selection), - ) - stack.enter_context(mock.patch.object(ax_document_selection, "Atspi", fakeAtspi)) - stack.enter_context( - mock.patch( - "cthulhu.script_utilities.cthulhu.cthulhuApp", - new=types.SimpleNamespace( - settingsManager=types.SimpleNamespace( - getSetting=lambda *_args, **_kwargs: False, - ) - ), - create=True, - ) - ) - self.addCleanup(stack.close) - return remove_selection, set_selected_text - - def test_selected_text_uses_document_selection_when_local_ranges_are_empty(self): - self.document.currentSelections = [ - self._make_selection(self.first, 2, self.second, 2), - ] - self._patch_environment() - - self.assertEqual(self.utility.selectedText(self.first), ["pha", 2, 5]) - self.assertEqual(self.utility.selectedText(self.second), ["be", 0, 2]) - - def test_all_text_selections_project_document_ranges_onto_each_object(self): - self.document.currentSelections = [ - self._make_selection(self.first, 2, self.second, 2), - ] - self._patch_environment() - - self.assertEqual(self.utility.allTextSelections(self.first), [(2, 5)]) - self.assertEqual(self.utility.allTextSelections(self.second), [(0, 2)]) - - def test_all_selected_text_aggregates_multi_object_document_selection(self): - self.document.currentSelections = [ - self._make_selection(self.first, 2, self.second, 2), - ] - self._patch_environment() - - self.assertEqual(self.utility.allSelectedText(self.first), ("pha be", 2, 5)) - - def test_clear_text_selection_uses_document_api_when_selection_is_authoritative(self): - self.document.currentSelections = [ - self._make_selection(self.first, 1, self.second, 3), - ] - remove_selection, _ = self._patch_environment() - - self.utility.clearTextSelection(self.first) - - self.assertEqual(self.document.setCalls, [[]]) - remove_selection.assert_not_called() - - def test_adjust_text_selection_preserves_other_document_ranges(self): - self.document.currentSelections = [ - self._make_selection(self.first, 2, self.first, 4), - self._make_selection(self.second, 1, self.second, 3), - ] - self.first.caret_offset = 4 - _, set_selected_text = self._patch_environment() - - self.utility.adjustTextSelection(self.first, 5) - - self.assertEqual(len(self.document.setCalls), 1) - stored = [ - (selection.start_object, selection.start_offset, - selection.end_object, selection.end_offset, - selection.start_is_active) - for selection in self.document.setCalls[0] - ] - self.assertEqual( - stored, - [ - (self.first, 2, self.first, 5, False), - (self.second, 1, self.second, 3, False), - ], - ) - set_selected_text.assert_not_called() - - def test_selected_text_falls_back_to_raw_substring_when_expand_eocs_is_empty(self): - self.document.currentSelections = [] - self.utility.expandEOCs = lambda _obj, _start=0, _end=-1: "" - self._patch_environment(local_ranges={self.first: [(2, 5)]}) - - self.assertEqual(self.utility.selectedText(self.first), ["pha", 2, 5]) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_event_manager_compositor_context_regressions.py b/tests/test_event_manager_compositor_context_regressions.py deleted file mode 100644 index 1396ca9..0000000 --- a/tests/test_event_manager_compositor_context_regressions.py +++ /dev/null @@ -1,383 +0,0 @@ -import sys -import types -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import cthulhu_state -from cthulhu import compositor_state_types - -stubCthulhu = types.ModuleType("cthulhu.cthulhu") -stubCthulhu.cthulhuApp = mock.Mock() -sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu) - -from cthulhu import event_manager - - -class FakeEvent: - def __init__(self, event_type, source="same", detail1=0, detail2=0, any_data=None): - self.type = event_type - self.source = source - self.detail1 = detail1 - self.detail2 = detail2 - self.any_data = any_data - - -class EventManagerCompositorContextRegressionTests(unittest.TestCase): - def setUp(self) -> None: - self.originalPauseAtspiChurn = cthulhu_state.pauseAtspiChurn - self.originalPrioritizedDesktopContextToken = cthulhu_state.prioritizedDesktopContextToken - self.originalCompositorSnapshot = cthulhu_state.compositorSnapshot - self.originalActiveScript = cthulhu_state.activeScript - self.addCleanup(self._restore_cthulhu_state) - - self.listener = mock.Mock() - fakeAtspi = types.SimpleNamespace( - Accessible=event_manager.Atspi.Accessible, - EventListener=types.SimpleNamespace(new=mock.Mock(return_value=self.listener)), - Role=event_manager.Atspi.Role, - ) - self.listenerPatch = mock.patch.object(event_manager, "Atspi", fakeAtspi) - self.listenerPatch.start() - self.addCleanup(self.listenerPatch.stop) - - self.manager = event_manager.EventManager(mock.Mock(), asyncMode=False) - self.manager._active = True - self.manager._context_token_for_event = mock.Mock(side_effect=lambda event: event.source) - cthulhu_state.pauseAtspiChurn = False - cthulhu_state.prioritizedDesktopContextToken = None - cthulhu_state.compositorSnapshot = None - cthulhu_state.activeScript = None - - def _restore_cthulhu_state(self) -> None: - cthulhu_state.pauseAtspiChurn = self.originalPauseAtspiChurn - cthulhu_state.prioritizedDesktopContextToken = self.originalPrioritizedDesktopContextToken - cthulhu_state.compositorSnapshot = self.originalCompositorSnapshot - cthulhu_state.activeScript = self.originalActiveScript - - def test_set_compositor_state_adapter_registers_compositor_listener(self) -> None: - adapter = mock.Mock() - - self.manager.set_compositor_state_adapter(adapter) - - adapter.add_listener.assert_called_once_with(self.manager._handle_compositor_signal) - - def test_set_compositor_state_adapter_updates_active_input_manager(self) -> None: - adapter = mock.Mock() - self.manager._inputEventManager = mock.Mock() - - self.manager.set_compositor_state_adapter(adapter) - - self.manager._inputEventManager.set_compositor_state_adapter.assert_called_once_with( - adapter - ) - - def test_pause_signal_updates_churn_state_and_resume_clears_it(self) -> None: - snapshot = compositor_state_types.DesktopContextSnapshot(session_type="wayland") - - self.manager._handle_compositor_signal( - compositor_state_types.CompositorStateEvent( - compositor_state_types.PAUSE_ATSPI_CHURN, - reason="workspace-transition", - snapshot=snapshot, - payload={"context_token": "current"}, - ) - ) - - self.assertTrue(cthulhu_state.pauseAtspiChurn) - self.assertTrue(self.manager._churnSuppressed) - - self.manager._handle_compositor_signal( - compositor_state_types.CompositorStateEvent( - compositor_state_types.RESUME_ATSPI_CHURN, - reason="workspace-transition", - snapshot=snapshot, - payload={"context_token": "current"}, - ) - ) - - self.assertFalse(cthulhu_state.pauseAtspiChurn) - self.assertFalse(self.manager._churnSuppressed) - - def test_confirmed_empty_i3_workspace_clears_stale_web_context(self) -> None: - staleScript = mock.Mock() - defaultScript = mock.Mock() - focusManager = mock.Mock() - self.manager.app.scriptManager.get_active_script.return_value = staleScript - self.manager.app.scriptManager.get_default_script.return_value = defaultScript - snapshot = compositor_state_types.DesktopContextSnapshot( - session_type="x11", - backend_name="i3-ipc", - active_workspace_ids=frozenset({"9"}), - focused_workspace_empty=True, - ) - - with mock.patch.object( - event_manager.focus_manager, - "get_manager", - return_value=focusManager, - ): - self.manager._handle_compositor_signal( - compositor_state_types.CompositorStateEvent( - compositor_state_types.DESKTOP_TRANSITION_FINISHED, - reason="workspace-focus", - snapshot=snapshot, - ) - ) - - staleScript.presentationInterrupt.assert_called_once_with() - focusManager.clear_state.assert_called_once_with("confirmed empty i3 workspace") - self.manager.app.scriptManager.set_active_script.assert_called_once_with( - defaultScript, - "focus: confirmed-empty-i3-workspace", - ) - self.assertTrue(self.manager._desktopContextConfirmedEmpty) - - def test_atspi_event_is_ignored_while_i3_workspace_is_confirmed_empty(self) -> None: - self.manager._desktopContextConfirmedEmpty = True - event = FakeEvent("object:state-changed:focused", source=object(), detail1=1) - self.manager._get_scriptForEvent = mock.Mock() - - with ( - mock.patch.object(event_manager.debug, "printObjectEvent"), - mock.patch.object(event_manager.debug, "printMessage"), - ): - self.manager._processObjectEvent(event) - - self.manager._get_scriptForEvent.assert_not_called() - - def test_nonempty_i3_workspace_schedules_focus_resync_after_empty_workspace(self) -> None: - self.manager._desktopContextConfirmedEmpty = True - snapshot = compositor_state_types.DesktopContextSnapshot( - session_type="x11", - backend_name="i3-ipc", - active_workspace_ids=frozenset({"8"}), - focused_window_id=0x200000C, - focused_workspace_empty=False, - ) - - with mock.patch.object(event_manager.GLib, "idle_add") as idleAdd: - self.manager._handle_compositor_signal( - compositor_state_types.CompositorStateEvent( - compositor_state_types.WORKSPACE_STATE_CHANGED, - reason="window-focus", - snapshot=snapshot, - ) - ) - - self.assertFalse(self.manager._desktopContextConfirmedEmpty) - idleAdd.assert_called_once_with(self.manager._sync_focus_on_startup) - - def test_stale_context_event_is_obsolete_while_churn_is_paused(self) -> None: - self.manager._churnSuppressed = True - self.manager._prioritizedContextToken = "current" - event = FakeEvent("object:children-changed:add", source="stale") - - self.assertTrue(self.manager._is_obsolete_by_context(event)) - - def test_flush_signal_removes_stale_events_from_queue(self) -> None: - self.manager._churnSuppressed = False - self.manager._prioritizedContextToken = "current" - staleEvent = FakeEvent("object:children-changed:add", source="stale") - currentEvent = FakeEvent("object:children-changed:add", source="current") - self.manager._eventQueue.put(staleEvent) - self.manager._eventQueue.put(currentEvent) - - self.manager._handle_compositor_signal( - compositor_state_types.CompositorStateEvent( - compositor_state_types.FLUSH_STALE_ATSPI_EVENTS, - reason="resume", - snapshot=compositor_state_types.DesktopContextSnapshot(session_type="wayland"), - payload={"context_token": "current"}, - ) - ) - - self.assertEqual(list(self.manager._eventQueue.queue), [currentEvent]) - - def test_flush_classifies_outside_queue_lock_and_preserves_nested_event(self) -> None: - staleEvent = FakeEvent("object:children-changed:add", source="stale") - currentEvent = FakeEvent("object:children-changed:add", source="current") - nestedEvent = FakeEvent("object:state-changed:focused", source="nested", detail1=1) - self.manager._eventQueue.put(staleEvent) - self.manager._eventQueue.put(currentEvent) - self.manager._ignore = mock.Mock(return_value=False) - self.manager._prioritizeSelfHostedFocusedEvent = mock.Mock(return_value=False) - self.manager._queuePrintln = mock.Mock() - self.manager._inFlood = mock.Mock(return_value=False) - self.manager._shouldSuspendEventsFor = mock.Mock(return_value=False) - self.manager._dequeue = mock.Mock(return_value=False) - script = types.SimpleNamespace(eventCache={}) - - def classify_event(event) -> bool: - self.assertFalse(self.manager._gidleLock.locked()) - if event is staleEvent: - self.manager._enqueue(nestedEvent) - return True - return False - - self.manager._event_is_from_stale_context = mock.Mock(side_effect=classify_event) - self.manager._should_preserve_during_suppression = mock.Mock(return_value=False) - - with ( - mock.patch.object(event_manager.AXObject, "get_application", return_value=object()), - mock.patch.object(event_manager.GLib, "idle_add", return_value=1), - mock.patch.object( - event_manager.cthulhu.cthulhuApp.scriptManager, - "get_script", - return_value=script, - ), - mock.patch.object( - event_manager.AXUtilities, - "get_application_toolkit_name", - return_value="VCL", - ), - ): - self.manager._flush_stale_atspi_events() - - self.assertEqual(list(self.manager._eventQueue.queue), [currentEvent, nestedEvent]) - self.manager._dequeue.assert_not_called() - - def test_flush_restores_retained_and_unexamined_events_after_exception(self) -> None: - firstEvent = FakeEvent("object:children-changed:add", source="first") - secondEvent = FakeEvent("object:children-changed:add", source="second") - self.manager._eventQueue.put(firstEvent) - self.manager._eventQueue.put(secondEvent) - self.manager._event_is_from_stale_context = mock.Mock( - side_effect=RuntimeError("property lookup failed"), - ) - - with self.assertRaisesRegex(RuntimeError, "property lookup failed"): - self.manager._flush_stale_atspi_events() - - self.assertEqual(list(self.manager._eventQueue.queue), [firstEvent, secondEvent]) - self.assertFalse(self.manager._flushingStaleAtspiEvents) - - def test_stale_background_event_does_not_activate_script_during_suppression(self) -> None: - script = mock.Mock() - script.isActivatableEvent.return_value = True - script.forceScriptActivation.return_value = False - self.manager._churnSuppressed = True - self.manager._prioritizedContextToken = "current" - - event = FakeEvent("object:state-changed:showing", source="old") - - result, reason = self.manager._isActivatableEvent(event, script) - - self.assertFalse(result) - self.assertIn("compositor-prioritized context", reason) - - def test_focus_event_syncs_accessible_context_back_into_adapter(self) -> None: - adapter = mock.Mock() - script = mock.Mock() - source = object() - event = FakeEvent("object:state-changed:focused", source=source, detail1=1) - self.manager._compositorStateAdapter = adapter - self.manager._get_scriptForEvent = mock.Mock(return_value=script) - self.manager._isActivatableEvent = mock.Mock(return_value=(False, "already active")) - self.manager._inFlood = mock.Mock(return_value=False) - - with ( - mock.patch.object(event_manager.debug, "printObjectEvent"), - mock.patch.object(event_manager.debug, "printDetails"), - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.debug, "printTokens"), - mock.patch.object(event_manager.AXUtilities, "get_desktop", return_value=object()), - mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_iconified", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_frame", return_value=False), - mock.patch.object(event_manager.AXObject, "is_dead", return_value=False), - ): - self.manager._processObjectEvent(event) - - adapter.sync_accessible_context.assert_called_once_with("object:state-changed:focused") - - def test_steam_children_changed_burst_is_suppressed_before_flood_threshold(self) -> None: - app = object() - cthulhu_state.activeScript = mock.Mock(app=app) - firstEvent = FakeEvent("object:children-changed:add", source="steam-context", any_data=object()) - secondEvent = FakeEvent("object:children-changed:add", source="steam-context", any_data=object()) - - with ( - mock.patch.object(event_manager.time, "monotonic", side_effect=[100.0, 100.05]), - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.debug, "printTokens"), - mock.patch.object(event_manager.debug, "print_log"), - mock.patch.object(event_manager.AXObject, "get_application", return_value=app), - mock.patch.object(event_manager.AXObject, "get_name", return_value="steamwebhelper"), - mock.patch.object(event_manager.AXObject, "get_role", return_value=mock.Mock()), - mock.patch.object(event_manager.AXObject, "is_dead", return_value=False), - mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False), - mock.patch.object(event_manager.AXUtilities, "manages_descendants", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_image", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_menu_item", return_value=False), - ): - self.manager._isSteamApp = mock.Mock(return_value=True) - self.manager._isSteamNotificationEvent = mock.Mock(return_value=False) - - self.assertFalse(self.manager._ignore(firstEvent)) - self.assertTrue(self.manager._ignore(secondEvent)) - - def test_steam_quick_access_name_changed_survives_without_active_script(self) -> None: - app = object() - event = FakeEvent("object:property-change:accessible-name", source="quick-access") - cthulhu_state.activeScript = None - - with ( - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.debug, "printTokens"), - mock.patch.object(event_manager.debug, "print_log"), - mock.patch.object(event_manager.AXObject, "get_application", return_value=app), - mock.patch.object(event_manager.AXObject, "get_name", return_value="steamwebhelper"), - ): - self.manager._isSteamOverlayNavigationEvent = mock.Mock(return_value=True) - - self.assertFalse(self.manager._ignore(event)) - - def test_steam_overlay_navigation_requires_quick_access_context(self) -> None: - app = object() - event = FakeEvent("object:property-change:accessible-name", source="not-quick-access") - - self.manager._isSteamApp = mock.Mock(return_value=True) - self.manager._activeX11WindowIsSteamSelectionContext = mock.Mock(return_value=True) - self.manager._eventHasSteamQuickAccessContext = mock.Mock(return_value=False) - - self.assertFalse(self.manager._isSteamOverlayNavigationEvent(event, app)) - - def test_steam_overlay_navigation_rejects_children_changed_churn(self) -> None: - app = object() - event = FakeEvent("object:children-changed:add", source="quick-access", any_data=object()) - - self.manager._isSteamApp = mock.Mock(return_value=True) - self.manager._activeX11WindowIsSteamSelectionContext = mock.Mock(return_value=True) - self.manager._eventHasSteamQuickAccessContext = mock.Mock(return_value=True) - - self.assertFalse(self.manager._isSteamOverlayNavigationEvent(event, app)) - - def test_steam_focus_lost_burst_is_ignored_but_focus_gain_is_preserved(self) -> None: - app = object() - cthulhu_state.activeScript = mock.Mock(app=app) - focusLost = FakeEvent("object:state-changed:focused", source="steam-context", detail1=0) - focusGained = FakeEvent("object:state-changed:focused", source="steam-context", detail1=1) - - with ( - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.debug, "printTokens"), - mock.patch.object(event_manager.debug, "print_log"), - mock.patch.object(event_manager.AXObject, "get_application", return_value=app), - mock.patch.object(event_manager.AXObject, "get_name", return_value="steamwebhelper"), - mock.patch.object(event_manager.AXObject, "get_role", return_value=mock.Mock()), - mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False), - ): - self.manager._isSteamApp = mock.Mock(return_value=True) - self.manager._isSteamNotificationEvent = mock.Mock(return_value=False) - - self.assertTrue(self.manager._ignore(focusLost)) - self.assertFalse(self.manager._ignore(focusGained)) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_event_manager_relevance_gate_regressions.py b/tests/test_event_manager_relevance_gate_regressions.py deleted file mode 100644 index f43505a..0000000 --- a/tests/test_event_manager_relevance_gate_regressions.py +++ /dev/null @@ -1,194 +0,0 @@ -import sys -import types -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import cthulhu_state - -stubCthulhu = types.ModuleType("cthulhu.cthulhu") -stubCthulhu.cthulhuApp = mock.Mock() -sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu) - -from cthulhu import event_manager - - -class FakeEvent: - def __init__(self, event_type, source="same", detail1=0, detail2=0, any_data=None): - self.type = event_type - self.source = source - self.detail1 = detail1 - self.detail2 = detail2 - self.any_data = any_data - - -class EventManagerRelevanceGateRegressionTests(unittest.TestCase): - def setUp(self) -> None: - self.listener = mock.Mock() - fakeAtspi = types.SimpleNamespace( - Accessible=event_manager.Atspi.Accessible, - EventListener=types.SimpleNamespace(new=mock.Mock(return_value=self.listener)), - Role=event_manager.Atspi.Role, - ) - self.listenerPatch = mock.patch.object(event_manager, "Atspi", fakeAtspi) - self.listenerPatch.start() - self.addCleanup(self.listenerPatch.stop) - - self.steamAppPatch = mock.patch.object(event_manager.EventManager, "_isSteamApp", return_value=False) - self.steamNotificationPatch = mock.patch.object( - event_manager.EventManager, - "_isSteamNotificationEvent", - return_value=False, - ) - self.steamAppPatch.start() - self.steamNotificationPatch.start() - self.addCleanup(self.steamAppPatch.stop) - self.addCleanup(self.steamNotificationPatch.stop) - - self.originalActiveScript = cthulhu_state.activeScript - self.originalLocusOfFocus = cthulhu_state.locusOfFocus - self.addCleanup(self._restore_state) - - self.manager = event_manager.EventManager(mock.Mock(), asyncMode=False) - self.manager._active = True - cthulhu_state.activeScript = None - cthulhu_state.locusOfFocus = None - - def _restore_state(self) -> None: - cthulhu_state.activeScript = self.originalActiveScript - cthulhu_state.locusOfFocus = self.originalLocusOfFocus - - def test_unfocused_web_link_name_change_is_dropped_when_focus_is_stable_elsewhere(self) -> None: - app = object() - focus = object() - source = object() - event = FakeEvent( - "object:property-change:accessible-name", - source=source, - any_data="Diablo II: Resurrected – Infernal Edition $39.99", - ) - cthulhu_state.activeScript = mock.Mock(app=app) - cthulhu_state.locusOfFocus = focus - - with ( - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.debug, "printTokens"), - mock.patch.object(event_manager.debug, "print_log"), - mock.patch.object(event_manager.AXObject, "get_application", return_value=app), - mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"), - mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.LINK), - mock.patch.object(event_manager.AXObject, "is_dead", return_value=False), - mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_focused", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False), - ): - self.assertTrue(self.manager._ignore(event)) - - def test_focused_web_link_name_change_is_kept(self) -> None: - app = object() - source = object() - event = FakeEvent("object:property-change:accessible-name", source=source, any_data="Cookie Clicker") - cthulhu_state.activeScript = mock.Mock(app=app) - cthulhu_state.locusOfFocus = source - - with ( - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.debug, "printTokens"), - mock.patch.object(event_manager.debug, "print_log"), - mock.patch.object(event_manager.AXObject, "get_application", return_value=app), - mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"), - mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.LINK), - mock.patch.object(event_manager.AXObject, "is_dead", return_value=False), - mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_focused", return_value=True), - mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False), - ): - self.assertFalse(self.manager._ignore(event)) - - def test_live_region_name_change_is_kept_even_when_unfocused(self) -> None: - app = object() - focus = object() - source = object() - event = FakeEvent("object:property-change:accessible-name", source=source, any_data="sale updated") - cthulhu_state.activeScript = mock.Mock(app=app) - cthulhu_state.locusOfFocus = focus - - def get_attribute(obj, name): - if name == "live": - return "polite" - return "" - - with ( - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.debug, "printTokens"), - mock.patch.object(event_manager.debug, "print_log"), - mock.patch.object(event_manager.AXObject, "get_application", return_value=app), - mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"), - mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.LINK), - mock.patch.object(event_manager.AXObject, "get_attribute", side_effect=get_attribute), - mock.patch.object(event_manager.AXObject, "is_dead", return_value=False), - mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_focused", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False), - ): - self.assertFalse(self.manager._ignore(event)) - - def test_unfocused_focus_loss_is_dropped_when_focus_is_stable_elsewhere(self) -> None: - app = object() - focus = object() - source = object() - event = FakeEvent("object:state-changed:focused", source=source, detail1=0) - cthulhu_state.activeScript = mock.Mock(app=app) - cthulhu_state.locusOfFocus = focus - - with ( - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.debug, "printTokens"), - mock.patch.object(event_manager.debug, "print_log"), - mock.patch.object(event_manager.AXObject, "get_application", return_value=app), - mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"), - mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.LINK), - mock.patch.object(event_manager.AXObject, "is_dead", return_value=False), - mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False), - ): - self.assertTrue(self.manager._ignore(event)) - - def test_repeated_web_children_changed_burst_is_collapsed(self) -> None: - app = object() - focus = object() - source = object() - firstEvent = FakeEvent("object:children-changed:add", source=source, any_data=object()) - secondEvent = FakeEvent("object:children-changed:add", source=source, any_data=object()) - cthulhu_state.activeScript = mock.Mock(app=app) - cthulhu_state.locusOfFocus = focus - - with ( - mock.patch.object(event_manager.time, "monotonic", side_effect=[100.0, 100.05]), - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.debug, "printTokens"), - mock.patch.object(event_manager.debug, "print_log"), - mock.patch.object(event_manager.AXObject, "get_application", return_value=app), - mock.patch.object(event_manager.AXObject, "get_name", return_value="Chromium"), - mock.patch.object(event_manager.AXObject, "get_role", return_value=event_manager.Atspi.Role.SECTION), - mock.patch.object(event_manager.AXObject, "is_dead", return_value=False), - mock.patch.object(event_manager.AXUtilities, "has_no_state", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False), - mock.patch.object(event_manager.AXUtilities, "manages_descendants", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_image", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_menu_item", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_notification", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_alert", return_value=False), - ): - self.assertFalse(self.manager._ignore(firstEvent)) - self.assertTrue(self.manager._ignore(secondEvent)) diff --git a/tests/test_event_manager_xterm_handoff_regressions.py b/tests/test_event_manager_xterm_handoff_regressions.py deleted file mode 100644 index 01b0a2e..0000000 --- a/tests/test_event_manager_xterm_handoff_regressions.py +++ /dev/null @@ -1,129 +0,0 @@ -import sys -import types -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -stubCthulhu = types.ModuleType("cthulhu.cthulhu") -stubCthulhu.cthulhuApp = mock.Mock() -sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu) - -from cthulhu import event_manager - - -class FakeEvent: - def __init__(self, event_type, source="window", detail1=0): - self.type = event_type - self.source = source - self.detail1 = detail1 - self.detail2 = 0 - self.any_data = None - - -class EventManagerXtermHandoffRegressionTests(unittest.TestCase): - def setUp(self) -> None: - listener = mock.Mock() - fakeAtspi = types.SimpleNamespace( - Accessible=event_manager.Atspi.Accessible, - EventListener=types.SimpleNamespace(new=mock.Mock(return_value=listener)), - Role=event_manager.Atspi.Role, - ) - self.listenerPatch = mock.patch.object(event_manager, "Atspi", fakeAtspi) - self.listenerPatch.start() - self.addCleanup(self.listenerPatch.stop) - - self.manager = event_manager.EventManager(mock.Mock(), asyncMode=False) - self.manager._active = True - self.manager._inputEventManager = mock.Mock() - self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.return_value = True - self.manager._get_scriptForEvent = mock.Mock() - - def test_window_activate_is_dropped_while_xterm_is_foreground(self) -> None: - event = FakeEvent("window:activate") - - with ( - mock.patch.object(event_manager.debug, "printObjectEvent"), - mock.patch.object(event_manager.debug, "printMessage"), - ): - self.manager._processObjectEvent(event) - - self.manager._get_scriptForEvent.assert_not_called() - self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_called_once_with( - refresh=True, - ) - - def test_active_frame_event_is_dropped_while_xterm_is_foreground(self) -> None: - event = FakeEvent("object:state-changed:active", detail1=1) - - with ( - mock.patch.object(event_manager.debug, "printObjectEvent"), - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object(event_manager.AXUtilities, "is_frame", return_value=True), - ): - self.manager._processObjectEvent(event) - - self.manager._get_scriptForEvent.assert_not_called() - self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_called_once_with( - refresh=True, - ) - - def test_focused_event_is_dropped_while_xterm_is_foreground(self) -> None: - event = FakeEvent("object:state-changed:focused", detail1=1) - - with ( - mock.patch.object(event_manager.debug, "printObjectEvent"), - mock.patch.object(event_manager.debug, "printMessage"), - ): - self.manager._processObjectEvent(event) - - self.manager._get_scriptForEvent.assert_not_called() - self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_called_once_with( - refresh=True, - ) - - def test_background_event_is_dropped_during_xterm_handoff_without_refresh(self) -> None: - event = FakeEvent("object:text-changed:insert") - - with ( - mock.patch.object(event_manager.debug, "printObjectEvent"), - mock.patch.object(event_manager.debug, "printMessage"), - ): - self.manager._processObjectEvent(event) - - self.manager._get_scriptForEvent.assert_not_called() - self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_called_once_with( - refresh=False, - ) - - def test_notification_daemon_window_create_is_processed_during_xterm_handoff(self) -> None: - event = FakeEvent("window:create", source=object()) - notificationApp = object() - self.manager._isActivatableEvent = mock.Mock(return_value=(False, "test")) - - with ( - mock.patch.object(event_manager.debug, "printObjectEvent"), - mock.patch.object(event_manager.debug, "printMessage"), - mock.patch.object( - event_manager.AXObject, - "get_application", - return_value=notificationApp, - ), - mock.patch.object( - event_manager.AXObject, - "get_name", - return_value="xfce4-notifyd", - ), - mock.patch.object(event_manager.AXObject, "is_dead", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False), - mock.patch.object(event_manager.AXUtilities, "is_iconified", return_value=False), - ): - self.manager._processObjectEvent(event) - - self.manager._get_scriptForEvent.assert_called_once_with(event) - self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_not_called() - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_hardwarefactory_regressions.py b/tests/test_hardwarefactory_regressions.py deleted file mode 100644 index de69d67..0000000 --- a/tests/test_hardwarefactory_regressions.py +++ /dev/null @@ -1,100 +0,0 @@ -import os -import select -import sys -import time -import unittest -from pathlib import Path - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import hardwarefactory -from cthulhu import settings - - -def read_available(fd, expectedLength, timeout=1.0): - deadline = time.monotonic() + timeout - data = b"" - while len(data) < expectedLength and time.monotonic() < deadline: - readable, _, _ = select.select([fd], [], [], 0.05) - if readable: - data += os.read(fd, 1024) - return data - - -class HardwareFactoryRegressionTests(unittest.TestCase): - def setUp(self): - self._oldDevice = settings.hardwareSpeechDevice - self._oldBaudRate = settings.hardwareSpeechBaudRate - hardwarefactory.SpeechServer.shutdownActiveServers() - - def tearDown(self): - hardwarefactory.SpeechServer.shutdownActiveServers() - settings.hardwareSpeechDevice = self._oldDevice - settings.hardwareSpeechBaudRate = self._oldBaudRate - - def test_lists_explicit_synth_choices_without_opening_serial_device(self): - settings.hardwareSpeechDevice = "" - - servers = hardwarefactory.SpeechServer.getSpeechServers() - - self.assertEqual( - ["litetalk", "doubletalk", "tripletalk", "dectalk"], - [server.getInfo()[1] for server in servers], - ) - self.assertEqual({}, hardwarefactory.SpeechServer._active_servers) - self.assertTrue(all(server._driver is None for server in servers)) - - def test_failed_initialization_is_not_cached(self): - settings.hardwareSpeechDevice = "" - - self.assertIsNone( - hardwarefactory.SpeechServer.getSpeechServer(["LiteTalk", "litetalk"]) - ) - self.assertEqual({}, hardwarefactory.SpeechServer._active_servers) - - masterFd, slaveFd = os.openpty() - try: - settings.hardwareSpeechDevice = os.ttyname(slaveFd) - server = hardwarefactory.SpeechServer.getSpeechServer( - ["LiteTalk", "litetalk"] - ) - - self.assertIsNotNone(server) - self.assertIsNotNone(server._driver) - self.assertIs( - server, - hardwarefactory.SpeechServer._active_servers.get("litetalk"), - ) - finally: - os.close(masterFd) - os.close(slaveFd) - - def test_explicit_synth_choices_write_expected_serial_bytes(self): - expectedBytes = { - "litetalk": b"Alias\r", - "doubletalk": b"Alias\r", - "tripletalk": b"Alias\r", - "dectalk": b"Alias\x01", - } - - for synthId, expected in expectedBytes.items(): - with self.subTest(synthId=synthId): - hardwarefactory.SpeechServer.shutdownActiveServers() - masterFd, slaveFd = os.openpty() - try: - settings.hardwareSpeechDevice = os.ttyname(slaveFd) - server = hardwarefactory.SpeechServer.getSpeechServer( - ["", synthId] - ) - - self.assertIsNotNone(server) - server.speak("Alias", interrupt=False) - self.assertEqual(expected, read_available(masterFd, len(expected))) - finally: - hardwarefactory.SpeechServer.shutdownActiveServers() - os.close(masterFd) - os.close(slaveFd) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_input_event_manager_key_watcher_regressions.py b/tests/test_input_event_manager_key_watcher_regressions.py deleted file mode 100644 index b959f26..0000000 --- a/tests/test_input_event_manager_key_watcher_regressions.py +++ /dev/null @@ -1,409 +0,0 @@ -import sys -import types -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import input_event_manager - - -class FakeDevice: - def __init__(self) -> None: - self.add_key_watcher_calls = [] - self.connect_calls = [] - self.disconnect_calls = [] - self.next_handler_id = 17 - self.add_key_grab_calls = [] - self.grab_ids = [] - - def add_key_watcher(self, callback: object, user_data: object = None) -> None: - self.add_key_watcher_calls.append((callback, user_data)) - - def connect(self, signalName: str, callback: object) -> int: - self.connect_calls.append((signalName, callback)) - handlerId = self.next_handler_id - self.next_handler_id += 1 - return handlerId - - def disconnect(self, handlerId: int) -> None: - self.disconnect_calls.append(handlerId) - - def add_key_grab(self, definition: object, callback: object = None) -> int: - self.add_key_grab_calls.append((definition, callback)) - return self.grab_ids.pop(0) - - -class FakeDeviceFactory: - def __init__(self, device: FakeDevice) -> None: - self.device = device - - def new(self) -> FakeDevice: - return self.device - - def new_full(self, _appId: str) -> FakeDevice: - return self.device - - -class InputEventManagerKeyWatcherTests(unittest.TestCase): - @staticmethod - def _fake_atspi( - version: tuple[int, int, int], - device: FakeDevice, - ) -> types.SimpleNamespace: - return types.SimpleNamespace( - get_version=lambda: version, - Device=FakeDeviceFactory(device), - ) - - def test_atspi_260_uses_key_signals_and_disconnects_them(self) -> None: - manager = input_event_manager.InputEventManager() - device = FakeDevice() - fakeAtspi = self._fake_atspi((2, 60, 5), device) - - with ( - mock.patch.object(input_event_manager, "Atspi", fakeAtspi), - mock.patch.dict(input_event_manager.os.environ, {"XDG_SESSION_TYPE": "wayland"}), - ): - manager.start_key_watcher() - manager.stop_key_watcher() - - self.assertEqual( - device.connect_calls, - [ - ("key-pressed", manager._on_key_pressed), - ("key-released", manager._on_key_released), - ], - ) - self.assertEqual(device.add_key_watcher_calls, []) - self.assertEqual(device.disconnect_calls, [17, 18]) - self.assertIsNone(manager.get_device()) - - def test_pre_atspi_260_keeps_legacy_key_watcher(self) -> None: - manager = input_event_manager.InputEventManager() - device = FakeDevice() - fakeAtspi = self._fake_atspi((2, 58, 4), device) - - with ( - mock.patch.object(input_event_manager, "Atspi", fakeAtspi), - mock.patch.dict(input_event_manager.os.environ, {"XDG_SESSION_TYPE": "wayland"}), - ): - manager.start_key_watcher() - - self.assertEqual( - device.add_key_watcher_calls, - [(manager.process_keyboard_event, None)], - ) - self.assertEqual(device.connect_calls, []) - - def test_key_signal_callbacks_preserve_pressed_state(self) -> None: - manager = input_event_manager.InputEventManager() - device = mock.Mock() - - with mock.patch.object(manager, "process_keyboard_event") as processEvent: - manager._on_key_pressed(device, 56, 98, 0, "b") - manager._on_key_released(device, 56, 98, 0, "b") - - self.assertEqual( - processEvent.call_args_list, - [ - mock.call(device, True, 56, 98, 0, "b"), - mock.call(device, False, 56, 98, 0, "b"), - ], - ) - - def test_x11_consumable_listener_includes_locking_modifier_combinations(self) -> None: - manager = input_event_manager.InputEventManager() - device = FakeDevice() - fakeAtspi = self._fake_atspi((2, 60, 5), device) - fakeAtspi.EventType = types.SimpleNamespace(KEY_PRESSED_EVENT=0, KEY_RELEASED_EVENT=1) - fakeAtspi.DeviceListener = types.SimpleNamespace(new=mock.Mock(return_value=object())) - fakeAtspi.register_keystroke_listener = mock.Mock(return_value=True) - fakeAtspi.deregister_keystroke_listener = mock.Mock(return_value=True) - fakeKeySet = [types.SimpleNamespace(keycode=38), types.SimpleNamespace(keycode=56)] - - with ( - mock.patch.object(input_event_manager, "Atspi", fakeAtspi), - mock.patch.dict(input_event_manager.os.environ, {"XDG_SESSION_TYPE": "x11"}), - mock.patch.object( - input_event_manager, - "_get_x11_consumable_key_set", - return_value=fakeKeySet, - ), - mock.patch.object(manager, "_initialize_xterm_handoff") as initializeXtermHandoff, - ): - manager.start_key_watcher() - manager.stop_key_watcher() - - shiftMask = 1 << int(input_event_manager.Atspi.ModifierType.SHIFT) - shiftLockMask = 1 << int(input_event_manager.Atspi.ModifierType.SHIFTLOCK) - numLockMask = 1 << int(input_event_manager.Atspi.ModifierType.NUMLOCK) - expectedMasks = [ - 0, - shiftMask, - shiftLockMask, - shiftMask | shiftLockMask, - numLockMask, - shiftMask | numLockMask, - shiftLockMask | numLockMask, - shiftMask | shiftLockMask | numLockMask, - ] - listener = fakeAtspi.DeviceListener.new.return_value - fakeAtspi.DeviceListener.new.assert_called_once_with( - manager._process_selective_legacy_keyboard_event, - None, - ) - self.assertEqual( - fakeAtspi.register_keystroke_listener.call_args_list, - [mock.call(listener, fakeKeySet, mask, 3, 3) for mask in expectedMasks], - ) - self.assertEqual( - fakeAtspi.deregister_keystroke_listener.call_args_list, - [mock.call(listener, fakeKeySet, mask, 3) for mask in expectedMasks], - ) - initializeXtermHandoff.assert_called_once_with() - self.assertEqual( - device.connect_calls, - [ - ("key-pressed", manager._on_key_pressed), - ("key-released", manager._on_key_released), - ], - ) - - def test_x11_consumable_listener_rolls_back_partial_registration(self) -> None: - manager = input_event_manager.InputEventManager() - device = FakeDevice() - fakeAtspi = self._fake_atspi((2, 60, 5), device) - fakeAtspi.EventType = types.SimpleNamespace(KEY_PRESSED_EVENT=0, KEY_RELEASED_EVENT=1) - fakeAtspi.DeviceListener = types.SimpleNamespace(new=mock.Mock(return_value=object())) - fakeAtspi.register_keystroke_listener = mock.Mock( - side_effect=[True, True, False], - ) - fakeAtspi.deregister_keystroke_listener = mock.Mock(return_value=True) - fakeKeySet = [types.SimpleNamespace(keycode=56)] - - with ( - mock.patch.object(input_event_manager, "Atspi", fakeAtspi), - mock.patch.dict(input_event_manager.os.environ, {"XDG_SESSION_TYPE": "x11"}), - mock.patch.object( - input_event_manager, - "_get_x11_consumable_key_set", - return_value=fakeKeySet, - ), - mock.patch.object(manager, "_initialize_xterm_handoff"), - ): - manager.start_key_watcher() - - expectedMasks = list(input_event_manager._X11_CONSUMABLE_MODIFIER_MASKS) - listener = fakeAtspi.DeviceListener.new.return_value - self.assertEqual( - fakeAtspi.register_keystroke_listener.call_args_list, - [ - mock.call(listener, fakeKeySet, expectedMasks[0], 3, 3), - mock.call(listener, fakeKeySet, expectedMasks[1], 3, 3), - mock.call(listener, fakeKeySet, expectedMasks[2], 3, 3), - ], - ) - self.assertEqual( - fakeAtspi.deregister_keystroke_listener.call_args_list, - [ - mock.call(listener, fakeKeySet, expectedMasks[0], 3), - mock.call(listener, fakeKeySet, expectedMasks[1], 3), - ], - ) - self.assertFalse(manager._selective_legacy_listener_active) - self.assertEqual(manager._selective_legacy_key_set, []) - self.assertEqual(manager._selective_legacy_keycodes, set()) - - def test_x11_consumable_listener_preserves_failed_deregistration_for_retry(self) -> None: - manager = input_event_manager.InputEventManager() - listener = object() - keySet = [types.SimpleNamespace(keycode=56)] - manager._selective_legacy_listener_active = True - manager._selective_legacy_listener = listener - manager._selective_legacy_registered_masks = [0] - manager._selective_legacy_key_set = keySet - manager._selective_legacy_keycodes = {56} - - with mock.patch.object( - input_event_manager.Atspi, - "deregister_keystroke_listener", - side_effect=[False, True], - ) as deregister: - manager._deregister_selective_legacy_key_listener() - - self.assertTrue(manager._selective_legacy_listener_active) - self.assertIs(manager._selective_legacy_listener, listener) - self.assertEqual(manager._selective_legacy_registered_masks, [0]) - self.assertEqual(manager._selective_legacy_key_set, keySet) - self.assertEqual(manager._selective_legacy_keycodes, {56}) - - manager._deregister_selective_legacy_key_listener() - - self.assertEqual(deregister.call_count, 2) - self.assertFalse(manager._selective_legacy_listener_active) - self.assertIsNone(manager._selective_legacy_listener) - self.assertEqual(manager._selective_legacy_registered_masks, []) - self.assertEqual(manager._selective_legacy_key_set, []) - self.assertEqual(manager._selective_legacy_keycodes, set()) - - def test_x11_consumable_keycodes_include_structural_navigation_but_not_tab(self) -> None: - keycodes = { - keysym: index + 20 - for index, keysym in enumerate(input_event_manager._X11_CONSUMABLE_KEYSYMS) - } - - with mock.patch("cthulhu.keybindings.get_keycodes") as getKeycodes: - getKeycodes.side_effect = lambda keysym: (0, keycodes[keysym]) - result = input_event_manager._get_x11_consumable_key_set() - - resultKeycodes = {definition.keycode for definition in result} - self.assertIn(keycodes["b"], resultKeycodes) - self.assertIn(keycodes["h"], resultKeycodes) - requestedKeysyms = {call.args[0] for call in getKeycodes.call_args_list} - self.assertNotIn("Tab", requestedKeysyms) - - def test_x11_consumable_key_set_uses_atspi_key_definitions(self) -> None: - with mock.patch("cthulhu.keybindings.get_keycodes", return_value=(0, 38)): - keySet = input_event_manager._get_x11_consumable_key_set() - - self.assertTrue(keySet) - self.assertTrue(all(isinstance(item, input_event_manager.Atspi.KeyDefinition) for item in keySet)) - - def test_modern_signal_defers_registered_x11_key_to_consumable_listener(self) -> None: - manager = input_event_manager.InputEventManager() - manager._selective_legacy_listener_active = True - manager._selective_legacy_keycodes = {56} - device = mock.Mock() - - with mock.patch.object(manager, "process_keyboard_event") as processEvent: - manager._on_key_pressed(device, 56, 98, 0, "b") - manager._on_key_released(device, 56, 98, 0, "b") - - processEvent.assert_not_called() - - def test_modern_signal_defers_x11_key_with_locking_modifiers(self) -> None: - manager = input_event_manager.InputEventManager() - manager._selective_legacy_listener_active = True - manager._selective_legacy_keycodes = {56} - device = mock.Mock() - shiftMask = 1 << int(input_event_manager.Atspi.ModifierType.SHIFT) - shiftLockMask = 1 << int(input_event_manager.Atspi.ModifierType.SHIFTLOCK) - numLockMask = 1 << int(input_event_manager.Atspi.ModifierType.NUMLOCK) - lockingMasks = ( - shiftLockMask, - shiftMask | shiftLockMask, - numLockMask, - shiftMask | numLockMask, - shiftLockMask | numLockMask, - shiftMask | shiftLockMask | numLockMask, - ) - - with mock.patch.object(manager, "process_keyboard_event") as processEvent: - for modifiers in lockingMasks: - manager._on_key_pressed(device, 56, 98, modifiers, "b") - manager._on_key_released(device, 56, 98, modifiers, "b") - - processEvent.assert_not_called() - - def test_modern_signal_still_processes_keys_not_owned_by_selective_listener(self) -> None: - manager = input_event_manager.InputEventManager() - manager._selective_legacy_listener_active = True - manager._selective_legacy_keycodes = {56} - device = mock.Mock() - - with mock.patch.object(manager, "process_keyboard_event") as processEvent: - manager._on_key_pressed(device, 23, 65289, 0, "Tab") - manager._on_key_released(device, 23, 65289, 0, "Tab") - - self.assertEqual( - processEvent.call_args_list, - [ - mock.call(device, True, 23, 65289, 0, "Tab"), - mock.call(device, False, 23, 65289, 0, "Tab"), - ], - ) - - def test_keyboard_event_returns_actual_consumption_decision(self) -> None: - manager = input_event_manager.InputEventManager() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = object() - focusManager.get_locus_of_focus.return_value = object() - scriptManager = mock.Mock() - scriptManager.get_active_script.return_value = mock.Mock() - keyboardEvent = mock.Mock() - keyboardEvent.is_modifier_key.return_value = False - keyboardEvent.process.return_value = False - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.cthulhu_state, "pendingSelfHostedFocus", None), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(manager, "_should_pass_through_for_active_xterm", return_value=False), - mock.patch.object(input_event_manager.AXUtilities, "can_be_active_window", return_value=True), - mock.patch.object(manager, "last_event_was_keyboard", return_value=False), - ): - result = manager.process_keyboard_event(mock.Mock(), True, 56, 98, 0, "b") - - self.assertFalse(result) - keyboardEvent.process.assert_called_once_with() - - def test_x11_consumable_listener_is_only_owner_of_matching_key_grabs(self) -> None: - manager = input_event_manager.InputEventManager() - device = FakeDevice() - device.grab_ids = [101, 102, 103] - manager._device = device - manager._selective_legacy_listener_active = True - manager._selective_legacy_keycodes = {56} - legacyOwned = types.SimpleNamespace(keycode=0, keysym=98, modifiers=0) - modified = types.SimpleNamespace(keycode=0, keysym=98, modifiers=4) - unrelated = types.SimpleNamespace(keycode=0, keysym=106, modifiers=0) - binding = mock.Mock() - binding.is_enabled.return_value = True - binding.is_bound.return_value = True - binding.has_grabs.return_value = False - binding.keycode = 56 - binding.key_definitions.return_value = [legacyOwned, modified] - - unrelatedBinding = mock.Mock() - unrelatedBinding.is_enabled.return_value = True - unrelatedBinding.is_bound.return_value = True - unrelatedBinding.has_grabs.return_value = False - unrelatedBinding.keycode = 44 - unrelatedBinding.key_definitions.return_value = [unrelated] - - result = manager.add_grabs_for_keybinding(binding) - unrelatedResult = manager.add_grabs_for_keybinding(unrelatedBinding) - - self.assertEqual(result, [101]) - self.assertEqual(unrelatedResult, [102]) - self.assertEqual( - device.add_key_grab_calls, - [(modified, None), (unrelated, None)], - ) - - def test_keybinding_grab_failure_rolls_back_partial_additions(self) -> None: - manager = input_event_manager.InputEventManager() - device = mock.Mock() - device.add_key_grab.side_effect = [101, RuntimeError("grab failed")] - manager._device = device - firstDefinition = types.SimpleNamespace(keycode=44, modifiers=0) - secondDefinition = types.SimpleNamespace(keycode=45, modifiers=0) - binding = mock.Mock() - binding.is_enabled.return_value = True - binding.is_bound.return_value = True - binding.has_grabs.return_value = False - binding.keycode = 44 - binding.key_definitions.return_value = [firstDefinition, secondDefinition] - - with self.assertRaisesRegex(RuntimeError, "grab failed"): - manager.add_grabs_for_keybinding(binding) - - device.remove_key_grab.assert_called_once_with(101) - self.assertEqual(manager._grabbed_bindings, {}) - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_input_event_manager_x11_focus_regressions.py b/tests/test_input_event_manager_x11_focus_regressions.py deleted file mode 100644 index 1f92260..0000000 --- a/tests/test_input_event_manager_x11_focus_regressions.py +++ /dev/null @@ -1,1090 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import input_event_manager -from cthulhu import compositor_state_types - - -class InputEventManagerX11FocusRegressionTests(unittest.TestCase): - def setUp(self): - self.compositorSnapshot = input_event_manager.cthulhu_state.compositorSnapshot - input_event_manager.cthulhu_state.compositorSnapshot = None - self.addCleanup( - setattr, - input_event_manager.cthulhu_state, - "compositorSnapshot", - self.compositorSnapshot, - ) - - def test_active_x11_window_differs_from_cached_atspi_window_by_pid(self): - manager = input_event_manager.InputEventManager() - cachedWindow = object() - - with ( - mock.patch.object(manager, "_get_active_x11_window_pid", return_value=1002), - mock.patch.object(input_event_manager.AXObject, "get_process_id", return_value=1001), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - self.assertTrue(manager._active_x11_window_differs_from(cachedWindow)) - - def test_keyboard_event_clears_stale_context_before_recovering_old_focus_window(self): - manager = input_event_manager.InputEventManager() - staleWindow = object() - staleFocus = object() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = staleWindow - focusManager.get_locus_of_focus.return_value = staleFocus - scriptManager = mock.Mock() - keyboardEvent = mock.Mock() - keyboardEvent.is_modifier_key.return_value = False - manager._last_input_event = object() - manager._last_non_modifier_key_event = object() - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(input_event_manager.AXUtilities, "can_be_active_window", return_value=False), - mock.patch.object(input_event_manager.AXUtilities, "find_active_window", return_value=None), - mock.patch.object(manager, "_find_active_x11_atspi_window", return_value=None), - mock.patch.object(manager, "_get_top_level_window", return_value=staleWindow), - mock.patch.object(manager, "_should_pass_through_for_active_xterm", return_value=False), - mock.patch.object(manager, "_active_x11_window_differs_from", return_value=True), - mock.patch.object(manager, "last_event_was_keyboard", return_value=False), - mock.patch.object(input_event_manager.debug, "print_message"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - True, - 36, - 65293, - 0, - "Return", - ) - - self.assertFalse(result) - scriptManager.set_active_script.assert_called_once_with( - None, - "active X11 window not found in AT-SPI", - ) - focusManager.clear_state.assert_called_once_with("active X11 window not found in AT-SPI") - focusManager.set_active_window.assert_not_called() - keyboardEvent.process.assert_not_called() - self.assertIsNone(manager._last_input_event) - self.assertIsNone(manager._last_non_modifier_key_event) - - def test_keyboard_event_clears_stale_script_when_cached_context_is_missing(self): - manager = input_event_manager.InputEventManager() - staleApp = object() - staleScript = mock.Mock(app=staleApp) - focusManager = mock.Mock() - focusManager.get_active_window.return_value = None - focusManager.get_locus_of_focus.return_value = None - scriptManager = mock.Mock() - scriptManager.get_active_script.return_value = staleScript - keyboardEvent = mock.Mock() - keyboardEvent.is_modifier_key.return_value = False - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(input_event_manager.AXUtilities, "can_be_active_window", return_value=False), - mock.patch.object(input_event_manager.AXUtilities, "find_active_window", return_value=None), - mock.patch.object(manager, "_find_active_x11_atspi_window", return_value=None), - mock.patch.object(manager, "_get_top_level_window", return_value=None), - mock.patch.object(manager, "_should_pass_through_for_active_xterm", return_value=False), - mock.patch.object(manager, "_active_x11_window_differs_from", return_value=True) as differs, - mock.patch.object(manager, "last_event_was_keyboard", return_value=False), - mock.patch.object(input_event_manager.debug, "print_message"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - True, - 81, - 65434, - 0, - "KP_Page_Up", - ) - - self.assertFalse(result) - differs.assert_called_once_with(staleApp) - scriptManager.set_active_script.assert_called_once_with( - None, - "active X11 window not found in AT-SPI", - ) - focusManager.clear_state.assert_called_once_with("active X11 window not found in AT-SPI") - keyboardEvent.process.assert_not_called() - - def test_keyboard_event_recovers_focus_window_when_x11_does_not_contradict_it(self): - manager = input_event_manager.InputEventManager() - cachedWindow = object() - staleFocus = object() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = cachedWindow - focusManager.get_locus_of_focus.return_value = staleFocus - scriptManager = mock.Mock() - keyboardEvent = mock.Mock() - keyboardEvent.is_modifier_key.return_value = False - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(input_event_manager.AXUtilities, "can_be_active_window", return_value=False), - mock.patch.object(input_event_manager.AXUtilities, "find_active_window", return_value=None), - mock.patch.object(manager, "_find_active_x11_atspi_window", return_value=None), - mock.patch.object(manager, "_get_top_level_window", return_value=cachedWindow), - mock.patch.object(manager, "_should_pass_through_for_active_xterm", return_value=False), - mock.patch.object(manager, "_active_x11_window_differs_from", return_value=False), - mock.patch.object(manager, "last_event_was_keyboard", return_value=False), - mock.patch.object(input_event_manager.debug, "print_message"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - True, - 36, - 65293, - 0, - "Return", - ) - - self.assertTrue(result) - focusManager.set_active_window.assert_called_once_with(cachedWindow) - scriptManager.set_active_script.assert_not_called() - focusManager.clear_state.assert_not_called() - keyboardEvent.process.assert_called_once_with() - - def test_keyboard_press_keeps_cthulhu_commands_when_unknown_window_is_not_xterm(self): - manager = input_event_manager.InputEventManager() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = None - focusManager.get_locus_of_focus.return_value = None - scriptManager = mock.Mock() - activeScript = mock.Mock(app=None) - scriptManager.get_active_script.return_value = activeScript - keyboardEvent = mock.Mock() - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.cthulhu_state, "pendingSelfHostedFocus", None), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(input_event_manager.AXUtilities, "can_be_active_window", return_value=False), - mock.patch.object(input_event_manager.AXUtilities, "find_active_window", return_value=None), - mock.patch.object(manager, "_get_top_level_window", return_value=None), - mock.patch.object(manager, "_should_pass_through_for_active_xterm", return_value=False), - mock.patch.object(manager, "_active_x11_window_differs_from", return_value=False), - mock.patch.object(manager, "last_event_was_keyboard", return_value=False), - mock.patch.object(input_event_manager.debug, "print_message"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - True, - 79, - 65429, - 0, - "KP_Home", - ) - - self.assertTrue(result) - activeScript.removeKeyGrabs.assert_not_called() - keyboardEvent.process.assert_called_once_with() - - def test_keyboard_press_suspends_grabs_and_passes_through_when_active_xterm_is_focused(self): - manager = input_event_manager.InputEventManager() - staleWindow = object() - staleFocus = object() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = staleWindow - focusManager.get_locus_of_focus.return_value = staleFocus - scriptManager = mock.Mock() - activeScript = mock.Mock(app=None) - scriptManager.get_active_script.return_value = activeScript - keyboardEvent = mock.Mock() - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.cthulhu_state, "pendingSelfHostedFocus", None), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(manager, "_should_pass_through_for_active_xterm", return_value=True), - mock.patch.object(input_event_manager.AXUtilities, "can_be_active_window") as canBeActiveWindow, - mock.patch.object(input_event_manager.AXUtilities, "find_active_window") as findActiveWindow, - mock.patch.object(input_event_manager.debug, "print_message"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - True, - 79, - 65429, - 0, - "KP_Home", - ) - - self.assertFalse(result) - activeScript.removeKeyGrabs.assert_called_once_with() - canBeActiveWindow.assert_not_called() - findActiveWindow.assert_not_called() - keyboardEvent.process.assert_not_called() - - def test_lxterminal_does_not_pass_through_as_xterm(self): - manager = input_event_manager.InputEventManager() - window = mock.Mock() - window.get_class_group_name.return_value = "lxterminal" - window.get_class_instance_name.return_value = "lxterminal" - window.get_name.return_value = "LXTerminal" - window.get_class_group.return_value = None - window.get_pid.return_value = -1 - - with ( - mock.patch.object(manager, "_get_active_x11_window", return_value=window), - mock.patch.object(input_event_manager.debug, "print_message"), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager._should_pass_through_for_active_xterm(None, None, None) - - self.assertFalse(result) - - def test_xterm_pass_through_stays_active_when_window_lookup_temporarily_fails(self): - manager = input_event_manager.InputEventManager() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = None - focusManager.get_locus_of_focus.return_value = None - scriptManager = mock.Mock() - activeScript = mock.Mock(app=None) - scriptManager.get_active_script.return_value = activeScript - keyboardEvent = mock.Mock() - manager._scriptWithSuspendedGrabsForXterm = activeScript - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.cthulhu_state, "pendingSelfHostedFocus", None), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=None), - mock.patch.object(input_event_manager.debug, "print_message"), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - True, - 90, - 65438, - 0, - "KP_Insert", - ) - - self.assertFalse(result) - self.assertIs(manager._scriptWithSuspendedGrabsForXterm, activeScript) - activeScript.addKeyGrabs.assert_not_called() - keyboardEvent.process.assert_not_called() - - def test_xterm_pass_through_ignores_stale_pending_self_hosted_focus(self): - manager = input_event_manager.InputEventManager() - pendingFocus = object() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = None - focusManager.get_locus_of_focus.return_value = None - scriptManager = mock.Mock() - activeScript = mock.Mock(app=None) - scriptManager.get_active_script.return_value = activeScript - keyboardEvent = mock.Mock() - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.cthulhu_state, "pendingSelfHostedFocus", pendingFocus), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=True), - mock.patch.object(input_event_manager.debug, "print_message"), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - True, - 90, - 65438, - 0, - "KP_Insert", - ) - - self.assertFalse(result) - activeScript.removeKeyGrabs.assert_called_once_with() - keyboardEvent.process.assert_not_called() - - def test_pending_self_hosted_focus_blocks_unknown_xterm_match(self): - manager = input_event_manager.InputEventManager() - - with ( - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=None), - mock.patch.object(input_event_manager.debug, "print_message"), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager._should_pass_through_for_active_xterm(None, None, object()) - - self.assertFalse(result) - - def test_xterm_grabs_restore_when_active_window_is_positively_not_xterm(self): - manager = input_event_manager.InputEventManager() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = None - focusManager.get_locus_of_focus.return_value = None - scriptManager = mock.Mock() - activeScript = mock.Mock(app=None) - scriptManager.get_active_script.return_value = activeScript - keyboardEvent = mock.Mock() - keyboardEvent.is_modifier_key.return_value = False - manager._scriptWithSuspendedGrabsForXterm = activeScript - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.cthulhu_state, "pendingSelfHostedFocus", None), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=False), - mock.patch.object(input_event_manager.AXUtilities, "can_be_active_window", return_value=True), - mock.patch.object(manager, "last_event_was_keyboard", return_value=False), - mock.patch.object(input_event_manager.debug, "print_message"), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - True, - 36, - 65293, - 0, - "Return", - ) - - self.assertTrue(result) - self.assertIsNone(manager._scriptWithSuspendedGrabsForXterm) - activeScript.addKeyGrabs.assert_called_once_with() - keyboardEvent.process.assert_called_once_with() - - def test_unidentified_active_x11_window_is_unknown_not_non_xterm(self): - manager = input_event_manager.InputEventManager() - window = mock.Mock() - window.get_class_group_name.return_value = None - window.get_class_instance_name.return_value = None - window.get_name.return_value = None - window.get_class_group.return_value = None - window.get_pid.return_value = -1 - - with ( - mock.patch.object(manager, "_get_active_x11_window", return_value=window), - mock.patch.object(input_event_manager.debug, "print_message"), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager._active_x11_window_xterm_match() - - self.assertIsNone(result) - - def test_finds_focused_atspi_window_for_active_x11_pid(self): - manager = input_event_manager.InputEventManager() - app = object() - unfocusedWindow = object() - focusedWindow = object() - - with ( - mock.patch.object(manager, "_get_active_x11_window_pid", return_value=23875), - mock.patch.object( - input_event_manager.AXUtilitiesApplication, - "get_application_with_pid", - return_value=app, - ), - mock.patch.object( - input_event_manager.AXObject, - "iter_children", - return_value=iter([unfocusedWindow, focusedWindow]), - ), - mock.patch.object(input_event_manager.AXUtilities, "is_frame", return_value=True), - mock.patch.object(input_event_manager.AXUtilities, "is_window", return_value=False), - mock.patch.object(input_event_manager.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(input_event_manager.AXUtilities, "is_focused", return_value=False), - mock.patch.object( - input_event_manager.AXUtilities, - "get_focused_object", - side_effect=[None, object()], - ), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager._find_active_x11_atspi_window() - - self.assertIs(result, focusedWindow) - - def test_keyboard_event_recovers_context_from_active_x11_pid_window(self): - manager = input_event_manager.InputEventManager() - recoveredWindow = object() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = None - focusManager.get_locus_of_focus.return_value = None - scriptManager = mock.Mock() - activeScript = mock.Mock(app=None) - scriptManager.get_active_script.return_value = activeScript - keyboardEvent = mock.Mock() - keyboardEvent.is_modifier_key.return_value = False - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.cthulhu_state, "pendingSelfHostedFocus", None), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(input_event_manager.AXUtilities, "can_be_active_window", return_value=False), - mock.patch.object(input_event_manager.AXUtilities, "find_active_window", return_value=None), - mock.patch.object(manager, "_find_active_x11_atspi_window", return_value=recoveredWindow), - mock.patch.object(manager, "last_event_was_keyboard", return_value=False), - mock.patch.object(input_event_manager.debug, "print_message"), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - True, - 79, - 65429, - 0, - "KP_Home", - ) - - self.assertTrue(result) - focusManager.set_active_window.assert_called_once_with(recoveredWindow) - activeScript.removeKeyGrabs.assert_not_called() - keyboardEvent.set_window.assert_called_once_with(recoveredWindow) - keyboardEvent.process.assert_called_once_with() - - def test_keyboard_release_suspends_grabs_and_passes_through_when_active_xterm_is_focused(self): - manager = input_event_manager.InputEventManager() - focusManager = mock.Mock() - focusManager.get_active_window.return_value = None - focusManager.get_locus_of_focus.return_value = None - scriptManager = mock.Mock() - activeScript = mock.Mock(app=None) - scriptManager.get_active_script.return_value = activeScript - keyboardEvent = mock.Mock() - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "capturingKeys", False), - mock.patch.object(input_event_manager.cthulhu_state, "pendingSelfHostedFocus", None), - mock.patch.object(input_event_manager.focus_manager, "get_manager", return_value=focusManager), - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.input_event, "KeyboardEvent", return_value=keyboardEvent), - mock.patch.object(manager, "_should_pass_through_for_active_xterm", return_value=True), - mock.patch.object(input_event_manager.debug, "print_message"), - ): - result = manager.process_keyboard_event( - mock.Mock(), - False, - 79, - 65429, - 0, - "KP_Home", - ) - - self.assertFalse(result) - activeScript.removeKeyGrabs.assert_called_once_with() - keyboardEvent.process.assert_not_called() - - def test_xterm_grab_suspension_is_idempotent(self): - manager = input_event_manager.InputEventManager() - activeScript = mock.Mock() - scriptManager = mock.Mock() - scriptManager.get_active_script.return_value = activeScript - - with mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager): - manager._suspend_key_grabs_for_xterm() - manager._suspend_key_grabs_for_xterm() - - activeScript.removeKeyGrabs.assert_called_once_with() - - def test_xterm_grab_restore_readds_grabs_for_same_active_script(self): - manager = input_event_manager.InputEventManager() - activeScript = mock.Mock() - scriptManager = mock.Mock() - scriptManager.get_active_script.return_value = activeScript - - with mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager): - manager._suspend_key_grabs_for_xterm() - manager._restore_key_grabs_after_xterm() - - activeScript.removeKeyGrabs.assert_called_once_with() - activeScript.addKeyGrabs.assert_called_once_with() - - def test_xterm_grab_restore_does_not_readd_grabs_for_inactive_script(self): - manager = input_event_manager.InputEventManager() - oldScript = mock.Mock() - newScript = mock.Mock() - scriptManager = mock.Mock() - scriptManager.get_active_script.side_effect = [oldScript, newScript] - - with mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager): - manager._suspend_key_grabs_for_xterm() - manager._restore_key_grabs_after_xterm() - - oldScript.removeKeyGrabs.assert_called_once_with() - oldScript.addKeyGrabs.assert_not_called() - - def test_xterm_grabs_restore_on_x11_focus_change_without_keyboard_event(self): - manager = input_event_manager.InputEventManager() - activeScript = mock.Mock() - scriptManager = mock.Mock() - scriptManager.get_active_script.return_value = activeScript - manager._scriptWithSuspendedGrabsForXterm = activeScript - - with ( - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=False) as matcher, - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - manager._on_active_x11_window_changed(mock.Mock(), None) - - matcher.assert_called_once_with() - activeScript.addKeyGrabs.assert_called_once_with() - self.assertIsNone(manager._scriptWithSuspendedGrabsForXterm) - - def test_active_x11_window_uses_ewmh_id_instead_of_stale_wnck_active_window(self): - manager = input_event_manager.InputEventManager() - wnck = mock.Mock() - screen = mock.Mock() - ewmhWindow = object() - wnck.Screen.get_default.return_value = screen - wnck.Window.get.return_value = ewmhWindow - - with ( - mock.patch.object(manager, "_get_wnck", return_value=wnck), - mock.patch.object(manager, "_ensure_xterm_focus_monitor"), - mock.patch.object(manager, "_get_ewmh_active_x11_window_id", return_value=0x1400010), - ): - result = manager._get_active_x11_window() - - self.assertIs(result, ewmhWindow) - wnck.Window.get.assert_called_once_with(0x1400010) - screen.get_active_window.assert_not_called() - - def test_active_x11_window_does_not_fall_back_to_stale_wnck_window_for_known_ewmh_id(self): - manager = input_event_manager.InputEventManager() - wnck = mock.Mock() - screen = mock.Mock() - wnck.Screen.get_default.return_value = screen - wnck.Window.get.return_value = None - - with ( - mock.patch.object(manager, "_get_wnck", return_value=wnck), - mock.patch.object(manager, "_ensure_xterm_focus_monitor"), - mock.patch.object(manager, "_get_ewmh_active_x11_window_id", return_value=0x1400010), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager._get_active_x11_window() - - self.assertIsNone(result) - screen.get_active_window.assert_not_called() - - def test_active_x11_window_falls_back_to_wnck_when_ewmh_is_unavailable(self): - manager = input_event_manager.InputEventManager() - wnck = mock.Mock() - screen = mock.Mock() - fallbackWindow = object() - wnck.Screen.get_default.return_value = screen - screen.get_active_window.return_value = fallbackWindow - - with ( - mock.patch.object(manager, "_get_wnck", return_value=wnck), - mock.patch.object(manager, "_ensure_xterm_focus_monitor"), - mock.patch.object(manager, "_get_ewmh_active_x11_window_id", return_value=None), - ): - result = manager._get_active_x11_window() - - self.assertIs(result, fallbackWindow) - - def test_xterm_match_reuses_cached_metadata_while_ewmh_window_id_is_unchanged(self): - manager = input_event_manager.InputEventManager() - - with ( - mock.patch.object( - manager, - "_get_ewmh_active_x11_window_id", - return_value=0x1400010, - ), - mock.patch.object( - manager, - "_x11_window_id_xterm_match", - return_value=False, - ) as matcher, - ): - firstResult = manager._active_x11_window_xterm_match() - secondResult = manager._active_x11_window_xterm_match() - - self.assertFalse(firstResult) - self.assertFalse(secondResult) - matcher.assert_called_once_with(0x1400010) - - def test_xterm_match_prefers_i3_focused_window_id_over_stale_ewmh_id(self): - manager = input_event_manager.InputEventManager() - snapshot = compositor_state_types.DesktopContextSnapshot( - session_type="x11", - backend_name="i3-ipc", - focused_window_id=0x2600003, - focused_workspace_empty=False, - ) - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "compositorSnapshot", snapshot), - mock.patch.object( - manager, - "_get_ewmh_active_x11_window_id", - return_value=0x200000C, - ) as getEwmhWindowId, - mock.patch.object( - manager, - "_x11_window_id_xterm_match", - return_value=False, - ) as matcher, - ): - result = manager._active_x11_window_xterm_match() - - self.assertFalse(result) - matcher.assert_called_once_with(0x2600003) - getEwmhWindowId.assert_not_called() - - def test_xterm_match_refreshes_i3_context_before_reusing_cached_match(self) -> None: - manager = input_event_manager.InputEventManager() - staleSnapshot = compositor_state_types.DesktopContextSnapshot( - session_type="x11", - backend_name="i3-ipc", - focused_window_id=0x200000C, - focused_workspace_empty=False, - ) - freshSnapshot = compositor_state_types.DesktopContextSnapshot( - session_type="x11", - backend_name="i3-ipc", - focused_window_id=0x2600003, - focused_workspace_empty=False, - ) - adapter = mock.Mock() - - def refresh_context(_reason: str) -> compositor_state_types.DesktopContextSnapshot: - input_event_manager.cthulhu_state.compositorSnapshot = freshSnapshot - return freshSnapshot - - adapter.refresh_workspace_context.side_effect = refresh_context - input_event_manager.cthulhu_state.compositorSnapshot = staleSnapshot - manager._lastEwmhActiveWindowId = 0x200000C - manager._lastEwmhXtermMatch = True - - manager.set_compositor_state_adapter(adapter) - with mock.patch.object( - manager, - "_x11_window_id_xterm_match", - return_value=False, - ) as matcher: - result = manager._active_x11_window_xterm_match() - - self.assertFalse(result) - adapter.refresh_workspace_context.assert_called_once_with("xterm-handoff-check") - matcher.assert_called_once_with(0x2600003) - - def test_i3_exact_xid_initializes_x11_before_matching_xterm(self): - manager = input_event_manager.InputEventManager() - snapshot = compositor_state_types.DesktopContextSnapshot( - session_type="x11", - backend_name="i3-ipc", - focused_window_id=0x200000C, - focused_workspace_empty=False, - ) - window = mock.Mock() - window.get_wm_class.return_value = ("xterm", "XTerm") - window.get_wm_name.return_value = "devel" - window.get_full_property.return_value = None - display = mock.Mock() - display.create_resource_object.return_value = window - - def initializeX11(): - manager._x11Display = display - manager._x11AnyPropertyType = object() - return True - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "compositorSnapshot", snapshot), - mock.patch.object( - manager, - "_ensure_x11_display", - side_effect=initializeX11, - ) as ensureX11, - mock.patch.object(manager, "_get_ewmh_active_x11_window_id") as getEwmhWindowId, - ): - result = manager._active_x11_window_xterm_match() - - self.assertTrue(result) - ensureX11.assert_called_once_with() - display.create_resource_object.assert_called_once_with("window", 0x200000C) - getEwmhWindowId.assert_not_called() - - def test_confirmed_empty_i3_workspace_is_definitely_not_xterm(self): - manager = input_event_manager.InputEventManager() - manager._lastEwmhActiveWindowId = 0x200000C - manager._lastEwmhXtermMatch = True - snapshot = compositor_state_types.DesktopContextSnapshot( - session_type="x11", - backend_name="i3-ipc", - focused_workspace_empty=True, - ) - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "compositorSnapshot", snapshot), - mock.patch.object(manager, "_get_ewmh_active_x11_window_id") as getEwmhWindowId, - mock.patch.object(manager, "_x11_window_id_xterm_match") as matcher, - ): - result = manager._active_x11_window_xterm_match() - - self.assertFalse(result) - self.assertIsNone(manager._lastEwmhActiveWindowId) - self.assertFalse(manager._lastEwmhXtermMatch) - getEwmhWindowId.assert_not_called() - matcher.assert_not_called() - - def test_unknown_i3_context_falls_back_to_generic_ewmh_window_id(self): - manager = input_event_manager.InputEventManager() - snapshot = compositor_state_types.DesktopContextSnapshot( - session_type="x11", - backend_name="i3-ipc", - focused_window_id=None, - focused_workspace_empty=None, - ) - - with ( - mock.patch.object(input_event_manager.cthulhu_state, "compositorSnapshot", snapshot), - mock.patch.object( - manager, - "_get_ewmh_active_x11_window_id", - return_value=0x2600003, - ), - mock.patch.object( - manager, - "_x11_window_id_xterm_match", - return_value=False, - ) as matcher, - ): - result = manager._active_x11_window_xterm_match() - - self.assertFalse(result) - matcher.assert_called_once_with(0x2600003) - - def test_ewmh_brave_window_does_not_use_stale_wnck_xterm_metadata(self): - manager = input_event_manager.InputEventManager() - - with ( - mock.patch.object( - manager, - "_get_ewmh_active_x11_window_id", - return_value=0x2600003, - ), - mock.patch.object( - manager, - "_x11_window_id_xterm_match", - return_value=False, - ) as directMatcher, - mock.patch.object(manager, "_get_active_x11_window") as getWnckWindow, - mock.patch.object(manager, "_x11_window_xterm_match") as wnckMatcher, - ): - result = manager._active_x11_window_xterm_match() - - self.assertFalse(result) - directMatcher.assert_called_once_with(0x2600003) - getWnckWindow.assert_not_called() - wnckMatcher.assert_not_called() - - def test_direct_x11_metadata_identifies_brave_as_non_xterm(self): - manager = input_event_manager.InputEventManager() - - with mock.patch.object( - manager, - "_get_x11_window_metadata", - return_value=(["brave-origin", "Brave-origin", "New Tab - Brave Origin"], 1234), - ): - result = manager._x11_window_id_xterm_match(0x2600003) - - self.assertFalse(result) - - def test_direct_x11_metadata_identifies_xterm(self): - manager = input_event_manager.InputEventManager() - - with mock.patch.object( - manager, - "_get_x11_window_metadata", - return_value=(["xterm", "XTerm", "devel"], 1234), - ): - result = manager._x11_window_id_xterm_match(0x200000C) - - self.assertTrue(result) - - def test_xterm_focus_change_suspends_grabs_without_keyboard_event(self): - manager = input_event_manager.InputEventManager() - activeScript = mock.Mock() - scriptManager = mock.Mock() - scriptManager.get_active_script.return_value = activeScript - - with ( - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=True) as matcher, - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - manager._on_active_x11_window_changed(mock.Mock(), None) - - matcher.assert_called_once_with() - activeScript.removeKeyGrabs.assert_called_once_with() - self.assertIs(manager._scriptWithSuspendedGrabsForXterm, activeScript) - - def test_initial_xterm_handoff_suspends_grabs(self): - manager = input_event_manager.InputEventManager() - manager._device = object() - - with ( - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=True), - mock.patch.object(manager, "_suspend_key_grabs_for_xterm") as suspend, - mock.patch.object(manager, "_ensure_xterm_recovery_timer") as ensureTimer, - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - manager._initialize_xterm_handoff() - - suspend.assert_called_once_with() - ensureTimer.assert_called_once_with() - - def test_xterm_focus_poll_suspends_grabs_after_entering_xterm(self): - manager = input_event_manager.InputEventManager() - manager._device = object() - - with ( - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=True), - mock.patch.object(manager, "_suspend_key_grabs_for_xterm") as suspend, - mock.patch.object(manager, "_restore_key_grabs_after_xterm") as restore, - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager._poll_xterm_grab_recovery() - - self.assertTrue(result) - suspend.assert_called_once_with() - restore.assert_not_called() - - def test_xterm_focus_poll_restores_grabs_after_leaving_xterm(self): - manager = input_event_manager.InputEventManager() - manager._device = object() - - with ( - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=False), - mock.patch.object(manager, "_suspend_key_grabs_for_xterm") as suspend, - mock.patch.object(manager, "_restore_key_grabs_after_xterm") as restore, - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager._poll_xterm_grab_recovery() - - self.assertTrue(result) - self.assertEqual(manager._xtermRecoveryPollCount, 1) - restore.assert_called_once_with() - suspend.assert_not_called() - - def test_xterm_match_records_last_raw_ewmh_window_id(self): - manager = input_event_manager.InputEventManager() - - with ( - mock.patch.object( - manager, - "_get_ewmh_active_x11_window_id", - return_value=0x1400010, - ), - mock.patch.object( - manager, - "_x11_window_id_xterm_match", - return_value=False, - ), - ): - result = manager._active_x11_window_xterm_match() - - self.assertFalse(result) - self.assertEqual(manager._lastEwmhReadWindowId, 0x1400010) - - def test_xterm_focus_poll_survives_transient_matcher_failure(self): - manager = input_event_manager.InputEventManager() - manager._device = object() - manager._xtermRecoverySourceId = 23 - - with ( - mock.patch.object( - manager, - "_active_x11_window_xterm_match", - side_effect=RuntimeError("transient matcher failure"), - ), - mock.patch.object(input_event_manager.debug, "print_message") as printMessage, - ): - result = manager._poll_xterm_grab_recovery() - - self.assertTrue(result) - self.assertEqual(manager._xtermRecoverySourceId, 23) - printMessage.assert_called_once() - - def test_ewmh_read_failure_reconnects_on_next_check(self): - manager = input_event_manager.InputEventManager() - x11Display = mock.Mock() - x11Root = mock.Mock() - x11Root.get_full_property.side_effect = RuntimeError("display connection failed") - manager._x11Display = x11Display - manager._x11Root = x11Root - manager._netActiveWindowAtom = object() - manager._x11AnyPropertyType = object() - manager._didAttemptX11Display = True - - with mock.patch.object(input_event_manager.debug, "print_message"): - result = manager._get_ewmh_active_x11_window_id() - - self.assertIsNone(result) - x11Display.close.assert_called_once_with() - self.assertFalse(manager._didAttemptX11Display) - - def test_xterm_suppression_does_not_check_x11_without_active_handoff(self): - manager = input_event_manager.InputEventManager() - - with mock.patch.object(manager, "_active_x11_window_xterm_match") as matcher: - result = manager.should_suppress_atspi_events_for_xterm(refresh=True) - - self.assertFalse(result) - matcher.assert_not_called() - - def test_xterm_suppression_ignores_background_event_without_x11_refresh(self): - manager = input_event_manager.InputEventManager() - manager._scriptWithSuspendedGrabsForXterm = object() - - with mock.patch.object(manager, "_active_x11_window_xterm_match") as matcher: - result = manager.should_suppress_atspi_events_for_xterm(refresh=False) - - self.assertTrue(result) - matcher.assert_not_called() - - def test_xterm_suppression_releases_handoff_for_real_focus_return(self): - manager = input_event_manager.InputEventManager() - activeScript = mock.Mock() - scriptManager = mock.Mock() - scriptManager.get_active_script.return_value = activeScript - manager._scriptWithSuspendedGrabsForXterm = activeScript - - with ( - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=False), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - result = manager.should_suppress_atspi_events_for_xterm(refresh=True) - - self.assertFalse(result) - activeScript.addKeyGrabs.assert_called_once_with() - self.assertIsNone(manager._scriptWithSuspendedGrabsForXterm) - - def test_xterm_focus_check_failure_starts_recovery_timer(self): - manager = input_event_manager.InputEventManager() - manager._device = object() - manager._scriptWithSuspendedGrabsForXterm = object() - - with ( - mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=None), - mock.patch.object(input_event_manager.GLib, "timeout_add", return_value=23), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - manager._on_active_x11_window_changed(mock.Mock(), None) - - self.assertEqual(manager._xtermRecoverySourceId, 23) - - def test_xterm_focus_monitor_is_connected_only_once(self): - manager = input_event_manager.InputEventManager() - screen = mock.Mock() - screen.connect.return_value = 17 - - manager._ensure_xterm_focus_monitor(screen) - manager._ensure_xterm_focus_monitor(screen) - - screen.connect.assert_called_once_with( - "active-window-changed", - manager._on_active_x11_window_changed, - ) - - def test_xterm_suspension_starts_fallback_when_focus_monitor_is_unavailable(self): - manager = input_event_manager.InputEventManager() - manager._device = object() - activeScript = mock.Mock() - scriptManager = mock.Mock() - scriptManager.get_active_script.return_value = activeScript - - with ( - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.GLib, "timeout_add", return_value=23) as timeoutAdd, - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - manager._suspend_key_grabs_for_xterm() - - timeoutAdd.assert_called_once_with(100, manager._poll_xterm_grab_recovery) - self.assertEqual(manager._xtermRecoverySourceId, 23) - - def test_xterm_grab_restore_failure_keeps_retry_state(self): - manager = input_event_manager.InputEventManager() - manager._device = object() - activeScript = mock.Mock() - activeScript.addKeyGrabs.side_effect = RuntimeError("grab failed") - scriptManager = mock.Mock() - scriptManager.get_active_script.return_value = activeScript - manager._scriptWithSuspendedGrabsForXterm = activeScript - - with ( - mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager), - mock.patch.object(input_event_manager.GLib, "timeout_add", return_value=23), - mock.patch.object(input_event_manager.debug, "print_message"), - mock.patch.object(input_event_manager.debug, "print_tokens"), - ): - manager._restore_key_grabs_after_xterm() - - self.assertIs(manager._scriptWithSuspendedGrabsForXterm, activeScript) - self.assertEqual(manager._xtermRecoverySourceId, 23) - activeScript.removeKeyGrabs.assert_called_once_with() - - def test_stopping_key_watcher_disconnects_xterm_focus_monitor(self): - manager = input_event_manager.InputEventManager() - screen = mock.Mock() - manager._xtermFocusScreen = screen - manager._xtermFocusHandlerId = 17 - manager._xtermRecoverySourceId = 23 - manager._scriptWithSuspendedGrabsForXterm = object() - x11Display = mock.Mock() - manager._x11Display = x11Display - manager._didAttemptX11Display = True - - with ( - mock.patch.object(input_event_manager.GLib, "source_remove") as sourceRemove, - mock.patch.object(input_event_manager.debug, "print_message"), - ): - manager.stop_key_watcher() - - screen.disconnect.assert_called_once_with(17) - sourceRemove.assert_called_once_with(23) - self.assertIsNone(manager._xtermFocusScreen) - self.assertEqual(manager._xtermFocusHandlerId, 0) - self.assertEqual(manager._xtermRecoverySourceId, 0) - self.assertIsNone(manager._scriptWithSuspendedGrabsForXterm) - x11Display.close.assert_called_once_with() - self.assertFalse(manager._didAttemptX11Display) - - def test_identifier_is_xterm_matches_exact_xterm_only(self): - self.assertTrue(input_event_manager.InputEventManager._identifier_is_xterm("xterm")) - self.assertTrue(input_event_manager.InputEventManager._identifier_is_xterm("/usr/bin/xterm")) - self.assertFalse(input_event_manager.InputEventManager._identifier_is_xterm("uxterm")) - self.assertFalse(input_event_manager.InputEventManager._identifier_is_xterm("gnome-terminal")) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_input_event_regressions.py b/tests/test_input_event_regressions.py deleted file mode 100644 index 9309966..0000000 --- a/tests/test_input_event_regressions.py +++ /dev/null @@ -1,65 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -soundGeneratorModule = sys.modules.get("cthulhu.sound_generator") -if soundGeneratorModule is not None and not hasattr(soundGeneratorModule, "SoundGenerator"): - class _StubSoundGenerator: - pass - - soundGeneratorModule.SoundGenerator = _StubSoundGenerator - -from gi.repository import Gdk - -from cthulhu import input_event - - -class KeyboardEventConsumptionTests(unittest.TestCase): - def test_script_consumed_key_without_handler_is_treated_as_consumed(self): - testScript = mock.Mock() - testScript.app = None - testScript.keyBindings.getInputHandler.return_value = None - testScript.shouldConsumeKeyboardEvent.return_value = True - testScript.learnModePresenter.is_active.return_value = False - testScript.presentKeyboardEvent.return_value = False - - keyboardEvent = input_event.KeyboardEvent( - True, - 36, - Gdk.KEY_Return, - 0, - "Return", - ) - keyboardEvent.set_script(testScript) - keyboardEvent.set_object(None) - keyboardEvent.set_window(None) - - with ( - mock.patch("cthulhu.input_event.cthulhu_state.capturingKeys", False), - mock.patch("cthulhu.input_event.cthulhu_state.bypassNextCommand", False), - ): - keyboardEvent._finalize_initialization() - self.assertTrue(keyboardEvent._should_consume) - self.assertEqual( - keyboardEvent._consume_reason, - "Script consumed without handler", - ) - - didConsume, resultReason = keyboardEvent._process() - - self.assertTrue(didConsume) - self.assertEqual(resultReason, "Consumed during shouldConsume") - testScript.presentationInterrupt.assert_called_once() - testScript.presentKeyboardEvent.assert_called_once_with(keyboardEvent) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_learn_mode_regressions.py b/tests/test_learn_mode_regressions.py deleted file mode 100644 index 69336e7..0000000 --- a/tests/test_learn_mode_regressions.py +++ /dev/null @@ -1,44 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - -gi.require_version("Gdk", "3.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from gi.repository import Gdk - -from cthulhu import cthulhu_state -from cthulhu import input_event -from cthulhu import learn_mode_presenter - - -class LearnModePresenterRegressionTests(unittest.TestCase): - def test_escape_keyval_exits_learn_mode_when_event_string_is_control_character(self): - presenter = learn_mode_presenter.LearnModePresenter(mock.Mock()) - presenter._is_active = True - - keyboardEvent = input_event.KeyboardEvent( - True, - 9, - Gdk.KEY_Escape, - 0, - "\x1b", - ) - - activeScript = mock.Mock() - - with mock.patch.object(cthulhu_state, "activeScript", activeScript): - result = presenter.handle_event(keyboardEvent) - - self.assertTrue(result) - self.assertFalse(presenter.is_active()) - activeScript.speakKeyEvent.assert_called_once_with(keyboardEvent) - activeScript.presentMessage.assert_called_once() - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_link_sound_regressions.py b/tests/test_link_sound_regressions.py deleted file mode 100644 index 85a68b1..0000000 --- a/tests/test_link_sound_regressions.py +++ /dev/null @@ -1,220 +0,0 @@ -import sys -import types -import unittest -from pathlib import Path -from unittest import mock -from types import SimpleNamespace - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -sound_stub = types.ModuleType("cthulhu.sound") -sound_stub.getPlayer = mock.Mock(return_value=None) -sys.modules.setdefault("cthulhu.sound", sound_stub) - -speech_stub = types.ModuleType("cthulhu.speech") -speech_stub.speak = mock.Mock() -sys.modules.setdefault("cthulhu.speech", speech_stub) - -from cthulhu import settings -from cthulhu.sound_generator import SoundGenerator -from cthulhu.sound_theme_manager import SoundThemeManager -from cthulhu.speech_generator import SpeechGenerator -from cthulhu.script_utilities import Utilities - - -class LinkSoundThemeRegressionTests(unittest.TestCase): - def test_default_theme_install_manifest_includes_link_sounds(self): - mesonPath = Path(__file__).resolve().parents[1] / "sounds" / "meson.build" - mesonText = mesonPath.read_text(encoding="utf-8") - - self.assertIn("'default/link.wav'", mesonText) - self.assertIn("'default/link_visited.wav'", mesonText) - - def _create_manager(self): - app = mock.Mock() - settingsManager = mock.Mock() - settingsManager.getSetting.return_value = "default" - app.getSettingsManager.return_value = settingsManager - return SoundThemeManager(app) - - def test_visited_link_prefers_visited_asset(self): - manager = self._create_manager() - - with mock.patch.object( - manager, - "getSoundPath", - side_effect=["/tmp/link_visited.wav", "/tmp/link.wav"], - ): - icon = manager.getLinkSoundIcon(visited=True) - - self.assertTrue(icon.path.endswith("link_visited.wav")) - - def test_visited_link_falls_back_to_plain_link_asset(self): - manager = self._create_manager() - - with mock.patch.object( - manager, - "getSoundPath", - side_effect=[None, "/tmp/link.wav"], - ): - icon = manager.getLinkSoundIcon(visited=True) - - self.assertTrue(icon.path.endswith("link.wav")) - - -class SpeechGeneratorLinkSoundRegressionTests(unittest.TestCase): - def test_role_sound_icon_uses_visited_link_asset_for_visited_links(self): - generator = object.__new__(SpeechGenerator) - generator._script = mock.Mock() - generator._script.utilities = mock.Mock() - - icon = SimpleNamespace(path="/tmp/link_visited.wav") - - with ( - mock.patch("cthulhu.speech_generator.AXUtilities.is_link", return_value=True), - mock.patch("cthulhu.speech_generator.AXUtilities.is_visited", return_value=True), - mock.patch("cthulhu.speech_generator.sound_theme_manager.getManager") as get_manager, - ): - get_manager.return_value.getLinkSoundIcon.return_value = icon - result = generator._getRoleSoundIcon(mock.Mock(), "link-role") - - self.assertEqual(result, icon) - get_manager.return_value.getLinkSoundIcon.assert_called_once_with(visited=True) - - -class LinkIndicatorPresentationRegressionTests(unittest.TestCase): - def test_sound_only_inline_link_marker_uses_icon_instead_of_word(self): - utility = object.__new__(Utilities) - utility.adjustForLinks = mock.Mock(return_value="Docs link") - - icon = SimpleNamespace(path="/tmp/link.wav") - link = mock.Mock() - - def get_setting(name): - values = { - "roleSoundPresentation": settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY, - "enableSound": True, - } - return values.get(name) - - fakeApp = mock.Mock() - fakeApp.settingsManager.getSetting.side_effect = get_setting - - with ( - mock.patch("cthulhu.script_utilities.AXObject.supports_hypertext", return_value=True), - mock.patch("cthulhu.script_utilities.AXHypertext.get_all_links", return_value=[link]), - mock.patch("cthulhu.script_utilities.AXHypertext.get_link_start_offset", return_value=0), - mock.patch("cthulhu.script_utilities.AXHypertext.get_link_end_offset", return_value=4), - mock.patch("cthulhu.script_utilities.AXUtilities.is_visited", return_value=False), - mock.patch("cthulhu.sound_theme_manager.getManager") as get_manager, - mock.patch("cthulhu.script_utilities.cthulhu.cthulhuApp", fakeApp), - ): - get_manager.return_value.getLinkSoundIcon.return_value = icon - spoken, icons = utility.getLinkIndicatorPresentation(mock.Mock(), "Docs", 0) - - self.assertEqual(spoken, "Docs") - self.assertEqual(icons, [icon]) - - def test_sound_and_speech_inline_link_marker_keeps_word_and_adds_icon(self): - utility = object.__new__(Utilities) - utility.adjustForLinks = mock.Mock(return_value="Docs link") - - icon = SimpleNamespace(path="/tmp/link_visited.wav") - link = mock.Mock() - - def get_setting(name): - values = { - "roleSoundPresentation": settings.ROLE_SOUND_PRESENTATION_SOUND_AND_SPEECH, - "enableSound": True, - } - return values.get(name) - - fakeApp = mock.Mock() - fakeApp.settingsManager.getSetting.side_effect = get_setting - - with ( - mock.patch("cthulhu.script_utilities.AXObject.supports_hypertext", return_value=True), - mock.patch("cthulhu.script_utilities.AXHypertext.get_all_links", return_value=[link]), - mock.patch("cthulhu.script_utilities.AXHypertext.get_link_start_offset", return_value=0), - mock.patch("cthulhu.script_utilities.AXHypertext.get_link_end_offset", return_value=4), - mock.patch("cthulhu.script_utilities.AXUtilities.is_visited", return_value=True), - mock.patch("cthulhu.sound_theme_manager.getManager") as get_manager, - mock.patch("cthulhu.script_utilities.cthulhu.cthulhuApp", fakeApp), - ): - get_manager.return_value.getLinkSoundIcon.return_value = icon - spoken, icons = utility.getLinkIndicatorPresentation(mock.Mock(), "Docs", 0) - - self.assertEqual(spoken, "Docs link") - self.assertEqual(icons, [icon]) - - def test_sound_pan_uses_object_position_inside_active_frame(self): - utility = object.__new__(Utilities) - obj = mock.Mock() - frame = mock.Mock() - icon = SimpleNamespace(path="/tmp/link.wav") - - fakeApp = mock.Mock() - fakeApp.settingsManager.getSetting.return_value = True - - def get_rect(target): - if target is frame: - return SimpleNamespace(x=0, y=0, width=1000, height=800) - if target is obj: - return SimpleNamespace(x=495, y=0, width=10, height=20) - return SimpleNamespace(x=0, y=0, width=0, height=0) - - utility.frameAndDialog = mock.Mock(return_value=[frame, None]) - - with ( - mock.patch("cthulhu.script_utilities.cthulhu.cthulhuApp", fakeApp), - mock.patch("cthulhu.script_utilities.AXComponent.get_rect", side_effect=get_rect), - ): - utility.spatializeSoundIcon(icon, obj) - - self.assertEqual(icon.pan, 0.0) - - def test_sound_pan_hard_pans_only_at_extreme_edges(self): - utility = object.__new__(Utilities) - obj = mock.Mock() - frame = mock.Mock() - fakeApp = mock.Mock() - fakeApp.settingsManager.getSetting.return_value = True - - utility.frameAndDialog = mock.Mock(return_value=[frame, None]) - - with ( - mock.patch("cthulhu.script_utilities.cthulhu.cthulhuApp", fakeApp), - mock.patch( - "cthulhu.script_utilities.AXComponent.get_rect", - side_effect=[ - SimpleNamespace(x=0, y=0, width=10, height=20), - SimpleNamespace(x=0, y=0, width=1000, height=800), - ], - ), - ): - self.assertEqual(utility.getSoundPanForObject(obj), -1.0) - - -class SoundGeneratorSpatializationRegressionTests(unittest.TestCase): - def test_generated_icons_and_tones_are_spatialized(self): - generator = object.__new__(SoundGenerator) - icon = SimpleNamespace(path="/tmp/link.wav") - tone = SimpleNamespace(duration=0.1, frequency=440, volume=0.5, wave=0) - generator._script = mock.Mock() - generator._script.utilities.spatializeSoundIcon.side_effect = lambda sound, obj: sound - - fakeApp = mock.Mock() - fakeApp.settingsManager.getSetting.return_value = True - obj = mock.Mock() - - with mock.patch("cthulhu.sound_generator.cthulhu.cthulhuApp", fakeApp): - result = generator._spatializeSounds([icon, [tone]], obj) - - self.assertEqual(result, [icon, [tone]]) - generator._script.utilities.spatializeSoundIcon.assert_has_calls( - [mock.call(icon, obj), mock.call(tone, obj)] - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_mako_notification_monitor.py b/tests/test_mako_notification_monitor.py deleted file mode 100644 index bac570f..0000000 --- a/tests/test_mako_notification_monitor.py +++ /dev/null @@ -1,160 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import notification_presenter -from cthulhu.mako_notification_monitor import MakoNotificationMonitor - - -class _FakeScript: - def __init__(self): - self.speechGenerator = mock.Mock() - self.speechGenerator.voice.return_value = object() - self.speakMessage = mock.Mock() - self.displayBrailleMessage = mock.Mock() - - -class _FakeScriptManager: - def __init__(self, script): - self._script = script - - def get_default_script(self): - return self._script - - -class _FakeApp: - def __init__(self, script): - self._script_manager = _FakeScriptManager(script) - - def getScriptManager(self): - return self._script_manager - - -class MakoNotificationMonitorTests(unittest.TestCase): - def setUp(self): - self.presenter = notification_presenter.NotificationPresenter() - self.script = _FakeScript() - self.app = _FakeApp(self.script) - - presenter_patcher = mock.patch( - "cthulhu.mako_notification_monitor.notification_presenter.getPresenter", - return_value=self.presenter, - ) - self.addCleanup(presenter_patcher.stop) - presenter_patcher.start() - - self.monitor = MakoNotificationMonitor(self.app) - self.monitor._generation = 1 - - def test_initial_seed_does_not_announce_existing_notifications(self): - self.monitor._sync_notifications( - [ - { - "id": 10, - "app-name": "discord", - "summary": "hello", - "body": "world", - "actions": {"default": "View"}, - } - ], - announce_new=False, - ) - - self.assertEqual(self.monitor._known_ids, {10}) - self.assertEqual(self.presenter._notifications, []) - self.script.speakMessage.assert_not_called() - self.script.displayBrailleMessage.assert_not_called() - - def test_new_notification_is_spoken_and_saved(self): - self.monitor._sync_notifications( - [ - { - "id": 10, - "app-name": "discord", - "summary": "old", - "body": "", - "actions": {}, - } - ], - announce_new=False, - ) - - self.monitor._sync_notifications( - [ - { - "id": 10, - "app-name": "discord", - "summary": "old", - "body": "", - "actions": {}, - }, - { - "id": 11, - "app-name": "discord", - "summary": "new summary", - "body": "new body", - "actions": {"default": "View"}, - }, - ], - announce_new=True, - ) - - self.assertEqual(len(self.presenter._notifications), 1) - entry = self.presenter._notifications[0] - self.assertEqual(entry.notification_id, 11) - self.assertTrue(entry.live) - self.assertEqual(entry.source, "mako") - self.assertEqual(entry.actions, {"default": "View"}) - self.assertEqual(entry.message, "Notification new summary new body") - self.script.speakMessage.assert_called_once() - self.script.displayBrailleMessage.assert_called_once() - - def test_removed_notification_is_marked_not_live(self): - self.monitor._sync_notifications( - [ - { - "id": 11, - "app-name": "discord", - "summary": "new summary", - "body": "new body", - "actions": {"default": "View"}, - }, - ], - announce_new=True, - ) - - self.assertTrue(self.presenter._notifications[0].live) - - self.monitor._sync_notifications([], announce_new=False) - - self.assertFalse(self.presenter._notifications[0].live) - self.assertEqual(self.monitor._known_ids, set()) - - def test_parse_notification_strips_markup_and_normalizes_actions(self): - parsed = self.monitor._parse_notification( - { - "id": 22, - "app-name": "Crash Reporting System", - "summary": "Service Crash", - "body": "/usr/bin/python3.14 crashed", - "desktop-entry": "crash-handler", - "urgency": 2, - "actions": {"1": "Details"}, - } - ) - - self.assertEqual(parsed["notification_id"], 22) - self.assertEqual(parsed["summary"], "Service Crash") - self.assertEqual(parsed["body"], "/usr/bin/python3.14 crashed") - self.assertEqual(parsed["actions"], {"1": "Details"}) - self.assertEqual( - parsed["message"], - "Notification Service Crash /usr/bin/python3.14 crashed", - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_mouse_review_pointer_monitor_regressions.py b/tests/test_mouse_review_pointer_monitor_regressions.py deleted file mode 100644 index 70d6e7b..0000000 --- a/tests/test_mouse_review_pointer_monitor_regressions.py +++ /dev/null @@ -1,232 +0,0 @@ -import sys -import types -import unittest -from pathlib import Path -from typing import Any -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import input_event_manager -from cthulhu import mouse_review - - -class FakeDevice: - def __init__(self): - self.add_key_watcher_calls = [] - self.connect_calls = [] - self.disconnect_calls = [] - self.set_capabilities_calls = [] - self.capabilities = 0 - self.next_handler_id = 17 - - def add_key_watcher(self, callback, user_data=None): - self.add_key_watcher_calls.append((callback, user_data)) - - def connect(self, signalName, callback): - self.connect_calls.append((signalName, callback)) - return self.next_handler_id - - def disconnect(self, handlerId): - self.disconnect_calls.append(handlerId) - - def get_capabilities(self): - return self.capabilities - - def set_capabilities(self, capabilities): - self.set_capabilities_calls.append(capabilities) - self.capabilities = capabilities - return capabilities - - -class FakeDeviceFactory: - def __init__(self, device): - self.device = device - self.new_calls = 0 - self.new_full_calls = 0 - self.app_ids = [] - - def new(self): - self.new_calls += 1 - return self.device - - def new_full(self, appId): - self.new_full_calls += 1 - self.app_ids.append(appId) - return self.device - - -class InputEventManagerPointerMonitorTests(unittest.TestCase): - def setUp(self): - self.manager = input_event_manager.InputEventManager() - - def test_activate_device_creates_the_device_only_once(self): - device = FakeDevice() - deviceFactory = FakeDeviceFactory(device) - fakeAtspi = types.SimpleNamespace( - get_version=lambda: (2, 58, 4), - Device=deviceFactory, - ) - - with mock.patch.object(input_event_manager, "Atspi", fakeAtspi): - firstDevice = self.manager.activate_device() - secondDevice = self.manager.activate_device() - - self.assertIs(firstDevice, device) - self.assertIs(secondDevice, device) - self.assertEqual(deviceFactory.new_full_calls, 1) - self.assertEqual(deviceFactory.new_calls, 0) - self.assertEqual(deviceFactory.app_ids, ["org.stormux.Cthulhu"]) - - def test_enable_pointer_monitoring_returns_false_without_a_device(self): - fakeAtspi = types.SimpleNamespace() - - with mock.patch.object(input_event_manager, "Atspi", fakeAtspi): - self.assertFalse(self.manager.enable_pointer_monitoring()) - - def test_enable_pointer_monitoring_returns_false_when_device_capability_is_missing(self): - device = FakeDevice() - deviceFactory = FakeDeviceFactory(device) - fakeAtspi = types.SimpleNamespace( - get_version=lambda: (2, 58, 4), - Device=deviceFactory, - ) - - with mock.patch.object(input_event_manager, "Atspi", fakeAtspi): - self.manager.activate_device() - self.assertFalse(self.manager.enable_pointer_monitoring()) - - self.assertEqual(device.set_capabilities_calls, []) - - def test_enable_pointer_monitoring_returns_true_when_pointer_monitor_is_granted(self): - device = FakeDevice() - deviceFactory = FakeDeviceFactory(device) - fakeDeviceCapability = types.SimpleNamespace(POINTER_MONITOR=8) - fakeAtspi = types.SimpleNamespace( - get_version=lambda: (2, 58, 4), - Device=deviceFactory, - DeviceCapability=fakeDeviceCapability, - ) - - with mock.patch.object(input_event_manager, "Atspi", fakeAtspi): - self.manager.activate_device() - self.assertTrue(self.manager.enable_pointer_monitoring()) - - self.assertEqual(device.set_capabilities_calls, [8]) - self.assertEqual(device.capabilities, 8) - - def test_start_and_stop_pointer_watcher_connect_and_disconnect_pointer_moved(self): - device = FakeDevice() - deviceFactory = FakeDeviceFactory(device) - fakeAtspi = types.SimpleNamespace( - get_version=lambda: (2, 58, 4), - Device=deviceFactory, - ) - callback = mock.Mock() - - with mock.patch.object(input_event_manager, "Atspi", fakeAtspi): - self.manager.activate_device() - self.manager.start_pointer_watcher(callback) - self.manager.stop_pointer_watcher() - - self.assertEqual(device.connect_calls, [("pointer-moved", callback)]) - self.assertEqual(device.disconnect_calls, [17]) - - -class MouseReviewBackendSelectionTests(unittest.TestCase): - @staticmethod - def _make_atspi( - version: tuple[int, int, int], - listener: Any, - pointerMonitor: int | None = None, - ) -> types.SimpleNamespace: - fakeAtspi = types.SimpleNamespace( - EventListener=types.SimpleNamespace(new=mock.Mock(return_value=listener)), - get_version=mock.Mock(return_value=version), - ) - if pointerMonitor is not None: - fakeAtspi.DeviceCapability = types.SimpleNamespace(POINTER_MONITOR=pointerMonitor) - return fakeAtspi - - @staticmethod - def _make_app(enabled=False): - app = mock.Mock() - settingsManager = mock.Mock() - settingsManager.getSetting.return_value = enabled - app.getSettingsManager.return_value = settingsManager - app.getScriptManager.return_value = mock.Mock() - return app - - def test_prefers_atspi_backend_when_version_and_capability_are_available(self): - listener = mock.Mock() - deviceManager = mock.Mock() - deviceManager.enable_pointer_monitoring.return_value = True - fakeAtspi = self._make_atspi((2, 60, 0), listener, pointerMonitor=8) - - with ( - mock.patch.object(mouse_review, "Atspi", fakeAtspi), - mock.patch.object(mouse_review.input_event_manager, "get_manager", return_value=deviceManager), - mock.patch.object(mouse_review, "Wnck", None), - ): - reviewer = mouse_review.MouseReviewer(self._make_app()) - - self.assertTrue(reviewer._useAtspi) - self.assertTrue(reviewer._mouseReviewCapable) - deviceManager.activate_device.assert_called_once_with() - deviceManager.enable_pointer_monitoring.assert_called_once_with() - - def test_activate_uses_pointer_watcher_for_atspi_backend(self): - listener = mock.Mock() - deviceManager = mock.Mock() - deviceManager.enable_pointer_monitoring.return_value = True - fakeAtspi = self._make_atspi((2, 60, 0), listener, pointerMonitor=8) - - with ( - mock.patch.object(mouse_review, "Atspi", fakeAtspi), - mock.patch.object(mouse_review.input_event_manager, "get_manager", return_value=deviceManager), - mock.patch.object(mouse_review.cthulhu_state, "locusOfFocus", None), - mock.patch.object(mouse_review, "Wnck", None), - ): - reviewer = mouse_review.MouseReviewer(self._make_app(enabled=False)) - reviewer.activate() - reviewer.deactivate() - - deviceManager.start_pointer_watcher.assert_called_once_with(reviewer._on_pointer_moved) - deviceManager.stop_pointer_watcher.assert_called_once_with() - listener.register.assert_not_called() - - def test_keeps_legacy_backend_when_atspi_pointer_monitor_is_unavailable(self): - listener = mock.Mock() - pointer = mock.Mock() - seat = mock.Mock() - seat.get_pointer.return_value = pointer - screen = mock.Mock() - screen.get_windows_stacked.return_value = [] - screen.get_active_workspace.return_value = None - fakeWnck = mock.Mock() - fakeWnck.Screen.get_default.return_value = screen - fakeAtspi = self._make_atspi((2, 58, 4), listener) - fakeGdk = types.SimpleNamespace( - Display=types.SimpleNamespace( - get_default=mock.Mock(return_value=mock.Mock()), - get_default_seat=mock.Mock(return_value=seat), - ), - ) - - with ( - mock.patch.object(mouse_review, "Atspi", fakeAtspi), - mock.patch.object(mouse_review.input_event_manager, "get_manager"), - mock.patch.object(mouse_review.cthulhu_state, "locusOfFocus", None), - mock.patch.object(mouse_review, "Gdk", fakeGdk), - mock.patch.object(mouse_review, "Wnck", fakeWnck), - ): - reviewer = mouse_review.MouseReviewer(self._make_app(enabled=False)) - reviewer.activate() - - self.assertFalse(reviewer._useAtspi) - self.assertTrue(reviewer._mouseReviewCapable) - listener.register.assert_called_once_with("mouse:abs") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_native_test_session.py b/tests/test_native_test_session.py new file mode 100644 index 0000000..931a786 --- /dev/null +++ b/tests/test_native_test_session.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +# Copyright (c) 2026 Storm Dragon +# Authors: Storm Dragon, Angus Kola +# SPDX-License-Identifier: GPL-3.0-or-later +"""Runtime isolation and real AT-SPI socket collision regressions.""" +import ast +import json +import os +from pathlib import Path +import socket +import stat +import subprocess +import sys +import tempfile +import unittest +from unittest.mock import patch + +from native_test_session import run_private_session + + +class PrivateSessionTests(unittest.TestCase): + def test_child_runtime_and_bus_are_private(self): + environment = dict(os.environ, XDG_RUNTIME_DIR="/invalid/desktop-runtime", + DBUS_SESSION_BUS_ADDRESS="unix:path=/invalid/desktop-bus", + AT_SPI_BUS_ADDRESS="unix:path=/invalid/accessibility-bus", + DBUS_STARTER_ADDRESS="unix:path=/invalid/starter-bus", + DBUS_STARTER_BUS_TYPE="session", WAYLAND_DISPLAY="desktop-wayland") + originalEnv = environment.copy() + script = """import json, os, socket, stat +from pathlib import Path +runtime = Path(os.environ['XDG_RUNTIME_DIR']) +listener = socket.socket(socket.AF_UNIX) +listener.bind(str(runtime / 'probe.sock')) +print(json.dumps(dict(runtime=str(runtime), mode=stat.S_IMODE(runtime.stat().st_mode), + bus=os.environ['DBUS_SESSION_BUS_ADDRESS'], + inherited=[name for name in ('AT_SPI_BUS_ADDRESS', 'DBUS_STARTER_ADDRESS', + 'DBUS_STARTER_BUS_TYPE', 'WAYLAND_DISPLAY') if name in os.environ]))) +""" + result = run_private_session( + ["dbus-run-session", "--", sys.executable, "-c", script], env=environment, + capture_output=True, text=True, check=True, timeout=15) + state = json.loads(result.stdout) + self.assertEqual(state["mode"], 0o700) + self.assertEqual(state["inherited"], []) + self.assertNotEqual(state["bus"], originalEnv["DBUS_SESSION_BUS_ADDRESS"]) + self.assertFalse(Path(state["runtime"]).exists(), "child runtime was not cleaned up") + self.assertEqual(environment, originalEnv) + + def test_cleanup_after_child_failure(self): + script = "import os, sys; print(os.environ['XDG_RUNTIME_DIR'], flush=True); sys.exit(7)" + with self.assertRaises(subprocess.CalledProcessError) as caught: + run_private_session( + ["dbus-run-session", "--", sys.executable, "-c", script], env=os.environ, + capture_output=True, text=True, check=True, timeout=15) + self.assertEqual(caught.exception.returncode, 7) + self.assertFalse(Path(caught.exception.stdout.strip()).exists()) + + def test_rejects_dbus_before_xvfb_without_launching(self): + with patch("native_test_session.subprocess.run") as launch: + with self.assertRaisesRegex(ValueError, "Start Xvfb before D-Bus"): + run_private_session( + ["dbus-run-session", "--", "xvfb-run", "-a", "true"], env=os.environ) + launch.assert_not_called() + + def test_cli_activates_atspi_on_virtual_display(self): + script = """import ast, json, os, subprocess +result = subprocess.run(['gdbus', 'call', '--session', '--dest', 'org.a11y.Bus', + '--object-path', '/org/a11y/bus', '--method', 'org.a11y.Bus.GetAddress'], + capture_output=True, text=True, check=True, timeout=10) +print(json.dumps(dict(display=os.environ['DISPLAY'], runtime=os.environ['XDG_RUNTIME_DIR'], + address=ast.literal_eval(result.stdout)[0]))) +""" + result = subprocess.run( + [sys.executable, "-B", str(Path(__file__).with_name("native_test_session.py")), + sys.executable, "-c", script], + env=dict(os.environ, DISPLAY=":7777"), capture_output=True, text=True, + check=True, timeout=20) + state = json.loads(result.stdout) + self.assertNotEqual(state["display"], ":7777") + expectedPath = Path(state["runtime"]) / "at-spi" / ("bus" + state["display"].replace(":", "_")) + self.assertEqual(state["address"].split(",", 1)[0], "unix:path=" + str(expectedPath)) + self.assertFalse(Path(state["runtime"]).exists()) + + def test_atspi_activation_preserves_other_session_socket(self): + # No real display is contacted. Reproduce D-Bus inheriting one display + # while its client uses another, with a live canary in the parent runtime. + with tempfile.TemporaryDirectory(prefix="cth-parent-", dir="/tmp") as parentRuntime: + socketDir = Path(parentRuntime) / "at-spi" + socketDir.mkdir(mode=0o700) + socketPath = socketDir / "bus_7777" + with socket.socket(socket.AF_UNIX) as listener: + listener.bind(str(socketPath)) + listener.listen(1) + originalInode = socketPath.stat().st_ino + environment = dict(os.environ, XDG_RUNTIME_DIR=parentRuntime, DISPLAY=":7777", + AT_SPI_BUS_ADDRESS="unix:path=/invalid/desktop-accessibility") + result = run_private_session( + ["dbus-run-session", "--", "env", "DISPLAY=:7778", "gdbus", "call", + "--session", "--dest", "org.a11y.Bus", "--object-path", "/org/a11y/bus", + "--method", "org.a11y.Bus.GetAddress"], env=environment, + capture_output=True, text=True, check=True, timeout=15) + address = ast.literal_eval(result.stdout)[0] + busPath = Path(address.split(",", 1)[0].removeprefix("unix:path=")) + self.assertEqual(busPath.name, "bus_7777", address) + self.assertNotEqual(busPath.parent.parent, Path(parentRuntime)) + self.assertFalse(busPath.parent.parent.exists(), "private runtime survived cleanup") + self.assertEqual(socketPath.stat().st_ino, originalInode) + self.assertTrue(stat.S_ISSOCK(socketPath.stat().st_mode)) + with socket.socket(socket.AF_UNIX) as client: + client.settimeout(2) + client.connect(str(socketPath)) + connection, _ = listener.accept() + connection.close() + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_notification_daemon_regressions.py b/tests/test_notification_daemon_regressions.py deleted file mode 100644 index 3712285..0000000 --- a/tests/test_notification_daemon_regressions.py +++ /dev/null @@ -1,58 +0,0 @@ -import importlib -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import messages - -notification_script = importlib.import_module("cthulhu.scripts.apps.notification-daemon.script") - - -class NotificationDaemonTests(unittest.TestCase): - def test_window_created_ignores_empty_labels(self): - testScript = notification_script.Script.__new__(notification_script.Script) - labelEmpty = object() - labelText = object() - eventSource = object() - event = mock.Mock(source=eventSource) - - testScript.utilities = mock.Mock() - testScript.utilities.displayedText.side_effect = lambda obj: { - labelEmpty: None, - labelText: "this is a test", - }.get(obj) - testScript.speechGenerator = mock.Mock() - testScript.speechGenerator.voice.return_value = object() - testScript.speakMessage = mock.Mock() - testScript.displayBrailleMessage = mock.Mock() - testScript.notificationPresenter = mock.Mock() - - with ( - mock.patch.object( - notification_script.AXUtilities, - "find_all_labels", - return_value=[labelEmpty, labelText], - ), - mock.patch.object( - notification_script.AXObject, - "get_name", - side_effect=lambda obj: { - labelEmpty: "", - labelText: "", - }.get(obj, ""), - ), - ): - testScript.onWindowCreated(event) - - expectedText = f"{messages.NOTIFICATION} this is a test" - testScript.speechGenerator.voice.assert_called_once_with(obj=eventSource, string=expectedText) - testScript.speakMessage.assert_called_once_with(expectedText, voice=testScript.speechGenerator.voice.return_value) - testScript.displayBrailleMessage.assert_called_once() - testScript.notificationPresenter.save_notification.assert_called_once_with(expectedText) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_notification_presenter_mako_regressions.py b/tests/test_notification_presenter_mako_regressions.py deleted file mode 100644 index b66ae35..0000000 --- a/tests/test_notification_presenter_mako_regressions.py +++ /dev/null @@ -1,409 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import notification_presenter -from cthulhu import messages -from cthulhu.notification_presenter import NotificationPresenter - - -class _FakeMonitor: - def __init__(self): - self.dismissed = [] - self.invoked = [] - self.current_generation = 2 - - def refresh(self, announce_new=False): - return True - - def is_current_entry(self, entry): - return entry.source == "mako" and entry.source_generation == self.current_generation - - def dismiss_notification(self, notification_id): - self.dismissed.append(notification_id) - return True - - def invoke_action(self, notification_id, action_key): - self.invoked.append((notification_id, action_key)) - return True - - -class _FakeButton: - def __init__(self, label=None): - self.label = label - self.sensitive = True - self._signals = {} - - def connect(self, signal_name, callback, *args): - self._signals[signal_name] = (callback, args) - - def set_sensitive(self, value): - self.sensitive = value - - def set_margin_top(self, _value): - return None - - def click(self): - callback, args = self._signals["clicked"] - callback(self, *args) - - -class _FakeBox: - def __init__(self): - self.children = [] - - def get_children(self): - return list(self.children) - - def remove(self, child): - self.children.remove(child) - - def pack_start(self, child, expand, fill, padding): - del expand, fill, padding - self.children.append(child) - - def show_all(self): - return None - - -class _FakeLabel: - def __init__(self): - self.text = "" - self.visible = False - - def set_text(self, value): - self.text = value - - def set_visible(self, value): - self.visible = value - - -class _FakeListStore: - def __init__(self, rows=None): - self.rows = list(rows or []) - - def iter_n_children(self, _parent): - return len(self.rows) - - def get_iter(self, path): - index = path if isinstance(path, int) else path[0] - if 0 <= index < len(self.rows): - return index - return None - - def get_value(self, row_iter, column): - return self.rows[row_iter][column] - - def remove(self, row_iter): - del self.rows[row_iter] - return row_iter < len(self.rows) - - -class _FakeSelection: - def __init__(self, model=None, selected_path=0): - self.model = model - self.selected_path = selected_path - - def get_selected_rows(self): - if self.selected_path is None: - return self.model, [] - return self.model, [self.selected_path] - - def select_path(self, path): - self.selected_path = path - - -class NotificationPresenterMakoTests(unittest.TestCase): - def setUp(self): - self.presenter = NotificationPresenter() - self.monitor = _FakeMonitor() - self.presenter.set_mako_monitor(self.monitor) - - def test_sync_updates_current_generation_only(self): - old_entry = self.presenter.save_notification( - "Notification old", - source="mako", - source_generation=1, - notification_id=5, - live=False, - actions={"default": "Old"}, - ) - current_entry = self.presenter.save_notification( - "Notification current", - source="mako", - source_generation=2, - notification_id=6, - live=True, - actions={"default": "View"}, - ) - - self.presenter.sync_live_notifications( - "mako", - { - 5: { - "message": "Notification replaced", - "actions": {"default": "New"}, - "app_name": "discord", - "summary": "replaced", - "body": "", - "urgency": 1, - "desktop_entry": "discord", - } - }, - source_generation=2, - ) - - self.assertEqual(old_entry.message, "Notification old") - self.assertEqual(old_entry.actions, {"default": "Old"}) - self.assertFalse(current_entry.live) - - def test_can_control_entry_and_get_actions_require_current_monitor_generation(self): - entry = self.presenter.save_notification( - "Notification current", - source="mako", - source_generation=2, - notification_id=6, - live=True, - actions={"default": "View"}, - ) - - self.assertTrue(self.presenter.can_control_entry(entry)) - self.assertEqual(self.presenter.get_actions_for_entry(entry), {"default": "View"}) - - stale_entry = self.presenter.save_notification( - "Notification stale", - source="mako", - source_generation=1, - notification_id=7, - live=True, - actions={"default": "Open"}, - ) - - self.assertFalse(self.presenter.can_control_entry(stale_entry)) - self.assertEqual(self.presenter.get_actions_for_entry(stale_entry), {}) - - def test_dismiss_and_invoke_action_route_through_monitor(self): - entry = self.presenter.save_notification( - "Notification current", - source="mako", - source_generation=2, - notification_id=6, - live=True, - actions={"default": "View"}, - ) - script = mock.Mock() - - self.assertTrue(self.presenter.dismiss_entry(script, entry)) - self.assertEqual(self.monitor.dismissed, [6]) - self.assertEqual(self.presenter._notifications, []) - script.presentMessage.assert_called_with(messages.NOTIFICATION_DISMISSED) - - script.reset_mock() - entry = self.presenter.save_notification( - "Notification current", - source="mako", - source_generation=2, - notification_id=6, - live=True, - actions={"default": "View"}, - ) - self.assertTrue(self.presenter.invoke_action_for_entry(script, entry, "default")) - self.assertEqual(self.monitor.invoked, [(6, "default")]) - script.presentMessage.assert_called_with(messages.NOTIFICATION_ACTION_INVOKED) - - def test_notification_list_dismiss_removes_selected_entry_from_history_and_model(self): - entry = self.presenter.save_notification( - "Notification current", - source="mako", - source_generation=2, - notification_id=6, - live=True, - actions={"default": "View"}, - ) - remaining = self.presenter.save_notification( - "Notification stale", - source="mako", - source_generation=1, - notification_id=7, - live=False, - actions={}, - ) - - gui = notification_presenter.NotificationListGUI.__new__( - notification_presenter.NotificationListGUI - ) - gui._script = mock.Mock() - gui._presenter = self.presenter - gui._dismiss_button = _FakeButton() - gui._actions_box = _FakeBox() - gui._actions_status_label = _FakeLabel() - gui._model = _FakeListStore( - [ - [entry.message, "now", entry], - [remaining.message, "later", remaining], - ] - ) - gui._selection = _FakeSelection(model=gui._model, selected_path=0) - gui._update_action_buttons = mock.Mock() - - gui._dismiss_selected_notification() - - self.assertEqual(self.monitor.dismissed, [6]) - self.assertEqual(self.presenter._notifications, [remaining]) - self.assertEqual(gui._model.rows, [[remaining.message, "later", remaining]]) - gui._script.presentMessage.assert_called_with(messages.NOTIFICATION_DISMISSED) - - def test_notification_list_dismiss_reselects_remaining_row_after_removing_last_selection(self): - remaining = self.presenter.save_notification( - "Notification stale", - source="mako", - source_generation=1, - notification_id=7, - live=False, - actions={}, - ) - entry = self.presenter.save_notification( - "Notification current", - source="mako", - source_generation=2, - notification_id=6, - live=True, - actions={"default": "View"}, - ) - - gui = notification_presenter.NotificationListGUI.__new__( - notification_presenter.NotificationListGUI - ) - gui._script = mock.Mock() - gui._presenter = self.presenter - gui._dismiss_button = _FakeButton() - gui._actions_box = _FakeBox() - gui._actions_status_label = _FakeLabel() - gui._model = _FakeListStore( - [ - [remaining.message, "later", remaining], - [entry.message, "now", entry], - ] - ) - gui._selection = _FakeSelection(model=gui._model, selected_path=1) - gui._update_action_buttons = mock.Mock() - - gui._dismiss_selected_notification() - - self.assertEqual(gui._model.rows, [[remaining.message, "later", remaining]]) - self.assertEqual(gui._selection.selected_path, 0) - - def test_notification_list_builds_inline_action_buttons_in_reported_order(self): - entry = self.presenter.save_notification( - "Notification current", - source="mako", - source_generation=2, - notification_id=6, - live=True, - actions={"default": "View", "snooze": "Snooze"}, - ) - - gui = notification_presenter.NotificationListGUI.__new__( - notification_presenter.NotificationListGUI - ) - gui._script = mock.Mock() - gui._presenter = mock.Mock() - gui._presenter.can_control_entry.return_value = True - gui._presenter.get_actions_for_entry.return_value = { - "default": "View", - "snooze": "Snooze", - } - gui._presenter.invoke_action_for_entry.return_value = True - gui._dismiss_button = _FakeButton() - gui._actions_box = _FakeBox() - gui._actions_status_label = _FakeLabel() - gui._get_selected_entry = mock.Mock(return_value=entry) - - with mock.patch.object(notification_presenter.Gtk, "Button", _FakeButton): - gui._update_action_buttons() - self.assertTrue(gui._dismiss_button.sensitive) - self.assertEqual( - [button.label for button in gui._actions_box.children], - ["View", "Snooze"], - ) - gui._actions_box.children[1].click() - - gui._presenter.invoke_action_for_entry.assert_called_once_with( - gui._script, - entry, - "snooze", - ) - - def test_notification_list_clears_inline_actions_when_notification_is_unavailable(self): - entry = self.presenter.save_notification( - "Notification stale", - source="mako", - source_generation=1, - notification_id=7, - live=True, - actions={"default": "Open"}, - ) - - gui = notification_presenter.NotificationListGUI.__new__( - notification_presenter.NotificationListGUI - ) - gui._script = mock.Mock() - gui._presenter = mock.Mock() - gui._presenter.can_control_entry.return_value = False - gui._presenter.get_actions_for_entry.return_value = {} - gui._dismiss_button = _FakeButton() - gui._actions_box = _FakeBox() - gui._actions_box.children.append(_FakeButton("Old")) - gui._actions_status_label = _FakeLabel() - gui._get_selected_entry = mock.Mock(return_value=entry) - - with mock.patch.object(notification_presenter.Gtk, "Button", _FakeButton): - gui._update_action_buttons() - - self.assertFalse(gui._dismiss_button.sensitive) - self.assertEqual(gui._actions_box.children, []) - self.assertEqual( - gui._actions_status_label.text, - messages.NOTIFICATION_UNAVAILABLE, - ) - self.assertTrue(gui._actions_status_label.visible) - - def test_notification_list_shows_no_actions_state_for_live_notification_without_actions(self): - entry = self.presenter.save_notification( - "Notification current", - source="mako", - source_generation=2, - notification_id=8, - live=True, - actions={}, - ) - - gui = notification_presenter.NotificationListGUI.__new__( - notification_presenter.NotificationListGUI - ) - gui._script = mock.Mock() - gui._presenter = mock.Mock() - gui._presenter.can_control_entry.return_value = True - gui._presenter.get_actions_for_entry.return_value = {} - gui._dismiss_button = _FakeButton() - gui._actions_box = _FakeBox() - gui._actions_status_label = _FakeLabel() - gui._get_selected_entry = mock.Mock(return_value=entry) - - with mock.patch.object(notification_presenter.Gtk, "Button", _FakeButton): - gui._update_action_buttons() - - self.assertTrue(gui._dismiss_button.sensitive) - self.assertEqual(gui._actions_box.children, []) - self.assertEqual( - gui._actions_status_label.text, - messages.NOTIFICATION_NO_ACTIONS, - ) - self.assertTrue(gui._actions_status_label.visible) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_nvda2cthulhu_regressions.py b/tests/test_nvda2cthulhu_regressions.py deleted file mode 100644 index 91bcdb3..0000000 --- a/tests/test_nvda2cthulhu_regressions.py +++ /dev/null @@ -1,47 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu.plugins.nvda2cthulhu import plugin as nvda_plugin - - -class Nvda2CthulhuRegressionTests(unittest.TestCase): - def _make_plugin(self): - plugin = nvda_plugin.Nvda2Cthulhu.__new__(nvda_plugin.Nvda2Cthulhu) - plugin.interruptEnabled = True - plugin._dependencies_available = mock.Mock(return_value=True) - return plugin - - def test_text_cancel_speech_frame_is_cancel_request(self): - plugin = self._make_plugin() - - self.assertEqual(("CancelSpeech", None), plugin._parse_request("CancelSpeech")) - - def test_websocket_speech_is_queued_instead_of_handled_synchronously(self): - plugin = self._make_plugin() - plugin._translation_enabled = mock.Mock(return_value=False) - - with mock.patch.object(nvda_plugin.speech, "speak") as speak: - plugin.handle_message("hello") - - speak.assert_not_called() - - def test_queued_websocket_speech_runs_on_main_loop(self): - if not hasattr(nvda_plugin, "GLib"): - self.fail("nvda2cthulhu does not expose a GLib main-loop dispatcher") - - plugin = self._make_plugin() - plugin._translation_enabled = mock.Mock(return_value=False) - - with mock.patch.object(nvda_plugin.GLib, "idle_add", side_effect=lambda callback, *args: callback(*args)), \ - mock.patch.object(nvda_plugin.speech, "speak") as speak: - plugin.handle_message("hello") - - speak.assert_called_once_with("hello", interrupt=True) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_piperfactory_rate_mapping.py b/tests/test_piperfactory_rate_mapping.py deleted file mode 100644 index 7ebd937..0000000 --- a/tests/test_piperfactory_rate_mapping.py +++ /dev/null @@ -1,78 +0,0 @@ -import sys -import threading -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import piperfactory -from cthulhu import speechserver - - -class PiperFactoryRateMappingTests(unittest.TestCase): - def setUp(self): - self.server = piperfactory.SpeechServer.__new__(piperfactory.SpeechServer) - - def test_default_rate_maps_to_native_piper_speed(self): - self.assertEqual(1.0, self.server._mapRate(50)) - - def test_rate_scale_uses_full_cthulhu_range(self): - self.assertEqual(2.0, self.server._mapRate(0)) - self.assertEqual(0.25, self.server._mapRate(100)) - - def test_high_screen_reader_rate_is_substantially_faster(self): - self.assertAlmostEqual(0.415, self.server._mapRate(89), places=3) - - def test_rate_values_are_clamped(self): - self.assertEqual(2.0, self.server._mapRate(-1)) - self.assertEqual(0.25, self.server._mapRate(101)) - - def _make_say_all_server(self): - server = piperfactory.SpeechServer.__new__(piperfactory.SpeechServer) - server._lock = threading.Lock() - server._stopEvent = threading.Event() - server._speakGeneration = 1 - server._currentFuture = None - server._executor = mock.Mock() - server._audioPlayer = None - return server - - def _make_say_all_context(self, utterance): - return speechserver.SayAllContext( - mock.Mock(), - utterance, - 0, - len(utterance), - ) - - def test_stop_invalidates_pending_say_all_worker(self): - server = self._make_say_all_server() - iterator = iter([[self._make_say_all_context("first"), None]]) - callback = mock.Mock() - - server.stop() - result = server._sayAllWorker(iterator, callback, 1) - - self.assertFalse(result) - callback.assert_not_called() - server._executor.submit.assert_not_called() - - def test_stale_say_all_completion_does_not_advance(self): - server = self._make_say_all_server() - first = self._make_say_all_context("first") - second = self._make_say_all_context("second") - iterator = iter([[first, None], [second, None]]) - callback = mock.Mock() - - server._sayAllWorker(iterator, callback, 1) - onComplete = server._executor.submit.call_args.args[3] - server.stop() - result = onComplete() - - self.assertFalse(result) - self.assertEqual(1, server._executor.submit.call_count) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_plugin_preferences_regressions.py b/tests/test_plugin_preferences_regressions.py deleted file mode 100644 index 3b67415..0000000 --- a/tests/test_plugin_preferences_regressions.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 - -"""Regression tests for the plugin controls in Preferences.""" - -import unittest -from unittest import mock - -from cthulhu import cthulhu # Import first to satisfy the application's initialization order. -from cthulhu import cthulhu_gui_prefs - - -class PluginPreferencesRegressionTests(unittest.TestCase): - """Keep plugin state changes independent from their presentation widgets.""" - - @staticmethod - def _create_gui(): - gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__( - cthulhu_gui_prefs.CthulhuSetupGUI - ) - gui.prefsDict = { - "activePlugins": ["HiddenPlugin", "SourceOne"], - "pluginSources": ["https://example.com/plugins.git"], - } - gui._available_plugins = {"HiddenPlugin", "SourceOne", "SourceTwo", "Required"} - gui._plugin_entries = { - "SourceOne": {"active": True, "can_toggle": True}, - "SourceTwo": {"active": False, "can_toggle": True}, - "Required": {"active": True, "can_toggle": False}, - } - gui._plugin_canonical_map = { - "SourceOne": "SharedPlugin", - "SourceTwo": "SharedPlugin", - "Required": "Required", - } - gui._plugin_group_map = { - "SharedPlugin": ["SourceOne", "SourceTwo"], - "Required": ["Required"], - } - gui._update_selected_plugin_controls = mock.Mock() - gui._update_plugin_tabs = mock.Mock() - return gui - - def test_active_plugins_include_hidden_and_selected_plugins(self): - gui = self._create_gui() - - self.assertEqual( - gui._get_active_plugins_from_ui(), - ["HiddenPlugin", "SourceOne", "Required"], - ) - - def test_enabling_plugin_disables_other_copy_with_same_name(self): - gui = self._create_gui() - - gui._set_plugin_active("SourceTwo", True) - - self.assertFalse(gui._plugin_entries["SourceOne"]["active"]) - self.assertTrue(gui._plugin_entries["SourceTwo"]["active"]) - gui._update_selected_plugin_controls.assert_called_once_with() - gui._update_plugin_tabs.assert_called_once_with() - - def test_required_plugin_cannot_be_disabled(self): - gui = self._create_gui() - - gui._set_plugin_active("Required", False) - - self.assertTrue(gui._plugin_entries["Required"]["active"]) - gui._update_plugin_tabs.assert_not_called() - - def test_apply_does_not_modify_plugin_sources(self): - gui = self._create_gui() - gui._populate_plugin_list = mock.Mock() - - gui._apply_plugin_changes() - - self.assertEqual( - gui.prefsDict["pluginSources"], - ["https://example.com/plugins.git"], - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_plugin_system_manager_regressions.py b/tests/test_plugin_system_manager_regressions.py deleted file mode 100644 index b415670..0000000 --- a/tests/test_plugin_system_manager_regressions.py +++ /dev/null @@ -1,201 +0,0 @@ -import sys -import tempfile -import textwrap -import types -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -import cthulhu as cthulhuPackage - -missingModule = object() -previousInputEventManagerModule = sys.modules.get( - "cthulhu.input_event_manager", - missingModule, -) -previousInputEventManagerAttribute = getattr( - cthulhuPackage, - "input_event_manager", - missingModule, -) -previousPluginSystemManagerModule = sys.modules.get( - "cthulhu.plugin_system_manager", - missingModule, -) -previousPluginSystemManagerAttribute = getattr( - cthulhuPackage, - "plugin_system_manager", - missingModule, -) -inputEventManagerStub = types.ModuleType("cthulhu.input_event_manager") -inputEventManagerStub.get_manager = mock.Mock(return_value=mock.Mock()) -sys.modules["cthulhu.input_event_manager"] = inputEventManagerStub -cthulhuPackage.input_event_manager = inputEventManagerStub - -try: - from cthulhu import plugin_system_manager - from cthulhu.plugin_system_manager import PluginInfo, PluginSystemManager -finally: - if previousInputEventManagerModule is missingModule: - sys.modules.pop("cthulhu.input_event_manager", None) - else: - sys.modules["cthulhu.input_event_manager"] = previousInputEventManagerModule - - if previousInputEventManagerAttribute is missingModule: - delattr(cthulhuPackage, "input_event_manager") - else: - cthulhuPackage.input_event_manager = previousInputEventManagerAttribute - - if previousPluginSystemManagerModule is missingModule: - sys.modules.pop("cthulhu.plugin_system_manager", None) - else: - sys.modules["cthulhu.plugin_system_manager"] = previousPluginSystemManagerModule - - if previousPluginSystemManagerAttribute is missingModule: - delattr(cthulhuPackage, "plugin_system_manager") - else: - cthulhuPackage.plugin_system_manager = previousPluginSystemManagerAttribute - - -PLUGIN_TEMPLATE = """ -from cthulhu.plugin import Plugin, cthulhu_hookimpl - - -class {class_name}(Plugin): - def __init__(self): - super().__init__() - self.activation_count = 0 - self.deactivation_count = 0 - - @cthulhu_hookimpl - def activate(self, plugin=None): - self.activation_count += 1 - - @cthulhu_hookimpl - def deactivate(self, plugin=None): - self.deactivation_count += 1 -""" - -PLUGIN_TEMPLATE_PLAIN_SIGNATURE = """ -from cthulhu.plugin import Plugin, cthulhu_hookimpl - - -class {class_name}(Plugin): - def __init__(self): - super().__init__() - self.activation_count = 0 - self.deactivation_count = 0 - - @cthulhu_hookimpl - def activate(self): - self.activation_count += 1 - - @cthulhu_hookimpl - def deactivate(self): - self.deactivation_count += 1 -""" - - -class PluginSystemManagerRegressionTests(unittest.TestCase): - def _create_plugin_info( - self, - root_dir: str, - module_name: str, - template: str = PLUGIN_TEMPLATE, - ) -> PluginInfo: - plugin_dir = Path(root_dir) / module_name - plugin_dir.mkdir() - (plugin_dir / "plugin.py").write_text( - textwrap.dedent(template.format(class_name=module_name)), - encoding="utf-8", - ) - return PluginInfo( - module_name, - module_name, - str(plugin_dir), - canonical_name=module_name, - source_id="test", - origin="test", - ) - - def _create_manager(self) -> PluginSystemManager: - app = mock.Mock() - app.getSignalManager.return_value = mock.Mock() - return PluginSystemManager(app) - - @mock.patch("cthulhu.plugin_system_manager.dbus_service.get_remote_controller") - def test_loading_second_plugin_does_not_reactivate_first_plugin(self, remote_controller): - remote_controller.return_value = mock.Mock() - - with tempfile.TemporaryDirectory() as temp_dir: - manager = self._create_manager() - first_plugin = self._create_plugin_info(temp_dir, "FirstPlugin") - second_plugin = self._create_plugin_info(temp_dir, "SecondPlugin") - - self.assertTrue(manager.loadPlugin(first_plugin)) - self.assertEqual(first_plugin.instance.activation_count, 1) - - self.assertTrue(manager.loadPlugin(second_plugin)) - - self.assertEqual(first_plugin.instance.activation_count, 1) - self.assertEqual(second_plugin.instance.activation_count, 1) - - @mock.patch("cthulhu.plugin_system_manager.dbus_service.get_remote_controller") - def test_unloading_plugin_does_not_deactivate_other_loaded_plugins(self, remote_controller): - remote_controller.return_value = mock.Mock() - - with tempfile.TemporaryDirectory() as temp_dir: - manager = self._create_manager() - first_plugin = self._create_plugin_info(temp_dir, "FirstPlugin") - second_plugin = self._create_plugin_info(temp_dir, "SecondPlugin") - - self.assertTrue(manager.loadPlugin(first_plugin)) - self.assertTrue(manager.loadPlugin(second_plugin)) - - second_instance = second_plugin.instance - - self.assertTrue(manager.unloadPlugin(second_plugin)) - - self.assertEqual(first_plugin.instance.deactivation_count, 0) - self.assertEqual(second_instance.deactivation_count, 1) - - @mock.patch("cthulhu.plugin_system_manager.dbus_service.get_remote_controller") - def test_loading_plugin_with_plain_activate_signature_succeeds(self, remote_controller): - remote_controller.return_value = mock.Mock() - - with tempfile.TemporaryDirectory() as temp_dir: - manager = self._create_manager() - plugin_info = self._create_plugin_info( - temp_dir, - "PlainSignaturePlugin", - template=PLUGIN_TEMPLATE_PLAIN_SIGNATURE, - ) - - self.assertTrue(manager.loadPlugin(plugin_info)) - instance = plugin_info.instance - self.assertEqual(instance.activation_count, 1) - - self.assertTrue(manager.unloadPlugin(plugin_info)) - self.assertEqual(instance.deactivation_count, 1) - self.assertEqual(plugin_info.instance, None) - - @mock.patch("cthulhu.plugin_system_manager.dbus_service.get_remote_controller") - def test_obsolete_plugin_manager_active_entry_is_dropped(self, remote_controller): - remote_controller.return_value = mock.Mock() - - with tempfile.TemporaryDirectory() as temp_dir: - manager = self._create_manager() - plugin_info = self._create_plugin_info(temp_dir, "OCR") - manager._plugins["OCR"] = plugin_info - manager._plugin_name_index["OCR"] = ["OCR"] - - with mock.patch.object(manager, "syncAllPluginsActive"): - manager.setActivePlugins(["PluginManager", "OCR"]) - - self.assertEqual(manager.getActivePlugins(), ["OCR"]) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_preferences_responses.py b/tests/test_preferences_responses.py new file mode 100644 index 0000000..6f609a5 --- /dev/null +++ b/tests/test_preferences_responses.py @@ -0,0 +1,59 @@ +"""Pipe-level regressions for the native preferences harness response reader.""" +import os +import select +import unittest +from unittest.mock import patch + +from native_preferences import ResponseReader + + +class ResponseReaderTests(unittest.TestCase): + def setUp(self): + readFd, writeFd = os.pipe() + self.stream = os.fdopen(readFd, encoding="utf-8") + self.writer = os.fdopen(writeFd, "wb", buffering=0) + self.addCleanup(self.stream.close) + self.addCleanup(self.writer.close) + self.reader = ResponseReader(self.stream) + + def test_batched_preview_and_save(self): + self.writer.write(b'{"Preview": true}\n{"Save": true}\n') + self.assertEqual(self.reader.request(), {"Preview": True}) + self.assertFalse(select.select([self.stream], [], [], 0)[0]) + self.assertEqual(self.reader.request(timeout=0), {"Save": True}) + + def test_missing_response_times_out(self): + with self.assertRaises(TimeoutError): + self.reader.request(timeout=0.01) + + def test_partial_response_times_out_and_can_resume(self): + self.writer.write(b'{"Name": "\xc3') + with self.assertRaises(TimeoutError): + self.reader.request(timeout=0.01) + self.writer.write(b'\xa9"}\n') + self.assertEqual(self.reader.request(), {"Name": "\u00e9"}) + + def test_partial_reads_share_one_deadline(self): + self.writer.write(b'{"Save":') + with patch("native_preferences.time.monotonic", side_effect=[10, 10, 16]): + with self.assertRaises(TimeoutError): + self.reader.request(timeout=5) + + def test_eof_is_reported_after_complete_responses(self): + self.writer.write(b'{"Save": true}\n{"Close":') + self.writer.close() + self.assertEqual(self.reader.request(), {"Save": True}) + with self.assertRaises(EOFError): + self.reader.request() + + def test_remaining_output_includes_read_ahead_and_pipe_bytes(self): + self.writer.write(b'{"Preview": true}\n{"Name": "\xc3') + self.assertEqual(self.reader.request(), {"Preview": True}) + self.writer.write(b'\xa9"}\n') + self.writer.close() + self.assertEqual(self.reader.read_remaining(), '{"Name": "\u00e9"}\n') + self.assertEqual(self.reader.read_remaining(), "") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_presentation_interrupt_sound_regressions.py b/tests/test_presentation_interrupt_sound_regressions.py deleted file mode 100644 index e02d141..0000000 --- a/tests/test_presentation_interrupt_sound_regressions.py +++ /dev/null @@ -1,46 +0,0 @@ -import sys -import unittest -import importlib -import tempfile -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -sys.modules.pop("cthulhu.speech", None) -speech = importlib.import_module("cthulhu.speech") - - -class PresentationInterruptSoundRegressionTests(unittest.TestCase): - def test_speech_stop_also_stops_sound_playback(self): - speechServer = mock.Mock() - echoServer = mock.Mock() - soundPlayer = mock.Mock() - - with ( - mock.patch.object(speech, "_speechserver", speechServer), - mock.patch.object(speech, "_echoSpeechserver", echoServer), - mock.patch.object(speech.sound, "getPlayer", return_value=soundPlayer), - ): - speech.stop() - - speechServer.stop.assert_called_once_with() - echoServer.stop.assert_called_once_with() - soundPlayer.stop.assert_called_once_with() - - def test_speech_icons_interrupt_previous_sound_when_speech_is_queued(self): - soundPlayer = mock.Mock() - - with tempfile.TemporaryDirectory() as temporaryDirectory: - soundPath = Path(temporaryDirectory) / "button.wav" - soundPath.write_bytes(b"RIFF") - icon = speech.Icon(temporaryDirectory, "button.wav") - - with mock.patch.object(speech.sound, "getPlayer", return_value=soundPlayer): - speech.speak([icon], interrupt=False) - - soundPlayer.play.assert_called_once_with(icon, interrupt=True) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_runtime_state_snapshot.py b/tests/test_runtime_state_snapshot.py deleted file mode 100644 index e388825..0000000 --- a/tests/test_runtime_state_snapshot.py +++ /dev/null @@ -1,174 +0,0 @@ -import queue -import sys -import types -import unittest -from pathlib import Path -from types import SimpleNamespace -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import cthulhu_state -from cthulhu import debug - -stubCthulhu = types.ModuleType("cthulhu.cthulhu") -stubCthulhu.cthulhuApp = mock.Mock() -sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu) - -from cthulhu import event_manager -from cthulhu.input_event_manager import InputEventManager -from cthulhu.plugin_system_manager import PluginSystemManager -from cthulhu.script_manager import ScriptManager - - -class RuntimeStateSnapshotTests(unittest.TestCase): - def test_formatter_sorts_keys_and_groups_sections(self) -> None: - result = debug.format_runtime_state_snapshot({ - "event_manager": {"z_count": 2, "a_count": 1}, - "speech": {"speech_server_present": False}, - }) - - self.assertEqual( - result, - "\n".join([ - "CTHULHU RUNTIME STATE SNAPSHOT", - "[event_manager]", - "a_count: 1", - "z_count: 2", - "[speech]", - "speech_server_present: False", - ]), - ) - - def test_event_manager_snapshot_reports_core_counters(self) -> None: - manager = event_manager.EventManager.__new__(event_manager.EventManager) - manager._active = True - manager._asyncMode = True - manager._eventQueue = queue.Queue() - manager._eventQueue.put(object()) - manager._prioritizedEvent = object() - manager._gidleId = 11 - manager._prioritizedIdleId = 12 - manager._eventsSuspended = True - manager._suspendableEvents = ["object:children-changed:add"] - manager._eventsTriggeringSuspension = [object(), object()] - manager._ignoredEvents = ["object:bounds-changed"] - manager._scriptListenerCounts = {"focus:": 1} - manager._parentsOfDefunctDescendants = [object()] - manager._cmdlineCache = {123: "app"} - manager._relevanceBurstHistory = {("a", "b", "c"): 1.0} - manager._churnSuppressed = True - manager._prioritizedContextToken = "token" - manager._keyHandlingActive = True - manager._inputEventManager = object() - - snapshot = manager.get_debug_snapshot() - - self.assertEqual(1, snapshot["event_queue_size"]) - self.assertTrue(snapshot["prioritized_event_present"]) - self.assertEqual(11, snapshot["idle_source_id"]) - self.assertEqual(2, snapshot["events_triggering_suspension"]) - self.assertEqual(1, snapshot["cmdline_cache_size"]) - self.assertTrue(snapshot["prioritized_context_token_present"]) - - def test_input_event_manager_snapshot_reports_grab_state(self) -> None: - manager = InputEventManager() - manager._device = object() - manager._pointer_moved_id = 42 - manager._mapped_keycodes = [1, 2] - manager._mapped_keysyms = [3] - manager._grabbed_bindings = {10: object(), 11: object()} - manager._paused = True - manager._scriptWithSuspendedGrabsForXterm = object() - manager._xtermFocusHandlerId = 17 - manager._xtermRecoverySourceId = 23 - manager._xtermRecoveryPollCount = 42 - manager._xtermHandoffHistory = [ - "ewmh:0x200000c->0x1400010", - "restore:success", - ] - manager._lastEwmhReadWindowId = 0x1400010 - manager._lastEwmhActiveWindowId = 0x1400010 - manager._lastEwmhXtermMatch = False - manager._last_input_event = object() - manager._last_non_modifier_key_event = None - - with mock.patch.object( - manager, - "_xterm_recovery_source_is_present", - return_value=True, - ): - snapshot = manager.get_debug_snapshot() - - self.assertTrue(snapshot["device_active"]) - self.assertTrue(snapshot["pointer_watcher_active"]) - self.assertEqual(2, snapshot["mapped_keycodes"]) - self.assertEqual(1, snapshot["mapped_keysyms"]) - self.assertEqual(2, snapshot["grabbed_bindings"]) - self.assertTrue(snapshot["suspended_xterm_script_present"]) - self.assertTrue(snapshot["xterm_focus_monitor_active"]) - self.assertTrue(snapshot["xterm_recovery_timer_active"]) - self.assertTrue(snapshot["xterm_recovery_source_present"]) - self.assertEqual(42, snapshot["xterm_recovery_poll_count"]) - self.assertEqual( - "ewmh:0x200000c->0x1400010 | restore:success", - snapshot["xterm_handoff_history"], - ) - self.assertEqual("0x1400010", snapshot["last_ewmh_read_window_id"]) - self.assertEqual("0x1400010", snapshot["last_ewmh_active_window_id"]) - self.assertFalse(snapshot["last_ewmh_xterm_match"]) - self.assertFalse(snapshot["last_non_modifier_key_event_present"]) - - def test_script_manager_snapshot_reports_cache_counts(self) -> None: - activeScript = SimpleNamespace(app=None) - oldActiveScript = cthulhu_state.activeScript - cthulhu_state.activeScript = activeScript - try: - manager = ScriptManager.__new__(ScriptManager) - manager._active = True - manager._defaultScript = object() - manager.appScripts = {"app": object()} - manager.toolkitScripts = {"app": {"toolkit": object()}} - manager.customScripts = {"app": {"role": object(), "other": object()}} - manager._sleepModeScripts = {"app": object()} - - snapshot = manager.get_debug_snapshot() - finally: - cthulhu_state.activeScript = oldActiveScript - - self.assertTrue(snapshot["active"]) - self.assertEqual("SimpleNamespace", snapshot["active_script"]) - self.assertTrue(snapshot["default_script_present"]) - self.assertEqual(1, snapshot["app_scripts"]) - self.assertEqual(1, snapshot["toolkit_scripts"]) - self.assertEqual(2, snapshot["custom_scripts"]) - self.assertEqual(1, snapshot["sleep_mode_scripts"]) - - def test_plugin_system_manager_snapshot_reports_plugin_counts(self) -> None: - manager = PluginSystemManager.__new__(PluginSystemManager) - manager._plugins = { - "Loaded": SimpleNamespace(loaded=True, builtin=False, hidden=False), - "Builtin": SimpleNamespace(loaded=True, builtin=True, hidden=False), - "Hidden": SimpleNamespace(loaded=False, builtin=False, hidden=True), - } - manager._active_plugins = ["Loaded", "Builtin"] - manager._plugin_keybindings = {"Loaded": [object(), object()]} - manager._global_bindings = [object()] - manager._last_active_script = object() - manager.plugin_manager = mock.Mock() - manager.plugin_manager.get_plugins.return_value = [object(), object()] - - snapshot = manager.get_debug_snapshot() - - self.assertEqual(3, snapshot["scanned_plugins"]) - self.assertEqual(2, snapshot["active_plugins"]) - self.assertEqual(2, snapshot["loaded_plugins"]) - self.assertEqual(1, snapshot["builtin_plugins"]) - self.assertEqual(1, snapshot["hidden_plugins"]) - self.assertEqual(2, snapshot["plugin_keybindings"]) - self.assertEqual(1, snapshot["global_keybindings"]) - self.assertEqual(2, snapshot["pluggy_registered_plugins"]) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_screen_lock_monitor.py b/tests/test_screen_lock_monitor.py deleted file mode 100644 index a320568..0000000 --- a/tests/test_screen_lock_monitor.py +++ /dev/null @@ -1,211 +0,0 @@ -import sys -import types -import unittest -from unittest import mock - -import cthulhu as cthulhu_package -from cthulhu import cthulhu_state - -stubCthulhu = types.ModuleType("cthulhu.cthulhu") -stubCthulhu.cthulhuApp = mock.Mock() -stubCthulhu.cthulhuApp.getPluginSystemManager.return_value = None -previousCthulhuModule = sys.modules.get("cthulhu.cthulhu") -sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu) - -from cthulhu import event_manager -from cthulhu import input_event_manager -from cthulhu.screen_lock_monitor import ScreenLockMonitor - -if previousCthulhuModule is None: - sys.modules.pop("cthulhu.cthulhu", None) - if getattr(cthulhu_package, "cthulhu", None) is stubCthulhu: - delattr(cthulhu_package, "cthulhu") -else: - sys.modules["cthulhu.cthulhu"] = previousCthulhuModule - - -class ScreenLockMonitorTests(unittest.TestCase): - def setUp(self): - self.app = mock.Mock() - self.monitor = ScreenLockMonitor(self.app) - - def test_name_appearance_enters_secure_lock_mode(self): - with mock.patch.object(self.monitor, "_is_trusted_owner", return_value=True): - self.monitor._on_name_appeared(mock.Mock(), self.monitor.BUS_NAME, ":1.42") - - self.app.eventManager.set_screen_lock_active.assert_called_once_with( - True, - schedule_focus_resync=True, - ) - self.assertTrue(self.monitor.is_active()) - - def test_untrusted_name_owner_does_not_enter_secure_lock_mode(self): - with mock.patch.object(self.monitor, "_is_trusted_owner", return_value=False): - self.monitor._on_name_appeared(mock.Mock(), self.monitor.BUS_NAME, ":1.42") - - self.app.eventManager.set_screen_lock_active.assert_not_called() - self.assertFalse(self.monitor.is_active()) - - def test_name_disappearance_leaves_secure_lock_mode(self): - with mock.patch.object(self.monitor, "_is_trusted_owner", return_value=True): - self.monitor._on_name_appeared(mock.Mock(), self.monitor.BUS_NAME, ":1.42") - self.monitor._on_name_vanished(mock.Mock(), self.monitor.BUS_NAME) - - self.assertEqual( - self.app.eventManager.set_screen_lock_active.call_args_list, - [ - mock.call(True, schedule_focus_resync=True), - mock.call(False, schedule_focus_resync=True), - ], - ) - self.assertFalse(self.monitor.is_active()) - - def test_start_watches_i38lock_bus_name(self): - connection = mock.Mock() - with ( - mock.patch("cthulhu.screen_lock_monitor.Gio.bus_get_sync", return_value=connection), - mock.patch( - "cthulhu.screen_lock_monitor.Gio.bus_watch_name_on_connection", - return_value=23, - ) as watch_name, - ): - self.monitor.start() - - watch_name.assert_called_once_with( - connection, - self.monitor.BUS_NAME, - mock.ANY, - self.monitor._on_name_appeared, - self.monitor._on_name_vanished, - ) - self.assertTrue(self.monitor.is_running()) - - def test_stop_releases_secure_lock_without_focus_resync(self): - with mock.patch.object(self.monitor, "_is_trusted_owner", return_value=True): - self.monitor._on_name_appeared(mock.Mock(), self.monitor.BUS_NAME, ":1.42") - - with mock.patch("cthulhu.screen_lock_monitor.Gio.bus_unwatch_name"): - self.monitor.stop() - - self.assertEqual( - self.app.eventManager.set_screen_lock_active.call_args_list, - [ - mock.call(True, schedule_focus_resync=True), - mock.call(False, schedule_focus_resync=False), - ], - ) - self.assertFalse(self.monitor.is_active()) - - def test_i38lock_process_owner_is_trusted(self): - connection = mock.Mock() - result = mock.Mock() - result.unpack.return_value = (1234,) - connection.call_sync.return_value = result - - with mock.patch("cthulhu.screen_lock_monitor.os.readlink", return_value="/usr/bin/i38lock"): - self.assertTrue(self.monitor._is_trusted_owner(connection, ":1.42")) - - def test_non_i38lock_process_owner_is_not_trusted(self): - connection = mock.Mock() - result = mock.Mock() - result.unpack.return_value = (1234,) - connection.call_sync.return_value = result - - with mock.patch("cthulhu.screen_lock_monitor.os.readlink", return_value="/usr/bin/python"): - self.assertFalse(self.monitor._is_trusted_owner(connection, ":1.42")) - - -class SecureScreenLockStateTests(unittest.TestCase): - def setUp(self): - self.original_screen_lock_active = cthulhu_state.screenLockActive - cthulhu_state.screenLockActive = False - - def tearDown(self): - cthulhu_state.screenLockActive = self.original_screen_lock_active - - def test_entering_secure_lock_clears_context_and_pauses_input(self): - app = mock.Mock() - active_script = mock.Mock() - app.scriptManager.get_active_script.return_value = active_script - manager = event_manager.EventManager(app, asyncMode=True) - keyboard_manager = mock.Mock() - focus_manager = mock.Mock() - - with ( - mock.patch.object(input_event_manager, "get_manager", return_value=keyboard_manager), - mock.patch("cthulhu.event_manager.focus_manager.get_manager", return_value=focus_manager), - mock.patch("cthulhu.event_manager.braille.clear") as clear_braille, - ): - manager.set_screen_lock_active(True) - - self.assertTrue(cthulhu_state.screenLockActive) - active_script.presentationInterrupt.assert_called_once_with() - app.scriptManager.set_active_script.assert_called_once_with( - None, - "I38Lock secure screen lock active", - ) - focus_manager.clear_state.assert_called_once_with( - "I38Lock secure screen lock active" - ) - keyboard_manager.set_secure_input_active.assert_called_once_with( - True, - "I38Lock secure screen lock active", - ) - clear_braille.assert_called_once_with() - - def test_object_events_are_dropped_without_inspecting_locked_content(self): - app = mock.Mock() - manager = event_manager.EventManager(app, asyncMode=True) - cthulhu_state.screenLockActive = True - event = mock.Mock() - - with ( - mock.patch.object(manager, "_addToQueue") as add_to_queue, - mock.patch("cthulhu.event_manager.AXObject.get_application") as get_application, - ): - manager._enqueue(event) - - add_to_queue.assert_not_called() - get_application.assert_not_called() - - def test_unlock_resumes_input_and_schedules_focus_resync(self): - app = mock.Mock() - manager = event_manager.EventManager(app, asyncMode=True) - keyboard_manager = mock.Mock() - focus_manager = mock.Mock() - cthulhu_state.screenLockActive = True - - with ( - mock.patch.object(input_event_manager, "get_manager", return_value=keyboard_manager), - mock.patch("cthulhu.event_manager.focus_manager.get_manager", return_value=focus_manager), - mock.patch("cthulhu.event_manager.GLib.idle_add") as idle_add, - ): - manager.set_screen_lock_active(False) - - self.assertFalse(cthulhu_state.screenLockActive) - keyboard_manager.set_secure_input_active.assert_called_once_with( - False, - "I38Lock secure screen lock released", - ) - idle_add.assert_called_once_with(manager._sync_focus_on_startup) - - def test_secure_input_blocks_key_echo_before_event_creation(self): - manager = input_event_manager.InputEventManager() - manager.set_secure_input_active(True, "test lock") - - with mock.patch("cthulhu.input_event_manager.input_event.KeyboardEvent") as event_class: - consumed = manager.process_keyboard_event( - mock.Mock(), - True, - 25, - 112, - 0, - "p", - ) - - self.assertFalse(consumed) - event_class.assert_not_called() - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_script_utilities_regressions.py b/tests/test_script_utilities_regressions.py deleted file mode 100644 index 6f62e19..0000000 --- a/tests/test_script_utilities_regressions.py +++ /dev/null @@ -1,28 +0,0 @@ -import sys -import unittest -from unittest import mock -from pathlib import Path - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import debug -from cthulhu.script_utilities import Utilities - - -class ScriptUtilitiesRegressionTests(unittest.TestCase): - @mock.patch("cthulhu.script_utilities.AXObject.get_application") - def test_can_be_active_window_skips_cmdline_lookup_without_info_logging(self, get_application): - utility = object.__new__(Utilities) - utility._getAppCommandLine = mock.Mock(side_effect=AssertionError("cmdline lookup should be skipped")) - utility._isActiveAndShowingAndNotIconified = mock.Mock(return_value=True) - - window = object() - app = object() - get_application.return_value = app - - with mock.patch.object(debug, "debugLevel", debug.LEVEL_SEVERE): - self.assertTrue(utility.canBeActiveWindow(window)) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_self_voice_plugin_regressions.py b/tests/test_self_voice_plugin_regressions.py deleted file mode 100644 index f04d733..0000000 --- a/tests/test_self_voice_plugin_regressions.py +++ /dev/null @@ -1,19 +0,0 @@ -import os -import unittest -from unittest import mock - -from cthulhu.plugins.self_voice import plugin - - -class SelfVoicePluginRegressionTests(unittest.TestCase): - def test_socket_file_is_scoped_to_user_runtime_directory(self) -> None: - with mock.patch.dict(os.environ, {"XDG_RUNTIME_DIR": "/run/user/1000"}, clear=True): - self.assertEqual(plugin._get_socket_file(), "/run/user/1000/cthulhu.sock") - - def test_socket_file_is_unavailable_without_user_runtime_directory(self) -> None: - with mock.patch.dict(os.environ, {}, clear=True): - self.assertIsNone(plugin._get_socket_file()) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_sound_helper_backend.py b/tests/test_sound_helper_backend.py deleted file mode 100644 index 0e614a0..0000000 --- a/tests/test_sound_helper_backend.py +++ /dev/null @@ -1,93 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import settings -from cthulhu import sound_helper - - -class _FakePlaybin: - def __init__(self): - self.properties = {} - - def set_property(self, name, value): - self.properties[name] = value - - -class SoundHelperBackendTests(unittest.TestCase): - def test_create_file_player_uses_playbin_default_sink_for_auto(self): - fakePlaybin = _FakePlaybin() - fakePanorama = object() - - with ( - mock.patch.object( - sound_helper.Gst.ElementFactory, - "make", - side_effect=[fakePlaybin, fakePanorama], - ) as makeElement, - mock.patch.object( - sound_helper.sound_sink, - "create_audio_sink", - ) as createAudioSink, - ): - player, panorama, sinkName, error = sound_helper._create_file_player( - "worker-file", - settings.SOUND_SINK_AUTO, - ) - - self.assertIs(player, fakePlaybin) - self.assertIs(panorama, fakePanorama) - self.assertEqual(sinkName, "playbin-default") - self.assertIsNone(error) - createAudioSink.assert_not_called() - makeElement.assert_has_calls( - [ - mock.call("playbin", "worker-file"), - mock.call("audiopanorama", "worker-file-panorama"), - ] - ) - self.assertNotIn("audio-sink", fakePlaybin.properties) - self.assertIs(fakePlaybin.properties["audio-filter"], fakePanorama) - - def test_create_file_player_sets_explicit_sink_when_requested(self): - fakePlaybin = _FakePlaybin() - fakePanorama = object() - fakeSink = object() - - with ( - mock.patch.object( - sound_helper.Gst.ElementFactory, - "make", - side_effect=[fakePlaybin, fakePanorama], - ) as makeElement, - mock.patch.object( - sound_helper.sound_sink, - "create_audio_sink", - return_value=(fakeSink, "pulsesink", None), - ) as createAudioSink, - ): - player, panorama, sinkName, error = sound_helper._create_file_player( - "worker-file", - settings.SOUND_SINK_PULSE, - ) - - self.assertIs(player, fakePlaybin) - self.assertIs(panorama, fakePanorama) - self.assertEqual(sinkName, "pulsesink") - self.assertIsNone(error) - makeElement.assert_has_calls( - [ - mock.call("playbin", "worker-file"), - mock.call("audiopanorama", "worker-file-panorama"), - ] - ) - createAudioSink.assert_called_once() - self.assertIs(fakePlaybin.properties["audio-sink"], fakeSink) - self.assertIs(fakePlaybin.properties["audio-filter"], fakePanorama) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_sound_preferences_regressions.py b/tests/test_sound_preferences_regressions.py deleted file mode 100644 index dd420c8..0000000 --- a/tests/test_sound_preferences_regressions.py +++ /dev/null @@ -1,179 +0,0 @@ -import sys -import tempfile -import unittest -import xml.etree.ElementTree as ET -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import cthulhu -from cthulhu import settings -from cthulhu import cthulhu_gui_prefs -from cthulhu import settings_manager - - -class SoundSettingsPersistenceTests(unittest.TestCase): - def test_progress_bar_beep_interval_is_user_customizable(self): - self.assertIn("progressBarBeepInterval", settings.userCustomizableSettings) - - def test_activate_writes_progress_bar_beep_interval_default(self): - with tempfile.TemporaryDirectory() as tempDir: - manager = settings_manager.SettingsManager(mock.Mock()) - manager.activate(prefsDir=tempDir) - settingsText = Path(tempDir, "user-settings.toml").read_text(encoding="utf-8") - - self.assertIn("progressBarBeepInterval = 0", settingsText) - - -class SoundPreferencesBuilderTests(unittest.TestCase): - def test_ui_definition_exposes_sounds_tab_controls(self): - uiPath = Path(__file__).resolve().parents[1] / "src" / "cthulhu" / "cthulhu-setup.ui" - root = ET.fromstring(uiPath.read_text(encoding="utf-8")) - - objectIds = { - element.attrib["id"] - for element in root.iter() - if element.tag == "object" and "id" in element.attrib - } - - self.assertIn("soundsGrid", objectIds) - self.assertIn("soundsTabLabel", objectIds) - self.assertIn("enableSoundCheckButton", objectIds) - self.assertIn("soundVolumeScale", objectIds) - self.assertIn("spatializeObjectSoundsCheckButton", objectIds) - self.assertIn("progressBarBeepIntervalSpinButton", objectIds) - - def test_notebook_tab_positions_keep_sounds_page_and_label_aligned(self): - uiPath = Path(__file__).resolve().parents[1] / "src" / "cthulhu" / "cthulhu-setup.ui" - root = ET.fromstring(uiPath.read_text(encoding="utf-8")) - notebook = next( - element for element in root.iter() - if element.tag == "object" and element.attrib.get("id") == "notebook" - ) - - positions = {} - for child in notebook.findall("child"): - obj = child.find("object") - if obj is None or "id" not in obj.attrib: - continue - position = None - packing = child.find("packing") - if packing is not None: - for prop in packing.findall("property"): - if prop.attrib.get("name") == "position": - position = int(prop.text) - break - positions[obj.attrib["id"]] = position - - self.assertEqual(positions["generalGrid"], 0) - self.assertEqual(positions["generalTabLabel"], 0) - self.assertEqual(positions["soundsGrid"], 1) - self.assertEqual(positions["soundsTabLabel"], 1) - self.assertEqual(positions["voiceGrid"], 2) - self.assertEqual(positions["voiceLabel"], 2) - self.assertEqual(positions["textAttributesGrid"], 8) - self.assertEqual(positions["textAttributesTabLabel"], 8) - - -class SoundPreferencesControllerTests(unittest.TestCase): - def test_init_sound_state_loads_sound_volume_and_beep_interval(self): - gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(cthulhu_gui_prefs.CthulhuSetupGUI) - gui.prefsDict = { - "enableSound": False, - "soundSink": settings.SOUND_SINK_PULSE, - "soundTheme": "default", - "roleSoundPresentation": settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY, - "soundVolume": 0.65, - "progressBarBeepInterval": 0, - "beepProgressBarUpdates": True, - "playSoundForRole": True, - "playSoundForState": True, - "playSoundForPositionInSet": False, - "playSoundForValue": False, - "spatializeObjectSounds": True, - } - widgets = { - "soundSinkCombo": mock.Mock(), - "soundThemeCombo": mock.Mock(), - "roleSoundPresentationCombo": mock.Mock(), - "soundVolumeScale": mock.Mock(), - "progressBarBeepIntervalSpinButton": mock.Mock(), - "enableSoundCheckButton": mock.Mock(), - "playSoundForRoleCheckButton": mock.Mock(), - "playSoundForStateCheckButton": mock.Mock(), - "playSoundForPositionInSetCheckButton": mock.Mock(), - "playSoundForValueCheckButton": mock.Mock(), - "spatializeObjectSoundsCheckButton": mock.Mock(), - "beepProgressBarUpdatesCheckButton": mock.Mock(), - } - gui.get_widget = widgets.__getitem__ - - fakeThemeManager = mock.Mock() - fakeThemeManager.getAvailableThemes.return_value = ["default"] - fakeSettingsManager = mock.Mock() - fakeSettingsManager.getSetting.return_value = settings.SOUND_SINK_AUTO - fakeApp = mock.Mock(settingsManager=fakeSettingsManager) - - with ( - mock.patch.object(cthulhu_gui_prefs.cthulhu, "cthulhuApp", fakeApp), - mock.patch.object( - cthulhu_gui_prefs.sound_theme_manager, - "getManager", - return_value=fakeThemeManager, - ), - ): - gui._initSoundThemeState() - - widgets["enableSoundCheckButton"].set_active.assert_called_once_with(False) - widgets["soundVolumeScale"].set_value.assert_called_once_with(0.65) - widgets["playSoundForRoleCheckButton"].set_active.assert_called_once_with(True) - widgets["playSoundForStateCheckButton"].set_active.assert_called_once_with(True) - widgets["playSoundForPositionInSetCheckButton"].set_active.assert_called_once_with(False) - widgets["playSoundForValueCheckButton"].set_active.assert_called_once_with(False) - widgets["spatializeObjectSoundsCheckButton"].set_active.assert_called_once_with(True) - widgets["beepProgressBarUpdatesCheckButton"].set_active.assert_called_once_with(True) - widgets["progressBarBeepIntervalSpinButton"].set_value.assert_called_once_with(0) - - def test_sound_value_handlers_store_current_values(self): - gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(cthulhu_gui_prefs.CthulhuSetupGUI) - gui.prefsDict = {} - - volumeWidget = mock.Mock() - volumeWidget.get_value.return_value = 0.7 - beepWidget = mock.Mock() - beepWidget.get_value_as_int.return_value = 0 - - gui.soundVolumeValueChanged(volumeWidget) - gui.progressBarBeepIntervalValueChanged(beepWidget) - - self.assertEqual(gui.prefsDict["soundVolume"], 0.7) - self.assertEqual(gui.prefsDict["progressBarBeepInterval"], 0) - - def test_load_profile_reinitializes_sound_state(self): - gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(cthulhu_gui_prefs.CthulhuSetupGUI) - gui.saveBasicSettings = mock.Mock() - gui._initGUIState = mock.Mock() - gui._initSoundThemeState = mock.Mock() - gui._initSpeechState = mock.Mock() - gui._initEchoSpeechState = mock.Mock() - gui._populateKeyBindings = mock.Mock() - gui._CthulhuSetupGUI__initProfileCombo = mock.Mock() - gui.prefsDict = {} - - fakeSettingsManager = mock.Mock() - fakeSettingsManager.getGeneralSettings.return_value = {"soundVolume": 0.5} - fakeApp = mock.Mock(settingsManager=fakeSettingsManager) - - with ( - mock.patch.object(cthulhu_gui_prefs.cthulhu, "cthulhuApp", fakeApp), - mock.patch.object(cthulhu_gui_prefs.cthulhu, "loadUserSettings"), - mock.patch.object(cthulhu_gui_prefs.braille, "checkBrailleSetting"), - ): - gui.loadProfile(["Default", "default"]) - - gui._initSoundThemeState.assert_called_once_with() - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_sound_recovery.py b/tests/test_sound_recovery.py deleted file mode 100644 index 7506360..0000000 --- a/tests/test_sound_recovery.py +++ /dev/null @@ -1,170 +0,0 @@ -import sys -import types -import unittest -import importlib -import os -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -soundGeneratorStub = types.ModuleType("cthulhu.sound_generator") - - -class _Icon: - def __init__(self, path="", name=""): - self.path = path - self.name = name - - def isValid(self): - return True - - -class _Tone: - def __init__(self, duration=0.1, frequency=440, volume=1.0, wave=0): - self.duration = duration - self.frequency = frequency - self.volume = volume - self.wave = wave - - -soundGeneratorStub.Icon = _Icon -soundGeneratorStub.Tone = _Tone -sys.modules.setdefault("cthulhu.sound_generator", soundGeneratorStub) - -from cthulhu import settings -from cthulhu import piper_audio_player -from cthulhu import sound -from cthulhu import sound_sink - - -class _FakeProcess: - def __init__(self, returnCode=None): - self.returnCode = returnCode - - def poll(self): - return self.returnCode - - -class SoundSinkTests(unittest.TestCase): - def test_auto_sink_prefers_autoaudiosink(self): - candidates = sound_sink._get_sink_element_candidates(settings.SOUND_SINK_AUTO) - self.assertGreaterEqual(len(candidates), 1) - self.assertEqual(candidates[0], "autoaudiosink") - - def test_gstreamer_init_check_bool_result_does_not_break_imports(self): - modules = [ - sound_sink, - sound, - piper_audio_player, - ] - - with mock.patch.object(sound_sink.Gst, "init_check", return_value=True): - reloadedModules = [] - for module in modules: - reloaded = importlib.reload(module) - reloadedModules.append(reloaded) - self.assertTrue(reloaded._gstreamerAvailable) - - for module in reloadedModules: - importlib.reload(module) - - def test_sound_helper_environment_defaults_to_orc_backup(self): - with mock.patch.dict(os.environ, {}, clear=True): - environment = sound._buildSoundHelperEnvironment() - - self.assertEqual("backup", environment["ORC_CODE"]) - - def test_sound_helper_environment_preserves_explicit_orc_code(self): - with mock.patch.dict(os.environ, {"ORC_CODE": "debug"}, clear=True): - environment = sound._buildSoundHelperEnvironment() - - self.assertEqual("debug", environment["ORC_CODE"]) - - -class PlayerRecoveryTests(unittest.TestCase): - def test_worker_diagnostic_marks_restart_required(self): - player = sound.Player() - - player._handleWorkerDiagnostic("RECOVERY REQUIRED: lost audio sink") - - self.assertTrue(player._workerRestartRequired) - self.assertEqual(player._workerRestartReason, "lost audio sink") - - def test_ensure_worker_restarts_when_recovery_is_required(self): - player = sound.Player() - player._workerProcess = _FakeProcess() - player._workerSink = settings.SOUND_SINK_AUTO - player._workerRestartRequired = True - player._workerRestartReason = "lost audio sink" - - stopReasons = [] - startedSinks = [] - - with ( - mock.patch.object( - sound_sink, - "get_configured_sound_sink", - return_value=settings.SOUND_SINK_AUTO, - ), - mock.patch.object( - player, - "_stopWorkerLocked", - side_effect=lambda reason: stopReasons.append(reason), - ), - mock.patch.object( - player, - "_startWorkerLocked", - side_effect=lambda configuredSink: startedSinks.append(configuredSink) or True, - ), - ): - self.assertTrue(player._ensureWorkerLocked()) - - self.assertEqual(stopReasons, ["lost audio sink"]) - self.assertEqual(startedSinks, [settings.SOUND_SINK_AUTO]) - - def test_stop_does_not_start_worker_when_worker_is_not_running(self): - player = sound.Player() - - with mock.patch.object(player, "_sendWorkerCommand") as sendCommand: - player.stop() - - sendCommand.assert_not_called() - - def test_stop_sends_command_to_running_worker(self): - player = sound.Player() - player._workerProcess = _FakeProcess() - - with mock.patch.object(player, "_sendWorkerCommand") as sendCommand: - player.stop() - - sendCommand.assert_called_once_with({"action": "stop"}, waitForResponse=False) - - def test_icon_pan_is_sent_to_worker(self): - player = sound.Player() - icon = sound.Icon("/tmp", "link.wav") - icon.pan = -0.5 - - with ( - mock.patch.object(icon, "isValid", return_value=True), - mock.patch.object(player, "_sendWorkerCommand", return_value=(True, None)) as sendCommand, - ): - player.play(icon) - - command = sendCommand.call_args.args[0] - self.assertEqual(command["pan"], -0.5) - - def test_tone_pan_is_sent_to_worker(self): - player = sound.Player() - tone = sound.Tone(0.1, 440) - tone.pan = 0.5 - - with mock.patch.object(player, "_sendWorkerCommand", return_value=(True, None)) as sendCommand: - player.play(tone) - - command = sendCommand.call_args.args[0] - self.assertEqual(command["pan"], 0.5) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_speech_default_policy_regressions.py b/tests/test_speech_default_policy_regressions.py deleted file mode 100644 index debb79b..0000000 --- a/tests/test_speech_default_policy_regressions.py +++ /dev/null @@ -1,91 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import settings -from cthulhu import speech -from cthulhu import cthulhu_state -from cthulhu.scripts import default - - -class SpeechDefaultPolicyRegressionTests(unittest.TestCase): - def _make_settings_manager(self): - values = { - "enableSpeech": True, - "onlySpeakDisplayedText": False, - "messagesAreDetailed": True, - "enableBraille": False, - "enableBrailleMonitor": False, - "enableFlashMessages": False, - "voices": {settings.SYSTEM_VOICE: "system"}, - "capitalizationStyle": settings.CAPITALIZATION_STYLE_NONE, - "verbalizePunctuationStyle": settings.PUNCTUATION_STYLE_NONE, - } - - manager = mock.Mock() - manager.getSetting.side_effect = values.get - return manager - - def _make_script(self): - testScript = default.Script.__new__(default.Script) - testScript.speechAndVerbosityManager = mock.Mock() - return testScript - - def test_speech_speak_queues_by_default(self): - server = mock.Mock() - - with ( - mock.patch.object(speech, "_speechserver", server), - mock.patch.object(speech, "_write_to_monitor"), - mock.patch.object(speech.speech_history, "add"), - mock.patch.object(cthulhu_state, "activeScript", None), - ): - speech.speak("status") - - server.speak.assert_called_once() - self.assertFalse(server.speak.call_args.args[2]) - - def test_speech_speak_explicit_interrupt_is_preserved(self): - server = mock.Mock() - - with ( - mock.patch.object(speech, "_speechserver", server), - mock.patch.object(speech, "_write_to_monitor"), - mock.patch.object(speech.speech_history, "add"), - mock.patch.object(cthulhu_state, "activeScript", None), - ): - speech.speak("status", interrupt=True) - - server.speak.assert_called_once() - self.assertTrue(server.speak.call_args.args[2]) - - def test_present_message_queues_by_default(self): - testScript = self._make_script() - manager = self._make_settings_manager() - - with ( - mock.patch.object(default.cthulhu.cthulhuApp, "settingsManager", manager), - mock.patch.object(default.speech, "speak") as speak, - ): - default.Script.presentMessage(testScript, "Status") - - speak.assert_called_once_with("Status", "system", False) - - def test_present_message_explicit_interrupt_is_preserved(self): - testScript = self._make_script() - manager = self._make_settings_manager() - - with ( - mock.patch.object(default.cthulhu.cthulhuApp, "settingsManager", manager), - mock.patch.object(default.speech, "speak") as speak, - ): - default.Script.presentMessage(testScript, "Status", interrupt=True) - - speak.assert_called_once_with("Status", "system", True) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_speechdispatcher_interrupt_regressions.py b/tests/test_speechdispatcher_interrupt_regressions.py deleted file mode 100644 index e280463..0000000 --- a/tests/test_speechdispatcher_interrupt_regressions.py +++ /dev/null @@ -1,154 +0,0 @@ -import sys -import time -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import speechdispatcherfactory -from cthulhu import speechserver -import speechd - - -class SpeechDispatcherInterruptRegressionTests(unittest.TestCase): - def _make_server(self): - server = speechdispatcherfactory.SpeechServer.__new__(speechdispatcherfactory.SpeechServer) - server._lastKeyEchoTime = None - server._cancel = mock.Mock() - server._apply_acss = mock.Mock() - server._send_command = mock.Mock() - server._speak = mock.Mock() - server._client = mock.Mock() - server._client.char = mock.Mock() - server._say_all_generation = 0 - server._cancelled_say_all_generation = None - server._CALLBACK_TYPE_MAP = { - speechd.CallbackType.BEGIN: speechserver.SayAllContext.PROGRESS, - speechd.CallbackType.CANCEL: speechserver.SayAllContext.INTERRUPTED, - speechd.CallbackType.END: speechserver.SayAllContext.COMPLETED, - speechd.CallbackType.INDEX_MARK: speechserver.SayAllContext.PROGRESS, - } - return server - - def _make_say_all_context(self, utterance): - return speechserver.SayAllContext( - mock.Mock(), - utterance, - 0, - len(utterance), - ) - - def test_interrupting_string_speech_cancels_active_output_first(self): - server = self._make_server() - - server.speak("long utterance", interrupt=True) - - server._cancel.assert_called_once_with() - server._speak.assert_called_once_with("long utterance", None) - - def test_string_speech_queues_by_default(self): - server = self._make_server() - - server.speak("next") - - server._cancel.assert_not_called() - server._speak.assert_called_once_with("next", None) - - def test_recent_key_echo_suppresses_backend_cancel(self): - server = self._make_server() - server._lastKeyEchoTime = time.time() - - server.speak("next", interrupt=True) - - server._cancel.assert_not_called() - server._speak.assert_called_once_with("next", None) - - def test_stop_invalidates_pending_say_all_continuation(self): - server = self._make_server() - first = self._make_say_all_context("first") - second = self._make_say_all_context("second") - callback = mock.Mock() - iterator = iter([[first, None], [second, None]]) - - server.sayAll(iterator, callback) - server._say_all(iterator, callback, 1) - speechd_callback = server._speak.call_args.kwargs["callback"] - - server.stop() - speechd_callback(speechd.CallbackType.END) - - self.assertEqual(1, server._speak.call_count) - callback.assert_not_called() - - def test_interrupting_speech_invalidates_pending_say_all_continuation(self): - server = self._make_server() - first = self._make_say_all_context("first") - second = self._make_say_all_context("second") - callback = mock.Mock() - iterator = iter([[first, None], [second, None]]) - - server.sayAll(iterator, callback) - server._say_all(iterator, callback, 1) - speechd_callback = server._speak.call_args.kwargs["callback"] - - server.speak("new speech", interrupt=True) - speechd_callback(speechd.CallbackType.END) - - self.assertEqual(2, server._speak.call_count) - self.assertEqual("new speech", server._speak.call_args.args[0]) - callback.assert_not_called() - - def test_send_command_logs_and_recovers_from_command_errors(self): - server = self._make_server() - server.reset = mock.Mock() - command = mock.Mock( - side_effect=[ - speechd.SSIPCommandError(500, "bad ssml", "bad ssml"), - "recovered", - ] - ) - - with mock.patch.object(speechdispatcherfactory.debug, "printMessage") as print_message: - result = speechdispatcherfactory.SpeechServer._send_command(server, command, "payload") - - self.assertEqual("recovered", result) - server.reset.assert_called_once_with() - self.assertEqual(2, command.call_count) - logged_messages = [call.args[1] for call in print_message.call_args_list] - self.assertTrue(any("SSIPCommandError" in message for message in logged_messages)) - - def test_debug_sd_values_logs_when_backend_state_queries_return_none(self): - server = self._make_server() - server._current_voice_properties = {} - server._id = "default" - server.reset = mock.Mock() - server._send_command = speechdispatcherfactory.SpeechServer._send_command.__get__( - server, speechdispatcherfactory.SpeechServer - ) - - fake_app = mock.Mock() - fake_app.settingsManager.getSetting.return_value = speechdispatcherfactory.settings.PUNCTUATION_STYLE_MOST - fake_script = mock.Mock() - fake_script.utilities.adjustForDigits.side_effect = lambda text: text - fake_state = mock.Mock(activeScript=fake_script) - - server._client.get_rate.return_value = None - server._client.get_pitch.return_value = None - server._client.get_volume.return_value = None - server._client.get_language.return_value = None - - with mock.patch.object(speechdispatcherfactory, "cthulhu") as fake_cthulhu, \ - mock.patch.object(speechdispatcherfactory, "cthulhu_state", fake_state), \ - mock.patch.object(speechdispatcherfactory.debug, "debugLevel", speechdispatcherfactory.debug.LEVEL_INFO), \ - mock.patch.object(speechdispatcherfactory.debug, "printMessage") as print_message: - fake_cthulhu.cthulhuApp = fake_app - speechdispatcherfactory.SpeechServer._debug_sd_values(server, "prefix") - - logged_messages = [str(call.args[1]) for call in print_message.call_args_list] - self.assertTrue(any("returned None" in message for message in logged_messages)) - self.assertEqual(4, server.reset.call_count) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_speechdispatcher_voice_selection_regressions.py b/tests/test_speechdispatcher_voice_selection_regressions.py deleted file mode 100644 index 8832713..0000000 --- a/tests/test_speechdispatcher_voice_selection_regressions.py +++ /dev/null @@ -1,212 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import guilabels -from cthulhu import settings -from cthulhu import settings_manager -from cthulhu import speech_and_verbosity_manager -from cthulhu import speechdispatcherfactory -from cthulhu import speechserver - - -class SpeechDispatcherVoiceSelectionRegressionTests(unittest.TestCase): - def test_session_speech_settings_override_profile_reload(self): - manager = settings_manager.SettingsManager.__new__( - settings_manager.SettingsManager - ) - manager._session_settings = { - "speechServerInfo": ["doubletalk", "doubletalk"], - "voices": { - settings.DEFAULT_VOICE: { - "family": { - speechserver.VoiceFamily.NAME: "Perfect Paul", - speechserver.VoiceFamily.LANG: "en", - speechserver.VoiceFamily.DIALECT: "US", - speechserver.VoiceFamily.VARIANT: "none", - } - } - }, - } - manager.customizedSettings = {} - manager._getCustomizedSettings = mock.Mock(return_value={}) - manager._logRoleSoundPresentationChange = mock.Mock() - saved_settings = { - "speechServerInfo": ["rhvoice", "rhvoice"], - "voices": { - settings.DEFAULT_VOICE: { - "family": { - speechserver.VoiceFamily.NAME: "Previous Voice", - } - } - }, - } - - with mock.patch.object( - settings, - "speechServerInfo", - saved_settings["speechServerInfo"], - ), mock.patch.object(settings, "voices", saved_settings["voices"]): - manager._setSettingsRuntime(saved_settings) - - self.assertEqual( - ["doubletalk", "doubletalk"], - settings.speechServerInfo, - ) - self.assertEqual( - "Perfect Paul", - settings.voices[settings.DEFAULT_VOICE]["family"][ - speechserver.VoiceFamily.NAME - ], - ) - - def test_quick_module_switch_preserves_module_and_voice_for_session(self): - current_module = {"name": "rhvoice"} - perfect_paul = speechserver.VoiceFamily( - { - speechserver.VoiceFamily.NAME: "Perfect Paul", - speechserver.VoiceFamily.LANG: "en", - speechserver.VoiceFamily.DIALECT: "US", - speechserver.VoiceFamily.VARIANT: "none", - } - ) - server = mock.Mock() - server.list_output_modules.return_value = ["rhvoice", "doubletalk"] - server.getOutputModule.side_effect = lambda: current_module["name"] - server.setOutputModule.side_effect = ( - lambda module: current_module.update(name=module) - ) - server.getVoiceFamilies.return_value = [perfect_paul] - - session_settings = mock.Mock() - app = mock.Mock() - app.getSettingsManager.return_value = session_settings - manager = speech_and_verbosity_manager.SpeechAndVerbosityManager.__new__( - speech_and_verbosity_manager.SpeechAndVerbosityManager - ) - manager.app = app - manager._get_server = mock.Mock(return_value=server) - manager._present_message = mock.Mock() - - runtime_voices = { - settings.DEFAULT_VOICE: { - "family": { - speechserver.VoiceFamily.NAME: "Previous Voice", - } - } - } - with mock.patch.object(settings, "voices", runtime_voices), \ - mock.patch.object( - settings, - "speechServerInfo", - ["rhvoice", "rhvoice"], - ): - manager._adjust_module(script=None, decrease=False) - - session_values = { - call.args[0]: call.args[1] - for call in session_settings.set_session_setting.call_args_list - } - self.assertEqual( - ["doubletalk", "doubletalk"], - session_values["speechServerInfo"], - ) - self.assertEqual( - "Perfect Paul", - session_values["voices"][settings.DEFAULT_VOICE]["family"][ - speechserver.VoiceFamily.NAME - ], - ) - - def test_output_module_updates_the_synthetic_default_voice_name(self): - server = speechdispatcherfactory.SpeechServer.__new__( - speechdispatcherfactory.SpeechServer - ) - server._client = mock.Mock() - server._default_voice_name = guilabels.SPEECH_DEFAULT_VOICE % "default" - server._current_voice_properties = { - speechdispatcherfactory.ACSS.FAMILY: {"name": "Previous Voice"} - } - - server.setOutputModule("doubletalk") - - server._client.set_output_module.assert_called_once_with("doubletalk") - self.assertEqual( - guilabels.SPEECH_DEFAULT_VOICE % "doubletalk", - server._default_voice_name, - ) - self.assertNotIn( - speechdispatcherfactory.ACSS.FAMILY, - server._current_voice_properties, - ) - - def test_quick_voice_list_prefers_real_doubletalk_voices(self): - default_name = guilabels.SPEECH_DEFAULT_VOICE % "doubletalk" - voice_names = [ - "Perfect Paul", - "Vader", - "Big Bob", - "Precise Pete", - "Ricochet", - "Biff", - "Skip", - "Robo Robert", - ] - voices = [ - speechserver.VoiceFamily( - { - speechserver.VoiceFamily.NAME: default_name, - speechserver.VoiceFamily.LANG: "en", - speechserver.VoiceFamily.DIALECT: "US", - speechserver.VoiceFamily.VARIANT: None, - } - ), - ] - voices.extend( - speechserver.VoiceFamily( - { - speechserver.VoiceFamily.NAME: voice_name, - speechserver.VoiceFamily.LANG: "en", - speechserver.VoiceFamily.DIALECT: "US", - speechserver.VoiceFamily.VARIANT: "none", - } - ) - for voice_name in voice_names - ) - server = mock.Mock() - server.getOutputModule.return_value = "doubletalk" - server.getVoiceFamilies.return_value = voices - manager = speech_and_verbosity_manager.SpeechAndVerbosityManager.__new__( - speech_and_verbosity_manager.SpeechAndVerbosityManager - ) - - available = manager._get_available_voices(server) - - self.assertEqual( - voice_names, - [voice[speechserver.VoiceFamily.NAME] for voice in available], - ) - - def test_quick_voice_list_keeps_default_when_no_real_voice_exists(self): - default_name = guilabels.SPEECH_DEFAULT_VOICE % "generic" - default_voice = speechserver.VoiceFamily( - { - speechserver.VoiceFamily.NAME: default_name, - speechserver.VoiceFamily.LANG: "en", - } - ) - server = mock.Mock() - server.getOutputModule.return_value = "generic" - server.getVoiceFamilies.return_value = [default_voice] - manager = speech_and_verbosity_manager.SpeechAndVerbosityManager.__new__( - speech_and_verbosity_manager.SpeechAndVerbosityManager - ) - - self.assertEqual([default_voice], manager._get_available_voices(server)) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_steam_notification_regressions.py b/tests/test_steam_notification_regressions.py deleted file mode 100644 index 8efc244..0000000 --- a/tests/test_steam_notification_regressions.py +++ /dev/null @@ -1,223 +0,0 @@ -import re -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") -gi.require_version("Atspi", "2.0") - -from gi.repository import Atspi - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -soundGeneratorModule = sys.modules.get("cthulhu.sound_generator") -if soundGeneratorModule is not None and not hasattr(soundGeneratorModule, "SoundGenerator"): - class _StubSoundGenerator: - pass - - soundGeneratorModule.SoundGenerator = _StubSoundGenerator - -from cthulhu.ax_object import AXObject -from cthulhu.ax_utilities import AXUtilities -from cthulhu import cthulhu_state -from cthulhu.scripts.apps.steamwebhelper import script as steam_script - - -class SteamInactiveNotificationContractTests(unittest.TestCase): - @staticmethod - def _prepare_event_script(testScript, presentIfInactive): - handler = mock.Mock() - testScript.presentIfInactive = presentIfInactive - testScript.listeners = {"object:state-changed:showing": handler} - testScript.generatorCache = {"stale": object()} - testScript.skipObjectEvent = mock.Mock(return_value=False) - return handler - - def test_steam_notification_is_processed_while_script_is_inactive(self): - app = object() - - def initialize_chromium(testScript, initializedApp): - testScript.app = initializedApp - testScript.presentIfInactive = False - - with mock.patch.object( - steam_script.Chromium.Script, - "__init__", - new=initialize_chromium, - ): - testScript = steam_script.Script(app) - - handler = self._prepare_event_script(testScript, testScript.presentIfInactive) - event = mock.Mock(type="object:state-changed:showing", source=object()) - - with ( - mock.patch.object(cthulhu_state, "activeScript", object()), - mock.patch.object(AXObject, "get_role", return_value=Atspi.Role.NOTIFICATION), - ): - testScript.processObjectEvent(event) - - self.assertTrue(testScript.presentIfInactive) - handler.assert_called_once_with(event) - - def test_generic_chromium_notification_is_deferred_while_script_is_inactive(self): - testScript = steam_script.Chromium.Script.__new__( - steam_script.Chromium.Script - ) - handler = self._prepare_event_script(testScript, presentIfInactive=False) - event = mock.Mock(type="object:state-changed:showing", source=object()) - - with ( - mock.patch.object(cthulhu_state, "activeScript", object()), - mock.patch.object(AXObject, "get_role", return_value=Atspi.Role.NOTIFICATION), - ): - testScript.processObjectEvent(event) - - handler.assert_not_called() - - -class SteamNotificationRootTests(unittest.TestCase): - def test_prefers_notification_ancestor_over_live_region_descendant(self): - testScript = steam_script.Script.__new__(steam_script.Script) - fragment = object() - notification = object() - - def get_attribute(obj, name): - if obj is fragment and name == "container-live": - return "assertive" - return None - - def find_ancestor(obj, predicate): - if obj is fragment and predicate(notification): - return notification - return None - - with ( - mock.patch.object(AXUtilities, "is_notification", side_effect=lambda obj: obj is notification), - mock.patch.object(AXUtilities, "is_alert", return_value=False), - mock.patch.object(AXObject, "get_attribute", side_effect=get_attribute), - mock.patch.object(AXObject, "find_ancestor", side_effect=find_ancestor), - ): - result = testScript._findSteamNotificationRoot(fragment) - - self.assertIs(result, notification) - - -class SteamNotificationRoutingContractTests(unittest.TestCase): - def test_steam_notification_override_handles_showing_before_chromium(self): - testScript = steam_script.Script.__new__(steam_script.Script) - notification = object() - event = mock.Mock(source=notification, detail1=1) - testScript._presentSteamNotification = mock.Mock() - - with ( - mock.patch.object( - testScript, - "_isSteamNotification", - return_value=True, - ), - mock.patch.object( - steam_script.Chromium.Script, - "onShowingChanged", - ) as chromiumHandler, - ): - testScript.onShowingChanged(event) - - testScript._presentSteamNotification.assert_called_once_with(notification) - chromiumHandler.assert_not_called() - - def test_nonsteam_showing_event_defers_to_chromium(self): - testScript = steam_script.Script.__new__(steam_script.Script) - event = mock.Mock(source=object(), detail1=1) - testScript._presentSteamNotification = mock.Mock() - - with ( - mock.patch.object( - testScript, - "_isSteamNotification", - return_value=False, - ), - mock.patch.object( - steam_script.Chromium.Script, - "onShowingChanged", - ) as chromiumHandler, - ): - testScript.onShowingChanged(event) - - testScript._presentSteamNotification.assert_not_called() - chromiumHandler.assert_called_once_with(event) - - -class SteamNotificationQueueTests(unittest.TestCase): - @staticmethod - def _make_script(): - testScript = steam_script.Script.__new__(steam_script.Script) - testScript._lastSteamNotification = ("", 0.0) - testScript._steamPendingNotification = None - testScript._steamRelativeTimePattern = re.compile( - r"^(?:just now|now|\d+\s+(?:second|minute|hour|day|week|month|year)s?\s+ago)$", - re.IGNORECASE, - ) - testScript._resetSteamPendingTimer = mock.Mock() - testScript._presentSteamNotificationTextNow = mock.Mock() - return testScript - - def test_merges_non_overlapping_fragments_for_same_notification(self): - testScript = self._make_script() - notification = object() - - testScript._queueSteamNotification("username", notification) - testScript._queueSteamNotification("Playing: Borderlands 2", notification) - - testScript._presentSteamNotificationTextNow.assert_not_called() - self.assertEqual( - testScript._steamPendingNotification["text"], - "username Playing: Borderlands 2", - ) - - testScript._flushSteamPendingNotification(fromTimer=True) - - testScript._presentSteamNotificationTextNow.assert_called_once_with( - "username Playing: Borderlands 2", - notification, - ) - - def test_merges_relative_timestamp_without_repeated_presentation(self): - testScript = self._make_script() - notification = object() - - testScript._queueSteamNotification("Username is now online", notification) - testScript._queueSteamNotification("2 minutes ago", notification) - - testScript._presentSteamNotificationTextNow.assert_not_called() - self.assertEqual( - testScript._steamPendingNotification["text"], - "Username is now online. 2 minutes ago", - ) - - testScript._flushSteamPendingNotification(fromTimer=True) - - testScript._presentSteamNotificationTextNow.assert_called_once_with( - "Username is now online. 2 minutes ago", - notification, - ) - - def test_duplicate_complete_notification_is_presented_once(self): - testScript = self._make_script() - notification = object() - - testScript._queueSteamNotification("Username is now online", notification) - testScript._queueSteamNotification("Username is now online", notification) - testScript._flushSteamPendingNotification(fromTimer=True) - - testScript._presentSteamNotificationTextNow.assert_called_once_with( - "Username is now online", - notification, - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_steam_selection_regressions.py b/tests/test_steam_selection_regressions.py deleted file mode 100644 index 5414757..0000000 --- a/tests/test_steam_selection_regressions.py +++ /dev/null @@ -1,1105 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -soundGeneratorModule = sys.modules.get("cthulhu.sound_generator") -if soundGeneratorModule is not None and not hasattr(soundGeneratorModule, "SoundGenerator"): - class _StubSoundGenerator: - pass - - soundGeneratorModule.SoundGenerator = _StubSoundGenerator - -from cthulhu.scripts.apps.steamwebhelper import script as steam_script -from cthulhu.scripts.apps.steamwebhelper import script_utilities as steam_script_utilities - - -class SteamSelectionChangedTests(unittest.TestCase): - def test_selection_changed_tolerates_scalar_any_data(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - event = mock.Mock(source=source, any_data=0) - chromiumCalls = [] - - def displayedText(obj): - if obj is source: - return "" - raise TypeError("argument self: Expected Atspi.Accessible, but got int") - - def get_name(obj): - if obj is source: - return "Notifications" - raise TypeError("argument self: Expected Atspi.Accessible, but got int") - - testScript.utilities = mock.Mock() - testScript.utilities.displayedText.side_effect = displayedText - - def chromiumOnSelectionChanged(self, selectionEvent): - chromiumCalls.append((self, selectionEvent)) - return True - - with ( - mock.patch.object(steam_script.AXObject, "get_name", side_effect=get_name), - mock.patch.object(steam_script.AXObject, "get_description", return_value=""), - mock.patch.object(steam_script.AXObject, "get_role_name", return_value="page tab list"), - mock.patch.object(steam_script.AXObject, "get_path", return_value=[1, 2, 3]), - mock.patch.object( - steam_script.Chromium.Script, - "onSelectionChanged", - new=chromiumOnSelectionChanged, - ), - ): - self.assertTrue(testScript.onSelectionChanged(event)) - - self.assertEqual(chromiumCalls, [(testScript, event)]) - - -class SteamOverlaySelectionPresentationTests(unittest.TestCase): - def test_selected_changed_presents_quick_access_item_over_steam_game(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - lastEvent = mock.Mock(event_string="Down", modifiers=0) - event = mock.Mock( - type="object:state-changed:selected", - source=source, - detail1=1, - any_data=None, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.displayedText.return_value = "" - testScript.presentMessage = mock.Mock() - testScript._lastSteamOverlaySelection = ("", 0.0) - - chromiumCalls = [] - - def chromiumOnSelectedChanged(self, selectedEvent): - chromiumCalls.append((self, selectedEvent)) - return False - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=True), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object(steam_script.AXObject, "get_name", return_value="Quick Settings"), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_list_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_menu_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object( - steam_script.Chromium.Script, - "onSelectedChanged", - new=chromiumOnSelectedChanged, - ), - ): - self.assertTrue(testScript.onSelectedChanged(event)) - - testScript.presentMessage.assert_called_once_with( - "Quick Settings", - force=True, - interrupt=True, - ) - self.assertEqual(chromiumCalls, []) - - def test_selected_changed_presents_inferred_quick_access_friends_tab_label(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - lastEvent = mock.Mock(event_string="Down", modifiers=0) - event = mock.Mock( - type="object:state-changed:selected", - source=source, - detail1=1, - any_data=None, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.displayedText.return_value = "" - testScript.presentMessage = mock.Mock() - testScript._lastSteamOverlaySelection = ("", 0.0) - - chromiumCalls = [] - - def chromiumOnSelectedChanged(self, selectedEvent): - chromiumCalls.append((self, selectedEvent)) - return False - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=True), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object(steam_script.AXObject, "get_name", return_value=""), - mock.patch.object( - steam_script.AXObject, - "get_attribute", - side_effect=lambda obj, name: "quickaccess_tab_3" if name == "id" else "", - ), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_list_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_menu_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object( - steam_script.Chromium.Script, - "onSelectedChanged", - new=chromiumOnSelectedChanged, - ), - ): - self.assertTrue(testScript.onSelectedChanged(event)) - - testScript.presentMessage.assert_called_once_with( - "Friends", - force=True, - interrupt=True, - ) - self.assertEqual(chromiumCalls, []) - self.assertEqual(testScript._steamActiveQuickAccessTab, "Friends") - - def test_selected_changed_defers_unknown_unnamed_quick_access_tab(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - lastEvent = mock.Mock(event_string="Down", modifiers=0) - event = mock.Mock( - type="object:state-changed:selected", - source=source, - detail1=1, - any_data=None, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.displayedText.return_value = "" - testScript.presentMessage = mock.Mock() - - chromiumCalls = [] - - def chromiumOnSelectedChanged(self, selectedEvent): - chromiumCalls.append((self, selectedEvent)) - return "handled" - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=True), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object(steam_script.AXObject, "get_name", return_value=""), - mock.patch.object( - steam_script.AXObject, - "get_attribute", - side_effect=lambda obj, name: "quickaccess_tab_unknown" if name == "id" else "", - ), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_list_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_menu_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object( - steam_script.Chromium.Script, - "onSelectedChanged", - new=chromiumOnSelectedChanged, - ), - ): - self.assertEqual(testScript.onSelectedChanged(event), "handled") - - testScript.presentMessage.assert_not_called() - self.assertEqual(chromiumCalls, [(testScript, event)]) - - def test_selected_changed_defers_when_foreground_is_not_steam_game(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - lastEvent = mock.Mock(event_string="Down", modifiers=0) - event = mock.Mock( - type="object:state-changed:selected", - source=source, - detail1=1, - any_data=None, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.displayedText.return_value = "" - testScript.presentMessage = mock.Mock() - - chromiumCalls = [] - - def chromiumOnSelectedChanged(self, selectedEvent): - chromiumCalls.append((self, selectedEvent)) - return "handled" - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=False, - ), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object( - steam_script.Chromium.Script, - "onSelectedChanged", - new=chromiumOnSelectedChanged, - ), - ): - self.assertEqual(testScript.onSelectedChanged(event), "handled") - - testScript.presentMessage.assert_not_called() - self.assertEqual(chromiumCalls, [(testScript, event)]) - - def test_selection_changed_uses_selected_child_from_quick_access_container(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - child = object() - lastEvent = mock.Mock(event_string=" ", modifiers=0) - event = mock.Mock( - type="object:selection-changed", - source=source, - detail1=0, - any_data=0, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.displayedText.return_value = "" - testScript.presentMessage = mock.Mock() - testScript._lastSteamOverlaySelection = ("", 0.0) - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=True), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object(steam_script.AXSelection, "get_selected_children", return_value=[child]), - mock.patch.object(steam_script.AXObject, "get_name", side_effect=lambda obj: "Friends" if obj is child else ""), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_list_item", side_effect=lambda obj: obj is child), - mock.patch.object(steam_script.AXUtilities, "is_menu_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - ): - self.assertTrue(testScript.onSelectionChanged(event)) - - testScript.presentMessage.assert_called_once_with( - "Friends", - force=True, - interrupt=True, - ) - - def test_selected_changed_presents_steam_big_picture_tab_when_steam_is_foreground(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - document = object() - lastEvent = mock.Mock(event_string="Right", modifiers=0) - event = mock.Mock( - type="object:state-changed:selected", - source=source, - detail1=1, - any_data=0, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.displayedText.return_value = "ACTIVITY" - testScript.utilities.getTopLevelDocumentForObject.return_value = document - testScript.utilities.documentFrameURI.return_value = "https://steamloopback.host/index.html" - testScript.presentMessage = mock.Mock() - testScript._lastSteamOverlaySelection = ("", 0.0) - - chromiumCalls = [] - - def chromiumOnSelectedChanged(self, selectedEvent): - chromiumCalls.append((self, selectedEvent)) - return False - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=False), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object(steam_script.AXObject, "get_name", return_value="ACTIVITY"), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_list_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_menu_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object( - steam_script.Chromium.Script, - "onSelectedChanged", - new=chromiumOnSelectedChanged, - ), - ): - self.assertTrue(testScript.onSelectedChanged(event)) - - testScript.presentMessage.assert_called_once_with( - "ACTIVITY", - force=True, - interrupt=True, - ) - self.assertEqual(chromiumCalls, []) - - def test_selected_changed_defers_steam_tab_outside_steam_big_picture_document(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - document = object() - lastEvent = mock.Mock(event_string="Right", modifiers=0) - event = mock.Mock( - type="object:state-changed:selected", - source=source, - detail1=1, - any_data=0, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.displayedText.return_value = "ACTIVITY" - testScript.utilities.getTopLevelDocumentForObject.return_value = document - testScript.utilities.documentFrameURI.return_value = "https://store.steampowered.com/" - testScript.presentMessage = mock.Mock() - - chromiumCalls = [] - - def chromiumOnSelectedChanged(self, selectedEvent): - chromiumCalls.append((self, selectedEvent)) - return "handled" - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=False), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object(steam_script.AXObject, "get_name", return_value="ACTIVITY"), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_list_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_menu_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object( - steam_script.Chromium.Script, - "onSelectedChanged", - new=chromiumOnSelectedChanged, - ), - ): - self.assertEqual(testScript.onSelectedChanged(event), "handled") - - testScript.presentMessage.assert_not_called() - self.assertEqual(chromiumCalls, [(testScript, event)]) - - def test_x11_steam_game_class_detects_steam_app_identifier(self): - classGroup = mock.Mock() - classGroup.get_name.return_value = "steam_app_1281930" - classGroup.get_res_class.return_value = "steam_app_1281930" - window = mock.Mock() - window.get_class_group_name.return_value = "" - window.get_class_instance_name.return_value = "" - window.get_class_group.return_value = classGroup - - self.assertTrue(steam_script.Script._x11WindowHasSteamGameClass(window)) - - def test_x11_steam_game_class_rejects_plain_chromium_window(self): - classGroup = mock.Mock() - classGroup.get_name.return_value = "chromium" - classGroup.get_res_class.return_value = "Chromium" - window = mock.Mock() - window.get_class_group_name.return_value = "Chromium" - window.get_class_instance_name.return_value = "chromium" - window.get_class_group.return_value = classGroup - - self.assertFalse(steam_script.Script._x11WindowHasSteamGameClass(window)) - - def test_x11_steam_big_picture_window_is_selection_context(self): - classGroup = mock.Mock() - classGroup.get_name.return_value = "steam" - classGroup.get_res_class.return_value = "steam" - window = mock.Mock() - window.get_name.return_value = "Steam Big Picture Mode" - window.get_class_group_name.return_value = "steam" - window.get_class_instance_name.return_value = "steamwebhelper" - window.get_class_group.return_value = classGroup - - self.assertTrue(steam_script.Script._x11WindowIsSteamBigPicture(window)) - - def test_x11_plain_steam_window_is_not_big_picture_selection_context(self): - classGroup = mock.Mock() - classGroup.get_name.return_value = "steam" - classGroup.get_res_class.return_value = "steam" - window = mock.Mock() - window.get_name.return_value = "Steam" - window.get_class_group_name.return_value = "steam" - window.get_class_instance_name.return_value = "steamwebhelper" - window.get_class_group.return_value = classGroup - - self.assertFalse(steam_script.Script._x11WindowIsSteamBigPicture(window)) - - -class SteamReturnActivationTests(unittest.TestCase): - def test_return_activates_focused_steam_button(self): - testScript = steam_script.Script.__new__(steam_script.Script) - button = object() - keyboardEvent = mock.Mock(event_string="Return", modifiers=0) - keyboardEvent.is_pressed_key.return_value = True - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.inFocusMode = mock.Mock(return_value=True) - testScript.presentMessage = mock.Mock() - testScript._presentDelayedMessage = mock.Mock() - testScript._restoreFocusAfterClick = mock.Mock() - - def has_action(obj, action_name): - return obj is button and action_name == "press" - - with ( - mock.patch.object(steam_script.cthulhu_state, "locusOfFocus", button), - mock.patch.object(steam_script.AXUtilities, "is_entry", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_text", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_password_text", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_combo_box", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_link", return_value=False), - mock.patch.object(steam_script.AXObject, "has_action", side_effect=has_action), - mock.patch.object(steam_script.Script, "_performClickableAction", return_value=True) as performAction, - ): - self.assertTrue(testScript.shouldConsumeKeyboardEvent(keyboardEvent, None)) - - performAction.assert_called_once_with(button) - - def test_return_activates_last_spoken_friends_panel_button(self): - testScript = steam_script.Script.__new__(steam_script.Script) - button = object() - keyboardEvent = mock.Mock(event_string="Return", modifiers=0) - keyboardEvent.is_pressed_key.return_value = True - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript._steamActiveQuickAccessTab = "Friends" - testScript._steamFriendsPanelActivationTarget = ( - button, - "Username Playing Terraria", - 100.0, - ) - testScript._steamFriendsPanelActivationTargetMaxAge = 10.0 - - def has_action(obj, action_name): - return obj is button and action_name == "press" - - with ( - mock.patch.object(steam_script.time, "monotonic", return_value=105.0), - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=True), - mock.patch.object(testScript, "_getClickableActivationTarget", return_value=None), - mock.patch.object(steam_script.AXObject, "is_dead", return_value=False), - mock.patch.object(steam_script.AXObject, "find_ancestor_inclusive", return_value=None), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_page_tab_list", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_list_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_table_row", return_value=False), - mock.patch.object(steam_script.AXObject, "has_action", side_effect=has_action), - mock.patch.object(steam_script.Script, "_performClickableAction", return_value=True) as performAction, - ): - self.assertTrue(testScript.shouldConsumeKeyboardEvent(keyboardEvent, None)) - - performAction.assert_called_once_with(button) - - def test_return_defers_stale_friends_panel_activation_target(self): - testScript = steam_script.Script.__new__(steam_script.Script) - button = object() - keyboardEvent = mock.Mock(event_string="Return", modifiers=0) - keyboardEvent.is_pressed_key.return_value = True - - testScript.utilities = mock.Mock() - testScript._steamActiveQuickAccessTab = "Friends" - testScript._steamFriendsPanelActivationTarget = ( - button, - "Username Playing Terraria", - 100.0, - ) - testScript._steamFriendsPanelActivationTargetMaxAge = 10.0 - - with ( - mock.patch.object(steam_script.time, "monotonic", return_value=111.0), - mock.patch.object(steam_script.debug, "printMessage"), - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(testScript, "_getClickableActivationTarget", return_value=None), - ): - self.assertFalse(testScript.shouldConsumeKeyboardEvent(keyboardEvent, None)) - - self.assertEqual(testScript._steamFriendsPanelActivationTarget, (None, "", 0.0)) - - def test_return_rejects_friends_target_after_nonsteam_x11_handoff(self): - testScript = steam_script.Script.__new__(steam_script.Script) - button = object() - keyboardEvent = mock.Mock(event_string="Return", modifiers=0) - keyboardEvent.is_pressed_key.return_value = True - - testScript.utilities = mock.Mock() - testScript._steamActiveQuickAccessTab = "Friends" - testScript._steamFriendsPanelActivationTarget = ( - button, - "Username Playing Terraria", - 100.0, - ) - testScript._steamFriendsPanelActivationTargetMaxAge = 10.0 - - with ( - mock.patch.object(steam_script.time, "monotonic", return_value=105.0), - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=False, - ), - mock.patch.object(testScript, "_getClickableActivationTarget", return_value=None), - mock.patch.object( - steam_script.Script, - "_performClickableAction", - ) as performAction, - ): - self.assertFalse(testScript.shouldConsumeKeyboardEvent(keyboardEvent, None)) - - performAction.assert_not_called() - - -class SteamVirtualizedListMutationTests(unittest.TestCase): - def test_name_changed_presents_friends_panel_item_after_friends_tab_activation(self): - testScript = steam_script.Script.__new__(steam_script.Script) - row = object() - lastEvent = mock.Mock(event_string="Down", modifiers=0) - event = mock.Mock( - type="object:property-change:accessible-name", - source=row, - any_data="Username Playing Terraria", - detail1=0, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.displayedText.side_effect = ( - lambda obj: "Username Playing Terraria" if obj is row else "" - ) - testScript.presentMessage = mock.Mock() - testScript._lastSteamOverlaySelection = ("", 0.0) - testScript._steamActiveQuickAccessTab = "Friends" - - chromiumCalls = [] - - def chromiumOnNameChanged(self, nameEvent): - chromiumCalls.append((self, nameEvent)) - return False - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=True), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_page_tab_list", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_list_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_table_row", return_value=False), - mock.patch.object(steam_script.AXObject, "find_ancestor_inclusive", return_value=None), - mock.patch.object( - steam_script.Chromium.Script, - "onNameChanged", - new=chromiumOnNameChanged, - ), - ): - self.assertTrue(testScript.onNameChanged(event)) - - testScript.presentMessage.assert_called_once_with( - "Username Playing Terraria", - force=True, - interrupt=True, - ) - self.assertEqual( - testScript._steamFriendsPanelActivationTarget[:2], - (row, "Username Playing Terraria"), - ) - self.assertEqual(chromiumCalls, []) - - def test_children_added_defers_friends_panel_load_artifact(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - row = object() - lastEvent = mock.Mock(event_string="Down", modifiers=0) - event = mock.Mock( - type="object:children-changed:add", - source=source, - any_data=row, - detail1=0, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.isSteamVirtualizedList.return_value = False - testScript.presentMessage = mock.Mock() - testScript._steamActiveQuickAccessTab = "Friends" - - chromiumCalls = [] - - def chromiumOnChildrenAdded(self, addedEvent): - chromiumCalls.append((self, addedEvent)) - return False - - with ( - mock.patch.object(steam_script.Script, "_isSteamNotification", return_value=False), - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object( - steam_script.Chromium.Script, - "onChildrenAdded", - new=chromiumOnChildrenAdded, - ), - ): - testScript.onChildrenAdded(event) - - testScript.presentMessage.assert_not_called() - self.assertEqual(chromiumCalls, [(testScript, event)]) - - def test_name_changed_ignores_add_friend_panel_button(self): - testScript = steam_script.Script.__new__(steam_script.Script) - button = object() - lastEvent = mock.Mock(event_string="Down", modifiers=0) - event = mock.Mock( - type="object:property-change:accessible-name", - source=button, - any_data="Add Friend", - detail1=0, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.displayedText.return_value = "Add Friend" - testScript.presentMessage = mock.Mock() - testScript._steamActiveQuickAccessTab = "Friends" - - chromiumCalls = [] - - def chromiumOnNameChanged(self, nameEvent): - chromiumCalls.append((self, nameEvent)) - return "handled" - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=True), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_page_tab_list", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_list_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_table_row", return_value=False), - mock.patch.object(steam_script.AXObject, "find_ancestor_inclusive", return_value=None), - mock.patch.object( - steam_script.Chromium.Script, - "onNameChanged", - new=chromiumOnNameChanged, - ), - ): - self.assertEqual(testScript.onNameChanged(event), "handled") - - testScript.presentMessage.assert_not_called() - self.assertEqual(chromiumCalls, [(testScript, event)]) - - def test_name_changed_ignores_friends_panel_chat_history_button(self): - testScript = steam_script.Script.__new__(steam_script.Script) - button = object() - lastEvent = mock.Mock(event_string="Down", modifiers=0) - event = mock.Mock( - type="object:property-change:accessible-name", - source=button, - any_data="LOADING OLDER MESSAGES... Username is typing a message...", - detail1=0, - ) - - testScript.utilities = mock.Mock() - testScript.utilities.displayedText.return_value = ( - "LOADING OLDER MESSAGES... Username is typing a message..." - ) - testScript.presentMessage = mock.Mock() - testScript._steamActiveQuickAccessTab = "Friends" - - chromiumCalls = [] - - def chromiumOnNameChanged(self, nameEvent): - chromiumCalls.append((self, nameEvent)) - return "handled" - - with ( - mock.patch.object( - steam_script.Script, - "_activeX11WindowIsSteamSelectionContext", - return_value=True, - ), - mock.patch.object(steam_script.Script, "_hasSteamQuickAccessMarker", return_value=True), - mock.patch.object(steam_script.cthulhu_state, "lastNonModifierKeyEvent", lastEvent), - mock.patch.object(steam_script.cthulhu_state, "lastInputEvent", None), - mock.patch.object(steam_script.AXUtilities, "is_page_tab", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_page_tab_list", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_list_item", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_button", return_value=True), - mock.patch.object(steam_script.AXUtilities, "is_push_button", return_value=False), - mock.patch.object(steam_script.AXUtilities, "is_table_row", return_value=False), - mock.patch.object(steam_script.AXObject, "find_ancestor_inclusive", return_value=None), - mock.patch.object( - steam_script.Chromium.Script, - "onNameChanged", - new=chromiumOnNameChanged, - ), - ): - self.assertEqual(testScript.onNameChanged(event), "handled") - - testScript.presentMessage.assert_not_called() - self.assertEqual(chromiumCalls, [(testScript, event)]) - - def test_caret_moved_ignores_transient_loading_spinner(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - spinner = object() - event = mock.Mock(type="object:text-caret-moved", source=source) - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - - with ( - mock.patch.object(steam_script.AXObject, "get_name", side_effect=["", "Steam Spinner"]), - mock.patch.object(steam_script.AXObject, "iter_children", return_value=iter([spinner])), - mock.patch.object(steam_script.AXUtilities, "is_image_or_canvas", return_value=True), - mock.patch.object(steam_script.debug, "printMessage"), - mock.patch.object(steam_script.Chromium.Script, "onCaretMoved") as chromiumCaretMoved, - ): - self.assertTrue(testScript.onCaretMoved(event)) - - chromiumCaretMoved.assert_not_called() - - def test_caret_moved_defers_to_chromium_without_loading_spinner(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - child = object() - event = mock.Mock(type="object:text-caret-moved", source=source) - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - - with ( - mock.patch.object(steam_script.AXObject, "get_name", side_effect=["", "Not A Spinner"]), - mock.patch.object(steam_script.AXObject, "iter_children", return_value=iter([child])), - mock.patch.object(steam_script.AXUtilities, "is_image_or_canvas", return_value=True), - mock.patch.object(steam_script.Chromium.Script, "onCaretMoved", return_value="handled") as chromiumCaretMoved, - ): - self.assertEqual(testScript.onCaretMoved(event), "handled") - - chromiumCaretMoved.assert_called_once_with(event) - - def test_children_added_skips_generic_web_cache_dump_for_virtualized_list_churn(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - focus = object() - event = mock.Mock( - type="object:children-changed:add", - source=source, - any_data=object(), - detail1=0, - ) - chromiumCalls = [] - - testScript.utilities = mock.Mock() - testScript.utilities.isSteamVirtualizedList.return_value = True - testScript.utilities.clearSteamVirtualizedListCaches = mock.Mock() - - def chromiumOnChildrenAdded(self, addedEvent): - chromiumCalls.append((self, addedEvent)) - return False - - with ( - mock.patch.object(steam_script.cthulhu_state, "locusOfFocus", focus), - mock.patch.object(steam_script.AXObject, "is_dead", return_value=False), - mock.patch.object(steam_script.AXObject, "find_ancestor", return_value=source), - mock.patch.object(steam_script.AXObject, "clear_cache_now") as clearCache, - mock.patch.object(steam_script.Script, "_isSteamNotification", return_value=False), - mock.patch.object( - steam_script.Chromium.Script, - "onChildrenAdded", - new=chromiumOnChildrenAdded, - ), - ): - self.assertTrue(testScript.onChildrenAdded(event)) - - clearCache.assert_called_once_with("children-changed event.") - testScript.utilities.clearSteamVirtualizedListCaches.assert_called_once_with() - self.assertEqual(chromiumCalls, []) - - def test_children_removed_skips_generic_web_cache_dump_for_virtualized_list_churn(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - focus = object() - event = mock.Mock( - type="object:children-changed:remove", - source=source, - any_data=object(), - detail1=0, - ) - chromiumCalls = [] - - testScript.utilities = mock.Mock() - testScript.utilities.isSteamVirtualizedList.return_value = True - testScript.utilities.clearSteamVirtualizedListCaches = mock.Mock() - - def chromiumOnChildrenRemoved(self, removedEvent): - chromiumCalls.append((self, removedEvent)) - return False - - with ( - mock.patch.object(steam_script.cthulhu_state, "locusOfFocus", focus), - mock.patch.object(steam_script.AXObject, "is_dead", return_value=False), - mock.patch.object(steam_script.AXObject, "find_ancestor", return_value=source), - mock.patch.object(steam_script.AXObject, "clear_cache_now") as clearCache, - mock.patch.object( - steam_script.Chromium.Script, - "onChildrenRemoved", - new=chromiumOnChildrenRemoved, - ), - ): - self.assertTrue(testScript.onChildrenRemoved(event)) - - clearCache.assert_called_once_with("children-changed event.") - testScript.utilities.clearSteamVirtualizedListCaches.assert_called_once_with() - self.assertEqual(chromiumCalls, []) - - def test_children_removed_defers_to_generic_handler_when_focus_is_dead(self): - testScript = steam_script.Script.__new__(steam_script.Script) - source = object() - focus = object() - event = mock.Mock( - type="object:children-changed:remove", - source=source, - any_data=object(), - detail1=0, - ) - chromiumCalls = [] - - testScript.utilities = mock.Mock() - testScript.utilities.isSteamVirtualizedList.return_value = True - - def chromiumOnChildrenRemoved(self, removedEvent): - chromiumCalls.append((self, removedEvent)) - return False - - with ( - mock.patch.object(steam_script.cthulhu_state, "locusOfFocus", focus), - mock.patch.object(steam_script.AXObject, "is_dead", return_value=True), - mock.patch.object( - steam_script.Chromium.Script, - "onChildrenRemoved", - new=chromiumOnChildrenRemoved, - ), - ): - self.assertFalse(testScript.onChildrenRemoved(event)) - - self.assertEqual(chromiumCalls, [(testScript, event)]) - testScript.utilities.clearSteamVirtualizedListCaches.assert_not_called() - - -class SteamLabelRecoveryTests(unittest.TestCase): - def test_displayed_label_recovers_friends_list_tab_text_from_parent_context(self): - testScript = mock.Mock(generatorCache={}) - utilities = steam_script_utilities.Utilities(testScript) - button = object() - parent = object() - textSibling = object() - - utilities.inDocumentContent = mock.Mock(return_value=True) - - def get_attribute(obj, name): - if obj is button and name == "class": - return "FriendsListTab Active Panel Focusable gpfocus" - return None - - def get_name(obj): - if obj is textSibling: - return "Friends" - return "" - - def iter_children(obj, pred=None): - children = [textSibling, button] - if obj is not parent: - children = [] - if pred is not None: - children = [child for child in children if pred(child)] - return iter(children) - - with ( - mock.patch.object(steam_script_utilities.ChromiumUtilities, "displayedLabel", return_value=""), - mock.patch.object(steam_script_utilities.AXObject, "get_parent", side_effect=lambda obj: parent if obj is button else None), - mock.patch.object(steam_script_utilities.AXObject, "get_attribute", side_effect=get_attribute), - mock.patch.object(steam_script_utilities.AXObject, "get_name", side_effect=get_name), - mock.patch.object(steam_script_utilities.AXObject, "supports_text", return_value=False), - mock.patch.object(steam_script_utilities.AXObject, "iter_children", side_effect=iter_children), - mock.patch.object(steam_script_utilities.AXUtilities, "is_button", side_effect=lambda obj: obj is button), - mock.patch.object(steam_script_utilities.AXUtilities, "is_push_button", return_value=False), - ): - self.assertEqual(utilities.displayedLabel(button), "Friends") - - def test_displayed_label_maps_add_friend_button_class_to_fallback_name(self): - testScript = mock.Mock(generatorCache={}) - utilities = steam_script_utilities.Utilities(testScript) - button = object() - - utilities.inDocumentContent = mock.Mock(return_value=True) - - def get_attribute(obj, name): - if obj is button and name == "class": - return "friendListButton AddFriendButton Panel Focusable" - return None - - with ( - mock.patch.object(steam_script_utilities.ChromiumUtilities, "displayedLabel", return_value=""), - mock.patch.object(steam_script_utilities.AXObject, "get_attribute", side_effect=get_attribute), - mock.patch.object(steam_script_utilities.AXObject, "get_name", return_value=""), - mock.patch.object(steam_script_utilities.AXUtilities, "is_button", side_effect=lambda obj: obj is button), - mock.patch.object(steam_script_utilities.AXUtilities, "is_push_button", return_value=False), - ): - self.assertEqual(utilities.displayedLabel(button), "Add Friend") - - -class SteamRedundantImageTests(unittest.TestCase): - def test_is_useless_image_treats_unlabeled_click_ancestor_image_with_nearby_text_as_useless(self): - testScript = mock.Mock(generatorCache={}) - utilities = steam_script_utilities.Utilities(testScript) - image = object() - parent = object() - entry = object() - - utilities.inDocumentContent = mock.Mock(return_value=True) - - def get_parent(obj): - if obj in (image, entry): - return parent - return None - - def get_name(obj): - if obj is entry: - return "Search for games or profiles..." - return "" - - def get_child_count(obj): - if obj is parent: - return 2 - return 0 - - def has_action(obj, actionName): - return obj is image and actionName == "click-ancestor" - - def iter_children(obj, pred=None): - children = [image, entry] if obj is parent else [] - if pred is not None: - children = [child for child in children if pred(child)] - return iter(children) - - with ( - mock.patch.object(steam_script_utilities.ChromiumUtilities, "isUselessImage", return_value=False), - mock.patch.object(steam_script_utilities.AXObject, "get_parent", side_effect=get_parent), - mock.patch.object(steam_script_utilities.AXObject, "get_name", side_effect=get_name), - mock.patch.object(steam_script_utilities.AXObject, "get_description", return_value=""), - mock.patch.object(steam_script_utilities.AXObject, "get_child_count", side_effect=get_child_count), - mock.patch.object(steam_script_utilities.AXObject, "has_action", side_effect=has_action), - mock.patch.object(steam_script_utilities.AXObject, "iter_children", side_effect=iter_children), - mock.patch.object(steam_script_utilities.AXObject, "supports_text", return_value=False), - mock.patch.object( - steam_script_utilities.AXObject, - "get_role_description", - side_effect=lambda obj: "Unlabeled image" if obj is image else "", - ), - mock.patch.object( - steam_script_utilities.AXUtilities, - "is_image_or_canvas", - side_effect=lambda obj: obj is image, - ), - mock.patch.object(steam_script_utilities.AXUtilities, "is_focusable", return_value=False), - mock.patch.object(steam_script_utilities.AXUtilities, "is_button", return_value=False), - mock.patch.object(steam_script_utilities.AXUtilities, "is_push_button", return_value=False), - ): - self.assertTrue(utilities.isUselessImage(image)) - - def test_is_useless_image_defers_to_generic_logic_without_nearby_text(self): - testScript = mock.Mock(generatorCache={}) - utilities = steam_script_utilities.Utilities(testScript) - image = object() - - utilities.inDocumentContent = mock.Mock(return_value=True) - - with ( - mock.patch.object(steam_script_utilities.ChromiumUtilities, "isUselessImage", return_value=False), - mock.patch.object(steam_script_utilities.AXObject, "get_parent", return_value=None), - mock.patch.object(steam_script_utilities.AXObject, "get_name", return_value=""), - mock.patch.object(steam_script_utilities.AXObject, "get_description", return_value=""), - mock.patch.object(steam_script_utilities.AXObject, "get_child_count", return_value=0), - mock.patch.object(steam_script_utilities.AXObject, "has_action", return_value=True), - mock.patch.object(steam_script_utilities.AXObject, "supports_text", return_value=False), - mock.patch.object(steam_script_utilities.AXObject, "get_role_description", return_value=""), - mock.patch.object( - steam_script_utilities.AXUtilities, - "is_image_or_canvas", - side_effect=lambda obj: obj is image, - ), - mock.patch.object(steam_script_utilities.AXUtilities, "is_focusable", return_value=False), - ): - self.assertFalse(utilities.isUselessImage(image)) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_structural_navigation_table_regressions.py b/tests/test_structural_navigation_table_regressions.py deleted file mode 100644 index 987c9e1..0000000 --- a/tests/test_structural_navigation_table_regressions.py +++ /dev/null @@ -1,105 +0,0 @@ -import os -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - -os.environ.setdefault("GSETTINGS_BACKEND", "memory") - -gi.require_version("Atspi", "2.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import messages -from cthulhu import structural_navigation - - -class StructuralNavigationTableRegressionTests(unittest.TestCase): - def test_object_presentation_marks_keyboard_interruption_as_already_handled(self): - navigator = structural_navigation.StructuralNavigation.__new__( - structural_navigation.StructuralNavigation - ) - navigator._script = mock.Mock() - navigator._presentWithSayAll = mock.Mock(return_value=False) - target = object() - - with mock.patch.object(structural_navigation.AXEventSynthesizer, "scroll_to_top_edge"): - navigator._presentObject(target, 3, "prior") - - navigator._script.presentObject.assert_called_once_with( - target, - offset=3, - priorObj="prior", - interrupt=True, - interrupt_already_handled=True, - ) - - def test_table_cell_coordinates_do_not_interrupt_cell_contents(self): - navigator = structural_navigation.StructuralNavigation.__new__( - structural_navigation.StructuralNavigation - ) - navigator._script = mock.Mock() - navigator._script.utilities.rowAndColumnSpan.return_value = (1, 1) - navigator._getCaretPosition = mock.Mock(return_value=("cell", 0)) - navigator._setCaretPosition = mock.Mock(return_value=("cell", 0)) - navigator._isBlankCell = mock.Mock(return_value=False) - navigator._presentObject = mock.Mock() - navigator.getCellCoordinates = mock.Mock(return_value=(1, 2)) - - with ( - mock.patch.object(structural_navigation.settings, "speakCellHeaders", False), - mock.patch.object(structural_navigation.settings, "speakCellCoordinates", True), - mock.patch.object(structural_navigation.settings, "speakCellSpan", False), - ): - navigator._tableCellPresentation("cell", None) - - navigator._presentObject.assert_called_once_with("cell", 0) - navigator._script.presentMessage.assert_called_once_with( - messages.TABLE_CELL_COORDINATES % {"row": 2, "column": 3} - ) - - def test_wrapping_announcement_does_not_interrupt_wrapped_object(self): - navigator = structural_navigation.StructuralNavigation.__new__( - structural_navigation.StructuralNavigation - ) - script = mock.Mock() - script.utilities.isZombie.return_value = False - script.utilities.isHidden.return_value = False - script.utilities.isEmpty.return_value = False - script.utilities.pathComparison.return_value = 0 - navigator._script = script - - first = object() - current = object() - structuralNavigationObject = mock.Mock() - structuralNavigationObject.predicate = None - events = [] - structuralNavigationObject.present.side_effect = lambda obj, arg=None: events.append( - ("present", obj, arg) - ) - script.presentMessage.side_effect = lambda message, **kwargs: events.append( - ("message", message, kwargs) - ) - navigator._getAll = mock.Mock(return_value=[first, current]) - - with ( - mock.patch.object(structural_navigation.settings, "wrappedStructuralNavigation", True), - mock.patch.object(structural_navigation.AXObject, "is_dead", return_value=False), - mock.patch.object(structural_navigation.AXObject, "get_parent", return_value=None), - mock.patch.object(structural_navigation.AXObject, "get_path", side_effect=lambda obj: [id(obj)]), - ): - navigator.goObject(structuralNavigationObject, True, current, "arg") - - self.assertEqual( - events, - [ - ("present", first, "arg"), - ("message", messages.WRAPPING_TO_TOP, {}), - ], - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_toml_backend_legacy_schema_regressions.py b/tests/test_toml_backend_legacy_schema_regressions.py deleted file mode 100644 index 6e63791..0000000 --- a/tests/test_toml_backend_legacy_schema_regressions.py +++ /dev/null @@ -1,139 +0,0 @@ -import tempfile -import unittest -from pathlib import Path - -from cthulhu import settings -from cthulhu.backends.toml_backend import Backend - - -LEGACY_SETTINGS = """format-version = 2 - -[profiles.default.metadata] -display-name = "Default" -internal-name = "default" - -[profiles.default.keybindings] -keyboard-layout = "desktop" -desktop-modifier-keys = ["Insert", "KP_Insert"] - -[profiles.default.ai-assistant] -enabled = false -provider = "ollama" -api-key-file = "" -ollama-model = "llama3.2-vision" -ollama-endpoint = "http://localhost:11434" -confirmation-required = true -action-timeout = 30 -screenshot-quality = "medium" -max-context-length = 4000 - -[profiles.default.ocr] -language-code = "eng" -scale-factor = 3 -grayscale-image = false -invert-image = false -black-white-image = false -black-white-threshold = 200 -color-calculation = false -color-calculation-max = 3 -copy-to-clipboard = false - -[profiles.default.plugins] -active-plugins = ["Clipboard", "OCR"] -plugin-sources = [] -""" - - -class LegacyTomlSchemaMigrationTests(unittest.TestCase): - def test_backend_migrates_legacy_nested_profile_schema_on_read(self): - with tempfile.TemporaryDirectory() as tempDir: - Path(tempDir, "user-settings.toml").write_text( - LEGACY_SETTINGS, - encoding="utf-8", - ) - - backend = Backend(tempDir) - - self.assertEqual(backend.availableProfiles(), [["Default", "default"]]) - - general = backend.getGeneral("default") - - self.assertEqual(general["profile"], ["Default", "default"]) - self.assertEqual( - general["keyboardLayout"], - settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP, - ) - self.assertEqual(general["cthulhuModifierKeys"], settings.DESKTOP_MODIFIER_KEYS) - self.assertEqual( - general["activePlugins"], - ["Clipboard", "OCR", "WineAccessibility"], - ) - self.assertTrue(general["wineAccessibilityPluginMigrated"]) - self.assertEqual(general["aiProvider"], settings.AI_PROVIDER_OLLAMA) - self.assertFalse(general["aiAssistantEnabled"]) - self.assertEqual(general["ocrLanguageCode"], "eng") - self.assertEqual(backend.getKeybindings("default"), {}) - - def test_saving_after_legacy_read_rewrites_current_schema(self): - with tempfile.TemporaryDirectory() as tempDir: - settingsPath = Path(tempDir, "user-settings.toml") - settingsPath.write_text(LEGACY_SETTINGS, encoding="utf-8") - - backend = Backend(tempDir) - general = backend.getGeneral("default") - backend.saveProfileSettings("default", dict(general), {}, {}) - - savedSettings = settingsPath.read_text(encoding="utf-8") - - self.assertIn('profile = ["Default", "default"]', savedSettings) - self.assertIn( - 'activePlugins = ["Clipboard", "OCR", "WineAccessibility"]', - savedSettings, - ) - self.assertIn("wineAccessibilityPluginMigrated = true", savedSettings) - self.assertNotIn("format-version = 2", savedSettings) - self.assertNotIn("[profiles.default.metadata]", savedSettings) - - def test_wine_accessibility_migration_respects_later_plugin_disable(self): - migratedSettings = """[general] -startingProfile = ["Default", "default"] - -[profiles.default] -profile = ["Default", "default"] -activePlugins = ["Clipboard", "OCR"] -wineAccessibilityPluginMigrated = true -""" - - with tempfile.TemporaryDirectory() as tempDir: - Path(tempDir, "user-settings.toml").write_text( - migratedSettings, - encoding="utf-8", - ) - - backend = Backend(tempDir) - general = backend.getGeneral("default") - - self.assertEqual(general["activePlugins"], ["Clipboard", "OCR"]) - - def test_legacy_profile_keybindings_are_preserved(self): - legacySettings = LEGACY_SETTINGS.replace( - 'desktop-modifier-keys = ["Insert", "KP_Insert"]', - 'desktop-modifier-keys = ["Insert", "KP_Insert"]\ncustom-binding = "kb:cthulhu+x"', - ) - - with tempfile.TemporaryDirectory() as tempDir: - Path(tempDir, "user-settings.toml").write_text( - legacySettings, - encoding="utf-8", - ) - - backend = Backend(tempDir) - - self.assertEqual( - backend.getKeybindings("default"), - {"custom-binding": "kb:cthulhu+x"}, - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_web_event_router_contract.py b/tests/test_web_event_router_contract.py deleted file mode 100644 index 8ef821c..0000000 --- a/tests/test_web_event_router_contract.py +++ /dev/null @@ -1,313 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu.scripts.web.event_router import RouteResult -from cthulhu.scripts.web.event_router import RoutingLayer -from cthulhu.scripts.web.event_router import WebEventRouter -from cthulhu.scripts import default -from cthulhu.scripts import web -from cthulhu.scripts.toolkits.Chromium import script as chromium_script -from cthulhu.scripts.toolkits.Gecko import script as gecko_script - - -class WebEventRouterContractTests(unittest.TestCase): - def setUp(self): - self.event = object() - self.application_handler = mock.Mock(return_value=RouteResult.CONTINUE) - self.toolkit_handler = mock.Mock(return_value=RouteResult.CONTINUE) - self.web_handler = mock.Mock(return_value=RouteResult.CONTINUE) - self.default_handler = mock.Mock() - self.router = WebEventRouter() - - def route_event(self): - return self.router.route_event( - self.event, - application_handler=self.application_handler, - toolkit_handler=self.toolkit_handler, - web_handler=self.web_handler, - default_handler=self.default_handler, - ) - - def test_application_handler_owns_steam_event(self): - self.application_handler.return_value = RouteResult.HANDLED - - self.assertEqual(self.route_event(), RoutingLayer.APPLICATION) - - self.application_handler.assert_called_once_with(self.event) - self.toolkit_handler.assert_not_called() - self.web_handler.assert_not_called() - self.default_handler.assert_not_called() - - def test_toolkit_handler_owns_chromium_quirk(self): - self.toolkit_handler.return_value = RouteResult.HANDLED - - self.assertEqual(self.route_event(), RoutingLayer.TOOLKIT) - - self.application_handler.assert_called_once_with(self.event) - self.toolkit_handler.assert_called_once_with(self.event) - self.web_handler.assert_not_called() - self.default_handler.assert_not_called() - - def test_shared_web_handler_owns_document_event(self): - self.web_handler.return_value = RouteResult.HANDLED - - self.assertEqual(self.route_event(), RoutingLayer.SHARED_WEB) - - self.application_handler.assert_called_once_with(self.event) - self.toolkit_handler.assert_called_once_with(self.event) - self.web_handler.assert_called_once_with(self.event) - self.default_handler.assert_not_called() - - def test_unhandled_browser_ui_reaches_default_once(self): - self.assertEqual(self.route_event(), RoutingLayer.DEFAULT) - - self.application_handler.assert_called_once_with(self.event) - self.toolkit_handler.assert_called_once_with(self.event) - self.web_handler.assert_called_once_with(self.event) - self.default_handler.assert_called_once_with(self.event) - - def test_explicit_default_deferral_skips_remaining_handlers(self): - self.toolkit_handler.return_value = RouteResult.DEFER_DEFAULT - - self.assertEqual(self.route_event(), RoutingLayer.DEFAULT) - - self.application_handler.assert_called_once_with(self.event) - self.toolkit_handler.assert_called_once_with(self.event) - self.web_handler.assert_not_called() - self.default_handler.assert_called_once_with(self.event) - - def test_invalid_route_result_logs_and_reaches_default_once(self): - self.toolkit_handler.return_value = object() - - with mock.patch( - "cthulhu.scripts.web.event_router.debug.printMessage" - ) as print_message: - self.assertEqual(self.route_event(), RoutingLayer.DEFAULT) - - self.web_handler.assert_not_called() - self.default_handler.assert_called_once_with(self.event) - messages = [call.args[1] for call in print_message.call_args_list] - self.assertTrue(any("invalid result" in message for message in messages)) - self.assertTrue(any("TOOLKIT" in message for message in messages)) - - def test_handler_exception_logs_and_reaches_default_once(self): - self.toolkit_handler.side_effect = RuntimeError("broken handler") - - with mock.patch( - "cthulhu.scripts.web.event_router.debug.printMessage" - ) as print_message: - self.assertEqual(self.route_event(), RoutingLayer.DEFAULT) - - self.web_handler.assert_not_called() - self.default_handler.assert_called_once_with(self.event) - messages = [call.args[1] for call in print_message.call_args_list] - self.assertTrue(any("raised RuntimeError" in message for message in messages)) - self.assertTrue(any("TOOLKIT" in message for message in messages)) - - -class CheckedStateRoutingContractTests(unittest.TestCase): - def test_shared_web_owns_checked_state_without_default_fallback(self): - for toolkit_script in (chromium_script, gecko_script): - with self.subTest(toolkit=toolkit_script.__name__): - test_script = toolkit_script.Script.__new__(toolkit_script.Script) - test_script._eventRouter = WebEventRouter() - event = object() - with ( - mock.patch.object( - web.Script, - "onCheckedChanged", - return_value=True, - ) as web_handler, - mock.patch.object( - default.Script, - "onCheckedChanged", - ) as default_handler, - mock.patch( - "cthulhu.scripts.web.event_router.debug.printMessage" - ) as print_message, - ): - toolkit_script.Script.onCheckedChanged(test_script, event) - - web_handler.assert_called_once_with(test_script, event) - default_handler.assert_not_called() - messages = [call.args[1] for call in print_message.call_args_list] - self.assertIn( - "WEB EVENT ROUTER: SHARED_WEB -> HANDLED", - messages, - ) - - def test_unhandled_checked_state_reaches_default_once(self): - for toolkit_script in (chromium_script, gecko_script): - with self.subTest(toolkit=toolkit_script.__name__): - test_script = toolkit_script.Script.__new__(toolkit_script.Script) - test_script._eventRouter = WebEventRouter() - event = object() - with ( - mock.patch.object( - web.Script, - "onCheckedChanged", - return_value=False, - ) as web_handler, - mock.patch.object( - default.Script, - "onCheckedChanged", - ) as default_handler, - mock.patch( - "cthulhu.scripts.web.event_router.debug.printMessage" - ) as print_message, - ): - toolkit_script.Script.onCheckedChanged(test_script, event) - - web_handler.assert_called_once_with(test_script, event) - default_handler.assert_called_once_with(test_script, event) - messages = [call.args[1] for call in print_message.call_args_list] - self.assertIn( - "WEB EVENT ROUTER: DEFAULT -> HANDLED", - messages, - ) - - -class ExpandedStateRoutingContractTests(unittest.TestCase): - def test_shared_web_owns_expanded_state_without_default_fallback(self): - for toolkit_script in (chromium_script, gecko_script): - with self.subTest(toolkit=toolkit_script.__name__): - test_script = toolkit_script.Script.__new__(toolkit_script.Script) - test_script._eventRouter = WebEventRouter() - event = object() - with ( - mock.patch.object( - web.Script, - "onExpandedChanged", - return_value=True, - ) as web_handler, - mock.patch.object( - default.Script, - "onExpandedChanged", - ) as default_handler, - mock.patch( - "cthulhu.scripts.web.event_router.debug.printMessage" - ) as print_message, - ): - toolkit_script.Script.onExpandedChanged(test_script, event) - - web_handler.assert_called_once_with(test_script, event) - default_handler.assert_not_called() - messages = [call.args[1] for call in print_message.call_args_list] - self.assertIn( - "WEB EVENT ROUTER: SHARED_WEB -> HANDLED", - messages, - ) - - def test_unhandled_expanded_state_reaches_default_once(self): - for toolkit_script in (chromium_script, gecko_script): - with self.subTest(toolkit=toolkit_script.__name__): - test_script = toolkit_script.Script.__new__(toolkit_script.Script) - test_script._eventRouter = WebEventRouter() - event = object() - with ( - mock.patch.object( - web.Script, - "onExpandedChanged", - return_value=False, - ) as web_handler, - mock.patch.object( - default.Script, - "onExpandedChanged", - ) as default_handler, - mock.patch( - "cthulhu.scripts.web.event_router.debug.printMessage" - ) as print_message, - ): - toolkit_script.Script.onExpandedChanged(test_script, event) - - web_handler.assert_called_once_with(test_script, event) - default_handler.assert_called_once_with(test_script, event) - messages = [call.args[1] for call in print_message.call_args_list] - self.assertIn( - "WEB EVENT ROUTER: DEFAULT -> HANDLED", - messages, - ) - - -class TableReorderRoutingContractTests(unittest.TestCase): - def test_shared_web_owns_table_reorder_without_default_fallback(self): - for toolkit_script in (chromium_script, gecko_script): - for handler_name in ("onColumnReordered", "onRowReordered"): - with self.subTest( - toolkit=toolkit_script.__name__, - handler=handler_name, - ): - test_script = toolkit_script.Script.__new__(toolkit_script.Script) - test_script._eventRouter = WebEventRouter() - event = object() - with ( - mock.patch.object( - web.Script, - handler_name, - return_value=True, - ) as web_handler, - mock.patch.object( - default.Script, - handler_name, - ) as default_handler, - mock.patch( - "cthulhu.scripts.web.event_router.debug.printMessage" - ) as print_message, - ): - getattr(toolkit_script.Script, handler_name)(test_script, event) - - web_handler.assert_called_once_with(test_script, event) - default_handler.assert_not_called() - messages = [call.args[1] for call in print_message.call_args_list] - self.assertIn( - "WEB EVENT ROUTER: SHARED_WEB -> HANDLED", - messages, - ) - - def test_unhandled_table_reorder_reaches_default_once(self): - for toolkit_script in (chromium_script, gecko_script): - for handler_name in ("onColumnReordered", "onRowReordered"): - with self.subTest( - toolkit=toolkit_script.__name__, - handler=handler_name, - ): - test_script = toolkit_script.Script.__new__(toolkit_script.Script) - test_script._eventRouter = WebEventRouter() - event = object() - with ( - mock.patch.object( - web.Script, - handler_name, - return_value=False, - ) as web_handler, - mock.patch.object( - default.Script, - handler_name, - ) as default_handler, - mock.patch( - "cthulhu.scripts.web.event_router.debug.printMessage" - ) as print_message, - ): - getattr(toolkit_script.Script, handler_name)(test_script, event) - - web_handler.assert_called_once_with(test_script, event) - default_handler.assert_called_once_with(test_script, event) - messages = [call.args[1] for call in print_message.call_args_list] - self.assertIn( - "WEB EVENT ROUTER: DEFAULT -> HANDLED", - messages, - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_web_event_sequences.py b/tests/test_web_event_sequences.py deleted file mode 100644 index 0123b0d..0000000 --- a/tests/test_web_event_sequences.py +++ /dev/null @@ -1,1216 +0,0 @@ -"""Ordered browser event-sequence regression tests.""" - -import unittest -from dataclasses import dataclass -from typing import Any -from unittest import mock - -import gi - -gi.require_version("Atspi", "2.0") -from gi.repository import Atspi - -from cthulhu import cthulhu_state -from cthulhu.ax_utilities_event import AXUtilitiesEvent, TextEventReason -from cthulhu.scripts import default -from cthulhu.scripts.toolkits.Chromium import script as chromium_script -from cthulhu.scripts.toolkits.Gecko import script as gecko_script -from cthulhu.scripts.web import script as web_script - - -@dataclass(eq=False) -class FakeAccessible: - """Minimal accessible metadata needed to describe a sequence target.""" - - role: Atspi.Role - editable: bool = False - - -@dataclass(eq=False) -class FakeEvent: - """Minimal AT-SPI event used by ordered web regression fixtures.""" - - type: str - source: FakeAccessible - detail1: int = 0 - any_data: FakeAccessible | None = None - - -class WebEventSequence: - """Dispatch an ordered event list through Chromium's current routing path.""" - - def __init__(self, testScript: chromium_script.Script) -> None: - self.testScript = testScript - - def run(self, events: list[FakeEvent]) -> None: - handlers = { - "object:active-descendant-changed": chromium_script.Script.onActiveDescendantChanged, - "object:children-changed:add": chromium_script.Script.onChildrenAdded, - "object:children-changed:remove": chromium_script.Script.onChildrenRemoved, - "object:selection-changed": chromium_script.Script.onSelectionChanged, - "object:state-changed:busy": chromium_script.Script.onBusyChanged, - "object:text-caret-moved": chromium_script.Script.onCaretMoved, - "object:text-selection-changed": chromium_script.Script.onTextSelectionChanged, - "object:state-changed:focused": chromium_script.Script.onFocusedChanged, - "document:load-complete": chromium_script.Script.onDocumentLoadComplete, - "document:reload": chromium_script.Script.onDocumentReload, - } - for event in events: - handler = handlers[event.type] - handler(self.testScript, event) - - -class GeckoEventSequence: - """Dispatch an ordered event list through Gecko's current routing path.""" - - def __init__(self, testScript: gecko_script.Script) -> None: - self.testScript = testScript - - def run(self, events: list[FakeEvent]) -> None: - handlers = { - "object:text-caret-moved": gecko_script.Script.onCaretMoved, - "object:state-changed:focused": gecko_script.Script.onFocusedChanged, - } - for event in events: - handler = handlers[event.type] - handler(self.testScript, event) - - -class ChromiumTabFocusSequenceTests(unittest.TestCase): - """Behavior contracts for controls reached by Tab in Chromium.""" - - @staticmethod - def _make_script(document: object, oldFocus: object) -> chromium_script.Script: - testScript = chromium_script.Script.__new__(chromium_script.Script) - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript._lastCommandWasMouseButton = False - testScript._clearSyntheticWebSelection = mock.Mock() - testScript.utilities = mock.Mock() - testScript.utilities.isStaticTextLeaf.return_value = False - testScript.utilities.isRedundantAutocompleteEvent.return_value = False - testScript.utilities.isZombie.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = document - testScript.utilities.getCaretContext.return_value = (oldFocus, 0) - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False - testScript.utilities.lastInputEventWasCharNav.return_value = False - testScript.utilities.getDocumentForObject.return_value = document - testScript.utilities.isWebAppDescendant.return_value = False - testScript.utilities.handleEventFromContextReplicant.return_value = False - return testScript - - def _assert_tab_caret_focused_sequence_presents_once( - self, - target: FakeAccessible, - ) -> None: - document = object() - oldFocus = object() - testScript = self._make_script(document, oldFocus) - inputManager = mock.Mock() - inputManager.last_event_was_caret_selection.return_value = False - inputManager.last_event_was_caret_navigation.return_value = False - inputManager.last_event_was_select_all.return_value = False - inputManager.last_event_was_primary_click_or_release.return_value = False - inputManager.last_event_was_tab_navigation.return_value = True - presentations: list[Any] = [] - events = [ - FakeEvent("object:text-caret-moved", target, detail1=0), - FakeEvent("object:state-changed:focused", target, detail1=1), - ] - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", oldFocus), - mock.patch( - "cthulhu.input_event_manager.get_manager", - return_value=inputManager, - ), - mock.patch( - "cthulhu.ax_utilities_event.focus_manager.get_manager" - ) as getFocusManager, - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_text_input_search", - return_value=False, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesState.is_editable", - side_effect=lambda obj: obj.editable, - ), - mock.patch.object( - web_script.AXUtilities, - "is_editable", - side_effect=lambda obj: obj.editable, - ), - mock.patch.object(web_script.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_focusable", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_focused", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_document", return_value=False), - mock.patch.object( - default.Script, - "onCaretMoved", - side_effect=lambda _script, event: presentations.append(event.source), - ) as defaultCaretHandler, - mock.patch.object( - default.Script, - "onFocusedChanged", - side_effect=lambda _script, event: presentations.append(event.source), - ) as defaultFocusHandler, - ): - getFocusManager.return_value.get_active_mode_and_object_of_interest.return_value = ( - None, - oldFocus, - ) - WebEventSequence(testScript).run(events) - - self.assertEqual(presentations, [target]) - defaultCaretHandler.assert_not_called() - defaultFocusHandler.assert_called_once_with(testScript, events[1]) - testScript._clearSyntheticWebSelection.assert_called_once_with() - - def test_tab_caret_focused_sequence_presents_editable_custom_button_once(self) -> None: - customButton = FakeAccessible(Atspi.Role.PUSH_BUTTON, editable=True) - - self._assert_tab_caret_focused_sequence_presents_once(customButton) - - def test_tab_caret_focused_sequence_presents_native_entry_once(self) -> None: - entry = FakeAccessible(Atspi.Role.ENTRY, editable=True) - - self._assert_tab_caret_focused_sequence_presents_once(entry) - - def test_tab_caret_focused_sequence_presents_native_checkbox_once(self) -> None: - checkbox = FakeAccessible(Atspi.Role.CHECK_BOX) - - self._assert_tab_caret_focused_sequence_presents_once(checkbox) - - def test_tab_caret_focused_sequence_presents_native_radio_once(self) -> None: - radio = FakeAccessible(Atspi.Role.RADIO_BUTTON) - - self._assert_tab_caret_focused_sequence_presents_once(radio) - - -class FocusedChangeInteractionSequenceTests(unittest.TestCase): - """Ordered ownership contracts around focused-change events.""" - - @staticmethod - def _make_script( - document: object, - caretContext: FakeAccessible, - ) -> chromium_script.Script: - testScript = chromium_script.Script.__new__(chromium_script.Script) - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript._lastCommandWasMouseButton = False - testScript._browseModeIsSticky = False - testScript._clearSyntheticWebSelection = mock.Mock() - testScript.refreshKeyGrabs = mock.Mock() - testScript.utilities = mock.Mock() - testScript.utilities.isDocument.return_value = False - testScript.utilities.isStaticTextLeaf.return_value = False - testScript.utilities.isRedundantAutocompleteEvent.return_value = False - testScript.utilities.isZombie.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = document - testScript.utilities.getDocumentForObject.return_value = document - testScript.utilities.getCaretContext.return_value = (caretContext, 0) - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False - testScript.utilities.lastInputEventWasCharNav.return_value = False - testScript.utilities.inFindContainer.return_value = False - testScript.utilities.eventIsFromLocusOfFocusDocument.return_value = True - testScript.utilities.isWebAppDescendant.return_value = False - testScript.utilities.handleEventFromContextReplicant.return_value = False - testScript.utilities.lastInputEventWasPageNav.return_value = False - testScript.utilities.isAnchor.return_value = False - testScript.utilities.isLink.return_value = False - testScript.utilities.isChildOfCurrentFragment.return_value = False - testScript.utilities.documentFragment.return_value = "" - return testScript - - def _assert_navigation_command_owns_caret_and_focus_pair( - self, - *, - caretNavigation: bool, - structuralNavigation: bool, - ) -> None: - document = object() - target = FakeAccessible(Atspi.Role.PARAGRAPH) - testScript = self._make_script(document, target) - testScript._lastCommandWasCaretNav = caretNavigation - testScript._lastCommandWasStructNav = structuralNavigation - events = [ - FakeEvent("object:text-caret-moved", target, detail1=4), - FakeEvent("object:state-changed:focused", target, detail1=1), - ] - presentations = ["navigation-command"] - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", target), - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.NAVIGATION_BY_CHARACTER, - ), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_focusable", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_focused", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_document", return_value=False), - mock.patch.object( - default.Script, - "onCaretMoved", - side_effect=lambda _script, _event: presentations.append("caret-event"), - ) as defaultCaretHandler, - mock.patch.object( - default.Script, - "onFocusedChanged", - side_effect=lambda _script, _event: presentations.append("focus-event"), - ) as defaultFocusHandler, - ): - WebEventSequence(testScript).run(events) - - self.assertEqual(presentations, ["navigation-command"]) - defaultCaretHandler.assert_not_called() - defaultFocusHandler.assert_not_called() - - def test_caret_navigation_owns_following_caret_and_focus_events(self) -> None: - self._assert_navigation_command_owns_caret_and_focus_pair( - caretNavigation=True, - structuralNavigation=False, - ) - - def test_structural_navigation_owns_following_caret_and_focus_events(self) -> None: - self._assert_navigation_command_owns_caret_and_focus_pair( - caretNavigation=False, - structuralNavigation=True, - ) - - def test_tab_clears_navigation_ownership_and_real_focus_still_presents(self) -> None: - document = object() - oldTarget = FakeAccessible(Atspi.Role.PARAGRAPH) - newTarget = FakeAccessible(Atspi.Role.ENTRY, editable=True) - testScript = self._make_script(document, oldTarget) - testScript._lastCommandWasCaretNav = True - ignoredFocus = FakeEvent( - "object:state-changed:focused", - oldTarget, - detail1=1, - ) - realFocus = FakeEvent( - "object:state-changed:focused", - newTarget, - detail1=1, - ) - tabEvent = mock.Mock(event_string="Tab") - tabEvent.is_modifier_key.return_value = False - presentations: list[FakeAccessible] = [] - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", oldTarget), - mock.patch.object( - web_script.AXUtilities, - "is_editable", - side_effect=lambda obj: obj.editable, - ), - mock.patch.object(web_script.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_focusable", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_focused", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_document", return_value=False), - mock.patch.object(default.Script, "shouldConsumeKeyboardEvent", return_value=False), - mock.patch.object( - default.Script, - "onFocusedChanged", - side_effect=lambda _script, event: presentations.append(event.source), - ) as defaultFocusHandler, - ): - WebEventSequence(testScript).run([ignoredFocus]) - web_script.Script.shouldConsumeKeyboardEvent(testScript, tabEvent, None) - WebEventSequence(testScript).run([realFocus]) - - self.assertEqual(presentations, [newTarget]) - self.assertFalse(testScript._lastCommandWasCaretNav) - self.assertFalse(testScript._lastCommandWasStructNav) - defaultFocusHandler.assert_called_once_with(testScript, realFocus) - - def _assert_document_focus_uses_recovered_context_once( - self, - *, - pageNavigation: bool, - documentFragment: str, - ) -> None: - document = FakeAccessible(Atspi.Role.DOCUMENT_WEB) - oldFocus = FakeAccessible(Atspi.Role.FRAME) - context = FakeAccessible(Atspi.Role.LINK) - testScript = self._make_script(document, context) - testScript.utilities.getDocumentForObject.side_effect = ( - lambda obj: document if obj is document else None - ) - testScript.utilities.getCaretContext.return_value = (None, -1) - testScript.utilities.searchForCaretContext.return_value = (context, 6) - testScript.utilities.lastInputEventWasPageNav.return_value = pageNavigation - testScript.utilities.isLink.side_effect = lambda obj: obj is context - testScript.utilities.documentFragment.return_value = documentFragment - event = FakeEvent("object:state-changed:focused", document, detail1=1) - presentations: list[FakeAccessible] = [] - - def set_focus( - _event: FakeEvent, - obj: FakeAccessible, - notifyScript: bool = True, - ) -> None: - if notifyScript: - presentations.append(obj) - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", oldFocus), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_focusable", return_value=True), - mock.patch.object( - web_script.AXUtilities, - "is_focused", - side_effect=lambda obj: obj is document, - ), - mock.patch.object( - web_script.AXUtilities, - "is_document", - side_effect=lambda obj: obj is document, - ), - mock.patch.object(web_script.AXObject, "clear_cache"), - mock.patch.object(web_script.cthulhu, "setLocusOfFocus", side_effect=set_focus) as setFocus, - mock.patch.object(default.Script, "onFocusedChanged") as defaultFocusHandler, - ): - WebEventSequence(testScript).run([event]) - - self.assertEqual(presentations, [context]) - self.assertEqual( - setFocus.call_args_list, - [mock.call(event, context, False), mock.call(event, context)], - ) - testScript.utilities.setCaretContext.assert_has_calls( - [mock.call(context, 6), mock.call(context, 6)] - if pageNavigation - else [mock.call(context, 6)] - ) - defaultFocusHandler.assert_not_called() - - def test_page_navigation_focus_uses_recovered_caret_context_once(self) -> None: - self._assert_document_focus_uses_recovered_context_once( - pageNavigation=True, - documentFragment="", - ) - - def test_page_fragment_focus_uses_recovered_caret_context_once(self) -> None: - self._assert_document_focus_uses_recovered_context_once( - pageNavigation=False, - documentFragment="#details", - ) - - -class ChromiumNativeContainerSequenceTests(unittest.TestCase): - """Current routing contracts for native containers in Chromium content.""" - - @staticmethod - def _make_script(document: object, caretContext: object) -> chromium_script.Script: - testScript = chromium_script.Script.__new__(chromium_script.Script) - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript._browseModeIsSticky = False - testScript.utilities = mock.Mock() - testScript.utilities.isDocument.return_value = False - testScript.utilities.isZombie.return_value = False - testScript.utilities.getDocumentForObject.return_value = document - testScript.utilities.isWebAppDescendant.return_value = False - testScript.utilities.handleEventFromContextReplicant.return_value = False - testScript.utilities.getCaretContext.return_value = (caretContext, 0) - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.eventIsBrowserUIAutocompleteNoise.return_value = False - testScript.utilities.eventIsBrowserUIPageSwitch.return_value = False - testScript.utilities.eventIsFromLocusOfFocusDocument.return_value = True - testScript.utilities.eventIsIrrelevantSelectionChangedEvent.return_value = False - testScript.utilities.commonAncestor.return_value = None - return testScript - - def _run_container_sequence( - self, - events: list[FakeEvent], - expectedOwner: str, - ) -> None: - document = object() - oldFocus = object() - testScript = self._make_script(document, oldFocus) - presentations: list[tuple[str, FakeAccessible]] = [] - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", oldFocus), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_focusable", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_focused", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_document", return_value=False), - mock.patch.object( - default.Script, - "onActiveDescendantChanged", - side_effect=lambda _script, event: presentations.append( - ("active-descendant", event.any_data) - ), - ) as defaultActiveDescendantHandler, - mock.patch.object( - default.Script, - "onSelectionChanged", - side_effect=lambda _script, event: presentations.append( - ("selection", event.source) - ), - ) as defaultSelectionHandler, - mock.patch.object( - default.Script, - "onFocusedChanged", - side_effect=lambda _script, event: presentations.append(("focus", event.source)), - ) as defaultFocusHandler, - ): - WebEventSequence(testScript).run(events) - - self.assertEqual(presentations, [(expectedOwner, events[-1].source)]) - defaultActiveDescendantHandler.assert_not_called() - if expectedOwner == "selection": - defaultSelectionHandler.assert_called_once_with(testScript, events[-1]) - defaultFocusHandler.assert_not_called() - else: - defaultSelectionHandler.assert_not_called() - defaultFocusHandler.assert_called_once_with(testScript, events[-1]) - - def test_combo_box_active_descendant_then_focus_uses_focus_owner(self) -> None: - comboBox = FakeAccessible(Atspi.Role.COMBO_BOX) - option = FakeAccessible(Atspi.Role.LIST_ITEM) - events = [ - FakeEvent("object:active-descendant-changed", comboBox, any_data=option), - FakeEvent("object:state-changed:focused", comboBox, detail1=1), - ] - - self._run_container_sequence(events, expectedOwner="focus") - - def test_listbox_active_descendant_then_selection_uses_selection_owner(self) -> None: - listBox = FakeAccessible(Atspi.Role.LIST_BOX) - option = FakeAccessible(Atspi.Role.LIST_ITEM) - events = [ - FakeEvent("object:active-descendant-changed", listBox, any_data=option), - FakeEvent("object:selection-changed", listBox), - ] - - self._run_container_sequence(events, expectedOwner="selection") - - def test_tree_active_descendant_then_focus_uses_focus_owner(self) -> None: - tree = FakeAccessible(Atspi.Role.TREE) - treeItem = FakeAccessible(Atspi.Role.TREE_ITEM) - events = [ - FakeEvent("object:active-descendant-changed", tree, any_data=treeItem), - FakeEvent("object:state-changed:focused", treeItem, detail1=1), - ] - - self._run_container_sequence(events, expectedOwner="focus") - - def test_grid_active_descendant_then_selection_uses_selection_owner(self) -> None: - grid = FakeAccessible(Atspi.Role.TABLE) - gridCell = FakeAccessible(Atspi.Role.TABLE_CELL) - events = [ - FakeEvent("object:active-descendant-changed", grid, any_data=gridCell), - FakeEvent("object:selection-changed", grid), - ] - - self._run_container_sequence(events, expectedOwner="selection") - - def test_dialog_focus_loss_then_gain_uses_shared_focus_owner(self) -> None: - document = object() - oldFocus = object() - dialog = FakeAccessible(Atspi.Role.DIALOG) - testScript = self._make_script(document, oldFocus) - events = [ - FakeEvent("object:state-changed:focused", dialog, detail1=0), - FakeEvent("object:state-changed:focused", dialog, detail1=1), - ] - presentations: list[FakeAccessible] = [] - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", oldFocus), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - mock.patch.object( - web_script.AXUtilities, - "is_dialog_or_alert", - side_effect=lambda obj: obj is dialog, - ), - mock.patch( - "cthulhu.scripts.web.script.cthulhu.setLocusOfFocus", - side_effect=lambda _event, obj: presentations.append(obj), - ) as setLocusOfFocus, - mock.patch.object(default.Script, "onFocusedChanged") as defaultFocusHandler, - ): - WebEventSequence(testScript).run(events) - - self.assertEqual(presentations, [dialog]) - setLocusOfFocus.assert_called_once_with(events[1], dialog) - defaultFocusHandler.assert_not_called() - - -class ChromiumImplementationDetailSequenceTests(unittest.TestCase): - """Routing contracts for Chromium-only accessibility-tree details.""" - - @staticmethod - def _make_script( - staticTextLeaf: FakeAccessible | None = None, - listItemMarker: FakeAccessible | None = None, - ) -> chromium_script.Script: - testScript = chromium_script.Script.__new__(chromium_script.Script) - testScript.utilities = mock.Mock() - testScript.utilities.isStaticTextLeaf.side_effect = ( - lambda obj: obj is staticTextLeaf - ) - testScript.utilities.isListItemMarker.side_effect = ( - lambda obj: obj is listItemMarker - ) - testScript.utilities.isRedundantAutocompleteEvent.return_value = False - return testScript - - def test_static_text_child_caret_then_parent_caret_uses_parent_owner(self) -> None: - staticText = FakeAccessible(Atspi.Role.STATIC) - parentText = FakeAccessible(Atspi.Role.PARAGRAPH) - testScript = self._make_script(staticTextLeaf=staticText) - events = [ - FakeEvent("object:text-caret-moved", staticText, detail1=0), - FakeEvent("object:text-caret-moved", parentText, detail1=0), - ] - presentations: list[FakeAccessible] = [] - - with ( - mock.patch.object(web_script.Script, "onCaretMoved", return_value=False) as webHandler, - mock.patch.object( - default.Script, - "onCaretMoved", - side_effect=lambda _script, event: presentations.append(event.source), - ) as defaultHandler, - ): - WebEventSequence(testScript).run(events) - - self.assertEqual(presentations, [parentText]) - webHandler.assert_called_once_with(events[1]) - defaultHandler.assert_called_once_with(testScript, events[1]) - - - def test_static_text_child_selection_then_parent_selection_uses_parent_owner(self) -> None: - staticText = FakeAccessible(Atspi.Role.STATIC) - parentText = FakeAccessible(Atspi.Role.PARAGRAPH) - testScript = self._make_script(staticTextLeaf=staticText) - events = [ - FakeEvent("object:text-selection-changed", staticText), - FakeEvent("object:text-selection-changed", parentText), - ] - - self._assert_text_selection_owner(testScript, events, parentText) - - def test_list_marker_selection_then_list_item_selection_uses_list_item_owner(self) -> None: - listMarker = FakeAccessible(Atspi.Role.STATIC) - listItem = FakeAccessible(Atspi.Role.LIST_ITEM) - testScript = self._make_script(listItemMarker=listMarker) - events = [ - FakeEvent("object:text-selection-changed", listMarker), - FakeEvent("object:text-selection-changed", listItem), - ] - - self._assert_text_selection_owner(testScript, events, listItem) - - def _assert_text_selection_owner( - self, - testScript: chromium_script.Script, - events: list[FakeEvent], - expectedOwner: FakeAccessible, - ) -> None: - presentations: list[FakeAccessible] = [] - - with ( - mock.patch.object( - web_script.Script, - "onTextSelectionChanged", - return_value=False, - ) as webHandler, - mock.patch.object( - default.Script, - "onTextSelectionChanged", - side_effect=lambda _script, event: presentations.append(event.source), - ) as defaultHandler, - ): - WebEventSequence(testScript).run(events) - - self.assertEqual(presentations, [expectedOwner]) - webHandler.assert_called_once_with(events[1]) - defaultHandler.assert_called_once_with(testScript, events[1]) - - -class ChromiumMutationRecoverySequenceTests(unittest.TestCase): - """Routing contracts for stale context replacement after child removal.""" - - @staticmethod - def _make_script(document: object, recoveredContext: FakeAccessible) -> chromium_script.Script: - testScript = chromium_script.Script.__new__(chromium_script.Script) - testScript._browseModeIsSticky = False - testScript._loadingDocumentContent = False - testScript.lastMouseRoutingTime = 0 - testScript.utilities = mock.Mock() - testScript.utilities.isStaticTextLeaf.return_value = False - testScript.utilities.eventIsBrowserUINoise.return_value = False - testScript.utilities.isLiveRegion.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = document - testScript.utilities.getDocumentForObject.return_value = document - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.isZombie.return_value = False - testScript.utilities.isWebAppDescendant.return_value = False - testScript.utilities.handleEventForRemovedChild.return_value = False - testScript.utilities.handleEventFromContextReplicant.side_effect = ( - lambda _event, candidate: candidate is recoveredContext - ) - return testScript - - def _assert_removed_context_then_replicant_recovers_once( - self, - recoveryEventType: str, - ) -> None: - document = object() - container = FakeAccessible(Atspi.Role.PANEL) - removedContext = FakeAccessible(Atspi.Role.PUSH_BUTTON) - recoveredContext = FakeAccessible(Atspi.Role.PUSH_BUTTON) - testScript = self._make_script(document, recoveredContext) - removalEvent = FakeEvent( - "object:children-changed:remove", - container, - detail1=0, - any_data=removedContext, - ) - if recoveryEventType == "object:children-changed:add": - recoveryEvent = FakeEvent( - recoveryEventType, - container, - detail1=0, - any_data=recoveredContext, - ) - else: - recoveryEvent = FakeEvent(recoveryEventType, recoveredContext, detail1=1) - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", removedContext), - mock.patch.object(web_script.AXObject, "clear_cache_now"), - mock.patch.object(web_script.AXObject, "is_dead", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_busy", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(default.Script, "onChildrenRemoved") as defaultRemovalHandler, - mock.patch.object(default.Script, "onChildrenAdded") as defaultAddedHandler, - mock.patch.object(default.Script, "onFocusedChanged") as defaultFocusHandler, - ): - WebEventSequence(testScript).run([removalEvent, recoveryEvent]) - - defaultRemovalHandler.assert_called_once_with(testScript, removalEvent) - testScript.utilities.handleEventForRemovedChild.assert_called_once_with(removalEvent) - testScript.utilities.handleEventFromContextReplicant.assert_called_once_with( - recoveryEvent, - recoveredContext, - ) - defaultAddedHandler.assert_not_called() - defaultFocusHandler.assert_not_called() - - def test_removed_context_then_added_replicant_uses_replicant_owner(self) -> None: - self._assert_removed_context_then_replicant_recovers_once( - "object:children-changed:add" - ) - - def test_removed_context_then_focused_replicant_uses_replicant_owner(self) -> None: - self._assert_removed_context_then_replicant_recovers_once( - "object:state-changed:focused" - ) - - -class StickyModeTransitionSequenceTests(unittest.TestCase): - """Ordered document-exit and re-entry contracts for sticky modes.""" - - @staticmethod - def _make_script( - document: object, - documentObjects: set[FakeAccessible], - inFocusMode: bool, - focusModeIsSticky: bool, - browseModeIsSticky: bool, - ) -> chromium_script.Script: - testScript = chromium_script.Script.__new__(chromium_script.Script) - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript._lastCommandWasMouseButton = False - testScript._madeFindAnnouncement = False - testScript._inFocusMode = inFocusMode - testScript._focusModeIsSticky = focusModeIsSticky - testScript._browseModeIsSticky = browseModeIsSticky - testScript._navSuspended = False - testScript.refreshKeyGrabs = mock.Mock() - testScript.presentMessage = mock.Mock() - testScript.utilities = mock.Mock() - testScript.utilities.isZombie.return_value = False - testScript.utilities.isDocument.return_value = False - testScript.utilities.getTopLevelDocumentForObject.side_effect = ( - lambda obj: document if obj in documentObjects else None - ) - testScript.utilities.getDocumentForObject.side_effect = ( - lambda obj: document if obj in documentObjects else None - ) - testScript.utilities.inDocumentContent.side_effect = ( - lambda obj: obj in documentObjects - ) - testScript.utilities.inFindContainer.return_value = False - testScript.utilities.queryNonEmptyText.return_value = None - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - testScript.utilities.isAnchor.return_value = False - testScript.utilities.lastInputEventWasPageNav.return_value = False - testScript.utilities.isFocusedWithMathChild.return_value = False - testScript.utilities.caretMovedToSamePageFragment.return_value = False - testScript.utilities.lastInputEventWasLineNav.return_value = False - testScript.utilities.shouldInterruptForLocusOfFocusChange.return_value = False - testScript.utilities.isWebAppDescendant.return_value = False - testScript.flatReviewPresenter = mock.Mock() - testScript.flatReviewPresenter.is_active.return_value = False - testScript.updateBraille = mock.Mock() - testScript.useFocusMode = mock.Mock(return_value=False) - testScript.speechGenerator = mock.Mock() - testScript.speechGenerator.generateSpeech.return_value = [] - testScript._saveFocusedObjectInfo = mock.Mock() - - def set_navigation_suspended(suspended: bool, _reason: str) -> None: - testScript._navSuspended = suspended - - testScript._setNavigationSuspended = mock.Mock( - side_effect=set_navigation_suspended - ) - return testScript - - @staticmethod - def _run_round_trip( - testScript: chromium_script.Script, - documentControl: FakeAccessible, - browserUI: FakeAccessible, - returnedControl: FakeAccessible, - ) -> list[tuple[bool, bool, bool, bool]]: - snapshots: list[tuple[bool, bool, bool, bool]] = [] - transitions = [ - (documentControl, browserUI), - (browserUI, returnedControl), - ] - for oldFocus, newFocus in transitions: - web_script.Script.locus_of_focus_changed( - testScript, - None, - oldFocus, - newFocus, - ) - snapshots.append( - ( - testScript._inFocusMode, - testScript._focusModeIsSticky, - testScript._browseModeIsSticky, - testScript._navSuspended, - ) - ) - return snapshots - - def test_sticky_focus_survives_document_exit_and_reentry(self) -> None: - document = object() - documentControl = FakeAccessible(Atspi.Role.ENTRY, editable=True) - browserUI = FakeAccessible(Atspi.Role.ENTRY, editable=True) - returnedControl = FakeAccessible(Atspi.Role.ENTRY, editable=True) - testScript = self._make_script( - document, - {documentControl, returnedControl}, - inFocusMode=True, - focusModeIsSticky=True, - browseModeIsSticky=False, - ) - - with ( - mock.patch.object(web_script.AXObject, "is_dead", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_unknown_or_redundant", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_heading", return_value=False), - mock.patch.object(web_script.speech, "speak"), - mock.patch.object(web_script.cthulhu, "emitRegionChanged"), - ): - snapshots = self._run_round_trip( - testScript, - documentControl, - browserUI, - returnedControl, - ) - - self.assertEqual( - snapshots, - [ - (True, True, False, True), - (True, True, False, False), - ], - ) - testScript._setNavigationSuspended.assert_has_calls( - [ - mock.call(True, "focus left document content"), - mock.call(False, "focus entered document content"), - ] - ) - - def test_sticky_browse_survives_round_trip_and_blocks_widget_focus(self) -> None: - document = object() - documentControl = FakeAccessible(Atspi.Role.PARAGRAPH) - browserUI = FakeAccessible(Atspi.Role.ENTRY, editable=True) - webAppWidget = FakeAccessible(Atspi.Role.PUSH_BUTTON) - testScript = self._make_script( - document, - {documentControl, webAppWidget}, - inFocusMode=False, - focusModeIsSticky=False, - browseModeIsSticky=True, - ) - testScript.utilities.isWebAppDescendant.side_effect = ( - lambda obj: obj is webAppWidget - ) - focusEvent = FakeEvent( - "object:state-changed:focused", - webAppWidget, - detail1=1, - ) - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", browserUI), - mock.patch.object(web_script.AXObject, "is_dead", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_unknown_or_redundant", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_heading", return_value=False), - mock.patch.object(web_script.speech, "speak"), - mock.patch.object(web_script.cthulhu, "emitRegionChanged"), - mock.patch.object(web_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - mock.patch.object(default.Script, "onFocusedChanged") as defaultFocusHandler, - ): - snapshots = self._run_round_trip( - testScript, - documentControl, - browserUI, - webAppWidget, - ) - WebEventSequence(testScript).run([focusEvent]) - - self.assertEqual( - snapshots, - [ - (False, False, True, True), - (False, False, True, False), - ], - ) - self.assertFalse(testScript._inFocusMode) - self.assertFalse(testScript._focusModeIsSticky) - self.assertTrue(testScript._browseModeIsSticky) - setLocusOfFocus.assert_not_called() - defaultFocusHandler.assert_not_called() - - -class DocumentAndBrowserUIRoundTripSequenceTests(unittest.TestCase): - """Lifecycle and browser-UI round-trip contracts for web document context.""" - - def test_script_deactivate_then_reactivate_restores_document_navigation(self) -> None: - testScript = chromium_script.Script.__new__(chromium_script.Script) - app = object() - document = object() - focus = FakeAccessible(Atspi.Role.PARAGRAPH) - testScript.app = app - testScript._sayAllContents = [object()] - testScript._inSayAll = True - testScript._sayAllIsInterrupted = True - testScript._loadingDocumentContent = True - testScript._madeFindAnnouncement = True - testScript._lastCommandWasCaretNav = True - testScript._lastCommandWasStructNav = True - testScript._lastCommandWasMouseButton = True - testScript._lastMouseButtonContext = (object(), 3) - testScript._lastMouseOverObject = object() - testScript._preMouseOverContext = (object(), 4) - testScript._inMouseOverObject = True - testScript.utilities = mock.Mock() - testScript.utilities.getDocumentForObject.return_value = document - testScript._setNavigationSuspended = mock.Mock() - testScript.removeKeyGrabs = mock.Mock() - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", focus), - mock.patch.object(web_script.AXObject, "is_dead", return_value=False), - mock.patch.object(web_script.AXObject, "get_application", return_value=app), - mock.patch.object(default.Script, "activate") as defaultActivate, - ): - web_script.Script.deactivate(testScript) - web_script.Script.activate(testScript) - - self.assertEqual(testScript._sayAllContents, []) - self.assertFalse(testScript._inSayAll) - self.assertFalse(testScript._sayAllIsInterrupted) - self.assertFalse(testScript._loadingDocumentContent) - self.assertFalse(testScript._madeFindAnnouncement) - self.assertFalse(testScript._lastCommandWasCaretNav) - self.assertFalse(testScript._lastCommandWasStructNav) - self.assertFalse(testScript._lastCommandWasMouseButton) - self.assertEqual(testScript._lastMouseButtonContext, (None, -1)) - self.assertIsNone(testScript._lastMouseOverObject) - self.assertEqual(testScript._preMouseOverContext, (None, -1)) - self.assertFalse(testScript._inMouseOverObject) - testScript.utilities.clearCachedObjects.assert_called_once_with() - testScript._setNavigationSuspended.assert_has_calls( - [ - mock.call(False, "script deactivation"), - mock.call(False, "activation-in-document"), - ] - ) - testScript.removeKeyGrabs.assert_called_once_with() - defaultActivate.assert_called_once_with() - - def test_address_bar_round_trip_has_one_owner_per_focus_and_recovers_context( - self, - ) -> None: - document = object() - pageControl = FakeAccessible(Atspi.Role.ENTRY, editable=True) - addressBar = FakeAccessible(Atspi.Role.ENTRY, editable=True) - returnedControl = FakeAccessible(Atspi.Role.ENTRY, editable=True) - testScript = StickyModeTransitionSequenceTests._make_script( - document, - {pageControl, returnedControl}, - inFocusMode=False, - focusModeIsSticky=False, - browseModeIsSticky=False, - ) - focusEvents = [ - FakeEvent("object:state-changed:focused", addressBar, detail1=1), - FakeEvent("object:state-changed:focused", returnedControl, detail1=1), - ] - presentations: list[FakeAccessible] = [] - - def present_and_move_focus( - _script: chromium_script.Script, - event: FakeEvent, - ) -> None: - oldFocus = cthulhu_state.locusOfFocus - presentations.append(event.source) - web_script.Script.locus_of_focus_changed( - testScript, - event, - oldFocus, - event.source, - ) - cthulhu_state.locusOfFocus = event.source - - with ( - mock.patch.object(cthulhu_state, "locusOfFocus", pageControl), - mock.patch.object(web_script.AXObject, "is_dead", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_editable", side_effect=lambda obj: obj.editable), - mock.patch.object(web_script.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_unknown_or_redundant", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_heading", return_value=False), - mock.patch.object(web_script.speech, "speak"), - mock.patch.object(web_script.cthulhu, "emitRegionChanged"), - mock.patch.object( - default.Script, - "onFocusedChanged", - side_effect=present_and_move_focus, - ) as defaultFocusHandler, - ): - WebEventSequence(testScript).run(focusEvents) - - self.assertEqual(presentations, [addressBar, returnedControl]) - self.assertEqual( - defaultFocusHandler.call_args_list, - [ - mock.call(testScript, focusEvents[0]), - mock.call(testScript, focusEvents[1]), - ], - ) - testScript._setNavigationSuspended.assert_has_calls( - [ - mock.call(True, "focus left document content"), - mock.call(False, "focus entered document content"), - ] - ) - self.assertFalse(testScript._navSuspended) - testScript.utilities.setCaretContext.assert_called_once_with( - returnedControl, - 0, - document, - ) - testScript.updateBraille.assert_called_once_with( - returnedControl, - documentFrame=document, - ) - - -class ChromiumDocumentLifecycleSequenceTests(unittest.TestCase): - """Routing contracts for transient and authoritative Chromium documents.""" - - @staticmethod - def _make_script( - transientDocument: FakeAccessible, - realDocument: FakeAccessible, - ) -> chromium_script.Script: - testScript = chromium_script.Script.__new__(chromium_script.Script) - testScript.utilities = mock.Mock() - testScript.utilities.hasNoSize.return_value = False - testScript.utilities.documentFrameURI.side_effect = ( - lambda obj: "" if obj is transientDocument else "https://example.test/" - ) - return testScript - - def _assert_real_document_owns_sequence( - self, - eventType: str, - webHandlerName: str, - defaultHandlerName: str, - detail1: int = 0, - ) -> None: - transientDocument = FakeAccessible(Atspi.Role.DOCUMENT_WEB) - realDocument = FakeAccessible(Atspi.Role.DOCUMENT_WEB) - testScript = self._make_script(transientDocument, realDocument) - events = [ - FakeEvent(eventType, transientDocument, detail1=detail1), - FakeEvent(eventType, realDocument, detail1=detail1), - ] - handledDocuments: list[FakeAccessible] = [] - - def handle_real_document(event: FakeEvent) -> bool: - handledDocuments.append(event.source) - return True - - with ( - mock.patch.object( - web_script.Script, - webHandlerName, - side_effect=handle_real_document, - ) as webHandler, - mock.patch.object(default.Script, defaultHandlerName) as defaultHandler, - ): - WebEventSequence(testScript).run(events) - - self.assertEqual(handledDocuments, [realDocument]) - webHandler.assert_called_once_with(events[1]) - defaultHandler.assert_not_called() - - def test_uri_less_busy_then_real_busy_uses_real_document_owner(self) -> None: - self._assert_real_document_owns_sequence( - "object:state-changed:busy", - "onBusyChanged", - "onBusyChanged", - detail1=1, - ) - - def test_uri_less_load_complete_then_real_load_complete_uses_real_document_owner( - self, - ) -> None: - self._assert_real_document_owns_sequence( - "document:load-complete", - "onDocumentLoadComplete", - "onDocumentLoadComplete", - ) - - def test_uri_less_reload_then_real_reload_uses_real_document_owner(self) -> None: - self._assert_real_document_owns_sequence( - "document:reload", - "onDocumentReload", - "onDocumentReload", - ) - - -class GeckoFocusAndFindSequenceTests(unittest.TestCase): - """Routing contracts for Gecko focus noise and find-result events.""" - - @staticmethod - def _make_script() -> gecko_script.Script: - testScript = gecko_script.Script.__new__(gecko_script.Script) - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript._lastCommandWasMouseButton = False - testScript._clearSyntheticWebSelection = mock.Mock() - testScript._saveFocusedObjectInfo = mock.Mock() - testScript.presentFindResults = mock.Mock() - testScript.utilities = mock.Mock() - testScript.utilities.isZombie.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = object() - testScript.utilities.getCaretContext.return_value = (object(), 0) - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False - testScript.utilities.lastInputEventWasCharNav.return_value = False - testScript.utilities.inFindContainer.return_value = True - return testScript - - def _assert_focus_noise_then_control_uses_control_owner( - self, - noiseRole: Atspi.Role, - ) -> None: - activeWindow = FakeAccessible(Atspi.Role.FRAME) - noise = FakeAccessible(noiseRole) - control = FakeAccessible(Atspi.Role.ENTRY, editable=True) - testScript = self._make_script() - events = [ - FakeEvent("object:state-changed:focused", noise, detail1=1), - FakeEvent("object:state-changed:focused", control, detail1=1), - ] - presentations: list[FakeAccessible] = [] - - with ( - mock.patch.object(cthulhu_state, "activeWindow", activeWindow), - mock.patch.object(cthulhu_state, "locusOfFocus", activeWindow), - mock.patch.object(web_script.Script, "onFocusedChanged", return_value=False) as webHandler, - mock.patch.object( - gecko_script.AXObject, - "get_role", - side_effect=lambda obj: obj.role, - ), - mock.patch.object( - default.Script, - "onFocusedChanged", - side_effect=lambda _script, event: presentations.append(event.source), - ) as defaultHandler, - ): - GeckoEventSequence(testScript).run(events) - - self.assertEqual(presentations, [control]) - self.assertEqual(webHandler.call_args_list, [mock.call(events[0]), mock.call(events[1])]) - defaultHandler.assert_called_once_with(testScript, events[1]) - - def test_panel_focus_noise_then_real_focus_uses_real_control_owner(self) -> None: - self._assert_focus_noise_then_control_uses_control_owner(Atspi.Role.PANEL) - - def test_frame_focus_noise_then_real_focus_uses_real_control_owner(self) -> None: - self._assert_focus_noise_then_control_uses_control_owner(Atspi.Role.FRAME) - - def test_find_entry_focus_then_result_caret_uses_find_presenter(self) -> None: - findEntry = FakeAccessible(Atspi.Role.ENTRY, editable=True) - resultText = FakeAccessible(Atspi.Role.PARAGRAPH) - testScript = self._make_script() - events = [ - FakeEvent("object:state-changed:focused", findEntry, detail1=1), - FakeEvent("object:text-caret-moved", resultText, detail1=7), - ] - focusPresentations: list[FakeAccessible] = [] - - with ( - mock.patch.object(cthulhu_state, "activeWindow", FakeAccessible(Atspi.Role.FRAME)), - mock.patch.object(cthulhu_state, "locusOfFocus", findEntry), - mock.patch.object(web_script.Script, "onFocusedChanged", return_value=False), - mock.patch.object( - gecko_script.AXObject, - "get_role", - side_effect=lambda obj: obj.role, - ), - mock.patch.object( - default.Script, - "onFocusedChanged", - side_effect=lambda _script, event: focusPresentations.append(event.source), - ) as defaultFocusHandler, - mock.patch.object(default.Script, "onCaretMoved") as defaultCaretHandler, - mock.patch.object(AXUtilitiesEvent, "get_text_event_reason", return_value=None), - ): - GeckoEventSequence(testScript).run(events) - - self.assertEqual(focusPresentations, [findEntry]) - defaultFocusHandler.assert_called_once_with(testScript, events[0]) - testScript.presentFindResults.assert_called_once_with(resultText, 7) - testScript._saveFocusedObjectInfo.assert_called_once_with(findEntry) - defaultCaretHandler.assert_not_called() - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_web_input_regressions.py b/tests/test_web_input_regressions.py deleted file mode 100644 index f196012..0000000 --- a/tests/test_web_input_regressions.py +++ /dev/null @@ -1,2610 +0,0 @@ -import os -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - -os.environ.setdefault("GSETTINGS_BACKEND", "memory") - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") -gi.require_version("Atspi", "2.0") - -from gi.repository import Atspi - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -soundGeneratorModule = sys.modules.get("cthulhu.sound_generator") -if soundGeneratorModule is not None and not hasattr(soundGeneratorModule, "SoundGenerator"): - class _StubSoundGenerator: - pass - - soundGeneratorModule.SoundGenerator = _StubSoundGenerator - -from cthulhu import messages -from cthulhu.ax_utilities_event import AXUtilitiesEvent, TextEventReason -from cthulhu.scripts.web import script as web_script -from cthulhu.scripts.web import script_utilities as web_script_utilities -from cthulhu.scripts.toolkits.Gecko import script_utilities as gecko_script_utilities - - -class WebKeyGrabRegressionTests(unittest.TestCase): - def _make_partial_script(self): - testScript = web_script.Script.__new__(web_script.Script) - testScript._lastCommandWasCaretNav = True - testScript._lastCommandWasStructNav = True - testScript._lastCommandWasMouseButton = True - testScript._lastMouseButtonContext = ("old", 7) - testScript._madeFindAnnouncement = True - testScript._inFocusMode = True - testScript._focusModeIsSticky = False - testScript._browseModeIsSticky = False - testScript._navSuspended = False - testScript.removeKeyGrabs = mock.Mock() - testScript.refreshKeyGrabs = mock.Mock() - testScript._setNavigationSuspended = mock.Mock() - testScript.presentMessage = mock.Mock() - testScript.utilities = mock.Mock() - testScript.utilities.isZombie.return_value = False - testScript.utilities.isDocument.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = None - testScript.utilities.inFindContainer.return_value = False - testScript.utilities.getCaretContext.return_value = (None, -1) - testScript.utilities.queryNonEmptyText.return_value = None - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - testScript.utilities.isAnchor.return_value = False - testScript.utilities.lastInputEventWasPageNav.return_value = False - testScript.utilities.isFocusedWithMathChild.return_value = False - testScript.utilities.caretMovedToSamePageFragment.return_value = False - testScript.utilities.lastInputEventWasLineNav.return_value = False - testScript.utilities.shouldInterruptForLocusOfFocusChange.return_value = False - testScript.flatReviewPresenter = mock.Mock() - testScript.flatReviewPresenter.is_active.return_value = False - testScript.updateBraille = mock.Mock() - testScript.speechGenerator = mock.Mock() - testScript.speechGenerator.generateSpeech.return_value = [] - testScript._saveFocusedObjectInfo = mock.Mock() - return testScript - - def test_window_deactivate_does_not_drop_key_grabs(self): - testScript = self._make_partial_script() - - result = web_script.Script.onWindowDeactivated(testScript, mock.Mock()) - - self.assertFalse(result) - self.assertFalse(testScript._lastCommandWasCaretNav) - self.assertFalse(testScript._lastCommandWasStructNav) - self.assertFalse(testScript._lastCommandWasMouseButton) - self.assertEqual(testScript._lastMouseButtonContext, (None, -1)) - testScript.removeKeyGrabs.assert_not_called() - - def test_non_document_focus_change_without_prior_document_does_not_refresh_grabs(self): - testScript = self._make_partial_script() - oldFocus = object() - newFocus = object() - - with mock.patch("cthulhu.scripts.web.script.AXObject.is_dead", return_value=False): - result = web_script.Script.locus_of_focus_changed(testScript, None, oldFocus, newFocus) - - self.assertFalse(result) - self.assertFalse(testScript._madeFindAnnouncement) - self.assertFalse(testScript._inFocusMode) - testScript._setNavigationSuspended.assert_called_once_with( - True, - "focus left document content", - ) - testScript.refreshKeyGrabs.assert_not_called() - - def test_non_document_focus_change_refreshes_grabs_after_leaving_document(self): - testScript = self._make_partial_script() - oldFocus = object() - newFocus = object() - oldDocument = object() - - testScript.utilities.getTopLevelDocumentForObject.side_effect = ( - lambda obj: oldDocument if obj is oldFocus else None - ) - - with mock.patch("cthulhu.scripts.web.script.AXObject.is_dead", return_value=False): - result = web_script.Script.locus_of_focus_changed(testScript, None, oldFocus, newFocus) - - self.assertFalse(result) - testScript.refreshKeyGrabs.assert_called_once_with() - - def test_non_document_focus_change_refreshes_grabs_when_old_focus_missing(self): - testScript = self._make_partial_script() - newFocus = object() - - with mock.patch("cthulhu.scripts.web.script.AXObject.is_dead", return_value=False): - result = web_script.Script.locus_of_focus_changed(testScript, None, None, newFocus) - - self.assertFalse(result) - testScript.refreshKeyGrabs.assert_called_once_with() - - def test_non_document_focus_preserves_sticky_focus_mode(self): - testScript = self._make_partial_script() - testScript._focusModeIsSticky = True - oldFocus = object() - newFocus = object() - - with mock.patch("cthulhu.scripts.web.script.AXObject.is_dead", return_value=False): - result = web_script.Script.locus_of_focus_changed(testScript, None, oldFocus, newFocus) - - self.assertFalse(result) - self.assertTrue(testScript._inFocusMode) - - def test_document_focus_restores_sticky_focus_after_suspension(self): - testScript = self._make_partial_script() - testScript._inFocusMode = False - testScript._focusModeIsSticky = True - testScript._navSuspended = True - oldFocus = object() - newFocus = object() - document = object() - testScript.utilities.getTopLevelDocumentForObject.side_effect = ( - lambda obj: document if obj is newFocus else None - ) - - with ( - mock.patch("cthulhu.scripts.web.script.AXObject.is_dead", return_value=False), - mock.patch("cthulhu.scripts.web.script.AXUtilities.is_unknown_or_redundant", return_value=False), - mock.patch("cthulhu.scripts.web.script.AXUtilities.is_heading", return_value=False), - mock.patch("cthulhu.scripts.web.script.speech.speak"), - mock.patch("cthulhu.scripts.web.script.cthulhu.emitRegionChanged"), - ): - result = web_script.Script.locus_of_focus_changed(testScript, None, oldFocus, newFocus) - - self.assertTrue(result) - self.assertTrue(testScript._inFocusMode) - testScript.presentMessage.assert_called_with(messages.MODE_FOCUS_IS_STICKY) - testScript.refreshKeyGrabs.assert_called_once_with() - - -class WebActiveWindowRegressionTests(unittest.TestCase): - def test_sanity_check_recovers_missing_script_app_from_active_window(self): - testScript = mock.Mock(app=None) - utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities) - utilities._script = testScript - activeWindow = object() - app = object() - - with ( - mock.patch.object(web_script_utilities.cthulhu_state, "activeWindow", activeWindow), - mock.patch.object(web_script_utilities.cthulhu_state, "locusOfFocus", None), - mock.patch.object( - web_script_utilities.AXObject, - "get_application", - side_effect=lambda obj: app if obj is activeWindow else None, - ), - mock.patch.object( - web_script_utilities.AXObject, - "get_parent", - side_effect=lambda obj: app if obj is activeWindow else None, - ), - mock.patch.object(web_script_utilities.cthulhu, "setActiveWindow") as setActiveWindow, - ): - result = web_script_utilities.Utilities.sanityCheckActiveWindow(utilities) - - self.assertTrue(result) - self.assertIs(testScript.app, app) - setActiveWindow.assert_not_called() - - def test_sanity_check_preserves_current_window_when_recovery_is_inconclusive(self): - oldApp = object() - testScript = mock.Mock(app=oldApp) - utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities) - utilities._script = testScript - activeWindow = object() - - with ( - mock.patch.object(web_script_utilities.cthulhu_state, "activeWindow", activeWindow), - mock.patch.object( - web_script_utilities.AXObject, - "get_parent", - return_value=object(), - ), - mock.patch.object(utilities, "activeWindow", return_value=None), - mock.patch.object(web_script_utilities.cthulhu, "setActiveWindow") as setActiveWindow, - ): - result = web_script_utilities.Utilities.sanityCheckActiveWindow(utilities) - - self.assertTrue(result) - self.assertIs(testScript.app, oldApp) - setActiveWindow.assert_not_called() - - -class WebPresentationModeSpeechRegressionTests(unittest.TestCase): - def _make_script(self, inFocusMode): - testScript = web_script.Script.__new__(web_script.Script) - testScript._inFocusMode = inFocusMode - testScript._focusModeIsSticky = True - testScript._browseModeIsSticky = True - testScript._loadingDocumentContent = False - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript.utilities = mock.Mock() - testScript.utilities.getCaretContext.return_value = ("button", 0) - testScript.utilities.grabFocusWhenSettingCaret.return_value = True - testScript.presentMessage = mock.Mock() - testScript.refreshKeyGrabs = mock.Mock() - testScript._shouldSuppressBrowseModeSound = mock.Mock(return_value=False) - return testScript - - def test_automatic_browse_mode_announcement_does_not_interrupt_focus_presentation(self): - testScript = self._make_script(inFocusMode=True) - soundManager = mock.Mock() - - with ( - mock.patch.object(web_script.AXObject, "get_parent", return_value=None), - mock.patch.object(web_script.AXUtilities, "is_list_box", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_menu", return_value=False), - mock.patch.object(web_script.sound_theme_manager, "getManager", return_value=soundManager), - ): - web_script.Script.togglePresentationMode(testScript, None, "document") - - testScript.presentMessage.assert_called_once_with(messages.MODE_BROWSE) - soundManager.playBrowseModeSound.assert_called_once_with() - self.assertFalse(testScript._inFocusMode) - self.assertFalse(testScript._focusModeIsSticky) - self.assertFalse(testScript._browseModeIsSticky) - testScript.refreshKeyGrabs.assert_called_once_with() - - def test_automatic_focus_mode_announcement_does_not_interrupt_focus_presentation(self): - testScript = self._make_script(inFocusMode=False) - soundManager = mock.Mock() - - with mock.patch.object( - web_script.sound_theme_manager, - "getManager", - return_value=soundManager, - ): - web_script.Script.togglePresentationMode(testScript, None, "document") - - testScript.presentMessage.assert_called_once_with(messages.MODE_FOCUS) - soundManager.playFocusModeSound.assert_called_once_with() - self.assertTrue(testScript._inFocusMode) - self.assertFalse(testScript._focusModeIsSticky) - self.assertFalse(testScript._browseModeIsSticky) - testScript.refreshKeyGrabs.assert_called_once_with() - - def test_manual_focus_mode_announcement_does_not_interrupt_after_keyboard_dispatch(self): - testScript = self._make_script(inFocusMode=False) - - with mock.patch.object(web_script.sound_theme_manager, "getManager", return_value=mock.Mock()): - web_script.Script.togglePresentationMode(testScript, object(), "document") - - testScript.presentMessage.assert_called_once_with(messages.MODE_FOCUS, interrupt=False) - - def test_manual_browse_mode_announcement_does_not_interrupt_after_keyboard_dispatch(self): - testScript = self._make_script(inFocusMode=True) - - with ( - mock.patch.object(web_script.AXObject, "get_parent", return_value=None), - mock.patch.object(web_script.AXUtilities, "is_list_box", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_menu", return_value=False), - mock.patch.object(web_script.sound_theme_manager, "getManager", return_value=mock.Mock()), - ): - web_script.Script.togglePresentationMode(testScript, object(), "document") - - testScript.presentMessage.assert_called_once_with(messages.MODE_BROWSE, interrupt=False) - - def test_non_keyboard_mode_announcement_keeps_interrupt_request(self): - testScript = self._make_script(inFocusMode=False) - - result = web_script.Script.should_interrupt_for_mode_announcement(testScript, True) - - self.assertTrue(result) - - -class WebObjectPresentationInterruptionRegressionTests(unittest.TestCase): - @staticmethod - def _make_script(): - testScript = web_script.Script.__new__(web_script.Script) - testScript._lastCommandWasCaretNav = False - testScript._loadingDocumentContent = False - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.getTable.return_value = None - testScript.utilities.get_objectContentsAtOffset.return_value = ["target"] - testScript.displayContents = mock.Mock() - testScript.speakContents = mock.Mock() - return testScript - - def test_keyboard_owned_object_presentation_does_not_interrupt_again(self): - testScript = self._make_script() - target = object() - - with ( - mock.patch.object(web_script.AXUtilities, "is_document", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_status_bar", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_entry", return_value=False), - ): - web_script.Script.presentObject( - testScript, - target, - interrupt=True, - interrupt_already_handled=True, - ) - - testScript.speakContents.assert_called_once_with(["target"], interrupt=False) - - def test_non_keyboard_object_presentation_still_interrupts(self): - testScript = self._make_script() - target = object() - - with ( - mock.patch.object(web_script.AXUtilities, "is_document", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_status_bar", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_entry", return_value=False), - ): - web_script.Script.presentObject(testScript, target, interrupt=True) - - testScript.speakContents.assert_called_once_with(["target"], interrupt=True) - - def test_web_alert_keeps_non_keyboard_interrupt_request(self): - testScript = self._make_script() - testScript._lastCommandWasStructNav = False - testScript._lastMouseButtonContext = (None, -1) - testScript.lastMouseRoutingTime = 0 - testScript.utilities.eventIsBrowserUINoise.return_value = False - testScript.utilities.isLiveRegion.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = "document" - testScript.utilities.isZombie.return_value = False - testScript.utilities.handleEventFromContextReplicant.return_value = False - testScript.utilities.lastQueuedLiveRegion.return_value = None - testScript.presentObject = mock.Mock() - alert = object() - event = mock.Mock(source=object(), any_data=alert) - - with ( - mock.patch.object(web_script.AXObject, "clear_cache_now"), - mock.patch.object(web_script.AXUtilities, "is_busy", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_alert", return_value=True), - mock.patch.object(web_script.AXUtilities, "get_focused_object", return_value=None), - ): - result = web_script.Script.onChildrenAdded(testScript, event) - - self.assertTrue(result) - testScript.presentObject.assert_called_once_with(alert, interrupt=True) - - -class WebFocusSpeechInterruptionRegressionTests(unittest.TestCase): - def _make_script(self): - testScript = web_script.Script.__new__(web_script.Script) - testScript._navSuspended = False - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript._lastCommandWasMouseButton = False - testScript._inFocusMode = True - testScript._focusModeIsSticky = True - testScript._browseModeIsSticky = False - testScript.flatReviewPresenter = mock.Mock() - testScript.flatReviewPresenter.is_active.return_value = False - testScript.utilities = mock.Mock() - testScript.utilities.isZombie.return_value = False - testScript.utilities.isDocument.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = "document" - testScript.utilities.inFindContainer.return_value = False - testScript.utilities.queryNonEmptyText.return_value = None - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - testScript.utilities.isAnchor.return_value = False - testScript.utilities.lastInputEventWasPageNav.return_value = False - testScript.utilities.isFocusedWithMathChild.return_value = False - testScript.utilities.caretMovedToSamePageFragment.return_value = False - testScript.utilities.lastInputEventWasLineNav.return_value = False - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.shouldInterruptForLocusOfFocusChange.return_value = True - testScript.speechGenerator = mock.Mock() - testScript.speechGenerator.generateSpeech.return_value = ["focus speech"] - testScript.updateBraille = mock.Mock() - testScript.presentationInterrupt = mock.Mock() - testScript._saveFocusedObjectInfo = mock.Mock() - return testScript - - def test_focus_generated_speech_uses_explicit_interrupt_then_appends(self): - testScript = self._make_script() - oldFocus = object() - newFocus = object() - event = mock.Mock(type="object:state-changed:focused", source=newFocus) - - with ( - mock.patch.object(web_script.AXObject, "is_dead", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_unknown_or_redundant", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_heading", return_value=False), - mock.patch.object(web_script.speech, "speak") as speak, - mock.patch.object(web_script.cthulhu, "emitRegionChanged"), - ): - result = web_script.Script.locus_of_focus_changed( - testScript, event, oldFocus, newFocus - ) - - self.assertTrue(result) - testScript.presentationInterrupt.assert_called_once_with() - speak.assert_called_once_with(["focus speech"], interrupt=False) - - def test_focus_generated_speech_appends_when_interruption_is_not_needed(self): - testScript = self._make_script() - testScript.utilities.shouldInterruptForLocusOfFocusChange.return_value = False - oldFocus = object() - newFocus = object() - event = mock.Mock(type="object:state-changed:focused", source=newFocus) - - with ( - mock.patch.object(web_script.AXObject, "is_dead", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_unknown_or_redundant", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_heading", return_value=False), - mock.patch.object(web_script.speech, "speak") as speak, - mock.patch.object(web_script.cthulhu, "emitRegionChanged"), - ): - result = web_script.Script.locus_of_focus_changed( - testScript, event, oldFocus, newFocus - ) - - self.assertTrue(result) - testScript.presentationInterrupt.assert_not_called() - speak.assert_called_once_with(["focus speech"], interrupt=False) - - -class WebCaretMovedRegressionTests(unittest.TestCase): - def _make_script(self): - testScript = web_script.Script.__new__(web_script.Script) - testScript._inFocusMode = False - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript._lastCommandWasMouseButton = False - testScript._clearSyntheticWebSelection = mock.Mock() - testScript.utilities = mock.Mock() - testScript.utilities.isZombie.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = "document" - testScript.utilities.getCaretContext.return_value = ("source", 4) - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False - testScript.utilities.lastInputEventWasCharNav.return_value = True - testScript.utilities.inFindContainer.return_value = False - testScript.utilities.eventIsFromLocusOfFocusDocument.return_value = True - testScript.utilities.isItemForEditableComboBox.return_value = False - testScript.utilities.lastInputEventWasLineBoundaryNav.return_value = False - testScript.utilities.eventIsAutocompleteNoise.return_value = False - testScript.utilities.caretMovedOutsideActiveGrid.return_value = False - testScript.utilities.treatEventAsSpinnerValueChange.return_value = False - testScript._saveLastCursorPosition = mock.Mock() - return testScript - - def test_typing_reasons_update_cursor_for_editable_focus(self): - for reason in (TextEventReason.TYPING, TextEventReason.TYPING_ECHOABLE): - with self.subTest(reason=reason): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-caret-moved", source=source, detail1=5) - testScript.utilities.lastInputEventWasCharNav.return_value = False - testScript.utilities.textEventIsDueToInsertion.return_value = False - testScript.utilities.textEventIsDueToDeletion.return_value = False - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=reason, - ), - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onCaretMoved(testScript, event) - - self.assertTrue(result) - testScript._saveLastCursorPosition.assert_called_once_with(source, 5) - testScript.utilities.textEventIsDueToInsertion.assert_not_called() - testScript.utilities.textEventIsDueToDeletion.assert_not_called() - testScript.utilities.isItemForEditableComboBox.assert_not_called() - - def test_typing_reason_from_non_focus_source_continues(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-caret-moved", source=source, detail1=5) - testScript.utilities.lastInputEventWasCharNav.return_value = False - testScript.utilities.textEventIsDueToInsertion.return_value = True - testScript.utilities.isItemForEditableComboBox.return_value = True - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.TYPING, - ), - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onCaretMoved(testScript, event) - - self.assertTrue(result) - testScript._saveLastCursorPosition.assert_not_called() - testScript.utilities.textEventIsDueToInsertion.assert_not_called() - testScript.utilities.textEventIsDueToDeletion.assert_not_called() - testScript.utilities.isItemForEditableComboBox.assert_called_once() - - def test_deletion_reasons_update_cursor_for_editable_source(self): - for reason in (TextEventReason.BACKSPACE, TextEventReason.DELETE): - with self.subTest(reason=reason): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-caret-moved", source=source, detail1=3) - testScript.utilities.lastInputEventWasCharNav.return_value = False - testScript.utilities.textEventIsDueToInsertion.return_value = False - testScript.utilities.textEventIsDueToDeletion.return_value = False - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=reason, - ), - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onCaretMoved(testScript, event) - - self.assertTrue(result) - testScript._saveLastCursorPosition.assert_called_once_with(source, 3) - testScript.utilities.textEventIsDueToInsertion.assert_not_called() - testScript.utilities.textEventIsDueToDeletion.assert_not_called() - testScript.utilities.isItemForEditableComboBox.assert_not_called() - - def test_deletion_reason_from_embedded_contenteditable_source_continues(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-caret-moved", source=source, detail1=3) - testScript.utilities.lastInputEventWasCharNav.return_value = False - testScript.utilities.textEventIsDueToInsertion.return_value = False - testScript.utilities.textEventIsDueToDeletion.return_value = True - testScript.utilities.isItemForEditableComboBox.return_value = True - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.DELETE, - ), - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - ): - result = web_script.Script.onCaretMoved(testScript, event) - - self.assertTrue(result) - testScript._saveLastCursorPosition.assert_not_called() - testScript.utilities.textEventIsDueToInsertion.assert_not_called() - testScript.utilities.textEventIsDueToDeletion.assert_not_called() - testScript.utilities.isItemForEditableComboBox.assert_called_once() - - def test_matching_char_nav_caret_event_is_consumed_without_duplicate_presentation(self): - testScript = self._make_script() - source = "source" - event = mock.Mock(type="object:text-caret-moved", source=source, detail1=4) - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.NAVIGATION_BY_CHARACTER, - ), - mock.patch.object(web_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - result = web_script.Script.onCaretMoved(testScript, event) - - self.assertTrue(result) - testScript.utilities.setCaretContext.assert_not_called() - setLocusOfFocus.assert_not_called() - - def test_focus_change_caret_event_does_not_replace_real_focus_event(self): - testScript = self._make_script() - source = object() - event = mock.Mock( - type="object:text-caret-moved", - source=source, - detail1=0, - ) - testScript.utilities.getCaretContext.return_value = ("old-focus", 0) - testScript.utilities.lastInputEventWasCharNav.return_value = False - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.FOCUS_CHANGE, - ) as getReason, - mock.patch.object(web_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - result = web_script.Script.onCaretMoved(testScript, event) - - self.assertTrue(result) - getReason.assert_called_once_with(event) - testScript.utilities.setCaretContext.assert_not_called() - setLocusOfFocus.assert_not_called() - - -class WebMultilineEditorLinePresentationRegressionTests(unittest.TestCase): - def test_native_multiline_editor_uses_visual_web_line(self): - testScript = web_script.Script.__new__(web_script.Script) - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript.pointOfReference = {} - testScript.utilities = mock.Mock() - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.getTopLevelDocumentForObject.return_value = "document" - testScript.utilities.getPriorContext.return_value = ("prior", 20) - testScript.utilities.getCaretContext.return_value = ("editor", 42) - visualLine = [["editor", 40, 55, "wrapped line"]] - testScript.utilities.getLineContentsAtOffset.return_value = visualLine - testScript.speakContents = mock.Mock() - - with ( - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_multi_line", return_value=True), - mock.patch.object(web_script.default.Script, "sayLine") as defaultSayLine, - ): - web_script.Script.sayLine(testScript, "editor") - - defaultSayLine.assert_not_called() - testScript.utilities.getLineContentsAtOffset.assert_called_once_with( - "editor", - 42, - useCache=True, - ) - testScript.speakContents.assert_called_once_with( - visualLine, - priorObj="prior", - alreadyFocused=True, - ) - - def test_native_multiline_editor_is_visual_line_boundary(self): - editor = object() - utilities = web_script_utilities.Utilities.__new__( - web_script_utilities.Utilities - ) - utilities.isContentEditableWithEmbeddedObjects = mock.Mock(return_value=False) - utilities.inDocumentContent = mock.Mock(return_value=True) - - with ( - mock.patch.object(web_script_utilities.AXUtilities, "is_editable", return_value=True), - mock.patch.object(web_script_utilities.AXUtilities, "is_multi_line", return_value=True), - mock.patch.object(web_script_utilities.AXObject, "find_ancestor") as findAncestor, - ): - boundary = utilities._getEditableLineBoundary(editor) - - self.assertIs(boundary, editor) - findAncestor.assert_not_called() - - -class TextEventReasonRegressionTests(unittest.TestCase): - @staticmethod - def _make_input_manager(): - manager = mock.Mock() - methods = ( - "last_event_was_page_switch", - "last_event_was_backspace", - "last_event_was_delete", - "last_event_was_cut", - "last_event_was_paste", - "last_event_was_undo", - "last_event_was_redo", - "last_event_was_command", - "last_event_was_space", - "last_event_was_tab", - "last_event_was_return", - "last_event_was_printable_key", - "last_event_was_middle_click", - "last_event_was_middle_release", - "last_event_was_up_or_down", - "last_event_was_page_up_or_page_down", - "last_event_was_caret_selection", - "last_event_was_caret_navigation", - "last_event_was_line_navigation", - "last_event_was_word_navigation", - "last_event_was_character_navigation", - "last_event_was_page_navigation", - "last_event_was_line_boundary_navigation", - "last_event_was_file_boundary_navigation", - "last_event_was_select_all", - "last_event_was_primary_click_or_release", - ) - for method in methods: - getattr(manager, method).return_value = False - return manager - - def _classify_selection( - self, - event, - manager, - *, - focus=None, - focusIsSearch=False, - isEditable=False, - spinAncestor=None, - ): - with ( - mock.patch("cthulhu.input_event_manager.get_manager", return_value=manager), - mock.patch( - "cthulhu.ax_utilities_event.focus_manager.get_manager" - ) as getFocusManager, - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_text_input_search", - return_value=focusIsSearch, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesState.is_editable", - return_value=isEditable, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_terminal", - return_value=False, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_spin_button", - return_value=False, - ), - mock.patch.object( - web_script.AXObject, - "find_ancestor", - return_value=spinAncestor, - ), - ): - getFocusManager.return_value.get_locus_of_focus.return_value = ( - event.source if focus is None else focus - ) - return AXUtilitiesEvent._get_text_selection_changed_event_reason(event) - - def _classify_insertion( - self, - event, - manager, - *, - role=Atspi.Role.ENTRY, - isLiveRegion=False, - isEditable=False, - spinAncestor=None, - ): - with ( - mock.patch("cthulhu.input_event_manager.get_manager", return_value=manager), - mock.patch.object( - web_script.AXObject, - "get_role", - return_value=role, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_live_region", - return_value=isLiveRegion, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesState.is_editable", - return_value=isEditable, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_terminal", - return_value=False, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_spin_button", - return_value=False, - ), - mock.patch.object( - web_script.AXObject, - "find_ancestor", - return_value=spinAncestor, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXText.get_selected_text", - return_value=("", 0, 0), - ), - ): - return AXUtilitiesEvent._get_text_insertion_event_reason(event) - - def _classify_deletion( - self, - event, - manager, - *, - role=Atspi.Role.ENTRY, - isLiveRegion=False, - isEditable=False, - spinAncestor=None, - selectedText="", - ): - with ( - mock.patch("cthulhu.input_event_manager.get_manager", return_value=manager), - mock.patch.object( - web_script.AXObject, - "get_role", - return_value=role, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_live_region", - return_value=isLiveRegion, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesState.is_editable", - return_value=isEditable, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_terminal", - return_value=False, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_spin_button", - return_value=False, - ), - mock.patch.object( - web_script.AXObject, - "find_ancestor", - return_value=spinAncestor, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXText.get_cached_selected_text", - return_value=(selectedText, 0, len(selectedText)), - ), - ): - return AXUtilitiesEvent._get_text_deletion_event_reason(event) - - def test_insertion_classifier_covers_initial_handler_reasons(self): - cases = ( - ("ui update", TextEventReason.UI_UPDATE, {"role": Atspi.Role.LABEL}, {}), - ( - "live region", - TextEventReason.LIVE_REGION_UPDATE, - {"isLiveRegion": True}, - {}, - ), - ( - "page switch", - TextEventReason.PAGE_SWITCH, - {}, - {"last_event_was_page_switch": True}, - ), - ( - "children change", - TextEventReason.CHILDREN_CHANGE, - {}, - {}, - ), - ( - "spin button", - TextEventReason.SPIN_BUTTON_VALUE_CHANGE, - {"isEditable": True, "spinAncestor": object()}, - {"last_event_was_up_or_down": True}, - ), - ( - "automatic insertion", - TextEventReason.AUTO_INSERTION_PRESENTABLE, - {"isEditable": True}, - {"last_event_was_up_or_down": True}, - ), - ) - - for name, expected, classifierKwargs, managerResults in cases: - with self.subTest(name=name): - manager = self._make_input_manager() - for method, result in managerResults.items(): - getattr(manager, method).return_value = result - anyData = "\ufffc" if expected == TextEventReason.CHILDREN_CHANGE else "x" - event = mock.Mock( - type="object:text-changed:insert", - source=object(), - any_data=anyData, - ) - - reason = self._classify_insertion( - event, - manager, - **classifierKwargs, - ) - - self.assertEqual(reason, expected) - - def test_deletion_classifier_covers_initial_handler_reasons(self): - cases = ( - ("ui update", TextEventReason.UI_UPDATE, {"role": Atspi.Role.LABEL}, {}), - ( - "live region", - TextEventReason.LIVE_REGION_UPDATE, - {"isLiveRegion": True}, - {}, - ), - ( - "page switch", - TextEventReason.PAGE_SWITCH, - {}, - {"last_event_was_page_switch": True}, - ), - ( - "backspace", - TextEventReason.BACKSPACE, - {"isEditable": True}, - {"last_event_was_backspace": True}, - ), - ( - "delete", - TextEventReason.DELETE, - {"isEditable": True}, - {"last_event_was_delete": True}, - ), - ( - "typing", - TextEventReason.TYPING, - {"isEditable": True}, - {"last_event_was_printable_key": True}, - ), - ( - "spin button", - TextEventReason.SPIN_BUTTON_VALUE_CHANGE, - {"isEditable": True, "spinAncestor": object()}, - {"last_event_was_up_or_down": True}, - ), - ( - "automatic deletion", - TextEventReason.AUTO_DELETION, - {"isEditable": True}, - {"last_event_was_up_or_down": True}, - ), - ( - "selected text", - TextEventReason.SELECTED_TEXT_DELETION, - {"isEditable": True, "selectedText": "selected"}, - {}, - ), - ( - "children change", - TextEventReason.CHILDREN_CHANGE, - {}, - {}, - ), - ) - - for name, expected, classifierKwargs, managerResults in cases: - with self.subTest(name=name): - manager = self._make_input_manager() - for method, result in managerResults.items(): - getattr(manager, method).return_value = result - if expected == TextEventReason.CHILDREN_CHANGE: - anyData = "\ufffc" - elif expected == TextEventReason.SELECTED_TEXT_DELETION: - anyData = "selected" - else: - anyData = "x" - event = mock.Mock( - type="object:text-changed:delete", - source=object(), - any_data=anyData, - ) - - reason = self._classify_deletion( - event, - manager, - **classifierKwargs, - ) - - self.assertEqual(reason, expected) - - def test_selection_classifier_covers_handler_reason_families(self): - source = object() - cases = ( - ( - "search presentable", - TextEventReason.SEARCH_PRESENTABLE, - {"focus": object(), "focusIsSearch": True}, - {}, - ), - ( - "search unpresentable", - TextEventReason.SEARCH_UNPRESENTABLE, - {"focus": object(), "focusIsSearch": True}, - {"last_event_was_backspace": True}, - ), - ( - "selection by word", - TextEventReason.SELECTION_BY_WORD, - {}, - { - "last_event_was_caret_selection": True, - "last_event_was_word_navigation": True, - }, - ), - ( - "unspecified selection", - TextEventReason.UNSPECIFIED_SELECTION, - {}, - {"last_event_was_caret_selection": True}, - ), - ( - "navigation by character", - TextEventReason.NAVIGATION_BY_CHARACTER, - {}, - { - "last_event_was_caret_navigation": True, - "last_event_was_character_navigation": True, - }, - ), - ( - "select all", - TextEventReason.SELECT_ALL, - {}, - {"last_event_was_select_all": True}, - ), - ( - "primary mouse", - TextEventReason.MOUSE_PRIMARY_BUTTON, - {}, - {"last_event_was_primary_click_or_release": True}, - ), - ( - "typing", - TextEventReason.TYPING, - {"isEditable": True}, - {"last_event_was_printable_key": True}, - ), - ( - "editing command", - TextEventReason.PASTE, - {"isEditable": True}, - {"last_event_was_paste": True}, - ), - ( - "spin button", - TextEventReason.SPIN_BUTTON_VALUE_CHANGE, - {"isEditable": True, "spinAncestor": object()}, - {"last_event_was_up_or_down": True}, - ), - ) - - for name, expected, classifierKwargs, managerResults in cases: - with self.subTest(name=name): - manager = self._make_input_manager() - for method, result in managerResults.items(): - getattr(manager, method).return_value = result - event = mock.Mock(type="object:text-selection-changed", source=source) - - reason = self._classify_selection( - event, - manager, - **classifierKwargs, - ) - - self.assertEqual(reason, expected) - - def test_tab_is_classified_as_focus_change_before_editable_state(self): - oldFocus = object() - source = object() - event = mock.Mock(type="object:text-caret-moved", source=source) - inputManager = mock.Mock() - inputManager.last_event_was_caret_selection.return_value = False - inputManager.last_event_was_caret_navigation.return_value = False - inputManager.last_event_was_select_all.return_value = False - inputManager.last_event_was_primary_click_or_release.return_value = False - inputManager.last_event_was_tab_navigation.return_value = True - - with ( - mock.patch( - "cthulhu.input_event_manager.get_manager", - return_value=inputManager, - ), - mock.patch( - "cthulhu.ax_utilities_event.focus_manager.get_manager" - ) as getFocusManager, - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesRole.is_text_input_search", - return_value=False, - ), - mock.patch( - "cthulhu.ax_utilities_event.AXUtilitiesState.is_editable", - return_value=True, - ) as isEditable, - ): - getFocusManager.return_value.get_active_mode_and_object_of_interest.return_value = ( - None, - oldFocus, - ) - reason = AXUtilitiesEvent._get_caret_moved_event_reason(event) - - self.assertEqual(reason, TextEventReason.FOCUS_CHANGE) - isEditable.assert_not_called() - - -class WebTextInsertedReasonRegressionTests(unittest.TestCase): - @staticmethod - def _make_script(): - testScript = web_script.Script.__new__(web_script.Script) - testScript.utilities = mock.Mock() - testScript.utilities.isZombie.return_value = False - testScript.utilities.lastInputEventWasPageSwitch.return_value = False - testScript.utilities.handleAsLiveRegion.return_value = False - testScript.utilities.isLiveRegion.return_value = False - testScript.utilities.eventIsEOCAdded.return_value = False - testScript.utilities.eventIsBrowserUINoise.return_value = False - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.eventIsSpinnerNoise.return_value = False - testScript.utilities.eventIsAutocompleteNoise.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = "document" - testScript.utilities.queryNonEmptyText.return_value = "text" - testScript.utilities.isClickableElement.return_value = False - testScript.liveRegionManager = mock.Mock() - testScript.structuralNavigation = mock.Mock() - return testScript - - def test_page_switch_reason_owns_insertion(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="x") - testScript.utilities.eventIsAutocompleteNoise.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.PAGE_SWITCH, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.utilities.lastInputEventWasPageSwitch.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_page_switch_fallback_precedes_overlapping_live_region_reason(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="x") - testScript.utilities.lastInputEventWasPageSwitch.return_value = True - testScript.utilities.handleAsLiveRegion.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.LIVE_REGION_UPDATE, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.utilities.lastInputEventWasPageSwitch.assert_called_once() - testScript.utilities.handleAsLiveRegion.assert_not_called() - testScript.liveRegionManager.handleEvent.assert_not_called() - - def test_live_region_reason_selects_live_region_owner(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="x") - testScript.utilities.handleAsLiveRegion.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.LIVE_REGION_UPDATE, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.liveRegionManager.handleEvent.assert_called_once_with(event) - testScript.utilities.isLiveRegion.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_unpresented_live_region_reason_is_consumed(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="x") - testScript.utilities.isLiveRegion.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.LIVE_REGION_UPDATE, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.liveRegionManager.handleEvent.assert_not_called() - testScript.utilities.isLiveRegion.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_unknown_reason_uses_legacy_live_region_fallback(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="x") - testScript.utilities.handleAsLiveRegion.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.UNKNOWN, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.liveRegionManager.handleEvent.assert_called_once_with(event) - - def test_children_change_reason_owns_insertion(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="\ufffc") - testScript.utilities.eventIsAutocompleteNoise.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.CHILDREN_CHANGE, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsEOCAdded.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_unknown_reason_uses_legacy_embedded_object_fallback(self): - testScript = self._make_script() - event = mock.Mock( - type="object:text-changed:insert", - source=object(), - any_data=" \ufffc", - ) - testScript.utilities.eventIsEOCAdded.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.UNKNOWN, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsEOCAdded.assert_called_once_with(event) - testScript.utilities.clearContentCache.assert_not_called() - - def test_ui_update_reason_owns_insertion_outside_document(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="x") - testScript.utilities.inDocumentContent.return_value = False - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.UI_UPDATE, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsBrowserUINoise.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_spin_button_reason_owns_insertion(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="1") - testScript.utilities.eventIsAutocompleteNoise.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.SPIN_BUTTON_VALUE_CHANGE, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsSpinnerNoise.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_presentable_automatic_insertion_reaches_default_owner(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="choice") - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.AUTO_INSERTION_PRESENTABLE, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertFalse(result) - testScript.utilities.eventIsSpinnerNoise.assert_called_once_with(event) - testScript.utilities.eventIsAutocompleteNoise.assert_called_once_with(event) - testScript.utilities.clearContentCache.assert_not_called() - - def test_autocomplete_noise_precedes_presentable_automatic_insertion(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:insert", source=object(), any_data="choice") - testScript.utilities.eventIsAutocompleteNoise.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.AUTO_INSERTION_PRESENTABLE, - ): - result = web_script.Script.onTextInserted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsAutocompleteNoise.assert_called_once_with(event) - testScript.utilities.clearContentCache.assert_not_called() - - -class WebTextDeletedReasonRegressionTests(unittest.TestCase): - @staticmethod - def _make_script(): - testScript = web_script.Script.__new__(web_script.Script) - testScript.utilities = mock.Mock() - testScript.utilities.isZombie.return_value = False - testScript.utilities.lastInputEventWasPageSwitch.return_value = False - testScript.utilities.isLiveRegion.return_value = False - testScript.utilities.eventIsBrowserUINoise.return_value = False - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.eventIsSpinnerNoise.return_value = False - testScript.utilities.eventIsAutocompleteNoise.return_value = False - testScript.utilities.textEventIsDueToDeletion.return_value = False - testScript.utilities.textEventIsDueToInsertion.return_value = False - testScript.utilities.isHidden.return_value = False - testScript.utilities.getCaretContext.return_value = (None, -1) - testScript.utilities.getDocumentForObject.return_value = None - testScript.utilities.isLink.return_value = False - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = True - testScript._inMouseOverObject = False - testScript._lastMouseOverObject = None - testScript.restorePreMouseOverContext = mock.Mock() - testScript.structuralNavigation = mock.Mock() - return testScript - - def test_page_switch_reason_owns_deletion(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:delete", source=object(), any_data="x") - testScript.utilities.eventIsAutocompleteNoise.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.PAGE_SWITCH, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.lastInputEventWasPageSwitch.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_page_switch_fallback_precedes_overlapping_live_region_reason(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:delete", source=object(), any_data="x") - testScript.utilities.lastInputEventWasPageSwitch.return_value = True - testScript.utilities.isLiveRegion.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.LIVE_REGION_UPDATE, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.lastInputEventWasPageSwitch.assert_called_once() - testScript.utilities.isLiveRegion.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_live_region_reason_owns_deletion(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:delete", source=object(), any_data="x") - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.LIVE_REGION_UPDATE, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.isLiveRegion.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_unknown_reason_uses_legacy_live_region_fallback(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:delete", source=object(), any_data="x") - testScript.utilities.isLiveRegion.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.UNKNOWN, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.isLiveRegion.assert_called_once_with(event.source) - testScript.utilities.clearContentCache.assert_not_called() - - def test_ui_update_reason_owns_deletion_outside_document(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:delete", source=object(), any_data="x") - testScript.utilities.inDocumentContent.return_value = False - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.UI_UPDATE, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsBrowserUINoise.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_unknown_browser_ui_noise_uses_legacy_fallback(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:delete", source=object(), any_data="x") - testScript.utilities.inDocumentContent.return_value = False - testScript.utilities.eventIsBrowserUINoise.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.UNKNOWN, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsBrowserUINoise.assert_called_once_with(event) - testScript.utilities.clearContentCache.assert_not_called() - - def test_spin_button_reason_owns_deletion(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:delete", source=object(), any_data="1") - testScript.utilities.eventIsAutocompleteNoise.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.SPIN_BUTTON_VALUE_CHANGE, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsSpinnerNoise.assert_not_called() - testScript.utilities.eventIsAutocompleteNoise.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_autocomplete_noise_precedes_automatic_deletion(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:delete", source=object(), any_data="choice") - testScript.utilities.eventIsAutocompleteNoise.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.AUTO_DELETION, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsSpinnerNoise.assert_called_once_with(event) - testScript.utilities.eventIsAutocompleteNoise.assert_called_once_with(event) - testScript.utilities.clearContentCache.assert_not_called() - - def test_unknown_reason_uses_legacy_spinner_fallback(self): - testScript = self._make_script() - event = mock.Mock(type="object:text-changed:delete", source=object(), any_data="1") - testScript.utilities.eventIsSpinnerNoise.return_value = True - - with mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.UNKNOWN, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.eventIsSpinnerNoise.assert_called_once_with(event) - testScript.utilities.eventIsAutocompleteNoise.assert_not_called() - testScript.utilities.clearContentCache.assert_not_called() - - def test_automatic_deletion_keeps_legacy_caret_relevance_path(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-changed:delete", source=source, any_data="choice") - testScript.utilities.getCaretContext.return_value = (source, 0) - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.AUTO_DELETION, - ), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertFalse(result) - testScript.utilities.clearContentCache.assert_called_once() - testScript.utilities.getCaretContext.assert_called_once_with(getZombieReplicant=False) - - def test_editable_deletion_reasons_reach_default_owner(self): - for reason in (TextEventReason.BACKSPACE, TextEventReason.DELETE): - with self.subTest(reason=reason): - testScript = self._make_script() - source = object() - event = mock.Mock( - type="object:text-changed:delete", - source=source, - any_data="x", - ) - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=reason, - ), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertFalse(result) - testScript.utilities.clearContentCache.assert_called_once() - testScript.utilities.textEventIsDueToDeletion.assert_not_called() - testScript.utilities.textEventIsDueToInsertion.assert_not_called() - testScript.utilities.getCaretContext.assert_not_called() - - def test_hidden_backspace_reason_keeps_caret_relevance_path(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-changed:delete", source=source, any_data="x") - testScript.utilities.isHidden.return_value = True - testScript.utilities.getCaretContext.return_value = (source, 0) - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.BACKSPACE, - ), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertFalse(result) - testScript.utilities.getCaretContext.assert_called_once_with(getZombieReplicant=False) - - def test_hidden_delete_reason_reaches_default_owner(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-changed:delete", source=source, any_data="x") - testScript.utilities.isHidden.return_value = True - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.DELETE, - ), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertFalse(result) - testScript.utilities.getCaretContext.assert_not_called() - - def test_deletion_reason_from_non_editable_source_continues(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-changed:delete", source=source, any_data="x") - testScript.utilities.getCaretContext.return_value = (source, 0) - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.DELETE, - ), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertFalse(result) - testScript.utilities.textEventIsDueToDeletion.assert_not_called() - testScript.utilities.textEventIsDueToInsertion.assert_not_called() - testScript.utilities.getCaretContext.assert_called_once_with(getZombieReplicant=False) - - def test_deletion_reason_from_ordinary_non_editable_source_is_consumed_late(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-changed:delete", source=source, any_data="x") - testScript.utilities.getCaretContext.return_value = (source, 0) - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.DELETE, - ), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.getCaretContext.assert_called_once_with(getZombieReplicant=False) - - def test_typing_reason_owns_insertion_caused_deletion_for_editable_focus(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-changed:delete", source=source, any_data="x") - keyboardEvent = mock.Mock(spec=web_script.input_event.KeyboardEvent) - nonModifierEvent = mock.Mock(modifiers=0) - nonModifierEvent.is_printable_key.return_value = True - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.TYPING, - ), - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source), - mock.patch.object(web_script.cthulhu_state, "lastInputEvent", keyboardEvent), - mock.patch.object( - web_script.cthulhu_state, - "lastNonModifierKeyEvent", - nonModifierEvent, - ), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertTrue(result) - testScript.utilities.clearContentCache.assert_called_once() - testScript.utilities.textEventIsDueToDeletion.assert_not_called() - testScript.utilities.textEventIsDueToInsertion.assert_not_called() - testScript.utilities.getCaretContext.assert_not_called() - - def test_modified_typing_reason_keeps_caret_relevance_path(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-changed:delete", source=source, any_data="x") - testScript.utilities.getCaretContext.return_value = (source, 0) - keyboardEvent = mock.Mock(spec=web_script.input_event.KeyboardEvent) - nonModifierEvent = mock.Mock(modifiers=Atspi.ModifierType.ALT) - nonModifierEvent.is_printable_key.return_value = True - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.TYPING, - ), - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source), - mock.patch.object(web_script.cthulhu_state, "lastInputEvent", keyboardEvent), - mock.patch.object( - web_script.cthulhu_state, - "lastNonModifierKeyEvent", - nonModifierEvent, - ), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertFalse(result) - testScript.utilities.getCaretContext.assert_called_once_with(getZombieReplicant=False) - - def test_typing_reason_from_non_focus_source_continues(self): - testScript = self._make_script() - source = object() - event = mock.Mock(type="object:text-changed:delete", source=source, any_data="x") - testScript.utilities.getCaretContext.return_value = (source, 0) - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.TYPING, - ), - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertFalse(result) - testScript.utilities.textEventIsDueToDeletion.assert_not_called() - testScript.utilities.textEventIsDueToInsertion.assert_not_called() - testScript.utilities.getCaretContext.assert_called_once_with(getZombieReplicant=False) - - def test_unknown_reason_preserves_zombie_caret_context_recovery(self): - testScript = self._make_script() - source = object() - zombie = object() - replacement = object() - document = object() - event = mock.Mock(type="object:text-changed:delete", source=source, any_data="x") - testScript.utilities.isZombie.side_effect = lambda obj: obj is zombie - testScript.utilities.getCaretContext.side_effect = ((zombie, 2), (replacement, 3)) - testScript.utilities.getDocumentForObject.return_value = document - - with ( - mock.patch.object( - AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.UNKNOWN, - ), - mock.patch.object(web_script.AXObject, "find_ancestor", return_value=source), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=True), - mock.patch.object(web_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - result = web_script.Script.onTextDeleted(testScript, event) - - self.assertFalse(result) - testScript.utilities.clearContentCache.assert_called_once() - testScript.utilities.textEventIsDueToDeletion.assert_not_called() - testScript.utilities.textEventIsDueToInsertion.assert_not_called() - self.assertEqual( - testScript.utilities.getCaretContext.call_args_list, - [ - mock.call(getZombieReplicant=False), - mock.call(getZombieReplicant=True), - ], - ) - setLocusOfFocus.assert_called_once_with(event, replacement, notifyScript=False) - testScript.structuralNavigation.clearCache.assert_called_once_with(document) - - -class WebDescriptionChangeRegressionTests(unittest.TestCase): - def _make_script(self): - testScript = web_script.Script.__new__(web_script.Script) - testScript.pointOfReference = {} - testScript.utilities = mock.Mock() - testScript.utilities.eventIsBrowserUINoise.return_value = False - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.stringsAreRedundant.side_effect = ( - lambda first, second: first == second - ) - testScript.presentMessage = mock.Mock() - return testScript - - def test_document_description_change_matching_name_is_ignored(self): - testScript = self._make_script() - source = object() - event = mock.Mock(source=source, any_data="More") - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source), - mock.patch.object(web_script.AXObject, "get_name", return_value="More"), - ): - result = web_script.Script.onDescriptionChanged(testScript, event) - - self.assertTrue(result) - testScript.presentMessage.assert_not_called() - - def test_document_description_change_appends_to_focus_presentation(self): - testScript = self._make_script() - source = object() - event = mock.Mock(source=source, any_data="Helpful tooltip") - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source), - mock.patch.object(web_script.AXObject, "get_name", return_value="Button"), - ): - result = web_script.Script.onDescriptionChanged(testScript, event) - - self.assertTrue(result) - testScript.presentMessage.assert_called_once_with("Helpful tooltip") - - -class WebDynamicContentRecoveryRegressionTests(unittest.TestCase): - def _make_dynamic_script(self): - testScript = web_script.Script.__new__(web_script.Script) - testScript._loadingDocumentContent = False - testScript._lastCommandWasCaretNav = False - testScript._lastCommandWasStructNav = False - testScript._lastMouseButtonContext = (None, -1) - testScript.lastMouseRoutingTime = 0 - testScript.utilities = mock.Mock() - testScript.utilities.eventIsBrowserUINoise.return_value = False - testScript.utilities.isLiveRegion.return_value = False - testScript.utilities.getTopLevelDocumentForObject.return_value = "document" - testScript.utilities.isZombie.return_value = False - testScript.utilities.handleEventFromContextReplicant.return_value = False - testScript.utilities.handleEventForRemovedChild.return_value = False - testScript.utilities.inDocumentContent.return_value = True - testScript.refreshKeyGrabs = mock.Mock() - return testScript - - def test_children_added_to_live_focus_preserves_caret_context(self): - testScript = self._make_dynamic_script() - focus = object() - event = mock.Mock(source=focus, any_data=object()) - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", focus), - mock.patch.object(web_script.AXObject, "is_dead", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_busy", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_alert", return_value=False), - ): - result = web_script.Script.onChildrenAdded(testScript, event) - - self.assertFalse(result) - testScript.utilities.dumpCache.assert_called_once_with( - "document", - preserveContext=True, - ) - - def test_children_removed_from_live_focus_preserves_caret_context(self): - testScript = self._make_dynamic_script() - focus = object() - event = mock.Mock(source=focus, any_data=object()) - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", focus), - mock.patch.object(web_script.AXObject, "is_dead", return_value=False), - ): - result = web_script.Script.onChildrenRemoved(testScript, event) - - self.assertFalse(result) - testScript.utilities.dumpCache.assert_called_once_with( - "document", - preserveContext=True, - ) - - def test_focused_event_source_becomes_context_when_search_fails(self): - testScript = self._make_dynamic_script() - source = object() - oldFocus = object() - event = mock.Mock(detail1=1, source=source) - testScript._lastCommandWasCaretNav = True - testScript.utilities.getDocumentForObject.return_value = "document" - testScript.utilities.isWebAppDescendant.return_value = False - testScript.utilities.handleEventFromContextReplicant.return_value = False - testScript.utilities.getCaretContext.return_value = (None, -1) - testScript.utilities.searchForCaretContext.return_value = (None, -1) - testScript.utilities.inFindContainer.return_value = False - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", oldFocus), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_focusable", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_focused", return_value=True), - mock.patch.object(web_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - result = web_script.Script.onFocusedChanged(testScript, event) - - self.assertTrue(result) - setLocusOfFocus.assert_called_once_with(event, source, False) - testScript.utilities.setCaretContext.assert_called_once_with(source, 0) - - def test_delayed_focused_link_does_not_rewind_section_context_after_caret_nav(self): - testScript = self._make_dynamic_script() - document = object() - section = object() - link = object() - event = mock.Mock(detail1=1, source=link) - testScript._lastCommandWasCaretNav = True - testScript.utilities.getDocumentForObject.return_value = document - testScript.utilities.isWebAppDescendant.return_value = False - testScript.utilities.handleEventFromContextReplicant.return_value = False - testScript.utilities.getCaretContext.return_value = (section, 4) - testScript.utilities.isLink.side_effect = lambda obj: obj is link - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", section), - mock.patch.object(web_script.AXUtilities, "is_editable", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_dialog_or_alert", return_value=False), - mock.patch.object(web_script.AXUtilities, "is_focusable", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_focused", return_value=True), - mock.patch.object(web_script.AXUtilities, "is_section", side_effect=lambda obj: obj is section), - mock.patch.object(web_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - result = web_script.Script.onFocusedChanged(testScript, event) - - self.assertTrue(result) - setLocusOfFocus.assert_not_called() - testScript.utilities.setCaretContext.assert_not_called() - testScript.utilities.searchForCaretContext.assert_not_called() - def test_browse_mode_sticky_blocks_web_app_descendant_focus_claim(self): - testScript = self._make_dynamic_script() - source = object() - event = mock.Mock(detail1=1, source=source) - testScript._browseModeIsSticky = True - testScript.utilities.getDocumentForObject.return_value = "document" - testScript.utilities.isWebAppDescendant.return_value = True - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()), - mock.patch.object(web_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - result = web_script.Script.onFocusedChanged(testScript, event) - - self.assertTrue(result) - setLocusOfFocus.assert_not_called() - - -class WebContextReplicantRegressionTests(unittest.TestCase): - def test_same_object_replicant_can_recover_before_old_focus_is_dead(self): - utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities) - document = object() - parent = object() - oldFocus = object() - replicant = object() - event = mock.Mock() - utilities._caretContexts = {hash(parent): (oldFocus, 0)} - utilities.getCaretContextPathRoleAndName = mock.Mock( - return_value=([1, 2, 3], "button", "storm, microphone on") - ) - utilities.documentFrame = mock.Mock(return_value=document) - utilities.isSameObject = mock.Mock(return_value=True) - utilities.setCaretContext = mock.Mock() - - with ( - mock.patch.object(web_script_utilities.cthulhu_state, "locusOfFocus", oldFocus), - mock.patch.object(web_script_utilities.AXObject, "is_dead", return_value=False), - mock.patch.object(web_script_utilities.AXObject, "get_path", return_value=[1, 2, 3]), - mock.patch.object(web_script_utilities.AXObject, "get_role", return_value="button"), - mock.patch.object(web_script_utilities.AXObject, "get_name", return_value="storm, microphone on"), - mock.patch.object(web_script_utilities.AXObject, "get_parent", return_value=parent), - mock.patch.object(web_script_utilities.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - result = web_script_utilities.Utilities.handleEventFromContextReplicant( - utilities, - event, - replicant, - ) - - self.assertTrue(result) - setLocusOfFocus.assert_called_once_with(event, replicant, False) - utilities.setCaretContext.assert_called_once_with(replicant, 0, document) - - -if __name__ == "__main__": - unittest.main() - - -class WebSelectionRegressionTests(unittest.TestCase): - def _make_script(self): - testScript = web_script.Script.__new__(web_script.Script) - testScript.pointOfReference = {} - testScript.utilities = mock.Mock() - testScript.utilities.sanityCheckActiveWindow = mock.Mock() - testScript.utilities.isZombie.return_value = False - testScript.utilities.eventIsBrowserUINoise.return_value = False - testScript.utilities.eventIsBrowserUIAutocompleteNoise.return_value = False - testScript.utilities.lastInputEventWasTab.return_value = False - testScript.utilities.inFindContainer.return_value = False - testScript.utilities.eventIsFromLocusOfFocusDocument.return_value = True - testScript.utilities.textEventIsDueToInsertion.return_value = False - testScript.utilities.textEventIsDueToDeletion.return_value = False - testScript.utilities.isItemForEditableComboBox.return_value = False - testScript.utilities.eventIsAutocompleteNoise.return_value = False - testScript.utilities.eventIsSpinnerNoise.return_value = False - testScript.utilities.caretMovedOutsideActiveGrid.return_value = False - testScript.utilities.treatEventAsSpinnerValueChange.return_value = False - testScript.utilities.queryNonEmptyText.return_value = "Darkest Dungeon" - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = True - testScript.utilities.getCharacterContentsAtOffset.return_value = [[None, 0, 1, "D"]] - testScript.utilities.pathComparison.return_value = -1 - testScript.updateBraille = mock.Mock() - testScript.speakContents = mock.Mock() - testScript.speakMessage = mock.Mock() - testScript._lastCommandWasCaretNav = True - testScript._lastCommandWasStructNav = False - testScript._lastCommandWasMouseButton = False - testScript._lastMouseButtonContext = (None, -1) - testScript._inFocusMode = False - testScript._focusModeIsSticky = False - testScript._browseModeIsSticky = False - return testScript - - def test_broken_web_caret_selection_synthesizes_selection_from_caret_context(self): - testScript = self._make_script() - document = object() - section = object() - event = mock.Mock( - type="object:text-caret-moved", - source=section, - detail1=-1, - ) - manager = mock.Mock() - manager.last_event_was_forward_caret_selection.return_value = True - manager.last_event_was_backward_caret_selection.return_value = False - - testScript.utilities.getTopLevelDocumentForObject.return_value = document - testScript.utilities.getCaretContext.return_value = (section, 0) - testScript.utilities.nextContext.return_value = (section, 1) - testScript.utilities.getCharacterContentsAtOffset.return_value = [[section, 0, 1, "D"]] - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", section), - mock.patch.object(web_script.input_event_manager, "get_manager", return_value=manager), - mock.patch.object(web_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - result = web_script.Script.onCaretMoved(testScript, event) - - self.assertTrue(result) - testScript.utilities.setCaretContext.assert_called_once_with(section, 1, document) - setLocusOfFocus.assert_called_once_with(event, section, False, True) - testScript.speakContents.assert_called_once_with([[section, 0, 1, "D"]]) - testScript.speakMessage.assert_called_once_with(messages.TEXT_SELECTED) - self.assertEqual( - testScript.pointOfReference["syntheticWebSelection"]["string"], - "D", - ) - - def test_broken_web_text_selection_event_synthesizes_selection_from_event_source(self): - testScript = self._make_script() - document = object() - anchor = object() - link = object() - event = mock.Mock(source=link) - - testScript.utilities.getTopLevelDocumentForObject.return_value = document - testScript.utilities.getCaretContext.return_value = (anchor, 0) - testScript.utilities.nextContext.side_effect = [(anchor, 0)] - testScript.utilities.getCharacterContentsAtOffset.side_effect = ( - lambda obj, _offset: [[link, 0, 1, "S"]] if obj is link else [] - ) - testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - testScript._compareCaretContexts = mock.Mock(return_value=1) - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", anchor), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.SELECTION_BY_CHARACTER, - ), - mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0), - mock.patch.object(web_script.AXText, "get_selected_ranges", return_value=[]), - mock.patch.object(web_script.AXText, "get_substring", return_value="S"), - mock.patch.object(web_script.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertTrue(result) - testScript.utilities.setCaretContext.assert_called_once_with(link, 0, document) - setLocusOfFocus.assert_called_once_with(event, link, False, True) - testScript.speakContents.assert_called_once_with([[link, 0, 1, "S"]]) - testScript.speakMessage.assert_called_once_with(messages.TEXT_SELECTED) - self.assertEqual( - testScript.pointOfReference["syntheticWebSelection"]["string"], - "S", - ) - - def test_selection_reason_owns_synthetic_selection_recovery(self): - testScript = self._make_script() - event = mock.Mock(source=object()) - testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - testScript._presentSyntheticCaretSelection = mock.Mock(return_value=True) - testScript.utilities.getTopLevelDocumentForObject.return_value = object() - testScript.utilities.getCaretContext.return_value = (object(), 0) - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.SELECTION_BY_CHARACTER, - ) as getReason, - mock.patch.object(web_script.AXText, "get_selected_ranges", return_value=[]), - mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0), - mock.patch.object(web_script.AXText, "get_substring", return_value="x"), - mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False), - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertTrue(result) - getReason.assert_called_once_with(event) - testScript._presentSyntheticCaretSelection.assert_called_once() - - def test_navigation_reason_does_not_claim_synthetic_selection_recovery(self): - testScript = self._make_script() - event = mock.Mock(source=object()) - testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = True - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - testScript._presentSyntheticCaretSelection = mock.Mock(return_value=True) - testScript.utilities.getTopLevelDocumentForObject.return_value = object() - testScript.utilities.getCaretContext.return_value = (object(), 0) - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.NAVIGATION_BY_CHARACTER, - ) as getReason, - mock.patch.object(web_script.AXText, "get_selected_ranges", return_value=[]), - mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0), - mock.patch.object(web_script.AXText, "get_substring", return_value="x"), - mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False), - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertFalse(result) - getReason.assert_called_once_with(event) - testScript._presentSyntheticCaretSelection.assert_not_called() - - def test_search_reason_preserves_focus_outside_document_suppression(self): - testScript = self._make_script() - source = object() - focus = object() - event = mock.Mock(source=source) - testScript.utilities.inDocumentContent.side_effect = lambda obj: obj is source - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", focus), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.SEARCH_PRESENTABLE, - ) as getReason, - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertTrue(result) - getReason.assert_called_once_with(event) - - def test_editing_reason_preserves_default_selection_owner(self): - testScript = self._make_script() - source = object() - event = mock.Mock(source=source) - testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.PASTE, - ) as getReason, - mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0), - mock.patch.object(web_script.AXText, "get_substring", return_value="x"), - mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False), - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertFalse(result) - getReason.assert_called_once_with(event) - - def test_autocomplete_noise_still_precedes_reason_specific_ownership(self): - testScript = self._make_script() - event = mock.Mock(source=object()) - testScript.utilities.eventIsAutocompleteNoise.return_value = True - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.SELECTION_BY_WORD, - ) as getReason, - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertTrue(result) - getReason.assert_called_once_with(event) - testScript.utilities.lastInputEventWasCaretNavWithSelection.assert_not_called() - - def test_spinner_noise_still_precedes_reason_specific_ownership(self): - testScript = self._make_script() - event = mock.Mock(source=object()) - testScript.utilities.eventIsSpinnerNoise.return_value = True - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.SPIN_BUTTON_VALUE_CHANGE, - ) as getReason, - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertTrue(result) - getReason.assert_called_once_with(event) - testScript.utilities.lastInputEventWasCaretNavWithSelection.assert_not_called() - - def test_non_navigable_text_still_suppresses_selection_reason(self): - testScript = self._make_script() - event = mock.Mock(source=object()) - testScript.utilities.textEventIsForNonNavigableTextObject.return_value = True - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", object()), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.SELECTION_BY_LINE, - ) as getReason, - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertTrue(result) - getReason.assert_called_once_with(event) - testScript.utilities.lastInputEventWasCaretNavWithSelection.assert_not_called() - - def test_selection_reason_at_embedded_object_offset_defers_to_default(self): - testScript = self._make_script() - source = object() - event = mock.Mock(source=source) - testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = False - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.SELECTION_BY_WORD, - ), - mock.patch.object(web_script.AXText, "get_selected_ranges", return_value=[(0, 1)]), - mock.patch.object(web_script.AXText, "get_caret_offset", return_value=0), - mock.patch.object( - web_script.AXText, - "get_substring", - return_value=web_script.Script.EMBEDDED_OBJECT_CHARACTER, - ), - mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False), - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertFalse(result) - testScript.utilities.lastInputEventWasCaretNavWithSelection.assert_not_called() - - def test_contenteditable_embedded_objects_still_defer_to_default(self): - testScript = self._make_script() - source = object() - event = mock.Mock(source=source) - testScript.utilities.textEventIsForNonNavigableTextObject.return_value = False - testScript.utilities.lastInputEventWasCaretNavWithSelection.return_value = False - testScript.utilities.isContentEditableWithEmbeddedObjects.return_value = True - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", source), - mock.patch.object( - web_script.AXUtilitiesEvent, - "get_text_event_reason", - return_value=TextEventReason.TYPING, - ) as getReason, - mock.patch.object(web_script.AXUtilities, "is_text_input", return_value=False), - ): - result = web_script.Script.onTextSelectionChanged(testScript, event) - - self.assertFalse(result) - getReason.assert_called_once_with(event) - - def test_web_utilities_all_selected_text_falls_back_to_synthetic_selection(self): - testScript = mock.Mock(pointOfReference={}) - utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities) - utilities._script = testScript - document = object() - obj = object() - testScript.pointOfReference["syntheticWebSelection"] = { - "document": document, - "string": "Dark", - } - - with ( - mock.patch.object( - web_script_utilities.script_utilities.Utilities, - "allSelectedText", - return_value=["", 0, 0], - ), - mock.patch.object(utilities, "inDocumentContent", return_value=True), - mock.patch.object(utilities, "getTopLevelDocumentForObject", return_value=document), - ): - result = web_script_utilities.Utilities.allSelectedText(utilities, obj) - - self.assertEqual(result, ["Dark", 0, 4]) - - -class WebContentCacheRegressionTests(unittest.TestCase): - def test_clear_cached_objects_clears_current_line_contents(self): - utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities) - utilities._currentObjectContents = ["object"] - utilities._currentSentenceContents = ["sentence"] - utilities._currentLineContents = ["line"] - utilities._currentWordContents = ["word"] - utilities._currentCharacterContents = ["character"] - utilities._currentTextAttrs = {"attrs": True} - utilities._cleanupContexts = mock.Mock() - - web_script_utilities.Utilities.clearCachedObjects(utilities) - - self.assertIsNone(utilities._currentObjectContents) - self.assertIsNone(utilities._currentSentenceContents) - self.assertIsNone(utilities._currentLineContents) - self.assertIsNone(utilities._currentWordContents) - self.assertIsNone(utilities._currentCharacterContents) - self.assertEqual(utilities._currentTextAttrs, {}) - utilities._cleanupContexts.assert_called_once_with() - - -class WebSkipSpaceCaretNavigationRegressionTests(unittest.TestCase): - def _make_utilities(self): - utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities) - utilities.getCaretContext = mock.Mock(return_value=(None, -1)) - utilities.treatAsTextObject = mock.Mock(return_value=True) - return utilities - - def test_next_context_does_not_skip_named_whole_object_as_space(self): - utilities = self._make_utilities() - start = object() - wholeObject = object() - after = object() - utilities.treatAsTextObject.return_value = False - utilities.findNextCaretInOrder = mock.Mock( - side_effect=[(wholeObject, 0), (after, 0)] - ) - - with mock.patch.object( - web_script_utilities.AXText, - "get_character_at_offset", - return_value=(" ", 0, 1), - ) as getCharacter: - result = web_script_utilities.Utilities.nextContext( - utilities, - start, - 0, - skipSpace=True, - ) - - self.assertEqual(result, (wholeObject, 0)) - utilities.treatAsTextObject.assert_called_once_with(wholeObject) - getCharacter.assert_not_called() - utilities.findNextCaretInOrder.assert_called_once_with(start, 0) - - def test_previous_context_does_not_skip_named_whole_object_as_space(self): - utilities = self._make_utilities() - start = object() - wholeObject = object() - before = object() - utilities.treatAsTextObject.return_value = False - utilities.findPreviousCaretInOrder = mock.Mock( - side_effect=[(wholeObject, 0), (before, 0)] - ) - - with mock.patch.object( - web_script_utilities.AXText, - "get_character_at_offset", - return_value=(" ", 0, 1), - ) as getCharacter: - result = web_script_utilities.Utilities.previousContext( - utilities, - start, - 0, - skipSpace=True, - ) - - self.assertEqual(result, (wholeObject, 0)) - utilities.treatAsTextObject.assert_called_once_with(wholeObject) - getCharacter.assert_not_called() - utilities.findPreviousCaretInOrder.assert_called_once_with(start, 0) - - def test_next_context_breaks_skip_space_cycles(self): - utilities = self._make_utilities() - start = object() - first = object() - second = object() - utilities.findNextCaretInOrder = mock.Mock( - side_effect=[(first, 0), (second, 0), (first, 0)] - ) - - with mock.patch.object( - web_script_utilities.AXText, - "get_character_at_offset", - return_value=(" ", 0, 1), - ): - result = web_script_utilities.Utilities.nextContext( - utilities, - start, - 0, - skipSpace=True, - ) - - self.assertEqual(result, (first, 0)) - self.assertEqual(utilities.findNextCaretInOrder.call_args_list, [ - mock.call(start, 0), - mock.call(first, 0), - mock.call(second, 0), - ]) - - def test_previous_context_breaks_skip_space_cycles(self): - utilities = self._make_utilities() - start = object() - first = object() - second = object() - utilities.findPreviousCaretInOrder = mock.Mock( - side_effect=[(first, 0), (second, 0), (first, 0)] - ) - - with mock.patch.object( - web_script_utilities.AXText, - "get_character_at_offset", - return_value=(" ", 0, 1), - ): - result = web_script_utilities.Utilities.previousContext( - utilities, - start, - 0, - skipSpace=True, - ) - - self.assertEqual(result, (first, 0)) - self.assertEqual(utilities.findPreviousCaretInOrder.call_args_list, [ - mock.call(start, 0), - mock.call(first, 0), - mock.call(second, 0), - ]) - - -class WebSplitLinkLineNavigationRegressionTests(unittest.TestCase): - def _make_utilities(self, link): - utilities = web_script_utilities.Utilities.__new__(web_script_utilities.Utilities) - utilities.isZombie = mock.Mock(return_value=False) - utilities.getMathAncestor = mock.Mock(return_value=None) - utilities.isLink = mock.Mock(side_effect=lambda obj: obj is link) - utilities.clearCachedObjects = mock.Mock() - return utilities - - def test_next_line_uses_non_layout_contents_for_split_link(self): - link = object() - utilities = self._make_utilities(link) - currentLine = [[link, 0, 20, "https://stormux.org/"]] - nextLine = [[link, 20, 29, "downloads"]] - utilities.nextContext = mock.Mock(return_value=(link, 20)) - utilities.getLineContentsAtOffset = mock.Mock(side_effect=[currentLine, nextLine]) - - manager = mock.Mock() - manager.get_speak_blank_lines.return_value = False - with mock.patch.object( - web_script_utilities.speech_and_verbosity_manager, - "getManager", - return_value=manager, - ): - result = web_script_utilities.Utilities.getNextLineContents(utilities, link, 0) - - self.assertEqual(result, nextLine) - utilities.nextContext.assert_called_once_with(link, 19, True) - self.assertEqual( - utilities.getLineContentsAtOffset.call_args_list, - [ - mock.call(link, 0, None, True), - mock.call(link, 20, layoutMode=False, useCache=False), - ], - ) - - def test_previous_line_uses_non_layout_contents_for_split_link(self): - link = object() - utilities = self._make_utilities(link) - previousLine = [[link, 0, 20, "https://stormux.org/"]] - currentLine = [[link, 20, 29, "downloads"]] - utilities.previousContext = mock.Mock(return_value=(link, 19)) - utilities.getLineContentsAtOffset = mock.Mock(side_effect=[currentLine, previousLine]) - - manager = mock.Mock() - manager.get_speak_blank_lines.return_value = False - with mock.patch.object( - web_script_utilities.speech_and_verbosity_manager, - "getManager", - return_value=manager, - ): - result = web_script_utilities.Utilities.getPreviousLineContents(utilities, link, 20) - - self.assertEqual(result, previousLine) - utilities.previousContext.assert_called_once_with(link, 20, True) - self.assertEqual( - utilities.getLineContentsAtOffset.call_args_list, - [ - mock.call(link, 20, None, True), - mock.call(link, 19, layoutMode=False, useCache=False), - ], - ) - - def test_current_line_on_wrapped_link_continuation_does_not_expand_to_parent(self): - link = object() - utilities = self._make_utilities(link) - utilities._currentLineContents = None - utilities._debugContentsInfo = mock.Mock() - utilities.findObjectInContents = mock.Mock(return_value=-1) - utilities.treatAsEndOfLine = mock.Mock(return_value=False) - utilities.getExtents = mock.Mock(return_value=[321, 763, 86, 19]) - utilities.isInlineListDescendant = mock.Mock(return_value=False) - utilities._getContentsForObj = mock.Mock( - return_value=[[link, 20, 29, "downloads"]] - ) - utilities.getDocumentForObject = mock.Mock() - - with ( - mock.patch.object(web_script_utilities.AXObject, "is_dead", return_value=False), - mock.patch.object(web_script_utilities.AXObject, "find_ancestor", return_value=None), - mock.patch.object(web_script_utilities.AXUtilities, "is_tool_bar", return_value=False), - mock.patch.object(web_script_utilities.AXUtilities, "is_menu_bar", return_value=False), - ): - result = web_script_utilities.Utilities._getLineContentsAtOffset( - utilities, - link, - 23, - layoutMode=True, - ) - - self.assertEqual(result, [[link, 20, 29, "downloads"]]) - utilities.getDocumentForObject.assert_not_called() - utilities._debugContentsInfo.assert_called_once_with( - link, - 23, - [[link, 20, 29, "downloads"]], - "Line (wrapped link)", - ) - - def test_next_line_after_split_link_uses_parent_line_after_embedded_marker(self): - link = object() - paragraph = object() - utilities = self._make_utilities(link) - currentLine = [[link, 20, 29, "downloads"]] - paragraphLine = [[paragraph, 95, 191, "[OBJ]. On first boot"]] - expectedLine = [[paragraph, 96, 191, ". On first boot"]] - utilities.nextContext = mock.Mock(return_value=(paragraph, 96)) - utilities.getLineContentsAtOffset = mock.Mock( - side_effect=[currentLine, paragraphLine] - ) - utilities.getHyperlinkRange = mock.Mock(return_value=(95, 96)) - - manager = mock.Mock() - manager.get_speak_blank_lines.return_value = False - with ( - mock.patch.object( - web_script_utilities.speech_and_verbosity_manager, - "getManager", - return_value=manager, - ), - mock.patch.object( - web_script_utilities.AXObject, - "get_parent", - return_value=paragraph, - ), - mock.patch.object( - web_script_utilities.AXText, - "get_character_at_offset", - return_value=(utilities.EMBEDDED_OBJECT_CHARACTER, 95, 96), - ), - mock.patch.object( - web_script_utilities.AXText, - "get_substring", - return_value=". On first boot", - ), - ): - result = web_script_utilities.Utilities.getNextLineContents( - utilities, - link, - 23, - ) - - self.assertEqual(result, expectedLine) - utilities.nextContext.assert_called_once_with(link, 28, True) - self.assertEqual( - utilities.getLineContentsAtOffset.call_args_list, - [ - mock.call(link, 23, None, True), - mock.call(paragraph, 96, layoutMode=False, useCache=False), - ], - ) - - -class WebGeckoBrokenTextRecoveryRegressionTests(unittest.TestCase): - def test_gecko_limits_broken_text_recovery_to_sentences(self): - utilities = gecko_script_utilities.Utilities.__new__(gecko_script_utilities.Utilities) - utilities.isContentEditableWithEmbeddedObjects = mock.Mock(return_value=True) - obj = object() - - self.assertTrue( - gecko_script_utilities.Utilities._attemptBrokenTextRecovery( - utilities, - obj, - boundary=Atspi.TextBoundaryType.SENTENCE_START, - ) - ) - self.assertFalse( - gecko_script_utilities.Utilities._attemptBrokenTextRecovery( - utilities, - obj, - boundary=Atspi.TextBoundaryType.LINE_START, - ) - ) - self.assertFalse( - gecko_script_utilities.Utilities._attemptBrokenTextRecovery( - utilities, - obj, - boundary=Atspi.TextBoundaryType.WORD_START, - ) - ) diff --git a/tests/test_web_layout_mode_regressions.py b/tests/test_web_layout_mode_regressions.py deleted file mode 100644 index 8ca0276..0000000 --- a/tests/test_web_layout_mode_regressions.py +++ /dev/null @@ -1,164 +0,0 @@ -import sys -import tempfile -import unittest -from pathlib import Path -from unittest import mock - -import gi - -gi.require_version("Atspi", "2.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import settings -from cthulhu import settings_manager -from cthulhu.scripts.web import script_utilities as web_script_utilities - - -class WebLayoutModeSettingsRegressionTests(unittest.TestCase): - def test_layout_mode_defaults_to_object_mode(self): - self.assertFalse(settings.layoutMode) - - def test_explicit_persisted_layout_mode_true_is_preserved(self): - with tempfile.TemporaryDirectory() as tempDir: - with mock.patch.object(settings, "layoutMode", False): - manager = settings_manager.SettingsManager(mock.Mock()) - manager.activate(prefsDir=tempDir) - settingsPath = Path(tempDir, "user-settings.toml") - settingsText = settingsPath.read_text(encoding="utf-8") - settingsPath.write_text( - settingsText.replace("layoutMode = false", "layoutMode = true"), - encoding="utf-8", - ) - - reloadedManager = settings_manager.SettingsManager(mock.Mock()) - reloadedManager.activate(prefsDir=tempDir) - - self.assertTrue(reloadedManager.getSetting("layoutMode")) - - def test_application_specific_layout_mode_true_is_preserved(self): - with tempfile.TemporaryDirectory() as tempDir: - with mock.patch.object(settings, "layoutMode", False): - manager = settings_manager.SettingsManager(mock.Mock()) - manager.activate(prefsDir=tempDir) - manager._backend.saveAppSettings( - "Browser", - manager.profile, - {"layoutMode": True}, - {}, - {}, - ) - script = mock.Mock() - script.app = object() - script.getKeyBindings.return_value = mock.Mock() - - with mock.patch.object( - settings_manager.AXObject, - "get_name", - return_value="Browser", - ): - manager.loadAppSettings(script) - - self.assertTrue(manager.getSetting("layoutMode")) - - -class WebLayoutModeLineRegressionTests(unittest.TestCase): - def _make_utilities(self): - obj = object() - contents = [[obj, 0, 4, "Text"]] - utilities = web_script_utilities.Utilities.__new__( - web_script_utilities.Utilities - ) - utilities._script = mock.Mock() - utilities._script.inFocusMode.return_value = False - utilities._currentLineContents = [] - utilities._debugContentsInfo = mock.Mock() - utilities.findObjectInContents = mock.Mock(return_value=-1) - utilities.treatAsEndOfLine = mock.Mock(return_value=False) - utilities.getExtents = mock.Mock(return_value=[0, 0, 10, 10]) - utilities.isInlineListDescendant = mock.Mock(return_value=False) - utilities._getContentsForObj = mock.Mock(return_value=contents) - utilities.isLink = mock.Mock(return_value=False) - utilities.isMath = mock.Mock(return_value=False) - utilities.isMathTopLevel = mock.Mock(return_value=False) - utilities.getDocumentForObject = mock.Mock(return_value=object()) - utilities.findPreviousCaretInOrder = mock.Mock(return_value=(None, -1)) - utilities.findNextCaretInOrder = mock.Mock(return_value=(None, -1)) - utilities.isContentEditableWithEmbeddedObjects = mock.Mock(return_value=False) - utilities.inDocumentContent = mock.Mock(return_value=False) - return utilities, obj, contents - - def _get_line_for_setting(self, layoutMode): - utilities, obj, contents = self._make_utilities() - settingsManager = mock.Mock() - settingsManager.getSetting.return_value = layoutMode - - with ( - mock.patch.object( - web_script_utilities.cthulhu.cthulhuApp, - "settingsManager", - settingsManager, - ), - mock.patch.object( - web_script_utilities.AXObject, - "is_dead", - return_value=False, - ), - mock.patch.object( - web_script_utilities.AXObject, - "find_ancestor", - return_value=None, - ), - mock.patch.object( - web_script_utilities.AXUtilities, - "is_tool_bar", - return_value=False, - ), - mock.patch.object( - web_script_utilities.AXUtilities, - "is_menu_bar", - return_value=False, - ), - mock.patch.object( - web_script_utilities.AXUtilities, - "is_table_row", - return_value=False, - ), - ): - result = web_script_utilities.Utilities._getLineContentsAtOffset( - utilities, - obj, - 0, - layoutMode=None, - useCache=False, - ) - - return utilities, obj, contents, result - - def test_unset_profile_setting_uses_object_mode_for_web_line(self): - utilities, obj, contents, result = self._get_line_for_setting(False) - - self.assertEqual(result, contents) - utilities.getDocumentForObject.assert_not_called() - utilities._debugContentsInfo.assert_called_once_with( - obj, - 0, - contents, - "Line (not layout mode)", - ) - - def test_explicit_layout_mode_true_uses_visual_web_line(self): - utilities, obj, contents, result = self._get_line_for_setting(True) - - self.assertEqual(result, contents) - utilities.getDocumentForObject.assert_called_once_with(obj) - utilities._debugContentsInfo.assert_called_once_with( - obj, - 0, - contents, - "Line (layout mode)", - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_web_router_regressions.py b/tests/test_web_router_regressions.py deleted file mode 100644 index 9683f1b..0000000 --- a/tests/test_web_router_regressions.py +++ /dev/null @@ -1,153 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -soundGeneratorModule = sys.modules.get("cthulhu.sound_generator") -if soundGeneratorModule is not None and not hasattr(soundGeneratorModule, "SoundGenerator"): - class _StubSoundGenerator: - pass - - soundGeneratorModule.SoundGenerator = _StubSoundGenerator - -from cthulhu import ax_object -from cthulhu import ax_utilities -from cthulhu.scripts.web import script as web_script -from cthulhu.scripts.web import script_utilities - - -class WebClickableActivationTests(unittest.TestCase): - def test_return_activates_click_ancestor_on_caret_context(self): - testScript = web_script.Script.__new__(web_script.Script) - caretObject = object() - documentObject = object() - - testScript.utilities = mock.Mock() - testScript.utilities.inDocumentContent.return_value = True - testScript.utilities.getCaretContext.return_value = (caretObject, 0) - testScript.utilities.isClickableElement.return_value = False - testScript.inFocusMode = mock.Mock(return_value=False) - testScript.presentMessage = mock.Mock() - testScript._presentDelayedMessage = mock.Mock() - testScript._restoreFocusAfterClick = mock.Mock() - - def has_action(obj, action_name): - return obj is caretObject and action_name == "click-ancestor" - - with ( - mock.patch.object(web_script.cthulhu_state, "locusOfFocus", documentObject), - mock.patch.object(ax_utilities.AXUtilities, "is_entry", return_value=False), - mock.patch.object(ax_utilities.AXUtilities, "is_text", return_value=False), - mock.patch.object(ax_utilities.AXUtilities, "is_password_text", return_value=False), - mock.patch.object(ax_utilities.AXUtilities, "is_combo_box", return_value=False), - mock.patch.object(ax_utilities.AXUtilities, "is_button", return_value=False), - mock.patch.object(ax_utilities.AXUtilities, "is_push_button", return_value=False), - mock.patch.object(ax_utilities.AXUtilities, "is_link", return_value=False), - mock.patch.object(ax_object.AXObject, "has_action", side_effect=has_action), - mock.patch.object(ax_object.AXObject, "do_named_action", return_value=True) as doAction, - mock.patch("cthulhu.ax_event_synthesizer.AXEventSynthesizer.click_object") as clickObject, - ): - self.assertTrue(testScript._tryClickableActivation(mock.Mock(event_string="Return"))) - - doAction.assert_called_once_with(caretObject, "click-ancestor") - clickObject.assert_not_called() - testScript._presentDelayedMessage.assert_not_called() - - -class WebHiddenPopupTests(unittest.TestCase): - def test_hidden_ancestor_marks_descendant_hidden(self): - utilities = script_utilities.Utilities.__new__(script_utilities.Utilities) - child = object() - hiddenParent = object() - - utilities.inDocumentContent = mock.Mock(return_value=True) - utilities.objectAttributes = mock.Mock( - side_effect=lambda obj, useCache=False: { - child: {"display": "block"}, - hiddenParent: {"display": "none"}, - }.get(obj, {}) - ) - - with mock.patch.object( - script_utilities.AXObject, - "get_parent", - side_effect=lambda obj: hiddenParent if obj is child else None, - ): - self.assertTrue(utilities.isHidden(child)) - - def test_focusable_hidden_object_cannot_have_caret_context(self): - utilities = script_utilities.Utilities.__new__(script_utilities.Utilities) - hiddenObject = object() - - utilities._canHaveCaretContextDecision = {} - utilities.isZombie = mock.Mock(return_value=False) - utilities.isStaticTextLeaf = mock.Mock(return_value=False) - utilities.isUselessEmptyElement = mock.Mock(return_value=False) - utilities.isOffScreenLabel = mock.Mock(return_value=False) - utilities.isNonNavigablePopup = mock.Mock(return_value=False) - utilities.isUselessImage = mock.Mock(return_value=False) - utilities.isEmptyAnchor = mock.Mock(return_value=False) - utilities.isEmptyToolTip = mock.Mock(return_value=False) - utilities.isParentOfNullChild = mock.Mock(return_value=False) - utilities.isPseudoElement = mock.Mock(return_value=False) - utilities.isFakePlaceholderForEntry = mock.Mock(return_value=False) - utilities.isNonInteractiveDescendantOfControl = mock.Mock(return_value=False) - utilities.isHidden = mock.Mock(return_value=True) - utilities.hasNoSize = mock.Mock(return_value=False) - - with ( - mock.patch.object(script_utilities.AXObject, "is_dead", return_value=False), - mock.patch.object(script_utilities.AXUtilities, "is_focusable", return_value=True), - ): - self.assertFalse(utilities._canHaveCaretContext(hiddenObject)) - - -class WebRemovedChildRegressionTests(unittest.TestCase): - def test_removed_child_recovery_does_not_crash_when_last_key_is_not_up_or_down(self): - utilities = script_utilities.Utilities.__new__(script_utilities.Utilities) - removedChild = object() - locusOfFocus = object() - source = object() - recoveredObject = object() - event = mock.Mock(any_data=removedChild, source=source, detail1=0) - - utilities._script = mock.Mock(pointOfReference={"names": {}}) - utilities._handleEventForRemovedListBoxChild = mock.Mock(return_value=False) - utilities.isSameObject = mock.Mock(return_value=False) - utilities.searchForCaretContext = mock.Mock(return_value=(recoveredObject, 0)) - utilities.setCaretContext = mock.Mock() - - manager = mock.Mock() - manager.last_event_was_up.return_value = False - manager.last_event_was_down.return_value = False - - def find_ancestor(obj, predicate): - if obj is locusOfFocus and predicate(removedChild): - return removedChild - return None - - with ( - mock.patch.object(script_utilities.cthulhu_state, "locusOfFocus", locusOfFocus), - mock.patch.object(script_utilities.input_event_manager, "get_manager", return_value=manager), - mock.patch.object(script_utilities.AXObject, "find_ancestor", side_effect=find_ancestor), - mock.patch.object(script_utilities.AXObject, "get_child_count", return_value=0), - mock.patch.object(script_utilities.AXObject, "clear_cache"), - mock.patch.object(script_utilities.AXObject, "is_dead", return_value=False), - mock.patch.object(script_utilities.AXUtilities, "get_focused_object", return_value=None), - mock.patch.object(script_utilities.cthulhu, "setLocusOfFocus") as setLocusOfFocus, - ): - self.assertTrue(utilities.handleEventForRemovedChild(event)) - - setLocusOfFocus.assert_called_once_with(event, recoveredObject, False) - utilities.setCaretContext.assert_called_once_with(recoveredObject, 0) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_window_title_fallback_regressions.py b/tests/test_window_title_fallback_regressions.py deleted file mode 100644 index 266f994..0000000 --- a/tests/test_window_title_fallback_regressions.py +++ /dev/null @@ -1,263 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import where_am_i_presenter -from cthulhu.plugins.WindowTitleReader.plugin import WindowTitleReader - - -class WindowTitleFallbackRegressionTests(unittest.TestCase): - def test_activate_registers_reader_api_and_starts_fallback_tracking(self): - plugin = WindowTitleReader() - plugin.app = mock.Mock() - - with ( - mock.patch.object(plugin, "_register_keybinding"), - mock.patch.object(plugin, "_start_tracking") as startTracking, - ): - plugin.activate(plugin) - - plugin.app.getDynamicApiManager.return_value.registerAPI.assert_called_once_with( - "WindowTitleReader", - plugin, - overwrite=True, - ) - startTracking.assert_called_once_with() - - def test_poll_schedules_fallback_after_active_window_changes(self): - plugin = WindowTitleReader() - plugin._pollSourceId = 1 - plugin._lastActiveWindowId = 100 - activeWindow = mock.Mock(id=200) - - with ( - mock.patch.object(plugin, "_ensure_x11_display", return_value=True), - mock.patch.object(plugin, "_get_active_window", return_value=activeWindow), - mock.patch.object(plugin, "_get_current_title", return_value="XTerm"), - mock.patch.object(plugin, "_schedule_fallback_title") as scheduleFallback, - ): - self.assertTrue(plugin._poll_window_title()) - - scheduleFallback.assert_called_once_with() - - def test_poll_keeps_previous_window_across_transient_missing_active_window(self): - plugin = WindowTitleReader() - plugin._pollSourceId = 1 - plugin._lastActiveWindowId = 100 - - with ( - mock.patch.object(plugin, "_ensure_x11_display", return_value=True), - mock.patch.object(plugin, "_get_active_window", return_value=None), - ): - self.assertTrue(plugin._poll_window_title()) - - self.assertEqual(plugin._lastActiveWindowId, 100) - - def test_fallback_is_empty_when_atspi_exposes_same_title(self): - plugin = WindowTitleReader() - plugin._pollSourceId = 1 - activeWindow = mock.Mock() - - with ( - mock.patch.object(plugin, "_ensure_x11_display", return_value=True), - mock.patch.object(plugin, "_get_active_window", return_value=activeWindow), - mock.patch.object(plugin, "_get_current_title", return_value="Terminal"), - ): - self.assertEqual(plugin.get_fallback_title("Terminal"), "") - - def test_fallback_replaces_wine_desktop_title(self): - plugin = WindowTitleReader() - plugin._pollSourceId = 1 - activeWindow = mock.Mock() - - with ( - mock.patch.object(plugin, "_ensure_x11_display", return_value=True), - mock.patch.object(plugin, "_get_active_window", return_value=activeWindow), - mock.patch.object(plugin, "_get_current_title", return_value="Game Window"), - ): - self.assertEqual(plugin.get_fallback_title("Wine Desktop"), "Game Window") - - def test_fallback_prefers_i3_title_and_window_id(self): - plugin = WindowTitleReader() - plugin.app = mock.Mock() - snapshot = mock.Mock( - backend_name="i3-ipc", - focused_workspace_empty=False, - focused_window_id=0x200000C, - focused_window_title="Accurate i3 title", - ) - plugin.app.getCompositorStateAdapter.return_value.get_snapshot.return_value = snapshot - - with mock.patch.object(plugin, "_get_active_window") as getX11Window: - self.assertEqual(plugin.get_fallback_title("Incomplete title"), "Accurate i3 title") - - getX11Window.assert_not_called() - - def test_i3_wine_desktop_title_uses_existing_child_window_resolution(self): - plugin = WindowTitleReader() - plugin.app = mock.Mock() - snapshot = mock.Mock( - backend_name="i3-ipc", - focused_workspace_empty=False, - focused_window_id=0x2400007, - focused_window_title="Wine Desktop", - ) - desktopWindow = mock.Mock() - plugin.app.getCompositorStateAdapter.return_value.get_snapshot.return_value = snapshot - plugin._display = mock.Mock() - plugin._display.create_resource_object.return_value = desktopWindow - - with ( - mock.patch.object(plugin, "_ensure_x11_display", return_value=True), - mock.patch.object( - plugin, - "_get_window_title", - return_value="Wine Desktop", - ), - mock.patch.object( - plugin, - "_get_wine_desktop_title", - return_value="Actual Game Window", - ) as getWineTitle, - ): - self.assertEqual( - plugin.get_fallback_title("Wine Desktop"), - "Actual Game Window", - ) - - plugin._display.create_resource_object.assert_called_once_with("window", 0x2400007) - getWineTitle.assert_called_once_with(desktopWindow) - - def test_wine_title_resolution_ignores_unrelated_x11_focus(self): - plugin = WindowTitleReader() - desktopWindow = mock.Mock(id=10) - unrelatedFocus = mock.Mock(id=20) - - with ( - mock.patch.object(plugin, "_get_focus_window", return_value=unrelatedFocus), - mock.patch.object( - plugin, - "_window_is_descendant_of", - return_value=False, - ) as isDescendant, - mock.patch.object(plugin, "_get_window_title", return_value="Unrelated Terminal"), - mock.patch.object( - plugin, - "_find_child_title", - return_value="Actual Game Window", - ) as findChildTitle, - ): - self.assertEqual( - plugin._get_wine_desktop_title(desktopWindow), - "Actual Game Window", - ) - - isDescendant.assert_called_once_with(unrelatedFocus, desktopWindow) - findChildTitle.assert_called_once_with(desktopWindow) - - def test_wine_child_title_filter_rejects_infrastructure_windows(self): - plugin = WindowTitleReader() - helperWindow = mock.Mock() - helperWindow.get_wm_class.return_value = ( - "cthulhu-wine-access.exe", - "cthulhu-wine-access.exe", - ) - gameWindow = mock.Mock() - gameWindow.get_wm_class.return_value = ("game.exe", "game.exe") - - self.assertFalse(plugin._is_usable_wine_child_title(gameWindow, "Default IME")) - self.assertFalse(plugin._is_usable_wine_child_title(helperWindow, "NVDA")) - self.assertTrue(plugin._is_usable_wine_child_title(gameWindow, "Actual Game Window")) - - def test_confirmed_empty_i3_workspace_does_not_fall_back_to_stale_x11_title(self): - plugin = WindowTitleReader() - plugin.app = mock.Mock() - snapshot = mock.Mock( - backend_name="i3-ipc", - focused_workspace_empty=True, - focused_window_id=None, - focused_window_title="", - ) - plugin.app.getCompositorStateAdapter.return_value.get_snapshot.return_value = snapshot - - with mock.patch.object(plugin, "_get_active_window") as getX11Window: - self.assertEqual(plugin.get_fallback_title("Browser"), "") - - getX11Window.assert_not_called() - - def test_unknown_i3_context_falls_back_to_generic_x11_title(self): - plugin = WindowTitleReader() - plugin.app = mock.Mock() - snapshot = mock.Mock( - backend_name="i3-ipc", - focused_workspace_empty=None, - focused_window_id=None, - focused_window_title="", - ) - plugin.app.getCompositorStateAdapter.return_value.get_snapshot.return_value = snapshot - plugin._pollSourceId = 1 - activeWindow = mock.Mock() - - with ( - mock.patch.object(plugin, "_ensure_x11_display", return_value=True) as ensureX11, - mock.patch.object(plugin, "_get_active_window", return_value=activeWindow), - mock.patch.object(plugin, "_get_current_title", return_value="Generic X title"), - ): - self.assertEqual(plugin.get_fallback_title("Incomplete"), "Generic X title") - - ensureX11.assert_called_once_with() - - def test_known_i3_xid_with_missing_title_uses_exact_x11_title(self): - plugin = WindowTitleReader() - plugin.app = mock.Mock() - snapshot = mock.Mock( - backend_name="i3-ipc", - focused_workspace_empty=False, - focused_window_id=0x2600003, - focused_window_title="", - ) - activeWindow = mock.Mock() - plugin.app.getCompositorStateAdapter.return_value.get_snapshot.return_value = snapshot - plugin._display = mock.Mock() - plugin._display.create_resource_object.return_value = activeWindow - - with ( - mock.patch.object(plugin, "_ensure_x11_display", return_value=True), - mock.patch.object( - plugin, - "_get_current_title", - return_value="Exact X11 title", - ) as getCurrentTitle, - ): - self.assertEqual( - plugin.get_fallback_title("Incomplete"), - "Exact X11 title", - ) - - plugin._display.create_resource_object.assert_called_once_with("window", 0x2600003) - getCurrentTitle.assert_called_once_with(activeWindow) - - def test_present_title_uses_fallback_instead_of_atspi_title(self): - presenter = where_am_i_presenter.WhereAmIPresenter() - script = mock.Mock() - script.speechGenerator.generateTitle.return_value = [("Wine Desktop", None)] - - with ( - mock.patch.object(where_am_i_presenter.cthulhu_state, "locusOfFocus", object()), - mock.patch.object(where_am_i_presenter.AXObject, "is_dead", return_value=False), - mock.patch.object( - presenter, - "_get_fallback_title", - return_value="Game Window", - ), - ): - self.assertTrue(presenter.present_title(script)) - - script.presentMessage.assert_called_once_with("Game Window") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_wine_access_controller_contract.py b/tests/test_wine_access_controller_contract.py deleted file mode 100644 index 15e1e60..0000000 --- a/tests/test_wine_access_controller_contract.py +++ /dev/null @@ -1,46 +0,0 @@ -import re -import unittest -from pathlib import Path - - -class WineAccessControllerContractTests(unittest.TestCase): - def test_legacy_speak_text_queues_without_cancelling_current_speech(self): - sourcePath = Path(__file__).resolve().parents[1] / "wine-access" / "main.cpp" - source = sourcePath.read_text(encoding="utf-8") - match = re.search( - r'extern "C" error_status_t __stdcall speakText\(.*?\n\}', - source, - re.DOTALL, - ) - - self.assertIsNotNone(match) - self.assertIn( - 'g_variant_new("(sb)", utf8.c_str(), FALSE)', - match.group(0), - ) - - def test_helper_uses_windows_subsystem_without_a_console_window(self): - cmakePath = Path(__file__).resolve().parents[1] / "wine-access" / "CMakeLists.txt" - source = cmakePath.read_text(encoding="utf-8") - - self.assertIn( - "target_link_options(cthulhu-wine-access PRIVATE -mwindows)", - source, - ) - - def test_compatibility_window_stays_hidden_zero_sized_and_nonactivating(self): - sourcePath = Path(__file__).resolve().parents[1] / "wine-access" / "main.cpp" - source = sourcePath.read_text(encoding="utf-8") - - self.assertIn("WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW", source) - self.assertIsNotNone(re.search( - r"CreateWindowExW\(WS_EX_NOACTIVATE \| WS_EX_TOOLWINDOW,.*?" - r"L\"NVDA\", 0, 0, 0, 0, 0,", - source, - re.DOTALL, - )) - self.assertIn("ShowWindow(window, SW_HIDE)", source) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_wine_access_manager.py b/tests/test_wine_access_manager.py deleted file mode 100644 index d80b47d..0000000 --- a/tests/test_wine_access_manager.py +++ /dev/null @@ -1,146 +0,0 @@ -import unittest -from unittest import mock - -from cthulhu.wine_access_manager import PrefixProcess, WineAccessManager - - -class WineAccessManagerTest(unittest.TestCase): - @mock.patch.object(WineAccessManager, "_find_helper", return_value=None) - @mock.patch.object(WineAccessManager, "discover_prefixes") - def test_poll_without_installed_helper_is_a_no_op( - self, discover_prefixes, _find_helper - ): - manager = WineAccessManager(helperPath=None) - - self.assertIsNone(manager.helperPath) - self.assertTrue(manager.poll()) - discover_prefixes.assert_not_called() - self.assertEqual(manager.prefixes, {}) - - def test_prefix_prefers_explicit_wineprefix(self): - environment = { - "WINEPREFIX": "/tmp/custom-prefix", - "STEAM_COMPAT_DATA_PATH": "/tmp/compat", - } - - self.assertEqual( - WineAccessManager._prefix_from_environ(environment), "/tmp/custom-prefix" - ) - - def test_prefix_uses_proton_pfx(self): - environment = {"STEAM_COMPAT_DATA_PATH": "/tmp/compat"} - - self.assertEqual(WineAccessManager._prefix_from_environ(environment), "/tmp/compat/pfx") - - @mock.patch("cthulhu.wine_access_manager.os.access", return_value=True) - @mock.patch( - "cthulhu.wine_access_manager.os.readlink", - return_value="/opt/proton/files/bin/wine64-preloader", - ) - def test_preloader_resolves_to_runtime_loader(self, _readlink, _access): - self.assertEqual( - WineAccessManager._loader_for_process(100, {}), - "/opt/proton/files/bin/wine64", - ) - - @mock.patch("cthulhu.wine_access_manager.subprocess.Popen") - def test_launch_preserves_prefix_and_runtime_loader(self, popen): - process = mock.Mock() - process.poll.return_value = None - popen.return_value = process - manager = WineAccessManager("/usr/bin/cthulhu-wine-access.exe") - state = PrefixProcess() - - manager._ensure_running( - "/tmp/prefix", - state, - {"DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus"}, - "/opt/proton/files/bin/wine64", - 10.0, - ) - - environment = popen.call_args.kwargs["env"] - self.assertEqual(environment["WINEPREFIX"], "/tmp/prefix") - self.assertEqual(environment["WINELOADER"], "/opt/proton/files/bin/wine64") - self.assertEqual(environment[manager.MANAGED_ENVIRONMENT_KEY], "1") - self.assertEqual( - environment["DBUS_SESSION_BUS_ADDRESS"], "unix:path=/run/user/1000/bus" - ) - self.assertEqual(popen.call_args.args[0], ["/usr/bin/cthulhu-wine-access.exe"]) - - @mock.patch("cthulhu.wine_access_manager.subprocess.Popen") - def test_disabled_surfaces_are_passed_to_helper(self, popen): - process = mock.Mock() - process.poll.return_value = None - popen.return_value = process - manager = WineAccessManager("/usr/bin/cthulhu-wine-access.exe") - manager.dialogReaderEnabled = False - manager.controllerEnabled = False - - manager._ensure_running("/tmp/prefix", PrefixProcess(), {}, None, 10.0) - - self.assertEqual( - popen.call_args.args[0], - [ - "/usr/bin/cthulhu-wine-access.exe", - "--no-dialog-reader", - "--no-controller", - ], - ) - - def test_short_lived_helper_gets_restart_backoff(self): - manager = WineAccessManager("/usr/bin/cthulhu-wine-access.exe") - state = PrefixProcess() - state.process = mock.Mock() - state.process.poll.return_value = 0 - state.startedAt = 9.0 - - manager._record_exit(state, 10.0) - - self.assertIsNone(state.process) - self.assertEqual(state.failures, 1) - self.assertEqual(state.nextStart, 12.0) - - @mock.patch.object(WineAccessManager, "_loader_for_process", return_value=None) - @mock.patch.object( - WineAccessManager, - "_read_environ", - return_value={"WINEPREFIX": "/tmp/exported-prefix"}, - ) - @mock.patch("cthulhu.wine_access_manager.Path.iterdir") - @mock.patch("cthulhu.wine_access_manager.os.getuid", return_value=1000) - def test_discovery_ignores_non_wine_processes( - self, _getuid, iterdir, _read_environ, _loader - ): - entry = mock.Mock() - entry.name = "123" - entry.stat.return_value.st_uid = 1000 - iterdir.return_value = [entry] - - self.assertEqual(WineAccessManager("/tmp/helper").discover_prefixes(), {}) - - @mock.patch.object(WineAccessManager, "_loader_for_process") - @mock.patch.object( - WineAccessManager, - "_read_environ", - return_value={ - "WINEPREFIX": "/tmp/prefix", - WineAccessManager.MANAGED_ENVIRONMENT_KEY: "1", - }, - ) - @mock.patch("cthulhu.wine_access_manager.Path.iterdir") - @mock.patch("cthulhu.wine_access_manager.os.getuid", return_value=1000) - def test_discovery_ignores_managed_helper_processes( - self, _getuid, iterdir, _read_environ, loader - ): - entry = mock.Mock() - entry.name = "123" - entry.stat.return_value.st_uid = 1000 - iterdir.return_value = [entry] - - self.assertEqual(WineAccessManager("/tmp/helper").discover_prefixes(), {}) - loader.assert_not_called() - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/test_wnck_session_regressions.py b/tests/test_wnck_session_regressions.py deleted file mode 100644 index 1a9cad5..0000000 --- a/tests/test_wnck_session_regressions.py +++ /dev/null @@ -1,66 +0,0 @@ -import sys -import unittest -from pathlib import Path -from unittest import mock - -import gi - -gi.require_version("Gdk", "3.0") -gi.require_version("Gtk", "3.0") - -sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) - -from cthulhu import wnck_support -from cthulhu.plugins.OCR import plugin as ocr_plugin - - -class WnckSupportTests(unittest.TestCase): - def test_load_wnck_skips_import_when_session_is_wayland(self): - with mock.patch.object( - wnck_support.importlib, - "import_module", - side_effect=AssertionError("import_module should not be called"), - ): - self.assertIsNone(wnck_support.load_wnck(session_type="wayland")) - - def test_load_wnck_imports_wnck_when_session_is_x11(self): - fakeGi = mock.Mock() - fakeWnck = object() - - def importModule(name): - if name == "gi": - return fakeGi - if name == "gi.repository.Wnck": - return fakeWnck - raise AssertionError(f"Unexpected import: {name}") - - with mock.patch.object(wnck_support.importlib, "import_module", side_effect=importModule): - self.assertIs(wnck_support.load_wnck(session_type="x11"), fakeWnck) - - fakeGi.require_version.assert_called_once_with("Wnck", "3.0") - - -class OCRWnckHandlingTests(unittest.TestCase): - def test_check_dependencies_does_not_fail_when_wnck_is_unavailable(self): - testPlugin = ocr_plugin.OCRDesktop.__new__(ocr_plugin.OCRDesktop) - - with ( - mock.patch.object(ocr_plugin, "PIL_AVAILABLE", True), - mock.patch.object(ocr_plugin, "PYTESSERACT_AVAILABLE", True), - mock.patch.object(ocr_plugin, "GTK_AVAILABLE", True), - mock.patch.object(ocr_plugin, "WNCK_AVAILABLE", False), - ): - self.assertTrue(testPlugin._checkDependencies()) - - def test_screen_shot_window_returns_false_when_wnck_is_unavailable(self): - testPlugin = ocr_plugin.OCRDesktop.__new__(ocr_plugin.OCRDesktop) - - with ( - mock.patch.object(ocr_plugin, "GTK_AVAILABLE", True), - mock.patch.object(ocr_plugin, "WNCK_AVAILABLE", False), - ): - self.assertFalse(testPlugin._screenShotWindow()) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/text-preferences.html b/tests/text-preferences.html new file mode 100644 index 0000000..90a58b0 --- /dev/null +++ b/tests/text-preferences.html @@ -0,0 +1,9 @@ + + + +Cthulhu text preferences check +

Text preferences check

+

SQL should be pronounced sequel. Braille should still show SQL.

+

Plain text, bold text, then plain text again.

+

Plain text, underlined text, then plain text again.

+ diff --git a/tests/text_label_fixture.py b/tests/text_label_fixture.py new file mode 100644 index 0000000..c978a19 --- /dev/null +++ b/tests/text_label_fixture.py @@ -0,0 +1,77 @@ +# Copyright (c) 2026 Storm Dragon +# Authors: Storm Dragon, Angus Kola +# SPDX-License-Identifier: GPL-3.0-or-later +"""Native label relationships for private Xvfb/AT-SPI tests.""" +import subprocess +import sys + +import gi + +gi.require_version("Gtk", "3.0") +gi.require_version("Atk", "1.0") +gi.require_version("GdkX11", "3.0") +gi.require_version("Gdk", "3.0") +from gi.repository import Atk, Gdk, GdkX11, GLib, Gtk + + +def main(): + window = Gtk.Window(title="Text label probe") + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + window.add(box) + entries = [] + for text, value, explicitName, protected in ( + ("_Destination:", "", "", False), + ("Display _name:", "Example document", "", False), + ("Visible _label:", "Example value", "Preferred name", False), + ("_Secret:", "private fixture value", "", True), + (None, "Unlabeled value", "", False), + ): + entry = Gtk.Entry() + entry.set_text(value) + entry.set_visibility(not protected) + if explicitName: + entry.get_accessible().set_name(explicitName) + if text: + label = Gtk.Label.new_with_mnemonic(text) + label.set_mnemonic_widget(entry) + box.pack_start(label, False, False, 0) + box.pack_start(entry, False, False, 0) + entries.append(entry) + # Explicit multi-label relations also preserve their provider order. + combined = Gtk.Entry() + for text in ("Account", "identifier"): + label = Gtk.Label(label=text) + box.pack_start(label, False, False, 0) + combined.get_accessible().add_relationship(Atk.RelationType.LABELLED_BY, label.get_accessible()) + box.pack_start(combined, False, False, 0) + entries.append(combined) + summary = Gtk.Entry() + summary.set_text("Example summary") + summary.set_editable(False) + label = Gtk.Label(label="Read-only summary:") + label.set_mnemonic_widget(summary) + box.pack_start(label, False, False, 0) + box.pack_start(summary, False, False, 0) + entries.append(summary) + window.show_all() + Gdk.Display.get_default().sync() + subprocess.run(["xdotool", "windowfocus", str(GdkX11.X11Window.get_xid(window.get_window()))], check=True) + + def command_ready(_source, condition): + if condition & GLib.IO_HUP: + Gtk.main_quit() + return False + line = sys.stdin.readline() + if not line: + Gtk.main_quit() + return False + entries[int(line)].grab_focus() + return True + + GLib.io_add_watch(sys.stdin, GLib.IO_IN | GLib.IO_HUP, command_ready) + GLib.idle_add(lambda: (print("ready", flush=True), False)[1]) + Gtk.main() + + +if __name__ == "__main__": + main() diff --git a/tests/vte_terminal.py b/tests/vte_terminal.py new file mode 100644 index 0000000..fb5489d --- /dev/null +++ b/tests/vte_terminal.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +"""VTE text fixture, including Unicode and trailing empty terminal rows.""" +import gi +import os + +gi.require_version("Gtk", "3.0") +gi.require_version("Vte", "2.91") +from gi.repository import Gtk, Vte + +window = Gtk.Window(title="Cthulhu Tree Probe") +window.connect("destroy", Gtk.main_quit) +terminal = Vte.Terminal() +window.add(terminal) +mode = os.environ.get("CTHULHU_VTE_MODE", "") +if mode == "large": + window.set_default_size(1400, 1000) +else: + window.set_default_size(500, 300) +window.show_all() +if mode == "large": + terminal.feed("\r\n".join(f"Row {row:02d} " + "x" * 140 for row in range(50)).encode()) +elif mode == "prompt": + terminal.feed("Previous output\r\nCafé 猫> ".encode()) +else: + terminal.feed("Café 猫\r\n\r\nSecond line\r\nThird line".encode()) +Gtk.main() diff --git a/tests/window_title_fixture.py b/tests/window_title_fixture.py new file mode 100644 index 0000000..3698cb3 --- /dev/null +++ b/tests/window_title_fixture.py @@ -0,0 +1,75 @@ +"""X11 title fixtures for an isolated Xvfb session; no accessible toolkit.""" +import json +import sys + +from Xlib import X, Xatom, display + + +def main(): + connection = display.Display() + root = connection.screen().root + utf8 = connection.intern_atom("UTF8_STRING") + nameAtom = connection.intern_atom("_NET_WM_NAME") + activeAtom = connection.intern_atom("_NET_ACTIVE_WINDOW") + + def make_window(parent, title, application="example"): + window = parent.create_window(0, 0, 250, 150, 0, + connection.screen().root_depth, + X.InputOutput, X.CopyFromParent) + if title: + window.set_wm_name(title) + window.change_property(nameAtom, utf8, 8, title.encode("utf-8")) + window.set_wm_class(application, application) + window.map() + return window + + normal = make_window(root, "Example title") + desktop = make_window(root, "Wine Desktop") + helper = make_window(desktop, "NVDA", "wine-access.exe") + oldHelper = make_window(desktop, "NVDA", "cthulhu-wine-access.exe") + ime = make_window(desktop, "Default IME") + hidden = make_window(desktop, "Hidden game", "hidden.exe") + hidden.unmap() + game = make_window(desktop, "Wine game", "game.exe") + control = make_window(game, "") + second = make_window(desktop, "Wine dialog", "game.exe") + unrelated = make_window(root, "Unrelated title") + windows = dict(normal=normal, desktop=desktop, helper=helper, oldHelper=oldHelper, ime=ime, + hidden=hidden, game=game, control=control, second=second, + unrelated=unrelated) + root.change_property(activeAtom, Xatom.WINDOW, 32, [normal.id]) + normal.set_input_focus(X.RevertToParent, X.CurrentTime) + connection.sync() + print(json.dumps({key: window.id for key, window in windows.items()}), flush=True) + for line in sys.stdin: + command = json.loads(line) + window = windows[command["window"]] + action = command["action"] + if action == "activate": + root.change_property(activeAtom, Xatom.WINDOW, 32, [window.id]) + window.set_input_focus(X.RevertToParent, X.CurrentTime) + elif action == "focus": + window.set_input_focus(X.RevertToParent, X.CurrentTime) + elif action == "title": + window.change_property(nameAtom, utf8, 8, command["title"].encode("utf-8")) + elif action == "legacy": + window.delete_property(nameAtom) + window.set_wm_name(command["title"]) + elif action == "class": + window.set_wm_class(command["instance"], command["class"]) + elif action == "pid": + window.change_property(connection.intern_atom("_NET_WM_PID"), + Xatom.CARDINAL, 32, [int(command["title"])]) + elif action == "empty": + root.change_property(activeAtom, Xatom.WINDOW, 32, [0]) + elif action == "hide": + window.unmap() + elif action == "destroy": + window.destroy() + connection.sync() + print("ready", flush=True) + connection.close() + + +if __name__ == "__main__": + main() diff --git a/tests/window_titles.md b/tests/window_titles.md new file mode 100644 index 0000000..5fa9240 --- /dev/null +++ b/tests/window_titles.md @@ -0,0 +1,86 @@ +# Window title regression checks + +Wine review focus provides navigation ownership and title metadata. It does +not speak a window activation. The native title controller must introduce +that window once, retain its pending announcement across Wine control focus +updates, and introduce it again after a foreground switch. Title changes +within the window still follow the application's title-change preference. + +Fresh input cancels titles still waiting for their coalescing deadline or an +application override, as well as titles already in the speech queue. Held-key +repeats retain automatic titles; Control and Escape remain explicit stop keys. +Input that initiates a window switch precedes the destination's title and must +not cancel that new introduction. Later title changes remain enabled normally. + +Run the focused checks from the repository root: + +```sh +go test -race ./internal/app -run 'Title|WineReview|XTerm|Foreground' -count=1 +CTHULHU_NATIVE_BROWSER_TESTS=editing GOCACHE=/tmp/cthulhu-go-cache GOPROXY=off python3 tests/native_browser.py +python3 tests/native_test_session.py env CTHULHU_NATIVE_WINDOW_TITLES=1 GOCACHE=/tmp/cthulhu-go-cache GOPROXY=off go test ./internal/app -run '^TestNativeAutomaticTitleDispatchLatency$' -count=1 -v +python3 tests/native_test_session.py env CTHULHU_WINE_TITLE_DBUS=1 go test -race ./internal/app -run '^TestPrivateWineTitleSurvivesReviewFocusBurst$' -count=1 -v +``` + +The private D-Bus test runs the event loop against copied foreground metadata +and a real Wine review registry. It checks that a frame-to-control focus burst +keeps the pending title and that later review revisions do not repeat it. +Unit tests cover both arrival orders, Wine desktop children, returning to the +same window, native application preferences, and XTerm handoff. + +## Read the title on demand + +The desktop command is **Cthulhu+Numpad Enter**; the laptop command is +**Cthulhu+Slash**. Both use the existing copied foreground title metadata, +with the owned accessible window title available when native title metadata +is unavailable. The command reports when no title is available, respects +screen locking and terminal handoff, and does not move focus or the browse +cursor. Automatic title preferences and duplicate suppression do not prevent +an explicit request. Repeated presses repeat the title; status-bar reading +is not implemented. + +```sh +go test ./internal/input ./internal/app -run 'WindowTitle|WhereAmI|CommandRuntimeRoutesFocusPresentationRequests' -count=1 +python3 tests/native_test_session.py env CTHULHU_NATIVE_X11=1 go test ./internal/platform/xorg -run '^TestNativeDispatchBeforeRelease$' -count=1 -v +``` + +The native automatic-title fixture above also checks the desktop title chord +through actual X11 command dispatch and the event loop with automatic changes +disabled. The native command test checks desktop and laptop bindings on press +with both release orders. Event-loop tests check changed titles and preserved +Where Am I focus; a queue test checks Braille flash delivery. + +For live acceptance, use a rebuilt reader after arranging any active reader +replacement with its user. Review and listening are required before submission. + +1. Alt+Tab between a Wine application, an accessible Linux application, and + xterm. Each destination should speak its title once on every return. +2. Tab between controls inside Wine. Controls should speak normally without + repeating the title. Check Wine flat review still follows the focused window. +3. Check Fenrir retains xterm keyboard input and terminal reading. Return to + Linux controls and confirm ordinary focus speech and reader commands work. +4. Repeat with the application's automatic title changes disabled. Window + introductions should still speak; subsequent status/title changes should + stay quiet. With the preference enabled, changed titles should speak once. +5. If used, repeat with a Wine virtual desktop and check title messages on a + physical Braille display. +6. In Brave, use Ctrl+L and immediately type several characters. Each character + should echo and interrupt previous speech without an older title following + it. Repeat while a long title is speaking, and use Control and Escape to stop + it. Switch away and back without typing; the window title must still speak. +7. With automatic title reading enabled, change a page's title and verify it + speaks once. The editing fixture's F8 key changes its title to + "Cthulhu Browser Probe updated". Check address suggestions, deletion, and + native caret movement still announce their usual output. +8. Use Cthulhu+Numpad Enter on desktop or Cthulhu+Slash on laptop in a native + application, a browser page and a Wine application. Confirm the foreground + title is spoken, including an active dialog. Repeat after switching tabs + and windows and after disabling automatic title changes. Repeating the + command should repeat the title. Check the Braille flash if enabled. +9. Navigate to a browser heading, read the title, then continue heading and + arrow navigation in both directions. The reading position must remain + intact. Plain Numpad Enter on desktop or Cthulhu+Enter on laptop should + still describe the focused item. Check learn mode describes the title + command, and confirm its binding can be changed in Preferences. + +Automated queue assertions do not establish physical Alt+Tab, audible speech, +installed-binary behavior, or physical Braille acceptance. diff --git a/tests/wine_review_x11.py b/tests/wine_review_x11.py new file mode 100644 index 0000000..6ada957 --- /dev/null +++ b/tests/wine_review_x11.py @@ -0,0 +1,153 @@ +"""Private-display physical-key driver for the Go Wine review acceptance test.""" +import ctypes +import json +import os +import re +from pathlib import Path +import subprocess +import sys +import tempfile +import time +sys.dont_write_bytecode = True + +from native_x11 import set_active_window, wait_for + +def chord(symbols): + x11 = ctypes.CDLL('libX11.so.6') + xtst = ctypes.CDLL('libXtst.so.6') + x11.XOpenDisplay.argtypes = [ctypes.c_char_p] + x11.XOpenDisplay.restype = ctypes.c_void_p + x11.XKeysymToKeycode.argtypes = [ctypes.c_void_p, ctypes.c_ulong] + x11.XKeysymToKeycode.restype = ctypes.c_ubyte + x11.XSync.argtypes = [ctypes.c_void_p, ctypes.c_int] + x11.XCloseDisplay.argtypes = [ctypes.c_void_p] + xtst.XTestFakeKeyEvent.argtypes = [ctypes.c_void_p, ctypes.c_uint, ctypes.c_int, ctypes.c_ulong] + display = x11.XOpenDisplay(None) + assert display + codes = [x11.XKeysymToKeycode(display, value) for value in symbols] + assert all(codes) + try: + for code in codes: + assert xtst.XTestFakeKeyEvent(display, code, 1, 0) + for code in reversed(codes): + assert xtst.XTestFakeKeyEvent(display, code, 0, 0) + x11.XSync(display, 0) + finally: + x11.XCloseDisplay(display) + +def main(): + build = Path(os.environ['CTHULHU_WINE_REVIEW_BUILD']) + fixture = build / ('review-fixture32.exe' if os.environ.get('CTHULHU_WINE_REVIEW_32') == '1' else 'review-fixture64.exe') + processes = [] + window_manager = None + with tempfile.TemporaryDirectory(prefix='wine-review-keys-') as directory: + if os.environ.get('CTHULHU_WINE_REVIEW_WM') == 'i3': + config=Path(directory)/'i3.conf' + config.write_text('font pango:monospace 10\ndefault_border pixel 2\nfocus_follows_mouse no\n') + window_manager=subprocess.Popen(['i3','-a','-c',str(config)],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL) + wait_for(lambda: '0x' in subprocess.run(['xprop','-root','_NET_SUPPORTING_WM_CHECK'],capture_output=True,text=True).stdout,'private i3 did not start',5) + env = dict(os.environ, WINEPREFIX=str(Path(directory)/'prefix'), WINEDEBUG='-all', WINEDLLOVERRIDES='mscoree,mshtml=', CTHULHU_WINE_ACCESS_MANAGED='1') + secondary_env, secondary_window = None, None + def configure(mode): + subprocess.run(['wine', str(fixture), '--configure', str(mode)],env=env,check=True,timeout=5,stdout=subprocess.DEVNULL) + def activate(): + found = subprocess.run(['xdotool','search','--onlyvisible','--name','^Wine review fixture$'],capture_output=True,text=True) + if not found.stdout.strip():return False + candidates = [int(value) for value in found.stdout.splitlines() if int(value) != secondary_window] + if not candidates:return False + window = candidates[0] + if window_manager is not None: + subprocess.run(['xdotool','windowactivate','--sync',str(window)],check=True) + subprocess.run(['xdotool','windowfocus',str(window)],check=True) + set_active_window(window) + return window + linux = None + def activate_linux(): + nonlocal linux + if linux is None: + source = ('import gi; gi.require_version("Gtk", "3.0"); ' + 'from gi.repository import Gtk, GLib; ' + 'window=Gtk.Window(title="Wine review Linux fixture"); ' + 'window.set_default_size(400,250); view=Gtk.TextView(); ' + 'view.get_buffer().set_text("Linux review ready\\nnext Linux"); ' + 'view.get_buffer().place_cursor(view.get_buffer().get_start_iter()); ' + 'window.add(view); window.show_all(); view.grab_focus(); Gtk.main()') + linux = subprocess.Popen([sys.executable, '-c', source],stdout=subprocess.DEVNULL) + processes.append(linux) + def focus(): + result = subprocess.run(['xdotool','search','--onlyvisible','--name','^Wine review Linux fixture$'],capture_output=True,text=True) + if not result.stdout.strip():return False + window = int(result.stdout.splitlines()[0]) + subprocess.run(['xdotool','windowfocus',str(window)],check=True) + set_active_window(window) + return True + wait_for(focus,'Linux fixture missing',5) + try: + subprocess.run(['wineboot','-u'],env=env,check=True,timeout=45,stdout=subprocess.DEVNULL) + processes.append(subprocess.Popen([str(build/'wine-access.exe'),'--no-controller'],env=env,stdout=subprocess.DEVNULL)) + processes.append(subprocess.Popen(['wine',str(fixture)],env=env,stdout=subprocess.DEVNULL)) + wait_for(activate,'native Wine window missing',10) + window = activate() + diagnostics = subprocess.run(['xprop', '-id', str(window), 'WM_CLASS', '_NET_WM_PID'],capture_output=True,text=True) + print(diagnostics.stdout,file=sys.stderr,flush=True) + match = re.search(r'_NET_WM_PID\(CARDINAL\) = (\d+)', diagnostics.stdout) + if match:print('Wine executable: '+os.readlink('/proc/'+match.group(1)+'/exe'),file=sys.stderr,flush=True) + configure(12) + print(json.dumps({'ready':True}),flush=True) + for line in sys.stdin: + command = json.loads(line) + action = command['action'] + if action == 'keys':chord(command['symbols']) + elif action == 'configure':configure(command['mode']);activate() + elif action == 'check': + subprocess.run(['wine',str(fixture),command.get('check','--check-strict')],env=env,check=True,timeout=5,stdout=subprocess.DEVNULL) + elif action == 'restart-helper': + processes[0].terminate();processes[0].wait(timeout=3) + processes[0]=subprocess.Popen([str(build/'wine-access.exe'),'--no-controller'],env=env,stdout=subprocess.DEVNULL) + elif action == 'linux':activate_linux() + elif action == 'wine':activate() + elif action == 'second-prefix': + known = set(subprocess.run(['xdotool','search','--onlyvisible','--name','^Wine review fixture$'],capture_output=True,text=True).stdout.splitlines()) + secondary_env = dict(env, WINEPREFIX=str(Path(directory)/'second-prefix')) + subprocess.run(['wineboot','-u'],env=secondary_env,check=True,timeout=45,stdout=subprocess.DEVNULL) + processes.append(subprocess.Popen([str(build/'wine-access.exe'),'--no-controller'],env=secondary_env,stdout=subprocess.DEVNULL)) + processes.append(subprocess.Popen(['wine',str(fixture)],env=secondary_env,stdout=subprocess.DEVNULL)) + def focus_second(): + found = subprocess.run(['xdotool','search','--onlyvisible','--name','^Wine review fixture$'],capture_output=True,text=True) + fresh = [value for value in found.stdout.splitlines() if value not in known] + return int(fresh[0]) if fresh else None + secondary_window = wait_for(focus_second,'second-prefix window missing',10) + subprocess.run(['xdotool','windowfocus',str(secondary_window)],check=True) + set_active_window(secondary_window) + elif action == 'virtual-desktop': + # Configure the same default desktop used by winecfg. A + # helper on another named Windows desktop cannot inspect + # this desktop's foreground, even within the same prefix. + subprocess.run(['wine','reg','add',r'HKCU\Software\Wine\Explorer','/v','Desktop','/d','Default','/f'],env=env,check=True,stdout=subprocess.DEVNULL,timeout=5) + subprocess.run(['wine','reg','add',r'HKCU\Software\Wine\Explorer\Desktops','/v','Default','/d','900x700','/f'],env=env,check=True,stdout=subprocess.DEVNULL,timeout=5) + subprocess.run(['wineserver','-k'],env=env,check=True,timeout=5) + processes[0].wait(timeout=3);processes[1].wait(timeout=3) + processes[0]=subprocess.Popen([str(build/'wine-access.exe'),'--no-controller'],env=env,stdout=subprocess.DEVNULL) + processes[1]=subprocess.Popen(['wine',str(fixture)],env=env,stdout=subprocess.DEVNULL) + window = wait_for(activate,'virtual-desktop app missing',10) + result = subprocess.run(['xdotool','search','--onlyvisible','--name','Wine Desktop'],capture_output=True,text=True,check=True) + assert result.stdout.strip(), 'Wine desktop container missing' + subprocess.run(['xdotool','windowfocus',str(window)],check=True) + set_active_window(int(result.stdout.splitlines()[0])) + diagnostics = subprocess.run(['xwininfo','-id',str(window),'-tree'],capture_output=True,text=True) + print(diagnostics.stdout,file=sys.stderr,flush=True) + elif action == 'quit':break + else:raise ValueError(action) + print(json.dumps({'ready':True}),flush=True) + finally: + for process in reversed(processes): + if process.poll() is None: + process.terminate() + try:process.wait(timeout=3) + except subprocess.TimeoutExpired:process.kill();process.wait(timeout=3) + subprocess.run(['wineserver','-k'],env=env,timeout=5) + if secondary_env is not None:subprocess.run(['wineserver','-k'],env=secondary_env,timeout=5) + if window_manager is not None: + window_manager.terminate();window_manager.wait(timeout=3) + +if __name__ == '__main__':main() diff --git a/tests/x11_focus_child.py b/tests/x11_focus_child.py new file mode 100644 index 0000000..a59ce91 --- /dev/null +++ b/tests/x11_focus_child.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +"""Move X input focus into a child of the current test client window.""" + +import ctypes +import sys + + +def main() -> None: + parent = int(sys.argv[1]) + x11 = ctypes.CDLL("libX11.so.6") + x11.XOpenDisplay.argtypes = [ctypes.c_char_p] + x11.XOpenDisplay.restype = ctypes.c_void_p + x11.XCreateSimpleWindow.argtypes = [ + ctypes.c_void_p, ctypes.c_ulong, ctypes.c_int, ctypes.c_int, + ctypes.c_uint, ctypes.c_uint, ctypes.c_uint, + ctypes.c_ulong, ctypes.c_ulong, + ] + x11.XCreateSimpleWindow.restype = ctypes.c_ulong + x11.XMapWindow.argtypes = [ctypes.c_void_p, ctypes.c_ulong] + x11.XSetInputFocus.argtypes = [ + ctypes.c_void_p, ctypes.c_ulong, ctypes.c_int, ctypes.c_ulong, + ] + x11.XSync.argtypes = [ctypes.c_void_p, ctypes.c_int] + x11.XCloseDisplay.argtypes = [ctypes.c_void_p] + + display = x11.XOpenDisplay(None) + if not display: + raise RuntimeError("X11 display unavailable") + try: + child = x11.XCreateSimpleWindow(display, parent, 0, 0, 1, 1, 0, 0, 0) + if not child: + raise RuntimeError("could not create child window") + x11.XMapWindow(display, child) + x11.XSetInputFocus(display, child, 2, 0) # RevertToParent, CurrentTime + x11.XSync(display, 0) + print(child, flush=True) + sys.stdin.readline() + x11.XSetInputFocus(display, parent, 2, 0) + x11.XSync(display, 0) + finally: + x11.XCloseDisplay(display) + + +if __name__ == "__main__": + main() diff --git a/tests/x11_grab_fixture.py b/tests/x11_grab_fixture.py new file mode 100644 index 0000000..54550ff --- /dev/null +++ b/tests/x11_grab_fixture.py @@ -0,0 +1,75 @@ +"""Window-group and transient-popup fixtures for private X11 focus tests.""" + +import json +import os +import sys + +from Xlib import X, Xatom, display + + +connection = display.Display() +root = connection.screen().root +leaderAtom = connection.intern_atom("WM_CLIENT_LEADER") +pidAtom = connection.intern_atom("_NET_WM_PID") +typeAtom = connection.intern_atom("_NET_WM_WINDOW_TYPE") +activeAtom = connection.intern_atom("_NET_ACTIVE_WINDOW") + + +def make_window(parent, x, y, width, height, inputOnly=False, override=False): + window = parent.create_window( + x, y, width, height, 0, 0 if inputOnly else connection.screen().root_depth, + X.InputOnly if inputOnly else X.InputOutput, X.CopyFromParent, + override_redirect=override, + ) + window.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid()]) + return window + + +leader = make_window(root, 0, 0, 1, 1, inputOnly=True) +owner = make_window(root, 20, 30, 600, 400) +grab = make_window(root, -100, -100, 10, 10, inputOnly=True, override=True) +popup = make_window(root, 40, 60, 200, 80, override=True) +other = make_window(root, 700, 30, 100, 100) +for window in [owner, grab, popup]: + window.change_property(leaderAtom, Xatom.WINDOW, 32, [leader.id]) +owner.map() +other.map() + + +def configure(action): + root.delete_property(activeAtom) + popup.change_property(leaderAtom, Xatom.WINDOW, 32, [leader.id]) + popup.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid()]) + popup.change_property(typeAtom, Xatom.ATOM, 32, + [connection.intern_atom("_NET_WM_WINDOW_TYPE_COMBO")]) + popup.set_wm_transient_for(owner) + popup.map() + grab.map() + focus = grab + if action == "hidden": + popup.unmap() + elif action == "other-group": + popup.change_property(leaderAtom, Xatom.WINDOW, 32, [other.id]) + elif action == "other-pid": + popup.change_property(pidAtom, Xatom.CARDINAL, 32, [os.getpid() + 1]) + elif action == "ordinary-window": + popup.change_property(typeAtom, Xatom.ATOM, 32, + [connection.intern_atom("_NET_WM_WINDOW_TYPE_NORMAL")]) + elif action == "no-owner": + popup.delete_property(connection.intern_atom("WM_TRANSIENT_FOR")) + elif action == "foreign-owner": + popup.set_wm_transient_for(other) + elif action == "input-output-focus": + focus = other + elif action == "ewmh": + root.change_property(activeAtom, Xatom.WINDOW, 32, [other.id]) + focus.set_input_focus(X.RevertToParent, X.CurrentTime) + connection.sync() + + +configure("popup") +print(json.dumps(dict(owner=owner.id, grab=grab.id, other=other.id)), flush=True) +for line in sys.stdin: + configure(line.strip()) + print("ready", flush=True) +connection.close() diff --git a/tests/xorg_suspension_probe.c b/tests/xorg_suspension_probe.c new file mode 100644 index 0000000..5bf3e00 --- /dev/null +++ b/tests/xorg_suspension_probe.c @@ -0,0 +1,66 @@ +// Deterministic native queue boundary: a key was captured before suspension, +// but remains in Xlib's queue when the Go owner gives the keyboard back. +#include "commands_native.h" +#include +#include +#include +#include + +int main(int argc, char **argv) { + int error = 0, failed = 0; + CommandDevice *device = open_commands(1, 0, 0, &error); + if (!device) { fprintf(stderr, "open: %d\n", error); return 1; } + if (argc == 2 && strcmp(argv[1], "queued") == 0) { + if (XGrabKeyboard(device->display, device->root, False, + GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) return 1; + device->active = 1; + XEvent event = {0}; + event.xkey.type = KeyPress; + event.xkey.display = device->display; + event.xkey.window = device->root; + event.xkey.keycode = XKeysymToKeycode(device->display, XK_q); + XPutBackEvent(device->display, &event); + release_command_keyboard(device); + set_command_keys(device, 0); + CommandKey key = {0}; + int result = next_command_key(device, &key); + if (result != 0 || device->active) { + fprintf(stderr, "suspended queued key: result=%d active=%d\n", result, device->active); + failed = 1; + } + } else if (argc == 2 && strcmp(argv[1], "passive") == 0) { + Display *sender = XOpenDisplay(NULL); + int code = XKeysymToKeycode(sender, XK_Insert); + XTestFakeKeyEvent(sender, code, True, CurrentTime); + XSync(sender, False); // The synchronous passive grab is now active. + set_command_keys(device, 0); + CommandKey key = {0}; + next_command_key(device, &key); + int status = XGrabKeyboard(sender, DefaultRootWindow(sender), False, + GrabModeAsync, GrabModeAsync, CurrentTime); + if (status != GrabSuccess) { + fprintf(stderr, "suspension left activated passive grab: %d\n", status); + failed = 1; + } + XUngrabKeyboard(sender, CurrentTime); + close_commands(device); + device = NULL; + XTestFakeKeyEvent(sender, code, False, CurrentTime); + XSync(sender, False); + XCloseDisplay(sender); + } else { + set_command_keys(device, 0); + CommandKey keys[2] = {{.pressed = 1}, {.pressed = 0}}; + keys[0].code = keys[1].code = XKeysymToKeycode(device->display, XK_q); + if (replay_command_keys(device, keys, 2) != 0) return 1; + CommandDevice *competitor = open_commands(1, 0, 0, &error); + if (!competitor) { + fprintf(stderr, "replay restored disabled passive grabs: %d\n", error); + failed = 1; + } else { + close_commands(competitor); + } + } + if (device) close_commands(device); + return failed; +} diff --git a/tools/generate_dbus_documentation.py b/tools/generate_dbus_documentation.py deleted file mode 100755 index 7dcfd2f..0000000 --- a/tools/generate_dbus_documentation.py +++ /dev/null @@ -1,477 +0,0 @@ -#!/usr/bin/python -# generate_dbus_documentation.py -# -# Generate markdown documentation for Cthulhu's D-Bus remote controller. -# Must be run while Cthulhu is active with the D-Bus service enabled. -# -# Copyright 2025 Igalia, S.L. -# Author: Joanmarie Diggs -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., Franklin Street, Fifth Floor, -# Boston MA 02110-1301 USA. - -"""Generate markdown documentation for Cthulhu's D-Bus remote controller.""" - -import os -import sys -from dasbus.connection import SessionMessageBus -from dasbus.error import DBusError - - -SERVICE_NAME = "org.stormux.Cthulhu.Service" -SERVICE_PATH = "/org/stormux/Cthulhu/Service" - - -def get_system_commands(proxy): - """Get system-level commands from the main service interface.""" - try: - commands = proxy.ListCommands() - return sorted(commands, key=lambda x: x[0]) - except DBusError as e: - print(f"Error getting system commands: {e}", file=sys.stderr) - return [] - - -def get_modules(proxy): - """Get list of registered modules.""" - try: - modules = proxy.ListModules() - return sorted(modules) - except DBusError as e: - print(f"Error getting modules: {e}", file=sys.stderr) - return [] - - -def get_module_info(bus, module_name): - """Get all commands, parameterized commands, getters, and setters for a module.""" - object_path = f"{SERVICE_PATH}/{module_name}" - - try: - module_proxy = bus.get_proxy(SERVICE_NAME, object_path) - - commands = module_proxy.ListCommands() - parameterized_commands = module_proxy.ListParameterizedCommands() - getters = module_proxy.ListRuntimeGetters() - setters = module_proxy.ListRuntimeSetters() - - return { - "commands": sorted(commands, key=lambda x: x[0]), - "parameterized_commands": sorted(parameterized_commands, key=lambda x: x[0]), - "getters": sorted(getters, key=lambda x: x[0]), - "setters": sorted(setters, key=lambda x: x[0]) - } - except DBusError as e: - print(f"Error getting info for module {module_name}: {e}", file=sys.stderr) - return { - "commands": [], - "parameterized_commands": [], - "getters": [], - "setters": [] - } - - -def format_system_commands(commands): - """Format system-level commands as markdown.""" - lines = [] - lines.append("## Service-Level Commands") - lines.append("") - lines.append( - "These commands are available directly on the main service object " - "at `/org/stormux/Cthulhu/Service`." - ) - lines.append("") - - for name, description in commands: - lines.append(f"- **`{name}`:** {description}") - - lines.append("") - return "\n".join(lines) - - -def _group_structural_navigator_commands(commands): - """Group structural navigator commands by object type.""" - groups = {} - other = [] - - def normalize_obj_type(obj_type): # pylint: disable=too-many-return-statements - """Convert to a canonical form for grouping.""" - - # Group all heading commands together. Ditto for link commands. - if obj_type.startswith("Heading"): - return "Heading" - if "Link" in obj_type: - return "Link" - - # Common plural patterns - if obj_type.endswith("ies"): # Entries -> Entry - return obj_type[:-3] + "y" - if obj_type.endswith("xes"): # Checkboxes -> Checkbox - return obj_type[:-2] - if obj_type.endswith("shes") or obj_type.endswith("ches"): # Matches -> Match - return obj_type[:-2] - if obj_type.endswith("s") and not obj_type.endswith("ss"): - return obj_type[:-1] - return obj_type - - for name, description in commands: - # Extract the object type from command names like NextHeading, ListButtons, etc. - if name.startswith("Next") or name.startswith("Previous"): - prefix = "Next" if name.startswith("Next") else "Previous" - obj_type = name[len(prefix):] - normalized = normalize_obj_type(obj_type) - if normalized not in groups: - if normalized == "Heading": - display = "Headings" - elif not obj_type.endswith("s"): - display = obj_type + "s" - else: - display = obj_type - groups[normalized] = {"commands": [], "display_name": display} - groups[normalized]["commands"].append((name, description)) - elif name.startswith("List"): - obj_type = name[4:] - normalized = normalize_obj_type(obj_type) - if normalized not in groups: - display = "Headings" if normalized == "Heading" else obj_type - groups[normalized] = {"commands": [], "display_name": display} - else: - current_display = groups[normalized]["display_name"] - if not current_display.endswith("s") or normalized == "Heading": - new_display = "Headings" if normalized == "Heading" else obj_type - groups[normalized]["display_name"] = new_display - groups[normalized]["commands"].append((name, description)) - else: - # Other commands like ContainerStart, CycleMode - other.append((name, description)) - - return groups, other - -# pylint: disable-next=too-many-branches,too-many-statements,too-many-locals -def format_module_commands(module_name, info): - """Format module-level commands as markdown.""" - - lines = [] - lines.append(f"### {module_name}") - lines.append("") - lines.append(f"**Object Path:** `/org/stormux/Cthulhu/Service/{module_name}`") - lines.append("") - - # Commands - special handling for certain modules - if info["commands"]: - lines.append("#### Commands") - lines.append("") - lines.append("**Method:** `org.stormux.Cthulhu.Module.ExecuteCommand`") - lines.append("") - lines.append( - "**Parameters:** `CommandName` (string), " - "[`NotifyUser`](README-REMOTE-CONTROLLER.md#user-notification-applicability) (boolean)" - ) - lines.append("") - - if module_name == "SpeechAndVerbosityManager": - # Group related increase/decrease commands - def sort_speech_commands(cmd_tuple): - name, _ = cmd_tuple - # Define groups and their order - groups = { - "Rate": 0, "Pitch": 1, "Volume": 2, - } - # Check if it's an Increase/Decrease command - for group_name, group_order in groups.items(): - if group_name in name: - if name.startswith("Increase"): - return (group_order, 0, name) - if name.startswith("Decrease"): - return (group_order, 1, name) - # Other commands go at the end, sorted alphabetically - return (100, 0, name) - - sorted_commands = sorted(info["commands"], key=sort_speech_commands) - for name, description in sorted_commands: - lines.append(f"- **`{name}`:** {description}") - lines.append("") - - elif module_name == "FlatReviewPresenter": - # Group Go commands at the top - def sort_flat_review_commands(cmd_tuple): - name, _ = cmd_tuple - if name.startswith("Go"): - return (0, name) - return (1, name) - - sorted_commands = sorted(info["commands"], key=sort_flat_review_commands) - for name, description in sorted_commands: - lines.append(f"- **`{name}`:** {description}") - lines.append("") - - elif module_name == "CaretNavigator": - # Group related navigation commands - def sort_caret_commands(cmd_tuple): - name, _ = cmd_tuple - # Define groups for Character, Word, Line, File - if "Character" in name: - group = 0 - elif "Word" in name: - group = 1 - elif "Line" in name: - group = 2 - elif "File" in name: - group = 3 - else: - group = 100 - - # Within each group: Next, Previous, Start, End, Toggle - if name.startswith("Next"): - order = 0 - elif name.startswith("Previous"): - order = 1 - elif name.startswith("Start"): - order = 0 - elif name.startswith("End"): - order = 1 - elif name.startswith("Toggle"): - order = 2 - else: - order = 99 - - return (group, order, name) - - sorted_commands = sorted(info["commands"], key=sort_caret_commands) - for name, description in sorted_commands: - lines.append(f"- **`{name}`:** {description}") - lines.append("") - - elif module_name == "StructuralNavigator": - groups, other = _group_structural_navigator_commands(info["commands"]) - - # Show grouped commands by object type first - for obj_type in sorted(groups.keys()): - cmds = groups[obj_type] - display_name = cmds["display_name"] - lines.append(f"##### {display_name}") - lines.append("") - - # Sort commands in a specific order: Next, Previous, List, grouped by variant - def sort_key(cmd_tuple): - name, _ = cmd_tuple - # Extract base command and any suffix (like Level1, UnvisitedLink, etc.) - if name.startswith("Next"): - prefix_order = 0 - suffix = name[4:] # Remove "Next" - elif name.startswith("Previous"): - prefix_order = 1 - suffix = name[8:] # Remove "Previous" - elif name.startswith("List"): - prefix_order = 2 - suffix = name[4:] # Remove "List" - else: - prefix_order = 3 - suffix = name - - # Extract level number or variant for proper ordering - level_or_variant = 0 - - if "Level" in suffix: - # For headings: extract level number - try: - level_or_variant = int(suffix.split("Level")[1]) - except (IndexError, ValueError): - pass - elif "Unvisited" in suffix: - # For links: Unvisited comes after base - level_or_variant = 1 - elif "Visited" in suffix: - # For links: Visited comes after Unvisited - level_or_variant = 2 - - return (level_or_variant, prefix_order, name) - - sorted_commands = sorted(cmds["commands"], key=sort_key) - for name, desc in sorted_commands: - lines.append(f"- **`{name}`:** {desc}") - lines.append("") - - # Show uncategorized commands at the end - if other: - lines.append("##### Other") - lines.append("") - for name, description in other: - lines.append(f"- **`{name}`:** {description}") - lines.append("") - else: - for name, description in info["commands"]: - lines.append(f"- **`{name}`:** {description}") - lines.append("") - - # Parameterized Commands - if info["parameterized_commands"]: - lines.append("#### Parameterized Commands") - lines.append("") - lines.append("**Method:** `org.stormux.Cthulhu.Module.ExecuteParameterizedCommand`") - lines.append("") - for name, description, parameters in info["parameterized_commands"]: - param_list = ", ".join([f"`{pname}` ({ptype})" for pname, ptype in parameters]) - if param_list: - lines.append(f"- **`{name}`:** {description} Parameters: {param_list}") - else: - lines.append(f"- **`{name}`:** {description}") - lines.append("") - - # Runtime Settings (combine getters and setters) - if info["getters"] or info["setters"]: - lines.append("#### Settings") - lines.append("") - lines.append("**Methods:** `org.stormux.Cthulhu.Module.ExecuteRuntimeGetter` / `org.stormux.Cthulhu.Module.ExecuteRuntimeSetter`") - lines.append("") - lines.append( - "**Parameters:** `PropertyName` (string), " - "`Value` (variant, setter only)" - ) - lines.append("") - - # Build a merged dictionary of properties - # Prefer setter descriptions as they may contain range/default info - properties = {} - for name, description in info["getters"]: - properties[name] = {"description": description, "getter": True, "setter": False} - for name, description in info["setters"]: - if name in properties: - properties[name]["setter"] = True - properties[name]["description"] = description - else: - properties[name] = {"description": description, "getter": False, "setter": True} - - # Output sorted properties with annotations - for name in sorted(properties.keys()): - prop = properties[name] - description = prop["description"] - annotation = "" - - if prop["getter"] and not prop["setter"]: - annotation = " (getter only)" - elif prop["setter"] and not prop["getter"]: - annotation = " (setter only)" - else: - # Both getter and setter - change "Returns" or "Sets" to "Gets/Sets" - if description.startswith("Returns "): - description = description.replace("Returns ", "Gets/Sets ", 1) - elif description.startswith("Sets "): - description = description.replace("Sets ", "Gets/Sets ", 1) - - lines.append(f"- **`{name}`:** {description}{annotation}") - lines.append("") - - return "\n".join(lines) - - -def generate_documentation(): - """Generate the complete documentation.""" - try: - bus = SessionMessageBus() - except DBusError as e: - print(f"Error connecting to D-Bus: {e}", file=sys.stderr) - return None - - try: - proxy = bus.get_proxy(SERVICE_NAME, SERVICE_PATH) - except DBusError as e: - print(f"Error connecting to Cthulhu service: {e}", file=sys.stderr) - print("Make sure Cthulhu is running with the D-Bus service enabled.", file=sys.stderr) - return None - - system_commands = get_system_commands(proxy) - modules = get_modules(proxy) - module_infos = {} - for module_name in modules: - module_infos[module_name] = get_module_info(bus, module_name) - - total_commands = len(system_commands) - total_commands += sum(len(info["commands"]) for info in module_infos.values()) - total_commands += sum(len(info["parameterized_commands"]) for info in module_infos.values()) - total_getters = sum(len(info["getters"]) for info in module_infos.values()) - total_setters = sum(len(info["setters"]) for info in module_infos.values()) - - lines = [] - lines.append("# Cthulhu D-Bus Service Commands Reference") - lines.append("") - lines.append( - f"This document lists all commands ({total_commands}), " - f"runtime getters ({total_getters}), and runtime setters ({total_setters}) available" - ) - lines.append("via Cthulhu's D-Bus Remote Controller interface.") - lines.append("") - lines.append("The service can be accessed at:") - lines.append("") - lines.append("- **Service Name:** `org.stormux.Cthulhu.Service`") - lines.append("- **Main Object Path:** `/org/stormux/Cthulhu/Service`") - lines.append("- **Module Object Paths:** `/org/stormux/Cthulhu/Service/ModuleName`") - lines.append("") - lines.append( - "Additional information about using the remote controller can be found in " - "[README-REMOTE-CONTROLLER.md](README-REMOTE-CONTROLLER.md)." - ) - lines.append("") - lines.append("---") - lines.append("") - - # System commands - lines.append(format_system_commands(system_commands)) - lines.append("---") - lines.append("") - - # Module commands - lines.append("## Modules") - lines.append("") - lines.append( - "Each module exposes commands, getters, and setters on its object " - "at `/org/stormux/Cthulhu/Service/ModuleName`." - ) - lines.append("") - - for module_name in modules: - lines.append(format_module_commands(module_name, module_infos[module_name])) - lines.append("---") - lines.append("") - - return "\n".join(lines) - - -def main(): - """Main entry point.""" - - # Write to parent directory since script is in tools/ - script_dir = os.path.dirname(os.path.abspath(__file__)) - parent_dir = os.path.dirname(script_dir) - output_file = os.path.join(parent_dir, "REMOTE-CONTROLLER-COMMANDS.md") - - print("Generating D-Bus documentation...", file=sys.stderr) - documentation = generate_documentation() - - if documentation is None: - print("Failed to generate documentation.", file=sys.stderr) - return 1 - - try: - with open(output_file, "w", encoding="utf-8") as f: - f.write(documentation) - print(f"Documentation written to {output_file}", file=sys.stderr) - return 0 - except IOError as e: - print(f"Error writing to {output_file}: {e}", file=sys.stderr) - return 1 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/wine-access/CMakeLists.txt b/wine-access/CMakeLists.txt deleted file mode 100644 index cdc2b4c..0000000 --- a/wine-access/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(cthulhu_wine_access LANGUAGES C CXX) - -include(GNUInstallDirs) -find_package(PkgConfig REQUIRED) -pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) -find_program(WIDL_EXECUTABLE widl REQUIRED) - -set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") -set(generated_header "${generated_dir}/nvdaController.h") -set(generated_server "${generated_dir}/nvdaController_s.c") -file(MAKE_DIRECTORY "${generated_dir}") - -add_custom_command( - OUTPUT "${generated_header}" "${generated_server}" - COMMAND "${WIDL_EXECUTABLE}" --win64 -h -H "${generated_header}" - -s -S "${generated_server}" "${CMAKE_CURRENT_SOURCE_DIR}/nvdaController.idl" - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/nvdaController.idl" - VERBATIM) - -add_executable(cthulhu-wine-access main.cpp "${generated_server}") -target_compile_features(cthulhu-wine-access PRIVATE cxx_std_20) -target_include_directories(cthulhu-wine-access PRIVATE "${generated_dir}") -target_link_libraries(cthulhu-wine-access PRIVATE - PkgConfig::GIO oleacc ole32 oleaut32 rpcrt4 user32) -target_link_options(cthulhu-wine-access PRIVATE -mwindows) -target_compile_options(cthulhu-wine-access PRIVATE - $<$:-Wall -Wextra>) - -install(TARGETS cthulhu-wine-access RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") diff --git a/wine-access/main.cpp b/wine-access/main.cpp deleted file mode 100644 index 67a3d17..0000000 --- a/wine-access/main.cpp +++ /dev/null @@ -1,555 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later - -#include "nvdaController.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace { -constexpr auto BUS_NAME = "org.stormux.Cthulhu1.Service"; -constexpr auto OBJECT_PATH = "/org/stormux/Cthulhu1/Service"; -constexpr auto INTERFACE_NAME = "org.stormux.Cthulhu1.Service"; -constexpr int DBUS_TIMEOUT_MS = 500; -GDBusConnection *connection = nullptr; - -struct ControlDescription { - std::string name; - std::string role; - std::string value; - std::string states; - std::string description; - int position = 0; - int count = 0; -}; - -std::string to_utf8(const wchar_t *text) { - if (text == nullptr) - return {}; - GError *error = nullptr; - gchar *converted = g_utf16_to_utf8(reinterpret_cast(text), - -1, nullptr, nullptr, &error); - if (error != nullptr) - g_error_free(error); - if (converted == nullptr) - return {}; - std::string result{converted}; - g_free(converted); - return result; -} - -DWORD call_boolean(const char *method, GVariant *parameters) { - if (connection == nullptr) - return ERROR_SERVICE_NOT_ACTIVE; - GError *error = nullptr; - GVariant *reply = g_dbus_connection_call_sync( - connection, BUS_NAME, OBJECT_PATH, INTERFACE_NAME, method, parameters, - G_VARIANT_TYPE("(b)"), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT_MS, nullptr, - &error); - if (error != nullptr) - g_error_free(error); - if (reply == nullptr) - return ERROR_GEN_FAILURE; - gboolean result = FALSE; - g_variant_get(reply, "(b)", &result); - g_variant_unref(reply); - return result == TRUE ? ERROR_SUCCESS : ERROR_GEN_FAILURE; -} - -bool cthulhu_is_available() { - GError *error = nullptr; - GVariant *reply = g_dbus_connection_call_sync( - connection, "org.freedesktop.DBus", "/org/freedesktop/DBus", - "org.freedesktop.DBus", "NameHasOwner", g_variant_new("(s)", BUS_NAME), - G_VARIANT_TYPE("(b)"), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT_MS, nullptr, - &error); - if (error != nullptr) - g_error_free(error); - if (reply == nullptr) - return false; - gboolean owned = FALSE; - g_variant_get(reply, "(b)", &owned); - g_variant_unref(reply); - return owned == TRUE; -} - -std::string variant_text(const VARIANT &value) { - if (value.vt == VT_BSTR) - return to_utf8(value.bstrVal); - if (value.vt == VT_I4) { - wchar_t buffer[128] = {}; - if (GetRoleTextW(value.lVal, buffer, 128) > 0) - return to_utf8(buffer); - return std::to_string(value.lVal); - } - return {}; -} - -std::string accessible_property( - IAccessible *accessible, - HRESULT (STDMETHODCALLTYPE IAccessible::*getter)(VARIANT, BSTR *), - const VARIANT &child) { - BSTR value = nullptr; - const HRESULT result = (accessible->*getter)(child, &value); - if (FAILED(result) || value == nullptr) - return {}; - const std::string text = to_utf8(value); - SysFreeString(value); - return text; -} - -// Standard-control queries follow the LGPL wine-a11y reader published by -// Mudb0y, while presentation remains on Cthulhu's D-Bus interface. -void tidy_text(wchar_t *text, bool label = false) { - wchar_t *output = text; - for (wchar_t *input = text; *input != L'\0'; ++input) { - if (*input != L'&') - *output++ = *input; - } - *output = L'\0'; - if (label && output > text && output[-1] == L':') - output[-1] = L'\0'; -} - -bool get_control_text(HWND window, wchar_t *text, int capacity) { - DWORD_PTR result = 0; - text[0] = L'\0'; - if (!SendMessageTimeoutW(window, WM_GETTEXT, capacity, - reinterpret_cast(text), SMTO_ABORTIFHUNG, - 200, &result)) - return false; - tidy_text(text); - return text[0] != L'\0'; -} - -void find_control_label(HWND window, wchar_t *text, int capacity) { - HWND previous = window; - wchar_t className[64] = {}; - text[0] = L'\0'; - for (int hop = 0; hop < 3; ++hop) { - previous = GetWindow(previous, GW_HWNDPREV); - if (previous == nullptr || - !GetClassNameW(previous, className, std::size(className))) - return; - if (wcscmp(className, L"Static") != 0 && wcscmp(className, L"Button") != 0) - continue; - if (get_control_text(previous, text, capacity)) - tidy_text(text, true); - return; - } -} - -std::string window_title(HWND window) { - wchar_t title[512] = {}; - GetWindowTextW(GetAncestor(window, GA_ROOT), title, std::size(title)); - tidy_text(title); - return to_utf8(title); -} - -std::string source_id(HWND window, const char *suffix) { - return std::to_string(reinterpret_cast(window)) + ":" + - suffix; -} - -bool present_accessible_event(const std::string &sourceId, - const char *eventType, - const ControlDescription &control, - const std::string &windowTitle) { - return call_boolean("PresentAccessibleEvent", - g_variant_new( - "(sssssssiis)", sourceId.c_str(), eventType, - control.name.c_str(), control.role.c_str(), - control.value.c_str(), control.states.c_str(), - control.description.c_str(), control.position, - control.count, windowTitle.c_str())) == ERROR_SUCCESS; -} - -ControlDescription describe_standard_control(HWND window) { - ControlDescription control; - wchar_t className[64] = {}; - wchar_t text[512] = {}; - wchar_t label[256] = {}; - if (!GetClassNameW(window, className, std::size(className))) - return control; - get_control_text(window, text, std::size(text)); - - if (wcscmp(className, L"Button") == 0) { - control.name = to_utf8(text); - const LONG_PTR style = GetWindowLongPtrW(window, GWL_STYLE); - DWORD_PTR checked = 0; - switch (style & BS_TYPEMASK) { - case BS_CHECKBOX: - case BS_AUTOCHECKBOX: - case BS_3STATE: - case BS_AUTO3STATE: - control.role = "check box"; - SendMessageTimeoutW(window, BM_GETCHECK, 0, 0, SMTO_ABORTIFHUNG, 200, - &checked); - control.description = checked == BST_CHECKED ? "checked" - : checked == BST_INDETERMINATE ? "half checked" - : "not checked"; - break; - case BS_RADIOBUTTON: - case BS_AUTORADIOBUTTON: - control.role = "radio button"; - SendMessageTimeoutW(window, BM_GETCHECK, 0, 0, SMTO_ABORTIFHUNG, 200, - &checked); - control.description = checked == BST_CHECKED ? "checked" : "not checked"; - break; - case BS_GROUPBOX: - control.role = "grouping"; - break; - default: - control.role = "button"; - } - return control; - } - - const bool isEdit = wcscmp(className, L"Edit") == 0 || - wcscmp(className, L"RICHEDIT50W") == 0 || - wcscmp(className, L"RichEdit20W") == 0 || - wcscmp(className, L"RichEdit20A") == 0; - if (isEdit) { - find_control_label(window, label, std::size(label)); - control.name = to_utf8(label); - const LONG_PTR style = GetWindowLongPtrW(window, GWL_STYLE); - control.role = style & ES_READONLY ? "read only edit" : "edit"; - if (style & ES_PASSWORD) - control.description = "password"; - else - control.value = to_utf8(text); - return control; - } - - if (wcscmp(className, L"ComboBox") == 0 || - wcscmp(className, L"ComboBoxEx32") == 0) { - find_control_label(window, label, std::size(label)); - control.name = to_utf8(label); - control.role = "combo box"; - control.value = to_utf8(text); - return control; - } - - if (wcscmp(className, L"ListBox") == 0 || - wcscmp(className, L"ComboLBox") == 0) { - find_control_label(window, label, std::size(label)); - control.name = to_utf8(label); - control.role = "list"; - DWORD_PTR selected = static_cast(-1); - DWORD_PTR count = 0; - DWORD_PTR length = 0; - SendMessageTimeoutW(window, LB_GETCOUNT, 0, 0, SMTO_ABORTIFHUNG, 200, - &count); - SendMessageTimeoutW(window, LB_GETCURSEL, 0, 0, SMTO_ABORTIFHUNG, 200, - &selected); - const LONG_PTR style = GetWindowLongPtrW(window, GWL_STYLE); - const bool stringItems = - !(style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) || - (style & LBS_HASSTRINGS); - if (static_cast(selected) >= 0) { - SendMessageTimeoutW(window, LB_GETTEXTLEN, selected, 0, SMTO_ABORTIFHUNG, - 200, &length); - if (stringItems && length < std::size(text) && - SendMessageTimeoutW(window, LB_GETTEXT, selected, - reinterpret_cast(text), SMTO_ABORTIFHUNG, - 200, &length)) { - tidy_text(text); - control.value = to_utf8(text); - } - control.position = static_cast(selected) + 1; - } - if (static_cast(count) >= 0) - control.count = static_cast(count); - return control; - } - - if (wcscmp(className, L"msctls_trackbar32") == 0) { - find_control_label(window, label, std::size(label)); - control.name = to_utf8(label); - control.role = "slider"; - DWORD_PTR position = 0; - SendMessageTimeoutW(window, TBM_GETPOS, 0, 0, SMTO_ABORTIFHUNG, 200, - &position); - control.value = std::to_string(static_cast(position)); - return control; - } - - if (wcscmp(className, L"Static") == 0) { - control.name = to_utf8(text); - control.role = "static text"; - return control; - } - - control.name = to_utf8(text); - return control; -} - -bool present_standard_focus(HWND window) { - const ControlDescription control = describe_standard_control(window); - if (control.name.empty() && control.role.empty() && control.value.empty() && - control.description.empty()) - return false; - return present_accessible_event(source_id(window, "standard"), "focus", - control, window_title(window)); -} - -void CALLBACK winevent_callback(HWINEVENTHOOK, DWORD event, HWND window, - LONG objectId, LONG childId, DWORD, DWORD) { - if (event != EVENT_OBJECT_FOCUS && event != EVENT_OBJECT_NAMECHANGE && - event != EVENT_OBJECT_VALUECHANGE && event != EVENT_OBJECT_SELECTION && - event != EVENT_OBJECT_STATECHANGE) - return; - IAccessible *accessible = nullptr; - VARIANT child{}; - VariantInit(&child); - if (FAILED(AccessibleObjectFromEvent(window, objectId, childId, &accessible, - &child)) || - accessible == nullptr) { - if (event == EVENT_OBJECT_FOCUS) - present_standard_focus(window); - return; - } - - const std::string name = - accessible_property(accessible, &IAccessible::get_accName, child); - const std::string value = - accessible_property(accessible, &IAccessible::get_accValue, child); - const std::string description = - accessible_property(accessible, &IAccessible::get_accDescription, child); - VARIANT role{}; - VariantInit(&role); - std::string roleText; - if (SUCCEEDED(accessible->get_accRole(child, &role))) - roleText = variant_text(role); - VariantClear(&role); - VARIANT state{}; - VariantInit(&state); - std::string stateText; - if (SUCCEEDED(accessible->get_accState(child, &state))) - stateText = variant_text(state); - VariantClear(&state); - LONG childCount = 0; - accessible->get_accChildCount(&childCount); - accessible->Release(); - VariantClear(&child); - - if (event == EVENT_OBJECT_FOCUS && name.empty() && value.empty() && - description.empty() && (roleText.empty() || roleText == "client") && - present_standard_focus(window)) - return; - - const std::string windowTitle = window_title(window); - const std::string sourceId = - std::to_string(reinterpret_cast(window)) + ":" + - std::to_string(objectId) + ":" + std::to_string(childId); - const char *eventType = nullptr; - switch (event) { - case EVENT_OBJECT_FOCUS: - eventType = "focus"; - break; - case EVENT_OBJECT_NAMECHANGE: - eventType = "name"; - break; - case EVENT_OBJECT_VALUECHANGE: - eventType = "value"; - break; - case EVENT_OBJECT_SELECTION: - eventType = "selection"; - break; - case EVENT_OBJECT_STATECHANGE: - eventType = "state"; - break; - default: - return; - } - ControlDescription control; - control.name = name; - control.role = roleText; - control.value = value; - control.states = stateText; - control.description = description; - control.count = static_cast(childCount); - present_accessible_event(sourceId, eventType, control, windowTitle); -} - -void reset_rpc_server() { - RpcMgmtStopServerListening(nullptr); - RpcServerUnregisterIf(nullptr, nullptr, FALSE); -} - -bool register_rpc_server() { - if (RpcServerUseProtseqEpW( - reinterpret_cast(const_cast(L"ncalrpc")), - RPC_C_PROTSEQ_MAX_REQS_DEFAULT, - reinterpret_cast(const_cast(L"NvdaCtlr")), - nullptr) != RPC_S_OK) - return false; - DWORD sessionId = 0; - if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId)) { - reset_rpc_server(); - return false; - } - wchar_t desktopName[256] = {}; - DWORD bytesNeeded = 0; - if (!GetUserObjectInformationW(GetThreadDesktop(GetCurrentThreadId()), - UOI_NAME, desktopName, sizeof(desktopName), - &bytesNeeded)) { - reset_rpc_server(); - return false; - } - wchar_t endpoint[512] = {}; - wsprintfW(endpoint, L"NvdaCtlr.%lu.%s", sessionId, desktopName); - if (RpcServerUseProtseqEpW( - reinterpret_cast(const_cast(L"ncalrpc")), - RPC_C_PROTSEQ_MAX_REQS_DEFAULT, reinterpret_cast(endpoint), - nullptr) != RPC_S_OK) { - reset_rpc_server(); - return false; - } - for (RPC_IF_HANDLE spec : - {NvdaController_v1_0_s_ifspec, NvdaController2_v1_0_s_ifspec, - NvdaController3_v1_0_s_ifspec}) { - if (RpcServerRegisterIf(spec, nullptr, nullptr) != RPC_S_OK) { - reset_rpc_server(); - return false; - } - } - if (RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE) == RPC_S_OK) - return true; - - reset_rpc_server(); - return false; -} -} // namespace - -extern "C" void *__RPC_USER MIDL_user_allocate(size_t size) { - return malloc(size); -} -extern "C" void __RPC_USER MIDL_user_free(void *pointer) { free(pointer); } - -extern "C" error_status_t __stdcall testIfRunning(void) { - return cthulhu_is_available() ? ERROR_SUCCESS : ERROR_SERVICE_NOT_ACTIVE; -} -extern "C" error_status_t __stdcall speakText(const wchar_t *text) { - const std::string utf8 = to_utf8(text); - // Tolk calls cancelSpeech separately when its interrupt argument is true. - return call_boolean("SpeakText", g_variant_new("(sb)", utf8.c_str(), FALSE)); -} -extern "C" error_status_t __stdcall cancelSpeech(void) { - return call_boolean("CancelSpeech", nullptr); -} -extern "C" error_status_t __stdcall brailleMessage(const wchar_t *text) { - const std::string utf8 = to_utf8(text); - return call_boolean("BrailleMessage", g_variant_new("(s)", utf8.c_str())); -} -extern "C" error_status_t __stdcall getProcessId(ULONG *pid) { - if (pid == nullptr) - return ERROR_INVALID_PARAMETER; - *pid = GetCurrentProcessId(); - return ERROR_SUCCESS; -} -extern "C" error_status_t __stdcall speakSsml(const wchar_t *ssml, SYMBOL_LEVEL, - SPEECH_PRIORITY, boolean) { - const std::string utf8 = to_utf8(ssml); - GError *error = nullptr; - GVariant *reply = g_dbus_connection_call_sync( - connection, BUS_NAME, OBJECT_PATH, INTERFACE_NAME, "SpeakSsml", - g_variant_new("(ss)", "wine-nvda-controller", utf8.c_str()), - G_VARIANT_TYPE("(i)"), G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT_MS, nullptr, - &error); - if (error != nullptr) - g_error_free(error); - if (reply == nullptr) - return ERROR_GEN_FAILURE; - gint result = ERROR_GEN_FAILURE; - g_variant_get(reply, "(i)", &result); - g_variant_unref(reply); - return static_cast(result); -} -extern "C" error_status_t __stdcall onSsmlMarkReached(const wchar_t *) { - return ERROR_CALL_NOT_IMPLEMENTED; -} -extern "C" error_status_t __stdcall isSpeaking(boolean *speaking) { - if (speaking == nullptr) - return ERROR_INVALID_PARAMETER; - *speaking = FALSE; - return ERROR_CALL_NOT_IMPLEMENTED; -} - -int WINAPI WinMain(HINSTANCE instance, HINSTANCE, char *, int) { - const wchar_t *commandLine = GetCommandLineW(); - const bool dialogReaderEnabled = - wcsstr(commandLine, L"--no-dialog-reader") == nullptr; - const bool controllerEnabled = - wcsstr(commandLine, L"--no-controller") == nullptr; - if (!dialogReaderEnabled && !controllerEnabled) - return 0; - - HANDLE singleton = - CreateMutexW(nullptr, TRUE, L"Local\\cthulhu-wine-access-singleton"); - if (singleton == nullptr) - return 1; - if (GetLastError() == ERROR_ALREADY_EXISTS) { - CloseHandle(singleton); - return 0; - } - - GError *error = nullptr; - connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, &error); - if (error != nullptr) - g_error_free(error); - if (connection == nullptr || !cthulhu_is_available()) { - CloseHandle(singleton); - return 1; - } - - HWND window = nullptr; - bool controllerActive = false; - if (controllerEnabled && - FindWindowW(L"wxWindowClassNR", L"NVDA") == nullptr) { - WNDCLASSW windowClass{}; - windowClass.lpfnWndProc = DefWindowProcW; - windowClass.hInstance = instance; - windowClass.lpszClassName = L"wxWindowClassNR"; - RegisterClassW(&windowClass); - window = CreateWindowExW(WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW, - windowClass.lpszClassName, L"NVDA", 0, 0, 0, 0, 0, - nullptr, nullptr, instance, nullptr); - if (window != nullptr) { - ShowWindow(window, SW_HIDE); - controllerActive = register_rpc_server(); - } - } - if (!controllerActive && window != nullptr) { - DestroyWindow(window); - window = nullptr; - } - - HWINEVENTHOOK hook = nullptr; - if (dialogReaderEnabled) - hook = SetWinEventHook(EVENT_MIN, EVENT_MAX, nullptr, winevent_callback, 0, - 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); - MSG message{}; - while (GetMessageW(&message, nullptr, 0, 0) > 0) { - TranslateMessage(&message); - DispatchMessageW(&message); - } - if (hook != nullptr) - UnhookWinEvent(hook); - if (controllerActive) { - reset_rpc_server(); - } - if (window != nullptr) - DestroyWindow(window); - g_object_unref(connection); - CloseHandle(singleton); - return 0; -} diff --git a/wine-access/nvdaController.idl b/wine-access/nvdaController.idl deleted file mode 100644 index 8e717a4..0000000 --- a/wine-access/nvdaController.idl +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later - -typedef [v1_enum] enum tagSPEECH_PRIORITY { - SPEECH_PRIORITY_NORMAL = 0, - SPEECH_PRIORITY_NEXT = 1, - SPEECH_PRIORITY_NOW = 2 -} SPEECH_PRIORITY; - -typedef [v1_enum] enum tagSYMBOL_LEVEL { - SYMBOL_LEVEL_NONE = 0, - SYMBOL_LEVEL_SOME = 100, - SYMBOL_LEVEL_MOST = 200, - SYMBOL_LEVEL_ALL = 300, - SYMBOL_LEVEL_CHAR = 1000, - SYMBOL_LEVEL_UNCHANGED = -1 -} SYMBOL_LEVEL; - -[ - uuid(DFF50B99-F7FD-4ca7-A82C-DAEB3E025295), - version(1.0) -] -interface NvdaController { - error_status_t __stdcall testIfRunning(); - error_status_t __stdcall speakText([in, string] const wchar_t *text); - error_status_t __stdcall cancelSpeech(); - error_status_t __stdcall brailleMessage([in, string] const wchar_t *message); -}; - -[ - uuid(3D168D45-CB58-4270-8257-4E0BE515D557), - version(1.0) -] -interface NvdaController2 { - error_status_t __stdcall getProcessId([out] unsigned long *pid); - error_status_t __stdcall speakSsml( - [in, string] const wchar_t *ssml, - [in] const SYMBOL_LEVEL symbolLevel, - [in] const SPEECH_PRIORITY priority, - [in] const boolean asynchronous); - // WIDL lacks MIDL's callback attribute. Keeping this method in slot 2 - // preserves the wire layout used by the unmodified controller client. - error_status_t __stdcall onSsmlMarkReached([in, string] const wchar_t *mark); -}; - -[ - uuid(019e4216-a9a1-7540-a217-e1a2d2793025), - version(1.0) -] -interface NvdaController3 { - error_status_t __stdcall isSpeaking([out] boolean *speaking); -}; diff --git a/wine-access/winelib-toolchain.cmake b/wine-access/winelib-toolchain.cmake deleted file mode 100644 index cadc138..0000000 --- a/wine-access/winelib-toolchain.cmake +++ /dev/null @@ -1,14 +0,0 @@ -set(CMAKE_SYSTEM_NAME Linux) -find_program(WINEGCC winegcc REQUIRED) -find_program(WINEGXX wineg++ REQUIRED) -set(CMAKE_C_COMPILER "${WINEGCC}") -set(CMAKE_CXX_COMPILER "${WINEGXX}") -foreach(language C CXX) - set(CMAKE_SHARED_LIBRARY_PREFIX_${language} "") - set(CMAKE_SHARED_LIBRARY_SUFFIX_${language} ".dll") -endforeach() -set(CMAKE_SHARED_LIBRARY_PREFIX "") -set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") -set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "") -set(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "") -set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)